diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/COPYING linux/COPYING
--- linux.orig/COPYING	2001-10-09 22:00:06.000000000 +0000
+++ linux/COPYING	2002-07-20 01:08:21.000000000 +0000
@@ -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	2002-02-25 19:37:50.000000000 +0000
+++ linux/CREDITS	2002-07-20 01:08:27.000000000 +0000
@@ -198,12 +198,10 @@
 S: USA
 
 N: Greg Banks
-E: gnb@linuxfan.com
+E: gnb@alphalink.com.au
 D: IDT77105 ATM network driver
-S: NEC Australia
-S: 649-655 Springvale Rd
-S: Mulgrave, Victoria 3170
-S: Australia
+D: some SuperH port work
+D: some trivial futzing with kconfig
 
 N: James Banks
 E: james@sovereign.org
@@ -586,8 +584,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 +633,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 +744,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 +1199,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
@@ -1500,6 +1512,13 @@
 S: 602 00 Brno
 S: Czech Republic
 
+N: Jakob Kemi
+E: jakob.kemi@telia.com
+D: V4L W9966 Webcam driver
+S: Forsbyvägen 33
+S: 74143 Knivsta
+S: Sweden
+
 N: Fred N. van Kempen
 E: waltje@linux.com
 D: NET-2
@@ -1574,8 +1593,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 +1673,14 @@
 S: San Antonio, Texas 78269-1886
 S: USA
 
+N: Denis O. Kropp
+E: dok@directfb.org
+D: NeoMagic framebuffer driver
+D: CyberPro 32 bit support, fixes
+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 
@@ -1661,13 +1690,6 @@
 S: 80-283 Gdansk
 S: Poland
 
-N: Jakob Kemi
-E: jakob.kemi@telia.com
-D: V4L W9966 Webcam driver
-S: Forsbyvägen 33
-S: 74143 Knivsta
-S: Sweden
-
 N: Gero Kuhlmann
 E: gero@gkminix.han.de
 D: mounting root via NFS
@@ -1895,13 +1917,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 +2153,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 +2540,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
@@ -2741,6 +2769,10 @@
 E: x@xman.org
 D: Tulip net driver hacker
 
+N: Mark Smith
+E: mark.smith@comdev.cc
+D: Multicast support in bonding driver
+
 N: Miquel van Smoorenburg
 E: miquels@cistron.nl
 D: Kernel and net hacker. Sysvinit, minicom. doing Debian stuff.
@@ -3265,9 +3297,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	2001-12-21 17:41:53.000000000 +0000
+++ linux/Documentation/Changes	2002-07-20 01:08:39.000000000 +0000
@@ -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	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/Configure.help	2002-07-20 01:08:40.000000000 +0000
@@ -2,7 +2,7 @@
 #	Eric S. Raymond <mailto:esr@thyrsus.com>
 #	Steven Cole <mailto:elenstev@mesatop.com>
 #
-# Merged version 2.69: current with 2.4.17-pre8/2.5.1-pre10.
+# Version 3.00: current with 2.4.19
 #
 # This version of the Linux kernel configuration help texts
 # corresponds to kernel versions 2.4.x and 2.5.x.
@@ -31,7 +31,7 @@
 #
 # Information about what a kernel is, what it does, how to patch and
 # compile it and much more is contained in the Kernel-HOWTO, available
-# at <http://www.linuxdoc.org/docs.html#howto>. Before you start
+# at <http://www.tldp.org/docs.html#howto>. Before you start
 # compiling, make sure that you have the necessary versions of all
 # programs and libraries required to compile and run this kernel; they
 # are listed in the <file:Documentation/Changes>. Make sure to read the
@@ -58,7 +58,7 @@
 #
 # Mention all the relevant READMEs and HOWTOs in the help text.
 # Make them file URLs relative to the top level of the source tree so
-# that help browsers can turn them into hotlinks.  All URLs ahould be
+# that help browsers can turn them into hotlinks.  All URLs should be
 # surrounded by <>.
 #
 # Repetitions are fine since the help texts are not meant to be read
@@ -121,7 +121,7 @@
   If you say N here, the kernel will run on single and multiprocessor
   machines, but will use only one CPU of a multiprocessor machine. If
   you say Y here, the kernel will run on many, but not all,
-  singleprocessor machines. On a singleprocessor machine, the kernel
+  single machines. On a singleprocessor machine, the kernel
   will run faster if you say N here.
 
   Note that if you say Y here and choose architecture "586" or
@@ -136,7 +136,7 @@
   See also the <file:Documentation/smp.tex>,
   <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
   <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you don't know what to do here, say N.
 
@@ -277,7 +277,7 @@
 
   If you don't have a math coprocessor, you need to say Y here; if you
   say Y here even though you have a coprocessor, the coprocessor will
-  be used nevertheless. (This behavior can be changed with the kernel
+  be used nevertheless. (This behaviour can be changed with the kernel
   command line option "no387", which comes handy if your coprocessor
   is broken. Try "man bootparam" or see the documentation of your boot
   loader (lilo or loadlin) about how to pass options to the kernel at
@@ -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
@@ -575,7 +592,7 @@
   topics, is contained in <file:Documentation/ide.txt>. For detailed
   information about hard drives, consult the Disk-HOWTO and the
   Multi-Disk-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   To fine-tune ATA/IDE drive/interface parameters for improved
   performance, look for the hdparm package at
@@ -608,7 +625,7 @@
   If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver
   instead of this one. For more detailed information, read the
   Disk-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 Use old disk-only driver on primary interface
 CONFIG_BLK_DEV_HD_IDE
@@ -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 separate 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
@@ -906,7 +984,7 @@
 
   It is SAFEST to say N to this question.
 
-Asyncronious DMA support (EXPERIMENTAL)
+Asynchronous DMA support (EXPERIMENTAL)
 CONFIG_BLK_DEV_ADMA
   Please read the comments at the top of
   <file:drivers/ide/ide-adma.c>.
@@ -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.
@@ -1122,7 +1200,7 @@
 
   It was originally designed for the PDC20246/Ultra33, whose BIOS will
   only setup UDMA on the first two PDC20246 cards.  It has also been
-  used succesfully on a PDC20265/Ultra100, allowing use of UDMA modes
+  used successfully on a PDC20265/Ultra100, allowing use of UDMA modes
   when the PDC20265 BIOS has been disabled (for faster boot up).
 
   Please read the comments at the top of
@@ -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.
@@ -1709,7 +1793,7 @@
 
   More information about Software RAID on Linux is contained in the
   Software RAID mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. There you will also learn
+  <http://www.tldp.org/docs.html#howto>. There you will also learn
   where to get the supporting user space utilities raidtools.
 
   If unsure, say N.
@@ -1737,7 +1821,7 @@
 
   Information about Software RAID on Linux is contained in the
   Software-RAID mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. There you will also
+  <http://www.tldp.org/docs.html#howto>. There you will also
   learn where to get the supporting user space utilities raidtools.
 
   If you want to compile this as a module ( = code which can be
@@ -1759,7 +1843,7 @@
 
   Information about Software RAID on Linux is contained in the
   Software-RAID mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  There you will also
+  <http://www.tldp.org/docs.html#howto>.  There you will also
   learn where to get the supporting user space utilities raidtools.
 
   If you want to use such a RAID-1 set, say Y. This code is also
@@ -1782,7 +1866,7 @@
 
   Information about Software RAID on Linux is contained in the
   Software-RAID mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. There you will also
+  <http://www.tldp.org/docs.html#howto>. There you will also
   learn where to get the supporting user space utilities raidtools.
 
   If you want to use such a RAID-4/RAID-5 set, say Y. This code is
@@ -1809,7 +1893,7 @@
   to use its softwareraid feature.  You must also select an
   appropriate for your board low-level driver below.
 
-  Note, that Linux does not use the Raid implemetation in BIOS, and
+  Note, that Linux does not use the Raid implementation in BIOS, and
   the main purpose for this feature is to retain compatibility and
   data integrity with other OS-es, using the same disk array. Linux
   has its own Raid drivers, which you should use if you need better
@@ -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,
@@ -2012,7 +2101,7 @@
 
 Kernel floating-point instruction emulation
 CONFIG_MIPS_FPU_EMULATOR
-  This option enables the MIPS software floatingpoint support.  Due to
+  This option enables the MIPS software floating support.  Due to
   the way floating point works you should always enable this option
   unless you exactly know what you're doing.
 
@@ -2171,7 +2260,7 @@
 
 Discontiguous Memory Support
 CONFIG_DISCONTIGMEM
-  Say Y to upport efficient handling of discontiguous physical memory,
+  Say Y to support efficient handling of discontiguous physical memory,
   for architectures which are either NUMA (Non-Uniform Memory Access)
   or have huge holes in the physical address space for other reasons.
   See <file:Documentation/vm/numa> for more.
@@ -2180,7 +2269,7 @@
 CONFIG_MAPPED_KERNEL
   Change the way a Linux kernel is loaded unto memory on a MIPS64
   machine.  This is required in order to support text replication and
-  NUMA.  If you need to undersatand it, read the source code.
+  NUMA.  If you need to understand it, read the source code.
 
 Kernel text replication support
 CONFIG_REPLICATE_KTEXT
@@ -2250,7 +2339,7 @@
 Use power LED as a heartbeat
 CONFIG_HEARTBEAT
   Use the power-on LED on your machine as a load meter.  The exact
-  behavior is platform-dependent, but normally the flash frequency is
+  behaviour is platform-dependent, but normally the flash frequency is
   a hyperbolic function of the 5-minute load average.
 
 Networking support
@@ -2266,7 +2355,7 @@
 
   For a general introduction to Linux networking, it is highly
   recommended to read the NET-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 Socket filtering
 CONFIG_FILTER
@@ -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
@@ -2582,7 +2684,7 @@
   associated with the packet prior to routing. This can change
   the routing method (see `Use netfilter MARK value as routing
   key') and can also be used by other subsystems to change their
-  behavior.
+  behaviour.
 
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
@@ -2628,7 +2730,7 @@
   daemon using netlink multicast sockets; unlike the LOG target
   which can only be viewed through syslog.
 
-  The apropriate userspace logging daemon (ulogd) may be obtained from
+  The appropriate userspace logging daemon (ulogd) may be obtained from
   http://www.gnumonks.org/projects/ulogd
 
   If you want to compile it as a module, say M here and read
@@ -2740,7 +2842,7 @@
   associated with the packet packet prior to routing. This can change
   the routing method (see `Use netfilter MARK value as routing
   key') and can also be used by other subsystems to change their
-  behavior.
+  behaviour.
 
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
@@ -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
@@ -3104,20 +3198,12 @@
   Say Y here if you have dumb serial boards other than the four
   standard COM 1/2/3/4 ports. This may happen if you have an AST
   FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
-  from <http://www.linuxdoc.org/docs.html#howto>), or other custom
+  from <http://www.tldp.org/docs.html#howto>), or other custom
   serial port hardware which acts similar to standard serial port
   hardware. If you only use the standard COM 1/2/3/4 ports, you can
   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
@@ -3323,7 +3420,7 @@
   VESA. If you have PCI, say Y, otherwise N.
 
   The PCI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, contains valuable
+  <http://www.tldp.org/docs.html#howto>, contains valuable
   information about which PCI hardware does work under Linux and which
   doesn't.
 
@@ -3335,7 +3432,7 @@
   VESA. If you have PCI, say Y, otherwise N.
 
   The PCI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, contains valuable
+  <http://www.tldp.org/docs.html#howto>, contains valuable
   information about which PCI hardware does work under Linux and which
   doesn't.
 
@@ -3347,7 +3444,7 @@
   VESA. If you have PCI, say Y, otherwise N.
 
   The PCI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, contains valuable
+  <http://www.tldp.org/docs.html#howto>, contains valuable
   information about which PCI hardware does work under Linux and which
   doesn't.
 
@@ -3602,7 +3699,7 @@
   To use your PC-cards, you will need supporting software from David
   Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
   for location).  Please also read the PCMCIA-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -3656,12 +3753,12 @@
   and some programs won't run unless you say Y here. In particular, if
   you want to run the DOS emulator dosemu under Linux (read the
   DOSEMU-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>), you'll need to say Y
+  <http://www.tldp.org/docs.html#howto>), you'll need to say Y
   here.
 
   You can find documentation about IPC with "info ipc" and also in
   section 6.4 of the Linux Programmer's Guide, available from
-  <http://www.linuxdoc.org/docs.html#guide>.
+  <http://www.tldp.org/docs.html#guide>.
 
 BSD Process Accounting
 CONFIG_BSD_PROCESS_ACCT
@@ -3730,7 +3827,7 @@
   want to say Y here.
 
   Information about ELF is contained in the ELF HOWTO available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you find that after upgrading from Linux kernel 1.2 and saying Y
   here, you still can't run any ELF binaries (they just crash), then
@@ -3765,6 +3862,12 @@
   because some crucial programs on your system might still be in A.OUT
   format.
 
+OSF/1 v4 readv/writev compatibility
+CONFIG_OSF4_COMPAT
+  Say Y if you are using OSF/1 binaries (like Netscape and Acrobat)
+  with v4 shared libraries freely available from Compaq. If you're
+  going to use shared libraries from Tru64 version 5.0 or later, say N.
+
 Kernel support for Linux/Intel ELF binaries
 CONFIG_BINFMT_EM86
   Say Y here if you want to be able to execute Linux/Intel ELF
@@ -3790,7 +3893,7 @@
   programs that need an interpreter to run like Java, Python or
   Emacs-Lisp. It's also useful if you often run DOS executables under
   the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>). Once you have
+  <http://www.tldp.org/docs.html#howto>). Once you have
   registered such a binary class with the kernel, you can start one of
   those programs simply by typing in its name at a shell prompt; Linux
   will automatically feed it to the correct interpreter.
@@ -4207,6 +4310,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 +4527,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 +4567,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 +4621,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 +4764,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 +4921,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
@@ -4985,7 +5117,7 @@
 
   For an excellent introduction to Linux networking, please read the
   NET-3-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   This option is also necessary if you want to use the full power of
   term (term is a program which gives you almost full Internet
@@ -4995,7 +5127,7 @@
 
   If you say Y here and also to "/proc file system support" and
   "Sysctl support" below, you can change various aspects of the
-  behavior of the TCP/IP code by writing to the (virtual) files in
+  behaviour of the TCP/IP code by writing to the (virtual) files in
   /proc/sys/net/ipv4/*; the options are explained in the file
   <file:Documentation/networking/ip-sysctl.txt>.
 
@@ -5307,7 +5439,7 @@
   Novell client ncpfs (available from
   <ftp://platan.vc.cvut.cz/pub/linux/ncpfs/>) or from
   within the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>).  In order
+  available from <http://www.tldp.org/docs.html#howto>).  In order
   to do the former, you'll also have to say Y to "NCP file system
   support", below.
 
@@ -5320,7 +5452,7 @@
   <ftp://ibiblio.org/pub/Linux/system/network/daemons/> or
   mars_nwe from <ftp://www.compu-art.de/mars_nwe/>. For more
   information, read the IPX-HOWTO available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   General information about how to connect Linux, Windows machines and
   Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
@@ -5341,7 +5473,7 @@
   same address). The way this is done is to create a virtual internal
   "network" inside your box and to assign an IPX address to this
   network. Say Y here if you want to do this; read the IPX-HOWTO at
-  <http://www.linuxdoc.org/docs.html#howto> for details.
+  <http://www.tldp.org/docs.html#howto> for details.
 
   The full internal IPX network enables you to allocate sockets on
   different virtual nodes of the internal network. This is done by
@@ -5376,7 +5508,7 @@
   space programs lwared or mars_nwe for the server side).
 
   Say Y here if you have use for SPX; read the IPX-HOWTO at
-  <http://www.linuxdoc.org/docs.html#howto> for details.
+  <http://www.tldp.org/docs.html#howto> for details.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5434,18 +5566,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
@@ -5455,7 +5588,7 @@
   General information about how to connect Linux, Windows machines and
   Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.  The
   NET-3-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, contains valuable
+  <http://www.tldp.org/docs.html#howto>, contains valuable
   information as well.
 
   This driver is also available as a module ( = code which can be
@@ -5544,7 +5677,7 @@
 CONFIG_HAMRADIO
   If you want to connect your Linux box to an amateur radio, answer Y
   here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> and
-  the AX25-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
+  the AX25-HOWTO, available from <http://www.tldp.org/docs.html#howto>.
 
   Note that the answer to this question won't directly affect the
   kernel: saying N will just cause the configurator to skip all
@@ -5568,7 +5701,7 @@
   Information about where to get supporting software for Linux amateur
   radio as well as information about how to configure an AX.25 port is
   contained in the AX25-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. You might also want to
+  <http://www.tldp.org/docs.html#howto>. You might also want to
   check out the file <file:Documentation/networking/ax25.txt> in the
   kernel source. More information about digital amateur radio in
   general is on the WWW at
@@ -5605,7 +5738,7 @@
   A comprehensive listing of all the software for Linux amateur radio
   users as well as information about how to configure an AX.25 port is
   contained in the AX25-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. You also might want to
+  <http://www.tldp.org/docs.html#howto>. You also might want to
   check out the file <file:Documentation/networking/ax25.txt>. More
   information about digital amateur radio in general is on the WWW at
   <http://www.tapr.org/tapr/html/pkthome.html>.
@@ -5624,7 +5757,7 @@
   A comprehensive listing of all the software for Linux amateur radio
   users as well as information about how to configure an AX.25 port is
   contained in the AX25-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  You also might want to
+  <http://www.tldp.org/docs.html#howto>.  You also might want to
   check out the file <file:Documentation/networking/ax25.txt>. More
   information about digital amateur radio in general is on the WWW at
   <http://www.tapr.org/tapr/html/pkthome.html>.
@@ -5688,7 +5821,7 @@
   Currently, this driver supports Ottawa PI/PI2, Paccomm/Gracilis
   PackeTwin, and S5SCC/DMA boards. They are detected automatically.
   If you have one of these cards, say Y here and read the AX25-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   This driver can operate multiple boards simultaneously. If you
   compile it as a module (by saying M instead of Y), it will be called
@@ -5714,7 +5847,7 @@
   in order to communicate with other computers. If you want to use
   this, read <file:Documentation/networking/z8530drv.txt> and the
   AX25-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. Also make sure to say Y
+  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
   to "Amateur Radio AX.25 Level 2" support.
 
   If you want to compile this as a module ( = code which can be
@@ -6001,7 +6134,7 @@
   Note that if your box acts as a bridge, it probably contains several
   Ethernet devices, but the kernel is not able to recognize more than
   one at boot time without help; for details read the Ethernet-HOWTO,
-  available from in <http://www.linuxdoc.org/docs.html#howto>.
+  available from in <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this code as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -6099,6 +6232,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 +6540,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 +6569,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
@@ -6636,7 +6800,7 @@
   If you want to use a SCSI hard disk or the SCSI or parallel port
   version of the IOMEGA ZIP drive under Linux, say Y and read the
   SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. This is NOT for SCSI
+  <http://www.tldp.org/docs.html#howto>. This is NOT for SCSI
   CD-ROMs.
 
   This driver is also available as a module ( = code which can be
@@ -6680,7 +6844,7 @@
 CONFIG_CHR_DEV_ST
   If you want to use a SCSI tape drive under Linux, say Y and read the
   SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, and
+  <http://www.tldp.org/docs.html#howto>, and
   <file:drivers/scsi/README.st> in the kernel source.  This is NOT for
   SCSI CD-ROMs.
 
@@ -6700,7 +6864,7 @@
   tape drives (ADR-x0) that supports the standard SCSI-2 commands for
   tapes (QIC-157) and can be driven by the standard driver st.
   For more information, you may have a look at the SCSI-HOWTO
-  <http://www.linuxdoc.org/docs.html#howto>  and
+  <http://www.tldp.org/docs.html#howto>  and
   <file:drivers/scsi/README.osst>  in the kernel source.
   More info on the OnStream driver may be found on
   <http://linux1.onstream.nl/test/>
@@ -6717,7 +6881,7 @@
 CONFIG_BLK_DEV_SR
   If you want to use a SCSI CD-ROM under Linux, say Y and read the
   SCSI-HOWTO and the CD-ROM-HOWTO at
-  <http://www.linuxdoc.org/docs.html#howto>. Also make sure to say Y
+  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
   or M to "ISO 9660 CD-ROM file system support" later.
 
   This driver is also available as a module ( = code which can be
@@ -6840,7 +7004,7 @@
   must be manually specified in this case.
 
   It is explained in section 3.3 of the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. You might also want to
+  <http://www.tldp.org/docs.html#howto>. You might also want to
   read the file <file:drivers/scsi/README.aha152x>.
 
   This driver is also available as a module ( = code which can be
@@ -6852,7 +7016,7 @@
 CONFIG_SCSI_AHA1542
   This is support for a SCSI host adapter.  It is explained in section
   3.4 of the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  Note that Trantor was
+  <http://www.tldp.org/docs.html#howto>.  Note that Trantor was
   purchased by Adaptec, and some former Trantor products are being
   sold under the Adaptec name.  If it doesn't work out of the box, you
   may have to change some settings in <file:drivers/scsi/aha1542.h>.
@@ -6866,7 +7030,7 @@
 CONFIG_SCSI_AHA1740
   This is support for a SCSI host adapter.  It is explained in section
   3.5 of the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  If it doesn't work out
+  <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
   of the box, you may have to change some settings in
   <file:drivers/scsi/aha1740.h>.
 
@@ -6903,9 +7067,9 @@
 
   This is an upper bound value for the number of tagged transactions
   to be used for any device.  The aic7xxx driver will automatically
-  vary this number based on device behavior.  For devices with a
+  vary this number based on device behaviour.  For devices with a
   fixed maximum, the driver will eventually lock to this maximum
-  and display a console message inidicating this value.
+  and display a console message indicating this value.
 
   Note: Unless you experience some type of device failure, the default
 	value, no enforced limit, should work for you.
@@ -6962,7 +7126,7 @@
   configuration options. You should read
   <file:drivers/scsi/aic7xxx_old/README.aic7xxx> at a minimum before
   contacting the maintainer with any questions.  The SCSI-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>, can also
+  available from <http://www.tldp.org/docs.html#howto>, can also
   be of great help.
 
   If you want to compile this driver as a module ( = code which can be
@@ -7056,7 +7220,7 @@
 CONFIG_SCSI_BUSLOGIC
   This is support for BusLogic MultiMaster and FlashPoint SCSI Host
   Adapters. Consult the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, and the files
+  <http://www.tldp.org/docs.html#howto>, and the files
   <file:drivers/scsi/README.BusLogic> and
   <file:drivers/scsi/README.FlashPoint> for more information. If this
   driver does not work correctly without modification, please contact
@@ -7093,7 +7257,7 @@
 CONFIG_SCSI_DTC3280
   This is support for DTC 3180/3280 SCSI Host Adapters.  Please read
   the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, and the file
+  <http://www.tldp.org/docs.html#howto>, and the file
   <file:drivers/scsi/README.dtc3x80>.
 
   This driver is also available as a module ( = code which can be
@@ -7110,7 +7274,7 @@
   Note that this driver is obsolete; if you have one of the above
   SCSI Host Adapters, you should normally say N here and Y to "EATA
   ISA/EISA/PCI support", below.  Please read the SCSI-HOWTO, available
-  from <http://www.linuxdoc.org/docs.html#howto>.
+  from <http://www.tldp.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).
@@ -7124,7 +7288,7 @@
   host adapters could also use this driver but are discouraged from
   doing so, since this driver only supports hard disks and lacks
   numerous features.  You might want to have a look at the SCSI-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -7138,7 +7302,7 @@
   information about this hardware.  If the driver doesn't work out of
   the box, you may have to change some settings in
   <file: drivers/scsi/u14-34f.c>.  Read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  Note that there is also
+  <http://www.tldp.org/docs.html#howto>.  Note that there is also
   another driver for the same hardware: "UltraStor SCSI support",
   below.  You should say Y to both only if you want 24F support as
   well.
@@ -7173,7 +7337,7 @@
   other adapters based on the Future Domain chipsets (Quantum
   ISA-200S, ISA-250MG; Adaptec AHA-2920A; and at least one IBM board).
   It is explained in section 3.7 of the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip
   and should use the aic7xxx driver ("Adaptec AIC7xxx chipset SCSI
@@ -7203,7 +7367,7 @@
   This is the generic NCR family of SCSI controllers, not to be
   confused with the NCR 53c7 or 8xx controllers.  It is explained in
   section 3.8 of the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  If it doesn't work out
+  <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
   of the box, you may have to change some settings in
   <file:drivers/scsi/g_NCR5380.h>.
 
@@ -7250,7 +7414,7 @@
   This is a driver for the 53c7 and 8xx NCR family of SCSI
   controllers, not to be confused with the NCR 5380 controllers.  It
   is explained in section 3.8 of the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  If it doesn't work out
+  <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
   of the box, you may have to change some settings in
   <file:drivers/scsi/53c7,8xx.h>.  Please read
   <file:drivers/scsi/README.ncr53c7xx> for the available boot time
@@ -7609,7 +7773,7 @@
 CONFIG_SCSI_INITIO
   This is support for the Initio 91XXU(W) SCSI host adapter.  Please
   read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -7620,7 +7784,7 @@
 CONFIG_SCSI_PAS16
   This is support for a SCSI host adapter.  It is explained in section
   3.10 of the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  If it doesn't work out
+  <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
   of the box, you may have to change some settings in
   <file:drivers/scsi/pas16.h>.
 
@@ -7633,7 +7797,7 @@
 CONFIG_SCSI_INIA100
   This is support for the Initio INI-A100U2W SCSI host adapter.
   Please read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -7644,7 +7808,7 @@
 CONFIG_SCSI_PCI2000
   This is support for the PCI2000I EIDE interface card which acts as a
   SCSI host adapter.  Please read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   This driver is also available as a module called pci2000.o ( = code
   which can be inserted in and removed from the running kernel
@@ -7655,7 +7819,7 @@
 CONFIG_SCSI_PCI2220I
   This is support for the PCI2220i EIDE interface card which acts as a
   SCSI host adapter.  Please read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   This driver is also available as a module called pci2220i.o ( = code
   which can be inserted in and removed from the running kernel
@@ -7666,7 +7830,7 @@
 CONFIG_SCSI_PSI240I
   This is support for the PSI240i EIDE interface card which acts as a
   SCSI host adapter.  Please read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   This driver is also available as a module called psi240i.o ( = code
   which can be inserted in and removed from the running kernel
@@ -7686,7 +7850,7 @@
   Information about this driver is contained in
   <file:drivers/scsi/README.qlogicfas>.  You should also read the
   SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -7704,7 +7868,7 @@
 
   Please read the file <file:drivers/scsi/README.qlogicisp>.  You
   should also read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -7720,6 +7884,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.
@@ -7733,7 +7903,7 @@
 CONFIG_SCSI_SEAGATE
   These are 8-bit SCSI controllers; the ST-01 is also supported by
   this driver.  It is explained in section 3.9 of the SCSI-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.  If it
+  available from <http://www.tldp.org/docs.html#howto>.  If it
   doesn't work out of the box, you may have to change some settings in
   <file:drivers/scsi/seagate.h>.
 
@@ -7746,7 +7916,7 @@
 CONFIG_SCSI_T128
   This is support for a SCSI host adapter. It is explained in section
   3.11 of the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  If it doesn't work out
+  <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
   of the box, you may have to change some settings in
   <file:drivers/scsi/t128.h>.  Note that Trantor was purchased by
   Adaptec, and some former Trantor products are being sold under the
@@ -7762,7 +7932,7 @@
   This is support for the UltraStor 14F, 24F and 34F SCSI-2 host
   adapter family.  This driver is explained in section 3.12 of the
   SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  If it doesn't work out
+  <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
   of the box, you may have to change some settings in
   <file:drivers/scsi/ultrastor.h>.
 
@@ -7804,7 +7974,7 @@
 
   You want to read the start of <file:drivers/scsi/eata.c> and the
   SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   Note that there is also another driver for the same hardware
   available: "EATA-DMA [Obsolete] (DPT, NEC, AT&T, SNI, AST, Olivetti,
@@ -7845,7 +8015,7 @@
   This is support for the NCR53c406a SCSI host adapter.  For user
   configurable parameters, check out <file:drivers/scsi/NCR53c406a.c>
   in the kernel source.  Also read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   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),
@@ -7928,7 +8098,7 @@
   This is support for the AM53/79C974 SCSI host adapters.  Please read
   <file:drivers/scsi/README.AM53C974> for details.  Also, the
   SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, is for you.
+  <http://www.tldp.org/docs.html#howto>, is for you.
 
   Note that there is another driver for AM53C974 based adapters:
   "Tekram DC390(T) and Am53/79C974 (PCscsi) SCSI support", above.  You
@@ -7980,7 +8150,7 @@
   For more information about this driver and how to use it you should
   read the file <file:drivers/scsi/README.ppa>.  You should also read
   the SCSI-HOWTO, which is available from
-  <http://www.linuxdoc.org/docs.html#howto>.  If you use this driver,
+  <http://www.tldp.org/docs.html#howto>.  If you use this driver,
   you will still be able to use the parallel port for other tasks,
   such as a printer; it is safe to compile both drivers into the
   kernel.
@@ -8007,7 +8177,7 @@
   For more information about this driver and how to use it you should
   read the file <file:drivers/scsi/README.ppa>.  You should also read
   the SCSI-HOWTO, which is available from
-  <http://www.linuxdoc.org/docs.html#howto>.  If you use this driver,
+  <http://www.tldp.org/docs.html#howto>.  If you use this driver,
   you will still be able to use the parallel port for other tasks,
   such as a printer; it is safe to compile both drivers into the
   kernel.
@@ -8293,7 +8463,7 @@
   telephone line with a modem either via UUCP (UUCP is a protocol to
   forward mail and news between unix hosts over telephone lines; read
   the UUCP-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>) or dialing up a shell
+  <http://www.tldp.org/docs.html#howto>) or dialing up a shell
   account or a BBS, even using term (term is a program which gives you
   almost full Internet connectivity if you have a regular dial up
   shell account on some Internet connected Unix computer. Read
@@ -8313,7 +8483,7 @@
 
   Make sure to read the NET-3-HOWTO. Eventually, you will have to read
   Olaf Kirch's excellent and free book "Network Administrator's
-  Guide", to be found in <http://www.linuxdoc.org/docs.html#guide>. If
+  Guide", to be found in <http://www.tldp.org/docs.html#guide>. If
   unsure, say Y.
 
 Dummy net driver support
@@ -8326,7 +8496,7 @@
   thing often comes in handy, the default is Y. It won't enlarge your
   kernel either. What a deal. Read about it in the Network
   Administrator's Guide, available from
-  <http://www.linuxdoc.org/docs.html#guide>.
+  <http://www.tldp.org/docs.html#guide>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -8374,7 +8544,7 @@
   allows you to use SLIP over a regular dial up shell connection. If
   you plan to use SLiRP, make sure to say Y to CSLIP, below. The
   NET-3-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, explains how to
+  <http://www.tldp.org/docs.html#howto>, explains how to
   configure SLIP. Note that you don't need this option if you just
   want to run term (term is a program which gives you almost full
   Internet connectivity if you have a regular dial up shell account on
@@ -8398,7 +8568,7 @@
   <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
   allows you to use SLIP over a regular dial up shell connection, you
   definitely want to say Y here. The NET-3-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, explains how to configure
+  <http://www.tldp.org/docs.html#howto>, explains how to configure
   CSLIP. This won't enlarge your kernel.
 
 Keepalive and linefill
@@ -8427,7 +8597,7 @@
 
   To use PPP, you need an additional program called pppd as described
   in the PPP-HOWTO, available at
-  <http://www.linuxdoc.org/docs.html#howto>.  Make sure that you have
+  <http://www.tldp.org/docs.html#howto>.  Make sure that you have
   the version of pppd recommended in <file:Documentation/Changes>.
   The PPP option enlarges your kernel by about 16 KB.
 
@@ -8530,9 +8700,9 @@
 CONFIG_PPPOE
   Support for PPP over Ethernet.
 
-  This driver requires a specially patched pppd daemon.  The patch to
-  pppd, along with binaries of a patched pppd package can be found at:
-  <http://www.shoshin.uwaterloo.ca/~mostrows/>.
+  This driver requires the current pppd from the "ppp" CVS repository
+  on cvs.samba.org.  The required support will be present in the next
+  ppp release (2.4.2).
 
 Wireless LAN (non-hamradio)
 CONFIG_NET_RADIO
@@ -8592,7 +8762,7 @@
 
   If you want to use an ISA WaveLAN card under Linux, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. Some more specific
+  <http://www.tldp.org/docs.html#howto>. Some more specific
   information is contained in
   <file:Documentation/networking/wavelan.txt> and in the source code
   <file:drivers/net/wavelan.p.h>.
@@ -8753,7 +8923,7 @@
   To use your PC-cards, you will need supporting software from David
   Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
   for location).  You also want to check out the PCMCIA-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   If unsure, say N.
 
@@ -8882,6 +9052,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
@@ -8891,7 +9074,7 @@
   To use your PC-cards, you will need supporting software from David
   Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
   for location). You also want to check out the PCMCIA-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
 Hermes chipset 802.11b support (Orinoco/Prism2/Symbol cards)
 CONFIG_HERMES
@@ -8925,6 +9108,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
@@ -8937,7 +9128,7 @@
   To use your PC-cards, you will need supporting software from David
   Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
   for location).  You also want to check out the PCMCIA-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   You will also very likely also need the Wireless Tools in order to
   configure your card and that /etc/pcmcia/wireless.opts works:
@@ -8949,7 +9140,7 @@
   PCI 802.11 wireless cards.
   It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
   - with or without encryption) as well as card before the Cisco
-  aquisition (Aironet 4500, Aironet 4800, Aironet 4800B).
+  acquisition (Aironet 4500, Aironet 4800, Aironet 4800B).
 
   This driver support both the standard Linux Wireless Extensions
   and Cisco proprietary API, so both the Linux Wireless Tools and the
@@ -8964,7 +9155,7 @@
   driver part of the Linux Pcmcia package.
   It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
   - with or without encryption) as well as card before the Cisco
-  aquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also
+  acquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also
   supports OEM of Cisco such as the DELL TrueMobile 4800 and Xircom
   802.11b cards.
 
@@ -8975,7 +9166,7 @@
   To use your PC-cards, you will need supporting software from David
   Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
   for location).  You also want to check out the PCMCIA-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
 Aviator/Raytheon 2.4MHz wireless support
 CONFIG_PCMCIA_RAYCS
@@ -9044,7 +9235,7 @@
 
   If you want to use PLIP, say Y and read the PLIP mini-HOWTO as well
   as the NET-3-HOWTO, both available from
-  <http://www.linuxdoc.org/docs.html#howto>.  Note that the PLIP
+  <http://www.tldp.org/docs.html#howto>.  Note that the PLIP
   protocol has been changed and this PLIP driver won't work together
   with the PLIP support in Linux versions 1.0.x.  This option enlarges
   your kernel by about 8 KB.
@@ -9069,7 +9260,7 @@
   Say Y if you want this and read
   <file:Documentation/networking/eql.txt>.  You may also want to read
   section 6.2 of the NET-3-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -9132,6 +9323,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.
@@ -9386,7 +9599,7 @@
 
 Diffserv field marker
 CONFIG_NET_SCH_DSMARK
-  Say Y if you want to schedule packets avccording to the
+  Say Y if you want to schedule packets according to the
   Differentiated Services architecture proposed in RFC 2475.
   Technical information on this method, with pointers to associated
   RFCs, is available at <http://www.gta.ufrj.br/diffserv/>.
@@ -9588,6 +9801,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
@@ -9655,7 +9883,7 @@
   V.35 or V.36 interface) to your Linux box.
 
   LMC 1200 with on board DSU board allows you to connect your Linux
-  box dirrectly to a T1 or E1 circuit.
+  box directly to a T1 or E1 circuit.
 
   LMC 5200 board provides a HSSI interface capable of running up to
   52 mbits per second.
@@ -9772,14 +10000,14 @@
 CONFIG_WANPIPE_X25
   Say Y to this option if you are planning to connect a WANPIPE card
   to an X.25 network.  Note, this feature also includes the X.25 API
-  support used to develope custom applications over the X.25 protocol.
+  support used to develop custom applications over the X.25 protocol.
   If you say N, the X.25 support will not be included in the driver.
   The X.25 option is supported on S514-PCI and S508-ISA cards.
 
 WANPIPE Frame Relay support
 CONFIG_WANPIPE_FR
   Say Y to this option if you are planning to connect a WANPIPE card
-  to a frame relay network, or use frame relay API to develope
+  to a frame relay network, or use frame relay API to develop
   custom applications over the Frame  Relay protocol.
   This feature also contains the Ethernet Bridging over Frame Relay,
   where a WANPIPE frame relay link can be directly connected to the
@@ -9879,7 +10107,7 @@
   Hardware driver for the TCO timer built into the Intel i810 and i815
   chipset family.  The TCO (Total Cost of Ownership) timer is a
   watchdog timer that will reboot the machine after its second
-  expiration. The expiration time can be configured by commandline
+  expiration. The expiration time can be configured by command
   argument "i810_margin=<n>" where <n> is the counter initial value.
   It is decremented every 0.6 secs, the default is 50 which gives a
   timeout of 30 seconds and one minute until reset.
@@ -9893,6 +10121,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
@@ -10045,7 +10287,7 @@
   If your Linux machine will be connected to an Ethernet and you have
   an Ethernet network interface card (NIC) installed in your computer,
   say Y here and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. You will then also have
+  <http://www.tldp.org/docs.html#howto>. You will then also have
   to say Y to the driver for your particular NIC.
 
   Note that the answer to this question won't directly affect the
@@ -10056,7 +10298,7 @@
 CONFIG_NET_VENDOR_SMC
   If you have a network (Ethernet) card belonging to this class, say Y
   and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause the configurator to skip all
@@ -10067,7 +10309,7 @@
 CONFIG_WD80x3
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10079,7 +10321,7 @@
 CONFIG_ULTRAMCA
   If you have a network (Ethernet) card of this type and are running
   an MCA based system (PS/2), say Y and read the Ethernet-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.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).
@@ -10091,7 +10333,7 @@
 CONFIG_ULTRA
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   Important: There have been many reports that, with some motherboards
   mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
@@ -10110,7 +10352,7 @@
 CONFIG_ULTRA32
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10125,7 +10367,7 @@
   another SMC9192/9194 based chipset.  Say Y if you want it compiled
   into the kernel, and read the file
   <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.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).
@@ -10139,7 +10381,7 @@
   with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
   support" below). If you have a PCI NE2000 network (Ethernet) card,
   say Y and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   This driver also works for the following NE2000 clone cards:
     RealTek RTL-8029  Winbond 89C940  Compex RL2000  KTI ET32P2
@@ -10156,7 +10398,7 @@
 CONFIG_NET_VENDOR_RACAL
   If you have a network (Ethernet) card belonging to this class, such
   as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause the configurator to skip all
@@ -10167,7 +10409,7 @@
 CONFIG_NI5010
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. Note that this is still
+  <http://www.tldp.org/docs.html#howto>. Note that this is still
   experimental code.
 
   This driver is also available as a module ( = code which can be
@@ -10180,7 +10422,7 @@
 CONFIG_NI52
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10192,7 +10434,7 @@
 CONFIG_NI65
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10205,7 +10447,7 @@
   This is a driver for the Fast Ethernet PCI network cards based on
   the RTL8139C+ chips. If you have one of those, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   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),
@@ -10218,7 +10460,7 @@
   the RTL8139 chips. If you have one of those, say Y and read
   <file:Documentation/networking/8139too.txt> as well as the
   Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   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),
@@ -10252,7 +10494,7 @@
   the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
   SiS 630 and SiS 540 chipsets.  If you have one of those, say Y and
   read the Ethernet-HOWTO, available at
-  <http://www.linuxdoc.org/docs.html#howto>.  Please read
+  <http://www.tldp.org/docs.html#howto>.  Please read
   <file:Documentation/networking/sis900.txt> and comments at the
   beginning of <file:drivers/net/sis900.c> for more information.
 
@@ -10367,6 +10609,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.
@@ -10392,7 +10643,7 @@
 CONFIG_LANCE
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. Some LinkSys cards are
+  <http://www.tldp.org/docs.html#howto>. Some LinkSys cards are
   of this type.
 
   If you want to compile this driver as a module ( = code which can be
@@ -10404,7 +10655,7 @@
 CONFIG_SGI_IOC3_ETH
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 National Semiconductor DP83902AV support
 CONFIG_STNIC
@@ -10419,7 +10670,7 @@
 CONFIG_NET_VENDOR_3COM
   If you have a network (Ethernet) card belonging to this class, say Y
   and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause the configurator to skip all
@@ -10430,7 +10681,7 @@
 CONFIG_EL1
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  Also, consider buying a
+  <http://www.tldp.org/docs.html#howto>.  Also, consider buying a
   new card, since the 3c501 is slow, broken, and obsolete: you will
   have problems.  Some people suggest to ping ("man ping") a nearby
   machine every minute ("man cron") when using this card.
@@ -10445,7 +10696,7 @@
 CONFIG_EL2
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10458,7 +10709,7 @@
   Information about this network (Ethernet) card can be found in
   <file:Documentation/networking/3c505.txt>.  If you have a card of
   this type, say Y and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -10470,7 +10721,7 @@
 CONFIG_EL16
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10482,7 +10733,7 @@
 CONFIG_ELMC
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10494,7 +10745,7 @@
 CONFIG_ELMC_II
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10506,7 +10757,7 @@
 CONFIG_EL3
   If you have a network (Ethernet) card belonging to the 3Com
   EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
-  from <http://www.linuxdoc.org/docs.html#howto>.
+  from <http://www.tldp.org/docs.html#howto>.
 
   If your card is not working you may need to use the DOS
   setup disk to disable Plug & Play mode, and to select the default
@@ -10522,7 +10773,7 @@
 CONFIG_3C515
   If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
   network card, say Y and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -10542,7 +10793,7 @@
   "Hurricane" (3c555/3cSOHO)                           PCI
 
   If you have such a card, say Y and read the Ethernet-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>. More
+  available from <http://www.tldp.org/docs.html#howto>. More
   specific information is in
   <file:Documentation/networking/vortex.txt> and in the comments at
   the beginning of <file:drivers/net/3c59x.c>.
@@ -10558,7 +10809,7 @@
   bus system (that's the way the cards talks to the other components
   of your computer) is ISA (as opposed to EISA, VLB or PCI), say Y.
   Make sure you know the name of your card. Read the Ethernet-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   If unsure, say Y.
 
@@ -10579,7 +10830,7 @@
   support" below.
 
   You might also want to have a look at the Ethernet-HOWTO, available
-  from <http://www.linuxdoc.org/docs.html#howto>(even though ARCnet
+  from <http://www.tldp.org/docs.html#howto>(even though ARCnet
   is not really Ethernet).
 
   This driver is also available as a module ( = code which can be
@@ -10670,7 +10921,7 @@
 CONFIG_E2100
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10683,7 +10934,7 @@
   Support for CS89x0 chipset based Ethernet cards. If you have a
   network (Ethernet) card of this type, say Y and read the
   Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto> as well as
+  <http://www.tldp.org/docs.html#howto> as well as
   <file:Documentation/networking/cs89x0.txt>.
 
   If you want to compile this as a module ( = code which can be
@@ -10696,7 +10947,7 @@
 CONFIG_DEPCA
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto> as well as
+  <http://www.tldp.org/docs.html#howto> as well as
   <file:drivers/net/depca.c>.
 
   If you want to compile this as a module ( = code which can be
@@ -10712,7 +10963,7 @@
   cards. If this is for you, say Y and read
   <file:Documentation/networking/ewrk3.txt> in the kernel source as
   well as the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -10724,7 +10975,7 @@
 CONFIG_SEEQ8005
   This is a driver for the SEEQ 8005 network (Ethernet) card.  If this
   is for you, read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -10736,7 +10987,7 @@
 CONFIG_AT1700
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10749,7 +11000,7 @@
 CONFIG_FMV18X
   If you have a Fujitsu FMV-181/182/183/184 network (Ethernet) card,
   say Y and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you use an FMV-183 or FMV-184 and it is not working, you may need
   to disable Plug & Play mode of the card.
@@ -10766,7 +11017,7 @@
   driver supports intel i82595{FX,TX} based boards. Note however
   that the EtherExpress PRO/100 Ethernet card has its own separate
   driver.  Please read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10778,7 +11029,7 @@
 CONFIG_EEXPRESS
   If you have an EtherExpress16 network (Ethernet) card, say Y and
   read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  Note that the Intel
+  <http://www.tldp.org/docs.html#howto>.  Note that the Intel
   EtherExpress16 card used to be regarded as a very poor choice
   because the driver was very unreliable. We now have a new driver
   that should do better.
@@ -10793,7 +11044,7 @@
 CONFIG_HAMACHI
   If you have a Gigabit Ethernet card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -10805,7 +11056,7 @@
 CONFIG_HPLAN_PLUS
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10817,7 +11068,7 @@
 CONFIG_HPLAN
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10829,7 +11080,7 @@
 CONFIG_HP100
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -10841,7 +11092,7 @@
 CONFIG_NE2000
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  Many Ethernet cards
+  <http://www.tldp.org/docs.html#howto>.  Many Ethernet cards
   without a specific driver are compatible with NE2000.
 
   If you have a PCI NE2000 card however, say N here and Y to "PCI
@@ -10877,13 +11128,13 @@
 CONFIG_SK_G16
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 NE/2 (ne2000 MCA version) support
 CONFIG_NE2_MCA
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10924,7 +11175,7 @@
 CONFIG_NET_PCI
   This is another class of network cards which attach directly to the
   bus. If you have one of those, say Y and read the Ethernet-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause the configurator to skip all
@@ -10936,7 +11187,7 @@
 CONFIG_PCNET32
   If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
   answer Y here and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10948,7 +11199,7 @@
 CONFIG_AC3200
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10960,7 +11211,7 @@
 CONFIG_LNE390
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -10972,7 +11223,7 @@
 CONFIG_NE3210
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  Note that this driver
+  <http://www.tldp.org/docs.html#howto>.  Note that this driver
   will NOT WORK for NE3200 cards as they are completely different.
 
   This driver is also available as a module ( = code which can be
@@ -10985,7 +11236,7 @@
 CONFIG_APRICOT
   If you have a network (Ethernet) controller of this type, say Y and
   read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -10999,7 +11250,7 @@
   These include the DE425, DE434, DE435, DE450 and DE500 models.  If
   you have a network card of this type, say Y and read the
   Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. More specific
+  <http://www.tldp.org/docs.html#howto>. More specific
   information is contained in
   <file:Documentation/networking/de4x5.txt>.
 
@@ -11018,7 +11269,7 @@
   (smc9332dst), you can also try the driver for "Generic DECchip"
   cards, above.  However, most people with a network card of this type
   will say Y here.) Do read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  More specific
+  <http://www.tldp.org/docs.html#howto>.  More specific
   information is contained in 
   <file:Documentation/networking/tulip.txt>.
 
@@ -11050,7 +11301,7 @@
   PCI/EISA Ethernet switch cards. These include the SE-4 and the SE-6
   models.  If you have a network card of this type, say Y and read the
   Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.  More specific
+  <http://www.tldp.org/docs.html#howto>.  More specific
   information is contained in <file:Documentation/networking/dgrs.txt>.
 
   This driver is also available as a module ( = code which can be
@@ -11063,7 +11314,7 @@
 CONFIG_EEPRO100
   If you have an Intel EtherExpress PRO/100 PCI network (Ethernet)
   card, say Y and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -11089,11 +11340,17 @@
   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
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -11106,7 +11363,7 @@
   If you have a PCI Ethernet network card based on the ThunderLAN chip
   which is supported by this driver, say Y and read the
   Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   Devices currently supported by this driver are Compaq Netelligent,
   Compaq NetFlex and Olicom cards.  Please read the file
@@ -11159,7 +11416,7 @@
 CONFIG_ES3210
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -11222,7 +11479,7 @@
   (Ethernet) card, and this is the Linux driver for it. Note that the
   IBM Thinkpad 300 is compatible with the Z-Note and is also supported
   by this driver. Read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 Philips SAA9730 Ethernet support
 CONFIG_LAN_SAA9730
@@ -11236,7 +11493,7 @@
   Cute little network (Ethernet) devices which attach to the parallel
   port ("pocket adapters"), commonly used with laptops. If you have
   one of those, say Y and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to plug a network (or some other) card into the PCMCIA
   (or PC-card) slot of your laptop instead (PCMCIA is the standard for
@@ -11256,7 +11513,7 @@
 CONFIG_ATP
   This is a network (Ethernet) device which attaches to your parallel
   port. Read <file:drivers/net/atp.c> as well as the Ethernet-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>, if you
+  available from <http://www.tldp.org/docs.html#howto>, if you
   want to use this.  If you intend to use this driver, you should have
   said N to the "Parallel printer support", because the two drivers
   don't like each other.
@@ -11271,7 +11528,7 @@
   This is a network (Ethernet) device which attaches to your parallel
   port. Read <file:Documentation/networking/DLINK.txt> as well as the
   Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, if you want to use
+  <http://www.tldp.org/docs.html#howto>, if you want to use
   this. It is possible to have several devices share a single parallel
   port and it is safe to compile the corresponding drivers into the
   kernel.
@@ -11287,7 +11544,7 @@
   This is a network (Ethernet) device which attaches to your parallel
   port. Read <file:Documentation/networking/DLINK.txt> as well as the
   Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, if you want to use
+  <http://www.tldp.org/docs.html#howto>, if you want to use
   this. It is possible to have several devices share a single parallel
   port and it is safe to compile the corresponding drivers into the
   kernel.
@@ -11306,14 +11563,14 @@
   connected to such a Token Ring network and want to use your Token
   Ring card under Linux, say Y here and to the driver for your
   particular card below and read the Token-Ring mini-HOWTO, available
-  from <http://www.linuxdoc.org/docs.html#howto>. Most people can
+  from <http://www.tldp.org/docs.html#howto>. Most people can
   say N here.
 
 IBM Tropic chipset based adapter support
 CONFIG_IBMTR
   This is support for all IBM Token Ring cards that don't use DMA. If
   you have such a beast, say Y and read the Token-Ring mini-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   Warning: this driver will almost definitely fail if more than one
   active Token Ring card is present.
@@ -11330,7 +11587,7 @@
   Wake On Lan, and PCI 100/16/4 adapters.
 
   If you have such an adapter, say Y and read the Token-Ring
-  mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
+  mini-HOWTO, available from <http://www.tldp.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).
@@ -11346,7 +11603,7 @@
   This is support for IBM Lanstreamer PCI Token Ring Cards.
 
   If you have such an adapter, say Y and read the Token-Ring
-  mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
+  mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>.
 
   This driver is also available as a modules ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -11366,7 +11623,7 @@
 
   If you have such an adapter and would like to use it, say Y and
   read the Token-Ring mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   Also read the file <file:Documentation/networking/tms380tr.txt> or
   check <http://www.auk.cx/tms380tr/>.
@@ -11431,7 +11688,7 @@
 
   If you have such an adapter and would like to use it, say Y or M and
   read the Token-Ring mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto> and the file
+  <http://www.tldp.org/docs.html#howto> and the file
   <file:Documentation/networking/smctr.txt>.
 
   This driver is also available as a module ( = code which can be
@@ -11439,6 +11696,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.tldp.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
@@ -11615,7 +11890,7 @@
 CONFIG_CD_NO_IDESCSI
   If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
   here, otherwise N. Read the CD-ROM-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause the configurator to skip all
@@ -11893,7 +12168,7 @@
   usage (also called disk quotas). Currently, it works only for the
   ext2 file system. You need additional software in order to use quota
   support; for details, read the Quota mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. Probably the quota
+  <http://www.tldp.org/docs.html#howto>. Probably the quota
   support is only useful for multi user systems. If unsure, say N.
 
 Memory Technology Device (MTD) support
@@ -12221,7 +12496,7 @@
 CONFIG_MTD_PHYSMAP_BUSWIDTH
   This is the total width of the data bus of the flash devices
   in octets. For example, if you have a data bus width of 32
-  bits, you would set the bus width octect value to 4. This is
+  bits, you would set the bus width octet value to 4. This is
   used internally by the CFI drivers.
 
 Flash chip mapping on Sun Microsystems boardsets
@@ -12376,7 +12651,7 @@
   NAND flash device internally checks only bits transitioning
   from 1 to 0. There is a rare possibility that even though the
   device thinks the write was successful, a bit could have been
-  flipped accidentaly due to device wear, gamma rays, whatever.
+  flipped accidentally due to device wear, gamma rays, whatever.
   Enable this if you are really paranoid.
 
 Support for the SPIA board
@@ -12661,18 +12936,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 +12946,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 +13031,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 +13046,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 +13064,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 +13230,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 +13302,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 +13600,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 +13694,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 +13951,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
@@ -13766,7 +14117,7 @@
   kernels can talk to each other, the host, and with the host's help,
   machines on the outside world.
 
-  For more information, including explations of the networking and
+  For more information, including explanations of the networking and
   sample configurations, see
   <http://user-mode-linux.sourceforge.net/networking.html>.
 
@@ -13991,10 +14342,10 @@
   by about 44 KB.
 
   The Ext2fs-Undeletion mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, gives information about
+  <http://www.tldp.org/docs.html#howto>, gives information about
   how to retrieve deleted files on ext2fs file systems.
 
-  To change the behavior of ext2 file systems, you can use the tune2fs
+  To change the behaviour of ext2 file systems, you can use the tune2fs
   utility ("man tune2fs"). To modify attributes of files and
   directories on ext2 file systems, use chattr ("man chattr").
 
@@ -14035,7 +14386,7 @@
   system.
 
   To add a journal on an existing ext2 file system or change the
-  behavior of ext3 file systems, you can use the tune2fs utility ("man
+  behaviour of ext3 file systems, you can use the tune2fs utility ("man
   tune2fs").  To modify attributes of files and directories on ext3
   file systems, use chattr ("man chattr").  You need to be using
   e2fsprogs version 1.20 or later in order to create ext3 journals
@@ -14066,7 +14417,7 @@
 
 JBD (ext3) debugging support
 CONFIG_JBD_DEBUG
-  If you are using the ext3 journaled file system (or potentially any
+  If you are using the ext3 journalling file system (or potentially any
   other file system/device using JBD), this option allows you to
   enable debugging output while the system is running, in order to
   help track down any problems you are having.  By default the
@@ -14177,7 +14528,7 @@
   Ramfs is a file system which keeps all files in RAM. It allows
   read and write access.
 
-  It is more of an programming example than a useable file system.  If
+  It is more of an programming example than a usable file system.  If
   you need a file system which lives in RAM with limit checking use
   tmpfs.
 
@@ -14195,7 +14546,7 @@
   driver.  If you have a CD-ROM drive and want to do more with it than
   just listen to audio CDs and watch its LEDs, say Y (and read
   <file:Documentation/filesystems/isofs.txt> and the CD-ROM-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>), thereby
+  available from <http://www.tldp.org/docs.html#howto>), thereby
   enlarging your kernel by about 27 KB; otherwise say N.
 
   If you want to compile this as a module ( = code which can be
@@ -14293,7 +14644,7 @@
   they are compressed; to access compressed MSDOS partitions under
   Linux, you can either use the DOS emulator DOSEMU, described in the
   DOSEMU-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, or try dmsdosfs in
+  <http://www.tldp.org/docs.html#howto>, or try dmsdosfs in
   <ftp://ibiblio.org/pub/Linux/system/filesystems/dosfs/>. If you
   intend to use dosemu with a non-compressed MSDOS partition, say Y
   here) and MSDOS floppies. This means that file access becomes
@@ -14402,9 +14753,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
@@ -14450,7 +14808,7 @@
   programs nfsd and mountd (but does not need to have NFS file system
   support enabled in its kernel). NFS is explained in the Network
   Administrator's Guide, available from
-  <http://www.linuxdoc.org/docs.html#guide>, on its man page: "man
+  <http://www.tldp.org/docs.html#guide>, on its man page: "man
   nfs", and in the NFS-HOWTO.
 
   A superior but less widely used alternative to NFS is provided by
@@ -14513,7 +14871,7 @@
   as well.
 
   Please read the NFS-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   The NFS server is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -14674,10 +15032,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 +15052,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
@@ -14884,7 +15247,7 @@
 
   Windows 2000 introduced the concept of Dynamic Disks to get around
   the limitations of the PC's partitioning scheme.  The Logical Disk
-  Manager allows the user to repartion a disk and create spanned,
+  Manager allows the user to repartition a disk and create spanned,
   mirrored, striped or RAID volumes, all without the need for
   rebooting.
 
@@ -15078,7 +15441,7 @@
   works only if the Windows machines use TCP/IP as the underlying
   transport protocol, and not NetBEUI.  For details, read
   <file:Documentation/filesystems/smbfs.txt> and the SMB-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   Note: if you just want your box to act as an SMB *server* and make
   files and printing services available to Windows clients (which need
@@ -15159,7 +15522,7 @@
   to mount NetWare file server volumes and to access them just like
   any other Unix directory.  For details, please read the file
   <file:Documentation/filesystems/ncpfs.txt> in the kernel source and
-  the IPX-HOWTO from <http://www.linuxdoc.org/docs.html#howto>.
+  the IPX-HOWTO from <http://www.tldp.org/docs.html#howto>.
 
   You do not have to say Y here if you want your Linux box to act as a
   file *server* for Novell NetWare clients.
@@ -15317,8 +15680,8 @@
   say Y here if you want to include the Latin 2 codepage used by DOS
   for much of Central and Eastern Europe. It has all the required
   characters for these languages: Albanian, Croatian, Czech, English,
-  Finnish, Hungarian, Irish, German, Polish, Romanian, Serbian (Latin
-  transcription), Slovak, Slovenian, and Sorbian.
+  Finnish, Hungarian, Irish, German, Polish, Rumanian, Serbian (Latin
+  transcription), Slovak, Slovenian, and Serbian.
 
 Codepage 855 (Cyrillic)
 CONFIG_NLS_CODEPAGE_855
@@ -15728,7 +16091,7 @@
 CPM SCC Ethernet
 CONFIG_SCC_ENET
   Enable Ethernet support via the Motorola MPC8xx serial
-  commmunications controller.
+  communications controller.
 
 # Choice: scc_ethernet
 Ethernet on SCC1
@@ -15746,7 +16109,7 @@
 
 Use Big CPM Ethernet Buffers
 CONFIG_ENET_BIG_BUFFERS
-  Allocate large buffers for MPC8xx Etherenet.  Increases throughput
+  Allocate large buffers for MPC8xx Ethernet.  Increases throughput
   and decreases the likelihood of dropped packets, but costs memory.
 
 Apple Desktop Bus (ADB) support
@@ -15793,7 +16156,7 @@
 HIL keyboard support
 CONFIG_HIL
   The "Human Interface Loop" is a older, 8-channel USB-like controller
-  used in Hewlette Packard PA-RISC based machines.  There are a few
+  used in Hewlett Packard PA-RISC based machines.  There are a few
   cases where it is seen on PC/MAC architectures as well, usually also
   manufactured by HP.  This driver is based off MACH and BSD drivers,
   and implements support for a keyboard attached to the HIL port.
@@ -15844,14 +16207,14 @@
   If you want to include a driver to support Nubus or LC-PDS
   Ethernet cards using an NS8390 chipset or its equivalent, say Y
   and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 Macintosh CS89x0 based Ethernet support
 CONFIG_MAC89x0
   Support for CS89x0 chipset based Ethernet cards.  If you have a
   Nubus or LC-PDS network (Ethernet) card of this type, say Y and
   read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -15864,7 +16227,7 @@
   Support for the onboard AMD 79C940 MACE Ethernet controller used in
   the 660AV and 840AV Macintosh.  If you have one of these Macintoshes
   say Y and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 Macintosh SONIC based Ethernet support (onboard, NuBus, LC, CS)
 CONFIG_MACSONIC
@@ -15872,7 +16235,7 @@
   the onboard Ethernet in many Quadras as well as some LC-PDS,
   a few Nubus and all known Comm Slot Ethernet cards.  If you have
   one of these say Y and read the Ethernet-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -15885,14 +16248,14 @@
   This is the NCR 5380 SCSI controller included on most of the 68030
   based Macintoshes.  If you have one of these say Y and read the
   SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 Macintosh NCR53c9[46] SCSI support
 CONFIG_SCSI_MAC_ESP
   This is the NCR 53c9x SCSI controller found on most of the 68040
   based Macintoshes.  If you have one of these say Y and read the
   SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.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).
@@ -16225,7 +16588,7 @@
   box (as opposed to using a serial printer; if the connector at the
   printer has 9 or 25 holes ["female"], then it's serial), say Y.
   Also read the Printing-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   It is possible to share one parallel port among several devices
   (e.g. printer and ZIP drive) and it is safe to compile the
@@ -16394,6 +16757,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 +16862,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
@@ -16541,7 +16933,7 @@
   MouseSystem or Microsoft mouse (made by Logitech) that plugs into a
   COM port (rectangular with 9 or 25 pins). These people say N here.
   If you have something else, read the Busmouse-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. This HOWTO contains
+  <http://www.tldp.org/docs.html#howto>. This HOWTO contains
   information about all non-serial mice, not just bus mice.
 
   If you have a laptop, you either have to check the documentation or
@@ -16558,7 +16950,7 @@
   generally a round connector with 9 pins. Note that the newer mice
   made by Logitech don't use the Logitech protocol anymore; for those,
   you don't need this option.  You want to read the Busmouse-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -16578,7 +16970,7 @@
 
   Although PS/2 mice are not technically bus mice, they are explained
   in detail in the Busmouse-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   When using a PS/2 mouse, you can get problems if you want to use the
   mouse both on the Linux console and under X. Using the "-R" option
@@ -16591,7 +16983,7 @@
   This is a certain kind of PS/2 mouse used on the TI Travelmate. If
   you are unsure, try first to say N here and come back if the mouse
   doesn't work. Read the Busmouse-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
 PC110 digitizer pad support
 CONFIG_PC110_PAD
@@ -16609,7 +17001,7 @@
   These animals (also called Inport mice) are connected to an
   expansion board using a round connector with 9 pins. If this is what
   you have, say Y and read the Busmouse-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you are unsure, say N and read the HOWTO nevertheless: it will
   tell you what you have. Also be aware that several vendors talk
@@ -16625,7 +17017,7 @@
 CONFIG_ADBMOUSE
   Say Y here if you have this type of bus mouse (4 pin connector) as
   is common on Macintoshes.  You may want to read the Busmouse-HOWTO,
-  available from <http://www.linuxdoc.org/docs.html#howto>.
+  available from <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -16639,7 +17031,7 @@
   most mice by ATI are actually Microsoft busmice; you should say Y to
   "Microsoft busmouse support" above if you have one of those.  Read
   the Busmouse-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -17188,7 +17580,7 @@
   page on the WWW at
   <http://www.cs.utexas.edu/users/kharker/linux-laptop/> and the
   Battery Powered Linux mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   Note that, even if you say N here, Linux on the x86 architecture
   will issue the hlt instruction if nothing is to be done, thereby
@@ -17305,7 +17697,7 @@
   In order to use APM, you will need supporting software. For location
   and more information, read <file:Documentation/pm.txt> and the
   Battery Powered Linux mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   This driver does not spin down disk drives (see the hdparm(8)
   manpage ("man 8 hdparm") for that), and it doesn't turn off
@@ -17551,6 +17943,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 +17995,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,12 +18017,34 @@
   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
   the CPU on Toshiba portables with a genuine Toshiba BIOS. It does
-  not work on models with a Pheonix BIOS. The System Management Mode
+  not work on models with a Phoenix BIOS. The System Management Mode
   is used to set the BIOS and power saving options on Toshiba portables.
 
   For information on utilities to make use of this driver see the
@@ -17690,6 +18127,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
@@ -18142,7 +18601,7 @@
   interrupt and DMA channel), because you will be asked for it.
 
   You want to read the Sound-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. General information about
+  <http://www.tldp.org/docs.html#howto>. General information about
   the modular sound system is contained in the files
   <file:Documentation/sound/Introduction>.  The file
   <file:Documentation/sound/README.OSS> contains some slightly
@@ -18184,7 +18643,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 +18819,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
@@ -18636,7 +19101,7 @@
   Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or
   similar sound card. See <file:Documentation/sound/README.awe>,
   <file:Documentation/sound/AWE32> and the Soundblaster-AWE
-  mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>
+  mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
   for more info.
 
 Gallant Audio Cards (SC-6000 and SC-6600 based)
@@ -18707,6 +19172,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 +19221,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
@@ -18919,8 +19427,21 @@
 
 Intel ICH audio support
 CONFIG_SOUND_ICH
-  Support for integral audio in Intel's I/O Controller Hub (ICH)
-  chipset, as used on the 810/820/840 motherboards.
+  Supports the following chipsets:
+  
+  Intel ICH 82801AA
+  Intel ICH 82901AB
+  Intel 440 MX
+  Intel ICH2
+  Intel ICH3
+  SiS 7012
+  NVidia nForce
+  AMD 768
+  
+  These are audio drivers for integral audio in chipsets of motherboards.
+  
+  Intel's I/O Controller Hub (ICH) is used on 810/815/820/840/845/845D/850 motherboards.
+  SiS 7012 is used on 645/735/745 motherboards.
 
 Verbose initialization
 CONFIG_SOUND_TRACEINIT
@@ -18943,8 +19464,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 +19476,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
@@ -18997,7 +19522,7 @@
 
 Support for Globespan IVR board
 CONFIG_MIPS_IVR
-  This is an evaluation board built by Globespan to showcase thir
+  This is an evaluation board built by Globespan to showcase their
   iVR (Internet Video Recorder) design. It utilizes a QED RM5231
   R5000 MIPS core. More information can be found out their website
   located at <http://www.globespan.net/products/product4.html>P. Say Y
@@ -19005,7 +19530,7 @@
 
 Support for Alchemy Semi PB1000 board
 CONFIG_MIPS_PB1000
-  This is an evaluation board built by Alchemy Semiconducttor to
+  This is an evaluation board built by Alchemy Semiconductor to
   showcase their Au1000 Internet Edge Processor. It is SOC design
   containing a MIPS32 core running at 266/400/500MHz with many
   integrated peripherals. Further information can be found at their
@@ -19504,6 +20029,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 +20383,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 +20404,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 +20417,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 +20428,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 +20464,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 +20489,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 +20607,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 +20621,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 +20633,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
@@ -20189,8 +20772,8 @@
 
 Support for ST-RAM as swap space
 CONFIG_STRAM_SWAP
-  Some Atari 68k macines (including the 520STF and 1020STE) divide
-  their addressible memory into ST and TT sections.  The TT section
+  Some Atari 68k machines (including the 520STF and 1020STE) divide
+  their addressable memory into ST and TT sections.  The TT section
   (up to 512MB) is the main memory; the ST section (up to 4MB) is
   accessible to the built-in graphics board, runs slower, and is
   present mainly for backward compatibility with older machines.
@@ -20348,6 +20931,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 +21005,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
@@ -20801,7 +21408,7 @@
 Average high and low temp
 CONFIG_TAU_AVERAGE
   The TAU hardware can compare the temperature to an upper and lower bound.
-  The default behavior is to show both the upper and lower bound in
+  The default behaviour is to show both the upper and lower bound in
   /proc/cpuinfo. If the range is large, the temperature is either changing
   a lot, or the TAU hardware is broken (likely on some G4's). If the range
   is small (around 4 degrees), the temperature is relatively stable.
@@ -21662,6 +22269,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 +23028,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
@@ -22568,7 +23187,7 @@
 MFM hard disk support
 CONFIG_BLK_DEV_MFM
   Support the MFM hard drives on the Acorn Archimedes both
-  on-board the A4x0 motherboards and via the Acorn MFM podules.
+  on-board the A4x0 motherboards and via the Acorn MFM modules.
   Drives up to 64MB are supported. If you haven't got one of these
   machines or drives just say N.
 
@@ -22641,7 +23260,7 @@
   some user-space utilities like irattach.  For more information, see
   the file <file:Documentation/networking/irda.txt>.  You also want to
   read the IR-HOWTO, available at
-  <http://www.linuxdoc.org/docs.html#howto>.
+  <http://www.tldp.org/docs.html#howto>.
 
   If you want to exchange bits of data (vCal, vCard) with a PDA, you
   will need to install some OBEX application, such as OpenObex :
@@ -22719,7 +23338,7 @@
   will also need a working PPP subsystem (driver, daemon and
   config)...
 
-  IrNET is an alternate way to tranfer TCP/IP traffic over IrDA.  It
+  IrNET is an alternate way to transfer TCP/IP traffic over IrDA.  It
   uses synchronous PPP over a set of point to point IrDA sockets.  You
   can use it between Linux machine or with W2k.
 
@@ -22767,7 +23386,7 @@
   device driver.  If you want to compile it as a module (irda-usb.o),
   say M here and read <file:Documentation/modules.txt>.  IrDA-USB
   support the various IrDA USB dongles available and most of their
-  pecularities.  Those dongles plug in the USB port of your computer,
+  peculiarities.  Those dongles plug in the USB port of your computer,
   are plug and play, and support SIR and FIR (4Mbps) speeds.  On the
   other hand, those dongles tend to be less efficient than a FIR
   chipset.
@@ -23279,7 +23898,7 @@
 
 Etrax bus waitstates
 CONFIG_ETRAX_DEF_R_WAITSTATES
-  Waitstates for SRAM, Flash and peripherials (not DRAM).  95f8 is a
+  Waitstates for SRAM, Flash and peripherals (not DRAM).  95f8 is a
   good choice for most Axis products...
 
 Etrax bus configuration
@@ -23443,13 +24062,13 @@
 
 Etrax100 RS-485 mode on PA
 CONFIG_ETRAX_RS485_ON_PA
-  Control Driver Output Enable on RS485 tranceiver using a pin on PA
+  Control Driver Output Enable on RS485 transceiver using a pin on PA
   port:
           Axis 2400/2401 uses PA 3.
 
 Etrax100 RS-485 mode on PA bit
 CONFIG_ETRAX_RS485_ON_PA_BIT
-  Control Driver Output Enable on RS485 tranceiver using a this bit
+  Control Driver Output Enable on RS485 transceiver using a this bit
   on PA port.
 
 Ser0 DTR on PB bit
@@ -24109,12 +24728,12 @@
 CONFIG_SH_GENERIC
   Select Generic if configuring for a generic SuperH system.
   The "generic" option compiles in *all* the possible hardware
-  support and relies on the sh_mv= kernel commandline option to choose
+  support and relies on the sh_mv= kernel command option to choose
   at runtime which routines to use.  "MV" stands for "machine vector";
   each of the machines below is described by a machine vector.
 
   Select SolutionEngine if configuring for a Hitachi SH7709
-  or SH7750/7750S evalutation board.
+  or SH7750/7750S evaluation board.
 
   Select Overdrive if configuring for a ST407750 Overdrive board.
   More information at
@@ -24162,12 +24781,12 @@
 SolutionEngine
 CONFIG_SH_SOLUTION_ENGINE
   Select SolutionEngine if configuring for a Hitachi SH7709
-  or SH7750 evalutation board.
+  or SH7750 evaluation board.
 
 7751 SolutionEngine
 CONFIG_SH_7751_SOLUTION_ENGINE
   Select 7751 SolutionEngine if configuring for a Hitachi SH7751
-  evalutation board.
+  evaluation board.
 
 Overdrive
 CONFIG_SH_OVERDRIVE
@@ -24382,6 +25001,285 @@
   information:  http://www.candelatech.com/~greear/vlan.html  If unsure,
   you can safely say 'N'.
 
+ARC console support
+CONFIG_ARC_CONSOLE
+  Support for the PROM-based console on MIPS machines built according
+  to the Advanced Risc Computing specification, which is now (2001)
+  dead.  These included boxes from Deskstation, Acer, Olivetti and
+  NEC.  There is a history at <http://www.openbsd.org/arc.html>.
+
+AUTCPU12
+CONFIG_ARCH_AUTCPU12
+  Say Y if you intend to run the kernel on the autronix autcpu12
+  board. This board is based on a Cirrus Logic CS89712.
+
+IT8172 IDE support
+CONFIG_BLK_DEV_IT8172
+  Say Y here to support the on-board IDE controller 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>.
+
+Use chscs for Common I/O
+CONFIG_CHSC
+  Select this option if you want the s390 common I/O layer to use information
+  obtained by channel subsystem calls. This will enable Linux to process link
+  failures and resource accessibility events. Moreover, if you have procfs
+  enabled, you'll be able to toggle chpids logically offline and online. Even
+  if you don't understand what this means, you should say "Y".
+
+Support ARM926T processor
+CONFIG_CPU_ARM926T
+  This is a variant of the ARM920.  It has slightly different
+  instruction sequences for cache and TLB operations.  Curiously,
+  there is no documentation on it at the ARM corporate website.
+
+  Say Y if you want support for the ARM926T processor.
+  Otherwise, say N.
+
+Support CPU clock change (EXPERIMENTAL)
+CONFIG_CPU_FREQ
+  CPU clock scaling allows you to change the clock speed of the
+  running CPU on the fly. This is a nice method to save battery power,
+  because the lower the clock speed, the less power the CPU
+  consumes. Note that this driver doesn't automatically change the CPU
+  clock speed, you need some userland tools (which still have to be
+  written) to implement the policy. If you don't understand what this
+  is all about, it's safe to say 'N'.
+
+Automatic activation of DIAG module
+CONFIG_DASD_AUTO_DIAG
+  Enable this option if you want your DIAG discipline module loaded
+  on DASD driver startup.
+
+Automatic activation of ECKD module
+CONFIG_DASD_AUTO_ECKD
+  Enable this option if you want your ECKD discipline module loaded
+  on DASD driver startup.
+
+Automatic activation of FBA  module
+CONFIG_DASD_AUTO_FBA
+  Enable this option if you want your FBA discipline module loaded
+  on DASD driver startup.
+
+SiS
+CONFIG_DRM_SIS
+  Choose this option if you have a SIS graphics card. AGP support is
+  required for this driver to work.
+
+Etrax Ethernet slave support (over lp0/1)
+CONFIG_ETRAX_ETHERNET_LPSLAVE
+  This option enables a slave ETRAX 100 or ETRAX 100LX, connected to a
+  master ETRAX 100 or ETRAX 100LX through par0 and par1, to act as an
+  Ethernet controller.
+
+Slave has its own LEDs
+CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+  Enable if the slave has it's own LEDs.
+
+ATA/IDE support
+CONFIG_ETRAX_IDE
+  Enable this to get support for ATA/IDE.  You can't use parallel
+  ports or SCSI ports at the same time.
+
+LED on when link
+CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK
+
+  Selecting LED_on_when_link will light the LED when there is a
+  connection and will flash off when there is activity.
+
+  Selecting LED_on_when_activity will light the LED only when
+  there is activity.
+
+  This setting will also affect the behaviour of other activity LEDs
+  e.g. Bluetooth.
+
+Power button bit on port G
+CONFIG_ETRAX_POWERBUTTON_BIT
+  Configure where power button is connected.
+
+Root device name
+CONFIG_ETRAX_ROOT_DEVICE
+  Specifies the device that should be mounted as root file system
+  when booting from flash. The axisflashmap driver adds an additional
+  mtd partition for the appended root file system image, so this option
+  should normally be the mtdblock device for the partition after the
+  last partition in the partition table.
+
+Serial port 0 enabled
+CONFIG_ETRAX_SERIAL_PORT0
+  Enables the ETRAX 100 serial driver for ser0 (ttyS0)
+  Normally you want this on, unless you use external DMA 1 that uses
+  the same DMA channels.
+
+Shutdown bit on port CSP0
+CONFIG_ETRAX_SHUTDOWN_BIT
+  Configure what pin on CSPO-port that is used for controlling power
+  supply.
+
+Software Shutdown Support
+CONFIG_ETRAX_SOFT_SHUTDOWN
+  Enable this if Etrax is used with a power-supply that can be turned
+  off and on with PS_ON signal. Gives the possibility to detect
+  powerbutton and then do a power off after unmounting disks.
+
+Disable watchdog during Oops printouts
+CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+  By enabling this you make sure that the watchdog does not bite while
+  printing oopses. Recommended for development systems but not for
+  production releases.
+
+Compaq iPAQ Handheld sleeve support
+CONFIG_H3600_SLEEVE
+  Choose this option to enable support for extension packs (sleeves)
+  for the Compaq iPAQ H3XXX series of handheld computers.  This option
+  is required for the CF, PCMCIA, Bluetooth and GSM/GPRS extension
+  packs.
+
+AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)
+CONFIG_HISAX_FRITZ_PCIPNP
+  This enables the driver for the AVM Fritz!Card PCI, Fritz!Card PCI v2
+  and Fritz!Card PnP.
+  (the latter also needs you to select "ISA Plug and Play support"
+  from the menu "Plug and Play configuration")
+
+IBM PCI Hotplug driver
+CONFIG_HOTPLUG_PCI_IBM
+  Say Y here if you have a motherboard with a IBM PCI Hotplug
+  controller.
+
+  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 cpqphp.o. If you want to compile it
+  as a module, say M here and read Documentation/modules.txt.
+
+  When in doubt, say N.
+
+Control-Program Identification
+CONFIG_HWC_CPI
+  This option enables the hardware console interface for system
+  identification This is commonly used for workload management and
+  gives you a nice name for the system on the service element.
+  Please select this option as a module since built-in operation is
+  completely untested.
+  You should only select this option if you know what you are doing,
+  need this feature and intend to run your kernel in LPAR.
+
+Enable autotest (llsc). Option to run cache test instead of booting
+CONFIG_IA64_SGI_AUTOTEST
+  Build a kernel used for hardware validation. If you include the
+  keyword "autotest" on the boot command line, the kernel does NOT boot.
+  Instead, it starts all cpus and runs cache coherency tests instead.
+
+  If unsure, say N.
+
+IEC61883-6 (Audio transmission) support
+CONFIG_IEEE1394_AMDTP
+  This option enables the Audio & Music Data Transmission Protocol
+  (IEC61883-6) driver, which implements audio transmission over
+  IEEE1394.
+
+  The userspace interface is documented in amdtp.h.
+
+  If you want to compile this 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 amdtp.o.
+
+IEC61883-1 Plug support
+CONFIG_IEEE1394_CMP
+  This option enables the Connection Management Procedures
+  (IEC61883-1) driver, which implements input and output plugs.
+
+  If you want to compile this 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 amdtp.o.
+
+OHCI-DV I/O support
+CONFIG_IEEE1394_DV1394
+  This driver allows you to transmit and receive DV (digital video)
+  streams on an OHCI-1394 card using a simple frame-oriented
+  interface.
+
+  The user-space API for dv1394 is documented in dv1394.h.
+
+  If you want to compile this 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 dv1394.o.
+
+Ethernet over 1394
+CONFIG_IEEE1394_ETH1394
+  Extremely Experimental! This driver is a Linux specific way to use your
+  IEEE1394 Host as an Ethernet type device. This is _NOT_ IP1394.
+
+Support for older IT8172 (Rev C)
+CONFIG_IT8172_REVC
+  Say Y here to support the older, Revision C version of 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>.
+
+Enable Smart Card Reader 0 Support
+CONFIG_IT8172_SCR0
+  Say Y here to support smart-card reader 0 (SCR0) 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>.
+
+Enable Smart Card Reader 1 Support
+CONFIG_IT8172_SCR1
+  Say Y here to support smart-card reader 1 (SCR1) 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>.
+
+IT8172 IDE Tuning support
+CONFIG_IT8172_TUNING
+  Say Y here to support tuning the ITE8172's IDE interface.  This makes
+  it possible to set DMA channel or PIO opration and the transfer rate.
+
+Process warning machine checks
+CONFIG_MACHCHK_WARNING
+  Select this option if you want the machine check handler on IBM S/390 or
+  zSeries to process warning machine checks (e.g. on power failures).
+  If unsure, say "Y".
+
+Pseudo page fault support
+CONFIG_PFAULT
+  Select this option, if you want to use PFAULT pseudo page fault
+  handling under VM. If running native or in LPAR, this option
+  has no effect. If your VM does not support PFAULT, PAGEEX
+  pseudo page fault handling will be used.
+  Note that VM 4.2 supports PFAULT but has a bug in its
+  implementation that causes some problems.
+  Everybody who wants to run Linux under VM != VM4.2 should select
+  this option.
+
+Enable protocol mode for the L1 console
+CONFIG_SERIAL_SGI_L1_PROTOCOL
+  Uses protocol mode instead of raw mode for the level 1 console on the
+  SGI SN (Scalable NUMA) platform for IA64.  If you are compiling for
+  an SGI SN box then Y is the recommended value, otherwise say N.
+
+VM shared kernel support
+CONFIG_SHARED_KERNEL
+  Select this option, if you want to share the text segment of the
+  Linux kernel between different VM guests. This reduces memory
+  usage with lots of guests but greatly increases kernel size.
+  You should only select this option if you know what you are
+  doing and want to exploit this feature.
+
+New bus configuration (EXPERIMENTAL)  
+CONFIG_TULIP_MWI
+  This configures your Tulip card specifically for the card and
+  system cache line size type you are using.
+
+  This is experimental code, not yet tested on many boards.
+
+  If unsure, say N.
+
 #
 # A couple of things I keep forgetting:
 #   capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/DMA-mapping.txt linux/Documentation/DMA-mapping.txt
--- linux.orig/Documentation/DMA-mapping.txt	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/DMA-mapping.txt	2002-07-20 01:08:37.000000000 +0000
@@ -8,7 +8,7 @@
 Most of the 64bit platforms have special hardware that translates bus
 addresses (DMA addresses) into physical addresses.  This is similar to
 how page tables and/or a TLB translates virtual addresses to physical
-addresses on a cpu.  This is needed so that e.g. PCI devices can
+addresses on a CPU.  This is needed so that e.g. PCI devices can
 access with a Single Address Cycle (32bit DMA address) any page in the
 64bit physical address space.  Previously in Linux those 64bit
 platforms had to set artificial limits on the maximum RAM size in the
@@ -37,7 +37,7 @@
 			 What memory is DMA'able?
 
 The first piece of information you must know is what kernel memory can
-be used with the DMA mapping facilitites.  There has been an unwritten
+be used with the DMA mapping facilities.  There has been an unwritten
 set of rules regarding this, and this text is an attempt to finally
 write them down.
 
@@ -106,7 +106,7 @@
 3) Ignore this device and do not initialize it.
 
 It is recommended that your driver print a kernel KERN_WARNING message
-when you end up performing either #2 or #2.  In this manner, if a user
+when you end up performing either #2 or #3.  In this manner, if a user
 of your driver reports that performance is bad or that the device is not
 even detected, you can ask them for the kernel messages to find out
 exactly why.
@@ -146,7 +146,7 @@
 If your 64-bit device is going to be an enormous consumer of DMA
 mappings, this can be problematic since the DMA mappings are a
 finite resource on many platforms.  Please see the "DAC Addressing
-for Address Space Hungry Devices" setion near the end of this
+for Address Space Hungry Devices" section near the end of this
 document for how to handle this case.
 
 Finally, if your device can only drive the low 24-bits of
@@ -205,7 +205,7 @@
 
 - Consistent DMA mappings which are usually mapped at driver
   initialization, unmapped at the end and for which the hardware should
-  guarantee that the device and the cpu can access the data
+  guarantee that the device and the CPU can access the data
   in parallel and will see updates made by each other without any
   explicit software flushing.
 
@@ -222,12 +222,12 @@
 	- Device firmware microcode executed out of
 	  main memory.
 
-  The invariant these examples all require is that any cpu store
+  The invariant these examples all require is that any CPU store
   to memory is immediately visible to the device, and vice
   versa.  Consistent mappings guarantee this.
 
   IMPORTANT: Consistent DMA memory does not preclude the usage of
-             proper memory barriers.  The cpu may reorder stores to
+             proper memory barriers.  The CPU may reorder stores to
 	     consistent memory just as it may normal memory.  Example:
 	     if it is important for the device to see the first word
 	     of a descriptor updated before the second, you must do
@@ -284,7 +284,7 @@
 the pci_pool interface, described below.
 
 The consistent DMA mapping interfaces, for non-NULL dev, will always
-return a DMA address which is SAC (Single Address Cycle) addressible.
+return a DMA address which is SAC (Single Address Cycle) addressable.
 Even if the device indicates (via PCI dma mask) that it may address
 the upper 32-bits and thus perform DAC cycles, consistent allocation
 will still only return 32-bit PCI addresses for DMA.  This is true
@@ -484,7 +484,7 @@
 of sg entries it mapped them to.
 
 Then you should loop count times (note: this can be less than nents times)
-and use sg_dma_address() and sg_dma_length() macros where you previously
+and use sg_dma_address() and sg_dma_len() macros where you previously
 accessed sg->address and sg->length as shown above.
 
 To unmap a scatterlist, just call:
@@ -622,7 +622,7 @@
 Note that for streaming type mappings you must either use these
 interfaces, or the dynamic mapping interfaces above.  You may not mix
 usage of both for the same device.  Such an act is illegal and is
-guarenteed to put a banana in your tailpipe.
+guaranteed to put a banana in your tailpipe.
 
 However, consistent mappings may in fact be used in conjunction with
 these interfaces.  Remember that, as defined, consistent mappings are
@@ -637,7 +637,7 @@
 use the following interfaces if this routine fails.
 
 Next, DMA addresses using this API are kept track of using the
-dma64_addr_t type.  It is guarenteed to be big enough to hold any
+dma64_addr_t type.  It is guaranteed to be big enough to hold any
 DAC address the platform layer will give to you from the following
 routines.  If you have consistent mappings as well, you still
 use plain dma_addr_t to keep track of those.
@@ -745,7 +745,7 @@
 			 PCI_DMA_FROMDEVICE);
 
 It really should be self-explanatory.  We treat the ADDR and LEN
-seperately, because it is possible for an implementation to only
+separately, because it is possible for an implementation to only
 need the address in order to perform the unmap operation.
 
 			Platform Issues
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/DocBook/Makefile linux/Documentation/DocBook/Makefile
--- linux.orig/Documentation/DocBook/Makefile	2001-11-03 01:13:53.000000000 +0000
+++ linux/Documentation/DocBook/Makefile	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-10-05 19:06:51.000000000 +0000
+++ linux/Documentation/DocBook/kernel-api.tmpl	2002-07-20 01:08:21.000000000 +0000
@@ -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
@@ -268,7 +272,7 @@
 !Edrivers/video/fbcmap.c
      </sect1>
      <sect1><title>Frame Buffer Generic Functions</title>
-!Idrivers/video/fbgen.c
+!Edrivers/video/fbgen.c
      </sect1>
      <sect1><title>Frame Buffer Video Mode Database</title>
 !Idrivers/video/modedb.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	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/DocBook/kernel-hacking.tmpl	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-05-20 00:43:05.000000000 +0000
+++ linux/Documentation/DocBook/kernel-locking.tmpl	2002-07-20 01:08:32.000000000 +0000
@@ -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/DocBook/sis900.tmpl linux/Documentation/DocBook/sis900.tmpl
--- linux.orig/Documentation/DocBook/sis900.tmpl	2000-12-29 22:07:19.000000000 +0000
+++ linux/Documentation/DocBook/sis900.tmpl	2002-07-20 01:08:22.000000000 +0000
@@ -323,8 +323,8 @@
 The 1.06 revision can be found in kernel version later than 2.3.15 and pre-2.2.14, 
 and 1.07 revision can be found in kernel version 2.4.0.
 If you have no prior experience in networking under Linux, please read
-<ULink URL="http://www.linuxdoc.org/">Ethernet HOWTO</ULink> and
-<ULink URL="http://www.linuxdoc.org/">Networking HOWTO</ULink> available from
+<ULink URL="http://www.tldp.org/">Ethernet HOWTO</ULink> and
+<ULink URL="http://www.tldp.org/">Networking HOWTO</ULink> available from
 Linux Documentation Project (LDP).
 </Para>
 
@@ -435,7 +435,7 @@
 Typical values are "10baseT"(twisted-pair 10Mbps Ethernet) or "100baseT"
 (twisted-pair 100Mbps Ethernet). For more information on how to configure 
 network interface, please refer to  
-<ULink URL="http://www.linuxdoc.org/">Networking HOWTO</ULink>.
+<ULink URL="http://www.tldp.org/">Networking HOWTO</ULink>.
 </Para>
 
 <Para>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/IRQ-affinity.txt linux/Documentation/IRQ-affinity.txt
--- linux.orig/Documentation/IRQ-affinity.txt	2000-02-25 06:41:16.000000000 +0000
+++ linux/Documentation/IRQ-affinity.txt	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-08-27 15:59:16.000000000 +0000
+++ linux/Documentation/SubmittingDrivers	2002-07-20 01:08:27.000000000 +0000
@@ -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	2001-12-21 17:41:53.000000000 +0000
+++ linux/Documentation/cachetlb.txt	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/Documentation/cciss.txt	2002-07-20 01:08:26.000000000 +0000
@@ -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/README-sstfb.txt linux/Documentation/fb/README-sstfb.txt
--- linux.orig/Documentation/fb/README-sstfb.txt	2001-09-07 16:28:38.000000000 +0000
+++ linux/Documentation/fb/README-sstfb.txt	2002-07-20 01:08:28.000000000 +0000
@@ -9,12 +9,12 @@
 	combinations and it seems that it works.
 	  The main page is located at <http://sstfb.sourceforge.net>, and if
 	you want the latest version, check out the CVS, as the driver is a work
-	in progress, i feel incomfortable with releasing tarballs of something
+	in progress, I feel incomfortable with releasing tarballs of something
 	not completely working...Don't worry, it's still more than useable
 	(I eat my own dog food)
 
 	  Please read the Bug section, and report any success or failure to me
-	(Ghozlane Toumi <gtoumi@messel.emse.fr>).
+	(Ghozlane Toumi <gtoumi@laposte.net>).
 	  BTW, If you have only one monitor , and you don't feel like playing
 	with the vga passthrou cable, I can only suggest borrowing a screen
 	somewhere... 
@@ -22,8 +22,9 @@
 
 Installation 
 
-	  This driver (should) work on ix86, with any 2.2.x kernel (tested
+	  This driver (should) work on ix86, with "late" 2.2.x kernel (tested
 	with x = 19) and "recent" 2.4.x kernel, as a module or compiled in.
+	  It has been included in mainstream kernel since the infamous 2.4.10.
 	  You can apply the patches found in sstfb/kernel/*-2.{2|4}.x.patch,
 	and copy sstfb.c to linux/drivers/video/, or apply a single patch, 
 	sstfb/patch-2.{2|4}.x-sstfb-yymmdd to your linux source tree.
@@ -41,7 +42,7 @@
 	  module, the 3dfx takes control of the output, so you'll have to
 	  plug the monitor to the "normal" video board in order to issue
 	  the commands, or you can blindly use sst_dbg_vgapass
-          in the tools directory (See Tools). The latest option is pass the
+          in the tools directory (See Tools). The latest solution is pass the
 	  parameter vgapass=1 when insmodding the driver. (See Kernel/Modules
 	  Options)
 
@@ -77,36 +78,39 @@
 	in kernel :  video=sstfb:option1,option2:value2,option3 ...
 	
 	sstfb supports the folowing options :
-	module		kernel		description
 
-	vgapass=1	vgapass		enable or disable VGA passthrou cable
-	vgapass=0	vganopass	when enabled, the monitor will
-					get the signal from the VGA board
-					and not from the voodoo. default nopass
-
-	mem=x		mem:x		force frame buffer memory in MiB
-					allowed values: 1, 2, 4. default detect
-
-	inverse=1	inverse		suposed to enable inverse console.
-					doesn't work ...
-
-	clipping=1	clipping	enable or disable clipping . with
-	clipping=0	noclipping	clipping enabled, all offscreen reads
-					and writes are disgarded. default:
-					enable clipping.
-
-	gfxclk=x	gfxclk:x	force graphic clock frequency (in MHz)
-					becarefull with this option .
-					default is 50Mhz for voodoo1, 75MHz
-					for voodoo2. Be carefull, this one is
-					dangerous. default=auto
-
-	slowpci=0	slowpci		enable or disable fast PCI read/writes
-	slowpci=1	fastpci		default : fastpci
-
-	dev=x		dev:x		attach the driver to device number x
-					0 is the first compatible board (in 
-					lspci order)
+Module		Kernel		Description
+
+vgapass=0	vganopass	Enable or disable VGA passthrou cable.
+vgapass=1	vgapass		When enabled, the monitor will get the signal
+				from the VGA board and not from the voodoo.
+				Default: nopass
+
+mem=x		mem:x		Force frame buffer memory in MiB
+				allowed values: 0, 1, 2, 4.
+				Default: 0 (= autodetect)
+
+inverse=1	inverse		Supposed to enable inverse console.
+				doesn't work yet...
+
+clipping=1	clipping	Enable or disable clipping.
+clipping=0	noclipping	With clipping enabled, all offscreen
+				reads and writes are disgarded.
+				Default: enable clipping.
+
+gfxclk=x	gfxclk:x	Force graphic clock frequency (in MHz).
+				Be carefull with this option, it may be
+				DANGEROUS.
+				Default: auto 
+					50Mhz for Voodoo 1,
+					75MHz for Voodoo 2. 
+
+slowpci=1	fastpci		Enable or disable fast PCI read/writes.
+slowpci=1	slowpci		Default : fastpci
+
+dev=x		dev:x		Attach the driver to device number x.
+				0 is the first compatible board (in 
+				lspci order)
 
 Tools
 
@@ -126,8 +130,8 @@
 
 	- DO NOT use glide while the sstfb module is in, you'll most likely
 	hang your computer.
-	- if you see some artefacts (pixels not cleaning and stuff like that), 
-	try turning off clipping (clipping=0)
+	- If you see some artefacts (pixels not cleaning and stuff like that), 
+	try turning off clipping (clipping=0), and/or using slowpci
 	- the driver don't detect the 4Mb frame buffer voodoos, it seems that
 	the 2 last Mbs wrap around. looking into that .
 	- The driver is 16 bpp only, 24/32 won't work.
@@ -137,8 +141,8 @@
 	patterns at the border of your windows (the pixels loose the lowest
 	byte -> basicaly the blue component nd some of the green) . I'm unable
 	to reproduce this with XFree86-3.3, but one of the testers has this
-	problem with XFree86-4. I don't know yet if this is the drivers fault
-	or X's (most likely the driver, of course).
+	problem with XFree86-4. apparently recent Xfree86-4.x solve this
+	problem.
 	- I didn't really test changing the palette, so you may find some weird
 	things when playing with that.
 	- Sometimes the driver will not recognise the DAC , and the
@@ -147,6 +151,9 @@
 	contact me .
 	- the 24/32 is not likely to work anytime soon , knowing that the
 	hardware does ... unusual thigs in 24/32 bpp
+	- When used with anther video board, current limitations of linux
+	console subsystem can cause some troubles, specificaly, you should
+	disable software scrollback , as it can oops badly ...
 
 Todo
 
@@ -154,14 +161,14 @@
 	- Buy more coffee.
 	- test/port to other arch.
 	- try to add panning using tweeks with front and back buffer .
-	- try to implement accel en voodoo2 , this board can actualy do a 
+	- try to implement accel on voodoo2 , this board can actualy do a 
 	  lot in 2D even if it was sold as a 3D only board ...
 
 ghoz.
 
 -- 
-Ghozlane Toumi <gtoumi@messel.emse.fr>
+Ghozlane Toumi <gtoumi@laposte.net>
 
 
-$Date: 2001/08/29 00:21:11 $
+$Date: 2002/05/09 20:11:45 $
 http://sstfb.sourceforge.net/README
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/fb/matroxfb.txt linux/Documentation/fb/matroxfb.txt
--- linux.orig/Documentation/fb/matroxfb.txt	2001-09-30 19:26:08.000000000 +0000
+++ linux/Documentation/fb/matroxfb.txt	2002-07-20 01:08:29.000000000 +0000
@@ -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	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/fb/tridentfb.txt	2002-07-20 01:08:25.000000000 +0000
@@ -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	2001-12-21 17:41:53.000000000 +0000
+++ linux/Documentation/filesystems/Locking	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-07-19 23:14:53.000000000 +0000
+++ linux/Documentation/filesystems/cramfs.txt	2002-07-20 01:08:40.000000000 +0000
@@ -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	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/filesystems/devfs/ChangeLog	2002-07-20 01:08:26.000000000 +0000
@@ -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	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/filesystems/devfs/README	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-04-19 16:34:05.000000000 +0000
+++ linux/Documentation/i810_rng.txt	2002-07-20 01:08:38.000000000 +0000
@@ -70,6 +70,14 @@
 
 Change history:
 
+	Version 0.9.8:
+	* Support other i8xx chipsets by adding 82801E detection
+	* 82801DB detection is the same as for 82801CA.
+
+	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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/ia64/IRQ-redir.txt	2002-07-20 01:08:27.000000000 +0000
@@ -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	2001-08-13 23:35:28.000000000 +0000
+++ linux/Documentation/isdn/README.HiSax	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-09-08 01:15:17.000000000 +0000
+++ linux/Documentation/kernel-doc-nano-HOWTO.txt	2002-07-20 01:08:35.000000000 +0000
@@ -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-docs.txt linux/Documentation/kernel-docs.txt
--- linux.orig/Documentation/kernel-docs.txt	2001-06-28 21:45:07.000000000 +0000
+++ linux/Documentation/kernel-docs.txt	2002-07-20 01:08:38.000000000 +0000
@@ -41,7 +41,7 @@
        
      * Title: "The Linux Kernel"
        Author: David A. Rusling.
-       URL: http://www.linuxdoc.org/LDP/tlk/tlk.html
+       URL: http://www.tldp.org/LDP/tlk/tlk.html
        Keywords: everything!, book.
        Description: On line, 200 pages book describing most aspects of
        the Linux Kernel. Probably, the first reference for beginners.
@@ -57,7 +57,7 @@
        
      * Title: "The Linux Kernel Hackers' Guide"
        Author: Michael K.Johnson and others.
-       URL: http://www.linuxdoc.org/LDP/khg/HyperNews/get/khg.html
+       URL: http://www.tldp.org/LDP/khg/HyperNews/get/khg.html
        Keywords: everything!
        Description: No more Postscript book-like version. Only HTML now.
        Many people have contributed. The interface is similar to web
@@ -277,7 +277,7 @@
        
      * Title: "Linux Kernel Module Programming Guide"
        Author: Ori Pomerantz.
-       URL: http://www.linuxdoc.org/LDP/lkmpg/mpg.html
+       URL: http://www.tldp.org/LDP/lkmpg/mpg.html
        Keywords: modules, GPL book, /proc, ioctls, system calls,
        interrupt handlers .
        Description: Very nice 92 pages GPL book on the topic of modules
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt
--- linux.orig/Documentation/kernel-parameters.txt	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/kernel-parameters.txt	2002-07-20 01:08:37.000000000 +0000
@@ -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]
 
@@ -379,6 +381,8 @@
  
 	no-hlt		[BUGS=ix86]
 
+	noht		[SMP,IA-32] Disables P4 Xeon(tm) HyperThreading.
+
 	noisapnp	[ISAPNP] Disables ISA PnP code.
 
 	noinitrd	[RAM] Tells the kernel not to load any configured
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/nbd.txt linux/Documentation/nbd.txt
--- linux.orig/Documentation/nbd.txt	1999-08-05 21:34:01.000000000 +0000
+++ linux/Documentation/nbd.txt	2002-07-20 01:08:39.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/networking/3c359.txt	2002-07-20 01:08:29.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/networking/3c509.txt	2002-07-20 01:08:34.000000000 +0000
@@ -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/8139too.txt linux/Documentation/networking/8139too.txt
--- linux.orig/Documentation/networking/8139too.txt	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/networking/8139too.txt	2002-07-20 01:08:23.000000000 +0000
@@ -98,6 +98,7 @@
 Lantech FastNet TX
 Ovislink Fast Ethernet
 Planet ENW-9504 (V.4) 10/100
+SDT Jeoun Fast PCI-TX
 SMC EZNET 10/100
 UNEX NexNIC ND012C
 
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	2000-08-22 22:21:54.000000000 +0000
+++ linux/Documentation/networking/arcnet-hardware.txt	2002-07-20 01:08:35.000000000 +0000
@@ -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	2001-11-07 22:39:36.000000000 +0000
+++ linux/Documentation/networking/bonding.txt	2002-07-20 01:08:29.000000000 +0000
@@ -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	2001-04-06 17:42:48.000000000 +0000
+++ linux/Documentation/networking/comx.txt	2002-07-20 01:08:33.000000000 +0000
@@ -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/cs89x0.txt linux/Documentation/networking/cs89x0.txt
--- linux.orig/Documentation/networking/cs89x0.txt	2001-03-26 02:24:31.000000000 +0000
+++ linux/Documentation/networking/cs89x0.txt	2002-07-20 01:08:22.000000000 +0000
@@ -51,7 +51,7 @@
     6.2 Information Required Before Contacting Technical Support
     6.3 Obtaining the Latest Driver Version
     6.4 Current maintainer
-
+    6.5 Kernel boot parameters
 
 
 1.0 CIRRUS LOGIC LAN CS8900/CS8920 ETHERNET ADAPTERS
@@ -690,4 +690,14 @@
 6.4 Current maintainer
 
 In February 2000 the maintenance of this driver was assumed by Andrew
-Morton <andrewm@uow.edu.au>
+Morton <akpm@zip.com.au>
+
+6.5 Kernel module parameters
+
+For use in embedded environments with no cs89x0 EEPROM, the kernel boot
+parameter `cs89x0_media=' has been implemented.  Usage is:
+
+	cs89x0_media=rj45    or
+	cs89x0_media=aui     or
+	cs89x0_media=bnc
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/dl2k.txt linux/Documentation/networking/dl2k.txt
--- linux.orig/Documentation/networking/dl2k.txt	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/networking/dl2k.txt	2002-07-20 01:08:26.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/networking/driver.txt	2002-07-20 01:08:24.000000000 +0000
@@ -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	2001-11-07 22:39:36.000000000 +0000
+++ linux/Documentation/networking/ifenslave.c	2002-07-20 01:08:27.000000000 +0000
@@ -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	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/networking/ip-sysctl.txt	2002-07-20 01:08:34.000000000 +0000
@@ -43,23 +43,23 @@
 	Minimum time-to-live of entries.  Should be enough to cover fragment
 	time-to-live on the reassembling side.  This minimum time-to-live  is
 	guaranteed if the pool size is less than inet_peer_threshold.
-	Measured in jiffies.
+	Measured in jiffies(1).
 
 inet_peer_maxttl - INTEGER
 	Maximum time-to-live of entries.  Unused entries will expire after
 	this period of time if there is no memory pressure on the pool (i.e.
 	when the number of entries in the pool is very small).
-	Measured in jiffies.
+	Measured in jiffies(1).
 
 inet_peer_gc_mintime - INTEGER
 	Minimum interval between garbage collection passes.  This interval is
 	in effect under high memory pressure on the pool.
-	Measured in jiffies.
+	Measured in jiffies(1).
 
 inet_peer_gc_maxtime - INTEGER
 	Minimum interval between garbage collection passes.  This interval is
 	in effect under low (or absent) memory pressure on the pool.
-	Measured in jiffies.
+	Measured in jiffies(1).
 
 TCP variables: 
 
@@ -81,7 +81,7 @@
 	How many keepalive probes TCP sends out, until it decides that the
 	connection is broken. Default value: 9.
 
-tcp_keepalive_interval - INTEGER
+tcp_keepalive_intvl - INTEGER
 	How frequently the probes are send out. Multiplied by
 	tcp_keepalive_probes it is time to kill not responding connection,
 	after probes started. Default value: 75sec i.e. connection
@@ -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.
@@ -313,28 +316,37 @@
 	Limit the maximal rates for sending ICMP packets whose type matches
 	icmp_ratemask (see below) to specific targets.
 	0 to disable any limiting, otherwise the maximal rate in jiffies(1)
-	Default: 1
+	Default: 100
 
 icmp_ratemask - INTEGER
 	Mask made of ICMP types for which rates are being limited.
-	Default: 6168
-	Note: 6168 = 0x1818 = 1<<ICMP_DEST_UNREACH + 1<<ICMP_SOURCE_QUENCH +
-	      1<<ICMP_TIME_EXCEEDED + 1<<ICMP_PARAMETERPROB, which means
-	      dest unreachable (3), source quench (4), time exceeded (11)
-	      and parameter problem (12) ICMP packets are rate limited
-	      (check values in icmp.h)
+	Significant bits: IHGFEDCBA9876543210
+	Default mask:     0000001100000011000 (6168)
+
+	Bit definitions (see include/linux/icmp.h):
+		0 Echo Reply
+		3 Destination Unreachable *
+		4 Source Quench *
+		5 Redirect
+		8 Echo Request
+		B Time Exceeded *
+		C Parameter Problem *
+		D Timestamp Request
+		E Timestamp Reply
+		F Info Request
+		G Info Reply
+		H Address Mask Request
+		I Address Mask Reply
+
+	* These are rate limited by default (see default mask above)
 
 icmp_ignore_bogus_error_responses - BOOLEAN
-	Some routers violate RFC 1122 by sending bogus responses to broadcast
+	Some routers violate RFC1122 by sending bogus responses to broadcast
 	frames.  Such violations are normally logged via a kernel warning.
 	If this is set to TRUE, the kernel will not give such warnings, which
 	will avoid log file clutter.
 	Default: FALSE
 
-(1) Jiffie: internal timeunit for the kernel. On the i386 1/100s, on the
-Alpha 1/1024s. See the HZ define in /usr/include/asm/param.h for the exact
-value on your system. 
-
 igmp_max_memberships - INTEGER
 	Change the maximum number of multicast groups we can subscribe to.
 	Default: 20
@@ -358,6 +370,17 @@
 	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.
 
@@ -397,7 +420,30 @@
 	0 - No source validation. 
 
 	Default value is 0. Note that some distributions enable it
-	in startip scripts.
+	in startup scripts.
+
+arp_filter - BOOLEAN
+	1 - Allows you to have multiple network interfaces on the same
+	subnet, and have the ARPs for each interface be answered
+	based on whether or not the kernel would route a packet from
+	the ARP'd IP out that interface (therefore you must use source
+	based routing for this to work). In other words it allows control
+	of which cards (usually 1) will respond to an arp request.
+
+	0 - (default) The kernel can respond to arp requests with addresses
+	from other interfaces. This may seem wrong but it usually makes
+	sense, because it increases the chance of successful communication.
+	IP addresses are owned by the complete host on Linux, not by
+	particular interfaces. Only for more complex setups like load-
+	balancing, does this behaviour cause problems.
+
+tag - INTEGER
+	Allows you to write a number, which can be used as required.
+	Default value is 0.
+
+(1) Jiffie: internal timeunit for the kernel. On the i386 1/100s, on the
+Alpha 1/1024s. See the HZ define in /usr/include/asm/param.h for the exact
+value on your system. 
 
 Alexey Kuznetsov.
 kuznet@ms2.inr.ac.ru
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/pktgen.txt linux/Documentation/networking/pktgen.txt
--- linux.orig/Documentation/networking/pktgen.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/networking/pktgen.txt	2002-07-20 01:08:32.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/networking/ppp_generic.txt	2002-07-20 01:08:27.000000000 +0000
@@ -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	2000-05-12 18:43:26.000000000 +0000
+++ linux/Documentation/networking/skfp.txt	2002-07-20 01:08:21.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/networking/slicecom.hun	2002-07-20 01:08:25.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/networking/slicecom.txt	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-08-12 19:27:36.000000000 +0000
+++ linux/Documentation/networking/vortex.txt	2002-07-20 01:08:28.000000000 +0000
@@ -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	2001-12-21 17:41:53.000000000 +0000
+++ linux/Documentation/pci.txt	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-06-28 21:58:05.000000000 +0000
+++ linux/Documentation/power/pci.txt	2002-07-20 01:08:30.000000000 +0000
@@ -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/scsi-generic.txt linux/Documentation/scsi-generic.txt
--- linux.orig/Documentation/scsi-generic.txt	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/scsi-generic.txt	2002-07-20 01:08:25.000000000 +0000
@@ -30,7 +30,7 @@
 =======================
 The most recent documentation of the sg driver is kept at the Linux
 Documentation Project's (LDP) site: 
-http://www.linuxdoc.org/HOWTO/SCSI-Generic-HOWTO
+http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO
 This describes the sg version 3 driver found in the lk 2.4 series.
 The LDP renders documents in single and multiple page HTML, postscript
 and pdf. This document can also be found at:
@@ -51,7 +51,7 @@
 can be found at the top of the /usr/src/linux/drivers/scsi/sg.c file.
 
 A more general description of the Linux SCSI subsystem of which sg is a 
-part can be found at http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO .
+part can be found at http://www.tldp.org/HOWTO/SCSI-2.4-HOWTO .
 
 
 Example code and utilities
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/scsi.txt linux/Documentation/scsi.txt
--- linux.orig/Documentation/scsi.txt	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/scsi.txt	2002-07-20 01:08:24.000000000 +0000
@@ -2,7 +2,7 @@
 ============================
 The Linux Documentation Project (LDP) maintains a document describing
 the SCSI subsystem in the Linux kernel (lk) 2.4 series. See:
-http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO . The LDP has single
+http://www.tldp.org/HOWTO/SCSI-2.4-HOWTO . The LDP has single
 and multiple page HTML renderings as well as postscript and pdf.
 It can also be found at http://www.torque.net/scsi/SCSI-2.4-HOWTO .
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sonypi.txt linux/Documentation/sonypi.txt
--- linux.orig/Documentation/sonypi.txt	2002-02-25 19:37:51.000000000 +0000
+++ linux/Documentation/sonypi.txt	2002-07-20 01:08:22.000000000 +0000
@@ -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:
 
@@ -71,6 +71,9 @@
 			(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	2001-07-18 14:14:01.000000000 +0000
+++ linux/Documentation/sound/OPL3-SA2	2002-07-20 01:08:25.000000000 +0000
@@ -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/PAS16 linux/Documentation/sound/PAS16
--- linux.orig/Documentation/sound/PAS16	2001-04-12 02:02:27.000000000 +0000
+++ linux/Documentation/sound/PAS16	2002-07-20 01:08:40.000000000 +0000
@@ -71,7 +71,7 @@
   interrupt and DMA channel), because you will be asked for it.
 
   You want to read the Sound-HOWTO, available from
-  http://www.linuxdoc.org/docs.html#howto . General information
+  http://www.tldp.org/docs.html#howto . General information
   about the modular sound system is contained in the files
   Documentation/sound/Introduction. The file
   Documentation/sound/README.OSS contains some slightly outdated but
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sound/README.OSS linux/Documentation/sound/README.OSS
--- linux.orig/Documentation/sound/README.OSS	2001-06-12 17:56:11.000000000 +0000
+++ linux/Documentation/sound/README.OSS	2002-07-20 01:08:23.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/sound/rme96xx	2002-07-20 01:08:25.000000000 +0000
@@ -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	2001-09-10 21:36:25.000000000 +0000
+++ linux/Documentation/sysctl/vm.txt	2002-07-20 01:08:39.000000000 +0000
@@ -21,6 +21,7 @@
 - buffermem
 - freepages
 - kswapd
+- max_map_count
 - overcommit_memory
 - page-cluster
 - pagecache
@@ -170,6 +171,19 @@
 
 ==============================================================
 
+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.
+
+==============================================================
+
 page-cluster:
 
 The Linux VM subsystem avoids excessive disk seeks by reading
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sysrq.txt linux/Documentation/sysrq.txt
--- linux.orig/Documentation/sysrq.txt	2001-09-18 05:52:35.000000000 +0000
+++ linux/Documentation/sysrq.txt	2002-07-20 01:08:36.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/usb/auerswald.txt	2002-07-20 01:08:36.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/usb/brlvger.txt	2002-07-20 01:08:32.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/usb/ehci.txt	2002-07-20 01:08:37.000000000 +0000
@@ -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	2000-04-02 22:19:56.000000000 +0000
+++ linux/Documentation/usb/ibmcam.txt	2002-07-20 01:08:40.000000000 +0000
@@ -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	2000-08-22 16:06:31.000000000 +0000
+++ linux/Documentation/usb/proc_usb_info.txt	2002-07-20 01:08:24.000000000 +0000
@@ -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,17 +247,39 @@
 |   |__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	2002-02-25 19:37:52.000000000 +0000
+++ linux/Documentation/usb/usb-serial.txt	2002-07-20 01:08:24.000000000 +0000
@@ -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/API.html linux/Documentation/video4linux/API.html
--- linux.orig/Documentation/video4linux/API.html	2000-01-06 22:46:18.000000000 +0000
+++ linux/Documentation/video4linux/API.html	2002-07-20 01:08:34.000000000 +0000
@@ -105,7 +105,7 @@
 <TR><TD><b>height</b><TD>The height of the image capture.</TD>
 <TR><TD><b>chromakey</b><TD>A host order RGB32 value for the chroma key.</TD>
 <TR><TD><b>flags</b><TD>Additional capture flags.</TD>
-<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em)</TD>
+<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em></TD>
 <TR><TD><b>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD>
 </TABLE>
 <P>
@@ -120,6 +120,7 @@
 </TABLE>
 <P>
 Merely setting the window does not enable capturing. Overlay capturing
+(i.e. PCI-PCI transfer to the frame buffer of the video card)
 is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
 disabled by passing it a value of 0. 
 <P>
@@ -310,9 +311,10 @@
 </TABLE>
 <P>
 <H3>Reading Images</H3>
-Each call to the <b>read</b> syscall returns the next available image from
-the device. It is up to the caller to set the format and then to pass a 
-suitable size buffer and length to the function. Not all devices will support
+Each call to the <b>read</b> syscall returns the next available image
+from the device. It is up to the caller to set format and size (using
+the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable
+size buffer and length to the function. Not all devices will support
 read operations.
 <P>
 A second way to handle image capture is via the mmap interface if supported.
@@ -329,16 +331,39 @@
 <TR><TD><b>offsets</b><TD>The offset of each frame</TD>
 </TABLE>
 <P>
-Once the mmap has been made the VIDIOCMCAPTURE ioctl sets the image size
-you wish to use (which should match or be below the initial query size).
-Having done so it will begin capturing to the memory mapped buffer. Whenever
-a buffer is "used" by the program it should called VIDIOCSYNC to free this
-frame up and continue. <em>to add:</em>VIDIOCSYNC takes the frame number
-you are freeing as its argument. When the buffer is unmapped or all the
-buffers are full capture ceases. While capturing to memory the driver will
-make a "best effort" attempt to capture to screen as well if requested. This
-normally means all frames that "miss" memory mapped capture will go to the
-display.
+Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the
+capture to a frame using the format and image size specified in the
+video_mmap (which should match or be below the initial query size).
+When the VIDIOCMCAPTURE ioctl returns the frame is <em>not</em>
+captured yet, the driver just instructed the hardware to start the
+capture.  The application has to use the VIDIOCSYNC ioctl to wait
+until the capture of a frame is finished.  VIDIOCSYNC takes the frame
+number you want to wait for as argument.
+<p>
+It is allowed to call VIDIOCMCAPTURE multiple times (with different
+frame numbers in video_mmap->frame of course) and thus have multiple
+outstanding capture requests.  A simple way do to double-buffering
+using this feature looks like this:
+<pre>
+/* setup everything */
+VIDIOCMCAPTURE(0)
+while (whatever) {
+   VIDIOCMCAPTURE(1)
+   VIDIOCSYNC(0)
+   /* process frame 0 while the hardware captures frame 1 */
+   VIDIOCMCAPTURE(0)
+   VIDIOCSYNC(1)
+   /* process frame 1 while the hardware captures frame 0 */
+}
+</pre>
+Note that you are <em>not</em> limited to only two frames.  The API
+allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of
+frames the driver granted.  Thus it is possible to build deeper queues
+to avoid loosing frames on load peaks.
+<p>
+While capturing to memory the driver will make a "best effort" attempt
+to capture to screen as well if requested. This normally means all
+frames that "miss" memory mapped capture will go to the display.
 <P>
 A final ioctl exists to allow a device to obtain related devices if a
 driver has multiple components (for example video0 may not be associated
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/video4linux/bttv/CARDLIST linux/Documentation/video4linux/bttv/CARDLIST
--- linux.orig/Documentation/video4linux/bttv/CARDLIST	2001-10-17 21:19:20.000000000 +0000
+++ linux/Documentation/video4linux/bttv/CARDLIST	2002-07-20 01:08:25.000000000 +0000
@@ -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	2001-10-17 21:19:20.000000000 +0000
+++ linux/Documentation/video4linux/bttv/Cards	2002-07-20 01:08:28.000000000 +0000
@@ -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	2001-10-17 21:19:20.000000000 +0000
+++ linux/Documentation/video4linux/bttv/Insmod-options	2002-07-20 01:08:26.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/video4linux/bttv/README.freeze	2002-07-20 01:08:29.000000000 +0000
@@ -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	2001-10-17 21:19:20.000000000 +0000
+++ linux/Documentation/video4linux/bttv/Sound-FAQ	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/Documentation/video4linux/meye.txt	2002-07-20 01:08:28.000000000 +0000
@@ -15,9 +15,17 @@
 
 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)
 
 	gbufsize:	size of each capture buffer, default is 614400
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/watchdog-api.txt linux/Documentation/watchdog-api.txt
--- linux.orig/Documentation/watchdog-api.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux/Documentation/watchdog-api.txt	2002-07-20 01:08:37.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/MAINTAINERS	2002-07-20 01:08:23.000000000 +0000
@@ -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
@@ -1254,6 +1291,17 @@
 W:	http://www.pnd-pc.demon.co.uk/promise/
 S:	Maintained
 
+PROMISE PDC202XX IDE CONTROLLER DRIVER
+P:	Hank Yang
+M:	support@promise.com.tw [TAIWAN]
+P:	Jordan Rhody
+M:	support@promise.com [U.S.A]
+P:	Jack Hu
+M:	support-china@promise.com [CHINA]
+W:	http://www.promise.com/support/linux_eng.asp
+W:	http://www.promise.com.tw/support/linux_eng.asp
+S:	Maintained
+
 QNX4 FILESYSTEM
 P:	Anders Larsen
 M:	al@alarsen.net
@@ -1304,6 +1352,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 +1385,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 +1421,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 +1478,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 +1541,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 +1631,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 +1655,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 +1677,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 +1708,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 +1718,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 +1773,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 +1796,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 +1822,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	2002-02-25 19:37:52.000000000 +0000
+++ linux/Makefile	2002-07-20 01:08:25.000000000 +0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 18
-EXTRAVERSION =
+SUBLEVEL = 19
+EXTRAVERSION = -rc3
 
 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) \
@@ -306,25 +324,29 @@
 	. scripts/mkversion > .tmpversion
 	@mv -f .tmpversion .version
 
+uts_len		:= 64
+uts_truncate	:= sed -e 's/\(.\{1,$(uts_len)\}\).*/\1/'
+
 include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
-	@echo -n \#define UTS_VERSION \"\#`cat .version` > .ver
-	@if [ -n "$(CONFIG_SMP)" ] ; then echo -n " SMP" >> .ver; fi
-	@if [ -f .name ]; then  echo -n \-`cat .name` >> .ver; fi
-	@echo ' '`date`'"' >> .ver
-	@echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
+	@echo -n \#`cat .version` > .ver1
+	@if [ -n "$(CONFIG_SMP)" ] ; then echo -n " SMP" >> .ver1; fi
+	@if [ -f .name ]; then  echo -n \-`cat .name` >> .ver1; fi
+	@LANG=C echo ' '`date` >> .ver1
+	@echo \#define UTS_VERSION \"`cat .ver1 | $(uts_truncate)`\" > .ver
+	@LANG=C echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
 	@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver
-	@echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> .ver
-	@if [ -x /bin/dnsdomainname ]; then \
-	   echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname`\"; \
-	 elif [ -x /bin/domainname ]; then \
-	   echo \#define LINUX_COMPILE_DOMAIN \"`domainname`\"; \
-	 else \
-	   echo \#define LINUX_COMPILE_DOMAIN ; \
-	 fi >> .ver
+	@echo \#define LINUX_COMPILE_HOST \"`hostname | $(uts_truncate)`\" >> .ver
+	@([ -x /bin/dnsdomainname ] && /bin/dnsdomainname > .ver1) || \
+	 ([ -x /bin/domainname ] && /bin/domainname > .ver1) || \
+	 echo > .ver1
+	@echo \#define LINUX_COMPILE_DOMAIN \"`cat .ver1 | $(uts_truncate)`\" >> .ver
 	@echo \#define LINUX_COMPILER \"`$(CC) $(CFLAGS) -v 2>&1 | tail -1`\" >> .ver
 	@mv -f .ver $@
+	@rm -f .ver1
 
 include/linux/version.h: ./Makefile
+	@expr length "$(KERNELRELEASE)" \<= $(uts_len) > /dev/null || \
+	  (echo KERNELRELEASE \"$(KERNELRELEASE)\" exceeds $(uts_len) characters >&2; false)
 	@echo \#define UTS_RELEASE \"$(KERNELRELEASE)\" > .ver
 	@echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver
 	@echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver
@@ -336,15 +358,18 @@
 	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(ARCH)"' -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o init/version.c
 
 init/main.o: init/main.c include/config/MARKER
-	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $*.o $<
+	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -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 $@ $<
 
 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 arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | etags -
 
 # Exuberant ctags works better with -I
 tags: dummy
@@ -452,6 +477,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	2001-10-05 19:10:00.000000000 +0000
+++ linux/README	2002-07-20 01:08:31.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/Rules.make	2002-07-20 01:08:33.000000000 +0000
@@ -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 $(sort $(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	2000-12-04 01:45:20.000000000 +0000
+++ linux/arch/alpha/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -40,22 +40,22 @@
     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)
     CFLAGS := $(CFLAGS) -mcpu=ev67
     mcpu_done := y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/config.in linux/arch/alpha/config.in
--- linux.orig/arch/alpha/config.in	2001-11-20 23:49:31.000000000 +0000
+++ linux/arch/alpha/config.in	2002-07-20 01:08:28.000000000 +0000
@@ -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,11 +278,15 @@
 	"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
  
 tristate 'Kernel support for a.out (ECOFF) binaries' CONFIG_BINFMT_AOUT
+if [ "$CONFIG_BINFMT_AOUT" != "n" ]; then
+	bool '  OSF/1 v4 readv/writev compatibility' CONFIG_OSF4_COMPAT
+fi
+
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 tristate 'Kernel support for Linux/Intel ELF binaries' CONFIG_BINFMT_EM86
@@ -371,9 +403,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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/alpha/kernel/alpha_ksyms.c	2002-07-20 01:08:24.000000000 +0000
@@ -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	2001-11-09 21:45:35.000000000 +0000
+++ linux/arch/alpha/kernel/entry.S	2002-07-20 01:08:21.000000000 +0000
@@ -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>.
@@ -886,8 +886,13 @@
 	.quad osf_getrusage
 	.quad sys_getsockopt
 	.quad alpha_ni_syscall
+#ifdef CONFIG_OSF4_COMPAT
+	.quad osf_readv				/* 120 */
+	.quad osf_writev
+#else
 	.quad sys_readv				/* 120 */
 	.quad sys_writev
+#endif
 	.quad osf_settimeofday
 	.quad sys_fchown
 	.quad sys_fchmod
@@ -1148,3 +1153,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/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
--- linux.orig/arch/alpha/kernel/osf_sys.c	2001-11-03 01:39:20.000000000 +0000
+++ linux/arch/alpha/kernel/osf_sys.c	2002-07-20 01:08:21.000000000 +0000
@@ -1384,3 +1384,44 @@
 
 	return addr;
 }
+
+#ifdef CONFIG_OSF4_COMPAT
+extern ssize_t sys_readv(unsigned long, const struct iovec *, unsigned long);
+extern ssize_t sys_writev(unsigned long, const struct iovec *, unsigned long);
+
+/* Clear top 32 bits of iov_len in the user's buffer for
+   compatibility with old versions of OSF/1 where iov_len
+   was defined as int. */
+static int
+osf_fix_iov_len(const struct iovec *iov, unsigned long count)
+{
+	unsigned long i;
+
+	for (i = 0 ; i < count ; i++) {
+		int *iov_len_high = (int *)&iov[i].iov_len + 1;
+
+		if (put_user(0, iov_len_high))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+asmlinkage ssize_t
+osf_readv(unsigned long fd, const struct iovec * vector, unsigned long count)
+{
+	if (unlikely(personality(current->personality) == PER_OSF4))
+		if (osf_fix_iov_len(vector, count))
+			return -EFAULT;
+	return sys_readv(fd, vector, count);
+}
+
+asmlinkage ssize_t
+osf_writev(unsigned long fd, const struct iovec * vector, unsigned long count)
+{
+	if (unlikely(personality(current->personality) == PER_OSF4))
+		if (osf_fix_iov_len(vector, count))
+			return -EFAULT;
+	return sys_writev(fd, vector, count);
+}
+
+#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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/alpha/kernel/pci_iommu.c	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-11-17 02:38:39.000000000 +0000
+++ linux/arch/alpha/kernel/setup.c	2002-07-20 01:08:27.000000000 +0000
@@ -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	2001-11-09 21:45:35.000000000 +0000
+++ linux/arch/alpha/kernel/signal.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/alpha/kernel/smp.c	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-10-21 17:20:57.000000000 +0000
+++ linux/arch/alpha/kernel/srm_env.c	2002-07-20 01:08:26.000000000 +0000
@@ -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/lib/ev6-memset.S linux/arch/alpha/lib/ev6-memset.S
--- linux.orig/arch/alpha/lib/ev6-memset.S	2000-12-11 21:46:26.000000000 +0000
+++ linux/arch/alpha/lib/ev6-memset.S	2002-07-20 01:08:25.000000000 +0000
@@ -236,7 +236,7 @@
 	 * entry point.
 	 */
 .align 4
-	.ent __memset
+	.ent __constant_c_memset
 __constant_c_memset:
 	.frame $30,0,$26,0
 	.prologue 0
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	2000-09-22 20:54:09.000000000 +0000
+++ linux/arch/alpha/math-emu/math.c	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-09-21 03:02:03.000000000 +0000
+++ linux/arch/alpha/mm/init.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-08-12 17:38:48.000000000 +0000
+++ linux/arch/alpha/mm/numa.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/arm/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/boot/Makefile	2002-07-20 01:08:25.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/boot/compressed/Makefile	2002-07-20 01:08:26.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/boot/compressed/head-epxa10db.S	2002-07-20 01:08:22.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/boot/compressed/head-mx1ads.S	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-04-12 19:03:50.000000000 +0000
+++ linux/arch/arm/boot/compressed/head-shark.S	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/boot/compressed/head.S	2002-07-20 01:08:39.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/boot/compressed/misc.c	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/boot/compressed/ofw-shark.c	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/arm/config.in	2002-07-20 01:08:28.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/adsbitsy	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/anakin	2002-07-20 01:08:24.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/assabet	2002-07-20 01:08:32.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/def-configs/badge4	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/cerfcube	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/cerfpda	2002-07-20 01:08:27.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/cerfpod	2002-07-20 01:08:35.000000000 +0000
@@ -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	2001-05-20 00:43:05.000000000 +0000
+++ linux/arch/arm/def-configs/clps7500	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/ebsa110	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/epxa10db	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/flexanet	2002-07-20 01:08:34.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/def-configs/fortunet	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/freebird	2002-07-20 01:08:27.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/freebird_new	2002-07-20 01:08:24.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/def-configs/frodo	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/graphicsclient	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/graphicsmaster	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/h3600	2002-07-20 01:08:29.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/integrator	2002-07-20 01:08:24.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/jornada720	2002-07-20 01:08:29.000000000 +0000
@@ -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	2001-10-25 20:53:44.000000000 +0000
+++ linux/arch/arm/def-configs/lart	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/def-configs/neponset	2002-07-20 01:08:31.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/def-configs/pangolin	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/pfs168_mqtft	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/pfs168_mqvga	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/pfs168_sastn	2002-07-20 01:08:24.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/pfs168_satft	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-08-13 00:36:24.000000000 +0000
+++ linux/arch/arm/def-configs/pleb	2002-07-20 01:08:27.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/def-configs/rpc	2002-07-20 01:08:21.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/def-configs/shannon	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/def-configs/shark	2002-07-20 01:08:25.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/def-configs/system3	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/kernel/Makefile	2002-07-20 01:08:39.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/kernel/armksyms.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/kernel/bios32.c	2002-07-20 01:08:33.000000000 +0000
@@ -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	2001-10-08 17:39:18.000000000 +0000
+++ linux/arch/arm/kernel/calls.S	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/kernel/compat.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/kernel/debug-armv.S	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-07-04 21:56:44.000000000 +0000
+++ linux/arch/arm/kernel/dma-arc.c	2002-07-20 01:08:38.000000000 +0000
@@ -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	2001-02-09 19:29:44.000000000 +0000
+++ linux/arch/arm/kernel/dma.c	2002-07-20 01:08:39.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/kernel/entry-armv.S	2002-07-20 01:08:31.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/kernel/entry-header.S	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/kernel/init_task.c	2002-07-20 01:08:33.000000000 +0000
@@ -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	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/arm/kernel/process.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/arm/kernel/semaphore.c	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/kernel/signal.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/kernel/traps.c	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/kernel/via82c505.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/lib/backtrace.S	2002-07-20 01:08:27.000000000 +0000
@@ -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	2000-11-28 01:07:59.000000000 +0000
+++ linux/arch/arm/lib/ecard.S	2002-07-20 01:08:31.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/lib/getuser.S	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/lib/io-acorn.S	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-04-12 19:20:31.000000000 +0000
+++ linux/arch/arm/lib/io-shark.c	2002-07-20 01:08:27.000000000 +0000
@@ -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	2000-09-18 22:15:25.000000000 +0000
+++ linux/arch/arm/lib/strrchr.S	2002-07-20 01:08:37.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/autcpu12.c	2002-07-20 01:08:33.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/cdb89712.c	2002-07-20 01:08:21.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/clep7312.c	2002-07-20 01:08:38.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/dma.c	2002-07-20 01:08:25.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/edb7211-arch.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/edb7211-mm.c	2002-07-20 01:08:35.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/fortunet.c	2002-07-20 01:08:26.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/irq.c	2002-07-20 01:08:24.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/mm.c	2002-07-20 01:08:26.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/p720t-leds.c	2002-07-20 01:08:38.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/p720t.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-clps711x/time.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-ebsa110/io.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/mach-epxa10db/arch.c	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/mach-epxa10db/mm.c	2002-07-20 01:08:38.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-integrator/pci_v3.c	2002-07-20 01:08:27.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-mx1ads/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-mx1ads/arch.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-mx1ads/cpu.c	2002-07-20 01:08:33.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-mx1ads/irq.c	2002-07-20 01:08:38.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-mx1ads/mm.c	2002-07-20 01:08:40.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-mx1ads/time.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/mach-sa1100/Makefile	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/adsbitsy.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-25 20:53:45.000000000 +0000
+++ linux/arch/arm/mach-sa1100/assabet.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-sa1100/badge4.c	2002-07-20 01:08:39.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/cerf.c	2002-07-20 01:08:35.000000000 +0000
@@ -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,13 +78,19 @@
 	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
 }
 
 MACHINE_START(CERF, "Intrinsyc's Cerf Family of Products")
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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/cpu-sa1100.c	2002-07-20 01:08:24.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/cpu-sa1110.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/dma-sa1100.c	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/dma-sa1111.c	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/empeg.c	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/flexanet.c	2002-07-20 01:08:34.000000000 +0000
@@ -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;
+	}
 
-EXPORT_SYMBOL(BCR_value);
-EXPORT_SYMBOL(flexanet_GUI_type);
+	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;
+
+	/* 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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/freebird.c	2002-07-20 01:08:27.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-sa1100/frodo.c	2002-07-20 01:08:33.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/generic.c	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/graphicsclient.c	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/graphicsmaster.c	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/h3600.c	2002-07-20 01:08:28.000000000 +0000
@@ -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);
+
+	/*
+	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 )
+{
+	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 *************************/
 
-void init_h3600_egpio(void)
+static void h3600_init_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;
+	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);
+}
+
+static unsigned long h3800_read_egpio( void )
+{
+	return h3800_asic1_gpio | (h3800_asic2_gpio << 16);
 }
 
-EXPORT_SYMBOL(clr_h3600_egpio);
-EXPORT_SYMBOL(set_h3600_egpio);
+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,18 +409,28 @@
 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)
@@ -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;
+	PWER = PWER_GPIO0 | PWER_RTC;
+	PCFR = PCFR_OPDE;
+	PSDR = 0;
 }
 
-MACHINE_START(H3600, "Compaq iPAQ")
+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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/huw_webpanel.c	2002-07-20 01:08:35.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/irq.c	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/itsy.c	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/jornada720.c	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-08-13 00:36:24.000000000 +0000
+++ linux/arch/arm/mach-sa1100/lart.c	2002-07-20 01:08:35.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/leds-assabet.c	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/leds-flexanet.c	2002-07-20 01:08:24.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-sa1100/leds-frodo.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-sa1100/leds-system3.c	2002-07-20 01:08:31.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/leds.c	2002-07-20 01:08:27.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/leds.h	2002-07-20 01:08:28.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/nanoengine.c	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/neponset.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/omnimeter.c	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/pangolin.c	2002-07-20 01:08:39.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/pfs168.c	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-08-13 00:36:24.000000000 +0000
+++ linux/arch/arm/mach-sa1100/pleb.c	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/pm.c	2002-07-20 01:08:28.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/sa1111-pcibuf.c	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/sa1111.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/sa1111.h	2002-07-20 01:08:36.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-sa1100/shannon.c	2002-07-20 01:08:31.000000000 +0000
@@ -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	2001-08-13 00:36:24.000000000 +0000
+++ linux/arch/arm/mach-sa1100/sherman.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mach-sa1100/simpad.c	2002-07-20 01:08:25.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mach-sa1100/system3.c	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/victor.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mach-sa1100/xp860.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/mach-sa1100/yopy.c	2002-07-20 01:08:25.000000000 +0000
@@ -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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/arm/mm/Makefile	2002-07-20 01:08:37.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mm/alignment.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mm/fault-armv.c	2002-07-20 01:08:28.000000000 +0000
@@ -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;
 
 		/*
@@ -749,3 +220,30 @@
 	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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mm/fault-common.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-06-27 21:12:04.000000000 +0000
+++ linux/arch/arm/mm/mm-armv.c	2002-07-20 01:08:25.000000000 +0000
@@ -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>
@@ -225,6 +225,19 @@
 	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) |
 		   (md->prot_write ? L_PTE_WRITE      : 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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/arm/mm/proc-arm1020.S	2002-07-20 01:08:24.000000000 +0000
@@ -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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/mm/proc-arm720.S	2002-07-20 01:08:25.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mm/proc-arm920.S	2002-07-20 01:08:23.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm/mm/proc-arm922.S	2002-07-20 01:08:35.000000000 +0000
@@ -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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/arm/mm/proc-arm926.S	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-10-25 20:53:46.000000000 +0000
+++ linux/arch/arm/mm/proc-sa110.S	2002-07-20 01:08:36.000000000 +0000
@@ -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	1999-06-17 08:11:35.000000000 +0000
+++ linux/arch/arm/nwfpe/ARM-gcc.h	2002-07-20 01:08:34.000000000 +0000
@@ -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	1999-10-20 23:29:08.000000000 +0000
+++ linux/arch/arm/nwfpe/ChangeLog	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/double_cpdo.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/entry.S	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-04-12 02:02:27.000000000 +0000
+++ linux/arch/arm/nwfpe/entry26.S	2002-07-20 01:08:31.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/extended_cpdo.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/fpa11.c	2002-07-20 01:08:33.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/fpa11.h	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/fpa11_cpdt.c	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/fpa11_cprt.c	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/fpmodule.c	2002-07-20 01:08:35.000000000 +0000
@@ -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 */
@@ -86,6 +87,11 @@
     return -EINVAL;
   }
 
+  if (sizeof(FPREG) != 12) {
+    printk(KERN_ERR "nwfpe: bad register size\n");
+    return -EINVAL;
+  }
+
 #ifdef MODULE
   if (!mod_member_present(&__this_module, can_unload))
     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	2001-04-12 02:02:27.000000000 +0000
+++ linux/arch/arm/nwfpe/fpopcode.c	2002-07-20 01:08:34.000000000 +0000
@@ -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	2001-08-12 18:13:59.000000000 +0000
+++ linux/arch/arm/nwfpe/single_cpdo.c	2002-07-20 01:08:34.000000000 +0000
@@ -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	1999-06-17 08:11:35.000000000 +0000
+++ linux/arch/arm/nwfpe/softfloat-specialize	2002-07-20 01:08:40.000000000 +0000
@@ -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	2000-11-28 01:07:59.000000000 +0000
+++ linux/arch/arm/nwfpe/softfloat.c	2002-07-20 01:08:37.000000000 +0000
@@ -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,
@@ -3832,1045 +3437,3 @@
 
 #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
-          aSign ? lt128( b.high, b.low, a.high, a.low )
-        : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-#endif
-
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	1999-06-17 08:11:35.000000000 +0000
+++ linux/arch/arm/nwfpe/softfloat.h	2002-07-20 01:08:25.000000000 +0000
@@ -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
 
 /*
 -------------------------------------------------------------------------------
@@ -250,41 +229,4 @@
 
 #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
-
 #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	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/arm/tools/Makefile	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/arm/tools/mach-types	2002-07-20 01:08:36.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/Makefile	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/cris/defconfig	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/cris/drivers/Config.in	2002-07-20 01:08:28.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/drivers/axisflashmap.c	2002-07-20 01:08:39.000000000 +0000
@@ -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	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/cris/drivers/bluetooth/Makefile	2002-07-20 01:08:38.000000000 +0000
@@ -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	2001-07-04 18:50:38.000000000 +0000
+++ linux/arch/cris/drivers/ds1302.c	2002-07-20 01:08:39.000000000 +0000
@@ -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. */
@@ -480,6 +435,56 @@
         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. */
 
 int __init
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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/drivers/ethernet.c	2002-07-20 01:08:35.000000000 +0000
@@ -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 etrax_eth_descr *myLastRxDesc;  /* The last processed descriptor */
+static etrax_eth_descr *myPrevRxDesc;  /* The descriptor right before myNextRxDesc */
 
-static unsigned char RxBuf[RX_BUF_SIZE];
+static etrax_eth_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(32)));
 
-static etrax_dma_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(4)));
-static etrax_dma_descr TxDesc __attribute__ ((aligned(4)));
-
-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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/drivers/gpio.c	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-07-04 18:50:38.000000000 +0000
+++ linux/arch/cris/drivers/ide.c	2002-07-20 01:08:28.000000000 +0000
@@ -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	2001-07-26 22:10:06.000000000 +0000
+++ linux/arch/cris/drivers/lpslave/e100lpslavenet.c	2002-07-20 01:08:33.000000000 +0000
@@ -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	2001-10-08 18:43:54.000000000 +0000
+++ linux/arch/cris/drivers/parport.c	2002-07-20 01:08:24.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/drivers/serial.c	2002-07-20 01:08:25.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/drivers/serial.h	2002-07-20 01:08:32.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/drivers/sync_serial.c	2002-07-20 01:08:25.000000000 +0000
@@ -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	2001-05-01 23:04:56.000000000 +0000
+++ linux/arch/cris/kernel/debugport.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/kernel/entry.S	2002-07-20 01:08:34.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/kernel/head.S	2002-07-20 01:08:33.000000000 +0000
@@ -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	2001-10-08 18:43:54.000000000 +0000
+++ linux/arch/cris/kernel/signal.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/kernel/time.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-10-08 18:43:54.000000000 +0000
+++ linux/arch/cris/mm/extable.c	2002-07-20 01:08:37.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/mm/fault.c	2002-07-20 01:08:31.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/cris/mm/init.c	2002-07-20 01:08:35.000000000 +0000
@@ -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/compressed/misc.c linux/arch/i386/boot/compressed/misc.c
--- linux.orig/arch/i386/boot/compressed/misc.c	2001-11-12 17:59:43.000000000 +0000
+++ linux/arch/i386/boot/compressed/misc.c	2002-07-20 01:08:38.000000000 +0000
@@ -125,7 +125,7 @@
 static int lines, cols;
 
 #ifdef CONFIG_MULTIQUAD
-static void *xquad_portio = NULL;
+static void * const xquad_portio = NULL;
 #endif
 
 #include "../../../../lib/inflate.c"
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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/i386/boot/setup.S	2002-07-20 01:08:22.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/i386/config.in	2002-07-20 01:08:31.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/i386/defconfig	2002-07-20 01:08:26.000000000 +0000
@@ -31,6 +31,7 @@
 # CONFIG_MPENTIUM4 is not set
 # CONFIG_MK6 is not set
 # CONFIG_MK7 is not set
+# CONFIG_MELAN is not set
 # CONFIG_MCRUSOE is not set
 # CONFIG_MWINCHIPC6 is not set
 # CONFIG_MWINCHIP2 is not set
@@ -49,6 +50,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
@@ -85,9 +87,9 @@
 #
 CONFIG_PCMCIA=y
 CONFIG_CARDBUS=y
+# CONFIG_TCIC is not set
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
 
 #
 # PCI Hotplug Support
@@ -95,6 +97,8 @@
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_IBM is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -130,7 +134,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -153,7 +159,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -166,12 +172,18 @@
 # CONFIG_IP_MROUTE is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
 #  
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 
@@ -181,6 +193,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -204,6 +221,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_STROKE 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
@@ -218,6 +236,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -229,12 +248,15 @@
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
@@ -242,6 +264,7 @@
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CMD680 is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
@@ -394,7 +417,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -411,6 +433,7 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
@@ -426,11 +449,13 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # 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
 
@@ -444,6 +469,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_PLIP is not set
 # CONFIG_PPP is not set
@@ -473,10 +499,10 @@
 # CONFIG_PCMCIA_3C574 is not set
 # CONFIG_PCMCIA_FMVJ18X is not set
 CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
 # 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_PCMCIA_XIRCOM is not set
@@ -496,9 +522,6 @@
 # IrDA (infrared) support
 #
 # CONFIG_IRDA is not set
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
 
 #
 # ISDN subsystem
@@ -544,6 +567,7 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -563,6 +587,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
+# CONFIG_AMD_RNG is not set
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
@@ -583,12 +608,18 @@
 CONFIG_AGP_ALI=y
 # CONFIG_AGP_SWORKS is not set
 CONFIG_DRM=y
+# CONFIG_DRM_OLD is not set
+
+#
+# DRM 4.1 drivers
+#
+CONFIG_DRM_NEW=y
 CONFIG_DRM_TDFX=y
-# CONFIG_DRM_GAMMA is not set
 # CONFIG_DRM_R128 is not set
 CONFIG_DRM_RADEON=y
 # CONFIG_DRM_I810 is not set
 # CONFIG_DRM_MGA is not set
+# CONFIG_DRM_SIS is not set
 
 #
 # PCMCIA character devices
@@ -627,7 +658,7 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -730,8 +761,9 @@
 # CONFIG_USB_LONG_TIMEOUT is not set
 
 #
-# USB Controllers
+# USB Host Controller Drivers
 #
+# CONFIG_USB_EHCI_HCD is not set
 CONFIG_USB_UHCI_ALT=y
 # CONFIG_USB_OHCI is not set
 
@@ -739,6 +771,7 @@
 # USB Device Class drivers
 #
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -755,10 +788,16 @@
 #
 # USB Human Interface Devices (HID)
 #
+# CONFIG_USB_HID is not set
 
 #
-#   Input core support is needed for USB HID
+#     Input core support is needed for USB HID input layer or HIDBP support
 #
+# CONFIG_USB_HIDINPUT 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
 
 #
 # USB Imaging devices
@@ -781,6 +820,7 @@
 # USB Network adaptors
 #
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_CDCETHER is not set
@@ -802,6 +842,7 @@
 # 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_IPAQ 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
@@ -815,6 +856,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
@@ -824,6 +866,13 @@
 # USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
 
 #
 # Kernel hacking
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	2001-11-12 03:15:06.000000000 +0000
+++ linux/arch/i386/kernel/acpitable.c	2002-07-20 01:08:39.000000000 +0000
@@ -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	2002-02-25 19:37:52.000000000 +0000
+++ linux/arch/i386/kernel/apic.c	2002-07-20 01:08:36.000000000 +0000
@@ -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;
 
@@ -924,6 +941,26 @@
 	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);
+	}
+}
+
 /*
  * the frequency of the profiling timer can be changed
  * by writing a multiplier value into /proc/profile.
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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/apm.c	2002-07-20 01:08:24.000000000 +0000
@@ -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,20 +1189,21 @@
 		/* 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;
 		}
 		printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
 	}
 	get_time_diff();
-	cli();
-	err = apm_set_power_state(APM_STATE_SUSPEND);
+	__cli();
+	err = set_system_power_state(APM_STATE_SUSPEND);
 	reinit_timer();
 	set_time();
-	sti();
+	ignore_normal_resume = 1;
+	__sti();
 	if (err == APM_NO_ERROR)
 		err = APM_SUCCESS;
 	if (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);
 		}
@@ -1788,7 +1783,7 @@
 			idle_threshold = simple_strtol(str + 15, NULL, 0);
 		if ((strncmp(str, "idle-period=", 12) == 0) ||
 		    (strncmp(str, "idle_period=", 12) == 0))
-			idle_threshold = simple_strtol(str + 15, NULL, 0);
+			idle_period = simple_strtol(str + 12, NULL, 0);
 		invert = (strncmp(str, "no-", 3) == 0) ||
 			(strncmp(str, "no_", 3) == 0);
 		if (invert)
@@ -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	2001-11-12 17:59:43.000000000 +0000
+++ linux/arch/i386/kernel/bluesmoke.c	2002-07-20 01:08:31.000000000 +0000
@@ -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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/dmi_scan.c	2002-07-20 01:08:33.000000000 +0000
@@ -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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/entry.S	2002-07-20 01:08:29.000000000 +0000
@@ -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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/head.S	2002-07-20 01:08:25.000000000 +0000
@@ -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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/i386_ksyms.c	2002-07-20 01:08:36.000000000 +0000
@@ -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
@@ -168,9 +173,9 @@
 EXPORT_SYMBOL(atomic_dec_and_lock);
 #endif
 
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-EXPORT_SYMBOL(do_BUG);
-#endif
-
 extern int is_sony_vaio_laptop;
 EXPORT_SYMBOL(is_sony_vaio_laptop);
+
+#ifdef CONFIG_MULTIQUAD
+EXPORT_SYMBOL(xquad_portio);
+#endif
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	2001-11-14 01:28:41.000000000 +0000
+++ linux/arch/i386/kernel/io_apic.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-10-30 23:13:17.000000000 +0000
+++ linux/arch/i386/kernel/microcode.c	2002-07-20 01:08:28.000000000 +0000
@@ -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,11 +332,15 @@
 {
 	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);
 	if (!mc_applied) {
 		mc_applied = kmalloc(smp_num_cpus*sizeof(struct microcode),
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	2001-11-09 22:58:18.000000000 +0000
+++ linux/arch/i386/kernel/mpparse.c	2002-07-20 01:08:31.000000000 +0000
@@ -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;
 }
 
 /*
@@ -495,10 +502,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");
 	return num_processors;
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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/i386/kernel/mtrr.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-09-21 03:55:24.000000000 +0000
+++ linux/arch/i386/kernel/nmi.c	2002-07-20 01:08:38.000000000 +0000
@@ -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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/pci-irq.c	2002-07-20 01:08:40.000000000 +0000
@@ -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,10 +461,19 @@
 	{ "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 },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, 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 },
 	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
@@ -462,6 +489,10 @@
 	  pirq_serverworks_get, pirq_serverworks_set },
 	{ "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B,
 		pirq_amd756_get, pirq_amd756_set },
+	{ "AMD766", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413,
+		pirq_amd756_get, pirq_amd756_set },
+	{ "AMD768", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7443,
+		pirq_amd756_get, pirq_amd756_set },
 
 	{ "default", 0, 0, NULL, NULL }
 };
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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/pci-pc.c	2002-07-20 01:08:34.000000000 +0000
@@ -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,11 +1130,23 @@
 	 */
 	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;
 }
 
+static void __devinit  pci_fixup_ncr53c810(struct pci_dev *d)
+{
+	/*
+	 * NCR 53C810 returns class code 0 (at least on some systems).
+	 * Fix class to be PCI_CLASS_STORAGE_SCSI
+	 */
+	if (!d->class) {
+		printk("PCI: fixing NCR 53C810 class code for %s\n", d->slot_name);
+		d->class = PCI_CLASS_STORAGE_SCSI << 8;
+	}
+}
+
 static void __devinit pci_fixup_ide_bases(struct pci_dev *d)
 {
 	int i;
@@ -1110,27 +1199,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);
 	}
 }
@@ -1148,6 +1258,7 @@
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8622,	        pci_fixup_via_northbridge_bug },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8361,	        pci_fixup_via_northbridge_bug },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8367_0,	pci_fixup_via_northbridge_bug },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_NCR,	PCI_DEVICE_ID_NCR_53C810,	pci_fixup_ncr53c810 },
 	{ 0 }
 };
 
@@ -1199,15 +1310,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/process.c linux/arch/i386/kernel/process.c
--- linux.orig/arch/i386/kernel/process.c	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/process.c	2002-07-20 01:08:21.000000000 +0000
@@ -311,7 +311,7 @@
 	/*
 	 * Use `swapper_pg_dir' as our page directory.
 	 */
-	asm volatile("movl %0,%%cr3": :"r" (__pa(swapper_pg_dir)));
+	load_cr3(swapper_pg_dir);
 
 	/* Write 0x1234 to absolute memory location 0x472.  The BIOS reads
 	   this on booting to tell it to "Bypass memory test (also warm
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	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/i386/kernel/semaphore.c	2002-07-20 01:08:34.000000000 +0000
@@ -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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/setup.c	2002-07-20 01:08:36.000000000 +0000
@@ -71,6 +71,13 @@
  *  CacheSize bug workaround updates for AMD, Intel & VIA Cyrix.
  *  Dave Jones <davej@suse.de>, September, October 2001.
  *
+ *  Short-term fix for a conflicting cache attribute bug in the kernel
+ *  that is exposed by advanced speculative caching on new AMD Athlon
+ *  processors.
+ *  Richard Brunner <richard.brunner@amd.com> and Mark Langsdorf
+ *  <mark.langsdorf@amd.com>, June 2002 
+ *  Adapted to work with uniprocessor APIC by Bryan O'Sullivan
+ *  <bos@serpentine.com>, June 2002.
  */
 
 /*
@@ -98,6 +105,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 +148,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,14 +167,22 @@
 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;
 
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+int disable_adv_spec_cache __initdata = 1;
+#else
+int disable_adv_spec_cache __initdata = 0;
+#endif /* CONFIG_AGP */
+
 /*
  * This is set up by the setup-routine at boot-time
  */
@@ -408,6 +428,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 +741,54 @@
 } /* setup_memory_region */
 
 
-static void __init parse_mem_cmdline (char ** cmdline_p)
+int __init amd_adv_spec_cache_feature(void)
+{
+	char vendor_id[16];
+	int ident;
+	int family, model;
+ 
+	/* Must have CPUID */
+	if(!have_cpuid_p())
+		goto donthave;
+	if(cpuid_eax(0)<1)
+		goto donthave;
+	
+	/* Must be x86 architecture */
+	cpuid(0, &ident,  
+		(int *)&vendor_id[0],
+		(int *)&vendor_id[8],
+		(int *)&vendor_id[4]);
+
+	if (memcmp(vendor_id, "AuthenticAMD", 12)) 
+	       goto donthave;
+
+	ident = cpuid_eax(1);
+	family = (ident >> 8) & 0xf;
+	model  = (ident >> 4) & 0xf;
+	if (((family == 6)  && (model >= 6)) || (family == 15)) {
+		printk(KERN_INFO "Advanced speculative caching feature present\n");
+		return 1;
+	}
+
+donthave:
+	printk(KERN_INFO "Advanced speculative caching feature not present\n");
+	return 0;
+}
+
+
+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 +796,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 +805,54 @@
 			} 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;
+		/*
+		 * unsafe-gart-alias overrides the short-term fix for a
+		 * conflicting cache attribute bug in the kernel that is
+		 * exposed by advanced speculative caching in newer AMD
+		 * Athlon processors.  Overriding the fix will allow
+		 * higher performance but the kernel bug can cause system
+		 * lock-ups if the system uses an AGP card.  unsafe-gart-alias
+		 * can be turned on for higher performance in servers.
+		 */
+		else if (!memcmp(from, "unsafe-gart-alias", 17))
+			disable_adv_spec_cache = 0;
+nextchar:
 		c = *(from++);
 		if (!c)
 			break;
@@ -773,7 +862,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 +909,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 +949,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 +975,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 +1094,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.
 	 */
@@ -983,6 +1116,14 @@
 #ifdef CONFIG_SMP
 	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
 #endif
+	/*
+	 * short-term fix for a conflicting cache attribute bug in the 
+	 * kernel that is exposed by advanced speculative caching on
+	 * newer AMD Athlon processors.
+	 */
+	if (disable_adv_spec_cache && amd_adv_spec_cache_feature())
+		clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
+
 	paging_init();
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
@@ -990,7 +1131,6 @@
 	 */
 	if (smp_found_config)
 		get_smp_config();
-	init_apic_mappings();
 #endif
 
 
@@ -1042,6 +1182,7 @@
 	conswitchp = &dummy_con;
 #endif
 #endif
+	dmi_scan_machine();
 }
 
 static int cachesize_override __initdata = -1;
@@ -1151,6 +1292,31 @@
 	       l2size, ecx & 0xFF);
 }
 
+
+/*=======================================================================
+ * amd_adv_spec_cache_disable
+ * Setting a special MSR big that disables a small part of advanced
+ * speculative caching as part of a short-term fix for a conflicting cache
+ * attribute bug in the kernel that is exposed by advanced speculative
+ * caching in newer AMD Athlon processors.
+ =======================================================================*/
+static void amd_adv_spec_cache_disable(void)
+{
+	printk(KERN_INFO "Disabling advanced speculative caching\n");
+
+	__asm__ __volatile__ (
+		" movl	 $0x9c5a203a,%%edi   \n" /* msr enable */
+		" movl	 $0xc0011022,%%ecx   \n" /* msr addr	 */
+		" rdmsr			     \n" /* get reg val	 */
+		" orl	 $0x00010000,%%eax   \n" /* set bit 16	 */
+		" wrmsr			     \n" /* put it back	 */
+		" xorl	%%edi, %%edi	     \n" /* clear msr enable */
+		: /* no outputs */
+		: /* no inputs, either */
+		: "%eax","%ecx","%edx","%edi" /* clobbered regs */ );
+}
+
+
 /*
  *	B step AMD K6 before B 9730xxxx have hardware bugs that can cause
  *	misexecution of code under Linux. Owners of such processors should
@@ -1284,10 +1450,21 @@
  			 * to enable SSE on Palomino/Morgan CPU's.
 			 * If the BIOS didn't enable it already, enable it
 			 * here.
+			 *
+			 * Avoiding the use of 4MB/2MB pages along with
+			 * setting a special MSR bit that disables a small
+			 * part of advanced speculative caching as part of a
+			 * short-term fix for a conflicting cache attribute
+			 * bug in the kernel that is exposed by advanced
+			 * speculative caching in newer AMD Atlon processors.
+			 *
+			 * If we cleared the PSE bit earlier as part
+			 * of the workaround for this problem, we need
+			 * to clear it again, as our caller may have
+			 * clobbered it if uniprocessor APIC is enabled.
 			 */
-			if (c->x86_model == 6 || c->x86_model == 7) {
-				if (!test_bit(X86_FEATURE_XMM,
-					      &c->x86_capability)) {
+			if (c->x86_model >= 6) {
+				if (!cpu_has_xmm) {
 					printk(KERN_INFO
 					       "Enabling Disabled K7/SSE Support...\n");
 					rdmsr(MSR_K7_HWCR, l, h);
@@ -1296,6 +1473,18 @@
 					set_bit(X86_FEATURE_XMM,
                                                 &c->x86_capability);
 				}
+				if (disable_adv_spec_cache &&
+				    amd_adv_spec_cache_feature()) {
+					clear_bit(X86_FEATURE_PSE,
+						  &c->x86_capability);
+					amd_adv_spec_cache_disable();
+				}
+			}
+			break;
+		case 15: 
+			if (disable_adv_spec_cache && amd_adv_spec_cache_feature()) {
+				clear_bit(X86_FEATURE_PSE, &c->x86_capability);
+				amd_adv_spec_cache_disable();
 			}
 			break;
 
@@ -1306,7 +1495,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 +1657,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 +1678,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 +2402,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 +2462,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"))
@@ -2555,6 +2749,12 @@
 			      &c->x86_capability[0]);
 			c->x86 = (tfms >> 8) & 15;
 			c->x86_model = (tfms >> 4) & 15;
+			if ( (c->x86_vendor == X86_VENDOR_AMD) &&
+				(c->x86 == 0xf)) {
+				/* AMD Extended Family and Model Values */
+				c->x86 += (tfms >> 20) & 0xff;
+				c->x86_model += (tfms >> 12) & 0xf0;
+			}
 			c->x86_mask = tfms & 15;
 		} else {
 			/* Have CPUID level 0 only - unheard of */
@@ -2613,6 +2813,10 @@
 		init_cyrix(c);
 		break;
 
+	case X86_VENDOR_NSC:
+	        init_cyrix(c);
+		break;
+
 	case X86_VENDOR_AMD:
 		init_amd(c);
 		break;
@@ -2655,6 +2859,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 +2921,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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/kernel/signal.c	2002-07-20 01:08:35.000000000 +0000
@@ -658,7 +658,7 @@
 				continue;
 
 			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH:
+			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 				continue;
 
 			case SIGTSTP: case SIGTTIN: case SIGTTOU:
@@ -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	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/i386/kernel/smp.c	2002-07-20 01:08:25.000000000 +0000
@@ -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.
@@ -298,12 +298,15 @@
 /*
  * We cannot call mmdrop() because we are in interrupt context, 
  * instead update mm->cpu_vm_mask.
+ *
+ * We need to reload %cr3 since the page tables may be going
+ * away frm under us...
  */
 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);
+	load_cr3(swapper_pg_dir);
 }
 
 /*
@@ -529,7 +532,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 +548,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 +561,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	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/i386/kernel/smpboot.c	2002-07-20 01:08:36.000000000 +0000
@@ -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;
@@ -973,7 +973,7 @@
 
 static int boot_cpu_logical_apicid;
 /* Where the IO area was mapped on multiquad, always 0 otherwise */
-void *xquad_portio = NULL;
+void *xquad_portio;
 
 int cpu_sibling_map[NR_CPUS] __cacheline_aligned;
 
@@ -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	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/i386/kernel/traps.c	2002-07-20 01:08:27.000000000 +0000
@@ -139,14 +139,14 @@
 	if (!stack)
 		stack = (unsigned long*)&stack;
 
-	printk("Call Trace: ");
+	printk("Call Trace:   ");
 	i = 1;
 	while (((long) stack & (THREAD_SIZE-1)) != 0) {
 		addr = *stack++;
 		if (kernel_text_address(addr)) {
 			if (i && ((i % 6) == 0))
-				printk("\n   ");
-			printk("[<%08lx>] ", addr);
+				printk("\n ");
+			printk(" [<%08lx>]", addr);
 			i++;
 		}
 	}
@@ -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;
 	}
@@ -580,9 +618,10 @@
 		default:
 			break;
 		case 0x001: /* Invalid Op */
-		case 0x040: /* Stack Fault */
-		case 0x240: /* Stack Fault | Direction */
+		case 0x041: /* Stack Fault */
+		case 0x241: /* Stack Fault | Direction */
 			info.si_code = FPE_FLTINV;
+			/* Should we clear the SF or let user space do it ???? */
 			break;
 		case 0x002: /* Denormalize */
 		case 0x010: /* Underflow */
@@ -920,6 +959,10 @@
 		EISA_bus = 1;
 #endif
 
+#ifdef CONFIG_X86_LOCAL_APIC
+	init_apic_mappings();
+#endif
+
 	set_trap_gate(0,&divide_error);
 	set_trap_gate(1,&debug);
 	set_intr_gate(2,&nmi);
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	2001-05-22 17:23:16.000000000 +0000
+++ linux/arch/i386/lib/mmx.c	2002-07-20 01:08:37.000000000 +0000
@@ -57,7 +57,7 @@
 		: : "r" (from) );
 		
 	
-	for(; i>0; i--)
+	for(; i>5; i--)
 	{
 		__asm__ __volatile__ (
 		"1:  prefetch 320(%0)\n"
@@ -89,6 +89,30 @@
 		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;
+	}
 	/*
 	 *	Now do the tail of the block
 	 */
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	1997-12-10 01:57:09.000000000 +0000
+++ linux/arch/i386/math-emu/reg_add_sub.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-04-06 17:42:47.000000000 +0000
+++ linux/arch/i386/math-emu/reg_compare.c	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-04-06 17:42:47.000000000 +0000
+++ linux/arch/i386/math-emu/reg_divide.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-04-06 17:42:47.000000000 +0000
+++ linux/arch/i386/math-emu/reg_ld_str.c	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-04-06 17:42:47.000000000 +0000
+++ linux/arch/i386/math-emu/reg_mul.c	2002-07-20 01:08:30.000000000 +0000
@@ -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	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/i386/mm/fault.c	2002-07-20 01:08:21.000000000 +0000
@@ -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	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/i386/mm/init.c	2002-07-20 01:08:28.000000000 +0000
@@ -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.
@@ -334,7 +331,7 @@
 {
 	pagetable_init();
 
-	__asm__( "movl %%ecx,%%cr3\n" ::"c"(__pa(swapper_pg_dir)));
+	load_cr3(swapper_pg_dir);	
 
 #if CONFIG_X86_PAE
 	/*
@@ -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	2001-03-20 16:13:33.000000000 +0000
+++ linux/arch/i386/mm/ioremap.c	2002-07-20 01:08:29.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/Makefile	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/config.in	2002-07-20 01:08:37.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/defconfig	2002-07-20 01:08:25.000000000 +0000
@@ -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	2000-10-12 21:20:48.000000000 +0000
+++ linux/arch/ia64/hp/hpsim_console.c	2002-07-20 01:08:30.000000000 +0000
@@ -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,
@@ -56,17 +54,6 @@
 	}
 }
 
-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
 simcons_console_device (struct console *c)
 {
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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/ia32/binfmt_elf32.c	2002-07-20 01:08:40.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/ia32/ia32_entry.S	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/ia32/ia32_ioctl.c	2002-07-20 01:08:39.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/ia32/ia32_signal.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/ia32/ia32_support.c	2002-07-20 01:08:24.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/ia32/ia32_traps.c	2002-07-20 01:08:32.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/ia32/sys_ia32.c	2002-07-20 01:08:24.000000000 +0000
@@ -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;
 }
 
 /*
@@ -3810,6 +3812,19 @@
 	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;
+}
+
 #ifdef	NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
 
 struct ncp_mount_data32 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/Makefile linux/arch/ia64/kernel/Makefile
--- linux.orig/arch/ia64/kernel/Makefile	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/Makefile	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/acpi.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/kernel/brl_emu.c	2002-07-20 01:08:29.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/efi.c	2002-07-20 01:08:23.000000000 +0000
@@ -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	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/ia64/kernel/efivars.c	2002-07-20 01:08:35.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/entry.S	2002-07-20 01:08:29.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/gate.S	2002-07-20 01:08:30.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/head.S	2002-07-20 01:08:38.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/ia64_ksyms.c	2002-07-20 01:08:35.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/iosapic.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/irq.c	2002-07-20 01:08:31.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/ivt.S	2002-07-20 01:08:26.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/mca.c	2002-07-20 01:08:36.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/mca_asm.S	2002-07-20 01:08:31.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/palinfo.c	2002-07-20 01:08:22.000000000 +0000
@@ -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	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/perfmon.c	2002-07-20 01:08:33.000000000 +0000
@@ -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_pmcds[0]=0x%lx\n", pmu_conf.counter_pmds[0]);
+	p += sprintf(p, "overflow interrupts=%lu\n", pfm_ovfl_intr_count);
+	p += sprintf(p, "spurious overflow interrupts=%lu\n", pfm_spurious_ovfl_intr_count);
+	p += sprintf(p, "recorded samples=%lu\n", pfm_recorded_samples_count);
+
+	p += sprintf(p, "CPU%d.pmc[0]=%lx\nPerfmon debug: %s\n", 
+			smp_processor_id(), pmc0, pfm_debug_mode ? "On" : "Off");
+
+#ifdef CONFIG_SMP
+	p += sprintf(p, "CPU%d cpu_data.pfm_syst_wide=%d cpu_data.dcr_pp=%d\n", 
+			smp_processor_id(), local_cpu_data->pfm_syst_wide, local_cpu_data->pfm_dcr_pp);
+#endif
+
+	LOCK_PFS();
+	p += sprintf(p, "proc_sessions=%lu\nsys_sessions=%lu\nsys_use_dbregs=%lu\nptrace_use_dbregs=%lu\n", 
+			pfm_sessions.pfs_task_sessions, 
+			pfm_sessions.pfs_sys_sessions,
+			pfm_sessions.pfs_sys_use_dbregs,
+			pfm_sessions.pfs_ptrace_use_dbregs);
+
+	UNLOCK_PFS();
 
 	for(i=0; i < NR_CPUS; i++) {
 		if (cpu_is_online(i)) {
@@ -1794,10 +2842,11 @@
 					pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1);
 		}
 	}
+
 	return p - page;
 }
 
-/* for debug only */
+/* /proc interface, for debug only */
 static int
 perfmon_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
@@ -1814,153 +2863,90 @@
 	return len;
 }
 
-static struct irqaction perfmon_irqaction = {
-	handler:	perfmon_interrupt,
-	flags:		SA_INTERRUPT,
-	name:		"perfmon"
-};
-
-void __init
-perfmon_init (void)
+#ifdef CONFIG_SMP
+void
+pfm_syst_wide_update_task(struct task_struct *task, int mode)
 {
-	pal_perf_mon_info_u_t pm_info;
-	s64 status;
+	struct pt_regs *regs = (struct pt_regs *)((unsigned long) task + IA64_STK_OFFSET);
 
-	register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
+	regs--;
 
-	ia64_set_pmv(IA64_PERFMON_VECTOR);
-	ia64_srlz_d();
-
-	pmu_conf.pfm_is_disabled = 1;
+	/*
+	 * propagate the value of the dcr_pp bit to the psr
+	 */
+	ia64_psr(regs)->pp = mode ? local_cpu_data->pfm_dcr_pp : 0;
+}
+#endif
 
-	printk("perfmon: version %s (sampling format v%d)\n", PFM_VERSION, PFM_SMPL_HDR_VERSION);
-	printk("perfmon: Interrupt vectored to %u\n", IA64_PERFMON_VECTOR);
 
-	if ((status=ia64_pal_perf_mon_info(pmu_conf.impl_regs, &pm_info)) != 0) {
-		printk("perfmon: PAL call failed (%ld)\n", status);
-		return;
-	}
-	pmu_conf.perf_ovfl_val = (1L << pm_info.pal_perf_mon_info_s.width) - 1;
-	pmu_conf.max_counters  = pm_info.pal_perf_mon_info_s.generic;
-	pmu_conf.num_pmcs      = find_num_pm_regs(pmu_conf.impl_regs);
-	pmu_conf.num_pmds      = find_num_pm_regs(&pmu_conf.impl_regs[4]);
+void
+pfm_save_regs (struct task_struct *task)
+{
+	pfm_context_t *ctx;
+	u64 psr;
 
-	printk("perfmon: %d bits counters (max value 0x%lx)\n", pm_info.pal_perf_mon_info_s.width, pmu_conf.perf_ovfl_val);
-	printk("perfmon: %ld PMC/PMD pairs, %ld PMCs, %ld PMDs\n", pmu_conf.max_counters, pmu_conf.num_pmcs, pmu_conf.num_pmds);
+	ctx = task->thread.pfm_context;
 
-	/* sanity check */
-	if (pmu_conf.num_pmds >= IA64_NUM_PMD_REGS || pmu_conf.num_pmcs >= IA64_NUM_PMC_REGS) {
-		printk(KERN_ERR "perfmon: ERROR not enough PMC/PMD storage in kernel, perfmon is DISABLED\n");
-		return; /* no need to continue anyway */
-	}
-	/* we are all set */
-	pmu_conf.pfm_is_disabled = 0;
 
 	/*
-	 * Insert the tasklet in the list.
-	 * It is still disabled at this point, so it won't run
-	printk(__FUNCTION__" tasklet is %p state=%d, count=%d\n", &perfmon_tasklet, perfmon_tasklet.state, perfmon_tasklet.count);
+	 * save current PSR: needed because we modify it
 	 */
+	__asm__ __volatile__ ("mov %0=psr;;": "=r"(psr) :: "memory");
 
 	/*
-	 * for now here for debug purposes
+	 * stop monitoring:
+	 * This is the last instruction which can generate an overflow
+	 *
+	 * We do not need to set psr.sp because, it is irrelevant in kernel.
+	 * It will be restored from ipsr when going back to user level
 	 */
-	perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL);
-}
+	__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+
+	ctx->ctx_saved_psr = psr;
+
+	//ctx->ctx_last_cpu  = smp_processor_id();
 
-void
-perfmon_init_percpu (void)
-{
-	ia64_set_pmv(IA64_PERFMON_VECTOR);
-	ia64_srlz_d();
 }
 
-void
-pfm_save_regs (struct task_struct *ta)
+static void
+pfm_lazy_save_regs (struct task_struct *task)
 {
-	struct task_struct *owner;
 	pfm_context_t *ctx;
 	struct thread_struct *t;
-	u64 pmc0, psr;
 	unsigned long mask;
 	int i;
 
-	t   = &ta->thread;
-	ctx = ta->thread.pfm_context;
+	DBprintk(("on [%d] by [%d]\n", task->pid, current->pid));
 
-	/*
-	 * We must make sure that we don't loose any potential overflow
-	 * interrupt while saving PMU context. In this code, external
-	 * interrupts are always enabled.
-	 */
+	t   = &task->thread;
+	ctx = task->thread.pfm_context;
 
-	/*
-	 * save current PSR: needed because we modify it
+#ifdef CONFIG_SMP
+	/* 
+	 * announce we are saving this PMU state
+	 * This will cause other CPU, to wait until we're done
+	 * before using the context.h
+	 *
+	 * must be an atomic operation
 	 */
-	__asm__ __volatile__ ("mov %0=psr;;": "=r"(psr) :: "memory");
+	atomic_set(&ctx->ctx_saving_in_progress, 1);
 
-	/*
-	 * stop monitoring:
-	 * This is the only way to stop monitoring without destroying overflow
-	 * information in PMC[0].
-	 * This is the last instruction which can cause overflow when monitoring
-	 * in kernel.
-	 * By now, we could still have an overflow interrupt in-flight.
-	 */
-	__asm__ __volatile__ ("rsm psr.up|psr.pp;;"::: "memory");
+	 /*
+	  * if owner is NULL, it means that the other CPU won the race
+	  * and the IPI has caused the context to be saved in pfm_handle_fectch_regs()
+	  * instead of here. We have nothing to do
+	  *
+	  * note that this is safe, because the other CPU NEVER modifies saving_in_progress.
+	  */
+	if (PMU_OWNER() == NULL) goto do_nothing;
+#endif
 
 	/*
-	 * Mark the PMU as not owned
-	 * This will cause the interrupt handler to do nothing in case an overflow
-	 * interrupt was in-flight
-	 * This also guarantees that pmc0 will contain the final state
-	 * It virtually gives us full control over overflow processing from that point
-	 * on.
-	 * It must be an atomic operation.
+	 * do not own the PMU
 	 */
-	owner = PMU_OWNER();
 	SET_PMU_OWNER(NULL);
 
-	/*
-	 * read current overflow status:
-	 *
-	 * we are guaranteed to read the final stable state
-	 */
 	ia64_srlz_d();
-	pmc0 = ia64_get_pmc(0); /* slow */
-
-	/*
-	 * freeze PMU:
-	 *
-	 * This destroys the overflow information. This is required to make sure
-	 * next process does not start with monitoring on if not requested
-	 */
-	ia64_set_pmc(0, 1);
-
-	/*
-	 * Check for overflow bits and proceed manually if needed
-	 *
-	 * It is safe to call the interrupt handler now because it does
-	 * not try to block the task right away. Instead it will set a
-	 * flag and let the task proceed. The blocking will only occur
-	 * next time the task exits from the kernel.
-	 */
-	if (pmc0 & ~0x1) {
-		update_counters(owner, pmc0, NULL);
-		/* we will save the updated version of pmc0 */
-	}
-	/*
-	 * restore PSR for context switch to save
-	 */
-	__asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(psr): "memory");
-
-	/*
-	 * we do not save registers if we can do lazy
-	 */
-	if (PFM_CAN_DO_LAZY()) {
-		SET_PMU_OWNER(owner);
-		return;
-	}
 
 	/*
 	 * XXX needs further optimization.
@@ -1970,30 +2956,75 @@
 	for (i=0; mask; i++, mask>>=1) {
 		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
 	}
-
-	/* skip PMC[0], we handle it separately */
-	mask = ctx->ctx_used_pmcs[0]>>1;
-	for (i=1; mask; i++, mask>>=1) {
+	/*
+	 * XXX: simplify to pmc0 only
+	 */
+	mask = ctx->ctx_saved_pmcs[0];
+	for (i=0; mask; i++, mask>>=1) {
 		if (mask & 0x1) t->pmc[i] = ia64_get_pmc(i);
 	}
+
+	/* not owned by this CPU */
+	atomic_set(&ctx->ctx_last_cpu, -1);
+
+#ifdef CONFIG_SMP
+do_nothing:
+#endif
 	/*
-	 * Throughout this code we could have gotten an overflow interrupt. It is transformed
-	 * into a spurious interrupt as soon as we give up pmu ownership.
+	 * declare we are done saving this context
+	 *
+	 * must be an atomic operation
 	 */
+	atomic_set(&ctx->ctx_saving_in_progress,0);
+
 }
 
-static void
-pfm_lazy_save_regs (struct task_struct *ta)
+#ifdef CONFIG_SMP
+/*
+ * Handles request coming from other CPUs
+ */
+static void 
+pfm_handle_fetch_regs(void *info)
 {
-	pfm_context_t *ctx;
+	pfm_smp_ipi_arg_t *arg = info;
 	struct thread_struct *t;
+	pfm_context_t *ctx;
 	unsigned long mask;
 	int i;
 
-	DBprintk(("  on [%d] by [%d]\n", ta->pid, current->pid));
+	ctx = arg->task->thread.pfm_context;
+	t   = &arg->task->thread;
+
+	DBprintk(("task=%d owner=%d saving=%d\n", 
+		  arg->task->pid,
+		  PMU_OWNER() ? PMU_OWNER()->pid: -1,
+		  atomic_read(&ctx->ctx_saving_in_progress)));
+
+	/* must wait if saving was interrupted */
+	if (atomic_read(&ctx->ctx_saving_in_progress)) {
+		arg->retval = 1;
+		return;
+	}
+
+	/* can proceed, done with context */
+	if (PMU_OWNER() != arg->task) {
+		arg->retval = 0;
+		return;
+	}
+
+	DBprintk(("saving state for [%d] save_pmcs=0x%lx all_pmcs=0x%lx used_pmds=0x%lx\n", 
+		arg->task->pid,
+		ctx->ctx_saved_pmcs[0],
+		ctx->ctx_reload_pmcs[0],
+		ctx->ctx_used_pmds[0]));
+
+	/*
+	 * XXX: will be replaced with pure assembly call
+	 */
+	SET_PMU_OWNER(NULL);
+
+	ia64_srlz_d();
 
-	t   = &ta->thread;
-	ctx = ta->thread.pfm_context;
 	/*
 	 * XXX needs further optimization.
 	 * Also must take holes into account
@@ -2003,84 +3034,295 @@
 		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
 	}
 	
-	/* skip PMC[0], we handle it separately */
-	mask = ctx->ctx_used_pmcs[0]>>1;
-	for (i=1; mask; i++, mask>>=1) {
+	mask = ctx->ctx_saved_pmcs[0];
+	for (i=0; mask; i++, mask>>=1) {
 		if (mask & 0x1) t->pmc[i] = ia64_get_pmc(i);
 	}
-	SET_PMU_OWNER(NULL);
+	/* not owned by this CPU */
+	atomic_set(&ctx->ctx_last_cpu, -1);
+
+	/* can proceed */
+	arg->retval = 0;
+}
+
+/*
+ * Function call to fetch PMU state from another CPU identified by 'cpu'.
+ * If the context is being saved on the remote CPU, then we busy wait until
+ * the saving is done and then we return. In this case, non IPI is sent.
+ * Otherwise, we send an IPI to the remote CPU, potentially interrupting 
+ * pfm_lazy_save_regs() over there.
+ *
+ * If the retval==1, then it means that we interrupted remote save and that we must
+ * wait until the saving is over before proceeding.
+ * Otherwise, we did the saving on the remote CPU, and it was done by the time we got there.
+ * in either case, we can proceed.
+ */
+static void
+pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx)
+{
+	pfm_smp_ipi_arg_t  arg;
+	int ret;
+
+	arg.task   = task;
+	arg.retval = -1;
+
+	if (atomic_read(&ctx->ctx_saving_in_progress)) {
+		DBprintk(("no IPI, must wait for [%d] to be saved on [%d]\n", task->pid, cpu));
+
+		/* busy wait */
+		while (atomic_read(&ctx->ctx_saving_in_progress));
+		return;
+	}
+	DBprintk(("calling CPU %d from CPU %d\n", cpu, smp_processor_id()));
+
+	if (cpu == -1) {
+		printk("refusing to use -1 for [%d]\n", task->pid);
+		return;
+	}
+
+	/* will send IPI to other CPU and wait for completion of remote call */
+	if ((ret=smp_call_function_single(cpu, pfm_handle_fetch_regs, &arg, 0, 1))) {
+		printk("perfmon: remote CPU call from %d to %d error %d\n", smp_processor_id(), cpu, ret);
+		return;
+	}
+	/*
+	 * we must wait until saving is over on the other CPU
+	 * This is the case, where we interrupted the saving which started just at the time we sent the
+	 * IPI.
+	 */
+	if (arg.retval == 1) {
+		DBprintk(("must wait for [%d] to be saved on [%d]\n", task->pid, cpu));
+		while (atomic_read(&ctx->ctx_saving_in_progress));
+		DBprintk(("done saving for [%d] on [%d]\n", task->pid, cpu));
+	}
 }
+#endif /* CONFIG_SMP */
 
 void
-pfm_load_regs (struct task_struct *ta)
+pfm_load_regs (struct task_struct *task)
 {
-	struct thread_struct *t = &ta->thread;
-	pfm_context_t *ctx = ta->thread.pfm_context;
+	struct thread_struct *t;
+	pfm_context_t *ctx;
 	struct task_struct *owner;
 	unsigned long mask;
+	u64 psr;
 	int i;
+#ifdef CONFIG_SMP
+	int cpu;
+#endif
 
 	owner = PMU_OWNER();
-	if (owner == ta) goto skip_restore;
+	ctx   = task->thread.pfm_context;
+
+	/*
+	 * if we were the last user, then nothing to do except restore psr
+	 */
+	if (owner == task) {
+		if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id())
+			DBprintk(("invalid last_cpu=%d for [%d]\n", 
+				atomic_read(&ctx->ctx_last_cpu), task->pid));
+
+		psr = ctx->ctx_saved_psr;
+		__asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(psr): "memory");
+
+		return;
+	}
+	DBprintk(("load_regs: must reload for [%d] owner=%d\n", 
+		task->pid, owner ? owner->pid : -1 ));
+	/*
+	 * someone else is still using the PMU, first push it out and
+	 * then we'll be able to install our stuff !
+	 */
 	if (owner) pfm_lazy_save_regs(owner);
 
-	SET_PMU_OWNER(ta);
+#ifdef CONFIG_SMP
+	/* 
+	 * check if context on another CPU (-1 means saved)
+	 * We MUST use the variable, as last_cpu may change behind our 
+	 * back. If it changes to -1 (not on a CPU anymore), then in cpu
+	 * we have the last CPU the context was on. We may be sending the 
+	 * IPI for nothing, but we have no way of verifying this. 
+	 */
+	cpu = atomic_read(&ctx->ctx_last_cpu);
+	if (cpu != -1) {
+		pfm_fetch_regs(cpu, task, ctx);
+	}
+#endif
+	t   = &task->thread;
 
+	/*
+	 * XXX: will be replaced by assembly routine
+	 * We clear all unused PMDs to avoid leaking information
+	 */
 	mask = ctx->ctx_used_pmds[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) ia64_set_pmd(i, t->pmd[i]);
+		if (mask & 0x1) 
+			ia64_set_pmd(i, t->pmd[i]);
+		else
+			ia64_set_pmd(i, 0UL);
 	}
+	/* XXX: will need to clear all unused pmd, for security */
 
-	/* skip PMC[0] to avoid side effects */
-	mask = ctx->ctx_used_pmcs[0]>>1;
+	/* 
+	 * skip pmc[0] to avoid side-effects, 
+	 * all PMCs are systematically reloaded, unsued get default value
+	 * to avoid picking up stale configuration
+	 */	
+	mask = ctx->ctx_reload_pmcs[0]>>1;
 	for (i=1; mask; i++, mask>>=1) {
 		if (mask & 0x1) ia64_set_pmc(i, t->pmc[i]);
 	}
-skip_restore:
+
+	/*
+	 * restore debug registers when used for range restrictions.
+	 * We must restore the unused registers to avoid picking up
+	 * stale information.
+	 */
+	mask = ctx->ctx_used_ibrs[0];
+	for (i=0; mask; i++, mask>>=1) {
+		if (mask & 0x1) 
+			ia64_set_ibr(i, t->ibr[i]);
+		else
+			ia64_set_ibr(i, 0UL);
+	}
+
+	mask = ctx->ctx_used_dbrs[0];
+	for (i=0; mask; i++, mask>>=1) {
+		if (mask & 0x1) 
+			ia64_set_dbr(i, t->dbr[i]);
+		else
+			ia64_set_dbr(i, 0UL);
+	}
+
+	if (t->pmc[0] & ~0x1) {
+		ia64_srlz_d();
+		pfm_overflow_handler(task, t->pmc[0], NULL);
+	}
+
+	/*
+	 * fl_frozen==1 when we are in blocking mode waiting for restart
+	 */
+	if (ctx->ctx_fl_frozen == 0) {
+		ia64_set_pmc(0, 0);
+		ia64_srlz_d();
+	}
+	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
+
+	SET_PMU_OWNER(task);
+
+	/*
+	 * restore the psr we changed in pfm_save_regs()
+	 */
+	psr = ctx->ctx_saved_psr;
+	__asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(psr): "memory");
+
+}
+
+/*
+ * XXX: make this routine able to work with non current context
+ */
+static void
+ia64_reset_pmu(struct task_struct *task)
+{
+	struct thread_struct *t = &task->thread;
+	pfm_context_t *ctx = t->pfm_context;
+	unsigned long mask;
+	int i;
+
+	if (task != current) {
+		printk("perfmon: invalid task in ia64_reset_pmu()\n");
+		return;
+	}
+
+	/* Let's make sure the PMU is frozen */
+	ia64_set_pmc(0,1);
+
+	/*
+	 * install reset values for PMC. We skip PMC0 (done above)
+	 * XX: good up to 64 PMCS
+	 */
+	mask = pmu_conf.impl_regs[0] >> 1;
+	for(i=1; mask; mask>>=1, i++) {
+		if (mask & 0x1) {
+			ia64_set_pmc(i, reset_pmcs[i]);
+			/*
+			 * When restoring context, we must restore ALL pmcs, even the ones 
+			 * that the task does not use to avoid leaks and possibly corruption
+			 * of the sesion because of configuration conflicts. So here, we 
+			 * initializaed the table used in the context switch restore routine.
+	 		 */
+			t->pmc[i] = reset_pmcs[i];
+			DBprintk((" pmc[%d]=0x%lx\n", i, reset_pmcs[i]));
+						 
+		}
+	}
+	/*
+	 * clear reset values for PMD. 
+	 * XX: good up to 64 PMDS. Suppose that zero is a valid value.
+	 */
+	mask = pmu_conf.impl_regs[4];
+	for(i=0; mask; mask>>=1, i++) {
+		if (mask & 0x1) ia64_set_pmd(i, 0UL);
+	}
+
 	/*
-	 * unfreeze only when possible
+	 * On context switched restore, we must restore ALL pmc even
+	 * when they are not actively used by the task. In UP, the incoming process 
+	 * may otherwise pick up left over PMC state from the previous process.
+	 * As opposed to PMD, stale PMC can cause harm to the incoming
+	 * process because they may change what is being measured. 
+	 * Therefore, we must systematically reinstall the entire
+	 * PMC state. In SMP, the same thing is possible on the 
+	 * same CPU but also on between 2 CPUs.
+	 *
+	 * There is unfortunately no easy way to avoid this problem
+	 * on either UP or SMP. This definitively slows down the 
+	 * pfm_load_regs(). 
 	 */
-	if (ctx->ctx_fl_frozen == 0) {
-		ia64_set_pmc(0, 0);
-		ia64_srlz_d();
-		/* place where we potentially (kernel level) start monitoring again */
-	}
-}
+	
+	 /*
+	  * We must include all the PMC in this mask to make sure we don't
+	  * see any side effect of the stale state, such as opcode matching
+	  * or range restrictions, for instance.
+	  */
+	ctx->ctx_reload_pmcs[0] = pmu_conf.impl_regs[0];
 
+	/*
+	 * useful in case of re-enable after disable
+	 */
+	ctx->ctx_used_pmds[0] = 0UL;
+	ctx->ctx_used_ibrs[0] = 0UL;
+	ctx->ctx_used_dbrs[0] = 0UL;
+
+	ia64_srlz_d();
+}
 
 /*
  * This function is called when a thread exits (from exit_thread()).
  * This is a simplified pfm_save_regs() that simply flushes the current
  * register state into the save area taking into account any pending
- * overflow. This time no notification is sent because the taks is dying
+ * overflow. This time no notification is sent because the task is dying
  * anyway. The inline processing of overflows avoids loosing some counts.
  * The PMU is frozen on exit from this call and is to never be reenabled
  * again for this task.
+ *
  */
 void
-pfm_flush_regs (struct task_struct *ta)
+pfm_flush_regs (struct task_struct *task)
 {
 	pfm_context_t *ctx;
-	u64 pmc0, psr, mask;
-	int i,j;
+	u64 pmc0;
+	unsigned long mask, mask2, val;
+	int i;
 
-	if (ta == NULL) {
-		panic(__FUNCTION__" task is NULL\n");
-	}
-	ctx = ta->thread.pfm_context;
-	if (ctx == NULL) {
-		panic(__FUNCTION__" no PFM ctx is NULL\n");
-	}
-	/*
-	 * We must make sure that we don't loose any potential overflow
-	 * interrupt while saving PMU context. In this code, external
-	 * interrupts are always enabled.
-	 */
+	ctx = task->thread.pfm_context;
 
-	/*
-	 * save current PSR: needed because we modify it
+	if (ctx == NULL) return;
+
+	/* 
+	 * that's it if context already disabled
 	 */
-	__asm__ __volatile__ ("mov %0=psr;;": "=r"(psr) :: "memory");
+	if (ctx->ctx_flags.state == PFM_CTX_DISABLED) return;
 
 	/*
 	 * stop monitoring:
@@ -2090,7 +3332,27 @@
 	 * in kernel.
 	 * By now, we could still have an overflow interrupt in-flight.
 	 */
-	__asm__ __volatile__ ("rsm psr.up;;"::: "memory");
+	if (ctx->ctx_fl_system) {
+
+		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+
+		/* disable dcr pp */
+		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
+
+#ifdef CONFIG_SMP
+		local_cpu_data->pfm_syst_wide = 0;
+		local_cpu_data->pfm_dcr_pp    = 0;
+#else
+		pfm_tasklist_toggle_pp(0);
+#endif
+
+	} else  {
+
+		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+
+		/* no more save/restore on ctxsw */
+		current->thread.flags &= ~IA64_THREAD_PM_VALID;
+	}
 
 	/*
 	 * Mark the PMU as not owned
@@ -2121,85 +3383,68 @@
 	ia64_srlz_d();
 
 	/*
-	 * restore PSR for context switch to save
+	 * We don't need to restore psr, because we are on our way out anyway
 	 */
-	__asm__ __volatile__ ("mov psr.l=%0;;srlz.i;"::"r"(psr): "memory");
 
 	/*
 	 * This loop flushes the PMD into the PFM context.
-	 * IT also processes overflow inline.
+	 * It also processes overflow inline.
 	 *
 	 * IMPORTANT: No notification is sent at this point as the process is dying.
 	 * The implicit notification will come from a SIGCHILD or a return from a
 	 * waitpid().
 	 *
-	 * XXX: must take holes into account
 	 */
-	mask = pmc0 >> PMU_FIRST_COUNTER;
-	for (i=0,j=PMU_FIRST_COUNTER; i< pmu_conf.max_counters; i++,j++) {
-
-		/* collect latest results */
-		ctx->ctx_pmds[i].val += ia64_get_pmd(j) & pmu_conf.perf_ovfl_val;
-
-		/*
-		 * now everything is in ctx_pmds[] and we need
-		 * to clear the saved context from save_regs() such that
-		 * pfm_read_pmds() gets the correct value
-		 */
-		ta->thread.pmd[j] = 0;
 
-		/* take care of overflow inline */
-		if (mask & 0x1) {
-			ctx->ctx_pmds[i].val += 1 + pmu_conf.perf_ovfl_val;
-			DBprintk((" PMD[%d] overflowed pmd=0x%lx pmds.val=0x%lx\n",
-			j, ia64_get_pmd(j), ctx->ctx_pmds[i].val));
-		}
-		mask >>=1;
-	}
-}
+	if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) 
+		printk("perfmon: [%d] last_cpu=%d\n", task->pid, atomic_read(&ctx->ctx_last_cpu));
 
-/*
- * XXX: this routine is not very portable for PMCs
- * XXX: make this routine able to work with non current context
- */
-static void
-ia64_reset_pmu(void)
-{
-	int i;
+	mask  = pmc0 >> PMU_FIRST_COUNTER;
+	mask2 = ctx->ctx_used_pmds[0] >> PMU_FIRST_COUNTER;
 
-	/* PMU is frozen, no pending overflow bits */
-	ia64_set_pmc(0,1);
+	for (i = PMU_FIRST_COUNTER; mask2; i++, mask>>=1, mask2>>=1) {
 
-	/* extra overflow bits + counter configs cleared */
-	for(i=1; i< PMU_FIRST_COUNTER + pmu_conf.max_counters ; i++) {
-		ia64_set_pmc(i,0);
-	}
+		/* skip non used pmds */
+		if ((mask2 & 0x1) == 0) continue;
 
-	/* opcode matcher set to all 1s */
-	ia64_set_pmc(8,~0);
-	ia64_set_pmc(9,~0);
+		val = ia64_get_pmd(i);
 
-	/* I-EAR config cleared, plm=0 */
-	ia64_set_pmc(10,0);
+		if (PMD_IS_COUNTING(i)) {
 
-	/* D-EAR config cleared, PMC[11].pt must be 1 */
-	ia64_set_pmc(11,1 << 28);
+			DBprintk(("[%d] pmd[%d] soft_pmd=0x%lx hw_pmd=0x%lx\n", task->pid, i, ctx->ctx_soft_pmds[i].val, val & pmu_conf.perf_ovfl_val));
 
-	/* BTB config. plm=0 */
-	ia64_set_pmc(12,0);
+			/* collect latest results */
+			ctx->ctx_soft_pmds[i].val += val & pmu_conf.perf_ovfl_val;
 
-	/* Instruction address range, PMC[13].ta must be 1 */
-	ia64_set_pmc(13,1);
+			/*
+			 * now everything is in ctx_soft_pmds[] and we need
+			 * to clear the saved context from save_regs() such that
+			 * pfm_read_pmds() gets the correct value
+			 */
+			task->thread.pmd[i] = 0;
 
-	/* clears all PMD registers */
-	for(i=0;i< pmu_conf.num_pmds; i++) {
-		if (PMD_IS_IMPL(i))  ia64_set_pmd(i,0);
+			/* take care of overflow inline */
+			if (mask & 0x1) {
+				ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.perf_ovfl_val;
+				DBprintk(("[%d] pmd[%d] overflowed soft_pmd=0x%lx\n",
+					task->pid, i, ctx->ctx_soft_pmds[i].val));
+			}
+		} else {
+			DBprintk(("[%d] pmd[%d] hw_pmd=0x%lx\n", task->pid, i, val));
+			/* not a counter, just save value as is */
+			task->thread.pmd[i] = val;
+		}
 	}
-	ia64_srlz_d();
+	/* 
+	 * indicates that context has been saved
+	 */
+	atomic_set(&ctx->ctx_last_cpu, -1);
+
 }
 
+
 /*
- * task is the newly created task
+ * task is the newly created task, pt_regs for new child
  */
 int
 pfm_inherit(struct task_struct *task, struct pt_regs *regs)
@@ -2207,25 +3452,29 @@
 	pfm_context_t *ctx = current->thread.pfm_context;
 	pfm_context_t *nctx;
 	struct thread_struct *th = &task->thread;
-	int i, cnum;
+	unsigned long m;
+	int i;
 
 	/*
-	 * bypass completely for system wide
+	 * make sure child cannot mess up the monitoring session
 	 */
-	if (pfs_info.pfs_sys_session) {
-		DBprintk((" enabling psr.pp for %d\n", task->pid));
-		ia64_psr(regs)->pp = pfs_info.pfs_pp;
-		return 0;
-	}
+	 ia64_psr(regs)->sp = 1;
+	 DBprintk(("enabling psr.sp for [%d]\n", task->pid));
+
+	 /*
+	  * remove any sampling buffer mapping from child user 
+	  * address space. Must be done for all cases of inheritance.
+	  */
+	 if (ctx->ctx_smpl_vaddr) pfm_remove_smpl_mapping(task);
 
 	/*
 	 * takes care of easiest case first
 	 */
 	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_NONE) {
-		DBprintk((" removing PFM context for %d\n", task->pid));
+		DBprintk(("removing PFM context for [%d]\n", task->pid));
 		task->thread.pfm_context     = NULL;
-		task->thread.pfm_must_block  = 0;
-		atomic_set(&task->thread.pfm_notifiers_check, 0);
+		task->thread.pfm_ovfl_block_reset  = 0;
+
 		/* copy_thread() clears IA64_THREAD_PM_VALID */
 		return 0;
 	}
@@ -2235,45 +3484,81 @@
 	/* copy content */
 	*nctx = *ctx;
 
+
 	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) {
 		nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE;
-		atomic_set(&task->thread.pfm_notifiers_check, 0);
-		DBprintk((" downgrading to INHERIT_NONE for %d\n", task->pid));
-		pfs_info.pfs_proc_sessions++;
+		atomic_set(&nctx->ctx_last_cpu, -1);
+
+		/*
+		 * task is not yet visible in the tasklist, so we do 
+		 * not need to lock the newly created context.
+		 * However, we must grab the tasklist_lock to ensure
+		 * that the ctx_owner or ctx_notify_task do not disappear
+		 * while we increment their check counters.
+		 */
+		read_lock(&tasklist_lock);
+
+		if (nctx->ctx_notify_task) 
+			atomic_inc(&nctx->ctx_notify_task->thread.pfm_notifiers_check);
+
+		if (nctx->ctx_owner)
+			atomic_inc(&nctx->ctx_owner->thread.pfm_owners_check);
+
+		read_unlock(&tasklist_lock);
+
+		DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid));
+
+		LOCK_PFS();
+		pfm_sessions.pfs_task_sessions++;
+		UNLOCK_PFS();
 	}
 
 	/* initialize counters in new context */
-	for(i=0, cnum= PMU_FIRST_COUNTER; i < pmu_conf.max_counters; cnum++, i++) {
-		nctx->ctx_pmds[i].val = nctx->ctx_pmds[i].ival & ~pmu_conf.perf_ovfl_val;
-		th->pmd[cnum]	      = nctx->ctx_pmds[i].ival & pmu_conf.perf_ovfl_val;
+	m = pmu_conf.counter_pmds[0] >> PMU_FIRST_COUNTER;
+	for(i = PMU_FIRST_COUNTER ; m ; m>>=1, i++) {
+		if (m & 0x1) {
+			nctx->ctx_soft_pmds[i].val = nctx->ctx_soft_pmds[i].ival & ~pmu_conf.perf_ovfl_val;
+			th->pmd[i]	      	   = nctx->ctx_soft_pmds[i].ival & pmu_conf.perf_ovfl_val;
+		}
 
 	}
 	/* clear BTB index register */
 	th->pmd[16] = 0;
 
 	/* if sampling then increment number of users of buffer */
-	if (nctx->ctx_smpl_buf) {
-		atomic_inc(&nctx->ctx_smpl_buf->psb_refcnt);
+	if (nctx->ctx_psb) {
+
+		/*
+		 * XXX: nopt very pretty!
+		 */
+		LOCK_PSB(nctx->ctx_psb);
+		nctx->ctx_psb->psb_refcnt++;
+		UNLOCK_PSB(nctx->ctx_psb);
+		/*
+	 	 * remove any pointer to sampling buffer mapping
+	 	 */
+		nctx->ctx_smpl_vaddr = 0;
 	}
 
 	nctx->ctx_fl_frozen = 0;
-	nctx->ctx_ovfl_regs = 0;
+	nctx->ctx_ovfl_regs[0] = 0UL;
+
 	sema_init(&nctx->ctx_restart_sem, 0); /* reset this semaphore to locked */
 
 	/* clear pending notification */
-	th->pfm_must_block = 0;
+	th->pfm_ovfl_block_reset = 0;
 
 	/* link with new task */
-	th->pfm_context     = nctx;
+	th->pfm_context    = nctx;
 
-	DBprintk((" nctx=%p for process %d\n", (void *)nctx, task->pid));
+	DBprintk(("nctx=%p for process [%d]\n", (void *)nctx, task->pid));
 
 	/*
 	 * the copy_thread routine automatically clears
 	 * IA64_THREAD_PM_VALID, so we need to reenable it, if it was used by the caller
 	 */
 	if (current->thread.flags & IA64_THREAD_PM_VALID) {
-		DBprintk(("  setting PM_VALID for %d\n", task->pid));
+		DBprintk(("setting PM_VALID for [%d]\n", task->pid));
 		th->flags |= IA64_THREAD_PM_VALID;
 	}
 
@@ -2281,100 +3566,249 @@
 }
 
 /* 
- * called from release_thread(), at this point this task is not in the 
- * tasklist anymore
+ *
+ * We cannot touch any of the PMU registers at this point as we may
+ * not be running on the same CPU the task was last run on.  Therefore
+ * it is assumed that the PMU has been stopped appropriately in
+ * pfm_flush_regs() called from exit_thread(). 
+ *
+ * The function is called in the context of the parent via a release_thread()
+ * and wait4(). The task is not in the tasklist anymore.
  */
 void
 pfm_context_exit(struct task_struct *task)
 {
 	pfm_context_t *ctx = task->thread.pfm_context;
 
-	if (!ctx) {
-		DBprintk((" invalid context for %d\n", task->pid));
-		return;
-	}
+	/*
+	 * check sampling buffer
+	 */
+	if (ctx->ctx_psb) {
+		pfm_smpl_buffer_desc_t *psb = ctx->ctx_psb;
+
+		LOCK_PSB(psb);
+
+		DBprintk(("sampling buffer from [%d] @%p size %ld vma_flag=0x%x\n",
+			task->pid,
+			psb->psb_hdr, psb->psb_size, psb->psb_flags));
+
+		/*
+		 * in the case where we are the last user, we may be able to free
+		 * the buffer
+		 */
+		psb->psb_refcnt--;
+
+		if (psb->psb_refcnt == 0) {
+
+			/*
+			 * The flag is cleared in pfm_vm_close(). which gets 
+			 * called from do_exit() via exit_mm(). 
+			 * By the time we come here, the task has no more mm context.
+			 *
+			 * We can only free the psb and buffer here after the vm area
+			 * describing the buffer has been removed. This normally happens 
+			 * as part of do_exit() but the entire mm context is ONLY removed
+			 * once its reference counts goes to zero. This is typically
+			 * the case except for multi-threaded (several tasks) processes.
+			 *
+			 * See pfm_vm_close() and pfm_cleanup_smpl_buf() for more details.
+			 */
+			if ((psb->psb_flags & PFM_PSB_VMA) == 0) {
+
+				DBprintk(("cleaning sampling buffer from [%d] @%p size %ld\n",
+					task->pid,
+					psb->psb_hdr, psb->psb_size));
+
+				/* 
+				 * free the buffer and psb 
+				 */
+				pfm_rvfree(psb->psb_hdr, psb->psb_size);
+				kfree(psb);
+				psb = NULL;
+			} 
+		} 
+		/* psb may have been deleted */
+		if (psb) UNLOCK_PSB(psb);
+	} 
+
+	DBprintk(("cleaning [%d] pfm_context @%p notify_task=%p check=%d mm=%p\n", 
+		task->pid, ctx, 
+		ctx->ctx_notify_task, 
+		atomic_read(&task->thread.pfm_notifiers_check), task->mm));
 
-	/* check is we have a sampling buffer attached */
-	if (ctx->ctx_smpl_buf) {
-		pfm_smpl_buffer_desc_t *psb = ctx->ctx_smpl_buf;
-
-		/* if only user left, then remove */
-		DBprintk((" [%d] [%d] psb->refcnt=%d\n", current->pid, task->pid, psb->psb_refcnt.counter));
-
-		if (atomic_dec_and_test(&psb->psb_refcnt) ) {
-			rvfree(psb->psb_hdr, psb->psb_size);
-			vfree(psb);
-			DBprintk((" [%d] cleaning [%d] sampling buffer\n", current->pid, task->pid ));
-		}
-	}
-	DBprintk((" [%d] cleaning [%d] pfm_context @%p\n", current->pid, task->pid, (void *)ctx));
-
-	/*
-	 * To avoid getting the notified task scan the entire process list
-	 * when it exits because it would have pfm_notifiers_check set, we 
-	 * decrease it by 1 to inform the task, that one less task is going
-	 * to send it notification. each new notifer increases this field by
-	 * 1 in pfm_context_create(). Of course, there is race condition between
-	 * decreasing the value and the notified task exiting. The danger comes
-	 * from the fact that we have a direct pointer to its task structure
-	 * thereby bypassing the tasklist. We must make sure that if we have 
-	 * notify_task!= NULL, the target task is still somewhat present. It may
-	 * already be detached from the tasklist but that's okay. Note that it is
-	 * okay if we 'miss the deadline' and the task scans the list for nothing,
-	 * it will affect performance but not correctness. The correctness is ensured
-	 * by using the notify_lock whic prevents the notify_task from changing on us.
-	 * Once holdhing this lock, if we see notify_task!= NULL, then it will stay like
+	/*
+	 * To avoid getting the notified task or owner task scan the entire process 
+	 * list when they exit, we decrement notifiers_check and owners_check respectively.
+	 *
+	 * Of course, there is race condition between decreasing the value and the 
+	 * task exiting. The danger comes from the fact that, in both cases, we have a 
+	 * direct pointer to a task structure thereby bypassing the tasklist. 
+	 * We must make sure that, if we have task!= NULL, the target task is still 
+	 * present and is identical to the initial task specified 
+	 * during pfm_create_context(). It may already be detached from the tasklist but 
+	 * that's okay. Note that it is okay if we miss the deadline and the task scans 
+	 * the list for nothing, it will affect performance but not correctness. 
+	 * The correctness is ensured by using the ctx_lock which prevents the 
+	 * notify_task from changing the fields in our context.
+	 * Once holdhing this lock, if we see task!= NULL, then it will stay like
 	 * that until we release the lock. If it is NULL already then we came too late.
 	 */
-	spin_lock(&ctx->ctx_notify_lock);
+	LOCK_CTX(ctx);
 
-	if (ctx->ctx_notify_task) {
-		DBprintk((" [%d] [%d] atomic_sub on [%d] notifiers=%u\n", current->pid, task->pid,
-					ctx->ctx_notify_task->pid, 
-					atomic_read(&ctx->ctx_notify_task->thread.pfm_notifiers_check)));
+	if (ctx->ctx_notify_task != NULL) {
+		DBprintk(("[%d], [%d] atomic_sub on [%d] notifiers=%u\n", current->pid,
+			task->pid,
+			ctx->ctx_notify_task->pid, 
+			atomic_read(&ctx->ctx_notify_task->thread.pfm_notifiers_check)));
+
+		atomic_dec(&ctx->ctx_notify_task->thread.pfm_notifiers_check);
+	}
+
+	if (ctx->ctx_owner != NULL) {
+		DBprintk(("[%d], [%d] atomic_sub on [%d] owners=%u\n", 
+			 current->pid, 
+			 task->pid,
+			 ctx->ctx_owner->pid, 
+			 atomic_read(&ctx->ctx_owner->thread.pfm_owners_check)));
 
-		atomic_sub(1, &ctx->ctx_notify_task->thread.pfm_notifiers_check);
+		atomic_dec(&ctx->ctx_owner->thread.pfm_owners_check);
 	}
 
-	spin_unlock(&ctx->ctx_notify_lock);
+	UNLOCK_CTX(ctx);
+
+	LOCK_PFS();
 
 	if (ctx->ctx_fl_system) {
-		/*
-		 * if included interrupts (true by default), then reset
-		 * to get default value
-		 */
-		if (ctx->ctx_fl_exclintr == 0) {
-			/*
-			 * reload kernel default DCR value
-			 */
-			ia64_set_dcr(pfs_info.pfs_dfl_dcr);
-			DBprintk((" restored dcr to 0x%lx\n", pfs_info.pfs_dfl_dcr));
+
+		pfm_sessions.pfs_sys_session[ctx->ctx_cpu] = NULL;
+		pfm_sessions.pfs_sys_sessions--;
+		DBprintk(("freeing syswide session on CPU%ld\n", ctx->ctx_cpu));
+		/* update perfmon debug register counter */
+		if (ctx->ctx_fl_using_dbreg) {
+			if (pfm_sessions.pfs_sys_use_dbregs == 0) {
+				printk("perfmon: invalid release for [%d] sys_use_dbregs=0\n", task->pid);
+			} else
+				pfm_sessions.pfs_sys_use_dbregs--;
 		}
-		/* 
-		 * free system wide session slot
-		 */
-		pfs_info.pfs_sys_session = 0;
+
+		/*
+	 	 * remove any CPU pinning
+	 	 */
+		task->cpus_allowed = ctx->ctx_saved_cpus_allowed;
+		task->need_resched = 1;
 	} else {
-		pfs_info.pfs_proc_sessions--;
+		pfm_sessions.pfs_task_sessions--;
 	}
+	UNLOCK_PFS();
 
 	pfm_context_free(ctx);
 	/* 
 	 *  clean pfm state in thread structure,
 	 */
-	task->thread.pfm_context    = NULL;
-	task->thread.pfm_must_block = 0;
+	task->thread.pfm_context          = NULL;
+	task->thread.pfm_ovfl_block_reset = 0;
+
 	/* pfm_notifiers is cleaned in pfm_cleanup_notifiers() */
+}
+
+/*
+ * function invoked from release_thread when pfm_smpl_buf_list is not NULL
+ */
+int
+pfm_cleanup_smpl_buf(struct task_struct *task)
+{
+	pfm_smpl_buffer_desc_t *tmp, *psb = task->thread.pfm_smpl_buf_list;
 
+	if (psb == NULL) {
+		printk("perfmon: psb is null in [%d]\n", current->pid);
+		return -1;
+	}
+	/*
+	 * Walk through the list and free the sampling buffer and psb
+	 */
+	while (psb) {
+		DBprintk(("[%d] freeing smpl @%p size %ld\n", current->pid, psb->psb_hdr, psb->psb_size));
+
+		pfm_rvfree(psb->psb_hdr, psb->psb_size);
+		tmp = psb->psb_next;
+		kfree(psb);
+		psb = tmp;
+	}
+
+	/* just in case */
+	task->thread.pfm_smpl_buf_list = NULL;
+
+	return 0;
+}
+
+/*
+ * function invoked from release_thread to make sure that the ctx_owner field does not
+ * point to an unexisting task.
+ */
+void
+pfm_cleanup_owners(struct task_struct *task)
+{
+	struct task_struct *p;
+	pfm_context_t *ctx;
+
+	DBprintk(("called by [%d] for [%d]\n", current->pid, task->pid));
+
+	read_lock(&tasklist_lock);
+
+	for_each_task(p) {
+		/*
+		 * It is safe to do the 2-step test here, because thread.ctx
+		 * is cleaned up only in release_thread() and at that point
+		 * the task has been detached from the tasklist which is an
+		 * operation which uses the write_lock() on the tasklist_lock
+		 * so it cannot run concurrently to this loop. So we have the
+		 * guarantee that if we find p and it has a perfmon ctx then
+		 * it is going to stay like this for the entire execution of this
+		 * loop.
+		 */
+		ctx = p->thread.pfm_context;
+
+		//DBprintk(("[%d] scanning task [%d] ctx=%p\n", task->pid, p->pid, ctx));
+
+		if (ctx && ctx->ctx_owner == task) {
+			DBprintk(("trying for owner [%d] in [%d]\n", task->pid, p->pid));
+			/*
+			 * the spinlock is required to take care of a race condition
+			 * with the send_sig_info() call. We must make sure that 
+			 * either the send_sig_info() completes using a valid task,
+			 * or the notify_task is cleared before the send_sig_info()
+			 * can pick up a stale value. Note that by the time this
+			 * function is executed the 'task' is already detached from the
+			 * tasklist. The problem is that the notifiers have a direct
+			 * pointer to it. It is okay to send a signal to a task in this
+			 * stage, it simply will have no effect. But it is better than sending
+			 * to a completely destroyed task or worse to a new task using the same
+			 * task_struct address.
+			 */
+			LOCK_CTX(ctx);
+
+			ctx->ctx_owner = NULL;
+
+			UNLOCK_CTX(ctx);
+
+			DBprintk(("done for notifier [%d] in [%d]\n", task->pid, p->pid));
+		}
+	}
+	read_unlock(&tasklist_lock);
 }
 
+
+/*
+ * function called from release_thread to make sure that the ctx_notify_task is not pointing
+ * to an unexisting task
+ */
 void
 pfm_cleanup_notifiers(struct task_struct *task)
 {
 	struct task_struct *p;
 	pfm_context_t *ctx;
 
-	DBprintk((" [%d] called\n", task->pid));
+	DBprintk(("called by [%d] for [%d]\n", current->pid, task->pid));
 
 	read_lock(&tasklist_lock);
 
@@ -2391,10 +3825,10 @@
 		 */
 		ctx = p->thread.pfm_context;
 
-		DBprintk((" [%d] scanning task [%d] ctx=%p\n", task->pid, p->pid, ctx));
+		//DBprintk(("[%d] scanning task [%d] ctx=%p\n", task->pid, p->pid, ctx));
 
 		if (ctx && ctx->ctx_notify_task == task) {
-			DBprintk((" trying for notifier %d in %d\n", task->pid, p->pid));
+			DBprintk(("trying for notifier [%d] in [%d]\n", task->pid, p->pid));
 			/*
 			 * the spinlock is required to take care of a race condition
 			 * with the send_sig_info() call. We must make sure that 
@@ -2408,23 +3842,146 @@
 			 * to a completely destroyed task or worse to a new task using the same
 			 * task_struct address.
 			 */
-			spin_lock(&ctx->ctx_notify_lock);
+			LOCK_CTX(ctx);
 
 			ctx->ctx_notify_task = NULL;
 
-			spin_unlock(&ctx->ctx_notify_lock);
+			UNLOCK_CTX(ctx);
 
-			DBprintk((" done for notifier %d in %d\n", task->pid, p->pid));
+			DBprintk(("done for notifier [%d] in [%d]\n", task->pid, p->pid));
 		}
 	}
 	read_unlock(&tasklist_lock);
+}
+
+static struct irqaction perfmon_irqaction = {
+	handler:	perfmon_interrupt,
+	flags:		SA_INTERRUPT,
+	name:		"perfmon"
+};
+
 
+static void
+pfm_pmu_snapshot(void)
+{
+	int i;
+
+	for (i=0; i < IA64_NUM_PMC_REGS; i++) {
+		if (i >= pmu_conf.num_pmcs) break;
+		if (PMC_IS_IMPL(i)) reset_pmcs[i] = ia64_get_pmc(i);
+	}
+}
+
+/*
+ * perfmon initialization routine, called from the initcall() table
+ */
+int __init
+perfmon_init (void)
+{
+	pal_perf_mon_info_u_t pm_info;
+	s64 status;
+
+	register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
+
+	ia64_set_pmv(IA64_PERFMON_VECTOR);
+	ia64_srlz_d();
+
+	pmu_conf.pfm_is_disabled = 1;
+
+	printk("perfmon: version %u.%u (sampling format v%u.%u) IRQ %u\n", 
+		PFM_VERSION_MAJ, 
+		PFM_VERSION_MIN, 
+		PFM_SMPL_VERSION_MAJ, 
+		PFM_SMPL_VERSION_MIN, 
+		IA64_PERFMON_VECTOR);
+
+	if ((status=ia64_pal_perf_mon_info(pmu_conf.impl_regs, &pm_info)) != 0) {
+		printk("perfmon: PAL call failed (%ld), perfmon disabled\n", status);
+		return -1;
+	}
+
+	pmu_conf.perf_ovfl_val = (1UL << pm_info.pal_perf_mon_info_s.width) - 1;
+	pmu_conf.max_counters  = pm_info.pal_perf_mon_info_s.generic;
+	pmu_conf.num_pmcs      = find_num_pm_regs(pmu_conf.impl_regs);
+	pmu_conf.num_pmds      = find_num_pm_regs(&pmu_conf.impl_regs[4]);
+
+	printk("perfmon: %u bits counters\n", pm_info.pal_perf_mon_info_s.width);
+
+	printk("perfmon: %lu PMC/PMD pairs, %lu PMCs, %lu PMDs\n", 
+	       pmu_conf.max_counters, pmu_conf.num_pmcs, pmu_conf.num_pmds);
+
+	/* sanity check */
+	if (pmu_conf.num_pmds >= IA64_NUM_PMD_REGS || pmu_conf.num_pmcs >= IA64_NUM_PMC_REGS) {
+		printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon is DISABLED\n");
+		return -1; /* no need to continue anyway */
+	}
+
+	if (ia64_pal_debug_info(&pmu_conf.num_ibrs, &pmu_conf.num_dbrs)) {
+		printk(KERN_WARNING "perfmon: unable to get number of debug registers\n");
+		pmu_conf.num_ibrs = pmu_conf.num_dbrs = 0;
+	}
+	/* PAL reports the number of pairs */
+	pmu_conf.num_ibrs <<=1;
+	pmu_conf.num_dbrs <<=1;
+
+	/*
+	 * take a snapshot of all PMU registers. PAL is supposed
+	 * to configure them with stable/safe values, i.e., not
+	 * capturing anything.
+	 * We take a snapshot now, before we make any modifications. This
+	 * will become our master copy. Then we will reuse the snapshot
+	 * to reset the PMU in pfm_enable(). Using this technique, perfmon
+	 * does NOT have to know about the specific values to program for
+	 * the PMC/PMD. The safe values may be different from one CPU model to
+	 * the other.
+	 */
+	pfm_pmu_snapshot();
+
+	/* 
+	 * list the pmc registers used to control monitors 
+	 * XXX: unfortunately this information is not provided by PAL
+	 *
+	 * We start with the architected minimum and then refine for each CPU model
+	 */
+	pmu_conf.monitor_pmcs[0] = PMM(4)|PMM(5)|PMM(6)|PMM(7);
+
+	/*
+	 * architected counters
+	 */
+	pmu_conf.counter_pmds[0] |= PMM(4)|PMM(5)|PMM(6)|PMM(7);
+
+#ifdef CONFIG_ITANIUM
+	pmu_conf.monitor_pmcs[0] |= PMM(10)|PMM(11)|PMM(12);
+	/* Itanium does not add more counters */
+#endif
+	/* we are all set */
+	pmu_conf.pfm_is_disabled = 0;
+
+	/*
+	 * for now here for debug purposes
+	 */
+	perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL);
+
+	spin_lock_init(&pfm_sessions.pfs_lock);
+
+	return 0;
+}
+
+__initcall(perfmon_init);
+
+void
+perfmon_init_percpu (void)
+{
+	ia64_set_pmv(IA64_PERFMON_VECTOR);
+	ia64_srlz_d();
 }
 
+
 #else /* !CONFIG_PERFMON */
 
 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 (int pid, int cmd, void *req, int count, long arg5, long arg6, 
+		long arg7, long arg8, long stack)
 {
 	return -ENOSYS;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/process.c linux/arch/ia64/kernel/process.c
--- linux.orig/arch/ia64/kernel/process.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/process.c	2002-07-20 01:08:36.000000000 +0000
@@ -1,8 +1,8 @@
 /*
  * Architecture-specific setup.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #define __KERNEL_SYSCALLS__	/* see <asm/unistd.h> */
 #include <linux/config.h>
@@ -12,6 +12,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/personality.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
@@ -28,6 +29,10 @@
 #include <asm/unwind.h>
 #include <asm/user.h>
 
+#ifdef CONFIG_IA64_SGI_SN
+#include <asm/sn/idle.h>
+#endif
+
 static void
 do_show_stack (struct unw_frame_info *info, void *arg)
 {
@@ -46,6 +51,15 @@
 }
 
 void
+show_trace_task (struct task_struct *task)
+{
+	struct unw_frame_info info;
+
+	unw_init_from_blocked_task(&info, task);
+	do_show_stack(&info, 0);
+}
+
+void
 show_stack (struct task_struct *task)
 {
 	if (!task)
@@ -90,8 +104,8 @@
 	printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, regs->r27, regs->r28);
 	printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, regs->r30, regs->r31);
 
-	/* print the stacked registers if cr.ifs is valid: */
-	if (regs->cr_ifs & 0x8000000000000000) {
+	if (user_mode(regs)) {
+		/* print the stacked registers */
 		unsigned long val, sof, *bsp, ndirty;
 		int i, is_nat = 0;
 
@@ -122,8 +136,18 @@
 		if (!current->need_resched)
 			min_xtp();
 #endif
-		while (!current->need_resched)
+
+		while (!current->need_resched) {
+#ifdef CONFIG_IA64_SGI_SN
+			snidle();
+#endif
 			continue;
+		}
+
+#ifdef CONFIG_IA64_SGI_SN
+		snidleoff();
+#endif
+
 #ifdef CONFIG_SMP
 		normal_xtp();
 #endif
@@ -139,10 +163,17 @@
 {
 	if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
 		ia64_save_debug_regs(&task->thread.dbr[0]);
+
 #ifdef CONFIG_PERFMON
 	if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
 		pfm_save_regs(task);
+
+# ifdef CONFIG_SMP
+	if (local_cpu_data->pfm_syst_wide)
+		pfm_syst_wide_update_task(task, 0);
+# endif
 #endif
+
 	if (IS_IA32_PROCESS(ia64_task_regs(task)))
 		ia32_save_state(task);
 }
@@ -152,10 +183,17 @@
 {
 	if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
 		ia64_load_debug_regs(&task->thread.dbr[0]);
+
 #ifdef CONFIG_PERFMON
 	if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
 		pfm_load_regs(task);
+
+# ifdef CONFIG_SMP
+	if (local_cpu_data->pfm_syst_wide)
+		pfm_syst_wide_update_task(task, 1);
+# endif
 #endif
+
 	if (IS_IA32_PROCESS(ia64_task_regs(task)))
 		ia32_load_state(task);
 }
@@ -235,7 +273,7 @@
 
 	if (user_mode(child_ptregs)) {
 		if (user_stack_base) {
-			child_ptregs->r12 = user_stack_base + user_stack_size;
+			child_ptregs->r12 = user_stack_base + user_stack_size - 16;
 			child_ptregs->ar_bspstore = user_stack_base;
 			child_ptregs->ar_rnat = 0;
 			child_ptregs->loadrs = 0;
@@ -288,9 +326,15 @@
 	if (IS_IA32_PROCESS(ia64_task_regs(current)))
 		ia32_save_state(p);
 #endif
+
 #ifdef CONFIG_PERFMON
-	if (p->thread.pfm_context)
-		retval = pfm_inherit(p, child_ptregs);
+	/*
+	 * reset notifiers and owner check (may not have a perfmon context)
+	 */
+	atomic_set(&p->thread.pfm_notifiers_check, 0);
+	atomic_set(&p->thread.pfm_owners_check, 0);
+
+	if (current->thread.pfm_context) retval = pfm_inherit(p, child_ptregs);
 #endif
 	return retval;
 }
@@ -414,6 +458,16 @@
 	return error;
 }
 
+void
+ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter)
+{
+	set_personality(PER_LINUX);
+	if (elf_ex->e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK)
+		current->thread.flags |= IA64_THREAD_XSTACK;
+	else
+		current->thread.flags &= ~IA64_THREAD_XSTACK;
+}
+
 pid_t
 kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
 {
@@ -445,15 +499,15 @@
 
 #ifdef CONFIG_PERFMON
 /*
- * By the time we get here, the task is detached from the tasklist. This is important
- * because it means that no other tasks can ever find it as a notifiied task, therfore
- * there is no race condition between this code and let's say a pfm_context_create().
- * Conversely, the pfm_cleanup_notifiers() cannot try to access a task's pfm context if
- * this other task is in the middle of its own pfm_context_exit() because it would alreayd
- * be out of the task list. Note that this case is very unlikely between a direct child
- * and its parents (if it is the notified process) because of the way the exit is notified
- * via SIGCHLD.
+ * by the time we get here, the task is detached from the tasklist. This is important
+ * because it means that no other tasks can ever find it as a notified task, therfore there
+ * is no race condition between this code and let's say a pfm_context_create().
+ * Conversely, the pfm_cleanup_notifiers() cannot try to access a task's pfm context if this
+ * other task is in the middle of its own pfm_context_exit() because it would already be out of
+ * the task list. Note that this case is very unlikely between a direct child and its parents
+ * (if it is the notified process) because of the way the exit is notified via SIGCHLD.
  */
+
 void
 release_thread (struct task_struct *task)
 {
@@ -462,6 +516,12 @@
 
 	if (atomic_read(&task->thread.pfm_notifiers_check) > 0)
 		pfm_cleanup_notifiers(task);
+
+	if (atomic_read(&task->thread.pfm_owners_check) > 0)
+		pfm_cleanup_owners(task);
+
+	if (task->thread.pfm_smpl_buf_list)
+		pfm_cleanup_smpl_buf(task);
 }
 #endif
 
@@ -477,21 +537,13 @@
 		ia64_set_fpu_owner(0);
 #endif
 #ifdef CONFIG_PERFMON
-       /* stop monitoring */
-	if ((current->thread.flags & IA64_THREAD_PM_VALID) != 0) {
-		/*
-		 * we cannot rely on switch_to() to save the PMU
-		 * context for the last time. There is a possible race
-		 * condition in SMP mode between the child and the
-		 * parent.  by explicitly saving the PMU context here
-		 * we garantee no race.  this call we also stop
-		 * monitoring
-		 */
+       /* if needed, stop monitoring and flush state to perfmon context */
+	if (current->thread.pfm_context) 
 		pfm_flush_regs(current);
-		/*
-		 * make sure that switch_to() will not save context again
-		 */
-		current->thread.flags &= ~IA64_THREAD_PM_VALID;
+
+	/* free debug register resources */
+	if ((current->thread.flags & IA64_THREAD_DBG_VALID) != 0) {
+		pfm_release_debug_registers(current);
 	}
 #endif
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/ptrace.c linux/arch/ia64/kernel/ptrace.c
--- linux.orig/arch/ia64/kernel/ptrace.c	2001-11-21 19:04:18.000000000 +0000
+++ linux/arch/ia64/kernel/ptrace.c	2002-07-20 01:08:35.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Kernel support for the ptrace() and syscall tracing interfaces.
  *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Derived from the x86 and Alpha versions.  Most of the code in here
@@ -23,6 +23,9 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/unwind.h>
+#ifdef CONFIG_PERFMON
+# include <asm/perfmon.h>
+#endif
 
 /*
  * Bits in the PSR that we allow ptrace() to change:
@@ -755,11 +758,6 @@
 	} else {
 		/* access debug registers */
 
-		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
-			child->thread.flags |= IA64_THREAD_DBG_VALID;
-			memset(child->thread.dbr, 0, sizeof(child->thread.dbr));
-			memset(child->thread.ibr, 0, sizeof(child->thread.ibr));
-		}
 		if (addr >= PT_IBR) {
 			regnum = (addr - PT_IBR) >> 3;
 			ptr = &child->thread.ibr[0];
@@ -772,6 +770,30 @@
 			dprintk("ptrace: rejecting access to register address 0x%lx\n", addr);
 			return -1;
 		}
+#ifdef CONFIG_PERFMON
+		/*
+		 * Check if debug registers are used by perfmon. This test must be done
+		 * once we know that we can do the operation, i.e. the arguments are all
+		 * valid, but before we start modifying the state.
+		 *
+		 * Perfmon needs to keep a count of how many processes are trying to
+		 * modify the debug registers for system wide monitoring sessions.
+		 *
+		 * We also include read access here, because they may cause the
+		 * PMU-installed debug register state (dbr[], ibr[]) to be reset. The two
+		 * arrays are also used by perfmon, but we do not use
+		 * IA64_THREAD_DBG_VALID. The registers are restored by the PMU context
+		 * switch code.
+		 */
+		if (pfm_use_debug_registers(child))
+			return -1;
+#endif
+
+		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
+			child->thread.flags |= IA64_THREAD_DBG_VALID;
+			memset(child->thread.dbr, 0, sizeof(child->thread.dbr));
+			memset(child->thread.ibr, 0, sizeof(child->thread.ibr));
+		}
 
 		ptr += regnum;
 
@@ -789,6 +811,260 @@
 	return 0;
 }
 
+static long
+ptrace_getregs (struct task_struct *child, struct pt_all_user_regs *ppr)
+{
+	struct switch_stack *sw;
+	struct pt_regs *pt;
+	long ret, retval;
+	struct unw_frame_info info;
+	char nat = 0;
+	int i;
+
+	retval = verify_area(VERIFY_WRITE, ppr, sizeof(struct pt_all_user_regs));
+	if (retval != 0) {
+		return -EIO;
+	}
+
+	pt = ia64_task_regs(child);
+	sw = (struct switch_stack *) (child->thread.ksp + 16);
+	unw_init_from_blocked_task(&info, child);
+	if (unw_unwind_to_user(&info) < 0) {
+		return -EIO;
+	}
+
+	if (((unsigned long) ppr & 0x7) != 0) {
+		dprintk("ptrace:unaligned register address %p\n", ppr);
+		return -EIO;
+	}
+
+	retval = 0;
+
+	/* control regs */
+
+	retval |= __put_user(pt->cr_iip, &ppr->cr_iip);
+	retval |= access_uarea(child, PT_CR_IPSR, &ppr->cr_ipsr, 0);
+
+	/* app regs */
+
+	retval |= __put_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
+	retval |= __put_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]);
+	retval |= __put_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
+	retval |= __put_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
+	retval |= __put_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
+	retval |= __put_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);
+
+	retval |= access_uarea(child, PT_AR_EC, &ppr->ar[PT_AUR_EC], 0);
+	retval |= access_uarea(child, PT_AR_LC, &ppr->ar[PT_AUR_LC], 0);
+	retval |= access_uarea(child, PT_AR_RNAT, &ppr->ar[PT_AUR_RNAT], 0);
+	retval |= access_uarea(child, PT_AR_BSP, &ppr->ar[PT_AUR_BSP], 0);
+	retval |= access_uarea(child, PT_CFM, &ppr->cfm, 0);
+
+	/* gr1-gr3 */
+
+	retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long) * 3);
+
+	/* gr4-gr7 */
+
+	for (i = 4; i < 8; i++) {
+		retval |= unw_access_gr(&info, i, &ppr->gr[i], &nat, 0);
+	}
+
+	/* gr8-gr11 */
+
+	retval |= __copy_to_user(&ppr->gr[8], &pt->r8, sizeof(long) * 4);
+
+	/* gr12-gr15 */
+
+	retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 4);
+
+	/* gr16-gr31 */
+
+	retval |= __copy_to_user(&ppr->gr[16], &pt->r16, sizeof(long) * 16);
+
+	/* b0 */
+
+	retval |= __put_user(pt->b0, &ppr->br[0]);
+
+	/* b1-b5 */
+
+	for (i = 1; i < 6; i++) {
+		retval |= unw_access_br(&info, i, &ppr->br[i], 0);
+	}
+
+	/* b6-b7 */
+
+	retval |= __put_user(pt->b6, &ppr->br[6]);
+	retval |= __put_user(pt->b7, &ppr->br[7]);
+
+	/* fr2-fr5 */
+
+	for (i = 2; i < 6; i++) {
+		retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 0);
+		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0);
+	}
+
+	/* fr6-fr9 */
+
+	retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 4);
+
+	/* fp scratch regs(10-15) */
+
+	retval |= __copy_to_user(&ppr->fr[10], &sw->f10, sizeof(struct ia64_fpreg) * 6);
+
+	/* fr16-fr31 */
+
+	for (i = 16; i < 32; i++) {
+		retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 0);
+		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0);
+	}
+
+	/* fph */
+
+	ia64_flush_fph(child);
+	retval |= __copy_to_user(&ppr->fr[32], &child->thread.fph, sizeof(ppr->fr[32]) * 96);
+
+	/* preds */
+
+	retval |= __put_user(pt->pr, &ppr->pr);
+
+	/* nat bits */
+
+	retval |= access_uarea(child, PT_NAT_BITS, &ppr->nat, 0);
+
+	ret = retval ? -EIO : 0;
+	return ret;
+}
+
+static long
+ptrace_setregs (struct task_struct *child, struct pt_all_user_regs *ppr)
+{
+	struct switch_stack *sw;
+	struct pt_regs *pt;
+	long ret, retval;
+	struct unw_frame_info info;
+	char nat = 0;
+	int i;
+
+	retval = verify_area(VERIFY_READ, ppr, sizeof(struct pt_all_user_regs));
+	if (retval != 0) {
+		return -EIO;
+	}
+
+	pt = ia64_task_regs(child);
+	sw = (struct switch_stack *) (child->thread.ksp + 16);
+	unw_init_from_blocked_task(&info, child);
+	if (unw_unwind_to_user(&info) < 0) {
+		return -EIO;
+	}
+
+	if (((unsigned long) ppr & 0x7) != 0) {
+		dprintk("ptrace:unaligned register address %p\n", ppr);
+		return -EIO;
+	}
+
+	retval = 0;
+
+	/* control regs */
+
+	retval |= __get_user(pt->cr_iip, &ppr->cr_iip);
+	retval |= access_uarea(child, PT_CR_IPSR, &ppr->cr_ipsr, 1);
+
+	/* app regs */
+
+	retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
+	retval |= __get_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]);
+	retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
+	retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
+	retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
+	retval |= __get_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);
+
+	retval |= access_uarea(child, PT_AR_EC, &ppr->ar[PT_AUR_EC], 1);
+	retval |= access_uarea(child, PT_AR_LC, &ppr->ar[PT_AUR_LC], 1);
+	retval |= access_uarea(child, PT_AR_RNAT, &ppr->ar[PT_AUR_RNAT], 1);
+	retval |= access_uarea(child, PT_AR_BSP, &ppr->ar[PT_AUR_BSP], 1);
+	retval |= access_uarea(child, PT_CFM, &ppr->cfm, 1);
+
+	/* gr1-gr3 */
+
+	retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long) * 3);
+
+	/* gr4-gr7 */
+
+	for (i = 4; i < 8; i++) {
+		long ret = unw_get_gr(&info, i, &ppr->gr[i], &nat);
+		if (ret < 0) {
+			return ret;
+		}
+		retval |= unw_access_gr(&info, i, &ppr->gr[i], &nat, 1);
+	}
+
+	/* gr8-gr11 */
+
+	retval |= __copy_from_user(&pt->r8, &ppr->gr[8], sizeof(long) * 4);
+
+	/* gr12-gr15 */
+
+	retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 4);
+
+	/* gr16-gr31 */
+
+	retval |= __copy_from_user(&pt->r16, &ppr->gr[16], sizeof(long) * 16);
+
+	/* b0 */
+
+	retval |= __get_user(pt->b0, &ppr->br[0]);
+
+	/* b1-b5 */
+
+	for (i = 1; i < 6; i++) {
+		retval |= unw_access_br(&info, i, &ppr->br[i], 1);
+	}
+
+	/* b6-b7 */
+
+	retval |= __get_user(pt->b6, &ppr->br[6]);
+	retval |= __get_user(pt->b7, &ppr->br[7]);
+
+	/* fr2-fr5 */
+
+	for (i = 2; i < 6; i++) {
+		retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 1);
+		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1);
+	}
+
+	/* fr6-fr9 */
+
+	retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 4);
+
+	/* fp scratch regs(10-15) */
+
+	retval |= __copy_from_user(&sw->f10, &ppr->fr[10], sizeof(ppr->fr[10]) * 6);
+
+	/* fr16-fr31 */
+
+	for (i = 16; i < 32; i++) {
+		retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 1);
+		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1);
+	}
+
+	/* fph */
+
+	ia64_sync_fph(child);
+	retval |= __copy_from_user(&child->thread.fph, &ppr->fr[32], sizeof(ppr->fr[32]) * 96);
+
+	/* preds */
+
+	retval |= __get_user(pt->pr, &ppr->pr);
+
+	/* nat bits */
+
+	retval |= access_uarea(child, PT_NAT_BITS, &ppr->nat, 1);
+
+	ret = retval ? -EIO : 0;
+	return ret;
+}
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -979,6 +1255,14 @@
 		ret = ptrace_detach(child, data);
 		goto out_tsk;
 
+	      case PTRACE_GETREGS:
+		ret = ptrace_getregs(child, (struct pt_all_user_regs*) data);
+		goto out_tsk;
+
+	      case PTRACE_SETREGS:
+		ret = ptrace_setregs(child, (struct pt_all_user_regs*) data);
+		goto out_tsk;
+
 	      default:
 		ret = -EIO;
 		goto out_tsk;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/sal.c linux/arch/ia64/kernel/sal.c
--- linux.orig/arch/ia64/kernel/sal.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/sal.c	2002-07-20 01:08:40.000000000 +0000
@@ -18,7 +18,8 @@
 #include <asm/sal.h>
 #include <asm/pal.h>
 
-spinlock_t sal_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t sal_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+unsigned long sal_platform_features;
 
 static struct {
 	void *addr;	/* function entry point */
@@ -76,7 +77,7 @@
 	return str;
 }
 
-static void __init 
+static void __init
 ia64_sal_handler_init (void *entry_point, void *gpval)
 {
 	/* fill in the SAL procedure descriptor and point ia64_sal to it: */
@@ -102,7 +103,7 @@
 	if (strncmp(systab->signature, "SST_", 4) != 0)
 		printk("bad signature in system table!");
 
-	/* 
+	/*
 	 * revisions are coded in BCD, so %x does the job for us
 	 */
 	printk("SAL v%x.%02x: oem=%.32s, product=%.32s\n",
@@ -152,12 +153,12 @@
 		      case SAL_DESC_PLATFORM_FEATURE:
 		      {
 			      struct ia64_sal_desc_platform_feature *pf = (void *) p;
+			      sal_platform_features = pf->feature_mask;
 			      printk("SAL: Platform features ");
 
-			      if (pf->feature_mask & (1 << 0))
+			      if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK)
 				      printk("BusLock ");
-
-			      if (pf->feature_mask & (1 << 1)) {
+			      if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT) {
 				      printk("IRQ_Redirection ");
 #ifdef CONFIG_SMP
 				      if (no_int_routing)
@@ -166,15 +167,17 @@
 					      smp_int_redirect |= SMP_IRQ_REDIRECTION;
 #endif
 			      }
-			      if (pf->feature_mask & (1 << 2)) {
+			      if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT) {
 				      printk("IPI_Redirection ");
 #ifdef CONFIG_SMP
-				      if (no_int_routing) 
+				      if (no_int_routing)
 					      smp_int_redirect &= ~SMP_IPI_REDIRECTION;
 				      else
 					      smp_int_redirect |= SMP_IPI_REDIRECTION;
 #endif
 			      }
+			      if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)
+				      printk("ITC_Drift ");
 			      printk("\n");
 			      break;
  		      }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/setup.c linux/arch/ia64/kernel/setup.c
--- linux.orig/arch/ia64/kernel/setup.c	2001-11-13 17:01:16.000000000 +0000
+++ linux/arch/ia64/kernel/setup.c	2002-07-20 01:08:26.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1998-2001 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1998, 1999, 2001 Stephane Eranian <eranian@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
@@ -147,6 +147,10 @@
 }
 
 
+/*
+ * Find a place to put the bootmap and return its starting address in bootmap_start.
+ * This address must be page-aligned.
+ */
 static int
 find_bootmap_location (unsigned long start, unsigned long end, void *arg)
 {
@@ -165,7 +169,7 @@
 
 	for (i = 0; i < num_rsvd_regions; i++) {
 		range_start = MAX(start, free_start);
-		range_end   = MIN(end, rsvd_region[i].start);
+		range_end   = MIN(end, rsvd_region[i].start & PAGE_MASK);
 
 		if (range_end <= range_start) continue;	/* skip over empty range */
 
@@ -177,7 +181,7 @@
 		/* nothing more available in this segment */
 		if (range_end == end) return 0;
 
-		free_start = rsvd_region[i].end;
+		free_start = PAGE_ALIGN(rsvd_region[i].end);
 	}
 	return 0;
 }
@@ -306,6 +310,10 @@
 	/* process SAL system table: */
 	ia64_sal_init(efi.sal_systab);
 
+#ifdef CONFIG_IA64_GENERIC
+	machvec_init(acpi_get_sysname());
+#endif
+
 	/*
 	 *  Set `iobase' to the appropriate address in region 6
 	 *    (uncached access range)
@@ -332,10 +340,6 @@
 
 	cpu_init();	/* initialize the bootstrap CPU */
 
-#ifdef CONFIG_IA64_GENERIC
-	machvec_init(acpi_get_sysname());
-#endif
-
 	if (efi.acpi20) {
 		/* Parse the ACPI 2.0 tables */
 		acpi20_parse(efi.acpi20);
@@ -343,6 +347,10 @@
 		/* Parse the ACPI tables */
 		acpi_parse(efi.acpi);
 	}
+	if (efi.hcdp) {
+		/* Setup the serial ports described by HCDP */
+		setup_serial_hcdp(efi.hcdp);
+	}
 
 #ifdef CONFIG_VT
 # if defined(CONFIG_VGA_CONSOLE)
@@ -371,17 +379,14 @@
 {
 #ifdef CONFIG_SMP
 #	define lpj	c->loops_per_jiffy
+#	define cpu	c->processor
 #else
 #	define lpj	loops_per_jiffy
+#	define cpu	0
 #endif
 	char family[32], features[128], *cp;
 	struct cpuinfo_ia64 *c = v;
-	unsigned long mask, cpu = c - cpu_data(0);
-
-#ifdef CONFIG_SMP
-	if (!(cpu_online_map & (1 << cpu)))
-		return 0;
-#endif
+	unsigned long mask;
 
 	mask = c->features;
 
@@ -403,7 +408,7 @@
 		sprintf(cp, " 0x%lx", mask);
 
 	seq_printf(m,
-		   "processor  : %lu\n"
+		   "processor  : %d\n"
 		   "vendor     : %s\n"
 		   "arch       : IA-64\n"
 		   "family     : %s\n"
@@ -427,6 +432,10 @@
 static void *
 c_start (struct seq_file *m, loff_t *pos)
 {
+#ifdef CONFIG_SMP
+	while (*pos < NR_CPUS && !(cpu_online_map & (1 << *pos)))
+		++*pos;
+#endif
 	return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
 }
 
@@ -483,6 +492,9 @@
 		cpuid.bits[i] = ia64_get_cpuid(i);
 
 	memcpy(c->vendor, cpuid.field.vendor, 16);
+#ifdef CONFIG_SMP
+	c->processor = smp_processor_id();
+#endif
 	c->ppn = cpuid.field.ppn;
 	c->number = cpuid.field.number;
 	c->revision = cpuid.field.revision;
@@ -534,7 +546,7 @@
 				= alloc_bootmem_pages_node(NODE_DATA(numa_node_id()),
 							   sizeof(struct cpuinfo_ia64));
 		for (cpu = 1; cpu < NR_CPUS; ++cpu)
-			memcpy(my_cpu_data->cpu_data[cpu]->cpu_data_ptrs,
+			memcpy(my_cpu_data->cpu_data[cpu]->cpu_data,
 			       my_cpu_data->cpu_data, sizeof(my_cpu_data->cpu_data));
 	} else {
 		order = get_order(sizeof(struct cpuinfo_ia64));
@@ -616,4 +628,6 @@
 		num_phys_stacked = 96;
 	}
 	local_cpu_data->phys_stacked_size_p8 = num_phys_stacked*8 + 8;
+
+	platform_cpu_init();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/signal.c linux/arch/ia64/kernel/signal.c
--- linux.orig/arch/ia64/kernel/signal.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/signal.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific signal handling support.
  *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Derived from i386 and Alpha versions.
@@ -160,6 +160,7 @@
 		err |= __put_user((short)from->si_code, &to->si_code);
 		switch (from->si_code >> 16) {
 		      case __SI_FAULT >> 16:
+			err |= __put_user(from->si_flags, &to->si_flags);
 			err |= __put_user(from->si_isr, &to->si_isr);
 		      case __SI_POLL >> 16:
 			err |= __put_user(from->si_addr, &to->si_addr);
@@ -172,7 +173,12 @@
 		      case __SI_PROF >> 16:
 			err |= __put_user(from->si_uid, &to->si_uid);
 			err |= __put_user(from->si_pid, &to->si_pid);
-			err |= __put_user(from->si_pfm_ovfl, &to->si_pfm_ovfl);
+			if (from->si_code == PROF_OVFL) {
+				err |= __put_user(from->si_pfm_ovfl[0], &to->si_pfm_ovfl[0]);
+				err |= __put_user(from->si_pfm_ovfl[1], &to->si_pfm_ovfl[1]);
+				err |= __put_user(from->si_pfm_ovfl[2], &to->si_pfm_ovfl[2]);
+				err |= __put_user(from->si_pfm_ovfl[3], &to->si_pfm_ovfl[3]);
+			}
 			break;
 		      default:
 			err |= __put_user(from->si_uid, &to->si_uid);
@@ -578,10 +584,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/ia64/kernel/smpboot.c linux/arch/ia64/kernel/smpboot.c
--- linux.orig/arch/ia64/kernel/smpboot.c	2001-11-21 18:31:09.000000000 +0000
+++ linux/arch/ia64/kernel/smpboot.c	2002-07-20 01:08:29.000000000 +0000
@@ -416,9 +416,9 @@
 	if (!idle)
 		panic("No idle process for CPU %d", cpu);
 
-	idle->processor = cpu;
+	task_set_cpu(idle, cpu);	/* we schedule the first task manually */
+
 	ia64_cpu_to_sapicid[cpu] = sapicid;
-	idle->cpus_runnable = 1 << cpu; /* we schedule the first task manually */
 
 	del_from_runqueue(idle);
 	unhash_process(idle);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/traps.c linux/arch/ia64/kernel/traps.c
--- linux.orig/arch/ia64/kernel/traps.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/traps.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific trap handling.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 05/12/00 grao <goutham.rao@intel.com> : added isr in siginfo for SIGFPE
@@ -133,6 +133,8 @@
 	/* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
 	siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
 	siginfo.si_imm = break_num;
+	siginfo.si_flags = 0;		/* clear __ISR_VALID */
+	siginfo.si_isr = 0;
 
 	switch (break_num) {
 	      case 0: /* unknown error */
@@ -352,6 +354,8 @@
 				siginfo.si_code = FPE_FLTDIV;
 			}
 			siginfo.si_isr = isr;
+			siginfo.si_flags = __ISR_VALID;
+			siginfo.si_imm = 0;
 			force_sig_info(SIGFPE, &siginfo, current);
 		}
 	} else {
@@ -372,6 +376,8 @@
 				siginfo.si_code = FPE_FLTRES;
 			}
 			siginfo.si_isr = isr;
+			siginfo.si_flags = __ISR_VALID;
+			siginfo.si_imm = 0;
 			force_sig_info(SIGFPE, &siginfo, current);
 		}
 	}
@@ -490,6 +496,8 @@
 			siginfo.si_errno = 0;
 			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
 			siginfo.si_imm = vector;
+			siginfo.si_flags = __ISR_VALID;
+			siginfo.si_isr = isr;
 			force_sig_info(SIGILL, &siginfo, current);
 			return;
 		}
@@ -517,6 +525,10 @@
 		}
 		siginfo.si_signo = SIGTRAP;
 		siginfo.si_errno = 0;
+		siginfo.si_flags = 0;
+		siginfo.si_isr = 0;
+		siginfo.si_addr = 0;
+		siginfo.si_imm = 0;
 		force_sig_info(SIGTRAP, &siginfo, current);
 		return;
 
@@ -528,6 +540,9 @@
 			siginfo.si_errno = 0;
 			siginfo.si_code = FPE_FLTINV;
 			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+			siginfo.si_flags = __ISR_VALID;
+			siginfo.si_isr = isr;
+			siginfo.si_imm = 0;
 			force_sig_info(SIGFPE, &siginfo, current);
 		}
 		return;
@@ -537,6 +552,9 @@
 			siginfo.si_signo = SIGILL;
 			siginfo.si_code = ILL_BADIADDR;
 			siginfo.si_errno = 0;
+			siginfo.si_flags = 0;
+			siginfo.si_isr = 0;
+			siginfo.si_imm = 0;
 			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
 			force_sig_info(SIGILL, &siginfo, current);
 			return;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/unaligned.c linux/arch/ia64/kernel/unaligned.c
--- linux.orig/arch/ia64/kernel/unaligned.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/unaligned.c	2002-07-20 01:08:39.000000000 +0000
@@ -1,9 +1,9 @@
 /*
  * Architecture-specific unaligned trap handling.
  *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
- * Copyright (C) 1999-2000 Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2002 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 2001/10/11	Fix unaligned access to rotating registers in s/w pipelined loops.
  * 2001/08/13	Correct size of extended floats (float_fsz) from 16 to 10 bytes.
@@ -23,7 +23,7 @@
 #undef DEBUG_UNALIGNED_TRAP
 
 #ifdef DEBUG_UNALIGNED_TRAP
-# define DPRINT(a...)	do { printk("%s.%u: ", __FUNCTION__, __LINE__); printk (a); } while (0)
+# define DPRINT(a...)	do { printk("%s %u: ", __FUNCTION__, __LINE__); printk (a); } while (0)
 # define DDUMP(str,vp,len)	dump(str, vp, len)
 
 static void
@@ -650,7 +650,7 @@
 	 * just in case.
 	 */
 	if (ld.x6_op == 1 || ld.x6_op == 3) {
-		printk(KERN_ERR __FUNCTION__": register update on speculative load, error\n");
+		printk("%s %s: register update on speculative load, error\n", KERN_ERR, __FUNCTION__);
 		die_if_kernel("unaligned reference on specualtive load with register update\n",
 			      regs, 30);
 	}
@@ -1080,8 +1080,8 @@
 		 * For this reason we keep this sanity check
 		 */
 		if (ld.x6_op == 1 || ld.x6_op == 3)
-			printk(KERN_ERR __FUNCTION__": register update on speculative load pair, "
-			       "error\n");
+			printk("%s %s: register update on speculative load pair, "
+			       "error\n",KERN_ERR, __FUNCTION__);
 
 		setreg(ld.r3, ifa, 0, regs);
 	}
@@ -1488,6 +1488,9 @@
 	si.si_errno = 0;
 	si.si_code = BUS_ADRALN;
 	si.si_addr = (void *) ifa;
+	si.si_flags = 0;
+	si.si_isr = 0;
+	si.si_imm = 0;
 	force_sig_info(SIGBUS, &si, current);
 	goto done;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/unwind.c linux/arch/ia64/kernel/unwind.c
--- linux.orig/arch/ia64/kernel/unwind.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/kernel/unwind.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 1999-2001 Hewlett-Packard Co
- * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
  * This file implements call frame unwind support for the Linux
@@ -72,6 +72,8 @@
 
 #define alloc_reg_state()	kmalloc(sizeof(struct unw_state_record), GFP_ATOMIC)
 #define free_reg_state(usr)	kfree(usr)
+#define alloc_labeled_state()	kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC)
+#define free_labeled_state(usr)	kfree(usr)
 
 typedef unsigned long unw_word;
 typedef unsigned char unw_hash_index_t;
@@ -521,7 +523,7 @@
 }
 
 
-/* Unwind decoder routines */
+/* Routines to manipulate the state stack.  */
 
 static inline void
 push (struct unw_state_record *sr)
@@ -534,24 +536,60 @@
 		return;
 	}
 	memcpy(rs, &sr->curr, sizeof(*rs));
-	rs->next = sr->stack;
-	sr->stack = rs;
+	sr->curr.next = rs;
 }
 
 static void
 pop (struct unw_state_record *sr)
 {
-	struct unw_reg_state *rs;
+	struct unw_reg_state *rs = sr->curr.next;
 
-	if (!sr->stack) {
-		printk ("unwind: stack underflow!\n");
+	if (!rs) {
+		printk("unwind: stack underflow!\n");
 		return;
 	}
-	rs = sr->stack;
-	sr->stack = rs->next;
+	memcpy(&sr->curr, rs, sizeof(*rs));
 	free_reg_state(rs);
 }
 
+/* Make a copy of the state stack.  Non-recursive to avoid stack overflows.  */
+static struct unw_reg_state *
+dup_state_stack (struct unw_reg_state *rs)
+{
+	struct unw_reg_state *copy, *prev = NULL, *first = NULL;
+
+	while (rs) {
+		copy = alloc_reg_state();
+		if (!copy) {
+			printk ("unwind.dup_state_stack: out of memory\n");
+			return NULL;
+		}
+		memcpy(copy, rs, sizeof(*copy));
+		if (first)
+			prev->next = copy;
+		else
+			first = copy;
+		rs = rs->next;
+		prev = copy;
+	}
+	return first;
+}
+
+/* Free all stacked register states (but not RS itself).  */
+static void
+free_state_stack (struct unw_reg_state *rs)
+{
+	struct unw_reg_state *p, *next;
+
+	for (p = rs->next; p != NULL; p = next) {
+		next = p->next;
+		free_reg_state(p);
+	}
+	rs->next = NULL;
+}
+
+/* Unwind decoder routines */
+
 static enum unw_register_index __attribute__((const))
 decode_abreg (unsigned char abreg, int memory)
 {
@@ -689,7 +727,7 @@
 	sr->first_region = 0;
 
 	/* check if we're done: */
-	if (body && sr->when_target < sr->region_start + sr->region_len) {
+	if (sr->when_target < sr->region_start + sr->region_len) {
 		sr->done = 1;
 		return;
 	}
@@ -902,31 +940,36 @@
 static inline void
 desc_copy_state (unw_word label, struct unw_state_record *sr)
 {
-	struct unw_reg_state *rs;
+	struct unw_labeled_state *ls;
 
-	for (rs = sr->reg_state_list; rs; rs = rs->next) {
-		if (rs->label == label) {
-			memcpy (&sr->curr, rs, sizeof(sr->curr));
+	for (ls = sr->labeled_states; ls; ls = ls->next) {
+		if (ls->label == label) {
+			free_state_stack(&sr->curr);
+			memcpy(&sr->curr, &ls->saved_state, sizeof(sr->curr));
+			sr->curr.next = dup_state_stack(ls->saved_state.next);
 			return;
 		}
 	}
-	printk("unwind: failed to find state labelled 0x%lx\n", label);
+	printk("unwind: failed to find state labeled 0x%lx\n", label);
 }
 
 static inline void
 desc_label_state (unw_word label, struct unw_state_record *sr)
 {
-	struct unw_reg_state *rs;
+	struct unw_labeled_state *ls;
 
-	rs = alloc_reg_state();
-	if (!rs) {
-		printk("unwind: cannot stack!\n");
+	ls = alloc_labeled_state();
+	if (!ls) {
+		printk("unwind.desc_label_state(): out of memory\n");
 		return;
 	}
-	memcpy(rs, &sr->curr, sizeof(*rs));
-	rs->label = label;
-	rs->next = sr->reg_state_list;
-	sr->reg_state_list = rs;
+	ls->label = label;
+	memcpy(&ls->saved_state, &sr->curr, sizeof(ls->saved_state));
+	ls->saved_state.next = dup_state_stack(sr->curr.next);
+
+	/* insert into list of labeled states: */
+	ls->next = sr->labeled_states;
+	sr->labeled_states = ls;
 }
 
 /*
@@ -1378,6 +1421,8 @@
 		else
 			break;
 	}
+	if (rel_ip < e->start_offset || rel_ip >= e->end_offset)
+		return NULL;
 	return e;
 }
 
@@ -1388,9 +1433,9 @@
 static inline struct unw_script *
 build_script (struct unw_frame_info *info)
 {
-	struct unw_reg_state *rs, *next;
 	const struct unw_table_entry *e = 0;
 	struct unw_script *script = 0;
+	struct unw_labeled_state *ls, *next;
 	unsigned long ip = info->ip;
 	struct unw_state_record sr;
 	struct unw_table *table;
@@ -1535,15 +1580,15 @@
 	for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
 		compile_reg(&sr, i, script);
 
-	/* free labelled register states & stack: */
+	/* free labeled register states & stack: */
 
 	STAT(parse_start = ia64_get_itc());
-	for (rs = sr.reg_state_list; rs; rs = next) {
-		next = rs->next;
-		free_reg_state(rs);
+	for (ls = sr.labeled_states; ls; ls = next) {
+		next = ls->next;
+		free_state_stack(&ls->saved_state);
+		free_labeled_state(ls);
 	}
-	while (sr.stack)
-		pop(&sr);
+	free_state_stack(&sr.curr);
 	STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
 
 	script_finalize(script, &sr);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/unwind_i.h linux/arch/ia64/kernel/unwind_i.h
--- linux.orig/arch/ia64/kernel/unwind_i.h	2001-07-31 17:30:08.000000000 +0000
+++ linux/arch/ia64/kernel/unwind_i.h	2002-07-20 01:08:34.000000000 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2000 Hewlett-Packard Co
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2000, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Kernel unwind support.
  */
@@ -85,6 +85,17 @@
 	int when;			/* when the register gets saved */
 };
 
+struct unw_reg_state {
+	struct unw_reg_state *next;		/* next (outer) element on state stack */
+	struct unw_reg_info reg[UNW_NUM_REGS];	/* register save locations */
+};
+
+struct unw_labeled_state {
+	struct unw_labeled_state *next;		/* next labeled state (or NULL) */
+	unsigned long label;			/* label for this state */
+	struct unw_reg_state saved_state;
+};
+
 struct unw_state_record {
 	unsigned int first_region : 1;	/* is this the first region? */
 	unsigned int done : 1;		/* are we done scanning descriptors? */
@@ -105,11 +116,8 @@
 	u8 gr_save_loc;			/* next general register to use for saving a register */
 	u8 return_link_reg;		/* branch register in which the return link is passed */
 
-	struct unw_reg_state {
-		struct unw_reg_state *next;
-		unsigned long label;		/* label of this state record */
-		struct unw_reg_info reg[UNW_NUM_REGS];
-	} curr, *stack, *reg_state_list;
+	struct unw_labeled_state *labeled_states;	/* list of all labeled states */
+	struct unw_reg_state curr;	/* current state */
 };
 
 enum unw_nat_type {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/lib/swiotlb.c linux/arch/ia64/lib/swiotlb.c
--- linux.orig/arch/ia64/lib/swiotlb.c	2001-11-13 17:01:16.000000000 +0000
+++ linux/arch/ia64/lib/swiotlb.c	2002-07-20 01:08:38.000000000 +0000
@@ -27,11 +27,21 @@
 #define ALIGN(val, align) ((unsigned long)	\
 	(((unsigned long) (val) + ((align) - 1)) & ~((align) - 1)))
 
+#define OFFSET(val,align) ((unsigned long)	\
+	                   ( (val) & ( (align) - 1)))
+
 #define SG_ENT_VIRT_ADDRESS(sg)	((sg)->address ? (sg)->address			\
 				 : page_address((sg)->page) + (sg)->offset)
 #define SG_ENT_PHYS_ADDRESS(SG)	virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
 
 /*
+ * Maximum allowable number of contiguous slabs to map,
+ * must be a power of 2.  What is the appropriate value ?
+ * The complexity of {map,unmap}_single is linearly dependent on this value.
+ */
+#define IO_TLB_SEGSIZE	128
+
+/*
  * log of the size of each IO TLB slab.  The number of slabs is command line controllable.
  */
 #define IO_TLB_SHIFT 11
@@ -69,10 +79,15 @@
 setup_io_tlb_npages (char *str)
 {
 	io_tlb_nslabs = simple_strtoul(str, NULL, 0) << (PAGE_SHIFT - IO_TLB_SHIFT);
+
+	/* avoid tail segment of size < IO_TLB_SEGSIZE */
+	io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
+
 	return 1;
 }
 __setup("swiotlb=", setup_io_tlb_npages);
 
+
 /*
  * Statically reserve bounce buffer space and initialize bounce buffer data structures for
  * the software IO TLB used to implement the PCI DMA API.
@@ -92,12 +107,12 @@
 
 	/*
 	 * Allocate and initialize the free list array.  This array is used
-	 * to find contiguous free memory regions of size 2^IO_TLB_SHIFT between
-	 * io_tlb_start and io_tlb_end.
+	 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
+	 * between io_tlb_start and io_tlb_end.
 	 */
 	io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int));
 	for (i = 0; i < io_tlb_nslabs; i++)
-		io_tlb_list[i] = io_tlb_nslabs - i;
+ 		io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
 	io_tlb_index = 0;
 	io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
 
@@ -124,7 +139,7 @@
 	if (size > (1 << PAGE_SHIFT))
 		stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
 	else
-		stride = nslots;
+		stride = 1;
 
 	if (!nslots)
 		BUG();
@@ -151,7 +166,8 @@
 
 				for (i = index; i < index + nslots; i++)
 					io_tlb_list[i] = 0;
-				for (i = index - 1; (i >= 0) && io_tlb_list[i]; i--)
+				for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1)
+				       && io_tlb_list[i]; i--)
 					io_tlb_list[i] = ++count;
 				dma_addr = io_tlb_start + (index << IO_TLB_SHIFT);
 
@@ -217,7 +233,8 @@
 	 */
 	spin_lock_irqsave(&io_tlb_lock, flags);
 	{
-		int count = ((index + nslots) < io_tlb_nslabs ? io_tlb_list[index + nslots] : 0);
+		int count = ((index + nslots) < ALIGN(index + 1, IO_TLB_SEGSIZE) ?
+			     io_tlb_list[index + nslots] : 0);
 		/*
 		 * Step 1: return the slots to the free list, merging the slots with
 		 * superceeding slots
@@ -228,7 +245,8 @@
 		 * Step 2: merge the returned slots with the preceeding slots, if
 		 * available (non zero)
 		 */
-		for (i = index - 1; (i >= 0) && io_tlb_list[i]; i--)
+		for (i = index - 1;  (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) &&
+		       io_tlb_list[i]; i--)
 			io_tlb_list[i] = ++count;
 	}
 	spin_unlock_irqrestore(&io_tlb_lock, flags);
@@ -405,11 +423,13 @@
 	for (i = 0; i < nelems; i++, sg++) {
 		sg->orig_address = SG_ENT_VIRT_ADDRESS(sg);
 		if ((SG_ENT_PHYS_ADDRESS(sg) & ~hwdev->dma_mask) != 0) {
-			addr = map_single(hwdev, sg->address, sg->length, direction);
+			addr = map_single(hwdev, sg->orig_address, sg->length, direction);
 			if (sg->address)
 				sg->address = addr;
-			else
+			else {
 				sg->page = virt_to_page(addr);
+				sg->offset = (u64) addr & ~PAGE_MASK;
+			}
 		}
 	}
 	return nelems;
@@ -432,10 +452,12 @@
 			unmap_single(hwdev, SG_ENT_VIRT_ADDRESS(sg), sg->length, direction);
 			if (sg->address)
 				sg->address = sg->orig_address;
-			else
+			else {
 				sg->page = virt_to_page(sg->orig_address);
+				sg->offset = (u64) sg->orig_address & ~PAGE_MASK;
+			}
 		} else if (direction == PCI_DMA_FROMDEVICE)
-			mark_clean(sg->address, sg->length);
+			mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->length);
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/mm/extable.c linux/arch/ia64/mm/extable.c
--- linux.orig/arch/ia64/mm/extable.c	2001-07-31 17:30:08.000000000 +0000
+++ linux/arch/ia64/mm/extable.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,8 +1,8 @@
 /*
  * Kernel exception handling table support.  Derived from arch/alpha/mm/extable.c.
  *
- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1998, 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998, 1999, 2001-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/config.h>
@@ -55,10 +55,12 @@
 	struct module *mp;
 
 	/* The kernel is the last "module" -- no need to treat it special. */
-	for (mp = module_list; mp ; mp = mp->next) {
+	for (mp = module_list; mp; mp = mp->next) {
 		if (!mp->ex_table_start)
 			continue;
 		archdata = (struct archdata *) mp->archdata_start;
+		if (!archdata)
+			continue;
 		entry = search_one_table(mp->ex_table_start, mp->ex_table_end - 1,
 					 addr, (unsigned long) archdata->gp);
 		if (entry) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/mm/fault.c linux/arch/ia64/mm/fault.c
--- linux.orig/arch/ia64/mm/fault.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/mm/fault.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * MMU fault handling support.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <linux/sched.h>
@@ -96,7 +96,7 @@
 	 * sure we exit gracefully rather than endlessly redo the
 	 * fault.
 	 */
-	switch (handle_mm_fault(mm, vma, address, mask)) {
+	switch (handle_mm_fault(mm, vma, address, (mask & VM_WRITE) != 0)) {
 	      case 1:
 		++current->min_flt;
 		break;
@@ -151,6 +151,8 @@
 		si.si_errno = 0;
 		si.si_code = code;
 		si.si_addr = (void *) address;
+		si.si_isr = isr;
+		si.si_flags = __ISR_VALID;
 		force_sig_info(signal, &si, current);
 		return;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/mm/init.c linux/arch/ia64/mm/init.c
--- linux.orig/arch/ia64/mm/init.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/mm/init.c	2002-07-20 01:08:34.000000000 +0000
@@ -99,7 +99,7 @@
 		free_page(addr);
 		++totalram_pages;
 	}
-	printk ("Freeing unused kernel memory: %ldkB freed\n",
+	printk (KERN_INFO "Freeing unused kernel memory: %ldkB freed\n",
 		(&__init_end - &__init_begin) >> 10);
 }
 
@@ -141,7 +141,7 @@
 	end = end & PAGE_MASK;
 
 	if (start < end)
-		printk ("Freeing initrd memory: %ldkB freed\n", (end - start) >> 10);
+		printk (KERN_INFO "Freeing initrd memory: %ldkB freed\n", (end - start) >> 10);
 
 	for (; start < end; start += PAGE_SIZE) {
 		if (!VALID_PAGE(virt_to_page(start)))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/Makefile linux/arch/ia64/sn/Makefile
--- linux.orig/arch/ia64/sn/Makefile	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-#
-# ia64/sn/Makefile
-#
-# Copyright (C) 1999 Silicon Graphics, Inc.
-# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
-#
-
-EXTRA_CFLAGS	:= -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \
-		   -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \
-		   -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \
-		   -DNEW_INTERRUPTS
-all: sn.a
-
-O_TARGET        = sn.a
-obj-y           = sn1/sn1.a
-
-clean::
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-bigsur-mp linux/arch/ia64/sn/configs/sn1/defconfig-bigsur-mp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-bigsur-mp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-bigsur-mp	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,777 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
+# CONFIG_IA64_MCA is not set
+CONFIG_PM=y
+CONFIG_IA64_HAVE_SYNCRONIZED_ITC=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# 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_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_PIIX_TUNING is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_QLOGIC_1280=y
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+# CONFIG_XFS_SUPPORT is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+CONFIG_KDB=y
+CONFIG_KDB_MODULES=y
+# CONFIG_KDB_OFF is not set
+
+#
+#   Load all symbols for debugging is required for KDB
+#
+CONFIG_KALLSYMS=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-bigsur-sp linux/arch/ia64/sn/configs/sn1/defconfig-bigsur-sp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-bigsur-sp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-bigsur-sp	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,772 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
+# CONFIG_IA64_MCA is not set
+CONFIG_PM=y
+CONFIG_IA64_HAVE_SYNCRONIZED_ITC=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_KCORE_ELF=y
+# CONFIG_SMP is not set
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# 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_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_PIIX_TUNING is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_QLOGIC_1280=y
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+# CONFIG_XFS_SUPPORT is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-dig-mp linux/arch/ia64/sn/configs/sn1/defconfig-dig-mp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-dig-mp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-dig-mp	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,459 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
+# CONFIG_IA64_MCA is not set
+CONFIG_PM=y
+CONFIG_IA64_HAVE_SYNCRONIZED_ITC=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+# CONFIG_IA32_SUPPORT is not set
+# CONFIG_PERFMON is not set
+# CONFIG_IA64_PALINFO is not set
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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
+# CONFIG_XFS_SUPPORT is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-dig-sp linux/arch/ia64/sn/configs/sn1/defconfig-dig-sp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-dig-sp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-dig-sp	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,459 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
+# CONFIG_IA64_MCA is not set
+CONFIG_PM=y
+CONFIG_IA64_HAVE_SYNCRONIZED_ITC=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_SMP is not set
+# CONFIG_IA32_SUPPORT is not set
+# CONFIG_PERFMON is not set
+# CONFIG_IA64_PALINFO is not set
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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
+# CONFIG_XFS_SUPPORT is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-generic-mp linux/arch/ia64/sn/configs/sn1/defconfig-generic-mp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-generic-mp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-generic-mp	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,460 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+CONFIG_IA64_GENERIC=y
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+# CONFIG_IA32_SUPPORT is not set
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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
+# CONFIG_XFS_SUPPORT is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# Simulated drivers
+#
+# CONFIG_SIMETH is not set
+# CONFIG_SIM_SERIAL is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-generic-sp linux/arch/ia64/sn/configs/sn1/defconfig-generic-sp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-generic-sp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-generic-sp	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,460 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+CONFIG_IA64_GENERIC=y
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+CONFIG_KCORE_ELF=y
+# CONFIG_SMP is not set
+# CONFIG_IA32_SUPPORT is not set
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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
+# CONFIG_XFS_SUPPORT is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# Simulated drivers
+#
+# CONFIG_SIMETH is not set
+# CONFIG_SIM_SERIAL is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-hp-sp linux/arch/ia64/sn/configs/sn1/defconfig-hp-sp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-hp-sp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-hp-sp	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,334 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+CONFIG_IA64_HP_SIM=y
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+CONFIG_KCORE_ELF=y
+# CONFIG_SMP is not set
+# CONFIG_IA32_SUPPORT is not set
+# CONFIG_PERFMON is not set
+# CONFIG_IA64_PALINFO is not set
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC 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_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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=y
+# 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_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
+
+#
+# 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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
+# CONFIG_XFS_SUPPORT is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_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
+
+#
+# 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Simulated drivers
+#
+CONFIG_SIMETH=y
+CONFIG_SIM_SERIAL=y
+CONFIG_SCSI_SIM=y
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-prom-medusa linux/arch/ia64/sn/configs/sn1/defconfig-prom-medusa
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-prom-medusa	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-prom-medusa	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,529 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+CONFIG_IA64_SGI_SN1=y
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_SERIAL_SGI_L1_PROTOCOL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+# CONFIG_IA32_SUPPORT is not set
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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=y
+# 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
+# CONFIG_XFS_SUPPORT is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-sn1-mp linux/arch/ia64/sn/configs/sn1/defconfig-sn1-mp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-sn1-mp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-sn1-mp	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,736 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+CONFIG_IA64_SGI_SN1=y
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_SERIAL_SGI_L1_PROTOCOL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM 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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI=y
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI_DKSC=y
+# CONFIG_XSCSI_QLFC is not set
+# CONFIG_XSCSI_QL is not set
+# CONFIG_XSCSI_SBP2 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG 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=y
+CONFIG_SGI_IOC3_ETH=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+CONFIG_XFS_SUPPORT=y
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="n"
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+CONFIG_KDB=y
+CONFIG_KDB_MODULES=y
+# CONFIG_KDB_OFF is not set
+
+#
+#   Load all symbols for debugging is required for KDB
+#
+CONFIG_KALLSYMS=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-sn1-mp-modules linux/arch/ia64/sn/configs/sn1/defconfig-sn1-mp-modules
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-sn1-mp-modules	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-sn1-mp-modules	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,738 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+CONFIG_IA64_SGI_SN1=y
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_SERIAL_SGI_L1_PROTOCOL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM 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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI=y
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI_DKSC=y
+# CONFIG_XSCSI_QLFC is not set
+# CONFIG_XSCSI_QL is not set
+# CONFIG_XSCSI_SBP2 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG 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=y
+CONFIG_SGI_IOC3_ETH=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+CONFIG_XFS_SUPPORT=y
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="n"
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+CONFIG_KDB=y
+CONFIG_KDB_MODULES=y
+# CONFIG_KDB_OFF is not set
+
+#
+#   Load all symbols for debugging is required for KDB
+#
+CONFIG_KALLSYMS=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-sn1-mp-syn1-0 linux/arch/ia64/sn/configs/sn1/defconfig-sn1-mp-syn1-0
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-sn1-mp-syn1-0	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-sn1-mp-syn1-0	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,736 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+CONFIG_IA64_SGI_SN1=y
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_SERIAL_SGI_L1_PROTOCOL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM 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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI=y
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI_DKSC=y
+# CONFIG_XSCSI_QLFC is not set
+# CONFIG_XSCSI_QL is not set
+# CONFIG_XSCSI_SBP2 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG 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=y
+CONFIG_SGI_IOC3_ETH=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+CONFIG_XFS_SUPPORT=y
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="n"
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+CONFIG_KDB=y
+CONFIG_KDB_MODULES=y
+# CONFIG_KDB_OFF is not set
+
+#
+#   Load all symbols for debugging is required for KDB
+#
+CONFIG_KALLSYMS=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn1/defconfig-sn1-sp linux/arch/ia64/sn/configs/sn1/defconfig-sn1-sp
--- linux.orig/arch/ia64/sn/configs/sn1/defconfig-sn1-sp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn1/defconfig-sn1-sp	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,736 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+CONFIG_IA64_SGI_SN1=y
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_SERIAL_SGI_L1_PROTOCOL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+# CONFIG_SMP is not set
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM 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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI=y
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI_DKSC=y
+# CONFIG_XSCSI_QLFC is not set
+# CONFIG_XSCSI_QL is not set
+# CONFIG_XSCSI_SBP2 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG 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=y
+CONFIG_SGI_IOC3_ETH=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+CONFIG_XFS_SUPPORT=y
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="n"
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+CONFIG_KDB=y
+CONFIG_KDB_MODULES=y
+# CONFIG_KDB_OFF is not set
+
+#
+#   Load all symbols for debugging is required for KDB
+#
+CONFIG_KALLSYMS=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn2/defconfig-dig-numa linux/arch/ia64/sn/configs/sn2/defconfig-dig-numa
--- linux.orig/arch/ia64/sn/configs/sn2/defconfig-dig-numa	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn2/defconfig-dig-numa	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,460 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+CONFIG_NUMA=y
+CONFIG_DISCONTIGMEM=y
+# CONFIG_IA64_MCA is not set
+CONFIG_PM=y
+CONFIG_IA64_HAVE_SYNCRONIZED_ITC=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+# CONFIG_IA32_SUPPORT is not set
+# CONFIG_PERFMON is not set
+# CONFIG_IA64_PALINFO is not set
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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
+# CONFIG_XFS_SUPPORT is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-dig-mp linux/arch/ia64/sn/configs/sn2/defconfig-sn2-dig-mp
--- linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-dig-mp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn2/defconfig-sn2-dig-mp	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,459 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
+# CONFIG_IA64_MCA is not set
+CONFIG_PM=y
+CONFIG_IA64_HAVE_SYNCRONIZED_ITC=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+# CONFIG_IA32_SUPPORT is not set
+# CONFIG_PERFMON is not set
+# CONFIG_IA64_PALINFO is not set
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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
+# CONFIG_XFS_SUPPORT is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-dig-sp linux/arch/ia64/sn/configs/sn2/defconfig-sn2-dig-sp
--- linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-dig-sp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn2/defconfig-sn2-dig-sp	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,459 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_BRL_EMU=y
+CONFIG_ITANIUM_BSTEP_SPECIFIC=y
+CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
+# CONFIG_IA64_MCA is not set
+CONFIG_PM=y
+CONFIG_IA64_HAVE_SYNCRONIZED_ITC=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_SMP is not set
+# CONFIG_IA32_SUPPORT is not set
+# CONFIG_PERFMON is not set
+# CONFIG_IA64_PALINFO is not set
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+# CONFIG_XSCSI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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
+# CONFIG_XFS_SUPPORT is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-mp linux/arch/ia64/sn/configs/sn2/defconfig-sn2-mp
--- linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-mp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn2/defconfig-sn2-mp	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,730 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+CONFIG_IA64_SGI_SN2=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_MCKINLEY_ASTEP_SPECIFIC=y
+CONFIG_MCKINLEY_A0_SPECIFIC=y
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_SERIAL_SGI_L1_PROTOCOL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM 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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI=y
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI_DKSC=y
+# CONFIG_XSCSI_QLFC is not set
+# CONFIG_XSCSI_QL is not set
+# CONFIG_XSCSI_SBP2 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+CONFIG_XFS_SUPPORT=y
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="n"
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+CONFIG_KALLSYMS=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-mp-modules linux/arch/ia64/sn/configs/sn2/defconfig-sn2-mp-modules
--- linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-mp-modules	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn2/defconfig-sn2-mp-modules	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,732 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+CONFIG_IA64_SGI_SN2=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_MCKINLEY_ASTEP_SPECIFIC=y
+CONFIG_MCKINLEY_A0_SPECIFIC=y
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+# CONFIG_SERIAL_SGI_L1_PROTOCOL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM 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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI=y
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI_DKSC=y
+# CONFIG_XSCSI_QLFC is not set
+# CONFIG_XSCSI_QL is not set
+# CONFIG_XSCSI_SBP2 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+CONFIG_XFS_SUPPORT=y
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="n"
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+CONFIG_KALLSYMS=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-prom-medusa linux/arch/ia64/sn/configs/sn2/defconfig-sn2-prom-medusa
--- linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-prom-medusa	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn2/defconfig-sn2-prom-medusa	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,537 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+CONFIG_IA64_SGI_SN2=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_MCKINLEY_ASTEP_SPECIFIC=y
+CONFIG_MCKINLEY_A0_SPECIFIC=y
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_SERIAL_SGI_L1_PROTOCOL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+CONFIG_SMP=y
+# CONFIG_IA32_SUPPORT is not set
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI=y
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI_DKSC=y
+# CONFIG_XSCSI_QLFC is not set
+# CONFIG_XSCSI_QL is not set
+# CONFIG_XSCSI_SBP2 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_EFI_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
+# CONFIG_MWAVE 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_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 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=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+CONFIG_XFS_SUPPORT=y
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# 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
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+# CONFIG_KALLSYMS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-sp linux/arch/ia64/sn/configs/sn2/defconfig-sn2-sp
--- linux.orig/arch/ia64/sn/configs/sn2/defconfig-sn2-sp	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/configs/sn2/defconfig-sn2-sp	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,730 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_GENERIC is not set
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_SGI_SN1 is not set
+CONFIG_IA64_SGI_SN2=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_MCKINLEY_ASTEP_SPECIFIC=y
+CONFIG_MCKINLEY_A0_SPECIFIC=y
+CONFIG_IA64_SGI_SN=y
+CONFIG_IA64_SGI_SN_DEBUG=y
+CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_AUTOTEST=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_DEBUG=y
+CONFIG_SERIAL_SGI_L1_PROTOCOL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_NUMA=y
+CONFIG_PERCPU_IRQ=y
+CONFIG_PCIBA=y
+CONFIG_KCORE_ELF=y
+# CONFIG_SMP is not set
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+# CONFIG_EFI_VARS is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_BUSMGR is not set
+# CONFIG_ACPI_SYS is not set
+# CONFIG_ACPI_CPU is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_EC is not set
+# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_PCI=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM 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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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
+
+#
+# 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 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_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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
+
+#
+# Alternate 1394 support
+#
+# CONFIG_X1394 is not set
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI=y
+
+#
+# Alternate SCSI support
+#
+CONFIG_XSCSI_DKSC=y
+# CONFIG_XSCSI_QLFC is not set
+# CONFIG_XSCSI_QL is not set
+# CONFIG_XSCSI_SBP2 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_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
+# CONFIG_MWAVE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK 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=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 is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET 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=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+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
+CONFIG_XFS_SUPPORT=y
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="n"
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+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
+# CONFIG_IA64_DEBUG_IRQ is not set
+# CONFIG_KDB is not set
+# CONFIG_KDB_MODULES is not set
+CONFIG_KALLSYMS=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/Makefile linux/arch/ia64/sn/fakeprom/Makefile
--- linux.orig/arch/ia64/sn/fakeprom/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/Makefile	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,30 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+#  Copyright (c) 2000-2001 Silicon Graphics, Inc.  All rights reserved.
+#
+
+TOPDIR=../../../..
+HPATH           = $(TOPDIR)/include
+
+LIB     = ../../lib/lib.a
+
+OBJ=fpromasm.o main.o  fw-emu.o fpmem.o klgraph_init.o
+obj-y=fprom
+
+fprom: $(OBJ)
+	$(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB)
+
+.S.o:
+	$(CC)  -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
+.c.o:
+	$(CC)  $(CFLAGS) $(CFLAGS_KERNEL) -c -o $*.o $<
+
+clean:
+	rm -f *.o fprom
+
+
+include $(TOPDIR)/Rules.make
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/README linux/arch/ia64/sn/fakeprom/README
--- linux.orig/arch/ia64/sn/fakeprom/README	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/README	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,85 @@
+This directory contains the files required to build
+the fake PROM image that is currently being used to
+boot IA64 kernels running under the SGI Medusa kernel.
+
+The FPROM currently provides the following functions:
+
+	- PAL emulation for all PAL calls we've made so far.
+	- SAL emulation for all SAL calls we've made so far.
+	- EFI emulation for all EFI calls we've made so far.
+	- builds the "ia64_bootparam" structure that is
+	  passed to the kernel from SAL. This structure 
+	  shows the cpu & memory configurations.
+	- supports medusa boottime options for changing
+	  the number of cpus present
+	- supports medusa boottime options for changing
+	  the memory configuration.
+
+
+
+At some point, this fake PROM will be replaced by the
+real PROM.
+
+
+
+
+To build a fake PROM, cd to this directory & type:
+
+	make
+
+This will (or should) build a fake PROM named "fprom".
+
+
+
+
+Use this fprom image when booting the Medusa simulator. The
+control file used to boot Medusa should include the 
+following lines:
+
+	load fprom
+	load vmlinux
+	sr pc 0x100000
+	sr g 9 <address of kernel _start function> #(currently 0xe000000000520000)
+
+NOTE: There is a script "runsim" in this directory that can be used to
+simplify setting up an environment for running under Medusa.
+
+
+
+
+The following parameters may be passed to the fake PROM to
+control the PAL/SAL/EFI parameters passed to the kernel:
+
+	GR[8] = # of cpus
+	GR[9] = address of primary entry point into the kernel
+	GR[20] = memory configuration for node 0
+	GR[21] = memory configuration for node 1
+	GR[22] = memory configuration for node 2
+	GR[23] = memory configuration for node 3
+
+
+Registers GR[20] - GR[23] contain information to specify the
+amount of memory present on nodes 0-3.
+
+  - if nothing is specified (all registers are 0), the configuration
+    defaults to 8 MB on node 0.
+
+  - a mem config entry for node N is passed in GR[20+N]
+
+  - a mem config entry consists of 8 hex digits. Each digit gives the
+    amount of physical memory available on the node starting at
+    1GB*<dn>, where dn is the digit number. The amount of memory
+    is 8MB*2**<d>. (If <d> = 0, the memory size is 0).
+
+    SN1 doesnt support dimms this small but small memory systems 
+    boot faster on Medusa.
+
+
+
+An example helps a lot. The following specifies that node 0 has
+physical memory 0 to 8MB and 1GB to 1GB+32MB, and that node 1 has
+64MB starting at address 0 of the node which is 8GB.
+
+      gr[20] = 0x21           # 0 to 8MB, 1GB to 1GB+32MB
+      gr[21] = 0x4            # 8GB to 8GB+64MB
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/fpmem.c linux/arch/ia64/sn/fakeprom/fpmem.c
--- linux.orig/arch/ia64/sn/fakeprom/fpmem.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/fpmem.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,266 @@
+/* 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+
+
+/*
+ * FPROM EFI memory descriptor build routines
+ *
+ * 	- Routines to build the EFI memory descriptor map
+ * 	- Should also be usable by the SGI SN1 prom to convert
+ * 	  klconfig to efi_memmap
+ */
+
+#include <linux/config.h>
+#include <asm/efi.h>
+#include "fpmem.h"
+
+/*
+ * args points to a layout in memory like this
+ *
+ *		32 bit		32 bit
+ *
+ * 		numnodes	numcpus
+ *
+ *		16 bit   16 bit		   32 bit
+ *		nasid0	cpuconf		membankdesc0
+ *		nasid1	cpuconf		membankdesc1
+ *			   .
+ *			   .
+ *			   .
+ *			   .
+ *			   .
+ */
+
+sn_memmap_t	*sn_memmap ;
+sn_config_t	*sn_config ;
+
+/*
+ * There is a hole in the node 0 address space. Dont put it
+ * in the memory map
+ */
+#define NODE0_HOLE_SIZE         (20*MB)
+#define NODE0_HOLE_END          (4UL*GB)
+
+#define	MB			(1024*1024)
+#define GB			(1024*MB)
+#define KERNEL_SIZE		(4*MB)
+#define PROMRESERVED_SIZE	(1*MB)
+
+#ifdef CONFIG_IA64_SGI_SN1
+#define PHYS_ADDRESS(_n, _x)		(((long)_n<<33L) | (long)_x)
+#define MD_BANK_SHFT 30
+#else
+#define PHYS_ADDRESS(_n, _x)		(((long)_n<<38L) | (long)_x | 0x3000000000UL)
+#define MD_BANK_SHFT 34
+#endif
+
+/*
+ * For SN, this may not take an arg and gets the numnodes from 
+ * the prom variable or by traversing klcfg or promcfg
+ */
+int
+GetNumNodes(void)
+{
+	return sn_config->nodes;
+}
+
+int
+GetNumCpus(void)
+{
+	return sn_config->cpus;
+}
+
+/* For SN1, get the index th nasid */
+
+int
+GetNasid(int index)
+{
+	return sn_memmap[index].nasid ;
+}
+
+node_memmap_t
+GetMemBankInfo(int index)
+{
+	return sn_memmap[index].node_memmap ;
+}
+
+int
+IsCpuPresent(int cnode, int cpu)
+{
+	return  sn_memmap[cnode].cpuconfig & (1<<cpu);
+}
+
+
+/*
+ * Made this into an explicit case statement so that
+ * we can assign specific properties to banks like bank0
+ * actually disabled etc.
+ */
+
+#ifdef CONFIG_IA64_SGI_SN1
+int
+IsBankPresent(int index, node_memmap_t nmemmap)
+{
+	switch (index) {
+		case 0:return nmemmap.b0;
+		case 1:return nmemmap.b1;
+		case 2:return nmemmap.b2;
+		case 3:return nmemmap.b3;
+		case 4:return nmemmap.b4;
+		case 5:return nmemmap.b5;
+		case 6:return nmemmap.b6;
+		case 7:return nmemmap.b7;
+		default:return -1 ;
+	}
+}
+
+int
+GetBankSize(int index, node_memmap_t nmemmap)
+{
+        switch (index) {
+                case 0:
+                case 1:return nmemmap.b01size;
+                case 2:
+                case 3:return nmemmap.b23size;
+                case 4:
+                case 5:return nmemmap.b45size;
+                case 6:
+                case 7:return nmemmap.b67size;
+                default:return -1 ;
+        }
+}
+
+#else
+int
+IsBankPresent(int index, node_memmap_t nmemmap)
+{
+	switch (index) {
+		case 0:return BankPresent(nmemmap.b0size);
+		case 1:return BankPresent(nmemmap.b1size);
+		case 2:return BankPresent(nmemmap.b2size);
+		case 3:return BankPresent(nmemmap.b3size);
+		default:return -1 ;
+	}
+}
+
+int
+GetBankSize(int index, node_memmap_t nmemmap)
+{
+	/*
+	 * Add 2 because there are 4 dimms per bank.
+	 */
+        switch (index) {
+                case 0:return 2 + ((long)nmemmap.b0size + nmemmap.b0dou);
+                case 1:return 2 + ((long)nmemmap.b1size + nmemmap.b1dou);
+                case 2:return 2 + ((long)nmemmap.b2size + nmemmap.b2dou);
+                case 3:return 2 + ((long)nmemmap.b3size + nmemmap.b3dou);
+                default:return -1 ;
+        }
+}
+
+#endif
+
+void
+build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes)
+{
+        md->type = type;
+        md->phys_addr = paddr;
+        md->virt_addr = 0;
+        md->num_pages = numbytes >> 12;
+        md->attribute = EFI_MEMORY_WB;
+}
+
+int
+build_efi_memmap(void *md, int mdsize)
+{
+	int		numnodes = GetNumNodes() ;
+	int		cnode,bank ;
+	int		nasid ;
+	node_memmap_t	membank_info ;
+	int		bsize;
+	int		count = 0 ;
+	long		paddr, hole, numbytes;
+
+
+	for (cnode=0;cnode<numnodes;cnode++) {
+		nasid = GetNasid(cnode) ;
+		membank_info = GetMemBankInfo(cnode) ;
+		for (bank=0;bank<PLAT_CLUMPS_PER_NODE;bank++) {
+			if (IsBankPresent(bank, membank_info)) {
+				bsize = GetBankSize(bank, membank_info) ;
+                                paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
+                                numbytes = BankSizeBytes(bsize);
+#ifdef CONFIG_IA64_SGI_SN2
+				/* 
+				 * Ignore directory.
+				 * Shorten memory chunk by 1 page - makes a better
+				 * testcase & is more like the real PROM.
+				 */
+				numbytes = numbytes * 31 / 32;
+#endif
+				numbytes -= 1000;
+
+                                /*
+                                 * Check for the node 0 hole. Since banks cant
+                                 * span the hole, we only need to check if the end of
+                                 * the range is the end of the hole.
+                                 */
+                                if (paddr+numbytes == NODE0_HOLE_END)
+                                        numbytes -= NODE0_HOLE_SIZE;
+                                /*
+                                 * UGLY hack - we must skip overr the kernel and
+                                 * PROM runtime services but we dont exactly where it is.
+                                 * So lets just reserve:
+				 *	node 0
+				 *		0-1MB for PAL
+				 *		1-4MB for SAL
+				 *	node 1-N
+				 *		0-1 for SAL
+                                 */
+                                if (bank == 0) {
+					if (cnode == 0) {
+						hole = 1*1024*1024;
+						build_mem_desc(md, EFI_PAL_CODE, paddr, hole);
+						numbytes -= hole;
+                                        	paddr += hole;
+			        		count++ ;
+                                        	md += mdsize;
+						hole = 3*1024*1024;
+						build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
+						numbytes -= hole;
+                                        	paddr += hole;
+			        		count++ ;
+                                        	md += mdsize;
+					} else {
+						hole = PROMRESERVED_SIZE;
+                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
+						numbytes -= hole;
+                                        	paddr += hole;
+			        		count++ ;
+                                        	md += mdsize;
+					}
+                                }
+                                build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes);
+
+			        md += mdsize ;
+			        count++ ;
+			}
+		}
+	}
+	return count ;
+}
+
+void
+build_init(unsigned long args)
+{
+	sn_config = (sn_config_t *) (args);	
+	sn_memmap = (sn_memmap_t *)(args + 8) ; /* SN equiv for this is */
+						/* init to klconfig start */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/fpmem.h linux/arch/ia64/sn/fakeprom/fpmem.h
--- linux.orig/arch/ia64/sn/fakeprom/fpmem.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/fpmem.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,99 @@
+/* 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/config.h>
+
+/*
+ * Structure of the mem config of the node as a SN1 MI reg
+ * Medusa supports this reg config.
+ *
+ * BankSize nibble to bank size mapping
+ *
+ *      1 - 64 MB
+ *      2 - 128 MB
+ *      3 - 256 MB
+ *      4 - 512 MB
+ *      5 - 1024 MB (1GB)
+ */
+
+#define MBSHIFT				20
+
+#ifdef CONFIG_IA64_SGI_SN1
+typedef struct node_memmap_s
+{
+        unsigned int    b0      :1,     /* 0 bank 0 present */
+                        b1      :1,     /* 1 bank 1 present */
+                        r01     :2,     /* 2-3 reserved */
+                        b01size :4,     /* 4-7 Size of bank 0 and 1 */
+                        b2      :1,     /* 8 bank 2 present */
+                        b3      :1,     /* 9 bank 3 present */
+                        r23     :2,     /* 10-11 reserved */
+                        b23size :4,     /* 12-15 Size of bank 2 and 3 */
+                        b4      :1,     /* 16 bank 4 present */
+                        b5      :1,     /* 17 bank 5 present */
+                        r45     :2,     /* 18-19 reserved */
+                        b45size :4,     /* 20-23 Size of bank 4 and 5 */
+                        b6      :1,     /* 24 bank 6 present */
+                        b7      :1,     /* 25 bank 7 present */
+                        r67     :2,     /* 26-27 reserved */
+                        b67size :4;     /* 28-31 Size of bank 6 and 7 */
+} node_memmap_t ;
+
+/* Support the medusa hack for 8M/16M/32M nodes */
+#define SN1_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
+#define BankSizeBytes(bsize)            ((bsize<6) ? (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT)) :\
+                                         (1<<((bsize-9)+MBSHIFT)))
+#else
+typedef struct node_memmap_s
+{
+        unsigned int    b0size  :3,     /* 0-2   bank 0 size */
+                        b0dou   :1,     /* 3     bank 0 is 2-sided */
+                        ena0    :1,     /* 4     bank 0 enabled */
+                        r0      :3,     /* 5-7   reserved */
+        		b1size  :3,     /* 8-10  bank 1 size */
+                        b1dou   :1,     /* 11    bank 1 is 2-sided */
+                        ena1    :1,     /* 12    bank 1 enabled */
+                        r1      :3,     /* 13-15 reserved */
+        		b2size  :3,     /* 16-18 bank 2 size */
+                        b2dou   :1,     /* 19    bank 1 is 2-sided */
+                        ena2    :1,     /* 20    bank 2 enabled */
+                        r2      :3,     /* 21-23 reserved */
+        		b3size  :3,     /* 24-26 bank 3 size */
+                        b3dou   :1,     /* 27    bank 3 is 2-sided */
+                        ena3    :1,     /* 28    bank 3 enabled */
+                        r3      :3;     /* 29-31 reserved */
+} node_memmap_t ;
+
+#define SN2_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
+#define BankPresent(bsize)		(bsize<6)
+#define BankSizeBytes(bsize)            (BankPresent(bsize) ? 1UL<<((bsize)+SN2_BANK_SIZE_SHIFT) : 0)
+#endif
+
+typedef struct sn_memmap_s
+{
+	short		nasid ;
+	short		cpuconfig;
+	node_memmap_t 	node_memmap ;
+} sn_memmap_t ;
+
+typedef struct sn_config_s
+{
+	int		cpus;
+	int		nodes;
+	sn_memmap_t	memmap[1];		/* start of array */
+} sn_config_t;
+
+
+
+extern void build_init(unsigned long);
+extern int build_efi_memmap(void *, int);
+extern int GetNumNodes(void);
+extern int GetNumCpus(void);
+extern int IsCpuPresent(int, int);
+extern int GetNasid(int);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/fprom.lds linux/arch/ia64/sn/fakeprom/fprom.lds
--- linux.orig/arch/ia64/sn/fakeprom/fprom.lds	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/fprom.lds	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,96 @@
+
+OUTPUT_FORMAT("elf64-ia64-little")
+OUTPUT_ARCH(ia64)
+ENTRY(_start)
+SECTIONS
+{
+  v = 0x0000000000000000 ;	/* this symbol is here to make debugging with kdb easier... */
+
+  . = (0x000000000000000  + 0x100000) ;
+
+  _text = .;
+  .text : AT(ADDR(.text) - 0x0000000000000000 )
+    {
+	*(__ivt_section)
+	/* these are not really text pages, but the zero page needs to be in a fixed location: */
+	*(__special_page_section)
+	__start_gate_section = .;
+	*(__gate_section)
+	__stop_gate_section = .;
+	*(.text)
+    }
+
+  /* Global data */
+  _data = .;
+
+  .rodata : AT(ADDR(.rodata) - 0x0000000000000000 )
+	{ *(.rodata) *(.rodata.*) }
+  .opd : AT(ADDR(.opd) - 0x0000000000000000 )
+	{ *(.opd) }
+  .data : AT(ADDR(.data) - 0x0000000000000000 )
+	{ *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
+
+  __gp = ALIGN (8) + 0x200000;
+
+  .got : AT(ADDR(.got) - 0x0000000000000000 )
+	{ *(.got.plt) *(.got) }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata : AT(ADDR(.sdata) - 0x0000000000000000 )
+	{ *(.sdata) }
+  _edata  =  .;
+  _bss = .;
+  .sbss : AT(ADDR(.sbss) - 0x0000000000000000 )
+	{ *(.sbss) *(.scommon) }
+  .bss : AT(ADDR(.bss) - 0x0000000000000000 )
+	{ *(.bss) *(COMMON) }
+  . = ALIGN(64 / 8);
+  _end = .;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+	*(.text.exit)
+	*(.data.exit)
+	}
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* These must appear regardless of  .  */
+  /* Discard them for now since Intel SoftSDV cannot handle them.
+  .comment 0 : { *(.comment) }
+  .note 0 : { *(.note) }
+  */
+  /DISCARD/ : { *(.comment) }
+  /DISCARD/ : { *(.note) }
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/fpromasm.S linux/arch/ia64/sn/fakeprom/fpromasm.S
--- linux.orig/arch/ia64/sn/fakeprom/fpromasm.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/fpromasm.S	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,403 @@
+/* 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *   (Code copied from or=ther files)
+ * Copyright (C) 1998-2000 Hewlett-Packard Co
+ * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+
+#define __ASSEMBLY__ 1
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn2/shub_mmr.h>
+
+/*
+ * This file contains additional set up code that is needed to get going on
+ * Medusa.  This code should disappear once real hw is available.
+ *
+ * On entry to this routine, the following register values are assumed:
+ *
+ *	gr[8]	- BSP cpu
+ *	pr[9]	- kernel entry address
+ *	pr[10]	- cpu number on the node
+ *
+ * NOTE:
+ *   This FPROM may be loaded/executed at an address different from the
+ *   address that it was linked at. The FPROM is linked to run on node 0
+ *   at address 0x100000. If the code in loaded into another node, it
+ *   must be loaded at offset 0x100000 of the node. In addition, the
+ *   FPROM does the following things:
+ *		- determine the base address of the node it is loaded on
+ *		- add the node base to _gp.
+ *		- add the node base to all addresses derived from "movl" 
+ *		  instructions. (I couldnt get GPREL addressing to work)
+ *		  (maybe newer versions of the tools will support this)
+ *		- scan the .got section and add the node base to all
+ *		  pointers in this section.
+ *		- add the node base to all physical addresses in the
+ *		  SAL/PAL/EFI table built by the C code. (This is done
+ *		  in the C code - not here)
+ *		- add the node base to the TLB entries for vmlinux
+ */
+
+#define KERNEL_BASE	0xe000000000000000
+#define BOOT_PARAM_ADDR 0x40000
+
+
+/* 
+ * ar.k0 gets set to IOPB_PA value, on 460gx chipset it should 
+ * be 0x00000ffffc000000, but on snia we use the (inverse swizzled)
+ * IOSPEC_BASE value
+ */
+#ifdef CONFIG_IA64_SGI_SN1
+#define IOPB_PA		0xc0000FFFFC000000
+#else
+#define IOPB_PA		0xc000000fcc000000
+#endif
+
+#define RR_RID		8
+
+
+
+// ====================================================================================	
+        .text
+        .align 16
+	.global _start
+	.proc _start
+_start:
+
+// Setup psr and rse for system init
+	mov		psr.l = r0;;
+	srlz.d;;
+	invala
+	mov		ar.rsc = r0;;
+	loadrs
+	;;
+
+// Isolate node number we are running on.
+	mov		r6 = ip;;
+#ifdef CONFIG_IA64_SGI_SN1
+	shr		r5 = r6,33;;			// r5 = node number
+	shl		r6 = r5,33			// r6 = base memory address of node
+#else
+	shr		r5 = r6,38			// r5 = node number
+	dep		r6 = 0,r6,0,36			// r6 = base memory address of node
+
+#endif
+
+
+// Set & relocate gp.
+	movl		r1= __gp;;			// Add base memory address
+	or 		r1 = r1,r6			// Relocate to boot node
+
+// Lets figure out who we are & put it in the LID register.
+#ifdef CONFIG_IA64_SGI_SN2
+// On SN2, we (currently) pass the cpu number in r10 at boot
+	and		r25=3,r10;;
+	movl		r16=0x8000008110000400		// Allow IPIs
+	mov		r17=-1;;
+	st8		[r16]=r17
+	movl		r16=0x8000008110060580;;	// SHUB_ID
+	ld8		r27=[r16];;
+	extr.u		r27=r27,32,11;;
+	shl 		r26=r25,28;;			// Align local cpu# to lid.eid
+	shl 		r27=r27,16;;			// Align NASID to lid.id
+	or  		r26=r26,r27;;			// build the LID
+#else
+// The BR_PI_SELF_CPU_NUM register gives us a value of 0-3.
+// This identifies the cpu on the node. 
+// Merge the cpu number with the NASID to generate the LID.
+	movl		r24=0x80000a0001000020;;	// BR_PI_SELF_CPU_NUM
+	ld8 		r25=[r24]			// Fetch PI_SELF
+	movl		r27=0x80000a0001600000;;	// Fetch REVID to get local NASID
+	ld8 		r27=[r27];;
+	extr.u		r27=r27,32,8;;
+	shl 		r26=r25,16;;			// Align local cpu# to lid.eid
+	shl 		r27=r27,24;;			// Align NASID to lid.id
+	or  		r26=r26,r27;;			// build the LID
+#endif
+	mov 		cr.lid=r26			// Now put in in the LID register
+
+	movl		r2=FPSR_DEFAULT;;
+	mov 		ar.fpsr=r2
+	movl		sp = bootstacke-16;;
+	or 		sp = sp,r6			// Relocate to boot node			
+
+// Save the NASID that we are loaded on.
+	movl		r2=base_nasid;;			// Save base_nasid for C code
+	or 		r2 = r2,r6;;			// Relocate to boot node
+  	st8 		[r2]=r5				// Uncond st8 - same on all cpus
+
+// Save the kernel entry address. It is passed in r9 on one of
+// the cpus.
+	movl		r2=bsp_entry_pc
+	cmp.ne		p6,p0=r9,r0;;
+	or 		r2 = r2,r6;;			// Relocate to boot node
+(p6)  	st8 		[r2]=r9				// Uncond st8 - same on all cpus
+
+
+// The following can ONLY be done by 1 cpu. Lets set a lock - the
+// cpu that gets it does the initilization. The rest just spin waiting
+// til initilization is complete.
+	movl		r22 = initlock;;
+	or		r22 = r22,r6			// Relocate to boot node
+	mov		r23 = 1;;
+	xchg8		r23 = [r22],r23;;
+	cmp.eq 		p6,p0 = 0,r23
+(p6)	br.cond.spnt.few init
+1:	ld4		r23 = [r22];;
+	cmp.eq		p6,p0 = 1,r23
+(p6)	br.cond.sptk	1b
+	br		initx
+
+// Add base address of node memory to each pointer in the .got section.
+init:	movl		r16 = _GLOBAL_OFFSET_TABLE_;;
+	or		r16 = r16,r6;;			// Relocate to boot node
+1: 	ld8		r17 = [r16];;
+	cmp.eq		p6,p7=0,r17
+(p6)	br.cond.sptk.few.clr 2f;;
+	or		r17 = r17,r6;;			// Relocate to boot node
+	st8		[r16] = r17,8
+	br		1b
+2:
+	mov		r23 = 2;;			// All done, release the spinning cpus
+	st4		[r22] = r23
+initx:
+
+//
+//	I/O-port space base address:
+//
+	movl		r2 = IOPB_PA;;
+	mov		ar.k0 = r2
+
+
+// Now call main & pass it the current LID value.
+	alloc 		r0=ar.pfs,0,0,2,0
+	mov    		r32=r26
+	mov   		r33=r8;;
+	br.call.sptk.few rp=fmain
+	
+// Initialize Region Registers
+//
+        mov             r10 = r0
+        mov             r2 = (13<<2)
+        mov             r3 = r0;;
+1:      cmp4.gtu        p6,p7 = 7, r3
+        dep             r10 = r3, r10, 61, 3
+        dep             r2 = r3, r2, RR_RID, 4;;
+(p7)    dep             r2 = 0, r2, 0, 1;;
+(p6)    dep             r2 = -1, r2, 0, 1;;
+        mov             rr[r10] = r2
+        add             r3 = 1, r3;;
+        srlz.d;;
+        cmp4.gtu        p6,p0 = 8, r3
+(p6)    br.cond.sptk.few.clr 1b
+
+//
+// Return value indicates if we are the BSP or AP.
+// 	   1 = BSP, 0 = AP
+	mov             cr.tpr=r0;;
+	cmp.eq		p6,p0=r8,r0
+(p6)	br.cond.spnt	slave
+
+//
+// Go to kernel C startup routines
+//	Need to do a "rfi" in order set "it" and "ed" bits in the PSR.
+//	This is the only way to set them.
+
+	movl		r28=BOOT_PARAM_ADDR
+	movl		r2=bsp_entry_pc;;
+	or 		r28 = r28,r6;;			// Relocate to boot node
+	or 		r2 = r2,r6;;			// Relocate to boot node
+	ld8		r2=[r2];;
+	or		r2=r2,r6;;
+	dep		r2=0,r2,61,3;;			// convert to phys mode
+
+//
+// Turn on address translation, interrupt collection, psr.ed, protection key.
+// Interrupts (PSR.i) are still off here.
+//
+
+        movl            r3 = (  IA64_PSR_BN | \
+                                IA64_PSR_AC | \
+                                IA64_PSR_DB | \
+                                IA64_PSR_DA | \
+                                IA64_PSR_IC   \
+                             )
+        ;;
+        mov             cr.ipsr = r3
+
+//
+// Go to kernel C startup routines
+//      Need to do a "rfi" in order set "it" and "ed" bits in the PSR.
+//      This is the only way to set them.
+
+	mov		r8=r28;;
+	bsw.1		;;
+	mov		r28=r8;;
+	bsw.0		;;
+        mov             cr.iip = r2
+        srlz.d;;
+        rfi;;
+
+	.endp		_start
+
+
+
+// Slave processors come here to spin til they get an interrupt. Then they launch themselves to
+// the place ap_entry points. No initialization is necessary - the kernel makes no
+// assumptions about state on this entry.
+//	Note: should verify that the interrupt we got was really the ap_wakeup
+//	      interrupt but this should not be an issue on medusa
+slave:
+	nop.i		0x8beef				// Medusa - put cpu to sleep til interrupt occurs
+	mov		r8=cr.irr0;;			// Check for interrupt pending.
+	cmp.eq		p6,p0=r8,r0
+(p6)	br.cond.sptk	slave;;
+
+	mov		r8=cr.ivr;;			// Got one. Must read ivr to accept it
+	srlz.d;;
+	mov		cr.eoi=r0;;			// must write eoi to clear
+	movl		r8=ap_entry;;			// now jump to kernel entry
+	or 		r8 = r8,r6;;			// Relocate to boot node
+	ld8		r9=[r8],8;;
+	ld8		r1=[r8]
+	mov		b0=r9;;
+	br		b0
+
+// Here is the kernel stack used for the fake PROM
+	.bss
+	.align		16384
+bootstack:
+	.skip		16384
+bootstacke:
+initlock:
+	data4
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+// This code emulates the PAL. Only essential interfaces are emulated.
+
+
+	.text
+	.global	pal_emulator
+	.proc	pal_emulator
+pal_emulator:
+	mov	r8=-1
+
+	mov	r9=256
+	;;
+	cmp.gtu p6,p7=r9,r28		/* r28 <= 255? */
+(p6)	br.cond.sptk.few static
+	;;
+	mov	r9=512
+	;;
+	cmp.gtu p6,p7=r9,r28
+(p6)	br.cond.sptk.few stacked
+	;;
+
+static:	cmp.eq	p6,p7=6,r28		/* PAL_PTCE_INFO */
+(p7)	br.cond.sptk.few 1f
+	movl	r8=0				/* status = 0 */
+	movl	r9=0x100000000			/* tc.base */
+	movl	r10=0x0000000200000003		/* count[0], count[1] */
+	movl	r11=0x1000000000002000		/* stride[0], stride[1] */
+	;;
+
+1:	cmp.eq	p6,p7=14,r28		/* PAL_FREQ_RATIOS */
+(p7)	br.cond.sptk.few 1f
+	movl	r8=0				/* status = 0 */
+	movl	r9 =0x100000064			/* proc_ratio (1/100) */
+	movl	r10=0x100000100			/* bus_ratio<<32 (1/256) */
+	movl	r11=0x10000000a			/* itc_ratio<<32 (1/100) */
+	;;
+
+1:	cmp.eq	p6,p7=8,r28		/* PAL_VM_SUMMARY */
+(p7)	br.cond.sptk.few 1f
+	movl	r8=0
+#ifdef CONFIG_IA64_SGI_SN1
+	movl	r9=0x0203083001151059
+	movl	r10=0x1232
+#else
+	movl	r9=0x0203083001151065
+	movl	r10=0x183f
+#endif
+	movl	r11=0
+	;;
+
+1:	cmp.eq	p6,p7=19,r28		/* PAL_RSE_INFO */
+(p7)	br.cond.sptk.few 1f
+	movl	r8=0
+	movl	r9=0x60
+	movl	r10=0x0
+	movl	r11=0
+	;;
+
+1:	cmp.eq	p6,p7=15,r28		/* PAL_PERF_MON_INFO */
+(p7)	br.cond.sptk.few 1f
+	movl	r8=0
+	movl	r9=0x08122004
+	movl	r10=0x0
+	movl	r11=0
+	mov	r2=ar.lc
+	mov	r3=16;;
+	mov	ar.lc=r3
+	mov	r3=r29;;
+5:	st8	[r3]=r0,8
+	br.cloop.sptk.few 5b;;
+	mov	ar.lc=r2
+	mov	r3=r29
+	movl	r2=0x1fff;;			/* PMC regs */
+	st8	[r3]=r2
+	add	r3=32,r3
+	movl	r2=0x3ffff;;			/* PMD regs */
+	st8	[r3]=r2
+	add	r3=32,r3
+	movl	r2=0xf0;;			/* cycle regs */
+	st8	[r3]=r2
+	add	r3=32,r3
+	movl	r2=0x10;;			/* retired regs */
+	st8	[r3]=r2
+	;;
+
+1:	cmp.eq	p6,p7=19,r28		/* PAL_RSE_INFO */
+(p7)	br.cond.sptk.few 1f
+	movl	r8=0				/* status = 0 */
+	movl	r9=96				/* num phys stacked */
+	movl	r10=0				/* hints */
+	movl	r11=0
+	;;
+
+1:	cmp.eq	p6,p7=1,r28		/* PAL_CACHE_FLUSH */
+(p7)	br.cond.sptk.few 1f
+	mov	r9=ar.lc
+	movl	r8=524288				/* flush 512k million cache lines (16MB) */
+	;;
+	mov	ar.lc=r8
+	movl	r8=0xe000000000000000
+	;;
+.loop:	fc	r8
+	add	r8=32,r8
+	br.cloop.sptk.few .loop
+	sync.i
+	;;
+	srlz.i
+	;;
+	mov	ar.lc=r9
+	mov	r8=r0
+1:	br.cond.sptk.few rp
+
+stacked:
+	br.ret.sptk.few rp
+
+	.endp pal_emulator
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/fw-emu.c linux/arch/ia64/sn/fakeprom/fw-emu.c
--- linux.orig/arch/ia64/sn/fakeprom/fw-emu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/fw-emu.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,836 @@
+/*
+ * PAL & SAL emulation.
+ *
+ * Copyright (C) 1998-2000 Hewlett-Packard Co
+ * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+#include <linux/config.h>
+#include <asm/efi.h>
+#include <asm/pal.h>
+#include <asm/sal.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/processor.h>
+#include <asm/sn/sn_cpuid.h>
+#ifdef CONFIG_IA64_SGI_SN2
+#include <asm/sn/sn2/addrs.h>
+#include <asm/sn/sn2/shub_mmr.h>
+#endif
+#include <asm/acpi-ext.h>
+#include "fpmem.h"
+
+#define zzACPI_1_0	1		/* Include ACPI 1.0 tables */
+
+#define OEMID			"SGI"
+#ifdef CONFIG_IA64_SGI_SN1
+#define PRODUCT			"SN1"
+#define PROXIMITY_DOMAIN(nasid)	(nasid)
+#else
+#define PRODUCT			"SN2"
+#define PROXIMITY_DOMAIN(nasid)	(((nasid)>>1) & 255)
+#endif
+
+#define MB	(1024*1024UL)
+#define GB	(MB*1024UL)
+#define BOOT_PARAM_ADDR 0x40000
+#define MAX(i,j)		((i) > (j) ? (i) : (j))
+#define MIN(i,j)		((i) < (j) ? (i) : (j))
+#define ABS(i)			((i) > 0   ? (i) : -(i))
+#define ALIGN8(p)		(((long)(p) +7) & ~7)
+
+#define FPROM_BUG()		do {while (1);} while (0)
+#define MAX_SN_NODES		128
+#define MAX_LSAPICS		512
+#define MAX_CPUS		512
+#define MAX_CPUS_NODE		4
+#define CPUS_PER_NODE		4
+#define CPUS_PER_FSB		2
+#define CPUS_PER_FSB_MASK	(CPUS_PER_FSB-1)
+
+#ifdef ACPI_1_0
+#define NUM_EFI_DESCS		3
+#else
+#define NUM_EFI_DESCS		2
+#endif
+
+#define RSDP_CHECKSUM_LENGTH	20
+
+typedef union ia64_nasid_va {
+        struct {
+#if defined(CONFIG_IA64_SGI_SN1)
+                unsigned long off   : 33;       /* intra-region offset */
+		unsigned long nasid :  7;	/* NASID */
+		unsigned long off2  : 21;	/* fill */
+                unsigned long reg   :  3;       /* region number */
+#elif defined(CONFIG_IA64_SGI_SN2)
+                unsigned long off   : 36;       /* intra-region offset */
+		unsigned long attr  :  2;
+		unsigned long nasid : 11;	/* NASID */
+		unsigned long off2  : 12;	/* fill */
+                unsigned long reg   :  3;       /* region number */
+#endif
+        } f;
+        unsigned long l;
+        void *p;
+} ia64_nasid_va;
+
+typedef struct {
+	unsigned long	pc;
+	unsigned long	gp;
+} func_ptr_t;
+ 
+#define IS_VIRTUAL_MODE() 	 ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
+#define ADDR_OF(p)		(IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
+
+#if defined(CONFIG_IA64_SGI_SN1)
+#define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.l;})
+#elif defined(CONFIG_IA64_SGI_SN2)
+#define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.f.attr = 3; _v.l;})
+#endif
+
+/*
+ * The following variables are passed thru registersfrom the configuration file and
+ * are set via the _start function.
+ */
+long		base_nasid;
+long		num_cpus;
+long		bsp_entry_pc=0;
+long		num_nodes;
+long		app_entry_pc;
+int		bsp_lid;
+func_ptr_t	ap_entry;
+
+
+extern void pal_emulator(void);
+static efi_runtime_services_t    *efi_runtime_p;
+static char fw_mem[(  sizeof(efi_system_table_t)
+		    + sizeof(efi_runtime_services_t)
+		    + NUM_EFI_DESCS*sizeof(efi_config_table_t)
+		    + sizeof(struct ia64_sal_systab)
+		    + sizeof(struct ia64_sal_desc_entry_point)
+		    + sizeof(struct ia64_sal_desc_ap_wakeup)
+#ifdef ACPI_1_0
+		    + sizeof(acpi_rsdp_t)
+		    + sizeof(acpi_rsdt_t)
+		    + sizeof(acpi_sapic_t)
+		    + MAX_LSAPICS*(sizeof(acpi_entry_lsapic_t))
+#endif
+		    + sizeof(acpi20_rsdp_t)
+		    + sizeof(acpi_xsdt_t)
+		    + sizeof(acpi_slit_t)
+		    +   MAX_SN_NODES*MAX_SN_NODES+8
+		    + sizeof(acpi_madt_t)
+		    +   16*MAX_CPUS
+		    + (1+8*MAX_SN_NODES)*(sizeof(efi_memory_desc_t))
+		    + sizeof(acpi_srat_t)
+		    +   MAX_CPUS*sizeof(srat_cpu_affinity_t)
+		    +   MAX_SN_NODES*sizeof(srat_memory_affinity_t)
+		    + sizeof(ia64_sal_desc_ptc_t) +
+		    + MAX_SN_NODES*sizeof(ia64_sal_ptc_domain_info_t) +
+		    + MAX_CPUS*sizeof(ia64_sal_ptc_domain_proc_entry_t) +
+		    + 1024)] __attribute__ ((aligned (8)));
+
+
+static efi_status_t
+efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
+{
+	if (tm) {
+		memset(tm, 0, sizeof(*tm));
+		tm->year = 2000;
+		tm->month = 2;
+		tm->day = 13;
+		tm->hour = 10;
+		tm->minute = 11;
+		tm->second = 12;
+	}
+
+	if (tc) {
+		tc->resolution = 10;
+		tc->accuracy = 12;
+		tc->sets_to_zero = 1;
+	}
+
+	return EFI_SUCCESS;
+}
+
+static void
+efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
+{
+	while(1);	/* Is there a pseudo-op to stop medusa */
+}
+
+static efi_status_t
+efi_success (void)
+{
+	return EFI_SUCCESS;
+}
+
+static efi_status_t
+efi_unimplemented (void)
+{
+	return EFI_UNSUPPORTED;
+}
+
+#ifdef CONFIG_IA64_SGI_SN2
+
+#undef cpu_physical_id
+#define cpu_physical_id(cpuid)                  ((ia64_get_lid() >> 16) & 0xffff)
+
+void
+fprom_send_cpei(void) {
+        long            *p, val;
+        long            physid;
+        long            nasid, slice;
+
+        physid = cpu_physical_id(0);
+        nasid = cpu_physical_id_to_nasid(physid);
+        slice = cpu_physical_id_to_slice(physid);
+
+        p = (long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT);
+        val =   (1UL<<SH_IPI_INT_SEND_SHFT) |
+                (physid<<SH_IPI_INT_PID_SHFT) |
+                ((long)0<<SH_IPI_INT_TYPE_SHFT) |
+                ((long)0x1e<<SH_IPI_INT_IDX_SHFT) |
+                (0x000feeUL<<SH_IPI_INT_BASE_SHFT);
+        *p = val;
+
+}
+#endif
+
+
+static long
+sal_emulator (long index, unsigned long in1, unsigned long in2,
+	      unsigned long in3, unsigned long in4, unsigned long in5,
+	      unsigned long in6, unsigned long in7)
+{
+	register long r9 asm ("r9") = 0;
+	register long r10 asm ("r10") = 0;
+	register long r11 asm ("r11") = 0;
+	long status;
+
+	/*
+	 * Don't do a "switch" here since that gives us code that
+	 * isn't self-relocatable.
+	 */
+	status = 0;
+	if (index == SAL_FREQ_BASE) {
+		switch (in1) {
+		      case SAL_FREQ_BASE_PLATFORM:
+			r9 = 500000000;
+			break;
+
+		      case SAL_FREQ_BASE_INTERVAL_TIMER:
+			/*
+			 * Is this supposed to be the cr.itc frequency
+			 * or something platform specific?  The SAL
+			 * doc ain't exactly clear on this...
+			 */
+			r9 = 700000000;
+			break;
+
+		      case SAL_FREQ_BASE_REALTIME_CLOCK:
+			r9 = 50000000;
+			break;
+
+		      default:
+			status = -1;
+			break;
+		}
+	} else if (index == SAL_SET_VECTORS) {
+		if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
+			func_ptr_t	*fp;
+			fp = ADDR_OF(&ap_entry);
+			fp->pc = in2;
+			fp->gp = in3;
+		} else if (in1 == SAL_VECTOR_OS_MCA || in1 == SAL_VECTOR_OS_INIT) {
+		} else {
+			status = -1;
+		}
+		;
+	} else if (index == SAL_GET_STATE_INFO) {
+		;
+	} else if (index == SAL_GET_STATE_INFO_SIZE) {
+		;
+	} else if (index == SAL_CLEAR_STATE_INFO) {
+		;
+	} else if (index == SAL_MC_RENDEZ) {
+		;
+	} else if (index == SAL_MC_SET_PARAMS) {
+		;
+	} else if (index == SAL_CACHE_FLUSH) {
+		;
+	} else if (index == SAL_CACHE_INIT) {
+		;
+	} else if (index == SAL_UPDATE_PAL) {
+		;
+#ifdef CONFIG_IA64_SGI_SN2
+	} else if (index == SN_SAL_LOG_CE) {
+#ifdef ajmtestcpei
+		fprom_send_cpei();
+#else /* ajmtestcpei */
+		;
+#endif /* ajmtestcpei */
+#endif
+	} else if (index == SN_SAL_PROBE) {
+		r9 = 0UL;
+		if (in2 == 4) {
+			r9 = *(unsigned *)in1;
+			if (r9 == -1) {
+				status = 1;
+			}
+		} else if (in2 == 2) {
+			r9 = *(unsigned short *)in1;
+			if (r9 == -1) {
+				status = 1;
+			}
+		} else if (in2 == 1) {
+			r9 = *(unsigned char *)in1;
+			if (r9 == -1) {
+				status = 1;
+			}
+		} else if (in2 == 8) {
+			r9 = *(unsigned long *)in1;
+			if (r9 == -1) {
+				status = 1;
+			}
+		} else {
+			status = 2;
+		}
+	} else if (index == SN_SAL_GET_KLCONFIG_ADDR) {
+		r9 = 0x30000;
+	} else if (index == SN_SAL_CONSOLE_PUTC) {
+		status = -1;
+	} else if (index == SN_SAL_CONSOLE_GETC) {
+		status = -1;
+	} else if (index == SN_SAL_CONSOLE_POLL) {
+		status = -1;
+	} else {
+		status = -1;
+	}
+
+	asm volatile ("" :: "r"(r9), "r"(r10), "r"(r11));
+	return status;
+}
+
+
+/*
+ * This is here to work around a bug in egcs-1.1.1b that causes the
+ * compiler to crash (seems like a bug in the new alias analysis code.
+ */
+void *
+id (long addr)
+{
+	return (void *) addr;
+}
+
+
+/*
+ * Fix the addresses in a function pointer by adding base node address
+ * to pc & gp.
+ */
+void
+fix_function_pointer(void *fp)
+{
+	func_ptr_t	*_fp;
+
+	_fp = fp;
+	_fp->pc = __fwtab_pa(base_nasid, _fp->pc);
+	_fp->gp = __fwtab_pa(base_nasid, _fp->gp);
+}
+
+void
+fix_virt_function_pointer(void **fptr)
+{
+        func_ptr_t      *fp;
+	long		*p;
+
+	p = (long*)fptr;
+        fp = *fptr;
+        fp->pc = fp->pc | PAGE_OFFSET;
+        fp->gp = fp->gp | PAGE_OFFSET;
+	*p |= PAGE_OFFSET;
+}
+
+
+int
+efi_set_virtual_address_map(void)
+{
+        efi_runtime_services_t            *runtime;
+
+        runtime = efi_runtime_p;
+        fix_virt_function_pointer((void**)&runtime->get_time);
+        fix_virt_function_pointer((void**)&runtime->set_time);
+        fix_virt_function_pointer((void**)&runtime->get_wakeup_time);
+        fix_virt_function_pointer((void**)&runtime->set_wakeup_time);
+        fix_virt_function_pointer((void**)&runtime->set_virtual_address_map);
+        fix_virt_function_pointer((void**)&runtime->get_variable);
+        fix_virt_function_pointer((void**)&runtime->get_next_variable);
+        fix_virt_function_pointer((void**)&runtime->set_variable);
+        fix_virt_function_pointer((void**)&runtime->get_next_high_mono_count);
+        fix_virt_function_pointer((void**)&runtime->reset_system);
+        return EFI_SUCCESS;;
+}
+
+void
+acpi_table_init(acpi_desc_table_hdr_t *p, char *sig, int siglen, int revision, int oem_revision)
+{
+	memcpy(p->signature, sig, siglen);
+	memcpy(p->oem_id, OEMID, 6);
+	memcpy(p->oem_table_id, sig, 4);
+	memcpy(p->oem_table_id+4, PRODUCT, 4);
+	p->revision = revision;
+	p->oem_revision = (revision<<16) + oem_revision;
+	p->creator_id = 1;
+	p->creator_revision = 1;
+}
+
+void
+acpi_checksum(acpi_desc_table_hdr_t *p, int length)
+{
+	u8	*cp, *cpe, checksum;
+
+	p->checksum = 0;
+	p->length = length;
+	checksum = 0;
+	for (cp=(u8*)p, cpe=cp+p->length; cp<cpe; cp++)
+		checksum += *cp;
+	p->checksum = -checksum;
+}
+
+void
+acpi_checksum_rsdp20(acpi20_rsdp_t *p, int length)
+{
+	u8	*cp, *cpe, checksum;
+
+	p->checksum = 0;
+	p->length = length;
+	checksum = 0;
+	for (cp=(u8*)p, cpe=cp+RSDP_CHECKSUM_LENGTH; cp<cpe; cp++)
+		checksum += *cp;
+	p->checksum = -checksum;
+}
+
+int
+nasid_present(int nasid)
+{
+	int	cnode;
+	for (cnode=0; cnode<num_nodes; cnode++)
+		if (GetNasid(cnode) == nasid)
+			return 1;
+	return 0;
+}
+
+void
+sys_fw_init (const char *args, int arglen, int bsp)
+{
+	/*
+	 * Use static variables to keep from overflowing the RSE stack
+	 */
+	static efi_system_table_t *efi_systab;
+	static efi_runtime_services_t *efi_runtime;
+	static efi_config_table_t *efi_tables;
+	static ia64_sal_desc_ptc_t *sal_ptc;
+	static ia64_sal_ptc_domain_info_t *sal_ptcdi;
+	static ia64_sal_ptc_domain_proc_entry_t *sal_ptclid;
+#ifdef ACPI_1_0
+	static acpi_rsdp_t *acpi_rsdp;
+	static acpi_rsdt_t *acpi_rsdt;
+	static acpi_sapic_t *acpi_sapic;
+	static acpi_entry_lsapic_t *acpi_lsapic;
+#endif
+	static acpi20_rsdp_t *acpi20_rsdp;
+	static acpi_xsdt_t *acpi_xsdt;
+	static acpi_slit_t *acpi_slit;
+	static acpi_madt_t *acpi_madt;
+	static acpi20_entry_lsapic_t *lsapic20;
+	static struct ia64_sal_systab *sal_systab;
+	static acpi_srat_t *acpi_srat;
+	static srat_cpu_affinity_t *srat_cpu_affinity;
+	static srat_memory_affinity_t *srat_memory_affinity;
+	static efi_memory_desc_t *efi_memmap, *md;
+	static unsigned long *pal_desc, *sal_desc;
+	static struct ia64_sal_desc_entry_point *sal_ed;
+	static struct ia64_boot_param *bp;
+	static struct ia64_sal_desc_ap_wakeup *sal_apwake;
+	static unsigned char checksum;
+	static char *cp, *cmd_line, *vendor;
+	static void *ptr;
+	static int mdsize, domain, last_domain ;
+	static int i, j, cnode, max_nasid, nasid, cpu, num_memmd, cpus_found;
+
+	/*
+	 * Pass the parameter base address to the build_efi_xxx routines.
+	 */
+#if defined(CONFIG_IA64_SGI_SN1)
+	build_init(8LL*GB*base_nasid);
+#else
+	build_init(0x3000000000UL | ((long)base_nasid<<38));
+#endif
+
+	num_nodes = GetNumNodes();
+	num_cpus = GetNumCpus();
+	for (max_nasid=0, cnode=0; cnode<num_nodes; cnode++)
+		max_nasid = MAX(max_nasid, GetNasid(cnode));
+
+
+	memset(fw_mem, 0, sizeof(fw_mem));
+
+	pal_desc = (unsigned long *) &pal_emulator;
+	sal_desc = (unsigned long *) &sal_emulator;
+	fix_function_pointer(&pal_emulator);
+	fix_function_pointer(&sal_emulator);
+
+	/* Align this to 16 bytes, probably EFI does this  */
+	mdsize = (sizeof(efi_memory_desc_t) + 15) & ~15 ;
+
+	cp = fw_mem;
+	efi_systab  = (void *) cp; cp += ALIGN8(sizeof(*efi_systab));
+	efi_runtime_p = efi_runtime = (void *) cp; cp += ALIGN8(sizeof(*efi_runtime));
+	efi_tables  = (void *) cp; cp += ALIGN8(NUM_EFI_DESCS*sizeof(*efi_tables));
+	sal_systab  = (void *) cp; cp += ALIGN8(sizeof(*sal_systab));
+	sal_ed      = (void *) cp; cp += ALIGN8(sizeof(*sal_ed));
+	sal_ptc     = (void *) cp; cp += ALIGN8(sizeof(*sal_ptc));
+	sal_apwake  = (void *) cp; cp += ALIGN8(sizeof(*sal_apwake));
+	acpi20_rsdp = (void *) cp; cp += ALIGN8(sizeof(*acpi20_rsdp));
+	acpi_xsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_xsdt) + 64); 
+			/* save space for more OS defined table pointers. */
+
+#ifdef ACPI_1_0
+	acpi_rsdp   = (void *) cp; cp += ALIGN8(sizeof(*acpi_rsdp));
+	acpi_rsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_rsdt));
+	acpi_sapic  = (void *) cp; cp += sizeof(*acpi_sapic);
+	acpi_lsapic = (void *) cp; cp += num_cpus*sizeof(*acpi_lsapic);
+#endif
+	acpi_slit   = (void *) cp; cp += ALIGN8(sizeof(*acpi_slit) + 8 + (max_nasid+1)*(max_nasid+1));
+	acpi_madt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_madt) + 8 * num_cpus+ 8);
+	acpi_srat   = (void *) cp; cp += ALIGN8(sizeof(acpi_srat_t));
+	cp         += sizeof(srat_cpu_affinity_t)*num_cpus + sizeof(srat_memory_affinity_t)*num_nodes;
+	vendor 	    = (char *) cp; cp += ALIGN8(40);
+	efi_memmap  = (void *) cp; cp += ALIGN8(8*32*sizeof(*efi_memmap));
+	sal_ptcdi   = (void *) cp; cp += ALIGN8(CPUS_PER_FSB*(1+num_nodes)*sizeof(*sal_ptcdi));
+	sal_ptclid  = (void *) cp; cp += ALIGN8(((3+num_cpus)*sizeof(*sal_ptclid)+7)/8*8);
+	cmd_line    = (void *) cp;
+
+	if (args) {
+		if (arglen >= 1024)
+			arglen = 1023;
+		memcpy(cmd_line, args, arglen);
+	} else {
+		arglen = 0;
+	}
+	cmd_line[arglen] = '\0';
+	/* 
+	 * For now, just bring up bash.
+	 * If you want to execute all the startup scripts, delete the "init=..".
+	 * You can also edit this line to pass other arguments to the kernel.
+	 *    Note: disable kernel text replication.
+	 */
+	strcpy(cmd_line, "init=/bin/bash ktreplicate=0");
+
+	memset(efi_systab, 0, sizeof(efi_systab));
+	efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
+	efi_systab->hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
+	efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
+	efi_systab->fw_vendor = __fwtab_pa(base_nasid, vendor);
+	efi_systab->fw_revision = 1;
+	efi_systab->runtime = __fwtab_pa(base_nasid, efi_runtime);
+	efi_systab->nr_tables = 2;
+	efi_systab->tables = __fwtab_pa(base_nasid, efi_tables);
+	memcpy(vendor, "S\0i\0l\0i\0c\0o\0n\0-\0G\0r\0a\0p\0h\0i\0c\0s\0\0", 40);
+
+	efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
+	efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
+	efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
+	efi_runtime->get_time = __fwtab_pa(base_nasid, &efi_get_time);
+	efi_runtime->set_time = __fwtab_pa(base_nasid, &efi_unimplemented);
+	efi_runtime->get_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
+	efi_runtime->set_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
+	efi_runtime->set_virtual_address_map = __fwtab_pa(base_nasid, &efi_set_virtual_address_map);
+	efi_runtime->get_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
+	efi_runtime->get_next_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
+	efi_runtime->set_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
+	efi_runtime->get_next_high_mono_count = __fwtab_pa(base_nasid, &efi_unimplemented);
+	efi_runtime->reset_system = __fwtab_pa(base_nasid, &efi_reset_system);
+
+	efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
+	efi_tables->table = __fwtab_pa(base_nasid, sal_systab);
+	efi_tables++;
+#ifdef ACPI_1_0
+	efi_tables->guid = ACPI_TABLE_GUID;
+	efi_tables->table = __fwtab_pa(base_nasid, acpi_rsdp);
+	efi_tables++;
+#endif
+	efi_tables->guid = ACPI_20_TABLE_GUID;
+	efi_tables->table = __fwtab_pa(base_nasid, acpi20_rsdp);
+	efi_tables++;
+
+	fix_function_pointer(&efi_unimplemented);
+	fix_function_pointer(&efi_get_time);
+	fix_function_pointer(&efi_success);
+	fix_function_pointer(&efi_reset_system);
+	fix_function_pointer(&efi_set_virtual_address_map);
+
+#ifdef ACPI_1_0
+	/* fill in the ACPI system table - has a pointer to the ACPI table header */
+	memcpy(acpi_rsdp->signature, "RSD PTR ", 8);
+	acpi_rsdp->rsdt = (struct acpi_rsdt*)__fwtab_pa(base_nasid, acpi_rsdt);
+
+	acpi_table_init(&acpi_rsdt->header, ACPI_RSDT_SIG, ACPI_RSDT_SIG_LEN, 1, 1);
+	acpi_rsdt->header.length = sizeof(acpi_rsdt_t);
+	acpi_rsdt->entry_ptrs[0] = __fwtab_pa(base_nasid, acpi_sapic);
+
+	memcpy(acpi_sapic->header.signature, "SPIC ", 4);
+	acpi_sapic->header.length = sizeof(acpi_sapic_t)+num_cpus*sizeof(acpi_entry_lsapic_t);
+
+	for (cnode=0; cnode<num_nodes; cnode++) {
+		nasid = GetNasid(cnode);
+		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
+			if (!IsCpuPresent(cnode, cpu))
+				continue;
+			acpi_lsapic->type = ACPI_ENTRY_LOCAL_SAPIC;
+			acpi_lsapic->length = sizeof(acpi_entry_lsapic_t);
+			acpi_lsapic->acpi_processor_id = cnode*4+cpu;
+			acpi_lsapic->flags = LSAPIC_ENABLED|LSAPIC_PRESENT;
+#if defined(CONFIG_IA64_SGI_SN1)
+			acpi_lsapic->eid = cpu;
+			acpi_lsapic->id = nasid;
+#else
+			acpi_lsapic->eid = nasid&0xffff;
+			acpi_lsapic->id = (cpu<<4) | (nasid>>16);
+#endif
+			acpi_lsapic++;
+		}
+	}
+#endif
+
+
+	/* fill in the ACPI20 system table - has a pointer to the ACPI table header */
+	memcpy(acpi20_rsdp->signature, "RSD PTR ", 8);
+	acpi20_rsdp->xsdt = (struct acpi_xsdt*)__fwtab_pa(base_nasid, acpi_xsdt);
+	acpi20_rsdp->revision = 2;
+	acpi_checksum_rsdp20(acpi20_rsdp, sizeof(acpi20_rsdp_t));
+
+	/* Set up the XSDT table  - contains pointers to the other ACPI tables */
+	acpi_table_init(&acpi_xsdt->header, ACPI_XSDT_SIG, ACPI_XSDT_SIG_LEN, 1, 1);
+	acpi_xsdt->entry_ptrs[0] = __fwtab_pa(base_nasid, acpi_madt);
+	acpi_xsdt->entry_ptrs[1] = __fwtab_pa(base_nasid, acpi_slit);
+	acpi_xsdt->entry_ptrs[2] = __fwtab_pa(base_nasid, acpi_srat);
+	acpi_checksum(&acpi_xsdt->header, sizeof(acpi_xsdt_t) + 16);
+
+	/* Set up the MADT table */
+	acpi_table_init(&acpi_madt->header, ACPI_MADT_SIG, ACPI_MADT_SIG_LEN, 1, 1);
+	lsapic20 = (acpi20_entry_lsapic_t*) (acpi_madt + 1);
+	for (cnode=0; cnode<num_nodes; cnode++) {
+		nasid = GetNasid(cnode);
+		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
+			if (!IsCpuPresent(cnode, cpu))
+				continue;
+			lsapic20->type = ACPI20_ENTRY_LOCAL_SAPIC;
+			lsapic20->length = sizeof(acpi_entry_lsapic_t);
+			lsapic20->acpi_processor_id = cnode*4+cpu;
+			lsapic20->flags = LSAPIC_ENABLED|LSAPIC_PRESENT;
+#if defined(CONFIG_IA64_SGI_SN1)
+			lsapic20->eid = cpu;
+			lsapic20->id = nasid;
+#else
+			lsapic20->eid = nasid&0xffff;
+			lsapic20->id = (cpu<<4) | (nasid>>16);
+#endif
+			lsapic20 = (acpi20_entry_lsapic_t*) ((long)lsapic20+sizeof(acpi_entry_lsapic_t));
+		}
+	}
+	acpi_checksum(&acpi_madt->header, (char*)lsapic20 - (char*)acpi_madt);
+
+	/* Set up the SRAT table */
+	acpi_table_init(&acpi_srat->header, ACPI_SRAT_SIG, ACPI_SRAT_SIG_LEN, ACPI_SRAT_REVISION, 1);
+	ptr = acpi_srat+1;
+	for (cnode=0; cnode<num_nodes; cnode++) {
+		nasid = GetNasid(cnode);
+		srat_memory_affinity = ptr;
+		ptr = srat_memory_affinity+1;
+		srat_memory_affinity->type = SRAT_MEMORY_STRUCTURE;
+		srat_memory_affinity->length = sizeof(srat_memory_affinity_t);
+		srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
+		srat_memory_affinity->base_addr_lo = 0;
+		srat_memory_affinity->length_lo = 0;
+#if defined(CONFIG_IA64_SGI_SN1)
+		srat_memory_affinity->base_addr_hi = nasid<<1;
+		srat_memory_affinity->length_hi = SN1_NODE_SIZE>>32;
+#else
+		srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4);
+		srat_memory_affinity->length_hi = SN2_NODE_SIZE>>32;
+#endif
+		srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
+		srat_memory_affinity->flags = SRAT_MEMORY_FLAGS_ENABLED;
+	}
+
+	for (cnode=0; cnode<num_nodes; cnode++) {
+		nasid = GetNasid(cnode);
+		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
+			if (!IsCpuPresent(cnode, cpu))
+				continue;
+			srat_cpu_affinity = ptr;
+			ptr = srat_cpu_affinity + 1;
+			srat_cpu_affinity->type = SRAT_CPU_STRUCTURE;
+			srat_cpu_affinity->length = sizeof(srat_cpu_affinity_t);
+			srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
+			srat_cpu_affinity->flags = SRAT_CPU_FLAGS_ENABLED;
+#if defined(CONFIG_IA64_SGI_SN1)
+			srat_cpu_affinity->apic_id = nasid;
+			srat_cpu_affinity->local_sapic_eid = cpu;
+#else
+			srat_cpu_affinity->local_sapic_eid = nasid&0xffff;
+			srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);
+#endif
+		}
+	}
+	acpi_checksum(&acpi_srat->header, (char*)ptr - (char*)acpi_srat);
+
+
+	/* Set up the SLIT table */
+	acpi_table_init(&acpi_slit->header, ACPI_SLIT_SIG, ACPI_SLIT_SIG_LEN, ACPI_SLIT_REVISION, 1);
+	acpi_slit->localities = PROXIMITY_DOMAIN(max_nasid)+1;
+	cp=acpi_slit->entries;
+	memset(cp, 255, acpi_slit->localities*acpi_slit->localities);
+
+	for (i=0; i<=max_nasid; i++)
+		for (j=0; j<=max_nasid; j++)
+			if (nasid_present(i) && nasid_present(j))
+				*(cp+PROXIMITY_DOMAIN(i)*acpi_slit->localities+PROXIMITY_DOMAIN(j)) = 10 + MIN(254, 5*ABS(i-j));
+
+	cp = acpi_slit->entries + acpi_slit->localities*acpi_slit->localities;
+	acpi_checksum(&acpi_slit->header, cp - (char*)acpi_slit);
+
+
+	/* fill in the SAL system table: */
+	memcpy(sal_systab->signature, "SST_", 4);
+	sal_systab->size = sizeof(*sal_systab);
+	sal_systab->sal_rev_minor = 1;
+	sal_systab->sal_rev_major = 0;
+	sal_systab->entry_count = 3;
+
+	strcpy(sal_systab->oem_id, "SGI");
+	strcpy(sal_systab->product_id, "SN1");
+
+	/* fill in an entry point: */	
+	sal_ed->type = SAL_DESC_ENTRY_POINT;
+	sal_ed->pal_proc = __fwtab_pa(base_nasid, pal_desc[0]);
+	sal_ed->sal_proc = __fwtab_pa(base_nasid, sal_desc[0]);
+	sal_ed->gp = __fwtab_pa(base_nasid, sal_desc[1]);
+
+	/* kludge the PTC domain info */
+	sal_ptc->type = SAL_DESC_PTC;
+	sal_ptc->num_domains = 0;
+	sal_ptc->domain_info = __fwtab_pa(base_nasid, sal_ptcdi);
+	cpus_found = 0;
+	last_domain = -1;
+	sal_ptcdi--;
+	for (cnode=0; cnode<num_nodes; cnode++) {
+		nasid = GetNasid(cnode);
+		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
+			if (IsCpuPresent(cnode, cpu)) {
+				domain = cnode*CPUS_PER_NODE + cpu/CPUS_PER_FSB;
+				if (domain != last_domain) {
+					sal_ptc->num_domains++;
+					sal_ptcdi++;
+					sal_ptcdi->proc_count = 0;
+					sal_ptcdi->proc_list = __fwtab_pa(base_nasid, sal_ptclid);
+					last_domain = domain;
+				}
+				sal_ptcdi->proc_count++;
+				sal_ptclid->id = nasid;
+				sal_ptclid->eid = cpu;
+				sal_ptclid++;
+				cpus_found++;
+			}
+		}
+	}
+
+	if (cpus_found != num_cpus)
+		FPROM_BUG();
+
+	/* Make the AP WAKEUP entry */
+	sal_apwake->type = SAL_DESC_AP_WAKEUP;
+	sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT;
+	sal_apwake->vector = 18;
+
+	for (checksum=0, cp=(char*)sal_systab; cp < (char *)efi_memmap; ++cp)
+		checksum += *cp;
+	sal_systab->checksum = -checksum;
+
+	/* If the checksum is correct, the kernel tries to use the
+	 * table. We dont build enough table & the kernel aborts.
+	 * Note that the PROM hasd thhhe same problem!!
+	 */
+#ifdef DOESNT_WORK
+	for (checksum=0, cp=(char*)acpi_rsdp, cpe=cp+RSDP_CHECKSUM_LENGTH; cp<cpe; ++cp)
+		checksum += *cp;
+	acpi_rsdp->checksum = -checksum;
+#endif
+
+	md = &efi_memmap[0];
+	num_memmd = build_efi_memmap((void *)md, mdsize) ;
+
+	bp = (struct ia64_boot_param*) __fwtab_pa(base_nasid, BOOT_PARAM_ADDR);
+	bp->efi_systab = __fwtab_pa(base_nasid, &fw_mem);
+	bp->efi_memmap = __fwtab_pa(base_nasid, efi_memmap);
+	bp->efi_memmap_size = num_memmd*mdsize;
+	bp->efi_memdesc_size = mdsize;
+	bp->efi_memdesc_version = 0x101;
+	bp->command_line = __fwtab_pa(base_nasid, cmd_line);
+	bp->console_info.num_cols = 80;
+	bp->console_info.num_rows = 25;
+	bp->console_info.orig_x = 0;
+	bp->console_info.orig_y = 24;
+	bp->fpswa = 0;
+
+	/*
+	 * Now pick the BSP & store it LID value in
+	 * a global variable. Note if BSP is greater than last cpu,
+	 * pick the last cpu.
+	 */
+	for (cnode=0; cnode<num_nodes; cnode++) {
+		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
+			if (!IsCpuPresent(cnode, cpu))
+				continue;
+#ifdef CONFIG_IA64_SGI_SN1
+			bsp_lid = (GetNasid(cnode)<<24) | (cpu<<16);
+#else
+			bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);
+#endif
+			if (bsp-- > 0)
+				continue;
+			return;
+		}
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/klgraph_init.c linux/arch/ia64/sn/fakeprom/klgraph_init.c
--- linux.orig/arch/ia64/sn/fakeprom/klgraph_init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/klgraph_init.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,287 @@
+/* $Id: klgraph_init.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+
+/*
+ * This is a temporary file that statically initializes the expected 
+ * initial klgraph information that is normally provided by prom.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/xtalk/xtalkaddrs.h>
+#include <asm/sn/klconfig.h>
+
+#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
+#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
+#define HUBREG                  ((char *)0xc0000a0001e00000)
+#define WIDGET0                 ((char *)0xc0000a0000000000)
+#define WIDGET4                 ((char *)0xc0000a0000000004)
+
+#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
+#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
+#define HUBREG                  ((char *)0xc0000a0001e00000)
+#define WIDGET0                 ((char *)0xc0000a0000000000)
+
+#define convert(a,b,c) temp = (u64 *)a; *temp = b; temp++; *temp = c
+void
+klgraph_init(void)
+{
+
+	u64	*temp;
+
+	/*
+	 * Initialize some hub/xbow registers that allows access to 
+	 * Xbridge etc.  These are normally done in PROM.
+	 */
+
+        /* Write IOERR clear to clear the CRAZY bit in the status */
+#ifdef CONFIG_IA64_SGI_SN1
+        *(volatile uint64_t *)0xc0000a0001c001f8 = (uint64_t)0xffffffff;
+
+        /* set widget control register...setting bedrock widget id to b */
+        *(volatile uint64_t *)0xc0000a0001c00020 = (uint64_t)0x801b;
+
+        /* set io outbound widget access...allow all */
+        *(volatile uint64_t *)0xc0000a0001c00110 = (uint64_t)0xff01;
+
+        /* set io inbound widget access...allow all */
+        *(volatile uint64_t *)0xc0000a0001c00118 = (uint64_t)0xff01;
+
+        /* set io crb timeout to max */
+        *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff;
+        *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff;
+
+        /* set local block io permission...allow all */
+        *(volatile uint64_t *)0xc0000a0001e04010 = (uint64_t)0xfffffffffffffff;
+
+        /* clear any errors */
+        /* clear_ii_error(); medusa should have cleared these */
+
+        /* set default read response buffers in bridge */
+        *(volatile u32 *)0xc0000a000f000280L = 0xba98;
+        *(volatile u32 *)0xc0000a000f000288L = 0xba98;
+#elif CONFIG_IA64_SGI_SN2
+        *(volatile uint64_t *)0xc000000801c001f8 = (uint64_t)0xffffffff;
+
+        /* set widget control register...setting bedrock widget id to a */
+        *(volatile uint64_t *)0xc000000801c00020 = (uint64_t)0x801a;
+
+        /* set io outbound widget access...allow all */
+        *(volatile uint64_t *)0xc000000801c00110 = (uint64_t)0xff01;
+
+        /* set io inbound widget access...allow all */
+        *(volatile uint64_t *)0xc000000801c00118 = (uint64_t)0xff01;
+
+        /* set io crb timeout to max */
+        *(volatile uint64_t *)0xc000000801c003c0 = (uint64_t)0xffffff;
+        *(volatile uint64_t *)0xc000000801c003c0 = (uint64_t)0xffffff;
+
+        /* set local block io permission...allow all */
+// [LB]        *(volatile uint64_t *)0xc000000801e04010 = (uint64_t)0xfffffffffffffff;
+
+        /* clear any errors */
+        /* clear_ii_error(); medusa should have cleared these */
+
+        /* set default read response buffers in bridge */
+// [PI]       *(volatile u32 *)0xc00000080f000280L = 0xba98;
+// [PI]       *(volatile u32 *)0xc00000080f000288L = 0xba98;
+#endif	/* CONFIG_IA64_SGI_SN1 */
+
+	/*
+	 * kldir entries initialization - mankato
+	 */
+	convert(0x8000000000002000, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002010, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002020, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002030, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002040, 0x434d5f53505f5357, 0x0000000000030000);
+	convert(0x8000000000002050, 0x0000000000000000, 0x0000000000010000);
+	convert(0x8000000000002060, 0x0000000000000001, 0x0000000000000000);
+	convert(0x8000000000002070, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002080, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002090, 0x0000000000000000, 0x0000000000000000);
+	convert(0x80000000000020a0, 0x0000000000000000, 0x0000000000000000);
+	convert(0x80000000000020b0, 0x0000000000000000, 0x0000000000000000);
+	convert(0x80000000000020c0, 0x434d5f53505f5357, 0x0000000000000000);
+	convert(0x80000000000020d0, 0x0000000000002400, 0x0000000000000400);
+	convert(0x80000000000020e0, 0x0000000000000001, 0x0000000000000000);
+	convert(0x80000000000020f0, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002100, 0x434d5f53505f5357, 0x0000000000040000);
+	convert(0x8000000000002110, 0x0000000000000000, 0xffffffffffffffff);
+	convert(0x8000000000002120, 0x0000000000000001, 0x0000000000000000);
+	convert(0x8000000000002130, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002140, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002150, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002160, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002170, 0x0000000000000000, 0x0000000000000000);
+	convert(0x8000000000002180, 0x434d5f53505f5357, 0x0000000000020000);
+	convert(0x8000000000002190, 0x0000000000000000, 0x0000000000010000);
+	convert(0x80000000000021a0, 0x0000000000000001, 0x0000000000000000); 
+
+	/*
+	 * klconfig entries initialization - mankato
+	 */
+	convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000);
+	convert(0x0000000000030010, 0x0003007000000018, 0x800002000f820178);
+	convert(0x0000000000030020, 0x80000a000f024000, 0x800002000f800000);
+	convert(0x0000000000030030, 0x0300fafa00012580, 0x00000000040f0000);
+	convert(0x0000000000030040, 0x0000000000000000, 0x0003097000030070);
+	convert(0x0000000000030050, 0x00030970000303b0, 0x0003181000033f70);
+	convert(0x0000000000030060, 0x0003d51000037570, 0x0000000000038330);
+	convert(0x0000000000030070, 0x0203110100030140, 0x0001000000000101);
+	convert(0x0000000000030080, 0x0900000000000000, 0x000000004e465e67);
+	convert(0x0000000000030090, 0x0003097000000000, 0x00030b1000030a40);
+	convert(0x00000000000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
+	convert(0x00000000000300b0, 0x0003174000031670, 0x0000000000000000);
+	convert(0x0000000000030100, 0x000000000000001a, 0x3350490000000000);
+	convert(0x0000000000030110, 0x0000000000000037, 0x0000000000000000);
+	convert(0x0000000000030140, 0x0002420100030210, 0x0001000000000101);
+	convert(0x0000000000030150, 0x0100000000000000, 0xffffffffffffffff);
+	convert(0x0000000000030160, 0x00030d8000000000, 0x0000000000030e50);
+	convert(0x00000000000301c0, 0x0000000000000000, 0x0000000000030070);
+	convert(0x00000000000301d0, 0x0000000000000025, 0x424f490000000000);
+	convert(0x00000000000301e0, 0x000000004b434952, 0x0000000000000000);
+	convert(0x0000000000030210, 0x00027101000302e0, 0x00010000000e4101);
+	convert(0x0000000000030220, 0x0200000000000000, 0xffffffffffffffff);
+	convert(0x0000000000030230, 0x00030f2000000000, 0x0000000000030ff0);
+	convert(0x0000000000030290, 0x0000000000000000, 0x0000000000030140);
+	convert(0x00000000000302a0, 0x0000000000000026, 0x7262490000000000);
+	convert(0x00000000000302b0, 0x00000000006b6369, 0x0000000000000000);
+	convert(0x00000000000302e0, 0x0002710100000000, 0x00010000000f3101);
+	convert(0x00000000000302f0, 0x0500000000000000, 0xffffffffffffffff);
+	convert(0x0000000000030300, 0x000310c000000000, 0x0003126000031190);
+	convert(0x0000000000030310, 0x0003140000031330, 0x0000000000000000);
+	convert(0x0000000000030360, 0x0000000000000000, 0x0000000000030140);
+	convert(0x0000000000030370, 0x0000000000000029, 0x7262490000000000);
+	convert(0x0000000000030380, 0x00000000006b6369, 0x0000000000000000);
+	convert(0x0000000000030970, 0x0000000002010102, 0x0000000000000000);
+	convert(0x0000000000030980, 0x000000004e465e67, 0xffffffff00000000);
+	/* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
+	convert(0x00000000000309a0, 0x0000000000037570, 0xffffffff00000000);
+	convert(0x00000000000309b0, 0x0000000000030070, 0x0000000000000000);
+	convert(0x00000000000309c0, 0x000000000003f420, 0x0000000000000000);
+	convert(0x0000000000030a40, 0x0000000002010125, 0x0000000000000000);
+	convert(0x0000000000030a50, 0xffffffffffffffff, 0xffffffff00000000);
+	convert(0x0000000000030a70, 0x0000000000037b78, 0x0000000000000000);
+	convert(0x0000000000030b10, 0x0000000002010125, 0x0000000000000000);
+	convert(0x0000000000030b20, 0xffffffffffffffff, 0xffffffff00000000);
+	convert(0x0000000000030b40, 0x0000000000037d30, 0x0000000000000001);
+	convert(0x0000000000030be0, 0x00000000ff010203, 0x0000000000000000);
+	convert(0x0000000000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
+	convert(0x0000000000030c10, 0x0000000000037ee8, 0x0100010000000200);
+	convert(0x0000000000030cb0, 0x00000000ff310111, 0x0000000000000000);
+	convert(0x0000000000030cc0, 0xffffffffffffffff, 0x0000000000000000);
+	convert(0x0000000000030d80, 0x0000000002010104, 0x0000000000000000);
+	convert(0x0000000000030d90, 0xffffffffffffffff, 0x00000000000000ff);
+	convert(0x0000000000030db0, 0x0000000000037f18, 0x0000000000000000);
+	convert(0x0000000000030dc0, 0x0000000000000000, 0x0003007000060000);
+	convert(0x0000000000030de0, 0x0000000000000000, 0x0003021000050000);
+	convert(0x0000000000030df0, 0x000302e000050000, 0x0000000000000000);
+	convert(0x0000000000030e30, 0x0000000000000000, 0x000000000000000a);
+	convert(0x0000000000030e50, 0x00000000ff00011a, 0x0000000000000000);
+	convert(0x0000000000030e60, 0xffffffffffffffff, 0x0000000000000000);
+	convert(0x0000000000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
+	convert(0x0000000000030e90, 0x000000000000bc6e, 0x0000000000000000);
+	convert(0x0000000000030f20, 0x0000000002010205, 0x00000000d0020000);
+	convert(0x0000000000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
+	convert(0x0000000000030f40, 0x000000000000000e, 0x0000000000000000);
+	convert(0x0000000000030f50, 0x0000000000038010, 0x00000000000007ff);
+	convert(0x0000000000030f70, 0x0000000000000000, 0x0000000022001077);
+	convert(0x0000000000030fa0, 0x0000000000000000, 0x000000000003f4a8);
+	convert(0x0000000000030ff0, 0x0000000000310120, 0x0000000000000000);
+	convert(0x0000000000031000, 0xffffffffffffffff, 0xffffffff00000002);
+	convert(0x0000000000031010, 0x000000000000000e, 0x0000000000000000);
+	convert(0x0000000000031020, 0x0000000000038088, 0x0000000000000000);
+	convert(0x00000000000310c0, 0x0000000002010205, 0x00000000d0020000);
+	convert(0x00000000000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
+	convert(0x00000000000310e0, 0x000000000000000f, 0x0000000000000000);
+	convert(0x00000000000310f0, 0x00000000000380b8, 0x00000000000007ff);
+	convert(0x0000000000031120, 0x0000000022001077, 0x00000000000310a9);
+	convert(0x0000000000031130, 0x00000000580211c1, 0x000000008009104c);
+	convert(0x0000000000031140, 0x0000000000000000, 0x000000000003f4c0);
+	convert(0x0000000000031190, 0x0000000000310120, 0x0000000000000000);
+	convert(0x00000000000311a0, 0xffffffffffffffff, 0xffffffff00000003);
+	convert(0x00000000000311b0, 0x000000000000000f, 0x0000000000000000);
+	convert(0x00000000000311c0, 0x0000000000038130, 0x0000000000000000);
+	convert(0x0000000000031260, 0x0000000000110106, 0x0000000000000000);
+	convert(0x0000000000031270, 0xffffffffffffffff, 0xffffffff00000004);
+	convert(0x0000000000031280, 0x000000000000000f, 0x0000000000000000);
+	convert(0x00000000000312a0, 0x00000000ff110013, 0x0000000000000000);
+	convert(0x00000000000312b0, 0xffffffffffffffff, 0xffffffff00000000);
+	convert(0x00000000000312c0, 0x000000000000000f, 0x0000000000000000);
+	convert(0x00000000000312e0, 0x0000000000110012, 0x0000000000000000);
+	convert(0x00000000000312f0, 0xffffffffffffffff, 0xffffffff00000000);
+	convert(0x0000000000031300, 0x000000000000000f, 0x0000000000000000);
+	convert(0x0000000000031310, 0x0000000000038160, 0x0000000000000000);
+	convert(0x0000000000031330, 0x00000000ff310122, 0x0000000000000000);
+	convert(0x0000000000031340, 0xffffffffffffffff, 0xffffffff00000005);
+	convert(0x0000000000031350, 0x000000000000000f, 0x0000000000000000);
+	convert(0x0000000000031360, 0x0000000000038190, 0x0000000000000000);
+	convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000);
+	convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000);
+	convert(0x0000000000031410, 0xffffffffffffffff, 0xffffffff00000006);
+	convert(0x0000000000031420, 0x000000000000000f, 0x0000000000000000);
+	convert(0x0000000000031430, 0x00000000000381c0, 0x0000000000000000);
+	convert(0x00000000000314d0, 0x00000000ff010201, 0x0000000000000000);
+	convert(0x00000000000314e0, 0xffffffffffffffff, 0xffffffff00000000);
+	convert(0x0000000000031500, 0x00000000000381f0, 0x000030430000ffff);
+	convert(0x0000000000031510, 0x000000000000ffff, 0x0000000000000000);
+	convert(0x00000000000315a0, 0x00000020ff000201, 0x0000000000000000);
+	convert(0x00000000000315b0, 0xffffffffffffffff, 0xffffffff00000001);
+	convert(0x00000000000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
+	convert(0x00000000000315e0, 0x000000000000ffff, 0x0000000000000000);
+	convert(0x0000000000031670, 0x00000000ff010201, 0x0000000000000000);
+	convert(0x0000000000031680, 0xffffffffffffffff, 0x0000000100000002);
+	convert(0x00000000000316a0, 0x0000000000038290, 0x000030430000ffff);
+	convert(0x00000000000316b0, 0x000000000000ffff, 0x0000000000000000);
+	convert(0x0000000000031740, 0x00000020ff000201, 0x0000000000000000);
+	convert(0x0000000000031750, 0xffffffffffffffff, 0x0000000500000003);
+	convert(0x0000000000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
+	convert(0x0000000000031780, 0x000000000000ffff, 0x0000000000000000);
+
+	/*
+	 * GDA initialization - mankato
+	 */
+	convert(0x8000000000002400, 0x0000000258464552, 0x000000000ead0000);
+	convert(0x8000000000002480, 0xffffffff00010000, 0xffffffffffffffff);
+	convert(0x8000000000002490, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x80000000000024a0, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x80000000000024b0, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x80000000000024c0, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x80000000000024d0, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x80000000000024e0, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x80000000000024f0, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002500, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002510, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002520, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002530, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002540, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002550, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002560, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002570, 0xffffffffffffffff, 0xffffffffffffffff);
+	convert(0x8000000000002580, 0x000000000000ffff, 0x0000000000000000);
+	
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/main.c linux/arch/ia64/sn/fakeprom/main.c
--- linux.orig/arch/ia64/sn/fakeprom/main.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/main.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,125 @@
+/* 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/bitops.h>
+
+extern void klgraph_init(void);
+void bedrock_init(int);
+void synergy_init(int, int);
+void sys_fw_init (const char *args, int arglen, int bsp);
+
+volatile int	bootmaster=0;		/* Used to pick bootmaster */
+volatile int	nasidmaster[128]={0};	/* Used to pick node/synergy masters */
+int		init_done=0;
+extern int	bsp_lid;
+
+#define get_bit(b,p)	(((*p)>>(b))&1)
+
+int
+fmain(int lid, int bsp) {
+	int	syn, nasid, cpu;
+
+	/*
+	 * First lets figure out who we are. This is done from the
+	 * LID passed to us.
+	 */
+
+#ifdef CONFIG_IA64_SGI_SN1
+	nasid = (lid>>24);
+	syn = (lid>>17)&1;
+	cpu = (lid>>16)&1;
+
+	/*
+	 * Now pick a synergy master to initialize synergy registers.
+	 */
+	if (test_and_set_bit(syn, &nasidmaster[nasid]) == 0) {
+		synergy_init(nasid, syn);
+		test_and_set_bit(syn+2, &nasidmaster[nasid]);
+	} else
+		while (get_bit(syn+2, &nasidmaster[nasid]) == 0);
+#else
+	nasid = (lid>>16)&0xfff;
+	cpu = (lid>>28)&3;
+	syn = 0;
+#endif
+	
+	/*
+	 * Now pick a nasid master to initialize Bedrock registers.
+	 */
+	if (test_and_set_bit(8, &nasidmaster[nasid]) == 0) {
+		bedrock_init(nasid);
+		test_and_set_bit(9, &nasidmaster[nasid]);
+	} else
+		while (get_bit(9, &nasidmaster[nasid]) == 0);
+	
+
+	/*
+	 * Now pick a BSP & finish init.
+	 */
+	if (test_and_set_bit(0, &bootmaster) == 0) {
+		sys_fw_init(0, 0, bsp);
+		test_and_set_bit(1, &bootmaster);
+	} else
+		while (get_bit(1, &bootmaster) == 0);
+
+	return (lid == bsp_lid);
+}
+
+
+void
+bedrock_init(int nasid)
+{
+	nasid = nasid;		/* to quiet gcc */
+#if 0
+	/*
+	 * Undef if you need fprom to generate a 1 node klgraph
+	 * information .. only works for 1 node for nasid 0.
+	 */
+	klgraph_init();
+#endif
+}
+
+
+void
+synergy_init(int nasid, int syn)
+{
+	long	*base;
+	long	off;
+
+	/*
+	 * Enable all FSB flashed interrupts.
+	 * ZZZ - I'd really like defines for this......
+	 */
+	base = (long*)0x80000e0000000000LL;		/* base of synergy regs */
+	for (off = 0x2a0; off < 0x2e0; off+=8)		/* offset for VEC_MASK_{0-3}_A/B */
+		*(base+off/8) = -1LL;
+
+	/*
+	 * Set the NASID in the FSB_CONFIG register.
+	 */
+	base = (long*)0x80000e0000000450LL;
+	*base = (long)((nasid<<16)|(syn<<9));
+}
+
+
+/* Why isnt there a bcopy/memcpy in lib64.a */
+
+void* 
+memcpy(void * dest, const void *src, size_t count)
+{
+	char *s, *se, *d;
+
+	for(d=dest, s=(char*)src, se=s+count; s<se; s++, d++)
+		*d = *s;
+	return dest;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fakeprom/runsim linux/arch/ia64/sn/fakeprom/runsim
--- linux.orig/arch/ia64/sn/fakeprom/runsim	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/fakeprom/runsim	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,387 @@
+#!/bin/sh
+
+# Script for running PROMs and LINUX kernwls on medusa. 
+# Type "sim -H" for instructions.
+
+MEDUSA=${MEDUSA:-/home/rickc/official_medusa/medusa}
+
+# ------------------ err -----------------------
+err() {
+	echo "ERROR - $1"
+	exit 1
+}
+
+# ----------------  help ----------------------
+help() {
+cat <<END
+Script for running a PROM or LINUX kernel under medusa.
+This script creates a control file, creates links to the appropriate
+linux/prom files, and/or calls medusa to make simulation runs.
+
+Usage:  
+   Initial setup:
+   	sim [-c <config_file>] <-p> | <-k>  [<work_dir>]
+		-p	Create PROM control file & links
+		-k	Create LINUX control file & links
+		-c<cf>	Control file name				[Default: cf]
+		<work_dir> Path to directory that contains the linux or PROM files.
+		    The directory can be any of the following:
+		       (linux simulations)
+		       		worktree
+				worktree/linux
+				any directory with vmlinux, vmlinux.sym & fprom files
+			(prom simulations)
+				worktree
+				worktree/stand/arcs/IP37prom/dev
+				any directory with fw.bin & fw.sim files
+
+    Simulations:
+	sim  [-X <n>] [-o <output>] [-M] [<config_file>]
+		-c<cf>	Control file name				[Default: cf]
+		-M	Pipe output thru fmtmedusa
+		-o	Output filename (copy of all commands/output)	[Default: simout]
+		-X	Specifies number of instructions to execute	[Default: 0]
+			(Used only in auto test mode - not described here)
+
+Examples:
+	sim -p <promtree>	# create control file (cf) & links for prom simulations
+	sim -k <linuxtree>	# create control file (cf) & links for linux simulations
+	sim -p -c cfprom	# create a prom control file (cfprom) only. No links are made.
+
+	sim			# run medusa using previously created links &
+				#   control file (cf).
+END
+exit 1
+}
+
+# ----------------------- create control file header --------------------
+create_cf_header() {
+cat <<END >>$CF
+#
+# Template for a control file for running linux kernels under medusa. 
+# You probably want to make mods here but this is a good starting point.
+#
+
+# Preferences
+setenv cpu_stepping A
+setenv exceptionPrint off
+setenv interrupt_messages off
+setenv lastPCsize 100000
+setenv low_power_mode on
+setenv partialIntelChipSet on
+setenv printIntelMessages off
+setenv prom_write_action halt
+setenv prom_write_messages on
+setenv step_quantum 100
+setenv swizzling on
+setenv tsconsole on
+setenv uart_echo on
+symbols on
+
+# IDE disk params
+setenv diskCylinders 611
+setenv bootDrive C
+setenv diskHeads 16
+setenv diskPath idedisk
+setenv diskPresent 1
+setenv diskSpt 63
+
+# Hardware config
+setenv coherency_type nasid
+setenv cpu_cache_type default
+setenv synergy_cache_type syn_cac_64m_8w
+setenv l4_uc_snoop off
+
+# Numalink config
+setenv route_enable on
+setenv network_type router		# Select [xbar|router]
+setenv network_warning 0xff
+
+END
+}
+
+
+# ------------------ create control file entries for linux simulations -------------
+create_cf_linux() {
+cat <<END >>$CF
+# Kernel specific options
+setenv calias_size 0
+setenv mca_on_memory_failure off
+setenv LOADPC 0x00100000		# FPROM load address/entry point (8 digits!)
+setenv symbol_table vmlinux.sym
+load fprom
+load vmlinux
+
+# Useful breakpoints to always have set. Add more if desired.
+break 0xe000000000505e00	all	# dispatch_to_fault_handler
+break panic			all	# stop on panic
+break die_if_kernel		all	# may as well stop
+
+END
+}
+
+# ------------------ create control file entries for prom simulations ---------------
+create_cf_prom() {
+	SYM2=""
+	ADDR="0x80000000ff800000"
+	[ "$EMBEDDED_LINUX" != "0" ] || SYM2="setenv symbol_table2 vmlinux.sym"
+	[ "$SIZE" = "8MB" ] || ADDR="0x80000000ffc00000"
+	cat <<END >>$CF
+# PROM specific options
+setenv mca_on_memory_failure on
+setenv LOADPC 0x80000000ffffffb0
+setenv promFile fw.bin
+setenv promAddr $ADDR
+setenv symbol_table fw.sym
+$SYM2
+
+# Useful breakpoints to always have set. Add more if desired.
+break ivt_gexx 		all
+break ivt_brk		all
+break PROM_Panic_Spin	all
+break PROM_Panic	all
+break PROM_C_Panic	all
+break fled_die		all
+break ResetNow		all
+break zzzbkpt		all
+
+END
+}
+
+
+# ------------------ create control file entries for memory configuration -------------
+create_cf_memory() {
+cat <<END >>$CF
+# CPU/Memory map format:
+#	setenv nodeN_memory_config 0xBSBSBSBS
+#		B=banksize (0=unused, 1=64M, 2=128M, .., 5-1G, c=8M, d=16M, e=32M)
+#		S=bank enable (0=both disable, 3=both enable, 2=bank1 enable, 1=bank0 enable)
+#		  rightmost digits are for bank 0, the lowest address.
+#	setenv nodeN_nasid <nasid>
+#		specifies the NASID for the node. This is used ONLY if booting the kernel.
+#		On PROM configurations, set to 0 - PROM will change it later.
+#	setenv nodeN_cpu_config <cpu_mask>
+#		Set bit number N to 1 to enable cpu N. Ex., a value of 5 enables cpu 0 & 2.
+#
+# Repeat the above 3 commands for each node.
+#
+# For kernel, default to 32MB. Although this is not a valid hardware configuration,
+# it runs faster on medusa. For PROM, 64MB is smallest allowed value.
+
+setenv node0_cpu_config		0x1	# Enable only cpu 0 on the node
+END
+
+if [ $LINUX -eq 1 ] ; then
+cat <<END >>$CF
+setenv node0_nasid		0	# cnode 0 has NASID 0
+setenv node0_memory_config 	0xe1	# 32MB
+END
+else
+cat <<END >>$CF
+setenv node0_memory_config 	0x31	# 256MB
+END
+fi
+}
+
+# -------------------- set links to linux files -------------------------
+set_linux_links() {
+	if [ -d $D/linux/arch ] ; then
+		D=$D/linux
+	elif [ -d $D/arch -o -e vmlinux.sym -o -e $D/vmlinux ] ; then
+		D=$D
+	else
+		err "cant determine directory for linux binaries"
+	fi
+	rm -rf vmlinux vmlinux.sym fprom
+	ln -s $D/vmlinux vmlinux
+	if [ -f $D/vmlinux.sym ] ; then
+		ln -s $D/vmlinux.sym vmlinux.sym
+	elif  [ -f $D/System.map ] ; then
+		ln -s $D/System.map vmlinux.sym
+	fi
+	if [ -d $D/arch ] ; then
+		ln -s $D/arch/ia64/sn/fprom/fprom fprom
+	else
+		ln -s $D/fprom fprom
+	fi
+	echo "  .. Created links to linux files"	
+}
+
+# -------------------- set links to prom files -------------------------
+set_prom_links() {
+	if [ -d $D/stand ] ; then
+		D=$D/stand/arcs/IP37prom/dev
+	elif [ -d $D/sal ] ; then
+		D=$D
+	else
+		err "cant determine directory for PROM binaries"
+	fi
+	SETUP="/tmp/tmp.$$"
+	rm -r -f $SETUP
+	sed 's/export/setenv/' < $D/../../../../.setup | sed 's/=/ /' >$SETUP
+	egrep -q '^ *setenv *PROMSIZE *8MB|^ *export' $SETUP
+	if [ $? -eq 0 ] ; then
+		SIZE="8MB"
+	else
+		SIZE="4MB"
+	fi
+	grep -q '^ *setenv *LAUNCH_VMLINUX' $SETUP
+	EMBEDDED_LINUX=$?
+	PRODUCT=`grep '^ *setenv *PRODUCT' $SETUP | cut -d" " -f3`
+	rm -f fw.bin fw.map fw.sym vmlinux vmlinux.sym fprom $SETUP
+	SDIR="${PRODUCT}${SIZE}.O"
+	BIN="${PRODUCT}ip37prom${SIZE}"
+	ln -s $D/$SDIR/$BIN.bin fw.bin
+	ln -s $D/$SDIR/$BIN.map fw.map
+	ln -s $D/$SDIR/$BIN.sym fw.sym
+	echo "  .. Created links to $SIZE prom files"
+	if [ $EMBEDDED_LINUX -eq 0 ] ; then
+		ln -s $D/linux/vmlinux vmlinux
+		ln -s $D/linux/vmlinux.sym vmlinux.sym
+		if [ -d linux/arch ] ; then
+			ln -s $D/linux/arch/ia64/sn/fprom/fprom fprom
+		else
+			ln -s $D/linux/fprom fprom
+		fi
+		echo "  .. Created links to embedded linux files in prom tree"
+	fi
+}
+
+# --------------- start of shell script --------------------------------
+OUT="simout"
+FMTMED=0
+STEPCNT=0
+PROM=0
+LINUX=0
+NCF="cf"
+while getopts "HMX:c:o:pk" c ; do
+        case ${c} in
+                H) help;;
+		M) FMTMED=1;;
+		X) STEPCNT=${OPTARG};;
+		c) NCF=${OPTARG};;
+		k) PROM=0;LINUX=1;;
+		p) PROM=1;LINUX=0;;
+		o) OUT=${OPTARG};;
+                \?) exit 1;;
+        esac
+done
+shift `expr ${OPTIND} - 1`
+
+# Check if command is for creating control file and/or links to images.
+if [ $PROM -eq 1 -o $LINUX -eq 1 ] ; then
+	CF=$NCF
+	[ ! -f $CF ] || err "wont overwrite an existing control file ($CF)"
+	if [ $# -gt 0 ] ; then
+		D=$1
+		[ -d $D ] || err "cannot find directory $D"
+		[ $PROM -eq 0 ]  || set_prom_links
+		[ $LINUX -eq 0 ] || set_linux_links
+	fi
+	create_cf_header
+	[ $PROM -eq 0 ]  || create_cf_prom
+	[ $LINUX -eq 0 ] || create_cf_linux
+	[ ! -f ../idedisk ] || ln -s ../idedisk .
+	create_cf_memory
+	echo "  .. Basic control file created (in $CF). You might want to edit"
+	echo "     this file (at least, look at it)."
+	exit 0
+fi
+
+# Verify that the control file exists
+CF=${1:-$NCF}
+[ -f $CF ] || err "No control file exists. For help, type: $0 -H"
+
+# Build the .cf files from the user control file. The .cf file is
+# identical except that the actual start & load addresses are inserted
+# into the file. In addition, the FPROM commands for configuring memory
+# and LIDs are generated. 
+
+rm -f .cf .cf1 .cf2
+awk '
+function strtonum(n) {
+	 if (substr(n,1,2) != "0x")
+	 	return int(n)
+	 n = substr(n,3)
+	 r=0
+	 while (length(n) > 0) {
+	 	r = r*16+(index("0123456789abcdef", substr(n,1,1))-1)
+		n = substr(n,2)
+	 }
+	 return r
+	}
+/^#/   	{next}
+/^$/	{next}
+/^setenv *LOADPC/               {loadpc = $3; next}
+/^setenv *node.._cpu_config/	{n=int(substr($2,5,2)); cpuconf[n] = strtonum($3); print; next}
+/^setenv *node.._memory_config/	{n=int(substr($2,5,2)); memconf[n] = strtonum($3); print; next}
+/^setenv *node.._nasid/		{n=int(substr($2,5,2)); nasid[n] = strtonum($3); print; next}
+/^setenv *node._cpu_config/	{n=int(substr($2,5,1)); cpuconf[n] = strtonum($3); print; next}
+/^setenv *node._memory_config/	{n=int(substr($2,5,1)); memconf[n] = strtonum($3); print; next}
+/^setenv *node._nasid/		{n=int(substr($2,5,1)); nasid[n] = strtonum($3); print; next}
+		{print}
+END	{
+	 # Generate the memmap info that starts at the beginning of
+	 # the node the kernel was loaded on.
+	 loadnasid = nasid[0]
+	 cnode = 0
+	 for (i=0; i<128; i++) {
+		if (memconf[i] != "") {
+			printf "sm 0x%x%08x 0x%x%04x%04x\n", 
+				2*loadnasid, 8*cnodes+8, memconf[i], cpuconf[i], nasid[i]
+			cnodes++
+			cpus += substr("0112122312232334", cpuconf[i]+1,1)
+		}
+	 }
+	 printf "sm 0x%x00000000 0x%x%08x\n", 2*loadnasid, cnodes, cpus
+	 printf "setenv number_of_nodes %d\n", cnodes
+
+	 # Now set the starting PC for each cpu.
+	 cnode = 0
+	 lowcpu=-1
+	 for (i=0; i<128; i++) {
+		if (memconf[i] != "") {
+			printf "setnode %d\n", cnode
+			conf = cpuconf[i]
+			for (j=0; j<4; j++) {
+				if (conf != int(conf/2)*2) {
+	 				printf "setcpu %d\n", j
+					if (length(loadpc) == 18)
+						printf "sr pc %s\n", loadpc
+					else
+						printf "sr pc 0x%x%s\n", 2*loadnasid, substr(loadpc,3)
+					if (lowcpu == -1)
+						lowcpu = j
+				}
+				conf = int(conf/2)
+			}
+			cnode++
+		}
+	 }
+	 printf "setnode 0\n"
+	 printf "setcpu %d\n", lowcpu
+	}
+' <$CF >.cf
+
+# Now build the .cf1 & .cf2 control files.
+CF2_LINES="^sm |^break |^run |^si |^quit |^symbols "
+egrep  "$CF2_LINES" .cf >.cf2
+egrep -v "$CF2_LINES" .cf >.cf1
+if [ $STEPCNT -ne 0 ] ; then
+	echo "s $STEPCNT" >>.cf2
+	echo "lastpc 1000" >>.cf2
+	echo "q" >>.cf2
+fi
+if [ -f vmlinux.sym ] ; then
+	awk '/ _start$/ {print "sr g 9 0x" $3}' < vmlinux.sym >> .cf2
+fi
+echo "script-on $OUT" >>.cf2
+
+# Now start medusa....
+if [ $FMTMED -ne 0 ] ; then
+	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 |  fmtmedusa
+elif [ $STEPCNT -eq 0 ] ; then
+	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 
+else
+	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 2>&1 
+fi
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/Makefile linux/arch/ia64/sn/fprom/Makefile
--- linux.orig/arch/ia64/sn/fprom/Makefile	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/ia64/sn/fprom/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,33 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 2000 Silicon Graphics, Inc.
-# Copyright (C) Jack Steiner (steiner@sgi.com)
-#
-
-TOPDIR=../../../..
-HPATH           = $(TOPDIR)/include
-
-LIB     = ../../lib/lib.a
-
-OBJ=fpromasm.o main.o  fw-emu.o fpmem.o
-obj-y=fprom
-
-fprom: $(OBJ)
-	$(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB)
-
-comma	:= ,
-
-.S.o:
-	$(CC)  -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
-.c.o:
-	$(CC)  $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_KERNEL) -c -o $*.o $<
-
-clean:
-	rm -f *.o fprom
-
-
-include $(TOPDIR)/Rules.make
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/README linux/arch/ia64/sn/fprom/README
--- linux.orig/arch/ia64/sn/fprom/README	2001-01-04 21:00:15.000000000 +0000
+++ linux/arch/ia64/sn/fprom/README	1970-01-01 00:00:00.000000000 +0000
@@ -1,85 +0,0 @@
-This directory contains the files required to build
-the fake PROM image that is currently being used to
-boot IA64 kernels running under the SGI Medusa kernel.
-
-The FPROM currently provides the following functions:
-
-	- PAL emulation for all PAL calls we've made so far.
-	- SAL emulation for all SAL calls we've made so far.
-	- EFI emulation for all EFI calls we've made so far.
-	- builds the "ia64_bootparam" structure that is
-	  passed to the kernel from SAL. This structure 
-	  shows the cpu & memory configurations.
-	- supports medusa boottime options for changing
-	  the number of cpus present
-	- supports medusa boottime options for changing
-	  the memory configuration.
-
-
-
-At some point, this fake PROM will be replaced by the
-real PROM.
-
-
-
-
-To build a fake PROM, cd to this directory & type:
-
-	make
-
-This will (or should) build a fake PROM named "fprom".
-
-
-
-
-Use this fprom image when booting the Medusa simulator. The
-control file used to boot Medusa should include the 
-following lines:
-
-	load fprom
-	load vmlinux
-	sr pc 0x100000
-	sr g 9 <address of kernel _start function> #(currently 0xe000000000520000)
-
-NOTE: There is a script "runsim" in this directory that can be used to
-simplify setting up an environment for running under Medusa.
-
-
-
-
-The following parameters may be passed to the fake PROM to
-control the PAL/SAL/EFI parameters passed to the kernel:
-
-	GR[8] = # of cpus
-	GR[9] = address of primary entry point into the kernel
-	GR[20] = memory configuration for node 0
-	GR[21] = memory configuration for node 1
-	GR[22] = memory configuration for node 2
-	GR[23] = memory configuration for node 3
-
-
-Registers GR[20] - GR[23] contain information to specify the
-amount of memory present on nodes 0-3.
-
-  - if nothing is specified (all registers are 0), the configuration
-    defaults to 8 MB on node 0.
-
-  - a mem config entry for node N is passed in GR[20+N]
-
-  - a mem config entry consists of 8 hex digits. Each digit gives the
-    amount of physical memory available on the node starting at
-    1GB*<dn>, where dn is the digit number. The amount of memory
-    is 8MB*2**<d>. (If <d> = 0, the memory size is 0).
-
-    SN1 doesnt support dimms this small but small memory systems 
-    boot faster on Medusa.
-
-
-
-An example helps a lot. The following specifies that node 0 has
-physical memory 0 to 8MB and 1GB to 1GB+32MB, and that node 1 has
-64MB starting at address 0 of the node which is 8GB.
-
-      gr[20] = 0x21           # 0 to 8MB, 1GB to 1GB+32MB
-      gr[21] = 0x4            # 8GB to 8GB+64MB
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/fpmem.c linux/arch/ia64/sn/fprom/fpmem.c
--- linux.orig/arch/ia64/sn/fprom/fpmem.c	2001-01-04 21:00:15.000000000 +0000
+++ linux/arch/ia64/sn/fprom/fpmem.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,200 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
- */
-
-
-/*
- * FPROM EFI memory descriptor build routines
- *
- * 	- Routines to build the EFI memory descriptor map
- * 	- Should also be usable by the SGI SN1 prom to convert
- * 	  klconfig to efi_memmap
- */
-
-#include <asm/efi.h>
-#include "fpmem.h"
-
-/*
- * args points to a layout in memory like this
- *
- *		32 bit		32 bit
- *
- * 		numnodes	numcpus
- *
- *		16 bit   16 bit		   32 bit
- *		nasid0	cpuconf		membankdesc0
- *		nasid1	cpuconf		membankdesc1
- *			   .
- *			   .
- *			   .
- *			   .
- *			   .
- */
-
-sn_memmap_t	*sn_memmap ;
-sn_config_t	*sn_config ;
-
-/*
- * There is a hole in the node 0 address space. Dont put it
- * in the memory map
- */
-#define NODE0_HOLE_SIZE         (20*MB)
-#define NODE0_HOLE_END          (4UL*GB)
-
-#define	MB			(1024*1024)
-#define GB			(1024*MB)
-#define KERNEL_SIZE		(4*MB)
-#define PROMRESERVED_SIZE	(1*MB)
-#define MD_BANK_SHFT 30
-
-#define TO_NODE(_n, _x)		(((long)_n<<33L) | (long)_x)
-
-/*
- * For SN, this may not take an arg and gets the numnodes from 
- * the prom variable or by traversing klcfg or promcfg
- */
-int
-GetNumNodes(void)
-{
-	return sn_config->nodes;
-}
-
-int
-GetNumCpus(void)
-{
-	return sn_config->cpus;
-}
-
-/* For SN1, get the index th nasid */
-
-int
-GetNasid(int index)
-{
-	return sn_memmap[index].nasid ;
-}
-
-node_memmap_t
-GetMemBankInfo(int index)
-{
-	return sn_memmap[index].node_memmap ;
-}
-
-int
-IsCpuPresent(int cnode, int cpu)
-{
-	return  sn_memmap[cnode].cpuconfig & (1<<cpu);
-}
-
-
-/*
- * Made this into an explicit case statement so that
- * we can assign specific properties to banks like bank0
- * actually disabled etc.
- */
-
-int
-IsBankPresent(int index, node_memmap_t nmemmap)
-{
-	switch (index) {
-		case 0:return nmemmap.b0;
-		case 1:return nmemmap.b1;
-		case 2:return nmemmap.b2;
-		case 3:return nmemmap.b3;
-		case 4:return nmemmap.b4;
-		case 5:return nmemmap.b5;
-		case 6:return nmemmap.b6;
-		case 7:return nmemmap.b7;
-		default:return -1 ;
-	}
-}
-
-int
-GetBankSize(int index, node_memmap_t nmemmap)
-{
-        switch (index) {
-                case 0:
-                case 1:return nmemmap.b01size;
-                case 2:
-                case 3:return nmemmap.b23size;
-                case 4:
-                case 5:return nmemmap.b45size;
-                case 6:
-                case 7:return nmemmap.b67size;
-                default:return -1 ;
-        }
-}
-
-void
-build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes)
-{
-        md->type = type;
-        md->phys_addr = paddr;
-        md->virt_addr = 0;
-        md->num_pages = numbytes >> 12;
-        md->attribute = EFI_MEMORY_WB;
-}
-
-int
-build_efi_memmap(void *md, int mdsize)
-{
-	int		numnodes = GetNumNodes() ;
-	int		cnode,bank ;
-	int		nasid ;
-	node_memmap_t	membank_info ;
-	int		bsize;
-	int		count = 0 ;
-	long		paddr, hole, numbytes;
-
-
-	for (cnode=0;cnode<numnodes;cnode++) {
-		nasid = GetNasid(cnode) ;
-		membank_info = GetMemBankInfo(cnode) ;
-		for (bank=0;bank<SN1_MAX_BANK_PER_NODE;bank++) {
-			if (IsBankPresent(bank, membank_info)) {
-				bsize = GetBankSize(bank, membank_info) ;
-                                paddr = TO_NODE(nasid, (long)bank<<MD_BANK_SHFT);
-                                numbytes = BankSizeBytes(bsize);
-
-                                /*
-                                 * Check for the node 0 hole. Since banks cant
-                                 * span the hole, we only need to check if the end of
-                                 * the range is the end of the hole.
-                                 */
-                                if (paddr+numbytes == NODE0_HOLE_END)
-                                        numbytes -= NODE0_HOLE_SIZE;
-                                /*
-                                 * UGLY hack - we must skip overr the kernel and
-                                 * PROM runtime services but we dont exactly where it is.
-                                 * So lets just reserve 0-12MB.
-                                 */
-                                if (bank == 0) {
-					hole = (cnode == 0) ? KERNEL_SIZE : PROMRESERVED_SIZE;
-					numbytes -= hole;
-                                        build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
-                                        paddr += hole;
-			        	count++ ;
-                                        md += mdsize;
-                                }
-                                build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes);
-
-			        md += mdsize ;
-			        count++ ;
-			}
-		}
-	}
-	return count ;
-}
-
-void
-build_init(unsigned long args)
-{
-	sn_config = (sn_config_t *) (args);	
-	sn_memmap = (sn_memmap_t *)(args + 8) ; /* SN equiv for this is */
-						/* init to klconfig start */
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/fpmem.h linux/arch/ia64/sn/fprom/fpmem.h
--- linux.orig/arch/ia64/sn/fprom/fpmem.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/arch/ia64/sn/fprom/fpmem.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,35 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
- */
-
-
-
-#include <asm/sn/mmzone_sn1.h>
-
-typedef struct sn_memmap_s
-{
-	short		nasid ;
-	short		cpuconfig;
-	node_memmap_t 	node_memmap ;
-} sn_memmap_t ;
-
-typedef struct sn_config_s
-{
-	int		cpus;
-	int		nodes;
-	sn_memmap_t	memmap[1];		/* start of array */
-} sn_config_t;
-
-
-extern void build_init(unsigned long);
-extern int build_efi_memmap(void *, int);
-extern int GetNumNodes(void);
-extern int GetNumCpus(void);
-extern int IsCpuPresent(int, int);
-extern int GetNasid(int);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/fprom.lds linux/arch/ia64/sn/fprom/fprom.lds
--- linux.orig/arch/ia64/sn/fprom/fprom.lds	2001-07-02 21:40:14.000000000 +0000
+++ linux/arch/ia64/sn/fprom/fprom.lds	1970-01-01 00:00:00.000000000 +0000
@@ -1,96 +0,0 @@
-
-OUTPUT_FORMAT("elf64-ia64-little")
-OUTPUT_ARCH(ia64)
-ENTRY(_start)
-SECTIONS
-{
-  v = 0x0000000000000000 ;	/* this symbol is here to make debugging with kdb easier... */
-
-  . = (0x000000000000000  + 0x100000) ;
-
-  _text = .;
-  .text : AT(ADDR(.text) - 0x0000000000000000 )
-    {
-	*(__ivt_section)
-	/* these are not really text pages, but the zero page needs to be in a fixed location: */
-	*(__special_page_section)
-	__start_gate_section = .;
-	*(__gate_section)
-	__stop_gate_section = .;
-	*(.text)
-    }
-
-  /* Global data */
-  _data = .;
-
-  .rodata : AT(ADDR(.rodata) - 0x0000000000000000 )
-	{ *(.rodata) *(.rodata.*) }
-  .opd : AT(ADDR(.opd) - 0x0000000000000000 )
-	{ *(.opd) }
-  .data : AT(ADDR(.data) - 0x0000000000000000 )
-	{ *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
-
-  __gp = ALIGN (8) + 0x200000;
-
-  .got : AT(ADDR(.got) - 0x0000000000000000 )
-	{ *(.got.plt) *(.got) }
-  /* We want the small data sections together, so single-instruction offsets
-     can access them all, and initialized data all before uninitialized, so
-     we can shorten the on-disk segment size.  */
-  .sdata : AT(ADDR(.sdata) - 0x0000000000000000 )
-	{ *(.sdata) }
-  _edata  =  .;
-  _bss = .;
-  .sbss : AT(ADDR(.sbss) - 0x0000000000000000 )
-	{ *(.sbss) *(.scommon) }
-  .bss : AT(ADDR(.bss) - 0x0000000000000000 )
-	{ *(.bss) *(COMMON) }
-  . = ALIGN(64 / 8);
-  _end = .;
-
-  /* Sections to be discarded */
-  /DISCARD/ : {
-	*(.text.exit)
-	*(.data.exit)
-	}
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  /* DWARF debug sections.
-     Symbols in the DWARF debugging sections are relative to the beginning
-     of the section so we begin them at 0.  */
-  /* DWARF 1 */
-  .debug          0 : { *(.debug) }
-  .line           0 : { *(.line) }
-  /* GNU DWARF 1 extensions */
-  .debug_srcinfo  0 : { *(.debug_srcinfo) }
-  .debug_sfnames  0 : { *(.debug_sfnames) }
-  /* DWARF 1.1 and DWARF 2 */
-  .debug_aranges  0 : { *(.debug_aranges) }
-  .debug_pubnames 0 : { *(.debug_pubnames) }
-  /* DWARF 2 */
-  .debug_info     0 : { *(.debug_info) }
-  .debug_abbrev   0 : { *(.debug_abbrev) }
-  .debug_line     0 : { *(.debug_line) }
-  .debug_frame    0 : { *(.debug_frame) }
-  .debug_str      0 : { *(.debug_str) }
-  .debug_loc      0 : { *(.debug_loc) }
-  .debug_macinfo  0 : { *(.debug_macinfo) }
-  /* SGI/MIPS DWARF 2 extensions */
-  .debug_weaknames 0 : { *(.debug_weaknames) }
-  .debug_funcnames 0 : { *(.debug_funcnames) }
-  .debug_typenames 0 : { *(.debug_typenames) }
-  .debug_varnames  0 : { *(.debug_varnames) }
-  /* These must appear regardless of  .  */
-  /* Discard them for now since Intel SoftSDV cannot handle them.
-  .comment 0 : { *(.comment) }
-  .note 0 : { *(.note) }
-  */
-  /DISCARD/ : { *(.comment) }
-  /DISCARD/ : { *(.note) }
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/fpromasm.S linux/arch/ia64/sn/fprom/fpromasm.S
--- linux.orig/arch/ia64/sn/fprom/fpromasm.S	2001-01-04 21:00:15.000000000 +0000
+++ linux/arch/ia64/sn/fprom/fpromasm.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,314 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *   (Code copied from or=ther files)
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
- */
-
-
-
-#define __ASSEMBLY__ 1
-#include "asm/processor.h"
-
-/*
- * This file contains additional set up code that is needed to get going on
- * Medusa.  This code should disappear once real hw is available.
- *
- * On entry to this routine, the following register values are assumed:
- *
- *	gr[8]	- BSP cpu
- *	pr[9]	- kernel entry address
- *
- * NOTE:
- *   This FPROM may be loaded/executed at an address different from the
- *   address that it was linked at. The FPROM is linked to run on node 0
- *   at address 0x100000. If the code in loaded into another node, it
- *   must be loaded at offset 0x100000 of the node. In addition, the
- *   FPROM does the following things:
- *		- determine the base address of the node it is loaded on
- *		- add the node base to _gp.
- *		- add the node base to all addresses derived from "movl" 
- *		  instructions. (I couldnt get GPREL addressing to work)
- *		  (maybe newer versions of the tools will support this)
- *		- scan the .got section and add the node base to all
- *		  pointers in this section.
- *		- add the node base to all physical addresses in the
- *		  SAL/PAL/EFI table built by the C code. (This is done
- *		  in the C code - not here)
- *		- add the node base to the TLB entries for vmlinux
- */
-
-#define KERNEL_BASE	0xe000000000000000
-#define PAGESIZE_256M	28
-
-/* 
- * ar.k0 gets set to IOPB_PA value, on 460gx chipset it should 
- * be 0x00000ffffc000000, but on snia we use the (inverse swizzled)
- * IOSPEC_BASE value
- */
-#define IOPB_PA		0x00000a0000000000 /* inv swizzle IOSPEC_BASE */
-
-#define RR_RID		8
-
-
-
-// ====================================================================================	
-        .text
-        .align 16
-	.global _start
-	.proc _start
-_start:
-
-// Setup psr and rse for system init
-	mov		psr.l = r0;;
-	srlz.d;;
-	invala
-	mov		ar.rsc = r0;;
-	loadrs
-	;;
-
-// Set CALIAS size to zero. We dont use it.
-	movl		r24=0x80000a0001000028;;	// BR_PI_CALIAS_SIZE
-	st8 		[r24]=r0
-
-// Isolate node number we are running on.
-	mov		r6 = ip;;
-	shr		r5 = r6,33;;			// r5 = node number
-	shl		r6 = r5,33			// r6 = base memory address of node
-
-// Set & relocate gp.
-	movl		r1= __gp;;			// Add base memory address
-	add 		r1 = r1,r6			// Relocate to boot node
-
-// Lets figure out who we are & put it in the LID register.
-// The BR_PI_SELF_CPU_NUM register gives us a value of 0-3.
-// This identifies the cpu on the node. 
-// Merge the cpu number with the NASID to generate the LID.
-	movl		r24=0x80000a0001000020;;	// BR_PI_SELF_CPU_NUM
-	ld8 		r25=[r24]			// Fetch PI_SELF
-	movl		r27=0x80000a0001600000;;	// Fetch REVID to get local NASID
-	ld8 		r27=[r27];;
-	extr.u		r27=r27,32,8
-	shl 		r26=r25,16;;			// Align local cpu# to lid.eid
-	shl 		r27=r27,24;;			// Align NASID to lid.id
-	or  		r26=r26,r27;;			// build the LID
-	mov 		cr.lid=r26			// Now put in in the LID register
-	
-	movl		r2=FPSR_DEFAULT;;
-	mov 		ar.fpsr=r2
-	movl		sp = bootstacke-16;;
-	add 		sp = sp,r6			// Relocate to boot node			
-
-// Save the NASID that we are loaded on.
-	movl		r2=base_nasid;;			// Save base_nasid for C code
-	add 		r2 = r2,r6;;			// Relocate to boot node
-  	st8 		[r2]=r5				// Uncond st8 - same on all cpus
-
-// Save the kernel entry address. It is passed in r9 on one of
-// the cpus.
-	movl		r2=bsp_entry_pc
-	cmp.ne		p6,p0=r9,r0;;
-	add 		r2 = r2,r6;;			// Relocate to boot node
-(p6)  	st8 		[r2]=r9				// Uncond st8 - same on all cpus
-
-
-// The following can ONLY be done by 1 cpu. Lets set a lock - the
-// cpu that gets it does the initilization. The rest just spin waiting
-// til initilization is complete.
-	movl		r22 = initlock;;
-	add		r22 = r22,r6			// Relocate to boot node
-	mov		r23 = 1;;
-	xchg8		r23 = [r22],r23;;
-	cmp.eq 		p6,p0 = 0,r23
-(p6)	br.cond.spnt.few init
-1:	ld4		r23 = [r22];;
-	cmp.eq		p6,p0 = 1,r23
-(p6)	br.cond.sptk	1b
-	br		initx
-
-// Add base address of node memory to each pointer in the .got section.
-init:	movl		r16 = _GLOBAL_OFFSET_TABLE_;;
-	add		r16 = r16,r6;;			// Relocate to boot node
-1: 	ld8		r17 = [r16];;
-	cmp.eq		p6,p7=0,r17
-(p6)	br.cond.sptk.few.clr 2f;;
-	add		r17 = r17,r6;;			// Relocate to boot node
-	st8		[r16] = r17,8
-	br		1b
-2:
-	mov		r23 = 2;;			// All done, release the spinning cpus
-	st4		[r22] = r23
-initx:
-
-//
-//	I/O-port space base address:
-//
-	movl		r2 = IOPB_PA;;
-	mov		ar.k0 = r2
-
-
-// Now call main & pass it the current LID value.
-	alloc 		r0=ar.pfs,0,0,2,0
-	mov    		r32=r26
-	mov   		r33=r8;;
-	br.call.sptk.few rp=fmain
-	
-// Initialize Region Registers
-//
-	mov		r10 = r0
-	mov		r2 = (13<<2) 
-	mov		r3 = r0;;
-1:	cmp4.gtu	p6,p7 = 7, r3
-	dep		r10 = r3, r10, 61, 3
-	dep		r2 = r3, r2, RR_RID, 4;;
-(p7)	dep		r2 = 0, r2, 0, 1;;
-(p6)	dep		r2 = -1, r2, 0, 1;;
-	mov		rr[r10] = r2
-	add		r3 = 1, r3;;
-	srlz.d;;
-	cmp4.gtu	p6,p0 = 8, r3
-(p6)	br.cond.sptk.few.clr 1b
-
-//
-// Return value indicates if we are the BSP or AP.
-// 	   1 = BSP, 0 = AP
-	mov             cr.tpr=r0;;
-	cmp.eq		p6,p0=r8,r0
-(p6)	br.cond.spnt	slave
-
-//
-// Initialize the protection key registers with only pkr[0] = valid.
-//
-// Should be initialized in accordance with the OS.
-//
-	mov		r2 = 1
-	mov		r3 = r0;;
-	mov		pkr[r3] = r2;;
-	srlz.d;;
-	mov		r2 = r0
-
-1:	add		r3 = r3, r0, 1;;		// increment PKR
-	cmp.gtu		p6, p0 = 16, r3;;
-(p6)	mov		pkr[r3] = r2
-(p6)	br.cond.sptk.few.clr 1b
-
-	mov		ar.rnat = r0			// clear RNAT register
-
-//
-// Setup system address translation for kernel
-//
-// Note: The setup of Kernel Virtual address space can be done by the
-// C code of the boot loader.
-//
-//
-
-#define LINUX_PAGE_OFFSET       0xe000000000000000
-#define ITIR(key, ps)           ((key<<8) | (ps<<2))
-#define ITRGR(ed,ar,ma)         ((ed<<52) | (ar<<9) | (ma<<2) | 0x61)
-
-#define AR_RX                   1                       // RX permission
-#define AR_RW                   4                       // RW permission
-#define MA_WB                   0                       // WRITEBACK memory attribute
-
-#define TLB_PAGESIZE		28			// Use 256MB pages for now.
-	mov		r16=r5
-
-//
-//     text section
-//
-        movl            r2 = LINUX_PAGE_OFFSET;;        // Set up IFA with VPN of linux
-        mov             cr.ifa = r2
-        movl            r3 = ITIR(0,TLB_PAGESIZE);;     // Set ITIR to default pagesize
-        mov             cr.itir = r3
-
-        shl             r4 = r16,33;;                   // physical addr of start of node
-        movl            r5 = ITRGR(1,AR_RX,MA_WB);;     // TLB attributes
-        or              r10=r4,r5;;
-
-        itr.i           itr[r0] = r10;;                   // Dropin ITR entry
-	srlz.i;;
-
-//
-//     data section
-//
-        movl            r2 = LINUX_PAGE_OFFSET;;        // Set up IFA with VPN of linux
-        mov             cr.ifa = r2
-        movl            r3 = ITIR(0,TLB_PAGESIZE);;     // Set ITIR to default pagesize
-        mov             cr.itir = r3
-
-        shl             r4 = r16,33;;                   // physical addr of start of node
-        movl            r5 = ITRGR(1,AR_RW,MA_WB);;     // TLB attributes
-        or              r10=r4,r5;;
-
-        itr.d           dtr[r0] = r10;;                 // Dropin DTR entry
-	srlz.d;;
-
-
-
-
-//
-// Turn on address translation, interrupt collection, psr.ed, protection key.
-// Interrupts (PSR.i) are still off here.
-//
-
-	movl		r3 = (	IA64_PSR_BN | \
-				IA64_PSR_AC | \
-				IA64_PSR_IT | \
-				IA64_PSR_DB | \
-				IA64_PSR_DA | \
-				IA64_PSR_RT | \
-				IA64_PSR_DT | \
-				IA64_PSR_IC   \
-			     )
-	;;
-	mov		cr.ipsr = r3
-
-//
-// Go to kernel C startup routines
-//	Need to do a "rfi" in order set "it" and "ed" bits in the PSR.
-//	This is the only way to set them.
-
-	movl		r2=bsp_entry_pc;;
-	add 		r2 = r2,r6;;			// Relocate to boot node
-	ld8		r2=[r2];;
-	mov		cr.iip = r2
-	srlz.d;;
-	rfi;;
-	.endp		_start
-
-// Slave processors come here to spin til they get an interrupt. Then they launch themselves to
-// the place ap_entry points. No initialization is necessary - the kernel makes no
-// assumptions about state on this entry.
-//	Note: should verify that the interrupt we got was really the ap_wakeup
-//	      interrupt but this should not be an issue on medusa
-slave:
-	nop.i		0x8beef				// Medusa - put cpu to sleep til interrupt occurs
-	mov		r8=cr.irr0;;			// Check for interrupt pending.
-	cmp.eq		p6,p0=r8,r0
-(p6)	br.cond.sptk	slave;;
-
-	mov		r8=cr.ivr;;			// Got one. Must read ivr to accept it
-	srlz.d;;
-	mov		cr.eoi=r0;;			// must write eoi to clear
-	movl		r8=ap_entry;;			// now jump to kernel entry
-	add 		r8 = r8,r6;;			// Relocate to boot node
-	ld8		r9=[r8],8;;
-	ld8		r1=[r8]
-	mov		b0=r9;;
-	br		b0
-
-// Here is the kernel stack used for the fake PROM
-	.bss
-	.align		16384
-bootstack:
-	.skip		16384
-bootstacke:
-initlock:
-	data4
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/fw-emu.c linux/arch/ia64/sn/fprom/fw-emu.c
--- linux.orig/arch/ia64/sn/fprom/fw-emu.c	2001-07-31 17:30:09.000000000 +0000
+++ linux/arch/ia64/sn/fprom/fw-emu.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,524 +0,0 @@
-/*
- * PAL & SAL emulation.
- *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
- */
-#include <asm/efi.h>
-#include <asm/pal.h>
-#include <asm/sal.h>
-#include <asm/processor.h>
-#include <asm/acpi-ext.h>
-#include "fpmem.h"
-
-#define MB	(1024*1024UL)
-#define GB	(MB*1024UL)
-
-#define FPROM_BUG()		do {while (1);} while (0)
-#define MAX_NODES		128
-#define MAX_LSAPICS		512
-#define MAX_CPUS		512
-#define MAX_CPUS_NODE		4
-#define CPUS_PER_NODE		4
-#define CPUS_PER_FSB		2
-#define CPUS_PER_FSB_MASK	(CPUS_PER_FSB-1)
-
-#define NUM_EFI_DESCS		2
-
-typedef union ia64_nasid_va {
-        struct {
-                unsigned long off   : 33;       /* intra-region offset */
-		unsigned long nasid :  7;	/* NASID */
-		unsigned long off2  : 21;	/* fill */
-                unsigned long reg   :  3;       /* region number */
-        } f;
-        unsigned long l;
-        void *p;
-} ia64_nasid_va;
-
-typedef struct {
-	unsigned long	pc;
-	unsigned long	gp;
-} func_ptr_t;
- 
-#define IS_VIRTUAL_MODE() 	 ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
-#define ADDR_OF(p)		(IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
-#define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.l;})
-
-/*
- * The following variables are passed thru registersfrom the configuration file and
- * are set via the _start function.
- */
-long		base_nasid;
-long		num_cpus;
-long		bsp_entry_pc=0;
-long		num_nodes;
-long		app_entry_pc;
-int		bsp_lid;
-func_ptr_t	ap_entry;
-
-
-static efi_runtime_services_t    *efi_runtime_p;
-static char fw_mem[(  sizeof(efi_system_table_t)
-		    + sizeof(efi_runtime_services_t)
-		    + NUM_EFI_DESCS*sizeof(efi_config_table_t)
-		    + sizeof(struct ia64_sal_systab)
-		    + sizeof(struct ia64_sal_desc_entry_point)
-		    + sizeof(struct ia64_sal_desc_ap_wakeup)
-		    + sizeof(acpi_rsdp_t)
-		    + sizeof(acpi_rsdt_t)
-		    + sizeof(acpi_sapic_t)
-		    + MAX_LSAPICS*(sizeof(acpi_entry_lsapic_t))
-		    + (1+8*MAX_NODES)*(sizeof(efi_memory_desc_t))
-		    + sizeof(ia64_sal_desc_ptc_t) +
-		    + MAX_NODES*sizeof(ia64_sal_ptc_domain_info_t) +
-		    + MAX_CPUS*sizeof(ia64_sal_ptc_domain_proc_entry_t) +
-		    + 1024)] __attribute__ ((aligned (8)));
-
-/*
- * Very ugly, but we need this in the simulator only.  Once we run on
- * real hw, this can all go away.
- */
-extern void pal_emulator_static (void);
-
-asm ("
-	.text
-	.proc pal_emulator_static
-pal_emulator_static:
-	mov r8=-1;;
-	cmp.eq p6,p7=6,r28;;		/* PAL_PTCE_INFO */
-(p7)	br.cond.sptk.few 1f
-	;;
-	mov r8=0			/* status = 0 */
-	movl r9=0x500000000		/* tc.base */
-	movl r10=0x0000000200000003	/* count[0], count[1] */
-	movl r11=0x1000000000002000	/* stride[0], stride[1] */
-	br.cond.sptk.few rp
-
-1:	cmp.eq p6,p7=14,r28;;		/* PAL_FREQ_RATIOS */
-(p7)	br.cond.sptk.few 1f;;
-	mov r8=0			/* status = 0 */
-	movl r9 =0x100000064		/* proc_ratio (1/100) */
-	movl r10=0x100000100		/* bus_ratio<<32 (1/256) */
-	movl r11=0x10000000a		/* itc_ratio<<32 (1/100) */
-
-1:	cmp.eq p6,p7=22,r28;;		/* PAL_MC_DRAIN */
-(p7)	br.cond.sptk.few 1f;;
-	mov r8=0
-	br.cond.sptk.few rp
-
-1:	cmp.eq p6,p7=23,r28;;		/* PAL_MC_EXPECTED */
-(p7)	br.cond.sptk.few 1f;;
-	mov r8=0
-	br.cond.sptk.few rp
-
-1:	br.cond.sptk.few rp
-	.endp pal_emulator_static\n");
-
-
-static efi_status_t
-efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
-{
-	if (tm) {
-		memset(tm, 0, sizeof(*tm));
-		tm->year = 2000;
-		tm->month = 2;
-		tm->day = 13;
-		tm->hour = 10;
-		tm->minute = 11;
-		tm->second = 12;
-	}
-
-	if (tc) {
-		tc->resolution = 10;
-		tc->accuracy = 12;
-		tc->sets_to_zero = 1;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static void
-efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
-{
-	while(1);	/* Is there a pseudo-op to stop medusa */
-}
-
-static efi_status_t
-efi_success (void)
-{
-	return EFI_SUCCESS;
-}
-
-static efi_status_t
-efi_unimplemented (void)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static long
-sal_emulator (long index, unsigned long in1, unsigned long in2,
-	      unsigned long in3, unsigned long in4, unsigned long in5,
-	      unsigned long in6, unsigned long in7)
-{
-	register long r9 asm ("r9") = 0;
-	register long r10 asm ("r10") = 0;
-	register long r11 asm ("r11") = 0;
-	long status;
-
-	/*
-	 * Don't do a "switch" here since that gives us code that
-	 * isn't self-relocatable.
-	 */
-	status = 0;
-	if (index == SAL_FREQ_BASE) {
-		switch (in1) {
-		      case SAL_FREQ_BASE_PLATFORM:
-			r9 = 500000000;
-			break;
-
-		      case SAL_FREQ_BASE_INTERVAL_TIMER:
-			/*
-			 * Is this supposed to be the cr.itc frequency
-			 * or something platform specific?  The SAL
-			 * doc ain't exactly clear on this...
-			 */
-			r9 = 700000000;
-			break;
-
-		      case SAL_FREQ_BASE_REALTIME_CLOCK:
-			r9 = 1;
-			break;
-
-		      default:
-			status = -1;
-			break;
-		}
-	} else if (index == SAL_SET_VECTORS) {
-		if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
-			func_ptr_t	*fp;
-			fp = ADDR_OF(&ap_entry);
-			fp->pc = in2;
-			fp->gp = in3;
-		} else {
-			status = -1;
-		}
-		;
-	} else if (index == SAL_GET_STATE_INFO) {
-		;
-	} else if (index == SAL_GET_STATE_INFO_SIZE) {
-		;
-	} else if (index == SAL_CLEAR_STATE_INFO) {
-		;
-	} else if (index == SAL_MC_RENDEZ) {
-		;
-	} else if (index == SAL_MC_SET_PARAMS) {
-		;
-	} else if (index == SAL_CACHE_FLUSH) {
-		;
-	} else if (index == SAL_CACHE_INIT) {
-		;
-	} else if (index == SAL_UPDATE_PAL) {
-		;
-	} else {
-		status = -1;
-	}
-	asm volatile ("" :: "r"(r9), "r"(r10), "r"(r11));
-	return status;
-}
-
-
-/*
- * This is here to work around a bug in egcs-1.1.1b that causes the
- * compiler to crash (seems like a bug in the new alias analysis code.
- */
-void *
-id (long addr)
-{
-	return (void *) addr;
-}
-
-
-/*
- * Fix the addresses in a function pointer by adding base node address
- * to pc & gp.
- */
-void
-fix_function_pointer(void *fp)
-{
-	func_ptr_t	*_fp;
-
-	_fp = fp;
-	_fp->pc = __fwtab_pa(base_nasid, _fp->pc);
-	_fp->gp = __fwtab_pa(base_nasid, _fp->gp);
-}
-
-void
-fix_virt_function_pointer(void *fptr)
-{
-        func_ptr_t      *fp;
-
-        fp = fptr;
-        fp->pc = fp->pc | PAGE_OFFSET;
-        fp->gp = fp->gp | PAGE_OFFSET;
-}
-
-
-int
-efi_set_virtual_address_map(void)
-{
-        efi_runtime_services_t            *runtime;
-
-        runtime = efi_runtime_p;
-        fix_virt_function_pointer((void*)runtime->get_time);
-        fix_virt_function_pointer((void*)runtime->set_time);
-        fix_virt_function_pointer((void*)runtime->get_wakeup_time);
-        fix_virt_function_pointer((void*)runtime->set_wakeup_time);
-        fix_virt_function_pointer((void*)runtime->set_virtual_address_map);
-        fix_virt_function_pointer((void*)runtime->get_variable);
-        fix_virt_function_pointer((void*)runtime->get_next_variable);
-        fix_virt_function_pointer((void*)runtime->set_variable);
-        fix_virt_function_pointer((void*)runtime->get_next_high_mono_count);
-        fix_virt_function_pointer((void*)runtime->reset_system);
-        return EFI_SUCCESS;;
-}
-
-
-void
-sys_fw_init (const char *args, int arglen, int bsp)
-{
-	/*
-	 * Use static variables to keep from overflowing the RSE stack
-	 */
-	static efi_system_table_t *efi_systab;
-	static efi_runtime_services_t *efi_runtime;
-	static efi_config_table_t *efi_tables;
-	static ia64_sal_desc_ptc_t *sal_ptc;
-	static ia64_sal_ptc_domain_info_t *sal_ptcdi;
-	static ia64_sal_ptc_domain_proc_entry_t *sal_ptclid;
-	static acpi_rsdp_t *acpi_systab;
-	static acpi_rsdt_t *acpi_rsdt;
-	static acpi_sapic_t *acpi_sapic;
-	static acpi_entry_lsapic_t *acpi_lsapic;
-	static struct ia64_sal_systab *sal_systab;
-	static efi_memory_desc_t *efi_memmap, *md;
-	static unsigned long *pal_desc, *sal_desc;
-	static struct ia64_sal_desc_entry_point *sal_ed;
-	static struct ia64_boot_param *bp;
-	static struct ia64_sal_desc_ap_wakeup *sal_apwake;
-	static unsigned char checksum = 0;
-	static char *cp, *cmd_line, *vendor;
-	static int mdsize, domain, last_domain ;
-	static int cnode, nasid, cpu, num_memmd, cpus_found;
-
-	/*
-	 * Pass the parameter base address to the build_efi_xxx routines.
-	 */
-	build_init(8LL*GB*base_nasid);
-
-	num_nodes = GetNumNodes();
-	num_cpus = GetNumCpus();
-
-
-	memset(fw_mem, 0, sizeof(fw_mem));
-
-	pal_desc = (unsigned long *) &pal_emulator_static;
-	sal_desc = (unsigned long *) &sal_emulator;
-	fix_function_pointer(&pal_emulator_static);
-	fix_function_pointer(&sal_emulator);
-
-	/* Align this to 16 bytes, probably EFI does this  */
-	mdsize = (sizeof(efi_memory_desc_t) + 15) & ~15 ;
-
-	cp = fw_mem;
-	efi_systab  = (void *) cp; cp += sizeof(*efi_systab);
-	efi_runtime_p = efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
-	efi_tables  = (void *) cp; cp += NUM_EFI_DESCS*sizeof(*efi_tables);
-	sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
-	sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
-	sal_ptc     = (void *) cp; cp += sizeof(*sal_ptc);
-	sal_apwake  = (void *) cp; cp += sizeof(*sal_apwake);
-	acpi_systab = (void *) cp; cp += sizeof(*acpi_systab);
-	acpi_rsdt   = (void *) cp; cp += sizeof(*acpi_rsdt);
-	acpi_sapic  = (void *) cp; cp += sizeof(*acpi_sapic);
-	acpi_lsapic = (void *) cp; cp += num_cpus*sizeof(*acpi_lsapic);
-	vendor 	    = (char *) cp; cp += 32;
-	efi_memmap  = (void *) cp; cp += 8*32*sizeof(*efi_memmap);
-	sal_ptcdi   = (void *) cp; cp += CPUS_PER_FSB*(1+num_nodes)*sizeof(*sal_ptcdi);
-	sal_ptclid  = (void *) cp; cp += ((3+num_cpus)*sizeof(*sal_ptclid)+7)/8*8;
-	cmd_line    = (void *) cp;
-
-	if (args) {
-		if (arglen >= 1024)
-			arglen = 1023;
-		memcpy(cmd_line, args, arglen);
-	} else {
-		arglen = 0;
-	}
-	cmd_line[arglen] = '\0';
-#ifdef BRINGUP
-	/* for now, just bring up bash */
-	strcpy(cmd_line, "init=/bin/bash");
-#else
-	strcpy(cmd_line, "");
-#endif
-
-	memset(efi_systab, 0, sizeof(efi_systab));
-	efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
-	efi_systab->hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
-	efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
-	efi_systab->fw_vendor = __fwtab_pa(base_nasid, vendor);
-	efi_systab->fw_revision = 1;
-	efi_systab->runtime = __fwtab_pa(base_nasid, efi_runtime);
-	efi_systab->nr_tables = 2;
-	efi_systab->tables = __fwtab_pa(base_nasid, efi_tables);
-	memcpy(vendor, "S\0i\0l\0i\0c\0o\0n\0-\0G\0r\0a\0p\0h\0i\0c\0s\0\0", 32);
-
-	efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
-	efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
-	efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
-	efi_runtime->get_time = __fwtab_pa(base_nasid, &efi_get_time);
-	efi_runtime->set_time = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->get_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->set_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->set_virtual_address_map = __fwtab_pa(base_nasid, &efi_set_virtual_address_map);
-	efi_runtime->get_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->get_next_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->set_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->get_next_high_mono_count = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->reset_system = __fwtab_pa(base_nasid, &efi_reset_system);
-
-	efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
-	efi_tables->table = __fwtab_pa(base_nasid, sal_systab);
-	efi_tables++;
-	efi_tables->guid = ACPI_TABLE_GUID;
-	efi_tables->table = __fwtab_pa(base_nasid, acpi_systab);
-	fix_function_pointer(&efi_unimplemented);
-	fix_function_pointer(&efi_get_time);
-	fix_function_pointer(&efi_success);
-	fix_function_pointer(&efi_reset_system);
-	fix_function_pointer(&efi_set_virtual_address_map);
-
-	/* fill in the ACPI system table: */
-	memcpy(acpi_systab->signature, "RSD PTR ", 8);
-	acpi_systab->rsdt = (struct acpi_rsdt*)__fwtab_pa(base_nasid, acpi_rsdt);
-
-	memcpy(acpi_rsdt->header.signature, "RSDT",4);
-	acpi_rsdt->header.length = sizeof(acpi_rsdt_t);
-	memcpy(acpi_rsdt->header.oem_id, "SGI", 3);
-	memcpy(acpi_rsdt->header.oem_table_id, "SN1", 3);
-	acpi_rsdt->header.oem_revision = 0x00010001;
-	acpi_rsdt->entry_ptrs[0] = __fwtab_pa(base_nasid, acpi_sapic);
-
-	memcpy(acpi_sapic->header.signature, "SPIC ", 4);
-	acpi_sapic->header.length = sizeof(acpi_sapic_t)+num_cpus*sizeof(acpi_entry_lsapic_t);
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		nasid = GetNasid(cnode);
-		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
-			if (!IsCpuPresent(cnode, cpu))
-				continue;
-			acpi_lsapic->type = ACPI_ENTRY_LOCAL_SAPIC;
-			acpi_lsapic->length = sizeof(acpi_entry_lsapic_t);
-			acpi_lsapic->acpi_processor_id = cnode*4+cpu;
-			acpi_lsapic->flags = LSAPIC_ENABLED|LSAPIC_PRESENT;
-			acpi_lsapic->eid = cpu;
-			acpi_lsapic->id = nasid;
-			acpi_lsapic++;
-		}
-	}
-
-
-	/* fill in the SAL system table: */
-	memcpy(sal_systab->signature, "SST_", 4);
-	sal_systab->size = sizeof(*sal_systab);
-	sal_systab->sal_rev_minor = 1;
-	sal_systab->sal_rev_major = 0;
-	sal_systab->entry_count = 3;
-
-	strcpy(sal_systab->oem_id, "SGI");
-	strcpy(sal_systab->product_id, "SN1");
-
-	/* fill in an entry point: */	
-	sal_ed->type = SAL_DESC_ENTRY_POINT;
-	sal_ed->pal_proc = __fwtab_pa(base_nasid, pal_desc[0]);
-	sal_ed->sal_proc = __fwtab_pa(base_nasid, sal_desc[0]);
-	sal_ed->gp = __fwtab_pa(base_nasid, sal_desc[1]);
-
-	/* kludge the PTC domain info */
-	sal_ptc->type = SAL_DESC_PTC;
-	sal_ptc->num_domains = 0;
-	sal_ptc->domain_info = __fwtab_pa(base_nasid, sal_ptcdi);
-	cpus_found = 0;
-	last_domain = -1;
-	sal_ptcdi--;
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		nasid = GetNasid(cnode);
-		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
-			if (IsCpuPresent(cnode, cpu)) {
-				domain = cnode*CPUS_PER_NODE + cpu/CPUS_PER_FSB;
-				if (domain != last_domain) {
-					sal_ptc->num_domains++;
-					sal_ptcdi++;
-					sal_ptcdi->proc_count = 0;
-					sal_ptcdi->proc_list = __fwtab_pa(base_nasid, sal_ptclid);
-					last_domain = domain;
-				}
-				sal_ptcdi->proc_count++;
-				sal_ptclid->id = nasid;
-				sal_ptclid->eid = cpu;
-				sal_ptclid++;
-				cpus_found++;
-			}
-		}
-	}
-
-	if (cpus_found != num_cpus)
-		FPROM_BUG();
-
-	/* Make the AP WAKEUP entry */
-	sal_apwake->type = SAL_DESC_AP_WAKEUP;
-	sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT;
-	sal_apwake->vector = 18;
-
-	for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
-		checksum += *cp;
-
-	sal_systab->checksum = -checksum;
-
-	md = &efi_memmap[0];
-	num_memmd = build_efi_memmap((void *)md, mdsize) ;
-
-	bp = id(ZERO_PAGE_ADDR + (((long)base_nasid)<<33));
-	bp->efi_systab = __fwtab_pa(base_nasid, &fw_mem);
-	bp->efi_memmap = __fwtab_pa(base_nasid, efi_memmap);
-	bp->efi_memmap_size = num_memmd*mdsize;
-	bp->efi_memdesc_size = mdsize;
-	bp->efi_memdesc_version = 0x101;
-	bp->command_line = __fwtab_pa(base_nasid, cmd_line);
-	bp->console_info.num_cols = 80;
-	bp->console_info.num_rows = 25;
-	bp->console_info.orig_x = 0;
-	bp->console_info.orig_y = 24;
-	bp->num_pci_vectors = 0;
-	bp->fpswa = 0;
-
-	/*
-	 * Now pick the BSP & store it LID value in
-	 * a global variable. Note if BSP is greater than last cpu,
-	 * pick the last cpu.
-	 */
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
-			if (!IsCpuPresent(cnode, cpu))
-				continue;
-			bsp_lid = (GetNasid(cnode)<<24) | (cpu<<16);
-			if (bsp-- > 0)
-				continue;
-			return;
-		}
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/main.c linux/arch/ia64/sn/fprom/main.c
--- linux.orig/arch/ia64/sn/fprom/main.c	2001-01-04 21:00:15.000000000 +0000
+++ linux/arch/ia64/sn/fprom/main.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,110 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
- */
-
-
-
-#include <linux/types.h>
-#include <asm/bitops.h>
-
-void bedrock_init(int);
-void synergy_init(int, int);
-void sys_fw_init (const char *args, int arglen, int bsp);
-
-volatile int	bootmaster=0;		/* Used to pick bootmaster */
-volatile int	nasidmaster[128]={0};	/* Used to pick node/synergy masters */
-int		init_done=0;
-extern int	bsp_lid;
-
-#define get_bit(b,p)	(((*p)>>(b))&1)
-
-int
-fmain(int lid, int bsp) {
-	int	syn, nasid, cpu;
-
-	/*
-	 * First lets figure out who we are. This is done from the
-	 * LID passed to us.
-	 */
-	nasid = (lid>>24);
-	syn = (lid>>17)&1;
-	cpu = (lid>>16)&1;
-
-	/*
-	 * Now pick a synergy master to initialize synergy registers.
-	 */
-	if (test_and_set_bit(syn, &nasidmaster[nasid]) == 0) {
-		synergy_init(nasid, syn);
-		test_and_set_bit(syn+2, &nasidmaster[nasid]);
-	} else
-		while (get_bit(syn+2, &nasidmaster[nasid]) == 0);
-	
-	/*
-	 * Now pick a nasid master to initialize Bedrock registers.
-	 */
-	if (test_and_set_bit(8, &nasidmaster[nasid]) == 0) {
-		bedrock_init(nasid);
-		test_and_set_bit(9, &nasidmaster[nasid]);
-	} else
-		while (get_bit(9, &nasidmaster[nasid]) == 0);
-	
-
-	/*
-	 * Now pick a BSP & finish init.
-	 */
-	if (test_and_set_bit(0, &bootmaster) == 0) {
-		sys_fw_init(0, 0, bsp);
-		test_and_set_bit(1, &bootmaster);
-	} else
-		while (get_bit(1, &bootmaster) == 0);
-
-	return (lid == bsp_lid);
-}
-
-
-void
-bedrock_init(int nasid)
-{
-	nasid = nasid;		/* to quiet gcc */
-}
-
-
-void
-synergy_init(int nasid, int syn)
-{
-	long	*base;
-	long	off;
-
-	/*
-	 * Enable all FSB flashed interrupts.
-	 * ZZZ - I'd really like defines for this......
-	 */
-	base = (long*)0x80000e0000000000LL;		/* base of synergy regs */
-	for (off = 0x2a0; off < 0x2e0; off+=8)		/* offset for VEC_MASK_{0-3}_A/B */
-		*(base+off/8) = -1LL;
-
-	/*
-	 * Set the NASID in the FSB_CONFIG register.
-	 */
-	base = (long*)0x80000e0000000450LL;
-	*base = (long)((nasid<<16)|(syn<<9));
-}
-
-
-/* Why isnt there a bcopy/memcpy in lib64.a */
-
-void* 
-memcpy(void * dest, const void *src, size_t count)
-{
-	char *s, *se, *d;
-
-	for(d=dest, s=(char*)src, se=s+count; s<se; s++, d++)
-		*d = *s;
-	return dest;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/fprom/runsim linux/arch/ia64/sn/fprom/runsim
--- linux.orig/arch/ia64/sn/fprom/runsim	2001-01-04 21:00:15.000000000 +0000
+++ linux/arch/ia64/sn/fprom/runsim	1970-01-01 00:00:00.000000000 +0000
@@ -1,372 +0,0 @@
-#!/bin/sh
-
-# Script for running PROMs and LINUX kernwls on medusa. 
-# Type "sim -H" for instructions.
-
-MEDUSA=${MEDUSA:-/home/rickc/official_medusa/medusa}
-
-# ------------------ err -----------------------
-err() {
-	echo "ERROR - $1"
-	exit 1
-}
-
-# ----------------  help ----------------------
-help() {
-cat <<END
-Script for running a PROM or LINUX kernel under medusa.
-This script creates a control file, creates links to the appropriate
-linux/prom files, and/or calls medusa to make simulation runs.
-
-Usage:  
-   Initial setup:
-   	sim [-c <config_file>] <-p> | <-k>  [<work_dir>]
-		-p	Create PROM control file & links
-		-k	Create LINUX control file & links
-		-c<cf>	Control file name				[Default: cf]
-		<work_dir> Path to directory that contains the linux or PROM files.
-		    The directory can be any of the following:
-		       (linux simulations)
-		       		worktree
-				worktree/linux
-				any directory with vmlinux, vmlinux.sym & fprom files
-			(prom simulations)
-				worktree
-				worktree/stand/arcs/IP37prom/dev
-				any directory with fw.bin & fw.sim files
-
-    Simulations:
-	sim  [-X <n>] [-o <output>] [-M] [<config_file>]
-		-c<cf>	Control file name				[Default: cf]
-		-M	Pipe output thru fmtmedusa
-		-o	Output filename (copy of all commands/output)	[Default: simout]
-		-X	Specifies number of instructions to execute	[Default: 0]
-			(Used only in auto test mode - not described here)
-
-Examples:
-	sim -p <promtree>	# create control file (cf) & links for prom simulations
-	sim -k <linuxtree>	# create control file (cf) & links for linux simulations
-	sim -p -c cfprom	# create a prom control file (cfprom) only. No links are made.
-
-	sim			# run medusa using previously created links &
-				#   control file (cf).
-END
-exit 1
-}
-
-# ----------------------- create control file header --------------------
-create_cf_header() {
-cat <<END >>$CF
-#
-# Template for a control file for running linux kernels under medusa. 
-# You probably want to make mods here but this is a good starting point.
-#
-
-# Preferences
-setenv cpu_stepping A
-setenv exceptionPrint off
-setenv interrupt_messages off
-setenv lastPCsize 100000
-setenv low_power_mode on
-setenv partialIntelChipSet on
-setenv printIntelMessages off
-setenv prom_write_action halt
-setenv prom_write_messages on
-setenv step_quantum 100
-setenv swizzling on
-setenv tsconsole on
-setenv uart_echo on
-symbols on
-
-# IDE disk params
-setenv diskCylinders 611
-setenv bootDrive C
-setenv diskHeads 16
-setenv diskPath idedisk
-setenv diskPresent 1
-setenv diskSpt 63
-
-# Hardware config
-setenv coherency_type nasid
-setenv cpu_cache_type default
-setenv synergy_cache_type syn_cac_64m_8w
-
-# Numalink config
-setenv route_enable on
-setenv network_type xbar		# Select [xbar|router]
-setenv network_warning 0xff
-
-END
-}
-
-
-# ------------------ create control file entries for linux simulations -------------
-create_cf_linux() {
-cat <<END >>$CF
-# Kernel specific options
-setenv mca_on_memory_failure off
-setenv LOADPC 0x00100000		# FPROM load address/entry point (8 digits!)
-sr g 9 0xe000000000520000		# Kernel entry point
-setenv symbol_table vmlinux.sym
-load fprom
-load vmlinux
-
-# Useful breakpoints to always have set. Add more if desired.
-break 0xe000000000505e00	all	# dispatch_to_fault_handler
-break panic			all	# stop on panic
-break die_if_kernel		all	# may as well stop
-
-END
-}
-
-# ------------------ create control file entries for prom simulations ---------------
-create_cf_prom() {
-	SYM2=""
-	ADDR="0x80000000ff800000"
-	[ "$EMBEDDED_LINUX" != "0" ] || SYM2="setenv symbol_table2 vmlinux.sym"
-	[ "$SIZE" = "8MB" ] || ADDR="0x80000000ffc00000"
-	cat <<END >>$CF
-# PROM specific options
-setenv mca_on_memory_failure on
-setenv LOADPC 0x80000000ffffffb0
-setenv promFile fw.bin
-setenv promAddr $ADDR
-setenv symbol_table fw.sym
-$SYM2
-
-# Useful breakpoints to always have set. Add more if desired.
-break Pr_ivt_gexx 		all
-break Pr_ivt_brk		all
-break Pr_PROM_Panic_Spin	all
-break Pr_PROM_Panic		all
-break Pr_PROM_C_Panic		all
-break Pr_fled_die		all
-break Pr_ResetNow		all
-break Pr_zzzbkpt		all
-
-END
-}
-
-
-# ------------------ create control file entries for memory configuration -------------
-create_cf_memory() {
-cat <<END >>$CF
-# CPU/Memory map format:
-#	setenv nodeN_memory_config 0xBSBSBSBS
-#		B=banksize (0=unused, 1=64M, 2=128M, .., 5-1G, c=8M, d=16M, e=32M)
-#		S=bank enable (0=both disable, 3=both enable, 2=bank1 enable, 1=bank0 enable)
-#		  rightmost digits are for bank 0, the lowest address.
-#	setenv nodeN_nasid <nasid>
-#		specifies the NASID for the node. This is used ONLY if booting the kernel.
-#		On PROM configurations, set to 0 - PROM will change it later.
-#	setenv nodeN_cpu_config <cpu_mask>
-#		Set bit number N to 1 to enable cpu N. Ex., a value of 5 enables cpu 0 & 2.
-#
-# Repeat the above 3 commands for each node.
-#
-# For kernel, default to 32MB. Although this is not a valid hardware configuration,
-# it runs faster on medusa. For PROM, 64MB is smallest allowed value.
-
-setenv node0_cpu_config		0x1	# Enable only cpu 0 on the node
-END
-
-if [ $LINUX -eq 1 ] ; then
-cat <<END >>$CF
-setenv node0_nasid		0	# cnode 0 has NASID 0
-setenv node0_memory_config 	0xe1	# 32MB
-END
-else
-cat <<END >>$CF
-setenv node0_memory_config 	0x11	# 64MB
-END
-fi
-}
-
-# -------------------- set links to linux files -------------------------
-set_linux_links() {
-	if [ -d $D/linux/arch ] ; then
-		D=$D/linux
-	elif [ -d $D/arch -o -e vmlinux.sym ] ; then
-		D=$D
-	else
-		err "cant determine directory for linux binaries"
-	fi
-	rm -rf vmlinux vmlinux.sym fprom
-	ln -s $D/vmlinux vmlinux
-	ln -s $D/vmlinux.sym vmlinux.sym
-	if [ -d $D/arch ] ; then
-		ln -s $D/arch/ia64/sn/fprom/fprom fprom
-	else
-		ln -s $D/fprom fprom
-	fi
-	echo "  .. Created links to linux files"	
-}
-
-# -------------------- set links to prom files -------------------------
-set_prom_links() {
-	if [ -d $D/stand ] ; then
-		D=$D/stand/arcs/IP37prom/dev
-	elif [ -d $D/sal ] ; then
-		D=$D
-	else
-		err "cant determine directory for PROM binaries"
-	fi
-	SETUP="$D/../../../../.setup"
-	grep -q '^ *setenv *PROMSIZE *8MB' $SETUP
-	if [ $? -eq 0 ] ; then
-		SIZE="8MB"
-	else
-		SIZE="4MB"
-	fi
-	grep -q '^ *setenv *LAUNCH_VMLINUX' $SETUP
-	EMBEDDED_LINUX=$?
-	rm -f fw.bin fw.map fw.sym vmlinux vmlinux.sym fprom
-	SDIR="SN1IA${SIZE}.O"
-	BIN="SN1IAip37prom${SIZE}"
-	ln -s $D/$SDIR/$BIN.bin fw.bin
-	ln -s $D/$SDIR/$BIN.map fw.map
-	ln -s $D/$SDIR/$BIN.sym fw.sym
-	echo "  .. Created links to $SIZE prom files"
-	if [ $EMBEDDED_LINUX -eq 0 ] ; then
-		ln -s $D/linux/vmlinux vmlinux
-		ln -s $D/linux/vmlinux.sym vmlinux.sym
-		if [ -d linux/arch ] ; then
-			ln -s $D/linux/arch/ia64/sn/fprom/fprom fprom
-		else
-			ln -s $D/linux/fprom fprom
-		fi
-		echo "  .. Created links to embedded linux files in prom tree"
-	fi
-}
-
-# --------------- start of shell script --------------------------------
-OUT="simout"
-FMTMED=0
-STEPCNT=0
-PROM=0
-LINUX=0
-NCF="cf"
-while getopts "HMX:c:o:pk" c ; do
-        case ${c} in
-                H) help;;
-		M) FMTMED=1;;
-		X) STEPCNT=${OPTARG};;
-		c) NCF=${OPTARG};;
-		k) PROM=0;LINUX=1;;
-		p) PROM=1;LINUX=0;;
-		o) OUT=${OPTARG};;
-                \?) exit 1;;
-        esac
-done
-shift `expr ${OPTIND} - 1`
-
-# Check if command is for creating control file and/or links to images.
-if [ $PROM -eq 1 -o $LINUX -eq 1 ] ; then
-	CF=$NCF
-	[ ! -f $CF ] || err "wont overwrite an existing control file ($CF)"
-	if [ $# -gt 0 ] ; then
-		D=$1
-		[ -d $D ] || err "cannot find directory $D"
-		[ $PROM -eq 0 ]  || set_prom_links
-		[ $LINUX -eq 0 ] || set_linux_links
-	fi
-	create_cf_header
-	[ $PROM -eq 0 ]  || create_cf_prom
-	[ $LINUX -eq 0 ] || create_cf_linux
-	create_cf_memory
-	echo "  .. Basic control file created (in $CF). You might want to edit"
-	echo "     this file (at least, look at it)."
-	exit 0
-fi
-
-# Verify that the control file exists
-CF=${1:-$NCF}
-[ -f $CF ] || err "No control file exists. For help, type: $0 -H"
-
-# Build the .cf files from the user control file. The .cf file is
-# identical except that the actual start & load addresses are inserted
-# into the file. In addition, the FPROM commands for configuring memory
-# and LIDs are generated. 
-
-rm -f .cf .cf1 .cf2
-awk '
-function strtonum(n) {
-	 if (substr(n,1,2) != "0x")
-	 	return int(n)
-	 n = substr(n,3)
-	 r=0
-	 while (length(n) > 0) {
-	 	r = r*16+(index("0123456789abcdef", substr(n,1,1))-1)
-		n = substr(n,2)
-	 }
-	 return r
-	}
-/^#/   	{next}
-/^$/	{next}
-/^setenv *LOADPC/               {loadpc = $3; next}
-/^setenv *node._cpu_config/	{n=int(substr($2,5,1)); cpuconf[n] = strtonum($3); print; next}
-/^setenv *node._memory_config/	{n=int(substr($2,5,1)); memconf[n] = strtonum($3); print; next}
-/^setenv *node._nasid/		{n=int(substr($2,5,1)); nasid[n] = strtonum($3); print; next}
-		{print}
-END	{
-	 # Generate the memmap info that starts at the beginning of
-	 # the node the kernel was loaded on.
-	 loadnasid = nasid[0]
-	 cnode = 0
-	 for (i=0; i<128; i++) {
-		if (memconf[i] != "") {
-			printf "sm 0x%x%08x 0x%x%04x%04x\n", 
-				2*loadnasid, 8*cnodes+8, memconf[i], cpuconf[i], nasid[i]
-			cnodes++
-			cpus += substr("0112122312232334", cpuconf[i]+1,1)
-		}
-	 }
-	 printf "sm 0x%x00000000 0x%x%08x\n", 2*loadnasid, cnodes, cpus
-	 printf "setenv number_of_nodes %d\n", cnodes
-
-	 # Now set the starting PC for each cpu.
-	 cnode = 0
-	 lowcpu=-1
-	 for (i=0; i<128; i++) {
-		if (memconf[i] != "") {
-			printf "setnode %d\n", cnode
-			conf = cpuconf[i]
-			for (j=0; j<4; j++) {
-				if (conf != int(conf/2)*2) {
-	 				printf "setcpu %d\n", j
-					if (length(loadpc) == 18)
-						printf "sr pc %s\n", loadpc
-					else
-						printf "sr pc 0x%x%s\n", 2*loadnasid, substr(loadpc,3)
-					if (lowcpu == -1)
-						lowcpu = j
-				}
-				conf = int(conf/2)
-			}
-			cnode++
-		}
-	 }
-	 printf "setnode 0\n"
-	 printf "setcpu %d\n", lowcpu
-	}
-' <$CF >.cf
-
-# Now build the .cf1 & .cf2 control files.
-CF2_LINES="^sm |^break |^run |^si |^quit |^symbols "
-egrep  "$CF2_LINES" .cf >.cf2
-egrep -v "$CF2_LINES" .cf >.cf1
-if [ $STEPCNT -ne 0 ] ; then
-	echo "s $STEPCNT" >>.cf2
-	echo "lastpc 1000" >>.cf2
-	echo "q" >>.cf2
-fi
-echo "script-on $OUT" >>.cf2
-
-# Now start medusa....
-if [ $FMTMED -ne 0 ] ; then
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 |  fmtmedusa
-elif [ $STEPCNT -eq 0 ] ; then
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 
-else
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 2>&1 
-fi
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/Makefile linux/arch/ia64/sn/io/Makefile
--- linux.orig/arch/ia64/sn/io/Makefile	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -3,8 +3,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2000 Silicon Graphics, Inc.
-# Copyright (C) Jack Steiner (steiner@sgi.com)
+# Copyright (C) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
 #
 #
 # Makefile for the linux kernel.
@@ -13,20 +12,34 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (ie not a .c file).
 #
-# Note 2! The CFLAGS definitions are now in the main makefile...
 
-EXTRA_CFLAGS	:= -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \
-		   -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \
-		   -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \
-		   -DNEW_INTERRUPTS
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
 O_TARGET := sgiio.o
-obj-y   := stubs.o sgi_if.o pciio.o pcibr.o xtalk.o xbow.o xswitch.o hubspc.o \
-		klgraph_hack.o io.o hubdev.o huberror.o \
+
+ifeq ($(CONFIG_MODULES),y)
+export-objs = pciio.o hcl.o
+endif
+
+obj-y  := stubs.o sgi_if.o pciio.o xtalk.o xbow.o xswitch.o klgraph_hack.o \
 		hcl.o labelcl.o invent.o klgraph.o klconflib.o sgi_io_sim.o \
 		module.o sgi_io_init.o klgraph_hack.o ml_SN_init.o \
-		ml_SN_intr.o ip37.o pciba.o \
-		ml_iograph.o hcl_util.o cdl.o \
-		mem_refcnt.o devsupport.o alenlist.o pci_bus_cvlink.o \
-		eeprom.o pci.o pci_dma.o l1.o l1_command.o ate_utils.o
+		ml_iograph.o hcl_util.o cdl.o hubdev.o hubspc.o \
+		alenlist.o pci_bus_cvlink.o \
+		eeprom.o pci.o pci_dma.o l1.o l1_command.o ate_utils.o \
+		ifconfig_net.o efi-rtc.o io.o
+
+obj-$(CONFIG_IA64_SGI_SN1)   += sn1/ml_SN_intr.o sn1/mem_refcnt.o sn1/hubcounters.o \
+				sn1/ip37.o sn1/huberror.o sn1/hub_intr.o sn1/pcibr.o
+
+obj-$(CONFIG_IA64_SGI_SN2)   += sn2/ml_SN_intr.o sn2/shub_intr.o sn2/shuberror.o \
+				sn2/bte_error.o \
+				sn2/pcibr/pcibr_dvr.o sn2/pcibr/pcibr_ate.o \
+				sn2/pcibr/pcibr_config.o sn2/pcibr/pcibr_dvr.o \
+				sn2/pcibr/pcibr_hints.o \
+				sn2/pcibr/pcibr_idbg.o sn2/pcibr/pcibr_intr.o \
+				sn2/pcibr/pcibr_rrb.o sn2/pcibr/pcibr_slot.o 
+
+obj-$(CONFIG_PCIBA) += pciba.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/alenlist.c linux/arch/ia64/sn/io/alenlist.c
--- linux.orig/arch/ia64/sn/io/alenlist.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/alenlist.c	2002-07-20 01:08:37.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
  */
 
 /* Implementation of Address/Length Lists. */
@@ -13,9 +12,9 @@
 
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/mmzone.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/alenlist.h>
-#include <asm/sn/mmzone_sn1.h>
 
 /*
  * Logically, an Address/Length List is a list of Pairs, where each pair
@@ -218,9 +217,9 @@
 void
 alenlist_init(void)
 {
-	alenlist_zone = kmem_zone_init(sizeof(struct alenlist_s), "alenlist");
-	alenlist_chunk_zone = kmem_zone_init(sizeof(struct alenlist_chunk_s), "alchunk");
-	alenlist_cursor_zone = kmem_zone_init(sizeof(struct alenlist_cursor_s), "alcursor");
+	alenlist_zone = snia_kmem_zone_init(sizeof(struct alenlist_s), "alenlist");
+	alenlist_chunk_zone = snia_kmem_zone_init(sizeof(struct alenlist_chunk_s), "alchunk");
+	alenlist_cursor_zone = snia_kmem_zone_init(sizeof(struct alenlist_cursor_s), "alcursor");
 #if DEBUG
 	idbg_addfunc("alenshow", alenlist_show);
 #endif /* DEBUG */
@@ -250,7 +249,7 @@
 {
 	alenlist_t alenlist;
 
-	alenlist = kmem_zone_alloc(alenlist_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
+	alenlist = snia_kmem_zone_alloc(alenlist_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
 	if (alenlist) {
 		INCR_COUNT(&alenlist_count);
 
@@ -334,7 +333,7 @@
 		while (chunk) {
 			freechunk = chunk;
 			chunk = chunk->alc_next;
-			kmem_zone_free(alenlist_chunk_zone, freechunk);
+			snia_kmem_zone_free(alenlist_chunk_zone, freechunk);
 			DECR_COUNT(&alenlist_chunk_count);
 		}
 		alenlist->al_actual_size = ALEN_CHUNK_SZ;
@@ -407,7 +406,7 @@
 		alenlist_clear(alenlist);
 
 	/* Now, free the alenlist itself */
-	kmem_zone_free(alenlist_zone, alenlist);
+	snia_kmem_zone_free(alenlist_zone, alenlist);
 	DECR_COUNT(&alenlist_count);
 }
 
@@ -473,7 +472,7 @@
 			} else {
 				alenlist_chunk_t new_chunk;
 
-				new_chunk = kmem_zone_alloc(alenlist_chunk_zone, 
+				new_chunk = snia_kmem_zone_alloc(alenlist_chunk_zone, 
 							flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
 
 				if (new_chunk == NULL)
@@ -656,7 +655,7 @@
 	alenlist_cursor_t cursorp;
 
 	ASSERT(alenlist != NULL);
-	cursorp = kmem_zone_alloc(alenlist_cursor_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
+	cursorp = snia_kmem_zone_alloc(alenlist_cursor_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
 	if (cursorp) {
 		INCR_COUNT(&alenlist_cursor_count);
 		alenlist_cursor_init(alenlist, 0, cursorp);
@@ -671,7 +670,7 @@
 alenlist_cursor_destroy(alenlist_cursor_t cursorp)
 {
 	DECR_COUNT(&alenlist_cursor_count);
-	kmem_zone_free(alenlist_cursor_zone, cursorp);
+	snia_kmem_zone_free(alenlist_cursor_zone, cursorp);
 }
 
 
@@ -752,7 +751,7 @@
 			maxlength -= 
 			   ((alenp->al_addr + cursorp->al_bcount) & maxlen1);
 
-		length = MIN(maxlength, length);
+		length = min(maxlength, length);
 	}
 
 	/* Update the cursor, if desired. */
@@ -842,7 +841,7 @@
 	offset = poff(kvaddr);
 
 	/* Handle first page */
-	piece_length = MIN(NBPP - offset, length);
+	piece_length = min((size_t)(NBPP - offset), length);
 	if (alenlist_append(alenlist, paddr, piece_length, flags) == ALENLIST_FAILURE)
 		goto failure;
 	length -= piece_length;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/ate_utils.c linux/arch/ia64/sn/io/ate_utils.c
--- linux.orig/arch/ia64/sn/io/ate_utils.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/ate_utils.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,205 @@
+/* $Id: ate_utils.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/io.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/ioerror_handling.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/sn_private.h>
+
+#include <asm/sn/ate_utils.h>
+
+/*
+ * Allocate the map needed to allocate the ATE entries.
+ */
+struct map *
+atemapalloc(ulong_t mapsiz)
+{
+	struct map *mp;
+	ulong_t size;
+	struct a {
+		spinlock_t lock;
+		sv_t 	sema;
+	} *sync;
+
+	if (mapsiz == 0)
+		return(NULL);
+	size = sizeof(struct map) * (mapsiz + 2);
+	if ((mp = (struct map *) kmalloc(size, GFP_KERNEL)) == NULL)
+		return(NULL);
+	memset(mp, 0x0, size);
+
+	sync = kmalloc(sizeof(struct a), GFP_KERNEL);
+	if (sync == NULL) {
+		kfree(mp);
+		return(NULL);
+	}
+	memset(sync, 0x0, sizeof(struct a));
+
+	mutex_spinlock_init(&sync->lock);
+	sv_init( &(sync->sema), &(sync->lock), SV_MON_SPIN | SV_ORDER_FIFO /*| SV_INTS*/);
+	mp[1].m_size = (unsigned long) &sync->lock;
+	mp[1].m_addr = (unsigned long) &sync->sema;
+	mapsize(mp) = mapsiz - 1;
+	return(mp);
+}
+
+/*
+ * free a map structure previously allocated via rmallocmap().
+ */
+void
+atemapfree(struct map *mp)
+{
+	struct a {
+		spinlock_t lock;
+		sv_t 	sema;
+	};
+	/* ASSERT(sv_waitq(mapout(mp)) == 0); */
+	/* sv_destroy(mapout(mp)); */
+	spin_lock_destroy(maplock(mp));
+	kfree((void *)mp[1].m_size);
+	kfree(mp);
+}
+
+/*
+ * Allocate 'size' units from the given map.
+ * Return the base of the allocated space.
+ * In a map, the addresses are increasing and the
+ * list is terminated by a 0 size.
+ * Algorithm is first-fit.
+ */
+
+ulong_t
+atealloc(
+	struct map *mp,
+	size_t size)
+{
+	register unsigned int a;
+	register struct map *bp;
+	register unsigned long s;
+
+	ASSERT(size >= 0);
+
+	if (size == 0)
+		return((ulong_t) NULL);
+
+	s = mutex_spinlock(maplock(mp));
+
+	for (bp = mapstart(mp); bp->m_size; bp++) {
+		if (bp->m_size >= size) {
+			a = bp->m_addr;
+			bp->m_addr += size;
+			if ((bp->m_size -= size) == 0) {
+				do {
+					bp++;
+					(bp-1)->m_addr = bp->m_addr;
+				} while ((((bp-1)->m_size) = (bp->m_size)));
+				mapsize(mp)++;
+			}
+
+			ASSERT(bp->m_size < 0x80000000);
+			mutex_spinunlock(maplock(mp), s);
+			return(a);
+		}
+	}
+
+	/*
+	 * We did not get what we need .. we cannot sleep .. 
+	 */
+	mutex_spinunlock(maplock(mp), s);
+	return(0);
+}
+
+/*
+ * Free the previously allocated space a of size units into the specified map.
+ * Sort ``a'' into map and combine on one or both ends if possible.
+ * Returns 0 on success, 1 on failure.
+ */
+void
+atefree(struct map *mp, size_t size, ulong_t a)
+{
+	register struct map *bp;
+	register unsigned int t;
+	register unsigned long s;
+
+	ASSERT(size >= 0);
+
+	if (size == 0)
+		return;
+
+	bp = mapstart(mp);
+	s = mutex_spinlock(maplock(mp));
+
+	for ( ; bp->m_addr<=a && bp->m_size!=0; bp++)
+		;
+	if (bp>mapstart(mp) && (bp-1)->m_addr+(bp-1)->m_size == a) {
+		(bp-1)->m_size += size;
+		if (bp->m_addr) {	
+			/* m_addr==0 end of map table */
+			ASSERT(a+size <= bp->m_addr);
+			if (a+size == bp->m_addr) { 
+
+				/* compress adjacent map addr entries */
+				(bp-1)->m_size += bp->m_size;
+				while (bp->m_size) {
+					bp++;
+					(bp-1)->m_addr = bp->m_addr;
+					(bp-1)->m_size = bp->m_size;
+				}
+				mapsize(mp)++;
+			}
+		}
+	} else {
+		if (a+size == bp->m_addr && bp->m_size) {
+			bp->m_addr -= size;
+			bp->m_size += size;
+		} else {
+			ASSERT(size);
+			if (mapsize(mp) == 0) {
+				mutex_spinunlock(maplock(mp), s);
+				printk("atefree : map overflow 0x%p Lost 0x%lx items at 0x%lx",
+						(void *)mp, size, a) ;
+				return ;
+			}
+			do {
+				t = bp->m_addr;
+				bp->m_addr = a;
+				a = t;
+				t = bp->m_size;
+				bp->m_size = size;
+				bp++;
+			} while ((size = t));
+			mapsize(mp)--;
+		}
+	}
+	mutex_spinunlock(maplock(mp), s);
+	/*
+	 * wake up everyone waiting for space
+	 */
+	if (mapout(mp))
+		;
+		/* sv_broadcast(mapout(mp)); */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/cdl.c linux/arch/ia64/sn/io/cdl.c
--- linux.orig/arch/ia64/sn/io/cdl.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/cdl.c	2002-07-20 01:08:30.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -17,11 +16,9 @@
 #include "asm/sn/ioerror_handling.h"
 #include <asm/sn/xtalk/xbow.h>
 
-#ifdef BRINGUP
 /* these get called directly in cdl_add_connpt in fops bypass hack */
 extern int pcibr_attach(devfs_handle_t);
 extern int xbow_attach(devfs_handle_t);
-#endif /* BRINGUP */
 
 /*
  *    cdl: Connection and Driver List
@@ -38,8 +35,6 @@
     int (*attach) (devfs_handle_t);
 } dummy_reg;
 
-typedef struct cdl     *cdl_p;
-
 #define MAX_SGI_IO_INFRA_DRVR 4
 struct cdl sgi_infrastructure_drivers[MAX_SGI_IO_INFRA_DRVR] =
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/devsupport.c linux/arch/ia64/sn/io/devsupport.c
--- linux.orig/arch/ia64/sn/io/devsupport.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/devsupport.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1289 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/iobus.h>
-#include <asm/sn/iograph.h>
-
-/* 
- * Interfaces in this file are all platform-independent AND IObus-independent.
- * Be aware that there may be macro equivalents to each of these hiding in
- * header files which supercede these functions.
- */
-
-/* =====Generic iobus support===== */
-
-/* String table to hold names of interrupts. */
-#ifdef LATER
-static struct string_table device_desc_string_table;
-#endif
-
-/* One time initialization for device descriptor support. */
-static void
-device_desc_init(void)
-{
-#ifdef LATER
-	string_table_init(&device_desc_string_table);
-#endif
-	FIXME("device_desc_init");
-}
-
-
-/* Drivers use these interfaces to manage device descriptors */
-static device_desc_t
-device_desc_alloc(void)
-{
-#ifdef LATER
-	device_desc_t device_desc;
-
-	device_desc = (device_desc_t)kmem_zalloc(sizeof(struct device_desc_s), 0);
-	device_desc->intr_target = GRAPH_VERTEX_NONE;
-
-	ASSERT(device_desc->intr_policy == 0);
-	device_desc->intr_swlevel = -1;
-	ASSERT(device_desc->intr_name == NULL);
-	ASSERT(device_desc->flags == 0);
-
-	ASSERT(!(device_desc->flags & D_IS_ASSOC));
-	return(device_desc);
-#else
-	FIXME("device_desc_alloc");
-	return((device_desc_t)0);
-#endif
-}
-
-void
-device_desc_free(device_desc_t device_desc)
-{
-#ifdef LATER
-	if (!(device_desc->flags & D_IS_ASSOC)) /* sanity */
-		kfree(device_desc);
-#endif
-	FIXME("device_desc_free");
-}
-
-device_desc_t
-device_desc_dup(devfs_handle_t dev)
-{
-#ifdef LATER
-	device_desc_t orig_device_desc, new_device_desc;
-
-
-	new_device_desc = device_desc_alloc();
-	orig_device_desc = device_desc_default_get(dev);
-	if (orig_device_desc)
-		*new_device_desc = *orig_device_desc;/* small structure copy */
-	else {
-		device_driver_t		driver;
-		ilvl_t			pri;		
-		/* 
-		 * Use the driver's thread priority in 
-		 * case the device thread priority has not
-		 * been given.
-		 */
-		if (driver = device_driver_getbydev(dev)) {
-			pri = device_driver_thread_pri_get(driver);
-			device_desc_intr_swlevel_set(new_device_desc,pri);
-		}
-	}		
-	new_device_desc->flags &= ~D_IS_ASSOC;
-	return(new_device_desc);
-#else
-	FIXME("device_desc_dup");
-	return((device_desc_t)0);
-#endif
-}
-
-device_desc_t	
-device_desc_default_get(devfs_handle_t dev)
-{
-#ifdef LATER
-	graph_error_t rc;
-	device_desc_t device_desc;
-
-	rc = hwgraph_info_get_LBL(dev, INFO_LBL_DEVICE_DESC, (arbitrary_info_t *)&device_desc);
-
-	if (rc == GRAPH_SUCCESS)
-		return(device_desc);
-	else
-		return(NULL);
-#else
-	FIXME("device_desc_default_get");
-	return((device_desc_t)0);
-#endif
-}
-
-void		
-device_desc_default_set(devfs_handle_t dev, device_desc_t new_device_desc)
-{
-#ifdef LATER
-	graph_error_t rc;
-	device_desc_t old_device_desc = NULL;
-
-	if (new_device_desc) {
-		new_device_desc->flags |= D_IS_ASSOC;
-		rc = hwgraph_info_add_LBL(dev, INFO_LBL_DEVICE_DESC, 
-						(arbitrary_info_t)new_device_desc);
-		if (rc == GRAPH_DUP) {
-			rc = hwgraph_info_replace_LBL(dev, INFO_LBL_DEVICE_DESC, 
-				(arbitrary_info_t)new_device_desc, 
-				(arbitrary_info_t *)&old_device_desc);
-
-			ASSERT(rc == GRAPH_SUCCESS);
-		}
-		hwgraph_info_export_LBL(dev, INFO_LBL_DEVICE_DESC,
-					sizeof(struct device_desc_s));
-	} else {
-		rc = hwgraph_info_remove_LBL(dev, INFO_LBL_DEVICE_DESC,
-					(arbitrary_info_t *)&old_device_desc);
-	}
-
-	if (old_device_desc) {
-		ASSERT(old_device_desc->flags & D_IS_ASSOC);
-		old_device_desc->flags &= ~D_IS_ASSOC;
-		device_desc_free(old_device_desc);
-	}
-#endif
-	FIXME("device_desc_default_set");
-}
-
-devfs_handle_t
-device_desc_intr_target_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->intr_target);
-#else
-	FIXME("device_desc_intr_target_get");
-	return((devfs_handle_t)0);
-#endif
-}
-
-int
-device_desc_intr_policy_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->intr_policy);
-#else
-	FIXME("device_desc_intr_policy_get");
-	return(0);
-#endif
-}
-
-ilvl_t
-device_desc_intr_swlevel_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->intr_swlevel);
-#else
-	FIXME("device_desc_intr_swlevel_get");
-	return((ilvl_t)0);
-#endif
-}
-
-char *
-device_desc_intr_name_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->intr_name);
-#else
-	FIXME("device_desc_intr_name_get");
-	return(NULL);
-#endif
-}
-
-int
-device_desc_flags_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->flags);
-#else
-	FIXME("device_desc_flags_get");
-	return(0);
-#endif
-}
-
-void
-device_desc_intr_target_set(device_desc_t device_desc, devfs_handle_t target)
-{
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->intr_target = target;
-}
-
-void
-device_desc_intr_policy_set(device_desc_t device_desc, int policy)
-{
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->intr_policy = policy;
-}
-
-void
-device_desc_intr_swlevel_set(device_desc_t device_desc, ilvl_t swlevel)
-{
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->intr_swlevel = swlevel;
-}
-
-void
-device_desc_intr_name_set(device_desc_t device_desc, char *name)
-{
-#ifdef LATER
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->intr_name = string_table_insert(&device_desc_string_table, name);
-#else
-	FIXME("device_desc_intr_name_set");
-#endif
-}
-
-void
-device_desc_flags_set(device_desc_t device_desc, int flags)
-{
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->flags = flags;
-}
-
-
-
-/*============= device admin registry routines ===================== */
-
-/* Linked list of <admin-name,admin-val> pairs */
-typedef struct dev_admin_list_s {
-	struct dev_admin_list_s		*admin_next; 	/* next entry in the
-							 * list 
-							 */
-	char				*admin_name;	/* info label */
-	char				*admin_val;	/* actual info */
-} dev_admin_list_t;
-
-/* Device/Driver administration registry */
-typedef struct dev_admin_registry_s {
-	mrlock_t			reg_lock;	/* To allow
-							 * exclusive
-							 * access
-							 */
-	dev_admin_list_t		*reg_first;	/* first entry in 
-							 * the list
-							 */
-	dev_admin_list_t		**reg_last;	/* pointer to the
-							 * next to last entry
-							 * in the last which 
-							 * is also the place
-							 * where the new
-							 * entry gets
-							 * inserted
-							 */
-} dev_admin_registry_t;
-
-/*
-** device_driver_s associates a device driver prefix with device switch entries.
-*/
-struct device_driver_s {
-	struct device_driver_s	*dd_next;	/* next element on hash chain */
-	struct device_driver_s	*dd_prev;	/* previous element on hash chain */
-	char			*dd_prefix;	/* driver prefix string */
-	struct bdevsw		*dd_bdevsw;	/* driver's bdevsw */
-	struct cdevsw		*dd_cdevsw;	/* driver's cdevsw */
-	
-	/* driver administration specific data structures need to
-	 * maintain the list of <driver-paramater,value> pairs
-	 */
-	dev_admin_registry_t	dd_dev_admin_registry;
-	ilvl_t			dd_thread_pri;	/* default thread priority for
-						 *  all this driver's
-						 * threads.
-						 */
-
-};
-
-#define	NEW(_p)		(_p = kmalloc(sizeof(*_p), GFP_KERNEL))
-#define FREE(_p)	(kmem_free(_p))
-	
-/*
- * helpful lock macros
- */
-
-#define DEV_ADMIN_REGISTRY_INITLOCK(lockp,name)	mrinit(lockp,name)
-#define DEV_ADMIN_REGISTRY_RDLOCK(lockp)	mraccess(lockp)	       
-#define DEV_ADMIN_REGISTRY_WRLOCK(lockp)	mrupdate(lockp)	       
-#define DEV_ADMIN_REGISTRY_UNLOCK(lockp)	mrunlock(lockp)
-
-/* Initialize the registry 
- */
-static void
-dev_admin_registry_init(dev_admin_registry_t *registry)
-{
-#ifdef LATER
-	if ( registry != (dev_admin_registry_t *)0 )
-		DEV_ADMIN_REGISTRY_INITLOCK(&registry->reg_lock,
-				    "dev_admin_registry_lock");
-		registry->reg_first = NULL;
-		registry->reg_last = &registry->reg_first;
-	}
-#else
-	FIXME("dev_admin_registry_init");
-#endif
-}
-
-/*
- * add an <name , value > entry to the dev admin registry.
- * if the name already exists in the registry then change the
- * value iff the new value differs from the old value.
- * if the name doesn't exist a new list entry is created and put
- * at the end.
- */
-static void
-dev_admin_registry_add(dev_admin_registry_t	*registry,
-		       char			*name,
-		       char			*val)
-{
-#ifdef LATER
-	dev_admin_list_t	*reg_entry;
-	dev_admin_list_t	*scan = 0;
-
-	DEV_ADMIN_REGISTRY_WRLOCK(&registry->reg_lock);
-
-	/* check if the name already exists in the registry */
-	scan = registry->reg_first;
-
-	while (scan) {
-		if (strcmp(scan->admin_name,name) == 0) {
-			/* name is there in the registry */
-			if (strcmp(scan->admin_val,val)) {
-				/* old value != new value 
-				 * reallocate  memory and copy the new value
-				 */
-				FREE(scan->admin_val);
-				scan->admin_val = 
-					(char *)kern_calloc(1,strlen(val)+1);
-				strcpy(scan->admin_val,val);
-				goto out;
-			}
-			goto out;	/* old value == new value */
-		}
-		scan = scan->admin_next;
-	}
-
-	/* name is not there in the registry.
-	 * allocate memory for the new registry entry 
-	 */
-	NEW(reg_entry);
-	
-	reg_entry->admin_next   	= 0;
-	reg_entry->admin_name	= (char *)kern_calloc(1,strlen(name)+1);
-	strcpy(reg_entry->admin_name,name);
-	reg_entry->admin_val	= (char *)kern_calloc(1,strlen(val)+1);
-	strcpy(reg_entry->admin_val,val);
-
-	/* add the entry at the end of the registry */
-
-	*(registry->reg_last)	= reg_entry;
-	registry->reg_last	= &reg_entry->admin_next;
-
-out:	DEV_ADMIN_REGISTRY_UNLOCK(&registry->reg_lock);
-#endif
-	FIXME("dev_admin_registry_add");
-}
-/*
- * check if there is an info corr. to a particular
- * name starting from the cursor position in the 
- * registry
- */
-static char *
-dev_admin_registry_find(dev_admin_registry_t *registry,char *name)
-{
-#ifdef LATER
-	dev_admin_list_t	*scan = 0;
-	
-	DEV_ADMIN_REGISTRY_RDLOCK(&registry->reg_lock);
-	scan = registry->reg_first;
-
-	while (scan) {
-		if (strcmp(scan->admin_name,name) == 0) {
-			DEV_ADMIN_REGISTRY_UNLOCK(&registry->reg_lock);
-			return scan->admin_val;
-		}
-		scan = scan->admin_next;
-	}
-	DEV_ADMIN_REGISTRY_UNLOCK(&registry->reg_lock);
-	return 0;
-#else
-	FIXME("dev_admin_registry_find");
-	return(NULL);
-#endif
-}
-/*============= MAIN DEVICE/ DRIVER ADMINISTRATION INTERFACE================ */
-/*
- * return any labelled info associated with a device.
- * called by any kernel code including device drivers.
- */
-char *
-device_admin_info_get(devfs_handle_t	dev_vhdl,
-		      char		*info_lbl)
-{
-#ifdef LATER
-	char		*info = 0;
-
-	/* return value need not be GRAPH_SUCCESS as the labelled
-	 * info may not be present
-	 */
-	(void)hwgraph_info_get_LBL(dev_vhdl,info_lbl,
-				   (arbitrary_info_t *)&info);
-
-	
-	return info;
-#else
-	FIXME("device_admin_info_get");
-	return(NULL);
-#endif
-}
-
-/*
- * set labelled info associated with a device.
- * called by hwgraph infrastructure . may also be called
- * by device drivers etc.
- */
-int
-device_admin_info_set(devfs_handle_t	dev_vhdl,
-		      char		*dev_info_lbl,
-		      char		*dev_info_val)
-{
-#ifdef LATER
-	graph_error_t		rv;
-	arbitrary_info_t	old_info;
-
-	/* Handle the labelled info
-	 *		intr_target
-	 *		sw_level 
-	 * in a special way. These are part of device_desc_t
-	 * Right now this is the only case where we have 
-	 * a set of related device_admin attributes which 
-	 * are grouped together.
-	 * In case there is a need for another set we need to
-	 * take a more generic approach to solving this.
-	 * Basically a registry should be implemented. This
-	 * registry is initialized with the callbacks for the
-	 * attributes which need to handled in a special way
-	 * For example:
-	 * Consider
-	 * 		device_desc
-	 *			intr_target
-	 *			intr_swlevel
-	 * register "do_intr_target" for intr_target
-	 * register "do_intr_swlevel" for intr_swlevel.
-	 * When the device_admin interface layer gets an <attr,val> pair
-	 * it looks in the registry to see if there is a function registered to
-	 * handle "attr. If not follow the default path of setting the <attr,val>
-	 * as labelled information hanging off the vertex.
-	 * In the above example:
-	 * "do_intr_target" does what is being done below for the ADMIN_LBL_INTR_TARGET
-	 * case
-	 */		
-	if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_TARGET) ||
-	    !strcmp(dev_info_lbl,ADMIN_LBL_INTR_SWLEVEL)) {
-
-		device_desc_t	device_desc;
-		
-		/* Check if there is a default device descriptor
-		 * information for this vertex. If not dup one .
-		 */
-		if (!(device_desc = device_desc_default_get(dev_vhdl))) {
-			device_desc = device_desc_dup(dev_vhdl);
-			device_desc_default_set(dev_vhdl,device_desc);
-
-		}
-		if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_TARGET)) {
-			/* Check if a target cpu has been specified
-			 * for this device by a device administration
-			 * directive
-			 */
-#ifdef DEBUG	
-			printf(ADMIN_LBL_INTR_TARGET
-			       " dev = 0x%x "
-			       "dev_admin_info = %s"
-			       " target = 0x%x\n",
-			       dev_vhdl,
-			       dev_info_lbl,
-			       hwgraph_path_to_vertex(dev_info_val));
-#endif	
-
-			device_desc->intr_target = 
-				hwgraph_path_to_vertex(dev_info_val);
-		} else if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_SWLEVEL)) {
-			/* Check if the ithread priority level  has been 
-			 * specified for this device by a device administration
-			 * directive
-			 */
-#ifdef DEBUG	
-			printf(ADMIN_LBL_INTR_SWLEVEL
-			       " dev = 0x%x "
-			       "dev_admin_info = %s"
-			       " sw level = 0x%x\n",
-			       dev_vhdl,
-			       dev_info_lbl,
-			       atoi(dev_info_val));
-#endif	
-			device_desc->intr_swlevel = atoi(dev_info_val);
-		}
-
-	}
-	if (!dev_info_val)
-		rv = hwgraph_info_remove_LBL(dev_vhdl,
-					     dev_info_lbl,
-					     &old_info);
-	else {
-
-		rv = hwgraph_info_add_LBL(dev_vhdl,
-					  dev_info_lbl,
-					  (arbitrary_info_t)dev_info_val);
-	
-		if (rv == GRAPH_DUP)  {
-			rv = hwgraph_info_replace_LBL(dev_vhdl,
-					      dev_info_lbl,
-					      (arbitrary_info_t)dev_info_val,
-					      &old_info);
-		}
-	}
-	ASSERT(rv == GRAPH_SUCCESS);
-#endif
-	FIXME("device_admin_info_set");
-	return 0;
-}
-
-/*
- * return labelled info associated with a device driver
- * called by kernel code including device drivers
- */
-char *
-device_driver_admin_info_get(char		*driver_prefix,
-			     char		*driver_info_lbl)
-{
-#ifdef LATER
-	device_driver_t driver;
-
-	driver = device_driver_get(driver_prefix);
-	return (dev_admin_registry_find(&driver->dd_dev_admin_registry,
-					driver_info_lbl));
-#else
-	FIXME("device_driver_admin_info_get");
-	return(NULL);
-#endif
-}
-
-/*
- * set labelled info associated with a device driver.
- * called by hwgraph infrastructure . may also be called
- * from drivers etc.
- */
-int
-device_driver_admin_info_set(char		*driver_prefix,
-			     char		*driver_info_lbl,
-			     char		*driver_info_val)
-{
-#ifdef LATER
-	device_driver_t driver;
-
-	driver = device_driver_get(driver_prefix);
-	dev_admin_registry_add(&driver->dd_dev_admin_registry,	
-			       driver_info_lbl,
-			       driver_info_val);
-#endif
-	FIXME("device_driver_admin_info_set");
-	return 0;
-}
-/*================== device / driver  admin support routines================*/
-
-/* static tables created by lboot */
-extern dev_admin_info_t	dev_admin_table[];
-extern dev_admin_info_t	drv_admin_table[];
-extern int		dev_admin_table_size;
-extern int		drv_admin_table_size;
-
-/* Extend the device admin table to allow the kernel startup code to 
- * provide some device specific administrative hints
- */
-#define ADMIN_TABLE_CHUNK	100
-static dev_admin_info_t extended_dev_admin_table[ADMIN_TABLE_CHUNK];	
-static int		extended_dev_admin_table_size = 0;
-static mrlock_t		extended_dev_admin_table_lock;
-
-/* Initialize the extended device admin table */
-void
-device_admin_table_init(void)
-{
-#ifdef LATER
-	extended_dev_admin_table_size = 0;
-	mrinit(&extended_dev_admin_table_lock,
-	       "extended_dev_admin_table_lock");
-#endif
-	FIXME("device_admin_table_init");
-}
-/* Add <device-name , parameter-name , parameter-value> triple to
- * the extended device administration info table. This is helpful
- * for kernel startup code to put some hints before the hwgraph
- * is setup 
- */
-void
-device_admin_table_update(char *name,char *label,char *value)
-{
-#ifdef LATER
-	dev_admin_info_t	*p;
-
-	mrupdate(&extended_dev_admin_table_lock);
-
-	/* Safety check that we haven't exceeded array limits */
-	ASSERT(extended_dev_admin_table_size < ADMIN_TABLE_CHUNK);
-
-	if (extended_dev_admin_table_size == ADMIN_TABLE_CHUNK)
-		goto out;
-	
-	/* Get the pointer to the entry in the table where we are
-	 * going to put the new information 
-	 */
-	p = &extended_dev_admin_table[extended_dev_admin_table_size++];
-
-	/* Allocate memory for the strings and copy them in */
-	p->dai_name = (char *)kern_calloc(1,strlen(name)+1);
-	strcpy(p->dai_name,name);
-	p->dai_param_name = (char *)kern_calloc(1,strlen(label)+1);
-	strcpy(p->dai_param_name,label);
-	p->dai_param_val = (char *)kern_calloc(1,strlen(value)+1);
-	strcpy(p->dai_param_val,value);
-
-out:	mrunlock(&extended_dev_admin_table_lock);
-#endif
-	FIXME("device_admin_table_update");
-}
-/* Extend the device driver  admin table to allow the kernel startup code to 
- * provide some device driver specific administrative hints
- */
-
-static dev_admin_info_t extended_drv_admin_table[ADMIN_TABLE_CHUNK];	
-static int		extended_drv_admin_table_size = 0;
-mrlock_t		extended_drv_admin_table_lock;
-
-/* Initialize the extended device driver admin table */
-void
-device_driver_admin_table_init(void)
-{
-#ifdef LATER
-	extended_drv_admin_table_size = 0;
-	mrinit(&extended_drv_admin_table_lock,
-	       "extended_drv_admin_table_lock");
-#endif
-	FIXME("device_driver_admin_table_init");
-}
-/* Add <device-driver prefix , parameter-name , parameter-value> triple to
- * the extended device administration info table. This is helpful
- * for kernel startup code to put some hints before the hwgraph
- * is setup 
- */
-void
-device_driver_admin_table_update(char *name,char *label,char *value)
-{
-#ifdef LATER
-	dev_admin_info_t	*p;
-
-	mrupdate(&extended_dev_admin_table_lock);
-
-	/* Safety check that we haven't exceeded array limits */
-	ASSERT(extended_drv_admin_table_size < ADMIN_TABLE_CHUNK);
-
-	if (extended_drv_admin_table_size == ADMIN_TABLE_CHUNK)
-		goto out;
-	
-	/* Get the pointer to the entry in the table where we are
-	 * going to put the new information 
-	 */
-	p = &extended_drv_admin_table[extended_drv_admin_table_size++];
-
-	/* Allocate memory for the strings and copy them in */
-	p->dai_name = (char *)kern_calloc(1,strlen(name)+1);
-	strcpy(p->dai_name,name);
-	p->dai_param_name = (char *)kern_calloc(1,strlen(label)+1);
-	strcpy(p->dai_param_name,label);
-	p->dai_param_val = (char *)kern_calloc(1,strlen(value)+1);
-	strcpy(p->dai_param_val,value);
-
-out:	mrunlock(&extended_drv_admin_table_lock);
-#endif
-	FIXME("device_driver_admin_table_update");
-}
-/*
- * keeps on adding the labelled info for each new (lbl,value) pair
- * that it finds in the static dev admin table (  created by lboot)
- * and the extended dev admin table ( created if at all by the kernel startup
- *  code) corresponding to a device in the hardware graph.
- */
-void
-device_admin_info_update(devfs_handle_t	dev_vhdl)
-{
-#ifdef LATER
-	int			i = 0;
-	dev_admin_info_t	*scan;
-	devfs_handle_t		scan_vhdl;
-	
-	/* Check the static device administration info table */
-	scan = dev_admin_table;
-	while (i < dev_admin_table_size) {
-		
-		scan_vhdl = hwgraph_path_to_dev(scan->dai_name);
-		if (scan_vhdl == dev_vhdl) {
-			device_admin_info_set(dev_vhdl,
-					      scan->dai_param_name,
-					      scan->dai_param_val);
-		}
-		if (scan_vhdl != NODEV)
-			hwgraph_vertex_unref(scan_vhdl);
-		scan++;i++;
-
-	}
-	i = 0;
-	/* Check the extended device administration info table */
-	scan = extended_dev_admin_table;
-	while (i < extended_dev_admin_table_size) {
-		scan_vhdl = hwgraph_path_to_dev(scan->dai_name);
-		if (scan_vhdl == dev_vhdl) {
-			device_admin_info_set(dev_vhdl,
-					      scan->dai_param_name,
-					      scan->dai_param_val);
-		}
-		if (scan_vhdl != NODEV)
-			hwgraph_vertex_unref(scan_vhdl);
-		scan++;i++;
-
-	}
-
-
-#endif
-	FIXME("device_admin_info_update");
-}
-
-/* looks up the static drv admin table ( created by the lboot) and the extended
- * drv admin table (created if at all by the kernel startup code) 
- * for this driver specific administration info and adds it to the admin info 
- * associated with this device driver's object
- */
-void
-device_driver_admin_info_update(device_driver_t	driver)
-{
-#ifdef LATER
-	int			i = 0;
-	dev_admin_info_t	*scan;
-
-	/* Check the static device driver administration info table */
-	scan = drv_admin_table;
-	while (i < drv_admin_table_size) {
-
-		if (strcmp(scan->dai_name,driver->dd_prefix) == 0) {
-			dev_admin_registry_add(&driver->dd_dev_admin_registry,
-						scan->dai_param_name,
-					 	scan->dai_param_val);
-		}
-		scan++;i++;
-	}
-	i = 0;
-	/* Check the extended device driver administration info table */
-	scan = extended_drv_admin_table;
-	while (i < extended_drv_admin_table_size) {
-
-		if (strcmp(scan->dai_name,driver->dd_prefix) == 0) {
-			dev_admin_registry_add(&driver->dd_dev_admin_registry,
-						scan->dai_param_name,
-					 	scan->dai_param_val);
-		}
-		scan++;i++;
-	}
-#endif
-	FIXME("device_driver_admin_info_update");
-}
-
-/* =====Device Driver Support===== */
-
-
-
-/*
-** Generic device driver support routines for use by kernel modules that
-** deal with device drivers (but NOT for use by the drivers themselves).
-** EVERY registered driver currently in the system -- static or loadable --
-** has an entry in the device_driver_hash table.  A pointer to such an entry
-** serves as a generic device driver handle.
-*/
-
-#define DEVICE_DRIVER_HASH_SIZE 32
-#ifdef LATER
-lock_t device_driver_lock[DEVICE_DRIVER_HASH_SIZE];
-device_driver_t device_driver_hash[DEVICE_DRIVER_HASH_SIZE];
-static struct string_table driver_prefix_string_table;
-#endif
-
-/*
-** Initialize device driver infrastructure.
-*/
-void
-device_driver_init(void)
-{
-#ifdef LATER
-	int i;
-	extern void alenlist_init(void);
-	extern void hwgraph_init(void);
-	extern void device_desc_init(void);
-
-	ASSERT(DEVICE_DRIVER_NONE == NULL);
-	alenlist_init();
-	hwgraph_init();
-	device_desc_init();
-
-	string_table_init(&driver_prefix_string_table);
-
-	for (i=0; i<DEVICE_DRIVER_HASH_SIZE; i++) {
-		spin_lock_init(&device_driver_lock[i]);
-		device_driver_hash[i] = NULL;
-	}
-
-	/* Initialize static drivers from master.c table */
-	for (i=0; i<static_devsw_count; i++) {
-		device_driver_t driver;
-		static_device_driver_desc_t desc;
-		int pri;
-
-		desc = &static_device_driver_table[i];
-		driver = device_driver_get(desc->sdd_prefix);
-		if (!driver)
-			driver = device_driver_alloc(desc->sdd_prefix);
-		pri = device_driver_sysgen_thread_pri_get(desc->sdd_prefix);
-		device_driver_thread_pri_set(driver, pri);
-		device_driver_devsw_put(driver, desc->sdd_bdevsw, desc->sdd_cdevsw);
-	}
-#endif
-	FIXME("device_driver_init");
-}
-
-/*
-** Hash a prefix string into a hash table chain.
-*/
-static int
-driver_prefix_hash(char *prefix)
-{
-#ifdef LATER
-	int accum = 0;
-	char nextchar;
-
-	while (nextchar = *prefix++)
-		accum = accum ^ nextchar;
-
-	return(accum % DEVICE_DRIVER_HASH_SIZE);
-#else
-	FIXME("driver_prefix_hash");
-	return(0);
-#endif
-}
-
-
-/*
-** Allocate a driver handle.
-** Returns the driver handle, or NULL if the driver prefix 
-** already has a handle.
-** 
-** Upper layers prevent races among device_driver_alloc,
-** device_driver_free, and device_driver_get*.
-*/
-device_driver_t
-device_driver_alloc(char *prefix)
-{
-#ifdef LATER
-	int which_hash;
-	device_driver_t new_driver;
-	unsigned long s;
-		
-	which_hash = driver_prefix_hash(prefix);
-
-	new_driver = kern_calloc(1, sizeof(*new_driver));
-	ASSERT(new_driver != NULL);
-	new_driver->dd_prev = NULL;
-	new_driver->dd_prefix = string_table_insert(&driver_prefix_string_table, prefix);
-	new_driver->dd_bdevsw = NULL;
-	new_driver->dd_cdevsw = NULL;
-
-	dev_admin_registry_init(&new_driver->dd_dev_admin_registry);
-	device_driver_admin_info_update(new_driver);
-
-	s = mutex_spinlock(&device_driver_lock[which_hash]);
-
-#if DEBUG
-	{
-		device_driver_t drvscan;
-
-		/* Make sure we haven't already added a driver with this prefix */
-		drvscan = device_driver_hash[which_hash];
-		while (drvscan && 
-		        strcmp(drvscan->dd_prefix, prefix)) {
-			drvscan = drvscan->dd_next;
-		}
-
-		ASSERT(!drvscan);
-	}
-#endif /* DEBUG */
-
-
-	/* Add new_driver to front of hash chain. */
-	new_driver->dd_next = device_driver_hash[which_hash];
-	if (new_driver->dd_next)
-		new_driver->dd_next->dd_prev = new_driver;
-	device_driver_hash[which_hash] = new_driver;
-
-	mutex_spinunlock(&device_driver_lock[which_hash], s);
-
-	return(new_driver);
-#else
-	FIXME("device_driver_alloc");
-	return((device_driver_t)0);
-#endif
-}
-
-/*
-** Free a driver handle.
-**
-** Statically loaded drivers should never device_driver_free.
-** Dynamically loaded drivers device_driver_free when either an
-** unloaded driver is unregistered, or when an unregistered driver
-** is unloaded.
-*/
-void
-device_driver_free(device_driver_t driver)
-{
-#ifdef LATER
-	int which_hash;
-	unsigned long s;
-
-	if (!driver)
-		return;
-
-	which_hash = driver_prefix_hash(driver->dd_prefix);
-
-	s = mutex_spinlock(&device_driver_lock[which_hash]);
-
-#if DEBUG
-	{
-		device_driver_t drvscan;
-
-		/* Make sure we're dealing with the right list */
-		drvscan = device_driver_hash[which_hash];
-		while (drvscan && (drvscan != driver))
-			drvscan = drvscan->dd_next;
-
-		ASSERT(drvscan);
-	}
-#endif /* DEBUG */
-
-	if (driver->dd_next)
-		driver->dd_next->dd_prev = driver->dd_prev;
-
-	if (driver->dd_prev)
-		driver->dd_prev->dd_next = driver->dd_next;
-	else
-		device_driver_hash[which_hash] = driver->dd_next;
-
-	mutex_spinunlock(&device_driver_lock[which_hash], s);
-
-	driver->dd_next = NULL;		/* sanity */
-	driver->dd_prev = NULL;		/* sanity */
-	driver->dd_prefix = NULL;	/* sanity */
-
-	if (driver->dd_bdevsw) {
-		driver->dd_bdevsw->d_driver = NULL;
-		driver->dd_bdevsw = NULL;
-	}
-
-	if (driver->dd_cdevsw) {
-		if (driver->dd_cdevsw->d_str) {
-			str_free_mux_node(driver);
-		}
-		driver->dd_cdevsw->d_driver = NULL;
-		driver->dd_cdevsw = NULL;
-	}
-
-	kern_free(driver);
-#endif
-	FIXME("device_driver_free");
-}
-
-
-/*
-** Given a device driver prefix, return a handle to the caller.
-*/
-device_driver_t
-device_driver_get(char *prefix)
-{
-#ifdef LATER
-	int which_hash;
-	device_driver_t drvscan;
-	unsigned long s;
-
-	if (prefix == NULL)
-		return(NULL);
-		
-	which_hash = driver_prefix_hash(prefix);
-
-	s = mutex_spinlock(&device_driver_lock[which_hash]);
-
-	drvscan = device_driver_hash[which_hash];
-	while (drvscan && strcmp(drvscan->dd_prefix, prefix))
-		drvscan = drvscan->dd_next;
-
-	mutex_spinunlock(&device_driver_lock[which_hash], s);
-
-	return(drvscan);
-#else
-	FIXME("device_driver_get");
-	return((device_driver_t)0);
-#endif
-}
-
-
-/*
-** Given a block or char special file devfs_handle_t, find the 
-** device driver that controls it.
-*/
-device_driver_t
-device_driver_getbydev(devfs_handle_t device)
-{
-#ifdef LATER
-	struct bdevsw *my_bdevsw;
-	struct cdevsw *my_cdevsw;
-
-	my_cdevsw = get_cdevsw(device);
-	if (my_cdevsw != NULL)
-		return(my_cdevsw->d_driver);
-
-	my_bdevsw = get_bdevsw(device);
-	if (my_bdevsw != NULL)
-		return(my_bdevsw->d_driver);
-
-#endif
-	FIXME("device_driver_getbydev");
-	return((device_driver_t)0);
-}
-
-
-/*
-** Associate a driver with bdevsw/cdevsw pointers.
-**
-** Statically loaded drivers are permanently and automatically associated
-** with the proper bdevsw/cdevsw.  Dynamically loaded drivers associate
-** themselves when the driver is registered, and disassociate when the
-** driver unregisters.
-**
-** Returns 0 on success, -1 on failure (devsw already associated with driver)
-*/
-int
-device_driver_devsw_put(device_driver_t driver,
-			struct bdevsw *my_bdevsw,
-			struct cdevsw *my_cdevsw)
-{
-#ifdef LATER
-	int i;
-
-	if (!driver)
-		return(-1);
-
-	/* Trying to re-register data?  */
-	if (((my_bdevsw != NULL) && (driver->dd_bdevsw != NULL)) ||
-	    ((my_cdevsw != NULL) && (driver->dd_cdevsw != NULL)))
-		return(-1);
-
-	if (my_bdevsw != NULL) {
-		driver->dd_bdevsw = my_bdevsw;
-		my_bdevsw->d_driver = driver;
-		for (i = 0; i < bdevmax; i++) {
-			if (driver->dd_bdevsw->d_flags == bdevsw[i].d_flags) {
-				bdevsw[i].d_driver = driver;
-				break;
-			}
-		}
-	}
-
-	if (my_cdevsw != NULL) {
-		driver->dd_cdevsw = my_cdevsw;
-		my_cdevsw->d_driver = driver;
-		for (i = 0; i < cdevmax; i++) {
-			if (driver->dd_cdevsw->d_flags == cdevsw[i].d_flags) {
-				cdevsw[i].d_driver = driver;
-				break;
-			}
-		}
-	}
-#endif
-	FIXME("device_driver_devsw_put");
-	return(0);
-}
-
-
-/*
-** Given a driver, return the corresponding bdevsw and cdevsw pointers.
-*/
-void
-device_driver_devsw_get(	device_driver_t driver, 
-				struct bdevsw **bdevswp,
-				struct cdevsw **cdevswp)
-{
-	if (!driver) {
-		*bdevswp = NULL;
-		*cdevswp = NULL;
-	} else {
-		*bdevswp = driver->dd_bdevsw;
-		*cdevswp = driver->dd_cdevsw;
-	}
-}
-
-/*
- * device_driver_thread_pri_set
- *	Given a driver try to set its thread priority.
- *	Returns 0 on success , -1 on failure.
- */ 
-int
-device_driver_thread_pri_set(device_driver_t driver,ilvl_t pri)
-{
-	if (!driver)
-		return(-1);
-	driver->dd_thread_pri = pri;
-	return(0);
-}
-/*
- * device_driver_thread_pri_get
- * 	Given a driver return the driver thread priority.
- * 	If the driver is NULL return invalid driver thread
- * 	priority.
- */
-ilvl_t
-device_driver_thread_pri_get(device_driver_t driver)
-{
-	if (driver)
-		return(driver->dd_thread_pri);
-	else
-		return(DRIVER_THREAD_PRI_INVALID);
-}
-/*
-** Given a device driver, return it's handle (prefix).
-*/
-void
-device_driver_name_get(device_driver_t driver, char *buffer, int length)
-{
-	if (driver == NULL)
-		return;
-
-	strncpy(buffer, driver->dd_prefix, length);
-}
-
-
-/*
-** Associate a pointer-sized piece of information with a device.
-*/
-void 
-device_info_set(devfs_handle_t device, void *info)
-{
-#ifdef LATER
-	hwgraph_fastinfo_set(device, (arbitrary_info_t)info);
-#endif
-	FIXME("device_info_set");
-}
-
-
-/*
-** Retrieve a pointer-sized piece of information associated with a device.
-*/
-void *
-device_info_get(devfs_handle_t device)
-{
-#ifdef LATER
-	return((void *)hwgraph_fastinfo_get(device));
-#else
-	FIXME("device_info_get");
-	return(NULL);
-#endif
-}
-
-/*
- * Find the thread priority for a device, from the various
- * sysgen files.
- */
-int
-device_driver_sysgen_thread_pri_get(char *dev_prefix)
-{
-#ifdef LATER
-	int pri;
-	char *pri_s;
-	char *class;
-
-	extern default_intr_pri;
-	extern disk_intr_pri;
-	extern serial_intr_pri;
-	extern parallel_intr_pri;
-	extern tape_intr_pri;
-	extern graphics_intr_pri;
-	extern network_intr_pri;
-	extern scsi_intr_pri;
-	extern audio_intr_pri;
-	extern video_intr_pri;
-	extern external_intr_pri;
-	extern tserialio_intr_pri;
-
-	/* Check if there is a thread priority specified for
-	 * this driver's thread thru admin hints. If so 
-	 * use that value. Otherwise set it to its default
-	 * class value, otherwise set it to the default
-	 * value.
-	 */
-
-	if (pri_s = device_driver_admin_info_get(dev_prefix,
-						ADMIN_LBL_THREAD_PRI)) {
-		pri = atoi(pri_s);
-	} else if (class = device_driver_admin_info_get(dev_prefix,
-						ADMIN_LBL_THREAD_CLASS)) {
-		if (strcmp(class, "disk") == 0)
-			pri = disk_intr_pri;
-		else if (strcmp(class, "serial") == 0)
-			pri = serial_intr_pri;
-		else if (strcmp(class, "parallel") == 0)
-			pri = parallel_intr_pri;
-		else if (strcmp(class, "tape") == 0)
-			pri = tape_intr_pri;
-		else if (strcmp(class, "graphics") == 0)
-			pri = graphics_intr_pri;
-		else if (strcmp(class, "network") == 0)
-			pri = network_intr_pri;
-		else if (strcmp(class, "scsi") == 0)
-			pri = scsi_intr_pri;
-		else if (strcmp(class, "audio") == 0)
-			pri = audio_intr_pri;
-		else if (strcmp(class, "video") == 0)
-			pri = video_intr_pri;
-		else if (strcmp(class, "external") == 0)
-			pri = external_intr_pri;
-		else if (strcmp(class, "tserialio") == 0)
-			pri = tserialio_intr_pri;
-		else
-			pri = default_intr_pri;
-	} else
-		pri = default_intr_pri;
-
-	if (pri > 255)
-		pri = 255;
-	else if (pri < 0)
-		pri = 0;
-	return pri;
-#else
-	FIXME("device_driver_sysgen_thread_pri_get");
-	return(-1);
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/eeprom.c linux/arch/ia64/sn/io/eeprom.c
--- linux.orig/arch/ia64/sn/io/eeprom.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/eeprom.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,14 +1,11 @@
 /*
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
+ * Copyright (C) 1999-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
-
 /*
  * WARNING:     There is more than one copy of this file in different isms.
  *              All copies must be kept exactly in sync.
@@ -28,37 +25,24 @@
  *
  */
 
-/**************************************************************************
- *                                                                        *
- *  Copyright (C) 1999 Silicon Graphics, Inc.                             *
- *                                                                        *
- *  These coded instructions, statements, and computer programs  contain  *
- *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
- *  are protected by Federal copyright law.  They  may  not be disclosed  *
- *  to  third  parties  or copied or duplicated in any form, in whole or  *
- *  in part, without the prior written consent of Silicon Graphics, Inc.  *
- *                                                                        *
- **************************************************************************
- */
-
-
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
 #include <asm/sn/labelcl.h>
 #include <asm/sn/eeprom.h>
-#include <asm/sn/ksys/i2c.h>
-/* #include <sys/SN/SN1/ip27log.h> */
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
 #include <asm/sn/nodepda.h>
 #include <asm/sn/clksupport.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/simulator.h>
 
 #if defined(EEPROM_DEBUG)
 #define db_printf(x) printk x
@@ -384,9 +368,6 @@
 
 int cbrick_uid_get( nasid_t nasid, uint64_t *uid )
 {
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
     char uid_str[32];
     char msg[BRL1_QSIZE];
     int subch, len;
@@ -421,7 +402,7 @@
     }
     else {
 	scp = &sc;
-	sc_init( &sc, nasid, BRL1_LOCALUART );
+	sc_init( &sc, nasid, BRL1_LOCALHUB_UART );
     }
 
     /* fill in msg with the opcode & params */
@@ -455,15 +436,11 @@
     *uid = generate_unique_id( uid_str, strlen( uid_str ) );
 
     return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
 
 
 int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid )
 {
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
     char uid_str[32];
     char msg[BRL1_QSIZE];
     int subch, len;
@@ -472,14 +449,12 @@
     if ( IS_RUNNING_ON_SIMULATOR() )
 	return EEP_L1;
 
-#ifdef BRINGUP
 #define FAIL								\
     {									\
 	*uid = rtc_time();						\
 	printk( "rbrick_uid_get failed; using current time as uid\n" );	\
 	return EEP_OK;							\
     }
-#endif /* BRINGUP */
 
     ROUTER_LOCK(path);
     sc_init( &sc, nasid, path );
@@ -520,7 +495,6 @@
     *uid = generate_unique_id( uid_str, strlen( uid_str ) );
 
     return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
 
 int iobrick_uid_get( nasid_t nasid, uint64_t *uid )
@@ -593,12 +567,10 @@
 
 extern char *nic_vertex_info_get( devfs_handle_t );
 extern void nic_vmc_check( devfs_handle_t, char * );
-#ifdef BRINGUP
 /* the following were lifted from nic.c - change later? */
 #define MAX_INFO 2048
 #define NEWSZ(ptr,sz)   ((ptr) = kern_malloc((sz)))
 #define DEL(ptr) (kern_free((ptr)))
-#endif /* BRINGUP */
 
 char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
                               net_vec_t path )
@@ -884,9 +856,6 @@
 int read_ia( l1sc_t *sc, int subch, int l1_compt, 
 	     int ia_code, char *eep_record )
 {
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
     char msg[BRL1_QSIZE]; 	   /* message buffer */
     int len;              	   /* number of bytes used in message buffer */
     int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */
@@ -936,16 +905,12 @@
     }
 
     return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
 
 
 int read_spd( l1sc_t *sc, int subch, int l1_compt,
 	      eeprom_spd_u *spd )
 {
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
     char msg[BRL1_QSIZE]; 	    /* message buffer */
     int len;              	    /* number of bytes used in message buffer */
     int resp;                       /* l1 response code */
@@ -1010,7 +975,6 @@
 	offset += EEPROM_CHUNKSIZE;
     }
     return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
 
 
@@ -1068,7 +1032,7 @@
     if( (checksum & 0xff) != 0 )
     {
 	db_printf(( "read_chassis_ia: bad checksum\n" ));
-	db_printf(( "read_chassis_ia: target 0x%x  uart 0x%x\n",
+	db_printf(( "read_chassis_ia: target 0x%x  uart 0x%lx\n",
 			   sc->subch[subch].target, sc->uart ));
 	return EEP_BAD_CHECKSUM;
     }
@@ -1199,7 +1163,7 @@
     if( (checksum & 0xff) != 0 )
     {
 	db_printf(( "read_board_ia: bad checksum\n" ));
-	db_printf(( "read_board_ia: target 0x%x  uart 0x%x\n",
+	db_printf(( "read_board_ia: target 0x%x  uart 0x%lx\n",
 		    sc->subch[subch].target, sc->uart ));
 	return EEP_BAD_CHECKSUM;
     }
@@ -1211,9 +1175,6 @@
 int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp,
 			 int component )
 {
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
     int r;
     uint64_t uid = 0;
 #ifdef LOG_GETENV
@@ -1290,16 +1251,12 @@
 	return fake_an_eeprom_record( buf, component, uid );
     }
     return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
 
 
 int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
     		        int component )
 {
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
     l1sc_t *scp;
     int local = (nasid == get_nasid());
 
@@ -1318,16 +1275,12 @@
     }
 
     return _cbrick_eeprom_read( buf, scp, component );
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
 
 
 int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
 			 int component )
 {
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
     int r;
     int l1_compt, subch;
     l1sc_t *scp;
@@ -1391,16 +1344,12 @@
 	return r;
     }
     return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */    
 }
 
 
 int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
 			net_vec_t path, int component )
 {
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
     int r;
     uint64_t uid = 0;
     int l1_compt, subch;
@@ -1470,5 +1419,4 @@
 	/* unsupported brick type */
 	return EEP_PARAM;
     }
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/efi-rtc.c linux/arch/ia64/sn/io/efi-rtc.c
--- linux.orig/arch/ia64/sn/io/efi-rtc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/efi-rtc.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,185 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2001 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <asm/efi.h>
+#include <asm/sn/klclock.h>
+
+/*
+ * No locking necessary when this is called from efirtc which protects us
+ * from racing by efi_rtc_lock.
+ */
+#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3))
+#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr))
+#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data))
+
+#define TOD_SGS_M48T35		1
+#define TOD_DALLAS_DS1386	2
+
+static unsigned long nvram_base = 0;
+static int tod_chip_type;
+
+static int
+get_tod_chip_type(void)
+{
+	unsigned char testval;
+
+	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
+	write_io_port(RTC_DAL_DAY_ADDR, 0xff);
+	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
+
+	testval = read_io_port(RTC_DAL_DAY_ADDR);
+	if (testval == 0xff)
+		return TOD_SGS_M48T35;
+
+	return TOD_DALLAS_DS1386;
+}
+
+efi_status_t
+ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
+{
+	if (!nvram_base) {
+		printk(KERN_CRIT "nvram_base is zero\n");
+		return EFI_UNSUPPORTED;
+	}
+
+	memset(time, 0, sizeof(*time));
+
+	switch (tod_chip_type) {
+	case TOD_SGS_M48T35:
+		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);
+
+		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
+		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
+		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
+		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
+		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
+		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
+		time->nanosecond = 0;
+
+		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
+		break;
+
+	case TOD_DALLAS_DS1386:
+		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
+
+		time->nanosecond = 0;
+		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
+		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
+		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
+		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
+		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
+		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;
+
+		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
+		break;
+
+	default:
+		break;
+	}
+
+	if (caps) {
+		caps->resolution = 50000000;	/*  50PPM */
+		caps->accuracy = 1000;		/*  1ms */
+		caps->sets_to_zero = 0;
+	}
+
+	return EFI_SUCCESS;
+}
+
+static efi_status_t ioc3_set_time (efi_time_t *t)
+{
+	if (!nvram_base) {
+		printk(KERN_CRIT "nvram_base is zero\n");
+		return EFI_UNSUPPORTED;
+	}
+
+	switch (tod_chip_type) {
+	case TOD_SGS_M48T35:
+		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE);
+        	write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
+		write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month));
+		write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day));
+		write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour));
+		write_io_port(RTC_SGS_MIN_ADDR,  INT_TO_BCD(t->minute));
+		write_io_port(RTC_SGS_SEC_ADDR,  INT_TO_BCD(t->second));
+		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
+		break;
+
+	case TOD_DALLAS_DS1386:
+		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
+		write_io_port(RTC_DAL_SEC_ADDR,  INT_TO_BCD(t->second));
+		write_io_port(RTC_DAL_MIN_ADDR,  INT_TO_BCD(t->minute));
+		write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour));
+		write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day));
+		write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month));
+		write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
+		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
+		break;
+
+	default:
+		break;
+	}
+
+	return EFI_SUCCESS;
+}
+
+/* The following two are not supported atm.  */
+static efi_status_t
+ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
+{
+	return EFI_UNSUPPORTED;
+}
+
+static efi_status_t
+ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
+{
+	return EFI_UNSUPPORTED;
+}
+
+/*
+ * It looks like the master IOC3 is usually on bus 0, device 4.  Hope
+ * that's right
+ */
+static __init int efi_ioc3_time_init(void)
+{
+	struct pci_dev *dev;
+	static struct ioc3 *ioc3;
+
+	dev = pci_find_slot(0, PCI_DEVFN(4, 0));
+	if (!dev) {
+		printk(KERN_CRIT "Couldn't find master IOC3\n");
+
+		return -ENODEV;
+	}
+
+	ioc3 = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
+	nvram_base = (unsigned long) ioc3 + IOC3_BYTEBUS_DEV0;
+
+	tod_chip_type = get_tod_chip_type();
+	if (tod_chip_type == 1)
+		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
+	else if (tod_chip_type == 2)
+		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
+	else
+		printk(KERN_CRIT "No or unknown TOD\n");
+
+	efi.get_time = ioc3_get_time;
+	efi.set_time = ioc3_set_time;
+	efi.get_wakeup_time = ioc3_get_wakeup_time;
+	efi.set_wakeup_time = ioc3_set_wakeup_time;
+
+	return 0;
+}
+
+module_init(efi_ioc3_time_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/hcl.c linux/arch/ia64/sn/io/hcl.c
--- linux.orig/arch/ia64/sn/io/hcl.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/ia64/sn/io/hcl.c	2002-07-20 01:08:29.000000000 +0000
@@ -6,8 +6,7 @@
  *
  *  hcl - SGI's Hardware Graph compatibility layer.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -49,7 +48,6 @@
 /*
  * Some Global definitions.
  */
-spinlock_t hcl_spinlock;
 devfs_handle_t hcl_handle = NULL;
 
 invplace_t invplace_none = {
@@ -142,6 +140,7 @@
 {
 	extern void string_table_init(struct string_table *);
 	extern struct string_table label_string_table;
+	extern int init_ifconfig_net(void);
 	int rv = 0;
 
 #if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
@@ -153,8 +152,6 @@
 	printk ("\n%s: boot_options: 0x%0x\n", HCL_NAME, boot_options);
 #endif
 
-	spin_lock_init(&hcl_spinlock);
-
 	/*
 	 * Create the hwgraph_root on devfs.
 	 */
@@ -192,6 +189,12 @@
 		return(0);
 	}
 
+	/*
+	 * Initialize the ifconfgi_net driver that does network devices 
+	 * Persistent Naming.
+	 */
+	init_ifconfig_net();
+
 	return(0);
 
 }
@@ -238,8 +241,7 @@
 {
 
 	if (hcl_debug) {
-		printk("HCL: hwgraph_fastinfo_set handle 0x%p fastinfo %ld\n",
-			de, fastinfo);
+		printk("HCL: hwgraph_fastinfo_set handle 0x%p fastinfo %ld\n", (void *)de, fastinfo);
 	}
 		
 	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
@@ -466,7 +468,7 @@
 		 * We need to clean up!
 		 */
 		printk(KERN_WARNING "HCL: Unable to set the connect point to it's parent 0x%p\n",
-			new_devfs_handle);
+			(void *)new_devfs_handle);
 	}
 
         /*
@@ -1044,30 +1046,6 @@
 }
 
 /*
- * hwgraph_cdevsw_get - returns the fops of the given devfs entry.
- */
-struct file_operations *
-hwgraph_cdevsw_get(devfs_handle_t de)
-{
-	struct file_operations *fops = devfs_get_ops(de);
-
-	devfs_put_ops(de); /*  FIXME: this may need to be moved to callers  */
-	return(fops);
-}
-
-/*
- * hwgraph_bdevsw_get - returns the fops of the given devfs entry.
-*/
-struct file_operations *    /*  FIXME: shouldn't this be a blkdev?  */
-hwgraph_bdevsw_get(devfs_handle_t de)
-{
-	struct file_operations *fops = devfs_get_ops(de);
-
-	devfs_put_ops(de); /*  FIXME: this may need to be moved to callers  */
-	return(fops);
-}
-
-/*
 ** Inventory is now associated with a vertex in the graph.  For items that
 ** belong in the inventory but have no vertex 
 ** (e.g. old non-graph-aware drivers), we create a bogus vertex under the 
@@ -1550,6 +1528,4 @@
 EXPORT_SYMBOL(hwgraph_path_to_dev);
 EXPORT_SYMBOL(hwgraph_block_device_get);
 EXPORT_SYMBOL(hwgraph_char_device_get);
-EXPORT_SYMBOL(hwgraph_cdevsw_get);
-EXPORT_SYMBOL(hwgraph_bdevsw_get);
 EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/hcl_util.c linux/arch/ia64/sn/io/hcl_util.c
--- linux.orig/arch/ia64/sn/io/hcl_util.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/hcl_util.c	2002-07-20 01:08:38.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -14,6 +13,7 @@
 #include <linux/devfs_fs_kernel.h>
 #include <asm/sn/sgi.h>
 #include <asm/io.h>
+#include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/hubdev.c linux/arch/ia64/sn/io/hubdev.c
--- linux.orig/arch/ia64/sn/io/hubdev.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/hubdev.c	2002-07-20 01:08:39.000000000 +0000
@@ -4,13 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/sn1/hubdev.h>
 #include <asm/sn/sn_private.h>
@@ -42,7 +43,7 @@
         
         ASSERT(attach_method);
 
-        callout =  (hubdev_callout_t *)kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
+        callout =  (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
         ASSERT(callout);
         
 	mutex_lock(&hubdev_callout_mutex);
@@ -104,6 +105,9 @@
  * Given a hub vertex, return the base address of the Hspec space
  * for that hub.
  */
+
+#if defined(CONFIG_IA64_SGI_SN1)
+
 caddr_t
 hubdev_prombase_get(devfs_handle_t hub)
 {
@@ -124,3 +128,5 @@
 
 	return hinfo->h_cnodeid;
 }
+
+#endif	/* CONFIG_IA64_SGI_SN1 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/huberror.c linux/arch/ia64/sn/io/huberror.c
--- linux.orig/arch/ia64/sn/io/huberror.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/huberror.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,475 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Alan Mayer
- */
-
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/smp.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/nodemask.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/synergy.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/intr.h>
-
-extern void hubni_eint_init(cnodeid_t cnode);
-extern void hubii_eint_init(cnodeid_t cnode);
-extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
-extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
-
-extern int maxcpus;
-
-#define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
-
-
-void
-hub_error_clear(nasid_t nasid)
-{
-	int i;
-	hubreg_t idsr;
-	int sn;
-
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_PEND, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_A_CLR, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_B_CLR, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_0, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_1, 0);
-	}
-
-	REMOTE_HUB_L(nasid, MD_DIR_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_MEM_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_MISC1_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_PROTOCOL_ERR_CLR);
-
-    /*
-     * Make sure spurious write response errors are cleared
-     * (values are from hub_set_prb())
-     */
-    for (i = 0; i <= HUB_WIDGET_ID_MAX - HUB_WIDGET_ID_MIN + 1; i++) {
-        iprb_t prb;
-
-	prb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)));
-
-        /* Clear out some fields */
-        prb.iprb_ovflow = 1;
-        prb.iprb_bnakctr = 0;
-        prb.iprb_anakctr = 0;
-
-	/*
-	 * PIO reads in fire-and-forget mode on bedrock 1.0 don't
-	 * frob the credit count properly, making the responses appear
-	 * spurious.  So don't use fire-and-forget mode.  Bug 761802.
-	 */
-        prb.iprb_ff = 0;        /* disable fire-and-forget mode by default */
-
-        prb.iprb_xtalkctr = 3;  /* approx. PIO credits for the widget */
-
-        REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
-    }
-
-    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
-    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
-    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
-
-    REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-    /* No need to clear NI_PORT_HEADER regs; they are continually overwritten*/
-
-    REMOTE_HUB_S(nasid, LB_ERROR_MASK_CLR, -1);
-    REMOTE_HUB_S(nasid, LB_ERROR_HDR1, 0);
-
-    /* Clear XB error regs, in order */
-    for (i = 0;
-         i <= XB_FIRST_ERROR_CLEAR - XB_POQ0_ERROR_CLEAR;
-         i += sizeof(hubreg_t)) {
-        REMOTE_HUB_S(nasid, XB_POQ0_ERROR_CLEAR + i, 0);
-    }
-}
-
-
-/*
- * Function	: hub_error_init
- * Purpose	: initialize the error handling requirements for a given hub.
- * Parameters	: cnode, the compact nodeid.
- * Assumptions	: Called only once per hub, either by a local cpu. Or by a 
- *			remote cpu, when this hub is headless.(cpuless)
- * Returns	: None
- */
-
-void
-hub_error_init(cnodeid_t cnode)
-{
-	nasid_t nasid;
-
-    nasid = cnodeid_to_nasid(cnode);
-    hub_error_clear(nasid);
-
-#ifdef ajm
-    if (cnode == 0) {
-	/*
-	 * Allocate log for storing the node specific error info
-	 */
-	for (i = 0; i < numnodes; i++) {
-	    kl_error_log[i]  = kmem_zalloc_node(sizeof(sn0_error_log_t), 
-						KM_NOSLEEP, i);
-	    hub_err_count[i] = kmem_zalloc_node(sizeof(hub_errcnt_t),
-						VM_DIRECT | KM_NOSLEEP, i);
-	    ASSERT_ALWAYS(kl_error_log[i] && hub_err_count[i]);
-	}
-    }
-
-    /*
-     * Assumption: There will be only one cpu who will initialize
-     * a hub. we need to setup the ii and each pi error interrupts.
-     * The SN1 hub (bedrock) has two PI, one for up to two processors.
-     */
-
-    if (cpuid_to_cnodeid(smp_processor_id()) == cnode) { 
-	int generic_intr_mask = PI_ERR_GENERIC; /* These interrupts are sent to only 1 CPU per NODE */
-
-	ASSERT_ALWAYS(kl_error_log[cnode]);
-	ASSERT_ALWAYS(hub_err_count[cnode]);
-	MD_ERR_LOG_INIT(kl_error_log[cnode]);
-
-	/* One for each CPU */
-	recover_error_init(RECOVER_ERROR_TABLE(cnode, 0));
-	recover_error_init(RECOVER_ERROR_TABLE(cnode, 1));
-	recover_error_init(RECOVER_ERROR_TABLE(cnode, 2));
-	recover_error_init(RECOVER_ERROR_TABLE(cnode, 3));
-
-	/*
-	 * Setup error intr masks.
-	 */
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		int cpuA_present = REMOTE_HUB_PI_L(nasid, sn, PI_CPU_ENABLE_A);
-		int cpuB_present = REMOTE_HUB_PI_L(nasid, sn, PI_CPU_ENABLE_B);
-
-		if (cpuA_present) {
-			if (cpuB_present) {		/* A && B */
-	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A,
-					(PI_FATAL_ERR_CPU_B | PI_MISC_ERR_CPU_A|generic_intr_mask));
-	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B,
-					(PI_FATAL_ERR_CPU_A | PI_MISC_ERR_CPU_B));
-
-			} else {			/* A && !B */
-	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A,
-					(PI_FATAL_ERR_CPU_A | PI_MISC_ERR_CPU_A|generic_intr_mask));
-			}
-			generic_intr_mask = 0;
-		} else {
-			if (cpuB_present) {		/* !A && B */
-	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B,
-					(PI_FATAL_ERR_CPU_B | PI_MISC_ERR_CPU_B|generic_intr_mask));
-				generic_intr_mask = 0;
-
-			} else {			/* !A && !B */
-				/* nothing to set up */
-			}
-		}
-	}
-
-	/*
-	 * Turn off UNCAC_UNCORR interrupt in the masks. Anyone interested
-	 * in these errors will peek at the int pend register to see if its
-	 * set.
-	 */ 
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		misc = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_INT_MASK_A);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, (misc & ~PI_ERR_UNCAC_UNCORR_A));
-		misc = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_INT_MASK_B);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, (misc & ~PI_ERR_UNCAC_UNCORR_B));
-	}
-
-	/*
-	 * enable all error indicators to turn on, in case of errors.
-	 *
-	 * This is not good on single cpu node boards.
-	 **** LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
-	 */
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS1_A_CLR, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS1_B_CLR, 0);
-	}
-
-	/* Set up stack for each present processor */
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_A)) {
-	    	SN0_ERROR_LOG(cnode)->el_spool_cur_addr[0] =
-			SN0_ERROR_LOG(cnode)->el_spool_last_addr[0] =
-		    	REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_A);
-		}
-	    
-		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_B)) {
-	    	SN0_ERROR_LOG(cnode)->el_spool_cur_addr[1] =
-			SN0_ERROR_LOG(cnode)->el_spool_last_addr[1] =
-		    	REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
-		}
-	}
-
-
-	PI_SPOOL_SIZE_BYTES = 
-	    ERR_STACK_SIZE_BYTES(REMOTE_HUB_L(nasid, PI_ERR_STACK_SIZE));
-
-#ifdef BRINGUP
-/* BRINGUP: The following code looks like a check to make sure
-the prom set up the error spool correctly for 2 processors.  I
-don't think it is needed.  */
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_B)) {
-			__psunsigned_t addr_a = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_A);
-			__psunsigned_t addr_b = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
-			if ((addr_a & ~0xff) == (addr_b & ~0xff)) {
-			    REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STACK_ADDR_B, 	
-					addr_b + PI_SPOOL_SIZE_BYTES);
-	
-			    SN0_ERROR_LOG(cnode)->el_spool_cur_addr[1] =
-				SN0_ERROR_LOG(cnode)->el_spool_last_addr[1] =
-				    REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
-	
-		    }
-		}
-	}
-#endif /* BRINGUP */
-
-	/* programming our own hub. Enable error_int_pend intr.
-	 * If both present, CPU A takes CPU b's error interrupts and any
-	 * generic ones. CPU B takes CPU A error ints.
-	 */
-	if (cause_intr_connect (SRB_ERR_IDX,
-				(intr_func_t)(hubpi_eint_handler),
-				SR_ALL_MASK|SR_IE)) {
-	    cmn_err(ERR_WARN, 
-		    "hub_error_init: cause_intr_connect failed on %d", cnode);
-	}
-    }
-    else {
-	/* programming remote hub. The only valid reason that this
-	 * is called will be on headless hubs. No interrupts 
-	 */
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, 0); /* not necessary */
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, 0); /* not necessary */
-	}
-    }
-#endif /* ajm */
-    /*
-     * Now setup the hub ii and ni error interrupt handler.
-     */
-
-    hubii_eint_init(cnode);
-    hubni_eint_init(cnode);
-
-#ifdef ajm
-    /*** XXX FIXME XXX resolve the following***/
-    /* INT_PEND1 bits set up for one hub only:
-     *	SHUTDOWN_INTR
-     *	MD_COR_ERR_INTR
-     *  COR_ERR_INTR_A and COR_ERR_INTR_B should be sent to the
-     *  appropriate CPU only.
-     */
-
-    if (cnode == 0) {
-	    error_consistency_check.eps_state = 0;
-	    error_consistency_check.eps_cpuid = -1;
-	    spinlock_init(&error_consistency_check.eps_lock, "error_dump_lock");
-    }
-#endif
-
-    nodepda->huberror_ticks = HUB_ERROR_PERIOD;
-    return;
-}
-
-/*
- * Function	: hubii_eint_init
- * Parameters	: cnode
- * Purpose	: to initialize the hub iio error interrupt.
- * Assumptions	: Called once per hub, by the cpu which will ultimately
- *			handle this interrupt.
- * Returns	: None.
- */
-
-
-void
-hubii_eint_init(cnodeid_t cnode)
-{
-    int			bit, rv;
-    ii_iidsr_u_t    	hubio_eint;
-    hubinfo_t		hinfo; 
-    cpuid_t		intr_cpu;
-    devfs_handle_t 	hub_v;
-    ii_ilcsr_u_t	ilcsr;
-
-    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
-    ASSERT_ALWAYS(hub_v);
-    hubinfo_get(hub_v, &hinfo);
-
-    ASSERT(hinfo);
-    ASSERT(hinfo->h_cnodeid == cnode);
-
-    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
-
-    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
-	/* 
-	 * HUB II link is not up. 
-	 * Just disable LLP, and don't connect any interrupts.
-	 */
-	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
-	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
-	return;
-    }
-    /* Select a possible interrupt target where there is a free interrupt
-     * bit and also reserve the interrupt bit for this IO error interrupt
-     */
-    intr_cpu = intr_heuristic(hub_v,0,INTRCONNECT_ANYBIT,II_ERRORINT,hub_v,
-			      "HUB IO error interrupt",&bit);
-    if (intr_cpu == CPU_NONE) {
-	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
-	return;
-    }
-	
-    rv = intr_connect_level(intr_cpu, bit, 0,(intr_func_t)(NULL),
-			    (void *)(long)hub_v, NULL);
-    synergy_intr_connect(bit, intr_cpu);
-    request_irq(bit_pos_to_irq(bit) + (intr_cpu << 8), hubii_eint_handler, 0, NULL, (void *)hub_v);
-    ASSERT_ALWAYS(rv >= 0);
-    hubio_eint.ii_iidsr_regval = 0;
-    hubio_eint.ii_iidsr_fld_s.i_enable = 1;
-    hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/
-    hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode);
-    hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu);
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval);
-
-}
-
-void
-hubni_eint_init(cnodeid_t cnode)
-{
-    int intr_bit;
-    cpuid_t targ;
-
-
-    if ((targ = cnodeid_to_cpuid(cnode)) == CPU_NONE)
-	return;
-
-	/* The prom chooses which cpu gets these interrupts, but we
-	*  don't know which one it chose.  We will register all of the 
-	*  cpus to be sure.  This only costs us an irqaction per cpu.
-	*/
-    for (; targ < CPUS_PER_NODE; targ++) {
-	if (!cpu_enabled(targ) ) continue;
-	/* connect the INTEND1 bits. */
-	for (intr_bit = XB_ERROR; intr_bit <= MSC_PANIC_INTR; intr_bit++) {
-		intr_connect_level(targ, intr_bit, II_ERRORINT, NULL, NULL, NULL);
-	}
-	request_irq(SGI_HUB_ERROR_IRQ + (targ << 8), snia_error_intr_handler, 0, NULL, NULL);
-	/* synergy masks are initialized in the prom to enable all interrupts. */
-	/* We'll just leave them that way, here, for these interrupts. */
-    }
-}
-
-
-/*ARGSUSED*/
-void
-hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
-{
-    devfs_handle_t	hub_v;
-    hubinfo_t		hinfo; 
-    ii_wstat_u_t	wstat;
-    hubreg_t		idsr;
-
-	panic("Hubii interrupt\n");
-#ifdef ajm
-    /*
-     * If the NI has a problem, everyone has a problem.  We shouldn't
-     * even attempt to handle other errors when an NI error is present.
-     */
-    if (check_ni_errors()) {
-	hubni_error_handler("II interrupt", 1);
-	/* NOTREACHED */
-    }
-
-    /* two levels of casting avoids compiler warning.!! */
-    hub_v = (devfs_handle_t)(long)(arg); 
-    ASSERT(hub_v);
-
-    hubinfo_get(hub_v, &hinfo);
-    
-    /* 
-     * Identify the reason for error. 
-     */
-    wstat.ii_wstat_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_WSTAT);
-
-    if (wstat.ii_wstat_fld_s.w_crazy) {
-	char	*reason;
-	/*
-	 * We can do a couple of things here. 
-	 * Look at the fields TX_MX_RTY/XT_TAIL_TO/XT_CRD_TO to check
-	 * which of these caused the CRAZY bit to be set. 
-	 * You may be able to check if the Link is up really.
-	 */
-	if (wstat.ii_wstat_fld_s.w_tx_mx_rty)
-		reason = "Micro Packet Retry Timeout";
-	else if (wstat.ii_wstat_fld_s.w_xt_tail_to)
-		reason = "Crosstalk Tail Timeout";
-	else if (wstat.ii_wstat_fld_s.w_xt_crd_to)
-		reason = "Crosstalk Credit Timeout";
-	else {
-		hubreg_t	hubii_imem;
-		/*
-		 * Check if widget 0 has been marked as shutdown, or
-		 * if BTE 0/1 has been marked.
-		 */
-		hubii_imem = REMOTE_HUB_L(hinfo->h_nasid, IIO_IMEM);
-		if (hubii_imem & IIO_IMEM_W0ESD)
-			reason = "Hub Widget 0 has been Shutdown";
-		else if (hubii_imem & IIO_IMEM_B0ESD)
-			reason = "BTE 0 has been shutdown";
-		else if (hubii_imem & IIO_IMEM_B1ESD)
-			reason = "BTE 1 has been shutdown";
-		else	reason = "Unknown";
-	
-	}
-	/*
-	 * Note: we may never be able to print this, if the II talking
-	 * to Xbow which hosts the console is dead. 
-	 */
-	printk("Hub %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
-		hinfo->h_cnodeid, reason);
-    }
-
-    /* 
-     * It's a toss as to which one among PRB/CRB to check first. 
-     * Current decision is based on the severity of the errors. 
-     * IO CRB errors tend to be more severe than PRB errors.
-     *
-     * It is possible for BTE errors to have been handled already, so we
-     * may not see any errors handled here. 
-     */
-    (void)hubiio_crb_error_handler(hub_v, hinfo);
-    (void)hubiio_prb_error_handler(hub_v, hinfo);
-    /*
-     * If we reach here, it indicates crb/prb handlers successfully
-     * handled the error. So, re-enable II to send more interrupt
-     * and return.
-     */
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xffffff);
-    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
-#endif /* ajm */
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/hubspc.c linux/arch/ia64/sn/io/hubspc.c
--- linux.orig/arch/ia64/sn/io/hubspc.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/ia64/sn/io/hubspc.c	2002-07-20 01:08:23.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
  */
 
 /*
@@ -19,6 +18,8 @@
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
 #include <linux/devfs_fs.h>
 #include <linux/devfs_fs_kernel.h>
 #include <asm/io.h>
@@ -26,18 +27,12 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/mem_refcnt.h>
-#include <asm/sn/agent.h>
+#include <asm/sn/sn1/mem_refcnt.h>
 #include <asm/sn/addrs.h>
-
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/ip27config.h>
-#include <asm/sn/sn1/hubdev.h>
+#include <asm/sn/snconfig.h>
+#include <asm/sn/sn1/hubspc.h>
 #include <asm/sn/ksys/elsc.h>
-#endif
-
-#include <asm/sn/hubspc.h>
+#include <asm/sn/simulator.h>
 
 
 /* Uncomment the following line for tracing */
@@ -45,10 +40,6 @@
 
 int hubspc_devflag = D_MP;
 
-extern void *device_info_get(devfs_handle_t device);
-extern void device_info_set(devfs_handle_t device, void *info);
-
-
 
 /***********************************************************************/
 /* CPU Prom Space 						       */
@@ -127,9 +118,8 @@
 	return 0;
 }
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#if defined(CONFIG_IA64_SGI_SN1)
 #define	SN_PROMVERSION		INV_IP35PROM
-#endif
 
 /* Add "detailed" labelled inventory information to the
  * prom vertex 
@@ -159,7 +149,6 @@
 	cpuprom_inventory_info->im_rev = IP27CONFIG.pvers_rev;
 	cpuprom_inventory_info->im_version = IP27CONFIG.pvers_vers;
 
-
 	/* Store this info as labelled information hanging off the
 	 * prom device vertex
 	 */
@@ -172,41 +161,17 @@
 				sizeof(invent_miscinfo_t));
 }
 
-int
-cpuprom_attach(devfs_handle_t node)
-{
-        devfs_handle_t prom_dev;
-
-        hwgraph_char_device_add(node, EDGE_LBL_PROM, "hubspc_", &prom_dev);
-#ifdef	HUBSPC_DEBUG
-	printf("hubspc: prom_attach hub: 0x%x prom: 0x%x\n", node, prom_dev);
-#endif	/* HUBSPC_DEBUG */
-	device_inventory_add(prom_dev, INV_PROM, SN_PROMVERSION,
-				(major_t)0, (minor_t)0, 0);
-
-	/* Add additional inventory info about the cpu prom like
-	 * revision & version numbers etc.
-	 */
-	cpuprom_detailed_inventory_info_add(prom_dev,node);
-        device_info_set(prom_dev, (void*)(ulong)HUBSPC_PROM);
-	prominfo_add(node, prom_dev);
-
-        return (0);
-}
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #define FPROM_CONFIG_ADDR	MD_JUNK_BUS_TIMING
 #define FPROM_ENABLE_MASK	MJT_FPROM_ENABLE_MASK
 #define FPROM_ENABLE_SHFT	MJT_FPROM_ENABLE_SHFT
 #define FPROM_SETUP_MASK	MJT_FPROM_SETUP_MASK
 #define FPROM_SETUP_SHFT	MJT_FPROM_SETUP_SHFT
-#endif
 
 /*ARGSUSED*/
 int
 cpuprom_map(devfs_handle_t dev, vhandl_t *vt, off_t addr, size_t len)
 {
-        int 		errcode;
+        int 		errcode = 0;
 	caddr_t 	kvaddr;
 	devfs_handle_t		node;
 	cnodeid_t 	cnode;
@@ -220,7 +185,7 @@
 	kvaddr = hubdev_prombase_get(node);
 	cnode  = hubdev_cnodeid_get(node);
 #ifdef	HUBSPC_DEBUG
-	printf("cpuprom_map: hubnode %d kvaddr 0x%x\n", node, kvaddr);
+	printk("cpuprom_map: hubnode %d kvaddr 0x%x\n", node, kvaddr);
 #endif
 
 	if (len > RBOOT_SIZE)
@@ -251,6 +216,7 @@
 	}
         return (errcode);
 }
+#endif	/* CONFIG_IA64_SGI_SN1 */
 
 /*ARGSUSED*/
 int
@@ -263,8 +229,6 @@
 /* Base Hub Space Driver                                               */
 /***********************************************************************/
 
-// extern int l1_attach( devfs_handle_t );
-
 /*
  * hubspc_init
  * Registration of the hubspc devices with the hub manager
@@ -277,24 +241,19 @@
          */
 
         /* The reference counters */
+#if defined(CONFIG_IA64_SGI_SN1)
         hubdev_register(mem_refcnt_attach);
+#endif
 
-	/* Prom space */
-	hubdev_register(cpuprom_attach);
-
-#if defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
 	/* L1 system controller link */
 	if ( !IS_RUNNING_ON_SIMULATOR() ) {
 		/* initialize the L1 link */
-		void l1_cons_init( l1sc_t *sc );
-		elsc_t *get_elsc(void);
-
-		l1_cons_init((l1sc_t *)get_elsc());
+		extern void l1_init(void);
+		l1_init();
 	}
-#endif
 
 #ifdef	HUBSPC_DEBUG
-	printf("hubspc_init: Completed\n");
+	printk("hubspc_init: Completed\n");
 #endif	/* HUBSPC_DEBUG */
 	/* Initialize spinlocks */
 	mutex_spinlock_init(&cpuprom_spinlock);
@@ -304,26 +263,7 @@
 int
 hubspc_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
 {
-        int errcode = 0;
-        
-        switch ((hubspc_subdevice_t)(ulong)device_info_get(*devp)) {
-        case HUBSPC_REFCOUNTERS:
-                errcode = mem_refcnt_open(devp, oflag, otyp, crp);
-                break;
-
-        case HUBSPC_PROM:
-                break;
-
-        default:
-                errcode = ENODEV;
-        }
-
-#ifdef	HUBSPC_DEBUG
-	printf("hubspc_open: Completed open for type %d\n",
-               (hubspc_subdevice_t)(ulong)device_info_get(*devp));
-#endif	/* HUBSPC_DEBUG */
-
-        return (errcode);
+        return (0);
 }
 
 
@@ -331,25 +271,7 @@
 int
 hubspc_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
 {
-        int errcode = 0;
-        
-        switch ((hubspc_subdevice_t)(ulong)device_info_get(dev)) {
-        case HUBSPC_REFCOUNTERS:
-                errcode = mem_refcnt_close(dev, oflag, otyp, crp);
-                break;
-
-        case HUBSPC_PROM:
-                break;
-        default:
-                errcode = ENODEV;
-        }
-
-#ifdef	HUBSPC_DEBUG
-	printf("hubspc_close: Completed close for type %d\n",
-               (hubspc_subdevice_t)(ulong)device_info_get(dev));
-#endif	/* HUBSPC_DEBUG */
-
-        return (errcode);
+        return (0);
 }
 
 /* ARGSUSED */
@@ -357,7 +279,6 @@
 hubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
 {
 	/*REFERENCED*/
-        hubspc_subdevice_t subdevice;
         int errcode = 0;
 
 	/* check validity of request */
@@ -365,30 +286,6 @@
 		return ENXIO;
         }
 
-        subdevice = (hubspc_subdevice_t)(ulong)device_info_get(dev);
-
-#ifdef	HUBSPC_DEBUG
-	printf("hubspc_map: subdevice: %d vaddr: 0x%x phyaddr: 0x%x len: 0x%x\n",
-	       subdevice, v_getaddr(vt), off, len);
-#endif /* HUBSPC_DEBUG */
-
-        switch ((hubspc_subdevice_t)(ulong)device_info_get(dev)) {
-        case HUBSPC_REFCOUNTERS:
-                errcode = mem_refcnt_mmap(dev, vt, off, len, prot);
-                break;
-
-        case HUBSPC_PROM:
-		errcode = cpuprom_map(dev, vt, off, len);
-                break;
-        default:
-                errcode = ENODEV;
-        }
-
-#ifdef	HUBSPC_DEBUG
-	printf("hubspc_map finished: spctype: %d vaddr: 0x%x len: 0x%x\n",
-	       (hubspc_subdevice_t)(ulong)device_info_get(dev), v_getaddr(vt), len);
-#endif /* HUBSPC_DEBUG */
-
 	return errcode;
 }
 
@@ -396,21 +293,7 @@
 int
 hubspc_unmap(devfs_handle_t dev, vhandl_t *vt)
 {
-        int errcode = 0;
-        
-        switch ((hubspc_subdevice_t)(ulong)device_info_get(dev)) {
-        case HUBSPC_REFCOUNTERS:
-                errcode = mem_refcnt_unmap(dev, vt);
-                break;
-
-        case HUBSPC_PROM:
-                errcode = cpuprom_unmap(dev, vt);
-                break;
-
-        default:
-                errcode = ENODEV;
-        }
-	return errcode;
+	return (0);
 
 }
 
@@ -423,19 +306,6 @@
              cred_t *cred_p,
              int *rvalp)
 {
-        int errcode = 0;
-        
-        switch ((hubspc_subdevice_t)(ulong)device_info_get(dev)) {
-        case HUBSPC_REFCOUNTERS:
-                errcode = mem_refcnt_ioctl(dev, cmd, arg, mode, cred_p, rvalp);
-                break;
-
-        case HUBSPC_PROM:
-                break;
-
-        default:
-                errcode = ENODEV;
-        }
-	return errcode;
+	return (0);
 
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/ifconfig_net.c linux/arch/ia64/sn/io/ifconfig_net.c
--- linux.orig/arch/ia64/sn/io/ifconfig_net.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/ifconfig_net.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,298 @@
+/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  ifconfig_net - SGI's Persistent Network Device names.
+ *
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/ifconfig_net.h>
+
+#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
+#define SGI_IFCONFIG_NET_VERSION "1.0"
+
+/*
+ * Some Global definitions.
+ */
+devfs_handle_t ifconfig_net_handle = NULL;
+unsigned long ifconfig_net_debug = 0;
+
+/*
+ * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
+ */
+static int ifconfig_net_open(struct inode * inode, struct file * filp)
+{
+	if (ifconfig_net_debug) {
+        	printk("ifconfig_net_open called.\n");
+	}
+
+        return(0);
+
+}
+
+/*
+ * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
+ */
+static int ifconfig_net_close(struct inode * inode, struct file * filp)
+{
+
+	if (ifconfig_net_debug) {
+        	printk("ifconfig_net_close called.\n");
+	}
+
+        return(0);
+}
+
+/*
+ * assign_ifname - Assign the next available interface name from the persistent list.
+ */
+void
+assign_ifname(struct net_device *dev,
+		  struct ifname_num *ifname_num)
+
+{
+
+	/*
+	 * Handle eth devices.
+	 */
+        if ( (memcmp(dev->name, "eth", 3) == 0) ) {
+		if (ifname_num->next_eth != -1) {
+			/*
+			 * Assign it the next available eth interface number. 
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
+			ifname_num->next_eth++;
+		} 
+
+                return;
+        }
+
+	/*
+	 * Handle fddi devices.
+	 */
+	if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
+		if (ifname_num->next_fddi != -1) {
+			/*
+			 * Assign it the next available fddi interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
+			ifname_num->next_fddi++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle hip devices.
+	 */
+	if ( (memcmp(dev->name, "hip", 3) == 0) ) {
+		if (ifname_num->next_hip != -1) {
+			/*
+			 * Assign it the next available hip interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
+			ifname_num->next_hip++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle tr devices.
+	 */
+	if ( (memcmp(dev->name, "tr", 2) == 0) ) {
+		if (ifname_num->next_tr != -1) {
+			/*
+			 * Assign it the next available tr interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
+			ifname_num->next_tr++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle fc devices.
+	 */
+	if ( (memcmp(dev->name, "fc", 2) == 0) ) {
+		if (ifname_num->next_fc != -1) {
+			/*
+			 * Assign it the next available fc interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
+			ifname_num->next_fc++;
+		}
+
+		return;
+	}
+}
+
+/*
+ * find_persistent_ifname: Returns the entry that was seen in previous boot.
+ */
+struct ifname_MAC *
+find_persistent_ifname(struct net_device *dev,
+	struct ifname_MAC *ifname_MAC)
+
+{
+
+	while (ifname_MAC->addr_len) {
+		if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
+			return(ifname_MAC);
+
+		ifname_MAC++;
+	}
+
+	return(NULL);
+}
+
+/*
+ * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
+ */
+static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	extern struct net_device *__dev_get_by_name(const char *);
+#ifdef CONFIG_NET
+	struct net_device *dev;
+	struct ifname_MAC *found;
+	char temp[64];
+#endif
+	struct ifname_MAC *ifname_MAC;
+	struct ifname_MAC *new_devices, *temp_new_devices;
+	struct ifname_num *ifname_num;
+	unsigned long size;
+
+
+	if (ifconfig_net_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	/*
+	 * Read in the header and see how big of a buffer we really need to 
+	 * allocate.
+	 */
+	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
+			GFP_KERNEL);
+	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
+	size = ifname_num->size;
+	kfree(ifname_num);
+	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
+	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
+
+	copy_from_user( ifname_num, (char *) arg, size);
+	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
+	temp_new_devices = new_devices;
+
+	memset(new_devices, 0, size - sizeof(struct ifname_num));
+
+#ifdef CONFIG_NET
+	/*
+	 * Go through the net device entries and make them persistent!
+	 */
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+		/*
+		 * Skip NULL entries or "lo"
+		 */
+		if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
+			continue;
+		}
+
+		/*
+		 * See if we have a persistent interface name for this device.
+		 */
+		found = NULL;
+		found = find_persistent_ifname(dev, ifname_MAC);
+		if (found) {
+			strcpy(dev->name, found->name);
+		} else {
+			/* Never seen this before .. */
+			assign_ifname(dev, ifname_num);
+
+			/* 
+			 * Save the information for the next boot.
+			 */
+ 			sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+				dev->dev_addr[0],  dev->dev_addr[1],  dev->dev_addr[2],
+				dev->dev_addr[3],  dev->dev_addr[4],  dev->dev_addr[5]);
+			strcpy(temp_new_devices->name, dev->name);
+			temp_new_devices->addr_len = dev->addr_len;
+			memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
+			temp_new_devices++;
+		}
+		
+	}
+#endif
+
+	/*
+	 * Copy back to the User Buffer area any new devices encountered.
+	 */
+	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
+			size - sizeof(struct ifname_num));
+
+	return(0);
+
+}
+
+struct file_operations ifconfig_net_fops = {
+	ioctl:ifconfig_net_ioctl,	/* ioctl */
+	open:ifconfig_net_open,		/* open */
+	release:ifconfig_net_close	/* release */
+};
+
+
+/*
+ * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ */
+#ifdef MODULE
+int init_module (void)
+#else
+int __init init_ifconfig_net(void)
+#endif
+{
+	ifconfig_net_handle = NULL;
+	ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&ifconfig_net_fops, NULL);
+
+	if (ifconfig_net_handle == NULL) {
+		panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n");
+	}
+
+	return(0);
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/invent.c linux/arch/ia64/sn/io/invent.c
--- linux.orig/arch/ia64/sn/io/invent.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/invent.c	2002-07-20 01:08:37.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/io.c linux/arch/ia64/sn/io/io.c
--- linux.orig/arch/ia64/sn/io/io.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/io.c	2002-07-20 01:08:35.000000000 +0000
@@ -1,36 +1,50 @@
-/* $Id$
+/* $Id: io.c,v 1.2 2001/06/26 14:02:43 pfg Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/types.h>
-#include <linux/config.h>
 #include <linux/slab.h>
 #include <asm/sn/types.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
 #include <asm/sn/iograph.h>
 #include <asm/param.h>
 #include <asm/sn/pio.h>
 #include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
-#include <asm/sn/agent.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/xtalk/xtalkaddrs.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/io.h>
 #include <asm/sn/sn_cpuid.h>
 
 extern xtalk_provider_t hub_provider;
+extern void hub_intr_init(devfs_handle_t hubv);
+
+
+/*      
+ * hub_device_desc_update               
+ *      Update the passed in device descriptor with the actual the
+ *      target cpu number and interrupt priority level.
+ *      NOTE : These might be the same as the ones passed in thru
+ *      the descriptor.
+ */     
+void
+hub_device_desc_update(device_desc_t    dev_desc,
+                       ilvl_t           intr_swlevel, 
+                       cpuid_t          cpu)
+{       
+}
+
 
 /*
  * Perform any initializations needed to support hub-based I/O.
@@ -63,7 +77,7 @@
 /*
  * Setup pio structures needed for a particular hub.
  */
-static void
+void
 hub_pio_init(devfs_handle_t hubv)
 {
 	xwidgetnum_t widget;
@@ -386,7 +400,7 @@
 
 
 /* ARGSUSED */
-static void
+void
 hub_dma_init(devfs_handle_t hubv)
 {
 }
@@ -411,7 +425,7 @@
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
 	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
 
-	dmamap = kern_malloc(sizeof(struct hub_dmamap_s));
+	dmamap = kmalloc(sizeof(struct hub_dmamap_s), GFP_ATOMIC);
 	dmamap->hdma_xtalk_info.xd_dev = dev;
 	dmamap->hdma_xtalk_info.xd_target = widget;
 	dmamap->hdma_hub = hubv;
@@ -454,9 +468,9 @@
 	    if (!(dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
 		vhdl = dmamap->hdma_xtalk_info.xd_dev;
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		PRINT_WARNING("%v: hub_dmamap_addr re-uses dmamap.\n",vhdl);
+		printk(KERN_WARNING  "%v: hub_dmamap_addr re-uses dmamap.\n",vhdl);
 #else
-		PRINT_WARNING("0x%x: hub_dmamap_addr re-uses dmamap.\n", vhdl);
+		printk(KERN_WARNING  "%p: hub_dmamap_addr re-uses dmamap.\n", (void *)vhdl);
 #endif
 	    }
 	} else {
@@ -487,9 +501,9 @@
 	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
 		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		PRINT_WARNING("%v: hub_dmamap_list re-uses dmamap\n",vhdl);
+		printk(KERN_WARNING  "%v: hub_dmamap_list re-uses dmamap\n",vhdl);
 #else
-		PRINT_WARNING("0x%x: hub_dmamap_list re-uses dmamap\n", vhdl);
+		printk(KERN_WARNING  "%p: hub_dmamap_list re-uses dmamap\n", (void *)vhdl);
 #endif
 	    }
 	} else {
@@ -516,9 +530,9 @@
 	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
 		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		PRINT_WARNING("%v: hub_dmamap_done already done with dmamap\n",vhdl);
+		printk(KERN_WARNING  "%v: hub_dmamap_done already done with dmamap\n",vhdl);
 #else
-		PRINT_WARNING("0x%x: hub_dmamap_done already done with dmamap\n", vhdl);
+		printk(KERN_WARNING  "%p: hub_dmamap_done already done with dmamap\n", (void *)vhdl);
 #endif
 	    }
 	}
@@ -581,329 +595,6 @@
 
 
 
-/* INTERRUPT MANAGEMENT */
-
-/* ARGSUSED */
-static void
-hub_intr_init(devfs_handle_t hubv)
-{
-}
-
-/*
- * hub_device_desc_update
- *	Update the passed in device descriptor with the actual the
- * 	target cpu number and interrupt priority level.
- *	NOTE : These might be the same as the ones passed in thru
- *	the descriptor.
- */
-static void
-hub_device_desc_update(device_desc_t 	dev_desc, 
-		       ilvl_t 		intr_swlevel,
-		       cpuid_t		cpu)
-{
-	char	cpuname[40];
-	
-	/* Store the interrupt priority level in the device descriptor */
-	device_desc_intr_swlevel_set(dev_desc, intr_swlevel);
-
-	/* Convert the cpuid to the vertex handle in the hwgraph and
-	 * save it in the device descriptor.
-	 */
-	sprintf(cpuname,"/hw/cpunum/%ld",cpu);
-	device_desc_intr_target_set(dev_desc, 
-				    hwgraph_path_to_dev(cpuname));
-}
-
-int allocate_my_bit = INTRCONNECT_ANYBIT;
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-static hub_intr_t
-do_hub_intr_alloc(devfs_handle_t dev,		/* which crosstalk device */
-		  device_desc_t dev_desc,	/* device descriptor */
-		  devfs_handle_t owner_dev,	/* owner of this interrupt, if known */
-		  int uncond_nothread)		/* unconditionally non-threaded */
-{
-	cpuid_t cpu = (cpuid_t)0;			/* cpu to receive interrupt */
-        int cpupicked = 0;
-	int bit;			/* interrupt vector */
-	/*REFERENCED*/
-	int intr_resflags = 0;
-	hub_intr_t intr_hdl;
-	cnodeid_t nodeid;		/* node to receive interrupt */
-	/*REFERENCED*/
-	nasid_t nasid;			/* nasid to receive interrupt */
-	struct xtalk_intr_s *xtalk_info;
-	iopaddr_t xtalk_addr;		/* xtalk addr on hub to set intr */
-	xwidget_info_t xwidget_info;	/* standard crosstalk widget info handle */
-	char *intr_name = NULL;
-	ilvl_t intr_swlevel;
-	extern int default_intr_pri;
-#ifdef CONFIG_IA64_SGI_SN1 
-	extern void synergy_intr_alloc(int, int);
-#endif
-	
-	/*
-	 * If caller didn't explicily specify a device descriptor, see if there's
-	 * a default descriptor associated with the device.
-	 */
-	if (!dev_desc) 
-		dev_desc = device_desc_default_get(dev);
-
-	if (dev_desc) {
-		intr_name = device_desc_intr_name_get(dev_desc);
-		intr_swlevel = device_desc_intr_swlevel_get(dev_desc);
-		if (dev_desc->flags & D_INTR_ISERR) {
-			intr_resflags = II_ERRORINT;
-		} else if (!uncond_nothread && !(dev_desc->flags & D_INTR_NOTHREAD)) {
-			intr_resflags = II_THREADED;
-		} else {
-			/* Neither an error nor a thread. */
-			intr_resflags = 0;
-		}
-	} else {
-		intr_swlevel = default_intr_pri;
-		if (!uncond_nothread)
-			intr_resflags = II_THREADED;
-	}
-
-	/* XXX - Need to determine if the interrupt should be threaded. */
-
-	/* If the cpu has not been picked already then choose a candidate 
-	 * interrupt target and reserve the interrupt bit 
-	 */
-#if defined(NEW_INTERRUPTS)
-	if (!cpupicked) {
-		cpu = intr_heuristic(dev,dev_desc,allocate_my_bit,
-				     intr_resflags,owner_dev,
-				     intr_name,&bit);
-	}
-#endif
-
-	/* At this point we SHOULD have a valid cpu */
-	if (cpu == CPU_NONE) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		PRINT_WARNING("%v hub_intr_alloc could not allocate interrupt\n",
-			owner_dev);
-#else
-		PRINT_WARNING("0x%x hub_intr_alloc could not allocate interrupt\n",
-			owner_dev);
-#endif
-		return(0);
-
-	}
-
-	/* If the cpu has been picked already (due to the bridge data 
-	 * corruption bug) then try to reserve an interrupt bit .
-	 */
-#if defined(NEW_INTERRUPTS)
-	if (cpupicked) {
-		bit = intr_reserve_level(cpu, allocate_my_bit, 
-					 intr_resflags, 
-					 owner_dev, intr_name);
-		if (bit < 0) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			PRINT_WARNING("Could not reserve an interrupt bit for cpu "
-				" %d and dev %v\n",
-				cpu,owner_dev);
-#else
-			PRINT_WARNING("Could not reserve an interrupt bit for cpu "
-				" %d and dev 0x%x\n",
-				cpu, owner_dev);
-#endif
-				
-			return(0);
-		}
-	}
-#endif	/* NEW_INTERRUPTS */
-
-	nodeid = cpuid_to_cnodeid(cpu);
-	nasid = cpuid_to_nasid(cpu);
-	xtalk_addr = HUBREG_AS_XTALKADDR(nasid, PIREG(PI_INT_PEND_MOD, cpuid_to_subnode(cpu)));
-
-	/*
-	 * Allocate an interrupt handle, and fill it in.  There are two
-	 * pieces to an interrupt handle: the piece needed by generic
-	 * xtalk code which is used by crosstalk device drivers, and
-	 * the piece needed by low-level IP27 hardware code.
-	 */
-	intr_hdl = kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, nodeid);
-	ASSERT_ALWAYS(intr_hdl);
-
-	/* 
-	 * Fill in xtalk information for generic xtalk interfaces that
-	 * operate on xtalk_intr_hdl's.
-	 */
-	xtalk_info = &intr_hdl->i_xtalk_info;
-	xtalk_info->xi_dev = dev;
-	xtalk_info->xi_vector = bit;
-	xtalk_info->xi_addr = xtalk_addr;
-
-	/*
-	 * Regardless of which CPU we ultimately interrupt, a given crosstalk
-	 * widget always handles interrupts (and PIO and DMA) through its 
-	 * designated "master" crosstalk provider.
-	 */
-	xwidget_info = xwidget_info_get(dev);
-	if (xwidget_info)
-		xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info);
-
-	/* Fill in low level hub information for hub_* interrupt interface */
-	intr_hdl->i_swlevel = intr_swlevel;
-	intr_hdl->i_cpuid = cpu;
-	intr_hdl->i_bit = bit;
-	intr_hdl->i_flags = HUB_INTR_IS_ALLOCED;
-
-	/* Store the actual interrupt priority level & interrupt target
-	 * cpu back in the device descriptor.
-	 */
-	hub_device_desc_update(dev_desc, intr_swlevel, cpu);
-#ifdef CONFIG_IA64_SGI_SN1
-	synergy_intr_alloc((int)bit, (int)cpu);
-#endif
-	return(intr_hdl);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-hub_intr_t
-hub_intr_alloc(	devfs_handle_t dev,		/* which crosstalk device */
-		device_desc_t dev_desc,		/* device descriptor */
-		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
-{
-	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Uncondtionally request non-threaded, regardless of what the device
- * descriptor might say.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,		/* which crosstalk device */
-		device_desc_t dev_desc,		/* device descriptor */
-		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
-{
-	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-hub_intr_free(hub_intr_t intr_hdl)
-{
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	xtalk_intr_t xtalk_info;
-
-	if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) {
-		/* Setting the following fields in the xtalk interrupt info
-	 	 * clears the interrupt target register in the xtalk user
-	 	 */
-		xtalk_info = &intr_hdl->i_xtalk_info;
-		xtalk_info->xi_dev = NODEV;
-		xtalk_info->xi_vector = 0;
-		xtalk_info->xi_addr = 0;
-		hub_intr_disconnect(intr_hdl);
-	}
-
-	if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED)
-		kfree(intr_hdl);
-
-#if defined(NEW_INTERRUPTS)
-	intr_unreserve_level(cpu, bit);
-#endif
-}
-
-
-/*
- * Associate resources allocated with a previous hub_intr_alloc call with the
- * described handler, arg, name, etc.
- */
-/*ARGSUSED*/
-int
-hub_intr_connect(	hub_intr_t intr_hdl,		/* xtalk intr resource handle */
-			intr_func_t intr_func,		/* xtalk intr handler */
-			void *intr_arg,			/* arg to intr handler */
-			xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-			void *setfunc_arg,		/* arg to setfunc */
-			void *thread)			/* intr thread to use */
-{
-	int rv;
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-#ifdef CONFIG_IA64_SGI_SN1
-	extern int synergy_intr_connect(int, int);
-#endif
-
-	ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED);
-
-#if defined(NEW_INTERRUPTS)
-	rv = intr_connect_level(cpu, bit, intr_hdl->i_swlevel, 
-					intr_func, intr_arg, NULL);
-	if (rv < 0)
-		return(rv);
-
-#endif
-	intr_hdl->i_xtalk_info.xi_setfunc = setfunc;
-	intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg;
-
-	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
-
-	intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED;
-#ifdef CONFIG_IA64_SGI_SN1
-	return(synergy_intr_connect((int)bit, (int)cpu));
-#endif
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-hub_intr_disconnect(hub_intr_t intr_hdl)
-{
-	/*REFERENCED*/
-	int rv;
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	xtalk_intr_setfunc_t setfunc;
-
-	setfunc = intr_hdl->i_xtalk_info.xi_setfunc;
-
-	/* TBD: send disconnected interrupts somewhere harmless */
-	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
-
-#if defined(NEW_INTERRUPTS)
-	rv = intr_disconnect_level(cpu, bit);
-	ASSERT(rv == 0);
-#endif
-
-	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl)
-{
-	cpuid_t cpuid = intr_hdl->i_cpuid;
-	ASSERT(cpuid != CPU_NONE);
-
-	return(cpuid_to_vertex(cpuid));
-}
-
-
-
 /* CONFIGURATION MANAGEMENT */
 
 /*
@@ -912,6 +603,9 @@
 void
 hub_provider_startup(devfs_handle_t hubv)
 {
+	extern void hub_dma_init(devfs_handle_t hubv);
+	extern void hub_pio_init(devfs_handle_t hubv);
+
 	hub_pio_init(hubv);
 	hub_dma_init(hubv);
 	hub_intr_init(hubv);
@@ -1170,58 +864,6 @@
 	return rv;
 }
 
-#if ((defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)) && defined(BRINGUP))
-/* BRINGUP:  This ought to be useful for IP27 too but, for now,
- * make it SN1 only because `ii_ixtt_u_t' is not in IP27/hubio.h
- * (or anywhere else :-).
- */
-int
-hubii_ixtt_set(devfs_handle_t widget_vhdl, ii_ixtt_u_t *ixtt)
-{
-	xwidget_info_t		widget_info = xwidget_info_get(widget_vhdl);
-	devfs_handle_t		hub_vhdl    = xwidget_info_master_get(widget_info);
-	hubinfo_t		hub_info = 0;
-	nasid_t			nasid;
-	unsigned long			s;
-
-	/* Use the nasid from the hub info hanging off the hub vertex
-	 * and widget number from the widget vertex
-	 */
-	hubinfo_get(hub_vhdl, &hub_info);
-	/* Being over cautious by grabbing a lock */
-	s 	= mutex_spinlock(&hub_info->h_bwlock);
-	nasid 	= hub_info->h_nasid;
-
-	REMOTE_HUB_S(nasid, IIO_IXTT, ixtt->ii_ixtt_regval);
-
-	mutex_spinunlock(&hub_info->h_bwlock, s);
-	return 0;
-}
-
-int
-hubii_ixtt_get(devfs_handle_t widget_vhdl, ii_ixtt_u_t *ixtt)
-{
-	xwidget_info_t		widget_info = xwidget_info_get(widget_vhdl);
-	devfs_handle_t		hub_vhdl    = xwidget_info_master_get(widget_info);
-	hubinfo_t		hub_info = 0;
-	nasid_t			nasid;
-	unsigned long		s;
-
-	/* Use the nasid from the hub info hanging off the hub vertex
-	 * and widget number from the widget vertex
-	 */
-	hubinfo_get(hub_vhdl, &hub_info);
-	/* Being over cautious by grabbing a lock */
-	s 	= mutex_spinlock(&hub_info->h_bwlock);
-	nasid 	= hub_info->h_nasid;
-
-	ixtt->ii_ixtt_regval = REMOTE_HUB_L(nasid, IIO_IXTT);
-
-	mutex_spinunlock(&hub_info->h_bwlock, s);
-	return 0;
-}
-#endif /* CONFIG_IA64_SGI_SN1 */
-
 /*
  * hub_device_inquiry
  *	Find out the xtalk widget related information stored in this 
@@ -1259,7 +901,7 @@
 #if defined(SUPPORT_PRINTING_V_FORMAT)
 	printk("Inquiry Info for %v\n", xconn);
 #else
-	printk("Inquiry Info for 0x%x\n", xconn);
+	printk("Inquiry Info for %p\n", (void *)xconn);
 #endif
 
 	printk("\tDevices shutdown [ ");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/ip37.c linux/arch/ia64/sn/io/ip37.c
--- linux.orig/arch/ia64/sn/io/ip37.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/ip37.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,121 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-/*
- * ip37.c
- *	Support for IP35/IP37 machines
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sgi.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/pci/bridge.h>     /* for bridge_t */
-
-
-xwidgetnum_t
-hub_widget_id(nasid_t nasid)
-{
-	hubii_wcr_t	ii_wcr;	/* the control status register */
-		
-	ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
-
-	return ii_wcr.wcr_fields_s.wcr_widget_id;
-}
-
-/*
- * get_nasid() returns the physical node id number of the caller.
- */
-nasid_t
-get_nasid(void)
-{
-	return (nasid_t)((LOCAL_HUB_L(LB_REV_ID) & LRI_NODEID_MASK) >> LRI_NODEID_SHFT);
-}
-
-int
-get_slice(void)
-{
-	return LOCAL_HUB_L(PI_CPU_NUM);
-}
-
-int
-is_fine_dirmode(void)
-{
-	return (((LOCAL_HUB_L(LB_REV_ID) & LRI_SYSTEM_SIZE_MASK)
-		>> LRI_SYSTEM_SIZE_SHFT) == SYSTEM_SIZE_SMALL);
-
-}
-
-hubreg_t
-get_hub_chiprev(nasid_t nasid)
-{
-
-	return ((REMOTE_HUB_L(nasid, LB_REV_ID) & LRI_REV_MASK)
-		                                         >> LRI_REV_SHFT);
-}
-
-int
-verify_snchip_rev(void)
-{
-	int hub_chip_rev;
-	int i;
-	static int min_hub_rev = 0;
-	nasid_t nasid;
-	static int first_time = 1;
-	extern int maxnodes;
-
-        
-	if (first_time) {
-	    for (i = 0; i < maxnodes; i++) {	
-		nasid = COMPACT_TO_NASID_NODEID(i);
-		hub_chip_rev = get_hub_chiprev(nasid);
-
-		if ((hub_chip_rev < min_hub_rev) || (i == 0))
-		    min_hub_rev = hub_chip_rev;
-	    }
-
-	
-	    first_time = 0;
-	}
-
-	return min_hub_rev;
-	
-}
-
-#ifdef SN1_USE_POISON_BITS
-int
-hub_bte_poison_ok(void)
-{
-	/*
-	 * For now, assume poisoning is ok. If it turns out there are chip
-	 * bugs that prevent its use in early revs, there is some neat code
-	 * to steal from the IP27 equivalent of this code.
-	 */
-
-#ifdef BRINGUP	/* temp disable BTE poisoning - might be sw bugs in this area */
-	return 0;
-#else
-	return 1;
-#endif
-}
-#endif /* SN1_USE_POISON_BITS */
-                
-
-void
-ni_reset_port(void)
-{
-	LOCAL_HUB_S(NI_RESET_ENABLE, NRE_RESETOK);
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-}
-
-#endif	/* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/klconflib.c linux/arch/ia64/sn/io/klconflib.c
--- linux.orig/arch/ia64/sn/io/klconflib.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/klconflib.c	2002-07-20 01:08:31.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -13,12 +12,13 @@
 #include <linux/config.h>
 #include <linux/ctype.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-
-#include <asm/sn/agent.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/nodepda.h>
 #include <asm/sn/module.h>
@@ -40,6 +40,9 @@
 
 static void sort_nic_names(lboard_t *) ;
 
+u64 klgraph_addr[MAX_COMPACT_NODES];
+int module_number = 0;
+
 lboard_t *
 find_lboard(lboard_t *start, unsigned char brd_type)
 {
@@ -213,14 +216,13 @@
 {
 	lboard_t	*board;
 
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
-/* BRINGUP: If this works then look for callers of is_master_baseio()
+#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+/* If this works then look for callers of is_master_baseio()
  * (e.g. iograph.c) and let them pass in a slot if they want
  */
 	board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module);
 #else
-	board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				    module, slot);
+	board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), module, slot);
 #endif
 
 #ifndef _STANDALONE
@@ -228,7 +230,7 @@
 		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
 
 		if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
+#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 			board = find_lboard_module((lboard_t *)
 				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
 				    module);
@@ -300,16 +302,6 @@
 	return(brd);
 }
 
-int
-get_cpu_slice(cpuid_t cpu)
-{
-	klcpu_t *acpu;
-	if ((acpu = get_cpuinfo(cpu)) == NULL)
-	    return -1;
-	return acpu->cpu_info.physid;
-}
-
-
 /*
  * get_actual_nasid
  *
@@ -366,10 +358,6 @@
 {
 	moduleid_t modnum;
 	char *board_name;
-#if !defined(CONFIG_SGI_IP35) && !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC)
-	slotid_t slot;
-	char slot_name[SLOTNUM_MAXLENGTH];
-#endif
 
 	ASSERT(brd);
 
@@ -410,7 +398,10 @@
 			
 	modnum = brd->brd_module;
 
-	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
+	/* ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); */
+if ((modnum == MODULE_UNKNOWN) || (modnum == INVALID_MODULE)) {
+	modnum = ++module_number;
+}
 #ifdef __ia64
 	{
 		char	buffer[16];
@@ -431,7 +422,7 @@
 {
 	lboard_t *brd;
 
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
 
 	if (!brd)
 		return INVALID_MODULE;
@@ -569,8 +560,8 @@
 		if (component_serial_number_get(board,
 						hub->hub_mfg_nic,
 						serial_number,
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-						"IP35"))
+#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+						"IP37"))
 #else
 						"IP27"))
 			/* Try with IP31 key if IP27 key fails */
@@ -578,7 +569,7 @@
 							hub->hub_mfg_nic,
 							serial_number,
 							"IP31"))
-#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
+#endif /* CONFIG_IA64_SGI_SN1 */
 				return(1);
 		break;
 	}
@@ -875,10 +866,11 @@
 }
 
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 
 char brick_types[MAX_BRICK_TYPES + 1] = "crikxdp789012345";
 
+#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+
 /*
  * Format a module id for printing.
  */
@@ -1009,7 +1001,7 @@
 	return (int)(unsigned short)m;
 }
 
-#else /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
+#else /* CONFIG_IA64_SGI_SN1 */
 
 /*
  * Format a module id for printing.
@@ -1038,8 +1030,8 @@
     if (strstr(buffer, EDGE_LBL_MODULE "/") == buffer)
 	buffer += strlen(EDGE_LBL_MODULE "/");
 
-    m = 0;
-    while(c = *buffer++) {
+    for (m = 0; *buffer; buffer++) {
+	c = *buffer;
 	if (!isdigit(c))
 	    return -1;
 	m = 10 * m + (c - '0');
@@ -1049,6 +1041,6 @@
     return (int)(unsigned short)m;
 }
 
-#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
+#endif /* CONFIG_IA64_SGI_SN1 */
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/klgraph.c linux/arch/ia64/sn/io/klgraph.c
--- linux.orig/arch/ia64/sn/io/klgraph.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/klgraph.c	2002-07-20 01:08:26.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
@@ -18,12 +17,12 @@
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-
-#include <asm/sn/agent.h>
 #include <asm/sn/kldir.h>
 #include <asm/sn/gda.h> 
 #include <asm/sn/klconfig.h>
@@ -43,8 +42,7 @@
 #include <asm/sn/sn_private.h>
 
 extern char arg_maxnodes[];
-extern int maxnodes;
-
+extern u64 klgraph_addr[];
 
 /*
  * Support for verbose inventory via hardware graph. 
@@ -139,193 +137,63 @@
 void
 klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
 {
+#if defined(CONFIG_IA64_SGI_SN1)
 	devfs_handle_t myhubv;
+	devfs_handle_t hub_mon;
+	devfs_handle_t synergy;
+	devfs_handle_t fsb0;
+	devfs_handle_t fsb1;
 	int rc;
+	extern struct file_operations hub_mon_fops;
 
 	GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB));
 
 	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
 	rc = device_master_set(myhubv, node_vertex);
 
-#ifdef	LATER
 	/*
-	 * Activate when we support hub stats.
+	 * hub perf stats.
 	 */
 	rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO,
                         (arbitrary_info_t)(&NODEPDA(cnode)->hubstats));
-#endif
 
 	if (rc != GRAPH_SUCCESS) {
-		PRINT_WARNING("klhwg_add_hub: Can't add hub info label 0x%p, code %d",
-			myhubv, rc);
+		printk(KERN_WARNING  "klhwg_add_hub: Can't add hub info label 0x%p, code %d",
+			(void *)myhubv, rc);
 	}
 
 	klhwg_hub_invent_info(myhubv, cnode, hub);
 
-#ifndef BRINGUP
+	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
+	    0, DEVFS_FL_AUTO_DEVNUM,
+	    0, 0,
+	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+	    &hub_mon_fops,
+	    (void *)(long)cnode);
+
 	init_hub_stats(cnode, NODEPDA(cnode));
-	sndrv_attach(myhubv);
-#else
+
 	/*
-	 * Need to call our driver to do the attach?
+	 * synergy perf
 	 */
-	FIXME("klhwg_add_hub: Need to add code to do the attach.\n");
-#endif
-}
-
-#ifndef BRINGUP
-
-void
-klhwg_add_rps(devfs_handle_t node_vertex, cnodeid_t cnode, int flag)
-{
-	devfs_handle_t myrpsv;
-	invent_rpsinfo_t *rps_invent;
-	int rc;
-
-        if(cnode == CNODEID_NONE)
-                return;                                                        
-	
-	GRPRINTF(("klhwg_add_rps: adding %s to vertex 0x%x\n", EDGE_LBL_RPS,
-		node_vertex));
-
-	rc = hwgraph_path_add(node_vertex, EDGE_LBL_RPS, &myrpsv);
-	if (rc != GRAPH_SUCCESS)
-		return;
-
-	device_master_set(myrpsv, node_vertex);
-
-        rps_invent = (invent_rpsinfo_t *)
-            klhwg_invent_alloc(cnode, INV_RPS, sizeof(invent_rpsinfo_t));
-
-        if (!rps_invent)
-            return;
-
-	rps_invent->ir_xbox = 0;	/* not an xbox RPS */
-
-        if (flag)
-            rps_invent->ir_gen.ig_flag = INVENT_ENABLED;
-        else
-            rps_invent->ir_gen.ig_flag = 0x0;                                  
-
-        hwgraph_info_add_LBL(myrpsv, INFO_LBL_DETAIL_INVENT,
-                             (arbitrary_info_t) rps_invent);
-        hwgraph_info_export_LBL(myrpsv, INFO_LBL_DETAIL_INVENT,
-                                sizeof(invent_rpsinfo_t));                     
-	
-}
-
-/*
- * klhwg_update_rps gets invoked when the system controller sends an 
- * interrupt indicating the power supply has lost/regained the redundancy.
- * It's responsible for updating the Hardware graph information.
- *	rps_state = 0 -> if the rps lost the redundancy
- *		  = 1 -> If it is redundant. 
- */
-void 
-klhwg_update_rps(cnodeid_t cnode, int rps_state)
-{
-        devfs_handle_t node_vertex;
-        devfs_handle_t rpsv;
-        invent_rpsinfo_t *rps_invent;                                          
-        int rc;
-        if(cnode == CNODEID_NONE)
-                return;                                                        
-
-        node_vertex = cnodeid_to_vertex(cnode);                                
-	rc = hwgraph_edge_get(node_vertex, EDGE_LBL_RPS, &rpsv);
-        if (rc != GRAPH_SUCCESS)  {
-		return;
-	}
-
-	rc = hwgraph_info_get_LBL(rpsv, INFO_LBL_DETAIL_INVENT, 
-				  (arbitrary_info_t *)&rps_invent);
-        if (rc != GRAPH_SUCCESS)  {
-                return;
-        }                                                                      
-
-	if (rps_state == 0 ) 
-		rps_invent->ir_gen.ig_flag = 0;
-	else 
-		rps_invent->ir_gen.ig_flag = INVENT_ENABLED;
-}
-
-void
-klhwg_add_xbox_rps(devfs_handle_t node_vertex, cnodeid_t cnode, int flag)
-{
-	devfs_handle_t myrpsv;
-	invent_rpsinfo_t *rps_invent;
-	int rc;
-
-        if(cnode == CNODEID_NONE)
-                return;                                                        
-	
-	GRPRINTF(("klhwg_add_rps: adding %s to vertex 0x%x\n", 
-		  EDGE_LBL_XBOX_RPS, node_vertex));
-
-	rc = hwgraph_path_add(node_vertex, EDGE_LBL_XBOX_RPS, &myrpsv);
-	if (rc != GRAPH_SUCCESS)
-		return;
-
-	device_master_set(myrpsv, node_vertex);
-
-        rps_invent = (invent_rpsinfo_t *)
-            klhwg_invent_alloc(cnode, INV_RPS, sizeof(invent_rpsinfo_t));
-
-        if (!rps_invent)
-            return;
-
-	rps_invent->ir_xbox = 1;	/* xbox RPS */
-
-        if (flag)
-            rps_invent->ir_gen.ig_flag = INVENT_ENABLED;
-        else
-            rps_invent->ir_gen.ig_flag = 0x0;                                  
-
-        hwgraph_info_add_LBL(myrpsv, INFO_LBL_DETAIL_INVENT,
-                             (arbitrary_info_t) rps_invent);
-        hwgraph_info_export_LBL(myrpsv, INFO_LBL_DETAIL_INVENT,
-                                sizeof(invent_rpsinfo_t));                     
-	
-}
-
-/*
- * klhwg_update_xbox_rps gets invoked when the xbox system controller
- * polls the status register and discovers that the power supply has 
- * lost/regained the redundancy.
- * It's responsible for updating the Hardware graph information.
- *	rps_state = 0 -> if the rps lost the redundancy
- *		  = 1 -> If it is redundant. 
- */
-void 
-klhwg_update_xbox_rps(cnodeid_t cnode, int rps_state)
-{
-        devfs_handle_t node_vertex;
-        devfs_handle_t rpsv;
-        invent_rpsinfo_t *rps_invent;                                          
-        int rc;
-        if(cnode == CNODEID_NONE)
-                return;                                                        
-
-        node_vertex = cnodeid_to_vertex(cnode);                                
-	rc = hwgraph_edge_get(node_vertex, EDGE_LBL_XBOX_RPS, &rpsv);
-        if (rc != GRAPH_SUCCESS)  {
-		return;
-	}
-
-	rc = hwgraph_info_get_LBL(rpsv, INFO_LBL_DETAIL_INVENT, 
-				  (arbitrary_info_t *)&rps_invent);
-        if (rc != GRAPH_SUCCESS)  {
-                return;
-        }                                                                      
-
-	if (rps_state == 0 ) 
-		rps_invent->ir_gen.ig_flag = 0;
-	else 
-		rps_invent->ir_gen.ig_flag = INVENT_ENABLED;
+	(void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy);
+	(void) hwgraph_path_add(synergy, "0", &fsb0);
+	(void) hwgraph_path_add(synergy, "1", &fsb1);
+
+	fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON,
+	    0, DEVFS_FL_AUTO_DEVNUM,
+	    0, 0,
+	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0));
+
+	fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON,
+	    0, DEVFS_FL_AUTO_DEVNUM,
+	    0, 0,
+	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1));
+#endif /* CONFIG_IA64_SGI_SN1 */
 }
 
-#endif /* BRINGUP */
-
 void
 klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
 {
@@ -338,11 +206,8 @@
 	/*REFERENCED*/
 	graph_error_t err;
 
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || defined(CONFIG_IA64_GENERIC)
-	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_IOBRICK_XBOW)) == NULL)
+	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL)
 			return;
-#endif
 
 	if (KL_CONFIG_DUPLICATE_BOARD(brd))
 	    return;
@@ -372,7 +237,7 @@
 
 		hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum);
 		if (hub_nasid == INVALID_NASID) {
-			PRINT_WARNING("hub widget %d, skipping xbow graph\n", widgetnum);
+			printk(KERN_WARNING  "hub widget %d, skipping xbow graph\n", widgetnum);
 			continue;
 		}
 
@@ -387,13 +252,13 @@
 		err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v);
                 if (err != GRAPH_SUCCESS) {
                         if (err == GRAPH_DUP)
-                                PRINT_WARNING("klhwg_add_xbow: Check for "
+                                printk(KERN_WARNING  "klhwg_add_xbow: Check for "
                                         "working routers and router links!");
 
                         PRINT_PANIC("klhwg_add_xbow: Failed to add "
-                                "edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p),"
+                                "edge: vertex 0x%p to vertex 0x%p,"
                                 "error %d\n",
-                                hubv, hubv, xbow_v, xbow_v, err);
+                                (void *)hubv, (void *)xbow_v, err);
                 }
 		xswitch_vertex_init(xbow_v); 
 
@@ -416,7 +281,7 @@
 		err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK);
 		if (err != GRAPH_SUCCESS) {
 			if (err == GRAPH_DUP)
-				PRINT_WARNING("klhwg_add_xbow: Check for "
+				printk(KERN_WARNING  "klhwg_add_xbow: Check for "
 					"working routers and router links!");
 
 			PRINT_PANIC("klhwg_add_xbow: Failed to add "
@@ -443,7 +308,7 @@
 	int board_disabled = 0;
 
 	nasid = COMPACT_TO_NASID_NODEID(cnode);
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
 	GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n",
                 cnode, nasid, brd));
 	ASSERT(brd);
@@ -495,7 +360,7 @@
 		
 		brd = KLCF_NEXT(brd);
 		if (brd)
-			brd = find_lboard(brd, KLTYPE_IP27);
+			brd = find_lboard(brd, KLTYPE_SNIA);
 		else
 			break;
 	} while(brd);
@@ -513,7 +378,7 @@
 	char path_buffer[100];
 	int rv;
 
-	for (cnode = 0; cnode < maxnodes; cnode++) {
+	for (cnode = 0; cnode < numnodes; cnode++) {
 		nasid = COMPACT_TO_NASID_NODEID(cnode);
 
 		GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n",
@@ -594,7 +459,7 @@
 			return;
 
 	if (rc != GRAPH_SUCCESS)
-		PRINT_WARNING("Can't find router: %s", path_buffer);
+		printk(KERN_WARNING  "Can't find router: %s", path_buffer);
 
 	/* We don't know what to do with multiple router components */
 	if (brd->brd_numcompts != 1) {
@@ -650,7 +515,7 @@
 
 		if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
 			PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
-				path_buffer, dest_path, dest_hndl, rc);
+				path_buffer, dest_path, (void *)dest_hndl, rc);
 		
 	}
 }
@@ -663,7 +528,7 @@
 	cnodeid_t cnode;
 	lboard_t *brd;
 
-	for (cnode = 0; cnode < maxnodes; cnode++) {
+	for (cnode = 0; cnode < numnodes; cnode++) {
 		nasid = COMPACT_TO_NASID_NODEID(cnode);
 
 		GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n",
@@ -703,14 +568,13 @@
 	char dest_path[50];
 	graph_error_t rc;
 
-	for (cnode = 0; cnode < maxnodes; cnode++) {
+	for (cnode = 0; cnode < numnodes; cnode++) {
 		nasid = COMPACT_TO_NASID_NODEID(cnode);
 
 		GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n",
 			cnode));
 
-		brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_IP27);
+		brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
 		ASSERT(brd);
 
 		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
@@ -732,7 +596,7 @@
 		rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
 
 		if (rc != GRAPH_SUCCESS)
-			PRINT_WARNING("Can't find hub: %s", path_buffer);
+			printk(KERN_WARNING  "Can't find hub: %s", path_buffer);
 
 		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
 				hub->hub_port.port_nasid,
@@ -757,7 +621,7 @@
 
 			if (rc != GRAPH_SUCCESS)
 				PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
-				path_buffer, dest_path, dest_hndl, rc);
+				path_buffer, dest_path, (void *)dest_hndl, rc);
 
 		}
 	}
@@ -896,23 +760,14 @@
 void
 klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
 {
-	//gda_t		*gdap = GDA;
-	gda_t		*gdap;
 	cnodeid_t	cnode;
 
-	gdap = (gda_t *)0xe000000000002400;
-
-	FIXME("klhwg_add_all_nodes: FIX GDA\n");
-
 	for (cnode = 0; cnode < numnodes; cnode++) {
-		ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID);
-		klhwg_add_node(hwgraph_root, cnode, gdap);
+		klhwg_add_node(hwgraph_root, cnode, NULL);
 	}
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
-		ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID);
-
-		klhwg_add_xbow(cnode, gdap->g_nasidtable[cnode]);
+		klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode));
 	}
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/klgraph_hack.c linux/arch/ia64/sn/io/klgraph_hack.c
--- linux.orig/arch/ia64/sn/io/klgraph_hack.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/klgraph_hack.c	2002-07-20 01:08:22.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -18,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
 #include <asm/sn/klconfig.h>
 
 void * real_port;
@@ -28,11 +28,11 @@
 
 kl_config_hdr_t *linux_klcfg;
 
-#ifdef BRINGUP
+#ifdef DEFINE_DUMP_RTNS
 /* forward declarations */
-extern void dump_ii(void), dump_lb(void), dump_crossbow(void);
-extern void clear_ii_error(void);
-#endif /* BRINGUP */
+static void dump_ii(void), dump_crossbow(void);
+static void clear_ii_error(void);
+#endif /* DEFINE_DUMP_RTNS */
 
 #define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
 #define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
@@ -45,115 +45,10 @@
 #define HUBREG                  ((char *)0xc0000a0001e00000)
 #define WIDGET0                 ((char *)0xc0000a0000000000)
 
-int test = 0;
-
-/*
- * Hack to loop for test.
- */
-void
-test_io_regs(void)
-{
-
-	uint32_t reg_32bits;
-	uint64_t reg_64bits;
-
-	while (test) {
-
-		reg_32bits = (uint32_t)(*(volatile uint32_t *) SYNERGY_WIDGET);
-		reg_64bits = (uint64_t) (*(volatile uint64_t *) SYNERGY_WIDGET);
-
-	}
-
-        printk("Synergy Widget Address = 0x%p, Value = 0x%lx\n", SYNERGY_WIDGET, (uint64_t)*(SYNERGY_WIDGET));
-
-        printk("Synergy swizzle Address = 0x%p, Value = 0x%lx\n", SYNERGY_SWIZZLE, (uint64_t)*(SYNERGY_SWIZZLE));
-        printk("HUBREG  Address = 0x%p, Value = 0x%lx\n",  HUBREG, (uint64_t)*(HUBREG));
-        printk("WIDGET0 Address = 0x%p, Value = 0x%lx\n", WIDGET0, (uint64_t)*(WIDGET0));
-        printk("WIDGET4 Address = 0x%p, Value = 0x%x\n", WIDGET4, (uint32_t)*(WIDGET4));
-
-}
-
 void
 klgraph_hack_init(void)
 {
 
-	kl_config_hdr_t *kl_hdr_ptr;
-	lboard_t	*lb_ptr;
-	lboard_t	*temp_ptr;
-	klhub_t		*klhub_ptr;
-	klioc3_t	*klioc3_ptr;
-	klbri_t		*klbri_ptr;
-	klxbow_t	*klxbow_ptr;
-	klinfo_t	*klinfo_ptr;
-	klcomp_t	*klcomp_ptr;
-#if 0
-	uint64_t	*tmp;
-	volatile u32	*tmp32;
-
-	/* Preset some values */
-	/* Write IOERR clear to clear the CRAZY bit in the status */
-	tmp = (uint64_t *)0xc0000a0001c001f8; *tmp = (uint64_t)0xffffffff;
-	/* set widget control register...setting bedrock widget id to b */
-	/* tmp = (uint64_t *)0xc0000a0001c00020; *tmp = (uint64_t)0x801b; */
-	/* set io outbound widget access...allow all */
-	tmp = (uint64_t *)0xc0000a0001c00110; *tmp = (uint64_t)0xff01;
-	/* set io inbound widget access...allow all */
-	tmp = (uint64_t *)0xc0000a0001c00118; *tmp = (uint64_t)0xff01;
-	/* set io crb timeout to max */
-	tmp = (uint64_t *)0xc0000a0001c003c0; *tmp = (uint64_t)0xffffff;
-	tmp = (uint64_t *)0xc0000a0001c003c0; *tmp = (uint64_t)0xffffff;
-	
-	/* set local block io permission...allow all */
-	tmp = (uint64_t *)0xc0000a0001e04010; *tmp = (uint64_t)0xfffffffffffffff;
-
-	/* clear any errors */
-	clear_ii_error();
-
-	/* set default read response buffers in bridge */
-	tmp32 = (volatile u32 *)0xc0000a000f000280L;
-	*tmp32 = 0xba98;
-	tmp32 = (volatile u32 *)0xc0000a000f000288L;
-	*tmp32 = 0xba98;
-
-printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc0000a0001e00000, *( (volatile uint64_t *)0xc0000a0001e00000) );
-
-printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc0000a0001c00000, *( (volatile uint64_t *)0xc0000a0001c00000) );
-
-printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc000020001e00000, *( (volatile uint64_t *)0xc000020001e00000) );
-
-
-printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc000020001c00000, *( (volatile uint64_t *)0xc000020001c00000) );
-
-printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc0000a0001e00000, *( (volatile uint64_t *)0xc0000a0001e00000) );
-
-printk("Xbow ID Address 0x%p Value 0x%x\n", (uint64_t *)0xc0000a0000000000, *( (volatile uint32_t *)0xc0000a0000000000) );
-
-printk("Xbow ID Address 0x%p Value 0x%x\n", (uint64_t *)0xc000020000000004, *( (volatile uint32_t *)0xc000020000000004) );
-
-#endif
-
-	if ( test )
-		test_io_regs();
-	/*
-	 * Klconfig header.
-	 */
-	kl_hdr_ptr = kmalloc(sizeof(kl_config_hdr_t), GFP_KERNEL);
-        kl_hdr_ptr->ch_magic = 0xbeedbabe;
-        kl_hdr_ptr->ch_version = 0x0;
-        kl_hdr_ptr->ch_malloc_hdr_off = 0x48;
-        kl_hdr_ptr->ch_cons_off = 0x18;
-        kl_hdr_ptr->ch_board_info = 0x0;
-        kl_hdr_ptr->ch_cons_info.uart_base = 0x920000000f820178;
-        kl_hdr_ptr->ch_cons_info.config_base = 0x920000000f024000;
-        kl_hdr_ptr->ch_cons_info.memory_base = 0x920000000f800000;
-        kl_hdr_ptr->ch_cons_info.baud = 0x2580;
-        kl_hdr_ptr->ch_cons_info.flag = 0x1;
-        kl_hdr_ptr->ch_cons_info.type = 0x300fafa;
-        kl_hdr_ptr->ch_cons_info.nasid = 0x0;
-        kl_hdr_ptr->ch_cons_info.wid = 0xf;
-        kl_hdr_ptr->ch_cons_info.npci = 0x4;
-        kl_hdr_ptr->ch_cons_info.baseio_nic = 0x0;
-
 	/*
 	 * We need to know whether we are booting from PROM or 
 	 * boot from disk.
@@ -162,520 +57,44 @@
 	if (linux_klcfg->ch_magic == 0xbeedbabe) {
 		return;
 	} else {
-		linux_klcfg = kl_hdr_ptr;
+		panic("klgraph_hack_init: Unable to locate KLCONFIG TABLE\n");
 	}
 
-	/*
-	 * lboard KLTYPE_IP35
-	 */
-	lb_ptr = kmalloc(sizeof(lboard_t), GFP_KERNEL);
-	kl_hdr_ptr->ch_board_info = (klconf_off_t) lb_ptr;
-	temp_ptr = lb_ptr;
-	printk("First Lboard = %p\n", temp_ptr);
-
-        lb_ptr->brd_next = 0;
-        lb_ptr->struct_type = 0x1;
-        lb_ptr->brd_type  = 0x11;
-        lb_ptr->brd_sversion = 0x3;
-        lb_ptr->brd_brevision = 0x1;
-        lb_ptr->brd_promver = 0x1;
-        lb_ptr->brd_promver = 0x1;
-        lb_ptr->brd_slot = 0x0;
-        lb_ptr->brd_debugsw = 0x0;
-        lb_ptr->brd_module = 0x145;
-        lb_ptr->brd_partition = 0x0;
-        lb_ptr->brd_diagval = 0x0;
-        lb_ptr->brd_diagparm = 0x0;
-        lb_ptr->brd_inventory = 0x0;
-        lb_ptr->brd_numcompts = 0x5;
-        lb_ptr->brd_nic = 0x2a0aed35;
-        lb_ptr->brd_nasid = 0x0;
-        lb_ptr->brd_errinfo = 0x0;
-        lb_ptr->brd_parent = 0x0;
-        lb_ptr->brd_graph_link  = (devfs_handle_t)0x26;
-        lb_ptr->brd_owner = 0x0;
-        lb_ptr->brd_nic_flags = 0x0;
-	memcpy(&lb_ptr->brd_name[0], "IP35", 4);
-
-	/*
-	 * Hub Component
-	 */
-	klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-	klhub_ptr = (klhub_t *)klcomp_ptr;
-	klinfo_ptr = (klinfo_t *)klcomp_ptr;
-	lb_ptr->brd_compts[0] = (klconf_off_t)klcomp_ptr;
-	printk("hub info = %p lboard = %p\n", klhub_ptr, lb_ptr);
-
-	klinfo_ptr = (klinfo_t *)klhub_ptr;
-        klinfo_ptr->struct_type = 0x2;
-        klinfo_ptr->struct_version = 0x1;
-        klinfo_ptr->flags = 0x1;
-        klinfo_ptr->revision = 0x1;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0x2a0aed35;
-        klinfo_ptr->physid = 0x0;
-        klinfo_ptr->virtid = 0x0;
-        klinfo_ptr->widid = 0x0;
-        klinfo_ptr->nasid = 0x0;
-
-        klhub_ptr->hub_flags = 0x0;
-        klhub_ptr->hub_port.port_nasid = (nasid_t)0x0ffffffff;
-        klhub_ptr->hub_port.port_flag = 0x0;
-        klhub_ptr->hub_port.port_offset = 0x0;
-        klhub_ptr->hub_box_nic = 0x0;
-        klhub_ptr->hub_mfg_nic = 0x3f420;
-        klhub_ptr->hub_speed = 0xbebc200;
-
-	/*
-	 * Memory Component
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-	lb_ptr->brd_compts[1] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x3;
-        klinfo_ptr->struct_version = 0x2;
-        klinfo_ptr->flags = 0x1;
-        klinfo_ptr->revision = 0xff;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0xff;
-        klinfo_ptr->virtid = 0xffffffff;
-        klinfo_ptr->widid = 0x0;
-        klinfo_ptr->nasid = 0x0;
-
-	/*
-	 * KLSTRUCT_HUB_UART Component
-	 */
-	klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-	klinfo_ptr = (klinfo_t *)klcomp_ptr;
-	lb_ptr->brd_compts[2] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x11;
-        klinfo_ptr->struct_version = 0x1;
-        klinfo_ptr->flags = 0x31;
-        klinfo_ptr->revision = 0xff;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0x0;
-        klinfo_ptr->virtid = 0x0;
-        klinfo_ptr->widid = 0x0;
-        klinfo_ptr->nasid = 0x0;
-
-	/*
-	 * KLSTRUCT_CPU Component
-	 */
-	klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-	lb_ptr->brd_compts[3] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x1;
-        klinfo_ptr->struct_version = 0x2;
-        klinfo_ptr->flags = 0x1;
-        klinfo_ptr->revision = 0xff;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0x0;
-        klinfo_ptr->virtid = 0x0;
-        klinfo_ptr->widid = 0x0;
-        klinfo_ptr->nasid = 0x0;
-
-	/*
-	 * KLSTRUCT_CPU Component
-	 */
-	klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-	lb_ptr->brd_compts[4] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x1;
-        klinfo_ptr->struct_version = 0x2;
-        klinfo_ptr->flags = 0x1;
-        klinfo_ptr->revision = 0xff;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0x1;
-        klinfo_ptr->virtid = 0x1;
-        klinfo_ptr->widid = 0x0;
-        klinfo_ptr->nasid = 0x0;
-
-	lb_ptr->brd_compts[5] = 0; /* Set the next one to 0 .. end */
-	lb_ptr->brd_numcompts = 5; /* 0 to 4 */
-
-	/*
-	 * lboard(0x42) KLTYPE_PBRICK_XBOW
-	 */
-	lb_ptr = kmalloc(sizeof(lboard_t), GFP_KERNEL);
-	temp_ptr->brd_next = (klconf_off_t)lb_ptr; /* Let the previous point at the new .. */
-	temp_ptr = lb_ptr;
-	printk("Second Lboard = %p\n", temp_ptr);
-
-        lb_ptr->brd_next = 0;
-        lb_ptr->struct_type = 0x1;
-        lb_ptr->brd_type  = 0x42;
-        lb_ptr->brd_sversion = 0x2;
-        lb_ptr->brd_brevision = 0x0;
-        lb_ptr->brd_promver = 0x1;
-        lb_ptr->brd_promver = 0x1;
-        lb_ptr->brd_slot = 0x0;
-        lb_ptr->brd_debugsw = 0x0;
-        lb_ptr->brd_module = 0x145;
-        lb_ptr->brd_partition = 0x1;
-        lb_ptr->brd_diagval = 0x0;
-        lb_ptr->brd_diagparm = 0x0;
-        lb_ptr->brd_inventory = 0x0;
-        lb_ptr->brd_numcompts = 0x1;
-        lb_ptr->brd_nic = 0xffffffffffffffff;
-        lb_ptr->brd_nasid = 0x0;
-        lb_ptr->brd_errinfo = 0x0;
-        lb_ptr->brd_parent = (struct lboard_s *)0x9600000000030070;
-        lb_ptr->brd_graph_link  = (devfs_handle_t)0xffffffff;
-        lb_ptr->brd_owner = 0x0;
-        lb_ptr->brd_nic_flags = 0x0;
-        memcpy(&lb_ptr->brd_name[0], "IOBRICK", 7);
-
-	/*
-	 * KLSTRUCT_XBOW Component
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-	memset(klcomp_ptr, 0, sizeof(klcomp_t));
-        klxbow_ptr = (klxbow_t *)klcomp_ptr;
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-        lb_ptr->brd_compts[0] = (klconf_off_t)klcomp_ptr;
-	printk("xbow_p 0x%p\n", klcomp_ptr);
-
-        klinfo_ptr->struct_type = 0x4;
-        klinfo_ptr->struct_version = 0x1;
-        klinfo_ptr->flags = 0x1;
-        klinfo_ptr->revision = 0x2;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0xff;
-        klinfo_ptr->virtid = 0x0;
-        klinfo_ptr->widid = 0x0;
-        klinfo_ptr->nasid = 0x0;
-
-        klxbow_ptr->xbow_master_hub_link = 0xb;
-        klxbow_ptr->xbow_port_info[0].port_nasid = 0x0;
-        klxbow_ptr->xbow_port_info[0].port_flag = 0x0;
-        klxbow_ptr->xbow_port_info[0].port_offset = 0x0;
-
-        klxbow_ptr->xbow_port_info[1].port_nasid = 0x401;
-        klxbow_ptr->xbow_port_info[1].port_flag = 0x0;
-        klxbow_ptr->xbow_port_info[1].port_offset = 0x0;
-
-        klxbow_ptr->xbow_port_info[2].port_nasid = 0x0;
-        klxbow_ptr->xbow_port_info[2].port_flag = 0x0;
-        klxbow_ptr->xbow_port_info[2].port_offset = 0x0;
-
-        klxbow_ptr->xbow_port_info[3].port_nasid = 0x0; /* ffffffff */
-        klxbow_ptr->xbow_port_info[3].port_flag = 0x6;
-        klxbow_ptr->xbow_port_info[3].port_offset = 0x30070;
-
-        klxbow_ptr->xbow_port_info[4].port_nasid = 0x0; /* ffffff00; */
-        klxbow_ptr->xbow_port_info[4].port_flag = 0x0;
-        klxbow_ptr->xbow_port_info[4].port_offset = 0x0;
-
-        klxbow_ptr->xbow_port_info[5].port_nasid = 0x0;
-        klxbow_ptr->xbow_port_info[5].port_flag = 0x0;
-        klxbow_ptr->xbow_port_info[5].port_offset = 0x0;
-        klxbow_ptr->xbow_port_info[6].port_nasid = 0x0;
-        klxbow_ptr->xbow_port_info[6].port_flag = 0x5;
-        klxbow_ptr->xbow_port_info[6].port_offset = 0x30210;
-        klxbow_ptr->xbow_port_info[7].port_nasid = 0x3;
-        klxbow_ptr->xbow_port_info[7].port_flag = 0x5;
-        klxbow_ptr->xbow_port_info[7].port_offset = 0x302e0;
-	
-	lb_ptr->brd_compts[1] = 0;
-        lb_ptr->brd_numcompts = 1;
-
-
-	/*
-	 * lboard KLTYPE_PBRICK
-	 */
-	lb_ptr = kmalloc(sizeof(lboard_t), GFP_KERNEL);
-	temp_ptr->brd_next = (klconf_off_t)lb_ptr; /* Let the previous point at the new .. */
-	temp_ptr = lb_ptr;
-	printk("Third Lboard %p\n", lb_ptr);
-
-        lb_ptr->brd_next = 0;
-        lb_ptr->struct_type = 0x1;
-        lb_ptr->brd_type  = 0x72;
-        lb_ptr->brd_sversion = 0x2;
-        lb_ptr->brd_brevision = 0x0;
-        lb_ptr->brd_promver = 0x1;
-        lb_ptr->brd_promver = 0x41;
-        lb_ptr->brd_slot = 0xe;
-        lb_ptr->brd_debugsw = 0x0;
-        lb_ptr->brd_module = 0x145;
-        lb_ptr->brd_partition = 0x1;
-        lb_ptr->brd_diagval = 0x0;
-        lb_ptr->brd_diagparm = 0x0;
-        lb_ptr->brd_inventory = 0x0;
-        lb_ptr->brd_numcompts = 0x1;
-        lb_ptr->brd_nic = 0x30e3fd;
-        lb_ptr->brd_nasid = 0x0;
-        lb_ptr->brd_errinfo = 0x0;
-        lb_ptr->brd_parent = (struct lboard_s *)0x9600000000030140;
-        lb_ptr->brd_graph_link  = (devfs_handle_t)0xffffffff;
-        lb_ptr->brd_owner = 0x0;
-        lb_ptr->brd_nic_flags = 0x0;
-	memcpy(&lb_ptr->brd_name[0], "IP35", 4);
-
-	/*
-	 * KLSTRUCT_BRI Component
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klbri_ptr = (klbri_t *)klcomp_ptr;
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-        lb_ptr->brd_compts[0] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x5;
-        klinfo_ptr->struct_version = 0x2;
-        klinfo_ptr->flags = 0x1;
-        klinfo_ptr->revision = 0x2;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0xd002;
-        klinfo_ptr->nic = 0x30e3fd;
-        klinfo_ptr->physid = 0xe;
-        klinfo_ptr->virtid = 0xe;
-        klinfo_ptr->widid = 0xe;
-        klinfo_ptr->nasid = 0x0;
-
-        klbri_ptr->bri_eprominfo = 0xff;
-        klbri_ptr->bri_bustype = 0x7;
-        klbri_ptr->bri_mfg_nic = 0x3f4a8;
-
-        lb_ptr->brd_compts[1] = 0;
-        lb_ptr->brd_numcompts = 1;
-
-	/*
-	 * lboard KLTYPE_PBRICK
-	 */
-	lb_ptr = kmalloc(sizeof(lboard_t), GFP_KERNEL);
-	temp_ptr->brd_next = (klconf_off_t)lb_ptr; /* Let the previous point at the new .. */
-	temp_ptr = lb_ptr;
-	printk("Fourth Lboard %p\n", lb_ptr);
-
-        lb_ptr->brd_next = 0x0;
-        lb_ptr->struct_type = 0x1;
-        lb_ptr->brd_type  = 0x72;
-        lb_ptr->brd_sversion = 0x2;
-        lb_ptr->brd_brevision = 0x0;
-        lb_ptr->brd_promver = 0x1;
-        lb_ptr->brd_promver = 0x31;
-        lb_ptr->brd_slot = 0xf;
-        lb_ptr->brd_debugsw = 0x0;
-        lb_ptr->brd_module = 0x145;
-        lb_ptr->brd_partition = 0x1;
-        lb_ptr->brd_diagval = 0x0;
-        lb_ptr->brd_diagparm = 0x0;
-        lb_ptr->brd_inventory = 0x0;
-        lb_ptr->brd_numcompts = 0x6;
-        lb_ptr->brd_nic = 0x30e3fd;
-        lb_ptr->brd_nasid = 0x0;
-        lb_ptr->brd_errinfo = 0x0;
-        lb_ptr->brd_parent = (struct lboard_s *)0x9600000000030140;
-        lb_ptr->brd_graph_link  = (devfs_handle_t)0xffffffff;
-        lb_ptr->brd_owner = 0x0;
-        lb_ptr->brd_nic_flags = 0x0;
-	memcpy(&lb_ptr->brd_name[0], "IP35", 4);
-
-
-	/*
-	 * KLSTRUCT_BRI Component
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-	klbri_ptr = (klbri_t *)klcomp_ptr;
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-        lb_ptr->brd_compts[0] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x5;
-        klinfo_ptr->struct_version = 0x2;
-        klinfo_ptr->flags = 0x1;
-        klinfo_ptr->revision = 0x2;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0xd002;
-        klinfo_ptr->nic = 0x30e3fd;
-        klinfo_ptr->physid = 0xf;
-        klinfo_ptr->virtid = 0xf;
-        klinfo_ptr->widid = 0xf;
-        klinfo_ptr->nasid = 0x0;
-
-        klbri_ptr->bri_eprominfo = 0xff;
-        klbri_ptr->bri_bustype = 0x7;
-        klbri_ptr->bri_mfg_nic = 0x3f528;
-
-	/*
-	 * KLSTRUCT_SCSI component
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-        lb_ptr->brd_compts[1] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0xb;
-        klinfo_ptr->struct_version = 0x1;
-        klinfo_ptr->flags = 0x31;
-        klinfo_ptr->revision = 0x5;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0x1;
-        klinfo_ptr->virtid = 0x0;
-        klinfo_ptr->widid = 0xf;
-        klinfo_ptr->nasid = 0x0;
-
-	/*
-	 * KLSTRUCT_IOC3 Component
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klioc3_ptr = (klioc3_t *)klcomp_ptr;
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-        lb_ptr->brd_compts[2] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x6;
-        klinfo_ptr->struct_version = 0x1;
-        klinfo_ptr->flags = 0x31;
-        klinfo_ptr->revision = 0x1;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0x4;
-        klinfo_ptr->virtid = 0x0;
-        klinfo_ptr->widid = 0xf;
-        klinfo_ptr->nasid = 0x0;
-
-        klioc3_ptr->ioc3_ssram = 0x0;
-        klioc3_ptr->ioc3_nvram = 0x0;
-
-	/*
-	 * KLSTRUCT_UNKNOWN Component
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-        lb_ptr->brd_compts[3] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x0;
-        klinfo_ptr->struct_version = 0x1;
-        klinfo_ptr->flags = 0x31;
-        klinfo_ptr->revision = 0xff;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0x5;
-        klinfo_ptr->virtid = 0x0;
-        klinfo_ptr->widid = 0xf;
-        klinfo_ptr->nasid = 0x0;
-
-	/*
-	 * KLSTRUCT_SCSI Component
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-        lb_ptr->brd_compts[4] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0xb;
-        klinfo_ptr->struct_version = 0x1;
-        klinfo_ptr->flags = 0x31;
-        klinfo_ptr->revision = 0x1;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0x6;
-        klinfo_ptr->virtid = 0x5;
-        klinfo_ptr->widid = 0xf;
-        klinfo_ptr->nasid = 0x0;
-
-	/*
-	 * KLSTRUCT_UNKNOWN
-	 */
-        klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL);
-        klinfo_ptr = (klinfo_t *)klcomp_ptr;
-        lb_ptr->brd_compts[5] = (klconf_off_t)klcomp_ptr;
-
-        klinfo_ptr->struct_type = 0x0;
-        klinfo_ptr->struct_version = 0x1;
-        klinfo_ptr->flags = 0x31;
-        klinfo_ptr->revision = 0xff;
-        klinfo_ptr->diagval = 0x0;
-        klinfo_ptr->diagparm = 0x0;
-        klinfo_ptr->inventory = 0x0;
-        klinfo_ptr->partid = 0x0;
-        klinfo_ptr->nic = 0xffffffffffffffff;
-        klinfo_ptr->physid = 0x7;
-        klinfo_ptr->virtid = 0x0;
-        klinfo_ptr->widid = 0xf;
-        klinfo_ptr->nasid = 0x0;
-
-	lb_ptr->brd_compts[6] = 0;
-	lb_ptr->brd_numcompts = 6;
-
 }
 
 
 
 
 	
-#ifdef BRINGUP
+#ifdef DEFINE_DUMP_RTNS
 /* 
  * these were useful for printing out registers etc
  * during bringup  
  */
 
-void
+static void
 xdump(long long *addr, int count)
 {
 	int ii;
 	volatile long long *xx = addr;
 
 	for ( ii = 0; ii < count; ii++, xx++ ) {
-		printk("0x%p : 0x%p\n", xx, *xx);
+		printk("0x%p : 0x%p\n", (void *)xx, (void *)*xx);
 	}
 }
 
-void
+static void
 xdump32(unsigned int *addr, int count)
 {
 	int ii;
 	volatile unsigned int *xx = addr;
 
 	for ( ii = 0; ii < count; ii++, xx++ ) {
-		printk("0x%p : 0x%0x\n", xx, *xx);
+		printk("0x%p : 0x%0x\n", (void *)xx, (int)*xx);
 	}
 }
 
-
-
-void
+static void
 clear_ii_error(void)
 {
 	volatile long long *tmp;
@@ -716,8 +135,8 @@
 }
 
 
-void
-dump_ii()
+static void
+dump_ii(void)
 {
 	printk("===== Dump the II regs =====\n");
 	xdump((long long *)0xc0000a0001c00000, 2);
@@ -746,23 +165,8 @@
 	xdump((long long *)0xc0000a000f000000, 1);
 }
 
-void
-dump_lb()
-{
-	printk("===== Dump the LB regs =====\n");
-	xdump((long long *)0xc0000a0001e00000, 1);
-	xdump((long long *)0xc0000a0001e04000, 13);
-	xdump((long long *)0xc0000a0001e04100, 2);
-	xdump((long long *)0xc0000a0001e04200, 2);
-	xdump((long long *)0xc0000a0001e08000, 5);
-	xdump((long long *)0xc0000a0001e08040, 2);
-	xdump((long long *)0xc0000a0001e08050, 3);
-	xdump((long long *)0xc0000a0001e0c000, 3);
-	xdump((long long *)0xc0000a0001e0c020, 4);
-}
-
-void
-dump_crossbow()
+static void
+dump_crossbow(void)
 {
 	printk("===== Dump the Crossbow regs =====\n");
 	clear_ii_error();
@@ -793,4 +197,4 @@
 
 
 }
-#endif /* BRINGUP */
+#endif /* DEFINE_DUMP_RTNS */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/l1.c linux/arch/ia64/sn/io/l1.c
--- linux.orig/arch/ia64/sn/io/l1.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/l1.c	2002-07-20 01:08:33.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
  */
 
 /* In general, this file is organized in a hierarchy from lower-level
@@ -16,18 +15,12 @@
  *	System controller "message" interface (allows multiplexing
  *		of various kinds of requests and responses with
  *		console I/O)
- *	Console interfaces (there are two):
- *	  (1) "elscuart", used in the IP35prom and (maybe) some
- *		debugging situations elsewhere, and
- *	  (2) "l1_cons", the glue that allows the L1 to act
+ *	Console interface:
+ *	  "l1_cons", the glue that allows the L1 to act
  *		as the system console for the stdio libraries
  *
  * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.  Their names are leftover from early SN0, 
- * when the "module system controller" (msc) was known as the "entry level
- * system controller" (elsc).  The names and signatures of those functions 
- * remain unchanged in order to keep the SN0 -> SN1 system controller
- * changes fairly localized.
+ * can be found in l1_command.c.
  */
 
 
@@ -35,45 +28,32 @@
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/delay.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
 #include <asm/sn/labelcl.h>
 #include <asm/sn/eeprom.h>
-#include <asm/sn/ksys/i2c.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
 #include <asm/sn/nodepda.h>
 #include <asm/sn/clksupport.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/uart16550.h>
+#include <asm/sn/simulator.h>
 
-#include <asm/sn/sn1/uart16550.h>
-
-/*
- * Delete this when atomic_clear is part of atomic.h.
- */
-static __inline__ int
-atomic_clear (int i, atomic_t *v)
-{
-	__s32 old, new;
-
-	do {
-		old = atomic_read(v);
-		new = old & ~i;
-	} while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old);
-	return new;
-}
-
-#if defined(EEPROM_DEBUG)
-#define db_printf(x) printk x
-#else
-#define db_printf(x)
+#if defined(CONFIG_IA64_SGI_SN2)
+#define USE_SAL_CONSOLE_IO	1	/* DON'T un-def this for the simulator... */
 #endif
 
-// From irix/kern/sys/SN/SN1/bdrkhspecregs.h
-#define    HSPEC_UART_0              0x00000080    /* UART Registers         */
+/* Make all console writes atomic */
+#define SYNC_CONSOLE_WRITE	1
+
 
 /*********************************************************************
  * Hardware-level (UART) driver routines.
@@ -81,28 +61,33 @@
 
 /* macros for reading/writing registers */
 
-#define LD(x)		(*(volatile uint64_t *)(x))
-#define SD(x, v)        (LD(x) = (uint64_t) (v))
+#define LD(x)			(*(volatile uint64_t *)(x))
+#define SD(x, v)        	(LD(x) = (uint64_t) (v))
 
 /* location of uart receive/xmit data register */
-#define L1_UART_BASE(n)	((ulong)REMOTE_HSPEC_ADDR((n), HSPEC_UART_0))
-#define LOCAL_HUB	LOCAL_HUB_ADDR
-#define LOCK_HUB	REMOTE_HUB_ADDR
-
-#define ADDR_L1_REG(n, r)	\
-    (L1_UART_BASE(n) | ( (r) << 3 ))
+#if defined(CONFIG_IA64_SGI_SN1)
+#define L1_UART_BASE(n)		((ulong)REMOTE_HSPEC_ADDR((n), 0x00000080))
+#define LOCK_HUB		REMOTE_HUB_ADDR
+#elif defined(CONFIG_IA64_SGI_SN2)
+#define L1_UART_BASE(n)		((ulong)REMOTE_HUB((n), SH_JUNK_BUS_UART0))
+#define LOCK_HUB		REMOTE_HUB
+typedef u64 rtc_time_t;
+#endif
 
-#define READ_L1_UART_REG(n, r) \
-    ( LD(ADDR_L1_REG((n), (r))) )
 
-#define WRITE_L1_UART_REG(n, r, v) \
-    ( SD(ADDR_L1_REG((n), (r)), (v)) )
+#define ADDR_L1_REG(n, r)	( L1_UART_BASE(n) | ( (r) << 3 ) )
+#define READ_L1_UART_REG(n, r)	( LD(ADDR_L1_REG((n), (r))) )
+#define WRITE_L1_UART_REG(n, r, v) ( SD(ADDR_L1_REG((n), (r)), (v)) )
+
+/* upper layer interface calling methods */
+#define SERIAL_INTERRUPT_MODE	0
+#define SERIAL_POLLED_MODE	1
 
 
 /* UART-related #defines */
 
 #define UART_BAUD_RATE		57600
-#define UART_FIFO_DEPTH		0xf0
+#define UART_FIFO_DEPTH		16
 #define UART_DELAY_SPAN		10
 #define UART_PUTC_TIMEOUT	50000
 #define UART_INIT_TIMEOUT	100000
@@ -114,17 +99,32 @@
 #define UART_NO_CHAR		(-3)
 #define UART_VECTOR		(-4)
 
-#ifdef BRINGUP
-#define UART_DELAY(x)	{ int i; i = x * 1000; while (--i); }
-#else
-#define UART_DELAY(x)	us_delay(x)
-#endif
+#define UART_DELAY(x)		udelay(x)
+
+/* Some debug counters */
+#define L1C_INTERRUPTS		0
+#define L1C_OUR_R_INTERRUPTS	1
+#define L1C_OUR_X_INTERRUPTS	2
+#define L1C_SEND_CALLUPS	3
+#define L1C_RECEIVE_CALLUPS	4
+#define L1C_SET_BAUD		5
+#define L1C_ALREADY_LOCKED	L1C_SET_BAUD
+#define L1C_R_IRQ		6
+#define L1C_R_IRQ_RET		7
+#define L1C_LOCK_TIMEOUTS	8
+#define L1C_LOCK_COUNTER	9
+#define L1C_UNLOCK_COUNTER	10
+#define L1C_REC_STALLS		11
+#define L1C_CONNECT_CALLS	12
+#define L1C_SIZE		L1C_CONNECT_CALLS	/* Set to the last one */
+
+uint64_t L1_collectibles[L1C_SIZE + 1];
+
 
 /*
  *	Some macros for handling Endian-ness
  */
 
-#ifdef	LITTLE_ENDIAN
 #define COPY_INT_TO_BUFFER(_b, _i, _n)		\
 	{					\
 		_b[_i++] = (_n >> 24) & 0xff;	\
@@ -149,42 +149,64 @@
 	    _xyz[1] = _b[_i++];			\
 	    _xyz[0] = _b[_i++];			\
 	}
-#else	/* BIG_ENDIAN */
-
-extern char *bcopy(const char * src, char * dest, int count);
 
-#define COPY_INT_TO_BUFFER(_b, _i, _n)			\
-	{						\
-		bcopy((char *)&_n, _b, sizeof(_n));	\
-		_i += sizeof(_n);			\
-	}
+void snia_kmem_free(void *where, int size);
 
-#define COPY_BUFFER_TO_INT(_b, _i, _n)			\
-	{						\
-		bcopy(&_b[_i], &_n, sizeof(_n));	\
-		_i += sizeof(_n);			\
-	}
+#define ALREADY_LOCKED		1
+#define NOT_LOCKED		0
+static int early_l1_serial_out(nasid_t, char *, int, int /* defines above*/ );
 
-#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn)		\
-	{						\
-            bcopy(&(_b[_i]), _bn, sizeof(int));		\
-            _i += sizeof(int);				\
-	}
-#endif	/* LITTLE_ENDIAN */
+#define BCOPY(x,y,z)	memcpy(y,x,z)
 
-void kmem_free(void *where, int size);
+uint8_t L1_interrupts_connected;		/* Non-zero when we are in interrupt mode */
 
-#define BCOPY(x,y,z)	memcpy(y,x,z)
 
 /*
  * Console locking defines and functions.
  *
  */
 
-#ifdef BRINGUP
-#define FORCE_CONSOLE_NASID
+uint8_t L1_cons_is_inited = 0;			/* non-zero when console is init'd */
+nasid_t Master_console_nasid = (nasid_t)-1;
+extern nasid_t console_nasid;
+
+#if defined(CONFIG_IA64_SGI_SN1)
+u64 ia64_sn_get_console_nasid(void);
 #endif
 
+inline nasid_t
+get_master_nasid(void)
+{
+#if defined(CONFIG_IA64_SGI_SN1)
+	nasid_t nasid = Master_console_nasid;
+
+	if ( nasid == (nasid_t)-1 ) {
+		nasid = (nasid_t)ia64_sn_get_console_nasid();
+		if ( (nasid < 0) || (nasid >= MAX_NASIDS) ) {
+			/* Out of bounds, use local */
+			console_nasid = nasid = get_nasid();
+		}
+		else {
+			/* Got a valid nasid, set the console_nasid */
+			char xx[100];
+/* zzzzzz - force nasid to 0 for now */
+			sprintf(xx, "Master console is set to nasid %d (%d)\n", 0, (int)nasid);
+nasid = 0;
+/* end zzzzzz */
+			xx[99] = (char)0;
+			early_l1_serial_out(nasid, xx, strlen(xx), NOT_LOCKED);
+			Master_console_nasid = console_nasid = nasid;
+		}
+	}
+	return(nasid);
+#else
+	return((nasid_t)0);
+#endif	/* CONFIG_IA64_SGI_SN1 */
+}
+
+
+#if defined(CONFIG_IA64_SGI_SN1)
+
 #define HUB_LOCK		16
 
 #define PRIMARY_LOCK_TIMEOUT    10000000
@@ -199,7 +221,6 @@
 
 #define RTC_TIME_MAX		((rtc_time_t) ~0ULL)
 
-
 /*
  * primary_lock
  *
@@ -295,26 +316,37 @@
 
 #define LOCK_TIMEOUT	(0x1500000 * 1) /* 0x1500000 is ~30 sec */
 
-inline void
+void
 lock_console(nasid_t nasid)
 {
 	int ret;
 
+	/* If we already have it locked, just return */
+	L1_collectibles[L1C_LOCK_COUNTER]++;
+
 	ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
 	if ( ret != 0 ) {
+		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
 		/* timeout */
 		hub_unlock(nasid, HUB_LOCK);
 		/* If the 2nd lock fails, just pile ahead.... */
 		hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
+		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
 	}
 }
 
 inline void
 unlock_console(nasid_t nasid)
 {
+	L1_collectibles[L1C_UNLOCK_COUNTER]++;
 	hub_unlock(nasid, HUB_LOCK);
 }
 
+#else /* SN2 */
+inline void lock_console(nasid_t n)	{}
+inline void unlock_console(nasid_t n)	{}
+
+#endif	/* CONFIG_IA64_SGI_SN1 */
 
 int 
 get_L1_baud(void)
@@ -325,27 +357,18 @@
 
 /* uart driver functions */
 
-static void
+static inline void
 uart_delay( rtc_time_t delay_span )
 {
     UART_DELAY( delay_span );
 }
 
-#define UART_PUTC_READY(n)      ( (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE) && (READ_L1_UART_REG((n), REG_MSR) & MSR_CTS) )
+#define UART_PUTC_READY(n)      (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE)
 
 static int
 uart_putc( l1sc_t *sc ) 
 {
-#ifdef BRINGUP
-    /* need a delay to avoid dropping chars */
-    UART_DELAY(57);
-#endif
-#ifdef FORCE_CONSOLE_NASID
-    /* We need this for the console write path _elscuart_flush() -> brl1_send() */
-    sc->nasid = 0;
-#endif
-    WRITE_L1_UART_REG( sc->nasid, REG_DAT,
-		       sc->send[sc->sent] );
+    WRITE_L1_UART_REG( sc->nasid, REG_DAT, sc->send[sc->sent] );
     return UART_SUCCESS;
 }
 
@@ -356,10 +379,6 @@
     u_char lsr_reg = 0;
     nasid_t nasid = sc->nasid;
 
-#ifdef FORCE_CONSOLE_NASID
-    nasid = sc->nasid = 0;
-#endif
-
     if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & 
 	(LSR_RCA | LSR_PARERR | LSR_FRMERR) ) 
     {
@@ -396,9 +415,10 @@
 	}
     }
 
-    if ( sc->uart == BRL1_LOCALUART )
+    if ( sc->uart == BRL1_LOCALHUB_UART )
 	lock_console(nasid);
 
+    /* Setup for the proper baud rate */
     WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB );
 	uart_delay( UART_DELAY_SPAN );
     WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff );
@@ -407,6 +427,8 @@
 	uart_delay( UART_DELAY_SPAN );
 
     /* set operating parameters and set DLAB to 0 */
+
+    /* 8bit, one stop, clear request to send, auto flow control */
     WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 );
 	uart_delay( UART_DELAY_SPAN );
     WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE );
@@ -416,23 +438,28 @@
     WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 );
 	uart_delay( UART_DELAY_SPAN );
 
-    /* enable FIFO mode and reset both FIFOs */
+    /* enable FIFO mode and reset both FIFOs, trigger on 1 */
     WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN );
 	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_FCR,
-	FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO );
+    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL0);
 
-    if ( sc->uart == BRL1_LOCALUART )
+    if ( sc->uart == BRL1_LOCALHUB_UART )
 	unlock_console(nasid);
 }
 
 /* This requires the console lock */
+
+#if	defined(CONFIG_IA64_SGI_SN1)
+
 static void
 uart_intr_enable( l1sc_t *sc, u_char mask )
 {
     u_char lcr_reg, icr_reg;
     nasid_t nasid = sc->nasid;
 
+    if ( sc->uart == BRL1_LOCALHUB_UART )
+	lock_console(nasid);
+
     /* make sure that the DLAB bit in the LCR register is 0
      */
     lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
@@ -444,6 +471,9 @@
     icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
     icr_reg |= mask;
     WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
+
+    if ( sc->uart == BRL1_LOCALHUB_UART )
+	unlock_console(nasid);
 }
 
 /* This requires the console lock */
@@ -453,6 +483,9 @@
     u_char lcr_reg, icr_reg;
     nasid_t nasid = sc->nasid;
 
+    if ( sc->uart == BRL1_LOCALHUB_UART )
+	lock_console(nasid);
+
     /* make sure that the DLAB bit in the LCR register is 0
      */
     lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
@@ -464,7 +497,11 @@
     icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
     icr_reg &= mask;
     WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
+
+    if ( sc->uart == BRL1_LOCALHUB_UART )
+	unlock_console(nasid);
 }
+#endif	/* CONFIG_IA64_SGI_SN1 */
 
 #define uart_enable_xmit_intr(sc) \
 	uart_intr_enable((sc), ICR_TIEN)
@@ -511,10 +548,6 @@
     net_vec_t path = sc->uart;
     rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT;
 
-#ifdef FORCE_CONSOLE_NASID
-    /* We need this for the console write path _elscuart_flush() -> brl1_send() */
-    nasid = sc->nasid = 0;
-#endif
     c = (sc->send[sc->sent] & 0xffULL);
     
     while( 1 ) 
@@ -543,10 +576,6 @@
     nasid_t nasid = sc->nasid;
     net_vec_t path = sc->uart;
 
-#ifdef FORCE_CONSOLE_NASID
-    nasid = sc->nasid = 0;
-#endif
-
     READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
     if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) )
     {
@@ -617,6 +646,15 @@
     return 0;
 }
 
+/*********************************************************************
+ * locking macros 
+ */
+
+#define L1SC_SEND_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->send_lock),p); }
+#define L1SC_SEND_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->send_lock), p); }
+#define L1SC_RECV_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->recv_lock), p); } 
+#define L1SC_RECV_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->recv_lock), p); }
+
 
 /*********************************************************************
  * subchannel manipulation 
@@ -626,31 +664,43 @@
  * associated with particular subchannels (e.g., receive queues).
  *
  */
-
-#ifdef SPINLOCKS_WORK
-#define SUBCH_LOCK(sc)			spin_lock_irq( &((sc)->subch_lock) )
-#define SUBCH_UNLOCK(sc)		spin_unlock_irq( &((sc)->subch_lock) )
-#define SUBCH_DATA_LOCK(sbch) 		spin_lock_irq( &((sbch)->data_lock) )
-#define SUBCH_DATA_UNLOCK(sbch)		spin_unlock_irq( &((sbch)->data_lock) )
-#else
-#define SUBCH_LOCK(sc)
-#define SUBCH_UNLOCK(sc)
-#define SUBCH_DATA_LOCK(sbch)
-#define SUBCH_DATA_UNLOCK(sbch)
-#endif
+#define SUBCH_LOCK(sc, p)		spin_lock_irqsave( &((sc)->subch_lock), p )
+#define SUBCH_UNLOCK(sc, p)		spin_unlock_irqrestore( &((sc)->subch_lock), p )
+#define SUBCH_DATA_LOCK(sbch, p) 	spin_lock_irqsave( &((sbch)->data_lock), p )
+#define SUBCH_DATA_UNLOCK(sbch, p)	spin_unlock_irqrestore( &((sbch)->data_lock), p )
 
 
-/* get_myid is an internal function that reads the PI_CPU_NUM
- * register of the local bedrock to determine which of the
- * four possible CPU's "this" one is
+/*
+ * set a function to be called for subchannel ch in the event of
+ * a transmission low-water interrupt from the uart
  */
-static int
-get_myid( void )
+void
+subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
 {
-    return( LD(LOCAL_HUB(PI_CPU_NUM)) );
+    unsigned long pl = 0;
+
+    L1SC_SEND_LOCK( sc, pl );
+#if	!defined(SYNC_CONSOLE_WRITE)
+    if ( func && !sc->send_in_use )
+	uart_enable_xmit_intr( sc );
+#endif
+    sc->subch[ch].tx_notify = func;
+    L1SC_SEND_UNLOCK(sc, pl );
 }
 
+/*
+ * set a function to be called for subchannel ch when data is received
+ */
+void
+subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
+{
+    unsigned long pl = 0;
+    brl1_sch_t *subch = &(sc->subch[ch]);
 
+    SUBCH_DATA_LOCK( subch, pl );
+    sc->subch[ch].rx_notify = func;
+    SUBCH_DATA_UNLOCK( subch, pl );
+}
 
 /*********************************************************************
  * Queue manipulation macros
@@ -767,14 +817,16 @@
  * brl1_discard_packet is a dummy "receive callback" used to get rid
  * of packets we don't want
  */
-void brl1_discard_packet( l1sc_t *sc, int ch )
+void brl1_discard_packet( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
 {
+    unsigned long pl = 0;
     brl1_sch_t *subch = &sc->subch[ch];
+
     sc_cq_t *q = subch->iqp;
-    SUBCH_DATA_LOCK( subch );
+    SUBCH_DATA_LOCK( subch, pl );
     q->opos = q->ipos;
-    atomic_clear( &(subch->packet_arrived), ~((unsigned)0) );
-    SUBCH_DATA_UNLOCK( subch );
+    atomic_set(&(subch->packet_arrived), 0);
+    SUBCH_DATA_UNLOCK( subch, pl );
 }
 
 
@@ -789,17 +841,15 @@
 static int
 brl1_send_chars( l1sc_t *sc )
 {
-    /* In the kernel, we track the depth of the C brick's UART's
+    /* We track the depth of the C brick's UART's
      * fifo in software, and only check if the UART is accepting
      * characters when our count indicates that the fifo should
      * be full.
      *
-     * For remote (router) UARTs, and also for the local (C brick)
-     * UART in the prom, we check with the UART before sending every
+     * For remote (router) UARTs, we check with the UART before sending every
      * character.
      */
-    if( sc->uart == BRL1_LOCALUART ) 
-    {
+    if( sc->uart == BRL1_LOCALHUB_UART ) {
 	if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) )
 	    sc->fifo_space = UART_FIFO_DEPTH;
 	
@@ -809,16 +859,10 @@
 	    sc->sent++;
 	}
     }
+    else {
 
-    else
-
-    /* The following applies to all UARTs in the prom, and to remote
-     * (router) UARTs in the kernel...
-     */
-
-#define TIMEOUT_RETRIES	30
+	/* remote (router) UARTs */
 
-    {
 	int result;
 	int tries = 0;
 
@@ -831,7 +875,7 @@
 	    if( result == UART_TIMEOUT ) {
 		tries++;
 		/* send this character in TIMEOUT_RETRIES... */
-		if( tries < TIMEOUT_RETRIES ) {
+		if( tries < 30 /* TIMEOUT_RETRIES */ ) {
 		    continue;
 		}
 		/* ...or else... */
@@ -864,33 +908,39 @@
 static int
 brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait )
 {
+    unsigned long pl = 0;
     int index;
     int pkt_len = 0;
     unsigned short crc = INIT_CRC;
     char *send_ptr = sc->send;
 
-#ifdef BRINGUP
-    /* We want to be sure that we are sending the entire packet before returning */
-    wait = 1;
-#endif
-    if ( sc->uart == BRL1_LOCALUART )
-	lock_console(sc->nasid);
 
-    if( sc->send_in_use ) {
-	if( !wait ) {
-    	    if ( sc->uart == BRL1_LOCALUART )
-	    	unlock_console(sc->nasid);
-	    return 0; /* couldn't send anything; wait for buffer to drain */
-	}
-	else {
-	    /* buffer's in use, but we're synchronous I/O, so we're going
-	     * to send whatever's in there right now and take the buffer
-	     */
-	    while( sc->sent < sc->send_len )
+    if( sc->send_in_use && !(wait) ) {
+	/* We are in the middle of sending, but can wait until done */
+	return 0;
+    }
+    else if( sc->send_in_use ) {
+	/* buffer's in use, but we're synchronous I/O, so we're going
+	 * to send whatever's in there right now and take the buffer
+	 */
+	int counter = 0;
+
+	if ( sc->uart == BRL1_LOCALHUB_UART )
+		lock_console(sc->nasid);
+	L1SC_SEND_LOCK(sc, pl);
+	while( sc->sent < sc->send_len ) {
 		brl1_send_chars( sc );
+		if ( counter++ > 0xfffff ) {
+			char *str = "Looping waiting for uart to clear (1)\n";
+			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
+			break;
+		}
 	}
     }
     else {
+	if ( sc->uart == BRL1_LOCALHUB_UART )
+		lock_console(sc->nasid);
+	L1SC_SEND_LOCK(sc, pl);
 	sc->send_in_use = 1;
     }
     *send_ptr++ = BRL1_FLAG_CH;
@@ -948,23 +998,100 @@
     sc->send_len = pkt_len;
     sc->sent = 0;
 
-    do {
-	brl1_send_chars( sc );
-    } while( (sc->sent < sc->send_len) && wait );
+    {
+	int counter = 0;
+	do {
+		brl1_send_chars( sc );
+		if ( counter++ > 0xfffff ) {
+			char *str = "Looping waiting for uart to clear (2)\n";
+			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
+			break;
+		}
+	} while( (sc->sent < sc->send_len) && wait );
+    }
+
+    if ( sc->uart == BRL1_LOCALHUB_UART )
+	unlock_console(sc->nasid);
 
     if( sc->sent == sc->send_len ) {
-	/* success! release the send buffer */
+	/* success! release the send buffer and call the callup */
+#if	!defined(SYNC_CONSOLE_WRITE)
+	brl1_notif_t callup;
+#endif
+
 	sc->send_in_use = 0;
+	/* call any upper layer that's asked for notification */
+#if	defined(XX_SYNC_CONSOLE_WRITE)
+	/*
+	 * This is probably not a good idea - since the l1_ write func can be called multiple
+	 * time within the callup function.
+	 */
+	callup = subch->tx_notify;
+	if( callup && (SUBCH(type_and_subch) == SC_CONS_SYSTEM) ) {
+		L1_collectibles[L1C_SEND_CALLUPS]++;
+		(*callup)(sc->subch[SUBCH(type_and_subch)].irq_frame.bf_irq,
+				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_dev_id,
+				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_regs, sc, SUBCH(type_and_subch));
+	}
+#endif	/* SYNC_CONSOLE_WRITE */
     }
-    else if( !wait ) {
+#if	!defined(SYNC_CONSOLE_WRITE)
+    else if ( !wait ) {
 	/* enable low-water interrupts so buffer will be drained */
 	uart_enable_xmit_intr(sc);
     }
-    if ( sc->uart == BRL1_LOCALUART )
-	unlock_console(sc->nasid);
+#endif
+
+    L1SC_SEND_UNLOCK(sc, pl);
+
     return len;
 }
 
+/* brl1_send_cont is intended to be called as an interrupt service
+ * routine.  It sends until the UART won't accept any more characters,
+ * or until an error is encountered (in which case we surrender the
+ * send buffer and give up trying to send the packet).  Once the
+ * last character in the packet has been sent, this routine releases
+ * the send buffer and calls any previously-registered "low-water"
+ * output routines.
+ */
+
+#if	!defined(SYNC_CONSOLE_WRITE)
+
+int
+brl1_send_cont( l1sc_t *sc )
+{
+    unsigned long pl = 0;
+    int done = 0;
+    brl1_notif_t callups[BRL1_NUM_SUBCHANS];
+    brl1_notif_t *callup;
+    brl1_sch_t *subch;
+    int index;
+
+    /*
+     * I'm not sure how I think this is to be handled - whether the lock is held
+     * over the interrupt - but it seems like it is a bad idea....
+     */
+
+    if ( sc->uart == BRL1_LOCALHUB_UART )
+	lock_console(sc->nasid);
+    L1SC_SEND_LOCK(sc, pl);
+    brl1_send_chars( sc );
+    done = (sc->sent == sc->send_len);
+    if( done ) {
+	sc->send_in_use = 0;
+#if	!defined(SYNC_CONSOLE_WRITE)
+	uart_disable_xmit_intr(sc);
+#endif
+    }
+    if ( sc->uart == BRL1_LOCALHUB_UART )
+	unlock_console(sc->nasid);
+    /* Release the lock */
+    L1SC_SEND_UNLOCK(sc, pl);
+
+    return 0;
+}
+#endif	/* SYNC_CONSOLE_WRITE */
 
 /* internal function -- used by brl1_receive to read a character 
  * from the uart and check whether errors occurred in the process.
@@ -1046,40 +1173,33 @@
  * error (parity error, bad header, bad CRC, etc.).
  */
 
-#define STATE_SET(l,s)	((l)->brl1_state = (s))
-#define STATE_GET(l)	((l)->brl1_state)
+#define STATE_SET(l,s)		((l)->brl1_state = (s))
+#define STATE_GET(l)		((l)->brl1_state)
 
 #define LAST_HDR_SET(l,h)	((l)->brl1_last_hdr = (h))
 #define LAST_HDR_GET(l)		((l)->brl1_last_hdr)
 
-#define SEQSTAMP_INCR(l)
-#define SEQSTAMP_GET(l)
-
 #define VALID_HDR(c)				\
     ( SUBCH((c)) <= SC_CONS_SYSTEM		\
 	? PKT_TYPE((c)) == BRL1_REQUEST		\
 	: ( PKT_TYPE((c)) == BRL1_RESPONSE ||	\
 	    PKT_TYPE((c)) == BRL1_EVENT ) )
 
-#define IS_TTY_PKT(l) \
-         ( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 )
+#define IS_TTY_PKT(l)		( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 )
 
 
 int
-brl1_receive( l1sc_t *sc )
+brl1_receive( l1sc_t *sc, int mode )
 {
     int result;		/* value to be returned by brl1_receive */
     int c;		/* most-recently-read character	     	*/
     int done;		/* set done to break out of recv loop	*/
+    unsigned long pl = 0, cpl = 0;
     sc_cq_t *q;		/* pointer to queue we're working with	*/
 
     result = BRL1_NO_MESSAGE;
 
-#ifdef FORCE_CONSOLE_NASID
-    sc->nasid = 0;
-#endif
-    if ( sc->uart == BRL1_LOCALUART )
-	lock_console(sc->nasid);
+    L1SC_RECV_LOCK(sc, cpl);
 
     done = 0;
     while( !done )
@@ -1210,8 +1330,7 @@
 		 * starting a new packet
 		 */
 		STATE_SET( sc, BRL1_FLAG );
-		SEQSTAMP_INCR(sc); /* bump the packet sequence counter */
-		
+
 		/* if the packet body has less than 2 characters,
 		 * it can't be a well-formed packet.  Discard it.
 		 */
@@ -1258,7 +1377,7 @@
 
 		/* get the subchannel and lock it */
 		subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]);
-		SUBCH_DATA_LOCK( subch );
+		SUBCH_DATA_LOCK( subch, pl );
 		
 		/* if this isn't a console packet, we need to record
 		 * a length byte
@@ -1276,14 +1395,16 @@
 		 */
 		atomic_inc(&(subch->packet_arrived));
 		callup = subch->rx_notify;
-		SUBCH_DATA_UNLOCK( subch );
+		SUBCH_DATA_UNLOCK( subch, pl );
 
-		if( callup ) {
-		    if ( sc->uart == BRL1_LOCALUART )
-			unlock_console(sc->nasid);
-		    (*callup)( sc, SUBCH(LAST_HDR_GET(sc)) );
-		    if ( sc->uart == BRL1_LOCALUART )
-			lock_console(sc->nasid);
+		if( callup && (mode == SERIAL_INTERRUPT_MODE) ) {
+		    L1SC_RECV_UNLOCK( sc, cpl );
+		    L1_collectibles[L1C_RECEIVE_CALLUPS]++;
+		    (*callup)( sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_irq,
+				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_dev_id,
+				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_regs,
+				sc, SUBCH(LAST_HDR_GET(sc)) );
+		    L1SC_RECV_LOCK( sc, cpl );
 		}
 		continue;	/* go back for more! */
 	    }
@@ -1351,9 +1472,8 @@
 
 	} /* end of switch( STATE_GET(sc) ) */
     } /* end of while(!done) */
-    
-    if ( sc->uart == BRL1_LOCALUART )
-	unlock_console(sc->nasid);
+
+    L1SC_RECV_UNLOCK( sc, cpl );
 
     return result;
 }	    
@@ -1370,13 +1490,10 @@
     brl1_sch_t *subch;
 
     bzero( sc, sizeof( *sc ) );
-#ifdef FORCE_CONSOLE_NASID
-    nasid = (nasid_t)0;
-#endif
     sc->nasid = nasid;
     sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALUART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALUART ? uart_putc : rtr_uart_putc);
+    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
+    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
     sc->sol = 1;
     subch = sc->subch;
 
@@ -1403,9 +1520,8 @@
     spin_lock_init( &(subch->data_lock) );
     sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
     subch->tx_notify = NULL;
-    if( sc->uart == BRL1_LOCALUART ) {
-	subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				       NASID_TO_COMPACT_NODEID(nasid) );
+    if( sc->uart == BRL1_LOCALHUB_UART ) {
+	subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) );
 	ASSERT( subch->iqp );
 	cq_init( subch->iqp );
 	subch->rx_notify = NULL;
@@ -1440,8 +1556,10 @@
     /* initialize synchronization structures
      */
     spin_lock_init( &(sc->subch_lock) );
+    spin_lock_init( &(sc->send_lock) );
+    spin_lock_init( &(sc->recv_lock) );
 
-    if( sc->uart == BRL1_LOCALUART ) {
+    if( sc->uart == BRL1_LOCALHUB_UART ) {
 	uart_init( sc, UART_BAUD_RATE );
     }
     else {
@@ -1461,93 +1579,574 @@
     }
 }
 
+/*********************************************************************
+ * These are interrupt-related functions used in the kernel to service
+ * the L1.
+ */
+
+/*
+ * brl1_intrd is the function which is called on a console interrupt.
+ */
 
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
+#if defined(CONFIG_IA64_SGI_SN1)
+
+static void
+brl1_intrd(int irq, void *dev_id, struct pt_regs *stuff)
+{
+    u_char isr_reg;
+    l1sc_t *sc = get_elsc();
+    int ret;
+
+    L1_collectibles[L1C_INTERRUPTS]++;
+    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
+
+    /* Save for callup args in console */
+    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq;
+    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id;
+    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff;
+
+#if	defined(SYNC_CONSOLE_WRITE)
+    while( isr_reg & ISR_RxRDY )
+#else
+    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) )
+#endif
+    {
+	if( isr_reg & ISR_RxRDY ) {
+	    L1_collectibles[L1C_OUR_R_INTERRUPTS]++;
+	    ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE);
+	    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
+		L1_collectibles[L1C_REC_STALLS] = ret;
+	}
+#if	!defined(SYNC_CONSOLE_WRITE)
+	if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) {
+	    L1_collectibles[L1C_OUR_X_INTERRUPTS]++;
+	    brl1_send_cont(sc);
+	}
+#endif	/* SYNC_CONSOLE_WRITE */
+	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
+    }
+}
+#endif	/* CONFIG_IA64_SGI_SN1 */
+
+
+/*
+ * Install a callback function for the system console subchannel 
+ * to allow an upper layer to be notified when the send buffer 
+ * has been emptied.
+ */
+static inline void
+l1_tx_notif( brl1_notif_t func )
+{
+	subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
+			SC_CONS_SYSTEM, func );
+}
+
+
+/*
+ * Install a callback function for the system console subchannel
+ * to allow an upper layer to be notified when a packet has been
+ * received.
+ */
+static inline void
+l1_rx_notif( brl1_notif_t func )
+{
+	subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
+				SC_CONS_SYSTEM, func );
+}
+
+
+/* brl1_intr is called directly from the uart interrupt; after it runs, the
+ * interrupt "daemon" xthread is signalled to continue.
  */
 void
-l1_control_out(int offset, int value)
+brl1_intr( void )
 {
-	nasid_t nasid = 0; //(get_elsc())->nasid;
-	WRITE_L1_UART_REG(nasid, offset, value); 
 }
 
+#define BRL1_INTERRUPT_LEVEL	65	/* linux request_irq() value */
+
+/* Return the current interrupt level */
+
+//#define CONSOLE_POLLING_ALSO
+
 int
-l1_control_in(int offset)
+l1_get_intr_value( void )
 {
-	nasid_t nasid = 0; //(get_elsc())->nasid;
-	return(READ_L1_UART_REG(nasid, offset)); 
+#if defined(USE_SAL_CONSOLE_IO)
+	return(0);
+#else
+#if defined(CONSOLE_POLLING_ALSO)
+	return(0);
+#else
+	return(BRL1_INTERRUPT_LEVEL);
+#endif /* CONSOLE_POLLING_ALSO */
+#endif /* USE_SAL_CONSOLE_IO */
 }
 
-#define PUTCHAR(ch) \
-    { \
-        while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \
-                (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \
-        WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \
-    }
+/* Disconnect the callup functions - throw away interrupts */
 
-int
-l1_serial_out( char *str, int len )
+void
+l1_unconnect_intr(void)
 {
-    int sent = len;
-    char crc_char;
-    unsigned short crc = INIT_CRC;
-    nasid_t nasid = 0; //(get_elsc())->nasid;
+#if !defined(USE_SAL_CONSOLE_IO)
+	/* UnRegister the upper-level callup functions */
+	l1_rx_notif((brl1_notif_t)NULL);
+	l1_tx_notif((brl1_notif_t)NULL);
+	/* We do NOT unregister the interrupts */
+#endif /* !USE_SAL_CONSOLE_IO */
+}
 
-    lock_console(nasid);
+/* Set up uart interrupt handling for this node's uart */
 
-    PUTCHAR( BRL1_FLAG_CH );
-    PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
-    crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) );
+void
+l1_connect_intr(void *rx_notify, void *tx_notify)
+{
+#if defined(USE_SAL_CONSOLE_IO)
+#if 0
+	// Will need code here for sn2 - something like this
+	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());
+	intr_connect_level(console_nodepda->node_first_cpu,
+                                SGI_UART_VECTOR, INTPEND0_MAXMASK,
+                                dummy_intr_func);
+	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),
+                                intr_func, SA_INTERRUPT | SA_SHIRQ,
+                                "l1_protocol_driver", (void *)sc);
+#endif
+#else
+	l1sc_t *sc;
+	nasid_t nasid;
+#if defined(CONFIG_IA64_SGI_SN1)
+	int tmp;
+#endif
+	nodepda_t *console_nodepda;
+	int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);
 
-    while( len ) {
+	if ( L1_interrupts_connected ) {
+		/* Interrupts are connected, so just register the callups */
+		l1_rx_notif((brl1_notif_t)rx_notify);
+		l1_tx_notif((brl1_notif_t)tx_notify);
 
-	if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) {
-	    PUTCHAR( BRL1_ESC_CH );
-	    PUTCHAR( (*str) ^ BRL1_XOR_CH );
+		L1_collectibles[L1C_CONNECT_CALLS]++;
+		return;
+	}
+	else
+		L1_interrupts_connected = 1;
+
+	nasid = get_master_nasid();
+	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid));
+	sc = &console_nodepda->module->elsc;
+	sc->intr_cpu = console_nodepda->node_first_cpu;
+
+#if defined(CONFIG_IA64_SGI_SN1)
+	if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) {
+		L1_interrupts_connected = 0; /* FAILS !! */
 	}
 	else {
-	    PUTCHAR( *str );
+		void synergy_intr_connect(int, int);
+
+		synergy_intr_connect(UART_INTR, sc->intr_cpu);
+		L1_collectibles[L1C_R_IRQ]++;
+		tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc);
+		L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp;
+		if ( tmp ) {
+			L1_interrupts_connected = 0; /* FAILS !! */
+		}
+		else {
+			/* Register the upper-level callup functions */
+			l1_rx_notif((brl1_notif_t)rx_notify);
+			l1_tx_notif((brl1_notif_t)tx_notify);
+
+			/* Set the uarts the way we like it */
+			uart_enable_recv_intr( sc );
+			uart_disable_xmit_intr( sc );
+		}
 	}
-	
-	crc = crc16_calc( crc, *str );
+#endif	/* CONFIG_IA64_SGI_SN1 */
+#endif	/* USE_SAL_CONSOLE_IO */
+}
 
-	str++; len--;
-    }
-    
-    crc ^= 0xffff;
-    crc_char = crc & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    crc_char = (crc >> 8) & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    PUTCHAR( BRL1_FLAG_CH );
 
-    unlock_console(nasid);
-    return sent - len;
+/* These are functions to use from serial_in/out when in protocol
+ * mode to send and receive uart control regs. These are external
+ * interfaces into the protocol driver.
+ */
+
+void
+l1_control_out(int offset, int value)
+{
+#if defined(USE_SAL_CONSOLE_IO)
+	/* quietly ignore unless simulator */
+	if ( IS_RUNNING_ON_SIMULATOR() ) {
+		extern u64 master_node_bedrock_address;
+		if ( master_node_bedrock_address != (u64)0 ) {
+			writeb(value, (unsigned long)master_node_bedrock_address +
+				(offset<< 3));
+		}
+		return;
+	}
+#else
+	nasid_t nasid = get_master_nasid();
+	WRITE_L1_UART_REG(nasid, offset, value); 
+#endif
 }
 
+/* Console input exported interface. Return a register value.  */
+
 int
-l1_serial_in(void)
+l1_control_in_polled(int offset)
 {
-	static int l1_cons_getc( l1sc_t *sc );
+	static int l1_control_in_local(int, int);
 
-	return(l1_cons_getc(get_elsc()));
+	return(l1_control_in_local(offset, SERIAL_POLLED_MODE));
 }
 
+int
+l1_control_in(int offset)
+{
+	static int l1_control_in_local(int, int);
 
-/*********************************************************************
- * l1_cons functions
- *
- * These allow the L1 to act as the system console.  They're intended
+	return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE));
+}
+
+static int
+l1_control_in_local(int offset, int mode)
+{
+#if defined(USE_SAL_CONSOLE_IO)
+	int sal_call_status = 0, input;
+	int ret = 0;
+
+	if ( offset == REG_LSR ) {
+		ret = (LSR_XHRE | LSR_XSRE);	/* can send anytime */
+		sal_call_status = ia64_sn_console_check(&input);
+		if ( !sal_call_status && input ) {
+			/* input pending */
+			ret |= LSR_RCA;
+		}
+	}
+
+	/* If the sal call failed, do it the old-fashioned way */
+	if ( sal_call_status ) {
+		if ( IS_RUNNING_ON_SIMULATOR() ) {
+			extern u64 master_node_bedrock_address;
+			ret = readb((unsigned long)master_node_bedrock_address +
+					(offset<< 3));
+		}		
+		else {
+#endif	/* USE_SAL_CONSOLE_IO */
+			nasid_t nasid;
+			int ret, input;
+			static int l1_poll(l1sc_t *, int);
+
+			nasid = get_master_nasid();
+			ret = READ_L1_UART_REG(nasid, offset); 
+
+			if ( offset == REG_LSR ) {
+				ret |= (LSR_XHRE | LSR_XSRE);	/* can send anytime */
+				if ( L1_cons_is_inited ) {
+					if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
+						input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode);
+						if ( input ) {
+							ret |= LSR_RCA;
+						}
+					}
+				}
+			}
+#if defined(USE_SAL_CONSOLE_IO)
+		}
+	}
+#endif
+	return(ret);
+}
+
+/*
+ * Console input exported interface. Return a character (if one is available)
+ */
+
+int
+l1_serial_in_polled(void)
+{
+	static int l1_serial_in_local(int mode);
+
+	return(l1_serial_in_local(SERIAL_POLLED_MODE));
+}
+
+int
+l1_serial_in(void)
+{
+	static int l1_serial_in_local(int mode);
+
+	return(l1_serial_in_local(SERIAL_INTERRUPT_MODE));
+}
+
+static int
+l1_serial_in_local(int mode)
+{
+#if defined(USE_SAL_CONSOLE_IO)
+	int sal_call_status;
+	int ch;
+
+	sal_call_status = ia64_sn_console_getc(&ch);
+	if ( !sal_call_status ) {
+		return(ch);
+	}
+	else {
+		/* If the sal called failed - do it the old-fashioned way */
+		if ( IS_RUNNING_ON_SIMULATOR() ) {
+			extern u64 master_node_bedrock_address;
+			return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
+		}		
+		else {
+#endif	/* USE_SAL_CONSOLE_IO */
+			nasid_t nasid;
+			l1sc_t *sc;
+			int value;
+			static int l1_getc( l1sc_t *, int );
+			static inline l1sc_t *early_sc_init(nasid_t);
+
+			nasid = get_master_nasid();
+			sc = early_sc_init(nasid);
+			if ( L1_cons_is_inited ) {
+				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
+					sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc;
+				}
+			}
+			value = l1_getc(sc, mode);
+			return(value);
+#if defined(USE_SAL_CONSOLE_IO)
+		}
+	}
+#endif
+}
+
+/* Console output exported interface. Write message to the console.  */
+
+int
+l1_serial_out( char *str, int len )
+{
+#if defined(USE_SAL_CONSOLE_IO)
+	int sal_call_status = 0;
+	int counter = len;
+
+	/* Attempt to write things out thru the sal */
+	while ( counter > 0 ) {
+		if ( (sal_call_status = ia64_sn_console_putc(*str)) ) {
+			break;
+		}
+		counter--;
+		str++;
+	}
+	if ( sal_call_status ) {
+		/* If the sal called failed - do it the old-fashioned way */
+		if ( IS_RUNNING_ON_SIMULATOR() ) {
+			extern u64 master_node_bedrock_address;
+                        if (!master_node_bedrock_address)
+                                early_sn_setup();
+			if ( master_node_bedrock_address != (u64)0 ) {
+#ifdef FLAG_DIRECT_CONSOLE_WRITES
+				/* This is an easy way to pre-pend the output to know whether the output
+				 * was done via sal or directly */
+				writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
+				writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
+				writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
+				writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
+#endif	/* FLAG_DIRECT_CONSOLE_WRITES */
+				while ( counter > 0 ) {
+					writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
+					counter--;
+					str++;
+				}
+			}
+		}
+		else {
+#endif	/* USE_SAL_CONSOLE_IO */
+			nasid_t nasid = get_master_nasid();
+			int l1_write(l1sc_t *, char *, int, int);
+
+			if ( L1_cons_is_inited ) {
+				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 )
+					return(l1_write(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, str, len,
+#if	defined(SYNC_CONSOLE_WRITE)
+							1
+#else
+							!L1_interrupts_connected
+#endif
+									));
+			}
+			return(early_l1_serial_out(nasid, str, len, NOT_LOCKED));
+#if defined(USE_SAL_CONSOLE_IO)
+		}
+	}
+	return((counter <= 0) ? 0 : (len - counter));
+#endif
+}
+
+
+/*
+ * These are the 'early' functions - when we need to do things before we have
+ * all the structs setup.
+ */
+
+
+static l1sc_t Early_console;		/* fake l1sc_t */
+static int Early_console_inited = 0;
+
+static void
+early_brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
+{
+    int i;
+    brl1_sch_t *subch;
+
+    bzero( sc, sizeof( *sc ) );
+    sc->nasid = nasid;
+    sc->uart = uart;
+    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
+    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
+    sc->sol = 1;
+    subch = sc->subch;
+
+    /* initialize L1 subchannels
+     */
+
+    /* assign processor TTY channels */
+    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
+	subch->use = BRL1_SUBCH_RSVD;
+	subch->packet_arrived = ATOMIC_INIT(0);
+	subch->tx_notify = NULL;
+	subch->rx_notify = NULL;
+	subch->iqp = &sc->garbage_q;
+    }
+
+    /* assign system TTY channel (first free subchannel after each
+     * processor's individual TTY channel has been assigned)
+     */
+    subch->use = BRL1_SUBCH_RSVD;
+    subch->packet_arrived = ATOMIC_INIT(0);
+    subch->tx_notify = NULL;
+    subch->rx_notify = NULL;
+    if( sc->uart == BRL1_LOCALHUB_UART ) {
+	static sc_cq_t x_iqp;
+
+	subch->iqp = &x_iqp;
+	ASSERT( subch->iqp );
+	cq_init( subch->iqp );
+    }
+    else {
+	/* we shouldn't be getting console input from remote UARTs */
+	subch->iqp = &sc->garbage_q;
+    }
+    subch++; i++;
+
+    /* "reserved" subchannels (0x05-0x0F); for now, throw away
+     * incoming packets
+     */
+    for( ; i < 0x10; i++, subch++ ) {
+	subch->use = BRL1_SUBCH_FREE;
+	subch->packet_arrived = ATOMIC_INIT(0);
+	subch->tx_notify = NULL;
+	subch->rx_notify = NULL;
+	subch->iqp = &sc->garbage_q;
+    }
+
+    /* remaining subchannels are free */
+    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
+	subch->use = BRL1_SUBCH_FREE;
+	subch->packet_arrived = ATOMIC_INIT(0);
+	subch->tx_notify = NULL;
+	subch->rx_notify = NULL;
+	subch->iqp = &sc->garbage_q;
+    }
+}
+
+static inline l1sc_t *
+early_sc_init(nasid_t nasid)
+{
+	/* This is for early I/O */
+	if ( Early_console_inited == 0 ) {
+    		early_brl1_init(&Early_console, nasid,  BRL1_LOCALHUB_UART);
+		Early_console_inited = 1;
+	}
+	return(&Early_console);
+}
+
+#define PUTCHAR(ch) \
+    { \
+        while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \
+                (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \
+        WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \
+    }
+
+static int
+early_l1_serial_out( nasid_t nasid, char *str, int len, int lock_state )
+{
+	int ret, sent = 0;
+	char *msg = str;
+	static int early_l1_send( nasid_t nasid, char *str, int len, int lock_state );
+
+	while ( sent < len ) {
+		ret = early_l1_send(nasid, msg, len - sent, lock_state);
+		sent += ret;
+		msg += ret;
+	}
+	return(len);
+}
+
+static inline int
+early_l1_send( nasid_t nasid, char *str, int len, int lock_state )
+{
+    int sent;
+    char crc_char;
+    unsigned short crc = INIT_CRC;
+
+    if( len > (BRL1_QSIZE - 1) )
+	len = (BRL1_QSIZE - 1);
+
+    sent = len;
+    if ( lock_state == NOT_LOCKED )
+    	lock_console(nasid);
+
+    PUTCHAR( BRL1_FLAG_CH );
+    PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
+    crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) );
+
+    while( len ) {
+
+	if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) {
+	    PUTCHAR( BRL1_ESC_CH );
+	    PUTCHAR( (*str) ^ BRL1_XOR_CH );
+	}
+	else {
+	    PUTCHAR( *str );
+	}
+	
+	crc = crc16_calc( crc, *str );
+
+	str++; len--;
+    }
+    
+    crc ^= 0xffff;
+    crc_char = crc & 0xff;
+    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
+	crc_char ^= BRL1_XOR_CH;
+	PUTCHAR( BRL1_ESC_CH );
+    }
+    PUTCHAR( crc_char );
+    crc_char = (crc >> 8) & 0xff;
+    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
+	crc_char ^= BRL1_XOR_CH;
+	PUTCHAR( BRL1_ESC_CH );
+    }
+    PUTCHAR( crc_char );
+    PUTCHAR( BRL1_FLAG_CH );
+
+    if ( lock_state == NOT_LOCKED )
+    	unlock_console(nasid);
+    return sent;
+}
+
+/*********************************************************************
+ * l1_cons functions
+ *
+ * These allow the L1 to act as the system console.  They're intended
  * to abstract away most of the br/l1 internal details from the
  * _L1_cons_* functions (in the prom-- see "l1_console.c") and
  * l1_* functions (in the kernel-- see "sio_l1.c") that they support.
@@ -1555,12 +2154,16 @@
  */
 
 static int
-l1_cons_poll( l1sc_t *sc )
+l1_poll( l1sc_t *sc, int mode )
 {
+    int ret;
+
     /* in case this gets called before the l1sc_t structure for the module_t
      * struct for this node is initialized (i.e., if we're called with a
      * zero l1sc_t pointer)...
      */
+
+
     if( !sc ) {
 	return 0;
     }
@@ -1569,7 +2172,9 @@
 	return 1;
     }
 
-    brl1_receive( sc );
+    ret = brl1_receive( sc, mode );
+    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
+	L1_collectibles[L1C_REC_STALLS] = ret;
 
     if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
 	return 1;
@@ -1581,43 +2186,65 @@
 /* pull a character off of the system console queue (if one is available)
  */
 static int
-l1_cons_getc( l1sc_t *sc )
+l1_getc( l1sc_t *sc, int mode )
 {
+    unsigned long pl = 0;
     int c;
 
     brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
     sc_cq_t *q = subch->iqp;
 
-    if( !l1_cons_poll( sc ) ) {
+    if( !l1_poll( sc, mode ) ) {
 	return 0;
     }
 
-    SUBCH_DATA_LOCK( subch );
+    SUBCH_DATA_LOCK( subch, pl );
     if( cq_empty( q ) ) {
 	atomic_set(&subch->packet_arrived, 0);
-	SUBCH_DATA_UNLOCK( subch );
+	SUBCH_DATA_UNLOCK( subch, pl );
 	return 0;
     }
     cq_rem( q, c );
     if( cq_empty( q ) )
 	atomic_set(&subch->packet_arrived, 0);
-    SUBCH_DATA_UNLOCK( subch );
+    SUBCH_DATA_UNLOCK( subch, pl );
 
     return c;
 }
 
+/*
+ * Write a message to the L1 on the system console subchannel.
+ *
+ * Danger: don't use a non-zero value for the wait parameter unless you're
+ * someone important (like a kernel error message).
+ */
+
+int
+l1_write( l1sc_t *sc, char *msg, int len, int wait )
+{
+	int sent = 0, ret = 0;
+
+	if ( wait ) {
+		while ( sent < len ) {
+			ret = brl1_send( sc, msg, len - sent, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
+			sent += ret;
+			msg += ret;
+		}
+		ret = len;
+	}
+	else {
+		ret = brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
+	}
+	return(ret);
+}
 
 /* initialize the system console subchannel
  */
 void
-l1_cons_init( l1sc_t *sc )
+l1_init(void)
 {
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-
-    SUBCH_DATA_LOCK( subch );
-    atomic_set(&subch->packet_arrived, 0);
-    cq_init( subch->iqp );
-    SUBCH_DATA_UNLOCK( subch );
+	/* All we do now is remember that we have been called */
+	L1_cons_is_inited = 1;
 }
 
 
@@ -1637,16 +2264,18 @@
 #define L1_DBG_PRF(x)
 #endif
 
-/* sc_data_ready is called to signal threads that are blocked on 
- * l1 input.
+/*
+ * sc_data_ready is called to signal threads that are blocked on l1 input.
  */
 void
-sc_data_ready( l1sc_t *sc, int ch )
+sc_data_ready( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
 {
+    unsigned long pl = 0;
+
     brl1_sch_t *subch = &(sc->subch[ch]);
-    SUBCH_DATA_LOCK( subch );
+    SUBCH_DATA_LOCK( subch, pl );
     sv_signal( &(subch->arrive_sv) );
-    SUBCH_DATA_UNLOCK( subch );
+    SUBCH_DATA_UNLOCK( subch, pl );
 }
 
 /* sc_open reserves a subchannel to send a request to the L1 (the
@@ -1661,9 +2290,10 @@
      * subchannel assignment.
      */
     int ch;
+    unsigned long pl = 0;
     brl1_sch_t *subch;
 
-    SUBCH_LOCK( sc );
+    SUBCH_LOCK( sc, pl );
 
     /* Look for a free subchannel. Subchannels 0-15 are reserved
      * for other purposes.
@@ -1676,12 +2306,12 @@
 
     if( ch == BRL1_NUM_SUBCHANS ) {
         /* there were no subchannels available! */
-        SUBCH_UNLOCK( sc );
+        SUBCH_UNLOCK( sc, pl );
         return SC_NSUBCH;
     }
 
     subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc );
+    SUBCH_UNLOCK( sc, pl );
 
     atomic_set(&subch->packet_arrived, 0);
     subch->target = target;
@@ -1689,7 +2319,7 @@
     sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
     subch->tx_notify = NULL;
     subch->rx_notify = sc_data_ready;
-    subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
+    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
 				   NASID_TO_COMPACT_NODEID(sc->nasid) );
     ASSERT( subch->iqp );
     cq_init( subch->iqp );
@@ -1703,29 +2333,31 @@
 int
 sc_close( l1sc_t *sc, int ch )
 {
+    unsigned long pl = 0;
     brl1_sch_t *subch;
 
-    SUBCH_LOCK( sc );
+    SUBCH_LOCK( sc, pl );
     subch = &(sc->subch[ch]);
     if( subch->use != BRL1_SUBCH_RSVD ) {
         /* we're trying to close a subchannel that's not open */
+	SUBCH_UNLOCK( sc, pl );
         return SC_NOPEN;
     }
 
     atomic_set(&subch->packet_arrived, 0);
     subch->use = BRL1_SUBCH_FREE;
 
-    SUBCH_DATA_LOCK( subch );
     sv_broadcast( &(subch->arrive_sv) );
     sv_destroy( &(subch->arrive_sv) );
-    SUBCH_DATA_UNLOCK( subch );
     spin_lock_destroy( &(subch->data_lock) );
 
     ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) );
-    kmem_free( subch->iqp, sizeof(sc_cq_t) );
+    snia_kmem_free( subch->iqp, sizeof(sc_cq_t) );
     subch->iqp = &sc->garbage_q;
+    subch->tx_notify = NULL;
+    subch->rx_notify = brl1_discard_packet;
 
-    SUBCH_UNLOCK( sc );
+    SUBCH_UNLOCK( sc, pl );
 
     return SC_SUCCESS;
 }
@@ -2003,9 +2635,6 @@
     return 0;
 }
 
-
-
-
 /* sc_send takes as arguments a system controller struct, a
  * buffer which contains a Bedrock<->L1 "request" message,
  * the message length, and the subchannel (presumably obtained
@@ -2033,11 +2662,10 @@
 
     /* Verify that this is an open subchannel
      */
-    if( sc->subch[ch].use == BRL1_SUBCH_FREE )
-    {
+    if( sc->subch[ch].use == BRL1_SUBCH_FREE ) {
         return SC_NOPEN;
     }
-       
+
     type_and_subch = (BRL1_REQUEST | ((u_char)ch));
     result = brl1_send( sc, msg, len, type_and_subch, wait );
 
@@ -2058,8 +2686,6 @@
 	return( result );
 }
 
-
-
 /* subch_pull_msg pulls a message off the receive queue for subch
  * and places it the buffer pointed to by msg.  This routine should only
  * be called when the caller already knows a message is available on the
@@ -2115,6 +2741,7 @@
 sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
 {
     int is_msg = 0;
+    unsigned long pl = 0;
     brl1_sch_t *subch = &(sc->subch[ch]);
 
     rtc_time_t exp_time = rtc_time() + block;
@@ -2127,7 +2754,7 @@
 
         /* kick the next lower layer and see if it pulls anything in
          */
-	brl1_receive( sc );
+	brl1_receive( sc, SERIAL_POLLED_MODE );
 	is_msg = atomic_read(&subch->packet_arrived);
 
     } while( block && !is_msg && (rtc_time() < exp_time) );
@@ -2137,9 +2764,9 @@
 	return( SC_NMSG );
     }
 
-    SUBCH_DATA_LOCK( subch );
+    SUBCH_DATA_LOCK( subch, pl );
     subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch );
+    SUBCH_DATA_UNLOCK( subch, pl );
 
     return( SC_SUCCESS );
 }
@@ -2156,10 +2783,11 @@
 sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
 {
     int is_msg = 0;
+    unsigned long pl = 0;
     brl1_sch_t *subch = &(sc->subch[ch]);
 
     do {
-	SUBCH_DATA_LOCK(subch);
+	SUBCH_DATA_LOCK(subch, pl);
 	is_msg = atomic_read(&subch->packet_arrived);
 	if( !is_msg && block ) {
 	    /* wake me when you've got something */
@@ -2178,12 +2806,12 @@
 
     if( !is_msg ) {
 	/* no message and we didn't care to wait for one */
-	SUBCH_DATA_UNLOCK( subch );
+	SUBCH_DATA_UNLOCK( subch, pl );
 	return( SC_NMSG );
     }
 
     subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch );
+    SUBCH_DATA_UNLOCK( subch, pl );
 
     return( SC_SUCCESS );
 }
@@ -2206,16 +2834,13 @@
  * rewriting of the L1 command interface anyway.)
  */
 #define __RETRIES	50
-#define __WAIT_SEND	( sc->uart != BRL1_LOCALUART )
+#define __WAIT_SEND	1	// ( sc->uart != BRL1_LOCALHUB_UART )
 #define __WAIT_RECV	10000000
 
 
 int
 sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
 {
-#ifndef CONFIG_SERIAL_SGI_L1_PROTOCOL
-    return SC_NMSG;
-#else
     int result;
     int retries;
 
@@ -2237,16 +2862,12 @@
     }
     
     /* block on sc_recv_* */
-#ifdef LATER
-    if( sc->uart == BRL1_LOCALUART ) {
+    if( (sc->uart == BRL1_LOCALHUB_UART) && L1_interrupts_connected ) {
 	return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) );
     }
-    else
-#endif	/* LATER */
-    {
+    else {
 	return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
     }
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
 
 /* sc_command_kern is a knuckle-dragging, no-patience version of sc_command
@@ -2254,12 +2875,10 @@
  * delayed until the send buffer clears.  sc_command should be used instead
  * under most circumstances.
  */
+
 int
 sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
 {
-#ifndef CONFIG_SERIAL_SGI_L1_PROTOCOL
-    return SC_NMSG;
-#else
     int result;
 
     if ( IS_RUNNING_ON_SIMULATOR() )
@@ -2270,7 +2889,6 @@
     }
 
     return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
 }
 
 
@@ -2282,6 +2900,7 @@
  * Returns 1 if input is available on the given queue,
  * 0 otherwise.
  */
+
 int
 sc_poll( l1sc_t *sc, int ch )
 {
@@ -2290,7 +2909,7 @@
     if( atomic_read(&subch->packet_arrived) )
 	return 1;
 
-    brl1_receive( sc );
+    brl1_receive( sc, SERIAL_POLLED_MODE );
 
     if( atomic_read(&subch->packet_arrived) )
 	return 1;
@@ -2298,8 +2917,8 @@
     return 0;
 }
 
-/* for now, sc_init just calls brl1_init
- */
+/* for now, sc_init just calls brl1_init */
+
 void
 sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
 {
@@ -2311,7 +2930,7 @@
  * network's environmental monitor tasks.
  */
 
-#ifdef LINUX_KERNEL_THREADS
+#if	defined(LINUX_KERNEL_THREADS)
 
 static void
 sc_dispatch_env_event( uint code, int argc, char *args, int maxlen )
@@ -2366,14 +2985,12 @@
 	     i++ );
     }
 }
-#endif	/* LINUX_KERNEL_THREADS */
 
 
 /* sc_event waits for events to arrive from the system controller, and
  * prints appropriate messages to the syslog.
  */
 
-#ifdef LINUX_KERNEL_THREADS
 static void
 sc_event( l1sc_t *sc, int ch )
 {
@@ -2394,7 +3011,7 @@
 	 */
 	result = sc_recv_intr( sc, ch, event, &event_len, 1 );
 	if( result != SC_SUCCESS ) {
-	    PRINT_WARNING("Error receiving sysctl event on nasid %d\n",
+	    printk(KERN_WARNING  "Error receiving sysctl event on nasid %d\n",
 		     sc->nasid );
 	}
 	else {
@@ -2438,53 +3055,50 @@
 	
     }			
 }
-#endif	/* LINUX_KERNEL_THREADS */
 
 /* sc_listen sets up a service thread to listen for incoming events.
  */
+
 void
 sc_listen( l1sc_t *sc )
 {
     int result;
+    unsigned long pl = 0;
     brl1_sch_t *subch;
 
     char        msg[BRL1_QSIZE];
     int         len;    /* length of message being sent */
     int         ch;     /* system controller subchannel used */
 
-#ifdef LINUX_KERNEL_THREADS
     extern int msc_shutdown_pri;
-#endif
 
     /* grab the designated "event subchannel" */
-    SUBCH_LOCK( sc );
+    SUBCH_LOCK( sc, pl );
     subch = &(sc->subch[BRL1_EVENT_SUBCH]);
     if( subch->use != BRL1_SUBCH_FREE ) {
-	SUBCH_UNLOCK( sc );
-	PRINT_WARNING("sysctl event subchannel in use! "
+	SUBCH_UNLOCK( sc, pl );
+	printk(KERN_WARNING  "sysctl event subchannel in use! "
 		 "Not monitoring sysctl events.\n" );
 	return;
     }
     subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc );
+    SUBCH_UNLOCK( sc, pl );
 
     atomic_set(&subch->packet_arrived, 0);
-    subch->target = BRL1_LOCALUART;
+    subch->target = BRL1_LOCALHUB_UART;
     spin_lock_init( &(subch->data_lock) );
     sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
     subch->tx_notify = NULL;
     subch->rx_notify = sc_data_ready;
-    subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
+    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
 				   NASID_TO_COMPACT_NODEID(sc->nasid) );
     ASSERT( subch->iqp );
     cq_init( subch->iqp );
 
-#ifdef LINUX_KERNEL_THREADS
     /* set up a thread to listen for events */
     sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri,
 		    KT_PS, (st_func_t *) sc_event,
 		    (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 );
-#endif
 
     /* signal the L1 to begin sending events */
     bzero( msg, BRL1_QSIZE );
@@ -2522,276 +3136,8 @@
 	
 err_return:
     /* there was a problem; complain */
-    PRINT_WARNING("failed to set sysctl event-monitoring subchannel.  "
+    printk(KERN_WARNING  "failed to set sysctl event-monitoring subchannel.  "
 	     "Sysctl events will not be monitored.\n" );
 }
 
-
-/*********************************************************************
- * elscuart functions.  These provide a uart-like interface to the
- * bedrock/l1 protocol console channels.  They are similar in form
- * and intent to the elscuart_* functions defined for SN0 in elsc.c.
- *
- */
-
-int _elscuart_flush( l1sc_t *sc );
-
-/* Leave room in queue for CR/LF */
-#define ELSCUART_LINE_MAX       (BRL1_QSIZE - 2)
-
-
-/*
- * _elscuart_putc provides an entry point to the L1 interface driver;
- * writes a single character to the output queue.  Flushes at the
- * end of each line, and translates newlines into CR/LF.
- *
- * The kernel should generally use l1_cons_write instead, since it assumes
- * buffering, translation, prefixing, etc. are done at a higher
- * level.
- *
- */
-int
-_elscuart_putc( l1sc_t *sc, int c )
-{
-    sc_cq_t *q;
-    
-    q = &(sc->oq[ MAP_OQ(L1_ELSCUART_SUBCH(get_myid())) ]);
-
-    if( c != '\n' && c != '\r' && cq_used(q) >= ELSCUART_LINE_MAX ) {
-        cq_add( q, '\r' );
-        cq_add( q, '\n' );
-         _elscuart_flush( sc );
-        sc->sol = 1;
-    }
-
-    if( sc->sol && c != '\r' ) {
-        char            prefix[16], *s;
-
-        if( cq_room( q ) < 8 && _elscuart_flush(sc) < 0 )
-        {
-            return -1;
-        }
-	
-	if( sc->verbose )
-	{
-#ifdef  SUPPORT_PRINTING_M_FORMAT
-	    sprintf( prefix,
-		     "%c %d%d%d %M:",
-		     'A' + get_myid(),
-		     sc->nasid / 100,
-		     (sc->nasid / 10) % 10,
-		     sc->nasid / 10,
-		     sc->modid );
-#else
-	    sprintf( prefix,
-		     "%c %d%d%d 0x%x:",
-		     'A' + get_myid(),
-		     sc->nasid / 100,
-		     (sc->nasid / 10) % 10,
-		     sc->nasid / 10,
-		     sc->modid );
-#endif
-	    
-	    for( s = prefix; *s; s++ )
-		cq_add( q, *s );
-	}	    
-	sc->sol = 0;
-
-    }
-
-    if( cq_room( q ) < 2 && _elscuart_flush(sc) < 0 )
-    {
-        return -1;
-    }
-
-    if( c == '\n' ) {
-        cq_add( q, '\r' );
-        sc->sol = 1;
-    }
-
-    cq_add( q, (u_char) c );
-
-    if( c == '\n' ) {
-        /* flush buffered line */
-        if( _elscuart_flush( sc ) < 0 )
-        {
-            return -1;
-        }
-    }
-
-    if( c== '\r' )
-    {
-        sc->sol = 1;
-    }
-
-    return 0;
-}
-
-
-/*
- * _elscuart_getc reads a character from the input queue.  This
- * routine blocks.
- */
-int
-_elscuart_getc( l1sc_t *sc )
-{
-    int r;
-
-    while( (r = _elscuart_poll( sc )) == 0 );
-
-    if( r < 0 ) {
-	/* some error occurred */
-	return r;
-    }
-
-    return _elscuart_readc( sc );
-}
-
-
-
-/*
- * _elscuart_poll returns 1 if characters are ready for the
- * calling processor, 0 if they are not
- */
-int
-_elscuart_poll( l1sc_t *sc )
-{
-    int result;
-
-    if( sc->cons_listen ) {
-        result = l1_cons_poll( sc );
-        if( result )
-            return result;
-    }
-
-    return sc_poll( sc, L1_ELSCUART_SUBCH(get_myid()) );
-}
-
-
-
-/* _elscuart_readc is to be used only when _elscuart_poll has
- * indicated that a character is waiting.  Pulls a character
- * of this processor's console queue and returns it.
- *
- */
-int
-_elscuart_readc( l1sc_t *sc )
-{
-    int c;
-    sc_cq_t *q;
-    brl1_sch_t *subch;
-
-    if( sc->cons_listen ) {
-	subch = &(sc->subch[ SC_CONS_SYSTEM ]);
-	q = subch->iqp;
-	
-	SUBCH_DATA_LOCK( subch );
-        if( !cq_empty( q ) ) {
-            cq_rem( q, c );
-	    if( cq_empty( q ) ) {
-		atomic_set(&subch->packet_arrived, 0);
-	    }
-	    SUBCH_DATA_UNLOCK( subch );
-            return c;
-        }
-	SUBCH_DATA_UNLOCK( subch );
-    }
-
-    subch = &(sc->subch[ L1_ELSCUART_SUBCH(get_myid()) ]);
-    q = subch->iqp;
-
-    SUBCH_DATA_LOCK( subch );
-    if( cq_empty( q ) ) {
-	SUBCH_DATA_UNLOCK( subch );
-        return -1;
-    }
-
-    cq_rem( q, c );
-    if( cq_empty ( q ) ) {
-	atomic_set(&subch->packet_arrived, 0);
-    }
-    SUBCH_DATA_UNLOCK( subch );
-
-    return c;
-}
-
-
-/*
- * _elscuart_flush flushes queued output to the L1.
- * This routine blocks until the queue is flushed.
- */
-int
-_elscuart_flush( l1sc_t *sc )
-{
-    int r, n;
-    char buf[BRL1_QSIZE];
-    sc_cq_t *q = &(sc->oq[ MAP_OQ(L1_ELSCUART_SUBCH(get_myid())) ]);
-
-    while( (n = cq_used(q)) ) {
-
-        /* buffer queue contents */
-        r = BRL1_QSIZE - q->opos;
-
-        if( n > r ) {
-            BCOPY( q->buf + q->opos, buf, r  );
-            BCOPY( q->buf, buf + r, n - r  );
-        } else {
-            BCOPY( q->buf + q->opos, buf, n  );
-        }
-
-        /* attempt to send buffer contents */
-        r = brl1_send( sc, buf, cq_used( q ), 
-		       (BRL1_EVENT | L1_ELSCUART_SUBCH(get_myid())), 1 );
-
-        /* if no error, dequeue the sent characters; otherwise,
-         * return the error
-         */
-        if( r >= SC_SUCCESS ) {
-            q->opos = (q->opos + r) % BRL1_QSIZE;
-        }
-        else {
-            return r;
-        }
-    }
-
-    return 0;
-}
-
-
-
-/* _elscuart_probe returns non-zero if the L1 (and
- * consequently the elscuart) can be accessed
- */
-int
-_elscuart_probe( l1sc_t *sc )
-{
-#ifndef CONFIG_SERIAL_SGI_L1_PROTOCOL
-    return 0;
-#else
-    char ver[BRL1_QSIZE];
-    extern int elsc_version( l1sc_t *, char * );
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return 0;
-    return( elsc_version(sc, ver) >= 0 );
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-
-
-/* _elscuart_init zeroes out the l1sc_t console
- * queues for this processor's console subchannel.
- */
-void
-_elscuart_init( l1sc_t *sc )
-{
-    brl1_sch_t *subch = &sc->subch[L1_ELSCUART_SUBCH(get_myid())];
-
-    SUBCH_DATA_LOCK(subch);
-
-    atomic_set(&subch->packet_arrived, 0);
-    cq_init( subch->iqp );
-    cq_init( &sc->oq[MAP_OQ(L1_ELSCUART_SUBCH(get_myid()))] );
-
-    SUBCH_DATA_UNLOCK(subch);
-}
+#endif	/* LINUX_KERNEL_THREADS */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/l1_command.c linux/arch/ia64/sn/io/l1_command.c
--- linux.orig/arch/ia64/sn/io/l1_command.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/l1_command.c	2002-07-20 01:08:37.000000000 +0000
@@ -4,20 +4,20 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000 - 2001 Silicon Graphics, Inc.
+ * All rights reserved.
  */ 
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
 #include <asm/sn/labelcl.h>
 #include <asm/sn/eeprom.h>
-#include <asm/sn/ksys/i2c.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
@@ -27,7 +27,6 @@
 #define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
 #define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
 
-#define LOCAL_HUB	LOCAL_HUB_ADDR
 #define LD(x)		(*(volatile uint64_t *)(x))
 #define SD(x, v)	(LD(x) = (uint64_t) (v))
 
@@ -75,7 +74,7 @@
 
 void elsc_init(elsc_t *e, nasid_t nasid)
 {
-    sc_init((l1sc_t *)e, nasid, BRL1_LOCALUART);
+    sc_init((l1sc_t *)e, nasid, BRL1_LOCALHUB_UART);
 }
 
 
@@ -1377,84 +1376,3 @@
 
     return 0;
 }
-
-
-
-/* elscuart routines 
- *
- * Most of the elscuart functionality is implemented in l1.c.  The following
- * is directly "recycled" from elsc.c.
- */
-
-
-/*
- * _elscuart_puts
- */
-
-int _elscuart_puts(elsc_t *e, char *s)
-{
-    int			c;
-
-    if (s == 0)
-	s = "<NULL>";
-
-    while ((c = LBYTE(s)) != 0) {
-	if (_elscuart_putc(e, c) < 0)
-	    return -1;
-	s++;
-    }
-
-    return 0;
-}
-
-
-/*
- * elscuart wrapper routines
- *
- *   The following routines are similar to their counterparts in l1.c,
- *   except instead of taking an elsc_t pointer directly, they call
- *   a global routine "get_elsc" to obtain the pointer.
- *   This is useful when the elsc is employed for stdio.
- */
-
-int elscuart_probe(void)
-{
-    return _elscuart_probe(get_elsc());
-}
-
-void elscuart_init(void *init_data)
-{
-    _elscuart_init(get_elsc());
-    /* dummy variable included for driver compatability */
-    init_data = init_data;
-}
-
-int elscuart_poll(void)
-{
-    return _elscuart_poll(get_elsc());
-}
-
-int elscuart_readc(void)
-{
-    return _elscuart_readc(get_elsc());
-}
-
-int elscuart_getc(void)
-{
-    return _elscuart_getc(get_elsc());
-}
-
-int elscuart_puts(char *s)
-{
-    return _elscuart_puts(get_elsc(), s);
-}
-
-int elscuart_putc(int c)
-{
-    return _elscuart_putc(get_elsc(), c);
-}
-
-int elscuart_flush(void)
-{
-    return _elscuart_flush(get_elsc());
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/labelcl.c linux/arch/ia64/sn/io/labelcl.c
--- linux.orig/arch/ia64/sn/io/labelcl.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/labelcl.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,21 +1,10 @@
 /*  labelcl - SGI's Hwgraph Compatibility Layer.
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    Colin Ngam may be reached by email at cngam@sgi.com
-
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
 */
 
 #include <linux/types.h>
@@ -286,7 +275,7 @@
 		if (!strcmp(info_name, old_label_list[i].name)) {
 			/* Not allowed to add duplicate labelled info names. */
 			kfree(new_label_list);
-			printk(KERN_WARNING "labelcl_info_add_LBL: Duplicate label name %s for vertex 0x%p\n", info_name, de);
+			printk(KERN_WARNING "labelcl_info_add_LBL: Duplicate label name %s for vertex 0x%p\n", info_name, (void *)de);
 			return(-1);
 		}
 		new_label_list[i] = old_label_list[i]; /* structure copy */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/mem_refcnt.c linux/arch/ia64/sn/io/mem_refcnt.c
--- linux.orig/arch/ia64/sn/io/mem_refcnt.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/mem_refcnt.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,222 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-#include <linux/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/hubspc.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/mem_refcnt.h>
-#include <asm/sn/hwcntrs.h>
-// From numa_hw.h
-
-#define MIGR_COUNTER_MAX_GET(nodeid) \
-        (NODEPDA_MCD((nodeid))->migr_system_kparms.migr_threshold_reference)
-/*
- * Get the Absolute Theshold
- */
-#define MIGR_THRESHOLD_ABS_GET(nodeid) ( \
-        MD_MIG_VALUE_THRESH_GET(COMPACT_TO_NASID_NODEID(nodeid)))
-/*
- * Get the current Differential Threshold
- */
-#define MIGR_THRESHOLD_DIFF_GET(nodeid) \
-        (NODEPDA_MCD(nodeid)->migr_as_kparms.migr_base_threshold)
-
-#define NUM_OF_HW_PAGES_PER_SW_PAGE()   (NBPP / MD_PAGE_SIZE)
-
-// #include "migr_control.h"
-
-int
-mem_refcnt_attach(devfs_handle_t hub)
-{
-        devfs_handle_t refcnt_dev;
-        
-        hwgraph_char_device_add(hub,
-                                "refcnt",
-                                "hubspc_", 
-				&refcnt_dev);
-        device_info_set(refcnt_dev, (void*)(ulong)HUBSPC_REFCOUNTERS);
-
-        return (0);
-}
-
-
-/*ARGSUSED*/
-int
-mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
-{
-        cnodeid_t node;
-
-        ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(*devp) == HUBSPC_REFCOUNTERS );
-
-        node = master_node_get(*devp);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) {
-                return (ENODEV);
-        }
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 );
-
-        return (0);
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-        return 0;
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-        cnodeid_t node;
-        int errcode;
-        char* buffer;
-        size_t blen;
-        
-        ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS );
-
-        node = master_node_get(dev);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
-
-        /*
-         * XXXX deal with prot's somewhere around here....
-         */
-
-        buffer = NODEPDA(node)->migr_refcnt_counterbuffer;
-        blen = NODEPDA(node)->migr_refcnt_cbsize;
-
-        /*
-         * Force offset to be a multiple of sizeof(refcnt_t)
-         * We round up.
-         */
-
-        off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t);
-
-        if ( ((buffer + blen) - (buffer + off + len)) < 0 ) {
-                return (EPERM);
-        }
-
-        errcode = v_mapphys(vt,
-                            buffer + off,
-                            len);
-
-        return errcode;
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-        return 0;
-}
-
-/* ARGSUSED */
-int
-mem_refcnt_ioctl(devfs_handle_t dev,
-                 int cmd,
-                 void *arg,
-                 int mode,
-                 cred_t *cred_p,
-                 int *rvalp)
-{
-        cnodeid_t node;
-        int errcode;
-	extern int numnodes;
-        
-        ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS );
-
-        node = master_node_get(dev);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
-
-        errcode = 0;
-        
-        switch (cmd) {
-        case RCB_INFO_GET:
-        {
-                rcb_info_t rcb;
-                
-                rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize;
-                
-                rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets;
-                rcb.rcb_sw_counters_per_set = numnodes;
-                rcb.rcb_sw_counter_size = sizeof(refcnt_t);
-
-                rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets /
-                                     NUM_OF_HW_PAGES_PER_SW_PAGE();  
-                rcb.rcb_base_page_size = NBPP;
-                rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0));
-                
-                rcb.rcb_cnodeid = node;
-                rcb.rcb_granularity = MD_PAGE_SIZE;
-#ifdef LATER
-                rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node);
-                rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node);
-#endif
-                rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node);
-                rcb.rcb_num_slots = node_getnumslots(node);
-
-                if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) {
-                        errcode = EFAULT;
-                }
-
-                break;
-        }
-        case RCB_SLOT_GET:
-        {
-                rcb_slot_t slot[MAX_MEM_SLOTS];
-                int s;
-                int nslots;
-
-                nslots = node_getnumslots(node);
-                ASSERT(nslots <= MAX_MEM_SLOTS);
-                for (s = 0; s < nslots; s++) {
-                        slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s));
-#ifdef LATER
-                        slot[s].size  = (uint64_t)ctob(slot_getsize(node, s));
-#else
-                        slot[s].size  = (uint64_t)1;
-#endif
-                }
-                if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) {
-                        errcode = EFAULT;
-                }
-                
-                *rvalp = nslots;
-                break;
-        }
-                
-        default:
-                errcode = EINVAL;
-                break;
-
-        }
-        
-        return errcode;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/ml_SN_init.c linux/arch/ia64/sn/io/ml_SN_init.c
--- linux.orig/arch/ia64/sn/io/ml_SN_init.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/ml_SN_init.c	2002-07-20 01:08:25.000000000 +0000
@@ -4,37 +4,30 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/slab.h>
+#include <linux/bootmem.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/nodemask.h>
 #include <asm/sn/sn_private.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/sn_cpuid.h>
-#include <asm/sn/synergy.h>
-
-
-#if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/ip27config.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/sn1/sn1.h>
-#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
-
+#include <asm/sn/snconfig.h>
 
 extern int numcpus;
 extern char arg_maxnodes[];
 extern cpuid_t master_procid;
-extern void * kmem_alloc_node(register size_t, register int , cnodeid_t);
+#if defined(CONFIG_IA64_SGI_SN1)
 extern synergy_da_t    *Synergy_da_indr[];
+#endif
 
 extern int hasmetarouter;
 
@@ -45,18 +38,8 @@
 
 extern xwidgetnum_t hub_widget_id(nasid_t);
 
-static int	fine_mode = 0;
-
-static cnodemask_t	hub_init_mask;	/* Mask of cpu in a node doing init */
-static volatile cnodemask_t hub_init_done_mask;
-					/* Node mask where we wait for
-					 * per hub initialization
-					 */
-spinlock_t		hub_mask_lock;  /* Lock for hub_init_mask above. */
-
 extern int valid_icache_reasons;	/* Reasons to flush the icache */
 extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern int numnodes;
 extern u_char miniroot;
 extern volatile int	need_utlbmiss_patch;
 extern void iograph_early_init(void);
@@ -83,20 +66,6 @@
 		 */ 
 		master_nasid = get_nasid();
 		set_master_bridge_base();
-		FIXME("mlreset: Enable when we support ioc3 ..");
-#ifdef	LATER
-		if (get_console_nasid() == master_nasid) 
-			/* Set up the IOC3 */
-			ioc3_mlreset((ioc3_cfg_t *)KL_CONFIG_CH_CONS_INFO(master_nasid)->config_base,
-				     (ioc3_mem_t *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base);
-
-		/*
-		 * Initialize Master nvram base.
-		 */
-		nvram_baseinit();
-
-		fine_mode = is_fine_dirmode();
-#endif /* LATER */
 
 		/* We're the master processor */
 		master_procid = smp_processor_id();
@@ -108,75 +77,12 @@
 		 */
 		ASSERT_ALWAYS(master_nasid == get_nasid());
 
-#ifdef	LATER
-
-	/*
-	 * Activate when calias is implemented.
-	 */
-		/* Set all nodes' calias sizes to 8k */
-		for (i = 0; i < maxnodes; i++) {
-			nasid_t nasid;
-			int	sn;
-
-			nasid = COMPACT_TO_NASID_NODEID(i);
-
-			/*
-			 * Always have node 0 in the region mask, otherwise CALIAS accesses
-			 * get exceptions since the hub thinks it is a node 0 address.
-			 */
-			for (sn=0; sn<NUM_SUBNODES; sn++) {
-				REMOTE_HUB_PI_S(nasid, sn, PI_REGION_PRESENT, (region_mask | 1));
-				REMOTE_HUB_PI_S(nasid, sn, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K);
-			}
-
-			/*
-			 * Set up all hubs to havew a big window pointing at
-			 * widget 0.
-			 * Memory mode, widget 0, offset 0
-			 */
-			REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN),
-				((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) |
-				(0 << IIO_ITTE_WIDGET_SHIFT)));
-		}
-#endif /* LATER */
-
-		/* Set up the hub initialization mask and init the lock */
-		CNODEMASK_CLRALL(hub_init_mask);
-		CNODEMASK_CLRALL(hub_init_done_mask);
-
-		spin_lock_init(&hub_mask_lock);
-
 		/* early initialization of iograph */
 		iograph_early_init();
 
 		/* Initialize Hub Pseudodriver Management */
 		hubdev_init();
 
-#ifdef	LATER
-		/*
-		 * Our IO system doesn't require cache writebacks.  Set some
-		 * variables appropriately.
-		 */
-		cachewrback = 0;
-		valid_icache_reasons &= ~(CACH_AVOID_VCES | CACH_IO_COHERENCY);
-		valid_dcache_reasons &= ~(CACH_AVOID_VCES | CACH_IO_COHERENCY);
-
-		/*
-		 * make sure we are running with the right rev of chips
-		 */
-		verify_snchip_rev();
-
-		/*
-                 * Since we've wiped out memory at this point, we
-                 * need to reset the ARCS vector table so that it
-                 * points to appropriate functions in the kernel
-                 * itself.  In this way, we can maintain the ARCS
-                 * vector table conventions without having to actually
-                 * keep redundant PROM code in memory.
-                 */
-		he_arcs_set_vectors();
-#endif /* LATER */
-
 	} else { /* slave != 0 */
 		/*
 		 * This code is performed ONLY by slave processors.
@@ -193,34 +99,17 @@
 void init_platform_nodepda(nodepda_t *npda, cnodeid_t node)
 {
 	hubinfo_t hubinfo;
+#ifdef CONFIG_IA64_SGI_SN1
 	int	  sn;
-	cnodeid_t i;
-	ushort *numcpus_p;
+#endif
 
 	extern void router_map_init(nodepda_t *);
 	extern void router_queue_init(nodepda_t *,cnodeid_t);
 	extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int);
 
-#if defined(DEBUG)
-	extern spinlock_t	intr_dev_targ_map_lock;
-	extern uint64_t 	intr_dev_targ_map_size;
-
-	/* Initialize the lock to access the device - target cpu mapping
-	 * table. This table is explicitly for debugging purposes only and
-	 * to aid the "intrmap" idbg command
-	 */
-	if (node == 0) {
-		/* Make sure we do this only once .
-		 * There is always a cnode 0 present.
-		 */
-		intr_dev_targ_map_size = 0;
-		spin_lock_init(&intr_dev_targ_map_lock);
-	}
-#endif	/* DEBUG */
 	/* Allocate per-node platform-dependent data */
-	hubinfo = (hubinfo_t)kmem_alloc_node(sizeof(struct hubinfo_s), GFP_ATOMIC, node);
+	hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s));
 
-	ASSERT_ALWAYS(hubinfo);
 	npda->pdinfo = (void *)hubinfo;
 	hubinfo->h_nodepda = npda;
 	hubinfo->h_cnodeid = node;
@@ -230,92 +119,37 @@
 
 	hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
 	npda->xbow_peer = INVALID_NASID;
-	/* Initialize the linked list of
+
+	/* 
+	 * Initialize the linked list of
 	 * router info pointers to the dependent routers
 	 */
 	npda->npda_rip_first = NULL;
-	/* npda_rip_last always points to the place
+
+	/*
+	 * npda_rip_last always points to the place
 	 * where the next element is to be inserted
 	 * into the list 
 	 */
 	npda->npda_rip_last = &npda->npda_rip_first;
-	npda->dependent_routers = 0;
 	npda->module_id = INVALID_MODULE;
 
+#ifdef CONFIG_IA64_SGI_SN1
 	/*
-	 * Initialize the subnodePDA.
-	 */
+	* Initialize the interrupts.
+	* On sn2, this is done at pci init time,
+	* because sn2 needs the cpus checked in
+	* when it initializes interrupts.  This is
+	* so we don't see all the nodes as headless.
+	*/
 	for (sn=0; sn<NUM_SUBNODES; sn++) {
-		SNPDA(npda,sn)->prof_count = 0;
-		SNPDA(npda,sn)->next_prof_timeout = 0;
 		intr_init_vecblk(npda, node, sn);
 	}
+#endif /* CONFIG_IA64_SGI_SN1 */
 
-	npda->vector_unit_busy = 0;
-
-	spin_lock_init(&npda->vector_lock);
 	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
-	spin_lock_init(&npda->fprom_lock);
 
-	spin_lock_init(&npda->node_utlbswitchlock);
-	npda->ni_error_print = 0;
 #ifdef	LATER
-	if (need_utlbmiss_patch) {
-		npda->node_need_utlbmiss_patch = 1;
-		npda->node_utlbmiss_patched = 1;
-	}
-#endif
-
-	/*
-	 * Clear out the nasid mask.
-	 */
-	for (i = 0; i < NASID_MASK_BYTES; i++)
-		npda->nasid_mask[i] = 0;
-
-	for (i = 0; i < numnodes; i++) {
-		nasid_t nasid = COMPACT_TO_NASID_NODEID(i);
-
-		/* Set my mask bit */
-		npda->nasid_mask[nasid / 8] |= (1 << nasid % 8);
-	}
-
-#ifdef	LATER
-	npda->node_first_cpu = get_cnode_cpu(node);
-#endif
-
-	if (npda->node_first_cpu != CPU_NONE) {
-		/*
-		 * Count number of cpus only if first CPU is valid.
-		 */
-		numcpus_p = &npda->node_num_cpus;
-		*numcpus_p = 0;
-		for (i = npda->node_first_cpu; i < MAXCPUS; i++) {
-			if (CPUID_TO_COMPACT_NODEID(i) != node)
-			    break;
-			else
-			    (*numcpus_p)++;
-		}
-	} else {
-		npda->node_num_cpus = 0; 
-	}
-
-	/* Allocate memory for the dump stack on each node 
-	 * This is useful during nmi handling since we
-	 * may not be guaranteed shared memory at that time
-	 * which precludes depending on a global dump stack
-	 */
-#ifdef	LATER
-	npda->dump_stack = (uint64_t *)kmem_zalloc_node(DUMP_STACK_SIZE,VM_NOSLEEP,
-							  node);
-	ASSERT_ALWAYS(npda->dump_stack);
-	ASSERT(npda->dump_stack);
-#endif
-	/* Initialize the counter which prevents
-	 * both the cpus on a node to proceed with nmi
-	 * handling.
-	 */
-#ifdef	LATER
-	npda->dump_count = 0;
 
 	/* Setup the (module,slot) --> nic mapping for all the routers
 	 * in the system. This is useful during error handling when
@@ -325,17 +159,9 @@
 
 	/* Allocate memory for the per-node router traversal queue */
 	router_queue_init(npda,node);
-	npda->sbe_info = kmem_zalloc_node_hint(sizeof (sbe_info_t), 0, node);
+	npda->sbe_info = alloc_bootmem_node(NODE_DATA(node), sizeof (sbe_info_t));
 	ASSERT(npda->sbe_info);
 
-#ifdef CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
-	/*
-	 * Initialize bte info pointers to NULL
-	 */
-	for (i = 0; i < BTES_PER_NODE; i++) {
-		npda->node_bte_info[i] = (bteinfo_t *)NULL;
-	}
-#endif
 #endif /* LATER */
 }
 
@@ -345,260 +171,44 @@
  * Must be done _after_ init_platform_nodepda().
  * If we need a lock here, something else is wrong!
  */
-// void init_platform_pda(pda_t *ppda, cpuid_t cpu)
 void init_platform_pda(cpuid_t cpu)
 {
+#if defined(CONFIG_IA64_SGI_SN1)
 	hub_intmasks_t *intmasks;
-#ifdef	LATER
-	cpuinfo_t cpuinfo;
-#endif
-	int i;
+	int i, subnode;
 	cnodeid_t	cnode;
 	synergy_da_t	*sda;
 	int	which_synergy;
 
-#ifdef	LATER
-	/* Allocate per-cpu platform-dependent data */
-	cpuinfo = (cpuinfo_t)kmem_alloc_node(sizeof(struct cpuinfo_s), GFP_ATOMIC, cputocnode(cpu));
-	ASSERT_ALWAYS(cpuinfo);
-	ppda->pdinfo = (void *)cpuinfo;
-	cpuinfo->ci_cpupda = ppda;
-	cpuinfo->ci_cpuid = cpu;
-#endif
 
 	cnode = cpuid_to_cnodeid(cpu);
 	which_synergy = cpuid_to_synergy(cpu);
+
 	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	// intmasks = &ppda->p_intmasks;
 	intmasks = &sda->s_intmasks;
 
-#ifdef	LATER
-	ASSERT_ALWAYS(&ppda->p_nodepda);
-#endif
-
 	/* Clear INT_PEND0 masks. */
 	for (i = 0; i < N_INTPEND0_MASKS; i++)
 		intmasks->intpend0_masks[i] = 0;
 
 	/* Set up pointer to the vector block in the nodepda. */
 	/* (Cant use SUBNODEPDA - not working yet) */
-	intmasks->dispatch0 = &Nodepdaindr[cnode]->snpda[cpuid_to_subnode(cpu)].intr_dispatch0;
-	intmasks->dispatch1 = &Nodepdaindr[cnode]->snpda[cpuid_to_subnode(cpu)].intr_dispatch1;
+	subnode = cpuid_to_subnode(cpu);
+	intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0;
+	intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1;
+	if (intmasks->dispatch0 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch0 ||
+	   intmasks->dispatch1 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch1)
+	   	panic("xxx");
+	intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0;
+	intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1;
 
 	/* Clear INT_PEND1 masks. */
 	for (i = 0; i < N_INTPEND1_MASKS; i++)
 		intmasks->intpend1_masks[i] = 0;
-
-
-#ifdef	LATER
-	/* Don't read the routers unless we're the master. */
-	ppda->p_routertick = 0;
-#endif
-
+#endif	/* CONFIG_IA64_SGI_SN1 */
 }
 
-#if (defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)) && !defined(BRINGUP)	/* protect low mem for IP35/7 */
-#error "need protect_hub_calias, protect_nmi_handler_data"
-#endif
-
-#ifdef	LATER
-/*
- * For now, just protect the first page (exception handlers). We
- * may want to protect more stuff later.
- */
 void
-protect_hub_calias(nasid_t nasid)
-{
-	paddr_t pa = NODE_OFFSET(nasid) + 0; /* page 0 on node nasid */
-	int i;
-
-	for (i = 0; i < MAX_REGIONS; i++) {
-		if (i == nasid_to_region(nasid))
-			continue;
-	}
-}
-
-/*
- * Protect the page of low memory used to communicate with the NMI handler.
- */
-void
-protect_nmi_handler_data(nasid_t nasid, int slice)
-{
-	paddr_t pa = NODE_OFFSET(nasid) + NMI_OFFSET(nasid, slice);
-	int i;
-
-	for (i = 0; i < MAX_REGIONS; i++) {
-		if (i == nasid_to_region(nasid))
-			continue;
-	}
-}
-#endif /* LATER */
-
-
-#ifdef LATER
-/*
- * Protect areas of memory that we access uncached by marking them as
- * poisoned so the T5 can't read them speculatively and erroneously
- * mark them dirty in its cache only to write them back with old data
- * later.
- */
-static void
-protect_low_memory(nasid_t nasid)
-{
-	/* Protect low memory directory */
-	poison_state_alter_range(KLDIR_ADDR(nasid), KLDIR_SIZE, 1);
-
-	/* Protect klconfig area */
-	poison_state_alter_range(KLCONFIG_ADDR(nasid), KLCONFIG_SIZE(nasid), 1);
-
-	/* Protect the PI error spool area. */
-	poison_state_alter_range(PI_ERROR_ADDR(nasid), PI_ERROR_SIZE(nasid), 1);
-
-	/* Protect CPU A's cache error eframe area. */
-	poison_state_alter_range(TO_NODE_UNCAC(nasid, CACHE_ERR_EFRAME),
-				CACHE_ERR_AREA_SIZE, 1);
-
-	/* Protect CPU B's area */
-	poison_state_alter_range(TO_NODE_UNCAC(nasid, CACHE_ERR_EFRAME)
-				^ UALIAS_FLIP_BIT,
-				CACHE_ERR_AREA_SIZE, 1);
-#error "SN1 not handled correctly"
-}
-#endif	/* LATER */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-void
-per_hub_init(cnodeid_t cnode)
-{
-	uint64_t	done;
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)	/* SN1 specific */
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-#endif
-#ifdef	LATER
-	int i;
-#endif
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	/* Grab the hub_mask lock. */
-	spin_lock(&hub_mask_lock);
-
-	/* Test our bit. */
-	if (!(done = CNODEMASK_TSTB(hub_init_mask, cnode))) {
-
-		/* Turn our bit on in the mask. */
-		CNODEMASK_SETB(hub_init_mask, cnode);
-	}
-
-#if defined(SN0_HWDEBUG)
-	hub_config_setup();
-#endif
-	/* Release the hub_mask lock. */
-	spin_unlock(&hub_mask_lock);
-
-	/*
-	 * Do the actual initialization if it hasn't been done yet.
-	 * We don't need to hold a lock for this work.
-	 */
-	if (!done) {
-		npdap = NODEPDA(cnode);
-
-#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
-		/* initialize per-node synergy perf instrumentation */
-		npdap->synergy_perf_enabled = 0; /* off by default */
-		npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED;
-		npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT;
-		npdap->synergy_inactive_intervals = 0;
-		npdap->synergy_active_intervals = 0;
-		npdap->synergy_perf_data = NULL;
-		npdap->synergy_perf_first = NULL;
-#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
-
-		npdap->hub_chip_rev = get_hub_chiprev(nasid);
-
-#ifdef	LATER
-		for (i = 0; i < CPUS_PER_NODE; i++) {
-			cpu = cnode_slice_to_cpuid(cnode, i);
-			if (!cpu_enabled(cpu))
-			    SET_CPU_LEDS(nasid, i, 0xf);
-		}
-#endif /* LATER */
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) /* SN1 specific */
-
-		/*
-		 * Set the total number of CRBs that can be used.
-		 */
-		ii_icmr.ii_icmr_regval= 0x0;
-		ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
-		REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-		/*
-		 * Set the number of CRBs that both of the BTEs combined
-		 * can use minus 1.
-		 */
-		ii_ibcr.ii_ibcr_regval= 0x0;
-		ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-		REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-		/*
-		 * Set CRB timeout to be 10ms.
-		 */
-		REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 );
-		REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-
-#endif /* SN0_HWDEBUG */
-
-
-
-		/* Reserve all of the hardwired interrupt levels. */
-		intr_reserve_hardwired(cnode);
-
-		/* Initialize error interrupts for this hub. */
-		hub_error_init(cnode);
-
-#ifdef LATER
-		/* Set up correctable memory/directory ECC error interrupt. */
-		install_eccintr(cnode);
-
-		/* Protect our exception vectors from accidental corruption. */
-		protect_hub_calias(nasid);
-
-		/* Enable RT clock interrupts */
-		hub_rtc_init(cnode);
-		hub_migrintr_init(cnode); /* Enable migration interrupt */
-#endif	/* LATER */
-
-		spin_lock(&hub_mask_lock);
-		CNODEMASK_SETB(hub_init_done_mask, cnode);
-		spin_unlock(&hub_mask_lock);
-
-	} else {
-		/*
-		 * Wait for the other CPU to complete the initialization.
-		 */
-		while (CNODEMASK_TSTB(hub_init_done_mask, cnode) == 0) {
-			/*
-			 * On SNIA64 we should never get here ..
-			 */
-			printk("WARNING: per_hub_init: Should NEVER get here!\n");
-			/* LOOP */
-			;
-		}
-	}
-}
-
-extern void
 update_node_information(cnodeid_t cnodeid)
 {
 	nodepda_t *npda = NODEPDA(cnodeid);
@@ -623,22 +233,3 @@
 		npda_rip = npda_rip->router_next;
 	}
 }
-
-hubreg_t
-get_region(cnodeid_t cnode)
-{
-	if (fine_mode)
-		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
-	else
-		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
-}
-
-hubreg_t
-nasid_to_region(nasid_t nasid)
-{
-	if (fine_mode)
-		return nasid >> NASID_TO_FINEREG_SHFT;
-	else
-		return nasid >> NASID_TO_COARSEREG_SHFT;
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/ml_SN_intr.c linux/arch/ia64/sn/io/ml_SN_intr.c
--- linux.orig/arch/ia64/sn/io/ml_SN_intr.c	2001-07-31 17:30:09.000000000 +0000
+++ linux/arch/ia64/sn/io/ml_SN_intr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1728 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Alan Mayer
- */
-
-/*
- * intr.c-
- *	This file contains all of the routines necessary to set up and
- *	handle interrupts on an IP27 board.
- */
-
-#ident  "$Revision: 1.167 $"
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/smp.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/nodemask.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/synergy.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/intr.h>
-
-#if DEBUG_INTR_TSTAMP_DEBUG
-#include <sys/debug.h>
-#include <sys/idbg.h>
-#include <sys/inst.h>
-void do_splx_log(int, int);
-void spldebug_log_event(int);
-#endif
-
-// FIXME - BRINGUP
-#ifdef CONFIG_SMP
-extern unsigned long cpu_online_map;
-#endif
-#define cpu_allows_intr(cpu)	(1)
-// If I understand what's going on with this, 32 should work.
-// physmem_maxradius seems to be the maximum number of router
-// hops to get from one end of the system to the other.  With
-// a maximally configured machine, with the dumbest possible
-// topology, we would make 32 router hops.  For what we're using
-// it for, the dumbest possible should suffice.
-#define physmem_maxradius()	32
-
-#define SUBNODE_ANY -1
-
-extern int	nmied;
-extern int	hub_intr_wakeup_cnt;
-extern synergy_da_t	*Synergy_da_indr[];
-extern cpuid_t         master_procid;
-
-extern cnodeid_t master_node_get(devfs_handle_t vhdl);
-
-extern snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
-
-
-#define INTR_LOCK(vecblk) \
-     (s = mutex_spinlock(&(vecblk)->vector_lock))
-#define INTR_UNLOCK(vecblk) \
-      mutex_spinunlock(&(vecblk)->vector_lock, s)
-
-/*
- * REACT/Pro
- */
-
-
-
-/* 
- * Find first bit set 
- * Used outside this file also 
- */
-int ms1bit(unsigned long x)
-{
-    int			b;
-
-    if (x >> 32)	b  = 32, x >>= 32;
-    else		b  =  0;
-    if (x >> 16)	b += 16, x >>= 16;
-    if (x >>  8)	b +=  8, x >>=  8;
-    if (x >>  4)	b +=  4, x >>=  4;
-    if (x >>  2)	b +=  2, x >>=  2;
-
-    return b + (int) (x >> 1);
-}
-
-/* ARGSUSED */
-void
-intr_stray(void *lvl)
-{
-    PRINT_WARNING("Stray Interrupt - level %ld to cpu %d", (long)lvl, cpuid());
-}
-
-#if defined(DEBUG)
-
-/* Infrastructure  to gather the device - target cpu mapping info */
-#define MAX_DEVICES	1000	/* Reasonable large number . Need not be 
-				 * the exact maximum # devices possible.
-				 */
-#define MAX_NAME	100	
-typedef struct {
-	dev_t		dev;	/* device */
-	cpuid_t		cpuid;	/* target cpu */
-	cnodeid_t	cnodeid;/* node on which the target cpu is present */
-	int		bit;	/* intr bit reserved */
-	char		intr_name[MAX_NAME]; /* name of the interrupt */
-} intr_dev_targ_map_t;
-
-intr_dev_targ_map_t 	intr_dev_targ_map[MAX_DEVICES];
-uint64_t		intr_dev_targ_map_size;
-spinlock_t		intr_dev_targ_map_lock;
-
-/* Print out the device - target cpu mapping.
- * This routine is used only in the idbg command
- * "intrmap" 
- */
-void
-intr_dev_targ_map_print(cnodeid_t cnodeid)
-{
-	int  i,j,size = 0;
-	int  print_flag = 0,verbose = 0;	
-	char node_name[10];
-	
-	if (cnodeid != CNODEID_NONE) {
-		nodepda_t 	*npda;
-
-		npda = NODEPDA(cnodeid);
-		for (j=0; j<NUM_SUBNODES; j++) {
-			qprintf("\n SUBNODE %d\n INT_PEND0: ", j);
-			for(i = 0 ; i < N_INTPEND_BITS ; i++)
-				qprintf("%d",SNPDA(npda,j)->intr_dispatch0.info[i].ii_flags);
-			qprintf("\n INT_PEND1: ");
-			for(i = 0 ; i < N_INTPEND_BITS ; i++)
-				qprintf("%d",SNPDA(npda,j)->intr_dispatch1.info[i].ii_flags);
-		}
-		verbose = 1;
-	}
-	qprintf("\n Device - Target Map [Interrupts: %s Node%s]\n\n",
-		(verbose ? "All" : "Non-hardwired"),
-		(cnodeid == CNODEID_NONE) ? "s: All" : node_name); 
-		
-	qprintf("Device\tCpu\tCnode\tIntr_bit\tIntr_name\n");
-	for (i = 0 ; i < intr_dev_targ_map_size ; i++) {
-
-		print_flag = 0;
-		if (verbose) {
-			if (cnodeid != CNODEID_NONE) {
-				if (cnodeid == intr_dev_targ_map[i].cnodeid)
-					print_flag = 1;
-			} else {
-				print_flag = 1;
-			}
-		} else {
-			if (intr_dev_targ_map[i].dev != 0) {
-				if (cnodeid != CNODEID_NONE) {
-					if (cnodeid == 
-					    intr_dev_targ_map[i].cnodeid)
-						print_flag = 1;
-				} else {
-					print_flag = 1;
-				}
-			}
-		}
-		if (print_flag) {
-			size++;
-			qprintf("%d\t%d\t%d\t%d\t%s\n",
-				intr_dev_targ_map[i].dev,
-				intr_dev_targ_map[i].cpuid,
-				intr_dev_targ_map[i].cnodeid,
-				intr_dev_targ_map[i].bit,
-				intr_dev_targ_map[i].intr_name);
-		}
-
-	}
-	qprintf("\nTotal : %d\n",size);
-}
-#endif /* DEBUG */
-
-/*
- * The spinlocks have already been initialized.  Now initialize the interrupt
- * vectors.  One processor on each hub does the work.
- */
-void
-intr_init_vecblk(nodepda_t *npda, cnodeid_t node, int sn)
-{
-    int			i, ip=0;
-    intr_vecblk_t	*vecblk;
-    subnode_pda_t	*snpda;
-
-
-    snpda = SNPDA(npda,sn);
-    do {
-	if (ip == 0) {
-	    vecblk = &snpda->intr_dispatch0;
-	} else {
-	    vecblk = &snpda->intr_dispatch1;
-	}
-
-	/* Initialize this vector. */
-	for (i = 0; i < N_INTPEND_BITS; i++) {
-		vecblk->vectors[i].iv_func = intr_stray;
-		vecblk->vectors[i].iv_prefunc = NULL;
-		vecblk->vectors[i].iv_arg = (void *)(__psint_t)(ip * N_INTPEND_BITS + i);
-
-		vecblk->info[i].ii_owner_dev = 0;
-		strcpy(vecblk->info[i].ii_name, "Unused");
-		vecblk->info[i].ii_flags = 0;	/* No flags */
-		vecblk->vectors[i].iv_mustruncpu = -1; /* No CPU yet. */
-
-	    }
-
-	mutex_spinlock_init(&vecblk->vector_lock);
-
-	vecblk->vector_count = 0;    
-	for (i = 0; i < CPUS_PER_SUBNODE; i++)
-		vecblk->cpu_count[i] = 0;
-
-	vecblk->vector_state = VECTOR_UNINITED;
-
-    } while (++ip < 2);
-
-}
-
-
-/*
- * do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
- *					devfs_handle_t owner_dev, char *name)
- *	Internal work routine to reserve or unreserve an interrupt level.
- *		cpu is the CPU to which the interrupt will be sent.
- *		bit is the level bit to reserve.  -1 means any level
- *		resflags should include II_ERRORINT if this is an
- *			error interrupt, II_THREADED if the interrupt handler
- *			will be threaded, or 0 otherwise.
- *		reserve should be set to II_RESERVE or II_UNRESERVE
- *			to get or clear a reservation.
- *		owner_dev is the device that "owns" this interrupt, if supplied
- *		name is a human-readable name for this interrupt, if supplied
- *	intr_reserve_level returns the bit reserved or -1 to indicate an error
- */
-static int
-do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
-					devfs_handle_t owner_dev, char *name)
-{
-    intr_vecblk_t	*vecblk;
-    hub_intmasks_t 	*hub_intmasks;
-    unsigned long s;
-    int rv = 0;
-    int ip;
-    synergy_da_t	*sda;
-    int		which_synergy;
-    cnodeid_t	cnode;
-
-    ASSERT(bit < N_INTPEND_BITS * 2);
-
-    cnode = cpuid_to_cnodeid(cpu);
-    which_synergy = cpuid_to_synergy(cpu);
-    sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-    hub_intmasks = &sda->s_intmasks;
-    // hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
-
-    // if (pdaindr[cpu].pda == NULL) return -1;
-    if ((bit < N_INTPEND_BITS) && !(resflags & II_ERRORINT)) {
-	vecblk = hub_intmasks->dispatch0;
-	ip = 0;
-    } else {
-	ASSERT((bit >= N_INTPEND_BITS) || (bit == -1));
-	bit -= N_INTPEND_BITS;	/* Get position relative to INT_PEND1 reg. */
-	vecblk = hub_intmasks->dispatch1;
-	ip = 1;
-    }
-
-    INTR_LOCK(vecblk);
-
-    if (bit <= -1) {
-	bit = 0;
-	ASSERT(reserve == II_RESERVE);
-	/* Choose any available level */
-	for (; bit < N_INTPEND_BITS; bit++) {
-	    if (!(vecblk->info[bit].ii_flags & II_RESERVE)) {
-		rv = bit;
-		break;
-	    }
-	}
-
-	/* Return -1 if all interrupt levels int this register are taken. */
-	if (bit == N_INTPEND_BITS)
-	    rv = -1;
-
-    } else {
-	/* Reserve a particular level if it's available. */
-	if ((vecblk->info[bit].ii_flags & II_RESERVE) == reserve) {
-	    /* Can't (un)reserve a level that's already (un)reserved. */
-	    rv = -1;
-	} else {
-	    rv = bit;
-	}
-    }
-
-    /* Reserve the level and bump the count. */
-    if (rv != -1) {
-	if (reserve) {
-	    int maxlen = sizeof(vecblk->info[bit].ii_name) - 1;
-	    int namelen;
-	    vecblk->info[bit].ii_flags |= (II_RESERVE | resflags);
-	    vecblk->info[bit].ii_owner_dev = owner_dev;
-	    /* Copy in the name. */
-	    namelen = name ? strlen(name) : 0;
-	    strncpy(vecblk->info[bit].ii_name, name, MIN(namelen, maxlen)); 
-	    vecblk->info[bit].ii_name[maxlen] = '\0';
-	    vecblk->vector_count++;
-	} else {
-	    vecblk->info[bit].ii_flags = 0;	/* Clear all the flags */
-	    vecblk->info[bit].ii_owner_dev = 0;
-	    /* Clear the name. */
-	    vecblk->info[bit].ii_name[0] = '\0';
-	    vecblk->vector_count--;
-	}
-    }
-
-    INTR_UNLOCK(vecblk);
-
-#if defined(DEBUG)
-    if (rv >= 0) {
-	    int namelen = name ? strlen(name) : 0;
-	    /* Gather this device - target cpu mapping information
-	     * in a table which can be used later by the idbg "intrmap"
-	     * command
-	     */
-	    s = mutex_spinlock(&intr_dev_targ_map_lock);
-	    if (intr_dev_targ_map_size < MAX_DEVICES) {
-		    intr_dev_targ_map_t	*p;
-
-		    p 		= &intr_dev_targ_map[intr_dev_targ_map_size];
-		    p->dev  	= owner_dev;
-		    p->cpuid 	= cpu; 
-		    p->cnodeid 	= cputocnode(cpu); 
-		    p->bit 	= ip * N_INTPEND_BITS + rv;
-		    strncpy(p->intr_name,
-			    name,
-			    MIN(MAX_NAME,namelen));
-		    intr_dev_targ_map_size++;
-	    }
-	    mutex_spinunlock(&intr_dev_targ_map_lock,s);
-    }
-#endif /* DEBUG */
-
-    return (((rv == -1) ? rv : (ip * N_INTPEND_BITS) + rv)) ;
-}
-
-
-/*
- * WARNING:  This routine should only be called from within ml/SN.
- *	Reserve an interrupt level.
- */
-int
-intr_reserve_level(cpuid_t cpu, int bit, int resflags, devfs_handle_t owner_dev, char *name)
-{
-	return(do_intr_reserve_level(cpu, bit, resflags, II_RESERVE, owner_dev, name));
-}
-
-
-/*
- * WARNING:  This routine should only be called from within ml/SN.
- *	Unreserve an interrupt level.
- */
-void
-intr_unreserve_level(cpuid_t cpu, int bit)
-{
-	(void)do_intr_reserve_level(cpu, bit, 0, II_UNRESERVE, 0, NULL);
-}
-
-/*
- * Get values that vary depending on which CPU and bit we're operating on
- */
-static hub_intmasks_t *
-intr_get_ptrs(cpuid_t cpu, int bit,
-	      int *new_bit,		/* Bit relative to the register */
-	      hubreg_t **intpend_masks, /* Masks for this register */
-	      intr_vecblk_t **vecblk,	/* Vecblock for this interrupt */
-	      int *ip)			/* Which intpend register */
-{
-	hub_intmasks_t *hub_intmasks;
-	synergy_da_t	*sda;
-	int		which_synergy;
-	cnodeid_t	cnode;
-
-	ASSERT(bit < N_INTPEND_BITS * 2);
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	hub_intmasks = &sda->s_intmasks;
-
-	// hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
-
-	if (bit < N_INTPEND_BITS) {
-		*intpend_masks = hub_intmasks->intpend0_masks;
-		*vecblk = hub_intmasks->dispatch0;
-		*ip = 0;
-		*new_bit = bit;
-	} else {
-		*intpend_masks = hub_intmasks->intpend1_masks;
-		*vecblk = hub_intmasks->dispatch1;
-		*ip = 1;
-		*new_bit = bit - N_INTPEND_BITS;
-	}
-
-	return hub_intmasks;
-}
-
-
-/*
- * intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, 
- *		intr_func_t intr_func, void *intr_arg);
- *	This is the lowest-level interface to the interrupt code.  It shouldn't
- *	be called from outside the ml/SN directory.
- *	intr_connect_level hooks up an interrupt to a particular bit in
- *	the INT_PEND0/1 masks.  Returns 0 on success.
- *		cpu is the CPU to which the interrupt will be sent.
- *		bit is the level bit to connect to
- *		intr_swlevel tells which software level to use
- *		intr_func is the interrupt handler
- *		intr_arg is an arbitrary argument interpreted by the handler
- *		intr_prefunc is a prologue function, to be called
- *			with interrupts disabled, to disable
- *			the interrupt at source.  It is called
- *			with the same argument.  Should be NULL for
- *			typical interrupts, which can be masked
- *			by the infrastructure at the level bit.
- *	intr_connect_level returns 0 on success or nonzero on an error
- */
-/* ARGSUSED */
-int
-intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, 
-		intr_func_t intr_func, void *intr_arg,
-		intr_func_t intr_prefunc)
-{
-    intr_vecblk_t	*vecblk;
-    hubreg_t		*intpend_masks;
-    int rv = 0;
-    int ip;
-    unsigned long s;
-
-    ASSERT(bit < N_INTPEND_BITS * 2);
-
-    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
-				 &vecblk, &ip);
-
-    INTR_LOCK(vecblk);
-
-    if ((vecblk->info[bit].ii_flags & II_INUSE) ||
-	(!(vecblk->info[bit].ii_flags & II_RESERVE))) {
-	/* Can't assign to a level that's in use or isn't reserved. */
-	rv = -1;
-    } else {
-	/* Stuff parameters into vector and info */
-	vecblk->vectors[bit].iv_func = intr_func;
-	vecblk->vectors[bit].iv_prefunc = intr_prefunc;
-	vecblk->vectors[bit].iv_arg = intr_arg;
-	vecblk->info[bit].ii_flags |= II_INUSE;
-    }
-
-    /* Now stuff the masks if everything's okay. */
-    if (!rv) {
-	int lslice;
-	volatile hubreg_t *mask_reg;
-	// nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
-	nasid_t nasid = cpuid_to_nasid(cpu);
-	int	subnode = cpuid_to_subnode(cpu);
-
-	/* Make sure it's not already pending when we connect it. */
-	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit + ip * N_INTPEND_BITS);
-
-	intpend_masks[0] |= (1ULL << (uint64_t)bit);
-
-	lslice = cputolocalslice(cpu);
-	vecblk->cpu_count[lslice]++;
-#if SN1
-	/*
-	 * On SN1, there are 8 interrupt mask registers per node:
-	 * 	PI_0 MASK_0 A
-	 * 	PI_0 MASK_1 A
-	 * 	PI_0 MASK_0 B
-	 * 	PI_0 MASK_1 B
-	 * 	PI_1 MASK_0 A
-	 * 	PI_1 MASK_1 A
-	 * 	PI_1 MASK_0 B
-	 * 	PI_1 MASK_1 B
-	 */
-#endif
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, 
-		        PI_INT_MASK0_A + PI_INT_MASK_OFFSET * lslice);
-	} else {
-		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode,
-			PI_INT_MASK1_A + PI_INT_MASK_OFFSET * lslice);
-	}
-
-	HUB_S(mask_reg, intpend_masks[0]);
-    }
-
-    INTR_UNLOCK(vecblk);
-
-    return rv;
-}
-
-
-/*
- * intr_disconnect_level(cpuid_t cpu, int bit)
- *
- *	This is the lowest-level interface to the interrupt code.  It should
- *	not be called from outside the ml/SN directory.
- *	intr_disconnect_level removes a particular bit from an interrupt in
- * 	the INT_PEND0/1 masks.  Returns 0 on success or nonzero on failure.
- */
-int
-intr_disconnect_level(cpuid_t cpu, int bit)
-{
-    intr_vecblk_t	*vecblk;
-    hubreg_t		*intpend_masks;
-    unsigned long s;
-    int rv = 0;
-    int ip;
-
-    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
-				 &vecblk, &ip);
-
-    INTR_LOCK(vecblk);
-
-    if ((vecblk->info[bit].ii_flags & (II_RESERVE | II_INUSE)) !=
-	((II_RESERVE | II_INUSE))) {
-	/* Can't remove a level that's not in use or isn't reserved. */
-	rv = -1;
-    } else {
-	/* Stuff parameters into vector and info */
-	vecblk->vectors[bit].iv_func = (intr_func_t)NULL;
-	vecblk->vectors[bit].iv_prefunc = (intr_func_t)NULL;
-	vecblk->vectors[bit].iv_arg = 0;
-	vecblk->info[bit].ii_flags &= ~II_INUSE;
-#ifdef BASE_ITHRTEAD
-	vecblk->vectors[bit].iv_mustruncpu = -1; /* No mustrun CPU any more. */
-#endif
-    }
-
-    /* Now clear the masks if everything's okay. */
-    if (!rv) {
-	int lslice;
-	volatile hubreg_t *mask_reg;
-
-	intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
-	lslice = cputolocalslice(cpu);
-	vecblk->cpu_count[lslice]--;
-	mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(cpu)), 
-				   cpuid_to_subnode(cpu),
-				   ip == 0 ? PI_INT_MASK0_A : PI_INT_MASK1_A);
-	mask_reg = (volatile hubreg_t *)((__psunsigned_t)mask_reg +
-					(PI_INT_MASK_OFFSET * lslice));
-	*mask_reg = intpend_masks[0];
-    }
-
-    INTR_UNLOCK(vecblk);
-
-    return rv;
-}
-
-/*
- * Actually block or unblock an interrupt
- */
-void
-do_intr_block_bit(cpuid_t cpu, int bit, int block)
-{
-	intr_vecblk_t *vecblk;
-	int ip;
-	unsigned long s;
-	hubreg_t *intpend_masks;
-	volatile hubreg_t mask_value;
-	volatile hubreg_t *mask_reg;
-
-	intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &vecblk, &ip);
-
-	INTR_LOCK(vecblk);
-
-	if (block)
-		/* Block */
-		intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
-	else
-		/* Unblock */
-		intpend_masks[0] |= (1ULL << (uint64_t)bit);
-
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(cpu)), 
-		        cpuid_to_subnode(cpu), PI_INT_MASK0_A);
-	} else {
-		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(cpu)), 
-			cpuid_to_subnode(cpu), PI_INT_MASK1_A);
-	}
-
-	HUB_S(mask_reg, intpend_masks[0]);
-
-	/*
-	 * Wait for it to take effect.  (One read should suffice.)
-	 * This is only necessary when blocking an interrupt
-	 */
-	if (block)
-		while ((mask_value = HUB_L(mask_reg)) != intpend_masks[0])
-			;
-
-	INTR_UNLOCK(vecblk);
-}
-
-
-/*
- * Block a particular interrupt (cpu/bit pair).
- */
-/* ARGSUSED */
-void
-intr_block_bit(cpuid_t cpu, int bit)
-{
-	do_intr_block_bit(cpu, bit, 1);
-}
-
-
-/*
- * Unblock a particular interrupt (cpu/bit pair).
- */
-/* ARGSUSED */
-void
-intr_unblock_bit(cpuid_t cpu, int bit)
-{
-	do_intr_block_bit(cpu, bit, 0);
-}
-
-
-/* verifies that the specified CPUID is on the specified SUBNODE (if any) */
-#define cpu_on_subnode(cpuid, which_subnode) \
-	   (((which_subnode) == SUBNODE_ANY) || (cpuid_to_subnode(cpuid) == (which_subnode)))
-
-
-/*
- * Choose one of the CPUs on a specified node or subnode to receive
- * interrupts. Don't pick a cpu which has been specified as a NOINTR cpu.
- *
- * Among all acceptable CPUs, the CPU that has the fewest total number
- * of interrupts targetted towards it is chosen.  Note that we never
- * consider how frequent each of these interrupts might occur, so a rare
- * hardware error interrupt is weighted equally with a disk interrupt.
- */
-static cpuid_t
-do_intr_cpu_choose(cnodeid_t cnode, int which_subnode)
-{
-	cpuid_t 	cpu, best_cpu = CPU_NONE;
-	int		slice, min_count=1000;
-
-	min_count = 1000;
-	for (slice=0; slice < CPUS_PER_NODE; slice++) {
-		intr_vecblk_t 	*vecblk0, *vecblk1;
-		int total_intrs_to_slice;
-		subnode_pda_t *snpda;
-		int local_cpu_num;
-
-		cpu = cnode_slice_to_cpuid(cnode, slice);
-		if (cpu == CPU_NONE)
-			continue;
-
-		/* If this cpu isn't enabled for interrupts, skip it */
-		if (!cpu_enabled(cpu) || !cpu_allows_intr(cpu))
-			continue;
-
-		/* If this isn't the right subnode, skip it */
-		if (!cpu_on_subnode(cpu, which_subnode))
-			continue;
-
-		/* OK, this one's a potential CPU for interrupts */
-		snpda = SUBNODEPDA(cnode,SUBNODE(slice));
-		vecblk0 = &snpda->intr_dispatch0;
-		vecblk1 = &snpda->intr_dispatch1;
-		local_cpu_num = LOCALCPU(slice);
-		total_intrs_to_slice = vecblk0->cpu_count[local_cpu_num] +
-		              vecblk1->cpu_count[local_cpu_num];
-
-		if (min_count > total_intrs_to_slice) {
-			min_count = total_intrs_to_slice;
-			best_cpu = cpu;
-		}
-	}
-	return best_cpu;
-}
-
-/*
- * Choose an appropriate interrupt target CPU on a specified node.
- * If which_subnode is SUBNODE_ANY, then subnode is not considered.
- * Otherwise, the chosen CPU must be on the specified subnode.
- */
-static cpuid_t
-intr_cpu_choose_from_node(cnodeid_t cnode, int which_subnode)
-{
-	return(do_intr_cpu_choose(cnode, which_subnode));
-}
-
-
-#ifdef	LATER
-/*
- * Convert a subnode vertex into a (cnodeid, which_subnode) pair.
- * Return 0 on success, non-zero on failure.
- */
-static int
-subnodevertex_to_subnode(devfs_handle_t vhdl, cnodeid_t *cnodeidp, int *which_subnodep)
-{
-	arbitrary_info_t which_subnode;
-	cnodeid_t cnodeid;
-
-	/* Try to grab subnode information */
-	if (hwgraph_info_get_LBL(vhdl, INFO_LBL_CPUBUS, &which_subnode) != GRAPH_SUCCESS)
-		return(-1);
-
-	/* On which node? */
-	cnodeid = master_node_get(vhdl);
-	if (cnodeid == CNODEID_NONE)
-		return(-1);
-
-	*which_subnodep = (int)which_subnode;
-	*cnodeidp = cnodeid;
-	return(0); /* success */
-}
-
-#endif /* LATER */
-
-/* Make it easy to identify subnode vertices in the hwgraph */
-void
-mark_subnodevertex_as_subnode(devfs_handle_t vhdl, int which_subnode)
-{
-	graph_error_t rv;
-
-	ASSERT(0 <= which_subnode);
-	ASSERT(which_subnode < NUM_SUBNODES);
-
-	rv = hwgraph_info_add_LBL(vhdl, INFO_LBL_CPUBUS, (arbitrary_info_t)which_subnode);
-	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
-
-	rv = hwgraph_info_export_LBL(vhdl, INFO_LBL_CPUBUS, sizeof(arbitrary_info_t));
-	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
-}
-
-
-/*
- * Given a device descriptor, extract interrupt target information and
- * choose an appropriate CPU.  Return CPU_NONE if we can't make sense
- * out of the target information.
- * TBD: Should this be considered platform-independent code?
- */
-
-#ifdef	LATER
-static cpuid_t
-intr_target_from_desc(device_desc_t dev_desc, int favor_subnode)
-{
-	cpuid_t cpuid = CPU_NONE;
-	cnodeid_t cnodeid;
-	int which_subnode;
-	devfs_handle_t intr_target_dev;
-
-	if ((intr_target_dev = device_desc_intr_target_get(dev_desc)) != GRAPH_VERTEX_NONE) {
-		/* 
-		 * A valid device was specified.  If it's a particular
-		 * CPU, then use that CPU as target.  
-		 */
-		cpuid = cpuvertex_to_cpuid(intr_target_dev);
-		if (cpuid != CPU_NONE)
-			goto cpuchosen;
-
-		/* If a subnode vertex was specified, pick a CPU on that subnode. */
-		if (subnodevertex_to_subnode(intr_target_dev, &cnodeid, &which_subnode) == 0) {
-			cpuid = intr_cpu_choose_from_node(cnodeid, which_subnode);
-			goto cpuchosen;
-		}
-
-		/*
-		 * Otherwise, pick a CPU on the node that owns the 
-		 * specified target.  Favor "favor_subnode", if specified.
-		 */
-		cnodeid = master_node_get(intr_target_dev);
-		if (cnodeid != CNODEID_NONE) {
-			cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode);
-			goto cpuchosen;
-		}
-	}
-
-cpuchosen:
-	return(cpuid);
-}
-#endif	/* LATER */
-
-
-#ifdef	LATER
-/*
- * Check if we had already visited this candidate cnode
- */
-static void *
-intr_cnode_seen(cnodeid_t 	candidate,
-		void 		*arg1,
-		void 		*arg2)
-{
-	int		i;
-	cnodeid_t	*visited_cnodes = (cnodeid_t *)arg1;
-	int		*num_visited_cnodes = (int *)arg2;
-
-	ASSERT(visited_cnodes);
-	ASSERT(*num_visited_cnodes <= numnodes);
-	for(i = 0 ; i < *num_visited_cnodes; i++) {
-		if (candidate == visited_cnodes[i])
-			return(NULL);
-	}
-	return(visited_cnodes);
-}
-
-#endif /* LATER */
-
-
-
-/*
- * intr_bit_reserve_test(cpuid,which_subnode,cnode,req_bit,intr_resflags,
- *		owner_dev,intr_name,*resp_bit)
- *	Either cpuid is not CPU_NONE or cnodeid not CNODE_NONE but
- * 	not both.
- * 1. 	If cpuid is specified, this routine tests if this cpu can be a valid
- * 	interrupt target candidate.
- * 2. 	If cnodeid is specified, this routine tests if there is a cpu on 
- *	this node which can be a valid interrupt target candidate.
- * 3.	If a valid interrupt target cpu candidate is found then an attempt at 
- * 	reserving an interrupt bit on the corresponding cnode is made.
- *
- * If steps 1 & 2 both fail or step 3 fails then we are not able to get a valid
- * interrupt target cpu then routine returns CPU_NONE (failure)
- * Otherwise routine returns cpuid of interrupt target (success)
- */
-static cpuid_t
-intr_bit_reserve_test(cpuid_t 		cpuid,
-		      int		favor_subnode,
-		      cnodeid_t 	cnodeid,
-		      int		req_bit,
-		      int 		intr_resflags,
-		      devfs_handle_t 	owner_dev,
-		      char		*intr_name,
-		      int		*resp_bit)
-{
-
-	ASSERT((cpuid==CPU_NONE) || (cnodeid==CNODEID_NONE));
-
-	if (cnodeid != CNODEID_NONE) {
-		/* Try to choose a interrupt cpu candidate */
-		cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode);
-	}
-
-	if (cpuid != CPU_NONE) {
-		/* Try to reserve an interrupt bit on the hub 
-		 * corresponding to the canidate cnode. If we
-		 * are successful then we got a cpu which can
-		 * act as an interrupt target for the io device.
-		 * Otherwise we need to continue the search
-		 * further.
-		 */
-		*resp_bit = do_intr_reserve_level(cpuid, 
-						  req_bit,
-						  intr_resflags,
-						  II_RESERVE,
-						  owner_dev, 
-						  intr_name);
-
-		if (*resp_bit >= 0)
-			/* The interrupt target  specified was fine */
-			return(cpuid);
-	}
-	return(CPU_NONE);
-}
-/*
- * intr_heuristic(dev_t dev,device_desc_t dev_desc,
- *		  int req_bit,int intr_resflags,dev_t owner_dev,
- *		  char *intr_name,int *resp_bit)
- *
- * Choose an interrupt destination for an interrupt.
- *	dev is the device for which the interrupt is being set up
- *	dev_desc is a description of hardware and policy that could
- *		help determine where this interrupt should go
- *	req_bit is the interrupt bit requested 
- *		(can be INTRCONNECT_ANY_BIT in which the first available
- * 		 interrupt bit is used)
- *	intr_resflags indicates whether we want to (un)reserve bit
- *	owner_dev is the owner device
- *	intr_name is the readable interrupt name	
- * 	resp_bit indicates whether we succeeded in getting the required
- *		 action  { (un)reservation} done	
- *		 negative value indicates failure
- *
- */
-/* ARGSUSED */
-cpuid_t
-intr_heuristic(devfs_handle_t 		dev,
-	       device_desc_t 	dev_desc,
-	       int		req_bit,
-	       int 		intr_resflags,
-	       devfs_handle_t 		owner_dev,
-	       char		*intr_name,
-	       int		*resp_bit)
-{
-	cpuid_t		cpuid;				/* possible intr targ*/
-	cnodeid_t 	candidate;			/* possible canidate */
-#ifdef LATER
-	cnodeid_t	visited_cnodes[MAX_NASIDS], 	/* nodes seen so far */
-		        center,				/* node we are on */
-		        candidate;			/* possible canidate */
-	int		num_visited_cnodes = 0;		/* # nodes seen */
-
-	int		radius = 1,			/* start looking at the
-							 * current node
-							 */
-		        maxradius = physmem_maxradius();
-	void		*rv;
-#endif /* LATER */
-	int		which_subnode = SUBNODE_ANY;
-
-/* SN1 + pcibr Addressing Limitation */
-	{
-	devfs_handle_t pconn_vhdl;
-	pcibr_soft_t pcibr_soft;
-
-	/*
-	 * This combination of SN1 and Bridge hardware has an odd "limitation".
-	 * Due to the choice of addresses for PI0 and PI1 registers on SN1
-	 * and historical limitations in Bridge, Bridge is unable to
-	 * send interrupts to both PI0 CPUs and PI1 CPUs -- we have
-	 * to choose one set or the other.  That choice is implicitly
-	 * made when Bridge first attaches its error interrupt.  After
-	 * that point, all subsequent interrupts are restricted to the
-	 * same PI number (though it's possible to send interrupts to
-	 * the same PI number on a different node).
-	 *
-	 * Since neither SN1 nor Bridge designers are willing to admit a
-	 * bug, we can't really call this a "workaround".  It's a permanent
-	 * solution for an SN1-specific and Bridge-specific hardware
-	 * limitation that won't ever be lifted.
-	 */
-        if ((hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
-	   ((pcibr_soft = pcibr_soft_get(pconn_vhdl)) != NULL)) {
-		/*
-		 * We "know" that the error interrupt is the first
-		 * interrupt set up by pcibr_attach.  Send all interrupts
-		 * on this bridge to the same subnode number.
-		 */
-		if (pcibr_soft->bsi_err_intr) {
-			which_subnode = cpuid_to_subnode(((hub_intr_t) pcibr_soft->bsi_err_intr)->i_cpuid);
-		}
-	}
-	}
-
-#ifdef	LATER
-	/* 
-	 * If an interrupt target was specified for this
-	 * interrupt allocation, try to use it.
-	 */
-	if (dev_desc) {
-
-		/* Try to see if the interrupt target specified in the
-		 * device descriptor is a legal candidate.
-		 */
-		cpuid = intr_bit_reserve_test(intr_target_from_desc(dev_desc, which_subnode),
-					      which_subnode,
-					      CNODEID_NONE,
-					      req_bit,
-					      intr_resflags,
-					      owner_dev,
-					      intr_name,
-					      resp_bit);
-
-		if (cpuid != CPU_NONE) {
-			if (cpu_on_subnode(cpuid, which_subnode))
-				return(cpuid);	/* got a valid interrupt target */
-
-			printk("Override explicit interrupt targetting: %v (0x%x)\n",
-				owner_dev, owner_dev);
-
-			intr_unreserve_level(cpuid, *resp_bit);
-		}
-
-		/* Fall through on to the next step in the search for
-		 * the interrupt candidate.
-		 */
-
-	}
-#endif  /* LATER */
-	
-	/* Check if we can find a valid interrupt target candidate on
-	 * the master node for the device.
-	 */
-	cpuid = intr_bit_reserve_test(CPU_NONE,
-				      which_subnode,	
-				      master_node_get(dev),
-				      req_bit,
-				      intr_resflags,
-				      owner_dev,
-				      intr_name,
-				      resp_bit);
-
-	if (cpuid != CPU_NONE) {
-		if (cpu_on_subnode(cpuid, which_subnode))
-			return(cpuid);	/* got a valid interrupt target */
-		else
-			intr_unreserve_level(cpuid, *resp_bit);
-	}
-
-	PRINT_WARNING("Cannot target interrupts to closest node(%d): %ld (0x%lx)\n",
-		master_node_get(dev),(long) owner_dev, (unsigned long)owner_dev);
-
-	/* Fall through into the default algorithm
-	 * (exhaustive-search-for-the-nearest-possible-interrupt-target)
-	 * for finding the interrupt target
-	 */
-
-#ifndef BRINGUP
-	// Use of this algorithm is deferred until the supporting
-	// code has been implemented.
-	/* 
-	 * No valid interrupt specification exists.
-	 * Try to find a node which is closest to the current node
-	 * which can process interrupts from a device
-	 */
-
-	center = cpuid_to_cnodeid(smp_processor_id());
-	while (radius <= maxradius) {
-
-		/* Try to find a node at the given radius and which
-		 * we haven't seen already.
-		 */
-		rv = physmem_select_neighbor_node(center,radius,&candidate,
-						  intr_cnode_seen,
-						  (void *)visited_cnodes,
-						  (void *)&num_visited_cnodes);
-		if (!rv) {
-			/* We have seen all the nodes at this particular radius
-			 * Go on to the next radius level.
-			 */
-			radius++;
-			continue;
-		}			      
-		/* We are seeing this candidate  cnode for the first time
-		 */
-		visited_cnodes[num_visited_cnodes++] = candidate;
-
-		cpuid = intr_bit_reserve_test(CPU_NONE,
-					      which_subnode,
-					      candidate,
-					      req_bit,
-					      intr_resflags,
-					      owner_dev,
-					      intr_name,
-					      resp_bit);
-
-		if (cpuid != CPU_NONE) {
-			if (cpu_on_subnode(cpuid, which_subnode))
-				return(cpuid);	/* got a valid interrupt target */
-			else
-				intr_unreserve_level(cpuid, *resp_bit);
-		}
-	}
-#else  /* BRINGUP */
-	{
-	// Do a stupid round-robin assignment of the node.
-		static cnodeid_t last_node = -1;
-
-		if (last_node >= numnodes) last_node = 0;
-		for (candidate = last_node + 1; candidate != last_node; candidate++) {
-			if (candidate == numnodes) candidate = 0;
-			cpuid = intr_bit_reserve_test(CPU_NONE,
-					      which_subnode,
-					      candidate,
-					      req_bit,
-					      intr_resflags,
-					      owner_dev,
-					      intr_name,
-					      resp_bit);
-
-			if (cpuid != CPU_NONE) {
-				if (cpu_on_subnode(cpuid, which_subnode)) {
-					last_node = candidate;
-					return(cpuid);	/* got a valid interrupt target */
-				}
-				else
-					intr_unreserve_level(cpuid, *resp_bit);
-			}
-		}
-		last_node = candidate;
-	}
-#endif
-
-	PRINT_WARNING("Cannot target interrupts to any close node: %ld (0x%lx)\n",
-		(long)owner_dev, (unsigned long)owner_dev);
-
-	/* In the worst case try to allocate interrupt bits on the
-	 * master processor's node. We may get here during error interrupt
-	 * allocation phase when the topology matrix is not yet setup
-	 * and hence cannot do an exhaustive search.
-	 */
-	ASSERT(cpu_allows_intr(master_procid));
-	cpuid = intr_bit_reserve_test(master_procid,
-				      which_subnode,
-				      CNODEID_NONE,
-				      req_bit,
-				      intr_resflags,
-				      owner_dev,
-				      intr_name,
-				      resp_bit);
-
-	if (cpuid != CPU_NONE) {
-		if (cpu_on_subnode(cpuid, which_subnode))
-			return(cpuid);
-		else
-			intr_unreserve_level(cpuid, *resp_bit);
-	}
-
-	PRINT_WARNING("Cannot target interrupts: %ld (0x%lx)\n",
-		(long)owner_dev, (unsigned long)owner_dev);
-
-	return(CPU_NONE);	/* Should never get here */
-}
-
-
-
-
-#ifndef BRINGUP
-/*
- * Should never receive an exception while running on the idle 
- * stack.  It IS possible to handle *interrupts* while on the
- * idle stack, but a non-interrupt *exception* is a problem.
- */
-void
-idle_err(inst_t *epc, uint cause, void *fep, void *sp)
-{
-	eframe_t *ep = (eframe_t *)fep;
-
-    if ((cause & CAUSE_EXCMASK) == EXC_IBE ||
-	(cause & CAUSE_EXCMASK) == EXC_DBE) {
-	(void)dobuserre((eframe_t *)ep, epc, 0);
-    }
-
-    /* XXX - This will have to change to deal with various SN errors. */
-    panic( "exception on IDLE stack "
-	    "ep:0x%x epc:0x%x cause:0x%w32x sp:0x%x badvaddr:0x%x",
-	    ep, epc, cause, sp, getbadvaddr());
-    /* NOTREACHED */
-}
-
-
-/*
- * earlynofault - handle very early global faults - usually just while
- *      sizing memory
- * Returns: 1 if should do nofault
- *          0 if not
- */
-/* ARGSUSED */
-int
-earlynofault(eframe_t *ep, uint code)
-{
-	switch(code) {
-	case EXC_DBE:
-		return(1);
-	default:
-		return(0);
-	}
-}
-
-
-
-/* ARGSUSED */
-static void
-cpuintr(void *arg1, void *arg2)
-{
-#if RTE
-	static int rte_intrdebug = 1;
-#endif
-	/*
-	 * Frame Scheduler
-	 */
-	LOG_TSTAMP_EVENT(RTMON_INTR, TSTAMP_EV_CPUINTR, NULL, NULL,
-			 NULL, NULL);
-
-	/*
-	 * Hardware clears the IO interrupts, but we need to clear software-
-	 * generated interrupts.
-	 */
-	LOCAL_HUB_CLR_INTR(CPU_ACTION_A + cputolocalslice(cpuid()));
-
-#if 0
-	/* XXX - Handle error interrupts. */
-	if (error_intr_reason)
-		error_intr();
-#endif /* 0 */
-
-	/*
-	 * If we're headed for panicspin and it is due to a NMI, save the
-	 * eframe in the NMI area
-	 */
-	if (private.p_va_panicspin && nmied) {
-		caddr_t	nmi_save_area;
-
-		nmi_save_area = (caddr_t) (TO_UNCAC(TO_NODE(
-			cputonasid(cpuid()), IP27_NMI_EFRAME_OFFSET)) + 
-			cputoslice(cpuid()) * IP27_NMI_EFRAME_SIZE);
-		bcopy((caddr_t) arg2, nmi_save_area, sizeof(eframe_t));
-	}
-
-	doacvec();
-#if RTE
-	if (private.p_flags & PDAF_ISOLATED && !rte_intrdebug)
-		goto end_cpuintr;
-#endif
-	doactions();
-#if RTE
-end_cpuintr:
-#endif
-	LOG_TSTAMP_EVENT(RTMON_INTR, TSTAMP_EV_INTREXIT, TSTAMP_EV_CPUINTR, NULL, NULL, NULL);
-}
-
-void
-install_cpuintr(cpuid_t cpu)
-{
-	int		intr_bit = CPU_ACTION_A + cputolocalslice(cpu);
-
-	if (intr_connect_level(cpu, intr_bit, INTPEND0_MAXMASK,
-				(intr_func_t) cpuintr, NULL, NULL))
-		panic("install_cpuintr: Can't connect interrupt.");
-}
-#endif /* BRINGUP */
-
-#ifdef DEBUG_INTR_TSTAMP
-/* We allocate an array, but only use element number 64.  This guarantees that
- * the entry is in a cacheline by itself.
- */
-#define DINTR_CNTIDX	32
-#define DINTR_TSTAMP1	48
-#define	DINTR_TSTAMP2	64
-volatile long long dintr_tstamp_cnt[128];
-int dintr_debug_output=0;
-extern void idbg_tstamp_debug(void);
-#ifdef SPLDEBUG
-extern void idbg_splx_log(int);
-#endif
-#if DEBUG_INTR_TSTAMP_DEBUG
-int dintr_enter_symmon=1000;	/* 1000 microseconds is 1 millisecond */
-#endif
-
-#ifndef BRINGUP
-/* ARGSUSED */
-static void
-cpulatintr(void *arg)
-{
-	/*
-	 * Hardware only clears IO interrupts so we have to clear our level
-	 * here.
-	 */
-	LOCAL_HUB_CLR_INTR(CPU_INTRLAT_A + cputolocalslice(cpuid()));
-
-#if DEBUG_INTR_TSTAMP_DEBUG
-	dintr_tstamp_cnt[DINTR_TSTAMP2] =  GET_LOCAL_RTC;
-	if ((dintr_tstamp_cnt[DINTR_TSTAMP2] - dintr_tstamp_cnt[DINTR_TSTAMP1])
-	    > dintr_enter_symmon) {
-#ifdef SPLDEBUG
-		extern int spldebug_log_off;
-
-		spldebug_log_off = 1;
-#endif /* SPLDEBUG */
-		debug("ring");
-#ifdef SPLDEBUG
-		spldebug_log_off = 0;
-#endif /* SPLDEBUG */
-	}
-#endif
-	dintr_tstamp_cnt[DINTR_CNTIDX]++;
-
-	return;
-}
-
-static int install_cpulat_first=0;
-
-void
-install_cpulatintr(cpuid_t cpu)
-{
-	int		intr_bit;
-	devfs_handle_t	cpuv = cpuid_to_vertex(cpu);
-
-	intr_bit = CPU_INTRLAT_A + cputolocalslice(cpu);
-	if (intr_bit != intr_reserve_level(cpu, intr_bit, II_THREADED,
-					   cpuv, "intrlat"))
-		panic( "install_cpulatintr: Can't reserve interrupt.");
-
-	if (intr_connect_level(cpu, intr_bit, INTPEND0_MAXMASK,
-				cpulatintr, NULL, NULL))
-		panic( "install_cpulatintr: Can't connect interrupt.");
-
-	if (!install_cpulat_first) {
-		install_cpulat_first++;
-		idbg_addfunc("tstamp_debug", (void (*)())idbg_tstamp_debug);
-#if defined(SPLDEBUG) || defined(SPLDEBUG_CPU_EVENTS)
-		idbg_addfunc("splx_log", (void (*)())idbg_splx_log);
-#endif /* SPLDEBUG || SPLDEBUG_CPU_EVENTS */
-	}
-}
-#endif /* BRINGUP */
-
-#endif /* DEBUG_INTR_TSTAMP */
-
-#ifndef BRINGUP
-/* ARGSUSED */
-static void
-dbgintr(void *arg)
-{
-	/*
-	 * Hardware only clears IO interrupts so we have to clear our level
-	 * here.
-	 */
-	LOCAL_HUB_CLR_INTR(N_INTPEND_BITS + DEBUG_INTR_A + cputolocalslice(cpuid()));
-
-	debug("zing");
-	return;
-}
-
-
-void
-install_dbgintr(cpuid_t cpu)
-{
-	int		intr_bit;
-	devfs_handle_t	cpuv = cpuid_to_vertex(cpu);
-
-	intr_bit = N_INTPEND_BITS + DEBUG_INTR_A + cputolocalslice(cpu);
-	if (intr_bit != intr_reserve_level(cpu, intr_bit, 1, cpuv, "DEBUG"))
-		panic("install_dbgintr: Can't reserve interrupt. "
-			" intr_bit %d" ,intr_bit);
-
-	if (intr_connect_level(cpu, intr_bit, INTPEND1_MAXMASK,
-				dbgintr, NULL, NULL))
-		panic("install_dbgintr: Can't connect interrupt.");
-
-#ifdef DEBUG_INTR_TSTAMP
-	/* Set up my interrupt latency test interrupt */
-	install_cpulatintr(cpu);
-#endif
-}
-
-/* ARGSUSED */
-static void
-tlbintr(void *arg)
-{
-	extern void tlbflush_rand(void);
-
-	/*
-	 * Hardware only clears IO interrupts so we have to clear our level
-	 * here.
-	 */
-	LOCAL_HUB_CLR_INTR(N_INTPEND_BITS + TLB_INTR_A + cputolocalslice(cpuid()));
-
-	tlbflush_rand();
-	return;
-}
-
-
-void
-install_tlbintr(cpuid_t cpu)
-{
-	int		intr_bit;
-	devfs_handle_t	cpuv = cpuid_to_vertex(cpu);
-
-	intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputolocalslice(cpu);
-	if (intr_bit != intr_reserve_level(cpu, intr_bit, 1, cpuv, "DEBUG"))
-		panic("install_tlbintr: Can't reserve interrupt. "
-			" intr_bit %d" ,intr_bit);
-
-	if (intr_connect_level(cpu, intr_bit, INTPEND1_MAXMASK,
-				tlbintr, NULL, NULL))
-		panic("install_tlbintr: Can't connect interrupt.");
-
-}
-
-
-/*
- * Send an interrupt to all nodes.  Don't panic if we get an error.
- * Returns 1 if any exceptions occurred.
- */
-int
-protected_broadcast(hubreg_t intrbit)
-{
-	nodepda_t *npdap = private.p_nodepda;
-	int byte, bit, sn;
-	int error = 0;
-
-	extern int _wbadaddr_val(volatile void *, int, volatile int *);
-
-	/* Send rather than clear an interrupt. */
-	intrbit |= 0x100;
-	
-	for (byte = 0; byte < NASID_MASK_BYTES; byte++) {
-		for (bit = 0; bit < 8; bit++) {
-			if (npdap->nasid_mask[byte] & (1 << bit)) {
-				nasid_t nasid = byte * 8 + bit;
-				for (sn=0; sn<NUM_SUBNODES; sn++) {
-					error += _wbadaddr_val(REMOTE_HUB_PI_ADDR(nasid,
-					      sn, PI_INT_PEND_MOD),
-					      sizeof(hubreg_t),
-					      (volatile int *)&intrbit);
-				}
-			}
-		}
-	}
-
-	return error;
-}
-
-
-/*
- * Poll the interrupt register to see if another cpu has asked us
- * to drop into the debugger (without lowering spl).
- */
-void
-chkdebug(void)
-{
-	if (LOCAL_HUB_L(PI_INT_PEND1) & (1L << (DEBUG_INTR_A + cputolocalslice(cpuid()))))
-		dbgintr((void *)NULL);
-}
-
-
-/*
- * Install special graphics interrupt.
- */
-void
-install_gfxintr(cpuid_t cpu, ilvl_t swlevel, intr_func_t intr_func, void *intr_arg)
-{
-	int intr_bit = GFX_INTR_A + cputolocalslice(cpu);
-
-	if (intr_connect_level(cpu, intr_bit, swlevel,
-				intr_func, intr_arg, NULL))
-		panic("install_gfxintr: Can't connect interrupt.");
-}
-
-
-/*
- * Install page migration interrupt handler.
- */
-void
-hub_migrintr_init(cnodeid_t cnode)
-{
-	cpuid_t cpu = cnodetocpu(cnode);
-	int intr_bit = INT_PEND0_BASELVL + PG_MIG_INTR;
-
-	if (numnodes == 1){
-		/* 
-		 * No migration with just one node..
-		 */
-		return;
-	}
-	
-	if (cpu != -1) {
-		if (intr_connect_level(cpu, intr_bit, 0,
-			       (intr_func_t) migr_intr_handler, 0, (intr_func_t) migr_intr_prologue_handler))
-			panic( "hub_migrintr_init: Can't connect interrupt.");
-	}
-}
-
-
-/*
- * Cause all CPUs to stop by sending them each a DEBUG interrupt.
- * Parameter is actually a (cpumask_t *).
- */
-void
-debug_stop_all_cpus(void *stoplist)
-{
-	int cpu;
-	ulong level;
-
-	for (cpu=0; cpu<maxcpus; cpu++) {
-		if (cpu == cpuid())
-			continue;
-		if (!cpu_enabled(cpu))
-		        continue;
-		/* "-1" is the old style parameter OR could be the new style
-		 * if no-one is currently stopped.  We only stop the
-		 * requested cpus, the others are already stopped (probably
-		 * at a breakpoint).
-		 */
-
-		if (((cpumask_t *)stoplist != (cpumask_t *)-1LL) &&
-		    (!CPUMASK_TSTB(*(cpumask_t*)stoplist, cpu)))
-			continue;
-
-		/*
-		 * CPU lslice A gets level DEBUG_INTR_A
-		 * CPU lslice B gets level DEBUG_INTR_B
-		 */
-		level = DEBUG_INTR_A + LOCALCPU(get_cpu_slice(cpu));
-		/*
-		 * Convert the compact hub number to the NASID to get the
-		 * correct part of the address space.  Then set the interrupt
-		 * bit associated with the CPU we want to send the interrupt
-		 * to.
-		 */
-		REMOTE_CPU_SEND_INTR(cpu, N_INTPEND_BITS + level);
-
-	}
-}
-
-#endif /* BRINGUP */
-
-struct hardwired_intr_s {
-	signed char level;
-	int flags;
-	char *name;
-} const hardwired_intr[] = {
-	{ INT_PEND0_BASELVL + RESERVED_INTR,	0,	"Reserved" },
-	{ INT_PEND0_BASELVL + GFX_INTR_A,	0, 	"Gfx A" },
-	{ INT_PEND0_BASELVL + GFX_INTR_B,	0, 	"Gfx B" },
-	{ INT_PEND0_BASELVL + PG_MIG_INTR,	II_THREADED, "Migration" },
-	{ INT_PEND0_BASELVL + UART_INTR,	II_THREADED, "Bedrock/L1" },
-	{ INT_PEND0_BASELVL + CC_PEND_A,	0,	"Crosscall A" },
-	{ INT_PEND0_BASELVL + CC_PEND_B,	0,	"Crosscall B" },
-	{ INT_PEND1_BASELVL + CLK_ERR_INTR,	II_ERRORINT, "Clock Error" },
-	{ INT_PEND1_BASELVL + COR_ERR_INTR_A,	II_ERRORINT, "Correctable Error A" },
-	{ INT_PEND1_BASELVL + COR_ERR_INTR_B,	II_ERRORINT, "Correctable Error B" },
-	{ INT_PEND1_BASELVL + MD_COR_ERR_INTR,	II_ERRORINT, "MD Correct. Error" },
-	{ INT_PEND1_BASELVL + NI_ERROR_INTR,	II_ERRORINT, "NI Error" },
-	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_A,	II_ERRORINT, "Remote NI Error"},
-	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_B,	II_ERRORINT, "Remote NI Error"},
-	{ INT_PEND1_BASELVL + MSC_PANIC_INTR,	II_ERRORINT, "MSC Panic" },
-	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_A,	II_ERRORINT, "LLP Pfail WAR" },
-	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_B,	II_ERRORINT, "LLP Pfail WAR" },
-	{ INT_PEND1_BASELVL + NACK_INT_A,	0, "CPU A Nack count == NACK_CMP" },
-	{ INT_PEND1_BASELVL + NACK_INT_B,	0, "CPU B Nack count == NACK_CMP" },
-	{ INT_PEND1_BASELVL + LB_ERROR,		0, "Local Block Error" },
-	{ INT_PEND1_BASELVL + XB_ERROR,		0, "Local XBar Error" },
-	{ -1, 0, (char *)NULL},
-};
-
-/*
- * Reserve all of the hardwired interrupt levels so they're not used as
- * general purpose bits later.
- */
-void
-intr_reserve_hardwired(cnodeid_t cnode)
-{
-	cpuid_t cpu;
-	int level;
-	int i;
-	char subnode_done[NUM_SUBNODES];
-
-	// cpu = cnodetocpu(cnode);
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		if (cpuid_to_cnodeid(cpu) == cnode) {
-			break;
-		}
-	}
-	if (cpu == smp_num_cpus) cpu = CPU_NONE;
-	if (cpu == CPU_NONE) {
-		printk("Node %d has no CPUs", cnode);
-		return;
-	}
-
-	for (i=0; i<NUM_SUBNODES; i++)
-		subnode_done[i] = 0;
-
-	for (; cpu<smp_num_cpus && cpu_enabled(cpu) && cpuid_to_cnodeid(cpu) == cnode; cpu++) {
-		int which_subnode = cpuid_to_subnode(cpu);
-		if (subnode_done[which_subnode])
-			continue;
-		subnode_done[which_subnode] = 1;
-
-		for (i = 0; hardwired_intr[i].level != -1; i++) {
-			level = hardwired_intr[i].level;
-
-			if (level != intr_reserve_level(cpu, level,
-						hardwired_intr[i].flags,
-						(devfs_handle_t) NULL,
-						hardwired_intr[i].name))
-				panic("intr_reserve_hardwired: Can't reserve level %d.", level);
-		}
-	}
-}
-
-
-/*
- * Check and clear interrupts.
- */
-/*ARGSUSED*/
-static void
-intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level,
-		char *name)
-{
-	volatile hubreg_t bits;
-	int i;
-
-	/* Check pending interrupts */
-	if ((bits = HUB_L(pend)) != 0) {
-		for (i = 0; i < N_INTPEND_BITS; i++) {
-			if (bits & (1 << i)) {
-#ifdef INTRDEBUG
-				PRINT_WARNING("Nasid %d interrupt bit %d set in %s",
-					nasid, i, name);
-#endif
-				LOCAL_HUB_CLR_INTR(base_level + i);
-			}
-		}
-	}
-}
-
-/*
- * Clear out our interrupt registers.
- */
-void
-intr_clear_all(nasid_t nasid)
-{
-	int	sn;
-
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_A, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_B, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_A, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_B, 0);
-	
-		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND0),
-				INT_PEND0_BASELVL, "INT_PEND0");
-		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND1),
-				INT_PEND1_BASELVL, "INT_PEND1");
-	}
-}
-
-/* 
- * Dump information about a particular interrupt vector.
- */
-static void
-dump_vector(intr_info_t *info, intr_vector_t *vector, int bit, hubreg_t ip,
-		hubreg_t ima, hubreg_t imb, void (*pf)(char *, ...))
-{
-	hubreg_t value = 1LL << bit;
-
-	pf("  Bit %02d: %s: func 0x%x arg 0x%x prefunc 0x%x\n",
-		bit, info->ii_name,
-		vector->iv_func, vector->iv_arg, vector->iv_prefunc);
-	pf("   vertex 0x%x %s%s",
-		info->ii_owner_dev,
-		((info->ii_flags) & II_RESERVE) ? "R" : "U",
-		((info->ii_flags) & II_INUSE) ? "C" : "-");
-	pf("%s%s%s%s",
-		ip & value ? "P" : "-",
-		ima & value ? "A" : "-",
-		imb & value ? "B" : "-",
-		((info->ii_flags) & II_ERRORINT) ? "E" : "-");
-	pf("\n");
-}
-
-
-/*
- * Dump information about interrupt vector assignment.
- */
-void
-intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...))
-{
-	nodepda_t *npda;
-	int ip, sn, bit;
-	intr_vecblk_t *dispatch;
-	hubreg_t ipr, ima, imb;
-	nasid_t nasid;
-
-	if ((cnode < 0) || (cnode >= numnodes)) {
-		pf("intr_dumpvec: cnodeid out of range: %d\n", cnode);
-		return ;
-	}
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	if (nasid == INVALID_NASID) {
-		pf("intr_dumpvec: Bad cnodeid: %d\n", cnode);
-		return ;
-	}
-		
-
-	npda = NODEPDA(cnode);
-
-	for (sn = 0; sn < NUM_SUBNODES; sn++) {
-		for (ip = 0; ip < 2; ip++) {
-			dispatch = ip ? &(SNPDA(npda,sn)->intr_dispatch1) : &(SNPDA(npda,sn)->intr_dispatch0);
-			ipr = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_PEND1 : PI_INT_PEND0);
-			ima = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_A : PI_INT_MASK0_A);
-			imb = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_B : PI_INT_MASK0_B);
-	
-			pf("Node %d INT_PEND%d:\n", cnode, ip);
-	
-			if (dispatch->ithreads_enabled)
-				pf(" Ithreads enabled\n");
-			else
-				pf(" Ithreads disabled\n");
-			pf(" vector_count = %d, vector_state = %d\n",
-				dispatch->vector_count,
-				dispatch->vector_state);
-			pf(" CPU A count %d, CPU B count %d\n",
- 		   	dispatch->cpu_count[0],
- 		   	dispatch->cpu_count[1]);
-			pf(" &vector_lock = 0x%x\n",
-				&(dispatch->vector_lock));
-			for (bit = 0; bit < N_INTPEND_BITS; bit++) {
-				if ((dispatch->info[bit].ii_flags & II_RESERVE) ||
-			    	(ipr & (1L << bit))) {
-					dump_vector(&(dispatch->info[bit]),
-					    	&(dispatch->vectors[bit]),
-					    	bit, ipr, ima, imb, pf);
-				}
-			}
-			pf("\n");
-		}
-	}
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/ml_iograph.c linux/arch/ia64/sn/io/ml_iograph.c
--- linux.orig/arch/ia64/sn/io/ml_iograph.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/ml_iograph.c	2002-07-20 01:08:27.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -13,6 +12,9 @@
 #include <linux/slab.h>
 #include <linux/ctype.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
@@ -30,8 +32,6 @@
 #include <asm/sn/xtalk/xtalk_private.h>
 #include <asm/sn/xtalk/xtalkaddrs.h>
 
-extern int maxnodes;
-
 /* #define IOGRAPH_DEBUG */
 #ifdef IOGRAPH_DEBUG
 #define DBG(x...) printk(x)
@@ -107,10 +107,10 @@
 #ifdef LATER
 	    if (!is_headless_node_vertex(master)) {
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		PRINT_WARNING("volunteer for widgets: vertex %v has no info label",
+		printk(KERN_WARNING  "volunteer for widgets: vertex %v has no info label",
 			xswitch);
 #else
-		PRINT_WARNING("volunteer for widgets: vertex 0x%x has no info label",
+		printk(KERN_WARNING  "volunteer for widgets: vertex 0x%x has no info label",
 			xswitch);
 #endif
 	    }
@@ -155,11 +155,11 @@
 #ifdef LATER
 	    if (!is_headless_node_vertex(hubv)) {
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		PRINT_WARNING("assign_widgets_to_volunteers:vertex %v has "
+		printk(KERN_WARNING  "assign_widgets_to_volunteers:vertex %v has "
 			" no info label",
 			xswitch);
 #else
-		PRINT_WARNING("assign_widgets_to_volunteers:vertex 0x%x has "
+		printk(KERN_WARNING  "assign_widgets_to_volunteers:vertex 0x%x has "
 			" no info label",
 			xswitch);
 #endif
@@ -184,9 +184,6 @@
 	 */
 	for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
 
-#ifndef BRINGUP
-		int i;
-#endif
 		/*
 		 * Ignore disabled/empty ports.
 		 */
@@ -244,7 +241,7 @@
 	cnodeid_t cnode;
 	nasid_t nasid;
 	lboard_t *board;
-
+	
 	/*
 	 * Init. the board-to-hwgraph link early, so FRU analyzer
 	 * doesn't trip on leftover values if we panic early on.
@@ -267,55 +264,6 @@
 	hubio_init();
 }
 
-#ifdef LATER
-/* There is an identical definition of this in os/scheduler/runq.c */
-#define INIT_COOKIE(cookie) cookie.must_run = 0; cookie.cpu = PDA_RUNANYWHERE
-/*
- * These functions absolutely doesn't belong here.  It's  here, though, 
- * until the scheduler provides a platform-independent version
- * that works the way it should.  The interface will definitely change, 
- * too.  Currently used only in this file and by io/cdl.c in order to
- * bind various I/O threads to a CPU on the proper node.
- */
-cpu_cookie_t
-setnoderun(cnodeid_t cnodeid)
-{
-	int i;
-	cpuid_t cpunum;
-	cpu_cookie_t cookie;
-
-	INIT_COOKIE(cookie);
-	if (cnodeid == CNODEID_NONE)
-		return(cookie);
-
-	/*
-	 * Do a setmustrun to one of the CPUs on the specified
-	 * node.
-	 */
-	if ((cpunum = CNODE_TO_CPU_BASE(cnodeid)) == CPU_NONE) {
-		return(cookie);
-	}
-
-	cpunum += CNODE_NUM_CPUS(cnodeid) - 1;
-
-	for (i = 0; i < CNODE_NUM_CPUS(cnodeid); i++, cpunum--) {
-
-		if (cpu_enabled(cpunum)) {
-			cookie = setmustrun(cpunum);
-			break;
-		}
-	}
-
-	return(cookie);
-}
-
-void
-restorenoderun(cpu_cookie_t cookie)
-{
-	restoremustrun(cookie);
-}
-#endif	/* LATER */
-
 #ifdef LINUX_KERNEL_THREADS
 static struct semaphore io_init_sema;
 #endif
@@ -445,6 +393,7 @@
 	slotid_t		slot;
 	lboard_t		*board = NULL;
 	char			buffer[16];
+	slotid_t get_widget_slotnum(int xbow, int widget);
 	
 	DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);
 	/*
@@ -507,6 +456,7 @@
 {
 		lboard_t dummy;
 
+
 			if (board) {
 				DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type);
 			} else {
@@ -517,7 +467,6 @@
 }
 
 			/*
-			 * BRINGUP
 	 		 * Make sure we really want to say xbrick, pbrick,
 			 * etc. rather than XIO, graphics, etc.
 	 		 */
@@ -534,14 +483,10 @@
 				"%cbrick" "/%s/%d",
 				buffer,
 #endif
-#ifdef BRINGUP
 
 				(board->brd_type == KLTYPE_IBRICK) ? 'I' :
 				(board->brd_type == KLTYPE_PBRICK) ? 'P' :
 				(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
-#else
-				toupper(MODULE_GET_BTCHAR(NODEPDA(cnode)->module_id)),
-#endif /* BRINGUP */
 				EDGE_LBL_XTALK, widgetnum);
 		} 
 		
@@ -563,11 +508,7 @@
 		 */
 		if (is_master_baseio(nasid,
 				     NODEPDA(cnode)->module_id,
-#ifdef BRINGUP
  				     get_widget_slotnum(0,widgetnum))) {
-#else
-	<<< BOMB! >>> Need a new way to get slot numbers on IP35/IP37
-#endif
 			extern void klhwg_baseio_inventory_add(devfs_handle_t,
 							       cnodeid_t);
 			module 	= NODEPDA(cnode)->module_id;
@@ -582,7 +523,6 @@
 					(lboard_t *)KL_CONFIG_INFO(nasid),
 					module);
 				/*
-			 	 * BRINGUP
 				 * Change iobrick to correct i/o brick
 				 */
 #ifdef SUPPORT_PRINTING_M_FORMAT
@@ -594,11 +534,7 @@
 					NODEPDA(cnode)->module_id,
 					EDGE_LBL_XTALK, widgetnum);
 			} else {
-#ifdef BRINGUP
 				slot = get_widget_slotnum(0, widgetnum);
-#else
-	<<< BOMB! Need a new way to get slot numbers on IP35/IP37
-#endif
 				board = get_board_name(nasid, module, slot,
 								new_name);
 				/*
@@ -729,41 +665,25 @@
 		    GRAPH_SUCCESS)
 			continue;
 
-#if defined (CONFIG_SGI_IP35) || defined (CONFIG_IA64_SGI_SN1) || defined (CONFIG_IA64_GENERIC)
 		board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid),
 				NODEPDA(cnodeid)->module_id);
-#else
-		{
-		slotid_t	slot;
-		slot = get_widget_slotnum(xbow_num, widgetnum);
-		board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				    NODEPDA(cnodeid)->module_id, slot);
-		}
-#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
 		if (board == NULL && peer_nasid != INVALID_NASID) {
 			/*
 			 * Try to find the board on our peer
 			 */
-#if defined (CONFIG_SGI_IP35) || defined (CONFIG_IA64_SGI_SN1) || defined (CONFIG_IA64_GENERIC)
 			board = find_lboard_module(
 				(lboard_t *)KL_CONFIG_INFO(peer_nasid),
 				NODEPDA(cnodeid)->module_id);
-
-#else
-			board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(peer_nasid),
-						    NODEPDA(cnodeid)->module_id, slot);
-
-#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
 		}
 		if (board == NULL) {
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-			PRINT_WARNING("Could not find PROM info for vertex %v, "
+			printk(KERN_WARNING  "Could not find PROM info for vertex %v, "
 				"FRU analyzer may fail",
 				vhdl);
 #else
-			PRINT_WARNING("Could not find PROM info for vertex 0x%x, "
+			printk(KERN_WARNING  "Could not find PROM info for vertex 0x%p, "
 				"FRU analyzer may fail",
-				vhdl);
+				(void *)vhdl);
 #endif
 			return;
 		}
@@ -918,7 +838,6 @@
 		DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
 		npdap->basew_id = 0;
 
-#if defined(BRINGUP)
 	} else if (widget_partnum == XG_WIDGET_PART_NUM) {
 		/* 
 		 * OK, WTF do we do here if we have an XG direct connected to a HUB/Bedrock???
@@ -926,11 +845,10 @@
 		 */
 		npdap->basew_id = 0;
 		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-#endif
 	} else { 
 		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
 
-		panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widgt ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, hubv);
+		panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widgt ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv);
 
 		/*NOTREACHED*/
 	}
@@ -1037,7 +955,7 @@
 #define __DEVSTR3 	"/lun/0/disk/partition/"
 #define	__DEVSTR4	"/../ef"
 
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
+#if defined(CONFIG_IA64_SGI_SN1)
 /*
  * Currently, we need to allow for 5 IBrick slots with 1 FC each
  * plus an internal 1394.
@@ -1045,6 +963,8 @@
  * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR.
  */
 #define NUM_BASE_IO_SCSI_CTLR 6
+#else
+#define NUM_BASE_IO_SCSI_CTLR 6
 #endif
 /*
  * This tells ioconfig where it can start numbering scsi controllers.
@@ -1072,7 +992,6 @@
 		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++)
 			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
 	}
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
 	{
 	/*
 	 * May want to consider changing the SN0 code, above, to work more like
@@ -1129,14 +1048,10 @@
 
 	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
 	}
-#else
-#pragma error Bomb!
-#endif
 }
 
 
 #include <asm/sn/ioerror_handling.h>
-extern devfs_handle_t 	ioc3_console_vhdl_get(void);
 devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
 
 /* Define the system critical vertices and connect them through
@@ -1251,6 +1166,7 @@
 {
 	char 			name[MAXDEVNAME];
 	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
+	devfs_handle_t		ioc3_console_vhdl_get(void);
 
 
 	DBG("baseio_ctlr_num_set; FIXME\n");
@@ -1335,7 +1251,7 @@
 		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0);
 	}
 	if (rtn_val)
-		PRINT_WARNING("sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
+		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
 
 	if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && 
 	    (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) {
@@ -1355,7 +1271,7 @@
 		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0);
 	}
 	if (rtn_val)
-		PRINT_WARNING("sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
+		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
 }
 
 
@@ -1379,7 +1295,7 @@
 #endif
 
 	active = 0;
-	for (cnodeid = 0; cnodeid < maxnodes; cnodeid++) {
+	for (cnodeid = 0; cnodeid < numnodes; cnodeid++) {
 #ifdef LINUX_KERNEL_THREADS
 		char thread_name[16];
 		extern int io_init_pri;
@@ -1428,7 +1344,7 @@
 
 #endif /* LINUX_KERNEL_THREADS */
 
-	for (cnodeid = 0; cnodeid < maxnodes; cnodeid++)
+	for (cnodeid = 0; cnodeid < numnodes; cnodeid++)
 		/*
 	 	 * Update information generated by IO init.
 		 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/module.c linux/arch/ia64/sn/io/module.c
--- linux.orig/arch/ia64/sn/io/module.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/module.c	2002-07-20 01:08:33.000000000 +0000
@@ -4,13 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/io.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
@@ -25,7 +26,7 @@
 #include <asm/sn/sn_cpuid.h>
 
 
-/* #define LDEBUG	1	*/
+/* #define LDEBUG	1 */
 
 #ifdef LDEBUG
 #define DPRINTF		printk
@@ -173,9 +174,35 @@
     lboard_t	       *board;
     klmod_serial_num_t *comp;
     char * bcopy(const char * src, char * dest, int count);
+    char serial_number[16];
+
+    /*
+     * record brick serial number
+     */
+    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
+
+    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
+    {
+#if	LDEBUG
+	printf ("module_probe_snum: no IP35 board found!\n");
+#endif
+	return 0;
+    }
+
+    board_serial_number_get( board, serial_number );
+    if( serial_number[0] != '\0' ) {
+	encode_str_serial( serial_number, m->snum.snum_str );
+	m->snum_valid = 1;
+    }
+#if	LDEBUG
+    else {
+	printf("module_probe_snum: brick serial number is null!\n");
+    }
+    printf("module_probe_snum: brick serial number == %s\n", serial_number);
+#endif /* DEBUG */
 
     board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
-			KLTYPE_MIDPLANE8);
+			KLTYPE_IOBRICK_XBOW);
 
     if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
 	return 0;
@@ -196,13 +223,13 @@
 
 	    if (comp->snum.snum_str[0] != '\0') {
 		bcopy(comp->snum.snum_str,
-		      m->snum.snum_str,
+		      m->sys_snum,
 		      MAX_SERIAL_NUM_SIZE);
-		m->snum_valid = 1;
+		m->sys_snum_valid = 1;
 	    }
     }
 
-    if (m->snum_valid)
+    if (m->sys_snum_valid)
 	return 1;
     else {
 	DPRINTF("Invalid serial number for module %d, "
@@ -227,8 +254,7 @@
     for (node = 0; node < numnodes; node++) {
 	nasid = COMPACT_TO_NASID_NODEID(node);
 
-	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
-			    KLTYPE_IP27);
+	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
 	ASSERT(board);
 
 	m = module_add_node(board->brd_module, node);
@@ -241,7 +267,7 @@
 	    nserial);
 
     if (nserial == 0)
-	PRINT_WARNING("io_module_init: No serial number found.\n");
+	printk(KERN_WARNING  "io_module_init: No serial number found.\n");
 }
 
 elsc_t *get_elsc(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/pci.c linux/arch/ia64/sn/io/pci.c
--- linux.orig/arch/ia64/sn/io/pci.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/pci.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,12 +1,12 @@
 /* 
  *
+ * SNI64 specific PCI support for SNI IO.
+ *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * SNI64 specific PCI support for SNI IO.
- *
- * Copyright (C) 1997, 1998, 2000 Colin Ngam
+ * Copyright (c) 1997, 1998, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
  */
 #include <linux/init.h>
 #include <linux/types.h>
@@ -14,7 +14,8 @@
 #include <linux/pci.h>
 #include <asm/sn/types.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
 #include <asm/sn/iograph.h>
 #include <asm/param.h>
 #include <asm/sn/pio.h>
@@ -227,7 +228,7 @@
  * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code.
  */
 void __init
-sn1_pci_find_bios(void)
+sn_pci_find_bios(void)
 {
 	extern struct pci_ops pci_conf;
 	/*
@@ -237,11 +238,7 @@
 
 	sgi_master_io_infr_init();
 
-#ifdef BRINGUP
-	if ( IS_RUNNING_ON_SIMULATOR() )
-		return;
-#endif
-	/* sn1_io_infrastructure_init(); */
+	/* sn_io_infrastructure_init(); */
 	pci_conf = snia64_pci_ops;
 }
 
@@ -251,8 +248,6 @@
         int 		i;
 	unsigned int 	size;
 
-	devfs_handle_t	bridge_vhdl = pci_bus_to_vertex(d->bus->number);
-
         /* IOC3 only decodes 0x20 bytes of the config space, reading
 	 * beyond that is relatively benign but writing beyond that
 	 * (especially the base address registers) will shut down the
@@ -295,4 +290,11 @@
 
 }
 
+#else
+void sn_pci_find_bios(void) {}
+void pci_fixup_ioc3(struct pci_dev *d) {}
+struct list_head pci_root_buses;
+struct list_head pci_root_buses;
+struct list_head pci_devices;
+
 #endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/pci_bus_cvlink.c linux/arch/ia64/sn/io/pci_bus_cvlink.c
--- linux.orig/arch/ia64/sn/io/pci_bus_cvlink.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/pci_bus_cvlink.c	2002-07-20 01:08:29.000000000 +0000
@@ -4,19 +4,21 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <linux/sched.h>
 #include <linux/ioport.h>
 #include <asm/sn/types.h>
 #include <asm/sn/hack.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
 #include <asm/sn/iograph.h>
 #include <asm/param.h>
 #include <asm/sn/pio.h>
@@ -26,20 +28,19 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
-#include <asm/sn/agent.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/xtalk/xtalkaddrs.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/io.h>
-
+#include <asm/sn/nodepda.h>
 #include <asm/sn/pci/pciio.h>
-// #include <sys/ql.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pcibr_private.h>
-extern int bridge_rev_b_data_check_disable;
 #include <asm/sn/pci/pci_bus_cvlink.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/sn_cpuid.h>
+
+extern int bridge_rev_b_data_check_disable;
 
-#define MAX_PCI_XWIDGET 256
 devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
 nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
 void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
@@ -49,11 +50,13 @@
 static int pci_bus_map_create(devfs_handle_t xtalk);
 devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
 
-#define SN1_IOPORTS_UNIT 256
+#define SN_IOPORTS_UNIT 256
 #define MAX_IOPORTS 0xffff
-#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN1_IOPORTS_UNIT)
+#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN_IOPORTS_UNIT)
 struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS];
-unsigned long sn1_allocate_ioports(unsigned long pci_address);
+unsigned long sn_allocate_ioports(unsigned long pci_address);
+
+extern void sn_init_irq_desc(void);
 
 
 
@@ -104,7 +107,7 @@
 	int func = 0;
 	char	name[16];
 	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = NULL;
+	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
 
 	/*
 	 * Go get the pci bus vertex.
@@ -112,9 +115,9 @@
 	pci_bus = pci_bus_to_vertex(busnum);
 	if (!pci_bus) {
 		/*
-		 * During probing, the Linux pci code invents non existant
+		 * During probing, the Linux pci code invents non-existent
 		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existance. Don't crib during probing.
+		 * them to determine existence. Don't crib during probing.
 		 */
 		if (done_probing)
 			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
@@ -129,11 +132,25 @@
 	slot = PCI_SLOT(devfn);
 	func = PCI_FUNC(devfn);
 
-	if (func == 0)
+	/*
+	 * For a NON Multi-function card the name of the device looks like:
+	 * ../pci/1, ../pci/2 ..
+	 */
+	if (func == 0) {
         	sprintf(name, "%d", slot);
-	else
-		sprintf(name, "%d%c", slot, 'a'+func);
-
+		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
+			GRAPH_SUCCESS) {
+			if (device_vertex) {
+				return(device_vertex);
+			}
+		}
+	}
+			
+	/*
+	 * This maybe a multifunction card.  It's names look like:
+	 * ../pci/1a, ../pci/1b, etc.
+	 */
+	sprintf(name, "%d%c", slot, 'a'+func);
 	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
 		if (!device_vertex) {
 			return(NULL);
@@ -144,12 +161,42 @@
 }
 
 /*
+ * For the given device, initialize the addresses for both the Device(x) Flush 
+ * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
+ * is connected.
+ */
+static void
+set_flush_addresses(struct pci_dev *device_dev, 
+	struct sn_device_sysdata *device_sysdata)
+{
+	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
+	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
+	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    	bridge_t               *bridge = pcibr_soft->bs_base;
+
+	device_sysdata->dma_buf_sync = (volatile unsigned int *) 
+		&(bridge->b_wr_req_buf[pciio_slot].reg);
+	device_sysdata->xbow_buf_sync = (volatile unsigned int *)
+		XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), 
+		pcibr_soft->bs_xid);
+#ifdef DEBUG
+
+	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
+		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
+
+	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
+	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
+#endif
+
+}
+
+/*
  * Most drivers currently do not properly tell the arch specific pci dma
  * interfaces whether they can handle A64. Here is where we privately
  * keep track of this.
  */
 static void __init
-set_sn1_pci64(struct pci_dev *dev)
+set_sn_pci64(struct pci_dev *dev)
 {
 	unsigned short vendor = dev->vendor;
 	unsigned short device = dev->device;
@@ -172,7 +219,7 @@
 }
 
 /*
- * sn1_allocate_ioports() - This routine provides the allocation and 
+ * sn_allocate_ioports() - This routine provides the allocation and 
  *	mappings between Linux style IOPORTs management.
  *
  *	For simplicity sake, SN1 will allocate IOPORTs in chunks of 
@@ -189,9 +236,9 @@
  *	Address.  This address via the tlb entries generates the PCI Address 
  *	allocated by the SN1 IO Infrastructure Layer.
  */
-static unsigned long sn1_ioport_num = 0x100; /* Reserve room for Legacy stuff */
+static unsigned long sn_ioport_num = 0x1000; /* Reserve room for Legacy stuff */
 unsigned long
-sn1_allocate_ioports(unsigned long pci_address)
+sn_allocate_ioports(unsigned long pci_address)
 {
 	
 	unsigned long ioport_index;
@@ -199,8 +246,8 @@
 	/*
 	 * Just some idiot checking ..
 	 */
-	if ( sn1_ioport_num > 0xffff ) {
-		printk("sn1_allocate_ioports: No more IO PORTS available\n");
+	if ( sn_ioport_num > 0xffff ) {
+		printk("sn_allocate_ioports: No more IO PORTS available\n");
 		return(-1);
 	}
 
@@ -208,51 +255,64 @@
 	 * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's
 	 * Manual for details.
 	 */
-	ioport_index = sn1_ioport_num / SN1_IOPORTS_UNIT;
-	ioports_to_tlbs[ioport_index].ppn = pci_address;
+	ioport_index = sn_ioport_num / SN_IOPORTS_UNIT;
+
 	ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */
-	ioports_to_tlbs[ioport_index].ma = 5; /* Memory Attributes */
-	ioports_to_tlbs[ioport_index].a = 0; /* Set Data Access Bit Fault */
-	ioports_to_tlbs[ioport_index].d = 0; /* Dirty Bit */
-	ioports_to_tlbs[ioport_index].pl = 3;/* Privilege Level - All levels can R/W*/
-	ioports_to_tlbs[ioport_index].ar = 2; /* Access Rights - R/W only*/
+	ioports_to_tlbs[ioport_index].rv_1 = 0; /* 1 Bit */
+	ioports_to_tlbs[ioport_index].ma = 4; /* Memory Attributes 3 bits*/
+	ioports_to_tlbs[ioport_index].a = 1; /* Set Data Access Bit Fault 1 Bit*/
+	ioports_to_tlbs[ioport_index].d = 1; /* Dirty Bit */
+	ioports_to_tlbs[ioport_index].pl = 0;/* Privilege Level - All levels can R/W*/
+	ioports_to_tlbs[ioport_index].ar = 3; /* Access Rights - R/W only*/
+	ioports_to_tlbs[ioport_index].ppn = pci_address >> 12; /* 4K page size */
 	ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */
 	ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */
 
-	printk("sn1_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index].ppn);
+	/* printk("sn_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index]); */
 	
-	sn1_ioport_num += SN1_IOPORTS_UNIT;
+	sn_ioport_num += SN_IOPORTS_UNIT;
 
-	return(sn1_ioport_num - SN1_IOPORTS_UNIT);
+	return(sn_ioport_num - SN_IOPORTS_UNIT);
 }
 
 /*
- * sn1_pci_fixup() - This routine is called when platform_pci_fixup() is 
+ * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
  *	invoked at the end of pcibios_init() to link the Linux pci 
  *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
  *
  *	Other platform specific fixup can also be done here.
  */
 void
-sn1_pci_fixup(int arg)
+sn_pci_fixup(int arg)
 {
 	struct list_head *ln;
 	struct pci_bus *pci_bus = NULL;
 	struct pci_dev *device_dev = NULL;
-	struct sn1_widget_sysdata *widget_sysdata;
-	struct sn1_device_sysdata *device_sysdata;
+	struct sn_widget_sysdata *widget_sysdata;
+	struct sn_device_sysdata *device_sysdata;
+#ifdef SN_IOPORTS
 	unsigned long ioport;
+#endif
 	pciio_intr_t intr_handle;
 	int cpuid, bit;
-	devfs_handle_t *device_vertex;
+	devfs_handle_t device_vertex;
 	pciio_intr_line_t lines;
-	extern void sn1_pci_find_bios(void);
-
+	extern void sn_pci_find_bios(void);
+#ifdef CONFIG_IA64_SGI_SN2
+	extern int numnodes;
+	int cnode;
+#endif /* CONFIG_IA64_SGI_SN2 */
 
-unsigned long   res;
 
 	if (arg == 0) {
-		sn1_pci_find_bios();
+		sn_init_irq_desc();
+		sn_pci_find_bios();
+#ifdef CONFIG_IA64_SGI_SN2
+		for (cnode = 0; cnode < numnodes; cnode++) {
+				extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
+				intr_init_vecblk(NODEPDA(cnode), cnode, 0);
+		} 
+#endif /* CONFIG_IA64_SGI_SN2 */
 		return;
 	}
 
@@ -274,19 +334,12 @@
 #endif
 	done_probing = 1;
 
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		printk("sn1_pci_fixup not supported on simulator.\n");
-		return;
-	}
-
-#ifdef REAL_HARDWARE
-
 	/*
 	 * Initialize the pci bus vertex in the pci_bus struct.
 	 */
 	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
 		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn1_widget_sysdata), 
+		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
 					GFP_KERNEL);
 		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
 		pci_bus->sysdata = (void *)widget_sysdata;
@@ -296,8 +349,35 @@
  	 * set the root start and end so that drivers calling check_region()
 	 * won't see a conflict
 	 */
-	ioport_resource.start |= IO_SWIZ_BASE;
-	ioport_resource.end |= (HSPEC_SWIZ_BASE-1);
+#ifdef SN_IOPORTS
+	ioport_resource.start  = sn_ioport_num;
+	ioport_resource.end = 0xffff;
+#else
+#if defined(CONFIG_IA64_SGI_SN1)
+	if ( IS_RUNNING_ON_SIMULATOR() ) {
+		/*
+		 * IDE legacy IO PORTs are supported in Medusa.
+		 * Just open up IO PORTs from 0 .. ioport_resource.end.
+		 */
+		ioport_resource.start = 0;
+	} else {
+		/*
+		 * We do not support Legacy IO PORT numbers.
+		 */
+		ioport_resource.start |= IO_SWIZ_BASE | __IA64_UNCACHED_OFFSET;
+	}
+	ioport_resource.end |= (HSPEC_SWIZ_BASE-1) | __IA64_UNCACHED_OFFSET;
+#else
+	// Need something here for sn2.... ZXZXZX
+#endif
+#endif
+
+	/*
+	 * Set the root start and end for Mem Resource.
+	 */
+	iomem_resource.start = 0;
+	iomem_resource.end = 0xffffffffffffffff;
+
 	/*
 	 * Initialize the device vertex in the pci_dev struct.
 	 */
@@ -307,6 +387,7 @@
 		u16 cmd;
 		devfs_handle_t vhdl;
 		unsigned long size;
+		extern int bit_pos_to_irq(int);
 
 		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
 				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
@@ -316,12 +397,18 @@
 
 		/* Set the device vertex */
 
-		device_sysdata = kmalloc(sizeof(struct sn1_device_sysdata),
+		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
 					GFP_KERNEL);
 		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
 		device_sysdata->isa64 = 0;
+		/*
+		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
+		 * register addresses.
+		 */
+		(void) set_flush_addresses(device_dev, device_sysdata);
+
 		device_dev->sysdata = (void *) device_sysdata;
-		set_sn1_pci64(device_dev);
+		set_sn_pci64(device_dev);
 		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
 
 		/*
@@ -336,11 +423,8 @@
 			size = device_dev->resource[idx].end -
 				device_dev->resource[idx].start;
 			if (size) {
-				res = 0;
-				res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4);
 				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM);
-
-/* printk("sn1_pci_fixup: Mapped Address = 0x%p size = 0x%x\n", device_dev->resource[idx].start, size); */
+				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
 			}
 			else
 				continue;
@@ -348,6 +432,7 @@
 			device_dev->resource[idx].end = 
 				device_dev->resource[idx].start + size;
 
+#ifdef CONFIG_IA64_SGI_SN1
 			/*
 			 * Adjust the addresses to go to the SWIZZLE ..
 			 */
@@ -355,15 +440,25 @@
 				device_dev->resource[idx].start & 0xfffff7ffffffffff;
 			device_dev->resource[idx].end = 
 				device_dev->resource[idx].end & 0xfffff7ffffffffff;
-			res = 0;
-			res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4);
+#endif
+
 			if (device_dev->resource[idx].flags & IORESOURCE_IO) {
 				cmd |= PCI_COMMAND_IO;
-				ioport = sn1_allocate_ioports(device_dev->resource[idx].start);
-				/* device_dev->resource[idx].start = ioport; */
-				/* device_dev->resource[idx].end = ioport + SN1_IOPORTS_UNIT */
+#ifdef SN_IOPORTS
+				ioport = sn_allocate_ioports(device_dev->resource[idx].start);
+				if (ioport < 0) {
+					printk("sn_pci_fixup: PCI Device 0x%x on PCI Bus %d not mapped to IO PORTs .. IO PORTs exhausted\n", device_dev->devfn, device_dev->bus->number);
+					continue;
+				}
+				pciio_config_set(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + (idx * 4), 4, (res + (ioport & 0xfff)));
+
+printk("sn_pci_fixup: ioport number %d mapped to pci address 0x%lx\n", ioport, (res + (ioport & 0xfff)));
+
+				device_dev->resource[idx].start = ioport;
+				device_dev->resource[idx].end = ioport + SN_IOPORTS_UNIT;
+#endif
 			}
-			else if (device_dev->resource[idx].flags & IORESOURCE_MEM)
+			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
 				cmd |= PCI_COMMAND_MEMORY;
 		}
 		/*
@@ -371,17 +466,24 @@
 		 */
 		size = device_dev->resource[PCI_ROM_RESOURCE].end -
 			device_dev->resource[PCI_ROM_RESOURCE].start;
-		device_dev->resource[PCI_ROM_RESOURCE].start =
+
+		if (size) {
+			device_dev->resource[PCI_ROM_RESOURCE].start =
 			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
 				size, 0, PCIIO_BYTE_STREAM);
-		device_dev->resource[PCI_ROM_RESOURCE].end =
+			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
+			device_dev->resource[PCI_ROM_RESOURCE].end =
 			device_dev->resource[PCI_ROM_RESOURCE].start + size;
 
-                /*
-                 * go through synergy swizzled space
-                 */
-		device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL;
-		device_dev->resource[PCI_ROM_RESOURCE].end   &= 0xfffff7ffffffffffUL;
+#ifdef CONFIG_IA64_SGI_SN1
+                	/*
+                 	 * go through synergy swizzled space
+                 	 */
+			device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL;
+			device_dev->resource[PCI_ROM_RESOURCE].end   &= 0xfffff7ffffffffffUL;
+#endif
+
+		}
 
 		/*
 		 * Update the Command Word on the Card.
@@ -390,29 +492,46 @@
 					   /* bit gets dropped .. no harm */
 		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
 
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, &lines);
-#ifdef BRINGUP
+		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
 		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
 			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
 				lines = 1;
 		}
-
-#endif
  
-		device_sysdata = (struct sn1_device_sysdata *)device_dev->sysdata;
+		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
 		device_vertex = device_sysdata->vhdl;
  
 		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
 
 		bit = intr_handle->pi_irq;
 		cpuid = intr_handle->pi_cpu;
+#ifdef CONFIG_IA64_SGI_SN1
 		irq = bit_pos_to_irq(bit);
+#else /* SN2 */
+		irq = bit;
+#endif
 		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle, NULL, NULL, NULL);
+		pciio_intr_connect(intr_handle);
 		device_dev->irq = irq;
+#ifdef ajmtestintr
+		{
+			int slot = PCI_SLOT(device_dev->devfn);
+			static int timer_set = 0;
+			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
+			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
+			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
+
+			if (!timer_set) {
+				intr_test_set_timer();
+				timer_set = 1;
+			}
+			intr_test_register_irq(irq, pcibr_soft, slot);
+			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
+		}
+#endif
 
 	}
-#endif	/* REAL_HARDWARE */
+
 #if 0
 
 {
@@ -430,6 +549,10 @@
         printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
         printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
 }
+
+printk("testing Big Window: 0xC0000200c0000000 %p\n", *( (volatile uint64_t *)0xc0000200a0000000));
+printk("testing Big Window: 0xC0000200c0000008 %p\n", *( (volatile uint64_t *)0xc0000200a0000008));
+
 #endif
 
 }
@@ -472,12 +595,14 @@
 	 * Loop throught this vertex and get the Xwidgets ..
 	 */
 	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
+#if 0
         {
                 int pos;
                 char dname[256];
                 pos = devfs_generate_path(xtalk, dname, 256);
                 printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
         }
+#endif
 
 		sprintf(pathname, "%d", widgetnum);
 		xwidget = NULL;
@@ -512,12 +637,12 @@
 		 */
 		master_node_vertex = device_master_get(xwidget);
 		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", xwidget);
+			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
 		}
 	
 		hubinfo_get(master_node_vertex, &hubinfo);
 		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", master_node_vertex);
+			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
 			return(1);
 		} else {
 			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
@@ -527,12 +652,12 @@
 		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
 		 */
 		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn1_dma_maps_s) * 512, GFP_KERNEL);
+			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
 		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, xwidget);
+			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
 
 		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn1_dma_maps_s) * 512);
+			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
 
 	}
 
@@ -552,14 +677,10 @@
 {
 
 	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t module_comp = NULL;
-	devfs_handle_t node = NULL;
 	devfs_handle_t xtalk = NULL;
-	graph_vertex_place_t placeptr = EDGE_PLACE_WANT_REAL_EDGES;
 	int rv = 0;
 	char name[256];
 	int master_iobrick;
-	moduleid_t iobrick_id;
 	int i;
 
 	/*
@@ -620,65 +741,3 @@
 
 	return(0);
 }
-
-/*
- * sgi_pci_intr_support -
- */
-int
-sgi_pci_intr_support (unsigned int requested_irq, device_desc_t *dev_desc,
-	devfs_handle_t *bus_vertex, pciio_intr_line_t *lines,
-	devfs_handle_t *device_vertex)
-
-{
-
-	unsigned int bus;
-	unsigned int devfn;
-	struct pci_dev *pci_dev;
-	unsigned char intr_pin = 0;
-	struct sn1_widget_sysdata *widget_sysdata;
-	struct sn1_device_sysdata *device_sysdata;
-
-	if (!dev_desc || !bus_vertex || !device_vertex) {
-		printk("WARNING: sgi_pci_intr_support: Invalid parameter dev_desc 0x%p, bus_vertex 0x%p, device_vertex 0x%p\n", dev_desc, bus_vertex, device_vertex);
-		return(-1);
-	}
-
-	devfn = (requested_irq >> 8) & 0xff;
-	bus = (requested_irq >> 16) & 0xffff;
-	pci_dev = pci_find_slot(bus, devfn);
-	widget_sysdata = (struct sn1_widget_sysdata *)pci_dev->bus->sysdata;
-	*bus_vertex = widget_sysdata->vhdl;
-	device_sysdata = (struct sn1_device_sysdata *)pci_dev->sysdata;
-	*device_vertex = device_sysdata->vhdl;
-#if 0
-	{
-		int pos;
-		char dname[256];
-		pos = devfs_generate_path(*device_vertex, dname, 256);
-		printk("%s : path= %s pos %d\n", __FUNCTION__, &dname[pos], pos);
-	}
-#endif /* BRINGUP */
-
-
-	/*
-	 * Get the Interrupt PIN.
-	 */
-	pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intr_pin);
-	*lines = (pciio_intr_line_t)intr_pin;
-
-#ifdef BRINGUP
-	/*
-	 * ioc3 can't decode the PCI_INTERRUPT_PIN field of its config
-	 * space so we have to set it here
-	 */
-	if (pci_dev->vendor == PCI_VENDOR_ID_SGI &&
-	    pci_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-		*lines = 1;
-	}
-#endif /* BRINGUP */
-
-	/* Not supported currently */
-	*dev_desc = NULL;
-	return(0);
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/pci_dma.c linux/arch/ia64/sn/io/pci_dma.c
--- linux.orig/arch/ia64/sn/io/pci_dma.c	2001-10-12 22:35:53.000000000 +0000
+++ linux/arch/ia64/sn/io/pci_dma.c	2002-07-20 01:08:30.000000000 +0000
@@ -3,11 +3,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Leo Dagum
+ * Copyright (C) 2000,2002 Silicon Graphics, Inc. All rights reserved.
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/string.h>
@@ -15,37 +13,23 @@
 #include <linux/slab.h>
 #include <linux/devfs_fs_kernel.h>
 
-#ifndef LANGUAGE_C 
-#define LANGUAGE_C 99
-#endif
-#ifndef _LANGUAGE_C
-#define _LANGUAGE_C 99
-#endif
-
+#include <asm/delay.h>
 #include <asm/io.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
 #include <asm/sn/types.h>
 #include <asm/sn/alenlist.h>
 #include <asm/sn/pci/pci_bus_cvlink.h>
-
-/*
- * this is REALLY ugly, blame it on gcc's lame inlining that we
- * have to put procedures in header files
- */
-#if LANGUAGE_C == 99
-#undef LANGUAGE_C
-#endif
-#if CONFIG_IA64_SGI_IO == 99
-#undef CONFIG_IA64_SGI_IO
-#endif
+#include <asm/sn/nag.h>
 
 pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
-struct sn1_dma_maps_s *find_sn1_dma_map(dma_addr_t, unsigned char);
+void free_pciio_dmamap(pcibr_dmamap_t);
+struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
 extern devfs_handle_t busnum_to_pcibr_vhdl[];
 extern nasid_t busnum_to_nid[];
 extern void * busnum_to_atedmamaps[];
@@ -57,48 +41,92 @@
 get_free_pciio_dmamap(devfs_handle_t pci_bus)
 {
 	int i;
-	struct sn1_dma_maps_s *sn1_dma_map = NULL;
+	struct sn_dma_maps_s *sn_dma_map = NULL;
 
 	/*
 	 * Darn, we need to get the maps allocated for this bus.
 	 */
-	for (i=0; i<512; i++) {
+	for (i=0; i<MAX_PCI_XWIDGET; i++) {
 		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
-			sn1_dma_map = busnum_to_atedmamaps[i];
+			sn_dma_map = busnum_to_atedmamaps[i];
 		}
 	}
 
 	/*
 	 * Now get a free dmamap entry from this list.
 	 */
-	for (i=0; i<512; i++, sn1_dma_map++) {
-		if (!sn1_dma_map->dma_addr) {
-			sn1_dma_map->dma_addr = -1;
-			return( (pciio_dmamap_t) sn1_dma_map );
+	for (i=0; i<MAX_ATE_MAPS; i++, sn_dma_map++) {
+		if (!sn_dma_map->dma_addr) {
+			sn_dma_map->dma_addr = -1;
+			return( (pciio_dmamap_t) sn_dma_map );
 		}
 	}
 
-printk("get_pciio_dmamap: Unable to find a free dmamap\n");
 	return(NULL);
 
 }
 
-struct sn1_dma_maps_s *
-find_sn1_dma_map(dma_addr_t dma_addr, unsigned char busnum)
+/*
+ * Free pciio_dmamap_t entry.
+ */
+void
+free_pciio_dmamap(pcibr_dmamap_t dma_map)
+{
+	struct sn_dma_maps_s *sn_dma_map;
+
+	sn_dma_map = (struct sn_dma_maps_s *) dma_map;
+	sn_dma_map->dma_addr = 0;
+
+}
+
+/*
+ * sn_dma_sync: This routine flushes all DMA buffers for the device into the II.
+ *	This does not mean that the data is in the "Coherence Domain".  But it 
+ *	is very close.
+ */
+void
+sn_dma_sync( struct pci_dev *hwdev )
+{
+
+	struct sn_device_sysdata *device_sysdata;
+	volatile unsigned long dummy;
+
+	/*
+	 * It is expected that on IA64 platform, a DMA sync ensures that all 
+	 * the DMA (dma_handle) are complete and coherent.
+	 *	1. Flush Write Buffers from Bridge.
+	 *	2. Flush Xbow Port.
+	 */
+	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
+	dummy = (volatile unsigned long ) *device_sysdata->dma_buf_sync;
+
+	/*
+	 * For the Xbow Port flush, we maybe denied the request because 
+	 * someone else may be flushing the Port .. try again.
+	 */
+	while((volatile unsigned long ) *device_sysdata->xbow_buf_sync) {
+		udelay(2);
+	}
+}
+
+
+struct sn_dma_maps_s *
+find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum)
 {
 
-	struct sn1_dma_maps_s *sn1_dma_map = NULL;
+	struct sn_dma_maps_s *sn_dma_map = NULL;
 	int i;
 
-	sn1_dma_map = busnum_to_atedmamaps[busnum];
+	sn_dma_map = busnum_to_atedmamaps[busnum];
 
-	for (i=0; i<512; i++, sn1_dma_map++) {
-		if (sn1_dma_map->dma_addr == dma_addr) {
-			return( sn1_dma_map );
+	for (i=0; i<MAX_ATE_MAPS; i++, sn_dma_map++) {
+		if (sn_dma_map->dma_addr == dma_addr) {
+			return( sn_dma_map );
 		}
 	}
 
 printk("find_pciio_dmamap: Unable find the corresponding dma map\n");
+
 	return(NULL);
 
 }
@@ -111,12 +139,12 @@
  * write gathering turned on, hence the PCIIO_DMA_CMD flag
  */
 void *
-sn1_pci_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+sn_pci_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
 {
         void *ret;
         int gfp = GFP_ATOMIC;
 	devfs_handle_t    vhdl;
-	struct sn1_device_sysdata *device_sysdata;
+	struct sn_device_sysdata *device_sysdata;
 	paddr_t temp_ptr;
 
 	*dma_handle = (dma_addr_t) NULL;
@@ -124,7 +152,7 @@
 	/*
 	 * get vertex for the device
 	 */
-	device_sysdata = (struct sn1_device_sysdata *) hwdev->sysdata;
+	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
 
         if ( (ret = (void *)__get_free_pages(gfp, get_order(size))) ) {
@@ -139,9 +167,15 @@
 		/*
 		 * This device supports 64bits DMA addresses.
 		 */
+#ifdef CONFIG_IA64_SGI_SN1
 		*dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size,
 			PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD
 			| PCIIO_DMA_A64 );
+#else /* SN2 */
+		*dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size,
+			PCIBR_BARRIER | PCIIO_DMA_CMD | PCIIO_DMA_A64 );
+#endif
+
 		return (ret);
 	}
 
@@ -152,15 +186,21 @@
 	 * First try to get 32 Bit Direct Map Support.
 	 */
 	if (IS_PCI32G(hwdev)) {
+#ifdef CONFIG_IA64_SGI_SN1
 		*dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size,
 			PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD);
+#else /* SN2 */
+		*dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size,
+			PCIBR_BARRIER | PCIIO_DMA_CMD);
+#endif
+
 		if (dma_handle) {
 			return (ret);
 		} else {
 			/*
 			 * We need to map this request by using ATEs.
 			 */
-			printk("sn1_pci_alloc_consistent: 32Bits DMA Page Map support not available yet!");
+			printk("sn_pci_alloc_consistent: 32Bits DMA Page Map support not available yet!");
 			BUG();
 		}
 	}
@@ -176,17 +216,17 @@
 }
 
 void
-sn1_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
 	free_pages((unsigned long) vaddr, get_order(size));
 }
 
 /*
- * On sn1 we use the orig_address entry of the scatterlist to store
+ * On sn1 we use the page entry of the scatterlist to store
  * the physical address corresponding to the given virtual address
  */
 int
-sn1_pci_map_sg (struct pci_dev *hwdev,
+sn_pci_map_sg (struct pci_dev *hwdev,
                         struct scatterlist *sg, int nents, int direction)
 {
 
@@ -194,7 +234,7 @@
 	devfs_handle_t	vhdl;
 	dma_addr_t dma_addr;
 	paddr_t temp_ptr;
-	struct sn1_device_sysdata *device_sysdata;
+	struct sn_device_sysdata *device_sysdata;
 	pciio_dmamap_t dma_map;
 
 
@@ -205,21 +245,51 @@
 	/*
 	 * Handle 64 bit cards.
 	 */
-	device_sysdata = (struct sn1_device_sysdata *) hwdev->sysdata;
+	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
 	for (i = 0; i < nents; i++, sg++) {
-		sg->orig_address = (char *)NULL;
+		/* this catches incorrectly written drivers that
+                   attempt to map scatterlists that they have
+                   previously mapped.  we print a warning and
+                   continue, but the driver should be fixed */
+		switch (((u64)sg->address) >> 60) {
+		case 0xa:
+		case 0xb:
+#ifdef DEBUG
+/* This needs to be cleaned up at some point. */
+			NAG("A PCI driver (for device at%8s) has attempted to "
+			    "map a scatterlist that was previously mapped at "
+			    "%p - this is currently being worked around.\n",
+			    hwdev->slot_name, (void *)sg->address);
+#endif
+			temp_ptr = (u64)sg->address & TO_PHYS_MASK;
+			break;
+		case 0xe: /* a good address, we now map it. */
+			temp_ptr = (paddr_t) __pa(sg->address);
+			break;
+		default:
+			printk(KERN_ERR
+			       "Very bad address (%p) passed to sn_pci_map_sg\n",
+			       (void *)sg->address);
+			BUG();
+		}
+		sg->page = (char *)NULL;
 		dma_addr = 0;
-		temp_ptr = (paddr_t) __pa(sg->address);
 
 		/*
 		 * Handle the most common case 64Bit cards.
 		 */
 		if (IS_PCIA64(hwdev)) {
+#ifdef CONFIG_IA64_SGI_SN1
 			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
 				temp_ptr, sg->length,
-				PCIBR_BARRIER | PCIIO_BYTE_STREAM |
-				PCIIO_DMA_CMD | PCIIO_DMA_A64 );
+				PCIIO_BYTE_STREAM | PCIIO_DMA_DATA |
+				PCIIO_DMA_A64 );
+#else
+			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
+				temp_ptr, sg->length,
+				PCIIO_DMA_DATA | PCIIO_DMA_A64 );
+#endif
 			sg->address = (char *)dma_addr;
 			continue;
 		}
@@ -228,10 +298,14 @@
 		 * Handle 32Bits and greater cards.
 		 */
 		if (IS_PCI32G(hwdev)) {
+#ifdef CONFIG_IA64_SGI_SN1
 			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
 				temp_ptr, sg->length,
-				PCIBR_BARRIER | PCIIO_BYTE_STREAM |
-				PCIIO_DMA_CMD);
+				PCIIO_BYTE_STREAM | PCIIO_DMA_DATA);
+#else
+			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
+				temp_ptr, sg->length, PCIIO_DMA_DATA);
+#endif
 			if (dma_addr) {
 				sg->address = (char *)dma_addr;
 				continue;
@@ -244,9 +318,12 @@
 		 * Let's 32Bit Page map the request.
 		 */
 		dma_map = NULL;
+#ifdef CONFIG_IA64_SGI_SN1
 		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, 
-				PCIBR_BARRIER | PCIIO_BYTE_STREAM |
-				PCIIO_DMA_CMD);
+				PCIIO_BYTE_STREAM | PCIIO_DMA_DATA);
+#else
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, PCIIO_DMA_DATA);
+#endif
 		if (!dma_map) {
 			printk("pci_map_sg: Unable to allocate anymore 32Bits Page Map entries.\n");
 			BUG();
@@ -254,7 +331,7 @@
 		dma_addr = (dma_addr_t)pciio_dmamap_addr(dma_map, temp_ptr, sg->length);
 		/* printk("pci_map_sg: dma_map 0x%p Phys Addr 0x%p dma_addr 0x%p\n", dma_map, temp_ptr, dma_addr); */
 		sg->address = (char *)dma_addr;
-		sg->orig_address = (char *)dma_map;
+		sg->page = (char *)dma_map;
 		
 	}
 
@@ -268,30 +345,31 @@
  * pci_unmap_single() above.
  */
 void
-sn1_pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
+sn_pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
 {
 	int i;
-	struct sn1_dma_maps_s *sn1_dma_map;
+	struct sn_dma_maps_s *sn_dma_map;
 
 
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
 	for (i = 0; i < nelems; i++, sg++)
-		if (sg->orig_address) {
+		if (sg->page) {
 			/*
-			 * We maintain the DMA Map pointer in sg->orig_address if 
+			 * We maintain the DMA Map pointer in sg->page if 
 			 * it is ever allocated.
 			 */
 			/* phys_to_virt((dma_addr_t)sg->address | ~0x80000000); */
-			/* sg->address = sg->orig_address; */
+			/* sg->address = sg->page; */
 			sg->address = (char *)-1;
-			sn1_dma_map = (struct sn1_dma_maps_s *)sg->orig_address;
-			pciio_dmamap_done((pciio_dmamap_t)sn1_dma_map);
-			pciio_dmamap_free((pciio_dmamap_t)sn1_dma_map);
-			sn1_dma_map->dma_addr = 0;
-			sg->orig_address = 0;
+			sn_dma_map = (struct sn_dma_maps_s *)sg->page;
+			pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+			pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+			sn_dma_map->dma_addr = 0;
+			sg->page = 0;
 		}
+
 }
 
 /*
@@ -304,15 +382,15 @@
  *       get rid of dev_desc and vhdl (seems redundant given a pci_dev);
  *       figure out how to save dmamap handle so can use two step.
  */
-dma_addr_t sn1_pci_map_single (struct pci_dev *hwdev,
+dma_addr_t sn_pci_map_single (struct pci_dev *hwdev,
 				void *ptr, size_t size, int direction)
 {
 	devfs_handle_t	vhdl;
 	dma_addr_t dma_addr;
 	paddr_t temp_ptr;
-	struct sn1_device_sysdata *device_sysdata;
+	struct sn_device_sysdata *device_sysdata;
 	pciio_dmamap_t dma_map = NULL;
-	struct sn1_dma_maps_s *sn1_dma_map;
+	struct sn_dma_maps_s *sn_dma_map;
 
 
 	if (direction == PCI_DMA_NONE)
@@ -322,7 +400,7 @@
 	/*
 	 * find vertex for the device
 	 */
-	device_sysdata = (struct sn1_device_sysdata *)hwdev->sysdata;
+	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
 
 	/*
@@ -335,10 +413,14 @@
 		/*
 		 * This device supports 64bits DMA addresses.
 		 */
+#ifdef CONFIG_IA64_SGI_SN1
 		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
 			temp_ptr, size,
-			PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD
-			| PCIIO_DMA_A64 );
+			PCIIO_BYTE_STREAM | PCIIO_DMA_DATA | PCIIO_DMA_A64 );
+#else
+		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
+			temp_ptr, size, PCIIO_DMA_DATA | PCIIO_DMA_A64 );
+#endif
 		return (dma_addr);
 	}
 
@@ -349,9 +431,14 @@
 	 * First try to get 32 Bit Direct Map Support.
 	 */
 	if (IS_PCI32G(hwdev)) {
+#ifdef CONFIG_IA64_SGI_SN1
 		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
 			temp_ptr, size,
-			PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD);
+			PCIIO_BYTE_STREAM | PCIIO_DMA_DATA);
+#else
+		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
+			temp_ptr, size, PCIIO_DMA_DATA);
+#endif
 		if (dma_addr) {
 			return (dma_addr);
 		}
@@ -369,64 +456,72 @@
 	 * Let's 32Bit Page map the request.
 	 */
 	dma_map = NULL;
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIBR_BARRIER | 
-			PCIIO_BYTE_STREAM | PCIIO_DMA_CMD);
+#ifdef CONFIG_IA64_SGI_SN1
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIIO_BYTE_STREAM | 
+				     PCIIO_DMA_DATA);
+#else
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIIO_DMA_DATA);
+#endif
 	if (!dma_map) {
 		printk("pci_map_single: Unable to allocate anymore 32Bits Page Map entries.\n");
 		BUG();
 	}
 
 	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, temp_ptr, size);
-	/* printk("pci_map_single: dma_map 0x%p Phys Addr 0x%p dma_addr 0x%p\n", dma_map, 
+	/* printk("pci_map_single: dma_map 0x%p Phys Addr 0x%p dma_addr 0x%p\n", dma_map,
 		temp_ptr, dma_addr); */
-	sn1_dma_map = (struct sn1_dma_maps_s *)dma_map;
-	sn1_dma_map->dma_addr = dma_addr;
+	sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+	sn_dma_map->dma_addr = dma_addr;
 
 	return ((dma_addr_t)dma_addr);
 }
 
 void
-sn1_pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
+sn_pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
 {
 
-	struct sn1_dma_maps_s *sn1_dma_map = NULL;
+	struct sn_dma_maps_s *sn_dma_map = NULL;
 
         if (direction == PCI_DMA_NONE)
 		BUG();
 
 	/*
-	 * Get the sn1_dma_map entry.
+	 * Get the sn_dma_map entry.
 	 */
 	if (IS_PCI32_MAPPED(dma_addr))
-		sn1_dma_map = find_sn1_dma_map(dma_addr, hwdev->bus->number);
+		sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number);
 
-	if (sn1_dma_map) {
-		pciio_dmamap_done((pciio_dmamap_t)sn1_dma_map);
-		pciio_dmamap_free((pciio_dmamap_t)sn1_dma_map);
-		sn1_dma_map->dma_addr = (dma_addr_t)NULL;
+	if (sn_dma_map) {
+		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+		sn_dma_map->dma_addr = (dma_addr_t)NULL;
 	}
 
 }
 
 void
-sn1_pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
+sn_pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
 {
 	
         if (direction == PCI_DMA_NONE)
                 BUG();
-        /* Nothing to do */
+
+	sn_dma_sync(hwdev);
+
 }
 
 void
-sn1_pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
+sn_pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
 {
         if (direction == PCI_DMA_NONE)
                 BUG();
-        /* Nothing to do */
+
+	sn_dma_sync(hwdev);
+
 }
 
 unsigned long
-sn1_dma_address (struct scatterlist *sg)
+sn_dma_address (struct scatterlist *sg)
 {
 	return ((unsigned long)sg->address);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/pciba.c linux/arch/ia64/sn/io/pciba.c
--- linux.orig/arch/ia64/sn/io/pciba.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/pciba.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,1716 +1,958 @@
-/* $Id$
+/*
+ * arch/ia64/sn/io/pciba.c
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
+ * IRIX PCIBA-inspired user mode PCI interface
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * requires: devfs
+ *
+ * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the
+ * device is on, SS is the slot the device is in, and F is the
+ * device's function on a multi-function card).
+ *
+ * when compiled into the kernel, it will only be initialized by the
+ * sgi sn1 specific initialization code.  in this case, device nodes
+ * are under /dev/hw/..../
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * 03262001 - Initial version by Chad Talbott
  */
 
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/sn_private.h>
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/hubio.h>
-#include <asm/sn/sn1/hubio_next.h>
-#endif
 
-#define copyin(_a, _b, _c)	copy_from_user(_b, _a, _c)
+/* jesse's beefs:
+
+   register_pci_device should be documented
+   
+   grossness with do_swap should be documented
+   
+   big, gross union'ized node_data should be replaced with independent
+   structures
+
+   replace global list of nodes with global lists of resources.  could
+   use object oriented approach of allocating and cleaning up
+   resources.
+   
+*/
+
 
-#ifndef	DEBUG_PCIBA
-#define	DEBUG_PCIBA		0
+#include <linux/config.h>
+#ifndef CONFIG_DEVFS_FS
+#  error PCIBA requires devfs
 #endif
 
-/* v_mapphys does not percolate page offset back. */
-#define	PCIBA_ALIGN_CHECK	1
+#include <linux/module.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/raw.h>
+#include <linux/capability.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+#include <asm/page.h>
 
 #include <asm/sn/pci/pciba.h>
 
-/* grab an unused space code for "User DMA" space */
-#ifndef	PCIBA_SPACE_UDMA
-#define	PCIBA_SPACE_UDMA	(14)
+
+MODULE_DESCRIPTION("User mode PCI interface");
+MODULE_AUTHOR("Chad Talbott");
+
+
+#undef DEBUG_PCIBA
+/* #define DEBUG_PCIBA */
+
+#undef TRACE_PCIBA
+/* #define TRACE_PCIBA */
+
+#if defined(DEBUG_PCIBA)
+#  define DPRINTF(x...) printk(KERN_DEBUG x)
+#else
+#  define DPRINTF(x...)
 #endif
 
-#if DEBUG_REFCT
-extern int		hwgraph_vertex_refct(vertex_hdl_t);
+#if defined(TRACE_PCIBA)
+#  if defined(__GNUC__)
+#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
+			       __FILE__, __LINE__, __FUNCTION__)
+#  else
+#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
+#  endif
+#else
+#  define TRACE()
 #endif
-extern int		pci_user_dma_max_pages;
 
-#define NEW(ptr)	(ptr = kmem_zalloc(sizeof (*(ptr)), KM_SLEEP))
-#define DEL(ptr)	(kfree(ptr))
 
-/* Oops -- no standard "pci address" type! */
-typedef uint64_t        pciaddr_t;
+typedef enum { failure, success } status;
+typedef enum { false, true } boolean;
 
-/* ================================================================
- *            driver types
- */
-typedef struct pciba_slot_s *pciba_slot_t;
-typedef struct pciba_comm_s *pciba_comm_t;
-typedef struct pciba_soft_s *pciba_soft_t;
-typedef struct pciba_map_s *pciba_map_t, **pciba_map_h;
-typedef struct pciba_dma_s *pciba_dma_t, **pciba_dma_h;
-typedef struct pciba_bus_s *pciba_bus_t;
-
-#define	TRACKED_SPACES	16
-struct pciba_comm_s {
-    devfs_handle_t	    conn;
-    pciba_bus_t             bus;
-    int			    refct;
-    pciba_soft_t	    soft[TRACKED_SPACES][2];
-    struct semaphore        lock;
-    pciba_dma_t             dmap;
+
+/* major data structures:
+
+   struct node_data -
+   
+   	one for each file registered with devfs.  contains everything
+   	that any file's fops would need to know about.
+
+   struct dma_allocation -
+
+   	a single DMA allocation.  only the 'dma' nodes care about
+   	these.  they are there primarily to allow the driver to look
+   	up the kernel virtual address of dma buffers allocated by
+   	pci_alloc_consistent, as the application is only given the
+   	physical address (to program the device's dma, presumably) and
+   	cannot supply the kernel virtual address when freeing the
+   	buffer.
+
+	it's also useful to maintain a list of buffers allocated
+	through a specific node to allow some sanity checking by this
+	driver.  this prevents (for example) a broken application from
+	freeing buffers that it didn't allocate, or buffers allocated
+	on another node.
+   
+   global_node_list -
+
+   	a list of all nodes allocated.  this allows the driver to free
+   	all the memory it has 'kmalloc'd in case of an error, or on
+   	module removal.
+
+   global_dma_list -
+
+        a list of all dma buffers allocated by this driver.  this
+	allows the driver to 'pci_free_consistent' all buffers on
+	module removal or error.
+
+*/
+
+
+struct node_data {
+	/* flat list of all the device nodes.  makes it easy to free
+	   them all when we're unregistered */
+	struct list_head global_node_list;
+	devfs_handle_t devfs_handle;
+
+	void (* cleanup)(struct node_data *);
+
+	union {
+		struct {
+			struct pci_dev * dev;
+			struct list_head dma_allocs;
+			boolean mmapped;
+		} dma;
+		struct {
+			struct pci_dev * dev;
+			u32 saved_rom_base_reg;
+			boolean mmapped;
+		} rom;
+		struct {
+			struct resource * res;
+		} base;
+		struct {
+			struct pci_dev * dev;
+		} config;
+	} u;
 };
 
-/* pciba_soft: device_info() for all openables */
-struct pciba_soft_s {
-    pciba_comm_t	    comm;
-    devfs_handle_t          vhdl;
-    int			    refct;
-    pciio_space_t           space;
-    size_t                  size;
-    pciio_space_t           iomem;
-    pciaddr_t               base;
-    unsigned		    flags;
+struct dma_allocation {
+	struct list_head list;
+
+	dma_addr_t handle;
+	void * va;
+	size_t size;
 };
 
-#define	pciba_soft_get(v)	(pciba_soft_t)hwgraph_fastinfo_get(v)
-#define	pciba_soft_set(v,i)	hwgraph_fastinfo_set(v,(arbitrary_info_t)(i))
 
-#define	pciba_soft_lock(soft)	down(&soft->comm->lock)
-#define	pciba_soft_unlock(soft)	up(&soft->comm->lock)
+static LIST_HEAD(global_node_list);
+static LIST_HEAD(global_dma_list);
 
-/* pciba_map: data describing a mapping.
- * (ie. a user mmap request)
- */
-struct pciba_map_s {
-    pciba_map_t             next;
-#ifdef LATER
-    uthread_t              *uthread;
-#endif
-    __psunsigned_t          handle;
-    uvaddr_t                uvaddr;
-    size_t                  size;
-    pciio_piomap_t          map;
-    pciio_space_t           space;
-    pciaddr_t               base;
-    unsigned		    flags;
-};
 
-/* pciba_dma: data describing a DMA mapping.
- */
-struct pciba_dma_s {
-    pciba_dma_t             next;
-    iopaddr_t               paddr;	/* starting phys addr */
-    caddr_t                 kaddr;	/* starting kern addr */
-    pciio_dmamap_t          map;	/* mapping resources (ugh!) */
-    pciaddr_t               daddr;	/* starting pci addr */
-    size_t                  pages;	/* size of block in pages */
-    size_t                  bytes;	/* size of block in bytes */
-    __psunsigned_t          handle;	/* mapping handle */
+/* module entry points */
+int __init pciba_init(void);
+void __exit pciba_exit(void);
+
+static status __init register_with_devfs(void);
+static void __exit unregister_with_devfs(void);
+
+static status __init register_pci_device(devfs_handle_t device_dir_handle,
+					 struct pci_dev * dev);
+
+/* file operations */
+static int generic_open(struct inode * inode, struct file * file);
+static int rom_mmap(struct file * file, struct vm_area_struct * vma);
+static int rom_release(struct inode * inode, struct file * file);
+static int base_mmap(struct file * file, struct vm_area_struct * vma);
+static int config_ioctl(struct inode * inode, struct file * file, 
+			unsigned int cmd, 
+			unsigned long arg);
+static int dma_ioctl(struct inode * inode, struct file * file, 
+		     unsigned int cmd, 
+		     unsigned long arg);
+static int dma_mmap(struct file * file, struct vm_area_struct * vma);
+
+/* support routines */
+static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va);
+static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va);
+
+#ifdef DEBUG_PCIBA
+static void dump_nodes(struct list_head * nodes);
+static void dump_allocations(struct list_head * dalp);
+#endif
+
+/* file operations for each type of node */
+static struct file_operations rom_fops = {
+	owner:		THIS_MODULE,
+	mmap:		rom_mmap,
+	open:		generic_open,
+	release:	rom_release
 };
+ 
 
-/* pciba_bus: common bus info for all openables
- * descended from the same master vertex.
- */
-struct pciba_bus_s {
-    struct semaphore        lock;
-    pciba_map_t             maps;	/* stack of mappings */
-    int			    refct;
+static struct file_operations base_fops = {
+	owner:		THIS_MODULE,
+	mmap:		base_mmap,
+	open:		generic_open
 };
 
-#define	pciba_bus_lock(bus)	down(&bus->lock)
-#define	pciba_bus_unlock(bus)	up(&bus->lock)
 
-typedef union ioctl_arg_buffer_u {
-    char                    data[IOCPARM_MASK + 1];
-    uint8_t                 uc;
-    uint16_t                us;
-    uint32_t                ui;
-    uint64_t                ud;
-    caddr_t                 ca;
-#if ULI
-    struct uliargs          uli;
-    struct uliargs32	    uli32;
-#endif
-} ioctl_arg_buffer_t;
+static struct file_operations config_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		config_ioctl,
+	open:		generic_open
+};	
 
-/* ================================================================
- *            driver variables
- */
-char                   *pciba_mversion = "mload version 7.0";
-int                     pciba_devflag = 0x1 |
-                                        0x200 |
-                                        0x400;
+static struct file_operations dma_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		dma_ioctl,
+	mmap:		dma_mmap,
+	open:		generic_open
+};	
 
-/* this counts the reasons why we can not
- * currently unload this driver.
- */
-atomic_t                pciba_prevent_unload = ATOMIC_INIT(0);
 
-#if DEBUG_PCIBA
-static struct reg_values space_v[] =
-{
-    {PCIIO_SPACE_NONE, "none"},
-    {PCIIO_SPACE_ROM, "ROM"},
-    {PCIIO_SPACE_IO, "I/O"},
-    {PCIIO_SPACE_MEM, "MEM"},
-    {PCIIO_SPACE_MEM32, "MEM(32)"},
-    {PCIIO_SPACE_MEM64, "MEM(64)"},
-    {PCIIO_SPACE_CFG, "CFG"},
-    {PCIIO_SPACE_WIN(0), "WIN(0)"},
-    {PCIIO_SPACE_WIN(1), "WIN(1)"},
-    {PCIIO_SPACE_WIN(2), "WIN(2)"},
-    {PCIIO_SPACE_WIN(3), "WIN(3)"},
-    {PCIIO_SPACE_WIN(4), "WIN(4)"},
-    {PCIIO_SPACE_WIN(5), "WIN(5)"},
-    {PCIBA_SPACE_UDMA, "UDMA"},
-    {PCIIO_SPACE_BAD, "BAD"},
-    {0}
-};
+module_init(pciba_init);
+module_exit(pciba_exit);
+
 
-static struct reg_desc  space_desc[] =
+int __init
+pciba_init(void)
 {
-    {0xFF, 0, "space", 0, space_v},
-    {0}
-};
-#endif
+	TRACE();
 
-char                    pciba_edge_lbl_base[] = "base";
-char                    pciba_edge_lbl_cfg[] = "config";
-char                    pciba_edge_lbl_dma[] = "dma";
-char                    pciba_edge_lbl_intr[] = "intr";
-char                    pciba_edge_lbl_io[] = "io";
-char                    pciba_edge_lbl_mem[] = "mem";
-char                    pciba_edge_lbl_rom[] = "rom";
-char                   *pciba_edge_lbl_win[6] =
-{"0", "1", "2", "3", "4", "5"};
-
-#define	PCIBA_EDGE_LBL_BASE	pciba_edge_lbl_base
-#define	PCIBA_EDGE_LBL_CFG	pciba_edge_lbl_cfg
-#define	PCIBA_EDGE_LBL_DMA	pciba_edge_lbl_dma
-#define	PCIBA_EDGE_LBL_INTR	pciba_edge_lbl_intr
-#define	PCIBA_EDGE_LBL_IO	pciba_edge_lbl_io
-#define	PCIBA_EDGE_LBL_MEM	pciba_edge_lbl_mem
-#define	PCIBA_EDGE_LBL_ROM	pciba_edge_lbl_rom
-#define	PCIBA_EDGE_LBL_WIN(n)	pciba_edge_lbl_win[n]
-
-#define	PCIBA_EDGE_LBL_FLIP	pciba_edge_lbl_flip
-
-static char             pciba_info_lbl_bus[] = "pciba_bus";
-
-#define	PCIBA_INFO_LBL_BUS	pciba_info_lbl_bus
-
-struct file_operations pciba_fops = {
-	owner:	THIS_MODULE,
-	llseek: NULL,
-	read: NULL,
-	write: NULL,
-	readdir: NULL,
-	poll: NULL,
-	ioctl: NULL,
-	mmap: NULL,
-	open: NULL,
-	flush: NULL,
-	release: NULL,
-	fsync: NULL,
-	fasync: NULL,
-	lock: NULL,
-	readv: NULL,
-	writev: NULL
-};
-	
-/* ================================================================
- *            function table of contents
- */
+	if (register_with_devfs() == failure)
+		return 1; /* failure */
 
-void                    pciba_init(void);
-int                     pciba_attach(devfs_handle_t);
+	printk("PCIBA (a user mode PCI interface) initialized.\n");
 
-static void		pciba_sub_attach(pciba_comm_t,
-					 pciio_space_t, pciio_space_t, pciaddr_t,
-					 devfs_handle_t, devfs_handle_t, char *);
-
-static pciba_bus_t      pciba_find_bus(devfs_handle_t, int);
-#ifdef LATER
-static void             pciba_map_push(pciba_bus_t, pciba_map_t);
-static pciba_map_t      pciba_map_pop_hdl(pciba_bus_t, __psunsigned_t);
-static void             pciba_sub_detach(devfs_handle_t, char *);
-static pciio_iter_f     pciba_unload_me;
-#endif
+	return 0; /* success */
+}
 
-int                     pciba_unload(void);
-int                     pciba_unreg(void);
-int                     pciba_detach(devfs_handle_t);
-
-int                     pciba_open(dev_t *, int, int, struct cred *);
-int                     pciba_close(dev_t);
-int                     pciba_read(dev_t, cred_t *);
-int                     pciba_write(dev_t, cred_t *);
-int                     pciba_ioctl(dev_t, int, void *, int, cred_t *, int *);
-
-int                     pciba_map(dev_t, vhandl_t *, off_t, size_t, uint32_t);
-int                     pciba_unmap(dev_t, vhandl_t *);
-
-#if ULI
-void                    pciba_clearuli(struct uli *);
-static intr_func_f      pciba_intr;
-#endif /* Undef as it gets implemented */
 
-/* ================================================================
- *            driver load, register, and setup
- */
-void
-pciba_init(void)
+void __exit
+pciba_exit(void)
 {
+	TRACE();
 
-	/*
-	 * What do we need to do here?
-	 */
-#if DEBUG_PCIBA
-    printk("pciba_init()\n");
-#endif
+	/* FIXME: should also free all that memory that we allocated
+           ;) */
+	unregister_with_devfs();
 }
 
-#ifdef LATER
-#if HWG_PERF_CHECK && IP30 && !DEBUG
-void
-pciba_timeout(void *arg1, void *arg2)
-{
-    struct semaphore       *semap = (sema_t *) arg1;
-    unsigned long          *cvalp = (unsigned long *) arg2;
-
-    if (cvalp)
-	cvalp[0] = RAW_COUNT();
-    if (semap)
-	up(semap);
-}
-
-volatile unsigned long  cNval[1];
-struct semaphore        tsema;
-
-void
-pciba_timeout_test(void)
-{
-    unsigned long           c0val, cval;
-    toid_t                  tid;
-
-    extern void             hwg_hprint(unsigned long, char *);
-
-    sema_init(&tsema, 0);
-
-    cNval[0] = 0;
-    c0val = RAW_COUNT();
-    tid = timeout((void (*)()) pciba_timeout, (void *) 0, 1, (void *) cNval);
-    DELAY(1000000);
-    cval = cNval[0];
-    if (cval == 0) {
-	untimeout(tid);
-	PRINT_ALERT("pciba: one-tick timeout did not happen in a second\n");
-	return;
-    }
-    cval = cval - c0val;
-    hwg_hprint(cval, "timeout(1)");
-
-    cNval[0] = 0;
-    c0val = RAW_COUNT();
-    tid = timeout((void (*)()) pciba_timeout, (void *) &tsema, 2, (void *) cNval);
-
-    /* FIXME : this probably needs to be down_interruptible() */
-
-    if (down(&tsema) < 0) {	/* wait for the pciba_timeout */
-	untimeout(tid);
-	PRINT_WARNING("pciba: timeout(2) time check aborted\n");
-	return;
-    }
-    cval = cNval[0];
-    if (cval == 0) {
-	untimeout(tid);
-	PRINT_WARNING("pciba: timeout(2) time not logged\n");
-	return;
-    }
-    cval = cval - c0val;
-    hwg_hprint(cval, "timeout(2)");
-
-    cNval[0] = 0;
-    c0val = RAW_COUNT();
-    tid = timeout((void (*)()) pciba_timeout, (void *) &tsema, HZ, (void *) cNval);
-
-    /* FIXME : this probably needs to be down_interruptible() */
-
-    if (down(&tsema) < 0) {	/* wait for the pciba_timeout */
-	untimeout(tid);
-	PRINT_WARNING("pciba: timeout(HZ) time check aborted\n");
-	return;
-    }
-    cval = cNval[0];
-    if (cval == 0) {
-	untimeout(tid);
-	PRINT_WARNING("pciba: timeout(HZ) time not logged\n");
-	return;
-    }
-    cval = cval - c0val;
-    hwg_hprint(cval, "timeout(HZ)");
-
-    printk("verifying untimeout() cancells ...\n");
-    cNval[0] = 0;
-    tid = timeout((void (*)()) pciba_timeout, (void *) 0, 2, (void *) cNval);
-    untimeout(tid);
-    DELAY(1000000);
-    cval = cNval[0];
-    if (cval != 0) {
-	PRINT_ALERT("pciba: unable to cancel two-tick timeout\n");
-	cval -= c0val;
-	hwg_hprint(cval, "CANCELLED timeout(2)");
-    }
-}
-#endif
 
-int
-pciba_reg(void)
+# if 0
+static void __exit
+free_nodes(void)
 {
-#if DEBUG_PCIBA
-    printk("pciba_reg()\n");
-#endif
-    pciio_driver_register(-1, -1, "pciba_", 0);
-
-#if HWG_PERF_CHECK && IP30 && !DEBUG
-    printk("%s %d\n", __FUNCTION__, __LINE__);
-pciba_timeout_test();
-#endif
+	struct node_data * nd;
+	
+	TRACE();
 
-#if DEBUG_REFCT
-    {
-	char	       *cname = "pciba";
-	char	       *dname = "ptv";
-	char           *cpath0 = "node/xtalk/15";
-	char           *uname0 = "0";
-	char           *cpath1 = "node/xtalk/13";
-	char           *uname1 = "1";
-	devfs_handle_t conn;
-	devfs_handle_t conv;
-	devfs_handle_t vhdl;
-	int		ret;
-
-	printk("pciba refct tests:\n");
-
-#define	SHOWREF(vhdl,func)	printk("ref=%d\t%s\t(%d) %v\n", hwgraph_vertex_refct(vhdl), #func, vhdl, vhdl);
-
-	if (GRAPH_SUCCESS != (ret = hwgraph_path_add(hwgraph_root, cname, &conv)))
-	    printk("\tunable to create conv (ret=%d)\n", ret);
-	else {						SHOWREF(conv, hwgraph_path_add);
-	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath0, &conn)))
-		printk("\tunable to find %s (ret=%d)\n", cpath0, ret);
-	    else {					SHOWREF(conn, hwgraph_traverse);
-		if (GRAPH_SUCCESS != (ret = hwgraph_char_device_add(conn, dname, "pciba_", &vhdl)))
-		    printk("unable to create %v/%s (ret=%d)\n", conn, dname, ret);
-		else {					SHOWREF(vhdl, hwgraph_char_device_add);
-		    hwgraph_chmod(vhdl, 0666);		SHOWREF(vhdl, hwgraph_chmod);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_add(conv, vhdl, uname0)))
-			printk("unable to create %v/%s (ret=%d)\n", conn, uname0, vhdl, ret);
-		    else				SHOWREF(vhdl, hwgraph_edge_add);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))
-			printk("unable to unref %v\n", vhdl);
-		    else				SHOWREF(vhdl, hwgraph_vertex_unref);
-		}
-		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))
-		    printk("unable to unref %v\n", conn);
-		else					SHOWREF(conn, hwgraph_vertex_unref);
-	    }
- 
-	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath1, &conn)))
-		printk("\tunable to find %s (ret=%d)\n", cpath1, ret);
-	    else {					SHOWREF(conn, hwgraph_traverse);
-		if (GRAPH_SUCCESS != (ret = hwgraph_char_device_add(conn, dname, "pciba_", &vhdl)))
-		    printk("unable to create %v/%s (ret=%d)\n", conn, dname, ret);
-		else {					SHOWREF(vhdl, hwgraph_char_device_add);
-		    hwgraph_chmod(vhdl, 0666);		SHOWREF(vhdl, hwgraph_chmod);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_add(conv, vhdl, uname1)))
-			printk("unable to create %v/%s (ret=%d)\n", conn, uname1, vhdl, ret);
-		    else				SHOWREF(vhdl, hwgraph_edge_add);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))
-			printk("unable to unref %v\n", vhdl);
-		    else				SHOWREF(vhdl, hwgraph_vertex_unref);
-		}
-		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))
-		    printk("unable to unref %v\n", conn);
-		else					SHOWREF(conn, hwgraph_vertex_unref);
-	    }
- 
-	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath0, &conn)))
-		printk("\tunable to find %s (ret=%d)\n", cpath0, ret);
-	    else {					SHOWREF(conn, hwgraph_traverse);
-		if (GRAPH_SUCCESS != (ret = hwgraph_traverse(conn, dname, &vhdl)))
-		    printk("\tunable to find %v/%s (ret=%d)\n", conn, dname, ret);
-		else {					SHOWREF(vhdl, hwgraph_traverse);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conv, uname0, NULL)))
-			printk("\tunable to remove edge %v/%s (ret=%d)\n", conv, uname0, ret);
-		    else				SHOWREF(vhdl, hwgraph_edge_remove);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conn, dname, NULL)))
-			printk("\tunable to remove edge %v/%s (ret=%d)\n", conn, dname, ret);
-		    else				SHOWREF(vhdl, hwgraph_edge_remove);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))
-			printk("unable to unref %v\n", vhdl);
-		    else				SHOWREF(vhdl, hwgraph_vertex_unref);
-		    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(vhdl)))
-			printk("\tvertex %d destroyed OK\n", vhdl);
-		    else				SHOWREF(vhdl, hwgraph_vertex_destroy);
-		}
-		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))
-		    printk("unable to unref %v\n", conn);
-		else					SHOWREF(conn, hwgraph_vertex_unref);
-	    }
-
-	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath1, &conn)))
-		printk("\tunable to find %s (ret=%d)\n", cpath1, ret);
-	    else {					SHOWREF(conn, hwgraph_traverse);
-		if (GRAPH_SUCCESS != (ret = hwgraph_traverse(conn, dname, &vhdl)))
-		    printk("\tunable to find %v/%s (ret=%d)\n", conn, dname, ret);
-		else {					SHOWREF(vhdl, hwgraph_traverse);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conv, uname1, NULL)))
-			printk("\tunable to remove edge %v/%s (ret=%d)\n", conv, uname1, ret);
-		    else				SHOWREF(vhdl, hwgraph_edge_remove);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conn, dname, NULL)))
-			printk("\tunable to remove edge %v/%s (ret=%d)\n", conn, dname, ret);
-		    else				SHOWREF(vhdl, hwgraph_edge_remove);
-		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))
-			printk("unable to unref %v\n", vhdl);
-		    else				SHOWREF(vhdl, hwgraph_vertex_unref);
-		    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(vhdl)))
-			printk("\tvertex %d destroyed OK\n", vhdl);
-		    else				SHOWREF(vhdl, hwgraph_vertex_destroy);
-		}
-		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))
-		    printk("unable to unref %v\n", conn);
-		else					SHOWREF(conn, hwgraph_vertex_unref);
-	    }
-
-	    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(hwgraph_root, cname, NULL)))
-		printk("\tunable to remove edge %v/%s (ret=%d)\n", hwgraph_root, cname, ret);
-	    else				SHOWREF(conv, hwgraph_edge_remove);
-	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conv)))
-		printk("unable to unref %v\n", conv);
-	    else					SHOWREF(conv, hwgraph_vertex_unref);
-	    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(conv)))
-		printk("\tvertex %d destroyed OK\n", conv);
-	    else					SHOWREF(conv, hwgraph_vertex_destroy);
+	list_for_each(nd, &node_list) {
+		kfree(list_entry(nd, struct nd, node_list));
 	}
-    }
-#endif
-
-    return 0;
 }
-
-#endif
-int
-pciba_attach(devfs_handle_t hconn)
-{
-#if defined(PCIIO_SLOT_NONE)
-    pciio_info_t            info = pciio_info_get(hconn);
-    pciio_slot_t            slot = pciio_info_slot_get(info);
 #endif
-    pciba_comm_t	    comm;
-    pciba_bus_t             bus;
-    int                     ht;
-    devfs_handle_t	    hbase;
-    devfs_handle_t          gconn;
-    devfs_handle_t          gbase;
-    int                     win;
-    int                     wins;
-    pciio_space_t           space;
-    pciaddr_t               base;
 
-    int                     iwins;
-    int                     mwins;
 
-#if DEBUG_PCIBA
-    printk("pciba_attach(%p)\n", hconn);
-#endif
+static devfs_handle_t pciba_devfs_handle;
 
-    /* Pick up "dualslot guest" vertex,
-     * which gets all functionality except
-     * config space access.
-     */
-    if ((GRAPH_SUCCESS !=
-	 hwgraph_traverse(hconn, ".guest", &gconn)) ||
-	(hconn == gconn))
-	gconn = GRAPH_VERTEX_NONE;
-
-    bus = pciba_find_bus(hconn, 1);
-    bus->refct ++;
-
-    /* set up data common to all pciba openables
-     * on this connection point.
-     */
-    NEW(comm);
-    comm->conn = hconn;
-    comm->bus = bus;
-    comm->refct = 0;
-    sema_init(&comm->lock, 1);
 
-#if !defined(PCIIO_SLOT_NONE)
-    if (bus->refct == 1)
-#else
-    if (slot == PCIIO_SLOT_NONE)
-#endif
-    {
-	pciio_info_t            pciio_info;
-	devfs_handle_t          master;
-
-	pciio_info = pciio_info_get(hconn);
-	master = pciio_info_master_get(pciio_info);
-
-	pciba_sub_attach(comm, PCIIO_SPACE_IO, PCIIO_SPACE_IO, 0, master, master, PCIBA_EDGE_LBL_IO);
-	pciba_sub_attach(comm, PCIIO_SPACE_MEM, PCIIO_SPACE_MEM, 0, master, master, PCIBA_EDGE_LBL_MEM);
-#if defined(PCIIO_SLOT_NONE)
-	return 0;
-#endif
-    }
+#if !defined(CONFIG_IA64_SGI_SN1)
 
-    ht = 0x7F & pciio_config_get(hconn, PCI_CFG_HEADER_TYPE, 1);
+static status __init
+register_with_devfs(void)
+{
+	struct pci_dev * dev;
+	devfs_handle_t device_dir_handle;
+	char devfs_path[40];
 
-    wins = ((ht == 0x00) ? 6 :
-	    (ht == 0x01) ? 2 :
-	    0);
-
-    mwins = iwins = 0;
-
-    hbase = GRAPH_VERTEX_NONE;
-    gbase = GRAPH_VERTEX_NONE;
-
-    for (win = 0; win < wins; win++) {
-
-	base = pciio_config_get(hconn, PCI_CFG_BASE_ADDR(win), 4);
-	if (base & 1) {
-	    space = PCIIO_SPACE_IO;
-	    base &= 0xFFFFFFFC;
-	} else if ((base & 7) == 4) {
-	    space = PCIIO_SPACE_MEM;
-	    base &= 0xFFFFFFF0;
-	    base |= ((pciaddr_t) pciio_config_get(hconn, PCI_CFG_BASE_ADDR(win + 1), 4)) << 32;
-	} else {
-	    space = PCIIO_SPACE_MEM;
-	    base &= 0xFFFFFFF0;
-	}
+	TRACE();
 
-	if (!base)
-	    break;
+	pciba_devfs_handle = devfs_mk_dir(NULL, "pci", NULL);
+	if (pciba_devfs_handle == NULL)
+		return failure;
 
-#if PCIBA_ALIGN_CHECK
-	if (base & (_PAGESZ - 1)) {
-#if DEBUG_PCIBA
-	    PRINT_WARNING("%p pciba: BASE%d not page aligned!\n"
-		    "\tmmap this window at offset 0x%x via \".../pci/%s\"\n",
-		    hconn, win, base,
-		    (space == PCIIO_SPACE_IO) ? "io" : "mem");
-#endif
-	    continue;			/* next window */
-	}
-#endif
+	/* FIXME: don't forget /dev/pci/mem & /dev/pci/io */
+
+	pci_for_each_dev(dev) {
+		sprintf(devfs_path, "%02x/%02x.%x",
+			dev->bus->number,
+			PCI_SLOT(dev->devfn),
+			PCI_FUNC(dev->devfn));
+    
+		device_dir_handle =
+			devfs_mk_dir(pciba_devfs_handle, devfs_path, NULL);
+		if (device_dir_handle == NULL)
+			return failure;
 
-	if ((hbase == GRAPH_VERTEX_NONE) &&
-	    ((GRAPH_SUCCESS !=
-	      hwgraph_path_add(hconn, PCIBA_EDGE_LBL_BASE, &hbase)) ||
-	     (hbase == GRAPH_VERTEX_NONE)))
-	    break;			/* no base vertex, no more windows. */
-
-	if ((gconn != GRAPH_VERTEX_NONE) &&
-	    (gbase == GRAPH_VERTEX_NONE) &&
-	    ((GRAPH_SUCCESS !=
-	      hwgraph_path_add(gconn, PCIBA_EDGE_LBL_BASE, &gbase)) ||
-	     (gbase == GRAPH_VERTEX_NONE)))
-	    break;			/* no base vertex, no more windows. */
-
-	pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hbase, gbase, PCIBA_EDGE_LBL_WIN(win));
-
-	if (space == PCIIO_SPACE_IO) {
-	    if (!iwins++) {
-		pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hconn, gconn, PCIBA_EDGE_LBL_IO);
-	    }
-	} else {
-	    if (!mwins++) {
-		pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hconn, gconn, PCIBA_EDGE_LBL_MEM);
-	    }
+		if (register_pci_device(device_dir_handle, dev) == failure) {
+			devfs_unregister(pciba_devfs_handle);
+			return failure;
+		}
 	}
 
-	if ((base & 7) == 4)
-	    win++;
-    }
-
-    pciba_sub_attach(comm, PCIIO_SPACE_CFG, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_CFG);
-    pciba_sub_attach(comm, PCIBA_SPACE_UDMA, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_DMA);
-#if ULI
-    pciba_sub_attach(comm, PCIIO_SPACE_NONE, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_INTR);
-#endif
+	return success;
+}
 
-    /* XXX should ignore if device is an IOC3 */
-    if (ht == 0x01)
-	base = pciio_config_get(hconn, PCI_EXPANSION_ROM+8, 4);
-    else
-	base = pciio_config_get(hconn, PCI_EXPANSION_ROM, 4);
-
-    base &= 0xFFFFF000;
-
-    if (base) {
-	if (base & (_PAGESZ - 1))
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	    PRINT_WARNING("%v pciba: ROM is 0x%x\n"
-		    "\tnot page aligned, mmap will be difficult\n",
-		    hconn, base);
 #else
-	    PRINT_WARNING("0x%x pciba: ROM is 0x%x\n"
-		    "\tnot page aligned, mmap will be difficult\n",
-		    hconn, base);
-#endif
-	pciba_sub_attach(comm, PCIIO_SPACE_ROM, PCIIO_SPACE_MEM, base, hconn, gconn, PCIBA_EDGE_LBL_ROM);
-    }
 
-#if !FICUS	/* FICUS shorts the refct by one on path_add */
-    if (hbase != GRAPH_VERTEX_NONE)
-	hwgraph_vertex_unref(hbase);
+extern devfs_handle_t
+devfn_to_vertex(unsigned char busnum, unsigned int devfn);
 
-    if (gbase != GRAPH_VERTEX_NONE)
-	hwgraph_vertex_unref(gbase);
-#endif
+static status __init
+register_with_devfs(void)
+{
+	struct pci_dev * dev;
+	devfs_handle_t device_dir_handle;
 
-    return 0;
-}
+	TRACE();
 
-static void
-pciba_sub_attach2(pciba_comm_t comm,
-		  pciio_space_t space,
-		  pciio_space_t iomem,
-		  pciaddr_t base,
-		  devfs_handle_t from,
-		  char *name,
-		  char *suf,
-		  unsigned bigend)
-{
-    char		nbuf[128];
-    pciba_soft_t            soft;
-    devfs_handle_t	handle = NULL;
-
-    if (suf && *suf) {
-	strcpy(nbuf, name);
-	name = nbuf;
-	strcat(name, suf);
-    }
-
-#if DEBUG_PCIBA
-    printk("pciba_sub_attach2 %p/%s %p at %p[%x]\n",
-	   from, name, space, space_desc, iomem, space_desc, base, from, name);
-#endif
+	/* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
 
-    if (space < TRACKED_SPACES)
-	if ((soft = comm->soft[space][bigend]) != NULL) {
-	    soft->refct ++;
-	    hwgraph_edge_add(from, soft->vhdl, name);
-	    return;
+	pci_for_each_dev(dev) {
+		device_dir_handle = devfn_to_vertex(dev->bus->number,
+						    dev->devfn);
+		if (device_dir_handle == NULL)
+			return failure;
+	
+		if (register_pci_device(device_dir_handle, dev) == failure) {
+			devfs_unregister(pciba_devfs_handle);
+			return failure;
+		}
 	}
 
-    NEW(soft);
-    if (!soft)
-	return;
-
-    soft->comm = comm;
-    soft->space = space;
-    soft->size = 0;
-    soft->iomem = iomem;
-    soft->base = base;
-    soft->refct = 1;
-
-    if (space == PCIIO_SPACE_NONE)
-	soft->flags = 0;
-    else if (bigend)
-	soft->flags = PCIIO_BYTE_STREAM;
-    else
-	soft->flags = PCIIO_WORD_VALUES;
-
-    handle = hwgraph_register(from, name,
-		0, DEVFS_FL_AUTO_DEVNUM,
-		0, 0,
-		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-		&pciba_fops, NULL);
-    soft->vhdl = handle;
-    pciba_soft_set(soft->vhdl, soft);
-    if (space < TRACKED_SPACES)
-	comm->soft[space][bigend] = soft;
-    comm->refct ++;
+	return success;
 }
 
-static void
-pciba_sub_attach1(pciba_comm_t comm,
-		  pciio_space_t space,
-		  pciio_space_t iomem,
-		  pciaddr_t base,
-		  devfs_handle_t hfrom,
-		  devfs_handle_t gfrom,
-		  char *name,
-		  char *suf,
-		  unsigned bigend)
-{
-    pciba_sub_attach2(comm, space, iomem, base, hfrom, name, suf, bigend);
-    if ((gfrom != GRAPH_VERTEX_NONE) && (gfrom != hfrom))
-	pciba_sub_attach2(comm, space, iomem, base, gfrom, name, suf, bigend);
-}
+#endif /* CONFIG_IA64_SGI_SN1 */
+
+
+static void __exit
+unregister_with_devfs(void)
+{
+	struct list_head * lhp;
+	struct node_data * nd;
+	
+	TRACE();
+
+	list_for_each(lhp, &global_node_list) {
+		nd = list_entry(lhp, struct node_data, global_node_list);
+		devfs_unregister(nd->devfs_handle);
+	}
 
-static void
-pciba_sub_attach(pciba_comm_t comm,
-		 pciio_space_t space,
-		 pciio_space_t iomem,
-		 pciaddr_t base,
-		 devfs_handle_t hfrom,
-		 devfs_handle_t gfrom,
-		 char *name)
-{
-    pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, NULL, 0);
-    if (iomem != PCIIO_SPACE_NONE) {
-	pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, "_le", 0);
-	pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, "_be", 1);
-    }
 }
 
-#ifdef LATER
-static void
-pciba_reload_me(devfs_handle_t pconn_vhdl)
+
+struct node_data * new_node(void)
 {
-    devfs_handle_t            vhdl;
+	struct node_data * node;
+	
+	TRACE();
+	
+	node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
+	if (node == NULL)
+		return NULL;
+	list_add(&node->global_node_list, &global_node_list);
+	return node;
+}
 
-#if DEBUG_PCIBA
-    printf("pciba_reload_me(%v)\n", pconn_vhdl);
-#endif
 
-    if (GRAPH_SUCCESS !=
-	hwgraph_traverse(pconn_vhdl, PCIBA_EDGE_LBL_CFG, &vhdl))
-	return;
+void dma_cleanup(struct node_data * dma_node)
+{
+	TRACE();
 
-    hwgraph_vertex_unref(vhdl);
+	/* FIXME: should free these allocations */
+#ifdef DEBUG_PCIBA
+	dump_allocations(&dma_node->u.dma.dma_allocs);
+#endif
+	devfs_unregister(dma_node->devfs_handle);
 }
-#endif	/* LATER */
 
-static                  pciba_bus_t
-pciba_find_bus(devfs_handle_t pconn, int cflag)
+
+void init_dma_node(struct node_data * node,
+		   struct pci_dev * dev, devfs_handle_t dh)
 {
-    pciio_info_t            pciio_info;
-    devfs_handle_t          master;
-    arbitrary_info_t        ainfo;
-    pciba_bus_t             bus;
+	TRACE();
 
-    pciio_info = pciio_info_get(pconn);
-    master = pciio_info_master_get(pciio_info);
+	node->devfs_handle = dh;
+	node->u.dma.dev = dev;
+	node->cleanup = dma_cleanup;
+	INIT_LIST_HEAD(&node->u.dma.dma_allocs);
+}
 
-    if (GRAPH_SUCCESS ==
-	hwgraph_info_get_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo))
-	return (pciba_bus_t) ainfo;
 
-    if (!cflag)
-	return 0;
+void rom_cleanup(struct node_data * rom_node)
+{
+	TRACE();
 
-    NEW(bus);
-    if (!bus)
-	return 0;
+	if (rom_node->u.rom.mmapped)
+		pci_write_config_dword(rom_node->u.rom.dev,
+				       PCI_ROM_ADDRESS,
+				       rom_node->u.rom.saved_rom_base_reg);
+	devfs_unregister(rom_node->devfs_handle);
+}
 
-    sema_init(&bus->lock, 1);
 
-    ainfo = (arbitrary_info_t) bus;
-    hwgraph_info_add_LBL(master, PCIBA_INFO_LBL_BUS, ainfo);
-    hwgraph_info_get_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo);
-    if ((pciba_bus_t) ainfo != bus)
-	DEL(bus);
-#if DEBUG_PCIBA
-    else
-	printk("pcbia_find_bus: new bus at %p\n", master);
-#endif
+void init_rom_node(struct node_data * node,
+		   struct pci_dev * dev, devfs_handle_t dh)
+{
+	TRACE();
 
-    return (pciba_bus_t) ainfo;
+	node->devfs_handle = dh;
+	node->u.rom.dev = dev;
+	node->cleanup = rom_cleanup;
+	node->u.rom.mmapped = false;
 }
 
-#ifdef LATER
-static void
-pciba_map_push(pciba_bus_t bus, pciba_map_t map)
+
+static status __init
+register_pci_device(devfs_handle_t device_dir_handle, struct pci_dev * dev)
 {
-#if DEBUG_PCIBA
-    printk("pciba_map_push(bus=0x%x, map=0x%x, hdl=0x%x\n",
-	   bus, map, map->handle);
-#endif
-    pciba_bus_lock(bus);
-    map->next = bus->maps;
-    bus->maps = map;
-    pciba_bus_unlock(bus);
-}
-
-static                  pciba_map_t
-pciba_map_pop_hdl(pciba_bus_t bus, __psunsigned_t handle)
-{
-    pciba_map_h             hdl;
-    pciba_map_t             map;
-
-    pciba_bus_lock(bus);
-    for (hdl = &bus->maps; map = *hdl; hdl = &map->next)
-	if (map->handle == handle) {
-	    *hdl = map->next;
-	    break;
+	struct node_data * nd;
+	char devfs_path[20];
+	devfs_handle_t node_devfs_handle;
+	int ri;
+
+	TRACE();
+
+
+	/* register nodes for all the device's base address registers */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (pci_resource_len(dev, ri) != 0) {
+			sprintf(devfs_path, "base/%d", ri);
+			if (devfs_register(device_dir_handle, devfs_path,
+					   DEVFS_FL_NONE,
+					   0, 0,
+					   S_IFREG | S_IRUSR | S_IWUSR,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+		}
 	}
-    pciba_bus_unlock(bus);
-#if DEBUG_PCIBA
-    printk("pciba_map_pop_va(bus=0x%x, handle=0x%x) returns map=0x%x\n",
-	   bus, handle, map);
+	
+	/* register a node corresponding to the first MEM resource on
+           the device */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (dev->resource[ri].flags & IORESOURCE_MEM &&
+		    pci_resource_len(dev, ri) != 0) {
+			if (devfs_register(device_dir_handle, "mem",
+					   DEVFS_FL_NONE, 0, 0,
+					   S_IFREG | S_IRUSR | S_IWUSR,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+			break;
+		}
+	}
+
+	/* also register a node corresponding to the first IO resource
+           on the device */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (dev->resource[ri].flags & IORESOURCE_IO &&
+		    pci_resource_len(dev, ri) != 0) {
+			if (devfs_register(device_dir_handle, "io",
+					   DEVFS_FL_NONE, 0, 0,
+					   S_IFREG | S_IRUSR | S_IWUSR,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+			break;
+		}
+	}
+
+	/* register a node corresponding to the device's ROM resource,
+           if present */
+	if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
+		nd = new_node();
+		if (nd == NULL)
+			return failure;
+		node_devfs_handle = devfs_register(device_dir_handle, "rom",
+						   DEVFS_FL_NONE, 0, 0,
+						   S_IFREG | S_IRUSR,
+						   &rom_fops, nd);
+		if (node_devfs_handle == NULL)
+			return failure;
+		init_rom_node(nd, dev, node_devfs_handle);
+	}
+
+	/* register a node that allows ioctl's to read and write to
+           the device's config space */
+	if (devfs_register(device_dir_handle, "config", DEVFS_FL_NONE,
+			   0, 0, S_IFREG | S_IRUSR | S_IWUSR,
+			   &config_fops, dev) == NULL)
+		return failure;
+
+
+	/* finally, register a node that allows ioctl's to allocate
+           and free DMA buffers, as well as memory map those
+           buffers. */
+	nd = new_node();
+	if (nd == NULL)
+		return failure;
+	node_devfs_handle =
+		devfs_register(device_dir_handle, "dma", DEVFS_FL_NONE,
+			       0, 0, S_IFREG | S_IRUSR | S_IWUSR,
+			       &dma_fops, nd);
+	if (node_devfs_handle == NULL)
+		return failure;
+	init_dma_node(nd, dev, node_devfs_handle);
+
+#ifdef DEBUG_PCIBA
+	dump_nodes(&global_node_list);
 #endif
-    return map;
+	
+	return success;
 }
 
-/* ================================================================
- *            driver teardown, unregister and unload
- */
-int
-pciba_unload(void)
-{
-#if DEBUG_PCIBA
-    printk("pciba_unload()\n");
-#endif
 
-    if (atomic_read(&pciba_prevent_unload))
-	return -1;
+static int
+generic_open(struct inode * inode, struct file * file)
+{
+	TRACE();
 
-    pciio_iterate("pciba_", pciba_unload_me);
+	/* FIXME: should check that they're not trying to open the ROM
+           writable */
 
-    return 0;
+	return 0; /* success */
 }
 
-int
-pciba_unreg(void)
+
+static int
+rom_mmap(struct file * file, struct vm_area_struct * vma)
 {
+	unsigned long pci_pa;
+	struct node_data * nd;
 
-#if DEBUG_PCIBA
-    printf("pciba_unreg()\n");
-#endif
+	TRACE();
 
-    if (atomic_read(&pciba_prevent_unload))
-	return -1;
+	nd = (struct node_data * )file->private_data;
 
-    pciio_driver_unregister("pciba_");
-    return 0;
+	pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE);
+
+	if (!nd->u.rom.mmapped) {
+		nd->u.rom.mmapped = true;
+		DPRINTF("Enabling ROM address decoder.\n");
+		DPRINTF(
+"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n"
+"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n");
+		pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				      &nd->u.rom.saved_rom_base_reg);
+		DPRINTF("ROM base address contains %x\n",
+			nd->u.rom.saved_rom_base_reg);
+		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				       nd->u.rom.saved_rom_base_reg |
+				       PCI_ROM_ADDRESS_ENABLE);
+	}
+	
+	return mmap_pci_address(vma, pci_pa);
 }
 
-int
-pciba_detach(devfs_handle_t conn)
+
+static int
+rom_release(struct inode * inode, struct file * file)
 {
-    devfs_handle_t          base;
-    pciba_bus_t             bus;
-    devfs_handle_t          gconn;
-    devfs_handle_t          gbase;
+	struct node_data * nd;
 
-    pciio_info_t            pciio_info;
-    devfs_handle_t          master;
-    arbitrary_info_t        ainfo;
-    int			    ret;
+	TRACE();
 
-#if DEBUG_PCIBA
-    printf("pciba_detach(%v)\n", conn);
-#endif
+	nd = (struct node_data * )file->private_data;
 
-    if ((GRAPH_SUCCESS !=
-	 hwgraph_traverse(conn, ".guest", &gconn)) ||
-	(conn == gconn))
-	gconn = GRAPH_VERTEX_NONE;
-
-    if (gconn != GRAPH_VERTEX_NONE) {
-	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_CFG);
-	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_DMA);
-	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_ROM);
-#if ULI
-	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_INTR);
-#endif
-	if (GRAPH_SUCCESS == hwgraph_edge_remove(conn, PCIBA_EDGE_LBL_BASE, &gbase)) {
-	    pciba_sub_detach(gconn, PCIBA_EDGE_LBL_MEM);
-	    pciba_sub_detach(gconn, PCIBA_EDGE_LBL_IO);
-	    pciba_sub_detach(gbase, "0");
-	    pciba_sub_detach(gbase, "1");
-	    pciba_sub_detach(gbase, "2");
-	    pciba_sub_detach(gbase, "3");
-	    pciba_sub_detach(gbase, "4");
-	    pciba_sub_detach(gbase, "5");
-	    hwgraph_vertex_unref(gbase);
-	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(gbase))) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		PRINT_WARNING("pciba: hwgraph_vertex_destroy(%v/base) failed (%d)",
-			conn, ret);
-#else
-		PRINT_WARNING("pciba: hwgraph_vertex_destroy(0x%x/base) failed (%d)",
-			conn, ret);
-#endif
-#if DEBUG_REFCT
-		printk("\tretained refct %d\n", hwgraph_vertex_refct(gbase));
-#endif
-	    }
+	if (nd->u.rom.mmapped) {
+		nd->u.rom.mmapped = false;
+		DPRINTF("Disabling ROM address decoder.\n");
+		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				       nd->u.rom.saved_rom_base_reg);
 	}
-    }
+	return 0; /* indicate success */
+}
 
-    pciba_sub_detach(conn, PCIBA_EDGE_LBL_CFG);
-    pciba_sub_detach(conn, PCIBA_EDGE_LBL_DMA);
-    pciba_sub_detach(conn, PCIBA_EDGE_LBL_ROM);
-#if ULI
-    pciba_sub_detach(conn, PCIBA_EDGE_LBL_INTR);
-#endif
 
-    if (GRAPH_SUCCESS == hwgraph_edge_remove(conn, PCIBA_EDGE_LBL_BASE, &base)) {
-	pciba_sub_detach(conn, PCIBA_EDGE_LBL_MEM);
-	pciba_sub_detach(conn, PCIBA_EDGE_LBL_IO);
-	pciba_sub_detach(base, "0");
-	pciba_sub_detach(base, "1");
-	pciba_sub_detach(base, "2");
-	pciba_sub_detach(base, "3");
-	pciba_sub_detach(base, "4");
-	pciba_sub_detach(base, "5");
-	hwgraph_vertex_unref(base);
-	if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(base))) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	    PRINT_WARNING(CE_WARN, "pciba: hwgraph_vertex_destroy(%v/base) failed (%d)",
-		    conn, ret);
-#else
-	    PRINT_WARNING(CE_WARN, "pciba: hwgraph_vertex_destroy(0x%x/base) failed (%d)",
-		    conn, ret);
-#endif
-#if DEBUG_REFCT
-	    printk("\tretained refct %d\n", hwgraph_vertex_refct(base));
-#endif
-	}
-    }
+static int
+base_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	struct resource * resource;
 
-    bus = pciba_find_bus(conn, 0);
-    if (bus && !--(bus->refct)) {
+	TRACE();
 
-	pciio_info = pciio_info_get(conn);
+	resource = (struct resource *)file->private_data;
 
-	master = pciio_info_master_get(pciio_info);
+	return mmap_pci_address(vma, resource->start);
+}
 
-	pciba_sub_detach(master, PCIBA_EDGE_LBL_IO);
-	pciba_sub_detach(master, PCIBA_EDGE_LBL_MEM);
-	pciba_sub_detach(master, PCIBA_EDGE_LBL_CFG);
-	hwgraph_info_remove_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo);
 
-#if DEBUG_PCIBA
-	printf("pcbia_detach: DEL(bus) at %v\n", master);
-#endif
-	DEL(bus);
-    } 
+static int
+config_ioctl(struct inode * inode, struct file * file, 
+	     unsigned int cmd, 
+	     unsigned long arg)
+{
+	struct pci_dev * dev;
 
-    return 0;
-}
+	union cfg_data {
+		uint8_t byte;
+		uint16_t word;
+		uint32_t dword;
+	} read_data, write_data;
 
-static void
-pciba_sub_detach1(devfs_handle_t conn,
-		  char *name,
-		  char *suf)
-{
-    devfs_handle_t         vhdl;
-    pciba_soft_t            soft;
-    pciba_comm_t	    comm;
-    int			    ret;
-    char		nbuf[128];
-
-    if (suf && *suf) {
-	strcpy(nbuf, name);
-	name = nbuf;
-	strcat(name, suf);
-    }
-
-    if ((GRAPH_SUCCESS == hwgraph_edge_remove(conn, name, &vhdl)) &&
-	((soft = pciba_soft_get(vhdl)) != NULL)) {
-#if DEBUG_PCIBA
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	prink("pciba_sub_detach(%v,%s)\n", conn, name);
-#else
-	prink("pciba_sub_detach(0x%x,%s)\n", conn, name);
-#endif
-#endif
+	int dir, size, offset;
 
-	hwgraph_vertex_unref(soft->vhdl);
-#if DEBUG_REFCT
-	printk("\tadjusted refct %d (soft ref: %d)\n",
-		hwgraph_vertex_refct(vhdl),
-		soft->refct);
-#endif
-	if (!--(soft->refct)) {
-	    comm = soft->comm;
-	    if (!--(comm->refct)) {
-		DEL(comm);
-	    }
-	    pciba_soft_set(vhdl, 0);
-	    DEL(soft);
-
-	    hwgraph_vertex_unref(vhdl);
-	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(vhdl))) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		PRINT_WARNING("pciba: hwgraph_vertex_destroy(0x%x/%s) failed (%d)",
-			conn, name, ret);
-#else
-		PRINT_WARNING("pciba: hwgraph_vertex_destroy(%v/%s) failed (%d)",
-			conn, name, ret);
-#endif
-#if DEBUG_REFCT
-		printk("\tretained refct %d\n", hwgraph_vertex_refct(vhdl));
-#endif
-	    }
-	}
-    }
-}
+	TRACE();
 
-static void
-pciba_sub_detach(devfs_handle_t conn,
-		 char *name)
-{
-    pciba_sub_detach1(conn, name, "");
-    pciba_sub_detach1(conn, name, "_le");
-    pciba_sub_detach1(conn, name, "_be");
-}
+	DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", 
+		cmd, 
+		_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
+	DPRINTF("arg = %lx\n", arg);
 
-static void
-pciba_unload_me(devfs_handle_t pconn_vhdl)
-{
-    devfs_handle_t         c_vhdl;
+	dev = (struct pci_dev *)file->private_data;
 
-#if DEBUG_PCIBA
-    printf("pciba_unload_me(%v)\n", pconn_vhdl);
-#endif
+	/* PCIIOCCFG{RD,WR}: read and/or write PCI configuration
+	   space. If both, the read happens first (this becomes a swap
+	   operation, atomic with respect to other updates through
+	   this path).  */
 
-    if (GRAPH_SUCCESS !=
-	hwgraph_traverse(pconn_vhdl, PCIBA_EDGE_LBL_CFG, &c_vhdl))
-	return;
+	dir = _IOC_DIR(cmd);
 
-    hwgraph_vertex_unref(c_vhdl);
-}
+#define do_swap(suffix, type)	 					\
+	do {								\
+		if (dir & _IOC_READ) {					\
+			pci_read_config_##suffix(dev, _IOC_NR(cmd), 	\
+						 &read_data.suffix);	\
+		}							\
+		if (dir & _IOC_WRITE) {					\
+			get_user(write_data.suffix, (type)arg);		\
+			pci_write_config_##suffix(dev, _IOC_NR(cmd), 	\
+						  write_data.suffix);	\
+		}							\
+		if (dir & _IOC_READ) {					\
+			put_user(read_data.suffix, (type)arg);		\
+		}							\
+	} while (0)
 
-/* ================================================================
- *            standard unix entry points
- */
+	size = _IOC_SIZE(cmd);
+	offset = _IOC_NR(cmd);
 
-/*ARGSUSED */
-int
-pciba_open(dev_t *devp, int flag, int otyp, struct cred *crp)
-{
+	DPRINTF("sanity check\n");
+	if (((size > 0) || (size <= 4)) &&
+	    ((offset + size) <= 256) &&
+	    (dir & (_IOC_READ | _IOC_WRITE))) {
 
-#if DEBUG_PCIBA
-    printf("pciba_open(%V)\n", *devp);
-#endif
-    return 0;
+		switch (size)
+		{
+		case 1:
+			do_swap(byte, uint8_t *);
+			break;
+		case 2:
+			do_swap(word, uint16_t *);
+			break;
+		case 4:
+			do_swap(dword, uint32_t *);
+			break;
+		default:
+			DPRINTF("invalid ioctl\n");
+			return -EINVAL;
+		}
+	} else
+		return -EINVAL;
+		
+	return 0;
 }
 
-/*ARGSUSED */
-int
-pciba_close(dev_t dev)
-{
-    devfs_handle_t         vhdl = dev_to_vhdl(dev);
-    pciba_soft_t            soft = pciba_soft_get(vhdl);
-
-#if DEBUG_PCIBA
-    printf("pciba_close(%V)\n", dev);
-#endif
 
-    /* if there is pending DMA for this device, hit the
-     * device over the head with a baseball bat and
-     * release the system memory resources.
-     */
-    if (soft && soft->comm->dmap) {
-	pciba_dma_t             next;
-	pciba_dma_t             dmap;
-
-	pciba_soft_lock(soft);
-	if (dmap = soft->comm->dmap) {
-	    soft->comm->dmap = 0;
-
-	    pciio_reset(soft->comm->conn);
-
-	    do {
-		if (!dmap->kaddr)
-		    break;
-		if (!dmap->paddr)
-		    break;
-		if (dmap->bytes < NBPP)
-		    break;
-		next = dmap->next;
-		kvpfree(dmap->kaddr, dmap->bytes / NBPP);
-		dmap->paddr = 0;
-		dmap->bytes = 0;
-		DEL(dmap);
-	    } while (dmap = next);
+#ifdef DEBUG_PCIBA
+static void
+dump_allocations(struct list_head * dalp)
+{
+	struct dma_allocation * dap;
+	struct list_head * p;
+	
+	printk("{\n");
+	list_for_each(p, dalp) {
+		dap = list_entry(p, struct dma_allocation, 
+				 list);
+		printk("  handle = %lx, va = %p\n",
+		       dap->handle, dap->va);
 	}
-	pciba_soft_unlock(soft);
-    }
-    return 0;
+	printk("}\n");
 }
 
-/* ARGSUSED */
-int
-pciba_read(dev_t dev, cred_t *crp)
+static void
+dump_nodes(struct list_head * nodes)
 {
-#if DEBUG_PCIBA
-    printf("pciba_read(%V)\n", dev);
-#endif
-
-    return EINVAL;
+	struct node_data * ndp;
+	struct list_head * p;
+	
+	printk("{\n");
+	list_for_each(p, nodes) {
+		ndp = list_entry(p, struct node_data, 
+				 global_node_list);
+		printk("  %p\n", (void *)ndp);
+	}
+	printk("}\n");
 }
 
-/* ARGSUSED */
-int
-pciba_write(dev_t dev, cred_t *crp)
+
+#if 0
+#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
+
+static void
+test_list(void)
 {
-#if DEBUG_PCIBA
-    printf("pciba_write(%V)\n", dev);
-#endif
+	u64 i;
+	LIST_HEAD(the_list);
 
-    return EINVAL;
+	for (i = 0; i < 5; i++) {
+		struct dma_allocation * new_alloc;
+		NEW(new_alloc);
+		new_alloc->va = (void *)i;
+		new_alloc->handle = 5*i;
+		printk("%d - the_list->next = %lx\n", i, the_list.next);
+		list_add(&new_alloc->list, &the_list);
+	}
+	dump_allocations(&the_list);
 }
-
-/*ARGSUSED */
-int
-pciba_ioctl(dev_t dev, int cmd, void *uarg, int mode, cred_t *crp, int *rvalp)
-{
-    devfs_handle_t          vhdl;
-    pciba_soft_t            soft;
-    pciio_space_t           space;
-    ioctl_arg_buffer_t      arg;
-    int                     psize;
-    int                     err = 0;
-
-#if ULI
-    char		    abi = get_current_abi();
-    pciio_intr_t            intr=0;
-    device_desc_t           desc;
-    cpuid_t                 intrcpu;
-    unsigned                lines;
-    struct uli             *uli = 0;
 #endif
-    unsigned                flags;
-    void                   *kaddr = 0;
-    iopaddr_t               paddr;
-    pciba_dma_h             dmah;
-    pciba_dma_t             dmap = 0;
-    pciio_dmamap_t          dmamap = 0;
-    size_t                  bytes;
-    int                     pages;
-    pciaddr_t               daddr;
-
-#if DEBUG_PCIBA
-    printf("pciba_ioctl(%V,0x%x)\n", dev, cmd);
 #endif
 
-    psize = (cmd >> 16) & IOCPARM_MASK;
-
-#if ULI
-    ASSERT(sizeof(struct uliargs) > 8);	/* prevent CFG access conflict */
-    ASSERT(sizeof(struct uliargs) <= IOCPARM_MASK);
-#endif
 
-    arg.ca = uarg;
+static LIST_HEAD(dma_buffer_list);
 
-    if ((psize > 0) && (cmd & (IOC_OUT | IOC_IN))) {
-	if (psize > sizeof(arg))
-	    err = EINVAL;		/* "bad parameter size */
-	else {
-	    if (cmd & IOC_OUT)
-		bzero(arg.data, psize);
-	    if ((cmd & IOC_IN) &&
-		(copyin(uarg, arg.data, psize) < 0))
-		err = EFAULT;		/* "parameter copyin failed" */
-	}
-    }
-    vhdl = dev_to_vhdl(dev);
-    soft = pciba_soft_get(vhdl);
-    space = soft->space;
-
-    if (err == 0) {
-	err = EINVAL;			/* "invalid ioctl for this vertex" */
-	switch (space) {
-#if ULI
-	case PCIIO_SPACE_NONE:		/* the "intr" vertex */
-	    /* PCIIOCSETULI: set up user interrupts.
-	     */
-	    lines = cmd & 15;
-	    if (ABI_IS_64BIT(abi)) {
-		if (cmd != PCIIOCSETULI(lines)) {
-		    err = EINVAL;		/* "invalid ioctl for this vertex" */
-		    break;
-		}
-	    }
-	    else {
-		struct uliargs uliargs;
-
-		if (cmd != PCIIOCSETULI32(lines)) {
-		    err = EINVAL;		/* "invalid ioctl for this vertex" */
-		    break;
-		}
-		
-		uliargs32_to_uliargs(&arg.uli32, &uliargs);
-		arg.uli = uliargs;
-	    }
-	    desc = device_desc_dup(soft->comm->conn);
-	    device_desc_flags_set(desc, (device_desc_flags_get(desc) |
-					 D_INTR_NOTHREAD));
-	    device_desc_intr_swlevel_set(desc, INTR_SWLEVEL_NOTHREAD_DEFAULT);
-	    device_desc_intr_name_set(desc, "PCIBA");
-	    device_desc_default_set(soft->comm->conn, desc);
-
-	    /* When designating interrupts, the slot number
-	     * is taken from the connection point.
-	     * Bits 0..3 are used to select INTA..INTD; more
-	     * than one bit can be specified. These should
-	     * be constructed using PCIIO_INTR_LINE_[ABCD].
-	     */
-	    intr = pciio_intr_alloc
-		(soft->comm->conn, desc, lines, soft->vhdl);
-	    if (intr == 0) {
-		err = ENOMEM;		/* "insufficient resources" */
-		break;
-	    }
-	    intrcpu = cpuvertex_to_cpuid(pciio_intr_cpu_get(intr));
 
-	    if (err = new_uli(&arg.uli, &uli, intrcpu)) {
-		break;			/* "unable to set up ULI" */
-	    }
-	    atomic_inc(&pciba_prevent_unload);
-
-	    pciio_intr_connect(intr, pciba_intr, uli, (void *) 0);
-
-	    /* NOTE: don't set the teardown function
-	     * until the interrupt is connected.
-	     */
-	    uli->teardownarg1 = (__psint_t) intr;
-	    uli->teardown = pciba_clearuli;
-
-	    arg.uli.id = uli->index;
-
-	    if (!ABI_IS_64BIT(abi)) {
-		struct uliargs32 uliargs32;
-		uliargs_to_uliargs32(&arg.uli, &uliargs32);
-		arg.uli32 = uliargs32;
-	    }
+static int
+dma_ioctl(struct inode * inode, struct file * file, 
+	  unsigned int cmd, 
+	  unsigned long arg)
+{
+	struct node_data * nd;
+	uint64_t argv;
+	int result;
+	struct dma_allocation * dma_alloc;
+	struct list_head * iterp;
 
-	    err = 0;
-	    break;
-#endif
+	TRACE();
 
-	case PCIBA_SPACE_UDMA:		/* the "dma" vertex */
+	DPRINTF("cmd = %x\n", cmd);
+	DPRINTF("arg = %lx\n", arg);
 
-	    switch (cmd) {
+	nd = (struct node_data *)file->private_data;
 
-	    case PCIIOCDMAALLOC:
-		/* PCIIOCDMAALLOC: allocate a chunk of physical
-		 * memory and set it up for DMA. Return the
-		 * PCI address that gets to it.
-		 * NOTE: this allocates memory local to the
-		 * CPU doing the ioctl, not local to the
-		 * device that will be doing the DMA.
-		 */
-
-		if (!_CAP_ABLE(CAP_DEVICE_MGT)) {
-		    err = EPERM;
-		    break;
-		}
-		/* separate the halves of the incoming parameter */
-		flags = arg.ud >> 32;
-		bytes = arg.ud & 0xFFFFFFFF;
-
-#if DEBUG_PCIBA
-		printf("pciba: user wants 0x%x bytes of DMA, flags 0x%x\n",
-		       bytes, flags);
+#ifdef DEBUG_PCIBA
+	DPRINTF("at dma_ioctl entry\n");
+	dump_allocations(&nd->u.dma.dma_allocs);
 #endif
 
-		/* round up the requested size to the next highest page */
-		pages = (bytes + NBPP - 1) / NBPP;
-
-		/* make sure the requested size is something reasonable */
-		if (pages > pci_user_dma_max_pages) {
-#if DEBUG_PCIBA
-		    printf("pciba: request for too much buffer space\n");
+	switch (cmd) {
+	case PCIIOCDMAALLOC:
+		/* PCIIOCDMAALLOC: allocate a chunk of physical memory
+		   and set it up for DMA. Return the PCI address that
+		   gets to it.  */
+		DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC);
+		
+		if ( (result = get_user(argv, (uint64_t *)arg)) )
+			return result;
+		DPRINTF("argv (size of buffer) = %lx\n", argv);
+
+		dma_alloc = (struct dma_allocation *)
+			kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
+		if (dma_alloc == NULL)
+			return -ENOMEM;
+
+		dma_alloc->size = (size_t)argv;
+		dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev,
+						     dma_alloc->size,
+						     &dma_alloc->handle);
+		DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n",
+			dma_alloc->va, dma_alloc->handle);
+		if (dma_alloc->va == NULL) {
+			kfree(dma_alloc);
+			return -ENOMEM;
+		}
+
+		list_add(&dma_alloc->list, &nd->u.dma.dma_allocs);
+		if ( (result = put_user((uint64_t)dma_alloc->handle, 
+				      (uint64_t *)arg)) ) {
+			DPRINTF("put_user failed\n");
+			pci_free_consistent(nd->u.dma.dev, (size_t)argv,
+					    dma_alloc->va, dma_alloc->handle);
+			kfree(dma_alloc);
+			return result;
+		}
+
+#ifdef DEBUG_PCIBA
+		DPRINTF("after insertion\n");
+		dump_allocations(&nd->u.dma.dma_allocs);
 #endif
-		    err = EINVAL;
-		    break;		/* "request for too much buffer space" */
-		}
-		/* "correct" number of bytes */
-		bytes = pages * NBPP;
+		break;
 
-		/* allocate the space */
-		/* XXX- force to same node as the device? */
-		/* XXX- someday, we want to handle user buffers,
-		 *    and noncontiguous pages, but this will
-		 *      require either fancy mapping or handing
-		 *      a list of blocks back to the user. For
-		 *      now, just tell users to allocate a lot of
-		 *      individual single-pages and manage their
-		 *      scatter-gather manually.
-		 */
-		kaddr = kvpalloc(pages, VM_DIRECT | KM_NOSLEEP, 0);
-		if (kaddr == 0) {
-#if DEBUG_PCIBA
-		    printf("pciba: unable to get %d contiguous pages\n", pages);
-#endif
-		    err = EAGAIN;	/* "insufficient resources, try again later" */
-		    break;
-		}
-#if DEBUG_PCIBA
-		printf("pciba: kaddr is 0x%x\n", kaddr);
-#endif
-		paddr = kvtophys(kaddr);
+	case PCIIOCDMAFREE:
+		DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE);
 
-		daddr = pciio_dmatrans_addr
-		    (soft->comm->conn, 0, paddr, bytes, flags);
-		if (daddr == 0) {	/* "no direct path available" */
-#if DEBUG_PCIBA
-		    printf("pciba: dmatrans failed, trying dmamap\n");
-#endif
-		    dmamap = pciio_dmamap_alloc
-			(soft->comm->conn, 0, bytes, flags);
-		    if (dmamap == 0) {
-#if DEBUG_PCIBA
-			printf("pciba: unable to allocate dmamap\n");
-#endif
-			err = ENOMEM;
-			break;		/* "out of mapping resources" */
-		    }
-		    daddr = pciio_dmamap_addr
-			(dmamap, paddr, bytes);
-		    if (daddr == 0) {
-#if DEBUG_PCIBA
-			printf("pciba: dmamap_addr failed\n");
-#endif
-			err = EINVAL;
-			break;		/* "can't get there from here" */
-		    }
-		}
-#if DEBUG_PCIBA
-		printf("pciba: daddr is 0x%x\n", daddr);
+		if ( (result = get_user(argv, (uint64_t *)arg)) ) {
+			DPRINTF("get_user failed\n");
+			return result;
+		}
+
+		DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv);
+		list_for_each(iterp, &nd->u.dma.dma_allocs) {
+			struct dma_allocation * da =
+				list_entry(iterp, struct dma_allocation, list);
+			if (da->handle == argv) {
+				pci_free_consistent(nd->u.dma.dev, da->size,
+						    da->va, da->handle);
+				list_del(&da->list);
+				kfree(da);
+#ifdef DEBUG_PCIBA
+				DPRINTF("after deletion\n");
+				dump_allocations(&nd->u.dma.dma_allocs);
 #endif
-		NEW(dmap);
-		if (!dmap) {
-		    err = ENOMEM;
-		    break;		/* "no memory available" */
+				return 0; /* success */
+			}
 		}
-		dmap->bytes = bytes;
-		dmap->pages = pages;
-		dmap->paddr = paddr;
-		dmap->kaddr = kaddr;
-		dmap->map = dmamap;
-		dmap->daddr = daddr;
-		dmap->handle = 0;
-
-#if DEBUG_PCIBA
-		printf("pciba: dmap 0x%x contains va 0x%x bytes 0x%x pa 0x%x pages 0x%x daddr 0x%x\n",
-		       dmap, kaddr, bytes, paddr, pages, daddr);
-#endif
+		/* previously allocated dma buffer wasn't found */
+		DPRINTF("attempt to free invalid dma handle\n");
+		return -EINVAL;
 
-		arg.ud = dmap->daddr;
+	default:
+		DPRINTF("undefined ioctl\n");
+		return -EINVAL;
+	}
 
-		err = 0;
-		break;
+	DPRINTF("success\n");
+	return 0;
+}
+		
 
-	    case PCIIOCDMAFREE:
-		/* PCIIOCDMAFREE: Find the chunk of
-		 * User DMA memory, and release its
-		 * resources back to the system.
-		 */
-
-		if (!_CAP_ABLE(CAP_DEVICE_MGT)) {
-		    err = EPERM;	/* "you can't do that" */
-		    break;
-		}
-		if (soft->comm->dmap == NULL) {
-		    err = EINVAL;	/* "no User DMA to free" */
-		    break;
-		}
-		/* find the request. */
-		daddr = arg.ud;
-		err = EINVAL;		/* "block not found" */
-		pciba_soft_lock(soft);
-		for (dmah = &soft->comm->dmap; dmap = *dmah; dmah = &dmap->next) {
-		    if (dmap->daddr == daddr) {
-			if (dmap->handle != 0) {
-			    dmap = 0;	/* don't DEL this dmap! */
-			    err = EINVAL;	/* "please unmap first" */
-			    break;		/* break outa for loop. */
-			}
-			*dmah = dmap->next;
+static int
+dma_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	struct node_data * nd;
+	struct list_head * iterp;
+	int result;
+	
+	TRACE();
 
-			if (dmamap = dmap->map) {
-			    pciio_dmamap_free(dmamap);
-			    dmamap = 0;	/* don't free it twice! */
+	nd = (struct node_data *)file->private_data;
+	
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
+	DPRINTF("offset = %lx\n", vma->vm_pgoff);
+
+	/* get kernel virtual address for the dma buffer (necessary
+	 * for the mmap). */
+	list_for_each(iterp, &nd->u.dma.dma_allocs) {
+		struct dma_allocation * da =
+			list_entry(iterp, struct dma_allocation, list);
+		/* why does mmap shift its offset argument? */
+		if (da->handle == vma->vm_pgoff << PAGE_SHIFT) {
+			DPRINTF("found dma handle\n");
+			if ( (result = mmap_kernel_address(vma,
+							   da->va)) ) {
+				return result; /* failure */
+			} else {
+				/* it seems like at least one of these
+				   should show up in user land....
+				   I'm missing something */
+				*(char *)da->va = 0xaa;
+				strncpy(da->va, "        Toastie!", da->size);
+				if (put_user(0x18badbeeful,
+					     (u64 *)vma->vm_start))
+					DPRINTF("put_user failed?!\n");
+				return 0; /* success */
 			}
-			kvpfree(dmap->kaddr, dmap->bytes / NBPP);
-			DEL(dmap);
-			dmap = 0;	/* don't link this back into the list! */
-			err = 0;	/* "all done" */
-			break;		/* break outa for loop. */
-		    }
-		}
-		pciba_soft_unlock(soft);
-		break;		/* break outa case PCIIOCDMAFREE: */
-	    }
-	    break;		/* break outa case PCIBA_SPACE_UDMA: */
-
-	case PCIIO_SPACE_CFG:
-
-	    /* PCIIOCCFG{RD,WR}: read and/or write
-	     * PCI configuration space. If both,
-	     * the read happens first (this becomes
-	     * a swap operation, atomic with respect
-	     * to other updates through this path).
-	     *
-	     * Should be *last* IOCTl command checked,
-	     * so other patterns can nip useless codes
-	     * out of the space this decodes.
-	     */
-	    err = EINVAL;
-	    if ((psize > 0) || (psize <= 8) &&
-		(((cmd & 0xFF) + psize) <= 256) &&
-		(cmd & (IOC_IN | IOC_OUT))) {
-
-		uint64_t                rdata;
-		uint64_t                wdata;
-		int                     shft;
-
-		shft = 64 - (8 * psize);
-
-		wdata = arg.ud >> shft;
-
-		pciba_soft_lock(soft);
-
-		if (cmd & IOC_OUT)
-		    rdata = pciio_config_get(soft->comm->conn, cmd & 0xFFFF, psize);
-		if (cmd & IOC_IN)
-		    pciio_config_set(soft->comm->conn, cmd & 0xFFFF, psize, wdata);
-
-		pciba_soft_unlock(soft);
 
-		arg.ud = rdata << shft;
-		err = 0;
-		break;
-	    }
-	    break;
-	}
-    }
-    /* done: come here if all went OK.
-     */
-    if ((err == 0) &&
-	((cmd & IOC_OUT) && (psize > 0)) &&
-	copyout(arg.data, uarg, psize))
-	err = EFAULT;
-
-    /* This gets delayed until after the copyout so we
-     * do not free the dmap on a copyout error, or
-     * alternately end up with a dangling allocated
-     * buffer that the user never got back.
-     */
-    if ((err == 0) && dmap) {
-	pciba_soft_lock(soft);
-	dmap->next = soft->comm->dmap;
-	soft->comm->dmap = dmap;
-	pciba_soft_unlock(soft);
-    }
-    if (err) {
-	/* Things went badly. Clean up.
-	 */
-#if ULI
-	if (intr) {
-	    pciio_intr_disconnect(intr);
-	    pciio_intr_free(intr);
-	}
-	if (uli)
-	    free_uli(uli);
-#endif
-	if (dmap) {
-	    if (dmap->map && (dmap->map != dmamap))
-		pciio_dmamap_free(dmap->map);
-	    DEL(dmap);
+		}
 	}
-	if (dmamap)
-	    pciio_dmamap_free(dmamap);
-	if (kaddr)
-	    kvpfree(kaddr, pages);
-    }
-    return *rvalp = err;
+	DPRINTF("attempt to mmap an invalid dma handle\n");
+	return -EINVAL;
 }
 
-/* ================================================================
- *            mapping support
- */
-
-/*ARGSUSED */
-int
-pciba_map(dev_t dev, vhandl_t *vt,
-	  off_t off, size_t len, uint32_t prot)
-{
-    devfs_handle_t          vhdl = dev_to_vhdl(dev);
-    pciba_soft_t            soft = pciba_soft_get(vhdl);
-    devfs_handle_t          conn = soft->comm->conn;
-    pciio_space_t           space = soft->space;
-    size_t                  pages = (len + NBPP - 1) / NBPP;
-    pciio_piomap_t          pciio_piomap = 0;
-    caddr_t                 kaddr;
-    pciba_map_t             map;
-    pciba_dma_t             dmap;
 
-#if DEBUG_PCIBA
-    printf("pciba_map(%V,vt=0x%x)\n", dev, vt);
-#endif
+static int
+mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va)
+{
+	unsigned long pci_pa;
 
-    if (space == PCIBA_SPACE_UDMA) {
-	pciba_soft_lock(soft);
+	TRACE();
 
-	for (dmap = soft->comm->dmap; dmap != NULL; dmap = dmap->next) {
-	    if (off == dmap->daddr) {
-		if (pages != dmap->pages) {
-		    pciba_soft_unlock(soft);
-		    return EINVAL;	/* "size mismatch" */
-		}
-		v_mapphys(vt, dmap->kaddr, dmap->bytes);
-		dmap->handle = v_gethandle(vt);
-		pciba_soft_unlock(soft);
-#if DEBUG_PCIBA
-		printf("pciba: mapped dma at kaddr 0x%x via handle 0x%x\n",
-		       dmap->kaddr, dmap->handle);
-#endif
-		return 0;
-	    }
-	}
-	pciba_soft_unlock(soft);
-	return EINVAL;			/* "block not found" */
-    }
-    if (soft->iomem == PCIIO_SPACE_NONE)
-	return EINVAL;			/* "mmap not supported" */
-
-    kaddr = (caddr_t) pciio_pio_addr
-	(conn, 0, space, off, len, &pciio_piomap, soft->flags | PCIIO_FIXED );
-
-#if DEBUG_PCIBA
-    printf("pciba: mapped %R[0x%x..0x%x] via map 0x%x to kaddr 0x%x\n",
-	   space, space_desc, off, off + len - 1, pciio_piomap, kaddr);
-#endif
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
 
-    if (kaddr == NULL)
-	return EINVAL;			/* "you can't get there from here" */
+	/* the size of the vma doesn't necessarily correspond to the
+           size specified in the mmap call.  So we can't really do any
+           kind of sanity check here.  This is a dangerous driver, and
+           it's very easy for a user process to kill the machine.  */
 
-    NEW(map);
-    if (map == NULL) {
-	if (pciio_piomap)
-	    pciio_piomap_free(pciio_piomap);
-	return ENOMEM;			/* "unable to get memory resources */
-    }
-#ifdef LATER
-    map->uthread = curuthread;
-#endif
-    map->handle = v_gethandle(vt);
-    map->uvaddr = v_getaddr(vt);
-    map->map = pciio_piomap;
-    map->space = soft->iomem;
-    map->base = soft->base + off;
-    map->size = len;
-    pciba_map_push(soft->comm->bus, map);
-
-    /* Inform the system of the correct
-     * kvaddr corresponding to the thing
-     * that is being mapped.
-     */
-    v_mapphys(vt, kaddr, len);
-
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pciba_unmap(dev_t dev, vhandl_t *vt)
-{
-    devfs_handle_t         vhdl = dev_to_vhdl(dev);
-    pciba_soft_t            soft = pciba_soft_get(vhdl);
-    pciba_bus_t             bus = soft->comm->bus;
-    pciba_map_t             map;
-    __psunsigned_t          handle = v_gethandle(vt);
+	DPRINTF("PCI base at virtual address %lx\n", pci_va);
+	/* the __pa macro is intended for region 7 on IA64, so it
+	   doesn't work for region 6 */
+  	/* pci_pa = __pa(pci_va); */
+	/* should be replaced by __tpa or equivalent (preferably a
+	   generic equivalent) */
+	pci_pa = pci_va & ~0xe000000000000000ul;
+	DPRINTF("PCI base at physical address %lx\n", pci_pa);
 
-#if DEBUG_PCIBA
-    printf("pciba_unmap(%V,vt=%x)\n", dev, vt);
-#endif
+	/* there are various arch-specific versions of this function
+           defined in linux/drivers/char/mem.c, but it would be nice
+           if all architectures put it in pgtable.h.  it's defined
+           there for ia64.... */
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
-    /* If this is a userDMA buffer,
-     * make a note that it has been unmapped
-     * so it can be released.
-     */
-    if (soft->comm->dmap) {
-	pciba_dma_t             dmap;
-
-	pciba_soft_lock(soft);
-	for (dmap = soft->comm->dmap; dmap != NULL; dmap = dmap->next)
-	    if (handle == dmap->handle) {
-		dmap->handle = 0;
-		pciba_soft_unlock(soft);
-#if DEBUG_PCIBA
-		printf("pciba: unmapped dma at kaddr 0x%x via handle 0x%x\n",
-		       dmap->kaddr, handle);
-#endif
-		return 0;		/* found userPCI */
-	    }
-	pciba_soft_unlock(soft);
-    }
-    map = pciba_map_pop_hdl(bus, handle);
-    if (map == NULL)
-	return EINVAL;			/* no match */
+	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
 
-    if (map->map)
-	pciio_piomap_free(map->map);
-    DEL(map);
-
-    return (0);				/* all done OK */
+	return io_remap_page_range(vma->vm_start, pci_pa, 
+				   vma->vm_end-vma->vm_start,
+				   vma->vm_page_prot);
 }
 
-#if ULI
-void
-pciba_clearuli(struct uli *uli)
+
+static int
+mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va)
 {
-    pciio_intr_t            intr = (pciio_intr_t) uli->teardownarg1;
+	unsigned long kernel_pa;
 
-#if DEBUG_PCIBA
-    printf("pciba_clearuli(0x%x)\n", uli);
-#endif
+	TRACE();
 
-    pciio_intr_disconnect(intr);
-    pciio_intr_free(intr);
-    atomic_dec(&pciba_prevent_unload);
-}
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
 
-void
-pciba_intr(intr_arg_t arg)
-{
-    struct uli             *uli = (struct uli *) arg;
-    int                     ulinum = uli->index;
+	/* the size of the vma doesn't necessarily correspond to the
+           size specified in the mmap call.  So we can't really do any
+           kind of sanity check here.  This is a dangerous driver, and
+           it's very easy for a user process to kill the machine.  */
 
-    extern void frs_handle_uli(void);
+	DPRINTF("mapping virtual address %p\n", kernel_va);
+	kernel_pa = __pa(kernel_va);
+	DPRINTF("mapping physical address %lx\n", kernel_pa);
 
-    if (ulinum >= 0 && ulinum < MAX_ULIS) {
-	    uli_callup(ulinum);
+	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
 
-	    if (private.p_frs_flags)
-		    frs_handle_uli();
-    }
-}
-#endif
-#endif /* LATER - undef as we implement each routine */
+	return remap_page_range(vma->vm_start, kernel_pa, 
+				vma->vm_end-vma->vm_start,
+				vma->vm_page_prot);
+}	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/pcibr.c linux/arch/ia64/sn/io/pcibr.c
--- linux.orig/arch/ia64/sn/io/pcibr.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/pcibr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,9824 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-#ifdef BRINGUP
-int NeedXbridgeSwap = 0;
-#endif
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/sn_private.h>
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/hubio.h>
-#include <asm/sn/sn1/hubio_next.h>
-#endif
-
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-#undef PCIBR_ATE_DEBUG
-#if defined(BRINGUP)
-#if 0
-#define DEBUG 1	 /* To avoid lots of bad printk() formats leave off */
-#endif
-#define PCI_DEBUG 1
-#define ATTACH_DEBUG 1
-#define PCIBR_SOFT_LIST 1
-#endif
-
-#ifndef	LOCAL
-#define	LOCAL		static
-#endif
-
-/*
- * Macros related to the Lucent USS 302/312 usb timeout workaround.  It
- * appears that if the lucent part can get into a retry loop if it sees a
- * DAC on the bus during a pio read retry.  The loop is broken after about
- * 1ms, so we need to set up bridges holding this part to allow at least
- * 1ms for pio.
- */
-
-#define USS302_TIMEOUT_WAR
-
-#ifdef USS302_TIMEOUT_WAR
-#include <asm/sn/io.h>
-#define LUCENT_USBHC_VENDOR_ID_NUM	0x11c1
-#define LUCENT_USBHC302_DEVICE_ID_NUM	0x5801
-#define LUCENT_USBHC312_DEVICE_ID_NUM	0x5802
-#define USS302_BRIDGE_TIMEOUT_HLD	4
-#endif
-
-#define PCIBR_LLP_CONTROL_WAR
-#if defined (PCIBR_LLP_CONTROL_WAR)
-int                     pcibr_llp_control_war_cnt;
-#endif				/* PCIBR_LLP_CONTROL_WAR */
-
-#define	NEWAf(ptr,n,f)	(ptr = kmem_zalloc((n)*sizeof (*(ptr)), (f&PCIIO_NOSLEEP)?KM_NOSLEEP:KM_SLEEP))
-#define NEWA(ptr,n)	(ptr = kmem_zalloc((n)*sizeof (*(ptr)), KM_SLEEP))
-#define DELA(ptr,n)	(kfree(ptr))
-
-#define NEWf(ptr,f)	NEWAf(ptr,1,f)
-#define NEW(ptr)	NEWA(ptr,1)
-#define DEL(ptr)	DELA(ptr,1)
-
-int                     pcibr_devflag = D_MP;
-
-#ifdef LATER
-#define F(s,n)		{ 1l<<(s),-(s), n }
-
-struct reg_desc         bridge_int_status_desc[] =
-{
-    F(31, "MULTI_ERR"),
-    F(30, "PMU_ESIZE_EFAULT"),
-    F(29, "UNEXPECTED_RESP"),
-    F(28, "BAD_XRESP_PACKET"),
-    F(27, "BAD_XREQ_PACKET"),
-    F(26, "RESP_XTALK_ERROR"),
-    F(25, "REQ_XTALK_ERROR"),
-    F(24, "INVALID_ADDRESS"),
-    F(23, "UNSUPPORTED_XOP"),
-    F(22, "XREQ_FIFO_OFLOW"),
-    F(21, "LLP_REC_SNERROR"),
-    F(20, "LLP_REC_CBERROR"),
-    F(19, "LLP_RCTY"),
-    F(18, "LLP_TX_RETRY"),
-    F(17, "LLP_TCTY"),
-    F(16, "SSRAM_PERR"),
-    F(15, "PCI_ABORT"),
-    F(14, "PCI_PARITY"),
-    F(13, "PCI_SERR"),
-    F(12, "PCI_PERR"),
-    F(11, "PCI_MASTER_TOUT"),
-    F(10, "PCI_RETRY_CNT"),
-    F(9, "XREAD_REQ_TOUT"),
-    F(8, "GIO_BENABLE_ERR"),
-    F(7, "INT7"),
-    F(6, "INT6"),
-    F(5, "INT5"),
-    F(4, "INT4"),
-    F(3, "INT3"),
-    F(2, "INT2"),
-    F(1, "INT1"),
-    F(0, "INT0"),
-    {0}
-};
-
-struct reg_values       space_v[] =
-{
-    {PCIIO_SPACE_NONE, "none"},
-    {PCIIO_SPACE_ROM, "ROM"},
-    {PCIIO_SPACE_IO, "I/O"},
-    {PCIIO_SPACE_MEM, "MEM"},
-    {PCIIO_SPACE_MEM32, "MEM(32)"},
-    {PCIIO_SPACE_MEM64, "MEM(64)"},
-    {PCIIO_SPACE_CFG, "CFG"},
-    {PCIIO_SPACE_WIN(0), "WIN(0)"},
-    {PCIIO_SPACE_WIN(1), "WIN(1)"},
-    {PCIIO_SPACE_WIN(2), "WIN(2)"},
-    {PCIIO_SPACE_WIN(3), "WIN(3)"},
-    {PCIIO_SPACE_WIN(4), "WIN(4)"},
-    {PCIIO_SPACE_WIN(5), "WIN(5)"},
-    {PCIIO_SPACE_BAD, "BAD"},
-    {0}
-};
-
-struct reg_desc         space_desc[] =
-{
-    {0xFF, 0, "space", 0, space_v},
-    {0}
-};
-
-#if DEBUG
-#define	device_desc	device_bits
-LOCAL struct reg_desc   device_bits[] =
-{
-    {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
-    {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
-    {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"},
-    {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"},
-    {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"},
-    {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"},
-    {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"},
-    {BRIDGE_DEV_RT, 0, "RT"},
-    {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"},
-    {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"},
-    {BRIDGE_DEV_PREF, 0, "PREF"},
-    {BRIDGE_DEV_PRECISE, 0, "PRECISE"},
-    {BRIDGE_DEV_COH, 0, "COH"},
-    {BRIDGE_DEV_BARRIER, 0, "BARRIER"},
-    {BRIDGE_DEV_GBR, 0, "GBR"},
-    {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"},
-    {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"},
-    {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"},
-    {0}
-};
-#endif	/* DEBUG */
-
-#ifdef SUPPORT_PRINTING_R_FORMAT
-LOCAL struct reg_values xio_cmd_pactyp[] =
-{
-    {0x0, "RdReq"},
-    {0x1, "RdResp"},
-    {0x2, "WrReqWithResp"},
-    {0x3, "WrResp"},
-    {0x4, "WrReqNoResp"},
-    {0x5, "Reserved(5)"},
-    {0x6, "FetchAndOp"},
-    {0x7, "Reserved(7)"},
-    {0x8, "StoreAndOp"},
-    {0x9, "Reserved(9)"},
-    {0xa, "Reserved(a)"},
-    {0xb, "Reserved(b)"},
-    {0xc, "Reserved(c)"},
-    {0xd, "Reserved(d)"},
-    {0xe, "SpecialReq"},
-    {0xf, "SpecialResp"},
-    {0}
-};
-
-LOCAL struct reg_desc   xio_cmd_bits[] =
-{
-    {WIDGET_DIDN, -28, "DIDN", "%x"},
-    {WIDGET_SIDN, -24, "SIDN", "%x"},
-    {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp},
-    {WIDGET_TNUM, -15, "TNUM", "%x"},
-    {WIDGET_COHERENT, 0, "COHERENT"},
-    {WIDGET_DS, 0, "DS"},
-    {WIDGET_GBR, 0, "GBR"},
-    {WIDGET_VBPM, 0, "VBPM"},
-    {WIDGET_ERROR, 0, "ERROR"},
-    {WIDGET_BARRIER, 0, "BARRIER"},
-    {0}
-};
-#endif	/* SUPPORT_PRINTING_R_FORMAT */
-
-#if PCIBR_FREEZE_TIME || PCIBR_ATE_DEBUG
-LOCAL struct reg_desc   ate_bits[] =
-{
-    {0xFFFF000000000000ull, -48, "RMF", "%x"},
-    {~(IOPGSIZE - 1) &			/* may trim off some low bits */
-     0x0000FFFFFFFFF000ull, 0, "XIO", "%x"},
-    {0x0000000000000F00ull, -8, "port", "%x"},
-    {0x0000000000000010ull, 0, "Barrier"},
-    {0x0000000000000008ull, 0, "Prefetch"},
-    {0x0000000000000004ull, 0, "Precise"},
-    {0x0000000000000002ull, 0, "Coherent"},
-    {0x0000000000000001ull, 0, "Valid"},
-    {0}
-};
-#endif
-
-#if PCIBR_ATE_DEBUG
-LOCAL struct reg_values ssram_sizes[] =
-{
-    {BRIDGE_CTRL_SSRAM_512K, "512k"},
-    {BRIDGE_CTRL_SSRAM_128K, "128k"},
-    {BRIDGE_CTRL_SSRAM_64K, "64k"},
-    {BRIDGE_CTRL_SSRAM_1K, "1k"},
-    {0}
-};
-
-LOCAL struct reg_desc   control_bits[] =
-{
-    {BRIDGE_CTRL_FLASH_WR_EN, 0, "FLASH_WR_EN"},
-    {BRIDGE_CTRL_EN_CLK50, 0, "EN_CLK50"},
-    {BRIDGE_CTRL_EN_CLK40, 0, "EN_CLK40"},
-    {BRIDGE_CTRL_EN_CLK33, 0, "EN_CLK33"},
-    {BRIDGE_CTRL_RST_MASK, -24, "RST", "%x"},
-    {BRIDGE_CTRL_IO_SWAP, 0, "IO_SWAP"},
-    {BRIDGE_CTRL_MEM_SWAP, 0, "MEM_SWAP"},
-    {BRIDGE_CTRL_PAGE_SIZE, 0, "PAGE_SIZE"},
-    {BRIDGE_CTRL_SS_PAR_BAD, 0, "SS_PAR_BAD"},
-    {BRIDGE_CTRL_SS_PAR_EN, 0, "SS_PAR_EN"},
-    {BRIDGE_CTRL_SSRAM_SIZE_MASK, 0, "SSRAM_SIZE", 0, ssram_sizes},
-    {BRIDGE_CTRL_F_BAD_PKT, 0, "F_BAD_PKT"},
-    {BRIDGE_CTRL_LLP_XBAR_CRD_MASK, -12, "LLP_XBAR_CRD", "%d"},
-    {BRIDGE_CTRL_CLR_RLLP_CNT, 0, "CLR_RLLP_CNT"},
-    {BRIDGE_CTRL_CLR_TLLP_CNT, 0, "CLR_TLLP_CNT"},
-    {BRIDGE_CTRL_SYS_END, 0, "SYS_END"},
-    {BRIDGE_CTRL_MAX_TRANS_MASK, -4, "MAX_TRANS", "%d"},
-    {BRIDGE_CTRL_WIDGET_ID_MASK, 0, "WIDGET_ID", "%x"},
-    {0}
-};
-#endif
-#endif	/* LATER */
-
-/* kbrick widgetnum-to-bus layout */
-int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
-        0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
-        2,                                      /* 0x8          */
-        1,                                      /* 0x9          */
-        0, 0,                                   /* 0xa - 0xb    */
-        5,                                      /* 0xc          */
-        6,                                      /* 0xd          */
-        4,                                      /* 0xe          */
-        3,                                      /* 0xf          */
-};
-
-/*
- * Additional PIO spaces per slot are
- * recorded in this structure.
- */
-struct pciio_piospace_s {
-    pciio_piospace_t        next;	/* another space for this device */
-    char                    free;	/* 1 if free, 0 if in use               */
-    pciio_space_t           space;	/* Which space is in use                */
-    iopaddr_t               start;	/* Starting address of the PIO space    */
-    size_t                  count;	/* size of PIO space                    */
-};
-
-/* Use io spin locks. This ensures that all the PIO writes from a particular
- * CPU to a particular IO device are synched before the start of the next
- * set of PIO operations to the same device.
- */
-#define pcibr_lock(pcibr_soft)		io_splock(&pcibr_soft->bs_lock)
-#define pcibr_unlock(pcibr_soft,s)	io_spunlock(&pcibr_soft->bs_lock,s)
-
-#if PCIBR_SOFT_LIST
-typedef struct pcibr_list_s *pcibr_list_p;
-struct pcibr_list_s {
-    pcibr_list_p            bl_next;
-    pcibr_soft_t            bl_soft;
-    devfs_handle_t            bl_vhdl;
-};
-pcibr_list_p            pcibr_list = 0;
-#endif
-
-typedef volatile unsigned *cfg_p;
-typedef volatile bridgereg_t *reg_p;
-
-#define	INFO_LBL_PCIBR_ASIC_REV	"_pcibr_asic_rev"
-
-#define	PCIBR_D64_BASE_UNSET	(0xFFFFFFFFFFFFFFFF)
-#define	PCIBR_D32_BASE_UNSET	(0xFFFFFFFF)
-
-#define PCIBR_VALID_SLOT(s)	(s < 8)
-
-#ifdef SN_XXX
-extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
-                                     hub_widget_flags_t flags);
-#endif
-extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
-
-/*
- * This is the file operation table for the pcibr driver.
- * As each of the functions are implemented, put the 
- * appropriate function name below.
- */
-struct file_operations pcibr_fops = {
-        owner:  THIS_MODULE,
-        llseek: NULL,
-        read: NULL,
-        write: NULL,
-        readdir: NULL,
-        poll: NULL,
-        ioctl: NULL,
-        mmap: NULL,
-        open: NULL,
-        flush: NULL,
-        release: NULL,
-        fsync: NULL,
-        fasync: NULL,
-        lock: NULL,
-        readv: NULL,
-        writev: NULL
-};
-
-extern devfs_handle_t hwgraph_root;
-extern graph_error_t hwgraph_vertex_unref(devfs_handle_t vhdl);
-extern int cap_able(uint64_t x);
-extern uint64_t rmalloc(struct map *mp, size_t size);
-extern void rmfree(struct map *mp, size_t size, uint64_t a);
-extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-extern long atoi(register char *p);
-extern void *swap_ptr(void **loc, void *new);
-extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
-extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl);
-extern graph_error_t hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr);
-extern struct map *rmallocmap(uint64_t mapsiz);
-extern void rmfreemap(struct map *mp);
-extern int compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr);
-extern int io_path_map_widget(devfs_handle_t vertex);
-
-
-
-/* =====================================================================
- *    Function Table of Contents
- *
- *      The order of functions in this file has stopped
- *      making much sense. We might want to take a look
- *      at it some time and bring back some sanity, or
- *      perhaps bust this file into smaller chunks.
- */
-
-LOCAL void              do_pcibr_rrb_clear(bridge_t *, int);
-LOCAL void              do_pcibr_rrb_flush(bridge_t *, int);
-LOCAL int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t);
-LOCAL int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
-LOCAL int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int);
-LOCAL int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int);
-
-LOCAL void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int);
-
-int			pcibr_wrb_flush(devfs_handle_t);
-int                     pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-int                     pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
-int                     pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int);
-void                    pcibr_rrb_flush(devfs_handle_t);
-
-LOCAL int               pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
-void                    pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
-
-LOCAL void              pcibr_clearwidint(bridge_t *);
-LOCAL void              pcibr_setwidint(xtalk_intr_t);
-LOCAL int               pcibr_probe_slot(bridge_t *, cfg_p, unsigned *);
-
-void                    pcibr_init(void);
-int                     pcibr_attach(devfs_handle_t);
-int			pcibr_detach(devfs_handle_t);
-int                     pcibr_open(devfs_handle_t *, int, int, cred_t *);
-int                     pcibr_close(devfs_handle_t, int, int, cred_t *);
-int                     pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     pcibr_unmap(devfs_handle_t, vhandl_t *);
-int                     pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-void                    pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
-
-LOCAL int               pcibr_init_ext_ate_ram(bridge_t *);
-LOCAL int               pcibr_ate_alloc(pcibr_soft_t, int);
-LOCAL void              pcibr_ate_free(pcibr_soft_t, int, int);
-
-LOCAL pcibr_info_t      pcibr_info_get(devfs_handle_t);
-LOCAL pcibr_info_t      pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-LOCAL void		pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
-LOCAL iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-
-pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pcibr_piomap_free(pcibr_piomap_t);
-caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
-void                    pcibr_piomap_done(pcibr_piomap_t);
-caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-LOCAL iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
-LOCAL bridge_ate_t      pcibr_flags_to_ate(unsigned);
-
-pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pcibr_dmamap_free(pcibr_dmamap_t);
-LOCAL bridge_ate_p      pcibr_ate_addr(pcibr_soft_t, int);
-LOCAL iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
-iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
-alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
-void                    pcibr_dmamap_done(pcibr_dmamap_t);
-cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
-iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void                    pcibr_dmamap_drain(pcibr_dmamap_t);
-void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
-
-static unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines);
-pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pcibr_intr_free(pcibr_intr_t);
-LOCAL void              pcibr_setpciint(xtalk_intr_t);
-int                     pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t, void *);
-void                    pcibr_intr_disconnect(pcibr_intr_t);
-
-devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
-void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-void                    pcibr_intr_func(intr_arg_t);
-
-LOCAL void              print_bridge_errcmd(uint32_t, char *);
-
-void                    pcibr_error_dump(pcibr_soft_t);
-uint32_t              pcibr_errintr_group(uint32_t);
-LOCAL void		pcibr_pioerr_check(pcibr_soft_t);
-LOCAL void              pcibr_error_intr_handler(intr_arg_t);
-
-LOCAL int               pcibr_addr_toslot(pcibr_soft_t, iopaddr_t, pciio_space_t *, iopaddr_t *, pciio_function_t *);
-LOCAL void              pcibr_error_cleanup(pcibr_soft_t, int);
-void                    pcibr_device_disable(pcibr_soft_t, int);
-LOCAL int               pcibr_pioerror(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
-int                     pcibr_dmard_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
-int                     pcibr_dmawr_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
-LOCAL int               pcibr_error_handler(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *);
-int                     pcibr_error_devenable(devfs_handle_t, int);
-
-void                    pcibr_provider_startup(devfs_handle_t);
-void                    pcibr_provider_shutdown(devfs_handle_t);
-
-int                     pcibr_reset(devfs_handle_t);
-pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
-pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
-int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
-
-LOCAL cfg_p             pcibr_config_addr(devfs_handle_t, unsigned);
-uint64_t                pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-LOCAL uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
-void                    pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-LOCAL void              do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
-
-LOCAL pcibr_hints_t     pcibr_hints_get(devfs_handle_t, int);
-void                    pcibr_hints_fix_rrbs(devfs_handle_t);
-void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-void                    pcibr_hints_handsoff(devfs_handle_t);
-void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
-
-LOCAL int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
-
-#ifdef LATER
-LOCAL int	        pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t,
-                                               pcibr_slot_info_resp_t);
-LOCAL void       	pcibr_slot_func_info_return(pcibr_info_h, int,
-                                                    pcibr_slot_func_info_resp_t);
-#endif	/* LATER */
-
-LOCAL int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
-LOCAL int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_call_device_attach(devfs_handle_t,
-						      pciio_slot_t, int);
-LOCAL int		pcibr_slot_call_device_detach(devfs_handle_t,
-						      pciio_slot_t, int);
-
-LOCAL int               pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int);
-LOCAL int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
-#ifdef LATER
-LOCAL int		pcibr_slot_query(devfs_handle_t, pcibr_slot_info_req_t);
-#endif
-
-/* =====================================================================
- *    RRB management
- */
-
-#define LSBIT(word)		((word) &~ ((word)-1))
-
-#define PCIBR_RRB_SLOT_VIRTUAL	8
-
-LOCAL void
-do_pcibr_rrb_clear(bridge_t *bridge, int rrb)
-{
-    bridgereg_t             status;
-
-    /* bridge_lock must be held;
-     * this RRB must be disabled.
-     */
-
-    /* wait until RRB has no outstanduing XIO packets. */
-    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-	;				/* XXX- beats on bridge. bad idea? */
-    }
-
-    /* if the RRB has data, drain it. */
-    if (status & BRIDGE_RRB_VALID(rrb)) {
-	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-
-	/* wait until RRB is no longer valid. */
-	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-	    ;				/* XXX- beats on bridge. bad idea? */
-	}
-    }
-}
-
-LOCAL void
-do_pcibr_rrb_flush(bridge_t *bridge, int rrbn)
-{
-    reg_p                   rrbp = &bridge->b_rrb_map[rrbn & 1].reg;
-    bridgereg_t             rrbv;
-    int                     shft = 4 * (rrbn >> 1);
-    unsigned                ebit = BRIDGE_RRB_EN << shft;
-
-    rrbv = *rrbp;
-    if (rrbv & ebit)
-	*rrbp = rrbv & ~ebit;
-
-    do_pcibr_rrb_clear(bridge, rrbn);
-
-    if (rrbv & ebit)
-	*rrbp = rrbv;
-}
-
-/*
- *    pcibr_rrb_count_valid: count how many RRBs are
- *      marked valid for the specified PCI slot on this
- *      bridge.
- *
- *      NOTE: The "slot" parameter for all pcibr_rrb
- *      management routines must include the "virtual"
- *      bit; when manageing both the normal and the
- *      virtual channel, separate calls to these
- *      routines must be made. To denote the virtual
- *      channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot
- *      number.
- *
- *      IMPL NOTE: The obvious algorithm is to iterate
- *      through the RRB fields, incrementing a count if
- *      the RRB is valid and matches the slot. However,
- *      it is much simpler to use an algorithm derived
- *      from the "partitioned add" idea. First, XOR in a
- *      pattern such that the fields that match this
- *      slot come up "all ones" and all other fields
- *      have zeros in the mismatching bits. Then AND
- *      together the bits in the field, so we end up
- *      with one bit turned on for each field that
- *      matched. Now we need to count these bits. This
- *      can be done either with a series of shift/add
- *      instructions or by using "tmp % 15"; I expect
- *      that the cascaded shift/add will be faster.
- */
-
-LOCAL int
-do_pcibr_rrb_count_valid(bridge_t *bridge,
-			 pciio_slot_t slot)
-{
-    bridgereg_t             tmp;
-
-    tmp = bridge->b_rrb_map[slot & 1].reg;
-    tmp ^= 0x11111111 * (7 - slot / 2);
-    tmp &= (0xCCCCCCCC & tmp) >> 2;
-    tmp &= (0x22222222 & tmp) >> 1;
-    tmp += tmp >> 4;
-    tmp += tmp >> 8;
-    tmp += tmp >> 16;
-    return tmp & 15;
-}
-
-/*
- *    do_pcibr_rrb_count_avail: count how many RRBs are
- *      available to be allocated for the specified slot.
- *
- *      IMPL NOTE: similar to the above, except we are
- *      just counting how many fields have the valid bit
- *      turned off.
- */
-LOCAL int
-do_pcibr_rrb_count_avail(bridge_t *bridge,
-			 pciio_slot_t slot)
-{
-    bridgereg_t             tmp;
-
-    tmp = bridge->b_rrb_map[slot & 1].reg;
-    tmp = (0x88888888 & ~tmp) >> 3;
-    tmp += tmp >> 4;
-    tmp += tmp >> 8;
-    tmp += tmp >> 16;
-    return tmp & 15;
-}
-
-/*
- *    do_pcibr_rrb_alloc: allocate some additional RRBs
- *      for the specified slot. Returns -1 if there were
- *      insufficient free RRBs to satisfy the request,
- *      or 0 if the request was fulfilled.
- *
- *      Note that if a request can be partially filled,
- *      it will be, even if we return failure.
- *
- *      IMPL NOTE: again we avoid iterating across all
- *      the RRBs; instead, we form up a word containing
- *      one bit for each free RRB, then peel the bits
- *      off from the low end.
- */
-LOCAL int
-do_pcibr_rrb_alloc(bridge_t *bridge,
-		   pciio_slot_t slot,
-		   int more)
-{
-    int                     rv = 0;
-    bridgereg_t             reg, tmp, bit;
-
-    reg = bridge->b_rrb_map[slot & 1].reg;
-    tmp = (0x88888888 & ~reg) >> 3;
-    while (more-- > 0) {
-	bit = LSBIT(tmp);
-	if (!bit) {
-	    rv = -1;
-	    break;
-	}
-	tmp &= ~bit;
-	reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2)));
-    }
-    bridge->b_rrb_map[slot & 1].reg = reg;
-    return rv;
-}
-
-/*
- *    do_pcibr_rrb_free: release some of the RRBs that
- *      have been allocated for the specified
- *      slot. Returns zero for success, or negative if
- *      it was unable to free that many RRBs.
- *
- *      IMPL NOTE: We form up a bit for each RRB
- *      allocated to the slot, aligned with the VALID
- *      bitfield this time; then we peel bits off one at
- *      a time, releasing the corresponding RRB.
- */
-LOCAL int
-do_pcibr_rrb_free(bridge_t *bridge,
-		  pciio_slot_t slot,
-		  int less)
-{
-    int                     rv = 0;
-    bridgereg_t             reg, tmp, clr, bit;
-    int                     i;
-
-    clr = 0;
-    reg = bridge->b_rrb_map[slot & 1].reg;
-
-    /* This needs to be done otherwise the rrb's on the virtual channel
-     * for this slot won't be freed !!
-     */
-    tmp = reg & 0xbbbbbbbb;
-
-    tmp ^= (0x11111111 * (7 - slot / 2));
-    tmp &= (0x33333333 & tmp) << 2;
-    tmp &= (0x44444444 & tmp) << 1;
-    while (less-- > 0) {
-	bit = LSBIT(tmp);
-	if (!bit) {
-	    rv = -1;
-	    break;
-	}
-	tmp &= ~bit;
-	reg &= ~bit;
-	clr |= bit;
-    }
-    bridge->b_rrb_map[slot & 1].reg = reg;
-
-    for (i = 0; i < 8; i++)
-	if (clr & (8 << (4 * i)))
-	    do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1));
-
-    return rv;
-}
-
-LOCAL void
-do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft,
-		       int slot,
-		       int more_rrbs)
-{
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     got;
-
-    for (got = 0; got < more_rrbs; ++got) {
-	if (pcibr_soft->bs_rrb_res[slot & 7] > 0)
-	    pcibr_soft->bs_rrb_res[slot & 7]--;
-	else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
-	    pcibr_soft->bs_rrb_avail[slot & 1]--;
-	else
-	    break;
-	if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0)
-	    break;
-#if PCIBR_RRB_DEBUG
-	printk( "do_pcibr_rrb_autoalloc: add one to slot %d%s\n",
-		slot & 7, slot & 8 ? "v" : "");
-#endif
-	pcibr_soft->bs_rrb_valid[slot]++;
-    }
-#if PCIBR_RRB_DEBUG
-    printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name,
-	    pcibr_soft->bs_rrb_avail[0],
-	    pcibr_soft->bs_rrb_avail[1]);
-    for (slot = 0; slot < 8; ++slot)
-	printk("\t%d+%d+%d",
-		0xFFF & pcibr_soft->bs_rrb_valid[slot],
-		0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-		pcibr_soft->bs_rrb_res[slot]);
-	printk("\n");
-#endif
-}
-
-/*
- * Device driver interface to flush the write buffers for a specified
- * device hanging off the bridge.
- */
-int
-pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    volatile bridgereg_t   *wrb_flush;
-
-    wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg);
-    while (*wrb_flush);
-
-    return(0);
-}
-/*
- * Device driver interface to request RRBs for a specified device
- * hanging off a Bridge.  The driver requests the total number of
- * RRBs it would like for the normal channel (vchan0) and for the
- * "virtual channel" (vchan1).  The actual number allocated to each
- * channel is returned.
- *
- * If we cannot allocate at least one RRB to a channel that needs
- * at least one, return -1 (failure).  Otherwise, satisfy the request
- * as best we can and return 0.
- */
-int
-pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
-		int *count_vchan0,
-		int *count_vchan1)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     desired_vchan0;
-    int                     desired_vchan1;
-    int                     orig_vchan0;
-    int                     orig_vchan1;
-    int                     delta_vchan0;
-    int                     delta_vchan1;
-    int                     final_vchan0;
-    int                     final_vchan1;
-    int                     avail_rrbs;
-    unsigned long           s;
-    int                     error;
-
-    /*
-     * TBD: temper request with admin info about RRB allocation,
-     * and according to demand from other devices on this Bridge.
-     *
-     * One way of doing this would be to allocate two RRBs
-     * for each device on the bus, before any drivers start
-     * asking for extras. This has the weakness that one
-     * driver might not give back an "extra" RRB until after
-     * another driver has already failed to get one that
-     * it wanted.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-
-    /* How many RRBs do we own? */
-    orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot];
-    orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
-
-    /* How many RRBs do we want? */
-    desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
-    desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
-
-    /* How many RRBs are free? */
-    avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
-	+ pcibr_soft->bs_rrb_res[pciio_slot];
-
-    /* Figure desired deltas */
-    delta_vchan0 = desired_vchan0 - orig_vchan0;
-    delta_vchan1 = desired_vchan1 - orig_vchan1;
-
-    /* Trim back deltas to something
-     * that we can actually meet, by
-     * decreasing the ending allocation
-     * for whichever channel wants
-     * more RRBs. If both want the same
-     * number, cut the second channel.
-     * NOTE: do not change the allocation for
-     * a channel that was passed as NULL.
-     */
-    while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
-	if (count_vchan0 &&
-	    (!count_vchan1 ||
-	     ((orig_vchan0 + delta_vchan0) >
-	      (orig_vchan1 + delta_vchan1))))
-	    delta_vchan0--;
-	else
-	    delta_vchan1--;
-    }
-
-    /* Figure final RRB allocations
-     */
-    final_vchan0 = orig_vchan0 + delta_vchan0;
-    final_vchan1 = orig_vchan1 + delta_vchan1;
-
-    /* If either channel wants RRBs but our actions
-     * would leave it with none, declare an error,
-     * but DO NOT change any RRB allocations.
-     */
-    if ((desired_vchan0 && !final_vchan0) ||
-	(desired_vchan1 && !final_vchan1)) {
-
-	error = -1;
-
-    } else {
-
-	/* Commit the allocations: free, then alloc.
-	 */
-	if (delta_vchan0 < 0)
-	    (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0);
-	if (delta_vchan1 < 0)
-	    (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1);
-
-	if (delta_vchan0 > 0)
-	    (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0);
-	if (delta_vchan1 > 0)
-	    (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1);
-
-	/* Return final values to caller.
-	 */
-	if (count_vchan0)
-	    *count_vchan0 = final_vchan0;
-	if (count_vchan1)
-	    *count_vchan1 = final_vchan1;
-
-	/* prevent automatic changes to this slot's RRBs
-	 */
-	pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
-
-	/* Track the actual allocations, release
-	 * any further reservations, and update the
-	 * number of available RRBs.
-	 */
-
-	pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0;
-	pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1;
-	pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
-	    pcibr_soft->bs_rrb_avail[pciio_slot & 1]
-	    + pcibr_soft->bs_rrb_res[pciio_slot]
-	    - delta_vchan0
-	    - delta_vchan1;
-	pcibr_soft->bs_rrb_res[pciio_slot] = 0;
-
-#if PCIBR_RRB_DEBUG
-	printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n",
-		pciio_slot, final_vchan0, final_vchan1,
-		pcibr_soft->bs_rrb_avail[0],
-		pcibr_soft->bs_rrb_avail[1]);
-	for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot)
-	    printk("\t%d+%d+%d",
-		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot],
-		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL],
-		    pcibr_soft->bs_rrb_res[pciio_slot]);
-	printk("\n");
-#endif
-
-	error = 0;
-    }
-
-    pcibr_unlock(pcibr_soft, s);
-    return error;
-}
-
-/*
- * Device driver interface to check the current state
- * of the RRB allocations.
- *
- *   pconn_vhdl is your PCI connection point (specifies which
- *      PCI bus and which slot).
- *
- *   count_vchan0 points to where to return the number of RRBs
- *      assigned to the primary DMA channel, used by all DMA
- *      that does not explicitly ask for the alternate virtual
- *      channel.
- *
- *   count_vchan1 points to where to return the number of RRBs
- *      assigned to the secondary DMA channel, used when
- *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
- *
- *   count_reserved points to where to return the number of RRBs
- *      that have been automatically reserved for your device at
- *      startup, but which have not been assigned to a
- *      channel. RRBs must be assigned to a channel to be used;
- *      this can be done either with an explicit pcibr_rrb_alloc
- *      call, or automatically by the infrastructure when a DMA
- *      translation is constructed. Any call to pcibr_rrb_alloc
- *      will release any unassigned reserved RRBs back to the
- *      free pool.
- *
- *   count_pool points to where to return the number of RRBs
- *      that are currently unassigned and unreserved. This
- *      number can (and will) change as other drivers make calls
- *      to pcibr_rrb_alloc, or automatically allocate RRBs for
- *      DMA beyond their initial reservation.
- *
- * NULL may be passed for any of the return value pointers
- * the caller is not interested in.
- *
- * The return value is "0" if all went well, or "-1" if
- * there is a problem. Additionally, if the wrong vertex
- * is passed in, one of the subsidiary support functions
- * could panic with a "bad pciio fingerprint."
- */
-
-int
-pcibr_rrb_check(devfs_handle_t pconn_vhdl,
-		int *count_vchan0,
-		int *count_vchan1,
-		int *count_reserved,
-		int *count_pool)
-{
-    pciio_info_t            pciio_info;
-    pciio_slot_t            pciio_slot;
-    pcibr_soft_t            pcibr_soft;
-    unsigned long           s;
-    int                     error = -1;
-
-    if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
-	(pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
-	((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) {
-
-	s = pcibr_lock(pcibr_soft);
-
-	if (count_vchan0)
-	    *count_vchan0 =
-		pcibr_soft->bs_rrb_valid[pciio_slot];
-
-	if (count_vchan1)
-	    *count_vchan1 =
-		pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
-
-	if (count_reserved)
-	    *count_reserved =
-		pcibr_soft->bs_rrb_res[pciio_slot];
-
-	if (count_pool)
-	    *count_pool =
-		pcibr_soft->bs_rrb_avail[pciio_slot & 1];
-
-	error = 0;
-
-	pcibr_unlock(pcibr_soft, s);
-    }
-    return error;
-}
-
-/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities
- * requested for each of the devies.  The evn_odd argument indicates whether
- * allcoation for the odd or even rrbs is requested and next group of four pairse
- * are the amount to assign to each device (they should sum to <= 8) and
- * whether to set the viritual bit for that device (1 indictaes yes, 0 indicates no)
- * the devices in order are either 0, 2, 4, 6 or 1, 3, 5, 7
- * if even_odd is even we alloc even rrbs else we allocate odd rrbs
- * returns 0 if no errors else returns -1
- */
-
-int
-pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
-		     int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2,
-		     int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4)
-{
-    devfs_handle_t            pcibr_vhdl;
-    pcibr_soft_t            pcibr_soft = NULL;
-    bridge_t               *bridge = NULL;
-
-    uint32_t              rrb_setting = 0;
-    int                     rrb_shift = 7;
-    uint32_t              cur_rrb;
-    int                     dev_rrbs[4];
-    int                     virt[4];
-    int                     i, j;
-    unsigned long           s;
-
-    if (GRAPH_SUCCESS ==
-	hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) {
-	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-	if (pcibr_soft)
-	    bridge = pcibr_soft->bs_base;
-	hwgraph_vertex_unref(pcibr_vhdl);
-    }
-    if (bridge == NULL)
-	bridge = (bridge_t *) xtalk_piotrans_addr
-	    (vhdl, NULL, 0, sizeof(bridge_t), 0);
-
-    even_odd &= 1;
-
-    dev_rrbs[0] = dev_1_rrbs;
-    dev_rrbs[1] = dev_2_rrbs;
-    dev_rrbs[2] = dev_3_rrbs;
-    dev_rrbs[3] = dev_4_rrbs;
-
-    virt[0] = virt1;
-    virt[1] = virt2;
-    virt[2] = virt3;
-    virt[3] = virt4;
-
-    if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) {
-	return -1;
-    }
-    if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) {
-	return -1;
-    }
-    /* walk through rrbs */
-    for (i = 0; i < 4; i++) {
-	if (virt[i]) {
-	    cur_rrb = i | 0xc;
-	    cur_rrb = cur_rrb << (rrb_shift * 4);
-	    rrb_shift--;
-	    rrb_setting = rrb_setting | cur_rrb;
-	    dev_rrbs[i] = dev_rrbs[i] - 1;
-	}
-	for (j = 0; j < dev_rrbs[i]; j++) {
-	    cur_rrb = i | 0x8;
-	    cur_rrb = cur_rrb << (rrb_shift * 4);
-	    rrb_shift--;
-	    rrb_setting = rrb_setting | cur_rrb;
-	}
-    }
-
-    if (pcibr_soft)
-	s = pcibr_lock(pcibr_soft);
-
-    bridge->b_rrb_map[even_odd].reg = rrb_setting;
-
-    if (pcibr_soft) {
-
-	pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd;
-
-	/* since we've "FIXED" the allocations
-	 * for these slots, we probably can dispense
-	 * with tracking avail/res/valid data, but
-	 * keeping it up to date helps debugging.
-	 */
-
-	pcibr_soft->bs_rrb_avail[even_odd] =
-	    8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs);
-
-	pcibr_soft->bs_rrb_res[even_odd + 0] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 2] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 4] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 6] = 0;
-
-	pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1;
-	pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2;
-	pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3;
-	pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4;
-
-	pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1;
-	pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2;
-	pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3;
-	pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4;
-
-	pcibr_unlock(pcibr_soft, s);
-    }
-    return 0;
-}
-
-/*
- *    pcibr_rrb_flush: chase down all the RRBs assigned
- *      to the specified connection point, and flush
- *      them.
- */
-void
-pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned long           s;
-    reg_p                   rrbp;
-    unsigned                rrbm;
-    int                     i;
-    int                     rrbn;
-    unsigned                sval;
-    unsigned                mask;
-
-    sval = BRIDGE_RRB_EN | (pciio_slot >> 1);
-    mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV;
-    rrbn = pciio_slot & 1;
-    rrbp = &bridge->b_rrb_map[rrbn].reg;
-
-    s = pcibr_lock(pcibr_soft);
-    rrbm = *rrbp;
-    for (i = 0; i < 8; ++i) {
-	if ((rrbm & mask) == sval)
-	    do_pcibr_rrb_flush(bridge, rrbn);
-	rrbm >>= 4;
-	rrbn += 2;
-    }
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/* =====================================================================
- *    Device(x) register management
- */
-
-/* pcibr_try_set_device: attempt to modify Device(x)
- * for the specified slot on the specified bridge
- * as requested in flags, limited to the specified
- * bits. Returns which BRIDGE bits were in conflict,
- * or ZERO if everything went OK.
- *
- * Caller MUST hold pcibr_lock when calling this function.
- */
-LOCAL int
-pcibr_try_set_device(pcibr_soft_t pcibr_soft,
-		     pciio_slot_t slot,
-		     unsigned flags,
-		     bridgereg_t mask)
-{
-    bridge_t               *bridge;
-    pcibr_soft_slot_t       slotp;
-    bridgereg_t             old;
-    bridgereg_t             new;
-    bridgereg_t             chg;
-    bridgereg_t             bad;
-    bridgereg_t             badpmu;
-    bridgereg_t             badd32;
-    bridgereg_t             badd64;
-    bridgereg_t             fix;
-    unsigned long           s;
-    bridgereg_t             xmask;
-
-    xmask = mask;
-    if (pcibr_soft->bs_xbridge) {
-    	if (mask == BRIDGE_DEV_PMU_BITS)
-		xmask = XBRIDGE_DEV_PMU_BITS;
-	if (mask == BRIDGE_DEV_D64_BITS)
-		xmask = XBRIDGE_DEV_D64_BITS;
-    }
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    s = pcibr_lock(pcibr_soft);
-
-    bridge = pcibr_soft->bs_base;
-
-    old = slotp->bss_device;
-
-    /* figure out what the desired
-     * Device(x) bits are based on
-     * the flags specified.
-     */
-
-    new = old;
-
-    /* Currently, we inherit anything that
-     * the new caller has not specified in
-     * one way or another, unless we take
-     * action here to not inherit.
-     *
-     * This is needed for the "swap" stuff,
-     * since it could have been set via
-     * pcibr_endian_set -- altho note that
-     * any explicit PCIBR_BYTE_STREAM or
-     * PCIBR_WORD_VALUES will freely override
-     * the effect of that call (and vice
-     * versa, no protection either way).
-     *
-     * I want to get rid of pcibr_endian_set
-     * in favor of tracking DMA endianness
-     * using the flags specified when DMA
-     * channels are created.
-     */
-
-#define	BRIDGE_DEV_WRGA_BITS	(BRIDGE_DEV_PMU_WRGA_EN | BRIDGE_DEV_DIR_WRGA_EN)
-#define	BRIDGE_DEV_SWAP_BITS	(BRIDGE_DEV_SWAP_PMU | BRIDGE_DEV_SWAP_DIR)
-
-    /* Do not use Barrier, Write Gather,
-     * or Prefetch unless asked.
-     * Leave everything else as it
-     * was from the last time.
-     */
-    new = new
-	& ~BRIDGE_DEV_BARRIER
-	& ~BRIDGE_DEV_WRGA_BITS
-	& ~BRIDGE_DEV_PREF
-	;
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {
-	new = (new
-            & ~BRIDGE_DEV_BARRIER)      /* barrier off */
-            | BRIDGE_DEV_PREF;          /* prefetch on */
-
-    }
-    if (flags & PCIIO_DMA_CMD) {
-        new = ((new
-            & ~BRIDGE_DEV_PREF)         /* prefetch off */
-            & ~BRIDGE_DEV_WRGA_BITS)    /* write gather off */
-            | BRIDGE_DEV_BARRIER;       /* barrier on */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_WRITE_GATHER)
-	new |= BRIDGE_DEV_WRGA_BITS;
-    if (flags & PCIIO_NOWRITE_GATHER)
-	new &= ~BRIDGE_DEV_WRGA_BITS;
-
-    if (flags & PCIIO_PREFETCH)
-	new |= BRIDGE_DEV_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	new &= ~BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_WRITE_GATHER)
-	new |= BRIDGE_DEV_WRGA_BITS;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	new &= ~BRIDGE_DEV_WRGA_BITS;
-
-    if (flags & PCIIO_BYTE_STREAM)
-	new |= (pcibr_soft->bs_xbridge) ? 
-			BRIDGE_DEV_SWAP_DIR : BRIDGE_DEV_SWAP_BITS;
-    if (flags & PCIIO_WORD_VALUES)
-	new &= (pcibr_soft->bs_xbridge) ? 
-			~BRIDGE_DEV_SWAP_DIR : ~BRIDGE_DEV_SWAP_BITS;
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_PREFETCH)
-	new |= BRIDGE_DEV_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	new &= ~BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	new |= BRIDGE_DEV_PRECISE;
-    if (flags & PCIBR_NOPRECISE)
-	new &= ~BRIDGE_DEV_PRECISE;
-
-    if (flags & PCIBR_BARRIER)
-	new |= BRIDGE_DEV_BARRIER;
-    if (flags & PCIBR_NOBARRIER)
-	new &= ~BRIDGE_DEV_BARRIER;
-
-    if (flags & PCIBR_64BIT)
-	new |= BRIDGE_DEV_DEV_SIZE;
-    if (flags & PCIBR_NO64BIT)
-	new &= ~BRIDGE_DEV_DEV_SIZE;
-
-    chg = old ^ new;				/* what are we changing, */
-    chg &= xmask;				/* of the interesting bits */
-
-    if (chg) {
-
-	badd32 = slotp->bss_d32_uctr ? (BRIDGE_DEV_D32_BITS & chg) : 0;
-	if (pcibr_soft->bs_xbridge) {
-		badpmu = slotp->bss_pmu_uctr ? (XBRIDGE_DEV_PMU_BITS & chg) : 0;
-		badd64 = slotp->bss_d64_uctr ? (XBRIDGE_DEV_D64_BITS & chg) : 0;
-	} else {
-		badpmu = slotp->bss_pmu_uctr ? (BRIDGE_DEV_PMU_BITS & chg) : 0;
-		badd64 = slotp->bss_d64_uctr ? (BRIDGE_DEV_D64_BITS & chg) : 0;
-	}
-	bad = badpmu | badd32 | badd64;
-
-	if (bad) {
-
-	    /* some conflicts can be resolved by
-	     * forcing the bit on. this may cause
-	     * some performance degredation in
-	     * the stream(s) that want the bit off,
-	     * but the alternative is not allowing
-	     * the new stream at all.
-	     */
-            if ( (fix = bad & (BRIDGE_DEV_PRECISE |
-                             BRIDGE_DEV_BARRIER)) ){
-		bad &= ~fix;
-		/* don't change these bits if
-		 * they are already set in "old"
-		 */
-		chg &= ~(fix & old);
-	    }
-	    /* some conflicts can be resolved by
-	     * forcing the bit off. this may cause
-	     * some performance degredation in
-	     * the stream(s) that want the bit on,
-	     * but the alternative is not allowing
-	     * the new stream at all.
-	     */
-	    if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS |
-			     BRIDGE_DEV_PREF)) ) {
-		bad &= ~fix;
-		/* don't change these bits if
-		 * we wanted to turn them on.
-		 */
-		chg &= ~(fix & new);
-	    }
-	    /* conflicts in other bits mean
-	     * we can not establish this DMA
-	     * channel while the other(s) are
-	     * still present.
-	     */
-	    if (bad) {
-		pcibr_unlock(pcibr_soft, s);
-#if (DEBUG && PCIBR_DEV_DEBUG)
-		printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits);
-#endif
-		return bad;
-	    }
-	}
-    }
-    if (mask == BRIDGE_DEV_PMU_BITS)
-	slotp->bss_pmu_uctr++;
-    if (mask == BRIDGE_DEV_D32_BITS)
-	slotp->bss_d32_uctr++;
-    if (mask == BRIDGE_DEV_D64_BITS)
-	slotp->bss_d64_uctr++;
-
-    /* the value we want to write is the
-     * original value, with the bits for
-     * our selected changes flipped, and
-     * with any disabled features turned off.
-     */
-    new = old ^ chg;			/* only change what we want to change */
-
-    if (slotp->bss_device == new) {
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-    bridge->b_device[slot].reg = new;
-    slotp->bss_device = new;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-#if DEBUG && PCIBR_DEV_DEBUG
-    printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg);
-#endif
-
-    return 0;
-}
-
-void
-pcibr_release_device(pcibr_soft_t pcibr_soft,
-		     pciio_slot_t slot,
-		     bridgereg_t mask)
-{
-    pcibr_soft_slot_t       slotp;
-    unsigned long           s;
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    s = pcibr_lock(pcibr_soft);
-
-    if (mask == BRIDGE_DEV_PMU_BITS)
-	slotp->bss_pmu_uctr--;
-    if (mask == BRIDGE_DEV_D32_BITS)
-	slotp->bss_d32_uctr--;
-    if (mask == BRIDGE_DEV_D64_BITS)
-	slotp->bss_d64_uctr--;
-
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/*
- * flush write gather buffer for slot
- */
-LOCAL void
-pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft,
-              pciio_slot_t slot)
-{
-    bridge_t               *bridge;
-    unsigned long          s;
-    volatile uint32_t     wrf;
-    s = pcibr_lock(pcibr_soft);
-    bridge = pcibr_soft->bs_base;
-    wrf = bridge->b_wr_req_buf[slot].reg;
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/* =====================================================================
- *    Bridge (pcibr) "Device Driver" entry points
- */
-
-/*
- * pcibr_probe_slot: read a config space word
- * while trapping any errors; reutrn zero if
- * all went OK, or nonzero if there was an error.
- * The value read, if any, is passed back
- * through the valp parameter.
- */
-LOCAL int
-pcibr_probe_slot(bridge_t *bridge,
-		 cfg_p cfg,
-		 unsigned *valp)
-{
-    int                     rv;
-    bridgereg_t             old_enable, new_enable;
-    int badaddr_val(volatile void *, int, volatile void *);
-
-
-    old_enable = bridge->b_int_enable;
-    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-
-    bridge->b_int_enable = new_enable;
-
-	/*
-	 * The xbridge doesn't clear b_err_int_view unless
-	 * multi-err is cleared...
-	 */
-	if (is_xbridge(bridge))
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-	    }
-
-    if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
-	bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
-	(void) bridge->b_wid_tflush;	/* flushbus */
-    }
-    rv = badaddr_val((void *) cfg, 4, valp);
-
-	/*
-	 * The xbridge doesn't set master timeout in b_int_status
-	 * here.  Fortunately it's in error_interrupt_view.
-	 */
-	if (is_xbridge(bridge))
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-		rv = 1;		/* unoccupied slot */
-	    }
-
-    bridge->b_int_enable = old_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    return rv;
-}
-
-/*
- *    pcibr_init: called once during system startup or
- *      when a loadable driver is loaded.
- *
- *      The driver_register function should normally
- *      be in _reg, not _init.  But the pcibr driver is
- *      required by devinit before the _reg routines
- *      are called, so this is an exception.
- */
-void
-pcibr_init(void)
-{
-#if DEBUG && ATTACH_DEBUG
-    printk("pcibr_init\n");
-#endif
-
-    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
-			    XBRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
-			    BRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-}
-
-/*
- * open/close mmap/munmap interface would be used by processes
- * that plan to map the PCI bridge, and muck around with the
- * registers. This is dangerous to do, and will be allowed
- * to a select brand of programs. Typically these are
- * diagnostics programs, or some user level commands we may
- * write to do some weird things.
- * To start with expect them to have root priveleges.
- * We will ask for more later.
- */
-/* ARGSUSED */
-int
-pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    int                     error;
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    ASSERT(pcibr_soft);
-    len = ctob(btoc(len));		/* Make len page aligned */
-    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
-
-    /*
-     * If the offset being mapped corresponds to the flash prom
-     * base, and if the mapping succeeds, and if the user
-     * has requested the protections to be WRITE, enable the
-     * flash prom to be written.
-     *
-     * XXX- deprecate this in favor of using the
-     * real flash driver ...
-     */
-    if (!error &&
-	((off == BRIDGE_EXTERNAL_FLASH) ||
-	 (len > BRIDGE_EXTERNAL_FLASH))) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-	bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(s);
-    }
-    return error;
-}
-
-/*ARGSUSED */
-int
-pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    /*
-     * If flashprom write was enabled, disable it, as
-     * this is the last unmap.
-     */
-    if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-	bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(s);
-    }
-    return 0;
-}
-
-/* This is special case code used by grio. There are plans to make
- * this a bit more general in the future, but till then this should
- * be sufficient.
- */
-pciio_slot_t
-pcibr_device_slot_get(devfs_handle_t dev_vhdl)
-{
-    char                    devname[MAXDEVNAME];
-    devfs_handle_t            tdev;
-    pciio_info_t            pciio_info;
-    pciio_slot_t            slot = PCIIO_SLOT_NONE;
-
-    vertex_to_name(dev_vhdl, devname, MAXDEVNAME);
-
-    /* run back along the canonical path
-     * until we find a PCI connection point.
-     */
-    tdev = hwgraph_connectpt_get(dev_vhdl);
-    while (tdev != GRAPH_VERTEX_NONE) {
-	pciio_info = pciio_info_chk(tdev);
-	if (pciio_info) {
-	    slot = pciio_info_slot_get(pciio_info);
-	    break;
-	}
-	hwgraph_vertex_unref(tdev);
-	tdev = hwgraph_connectpt_get(tdev);
-    }
-    hwgraph_vertex_unref(tdev);
-
-    return slot;
-}
-
-/*==========================================================================
- *	BRIDGE PCI SLOT RELATED IOCTLs
- */
-char *pci_space_name[] = {"NONE", 
-			  "ROM",
-			  "IO",
-			  "",
-			  "MEM",
-			  "MEM32",
-			  "MEM64",
-			  "CFG",
-			  "WIN0",
-			  "WIN1",
-			  "WIN2",
-			  "WIN3",
-			  "WIN4",
-			  "WIN5",
-			  "",
-			  "BAD"};
-
-
-#ifdef LATER
-
-void
-pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh,
-                            int func,
-                            pcibr_slot_func_info_resp_t funcp)
-{
-    pcibr_info_t                 pcibr_info = pcibr_infoh[func];
-    int                          win;
-
-    funcp->resp_f_status = 0;
-
-    if (!pcibr_info) {
-        return;
-    }
-
-    funcp->resp_f_status |= FUNC_IS_VALID;
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
-#else
-    sprintf(funcp->resp_f_slot_name, "%x", pcibr_info->f_vertex);
-#endif
-
-    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {
-        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;
-    }
-
-    funcp->resp_f_bus = pcibr_info->f_bus;
-    funcp->resp_f_slot = pcibr_info->f_slot;
-    funcp->resp_f_func = pcibr_info->f_func;
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);
-#else
-    sprintf(funcp->resp_f_master_name, "%x", pcibr_info->f_master);
-#endif
-    funcp->resp_f_pops = pcibr_info->f_pops;
-    funcp->resp_f_efunc = pcibr_info->f_efunc;
-    funcp->resp_f_einfo = pcibr_info->f_einfo;
-
-    funcp->resp_f_vendor = pcibr_info->f_vendor;
-    funcp->resp_f_device = pcibr_info->f_device;
-
-    for(win = 0 ; win < 6 ; win++) {
-        funcp->resp_f_window[win].resp_w_base =
-                                  pcibr_info->f_window[win].w_base;
-        funcp->resp_f_window[win].resp_w_size =
-                                  pcibr_info->f_window[win].w_size;
-        sprintf(funcp->resp_f_window[win].resp_w_space,
-                "%s",
-                pci_space_name[pcibr_info->f_window[win].w_space]);
-    }
-
-    funcp->resp_f_rbase = pcibr_info->f_rbase;
-    funcp->resp_f_rsize = pcibr_info->f_rsize;
-
-    for (win = 0 ; win < 4; win++) {
-        funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];
-    }
-
-    funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;
-
-}
-
-int
-pcibr_slot_info_return(pcibr_soft_t             pcibr_soft,
-                       pciio_slot_t             slot,
-                       pcibr_slot_info_resp_t   respp)
-{
-    pcibr_soft_slot_t            pss;
-    int                          func;
-    bridge_t                    *bridge = pcibr_soft->bs_base;
-    reg_p                        b_respp;
-    pcibr_slot_info_resp_t       slotp;
-    pcibr_slot_func_info_resp_t  funcp;
-
-    slotp = kmem_zalloc(sizeof(*slotp), KM_SLEEP);
-    if (slotp == NULL) {
-        return(ENOMEM);
-    }
-
-    pss = &pcibr_soft->bs_slot[slot];
-    
-    printk("\nPCI INFRASTRUCTURAL INFO FOR SLOT %d\n\n", slot);
-
-    slotp->resp_has_host = pss->has_host;
-    slotp->resp_host_slot = pss->host_slot;
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(slotp->resp_slot_conn_name, "%v", pss->slot_conn);
-#else
-    sprintf(slotp->resp_slot_conn_name, "%x", pss->slot_conn);
-#endif
-    slotp->resp_slot_status = pss->slot_status;
-    slotp->resp_l1_bus_num = io_path_map_widget(pcibr_soft->bs_vhdl);
-
-    if (is_sys_critical_vertex(pss->slot_conn)) {
-        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;
-    }
-
-    slotp->resp_bss_ninfo = pss->bss_ninfo;
-
-    for (func = 0; func < pss->bss_ninfo; func++) {
-        funcp = &(slotp->resp_func[func]);
-        pcibr_slot_func_info_return(pss->bss_infos, func, funcp);
-    }
-
-    sprintf(slotp->resp_bss_devio_bssd_space, "%s",
-            pci_space_name[pss->bss_devio.bssd_space]);
-    slotp->resp_bss_devio_bssd_base = pss->bss_devio.bssd_base;
-    slotp->resp_bss_device = pss->bss_device;
-
-    slotp->resp_bss_pmu_uctr = pss->bss_pmu_uctr;
-    slotp->resp_bss_d32_uctr = pss->bss_d32_uctr;
-    slotp->resp_bss_d64_uctr = pss->bss_d64_uctr;
-
-    slotp->resp_bss_d64_base = pss->bss_d64_base;
-    slotp->resp_bss_d64_flags = pss->bss_d64_flags;
-    slotp->resp_bss_d32_base = pss->bss_d32_base;
-    slotp->resp_bss_d32_flags = pss->bss_d32_flags;
-
-    slotp->resp_bss_ext_ates_active = atomic_read(&pss->bss_ext_ates_active);
-
-    slotp->resp_bss_cmd_pointer = pss->bss_cmd_pointer;
-    slotp->resp_bss_cmd_shadow = pss->bss_cmd_shadow;
-
-    slotp->resp_bs_rrb_valid = pcibr_soft->bs_rrb_valid[slot];
-    slotp->resp_bs_rrb_valid_v = pcibr_soft->bs_rrb_valid[slot +
-                                                      PCIBR_RRB_SLOT_VIRTUAL];
-    slotp->resp_bs_rrb_res = pcibr_soft->bs_rrb_res[slot];
-
-    if (slot & 1) {
-        b_respp = &bridge->b_odd_resp;
-    } else {
-        b_respp = &bridge->b_even_resp;
-    }
-
-    slotp->resp_b_resp = *b_respp;
-
-    slotp->resp_b_int_device = bridge->b_int_device;
-    slotp->resp_b_int_enable = bridge->b_int_enable;
-    slotp->resp_b_int_host = bridge->b_int_addr[slot].addr;
-
-    if (COPYOUT(slotp, respp, sizeof(*respp))) {
-        return(EFAULT);
-    }
-
-    kmem_free(slotp, sizeof(*slotp));
-
-    return(0);
-}
-
-/*
- * pcibr_slot_query
- *	Return information about the PCI slot maintained by the infrastructure.
- *	Information is requested in the request structure.
- *
- *      Information returned in the response structure:
- *		Slot hwgraph name
- *		Vendor/Device info
- *		Base register info
- *		Interrupt mapping from device pins to the bridge pins
- *		Devio register
- *		Software RRB info
- *		RRB register info
- *		Host/Gues info
- *		PCI Bus #,slot #, function #
- *		Slot provider hwgraph name
- *		Provider Functions
- *		Error handler
- *		DMA mapping usage counters
- *		DMA direct translation info
- *		External SSRAM workaround info
- */
-int
-pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_info_req_t reqp)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    pciio_slot_t            slot = reqp->req_slot;
-    pciio_slot_t            tmp_slot;
-    pcibr_slot_info_resp_t  respp = (pcibr_slot_info_resp_t) reqp->req_respp;
-    int                     size = reqp->req_size;
-    int                     error;
-
-    /* Make sure that we are dealing with a bridge device vertex */
-    if (!pcibr_soft) {
-        return(EINVAL);
-    }
-
-    /* Make sure that we have a valid PCI slot number or PCIIO_SLOT_NONE */
-    if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE)) {
-        return(EINVAL);
-    }
-
-#ifdef LATER
-    /* Do not allow a query of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(EPERM);
-    }
-#endif
-
-    /* Return information for the requested PCI slot */
-    if (slot != PCIIO_SLOT_NONE) {
-        if (size < sizeof(*respp)) {
-            return(EINVAL);
-        }
-
-        /* Acquire read access to the slot */
-        mrlock(pcibr_soft->bs_slot[slot].slot_lock, MR_ACCESS, PZERO);
-
-        error = pcibr_slot_info_return(pcibr_soft, slot, respp);
-
-        /* Release the slot lock */
-        mrunlock(pcibr_soft->bs_slot[slot].slot_lock);
-
-        return(error);
-    }
-
-    /* Return information for all the slots */
-    for (tmp_slot = 0; tmp_slot < 8; tmp_slot++) {
-
-        if (size < sizeof(*respp)) {
-            return(EINVAL);
-        }
-
-        /* Acquire read access to the slot */
-        mrlock(pcibr_soft->bs_slot[tmp_slot].slot_lock, MR_ACCESS, PZERO);
-
-        error = pcibr_slot_info_return(pcibr_soft, tmp_slot, respp);
-
-        /* Release the slot lock */
-        mrunlock(pcibr_soft->bs_slot[tmp_slot].slot_lock);
-
-        if (error) {
-            return(error);
-        }
-
-        ++respp;
-        size -= sizeof(*respp);
-    }
-
-    return(error);
-}
-#endif	/* LATER */
-
-
-/*ARGSUSED */
-int
-pcibr_ioctl(devfs_handle_t dev,
-	    int cmd,
-	    void *arg,
-	    int flag,
-	    struct cred *cr,
-	    int *rvalp)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);
-#ifdef LATER
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-#endif
-    int                     error = 0;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    switch (cmd) {
-#ifdef LATER
-    case GIOCSETBW:
-	{
-	    grio_ioctl_info_t       info;
-	    pciio_slot_t            slot = 0;
-
-	    if (!cap_able((uint64_t)CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
-		    info.prev_vhdl, info.reqbw);
-#endif				/* GRIO_DEBUG */
-
-	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
-		PCIIO_SLOT_NONE) {
-		error = EIO;
-		break;
-	    }
-	    if (info.reqbw)
-		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH);
-	    break;
-	}
-
-    case GIOCRELEASEBW:
-	{
-	    grio_ioctl_info_t       info;
-	    pciio_slot_t            slot = 0;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
-		    info.prev_vhdl, info.reqbw);
-#endif				/* GRIO_DEBUG */
-
-	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
-		PCIIO_SLOT_NONE) {
-		error = EIO;
-		break;
-	    }
-	    if (info.reqbw)
-		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);
-	    break;
-	}
-
-    case PCIBR_SLOT_POWERUP:
-	{
-	    pciio_slot_t	slot;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
-	    break;
-	}
-    case PCIBR_SLOT_SHUTDOWN:
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
-	    break;
-	}
-    case PCIBR_SLOT_QUERY:
-	{
-	    struct pcibr_slot_info_req_s        req;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-            if (COPYIN(arg, &req, sizeof(req))) {
-                error = EFAULT;
-                break;
-            }
-
-            error = pcibr_slot_query(pcibr_vhdl, &req);
-	    break;
-	}
-#endif	/* LATER */
-    default:
-	break;
-
-    }
-
-    return error;
-}
-
-void
-pcibr_freeblock_sub(iopaddr_t *free_basep,
-		    iopaddr_t *free_lastp,
-		    iopaddr_t base,
-		    size_t size)
-{
-    iopaddr_t               free_base = *free_basep;
-    iopaddr_t               free_last = *free_lastp;
-    iopaddr_t               last = base + size - 1;
-
-    if ((last < free_base) || (base > free_last));	/* free block outside arena */
-
-    else if ((base <= free_base) && (last >= free_last))
-	/* free block contains entire arena */
-	*free_basep = *free_lastp = 0;
-
-    else if (base <= free_base)
-	/* free block is head of arena */
-	*free_basep = last + 1;
-
-    else if (last >= free_last)
-	/* free block is tail of arena */
-	*free_lastp = base - 1;
-
-    /*
-     * We are left with two regions: the free area
-     * in the arena "below" the block, and the free
-     * area in the arena "above" the block. Keep
-     * the one that is bigger.
-     */
-
-    else if ((base - free_base) > (free_last - last))
-	*free_lastp = base - 1;		/* keep lower chunk */
-    else
-	*free_basep = last + 1;		/* keep upper chunk */
-}
-
-/* Convert from ssram_bits in control register to number of SSRAM entries */
-#define ATE_NUM_ENTRIES(n) _ate_info[n]
-
-/* Possible choices for number of ATE entries in Bridge's SSRAM */
-LOCAL int               _ate_info[] =
-{
-    0,					/* 0 entries */
-    8 * 1024,				/* 8K entries */
-    16 * 1024,				/* 16K entries */
-    64 * 1024				/* 64K entries */
-};
-
-#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))
-#define ATE_PROBE_VALUE 0x0123456789abcdefULL
-
-/*
- * Determine the size of this bridge's external mapping SSRAM, and set
- * the control register appropriately to reflect this size, and initialize
- * the external SSRAM.
- */
-LOCAL int
-pcibr_init_ext_ate_ram(bridge_t *bridge)
-{
-    int                     largest_working_size = 0;
-    int                     num_entries, entry;
-    int                     i, j;
-    bridgereg_t             old_enable, new_enable;
-    int                     s;
-
-    /* Probe SSRAM to determine its size. */
-    old_enable = bridge->b_int_enable;
-    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-    bridge->b_int_enable = new_enable;
-
-    for (i = 1; i < ATE_NUM_SIZES; i++) {
-	/* Try writing a value */
-	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-
-	/* Guard against wrap */
-	for (j = 1; j < i; j++)
-	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
-
-	/* See if value was written */
-	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
-	    largest_working_size = i;
-    }
-    bridge->b_int_enable = old_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    /*
-     * ensure that we write and read without any interruption.
-     * The read following the write is required for the Bridge war
-     */
-
-    s = splhi();
-    bridge->b_wid_control = (bridge->b_wid_control
-	& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-	| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-    bridge->b_wid_control;		/* inval addr bug war */
-    splx(s);
-
-    num_entries = ATE_NUM_ENTRIES(largest_working_size);
-
-#if PCIBR_ATE_DEBUG
-    if (num_entries)
-	printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries);
-    else
-	printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge);
-#endif
-
-    /* Initialize external mapping entries */
-    for (entry = 0; entry < num_entries; entry++)
-	bridge->b_ext_ate_ram[entry] = 0;
-
-    return (num_entries);
-}
-
-/*
- * Allocate "count" contiguous Bridge Address Translation Entries
- * on the specified bridge to be used for PCI to XTALK mappings.
- * Indices in rm map range from 1..num_entries.  Indicies returned
- * to caller range from 0..num_entries-1.
- *
- * Return the start index on success, -1 on failure.
- */
-LOCAL int
-pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
-{
-    int                     index = 0;
-
-    index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
-/* printk("Colin: pcibr_ate_alloc - index %d count %d \n", index, count); */
-
-    if (!index && pcibr_soft->bs_ext_ate_map)
-	index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
-
-    /* rmalloc manages resources in the 1..n
-     * range, with 0 being failure.
-     * pcibr_ate_alloc manages resources
-     * in the 0..n-1 range, with -1 being failure.
-     */
-    return index - 1;
-}
-
-LOCAL void
-pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
-/* Who says there's no such thing as a free meal? :-) */
-{
-    /* note the "+1" since rmalloc handles 1..n but
-     * we start counting ATEs at zero.
-     */
-/* printk("Colin: pcibr_ate_free - index %d count %d\n", index, count); */
-
-    rmfree((index < pcibr_soft->bs_int_ate_size)
-	   ? pcibr_soft->bs_int_ate_map
-	   : pcibr_soft->bs_ext_ate_map,
-	   count, index + 1);
-}
-
-LOCAL pcibr_info_t
-pcibr_info_get(devfs_handle_t vhdl)
-{
-    return (pcibr_info_t) pciio_info_get(vhdl);
-}
-
-pcibr_info_t
-pcibr_device_info_new(
-			 pcibr_soft_t pcibr_soft,
-			 pciio_slot_t slot,
-			 pciio_function_t rfunc,
-			 pciio_vendor_id_t vendor,
-			 pciio_device_id_t device)
-{
-    pcibr_info_t            pcibr_info;
-    pciio_function_t        func;
-    int                     ibit;
-
-    func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc;
-
-    NEW(pcibr_info);
-    pciio_device_info_new(&pcibr_info->f_c,
-			  pcibr_soft->bs_vhdl,
-			  slot, rfunc,
-			  vendor, device);
-
-    if (slot != PCIIO_SLOT_NONE) {
-
-	/*
-	 * Currently favored mapping from PCI
-	 * slot number and INTA/B/C/D to Bridge
-	 * PCI Interrupt Bit Number:
-	 *
-	 *     SLOT     A B C D
-	 *      0       0 4 0 4
-	 *      1       1 5 1 5
-	 *      2       2 6 2 6
-	 *      3       3 7 3 7
-	 *      4       4 0 4 0
-	 *      5       5 1 5 1
-	 *      6       6 2 6 2
-	 *      7       7 3 7 3
-	 *
-	 * XXX- allow pcibr_hints to override default
-	 * XXX- allow ADMIN to override pcibr_hints
-	 */
-	for (ibit = 0; ibit < 4; ++ibit)
-	    pcibr_info->f_ibit[ibit] =
-		(slot + 4 * ibit) & 7;
-
-	/*
-	 * Record the info in the sparse func info space.
-	 */
-	if (func < pcibr_soft->bs_slot[slot].bss_ninfo)
-	    pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info;
-    }
-    return pcibr_info;
-}
-
-void
-pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    pcibr_info_t	pcibr_info;
-    pciio_function_t	func;
-    pcibr_soft_slot_t	slotp = &pcibr_soft->bs_slot[slot];
-    int			nfunc = slotp->bss_ninfo;
-
-
-    for (func = 0; func < nfunc; func++) {
-	pcibr_info = slotp->bss_infos[func];
-
-	if (!pcibr_info) 
-	    continue;
-
-	slotp->bss_infos[func] = 0;
-	pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);
-	pciio_device_info_free(&pcibr_info->f_c);
-	DEL(pcibr_info);
-    }
-
-    /* Clear the DEVIO(x) for this slot */
-    slotp->bss_devio.bssd_space = PCIIO_SPACE_NONE;
-    slotp->bss_devio.bssd_base = PCIBR_D32_BASE_UNSET;
-    slotp->bss_device  = 0;
-
-    
-    /* Reset the mapping usage counters */
-    slotp->bss_pmu_uctr = 0;
-    slotp->bss_d32_uctr = 0;
-    slotp->bss_d64_uctr = 0;
-
-    /* Clear the Direct translation info */
-    slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;
-    slotp->bss_d64_flags = 0;
-    slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;
-    slotp->bss_d32_flags = 0;
-
-    /* Clear out shadow info necessary for the external SSRAM workaround */
-    slotp->bss_ext_ates_active = ATOMIC_INIT(0);
-    slotp->bss_cmd_pointer = 0;
-    slotp->bss_cmd_shadow = 0;
-
-}
-
-/* 
- * PCI_ADDR_SPACE_LIMITS_LOAD
- *	Gets the current values of 
- *		pci io base, 
- *		pci io last,
- *		pci low memory base,
- *		pci low memory last,
- *		pci high memory base,
- * 		pci high memory last
- */
-#define PCI_ADDR_SPACE_LIMITS_LOAD()			\
-    pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base;	\
-    pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last;	\
-    pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base;	\
-    pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last;	\
-    pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base;	\
-    pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last;
-/*
- * PCI_ADDR_SPACE_LIMITS_STORE
- *	Sets the current values of
- *		pci io base, 
- *		pci io last,
- *		pci low memory base,
- *		pci low memory last,
- *		pci high memory base,
- * 		pci high memory last
- */
-#define PCI_ADDR_SPACE_LIMITS_STORE()			\
-    pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;	\
-    pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;	\
-    pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;	\
-    pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;	\
-    pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;	\
-    pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;
-
-#define PCI_ADDR_SPACE_LIMITS_PRINT()			\
-    printf("+++++++++++++++++++++++\n"			\
-	   "IO base 0x%x last 0x%x\n"			\
-	   "SWIN base 0x%x last 0x%x\n"			\
-	   "MEM base 0x%x last 0x%x\n"			\
-	   "+++++++++++++++++++++++\n",			\
-	   pcibr_soft->bs_spinfo.pci_io_base,		\
-	   pcibr_soft->bs_spinfo.pci_io_last,		\
-	   pcibr_soft->bs_spinfo.pci_swin_base,		\
-	   pcibr_soft->bs_spinfo.pci_swin_last,		\
-	   pcibr_soft->bs_spinfo.pci_mem_base,		\
-	   pcibr_soft->bs_spinfo.pci_mem_last);
-
-/*
- * pcibr_slot_info_init
- *	Probe for this slot and see if it is populated.
- *	If it is populated initialize the generic PCI infrastructural
- * 	information associated with this particular PCI device.
- */
-int
-pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
-		     pciio_slot_t 	slot)
-{
-    pcibr_soft_t	    pcibr_soft;
-    pcibr_info_h	    pcibr_infoh;
-    pcibr_info_t	    pcibr_info;
-    bridge_t		   *bridge;
-    cfg_p                   cfgw;
-    unsigned                idword;
-    unsigned                pfail;
-    unsigned                idwords[8];
-    pciio_vendor_id_t       vendor;
-    pciio_device_id_t       device;
-    unsigned                htype;
-#if !defined(CONFIG_IA64_SGI_SN1)
-    int			    nbars;
-#endif
-    cfg_p                   wptr;
-    int                     win;
-    pciio_space_t           space;
-    iopaddr_t		    pci_io_fb,	pci_io_fl;
-    iopaddr_t		    pci_lo_fb,  pci_lo_fl;
-    iopaddr_t		    pci_hi_fb,  pci_hi_fl;
-    int			    nfunc;
-    pciio_function_t	    rfunc;
-    int			    func;
-    devfs_handle_t	    conn_vhdl;
-    pcibr_soft_slot_t	    slotp;
-    
-    /* Get the basic software information required to proceed */
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft)
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-    if (!PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization
-     * is done by the host slot then we are done.
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	return(0);    
-    }
-
-    /* Check for a slot with any system critical functions */
-    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
-    /* Load the current values of allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
-    
-    /* Try to read the device-id/vendor-id from the config space */
-    cfgw = bridge->b_type0_cfg_dev[slot].l;
-
-    if (pcibr_probe_slot(bridge, cfgw, &idword)) 
-	return(ENODEV);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-    slotp->slot_status |= SLOT_POWER_UP;
-
-    vendor = 0xFFFF & idword;
-    /* If the vendor id is not valid then the slot is not populated
-     * and we are done.
-     */
-    if (vendor == 0xFFFF) 
-	return(ENODEV);			
-    
-    device = 0xFFFF & (idword >> 16);
-    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
-
-    nfunc = 1;
-    rfunc = PCIIO_FUNC_NONE;
-    pfail = 0;
-
-    /* NOTE: if a card claims to be multifunction
-     * but only responds to config space 0, treat
-     * it as a unifunction card.
-     */
-
-    if (htype & 0x80) {		/* MULTIFUNCTION */
-	for (func = 1; func < 8; ++func) {
-	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	    if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) {
-		pfail |= 1 << func;
-		continue;
-	    }
-	    vendor = 0xFFFF & idwords[func];
-	    if (vendor == 0xFFFF) {
-		pfail |= 1 << func;
-		continue;
-	    }
-	    nfunc = func + 1;
-	    rfunc = 0;
-	}
-	cfgw = bridge->b_type0_cfg_dev[slot].l;
-    }
-    NEWA(pcibr_infoh, nfunc);
-    
-    pcibr_soft->bs_slot[slot].bss_ninfo = nfunc;
-    pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
-
-    for (func = 0; func < nfunc; ++func) {
-	unsigned                cmd_reg;
-	
-	if (func) {
-	    if (pfail & (1 << func))
-		continue;
-	    
-	    idword = idwords[func];
-	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	    
-	    device = 0xFFFF & (idword >> 16);
-	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
-	    rfunc = func;
-	}
-	htype &= 0x7f;
-	if (htype != 0x00) {
-	    PRINT_WARNING("%s pcibr: pci slot %d func %d has strange header type 0x%x\n",
-		    pcibr_soft->bs_name, slot, func, htype);
-#if defined(CONFIG_IA64_SGI_SN1)
-	    continue;
-#else
-	    nbars = 2;
-	} else {
-	    nbars = PCI_CFG_BASE_ADDRS;
-#endif
-	}
-#if DEBUG && ATTACH_DEBUG
-	PRINT_NOTICE( 
-		"%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x",
-		pcibr_soft->bs_name, slot, func, vendor, device);
-#endif	
-
-	pcibr_info = pcibr_device_info_new
-	    (pcibr_soft, slot, rfunc, vendor, device);
-	conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
-	if (func == 0)
-	    slotp->slot_conn = conn_vhdl;
-
-	cmd_reg = cfgw[PCI_CFG_COMMAND / 4];
-	
-	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win)
-#else
-	for (win = 0; win < nbars; ++win)
-#endif
-	{
-	    iopaddr_t               base, mask, code;
-	    size_t                  size;
-
-	    /*
-	     * GET THE BASE & SIZE OF THIS WINDOW:
-	     *
-	     * The low two or four bits of the BASE register
-	     * determines which address space we are in; the
-	     * rest is a base address. BASE registers
-	     * determine windows that are power-of-two sized
-	     * and naturally aligned, so we can get the size
-	     * of a window by writing all-ones to the
-	     * register, reading it back, and seeing which
-	     * bits are used for decode; the least
-	     * significant nonzero bit is also the size of
-	     * the window.
-	     *
-	     * WARNING: someone may already have allocated
-	     * some PCI space to this window, and in fact
-	     * PIO may be in process at this very moment
-	     * from another processor (or even from this
-	     * one, if we get interrupted)! So, if the BASE
-	     * already has a nonzero address, be generous
-	     * and use the LSBit of that address as the
-	     * size; this could overstate the window size.
-	     * Usually, when one card is set up, all are set
-	     * up; so, since we don't bitch about
-	     * overlapping windows, we are ok.
-	     *
-	     * UNFORTUNATELY, some cards do not clear their
-	     * BASE registers on reset. I have two heuristics
-	     * that can detect such cards: first, if the
-	     * decode enable is turned off for the space
-	     * that the window uses, we can disregard the
-	     * initial value. second, if the address is
-	     * outside the range that we use, we can disregard
-	     * it as well.
-	     *
-	     * This is looking very PCI generic. Except for
-	     * knowing how many slots and where their config
-	     * spaces are, this window loop and the next one
-	     * could probably be shared with other PCI host
-	     * adapters. It would be interesting to see if
-	     * this could be pushed up into pciio, when we
-	     * start supporting more PCI providers.
-	     */
-#ifdef LITTLE_ENDIAN
-	    base = wptr[((win*4)^4)/4];
-#else
-	    base = wptr[win];
-#endif
-
-	    if (base & PCI_BA_IO_SPACE) {
-		/* BASE is in I/O space. */
-		space = PCIIO_SPACE_IO;
-		mask = -4;
-		code = base & 3;
-		base = base & mask;
-		if (base == 0) {
-		    ;		/* not assigned */
-		} else if (!(cmd_reg & PCI_CMD_IO_SPACE)) {
-		    base = 0;	/* decode not enabled */
-		}
-	    } else {
-		/* BASE is in MEM space. */
-		space = PCIIO_SPACE_MEM;
-		mask = -16;
-		code = base & PCI_BA_MEM_LOCATION;	/* extract BAR type */
-		base = base & mask;
-		if (base == 0) {
-		    ;		/* not assigned */
-		} else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) {
-		    base = 0;	/* decode not enabled */
-		} else if (base & 0xC0000000) {
-		    base = 0;	/* outside permissable range */
-		} else if ((code == PCI_BA_MEM_64BIT) &&
-#ifdef LITTLE_ENDIAN
-			   (wptr[(((win + 1)*4)^4)/4] != 0)) {
-#else 
-			   (wptr[win + 1] != 0)) {
-#endif /* LITTLE_ENDIAN */
-		    base = 0;	/* outside permissable range */
-		}
-	    }
-
-	    if (base != 0) {	/* estimate size */
-		size = base & -base;
-	    } else {		/* calculate size */
-#ifdef LITTLE_ENDIAN
-		wptr[((win*4)^4)/4] = ~0;	/* turn on all bits */
-		size = wptr[((win*4)^4)/4];	/* get stored bits */
-#else 
-		wptr[win] = ~0;	/* turn on all bits */
-		size = wptr[win];	/* get stored bits */
-#endif /* LITTLE_ENDIAN */
-		size &= mask;	/* keep addr */
-		size &= -size;	/* keep lsbit */
-		if (size == 0)
-		    continue;
-	    }	
-
-	    pcibr_info->f_window[win].w_space = space;
-	    pcibr_info->f_window[win].w_base = base;
-	    pcibr_info->f_window[win].w_size = size;
-
-	    /*
-	     * If this window already has PCI space
-	     * allocated for it, "subtract" that space from
-	     * our running freeblocks. Don't worry about
-	     * overlaps in existing allocated windows; we
-	     * may be overstating their sizes anyway.
-	     */
-
-	    if (base && size) {
-		if (space == PCIIO_SPACE_IO) {
-		    pcibr_freeblock_sub(&pci_io_fb,
-					&pci_io_fl,
-					base, size);
-		} else {
-		    pcibr_freeblock_sub(&pci_lo_fb,
-					&pci_lo_fl,
-					base, size);
-		    pcibr_freeblock_sub(&pci_hi_fb,
-					&pci_hi_fl,
-					base, size);
-		}	
-	    }
-#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
-	    /*
-	     * IOC3 BASE_ADDR* BUG WORKAROUND
-	     *
-	     
-	     * If we write to BASE1 on the IOC3, the
-	     * data in BASE0 is replaced. The
-	     * original workaround was to remember
-	     * the value of BASE0 and restore it
-	     * when we ran off the end of the BASE
-	     * registers; however, a later
-	     * workaround was added (I think it was
-	     * rev 1.44) to avoid setting up
-	     * anything but BASE0, with the comment
-	     * that writing all ones to BASE1 set
-	     * the enable-parity-error test feature
-	     * in IOC3's SCR bit 14.
-	     *
-	     * So, unless we defer doing any PCI
-	     * space allocation until drivers
-	     * attach, and set up a way for drivers
-	     * (the IOC3 in paricular) to tell us
-	     * generically to keep our hands off
-	     * BASE registers, we gotta "know" about
-	     * the IOC3 here.
-	     *
-	     * Too bad the PCI folks didn't reserve the
-	     * all-zero value for 'no BASE here' (it is a
-	     * valid code for an uninitialized BASE in
-	     * 32-bit PCI memory space).
-	     */
-	    
-	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
-		(device == IOC3_DEVICE_ID_NUM))
-		break;
-#endif
-	    if (code == PCI_BA_MEM_64BIT) {
-		win++;		/* skip upper half */
-#ifdef LITTLE_ENDIAN
-		wptr[((win*4)^4)/4] = 0;	/* which must be zero */
-#else 
-		wptr[win] = 0;	/* which must be zero */
-#endif /* LITTLE_ENDIAN */
-	    }
-	}				/* next win */
-    }				/* next func */
-
-    /* Store back the values for allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_STORE();
-    return(0);
-}					
-
-/*
- * pcibr_slot_info_free
- *	Remove all the PCI infrastructural information associated
- * 	with a particular PCI device.
- */
-int
-pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
-                     pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    int			nfunc;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-#if !defined(CONFIG_IA64_SGI_SN1)
-    /* Clean out all the base registers */
-    bridge = pcibr_soft->bs_base;
-    cfgw = bridge->b_type0_cfg_dev[slot].l;
-    wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-    
-    for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) 
-#ifdef LITTLE_ENDIAN
-	wptr[((win*4)^4)/4] = 0;
-#else
-	wptr[win] = 0;
-#endif  /* LITTLE_ENDIAN */
-#endif	/* !CONFIG_IA64_SGI_SN1 */
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-
-    pcibr_device_info_free(pcibr_vhdl, slot);
-
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    DELA(pcibr_infoh,nfunc);
-    pcibr_soft->bs_slot[slot].bss_ninfo = 0;
-
-    return(0);
-}
-
-int as_debug = 0;
-/*
- * pcibr_slot_addr_space_init
- *	Reserve chunks of PCI address space as required by 
- * 	the base registers in the card.
- */
-int
-pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
-			   pciio_slot_t	slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    bridge_t		*bridge;
-    iopaddr_t		pci_io_fb, pci_io_fl;
-    iopaddr_t		pci_lo_fb, pci_lo_fl;
-    iopaddr_t		pci_hi_fb, pci_hi_fl;
-    size_t              align;
-    iopaddr_t           mask;
-    int		    	nbars;
-    int		       	nfunc;
-    int			func;
-    int			win;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /* Get the current values for the allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
-
-    if (as_debug)
-#ifdef LATER
-    PCI_ADDR_SPACE_LIMITS_PRINT();
-#endif
-    /* allocate address space,
-     * for windows that have not been
-     * previously assigned.
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	return(0);
-    }
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    if (nfunc < 1)
-	return(EINVAL);
-
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    if (!pcibr_infoh)
-	return(EINVAL);
-
-    /*
-     * Try to make the DevIO windows not
-     * overlap by pushing the "io" and "hi"
-     * allocation areas up to the next one
-     * or two megabyte bound. This also
-     * keeps them from being zero.
-     *
-     * DO NOT do this with "pci_lo" since
-     * the entire "lo" area is only a
-     * megabyte, total ...
-     */
-    align = (slot < 2) ? 0x200000 : 0x100000;
-    mask = -align;
-    pci_io_fb = (pci_io_fb + align - 1) & mask;
-    pci_hi_fb = (pci_hi_fb + align - 1) & mask;
-
-    for (func = 0; func < nfunc; ++func) {
-	cfg_p                   cfgw;
-	cfg_p                   wptr;
-	pciio_space_t           space;
-	iopaddr_t               base;
-	size_t                  size;
-	cfg_p                   pci_cfg_cmd_reg_p;
-	unsigned                pci_cfg_cmd_reg;
-	unsigned                pci_cfg_cmd_reg_add = 0;
-
-	pcibr_info = pcibr_infoh[func];
-
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-	
-	cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	nbars = PCI_CFG_BASE_ADDRS;
-#else
-	if ((do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
-	    nbars = 2;
-	else
-	    nbars = PCI_CFG_BASE_ADDRS;
-#endif
-
-	for (win = 0; win < nbars; ++win) {
-
-	    space = pcibr_info->f_window[win].w_space;
-	    base = pcibr_info->f_window[win].w_base;
-	    size = pcibr_info->f_window[win].w_size;
-	    
-	    if (size < 1)
-		continue;
-
-	    if (base >= size) {
-#if DEBUG && PCI_DEBUG
-		printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by prom\n",
-			slot, func, win, space, base, base + size - 1);
-#endif
-		continue;		/* already allocated */
-	    }
-	    align = size;		/* ie. 0x00001000 */
-	    if (align < _PAGESZ)
-		align = _PAGESZ;	/* ie. 0x00004000 */
-	    mask = -align;		/* ie. 0xFFFFC000 */
-
-	    switch (space) {
-	    case PCIIO_SPACE_IO:
-		base = (pci_io_fb + align - 1) & mask;
-		if ((base + size) > pci_io_fl) {
-		    base = 0;
-		    break;
-		}
-		pci_io_fb = base + size;
-		break;
-		
-	    case PCIIO_SPACE_MEM:
-#ifdef LITTLE_ENDIAN
-		if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) ==
-#else
-		if ((wptr[win] & PCI_BA_MEM_LOCATION) ==
-#endif  /* LITTLE_ENDIAN */
-		    PCI_BA_MEM_1MEG) {
-		    /* allocate from 20-bit PCI space */
-		    base = (pci_lo_fb + align - 1) & mask;
-		    if ((base + size) > pci_lo_fl) {
-			base = 0;
-			break;
-		    }
-		    pci_lo_fb = base + size;
-		} else {
-		    /* allocate from 32-bit or 64-bit PCI space */
-		    base = (pci_hi_fb + align - 1) & mask;
-		    if ((base + size) > pci_hi_fl) {
-			base = 0;
-			break;
-		    }
-		    pci_hi_fb = base + size;
-		}
-		break;
-		
-	    default:
-		base = 0;
-#if DEBUG && PCI_DEBUG
-		printk("pcibr: slot %d window %d had bad space code %d\n",
-			slot, win, space);
-#endif
-	    }
-	    pcibr_info->f_window[win].w_base = base;
-#ifdef LITTLE_ENDIAN
-	    wptr[((win*4)^4)/4] = base;
-#if DEBUG && PCI_DEBUG
-		printk("Setting base address 0x%p base 0x%x\n", &(wptr[((win*4)^4)/4]), base);
-#endif
-#else
-	    wptr[win] = base;
-#endif  /* LITTLE_ENDIAN */
-
-#if DEBUG && PCI_DEBUG
-	    if (base >= size)
-		printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibr\n",
-			slot, func, win, space, base, base + size - 1);
-	    else
-		printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%p\n",
-			slot, func, win, size, space);
-#endif
-	}				/* next base */
-
-	/*
-	 * Allocate space for the EXPANSION ROM
-	 * NOTE: DO NOT DO THIS ON AN IOC3,
-	 * as it blows the system away.
-	 */
-	base = size = 0;
-	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
-	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
-
-	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
-#ifdef LITTLE_ENDIAN
-	    wptr[1] = 0xFFFFF000;
-	    mask = wptr[1];
-#else
-	    *wptr = 0xFFFFF000;
-	    mask = *wptr;
-#endif  /* LITTLE_ENDIAN */
-	    if (mask & 0xFFFFF000) {
-		size = mask & -mask;
-		align = size;
-		if (align < _PAGESZ)
-		    align = _PAGESZ;
-		mask = -align;
-		base = (pci_hi_fb + align - 1) & mask;
-		if ((base + size) > pci_hi_fl)
-		    base = size = 0;
-		else {
-		    pci_hi_fb = base + size;
-#ifdef LITTLE_ENDIAN
-		    wptr[1] = base;
-#else
-		    *wptr = base;
-#endif  /* LITTLE_ENDIAN */
-#if DEBUG && PCI_DEBUG
-		    printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)\n",
-			    pcibr_soft->bs_name, slot,
-			    base, base + size - 1);
-#endif
-		}
-	    }
-	}
-	pcibr_info->f_rbase = base;
-	pcibr_info->f_rsize = size;
-	
-	/*
-	 * if necessary, update the board's
-	 * command register to enable decoding
-	 * in the windows we added.
-	 *
-	 * There are some bits we always want to
-	 * be sure are set.
-	 */
-	pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
-
-	/*
-	 * The Adaptec 1160 FC Controller WAR #767995:
-	 * The part incorrectly ignores the upper 32 bits of a 64 bit
-	 * address when decoding references to it's registers so to
-	 * keep it from responding to a bus cycle that it shouldn't
-	 * we only use I/O space to get at it's registers.  Don't
-	 * enable memory space accesses on that PCI device.
-	 */
-	#define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */
-	#define FCADP_DEVID 0x1160  /* Adaptec 1160 Device ID from fcadp.h */
-
-	if ((pcibr_info->f_vendor != FCADP_VENDID) ||
-	    (pcibr_info->f_device != FCADP_DEVID))
-	    pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE;
-
-	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
-
-	pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4;
-	pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p;
-#if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
-	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
-	    fast_back_to_back_enable = 0;
-#endif
-	pci_cfg_cmd_reg &= 0xFFFF;
-	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
-	    *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add;
-	
-    }				/* next func */
-
-    /* Now that we have allocated new chunks of PCI address spaces to this
-     * card we need to update the bookkeeping values which indicate
-     * the current PCI address space allocations.
-     */
-    PCI_ADDR_SPACE_LIMITS_STORE();
-    return(0);
-}
-
-/*
- * pcibr_slot_device_init
- * 	Setup the device register in the bridge for this PCI slot.
- */
-int
-pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
-		       pciio_slot_t slot)
-{
-    pcibr_soft_t	 pcibr_soft;
-    bridge_t		*bridge;
-    bridgereg_t		 devreg;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /*
-     * Adjustments to Device(x)
-     * and init of bss_device shadow
-     */
-    devreg = bridge->b_device[slot].reg;
-    devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS;
-    devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN;
-#ifdef LITTLE_ENDIAN
-    devreg |= BRIDGE_DEV_DEV_SWAP;
-#endif
-    pcibr_soft->bs_slot[slot].bss_device = devreg;
-    bridge->b_device[slot].reg = devreg;
-
-#if DEBUG && PCI_DEBUG
-	printk("pcibr Device(%d): 0x%lx\n", slot, bridge->b_device[slot].reg);
-#endif
-
-#if DEBUG && PCI_DEBUG
-    printk("pcibr: PCI space allocation done.\n");
-#endif
-
-    return(0);
-}
-
-/*
- * pcibr_slot_guest_info_init
- *	Setup the host/guest relations for a PCI slot.
- */
-int
-pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
-			   pciio_slot_t	slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    pcibr_soft_slot_t	slotp;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    /* create info and verticies for guest slots;
-     * for compatibilitiy macros, create info
-     * for even unpopulated slots (but do not
-     * build verticies for them).
-     */
-    if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) {
-	NEWA(pcibr_infoh, 1);
-	pcibr_soft->bs_slot[slot].bss_ninfo = 1;
-	pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
-
-	pcibr_info = pcibr_device_info_new
-	    (pcibr_soft, slot, PCIIO_FUNC_NONE,
-	     PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
-
-	if (pcibr_soft->bs_slot[slot].has_host) {
-	    slotp->slot_conn = pciio_device_info_register
-		(pcibr_vhdl, &pcibr_info->f_c);
-	}
-    }
-
-    /* generate host/guest relations
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	int  host = pcibr_soft->bs_slot[slot].host_slot;
-	pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host];
-
-	hwgraph_edge_add(slotp->slot_conn,
-			 host_slotp->slot_conn,
-			 EDGE_LBL_HOST);
-
-	/* XXX- only gives us one guest edge per
-	 * host. If/when we have a host with more than
-	 * one guest, we will need to figure out how
-	 * the host finds all its guests, and sorts
-	 * out which one is which.
-	 */
-	hwgraph_edge_add(host_slotp->slot_conn,
-			 slotp->slot_conn,
-			 EDGE_LBL_GUEST);
-    }
-
-    return(0);
-}
-
-/*
- * pcibr_slot_initial_rrb_alloc
- *	Allocate a default number of rrbs for this slot on 
- * 	the two channels.  This is dictated by the rrb allocation
- * 	strategy routine defined per platform.
- */
-
-int
-pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
-			     pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    bridge_t		*bridge;
-    int                 c0, c1;
-    int			r;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /* How may RRBs are on this slot?
-     */
-    c0 = do_pcibr_rrb_count_valid(bridge, slot);
-    c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL);
-
-#if PCIBR_RRB_DEBUG
-    printk("pcibr_attach: slot %d started with %d+%d\n", slot, c0, c1);
-#endif
-
-    /* Do we really need any?
-     */
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    pcibr_info = pcibr_infoh[0];
-    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
-	!pcibr_soft->bs_slot[slot].has_host) {
-	if (c0 > 0)
-	    do_pcibr_rrb_free(bridge, slot, c0);
-	if (c1 > 0)
-	    do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1);
-	pcibr_soft->bs_rrb_valid[slot] = 0x1000;
-	pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000;
-	return(ENODEV);
-    }
-
-    pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1;
-    pcibr_soft->bs_rrb_valid[slot] = c0;
-    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1;
-
-    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
-    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
-
-    r = 3 - (c0 + c1);
-
-    if (r > 0) {
-	pcibr_soft->bs_rrb_res[slot] = r;
-	pcibr_soft->bs_rrb_avail[slot & 1] -= r;
-    }
-
-#if PCIBR_RRB_DEBUG
-    printk("\t%d+%d+%d",
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-    printk("\n");
-#endif
-
-    return(0);
-}
-
-/*
- * pcibr_slot_call_device_attach
- *	This calls the associated driver attach routine for the PCI
- * 	card in this slot.
- */
-int
-pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
-			      pciio_slot_t slot,
-			      int          drv_flags)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    async_attach_t	aa = NULL;
-    int			func;
-    devfs_handle_t	xconn_vhdl,conn_vhdl;
-    int			nfunc;
-    int                 error_func;
-    int                 error_slot = 0;
-    int                 error = ENODEV;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-
-    if (pcibr_soft->bs_slot[slot].has_host) {
-        return(EPERM);
-    }
-    
-    xconn_vhdl = pcibr_soft->bs_conn;
-    aa = async_attach_get_info(xconn_vhdl);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-	pcibr_info = pcibr_infoh[func];
-	
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-
-	conn_vhdl = pcibr_info->f_vertex;
-
-	/* If the PCI device has been disabled in the prom,
-	 * do not set it up for driver attach. NOTE: usrpci
-	 * and pciba will not "see" this connection point!
-	 */
-	if (device_admin_info_get(conn_vhdl, ADMIN_LBL_DISABLED)) {
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	    PRINT_WARNING("pcibr_slot_call_device_attach: %v disabled\n", 
-		    conn_vhdl);
-#endif
-	    continue;
-	}
-#ifdef LATER
-	/*
-	 * Activate if and when we support cdl.
-	 */
-	if (aa)
-	    async_attach_add_info(conn_vhdl, aa);
-#endif	/* LATER */
-
-	error_func = pciio_device_attach(conn_vhdl, drv_flags);
-
-        pcibr_info->f_att_det_error = error_func;
-
-	if (error_func)
-	    error_slot = error_func;
-
-        error = error_slot;
-
-    }				/* next func */
-
-    if (error) {
-	if ((error != ENODEV) && (error != EUNATCH))
-	    pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
-    } else {
-        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
-    }
-        
-    return(error);
-}
-
-/*
- * pcibr_slot_call_device_detach
- *	This calls the associated driver detach routine for the PCI
- * 	card in this slot.
- */
-int
-pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
-			      pciio_slot_t slot,
-			      int          drv_flags)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    int			func;
-    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
-    int			nfunc;
-    int                 error_func;
-    int                 error_slot = 0;
-    int                 error = ENODEV;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    if (pcibr_soft->bs_slot[slot].has_host)
-        return(EPERM);
-
-    /* Make sure that we do not detach a system critical function vertex */
-    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-	pcibr_info = pcibr_infoh[func];
-	
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-
-	conn_vhdl = pcibr_info->f_vertex;
-
-	error_func = pciio_device_detach(conn_vhdl, drv_flags);
-
-        pcibr_info->f_att_det_error = error_func;
-
-	if (error_func)
-	    error_slot = error_func;
-
-	error = error_slot;
-
-    }				/* next func */
-
-    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
-
-    if (error) {
-	if ((error != ENODEV) && (error != EUNATCH))
-            pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
-    } else {
-        if (conn_vhdl != GRAPH_VERTEX_NONE) 
-            pcibr_device_unregister(conn_vhdl);
-        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
-    }
-        
-    return(error);
-}
-
-/*
- * pcibr_slot_detach
- *	This is a place holder routine to keep track of all the
- *	slot-specific freeing that needs to be done.
- */
-int
-pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
-		  pciio_slot_t slot,
-		  int          drv_flags)
-{
-    int		  error;
-    
-    /* Call the device detach function */
-    error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
-    return (error);
-
-}
-
-/*
- * pcibr_is_slot_sys_critical
- *      Check slot for any functions that are system critical.
- *      Return 1 if any are system critical or 0 otherwise.
- *
- *      This function will always return 0 when called by 
- *      pcibr_attach() because the system critical vertices 
- *      have not yet been set in the hwgraph.
- */
-int
-pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
-                      pciio_slot_t slot)
-{
-    pcibr_soft_t        pcibr_soft;
-    pcibr_info_h        pcibr_infoh;
-    pcibr_info_t        pcibr_info;
-    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
-    int                 nfunc;
-    int                 func;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-        return(0);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-        pcibr_info = pcibr_infoh[func];
-        if (!pcibr_info)
-            continue;
-
-        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-            continue;
-
-        conn_vhdl = pcibr_info->f_vertex;
-        if (is_sys_critical_vertex(conn_vhdl)) { 
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-            PRINT_WARNING("%v is a system critical device vertex\n", conn_vhdl);
-#else
-            PRINT_WARNING("%p is a system critical device vertex\n", conn_vhdl);
-#endif
-            return(1); 
-        }
-
-    }
-
-    return(0);
-}
-
-/*
- * pcibr_device_unregister
- *	This frees up any hardware resources reserved for this PCI device
- * 	and removes any PCI infrastructural information setup for it.
- *	This is usually used at the time of shutting down of the PCI card.
- */
-int
-pcibr_device_unregister(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	 pciio_info;
-    devfs_handle_t	 pcibr_vhdl;
-    pciio_slot_t	 slot;
-    pcibr_soft_t	 pcibr_soft;
-    bridge_t		*bridge;
-    int			 error_call;
-    int			 error = 0;
-
-    pciio_info = pciio_info_get(pconn_vhdl);
-
-    pcibr_vhdl = pciio_info_master_get(pciio_info);
-    slot = pciio_info_slot_get(pciio_info);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge = pcibr_soft->bs_base;
-
-    /* Clear all the hardware xtalk resources for this device */
-    xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot);
-
-    /* Flush all the rrbs */
-    pcibr_rrb_flush(pconn_vhdl);
-
-    /* Free the rrbs allocated to this slot */
-    error_call = do_pcibr_rrb_free(bridge, slot, 
-		                   pcibr_soft->bs_rrb_valid[slot] +
-		                   pcibr_soft->bs_rrb_valid[slot + 
-                                   PCIBR_RRB_SLOT_VIRTUAL]);
-
-    if (error_call)
-        error = ERANGE;
-
-    pcibr_soft->bs_rrb_valid[slot] = 0;
-    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0;
-    pcibr_soft->bs_rrb_res[slot] = 0;
-
-    /* Flush the write buffers !! */
-    error_call = pcibr_wrb_flush(pconn_vhdl);
-
-    if (error_call)
-        error = error_call;
-
-    /* Clear the information specific to the slot */
-    error_call = pcibr_slot_info_free(pcibr_vhdl, slot);
-
-    if (error_call)
-        error = error_call;
-
-    return(error);
-    
-}
-
-/* 
- * build a convenience link path in the
- * form of ".../<iobrick>/bus/<busnum>"
- * 
- * returns 1 on success, 0 otherwise
- *
- * depends on hwgraph separator == '/'
- */
-int
-pcibr_bus_cnvlink(devfs_handle_t f_c, int slot)
-{
-        char dst[MAXDEVNAME];
-	char *dp = dst;
-        char *cp, *xp;
-        int widgetnum;
-        char pcibus[8];
-	devfs_handle_t nvtx, svtx;
-	int rv;
-
-#if DEBUG
-	printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", 
-		slot, f_c);
-	{
-		int pos;
-		char dname[256];
-		pos = devfs_generate_path(f_c, dname, 256);
-		printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-	}
-#endif
-
-	if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME))
-		return 0;
-
-	/* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */
-
-	/* find the widget number */
-	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
-	if (xp == NULL)
-		return 0;
-	widgetnum = atoi(xp+7);
-	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
-		return 0;
-
-	/* remove "/pci/direct" from path */
-	cp = strstr(dst, "/" EDGE_LBL_PCI "/" "direct");
-	if (cp == NULL)
-		return 0;
-	*cp = (char)NULL;
-
-	/* get the vertex for the widget */
-	if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx))	
-		return 0;
-
-	*xp = (char)NULL;		/* remove "/xtalk/..." from path */
-
-	/* dst example now == /hw/module/001c02/Pbrick */
-
-	/* get the bus number */
-        strcat(dst, "/bus");
-        sprintf(pcibus, "%d", p_busnum[widgetnum]);
-
-	/* link to bus to widget */
-	rv = hwgraph_path_add(NULL, dp, &nvtx);
-	if (GRAPH_SUCCESS == rv)
-		rv = hwgraph_edge_add(nvtx, svtx, pcibus);
-
-	return (rv == GRAPH_SUCCESS);
-}
-
-
-/*
- *    pcibr_attach: called every time the crosstalk
- *      infrastructure is asked to initialize a widget
- *      that matches the part number we handed to the
- *      registration routine above.
- */
-/*ARGSUSED */
-int
-pcibr_attach(devfs_handle_t xconn_vhdl)
-{
-    /* REFERENCED */
-    graph_error_t           rc;
-    devfs_handle_t            pcibr_vhdl;
-    devfs_handle_t            ctlr_vhdl;
-    bridge_t               *bridge = NULL;
-    bridgereg_t             id;
-    int                     rev;
-    pcibr_soft_t            pcibr_soft;
-    pcibr_info_t            pcibr_info;
-    xwidget_info_t          info;
-    xtalk_intr_t            xtalk_intr;
-    device_desc_t           dev_desc;
-    int                     slot;
-    int                     ibit;
-    devfs_handle_t            noslot_conn;
-    char                    devnm[MAXDEVNAME], *s;
-    pcibr_hints_t           pcibr_hints;
-    bridgereg_t             b_int_enable;
-    unsigned                rrb_fixed = 0;
-
-    iopaddr_t               pci_io_fb, pci_io_fl;
-    iopaddr_t               pci_lo_fb, pci_lo_fl;
-    iopaddr_t               pci_hi_fb, pci_hi_fl;
-
-    int                     spl_level;
-#ifdef LATER
-    char		    *nicinfo = (char *)0;
-#endif
-
-#if PCI_FBBE
-    int                     fast_back_to_back_enable;
-#endif
-    l1sc_t		    *scp;
-    nasid_t		    nasid;
-
-    async_attach_t          aa = NULL;
-
-    aa = async_attach_get_info(xconn_vhdl);
-
-#if DEBUG && ATTACH_DEBUG
-    printk("pcibr_attach: xconn_vhdl=  %p\n", xconn_vhdl);
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(xconn_vhdl, dname, 256);
-	printk("%s : path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif
-
-    /* Setup the PRB for the bridge in CONVEYOR BELT
-     * mode. PRBs are setup in default FIRE-AND-FORGET
-     * mode during the initialization.
-     */
-    hub_device_flags_set(xconn_vhdl, HUB_PIO_CONVEYOR);
-
-    bridge = (bridge_t *)
-	xtalk_piotrans_addr(xconn_vhdl, NULL,
-			    0, sizeof(bridge_t), 0);
-
-#ifndef MEDUSA_HACK
-    if ((bridge->b_wid_stat & BRIDGE_STAT_PCI_GIO_N) == 0)
-	return -1;			/* someone else handles GIO bridges. */
-#endif
-
-#ifdef BRINGUP
-    if (XWIDGET_PART_REV_NUM(bridge->b_wid_id) == XBRIDGE_PART_REV_A)
-	NeedXbridgeSwap = 1;
-#endif
-
-    /*
-     * Create the vertex for the PCI bus, which we
-     * will also use to hold the pcibr_soft and
-     * which will be the "master" vertex for all the
-     * pciio connection points we will hang off it.
-     * This needs to happen before we call nic_bridge_vertex_info
-     * as we are some of the *_vmc functions need access to the edges.
-     *
-     * Opening this vertex will provide access to
-     * the Bridge registers themselves.
-     */
-    rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl);
-    ASSERT(rc == GRAPH_SUCCESS);
-
-    ctlr_vhdl = NULL;
-    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
-                0, DEVFS_FL_AUTO_DEVNUM,
-                0, 0,
-                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                &pcibr_fops, NULL);
-
-    ASSERT(ctlr_vhdl != NULL);
-
-    /*
-     * decode the nic, and hang its stuff off our
-     * connection point where other drivers can get
-     * at it.
-     */
-#ifdef LATER
-    nicinfo = BRIDGE_VERTEX_MFG_INFO(xconn_vhdl, (nic_data_t) & bridge->b_nic);
-#endif
-
-    /*
-     * Get the hint structure; if some NIC callback
-     * marked this vertex as "hands-off" then we
-     * just return here, before doing anything else.
-     */
-    pcibr_hints = pcibr_hints_get(xconn_vhdl, 0);
-
-    if (pcibr_hints && pcibr_hints->ph_hands_off)
-	return -1;			/* generic operations disabled */
-
-    id = bridge->b_wid_id;
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev);
-
-    /*
-     * allocate soft state structure, fill in some
-     * fields, and hook it up to our vertex.
-     */
-    NEW(pcibr_soft);
-    BZERO(pcibr_soft, sizeof *pcibr_soft);
-    pcibr_soft_set(pcibr_vhdl, pcibr_soft);
-
-    pcibr_soft->bs_conn = xconn_vhdl;
-    pcibr_soft->bs_vhdl = pcibr_vhdl;
-    pcibr_soft->bs_base = bridge;
-    pcibr_soft->bs_rev_num = rev;
-    pcibr_soft->bs_intr_bits = pcibr_intr_bits;
-    if (is_xbridge(bridge)) {
-	pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES;
-	pcibr_soft->bs_xbridge = 1;
-    } else {
-	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
-	pcibr_soft->bs_xbridge = 0;
-    }
-
-    nasid = NASID_GET(bridge);
-    scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    pcibr_soft->bs_l1sc = scp;
-    pcibr_soft->bs_moduleid = iobrick_module_get(scp);
-    pcibr_soft->bsi_err_intr = 0;
-
-    /* Bridges up through REV C
-     * are unable to set the direct
-     * byteswappers to BYTE_STREAM.
-     */
-    if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) {
-	pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES;
-	pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES;
-    }
-#if PCIBR_SOFT_LIST
-    {
-	pcibr_list_p            self;
-
-	NEW(self);
-	self->bl_soft = pcibr_soft;
-	self->bl_vhdl = pcibr_vhdl;
-	self->bl_next = pcibr_list;
-	self->bl_next = swap_ptr((void **) &pcibr_list, (void *)self);
-    }
-#endif
-
-    /*
-     * get the name of this bridge vertex and keep the info. Use this
-     * only where it is really needed now: like error interrupts.
-     */
-    s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME);
-    pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(pcibr_soft->bs_name, s);
-
-#if SHOW_REVS || DEBUG
-#if !DEBUG
-    if (kdebug)
-#endif
-	printk("%sBridge ASIC: rev %s (code=0x%x) at %s\n",
-		is_xbridge(bridge) ? "X" : "",
-		(rev == BRIDGE_PART_REV_A) ? "A" :
-		(rev == BRIDGE_PART_REV_B) ? "B" :
-		(rev == BRIDGE_PART_REV_C) ? "C" :
-		(rev == BRIDGE_PART_REV_D) ? "D" :
-		(rev == XBRIDGE_PART_REV_A) ? "A" :
-		(rev == XBRIDGE_PART_REV_B) ? "B" :
-		"unknown",
-		rev, pcibr_soft->bs_name);
-#endif
-
-    info = xwidget_info_get(xconn_vhdl);
-    pcibr_soft->bs_xid = xwidget_info_id_get(info);
-    pcibr_soft->bs_master = xwidget_info_master_get(info);
-    pcibr_soft->bs_mxid = xwidget_info_masterid_get(info);
-
-    /*
-     * Init bridge lock.
-     */
-    spin_lock_init(&pcibr_soft->bs_lock);
-
-    /*
-     * If we have one, process the hints structure.
-     */
-    if (pcibr_hints) {
-	rrb_fixed = pcibr_hints->ph_rrb_fixed;
-
-	pcibr_soft->bs_rrb_fixed = rrb_fixed;
-
-	if (pcibr_hints->ph_intr_bits)
-	    pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;
-
-	for (slot = 0; slot < 8; ++slot) {
-	    int                     hslot = pcibr_hints->ph_host_slot[slot] - 1;
-
-	    if (hslot < 0) {
-		pcibr_soft->bs_slot[slot].host_slot = slot;
-	    } else {
-		pcibr_soft->bs_slot[slot].has_host = 1;
-		pcibr_soft->bs_slot[slot].host_slot = hslot;
-	    }
-	}
-    }
-    /*
-     * set up initial values for state fields
-     */
-    for (slot = 0; slot < 8; ++slot) {
-	pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;
-	pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;
-	pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;
-	pcibr_soft->bs_slot[slot].bss_ext_ates_active = ATOMIC_INIT(0);
-    }
-
-    for (ibit = 0; ibit < 8; ++ibit) {
-	pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_stat = 
-							&(bridge->b_int_status);
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;
-    }
-
-    /*
-     * connect up our error handler
-     */
-    xwidget_error_register(xconn_vhdl, pcibr_error_handler, pcibr_soft);
-
-    /*
-     * Initialize various Bridge registers.
-     */
-
-    /*
-     * On pre-Rev.D bridges, set the PCI_RETRY_CNT
-     * to zero to avoid dropping stores. (#475347)
-     */
-    if (rev < BRIDGE_PART_REV_D)
-	bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK;
-
-    /*
-     * Clear all pending interrupts.
-     */
-    bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
-
-    /*
-     * Until otherwise set up,
-     * assume all interrupts are
-     * from slot 7.
-     */
-    bridge->b_int_device = (uint32_t) 0xffffffff;
-
-    {
-	bridgereg_t             dirmap;
-	paddr_t                 paddr;
-	iopaddr_t               xbase;
-	xwidgetnum_t            xport;
-	iopaddr_t               offset;
-	int                     num_entries = 0;
-	int                     entry;
-	cnodeid_t		cnodeid;
-	nasid_t			nasid;
-	char		       *node_val;
-	devfs_handle_t		node_vhdl;
-	char			vname[MAXDEVNAME];
-
-	/* Set the Bridge's 32-bit PCI to XTalk
-	 * Direct Map register to the most useful
-	 * value we can determine.  Note that we
-	 * must use a single xid for all of:
-	 *      direct-mapped 32-bit DMA accesses
-	 *      direct-mapped 64-bit DMA accesses
-	 *      DMA accesses through the PMU
-	 *      interrupts
-	 * This is the only way to guarantee that
-	 * completion interrupts will reach a CPU
-	 * after all DMA data has reached memory.
-	 * (Of course, there may be a few special
-	 * drivers/controllers that explicitly manage
-	 * this ordering problem.)
-	 */
-
-	cnodeid = 0;  /* default node id */
-	/*
-	 * Determine the base address node id to be used for all 32-bit
-	 * Direct Mapping I/O. The default is node 0, but this can be changed
-	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE
-	 * attribute in the irix.sm config file. A device driver can obtain
-	 * this node value via a call to pcibr_get_dmatrans_node().
-	 */
-	node_val = device_admin_info_get(pcibr_vhdl, ADMIN_LBL_DMATRANS_NODE);
-	if (node_val != NULL) {
-	    node_vhdl = hwgraph_path_to_vertex(node_val);
-	    if (node_vhdl != GRAPH_VERTEX_NONE) {
-		cnodeid = nodevertex_to_cnodeid(node_vhdl);
-	    }
-	    if ((node_vhdl == GRAPH_VERTEX_NONE) || (cnodeid == CNODEID_NONE)) {
-		cnodeid = 0;
-		vertex_to_name(pcibr_vhdl, vname, sizeof(vname));
-		PRINT_WARNING( "Invalid hwgraph node path specified:\n     DEVICE_ADMIN: %s %s=%s\n",
-			vname, ADMIN_LBL_DMATRANS_NODE, node_val);
-	    }
-	}
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	paddr = NODE_OFFSET(nasid) + 0;
-
-	/* currently, we just assume that if we ask
-	 * for a DMA mapping to "zero" the XIO
-	 * host will transmute this into a request
-	 * for the lowest hunk of memory.
-	 */
-	xbase = xtalk_dmatrans_addr(xconn_vhdl, 0,
-				    paddr, _PAGESZ, 0);
-
-	if (xbase != XIO_NOWHERE) {
-	    if (XIO_PACKED(xbase)) {
-		xport = XIO_PORT(xbase);
-		xbase = XIO_ADDR(xbase);
-	    } else
-		xport = pcibr_soft->bs_mxid;
-
-	    offset = xbase & ((1ull << BRIDGE_DIRMAP_OFF_ADDRSHFT) - 1ull);
-	    xbase >>= BRIDGE_DIRMAP_OFF_ADDRSHFT;
-
-	    dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT;
-
-	    if (xbase)
-		dirmap |= BRIDGE_DIRMAP_OFF & xbase;
-	    else if (offset >= (512 << 20))
-		dirmap |= BRIDGE_DIRMAP_ADD512;
-
-	    bridge->b_dir_map = dirmap;
-	}
-	/*
-	 * Set bridge's idea of page size according to the system's
-	 * idea of "IO page size".  TBD: The idea of IO page size
-	 * should really go away.
-	 */
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	spl_level = splhi();
-#if IOPGSIZE == 4096
-	bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE;
-#elif IOPGSIZE == 16384
-	bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE;
-#else
-	<<<Unable to deal with IOPGSIZE >>>;
-#endif
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(spl_level);
-
-	/* Initialize internal mapping entries */
-	for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++)
-	    bridge->b_int_ate_ram[entry].wr = 0;
-
-	/*
-	 * Determine if there's external mapping SSRAM on this
-	 * bridge.  Set up Bridge control register appropriately,
-	 * inititlize SSRAM, and set software up to manage RAM
-	 * entries as an allocatable resource.
-	 *
-	 * Currently, we just use the rm* routines to manage ATE
-	 * allocation.  We should probably replace this with a
-	 * Best Fit allocator.
-	 *
-	 * For now, if we have external SSRAM, avoid using
-	 * the internal ssram: we can't turn PREFETCH on
-	 * when we use the internal SSRAM; and besides,
-	 * this also guarantees that no allocation will
-	 * straddle the internal/external line, so we
-	 * can increment ATE write addresses rather than
-	 * recomparing against BRIDGE_INTERNAL_ATES every
-	 * time.
-	 */
-	if (is_xbridge(bridge))
-		num_entries = 0;
-	else
-		num_entries = pcibr_init_ext_ate_ram(bridge);
-
-	/* we always have 128 ATEs (512 for Xbridge) inside the chip
-	 * even if disabled for debugging.
-	 */
-	pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
-	pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_attach: %d INTERNAL ATEs\n", pcibr_soft->bs_int_ate_size);
-#endif
-
-	if (num_entries > pcibr_soft->bs_int_ate_size) {
-#if PCIBR_ATE_NOTBOTH			/* for debug -- forces us to use external ates */
-	    printk("pcibr_attach: disabling internal ATEs.\n");
-	    pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
-#endif
-	    pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
-	    pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
-			   num_entries - pcibr_soft->bs_int_ate_size);
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_attach: %d EXTERNAL ATEs\n",
-		    num_entries - pcibr_soft->bs_int_ate_size);
-#endif
-	}
-    }
-
-    {
-	bridgereg_t             dirmap;
-	iopaddr_t               xbase;
-
-	/*
-	 * now figure the *real* xtalk base address
-	 * that dirmap sends us to.
-	 */
-	dirmap = bridge->b_dir_map;
-	if (dirmap & BRIDGE_DIRMAP_OFF)
-	    xbase = (iopaddr_t)(dirmap & BRIDGE_DIRMAP_OFF)
-			<< BRIDGE_DIRMAP_OFF_ADDRSHFT;
-	else if (dirmap & BRIDGE_DIRMAP_ADD512)
-	    xbase = 512 << 20;
-	else
-	    xbase = 0;
-
-	pcibr_soft->bs_dir_xbase = xbase;
-
-	/* it is entirely possible that we may, at this
-	 * point, have our dirmap pointing somewhere
-	 * other than our "master" port.
-	 */
-	pcibr_soft->bs_dir_xport =
-	    (dirmap & BRIDGE_DIRMAP_W_ID) >> BRIDGE_DIRMAP_W_ID_SHFT;
-    }
-
-    /* pcibr sources an error interrupt;
-     * figure out where to send it.
-     *
-     * If any interrupts are enabled in bridge,
-     * then the prom set us up and our interrupt
-     * has already been reconnected in mlreset
-     * above.
-     *
-     * Need to set the D_INTR_ISERR flag
-     * in the dev_desc used for allocating the
-     * error interrupt, so our interrupt will
-     * be properly routed and prioritized.
-     *
-     * If our crosstalk provider wants to
-     * fix widget error interrupts to specific
-     * destinations, D_INTR_ISERR is how it
-     * knows to do this.
-     */
-
-    dev_desc = device_desc_dup(pcibr_vhdl);
-    device_desc_flags_set(dev_desc,
-			  device_desc_flags_get(dev_desc) | D_INTR_ISERR);
-    device_desc_intr_name_set(dev_desc, "Bridge error");
-
-    xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, pcibr_vhdl);
-    ASSERT(xtalk_intr != NULL);
-
-    device_desc_free(dev_desc);
-
-    pcibr_soft->bsi_err_intr = xtalk_intr;
-
-    /*
-     * On IP35 with XBridge, we do some extra checks in pcibr_setwidint
-     * in order to work around some addressing limitations.  In order
-     * for that fire wall to work properly, we need to make sure we
-     * start from a known clean state.
-     */
-    pcibr_clearwidint(bridge);
-
-    xtalk_intr_connect(xtalk_intr,
-		       (intr_func_t) pcibr_error_intr_handler,
-		       (intr_arg_t) pcibr_soft,
-		       (xtalk_intr_setfunc_t) pcibr_setwidint,
-		       (void *) bridge,
-		       (void *) 0);
-
-    /*
-     * now we can start handling error interrupts;
-     * enable all of them.
-     * NOTE: some PCI ints may already be enabled.
-     */
-    b_int_enable = bridge->b_int_enable | BRIDGE_ISR_ERRORS;
-
-
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_int_mode = 0;		/* do not send "clear interrupt" packets */
-
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    /*
-     * Depending on the rev of bridge, disable certain features.
-     * Easiest way seems to be to force the PCIBR_NOwhatever
-     * flag to be on for all DMA calls, which overrides any
-     * PCIBR_whatever flag or even the setting of whatever
-     * from the PCIIO_DMA_class flags (or even from the other
-     * PCIBR flags, since NO overrides YES).
-     */
-    pcibr_soft->bs_dma_flags = 0;
-
-    /* PREFETCH:
-     * Always completely disabled for REV.A;
-     * at "pcibr_prefetch_enable_rev", anyone
-     * asking for PCIIO_PREFETCH gets it.
-     * Between these two points, you have to ask
-     * for PCIBR_PREFETCH, which promises that
-     * your driver knows about known Bridge WARs.
-     */
-    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
-	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
-    else if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
-	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
-
-    /* WRITE_GATHER:
-     * Disabled up to but not including the
-     * rev number in pcibr_wg_enable_rev. There
-     * is no "WAR range" as with prefetch.
-     */
-    if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
-	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
-
-    pciio_provider_register(pcibr_vhdl, &pcibr_provider);
-    pciio_provider_startup(pcibr_vhdl);
-
-    pci_io_fb = 0x00000004;		/* I/O FreeBlock Base */
-    pci_io_fl = 0xFFFFFFFF;		/* I/O FreeBlock Last */
-
-    pci_lo_fb = 0x00000010;		/* Low Memory FreeBlock Base */
-    pci_lo_fl = 0x001FFFFF;		/* Low Memory FreeBlock Last */
-
-    pci_hi_fb = 0x00200000;		/* High Memory FreeBlock Base */
-    pci_hi_fl = 0x3FFFFFFF;		/* High Memory FreeBlock Last */
-
-
-    PCI_ADDR_SPACE_LIMITS_STORE();
-
-    /* build "no-slot" connection point
-     */
-    pcibr_info = pcibr_device_info_new
-	(pcibr_soft, PCIIO_SLOT_NONE, PCIIO_FUNC_NONE,
-	 PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
-    noslot_conn = pciio_device_info_register
-	(pcibr_vhdl, &pcibr_info->f_c);
-
-    /* Remember the no slot connection point info for tearing it
-     * down during detach.
-     */
-    pcibr_soft->bs_noslot_conn = noslot_conn;
-    pcibr_soft->bs_noslot_info = pcibr_info;
-#if PCI_FBBE
-    fast_back_to_back_enable = 1;
-#endif
-
-#if PCI_FBBE
-    if (fast_back_to_back_enable) {
-	/*
-	 * All devices on the bus are capable of fast back to back, so
-	 * we need to set the fast back to back bit in all devices on
-	 * the bus that are capable of doing such accesses.
-	 */
-    }
-#endif
-
-#ifdef LATER
-    /* If the bridge has been reset then there is no need to reset
-     * the individual PCI slots.
-     */
-    for (slot = 0; slot < 8; ++slot)  
-	/* Reset all the slots */
-	(void)pcibr_slot_reset(pcibr_vhdl, slot);
-#endif
-
-    for (slot = 0; slot < 8; ++slot)
-	/* Find out what is out there */
-	(void)pcibr_slot_info_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Set up the address space for this slot in the pci land */
-	(void)pcibr_slot_addr_space_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Setup the device register */
-	(void)pcibr_slot_device_init(pcibr_vhdl, slot);
-
-#ifndef __ia64
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-    for (slot = 0; slot < 8; ++slot)  
-	/* Set up convenience links */
-	if (is_xbridge(bridge))
-		if (pcibr_soft->bs_slot[slot].bss_ninfo > 0) /* if occupied */
-			pcibr_bus_cnvlink(pcibr_info->f_vertex, slot);
-#endif
-#endif
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Setup host/guest relations */
-	(void)pcibr_slot_guest_info_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Initial RRB management */
-	(void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot);
-
-    /* driver attach routines should be called out from generic linux code */
-    for (slot = 0; slot < 8; ++slot)  
-	/* Call the device attach */
-	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
-
-    /*
-     * Each Pbrick PCI bus only has slots 1 and 2.   Similarly for
-     * widget 0xe on Ibricks.  Allocate RRB's accordingly.
-     */
-    if (pcibr_soft->bs_moduleid > 0) {
-	switch (MODULE_GET_BTCHAR(pcibr_soft->bs_moduleid)) {
-	case 'p':		/* Pbrick */
-		do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-		do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
-		break;
-	case 'i':		/* Ibrick */
-	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
-		if (pcibr_soft->bs_xid == 0xe) {
-			do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-			do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
-		}
-		else {
-		    	/* allocate one RRB for the serial port */
-			do_pcibr_rrb_autoalloc(pcibr_soft, 0, 1);
-		}
-		break;
-	} /* switch */
-    }
-
-#ifdef LATER
-    if (strstr(nicinfo, XTALK_PCI_PART_NUM)) {
-	do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-#if PCIBR_RRB_DEBUG
-	printf("\n\nFound XTALK_PCI (030-1275) at %v\n", xconn_vhdl);
-
-	printf("pcibr_attach: %v Shoebox RRB MANAGEMENT: %d+%d free\n",
-		pcibr_vhdl,
-		pcibr_soft->bs_rrb_avail[0],
-		pcibr_soft->bs_rrb_avail[1]);
-
-	for (slot = 0; slot < 8; ++slot)
-	    printf("\t%d+%d+%d",
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-
-	printf("\n");
-#endif
-    }
-#else
-	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
-#endif
-
-    if (aa)
-	    async_attach_add_info(noslot_conn, aa);
-
-    pciio_device_attach(noslot_conn, 0);
-
-
-    /* 
-     * Tear down pointer to async attach info -- async threads for
-     * bridge's descendants may be running but the bridge's work is done.
-     */
-    if (aa)
-	    async_attach_del_info(xconn_vhdl);
-
-    return 0;
-}
-/*
- * pcibr_detach:
- *	Detach the bridge device from the hwgraph after cleaning out all the 
- *	underlying vertices.
- */
-int
-pcibr_detach(devfs_handle_t xconn)
-{
-    pciio_slot_t	slot;
-    devfs_handle_t	pcibr_vhdl;
-    pcibr_soft_t	pcibr_soft;
-    bridge_t		*bridge;
-
-    /* Get the bridge vertex from its xtalk connection point */
-    if (hwgraph_traverse(xconn, EDGE_LBL_PCI, &pcibr_vhdl) != GRAPH_SUCCESS)
-	return(1);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge = pcibr_soft->bs_base;
-
-    /* Disable the interrupts from the bridge */
-    bridge->b_int_enable = 0;
-
-    /* Detach all the PCI devices talking to this bridge */
-    for(slot = 0; slot < 8; slot++) {
-#ifdef DEBUG
-	printk("pcibr_device_detach called for %p/%d\n",
-		pcibr_vhdl,slot);
-#endif
-	pcibr_slot_detach(pcibr_vhdl, slot, 0);
-    }
-
-    /* Unregister the no-slot connection point */
-    pciio_device_info_unregister(pcibr_vhdl,
-				 &(pcibr_soft->bs_noslot_info->f_c));
-
-    spin_lock_destroy(&pcibr_soft->bs_lock);
-    kfree(pcibr_soft->bs_name);
-    
-    /* Error handler gets unregistered when the widget info is 
-     * cleaned 
-     */
-    /* Free the soft ATE maps */
-    if (pcibr_soft->bs_int_ate_map)
-	rmfreemap(pcibr_soft->bs_int_ate_map);
-    if (pcibr_soft->bs_ext_ate_map)
-	rmfreemap(pcibr_soft->bs_ext_ate_map);
-
-    /* Disconnect the error interrupt and free the xtalk resources 
-     * associated with it.
-     */
-    xtalk_intr_disconnect(pcibr_soft->bsi_err_intr);
-    xtalk_intr_free(pcibr_soft->bsi_err_intr);
-
-    /* Clear the software state maintained by the bridge driver for this
-     * bridge.
-     */
-    DEL(pcibr_soft);
-    /* Remove the Bridge revision labelled info */
-    (void)hwgraph_info_remove_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, NULL);
-    /* Remove the character device associated with this bridge */
-    (void)hwgraph_edge_remove(pcibr_vhdl, EDGE_LBL_CONTROLLER, NULL);
-    /* Remove the PCI bridge vertex */
-    (void)hwgraph_edge_remove(xconn, EDGE_LBL_PCI, NULL);
-
-    return(0);
-}
-
-int
-pcibr_asic_rev(devfs_handle_t pconn_vhdl)
-{
-    devfs_handle_t            pcibr_vhdl;
-    arbitrary_info_t        ainfo;
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_traverse(pconn_vhdl, EDGE_LBL_MASTER, &pcibr_vhdl))
-	return -1;
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &ainfo))
-	return -1;
-
-    return (int) ainfo;
-}
-
-int
-pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    pciio_slot_t  slot;
-    slot = pciio_info_slot_get(pciio_info);
-    pcibr_device_write_gather_flush(pcibr_soft, slot);
-    return 0;
-}
-
-/* =====================================================================
- *    PIO MANAGEMENT
- */
-
-LOCAL iopaddr_t
-pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
-		      pciio_slot_t slot,
-		      pciio_space_t space,
-		      iopaddr_t pci_addr,
-		      size_t req_size,
-		      unsigned flags)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    unsigned                bar;	/* which BASE reg on device is decoding */
-    iopaddr_t               xio_addr = XIO_NOWHERE;
-
-    pciio_space_t           wspace;	/* which space device is decoding */
-    iopaddr_t               wbase;	/* base of device decode on PCI */
-    size_t                  wsize;	/* size of device decode on PCI */
-
-    int                     try;	/* DevIO(x) window scanning order control */
-    int                     win;	/* which DevIO(x) window is being used */
-    pciio_space_t           mspace;	/* target space for devio(x) register */
-    iopaddr_t               mbase;	/* base of devio(x) mapped area on PCI */
-    size_t                  msize;	/* size of devio(x) mapped area on PCI */
-    size_t                  mmask;	/* addr bits stored in Device(x) */
-
-    unsigned long           s;
-
-    s = pcibr_lock(pcibr_soft);
-
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	slot = pcibr_soft->bs_slot[slot].host_slot;
-	pcibr_info = pcibr_soft->bs_slot[slot].bss_infos[0];
-    }
-    if (space == PCIIO_SPACE_NONE)
-	goto done;
-
-    if (space == PCIIO_SPACE_CFG) {
-	/*
-	 * Usually, the first mapping
-	 * established to a PCI device
-	 * is to its config space.
-	 *
-	 * In any case, we definitely
-	 * do NOT need to worry about
-	 * PCI BASE registers, and
-	 * MUST NOT attempt to point
-	 * the DevIO(x) window at
-	 * this access ...
-	 */
-	if (((flags & PCIIO_BYTE_STREAM) == 0) &&
-	    ((pci_addr + req_size) <= BRIDGE_TYPE0_CFG_FUNC_OFF))
-	    xio_addr = pci_addr + BRIDGE_TYPE0_CFG_DEV(slot);
-
-	goto done;
-    }
-    if (space == PCIIO_SPACE_ROM) {
-	/* PIO to the Expansion Rom.
-	 * Driver is responsible for
-	 * enabling and disabling
-	 * decodes properly.
-	 */
-	wbase = pcibr_info->f_rbase;
-	wsize = pcibr_info->f_rsize;
-
-	/*
-	 * While the driver should know better
-	 * than to attempt to map more space
-	 * than the device is decoding, he might
-	 * do it; better to bail out here.
-	 */
-	if ((pci_addr + req_size) > wsize)
-	    goto done;
-
-	pci_addr += wbase;
-	space = PCIIO_SPACE_MEM;
-    }
-    /*
-     * reduce window mappings to raw
-     * space mappings (maybe allocating
-     * windows), and try for DevIO(x)
-     * usage (setting it if it is available).
-     */
-    bar = space - PCIIO_SPACE_WIN0;
-    if (bar < 6) {
-	wspace = pcibr_info->f_window[bar].w_space;
-	if (wspace == PCIIO_SPACE_NONE)
-	    goto done;
-
-	/* get PCI base and size */
-	wbase = pcibr_info->f_window[bar].w_base;
-	wsize = pcibr_info->f_window[bar].w_size;
-
-	/*
-	 * While the driver should know better
-	 * than to attempt to map more space
-	 * than the device is decoding, he might
-	 * do it; better to bail out here.
-	 */
-	if ((pci_addr + req_size) > wsize)
-	    goto done;
-
-	/* shift from window relative to
-	 * decoded space relative.
-	 */
-	pci_addr += wbase;
-	space = wspace;
-    } else
-	bar = -1;
-
-    /* Scan all the DevIO(x) windows twice looking for one
-     * that can satisfy our request. The first time through,
-     * only look at assigned windows; the second time, also
-     * look at PCIIO_SPACE_NONE windows. Arrange the order
-     * so we always look at our own window first.
-     *
-     * We will not attempt to satisfy a single request
-     * by concatinating multiple windows.
-     */
-    for (try = 0; try < 16; ++try) {
-	bridgereg_t             devreg;
-	unsigned                offset;
-
-	win = (try + slot) % 8;
-
-	/* If this DevIO(x) mapping area can provide
-	 * a mapping to this address, use it.
-	 */
-	msize = (win < 2) ? 0x200000 : 0x100000;
-	mmask = -msize;
-	if (space != PCIIO_SPACE_IO)
-	    mmask &= 0x3FFFFFFF;
-
-	offset = pci_addr & (msize - 1);
-
-	/* If this window can't possibly handle that request,
-	 * go on to the next window.
-	 */
-	if (((pci_addr & (msize - 1)) + req_size) > msize)
-	    continue;
-
-	devreg = pcibr_soft->bs_slot[win].bss_device;
-
-	/* Is this window "nailed down"?
-	 * If not, maybe we can use it.
-	 * (only check this the second time through)
-	 */
-	mspace = pcibr_soft->bs_slot[win].bss_devio.bssd_space;
-	if ((try > 7) && (mspace == PCIIO_SPACE_NONE)) {
-
-	    /* If this is the primary DevIO(x) window
-	     * for some other device, skip it.
-	     */
-	    if ((win != slot) &&
-		(PCIIO_VENDOR_ID_NONE !=
-		 pcibr_soft->bs_slot[win].bss_vendor_id))
-		continue;
-
-	    /* It's a free window, and we fit in it.
-	     * Set up Device(win) to our taste.
-	     */
-	    mbase = pci_addr & mmask;
-
-	    /* check that we would really get from
-	     * here to there.
-	     */
-	    if ((mbase | offset) != pci_addr)
-		continue;
-
-	    devreg &= ~BRIDGE_DEV_OFF_MASK;
-	    if (space != PCIIO_SPACE_IO)
-		devreg |= BRIDGE_DEV_DEV_IO_MEM;
-	    else
-		devreg &= ~BRIDGE_DEV_DEV_IO_MEM;
-	    devreg |= (mbase >> 20) & BRIDGE_DEV_OFF_MASK;
-
-	    /* default is WORD_VALUES.
-	     * if you specify both,
-	     * operation is undefined.
-	     */
-	    if (flags & PCIIO_BYTE_STREAM)
-		devreg |= BRIDGE_DEV_DEV_SWAP;
-	    else
-		devreg &= ~BRIDGE_DEV_DEV_SWAP;
-
-	    if (pcibr_soft->bs_slot[win].bss_device != devreg) {
-		bridge->b_device[win].reg = devreg;
-		pcibr_soft->bs_slot[win].bss_device = devreg;
-		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-
-#if DEBUG && PCI_DEBUG
-		printk("pcibr Device(%d): 0x%lx\n", win, bridge->b_device[win].reg);
-#endif
-	    }
-	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
-	    pcibr_soft->bs_slot[win].bss_devio.bssd_base = mbase;
-	    xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
-
-#if DEBUG && PCI_DEBUG
-	    printk("%s LINE %d map to space %d space desc 0x%x[%lx..%lx] for slot %d allocates DevIO(%d) devreg 0x%x\n", 
-		    __FUNCTION__, __LINE__, space, space_desc,
-		    pci_addr, pci_addr + req_size - 1,
-		    slot, win, devreg);
-#endif
-
-	    goto done;
-	}				/* endif DevIO(x) not pointed */
-	mbase = pcibr_soft->bs_slot[win].bss_devio.bssd_base;
-
-	/* Now check for request incompat with DevIO(x)
-	 */
-	if ((mspace != space) ||
-	    (pci_addr < mbase) ||
-	    ((pci_addr + req_size) > (mbase + msize)) ||
-	    ((flags & PCIIO_BYTE_STREAM) && !(devreg & BRIDGE_DEV_DEV_SWAP)) ||
-	    (!(flags & PCIIO_BYTE_STREAM) && (devreg & BRIDGE_DEV_DEV_SWAP)))
-	    continue;
-
-	/* DevIO(x) window is pointed at PCI space
-	 * that includes our target. Calculate the
-	 * final XIO address, release the lock and
-	 * return.
-	 */
-	xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
-
-#if DEBUG && PCI_DEBUG
-	printk("%s LINE %d map to space %d [0x%p..0x%p] for slot %d uses DevIO(%d)\n",
-		__FUNCTION__, __LINE__, space,  pci_addr, pci_addr + req_size - 1, slot, win);
-#endif
-	goto done;
-    }
-
-    switch (space) {
-	/*
-	 * Accesses to device decode
-	 * areas that do a not fit
-	 * within the DevIO(x) space are
-	 * modified to be accesses via
-	 * the direct mapping areas.
-	 *
-	 * If necessary, drivers can
-	 * explicitly ask for mappings
-	 * into these address spaces,
-	 * but this should never be needed.
-	 */
-    case PCIIO_SPACE_MEM:		/* "mem space" */
-    case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM32_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
-	break;
-
-    case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM64_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
-	break;
-
-    case PCIIO_SPACE_IO:		/* "i/o space" */
-	/* Bridge Hardware Bug WAR #482741:
-	 * The 4G area that maps directly from
-	 * XIO space to PCI I/O space is busted
-	 * until Bridge Rev D.
-	 */
-	if ((pcibr_soft->bs_rev_num > BRIDGE_PART_REV_C) &&
-	    ((pci_addr + BRIDGE_PCI_IO_BASE + req_size - 1) <=
-	     BRIDGE_PCI_IO_LIMIT))
-	    xio_addr = pci_addr + BRIDGE_PCI_IO_BASE;
-	break;
-    }
-
-    /* Check that "Direct PIO" byteswapping matches,
-     * try to change it if it does not.
-     */
-    if (xio_addr != XIO_NOWHERE) {
-	unsigned                bst;	/* nonzero to set bytestream */
-	unsigned               *bfp;	/* addr of record of how swapper is set */
-	unsigned                swb;	/* which control bit to mung */
-	unsigned                bfo;	/* current swapper setting */
-	unsigned                bfn;	/* desired swapper setting */
-
-	bfp = ((space == PCIIO_SPACE_IO)
-	       ? (&pcibr_soft->bs_pio_end_io)
-	       : (&pcibr_soft->bs_pio_end_mem));
-
-	bfo = *bfp;
-
-	bst = flags & PCIIO_BYTE_STREAM;
-
-	bfn = bst ? PCIIO_BYTE_STREAM : PCIIO_WORD_VALUES;
-
-	if (bfn == bfo) {		/* we already match. */
-	    ;
-	} else if (bfo != 0) {		/* we have a conflict. */
-#if DEBUG && PCI_DEBUG
-	    printk("pcibr_addr_pci_to_xio: swap conflict in space %d , was%s%s, want%s%s\n",
-		    space, 
-		    bfo & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfo & PCIIO_WORD_VALUES ? " WORD_VALUES" : "",
-		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
-#endif
-	    xio_addr = XIO_NOWHERE;
-	} else {			/* OK to make the change. */
-	    bridgereg_t             octl, nctl;
-
-	    swb = (space == PCIIO_SPACE_IO) ? BRIDGE_CTRL_IO_SWAP : BRIDGE_CTRL_MEM_SWAP;
-	    octl = bridge->b_wid_control;
-	    nctl = bst ? octl | swb : octl & ~swb;
-
-	    if (octl != nctl)		/* make the change if any */
-		bridge->b_wid_control = nctl;
-
-	    *bfp = bfn;			/* record the assignment */
-
-#if DEBUG && PCI_DEBUG
-	    printk("pcibr_addr_pci_to_xio: swap for space %d  set to%s%s\n",
-		    space, 
-		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
-#endif
-	}
-    }
-  done:
-    pcibr_unlock(pcibr_soft, s);
-    return xio_addr;
-}
-
-/*ARGSUSED6 */
-pcibr_piomap_t
-pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
-		   device_desc_t dev_desc,
-		   pciio_space_t space,
-		   iopaddr_t pci_addr,
-		   size_t req_size,
-		   size_t req_size_max,
-		   unsigned flags)
-{
-    pcibr_info_t	    pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    pcibr_piomap_t         *mapptr;
-    pcibr_piomap_t          maplist;
-    pcibr_piomap_t          pcibr_piomap;
-    iopaddr_t               xio_addr;
-    xtalk_piomap_t          xtalk_piomap;
-    unsigned long           s;
-
-    /* Make sure that the req sizes are non-zero */
-    if ((req_size < 1) || (req_size_max < 1))
-	return NULL;
-
-    /*
-     * Code to translate slot/space/addr
-     * into xio_addr is common between
-     * this routine and pcibr_piotrans_addr.
-     */
-    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
-
-    if (xio_addr == XIO_NOWHERE)
-	return NULL;
-
-    /* Check the piomap list to see if there is already an allocated
-     * piomap entry but not in use. If so use that one. Otherwise
-     * allocate a new piomap entry and add it to the piomap list
-     */
-    mapptr = &(pcibr_info->f_piomap);
-
-    s = pcibr_lock(pcibr_soft);
-    for (pcibr_piomap = *mapptr;
-	 pcibr_piomap != NULL;
-	 pcibr_piomap = pcibr_piomap->bp_next) {
-	if (pcibr_piomap->bp_mapsz == 0)
-	    break;
-    }
-
-    if (pcibr_piomap)
-	mapptr = NULL;
-    else {
-	pcibr_unlock(pcibr_soft, s);
-	NEW(pcibr_piomap);
-    }
-
-    pcibr_piomap->bp_dev = pconn_vhdl;
-    pcibr_piomap->bp_slot = pciio_slot;
-    pcibr_piomap->bp_flags = flags;
-    pcibr_piomap->bp_space = space;
-    pcibr_piomap->bp_pciaddr = pci_addr;
-    pcibr_piomap->bp_mapsz = req_size;
-    pcibr_piomap->bp_soft = pcibr_soft;
-    pcibr_piomap->bp_toc[0] = ATOMIC_INIT(0);
-
-    if (mapptr) {
-	s = pcibr_lock(pcibr_soft);
-	maplist = *mapptr;
-	pcibr_piomap->bp_next = maplist;
-	*mapptr = pcibr_piomap;
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-
-    if (pcibr_piomap) {
-	xtalk_piomap =
-	    xtalk_piomap_alloc(xconn_vhdl, 0,
-			       xio_addr,
-			       req_size, req_size_max,
-			       flags & PIOMAP_FLAGS);
-	if (xtalk_piomap) {
-	    pcibr_piomap->bp_xtalk_addr = xio_addr;
-	    pcibr_piomap->bp_xtalk_pio = xtalk_piomap;
-	} else {
-	    pcibr_piomap->bp_mapsz = 0;
-	    pcibr_piomap = 0;
-	}
-    }
-    return pcibr_piomap;
-}
-
-/*ARGSUSED */
-void
-pcibr_piomap_free(pcibr_piomap_t pcibr_piomap)
-{
-    xtalk_piomap_free(pcibr_piomap->bp_xtalk_pio);
-    pcibr_piomap->bp_xtalk_pio = 0;
-    pcibr_piomap->bp_mapsz = 0;
-}
-
-/*ARGSUSED */
-caddr_t
-pcibr_piomap_addr(pcibr_piomap_t pcibr_piomap,
-		  iopaddr_t pci_addr,
-		  size_t req_size)
-{
-    return xtalk_piomap_addr(pcibr_piomap->bp_xtalk_pio,
-			     pcibr_piomap->bp_xtalk_addr +
-			     pci_addr - pcibr_piomap->bp_pciaddr,
-			     req_size);
-}
-
-/*ARGSUSED */
-void
-pcibr_piomap_done(pcibr_piomap_t pcibr_piomap)
-{
-    xtalk_piomap_done(pcibr_piomap->bp_xtalk_pio);
-}
-
-/*ARGSUSED */
-caddr_t
-pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    pciio_space_t space,
-		    iopaddr_t pci_addr,
-		    size_t req_size,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    iopaddr_t               xio_addr;
-
-    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
-
-    if (xio_addr == XIO_NOWHERE)
-	return NULL;
-
-    return xtalk_piotrans_addr(xconn_vhdl, 0, xio_addr, req_size, flags & PIOMAP_FLAGS);
-}
-
-/*
- * PIO Space allocation and management.
- *      Allocate and Manage the PCI PIO space (mem and io space)
- *      This routine is pretty simplistic at this time, and
- *      does pretty trivial management of allocation and freeing..
- *      The current scheme is prone for fragmentation..
- *      Change the scheme to use bitmaps.
- */
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
-		     device_desc_t dev_desc,
-		     pciio_space_t space,
-		     size_t req_size,
-		     size_t alignment)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    pciio_piospace_t        piosp;
-    unsigned long           s;
-
-    iopaddr_t              *pciaddr, *pcilast;
-    iopaddr_t               start_addr;
-    size_t                  align_mask;
-
-    /*
-     * Check for proper alignment
-     */
-    ASSERT(alignment >= NBPP);
-    ASSERT((alignment & (alignment - 1)) == 0);
-
-    align_mask = alignment - 1;
-    s = pcibr_lock(pcibr_soft);
-
-    /*
-     * First look if a previously allocated chunk exists.
-     */
-    if ((piosp = pcibr_info->f_piospace)) {
-	/*
-	 * Look through the list for a right sized free chunk.
-	 */
-	do {
-	    if (piosp->free &&
-		(piosp->space == space) &&
-		(piosp->count >= req_size) &&
-		!(piosp->start & align_mask)) {
-		piosp->free = 0;
-		pcibr_unlock(pcibr_soft, s);
-		return piosp->start;
-	    }
-	    piosp = piosp->next;
-	} while (piosp);
-    }
-    ASSERT(!piosp);
-
-    switch (space) {
-    case PCIIO_SPACE_IO:
-	pciaddr = &pcibr_soft->bs_spinfo.pci_io_base;
-	pcilast = &pcibr_soft->bs_spinfo.pci_io_last;
-	break;
-    case PCIIO_SPACE_MEM:
-    case PCIIO_SPACE_MEM32:
-	pciaddr = &pcibr_soft->bs_spinfo.pci_mem_base;
-	pcilast = &pcibr_soft->bs_spinfo.pci_mem_last;
-	break;
-    default:
-	ASSERT(0);
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-
-    start_addr = *pciaddr;
-
-    /*
-     * Align start_addr.
-     */
-    if (start_addr & align_mask)
-	start_addr = (start_addr + align_mask) & ~align_mask;
-
-    if ((start_addr + req_size) > *pcilast) {
-	/*
-	 * If too big a request, reject it.
-	 */
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-    *pciaddr = (start_addr + req_size);
-
-    NEW(piosp);
-    piosp->free = 0;
-    piosp->space = space;
-    piosp->start = start_addr;
-    piosp->count = req_size;
-    piosp->next = pcibr_info->f_piospace;
-    pcibr_info->f_piospace = piosp;
-
-    pcibr_unlock(pcibr_soft, s);
-    return start_addr;
-}
-
-/*ARGSUSED */
-void
-pcibr_piospace_free(devfs_handle_t pconn_vhdl,
-		    pciio_space_t space,
-		    iopaddr_t pciaddr,
-		    size_t req_size)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-
-    pciio_piospace_t        piosp;
-    unsigned long           s;
-    char                    name[1024];
-
-    /*
-     * Look through the bridge data structures for the pciio_piospace_t
-     * structure corresponding to  'pciaddr'
-     */
-    s = pcibr_lock(pcibr_soft);
-    piosp = pcibr_info->f_piospace;
-    while (piosp) {
-	/*
-	 * Piospace free can only be for the complete
-	 * chunk and not parts of it..
-	 */
-	if (piosp->start == pciaddr) {
-	    if (piosp->count == req_size)
-		break;
-	    /*
-	     * Improper size passed for freeing..
-	     * Print a message and break;
-	     */
-	    hwgraph_vertex_name_get(pconn_vhdl, name, 1024);
-	    PRINT_WARNING("pcibr_piospace_free: error");
-	    PRINT_WARNING("Device %s freeing size (0x%lx) different than allocated (0x%lx)",
-					name, req_size, piosp->count);
-	    PRINT_WARNING("Freeing 0x%lx instead", piosp->count);
-	    break;
-	}
-	piosp = piosp->next;
-    }
-
-    if (!piosp) {
-	PRINT_WARNING(
-		"pcibr_piospace_free: Address 0x%lx size 0x%lx - No match\n",
-		pciaddr, req_size);
-	pcibr_unlock(pcibr_soft, s);
-	return;
-    }
-    piosp->free = 1;
-    pcibr_unlock(pcibr_soft, s);
-    return;
-}
-
-/* =====================================================================
- *    DMA MANAGEMENT
- *
- *      The Bridge ASIC provides three methods of doing
- *      DMA: via a "direct map" register available in
- *      32-bit PCI space (which selects a contiguous 2G
- *      address space on some other widget), via
- *      "direct" addressing via 64-bit PCI space (all
- *      destination information comes from the PCI
- *      address, including transfer attributes), and via
- *      a "mapped" region that allows a bunch of
- *      different small mappings to be established with
- *      the PMU.
- *
- *      For efficiency, we most prefer to use the 32-bit
- *      direct mapping facility, since it requires no
- *      resource allocations. The advantage of using the
- *      PMU over the 64-bit direct is that single-cycle
- *      PCI addressing can be used; the advantage of
- *      using 64-bit direct over PMU addressing is that
- *      we do not have to allocate entries in the PMU.
- */
-
-/*
- * Convert PCI-generic software flags and Bridge-specific software flags
- * into Bridge-specific Direct Map attribute bits.
- */
-LOCAL iopaddr_t
-pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft)
-{
-    iopaddr_t               attributes = 0;
-
-    /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */
-#ifdef LATER
-    ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64));
-#endif
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
-	attributes &= ~PCI64_ATTR_BAR;	/* no barrier bit */
-	attributes |= PCI64_ATTR_PREF;	/* prefetch on */
-    }
-    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
-	attributes |= PCI64_ATTR_BAR;	/* barrier bit on */
-	attributes &= ~PCI64_ATTR_PREF;	/* disable prefetch */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_PREFETCH)
-	attributes |= PCI64_ATTR_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	attributes &= ~PCI64_ATTR_PREF;
-
-    /* the swap bit is in the address attributes for xbridge */
-    if (pcibr_soft->bs_xbridge) {
-    	if (flags & PCIIO_BYTE_STREAM)
-        	attributes |= PCI64_ATTR_SWAP;
-    	if (flags & PCIIO_WORD_VALUES)
-        	attributes &= ~PCI64_ATTR_SWAP;
-    }
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_BARRIER)
-	attributes |= PCI64_ATTR_BAR;
-    if (flags & PCIBR_NOBARRIER)
-	attributes &= ~PCI64_ATTR_BAR;
-
-    if (flags & PCIBR_PREFETCH)
-	attributes |= PCI64_ATTR_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	attributes &= ~PCI64_ATTR_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	attributes |= PCI64_ATTR_PREC;
-    if (flags & PCIBR_NOPRECISE)
-	attributes &= ~PCI64_ATTR_PREC;
-
-    if (flags & PCIBR_VCHAN1)
-	attributes |= PCI64_ATTR_VIRTUAL;
-    if (flags & PCIBR_VCHAN0)
-	attributes &= ~PCI64_ATTR_VIRTUAL;
-
-    return (attributes);
-}
-
-/*
- * Convert PCI-generic software flags and Bridge-specific software flags
- * into Bridge-specific Address Translation Entry attribute bits.
- */
-LOCAL bridge_ate_t
-pcibr_flags_to_ate(unsigned flags)
-{
-    bridge_ate_t            attributes;
-
-    /* default if nothing specified:
-     * NOBARRIER
-     * NOPREFETCH
-     * NOPRECISE
-     * COHERENT
-     * Plus the valid bit
-     */
-    attributes = ATE_CO | ATE_V;
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
-	attributes &= ~ATE_BAR;		/* no barrier */
-	attributes |= ATE_PREF;		/* prefetch on */
-    }
-    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
-	attributes |= ATE_BAR;		/* barrier bit on */
-	attributes &= ~ATE_PREF;	/* disable prefetch */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_PREFETCH)
-	attributes |= ATE_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	attributes &= ~ATE_PREF;
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_BARRIER)
-	attributes |= ATE_BAR;
-    if (flags & PCIBR_NOBARRIER)
-	attributes &= ~ATE_BAR;
-
-    if (flags & PCIBR_PREFETCH)
-	attributes |= ATE_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	attributes &= ~ATE_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	attributes |= ATE_PREC;
-    if (flags & PCIBR_NOPRECISE)
-	attributes &= ~ATE_PREC;
-
-    return (attributes);
-}
-
-/*ARGSUSED */
-pcibr_dmamap_t
-pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
-		   device_desc_t dev_desc,
-		   size_t req_size_max,
-		   unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            slot;
-    xwidgetnum_t            xio_port;
-
-    xtalk_dmamap_t          xtalk_dmamap;
-    pcibr_dmamap_t          pcibr_dmamap;
-    int                     ate_count;
-    int                     ate_index;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-#ifdef IRIX
-    NEWf(pcibr_dmamap, flags);
-#else
-    /*
-     * On SNIA64, these maps are pre-allocated because pcibr_dmamap_alloc()
-     * can be called within an interrupt thread.
-     */
-    pcibr_dmamap = (pcibr_dmamap_t)get_free_pciio_dmamap(pcibr_soft->bs_vhdl);
-#endif
-
-    if (!pcibr_dmamap)
-	return 0;
-
-    xtalk_dmamap = xtalk_dmamap_alloc(xconn_vhdl, dev_desc, req_size_max,
-				      flags & DMAMAP_FLAGS);
-    if (!xtalk_dmamap) {
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_attach: xtalk_dmamap_alloc failed\n");
-#endif
-	DEL(pcibr_dmamap);
-	return 0;
-    }
-    xio_port = pcibr_soft->bs_mxid;
-    slot = pciio_info_slot_get(pciio_info);
-
-    pcibr_dmamap->bd_dev = pconn_vhdl;
-    pcibr_dmamap->bd_slot = slot;
-    pcibr_dmamap->bd_soft = pcibr_soft;
-    pcibr_dmamap->bd_xtalk = xtalk_dmamap;
-    pcibr_dmamap->bd_max_size = req_size_max;
-    pcibr_dmamap->bd_xio_port = xio_port;
-
-    if (flags & PCIIO_DMA_A64) {
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D64_BITS)) {
-	    iopaddr_t               pci_addr;
-	    int                     have_rrbs;
-	    int                     min_rrbs;
-
-	    /* Device is capable of A64 operations,
-	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
-	     * mappings using shared resources.
-	     */
-
-	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
-
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_xio_addr = 0;
-	    pcibr_dmamap->bd_pci_addr = pci_addr;
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
-		if (flags & PCIBR_VCHAN1)
-		    slot += PCIBR_RRB_SLOT_VIRTUAL;
-		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
-		if (have_rrbs < 2) {
-		    if (pci_addr & PCI64_ATTR_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
-		}
-	    }
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using direct64\n");
-#endif
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use direct64\n");
-#endif
-	flags &= ~PCIIO_DMA_A64;
-    }
-    if (flags & PCIIO_FIXED) {
-	/* warning: mappings may fail later,
-	 * if direct32 can't get to the address.
-	 */
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
-	    /* User desires DIRECT A32 operations,
-	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
-	     * mappings using shared resources.
-	     * Mapping calls may fail if target
-	     * is outside the direct32 range.
-	     */
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using direct32\n");
-#endif
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_xio_addr = pcibr_soft->bs_dir_xbase;
-	    pcibr_dmamap->bd_pci_addr = PCI32_DIRECT_BASE;
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use direct32\n");
-#endif
-	/* If the user demands FIXED and we can't
-	 * give it to him, fail.
-	 */
-	xtalk_dmamap_free(xtalk_dmamap);
-	DEL(pcibr_dmamap);
-	return 0;
-    }
-    /*
-     * Allocate Address Translation Entries from the mapping RAM.
-     * Unless the PCIBR_NO_ATE_ROUNDUP flag is specified,
-     * the maximum number of ATEs is based on the worst-case
-     * scenario, where the requested target is in the
-     * last byte of an ATE; thus, mapping IOPGSIZE+2
-     * does end up requiring three ATEs.
-     */
-    if (!(flags & PCIBR_NO_ATE_ROUNDUP)) {
-	ate_count = IOPG((IOPGSIZE - 1)	/* worst case start offset */
-		     +req_size_max	/* max mapping bytes */
-		     - 1) + 1;		/* round UP */
-    } else {	/* assume requested target is page aligned */
-	ate_count = IOPG(req_size_max   /* max mapping bytes */
-		     - 1) + 1;		/* round UP */
-    }
-
-    ate_index = pcibr_ate_alloc(pcibr_soft, ate_count);
-
-    if (ate_index != -1) {
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_PMU_BITS)) {
-	    bridge_ate_t            ate_proto;
-	    int                     have_rrbs;
-	    int                     min_rrbs;
-
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using PMU\n");
-#endif
-
-	    ate_proto = pcibr_flags_to_ate(flags);
-
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_pci_addr =
-		PCI32_MAPPED_BASE + IOPGSIZE * ate_index;
-	    /*
-	     * for xbridge the byte-swap bit == bit 29 of PCI address
-	     */
-	    if (pcibr_soft->bs_xbridge) {
-		    if (flags & PCIIO_BYTE_STREAM)
-			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
-		    /*
-		     * If swap was set in bss_device in pcibr_endian_set()
-		     * we need to change the address bit.
-		     */
-		    if (pcibr_soft->bs_slot[slot].bss_device & 
-							BRIDGE_DEV_SWAP_PMU)
-			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
-		    if (flags & PCIIO_WORD_VALUES)
-			    ATE_SWAP_OFF(pcibr_dmamap->bd_pci_addr);
-	    }
-	    pcibr_dmamap->bd_xio_addr = 0;
-	    pcibr_dmamap->bd_ate_ptr = pcibr_ate_addr(pcibr_soft, ate_index);
-	    pcibr_dmamap->bd_ate_index = ate_index;
-	    pcibr_dmamap->bd_ate_count = ate_count;
-	    pcibr_dmamap->bd_ate_proto = ate_proto;
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
-		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
-		if (have_rrbs < 2) {
-		    if (ate_proto & ATE_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
-		}
-	    }
-	    if (ate_index >= pcibr_soft->bs_int_ate_size && 
-				!pcibr_soft->bs_xbridge) {
-		bridge_t               *bridge = pcibr_soft->bs_base;
-		volatile unsigned      *cmd_regp;
-		unsigned                cmd_reg;
-		unsigned long           s;
-
-		pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM;
-
-		s = pcibr_lock(pcibr_soft);
-		cmd_regp = &(bridge->
-			     b_type0_cfg_dev[slot].
-			     l[PCI_CFG_COMMAND / 4]);
-		cmd_reg = *cmd_regp;
-		pcibr_soft->bs_slot[slot].bss_cmd_pointer = cmd_regp;
-		pcibr_soft->bs_slot[slot].bss_cmd_shadow = cmd_reg;
-		pcibr_unlock(pcibr_soft, s);
-	    }
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use PMU\n");
-#endif
-	pcibr_ate_free(pcibr_soft, ate_index, ate_count);
-    }
-    /* total failure: sorry, you just can't
-     * get from here to there that way.
-     */
-#if PCIBR_ATE_DEBUG
-    printk("pcibr_dmamap_alloc: complete failure.\n");
-#endif
-    xtalk_dmamap_free(xtalk_dmamap);
-    DEL(pcibr_dmamap);
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_dmamap_free(pcibr_dmamap_t pcibr_dmamap)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-    pciio_slot_t            slot = pcibr_dmamap->bd_slot;
-
-    unsigned                flags = pcibr_dmamap->bd_flags;
-
-    /* Make sure that bss_ext_ates_active
-     * is properly kept up to date.
-     */
-
-    if (PCIBR_DMAMAP_BUSY & flags)
-	if (PCIBR_DMAMAP_SSRAM & flags)
-	    atomic_dec(&(pcibr_soft->bs_slot[slot]. bss_ext_ates_active));
-
-    xtalk_dmamap_free(pcibr_dmamap->bd_xtalk);
-
-    if (pcibr_dmamap->bd_flags & PCIIO_DMA_A64) {
-	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_D64_BITS);
-    }
-    if (pcibr_dmamap->bd_ate_count) {
-	pcibr_ate_free(pcibr_dmamap->bd_soft,
-		       pcibr_dmamap->bd_ate_index,
-		       pcibr_dmamap->bd_ate_count);
-	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS);
-    }
-#ifdef IRIX
-    DEL(pcibr_dmamap);
-#endif
-}
-
-/*
- * Setup an Address Translation Entry as specified.  Use either the Bridge
- * internal maps or the external map RAM, as appropriate.
- */
-LOCAL bridge_ate_p
-pcibr_ate_addr(pcibr_soft_t pcibr_soft,
-	       int ate_index)
-{
-    bridge_t *bridge = pcibr_soft->bs_base;
-
-    return (ate_index < pcibr_soft->bs_int_ate_size)
-	? &(bridge->b_int_ate_ram[ate_index].wr)
-	: &(bridge->b_ext_ate_ram[ate_index]);
-}
-
-/*
- *    pcibr_addr_xio_to_pci: given a PIO range, hand
- *      back the corresponding base PCI MEM address;
- *      this is used to short-circuit DMA requests that
- *      loop back onto this PCI bus.
- */
-LOCAL iopaddr_t
-pcibr_addr_xio_to_pci(pcibr_soft_t soft,
-		      iopaddr_t xio_addr,
-		      size_t req_size)
-{
-    iopaddr_t               xio_lim = xio_addr + req_size - 1;
-    iopaddr_t               pci_addr;
-    pciio_slot_t            slot;
-
-    if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
-	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
-	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
-	return pci_addr;
-    }
-    if ((xio_addr >= BRIDGE_PCI_MEM64_BASE) &&
-	(xio_lim <= BRIDGE_PCI_MEM64_LIMIT)) {
-	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
-	return pci_addr;
-    }
-    for (slot = 0; slot < 8; ++slot)
-	if ((xio_addr >= BRIDGE_DEVIO(slot)) &&
-	    (xio_lim < BRIDGE_DEVIO(slot + 1))) {
-	    bridgereg_t             dev;
-
-	    dev = soft->bs_slot[slot].bss_device;
-	    pci_addr = dev & BRIDGE_DEV_OFF_MASK;
-	    pci_addr <<= BRIDGE_DEV_OFF_ADDR_SHFT;
-	    pci_addr += xio_addr - BRIDGE_DEVIO(slot);
-	    return (dev & BRIDGE_DEV_DEV_IO_MEM) ? pci_addr : PCI_NOWHERE;
-	}
-    return 0;
-}
-
-/* We are starting to get more complexity
- * surrounding writing ATEs, so pull
- * the writing code into this new function.
- */
-
-#if PCIBR_FREEZE_TIME
-#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs)
-#else
-#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, cmd_regs)
-#endif
-
-LOCAL unsigned
-ate_freeze(pcibr_dmamap_t pcibr_dmamap,
-#if PCIBR_FREEZE_TIME
-	   unsigned *freeze_time_ptr,
-#endif
-	   unsigned *cmd_regs)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-#ifdef LATER
-    int                     dma_slot = pcibr_dmamap->bd_slot;
-#endif
-    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
-    int                     slot;
-
-    unsigned long           s;
-    unsigned                cmd_reg;
-    volatile unsigned      *cmd_lwa;
-    unsigned                cmd_lwd;
-
-    if (!ext_ates)
-	return 0;
-
-    /* Bridge Hardware Bug WAR #484930:
-     * Bridge can't handle updating External ATEs
-     * while DMA is occuring that uses External ATEs,
-     * even if the particular ATEs involved are disjoint.
-     */
-
-    /* need to prevent anyone else from
-     * unfreezing the grant while we
-     * are working; also need to prevent
-     * this thread from being interrupted
-     * to keep PCI grant freeze time
-     * at an absolute minimum.
-     */
-    s = pcibr_lock(pcibr_soft);
-
-#ifdef LATER
-    /* just in case pcibr_dmamap_done was not called */
-    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
-	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
-	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomic_dec(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
-	xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
-    }
-#endif	/* LATER */
-#if PCIBR_FREEZE_TIME
-    *freeze_time_ptr = get_timestamp();
-#endif
-
-    cmd_lwa = 0;
-    for (slot = 0; slot < 8; ++slot)
-	if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
-	    cmd_reg = pcibr_soft->
-		bs_slot[slot].
-		bss_cmd_shadow;
-	    if (cmd_reg & PCI_CMD_BUS_MASTER) {
-		cmd_lwa = pcibr_soft->
-		    bs_slot[slot].
-		    bss_cmd_pointer;
-		cmd_lwd = cmd_reg ^ PCI_CMD_BUS_MASTER;
-		cmd_lwa[0] = cmd_lwd;
-	    }
-	    cmd_regs[slot] = cmd_reg;
-	} else
-	    cmd_regs[slot] = 0;
-
-    if (cmd_lwa) {
-	    bridge_t	*bridge = pcibr_soft->bs_base;
-
-	    /* Read the last master bit that has been cleared. This PIO read
-	     * on the PCI bus is to ensure the completion of any DMAs that
-	     * are due to bus requests issued by PCI devices before the
-	     * clearing of master bits.
-	     */
-	    cmd_lwa[0];
-
-	    /* Flush all the write buffers in the bridge */
-	    for (slot = 0; slot < 8; ++slot)
-		    if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
-			    /* Flush the write buffer associated with this
-			     * PCI device which might be using dma map RAM.
-			     */
-			    bridge->b_wr_req_buf[slot].reg;
-		    }
-    }
-    return s;
-}
-
-#define	ATE_WRITE()    ate_write(ate_ptr, ate_count, ate)
-
-LOCAL void
-ate_write(bridge_ate_p ate_ptr,
-	  int ate_count,
-	  bridge_ate_t ate)
-{
-    while (ate_count-- > 0) {
-	*ate_ptr++ = ate;
-	ate += IOPGSIZE;
-    }
-}
-
-
-#if PCIBR_FREEZE_TIME
-#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s)
-#else
-#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s)
-#endif
-
-LOCAL void
-ate_thaw(pcibr_dmamap_t pcibr_dmamap,
-	 int ate_index,
-#if PCIBR_FREEZE_TIME
-	 bridge_ate_t ate,
-	 int ate_total,
-	 unsigned freeze_time_start,
-#endif
-	 unsigned *cmd_regs,
-	 unsigned s)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-    int                     dma_slot = pcibr_dmamap->bd_slot;
-    int                     slot;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
-
-    unsigned                cmd_reg;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-    static unsigned         max_freeze_time = 0;
-    static unsigned         max_ate_total;
-#endif
-
-    if (!ext_ates)
-	return;
-
-    /* restore cmd regs */
-    for (slot = 0; slot < 8; ++slot)
-	if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER)
-	    bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
-
-    pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
-    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
-
-#if PCIBR_FREEZE_TIME
-    freeze_time = get_timestamp() - freeze_time_start;
-
-    if ((max_freeze_time < freeze_time) ||
-	(max_ate_total < ate_total)) {
-	if (max_freeze_time < freeze_time)
-	    max_freeze_time = freeze_time;
-	if (max_ate_total < ate_total)
-	    max_ate_total = ate_total;
-	pcibr_unlock(pcibr_soft, s);
-	printk("%s: pci freeze time %d usec for %d ATEs\n"
-		"\tfirst ate: %R\n",
-		pcibr_soft->bs_name,
-		freeze_time * 1000 / 1250,
-		ate_total,
-		ate, ate_bits);
-    } else
-#endif
-	pcibr_unlock(pcibr_soft, s);
-}
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap,
-		  paddr_t paddr,
-		  size_t req_size)
-{
-    pcibr_soft_t            pcibr_soft;
-    iopaddr_t               xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    unsigned                flags;
-
-    ASSERT(pcibr_dmamap != NULL);
-    ASSERT(req_size > 0);
-    ASSERT(req_size <= pcibr_dmamap->bd_max_size);
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    flags = pcibr_dmamap->bd_flags;
-
-    xio_addr = xtalk_dmamap_addr(pcibr_dmamap->bd_xtalk, paddr, req_size);
-    if (XIO_PACKED(xio_addr)) {
-	xio_port = XIO_PORT(xio_addr);
-	xio_addr = XIO_ADDR(xio_addr);
-    } else
-	xio_port = pcibr_dmamap->bd_xio_port;
-
-    /* If this DMA is to an address that
-     * refers back to this Bridge chip,
-     * reduce it back to the correct
-     * PCI MEM address.
-     */
-    if (xio_port == pcibr_soft->bs_xid) {
-	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
-    } else if (flags & PCIIO_DMA_A64) {
-	/* A64 DMA:
-	 * always use 64-bit direct mapping,
-	 * which always works.
-	 * Device(x) was set up during
-	 * dmamap allocation.
-	 */
-
-	/* attributes are already bundled up into bd_pci_addr.
-	 */
-	pci_addr = pcibr_dmamap->bd_pci_addr
-	    | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT)
-	    | xio_addr;
-
-	/* Bridge Hardware WAR #482836:
-	 * If the transfer is not cache aligned
-	 * and the Bridge Rev is <= B, force
-	 * prefetch to be off.
-	 */
-	if (flags & PCIBR_NOPREFETCH)
-	    pci_addr &= ~PCI64_ATTR_PREF;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-	printk("pcibr_dmamap_addr (direct64):\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\tXIO port 0x%x offset 0x%x\n"
-		"\treturning PCI 0x%x\n",
-		paddr, paddr + req_size - 1,
-		xio_port, xio_addr, pci_addr);
-#endif
-    } else if (flags & PCIIO_FIXED) {
-	/* A32 direct DMA:
-	 * always use 32-bit direct mapping,
-	 * which may fail.
-	 * Device(x) was set up during
-	 * dmamap allocation.
-	 */
-
-	if (xio_port != pcibr_soft->bs_dir_xport)
-	    pci_addr = 0;		/* wrong DIDN */
-	else if (xio_addr < pcibr_dmamap->bd_xio_addr)
-	    pci_addr = 0;		/* out of range */
-	else if ((xio_addr + req_size) >
-		 (pcibr_dmamap->bd_xio_addr + BRIDGE_DMA_DIRECT_SIZE))
-	    pci_addr = 0;		/* out of range */
-	else
-	    pci_addr = pcibr_dmamap->bd_pci_addr +
-		xio_addr - pcibr_dmamap->bd_xio_addr;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-	printk("pcibr_dmamap_addr (direct32):\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\tXIO port 0x%x offset 0x%x\n"
-		"\treturning PCI 0x%x\n",
-		paddr, paddr + req_size - 1,
-		xio_port, xio_addr, pci_addr);
-#endif
-    } else {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-	iopaddr_t               offset = IOPGOFF(xio_addr);
-	bridge_ate_t            ate_proto = pcibr_dmamap->bd_ate_proto;
-	int                     ate_count = IOPG(offset + req_size - 1) + 1;
-
-	int                     ate_index = pcibr_dmamap->bd_ate_index;
-	unsigned                cmd_regs[8];
-	unsigned                s;
-
-#if PCIBR_FREEZE_TIME
-	int                     ate_total = ate_count;
-	unsigned                freeze_time;
-#endif
-
-#if PCIBR_ATE_DEBUG
-	bridge_ate_t            ate_cmp;
-	bridge_ate_p            ate_cptr;
-	unsigned                ate_lo, ate_hi;
-	int                     ate_bad = 0;
-	int                     ate_rbc = 0;
-#endif
-	bridge_ate_p            ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	bridge_ate_t            ate;
-
-	/* Bridge Hardware WAR #482836:
-	 * If the transfer is not cache aligned
-	 * and the Bridge Rev is <= B, force
-	 * prefetch to be off.
-	 */
-	if (flags & PCIBR_NOPREFETCH)
-	    ate_proto &= ~ATE_PREF;
-
-	ate = ate_proto
-	    | (xio_port << ATE_TIDSHIFT)
-	    | (xio_addr - offset);
-
-	pci_addr = pcibr_dmamap->bd_pci_addr + offset;
-
-	/* Fill in our mapping registers
-	 * with the appropriate xtalk data,
-	 * and hand back the PCI address.
-	 */
-
-	ASSERT(ate_count > 0);
-	if (ate_count <= pcibr_dmamap->bd_ate_count) {
-		ATE_FREEZE();
-		ATE_WRITE();
-		ATE_THAW();
-		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	} else {
-		/* The number of ATE's required is greater than the number
-		 * allocated for this map. One way this can happen is if
-		 * pcibr_dmamap_alloc() was called with the PCIBR_NO_ATE_ROUNDUP
-		 * flag, and then when that map is used (right now), the
-		 * target address tells us we really did need to roundup.
-		 * The other possibility is that the map is just plain too
-		 * small to handle the requested target area.
-		 */
-#if PCIBR_ATE_DEBUG
-		PRINT_WARNING( "pcibr_dmamap_addr :\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\tate_count 0x%x bd_ate_count 0x%x\n"
-			"\tATE's required > number allocated\n",
-			paddr, paddr + req_size - 1,
-			ate_count, pcibr_dmamap->bd_ate_count);
-#endif
-		pci_addr = 0;
-	}
-
-    }
-    return pci_addr;
-}
-
-/*ARGSUSED */
-alenlist_t
-pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
-		  alenlist_t palenlist,
-		  unsigned flags)
-{
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge=NULL;
-
-    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-    int                     inplace = flags & PCIIO_INPLACE;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist;
-    size_t                  length;
-    iopaddr_t               offset;
-    unsigned                direct64;
-    int                     ate_index = 0;
-    int                     ate_count = 0;
-    int                     ate_total = 0;
-    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
-    bridge_ate_t            ate_proto = (bridge_ate_t)0;
-    bridge_ate_t            ate_prev;
-    bridge_ate_t            ate;
-    alenaddr_t              xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    alenaddr_t              new_addr;
-
-    unsigned                cmd_regs[8];
-    unsigned                s = 0;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-#endif
-    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
-							 * with an ATE_FREEZE
-							 */
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
-				       flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist)
-	goto fail;
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist)
-	    goto fail;
-    }
-
-    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
-    if (!direct64) {
-	bridge = pcibr_soft->bs_base;
-	ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	ate_index = pcibr_dmamap->bd_ate_index;
-	ate_proto = pcibr_dmamap->bd_ate_proto;
-	ATE_FREEZE();
-	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
-    }
-    pci_addr = pcibr_dmamap->bd_pci_addr;
-
-    ate_prev = 0;			/* matches no valid ATEs */
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &length, al_flags)) {
-	if (XIO_PACKED(xio_addr)) {
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_dmamap->bd_xio_port;
-
-	if (xio_port == pcibr_soft->bs_xid) {
-	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
-	    if (new_addr == PCI_NOWHERE)
-		goto fail;
-	} else if (direct64) {
-	    new_addr = pci_addr | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Bridge Hardware WAR #482836:
-	     * If the transfer is not cache aligned
-	     * and the Bridge Rev is <= B, force
-	     * prefetch to be off.
-	     */
-	    if (flags & PCIBR_NOPREFETCH)
-		new_addr &= ~PCI64_ATTR_PREF;
-
-	} else {
-	    /* calculate the ate value for
-	     * the first address. If it
-	     * matches the previous
-	     * ATE written (ie. we had
-	     * multiple blocks in the
-	     * same IOPG), then back up
-	     * and reuse that ATE.
-	     *
-	     * We are NOT going to
-	     * aggressively try to
-	     * reuse any other ATEs.
-	     */
-	    offset = IOPGOFF(xio_addr);
-	    ate = ate_proto
-		| (xio_port << ATE_TIDSHIFT)
-		| (xio_addr - offset);
-	    if (ate == ate_prev) {
-#if PCIBR_ATE_DEBUG
-		printk("pcibr_dmamap_list: ATE share\n");
-#endif
-		ate_ptr--;
-		ate_index--;
-		pci_addr -= IOPGSIZE;
-	    }
-	    new_addr = pci_addr + offset;
-
-	    /* Fill in the hardware ATEs
-	     * that contain this block.
-	     */
-	    ate_count = IOPG(offset + length - 1) + 1;
-	    ate_total += ate_count;
-
-	    /* Ensure that this map contains enough ATE's */
-	    if (ate_total > pcibr_dmamap->bd_ate_count) {
-#if PCIBR_ATE_DEBUG
-		PRINT_WARNING( "pcibr_dmamap_list :\n"
-			"\twanted xio_addr [0x%x..0x%x]\n"
-			"\tate_total 0x%x bd_ate_count 0x%x\n"
-			"\tATE's required > number allocated\n",
-			xio_addr, xio_addr + length - 1,
-			ate_total, pcibr_dmamap->bd_ate_count);
-#endif
-		goto fail;
-	    }
-
-	    ATE_WRITE();
-
-	    ate_index += ate_count;
-	    ate_ptr += ate_count;
-
-	    ate_count <<= IOPFNSHIFT;
-	    ate += ate_count;
-	    pci_addr += ate_count;
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &new_addr, &length, al_flags))
-		goto fail;
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				new_addr, length, al_flags))
-		goto fail;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-
-    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
-     * changes that ATE_FREEZE has done to implement the external SSRAM
-     * bug workaround.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    return pciio_alenlist;
-
-  fail:
-    /* There are various points of failure after doing an ATE_FREEZE
-     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
-     * The decision to do an ATE_THAW needs to be based on whether a
-     * an ATE_FREEZE was done before.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	bridge->b_wid_tflush;
-    }
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
-{
-    /*
-     * We could go through and invalidate ATEs here;
-     * for performance reasons, we don't.
-     * We also don't enforce the strict alternation
-     * between _addr/_list and _done, but Hub does.
-     */
-
-    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
-	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
-
-	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomic_dec(&(pcibr_dmamap->bd_soft->bs_slot[pcibr_dmamap->bd_slot]. bss_ext_ates_active));
-    }
-
-    xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
-}
-
-
-/*
- * For each bridge, the DIR_OFF value in the Direct Mapping Register
- * determines the PCI to Crosstalk memory mapping to be used for all
- * 32-bit Direct Mapping memory accesses. This mapping can be to any
- * node in the system. This function will return that compact node id.
- */
-
-/*ARGSUSED */
-cnodeid_t
-pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
-{
-
-	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-	pcibr_soft_t	pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	return(NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase)));
-}
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    paddr_t paddr,
-		    size_t req_size,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-
-    xwidgetnum_t            xio_port;
-    iopaddr_t               xio_addr;
-    iopaddr_t               pci_addr;
-
-    int                     have_rrbs;
-    int                     min_rrbs;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    xio_addr = xtalk_dmatrans_addr(xconn_vhdl, 0, paddr, req_size,
-				   flags & DMAMAP_FLAGS);
-
-    if (!xio_addr) {
-#if PCIBR_DMA_DEBUG
-	printk("pcibr_dmatrans_addr:\n"
-		"\tpciio connection point %v\n"
-		"\txtalk connection point %v\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\txtalk_dmatrans_addr returned 0x%x\n",
-		pconn_vhdl, xconn_vhdl,
-		paddr, paddr + req_size - 1,
-		xio_addr);
-#endif
-	return 0;
-    }
-    /*
-     * find which XIO port this goes to.
-     */
-    if (XIO_PACKED(xio_addr)) {
-	if (xio_addr == XIO_NOWHERE) {
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	    return 0;
-	}
-	xio_port = XIO_PORT(xio_addr);
-	xio_addr = XIO_ADDR(xio_addr);
-
-    } else
-	xio_port = pcibr_soft->bs_mxid;
-
-    /*
-     * If this DMA comes back to us,
-     * return the PCI MEM address on
-     * which it would land, or NULL
-     * if the target is something
-     * on bridge other than PCI MEM.
-     */
-    if (xio_port == pcibr_soft->bs_xid) {
-	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
-	return pci_addr;
-    }
-    /* If the caller can use A64, try to
-     * satisfy the request with the 64-bit
-     * direct map. This can fail if the
-     * configuration bits in Device(x)
-     * conflict with our flags.
-     */
-
-    if (flags & PCIIO_DMA_A64) {
-	pci_addr = slotp->bss_d64_base;
-	if (!(flags & PCIBR_VCHAN1))
-	    flags |= PCIBR_VCHAN0;
-	if ((pci_addr != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-
-	    pci_addr |= xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-#if DEBUG && PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-	    if (xio_addr != 0x20000000)
-#endif
-		printk("pcibr_dmatrans_addr: [reuse]\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tdirect 64bit address is 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, pci_addr);
-#endif
-	    return (pci_addr);
-	}
-	if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS)) {
-	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_addr;
-	    pci_addr |= xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
-		if (flags & PCIBR_VCHAN1)
-		    pciio_slot += PCIBR_RRB_SLOT_VIRTUAL;
-		have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
-		if (have_rrbs < 2) {
-		    if (pci_addr & PCI64_ATTR_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
-		}
-	    }
-#if PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-	    if (xio_addr != 0x20000000)
-#endif
-		printk("pcibr_dmatrans_addr:\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tdirect 64bit address is 0x%x\n"
-			"\tnew flags: 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, pci_addr, (uint64_t) flags);
-#endif
-	    return (pci_addr);
-	}
-	/* our flags conflict with Device(x).
-	 */
-	flags = flags
-	    & ~PCIIO_DMA_A64
-	    & ~PCIBR_VCHAN0
-	    ;
-
-#if PCIBR_DMA_DEBUG
-	printk("pcibr_dmatrans_addr:\n"
-		"\tpciio connection point %v\n"
-		"\txtalk connection point %v\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\txtalk_dmatrans_addr returned 0x%x\n"
-		"\tUnable to set Device(x) bits for Direct-64\n",
-		pconn_vhdl, xconn_vhdl,
-		paddr, paddr + req_size - 1,
-		xio_addr);
-#endif
-    }
-    /* Try to satisfy the request with the 32-bit direct
-     * map. This can fail if the configuration bits in
-     * Device(x) conflict with our flags, or if the
-     * target address is outside where DIR_OFF points.
-     */
-    {
-	size_t                  map_size = 1ULL << 31;
-	iopaddr_t               xio_base = pcibr_soft->bs_dir_xbase;
-	iopaddr_t               offset = xio_addr - xio_base;
-	iopaddr_t               endoff = req_size + offset;
-
-	if ((req_size > map_size) ||
-	    (xio_addr < xio_base) ||
-	    (xio_port != pcibr_soft->bs_dir_xport) ||
-	    (endoff > map_size)) {
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n"
-		    "\txio region outside direct32 target\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	} else {
-	    pci_addr = slotp->bss_d32_base;
-	    if ((pci_addr != PCIBR_D32_BASE_UNSET) &&
-		(flags == slotp->bss_d32_flags)) {
-
-		pci_addr |= offset;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-		printk("pcibr_dmatrans_addr: [reuse]\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tmapped via direct32 offset 0x%x\n"
-			"\twill DMA via pci addr 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, offset, pci_addr);
-#endif
-		return (pci_addr);
-	    }
-	    if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS)) {
-
-		pci_addr = PCI32_DIRECT_BASE;
-		slotp->bss_d32_flags = flags;
-		slotp->bss_d32_base = pci_addr;
-		pci_addr |= offset;
-
-		/* Make sure we have an RRB (or two).
-		 */
-		if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
-		    have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
-		    if (have_rrbs < 2) {
-			if (slotp->bss_device & BRIDGE_DEV_PREF)
-			    min_rrbs = 2;
-			else
-			    min_rrbs = 1;
-			if (have_rrbs < min_rrbs)
-			    do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
-		    }
-		}
-#if PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-		if (xio_addr != 0x20000000)
-#endif
-		    printk("pcibr_dmatrans_addr:\n"
-			    "\tpciio connection point %v\n"
-			    "\txtalk connection point %v\n"
-			    "\twanted paddr [0x%x..0x%x]\n"
-			    "\txtalk_dmatrans_addr returned 0x%x\n"
-			    "\tmapped via direct32 offset 0x%x\n"
-			    "\twill DMA via pci addr 0x%x\n"
-			    "\tnew flags: 0x%x\n",
-			    pconn_vhdl, xconn_vhdl,
-			    paddr, paddr + req_size - 1,
-			    xio_addr, offset, pci_addr, (uint64_t) flags);
-#endif
-		return (pci_addr);
-	    }
-	    /* our flags conflict with Device(x).
-	     */
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n"
-		    "\tUnable to set Device(x) bits for Direct-32\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	}
-    }
-
-#if PCIBR_DMA_DEBUG
-    printk("pcibr_dmatrans_addr:\n"
-	    "\tpciio connection point %v\n"
-	    "\txtalk connection point %v\n"
-	    "\twanted paddr [0x%x..0x%x]\n"
-	    "\txtalk_dmatrans_addr returned 0x%x\n"
-	    "\tno acceptable PCI address found or constructable\n",
-	    pconn_vhdl, xconn_vhdl,
-	    paddr, paddr + req_size - 1,
-	    xio_addr);
-#endif
-
-    return 0;
-}
-
-/*ARGSUSED */
-alenlist_t
-pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    alenlist_t palenlist,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-    xwidgetnum_t            xio_port;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist = 0;
-
-    int                     inplace;
-    unsigned                direct64;
-    unsigned                al_flags;
-
-    iopaddr_t               xio_base;
-    alenaddr_t              xio_addr;
-    size_t                  xio_size;
-
-    size_t                  map_size;
-    iopaddr_t               pci_base;
-    alenaddr_t              pci_addr;
-
-    unsigned                relbits = 0;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    inplace = flags & PCIIO_INPLACE;
-    direct64 = flags & PCIIO_DMA_A64;
-    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-
-    if (direct64) {
-	map_size = 1ull << 48;
-	xio_base = 0;
-	pci_base = slotp->bss_d64_base;
-	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D64_BITS;
-	    pci_base =
-		pcibr_flags_to_d64(flags, pcibr_soft);
-	}
-    } else {
-	xio_base = pcibr_soft->bs_dir_xbase;
-	map_size = 1ull << 31;
-	pci_base = slotp->bss_d32_base;
-	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
-	    (flags == slotp->bss_d32_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D32_BITS;
-	    pci_base = PCI32_DIRECT_BASE;
-	}
-    }
-
-    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
-					 flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist)
-	goto fail;
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist)
-	    goto fail;
-    }
-
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &xio_size, al_flags)) {
-
-	/*
-	 * find which XIO port this goes to.
-	 */
-	if (XIO_PACKED(xio_addr)) {
-	    if (xio_addr == XIO_NOWHERE) {
-#if PCIBR_DMA_DEBUG
-		printk("pcibr_dmatrans_addr:\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr);
-#endif
-		return 0;
-	    }
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_soft->bs_mxid;
-
-	/*
-	 * If this DMA comes back to us,
-	 * return the PCI MEM address on
-	 * which it would land, or NULL
-	 * if the target is something
-	 * on bridge other than PCI MEM.
-	 */
-	if (xio_port == pcibr_soft->bs_xid) {
-	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
-	    if ( (pci_addr == (alenaddr_t)NULL) )
-		goto fail;
-	} else if (direct64) {
-	    ASSERT(xio_port != 0);
-	    pci_addr = pci_base | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-	} else {
-	    iopaddr_t               offset = xio_addr - xio_base;
-	    iopaddr_t               endoff = xio_size + offset;
-
-	    if ((xio_size > map_size) ||
-		(xio_addr < xio_base) ||
-		(xio_port != pcibr_soft->bs_dir_xport) ||
-		(endoff > map_size))
-		goto fail;
-
-	    pci_addr = pci_base + (xio_addr - xio_base);
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &pci_addr, &xio_size, al_flags))
-		goto fail;
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				pci_addr, xio_size, al_flags))
-		goto fail;
-	}
-    }
-
-    if (relbits) {
-	if (direct64) {
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_base;
-	} else {
-	    slotp->bss_d32_flags = flags;
-	    slotp->bss_d32_base = pci_base;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-    return pciio_alenlist;
-
-  fail:
-    if (relbits)
-	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-void
-pcibr_dmamap_drain(pcibr_dmamap_t map)
-{
-    xtalk_dmamap_drain(map->bd_xtalk);
-}
-
-void
-pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
-		    paddr_t paddr,
-		    size_t bytes)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
-}
-
-void
-pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
-		    alenlist_t list)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmalist_drain(xconn_vhdl, list);
-}
-
-/*
- * Get the starting PCIbus address out of the given DMA map.
- * This function is supposed to be used by a close friend of PCI bridge
- * since it relies on the fact that the starting address of the map is fixed at
- * the allocation time in the current implementation of PCI bridge.
- */
-iopaddr_t
-pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap)
-{
-    return (pcibr_dmamap->bd_pci_addr);
-}
-
-/* =====================================================================
- *    INTERRUPT MANAGEMENT
- */
-
-static unsigned
-pcibr_intr_bits(pciio_info_t info,
-		pciio_intr_line_t lines)
-{
-    pciio_slot_t            slot = pciio_info_slot_get(info);
-    unsigned		    bbits = 0;
-
-    /*
-     * Currently favored mapping from PCI
-     * slot number and INTA/B/C/D to Bridge
-     * PCI Interrupt Bit Number:
-     *
-     *     SLOT     A B C D
-     *      0       0 4 0 4
-     *      1       1 5 1 5
-     *      2       2 6 2 6
-     *      3       3 7 3 7
-     *      4       4 0 4 0
-     *      5       5 1 5 1
-     *      6       6 2 6 2
-     *      7       7 3 7 3
-     */
-
-    if (slot < 8) {
-	if (lines & (PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_C))
-	    bbits |= 1 << slot;
-	if (lines & (PCIIO_INTR_LINE_B| PCIIO_INTR_LINE_D))
-	    bbits |= 1 << (slot ^ 4);
-    }
-    return bbits;
-}
-
-
-/*
- *	Get the next wrapper pointer queued in the interrupt circular buffer.
- */
-#ifdef KERNEL_THREADS
-pcibr_intr_wrap_t
-pcibr_wrap_get(pcibr_intr_cbuf_t cbuf)
-{
-    pcibr_intr_wrap_t	wrap;
-
-	if (cbuf->ib_in == cbuf->ib_out)
-	    PRINT_PANIC("pcibr intr circular buffer empty, cbuf=0x%x, ib_in=ib_out=%d\n",
-		cbuf, cbuf->ib_out);
-
-	wrap = cbuf->ib_cbuf[cbuf->ib_out++];
-	cbuf->ib_out = cbuf->ib_out % IBUFSIZE;
-	return(wrap);
-}
-
-/* 
- *	Queue a wrapper pointer in the interrupt circular buffer.
- */
-void
-pcibr_wrap_put(pcibr_intr_wrap_t wrap, pcibr_intr_cbuf_t cbuf)
-{
-	int	in;
-	unsigned long	s;
-
-	/*
-	 * Multiple CPUs could be executing this code simultaneously
-	 * if a handler has registered multiple interrupt lines and
-	 * the interrupts are directed to different CPUs.
-	 */
-	s = mutex_spinlock(&cbuf->ib_lock);
-	in = (cbuf->ib_in + 1) % IBUFSIZE;
-	if (in == cbuf->ib_out) 
-	    PRINT_PANIC("pcibr intr circular buffer full, cbuf=0x%x, ib_in=%d\n",
-		cbuf, cbuf->ib_in);
-
-	cbuf->ib_cbuf[cbuf->ib_in] = wrap;
-	cbuf->ib_in = in;
-	mutex_spinunlock(&cbuf->ib_lock, s);
-	return;
-}
-#endif	/* KERNEL_THREADS */
-
-/*
- *	There are end cases where a deadlock can occur if interrupt 
- *	processing completes and the Bridge b_int_status bit is still set.
- *
- *	One scenerio is if a second PCI interrupt occurs within 60ns of
- *	the previous interrupt being cleared. In this case the Bridge
- *	does not detect the transition, the Bridge b_int_status bit
- *	remains set, and because no transition was detected no interrupt
- *	packet is sent to the Hub/Heart.
- *
- *	A second scenerio is possible when a b_int_status bit is being
- *	shared by multiple devices:
- *						Device #1 generates interrupt
- *						Bridge b_int_status bit set
- *						Device #2 generates interrupt
- *		interrupt processing begins
- *		  ISR for device #1 runs and
- *			clears interrupt
- *						Device #1 generates interrupt
- *		  ISR for device #2 runs and
- *			clears interrupt
- *						(b_int_status bit still set)
- *		interrupt processing completes
- *		  
- *	Interrupt processing is now complete, but an interrupt is still
- *	outstanding for Device #1. But because there was no transition of
- *	the b_int_status bit, no interrupt packet will be generated and
- *	a deadlock will occur.
- *
- *	To avoid these deadlock situations, this function is used
- *	to check if a specific Bridge b_int_status bit is set, and if so,
- *	cause the setting of the corresponding interrupt bit.
- *
- *	On a XBridge (IP35), we do this by writing the appropriate Bridge Force 
- *	Interrupt register.
- */
-void
-pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
-{
-	unsigned	bit;
-	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
-	bridge_t       *bridge = pcibr_soft->bs_base;
-	cpuid_t cpuvertex_to_cpuid(devfs_handle_t vhdl);
-
-	bit = wrap->iw_intr;
-
-	if (pcibr_soft->bs_xbridge) {
-	    bridge->b_force_pin[bit].intr = 1;
-	} else if ((1 << bit) & *wrap->iw_stat) {
-	    cpuid_t	    cpu;
-	    unsigned        intr_bit;
-	    xtalk_intr_t    xtalk_intr =
-				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
-
-	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
-	    cpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
-	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
-	}
-}
-
-/* Wrapper for pcibr interrupt threads. */
-#ifdef KERNEL_THREADS
-static void
-pcibr_intrd(pcibr_intr_t intr)
-{
-    pcibr_intr_wrap_t	wrap;
-
-	/* Called on each restart */
-	ASSERT(cpuid() == intr->bi_mustruncpu);
-
-#ifdef ITHREAD_LATENCY
-	xthread_update_latstats(intr->bi_tinfo.thd_latstats);
-#endif /* ITHREAD_LATENCY */
-
-	ASSERT(intr->bi_func != NULL);
-	intr->bi_func(intr->bi_arg);		/* Invoke the interrupt handler */
-
-	/*
-	 * The pcibr_intrd thread needs access to the wrapper struct
-	 * specific to the current interrupt it is processing. Because
-	 * multiple calls/wakeups to the thread could be queued, each
-	 * potentially from a different interrupt line (PCIIO_INTR_LINE_A,
-	 * etc), multiple wrapper struct pointers need to be queued. This 
-	 * is done via a circular buffer of wrapper struct pointers. 
-	 */
-	wrap = pcibr_wrap_get(&intr->bi_ibuf);
-
-	/* 
-	 * The interrupt handler has completed. Now decrement the running
-	 * count tracking the number of handlers still running for this line.
-	 * If this was the last handler to complete (i.e., iw_hdlrcnt == 0),
-	 * avoid a potential deadlock condition and ensure that another
-	 * interrupt will occur if the Bridge b_int_status bit is still
-	 * set. 
-	 */
-	atomicAddInt(&(wrap->iw_hdlrcnt), -1);
-	if (wrap->iw_hdlrcnt == 0)
-		pcibr_force_interrupt(wrap);
-
-	ipsema(&intr->bi_tinfo.thd_isync);	/* Sleep 'till next interrupt */
-	/* NOTREACHED */
-}
-
-static void
-pcibr_intrd_start(pcibr_intr_t intr)
-{
-	ASSERT(intr->bi_mustruncpu >= 0);
-	setmustrun(intr->bi_mustruncpu);
-
-	xthread_set_func(KT_TO_XT(curthreadp), (xt_func_t *)pcibr_intrd, (void *)intr);
-	atomicSetInt(&intr->bi_tinfo.thd_flags, THD_INIT);
-	ipsema(&intr->bi_tinfo.thd_isync);  /* Comes out in pcibr_intrd */
-	/* NOTREACHED */
-}
-
-
-static void
-pcibr_thread_setup(pcibr_intr_t intr, int bridge_levels, ilvl_t intr_swlevel)
-{
-	char thread_name[32];
-
-	sprintf(thread_name, "pcibr_intrd[0x%x]", bridge_levels);
-	thread_name[IT_NAMELEN-1] = '\0';
-
-	/* XXX need to adjust priority whenever an interrupt is connected */
-	intr->bi_tinfo.thd_pri = intr_swlevel;
-	atomicSetInt(&intr->bi_tinfo.thd_flags, THD_ISTHREAD | THD_REG);
-	xthread_setup(thread_name, intr_swlevel, &intr->bi_tinfo,
-			(xt_func_t *)pcibr_intrd_start,
-			(void *)intr);
-}
-#endif	/* KERNEL_THREADS */
-
-
-
-/*ARGSUSED */
-pcibr_intr_t
-pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
-		 device_desc_t dev_desc,
-		 pciio_intr_line_t lines,
-		 devfs_handle_t owner_dev)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pcibr_info->f_slot;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     is_threaded = 0;
-#ifdef KERNEL_THREADS
-    cpuid_t		    mustruncpu = CPU_NONE;
-    cpuid_t		    old_intrcpu = CPU_NONE;
-#endif
-    int                     thread_swlevel;
-
-    xtalk_intr_t           *xtalk_intr_p;
-    pcibr_intr_t           *pcibr_intr_p;
-    pcibr_intr_list_t      *intr_list_p;
-
-    unsigned                pcibr_int_bits;
-    unsigned                pcibr_int_bit;
-    xtalk_intr_t            xtalk_intr = (xtalk_intr_t)0;
-    hub_intr_t		    hub_intr;
-    pcibr_intr_t            pcibr_intr;
-    pcibr_intr_list_t       intr_entry;
-    pcibr_intr_list_t       intr_list;
-    bridgereg_t             int_dev;
-
-#if DEBUG && INTR_DEBUG
-    printk("%v: pcibr_intr_alloc\n"
-	    "%v:%s%s%s%s%s\n",
-	    owner_dev, pconn_vhdl,
-	    !(lines & 15) ? " No INTs?" : "",
-	    lines & 1 ? " INTA" : "",
-	    lines & 2 ? " INTB" : "",
-	    lines & 4 ? " INTC" : "",
-	    lines & 8 ? " INTD" : "");
-#endif
-
-    NEW(pcibr_intr);
-    if (!pcibr_intr)
-	return NULL;
-
-    if (dev_desc) {
-	cpuid_t intr_target_from_desc(device_desc_t, int);
-
-#ifdef KERNEL_THREADS
-	is_threaded = !(device_desc_flags_get(dev_desc) & D_INTR_NOTHREAD);
-	if (is_threaded) {
-	    /*
-	     * If the device descriptor contains interrupt target info,
-	     * save the CPU requested. This is the CPU the pcibr_intrd
-	     * thread will be set to run on. 
-	     *
-	     * We need to get the interrupt target info at this time, because
-	     * the original intr_target value can be overwritten, as part of
-	     * the xtalk_intr_alloc_nothd() call, with the actual interrupt CPU.
-	     * This can be different than the requested CPU if the lower layers
-	     * could not direct the hardware interrupt to the requested CPU. 
-	     * Regardless of which CPU processes the hardware interrupt, the 
-	     * ISR thread will still be setup to run on the CPU originally 
-	     * requested.
-	     */
-		mustruncpu = intr_target_from_desc(dev_desc, SUBNODE_ANY);
-		thread_swlevel = device_desc_intr_swlevel_get(dev_desc);
-	}
-#endif	/* KERNEL_THREADS */
-    } else {
-	extern int default_intr_pri;
-
-	is_threaded = 1; /* PCI interrupts are threaded, by default */
-	thread_swlevel = default_intr_pri;
-    }
-
-    pcibr_intr->bi_dev = pconn_vhdl;
-    pcibr_intr->bi_lines = lines;
-    pcibr_intr->bi_soft = pcibr_soft;
-    pcibr_intr->bi_ibits = 0;		/* bits will be added below */
-    pcibr_intr->bi_func = 0;		/* unset until connect */
-    pcibr_intr->bi_arg = 0;		/* unset until connect */
-    pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD;
-    pcibr_intr->bi_mustruncpu = CPU_NONE;
-#ifdef KERNEL_THREADS
-    pcibr_intr->bi_ibuf.ib_in = 0;
-    pcibr_intr->bi_ibuf.ib_out = 0;
-#endif
-    mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock);
-
-    pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines);
-
-
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and make sure there are xtalk resources
-     * allocated for it.
-     */
-#if DEBUG && INTR_DEBUG
-    printk("pcibr_int_bits: 0x%X\n", pcibr_int_bits);
-#endif 
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit ++) {
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    xtalk_intr_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    xtalk_intr = *xtalk_intr_p;
-
-	    if (xtalk_intr == NULL) {
-		/*
-		 * This xtalk_intr_alloc is constrained for two reasons:
-		 * 1) Normal interrupts and error interrupts need to be delivered
-		 *    through a single xtalk target widget so that there aren't any
-		 *    ordering problems with DMA, completion interrupts, and error
-		 *    interrupts. (Use of xconn_vhdl forces this.)
-		 *
-		 * 2) On IP35, addressing constraints on IP35 and Bridge force
-		 *    us to use a single PI number for all interrupts from a
-		 *    single Bridge. (IP35-specific code forces this, and we
-		 *    verify in pcibr_setwidint.)
-		 */
-
-		/*
-		 * All code dealing with threaded PCI interrupt handlers
-		 * is located at the pcibr level. Because of this,
-		 * we always want the lower layers (hub/heart_intr_alloc, 
-		 * intr_level_connect) to treat us as non-threaded so we
-		 * don't set up a duplicate threaded environment. We make
-		 * this happen by calling a special xtalk interface.
-		 */
-		xtalk_intr = xtalk_intr_alloc_nothd(xconn_vhdl, dev_desc, 
-			owner_dev);
-#if DEBUG && INTR_DEBUG
-		printk("%v: xtalk_intr=0x%X\n", xconn_vhdl, xtalk_intr);
-#endif
-
-		/* both an assert and a runtime check on this:
-		 * we need to check in non-DEBUG kernels, and
-		 * the ASSERT gets us more information when
-		 * we use DEBUG kernels.
-		 */
-		ASSERT(xtalk_intr != NULL);
-		if (xtalk_intr == NULL) {
-		    /* it is quite possible that our
-		     * xtalk_intr_alloc failed because
-		     * someone else got there first,
-		     * and we can find their results
-		     * in xtalk_intr_p.
-		     */
-		    if (!*xtalk_intr_p) {
-#ifdef SUPPORT_PRINTING_V_FORMAT
-			PRINT_ALERT(
-				"pcibr_intr_alloc %v: unable to get xtalk interrupt resources",
-				xconn_vhdl);
-#endif
-			/* yes, we leak resources here. */
-			return 0;
-		    }
-		} else if (compare_and_swap_ptr((void **) xtalk_intr_p, NULL, xtalk_intr)) {
-		    /*
-		     * now tell the bridge which slot is
-		     * using this interrupt line.
-		     */
-		    int_dev = bridge->b_int_device;
-		    int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
-		    int_dev |= pciio_slot << BRIDGE_INT_DEV_SHFT(pcibr_int_bit);
-		    bridge->b_int_device = int_dev;	/* XXXMP */
-
-#if DEBUG && INTR_DEBUG
-		    printk("%v: bridge intr bit %d clears my wrb\n",
-			    pconn_vhdl, pcibr_int_bit);
-#endif
-		} else {
-		    /* someone else got one allocated first;
-		     * free the one we just created, and
-		     * retrieve the one they allocated.
-		     */
-		    xtalk_intr_free(xtalk_intr);
-		    xtalk_intr = *xtalk_intr_p;
-#if PARANOID
-		    /* once xtalk_intr is set, we never clear it,
-		     * so if the CAS fails above, this condition
-		     * can "never happen" ...
-		     */
-		    if (!xtalk_intr) {
-			PRINT_ALERT(
-				"pcibr_intr_alloc %v: unable to set xtalk interrupt resources",
-				xconn_vhdl);
-			/* yes, we leak resources here. */
-			return 0;
-		    }
-#endif
-		}
-	    }
-
-#ifdef KERNEL_THREADS
-	    if (is_threaded) {
-		cpuid_t intrcpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
-
-		/*
-		 * It is possible that 2 (or more) interrupts originating on a
-		 * single Bridge and used by a single device were assigned to
-		 * different CPUs. If this occurs issue a warning message for
-		 * this sub-optimal configuration. There are two ways this 
-		 * could happen:
-		 *
-		 *  - There were insufficient xtalk interrupt resources to
-		 *    allow all interrupts to be assigned to the same CPU.
-		 *    This is an unlikely case, but could happen if someone
-		 *    tries to target a lot of interrupts to a single CPU.
-		 *
-		 * - If there is no device descriptor associated with this
-		 *   device, the xtalk/hub/heart layers will not know to
-		 *   assign the same CPU to any additional interrupts this
-		 *   driver has specified, and will perform the normal load
-		 *   leveling of interrupts across CPUs.
-		 *   (The lower layers store the CPU assigned to the first
-		 *   interrupt in the device desc, if present, and then when
-		 *   called again for additional interrupts for the same device,
-		 *   use this information to assign the same CPU to these
-		 *   interrupts.)
-		 */
-		if ((old_intrcpu != CPU_NONE) && (old_intrcpu != intrcpu)) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			PRINT_WARNING("Conflict on where to schedule interrupts for %v\n", pconn_vhdl);
-#else
-			PRINT_WARNING("Conflict on where to schedule interrupts for 0x%x\n", pconn_vhdl);
-#endif
-			PRINT_WARNING("(on cpu %d or on cpu %d), cpu %d used\n", old_intrcpu, intrcpu, intrcpu);
-		}
-		if (old_intrcpu == CPU_NONE)
-			old_intrcpu = intrcpu;
-	    /*
-	     * For threaded drivers, set the interrupt thread to run wherever
-	     * the interrupt is targeted, or where requested in the dev_desc.
-	     */
-		if (mustruncpu != CPU_NONE) {
-			pcibr_intr->bi_mustruncpu = mustruncpu;
-			if (mustruncpu != intrcpu) {
-				PRINT_WARNING("Request to target PCI interrupts to CPU %d could not\n"
-                		"      be satisfied, CPU %d used. However, interrupt thread\n"
-                		"      pcibr_intrd will run on CPU %d as requested.\n"
-                		"      %v (0x%x)\n",
-                		mustruncpu, intrcpu, mustruncpu, owner_dev,
-				owner_dev);
-			}
-		} else {
-			pcibr_intr->bi_mustruncpu = intrcpu;
-		}
-		ASSERT(pcibr_intr->bi_mustruncpu >= 0);
-
-	    }
-#endif	/* KERNEL_THREADS */
-
-	    pcibr_intr->bi_ibits |= 1 << pcibr_int_bit;
-
-	    NEW(intr_entry);
-	    intr_entry->il_next = NULL;
-	    intr_entry->il_intr = pcibr_intr;
-	    intr_entry->il_wrbf = &(bridge->b_wr_req_buf[pciio_slot].reg);
-	    intr_list_p = 
-		&pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
-#if DEBUG && INTR_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	    printk("0x%x: Bridge bit %d wrap=0x%x\n",
-		pconn_vhdl, pcibr_int_bit,
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
-#else
-	    printk("%v: Bridge bit %d wrap=0x%x\n",
-		pconn_vhdl, pcibr_int_bit,
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
-#endif
-#endif
-
-	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		/* we are the first interrupt on this bridge bit.
-		 */
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) allocated [FIRST]\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    intr_list = *intr_list_p;
-	    pcibr_intr_p = &intr_list->il_intr;
-	    if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
-		/* first entry on list was erased,
-		 * and we replaced it, so we
-		 * don't need our intr_entry.
-		 */
-		DEL(intr_entry);
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) replaces erased first\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    intr_list_p = &intr_list->il_next;
-	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		/* we are the new second interrupt on this bit.
-		 */
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared = 1;
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) is new SECOND\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    while (1) {
-		pcibr_intr_p = &intr_list->il_intr;
-		if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
-		    /* an entry on list was erased,
-		     * and we replaced it, so we
-		     * don't need our intr_entry.
-		     */
-		    DEL(intr_entry);
-#if DEBUG && INTR_DEBUG
-		    printk("%v INT 0x%x (bridge bit %d) replaces erased Nth\n",
-			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		    break;
-		}
-		intr_list_p = &intr_list->il_next;
-		if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		    /* entry appended to share list
-		     */
-#if DEBUG && INTR_DEBUG
-		    printk("%v INT 0x%x (bridge bit %d) is new Nth\n",
-			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		    break;
-		}
-		/* step to next record in chain
-		 */
-		intr_list = *intr_list_p;
-	    }
-	}
-    }
-
-#ifdef KERNEL_THREADS
-    if (is_threaded) {
-	/* Set pcibr_intr->bi_tinfo */
-	pcibr_thread_setup(pcibr_intr, pcibr_int_bits, thread_swlevel);
-	ASSERT(!(pcibr_intr->bi_flags & PCIIO_INTR_CONNECTED));
-    }
-#endif	/* KERNEL_THREADS */
-
-#if DEBUG && INTR_DEBUG
-    printk("%v pcibr_intr_alloc complete\n", pconn_vhdl);
-#endif
-    hub_intr = (hub_intr_t)xtalk_intr;
-    pcibr_intr->bi_irq = hub_intr->i_bit;
-    pcibr_intr->bi_cpu = hub_intr->i_cpuid;
-    return pcibr_intr;
-}
-
-/*ARGSUSED */
-void
-pcibr_intr_free(pcibr_intr_t pcibr_intr)
-{
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    unsigned                pcibr_int_bit;
-    pcibr_intr_list_t       intr_list;
-    int			    intr_shared;
-    xtalk_intr_t	    *xtalk_intrp;
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) {
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    for (intr_list = 
-		     pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
-		 intr_list != NULL;
-		 intr_list = intr_list->il_next)
-		if (compare_and_swap_ptr((void **) &intr_list->il_intr, 
-					 pcibr_intr, 
-					 NULL)) {
-#if DEBUG && INTR_DEBUG
-		    printk("%s: cleared a handler from bit %d\n",
-			    pcibr_soft->bs_name, pcibr_int_bit);
-#endif
-		}
-	    /* If this interrupt line is not being shared between multiple
-	     * devices release the xtalk interrupt resources.
-	     */
-	    intr_shared = 
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared;
-	    xtalk_intrp = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    if ((!intr_shared) && (*xtalk_intrp)) {
-
-		bridge_t 	*bridge = pcibr_soft->bs_base;
-		bridgereg_t	int_dev;
-
-		xtalk_intr_free(*xtalk_intrp);
-		*xtalk_intrp = 0;
-
-		/* Clear the PCI device interrupt to bridge interrupt pin
-		 * mapping.
-		 */
-		int_dev = bridge->b_int_device;
-		int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
-		bridge->b_int_device = int_dev;
-
-	    }
-	}
-    }
-    DEL(pcibr_intr);
-}
-
-LOCAL void
-pcibr_setpciint(xtalk_intr_t xtalk_intr)
-{
-    iopaddr_t               addr = xtalk_intr_addr_get(xtalk_intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(xtalk_intr);
-    bridgereg_t            *int_addr = (bridgereg_t *)
-    xtalk_intr_sfarg_get(xtalk_intr);
-
-    *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-		 (BRIDGE_INT_ADDR_FLD & vect));
-}
-
-/*ARGSUSED */
-int
-pcibr_intr_connect(pcibr_intr_t pcibr_intr,
-		   intr_func_t intr_func,
-		   intr_arg_t intr_arg,
-		   void *thread)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-    bridgereg_t             b_int_enable;
-    unsigned long           s;
-
-    if (pcibr_intr == NULL)
-	return -1;
-
-#if DEBUG && INTR_DEBUG
-    printk("%v: pcibr_intr_connect 0x%X(0x%X)\n",
-	    pcibr_intr->bi_dev, intr_func, intr_arg);
-#endif
-
-    pcibr_intr->bi_func = intr_func;
-    pcibr_intr->bi_arg = intr_arg;
-    *((volatile unsigned *)&pcibr_intr->bi_flags) |= PCIIO_INTR_CONNECTED;
-
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and make sure there are xtalk resources
-     * allocated for it.
-     */
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    pcibr_intr_wrap_t       intr_wrap;
-	    xtalk_intr_t            xtalk_intr;
-
-	    xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    intr_wrap = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap;
-	    /*
-	     * If this interrupt line is being shared and the connect has
-	     * already been done, no need to do it again.
-	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected)
-		continue;
-
-
-	    /*
-	     * Use the pcibr wrapper function to handle all Bridge interrupts
-	     * regardless of whether the interrupt line is shared or not.
-	     */
-	    xtalk_intr_connect(xtalk_intr,
-				pcibr_intr_func,
-			       (intr_arg_t) intr_wrap,
-			       (xtalk_intr_setfunc_t) pcibr_setpciint,
-			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr),
-			       0);
-	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 1;
-
-#if DEBUG && INTR_DEBUG
-	    printk("%v bridge bit %d wrapper connected\n",
-		    pcibr_intr->bi_dev, pcibr_int_bit);
-#endif
-	}
-    s = pcibr_lock(pcibr_soft);
-    b_int_enable = bridge->b_int_enable;
-    b_int_enable |= pcibr_int_bits;
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_intr_disconnect(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-    pcibr_intr_wrap_t	    intr_wrap;
-    bridgereg_t             b_int_enable;
-    unsigned long           s;
-
-    /* Stop calling the function. Now.
-     */
-    *((volatile unsigned *)&pcibr_intr->bi_flags) &= ~PCIIO_INTR_CONNECTED;
-    pcibr_intr->bi_func = 0;
-    pcibr_intr->bi_arg = 0;
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and disconnect the interrupt.
-     */
-
-    /* don't disable interrupts for lines that
-     * are shared between devices.
-     */
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if ((pcibr_int_bits & (1 << pcibr_int_bit)) &&
-	    (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared))
-	    pcibr_int_bits &= ~(1 << pcibr_int_bit);
-    if (!pcibr_int_bits)
-	return;
-
-    s = pcibr_lock(pcibr_soft);
-    b_int_enable = bridge->b_int_enable;
-    b_int_enable &= ~pcibr_int_bits;
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    /* if the interrupt line is now shared,
-	     * do not disconnect it.
-	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
-		continue;
-
-	    xtalk_intr_disconnect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
-	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 0;
-
-#if DEBUG && INTR_DEBUG
-	    printk("%s: xtalk disconnect done for Bridge bit %d\n",
-		pcibr_soft->bs_name, pcibr_int_bit);
-#endif
-
-	    /* if we are sharing the interrupt line,
-	     * connect us up; this closes the hole
-	     * where the another pcibr_intr_alloc()
-	     * was in progress as we disconnected.
-	     */
-	    intr_wrap = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap;
-	    if (!pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
-		continue;
-
-
-	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
-			       pcibr_intr_func,
-			       (intr_arg_t) intr_wrap,
-			       (xtalk_intr_setfunc_t) pcibr_setpciint,
-			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr),
-			       0);
-	}
-}
-
-/*ARGSUSED */
-devfs_handle_t
-pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit))
-	    return xtalk_intr_cpu_get(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
-    return 0;
-}
-
-/* =====================================================================
- *    INTERRUPT HANDLING
- */
-LOCAL void
-pcibr_clearwidint(bridge_t *bridge)
-{
-    bridge->b_wid_int_upper = 0;
-    bridge->b_wid_int_lower = 0;
-}
-
-
-LOCAL void
-pcibr_setwidint(xtalk_intr_t intr)
-{
-    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
-    iopaddr_t               addr = xtalk_intr_addr_get(intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
-    widgetreg_t		    NEW_b_wid_int_upper, NEW_b_wid_int_lower;
-    widgetreg_t		    OLD_b_wid_int_upper, OLD_b_wid_int_lower;
-
-    bridge_t               *bridge = (bridge_t *)xtalk_intr_sfarg_get(intr);
-
-    NEW_b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
-			       XTALK_ADDR_TO_UPPER(addr));
-    NEW_b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-
-    OLD_b_wid_int_upper = bridge->b_wid_int_upper;
-    OLD_b_wid_int_lower = bridge->b_wid_int_lower;
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-    /* Verify that all interrupts from this Bridge are using a single PI */
-    if ((OLD_b_wid_int_upper != 0) && (OLD_b_wid_int_lower != 0)) {
-	/*
-	 * Once set, these registers shouldn't change; they should
-	 * be set multiple times with the same values.
-	 *
-	 * If we're attempting to change these registers, it means
-	 * that our heuristics for allocating interrupts in a way
-	 * appropriate for IP35 have failed, and the admin needs to
-	 * explicitly direct some interrupts (or we need to make the
-	 * heuristics more clever).
-	 *
-	 * In practice, we hope this doesn't happen very often, if
-	 * at all.
-	 */
-	if ((OLD_b_wid_int_upper != NEW_b_wid_int_upper) ||
-	    (OLD_b_wid_int_lower != NEW_b_wid_int_lower)) {
-		PRINT_WARNING("Interrupt allocation is too complex.\n");
-		PRINT_WARNING("Use explicit administrative interrupt targetting.\n");
-		PRINT_WARNING("bridge=0x%lx targ=0x%x\n", (unsigned long)bridge, targ);
-		PRINT_WARNING("NEW=0x%x/0x%x  OLD=0x%x/0x%x\n",
-			NEW_b_wid_int_upper, NEW_b_wid_int_lower,
-			OLD_b_wid_int_upper, OLD_b_wid_int_lower);
-		PRINT_PANIC("PCI Bridge interrupt targetting error\n");
-	}
-    }
-#endif /* CONFIG_SGI_IP35 */
-
-    bridge->b_wid_int_upper = NEW_b_wid_int_upper;
-    bridge->b_wid_int_lower = NEW_b_wid_int_lower;
-    bridge->b_int_host_err = vect;
-}
-
-/*
- * pcibr_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * one of the Bridge's xtalk interrupts before the
- * xtalk infrastructure is available.
- */
-void
-pcibr_xintr_preset(void *which_widget,
-		   int which_widget_intr,
-		   xwidgetnum_t targ,
-		   iopaddr_t addr,
-		   xtalk_intr_vector_t vect)
-{
-    bridge_t               *bridge = (bridge_t *) which_widget;
-
-    if (which_widget_intr == -1) {
-	/* bridge widget error interrupt */
-	bridge->b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
-				   XTALK_ADDR_TO_UPPER(addr));
-	bridge->b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-	bridge->b_int_host_err = vect;
-
-	/* turn on all interrupts except
-	 * the PCI interrupt requests,
-	 * at least at heart.
-	 */
-	bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK;
-
-    } else {
-	/* routing a PCI device interrupt.
-	 * targ and low 38 bits of addr must
-	 * be the same as the already set
-	 * value for the widget error interrupt.
-	 */
-	bridge->b_int_addr[which_widget_intr].addr =
-	    ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-	     (BRIDGE_INT_ADDR_FLD & vect));
-	/*
-	 * now bridge can let it through;
-	 * NB: still should be blocked at
-	 * xtalk provider end, until the service
-	 * function is set.
-	 */
-	bridge->b_int_enable |= 1 << vect;
-    }
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-}
-
-
-/*
- * pcibr_intr_func()
- *
- * This is the pcibr interrupt "wrapper" function that is called,
- * in interrupt context, to initiate the interrupt handler(s) registered
- * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
- * handlers will be called directly, and threaded handlers will have their 
- * thread woken up.
- */
-void
-pcibr_intr_func(intr_arg_t arg)
-{
-    pcibr_intr_wrap_t       wrap = (pcibr_intr_wrap_t) arg;
-    reg_p                   wrbf;
-    intr_func_t             func;
-    pcibr_intr_t            intr;
-    pcibr_intr_list_t       list;
-    int                     clearit;
-#ifdef KERNEL_THREADS
-    int			    do_nonthreaded = 0;
-    int			    do_threaded = 1;
-    int			    is_threaded = 0;
-#else
-    int			    do_nonthreaded = 1;
-    int			    do_threaded = 0;
-    int			    is_threaded = 0;
-#endif
-    int			    nonthreaded_count = 0;
-    int			    x = 0;
-
-	/*
-	 * If any handler is still running from a previous interrupt
-	 * just return. If there's a need to call the handler(s) again,
-	 * another interrupt will be generated either by the device or by
-	 * pcibr_force_interrupt().
-	 */
-
-	if (wrap->iw_hdlrcnt) {
-		return;
-	}
-
-    /*
-     * Call all interrupt handlers registered.
-     * First, the pcibr_intrd threads for any threaded handlers will be
-     * awoken, then any non-threaded handlers will be called sequentially.
-     */
-	
-	clearit = 1;
-	while (do_threaded || do_nonthreaded) {
-	    for (list = wrap->iw_list; list != NULL; list = list->il_next) {
-		if ((intr = list->il_intr) &&
-		    (intr->bi_flags & PCIIO_INTR_CONNECTED)) {
-
-		    ASSERT(intr->bi_func);
-
-		/*
-		 * This device may have initiated write
-		 * requests since the bridge last saw
-		 * an edge on this interrupt input; flushing
-		 * the buffer prior to invoking the handler
-		 * should help but may not be sufficient if we 
-		 * get more requests after the flush, followed
-		 * by the card deciding it wants service, before
-		 * the interrupt handler checks to see if things need
-		 * to be done.
-		 *
-		 * There is a similar race condition if
-		 * an interrupt handler loops around and
-		 * notices further service is requred.
-		 * Perhaps we need to have an explicit
-		 * call that interrupt handlers need to
-		 * do between noticing that DMA to memory
-		 * has completed, but before observing the
-		 * contents of memory?
-		 */
-
-#ifdef KERNEL_THREADS
-		    is_threaded = !(intr->bi_flags & PCIIO_INTR_NOTHREAD);
-		    if (!is_threaded) {
-			nonthreaded_count++;
-		    }
-
-		    if ((do_threaded) && (is_threaded)) {
-			/* Only need to flush write buffers if sharing */
-
-			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
-			    if (x = *wrbf)	/* write request buffer flush */
-#ifdef SUPPORT_PRINTING_V_FORMAT
-				PRINT_ALERT("pcibr_intr_func %v: \n"
-				    "write buffer flush failed, wrbf=0x%x\n", 
-				    list->il_intr->bi_dev, wrbf);
-#else
-				PRINT_ALERT("pcibr_intr_func 0x%x: \n"
-				    "write buffer flush failed, wrbf=0x%x\n", 
-				    list->il_intr->bi_dev, wrbf);
-#endif
-			}
-
-			/*
-			 * Keep a running count of the number of interrupt
-			 * handlers that have yet to complete. 
-			 */
-			atomicAddInt(&(wrap->iw_hdlrcnt), 1);
-
-			/* 
-			 * Prior to waking up pcibr_intrd, a pointer to the 
-			 * wrapper struct corresponding to the interrupt taken
-			 * needs to be queued in the interrupt circular buffer.
-			 * The pcibr_intrd thread needs the wrapper pointer in
-			 * order to decrement the handler count (iw_hdlrcnt).
-			 */
-			pcibr_wrap_put(wrap, &intr->bi_ibuf);
-#ifdef ITHREAD_LATENCY
-			xthread_set_istamp(intr->bi_tinfo.thd_latstats);
-#endif /* ITHREAD_LATENCY */
-		     	up(&intr->bi_tinfo.thd_isync); 
-		    } else
-#endif	/* KERNEL_THREADS */
-			if ((do_nonthreaded) && (!is_threaded)) {
-			/* Non-threaded. 
-			 * Call the interrupt handler at interrupt level
-			 */
-
-			/* Only need to flush write buffers if sharing */
-
-			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
-			    if ((x = *wrbf))	/* write request buffer flush */
-#ifdef SUPPORT_PRINTING_V_FORMAT
-				PRINT_ALERT("pcibr_intr_func %v: \n"
-				    "write buffer flush failed, wrbf=0x%x\n", 
-				    list->il_intr->bi_dev, wrbf);
-#else
-				PRINT_ALERT("pcibr_intr_func %p: \n"
-				    "write buffer flush failed, wrbf=0x%x\n", 
-				    list->il_intr->bi_dev, wrbf);
-#endif
-			}
-
-			func = intr->bi_func;
-			func(intr->bi_arg);
-		    }
-
-		    clearit = 0;
-		}
-	    }
-
-	    if (do_threaded) {
-		/* 
-		 * All threaded handlers have been called;
-		 * next do non-threaded, if any.
-		 */
-		do_threaded = 0;
-
-		if (nonthreaded_count)
-			do_nonthreaded = 1;
-	    } else {
-		do_nonthreaded = 0;
-		/*
-		 * If the non-threaded handler was the last to complete,
-		 * (i.e., no threaded handlers still running) force an
-		 * interrupt to avoid a potential deadlock situation.
-		 */
-		if (wrap->iw_hdlrcnt == 0) {
-			pcibr_force_interrupt(wrap);
-		}
-	    }
-	}
-
-	/* If there were no handlers,
-	 * disable the interrupt and return.
-	 * It will get enabled again after
-	 * a handler is connected.
-	 * If we don't do this, we would
-	 * sit here and spin through the
-	 * list forever.
-	 */
-	if (clearit) {
-	    pcibr_soft_t            pcibr_soft = wrap->iw_soft;
-	    bridge_t               *bridge = pcibr_soft->bs_base;
-	    bridgereg_t             b_int_enable;
-	    bridgereg_t		    mask = 1 << wrap->iw_intr;
-	    unsigned long           s;
-
-	    s = pcibr_lock(pcibr_soft);
-	    b_int_enable = bridge->b_int_enable;
-	    b_int_enable &= ~mask;
-	    bridge->b_int_enable = b_int_enable;
-	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	    pcibr_unlock(pcibr_soft, s);
-	    return;
-	}
-}
-
-/* =====================================================================
- *    ERROR HANDLING
- */
-
-#ifdef	DEBUG
-#ifdef	ERROR_DEBUG
-#define BRIDGE_PIOERR_TIMEOUT	100	/* Timeout with ERROR_DEBUG defined */
-#else
-#define BRIDGE_PIOERR_TIMEOUT	40	/* Timeout in debug mode  */
-#endif
-#else
-#define BRIDGE_PIOERR_TIMEOUT	1	/* Timeout in non-debug mode                            */
-#endif
-
-LOCAL void
-print_bridge_errcmd(uint32_t cmdword, char *errtype)
-{
-#ifdef SUPPORT_PRINTING_R_FORMAT
-    PRINT_WARNING(
-	    "	Bridge %s error command word register %R",
-	    errtype, cmdword, xio_cmd_bits);
-#else
-    PRINT_WARNING(
-	    "	Bridge %s error command word register 0x%x",
-	    errtype, cmdword);
-#endif
-}
-
-LOCAL char             *pcibr_isr_errs[] =
-{
-    "", "", "", "", "", "", "", "",
-    "08: GIO non-contiguous byte enable in crosstalk packet",
-    "09: PCI to Crosstalk read request timeout",
-    "10: PCI retry operation count exhausted.",
-    "11: PCI bus device select timeout",
-    "12: PCI device reported parity error",
-    "13: PCI Address/Cmd parity error ",
-    "14: PCI Bridge detected parity error",
-    "15: PCI abort condition",
-    "16: SSRAM parity error",
-    "17: LLP Transmitter Retry count wrapped",
-    "18: LLP Transmitter side required Retry",
-    "19: LLP Receiver retry count wrapped",
-    "20: LLP Receiver check bit error",
-    "21: LLP Receiver sequence number error",
-    "22: Request packet overflow",
-    "23: Request operation not supported by bridge",
-    "24: Request packet has invalid address for bridge widget",
-    "25: Incoming request xtalk command word error bit set or invalid sideband",
-    "26: Incoming response xtalk command word error bit set or invalid sideband",
-    "27: Framing error, request cmd data size does not match actual",
-    "28: Framing error, response cmd data size does not match actual",
-    "29: Unexpected response arrived",
-    "30: Access to SSRAM beyond device limits",
-    "31: Multiple errors occurred",
-};
-
-/*
- * PCI Bridge Error interrupt handling.
- * This routine gets invoked from system interrupt dispatcher
- * and is responsible for invoking appropriate error handler,
- * depending on the type of error.
- * This IS a duplicate of bridge_errintr defined specfic to IP30.
- * There are some minor differences in terms of the return value and
- * parameters passed. One of these two should be removed at some point
- * of time.
- */
-/*ARGSUSED */
-void
-pcibr_error_dump(pcibr_soft_t pcibr_soft)
-{
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    bridgereg_t             int_status;
-    int                     i;
-
-    int_status = (bridge->b_int_status & ~BRIDGE_ISR_INT_MSK);
-
-    PRINT_ALERT( "%s PCI BRIDGE ERROR: int_status is 0x%X",
-	    pcibr_soft->bs_name, int_status);
-
-    for (i = PCIBR_ISR_ERR_START; i < PCIBR_ISR_MAX_ERRS; i++) {
-	if (int_status & (1 << i)) {
-	    PRINT_WARNING( "%s", pcibr_isr_errs[i]);
-	}
-    }
-
-    if (int_status & BRIDGE_ISR_XTALK_ERROR) {
-	print_bridge_errcmd(bridge->b_wid_err_cmdword, "");
-
-	PRINT_WARNING("   Bridge error address 0x%lx",
-		(((uint64_t) bridge->b_wid_err_upper << 32) |
-		 bridge->b_wid_err_lower));
-
-	print_bridge_errcmd(bridge->b_wid_aux_err, "Aux");
-
-	if (int_status & (BRIDGE_ISR_BAD_XRESP_PKT | BRIDGE_ISR_RESP_XTLK_ERR)) {
-	    PRINT_WARNING("	Bridge response buffer: dev-num %d buff-num %d addr 0x%lx\n",
-		    ((bridge->b_wid_resp_upper >> 20) & 0x3),
-		    ((bridge->b_wid_resp_upper >> 16) & 0xF),
-		    (((uint64_t) (bridge->b_wid_resp_upper & 0xFFFF) << 32) |
-		     bridge->b_wid_resp_lower));
-	}
-    }
-    if (int_status & BRIDGE_ISR_SSRAM_PERR)
-	PRINT_WARNING("   Bridge SSRAM parity error register 0x%x",
-		bridge->b_ram_perr);
-
-    if (int_status & BRIDGE_ISR_PCIBUS_ERROR) {
-	PRINT_WARNING("   PCI/GIO error upper address register 0x%x",
-		bridge->b_pci_err_upper);
-
-	PRINT_WARNING("   PCI/GIO error lower address register 0x%x",
-		bridge->b_pci_err_lower);
-    }
-    if (int_status & BRIDGE_ISR_ERROR_FATAL) {
-	PRINT_PANIC("PCI Bridge Error interrupt killed the system");
-	/*NOTREACHED */
-    } else {
-	PRINT_ALERT( "Non-fatal Error in Bridge..");
-    }
-}
-
-#define PCIBR_ERRINTR_GROUP(error)	\
-		(( error & (BRIDGE_IRR_PCI_GRP|BRIDGE_IRR_GIO_GRP)
-
-uint32_t
-pcibr_errintr_group(uint32_t error)
-{
-    uint32_t              group = BRIDGE_IRR_MULTI_CLR;
-
-    if (error & BRIDGE_IRR_PCI_GRP)
-	group |= BRIDGE_IRR_PCI_GRP_CLR;
-    if (error & BRIDGE_IRR_SSRAM_GRP)
-	group |= BRIDGE_IRR_SSRAM_GRP_CLR;
-    if (error & BRIDGE_IRR_LLP_GRP)
-	group |= BRIDGE_IRR_LLP_GRP_CLR;
-    if (error & BRIDGE_IRR_REQ_DSP_GRP)
-	group |= BRIDGE_IRR_REQ_DSP_GRP_CLR;
-    if (error & BRIDGE_IRR_RESP_BUF_GRP)
-	group |= BRIDGE_IRR_RESP_BUF_GRP_CLR;
-    if (error & BRIDGE_IRR_CRP_GRP)
-	group |= BRIDGE_IRR_CRP_GRP_CLR;
-
-    return group;
-
-}
-
-
-/* pcibr_pioerr_check():
- *	Check to see if this pcibr has a PCI PIO
- *	TIMEOUT error; if so, clear it and bump
- *	the timeout-count on any piomaps that
- *	could cover the address.
- */
-static void
-pcibr_pioerr_check(pcibr_soft_t soft)
-{
-    bridge_t		   *bridge;
-    bridgereg_t		    b_int_status;
-    bridgereg_t		    b_pci_err_lower;
-    bridgereg_t		    b_pci_err_upper;
-    iopaddr_t		    pci_addr;
-    pciio_slot_t	    slot;
-    pcibr_piomap_t	    map;
-    iopaddr_t		    base;
-    size_t		    size;
-    unsigned		    win;
-    int			    func;
-
-    bridge = soft->bs_base;
-    b_int_status = bridge->b_int_status;
-    if (b_int_status & BRIDGE_ISR_PCIBUS_PIOERR) {
-	b_pci_err_lower = bridge->b_pci_err_lower;
-	b_pci_err_upper = bridge->b_pci_err_upper;
-	b_int_status = bridge->b_int_status;
-	if (b_int_status & BRIDGE_ISR_PCIBUS_PIOERR) {
-	    bridge->b_int_rst_stat = (BRIDGE_IRR_PCI_GRP_CLR|
-				      BRIDGE_IRR_MULTI_CLR);
-
-	    pci_addr = b_pci_err_upper & BRIDGE_ERRUPPR_ADDRMASK;
-	    pci_addr = (pci_addr << 32) | b_pci_err_lower;
-
-	    slot = 8;
-	    while (slot-- > 0) {
-		int 		nfunc = soft->bs_slot[slot].bss_ninfo;
-		pcibr_info_h	pcibr_infoh = soft->bs_slot[slot].bss_infos;
-
-		for (func = 0; func < nfunc; func++) {
-		    pcibr_info_t 	pcibr_info = pcibr_infoh[func];
-
-		    if (!pcibr_info)
-			continue;
-
-		    for (map = pcibr_info->f_piomap;
-			 map != NULL; map = map->bp_next) {
-			base = map->bp_pciaddr;
-			size = map->bp_mapsz;
-			win = map->bp_space - PCIIO_SPACE_WIN(0);
-			if (win < 6)
-			    base += 
-				soft->bs_slot[slot].bss_window[win].bssw_base;
-			else if (map->bp_space == PCIIO_SPACE_ROM)
-			    base += pcibr_info->f_rbase;
-			if ((pci_addr >= base) && (pci_addr < (base + size)))
-			    atomic_inc(map->bp_toc);
-		    }
-		}
-	    }
-	}
-    }
-}
-
-/*
- * PCI Bridge Error interrupt handler.
- *      This gets invoked, whenever a PCI bridge sends an error interrupt.
- *      Primarily this servers two purposes.
- *              - If an error can be handled (typically a PIO read/write
- *                error, we try to do it silently.
- *              - If an error cannot be handled, we die violently.
- *      Interrupt due to PIO errors:
- *              - Bridge sends an interrupt, whenever a PCI operation
- *                done by the bridge as the master fails. Operations could
- *                be either a PIO read or a PIO write.
- *                PIO Read operation also triggers a bus error, and it's
- *                We primarily ignore this interrupt in that context..
- *                For PIO write errors, this is the only indication.
- *                and we have to handle with the info from here.
- *
- *                So, there is no way to distinguish if an interrupt is
- *                due to read or write error!.
- */
-
-
-LOCAL void
-pcibr_error_intr_handler(intr_arg_t arg)
-{
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge;
-    bridgereg_t             int_status;
-    bridgereg_t             err_status;
-    int                     i;
-
-    /* REFERENCED */
-    bridgereg_t             disable_errintr_mask = 0;
-
-#if PCIBR_SOFT_LIST
-    /* IP27 seems to be handing us junk.
-     */
-    {
-	pcibr_list_p            entry;
-
-	entry = pcibr_list;
-	while (1) {
-	    if (entry == NULL) {
-		printk("pcibr_error_intr_handler:\n"
-			"\tparameter (0x%p) is not a pcibr_soft!",
-			arg);
-		PRINT_PANIC("Invalid parameter to pcibr_error_intr_handler");
-	    }
-	    if ((intr_arg_t) entry->bl_soft == arg)
-		break;
-	    entry = entry->bl_next;
-	}
-    }
-#endif
-    pcibr_soft = (pcibr_soft_t) arg;
-    bridge = pcibr_soft->bs_base;
-
-    /*
-     * pcibr_error_intr_handler gets invoked whenever bridge encounters
-     * an error situation, and the interrupt for that error is enabled.
-     * This routine decides if the error is fatal or not, and takes
-     * action accordingly.
-     *
-     * In one case there is a need for special action.
-     * In case of PIO read/write timeouts due to user level, we do
-     * get an error interrupt. In this case, way to handle would
-     * be to start a timeout. If the error was due to "read", bus
-     * error handling code takes care of it. If error is due to write,
-     * it's handled at timeout
-     */
-
-    /* int_status is which bits we have to clear;
-     * err_status is the bits we haven't handled yet.
-     */
-
-    int_status = bridge->b_int_status &  ~BRIDGE_ISR_INT_MSK;
-    err_status = int_status & ~BRIDGE_ISR_MULTI_ERR;
-
-    if (!(int_status & ~BRIDGE_ISR_INT_MSK)) {
-	/*
-	 * No error bit set!!.
-	 */
-	return;
-    }
-    /* If we have a PCIBUS_PIOERR,
-     * hand it to the logger but otherwise
-     * ignore the event.
-     */
-    if (int_status & BRIDGE_ISR_PCIBUS_PIOERR) {
-	pcibr_pioerr_check(pcibr_soft);
-	err_status &= ~BRIDGE_ISR_PCIBUS_PIOERR;
-	int_status &= ~BRIDGE_ISR_PCIBUS_PIOERR;
-    }
-
-
-    if (err_status) {
-	struct bs_errintr_stat_s *bs_estat = pcibr_soft->bs_errintr_stat;
-
-	for (i = PCIBR_ISR_ERR_START; i < PCIBR_ISR_MAX_ERRS; i++, bs_estat++) {
-	    if (err_status & (1 << i)) {
-		uint32_t              errrate = 0;
-		uint32_t              errcount = 0;
-		uint32_t              errinterval = 0, current_tick = 0;
-		int                     panic_on_llp_tx_retry = 0;
-		int                     is_llp_tx_retry_intr = 0;
-
-		bs_estat->bs_errcount_total++;
-
-#ifdef LATER
-		current_tick = lbolt;
-#else
-		current_tick = 0;
-#endif
-		errinterval = (current_tick - bs_estat->bs_lasterr_timestamp);
-		errcount = (bs_estat->bs_errcount_total -
-			    bs_estat->bs_lasterr_snapshot);
-
-		is_llp_tx_retry_intr = (BRIDGE_ISR_LLP_TX_RETRY == (1 << i));
-
-		/* On a non-zero error rate (which is equivalent to
-		 * to 100 errors /sec at least) for the LLP transmitter
-		 * retry interrupt we need to panic the system
-		 * to prevent potential data corruption .
-		 * NOTE : errcount is being compared to PCIBR_ERRTIME_THRESHOLD
-		 * to make sure that we are not seing cases like x error
-		 * interrupts per y ticks for very low x ,y (x > y ) which
-		 * makes error rate be > 100 /sec.
-		 */
-
-		/* Check for the divide by zero condition while
-		 * calculating the error rates.
-		 */
-
-		if (errinterval) {
-		    errrate = errcount / errinterval;
-		    /* If able to calculate error rate
-		     * on a LLP transmitter retry interrupt check
-		     * if the error rate is nonzero and we have seen
-		     * a certain minimum number of errors.
-		     */
-		    if (is_llp_tx_retry_intr &&
-			errrate &&
-			(errcount >= PCIBR_ERRTIME_THRESHOLD)) {
-			panic_on_llp_tx_retry = 1;
-		    }
-		} else {
-		    errrate = 0;
-		    /* Since we are not able to calculate the
-		     * error rate check if we exceeded a certain
-		     * minimum number of errors for LLP transmitter
-		     * retries. Note that this can only happen
-		     * within the first tick after the last snapshot.
-		     */
-		    if (is_llp_tx_retry_intr &&
-			(errcount >= PCIBR_ERRINTR_DISABLE_LEVEL)) {
-			panic_on_llp_tx_retry = 1;
-		    }
-		}
-		if (panic_on_llp_tx_retry) {
-		    static uint32_t       last_printed_rate;
-
-		    if (errrate > last_printed_rate) {
-			last_printed_rate = errrate;
-			/* Print the warning only if the error rate
-			 * for the transmitter retry interrupt
-			 * exceeded the previously printed rate.
-			 */
-			PRINT_WARNING(
-				"%s: %s, Excessive error interrupts : %d/tick\n",
-				pcibr_soft->bs_name,
-				pcibr_isr_errs[i],
-				errrate);
-
-		    }
-		    /*
-		     * Update snapshot, and time
-		     */
-		    bs_estat->bs_lasterr_timestamp = current_tick;
-		    bs_estat->bs_lasterr_snapshot =
-			bs_estat->bs_errcount_total;
-
-		}
-		/*
-		 * If the error rate is high enough, print the error rate.
-		 */
-		if (errinterval > PCIBR_ERRTIME_THRESHOLD) {
-
-		    if (errrate > PCIBR_ERRRATE_THRESHOLD) {
-			PRINT_NOTICE( "%s: %s, Error rate %d/tick",
-				pcibr_soft->bs_name,
-				pcibr_isr_errs[i],
-				errrate);
-			/*
-			 * Update snapshot, and time
-			 */
-			bs_estat->bs_lasterr_timestamp = current_tick;
-			bs_estat->bs_lasterr_snapshot =
-			    bs_estat->bs_errcount_total;
-		    }
-		}
-		if (bs_estat->bs_errcount_total > PCIBR_ERRINTR_DISABLE_LEVEL) {
-		    /*
-		     * We have seen a fairly large number of errors of
-		     * this type. Let's disable the interrupt. But flash
-		     * a message about the interrupt being disabled.
-		     */
-		    PRINT_NOTICE(
-			    "%s Disabling error interrupt type %s. Error count %d",
-			    pcibr_soft->bs_name,
-			    pcibr_isr_errs[i],
-			    bs_estat->bs_errcount_total);
-		    disable_errintr_mask |= (1 << i);
-		}
-	    }
-	}
-    }
-
-    if (disable_errintr_mask) {
-	/*
-	 * Disable some high frequency errors as they
-	 * could eat up too much cpu time.
-	 */
-	bridge->b_int_enable &= ~disable_errintr_mask;
-    }
-    /*
-     * If we leave the PROM cacheable, T5 might
-     * try to do a cache line sized writeback to it,
-     * which will cause a BRIDGE_ISR_INVLD_ADDR.
-     */
-    if ((err_status & BRIDGE_ISR_INVLD_ADDR) &&
-	(0x00000000 == bridge->b_wid_err_upper) &&
-	(0x00C00000 == (0xFFC00000 & bridge->b_wid_err_lower)) &&
-	(0x00402000 == (0x00F07F00 & bridge->b_wid_err_cmdword))) {
-	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
-    }
-#if defined (PCIBR_LLP_CONTROL_WAR)
-    /*
-     * The bridge bug, where the llp_config or control registers
-     * need to be read back after being written, affects an MP
-     * system since there could be small windows between writing
-     * the register and reading it back on one cpu while another
-     * cpu is fielding an interrupt. If we run into this scenario,
-     * workaround the problem by ignoring the error. (bug 454474)
-     * pcibr_llp_control_war_cnt keeps an approximate number of
-     * times we saw this problem on a system.
-     */
-
-    if ((err_status & BRIDGE_ISR_INVLD_ADDR) &&
-	((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower))
-	 == (BRIDGE_INT_RST_STAT & 0xff0))) {
-#ifdef LATER
-	if (kdebug)
-	    PRINT_NOTICE( "%s bridge: ignoring llp/control address interrupt",
-		    pcibr_soft->bs_name);
-#endif
-	pcibr_llp_control_war_cnt++;
-	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
-    }
-#endif				/* PCIBR_LLP_CONTROL_WAR */
-
-#ifdef	DEBUG
-	if (err_status & BRIDGE_ISR_ERROR_DUMP)
-	    pcibr_error_dump(pcibr_soft);
-#else	
-	if (err_status & BRIDGE_ISR_ERROR_FATAL) {
-	    printk("BRIDGE ERR STATUS 0x%x\n", err_status);
-	    pcibr_error_dump(pcibr_soft);
-	}
-#endif
-
-    /*
-     * We can't return without re-enabling the interrupt, since
-     * it would cause problems for devices like IOC3 (Lost
-     * interrupts ?.). So, just cleanup the interrupt, and
-     * use saved values later..
-     */
-    bridge->b_int_rst_stat = pcibr_errintr_group(int_status);
-}
-
-/*
- * pcibr_addr_toslot
- *      Given the 'pciaddr' find out which slot this address is
- *      allocated to, and return the slot number.
- *      While we have the info handy, construct the
- *      function number, space code and offset as well.
- *
- * NOTE: if this routine is called, we don't know whether
- * the address is in CFG, MEM, or I/O space. We have to guess.
- * This will be the case on PIO stores, where the only way
- * we have of getting the address is to check the Bridge, which
- * stores the PCI address but not the space and not the xtalk
- * address (from which we could get it).
- */
-LOCAL int
-pcibr_addr_toslot(pcibr_soft_t pcibr_soft,
-		  iopaddr_t pciaddr,
-		  pciio_space_t *spacep,
-		  iopaddr_t *offsetp,
-		  pciio_function_t *funcp)
-{
-    int                     s, f=0, w;
-    iopaddr_t               base;
-    size_t                  size;
-    pciio_piospace_t        piosp;
-
-    /*
-     * Check if the address is in config space
-     */
-
-    if ((pciaddr >= BRIDGE_CONFIG_BASE) && (pciaddr < BRIDGE_CONFIG_END)) {
-
-	if (pciaddr >= BRIDGE_CONFIG1_BASE)
-	    pciaddr -= BRIDGE_CONFIG1_BASE;
-	else
-	    pciaddr -= BRIDGE_CONFIG_BASE;
-
-	s = pciaddr / BRIDGE_CONFIG_SLOT_SIZE;
-	pciaddr %= BRIDGE_CONFIG_SLOT_SIZE;
-
-	if (funcp) {
-	    f = pciaddr / 0x100;
-	    pciaddr %= 0x100;
-	}
-	if (spacep)
-	    *spacep = PCIIO_SPACE_CFG;
-	if (offsetp)
-	    *offsetp = pciaddr;
-	if (funcp)
-	    *funcp = f;
-
-	return s;
-    }
-    for (s = 0; s < 8; s++) {
-	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
-	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
-
-	for (f = 0; f < nf; f++) {
-	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
-
-	    if (!pcibr_info)
-		continue;
-	    for (w = 0; w < 6; w++) {
-		if (pcibr_info->f_window[w].w_space
-		    == PCIIO_SPACE_NONE) {
-		    continue;
-		}
-		base = pcibr_info->f_window[w].w_base;
-		size = pcibr_info->f_window[w].w_size;
-
-		if ((pciaddr >= base) && (pciaddr < (base + size))) {
-		    if (spacep)
-			*spacep = PCIIO_SPACE_WIN(w);
-		    if (offsetp)
-			*offsetp = pciaddr - base;
-		    if (funcp)
-			*funcp = f;
-		    return s;
-		}			/* endif match */
-	    }				/* next window */
-	}				/* next func */
-    }					/* next slot */
-
-    /*
-     * Check if the address was allocated as part of the
-     * pcibr_piospace_alloc calls.
-     */
-    for (s = 0; s < 8; s++) {
-	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
-	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
-
-	for (f = 0; f < nf; f++) {
-	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
-
-	    if (!pcibr_info)
-		continue;
-	    piosp = pcibr_info->f_piospace;
-	    while (piosp) {
-		if ((piosp->start <= pciaddr) &&
-		    ((piosp->count + piosp->start) > pciaddr)) {
-		    if (spacep)
-			*spacep = piosp->space;
-		    if (offsetp)
-			*offsetp = pciaddr - piosp->start;
-		    return s;
-		}			/* endif match */
-		piosp = piosp->next;
-	    }				/* next piosp */
-	}				/* next func */
-    }					/* next slot */
-
-    /*
-     * Some other random address on the PCI bus ...
-     * we have no way of knowing whether this was
-     * a MEM or I/O access; so, for now, we just
-     * assume that the low 1G is MEM, the next
-     * 3G is I/O, and anything above the 4G limit
-     * is obviously MEM.
-     */
-
-    if (spacep)
-	*spacep = ((pciaddr < (1ul << 30)) ? PCIIO_SPACE_MEM :
-		   (pciaddr < (4ul << 30)) ? PCIIO_SPACE_IO :
-		   PCIIO_SPACE_MEM);
-    if (offsetp)
-	*offsetp = pciaddr;
-
-    return PCIIO_SLOT_NONE;
-
-}
-
-LOCAL void
-pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code)
-{
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    ASSERT(error_code & IOECODE_PIO);
-    error_code = error_code;
-
-    bridge->b_int_rst_stat =
-	(BRIDGE_IRR_PCI_GRP_CLR | BRIDGE_IRR_MULTI_CLR);
-    (void) bridge->b_wid_tflush;	/* flushbus */
-}
-
-/*
- * pcibr_error_extract
- *      Given the 'pcibr vertex handle' find out which slot
- *      the bridge status error address (from pcibr_soft info
- *      hanging off the vertex)
- *      allocated to, and return the slot number.
- *      While we have the info handy, construct the
- *      space code and offset as well.
- *
- * NOTE: if this routine is called, we don't know whether
- * the address is in CFG, MEM, or I/O space. We have to guess.
- * This will be the case on PIO stores, where the only way
- * we have of getting the address is to check the Bridge, which
- * stores the PCI address but not the space and not the xtalk
- * address (from which we could get it).
- *
- * XXX- this interface has no way to return the function
- * number on a multifunction card, even though that data
- * is available.
- */
-
-pciio_slot_t
-pcibr_error_extract(devfs_handle_t pcibr_vhdl,
-		    pciio_space_t *spacep,
-		    iopaddr_t *offsetp)
-{
-    pcibr_soft_t            pcibr_soft = 0;
-    iopaddr_t               bserr_addr;
-    bridge_t               *bridge;
-    pciio_slot_t            slot = PCIIO_SLOT_NONE;
-    arbitrary_info_t	    rev;
-
-    /* Do a sanity check as to whether we really got a 
-     * bridge vertex handle.
-     */
-    if (hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &rev) !=
-	GRAPH_SUCCESS) 
-	return(slot);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (pcibr_soft) {
-	bridge = pcibr_soft->bs_base;
-	bserr_addr =
-	    bridge->b_pci_err_lower |
-	    ((uint64_t) (bridge->b_pci_err_upper &
-			   BRIDGE_ERRUPPR_ADDRMASK) << 32);
-
-	slot = pcibr_addr_toslot(pcibr_soft, bserr_addr,
-				 spacep, offsetp, NULL);
-    }
-    return slot;
-}
-
-/*ARGSUSED */
-void
-pcibr_device_disable(pcibr_soft_t pcibr_soft, int devnum)
-{
-    /*
-     * XXX
-     * Device failed to handle error. Take steps to
-     * disable this device ? HOW TO DO IT ?
-     *
-     * If there are any Read response buffers associated
-     * with this device, it's time to get them back!!
-     *
-     * We can disassociate any interrupt level associated
-     * with this device, and disable that interrupt level
-     *
-     * For now it's just a place holder
-     */
-}
-
-/*
- * pcibr_pioerror
- *      Handle PIO error that happened at the bridge pointed by pcibr_soft.
- *
- *      Queries the Bus interface attached to see if the device driver
- *      mapping the device-number that caused error can handle the
- *      situation. If so, it will clean up any error, and return
- *      indicating the error was handled. If the device driver is unable
- *      to handle the error, it expects the bus-interface to disable that
- *      device, and takes any steps needed here to take away any resources
- *      associated with this device.
- */
-
-#define BEM_ADD_STR(s)	printk("%s", (s))
-#ifdef SUPPORT_SGI_CMN_ERR_STUFF
-#define BEM_ADD_VAR(v)	printk("\t%20s: 0x%x\n", #v, (v))
-#define BEM_ADD_REG(r)	printk("\t%20s: %R\n", #r, (r), r ## _desc)
-
-#define BEM_ADD_NSPC(n,s)	printk("\t%20s: %R\n", n, s, space_desc)
-#else
-#define BEM_ADD_VAR(v)	
-#define BEM_ADD_REG(r)	
-#define BEM_ADD_NSPC(n,s)
-#endif
-#define BEM_ADD_SPC(s)		BEM_ADD_NSPC(#s, s)
-
-/* BEM_ADD_IOE doesn't dump the whole ioerror, it just
- * decodes the PCI specific portions -- we count on our
- * callers to dump the raw IOE data.
- */
-#ifdef LATER
-#define BEM_ADD_IOE(ioe)						\
-	do {								\
-	    if (IOERROR_FIELDVALID(ioe, busspace)) {			\
-		unsigned		spc;				\
-		unsigned		win;				\
-									\
-		spc = IOERROR_GETVALUE(ioe, busspace);			\
-		win = spc - PCIIO_SPACE_WIN(0);				\
-									\
-		switch (spc) {						\
-		case PCIIO_SPACE_CFG:					\
-		    printk("\tPCI Slot %d Func %d CFG space Offset 0x%x\n",	\
-	    pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, widgetdev)),	\
-	    pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, widgetdev)),	\
-			    IOERROR_GETVALUE(ioe, busaddr));		\
-		    break;						\
-		case PCIIO_SPACE_IO:					\
-		    printk("\tPCI I/O space  Offset 0x%x\n",		\
-			    IOERROR_GETVALUE(ioe, busaddr));		\
-		    break;						\
-		case PCIIO_SPACE_MEM:					\
-		case PCIIO_SPACE_MEM32:					\
-		case PCIIO_SPACE_MEM64:					\
-		    printk("\tPCI MEM space Offset 0x%x\n",		\
-			    IOERROR_GETVALUE(ioe, busaddr));		\
-		    break;						\
-		default:						\
-		    if (win < 6) {					\
-		    printk("\tPCI Slot %d Func %d Window %d Offset 0x%x\n",\
-	    pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, widgetdev)),	\
-	    pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, widgetdev)),	\
-			    win,					\
-			    IOERROR_GETVALUE(ioe, busaddr));		\
-		    }							\
-		    break;						\
-		}							\
-	    }								\
-	} while (0)
-#else
-#define BEM_ADD_IOE(ioe)
-#endif
-
-/*ARGSUSED */
-LOCAL int
-pcibr_pioerror(
-		  pcibr_soft_t pcibr_soft,
-		  int error_code,
-		  ioerror_mode_t mode,
-		  ioerror_t *ioe)
-{
-    int                     retval = IOERROR_HANDLED;
-
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    bridgereg_t             bridge_int_status;
-    bridgereg_t             bridge_pci_err_lower;
-    bridgereg_t             bridge_pci_err_upper;
-    bridgereg_t             bridge_pci_err_addr;
-
-    iopaddr_t               bad_xaddr;
-
-    pciio_space_t           raw_space;	/* raw PCI space */
-    iopaddr_t               raw_paddr;	/* raw PCI address */
-
-    pciio_space_t           space;	/* final PCI space */
-    pciio_slot_t            slot;	/* final PCI slot, if appropriate */
-    pciio_function_t        func;	/* final PCI func, if appropriate */
-    iopaddr_t               offset;	/* final PCI offset */
-    
-    int                     cs, cw, cf;
-    pciio_space_t           wx;
-    iopaddr_t               wb;
-    size_t                  ws;
-    iopaddr_t               wl;
-
-
-    /*
-     * We expect to have an "xtalkaddr" coming in,
-     * and need to construct the slot/space/offset.
-     */
-
-#ifdef LATER
-    bad_xaddr = IOERROR_GETVALUE(ioe, xtalkaddr);
-#else
-    bad_xaddr = -1;
-#endif
-
-    slot = PCIIO_SLOT_NONE;
-    func = PCIIO_FUNC_NONE;
-    raw_space = PCIIO_SPACE_NONE;
-    raw_paddr = 0;
-
-    if ((bad_xaddr >= BRIDGE_TYPE0_CFG_DEV0) &&
-	(bad_xaddr < BRIDGE_TYPE1_CFG)) {
-	raw_paddr = bad_xaddr - BRIDGE_TYPE0_CFG_DEV0;
-	slot = raw_paddr / BRIDGE_TYPE0_CFG_SLOT_OFF;
-	raw_paddr = raw_paddr % BRIDGE_TYPE0_CFG_SLOT_OFF;
-	raw_space = PCIIO_SPACE_CFG;
-    }
-    if ((bad_xaddr >= BRIDGE_TYPE1_CFG) &&
-	(bad_xaddr < (BRIDGE_TYPE1_CFG + 0x1000))) {
-	/* Type 1 config space:
-	 * slot and function numbers not known.
-	 * Perhaps we can read them back?
-	 */
-	raw_paddr = bad_xaddr - BRIDGE_TYPE1_CFG;
-	raw_space = PCIIO_SPACE_CFG;
-    }
-    if ((bad_xaddr >= BRIDGE_DEVIO0) &&
-	(bad_xaddr < BRIDGE_DEVIO(BRIDGE_DEV_CNT))) {
-	int                     x;
-
-	raw_paddr = bad_xaddr - BRIDGE_DEVIO0;
-	x = raw_paddr / BRIDGE_DEVIO_OFF;
-	raw_paddr %= BRIDGE_DEVIO_OFF;
-	/* first two devio windows are double-sized */
-	if ((x == 1) || (x == 3))
-	    raw_paddr += BRIDGE_DEVIO_OFF;
-	if (x > 0)
-	    x--;
-	if (x > 1)
-	    x--;
-	/* x is which devio reg; no guarantee
-	 * PCI slot x will be responding.
-	 * still need to figure out who decodes
-	 * space/offset on the bus.
-	 */
-	raw_space = pcibr_soft->bs_slot[x].bss_devio.bssd_space;
-	if (raw_space == PCIIO_SPACE_NONE) {
-	    /* Someone got an error because they
-	     * accessed the PCI bus via a DevIO(x)
-	     * window that pcibr has not yet assigned
-	     * to any specific PCI address. It is
-	     * quite possible that the Device(x)
-	     * register has been changed since they
-	     * made their access, but we will give it
-	     * our best decode shot.
-	     */
-	    raw_space = pcibr_soft->bs_slot[x].bss_device
-		& BRIDGE_DEV_DEV_IO_MEM
-		? PCIIO_SPACE_MEM
-		: PCIIO_SPACE_IO;
-	    raw_paddr +=
-		(pcibr_soft->bs_slot[x].bss_device &
-		 BRIDGE_DEV_OFF_MASK) <<
-		BRIDGE_DEV_OFF_ADDR_SHFT;
-	} else
-	    raw_paddr += pcibr_soft->bs_slot[x].bss_devio.bssd_base;
-    }
-    if ((bad_xaddr >= BRIDGE_PCI_MEM32_BASE) &&
-	(bad_xaddr <= BRIDGE_PCI_MEM32_LIMIT)) {
-	raw_space = PCIIO_SPACE_MEM32;
-	raw_paddr = bad_xaddr - BRIDGE_PCI_MEM32_BASE;
-    }
-    if ((bad_xaddr >= BRIDGE_PCI_MEM64_BASE) &&
-	(bad_xaddr <= BRIDGE_PCI_MEM64_LIMIT)) {
-	raw_space = PCIIO_SPACE_MEM64;
-	raw_paddr = bad_xaddr - BRIDGE_PCI_MEM64_BASE;
-    }
-    if ((bad_xaddr >= BRIDGE_PCI_IO_BASE) &&
-	(bad_xaddr <= BRIDGE_PCI_IO_LIMIT)) {
-	raw_space = PCIIO_SPACE_IO;
-	raw_paddr = bad_xaddr - BRIDGE_PCI_IO_BASE;
-    }
-    space = raw_space;
-    offset = raw_paddr;
-
-    if ((slot == PCIIO_SLOT_NONE) && (space != PCIIO_SPACE_NONE)) {
-	/* we've got a space/offset but not which
-	 * PCI slot decodes it. Check through our
-	 * notions of which devices decode where.
-	 *
-	 * Yes, this "duplicates" some logic in
-	 * pcibr_addr_toslot; the difference is,
-	 * this code knows which space we are in,
-	 * and can really really tell what is
-	 * going on (no guessing).
-	 */
-
-	for (cs = 0; (cs < 8) && (slot == PCIIO_SLOT_NONE); cs++) {
-	    int                     nf = pcibr_soft->bs_slot[cs].bss_ninfo;
-	    pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[cs].bss_infos;
-
-	    for (cf = 0; (cf < nf) && (slot == PCIIO_SLOT_NONE); cf++) {
-		pcibr_info_t            pcibr_info = pcibr_infoh[cf];
-
-		if (!pcibr_info)
-		    continue;
-		for (cw = 0; (cw < 6) && (slot == PCIIO_SLOT_NONE); ++cw) {
-		    if (((wx = pcibr_info->f_window[cw].w_space) != PCIIO_SPACE_NONE) &&
-			((wb = pcibr_info->f_window[cw].w_base) != 0) &&
-			((ws = pcibr_info->f_window[cw].w_size) != 0) &&
-			((wl = wb + ws) > wb) &&
-			((wb <= offset) && (wl > offset))) {
-			/* MEM, MEM32 and MEM64 need to
-			 * compare as equal ...
-			 */
-			if ((wx == space) ||
-			    (((wx == PCIIO_SPACE_MEM) ||
-			      (wx == PCIIO_SPACE_MEM32) ||
-			      (wx == PCIIO_SPACE_MEM64)) &&
-			     ((space == PCIIO_SPACE_MEM) ||
-			      (space == PCIIO_SPACE_MEM32) ||
-			      (space == PCIIO_SPACE_MEM64)))) {
-			    slot = cs;
-			    func = cf;
-			    space = PCIIO_SPACE_WIN(cw);
-			    offset -= wb;
-			}		/* endif window space match */
-		    }			/* endif window valid and addr match */
-		}			/* next window unless slot set */
-	    }				/* next func unless slot set */
-	}				/* next slot unless slot set */
-	/* XXX- if slot is still -1, no PCI devices are
-	 * decoding here using their standard PCI BASE
-	 * registers. This would be a really good place
-	 * to cross-coordinate with the pciio PCI
-	 * address space allocation routines, to find
-	 * out if this address is "allocated" by any of
-	 * our subsidiary devices.
-	 */
-    }
-    /* Scan all piomap records on this PCI bus to update
-     * the TimeOut Counters on all matching maps. If we
-     * don't already know the slot number, take it from
-     * the first matching piomap. Note that we have to
-     * compare maps against raw_space and raw_paddr
-     * since space and offset could already be
-     * window-relative.
-     *
-     * There is a chance that one CPU could update
-     * through this path, and another CPU could also
-     * update due to an interrupt. Closing this hole
-     * would only result in the possibility of some
-     * errors never getting logged at all, and since the
-     * use for bp_toc is as a logical test rather than a
-     * strict count, the excess counts are not a
-     * problem.
-     */
-    for (cs = 0; cs < 8; ++cs) {
-	int 		nf = pcibr_soft->bs_slot[cs].bss_ninfo;
-	pcibr_info_h	pcibr_infoh = pcibr_soft->bs_slot[cs].bss_infos;
-
-	for (cf = 0; cf < nf; cf++) {
-	    pcibr_info_t 	pcibr_info = pcibr_infoh[cf];
-	    pcibr_piomap_t	map;    
-
-	    if (!pcibr_info)
-		continue;
-
-	    for (map = pcibr_info->f_piomap;
-	     map != NULL; map = map->bp_next) {
-	    wx = map->bp_space;
-	    wb = map->bp_pciaddr;
-	    ws = map->bp_mapsz;
-	    cw = wx - PCIIO_SPACE_WIN(0);
-	    if (cw < 6) {
-		wb += pcibr_soft->bs_slot[cs].bss_window[cw].bssw_base;
-		wx = pcibr_soft->bs_slot[cs].bss_window[cw].bssw_space;
-	    }
-	    if (wx == PCIIO_SPACE_ROM) {
-		wb += pcibr_info->f_rbase;
-		wx = PCIIO_SPACE_MEM;
-	    }
-	    if ((wx == PCIIO_SPACE_MEM32) ||
-		(wx == PCIIO_SPACE_MEM64))
-		wx = PCIIO_SPACE_MEM;
-	    wl = wb + ws;
-	    if ((wx == raw_space) && (raw_paddr >= wb) && (raw_paddr < wl)) {
-		atomic_inc(map->bp_toc);
-		if (slot == PCIIO_SLOT_NONE) {
-		    slot = cs;
-		    space = map->bp_space;
-		    if (cw < 6)
-			offset -= pcibr_soft->bs_slot[cs].bss_window[cw].bssw_base;
-		}
-	    }
-	    }
-	}
-    }
-
-    if (space != PCIIO_SPACE_NONE) {
-	if (slot != PCIIO_SLOT_NONE) {
-#ifdef LATER
-	    if (func != PCIIO_FUNC_NONE)
-		IOERROR_SETVALUE(ioe, widgetdev, 
-				 pciio_widgetdev_create(slot,func));
-	    else
-    		IOERROR_SETVALUE(ioe, widgetdev, 
-				 pciio_widgetdev_create(slot,0));
-#else
-            if (func != PCIIO_FUNC_NONE) {
-                IOERROR_SETVALUE(ioe, widgetdev,
-                                 pciio_widgetdev_create(slot,func));
-            } else {
-                IOERROR_SETVALUE(ioe, widgetdev,
-                                 pciio_widgetdev_create(slot,0));
-	    }
-#endif
-	}
-
-	IOERROR_SETVALUE(ioe, busspace, space);
-	IOERROR_SETVALUE(ioe, busaddr, offset);
-    }
-    if (mode == MODE_DEVPROBE) {
-	/*
-	 * During probing, we don't really care what the
-	 * error is. Clean up the error in Bridge, notify
-	 * subsidiary devices, and return success.
-	 */
-	pcibr_error_cleanup(pcibr_soft, error_code);
-
-	/* if appropriate, give the error handler for this slot
-	 * a shot at this probe access as well.
-	 */
-	return (slot == PCIIO_SLOT_NONE) ? IOERROR_HANDLED :
-	    pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
-    }
-    /*
-     * If we don't know what "PCI SPACE" the access
-     * was targeting, we may have problems at the
-     * Bridge itself. Don't touch any bridge registers,
-     * and do complain loudly.
-     */
-
-    if (space == PCIIO_SPACE_NONE) {
-	printk("XIO Bus Error at %s\n"
-		"\taccess to XIO bus offset 0x%lx\n"
-		"\tdoes not correspond to any PCI address\n",
-		pcibr_soft->bs_name, bad_xaddr);
-
-	/* caller will dump contents of ioe struct */
-	return IOERROR_XTALKLEVEL;
-    }
-    /*
-     * Read the PCI Bridge error log registers.
-     */
-    bridge_int_status = bridge->b_int_status;
-    bridge_pci_err_upper = bridge->b_pci_err_upper;
-    bridge_pci_err_lower = bridge->b_pci_err_lower;
-
-    bridge_pci_err_addr =
-	bridge_pci_err_lower
-	| (((iopaddr_t) bridge_pci_err_upper
-	    & BRIDGE_ERRUPPR_ADDRMASK) << 32);
-
-    /*
-     * Actual PCI Error handling situation.
-     * Typically happens when a user level process accesses
-     * PCI space, and it causes some error.
-     *
-     * Due to PCI Bridge implementation, we get two indication
-     * for a read error: an interrupt and a Bus error.
-     * We like to handle read error in the bus error context.
-     * But the interrupt comes and goes before bus error
-     * could make much progress. (NOTE: interrupd does
-     * come in _after_ bus error processing starts. But it's
-     * completed by the time bus error code reaches PCI PIO
-     * error handling.
-     * Similarly write error results in just an interrupt,
-     * and error handling has to be done at interrupt level.
-     * There is no way to distinguish at interrupt time, if an
-     * error interrupt is due to read/write error..
-     */
-
-    /* We know the xtalk addr, the raw PCI bus space,
-     * the raw PCI bus address, the decoded PCI bus
-     * space, the offset within that space, and the
-     * decoded PCI slot (which may be "PCIIO_SLOT_NONE" if no slot
-     * is known to be involved).
-     */
-
-    /*
-     * Hand the error off to the handler registered
-     * for the slot that should have decoded the error,
-     * or to generic PCI handling (if pciio decides that
-     * such is appropriate).
-     */
-    retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
-
-    if (retval != IOERROR_HANDLED) {
-
-	/* Generate a generic message for IOERROR_UNHANDLED
-	 * since the subsidiary handlers were silent, and
-	 * did no recovery.
-	 */
-	if (retval == IOERROR_UNHANDLED) {
-	    retval = IOERROR_PANIC;
-
-	    /* we may or may not want to print some of this,
-	     * depending on debug level and which error code.
-	     */
-
-	    PRINT_ALERT(
-		    "PIO Error on PCI Bus %s",
-		    pcibr_soft->bs_name);
-	    /* this decodes part of the ioe; our caller
-	     * will dump the raw details in DEBUG and
-	     * kdebug kernels.
-	     */
-	    BEM_ADD_IOE(ioe);
-	}
-#if defined(FORCE_ERRORS)
-	if (0) {
-#elif !DEBUG
-	if (kdebug) {
-#endif
-	    /*
-	       * dump raw data from bridge
-	     */
-
-	    BEM_ADD_STR("DEBUG DATA -- raw info from Bridge ASIC:\n");
-	    BEM_ADD_REG(bridge_int_status);
-	    BEM_ADD_VAR(bridge_pci_err_upper);
-	    BEM_ADD_VAR(bridge_pci_err_lower);
-	    BEM_ADD_VAR(bridge_pci_err_addr);
-	    BEM_ADD_SPC(raw_space);
-	    BEM_ADD_VAR(raw_paddr);
-	    if (IOERROR_FIELDVALID(ioe, widgetdev)) {
-
-#ifdef LATER
-		slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, 
-								 widgetdev));
-		func = pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, 
-								 widgetdev));
-#else
-		slot = -1;
-		func = -1;
-#endif
-		if (slot < 8) {
-#ifdef SUPPORT_SGI_CMN_ERR_STUFF
-		    bridgereg_t             device = bridge->b_device[slot].reg;
-#endif
-
-		    BEM_ADD_VAR(slot);
-		    BEM_ADD_VAR(func);
-		    BEM_ADD_REG(device);
-		}
-	    }
-#if !DEBUG || defined(FORCE_ERRORS)
-	}
-#endif
-
-	/*
-	 * Since error could not be handled at lower level,
-	 * error data logged has not  been cleared.
-	 * Clean up errors, and
-	 * re-enable bridge to interrupt on error conditions.
-	 * NOTE: Wheather we get the interrupt on PCI_ABORT or not is
-	 * dependent on INT_ENABLE register. This write just makes sure
-	 * that if the interrupt was enabled, we do get the interrupt.
-	 *
-	 * CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges
-	 *      a group of interrupts. If while handling this error,
-	 *      some other error has occurred, that would be
-	 *      implicitly cleared by this write.
-	 *      Need a way to ensure we don't inadvertently clear some
-	 *      other errors.
-	 */
-#ifdef LATER
-	if (IOERROR_FIELDVALID(ioe, widgetdev))
-	    pcibr_device_disable(pcibr_soft, 
-				 pciio_widgetdev_slot_get(
-					  IOERROR_GETVALUE(ioe, widgetdev)));
-#endif
-
-	if (mode == MODE_DEVUSERERROR)
-	    pcibr_error_cleanup(pcibr_soft, error_code);
-    }
-    return retval;
-}
-
-/*
- * bridge_dmaerror
- *      Some error was identified in a DMA transaction.
- *      This routine will identify the <device, address> that caused the error,
- *      and try to invoke the appropriate bus service to handle this.
- */
-
-#define BRIDGE_DMA_READ_ERROR (BRIDGE_ISR_RESP_XTLK_ERR|BRIDGE_ISR_XREAD_REQ_TIMEOUT)
-
-int
-pcibr_dmard_error(
-		     pcibr_soft_t pcibr_soft,
-		     int error_code,
-		     ioerror_mode_t mode,
-		     ioerror_t *ioe)
-{
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    bridgereg_t             bus_lowaddr, bus_uppraddr;
-    int                     retval = 0;
-    int                     bufnum;
-
-    /*
-     * In case of DMA errors, bridge should have logged the
-     * address that caused the error.
-     * Look up the address, in the bridge error registers, and
-     * take appropriate action
-     */
-#ifdef LATER
-    ASSERT(IOERROR_GETVALUE(ioe, widgetnum) == pcibr_soft->bs_xid);
-    ASSERT(bridge);
-#endif
-
-    /*
-     * read error log registers
-     */
-    bus_lowaddr = bridge->b_wid_resp_lower;
-    bus_uppraddr = bridge->b_wid_resp_upper;
-
-    bufnum = BRIDGE_RESP_ERRUPPR_BUFNUM(bus_uppraddr);
-    IOERROR_SETVALUE(ioe, widgetdev, 
-		     pciio_widgetdev_create(
-				    BRIDGE_RESP_ERRUPPR_DEVICE(bus_uppraddr),
-				    0));
-    IOERROR_SETVALUE(ioe, busaddr,
-		     (bus_lowaddr |
-		      ((iopaddr_t)
-		       (bus_uppraddr &
-			BRIDGE_ERRUPPR_ADDRMASK) << 32)));
-
-    /*
-     * need to ensure that the xtalk address in ioe
-     * maps to PCI error address read from bridge.
-     * How to convert PCI address back to Xtalk address ?
-     * (better idea: convert XTalk address to PCI address
-     * and then do the compare!)
-     */
-
-    retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
-    if (retval != IOERROR_HANDLED)
-#ifdef LATER
-	pcibr_device_disable(pcibr_soft, 
-			     pciio_widgetdev_slot_get(
-				      IOERROR_GETVALUE(ioe,widgetdev)));
-#else
-	pcibr_device_disable(pcibr_soft,
-			     pciio_widgetdev_slot_get(-1));
-#endif
-
-    /*
-     * Re-enable bridge to interrupt on BRIDGE_IRR_RESP_BUF_GRP_CLR
-     * NOTE: Wheather we get the interrupt on BRIDGE_IRR_RESP_BUF_GRP_CLR or
-     * not is dependent on INT_ENABLE register. This write just makes sure
-     * that if the interrupt was enabled, we do get the interrupt.
-     */
-    bridge->b_int_rst_stat = BRIDGE_IRR_RESP_BUF_GRP_CLR;
-
-    /*
-     * Also, release the "bufnum" back to buffer pool that could be re-used.
-     * This is done by "disabling" the buffer for a moment, then restoring
-     * the original assignment.
-     */
-
-    {
-	reg_p                   regp;
-	bridgereg_t             regv;
-	bridgereg_t             mask;
-
-	regp = (bufnum & 1)
-	    ? &bridge->b_odd_resp
-	    : &bridge->b_even_resp;
-
-	mask = 0xF << ((bufnum >> 1) * 4);
-
-	regv = *regp;
-	*regp = regv & ~mask;
-	*regp = regv;
-    }
-
-    return retval;
-}
-
-/*
- * pcibr_dmawr_error:
- *      Handle a dma write error caused by a device attached to this bridge.
- *
- *      ioe has the widgetnum, widgetdev, and memaddr fields updated
- *      But we don't know the PCI address that corresponds to "memaddr"
- *      nor do we know which device driver is generating this address.
- *
- *      There is no easy way to find out the PCI address(es) that map
- *      to a specific system memory address. Bus handling code is also
- *      of not much help, since they don't keep track of the DMA mapping
- *      that have been handed out.
- *      So it's a dead-end at this time.
- *
- *      If translation is available, we could invoke the error handling
- *      interface of the device driver.
- */
-/*ARGSUSED */
-int
-pcibr_dmawr_error(
-		     pcibr_soft_t pcibr_soft,
-		     int error_code,
-		     ioerror_mode_t mode,
-		     ioerror_t *ioe)
-{
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
-    int                     retval;
-
-    retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
-
-#ifdef LATER
-    if (retval != IOERROR_HANDLED) {
-	pcibr_device_disable(pcibr_soft, 
-			     pciio_widgetdev_slot_get(
-				      IOERROR_GETVALUE(ioe, widgetdev)));
-
-    }
-#endif
-    return retval;
-}
-
-/*
- * Bridge error handler.
- *      Interface to handle all errors that involve bridge in some way.
- *
- *      This normally gets called from xtalk error handler.
- *      ioe has different set of fields set depending on the error that
- *      was encountered. So, we have a bit field indicating which of the
- *      fields are valid.
- *
- * NOTE: This routine could be operating in interrupt context. So,
- *      don't try to sleep here (till interrupt threads work!!)
- */
-LOCAL int
-pcibr_error_handler(
-		       error_handler_arg_t einfo,
-		       int error_code,
-		       ioerror_mode_t mode,
-		       ioerror_t *ioe)
-{
-    pcibr_soft_t            pcibr_soft;
-    int                     retval = IOERROR_BADERRORCODE;
-
-    pcibr_soft = (pcibr_soft_t) einfo;
-
-    /* If we are in the action handling phase clean out the error state
-     * on the xswitch.
-     */
-#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-    if (e_state == ERROR_STATE_ACTION)
-	(void)error_state_set(xconn_vhdl, ERROR_STATE_NONE);
-#endif
-
-#if DEBUG && ERROR_DEBUG
-    printk("%s: pcibr_error_handler\n", pcibr_soft->bs_name);
-#endif
-
-    ASSERT(pcibr_soft != NULL);
-
-    if (error_code & IOECODE_PIO)
-	retval = pcibr_pioerror(pcibr_soft, error_code, mode, ioe);
-
-    if (error_code & IOECODE_DMA) {
-	if (error_code & IOECODE_READ) {
-	    /*
-	     * DMA read error occurs when a device attached to the bridge
-	     * tries to read some data from system memory, and this
-	     * either results in a timeout or access error.
-	     * First case is indicated by the bit "XREAD_REQ_TOUT"
-	     * and second case by "RESP_XTALK_ERROR" bit in bridge error
-	     * interrupt status register.
-	     *
-	     * pcibr_error_intr_handler would get invoked first, and it has
-	     * the responsibility of calling pcibr_error_handler with
-	     * suitable parameters.
-	     */
-
-	    retval = pcibr_dmard_error(pcibr_soft, error_code, MODE_DEVERROR, ioe);
-	}
-	if (error_code & IOECODE_WRITE) {
-	    /*
-	     * A device attached to this bridge has been generating
-	     * bad DMA writes. Find out the device attached, and
-	     * slap on it's wrist.
-	     */
-
-	    retval = pcibr_dmawr_error(pcibr_soft, error_code, MODE_DEVERROR, ioe);
-	}
-    }
-    return retval;
-
-}
-
-/*
- * Reenable a device after handling the error.
- * This is called by the lower layers when they wish to be reenabled
- * after an error.
- * Note that each layer would be calling the previous layer to reenable
- * first, before going ahead with their own re-enabling.
- */
-
-int
-pcibr_error_devenable(devfs_handle_t pconn_vhdl, int error_code)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    ASSERT(error_code & IOECODE_PIO);
-
-    /* If the error is not known to be a write,
-     * we have to call devenable.
-     * write errors are isolated to the bridge.
-     */
-    if (!(error_code & IOECODE_WRITE)) {
-	devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-	int                     rc;
-
-	rc = xtalk_error_devenable(xconn_vhdl, pciio_slot, error_code);
-	if (rc != IOERROR_HANDLED)
-	    return rc;
-    }
-    pcibr_error_cleanup(pcibr_soft, error_code);
-    return IOERROR_HANDLED;
-}
-
-/* =====================================================================
- *    CONFIGURATION MANAGEMENT
- */
-/*ARGSUSED */
-void
-pcibr_provider_startup(devfs_handle_t pcibr)
-{
-}
-
-/*ARGSUSED */
-void
-pcibr_provider_shutdown(devfs_handle_t pcibr)
-{
-}
-
-int
-pcibr_reset(devfs_handle_t conn)
-{
-    pciio_info_t            pciio_info = pciio_info_get(conn);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    bridgereg_t             ctlreg;
-    unsigned                cfgctl[8];
-    unsigned long           s;
-    int                     f, nf;
-    pcibr_info_h            pcibr_infoh;
-    pcibr_info_t            pcibr_info;
-    int                     win;
-
-    if (pcibr_soft->bs_slot[pciio_slot].has_host) {
-	pciio_slot = pcibr_soft->bs_slot[pciio_slot].host_slot;
-	pcibr_info = pcibr_soft->bs_slot[pciio_slot].bss_infos[0];
-    }
-    if (pciio_slot < 4) {
-	s = pcibr_lock(pcibr_soft);
-	nf = pcibr_soft->bs_slot[pciio_slot].bss_ninfo;
-	pcibr_infoh = pcibr_soft->bs_slot[pciio_slot].bss_infos;
-	for (f = 0; f < nf; ++f)
-	    if (pcibr_infoh[f])
-		cfgctl[f] = bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4];
-
-	ctlreg = bridge->b_wid_control;
-	bridge->b_wid_control = ctlreg | BRIDGE_CTRL_RST(pciio_slot);
-	/* XXX delay? */
-	bridge->b_wid_control = ctlreg;
-	/* XXX delay? */
-
-	for (f = 0; f < nf; ++f)
-	    if ((pcibr_info = pcibr_infoh[f]))
-		for (win = 0; win < 6; ++win)
-		    if (pcibr_info->f_window[win].w_base != 0)
-			bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_BASE_ADDR(win) / 4] =
-			    pcibr_info->f_window[win].w_base;
-	for (f = 0; f < nf; ++f)
-	    if (pcibr_infoh[f])
-		bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4] = cfgctl[f];
-	pcibr_unlock(pcibr_soft, s);
-
-	return 0;
-    }
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    PRINT_WARNING( "%v: pcibr_reset unimplemented for slot %d\n",
-	    conn, pciio_slot);
-#endif
-    return -1;
-}
-
-pciio_endian_t
-pcibr_endian_set(devfs_handle_t pconn_vhdl,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridgereg_t             devreg;
-    unsigned long           s;
-
-    /*
-     * Bridge supports hardware swapping; so we can always
-     * arrange for the caller's desired endianness.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-    if (device_end != desired_end)
-	devreg |= BRIDGE_DEV_SWAP_BITS;
-    else
-	devreg &= ~BRIDGE_DEV_SWAP_BITS;
-
-    /* NOTE- if we ever put SWAP bits
-     * onto the disabled list, we will
-     * have to change the logic here.
-     */
-    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	bridge->b_device[pciio_slot].reg = devreg;
-	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-#if DEBUG && PCIBR_DEV_DEBUG
-    printk("pcibr Device(%d): 0x%p\n", pciio_slot, bridge->b_device[pciio_slot].reg);
-#endif
-
-    return desired_end;
-}
-
-/* This (re)sets the GBR and REALTIME bits and also keeps track of how
- * many sets are outstanding. Reset succeeds only if the number of outstanding
- * sets == 1.
- */
-int
-pcibr_priority_bits_set(pcibr_soft_t pcibr_soft,
-			pciio_slot_t pciio_slot,
-			pciio_priority_t device_prio)
-{
-    unsigned long           s;
-    int                    *counter;
-    bridgereg_t             rtbits = 0;
-    bridgereg_t             devreg;
-    int                     rc = PRIO_SUCCESS;
-
-    /* in dual-slot configurations, the host and the
-     * guest have separate DMA resources, so they
-     * have separate requirements for priority bits.
-     */
-
-    counter = &(pcibr_soft->bs_slot[pciio_slot].bss_pri_uctr);
-
-    /*
-     * Bridge supports PCI notions of LOW and HIGH priority
-     * arbitration rings via a "REAL_TIME" bit in the per-device
-     * Bridge register. The "GBR" bit controls access to the GBR
-     * ring on the xbow. These two bits are (re)set together.
-     *
-     * XXX- Bug in Rev B Bridge Si:
-     * Symptom: Prefetcher starts operating incorrectly. This happens
-     * due to corruption of the address storage ram in the prefetcher
-     * when a non-real time PCI request is pulled and a real-time one is
-     * put in it's place. Workaround: Use only a single arbitration ring
-     * on PCI bus. GBR and RR can still be uniquely used per
-     * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C.
-     */
-
-    if (pcibr_soft->bs_rev_num != BRIDGE_PART_REV_B)
-	rtbits |= BRIDGE_DEV_RT;
-
-    /* NOTE- if we ever put DEV_RT or DEV_GBR on
-     * the disabled list, we will have to take
-     * it into account here.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-    if (device_prio == PCI_PRIO_HIGH) {
-	if ((++*counter == 1)) {
-	    if (rtbits)
-		devreg |= rtbits;
-	    else
-		rc = PRIO_FAIL;
-	}
-    } else if (device_prio == PCI_PRIO_LOW) {
-	if (*counter <= 0)
-	    rc = PRIO_FAIL;
-	else if (--*counter == 0)
-	    if (rtbits)
-		devreg &= ~rtbits;
-    }
-    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	bridge->b_device[pciio_slot].reg = devreg;
-	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-    return rc;
-}
-
-pciio_priority_t
-pcibr_priority_set(devfs_handle_t pconn_vhdl,
-		   pciio_priority_t device_prio)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    (void) pcibr_priority_bits_set(pcibr_soft, pciio_slot, device_prio);
-
-    return device_prio;
-}
-
-/*
- * Interfaces to allow special (e.g. SGI) drivers to set/clear
- * Bridge-specific device flags.  Many flags are modified through
- * PCI-generic interfaces; we don't allow them to be directly
- * manipulated here.  Only flags that at this point seem pretty
- * Bridge-specific can be set through these special interfaces.
- * We may add more flags as the need arises, or remove flags and
- * create PCI-generic interfaces as the need arises.
- *
- * Returns 0 on failure, 1 on success
- */
-int
-pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
-		       pcibr_device_flags_t flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridgereg_t             set = 0;
-    bridgereg_t             clr = 0;
-
-    ASSERT((flags & PCIBR_DEVICE_FLAGS) == flags);
-
-    if (flags & PCIBR_WRITE_GATHER)
-	set |= BRIDGE_DEV_PMU_WRGA_EN;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	clr |= BRIDGE_DEV_PMU_WRGA_EN;
-
-    if (flags & PCIBR_WRITE_GATHER)
-	set |= BRIDGE_DEV_DIR_WRGA_EN;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	clr |= BRIDGE_DEV_DIR_WRGA_EN;
-
-    if (flags & PCIBR_PREFETCH)
-	set |= BRIDGE_DEV_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	clr |= BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	set |= BRIDGE_DEV_PRECISE;
-    if (flags & PCIBR_NOPRECISE)
-	clr |= BRIDGE_DEV_PRECISE;
-
-    if (flags & PCIBR_BARRIER)
-	set |= BRIDGE_DEV_BARRIER;
-    if (flags & PCIBR_NOBARRIER)
-	clr |= BRIDGE_DEV_BARRIER;
-
-    if (flags & PCIBR_64BIT)
-	set |= BRIDGE_DEV_DEV_SIZE;
-    if (flags & PCIBR_NO64BIT)
-	clr |= BRIDGE_DEV_DEV_SIZE;
-
-    if (set || clr) {
-	bridgereg_t             devreg;
-	unsigned long           s;
-
-	s = pcibr_lock(pcibr_soft);
-	devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-	devreg = (devreg & ~clr) | set;
-	if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	    bridge_t               *bridge = pcibr_soft->bs_base;
-
-	    bridge->b_device[pciio_slot].reg = devreg;
-	    pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	}
-	pcibr_unlock(pcibr_soft, s);
-#if DEBUG && PCIBR_DEV_DEBUG
-	printk("pcibr Device(%d): %R\n", pciio_slot, bridge->b_device[pciio_slot].regbridge->b_device[pciio_slot].reg, device_bits);
-#endif
-    }
-    return (1);
-}
-
-#ifdef LITTLE_ENDIAN
-/*
- * on sn-ia we need to twiddle the addresses going out
- * the pci bus because we use the unswizzled synergy space
- * (the alternative is to use the swizzled synergy space
- * and byte swap the data)
- */
-#define	CB(b,r)	(((volatile uint8_t *) b)[((r)^4)])
-#define	CS(b,r)	(((volatile uint16_t *) b)[((r^4)/2)])
-#define	CW(b,r)	(((volatile uint32_t *) b)[((r^4)/4)])
-#else
-#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
-#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
-#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
-#endif /* LITTLE_ENDIAN */
-
-
-LOCAL                   cfg_p
-pcibr_config_addr(devfs_handle_t conn,
-		  unsigned reg)
-{
-    pcibr_info_t            pcibr_info;
-    pciio_slot_t            pciio_slot;
-    pciio_function_t        pciio_func;
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge;
-    cfg_p                   cfgbase = (cfg_p)0;
-
-    pcibr_info = pcibr_info_get(conn);
-
-    pciio_slot = pcibr_info->f_slot;
-    if (pciio_slot == PCIIO_SLOT_NONE)
-	pciio_slot = PCI_TYPE1_SLOT(reg);
-
-    pciio_func = pcibr_info->f_func;
-    if (pciio_func == PCIIO_FUNC_NONE)
-	pciio_func = PCI_TYPE1_FUNC(reg);
-
-    pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-
-    bridge = pcibr_soft->bs_base;
-
-    cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l;
-
-    return cfgbase;
-}
-
-uint64_t
-pcibr_config_get(devfs_handle_t conn,
-		 unsigned reg,
-		 unsigned size)
-{
-    return do_pcibr_config_get(pcibr_config_addr(conn, reg),
-			       PCI_TYPE1_REG(reg), size);
-}
-
-LOCAL uint64_t
-do_pcibr_config_get(
-		       cfg_p cfgbase,
-		       unsigned reg,
-		       unsigned size)
-{
-    unsigned                value;
-
-   
-    value = CW(cfgbase, reg);
-
-    if (reg & 3)
-	value >>= 8 * (reg & 3);
-    if (size < 4)
-	value &= (1 << (8 * size)) - 1;
-
-    return value;
-}
-
-void
-pcibr_config_set(devfs_handle_t conn,
-		 unsigned reg,
-		 unsigned size,
-		 uint64_t value)
-{
-    do_pcibr_config_set(pcibr_config_addr(conn, reg),
-			PCI_TYPE1_REG(reg), size, value);
-}
-
-LOCAL void
-do_pcibr_config_set(cfg_p cfgbase,
-		    unsigned reg,
-		    unsigned size,
-		    uint64_t value)
-{
-    switch (size) {
-    case 1:
-	CB(cfgbase, reg) = value;
-	break;
-    case 2:
-	if (reg & 1) {
-	    CB(cfgbase, reg) = value;
-	    CB(cfgbase, reg + 1) = value >> 8;
-	} else
-	    CS(cfgbase, reg) = value;
-	break;
-    case 3:
-	if (reg & 1) {
-	    CB(cfgbase, reg) = value;
-	    CS(cfgbase, (reg + 1)) = value >> 8;
-	} else {
-	    CS(cfgbase, reg) = value;
-	    CB(cfgbase, reg + 2) = value >> 16;
-	}
-	break;
-
-    case 4:
-	CW(cfgbase, reg) = value;
-	break;
-    }
-}
-
-pciio_provider_t        pcibr_provider =
-{
-    (pciio_piomap_alloc_f *) pcibr_piomap_alloc,
-    (pciio_piomap_free_f *) pcibr_piomap_free,
-    (pciio_piomap_addr_f *) pcibr_piomap_addr,
-    (pciio_piomap_done_f *) pcibr_piomap_done,
-    (pciio_piotrans_addr_f *) pcibr_piotrans_addr,
-    (pciio_piospace_alloc_f *) pcibr_piospace_alloc,
-    (pciio_piospace_free_f *) pcibr_piospace_free,
-
-    (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
-    (pciio_dmamap_free_f *) pcibr_dmamap_free,
-    (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
-    (pciio_dmamap_done_f *) pcibr_dmamap_done,
-    (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
-    (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
-    (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
-    (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
-
-    (pciio_intr_alloc_f *) pcibr_intr_alloc,
-    (pciio_intr_free_f *) pcibr_intr_free,
-    (pciio_intr_connect_f *) pcibr_intr_connect,
-    (pciio_intr_disconnect_f *) pcibr_intr_disconnect,
-    (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get,
-
-    (pciio_provider_startup_f *) pcibr_provider_startup,
-    (pciio_provider_shutdown_f *) pcibr_provider_shutdown,
-    (pciio_reset_f *) pcibr_reset,
-    (pciio_write_gather_flush_f *) pcibr_write_gather_flush,
-    (pciio_endian_set_f *) pcibr_endian_set,
-    (pciio_priority_set_f *) pcibr_priority_set,
-    (pciio_config_get_f *) pcibr_config_get,
-    (pciio_config_set_f *) pcibr_config_set,
-
-    (pciio_error_devenable_f *) pcibr_error_devenable,
-    (pciio_error_extract_f *) pcibr_error_extract,
-
-#ifdef LATER
-    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
-    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
-#else
-    (pciio_driver_reg_callback_f *) 0,
-    (pciio_driver_unreg_callback_f *) 0,
-#endif
-    (pciio_device_unregister_f 	*) pcibr_device_unregister,
-    (pciio_dma_enabled_f		*) pcibr_dma_enabled,
-};
-
-LOCAL                   pcibr_hints_t
-pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
-{
-    arbitrary_info_t        ainfo = 0;
-    graph_error_t	    rv;
-    pcibr_hints_t           hint;
-
-    rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
-
-    if (alloc && (rv != GRAPH_SUCCESS)) {
-
-	NEW(hint);
-	hint->rrb_alloc_funct = NULL;
-	hint->ph_intr_bits = NULL;
-	rv = hwgraph_info_add_LBL(xconn_vhdl, 
-				  INFO_LBL_PCIBR_HINTS, 	
-				  (arbitrary_info_t) hint);
-	if (rv != GRAPH_SUCCESS)
-	    goto abnormal_exit;
-
-	rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
-	
-	if (rv != GRAPH_SUCCESS)
-	    goto abnormal_exit;
-
-	if (ainfo != (arbitrary_info_t) hint)
-	    goto abnormal_exit;
-    }
-    return (pcibr_hints_t) ainfo;
-
-abnormal_exit:
-#ifdef LATER
-    printf("SHOULD NOT BE HERE\n");
-#endif
-    DEL(hint);
-    return(NULL);
-
-}
-
-void
-pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_rrb_fixed = mask;
-#if DEBUG
-    else
-	printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
-{
-    pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
-}
-
-void
-pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
-		     pciio_slot_t host,
-		     pciio_slot_t guest)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_host_slot[guest] = host + 1;
-#if DEBUG
-    else
-	printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
-		      pcibr_intr_bits_f *xxx_intr_bits)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_intr_bits = xxx_intr_bits;
-#if DEBUG
-    else
-	printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n"
-	       "\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->rrb_alloc_funct = rrb_alloc_funct;
-}
-
-void
-pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_hands_off = 1;
-#if DEBUG
-    else
-	printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
-		    pciio_slot_t slot,
-		    uint64_t subdevs)
-{
-    arbitrary_info_t        ainfo = 0;
-    char                    sdname[16];
-    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
-
-    sprintf(sdname, "pci/%d", slot);
-    (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
-    if (pconn_vhdl == GRAPH_VERTEX_NONE) {
-#if DEBUG
-	printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n"
-		"\t%p (seeking %s)\n", xconn_vhdl, sdname);
-#endif
-	return;
-    }
-    hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
-    if (ainfo == 0) {
-	uint64_t                *subdevp;
-
-	NEW(subdevp);
-	if (!subdevp) {
-#if DEBUG
-	    printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n"
-		    "\t%p\n", pconn_vhdl);
-#endif
-	    return;
-	}
-	*subdevp = subdevs;
-	hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
-	hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
-	if (ainfo == (arbitrary_info_t) subdevp)
-	    return;
-	DEL(subdevp);
-	if (ainfo == (arbitrary_info_t) NULL) {
-#if DEBUG
-	    printk("pcibr_hints_subdevs: null subdevs ptr at\n"
-		    "\t%p\n", pconn_vhdl);
-#endif
-	    return;
-	}
-#if DEBUG
-	printk("pcibr_subdevs_get: dup subdev add_LBL at\n"
-		"\t%p\n", pconn_vhdl);
-#endif
-    }
-    *(uint64_t *) ainfo = subdevs;
-}
-
-
-#ifdef LATER
-
-#include <sys/idbg.h>
-#include <sys/idbgentry.h>
-
-char *pci_space[] = {"NONE", 
-		     "ROM",
-		     "IO",
-		     "",
-		     "MEM",
-		     "MEM32",
-		     "MEM64",
-		     "CFG",
-		     "WIN0",
-		     "WIN1",
-		     "WIN2",
-		     "WIN3",
-		     "WIN4",
-		     "WIN5",
-		     "",
-		     "BAD"};
-
-void
-idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
-{
-    pcibr_info_t	pcibr_info = pcibr_infoh[func];
-    char		name[MAXDEVNAME];
-    int			win;
-    
-    if (!pcibr_info)
-	return;
-    qprintf("Per-slot Function Info\n");
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_vertex);
-#endif
-    qprintf("\tSlot Name : %s\n",name);
-    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
-    qprintf("Slot : %d ", pcibr_info->f_slot);
-    qprintf("Function : %d ", pcibr_info->f_func);
-    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
-    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_master);
-#endif
-    qprintf("\tBus provider : %s\n",name);
-    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
-    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
-	    pcibr_info->f_efunc,pcibr_info->f_einfo);
-    for(win = 0 ; win < 6 ; win++) 
-	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
-		win,pci_space[pcibr_info->f_window[win].w_space],
-		pcibr_info->f_window[win].w_base,
-		pcibr_info->f_window[win].w_size);
-
-    qprintf("\tRom base 0x%x size 0x%x\n", 
-	    pcibr_info->f_rbase,pcibr_info->f_rsize);
-
-    qprintf("\tInterrupt Bit Map\n");
-    qprintf("\t\tPCI Int#\tBridge Pin#\n");
-    for (win = 0 ; win < 4; win++)
-	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
-    qprintf("\n");
-}
-
-
-void
-idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
-{
-    pcibr_soft_slot_t	pss;
-    char		slot_conn_name[MAXDEVNAME];
-    int			func;
-
-    pss = &pcibr_soft->bs_slot[slot];
-    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
-    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
-    qprintf("\tHost Slot : %d\n",pss->host_slot);
-    sprintf(slot_conn_name, "%v", pss->slot_conn);
-    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
-    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
-    for (func = 0; func < pss->bss_ninfo; func++)
-	idbg_pss_func(pss->bss_infos,func);
-    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
-    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
-    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
-    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
-	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
-    
-    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
-	    "d32_base 0x%x d32_flags 0x%x\n",
-	    pss->bss_d64_base, pss->bss_d64_flags,
-	    pss->bss_d32_base, pss->bss_d32_flags);
-    
-    qprintf("\tExt ATEs active ? %s", 
-	    atomic_read(&pss->bss_ext_ates_active) ? "yes" : "no");
-    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
-    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
-
-    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
-	    pcibr_soft->bs_rrb_valid[slot],
-	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-		
-}
-
-int	ips = 0;
-
-void
-idbg_pss(pcibr_soft_t pcibr_soft)
-{
-    pciio_slot_t	slot;
-
-    
-    if (ips >= 0 && ips < 8)
-	idbg_pss_info(pcibr_soft,ips);
-    else if (ips < 0)
-	for (slot = 0; slot < 8; slot++) 
-	    idbg_pss_info(pcibr_soft,slot);
-    else
-	qprintf("Invalid ips %d\n",ips);
-}
-
-#endif /* LATER */
-
-int
-pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-	
-
-    return xtalk_dma_enabled(pcibr_soft->bs_conn);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/pciio.c linux/arch/ia64/sn/io/pciio.c
--- linux.orig/arch/ia64/sn/io/pciio.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/pciio.c	2002-07-20 01:08:36.000000000 +0000
@@ -4,14 +4,18 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 #define	USRPCI	0
 
+#include <linux/init.h>
 #include <linux/types.h>
 #include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/xtalk/xbow.h>	/* Must be before iograph.h to get MAX_PORT_NUM */
@@ -25,13 +29,16 @@
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/pci/pciio_private.h>
 #include <asm/sn/sn_sal.h>
+#include <asm/sn/io.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
+#include <asm/sn/simulator.h>
 
 #define DEBUG_PCIIO
 #undef DEBUG_PCIIO	/* turn this on for yet more console output */
 
 
-#define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DEL(ptr)	(kfree(ptr))
+#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
+#define DO_DEL(ptr)	(kfree(ptr))
 
 char                    pciio_info_fingerprint[] = "pciio_info";
 
@@ -45,7 +52,11 @@
 
 	switch (len) {
 		case 4:
+#ifdef CONFIG_IA64_SGI_SN1
 			new_addr = (void *)(((u64) addr)^4);
+#else
+			new_addr = (void *) addr;
+#endif
 			ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr);
 			break;
 		default:
@@ -63,6 +74,14 @@
 get_console_nasid(void)
 {
 	extern nasid_t console_nasid;
+	if (console_nasid < 0) {
+		console_nasid = ia64_sn_get_console_nasid();
+		if (console_nasid < 0) {
+// ZZZ What do we do if we don't get a console nasid on the hardware????
+			if (IS_RUNNING_ON_SIMULATOR() )
+				console_nasid = master_nasid;
+		}
+	} 
 	return console_nasid;
 }
 
@@ -105,7 +124,7 @@
  * completely disappear.
  */
 
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
+#if defined(CONFIG_IA64_SGI_SN1)
 /*
  *    For the moment, we will assume that IP27
  *      only use Bridge ASICs to provide PCI support.
@@ -115,7 +134,7 @@
 #define CAST_PIOMAP(x)		((pcibr_piomap_t)(x))
 #define CAST_DMAMAP(x)		((pcibr_dmamap_t)(x))
 #define CAST_INTR(x)		((pcibr_intr_t)(x))
-#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
+#endif /* CONFIG_IA64_SGI_SN1 */
 
 /* =====================================================================
  *    Function Table of Contents
@@ -150,14 +169,11 @@
 
 pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
 void                    pciio_intr_free(pciio_intr_t);
-int                     pciio_intr_connect(pciio_intr_t, intr_func_t, intr_arg_t, void *thread);
+int                     pciio_intr_connect(pciio_intr_t);
 void                    pciio_intr_disconnect(pciio_intr_t);
 devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
 
 void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
-static pciio_info_t     pciio_cardinfo_get(devfs_handle_t, pciio_slot_t);
-int                     pciio_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     pciio_error_devenable(devfs_handle_t, int);
 
 void                    pciio_provider_startup(devfs_handle_t);
 void                    pciio_provider_shutdown(devfs_handle_t);
@@ -257,7 +273,7 @@
 #if defined(SUPPORT_PRINTING_V_FORMAT)
 	PRINT_PANIC("%v: provider_fns == NULL", dev);
 #else
-	PRINT_PANIC("0x%x: provider_fns == NULL", dev);
+	PRINT_PANIC("0x%p: provider_fns == NULL", (void *)dev);
 #endif
 
     return provider_fns;
@@ -575,13 +591,10 @@
  * Returns 0 on success, returns <0 on failure.
  */
 int
-pciio_intr_connect(pciio_intr_t intr_hdl,	/* pciio intr resource handle */
-		   intr_func_t intr_func,	/* pciio intr handler */
-		   intr_arg_t intr_arg,	/* arg to intr handler */
-		   void *thread)
-{					/* intr thread to use */
+pciio_intr_connect(pciio_intr_t intr_hdl)	/* pciio intr resource handle */
+{
     return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl), intr_func, intr_arg, thread);
+	(CAST_INTR(intr_hdl));
 }
 
 /*
@@ -605,10 +618,6 @@
 	(CAST_INTR(intr_hdl));
 }
 
-/* =====================================================================
- *          ERROR MANAGEMENT
- */
-
 void
 pciio_slot_func_to_name(char		       *name,
 			pciio_slot_t		slot,
@@ -630,193 +639,6 @@
 	sprintf(name, "%d%c", slot, 'a'+func);
 }
 
-/*
- * pciio_cardinfo_get
- *
- * Get the pciio info structure corresponding to the
- * specified PCI "slot" (we like it when the same index
- * number is used for the PCI IDSEL, the REQ/GNT pair,
- * and the interrupt line being used for INTA. We like
- * it so much we call it the slot number).
- */
-static pciio_info_t
-pciio_cardinfo_get(
-		      devfs_handle_t pciio_vhdl,
-		      pciio_slot_t pci_slot)
-{
-    char                    namebuf[16];
-    pciio_info_t	    info = 0;
-    devfs_handle_t	    conn;
-
-    pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE);
-    if (GRAPH_SUCCESS ==
-	hwgraph_traverse(pciio_vhdl, namebuf, &conn)) {
-	info = pciio_info_chk(conn);
-	hwgraph_vertex_unref(conn);
-    }
-
-    return info;
-}
-
-/*
- * pciio_error_handler:
- * dispatch an error to the appropriate
- * pciio connection point, or process
- * it as a generic pci error.
- * Yes, the first parameter is the
- * provider vertex at the middle of
- * the bus; we get to the pciio connect
- * point using the ioerror widgetdev field.
- *
- * This function is called by the
- * specific PCI provider, after it has figured
- * out where on the PCI bus (including which slot,
- * if it can tell) the error came from.
- */
-/*ARGSUSED */
-int
-pciio_error_handler(
-		       devfs_handle_t pciio_vhdl,
-		       int error_code,
-		       ioerror_mode_t mode,
-		       ioerror_t *ioerror)
-{
-    pciio_info_t            pciio_info;
-    devfs_handle_t            pconn_vhdl;
-#if USRPCI
-    devfs_handle_t            usrpci_v;
-#endif
-    pciio_slot_t            slot;
-
-    int                     retval;
-#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-    error_state_t	    e_state;
-#endif
-
-#if DEBUG && ERROR_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk("%v: pciio_error_handler\n", pciio_vhdl);
-#else
-    printk("0x%x: pciio_error_handler\n", pciio_vhdl);
-#endif
-#endif
-
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    IOERR_PRINTF(printk("%v: PCI Bus Error: Error code: %d Error mode: %d\n",
-			 pciio_vhdl, error_code, mode));
-#else
-    IOERR_PRINTF(printk("0x%x: PCI Bus Error: Error code: %d Error mode: %d\n",
-			 pciio_vhdl, error_code, mode));
-#endif
-
-    /* If there is an error handler sitting on
-     * the "no-slot" connection point, give it
-     * first crack at the error. NOTE: it is
-     * quite possible that this function may
-     * do further refining of the ioerror.
-     */
-    pciio_info = pciio_cardinfo_get(pciio_vhdl, PCIIO_SLOT_NONE);
-    if (pciio_info && pciio_info->c_efunc) {
-	pconn_vhdl = pciio_info_dev_get(pciio_info);
-#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-	e_state = error_state_get(pciio_vhdl);
-
-	if (e_state == ERROR_STATE_ACTION)
-	    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
-
-	if (error_state_set(pconn_vhdl,e_state) ==
-	    ERROR_RETURN_CODE_CANNOT_SET_STATE)
-	    return(IOERROR_UNHANDLED);
-#endif
-	retval = pciio_info->c_efunc
-	    (pciio_info->c_einfo, error_code, mode, ioerror);
-	if (retval != IOERROR_UNHANDLED)
-	    return retval;
-    }
-
-    /* Is the error associated with a particular slot?
-     */
-    if (IOERROR_FIELDVALID(ioerror, widgetdev)) {
-	/*
-	 * NOTE : 
-	 * widgetdev is a 4byte value encoded as slot in the higher order
-	 * 2 bytes and function in the lower order 2 bytes.
-	 */
-#ifdef LATER
-	slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioerror, widgetdev));
-#else
-	slot = 0;
-#endif
-
-	/* If this slot has an error handler,
-	 * deliver the error to it.
-	 */
-	pciio_info = pciio_cardinfo_get(pciio_vhdl, slot);
-	if (pciio_info != NULL) {
-	    if (pciio_info->c_efunc != NULL) {
-
-		pconn_vhdl = pciio_info_dev_get(pciio_info);
-#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-		e_state = error_state_get(pciio_vhdl);
-
-
-		if (e_state == ERROR_STATE_ACTION)
-		    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
-
-
-
-		if (error_state_set(pconn_vhdl,e_state) ==
-		    ERROR_RETURN_CODE_CANNOT_SET_STATE)
-		    return(IOERROR_UNHANDLED);
-#endif
-		retval = pciio_info->c_efunc
-		    (pciio_info->c_einfo, error_code, mode, ioerror);
-		if (retval != IOERROR_UNHANDLED)
-		    return retval;
-	    }
-
-#if USRPCI
-	    /* If the USRPCI driver is available and
-	     * knows about this connection point,
-	     * deliver the error to it.
-	     *
-	     * OK to use pconn_vhdl here, even though we
-	     * have already UNREF'd it, since we know that
-	     * it is not going away.
-	     */
-	    pconn_vhdl = pciio_info_dev_get(pciio_info);
-	    if (GRAPH_SUCCESS ==
-		hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) {
-		retval = usrpci_error_handler
-		    (usrpci_v, error_code, IOERROR_GETVALUE(ioerror, busaddr));
-		hwgraph_vertex_unref(usrpci_v);
-		if (retval != IOERROR_UNHANDLED) {
-		    /*
-		     * This unref is not needed.  If this code is called often enough,
-		     * the system will crash, due to vertex reference count reaching 0,
-		     * causing vertex to be unallocated.  -jeremy
-		     * hwgraph_vertex_unref(pconn_vhdl);
-		     */
-		    return retval;
-		}
-	    }
-#endif
-	}
-    }
-
-    return (mode == MODE_DEVPROBE)
-	? IOERROR_HANDLED	/* probes are OK */
-	: IOERROR_UNHANDLED;	/* otherwise, foo! */
-}
-
-int
-pciio_error_devenable(devfs_handle_t pconn_vhdl, int error_code)
-{
-    return DEV_FUNC(pconn_vhdl, error_devenable)
-	(pconn_vhdl, error_code);
-    /* no cleanup specific to this layer. */
-}
-
 /* =====================================================================
  *          CONFIGURATION MANAGEMENT
  */
@@ -856,12 +678,12 @@
 
 #if DEBUG
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-    PRINT_ALERT("%v: pciio_endian_set is going away.\n"
+    printk(KERN_ALERT  "%v: pciio_endian_set is going away.\n"
 	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
 	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
 	    dev);
 #else
-    PRINT_ALERT("0x%x: pciio_endian_set is going away.\n"
+    printk(KERN_ALERT  "0x%x: pciio_endian_set is going away.\n"
 	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
 	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
 	    dev);
@@ -944,14 +766,6 @@
 /* =====================================================================
  *          GENERIC PCI SUPPORT FUNCTIONS
  */
-pciio_slot_t
-pciio_error_extract(devfs_handle_t 	dev,
-		   pciio_space_t 	*space,
-		   iopaddr_t		*offset)
-{
-	ASSERT(dev != NODEV);
-	return DEV_FUNC(dev,error_extract)(dev,space,offset);
-}
 
 /*
  * Issue a hardware reset to a card.
@@ -1054,14 +868,9 @@
     }
 #endif /* DEBUG_PCIIO */
 
-#ifdef BRINGUP
     if ((pciio_info != NULL) &&
 	(pciio_info->c_fingerprint != pciio_info_fingerprint)
 	&& (pciio_info->c_fingerprint != NULL)) {
-#else
-    if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)) {
-#endif /* BRINGUP */
 
 	return((pciio_info_t)-1); /* Should panic .. */
     }
@@ -1388,7 +1197,7 @@
 		pciio_device_id_t device_id)
 {
     if (!pciio_info)
-	NEW(pciio_info);
+	GET_NEW(pciio_info);
     ASSERT(pciio_info != NULL);
 
     pciio_info->c_slot = slot;
@@ -1420,6 +1229,7 @@
 {
     char		name[32];
     devfs_handle_t	pconn;
+    int device_master_set(devfs_handle_t, devfs_handle_t);
 
     pciio_slot_func_to_name(name,
 			    pciio_info->c_slot,
@@ -1431,16 +1241,14 @@
 
     pciio_info->c_vertex = pconn;
     pciio_info_set(pconn, pciio_info);
-#ifdef BRINGUP
+#ifdef DEBUG_PCIIO
     {
 	int pos;
 	char dname[256];
 	pos = devfs_generate_path(pconn, dname, 256);
-#ifdef DEBUG_PCIIO
 	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
-#endif
     }
-#endif /* BRINGUP */
+#endif /* DEBUG_PCIIO */
 
     /*
      * create link to our pci provider
@@ -1520,7 +1328,6 @@
     pciio_info_t            pciio_info;
     pciio_vendor_id_t       vendor_id;
     pciio_device_id_t       device_id;
-    int pciba_attach(devfs_handle_t);
 
 
     pciio_device_inventory_add(pconn);
@@ -1536,11 +1343,6 @@
      */
     ASSERT(pciio_registry != NULL);
 
-    /*
-     * Since pciba is not called from cdl routines .. call it here.
-     */
-    pciba_attach(pconn);
-
     return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
 }
 
@@ -1625,3 +1427,85 @@
 {
 	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
 }
+
+/*
+ * These are complementary Linux interfaces that takes in a pci_dev * as the 
+ * first arguement instead of devfs_handle_t.
+ */
+iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
+pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
+void                    snia_pciio_dmamap_free(pciio_dmamap_t);
+iopaddr_t               snia_pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
+void                    snia_pciio_dmamap_done(pciio_dmamap_t);
+pciio_endian_t          snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end,
+					      pciio_endian_t desired_end);
+
+#include <linux/module.h>
+EXPORT_SYMBOL(snia_pciio_dmatrans_addr);
+EXPORT_SYMBOL(snia_pciio_dmamap_alloc);
+EXPORT_SYMBOL(snia_pciio_dmamap_free);
+EXPORT_SYMBOL(snia_pciio_dmamap_addr);
+EXPORT_SYMBOL(snia_pciio_dmamap_done);
+EXPORT_SYMBOL(snia_pciio_endian_set);
+
+pciio_endian_t
+snia_pciio_endian_set(struct pci_dev *pci_dev,
+	pciio_endian_t device_end,
+	pciio_endian_t desired_end)
+{
+	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+	
+	return DEV_FUNC(dev, endian_set)
+		(dev, device_end, desired_end);
+}
+
+iopaddr_t
+snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device */
+                    device_desc_t dev_desc,     /* device descriptor */
+                    paddr_t paddr,      /* system physical address */
+                    size_t byte_count,  /* length */
+                    unsigned flags)
+{                                       /* defined in dma.h */
+
+    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+
+    return DEV_FUNC(dev, dmatrans_addr)
+        (dev, dev_desc, paddr, byte_count, flags);
+}
+
+pciio_dmamap_t
+snia_pciio_dmamap_alloc(struct pci_dev *pci_dev,  /* set up mappings for this device */
+                   device_desc_t dev_desc,      /* device descriptor */
+                   size_t byte_count_max,       /* max size of a mapping */
+                   unsigned flags)
+{                                       /* defined in dma.h */
+
+    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+
+    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
+        (dev, dev_desc, byte_count_max, flags);
+}
+
+void
+snia_pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
+{
+    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
+        (CAST_DMAMAP(pciio_dmamap));
+}
+
+iopaddr_t
+snia_pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,  /* use these mapping resources */
+                  paddr_t paddr,        /* map for this address */
+                  size_t byte_count)
+{                                       /* map this many bytes */
+    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
+        (CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
+}
+
+void
+snia_pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
+{
+    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
+        (CAST_DMAMAP(pciio_dmamap));
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sgi_if.c linux/arch/ia64/sn/io/sgi_if.c
--- linux.orig/arch/ia64/sn/io/sgi_if.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/sgi_if.c	2002-07-20 01:08:36.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -22,7 +21,7 @@
 #include <asm/sn/slotnum.h>
 
 void *
-kmem_zalloc(size_t size, int flag)
+snia_kmem_zalloc(size_t size, int flag)
 {
         void *ptr = kmalloc(size, GFP_KERNEL);
         BZERO(ptr, size);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sgi_io_init.c linux/arch/ia64/sn/io/sgi_io_init.c
--- linux.orig/arch/ia64/sn/io/sgi_io_init.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/sgi_io_init.c	2002-07-20 01:08:21.000000000 +0000
@@ -4,26 +4,24 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/agent.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/sn_private.h>
-#include <asm/sn/synergy.h>
+#include <asm/sn/pci/pciba.h>
 #include <linux/smp.h>
 
 extern void mlreset(int );
 extern int init_hcl(void);
 extern void klgraph_hack_init(void);
-extern void per_hub_init(cnodeid_t);
 extern void hubspc_init(void);
-extern void pciba_init(void);
 extern void pciio_init(void);
 extern void pcibr_init(void);
 extern void xtalk_init(void);
@@ -33,23 +31,21 @@
 extern void usrpci_init(void);
 extern void ioc3_init(void);
 extern void initialize_io(void);
-extern void init_platform_nodepda(nodepda_t *, cnodeid_t );
+#if defined(CONFIG_IA64_SGI_SN1)
 extern void intr_clear_all(nasid_t);
+#endif
 extern void klhwg_add_all_modules(devfs_handle_t);
 extern void klhwg_add_all_nodes(devfs_handle_t);
 
 void sn_mp_setup(void);
 extern devfs_handle_t hwgraph_root;
 extern void io_module_init(void);
-extern cnodeid_t nasid_to_compact_node[];
 extern void pci_bus_cvlink_init(void);
 extern void temp_hack(void);
-extern void init_platform_pda(cpuid_t cpu);
 
 extern int pci_bus_to_hcl_cvlink(void);
-extern synergy_da_t	*Synergy_da_indr[];
 
-#define DEBUG_IO_INIT
+/* #define DEBUG_IO_INIT 1 */
 #ifdef DEBUG_IO_INIT
 #define DBG(x...) printk(x)
 #else
@@ -57,20 +53,73 @@
 #endif /* DEBUG_IO_INIT */
 
 /*
- * kern/ml/csu.s calls mlsetup
- *   mlsetup calls mlreset(master) - kern/os/startup.c
- *   j main
- *
- 
- * SN/slave.s start_slave_loop calls slave_entry
- * SN/slave.s slave_entry calls slave_loop
- * SN/slave.s slave_loop calls bootstrap
- * bootstrap in SN1/SN1asm.s calls cboot
- * cboot calls mlreset(slave) - ml/SN/mp.c
+ * per_hub_init
  *
- * sgi_io_infrastructure_init() gets called right before pci_init() 
- * in Linux mainline.  This routine actually mirrors the IO Infrastructure 
- * call sequence in IRIX, ofcourse, nicely modified for Linux.
+ * 	This code is executed once for each Hub chip.
+ */
+static void
+per_hub_init(cnodeid_t cnode)
+{
+	nasid_t		nasid;
+	nodepda_t	*npdap;
+	ii_icmr_u_t	ii_icmr;
+	ii_ibcr_u_t	ii_ibcr;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	ASSERT(nasid != INVALID_NASID);
+	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
+
+	npdap = NODEPDA(cnode);
+
+#if defined(CONFIG_IA64_SGI_SN1)
+	/* initialize per-node synergy perf instrumentation */
+	npdap->synergy_perf_enabled = 0; /* off by default */
+	npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED;
+	npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT;
+	npdap->synergy_inactive_intervals = 0;
+	npdap->synergy_active_intervals = 0;
+	npdap->synergy_perf_data = NULL;
+	npdap->synergy_perf_first = NULL;
+#endif /* CONFIG_IA64_SGI_SN1 */
+
+
+	/*
+	 * Set the total number of CRBs that can be used.
+	 */
+	ii_icmr.ii_icmr_regval= 0x0;
+	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
+	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
+
+	/*
+	 * Set the number of CRBs that both of the BTEs combined
+	 * can use minus 1.
+	 */
+	ii_ibcr.ii_ibcr_regval= 0x0;
+	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
+	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
+
+	/*
+	 * Set CRB timeout to be 10ms.
+	 */
+	REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 );
+	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+
+
+#if defined(CONFIG_IA64_SGI_SN1)
+	/* Reserve all of the hardwired interrupt levels. */
+	intr_reserve_hardwired(cnode);
+#endif
+
+	/* Initialize error interrupts for this hub. */
+	hub_error_init(cnode);
+}
+
+/*
+ * This routine is responsible for the setup of all the IRIX hwgraph style
+ * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
+ * is called just before the generic Linux PCI layer does its probing (by 
+ * platform_pci_fixup aka sn_pci_fixup).
  *
  * It is very IMPORTANT that this call is only made by the Master CPU!
  *
@@ -80,7 +129,6 @@
 sgi_master_io_infr_init(void)
 {
 	int cnode;
-	extern int maxnodes;
 
 	/*
 	 * Do any early init stuff .. einit_tbl[] etc.
@@ -88,17 +136,49 @@
 	DBG("--> sgi_master_io_infr_init: calling init_hcl().\n");
 	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
 
+#ifdef Colin
+
+printk("Testing out Xbridge Access .. if it hangs Xbridge is not init yet.\n");
+printk("	Reading Xbridge WID at address 0xc00000080f000000 0x%p\n", (* (volatile uint32_t *)(0xc00000080f000000)));
+
+printk("Testing out PCI Address Space Accesses\n");
+printk("	Testing PCI Config Read Byte: address 0xc00000080f020000 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020000)));
+
+printk("	Testing PCI Config Read Byte: address 0xc00000080f020001 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020001)));
+
+printk("	Testing PCI Config Read Byte: address 0xc00000080f020002 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020002)));
+
+printk("	Testing PCI Config Read Byte: address 0xc00000080f020003 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020003)));
+
+printk("        Testing PCI Config Read Byte: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020004)));
+
+printk("        Testing PCI Config Read Byte: address 0xc00000080f020005 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020005)));
+
+printk("        Testing PCI Config Read Byte: address 0xc00000080f020006 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020006)));
+
+printk("        Testing PCI Config Read Byte: address 0xc00000080f020007 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020007)));
+
+printk("	Testing PCI Config Word: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020004)));
+
+printk("	Testing PCI Config Word: address 0xc00000080f020008 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020008)));
+
+#endif
+
 	/*
 	 * initialize the Linux PCI to xwidget vertexes ..
 	 */
 	DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n");
 	pci_bus_cvlink_init();
 
+#ifdef BRINGUP
+#ifdef CONFIG_IA64_SGI_SN1
 	/*
 	 * Hack to provide statically initialzed klgraph entries.
 	 */
 	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
 	klgraph_hack_init();
+#endif /* CONFIG_IA64_SGI_SN1 */
+#endif /* BRINGUP */
 
 	/*
 	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
@@ -117,7 +197,7 @@
 	sn_mp_setup();
 
 	DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n");
-	for (cnode = 0; cnode < maxnodes; cnode++) {
+	for (cnode = 0; cnode < numnodes; cnode++) {
 		per_hub_init(cnode);
 	}
 
@@ -133,9 +213,6 @@
 	DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n");
 	hubspc_init();
 
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
-	pciba_init();
-
 	DBG("--> sgi_master_io_infr_init: calling pciio_init()\n");
 	pciio_init();
 
@@ -172,6 +249,11 @@
 	DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n");
 	pci_bus_to_hcl_cvlink();
 
+#ifdef CONFIG_PCIBA
+	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
+	pciba_init();
+#endif
+
 	DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n");
 }
 
@@ -199,76 +281,15 @@
 sn_mp_setup(void)
 {
 	cnodeid_t	cnode;
-	extern int	maxnodes;
 	cpuid_t		cpu;
 
-	DBG("sn_mp_setup: Entered.\n");
-	/*
-	 * NODEPDA(x) Macro depends on nodepda
-	 * subnodepda is also statically set to calias space which we 
-	 * do not currently support yet .. just a hack for now.
-	 */
-#ifdef NUMA_BASE
-        maxnodes = numnodes;
-	DBG("sn_mp_setup(): maxnodes= %d  numnodes= %d\n", maxnodes,numnodes);
-        printk("sn_mp_setup(): Allocating backing store for *Nodepdaindr[%2d] \n",
-                maxnodes);
-
-        /*
-         * Initialize Nodpdaindr and per-node nodepdaindr array
-         */
-        *Nodepdaindr = (nodepda_t *) kmalloc(sizeof(nodepda_t *)*numnodes, GFP_KERNEL);
-        for (cnode=0; cnode<maxnodes; cnode++) {
-            Nodepdaindr[cnode] = (nodepda_t *) kmalloc(sizeof(struct nodepda_s),
-                                                                GFP_KERNEL);
-	    Synergy_da_indr[cnode * 2] = (synergy_da_t *) kmalloc(
-		sizeof(synergy_da_t), GFP_KERNEL);
-	    Synergy_da_indr[(cnode * 2) + 1] = (synergy_da_t *) kmalloc(
-		sizeof(synergy_da_t), GFP_KERNEL);
-            Nodepdaindr[cnode]->pernode_pdaindr = Nodepdaindr;
-            subnodepda = &Nodepdaindr[cnode]->snpda[cnode];
-        }
-        nodepda = Nodepdaindr[0];
-#else
-        Nodepdaindr = (nodepda_t *) kmalloc(sizeof(struct nodepda_s), GFP_KERNEL);
-        nodepda = Nodepdaindr[0];
-        subnodepda = &Nodepdaindr[0]->snpda[0];
-
-#endif /* NUMA_BASE */
-
-	/*
-	 * Before we let the other processors run, set up the platform specific
-	 * stuff in the nodepda.
-	 *
-	 * ???? maxnodes set in mlreset .. who sets it now ????
-	 * ???? cpu_node_probe() called in mlreset to set up the following:
-	 *      compact_to_nasid_node[] - cnode id gives nasid
-	 *      nasid_to_compact_node[] - nasid gives cnode id
-	 *
-	 *	do_cpumask() sets the following:
-	 *      cpuid_to_compact_node[] - cpuid gives cnode id
-	 *
-	 *      nasid comes from gdap->g_nasidtable[]
-	 *      ml/SN/promif.c
-	 */
-
-#ifdef CONFIG_IA64_SGI_SN1
 	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
 		/* Skip holes in CPU space */
 		if (cpu_enabled(cpu)) {
 			init_platform_pda(cpu);
 		}
 	}
-#endif
-	for (cnode = 0; cnode < maxnodes; cnode++) {
-		/*
-		 * Set up platform-dependent nodepda fields.
-		 * The following routine actually sets up the hubinfo struct
-		 * in nodepda.
-		 */
-		DBG("sn_mp_io_setup: calling init_platform_nodepda(%2d)\n",cnode);
-		init_platform_nodepda(Nodepdaindr[cnode], cnode);
-	}
+
 	/*
 	 * Initialize platform-dependent vertices in the hwgraph:
 	 *	module
@@ -290,24 +311,26 @@
 	klhwg_add_all_nodes(hwgraph_root);
 
 
-	for (cnode = 0; cnode < maxnodes; cnode++) {
+	for (cnode = 0; cnode < numnodes; cnode++) {
 
 		/*
 		 * This routine clears the Hub's Interrupt registers.
 		 */
-#ifdef CONFIG_IA64_SGI_SN1
 		/*
 		 * We need to move this intr_clear_all() routine 
 		 * from SN/intr.c to a more appropriate file.
 		 * Talk to Al Mayer.
 		 */
+#if defined(CONFIG_IA64_SGI_SN1)
                 intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
+#endif
 		/* now init the hub */
 	//	per_hub_init(cnode);
-#endif
+
 	}
 
-#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
+#if defined(CONFIG_IA64_SGI_SN1)
 	synergy_perf_init();
-#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
+#endif
+
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sgi_io_sim.c linux/arch/ia64/sn/io/sgi_io_sim.c
--- linux.orig/arch/ia64/sn/io/sgi_io_sim.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/sgi_io_sim.c	2002-07-20 01:08:31.000000000 +0000
@@ -4,31 +4,28 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/agent.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/module.h>
 #include <asm/sn/nic.h>
 #include <asm/sn/sn_private.h>
-#include <asm/sn/synergy.h>
 
 cpuid_t         master_procid = 0;
-int maxnodes;
 char arg_maxnodes[4];
 
-nodepda_t       *Nodepdaindr[MAX_COMPACT_NODES];
-nodepda_t        *nodepda;
-subnode_pda_t    *subnodepda;
-
-synergy_da_t	*Synergy_da_indr[MAX_COMPACT_NODES * 2];
-
 extern void init_all_devices(void);
 
+#if defined(CONFIG_IA64_SGI_SN1)
+synergy_da_t	*Synergy_da_indr[MAX_COMPACT_NODES * 2];
+#endif
 
 /*
  * Return non-zero if the given variable was specified
@@ -73,27 +70,23 @@
  * Routines provided by ml/SN/promif.c.
  */
 static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL;
-nasid_t console_nasid;
+nasid_t console_nasid = (nasid_t)-1;
 static char console_wid;
 static char console_pcislot;
 
 void
 set_master_bridge_base(void)
 {
-
-        console_nasid = KL_CONFIG_CH_CONS_INFO(master_nasid)->nasid;
         console_wid = WIDGETID_GET(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base);
         console_pcislot = KL_CONFIG_CH_CONS_INFO(master_nasid)->npci;
-        master_bridge_base = (__psunsigned_t)NODE_SWIN_BASE(console_nasid,
-                                                            console_wid);
-	FIXME("WARNING: set_master_bridge_base: NON NASID 0 DOES NOT WORK\n");
+        master_bridge_base = (__psunsigned_t)NODE_SWIN_BASE(console_nasid, console_wid);
+	// FIXME("WARNING: set_master_bridge_base: NON NASID 0 DOES NOT WORK\n");
 }
 
 int
 check_nasid_equiv(nasid_t nasida, nasid_t nasidb)
 {
-        if ((nasida == nasidb) ||
-            (nasida == NODEPDA(NASID_TO_COMPACT_NODEID(nasidb))->xbow_peer))
+        if ((nasida == nasidb) || (nasida == NODEPDA(NASID_TO_COMPACT_NODEID(nasidb))->xbow_peer))
                 return 1;
         else
                 return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn1/hub_intr.c linux/arch/ia64/sn/io/sn1/hub_intr.c
--- linux.orig/arch/ia64/sn/io/sn1/hub_intr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn1/hub_intr.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,307 @@
+/* $Id: hub_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/xtalk/xtalkaddrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_cpuid.h>
+
+extern xtalk_provider_t hub_provider;
+
+/* ARGSUSED */
+void
+hub_intr_init(devfs_handle_t hubv)
+{
+}
+
+/*
+ * hub_device_desc_update
+ *	Update the passed in device descriptor with the actual the
+ * 	target cpu number and interrupt priority level.
+ *	NOTE : These might be the same as the ones passed in thru
+ *	the descriptor.
+ */
+static void
+hub_device_desc_update(device_desc_t 	dev_desc, 
+		       ilvl_t 		intr_swlevel,
+		       cpuid_t		cpu)
+{
+}
+
+int allocate_my_bit = INTRCONNECT_ANYBIT;
+
+/*
+ * Allocate resources required for an interrupt as specified in dev_desc.
+ * Returns a hub interrupt handle on success, or 0 on failure.
+ */
+static hub_intr_t
+do_hub_intr_alloc(devfs_handle_t dev,		/* which crosstalk device */
+		  device_desc_t dev_desc,	/* device descriptor */
+		  devfs_handle_t owner_dev,	/* owner of this interrupt, if known */
+		  int uncond_nothread)		/* unconditionally non-threaded */
+{
+	cpuid_t cpu = (cpuid_t)0;			/* cpu to receive interrupt */
+        int cpupicked = 0;
+	int bit;			/* interrupt vector */
+	/*REFERENCED*/
+	int intr_resflags = 0;
+	hub_intr_t intr_hdl;
+	cnodeid_t nodeid;		/* node to receive interrupt */
+	/*REFERENCED*/
+	nasid_t nasid;			/* nasid to receive interrupt */
+	struct xtalk_intr_s *xtalk_info;
+	iopaddr_t xtalk_addr;		/* xtalk addr on hub to set intr */
+	xwidget_info_t xwidget_info;	/* standard crosstalk widget info handle */
+	char *intr_name = NULL;
+	ilvl_t intr_swlevel = (ilvl_t)0;
+	extern int default_intr_pri;
+	extern void synergy_intr_alloc(int, int);
+
+
+	if (dev_desc) {
+		if (dev_desc->flags & D_INTR_ISERR) {
+			intr_resflags = II_ERRORINT;
+		} else if (!uncond_nothread && !(dev_desc->flags & D_INTR_NOTHREAD)) {
+			intr_resflags = II_THREADED;
+		} else {
+			/* Neither an error nor a thread. */
+			intr_resflags = 0;
+		}
+	} else {
+		intr_swlevel = default_intr_pri;
+		if (!uncond_nothread)
+			intr_resflags = II_THREADED;
+	}
+
+	/* XXX - Need to determine if the interrupt should be threaded. */
+
+	/* If the cpu has not been picked already then choose a candidate 
+	 * interrupt target and reserve the interrupt bit 
+	 */
+	if (!cpupicked) {
+		cpu = intr_heuristic(dev,dev_desc,allocate_my_bit,
+				     intr_resflags,owner_dev,
+				     intr_name,&bit);
+	}
+
+	/* At this point we SHOULD have a valid cpu */
+	if (cpu == CPU_NONE) {
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+		printk(KERN_WARNING  "%v hub_intr_alloc could not allocate interrupt\n",
+			owner_dev);
+#else
+		printk(KERN_WARNING  "%p hub_intr_alloc could not allocate interrupt\n",
+			(void *)owner_dev);
+#endif
+		return(0);
+
+	}
+
+	/* If the cpu has been picked already (due to the bridge data 
+	 * corruption bug) then try to reserve an interrupt bit .
+	 */
+	if (cpupicked) {
+		bit = intr_reserve_level(cpu, allocate_my_bit, 
+					 intr_resflags, 
+					 owner_dev, intr_name);
+		if (bit < 0) {
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+			printk(KERN_WARNING  "Could not reserve an interrupt bit for cpu "
+				" %d and dev %v\n",
+				cpu,owner_dev);
+#else
+			printk(KERN_WARNING  "Could not reserve an interrupt bit for cpu "
+				" %d and dev %p\n",
+				(int)cpu, (void *)owner_dev);
+#endif
+				
+			return(0);
+		}
+	}
+
+	nodeid = cpuid_to_cnodeid(cpu);
+	nasid = cpuid_to_nasid(cpu);
+	xtalk_addr = HUBREG_AS_XTALKADDR(nasid, PIREG(PI_INT_PEND_MOD, cpuid_to_subnode(cpu)));
+
+	/*
+	 * Allocate an interrupt handle, and fill it in.  There are two
+	 * pieces to an interrupt handle: the piece needed by generic
+	 * xtalk code which is used by crosstalk device drivers, and
+	 * the piece needed by low-level IP27 hardware code.
+	 */
+	intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, nodeid);
+	ASSERT_ALWAYS(intr_hdl);
+
+	/* 
+	 * Fill in xtalk information for generic xtalk interfaces that
+	 * operate on xtalk_intr_hdl's.
+	 */
+	xtalk_info = &intr_hdl->i_xtalk_info;
+	xtalk_info->xi_dev = dev;
+	xtalk_info->xi_vector = bit;
+	xtalk_info->xi_addr = xtalk_addr;
+
+	/*
+	 * Regardless of which CPU we ultimately interrupt, a given crosstalk
+	 * widget always handles interrupts (and PIO and DMA) through its 
+	 * designated "master" crosstalk provider.
+	 */
+	xwidget_info = xwidget_info_get(dev);
+	if (xwidget_info)
+		xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info);
+
+	/* Fill in low level hub information for hub_* interrupt interface */
+	intr_hdl->i_swlevel = intr_swlevel;
+	intr_hdl->i_cpuid = cpu;
+	intr_hdl->i_bit = bit;
+	intr_hdl->i_flags = HUB_INTR_IS_ALLOCED;
+
+	/* Store the actual interrupt priority level & interrupt target
+	 * cpu back in the device descriptor.
+	 */
+	hub_device_desc_update(dev_desc, intr_swlevel, cpu);
+	synergy_intr_alloc((int)bit, (int)cpu);
+	return(intr_hdl);
+}
+
+/*
+ * Allocate resources required for an interrupt as specified in dev_desc.
+ * Returns a hub interrupt handle on success, or 0 on failure.
+ */
+hub_intr_t
+hub_intr_alloc(	devfs_handle_t dev,		/* which crosstalk device */
+		device_desc_t dev_desc,		/* device descriptor */
+		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
+{
+	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
+}
+
+/*
+ * Allocate resources required for an interrupt as specified in dev_desc.
+ * Uncondtionally request non-threaded, regardless of what the device
+ * descriptor might say.
+ * Returns a hub interrupt handle on success, or 0 on failure.
+ */
+hub_intr_t
+hub_intr_alloc_nothd(devfs_handle_t dev,		/* which crosstalk device */
+		device_desc_t dev_desc,		/* device descriptor */
+		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
+{
+	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
+}
+
+/*
+ * Free resources consumed by intr_alloc.
+ */
+void
+hub_intr_free(hub_intr_t intr_hdl)
+{
+	cpuid_t cpu = intr_hdl->i_cpuid;
+	int bit = intr_hdl->i_bit;
+	xtalk_intr_t xtalk_info;
+
+	if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) {
+		/* Setting the following fields in the xtalk interrupt info
+	 	 * clears the interrupt target register in the xtalk user
+	 	 */
+		xtalk_info = &intr_hdl->i_xtalk_info;
+		xtalk_info->xi_dev = NODEV;
+		xtalk_info->xi_vector = 0;
+		xtalk_info->xi_addr = 0;
+		hub_intr_disconnect(intr_hdl);
+	}
+
+	if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED)
+		kfree(intr_hdl);
+
+	intr_unreserve_level(cpu, bit);
+}
+
+
+/*
+ * Associate resources allocated with a previous hub_intr_alloc call with the
+ * described handler, arg, name, etc.
+ */
+/*ARGSUSED*/
+int
+hub_intr_connect(	hub_intr_t intr_hdl,		/* xtalk intr resource handle */
+			xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
+			void *setfunc_arg)		/* arg to setfunc */
+{
+	int rv;
+	cpuid_t cpu = intr_hdl->i_cpuid;
+	int bit = intr_hdl->i_bit;
+	extern int synergy_intr_connect(int, int);
+
+	ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED);
+
+	rv = intr_connect_level(cpu, bit, intr_hdl->i_swlevel, NULL);
+	if (rv < 0)
+		return(rv);
+
+	intr_hdl->i_xtalk_info.xi_setfunc = setfunc;
+	intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg;
+
+	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
+
+	intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED;
+	return(synergy_intr_connect((int)bit, (int)cpu));
+}
+
+
+/*
+ * Disassociate handler with the specified interrupt.
+ */
+void
+hub_intr_disconnect(hub_intr_t intr_hdl)
+{
+	/*REFERENCED*/
+	int rv;
+	cpuid_t cpu = intr_hdl->i_cpuid;
+	int bit = intr_hdl->i_bit;
+	xtalk_intr_setfunc_t setfunc;
+
+	setfunc = intr_hdl->i_xtalk_info.xi_setfunc;
+
+	/* TBD: send disconnected interrupts somewhere harmless */
+	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
+
+	rv = intr_disconnect_level(cpu, bit);
+	ASSERT(rv == 0);
+	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
+}
+
+
+/*
+ * Return a hwgraph vertex that represents the CPU currently
+ * targeted by an interrupt.
+ */
+devfs_handle_t
+hub_intr_cpu_get(hub_intr_t intr_hdl)
+{
+	cpuid_t cpuid = intr_hdl->i_cpuid;
+	ASSERT(cpuid != CPU_NONE);
+
+	return(cpuid_to_vertex(cpuid));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn1/hubcounters.c linux/arch/ia64/sn/io/sn1/hubcounters.c
--- linux.orig/arch/ia64/sn/io/sn1/hubcounters.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn1/hubcounters.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,283 @@
+/* $Id: hubcounters.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000 - 2001 Silicon Graphics, Inc.
+ * All rights reserved.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/types.h>
+#include <asm/sn/io.h>
+#include <asm/sn/nodepda.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/router.h>
+#include <asm/sn/snconfig.h>
+#include <asm/sn/slotnum.h>
+#include <asm/sn/clksupport.h>
+#include <asm/sn/sndrv.h>
+
+extern void hubni_error_handler(char *, int); /* huberror.c */
+
+static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+struct file_operations hub_mon_fops = {
+        ioctl:          hubstats_ioctl,
+};
+
+#define HUB_CAPTURE_TICKS	(2 * HZ)
+
+#define HUB_ERR_THRESH		500
+#define USEC_PER_SEC		1000000
+#define NSEC_PER_SEC		USEC_PER_SEC*1000
+
+volatile int hub_print_usecs = 600 * USEC_PER_SEC;
+
+/* Return success if the hub's crosstalk link is working */
+int
+hub_xtalk_link_up(nasid_t nasid)
+{
+	hubreg_t	llp_csr_reg;
+
+	/* Read the IO LLP control status register */
+	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+
+	/* Check if the xtalk link is working */
+	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) 
+		return(1);
+
+	return(0);
+
+	
+}
+
+static char *error_flag_to_type(unsigned char error_flag)
+{
+    switch(error_flag) {
+    case 0x1: return ("NI retries");
+    case 0x2: return ("NI SN errors");
+    case 0x4: return ("NI CB errors");
+    case 0x8: return ("II CB errors");
+    case 0x10: return ("II SN errors");
+    default: return ("Errors");
+    }
+}
+
+int
+print_hub_error(hubstat_t *hsp, hubreg_t reg,
+		int64_t delta, unsigned char error_flag)
+{
+	int64_t rate;
+
+	reg *= hsp->hs_per_minute;	/* Convert to minutes */
+	rate = reg / delta;
+
+	if (rate > HUB_ERR_THRESH) {
+		
+		if(hsp->hs_maint & error_flag) 
+		{
+		printk( "Excessive %s (%ld/min) on %s",
+			error_flag_to_type(error_flag), rate, hsp->hs_name); 
+		}
+		else 
+		{
+		   hsp->hs_maint |= error_flag;
+		printk( "Excessive %s (%ld/min) on %s",
+			error_flag_to_type(error_flag), rate, hsp->hs_name); 
+		}
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+
+int
+check_hub_error_rates(hubstat_t *hsp)
+{
+	int64_t delta = hsp->hs_timestamp - hsp->hs_timebase;
+	int printed = 0;
+
+	printed += print_hub_error(hsp, hsp->hs_ni_retry_errors,
+				   delta, 0x1);
+
+#if 0
+	printed += print_hub_error(hsp, hsp->hs_ni_sn_errors,
+				   delta, 0x2);
+#endif
+
+	printed += print_hub_error(hsp, hsp->hs_ni_cb_errors,
+				   delta, 0x4);
+
+
+	/* If the hub's xtalk link is not working there is 
+	 * no need to print the "Excessive..." warning 
+	 * messages
+	 */
+	if (!hub_xtalk_link_up(hsp->hs_nasid))
+		return(printed);
+
+
+	printed += print_hub_error(hsp, hsp->hs_ii_cb_errors,
+				   delta, 0x8);
+
+	printed += print_hub_error(hsp, hsp->hs_ii_sn_errors,
+				   delta, 0x10);
+
+	return printed;
+}
+
+
+void
+capture_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda)
+{
+	nasid_t nasid;
+	hubstat_t *hsp = &(npda->hubstats);
+	hubreg_t port_error;
+	ii_illr_u_t illr;
+	int count;
+	int overflow = 0;
+
+	/*
+	 * If our link wasn't up at boot time, don't worry about error rates.
+	 */
+	if (!(hsp->hs_ni_port_status & NPS_LINKUP_MASK)) {
+		printk("capture_hub_stats: cnode=%d hs_ni_port_status=0x%016lx : link is not up\n",
+		cnodeid, hsp->hs_ni_port_status);
+		return;
+	}
+
+	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
+
+	hsp->hs_timestamp = GET_RTC_COUNTER();
+
+	port_error = REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
+	count = ((port_error & NPE_RETRYCOUNT_MASK) >> NPE_RETRYCOUNT_SHFT);
+	hsp->hs_ni_retry_errors += count;
+	if (count == NPE_COUNT_MAX)
+		overflow = 1;
+	count = ((port_error & NPE_SNERRCOUNT_MASK) >> NPE_SNERRCOUNT_SHFT);
+	hsp->hs_ni_sn_errors += count;
+	if (count == NPE_COUNT_MAX)
+		overflow = 1;
+	count = ((port_error & NPE_CBERRCOUNT_MASK) >> NPE_CBERRCOUNT_SHFT);
+	hsp->hs_ni_cb_errors += count;
+	if (overflow || count == NPE_COUNT_MAX)
+		hsp->hs_ni_overflows++;
+
+	if (port_error & NPE_FATAL_ERRORS) {
+#ifdef ajm
+		hubni_error_handler("capture_hub_stats", 1);
+#else
+		printk("Error: hubni_error_handler in capture_hub_stats");
+#endif
+	}
+
+	illr.ii_illr_regval = REMOTE_HUB_L(nasid, IIO_LLP_LOG);
+	REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0);
+
+	hsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt;
+	hsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt;
+	if ((illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) ||
+	    (illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))
+		hsp->hs_ii_overflows++;
+
+	if (hsp->hs_print) {
+		if (check_hub_error_rates(hsp)) {
+			hsp->hs_last_print = GET_RTC_COUNTER();
+			hsp->hs_print = 0;
+		}
+	} else {
+		if ((GET_RTC_COUNTER() -
+		    hsp->hs_last_print) > hub_print_usecs)
+			hsp->hs_print = 1;
+	}
+		
+	npda->hubticks = HUB_CAPTURE_TICKS;
+}
+
+
+void
+init_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda)
+{
+	hubstat_t *hsp = &(npda->hubstats);
+	nasid_t nasid = cnodeid_to_nasid(cnodeid);
+	bzero(&(npda->hubstats), sizeof(hubstat_t));
+
+	hsp->hs_version = HUBSTAT_VERSION;
+	hsp->hs_cnode = cnodeid;
+	hsp->hs_nasid = nasid;
+	hsp->hs_timebase = GET_RTC_COUNTER();
+	hsp->hs_ni_port_status = REMOTE_HUB_L(nasid, NI_PORT_STATUS);
+
+	/* Clear the II error counts. */
+	REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0);
+
+	/* Clear the NI counts. */
+	REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
+
+	hsp->hs_per_minute = (long long)RTC_CYCLES_PER_SEC * 60LL;
+
+	npda->hubticks = HUB_CAPTURE_TICKS;
+
+	/* XX should use kmem_alloc_node */
+	hsp->hs_name = (char *)kmalloc(MAX_HUB_PATH, GFP_KERNEL);
+	ASSERT_ALWAYS(hsp->hs_name);
+
+	sprintf(hsp->hs_name, "/dev/hw/" EDGE_LBL_MODULE "/%03d/"
+	        EDGE_LBL_NODE "/" EDGE_LBL_HUB,
+		npda->module_id);
+
+	hsp->hs_last_print = 0;
+	hsp->hs_print = 1;
+
+	hub_print_usecs = hub_print_usecs;
+
+#if 0
+	printk("init_hub_stats: cnode=%d nasid=%d hs_version=%d hs_ni_port_status=0x%016lx\n",
+		cnodeid, nasid, hsp->hs_version, hsp->hs_ni_port_status);
+#endif
+}
+
+static int
+hubstats_ioctl(struct inode *inode, struct file *file,
+        unsigned int cmd, unsigned long arg)
+{
+        cnodeid_t       cnode;
+        nodepda_t       *npdap;
+        uint64_t        longarg;
+        devfs_handle_t  d;
+
+        if ((d = devfs_get_handle_from_inode(inode)) == NULL)
+                return -ENODEV;
+        cnode = (cnodeid_t)hwgraph_fastinfo_get(d);
+        npdap = NODEPDA(cnode);
+
+	if (npdap->hubstats.hs_version != HUBSTAT_VERSION) {
+		init_hub_stats(cnode, npdap);
+	}
+
+        switch (cmd) {
+	case SNDRV_GET_INFOSIZE:
+		longarg = sizeof(hubstat_t);
+		if (copy_to_user((void *)arg, &longarg, sizeof(longarg))) {
+		    return -EFAULT;
+		}
+		break;
+
+	case SNDRV_GET_HUBINFO:
+		/* refresh npda->hubstats */
+		capture_hub_stats(cnode, npdap);
+		if (copy_to_user((void *)arg, &npdap->hubstats, sizeof(hubstat_t))) {
+		    return -EFAULT;
+		}
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn1/huberror.c linux/arch/ia64/sn/io/sn1/huberror.c
--- linux.orig/arch/ia64/sn/io/sn1/huberror.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn1/huberror.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,228 @@
+/* $Id: huberror.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/smp.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/xtalk/xtalk.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/intr.h>
+
+extern void hubni_eint_init(cnodeid_t cnode);
+extern void hubii_eint_init(cnodeid_t cnode);
+extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
+extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
+
+extern int maxcpus;
+
+#define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
+
+
+void
+hub_error_clear(nasid_t nasid)
+{
+	int i;
+	hubreg_t idsr;
+	int sn;
+
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_PEND, -1);
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_A_CLR, -1);
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_B_CLR, -1);
+		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_0, 0);
+		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_1, 0);
+	}
+
+	REMOTE_HUB_L(nasid, MD_DIR_ERROR_CLR);
+	REMOTE_HUB_L(nasid, MD_MEM_ERROR_CLR);
+	REMOTE_HUB_L(nasid, MD_MISC1_ERROR_CLR);
+	REMOTE_HUB_L(nasid, MD_PROTOCOL_ERR_CLR);
+
+    /*
+     * Make sure spurious write response errors are cleared
+     * (values are from hub_set_prb())
+     */
+    for (i = 0; i <= HUB_WIDGET_ID_MAX - HUB_WIDGET_ID_MIN + 1; i++) {
+        iprb_t prb;
+
+	prb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)));
+
+        /* Clear out some fields */
+        prb.iprb_ovflow = 1;
+        prb.iprb_bnakctr = 0;
+        prb.iprb_anakctr = 0;
+
+	/*
+	 * PIO reads in fire-and-forget mode on bedrock 1.0 don't
+	 * frob the credit count properly, making the responses appear
+	 * spurious.  So don't use fire-and-forget mode.  Bug 761802.
+	 */
+        prb.iprb_ff = 0;        /* disable fire-and-forget mode by default */
+
+        prb.iprb_xtalkctr = 3;  /* approx. PIO credits for the widget */
+
+        REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
+    }
+
+    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
+    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
+    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
+
+    REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
+    /* No need to clear NI_PORT_HEADER regs; they are continually overwritten*/
+
+    REMOTE_HUB_S(nasid, LB_ERROR_MASK_CLR, -1);
+    REMOTE_HUB_S(nasid, LB_ERROR_HDR1, 0);
+
+    /* Clear XB error regs, in order */
+    for (i = 0;
+         i <= XB_FIRST_ERROR_CLEAR - XB_POQ0_ERROR_CLEAR;
+         i += sizeof(hubreg_t)) {
+        REMOTE_HUB_S(nasid, XB_POQ0_ERROR_CLEAR + i, 0);
+    }
+}
+
+
+/*
+ * Function	: hub_error_init
+ * Purpose	: initialize the error handling requirements for a given hub.
+ * Parameters	: cnode, the compact nodeid.
+ * Assumptions	: Called only once per hub, either by a local cpu. Or by a 
+ *			remote cpu, when this hub is headless.(cpuless)
+ * Returns	: None
+ */
+
+void
+hub_error_init(cnodeid_t cnode)
+{
+	nasid_t nasid;
+
+    nasid = cnodeid_to_nasid(cnode);
+    hub_error_clear(nasid);
+
+    /*
+     * Now setup the hub ii and ni error interrupt handler.
+     */
+
+    hubii_eint_init(cnode);
+    hubni_eint_init(cnode);
+
+    return;
+}
+
+/*
+ * Function	: hubii_eint_init
+ * Parameters	: cnode
+ * Purpose	: to initialize the hub iio error interrupt.
+ * Assumptions	: Called once per hub, by the cpu which will ultimately
+ *			handle this interrupt.
+ * Returns	: None.
+ */
+
+
+void
+hubii_eint_init(cnodeid_t cnode)
+{
+    int			bit, rv;
+    ii_iidsr_u_t    	hubio_eint;
+    hubinfo_t		hinfo; 
+    cpuid_t		intr_cpu;
+    devfs_handle_t 	hub_v;
+    ii_ilcsr_u_t	ilcsr;
+    int bit_pos_to_irq(int bit);
+    int synergy_intr_connect(int bit, int cpuid);
+
+
+    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
+    ASSERT_ALWAYS(hub_v);
+    hubinfo_get(hub_v, &hinfo);
+
+    ASSERT(hinfo);
+    ASSERT(hinfo->h_cnodeid == cnode);
+
+    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+
+    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
+	/* 
+	 * HUB II link is not up. 
+	 * Just disable LLP, and don't connect any interrupts.
+	 */
+	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
+	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
+	return;
+    }
+    /* Select a possible interrupt target where there is a free interrupt
+     * bit and also reserve the interrupt bit for this IO error interrupt
+     */
+    intr_cpu = intr_heuristic(hub_v,0,INTRCONNECT_ANYBIT,II_ERRORINT,hub_v,
+			      "HUB IO error interrupt",&bit);
+    if (intr_cpu == CPU_NONE) {
+	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
+	return;
+    }
+	
+    rv = intr_connect_level(intr_cpu, bit, 0, NULL);
+    synergy_intr_connect(bit, intr_cpu);
+    request_irq(bit_pos_to_irq(bit) + (intr_cpu << 8), hubii_eint_handler, 0, "SN hub error", (void *)hub_v);
+    ASSERT_ALWAYS(rv >= 0);
+    hubio_eint.ii_iidsr_regval = 0;
+    hubio_eint.ii_iidsr_fld_s.i_enable = 1;
+    hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/
+    hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode);
+    hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu);
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval);
+
+}
+
+void
+hubni_eint_init(cnodeid_t cnode)
+{
+    int intr_bit;
+    cpuid_t targ;
+
+
+    if ((targ = cnodeid_to_cpuid(cnode)) == CPU_NONE)
+	return;
+
+	/* The prom chooses which cpu gets these interrupts, but we
+	*  don't know which one it chose.  We will register all of the 
+	*  cpus to be sure.  This only costs us an irqaction per cpu.
+	*/
+    for (; targ < CPUS_PER_NODE; targ++) {
+	if (!cpu_enabled(targ) ) continue;
+	/* connect the INTEND1 bits. */
+	for (intr_bit = XB_ERROR; intr_bit <= MSC_PANIC_INTR; intr_bit++) {
+		intr_connect_level(targ, intr_bit, II_ERRORINT, NULL);
+	}
+	request_irq(SGI_HUB_ERROR_IRQ + (targ << 8), snia_error_intr_handler, 0, "SN hub error", NULL);
+	/* synergy masks are initialized in the prom to enable all interrupts. */
+	/* We'll just leave them that way, here, for these interrupts. */
+    }
+}
+
+
+/*ARGSUSED*/
+void
+hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
+{
+
+	panic("Hubii interrupt\n");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn1/ip37.c linux/arch/ia64/sn/io/sn1/ip37.c
--- linux.orig/arch/ia64/sn/io/sn1/ip37.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn1/ip37.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,47 @@
+/* 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * ip37.c
+ *	Support for IP35/IP37 machines
+ */
+
+#include <linux/types.h>
+
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/pci/bridge.h>     /* for bridge_t */
+
+
+xwidgetnum_t
+hub_widget_id(nasid_t nasid)
+{
+	hubii_wcr_t	ii_wcr;	/* the control status register */
+		
+	ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
+
+	return ii_wcr.wcr_fields_s.wcr_widget_id;
+}
+
+int
+is_fine_dirmode(void)
+{
+	return (((LOCAL_HUB_L(LB_REV_ID) & LRI_SYSTEM_SIZE_MASK)
+		>> LRI_SYSTEM_SIZE_SHFT) == SYSTEM_SIZE_SMALL);
+
+}
+
+
+void
+ni_reset_port(void)
+{
+	LOCAL_HUB_S(NI_RESET_ENABLE, NRE_RESETOK);
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn1/mem_refcnt.c linux/arch/ia64/sn/io/sn1/mem_refcnt.c
--- linux.orig/arch/ia64/sn/io/sn1/mem_refcnt.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn1/mem_refcnt.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,221 @@
+/* $Id: mem_refcnt.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/nodepda.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/sn1/mem_refcnt.h>
+#include <asm/sn/sn1/hwcntrs.h>
+#include <asm/sn/sn1/hubspc.h>
+// From numa_hw.h
+
+#define MIGR_COUNTER_MAX_GET(nodeid) \
+        (NODEPDA_MCD((nodeid))->migr_system_kparms.migr_threshold_reference)
+/*
+ * Get the Absolute Theshold
+ */
+#define MIGR_THRESHOLD_ABS_GET(nodeid) ( \
+        MD_MIG_VALUE_THRESH_GET(COMPACT_TO_NASID_NODEID(nodeid)))
+/*
+ * Get the current Differential Threshold
+ */
+#define MIGR_THRESHOLD_DIFF_GET(nodeid) \
+        (NODEPDA_MCD(nodeid)->migr_as_kparms.migr_base_threshold)
+
+#define NUM_OF_HW_PAGES_PER_SW_PAGE()   (NBPP / MD_PAGE_SIZE)
+
+// #include "migr_control.h"
+
+int
+mem_refcnt_attach(devfs_handle_t hub)
+{
+#ifndef CONFIG_IA64_SGI_SN
+        devfs_handle_t refcnt_dev;
+        
+        hwgraph_char_device_add(hub,
+                                "refcnt",
+                                "hubspc_", 
+				&refcnt_dev);
+        device_info_set(refcnt_dev, (void*)(ulong)HUBSPC_REFCOUNTERS);
+#endif
+
+        return (0);
+}
+
+
+/*ARGSUSED*/
+int
+mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
+{
+        cnodeid_t node;
+
+        node = master_node_get(*devp);
+
+        ASSERT( (node >= 0) && (node < numnodes) );
+
+        if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) {
+                return (ENODEV);
+        }
+
+        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
+        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 );
+
+        return (0);
+}
+
+/*ARGSUSED*/
+int
+mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
+{
+        return 0;
+}
+
+/*ARGSUSED*/
+int
+mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
+{
+        cnodeid_t node;
+        int errcode;
+        char* buffer;
+        size_t blen;
+        
+        node = master_node_get(dev);
+
+        ASSERT( (node >= 0) && (node < numnodes) );
+
+        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
+        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
+        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
+
+        /*
+         * XXXX deal with prot's somewhere around here....
+         */
+
+        buffer = NODEPDA(node)->migr_refcnt_counterbuffer;
+        blen = NODEPDA(node)->migr_refcnt_cbsize;
+
+        /*
+         * Force offset to be a multiple of sizeof(refcnt_t)
+         * We round up.
+         */
+
+        off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t);
+
+        if ( ((buffer + blen) - (buffer + off + len)) < 0 ) {
+                return (EPERM);
+        }
+
+        errcode = v_mapphys(vt,
+                            buffer + off,
+                            len);
+
+        return errcode;
+}
+
+/*ARGSUSED*/
+int
+mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt)
+{
+        return 0;
+}
+
+/* ARGSUSED */
+int
+mem_refcnt_ioctl(devfs_handle_t dev,
+                 int cmd,
+                 void *arg,
+                 int mode,
+                 cred_t *cred_p,
+                 int *rvalp)
+{
+        cnodeid_t node;
+        int errcode;
+	extern int numnodes;
+        
+        node = master_node_get(dev);
+
+        ASSERT( (node >= 0) && (node < numnodes) );
+
+        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
+        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
+        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
+
+        errcode = 0;
+        
+        switch (cmd) {
+        case RCB_INFO_GET:
+        {
+                rcb_info_t rcb;
+                
+                rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize;
+                
+                rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets;
+                rcb.rcb_sw_counters_per_set = numnodes;
+                rcb.rcb_sw_counter_size = sizeof(refcnt_t);
+
+                rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets /
+                                     NUM_OF_HW_PAGES_PER_SW_PAGE();  
+                rcb.rcb_base_page_size = NBPP;
+                rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0));
+                
+                rcb.rcb_cnodeid = node;
+                rcb.rcb_granularity = MD_PAGE_SIZE;
+#ifdef LATER
+                rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node);
+                rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node);
+#endif
+                rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node);
+                rcb.rcb_num_slots = MAX_MEM_SLOTS;
+
+                if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) {
+                        errcode = EFAULT;
+                }
+
+                break;
+        }
+        case RCB_SLOT_GET:
+        {
+                rcb_slot_t slot[MAX_MEM_SLOTS];
+                int s;
+                int nslots;
+
+                nslots = MAX_MEM_SLOTS;
+                ASSERT(nslots <= MAX_MEM_SLOTS);
+                for (s = 0; s < nslots; s++) {
+                        slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s));
+#ifdef LATER
+                        slot[s].size  = (uint64_t)ctob(slot_getsize(node, s));
+#else
+                        slot[s].size  = (uint64_t)1;
+#endif
+                }
+                if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) {
+                        errcode = EFAULT;
+                }
+                
+                *rvalp = nslots;
+                break;
+        }
+                
+        default:
+                errcode = EINVAL;
+                break;
+
+        }
+        
+        return errcode;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn1/ml_SN_intr.c linux/arch/ia64/sn/io/sn1/ml_SN_intr.c
--- linux.orig/arch/ia64/sn/io/sn1/ml_SN_intr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn1/ml_SN_intr.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,1154 @@
+/* $Id: ml_SN_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * intr.c-
+ *	This file contains all of the routines necessary to set up and
+ *	handle interrupts on an IP27 board.
+ */
+
+#ident  "$Revision: 1.1 $"
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <asm/smp.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/xtalk/xtalk.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/intr.h>
+
+
+#if DEBUG_INTR_TSTAMP_DEBUG
+#include <sys/debug.h>
+#include <sys/idbg.h>
+#include <sys/inst.h>
+void do_splx_log(int, int);
+void spldebug_log_event(int);
+#endif
+
+#ifdef CONFIG_SMP
+extern unsigned long cpu_online_map;
+#endif
+#define cpu_allows_intr(cpu)	(1)
+// If I understand what's going on with this, 32 should work.
+// physmem_maxradius seems to be the maximum number of router
+// hops to get from one end of the system to the other.  With
+// a maximally configured machine, with the dumbest possible
+// topology, we would make 32 router hops.  For what we're using
+// it for, the dumbest possible should suffice.
+#define physmem_maxradius()	32
+
+#define SUBNODE_ANY (-1)
+
+extern int	nmied;
+extern int	hub_intr_wakeup_cnt;
+extern synergy_da_t	*Synergy_da_indr[];
+extern cpuid_t         master_procid;
+
+extern cnodeid_t master_node_get(devfs_handle_t vhdl);
+
+extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
+
+
+#define INTR_LOCK(vecblk) \
+     (s = mutex_spinlock(&(vecblk)->vector_lock))
+#define INTR_UNLOCK(vecblk) \
+      mutex_spinunlock(&(vecblk)->vector_lock, s)
+
+/*
+ * REACT/Pro
+ */
+
+
+
+/* 
+ * Find first bit set 
+ * Used outside this file also 
+ */
+int ms1bit(unsigned long x)
+{
+    int			b;
+
+    if (x >> 32)	b  = 32, x >>= 32;
+    else		b  =  0;
+    if (x >> 16)	b += 16, x >>= 16;
+    if (x >>  8)	b +=  8, x >>=  8;
+    if (x >>  4)	b +=  4, x >>=  4;
+    if (x >>  2)	b +=  2, x >>=  2;
+
+    return b + (int) (x >> 1);
+}
+
+/* ARGSUSED */
+void
+intr_stray(void *lvl)
+{
+    printk(KERN_WARNING  "Stray Interrupt - level %ld to cpu %d", (long)lvl, smp_processor_id());
+}
+
+#if defined(DEBUG)
+
+/* Infrastructure  to gather the device - target cpu mapping info */
+#define MAX_DEVICES	1000	/* Reasonable large number . Need not be 
+				 * the exact maximum # devices possible.
+				 */
+#define MAX_NAME	100	
+typedef struct {
+	dev_t		dev;	/* device */
+	cpuid_t		cpuid;	/* target cpu */
+	cnodeid_t	cnodeid;/* node on which the target cpu is present */
+	int		bit;	/* intr bit reserved */
+	char		intr_name[MAX_NAME]; /* name of the interrupt */
+} intr_dev_targ_map_t;
+
+intr_dev_targ_map_t 	intr_dev_targ_map[MAX_DEVICES];
+uint64_t		intr_dev_targ_map_size;
+spinlock_t		intr_dev_targ_map_lock;
+
+/* Print out the device - target cpu mapping.
+ * This routine is used only in the idbg command
+ * "intrmap" 
+ */
+void
+intr_dev_targ_map_print(cnodeid_t cnodeid)
+{
+	int  i,j,size = 0;
+	int  print_flag = 0,verbose = 0;	
+	char node_name[10];
+	
+	if (cnodeid != CNODEID_NONE) {
+		nodepda_t 	*npda;
+
+		npda = NODEPDA(cnodeid);
+		for (j=0; j<NUM_SUBNODES; j++) {
+			qprintf("\n SUBNODE %d\n INT_PEND0: ", j);
+			for(i = 0 ; i < N_INTPEND_BITS ; i++)
+				qprintf("%d",SNPDA(npda,j)->intr_dispatch0.info[i].ii_flags);
+			qprintf("\n INT_PEND1: ");
+			for(i = 0 ; i < N_INTPEND_BITS ; i++)
+				qprintf("%d",SNPDA(npda,j)->intr_dispatch1.info[i].ii_flags);
+		}
+		verbose = 1;
+	}
+	qprintf("\n Device - Target Map [Interrupts: %s Node%s]\n\n",
+		(verbose ? "All" : "Non-hardwired"),
+		(cnodeid == CNODEID_NONE) ? "s: All" : node_name); 
+		
+	qprintf("Device\tCpu\tCnode\tIntr_bit\tIntr_name\n");
+	for (i = 0 ; i < intr_dev_targ_map_size ; i++) {
+
+		print_flag = 0;
+		if (verbose) {
+			if (cnodeid != CNODEID_NONE) {
+				if (cnodeid == intr_dev_targ_map[i].cnodeid)
+					print_flag = 1;
+			} else {
+				print_flag = 1;
+			}
+		} else {
+			if (intr_dev_targ_map[i].dev != 0) {
+				if (cnodeid != CNODEID_NONE) {
+					if (cnodeid == 
+					    intr_dev_targ_map[i].cnodeid)
+						print_flag = 1;
+				} else {
+					print_flag = 1;
+				}
+			}
+		}
+		if (print_flag) {
+			size++;
+			qprintf("%d\t%d\t%d\t%d\t%s\n",
+				intr_dev_targ_map[i].dev,
+				intr_dev_targ_map[i].cpuid,
+				intr_dev_targ_map[i].cnodeid,
+				intr_dev_targ_map[i].bit,
+				intr_dev_targ_map[i].intr_name);
+		}
+
+	}
+	qprintf("\nTotal : %d\n",size);
+}
+#endif /* DEBUG */
+
+/*
+ * The spinlocks have already been initialized.  Now initialize the interrupt
+ * vectors.  One processor on each hub does the work.
+ */
+void
+intr_init_vecblk(nodepda_t *npda, cnodeid_t node, int sn)
+{
+    int			i, ip=0;
+    intr_vecblk_t	*vecblk;
+    subnode_pda_t	*snpda;
+
+
+    snpda = SNPDA(npda,sn);
+    do {
+	if (ip == 0) {
+	    vecblk = &snpda->intr_dispatch0;
+	} else {
+	    vecblk = &snpda->intr_dispatch1;
+	}
+
+	/* Initialize this vector. */
+	for (i = 0; i < N_INTPEND_BITS; i++) {
+		vecblk->vectors[i].iv_func = intr_stray;
+		vecblk->vectors[i].iv_prefunc = NULL;
+		vecblk->vectors[i].iv_arg = (void *)(__psint_t)(ip * N_INTPEND_BITS + i);
+
+		vecblk->info[i].ii_owner_dev = 0;
+		strcpy(vecblk->info[i].ii_name, "Unused");
+		vecblk->info[i].ii_flags = 0;	/* No flags */
+		vecblk->vectors[i].iv_mustruncpu = -1; /* No CPU yet. */
+
+	    }
+
+	mutex_spinlock_init(&vecblk->vector_lock);
+
+	vecblk->vector_count = 0;    
+	for (i = 0; i < CPUS_PER_SUBNODE; i++)
+		vecblk->cpu_count[i] = 0;
+
+	vecblk->vector_state = VECTOR_UNINITED;
+
+    } while (++ip < 2);
+
+}
+
+
+/*
+ * do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
+ *					devfs_handle_t owner_dev, char *name)
+ *	Internal work routine to reserve or unreserve an interrupt level.
+ *		cpu is the CPU to which the interrupt will be sent.
+ *		bit is the level bit to reserve.  -1 means any level
+ *		resflags should include II_ERRORINT if this is an
+ *			error interrupt, II_THREADED if the interrupt handler
+ *			will be threaded, or 0 otherwise.
+ *		reserve should be set to II_RESERVE or II_UNRESERVE
+ *			to get or clear a reservation.
+ *		owner_dev is the device that "owns" this interrupt, if supplied
+ *		name is a human-readable name for this interrupt, if supplied
+ *	intr_reserve_level returns the bit reserved or -1 to indicate an error
+ */
+static int
+do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
+					devfs_handle_t owner_dev, char *name)
+{
+    intr_vecblk_t	*vecblk;
+    hub_intmasks_t 	*hub_intmasks;
+    unsigned long s;
+    int rv = 0;
+    int ip;
+    synergy_da_t	*sda;
+    int		which_synergy;
+    cnodeid_t	cnode;
+
+    ASSERT(bit < N_INTPEND_BITS * 2);
+
+    cnode = cpuid_to_cnodeid(cpu);
+    which_synergy = cpuid_to_synergy(cpu);
+    sda = Synergy_da_indr[(cnode * 2) + which_synergy];
+    hub_intmasks = &sda->s_intmasks;
+    // hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
+
+    // if (pdaindr[cpu].pda == NULL) return -1;
+    if ((bit < N_INTPEND_BITS) && !(resflags & II_ERRORINT)) {
+	vecblk = hub_intmasks->dispatch0;
+	ip = 0;
+    } else {
+	ASSERT((bit >= N_INTPEND_BITS) || (bit == -1));
+	bit -= N_INTPEND_BITS;	/* Get position relative to INT_PEND1 reg. */
+	vecblk = hub_intmasks->dispatch1;
+	ip = 1;
+    }
+
+    INTR_LOCK(vecblk);
+
+    if (bit <= -1) {
+	bit = 0;
+	ASSERT(reserve == II_RESERVE);
+	/* Choose any available level */
+	for (; bit < N_INTPEND_BITS; bit++) {
+	    if (!(vecblk->info[bit].ii_flags & II_RESERVE)) {
+		rv = bit;
+		break;
+	    }
+	}
+
+	/* Return -1 if all interrupt levels int this register are taken. */
+	if (bit == N_INTPEND_BITS)
+	    rv = -1;
+
+    } else {
+	/* Reserve a particular level if it's available. */
+	if ((vecblk->info[bit].ii_flags & II_RESERVE) == reserve) {
+	    /* Can't (un)reserve a level that's already (un)reserved. */
+	    rv = -1;
+	} else {
+	    rv = bit;
+	}
+    }
+
+    /* Reserve the level and bump the count. */
+    if (rv != -1) {
+	if (reserve) {
+	    int maxlen = sizeof(vecblk->info[bit].ii_name) - 1;
+	    int namelen;
+	    vecblk->info[bit].ii_flags |= (II_RESERVE | resflags);
+	    vecblk->info[bit].ii_owner_dev = owner_dev;
+	    /* Copy in the name. */
+	    namelen = name ? strlen(name) : 0;
+	    strncpy(vecblk->info[bit].ii_name, name, min(namelen, maxlen)); 
+	    vecblk->info[bit].ii_name[maxlen] = '\0';
+	    vecblk->vector_count++;
+	} else {
+	    vecblk->info[bit].ii_flags = 0;	/* Clear all the flags */
+	    vecblk->info[bit].ii_owner_dev = 0;
+	    /* Clear the name. */
+	    vecblk->info[bit].ii_name[0] = '\0';
+	    vecblk->vector_count--;
+	}
+    }
+
+    INTR_UNLOCK(vecblk);
+
+#if defined(DEBUG)
+    if (rv >= 0) {
+	    int namelen = name ? strlen(name) : 0;
+	    /* Gather this device - target cpu mapping information
+	     * in a table which can be used later by the idbg "intrmap"
+	     * command
+	     */
+	    s = mutex_spinlock(&intr_dev_targ_map_lock);
+	    if (intr_dev_targ_map_size < MAX_DEVICES) {
+		    intr_dev_targ_map_t	*p;
+
+		    p 		= &intr_dev_targ_map[intr_dev_targ_map_size];
+		    p->dev  	= owner_dev;
+		    p->cpuid 	= cpu; 
+		    p->cnodeid 	= cpuid_to_cnodeid(cpu); 
+		    p->bit 	= ip * N_INTPEND_BITS + rv;
+		    strncpy(p->intr_name,
+			    name,
+			    min(MAX_NAME,namelen));
+		    intr_dev_targ_map_size++;
+	    }
+	    mutex_spinunlock(&intr_dev_targ_map_lock,s);
+    }
+#endif /* DEBUG */
+
+    return (((rv == -1) ? rv : (ip * N_INTPEND_BITS) + rv)) ;
+}
+
+
+/*
+ * WARNING:  This routine should only be called from within ml/SN.
+ *	Reserve an interrupt level.
+ */
+int
+intr_reserve_level(cpuid_t cpu, int bit, int resflags, devfs_handle_t owner_dev, char *name)
+{
+	return(do_intr_reserve_level(cpu, bit, resflags, II_RESERVE, owner_dev, name));
+}
+
+
+/*
+ * WARNING:  This routine should only be called from within ml/SN.
+ *	Unreserve an interrupt level.
+ */
+void
+intr_unreserve_level(cpuid_t cpu, int bit)
+{
+	(void)do_intr_reserve_level(cpu, bit, 0, II_UNRESERVE, 0, NULL);
+}
+
+/*
+ * Get values that vary depending on which CPU and bit we're operating on
+ */
+static hub_intmasks_t *
+intr_get_ptrs(cpuid_t cpu, int bit,
+	      int *new_bit,		/* Bit relative to the register */
+	      hubreg_t **intpend_masks, /* Masks for this register */
+	      intr_vecblk_t **vecblk,	/* Vecblock for this interrupt */
+	      int *ip)			/* Which intpend register */
+{
+	hub_intmasks_t *hub_intmasks;
+	synergy_da_t	*sda;
+	int		which_synergy;
+	cnodeid_t	cnode;
+
+	ASSERT(bit < N_INTPEND_BITS * 2);
+
+	cnode = cpuid_to_cnodeid(cpu);
+	which_synergy = cpuid_to_synergy(cpu);
+	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
+	hub_intmasks = &sda->s_intmasks;
+
+	// hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
+
+	if (bit < N_INTPEND_BITS) {
+		*intpend_masks = hub_intmasks->intpend0_masks;
+		*vecblk = hub_intmasks->dispatch0;
+		*ip = 0;
+		*new_bit = bit;
+	} else {
+		*intpend_masks = hub_intmasks->intpend1_masks;
+		*vecblk = hub_intmasks->dispatch1;
+		*ip = 1;
+		*new_bit = bit - N_INTPEND_BITS;
+	}
+
+	return hub_intmasks;
+}
+
+
+/*
+ * intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, 
+ *		intr_func_t intr_func, void *intr_arg);
+ *	This is the lowest-level interface to the interrupt code.  It shouldn't
+ *	be called from outside the ml/SN directory.
+ *	intr_connect_level hooks up an interrupt to a particular bit in
+ *	the INT_PEND0/1 masks.  Returns 0 on success.
+ *		cpu is the CPU to which the interrupt will be sent.
+ *		bit is the level bit to connect to
+ *		intr_swlevel tells which software level to use
+ *		intr_func is the interrupt handler
+ *		intr_arg is an arbitrary argument interpreted by the handler
+ *		intr_prefunc is a prologue function, to be called
+ *			with interrupts disabled, to disable
+ *			the interrupt at source.  It is called
+ *			with the same argument.  Should be NULL for
+ *			typical interrupts, which can be masked
+ *			by the infrastructure at the level bit.
+ *	intr_connect_level returns 0 on success or nonzero on an error
+ */
+/* ARGSUSED */
+int
+intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, intr_func_t intr_prefunc)
+{
+    intr_vecblk_t	*vecblk;
+    hubreg_t		*intpend_masks;
+    int rv = 0;
+    int ip;
+    unsigned long s;
+
+    ASSERT(bit < N_INTPEND_BITS * 2);
+
+    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
+				 &vecblk, &ip);
+
+    INTR_LOCK(vecblk);
+
+    if ((vecblk->info[bit].ii_flags & II_INUSE) ||
+	(!(vecblk->info[bit].ii_flags & II_RESERVE))) {
+	/* Can't assign to a level that's in use or isn't reserved. */
+	rv = -1;
+    } else {
+	/* Stuff parameters into vector and info */
+	vecblk->vectors[bit].iv_prefunc = intr_prefunc;
+	vecblk->info[bit].ii_flags |= II_INUSE;
+    }
+
+    /* Now stuff the masks if everything's okay. */
+    if (!rv) {
+	int lslice;
+	volatile hubreg_t *mask_reg;
+	// nasid_t nasid = COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu));
+	nasid_t nasid = cpuid_to_nasid(cpu);
+	int	subnode = cpuid_to_subnode(cpu);
+
+	/* Make sure it's not already pending when we connect it. */
+	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit + ip * N_INTPEND_BITS);
+
+	if (bit >= GFX_INTR_A && bit <= CC_PEND_B) {
+		intpend_masks[0] |= (1ULL << (uint64_t)bit);
+	}
+
+	lslice = cpuid_to_localslice(cpu);
+	vecblk->cpu_count[lslice]++;
+#if SN1
+	/*
+	 * On SN1, there are 8 interrupt mask registers per node:
+	 * 	PI_0 MASK_0 A
+	 * 	PI_0 MASK_1 A
+	 * 	PI_0 MASK_0 B
+	 * 	PI_0 MASK_1 B
+	 * 	PI_1 MASK_0 A
+	 * 	PI_1 MASK_1 A
+	 * 	PI_1 MASK_0 B
+	 * 	PI_1 MASK_1 B
+	 */
+#endif
+	if (ip == 0) {
+		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, 
+		        PI_INT_MASK0_A + PI_INT_MASK_OFFSET * lslice);
+	} else {
+		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode,
+			PI_INT_MASK1_A + PI_INT_MASK_OFFSET * lslice);
+	}
+
+	HUB_S(mask_reg, intpend_masks[0]);
+    }
+
+    INTR_UNLOCK(vecblk);
+
+    return rv;
+}
+
+
+/*
+ * intr_disconnect_level(cpuid_t cpu, int bit)
+ *
+ *	This is the lowest-level interface to the interrupt code.  It should
+ *	not be called from outside the ml/SN directory.
+ *	intr_disconnect_level removes a particular bit from an interrupt in
+ * 	the INT_PEND0/1 masks.  Returns 0 on success or nonzero on failure.
+ */
+int
+intr_disconnect_level(cpuid_t cpu, int bit)
+{
+    intr_vecblk_t	*vecblk;
+    hubreg_t		*intpend_masks;
+    unsigned long s;
+    int rv = 0;
+    int ip;
+
+    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
+				 &vecblk, &ip);
+
+    INTR_LOCK(vecblk);
+
+    if ((vecblk->info[bit].ii_flags & (II_RESERVE | II_INUSE)) !=
+	((II_RESERVE | II_INUSE))) {
+	/* Can't remove a level that's not in use or isn't reserved. */
+	rv = -1;
+    } else {
+	/* Stuff parameters into vector and info */
+	vecblk->vectors[bit].iv_func = (intr_func_t)NULL;
+	vecblk->vectors[bit].iv_prefunc = (intr_func_t)NULL;
+	vecblk->vectors[bit].iv_arg = 0;
+	vecblk->info[bit].ii_flags &= ~II_INUSE;
+#ifdef BASE_ITHRTEAD
+	vecblk->vectors[bit].iv_mustruncpu = -1; /* No mustrun CPU any more. */
+#endif
+    }
+
+    /* Now clear the masks if everything's okay. */
+    if (!rv) {
+	int lslice;
+	volatile hubreg_t *mask_reg;
+
+	intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
+	lslice = cpuid_to_localslice(cpu);
+	vecblk->cpu_count[lslice]--;
+	mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
+				   cpuid_to_subnode(cpu),
+				   ip == 0 ? PI_INT_MASK0_A : PI_INT_MASK1_A);
+	mask_reg = (volatile hubreg_t *)((__psunsigned_t)mask_reg +
+					(PI_INT_MASK_OFFSET * lslice));
+	*mask_reg = intpend_masks[0];
+    }
+
+    INTR_UNLOCK(vecblk);
+
+    return rv;
+}
+
+/*
+ * Actually block or unblock an interrupt
+ */
+void
+do_intr_block_bit(cpuid_t cpu, int bit, int block)
+{
+	intr_vecblk_t *vecblk;
+	int ip;
+	unsigned long s;
+	hubreg_t *intpend_masks;
+	volatile hubreg_t mask_value;
+	volatile hubreg_t *mask_reg;
+
+	intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &vecblk, &ip);
+
+	INTR_LOCK(vecblk);
+
+	if (block)
+		/* Block */
+		intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
+	else
+		/* Unblock */
+		intpend_masks[0] |= (1ULL << (uint64_t)bit);
+
+	if (ip == 0) {
+		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
+		        cpuid_to_subnode(cpu), PI_INT_MASK0_A);
+	} else {
+		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
+			cpuid_to_subnode(cpu), PI_INT_MASK1_A);
+	}
+
+	HUB_S(mask_reg, intpend_masks[0]);
+
+	/*
+	 * Wait for it to take effect.  (One read should suffice.)
+	 * This is only necessary when blocking an interrupt
+	 */
+	if (block)
+		while ((mask_value = HUB_L(mask_reg)) != intpend_masks[0])
+			;
+
+	INTR_UNLOCK(vecblk);
+}
+
+
+/*
+ * Block a particular interrupt (cpu/bit pair).
+ */
+/* ARGSUSED */
+void
+intr_block_bit(cpuid_t cpu, int bit)
+{
+	do_intr_block_bit(cpu, bit, 1);
+}
+
+
+/*
+ * Unblock a particular interrupt (cpu/bit pair).
+ */
+/* ARGSUSED */
+void
+intr_unblock_bit(cpuid_t cpu, int bit)
+{
+	do_intr_block_bit(cpu, bit, 0);
+}
+
+
+/* verifies that the specified CPUID is on the specified SUBNODE (if any) */
+#define cpu_on_subnode(cpuid, which_subnode) \
+	   (((which_subnode) == SUBNODE_ANY) || (cpuid_to_subnode(cpuid) == (which_subnode)))
+
+
+/*
+ * Choose one of the CPUs on a specified node or subnode to receive
+ * interrupts. Don't pick a cpu which has been specified as a NOINTR cpu.
+ *
+ * Among all acceptable CPUs, the CPU that has the fewest total number
+ * of interrupts targetted towards it is chosen.  Note that we never
+ * consider how frequent each of these interrupts might occur, so a rare
+ * hardware error interrupt is weighted equally with a disk interrupt.
+ */
+static cpuid_t
+do_intr_cpu_choose(cnodeid_t cnode, int which_subnode)
+{
+	cpuid_t 	cpu, best_cpu = CPU_NONE;
+	int		slice, min_count=1000;
+
+	min_count = 1000;
+	for (slice=0; slice < CPUS_PER_NODE; slice++) {
+		intr_vecblk_t 	*vecblk0, *vecblk1;
+		int total_intrs_to_slice;
+		subnode_pda_t *snpda;
+		int local_cpu_num;
+
+		cpu = cnode_slice_to_cpuid(cnode, slice);
+		if (cpu == CPU_NONE)
+			continue;
+
+		/* If this cpu isn't enabled for interrupts, skip it */
+		if (!cpu_enabled(cpu) || !cpu_allows_intr(cpu))
+			continue;
+
+		/* If this isn't the right subnode, skip it */
+		if (!cpu_on_subnode(cpu, which_subnode))
+			continue;
+
+		/* OK, this one's a potential CPU for interrupts */
+		snpda = SUBNODEPDA(cnode,SUBNODE(slice));
+		vecblk0 = &snpda->intr_dispatch0;
+		vecblk1 = &snpda->intr_dispatch1;
+		local_cpu_num = LOCALCPU(slice);
+		total_intrs_to_slice = vecblk0->cpu_count[local_cpu_num] +
+		              vecblk1->cpu_count[local_cpu_num];
+
+		if (min_count > total_intrs_to_slice) {
+			min_count = total_intrs_to_slice;
+			best_cpu = cpu;
+		}
+	}
+	return best_cpu;
+}
+
+/*
+ * Choose an appropriate interrupt target CPU on a specified node.
+ * If which_subnode is SUBNODE_ANY, then subnode is not considered.
+ * Otherwise, the chosen CPU must be on the specified subnode.
+ */
+static cpuid_t
+intr_cpu_choose_from_node(cnodeid_t cnode, int which_subnode)
+{
+	return(do_intr_cpu_choose(cnode, which_subnode));
+}
+
+
+/* Make it easy to identify subnode vertices in the hwgraph */
+void
+mark_subnodevertex_as_subnode(devfs_handle_t vhdl, int which_subnode)
+{
+	graph_error_t rv;
+
+	ASSERT(0 <= which_subnode);
+	ASSERT(which_subnode < NUM_SUBNODES);
+
+	rv = hwgraph_info_add_LBL(vhdl, INFO_LBL_CPUBUS, (arbitrary_info_t)which_subnode);
+	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
+
+	rv = hwgraph_info_export_LBL(vhdl, INFO_LBL_CPUBUS, sizeof(arbitrary_info_t));
+	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
+}
+
+
+/*
+ * Given a device descriptor, extract interrupt target information and
+ * choose an appropriate CPU.  Return CPU_NONE if we can't make sense
+ * out of the target information.
+ * TBD: Should this be considered platform-independent code?
+ */
+
+
+/*
+ * intr_bit_reserve_test(cpuid,which_subnode,cnode,req_bit,intr_resflags,
+ *		owner_dev,intr_name,*resp_bit)
+ *	Either cpuid is not CPU_NONE or cnodeid not CNODE_NONE but
+ * 	not both.
+ * 1. 	If cpuid is specified, this routine tests if this cpu can be a valid
+ * 	interrupt target candidate.
+ * 2. 	If cnodeid is specified, this routine tests if there is a cpu on 
+ *	this node which can be a valid interrupt target candidate.
+ * 3.	If a valid interrupt target cpu candidate is found then an attempt at 
+ * 	reserving an interrupt bit on the corresponding cnode is made.
+ *
+ * If steps 1 & 2 both fail or step 3 fails then we are not able to get a valid
+ * interrupt target cpu then routine returns CPU_NONE (failure)
+ * Otherwise routine returns cpuid of interrupt target (success)
+ */
+static cpuid_t
+intr_bit_reserve_test(cpuid_t 		cpuid,
+		      int		favor_subnode,
+		      cnodeid_t 	cnodeid,
+		      int		req_bit,
+		      int 		intr_resflags,
+		      devfs_handle_t 	owner_dev,
+		      char		*intr_name,
+		      int		*resp_bit)
+{
+
+	ASSERT((cpuid==CPU_NONE) || (cnodeid==CNODEID_NONE));
+
+	if (cnodeid != CNODEID_NONE) {
+		/* Try to choose a interrupt cpu candidate */
+		cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode);
+	}
+
+	if (cpuid != CPU_NONE) {
+		/* Try to reserve an interrupt bit on the hub 
+		 * corresponding to the canidate cnode. If we
+		 * are successful then we got a cpu which can
+		 * act as an interrupt target for the io device.
+		 * Otherwise we need to continue the search
+		 * further.
+		 */
+		*resp_bit = do_intr_reserve_level(cpuid, 
+						  req_bit,
+						  intr_resflags,
+						  II_RESERVE,
+						  owner_dev, 
+						  intr_name);
+
+		if (*resp_bit >= 0)
+			/* The interrupt target  specified was fine */
+			return(cpuid);
+	}
+	return(CPU_NONE);
+}
+/*
+ * intr_heuristic(dev_t dev,device_desc_t dev_desc,
+ *		  int req_bit,int intr_resflags,dev_t owner_dev,
+ *		  char *intr_name,int *resp_bit)
+ *
+ * Choose an interrupt destination for an interrupt.
+ *	dev is the device for which the interrupt is being set up
+ *	dev_desc is a description of hardware and policy that could
+ *		help determine where this interrupt should go
+ *	req_bit is the interrupt bit requested 
+ *		(can be INTRCONNECT_ANY_BIT in which the first available
+ * 		 interrupt bit is used)
+ *	intr_resflags indicates whether we want to (un)reserve bit
+ *	owner_dev is the owner device
+ *	intr_name is the readable interrupt name	
+ * 	resp_bit indicates whether we succeeded in getting the required
+ *		 action  { (un)reservation} done	
+ *		 negative value indicates failure
+ *
+ */
+/* ARGSUSED */
+cpuid_t
+intr_heuristic(devfs_handle_t 		dev,
+	       device_desc_t 	dev_desc,
+	       int		req_bit,
+	       int 		intr_resflags,
+	       devfs_handle_t 		owner_dev,
+	       char		*intr_name,
+	       int		*resp_bit)
+{
+	cpuid_t		cpuid;				/* possible intr targ*/
+	cnodeid_t 	candidate;			/* possible canidate */
+	int		which_subnode = SUBNODE_ANY;
+
+/* SN1 + pcibr Addressing Limitation */
+	{
+	devfs_handle_t pconn_vhdl;
+	pcibr_soft_t pcibr_soft;
+
+	/*
+	 * This combination of SN1 and Bridge hardware has an odd "limitation".
+	 * Due to the choice of addresses for PI0 and PI1 registers on SN1
+	 * and historical limitations in Bridge, Bridge is unable to
+	 * send interrupts to both PI0 CPUs and PI1 CPUs -- we have
+	 * to choose one set or the other.  That choice is implicitly
+	 * made when Bridge first attaches its error interrupt.  After
+	 * that point, all subsequent interrupts are restricted to the
+	 * same PI number (though it's possible to send interrupts to
+	 * the same PI number on a different node).
+	 *
+	 * Since neither SN1 nor Bridge designers are willing to admit a
+	 * bug, we can't really call this a "workaround".  It's a permanent
+	 * solution for an SN1-specific and Bridge-specific hardware
+	 * limitation that won't ever be lifted.
+	 */
+        if ((hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
+	   ((pcibr_soft = pcibr_soft_get(pconn_vhdl)) != NULL)) {
+		/*
+		 * We "know" that the error interrupt is the first
+		 * interrupt set up by pcibr_attach.  Send all interrupts
+		 * on this bridge to the same subnode number.
+		 */
+		if (pcibr_soft->bsi_err_intr) {
+			which_subnode = cpuid_to_subnode(((hub_intr_t) pcibr_soft->bsi_err_intr)->i_cpuid);
+		}
+	}
+	}
+
+	/* Check if we can find a valid interrupt target candidate on
+	 * the master node for the device.
+	 */
+	cpuid = intr_bit_reserve_test(CPU_NONE,
+				      which_subnode,	
+				      master_node_get(dev),
+				      req_bit,
+				      intr_resflags,
+				      owner_dev,
+				      intr_name,
+				      resp_bit);
+
+	if (cpuid != CPU_NONE) {
+		if (cpu_on_subnode(cpuid, which_subnode))
+			return(cpuid);	/* got a valid interrupt target */
+		else
+			intr_unreserve_level(cpuid, *resp_bit);
+	}
+
+	printk(KERN_WARNING  "Cannot target interrupts to closest node(%d): (0x%lx)\n",
+		master_node_get(dev),(unsigned long)owner_dev);
+
+	/* Fall through into the default algorithm
+	 * (exhaustive-search-for-the-nearest-possible-interrupt-target)
+	 * for finding the interrupt target
+	 */
+
+	{
+	/*
+	 * Do a stupid round-robin assignment of the node.
+	 *  (Should do a "nearest neighbor" but not for SN1.
+	 */
+		static cnodeid_t last_node = -1;
+
+		if (last_node >= numnodes) last_node = 0;
+		for (candidate = last_node + 1; candidate != last_node; candidate++) {
+			if (candidate == numnodes) candidate = 0;
+			cpuid = intr_bit_reserve_test(CPU_NONE,
+					      which_subnode,
+					      candidate,
+					      req_bit,
+					      intr_resflags,
+					      owner_dev,
+					      intr_name,
+					      resp_bit);
+
+			if (cpuid != CPU_NONE) {
+				if (cpu_on_subnode(cpuid, which_subnode)) {
+					last_node = candidate;
+					return(cpuid);	/* got a valid interrupt target */
+				}
+				else
+					intr_unreserve_level(cpuid, *resp_bit);
+			}
+		}
+		last_node = candidate;
+	}
+
+	printk(KERN_WARNING  "Cannot target interrupts to any close node: %ld (0x%lx)\n",
+		(long)owner_dev, (unsigned long)owner_dev);
+
+	/* In the worst case try to allocate interrupt bits on the
+	 * master processor's node. We may get here during error interrupt
+	 * allocation phase when the topology matrix is not yet setup
+	 * and hence cannot do an exhaustive search.
+	 */
+	ASSERT(cpu_allows_intr(master_procid));
+	cpuid = intr_bit_reserve_test(master_procid,
+				      which_subnode,
+				      CNODEID_NONE,
+				      req_bit,
+				      intr_resflags,
+				      owner_dev,
+				      intr_name,
+				      resp_bit);
+
+	if (cpuid != CPU_NONE) {
+		if (cpu_on_subnode(cpuid, which_subnode))
+			return(cpuid);
+		else
+			intr_unreserve_level(cpuid, *resp_bit);
+	}
+
+	printk(KERN_WARNING  "Cannot target interrupts: (0x%lx)\n",
+		(unsigned long)owner_dev);
+
+	return(CPU_NONE);	/* Should never get here */
+}
+
+struct hardwired_intr_s {
+	signed char level;
+	int flags;
+	char *name;
+} const hardwired_intr[] = {
+	{ INT_PEND0_BASELVL + RESERVED_INTR,	0,	"Reserved" },
+	{ INT_PEND0_BASELVL + GFX_INTR_A,	0, 	"Gfx A" },
+	{ INT_PEND0_BASELVL + GFX_INTR_B,	0, 	"Gfx B" },
+	{ INT_PEND0_BASELVL + PG_MIG_INTR,	II_THREADED, "Migration" },
+	{ INT_PEND0_BASELVL + UART_INTR,	II_THREADED, "Bedrock/L1" },
+	{ INT_PEND0_BASELVL + CC_PEND_A,	0,	"Crosscall A" },
+	{ INT_PEND0_BASELVL + CC_PEND_B,	0,	"Crosscall B" },
+	{ INT_PEND1_BASELVL + CLK_ERR_INTR,	II_ERRORINT, "Clock Error" },
+	{ INT_PEND1_BASELVL + COR_ERR_INTR_A,	II_ERRORINT, "Correctable Error A" },
+	{ INT_PEND1_BASELVL + COR_ERR_INTR_B,	II_ERRORINT, "Correctable Error B" },
+	{ INT_PEND1_BASELVL + MD_COR_ERR_INTR,	II_ERRORINT, "MD Correct. Error" },
+	{ INT_PEND1_BASELVL + NI_ERROR_INTR,	II_ERRORINT, "NI Error" },
+	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_A,	II_ERRORINT, "Remote NI Error"},
+	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_B,	II_ERRORINT, "Remote NI Error"},
+	{ INT_PEND1_BASELVL + MSC_PANIC_INTR,	II_ERRORINT, "MSC Panic" },
+	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_A,	II_ERRORINT, "LLP Pfail WAR" },
+	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_B,	II_ERRORINT, "LLP Pfail WAR" },
+	{ INT_PEND1_BASELVL + NACK_INT_A,	0, "CPU A Nack count == NACK_CMP" },
+	{ INT_PEND1_BASELVL + NACK_INT_B,	0, "CPU B Nack count == NACK_CMP" },
+	{ INT_PEND1_BASELVL + LB_ERROR,		0, "Local Block Error" },
+	{ INT_PEND1_BASELVL + XB_ERROR,		0, "Local XBar Error" },
+	{ -1, 0, (char *)NULL},
+};
+
+/*
+ * Reserve all of the hardwired interrupt levels so they're not used as
+ * general purpose bits later.
+ */
+void
+intr_reserve_hardwired(cnodeid_t cnode)
+{
+	cpuid_t cpu;
+	int level;
+	int i;
+	char subnode_done[NUM_SUBNODES];
+
+	// cpu = cnodetocpu(cnode);
+	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+		if (cpuid_to_cnodeid(cpu) == cnode) {
+			break;
+		}
+	}
+	if (cpu == smp_num_cpus) cpu = CPU_NONE;
+	if (cpu == CPU_NONE) {
+		printk("Node %d has no CPUs", cnode);
+		return;
+	}
+
+	for (i=0; i<NUM_SUBNODES; i++)
+		subnode_done[i] = 0;
+
+	for (; cpu<smp_num_cpus && cpu_enabled(cpu) && cpuid_to_cnodeid(cpu) == cnode; cpu++) {
+		int which_subnode = cpuid_to_subnode(cpu);
+		if (subnode_done[which_subnode])
+			continue;
+		subnode_done[which_subnode] = 1;
+
+		for (i = 0; hardwired_intr[i].level != -1; i++) {
+			level = hardwired_intr[i].level;
+
+			if (level != intr_reserve_level(cpu, level,
+						hardwired_intr[i].flags,
+						(devfs_handle_t) NULL,
+						hardwired_intr[i].name))
+				panic("intr_reserve_hardwired: Can't reserve level %d, cpu %ld.", level, cpu);
+		}
+	}
+}
+
+
+/*
+ * Check and clear interrupts.
+ */
+/*ARGSUSED*/
+static void
+intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level,
+		char *name)
+{
+	volatile hubreg_t bits;
+	int i;
+
+	/* Check pending interrupts */
+	if ((bits = HUB_L(pend)) != 0) {
+		for (i = 0; i < N_INTPEND_BITS; i++) {
+			if (bits & (1 << i)) {
+#ifdef INTRDEBUG
+				printk(KERN_WARNING  "Nasid %d interrupt bit %d set in %s",
+					nasid, i, name);
+#endif
+				LOCAL_HUB_CLR_INTR(base_level + i);
+			}
+		}
+	}
+}
+
+/*
+ * Clear out our interrupt registers.
+ */
+void
+intr_clear_all(nasid_t nasid)
+{
+	int	sn;
+
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_A, 0);
+		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_B, 0);
+		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_A, 0);
+		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_B, 0);
+	
+		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND0),
+				INT_PEND0_BASELVL, "INT_PEND0");
+		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND1),
+				INT_PEND1_BASELVL, "INT_PEND1");
+	}
+}
+
+/* 
+ * Dump information about a particular interrupt vector.
+ */
+static void
+dump_vector(intr_info_t *info, intr_vector_t *vector, int bit, hubreg_t ip,
+		hubreg_t ima, hubreg_t imb, void (*pf)(char *, ...))
+{
+	hubreg_t value = 1LL << bit;
+
+	pf("  Bit %02d: %s: func 0x%x arg 0x%x prefunc 0x%x\n",
+		bit, info->ii_name,
+		vector->iv_func, vector->iv_arg, vector->iv_prefunc);
+	pf("   vertex 0x%x %s%s",
+		info->ii_owner_dev,
+		((info->ii_flags) & II_RESERVE) ? "R" : "U",
+		((info->ii_flags) & II_INUSE) ? "C" : "-");
+	pf("%s%s%s%s",
+		ip & value ? "P" : "-",
+		ima & value ? "A" : "-",
+		imb & value ? "B" : "-",
+		((info->ii_flags) & II_ERRORINT) ? "E" : "-");
+	pf("\n");
+}
+
+
+/*
+ * Dump information about interrupt vector assignment.
+ */
+void
+intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...))
+{
+	nodepda_t *npda;
+	int ip, sn, bit;
+	intr_vecblk_t *dispatch;
+	hubreg_t ipr, ima, imb;
+	nasid_t nasid;
+
+	if ((cnode < 0) || (cnode >= numnodes)) {
+		pf("intr_dumpvec: cnodeid out of range: %d\n", cnode);
+		return ;
+	}
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	if (nasid == INVALID_NASID) {
+		pf("intr_dumpvec: Bad cnodeid: %d\n", cnode);
+		return ;
+	}
+		
+
+	npda = NODEPDA(cnode);
+
+	for (sn = 0; sn < NUM_SUBNODES; sn++) {
+		for (ip = 0; ip < 2; ip++) {
+			dispatch = ip ? &(SNPDA(npda,sn)->intr_dispatch1) : &(SNPDA(npda,sn)->intr_dispatch0);
+			ipr = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_PEND1 : PI_INT_PEND0);
+			ima = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_A : PI_INT_MASK0_A);
+			imb = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_B : PI_INT_MASK0_B);
+	
+			pf("Node %d INT_PEND%d:\n", cnode, ip);
+	
+			if (dispatch->ithreads_enabled)
+				pf(" Ithreads enabled\n");
+			else
+				pf(" Ithreads disabled\n");
+			pf(" vector_count = %d, vector_state = %d\n",
+				dispatch->vector_count,
+				dispatch->vector_state);
+			pf(" CPU A count %d, CPU B count %d\n",
+ 		   	dispatch->cpu_count[0],
+ 		   	dispatch->cpu_count[1]);
+			pf(" &vector_lock = 0x%x\n",
+				&(dispatch->vector_lock));
+			for (bit = 0; bit < N_INTPEND_BITS; bit++) {
+				if ((dispatch->info[bit].ii_flags & II_RESERVE) ||
+			    	(ipr & (1L << bit))) {
+					dump_vector(&(dispatch->info[bit]),
+					    	&(dispatch->vectors[bit]),
+					    	bit, ipr, ima, imb, pf);
+				}
+			}
+			pf("\n");
+		}
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn1/pcibr.c linux/arch/ia64/sn/io/sn1/pcibr.c
--- linux.orig/arch/ia64/sn/io/sn1/pcibr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn1/pcibr.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,7950 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+int NeedXbridgeSwap = 0;
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+#ifdef __ia64
+#define rmallocmap atemapalloc
+#define rmfreemap atemapfree
+#define rmfree atefree
+#define rmalloc atealloc
+#endif
+
+extern boolean_t                is_sys_critical_vertex(devfs_handle_t);
+
+#undef PCIBR_ATE_DEBUG
+
+#if 0
+#define DEBUG 1	 /* To avoid lots of bad printk() formats leave off */
+#endif
+#define PCI_DEBUG 1
+#define ATTACH_DEBUG 1
+#define PCIBR_SOFT_LIST 1
+
+#ifndef	LOCAL
+#define	LOCAL		static
+#endif
+
+/*
+ * Macros related to the Lucent USS 302/312 usb timeout workaround.  It
+ * appears that if the lucent part can get into a retry loop if it sees a
+ * DAC on the bus during a pio read retry.  The loop is broken after about
+ * 1ms, so we need to set up bridges holding this part to allow at least
+ * 1ms for pio.
+ */
+
+#define USS302_TIMEOUT_WAR
+
+#ifdef USS302_TIMEOUT_WAR
+#define LUCENT_USBHC_VENDOR_ID_NUM	0x11c1
+#define LUCENT_USBHC302_DEVICE_ID_NUM	0x5801
+#define LUCENT_USBHC312_DEVICE_ID_NUM	0x5802
+#define USS302_BRIDGE_TIMEOUT_HLD	4
+#endif
+
+#define PCIBR_LLP_CONTROL_WAR
+#if defined (PCIBR_LLP_CONTROL_WAR)
+int                     pcibr_llp_control_war_cnt;
+#endif				/* PCIBR_LLP_CONTROL_WAR */
+
+int                     pcibr_devflag = D_MP;
+
+#ifdef LATER
+#define F(s,n)		{ 1l<<(s),-(s), n }
+
+struct reg_desc         bridge_int_status_desc[] =
+{
+    F(31, "MULTI_ERR"),
+    F(30, "PMU_ESIZE_EFAULT"),
+    F(29, "UNEXPECTED_RESP"),
+    F(28, "BAD_XRESP_PACKET"),
+    F(27, "BAD_XREQ_PACKET"),
+    F(26, "RESP_XTALK_ERROR"),
+    F(25, "REQ_XTALK_ERROR"),
+    F(24, "INVALID_ADDRESS"),
+    F(23, "UNSUPPORTED_XOP"),
+    F(22, "XREQ_FIFO_OFLOW"),
+    F(21, "LLP_REC_SNERROR"),
+    F(20, "LLP_REC_CBERROR"),
+    F(19, "LLP_RCTY"),
+    F(18, "LLP_TX_RETRY"),
+    F(17, "LLP_TCTY"),
+    F(16, "SSRAM_PERR"),
+    F(15, "PCI_ABORT"),
+    F(14, "PCI_PARITY"),
+    F(13, "PCI_SERR"),
+    F(12, "PCI_PERR"),
+    F(11, "PCI_MASTER_TOUT"),
+    F(10, "PCI_RETRY_CNT"),
+    F(9, "XREAD_REQ_TOUT"),
+    F(8, "GIO_BENABLE_ERR"),
+    F(7, "INT7"),
+    F(6, "INT6"),
+    F(5, "INT5"),
+    F(4, "INT4"),
+    F(3, "INT3"),
+    F(2, "INT2"),
+    F(1, "INT1"),
+    F(0, "INT0"),
+    {0}
+};
+
+struct reg_values       space_v[] =
+{
+    {PCIIO_SPACE_NONE, "none"},
+    {PCIIO_SPACE_ROM, "ROM"},
+    {PCIIO_SPACE_IO, "I/O"},
+    {PCIIO_SPACE_MEM, "MEM"},
+    {PCIIO_SPACE_MEM32, "MEM(32)"},
+    {PCIIO_SPACE_MEM64, "MEM(64)"},
+    {PCIIO_SPACE_CFG, "CFG"},
+    {PCIIO_SPACE_WIN(0), "WIN(0)"},
+    {PCIIO_SPACE_WIN(1), "WIN(1)"},
+    {PCIIO_SPACE_WIN(2), "WIN(2)"},
+    {PCIIO_SPACE_WIN(3), "WIN(3)"},
+    {PCIIO_SPACE_WIN(4), "WIN(4)"},
+    {PCIIO_SPACE_WIN(5), "WIN(5)"},
+    {PCIIO_SPACE_BAD, "BAD"},
+    {0}
+};
+
+struct reg_desc         space_desc[] =
+{
+    {0xFF, 0, "space", 0, space_v},
+    {0}
+};
+
+#if DEBUG
+#define	device_desc	device_bits
+LOCAL struct reg_desc   device_bits[] =
+{
+    {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
+    {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
+    {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"},
+    {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"},
+    {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"},
+    {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"},
+    {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"},
+    {BRIDGE_DEV_RT, 0, "RT"},
+    {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"},
+    {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"},
+    {BRIDGE_DEV_PREF, 0, "PREF"},
+    {BRIDGE_DEV_PRECISE, 0, "PRECISE"},
+    {BRIDGE_DEV_COH, 0, "COH"},
+    {BRIDGE_DEV_BARRIER, 0, "BARRIER"},
+    {BRIDGE_DEV_GBR, 0, "GBR"},
+    {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"},
+    {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"},
+    {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"},
+    {0}
+};
+#endif	/* DEBUG */
+
+#ifdef SUPPORT_PRINTING_R_FORMAT
+LOCAL struct reg_values xio_cmd_pactyp[] =
+{
+    {0x0, "RdReq"},
+    {0x1, "RdResp"},
+    {0x2, "WrReqWithResp"},
+    {0x3, "WrResp"},
+    {0x4, "WrReqNoResp"},
+    {0x5, "Reserved(5)"},
+    {0x6, "FetchAndOp"},
+    {0x7, "Reserved(7)"},
+    {0x8, "StoreAndOp"},
+    {0x9, "Reserved(9)"},
+    {0xa, "Reserved(a)"},
+    {0xb, "Reserved(b)"},
+    {0xc, "Reserved(c)"},
+    {0xd, "Reserved(d)"},
+    {0xe, "SpecialReq"},
+    {0xf, "SpecialResp"},
+    {0}
+};
+
+LOCAL struct reg_desc   xio_cmd_bits[] =
+{
+    {WIDGET_DIDN, -28, "DIDN", "%x"},
+    {WIDGET_SIDN, -24, "SIDN", "%x"},
+    {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp},
+    {WIDGET_TNUM, -15, "TNUM", "%x"},
+    {WIDGET_COHERENT, 0, "COHERENT"},
+    {WIDGET_DS, 0, "DS"},
+    {WIDGET_GBR, 0, "GBR"},
+    {WIDGET_VBPM, 0, "VBPM"},
+    {WIDGET_ERROR, 0, "ERROR"},
+    {WIDGET_BARRIER, 0, "BARRIER"},
+    {0}
+};
+#endif	/* SUPPORT_PRINTING_R_FORMAT */
+
+#if PCIBR_FREEZE_TIME || PCIBR_ATE_DEBUG
+LOCAL struct reg_desc   ate_bits[] =
+{
+    {0xFFFF000000000000ull, -48, "RMF", "%x"},
+    {~(IOPGSIZE - 1) &			/* may trim off some low bits */
+     0x0000FFFFFFFFF000ull, 0, "XIO", "%x"},
+    {0x0000000000000F00ull, -8, "port", "%x"},
+    {0x0000000000000010ull, 0, "Barrier"},
+    {0x0000000000000008ull, 0, "Prefetch"},
+    {0x0000000000000004ull, 0, "Precise"},
+    {0x0000000000000002ull, 0, "Coherent"},
+    {0x0000000000000001ull, 0, "Valid"},
+    {0}
+};
+#endif
+
+#if PCIBR_ATE_DEBUG
+LOCAL struct reg_values ssram_sizes[] =
+{
+    {BRIDGE_CTRL_SSRAM_512K, "512k"},
+    {BRIDGE_CTRL_SSRAM_128K, "128k"},
+    {BRIDGE_CTRL_SSRAM_64K, "64k"},
+    {BRIDGE_CTRL_SSRAM_1K, "1k"},
+    {0}
+};
+
+LOCAL struct reg_desc   control_bits[] =
+{
+    {BRIDGE_CTRL_FLASH_WR_EN, 0, "FLASH_WR_EN"},
+    {BRIDGE_CTRL_EN_CLK50, 0, "EN_CLK50"},
+    {BRIDGE_CTRL_EN_CLK40, 0, "EN_CLK40"},
+    {BRIDGE_CTRL_EN_CLK33, 0, "EN_CLK33"},
+    {BRIDGE_CTRL_RST_MASK, -24, "RST", "%x"},
+    {BRIDGE_CTRL_IO_SWAP, 0, "IO_SWAP"},
+    {BRIDGE_CTRL_MEM_SWAP, 0, "MEM_SWAP"},
+    {BRIDGE_CTRL_PAGE_SIZE, 0, "PAGE_SIZE"},
+    {BRIDGE_CTRL_SS_PAR_BAD, 0, "SS_PAR_BAD"},
+    {BRIDGE_CTRL_SS_PAR_EN, 0, "SS_PAR_EN"},
+    {BRIDGE_CTRL_SSRAM_SIZE_MASK, 0, "SSRAM_SIZE", 0, ssram_sizes},
+    {BRIDGE_CTRL_F_BAD_PKT, 0, "F_BAD_PKT"},
+    {BRIDGE_CTRL_LLP_XBAR_CRD_MASK, -12, "LLP_XBAR_CRD", "%d"},
+    {BRIDGE_CTRL_CLR_RLLP_CNT, 0, "CLR_RLLP_CNT"},
+    {BRIDGE_CTRL_CLR_TLLP_CNT, 0, "CLR_TLLP_CNT"},
+    {BRIDGE_CTRL_SYS_END, 0, "SYS_END"},
+    {BRIDGE_CTRL_MAX_TRANS_MASK, -4, "MAX_TRANS", "%d"},
+    {BRIDGE_CTRL_WIDGET_ID_MASK, 0, "WIDGET_ID", "%x"},
+    {0}
+};
+#endif
+#endif	/* LATER */
+
+/* kbrick widgetnum-to-bus layout */
+int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
+        0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
+        2,                                      /* 0x8          */
+        1,                                      /* 0x9          */
+        0, 0,                                   /* 0xa - 0xb    */
+        5,                                      /* 0xc          */
+        6,                                      /* 0xd          */
+        4,                                      /* 0xe          */
+        3,                                      /* 0xf          */
+};
+
+/*
+ * Additional PIO spaces per slot are
+ * recorded in this structure.
+ */
+struct pciio_piospace_s {
+    pciio_piospace_t        next;	/* another space for this device */
+    char                    free;	/* 1 if free, 0 if in use               */
+    pciio_space_t           space;	/* Which space is in use                */
+    iopaddr_t               start;	/* Starting address of the PIO space    */
+    size_t                  count;	/* size of PIO space                    */
+};
+
+#if PCIBR_SOFT_LIST
+pcibr_list_p            pcibr_list = 0;
+#endif
+
+#define	INFO_LBL_PCIBR_ASIC_REV	"_pcibr_asic_rev"
+
+#define	PCIBR_D64_BASE_UNSET	(0xFFFFFFFFFFFFFFFF)
+#define	PCIBR_D32_BASE_UNSET	(0xFFFFFFFF)
+
+#define PCIBR_VALID_SLOT(s)	(s < 8)
+
+#ifdef SN_XXX
+extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
+                                     hub_widget_flags_t flags);
+#endif
+extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
+extern void free_pciio_dmamap(pcibr_dmamap_t);
+
+/*
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the 
+ * appropriate function name below.
+ */
+struct file_operations pcibr_fops = {
+        owner:  THIS_MODULE,
+        llseek: NULL,
+        read: NULL,
+        write: NULL,
+        readdir: NULL,
+        poll: NULL,
+        ioctl: NULL,
+        mmap: NULL,
+        open: NULL,
+        flush: NULL,
+        release: NULL,
+        fsync: NULL,
+        fasync: NULL,
+        lock: NULL,
+        readv: NULL,
+        writev: NULL
+};
+
+extern devfs_handle_t hwgraph_root;
+extern graph_error_t hwgraph_vertex_unref(devfs_handle_t vhdl);
+extern int cap_able(uint64_t x);
+extern uint64_t rmalloc(struct map *mp, size_t size);
+extern void rmfree(struct map *mp, size_t size, uint64_t a);
+extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
+extern long atoi(register char *p);
+extern void *swap_ptr(void **loc, void *new);
+extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
+extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl);
+extern graph_error_t hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr);
+extern struct map *rmallocmap(uint64_t mapsiz);
+extern void rmfreemap(struct map *mp);
+extern int compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr);
+extern int io_path_map_widget(devfs_handle_t vertex);
+
+
+
+/* =====================================================================
+ *    Function Table of Contents
+ *
+ *      The order of functions in this file has stopped
+ *      making much sense. We might want to take a look
+ *      at it some time and bring back some sanity, or
+ *      perhaps bust this file into smaller chunks.
+ */
+
+LOCAL void              do_pcibr_rrb_clear(bridge_t *, int);
+LOCAL void              do_pcibr_rrb_flush(bridge_t *, int);
+LOCAL int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t);
+LOCAL int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
+LOCAL int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int);
+LOCAL int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int);
+
+LOCAL void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int);
+
+int			pcibr_wrb_flush(devfs_handle_t);
+int                     pcibr_rrb_alloc(devfs_handle_t, int *, int *);
+int                     pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
+int                     pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int);
+void                    pcibr_rrb_flush(devfs_handle_t);
+
+LOCAL int               pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
+void                    pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
+
+LOCAL void              pcibr_clearwidint(bridge_t *);
+LOCAL void              pcibr_setwidint(xtalk_intr_t);
+LOCAL int               pcibr_probe_slot(bridge_t *, cfg_p, unsigned *);
+
+void                    pcibr_init(void);
+int                     pcibr_attach(devfs_handle_t);
+int			pcibr_detach(devfs_handle_t);
+int                     pcibr_open(devfs_handle_t *, int, int, cred_t *);
+int                     pcibr_close(devfs_handle_t, int, int, cred_t *);
+int                     pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
+int                     pcibr_unmap(devfs_handle_t, vhandl_t *);
+int                     pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
+
+void                    pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
+
+LOCAL int               pcibr_init_ext_ate_ram(bridge_t *);
+LOCAL int               pcibr_ate_alloc(pcibr_soft_t, int);
+LOCAL void              pcibr_ate_free(pcibr_soft_t, int, int);
+
+LOCAL pcibr_info_t      pcibr_info_get(devfs_handle_t);
+LOCAL pcibr_info_t      pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
+LOCAL void		pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
+LOCAL iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+
+pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
+void                    pcibr_piomap_free(pcibr_piomap_t);
+caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
+void                    pcibr_piomap_done(pcibr_piomap_t);
+caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
+void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
+
+LOCAL iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
+LOCAL bridge_ate_t      pcibr_flags_to_ate(unsigned);
+
+pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+void                    pcibr_dmamap_free(pcibr_dmamap_t);
+LOCAL bridge_ate_p      pcibr_ate_addr(pcibr_soft_t, int);
+LOCAL iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
+iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
+alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
+void                    pcibr_dmamap_done(pcibr_dmamap_t);
+cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
+iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
+alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+void                    pcibr_dmamap_drain(pcibr_dmamap_t);
+void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
+void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
+iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
+
+static unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines);
+pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+void                    pcibr_intr_free(pcibr_intr_t);
+LOCAL void              pcibr_setpciint(xtalk_intr_t);
+int                     pcibr_intr_connect(pcibr_intr_t);
+void                    pcibr_intr_disconnect(pcibr_intr_t);
+
+devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
+void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
+void                    pcibr_intr_func(intr_arg_t);
+
+void                    pcibr_provider_startup(devfs_handle_t);
+void                    pcibr_provider_shutdown(devfs_handle_t);
+
+int                     pcibr_reset(devfs_handle_t);
+pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
+int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
+pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
+int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
+
+LOCAL cfg_p             pcibr_config_addr(devfs_handle_t, unsigned);
+uint64_t                pcibr_config_get(devfs_handle_t, unsigned, unsigned);
+LOCAL uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
+void                    pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
+LOCAL void              do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
+
+LOCAL pcibr_hints_t     pcibr_hints_get(devfs_handle_t, int);
+void                    pcibr_hints_fix_rrbs(devfs_handle_t);
+void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
+void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
+void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
+void                    pcibr_hints_handsoff(devfs_handle_t);
+void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
+
+LOCAL int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
+LOCAL int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
+
+#ifdef LATER
+LOCAL int	        pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t,
+                                               pcibr_slot_info_resp_t);
+LOCAL void       	pcibr_slot_func_info_return(pcibr_info_h, int,
+                                                    pcibr_slot_func_info_resp_t);
+#endif	/* LATER */
+
+LOCAL int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
+LOCAL int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
+LOCAL int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
+LOCAL int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+LOCAL int		pcibr_slot_call_device_attach(devfs_handle_t,
+						      pciio_slot_t, int);
+LOCAL int		pcibr_slot_call_device_detach(devfs_handle_t,
+						      pciio_slot_t, int);
+
+LOCAL int               pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int);
+LOCAL int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
+#ifdef LATER
+LOCAL int		pcibr_slot_query(devfs_handle_t, pcibr_slot_info_req_t);
+#endif
+
+/* =====================================================================
+ *    RRB management
+ */
+
+#define LSBIT(word)		((word) &~ ((word)-1))
+
+#define PCIBR_RRB_SLOT_VIRTUAL	8
+
+LOCAL void
+do_pcibr_rrb_clear(bridge_t *bridge, int rrb)
+{
+    bridgereg_t             status;
+
+    /* bridge_lock must be held;
+     * this RRB must be disabled.
+     */
+
+    /* wait until RRB has no outstanduing XIO packets. */
+    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
+	;				/* XXX- beats on bridge. bad idea? */
+    }
+
+    /* if the RRB has data, drain it. */
+    if (status & BRIDGE_RRB_VALID(rrb)) {
+	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
+
+	/* wait until RRB is no longer valid. */
+	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
+	    ;				/* XXX- beats on bridge. bad idea? */
+	}
+    }
+}
+
+LOCAL void
+do_pcibr_rrb_flush(bridge_t *bridge, int rrbn)
+{
+    reg_p                   rrbp = &bridge->b_rrb_map[rrbn & 1].reg;
+    bridgereg_t             rrbv;
+    int                     shft = 4 * (rrbn >> 1);
+    unsigned                ebit = BRIDGE_RRB_EN << shft;
+
+    rrbv = *rrbp;
+    if (rrbv & ebit)
+	*rrbp = rrbv & ~ebit;
+
+    do_pcibr_rrb_clear(bridge, rrbn);
+
+    if (rrbv & ebit)
+	*rrbp = rrbv;
+}
+
+/*
+ *    pcibr_rrb_count_valid: count how many RRBs are
+ *      marked valid for the specified PCI slot on this
+ *      bridge.
+ *
+ *      NOTE: The "slot" parameter for all pcibr_rrb
+ *      management routines must include the "virtual"
+ *      bit; when manageing both the normal and the
+ *      virtual channel, separate calls to these
+ *      routines must be made. To denote the virtual
+ *      channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot
+ *      number.
+ *
+ *      IMPL NOTE: The obvious algorithm is to iterate
+ *      through the RRB fields, incrementing a count if
+ *      the RRB is valid and matches the slot. However,
+ *      it is much simpler to use an algorithm derived
+ *      from the "partitioned add" idea. First, XOR in a
+ *      pattern such that the fields that match this
+ *      slot come up "all ones" and all other fields
+ *      have zeros in the mismatching bits. Then AND
+ *      together the bits in the field, so we end up
+ *      with one bit turned on for each field that
+ *      matched. Now we need to count these bits. This
+ *      can be done either with a series of shift/add
+ *      instructions or by using "tmp % 15"; I expect
+ *      that the cascaded shift/add will be faster.
+ */
+
+LOCAL int
+do_pcibr_rrb_count_valid(bridge_t *bridge,
+			 pciio_slot_t slot)
+{
+    bridgereg_t             tmp;
+
+    tmp = bridge->b_rrb_map[slot & 1].reg;
+    tmp ^= 0x11111111 * (7 - slot / 2);
+    tmp &= (0xCCCCCCCC & tmp) >> 2;
+    tmp &= (0x22222222 & tmp) >> 1;
+    tmp += tmp >> 4;
+    tmp += tmp >> 8;
+    tmp += tmp >> 16;
+    return tmp & 15;
+}
+
+/*
+ *    do_pcibr_rrb_count_avail: count how many RRBs are
+ *      available to be allocated for the specified slot.
+ *
+ *      IMPL NOTE: similar to the above, except we are
+ *      just counting how many fields have the valid bit
+ *      turned off.
+ */
+LOCAL int
+do_pcibr_rrb_count_avail(bridge_t *bridge,
+			 pciio_slot_t slot)
+{
+    bridgereg_t             tmp;
+
+    tmp = bridge->b_rrb_map[slot & 1].reg;
+    tmp = (0x88888888 & ~tmp) >> 3;
+    tmp += tmp >> 4;
+    tmp += tmp >> 8;
+    tmp += tmp >> 16;
+    return tmp & 15;
+}
+
+/*
+ *    do_pcibr_rrb_alloc: allocate some additional RRBs
+ *      for the specified slot. Returns -1 if there were
+ *      insufficient free RRBs to satisfy the request,
+ *      or 0 if the request was fulfilled.
+ *
+ *      Note that if a request can be partially filled,
+ *      it will be, even if we return failure.
+ *
+ *      IMPL NOTE: again we avoid iterating across all
+ *      the RRBs; instead, we form up a word containing
+ *      one bit for each free RRB, then peel the bits
+ *      off from the low end.
+ */
+LOCAL int
+do_pcibr_rrb_alloc(bridge_t *bridge,
+		   pciio_slot_t slot,
+		   int more)
+{
+    int                     rv = 0;
+    bridgereg_t             reg, tmp, bit;
+
+    reg = bridge->b_rrb_map[slot & 1].reg;
+    tmp = (0x88888888 & ~reg) >> 3;
+    while (more-- > 0) {
+	bit = LSBIT(tmp);
+	if (!bit) {
+	    rv = -1;
+	    break;
+	}
+	tmp &= ~bit;
+	reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2)));
+    }
+    bridge->b_rrb_map[slot & 1].reg = reg;
+    return rv;
+}
+
+/*
+ *    do_pcibr_rrb_free: release some of the RRBs that
+ *      have been allocated for the specified
+ *      slot. Returns zero for success, or negative if
+ *      it was unable to free that many RRBs.
+ *
+ *      IMPL NOTE: We form up a bit for each RRB
+ *      allocated to the slot, aligned with the VALID
+ *      bitfield this time; then we peel bits off one at
+ *      a time, releasing the corresponding RRB.
+ */
+LOCAL int
+do_pcibr_rrb_free(bridge_t *bridge,
+		  pciio_slot_t slot,
+		  int less)
+{
+    int                     rv = 0;
+    bridgereg_t             reg, tmp, clr, bit;
+    int                     i;
+
+    clr = 0;
+    reg = bridge->b_rrb_map[slot & 1].reg;
+
+    /* This needs to be done otherwise the rrb's on the virtual channel
+     * for this slot won't be freed !!
+     */
+    tmp = reg & 0xbbbbbbbb;
+
+    tmp ^= (0x11111111 * (7 - slot / 2));
+    tmp &= (0x33333333 & tmp) << 2;
+    tmp &= (0x44444444 & tmp) << 1;
+    while (less-- > 0) {
+	bit = LSBIT(tmp);
+	if (!bit) {
+	    rv = -1;
+	    break;
+	}
+	tmp &= ~bit;
+	reg &= ~bit;
+	clr |= bit;
+    }
+    bridge->b_rrb_map[slot & 1].reg = reg;
+
+    for (i = 0; i < 8; i++)
+	if (clr & (8 << (4 * i)))
+	    do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1));
+
+    return rv;
+}
+
+LOCAL void
+do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft,
+		       int slot,
+		       int more_rrbs)
+{
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    int                     got;
+
+    for (got = 0; got < more_rrbs; ++got) {
+	if (pcibr_soft->bs_rrb_res[slot & 7] > 0)
+	    pcibr_soft->bs_rrb_res[slot & 7]--;
+	else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
+	    pcibr_soft->bs_rrb_avail[slot & 1]--;
+	else
+	    break;
+	if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0)
+	    break;
+#if PCIBR_RRB_DEBUG
+	printk( "do_pcibr_rrb_autoalloc: add one to slot %d%s\n",
+		slot & 7, slot & 8 ? "v" : "");
+#endif
+	pcibr_soft->bs_rrb_valid[slot]++;
+    }
+#if PCIBR_RRB_DEBUG
+    printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name,
+	    pcibr_soft->bs_rrb_avail[0],
+	    pcibr_soft->bs_rrb_avail[1]);
+    for (slot = 0; slot < 8; ++slot)
+	printk("\t%d+%d+%d",
+		0xFFF & pcibr_soft->bs_rrb_valid[slot],
+		0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+		pcibr_soft->bs_rrb_res[slot]);
+	printk("\n");
+#endif
+}
+
+/*
+ * Device driver interface to flush the write buffers for a specified
+ * device hanging off the bridge.
+ */
+int
+pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    volatile bridgereg_t   *wrb_flush;
+
+    wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg);
+    while (*wrb_flush);
+
+    return(0);
+}
+/*
+ * Device driver interface to request RRBs for a specified device
+ * hanging off a Bridge.  The driver requests the total number of
+ * RRBs it would like for the normal channel (vchan0) and for the
+ * "virtual channel" (vchan1).  The actual number allocated to each
+ * channel is returned.
+ *
+ * If we cannot allocate at least one RRB to a channel that needs
+ * at least one, return -1 (failure).  Otherwise, satisfy the request
+ * as best we can and return 0.
+ */
+int
+pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
+		int *count_vchan0,
+		int *count_vchan1)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    int                     desired_vchan0;
+    int                     desired_vchan1;
+    int                     orig_vchan0;
+    int                     orig_vchan1;
+    int                     delta_vchan0;
+    int                     delta_vchan1;
+    int                     final_vchan0;
+    int                     final_vchan1;
+    int                     avail_rrbs;
+    unsigned long           s;
+    int                     error;
+
+    /*
+     * TBD: temper request with admin info about RRB allocation,
+     * and according to demand from other devices on this Bridge.
+     *
+     * One way of doing this would be to allocate two RRBs
+     * for each device on the bus, before any drivers start
+     * asking for extras. This has the weakness that one
+     * driver might not give back an "extra" RRB until after
+     * another driver has already failed to get one that
+     * it wanted.
+     */
+
+    s = pcibr_lock(pcibr_soft);
+
+    /* How many RRBs do we own? */
+    orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot];
+    orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
+
+    /* How many RRBs do we want? */
+    desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
+    desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
+
+    /* How many RRBs are free? */
+    avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
+	+ pcibr_soft->bs_rrb_res[pciio_slot];
+
+    /* Figure desired deltas */
+    delta_vchan0 = desired_vchan0 - orig_vchan0;
+    delta_vchan1 = desired_vchan1 - orig_vchan1;
+
+    /* Trim back deltas to something
+     * that we can actually meet, by
+     * decreasing the ending allocation
+     * for whichever channel wants
+     * more RRBs. If both want the same
+     * number, cut the second channel.
+     * NOTE: do not change the allocation for
+     * a channel that was passed as NULL.
+     */
+    while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
+	if (count_vchan0 &&
+	    (!count_vchan1 ||
+	     ((orig_vchan0 + delta_vchan0) >
+	      (orig_vchan1 + delta_vchan1))))
+	    delta_vchan0--;
+	else
+	    delta_vchan1--;
+    }
+
+    /* Figure final RRB allocations
+     */
+    final_vchan0 = orig_vchan0 + delta_vchan0;
+    final_vchan1 = orig_vchan1 + delta_vchan1;
+
+    /* If either channel wants RRBs but our actions
+     * would leave it with none, declare an error,
+     * but DO NOT change any RRB allocations.
+     */
+    if ((desired_vchan0 && !final_vchan0) ||
+	(desired_vchan1 && !final_vchan1)) {
+
+	error = -1;
+
+    } else {
+
+	/* Commit the allocations: free, then alloc.
+	 */
+	if (delta_vchan0 < 0)
+	    (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0);
+	if (delta_vchan1 < 0)
+	    (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1);
+
+	if (delta_vchan0 > 0)
+	    (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0);
+	if (delta_vchan1 > 0)
+	    (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1);
+
+	/* Return final values to caller.
+	 */
+	if (count_vchan0)
+	    *count_vchan0 = final_vchan0;
+	if (count_vchan1)
+	    *count_vchan1 = final_vchan1;
+
+	/* prevent automatic changes to this slot's RRBs
+	 */
+	pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
+
+	/* Track the actual allocations, release
+	 * any further reservations, and update the
+	 * number of available RRBs.
+	 */
+
+	pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0;
+	pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1;
+	pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
+	    pcibr_soft->bs_rrb_avail[pciio_slot & 1]
+	    + pcibr_soft->bs_rrb_res[pciio_slot]
+	    - delta_vchan0
+	    - delta_vchan1;
+	pcibr_soft->bs_rrb_res[pciio_slot] = 0;
+
+#if PCIBR_RRB_DEBUG
+	printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n",
+		pciio_slot, final_vchan0, final_vchan1,
+		pcibr_soft->bs_rrb_avail[0],
+		pcibr_soft->bs_rrb_avail[1]);
+	for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot)
+	    printk("\t%d+%d+%d",
+		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot],
+		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL],
+		    pcibr_soft->bs_rrb_res[pciio_slot]);
+	printk("\n");
+#endif
+
+	error = 0;
+    }
+
+    pcibr_unlock(pcibr_soft, s);
+    return error;
+}
+
+/*
+ * Device driver interface to check the current state
+ * of the RRB allocations.
+ *
+ *   pconn_vhdl is your PCI connection point (specifies which
+ *      PCI bus and which slot).
+ *
+ *   count_vchan0 points to where to return the number of RRBs
+ *      assigned to the primary DMA channel, used by all DMA
+ *      that does not explicitly ask for the alternate virtual
+ *      channel.
+ *
+ *   count_vchan1 points to where to return the number of RRBs
+ *      assigned to the secondary DMA channel, used when
+ *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
+ *
+ *   count_reserved points to where to return the number of RRBs
+ *      that have been automatically reserved for your device at
+ *      startup, but which have not been assigned to a
+ *      channel. RRBs must be assigned to a channel to be used;
+ *      this can be done either with an explicit pcibr_rrb_alloc
+ *      call, or automatically by the infrastructure when a DMA
+ *      translation is constructed. Any call to pcibr_rrb_alloc
+ *      will release any unassigned reserved RRBs back to the
+ *      free pool.
+ *
+ *   count_pool points to where to return the number of RRBs
+ *      that are currently unassigned and unreserved. This
+ *      number can (and will) change as other drivers make calls
+ *      to pcibr_rrb_alloc, or automatically allocate RRBs for
+ *      DMA beyond their initial reservation.
+ *
+ * NULL may be passed for any of the return value pointers
+ * the caller is not interested in.
+ *
+ * The return value is "0" if all went well, or "-1" if
+ * there is a problem. Additionally, if the wrong vertex
+ * is passed in, one of the subsidiary support functions
+ * could panic with a "bad pciio fingerprint."
+ */
+
+int
+pcibr_rrb_check(devfs_handle_t pconn_vhdl,
+		int *count_vchan0,
+		int *count_vchan1,
+		int *count_reserved,
+		int *count_pool)
+{
+    pciio_info_t            pciio_info;
+    pciio_slot_t            pciio_slot;
+    pcibr_soft_t            pcibr_soft;
+    unsigned long           s;
+    int                     error = -1;
+
+    if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
+	(pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
+	((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) {
+
+	s = pcibr_lock(pcibr_soft);
+
+	if (count_vchan0)
+	    *count_vchan0 =
+		pcibr_soft->bs_rrb_valid[pciio_slot];
+
+	if (count_vchan1)
+	    *count_vchan1 =
+		pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
+
+	if (count_reserved)
+	    *count_reserved =
+		pcibr_soft->bs_rrb_res[pciio_slot];
+
+	if (count_pool)
+	    *count_pool =
+		pcibr_soft->bs_rrb_avail[pciio_slot & 1];
+
+	error = 0;
+
+	pcibr_unlock(pcibr_soft, s);
+    }
+    return error;
+}
+
+/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities
+ * requested for each of the devies.  The evn_odd argument indicates whether
+ * allcoation for the odd or even rrbs is requested and next group of four pairse
+ * are the amount to assign to each device (they should sum to <= 8) and
+ * whether to set the viritual bit for that device (1 indictaes yes, 0 indicates no)
+ * the devices in order are either 0, 2, 4, 6 or 1, 3, 5, 7
+ * if even_odd is even we alloc even rrbs else we allocate odd rrbs
+ * returns 0 if no errors else returns -1
+ */
+
+int
+pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
+		     int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2,
+		     int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4)
+{
+    devfs_handle_t            pcibr_vhdl;
+    pcibr_soft_t            pcibr_soft = NULL;
+    bridge_t               *bridge = NULL;
+
+    uint32_t              rrb_setting = 0;
+    int                     rrb_shift = 7;
+    uint32_t              cur_rrb;
+    int                     dev_rrbs[4];
+    int                     virt[4];
+    int                     i, j;
+    unsigned long           s;
+
+    if (GRAPH_SUCCESS ==
+	hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) {
+	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+	if (pcibr_soft)
+	    bridge = pcibr_soft->bs_base;
+	hwgraph_vertex_unref(pcibr_vhdl);
+    }
+    if (bridge == NULL)
+	bridge = (bridge_t *) xtalk_piotrans_addr
+	    (vhdl, NULL, 0, sizeof(bridge_t), 0);
+
+    even_odd &= 1;
+
+    dev_rrbs[0] = dev_1_rrbs;
+    dev_rrbs[1] = dev_2_rrbs;
+    dev_rrbs[2] = dev_3_rrbs;
+    dev_rrbs[3] = dev_4_rrbs;
+
+    virt[0] = virt1;
+    virt[1] = virt2;
+    virt[2] = virt3;
+    virt[3] = virt4;
+
+    if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) {
+	return -1;
+    }
+    if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) {
+	return -1;
+    }
+    /* walk through rrbs */
+    for (i = 0; i < 4; i++) {
+	if (virt[i]) {
+	    cur_rrb = i | 0xc;
+	    cur_rrb = cur_rrb << (rrb_shift * 4);
+	    rrb_shift--;
+	    rrb_setting = rrb_setting | cur_rrb;
+	    dev_rrbs[i] = dev_rrbs[i] - 1;
+	}
+	for (j = 0; j < dev_rrbs[i]; j++) {
+	    cur_rrb = i | 0x8;
+	    cur_rrb = cur_rrb << (rrb_shift * 4);
+	    rrb_shift--;
+	    rrb_setting = rrb_setting | cur_rrb;
+	}
+    }
+
+    if (pcibr_soft)
+	s = pcibr_lock(pcibr_soft);
+
+    bridge->b_rrb_map[even_odd].reg = rrb_setting;
+
+    if (pcibr_soft) {
+
+	pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd;
+
+	/* since we've "FIXED" the allocations
+	 * for these slots, we probably can dispense
+	 * with tracking avail/res/valid data, but
+	 * keeping it up to date helps debugging.
+	 */
+
+	pcibr_soft->bs_rrb_avail[even_odd] =
+	    8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs);
+
+	pcibr_soft->bs_rrb_res[even_odd + 0] = 0;
+	pcibr_soft->bs_rrb_res[even_odd + 2] = 0;
+	pcibr_soft->bs_rrb_res[even_odd + 4] = 0;
+	pcibr_soft->bs_rrb_res[even_odd + 6] = 0;
+
+	pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1;
+	pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2;
+	pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3;
+	pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4;
+
+	pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1;
+	pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2;
+	pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3;
+	pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4;
+
+	pcibr_unlock(pcibr_soft, s);
+    }
+    return 0;
+}
+
+/*
+ *    pcibr_rrb_flush: chase down all the RRBs assigned
+ *      to the specified connection point, and flush
+ *      them.
+ */
+void
+pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    unsigned long           s;
+    reg_p                   rrbp;
+    unsigned                rrbm;
+    int                     i;
+    int                     rrbn;
+    unsigned                sval;
+    unsigned                mask;
+
+    sval = BRIDGE_RRB_EN | (pciio_slot >> 1);
+    mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV;
+    rrbn = pciio_slot & 1;
+    rrbp = &bridge->b_rrb_map[rrbn].reg;
+
+    s = pcibr_lock(pcibr_soft);
+    rrbm = *rrbp;
+    for (i = 0; i < 8; ++i) {
+	if ((rrbm & mask) == sval)
+	    do_pcibr_rrb_flush(bridge, rrbn);
+	rrbm >>= 4;
+	rrbn += 2;
+    }
+    pcibr_unlock(pcibr_soft, s);
+}
+
+/* =====================================================================
+ *    Device(x) register management
+ */
+
+/* pcibr_try_set_device: attempt to modify Device(x)
+ * for the specified slot on the specified bridge
+ * as requested in flags, limited to the specified
+ * bits. Returns which BRIDGE bits were in conflict,
+ * or ZERO if everything went OK.
+ *
+ * Caller MUST hold pcibr_lock when calling this function.
+ */
+LOCAL int
+pcibr_try_set_device(pcibr_soft_t pcibr_soft,
+		     pciio_slot_t slot,
+		     unsigned flags,
+		     bridgereg_t mask)
+{
+    bridge_t               *bridge;
+    pcibr_soft_slot_t       slotp;
+    bridgereg_t             old;
+    bridgereg_t             new;
+    bridgereg_t             chg;
+    bridgereg_t             bad;
+    bridgereg_t             badpmu;
+    bridgereg_t             badd32;
+    bridgereg_t             badd64;
+    bridgereg_t             fix;
+    unsigned long           s;
+    bridgereg_t             xmask;
+
+    xmask = mask;
+    if (pcibr_soft->bs_xbridge) {
+    	if (mask == BRIDGE_DEV_PMU_BITS)
+		xmask = XBRIDGE_DEV_PMU_BITS;
+	if (mask == BRIDGE_DEV_D64_BITS)
+		xmask = XBRIDGE_DEV_D64_BITS;
+    }
+
+    slotp = &pcibr_soft->bs_slot[slot];
+
+    s = pcibr_lock(pcibr_soft);
+
+    bridge = pcibr_soft->bs_base;
+
+    old = slotp->bss_device;
+
+    /* figure out what the desired
+     * Device(x) bits are based on
+     * the flags specified.
+     */
+
+    new = old;
+
+    /* Currently, we inherit anything that
+     * the new caller has not specified in
+     * one way or another, unless we take
+     * action here to not inherit.
+     *
+     * This is needed for the "swap" stuff,
+     * since it could have been set via
+     * pcibr_endian_set -- altho note that
+     * any explicit PCIBR_BYTE_STREAM or
+     * PCIBR_WORD_VALUES will freely override
+     * the effect of that call (and vice
+     * versa, no protection either way).
+     *
+     * I want to get rid of pcibr_endian_set
+     * in favor of tracking DMA endianness
+     * using the flags specified when DMA
+     * channels are created.
+     */
+
+#define	BRIDGE_DEV_WRGA_BITS	(BRIDGE_DEV_PMU_WRGA_EN | BRIDGE_DEV_DIR_WRGA_EN)
+#define	BRIDGE_DEV_SWAP_BITS	(BRIDGE_DEV_SWAP_PMU | BRIDGE_DEV_SWAP_DIR)
+
+    /* Do not use Barrier, Write Gather,
+     * or Prefetch unless asked.
+     * Leave everything else as it
+     * was from the last time.
+     */
+    new = new
+	& ~BRIDGE_DEV_BARRIER
+	& ~BRIDGE_DEV_WRGA_BITS
+	& ~BRIDGE_DEV_PREF
+	;
+
+    /* Generic macro flags
+     */
+    if (flags & PCIIO_DMA_DATA) {
+	new = (new
+            & ~BRIDGE_DEV_BARRIER)      /* barrier off */
+            | BRIDGE_DEV_PREF;          /* prefetch on */
+
+    }
+    if (flags & PCIIO_DMA_CMD) {
+        new = ((new
+            & ~BRIDGE_DEV_PREF)         /* prefetch off */
+            & ~BRIDGE_DEV_WRGA_BITS)    /* write gather off */
+            | BRIDGE_DEV_BARRIER;       /* barrier on */
+    }
+    /* Generic detail flags
+     */
+    if (flags & PCIIO_WRITE_GATHER)
+	new |= BRIDGE_DEV_WRGA_BITS;
+    if (flags & PCIIO_NOWRITE_GATHER)
+	new &= ~BRIDGE_DEV_WRGA_BITS;
+
+    if (flags & PCIIO_PREFETCH)
+	new |= BRIDGE_DEV_PREF;
+    if (flags & PCIIO_NOPREFETCH)
+	new &= ~BRIDGE_DEV_PREF;
+
+    if (flags & PCIBR_WRITE_GATHER)
+	new |= BRIDGE_DEV_WRGA_BITS;
+    if (flags & PCIBR_NOWRITE_GATHER)
+	new &= ~BRIDGE_DEV_WRGA_BITS;
+
+    if (flags & PCIIO_BYTE_STREAM)
+	new |= (pcibr_soft->bs_xbridge) ? 
+			BRIDGE_DEV_SWAP_DIR : BRIDGE_DEV_SWAP_BITS;
+    if (flags & PCIIO_WORD_VALUES)
+	new &= (pcibr_soft->bs_xbridge) ? 
+			~BRIDGE_DEV_SWAP_DIR : ~BRIDGE_DEV_SWAP_BITS;
+
+    /* Provider-specific flags
+     */
+    if (flags & PCIBR_PREFETCH)
+	new |= BRIDGE_DEV_PREF;
+    if (flags & PCIBR_NOPREFETCH)
+	new &= ~BRIDGE_DEV_PREF;
+
+    if (flags & PCIBR_PRECISE)
+	new |= BRIDGE_DEV_PRECISE;
+    if (flags & PCIBR_NOPRECISE)
+	new &= ~BRIDGE_DEV_PRECISE;
+
+    if (flags & PCIBR_BARRIER)
+	new |= BRIDGE_DEV_BARRIER;
+    if (flags & PCIBR_NOBARRIER)
+	new &= ~BRIDGE_DEV_BARRIER;
+
+    if (flags & PCIBR_64BIT)
+	new |= BRIDGE_DEV_DEV_SIZE;
+    if (flags & PCIBR_NO64BIT)
+	new &= ~BRIDGE_DEV_DEV_SIZE;
+
+    chg = old ^ new;				/* what are we changing, */
+    chg &= xmask;				/* of the interesting bits */
+
+    if (chg) {
+
+	badd32 = slotp->bss_d32_uctr ? (BRIDGE_DEV_D32_BITS & chg) : 0;
+	if (pcibr_soft->bs_xbridge) {
+		badpmu = slotp->bss_pmu_uctr ? (XBRIDGE_DEV_PMU_BITS & chg) : 0;
+		badd64 = slotp->bss_d64_uctr ? (XBRIDGE_DEV_D64_BITS & chg) : 0;
+	} else {
+		badpmu = slotp->bss_pmu_uctr ? (BRIDGE_DEV_PMU_BITS & chg) : 0;
+		badd64 = slotp->bss_d64_uctr ? (BRIDGE_DEV_D64_BITS & chg) : 0;
+	}
+	bad = badpmu | badd32 | badd64;
+
+	if (bad) {
+
+	    /* some conflicts can be resolved by
+	     * forcing the bit on. this may cause
+	     * some performance degredation in
+	     * the stream(s) that want the bit off,
+	     * but the alternative is not allowing
+	     * the new stream at all.
+	     */
+            if ( (fix = bad & (BRIDGE_DEV_PRECISE |
+                             BRIDGE_DEV_BARRIER)) ){
+		bad &= ~fix;
+		/* don't change these bits if
+		 * they are already set in "old"
+		 */
+		chg &= ~(fix & old);
+	    }
+	    /* some conflicts can be resolved by
+	     * forcing the bit off. this may cause
+	     * some performance degredation in
+	     * the stream(s) that want the bit on,
+	     * but the alternative is not allowing
+	     * the new stream at all.
+	     */
+	    if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS |
+			     BRIDGE_DEV_PREF)) ) {
+		bad &= ~fix;
+		/* don't change these bits if
+		 * we wanted to turn them on.
+		 */
+		chg &= ~(fix & new);
+	    }
+	    /* conflicts in other bits mean
+	     * we can not establish this DMA
+	     * channel while the other(s) are
+	     * still present.
+	     */
+	    if (bad) {
+		pcibr_unlock(pcibr_soft, s);
+#if (DEBUG && PCIBR_DEV_DEBUG)
+		printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits);
+#endif
+		return bad;
+	    }
+	}
+    }
+    if (mask == BRIDGE_DEV_PMU_BITS)
+	slotp->bss_pmu_uctr++;
+    if (mask == BRIDGE_DEV_D32_BITS)
+	slotp->bss_d32_uctr++;
+    if (mask == BRIDGE_DEV_D64_BITS)
+	slotp->bss_d64_uctr++;
+
+    /* the value we want to write is the
+     * original value, with the bits for
+     * our selected changes flipped, and
+     * with any disabled features turned off.
+     */
+    new = old ^ chg;			/* only change what we want to change */
+
+    if (slotp->bss_device == new) {
+	pcibr_unlock(pcibr_soft, s);
+	return 0;
+    }
+    bridge->b_device[slot].reg = new;
+    slotp->bss_device = new;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    pcibr_unlock(pcibr_soft, s);
+#if DEBUG && PCIBR_DEV_DEBUG
+    printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg);
+#endif
+
+    return 0;
+}
+
+void
+pcibr_release_device(pcibr_soft_t pcibr_soft,
+		     pciio_slot_t slot,
+		     bridgereg_t mask)
+{
+    pcibr_soft_slot_t       slotp;
+    unsigned long           s;
+
+    slotp = &pcibr_soft->bs_slot[slot];
+
+    s = pcibr_lock(pcibr_soft);
+
+    if (mask == BRIDGE_DEV_PMU_BITS)
+	slotp->bss_pmu_uctr--;
+    if (mask == BRIDGE_DEV_D32_BITS)
+	slotp->bss_d32_uctr--;
+    if (mask == BRIDGE_DEV_D64_BITS)
+	slotp->bss_d64_uctr--;
+
+    pcibr_unlock(pcibr_soft, s);
+}
+
+/*
+ * flush write gather buffer for slot
+ */
+LOCAL void
+pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft,
+              pciio_slot_t slot)
+{
+    bridge_t               *bridge;
+    unsigned long          s;
+    volatile uint32_t     wrf;
+    s = pcibr_lock(pcibr_soft);
+    bridge = pcibr_soft->bs_base;
+    wrf = bridge->b_wr_req_buf[slot].reg;
+    pcibr_unlock(pcibr_soft, s);
+}
+
+/* =====================================================================
+ *    Bridge (pcibr) "Device Driver" entry points
+ */
+
+/*
+ * pcibr_probe_slot: read a config space word
+ * while trapping any errors; reutrn zero if
+ * all went OK, or nonzero if there was an error.
+ * The value read, if any, is passed back
+ * through the valp parameter.
+ */
+LOCAL int
+pcibr_probe_slot(bridge_t *bridge,
+		 cfg_p cfg,
+		 unsigned *valp)
+{
+    int                     rv;
+    bridgereg_t             old_enable, new_enable;
+    int badaddr_val(volatile void *, int, volatile void *);
+
+
+    old_enable = bridge->b_int_enable;
+    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
+
+    bridge->b_int_enable = new_enable;
+
+	/*
+	 * The xbridge doesn't clear b_err_int_view unless
+	 * multi-err is cleared...
+	 */
+	if (is_xbridge(bridge))
+	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
+		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
+	    }
+
+    if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
+	bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
+	(void) bridge->b_wid_tflush;	/* flushbus */
+    }
+    rv = badaddr_val((void *) cfg, 4, valp);
+
+	/*
+	 * The xbridge doesn't set master timeout in b_int_status
+	 * here.  Fortunately it's in error_interrupt_view.
+	 */
+	if (is_xbridge(bridge))
+	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
+		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
+		rv = 1;		/* unoccupied slot */
+	    }
+
+    bridge->b_int_enable = old_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+
+    return rv;
+}
+
+/*
+ *    pcibr_init: called once during system startup or
+ *      when a loadable driver is loaded.
+ *
+ *      The driver_register function should normally
+ *      be in _reg, not _init.  But the pcibr driver is
+ *      required by devinit before the _reg routines
+ *      are called, so this is an exception.
+ */
+void
+pcibr_init(void)
+{
+#if DEBUG && ATTACH_DEBUG
+    printk("pcibr_init\n");
+#endif
+
+    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
+			    XBRIDGE_WIDGET_MFGR_NUM,
+			    "pcibr_",
+			    0);
+    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
+			    BRIDGE_WIDGET_MFGR_NUM,
+			    "pcibr_",
+			    0);
+}
+
+/*
+ * open/close mmap/munmap interface would be used by processes
+ * that plan to map the PCI bridge, and muck around with the
+ * registers. This is dangerous to do, and will be allowed
+ * to a select brand of programs. Typically these are
+ * diagnostics programs, or some user level commands we may
+ * write to do some weird things.
+ * To start with expect them to have root priveleges.
+ * We will ask for more later.
+ */
+/* ARGSUSED */
+int
+pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
+{
+    return 0;
+}
+
+/*ARGSUSED */
+int
+pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
+{
+    return 0;
+}
+
+/*ARGSUSED */
+int
+pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
+{
+    int                     error;
+    devfs_handle_t            vhdl = dev_to_vhdl(dev);
+    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+
+    hwgraph_vertex_unref(pcibr_vhdl);
+
+    ASSERT(pcibr_soft);
+    len = ctob(btoc(len));		/* Make len page aligned */
+    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
+
+    /*
+     * If the offset being mapped corresponds to the flash prom
+     * base, and if the mapping succeeds, and if the user
+     * has requested the protections to be WRITE, enable the
+     * flash prom to be written.
+     *
+     * XXX- deprecate this in favor of using the
+     * real flash driver ...
+     */
+    if (!error &&
+	((off == BRIDGE_EXTERNAL_FLASH) ||
+	 (len > BRIDGE_EXTERNAL_FLASH))) {
+	int                     s;
+
+	/*
+	 * ensure that we write and read without any interruption.
+	 * The read following the write is required for the Bridge war
+	 */
+	s = splhi();
+	bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
+	bridge->b_wid_control;		/* inval addr bug war */
+	splx(s);
+    }
+    return error;
+}
+
+/*ARGSUSED */
+int
+pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
+{
+    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+
+    hwgraph_vertex_unref(pcibr_vhdl);
+
+    /*
+     * If flashprom write was enabled, disable it, as
+     * this is the last unmap.
+     */
+    if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
+	int                     s;
+
+	/*
+	 * ensure that we write and read without any interruption.
+	 * The read following the write is required for the Bridge war
+	 */
+	s = splhi();
+	bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
+	bridge->b_wid_control;		/* inval addr bug war */
+	splx(s);
+    }
+    return 0;
+}
+
+/* This is special case code used by grio. There are plans to make
+ * this a bit more general in the future, but till then this should
+ * be sufficient.
+ */
+pciio_slot_t
+pcibr_device_slot_get(devfs_handle_t dev_vhdl)
+{
+    char                    devname[MAXDEVNAME];
+    devfs_handle_t            tdev;
+    pciio_info_t            pciio_info;
+    pciio_slot_t            slot = PCIIO_SLOT_NONE;
+
+    vertex_to_name(dev_vhdl, devname, MAXDEVNAME);
+
+    /* run back along the canonical path
+     * until we find a PCI connection point.
+     */
+    tdev = hwgraph_connectpt_get(dev_vhdl);
+    while (tdev != GRAPH_VERTEX_NONE) {
+	pciio_info = pciio_info_chk(tdev);
+	if (pciio_info) {
+	    slot = pciio_info_slot_get(pciio_info);
+	    break;
+	}
+	hwgraph_vertex_unref(tdev);
+	tdev = hwgraph_connectpt_get(tdev);
+    }
+    hwgraph_vertex_unref(tdev);
+
+    return slot;
+}
+
+/*==========================================================================
+ *	BRIDGE PCI SLOT RELATED IOCTLs
+ */
+char *pci_space_name[] = {"NONE", 
+			  "ROM",
+			  "IO",
+			  "",
+			  "MEM",
+			  "MEM32",
+			  "MEM64",
+			  "CFG",
+			  "WIN0",
+			  "WIN1",
+			  "WIN2",
+			  "WIN3",
+			  "WIN4",
+			  "WIN5",
+			  "",
+			  "BAD"};
+
+
+#ifdef LATER
+
+void
+pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh,
+                            int func,
+                            pcibr_slot_func_info_resp_t funcp)
+{
+    pcibr_info_t                 pcibr_info = pcibr_infoh[func];
+    int                          win;
+
+    funcp->resp_f_status = 0;
+
+    if (!pcibr_info) {
+        return;
+    }
+
+    funcp->resp_f_status |= FUNC_IS_VALID;
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
+#else
+    sprintf(funcp->resp_f_slot_name, "%x", pcibr_info->f_vertex);
+#endif
+
+    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {
+        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;
+    }
+
+    funcp->resp_f_bus = pcibr_info->f_bus;
+    funcp->resp_f_slot = pcibr_info->f_slot;
+    funcp->resp_f_func = pcibr_info->f_func;
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);
+#else
+    sprintf(funcp->resp_f_master_name, "%x", pcibr_info->f_master);
+#endif
+    funcp->resp_f_pops = pcibr_info->f_pops;
+    funcp->resp_f_efunc = pcibr_info->f_efunc;
+    funcp->resp_f_einfo = pcibr_info->f_einfo;
+
+    funcp->resp_f_vendor = pcibr_info->f_vendor;
+    funcp->resp_f_device = pcibr_info->f_device;
+
+    for(win = 0 ; win < 6 ; win++) {
+        funcp->resp_f_window[win].resp_w_base =
+                                  pcibr_info->f_window[win].w_base;
+        funcp->resp_f_window[win].resp_w_size =
+                                  pcibr_info->f_window[win].w_size;
+        sprintf(funcp->resp_f_window[win].resp_w_space,
+                "%s",
+                pci_space_name[pcibr_info->f_window[win].w_space]);
+    }
+
+    funcp->resp_f_rbase = pcibr_info->f_rbase;
+    funcp->resp_f_rsize = pcibr_info->f_rsize;
+
+    for (win = 0 ; win < 4; win++) {
+        funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];
+    }
+
+    funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;
+
+}
+
+int
+pcibr_slot_info_return(pcibr_soft_t             pcibr_soft,
+                       pciio_slot_t             slot,
+                       pcibr_slot_info_resp_t   respp)
+{
+    pcibr_soft_slot_t            pss;
+    int                          func;
+    bridge_t                    *bridge = pcibr_soft->bs_base;
+    reg_p                        b_respp;
+    pcibr_slot_info_resp_t       slotp;
+    pcibr_slot_func_info_resp_t  funcp;
+
+    slotp = snia_kmem_zalloc(sizeof(*slotp), KM_SLEEP);
+    if (slotp == NULL) {
+        return(ENOMEM);
+    }
+
+    pss = &pcibr_soft->bs_slot[slot];
+    
+    printk("\nPCI INFRASTRUCTURAL INFO FOR SLOT %d\n\n", slot);
+
+    slotp->resp_has_host = pss->has_host;
+    slotp->resp_host_slot = pss->host_slot;
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    sprintf(slotp->resp_slot_conn_name, "%v", pss->slot_conn);
+#else
+    sprintf(slotp->resp_slot_conn_name, "%x", pss->slot_conn);
+#endif
+    slotp->resp_slot_status = pss->slot_status;
+    slotp->resp_l1_bus_num = io_path_map_widget(pcibr_soft->bs_vhdl);
+
+    if (is_sys_critical_vertex(pss->slot_conn)) {
+        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;
+    }
+
+    slotp->resp_bss_ninfo = pss->bss_ninfo;
+
+    for (func = 0; func < pss->bss_ninfo; func++) {
+        funcp = &(slotp->resp_func[func]);
+        pcibr_slot_func_info_return(pss->bss_infos, func, funcp);
+    }
+
+    sprintf(slotp->resp_bss_devio_bssd_space, "%s",
+            pci_space_name[pss->bss_devio.bssd_space]);
+    slotp->resp_bss_devio_bssd_base = pss->bss_devio.bssd_base;
+    slotp->resp_bss_device = pss->bss_device;
+
+    slotp->resp_bss_pmu_uctr = pss->bss_pmu_uctr;
+    slotp->resp_bss_d32_uctr = pss->bss_d32_uctr;
+    slotp->resp_bss_d64_uctr = pss->bss_d64_uctr;
+
+    slotp->resp_bss_d64_base = pss->bss_d64_base;
+    slotp->resp_bss_d64_flags = pss->bss_d64_flags;
+    slotp->resp_bss_d32_base = pss->bss_d32_base;
+    slotp->resp_bss_d32_flags = pss->bss_d32_flags;
+
+    slotp->resp_bss_ext_ates_active = atomic_read(&pss->bss_ext_ates_active);
+
+    slotp->resp_bss_cmd_pointer = pss->bss_cmd_pointer;
+    slotp->resp_bss_cmd_shadow = pss->bss_cmd_shadow;
+
+    slotp->resp_bs_rrb_valid = pcibr_soft->bs_rrb_valid[slot];
+    slotp->resp_bs_rrb_valid_v = pcibr_soft->bs_rrb_valid[slot +
+                                                      PCIBR_RRB_SLOT_VIRTUAL];
+    slotp->resp_bs_rrb_res = pcibr_soft->bs_rrb_res[slot];
+
+    if (slot & 1) {
+        b_respp = &bridge->b_odd_resp;
+    } else {
+        b_respp = &bridge->b_even_resp;
+    }
+
+    slotp->resp_b_resp = *b_respp;
+
+    slotp->resp_b_int_device = bridge->b_int_device;
+    slotp->resp_b_int_enable = bridge->b_int_enable;
+    slotp->resp_b_int_host = bridge->b_int_addr[slot].addr;
+
+    if (COPYOUT(slotp, respp, sizeof(*respp))) {
+        return(EFAULT);
+    }
+
+    snia_kmem_free(slotp, sizeof(*slotp));
+
+    return(0);
+}
+
+/*
+ * pcibr_slot_query
+ *	Return information about the PCI slot maintained by the infrastructure.
+ *	Information is requested in the request structure.
+ *
+ *      Information returned in the response structure:
+ *		Slot hwgraph name
+ *		Vendor/Device info
+ *		Base register info
+ *		Interrupt mapping from device pins to the bridge pins
+ *		Devio register
+ *		Software RRB info
+ *		RRB register info
+ *		Host/Gues info
+ *		PCI Bus #,slot #, function #
+ *		Slot provider hwgraph name
+ *		Provider Functions
+ *		Error handler
+ *		DMA mapping usage counters
+ *		DMA direct translation info
+ *		External SSRAM workaround info
+ */
+int
+pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_info_req_t reqp)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    pciio_slot_t            slot = reqp->req_slot;
+    pciio_slot_t            tmp_slot;
+    pcibr_slot_info_resp_t  respp = (pcibr_slot_info_resp_t) reqp->req_respp;
+    int                     size = reqp->req_size;
+    int                     error;
+
+    /* Make sure that we are dealing with a bridge device vertex */
+    if (!pcibr_soft) {
+        return(EINVAL);
+    }
+
+    /* Make sure that we have a valid PCI slot number or PCIIO_SLOT_NONE */
+    if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE)) {
+        return(EINVAL);
+    }
+
+    /* Return information for the requested PCI slot */
+    if (slot != PCIIO_SLOT_NONE) {
+        if (size < sizeof(*respp)) {
+            return(EINVAL);
+        }
+
+        /* Acquire read access to the slot */
+        mrlock(pcibr_soft->bs_slot[slot].slot_lock, MR_ACCESS, PZERO);
+
+        error = pcibr_slot_info_return(pcibr_soft, slot, respp);
+
+        /* Release the slot lock */
+        mrunlock(pcibr_soft->bs_slot[slot].slot_lock);
+
+        return(error);
+    }
+
+    /* Return information for all the slots */
+    for (tmp_slot = 0; tmp_slot < 8; tmp_slot++) {
+
+        if (size < sizeof(*respp)) {
+            return(EINVAL);
+        }
+
+        /* Acquire read access to the slot */
+        mrlock(pcibr_soft->bs_slot[tmp_slot].slot_lock, MR_ACCESS, PZERO);
+
+        error = pcibr_slot_info_return(pcibr_soft, tmp_slot, respp);
+
+        /* Release the slot lock */
+        mrunlock(pcibr_soft->bs_slot[tmp_slot].slot_lock);
+
+        if (error) {
+            return(error);
+        }
+
+        ++respp;
+        size -= sizeof(*respp);
+    }
+
+    return(error);
+}
+#endif	/* LATER */
+
+
+/*ARGSUSED */
+int
+pcibr_ioctl(devfs_handle_t dev,
+	    int cmd,
+	    void *arg,
+	    int flag,
+	    struct cred *cr,
+	    int *rvalp)
+{
+    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);
+#ifdef LATER
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+#endif
+    int                     error = 0;
+
+    hwgraph_vertex_unref(pcibr_vhdl);
+
+    switch (cmd) {
+#ifdef LATER
+    case GIOCSETBW:
+	{
+	    grio_ioctl_info_t       info;
+	    pciio_slot_t            slot = 0;
+
+	    if (!cap_able((uint64_t)CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
+		error = EFAULT;
+		break;
+	    }
+#ifdef GRIO_DEBUG
+	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
+		    info.prev_vhdl, info.reqbw);
+#endif				/* GRIO_DEBUG */
+
+	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
+		PCIIO_SLOT_NONE) {
+		error = EIO;
+		break;
+	    }
+	    if (info.reqbw)
+		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH);
+	    break;
+	}
+
+    case GIOCRELEASEBW:
+	{
+	    grio_ioctl_info_t       info;
+	    pciio_slot_t            slot = 0;
+
+	    if (!cap_able(CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
+		error = EFAULT;
+		break;
+	    }
+#ifdef GRIO_DEBUG
+	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
+		    info.prev_vhdl, info.reqbw);
+#endif				/* GRIO_DEBUG */
+
+	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
+		PCIIO_SLOT_NONE) {
+		error = EIO;
+		break;
+	    }
+	    if (info.reqbw)
+		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);
+	    break;
+	}
+
+    case PCIBR_SLOT_POWERUP:
+	{
+	    pciio_slot_t	slot;
+
+	    if (!cap_able(CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+
+	    slot = (pciio_slot_t)(uint64_t)arg;
+	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
+	    break;
+	}
+    case PCIBR_SLOT_SHUTDOWN:
+	    if (!cap_able(CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+
+	    slot = (pciio_slot_t)(uint64_t)arg;
+	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
+	    break;
+	}
+    case PCIBR_SLOT_QUERY:
+	{
+	    struct pcibr_slot_info_req_s        req;
+
+	    if (!cap_able(CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+
+            if (COPYIN(arg, &req, sizeof(req))) {
+                error = EFAULT;
+                break;
+            }
+
+            error = pcibr_slot_query(pcibr_vhdl, &req);
+	    break;
+	}
+#endif	/* LATER */
+    default:
+	break;
+
+    }
+
+    return error;
+}
+
+void
+pcibr_freeblock_sub(iopaddr_t *free_basep,
+		    iopaddr_t *free_lastp,
+		    iopaddr_t base,
+		    size_t size)
+{
+    iopaddr_t               free_base = *free_basep;
+    iopaddr_t               free_last = *free_lastp;
+    iopaddr_t               last = base + size - 1;
+
+    if ((last < free_base) || (base > free_last));	/* free block outside arena */
+
+    else if ((base <= free_base) && (last >= free_last))
+	/* free block contains entire arena */
+	*free_basep = *free_lastp = 0;
+
+    else if (base <= free_base)
+	/* free block is head of arena */
+	*free_basep = last + 1;
+
+    else if (last >= free_last)
+	/* free block is tail of arena */
+	*free_lastp = base - 1;
+
+    /*
+     * We are left with two regions: the free area
+     * in the arena "below" the block, and the free
+     * area in the arena "above" the block. Keep
+     * the one that is bigger.
+     */
+
+    else if ((base - free_base) > (free_last - last))
+	*free_lastp = base - 1;		/* keep lower chunk */
+    else
+	*free_basep = last + 1;		/* keep upper chunk */
+}
+
+/* Convert from ssram_bits in control register to number of SSRAM entries */
+#define ATE_NUM_ENTRIES(n) _ate_info[n]
+
+/* Possible choices for number of ATE entries in Bridge's SSRAM */
+LOCAL int               _ate_info[] =
+{
+    0,					/* 0 entries */
+    8 * 1024,				/* 8K entries */
+    16 * 1024,				/* 16K entries */
+    64 * 1024				/* 64K entries */
+};
+
+#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))
+#define ATE_PROBE_VALUE 0x0123456789abcdefULL
+
+/*
+ * Determine the size of this bridge's external mapping SSRAM, and set
+ * the control register appropriately to reflect this size, and initialize
+ * the external SSRAM.
+ */
+LOCAL int
+pcibr_init_ext_ate_ram(bridge_t *bridge)
+{
+    int                     largest_working_size = 0;
+    int                     num_entries, entry;
+    int                     i, j;
+    bridgereg_t             old_enable, new_enable;
+    int                     s;
+
+    /* Probe SSRAM to determine its size. */
+    old_enable = bridge->b_int_enable;
+    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
+    bridge->b_int_enable = new_enable;
+
+    for (i = 1; i < ATE_NUM_SIZES; i++) {
+	/* Try writing a value */
+	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
+
+	/* Guard against wrap */
+	for (j = 1; j < i; j++)
+	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
+
+	/* See if value was written */
+	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
+	    largest_working_size = i;
+    }
+    bridge->b_int_enable = old_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+
+    /*
+     * ensure that we write and read without any interruption.
+     * The read following the write is required for the Bridge war
+     */
+
+    s = splhi();
+    bridge->b_wid_control = (bridge->b_wid_control
+	& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
+	| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
+    bridge->b_wid_control;		/* inval addr bug war */
+    splx(s);
+
+    num_entries = ATE_NUM_ENTRIES(largest_working_size);
+
+#if PCIBR_ATE_DEBUG
+    if (num_entries)
+	printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries);
+    else
+	printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge);
+#endif
+
+    /* Initialize external mapping entries */
+    for (entry = 0; entry < num_entries; entry++)
+	bridge->b_ext_ate_ram[entry] = 0;
+
+    return (num_entries);
+}
+
+/*
+ * Allocate "count" contiguous Bridge Address Translation Entries
+ * on the specified bridge to be used for PCI to XTALK mappings.
+ * Indices in rm map range from 1..num_entries.  Indicies returned
+ * to caller range from 0..num_entries-1.
+ *
+ * Return the start index on success, -1 on failure.
+ */
+LOCAL int
+pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
+{
+    int                     index = 0;
+
+    index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
+/* printk("Colin: pcibr_ate_alloc - index %d count %d \n", index, count); */
+
+    if (!index && pcibr_soft->bs_ext_ate_map)
+	index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
+
+    /* rmalloc manages resources in the 1..n
+     * range, with 0 being failure.
+     * pcibr_ate_alloc manages resources
+     * in the 0..n-1 range, with -1 being failure.
+     */
+    return index - 1;
+}
+
+LOCAL void
+pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
+/* Who says there's no such thing as a free meal? :-) */
+{
+    /* note the "+1" since rmalloc handles 1..n but
+     * we start counting ATEs at zero.
+     */
+/* printk("Colin: pcibr_ate_free - index %d count %d\n", index, count); */
+
+    rmfree((index < pcibr_soft->bs_int_ate_size)
+	   ? pcibr_soft->bs_int_ate_map
+	   : pcibr_soft->bs_ext_ate_map,
+	   count, index + 1);
+}
+
+LOCAL pcibr_info_t
+pcibr_info_get(devfs_handle_t vhdl)
+{
+    return (pcibr_info_t) pciio_info_get(vhdl);
+}
+
+pcibr_info_t
+pcibr_device_info_new(
+			 pcibr_soft_t pcibr_soft,
+			 pciio_slot_t slot,
+			 pciio_function_t rfunc,
+			 pciio_vendor_id_t vendor,
+			 pciio_device_id_t device)
+{
+    pcibr_info_t            pcibr_info;
+    pciio_function_t        func;
+    int                     ibit;
+
+    func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc;
+
+    NEW(pcibr_info);
+    pciio_device_info_new(&pcibr_info->f_c,
+			  pcibr_soft->bs_vhdl,
+			  slot, rfunc,
+			  vendor, device);
+
+    if (slot != PCIIO_SLOT_NONE) {
+
+	/*
+	 * Currently favored mapping from PCI
+	 * slot number and INTA/B/C/D to Bridge
+	 * PCI Interrupt Bit Number:
+	 *
+	 *     SLOT     A B C D
+	 *      0       0 4 0 4
+	 *      1       1 5 1 5
+	 *      2       2 6 2 6
+	 *      3       3 7 3 7
+	 *      4       4 0 4 0
+	 *      5       5 1 5 1
+	 *      6       6 2 6 2
+	 *      7       7 3 7 3
+	 *
+	 * XXX- allow pcibr_hints to override default
+	 * XXX- allow ADMIN to override pcibr_hints
+	 */
+	for (ibit = 0; ibit < 4; ++ibit)
+	    pcibr_info->f_ibit[ibit] =
+		(slot + 4 * ibit) & 7;
+
+	/*
+	 * Record the info in the sparse func info space.
+	 */
+	if (func < pcibr_soft->bs_slot[slot].bss_ninfo)
+	    pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info;
+    }
+    return pcibr_info;
+}
+
+void
+pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
+{
+    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    pcibr_info_t	pcibr_info;
+    pciio_function_t	func;
+    pcibr_soft_slot_t	slotp = &pcibr_soft->bs_slot[slot];
+    int			nfunc = slotp->bss_ninfo;
+
+
+    for (func = 0; func < nfunc; func++) {
+	pcibr_info = slotp->bss_infos[func];
+
+	if (!pcibr_info) 
+	    continue;
+
+	slotp->bss_infos[func] = 0;
+	pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);
+	pciio_device_info_free(&pcibr_info->f_c);
+	DEL(pcibr_info);
+    }
+
+    /* Clear the DEVIO(x) for this slot */
+    slotp->bss_devio.bssd_space = PCIIO_SPACE_NONE;
+    slotp->bss_devio.bssd_base = PCIBR_D32_BASE_UNSET;
+    slotp->bss_device  = 0;
+
+    
+    /* Reset the mapping usage counters */
+    slotp->bss_pmu_uctr = 0;
+    slotp->bss_d32_uctr = 0;
+    slotp->bss_d64_uctr = 0;
+
+    /* Clear the Direct translation info */
+    slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;
+    slotp->bss_d64_flags = 0;
+    slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;
+    slotp->bss_d32_flags = 0;
+
+    /* Clear out shadow info necessary for the external SSRAM workaround */
+    slotp->bss_ext_ates_active = ATOMIC_INIT(0);
+    slotp->bss_cmd_pointer = 0;
+    slotp->bss_cmd_shadow = 0;
+
+}
+
+/* 
+ * PCI_ADDR_SPACE_LIMITS_LOAD
+ *	Gets the current values of 
+ *		pci io base, 
+ *		pci io last,
+ *		pci low memory base,
+ *		pci low memory last,
+ *		pci high memory base,
+ * 		pci high memory last
+ */
+#define PCI_ADDR_SPACE_LIMITS_LOAD()			\
+    pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base;	\
+    pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last;	\
+    pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base;	\
+    pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last;	\
+    pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base;	\
+    pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last;
+/*
+ * PCI_ADDR_SPACE_LIMITS_STORE
+ *	Sets the current values of
+ *		pci io base, 
+ *		pci io last,
+ *		pci low memory base,
+ *		pci low memory last,
+ *		pci high memory base,
+ * 		pci high memory last
+ */
+#define PCI_ADDR_SPACE_LIMITS_STORE()			\
+    pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;	\
+    pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;	\
+    pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;	\
+    pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;	\
+    pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;	\
+    pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;
+
+#define PCI_ADDR_SPACE_LIMITS_PRINT()			\
+    printf("+++++++++++++++++++++++\n"			\
+	   "IO base 0x%x last 0x%x\n"			\
+	   "SWIN base 0x%x last 0x%x\n"			\
+	   "MEM base 0x%x last 0x%x\n"			\
+	   "+++++++++++++++++++++++\n",			\
+	   pcibr_soft->bs_spinfo.pci_io_base,		\
+	   pcibr_soft->bs_spinfo.pci_io_last,		\
+	   pcibr_soft->bs_spinfo.pci_swin_base,		\
+	   pcibr_soft->bs_spinfo.pci_swin_last,		\
+	   pcibr_soft->bs_spinfo.pci_mem_base,		\
+	   pcibr_soft->bs_spinfo.pci_mem_last);
+
+/*
+ * pcibr_slot_info_init
+ *	Probe for this slot and see if it is populated.
+ *	If it is populated initialize the generic PCI infrastructural
+ * 	information associated with this particular PCI device.
+ */
+int
+pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
+		     pciio_slot_t 	slot)
+{
+    pcibr_soft_t	    pcibr_soft;
+    pcibr_info_h	    pcibr_infoh;
+    pcibr_info_t	    pcibr_info;
+    bridge_t		   *bridge;
+    cfg_p                   cfgw;
+    unsigned                idword;
+    unsigned                pfail;
+    unsigned                idwords[8];
+    pciio_vendor_id_t       vendor;
+    pciio_device_id_t       device;
+    unsigned                htype;
+    cfg_p                   wptr;
+    int                     win;
+    pciio_space_t           space;
+    iopaddr_t		    pci_io_fb,	pci_io_fl;
+    iopaddr_t		    pci_lo_fb,  pci_lo_fl;
+    iopaddr_t		    pci_hi_fb,  pci_hi_fl;
+    int			    nfunc;
+    pciio_function_t	    rfunc;
+    int			    func;
+    devfs_handle_t	    conn_vhdl;
+    pcibr_soft_slot_t	    slotp;
+    
+    /* Get the basic software information required to proceed */
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    if (!pcibr_soft)
+	return(EINVAL);
+
+    bridge = pcibr_soft->bs_base;
+    if (!PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization
+     * is done by the host slot then we are done.
+     */
+    if (pcibr_soft->bs_slot[slot].has_host) {
+	return(0);    
+    }
+
+    /* Check for a slot with any system critical functions */
+    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
+        return(EPERM);
+
+    /* Load the current values of allocated PCI address spaces */
+    PCI_ADDR_SPACE_LIMITS_LOAD();
+    
+    /* Try to read the device-id/vendor-id from the config space */
+    cfgw = bridge->b_type0_cfg_dev[slot].l;
+
+    if (pcibr_probe_slot(bridge, cfgw, &idword)) 
+	return(ENODEV);
+
+    slotp = &pcibr_soft->bs_slot[slot];
+    slotp->slot_status |= SLOT_POWER_UP;
+
+    vendor = 0xFFFF & idword;
+    /* If the vendor id is not valid then the slot is not populated
+     * and we are done.
+     */
+    if (vendor == 0xFFFF) 
+	return(ENODEV);			
+    
+    device = 0xFFFF & (idword >> 16);
+    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
+
+    nfunc = 1;
+    rfunc = PCIIO_FUNC_NONE;
+    pfail = 0;
+
+    /* NOTE: if a card claims to be multifunction
+     * but only responds to config space 0, treat
+     * it as a unifunction card.
+     */
+
+    if (htype & 0x80) {		/* MULTIFUNCTION */
+	for (func = 1; func < 8; ++func) {
+	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
+	    if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) {
+		pfail |= 1 << func;
+		continue;
+	    }
+	    vendor = 0xFFFF & idwords[func];
+	    if (vendor == 0xFFFF) {
+		pfail |= 1 << func;
+		continue;
+	    }
+	    nfunc = func + 1;
+	    rfunc = 0;
+	}
+	cfgw = bridge->b_type0_cfg_dev[slot].l;
+    }
+    NEWA(pcibr_infoh, nfunc);
+    
+    pcibr_soft->bs_slot[slot].bss_ninfo = nfunc;
+    pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
+
+    for (func = 0; func < nfunc; ++func) {
+	unsigned                cmd_reg;
+	
+	if (func) {
+	    if (pfail & (1 << func))
+		continue;
+	    
+	    idword = idwords[func];
+	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
+	    
+	    device = 0xFFFF & (idword >> 16);
+	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
+	    rfunc = func;
+	}
+	htype &= 0x7f;
+	if (htype != 0x00) {
+	    printk(KERN_WARNING  "%s pcibr: pci slot %d func %d has strange header type 0x%x\n",
+		    pcibr_soft->bs_name, slot, func, htype);
+	    continue;
+	}
+#if DEBUG && ATTACH_DEBUG
+	printk(KERN_NOTICE   
+		"%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x",
+		pcibr_soft->bs_name, slot, func, vendor, device);
+#endif	
+
+	pcibr_info = pcibr_device_info_new
+	    (pcibr_soft, slot, rfunc, vendor, device);
+	conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
+	if (func == 0)
+	    slotp->slot_conn = conn_vhdl;
+
+#ifdef LITTLE_ENDIAN
+	cmd_reg = cfgw[(PCI_CFG_COMMAND ^ 4) / 4];
+#else
+	cmd_reg = cfgw[PCI_CFG_COMMAND / 4];
+#endif
+	
+	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
+
+	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) {
+	    iopaddr_t               base, mask, code;
+	    size_t                  size;
+
+	    /*
+	     * GET THE BASE & SIZE OF THIS WINDOW:
+	     *
+	     * The low two or four bits of the BASE register
+	     * determines which address space we are in; the
+	     * rest is a base address. BASE registers
+	     * determine windows that are power-of-two sized
+	     * and naturally aligned, so we can get the size
+	     * of a window by writing all-ones to the
+	     * register, reading it back, and seeing which
+	     * bits are used for decode; the least
+	     * significant nonzero bit is also the size of
+	     * the window.
+	     *
+	     * WARNING: someone may already have allocated
+	     * some PCI space to this window, and in fact
+	     * PIO may be in process at this very moment
+	     * from another processor (or even from this
+	     * one, if we get interrupted)! So, if the BASE
+	     * already has a nonzero address, be generous
+	     * and use the LSBit of that address as the
+	     * size; this could overstate the window size.
+	     * Usually, when one card is set up, all are set
+	     * up; so, since we don't bitch about
+	     * overlapping windows, we are ok.
+	     *
+	     * UNFORTUNATELY, some cards do not clear their
+	     * BASE registers on reset. I have two heuristics
+	     * that can detect such cards: first, if the
+	     * decode enable is turned off for the space
+	     * that the window uses, we can disregard the
+	     * initial value. second, if the address is
+	     * outside the range that we use, we can disregard
+	     * it as well.
+	     *
+	     * This is looking very PCI generic. Except for
+	     * knowing how many slots and where their config
+	     * spaces are, this window loop and the next one
+	     * could probably be shared with other PCI host
+	     * adapters. It would be interesting to see if
+	     * this could be pushed up into pciio, when we
+	     * start supporting more PCI providers.
+	     */
+#ifdef LITTLE_ENDIAN
+	    base = wptr[((win*4)^4)/4];
+#else
+	    base = wptr[win];
+#endif
+
+	    if (base & PCI_BA_IO_SPACE) {
+		/* BASE is in I/O space. */
+		space = PCIIO_SPACE_IO;
+		mask = -4;
+		code = base & 3;
+		base = base & mask;
+		if (base == 0) {
+		    ;		/* not assigned */
+		} else if (!(cmd_reg & PCI_CMD_IO_SPACE)) {
+		    base = 0;	/* decode not enabled */
+		}
+	    } else {
+		/* BASE is in MEM space. */
+		space = PCIIO_SPACE_MEM;
+		mask = -16;
+		code = base & PCI_BA_MEM_LOCATION;	/* extract BAR type */
+		base = base & mask;
+		if (base == 0) {
+		    ;		/* not assigned */
+		} else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) {
+		    base = 0;	/* decode not enabled */
+		} else if (base & 0xC0000000) {
+		    base = 0;	/* outside permissable range */
+		} else if ((code == PCI_BA_MEM_64BIT) &&
+#ifdef LITTLE_ENDIAN
+			   (wptr[(((win + 1)*4)^4)/4] != 0)) {
+#else 
+			   (wptr[win + 1] != 0)) {
+#endif /* LITTLE_ENDIAN */
+		    base = 0;	/* outside permissable range */
+		}
+	    }
+
+	    if (base != 0) {	/* estimate size */
+		size = base & -base;
+	    } else {		/* calculate size */
+#ifdef LITTLE_ENDIAN
+		wptr[((win*4)^4)/4] = ~0;	/* turn on all bits */
+		size = wptr[((win*4)^4)/4];	/* get stored bits */
+#else 
+		wptr[win] = ~0;	/* turn on all bits */
+		size = wptr[win];	/* get stored bits */
+#endif /* LITTLE_ENDIAN */
+		size &= mask;	/* keep addr */
+		size &= -size;	/* keep lsbit */
+		if (size == 0)
+		    continue;
+	    }	
+
+	    pcibr_info->f_window[win].w_space = space;
+	    pcibr_info->f_window[win].w_base = base;
+	    pcibr_info->f_window[win].w_size = size;
+
+	    /*
+	     * If this window already has PCI space
+	     * allocated for it, "subtract" that space from
+	     * our running freeblocks. Don't worry about
+	     * overlaps in existing allocated windows; we
+	     * may be overstating their sizes anyway.
+	     */
+
+	    if (base && size) {
+		if (space == PCIIO_SPACE_IO) {
+		    pcibr_freeblock_sub(&pci_io_fb,
+					&pci_io_fl,
+					base, size);
+		} else {
+		    pcibr_freeblock_sub(&pci_lo_fb,
+					&pci_lo_fl,
+					base, size);
+		    pcibr_freeblock_sub(&pci_hi_fb,
+					&pci_hi_fl,
+					base, size);
+		}	
+	    }
+#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
+	    /*
+	     * IOC3 BASE_ADDR* BUG WORKAROUND
+	     *
+	     
+	     * If we write to BASE1 on the IOC3, the
+	     * data in BASE0 is replaced. The
+	     * original workaround was to remember
+	     * the value of BASE0 and restore it
+	     * when we ran off the end of the BASE
+	     * registers; however, a later
+	     * workaround was added (I think it was
+	     * rev 1.44) to avoid setting up
+	     * anything but BASE0, with the comment
+	     * that writing all ones to BASE1 set
+	     * the enable-parity-error test feature
+	     * in IOC3's SCR bit 14.
+	     *
+	     * So, unless we defer doing any PCI
+	     * space allocation until drivers
+	     * attach, and set up a way for drivers
+	     * (the IOC3 in paricular) to tell us
+	     * generically to keep our hands off
+	     * BASE registers, we gotta "know" about
+	     * the IOC3 here.
+	     *
+	     * Too bad the PCI folks didn't reserve the
+	     * all-zero value for 'no BASE here' (it is a
+	     * valid code for an uninitialized BASE in
+	     * 32-bit PCI memory space).
+	     */
+	    
+	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
+		(device == IOC3_DEVICE_ID_NUM))
+		break;
+#endif
+	    if (code == PCI_BA_MEM_64BIT) {
+		win++;		/* skip upper half */
+#ifdef LITTLE_ENDIAN
+		wptr[((win*4)^4)/4] = 0;	/* which must be zero */
+#else 
+		wptr[win] = 0;	/* which must be zero */
+#endif /* LITTLE_ENDIAN */
+	    }
+	}				/* next win */
+    }				/* next func */
+
+    /* Store back the values for allocated PCI address spaces */
+    PCI_ADDR_SPACE_LIMITS_STORE();
+    return(0);
+}					
+
+/*
+ * pcibr_slot_info_free
+ *	Remove all the PCI infrastructural information associated
+ * 	with a particular PCI device.
+ */
+int
+pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
+                     pciio_slot_t slot)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    int			nfunc;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+
+    pcibr_device_info_free(pcibr_vhdl, slot);
+
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+    DELA(pcibr_infoh,nfunc);
+    pcibr_soft->bs_slot[slot].bss_ninfo = 0;
+
+    return(0);
+}
+
+int as_debug = 0;
+/*
+ * pcibr_slot_addr_space_init
+ *	Reserve chunks of PCI address space as required by 
+ * 	the base registers in the card.
+ */
+int
+pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
+			   pciio_slot_t	slot)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    bridge_t		*bridge;
+    iopaddr_t		pci_io_fb, pci_io_fl;
+    iopaddr_t		pci_lo_fb, pci_lo_fl;
+    iopaddr_t		pci_hi_fb, pci_hi_fl;
+    size_t              align;
+    iopaddr_t           mask;
+    int		    	nbars;
+    int		       	nfunc;
+    int			func;
+    int			win;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    bridge = pcibr_soft->bs_base;
+
+    /* Get the current values for the allocated PCI address spaces */
+    PCI_ADDR_SPACE_LIMITS_LOAD();
+
+    if (as_debug)
+#ifdef LATER
+    PCI_ADDR_SPACE_LIMITS_PRINT();
+#endif
+    /* allocate address space,
+     * for windows that have not been
+     * previously assigned.
+     */
+    if (pcibr_soft->bs_slot[slot].has_host) {
+	return(0);
+    }
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    if (nfunc < 1)
+	return(EINVAL);
+
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+    if (!pcibr_infoh)
+	return(EINVAL);
+
+    /*
+     * Try to make the DevIO windows not
+     * overlap by pushing the "io" and "hi"
+     * allocation areas up to the next one
+     * or two megabyte bound. This also
+     * keeps them from being zero.
+     *
+     * DO NOT do this with "pci_lo" since
+     * the entire "lo" area is only a
+     * megabyte, total ...
+     */
+    align = (slot < 2) ? 0x200000 : 0x100000;
+    mask = -align;
+    pci_io_fb = (pci_io_fb + align - 1) & mask;
+    pci_hi_fb = (pci_hi_fb + align - 1) & mask;
+
+    for (func = 0; func < nfunc; ++func) {
+	cfg_p                   cfgw;
+	cfg_p                   wptr;
+	pciio_space_t           space;
+	iopaddr_t               base;
+	size_t                  size;
+	cfg_p                   pci_cfg_cmd_reg_p;
+	unsigned                pci_cfg_cmd_reg;
+	unsigned                pci_cfg_cmd_reg_add = 0;
+
+	pcibr_info = pcibr_infoh[func];
+
+	if (!pcibr_info)
+	    continue;
+
+	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+	    continue;
+	
+	cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
+	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
+
+	nbars = PCI_CFG_BASE_ADDRS;
+
+	for (win = 0; win < nbars; ++win) {
+
+	    space = pcibr_info->f_window[win].w_space;
+	    base = pcibr_info->f_window[win].w_base;
+	    size = pcibr_info->f_window[win].w_size;
+	    
+	    if (size < 1)
+		continue;
+
+	    if (base >= size) {
+#if DEBUG && PCI_DEBUG
+		printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by prom\n",
+			slot, func, win, space, base, base + size - 1);
+#endif
+		continue;		/* already allocated */
+	    }
+	    align = size;		/* ie. 0x00001000 */
+	    if (align < _PAGESZ)
+		align = _PAGESZ;	/* ie. 0x00004000 */
+	    mask = -align;		/* ie. 0xFFFFC000 */
+
+	    switch (space) {
+	    case PCIIO_SPACE_IO:
+		base = (pci_io_fb + align - 1) & mask;
+		if ((base + size) > pci_io_fl) {
+		    base = 0;
+		    break;
+		}
+		pci_io_fb = base + size;
+		break;
+		
+	    case PCIIO_SPACE_MEM:
+#ifdef LITTLE_ENDIAN
+		if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) ==
+#else
+		if ((wptr[win] & PCI_BA_MEM_LOCATION) ==
+#endif  /* LITTLE_ENDIAN */
+		    PCI_BA_MEM_1MEG) {
+		    /* allocate from 20-bit PCI space */
+		    base = (pci_lo_fb + align - 1) & mask;
+		    if ((base + size) > pci_lo_fl) {
+			base = 0;
+			break;
+		    }
+		    pci_lo_fb = base + size;
+		} else {
+		    /* allocate from 32-bit or 64-bit PCI space */
+		    base = (pci_hi_fb + align - 1) & mask;
+		    if ((base + size) > pci_hi_fl) {
+			base = 0;
+			break;
+		    }
+		    pci_hi_fb = base + size;
+		}
+		break;
+		
+	    default:
+		base = 0;
+#if DEBUG && PCI_DEBUG
+		printk("pcibr: slot %d window %d had bad space code %d\n",
+			slot, win, space);
+#endif
+	    }
+	    pcibr_info->f_window[win].w_base = base;
+#ifdef LITTLE_ENDIAN
+	    wptr[((win*4)^4)/4] = base;
+#if DEBUG && PCI_DEBUG
+		printk("Setting base address 0x%p base 0x%x\n", &(wptr[((win*4)^4)/4]), base);
+#endif
+#else
+	    wptr[win] = base;
+#endif  /* LITTLE_ENDIAN */
+
+#if DEBUG && PCI_DEBUG
+	    if (base >= size)
+		printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibr\n",
+			slot, func, win, space, base, base + size - 1);
+	    else
+		printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%p\n",
+			slot, func, win, size, space);
+#endif
+	}				/* next base */
+
+	/*
+	 * Allocate space for the EXPANSION ROM
+	 * NOTE: DO NOT DO THIS ON AN IOC3,
+	 * as it blows the system away.
+	 */
+	base = size = 0;
+	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
+	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
+
+	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
+#ifdef LITTLE_ENDIAN
+	    wptr[1] = 0xFFFFF000;
+	    mask = wptr[1];
+#else
+	    *wptr = 0xFFFFF000;
+	    mask = *wptr;
+#endif  /* LITTLE_ENDIAN */
+	    if (mask & 0xFFFFF000) {
+		size = mask & -mask;
+		align = size;
+		if (align < _PAGESZ)
+		    align = _PAGESZ;
+		mask = -align;
+		base = (pci_hi_fb + align - 1) & mask;
+		if ((base + size) > pci_hi_fl)
+		    base = size = 0;
+		else {
+		    pci_hi_fb = base + size;
+#ifdef LITTLE_ENDIAN
+		    wptr[1] = base;
+#else
+		    *wptr = base;
+#endif  /* LITTLE_ENDIAN */
+#if DEBUG && PCI_DEBUG
+		    printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)\n",
+			    pcibr_soft->bs_name, slot,
+			    base, base + size - 1);
+#endif
+		}
+	    }
+	}
+	pcibr_info->f_rbase = base;
+	pcibr_info->f_rsize = size;
+	
+	/*
+	 * if necessary, update the board's
+	 * command register to enable decoding
+	 * in the windows we added.
+	 *
+	 * There are some bits we always want to
+	 * be sure are set.
+	 */
+	pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
+
+	/*
+	 * The Adaptec 1160 FC Controller WAR #767995:
+	 * The part incorrectly ignores the upper 32 bits of a 64 bit
+	 * address when decoding references to it's registers so to
+	 * keep it from responding to a bus cycle that it shouldn't
+	 * we only use I/O space to get at it's registers.  Don't
+	 * enable memory space accesses on that PCI device.
+	 */
+	#define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */
+	#define FCADP_DEVID 0x1160  /* Adaptec 1160 Device ID from fcadp.h */
+
+	if ((pcibr_info->f_vendor != FCADP_VENDID) ||
+	    (pcibr_info->f_device != FCADP_DEVID))
+	    pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE;
+
+	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
+
+	pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4;
+	pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p;
+#if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
+	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
+	    fast_back_to_back_enable = 0;
+#endif
+	pci_cfg_cmd_reg &= 0xFFFF;
+	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
+	    *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add;
+	
+    }				/* next func */
+
+    /* Now that we have allocated new chunks of PCI address spaces to this
+     * card we need to update the bookkeeping values which indicate
+     * the current PCI address space allocations.
+     */
+    PCI_ADDR_SPACE_LIMITS_STORE();
+    return(0);
+}
+
+/*
+ * pcibr_slot_device_init
+ * 	Setup the device register in the bridge for this PCI slot.
+ */
+int
+pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
+		       pciio_slot_t slot)
+{
+    pcibr_soft_t	 pcibr_soft;
+    bridge_t		*bridge;
+    bridgereg_t		 devreg;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    bridge = pcibr_soft->bs_base;
+
+    /*
+     * Adjustments to Device(x)
+     * and init of bss_device shadow
+     */
+    devreg = bridge->b_device[slot].reg;
+    devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS;
+    devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN;
+#ifdef LITTLE_ENDIAN
+    devreg |= BRIDGE_DEV_DEV_SWAP;
+#endif
+    pcibr_soft->bs_slot[slot].bss_device = devreg;
+    bridge->b_device[slot].reg = devreg;
+
+#if DEBUG && PCI_DEBUG
+	printk("pcibr Device(%d): 0x%lx\n", slot, bridge->b_device[slot].reg);
+#endif
+
+#if DEBUG && PCI_DEBUG
+    printk("pcibr: PCI space allocation done.\n");
+#endif
+
+    return(0);
+}
+
+/*
+ * pcibr_slot_guest_info_init
+ *	Setup the host/guest relations for a PCI slot.
+ */
+int
+pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
+			   pciio_slot_t	slot)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    pcibr_soft_slot_t	slotp;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    slotp = &pcibr_soft->bs_slot[slot];
+
+    /* create info and verticies for guest slots;
+     * for compatibilitiy macros, create info
+     * for even unpopulated slots (but do not
+     * build verticies for them).
+     */
+    if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) {
+	NEWA(pcibr_infoh, 1);
+	pcibr_soft->bs_slot[slot].bss_ninfo = 1;
+	pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
+
+	pcibr_info = pcibr_device_info_new
+	    (pcibr_soft, slot, PCIIO_FUNC_NONE,
+	     PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
+
+	if (pcibr_soft->bs_slot[slot].has_host) {
+	    slotp->slot_conn = pciio_device_info_register
+		(pcibr_vhdl, &pcibr_info->f_c);
+	}
+    }
+
+    /* generate host/guest relations
+     */
+    if (pcibr_soft->bs_slot[slot].has_host) {
+	int  host = pcibr_soft->bs_slot[slot].host_slot;
+	pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host];
+
+	hwgraph_edge_add(slotp->slot_conn,
+			 host_slotp->slot_conn,
+			 EDGE_LBL_HOST);
+
+	/* XXX- only gives us one guest edge per
+	 * host. If/when we have a host with more than
+	 * one guest, we will need to figure out how
+	 * the host finds all its guests, and sorts
+	 * out which one is which.
+	 */
+	hwgraph_edge_add(host_slotp->slot_conn,
+			 slotp->slot_conn,
+			 EDGE_LBL_GUEST);
+    }
+
+    return(0);
+}
+
+/*
+ * pcibr_slot_initial_rrb_alloc
+ *	Allocate a default number of rrbs for this slot on 
+ * 	the two channels.  This is dictated by the rrb allocation
+ * 	strategy routine defined per platform.
+ */
+
+int
+pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
+			     pciio_slot_t slot)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    bridge_t		*bridge;
+    int                 c0, c1;
+    int			r;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    bridge = pcibr_soft->bs_base;
+
+    /* How may RRBs are on this slot?
+     */
+    c0 = do_pcibr_rrb_count_valid(bridge, slot);
+    c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL);
+
+#if PCIBR_RRB_DEBUG
+    printk("pcibr_attach: slot %d started with %d+%d\n", slot, c0, c1);
+#endif
+
+    /* Do we really need any?
+     */
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+    pcibr_info = pcibr_infoh[0];
+    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
+	!pcibr_soft->bs_slot[slot].has_host) {
+	if (c0 > 0)
+	    do_pcibr_rrb_free(bridge, slot, c0);
+	if (c1 > 0)
+	    do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1);
+	pcibr_soft->bs_rrb_valid[slot] = 0x1000;
+	pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000;
+	return(ENODEV);
+    }
+
+    pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1;
+    pcibr_soft->bs_rrb_valid[slot] = c0;
+    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1;
+
+    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
+    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
+
+    r = 3 - (c0 + c1);
+
+    if (r > 0) {
+	pcibr_soft->bs_rrb_res[slot] = r;
+	pcibr_soft->bs_rrb_avail[slot & 1] -= r;
+    }
+
+#if PCIBR_RRB_DEBUG
+    printk("\t%d+%d+%d",
+	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
+	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+	    pcibr_soft->bs_rrb_res[slot]);
+    printk("\n");
+#endif
+
+    return(0);
+}
+
+/*
+ * pcibr_slot_call_device_attach
+ *	This calls the associated driver attach routine for the PCI
+ * 	card in this slot.
+ */
+int
+pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+			      pciio_slot_t slot,
+			      int          drv_flags)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    async_attach_t	aa = NULL;
+    int			func;
+    devfs_handle_t	xconn_vhdl,conn_vhdl;
+    int			nfunc;
+    int                 error_func;
+    int                 error_slot = 0;
+    int                 error = ENODEV;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+
+    if (pcibr_soft->bs_slot[slot].has_host) {
+        return(EPERM);
+    }
+    
+    xconn_vhdl = pcibr_soft->bs_conn;
+    aa = async_attach_get_info(xconn_vhdl);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+
+    for (func = 0; func < nfunc; ++func) {
+
+	pcibr_info = pcibr_infoh[func];
+	
+	if (!pcibr_info)
+	    continue;
+
+	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+	    continue;
+
+	conn_vhdl = pcibr_info->f_vertex;
+
+#ifdef LATER
+	/*
+	 * Activate if and when we support cdl.
+	 */
+	if (aa)
+	    async_attach_add_info(conn_vhdl, aa);
+#endif	/* LATER */
+
+	error_func = pciio_device_attach(conn_vhdl, drv_flags);
+
+        pcibr_info->f_att_det_error = error_func;
+
+	if (error_func)
+	    error_slot = error_func;
+
+        error = error_slot;
+
+    }				/* next func */
+
+    if (error) {
+	if ((error != ENODEV) && (error != EUNATCH))
+	    pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
+    } else {
+        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
+    }
+        
+    return(error);
+}
+
+/*
+ * pcibr_slot_call_device_detach
+ *	This calls the associated driver detach routine for the PCI
+ * 	card in this slot.
+ */
+int
+pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+			      pciio_slot_t slot,
+			      int          drv_flags)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    int			func;
+    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
+    int			nfunc;
+    int                 error_func;
+    int                 error_slot = 0;
+    int                 error = ENODEV;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    if (pcibr_soft->bs_slot[slot].has_host)
+        return(EPERM);
+
+    /* Make sure that we do not detach a system critical function vertex */
+    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
+        return(EPERM);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+
+    for (func = 0; func < nfunc; ++func) {
+
+	pcibr_info = pcibr_infoh[func];
+	
+	if (!pcibr_info)
+	    continue;
+
+	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+	    continue;
+
+	conn_vhdl = pcibr_info->f_vertex;
+
+	error_func = pciio_device_detach(conn_vhdl, drv_flags);
+
+        pcibr_info->f_att_det_error = error_func;
+
+	if (error_func)
+	    error_slot = error_func;
+
+	error = error_slot;
+
+    }				/* next func */
+
+    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
+
+    if (error) {
+	if ((error != ENODEV) && (error != EUNATCH))
+            pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
+    } else {
+        if (conn_vhdl != GRAPH_VERTEX_NONE) 
+            pcibr_device_unregister(conn_vhdl);
+        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
+    }
+        
+    return(error);
+}
+
+/*
+ * pcibr_slot_detach
+ *	This is a place holder routine to keep track of all the
+ *	slot-specific freeing that needs to be done.
+ */
+int
+pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
+		  pciio_slot_t slot,
+		  int          drv_flags)
+{
+    int		  error;
+    
+    /* Call the device detach function */
+    error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
+    return (error);
+
+}
+
+/*
+ * pcibr_is_slot_sys_critical
+ *      Check slot for any functions that are system critical.
+ *      Return 1 if any are system critical or 0 otherwise.
+ *
+ *      This function will always return 0 when called by 
+ *      pcibr_attach() because the system critical vertices 
+ *      have not yet been set in the hwgraph.
+ */
+int
+pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
+                      pciio_slot_t slot)
+{
+    pcibr_soft_t        pcibr_soft;
+    pcibr_info_h        pcibr_infoh;
+    pcibr_info_t        pcibr_info;
+    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
+    int                 nfunc;
+    int                 func;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+        return(0);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+
+    for (func = 0; func < nfunc; ++func) {
+
+        pcibr_info = pcibr_infoh[func];
+        if (!pcibr_info)
+            continue;
+
+        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+            continue;
+
+        conn_vhdl = pcibr_info->f_vertex;
+        if (is_sys_critical_vertex(conn_vhdl)) { 
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);
+#else
+            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);
+#endif
+            return(1); 
+        }
+
+    }
+
+    return(0);
+}
+
+/*
+ * pcibr_device_unregister
+ *	This frees up any hardware resources reserved for this PCI device
+ * 	and removes any PCI infrastructural information setup for it.
+ *	This is usually used at the time of shutting down of the PCI card.
+ */
+int
+pcibr_device_unregister(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t	 pciio_info;
+    devfs_handle_t	 pcibr_vhdl;
+    pciio_slot_t	 slot;
+    pcibr_soft_t	 pcibr_soft;
+    bridge_t		*bridge;
+    int			 error_call;
+    int			 error = 0;
+
+    pciio_info = pciio_info_get(pconn_vhdl);
+
+    pcibr_vhdl = pciio_info_master_get(pciio_info);
+    slot = pciio_info_slot_get(pciio_info);
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge = pcibr_soft->bs_base;
+
+    /* Clear all the hardware xtalk resources for this device */
+    xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot);
+
+    /* Flush all the rrbs */
+    pcibr_rrb_flush(pconn_vhdl);
+
+    /* Free the rrbs allocated to this slot */
+    error_call = do_pcibr_rrb_free(bridge, slot, 
+		                   pcibr_soft->bs_rrb_valid[slot] +
+		                   pcibr_soft->bs_rrb_valid[slot + 
+                                   PCIBR_RRB_SLOT_VIRTUAL]);
+
+    if (error_call)
+        error = ERANGE;
+
+    pcibr_soft->bs_rrb_valid[slot] = 0;
+    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0;
+    pcibr_soft->bs_rrb_res[slot] = 0;
+
+    /* Flush the write buffers !! */
+    error_call = pcibr_wrb_flush(pconn_vhdl);
+
+    if (error_call)
+        error = error_call;
+
+    /* Clear the information specific to the slot */
+    error_call = pcibr_slot_info_free(pcibr_vhdl, slot);
+
+    if (error_call)
+        error = error_call;
+
+    return(error);
+    
+}
+
+/* 
+ * build a convenience link path in the
+ * form of ".../<iobrick>/bus/<busnum>"
+ * 
+ * returns 1 on success, 0 otherwise
+ *
+ * depends on hwgraph separator == '/'
+ */
+int
+pcibr_bus_cnvlink(devfs_handle_t f_c, int slot)
+{
+        char dst[MAXDEVNAME];
+	char *dp = dst;
+        char *cp, *xp;
+        int widgetnum;
+        char pcibus[8];
+	devfs_handle_t nvtx, svtx;
+	int rv;
+
+#if DEBUG
+	printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", 
+		slot, f_c);
+	{
+		int pos;
+		char dname[256];
+		pos = devfs_generate_path(f_c, dname, 256);
+		printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
+	}
+#endif
+
+	if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME))
+		return 0;
+
+	/* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */
+
+	/* find the widget number */
+	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
+	if (xp == NULL)
+		return 0;
+	widgetnum = atoi(xp+7);
+	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
+		return 0;
+
+	/* remove "/pci/direct" from path */
+	cp = strstr(dst, "/" EDGE_LBL_PCI "/" "direct");
+	if (cp == NULL)
+		return 0;
+	*cp = (char)NULL;
+
+	/* get the vertex for the widget */
+	if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx))	
+		return 0;
+
+	*xp = (char)NULL;		/* remove "/xtalk/..." from path */
+
+	/* dst example now == /hw/module/001c02/Pbrick */
+
+	/* get the bus number */
+        strcat(dst, "/bus");
+        sprintf(pcibus, "%d", p_busnum[widgetnum]);
+
+	/* link to bus to widget */
+	rv = hwgraph_path_add(NULL, dp, &nvtx);
+	if (GRAPH_SUCCESS == rv)
+		rv = hwgraph_edge_add(nvtx, svtx, pcibus);
+
+	return (rv == GRAPH_SUCCESS);
+}
+
+
+/*
+ *    pcibr_attach: called every time the crosstalk
+ *      infrastructure is asked to initialize a widget
+ *      that matches the part number we handed to the
+ *      registration routine above.
+ */
+/*ARGSUSED */
+int
+pcibr_attach(devfs_handle_t xconn_vhdl)
+{
+    /* REFERENCED */
+    graph_error_t           rc;
+    devfs_handle_t            pcibr_vhdl;
+    devfs_handle_t            ctlr_vhdl;
+    bridge_t               *bridge = NULL;
+    bridgereg_t             id;
+    int                     rev;
+    pcibr_soft_t            pcibr_soft;
+    pcibr_info_t            pcibr_info;
+    xwidget_info_t          info;
+    xtalk_intr_t            xtalk_intr;
+    device_desc_t           dev_desc = (device_desc_t)0;
+    int                     slot;
+    int                     ibit;
+    devfs_handle_t            noslot_conn;
+    char                    devnm[MAXDEVNAME], *s;
+    pcibr_hints_t           pcibr_hints;
+    bridgereg_t             b_int_enable;
+    unsigned                rrb_fixed = 0;
+
+    iopaddr_t               pci_io_fb, pci_io_fl;
+    iopaddr_t               pci_lo_fb, pci_lo_fl;
+    iopaddr_t               pci_hi_fb, pci_hi_fl;
+
+    int                     spl_level;
+#ifdef LATER
+    char		    *nicinfo = (char *)0;
+#endif
+
+#if PCI_FBBE
+    int                     fast_back_to_back_enable;
+#endif
+    l1sc_t		    *scp;
+    nasid_t		    nasid;
+
+    async_attach_t          aa = NULL;
+
+    aa = async_attach_get_info(xconn_vhdl);
+
+#if DEBUG && ATTACH_DEBUG
+    printk("pcibr_attach: xconn_vhdl=  %p\n", xconn_vhdl);
+    {
+	int pos;
+	char dname[256];
+	pos = devfs_generate_path(xconn_vhdl, dname, 256);
+	printk("%s : path= %s \n", __FUNCTION__, &dname[pos]);
+    }
+#endif
+
+    /* Setup the PRB for the bridge in CONVEYOR BELT
+     * mode. PRBs are setup in default FIRE-AND-FORGET
+     * mode during the initialization.
+     */
+    hub_device_flags_set(xconn_vhdl, HUB_PIO_CONVEYOR);
+
+    bridge = (bridge_t *)
+	xtalk_piotrans_addr(xconn_vhdl, NULL,
+			    0, sizeof(bridge_t), 0);
+
+#ifndef MEDUSA_HACK
+    if ((bridge->b_wid_stat & BRIDGE_STAT_PCI_GIO_N) == 0)
+	return -1;			/* someone else handles GIO bridges. */
+#endif
+
+    if (XWIDGET_PART_REV_NUM(bridge->b_wid_id) == XBRIDGE_PART_REV_A)
+	NeedXbridgeSwap = 1;
+
+    /*
+     * Create the vertex for the PCI bus, which we
+     * will also use to hold the pcibr_soft and
+     * which will be the "master" vertex for all the
+     * pciio connection points we will hang off it.
+     * This needs to happen before we call nic_bridge_vertex_info
+     * as we are some of the *_vmc functions need access to the edges.
+     *
+     * Opening this vertex will provide access to
+     * the Bridge registers themselves.
+     */
+    rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl);
+    ASSERT(rc == GRAPH_SUCCESS);
+
+    ctlr_vhdl = NULL;
+    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
+                0, DEVFS_FL_AUTO_DEVNUM,
+                0, 0,
+                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+                &pcibr_fops, NULL);
+
+    ASSERT(ctlr_vhdl != NULL);
+
+    /*
+     * decode the nic, and hang its stuff off our
+     * connection point where other drivers can get
+     * at it.
+     */
+#ifdef LATER
+    nicinfo = BRIDGE_VERTEX_MFG_INFO(xconn_vhdl, (nic_data_t) & bridge->b_nic);
+#endif
+
+    /*
+     * Get the hint structure; if some NIC callback
+     * marked this vertex as "hands-off" then we
+     * just return here, before doing anything else.
+     */
+    pcibr_hints = pcibr_hints_get(xconn_vhdl, 0);
+
+    if (pcibr_hints && pcibr_hints->ph_hands_off)
+	return -1;			/* generic operations disabled */
+
+    id = bridge->b_wid_id;
+    rev = XWIDGET_PART_REV_NUM(id);
+
+    hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev);
+
+    /*
+     * allocate soft state structure, fill in some
+     * fields, and hook it up to our vertex.
+     */
+    NEW(pcibr_soft);
+    BZERO(pcibr_soft, sizeof *pcibr_soft);
+    pcibr_soft_set(pcibr_vhdl, pcibr_soft);
+
+    pcibr_soft->bs_conn = xconn_vhdl;
+    pcibr_soft->bs_vhdl = pcibr_vhdl;
+    pcibr_soft->bs_base = bridge;
+    pcibr_soft->bs_rev_num = rev;
+    pcibr_soft->bs_intr_bits = pcibr_intr_bits;
+    if (is_xbridge(bridge)) {
+	pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES;
+	pcibr_soft->bs_xbridge = 1;
+    } else {
+	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
+	pcibr_soft->bs_xbridge = 0;
+    }
+
+    nasid = NASID_GET(bridge);
+    scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
+    pcibr_soft->bs_l1sc = scp;
+    pcibr_soft->bs_moduleid = iobrick_module_get(scp);
+    pcibr_soft->bsi_err_intr = 0;
+
+    /* Bridges up through REV C
+     * are unable to set the direct
+     * byteswappers to BYTE_STREAM.
+     */
+    if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) {
+	pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES;
+	pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES;
+    }
+#if PCIBR_SOFT_LIST
+    {
+	pcibr_list_p            self;
+
+	NEW(self);
+	self->bl_soft = pcibr_soft;
+	self->bl_vhdl = pcibr_vhdl;
+	self->bl_next = pcibr_list;
+	self->bl_next = swap_ptr((void **) &pcibr_list, (void *)self);
+    }
+#endif
+
+    /*
+     * get the name of this bridge vertex and keep the info. Use this
+     * only where it is really needed now: like error interrupts.
+     */
+    s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME);
+    pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
+    strcpy(pcibr_soft->bs_name, s);
+
+#if SHOW_REVS || DEBUG
+#if !DEBUG
+    if (kdebug)
+#endif
+	printk("%sBridge ASIC: rev %s (code=0x%x) at %s\n",
+		is_xbridge(bridge) ? "X" : "",
+		(rev == BRIDGE_PART_REV_A) ? "A" :
+		(rev == BRIDGE_PART_REV_B) ? "B" :
+		(rev == BRIDGE_PART_REV_C) ? "C" :
+		(rev == BRIDGE_PART_REV_D) ? "D" :
+		(rev == XBRIDGE_PART_REV_A) ? "A" :
+		(rev == XBRIDGE_PART_REV_B) ? "B" :
+		"unknown",
+		rev, pcibr_soft->bs_name);
+#endif
+
+    info = xwidget_info_get(xconn_vhdl);
+    pcibr_soft->bs_xid = xwidget_info_id_get(info);
+    pcibr_soft->bs_master = xwidget_info_master_get(info);
+    pcibr_soft->bs_mxid = xwidget_info_masterid_get(info);
+
+    /*
+     * Init bridge lock.
+     */
+    spin_lock_init(&pcibr_soft->bs_lock);
+
+    /*
+     * If we have one, process the hints structure.
+     */
+    if (pcibr_hints) {
+	rrb_fixed = pcibr_hints->ph_rrb_fixed;
+
+	pcibr_soft->bs_rrb_fixed = rrb_fixed;
+
+	if (pcibr_hints->ph_intr_bits)
+	    pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;
+
+	for (slot = 0; slot < 8; ++slot) {
+	    int                     hslot = pcibr_hints->ph_host_slot[slot] - 1;
+
+	    if (hslot < 0) {
+		pcibr_soft->bs_slot[slot].host_slot = slot;
+	    } else {
+		pcibr_soft->bs_slot[slot].has_host = 1;
+		pcibr_soft->bs_slot[slot].host_slot = hslot;
+	    }
+	}
+    }
+    /*
+     * set up initial values for state fields
+     */
+    for (slot = 0; slot < 8; ++slot) {
+	pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;
+	pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;
+	pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;
+	pcibr_soft->bs_slot[slot].bss_ext_ates_active = ATOMIC_INIT(0);
+    }
+
+    for (ibit = 0; ibit < 8; ++ibit) {
+	pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_stat = 
+							&(bridge->b_int_status);
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;
+    }
+
+    /*
+     * Initialize various Bridge registers.
+     */
+
+    /*
+     * On pre-Rev.D bridges, set the PCI_RETRY_CNT
+     * to zero to avoid dropping stores. (#475347)
+     */
+    if (rev < BRIDGE_PART_REV_D)
+	bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK;
+
+    /*
+     * Clear all pending interrupts.
+     */
+    bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
+
+    /*
+     * Until otherwise set up,
+     * assume all interrupts are
+     * from slot 7.
+     */
+    bridge->b_int_device = (uint32_t) 0xffffffff;
+
+    {
+	bridgereg_t             dirmap;
+	paddr_t                 paddr;
+	iopaddr_t               xbase;
+	xwidgetnum_t            xport;
+	iopaddr_t               offset;
+	int                     num_entries = 0;
+	int                     entry;
+	cnodeid_t		cnodeid;
+	nasid_t			nasid;
+
+	/* Set the Bridge's 32-bit PCI to XTalk
+	 * Direct Map register to the most useful
+	 * value we can determine.  Note that we
+	 * must use a single xid for all of:
+	 *      direct-mapped 32-bit DMA accesses
+	 *      direct-mapped 64-bit DMA accesses
+	 *      DMA accesses through the PMU
+	 *      interrupts
+	 * This is the only way to guarantee that
+	 * completion interrupts will reach a CPU
+	 * after all DMA data has reached memory.
+	 * (Of course, there may be a few special
+	 * drivers/controlers that explicitly manage
+	 * this ordering problem.)
+	 */
+
+	cnodeid = 0;  /* default node id */
+	/*
+	 * Determine the base address node id to be used for all 32-bit
+	 * Direct Mapping I/O. The default is node 0, but this can be changed
+	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE
+	 * attribute in the irix.sm config file. A device driver can obtain
+	 * this node value via a call to pcibr_get_dmatrans_node().
+	 */
+	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
+	paddr = NODE_OFFSET(nasid) + 0;
+
+	/* currently, we just assume that if we ask
+	 * for a DMA mapping to "zero" the XIO
+	 * host will transmute this into a request
+	 * for the lowest hunk of memory.
+	 */
+	xbase = xtalk_dmatrans_addr(xconn_vhdl, 0,
+				    paddr, _PAGESZ, 0);
+
+	if (xbase != XIO_NOWHERE) {
+	    if (XIO_PACKED(xbase)) {
+		xport = XIO_PORT(xbase);
+		xbase = XIO_ADDR(xbase);
+	    } else
+		xport = pcibr_soft->bs_mxid;
+
+	    offset = xbase & ((1ull << BRIDGE_DIRMAP_OFF_ADDRSHFT) - 1ull);
+	    xbase >>= BRIDGE_DIRMAP_OFF_ADDRSHFT;
+
+	    dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT;
+
+	    if (xbase)
+		dirmap |= BRIDGE_DIRMAP_OFF & xbase;
+	    else if (offset >= (512 << 20))
+		dirmap |= BRIDGE_DIRMAP_ADD512;
+
+	    bridge->b_dir_map = dirmap;
+	}
+	/*
+	 * Set bridge's idea of page size according to the system's
+	 * idea of "IO page size".  TBD: The idea of IO page size
+	 * should really go away.
+	 */
+	/*
+	 * ensure that we write and read without any interruption.
+	 * The read following the write is required for the Bridge war
+	 */
+	spl_level = splhi();
+#if IOPGSIZE == 4096
+	bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE;
+#elif IOPGSIZE == 16384
+	bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE;
+#else
+	<<<Unable to deal with IOPGSIZE >>>;
+#endif
+	bridge->b_wid_control;		/* inval addr bug war */
+	splx(spl_level);
+
+	/* Initialize internal mapping entries */
+	for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++)
+	    bridge->b_int_ate_ram[entry].wr = 0;
+
+	/*
+	 * Determine if there's external mapping SSRAM on this
+	 * bridge.  Set up Bridge control register appropriately,
+	 * inititlize SSRAM, and set software up to manage RAM
+	 * entries as an allocatable resource.
+	 *
+	 * Currently, we just use the rm* routines to manage ATE
+	 * allocation.  We should probably replace this with a
+	 * Best Fit allocator.
+	 *
+	 * For now, if we have external SSRAM, avoid using
+	 * the internal ssram: we can't turn PREFETCH on
+	 * when we use the internal SSRAM; and besides,
+	 * this also guarantees that no allocation will
+	 * straddle the internal/external line, so we
+	 * can increment ATE write addresses rather than
+	 * recomparing against BRIDGE_INTERNAL_ATES every
+	 * time.
+	 */
+	if (is_xbridge(bridge))
+		num_entries = 0;
+	else
+		num_entries = pcibr_init_ext_ate_ram(bridge);
+
+	/* we always have 128 ATEs (512 for Xbridge) inside the chip
+	 * even if disabled for debugging.
+	 */
+	pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
+	pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_attach: %d INTERNAL ATEs\n", pcibr_soft->bs_int_ate_size);
+#endif
+
+	if (num_entries > pcibr_soft->bs_int_ate_size) {
+#if PCIBR_ATE_NOTBOTH			/* for debug -- forces us to use external ates */
+	    printk("pcibr_attach: disabling internal ATEs.\n");
+	    pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
+#endif
+	    pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
+	    pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
+			   num_entries - pcibr_soft->bs_int_ate_size);
+#if PCIBR_ATE_DEBUG
+	    printk("pcibr_attach: %d EXTERNAL ATEs\n",
+		    num_entries - pcibr_soft->bs_int_ate_size);
+#endif
+	}
+    }
+
+    {
+	bridgereg_t             dirmap;
+	iopaddr_t               xbase;
+
+	/*
+	 * now figure the *real* xtalk base address
+	 * that dirmap sends us to.
+	 */
+	dirmap = bridge->b_dir_map;
+	if (dirmap & BRIDGE_DIRMAP_OFF)
+	    xbase = (iopaddr_t)(dirmap & BRIDGE_DIRMAP_OFF)
+			<< BRIDGE_DIRMAP_OFF_ADDRSHFT;
+	else if (dirmap & BRIDGE_DIRMAP_ADD512)
+	    xbase = 512 << 20;
+	else
+	    xbase = 0;
+
+	pcibr_soft->bs_dir_xbase = xbase;
+
+	/* it is entirely possible that we may, at this
+	 * point, have our dirmap pointing somewhere
+	 * other than our "master" port.
+	 */
+	pcibr_soft->bs_dir_xport =
+	    (dirmap & BRIDGE_DIRMAP_W_ID) >> BRIDGE_DIRMAP_W_ID_SHFT;
+    }
+
+    /* pcibr sources an error interrupt;
+     * figure out where to send it.
+     *
+     * If any interrupts are enabled in bridge,
+     * then the prom set us up and our interrupt
+     * has already been reconnected in mlreset
+     * above.
+     *
+     * Need to set the D_INTR_ISERR flag
+     * in the dev_desc used for allocating the
+     * error interrupt, so our interrupt will
+     * be properly routed and prioritized.
+     *
+     * If our crosstalk provider wants to
+     * fix widget error interrupts to specific
+     * destinations, D_INTR_ISERR is how it
+     * knows to do this.
+     */
+
+    xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, pcibr_vhdl);
+    ASSERT(xtalk_intr != NULL);
+
+    pcibr_soft->bsi_err_intr = xtalk_intr;
+
+    /*
+     * On IP35 with XBridge, we do some extra checks in pcibr_setwidint
+     * in order to work around some addressing limitations.  In order
+     * for that fire wall to work properly, we need to make sure we
+     * start from a known clean state.
+     */
+    pcibr_clearwidint(bridge);
+
+    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge);
+
+    /*
+     * now we can start handling error interrupts;
+     * enable all of them.
+     * NOTE: some PCI ints may already be enabled.
+     */
+    b_int_enable = bridge->b_int_enable | BRIDGE_ISR_ERRORS;
+
+
+    bridge->b_int_enable = b_int_enable;
+    bridge->b_int_mode = 0;		/* do not send "clear interrupt" packets */
+
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+
+    /*
+     * Depending on the rev of bridge, disable certain features.
+     * Easiest way seems to be to force the PCIBR_NOwhatever
+     * flag to be on for all DMA calls, which overrides any
+     * PCIBR_whatever flag or even the setting of whatever
+     * from the PCIIO_DMA_class flags (or even from the other
+     * PCIBR flags, since NO overrides YES).
+     */
+    pcibr_soft->bs_dma_flags = 0;
+
+    /* PREFETCH:
+     * Always completely disabled for REV.A;
+     * at "pcibr_prefetch_enable_rev", anyone
+     * asking for PCIIO_PREFETCH gets it.
+     * Between these two points, you have to ask
+     * for PCIBR_PREFETCH, which promises that
+     * your driver knows about known Bridge WARs.
+     */
+    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
+	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
+    else if (pcibr_soft->bs_rev_num < 
+		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
+	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
+
+    /* WRITE_GATHER:
+     * Disabled up to but not including the
+     * rev number in pcibr_wg_enable_rev. There
+     * is no "WAR range" as with prefetch.
+     */
+    if (pcibr_soft->bs_rev_num < 
+		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
+	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
+
+    pciio_provider_register(pcibr_vhdl, &pcibr_provider);
+    pciio_provider_startup(pcibr_vhdl);
+
+    pci_io_fb = 0x00000004;		/* I/O FreeBlock Base */
+    pci_io_fl = 0xFFFFFFFF;		/* I/O FreeBlock Last */
+
+    pci_lo_fb = 0x00000010;		/* Low Memory FreeBlock Base */
+    pci_lo_fl = 0x001FFFFF;		/* Low Memory FreeBlock Last */
+
+    pci_hi_fb = 0x00200000;		/* High Memory FreeBlock Base */
+    pci_hi_fl = 0x3FFFFFFF;		/* High Memory FreeBlock Last */
+
+
+    PCI_ADDR_SPACE_LIMITS_STORE();
+
+    /* build "no-slot" connection point
+     */
+    pcibr_info = pcibr_device_info_new
+	(pcibr_soft, PCIIO_SLOT_NONE, PCIIO_FUNC_NONE,
+	 PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
+    noslot_conn = pciio_device_info_register
+	(pcibr_vhdl, &pcibr_info->f_c);
+
+    /* Remember the no slot connection point info for tearing it
+     * down during detach.
+     */
+    pcibr_soft->bs_noslot_conn = noslot_conn;
+    pcibr_soft->bs_noslot_info = pcibr_info;
+#if PCI_FBBE
+    fast_back_to_back_enable = 1;
+#endif
+
+#if PCI_FBBE
+    if (fast_back_to_back_enable) {
+	/*
+	 * All devices on the bus are capable of fast back to back, so
+	 * we need to set the fast back to back bit in all devices on
+	 * the bus that are capable of doing such accesses.
+	 */
+    }
+#endif
+
+#ifdef LATER
+    /* If the bridge has been reset then there is no need to reset
+     * the individual PCI slots.
+     */
+    for (slot = 0; slot < 8; ++slot)  
+	/* Reset all the slots */
+	(void)pcibr_slot_reset(pcibr_vhdl, slot);
+#endif
+
+    for (slot = 0; slot < 8; ++slot)
+	/* Find out what is out there */
+	(void)pcibr_slot_info_init(pcibr_vhdl,slot);
+
+    for (slot = 0; slot < 8; ++slot)  
+	/* Set up the address space for this slot in the pci land */
+	(void)pcibr_slot_addr_space_init(pcibr_vhdl,slot);
+
+    for (slot = 0; slot < 8; ++slot)  
+	/* Setup the device register */
+	(void)pcibr_slot_device_init(pcibr_vhdl, slot);
+
+#ifndef __ia64
+    for (slot = 0; slot < 8; ++slot)  
+	/* Set up convenience links */
+	if (is_xbridge(bridge))
+		if (pcibr_soft->bs_slot[slot].bss_ninfo > 0) /* if occupied */
+			pcibr_bus_cnvlink(pcibr_info->f_vertex, slot);
+#endif
+
+    for (slot = 0; slot < 8; ++slot)  
+	/* Setup host/guest relations */
+	(void)pcibr_slot_guest_info_init(pcibr_vhdl,slot);
+
+    for (slot = 0; slot < 8; ++slot)  
+	/* Initial RRB management */
+	(void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot);
+
+    /* driver attach routines should be called out from generic linux code */
+    for (slot = 0; slot < 8; ++slot)  
+	/* Call the device attach */
+	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
+
+    /*
+     * Each Pbrick PCI bus only has slots 1 and 2.   Similarly for
+     * widget 0xe on Ibricks.  Allocate RRB's accordingly.
+     */
+    if (pcibr_soft->bs_moduleid > 0) {
+	switch (MODULE_GET_BTCHAR(pcibr_soft->bs_moduleid)) {
+	case 'p':		/* Pbrick */
+		do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
+		do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
+		break;
+	case 'i':		/* Ibrick */
+	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
+		if (pcibr_soft->bs_xid == 0xe) {
+			do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
+			do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
+		}
+		else {
+		    	/* allocate one RRB for the serial port */
+			do_pcibr_rrb_autoalloc(pcibr_soft, 0, 1);
+		}
+		break;
+	} /* switch */
+    }
+
+#ifdef LATER
+    if (strstr(nicinfo, XTALK_PCI_PART_NUM)) {
+	do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
+#if PCIBR_RRB_DEBUG
+	printf("\n\nFound XTALK_PCI (030-1275) at %v\n", xconn_vhdl);
+
+	printf("pcibr_attach: %v Shoebox RRB MANAGEMENT: %d+%d free\n",
+		pcibr_vhdl,
+		pcibr_soft->bs_rrb_avail[0],
+		pcibr_soft->bs_rrb_avail[1]);
+
+	for (slot = 0; slot < 8; ++slot)
+	    printf("\t%d+%d+%d",
+	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
+	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+	    pcibr_soft->bs_rrb_res[slot]);
+
+	printf("\n");
+#endif
+    }
+#else
+	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
+#endif
+
+    if (aa)
+	    async_attach_add_info(noslot_conn, aa);
+
+    pciio_device_attach(noslot_conn, 0);
+
+
+    /* 
+     * Tear down pointer to async attach info -- async threads for
+     * bridge's descendants may be running but the bridge's work is done.
+     */
+    if (aa)
+	    async_attach_del_info(xconn_vhdl);
+
+    return 0;
+}
+/*
+ * pcibr_detach:
+ *	Detach the bridge device from the hwgraph after cleaning out all the 
+ *	underlying vertices.
+ */
+int
+pcibr_detach(devfs_handle_t xconn)
+{
+    pciio_slot_t	slot;
+    devfs_handle_t	pcibr_vhdl;
+    pcibr_soft_t	pcibr_soft;
+    bridge_t		*bridge;
+
+    /* Get the bridge vertex from its xtalk connection point */
+    if (hwgraph_traverse(xconn, EDGE_LBL_PCI, &pcibr_vhdl) != GRAPH_SUCCESS)
+	return(1);
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge = pcibr_soft->bs_base;
+
+    /* Disable the interrupts from the bridge */
+    bridge->b_int_enable = 0;
+
+    /* Detach all the PCI devices talking to this bridge */
+    for(slot = 0; slot < 8; slot++) {
+#ifdef DEBUG
+	printk("pcibr_device_detach called for %p/%d\n",
+		pcibr_vhdl,slot);
+#endif
+	pcibr_slot_detach(pcibr_vhdl, slot, 0);
+    }
+
+    /* Unregister the no-slot connection point */
+    pciio_device_info_unregister(pcibr_vhdl,
+				 &(pcibr_soft->bs_noslot_info->f_c));
+
+    spin_lock_destroy(&pcibr_soft->bs_lock);
+    kfree(pcibr_soft->bs_name);
+    
+    /* Error handler gets unregistered when the widget info is 
+     * cleaned 
+     */
+    /* Free the soft ATE maps */
+    if (pcibr_soft->bs_int_ate_map)
+	rmfreemap(pcibr_soft->bs_int_ate_map);
+    if (pcibr_soft->bs_ext_ate_map)
+	rmfreemap(pcibr_soft->bs_ext_ate_map);
+
+    /* Disconnect the error interrupt and free the xtalk resources 
+     * associated with it.
+     */
+    xtalk_intr_disconnect(pcibr_soft->bsi_err_intr);
+    xtalk_intr_free(pcibr_soft->bsi_err_intr);
+
+    /* Clear the software state maintained by the bridge driver for this
+     * bridge.
+     */
+    DEL(pcibr_soft);
+    /* Remove the Bridge revision labelled info */
+    (void)hwgraph_info_remove_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, NULL);
+    /* Remove the character device associated with this bridge */
+    (void)hwgraph_edge_remove(pcibr_vhdl, EDGE_LBL_CONTROLLER, NULL);
+    /* Remove the PCI bridge vertex */
+    (void)hwgraph_edge_remove(xconn, EDGE_LBL_PCI, NULL);
+
+    return(0);
+}
+
+int
+pcibr_asic_rev(devfs_handle_t pconn_vhdl)
+{
+    devfs_handle_t            pcibr_vhdl;
+    arbitrary_info_t        ainfo;
+
+    if (GRAPH_SUCCESS !=
+	hwgraph_traverse(pconn_vhdl, EDGE_LBL_MASTER, &pcibr_vhdl))
+	return -1;
+
+    if (GRAPH_SUCCESS !=
+	hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &ainfo))
+	return -1;
+
+    return (int) ainfo;
+}
+
+int
+pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    pciio_slot_t  slot;
+    slot = pciio_info_slot_get(pciio_info);
+    pcibr_device_write_gather_flush(pcibr_soft, slot);
+    return 0;
+}
+
+/* =====================================================================
+ *    PIO MANAGEMENT
+ */
+
+LOCAL iopaddr_t
+pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
+		      pciio_slot_t slot,
+		      pciio_space_t space,
+		      iopaddr_t pci_addr,
+		      size_t req_size,
+		      unsigned flags)
+{
+    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
+    pciio_info_t            pciio_info = &pcibr_info->f_c;
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+
+    unsigned                bar;	/* which BASE reg on device is decoding */
+    iopaddr_t               xio_addr = XIO_NOWHERE;
+
+    pciio_space_t           wspace;	/* which space device is decoding */
+    iopaddr_t               wbase;	/* base of device decode on PCI */
+    size_t                  wsize;	/* size of device decode on PCI */
+
+    int                     try;	/* DevIO(x) window scanning order control */
+    int                     win;	/* which DevIO(x) window is being used */
+    pciio_space_t           mspace;	/* target space for devio(x) register */
+    iopaddr_t               mbase;	/* base of devio(x) mapped area on PCI */
+    size_t                  msize;	/* size of devio(x) mapped area on PCI */
+    size_t                  mmask;	/* addr bits stored in Device(x) */
+
+    unsigned long           s;
+
+    s = pcibr_lock(pcibr_soft);
+
+    if (pcibr_soft->bs_slot[slot].has_host) {
+	slot = pcibr_soft->bs_slot[slot].host_slot;
+	pcibr_info = pcibr_soft->bs_slot[slot].bss_infos[0];
+    }
+    if (space == PCIIO_SPACE_NONE)
+	goto done;
+
+    if (space == PCIIO_SPACE_CFG) {
+	/*
+	 * Usually, the first mapping
+	 * established to a PCI device
+	 * is to its config space.
+	 *
+	 * In any case, we definitely
+	 * do NOT need to worry about
+	 * PCI BASE registers, and
+	 * MUST NOT attempt to point
+	 * the DevIO(x) window at
+	 * this access ...
+	 */
+	if (((flags & PCIIO_BYTE_STREAM) == 0) &&
+	    ((pci_addr + req_size) <= BRIDGE_TYPE0_CFG_FUNC_OFF))
+	    xio_addr = pci_addr + BRIDGE_TYPE0_CFG_DEV(slot);
+
+	goto done;
+    }
+    if (space == PCIIO_SPACE_ROM) {
+	/* PIO to the Expansion Rom.
+	 * Driver is responsible for
+	 * enabling and disabling
+	 * decodes properly.
+	 */
+	wbase = pcibr_info->f_rbase;
+	wsize = pcibr_info->f_rsize;
+
+	/*
+	 * While the driver should know better
+	 * than to attempt to map more space
+	 * than the device is decoding, he might
+	 * do it; better to bail out here.
+	 */
+	if ((pci_addr + req_size) > wsize)
+	    goto done;
+
+	pci_addr += wbase;
+	space = PCIIO_SPACE_MEM;
+    }
+    /*
+     * reduce window mappings to raw
+     * space mappings (maybe allocating
+     * windows), and try for DevIO(x)
+     * usage (setting it if it is available).
+     */
+    bar = space - PCIIO_SPACE_WIN0;
+    if (bar < 6) {
+	wspace = pcibr_info->f_window[bar].w_space;
+	if (wspace == PCIIO_SPACE_NONE)
+	    goto done;
+
+	/* get PCI base and size */
+	wbase = pcibr_info->f_window[bar].w_base;
+	wsize = pcibr_info->f_window[bar].w_size;
+
+	/*
+	 * While the driver should know better
+	 * than to attempt to map more space
+	 * than the device is decoding, he might
+	 * do it; better to bail out here.
+	 */
+	if ((pci_addr + req_size) > wsize)
+	    goto done;
+
+	/* shift from window relative to
+	 * decoded space relative.
+	 */
+	pci_addr += wbase;
+	space = wspace;
+    } else
+	bar = -1;
+
+    /* Scan all the DevIO(x) windows twice looking for one
+     * that can satisfy our request. The first time through,
+     * only look at assigned windows; the second time, also
+     * look at PCIIO_SPACE_NONE windows. Arrange the order
+     * so we always look at our own window first.
+     *
+     * We will not attempt to satisfy a single request
+     * by concatinating multiple windows.
+     */
+    for (try = 0; try < 16; ++try) {
+	bridgereg_t             devreg;
+	unsigned                offset;
+
+	win = (try + slot) % 8;
+
+	/* If this DevIO(x) mapping area can provide
+	 * a mapping to this address, use it.
+	 */
+	msize = (win < 2) ? 0x200000 : 0x100000;
+	mmask = -msize;
+	if (space != PCIIO_SPACE_IO)
+	    mmask &= 0x3FFFFFFF;
+
+	offset = pci_addr & (msize - 1);
+
+	/* If this window can't possibly handle that request,
+	 * go on to the next window.
+	 */
+	if (((pci_addr & (msize - 1)) + req_size) > msize)
+	    continue;
+
+	devreg = pcibr_soft->bs_slot[win].bss_device;
+
+	/* Is this window "nailed down"?
+	 * If not, maybe we can use it.
+	 * (only check this the second time through)
+	 */
+	mspace = pcibr_soft->bs_slot[win].bss_devio.bssd_space;
+	if ((try > 7) && (mspace == PCIIO_SPACE_NONE)) {
+
+	    /* If this is the primary DevIO(x) window
+	     * for some other device, skip it.
+	     */
+	    if ((win != slot) &&
+		(PCIIO_VENDOR_ID_NONE !=
+		 pcibr_soft->bs_slot[win].bss_vendor_id))
+		continue;
+
+	    /* It's a free window, and we fit in it.
+	     * Set up Device(win) to our taste.
+	     */
+	    mbase = pci_addr & mmask;
+
+	    /* check that we would really get from
+	     * here to there.
+	     */
+	    if ((mbase | offset) != pci_addr)
+		continue;
+
+	    devreg &= ~BRIDGE_DEV_OFF_MASK;
+	    if (space != PCIIO_SPACE_IO)
+		devreg |= BRIDGE_DEV_DEV_IO_MEM;
+	    else
+		devreg &= ~BRIDGE_DEV_DEV_IO_MEM;
+	    devreg |= (mbase >> 20) & BRIDGE_DEV_OFF_MASK;
+
+	    /* default is WORD_VALUES.
+	     * if you specify both,
+	     * operation is undefined.
+	     */
+	    if (flags & PCIIO_BYTE_STREAM)
+		devreg |= BRIDGE_DEV_DEV_SWAP;
+	    else
+		devreg &= ~BRIDGE_DEV_DEV_SWAP;
+
+	    if (pcibr_soft->bs_slot[win].bss_device != devreg) {
+		bridge->b_device[win].reg = devreg;
+		pcibr_soft->bs_slot[win].bss_device = devreg;
+		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
+
+#if DEBUG && PCI_DEBUG
+		printk("pcibr Device(%d): 0x%lx\n", win, bridge->b_device[win].reg);
+#endif
+	    }
+	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
+	    pcibr_soft->bs_slot[win].bss_devio.bssd_base = mbase;
+	    xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
+
+#if DEBUG && PCI_DEBUG
+	    printk("%s LINE %d map to space %d space desc 0x%x[%lx..%lx] for slot %d allocates DevIO(%d) devreg 0x%x\n", 
+		    __FUNCTION__, __LINE__, space, space_desc,
+		    pci_addr, pci_addr + req_size - 1,
+		    slot, win, devreg);
+#endif
+
+	    goto done;
+	}				/* endif DevIO(x) not pointed */
+	mbase = pcibr_soft->bs_slot[win].bss_devio.bssd_base;
+
+	/* Now check for request incompat with DevIO(x)
+	 */
+	if ((mspace != space) ||
+	    (pci_addr < mbase) ||
+	    ((pci_addr + req_size) > (mbase + msize)) ||
+	    ((flags & PCIIO_BYTE_STREAM) && !(devreg & BRIDGE_DEV_DEV_SWAP)) ||
+	    (!(flags & PCIIO_BYTE_STREAM) && (devreg & BRIDGE_DEV_DEV_SWAP)))
+	    continue;
+
+	/* DevIO(x) window is pointed at PCI space
+	 * that includes our target. Calculate the
+	 * final XIO address, release the lock and
+	 * return.
+	 */
+	xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
+
+#if DEBUG && PCI_DEBUG
+	printk("%s LINE %d map to space %d [0x%p..0x%p] for slot %d uses DevIO(%d)\n",
+		__FUNCTION__, __LINE__, space,  pci_addr, pci_addr + req_size - 1, slot, win);
+#endif
+	goto done;
+    }
+
+    switch (space) {
+	/*
+	 * Accesses to device decode
+	 * areas that do a not fit
+	 * within the DevIO(x) space are
+	 * modified to be accesses via
+	 * the direct mapping areas.
+	 *
+	 * If necessary, drivers can
+	 * explicitly ask for mappings
+	 * into these address spaces,
+	 * but this should never be needed.
+	 */
+    case PCIIO_SPACE_MEM:		/* "mem space" */
+    case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
+	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
+	    BRIDGE_PCI_MEM32_LIMIT)
+	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
+	break;
+
+    case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
+	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
+	    BRIDGE_PCI_MEM64_LIMIT)
+	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
+	break;
+
+    case PCIIO_SPACE_IO:		/* "i/o space" */
+	/* Bridge Hardware Bug WAR #482741:
+	 * The 4G area that maps directly from
+	 * XIO space to PCI I/O space is busted
+	 * until Bridge Rev D.
+	 */
+	if ((pcibr_soft->bs_rev_num > BRIDGE_PART_REV_C) &&
+	    ((pci_addr + BRIDGE_PCI_IO_BASE + req_size - 1) <=
+	     BRIDGE_PCI_IO_LIMIT))
+	    xio_addr = pci_addr + BRIDGE_PCI_IO_BASE;
+	break;
+    }
+
+    /* Check that "Direct PIO" byteswapping matches,
+     * try to change it if it does not.
+     */
+    if (xio_addr != XIO_NOWHERE) {
+	unsigned                bst;	/* nonzero to set bytestream */
+	unsigned               *bfp;	/* addr of record of how swapper is set */
+	unsigned                swb;	/* which control bit to mung */
+	unsigned                bfo;	/* current swapper setting */
+	unsigned                bfn;	/* desired swapper setting */
+
+	bfp = ((space == PCIIO_SPACE_IO)
+	       ? (&pcibr_soft->bs_pio_end_io)
+	       : (&pcibr_soft->bs_pio_end_mem));
+
+	bfo = *bfp;
+
+	bst = flags & PCIIO_BYTE_STREAM;
+
+	bfn = bst ? PCIIO_BYTE_STREAM : PCIIO_WORD_VALUES;
+
+	if (bfn == bfo) {		/* we already match. */
+	    ;
+	} else if (bfo != 0) {		/* we have a conflict. */
+#if DEBUG && PCI_DEBUG
+	    printk("pcibr_addr_pci_to_xio: swap conflict in space %d , was%s%s, want%s%s\n",
+		    space, 
+		    bfo & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
+		    bfo & PCIIO_WORD_VALUES ? " WORD_VALUES" : "",
+		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
+		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
+#endif
+	    xio_addr = XIO_NOWHERE;
+	} else {			/* OK to make the change. */
+	    bridgereg_t             octl, nctl;
+
+	    swb = (space == PCIIO_SPACE_IO) ? BRIDGE_CTRL_IO_SWAP : BRIDGE_CTRL_MEM_SWAP;
+	    octl = bridge->b_wid_control;
+	    nctl = bst ? octl | swb : octl & ~swb;
+
+	    if (octl != nctl)		/* make the change if any */
+		bridge->b_wid_control = nctl;
+
+	    *bfp = bfn;			/* record the assignment */
+
+#if DEBUG && PCI_DEBUG
+	    printk("pcibr_addr_pci_to_xio: swap for space %d  set to%s%s\n",
+		    space, 
+		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
+		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
+#endif
+	}
+    }
+  done:
+    pcibr_unlock(pcibr_soft, s);
+    return xio_addr;
+}
+
+/*ARGSUSED6 */
+pcibr_piomap_t
+pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
+		   device_desc_t dev_desc,
+		   pciio_space_t space,
+		   iopaddr_t pci_addr,
+		   size_t req_size,
+		   size_t req_size_max,
+		   unsigned flags)
+{
+    pcibr_info_t	    pcibr_info = pcibr_info_get(pconn_vhdl);
+    pciio_info_t            pciio_info = &pcibr_info->f_c;
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+
+    pcibr_piomap_t         *mapptr;
+    pcibr_piomap_t          maplist;
+    pcibr_piomap_t          pcibr_piomap;
+    iopaddr_t               xio_addr;
+    xtalk_piomap_t          xtalk_piomap;
+    unsigned long           s;
+
+    /* Make sure that the req sizes are non-zero */
+    if ((req_size < 1) || (req_size_max < 1))
+	return NULL;
+
+    /*
+     * Code to translate slot/space/addr
+     * into xio_addr is common between
+     * this routine and pcibr_piotrans_addr.
+     */
+    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
+
+    if (xio_addr == XIO_NOWHERE)
+	return NULL;
+
+    /* Check the piomap list to see if there is already an allocated
+     * piomap entry but not in use. If so use that one. Otherwise
+     * allocate a new piomap entry and add it to the piomap list
+     */
+    mapptr = &(pcibr_info->f_piomap);
+
+    s = pcibr_lock(pcibr_soft);
+    for (pcibr_piomap = *mapptr;
+	 pcibr_piomap != NULL;
+	 pcibr_piomap = pcibr_piomap->bp_next) {
+	if (pcibr_piomap->bp_mapsz == 0)
+	    break;
+    }
+
+    if (pcibr_piomap)
+	mapptr = NULL;
+    else {
+	pcibr_unlock(pcibr_soft, s);
+	NEW(pcibr_piomap);
+    }
+
+    pcibr_piomap->bp_dev = pconn_vhdl;
+    pcibr_piomap->bp_slot = pciio_slot;
+    pcibr_piomap->bp_flags = flags;
+    pcibr_piomap->bp_space = space;
+    pcibr_piomap->bp_pciaddr = pci_addr;
+    pcibr_piomap->bp_mapsz = req_size;
+    pcibr_piomap->bp_soft = pcibr_soft;
+    pcibr_piomap->bp_toc[0] = ATOMIC_INIT(0);
+
+    if (mapptr) {
+	s = pcibr_lock(pcibr_soft);
+	maplist = *mapptr;
+	pcibr_piomap->bp_next = maplist;
+	*mapptr = pcibr_piomap;
+    }
+    pcibr_unlock(pcibr_soft, s);
+
+
+    if (pcibr_piomap) {
+	xtalk_piomap =
+	    xtalk_piomap_alloc(xconn_vhdl, 0,
+			       xio_addr,
+			       req_size, req_size_max,
+			       flags & PIOMAP_FLAGS);
+	if (xtalk_piomap) {
+	    pcibr_piomap->bp_xtalk_addr = xio_addr;
+	    pcibr_piomap->bp_xtalk_pio = xtalk_piomap;
+	} else {
+	    pcibr_piomap->bp_mapsz = 0;
+	    pcibr_piomap = 0;
+	}
+    }
+    return pcibr_piomap;
+}
+
+/*ARGSUSED */
+void
+pcibr_piomap_free(pcibr_piomap_t pcibr_piomap)
+{
+    xtalk_piomap_free(pcibr_piomap->bp_xtalk_pio);
+    pcibr_piomap->bp_xtalk_pio = 0;
+    pcibr_piomap->bp_mapsz = 0;
+}
+
+/*ARGSUSED */
+caddr_t
+pcibr_piomap_addr(pcibr_piomap_t pcibr_piomap,
+		  iopaddr_t pci_addr,
+		  size_t req_size)
+{
+    return xtalk_piomap_addr(pcibr_piomap->bp_xtalk_pio,
+			     pcibr_piomap->bp_xtalk_addr +
+			     pci_addr - pcibr_piomap->bp_pciaddr,
+			     req_size);
+}
+
+/*ARGSUSED */
+void
+pcibr_piomap_done(pcibr_piomap_t pcibr_piomap)
+{
+    xtalk_piomap_done(pcibr_piomap->bp_xtalk_pio);
+}
+
+/*ARGSUSED */
+caddr_t
+pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
+		    device_desc_t dev_desc,
+		    pciio_space_t space,
+		    iopaddr_t pci_addr,
+		    size_t req_size,
+		    unsigned flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+
+    iopaddr_t               xio_addr;
+
+    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
+
+    if (xio_addr == XIO_NOWHERE)
+	return NULL;
+
+    return xtalk_piotrans_addr(xconn_vhdl, 0, xio_addr, req_size, flags & PIOMAP_FLAGS);
+}
+
+/*
+ * PIO Space allocation and management.
+ *      Allocate and Manage the PCI PIO space (mem and io space)
+ *      This routine is pretty simplistic at this time, and
+ *      does pretty trivial management of allocation and freeing..
+ *      The current scheme is prone for fragmentation..
+ *      Change the scheme to use bitmaps.
+ */
+
+/*ARGSUSED */
+iopaddr_t
+pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
+		     device_desc_t dev_desc,
+		     pciio_space_t space,
+		     size_t req_size,
+		     size_t alignment)
+{
+    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
+    pciio_info_t            pciio_info = &pcibr_info->f_c;
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+    pciio_piospace_t        piosp;
+    unsigned long           s;
+
+    iopaddr_t              *pciaddr, *pcilast;
+    iopaddr_t               start_addr;
+    size_t                  align_mask;
+
+    /*
+     * Check for proper alignment
+     */
+    ASSERT(alignment >= NBPP);
+    ASSERT((alignment & (alignment - 1)) == 0);
+
+    align_mask = alignment - 1;
+    s = pcibr_lock(pcibr_soft);
+
+    /*
+     * First look if a previously allocated chunk exists.
+     */
+    if ((piosp = pcibr_info->f_piospace)) {
+	/*
+	 * Look through the list for a right sized free chunk.
+	 */
+	do {
+	    if (piosp->free &&
+		(piosp->space == space) &&
+		(piosp->count >= req_size) &&
+		!(piosp->start & align_mask)) {
+		piosp->free = 0;
+		pcibr_unlock(pcibr_soft, s);
+		return piosp->start;
+	    }
+	    piosp = piosp->next;
+	} while (piosp);
+    }
+    ASSERT(!piosp);
+
+    switch (space) {
+    case PCIIO_SPACE_IO:
+	pciaddr = &pcibr_soft->bs_spinfo.pci_io_base;
+	pcilast = &pcibr_soft->bs_spinfo.pci_io_last;
+	break;
+    case PCIIO_SPACE_MEM:
+    case PCIIO_SPACE_MEM32:
+	pciaddr = &pcibr_soft->bs_spinfo.pci_mem_base;
+	pcilast = &pcibr_soft->bs_spinfo.pci_mem_last;
+	break;
+    default:
+	ASSERT(0);
+	pcibr_unlock(pcibr_soft, s);
+	return 0;
+    }
+
+    start_addr = *pciaddr;
+
+    /*
+     * Align start_addr.
+     */
+    if (start_addr & align_mask)
+	start_addr = (start_addr + align_mask) & ~align_mask;
+
+    if ((start_addr + req_size) > *pcilast) {
+	/*
+	 * If too big a request, reject it.
+	 */
+	pcibr_unlock(pcibr_soft, s);
+	return 0;
+    }
+    *pciaddr = (start_addr + req_size);
+
+    NEW(piosp);
+    piosp->free = 0;
+    piosp->space = space;
+    piosp->start = start_addr;
+    piosp->count = req_size;
+    piosp->next = pcibr_info->f_piospace;
+    pcibr_info->f_piospace = piosp;
+
+    pcibr_unlock(pcibr_soft, s);
+    return start_addr;
+}
+
+/*ARGSUSED */
+void
+pcibr_piospace_free(devfs_handle_t pconn_vhdl,
+		    pciio_space_t space,
+		    iopaddr_t pciaddr,
+		    size_t req_size)
+{
+    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
+
+    pciio_piospace_t        piosp;
+    unsigned long           s;
+    char                    name[1024];
+
+    /*
+     * Look through the bridge data structures for the pciio_piospace_t
+     * structure corresponding to  'pciaddr'
+     */
+    s = pcibr_lock(pcibr_soft);
+    piosp = pcibr_info->f_piospace;
+    while (piosp) {
+	/*
+	 * Piospace free can only be for the complete
+	 * chunk and not parts of it..
+	 */
+	if (piosp->start == pciaddr) {
+	    if (piosp->count == req_size)
+		break;
+	    /*
+	     * Improper size passed for freeing..
+	     * Print a message and break;
+	     */
+	    hwgraph_vertex_name_get(pconn_vhdl, name, 1024);
+	    printk(KERN_WARNING  "pcibr_piospace_free: error");
+	    printk(KERN_WARNING  "Device %s freeing size (0x%lx) different than allocated (0x%lx)",
+					name, req_size, piosp->count);
+	    printk(KERN_WARNING  "Freeing 0x%lx instead", piosp->count);
+	    break;
+	}
+	piosp = piosp->next;
+    }
+
+    if (!piosp) {
+	printk(KERN_WARNING  
+		"pcibr_piospace_free: Address 0x%lx size 0x%lx - No match\n",
+		pciaddr, req_size);
+	pcibr_unlock(pcibr_soft, s);
+	return;
+    }
+    piosp->free = 1;
+    pcibr_unlock(pcibr_soft, s);
+    return;
+}
+
+/* =====================================================================
+ *    DMA MANAGEMENT
+ *
+ *      The Bridge ASIC provides three methods of doing
+ *      DMA: via a "direct map" register available in
+ *      32-bit PCI space (which selects a contiguous 2G
+ *      address space on some other widget), via
+ *      "direct" addressing via 64-bit PCI space (all
+ *      destination information comes from the PCI
+ *      address, including transfer attributes), and via
+ *      a "mapped" region that allows a bunch of
+ *      different small mappings to be established with
+ *      the PMU.
+ *
+ *      For efficiency, we most prefer to use the 32-bit
+ *      direct mapping facility, since it requires no
+ *      resource allocations. The advantage of using the
+ *      PMU over the 64-bit direct is that single-cycle
+ *      PCI addressing can be used; the advantage of
+ *      using 64-bit direct over PMU addressing is that
+ *      we do not have to allocate entries in the PMU.
+ */
+
+/*
+ * Convert PCI-generic software flags and Bridge-specific software flags
+ * into Bridge-specific Direct Map attribute bits.
+ */
+LOCAL iopaddr_t
+pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft)
+{
+    iopaddr_t               attributes = 0;
+
+    /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */
+#ifdef LATER
+    ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64));
+#endif
+
+    /* Generic macro flags
+     */
+    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
+	attributes &= ~PCI64_ATTR_BAR;	/* no barrier bit */
+	attributes |= PCI64_ATTR_PREF;	/* prefetch on */
+    }
+    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
+	attributes |= PCI64_ATTR_BAR;	/* barrier bit on */
+	attributes &= ~PCI64_ATTR_PREF;	/* disable prefetch */
+    }
+    /* Generic detail flags
+     */
+    if (flags & PCIIO_PREFETCH)
+	attributes |= PCI64_ATTR_PREF;
+    if (flags & PCIIO_NOPREFETCH)
+	attributes &= ~PCI64_ATTR_PREF;
+
+    /* the swap bit is in the address attributes for xbridge */
+    if (pcibr_soft->bs_xbridge) {
+    	if (flags & PCIIO_BYTE_STREAM)
+        	attributes |= PCI64_ATTR_SWAP;
+    	if (flags & PCIIO_WORD_VALUES)
+        	attributes &= ~PCI64_ATTR_SWAP;
+    }
+
+    /* Provider-specific flags
+     */
+    if (flags & PCIBR_BARRIER)
+	attributes |= PCI64_ATTR_BAR;
+    if (flags & PCIBR_NOBARRIER)
+	attributes &= ~PCI64_ATTR_BAR;
+
+    if (flags & PCIBR_PREFETCH)
+	attributes |= PCI64_ATTR_PREF;
+    if (flags & PCIBR_NOPREFETCH)
+	attributes &= ~PCI64_ATTR_PREF;
+
+    if (flags & PCIBR_PRECISE)
+	attributes |= PCI64_ATTR_PREC;
+    if (flags & PCIBR_NOPRECISE)
+	attributes &= ~PCI64_ATTR_PREC;
+
+    if (flags & PCIBR_VCHAN1)
+	attributes |= PCI64_ATTR_VIRTUAL;
+    if (flags & PCIBR_VCHAN0)
+	attributes &= ~PCI64_ATTR_VIRTUAL;
+
+    return (attributes);
+}
+
+/*
+ * Convert PCI-generic software flags and Bridge-specific software flags
+ * into Bridge-specific Address Translation Entry attribute bits.
+ */
+LOCAL bridge_ate_t
+pcibr_flags_to_ate(unsigned flags)
+{
+    bridge_ate_t            attributes;
+
+    /* default if nothing specified:
+     * NOBARRIER
+     * NOPREFETCH
+     * NOPRECISE
+     * COHERENT
+     * Plus the valid bit
+     */
+    attributes = ATE_CO | ATE_V;
+
+    /* Generic macro flags
+     */
+    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
+	attributes &= ~ATE_BAR;		/* no barrier */
+	attributes |= ATE_PREF;		/* prefetch on */
+    }
+    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
+	attributes |= ATE_BAR;		/* barrier bit on */
+	attributes &= ~ATE_PREF;	/* disable prefetch */
+    }
+    /* Generic detail flags
+     */
+    if (flags & PCIIO_PREFETCH)
+	attributes |= ATE_PREF;
+    if (flags & PCIIO_NOPREFETCH)
+	attributes &= ~ATE_PREF;
+
+    /* Provider-specific flags
+     */
+    if (flags & PCIBR_BARRIER)
+	attributes |= ATE_BAR;
+    if (flags & PCIBR_NOBARRIER)
+	attributes &= ~ATE_BAR;
+
+    if (flags & PCIBR_PREFETCH)
+	attributes |= ATE_PREF;
+    if (flags & PCIBR_NOPREFETCH)
+	attributes &= ~ATE_PREF;
+
+    if (flags & PCIBR_PRECISE)
+	attributes |= ATE_PREC;
+    if (flags & PCIBR_NOPRECISE)
+	attributes &= ~ATE_PREC;
+
+    return (attributes);
+}
+
+/*ARGSUSED */
+pcibr_dmamap_t
+pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
+		   device_desc_t dev_desc,
+		   size_t req_size_max,
+		   unsigned flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    pciio_slot_t            slot;
+    xwidgetnum_t            xio_port;
+
+    xtalk_dmamap_t          xtalk_dmamap;
+    pcibr_dmamap_t          pcibr_dmamap;
+    int                     ate_count;
+    int                     ate_index;
+
+    /* merge in forced flags */
+    flags |= pcibr_soft->bs_dma_flags;
+
+#ifdef IRIX
+    NEWf(pcibr_dmamap, flags);
+#else
+    /*
+     * On SNIA64, these maps are pre-allocated because pcibr_dmamap_alloc()
+     * can be called within an interrupt thread.
+     */
+    pcibr_dmamap = (pcibr_dmamap_t)get_free_pciio_dmamap(pcibr_soft->bs_vhdl);
+#endif
+
+    if (!pcibr_dmamap)
+	return 0;
+
+    xtalk_dmamap = xtalk_dmamap_alloc(xconn_vhdl, dev_desc, req_size_max,
+				      flags & DMAMAP_FLAGS);
+    if (!xtalk_dmamap) {
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_attach: xtalk_dmamap_alloc failed\n");
+#endif
+#ifdef IRIX
+	DEL(pcibr_dmamap);
+#else
+	free_pciio_dmamap(pcibr_dmamap);
+#endif
+	return 0;
+    }
+    xio_port = pcibr_soft->bs_mxid;
+    slot = pciio_info_slot_get(pciio_info);
+
+    pcibr_dmamap->bd_dev = pconn_vhdl;
+    pcibr_dmamap->bd_slot = slot;
+    pcibr_dmamap->bd_soft = pcibr_soft;
+    pcibr_dmamap->bd_xtalk = xtalk_dmamap;
+    pcibr_dmamap->bd_max_size = req_size_max;
+    pcibr_dmamap->bd_xio_port = xio_port;
+
+    if (flags & PCIIO_DMA_A64) {
+	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D64_BITS)) {
+	    iopaddr_t               pci_addr;
+	    int                     have_rrbs;
+	    int                     min_rrbs;
+
+	    /* Device is capable of A64 operations,
+	     * and the attributes of the DMA are
+	     * consistant with any previous DMA
+	     * mappings using shared resources.
+	     */
+
+	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
+
+	    pcibr_dmamap->bd_flags = flags;
+	    pcibr_dmamap->bd_xio_addr = 0;
+	    pcibr_dmamap->bd_pci_addr = pci_addr;
+
+	    /* Make sure we have an RRB (or two).
+	     */
+	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
+		if (flags & PCIBR_VCHAN1)
+		    slot += PCIBR_RRB_SLOT_VIRTUAL;
+		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
+		if (have_rrbs < 2) {
+		    if (pci_addr & PCI64_ATTR_PREF)
+			min_rrbs = 2;
+		    else
+			min_rrbs = 1;
+		    if (have_rrbs < min_rrbs)
+			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
+		}
+	    }
+#if PCIBR_ATE_DEBUG
+	    printk("pcibr_dmamap_alloc: using direct64\n");
+#endif
+	    return pcibr_dmamap;
+	}
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_dmamap_alloc: unable to use direct64\n");
+#endif
+	flags &= ~PCIIO_DMA_A64;
+    }
+    if (flags & PCIIO_FIXED) {
+	/* warning: mappings may fail later,
+	 * if direct32 can't get to the address.
+	 */
+	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
+	    /* User desires DIRECT A32 operations,
+	     * and the attributes of the DMA are
+	     * consistant with any previous DMA
+	     * mappings using shared resources.
+	     * Mapping calls may fail if target
+	     * is outside the direct32 range.
+	     */
+#if PCIBR_ATE_DEBUG
+	    printk("pcibr_dmamap_alloc: using direct32\n");
+#endif
+	    pcibr_dmamap->bd_flags = flags;
+	    pcibr_dmamap->bd_xio_addr = pcibr_soft->bs_dir_xbase;
+	    pcibr_dmamap->bd_pci_addr = PCI32_DIRECT_BASE;
+	    return pcibr_dmamap;
+	}
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_dmamap_alloc: unable to use direct32\n");
+#endif
+	/* If the user demands FIXED and we can't
+	 * give it to him, fail.
+	 */
+	xtalk_dmamap_free(xtalk_dmamap);
+#ifdef IRIX
+	DEL(pcibr_dmamap);
+#else
+	free_pciio_dmamap(pcibr_dmamap);
+#endif
+	return 0;
+    }
+    /*
+     * Allocate Address Translation Entries from the mapping RAM.
+     * Unless the PCIBR_NO_ATE_ROUNDUP flag is specified,
+     * the maximum number of ATEs is based on the worst-case
+     * scenario, where the requested target is in the
+     * last byte of an ATE; thus, mapping IOPGSIZE+2
+     * does end up requiring three ATEs.
+     */
+    if (!(flags & PCIBR_NO_ATE_ROUNDUP)) {
+	ate_count = IOPG((IOPGSIZE - 1)	/* worst case start offset */
+		     +req_size_max	/* max mapping bytes */
+		     - 1) + 1;		/* round UP */
+    } else {	/* assume requested target is page aligned */
+	ate_count = IOPG(req_size_max   /* max mapping bytes */
+		     - 1) + 1;		/* round UP */
+    }
+
+    ate_index = pcibr_ate_alloc(pcibr_soft, ate_count);
+
+    if (ate_index != -1) {
+	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_PMU_BITS)) {
+	    bridge_ate_t            ate_proto;
+	    int                     have_rrbs;
+	    int                     min_rrbs;
+
+#if PCIBR_ATE_DEBUG
+	    printk("pcibr_dmamap_alloc: using PMU\n");
+#endif
+
+	    ate_proto = pcibr_flags_to_ate(flags);
+
+	    pcibr_dmamap->bd_flags = flags;
+	    pcibr_dmamap->bd_pci_addr =
+		PCI32_MAPPED_BASE + IOPGSIZE * ate_index;
+	    /*
+	     * for xbridge the byte-swap bit == bit 29 of PCI address
+	     */
+	    if (pcibr_soft->bs_xbridge) {
+		    if (flags & PCIIO_BYTE_STREAM)
+			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
+		    /*
+		     * If swap was set in bss_device in pcibr_endian_set()
+		     * we need to change the address bit.
+		     */
+		    if (pcibr_soft->bs_slot[slot].bss_device & 
+							BRIDGE_DEV_SWAP_PMU)
+			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
+		    if (flags & PCIIO_WORD_VALUES)
+			    ATE_SWAP_OFF(pcibr_dmamap->bd_pci_addr);
+	    }
+	    pcibr_dmamap->bd_xio_addr = 0;
+	    pcibr_dmamap->bd_ate_ptr = pcibr_ate_addr(pcibr_soft, ate_index);
+	    pcibr_dmamap->bd_ate_index = ate_index;
+	    pcibr_dmamap->bd_ate_count = ate_count;
+	    pcibr_dmamap->bd_ate_proto = ate_proto;
+
+	    /* Make sure we have an RRB (or two).
+	     */
+	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
+		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
+		if (have_rrbs < 2) {
+		    if (ate_proto & ATE_PREF)
+			min_rrbs = 2;
+		    else
+			min_rrbs = 1;
+		    if (have_rrbs < min_rrbs)
+			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
+		}
+	    }
+	    if (ate_index >= pcibr_soft->bs_int_ate_size && 
+				!pcibr_soft->bs_xbridge) {
+		bridge_t               *bridge = pcibr_soft->bs_base;
+		volatile unsigned      *cmd_regp;
+		unsigned                cmd_reg;
+		unsigned long           s;
+
+		pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM;
+
+		s = pcibr_lock(pcibr_soft);
+		cmd_regp = &(bridge->
+			     b_type0_cfg_dev[slot].
+			     l[PCI_CFG_COMMAND / 4]);
+		cmd_reg = *cmd_regp;
+		pcibr_soft->bs_slot[slot].bss_cmd_pointer = cmd_regp;
+		pcibr_soft->bs_slot[slot].bss_cmd_shadow = cmd_reg;
+		pcibr_unlock(pcibr_soft, s);
+	    }
+	    return pcibr_dmamap;
+	}
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_dmamap_alloc: unable to use PMU\n");
+#endif
+	pcibr_ate_free(pcibr_soft, ate_index, ate_count);
+    }
+    /* total failure: sorry, you just can't
+     * get from here to there that way.
+     */
+#if PCIBR_ATE_DEBUG
+    printk("pcibr_dmamap_alloc: complete failure.\n");
+#endif
+    xtalk_dmamap_free(xtalk_dmamap);
+#ifdef IRIX
+    DEL(pcibr_dmamap);
+#else
+    free_pciio_dmamap(pcibr_dmamap);
+#endif
+    return 0;
+}
+
+/*ARGSUSED */
+void
+pcibr_dmamap_free(pcibr_dmamap_t pcibr_dmamap)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
+    pciio_slot_t            slot = pcibr_dmamap->bd_slot;
+
+    unsigned                flags = pcibr_dmamap->bd_flags;
+
+    /* Make sure that bss_ext_ates_active
+     * is properly kept up to date.
+     */
+
+    if (PCIBR_DMAMAP_BUSY & flags)
+	if (PCIBR_DMAMAP_SSRAM & flags)
+	    atomic_dec(&(pcibr_soft->bs_slot[slot]. bss_ext_ates_active));
+
+    xtalk_dmamap_free(pcibr_dmamap->bd_xtalk);
+
+    if (pcibr_dmamap->bd_flags & PCIIO_DMA_A64) {
+	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_D64_BITS);
+    }
+    if (pcibr_dmamap->bd_ate_count) {
+	pcibr_ate_free(pcibr_dmamap->bd_soft,
+		       pcibr_dmamap->bd_ate_index,
+		       pcibr_dmamap->bd_ate_count);
+	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS);
+    }
+#ifdef IRIX
+    DEL(pcibr_dmamap);
+#else
+    free_pciio_dmamap(pcibr_dmamap);
+#endif
+}
+
+/*
+ * Setup an Address Translation Entry as specified.  Use either the Bridge
+ * internal maps or the external map RAM, as appropriate.
+ */
+LOCAL bridge_ate_p
+pcibr_ate_addr(pcibr_soft_t pcibr_soft,
+	       int ate_index)
+{
+    bridge_t *bridge = pcibr_soft->bs_base;
+
+    return (ate_index < pcibr_soft->bs_int_ate_size)
+	? &(bridge->b_int_ate_ram[ate_index].wr)
+	: &(bridge->b_ext_ate_ram[ate_index]);
+}
+
+/*
+ *    pcibr_addr_xio_to_pci: given a PIO range, hand
+ *      back the corresponding base PCI MEM address;
+ *      this is used to short-circuit DMA requests that
+ *      loop back onto this PCI bus.
+ */
+LOCAL iopaddr_t
+pcibr_addr_xio_to_pci(pcibr_soft_t soft,
+		      iopaddr_t xio_addr,
+		      size_t req_size)
+{
+    iopaddr_t               xio_lim = xio_addr + req_size - 1;
+    iopaddr_t               pci_addr;
+    pciio_slot_t            slot;
+
+    if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
+	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
+	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
+	return pci_addr;
+    }
+    if ((xio_addr >= BRIDGE_PCI_MEM64_BASE) &&
+	(xio_lim <= BRIDGE_PCI_MEM64_LIMIT)) {
+	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
+	return pci_addr;
+    }
+    for (slot = 0; slot < 8; ++slot)
+	if ((xio_addr >= BRIDGE_DEVIO(slot)) &&
+	    (xio_lim < BRIDGE_DEVIO(slot + 1))) {
+	    bridgereg_t             dev;
+
+	    dev = soft->bs_slot[slot].bss_device;
+	    pci_addr = dev & BRIDGE_DEV_OFF_MASK;
+	    pci_addr <<= BRIDGE_DEV_OFF_ADDR_SHFT;
+	    pci_addr += xio_addr - BRIDGE_DEVIO(slot);
+	    return (dev & BRIDGE_DEV_DEV_IO_MEM) ? pci_addr : PCI_NOWHERE;
+	}
+    return 0;
+}
+
+/* We are starting to get more complexity
+ * surrounding writing ATEs, so pull
+ * the writing code into this new function.
+ */
+
+#if PCIBR_FREEZE_TIME
+#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs)
+#else
+#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, cmd_regs)
+#endif
+
+LOCAL unsigned
+ate_freeze(pcibr_dmamap_t pcibr_dmamap,
+#if PCIBR_FREEZE_TIME
+	   unsigned *freeze_time_ptr,
+#endif
+	   unsigned *cmd_regs)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
+#ifdef LATER
+    int                     dma_slot = pcibr_dmamap->bd_slot;
+#endif
+    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
+    int                     slot;
+
+    unsigned long           s;
+    unsigned                cmd_reg;
+    volatile unsigned      *cmd_lwa;
+    unsigned                cmd_lwd;
+
+    if (!ext_ates)
+	return 0;
+
+    /* Bridge Hardware Bug WAR #484930:
+     * Bridge can't handle updating External ATEs
+     * while DMA is occuring that uses External ATEs,
+     * even if the particular ATEs involved are disjoint.
+     */
+
+    /* need to prevent anyone else from
+     * unfreezing the grant while we
+     * are working; also need to prevent
+     * this thread from being interrupted
+     * to keep PCI grant freeze time
+     * at an absolute minimum.
+     */
+    s = pcibr_lock(pcibr_soft);
+
+#ifdef LATER
+    /* just in case pcibr_dmamap_done was not called */
+    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
+	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
+	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
+	    atomic_dec(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
+	xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
+    }
+#endif	/* LATER */
+#if PCIBR_FREEZE_TIME
+    *freeze_time_ptr = get_timestamp();
+#endif
+
+    cmd_lwa = 0;
+    for (slot = 0; slot < 8; ++slot)
+	if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
+	    cmd_reg = pcibr_soft->
+		bs_slot[slot].
+		bss_cmd_shadow;
+	    if (cmd_reg & PCI_CMD_BUS_MASTER) {
+		cmd_lwa = pcibr_soft->
+		    bs_slot[slot].
+		    bss_cmd_pointer;
+		cmd_lwd = cmd_reg ^ PCI_CMD_BUS_MASTER;
+		cmd_lwa[0] = cmd_lwd;
+	    }
+	    cmd_regs[slot] = cmd_reg;
+	} else
+	    cmd_regs[slot] = 0;
+
+    if (cmd_lwa) {
+	    bridge_t	*bridge = pcibr_soft->bs_base;
+
+	    /* Read the last master bit that has been cleared. This PIO read
+	     * on the PCI bus is to ensure the completion of any DMAs that
+	     * are due to bus requests issued by PCI devices before the
+	     * clearing of master bits.
+	     */
+	    cmd_lwa[0];
+
+	    /* Flush all the write buffers in the bridge */
+	    for (slot = 0; slot < 8; ++slot)
+		    if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
+			    /* Flush the write buffer associated with this
+			     * PCI device which might be using dma map RAM.
+			     */
+			    bridge->b_wr_req_buf[slot].reg;
+		    }
+    }
+    return s;
+}
+
+#define	ATE_WRITE()    ate_write(ate_ptr, ate_count, ate)
+
+LOCAL void
+ate_write(bridge_ate_p ate_ptr,
+	  int ate_count,
+	  bridge_ate_t ate)
+{
+    while (ate_count-- > 0) {
+	*ate_ptr++ = ate;
+	ate += IOPGSIZE;
+    }
+}
+
+
+#if PCIBR_FREEZE_TIME
+#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s)
+#else
+#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s)
+#endif
+
+LOCAL void
+ate_thaw(pcibr_dmamap_t pcibr_dmamap,
+	 int ate_index,
+#if PCIBR_FREEZE_TIME
+	 bridge_ate_t ate,
+	 int ate_total,
+	 unsigned freeze_time_start,
+#endif
+	 unsigned *cmd_regs,
+	 unsigned s)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
+    int                     dma_slot = pcibr_dmamap->bd_slot;
+    int                     slot;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
+
+    unsigned                cmd_reg;
+
+#if PCIBR_FREEZE_TIME
+    unsigned                freeze_time;
+    static unsigned         max_freeze_time = 0;
+    static unsigned         max_ate_total;
+#endif
+
+    if (!ext_ates)
+	return;
+
+    /* restore cmd regs */
+    for (slot = 0; slot < 8; ++slot)
+	if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER)
+	    bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
+
+    pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
+    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
+
+#if PCIBR_FREEZE_TIME
+    freeze_time = get_timestamp() - freeze_time_start;
+
+    if ((max_freeze_time < freeze_time) ||
+	(max_ate_total < ate_total)) {
+	if (max_freeze_time < freeze_time)
+	    max_freeze_time = freeze_time;
+	if (max_ate_total < ate_total)
+	    max_ate_total = ate_total;
+	pcibr_unlock(pcibr_soft, s);
+	printk("%s: pci freeze time %d usec for %d ATEs\n"
+		"\tfirst ate: %R\n",
+		pcibr_soft->bs_name,
+		freeze_time * 1000 / 1250,
+		ate_total,
+		ate, ate_bits);
+    } else
+#endif
+	pcibr_unlock(pcibr_soft, s);
+}
+
+/*ARGSUSED */
+iopaddr_t
+pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap,
+		  paddr_t paddr,
+		  size_t req_size)
+{
+    pcibr_soft_t            pcibr_soft;
+    iopaddr_t               xio_addr;
+    xwidgetnum_t            xio_port;
+    iopaddr_t               pci_addr;
+    unsigned                flags;
+
+    ASSERT(pcibr_dmamap != NULL);
+    ASSERT(req_size > 0);
+    ASSERT(req_size <= pcibr_dmamap->bd_max_size);
+
+    pcibr_soft = pcibr_dmamap->bd_soft;
+
+    flags = pcibr_dmamap->bd_flags;
+
+    xio_addr = xtalk_dmamap_addr(pcibr_dmamap->bd_xtalk, paddr, req_size);
+    if (XIO_PACKED(xio_addr)) {
+	xio_port = XIO_PORT(xio_addr);
+	xio_addr = XIO_ADDR(xio_addr);
+    } else
+	xio_port = pcibr_dmamap->bd_xio_port;
+
+    /* If this DMA is to an address that
+     * refers back to this Bridge chip,
+     * reduce it back to the correct
+     * PCI MEM address.
+     */
+    if (xio_port == pcibr_soft->bs_xid) {
+	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
+    } else if (flags & PCIIO_DMA_A64) {
+	/* A64 DMA:
+	 * always use 64-bit direct mapping,
+	 * which always works.
+	 * Device(x) was set up during
+	 * dmamap allocation.
+	 */
+
+	/* attributes are already bundled up into bd_pci_addr.
+	 */
+	pci_addr = pcibr_dmamap->bd_pci_addr
+	    | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT)
+	    | xio_addr;
+
+	/* Bridge Hardware WAR #482836:
+	 * If the transfer is not cache aligned
+	 * and the Bridge Rev is <= B, force
+	 * prefetch to be off.
+	 */
+	if (flags & PCIBR_NOPREFETCH)
+	    pci_addr &= ~PCI64_ATTR_PREF;
+
+#if DEBUG && PCIBR_DMA_DEBUG
+	printk("pcibr_dmamap_addr (direct64):\n"
+		"\twanted paddr [0x%x..0x%x]\n"
+		"\tXIO port 0x%x offset 0x%x\n"
+		"\treturning PCI 0x%x\n",
+		paddr, paddr + req_size - 1,
+		xio_port, xio_addr, pci_addr);
+#endif
+    } else if (flags & PCIIO_FIXED) {
+	/* A32 direct DMA:
+	 * always use 32-bit direct mapping,
+	 * which may fail.
+	 * Device(x) was set up during
+	 * dmamap allocation.
+	 */
+
+	if (xio_port != pcibr_soft->bs_dir_xport)
+	    pci_addr = 0;		/* wrong DIDN */
+	else if (xio_addr < pcibr_dmamap->bd_xio_addr)
+	    pci_addr = 0;		/* out of range */
+	else if ((xio_addr + req_size) >
+		 (pcibr_dmamap->bd_xio_addr + BRIDGE_DMA_DIRECT_SIZE))
+	    pci_addr = 0;		/* out of range */
+	else
+	    pci_addr = pcibr_dmamap->bd_pci_addr +
+		xio_addr - pcibr_dmamap->bd_xio_addr;
+
+#if DEBUG && PCIBR_DMA_DEBUG
+	printk("pcibr_dmamap_addr (direct32):\n"
+		"\twanted paddr [0x%x..0x%x]\n"
+		"\tXIO port 0x%x offset 0x%x\n"
+		"\treturning PCI 0x%x\n",
+		paddr, paddr + req_size - 1,
+		xio_port, xio_addr, pci_addr);
+#endif
+    } else {
+	bridge_t               *bridge = pcibr_soft->bs_base;
+	iopaddr_t               offset = IOPGOFF(xio_addr);
+	bridge_ate_t            ate_proto = pcibr_dmamap->bd_ate_proto;
+	int                     ate_count = IOPG(offset + req_size - 1) + 1;
+
+	int                     ate_index = pcibr_dmamap->bd_ate_index;
+	unsigned                cmd_regs[8];
+	unsigned                s;
+
+#if PCIBR_FREEZE_TIME
+	int                     ate_total = ate_count;
+	unsigned                freeze_time;
+#endif
+
+#if PCIBR_ATE_DEBUG
+	bridge_ate_t            ate_cmp;
+	bridge_ate_p            ate_cptr;
+	unsigned                ate_lo, ate_hi;
+	int                     ate_bad = 0;
+	int                     ate_rbc = 0;
+#endif
+	bridge_ate_p            ate_ptr = pcibr_dmamap->bd_ate_ptr;
+	bridge_ate_t            ate;
+
+	/* Bridge Hardware WAR #482836:
+	 * If the transfer is not cache aligned
+	 * and the Bridge Rev is <= B, force
+	 * prefetch to be off.
+	 */
+	if (flags & PCIBR_NOPREFETCH)
+	    ate_proto &= ~ATE_PREF;
+
+	ate = ate_proto
+	    | (xio_port << ATE_TIDSHIFT)
+	    | (xio_addr - offset);
+
+	pci_addr = pcibr_dmamap->bd_pci_addr + offset;
+
+	/* Fill in our mapping registers
+	 * with the appropriate xtalk data,
+	 * and hand back the PCI address.
+	 */
+
+	ASSERT(ate_count > 0);
+	if (ate_count <= pcibr_dmamap->bd_ate_count) {
+		ATE_FREEZE();
+		ATE_WRITE();
+		ATE_THAW();
+		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
+	} else {
+		/* The number of ATE's required is greater than the number
+		 * allocated for this map. One way this can happen is if
+		 * pcibr_dmamap_alloc() was called with the PCIBR_NO_ATE_ROUNDUP
+		 * flag, and then when that map is used (right now), the
+		 * target address tells us we really did need to roundup.
+		 * The other possibility is that the map is just plain too
+		 * small to handle the requested target area.
+		 */
+#if PCIBR_ATE_DEBUG
+		printk(KERN_WARNING   "pcibr_dmamap_addr :\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\tate_count 0x%x bd_ate_count 0x%x\n"
+			"\tATE's required > number allocated\n",
+			paddr, paddr + req_size - 1,
+			ate_count, pcibr_dmamap->bd_ate_count);
+#endif
+		pci_addr = 0;
+	}
+
+    }
+    return pci_addr;
+}
+
+/*ARGSUSED */
+alenlist_t
+pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
+		  alenlist_t palenlist,
+		  unsigned flags)
+{
+    pcibr_soft_t            pcibr_soft;
+    bridge_t               *bridge=NULL;
+
+    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
+    int                     inplace = flags & PCIIO_INPLACE;
+
+    alenlist_t              pciio_alenlist = 0;
+    alenlist_t              xtalk_alenlist;
+    size_t                  length;
+    iopaddr_t               offset;
+    unsigned                direct64;
+    int                     ate_index = 0;
+    int                     ate_count = 0;
+    int                     ate_total = 0;
+    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
+    bridge_ate_t            ate_proto = (bridge_ate_t)0;
+    bridge_ate_t            ate_prev;
+    bridge_ate_t            ate;
+    alenaddr_t              xio_addr;
+    xwidgetnum_t            xio_port;
+    iopaddr_t               pci_addr;
+    alenaddr_t              new_addr;
+
+    unsigned                cmd_regs[8];
+    unsigned                s = 0;
+
+#if PCIBR_FREEZE_TIME
+    unsigned                freeze_time;
+#endif
+    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
+							 * with an ATE_FREEZE
+							 */
+
+    pcibr_soft = pcibr_dmamap->bd_soft;
+
+    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
+				       flags & DMAMAP_FLAGS);
+    if (!xtalk_alenlist)
+	goto fail;
+
+    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
+
+    if (inplace) {
+	pciio_alenlist = xtalk_alenlist;
+    } else {
+	pciio_alenlist = alenlist_create(al_flags);
+	if (!pciio_alenlist)
+	    goto fail;
+    }
+
+    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
+    if (!direct64) {
+	bridge = pcibr_soft->bs_base;
+	ate_ptr = pcibr_dmamap->bd_ate_ptr;
+	ate_index = pcibr_dmamap->bd_ate_index;
+	ate_proto = pcibr_dmamap->bd_ate_proto;
+	ATE_FREEZE();
+	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
+    }
+    pci_addr = pcibr_dmamap->bd_pci_addr;
+
+    ate_prev = 0;			/* matches no valid ATEs */
+    while (ALENLIST_SUCCESS ==
+	   alenlist_get(xtalk_alenlist, NULL, 0,
+			&xio_addr, &length, al_flags)) {
+	if (XIO_PACKED(xio_addr)) {
+	    xio_port = XIO_PORT(xio_addr);
+	    xio_addr = XIO_ADDR(xio_addr);
+	} else
+	    xio_port = pcibr_dmamap->bd_xio_port;
+
+	if (xio_port == pcibr_soft->bs_xid) {
+	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
+	    if (new_addr == PCI_NOWHERE)
+		goto fail;
+	} else if (direct64) {
+	    new_addr = pci_addr | xio_addr
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+
+	    /* Bridge Hardware WAR #482836:
+	     * If the transfer is not cache aligned
+	     * and the Bridge Rev is <= B, force
+	     * prefetch to be off.
+	     */
+	    if (flags & PCIBR_NOPREFETCH)
+		new_addr &= ~PCI64_ATTR_PREF;
+
+	} else {
+	    /* calculate the ate value for
+	     * the first address. If it
+	     * matches the previous
+	     * ATE written (ie. we had
+	     * multiple blocks in the
+	     * same IOPG), then back up
+	     * and reuse that ATE.
+	     *
+	     * We are NOT going to
+	     * aggressively try to
+	     * reuse any other ATEs.
+	     */
+	    offset = IOPGOFF(xio_addr);
+	    ate = ate_proto
+		| (xio_port << ATE_TIDSHIFT)
+		| (xio_addr - offset);
+	    if (ate == ate_prev) {
+#if PCIBR_ATE_DEBUG
+		printk("pcibr_dmamap_list: ATE share\n");
+#endif
+		ate_ptr--;
+		ate_index--;
+		pci_addr -= IOPGSIZE;
+	    }
+	    new_addr = pci_addr + offset;
+
+	    /* Fill in the hardware ATEs
+	     * that contain this block.
+	     */
+	    ate_count = IOPG(offset + length - 1) + 1;
+	    ate_total += ate_count;
+
+	    /* Ensure that this map contains enough ATE's */
+	    if (ate_total > pcibr_dmamap->bd_ate_count) {
+#if PCIBR_ATE_DEBUG
+		printk(KERN_WARNING   "pcibr_dmamap_list :\n"
+			"\twanted xio_addr [0x%x..0x%x]\n"
+			"\tate_total 0x%x bd_ate_count 0x%x\n"
+			"\tATE's required > number allocated\n",
+			xio_addr, xio_addr + length - 1,
+			ate_total, pcibr_dmamap->bd_ate_count);
+#endif
+		goto fail;
+	    }
+
+	    ATE_WRITE();
+
+	    ate_index += ate_count;
+	    ate_ptr += ate_count;
+
+	    ate_count <<= IOPFNSHIFT;
+	    ate += ate_count;
+	    pci_addr += ate_count;
+	}
+
+	/* write the PCI DMA address
+	 * out to the scatter-gather list.
+	 */
+	if (inplace) {
+	    if (ALENLIST_SUCCESS !=
+		alenlist_replace(pciio_alenlist, NULL,
+				 &new_addr, &length, al_flags))
+		goto fail;
+	} else {
+	    if (ALENLIST_SUCCESS !=
+		alenlist_append(pciio_alenlist,
+				new_addr, length, al_flags))
+		goto fail;
+	}
+    }
+    if (!inplace)
+	alenlist_done(xtalk_alenlist);
+
+    /* Reset the internal cursor of the alenlist to be returned back
+     * to the caller.
+     */
+    alenlist_cursor_init(pciio_alenlist, 0, NULL);
+
+
+    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
+     * changes that ATE_FREEZE has done to implement the external SSRAM
+     * bug workaround.
+     */
+    if (ate_freeze_done) {
+	ATE_THAW();
+	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    }
+    return pciio_alenlist;
+
+  fail:
+    /* There are various points of failure after doing an ATE_FREEZE
+     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
+     * The decision to do an ATE_THAW needs to be based on whether a
+     * an ATE_FREEZE was done before.
+     */
+    if (ate_freeze_done) {
+	ATE_THAW();
+	bridge->b_wid_tflush;
+    }
+    if (pciio_alenlist && !inplace)
+	alenlist_destroy(pciio_alenlist);
+    return 0;
+}
+
+/*ARGSUSED */
+void
+pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
+{
+    /*
+     * We could go through and invalidate ATEs here;
+     * for performance reasons, we don't.
+     * We also don't enforce the strict alternation
+     * between _addr/_list and _done, but Hub does.
+     */
+
+    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
+	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
+
+	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
+	    atomic_dec(&(pcibr_dmamap->bd_soft->bs_slot[pcibr_dmamap->bd_slot]. bss_ext_ates_active));
+    }
+
+    xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
+}
+
+
+/*
+ * For each bridge, the DIR_OFF value in the Direct Mapping Register
+ * determines the PCI to Crosstalk memory mapping to be used for all
+ * 32-bit Direct Mapping memory accesses. This mapping can be to any
+ * node in the system. This function will return that compact node id.
+ */
+
+/*ARGSUSED */
+cnodeid_t
+pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
+{
+
+	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
+	pcibr_soft_t	pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+	return(NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase)));
+}
+
+/*ARGSUSED */
+iopaddr_t
+pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
+		    device_desc_t dev_desc,
+		    paddr_t paddr,
+		    size_t req_size,
+		    unsigned flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
+
+    xwidgetnum_t            xio_port;
+    iopaddr_t               xio_addr;
+    iopaddr_t               pci_addr;
+
+    int                     have_rrbs;
+    int                     min_rrbs;
+
+    /* merge in forced flags */
+    flags |= pcibr_soft->bs_dma_flags;
+
+    xio_addr = xtalk_dmatrans_addr(xconn_vhdl, 0, paddr, req_size,
+				   flags & DMAMAP_FLAGS);
+
+    if (!xio_addr) {
+#if PCIBR_DMA_DEBUG
+	printk("pcibr_dmatrans_addr:\n"
+		"\tpciio connection point %v\n"
+		"\txtalk connection point %v\n"
+		"\twanted paddr [0x%x..0x%x]\n"
+		"\txtalk_dmatrans_addr returned 0x%x\n",
+		pconn_vhdl, xconn_vhdl,
+		paddr, paddr + req_size - 1,
+		xio_addr);
+#endif
+	return 0;
+    }
+    /*
+     * find which XIO port this goes to.
+     */
+    if (XIO_PACKED(xio_addr)) {
+	if (xio_addr == XIO_NOWHERE) {
+#if PCIBR_DMA_DEBUG
+	    printk("pcibr_dmatrans_addr:\n"
+		    "\tpciio connection point %v\n"
+		    "\txtalk connection point %v\n"
+		    "\twanted paddr [0x%x..0x%x]\n"
+		    "\txtalk_dmatrans_addr returned 0x%x\n",
+		    pconn_vhdl, xconn_vhdl,
+		    paddr, paddr + req_size - 1,
+		    xio_addr);
+#endif
+	    return 0;
+	}
+	xio_port = XIO_PORT(xio_addr);
+	xio_addr = XIO_ADDR(xio_addr);
+
+    } else
+	xio_port = pcibr_soft->bs_mxid;
+
+    /*
+     * If this DMA comes back to us,
+     * return the PCI MEM address on
+     * which it would land, or NULL
+     * if the target is something
+     * on bridge other than PCI MEM.
+     */
+    if (xio_port == pcibr_soft->bs_xid) {
+	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
+	return pci_addr;
+    }
+    /* If the caller can use A64, try to
+     * satisfy the request with the 64-bit
+     * direct map. This can fail if the
+     * configuration bits in Device(x)
+     * conflict with our flags.
+     */
+
+    if (flags & PCIIO_DMA_A64) {
+	pci_addr = slotp->bss_d64_base;
+	if (!(flags & PCIBR_VCHAN1))
+	    flags |= PCIBR_VCHAN0;
+	if ((pci_addr != PCIBR_D64_BASE_UNSET) &&
+	    (flags == slotp->bss_d64_flags)) {
+
+	    pci_addr |= xio_addr
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+
+#if DEBUG && PCIBR_DMA_DEBUG
+#if HWG_PERF_CHECK
+	    if (xio_addr != 0x20000000)
+#endif
+		printk("pcibr_dmatrans_addr: [reuse]\n"
+			"\tpciio connection point %v\n"
+			"\txtalk connection point %v\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\txtalk_dmatrans_addr returned 0x%x\n"
+			"\tdirect 64bit address is 0x%x\n",
+			pconn_vhdl, xconn_vhdl,
+			paddr, paddr + req_size - 1,
+			xio_addr, pci_addr);
+#endif
+	    return (pci_addr);
+	}
+	if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS)) {
+	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
+	    slotp->bss_d64_flags = flags;
+	    slotp->bss_d64_base = pci_addr;
+	    pci_addr |= xio_addr
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+
+	    /* Make sure we have an RRB (or two).
+	     */
+	    if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
+		if (flags & PCIBR_VCHAN1)
+		    pciio_slot += PCIBR_RRB_SLOT_VIRTUAL;
+		have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
+		if (have_rrbs < 2) {
+		    if (pci_addr & PCI64_ATTR_PREF)
+			min_rrbs = 2;
+		    else
+			min_rrbs = 1;
+		    if (have_rrbs < min_rrbs)
+			do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
+		}
+	    }
+#if PCIBR_DMA_DEBUG
+#if HWG_PERF_CHECK
+	    if (xio_addr != 0x20000000)
+#endif
+		printk("pcibr_dmatrans_addr:\n"
+			"\tpciio connection point %v\n"
+			"\txtalk connection point %v\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\txtalk_dmatrans_addr returned 0x%x\n"
+			"\tdirect 64bit address is 0x%x\n"
+			"\tnew flags: 0x%x\n",
+			pconn_vhdl, xconn_vhdl,
+			paddr, paddr + req_size - 1,
+			xio_addr, pci_addr, (uint64_t) flags);
+#endif
+	    return (pci_addr);
+	}
+	/* our flags conflict with Device(x).
+	 */
+	flags = flags
+	    & ~PCIIO_DMA_A64
+	    & ~PCIBR_VCHAN0
+	    ;
+
+#if PCIBR_DMA_DEBUG
+	printk("pcibr_dmatrans_addr:\n"
+		"\tpciio connection point %v\n"
+		"\txtalk connection point %v\n"
+		"\twanted paddr [0x%x..0x%x]\n"
+		"\txtalk_dmatrans_addr returned 0x%x\n"
+		"\tUnable to set Device(x) bits for Direct-64\n",
+		pconn_vhdl, xconn_vhdl,
+		paddr, paddr + req_size - 1,
+		xio_addr);
+#endif
+    }
+    /* Try to satisfy the request with the 32-bit direct
+     * map. This can fail if the configuration bits in
+     * Device(x) conflict with our flags, or if the
+     * target address is outside where DIR_OFF points.
+     */
+    {
+	size_t                  map_size = 1ULL << 31;
+	iopaddr_t               xio_base = pcibr_soft->bs_dir_xbase;
+	iopaddr_t               offset = xio_addr - xio_base;
+	iopaddr_t               endoff = req_size + offset;
+
+	if ((req_size > map_size) ||
+	    (xio_addr < xio_base) ||
+	    (xio_port != pcibr_soft->bs_dir_xport) ||
+	    (endoff > map_size)) {
+#if PCIBR_DMA_DEBUG
+	    printk("pcibr_dmatrans_addr:\n"
+		    "\tpciio connection point %v\n"
+		    "\txtalk connection point %v\n"
+		    "\twanted paddr [0x%x..0x%x]\n"
+		    "\txtalk_dmatrans_addr returned 0x%x\n"
+		    "\txio region outside direct32 target\n",
+		    pconn_vhdl, xconn_vhdl,
+		    paddr, paddr + req_size - 1,
+		    xio_addr);
+#endif
+	} else {
+	    pci_addr = slotp->bss_d32_base;
+	    if ((pci_addr != PCIBR_D32_BASE_UNSET) &&
+		(flags == slotp->bss_d32_flags)) {
+
+		pci_addr |= offset;
+
+#if DEBUG && PCIBR_DMA_DEBUG
+		printk("pcibr_dmatrans_addr: [reuse]\n"
+			"\tpciio connection point %v\n"
+			"\txtalk connection point %v\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\txtalk_dmatrans_addr returned 0x%x\n"
+			"\tmapped via direct32 offset 0x%x\n"
+			"\twill DMA via pci addr 0x%x\n",
+			pconn_vhdl, xconn_vhdl,
+			paddr, paddr + req_size - 1,
+			xio_addr, offset, pci_addr);
+#endif
+		return (pci_addr);
+	    }
+	    if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS)) {
+
+		pci_addr = PCI32_DIRECT_BASE;
+		slotp->bss_d32_flags = flags;
+		slotp->bss_d32_base = pci_addr;
+		pci_addr |= offset;
+
+		/* Make sure we have an RRB (or two).
+		 */
+		if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
+		    have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
+		    if (have_rrbs < 2) {
+			if (slotp->bss_device & BRIDGE_DEV_PREF)
+			    min_rrbs = 2;
+			else
+			    min_rrbs = 1;
+			if (have_rrbs < min_rrbs)
+			    do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
+		    }
+		}
+#if PCIBR_DMA_DEBUG
+#if HWG_PERF_CHECK
+		if (xio_addr != 0x20000000)
+#endif
+		    printk("pcibr_dmatrans_addr:\n"
+			    "\tpciio connection point %v\n"
+			    "\txtalk connection point %v\n"
+			    "\twanted paddr [0x%x..0x%x]\n"
+			    "\txtalk_dmatrans_addr returned 0x%x\n"
+			    "\tmapped via direct32 offset 0x%x\n"
+			    "\twill DMA via pci addr 0x%x\n"
+			    "\tnew flags: 0x%x\n",
+			    pconn_vhdl, xconn_vhdl,
+			    paddr, paddr + req_size - 1,
+			    xio_addr, offset, pci_addr, (uint64_t) flags);
+#endif
+		return (pci_addr);
+	    }
+	    /* our flags conflict with Device(x).
+	     */
+#if PCIBR_DMA_DEBUG
+	    printk("pcibr_dmatrans_addr:\n"
+		    "\tpciio connection point %v\n"
+		    "\txtalk connection point %v\n"
+		    "\twanted paddr [0x%x..0x%x]\n"
+		    "\txtalk_dmatrans_addr returned 0x%x\n"
+		    "\tUnable to set Device(x) bits for Direct-32\n",
+		    pconn_vhdl, xconn_vhdl,
+		    paddr, paddr + req_size - 1,
+		    xio_addr);
+#endif
+	}
+    }
+
+#if PCIBR_DMA_DEBUG
+    printk("pcibr_dmatrans_addr:\n"
+	    "\tpciio connection point %v\n"
+	    "\txtalk connection point %v\n"
+	    "\twanted paddr [0x%x..0x%x]\n"
+	    "\txtalk_dmatrans_addr returned 0x%x\n"
+	    "\tno acceptable PCI address found or constructable\n",
+	    pconn_vhdl, xconn_vhdl,
+	    paddr, paddr + req_size - 1,
+	    xio_addr);
+#endif
+
+    return 0;
+}
+
+/*ARGSUSED */
+alenlist_t
+pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
+		    device_desc_t dev_desc,
+		    alenlist_t palenlist,
+		    unsigned flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
+    xwidgetnum_t            xio_port;
+
+    alenlist_t              pciio_alenlist = 0;
+    alenlist_t              xtalk_alenlist = 0;
+
+    int                     inplace;
+    unsigned                direct64;
+    unsigned                al_flags;
+
+    iopaddr_t               xio_base;
+    alenaddr_t              xio_addr;
+    size_t                  xio_size;
+
+    size_t                  map_size;
+    iopaddr_t               pci_base;
+    alenaddr_t              pci_addr;
+
+    unsigned                relbits = 0;
+
+    /* merge in forced flags */
+    flags |= pcibr_soft->bs_dma_flags;
+
+    inplace = flags & PCIIO_INPLACE;
+    direct64 = flags & PCIIO_DMA_A64;
+    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
+
+    if (direct64) {
+	map_size = 1ull << 48;
+	xio_base = 0;
+	pci_base = slotp->bss_d64_base;
+	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
+	    (flags == slotp->bss_d64_flags)) {
+	    /* reuse previous base info */
+	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
+	    /* DMA configuration conflict */
+	    goto fail;
+	} else {
+	    relbits = BRIDGE_DEV_D64_BITS;
+	    pci_base =
+		pcibr_flags_to_d64(flags, pcibr_soft);
+	}
+    } else {
+	xio_base = pcibr_soft->bs_dir_xbase;
+	map_size = 1ull << 31;
+	pci_base = slotp->bss_d32_base;
+	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
+	    (flags == slotp->bss_d32_flags)) {
+	    /* reuse previous base info */
+	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
+	    /* DMA configuration conflict */
+	    goto fail;
+	} else {
+	    relbits = BRIDGE_DEV_D32_BITS;
+	    pci_base = PCI32_DIRECT_BASE;
+	}
+    }
+
+    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
+					 flags & DMAMAP_FLAGS);
+    if (!xtalk_alenlist)
+	goto fail;
+
+    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
+
+    if (inplace) {
+	pciio_alenlist = xtalk_alenlist;
+    } else {
+	pciio_alenlist = alenlist_create(al_flags);
+	if (!pciio_alenlist)
+	    goto fail;
+    }
+
+    while (ALENLIST_SUCCESS ==
+	   alenlist_get(xtalk_alenlist, NULL, 0,
+			&xio_addr, &xio_size, al_flags)) {
+
+	/*
+	 * find which XIO port this goes to.
+	 */
+	if (XIO_PACKED(xio_addr)) {
+	    if (xio_addr == XIO_NOWHERE) {
+#if PCIBR_DMA_DEBUG
+		printk("pcibr_dmatrans_addr:\n"
+			"\tpciio connection point %v\n"
+			"\txtalk connection point %v\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\txtalk_dmatrans_addr returned 0x%x\n",
+			pconn_vhdl, xconn_vhdl,
+			paddr, paddr + req_size - 1,
+			xio_addr);
+#endif
+		return 0;
+	    }
+	    xio_port = XIO_PORT(xio_addr);
+	    xio_addr = XIO_ADDR(xio_addr);
+	} else
+	    xio_port = pcibr_soft->bs_mxid;
+
+	/*
+	 * If this DMA comes back to us,
+	 * return the PCI MEM address on
+	 * which it would land, or NULL
+	 * if the target is something
+	 * on bridge other than PCI MEM.
+	 */
+	if (xio_port == pcibr_soft->bs_xid) {
+	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
+	    if ( (pci_addr == (alenaddr_t)NULL) )
+		goto fail;
+	} else if (direct64) {
+	    ASSERT(xio_port != 0);
+	    pci_addr = pci_base | xio_addr
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+	} else {
+	    iopaddr_t               offset = xio_addr - xio_base;
+	    iopaddr_t               endoff = xio_size + offset;
+
+	    if ((xio_size > map_size) ||
+		(xio_addr < xio_base) ||
+		(xio_port != pcibr_soft->bs_dir_xport) ||
+		(endoff > map_size))
+		goto fail;
+
+	    pci_addr = pci_base + (xio_addr - xio_base);
+	}
+
+	/* write the PCI DMA address
+	 * out to the scatter-gather list.
+	 */
+	if (inplace) {
+	    if (ALENLIST_SUCCESS !=
+		alenlist_replace(pciio_alenlist, NULL,
+				 &pci_addr, &xio_size, al_flags))
+		goto fail;
+	} else {
+	    if (ALENLIST_SUCCESS !=
+		alenlist_append(pciio_alenlist,
+				pci_addr, xio_size, al_flags))
+		goto fail;
+	}
+    }
+
+    if (relbits) {
+	if (direct64) {
+	    slotp->bss_d64_flags = flags;
+	    slotp->bss_d64_base = pci_base;
+	} else {
+	    slotp->bss_d32_flags = flags;
+	    slotp->bss_d32_base = pci_base;
+	}
+    }
+    if (!inplace)
+	alenlist_done(xtalk_alenlist);
+
+    /* Reset the internal cursor of the alenlist to be returned back
+     * to the caller.
+     */
+    alenlist_cursor_init(pciio_alenlist, 0, NULL);
+    return pciio_alenlist;
+
+  fail:
+    if (relbits)
+	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
+    if (pciio_alenlist && !inplace)
+	alenlist_destroy(pciio_alenlist);
+    return 0;
+}
+
+void
+pcibr_dmamap_drain(pcibr_dmamap_t map)
+{
+    xtalk_dmamap_drain(map->bd_xtalk);
+}
+
+void
+pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
+		    paddr_t paddr,
+		    size_t bytes)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+
+    xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
+}
+
+void
+pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
+		    alenlist_t list)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+
+    xtalk_dmalist_drain(xconn_vhdl, list);
+}
+
+/*
+ * Get the starting PCIbus address out of the given DMA map.
+ * This function is supposed to be used by a close friend of PCI bridge
+ * since it relies on the fact that the starting address of the map is fixed at
+ * the allocation time in the current implementation of PCI bridge.
+ */
+iopaddr_t
+pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap)
+{
+    return (pcibr_dmamap->bd_pci_addr);
+}
+
+/*
+ *	There are end cases where a deadlock can occur if interrupt 
+ *	processing completes and the Bridge b_int_status bit is still set.
+ *
+ *	One scenerio is if a second PCI interrupt occurs within 60ns of
+ *	the previous interrupt being cleared. In this case the Bridge
+ *	does not detect the transition, the Bridge b_int_status bit
+ *	remains set, and because no transition was detected no interrupt
+ *	packet is sent to the Hub/Heart.
+ *
+ *	A second scenerio is possible when a b_int_status bit is being
+ *	shared by multiple devices:
+ *						Device #1 generates interrupt
+ *						Bridge b_int_status bit set
+ *						Device #2 generates interrupt
+ *		interrupt processing begins
+ *		  ISR for device #1 runs and
+ *			clears interrupt
+ *						Device #1 generates interrupt
+ *		  ISR for device #2 runs and
+ *			clears interrupt
+ *						(b_int_status bit still set)
+ *		interrupt processing completes
+ *		  
+ *	Interrupt processing is now complete, but an interrupt is still
+ *	outstanding for Device #1. But because there was no transition of
+ *	the b_int_status bit, no interrupt packet will be generated and
+ *	a deadlock will occur.
+ *
+ *	To avoid these deadlock situations, this function is used
+ *	to check if a specific Bridge b_int_status bit is set, and if so,
+ *	cause the setting of the corresponding interrupt bit.
+ *
+ *	On a XBridge (IP35), we do this by writing the appropriate Bridge Force 
+ *	Interrupt register.
+ */
+void
+pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
+{
+	unsigned	bit;
+	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
+	bridge_t       *bridge = pcibr_soft->bs_base;
+	cpuid_t cpuvertex_to_cpuid(devfs_handle_t vhdl);
+
+	bit = wrap->iw_intr;
+
+	if (pcibr_soft->bs_xbridge) {
+	    bridge->b_force_pin[bit].intr = 1;
+	} else if ((1 << bit) & *wrap->iw_stat) {
+	    cpuid_t	    cpu;
+	    unsigned        intr_bit;
+	    xtalk_intr_t    xtalk_intr =
+				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
+
+	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
+	    cpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
+#if defined(CONFIG_IA64_SGI_SN1)
+	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
+#endif
+	}
+}
+
+/* =====================================================================
+ *    INTERRUPT MANAGEMENT
+ */
+
+static unsigned
+pcibr_intr_bits(pciio_info_t info,
+		pciio_intr_line_t lines)
+{
+    pciio_slot_t            slot = pciio_info_slot_get(info);
+    unsigned		    bbits = 0;
+
+    /*
+     * Currently favored mapping from PCI
+     * slot number and INTA/B/C/D to Bridge
+     * PCI Interrupt Bit Number:
+     *
+     *     SLOT     A B C D
+     *      0       0 4 0 4
+     *      1       1 5 1 5
+     *      2       2 6 2 6
+     *      3       3 7 3 7
+     *      4       4 0 4 0
+     *      5       5 1 5 1
+     *      6       6 2 6 2
+     *      7       7 3 7 3
+     */
+
+    if (slot < 8) {
+	if (lines & (PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_C))
+	    bbits |= 1 << slot;
+	if (lines & (PCIIO_INTR_LINE_B| PCIIO_INTR_LINE_D))
+	    bbits |= 1 << (slot ^ 4);
+    }
+    return bbits;
+}
+
+
+/*ARGSUSED */
+pcibr_intr_t
+pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
+		 device_desc_t dev_desc,
+		 pciio_intr_line_t lines,
+		 devfs_handle_t owner_dev)
+{
+    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pcibr_info->f_slot;
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    int                     is_threaded = 0;
+    int                     thread_swlevel;
+
+    xtalk_intr_t           *xtalk_intr_p;
+    pcibr_intr_t           *pcibr_intr_p;
+    pcibr_intr_list_t      *intr_list_p;
+
+    unsigned                pcibr_int_bits;
+    unsigned                pcibr_int_bit;
+    xtalk_intr_t            xtalk_intr = (xtalk_intr_t)0;
+    hub_intr_t		    hub_intr;
+    pcibr_intr_t            pcibr_intr;
+    pcibr_intr_list_t       intr_entry;
+    pcibr_intr_list_t       intr_list;
+    bridgereg_t             int_dev;
+
+#if DEBUG && INTR_DEBUG
+    printk("%v: pcibr_intr_alloc\n"
+	    "%v:%s%s%s%s%s\n",
+	    owner_dev, pconn_vhdl,
+	    !(lines & 15) ? " No INTs?" : "",
+	    lines & 1 ? " INTA" : "",
+	    lines & 2 ? " INTB" : "",
+	    lines & 4 ? " INTC" : "",
+	    lines & 8 ? " INTD" : "");
+#endif
+
+    NEW(pcibr_intr);
+    if (!pcibr_intr)
+	return NULL;
+
+    if (dev_desc) {
+	cpuid_t intr_target_from_desc(device_desc_t, int);
+    } else {
+	extern int default_intr_pri;
+
+	is_threaded = 1; /* PCI interrupts are threaded, by default */
+	thread_swlevel = default_intr_pri;
+    }
+
+    pcibr_intr->bi_dev = pconn_vhdl;
+    pcibr_intr->bi_lines = lines;
+    pcibr_intr->bi_soft = pcibr_soft;
+    pcibr_intr->bi_ibits = 0;		/* bits will be added below */
+    pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD;
+    pcibr_intr->bi_mustruncpu = CPU_NONE;
+    mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock);
+
+    pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines);
+
+
+    /*
+     * For each PCI interrupt line requested, figure
+     * out which Bridge PCI Interrupt Line it maps
+     * to, and make sure there are xtalk resources
+     * allocated for it.
+     */
+#if DEBUG && INTR_DEBUG
+    printk("pcibr_int_bits: 0x%X\n", pcibr_int_bits);
+#endif 
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit ++) {
+	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
+	    xtalk_intr_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
+
+	    xtalk_intr = *xtalk_intr_p;
+
+	    if (xtalk_intr == NULL) {
+		/*
+		 * This xtalk_intr_alloc is constrained for two reasons:
+		 * 1) Normal interrupts and error interrupts need to be delivered
+		 *    through a single xtalk target widget so that there aren't any
+		 *    ordering problems with DMA, completion interrupts, and error
+		 *    interrupts. (Use of xconn_vhdl forces this.)
+		 *
+		 * 2) On IP35, addressing constraints on IP35 and Bridge force
+		 *    us to use a single PI number for all interrupts from a
+		 *    single Bridge. (IP35-specific code forces this, and we
+		 *    verify in pcibr_setwidint.)
+		 */
+
+		/*
+		 * All code dealing with threaded PCI interrupt handlers
+		 * is located at the pcibr level. Because of this,
+		 * we always want the lower layers (hub/heart_intr_alloc, 
+		 * intr_level_connect) to treat us as non-threaded so we
+		 * don't set up a duplicate threaded environment. We make
+		 * this happen by calling a special xtalk interface.
+		 */
+		xtalk_intr = xtalk_intr_alloc_nothd(xconn_vhdl, dev_desc, 
+			owner_dev);
+#if DEBUG && INTR_DEBUG
+		printk("%v: xtalk_intr=0x%X\n", xconn_vhdl, xtalk_intr);
+#endif
+
+		/* both an assert and a runtime check on this:
+		 * we need to check in non-DEBUG kernels, and
+		 * the ASSERT gets us more information when
+		 * we use DEBUG kernels.
+		 */
+		ASSERT(xtalk_intr != NULL);
+		if (xtalk_intr == NULL) {
+		    /* it is quite possible that our
+		     * xtalk_intr_alloc failed because
+		     * someone else got there first,
+		     * and we can find their results
+		     * in xtalk_intr_p.
+		     */
+		    if (!*xtalk_intr_p) {
+#ifdef SUPPORT_PRINTING_V_FORMAT
+			printk(KERN_ALERT  
+				"pcibr_intr_alloc %v: unable to get xtalk interrupt resources",
+				xconn_vhdl);
+#else
+			printk(KERN_ALERT  
+				"pcibr_intr_alloc 0x%p: unable to get xtalk interrupt resources",
+				(void *)xconn_vhdl);
+#endif
+			/* yes, we leak resources here. */
+			return 0;
+		    }
+		} else if (compare_and_swap_ptr((void **) xtalk_intr_p, NULL, xtalk_intr)) {
+		    /*
+		     * now tell the bridge which slot is
+		     * using this interrupt line.
+		     */
+		    int_dev = bridge->b_int_device;
+		    int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
+		    int_dev |= pciio_slot << BRIDGE_INT_DEV_SHFT(pcibr_int_bit);
+		    bridge->b_int_device = int_dev;	/* XXXMP */
+
+#if DEBUG && INTR_DEBUG
+		    printk("%v: bridge intr bit %d clears my wrb\n",
+			    pconn_vhdl, pcibr_int_bit);
+#endif
+		} else {
+		    /* someone else got one allocated first;
+		     * free the one we just created, and
+		     * retrieve the one they allocated.
+		     */
+		    xtalk_intr_free(xtalk_intr);
+		    xtalk_intr = *xtalk_intr_p;
+#if PARANOID
+		    /* once xtalk_intr is set, we never clear it,
+		     * so if the CAS fails above, this condition
+		     * can "never happen" ...
+		     */
+		    if (!xtalk_intr) {
+			printk(KERN_ALERT  
+				"pcibr_intr_alloc %v: unable to set xtalk interrupt resources",
+				xconn_vhdl);
+			/* yes, we leak resources here. */
+			return 0;
+		    }
+#endif
+		}
+	    }
+
+	    pcibr_intr->bi_ibits |= 1 << pcibr_int_bit;
+
+	    NEW(intr_entry);
+	    intr_entry->il_next = NULL;
+	    intr_entry->il_intr = pcibr_intr;
+	    intr_entry->il_wrbf = &(bridge->b_wr_req_buf[pciio_slot].reg);
+	    intr_list_p = 
+		&pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
+#if DEBUG && INTR_DEBUG
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+	    printk("0x%x: Bridge bit %d wrap=0x%x\n",
+		pconn_vhdl, pcibr_int_bit,
+		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
+#else
+	    printk("%v: Bridge bit %d wrap=0x%x\n",
+		pconn_vhdl, pcibr_int_bit,
+		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
+#endif
+#endif
+
+	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
+		/* we are the first interrupt on this bridge bit.
+		 */
+#if DEBUG && INTR_DEBUG
+		printk("%v INT 0x%x (bridge bit %d) allocated [FIRST]\n",
+			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		continue;
+	    }
+	    intr_list = *intr_list_p;
+	    pcibr_intr_p = &intr_list->il_intr;
+	    if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
+		/* first entry on list was erased,
+		 * and we replaced it, so we
+		 * don't need our intr_entry.
+		 */
+		DEL(intr_entry);
+#if DEBUG && INTR_DEBUG
+		printk("%v INT 0x%x (bridge bit %d) replaces erased first\n",
+			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		continue;
+	    }
+	    intr_list_p = &intr_list->il_next;
+	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
+		/* we are the new second interrupt on this bit.
+		 */
+		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared = 1;
+#if DEBUG && INTR_DEBUG
+		printk("%v INT 0x%x (bridge bit %d) is new SECOND\n",
+			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		continue;
+	    }
+	    while (1) {
+		pcibr_intr_p = &intr_list->il_intr;
+		if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
+		    /* an entry on list was erased,
+		     * and we replaced it, so we
+		     * don't need our intr_entry.
+		     */
+		    DEL(intr_entry);
+#if DEBUG && INTR_DEBUG
+		    printk("%v INT 0x%x (bridge bit %d) replaces erased Nth\n",
+			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		    break;
+		}
+		intr_list_p = &intr_list->il_next;
+		if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
+		    /* entry appended to share list
+		     */
+#if DEBUG && INTR_DEBUG
+		    printk("%v INT 0x%x (bridge bit %d) is new Nth\n",
+			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		    break;
+		}
+		/* step to next record in chain
+		 */
+		intr_list = *intr_list_p;
+	    }
+	}
+    }
+
+#if DEBUG && INTR_DEBUG
+    printk("%v pcibr_intr_alloc complete\n", pconn_vhdl);
+#endif
+    hub_intr = (hub_intr_t)xtalk_intr;
+    pcibr_intr->bi_irq = hub_intr->i_bit;
+    pcibr_intr->bi_cpu = hub_intr->i_cpuid;
+    return pcibr_intr;
+}
+
+/*ARGSUSED */
+void
+pcibr_intr_free(pcibr_intr_t pcibr_intr)
+{
+    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
+    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
+    unsigned                pcibr_int_bit;
+    pcibr_intr_list_t       intr_list;
+    int			    intr_shared;
+    xtalk_intr_t	    *xtalk_intrp;
+
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) {
+	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
+	    for (intr_list = 
+		     pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
+		 intr_list != NULL;
+		 intr_list = intr_list->il_next)
+		if (compare_and_swap_ptr((void **) &intr_list->il_intr, 
+					 pcibr_intr, 
+					 NULL)) {
+#if DEBUG && INTR_DEBUG
+		    printk("%s: cleared a handler from bit %d\n",
+			    pcibr_soft->bs_name, pcibr_int_bit);
+#endif
+		}
+	    /* If this interrupt line is not being shared between multiple
+	     * devices release the xtalk interrupt resources.
+	     */
+	    intr_shared = 
+		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared;
+	    xtalk_intrp = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
+
+	    if ((!intr_shared) && (*xtalk_intrp)) {
+
+		bridge_t 	*bridge = pcibr_soft->bs_base;
+		bridgereg_t	int_dev;
+
+		xtalk_intr_free(*xtalk_intrp);
+		*xtalk_intrp = 0;
+
+		/* Clear the PCI device interrupt to bridge interrupt pin
+		 * mapping.
+		 */
+		int_dev = bridge->b_int_device;
+		int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
+		bridge->b_int_device = int_dev;
+
+	    }
+	}
+    }
+    DEL(pcibr_intr);
+}
+
+LOCAL void
+pcibr_setpciint(xtalk_intr_t xtalk_intr)
+{
+    iopaddr_t               addr = xtalk_intr_addr_get(xtalk_intr);
+    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(xtalk_intr);
+    bridgereg_t            *int_addr = (bridgereg_t *)
+    xtalk_intr_sfarg_get(xtalk_intr);
+
+#ifdef CONFIG_IA64_SGI_SN2
+    *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 26)) |
+		 (BRIDGE_INT_ADDR_FLD & vect));
+#elif CONFIG_IA64_SGI_SN1
+    *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
+		 (BRIDGE_INT_ADDR_FLD & vect));
+#endif
+}
+
+/*ARGSUSED */
+int
+pcibr_intr_connect(pcibr_intr_t pcibr_intr)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
+    unsigned                pcibr_int_bit;
+    bridgereg_t             b_int_enable;
+    unsigned long           s;
+
+    if (pcibr_intr == NULL)
+	return -1;
+
+#if DEBUG && INTR_DEBUG
+    printk("%v: pcibr_intr_connect\n",
+	    pcibr_intr->bi_dev);
+#endif
+
+    *((volatile unsigned *)&pcibr_intr->bi_flags) |= PCIIO_INTR_CONNECTED;
+
+    /*
+     * For each PCI interrupt line requested, figure
+     * out which Bridge PCI Interrupt Line it maps
+     * to, and make sure there are xtalk resources
+     * allocated for it.
+     */
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
+	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
+	    xtalk_intr_t            xtalk_intr;
+
+	    xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
+
+	    /*
+	     * If this interrupt line is being shared and the connect has
+	     * already been done, no need to do it again.
+	     */
+	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected)
+		continue;
+
+
+	    /*
+	     * Use the pcibr wrapper function to handle all Bridge interrupts
+	     * regardless of whether the interrupt line is shared or not.
+	     */
+	    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t) pcibr_setpciint,
+			       (void *)&(bridge->b_int_addr[pcibr_int_bit].addr));
+	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 1;
+
+#if DEBUG && INTR_DEBUG
+	    printk("%v bridge bit %d wrapper connected\n",
+		    pcibr_intr->bi_dev, pcibr_int_bit);
+#endif
+	}
+    s = pcibr_lock(pcibr_soft);
+    b_int_enable = bridge->b_int_enable;
+    b_int_enable |= pcibr_int_bits;
+    bridge->b_int_enable = b_int_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    pcibr_unlock(pcibr_soft, s);
+
+    return 0;
+}
+
+/*ARGSUSED */
+void
+pcibr_intr_disconnect(pcibr_intr_t pcibr_intr)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
+    unsigned                pcibr_int_bit;
+    bridgereg_t             b_int_enable;
+    unsigned long           s;
+
+    /* Stop calling the function. Now.
+     */
+    *((volatile unsigned *)&pcibr_intr->bi_flags) &= ~PCIIO_INTR_CONNECTED;
+    /*
+     * For each PCI interrupt line requested, figure
+     * out which Bridge PCI Interrupt Line it maps
+     * to, and disconnect the interrupt.
+     */
+
+    /* don't disable interrupts for lines that
+     * are shared between devices.
+     */
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
+	if ((pcibr_int_bits & (1 << pcibr_int_bit)) &&
+	    (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared))
+	    pcibr_int_bits &= ~(1 << pcibr_int_bit);
+    if (!pcibr_int_bits)
+	return;
+
+    s = pcibr_lock(pcibr_soft);
+    b_int_enable = bridge->b_int_enable;
+    b_int_enable &= ~pcibr_int_bits;
+    bridge->b_int_enable = b_int_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    pcibr_unlock(pcibr_soft, s);
+
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
+	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
+	    /* if the interrupt line is now shared,
+	     * do not disconnect it.
+	     */
+	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
+		continue;
+
+	    xtalk_intr_disconnect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
+	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 0;
+
+#if DEBUG && INTR_DEBUG
+	    printk("%s: xtalk disconnect done for Bridge bit %d\n",
+		pcibr_soft->bs_name, pcibr_int_bit);
+#endif
+
+	    /* if we are sharing the interrupt line,
+	     * connect us up; this closes the hole
+	     * where the another pcibr_intr_alloc()
+	     * was in progress as we disconnected.
+	     */
+	    if (!pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
+		continue;
+
+	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
+			       (xtalk_intr_setfunc_t)pcibr_setpciint,
+			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr));
+	}
+}
+
+/*ARGSUSED */
+devfs_handle_t
+pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
+    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
+    unsigned                pcibr_int_bit;
+
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
+	if (pcibr_int_bits & (1 << pcibr_int_bit))
+	    return xtalk_intr_cpu_get(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
+    return 0;
+}
+
+/* =====================================================================
+ *    INTERRUPT HANDLING
+ */
+LOCAL void
+pcibr_clearwidint(bridge_t *bridge)
+{
+    bridge->b_wid_int_upper = 0;
+    bridge->b_wid_int_lower = 0;
+}
+
+LOCAL void
+pcibr_setwidint(xtalk_intr_t intr)
+{
+    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
+    iopaddr_t               addr = xtalk_intr_addr_get(intr);
+    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
+    widgetreg_t		    NEW_b_wid_int_upper, NEW_b_wid_int_lower;
+    widgetreg_t		    OLD_b_wid_int_upper, OLD_b_wid_int_lower;
+
+    bridge_t               *bridge = (bridge_t *)xtalk_intr_sfarg_get(intr);
+
+    NEW_b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
+			       XTALK_ADDR_TO_UPPER(addr));
+    NEW_b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
+
+    OLD_b_wid_int_upper = bridge->b_wid_int_upper;
+    OLD_b_wid_int_lower = bridge->b_wid_int_lower;
+
+    /* Verify that all interrupts from this Bridge are using a single PI */
+    if ((OLD_b_wid_int_upper != 0) && (OLD_b_wid_int_lower != 0)) {
+	/*
+	 * Once set, these registers shouldn't change; they should
+	 * be set multiple times with the same values.
+	 *
+	 * If we're attempting to change these registers, it means
+	 * that our heuristics for allocating interrupts in a way
+	 * appropriate for IP35 have failed, and the admin needs to
+	 * explicitly direct some interrupts (or we need to make the
+	 * heuristics more clever).
+	 *
+	 * In practice, we hope this doesn't happen very often, if
+	 * at all.
+	 */
+	if ((OLD_b_wid_int_upper != NEW_b_wid_int_upper) ||
+	    (OLD_b_wid_int_lower != NEW_b_wid_int_lower)) {
+		printk(KERN_WARNING  "Interrupt allocation is too complex.\n");
+		printk(KERN_WARNING  "Use explicit administrative interrupt targetting.\n");
+		printk(KERN_WARNING  "bridge=0x%lx targ=0x%x\n", (unsigned long)bridge, targ);
+		printk(KERN_WARNING  "NEW=0x%x/0x%x  OLD=0x%x/0x%x\n",
+			NEW_b_wid_int_upper, NEW_b_wid_int_lower,
+			OLD_b_wid_int_upper, OLD_b_wid_int_lower);
+		PRINT_PANIC("PCI Bridge interrupt targetting error\n");
+	}
+    }
+
+    bridge->b_wid_int_upper = NEW_b_wid_int_upper;
+    bridge->b_wid_int_lower = NEW_b_wid_int_lower;
+    bridge->b_int_host_err = vect;
+}
+
+/*
+ * pcibr_intr_preset: called during mlreset time
+ * if the platform specific code needs to route
+ * one of the Bridge's xtalk interrupts before the
+ * xtalk infrastructure is available.
+ */
+void
+pcibr_xintr_preset(void *which_widget,
+		   int which_widget_intr,
+		   xwidgetnum_t targ,
+		   iopaddr_t addr,
+		   xtalk_intr_vector_t vect)
+{
+    bridge_t               *bridge = (bridge_t *) which_widget;
+
+    if (which_widget_intr == -1) {
+	/* bridge widget error interrupt */
+	bridge->b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
+				   XTALK_ADDR_TO_UPPER(addr));
+	bridge->b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
+	bridge->b_int_host_err = vect;
+
+	/* turn on all interrupts except
+	 * the PCI interrupt requests,
+	 * at least at heart.
+	 */
+	bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK;
+
+    } else {
+	/* routing a PCI device interrupt.
+	 * targ and low 38 bits of addr must
+	 * be the same as the already set
+	 * value for the widget error interrupt.
+	 */
+	bridge->b_int_addr[which_widget_intr].addr =
+	    ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
+	     (BRIDGE_INT_ADDR_FLD & vect));
+	/*
+	 * now bridge can let it through;
+	 * NB: still should be blocked at
+	 * xtalk provider end, until the service
+	 * function is set.
+	 */
+	bridge->b_int_enable |= 1 << vect;
+    }
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+}
+
+
+/*
+ * pcibr_intr_func()
+ *
+ * This is the pcibr interrupt "wrapper" function that is called,
+ * in interrupt context, to initiate the interrupt handler(s) registered
+ * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
+ * handlers will be called directly, and threaded handlers will have their 
+ * thread woken up.
+ */
+void
+pcibr_intr_func(intr_arg_t arg)
+{
+    pcibr_intr_wrap_t       wrap = (pcibr_intr_wrap_t) arg;
+    reg_p                   wrbf;
+    pcibr_intr_t            intr;
+    pcibr_intr_list_t       list;
+    int                     clearit;
+    int			    do_nonthreaded = 1;
+    int			    is_threaded = 0;
+    int			    x = 0;
+
+	/*
+	 * If any handler is still running from a previous interrupt
+	 * just return. If there's a need to call the handler(s) again,
+	 * another interrupt will be generated either by the device or by
+	 * pcibr_force_interrupt().
+	 */
+
+	if (wrap->iw_hdlrcnt) {
+		return;
+	}
+
+    /*
+     * Call all interrupt handlers registered.
+     * First, the pcibr_intrd threads for any threaded handlers will be
+     * awoken, then any non-threaded handlers will be called sequentially.
+     */
+	
+	clearit = 1;
+	while (do_nonthreaded) {
+	    for (list = wrap->iw_list; list != NULL; list = list->il_next) {
+		if ((intr = list->il_intr) &&
+		    (intr->bi_flags & PCIIO_INTR_CONNECTED)) {
+
+		/*
+		 * This device may have initiated write
+		 * requests since the bridge last saw
+		 * an edge on this interrupt input; flushing
+		 * the buffer prior to invoking the handler
+		 * should help but may not be sufficient if we 
+		 * get more requests after the flush, followed
+		 * by the card deciding it wants service, before
+		 * the interrupt handler checks to see if things need
+		 * to be done.
+		 *
+		 * There is a similar race condition if
+		 * an interrupt handler loops around and
+		 * notices further service is required.
+		 * Perhaps we need to have an explicit
+		 * call that interrupt handlers need to
+		 * do between noticing that DMA to memory
+		 * has completed, but before observing the
+		 * contents of memory?
+		 */
+
+			if ((do_nonthreaded) && (!is_threaded)) {
+			/* Non-threaded. 
+			 * Call the interrupt handler at interrupt level
+			 */
+
+			/* Only need to flush write buffers if sharing */
+
+			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
+			    if ((x = *wrbf))	/* write request buffer flush */
+#ifdef SUPPORT_PRINTING_V_FORMAT
+				printk(KERN_ALERT  "pcibr_intr_func %v: \n"
+				    "write buffer flush failed, wrbf=0x%x\n", 
+				    list->il_intr->bi_dev, wrbf);
+#else
+				printk(KERN_ALERT  "pcibr_intr_func %p: \n"
+				    "write buffer flush failed, wrbf=0x%lx\n", 
+				    (void *)list->il_intr->bi_dev, (long) wrbf);
+#endif
+			}
+		    }
+
+		    clearit = 0;
+		}
+	    }
+
+		do_nonthreaded = 0;
+		/*
+		 * If the non-threaded handler was the last to complete,
+		 * (i.e., no threaded handlers still running) force an
+		 * interrupt to avoid a potential deadlock situation.
+		 */
+		if (wrap->iw_hdlrcnt == 0) {
+			pcibr_force_interrupt(wrap);
+		}
+	}
+
+	/* If there were no handlers,
+	 * disable the interrupt and return.
+	 * It will get enabled again after
+	 * a handler is connected.
+	 * If we don't do this, we would
+	 * sit here and spin through the
+	 * list forever.
+	 */
+	if (clearit) {
+	    pcibr_soft_t            pcibr_soft = wrap->iw_soft;
+	    bridge_t               *bridge = pcibr_soft->bs_base;
+	    bridgereg_t             b_int_enable;
+	    bridgereg_t		    mask = 1 << wrap->iw_intr;
+	    unsigned long           s;
+
+	    s = pcibr_lock(pcibr_soft);
+	    b_int_enable = bridge->b_int_enable;
+	    b_int_enable &= ~mask;
+	    bridge->b_int_enable = b_int_enable;
+	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
+	    pcibr_unlock(pcibr_soft, s);
+	    return;
+	}
+}
+
+/* =====================================================================
+ *    CONFIGURATION MANAGEMENT
+ */
+/*ARGSUSED */
+void
+pcibr_provider_startup(devfs_handle_t pcibr)
+{
+}
+
+/*ARGSUSED */
+void
+pcibr_provider_shutdown(devfs_handle_t pcibr)
+{
+}
+
+int
+pcibr_reset(devfs_handle_t conn)
+{
+    pciio_info_t            pciio_info = pciio_info_get(conn);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    bridgereg_t             ctlreg;
+    unsigned                cfgctl[8];
+    unsigned long           s;
+    int                     f, nf;
+    pcibr_info_h            pcibr_infoh;
+    pcibr_info_t            pcibr_info;
+    int                     win;
+
+    if (pcibr_soft->bs_slot[pciio_slot].has_host) {
+	pciio_slot = pcibr_soft->bs_slot[pciio_slot].host_slot;
+	pcibr_info = pcibr_soft->bs_slot[pciio_slot].bss_infos[0];
+    }
+    if (pciio_slot < 4) {
+	s = pcibr_lock(pcibr_soft);
+	nf = pcibr_soft->bs_slot[pciio_slot].bss_ninfo;
+	pcibr_infoh = pcibr_soft->bs_slot[pciio_slot].bss_infos;
+	for (f = 0; f < nf; ++f)
+	    if (pcibr_infoh[f])
+		cfgctl[f] = bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4];
+
+	ctlreg = bridge->b_wid_control;
+	bridge->b_wid_control = ctlreg | BRIDGE_CTRL_RST(pciio_slot);
+	/* XXX delay? */
+	bridge->b_wid_control = ctlreg;
+	/* XXX delay? */
+
+	for (f = 0; f < nf; ++f)
+	    if ((pcibr_info = pcibr_infoh[f]))
+		for (win = 0; win < 6; ++win)
+		    if (pcibr_info->f_window[win].w_base != 0)
+			bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_BASE_ADDR(win) / 4] =
+			    pcibr_info->f_window[win].w_base;
+	for (f = 0; f < nf; ++f)
+	    if (pcibr_infoh[f])
+		bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4] = cfgctl[f];
+	pcibr_unlock(pcibr_soft, s);
+
+	return 0;
+    }
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    printk(KERN_WARNING   "%v: pcibr_reset unimplemented for slot %d\n",
+	    conn, pciio_slot);
+#endif
+    return -1;
+}
+
+pciio_endian_t
+pcibr_endian_set(devfs_handle_t pconn_vhdl,
+		 pciio_endian_t device_end,
+		 pciio_endian_t desired_end)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridgereg_t             devreg;
+    unsigned long           s;
+
+    /*
+     * Bridge supports hardware swapping; so we can always
+     * arrange for the caller's desired endianness.
+     */
+
+    s = pcibr_lock(pcibr_soft);
+    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
+    if (device_end != desired_end)
+	devreg |= BRIDGE_DEV_SWAP_BITS;
+    else
+	devreg &= ~BRIDGE_DEV_SWAP_BITS;
+
+    /* NOTE- if we ever put SWAP bits
+     * onto the disabled list, we will
+     * have to change the logic here.
+     */
+    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
+	bridge_t               *bridge = pcibr_soft->bs_base;
+
+	bridge->b_device[pciio_slot].reg = devreg;
+	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
+	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    }
+    pcibr_unlock(pcibr_soft, s);
+
+#if DEBUG && PCIBR_DEV_DEBUG
+    printk("pcibr Device(%d): 0x%p\n", pciio_slot, bridge->b_device[pciio_slot].reg);
+#endif
+
+    return desired_end;
+}
+
+/* This (re)sets the GBR and REALTIME bits and also keeps track of how
+ * many sets are outstanding. Reset succeeds only if the number of outstanding
+ * sets == 1.
+ */
+int
+pcibr_priority_bits_set(pcibr_soft_t pcibr_soft,
+			pciio_slot_t pciio_slot,
+			pciio_priority_t device_prio)
+{
+    unsigned long           s;
+    int                    *counter;
+    bridgereg_t             rtbits = 0;
+    bridgereg_t             devreg;
+    int                     rc = PRIO_SUCCESS;
+
+    /* in dual-slot configurations, the host and the
+     * guest have separate DMA resources, so they
+     * have separate requirements for priority bits.
+     */
+
+    counter = &(pcibr_soft->bs_slot[pciio_slot].bss_pri_uctr);
+
+    /*
+     * Bridge supports PCI notions of LOW and HIGH priority
+     * arbitration rings via a "REAL_TIME" bit in the per-device
+     * Bridge register. The "GBR" bit controls access to the GBR
+     * ring on the xbow. These two bits are (re)set together.
+     *
+     * XXX- Bug in Rev B Bridge Si:
+     * Symptom: Prefetcher starts operating incorrectly. This happens
+     * due to corruption of the address storage ram in the prefetcher
+     * when a non-real time PCI request is pulled and a real-time one is
+     * put in it's place. Workaround: Use only a single arbitration ring
+     * on PCI bus. GBR and RR can still be uniquely used per
+     * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C.
+     */
+
+    if (pcibr_soft->bs_rev_num != BRIDGE_PART_REV_B)
+	rtbits |= BRIDGE_DEV_RT;
+
+    /* NOTE- if we ever put DEV_RT or DEV_GBR on
+     * the disabled list, we will have to take
+     * it into account here.
+     */
+
+    s = pcibr_lock(pcibr_soft);
+    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
+    if (device_prio == PCI_PRIO_HIGH) {
+	if ((++*counter == 1)) {
+	    if (rtbits)
+		devreg |= rtbits;
+	    else
+		rc = PRIO_FAIL;
+	}
+    } else if (device_prio == PCI_PRIO_LOW) {
+	if (*counter <= 0)
+	    rc = PRIO_FAIL;
+	else if (--*counter == 0)
+	    if (rtbits)
+		devreg &= ~rtbits;
+    }
+    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
+	bridge_t               *bridge = pcibr_soft->bs_base;
+
+	bridge->b_device[pciio_slot].reg = devreg;
+	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
+	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    }
+    pcibr_unlock(pcibr_soft, s);
+
+    return rc;
+}
+
+pciio_priority_t
+pcibr_priority_set(devfs_handle_t pconn_vhdl,
+		   pciio_priority_t device_prio)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+    (void) pcibr_priority_bits_set(pcibr_soft, pciio_slot, device_prio);
+
+    return device_prio;
+}
+
+/*
+ * Interfaces to allow special (e.g. SGI) drivers to set/clear
+ * Bridge-specific device flags.  Many flags are modified through
+ * PCI-generic interfaces; we don't allow them to be directly
+ * manipulated here.  Only flags that at this point seem pretty
+ * Bridge-specific can be set through these special interfaces.
+ * We may add more flags as the need arises, or remove flags and
+ * create PCI-generic interfaces as the need arises.
+ *
+ * Returns 0 on failure, 1 on success
+ */
+int
+pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
+		       pcibr_device_flags_t flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridgereg_t             set = 0;
+    bridgereg_t             clr = 0;
+
+    ASSERT((flags & PCIBR_DEVICE_FLAGS) == flags);
+
+    if (flags & PCIBR_WRITE_GATHER)
+	set |= BRIDGE_DEV_PMU_WRGA_EN;
+    if (flags & PCIBR_NOWRITE_GATHER)
+	clr |= BRIDGE_DEV_PMU_WRGA_EN;
+
+    if (flags & PCIBR_WRITE_GATHER)
+	set |= BRIDGE_DEV_DIR_WRGA_EN;
+    if (flags & PCIBR_NOWRITE_GATHER)
+	clr |= BRIDGE_DEV_DIR_WRGA_EN;
+
+    if (flags & PCIBR_PREFETCH)
+	set |= BRIDGE_DEV_PREF;
+    if (flags & PCIBR_NOPREFETCH)
+	clr |= BRIDGE_DEV_PREF;
+
+    if (flags & PCIBR_PRECISE)
+	set |= BRIDGE_DEV_PRECISE;
+    if (flags & PCIBR_NOPRECISE)
+	clr |= BRIDGE_DEV_PRECISE;
+
+    if (flags & PCIBR_BARRIER)
+	set |= BRIDGE_DEV_BARRIER;
+    if (flags & PCIBR_NOBARRIER)
+	clr |= BRIDGE_DEV_BARRIER;
+
+    if (flags & PCIBR_64BIT)
+	set |= BRIDGE_DEV_DEV_SIZE;
+    if (flags & PCIBR_NO64BIT)
+	clr |= BRIDGE_DEV_DEV_SIZE;
+
+    if (set || clr) {
+	bridgereg_t             devreg;
+	unsigned long           s;
+
+	s = pcibr_lock(pcibr_soft);
+	devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
+	devreg = (devreg & ~clr) | set;
+	if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
+	    bridge_t               *bridge = pcibr_soft->bs_base;
+
+	    bridge->b_device[pciio_slot].reg = devreg;
+	    pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
+	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
+	}
+	pcibr_unlock(pcibr_soft, s);
+#if DEBUG && PCIBR_DEV_DEBUG
+	printk("pcibr Device(%d): %R\n", pciio_slot, bridge->b_device[pciio_slot].regbridge->b_device[pciio_slot].reg, device_bits);
+#endif
+    }
+    return (1);
+}
+
+#ifdef LITTLE_ENDIAN
+/*
+ * on sn-ia we need to twiddle the the addresses going out
+ * the pci bus because we use the unswizzled synergy space
+ * (the alternative is to use the swizzled synergy space
+ * and byte swap the data)
+ */
+#define	CB(b,r)	(((volatile uint8_t *) b)[((r)^4)])
+#define	CS(b,r)	(((volatile uint16_t *) b)[((r^4)/2)])
+#define	CW(b,r)	(((volatile uint32_t *) b)[((r^4)/4)])
+#else
+#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
+#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
+#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
+#endif /* LITTLE_ENDIAN */
+
+
+LOCAL                   cfg_p
+pcibr_config_addr(devfs_handle_t conn,
+		  unsigned reg)
+{
+    pcibr_info_t            pcibr_info;
+    pciio_slot_t            pciio_slot;
+    pciio_function_t        pciio_func;
+    pcibr_soft_t            pcibr_soft;
+    bridge_t               *bridge;
+    cfg_p                   cfgbase = (cfg_p)0;
+
+    pcibr_info = pcibr_info_get(conn);
+
+    pciio_slot = pcibr_info->f_slot;
+    if (pciio_slot == PCIIO_SLOT_NONE)
+	pciio_slot = PCI_TYPE1_SLOT(reg);
+
+    pciio_func = pcibr_info->f_func;
+    if (pciio_func == PCIIO_FUNC_NONE)
+	pciio_func = PCI_TYPE1_FUNC(reg);
+
+    pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
+
+    bridge = pcibr_soft->bs_base;
+
+    cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l;
+
+    return cfgbase;
+}
+
+uint64_t
+pcibr_config_get(devfs_handle_t conn,
+		 unsigned reg,
+		 unsigned size)
+{
+    return do_pcibr_config_get(pcibr_config_addr(conn, reg),
+			       PCI_TYPE1_REG(reg), size);
+}
+
+LOCAL uint64_t
+do_pcibr_config_get(
+		       cfg_p cfgbase,
+		       unsigned reg,
+		       unsigned size)
+{
+    unsigned                value;
+
+   
+    value = CW(cfgbase, reg);
+
+    if (reg & 3)
+	value >>= 8 * (reg & 3);
+    if (size < 4)
+	value &= (1 << (8 * size)) - 1;
+
+    return value;
+}
+
+void
+pcibr_config_set(devfs_handle_t conn,
+		 unsigned reg,
+		 unsigned size,
+		 uint64_t value)
+{
+    do_pcibr_config_set(pcibr_config_addr(conn, reg),
+			PCI_TYPE1_REG(reg), size, value);
+}
+
+LOCAL void
+do_pcibr_config_set(cfg_p cfgbase,
+		    unsigned reg,
+		    unsigned size,
+		    uint64_t value)
+{
+    switch (size) {
+    case 1:
+	CB(cfgbase, reg) = value;
+	break;
+    case 2:
+	if (reg & 1) {
+	    CB(cfgbase, reg) = value;
+	    CB(cfgbase, reg + 1) = value >> 8;
+	} else
+	    CS(cfgbase, reg) = value;
+	break;
+    case 3:
+	if (reg & 1) {
+	    CB(cfgbase, reg) = value;
+	    CS(cfgbase, (reg + 1)) = value >> 8;
+	} else {
+	    CS(cfgbase, reg) = value;
+	    CB(cfgbase, reg + 2) = value >> 16;
+	}
+	break;
+
+    case 4:
+	CW(cfgbase, reg) = value;
+	break;
+    }
+}
+
+pciio_provider_t        pcibr_provider =
+{
+    (pciio_piomap_alloc_f *) pcibr_piomap_alloc,
+    (pciio_piomap_free_f *) pcibr_piomap_free,
+    (pciio_piomap_addr_f *) pcibr_piomap_addr,
+    (pciio_piomap_done_f *) pcibr_piomap_done,
+    (pciio_piotrans_addr_f *) pcibr_piotrans_addr,
+    (pciio_piospace_alloc_f *) pcibr_piospace_alloc,
+    (pciio_piospace_free_f *) pcibr_piospace_free,
+
+    (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
+    (pciio_dmamap_free_f *) pcibr_dmamap_free,
+    (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
+    (pciio_dmamap_list_f *) pcibr_dmamap_list,
+    (pciio_dmamap_done_f *) pcibr_dmamap_done,
+    (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
+    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
+    (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
+    (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
+    (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
+
+    (pciio_intr_alloc_f *) pcibr_intr_alloc,
+    (pciio_intr_free_f *) pcibr_intr_free,
+    (pciio_intr_connect_f *) pcibr_intr_connect,
+    (pciio_intr_disconnect_f *) pcibr_intr_disconnect,
+    (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get,
+
+    (pciio_provider_startup_f *) pcibr_provider_startup,
+    (pciio_provider_shutdown_f *) pcibr_provider_shutdown,
+    (pciio_reset_f *) pcibr_reset,
+    (pciio_write_gather_flush_f *) pcibr_write_gather_flush,
+    (pciio_endian_set_f *) pcibr_endian_set,
+    (pciio_priority_set_f *) pcibr_priority_set,
+    (pciio_config_get_f *) pcibr_config_get,
+    (pciio_config_set_f *) pcibr_config_set,
+
+    (pciio_error_devenable_f *) 0,
+    (pciio_error_extract_f *) 0,
+
+#ifdef LATER
+    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
+    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
+#else
+    (pciio_driver_reg_callback_f *) 0,
+    (pciio_driver_unreg_callback_f *) 0,
+#endif
+    (pciio_device_unregister_f 	*) pcibr_device_unregister,
+    (pciio_dma_enabled_f		*) pcibr_dma_enabled,
+};
+
+LOCAL                   pcibr_hints_t
+pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
+{
+    arbitrary_info_t        ainfo = 0;
+    graph_error_t	    rv;
+    pcibr_hints_t           hint;
+
+    rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
+
+    if (alloc && (rv != GRAPH_SUCCESS)) {
+
+	NEW(hint);
+	hint->rrb_alloc_funct = NULL;
+	hint->ph_intr_bits = NULL;
+	rv = hwgraph_info_add_LBL(xconn_vhdl, 
+				  INFO_LBL_PCIBR_HINTS, 	
+				  (arbitrary_info_t) hint);
+	if (rv != GRAPH_SUCCESS)
+	    goto abnormal_exit;
+
+	rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
+	
+	if (rv != GRAPH_SUCCESS)
+	    goto abnormal_exit;
+
+	if (ainfo != (arbitrary_info_t) hint)
+	    goto abnormal_exit;
+    }
+    return (pcibr_hints_t) ainfo;
+
+abnormal_exit:
+#ifdef LATER
+    printf("SHOULD NOT BE HERE\n");
+#endif
+    DEL(hint);
+    return(NULL);
+
+}
+
+void
+pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->ph_rrb_fixed = mask;
+#if DEBUG
+    else
+	printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n"
+		"\t%p\n", xconn_vhdl);
+#endif
+}
+
+void
+pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
+{
+    pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
+}
+
+void
+pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
+		     pciio_slot_t host,
+		     pciio_slot_t guest)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->ph_host_slot[guest] = host + 1;
+#if DEBUG
+    else
+	printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n"
+		"\t%p\n", xconn_vhdl);
+#endif
+}
+
+void
+pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
+		      pcibr_intr_bits_f *xxx_intr_bits)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->ph_intr_bits = xxx_intr_bits;
+#if DEBUG
+    else
+	printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n"
+	       "\t%p\n", xconn_vhdl);
+#endif
+}
+
+void
+pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->rrb_alloc_funct = rrb_alloc_funct;
+}
+
+void
+pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->ph_hands_off = 1;
+#if DEBUG
+    else
+	printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n"
+		"\t%p\n", xconn_vhdl);
+#endif
+}
+
+void
+pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
+		    pciio_slot_t slot,
+		    uint64_t subdevs)
+{
+    arbitrary_info_t        ainfo = 0;
+    char                    sdname[16];
+    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
+
+    sprintf(sdname, "pci/%d", slot);
+    (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
+    if (pconn_vhdl == GRAPH_VERTEX_NONE) {
+#if DEBUG
+	printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n"
+		"\t%p (seeking %s)\n", xconn_vhdl, sdname);
+#endif
+	return;
+    }
+    hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
+    if (ainfo == 0) {
+	uint64_t                *subdevp;
+
+	NEW(subdevp);
+	if (!subdevp) {
+#if DEBUG
+	    printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n"
+		    "\t%p\n", pconn_vhdl);
+#endif
+	    return;
+	}
+	*subdevp = subdevs;
+	hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
+	hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
+	if (ainfo == (arbitrary_info_t) subdevp)
+	    return;
+	DEL(subdevp);
+	if (ainfo == (arbitrary_info_t) NULL) {
+#if DEBUG
+	    printk("pcibr_hints_subdevs: null subdevs ptr at\n"
+		    "\t%p\n", pconn_vhdl);
+#endif
+	    return;
+	}
+#if DEBUG
+	printk("pcibr_subdevs_get: dup subdev add_LBL at\n"
+		"\t%p\n", pconn_vhdl);
+#endif
+    }
+    *(uint64_t *) ainfo = subdevs;
+}
+
+
+#ifdef LATER
+
+#include <sys/idbg.h>
+#include <sys/idbgentry.h>
+
+char *pci_space[] = {"NONE", 
+		     "ROM",
+		     "IO",
+		     "",
+		     "MEM",
+		     "MEM32",
+		     "MEM64",
+		     "CFG",
+		     "WIN0",
+		     "WIN1",
+		     "WIN2",
+		     "WIN3",
+		     "WIN4",
+		     "WIN5",
+		     "",
+		     "BAD"};
+
+void
+idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
+{
+    pcibr_info_t	pcibr_info = pcibr_infoh[func];
+    char		name[MAXDEVNAME];
+    int			win;
+    
+    if (!pcibr_info)
+	return;
+    qprintf("Per-slot Function Info\n");
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    sprintf(name, "%v", pcibr_info->f_vertex);
+#endif
+    qprintf("\tSlot Name : %s\n",name);
+    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
+    qprintf("Slot : %d ", pcibr_info->f_slot);
+    qprintf("Function : %d ", pcibr_info->f_func);
+    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
+    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    sprintf(name, "%v", pcibr_info->f_master);
+#endif
+    qprintf("\tBus provider : %s\n",name);
+    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
+    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
+	    pcibr_info->f_efunc,pcibr_info->f_einfo);
+    for(win = 0 ; win < 6 ; win++) 
+	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
+		win,pci_space[pcibr_info->f_window[win].w_space],
+		pcibr_info->f_window[win].w_base,
+		pcibr_info->f_window[win].w_size);
+
+    qprintf("\tRom base 0x%x size 0x%x\n", 
+	    pcibr_info->f_rbase,pcibr_info->f_rsize);
+
+    qprintf("\tInterrupt Bit Map\n");
+    qprintf("\t\tPCI Int#\tBridge Pin#\n");
+    for (win = 0 ; win < 4; win++)
+	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
+    qprintf("\n");
+}
+
+
+void
+idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
+{
+    pcibr_soft_slot_t	pss;
+    char		slot_conn_name[MAXDEVNAME];
+    int			func;
+
+    pss = &pcibr_soft->bs_slot[slot];
+    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
+    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
+    qprintf("\tHost Slot : %d\n",pss->host_slot);
+    sprintf(slot_conn_name, "%v", pss->slot_conn);
+    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
+    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
+    for (func = 0; func < pss->bss_ninfo; func++)
+	idbg_pss_func(pss->bss_infos,func);
+    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
+    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
+    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
+    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
+	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
+    
+    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
+	    "d32_base 0x%x d32_flags 0x%x\n",
+	    pss->bss_d64_base, pss->bss_d64_flags,
+	    pss->bss_d32_base, pss->bss_d32_flags);
+    
+    qprintf("\tExt ATEs active ? %s", 
+	    atomic_read(&pss->bss_ext_ates_active) ? "yes" : "no");
+    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
+    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
+
+    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
+	    pcibr_soft->bs_rrb_valid[slot],
+	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+	    pcibr_soft->bs_rrb_res[slot]);
+		
+}
+
+int	ips = 0;
+
+void
+idbg_pss(pcibr_soft_t pcibr_soft)
+{
+    pciio_slot_t	slot;
+
+    
+    if (ips >= 0 && ips < 8)
+	idbg_pss_info(pcibr_soft,ips);
+    else if (ips < 0)
+	for (slot = 0; slot < 8; slot++) 
+	    idbg_pss_info(pcibr_soft,slot);
+    else
+	qprintf("Invalid ips %d\n",ips);
+}
+
+#endif /* LATER */
+
+int
+pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+	
+
+    return xtalk_dma_enabled(pcibr_soft->bs_conn);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/bte_error.c linux/arch/ia64/sn/io/sn2/bte_error.c
--- linux.orig/arch/ia64/sn/io/sn2/bte_error.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/bte_error.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,190 @@
+/* $Id: bte_error.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/smp.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/xtalk/xtalk.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/ioerror.h>
+#include <asm/sn/sn2/shubio.h>
+#include <asm/sn/bte.h>
+
+/************************************************************************
+ *									*
+ * 			 BTE ERROR RECOVERY				*
+ *									*
+ * Given a BTE error, the node causing the error must do the following: *
+ *    a) Clear all crbs relating to that BTE				*
+ *		1) Read CRBA value for crb in question			*
+ *		2) Mark CRB as VALID, store local physical 		*
+ *		   address known to be good in the address field	*
+ *		   (bte_notification_targ is a known good local		*
+ *		    address).						*
+ *		3) Write CRBA						*
+ *		4) Using ICCR, FLUSH the CRB, and wait for it to 	*
+ *		   complete.						*
+ *		... BTE BUSY bit should now be clear (or at least 	*
+ *		    should be after ALL CRBs associated with the 	*
+ *		    transfer are complete.				*
+ *									*
+ *    b) Re-enable BTE							*
+ *		1) Write IMEM with BTE Enable + XXX bits
+ *		2) Write IECLR with BTE clear bits
+ *		3) Clear IIDSR INT_SENT bits.
+ *									*
+ ************************************************************************/
+
+#ifdef BTE_ERROR
+// This routine is not called.  Yet.  It may be someday.  It probably
+// *should* be someday.  Until then, ifdef it out.
+bte_result_t
+bte_error_handler(bte_handle_t *bh)
+/*
+ * Function: 	bte_error_handler
+ * Purpose:	Process a BTE error after a transfer has failed.
+ * Parameters:	bh - bte handle of bte that failed.
+ * Returns:	The BTE error type.
+ * Notes:
+ */
+{
+    devfs_handle_t	hub_v;
+    hubinfo_t		hinfo;
+    int			il;
+    hubreg_t		iidsr, imem, ieclr;
+    hubreg_t		bte_status;
+
+    bh->bh_bte->bte_error_count++;
+
+    /* 
+     * Process any CRB logs - we know that the bte_context contains
+     * the BTE completion status, but to avoid a race with error
+     * processing, we force a call to pick up any CRB errors pending. 
+     * After this call, we know that we have any CRB errors related to 
+     * this BTE transfer in the context.
+     */
+    hub_v = cnodeid_to_vertex(bh->bh_bte->bte_cnode);
+    hubinfo_get(hub_v, &hinfo);
+    (void)hubiio_crb_error_handler(hub_v, hinfo);
+
+    /* Be sure BTE is stopped */
+
+    (void)BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_CTRL);
+
+    /*	
+     * Now clear up the rest of the error - be sure to hold crblock 
+     * to avoid race with other cpu on this node.
+     */
+    imem = REMOTE_HUB_L(hinfo->h_nasid, IIO_IMEM);
+    ieclr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IECLR);
+    if (bh->bh_bte->bte_num == 0) {
+	imem |= IIO_IMEM_W0ESD | IIO_IMEM_B0ESD;
+	ieclr|= IECLR_BTE0;
+    } else {
+	imem |= IIO_IMEM_W0ESD | IIO_IMEM_B1ESD;
+	ieclr|= IECLR_BTE1;
+    }
+
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IMEM, imem);
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, ieclr);
+
+    iidsr  = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR);
+    iidsr &= ~IIO_IIDSR_SENT_MASK;
+    iidsr |= IIO_IIDSR_ENB_MASK;
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, iidsr);
+    mutex_spinunlock(&hinfo->h_crblock, il);
+
+    bte_status = BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_STAT);
+    BTE_STORE(bh->bh_bte->bte_base, BTEOFF_STAT, bte_status & ~IBLS_BUSY);
+    ASSERT(!BTE_IS_BUSY(BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_STAT)));
+
+    switch(bh->bh_error) {
+    case IIO_ICRB_ECODE_PERR:
+	return(BTEFAIL_POISON);
+    case IIO_ICRB_ECODE_WERR:
+	return(BTEFAIL_PROT);
+    case IIO_ICRB_ECODE_AERR:
+	return(BTEFAIL_ACCESS);
+    case IIO_ICRB_ECODE_TOUT:
+	return(BTEFAIL_TOUT);
+    case IIO_ICRB_ECODE_XTERR:
+	return(BTEFAIL_ERROR);
+    case IIO_ICRB_ECODE_DERR:
+	return(BTEFAIL_DIR);
+    case IIO_ICRB_ECODE_PWERR:
+    case IIO_ICRB_ECODE_PRERR:
+	/* NO BREAK */
+    default:
+	printk("BTE failure (%d) unexpected\n", 
+		bh->bh_error);
+	return(BTEFAIL_ERROR);
+    }
+}
+#endif // BTE_ERROR
+
+void
+bte_crb_error_handler(devfs_handle_t hub_v, int btenum, 
+		      int crbnum, ioerror_t *ioe)
+/*
+ * Function: 	bte_crb_error_handler
+ * Purpose:	Process a CRB for a specific HUB/BTE
+ * Parameters:	hub_v	- vertex of hub in HW graph
+ *		btenum	- bte number on hub (0 == a, 1 == b)
+ *		crbnum	- crb number being processed
+ * Notes: 
+ *	This routine assumes serialization at a higher level. A CRB 
+ *	should not be processed more than once. The error recovery 
+ *	follows the following sequence - if you change this, be real
+ *	sure about what you are doing. 
+ *
+ */
+{
+        hubinfo_t	hinfo;
+	icrba_t		crba; 
+	icrbb_t		crbb; 
+	nasid_t		n;
+
+	hubinfo_get(hub_v, &hinfo);
+
+
+	n = hinfo->h_nasid;
+	
+	/* Step 1 */
+	crba.ii_icrb0_a_regval = REMOTE_HUB_L(n, IIO_ICRB_A(crbnum));
+	crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum));
+
+
+	/* Zero error and error code to prevent error_dump complaining
+	 * about these CRBs. 
+	 */
+	crbb.b_error=0;
+	crbb.b_ecode=0;
+
+	/* Step 2 */
+	REMOTE_HUB_S(n, IIO_ICRB_A(crbnum), crba.ii_icrb0_a_regval);
+	/* Step 3 */
+	REMOTE_HUB_S(n, IIO_ICCR, 
+		     IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum);
+	while (REMOTE_HUB_L(n, IIO_ICCR) & IIO_ICCR_PENDING)
+	    ;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/ml_SN_intr.c linux/arch/ia64/sn/io/sn2/ml_SN_intr.c
--- linux.orig/arch/ia64/sn/io/sn2/ml_SN_intr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/ml_SN_intr.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,469 @@
+/* $Id: ml_SN_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+/*
+ * intr.c-
+ *	This file contains all of the routines necessary to set up and
+ *	handle interrupts on an IPXX board.
+ */
+
+#ident  "$Revision: 1.1 $"
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <asm/smp.h>
+#include <asm/irq.h>
+#include <asm/hw_irq.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/xtalk/xtalk.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/sn2/shub_mmr_t.h>
+#include <asm/sal.h>
+#include <asm/sn/sn_sal.h>
+
+extern irqpda_t	*irqpdaindr[];
+extern cnodeid_t master_node_get(devfs_handle_t vhdl);
+extern nasid_t master_nasid;
+
+//  Initialize some shub registers for interrupts, both IO and error.
+
+void
+intr_init_vecblk( nodepda_t *npda,
+		cnodeid_t node,
+		int sn)
+{
+	int 			nasid = cnodeid_to_nasid(node);
+	nasid_t			console_nasid;
+	sh_ii_int0_config_u_t	ii_int_config;
+	cpuid_t			cpu;
+	cpuid_t			cpu0, cpu1;
+	nodepda_t		*lnodepda;
+	sh_ii_int0_enable_u_t	ii_int_enable;
+	sh_local_int0_config_u_t	local_int_config;
+	sh_local_int0_enable_u_t	local_int_enable;
+	sh_fsb_system_agent_config_u_t	fsb_system_agent;
+	sh_int_node_id_config_u_t	node_id_config;
+	int is_console;
+
+	console_nasid = get_console_nasid();
+	if (console_nasid < 0) {
+		console_nasid = master_nasid;
+	}
+
+	is_console = nasid == console_nasid;
+
+	if (is_headless_node(node) ) {
+		int cnode;
+		struct ia64_sal_retval ret_stuff;
+
+		// retarget all interrupts on this node to the master node.
+		node_id_config.sh_int_node_id_config_regval = 0;
+		node_id_config.sh_int_node_id_config_s.node_id = master_nasid;
+		node_id_config.sh_int_node_id_config_s.id_sel = 1;
+		HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_INT_NODE_ID_CONFIG),
+			node_id_config.sh_int_node_id_config_regval);
+		cnode = nasid_to_cnodeid(master_nasid);
+		lnodepda = NODEPDA(cnode);
+		cpu = lnodepda->node_first_cpu;
+		cpu = cpu_physical_id(cpu);
+		SAL_CALL(ret_stuff, SN_SAL_REGISTER_CE, nasid, cpu, master_nasid,0,0,0,0);
+		if (ret_stuff.status < 0) {
+			printk("%s: SN_SAL_REGISTER_CE SAL_CALL failed\n",__FUNCTION__);
+		}
+	} else {
+		lnodepda = NODEPDA(node);
+		cpu = lnodepda->node_first_cpu;
+		cpu = cpu_physical_id(cpu);
+	}
+
+	// Get the physical id's of the cpu's on this node.
+	cpu0 = id_eid_to_cpu_physical_id(nasid, 0);
+	cpu1 = id_eid_to_cpu_physical_id(nasid, 1);
+
+	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0);
+	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0);
+
+	// The II_INT_CONFIG register for cpu 0.
+	ii_int_config.sh_ii_int0_config_s.type = 0;
+	ii_int_config.sh_ii_int0_config_s.agt = 0;
+	ii_int_config.sh_ii_int0_config_s.pid = cpu0;
+	ii_int_config.sh_ii_int0_config_s.base = 0;
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_CONFIG),
+		ii_int_config.sh_ii_int0_config_regval);
+
+	// The II_INT_CONFIG register for cpu 1.
+	ii_int_config.sh_ii_int0_config_s.type = 0;
+	ii_int_config.sh_ii_int0_config_s.agt = 0;
+	ii_int_config.sh_ii_int0_config_s.pid = cpu1;
+	ii_int_config.sh_ii_int0_config_s.base = 0;
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_CONFIG),
+		ii_int_config.sh_ii_int0_config_regval);
+
+	// Enable interrupts for II_INT0 and 1.
+	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1;
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE),
+		ii_int_enable.sh_ii_int0_enable_regval);
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_ENABLE),
+		ii_int_enable.sh_ii_int0_enable_regval);
+
+	// init error regs
+	// LOCAL_INT0 is for the UART only.
+
+	local_int_config.sh_local_int0_config_s.type = 0;
+	local_int_config.sh_local_int0_config_s.agt = 0;
+	local_int_config.sh_local_int0_config_s.pid = cpu;
+	local_int_config.sh_local_int0_config_s.base = 0;
+	local_int_config.sh_local_int0_config_s.idx = SGI_UART_VECTOR;
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT0_CONFIG),
+		local_int_config.sh_local_int0_config_regval);
+
+	// LOCAL_INT1 is for all hardware errors.
+	// It will send a BERR, which will result in an MCA.
+	local_int_config.sh_local_int0_config_s.idx = 0;
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_CONFIG),
+		local_int_config.sh_local_int0_config_regval);
+
+	// Clear the LOCAL_INT_ENABLE register.
+	local_int_enable.sh_local_int0_enable_regval = 0;
+
+	if (is_console) {
+		// Enable the UART interrupt.  Only applies to the console nasid.
+		local_int_enable.sh_local_int0_enable_s.uart_int = 1;
+
+		HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT0_ENABLE),
+			local_int_enable.sh_local_int0_enable_regval);
+	}
+
+	// Enable all the error interrupts.
+	local_int_enable.sh_local_int0_enable_s.uart_int = 0;
+	local_int_enable.sh_local_int0_enable_s.pi_hw_int = 1;
+	local_int_enable.sh_local_int0_enable_s.md_hw_int = 1;
+	local_int_enable.sh_local_int0_enable_s.xn_hw_int = 1;
+	local_int_enable.sh_local_int0_enable_s.lb_hw_int = 1;
+	local_int_enable.sh_local_int0_enable_s.ii_hw_int = 1;
+	local_int_enable.sh_local_int0_enable_s.pi_uce_int = 1;
+	local_int_enable.sh_local_int0_enable_s.md_uce_int = 1;
+	local_int_enable.sh_local_int0_enable_s.xn_uce_int = 1;
+	local_int_enable.sh_local_int0_enable_s.system_shutdown_int = 1;
+	local_int_enable.sh_local_int0_enable_s.l1_nmi_int = 1;
+	local_int_enable.sh_local_int0_enable_s.stop_clock = 1;
+
+
+	// Send BERR, rather than an interrupt, for shub errors.
+	local_int_config.sh_local_int0_config_s.agt = 1;
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_CONFIG),
+		local_int_config.sh_local_int0_config_regval);
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_ENABLE),
+		local_int_enable.sh_local_int0_enable_regval);
+
+	// Make sure BERR is enabled.
+	fsb_system_agent.sh_fsb_system_agent_config_regval = 
+		HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_FSB_SYSTEM_AGENT_CONFIG) );
+	fsb_system_agent.sh_fsb_system_agent_config_s.berr_assert_en = 1;
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_FSB_SYSTEM_AGENT_CONFIG),
+		fsb_system_agent.sh_fsb_system_agent_config_regval);
+
+	// Set LOCAL_INT2 to field CEs
+
+	local_int_enable.sh_local_int0_enable_regval = 0;
+
+	local_int_config.sh_local_int0_config_s.agt = 0;
+	local_int_config.sh_local_int0_config_s.idx = SGI_SHUB_ERROR_VECTOR;
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT2_CONFIG),
+		local_int_config.sh_local_int0_config_regval);
+
+	local_int_enable.sh_local_int0_enable_s.pi_ce_int = 1;
+	local_int_enable.sh_local_int0_enable_s.md_ce_int = 1;
+	local_int_enable.sh_local_int0_enable_s.xn_ce_int = 1;
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT2_ENABLE),
+		local_int_enable.sh_local_int0_enable_regval);
+
+	// Make sure all the rest of the LOCAL_INT regs are disabled.
+	local_int_enable.sh_local_int0_enable_regval = 0;
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT3_ENABLE),
+		local_int_enable.sh_local_int0_enable_regval);
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT4_ENABLE),
+		local_int_enable.sh_local_int0_enable_regval);
+
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE),
+		local_int_enable.sh_local_int0_enable_regval);
+
+}
+
+// (Un)Reserve an irq on this cpu.
+
+static int
+do_intr_reserve_level(cpuid_t cpu,
+			int bit,
+			int reserve)
+{
+	int i;
+	irqpda_t	*irqs = irqpdaindr[cpu];
+
+	if (reserve) {
+		if (bit < 0) {
+			for (i = IA64_SN2_FIRST_DEVICE_VECTOR; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+				if (irqs->irq_flags[i] == 0) {
+					bit = i;
+					break;
+				}
+			}
+		}
+		if (bit < 0) {
+			return -1;
+		}
+		if (irqs->irq_flags[bit] & SN2_IRQ_RESERVED) {
+			return -1;
+		} else {
+			irqs->num_irq_used++;
+			irqs->irq_flags[bit] |= SN2_IRQ_RESERVED;
+			return bit;
+		}
+	} else {
+		if (irqs->irq_flags[bit] & SN2_IRQ_RESERVED) {
+			irqs->num_irq_used--;
+			irqs->irq_flags[bit] &= ~SN2_IRQ_RESERVED;
+			return bit;
+		} else {
+			return -1;
+		}
+	}
+}
+
+int
+intr_reserve_level(cpuid_t cpu,
+		int bit,
+		int resflags,
+		devfs_handle_t owner_dev,
+		char *name)
+{
+	return(do_intr_reserve_level(cpu, bit, 1));
+}
+
+void
+intr_unreserve_level(cpuid_t cpu,
+		int bit)
+{
+	(void)do_intr_reserve_level(cpu, bit, 0);
+}
+
+// Mark an irq on this cpu as (dis)connected.
+
+static int
+do_intr_connect_level(cpuid_t cpu,
+			int bit,
+			int connect)
+{
+	irqpda_t	*irqs = irqpdaindr[cpu];
+
+	if (connect) {
+		if (irqs->irq_flags[bit] & SN2_IRQ_CONNECTED) {
+			return -1;
+		} else {
+			irqs->irq_flags[bit] |= SN2_IRQ_CONNECTED;
+			return bit;
+		}
+	} else {
+		if (irqs->irq_flags[bit] & SN2_IRQ_CONNECTED) {
+			irqs->irq_flags[bit] &= ~SN2_IRQ_CONNECTED;
+			return bit;
+		} else {
+			return -1;
+		}
+	}
+	return(bit);
+}
+
+int
+intr_connect_level(cpuid_t cpu,
+		int bit,
+		ilvl_t is,
+		intr_func_t intr_prefunc)
+{
+	return(do_intr_connect_level(cpu, bit, 1));
+}
+
+int
+intr_disconnect_level(cpuid_t cpu,
+		int bit)
+{
+	return(do_intr_connect_level(cpu, bit, 0));
+}
+
+// Choose a cpu on this node.
+// We choose the one with the least number of int's assigned to it.
+
+static cpuid_t
+do_intr_cpu_choose(cnodeid_t cnode) {
+	cpuid_t		cpu, best_cpu = CPU_NONE;
+	int		slice, min_count = 1000;
+	irqpda_t	*irqs;
+
+	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
+		int intrs;
+
+		cpu = cnode_slice_to_cpuid(cnode, slice);
+		if (cpu == CPU_NONE) {
+			continue;
+		}
+
+		if (!cpu_enabled(cpu)) {
+			continue;
+		}
+
+		irqs = irqpdaindr[cpu];
+		intrs = irqs->num_irq_used;
+
+		if (min_count > intrs) {
+			min_count = intrs;
+			best_cpu = cpu;
+		}
+	}
+	return best_cpu;
+}
+
+static cpuid_t
+intr_cpu_choose_from_node(cnodeid_t cnode)
+{
+	return(do_intr_cpu_choose(cnode));
+}
+
+// See if we can use this cpu/vect.
+
+static cpuid_t
+intr_bit_reserve_test(cpuid_t cpu,
+			int favor_subnode,
+			cnodeid_t cnode,
+			int req_bit,
+			int resflags,
+			devfs_handle_t owner_dev,
+			char *name,
+			int *resp_bit)
+{
+	ASSERT( (cpu == CPU_NONE) || (cnode == CNODEID_NONE) );
+
+	if (cnode != CNODEID_NONE) {
+		cpu = intr_cpu_choose_from_node(cnode);
+	}
+
+	if (cpu != CPU_NONE) {
+		*resp_bit = do_intr_reserve_level(cpu, req_bit, 1);
+		if (*resp_bit >= 0) {
+			return(cpu);
+		}
+	}
+	return CPU_NONE;
+}
+
+// Find the node to assign for this interrupt.
+
+cpuid_t
+intr_heuristic(devfs_handle_t dev,
+		device_desc_t dev_desc,
+		int	req_bit,
+		int resflags,
+		devfs_handle_t owner_dev,
+		char *name,
+		int *resp_bit)
+{
+	cpuid_t		cpuid;
+	cnodeid_t	candidate = -1;
+	devfs_handle_t	pconn_vhdl;
+	pcibr_soft_t	pcibr_soft;
+
+/* SN2 + pcibr addressing limitation */
+/* Due to this limitation, all interrupts from a given bridge must go to the name node.*/
+/* This limitation does not exist on PIC. */
+
+	if ( (hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
+		( (pcibr_soft = pcibr_soft_get(pconn_vhdl) ) != NULL) ) {
+			if (pcibr_soft->bsi_err_intr) {
+				candidate = cpuid_to_cnodeid( ((hub_intr_t)pcibr_soft->bsi_err_intr)->i_cpuid);
+			}
+	}
+
+	if (candidate >= 0) {
+		// The node was chosen already when we assigned the error interrupt.
+		cpuid = intr_bit_reserve_test(CPU_NONE,
+						0,
+						candidate,
+						req_bit,
+						0,
+						owner_dev,
+						name,
+						resp_bit);
+	} else {
+		// Need to choose one.  Try the controlling c-brick first.
+		cpuid = intr_bit_reserve_test(CPU_NONE,
+						0,
+						master_node_get(dev),
+						req_bit,
+						0,
+						owner_dev,
+						name,
+						resp_bit);
+	}
+
+	if (cpuid != CPU_NONE) {
+		return cpuid;
+	}
+
+	if (candidate >= 0) {
+		printk("Cannot target interrupt to target node (%d).\n",candidate);
+		return CPU_NONE;
+	} else {
+		printk("Cannot target interrupt to closest node (%d) 0x%p\n",
+			master_node_get(dev), (void *)owner_dev);
+	}
+
+	// We couldn't put it on the closest node.  Try to find another one.
+	// Do a stupid round-robin assignment of the node.
+
+	{
+		static cnodeid_t last_node = -1;
+		if (last_node >= numnodes) last_node = 0;
+		for (candidate = last_node + 1; candidate != last_node; candidate++) {
+			if (candidate == numnodes) candidate = 0;
+			cpuid = intr_bit_reserve_test(CPU_NONE,
+							0,
+							candidate,
+							req_bit,
+							0,
+							owner_dev,
+							name,
+							resp_bit);
+			if (cpuid != CPU_NONE) {
+				return cpuid;
+			}
+		}
+	}
+
+	printk("cannot target interrupt: 0x%p\n",(void *)owner_dev);
+	return CPU_NONE;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,454 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+#ifdef __ia64
+uint64_t atealloc(struct map *mp, size_t size);
+void atefree(struct map *mp, size_t size, uint64_t a);
+void atemapfree(struct map *mp);
+struct map *atemapalloc(uint64_t mapsiz);
+
+#define rmallocmap atemapalloc
+#define rmfreemap atemapfree
+#define rmfree atefree
+#define rmalloc atealloc
+#endif
+
+
+#ifdef LATER
+#if (PCIBR_FREEZE_TIME) || PCIBR_ATE_DEBUG
+LOCAL struct reg_desc   ate_bits[] =
+{
+    {0xFFFF000000000000ull, -48, "RMF", "%x"},
+    {~(IOPGSIZE - 1) &			/* may trim off some low bits */
+     0x0000FFFFFFFFF000ull, 0, "XIO", "%x"},
+    {0x0000000000000F00ull, -8, "port", "%x"},
+    {0x0000000000000010ull, 0, "Barrier"},
+    {0x0000000000000008ull, 0, "Prefetch"},
+    {0x0000000000000004ull, 0, "Precise"},
+    {0x0000000000000002ull, 0, "Coherent"},
+    {0x0000000000000001ull, 0, "Valid"},
+    {0}
+};
+#endif
+#endif	/* LATER */
+
+#ifndef LOCAL
+#define LOCAL           static
+#endif
+
+/*
+ * functions
+ */
+int               pcibr_init_ext_ate_ram(bridge_t *);
+int               pcibr_ate_alloc(pcibr_soft_t, int);
+void              pcibr_ate_free(pcibr_soft_t, int, int);
+bridge_ate_t      pcibr_flags_to_ate(unsigned);
+bridge_ate_p      pcibr_ate_addr(pcibr_soft_t, int);
+unsigned 	  ate_freeze(pcibr_dmamap_t pcibr_dmamap,
+#if PCIBR_FREEZE_TIME
+	   			unsigned *freeze_time_ptr,
+#endif
+	   			unsigned *cmd_regs);
+void 	  ate_write(bridge_ate_p ate_ptr, int ate_count, bridge_ate_t ate);
+void ate_thaw(pcibr_dmamap_t pcibr_dmamap,
+	 			int ate_index,
+#if PCIBR_FREEZE_TIME
+	 			bridge_ate_t ate,
+	 			int ate_total,
+	 			unsigned freeze_time_start,
+#endif
+	 			unsigned *cmd_regs,
+	 			unsigned s);
+
+
+/* Convert from ssram_bits in control register to number of SSRAM entries */
+#define ATE_NUM_ENTRIES(n) _ate_info[n]
+
+/* Possible choices for number of ATE entries in Bridge's SSRAM */
+LOCAL int               _ate_info[] =
+{
+    0,					/* 0 entries */
+    8 * 1024,				/* 8K entries */
+    16 * 1024,				/* 16K entries */
+    64 * 1024				/* 64K entries */
+};
+
+#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))
+#define ATE_PROBE_VALUE 0x0123456789abcdefULL
+
+/*
+ * Determine the size of this bridge's external mapping SSRAM, and set
+ * the control register appropriately to reflect this size, and initialize
+ * the external SSRAM.
+ */
+int
+pcibr_init_ext_ate_ram(bridge_t *bridge)
+{
+    int                     largest_working_size = 0;
+    int                     num_entries, entry;
+    int                     i, j;
+    bridgereg_t             old_enable, new_enable;
+    int                     s;
+
+    /* Probe SSRAM to determine its size. */
+    old_enable = bridge->b_int_enable;
+    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
+    bridge->b_int_enable = new_enable;
+
+    for (i = 1; i < ATE_NUM_SIZES; i++) {
+	/* Try writing a value */
+	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
+
+	/* Guard against wrap */
+	for (j = 1; j < i; j++)
+	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
+
+	/* See if value was written */
+	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
+	    largest_working_size = i;
+    }
+    bridge->b_int_enable = old_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+
+    /*
+     * ensure that we write and read without any interruption.
+     * The read following the write is required for the Bridge war
+     */
+
+    s = splhi();
+    bridge->b_wid_control = (bridge->b_wid_control
+	& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
+	| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
+    bridge->b_wid_control;		/* inval addr bug war */
+    splx(s);
+
+    num_entries = ATE_NUM_ENTRIES(largest_working_size);
+
+#if PCIBR_ATE_DEBUG
+    if (num_entries)
+	printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries);
+    else
+	printk("bridge at 0x%x: no external ATE RAM found\n", bridge);
+#endif
+
+    /* Initialize external mapping entries */
+    for (entry = 0; entry < num_entries; entry++)
+	bridge->b_ext_ate_ram[entry] = 0;
+
+    return (num_entries);
+}
+
+/*
+ * Allocate "count" contiguous Bridge Address Translation Entries
+ * on the specified bridge to be used for PCI to XTALK mappings.
+ * Indices in rm map range from 1..num_entries.  Indicies returned
+ * to caller range from 0..num_entries-1.
+ *
+ * Return the start index on success, -1 on failure.
+ */
+int
+pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
+{
+    int                     index = 0;
+
+    index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
+
+    if (!index && pcibr_soft->bs_ext_ate_map)
+	index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
+
+    /* rmalloc manages resources in the 1..n
+     * range, with 0 being failure.
+     * pcibr_ate_alloc manages resources
+     * in the 0..n-1 range, with -1 being failure.
+     */
+    return index - 1;
+}
+
+void
+pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
+/* Who says there's no such thing as a free meal? :-) */
+{
+    /* note the "+1" since rmalloc handles 1..n but
+     * we start counting ATEs at zero.
+     */
+    rmfree((index < pcibr_soft->bs_int_ate_size)
+	   ? pcibr_soft->bs_int_ate_map
+	   : pcibr_soft->bs_ext_ate_map,
+	   count, index + 1);
+}
+
+/*
+ * Convert PCI-generic software flags and Bridge-specific software flags
+ * into Bridge-specific Address Translation Entry attribute bits.
+ */
+bridge_ate_t
+pcibr_flags_to_ate(unsigned flags)
+{
+    bridge_ate_t            attributes;
+
+    /* default if nothing specified:
+     * NOBARRIER
+     * NOPREFETCH
+     * NOPRECISE
+     * COHERENT
+     * Plus the valid bit
+     */
+    attributes = ATE_CO | ATE_V;
+
+    /* Generic macro flags
+     */
+    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
+	attributes &= ~ATE_BAR;		/* no barrier */
+	attributes |= ATE_PREF;		/* prefetch on */
+    }
+    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
+	attributes |= ATE_BAR;		/* barrier bit on */
+	attributes &= ~ATE_PREF;	/* disable prefetch */
+    }
+    /* Generic detail flags
+     */
+    if (flags & PCIIO_PREFETCH)
+	attributes |= ATE_PREF;
+    if (flags & PCIIO_NOPREFETCH)
+	attributes &= ~ATE_PREF;
+
+    /* Provider-specific flags
+     */
+    if (flags & PCIBR_BARRIER)
+	attributes |= ATE_BAR;
+    if (flags & PCIBR_NOBARRIER)
+	attributes &= ~ATE_BAR;
+
+    if (flags & PCIBR_PREFETCH)
+	attributes |= ATE_PREF;
+    if (flags & PCIBR_NOPREFETCH)
+	attributes &= ~ATE_PREF;
+
+    if (flags & PCIBR_PRECISE)
+	attributes |= ATE_PREC;
+    if (flags & PCIBR_NOPRECISE)
+	attributes &= ~ATE_PREC;
+
+    return (attributes);
+}
+
+/*
+ * Setup an Address Translation Entry as specified.  Use either the Bridge
+ * internal maps or the external map RAM, as appropriate.
+ */
+bridge_ate_p
+pcibr_ate_addr(pcibr_soft_t pcibr_soft,
+	       int ate_index)
+{
+    bridge_t *bridge = pcibr_soft->bs_base;
+
+    return (ate_index < pcibr_soft->bs_int_ate_size)
+	? &(bridge->b_int_ate_ram[ate_index].wr)
+	: &(bridge->b_ext_ate_ram[ate_index]);
+}
+
+/* We are starting to get more complexity
+ * surrounding writing ATEs, so pull
+ * the writing code into this new function.
+ */
+
+#if PCIBR_FREEZE_TIME
+#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs)
+#else
+#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, cmd_regs)
+#endif
+
+unsigned
+ate_freeze(pcibr_dmamap_t pcibr_dmamap,
+#if PCIBR_FREEZE_TIME
+	   unsigned *freeze_time_ptr,
+#endif
+	   unsigned *cmd_regs)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
+#ifdef LATER
+    int                     dma_slot = pcibr_dmamap->bd_slot;
+#endif
+    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
+    int                     slot;
+
+    unsigned long           s;
+    unsigned                cmd_reg;
+    volatile unsigned      *cmd_lwa;
+    unsigned                cmd_lwd;
+
+    if (!ext_ates)
+	return 0;
+
+    /* Bridge Hardware Bug WAR #484930:
+     * Bridge can't handle updating External ATEs
+     * while DMA is occuring that uses External ATEs,
+     * even if the particular ATEs involved are disjoint.
+     */
+
+    /* need to prevent anyone else from
+     * unfreezing the grant while we
+     * are working; also need to prevent
+     * this thread from being interrupted
+     * to keep PCI grant freeze time
+     * at an absolute minimum.
+     */
+    s = pcibr_lock(pcibr_soft);
+
+#ifdef LATER
+    /* just in case pcibr_dmamap_done was not called */
+    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
+	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
+	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
+	    atomic_dec(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
+	xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
+    }
+#endif	/* LATER */
+#if PCIBR_FREEZE_TIME
+    *freeze_time_ptr = get_timestamp();
+#endif
+
+    cmd_lwa = 0;
+    for (slot = 0; slot < 8; ++slot)
+	if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
+	    cmd_reg = pcibr_soft->
+		bs_slot[slot].
+		bss_cmd_shadow;
+	    if (cmd_reg & PCI_CMD_BUS_MASTER) {
+		cmd_lwa = pcibr_soft->
+		    bs_slot[slot].
+		    bss_cmd_pointer;
+		cmd_lwd = cmd_reg ^ PCI_CMD_BUS_MASTER;
+		cmd_lwa[0] = cmd_lwd;
+	    }
+	    cmd_regs[slot] = cmd_reg;
+	} else
+	    cmd_regs[slot] = 0;
+
+    if (cmd_lwa) {
+	    bridge_t	*bridge = pcibr_soft->bs_base;
+
+	    /* Read the last master bit that has been cleared. This PIO read
+	     * on the PCI bus is to ensure the completion of any DMAs that
+	     * are due to bus requests issued by PCI devices before the
+	     * clearing of master bits.
+	     */
+	    cmd_lwa[0];
+
+	    /* Flush all the write buffers in the bridge */
+	    for (slot = 0; slot < 8; ++slot)
+		    if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
+			    /* Flush the write buffer associated with this
+			     * PCI device which might be using dma map RAM.
+			     */
+			    bridge->b_wr_req_buf[slot].reg;
+		    }
+    }
+    return s;
+}
+
+#define	ATE_WRITE()    ate_write(ate_ptr, ate_count, ate)
+
+void
+ate_write(bridge_ate_p ate_ptr,
+	  int ate_count,
+	  bridge_ate_t ate)
+{
+    while (ate_count-- > 0) {
+	*ate_ptr++ = ate;
+	ate += IOPGSIZE;
+    }
+}
+
+#if PCIBR_FREEZE_TIME
+#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s)
+#else
+#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s)
+#endif
+
+void
+ate_thaw(pcibr_dmamap_t pcibr_dmamap,
+	 int ate_index,
+#if PCIBR_FREEZE_TIME
+	 bridge_ate_t ate,
+	 int ate_total,
+	 unsigned freeze_time_start,
+#endif
+	 unsigned *cmd_regs,
+	 unsigned s)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
+    int                     dma_slot = pcibr_dmamap->bd_slot;
+    int                     slot;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
+
+    unsigned                cmd_reg;
+
+#if PCIBR_FREEZE_TIME
+    unsigned                freeze_time;
+    static unsigned         max_freeze_time = 0;
+    static unsigned         max_ate_total;
+#endif
+
+    if (!ext_ates)
+	return;
+
+    /* restore cmd regs */
+    for (slot = 0; slot < 8; ++slot)
+	if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER)
+	    bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
+
+    pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
+    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
+
+#if PCIBR_FREEZE_TIME
+    freeze_time = get_timestamp() - freeze_time_start;
+
+    if ((max_freeze_time < freeze_time) ||
+	(max_ate_total < ate_total)) {
+	if (max_freeze_time < freeze_time)
+	    max_freeze_time = freeze_time;
+	if (max_ate_total < ate_total)
+	    max_ate_total = ate_total;
+	pcibr_unlock(pcibr_soft, s);
+	printk("%s: pci freeze time %d usec for %d ATEs\n"
+		"\tfirst ate: %R\n",
+		pcibr_soft->bs_name,
+		freeze_time * 1000 / 1250,
+		ate_total,
+		ate, ate_bits);
+    } else
+#endif
+	pcibr_unlock(pcibr_soft, s);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,167 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+extern pcibr_info_t      pcibr_info_get(devfs_handle_t);
+
+uint64_t          pcibr_config_get(devfs_handle_t, unsigned, unsigned);
+uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
+void              pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
+void              do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
+
+#ifdef LITTLE_ENDIAN
+#ifdef CONFIG_IA64_SGI_SN1
+/*
+ * on sn-ia we need to twiddle the the addresses going out
+ * the pci bus because we use the unswizzled synergy space
+ * (the alternative is to use the swizzled synergy space
+ * and byte swap the data)
+ */
+#define CB(b,r) (((volatile uint8_t *) b)[((r)^4)])
+#define CS(b,r) (((volatile uint16_t *) b)[((r^4)/2)])
+#define CW(b,r) (((volatile uint32_t *) b)[((r^4)/4)])
+#else
+#ifdef CONFIG_IA64_SGI_SN2
+/*
+ * On sn-ia sn2 everything is little endian.  No swizzling 
+ * or byte swapping of addresses required.
+ */
+#define CB(b,r) (((volatile uint8_t *) b)[(r)])
+#define CS(b,r) (((volatile uint16_t *) b)[(r)/2])
+#define CW(b,r) (((volatile uint32_t *) b)[(r)/4])
+#endif
+#endif
+#else
+#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
+#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
+#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
+#endif
+
+
+cfg_p
+pcibr_config_addr(devfs_handle_t conn,
+		  unsigned reg)
+{
+    pcibr_info_t            pcibr_info;
+    pciio_slot_t            pciio_slot;
+    pciio_function_t        pciio_func;
+    pcibr_soft_t            pcibr_soft;
+    bridge_t               *bridge;
+    cfg_p                   cfgbase = (cfg_p)0;
+
+    pcibr_info = pcibr_info_get(conn);
+
+    pciio_slot = pcibr_info->f_slot;
+    if (pciio_slot == PCIIO_SLOT_NONE)
+	pciio_slot = PCI_TYPE1_SLOT(reg);
+
+    pciio_func = pcibr_info->f_func;
+    if (pciio_func == PCIIO_FUNC_NONE)
+	pciio_func = PCI_TYPE1_FUNC(reg);
+
+    pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
+
+    bridge = pcibr_soft->bs_base;
+
+    cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l;
+
+    return cfgbase;
+}
+
+uint64_t
+pcibr_config_get(devfs_handle_t conn,
+		 unsigned reg,
+		 unsigned size)
+{
+    return do_pcibr_config_get(pcibr_config_addr(conn, reg),
+			       PCI_TYPE1_REG(reg), size);
+}
+
+uint64_t
+do_pcibr_config_get(
+		       cfg_p cfgbase,
+		       unsigned reg,
+		       unsigned size)
+{
+    unsigned                value;
+
+    value = CW(cfgbase, reg);
+
+    if (reg & 3)
+	value >>= 8 * (reg & 3);
+    if (size < 4)
+	value &= (1 << (8 * size)) - 1;
+    return value;
+}
+
+void
+pcibr_config_set(devfs_handle_t conn,
+		 unsigned reg,
+		 unsigned size,
+		 uint64_t value)
+{
+    do_pcibr_config_set(pcibr_config_addr(conn, reg),
+			PCI_TYPE1_REG(reg), size, value);
+}
+
+void
+do_pcibr_config_set(cfg_p cfgbase,
+		    unsigned reg,
+		    unsigned size,
+		    uint64_t value)
+{
+    switch (size) {
+    case 1:
+	CB(cfgbase, reg) = value;
+	break;
+    case 2:
+	if (reg & 1) {
+	    CB(cfgbase, reg) = value;
+	    CB(cfgbase, reg + 1) = value >> 8;
+	} else
+	    CS(cfgbase, reg) = value;
+	break;
+    case 3:
+	if (reg & 1) {
+	    CB(cfgbase, reg) = value;
+	    CS(cfgbase, (reg + 1)) = value >> 8;
+	} else {
+	    CS(cfgbase, reg) = value;
+	    CB(cfgbase, reg + 2) = value >> 16;
+	}
+	break;
+
+    case 4:
+	CW(cfgbase, reg) = value;
+	break;
+    }
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,4288 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+#ifdef __ia64
+#define rmallocmap atemapalloc
+#define rmfreemap atemapfree
+#define rmfree atefree
+#define rmalloc atealloc
+#endif
+
+/*
+ * Macros related to the Lucent USS 302/312 usb timeout workaround.  It
+ * appears that if the lucent part can get into a retry loop if it sees a
+ * DAC on the bus during a pio read retry.  The loop is broken after about
+ * 1ms, so we need to set up bridges holding this part to allow at least
+ * 1ms for pio.
+ */
+
+#define USS302_TIMEOUT_WAR
+
+#ifdef USS302_TIMEOUT_WAR
+#define LUCENT_USBHC_VENDOR_ID_NUM	0x11c1
+#define LUCENT_USBHC302_DEVICE_ID_NUM	0x5801
+#define LUCENT_USBHC312_DEVICE_ID_NUM	0x5802
+#define USS302_BRIDGE_TIMEOUT_HLD	4
+#endif
+
+int                     pcibr_devflag = D_MP;
+
+/*
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the
+ * appropriate function name below.
+ */
+struct file_operations pcibr_fops = {
+	owner:  THIS_MODULE,
+	llseek: NULL,
+	read: NULL,
+	write: NULL,
+	readdir: NULL,
+	poll: NULL,
+	ioctl: NULL,
+	mmap: NULL,
+	open: NULL,
+	flush: NULL,
+	release: NULL,
+	fsync: NULL,
+	fasync: NULL,
+	lock: NULL,
+	readv: NULL,
+	writev: NULL
+};
+
+#ifdef LATER
+
+#if PCIBR_ATE_DEBUG
+static struct reg_values ssram_sizes[] =
+{
+    {BRIDGE_CTRL_SSRAM_512K, "512k"},
+    {BRIDGE_CTRL_SSRAM_128K, "128k"},
+    {BRIDGE_CTRL_SSRAM_64K, "64k"},
+    {BRIDGE_CTRL_SSRAM_1K, "1k"},
+    {0}
+};
+
+static struct reg_desc   control_bits[] =
+{
+    {BRIDGE_CTRL_FLASH_WR_EN, 0, "FLASH_WR_EN"},
+    {BRIDGE_CTRL_EN_CLK50, 0, "EN_CLK50"},
+    {BRIDGE_CTRL_EN_CLK40, 0, "EN_CLK40"},
+    {BRIDGE_CTRL_EN_CLK33, 0, "EN_CLK33"},
+    {BRIDGE_CTRL_RST_MASK, -24, "RST", "%x"},
+    {BRIDGE_CTRL_IO_SWAP, 0, "IO_SWAP"},
+    {BRIDGE_CTRL_MEM_SWAP, 0, "MEM_SWAP"},
+    {BRIDGE_CTRL_PAGE_SIZE, 0, "PAGE_SIZE"},
+    {BRIDGE_CTRL_SS_PAR_BAD, 0, "SS_PAR_BAD"},
+    {BRIDGE_CTRL_SS_PAR_EN, 0, "SS_PAR_EN"},
+    {BRIDGE_CTRL_SSRAM_SIZE_MASK, 0, "SSRAM_SIZE", 0, ssram_sizes},
+    {BRIDGE_CTRL_F_BAD_PKT, 0, "F_BAD_PKT"},
+    {BRIDGE_CTRL_LLP_XBAR_CRD_MASK, -12, "LLP_XBAR_CRD", "%d"},
+    {BRIDGE_CTRL_CLR_RLLP_CNT, 0, "CLR_RLLP_CNT"},
+    {BRIDGE_CTRL_CLR_TLLP_CNT, 0, "CLR_TLLP_CNT"},
+    {BRIDGE_CTRL_SYS_END, 0, "SYS_END"},
+
+    {BRIDGE_CTRL_BUS_SPEED_MASK, -4, "BUS_SPEED", "%d"},
+    {BRIDGE_CTRL_WIDGET_ID_MASK, 0, "WIDGET_ID", "%x"},
+    {0}
+};
+#endif
+#endif	/* LATER */
+
+/* kbrick widgetnum-to-bus layout */
+int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
+        0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
+        2,                                      /* 0x8          */
+        1,                                      /* 0x9          */
+        0, 0,                                   /* 0xa - 0xb    */
+        5,                                      /* 0xc          */
+        6,                                      /* 0xd          */
+        4,                                      /* 0xe          */
+        3,                                      /* 0xf          */
+};
+
+/*
+ * Additional PIO spaces per slot are
+ * recorded in this structure.
+ */
+struct pciio_piospace_s {
+    pciio_piospace_t        next;       /* another space for this device */
+    char                    free;       /* 1 if free, 0 if in use               */
+    pciio_space_t           space;      /* Which space is in use                */
+    iopaddr_t               start;      /* Starting address of the PIO space    */
+    size_t                  count;      /* size of PIO space                    */
+};
+
+#if PCIBR_SOFT_LIST
+pcibr_list_p            pcibr_list = 0;
+#endif
+
+extern int              hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
+extern int              hub_device_flags_set(devfs_handle_t widget_dev, hub_widget_flags_t flags);
+extern long             atoi(register char *p);
+extern cnodeid_t        nodevertex_to_cnodeid(devfs_handle_t vhdl);
+extern void             *swap_ptr(void **loc, void *new);
+extern char             *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
+extern struct map       *atemapalloc(uint64_t);
+extern void             atefree(struct map *, size_t, uint64_t);
+extern void             atemapfree(struct map *);
+extern pciio_dmamap_t   get_free_pciio_dmamap(devfs_handle_t);
+extern void		free_pciio_dmamap(pcibr_dmamap_t);
+
+#define	ATE_WRITE()    ate_write(ate_ptr, ate_count, ate)
+#if PCIBR_FREEZE_TIME
+#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs)
+#else
+#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, cmd_regs)
+#endif /* PCIBR_FREEZE_TIME */
+
+#if PCIBR_FREEZE_TIME
+#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s)
+#else
+#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s)
+#endif
+
+
+/* =====================================================================
+ *    Function Table of Contents
+ *
+ *      The order of functions in this file has stopped
+ *      making much sense. We might want to take a look
+ *      at it some time and bring back some sanity, or
+ *      perhaps bust this file into smaller chunks.
+ */
+
+extern void              do_pcibr_rrb_clear(bridge_t *, int);
+extern void              do_pcibr_rrb_flush(bridge_t *, int);
+extern int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t);
+extern int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
+extern int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int);
+extern int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int);
+
+extern void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int);
+
+extern int  		 pcibr_wrb_flush(devfs_handle_t);
+extern int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
+extern int               pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
+extern int               pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int);
+extern void              pcibr_rrb_flush(devfs_handle_t);
+
+static int                pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
+void                     pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
+
+extern void              pcibr_clearwidint(bridge_t *);
+extern void              pcibr_setwidint(xtalk_intr_t);
+
+void                     pcibr_init(void);
+int                      pcibr_attach(devfs_handle_t);
+int			 pcibr_detach(devfs_handle_t);
+int                      pcibr_open(devfs_handle_t *, int, int, cred_t *);
+int                      pcibr_close(devfs_handle_t, int, int, cred_t *);
+int                      pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
+int                      pcibr_unmap(devfs_handle_t, vhandl_t *);
+int                      pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
+
+void                     pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
+
+extern int               pcibr_init_ext_ate_ram(bridge_t *);
+extern int               pcibr_ate_alloc(pcibr_soft_t, int);
+extern void              pcibr_ate_free(pcibr_soft_t, int, int);
+
+extern unsigned          ate_freeze(pcibr_dmamap_t pcibr_dmamap,
+#if PCIBR_FREEZE_TIME
+	   		 unsigned *freeze_time_ptr,
+#endif
+						unsigned *cmd_regs);
+extern void              ate_write(bridge_ate_p ate_ptr, int ate_count, bridge_ate_t ate);
+extern void              ate_thaw(pcibr_dmamap_t pcibr_dmamap, int ate_index,
+#if PCIBR_FREEZE_TIME
+	 				bridge_ate_t ate,
+	 				int ate_total,
+	 				unsigned freeze_time_start,
+#endif
+	 				unsigned *cmd_regs,
+	 				unsigned s);
+
+pcibr_info_t             pcibr_info_get(devfs_handle_t);
+
+static iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+
+pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
+void                    pcibr_piomap_free(pcibr_piomap_t);
+caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
+void                    pcibr_piomap_done(pcibr_piomap_t);
+caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
+void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
+
+static iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
+extern bridge_ate_t     pcibr_flags_to_ate(unsigned);
+
+pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+void                    pcibr_dmamap_free(pcibr_dmamap_t);
+extern bridge_ate_p     pcibr_ate_addr(pcibr_soft_t, int);
+static iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
+iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
+alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
+void                    pcibr_dmamap_done(pcibr_dmamap_t);
+cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
+iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
+alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+void                    pcibr_dmamap_drain(pcibr_dmamap_t);
+void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
+void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
+iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
+
+extern unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines);
+extern pcibr_intr_t     pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+extern void             pcibr_intr_free(pcibr_intr_t);
+extern void             pcibr_setpciint(xtalk_intr_t);
+extern int              pcibr_intr_connect(pcibr_intr_t);
+extern void             pcibr_intr_disconnect(pcibr_intr_t);
+
+extern devfs_handle_t     pcibr_intr_cpu_get(pcibr_intr_t);
+extern void             pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
+extern void             pcibr_intr_func(intr_arg_t);
+
+extern void             print_bridge_errcmd(uint32_t, char *);
+
+extern void             pcibr_error_dump(pcibr_soft_t);
+extern uint32_t         pcibr_errintr_group(uint32_t);
+extern void	        pcibr_pioerr_check(pcibr_soft_t);
+extern void             pcibr_error_intr_handler(intr_arg_t);
+
+extern int              pcibr_addr_toslot(pcibr_soft_t, iopaddr_t, pciio_space_t *, iopaddr_t *, pciio_function_t *);
+extern void             pcibr_error_cleanup(pcibr_soft_t, int);
+extern void                    pcibr_device_disable(pcibr_soft_t, int);
+extern int              pcibr_pioerror(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
+extern int              pcibr_dmard_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
+extern int              pcibr_dmawr_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
+extern int              pcibr_error_handler(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *);
+extern int              pcibr_error_devenable(devfs_handle_t, int);
+
+void                    pcibr_provider_startup(devfs_handle_t);
+void                    pcibr_provider_shutdown(devfs_handle_t);
+
+int                     pcibr_reset(devfs_handle_t);
+pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
+int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
+pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
+int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
+
+extern cfg_p            pcibr_config_addr(devfs_handle_t, unsigned);
+extern uint64_t         pcibr_config_get(devfs_handle_t, unsigned, unsigned);
+extern void             pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
+extern void             do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
+
+extern pcibr_hints_t    pcibr_hints_get(devfs_handle_t, int);
+extern void             pcibr_hints_fix_rrbs(devfs_handle_t);
+extern void             pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
+extern void	 	pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
+extern void             pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
+extern void             pcibr_hints_handsoff(devfs_handle_t);
+extern void             pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t);
+
+#ifdef BRIDGE_B_DATACORR_WAR
+extern int              ql_bridge_rev_b_war(devfs_handle_t);
+extern int              bridge_rev_b_data_check_disable;
+char                   *rev_b_datacorr_warning =
+"***************************** WARNING! ******************************\n";
+char                   *rev_b_datacorr_mesg =
+"UNRECOVERABLE IO LINK ERROR. CONTACT SERVICE PROVIDER\n";
+#endif
+
+extern int		pcibr_slot_reset(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
+extern int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_call_device_attach(devfs_handle_t, pciio_slot_t, int);
+extern int		pcibr_slot_call_device_detach(devfs_handle_t, pciio_slot_t, int);
+extern int              pcibr_slot_attach(devfs_handle_t, pciio_slot_t, int, char *, int *);
+extern int              pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int);
+extern int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
+
+#ifdef LATER
+extern int		pcibr_slot_startup(devfs_handle_t, pcibr_slot_req_t);
+extern int		pcibr_slot_shutdown(devfs_handle_t, pcibr_slot_req_t);
+extern int		pcibr_slot_query(devfs_handle_t, pcibr_slot_req_t);
+#endif
+
+extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t, pciio_slot_t);
+extern int		pcibr_initial_rrb(devfs_handle_t, pciio_slot_t, pciio_slot_t);
+
+
+
+/* =====================================================================
+ *    Device(x) register management
+ */
+
+/* pcibr_try_set_device: attempt to modify Device(x)
+ * for the specified slot on the specified bridge
+ * as requested in flags, limited to the specified
+ * bits. Returns which BRIDGE bits were in conflict,
+ * or ZERO if everything went OK.
+ *
+ * Caller MUST hold pcibr_lock when calling this function.
+ */
+static int
+pcibr_try_set_device(pcibr_soft_t pcibr_soft,
+		     pciio_slot_t slot,
+		     unsigned flags,
+		     bridgereg_t mask)
+{
+    bridge_t               *bridge;
+    pcibr_soft_slot_t       slotp;
+    bridgereg_t             old;
+    bridgereg_t             new;
+    bridgereg_t             chg;
+    bridgereg_t             bad;
+    bridgereg_t             badpmu;
+    bridgereg_t             badd32;
+    bridgereg_t             badd64;
+    bridgereg_t             fix;
+    unsigned long           s;
+    bridgereg_t             xmask;
+
+    xmask = mask;
+    if (pcibr_soft->bs_xbridge) {
+    	if (mask == BRIDGE_DEV_PMU_BITS)
+		xmask = XBRIDGE_DEV_PMU_BITS;
+	if (mask == BRIDGE_DEV_D64_BITS)
+		xmask = XBRIDGE_DEV_D64_BITS;
+    }
+
+    slotp = &pcibr_soft->bs_slot[slot];
+
+    s = pcibr_lock(pcibr_soft);
+
+    bridge = pcibr_soft->bs_base;
+
+    old = slotp->bss_device;
+
+    /* figure out what the desired
+     * Device(x) bits are based on
+     * the flags specified.
+     */
+
+    new = old;
+
+    /* Currently, we inherit anything that
+     * the new caller has not specified in
+     * one way or another, unless we take
+     * action here to not inherit.
+     *
+     * This is needed for the "swap" stuff,
+     * since it could have been set via
+     * pcibr_endian_set -- altho note that
+     * any explicit PCIBR_BYTE_STREAM or
+     * PCIBR_WORD_VALUES will freely override
+     * the effect of that call (and vice
+     * versa, no protection either way).
+     *
+     * I want to get rid of pcibr_endian_set
+     * in favor of tracking DMA endianness
+     * using the flags specified when DMA
+     * channels are created.
+     */
+
+#define	BRIDGE_DEV_WRGA_BITS	(BRIDGE_DEV_PMU_WRGA_EN | BRIDGE_DEV_DIR_WRGA_EN)
+#define	BRIDGE_DEV_SWAP_BITS	(BRIDGE_DEV_SWAP_PMU | BRIDGE_DEV_SWAP_DIR)
+
+    /* Do not use Barrier, Write Gather,
+     * or Prefetch unless asked.
+     * Leave everything else as it
+     * was from the last time.
+     */
+    new = new
+	& ~BRIDGE_DEV_BARRIER
+	& ~BRIDGE_DEV_WRGA_BITS
+	& ~BRIDGE_DEV_PREF
+	;
+
+    /* Generic macro flags
+     */
+    if (flags & PCIIO_DMA_DATA) {
+	new = (new
+            & ~BRIDGE_DEV_BARRIER)      /* barrier off */
+            | BRIDGE_DEV_PREF;          /* prefetch on */
+
+    }
+    if (flags & PCIIO_DMA_CMD) {
+        new = ((new
+            & ~BRIDGE_DEV_PREF)         /* prefetch off */
+            & ~BRIDGE_DEV_WRGA_BITS)    /* write gather off */
+            | BRIDGE_DEV_BARRIER;       /* barrier on */
+    }
+    /* Generic detail flags
+     */
+    if (flags & PCIIO_WRITE_GATHER)
+	new |= BRIDGE_DEV_WRGA_BITS;
+    if (flags & PCIIO_NOWRITE_GATHER)
+	new &= ~BRIDGE_DEV_WRGA_BITS;
+
+    if (flags & PCIIO_PREFETCH)
+	new |= BRIDGE_DEV_PREF;
+    if (flags & PCIIO_NOPREFETCH)
+	new &= ~BRIDGE_DEV_PREF;
+
+    if (flags & PCIBR_WRITE_GATHER)
+	new |= BRIDGE_DEV_WRGA_BITS;
+    if (flags & PCIBR_NOWRITE_GATHER)
+	new &= ~BRIDGE_DEV_WRGA_BITS;
+
+    if (flags & PCIIO_BYTE_STREAM)
+	new |= (pcibr_soft->bs_xbridge) ? 
+			BRIDGE_DEV_SWAP_DIR : BRIDGE_DEV_SWAP_BITS;
+    if (flags & PCIIO_WORD_VALUES)
+	new &= (pcibr_soft->bs_xbridge) ? 
+			~BRIDGE_DEV_SWAP_DIR : ~BRIDGE_DEV_SWAP_BITS;
+
+    /* Provider-specific flags
+     */
+    if (flags & PCIBR_PREFETCH)
+	new |= BRIDGE_DEV_PREF;
+    if (flags & PCIBR_NOPREFETCH)
+	new &= ~BRIDGE_DEV_PREF;
+
+    if (flags & PCIBR_PRECISE)
+	new |= BRIDGE_DEV_PRECISE;
+    if (flags & PCIBR_NOPRECISE)
+	new &= ~BRIDGE_DEV_PRECISE;
+
+    if (flags & PCIBR_BARRIER)
+	new |= BRIDGE_DEV_BARRIER;
+    if (flags & PCIBR_NOBARRIER)
+	new &= ~BRIDGE_DEV_BARRIER;
+
+    if (flags & PCIBR_64BIT)
+	new |= BRIDGE_DEV_DEV_SIZE;
+    if (flags & PCIBR_NO64BIT)
+	new &= ~BRIDGE_DEV_DEV_SIZE;
+
+    chg = old ^ new;				/* what are we changing, */
+    chg &= xmask;				/* of the interesting bits */
+
+    if (chg) {
+
+	badd32 = slotp->bss_d32_uctr ? (BRIDGE_DEV_D32_BITS & chg) : 0;
+	if (pcibr_soft->bs_xbridge) {
+		badpmu = slotp->bss_pmu_uctr ? (XBRIDGE_DEV_PMU_BITS & chg) : 0;
+		badd64 = slotp->bss_d64_uctr ? (XBRIDGE_DEV_D64_BITS & chg) : 0;
+	} else {
+		badpmu = slotp->bss_pmu_uctr ? (BRIDGE_DEV_PMU_BITS & chg) : 0;
+		badd64 = slotp->bss_d64_uctr ? (BRIDGE_DEV_D64_BITS & chg) : 0;
+	}
+	bad = badpmu | badd32 | badd64;
+
+	if (bad) {
+
+	    /* some conflicts can be resolved by
+	     * forcing the bit on. this may cause
+	     * some performance degredation in
+	     * the stream(s) that want the bit off,
+	     * but the alternative is not allowing
+	     * the new stream at all.
+	     */
+            if ( (fix = bad & (BRIDGE_DEV_PRECISE |
+                             BRIDGE_DEV_BARRIER)) ){
+		bad &= ~fix;
+		/* don't change these bits if
+		 * they are already set in "old"
+		 */
+		chg &= ~(fix & old);
+	    }
+	    /* some conflicts can be resolved by
+	     * forcing the bit off. this may cause
+	     * some performance degredation in
+	     * the stream(s) that want the bit on,
+	     * but the alternative is not allowing
+	     * the new stream at all.
+	     */
+	    if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS |
+			     BRIDGE_DEV_PREF)) ) {
+		bad &= ~fix;
+		/* don't change these bits if
+		 * we wanted to turn them on.
+		 */
+		chg &= ~(fix & new);
+	    }
+	    /* conflicts in other bits mean
+	     * we can not establish this DMA
+	     * channel while the other(s) are
+	     * still present.
+	     */
+	    if (bad) {
+		pcibr_unlock(pcibr_soft, s);
+#if (DEBUG && PCIBR_DEV_DEBUG)
+		printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits);
+#endif
+		return bad;
+	    }
+	}
+    }
+    if (mask == BRIDGE_DEV_PMU_BITS)
+	slotp->bss_pmu_uctr++;
+    if (mask == BRIDGE_DEV_D32_BITS)
+	slotp->bss_d32_uctr++;
+    if (mask == BRIDGE_DEV_D64_BITS)
+	slotp->bss_d64_uctr++;
+
+    /* the value we want to write is the
+     * original value, with the bits for
+     * our selected changes flipped, and
+     * with any disabled features turned off.
+     */
+    new = old ^ chg;			/* only change what we want to change */
+
+    if (slotp->bss_device == new) {
+	pcibr_unlock(pcibr_soft, s);
+	return 0;
+    }
+    bridge->b_device[slot].reg = new;
+    slotp->bss_device = new;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    pcibr_unlock(pcibr_soft, s);
+#if DEBUG && PCIBR_DEV_DEBUG
+    printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg);
+#endif
+
+    return 0;
+}
+
+void
+pcibr_release_device(pcibr_soft_t pcibr_soft,
+		     pciio_slot_t slot,
+		     bridgereg_t mask)
+{
+    pcibr_soft_slot_t       slotp;
+    unsigned long           s;
+
+    slotp = &pcibr_soft->bs_slot[slot];
+
+    s = pcibr_lock(pcibr_soft);
+
+    if (mask == BRIDGE_DEV_PMU_BITS)
+	slotp->bss_pmu_uctr--;
+    if (mask == BRIDGE_DEV_D32_BITS)
+	slotp->bss_d32_uctr--;
+    if (mask == BRIDGE_DEV_D64_BITS)
+	slotp->bss_d64_uctr--;
+
+    pcibr_unlock(pcibr_soft, s);
+}
+
+/*
+ * flush write gather buffer for slot
+ */
+static void
+pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft,
+              pciio_slot_t slot)
+{
+    bridge_t               *bridge;
+    unsigned long          s;
+    volatile uint32_t     wrf;
+    s = pcibr_lock(pcibr_soft);
+    bridge = pcibr_soft->bs_base;
+    wrf = bridge->b_wr_req_buf[slot].reg;
+    pcibr_unlock(pcibr_soft, s);
+}
+
+/* =====================================================================
+ *    Bridge (pcibr) "Device Driver" entry points
+ */
+
+
+/*
+ *    pcibr_init: called once during system startup or
+ *      when a loadable driver is loaded.
+ *
+ *      The driver_register function should normally
+ *      be in _reg, not _init.  But the pcibr driver is
+ *      required by devinit before the _reg routines
+ *      are called, so this is an exception.
+ */
+void
+pcibr_init(void)
+{
+#if DEBUG && ATTACH_DEBUG
+    printk("pcibr_init\n");
+#endif
+
+    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
+			    XBRIDGE_WIDGET_MFGR_NUM,
+			    "pcibr_",
+			    0);
+    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
+			    BRIDGE_WIDGET_MFGR_NUM,
+			    "pcibr_",
+			    0);
+}
+
+/*
+ * open/close mmap/munmap interface would be used by processes
+ * that plan to map the PCI bridge, and muck around with the
+ * registers. This is dangerous to do, and will be allowed
+ * to a select brand of programs. Typically these are
+ * diagnostics programs, or some user level commands we may
+ * write to do some weird things.
+ * To start with expect them to have root priveleges.
+ * We will ask for more later.
+ */
+/* ARGSUSED */
+int
+pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
+{
+    return 0;
+}
+
+/*ARGSUSED */
+int
+pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
+{
+    return 0;
+}
+
+/*ARGSUSED */
+int
+pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
+{
+    int                     error;
+    devfs_handle_t            vhdl = dev_to_vhdl(dev);
+    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+
+    hwgraph_vertex_unref(pcibr_vhdl);
+
+    ASSERT(pcibr_soft);
+    len = ctob(btoc(len));		/* Make len page aligned */
+    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
+
+    /*
+     * If the offset being mapped corresponds to the flash prom
+     * base, and if the mapping succeeds, and if the user
+     * has requested the protections to be WRITE, enable the
+     * flash prom to be written.
+     *
+     * XXX- deprecate this in favor of using the
+     * real flash driver ...
+     */
+    if (!error &&
+	((off == BRIDGE_EXTERNAL_FLASH) ||
+	 (len > BRIDGE_EXTERNAL_FLASH))) {
+	int                     s;
+
+	/*
+	 * ensure that we write and read without any interruption.
+	 * The read following the write is required for the Bridge war
+	 */
+	s = splhi();
+	bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
+	bridge->b_wid_control;		/* inval addr bug war */
+	splx(s);
+    }
+
+    return error;
+}
+
+/*ARGSUSED */
+int
+pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
+{
+    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+
+    hwgraph_vertex_unref(pcibr_vhdl);
+
+    /*
+     * If flashprom write was enabled, disable it, as
+     * this is the last unmap.
+     */
+    if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
+	int                     s;
+
+	/*
+	 * ensure that we write and read without any interruption.
+	 * The read following the write is required for the Bridge war
+	 */
+	s = splhi();
+	bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
+	bridge->b_wid_control;		/* inval addr bug war */
+	splx(s);
+    }
+    return 0;
+}
+
+/* This is special case code used by grio. There are plans to make
+ * this a bit more general in the future, but till then this should
+ * be sufficient.
+ */
+pciio_slot_t
+pcibr_device_slot_get(devfs_handle_t dev_vhdl)
+{
+    char                    devname[MAXDEVNAME];
+    devfs_handle_t            tdev;
+    pciio_info_t            pciio_info;
+    pciio_slot_t            slot = PCIIO_SLOT_NONE;
+
+    vertex_to_name(dev_vhdl, devname, MAXDEVNAME);
+
+    /* run back along the canonical path
+     * until we find a PCI connection point.
+     */
+    tdev = hwgraph_connectpt_get(dev_vhdl);
+    while (tdev != GRAPH_VERTEX_NONE) {
+	pciio_info = pciio_info_chk(tdev);
+	if (pciio_info) {
+	    slot = pciio_info_slot_get(pciio_info);
+	    break;
+	}
+	hwgraph_vertex_unref(tdev);
+	tdev = hwgraph_connectpt_get(tdev);
+    }
+    hwgraph_vertex_unref(tdev);
+
+    return slot;
+}
+
+/*ARGSUSED */
+int
+pcibr_ioctl(devfs_handle_t dev,
+	    int cmd,
+	    void *arg,
+	    int flag,
+	    struct cred *cr,
+	    int *rvalp)
+{
+    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);
+#ifdef LATER
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+#endif
+    int                     error = 0;
+
+    hwgraph_vertex_unref(pcibr_vhdl);
+
+    switch (cmd) {
+#ifdef LATER
+    case GIOCSETBW:
+	{
+	    grio_ioctl_info_t       info;
+	    pciio_slot_t            slot = 0;
+
+	    if (!cap_able((uint64_t)CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
+		error = EFAULT;
+		break;
+	    }
+#ifdef GRIO_DEBUG
+	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
+		    info.prev_vhdl, info.reqbw);
+#endif				/* GRIO_DEBUG */
+
+	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
+		PCIIO_SLOT_NONE) {
+		error = EIO;
+		break;
+	    }
+	    if (info.reqbw)
+		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH);
+	    break;
+	}
+
+    case GIOCRELEASEBW:
+	{
+	    grio_ioctl_info_t       info;
+	    pciio_slot_t            slot = 0;
+
+	    if (!cap_able(CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
+		error = EFAULT;
+		break;
+	    }
+#ifdef GRIO_DEBUG
+	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
+		    info.prev_vhdl, info.reqbw);
+#endif				/* GRIO_DEBUG */
+
+	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
+		PCIIO_SLOT_NONE) {
+		error = EIO;
+		break;
+	    }
+	    if (info.reqbw)
+		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);
+	    break;
+	}
+
+    case PCIBR_SLOT_STARTUP:
+	{
+	    struct pcibr_slot_req_s        req;
+
+	    if (!cap_able(CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+
+            if (COPYIN(arg, &req, sizeof(req))) {
+                error = EFAULT;
+                break;
+            }
+
+	    error = pcibr_slot_startup(pcibr_vhdl, &req);
+	    break;
+	}
+    case PCIBR_SLOT_SHUTDOWN:
+	{
+	    struct pcibr_slot_req_s        req;
+
+	    if (!cap_able(CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+
+            if (COPYIN(arg, &req, sizeof(req))) {
+                error = EFAULT;
+                break;
+            }
+
+	    error = pcibr_slot_shutdown(pcibr_vhdl, &req);
+	    break;
+	}
+    case PCIBR_SLOT_QUERY:
+	{
+	    struct pcibr_slot_req_s        req;
+
+	    if (!cap_able(CAP_DEVICE_MGT)) {
+		error = EPERM;
+		break;
+	    }
+
+            if (COPYIN(arg, &req, sizeof(req))) {
+                error = EFAULT;
+                break;
+            }
+
+            error = pcibr_slot_query(pcibr_vhdl, &req);
+	    break;
+	}
+#endif	/* LATER */
+    default:
+	break;
+
+    }
+
+    return error;
+}
+
+void
+pcibr_freeblock_sub(iopaddr_t *free_basep,
+		    iopaddr_t *free_lastp,
+		    iopaddr_t base,
+		    size_t size)
+{
+    iopaddr_t               free_base = *free_basep;
+    iopaddr_t               free_last = *free_lastp;
+    iopaddr_t               last = base + size - 1;
+
+    if ((last < free_base) || (base > free_last));	/* free block outside arena */
+
+    else if ((base <= free_base) && (last >= free_last))
+	/* free block contains entire arena */
+	*free_basep = *free_lastp = 0;
+
+    else if (base <= free_base)
+	/* free block is head of arena */
+	*free_basep = last + 1;
+
+    else if (last >= free_last)
+	/* free block is tail of arena */
+	*free_lastp = base - 1;
+
+    /*
+     * We are left with two regions: the free area
+     * in the arena "below" the block, and the free
+     * area in the arena "above" the block. Keep
+     * the one that is bigger.
+     */
+
+    else if ((base - free_base) > (free_last - last))
+	*free_lastp = base - 1;		/* keep lower chunk */
+    else
+	*free_basep = last + 1;		/* keep upper chunk */
+}
+
+pcibr_info_t
+pcibr_info_get(devfs_handle_t vhdl)
+{
+    return (pcibr_info_t) pciio_info_get(vhdl);
+}
+
+pcibr_info_t
+pcibr_device_info_new(
+			 pcibr_soft_t pcibr_soft,
+			 pciio_slot_t slot,
+			 pciio_function_t rfunc,
+			 pciio_vendor_id_t vendor,
+			 pciio_device_id_t device)
+{
+    pcibr_info_t            pcibr_info;
+    pciio_function_t        func;
+    int                     ibit;
+
+    func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc;
+
+    NEW(pcibr_info);
+
+    pciio_device_info_new(&pcibr_info->f_c,
+			  pcibr_soft->bs_vhdl,
+			  slot, rfunc,
+			  vendor, device);
+
+/* pfg - this is new ..... */
+    /* Set PCI bus number */
+    pcibr_info->f_bus = io_path_map_widget(pcibr_soft->bs_vhdl);
+
+    if (slot != PCIIO_SLOT_NONE) {
+
+	/*
+	 * Currently favored mapping from PCI
+	 * slot number and INTA/B/C/D to Bridge
+	 * PCI Interrupt Bit Number:
+	 *
+	 *     SLOT     A B C D
+	 *      0       0 4 0 4
+	 *      1       1 5 1 5
+	 *      2       2 6 2 6
+	 *      3       3 7 3 7
+	 *      4       4 0 4 0
+	 *      5       5 1 5 1
+	 *      6       6 2 6 2
+	 *      7       7 3 7 3
+	 *
+	 * XXX- allow pcibr_hints to override default
+	 * XXX- allow ADMIN to override pcibr_hints
+	 */
+	for (ibit = 0; ibit < 4; ++ibit)
+	    pcibr_info->f_ibit[ibit] =
+		(slot + 4 * ibit) & 7;
+
+	/*
+	 * Record the info in the sparse func info space.
+	 */
+	if (func < pcibr_soft->bs_slot[slot].bss_ninfo)
+	    pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info;
+    }
+    return pcibr_info;
+}
+
+
+/* FIXME:  for now this is needed by both pcibr.c and
+ * pcibr_slot.c.  Need to find a better way, the least
+ * of which would be to move it to pcibr_private.h
+ */
+
+/*
+ * PCI_ADDR_SPACE_LIMITS_STORE
+ *	Sets the current values of
+ *		pci io base, 
+ *		pci io last,
+ *		pci low memory base,
+ *		pci low memory last,
+ *		pci high memory base,
+ * 		pci high memory last
+ */
+#define PCI_ADDR_SPACE_LIMITS_STORE()			\
+    pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;	\
+    pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;	\
+    pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;	\
+    pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;	\
+    pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;	\
+    pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;
+
+
+/*
+ * pcibr_device_unregister
+ *	This frees up any hardware resources reserved for this PCI device
+ * 	and removes any PCI infrastructural information setup for it.
+ *	This is usually used at the time of shutting down of the PCI card.
+ */
+int
+pcibr_device_unregister(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t	 pciio_info;
+    devfs_handle_t	 pcibr_vhdl;
+    pciio_slot_t	 slot;
+    pcibr_soft_t	 pcibr_soft;
+    bridge_t		*bridge;
+    int                  count_vchan0, count_vchan1;
+    unsigned             s;
+    int			 error_call;
+    int			 error = 0;
+
+    pciio_info = pciio_info_get(pconn_vhdl);
+
+    pcibr_vhdl = pciio_info_master_get(pciio_info);
+    slot = pciio_info_slot_get(pciio_info);
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge = pcibr_soft->bs_base;
+
+    /* Clear all the hardware xtalk resources for this device */
+    xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot);
+
+    /* Flush all the rrbs */
+    pcibr_rrb_flush(pconn_vhdl);
+
+    /*
+     * If the RRB configuration for this slot has changed, set it 
+     * back to the boot-time default
+     */
+    if (pcibr_soft->bs_rrb_valid_dflt[slot] >= 0) {
+
+        s = pcibr_lock(pcibr_soft);
+
+        /* Free the rrbs allocated to this slot */
+        error_call = do_pcibr_rrb_free(bridge, slot, 
+		                       pcibr_soft->bs_rrb_valid[slot] +
+		                       pcibr_soft->bs_rrb_valid[slot + 
+                                       PCIBR_RRB_SLOT_VIRTUAL]);
+
+        if (error_call)
+            error = ERANGE;
+   
+         pcibr_soft->bs_rrb_res[slot] = pcibr_soft->bs_rrb_res[slot] +
+                                        pcibr_soft->bs_rrb_valid[slot] +
+                                        pcibr_soft->bs_rrb_valid[slot +
+                                        PCIBR_RRB_SLOT_VIRTUAL];
+
+        count_vchan0 = pcibr_soft->bs_rrb_valid_dflt[slot];
+        count_vchan1 = pcibr_soft->bs_rrb_valid_dflt[slot +
+                                                     PCIBR_RRB_SLOT_VIRTUAL];
+
+        pcibr_unlock(pcibr_soft, s);
+
+        pcibr_rrb_alloc(pconn_vhdl, &count_vchan0, &count_vchan1);
+
+    }
+
+    /* Flush the write buffers !! */
+    error_call = pcibr_wrb_flush(pconn_vhdl);
+
+    if (error_call)
+        error = error_call;
+
+    /* Clear the information specific to the slot */
+    error_call = pcibr_slot_info_free(pcibr_vhdl, slot);
+
+    if (error_call)
+        error = error_call;
+
+    return(error);
+    
+}
+
+/*
+ * pcibr_driver_reg_callback
+ *      CDL will call this function for each device found in the PCI
+ *      registry that matches the vendor/device IDs supported by 
+ *      the driver being registered.  The device's connection vertex
+ *      and the driver's attach function return status enable the
+ *      slot's device status to be set.
+ */
+void
+pcibr_driver_reg_callback(devfs_handle_t pconn_vhdl,
+			  int key1, int key2, int error)
+{
+    pciio_info_t	 pciio_info;
+    pcibr_info_t         pcibr_info;
+    devfs_handle_t	 pcibr_vhdl;
+    pciio_slot_t	 slot;
+    pcibr_soft_t	 pcibr_soft;
+
+    /* Do not set slot status for vendor/device ID wildcard drivers */
+    if ((key1 == -1) || (key2 == -1))
+        return;
+
+    pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_info = pcibr_info_get(pconn_vhdl);
+
+    pcibr_vhdl = pciio_info_master_get(pciio_info);
+    slot = pciio_info_slot_get(pciio_info);
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    /* This may be a loadable driver so lock out any pciconfig actions */
+    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
+
+    pcibr_info->f_att_det_error = error;
+
+    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
+
+    if (error) {
+        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
+    } else {
+        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
+    }
+        
+    /* Release the bus lock */
+    mrunlock(pcibr_soft->bs_bus_lock);
+
+}
+
+/*
+ * pcibr_driver_unreg_callback
+ *      CDL will call this function for each device found in the PCI
+ *      registry that matches the vendor/device IDs supported by 
+ *      the driver being unregistered.  The device's connection vertex
+ *      and the driver's detach function return status enable the
+ *      slot's device status to be set.
+ */
+void
+pcibr_driver_unreg_callback(devfs_handle_t pconn_vhdl, 
+                            int key1, int key2, int error)
+{
+    pciio_info_t	 pciio_info;
+    pcibr_info_t         pcibr_info;
+    devfs_handle_t	 pcibr_vhdl;
+    pciio_slot_t	 slot;
+    pcibr_soft_t	 pcibr_soft;
+
+    /* Do not set slot status for vendor/device ID wildcard drivers */
+    if ((key1 == -1) || (key2 == -1))
+        return;
+
+    pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_info = pcibr_info_get(pconn_vhdl);
+
+    pcibr_vhdl = pciio_info_master_get(pciio_info);
+    slot = pciio_info_slot_get(pciio_info);
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    /* This may be a loadable driver so lock out any pciconfig actions */
+    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
+
+    pcibr_info->f_att_det_error = error;
+
+    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
+
+    if (error) {
+        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
+    } else {
+        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
+    }
+        
+    /* Release the bus lock */
+    mrunlock(pcibr_soft->bs_bus_lock);
+
+}
+
+/* 
+ * build a convenience link path in the
+ * form of ".../<iobrick>/bus/<busnum>"
+ * 
+ * returns 1 on success, 0 otherwise
+ *
+ * depends on hwgraph separator == '/'
+ */
+int
+pcibr_bus_cnvlink(devfs_handle_t f_c, int slot)
+{
+        char dst[MAXDEVNAME];
+	char *dp = dst;
+        char *cp, *xp;
+        int widgetnum;
+        char pcibus[8];
+	devfs_handle_t nvtx, svtx;
+	int rv;
+
+#if DEBUG
+	printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", 
+		slot, f_c);
+	{
+		int pos;
+		char dname[256];
+		pos = devfs_generate_path(f_c, dname, 256);
+		printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
+	}
+#endif
+
+	if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME))
+		return 0;
+
+	/* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */
+
+	/* find the widget number */
+	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
+	if (xp == NULL)
+		return 0;
+	widgetnum = atoi(xp+7);
+	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
+		return 0;
+
+	/* remove "/pci/direct" from path */
+	cp = strstr(dst, "/" EDGE_LBL_PCI "/" "direct");
+	if (cp == NULL)
+		return 0;
+	*cp = (char)NULL;
+
+	/* get the vertex for the widget */
+	if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx))	
+		return 0;
+
+	*xp = (char)NULL;		/* remove "/xtalk/..." from path */
+
+	/* dst example now == /hw/module/001c02/Pbrick */
+
+	/* get the bus number */
+        strcat(dst, "/bus");
+        sprintf(pcibus, "%d", p_busnum[widgetnum]);
+
+	/* link to bus to widget */
+	rv = hwgraph_path_add(NULL, dp, &nvtx);
+	if (GRAPH_SUCCESS == rv)
+		rv = hwgraph_edge_add(nvtx, svtx, pcibus);
+
+	return (rv == GRAPH_SUCCESS);
+}
+
+
+/*
+ *    pcibr_attach: called every time the crosstalk
+ *      infrastructure is asked to initialize a widget
+ *      that matches the part number we handed to the
+ *      registration routine above.
+ */
+/*ARGSUSED */
+int
+pcibr_attach(devfs_handle_t xconn_vhdl)
+{
+    /* REFERENCED */
+    graph_error_t           rc;
+    devfs_handle_t            pcibr_vhdl;
+    devfs_handle_t            ctlr_vhdl;
+    bridge_t               *bridge = NULL;
+    bridgereg_t             id;
+    int                     rev;
+    pcibr_soft_t            pcibr_soft;
+    pcibr_info_t            pcibr_info;
+    xwidget_info_t          info;
+    xtalk_intr_t            xtalk_intr;
+    device_desc_t           dev_desc = (device_desc_t)0;
+    int                     slot;
+    int                     ibit;
+    devfs_handle_t            noslot_conn;
+    char                    devnm[MAXDEVNAME], *s;
+    pcibr_hints_t           pcibr_hints;
+    bridgereg_t             b_int_enable;
+    unsigned                rrb_fixed = 0;
+
+    iopaddr_t               pci_io_fb, pci_io_fl;
+    iopaddr_t               pci_lo_fb, pci_lo_fl;
+    iopaddr_t               pci_hi_fb, pci_hi_fl;
+
+    int                     spl_level;
+#ifdef LATER
+    char		    *nicinfo = (char *)0;
+#endif
+
+#if PCI_FBBE
+    int                     fast_back_to_back_enable;
+#endif
+    l1sc_t		    *scp;
+    nasid_t		    nasid;
+
+    async_attach_t          aa = NULL;
+
+    aa = async_attach_get_info(xconn_vhdl);
+
+#if DEBUG && ATTACH_DEBUG
+    printk("pcibr_attach: xconn_vhdl=  %p\n", xconn_vhdl);
+    {
+	int pos;
+	char dname[256];
+	pos = devfs_generate_path(xconn_vhdl, dname, 256);
+	printk("%s : path= %s \n", __FUNCTION__, &dname[pos]);
+    }
+#endif
+
+    /* Setup the PRB for the bridge in CONVEYOR BELT
+     * mode. PRBs are setup in default FIRE-AND-FORGET
+     * mode during the initialization.
+     */
+    hub_device_flags_set(xconn_vhdl, HUB_PIO_CONVEYOR);
+
+    bridge = (bridge_t *)
+	xtalk_piotrans_addr(xconn_vhdl, NULL,
+			    0, sizeof(bridge_t), 0);
+
+    /*
+     * Create the vertex for the PCI bus, which we
+     * will also use to hold the pcibr_soft and
+     * which will be the "master" vertex for all the
+     * pciio connection points we will hang off it.
+     * This needs to happen before we call nic_bridge_vertex_info
+     * as we are some of the *_vmc functions need access to the edges.
+     *
+     * Opening this vertex will provide access to
+     * the Bridge registers themselves.
+     */
+    rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl);
+    ASSERT(rc == GRAPH_SUCCESS);
+
+    ctlr_vhdl = NULL;
+    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
+                0, DEVFS_FL_AUTO_DEVNUM,
+                0, 0,
+                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+                &pcibr_fops, NULL);
+
+    ASSERT(ctlr_vhdl != NULL);
+
+    /*
+     * decode the nic, and hang its stuff off our
+     * connection point where other drivers can get
+     * at it.
+     */
+#ifdef LATER
+    nicinfo = BRIDGE_VERTEX_MFG_INFO(xconn_vhdl, (nic_data_t) & bridge->b_nic);
+#endif
+
+    /*
+     * Get the hint structure; if some NIC callback
+     * marked this vertex as "hands-off" then we
+     * just return here, before doing anything else.
+     */
+    pcibr_hints = pcibr_hints_get(xconn_vhdl, 0);
+
+    if (pcibr_hints && pcibr_hints->ph_hands_off)
+	return -1;			/* generic operations disabled */
+
+    id = bridge->b_wid_id;
+    rev = XWIDGET_PART_REV_NUM(id);
+
+    hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev);
+
+    /*
+     * allocate soft state structure, fill in some
+     * fields, and hook it up to our vertex.
+     */
+    NEW(pcibr_soft);
+    BZERO(pcibr_soft, sizeof *pcibr_soft);
+    pcibr_soft_set(pcibr_vhdl, pcibr_soft);
+
+    pcibr_soft->bs_conn = xconn_vhdl;
+    pcibr_soft->bs_vhdl = pcibr_vhdl;
+    pcibr_soft->bs_base = bridge;
+    pcibr_soft->bs_rev_num = rev;
+    pcibr_soft->bs_intr_bits = pcibr_intr_bits;
+    if (is_xbridge(bridge)) {
+	pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES;
+	pcibr_soft->bs_xbridge = 1;
+    } else {
+	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
+	pcibr_soft->bs_xbridge = 0;
+    }
+
+    nasid = NASID_GET(bridge);
+    scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
+    pcibr_soft->bs_l1sc = scp;
+    pcibr_soft->bs_moduleid = iobrick_module_get(scp);
+    pcibr_soft->bsi_err_intr = 0;
+
+    /* Bridges up through REV C
+     * are unable to set the direct
+     * byteswappers to BYTE_STREAM.
+     */
+    if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) {
+	pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES;
+	pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES;
+    }
+#if PCIBR_SOFT_LIST
+    {
+	pcibr_list_p            self;
+
+	NEW(self);
+	self->bl_soft = pcibr_soft;
+	self->bl_vhdl = pcibr_vhdl;
+	self->bl_next = pcibr_list;
+	self->bl_next = swap_ptr((void **) &pcibr_list, (void *)self);
+    }
+#endif
+
+    /*
+     * get the name of this bridge vertex and keep the info. Use this
+     * only where it is really needed now: like error interrupts.
+     */
+    s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME);
+    pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
+    strcpy(pcibr_soft->bs_name, s);
+
+#if SHOW_REVS || DEBUG
+#if !DEBUG
+    if (kdebug)
+#endif
+	printk("%sBridge ASIC: rev %s (code=0x%x) at %s\n",
+		is_xbridge(bridge) ? "X" : "",
+		(rev == BRIDGE_PART_REV_A) ? "A" :
+		(rev == BRIDGE_PART_REV_B) ? "B" :
+		(rev == BRIDGE_PART_REV_C) ? "C" :
+		(rev == BRIDGE_PART_REV_D) ? "D" :
+		(rev == XBRIDGE_PART_REV_A) ? "A" :
+		(rev == XBRIDGE_PART_REV_B) ? "B" :
+		"unknown",
+		rev, pcibr_soft->bs_name);
+#endif
+
+    info = xwidget_info_get(xconn_vhdl);
+    pcibr_soft->bs_xid = xwidget_info_id_get(info);
+    pcibr_soft->bs_master = xwidget_info_master_get(info);
+    pcibr_soft->bs_mxid = xwidget_info_masterid_get(info);
+
+    /*
+     * Init bridge lock.
+     */
+    spin_lock_init(&pcibr_soft->bs_lock);
+
+    /*
+     * If we have one, process the hints structure.
+     */
+    if (pcibr_hints) {
+	rrb_fixed = pcibr_hints->ph_rrb_fixed;
+
+	pcibr_soft->bs_rrb_fixed = rrb_fixed;
+
+	if (pcibr_hints->ph_intr_bits)
+	    pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;
+
+	for (slot = 0; slot < 8; ++slot) {
+	    int                     hslot = pcibr_hints->ph_host_slot[slot] - 1;
+
+	    if (hslot < 0) {
+		pcibr_soft->bs_slot[slot].host_slot = slot;
+	    } else {
+		pcibr_soft->bs_slot[slot].has_host = 1;
+		pcibr_soft->bs_slot[slot].host_slot = hslot;
+	    }
+	}
+    }
+    /*
+     * set up initial values for state fields
+     */
+    for (slot = 0; slot < 8; ++slot) {
+	pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;
+	pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;
+	pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;
+	pcibr_soft->bs_slot[slot].bss_ext_ates_active = ATOMIC_INIT(0);
+    }
+
+    for (ibit = 0; ibit < 8; ++ibit) {
+	pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_stat = 
+							&(bridge->b_int_status);
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;
+	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;
+    }
+
+    /*
+     * Initialize various Bridge registers.
+     */
+
+    /*
+     * On pre-Rev.D bridges, set the PCI_RETRY_CNT
+     * to zero to avoid dropping stores. (#475347)
+     */
+    if (rev < BRIDGE_PART_REV_D)
+	bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK;
+
+    /*
+     * Clear all pending interrupts.
+     */
+    bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
+
+    /*
+     * Until otherwise set up,
+     * assume all interrupts are
+     * from slot 7.
+     */
+    bridge->b_int_device = (uint32_t) 0xffffffff;
+
+    {
+	bridgereg_t             dirmap;
+	paddr_t                 paddr;
+	iopaddr_t               xbase;
+	xwidgetnum_t            xport;
+	iopaddr_t               offset;
+	int                     num_entries = 0;
+	int                     entry;
+	cnodeid_t		cnodeid;
+	nasid_t			nasid;
+
+	/* Set the Bridge's 32-bit PCI to XTalk
+	 * Direct Map register to the most useful
+	 * value we can determine.  Note that we
+	 * must use a single xid for all of:
+	 *      direct-mapped 32-bit DMA accesses
+	 *      direct-mapped 64-bit DMA accesses
+	 *      DMA accesses through the PMU
+	 *      interrupts
+	 * This is the only way to guarantee that
+	 * completion interrupts will reach a CPU
+	 * after all DMA data has reached memory.
+	 * (Of course, there may be a few special
+	 * drivers/controlers that explicitly manage
+	 * this ordering problem.)
+	 */
+
+	cnodeid = 0;  /* default node id */
+	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
+	paddr = NODE_OFFSET(nasid) + 0;
+
+	/* currently, we just assume that if we ask
+	 * for a DMA mapping to "zero" the XIO
+	 * host will transmute this into a request
+	 * for the lowest hunk of memory.
+	 */
+	xbase = xtalk_dmatrans_addr(xconn_vhdl, 0,
+				    paddr, _PAGESZ, 0);
+
+	if (xbase != XIO_NOWHERE) {
+	    if (XIO_PACKED(xbase)) {
+		xport = XIO_PORT(xbase);
+		xbase = XIO_ADDR(xbase);
+	    } else
+		xport = pcibr_soft->bs_mxid;
+
+	    offset = xbase & ((1ull << BRIDGE_DIRMAP_OFF_ADDRSHFT) - 1ull);
+	    xbase >>= BRIDGE_DIRMAP_OFF_ADDRSHFT;
+
+	    dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT;
+
+	    if (xbase)
+		dirmap |= BRIDGE_DIRMAP_OFF & xbase;
+	    else if (offset >= (512 << 20))
+		dirmap |= BRIDGE_DIRMAP_ADD512;
+
+	    bridge->b_dir_map = dirmap;
+	}
+	/*
+	 * Set bridge's idea of page size according to the system's
+	 * idea of "IO page size".  TBD: The idea of IO page size
+	 * should really go away.
+	 */
+	/*
+	 * ensure that we write and read without any interruption.
+	 * The read following the write is required for the Bridge war
+	 */
+	spl_level = splhi();
+#if IOPGSIZE == 4096
+	bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE;
+#elif IOPGSIZE == 16384
+	bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE;
+#else
+	<<<Unable to deal with IOPGSIZE >>>;
+#endif
+	bridge->b_wid_control;		/* inval addr bug war */
+	splx(spl_level);
+
+	/* Initialize internal mapping entries */
+	for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++) {
+	    bridge->b_int_ate_ram[entry].wr = 0;
+	}
+
+	/*
+	 * Determine if there's external mapping SSRAM on this
+	 * bridge.  Set up Bridge control register appropriately,
+	 * inititlize SSRAM, and set software up to manage RAM
+	 * entries as an allocatable resource.
+	 *
+	 * Currently, we just use the rm* routines to manage ATE
+	 * allocation.  We should probably replace this with a
+	 * Best Fit allocator.
+	 *
+	 * For now, if we have external SSRAM, avoid using
+	 * the internal ssram: we can't turn PREFETCH on
+	 * when we use the internal SSRAM; and besides,
+	 * this also guarantees that no allocation will
+	 * straddle the internal/external line, so we
+	 * can increment ATE write addresses rather than
+	 * recomparing against BRIDGE_INTERNAL_ATES every
+	 * time.
+	 */
+	if (is_xbridge(bridge))
+		num_entries = 0;
+	else
+		num_entries = pcibr_init_ext_ate_ram(bridge);
+
+	/* we always have 128 ATEs (512 for Xbridge) inside the chip
+	 * even if disabled for debugging.
+	 */
+	pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
+	pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_attach: %d INTERNAL ATEs\n", pcibr_soft->bs_int_ate_size);
+#endif
+
+	if (num_entries > pcibr_soft->bs_int_ate_size) {
+#if PCIBR_ATE_NOTBOTH			/* for debug -- forces us to use external ates */
+	    printk("pcibr_attach: disabling internal ATEs.\n");
+	    pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
+#endif
+	    pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
+	    pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
+			   num_entries - pcibr_soft->bs_int_ate_size);
+#if PCIBR_ATE_DEBUG
+	    printk("pcibr_attach: %d EXTERNAL ATEs\n",
+		    num_entries - pcibr_soft->bs_int_ate_size);
+#endif
+	}
+    }
+
+    {
+	bridgereg_t             dirmap;
+	iopaddr_t               xbase;
+
+	/*
+	 * now figure the *real* xtalk base address
+	 * that dirmap sends us to.
+	 */
+	dirmap = bridge->b_dir_map;
+	if (dirmap & BRIDGE_DIRMAP_OFF)
+	    xbase = (iopaddr_t)(dirmap & BRIDGE_DIRMAP_OFF)
+			<< BRIDGE_DIRMAP_OFF_ADDRSHFT;
+	else if (dirmap & BRIDGE_DIRMAP_ADD512)
+	    xbase = 512 << 20;
+	else
+	    xbase = 0;
+
+	pcibr_soft->bs_dir_xbase = xbase;
+
+	/* it is entirely possible that we may, at this
+	 * point, have our dirmap pointing somewhere
+	 * other than our "master" port.
+	 */
+	pcibr_soft->bs_dir_xport =
+	    (dirmap & BRIDGE_DIRMAP_W_ID) >> BRIDGE_DIRMAP_W_ID_SHFT;
+    }
+
+    /* pcibr sources an error interrupt;
+     * figure out where to send it.
+     *
+     * If any interrupts are enabled in bridge,
+     * then the prom set us up and our interrupt
+     * has already been reconnected in mlreset
+     * above.
+     *
+     * Need to set the D_INTR_ISERR flag
+     * in the dev_desc used for allocating the
+     * error interrupt, so our interrupt will
+     * be properly routed and prioritized.
+     *
+     * If our crosstalk provider wants to
+     * fix widget error interrupts to specific
+     * destinations, D_INTR_ISERR is how it
+     * knows to do this.
+     */
+
+    xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, pcibr_vhdl);
+    ASSERT(xtalk_intr != NULL);
+
+    pcibr_soft->bsi_err_intr = xtalk_intr;
+
+    /*
+     * On IP35 with XBridge, we do some extra checks in pcibr_setwidint
+     * in order to work around some addressing limitations.  In order
+     * for that fire wall to work properly, we need to make sure we
+     * start from a known clean state.
+     */
+    pcibr_clearwidint(bridge);
+
+    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge);
+
+    /*
+     * now we can start handling error interrupts;
+     * enable all of them.
+     * NOTE: some PCI ints may already be enabled.
+     */
+    b_int_enable = bridge->b_int_enable | BRIDGE_ISR_ERRORS;
+
+
+    bridge->b_int_enable = b_int_enable;
+    bridge->b_int_mode = 0;		/* do not send "clear interrupt" packets */
+
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+
+    /*
+     * Depending on the rev of bridge, disable certain features.
+     * Easiest way seems to be to force the PCIBR_NOwhatever
+     * flag to be on for all DMA calls, which overrides any
+     * PCIBR_whatever flag or even the setting of whatever
+     * from the PCIIO_DMA_class flags (or even from the other
+     * PCIBR flags, since NO overrides YES).
+     */
+    pcibr_soft->bs_dma_flags = 0;
+
+    /* PREFETCH:
+     * Always completely disabled for REV.A;
+     * at "pcibr_prefetch_enable_rev", anyone
+     * asking for PCIIO_PREFETCH gets it.
+     * Between these two points, you have to ask
+     * for PCIBR_PREFETCH, which promises that
+     * your driver knows about known Bridge WARs.
+     */
+    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
+	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
+    else if (pcibr_soft->bs_rev_num < 
+		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
+	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
+
+    /* WRITE_GATHER:
+     * Disabled up to but not including the
+     * rev number in pcibr_wg_enable_rev. There
+     * is no "WAR range" as with prefetch.
+     */
+    if (pcibr_soft->bs_rev_num < 
+		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
+	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
+
+    pciio_provider_register(pcibr_vhdl, &pcibr_provider);
+    pciio_provider_startup(pcibr_vhdl);
+
+    pci_io_fb = 0x00000004;		/* I/O FreeBlock Base */
+    pci_io_fl = 0xFFFFFFFF;		/* I/O FreeBlock Last */
+
+    pci_lo_fb = 0x00000010;		/* Low Memory FreeBlock Base */
+    pci_lo_fl = 0x001FFFFF;		/* Low Memory FreeBlock Last */
+
+    pci_hi_fb = 0x00200000;		/* High Memory FreeBlock Base */
+    pci_hi_fl = 0x3FFFFFFF;		/* High Memory FreeBlock Last */
+
+
+    PCI_ADDR_SPACE_LIMITS_STORE();
+
+    /* build "no-slot" connection point
+     */
+    pcibr_info = pcibr_device_info_new
+	(pcibr_soft, PCIIO_SLOT_NONE, PCIIO_FUNC_NONE,
+	 PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
+    noslot_conn = pciio_device_info_register
+	(pcibr_vhdl, &pcibr_info->f_c);
+
+    /* Remember the no slot connection point info for tearing it
+     * down during detach.
+     */
+    pcibr_soft->bs_noslot_conn = noslot_conn;
+    pcibr_soft->bs_noslot_info = pcibr_info;
+#if PCI_FBBE
+    fast_back_to_back_enable = 1;
+#endif
+
+#if PCI_FBBE
+    if (fast_back_to_back_enable) {
+	/*
+	 * All devices on the bus are capable of fast back to back, so
+	 * we need to set the fast back to back bit in all devices on
+	 * the bus that are capable of doing such accesses.
+	 */
+    }
+#endif
+
+#ifdef LATER
+    /* If the bridge has been reset then there is no need to reset
+     * the individual PCI slots.
+     */
+    for (slot = 0; slot < 8; ++slot)  
+	/* Reset all the slots */
+	(void)pcibr_slot_reset(pcibr_vhdl, slot);
+#endif
+
+    for (slot = 0; slot < 8; ++slot)
+	/* Find out what is out there */
+	(void)pcibr_slot_info_init(pcibr_vhdl,slot);
+
+    for (slot = 0; slot < 8; ++slot)  
+	/* Set up the address space for this slot in the pci land */
+	(void)pcibr_slot_addr_space_init(pcibr_vhdl,slot);
+
+    for (slot = 0; slot < 8; ++slot)  
+	/* Setup the device register */
+	(void)pcibr_slot_device_init(pcibr_vhdl, slot);
+
+    for (slot = 0; slot < 8; ++slot)  
+	/* Setup host/guest relations */
+	(void)pcibr_slot_guest_info_init(pcibr_vhdl,slot);
+
+    for (slot = 0; slot < 8; ++slot)  
+	/* Initial RRB management */
+	(void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot);
+
+    /* driver attach routines should be called out from generic linux code */
+    for (slot = 0; slot < 8; ++slot)  
+	/* Call the device attach */
+	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
+
+    /*
+     * Each Pbrick PCI bus only has slots 1 and 2.   Similarly for
+     * widget 0xe on Ibricks.  Allocate RRB's accordingly.
+     */
+    if (pcibr_soft->bs_moduleid > 0) {
+	switch (MODULE_GET_BTCHAR(pcibr_soft->bs_moduleid)) {
+	case 'p':		/* Pbrick */
+		do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
+		do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
+		break;
+	case 'i':		/* Ibrick */
+	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
+		if (pcibr_soft->bs_xid == 0xe) {
+			do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
+			do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
+		}
+		else {
+		    	/* allocate one RRB for the serial port */
+			do_pcibr_rrb_autoalloc(pcibr_soft, 0, 1);
+		}
+		break;
+	} /* switch */
+    }
+
+#ifdef LATER
+    if (strstr(nicinfo, XTALK_PCI_PART_NUM)) {
+	do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
+#if PCIBR_RRB_DEBUG
+	printf("\n\nFound XTALK_PCI (030-1275) at %v\n", xconn_vhdl);
+
+	printf("pcibr_attach: %v Shoebox RRB MANAGEMENT: %d+%d free\n",
+		pcibr_vhdl,
+		pcibr_soft->bs_rrb_avail[0],
+		pcibr_soft->bs_rrb_avail[1]);
+
+	for (slot = 0; slot < 8; ++slot)
+	    printf("\t%d+%d+%d",
+	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
+	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+	    pcibr_soft->bs_rrb_res[slot]);
+
+	printf("\n");
+#endif
+    }
+#else
+	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
+#endif
+
+    if (aa)
+	    async_attach_add_info(noslot_conn, aa);
+
+    pciio_device_attach(noslot_conn, 0);
+
+
+    /* 
+     * Tear down pointer to async attach info -- async threads for
+     * bridge's descendants may be running but the bridge's work is done.
+     */
+    if (aa)
+	    async_attach_del_info(xconn_vhdl);
+
+    return 0;
+}
+/*
+ * pcibr_detach:
+ *	Detach the bridge device from the hwgraph after cleaning out all the 
+ *	underlying vertices.
+ */
+int
+pcibr_detach(devfs_handle_t xconn)
+{
+    pciio_slot_t	slot;
+    devfs_handle_t	pcibr_vhdl;
+    pcibr_soft_t	pcibr_soft;
+    bridge_t		*bridge;
+
+    /* Get the bridge vertex from its xtalk connection point */
+    if (hwgraph_traverse(xconn, EDGE_LBL_PCI, &pcibr_vhdl) != GRAPH_SUCCESS)
+	return(1);
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge = pcibr_soft->bs_base;
+
+    /* Disable the interrupts from the bridge */
+    bridge->b_int_enable = 0;
+
+    /* Detach all the PCI devices talking to this bridge */
+    for(slot = 0; slot < 8; slot++) {
+#ifdef DEBUG
+	printk("pcibr_device_detach called for %p/%d\n",
+		pcibr_vhdl,slot);
+#endif
+	pcibr_slot_detach(pcibr_vhdl, slot, 0);
+    }
+
+    /* Unregister the no-slot connection point */
+    pciio_device_info_unregister(pcibr_vhdl,
+				 &(pcibr_soft->bs_noslot_info->f_c));
+
+    spin_lock_destroy(&pcibr_soft->bs_lock);
+    kfree(pcibr_soft->bs_name);
+    
+    /* Error handler gets unregistered when the widget info is 
+     * cleaned 
+     */
+    /* Free the soft ATE maps */
+    if (pcibr_soft->bs_int_ate_map)
+	rmfreemap(pcibr_soft->bs_int_ate_map);
+    if (pcibr_soft->bs_ext_ate_map)
+	rmfreemap(pcibr_soft->bs_ext_ate_map);
+
+    /* Disconnect the error interrupt and free the xtalk resources 
+     * associated with it.
+     */
+    xtalk_intr_disconnect(pcibr_soft->bsi_err_intr);
+    xtalk_intr_free(pcibr_soft->bsi_err_intr);
+
+    /* Clear the software state maintained by the bridge driver for this
+     * bridge.
+     */
+    DEL(pcibr_soft);
+    /* Remove the Bridge revision labelled info */
+    (void)hwgraph_info_remove_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, NULL);
+    /* Remove the character device associated with this bridge */
+    (void)hwgraph_edge_remove(pcibr_vhdl, EDGE_LBL_CONTROLLER, NULL);
+    /* Remove the PCI bridge vertex */
+    (void)hwgraph_edge_remove(xconn, EDGE_LBL_PCI, NULL);
+
+    return(0);
+}
+
+int
+pcibr_asic_rev(devfs_handle_t pconn_vhdl)
+{
+    devfs_handle_t            pcibr_vhdl;
+    arbitrary_info_t        ainfo;
+
+    if (GRAPH_SUCCESS !=
+	hwgraph_traverse(pconn_vhdl, EDGE_LBL_MASTER, &pcibr_vhdl))
+	return -1;
+
+    if (GRAPH_SUCCESS !=
+	hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &ainfo))
+	return -1;
+
+    return (int) ainfo;
+}
+
+int
+pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    pciio_slot_t  slot;
+    slot = pciio_info_slot_get(pciio_info);
+    pcibr_device_write_gather_flush(pcibr_soft, slot);
+    return 0;
+}
+
+/* =====================================================================
+ *    PIO MANAGEMENT
+ */
+
+static iopaddr_t
+pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
+		      pciio_slot_t slot,
+		      pciio_space_t space,
+		      iopaddr_t pci_addr,
+		      size_t req_size,
+		      unsigned flags)
+{
+    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
+    pciio_info_t            pciio_info = &pcibr_info->f_c;
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+
+    unsigned                bar;	/* which BASE reg on device is decoding */
+    iopaddr_t               xio_addr = XIO_NOWHERE;
+
+    pciio_space_t           wspace;	/* which space device is decoding */
+    iopaddr_t               wbase;	/* base of device decode on PCI */
+    size_t                  wsize;	/* size of device decode on PCI */
+
+    int                     try;	/* DevIO(x) window scanning order control */
+    int                     win;	/* which DevIO(x) window is being used */
+    pciio_space_t           mspace;	/* target space for devio(x) register */
+    iopaddr_t               mbase;	/* base of devio(x) mapped area on PCI */
+    size_t                  msize;	/* size of devio(x) mapped area on PCI */
+    size_t                  mmask;	/* addr bits stored in Device(x) */
+
+    unsigned long           s;
+
+    s = pcibr_lock(pcibr_soft);
+
+    if (pcibr_soft->bs_slot[slot].has_host) {
+	slot = pcibr_soft->bs_slot[slot].host_slot;
+	pcibr_info = pcibr_soft->bs_slot[slot].bss_infos[0];
+    }
+    if (space == PCIIO_SPACE_NONE)
+	goto done;
+
+    if (space == PCIIO_SPACE_CFG) {
+	/*
+	 * Usually, the first mapping
+	 * established to a PCI device
+	 * is to its config space.
+	 *
+	 * In any case, we definitely
+	 * do NOT need to worry about
+	 * PCI BASE registers, and
+	 * MUST NOT attempt to point
+	 * the DevIO(x) window at
+	 * this access ...
+	 */
+	if (((flags & PCIIO_BYTE_STREAM) == 0) &&
+	    ((pci_addr + req_size) <= BRIDGE_TYPE0_CFG_FUNC_OFF))
+	    xio_addr = pci_addr + BRIDGE_TYPE0_CFG_DEV(slot);
+
+	goto done;
+    }
+    if (space == PCIIO_SPACE_ROM) {
+	/* PIO to the Expansion Rom.
+	 * Driver is responsible for
+	 * enabling and disabling
+	 * decodes properly.
+	 */
+	wbase = pcibr_info->f_rbase;
+	wsize = pcibr_info->f_rsize;
+
+	/*
+	 * While the driver should know better
+	 * than to attempt to map more space
+	 * than the device is decoding, he might
+	 * do it; better to bail out here.
+	 */
+	if ((pci_addr + req_size) > wsize)
+	    goto done;
+
+	pci_addr += wbase;
+	space = PCIIO_SPACE_MEM;
+    }
+    /*
+     * reduce window mappings to raw
+     * space mappings (maybe allocating
+     * windows), and try for DevIO(x)
+     * usage (setting it if it is available).
+     */
+    bar = space - PCIIO_SPACE_WIN0;
+    if (bar < 6) {
+	wspace = pcibr_info->f_window[bar].w_space;
+	if (wspace == PCIIO_SPACE_NONE)
+	    goto done;
+
+	/* get PCI base and size */
+	wbase = pcibr_info->f_window[bar].w_base;
+	wsize = pcibr_info->f_window[bar].w_size;
+
+	/*
+	 * While the driver should know better
+	 * than to attempt to map more space
+	 * than the device is decoding, he might
+	 * do it; better to bail out here.
+	 */
+	if ((pci_addr + req_size) > wsize)
+	    goto done;
+
+	/* shift from window relative to
+	 * decoded space relative.
+	 */
+	pci_addr += wbase;
+	space = wspace;
+    } else
+	bar = -1;
+
+    /* Scan all the DevIO(x) windows twice looking for one
+     * that can satisfy our request. The first time through,
+     * only look at assigned windows; the second time, also
+     * look at PCIIO_SPACE_NONE windows. Arrange the order
+     * so we always look at our own window first.
+     *
+     * We will not attempt to satisfy a single request
+     * by concatinating multiple windows.
+     */
+    for (try = 0; try < 16; ++try) {
+	bridgereg_t             devreg;
+	unsigned                offset;
+
+	win = (try + slot) % 8;
+
+	/* If this DevIO(x) mapping area can provide
+	 * a mapping to this address, use it.
+	 */
+	msize = (win < 2) ? 0x200000 : 0x100000;
+	mmask = -msize;
+	if (space != PCIIO_SPACE_IO)
+	    mmask &= 0x3FFFFFFF;
+
+	offset = pci_addr & (msize - 1);
+
+	/* If this window can't possibly handle that request,
+	 * go on to the next window.
+	 */
+	if (((pci_addr & (msize - 1)) + req_size) > msize)
+	    continue;
+
+	devreg = pcibr_soft->bs_slot[win].bss_device;
+
+	/* Is this window "nailed down"?
+	 * If not, maybe we can use it.
+	 * (only check this the second time through)
+	 */
+	mspace = pcibr_soft->bs_slot[win].bss_devio.bssd_space;
+	if ((try > 7) && (mspace == PCIIO_SPACE_NONE)) {
+
+	    /* If this is the primary DevIO(x) window
+	     * for some other device, skip it.
+	     */
+	    if ((win != slot) &&
+		(PCIIO_VENDOR_ID_NONE !=
+		 pcibr_soft->bs_slot[win].bss_vendor_id))
+		continue;
+
+	    /* It's a free window, and we fit in it.
+	     * Set up Device(win) to our taste.
+	     */
+	    mbase = pci_addr & mmask;
+
+	    /* check that we would really get from
+	     * here to there.
+	     */
+	    if ((mbase | offset) != pci_addr)
+		continue;
+
+	    devreg &= ~BRIDGE_DEV_OFF_MASK;
+	    if (space != PCIIO_SPACE_IO)
+		devreg |= BRIDGE_DEV_DEV_IO_MEM;
+	    else
+		devreg &= ~BRIDGE_DEV_DEV_IO_MEM;
+	    devreg |= (mbase >> 20) & BRIDGE_DEV_OFF_MASK;
+
+	    /* default is WORD_VALUES.
+	     * if you specify both,
+	     * operation is undefined.
+	     */
+	    if (flags & PCIIO_BYTE_STREAM)
+		devreg |= BRIDGE_DEV_DEV_SWAP;
+	    else
+		devreg &= ~BRIDGE_DEV_DEV_SWAP;
+
+	    if (pcibr_soft->bs_slot[win].bss_device != devreg) {
+		bridge->b_device[win].reg = devreg;
+		pcibr_soft->bs_slot[win].bss_device = devreg;
+		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
+
+#if DEBUG && PCI_DEBUG
+		printk("pcibr Device(%d): 0x%lx\n", win, bridge->b_device[win].reg);
+#endif
+	    }
+	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
+	    pcibr_soft->bs_slot[win].bss_devio.bssd_base = mbase;
+	    xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
+
+#if DEBUG && PCI_DEBUG
+	    printk("%s LINE %d map to space %d space desc 0x%x[%lx..%lx] for slot %d allocates DevIO(%d) devreg 0x%x\n", 
+		    __FUNCTION__, __LINE__, space, space_desc,
+		    pci_addr, pci_addr + req_size - 1,
+		    slot, win, devreg);
+#endif
+
+	    goto done;
+	}				/* endif DevIO(x) not pointed */
+	mbase = pcibr_soft->bs_slot[win].bss_devio.bssd_base;
+
+	/* Now check for request incompat with DevIO(x)
+	 */
+	if ((mspace != space) ||
+	    (pci_addr < mbase) ||
+	    ((pci_addr + req_size) > (mbase + msize)) ||
+	    ((flags & PCIIO_BYTE_STREAM) && !(devreg & BRIDGE_DEV_DEV_SWAP)) ||
+	    (!(flags & PCIIO_BYTE_STREAM) && (devreg & BRIDGE_DEV_DEV_SWAP)))
+	    continue;
+
+	/* DevIO(x) window is pointed at PCI space
+	 * that includes our target. Calculate the
+	 * final XIO address, release the lock and
+	 * return.
+	 */
+	xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
+
+#if DEBUG && PCI_DEBUG
+	printk("%s LINE %d map to space %d [0x%p..0x%p] for slot %d uses DevIO(%d)\n",
+		__FUNCTION__, __LINE__, space,  pci_addr, pci_addr + req_size - 1, slot, win);
+#endif
+	goto done;
+    }
+
+    switch (space) {
+	/*
+	 * Accesses to device decode
+	 * areas that do a not fit
+	 * within the DevIO(x) space are
+	 * modified to be accesses via
+	 * the direct mapping areas.
+	 *
+	 * If necessary, drivers can
+	 * explicitly ask for mappings
+	 * into these address spaces,
+	 * but this should never be needed.
+	 */
+    case PCIIO_SPACE_MEM:		/* "mem space" */
+    case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
+	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
+	    BRIDGE_PCI_MEM32_LIMIT)
+	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
+	break;
+
+    case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
+	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
+	    BRIDGE_PCI_MEM64_LIMIT)
+	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
+	break;
+
+    case PCIIO_SPACE_IO:		/* "i/o space" */
+	/* Bridge Hardware Bug WAR #482741:
+	 * The 4G area that maps directly from
+	 * XIO space to PCI I/O space is busted
+	 * until Bridge Rev D.
+	 */
+	if ((pcibr_soft->bs_rev_num > BRIDGE_PART_REV_C) &&
+	    ((pci_addr + BRIDGE_PCI_IO_BASE + req_size - 1) <=
+	     BRIDGE_PCI_IO_LIMIT))
+	    xio_addr = pci_addr + BRIDGE_PCI_IO_BASE;
+	break;
+    }
+
+    /* Check that "Direct PIO" byteswapping matches,
+     * try to change it if it does not.
+     */
+    if (xio_addr != XIO_NOWHERE) {
+	unsigned                bst;	/* nonzero to set bytestream */
+	unsigned               *bfp;	/* addr of record of how swapper is set */
+	unsigned                swb;	/* which control bit to mung */
+	unsigned                bfo;	/* current swapper setting */
+	unsigned                bfn;	/* desired swapper setting */
+
+	bfp = ((space == PCIIO_SPACE_IO)
+	       ? (&pcibr_soft->bs_pio_end_io)
+	       : (&pcibr_soft->bs_pio_end_mem));
+
+	bfo = *bfp;
+
+	bst = flags & PCIIO_BYTE_STREAM;
+
+	bfn = bst ? PCIIO_BYTE_STREAM : PCIIO_WORD_VALUES;
+
+	if (bfn == bfo) {		/* we already match. */
+	    ;
+	} else if (bfo != 0) {		/* we have a conflict. */
+#if DEBUG && PCI_DEBUG
+	    printk("pcibr_addr_pci_to_xio: swap conflict in space %d , was%s%s, want%s%s\n",
+		    space, 
+		    bfo & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
+		    bfo & PCIIO_WORD_VALUES ? " WORD_VALUES" : "",
+		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
+		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
+#endif
+	    xio_addr = XIO_NOWHERE;
+	} else {			/* OK to make the change. */
+	    bridgereg_t             octl, nctl;
+
+	    swb = (space == PCIIO_SPACE_IO) ? BRIDGE_CTRL_IO_SWAP : BRIDGE_CTRL_MEM_SWAP;
+	    octl = bridge->b_wid_control;
+	    nctl = bst ? octl | swb : octl & ~swb;
+
+	    if (octl != nctl)		/* make the change if any */
+		bridge->b_wid_control = nctl;
+
+	    *bfp = bfn;			/* record the assignment */
+
+#if DEBUG && PCI_DEBUG
+	    printk("pcibr_addr_pci_to_xio: swap for space %d  set to%s%s\n",
+		    space, 
+		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
+		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
+#endif
+	}
+    }
+  done:
+    pcibr_unlock(pcibr_soft, s);
+    return xio_addr;
+}
+
+/*ARGSUSED6 */
+pcibr_piomap_t
+pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
+		   device_desc_t dev_desc,
+		   pciio_space_t space,
+		   iopaddr_t pci_addr,
+		   size_t req_size,
+		   size_t req_size_max,
+		   unsigned flags)
+{
+    pcibr_info_t	    pcibr_info = pcibr_info_get(pconn_vhdl);
+    pciio_info_t            pciio_info = &pcibr_info->f_c;
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+
+    pcibr_piomap_t         *mapptr;
+    pcibr_piomap_t          maplist;
+    pcibr_piomap_t          pcibr_piomap;
+    iopaddr_t               xio_addr;
+    xtalk_piomap_t          xtalk_piomap;
+    unsigned long           s;
+
+    /* Make sure that the req sizes are non-zero */
+    if ((req_size < 1) || (req_size_max < 1))
+	return NULL;
+
+    /*
+     * Code to translate slot/space/addr
+     * into xio_addr is common between
+     * this routine and pcibr_piotrans_addr.
+     */
+    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
+
+    if (xio_addr == XIO_NOWHERE)
+	return NULL;
+
+    /* Check the piomap list to see if there is already an allocated
+     * piomap entry but not in use. If so use that one. Otherwise
+     * allocate a new piomap entry and add it to the piomap list
+     */
+    mapptr = &(pcibr_info->f_piomap);
+
+    s = pcibr_lock(pcibr_soft);
+    for (pcibr_piomap = *mapptr;
+	 pcibr_piomap != NULL;
+	 pcibr_piomap = pcibr_piomap->bp_next) {
+	if (pcibr_piomap->bp_mapsz == 0)
+	    break;
+    }
+
+    if (pcibr_piomap)
+	mapptr = NULL;
+    else {
+	pcibr_unlock(pcibr_soft, s);
+	NEW(pcibr_piomap);
+    }
+
+    pcibr_piomap->bp_dev = pconn_vhdl;
+    pcibr_piomap->bp_slot = pciio_slot;
+    pcibr_piomap->bp_flags = flags;
+    pcibr_piomap->bp_space = space;
+    pcibr_piomap->bp_pciaddr = pci_addr;
+    pcibr_piomap->bp_mapsz = req_size;
+    pcibr_piomap->bp_soft = pcibr_soft;
+    pcibr_piomap->bp_toc[0] = ATOMIC_INIT(0);
+
+    if (mapptr) {
+	s = pcibr_lock(pcibr_soft);
+	maplist = *mapptr;
+	pcibr_piomap->bp_next = maplist;
+	*mapptr = pcibr_piomap;
+    }
+    pcibr_unlock(pcibr_soft, s);
+
+
+    if (pcibr_piomap) {
+	xtalk_piomap =
+	    xtalk_piomap_alloc(xconn_vhdl, 0,
+			       xio_addr,
+			       req_size, req_size_max,
+			       flags & PIOMAP_FLAGS);
+	if (xtalk_piomap) {
+	    pcibr_piomap->bp_xtalk_addr = xio_addr;
+	    pcibr_piomap->bp_xtalk_pio = xtalk_piomap;
+	} else {
+	    pcibr_piomap->bp_mapsz = 0;
+	    pcibr_piomap = 0;
+	}
+    }
+    return pcibr_piomap;
+}
+
+/*ARGSUSED */
+void
+pcibr_piomap_free(pcibr_piomap_t pcibr_piomap)
+{
+    xtalk_piomap_free(pcibr_piomap->bp_xtalk_pio);
+    pcibr_piomap->bp_xtalk_pio = 0;
+    pcibr_piomap->bp_mapsz = 0;
+}
+
+/*ARGSUSED */
+caddr_t
+pcibr_piomap_addr(pcibr_piomap_t pcibr_piomap,
+		  iopaddr_t pci_addr,
+		  size_t req_size)
+{
+    return xtalk_piomap_addr(pcibr_piomap->bp_xtalk_pio,
+			     pcibr_piomap->bp_xtalk_addr +
+			     pci_addr - pcibr_piomap->bp_pciaddr,
+			     req_size);
+}
+
+/*ARGSUSED */
+void
+pcibr_piomap_done(pcibr_piomap_t pcibr_piomap)
+{
+    xtalk_piomap_done(pcibr_piomap->bp_xtalk_pio);
+}
+
+/*ARGSUSED */
+caddr_t
+pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
+		    device_desc_t dev_desc,
+		    pciio_space_t space,
+		    iopaddr_t pci_addr,
+		    size_t req_size,
+		    unsigned flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+
+    iopaddr_t               xio_addr;
+
+    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
+
+    if (xio_addr == XIO_NOWHERE)
+	return NULL;
+
+    return xtalk_piotrans_addr(xconn_vhdl, 0, xio_addr, req_size, flags & PIOMAP_FLAGS);
+}
+
+/*
+ * PIO Space allocation and management.
+ *      Allocate and Manage the PCI PIO space (mem and io space)
+ *      This routine is pretty simplistic at this time, and
+ *      does pretty trivial management of allocation and freeing..
+ *      The current scheme is prone for fragmentation..
+ *      Change the scheme to use bitmaps.
+ */
+
+/*ARGSUSED */
+iopaddr_t
+pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
+		     device_desc_t dev_desc,
+		     pciio_space_t space,
+		     size_t req_size,
+		     size_t alignment)
+{
+    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
+    pciio_info_t            pciio_info = &pcibr_info->f_c;
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+    pciio_piospace_t        piosp;
+    unsigned long           s;
+
+    iopaddr_t              *pciaddr, *pcilast;
+    iopaddr_t               start_addr;
+    size_t                  align_mask;
+
+    /*
+     * Check for proper alignment
+     */
+    ASSERT(alignment >= NBPP);
+    ASSERT((alignment & (alignment - 1)) == 0);
+
+    align_mask = alignment - 1;
+    s = pcibr_lock(pcibr_soft);
+
+    /*
+     * First look if a previously allocated chunk exists.
+     */
+    if ((piosp = pcibr_info->f_piospace)) {
+	/*
+	 * Look through the list for a right sized free chunk.
+	 */
+	do {
+	    if (piosp->free &&
+		(piosp->space == space) &&
+		(piosp->count >= req_size) &&
+		!(piosp->start & align_mask)) {
+		piosp->free = 0;
+		pcibr_unlock(pcibr_soft, s);
+		return piosp->start;
+	    }
+	    piosp = piosp->next;
+	} while (piosp);
+    }
+    ASSERT(!piosp);
+
+    switch (space) {
+    case PCIIO_SPACE_IO:
+	pciaddr = &pcibr_soft->bs_spinfo.pci_io_base;
+	pcilast = &pcibr_soft->bs_spinfo.pci_io_last;
+	break;
+    case PCIIO_SPACE_MEM:
+    case PCIIO_SPACE_MEM32:
+	pciaddr = &pcibr_soft->bs_spinfo.pci_mem_base;
+	pcilast = &pcibr_soft->bs_spinfo.pci_mem_last;
+	break;
+    default:
+	ASSERT(0);
+	pcibr_unlock(pcibr_soft, s);
+	return 0;
+    }
+
+    start_addr = *pciaddr;
+
+    /*
+     * Align start_addr.
+     */
+    if (start_addr & align_mask)
+	start_addr = (start_addr + align_mask) & ~align_mask;
+
+    if ((start_addr + req_size) > *pcilast) {
+	/*
+	 * If too big a request, reject it.
+	 */
+	pcibr_unlock(pcibr_soft, s);
+	return 0;
+    }
+    *pciaddr = (start_addr + req_size);
+
+    NEW(piosp);
+    piosp->free = 0;
+    piosp->space = space;
+    piosp->start = start_addr;
+    piosp->count = req_size;
+    piosp->next = pcibr_info->f_piospace;
+    pcibr_info->f_piospace = piosp;
+
+    pcibr_unlock(pcibr_soft, s);
+    return start_addr;
+}
+
+/*ARGSUSED */
+void
+pcibr_piospace_free(devfs_handle_t pconn_vhdl,
+		    pciio_space_t space,
+		    iopaddr_t pciaddr,
+		    size_t req_size)
+{
+    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
+
+    pciio_piospace_t        piosp;
+    unsigned long           s;
+    char                    name[1024];
+
+    /*
+     * Look through the bridge data structures for the pciio_piospace_t
+     * structure corresponding to  'pciaddr'
+     */
+    s = pcibr_lock(pcibr_soft);
+    piosp = pcibr_info->f_piospace;
+    while (piosp) {
+	/*
+	 * Piospace free can only be for the complete
+	 * chunk and not parts of it..
+	 */
+	if (piosp->start == pciaddr) {
+	    if (piosp->count == req_size)
+		break;
+	    /*
+	     * Improper size passed for freeing..
+	     * Print a message and break;
+	     */
+	    hwgraph_vertex_name_get(pconn_vhdl, name, 1024);
+	    printk(KERN_WARNING  "pcibr_piospace_free: error");
+	    printk(KERN_WARNING  "Device %s freeing size (0x%lx) different than allocated (0x%lx)",
+					name, req_size, piosp->count);
+	    printk(KERN_WARNING  "Freeing 0x%lx instead", piosp->count);
+	    break;
+	}
+	piosp = piosp->next;
+    }
+
+    if (!piosp) {
+	printk(KERN_WARNING  
+		"pcibr_piospace_free: Address 0x%lx size 0x%lx - No match\n",
+		pciaddr, req_size);
+	pcibr_unlock(pcibr_soft, s);
+	return;
+    }
+    piosp->free = 1;
+    pcibr_unlock(pcibr_soft, s);
+    return;
+}
+
+/* =====================================================================
+ *    DMA MANAGEMENT
+ *
+ *      The Bridge ASIC provides three methods of doing
+ *      DMA: via a "direct map" register available in
+ *      32-bit PCI space (which selects a contiguous 2G
+ *      address space on some other widget), via
+ *      "direct" addressing via 64-bit PCI space (all
+ *      destination information comes from the PCI
+ *      address, including transfer attributes), and via
+ *      a "mapped" region that allows a bunch of
+ *      different small mappings to be established with
+ *      the PMU.
+ *
+ *      For efficiency, we most prefer to use the 32-bit
+ *      direct mapping facility, since it requires no
+ *      resource allocations. The advantage of using the
+ *      PMU over the 64-bit direct is that single-cycle
+ *      PCI addressing can be used; the advantage of
+ *      using 64-bit direct over PMU addressing is that
+ *      we do not have to allocate entries in the PMU.
+ */
+
+/*
+ * Convert PCI-generic software flags and Bridge-specific software flags
+ * into Bridge-specific Direct Map attribute bits.
+ */
+static iopaddr_t
+pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft)
+{
+    iopaddr_t               attributes = 0;
+
+    /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */
+#ifdef LATER
+    ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64));
+#endif
+
+    /* Generic macro flags
+     */
+    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
+	attributes &= ~PCI64_ATTR_BAR;	/* no barrier bit */
+	attributes |= PCI64_ATTR_PREF;	/* prefetch on */
+    }
+    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
+	attributes |= PCI64_ATTR_BAR;	/* barrier bit on */
+	attributes &= ~PCI64_ATTR_PREF;	/* disable prefetch */
+    }
+    /* Generic detail flags
+     */
+    if (flags & PCIIO_PREFETCH)
+	attributes |= PCI64_ATTR_PREF;
+    if (flags & PCIIO_NOPREFETCH)
+	attributes &= ~PCI64_ATTR_PREF;
+
+    /* the swap bit is in the address attributes for xbridge */
+    if (pcibr_soft->bs_xbridge) {
+    	if (flags & PCIIO_BYTE_STREAM)
+        	attributes |= PCI64_ATTR_SWAP;
+    	if (flags & PCIIO_WORD_VALUES)
+        	attributes &= ~PCI64_ATTR_SWAP;
+    }
+
+    /* Provider-specific flags
+     */
+    if (flags & PCIBR_BARRIER)
+	attributes |= PCI64_ATTR_BAR;
+    if (flags & PCIBR_NOBARRIER)
+	attributes &= ~PCI64_ATTR_BAR;
+
+    if (flags & PCIBR_PREFETCH)
+	attributes |= PCI64_ATTR_PREF;
+    if (flags & PCIBR_NOPREFETCH)
+	attributes &= ~PCI64_ATTR_PREF;
+
+    if (flags & PCIBR_PRECISE)
+	attributes |= PCI64_ATTR_PREC;
+    if (flags & PCIBR_NOPRECISE)
+	attributes &= ~PCI64_ATTR_PREC;
+
+    if (flags & PCIBR_VCHAN1)
+	attributes |= PCI64_ATTR_VIRTUAL;
+    if (flags & PCIBR_VCHAN0)
+	attributes &= ~PCI64_ATTR_VIRTUAL;
+
+    return (attributes);
+}
+
+/*ARGSUSED */
+pcibr_dmamap_t
+pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
+		   device_desc_t dev_desc,
+		   size_t req_size_max,
+		   unsigned flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    pciio_slot_t            slot;
+    xwidgetnum_t            xio_port;
+
+    xtalk_dmamap_t          xtalk_dmamap;
+    pcibr_dmamap_t          pcibr_dmamap;
+    int                     ate_count;
+    int                     ate_index;
+
+    /* merge in forced flags */
+    flags |= pcibr_soft->bs_dma_flags;
+
+    /*
+     * On SNIA64, these maps are pre-allocated because pcibr_dmamap_alloc()
+     * can be called within an interrupt thread.
+     */
+    pcibr_dmamap = (pcibr_dmamap_t)get_free_pciio_dmamap(pcibr_soft->bs_vhdl);
+
+    if (!pcibr_dmamap)
+	return 0;
+
+    xtalk_dmamap = xtalk_dmamap_alloc(xconn_vhdl, dev_desc, req_size_max,
+				      flags & DMAMAP_FLAGS);
+    if (!xtalk_dmamap) {
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_attach: xtalk_dmamap_alloc failed\n");
+#endif
+	free_pciio_dmamap(pcibr_dmamap);
+	return 0;
+    }
+    xio_port = pcibr_soft->bs_mxid;
+    slot = pciio_info_slot_get(pciio_info);
+
+    pcibr_dmamap->bd_dev = pconn_vhdl;
+    pcibr_dmamap->bd_slot = slot;
+    pcibr_dmamap->bd_soft = pcibr_soft;
+    pcibr_dmamap->bd_xtalk = xtalk_dmamap;
+    pcibr_dmamap->bd_max_size = req_size_max;
+    pcibr_dmamap->bd_xio_port = xio_port;
+
+    if (flags & PCIIO_DMA_A64) {
+	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D64_BITS)) {
+	    iopaddr_t               pci_addr;
+	    int                     have_rrbs;
+	    int                     min_rrbs;
+
+	    /* Device is capable of A64 operations,
+	     * and the attributes of the DMA are
+	     * consistant with any previous DMA
+	     * mappings using shared resources.
+	     */
+
+	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
+
+	    pcibr_dmamap->bd_flags = flags;
+	    pcibr_dmamap->bd_xio_addr = 0;
+	    pcibr_dmamap->bd_pci_addr = pci_addr;
+
+	    /* Make sure we have an RRB (or two).
+	     */
+	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
+		if (flags & PCIBR_VCHAN1)
+		    slot += PCIBR_RRB_SLOT_VIRTUAL;
+		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
+		if (have_rrbs < 2) {
+		    if (pci_addr & PCI64_ATTR_PREF)
+			min_rrbs = 2;
+		    else
+			min_rrbs = 1;
+		    if (have_rrbs < min_rrbs)
+			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
+		}
+	    }
+#if PCIBR_ATE_DEBUG
+	    printk("pcibr_dmamap_alloc: using direct64\n");
+#endif
+	    return pcibr_dmamap;
+	}
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_dmamap_alloc: unable to use direct64\n");
+#endif
+	flags &= ~PCIIO_DMA_A64;
+    }
+    if (flags & PCIIO_FIXED) {
+	/* warning: mappings may fail later,
+	 * if direct32 can't get to the address.
+	 */
+	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
+	    /* User desires DIRECT A32 operations,
+	     * and the attributes of the DMA are
+	     * consistant with any previous DMA
+	     * mappings using shared resources.
+	     * Mapping calls may fail if target
+	     * is outside the direct32 range.
+	     */
+#if PCIBR_ATE_DEBUG
+	    printk("pcibr_dmamap_alloc: using direct32\n");
+#endif
+	    pcibr_dmamap->bd_flags = flags;
+	    pcibr_dmamap->bd_xio_addr = pcibr_soft->bs_dir_xbase;
+	    pcibr_dmamap->bd_pci_addr = PCI32_DIRECT_BASE;
+	    return pcibr_dmamap;
+	}
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_dmamap_alloc: unable to use direct32\n");
+#endif
+	/* If the user demands FIXED and we can't
+	 * give it to him, fail.
+	 */
+	xtalk_dmamap_free(xtalk_dmamap);
+	free_pciio_dmamap(pcibr_dmamap);
+	return 0;
+    }
+    /*
+     * Allocate Address Translation Entries from the mapping RAM.
+     * Unless the PCIBR_NO_ATE_ROUNDUP flag is specified,
+     * the maximum number of ATEs is based on the worst-case
+     * scenario, where the requested target is in the
+     * last byte of an ATE; thus, mapping IOPGSIZE+2
+     * does end up requiring three ATEs.
+     */
+    if (!(flags & PCIBR_NO_ATE_ROUNDUP)) {
+	ate_count = IOPG((IOPGSIZE - 1)	/* worst case start offset */
+		     +req_size_max	/* max mapping bytes */
+		     - 1) + 1;		/* round UP */
+    } else {	/* assume requested target is page aligned */
+	ate_count = IOPG(req_size_max   /* max mapping bytes */
+		     - 1) + 1;		/* round UP */
+    }
+
+    ate_index = pcibr_ate_alloc(pcibr_soft, ate_count);
+
+    if (ate_index != -1) {
+	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_PMU_BITS)) {
+	    bridge_ate_t            ate_proto;
+	    int                     have_rrbs;
+	    int                     min_rrbs;
+
+#if PCIBR_ATE_DEBUG
+	    printk("pcibr_dmamap_alloc: using PMU\n");
+#endif
+
+	    ate_proto = pcibr_flags_to_ate(flags);
+
+	    pcibr_dmamap->bd_flags = flags;
+	    pcibr_dmamap->bd_pci_addr =
+		PCI32_MAPPED_BASE + IOPGSIZE * ate_index;
+	    /*
+	     * for xbridge the byte-swap bit == bit 29 of PCI address
+	     */
+	    if (pcibr_soft->bs_xbridge) {
+		    if (flags & PCIIO_BYTE_STREAM)
+			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
+		    /*
+		     * If swap was set in bss_device in pcibr_endian_set()
+		     * we need to change the address bit.
+		     */
+		    if (pcibr_soft->bs_slot[slot].bss_device & 
+							BRIDGE_DEV_SWAP_PMU)
+			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
+		    if (flags & PCIIO_WORD_VALUES)
+			    ATE_SWAP_OFF(pcibr_dmamap->bd_pci_addr);
+	    }
+	    pcibr_dmamap->bd_xio_addr = 0;
+	    pcibr_dmamap->bd_ate_ptr = pcibr_ate_addr(pcibr_soft, ate_index);
+	    pcibr_dmamap->bd_ate_index = ate_index;
+	    pcibr_dmamap->bd_ate_count = ate_count;
+	    pcibr_dmamap->bd_ate_proto = ate_proto;
+
+	    /* Make sure we have an RRB (or two).
+	     */
+	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
+		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
+		if (have_rrbs < 2) {
+		    if (ate_proto & ATE_PREF)
+			min_rrbs = 2;
+		    else
+			min_rrbs = 1;
+		    if (have_rrbs < min_rrbs)
+			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
+		}
+	    }
+	    if (ate_index >= pcibr_soft->bs_int_ate_size && 
+				!pcibr_soft->bs_xbridge) {
+		bridge_t               *bridge = pcibr_soft->bs_base;
+		volatile unsigned      *cmd_regp;
+		unsigned                cmd_reg;
+		unsigned long           s;
+
+		pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM;
+
+		s = pcibr_lock(pcibr_soft);
+		cmd_regp = &(bridge->
+			     b_type0_cfg_dev[slot].
+			     l[PCI_CFG_COMMAND / 4]);
+		cmd_reg = *cmd_regp;
+		pcibr_soft->bs_slot[slot].bss_cmd_pointer = cmd_regp;
+		pcibr_soft->bs_slot[slot].bss_cmd_shadow = cmd_reg;
+		pcibr_unlock(pcibr_soft, s);
+	    }
+	    return pcibr_dmamap;
+	}
+#if PCIBR_ATE_DEBUG
+	printk("pcibr_dmamap_alloc: unable to use PMU\n");
+#endif
+	pcibr_ate_free(pcibr_soft, ate_index, ate_count);
+    }
+    /* total failure: sorry, you just can't
+     * get from here to there that way.
+     */
+#if PCIBR_ATE_DEBUG
+    printk("pcibr_dmamap_alloc: complete failure.\n");
+#endif
+    xtalk_dmamap_free(xtalk_dmamap);
+    free_pciio_dmamap(pcibr_dmamap);
+    return 0;
+}
+
+/*ARGSUSED */
+void
+pcibr_dmamap_free(pcibr_dmamap_t pcibr_dmamap)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
+    pciio_slot_t            slot = pcibr_dmamap->bd_slot;
+
+    unsigned                flags = pcibr_dmamap->bd_flags;
+
+    /* Make sure that bss_ext_ates_active
+     * is properly kept up to date.
+     */
+
+    if (PCIBR_DMAMAP_BUSY & flags)
+	if (PCIBR_DMAMAP_SSRAM & flags)
+	    atomic_dec(&(pcibr_soft->bs_slot[slot]. bss_ext_ates_active));
+
+    xtalk_dmamap_free(pcibr_dmamap->bd_xtalk);
+
+    if (pcibr_dmamap->bd_flags & PCIIO_DMA_A64) {
+	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_D64_BITS);
+    }
+    if (pcibr_dmamap->bd_ate_count) {
+	pcibr_ate_free(pcibr_dmamap->bd_soft,
+		       pcibr_dmamap->bd_ate_index,
+		       pcibr_dmamap->bd_ate_count);
+	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS);
+    }
+
+    free_pciio_dmamap(pcibr_dmamap);
+}
+
+/*
+ *    pcibr_addr_xio_to_pci: given a PIO range, hand
+ *      back the corresponding base PCI MEM address;
+ *      this is used to short-circuit DMA requests that
+ *      loop back onto this PCI bus.
+ */
+static iopaddr_t
+pcibr_addr_xio_to_pci(pcibr_soft_t soft,
+		      iopaddr_t xio_addr,
+		      size_t req_size)
+{
+    iopaddr_t               xio_lim = xio_addr + req_size - 1;
+    iopaddr_t               pci_addr;
+    pciio_slot_t            slot;
+
+    if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
+	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
+	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
+	return pci_addr;
+    }
+    if ((xio_addr >= BRIDGE_PCI_MEM64_BASE) &&
+	(xio_lim <= BRIDGE_PCI_MEM64_LIMIT)) {
+	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
+	return pci_addr;
+    }
+    for (slot = 0; slot < 8; ++slot)
+	if ((xio_addr >= BRIDGE_DEVIO(slot)) &&
+	    (xio_lim < BRIDGE_DEVIO(slot + 1))) {
+	    bridgereg_t             dev;
+
+	    dev = soft->bs_slot[slot].bss_device;
+	    pci_addr = dev & BRIDGE_DEV_OFF_MASK;
+	    pci_addr <<= BRIDGE_DEV_OFF_ADDR_SHFT;
+	    pci_addr += xio_addr - BRIDGE_DEVIO(slot);
+	    return (dev & BRIDGE_DEV_DEV_IO_MEM) ? pci_addr : PCI_NOWHERE;
+	}
+    return 0;
+}
+
+/*ARGSUSED */
+iopaddr_t
+pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap,
+		  paddr_t paddr,
+		  size_t req_size)
+{
+    pcibr_soft_t            pcibr_soft;
+    iopaddr_t               xio_addr;
+    xwidgetnum_t            xio_port;
+    iopaddr_t               pci_addr;
+    unsigned                flags;
+
+    ASSERT(pcibr_dmamap != NULL);
+    ASSERT(req_size > 0);
+    ASSERT(req_size <= pcibr_dmamap->bd_max_size);
+
+    pcibr_soft = pcibr_dmamap->bd_soft;
+
+    flags = pcibr_dmamap->bd_flags;
+
+    xio_addr = xtalk_dmamap_addr(pcibr_dmamap->bd_xtalk, paddr, req_size);
+    if (XIO_PACKED(xio_addr)) {
+	xio_port = XIO_PORT(xio_addr);
+	xio_addr = XIO_ADDR(xio_addr);
+    } else
+	xio_port = pcibr_dmamap->bd_xio_port;
+
+    /* If this DMA is to an address that
+     * refers back to this Bridge chip,
+     * reduce it back to the correct
+     * PCI MEM address.
+     */
+    if (xio_port == pcibr_soft->bs_xid) {
+	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
+    } else if (flags & PCIIO_DMA_A64) {
+	/* A64 DMA:
+	 * always use 64-bit direct mapping,
+	 * which always works.
+	 * Device(x) was set up during
+	 * dmamap allocation.
+	 */
+
+	/* attributes are already bundled up into bd_pci_addr.
+	 */
+	pci_addr = pcibr_dmamap->bd_pci_addr
+	    | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT)
+	    | xio_addr;
+
+	/* Bridge Hardware WAR #482836:
+	 * If the transfer is not cache aligned
+	 * and the Bridge Rev is <= B, force
+	 * prefetch to be off.
+	 */
+	if (flags & PCIBR_NOPREFETCH)
+	    pci_addr &= ~PCI64_ATTR_PREF;
+
+#if DEBUG && PCIBR_DMA_DEBUG
+	printk("pcibr_dmamap_addr (direct64):\n"
+		"\twanted paddr [0x%x..0x%x]\n"
+		"\tXIO port 0x%x offset 0x%x\n"
+		"\treturning PCI 0x%x\n",
+		paddr, paddr + req_size - 1,
+		xio_port, xio_addr, pci_addr);
+#endif
+    } else if (flags & PCIIO_FIXED) {
+	/* A32 direct DMA:
+	 * always use 32-bit direct mapping,
+	 * which may fail.
+	 * Device(x) was set up during
+	 * dmamap allocation.
+	 */
+
+	if (xio_port != pcibr_soft->bs_dir_xport)
+	    pci_addr = 0;		/* wrong DIDN */
+	else if (xio_addr < pcibr_dmamap->bd_xio_addr)
+	    pci_addr = 0;		/* out of range */
+	else if ((xio_addr + req_size) >
+		 (pcibr_dmamap->bd_xio_addr + BRIDGE_DMA_DIRECT_SIZE))
+	    pci_addr = 0;		/* out of range */
+	else
+	    pci_addr = pcibr_dmamap->bd_pci_addr +
+		xio_addr - pcibr_dmamap->bd_xio_addr;
+
+#if DEBUG && PCIBR_DMA_DEBUG
+	printk("pcibr_dmamap_addr (direct32):\n"
+		"\twanted paddr [0x%x..0x%x]\n"
+		"\tXIO port 0x%x offset 0x%x\n"
+		"\treturning PCI 0x%x\n",
+		paddr, paddr + req_size - 1,
+		xio_port, xio_addr, pci_addr);
+#endif
+    } else {
+	bridge_t               *bridge = pcibr_soft->bs_base;
+	iopaddr_t               offset = IOPGOFF(xio_addr);
+	bridge_ate_t            ate_proto = pcibr_dmamap->bd_ate_proto;
+	int                     ate_count = IOPG(offset + req_size - 1) + 1;
+
+	int                     ate_index = pcibr_dmamap->bd_ate_index;
+	unsigned                cmd_regs[8];
+	unsigned                s;
+
+#if PCIBR_FREEZE_TIME
+	int                     ate_total = ate_count;
+	unsigned                freeze_time;
+#endif
+
+#if PCIBR_ATE_DEBUG
+	bridge_ate_t            ate_cmp;
+	bridge_ate_p            ate_cptr;
+	unsigned                ate_lo, ate_hi;
+	int                     ate_bad = 0;
+	int                     ate_rbc = 0;
+#endif
+	bridge_ate_p            ate_ptr = pcibr_dmamap->bd_ate_ptr;
+	bridge_ate_t            ate;
+
+	/* Bridge Hardware WAR #482836:
+	 * If the transfer is not cache aligned
+	 * and the Bridge Rev is <= B, force
+	 * prefetch to be off.
+	 */
+	if (flags & PCIBR_NOPREFETCH)
+	    ate_proto &= ~ATE_PREF;
+
+	ate = ate_proto
+	    | (xio_port << ATE_TIDSHIFT)
+	    | (xio_addr - offset);
+
+	pci_addr = pcibr_dmamap->bd_pci_addr + offset;
+
+	/* Fill in our mapping registers
+	 * with the appropriate xtalk data,
+	 * and hand back the PCI address.
+	 */
+
+	ASSERT(ate_count > 0);
+	if (ate_count <= pcibr_dmamap->bd_ate_count) {
+		ATE_FREEZE();
+		ATE_WRITE();
+		ATE_THAW();
+		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
+	} else {
+		/* The number of ATE's required is greater than the number
+		 * allocated for this map. One way this can happen is if
+		 * pcibr_dmamap_alloc() was called with the PCIBR_NO_ATE_ROUNDUP
+		 * flag, and then when that map is used (right now), the
+		 * target address tells us we really did need to roundup.
+		 * The other possibility is that the map is just plain too
+		 * small to handle the requested target area.
+		 */
+#if PCIBR_ATE_DEBUG
+		printk(KERN_WARNING "pcibr_dmamap_addr :\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\tate_count 0x%x bd_ate_count 0x%x\n"
+			"\tATE's required > number allocated\n",
+			paddr, paddr + req_size - 1,
+			ate_count, pcibr_dmamap->bd_ate_count);
+#endif
+		pci_addr = 0;
+	}
+
+    }
+    return pci_addr;
+}
+
+/*ARGSUSED */
+alenlist_t
+pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
+		  alenlist_t palenlist,
+		  unsigned flags)
+{
+    pcibr_soft_t            pcibr_soft;
+    bridge_t               *bridge=NULL;
+
+    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
+    int                     inplace = flags & PCIIO_INPLACE;
+
+    alenlist_t              pciio_alenlist = 0;
+    alenlist_t              xtalk_alenlist;
+    size_t                  length;
+    iopaddr_t               offset;
+    unsigned                direct64;
+    int                     ate_index = 0;
+    int                     ate_count = 0;
+    int                     ate_total = 0;
+    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
+    bridge_ate_t            ate_proto = (bridge_ate_t)0;
+    bridge_ate_t            ate_prev;
+    bridge_ate_t            ate;
+    alenaddr_t              xio_addr;
+    xwidgetnum_t            xio_port;
+    iopaddr_t               pci_addr;
+    alenaddr_t              new_addr;
+    unsigned                cmd_regs[8];
+    unsigned                s = 0;
+
+#if PCIBR_FREEZE_TIME
+    unsigned                freeze_time;
+#endif
+    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
+							 * with an ATE_FREEZE
+							 */
+
+    pcibr_soft = pcibr_dmamap->bd_soft;
+
+    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
+				       flags & DMAMAP_FLAGS);
+    if (!xtalk_alenlist)
+	goto fail;
+
+    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
+
+    if (inplace) {
+	pciio_alenlist = xtalk_alenlist;
+    } else {
+	pciio_alenlist = alenlist_create(al_flags);
+	if (!pciio_alenlist)
+	    goto fail;
+    }
+
+    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
+    if (!direct64) {
+	bridge = pcibr_soft->bs_base;
+	ate_ptr = pcibr_dmamap->bd_ate_ptr;
+	ate_index = pcibr_dmamap->bd_ate_index;
+	ate_proto = pcibr_dmamap->bd_ate_proto;
+	ATE_FREEZE();
+	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
+    }
+    pci_addr = pcibr_dmamap->bd_pci_addr;
+
+    ate_prev = 0;			/* matches no valid ATEs */
+    while (ALENLIST_SUCCESS ==
+	   alenlist_get(xtalk_alenlist, NULL, 0,
+			&xio_addr, &length, al_flags)) {
+	if (XIO_PACKED(xio_addr)) {
+	    xio_port = XIO_PORT(xio_addr);
+	    xio_addr = XIO_ADDR(xio_addr);
+	} else
+	    xio_port = pcibr_dmamap->bd_xio_port;
+
+	if (xio_port == pcibr_soft->bs_xid) {
+	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
+	    if (new_addr == PCI_NOWHERE)
+		goto fail;
+	} else if (direct64) {
+	    new_addr = pci_addr | xio_addr
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+
+	    /* Bridge Hardware WAR #482836:
+	     * If the transfer is not cache aligned
+	     * and the Bridge Rev is <= B, force
+	     * prefetch to be off.
+	     */
+	    if (flags & PCIBR_NOPREFETCH)
+		new_addr &= ~PCI64_ATTR_PREF;
+
+	} else {
+	    /* calculate the ate value for
+	     * the first address. If it
+	     * matches the previous
+	     * ATE written (ie. we had
+	     * multiple blocks in the
+	     * same IOPG), then back up
+	     * and reuse that ATE.
+	     *
+	     * We are NOT going to
+	     * aggressively try to
+	     * reuse any other ATEs.
+	     */
+	    offset = IOPGOFF(xio_addr);
+	    ate = ate_proto
+		| (xio_port << ATE_TIDSHIFT)
+		| (xio_addr - offset);
+	    if (ate == ate_prev) {
+#if PCIBR_ATE_DEBUG
+		printk("pcibr_dmamap_list: ATE share\n");
+#endif
+		ate_ptr--;
+		ate_index--;
+		pci_addr -= IOPGSIZE;
+	    }
+	    new_addr = pci_addr + offset;
+
+	    /* Fill in the hardware ATEs
+	     * that contain this block.
+	     */
+	    ate_count = IOPG(offset + length - 1) + 1;
+	    ate_total += ate_count;
+
+	    /* Ensure that this map contains enough ATE's */
+	    if (ate_total > pcibr_dmamap->bd_ate_count) {
+#if PCIBR_ATE_DEBUG
+		printk(KERN_WARNING "pcibr_dmamap_list :\n"
+			"\twanted xio_addr [0x%x..0x%x]\n"
+			"\tate_total 0x%x bd_ate_count 0x%x\n"
+			"\tATE's required > number allocated\n",
+			xio_addr, xio_addr + length - 1,
+			ate_total, pcibr_dmamap->bd_ate_count);
+#endif
+		goto fail;
+	    }
+
+	    ATE_WRITE();
+
+	    ate_index += ate_count;
+	    ate_ptr += ate_count;
+
+	    ate_count <<= IOPFNSHIFT;
+	    ate += ate_count;
+	    pci_addr += ate_count;
+	}
+
+	/* write the PCI DMA address
+	 * out to the scatter-gather list.
+	 */
+	if (inplace) {
+	    if (ALENLIST_SUCCESS !=
+		alenlist_replace(pciio_alenlist, NULL,
+				 &new_addr, &length, al_flags))
+		goto fail;
+	} else {
+	    if (ALENLIST_SUCCESS !=
+		alenlist_append(pciio_alenlist,
+				new_addr, length, al_flags))
+		goto fail;
+	}
+    }
+    if (!inplace)
+	alenlist_done(xtalk_alenlist);
+
+    /* Reset the internal cursor of the alenlist to be returned back
+     * to the caller.
+     */
+    alenlist_cursor_init(pciio_alenlist, 0, NULL);
+
+
+    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
+     * changes that ATE_FREEZE has done to implement the external SSRAM
+     * bug workaround.
+     */
+    if (ate_freeze_done) {
+	ATE_THAW();
+	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    }
+    return pciio_alenlist;
+
+  fail:
+    /* There are various points of failure after doing an ATE_FREEZE
+     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
+     * The decision to do an ATE_THAW needs to be based on whether a
+     * an ATE_FREEZE was done before.
+     */
+    if (ate_freeze_done) {
+	ATE_THAW();
+	bridge->b_wid_tflush;
+    }
+    if (pciio_alenlist && !inplace)
+	alenlist_destroy(pciio_alenlist);
+    return 0;
+}
+
+/*ARGSUSED */
+void
+pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
+{
+    /*
+     * We could go through and invalidate ATEs here;
+     * for performance reasons, we don't.
+     * We also don't enforce the strict alternation
+     * between _addr/_list and _done, but Hub does.
+     */
+
+    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
+	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
+
+	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
+	    atomic_dec(&(pcibr_dmamap->bd_soft->bs_slot[pcibr_dmamap->bd_slot]. bss_ext_ates_active));
+    }
+    xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
+}
+
+
+/*
+ * For each bridge, the DIR_OFF value in the Direct Mapping Register
+ * determines the PCI to Crosstalk memory mapping to be used for all
+ * 32-bit Direct Mapping memory accesses. This mapping can be to any
+ * node in the system. This function will return that compact node id.
+ */
+
+/*ARGSUSED */
+cnodeid_t
+pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
+{
+
+	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
+	pcibr_soft_t	pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+	return(NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase)));
+}
+
+/*ARGSUSED */
+iopaddr_t
+pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
+		    device_desc_t dev_desc,
+		    paddr_t paddr,
+		    size_t req_size,
+		    unsigned flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
+
+    xwidgetnum_t            xio_port;
+    iopaddr_t               xio_addr;
+    iopaddr_t               pci_addr;
+
+    int                     have_rrbs;
+    int                     min_rrbs;
+
+    /* merge in forced flags */
+    flags |= pcibr_soft->bs_dma_flags;
+
+    xio_addr = xtalk_dmatrans_addr(xconn_vhdl, 0, paddr, req_size,
+				   flags & DMAMAP_FLAGS);
+    if (!xio_addr) {
+#if PCIBR_DMA_DEBUG
+	printk("pcibr_dmatrans_addr:\n"
+		"\tpciio connection point %v\n"
+		"\txtalk connection point %v\n"
+		"\twanted paddr [0x%x..0x%x]\n"
+		"\txtalk_dmatrans_addr returned 0x%x\n",
+		pconn_vhdl, xconn_vhdl,
+		paddr, paddr + req_size - 1,
+		xio_addr);
+#endif
+	return 0;
+    }
+    /*
+     * find which XIO port this goes to.
+     */
+    if (XIO_PACKED(xio_addr)) {
+	if (xio_addr == XIO_NOWHERE) {
+#if PCIBR_DMA_DEBUG
+	    printk("pcibr_dmatrans_addr:\n"
+		    "\tpciio connection point %v\n"
+		    "\txtalk connection point %v\n"
+		    "\twanted paddr [0x%x..0x%x]\n"
+		    "\txtalk_dmatrans_addr returned 0x%x\n",
+		    pconn_vhdl, xconn_vhdl,
+		    paddr, paddr + req_size - 1,
+		    xio_addr);
+#endif
+	    return 0;
+	}
+	xio_port = XIO_PORT(xio_addr);
+	xio_addr = XIO_ADDR(xio_addr);
+
+    } else
+	xio_port = pcibr_soft->bs_mxid;
+
+    /*
+     * If this DMA comes back to us,
+     * return the PCI MEM address on
+     * which it would land, or NULL
+     * if the target is something
+     * on bridge other than PCI MEM.
+     */
+    if (xio_port == pcibr_soft->bs_xid) {
+	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
+	return pci_addr;
+    }
+    /* If the caller can use A64, try to
+     * satisfy the request with the 64-bit
+     * direct map. This can fail if the
+     * configuration bits in Device(x)
+     * conflict with our flags.
+     */
+
+    if (flags & PCIIO_DMA_A64) {
+	pci_addr = slotp->bss_d64_base;
+	if (!(flags & PCIBR_VCHAN1))
+	    flags |= PCIBR_VCHAN0;
+	if ((pci_addr != PCIBR_D64_BASE_UNSET) &&
+	    (flags == slotp->bss_d64_flags)) {
+
+#ifdef CONFIG_IA64_SGI_SN2
+	    pci_addr |= (PHYS_TO_DMA(xio_addr))
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+#else
+	    pci_addr |=  xio_addr
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+#endif
+
+#if DEBUG && PCIBR_DMA_DEBUG
+#if HWG_PERF_CHECK
+	    if (xio_addr != 0x20000000)
+#endif
+		printk("pcibr_dmatrans_addr: [reuse]\n"
+			"\tpciio connection point %v\n"
+			"\txtalk connection point %v\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\txtalk_dmatrans_addr returned 0x%x\n"
+			"\tdirect 64bit address is 0x%x\n",
+			pconn_vhdl, xconn_vhdl,
+			paddr, paddr + req_size - 1,
+			xio_addr, pci_addr);
+#endif
+	    return (pci_addr);
+	}
+	if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS)) {
+	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
+	    slotp->bss_d64_flags = flags;
+	    slotp->bss_d64_base = pci_addr;
+#ifdef CONFIG_IA64_SGI_SN2
+	    pci_addr |= (PHYS_TO_DMA(xio_addr))
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+#else
+            pci_addr |= xio_addr
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+#endif
+
+	    /* Make sure we have an RRB (or two).
+	     */
+	    if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
+		if (flags & PCIBR_VCHAN1)
+		    pciio_slot += PCIBR_RRB_SLOT_VIRTUAL;
+		have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
+		if (have_rrbs < 2) {
+		    if (pci_addr & PCI64_ATTR_PREF)
+			min_rrbs = 2;
+		    else
+			min_rrbs = 1;
+		    if (have_rrbs < min_rrbs)
+			do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
+		}
+	    }
+#if PCIBR_DMA_DEBUG
+#if HWG_PERF_CHECK
+	    if (xio_addr != 0x20000000)
+#endif
+		printk("pcibr_dmatrans_addr:\n"
+			"\tpciio connection point %v\n"
+			"\txtalk connection point %v\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\txtalk_dmatrans_addr returned 0x%x\n"
+			"\tdirect 64bit address is 0x%x\n"
+			"\tnew flags: 0x%x\n",
+			pconn_vhdl, xconn_vhdl,
+			paddr, paddr + req_size - 1,
+			xio_addr, pci_addr, (uint64_t) flags);
+#endif
+	    return (pci_addr);
+	}
+	/* our flags conflict with Device(x).
+	 */
+	flags = flags
+	    & ~PCIIO_DMA_A64
+	    & ~PCIBR_VCHAN0
+	    ;
+
+#if PCIBR_DMA_DEBUG
+	printk("pcibr_dmatrans_addr:\n"
+		"\tpciio connection point %v\n"
+		"\txtalk connection point %v\n"
+		"\twanted paddr [0x%x..0x%x]\n"
+		"\txtalk_dmatrans_addr returned 0x%x\n"
+		"\tUnable to set Device(x) bits for Direct-64\n",
+		pconn_vhdl, xconn_vhdl,
+		paddr, paddr + req_size - 1,
+		xio_addr);
+#endif
+    }
+    /* Try to satisfy the request with the 32-bit direct
+     * map. This can fail if the configuration bits in
+     * Device(x) conflict with our flags, or if the
+     * target address is outside where DIR_OFF points.
+     */
+    {
+	size_t                  map_size = 1ULL << 31;
+	iopaddr_t               xio_base = pcibr_soft->bs_dir_xbase;
+	iopaddr_t               offset = xio_addr - xio_base;
+	iopaddr_t               endoff = req_size + offset;
+
+	if ((req_size > map_size) ||
+	    (xio_addr < xio_base) ||
+	    (xio_port != pcibr_soft->bs_dir_xport) ||
+	    (endoff > map_size)) {
+#if PCIBR_DMA_DEBUG
+	    printk("pcibr_dmatrans_addr:\n"
+		    "\tpciio connection point %v\n"
+		    "\txtalk connection point %v\n"
+		    "\twanted paddr [0x%x..0x%x]\n"
+		    "\txtalk_dmatrans_addr returned 0x%x\n"
+		    "\txio region outside direct32 target\n",
+		    pconn_vhdl, xconn_vhdl,
+		    paddr, paddr + req_size - 1,
+		    xio_addr);
+#endif
+	} else {
+	    pci_addr = slotp->bss_d32_base;
+	    if ((pci_addr != PCIBR_D32_BASE_UNSET) &&
+		(flags == slotp->bss_d32_flags)) {
+
+		pci_addr |= offset;
+
+#if DEBUG && PCIBR_DMA_DEBUG
+		printk("pcibr_dmatrans_addr: [reuse]\n"
+			"\tpciio connection point %v\n"
+			"\txtalk connection point %v\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\txtalk_dmatrans_addr returned 0x%x\n"
+			"\tmapped via direct32 offset 0x%x\n"
+			"\twill DMA via pci addr 0x%x\n",
+			pconn_vhdl, xconn_vhdl,
+			paddr, paddr + req_size - 1,
+			xio_addr, offset, pci_addr);
+#endif
+		return (pci_addr);
+	    }
+	    if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS)) {
+
+		pci_addr = PCI32_DIRECT_BASE;
+		slotp->bss_d32_flags = flags;
+		slotp->bss_d32_base = pci_addr;
+		pci_addr |= offset;
+
+		/* Make sure we have an RRB (or two).
+		 */
+		if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
+		    have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
+		    if (have_rrbs < 2) {
+			if (slotp->bss_device & BRIDGE_DEV_PREF)
+			    min_rrbs = 2;
+			else
+			    min_rrbs = 1;
+			if (have_rrbs < min_rrbs)
+			    do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
+		    }
+		}
+#if PCIBR_DMA_DEBUG
+#if HWG_PERF_CHECK
+		if (xio_addr != 0x20000000)
+#endif
+		    printk("pcibr_dmatrans_addr:\n"
+			    "\tpciio connection point %v\n"
+			    "\txtalk connection point %v\n"
+			    "\twanted paddr [0x%x..0x%x]\n"
+			    "\txtalk_dmatrans_addr returned 0x%x\n"
+			    "\tmapped via direct32 offset 0x%x\n"
+			    "\twill DMA via pci addr 0x%x\n"
+			    "\tnew flags: 0x%x\n",
+			    pconn_vhdl, xconn_vhdl,
+			    paddr, paddr + req_size - 1,
+			    xio_addr, offset, pci_addr, (uint64_t) flags);
+#endif
+		return (pci_addr);
+	    }
+	    /* our flags conflict with Device(x).
+	     */
+#if PCIBR_DMA_DEBUG
+	    printk("pcibr_dmatrans_addr:\n"
+		    "\tpciio connection point %v\n"
+		    "\txtalk connection point %v\n"
+		    "\twanted paddr [0x%x..0x%x]\n"
+		    "\txtalk_dmatrans_addr returned 0x%x\n"
+		    "\tUnable to set Device(x) bits for Direct-32\n",
+		    pconn_vhdl, xconn_vhdl,
+		    paddr, paddr + req_size - 1,
+		    xio_addr);
+#endif
+	}
+    }
+
+#if PCIBR_DMA_DEBUG
+    printk("pcibr_dmatrans_addr:\n"
+	    "\tpciio connection point %v\n"
+	    "\txtalk connection point %v\n"
+	    "\twanted paddr [0x%x..0x%x]\n"
+	    "\txtalk_dmatrans_addr returned 0x%x\n"
+	    "\tno acceptable PCI address found or constructable\n",
+	    pconn_vhdl, xconn_vhdl,
+	    paddr, paddr + req_size - 1,
+	    xio_addr);
+#endif
+
+    return 0;
+}
+
+/*ARGSUSED */
+alenlist_t
+pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
+		    device_desc_t dev_desc,
+		    alenlist_t palenlist,
+		    unsigned flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
+    xwidgetnum_t            xio_port;
+
+    alenlist_t              pciio_alenlist = 0;
+    alenlist_t              xtalk_alenlist = 0;
+
+    int                     inplace;
+    unsigned                direct64;
+    unsigned                al_flags;
+
+    iopaddr_t               xio_base;
+    alenaddr_t              xio_addr;
+    size_t                  xio_size;
+
+    size_t                  map_size;
+    iopaddr_t               pci_base;
+    alenaddr_t              pci_addr;
+
+    unsigned                relbits = 0;
+
+    /* merge in forced flags */
+    flags |= pcibr_soft->bs_dma_flags;
+
+    inplace = flags & PCIIO_INPLACE;
+    direct64 = flags & PCIIO_DMA_A64;
+    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
+
+    if (direct64) {
+	map_size = 1ull << 48;
+	xio_base = 0;
+	pci_base = slotp->bss_d64_base;
+	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
+	    (flags == slotp->bss_d64_flags)) {
+	    /* reuse previous base info */
+	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
+	    /* DMA configuration conflict */
+	    goto fail;
+	} else {
+	    relbits = BRIDGE_DEV_D64_BITS;
+	    pci_base =
+		pcibr_flags_to_d64(flags, pcibr_soft);
+	}
+    } else {
+	xio_base = pcibr_soft->bs_dir_xbase;
+	map_size = 1ull << 31;
+	pci_base = slotp->bss_d32_base;
+	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
+	    (flags == slotp->bss_d32_flags)) {
+	    /* reuse previous base info */
+	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
+	    /* DMA configuration conflict */
+	    goto fail;
+	} else {
+	    relbits = BRIDGE_DEV_D32_BITS;
+	    pci_base = PCI32_DIRECT_BASE;
+	}
+    }
+
+    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
+					 flags & DMAMAP_FLAGS);
+    if (!xtalk_alenlist)
+	goto fail;
+
+    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
+
+    if (inplace) {
+	pciio_alenlist = xtalk_alenlist;
+    } else {
+	pciio_alenlist = alenlist_create(al_flags);
+	if (!pciio_alenlist)
+	    goto fail;
+    }
+
+    while (ALENLIST_SUCCESS ==
+	   alenlist_get(xtalk_alenlist, NULL, 0,
+			&xio_addr, &xio_size, al_flags)) {
+
+	/*
+	 * find which XIO port this goes to.
+	 */
+	if (XIO_PACKED(xio_addr)) {
+	    if (xio_addr == XIO_NOWHERE) {
+#if PCIBR_DMA_DEBUG
+		printk("pcibr_dmatrans_addr:\n"
+			"\tpciio connection point %v\n"
+			"\txtalk connection point %v\n"
+			"\twanted paddr [0x%x..0x%x]\n"
+			"\txtalk_dmatrans_addr returned 0x%x\n",
+			pconn_vhdl, xconn_vhdl,
+			paddr, paddr + req_size - 1,
+			xio_addr);
+#endif
+		return 0;
+	    }
+	    xio_port = XIO_PORT(xio_addr);
+	    xio_addr = XIO_ADDR(xio_addr);
+	} else
+	    xio_port = pcibr_soft->bs_mxid;
+
+	/*
+	 * If this DMA comes back to us,
+	 * return the PCI MEM address on
+	 * which it would land, or NULL
+	 * if the target is something
+	 * on bridge other than PCI MEM.
+	 */
+	if (xio_port == pcibr_soft->bs_xid) {
+	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
+	    if ( (pci_addr == (alenaddr_t)NULL) )
+		goto fail;
+	} else if (direct64) {
+	    ASSERT(xio_port != 0);
+	    pci_addr = pci_base | xio_addr
+		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
+	} else {
+	    iopaddr_t               offset = xio_addr - xio_base;
+	    iopaddr_t               endoff = xio_size + offset;
+
+	    if ((xio_size > map_size) ||
+		(xio_addr < xio_base) ||
+		(xio_port != pcibr_soft->bs_dir_xport) ||
+		(endoff > map_size))
+		goto fail;
+
+	    pci_addr = pci_base + (xio_addr - xio_base);
+	}
+
+	/* write the PCI DMA address
+	 * out to the scatter-gather list.
+	 */
+	if (inplace) {
+	    if (ALENLIST_SUCCESS !=
+		alenlist_replace(pciio_alenlist, NULL,
+				 &pci_addr, &xio_size, al_flags))
+		goto fail;
+	} else {
+	    if (ALENLIST_SUCCESS !=
+		alenlist_append(pciio_alenlist,
+				pci_addr, xio_size, al_flags))
+		goto fail;
+	}
+    }
+
+    if (relbits) {
+	if (direct64) {
+	    slotp->bss_d64_flags = flags;
+	    slotp->bss_d64_base = pci_base;
+	} else {
+	    slotp->bss_d32_flags = flags;
+	    slotp->bss_d32_base = pci_base;
+	}
+    }
+    if (!inplace)
+	alenlist_done(xtalk_alenlist);
+
+    /* Reset the internal cursor of the alenlist to be returned back
+     * to the caller.
+     */
+    alenlist_cursor_init(pciio_alenlist, 0, NULL);
+    return pciio_alenlist;
+
+  fail:
+    if (relbits)
+	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
+    if (pciio_alenlist && !inplace)
+	alenlist_destroy(pciio_alenlist);
+    return 0;
+}
+
+void
+pcibr_dmamap_drain(pcibr_dmamap_t map)
+{
+    xtalk_dmamap_drain(map->bd_xtalk);
+}
+
+void
+pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
+		    paddr_t paddr,
+		    size_t bytes)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+
+    xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
+}
+
+void
+pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
+		    alenlist_t list)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+
+    xtalk_dmalist_drain(xconn_vhdl, list);
+}
+
+/*
+ * Get the starting PCIbus address out of the given DMA map.
+ * This function is supposed to be used by a close friend of PCI bridge
+ * since it relies on the fact that the starting address of the map is fixed at
+ * the allocation time in the current implementation of PCI bridge.
+ */
+iopaddr_t
+pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap)
+{
+    return (pcibr_dmamap->bd_pci_addr);
+}
+
+/* =====================================================================
+ *    CONFIGURATION MANAGEMENT
+ */
+/*ARGSUSED */
+void
+pcibr_provider_startup(devfs_handle_t pcibr)
+{
+}
+
+/*ARGSUSED */
+void
+pcibr_provider_shutdown(devfs_handle_t pcibr)
+{
+}
+
+int
+pcibr_reset(devfs_handle_t conn)
+{
+    pciio_info_t            pciio_info = pciio_info_get(conn);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    bridgereg_t             ctlreg;
+    unsigned                cfgctl[8];
+    unsigned long           s;
+    int                     f, nf;
+    pcibr_info_h            pcibr_infoh;
+    pcibr_info_t            pcibr_info;
+    int                     win;
+
+    if (pcibr_soft->bs_slot[pciio_slot].has_host) {
+	pciio_slot = pcibr_soft->bs_slot[pciio_slot].host_slot;
+	pcibr_info = pcibr_soft->bs_slot[pciio_slot].bss_infos[0];
+    }
+    if (pciio_slot < 4) {
+	s = pcibr_lock(pcibr_soft);
+	nf = pcibr_soft->bs_slot[pciio_slot].bss_ninfo;
+	pcibr_infoh = pcibr_soft->bs_slot[pciio_slot].bss_infos;
+	for (f = 0; f < nf; ++f)
+	    if (pcibr_infoh[f])
+		cfgctl[f] = bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4];
+
+	ctlreg = bridge->b_wid_control;
+	bridge->b_wid_control = ctlreg | BRIDGE_CTRL_RST(pciio_slot);
+	/* XXX delay? */
+	bridge->b_wid_control = ctlreg;
+	/* XXX delay? */
+
+	for (f = 0; f < nf; ++f)
+	    if ((pcibr_info = pcibr_infoh[f]))
+		for (win = 0; win < 6; ++win)
+		    if (pcibr_info->f_window[win].w_base != 0)
+			bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_BASE_ADDR(win) / 4] =
+			    pcibr_info->f_window[win].w_base;
+	for (f = 0; f < nf; ++f)
+	    if (pcibr_infoh[f])
+		bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4] = cfgctl[f];
+	pcibr_unlock(pcibr_soft, s);
+
+	return 0;
+    }
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    printk(KERN_WARNING   "%v: pcibr_reset unimplemented for slot %d\n",
+	    conn, pciio_slot);
+#endif
+    return -1;
+}
+
+pciio_endian_t
+pcibr_endian_set(devfs_handle_t pconn_vhdl,
+		 pciio_endian_t device_end,
+		 pciio_endian_t desired_end)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridgereg_t             devreg;
+    unsigned long           s;
+
+    /*
+     * Bridge supports hardware swapping; so we can always
+     * arrange for the caller's desired endianness.
+     */
+
+    s = pcibr_lock(pcibr_soft);
+    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
+    if (device_end != desired_end)
+	devreg |= BRIDGE_DEV_SWAP_BITS;
+    else
+	devreg &= ~BRIDGE_DEV_SWAP_BITS;
+
+    /* NOTE- if we ever put SWAP bits
+     * onto the disabled list, we will
+     * have to change the logic here.
+     */
+    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
+	bridge_t               *bridge = pcibr_soft->bs_base;
+
+	bridge->b_device[pciio_slot].reg = devreg;
+	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
+	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    }
+    pcibr_unlock(pcibr_soft, s);
+
+#if DEBUG && PCIBR_DEV_DEBUG
+    printk("pcibr Device(%d): 0x%p\n", pciio_slot, bridge->b_device[pciio_slot].reg);
+#endif
+
+    return desired_end;
+}
+
+/* This (re)sets the GBR and REALTIME bits and also keeps track of how
+ * many sets are outstanding. Reset succeeds only if the number of outstanding
+ * sets == 1.
+ */
+int
+pcibr_priority_bits_set(pcibr_soft_t pcibr_soft,
+			pciio_slot_t pciio_slot,
+			pciio_priority_t device_prio)
+{
+    unsigned long           s;
+    int                    *counter;
+    bridgereg_t             rtbits = 0;
+    bridgereg_t             devreg;
+    int                     rc = PRIO_SUCCESS;
+
+    /* in dual-slot configurations, the host and the
+     * guest have separate DMA resources, so they
+     * have separate requirements for priority bits.
+     */
+
+    counter = &(pcibr_soft->bs_slot[pciio_slot].bss_pri_uctr);
+
+    /*
+     * Bridge supports PCI notions of LOW and HIGH priority
+     * arbitration rings via a "REAL_TIME" bit in the per-device
+     * Bridge register. The "GBR" bit controls access to the GBR
+     * ring on the xbow. These two bits are (re)set together.
+     *
+     * XXX- Bug in Rev B Bridge Si:
+     * Symptom: Prefetcher starts operating incorrectly. This happens
+     * due to corruption of the address storage ram in the prefetcher
+     * when a non-real time PCI request is pulled and a real-time one is
+     * put in it's place. Workaround: Use only a single arbitration ring
+     * on PCI bus. GBR and RR can still be uniquely used per
+     * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C.
+     */
+
+    if (pcibr_soft->bs_rev_num != BRIDGE_PART_REV_B)
+	rtbits |= BRIDGE_DEV_RT;
+
+    /* NOTE- if we ever put DEV_RT or DEV_GBR on
+     * the disabled list, we will have to take
+     * it into account here.
+     */
+
+    s = pcibr_lock(pcibr_soft);
+    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
+    if (device_prio == PCI_PRIO_HIGH) {
+	if ((++*counter == 1)) {
+	    if (rtbits)
+		devreg |= rtbits;
+	    else
+		rc = PRIO_FAIL;
+	}
+    } else if (device_prio == PCI_PRIO_LOW) {
+	if (*counter <= 0)
+	    rc = PRIO_FAIL;
+	else if (--*counter == 0)
+	    if (rtbits)
+		devreg &= ~rtbits;
+    }
+    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
+	bridge_t               *bridge = pcibr_soft->bs_base;
+
+	bridge->b_device[pciio_slot].reg = devreg;
+	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
+	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    }
+    pcibr_unlock(pcibr_soft, s);
+
+    return rc;
+}
+
+pciio_priority_t
+pcibr_priority_set(devfs_handle_t pconn_vhdl,
+		   pciio_priority_t device_prio)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+    (void) pcibr_priority_bits_set(pcibr_soft, pciio_slot, device_prio);
+
+    return device_prio;
+}
+
+/*
+ * Interfaces to allow special (e.g. SGI) drivers to set/clear
+ * Bridge-specific device flags.  Many flags are modified through
+ * PCI-generic interfaces; we don't allow them to be directly
+ * manipulated here.  Only flags that at this point seem pretty
+ * Bridge-specific can be set through these special interfaces.
+ * We may add more flags as the need arises, or remove flags and
+ * create PCI-generic interfaces as the need arises.
+ *
+ * Returns 0 on failure, 1 on success
+ */
+int
+pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
+		       pcibr_device_flags_t flags)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridgereg_t             set = 0;
+    bridgereg_t             clr = 0;
+
+    ASSERT((flags & PCIBR_DEVICE_FLAGS) == flags);
+
+    if (flags & PCIBR_WRITE_GATHER)
+	set |= BRIDGE_DEV_PMU_WRGA_EN;
+    if (flags & PCIBR_NOWRITE_GATHER)
+	clr |= BRIDGE_DEV_PMU_WRGA_EN;
+
+    if (flags & PCIBR_WRITE_GATHER)
+	set |= BRIDGE_DEV_DIR_WRGA_EN;
+    if (flags & PCIBR_NOWRITE_GATHER)
+	clr |= BRIDGE_DEV_DIR_WRGA_EN;
+
+    if (flags & PCIBR_PREFETCH)
+	set |= BRIDGE_DEV_PREF;
+    if (flags & PCIBR_NOPREFETCH)
+	clr |= BRIDGE_DEV_PREF;
+
+    if (flags & PCIBR_PRECISE)
+	set |= BRIDGE_DEV_PRECISE;
+    if (flags & PCIBR_NOPRECISE)
+	clr |= BRIDGE_DEV_PRECISE;
+
+    if (flags & PCIBR_BARRIER)
+	set |= BRIDGE_DEV_BARRIER;
+    if (flags & PCIBR_NOBARRIER)
+	clr |= BRIDGE_DEV_BARRIER;
+
+    if (flags & PCIBR_64BIT)
+	set |= BRIDGE_DEV_DEV_SIZE;
+    if (flags & PCIBR_NO64BIT)
+	clr |= BRIDGE_DEV_DEV_SIZE;
+
+    if (set || clr) {
+	bridgereg_t             devreg;
+	unsigned long           s;
+
+	s = pcibr_lock(pcibr_soft);
+	devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
+	devreg = (devreg & ~clr) | set;
+	if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
+	    bridge_t               *bridge = pcibr_soft->bs_base;
+
+	    bridge->b_device[pciio_slot].reg = devreg;
+	    pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
+	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
+	}
+	pcibr_unlock(pcibr_soft, s);
+#if DEBUG && PCIBR_DEV_DEBUG
+	printk("pcibr Device(%d): %R\n", pciio_slot, bridge->b_device[pciio_slot].regbridge->b_device[pciio_slot].reg, device_bits);
+#endif
+    }
+    return (1);
+}
+
+pciio_provider_t        pcibr_provider =
+{
+    (pciio_piomap_alloc_f *) pcibr_piomap_alloc,
+    (pciio_piomap_free_f *) pcibr_piomap_free,
+    (pciio_piomap_addr_f *) pcibr_piomap_addr,
+    (pciio_piomap_done_f *) pcibr_piomap_done,
+    (pciio_piotrans_addr_f *) pcibr_piotrans_addr,
+    (pciio_piospace_alloc_f *) pcibr_piospace_alloc,
+    (pciio_piospace_free_f *) pcibr_piospace_free,
+
+    (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
+    (pciio_dmamap_free_f *) pcibr_dmamap_free,
+    (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
+    (pciio_dmamap_list_f *) pcibr_dmamap_list,
+    (pciio_dmamap_done_f *) pcibr_dmamap_done,
+    (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
+    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
+    (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
+    (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
+    (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
+
+    (pciio_intr_alloc_f *) pcibr_intr_alloc,
+    (pciio_intr_free_f *) pcibr_intr_free,
+    (pciio_intr_connect_f *) pcibr_intr_connect,
+    (pciio_intr_disconnect_f *) pcibr_intr_disconnect,
+    (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get,
+
+    (pciio_provider_startup_f *) pcibr_provider_startup,
+    (pciio_provider_shutdown_f *) pcibr_provider_shutdown,
+    (pciio_reset_f *) pcibr_reset,
+    (pciio_write_gather_flush_f *) pcibr_write_gather_flush,
+    (pciio_endian_set_f *) pcibr_endian_set,
+    (pciio_priority_set_f *) pcibr_priority_set,
+    (pciio_config_get_f *) pcibr_config_get,
+    (pciio_config_set_f *) pcibr_config_set,
+
+    (pciio_error_devenable_f *) 0,
+    (pciio_error_extract_f *) 0,
+
+#ifdef LATER
+    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
+    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
+#else
+    (pciio_driver_reg_callback_f *) 0,
+    (pciio_driver_unreg_callback_f *) 0,
+#endif
+    (pciio_device_unregister_f 	*) pcibr_device_unregister,
+    (pciio_dma_enabled_f		*) pcibr_dma_enabled,
+};
+
+int
+pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+	
+
+    return xtalk_dma_enabled(pcibr_soft->bs_conn);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,1737 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+#ifdef __ia64
+#define rmallocmap atemapalloc
+#define rmfreemap atemapfree
+#define rmfree atefree
+#define rmalloc atealloc
+#endif
+
+extern int	hubii_check_widget_disabled(nasid_t, int);
+
+/* =====================================================================
+ *    ERROR HANDLING
+ */
+
+#ifdef	DEBUG
+#ifdef	ERROR_DEBUG
+#define BRIDGE_PIOERR_TIMEOUT	100	/* Timeout with ERROR_DEBUG defined */
+#else
+#define BRIDGE_PIOERR_TIMEOUT	40	/* Timeout in debug mode  */
+#endif
+#else
+#define BRIDGE_PIOERR_TIMEOUT	1	/* Timeout in non-debug mode                            */
+#endif
+
+#ifdef  DEBUG
+#ifdef ERROR_DEBUG
+bridgereg_t bridge_errors_to_dump = ~BRIDGE_ISR_INT_MSK;
+#else
+bridgereg_t bridge_errors_to_dump = BRIDGE_ISR_ERROR_DUMP;
+#endif
+#else
+bridgereg_t bridge_errors_to_dump = BRIDGE_ISR_ERROR_FATAL |
+                                BRIDGE_ISR_PCIBUS_PIOERR;
+#endif
+
+#if defined (PCIBR_LLP_CONTROL_WAR)
+int                     pcibr_llp_control_war_cnt;
+#endif				/* PCIBR_LLP_CONTROL_WAR */
+
+/* FIXME: can these arrays be local ? */
+
+#ifdef LATER
+
+struct reg_values xio_cmd_pactyp[] =
+{
+    {0x0, "RdReq"},
+    {0x1, "RdResp"},
+    {0x2, "WrReqWithResp"},
+    {0x3, "WrResp"},
+    {0x4, "WrReqNoResp"},
+    {0x5, "Reserved(5)"},
+    {0x6, "FetchAndOp"},
+    {0x7, "Reserved(7)"},
+    {0x8, "StoreAndOp"},
+    {0x9, "Reserved(9)"},
+    {0xa, "Reserved(a)"},
+    {0xb, "Reserved(b)"},
+    {0xc, "Reserved(c)"},
+    {0xd, "Reserved(d)"},
+    {0xe, "SpecialReq"},
+    {0xf, "SpecialResp"},
+    {0}
+};
+
+struct reg_desc   xio_cmd_bits[] =
+{
+    {WIDGET_DIDN, -28, "DIDN", "%x"},
+    {WIDGET_SIDN, -24, "SIDN", "%x"},
+    {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp},
+    {WIDGET_TNUM, -15, "TNUM", "%x"},
+    {WIDGET_COHERENT, 0, "COHERENT"},
+    {WIDGET_DS, 0, "DS"},
+    {WIDGET_GBR, 0, "GBR"},
+    {WIDGET_VBPM, 0, "VBPM"},
+    {WIDGET_ERROR, 0, "ERROR"},
+    {WIDGET_BARRIER, 0, "BARRIER"},
+    {0}
+};
+
+#define F(s,n)          { 1l<<(s),-(s), n }
+
+struct reg_desc         bridge_int_status_desc[] =
+{
+    F(31, "MULTI_ERR"),
+    F(30, "PMU_ESIZE_EFAULT"),
+    F(29, "UNEXPECTED_RESP"),
+    F(28, "BAD_XRESP_PACKET"),
+    F(27, "BAD_XREQ_PACKET"),
+    F(26, "RESP_XTALK_ERROR"),
+    F(25, "REQ_XTALK_ERROR"),
+    F(24, "INVALID_ADDRESS"),
+    F(23, "UNSUPPORTED_XOP"),
+    F(22, "XREQ_FIFO_OFLOW"),
+    F(21, "LLP_REC_SNERROR"),
+    F(20, "LLP_REC_CBERROR"),
+    F(19, "LLP_RCTY"),
+    F(18, "LLP_TX_RETRY"),
+    F(17, "LLP_TCTY"),
+    F(16, "SSRAM_PERR"),
+    F(15, "PCI_ABORT"),
+    F(14, "PCI_PARITY"),
+    F(13, "PCI_SERR"),
+    F(12, "PCI_PERR"),
+    F(11, "PCI_MASTER_TOUT"),
+    F(10, "PCI_RETRY_CNT"),
+    F(9, "XREAD_REQ_TOUT"),
+    F(8, "GIO_BENABLE_ERR"),
+    F(7, "INT7"),
+    F(6, "INT6"),
+    F(5, "INT5"),
+    F(4, "INT4"),
+    F(3, "INT3"),
+    F(2, "INT2"),
+    F(1, "INT1"),
+    F(0, "INT0"),
+    {0}
+};
+
+struct reg_values       space_v[] =
+{
+    {PCIIO_SPACE_NONE, "none"},
+    {PCIIO_SPACE_ROM, "ROM"},
+    {PCIIO_SPACE_IO, "I/O"},
+    {PCIIO_SPACE_MEM, "MEM"},
+    {PCIIO_SPACE_MEM32, "MEM(32)"},
+    {PCIIO_SPACE_MEM64, "MEM(64)"},
+    {PCIIO_SPACE_CFG, "CFG"},
+    {PCIIO_SPACE_WIN(0), "WIN(0)"},
+    {PCIIO_SPACE_WIN(1), "WIN(1)"},
+    {PCIIO_SPACE_WIN(2), "WIN(2)"},
+    {PCIIO_SPACE_WIN(3), "WIN(3)"},
+    {PCIIO_SPACE_WIN(4), "WIN(4)"},
+    {PCIIO_SPACE_WIN(5), "WIN(5)"},
+    {PCIIO_SPACE_BAD, "BAD"},
+    {0}
+};
+struct reg_desc         space_desc[] =
+{
+    {0xFF, 0, "space", 0, space_v},
+    {0}
+};
+#define	device_desc	device_bits
+struct reg_desc   device_bits[] =
+{
+    {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
+    {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
+    {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"},
+    {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"},
+    {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"},
+    {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"},
+    {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"},
+    {BRIDGE_DEV_RT, 0, "RT"},
+    {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"},
+    {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"},
+    {BRIDGE_DEV_PREF, 0, "PREF"},
+    {BRIDGE_DEV_PRECISE, 0, "PRECISE"},
+    {BRIDGE_DEV_COH, 0, "COH"},
+    {BRIDGE_DEV_BARRIER, 0, "BARRIER"},
+    {BRIDGE_DEV_GBR, 0, "GBR"},
+    {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"},
+    {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"},
+    {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"},
+    {0}
+};
+
+#endif	/* LATER */
+
+void
+print_bridge_errcmd(uint32_t cmdword, char *errtype)
+{
+    printk(
+	    "\t    Bridge %s Error Command Word Register %R\n",
+	    errtype, cmdword, xio_cmd_bits);
+}
+
+char             *pcibr_isr_errs[] =
+{
+    "", "", "", "", "", "", "", "",
+    "08: GIO non-contiguous byte enable in crosstalk packet",
+    "09: PCI to Crosstalk read request timeout",
+    "10: PCI retry operation count exhausted.",
+    "11: PCI bus device select timeout",
+    "12: PCI device reported parity error",
+    "13: PCI Address/Cmd parity error ",
+    "14: PCI Bridge detected parity error",
+    "15: PCI abort condition",
+    "16: SSRAM parity error",
+    "17: LLP Transmitter Retry count wrapped",
+    "18: LLP Transmitter side required Retry",
+    "19: LLP Receiver retry count wrapped",
+    "20: LLP Receiver check bit error",
+    "21: LLP Receiver sequence number error",
+    "22: Request packet overflow",
+    "23: Request operation not supported by bridge",
+    "24: Request packet has invalid address for bridge widget",
+    "25: Incoming request xtalk command word error bit set or invalid sideband",
+    "26: Incoming response xtalk command word error bit set or invalid sideband",
+    "27: Framing error, request cmd data size does not match actual",
+    "28: Framing error, response cmd data size does not match actual",
+    "29: Unexpected response arrived",
+    "30: PMU Access Fault",
+    "31: Multiple errors occurred",
+};
+
+#define BEM_ADD_STR(s)  printk("%s", (s))
+#define BEM_ADD_VAR(v)  printk("\t%20s: 0x%x\n", #v, (v))
+#define BEM_ADD_REG(r)  printk("\t%20s: %R\n", #r, (r), r ## _desc)
+#define BEM_ADD_NSPC(n,s)       printk("\t%20s: %R\n", n, s, space_desc)
+#define BEM_ADD_SPC(s)          BEM_ADD_NSPC(#s, s)
+
+/*
+ * display memory directory state
+ */
+void
+pcibr_show_dir_state(paddr_t paddr, char *prefix)
+{
+	int state;
+	uint64_t vec_ptr;
+	hubreg_t elo;
+	extern char *dir_state_str[];
+	extern void get_dir_ent(paddr_t, int *, uint64_t *, hubreg_t *);
+
+	get_dir_ent(paddr, &state, &vec_ptr, &elo);
+
+	printf("%saddr 0x%x: state 0x%x owner 0x%x (%s)\n", 
+		prefix, paddr, state, vec_ptr, dir_state_str[state]);
+}
+
+
+/*
+ *	Dump relevant error information for Bridge error interrupts.
+ */
+/*ARGSUSED */
+void
+pcibr_error_dump(pcibr_soft_t pcibr_soft)
+{
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    bridgereg_t             int_status;
+    bridgereg_t             mult_int;
+    int			    bit;
+    int                     i;
+    char		    *reg_desc;
+    paddr_t		    addr;
+
+    int_status = (bridge->b_int_status & ~BRIDGE_ISR_INT_MSK);
+    if (!int_status) {
+	/* No error bits set */
+	return;
+    }
+
+    /* Check if dumping the same error information multiple times */
+    if (test_and_set_int((int *) &pcibr_soft->bs_errinfo.bserr_intstat,
+	    int_status) == int_status) {
+	return;
+    }
+
+    printk(KERN_ALERT "PCI BRIDGE ERROR: int_status is 0x%X for %s\n"
+	"    Dumping relevant %sBridge registers for each bit set...\n",
+	    int_status, pcibr_soft->bs_name,
+	    (is_xbridge(bridge) ? "X" : ""));
+
+    for (i = PCIBR_ISR_ERR_START; i < PCIBR_ISR_MAX_ERRS; i++) {
+	bit = 1 << i;
+
+	/*
+	 * A number of int_status bits are only defined for Bridge.
+	 * Ignore them in the case of an XBridge.
+	 */
+	if (is_xbridge(bridge) && ((bit == BRIDGE_ISR_MULTI_ERR) ||
+		(bit == BRIDGE_ISR_SSRAM_PERR) ||
+		(bit == BRIDGE_ISR_GIO_B_ENBL_ERR))) {
+	    continue;
+	}
+
+	if (int_status & bit) {
+	    printk("\t%s\n", pcibr_isr_errs[i]);
+
+	    switch (bit) {
+	    case BRIDGE_ISR_PAGE_FAULT:		/* PMU_PAGE_FAULT  (XBridge) */
+/*	    case BRIDGE_ISR_PMU_ESIZE_FAULT:	   PMU_ESIZE_FAULT (Bridge) */
+		if (is_xbridge(bridge))
+		    reg_desc = "Map Fault Address";
+		else
+		    reg_desc = "SSRAM Parity Error";
+
+		printk("\t    %s Register: 0x%x\n", reg_desc,
+		    bridge->b_ram_perr_or_map_fault);
+		break;
+
+	    case BRIDGE_ISR_UNEXP_RESP:		/* UNEXPECTED_RESP */
+		print_bridge_errcmd(bridge->b_wid_aux_err, "Aux");
+		break;
+
+	    case BRIDGE_ISR_BAD_XRESP_PKT:		/* BAD_RESP_PACKET */
+	    case BRIDGE_ISR_RESP_XTLK_ERR:		/* RESP_XTALK_ERROR */
+	    case BRIDGE_ISR_XREAD_REQ_TIMEOUT:		/* XREAD_REQ_TOUT */
+
+		addr = (((uint64_t) (bridge->b_wid_resp_upper & 0xFFFF) << 32)
+			| bridge->b_wid_resp_lower);
+		printk(
+		    "\t    Bridge Response Buffer Error Upper Address Register: 0x%x\n"
+		    "\t    Bridge Response Buffer Error Lower Address Register: 0x%x\n"
+		    "\t    dev-num %d buff-num %d addr 0x%x\n",
+		    bridge->b_wid_resp_upper, bridge->b_wid_resp_lower,
+		    ((bridge->b_wid_resp_upper >> 20) & 0x3),
+		    ((bridge->b_wid_resp_upper >> 16) & 0xF),
+		    addr);
+		if (bit == BRIDGE_ISR_RESP_XTLK_ERR) {
+			/* display memory directory associated with cacheline */
+			pcibr_show_dir_state(addr, "\t    ");
+		}
+		break;
+
+	    case BRIDGE_ISR_BAD_XREQ_PKT:		/* BAD_XREQ_PACKET */
+	    case BRIDGE_ISR_REQ_XTLK_ERR:		/* REQ_XTALK_ERROR */
+	    case BRIDGE_ISR_INVLD_ADDR:			/* INVALID_ADDRESS */
+	    case BRIDGE_ISR_UNSUPPORTED_XOP:		/* UNSUPPORTED_XOP */
+		print_bridge_errcmd(bridge->b_wid_aux_err, "");
+		printk("\t    Bridge Error Upper Address Register: 0x%x\n"
+		    "\t    Bridge Error Lower Address Register: 0x%x\n"
+		    "\t    Bridge Error Address: 0x%x\n",
+		    (uint64_t) bridge->b_wid_err_upper,
+		    (uint64_t) bridge->b_wid_err_lower,
+		    (((uint64_t) bridge->b_wid_err_upper << 32) |
+		    bridge->b_wid_err_lower));
+		break;
+
+	    case BRIDGE_ISR_SSRAM_PERR:			/* SSRAM_PERR */
+		if (!is_xbridge(bridge)) {	/* only defined on Bridge */
+		    printk(
+			"\t    Bridge SSRAM Parity Error Register: 0x%x\n",
+			bridge->b_ram_perr);
+		}
+		break;
+
+	    case BRIDGE_ISR_PCI_ABORT:			/* PCI_ABORT */
+	    case BRIDGE_ISR_PCI_PARITY:			/* PCI_PARITY */
+	    case BRIDGE_ISR_PCI_SERR:			/* PCI_SERR */
+	    case BRIDGE_ISR_PCI_PERR:			/* PCI_PERR */
+	    case BRIDGE_ISR_PCI_MST_TIMEOUT:		/* PCI_MASTER_TOUT */
+	    case BRIDGE_ISR_PCI_RETRY_CNT:		/* PCI_RETRY_CNT */
+	    case BRIDGE_ISR_GIO_B_ENBL_ERR:		/* GIO BENABLE_ERR */
+		printk("\t    PCI Error Upper Address Register: 0x%x\n"
+		    "\t    PCI Error Lower Address Register: 0x%x\n"
+		    "\t    PCI Error Address: 0x%x\n",
+		    (uint64_t) bridge->b_pci_err_upper,
+		    (uint64_t) bridge->b_pci_err_lower,
+		    (((uint64_t) bridge->b_pci_err_upper << 32) |
+		    bridge->b_pci_err_lower));
+		break;
+	    }
+	}
+    }
+
+    if (is_xbridge(bridge) && (bridge->b_mult_int & ~BRIDGE_ISR_INT_MSK)) {
+	mult_int = bridge->b_mult_int;
+	printk("    XBridge Multiple Interrupt Register is 0x%x\n",
+		mult_int);
+	for (i = PCIBR_ISR_ERR_START; i < PCIBR_ISR_MAX_ERRS; i++) {
+	    if (mult_int & (1 << i))
+		printk("\t%s\n", pcibr_isr_errs[i]);
+	    }
+	}
+}
+
+#define PCIBR_ERRINTR_GROUP(error)	\
+		(( error & (BRIDGE_IRR_PCI_GRP|BRIDGE_IRR_GIO_GRP)
+
+uint32_t
+pcibr_errintr_group(uint32_t error)
+{
+    uint32_t              group = BRIDGE_IRR_MULTI_CLR;
+
+    if (error & BRIDGE_IRR_PCI_GRP)
+	group |= BRIDGE_IRR_PCI_GRP_CLR;
+    if (error & BRIDGE_IRR_SSRAM_GRP)
+	group |= BRIDGE_IRR_SSRAM_GRP_CLR;
+    if (error & BRIDGE_IRR_LLP_GRP)
+	group |= BRIDGE_IRR_LLP_GRP_CLR;
+    if (error & BRIDGE_IRR_REQ_DSP_GRP)
+	group |= BRIDGE_IRR_REQ_DSP_GRP_CLR;
+    if (error & BRIDGE_IRR_RESP_BUF_GRP)
+	group |= BRIDGE_IRR_RESP_BUF_GRP_CLR;
+    if (error & BRIDGE_IRR_CRP_GRP)
+	group |= BRIDGE_IRR_CRP_GRP_CLR;
+
+    return group;
+
+}
+
+
+/* pcibr_pioerr_check():
+ *	Check to see if this pcibr has a PCI PIO
+ *	TIMEOUT error; if so, bump the timeout-count
+ *	on any piomaps that could cover the address.
+ */
+static void
+pcibr_pioerr_check(pcibr_soft_t soft)
+{
+    bridge_t		   *bridge;
+    bridgereg_t		    b_int_status;
+    bridgereg_t		    b_pci_err_lower;
+    bridgereg_t		    b_pci_err_upper;
+    iopaddr_t		    pci_addr;
+    pciio_slot_t	    slot;
+    pcibr_piomap_t	    map;
+    iopaddr_t		    base;
+    size_t		    size;
+    unsigned		    win;
+    int			    func;
+
+    bridge = soft->bs_base;
+    b_int_status = bridge->b_int_status;
+    if (b_int_status & BRIDGE_ISR_PCIBUS_PIOERR) {
+	b_pci_err_lower = bridge->b_pci_err_lower;
+	b_pci_err_upper = bridge->b_pci_err_upper;
+	b_int_status = bridge->b_int_status;
+	if (b_int_status & BRIDGE_ISR_PCIBUS_PIOERR) {
+
+	    pci_addr = b_pci_err_upper & BRIDGE_ERRUPPR_ADDRMASK;
+	    pci_addr = (pci_addr << 32) | b_pci_err_lower;
+
+	    slot = 8;
+	    while (slot-- > 0) {
+		int 		nfunc = soft->bs_slot[slot].bss_ninfo;
+		pcibr_info_h	pcibr_infoh = soft->bs_slot[slot].bss_infos;
+
+		for (func = 0; func < nfunc; func++) {
+		    pcibr_info_t 	pcibr_info = pcibr_infoh[func];
+
+		    if (!pcibr_info)
+			continue;
+
+		    for (map = pcibr_info->f_piomap;
+			 map != NULL; map = map->bp_next) {
+			base = map->bp_pciaddr;
+			size = map->bp_mapsz;
+			win = map->bp_space - PCIIO_SPACE_WIN(0);
+			if (win < 6)
+			    base += 
+				soft->bs_slot[slot].bss_window[win].bssw_base;
+			else if (map->bp_space == PCIIO_SPACE_ROM)
+			    base += pcibr_info->f_rbase;
+			if ((pci_addr >= base) && (pci_addr < (base + size)))
+			    atomicAddInt(map->bp_toc, 1);
+		    }
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * PCI Bridge Error interrupt handler.
+ *      This gets invoked, whenever a PCI bridge sends an error interrupt.
+ *      Primarily this servers two purposes.
+ *              - If an error can be handled (typically a PIO read/write
+ *                error, we try to do it silently.
+ *              - If an error cannot be handled, we die violently.
+ *      Interrupt due to PIO errors:
+ *              - Bridge sends an interrupt, whenever a PCI operation
+ *                done by the bridge as the master fails. Operations could
+ *                be either a PIO read or a PIO write.
+ *                PIO Read operation also triggers a bus error, and it's
+ *                We primarily ignore this interrupt in that context..
+ *                For PIO write errors, this is the only indication.
+ *                and we have to handle with the info from here.
+ *
+ *                So, there is no way to distinguish if an interrupt is
+ *                due to read or write error!.
+ */
+
+
+void
+pcibr_error_intr_handler(intr_arg_t arg)
+{
+    pcibr_soft_t            pcibr_soft;
+    bridge_t               *bridge;
+    bridgereg_t             int_status;
+    bridgereg_t             err_status;
+    int                     i;
+
+    /* REFERENCED */
+    bridgereg_t             disable_errintr_mask = 0;
+    int 		    rv;
+    int 		    error_code = IOECODE_DMA | IOECODE_READ;
+    ioerror_mode_t 	    mode = MODE_DEVERROR;
+    ioerror_t 	            ioe;
+    nasid_t		    nasid;
+
+#if PCIBR_SOFT_LIST
+    {
+	extern pcibr_list_p	pcibr_list;
+	pcibr_list_p            entry;
+
+	entry = pcibr_list;
+	while (1) {
+	    if (entry == NULL) {
+		PRINT_PANIC(
+			"pcibr_error_intr_handler:\n"
+			"\tmy parameter (0x%x) is not a pcibr_soft!",
+			arg);
+	    }
+	    if ((intr_arg_t) entry->bl_soft == arg)
+		break;
+	    entry = entry->bl_next;
+	}
+    }
+#endif
+    pcibr_soft = (pcibr_soft_t) arg;
+    bridge = pcibr_soft->bs_base;
+
+    /*
+     * pcibr_error_intr_handler gets invoked whenever bridge encounters
+     * an error situation, and the interrupt for that error is enabled.
+     * This routine decides if the error is fatal or not, and takes
+     * action accordingly.
+     *
+     * In the case of PIO read/write timeouts, there is no way
+     * to know if it was a read or write request that timed out.
+     * If the error was due to a "read", a bus error will also occur
+     * and the bus error handling code takes care of it. 
+     * If the error is due to a "write", the error is currently logged 
+     * by this routine. For SN1 and SN0, if fire-and-forget mode is 
+     * disabled, a write error response xtalk packet will be sent to 
+     * the II, which will cause an II error interrupt. No write error 
+     * recovery actions of any kind currently take place at the pcibr 
+     * layer! (e.g., no panic on unrecovered write error)
+     *
+     * Prior to reading the Bridge int_status register we need to ensure
+     * that there are no error bits set in the lower layers (hubii)
+     * that have disabled PIO access to the widget. If so, there is nothing
+     * we can do until the bits clear, so we setup a timeout and try again
+     * later.
+     */
+
+    nasid = NASID_GET(bridge);
+    if (hubii_check_widget_disabled(nasid, pcibr_soft->bs_xid)) {
+	timeout(pcibr_error_intr_handler, pcibr_soft, BRIDGE_PIOERR_TIMEOUT);
+	pcibr_soft->bs_errinfo.bserr_toutcnt++;
+	return;
+    }
+
+    /* int_status is which bits we have to clear;
+     * err_status is the bits we haven't handled yet.
+     */
+
+    int_status = bridge->b_int_status &  ~BRIDGE_ISR_INT_MSK;
+    err_status = int_status & ~BRIDGE_ISR_MULTI_ERR;
+
+    if (!(int_status & ~BRIDGE_ISR_INT_MSK)) {
+	/*
+	 * No error bit set!!.
+	 */
+	return;
+    }
+    /*
+     * If we have a PCIBUS_PIOERR, hand it to the logger.
+     */
+    if (int_status & BRIDGE_ISR_PCIBUS_PIOERR) {
+	pcibr_pioerr_check(pcibr_soft);
+    }
+
+    if (err_status) {
+	struct bs_errintr_stat_s *bs_estat = pcibr_soft->bs_errintr_stat;
+
+	for (i = PCIBR_ISR_ERR_START; i < PCIBR_ISR_MAX_ERRS; i++, bs_estat++) {
+	    if (err_status & (1 << i)) {
+		uint32_t              errrate = 0;
+		uint32_t              errcount = 0;
+		uint32_t              errinterval = 0, current_tick = 0;
+		int                     llp_tx_retry_errors = 0;
+		int                     is_llp_tx_retry_intr = 0;
+
+		bs_estat->bs_errcount_total++;
+
+		current_tick = lbolt;
+		errinterval = (current_tick - bs_estat->bs_lasterr_timestamp);
+		errcount = (bs_estat->bs_errcount_total -
+			    bs_estat->bs_lasterr_snapshot);
+
+		is_llp_tx_retry_intr = (BRIDGE_ISR_LLP_TX_RETRY == (1 << i));
+
+		/* Check for the divide by zero condition while
+		 * calculating the error rates.
+		 */
+
+		if (errinterval) {
+		    errrate = errcount / errinterval;
+		    /* If able to calculate error rate
+		     * on a LLP transmitter retry interrupt, check
+		     * if the error rate is nonzero and we have seen
+		     * a certain minimum number of errors.
+		     *
+		     * NOTE : errcount is being compared to
+		     * PCIBR_ERRTIME_THRESHOLD to make sure that we are not
+		     * seeing cases like x error interrupts per y ticks for
+		     * very low x ,y (x > y ) which could result in a
+		     * rate > 100/tick.
+		     */
+		    if (is_llp_tx_retry_intr &&
+			errrate &&
+			(errcount >= PCIBR_ERRTIME_THRESHOLD)) {
+			llp_tx_retry_errors = 1;
+		    }
+		} else {
+		    errrate = 0;
+		    /* Since we are not able to calculate the
+		     * error rate check if we exceeded a certain
+		     * minimum number of errors for LLP transmitter
+		     * retries. Note that this can only happen
+		     * within the first tick after the last snapshot.
+		     */
+		    if (is_llp_tx_retry_intr &&
+			(errcount >= PCIBR_ERRINTR_DISABLE_LEVEL)) {
+			llp_tx_retry_errors = 1;
+		    }
+		}
+
+		/*
+		 * If a non-zero error rate (which is equivalent to
+		 * to 100 errors/tick at least) for the LLP transmitter
+		 * retry interrupt was seen, check if we should print
+		 * a warning message.
+		 */
+
+		if (llp_tx_retry_errors) {
+		    static uint32_t       last_printed_rate;
+
+		    if (errrate > last_printed_rate) {
+			last_printed_rate = errrate;
+			/* Print the warning only if the error rate
+			 * for the transmitter retry interrupt
+			 * exceeded the previously printed rate.
+			 */
+			printk(KERN_WARNING
+				"%s: %s, Excessive error interrupts : %d/tick\n",
+				pcibr_soft->bs_name,
+				pcibr_isr_errs[i],
+				errrate);
+
+		    }
+		    /*
+		     * Update snapshot, and time
+		     */
+		    bs_estat->bs_lasterr_timestamp = current_tick;
+		    bs_estat->bs_lasterr_snapshot =
+			bs_estat->bs_errcount_total;
+
+		}
+		/*
+		 * If the error rate is high enough, print the error rate.
+		 */
+		if (errinterval > PCIBR_ERRTIME_THRESHOLD) {
+
+		    if (errrate > PCIBR_ERRRATE_THRESHOLD) {
+			printk(KERN_NOTICE "%s: %s, Error rate %d/tick",
+				pcibr_soft->bs_name,
+				pcibr_isr_errs[i],
+				errrate);
+			/*
+			 * Update snapshot, and time
+			 */
+			bs_estat->bs_lasterr_timestamp = current_tick;
+			bs_estat->bs_lasterr_snapshot =
+			    bs_estat->bs_errcount_total;
+		    }
+		}
+		if (bs_estat->bs_errcount_total > PCIBR_ERRINTR_DISABLE_LEVEL) {
+		    /*
+		     * We have seen a fairly large number of errors of
+		     * this type. Let's disable the interrupt. But flash
+		     * a message about the interrupt being disabled.
+		     */
+		    printk(KERN_NOTICE
+			    "%s Disabling error interrupt type %s. Error count %d",
+			    pcibr_soft->bs_name,
+			    pcibr_isr_errs[i],
+			    bs_estat->bs_errcount_total);
+		    disable_errintr_mask |= (1 << i);
+		}
+	    }
+	}
+    }
+
+    if (disable_errintr_mask) {
+	/*
+	 * Disable some high frequency errors as they
+	 * could eat up too much cpu time.
+	 */
+	bridge->b_int_enable &= ~disable_errintr_mask;
+    }
+    /*
+     * If we leave the PROM cacheable, T5 might
+     * try to do a cache line sized writeback to it,
+     * which will cause a BRIDGE_ISR_INVLD_ADDR.
+     */
+    if ((err_status & BRIDGE_ISR_INVLD_ADDR) &&
+	(0x00000000 == bridge->b_wid_err_upper) &&
+	(0x00C00000 == (0xFFC00000 & bridge->b_wid_err_lower)) &&
+	(0x00402000 == (0x00F07F00 & bridge->b_wid_err_cmdword))) {
+	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
+    }
+#if defined (PCIBR_LLP_CONTROL_WAR)
+    /*
+     * The bridge bug, where the llp_config or control registers
+     * need to be read back after being written, affects an MP
+     * system since there could be small windows between writing
+     * the register and reading it back on one cpu while another
+     * cpu is fielding an interrupt. If we run into this scenario,
+     * workaround the problem by ignoring the error. (bug 454474)
+     * pcibr_llp_control_war_cnt keeps an approximate number of
+     * times we saw this problem on a system.
+     */
+
+    if ((err_status & BRIDGE_ISR_INVLD_ADDR) &&
+	((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower))
+	 == (BRIDGE_INT_RST_STAT & 0xff0))) {
+#if 0
+	if (kdebug)
+	    printk(KERN_NOTICE "%s bridge: ignoring llp/control address interrupt",
+		    pcibr_soft->bs_name);
+#endif
+	pcibr_llp_control_war_cnt++;
+	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
+    }
+#endif				/* PCIBR_LLP_CONTROL_WAR */
+
+#ifdef EHE_ENABLE
+    /* Check if this is the RESP_XTALK_ERROR interrupt. 
+     * This can happen due to a failed DMA READ operation.
+     */
+    if (err_status & BRIDGE_ISR_RESP_XTLK_ERR) {
+	/* Phase 1 : Look at the error state in the bridge and further
+	 * down in the device layers.
+	 */
+	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_LOOKUP);
+	IOERROR_SETVALUE(&ioe, widgetnum, pcibr_soft->bs_xid);
+	(void)pcibr_error_handler((error_handler_arg_t)pcibr_soft,
+				  error_code,
+				  mode,
+				  &ioe);
+	/* Phase 2 : Perform the action agreed upon in phase 1.
+	 */
+	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_ACTION);
+	rv = pcibr_error_handler((error_handler_arg_t)pcibr_soft,
+				 error_code,
+				 mode,
+				 &ioe);
+    }
+    if (rv != IOERROR_HANDLED) {
+#endif /* EHE_ENABLE */
+
+    /* Dump/Log Bridge error interrupt info */
+    if (err_status & bridge_errors_to_dump) {
+	printk("BRIDGE ERR_STATUS 0x%x\n", err_status);
+	pcibr_error_dump(pcibr_soft);
+    }
+
+    if (err_status & BRIDGE_ISR_ERROR_FATAL) {
+	machine_error_dump("");
+	cmn_err_tag(14, CE_PANIC, "PCI Bridge Error interrupt killed the system");
+	    /*NOTREACHED */
+    }
+
+#ifdef EHE_ENABLE
+    }
+#endif
+
+    /*
+     * We can't return without re-enabling the interrupt, since
+     * it would cause problems for devices like IOC3 (Lost
+     * interrupts ?.). So, just cleanup the interrupt, and
+     * use saved values later..
+     */
+    bridge->b_int_rst_stat = pcibr_errintr_group(int_status);
+
+    /* Zero out bserr_intstat field */
+    test_and_set_int((int *) &pcibr_soft->bs_errinfo.bserr_intstat, 0);
+}
+
+/*
+ * pcibr_addr_toslot
+ *      Given the 'pciaddr' find out which slot this address is
+ *      allocated to, and return the slot number.
+ *      While we have the info handy, construct the
+ *      function number, space code and offset as well.
+ *
+ * NOTE: if this routine is called, we don't know whether
+ * the address is in CFG, MEM, or I/O space. We have to guess.
+ * This will be the case on PIO stores, where the only way
+ * we have of getting the address is to check the Bridge, which
+ * stores the PCI address but not the space and not the xtalk
+ * address (from which we could get it).
+ */
+int
+pcibr_addr_toslot(pcibr_soft_t pcibr_soft,
+		  iopaddr_t pciaddr,
+		  pciio_space_t *spacep,
+		  iopaddr_t *offsetp,
+		  pciio_function_t *funcp)
+{
+    int                     s, f, w;
+    iopaddr_t               base;
+    size_t                  size;
+    pciio_piospace_t        piosp;
+
+    /*
+     * Check if the address is in config space
+     */
+
+    if ((pciaddr >= BRIDGE_CONFIG_BASE) && (pciaddr < BRIDGE_CONFIG_END)) {
+
+	if (pciaddr >= BRIDGE_CONFIG1_BASE)
+	    pciaddr -= BRIDGE_CONFIG1_BASE;
+	else
+	    pciaddr -= BRIDGE_CONFIG_BASE;
+
+	s = pciaddr / BRIDGE_CONFIG_SLOT_SIZE;
+	pciaddr %= BRIDGE_CONFIG_SLOT_SIZE;
+
+	if (funcp) {
+	    f = pciaddr / 0x100;
+	    pciaddr %= 0x100;
+	}
+	if (spacep)
+	    *spacep = PCIIO_SPACE_CFG;
+	if (offsetp)
+	    *offsetp = pciaddr;
+	if (funcp)
+	    *funcp = f;
+
+	return s;
+    }
+    for (s = 0; s < 8; s++) {
+	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
+	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
+
+	for (f = 0; f < nf; f++) {
+	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
+
+	    if (!pcibr_info)
+		continue;
+	    for (w = 0; w < 6; w++) {
+		if (pcibr_info->f_window[w].w_space
+		    == PCIIO_SPACE_NONE) {
+		    continue;
+		}
+		base = pcibr_info->f_window[w].w_base;
+		size = pcibr_info->f_window[w].w_size;
+
+		if ((pciaddr >= base) && (pciaddr < (base + size))) {
+		    if (spacep)
+			*spacep = PCIIO_SPACE_WIN(w);
+		    if (offsetp)
+			*offsetp = pciaddr - base;
+		    if (funcp)
+			*funcp = f;
+		    return s;
+		}			/* endif match */
+	    }				/* next window */
+	}				/* next func */
+    }					/* next slot */
+
+    /*
+     * Check if the address was allocated as part of the
+     * pcibr_piospace_alloc calls.
+     */
+    for (s = 0; s < 8; s++) {
+	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
+	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
+
+	for (f = 0; f < nf; f++) {
+	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
+
+	    if (!pcibr_info)
+		continue;
+	    piosp = pcibr_info->f_piospace;
+	    while (piosp) {
+		if ((piosp->start <= pciaddr) &&
+		    ((piosp->count + piosp->start) > pciaddr)) {
+		    if (spacep)
+			*spacep = piosp->space;
+		    if (offsetp)
+			*offsetp = pciaddr - piosp->start;
+		    return s;
+		}			/* endif match */
+		piosp = piosp->next;
+	    }				/* next piosp */
+	}				/* next func */
+    }					/* next slot */
+
+    /*
+     * Some other random address on the PCI bus ...
+     * we have no way of knowing whether this was
+     * a MEM or I/O access; so, for now, we just
+     * assume that the low 1G is MEM, the next
+     * 3G is I/O, and anything above the 4G limit
+     * is obviously MEM.
+     */
+
+    if (spacep)
+	*spacep = ((pciaddr < (1ul << 30)) ? PCIIO_SPACE_MEM :
+		   (pciaddr < (4ul << 30)) ? PCIIO_SPACE_IO :
+		   PCIIO_SPACE_MEM);
+    if (offsetp)
+	*offsetp = pciaddr;
+
+    return PCIIO_SLOT_NONE;
+
+}
+
+void
+pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code)
+{
+    bridge_t               *bridge = pcibr_soft->bs_base;
+
+    ASSERT(error_code & IOECODE_PIO);
+    error_code = error_code;
+
+    bridge->b_int_rst_stat =
+	(BRIDGE_IRR_PCI_GRP_CLR | BRIDGE_IRR_MULTI_CLR);
+    (void) bridge->b_wid_tflush;	/* flushbus */
+}
+
+/*
+ * pcibr_error_extract
+ *      Given the 'pcibr vertex handle' find out which slot
+ *      the bridge status error address (from pcibr_soft info
+ *      hanging off the vertex)
+ *      allocated to, and return the slot number.
+ *      While we have the info handy, construct the
+ *      space code and offset as well.
+ *
+ * NOTE: if this routine is called, we don't know whether
+ * the address is in CFG, MEM, or I/O space. We have to guess.
+ * This will be the case on PIO stores, where the only way
+ * we have of getting the address is to check the Bridge, which
+ * stores the PCI address but not the space and not the xtalk
+ * address (from which we could get it).
+ *
+ * XXX- this interface has no way to return the function
+ * number on a multifunction card, even though that data
+ * is available.
+ */
+
+pciio_slot_t
+pcibr_error_extract(devfs_handle_t pcibr_vhdl,
+		    pciio_space_t *spacep,
+		    iopaddr_t *offsetp)
+{
+    pcibr_soft_t            pcibr_soft = 0;
+    iopaddr_t               bserr_addr;
+    bridge_t               *bridge;
+    pciio_slot_t            slot = PCIIO_SLOT_NONE;
+    arbitrary_info_t	    rev;
+
+    /* Do a sanity check as to whether we really got a 
+     * bridge vertex handle.
+     */
+    if (hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &rev) !=
+	GRAPH_SUCCESS) 
+	return(slot);
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    if (pcibr_soft) {
+	bridge = pcibr_soft->bs_base;
+	bserr_addr =
+	    bridge->b_pci_err_lower |
+	    ((uint64_t) (bridge->b_pci_err_upper &
+			   BRIDGE_ERRUPPR_ADDRMASK) << 32);
+
+	slot = pcibr_addr_toslot(pcibr_soft, bserr_addr,
+				 spacep, offsetp, NULL);
+    }
+    return slot;
+}
+
+/*ARGSUSED */
+void
+pcibr_device_disable(pcibr_soft_t pcibr_soft, int devnum)
+{
+    /*
+     * XXX
+     * Device failed to handle error. Take steps to
+     * disable this device ? HOW TO DO IT ?
+     *
+     * If there are any Read response buffers associated
+     * with this device, it's time to get them back!!
+     *
+     * We can disassociate any interrupt level associated
+     * with this device, and disable that interrupt level
+     *
+     * For now it's just a place holder
+     */
+}
+
+/*
+ * pcibr_pioerror
+ *      Handle PIO error that happened at the bridge pointed by pcibr_soft.
+ *
+ *      Queries the Bus interface attached to see if the device driver
+ *      mapping the device-number that caused error can handle the
+ *      situation. If so, it will clean up any error, and return
+ *      indicating the error was handled. If the device driver is unable
+ *      to handle the error, it expects the bus-interface to disable that
+ *      device, and takes any steps needed here to take away any resources
+ *      associated with this device.
+ */
+
+#define BEM_ADD_STR(s)	printk("%s", (s))
+#define BEM_ADD_VAR(v)	printk("\t%20s: 0x%x\n", #v, (v))
+#define BEM_ADD_REG(r)	printk("\t%20s: %R\n", #r, (r), r ## _desc)
+
+#define BEM_ADD_NSPC(n,s)	printk("\t%20s: %R\n", n, s, space_desc)
+#define BEM_ADD_SPC(s)		BEM_ADD_NSPC(#s, s)
+
+/* BEM_ADD_IOE doesn't dump the whole ioerror, it just
+ * decodes the PCI specific portions -- we count on our
+ * callers to dump the raw IOE data.
+ */
+#define BEM_ADD_IOE(ioe)						\
+	do {								\
+	    if (IOERROR_FIELDVALID(ioe, busspace)) {			\
+		unsigned		spc;				\
+		unsigned		win;				\
+									\
+		spc = IOERROR_GETVALUE(ioe, busspace);			\
+		win = spc - PCIIO_SPACE_WIN(0);				\
+									\
+		switch (spc) {						\
+		case PCIIO_SPACE_CFG:					\
+		    printk(					\
+			    "\tPCI Slot %d Func %d CFG space Offset 0x%x\n",	\
+	    pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, widgetdev)),	\
+	    pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, widgetdev)),	\
+			    IOERROR_GETVALUE(ioe, busaddr));		\
+		    break;						\
+		case PCIIO_SPACE_IO:					\
+		    printk(					\
+			    "\tPCI I/O space  Offset 0x%x\n",		\
+			    IOERROR_GETVALUE(ioe, busaddr));		\
+		    break;						\
+		case PCIIO_SPACE_MEM:					\
+		case PCIIO_SPACE_MEM32:					\
+		case PCIIO_SPACE_MEM64:					\
+		    printk(					\
+			    "\tPCI MEM space Offset 0x%x\n",		\
+			    IOERROR_GETVALUE(ioe, busaddr));		\
+		    break;						\
+		default:						\
+		    if (win < 6) {					\
+		    printk(					\
+			    "\tPCI Slot %d Func %d Window %d Offset 0x%x\n",\
+	    pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, widgetdev)),	\
+	    pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, widgetdev)),	\
+			    win,					\
+			    IOERROR_GETVALUE(ioe, busaddr));		\
+		    }							\
+		    break;						\
+		}							\
+	    }								\
+	} while (0)
+
+/*ARGSUSED */
+int
+pcibr_pioerror(
+		  pcibr_soft_t pcibr_soft,
+		  int error_code,
+		  ioerror_mode_t mode,
+		  ioerror_t *ioe)
+{
+    int                     retval = IOERROR_HANDLED;
+
+    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+
+    iopaddr_t               bad_xaddr;
+
+    pciio_space_t           raw_space;	/* raw PCI space */
+    iopaddr_t               raw_paddr;	/* raw PCI address */
+
+    pciio_space_t           space;	/* final PCI space */
+    pciio_slot_t            slot;	/* final PCI slot, if appropriate */
+    pciio_function_t        func;	/* final PCI func, if appropriate */
+    iopaddr_t               offset;	/* final PCI offset */
+    
+    int                     cs, cw, cf;
+    pciio_space_t           wx;
+    iopaddr_t               wb;
+    size_t                  ws;
+    iopaddr_t               wl;
+
+
+    /*
+     * We expect to have an "xtalkaddr" coming in,
+     * and need to construct the slot/space/offset.
+     */
+
+    bad_xaddr = IOERROR_GETVALUE(ioe, xtalkaddr);
+
+    slot = PCIIO_SLOT_NONE;
+    func = PCIIO_FUNC_NONE;
+    raw_space = PCIIO_SPACE_NONE;
+    raw_paddr = 0;
+
+    if ((bad_xaddr >= BRIDGE_TYPE0_CFG_DEV0) &&
+	(bad_xaddr < BRIDGE_TYPE1_CFG)) {
+	raw_paddr = bad_xaddr - BRIDGE_TYPE0_CFG_DEV0;
+	slot = raw_paddr / BRIDGE_TYPE0_CFG_SLOT_OFF;
+	raw_paddr = raw_paddr % BRIDGE_TYPE0_CFG_SLOT_OFF;
+	raw_space = PCIIO_SPACE_CFG;
+    }
+    if ((bad_xaddr >= BRIDGE_TYPE1_CFG) &&
+	(bad_xaddr < (BRIDGE_TYPE1_CFG + 0x1000))) {
+	/* Type 1 config space:
+	 * slot and function numbers not known.
+	 * Perhaps we can read them back?
+	 */
+	raw_paddr = bad_xaddr - BRIDGE_TYPE1_CFG;
+	raw_space = PCIIO_SPACE_CFG;
+    }
+    if ((bad_xaddr >= BRIDGE_DEVIO0) &&
+	(bad_xaddr < BRIDGE_DEVIO(BRIDGE_DEV_CNT))) {
+	int                     x;
+
+	raw_paddr = bad_xaddr - BRIDGE_DEVIO0;
+	x = raw_paddr / BRIDGE_DEVIO_OFF;
+	raw_paddr %= BRIDGE_DEVIO_OFF;
+	/* first two devio windows are double-sized */
+	if ((x == 1) || (x == 3))
+	    raw_paddr += BRIDGE_DEVIO_OFF;
+	if (x > 0)
+	    x--;
+	if (x > 1)
+	    x--;
+	/* x is which devio reg; no guarantee
+	 * PCI slot x will be responding.
+	 * still need to figure out who decodes
+	 * space/offset on the bus.
+	 */
+	raw_space = pcibr_soft->bs_slot[x].bss_devio.bssd_space;
+	if (raw_space == PCIIO_SPACE_NONE) {
+	    /* Someone got an error because they
+	     * accessed the PCI bus via a DevIO(x)
+	     * window that pcibr has not yet assigned
+	     * to any specific PCI address. It is
+	     * quite possible that the Device(x)
+	     * register has been changed since they
+	     * made their access, but we will give it
+	     * our best decode shot.
+	     */
+	    raw_space = pcibr_soft->bs_slot[x].bss_device
+		& BRIDGE_DEV_DEV_IO_MEM
+		? PCIIO_SPACE_MEM
+		: PCIIO_SPACE_IO;
+	    raw_paddr +=
+		(pcibr_soft->bs_slot[x].bss_device &
+		 BRIDGE_DEV_OFF_MASK) <<
+		BRIDGE_DEV_OFF_ADDR_SHFT;
+	} else
+	    raw_paddr += pcibr_soft->bs_slot[x].bss_devio.bssd_base;
+    }
+    if ((bad_xaddr >= BRIDGE_PCI_MEM32_BASE) &&
+	(bad_xaddr <= BRIDGE_PCI_MEM32_LIMIT)) {
+	raw_space = PCIIO_SPACE_MEM32;
+	raw_paddr = bad_xaddr - BRIDGE_PCI_MEM32_BASE;
+    }
+    if ((bad_xaddr >= BRIDGE_PCI_MEM64_BASE) &&
+	(bad_xaddr <= BRIDGE_PCI_MEM64_LIMIT)) {
+	raw_space = PCIIO_SPACE_MEM64;
+	raw_paddr = bad_xaddr - BRIDGE_PCI_MEM64_BASE;
+    }
+    if ((bad_xaddr >= BRIDGE_PCI_IO_BASE) &&
+	(bad_xaddr <= BRIDGE_PCI_IO_LIMIT)) {
+	raw_space = PCIIO_SPACE_IO;
+	raw_paddr = bad_xaddr - BRIDGE_PCI_IO_BASE;
+    }
+    space = raw_space;
+    offset = raw_paddr;
+
+    if ((slot == PCIIO_SLOT_NONE) && (space != PCIIO_SPACE_NONE)) {
+	/* we've got a space/offset but not which
+	 * PCI slot decodes it. Check through our
+	 * notions of which devices decode where.
+	 *
+	 * Yes, this "duplicates" some logic in
+	 * pcibr_addr_toslot; the difference is,
+	 * this code knows which space we are in,
+	 * and can really really tell what is
+	 * going on (no guessing).
+	 */
+
+	for (cs = 0; (cs < 8) && (slot == PCIIO_SLOT_NONE); cs++) {
+	    int                     nf = pcibr_soft->bs_slot[cs].bss_ninfo;
+	    pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[cs].bss_infos;
+
+	    for (cf = 0; (cf < nf) && (slot == PCIIO_SLOT_NONE); cf++) {
+		pcibr_info_t            pcibr_info = pcibr_infoh[cf];
+
+		if (!pcibr_info)
+		    continue;
+		for (cw = 0; (cw < 6) && (slot == PCIIO_SLOT_NONE); ++cw) {
+		    if (((wx = pcibr_info->f_window[cw].w_space) != PCIIO_SPACE_NONE) &&
+			((wb = pcibr_info->f_window[cw].w_base) != 0) &&
+			((ws = pcibr_info->f_window[cw].w_size) != 0) &&
+			((wl = wb + ws) > wb) &&
+			((wb <= offset) && (wl > offset))) {
+			/* MEM, MEM32 and MEM64 need to
+			 * compare as equal ...
+			 */
+			if ((wx == space) ||
+			    (((wx == PCIIO_SPACE_MEM) ||
+			      (wx == PCIIO_SPACE_MEM32) ||
+			      (wx == PCIIO_SPACE_MEM64)) &&
+			     ((space == PCIIO_SPACE_MEM) ||
+			      (space == PCIIO_SPACE_MEM32) ||
+			      (space == PCIIO_SPACE_MEM64)))) {
+			    slot = cs;
+			    func = cf;
+			    space = PCIIO_SPACE_WIN(cw);
+			    offset -= wb;
+			}		/* endif window space match */
+		    }			/* endif window valid and addr match */
+		}			/* next window unless slot set */
+	    }				/* next func unless slot set */
+	}				/* next slot unless slot set */
+	/* XXX- if slot is still -1, no PCI devices are
+	 * decoding here using their standard PCI BASE
+	 * registers. This would be a really good place
+	 * to cross-coordinate with the pciio PCI
+	 * address space allocation routines, to find
+	 * out if this address is "allocated" by any of
+	 * our subsidiary devices.
+	 */
+    }
+    /* Scan all piomap records on this PCI bus to update
+     * the TimeOut Counters on all matching maps. If we
+     * don't already know the slot number, take it from
+     * the first matching piomap. Note that we have to
+     * compare maps against raw_space and raw_paddr
+     * since space and offset could already be
+     * window-relative.
+     *
+     * There is a chance that one CPU could update
+     * through this path, and another CPU could also
+     * update due to an interrupt. Closing this hole
+     * would only result in the possibility of some
+     * errors never getting logged at all, and since the
+     * use for bp_toc is as a logical test rather than a
+     * strict count, the excess counts are not a
+     * problem.
+     */
+    for (cs = 0; cs < 8; ++cs) {
+	int 		nf = pcibr_soft->bs_slot[cs].bss_ninfo;
+	pcibr_info_h	pcibr_infoh = pcibr_soft->bs_slot[cs].bss_infos;
+
+	for (cf = 0; cf < nf; cf++) {
+	    pcibr_info_t 	pcibr_info = pcibr_infoh[cf];
+	    pcibr_piomap_t	map;    
+
+	    if (!pcibr_info)
+		continue;
+
+	    for (map = pcibr_info->f_piomap;
+	     map != NULL; map = map->bp_next) {
+	    wx = map->bp_space;
+	    wb = map->bp_pciaddr;
+	    ws = map->bp_mapsz;
+	    cw = wx - PCIIO_SPACE_WIN(0);
+	    if (cw < 6) {
+		wb += pcibr_soft->bs_slot[cs].bss_window[cw].bssw_base;
+		wx = pcibr_soft->bs_slot[cs].bss_window[cw].bssw_space;
+	    }
+	    if (wx == PCIIO_SPACE_ROM) {
+		wb += pcibr_info->f_rbase;
+		wx = PCIIO_SPACE_MEM;
+	    }
+	    if ((wx == PCIIO_SPACE_MEM32) ||
+		(wx == PCIIO_SPACE_MEM64))
+		wx = PCIIO_SPACE_MEM;
+	    wl = wb + ws;
+	    if ((wx == raw_space) && (raw_paddr >= wb) && (raw_paddr < wl)) {
+		atomicAddInt(map->bp_toc, 1);
+		if (slot == PCIIO_SLOT_NONE) {
+		    slot = cs;
+		    space = map->bp_space;
+		    if (cw < 6)
+			offset -= pcibr_soft->bs_slot[cs].bss_window[cw].bssw_base;
+		}
+	    }
+	    }
+	}
+    }
+
+    if (space != PCIIO_SPACE_NONE) {
+	if (slot != PCIIO_SLOT_NONE) 
+	    if (func != PCIIO_FUNC_NONE)
+		IOERROR_SETVALUE(ioe, widgetdev, 
+				 pciio_widgetdev_create(slot,func));
+	    else
+    		IOERROR_SETVALUE(ioe, widgetdev, 
+				 pciio_widgetdev_create(slot,0));
+
+	IOERROR_SETVALUE(ioe, busspace, space);
+	IOERROR_SETVALUE(ioe, busaddr, offset);
+    }
+    if (mode == MODE_DEVPROBE) {
+	/*
+	 * During probing, we don't really care what the
+	 * error is. Clean up the error in Bridge, notify
+	 * subsidiary devices, and return success.
+	 */
+	pcibr_error_cleanup(pcibr_soft, error_code);
+
+	/* if appropriate, give the error handler for this slot
+	 * a shot at this probe access as well.
+	 */
+	return (slot == PCIIO_SLOT_NONE) ? IOERROR_HANDLED :
+	    pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
+    }
+    /*
+     * If we don't know what "PCI SPACE" the access
+     * was targeting, we may have problems at the
+     * Bridge itself. Don't touch any bridge registers,
+     * and do complain loudly.
+     */
+
+    if (space == PCIIO_SPACE_NONE) {
+	printk("XIO Bus Error at %s\n"
+		"\taccess to XIO bus offset 0x%x\n"
+		"\tdoes not correspond to any PCI address\n",
+		pcibr_soft->bs_name, bad_xaddr);
+
+	/* caller will dump contents of ioe struct */
+	return IOERROR_XTALKLEVEL;
+    }
+
+    /*
+     * Actual PCI Error handling situation.
+     * Typically happens when a user level process accesses
+     * PCI space, and it causes some error.
+     *
+     * Due to PCI Bridge implementation, we get two indication
+     * for a read error: an interrupt and a Bus error.
+     * We like to handle read error in the bus error context.
+     * But the interrupt comes and goes before bus error
+     * could make much progress. (NOTE: interrupd does
+     * come in _after_ bus error processing starts. But it's
+     * completed by the time bus error code reaches PCI PIO
+     * error handling.
+     * Similarly write error results in just an interrupt,
+     * and error handling has to be done at interrupt level.
+     * There is no way to distinguish at interrupt time, if an
+     * error interrupt is due to read/write error..
+     */
+
+    /* We know the xtalk addr, the raw PCI bus space,
+     * the raw PCI bus address, the decoded PCI bus
+     * space, the offset within that space, and the
+     * decoded PCI slot (which may be "PCIIO_SLOT_NONE" if no slot
+     * is known to be involved).
+     */
+
+    /*
+     * Hand the error off to the handler registered
+     * for the slot that should have decoded the error,
+     * or to generic PCI handling (if pciio decides that
+     * such is appropriate).
+     */
+    retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
+
+    if (retval != IOERROR_HANDLED) {
+
+	/* Generate a generic message for IOERROR_UNHANDLED
+	 * since the subsidiary handlers were silent, and
+	 * did no recovery.
+	 */
+	if (retval == IOERROR_UNHANDLED) {
+	    retval = IOERROR_PANIC;
+
+	    /* we may or may not want to print some of this,
+	     * depending on debug level and which error code.
+	     */
+
+	    printk(KERN_ALERT
+		    "PIO Error on PCI Bus %s",
+		    pcibr_soft->bs_name);
+	    /* this decodes part of the ioe; our caller
+	     * will dump the raw details in DEBUG and
+	     * kdebug kernels.
+	     */
+	    BEM_ADD_IOE(ioe);
+	}
+#if defined(FORCE_ERRORS)
+	if (0) {
+#elif !DEBUG
+	if (kdebug) {
+#endif
+	    /*
+	     * Dump raw data from Bridge/PCI layer.
+	     */
+
+	    BEM_ADD_STR("Raw info from Bridge/PCI layer:\n");
+	    if (bridge->b_int_status & BRIDGE_ISR_PCIBUS_PIOERR)
+		pcibr_error_dump(pcibr_soft);
+	    BEM_ADD_SPC(raw_space);
+	    BEM_ADD_VAR(raw_paddr);
+	    if (IOERROR_FIELDVALID(ioe, widgetdev)) {
+
+		slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, 
+								 widgetdev));
+		func = pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, 
+								 widgetdev));
+		if (slot < 8) {
+		    bridgereg_t             device = bridge->b_device[slot].reg;
+
+		    BEM_ADD_VAR(slot);
+		    BEM_ADD_VAR(func);
+		    BEM_ADD_REG(device);
+		}
+	    }
+#if !DEBUG || defined(FORCE_ERRORS)
+	}
+#endif
+
+	/*
+	 * Since error could not be handled at lower level,
+	 * error data logged has not  been cleared.
+	 * Clean up errors, and
+	 * re-enable bridge to interrupt on error conditions.
+	 * NOTE: Wheather we get the interrupt on PCI_ABORT or not is
+	 * dependent on INT_ENABLE register. This write just makes sure
+	 * that if the interrupt was enabled, we do get the interrupt.
+	 *
+	 * CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges
+	 *      a group of interrupts. If while handling this error,
+	 *      some other error has occured, that would be
+	 *      implicitly cleared by this write.
+	 *      Need a way to ensure we don't inadvertently clear some
+	 *      other errors.
+	 */
+	if (IOERROR_FIELDVALID(ioe, widgetdev))
+	    pcibr_device_disable(pcibr_soft, 
+				 pciio_widgetdev_slot_get(
+					  IOERROR_GETVALUE(ioe, widgetdev)));
+
+	if (mode == MODE_DEVUSERERROR)
+	    pcibr_error_cleanup(pcibr_soft, error_code);
+    }
+    return retval;
+}
+
+/*
+ * bridge_dmaerror
+ *      Some error was identified in a DMA transaction.
+ *      This routine will identify the <device, address> that caused the error,
+ *      and try to invoke the appropriate bus service to handle this.
+ */
+
+#define BRIDGE_DMA_READ_ERROR (BRIDGE_ISR_RESP_XTLK_ERR|BRIDGE_ISR_XREAD_REQ_TIMEOUT)
+
+int
+pcibr_dmard_error(
+		     pcibr_soft_t pcibr_soft,
+		     int error_code,
+		     ioerror_mode_t mode,
+		     ioerror_t *ioe)
+{
+    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    bridgereg_t             bus_lowaddr, bus_uppraddr;
+    int                     retval = 0;
+    int                     bufnum;
+
+    /*
+     * In case of DMA errors, bridge should have logged the
+     * address that caused the error.
+     * Look up the address, in the bridge error registers, and
+     * take appropriate action
+     */
+    ASSERT(IOERROR_GETVALUE(ioe, widgetnum) == pcibr_soft->bs_xid);
+    ASSERT(bridge);
+
+    /*
+     * read error log registers
+     */
+    bus_lowaddr = bridge->b_wid_resp_lower;
+    bus_uppraddr = bridge->b_wid_resp_upper;
+
+    bufnum = BRIDGE_RESP_ERRUPPR_BUFNUM(bus_uppraddr);
+    IOERROR_SETVALUE(ioe, widgetdev, 
+		     pciio_widgetdev_create(
+				    BRIDGE_RESP_ERRUPPR_DEVICE(bus_uppraddr),
+				    0));
+    IOERROR_SETVALUE(ioe, busaddr,
+		     (bus_lowaddr |
+		      ((iopaddr_t)
+		       (bus_uppraddr &
+			BRIDGE_ERRUPPR_ADDRMASK) << 32)));
+
+    /*
+     * need to ensure that the xtalk adress in ioe
+     * maps to PCI error address read from bridge.
+     * How to convert PCI address back to Xtalk address ?
+     * (better idea: convert XTalk address to PCI address
+     * and then do the compare!)
+     */
+
+    retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
+    if (retval != IOERROR_HANDLED)
+	pcibr_device_disable(pcibr_soft, 
+			     pciio_widgetdev_slot_get(
+				      IOERROR_GETVALUE(ioe,widgetdev)));
+
+    /*
+     * Re-enable bridge to interrupt on BRIDGE_IRR_RESP_BUF_GRP_CLR
+     * NOTE: Wheather we get the interrupt on BRIDGE_IRR_RESP_BUF_GRP_CLR or
+     * not is dependent on INT_ENABLE register. This write just makes sure
+     * that if the interrupt was enabled, we do get the interrupt.
+     */
+    bridge->b_int_rst_stat = BRIDGE_IRR_RESP_BUF_GRP_CLR;
+
+    /*
+     * Also, release the "bufnum" back to buffer pool that could be re-used.
+     * This is done by "disabling" the buffer for a moment, then restoring
+     * the original assignment.
+     */
+
+    {
+	reg_p                   regp;
+	bridgereg_t             regv;
+	bridgereg_t             mask;
+
+	regp = (bufnum & 1)
+	    ? &bridge->b_odd_resp
+	    : &bridge->b_even_resp;
+
+	mask = 0xF << ((bufnum >> 1) * 4);
+
+	regv = *regp;
+	*regp = regv & ~mask;
+	*regp = regv;
+    }
+
+    return retval;
+}
+
+/*
+ * pcibr_dmawr_error:
+ *      Handle a dma write error caused by a device attached to this bridge.
+ *
+ *      ioe has the widgetnum, widgetdev, and memaddr fields updated
+ *      But we don't know the PCI address that corresponds to "memaddr"
+ *      nor do we know which device driver is generating this address.
+ *
+ *      There is no easy way to find out the PCI address(es) that map
+ *      to a specific system memory address. Bus handling code is also
+ *      of not much help, since they don't keep track of the DMA mapping
+ *      that have been handed out.
+ *      So it's a dead-end at this time.
+ *
+ *      If translation is available, we could invoke the error handling
+ *      interface of the device driver.
+ */
+/*ARGSUSED */
+int
+pcibr_dmawr_error(
+		     pcibr_soft_t pcibr_soft,
+		     int error_code,
+		     ioerror_mode_t mode,
+		     ioerror_t *ioe)
+{
+    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    int                     retval;
+
+    retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
+
+    if (retval != IOERROR_HANDLED) {
+	pcibr_device_disable(pcibr_soft, 
+			     pciio_widgetdev_slot_get(
+				      IOERROR_GETVALUE(ioe, widgetdev)));
+
+    }
+    return retval;
+}
+
+/*
+ * Bridge error handler.
+ *      Interface to handle all errors that involve bridge in some way.
+ *
+ *      This normally gets called from xtalk error handler.
+ *      ioe has different set of fields set depending on the error that
+ *      was encountered. So, we have a bit field indicating which of the
+ *      fields are valid.
+ *
+ * NOTE: This routine could be operating in interrupt context. So,
+ *      don't try to sleep here (till interrupt threads work!!)
+ */
+int
+pcibr_error_handler(
+		       error_handler_arg_t einfo,
+		       int error_code,
+		       ioerror_mode_t mode,
+		       ioerror_t *ioe)
+{
+    pcibr_soft_t            pcibr_soft;
+    int                     retval = IOERROR_BADERRORCODE;
+
+#ifdef EHE_ENABLE
+    devfs_handle_t	    xconn_vhdl,pcibr_vhdl;
+    error_state_t	    e_state;
+#endif /* EHE_ENABLE */
+
+    pcibr_soft = (pcibr_soft_t) einfo;
+
+#ifdef EHE_ENABLE
+    xconn_vhdl = pcibr_soft->bs_conn;
+    pcibr_vhdl = pcibr_soft->bs_vhdl;
+
+    e_state = error_state_get(xconn_vhdl);
+    
+    if (error_state_set(pcibr_vhdl, e_state) == 
+	ERROR_RETURN_CODE_CANNOT_SET_STATE)
+	return(IOERROR_UNHANDLED);
+
+    /* If we are in the action handling phase clean out the error state
+     * on the xswitch.
+     */
+    if (e_state == ERROR_STATE_ACTION)
+	(void)error_state_set(xconn_vhdl, ERROR_STATE_NONE);
+#endif /* EHE_ENABLE */
+
+#if DEBUG && ERROR_DEBUG
+    printk("%s: pcibr_error_handler\n", pcibr_soft->bs_name);
+#endif
+
+    ASSERT(pcibr_soft != NULL);
+
+    if (error_code & IOECODE_PIO)
+	retval = pcibr_pioerror(pcibr_soft, error_code, mode, ioe);
+
+    if (error_code & IOECODE_DMA) {
+	if (error_code & IOECODE_READ) {
+	    /*
+	     * DMA read error occurs when a device attached to the bridge
+	     * tries to read some data from system memory, and this
+	     * either results in a timeout or access error.
+	     * First case is indicated by the bit "XREAD_REQ_TOUT"
+	     * and second case by "RESP_XTALK_ERROR" bit in bridge error
+	     * interrupt status register.
+	     *
+	     * pcibr_error_intr_handler would get invoked first, and it has
+	     * the responsibility of calling pcibr_error_handler with
+	     * suitable parameters.
+	     */
+
+	    retval = pcibr_dmard_error(pcibr_soft, error_code, MODE_DEVERROR, ioe);
+	}
+	if (error_code & IOECODE_WRITE) {
+	    /*
+	     * A device attached to this bridge has been generating
+	     * bad DMA writes. Find out the device attached, and
+	     * slap on it's wrist.
+	     */
+
+	    retval = pcibr_dmawr_error(pcibr_soft, error_code, MODE_DEVERROR, ioe);
+	}
+    }
+    return retval;
+
+}
+
+/*
+ * Reenable a device after handling the error.
+ * This is called by the lower layers when they wish to be reenabled
+ * after an error.
+ * Note that each layer would be calling the previous layer to reenable
+ * first, before going ahead with their own re-enabling.
+ */
+
+int
+pcibr_error_devenable(devfs_handle_t pconn_vhdl, int error_code)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+    ASSERT(error_code & IOECODE_PIO);
+
+    /* If the error is not known to be a write,
+     * we have to call devenable.
+     * write errors are isolated to the bridge.
+     */
+    if (!(error_code & IOECODE_WRITE)) {
+	devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+	int                     rc;
+
+	rc = xtalk_error_devenable(xconn_vhdl, pciio_slot, error_code);
+	if (rc != IOERROR_HANDLED)
+	    return rc;
+    }
+    pcibr_error_cleanup(pcibr_soft, error_code);
+    return IOERROR_HANDLED;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,204 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+pcibr_hints_t           pcibr_hints_get(devfs_handle_t, int);
+void                    pcibr_hints_fix_rrbs(devfs_handle_t);
+void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
+void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
+void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
+void                    pcibr_hints_handsoff(devfs_handle_t);
+void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t);
+
+pcibr_hints_t
+pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
+{
+    arbitrary_info_t        ainfo = 0;
+    graph_error_t	    rv;
+    pcibr_hints_t           hint;
+
+    rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
+
+    if (alloc && (rv != GRAPH_SUCCESS)) {
+
+	NEW(hint);
+	hint->rrb_alloc_funct = NULL;
+	hint->ph_intr_bits = NULL;
+	rv = hwgraph_info_add_LBL(xconn_vhdl, 
+				  INFO_LBL_PCIBR_HINTS, 	
+				  (arbitrary_info_t) hint);
+	if (rv != GRAPH_SUCCESS)
+	    goto abnormal_exit;
+
+	rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
+	
+	if (rv != GRAPH_SUCCESS)
+	    goto abnormal_exit;
+
+	if (ainfo != (arbitrary_info_t) hint)
+	    goto abnormal_exit;
+    }
+    return (pcibr_hints_t) ainfo;
+
+abnormal_exit:
+#ifdef LATER
+    printf("SHOULD NOT BE HERE\n");
+#endif
+    DEL(hint);
+    return(NULL);
+
+}
+
+void
+pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->ph_rrb_fixed = mask;
+#if DEBUG
+    else
+	printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n"
+		"\t%p\n", xconn_vhdl);
+#endif
+}
+
+void
+pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
+{
+    pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
+}
+
+void
+pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
+		     pciio_slot_t host,
+		     pciio_slot_t guest)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->ph_host_slot[guest] = host + 1;
+#if DEBUG
+    else
+	printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n"
+		"\t%p\n", xconn_vhdl);
+#endif
+}
+
+void
+pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
+		      pcibr_intr_bits_f *xxx_intr_bits)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->ph_intr_bits = xxx_intr_bits;
+#if DEBUG
+    else
+	printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n"
+	       "\t%p\n", xconn_vhdl);
+#endif
+}
+
+void
+pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->rrb_alloc_funct = rrb_alloc_funct;
+}
+
+void
+pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
+{
+    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
+
+    if (hint)
+	hint->ph_hands_off = 1;
+#if DEBUG
+    else
+	printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n"
+		"\t%p\n", xconn_vhdl);
+#endif
+}
+
+void
+pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
+		    pciio_slot_t slot,
+		    uint64_t subdevs)
+{
+    arbitrary_info_t        ainfo = 0;
+    char                    sdname[16];
+    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
+
+    sprintf(sdname, "pci/%d", slot);
+    (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
+    if (pconn_vhdl == GRAPH_VERTEX_NONE) {
+#if DEBUG
+	printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n"
+		"\t%p (seeking %s)\n", xconn_vhdl, sdname);
+#endif
+	return;
+    }
+    hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
+    if (ainfo == 0) {
+	uint64_t                *subdevp;
+
+	NEW(subdevp);
+	if (!subdevp) {
+#if DEBUG
+	    printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n"
+		    "\t%p\n", pconn_vhdl);
+#endif
+	    return;
+	}
+	*subdevp = subdevs;
+	hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
+	hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
+	if (ainfo == (arbitrary_info_t) subdevp)
+	    return;
+	DEL(subdevp);
+	if (ainfo == (arbitrary_info_t) NULL) {
+#if DEBUG
+	    printk("pcibr_hints_subdevs: null subdevs ptr at\n"
+		    "\t%p\n", pconn_vhdl);
+#endif
+	    return;
+	}
+#if DEBUG
+	printk("pcibr_subdevs_get: dup subdev add_LBL at\n"
+		"\t%p\n", pconn_vhdl);
+#endif
+    }
+    *(uint64_t *) ainfo = subdevs;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,147 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+#ifdef LATER
+
+char *pci_space[] = {"NONE", 
+		     "ROM",
+		     "IO",
+		     "",
+		     "MEM",
+		     "MEM32",
+		     "MEM64",
+		     "CFG",
+		     "WIN0",
+		     "WIN1",
+		     "WIN2",
+		     "WIN3",
+		     "WIN4",
+		     "WIN5",
+		     "",
+		     "BAD"};
+
+void
+idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
+{
+    pcibr_info_t	pcibr_info = pcibr_infoh[func];
+    char		name[MAXDEVNAME];
+    int			win;
+    
+    if (!pcibr_info)
+	return;
+    qprintf("Per-slot Function Info\n");
+    sprintf(name, "%v", pcibr_info->f_vertex);
+    qprintf("\tSlot Name : %s\n",name);
+    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
+    qprintf("Slot : %d ", pcibr_info->f_slot);
+    qprintf("Function : %d ", pcibr_info->f_func);
+    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
+    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
+    sprintf(name, "%v", pcibr_info->f_master);
+    qprintf("\tBus provider : %s\n",name);
+    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
+    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
+	    pcibr_info->f_efunc,pcibr_info->f_einfo);
+    for(win = 0 ; win < 6 ; win++) 
+	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
+		win,pci_space[pcibr_info->f_window[win].w_space],
+		pcibr_info->f_window[win].w_base,
+		pcibr_info->f_window[win].w_size);
+
+    qprintf("\tRom base 0x%x size 0x%x\n", 
+	    pcibr_info->f_rbase,pcibr_info->f_rsize);
+
+    qprintf("\tInterrupt Bit Map\n");
+    qprintf("\t\tPCI Int#\tBridge Pin#\n");
+    for (win = 0 ; win < 4; win++)
+	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
+    qprintf("\n");
+}
+
+
+void
+idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
+{
+    pcibr_soft_slot_t	pss;
+    char		slot_conn_name[MAXDEVNAME];
+    int			func;
+
+    pss = &pcibr_soft->bs_slot[slot];
+    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
+    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
+    qprintf("\tHost Slot : %d\n",pss->host_slot);
+    sprintf(slot_conn_name, "%v", pss->slot_conn);
+    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
+    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
+    for (func = 0; func < pss->bss_ninfo; func++)
+	idbg_pss_func(pss->bss_infos,func);
+    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
+    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
+    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
+    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
+	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
+    
+    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
+	    "d32_base 0x%x d32_flags 0x%x\n",
+	    pss->bss_d64_base, pss->bss_d64_flags,
+	    pss->bss_d32_base, pss->bss_d32_flags);
+    
+    qprintf("\tExt ATEs active ? %s", 
+	    pss->bss_ext_ates_active ? "yes" : "no");
+    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
+    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
+
+    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
+	    pcibr_soft->bs_rrb_valid[slot],
+	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+	    pcibr_soft->bs_rrb_res[slot]);
+		
+}
+
+int	ips = 0;
+
+void
+idbg_pss(pcibr_soft_t pcibr_soft)
+{
+    pciio_slot_t	slot;
+
+    
+    if (ips >= 0 && ips < 8)
+	idbg_pss_info(pcibr_soft,ips);
+    else if (ips < 0)
+	for (slot = 0; slot < 8; slot++) 
+	    idbg_pss_info(pcibr_soft,slot);
+    else
+	qprintf("Invalid ips %d\n",ips);
+}
+#endif	/* LATER */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,907 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+#ifdef __ia64
+#define rmallocmap atemapalloc
+#define rmfreemap atemapfree
+#define rmfree atefree
+#define rmalloc atealloc
+#endif
+
+unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines);
+pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+void                    pcibr_intr_free(pcibr_intr_t);
+void              pcibr_setpciint(xtalk_intr_t);
+int                     pcibr_intr_connect(pcibr_intr_t);
+void                    pcibr_intr_disconnect(pcibr_intr_t);
+
+devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
+void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
+void                    pcibr_intr_func(intr_arg_t);
+
+extern pcibr_info_t      pcibr_info_get(devfs_handle_t);
+
+/* =====================================================================
+ *    INTERRUPT MANAGEMENT
+ */
+
+unsigned
+pcibr_intr_bits(pciio_info_t info,
+		pciio_intr_line_t lines)
+{
+    pciio_slot_t            slot = pciio_info_slot_get(info);
+    unsigned		    bbits = 0;
+
+    /*
+     * Currently favored mapping from PCI
+     * slot number and INTA/B/C/D to Bridge
+     * PCI Interrupt Bit Number:
+     *
+     *     SLOT     A B C D
+     *      0       0 4 0 4
+     *      1       1 5 1 5
+     *      2       2 6 2 6
+     *      3       3 7 3 7
+     *      4       4 0 4 0
+     *      5       5 1 5 1
+     *      6       6 2 6 2
+     *      7       7 3 7 3
+     */
+
+    if (slot < 8) {
+	if (lines & (PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_C))
+	    bbits |= 1 << slot;
+	if (lines & (PCIIO_INTR_LINE_B| PCIIO_INTR_LINE_D))
+	    bbits |= 1 << (slot ^ 4);
+    }
+    return bbits;
+}
+
+
+/*
+ *	Get the next wrapper pointer queued in the interrupt circular buffer.
+ */
+pcibr_intr_wrap_t
+pcibr_wrap_get(pcibr_intr_cbuf_t cbuf)
+{
+    pcibr_intr_wrap_t	wrap;
+
+	if (cbuf->ib_in == cbuf->ib_out)
+	    PRINT_PANIC( "pcibr intr circular buffer empty, cbuf=0x%p, ib_in=ib_out=%d\n",
+		(void *)cbuf, cbuf->ib_out);
+
+	wrap = cbuf->ib_cbuf[cbuf->ib_out++];
+	cbuf->ib_out = cbuf->ib_out % IBUFSIZE;
+	return(wrap);
+}
+
+/* 
+ *	Queue a wrapper pointer in the interrupt circular buffer.
+ */
+void
+pcibr_wrap_put(pcibr_intr_wrap_t wrap, pcibr_intr_cbuf_t cbuf)
+{
+	int	in;
+	int	s;
+
+	/*
+	 * Multiple CPUs could be executing this code simultaneously
+	 * if a handler has registered multiple interrupt lines and
+	 * the interrupts are directed to different CPUs.
+	 */
+	s = mutex_spinlock(&cbuf->ib_lock);
+	in = (cbuf->ib_in + 1) % IBUFSIZE;
+	if (in == cbuf->ib_out) 
+	    PRINT_PANIC( "pcibr intr circular buffer full, cbuf=0x%p, ib_in=%d\n",
+		(void *)cbuf, cbuf->ib_in);
+
+	cbuf->ib_cbuf[cbuf->ib_in] = wrap;
+	cbuf->ib_in = in;
+	mutex_spinunlock(&cbuf->ib_lock, s);
+	return;
+}
+
+/*
+ *	There are end cases where a deadlock can occur if interrupt 
+ *	processing completes and the Bridge b_int_status bit is still set.
+ *
+ *	One scenerio is if a second PCI interrupt occurs within 60ns of
+ *	the previous interrupt being cleared. In this case the Bridge
+ *	does not detect the transition, the Bridge b_int_status bit
+ *	remains set, and because no transition was detected no interrupt
+ *	packet is sent to the Hub/Heart.
+ *
+ *	A second scenerio is possible when a b_int_status bit is being
+ *	shared by multiple devices:
+ *						Device #1 generates interrupt
+ *						Bridge b_int_status bit set
+ *						Device #2 generates interrupt
+ *		interrupt processing begins
+ *		  ISR for device #1 runs and
+ *			clears interrupt
+ *						Device #1 generates interrupt
+ *		  ISR for device #2 runs and
+ *			clears interrupt
+ *						(b_int_status bit still set)
+ *		interrupt processing completes
+ *		  
+ *	Interrupt processing is now complete, but an interrupt is still
+ *	outstanding for Device #1. But because there was no transition of
+ *	the b_int_status bit, no interrupt packet will be generated and
+ *	a deadlock will occur.
+ *
+ *	To avoid these deadlock situations, this function is used
+ *	to check if a specific Bridge b_int_status bit is set, and if so,
+ *	cause the setting of the corresponding interrupt bit.
+ *
+ *	On a XBridge (IP35), we do this by writing the appropriate Bridge Force 
+ *	Interrupt register.
+ */
+void
+pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
+{
+	unsigned	bit;
+	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
+	bridge_t       *bridge = pcibr_soft->bs_base;
+	cpuid_t cpuvertex_to_cpuid(devfs_handle_t vhdl);
+
+	bit = wrap->iw_intr;
+
+	if (pcibr_soft->bs_xbridge) {
+	    bridge->b_force_pin[bit].intr = 1;
+	} else if ((1 << bit) & *wrap->iw_stat) {
+	    cpuid_t	    cpu;
+	    unsigned        intr_bit;
+	    xtalk_intr_t    xtalk_intr =
+				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
+
+	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
+	    cpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
+#if defined(CONFIG_IA64_SGI_SN1)
+	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
+#endif
+	}
+}
+
+/*ARGSUSED */
+pcibr_intr_t
+pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
+		 device_desc_t dev_desc,
+		 pciio_intr_line_t lines,
+		 devfs_handle_t owner_dev)
+{
+    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pcibr_info->f_slot;
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
+    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    int                     is_threaded = 0;
+    int                     thread_swlevel;
+
+    xtalk_intr_t           *xtalk_intr_p;
+    pcibr_intr_t           *pcibr_intr_p;
+    pcibr_intr_list_t      *intr_list_p;
+
+    unsigned                pcibr_int_bits;
+    unsigned                pcibr_int_bit;
+    xtalk_intr_t            xtalk_intr = (xtalk_intr_t)0;
+    hub_intr_t		    hub_intr;
+    pcibr_intr_t            pcibr_intr;
+    pcibr_intr_list_t       intr_entry;
+    pcibr_intr_list_t       intr_list;
+    bridgereg_t             int_dev;
+
+#if DEBUG && INTR_DEBUG
+    printk("%v: pcibr_intr_alloc\n"
+	    "%v:%s%s%s%s%s\n",
+	    owner_dev, pconn_vhdl,
+	    !(lines & 15) ? " No INTs?" : "",
+	    lines & 1 ? " INTA" : "",
+	    lines & 2 ? " INTB" : "",
+	    lines & 4 ? " INTC" : "",
+	    lines & 8 ? " INTD" : "");
+#endif
+
+    NEW(pcibr_intr);
+    if (!pcibr_intr)
+	return NULL;
+
+    if (dev_desc) {
+	cpuid_t intr_target_from_desc(device_desc_t, int);
+    } else {
+	extern int default_intr_pri;
+
+	is_threaded = 1; /* PCI interrupts are threaded, by default */
+	thread_swlevel = default_intr_pri;
+    }
+
+    pcibr_intr->bi_dev = pconn_vhdl;
+    pcibr_intr->bi_lines = lines;
+    pcibr_intr->bi_soft = pcibr_soft;
+    pcibr_intr->bi_ibits = 0;		/* bits will be added below */
+    pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD;
+    pcibr_intr->bi_mustruncpu = CPU_NONE;
+    pcibr_intr->bi_ibuf.ib_in = 0;
+    pcibr_intr->bi_ibuf.ib_out = 0;
+    mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock);
+
+    pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines);
+
+
+    /*
+     * For each PCI interrupt line requested, figure
+     * out which Bridge PCI Interrupt Line it maps
+     * to, and make sure there are xtalk resources
+     * allocated for it.
+     */
+#if DEBUG && INTR_DEBUG
+    printk("pcibr_int_bits: 0x%X\n", pcibr_int_bits);
+#endif 
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit ++) {
+	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
+	    xtalk_intr_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
+
+	    xtalk_intr = *xtalk_intr_p;
+
+	    if (xtalk_intr == NULL) {
+		/*
+		 * This xtalk_intr_alloc is constrained for two reasons:
+		 * 1) Normal interrupts and error interrupts need to be delivered
+		 *    through a single xtalk target widget so that there aren't any
+		 *    ordering problems with DMA, completion interrupts, and error
+		 *    interrupts. (Use of xconn_vhdl forces this.)
+		 *
+		 * 2) On IP35, addressing constraints on IP35 and Bridge force
+		 *    us to use a single PI number for all interrupts from a
+		 *    single Bridge. (IP35-specific code forces this, and we
+		 *    verify in pcibr_setwidint.)
+		 */
+
+		/*
+		 * All code dealing with threaded PCI interrupt handlers
+		 * is located at the pcibr level. Because of this,
+		 * we always want the lower layers (hub/heart_intr_alloc, 
+		 * intr_level_connect) to treat us as non-threaded so we
+		 * don't set up a duplicate threaded environment. We make
+		 * this happen by calling a special xtalk interface.
+		 */
+		xtalk_intr = xtalk_intr_alloc_nothd(xconn_vhdl, dev_desc, 
+			owner_dev);
+#if DEBUG && INTR_DEBUG
+		printk("%v: xtalk_intr=0x%X\n", xconn_vhdl, xtalk_intr);
+#endif
+
+		/* both an assert and a runtime check on this:
+		 * we need to check in non-DEBUG kernels, and
+		 * the ASSERT gets us more information when
+		 * we use DEBUG kernels.
+		 */
+		ASSERT(xtalk_intr != NULL);
+		if (xtalk_intr == NULL) {
+		    /* it is quite possible that our
+		     * xtalk_intr_alloc failed because
+		     * someone else got there first,
+		     * and we can find their results
+		     * in xtalk_intr_p.
+		     */
+		    if (!*xtalk_intr_p) {
+#ifdef SUPPORT_PRINTING_V_FORMAT
+			printk(KERN_ALERT  
+				"pcibr_intr_alloc %v: unable to get xtalk interrupt resources",
+				xconn_vhdl);
+#else
+			printk(KERN_ALERT  
+				"pcibr_intr_alloc 0x%p: unable to get xtalk interrupt resources",
+				(void *)xconn_vhdl);
+#endif
+			/* yes, we leak resources here. */
+			return 0;
+		    }
+		} else if (compare_and_swap_ptr((void **) xtalk_intr_p, NULL, xtalk_intr)) {
+		    /*
+		     * now tell the bridge which slot is
+		     * using this interrupt line.
+		     */
+		    int_dev = bridge->b_int_device;
+		    int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
+		    int_dev |= pciio_slot << BRIDGE_INT_DEV_SHFT(pcibr_int_bit);
+		    bridge->b_int_device = int_dev;	/* XXXMP */
+
+#if DEBUG && INTR_DEBUG
+		    printk("%v: bridge intr bit %d clears my wrb\n",
+			    pconn_vhdl, pcibr_int_bit);
+#endif
+		} else {
+		    /* someone else got one allocated first;
+		     * free the one we just created, and
+		     * retrieve the one they allocated.
+		     */
+		    xtalk_intr_free(xtalk_intr);
+		    xtalk_intr = *xtalk_intr_p;
+#if PARANOID
+		    /* once xtalk_intr is set, we never clear it,
+		     * so if the CAS fails above, this condition
+		     * can "never happen" ...
+		     */
+		    if (!xtalk_intr) {
+			printk(KERN_ALERT  
+				"pcibr_intr_alloc %v: unable to set xtalk interrupt resources",
+				xconn_vhdl);
+			/* yes, we leak resources here. */
+			return 0;
+		    }
+#endif
+		}
+	    }
+
+	    pcibr_intr->bi_ibits |= 1 << pcibr_int_bit;
+
+	    NEW(intr_entry);
+	    intr_entry->il_next = NULL;
+	    intr_entry->il_intr = pcibr_intr;
+	    intr_entry->il_wrbf = &(bridge->b_wr_req_buf[pciio_slot].reg);
+	    intr_list_p = 
+		&pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
+#if DEBUG && INTR_DEBUG
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+	    printk("0x%x: Bridge bit %d wrap=0x%x\n",
+		pconn_vhdl, pcibr_int_bit,
+		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
+#else
+	    printk("%v: Bridge bit %d wrap=0x%x\n",
+		pconn_vhdl, pcibr_int_bit,
+		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
+#endif
+#endif
+
+	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
+		/* we are the first interrupt on this bridge bit.
+		 */
+#if DEBUG && INTR_DEBUG
+		printk("%v INT 0x%x (bridge bit %d) allocated [FIRST]\n",
+			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		continue;
+	    }
+	    intr_list = *intr_list_p;
+	    pcibr_intr_p = &intr_list->il_intr;
+	    if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
+		/* first entry on list was erased,
+		 * and we replaced it, so we
+		 * don't need our intr_entry.
+		 */
+		DEL(intr_entry);
+#if DEBUG && INTR_DEBUG
+		printk("%v INT 0x%x (bridge bit %d) replaces erased first\n",
+			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		continue;
+	    }
+	    intr_list_p = &intr_list->il_next;
+	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
+		/* we are the new second interrupt on this bit.
+		 */
+		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared = 1;
+#if DEBUG && INTR_DEBUG
+		printk("%v INT 0x%x (bridge bit %d) is new SECOND\n",
+			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		continue;
+	    }
+	    while (1) {
+		pcibr_intr_p = &intr_list->il_intr;
+		if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
+		    /* an entry on list was erased,
+		     * and we replaced it, so we
+		     * don't need our intr_entry.
+		     */
+		    DEL(intr_entry);
+#if DEBUG && INTR_DEBUG
+		    printk("%v INT 0x%x (bridge bit %d) replaces erased Nth\n",
+			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		    break;
+		}
+		intr_list_p = &intr_list->il_next;
+		if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
+		    /* entry appended to share list
+		     */
+#if DEBUG && INTR_DEBUG
+		    printk("%v INT 0x%x (bridge bit %d) is new Nth\n",
+			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
+#endif
+		    break;
+		}
+		/* step to next record in chain
+		 */
+		intr_list = *intr_list_p;
+	    }
+	}
+    }
+
+#if DEBUG && INTR_DEBUG
+    printk("%v pcibr_intr_alloc complete\n", pconn_vhdl);
+#endif
+    hub_intr = (hub_intr_t)xtalk_intr;
+    pcibr_intr->bi_irq = hub_intr->i_bit;
+    pcibr_intr->bi_cpu = hub_intr->i_cpuid;
+    return pcibr_intr;
+}
+
+/*ARGSUSED */
+void
+pcibr_intr_free(pcibr_intr_t pcibr_intr)
+{
+    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
+    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
+    unsigned                pcibr_int_bit;
+    pcibr_intr_list_t       intr_list;
+    int			    intr_shared;
+    xtalk_intr_t	    *xtalk_intrp;
+
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) {
+	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
+	    for (intr_list = 
+		     pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
+		 intr_list != NULL;
+		 intr_list = intr_list->il_next)
+		if (compare_and_swap_ptr((void **) &intr_list->il_intr, 
+					 pcibr_intr, 
+					 NULL)) {
+#if DEBUG && INTR_DEBUG
+		    printk("%s: cleared a handler from bit %d\n",
+			    pcibr_soft->bs_name, pcibr_int_bit);
+#endif
+		}
+	    /* If this interrupt line is not being shared between multiple
+	     * devices release the xtalk interrupt resources.
+	     */
+	    intr_shared = 
+		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared;
+	    xtalk_intrp = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
+
+	    if ((!intr_shared) && (*xtalk_intrp)) {
+
+		bridge_t 	*bridge = pcibr_soft->bs_base;
+		bridgereg_t	int_dev;
+
+		xtalk_intr_free(*xtalk_intrp);
+		*xtalk_intrp = 0;
+
+		/* Clear the PCI device interrupt to bridge interrupt pin
+		 * mapping.
+		 */
+		int_dev = bridge->b_int_device;
+		int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
+		bridge->b_int_device = int_dev;
+
+	    }
+	}
+    }
+    DEL(pcibr_intr);
+}
+
+void
+pcibr_setpciint(xtalk_intr_t xtalk_intr)
+{
+    iopaddr_t               addr = xtalk_intr_addr_get(xtalk_intr);
+    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(xtalk_intr);
+    bridgereg_t            *int_addr = (bridgereg_t *)
+    xtalk_intr_sfarg_get(xtalk_intr);
+
+    *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
+		 (BRIDGE_INT_ADDR_FLD & vect));
+}
+
+/*ARGSUSED */
+int
+pcibr_intr_connect(pcibr_intr_t pcibr_intr)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
+    unsigned                pcibr_int_bit;
+    bridgereg_t             b_int_enable;
+    unsigned long           s;
+
+    if (pcibr_intr == NULL)
+	return -1;
+
+#if DEBUG && INTR_DEBUG
+    printk("%v: pcibr_intr_connect\n",
+	    pcibr_intr->bi_dev);
+#endif
+
+    *((volatile unsigned *)&pcibr_intr->bi_flags) |= PCIIO_INTR_CONNECTED;
+
+    /*
+     * For each PCI interrupt line requested, figure
+     * out which Bridge PCI Interrupt Line it maps
+     * to, and make sure there are xtalk resources
+     * allocated for it.
+     */
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
+	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
+	    xtalk_intr_t            xtalk_intr;
+
+	    xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
+
+	    /*
+	     * If this interrupt line is being shared and the connect has
+	     * already been done, no need to do it again.
+	     */
+	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected)
+		continue;
+
+
+	    /*
+	     * Use the pcibr wrapper function to handle all Bridge interrupts
+	     * regardless of whether the interrupt line is shared or not.
+	     */
+	    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t) pcibr_setpciint,
+			       (void *)&(bridge->b_int_addr[pcibr_int_bit].addr));
+	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 1;
+
+#if DEBUG && INTR_DEBUG
+	    printk("%v bridge bit %d wrapper connected\n",
+		    pcibr_intr->bi_dev, pcibr_int_bit);
+#endif
+	}
+    s = pcibr_lock(pcibr_soft);
+    b_int_enable = bridge->b_int_enable;
+    b_int_enable |= pcibr_int_bits;
+    bridge->b_int_enable = b_int_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    pcibr_unlock(pcibr_soft, s);
+
+    return 0;
+}
+
+/*ARGSUSED */
+void
+pcibr_intr_disconnect(pcibr_intr_t pcibr_intr)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
+    unsigned                pcibr_int_bit;
+    bridgereg_t             b_int_enable;
+    unsigned long           s;
+
+    /* Stop calling the function. Now.
+     */
+    *((volatile unsigned *)&pcibr_intr->bi_flags) &= ~PCIIO_INTR_CONNECTED;
+
+    /*
+     * For each PCI interrupt line requested, figure
+     * out which Bridge PCI Interrupt Line it maps
+     * to, and disconnect the interrupt.
+     */
+
+    /* don't disable interrupts for lines that
+     * are shared between devices.
+     */
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
+	if ((pcibr_int_bits & (1 << pcibr_int_bit)) &&
+	    (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared))
+	    pcibr_int_bits &= ~(1 << pcibr_int_bit);
+    if (!pcibr_int_bits)
+	return;
+
+    s = pcibr_lock(pcibr_soft);
+    b_int_enable = bridge->b_int_enable;
+    b_int_enable &= ~pcibr_int_bits;
+    bridge->b_int_enable = b_int_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+    pcibr_unlock(pcibr_soft, s);
+
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
+	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
+	    /* if the interrupt line is now shared,
+	     * do not disconnect it.
+	     */
+	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
+		continue;
+
+	    xtalk_intr_disconnect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
+	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 0;
+
+#if DEBUG && INTR_DEBUG
+	    printk("%s: xtalk disconnect done for Bridge bit %d\n",
+		pcibr_soft->bs_name, pcibr_int_bit);
+#endif
+
+	    /* if we are sharing the interrupt line,
+	     * connect us up; this closes the hole
+	     * where the another pcibr_intr_alloc()
+	     * was in progress as we disconnected.
+	     */
+	    if (!pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
+		continue;
+
+	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
+			       (xtalk_intr_setfunc_t)pcibr_setpciint,
+			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr));
+	}
+}
+
+/*ARGSUSED */
+devfs_handle_t
+pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
+    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
+    unsigned                pcibr_int_bit;
+
+    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
+	if (pcibr_int_bits & (1 << pcibr_int_bit))
+	    return xtalk_intr_cpu_get(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
+    return 0;
+}
+
+/* =====================================================================
+ *    INTERRUPT HANDLING
+ */
+void
+pcibr_clearwidint(bridge_t *bridge)
+{
+    bridge->b_wid_int_upper = 0;
+    bridge->b_wid_int_lower = 0;
+}
+
+
+void
+pcibr_setwidint(xtalk_intr_t intr)
+{
+    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
+    iopaddr_t               addr = xtalk_intr_addr_get(intr);
+    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
+    widgetreg_t		    NEW_b_wid_int_upper, NEW_b_wid_int_lower;
+    widgetreg_t		    OLD_b_wid_int_upper, OLD_b_wid_int_lower;
+
+    bridge_t               *bridge = (bridge_t *)xtalk_intr_sfarg_get(intr);
+
+    NEW_b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
+			       XTALK_ADDR_TO_UPPER(addr));
+    NEW_b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
+
+    OLD_b_wid_int_upper = bridge->b_wid_int_upper;
+    OLD_b_wid_int_lower = bridge->b_wid_int_lower;
+
+    /* Verify that all interrupts from this Bridge are using a single PI */
+    if ((OLD_b_wid_int_upper != 0) && (OLD_b_wid_int_lower != 0)) {
+	/*
+	 * Once set, these registers shouldn't change; they should
+	 * be set multiple times with the same values.
+	 *
+	 * If we're attempting to change these registers, it means
+	 * that our heuristics for allocating interrupts in a way
+	 * appropriate for IP35 have failed, and the admin needs to
+	 * explicitly direct some interrupts (or we need to make the
+	 * heuristics more clever).
+	 *
+	 * In practice, we hope this doesn't happen very often, if
+	 * at all.
+	 */
+	if ((OLD_b_wid_int_upper != NEW_b_wid_int_upper) ||
+	    (OLD_b_wid_int_lower != NEW_b_wid_int_lower)) {
+		printk(KERN_WARNING  "Interrupt allocation is too complex.\n");
+		printk(KERN_WARNING  "Use explicit administrative interrupt targetting.\n");
+		printk(KERN_WARNING  "bridge=0x%lx targ=0x%x\n", (unsigned long)bridge, targ);
+		printk(KERN_WARNING  "NEW=0x%x/0x%x  OLD=0x%x/0x%x\n",
+			NEW_b_wid_int_upper, NEW_b_wid_int_lower,
+			OLD_b_wid_int_upper, OLD_b_wid_int_lower);
+		PRINT_PANIC("PCI Bridge interrupt targetting error\n");
+	}
+    }
+
+    bridge->b_wid_int_upper = NEW_b_wid_int_upper;
+    bridge->b_wid_int_lower = NEW_b_wid_int_lower;
+    bridge->b_int_host_err = vect;
+}
+
+/*
+ * pcibr_intr_preset: called during mlreset time
+ * if the platform specific code needs to route
+ * one of the Bridge's xtalk interrupts before the
+ * xtalk infrastructure is available.
+ */
+void
+pcibr_xintr_preset(void *which_widget,
+		   int which_widget_intr,
+		   xwidgetnum_t targ,
+		   iopaddr_t addr,
+		   xtalk_intr_vector_t vect)
+{
+    bridge_t               *bridge = (bridge_t *) which_widget;
+
+    if (which_widget_intr == -1) {
+	/* bridge widget error interrupt */
+	bridge->b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
+				   XTALK_ADDR_TO_UPPER(addr));
+	bridge->b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
+	bridge->b_int_host_err = vect;
+
+	/* turn on all interrupts except
+	 * the PCI interrupt requests,
+	 * at least at heart.
+	 */
+	bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK;
+
+    } else {
+	/* routing a PCI device interrupt.
+	 * targ and low 38 bits of addr must
+	 * be the same as the already set
+	 * value for the widget error interrupt.
+	 */
+	bridge->b_int_addr[which_widget_intr].addr =
+	    ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
+	     (BRIDGE_INT_ADDR_FLD & vect));
+	/*
+	 * now bridge can let it through;
+	 * NB: still should be blocked at
+	 * xtalk provider end, until the service
+	 * function is set.
+	 */
+	bridge->b_int_enable |= 1 << vect;
+    }
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+}
+
+
+/*
+ * pcibr_intr_func()
+ *
+ * This is the pcibr interrupt "wrapper" function that is called,
+ * in interrupt context, to initiate the interrupt handler(s) registered
+ * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
+ * handlers will be called directly, and threaded handlers will have their 
+ * thread woken up.
+ */
+void
+pcibr_intr_func(intr_arg_t arg)
+{
+    pcibr_intr_wrap_t       wrap = (pcibr_intr_wrap_t) arg;
+    reg_p                   wrbf;
+    pcibr_intr_t            intr;
+    pcibr_intr_list_t       list;
+    int                     clearit;
+    int			    do_nonthreaded = 1;
+    int			    is_threaded = 0;
+    int			    x = 0;
+
+	/*
+	 * If any handler is still running from a previous interrupt
+	 * just return. If there's a need to call the handler(s) again,
+	 * another interrupt will be generated either by the device or by
+	 * pcibr_force_interrupt().
+	 */
+
+	if (wrap->iw_hdlrcnt) {
+		return;
+	}
+
+    /*
+     * Call all interrupt handlers registered.
+     * First, the pcibr_intrd threads for any threaded handlers will be
+     * awoken, then any non-threaded handlers will be called sequentially.
+     */
+	
+	clearit = 1;
+	while (do_nonthreaded) {
+	    for (list = wrap->iw_list; list != NULL; list = list->il_next) {
+		if ((intr = list->il_intr) &&
+		    (intr->bi_flags & PCIIO_INTR_CONNECTED)) {
+
+		/*
+		 * This device may have initiated write
+		 * requests since the bridge last saw
+		 * an edge on this interrupt input; flushing
+		 * the buffer prior to invoking the handler
+		 * should help but may not be sufficient if we 
+		 * get more requests after the flush, followed
+		 * by the card deciding it wants service, before
+		 * the interrupt handler checks to see if things need
+		 * to be done.
+		 *
+		 * There is a similar race condition if
+		 * an interrupt handler loops around and
+		 * notices further service is required.
+		 * Perhaps we need to have an explicit
+		 * call that interrupt handlers need to
+		 * do between noticing that DMA to memory
+		 * has completed, but before observing the
+		 * contents of memory?
+		 */
+
+			if ((do_nonthreaded) && (!is_threaded)) {
+			/* Non-threaded. 
+			 * Call the interrupt handler at interrupt level
+			 */
+
+			/* Only need to flush write buffers if sharing */
+
+			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
+			    if ((x = *wrbf))	/* write request buffer flush */
+#ifdef SUPPORT_PRINTING_V_FORMAT
+				printk(KERN_ALERT  "pcibr_intr_func %v: \n"
+				    "write buffer flush failed, wrbf=0x%x\n", 
+				    list->il_intr->bi_dev, wrbf);
+#else
+				printk(KERN_ALERT  "pcibr_intr_func %p: \n"
+				    "write buffer flush failed, wrbf=0x%lx\n", 
+				    (void *)list->il_intr->bi_dev, (long) wrbf);
+#endif
+			}
+		    }
+
+		    clearit = 0;
+		}
+	    }
+
+		do_nonthreaded = 0;
+		/*
+		 * If the non-threaded handler was the last to complete,
+		 * (i.e., no threaded handlers still running) force an
+		 * interrupt to avoid a potential deadlock situation.
+		 */
+		if (wrap->iw_hdlrcnt == 0) {
+			pcibr_force_interrupt(wrap);
+		}
+	}
+
+	/* If there were no handlers,
+	 * disable the interrupt and return.
+	 * It will get enabled again after
+	 * a handler is connected.
+	 * If we don't do this, we would
+	 * sit here and spin through the
+	 * list forever.
+	 */
+	if (clearit) {
+	    pcibr_soft_t            pcibr_soft = wrap->iw_soft;
+	    bridge_t               *bridge = pcibr_soft->bs_base;
+	    bridgereg_t             b_int_enable;
+	    bridgereg_t		    mask = 1 << wrap->iw_intr;
+	    unsigned long           s;
+
+	    s = pcibr_lock(pcibr_soft);
+	    b_int_enable = bridge->b_int_enable;
+	    b_int_enable &= ~mask;
+	    bridge->b_int_enable = b_int_enable;
+	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
+	    pcibr_unlock(pcibr_soft, s);
+	    return;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,896 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+void              do_pcibr_rrb_clear(bridge_t *, int);
+void              do_pcibr_rrb_flush(bridge_t *, int);
+int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t);
+int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
+int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int);
+int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int);
+
+void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int);
+
+int		  pcibr_wrb_flush(devfs_handle_t);
+int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
+int               pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
+int               pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int);
+void              pcibr_rrb_flush(devfs_handle_t);
+int		  pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+
+/* 
+ *    RRB Management
+ */
+
+#define LSBIT(word)		((word) &~ ((word)-1))
+
+void
+do_pcibr_rrb_clear(bridge_t *bridge, int rrb)
+{
+    bridgereg_t             status;
+
+    /* bridge_lock must be held;
+     * this RRB must be disabled.
+     */
+
+    /* wait until RRB has no outstanduing XIO packets. */
+    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
+	;				/* XXX- beats on bridge. bad idea? */
+    }
+
+    /* if the RRB has data, drain it. */
+    if (status & BRIDGE_RRB_VALID(rrb)) {
+	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
+
+	/* wait until RRB is no longer valid. */
+	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
+	    ;				/* XXX- beats on bridge. bad idea? */
+	}
+    }
+}
+
+void
+do_pcibr_rrb_flush(bridge_t *bridge, int rrbn)
+{
+    reg_p                   rrbp = &bridge->b_rrb_map[rrbn & 1].reg;
+    bridgereg_t             rrbv;
+    int                     shft = 4 * (rrbn >> 1);
+    unsigned                ebit = BRIDGE_RRB_EN << shft;
+
+    rrbv = *rrbp;
+    if (rrbv & ebit)
+	*rrbp = rrbv & ~ebit;
+
+    do_pcibr_rrb_clear(bridge, rrbn);
+
+    if (rrbv & ebit)
+	*rrbp = rrbv;
+}
+
+/*
+ *    pcibr_rrb_count_valid: count how many RRBs are
+ *      marked valid for the specified PCI slot on this
+ *      bridge.
+ *
+ *      NOTE: The "slot" parameter for all pcibr_rrb
+ *      management routines must include the "virtual"
+ *      bit; when manageing both the normal and the
+ *      virtual channel, separate calls to these
+ *      routines must be made. To denote the virtual
+ *      channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot
+ *      number.
+ *
+ *      IMPL NOTE: The obvious algorithm is to iterate
+ *      through the RRB fields, incrementing a count if
+ *      the RRB is valid and matches the slot. However,
+ *      it is much simpler to use an algorithm derived
+ *      from the "partitioned add" idea. First, XOR in a
+ *      pattern such that the fields that match this
+ *      slot come up "all ones" and all other fields
+ *      have zeros in the mismatching bits. Then AND
+ *      together the bits in the field, so we end up
+ *      with one bit turned on for each field that
+ *      matched. Now we need to count these bits. This
+ *      can be done either with a series of shift/add
+ *      instructions or by using "tmp % 15"; I expect
+ *      that the cascaded shift/add will be faster.
+ */
+
+int
+do_pcibr_rrb_count_valid(bridge_t *bridge,
+			 pciio_slot_t slot)
+{
+    bridgereg_t             tmp;
+
+    tmp = bridge->b_rrb_map[slot & 1].reg;
+    tmp ^= 0x11111111 * (7 - slot / 2);
+    tmp &= (0xCCCCCCCC & tmp) >> 2;
+    tmp &= (0x22222222 & tmp) >> 1;
+    tmp += tmp >> 4;
+    tmp += tmp >> 8;
+    tmp += tmp >> 16;
+    return tmp & 15;
+}
+
+/*
+ *    do_pcibr_rrb_count_avail: count how many RRBs are
+ *      available to be allocated for the specified slot.
+ *
+ *      IMPL NOTE: similar to the above, except we are
+ *      just counting how many fields have the valid bit
+ *      turned off.
+ */
+int
+do_pcibr_rrb_count_avail(bridge_t *bridge,
+			 pciio_slot_t slot)
+{
+    bridgereg_t             tmp;
+
+    tmp = bridge->b_rrb_map[slot & 1].reg;
+    tmp = (0x88888888 & ~tmp) >> 3;
+    tmp += tmp >> 4;
+    tmp += tmp >> 8;
+    tmp += tmp >> 16;
+    return tmp & 15;
+}
+
+/*
+ *    do_pcibr_rrb_alloc: allocate some additional RRBs
+ *      for the specified slot. Returns -1 if there were
+ *      insufficient free RRBs to satisfy the request,
+ *      or 0 if the request was fulfilled.
+ *
+ *      Note that if a request can be partially filled,
+ *      it will be, even if we return failure.
+ *
+ *      IMPL NOTE: again we avoid iterating across all
+ *      the RRBs; instead, we form up a word containing
+ *      one bit for each free RRB, then peel the bits
+ *      off from the low end.
+ */
+int
+do_pcibr_rrb_alloc(bridge_t *bridge,
+		   pciio_slot_t slot,
+		   int more)
+{
+    int                     rv = 0;
+    bridgereg_t             reg, tmp, bit;
+
+    reg = bridge->b_rrb_map[slot & 1].reg;
+    tmp = (0x88888888 & ~reg) >> 3;
+    while (more-- > 0) {
+	bit = LSBIT(tmp);
+	if (!bit) {
+	    rv = -1;
+	    break;
+	}
+	tmp &= ~bit;
+	reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2)));
+    }
+    bridge->b_rrb_map[slot & 1].reg = reg;
+    return rv;
+}
+
+/*
+ *    do_pcibr_rrb_free: release some of the RRBs that
+ *      have been allocated for the specified
+ *      slot. Returns zero for success, or negative if
+ *      it was unable to free that many RRBs.
+ *
+ *      IMPL NOTE: We form up a bit for each RRB
+ *      allocated to the slot, aligned with the VALID
+ *      bitfield this time; then we peel bits off one at
+ *      a time, releasing the corresponding RRB.
+ */
+int
+do_pcibr_rrb_free(bridge_t *bridge,
+		  pciio_slot_t slot,
+		  int less)
+{
+    int                     rv = 0;
+    bridgereg_t             reg, tmp, clr, bit;
+    int                     i;
+
+    clr = 0;
+    reg = bridge->b_rrb_map[slot & 1].reg;
+
+    /* This needs to be done otherwise the rrb's on the virtual channel
+     * for this slot won't be freed !!
+     */
+    tmp = reg & 0xbbbbbbbb;
+
+    tmp ^= (0x11111111 * (7 - slot / 2));
+    tmp &= (0x33333333 & tmp) << 2;
+    tmp &= (0x44444444 & tmp) << 1;
+    while (less-- > 0) {
+	bit = LSBIT(tmp);
+	if (!bit) {
+	    rv = -1;
+	    break;
+	}
+	tmp &= ~bit;
+	reg &= ~bit;
+	clr |= bit;
+    }
+    bridge->b_rrb_map[slot & 1].reg = reg;
+
+    for (i = 0; i < 8; i++)
+	if (clr & (8 << (4 * i)))
+	    do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1));
+
+    return rv;
+}
+
+void
+do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft,
+		       int slot,
+		       int more_rrbs)
+{
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    int                     got;
+
+    for (got = 0; got < more_rrbs; ++got) {
+	if (pcibr_soft->bs_rrb_res[slot & 7] > 0)
+	    pcibr_soft->bs_rrb_res[slot & 7]--;
+	else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
+	    pcibr_soft->bs_rrb_avail[slot & 1]--;
+	else
+	    break;
+	if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0)
+	    break;
+#if PCIBR_RRB_DEBUG
+	printk("do_pcibr_rrb_autoalloc: add one to slot %d%s\n",
+		slot & 7, slot & 8 ? "v" : "");
+#endif
+	pcibr_soft->bs_rrb_valid[slot]++;
+    }
+#if PCIBR_RRB_DEBUG
+    printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name,
+	    pcibr_soft->bs_rrb_avail[0],
+	    pcibr_soft->bs_rrb_avail[1]);
+    for (slot = 0; slot < 8; ++slot)
+	printk("\t%d+%d+%d",
+		0xFFF & pcibr_soft->bs_rrb_valid[slot],
+		0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+		pcibr_soft->bs_rrb_res[slot]);
+    printk("\n");
+#endif
+}
+
+/*
+ * Device driver interface to flush the write buffers for a specified
+ * device hanging off the bridge.
+ */
+int
+pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    volatile bridgereg_t   *wrb_flush;
+
+    wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg);
+    while (*wrb_flush);
+
+    return(0);
+}
+
+/*
+ * Device driver interface to request RRBs for a specified device
+ * hanging off a Bridge.  The driver requests the total number of
+ * RRBs it would like for the normal channel (vchan0) and for the
+ * "virtual channel" (vchan1).  The actual number allocated to each
+ * channel is returned.
+ *
+ * If we cannot allocate at least one RRB to a channel that needs
+ * at least one, return -1 (failure).  Otherwise, satisfy the request
+ * as best we can and return 0.
+ */
+int
+pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
+		int *count_vchan0,
+		int *count_vchan1)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    int                     desired_vchan0;
+    int                     desired_vchan1;
+    int                     orig_vchan0;
+    int                     orig_vchan1;
+    int                     delta_vchan0;
+    int                     delta_vchan1;
+    int                     final_vchan0;
+    int                     final_vchan1;
+    int                     avail_rrbs;
+    int                     res_rrbs;
+    unsigned long           s;
+    int                     error;
+
+    /*
+     * TBD: temper request with admin info about RRB allocation,
+     * and according to demand from other devices on this Bridge.
+     *
+     * One way of doing this would be to allocate two RRBs
+     * for each device on the bus, before any drivers start
+     * asking for extras. This has the weakness that one
+     * driver might not give back an "extra" RRB until after
+     * another driver has already failed to get one that
+     * it wanted.
+     */
+
+    s = pcibr_lock(pcibr_soft);
+
+    /* Save the boot-time RRB configuration for this slot */
+    if (pcibr_soft->bs_rrb_valid_dflt[pciio_slot] < 0) {
+        pcibr_soft->bs_rrb_valid_dflt[pciio_slot] =
+                pcibr_soft->bs_rrb_valid[pciio_slot]; 
+        pcibr_soft->bs_rrb_valid_dflt[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] =
+                pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
+        pcibr_soft->bs_rrb_res_dflt[pciio_slot] =
+                pcibr_soft->bs_rrb_res[pciio_slot];
+                  
+    }
+
+    /* How many RRBs do we own? */
+    orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot];
+    orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
+
+    /* How many RRBs do we want? */
+    desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
+    desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
+
+    /* How many RRBs are free? */
+    avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
+	+ pcibr_soft->bs_rrb_res[pciio_slot];
+
+    /* Figure desired deltas */
+    delta_vchan0 = desired_vchan0 - orig_vchan0;
+    delta_vchan1 = desired_vchan1 - orig_vchan1;
+
+    /* Trim back deltas to something
+     * that we can actually meet, by
+     * decreasing the ending allocation
+     * for whichever channel wants
+     * more RRBs. If both want the same
+     * number, cut the second channel.
+     * NOTE: do not change the allocation for
+     * a channel that was passed as NULL.
+     */
+    while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
+	if (count_vchan0 &&
+	    (!count_vchan1 ||
+	     ((orig_vchan0 + delta_vchan0) >
+	      (orig_vchan1 + delta_vchan1))))
+	    delta_vchan0--;
+	else
+	    delta_vchan1--;
+    }
+
+    /* Figure final RRB allocations
+     */
+    final_vchan0 = orig_vchan0 + delta_vchan0;
+    final_vchan1 = orig_vchan1 + delta_vchan1;
+
+    /* If either channel wants RRBs but our actions
+     * would leave it with none, declare an error,
+     * but DO NOT change any RRB allocations.
+     */
+    if ((desired_vchan0 && !final_vchan0) ||
+	(desired_vchan1 && !final_vchan1)) {
+
+	error = -1;
+
+    } else {
+
+	/* Commit the allocations: free, then alloc.
+	 */
+	if (delta_vchan0 < 0)
+	    (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0);
+	if (delta_vchan1 < 0)
+	    (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1);
+
+	if (delta_vchan0 > 0)
+	    (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0);
+	if (delta_vchan1 > 0)
+	    (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1);
+
+	/* Return final values to caller.
+	 */
+	if (count_vchan0)
+	    *count_vchan0 = final_vchan0;
+	if (count_vchan1)
+	    *count_vchan1 = final_vchan1;
+
+	/* prevent automatic changes to this slot's RRBs
+	 */
+	pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
+
+	/* Track the actual allocations, release
+	 * any further reservations, and update the
+	 * number of available RRBs.
+	 */
+
+	pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0;
+	pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1;
+	pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
+	    pcibr_soft->bs_rrb_avail[pciio_slot & 1]
+	    + pcibr_soft->bs_rrb_res[pciio_slot]
+	    - delta_vchan0
+	    - delta_vchan1;
+	pcibr_soft->bs_rrb_res[pciio_slot] = 0;
+
+        /*
+         * Reserve enough RRBs so this slot's RRB configuration can be
+         * reset to its boot-time default following a hot-plug shut-down
+         */
+        res_rrbs =   (pcibr_soft->bs_rrb_valid_dflt[pciio_slot] -
+                      pcibr_soft->bs_rrb_valid[pciio_slot]) 
+                   + (pcibr_soft->bs_rrb_valid_dflt[pciio_slot +
+                                                    PCIBR_RRB_SLOT_VIRTUAL] -
+                      pcibr_soft->bs_rrb_valid[pciio_slot +
+                                               PCIBR_RRB_SLOT_VIRTUAL])
+                   + (pcibr_soft->bs_rrb_res_dflt[pciio_slot] -
+                      pcibr_soft->bs_rrb_res[pciio_slot]);
+
+         if (res_rrbs > 0) {
+             pcibr_soft->bs_rrb_res[pciio_slot] = res_rrbs;
+             pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
+                 pcibr_soft->bs_rrb_avail[pciio_slot & 1]
+                 - res_rrbs;
+         }
+ 
+#if PCIBR_RRB_DEBUG
+	printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n",
+		pciio_slot, final_vchan0, final_vchan1,
+		pcibr_soft->bs_rrb_avail[0],
+		pcibr_soft->bs_rrb_avail[1]);
+	for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot)
+	    printk("\t%d+%d+%d",
+		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot],
+		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL],
+		    pcibr_soft->bs_rrb_res[pciio_slot]);
+	printk("\n");
+#endif
+
+	error = 0;
+    }
+
+    pcibr_unlock(pcibr_soft, s);
+
+    return error;
+}
+
+/*
+ * Device driver interface to check the current state
+ * of the RRB allocations.
+ *
+ *   pconn_vhdl is your PCI connection point (specifies which
+ *      PCI bus and which slot).
+ *
+ *   count_vchan0 points to where to return the number of RRBs
+ *      assigned to the primary DMA channel, used by all DMA
+ *      that does not explicitly ask for the alternate virtual
+ *      channel.
+ *
+ *   count_vchan1 points to where to return the number of RRBs
+ *      assigned to the secondary DMA channel, used when
+ *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
+ *
+ *   count_reserved points to where to return the number of RRBs
+ *      that have been automatically reserved for your device at
+ *      startup, but which have not been assigned to a
+ *      channel. RRBs must be assigned to a channel to be used;
+ *      this can be done either with an explicit pcibr_rrb_alloc
+ *      call, or automatically by the infrastructure when a DMA
+ *      translation is constructed. Any call to pcibr_rrb_alloc
+ *      will release any unassigned reserved RRBs back to the
+ *      free pool.
+ *
+ *   count_pool points to where to return the number of RRBs
+ *      that are currently unassigned and unreserved. This
+ *      number can (and will) change as other drivers make calls
+ *      to pcibr_rrb_alloc, or automatically allocate RRBs for
+ *      DMA beyond their initial reservation.
+ *
+ * NULL may be passed for any of the return value pointers
+ * the caller is not interested in.
+ *
+ * The return value is "0" if all went well, or "-1" if
+ * there is a problem. Additionally, if the wrong vertex
+ * is passed in, one of the subsidiary support functions
+ * could panic with a "bad pciio fingerprint."
+ */
+
+int
+pcibr_rrb_check(devfs_handle_t pconn_vhdl,
+		int *count_vchan0,
+		int *count_vchan1,
+		int *count_reserved,
+		int *count_pool)
+{
+    pciio_info_t            pciio_info;
+    pciio_slot_t            pciio_slot;
+    pcibr_soft_t            pcibr_soft;
+    unsigned long           s;
+    int                     error = -1;
+
+    if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
+	(pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
+	((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) {
+
+	s = pcibr_lock(pcibr_soft);
+
+	if (count_vchan0)
+	    *count_vchan0 =
+		pcibr_soft->bs_rrb_valid[pciio_slot];
+
+	if (count_vchan1)
+	    *count_vchan1 =
+		pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
+
+	if (count_reserved)
+	    *count_reserved =
+		pcibr_soft->bs_rrb_res[pciio_slot];
+
+	if (count_pool)
+	    *count_pool =
+		pcibr_soft->bs_rrb_avail[pciio_slot & 1];
+
+	error = 0;
+
+	pcibr_unlock(pcibr_soft, s);
+    }
+    return error;
+}
+
+/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities
+ * requested for each of the devices.  The evn_odd argument indicates whether
+ * allocation is for the odd or even rrbs. The next group of four argument
+ * pairs indicate the amount of rrbs to be assigned to each device. The first
+ * argument of each pair indicate the total number of rrbs to allocate for that
+ * device. The second argument of each pair indicates how many rrb's from the
+ * first argument should be assigned to the virtual channel. The total of all
+ * of the first arguments should be <= 8. The second argument should be <= the
+ * first argument.
+ * if even_odd = 0 the devices in order are 0, 2, 4, 6 
+ * if even_odd = 1 the devices in order are 1, 3, 5, 7
+ * returns 0 if no errors else returns -1
+ */
+
+int
+pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
+		     int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2,
+		     int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4)
+{
+    devfs_handle_t          pcibr_vhdl;
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t)0;
+    bridge_t               *bridge = NULL;
+
+    uint32_t                rrb_setting = 0;
+    int                     rrb_shift = 7;
+    uint32_t                cur_rrb;
+    int                     dev_rrbs[4];
+    int                     virt[4];
+    int                     i, j;
+    unsigned long           s;
+
+    if (GRAPH_SUCCESS ==
+	hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) {
+	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+	if (pcibr_soft)
+	    bridge = pcibr_soft->bs_base;
+	hwgraph_vertex_unref(pcibr_vhdl);
+    }
+    if (bridge == NULL)
+	bridge = (bridge_t *) xtalk_piotrans_addr
+	    (vhdl, NULL, 0, sizeof(bridge_t), 0);
+
+    even_odd &= 1;
+
+    dev_rrbs[0] = dev_1_rrbs;
+    dev_rrbs[1] = dev_2_rrbs;
+    dev_rrbs[2] = dev_3_rrbs;
+    dev_rrbs[3] = dev_4_rrbs;
+
+    virt[0] = virt1;
+    virt[1] = virt2;
+    virt[2] = virt3;
+    virt[3] = virt4;
+
+    if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) {
+	return -1;
+    }
+    if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) {
+	return -1;
+    }
+    /* walk through rrbs */
+    for (i = 0; i < 4; i++) {
+	if (virt[i]) {
+		for( j = 0; j < virt[i]; j++) {
+			cur_rrb = i | 0xc;
+			cur_rrb = cur_rrb << (rrb_shift * 4);
+			rrb_shift--;
+			rrb_setting = rrb_setting | cur_rrb;
+			dev_rrbs[i] = dev_rrbs[i] - 1;
+		}
+	}
+	for (j = 0; j < dev_rrbs[i]; j++) {
+	    cur_rrb = i | 0x8;
+	    cur_rrb = cur_rrb << (rrb_shift * 4);
+	    rrb_shift--;
+	    rrb_setting = rrb_setting | cur_rrb;
+	}
+    }
+
+    if (pcibr_soft)
+	s = pcibr_lock(pcibr_soft);
+
+    bridge->b_rrb_map[even_odd].reg = rrb_setting;
+
+    if (pcibr_soft) {
+
+	pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd;
+
+	/* since we've "FIXED" the allocations
+	 * for these slots, we probably can dispense
+	 * with tracking avail/res/valid data, but
+	 * keeping it up to date helps debugging.
+	 */
+
+	pcibr_soft->bs_rrb_avail[even_odd] =
+	    8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs);
+
+	pcibr_soft->bs_rrb_res[even_odd + 0] = 0;
+	pcibr_soft->bs_rrb_res[even_odd + 2] = 0;
+	pcibr_soft->bs_rrb_res[even_odd + 4] = 0;
+	pcibr_soft->bs_rrb_res[even_odd + 6] = 0;
+
+	pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1;
+	pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2;
+	pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3;
+	pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4;
+
+	pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1;
+	pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2;
+	pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3;
+	pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4;
+
+	pcibr_unlock(pcibr_soft, s);
+    }
+    return 0;
+}
+
+/*
+ *    pcibr_rrb_flush: chase down all the RRBs assigned
+ *      to the specified connection point, and flush
+ *      them.
+ */
+void
+pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
+{
+    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
+    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    unsigned long           s;
+    reg_p                   rrbp;
+    unsigned                rrbm;
+    int                     i;
+    int                     rrbn;
+    unsigned                sval;
+    unsigned                mask;
+
+    sval = BRIDGE_RRB_EN | (pciio_slot >> 1);
+    mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV;
+    rrbn = pciio_slot & 1;
+    rrbp = &bridge->b_rrb_map[rrbn].reg;
+
+    s = pcibr_lock(pcibr_soft);
+    rrbm = *rrbp;
+    for (i = 0; i < 8; ++i) {
+	if ((rrbm & mask) == sval)
+	    do_pcibr_rrb_flush(bridge, rrbn);
+	rrbm >>= 4;
+	rrbn += 2;
+    }
+    pcibr_unlock(pcibr_soft, s);
+}
+
+/*
+ * pcibr_slot_initial_rrb_alloc
+ *	Allocate a default number of rrbs for this slot on 
+ * 	the two channels.  This is dictated by the rrb allocation
+ * 	strategy routine defined per platform.
+ */
+
+int
+pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
+			     pciio_slot_t slot)
+{
+    pcibr_soft_t	 pcibr_soft;
+    pcibr_info_h	 pcibr_infoh;
+    pcibr_info_t	 pcibr_info;
+    bridge_t		*bridge;
+    int                  c0, c1, r;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    bridge = pcibr_soft->bs_base;
+
+    /* How may RRBs are on this slot?
+     */
+    c0 = do_pcibr_rrb_count_valid(bridge, slot);
+    c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL);
+
+#if PCIBR_RRB_DEBUG
+    printk(
+	    "pcibr_slot_initial_rrb_alloc: slot %d started with %d+%d\n",
+            slot, c0, c1);
+#endif
+
+    /* Do we really need any?
+     */
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+    pcibr_info = pcibr_infoh[0];
+    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
+	!pcibr_soft->bs_slot[slot].has_host) {
+	if (c0 > 0)
+	    do_pcibr_rrb_free(bridge, slot, c0);
+	if (c1 > 0)
+	    do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1);
+	pcibr_soft->bs_rrb_valid[slot] = 0x1000;
+	pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000;
+	return(ENODEV);
+    }
+
+    pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1;
+    pcibr_soft->bs_rrb_valid[slot] = c0;
+    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1;
+
+    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
+    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
+
+    r = 3 - (c0 + c1);
+
+    if (r > 0) {
+	pcibr_soft->bs_rrb_res[slot] = r;
+	pcibr_soft->bs_rrb_avail[slot & 1] -= r;
+    }
+
+#if PCIBR_RRB_DEBUG
+    printk("\t%d+%d+%d",
+	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
+	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+	    pcibr_soft->bs_rrb_res[slot]);
+    printk("\n");
+#endif
+
+    return(0);
+}
+
+/*
+ * pcibr_initial_rrb
+ *      Assign an equal total number of RRBs to all candidate slots, 
+ *      where the total is the sum of the number of RRBs assigned to
+ *      the normal channel, the number of RRBs assigned to the virtual
+ *      channel, and the number of RRBs assigned as reserved. 
+ *
+ *      A candidate slot is a populated slot on a non-SN1 system or 
+ *      any existing (populated or empty) slot on an SN1 system.
+ *      Empty SN1 slots need RRBs to support hot-plug operations.
+ */
+
+int
+pcibr_initial_rrb(devfs_handle_t pcibr_vhdl,
+			     pciio_slot_t first, pciio_slot_t last)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge_t               *bridge = pcibr_soft->bs_base;
+    pciio_slot_t            slot;
+    int                     c0, c1;
+    int                     have[2][3];
+    int                     res[2];
+    int                     eo;
+
+    have[0][0] = have[0][1] = have[0][2] = 0;
+    have[1][0] = have[1][1] = have[1][2] = 0;
+    res[0] = res[1] = 0;
+
+    for (slot = 0; slot < 8; ++slot) {
+        /* Initial RRB management; give back RRBs in all non-existent slots */
+        (void) pcibr_slot_initial_rrb_alloc(pcibr_vhdl, slot);
+
+        /* Base calculations only on existing slots */
+        if ((slot >= first) && (slot <= last)) {
+            c0 = pcibr_soft->bs_rrb_valid[slot];
+            c1 = pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL];
+            if ((c0 + c1) < 3)
+                have[slot & 1][c0 + c1]++;
+        }
+    }
+
+    /* Initialize even/odd slot available RRB counts */
+    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
+    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
+
+    /*
+     * Calculate reserved RRBs for slots based on current RRB usage
+     */
+    for (eo = 0; eo < 2; eo++) {
+        if ((3 * have[eo][0] + 2 * have[eo][1] + have[eo][2]) <= pcibr_soft->bs_rrb_avail[eo])
+            res[eo] = 3;
+        else if ((2 * have[eo][0] + have[eo][1]) <= pcibr_soft->bs_rrb_avail[eo])
+            res[eo] = 2;
+        else if (have[eo][0] <= pcibr_soft->bs_rrb_avail[eo])
+            res[eo] = 1;
+        else
+            res[eo] = 0;
+
+    }
+
+    /* Assign reserved RRBs to existing slots */
+    for (slot = first; slot <= last; ++slot) {
+        int                     r;
+
+        c0 = pcibr_soft->bs_rrb_valid[slot];
+        c1 = pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL];
+        r = res[slot & 1] - (c0 + c1);
+
+        if (r > 0) {
+            pcibr_soft->bs_rrb_res[slot] = r;
+            pcibr_soft->bs_rrb_avail[slot & 1] -= r;
+            }
+    }
+
+#if PCIBR_RRB_DEBUG
+    printk("%v RRB MANAGEMENT: %d+%d free\n",
+            pcibr_vhdl,
+            pcibr_soft->bs_rrb_avail[0],
+            pcibr_soft->bs_rrb_avail[1]);
+    for (slot = first; slot <= last; ++slot)
+        printk("\tslot %d: %d+%d+%d", slot,
+                0xFFF & pcibr_soft->bs_rrb_valid[slot],
+                0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
+                pcibr_soft->bs_rrb_res[slot]);
+    printk("\n");
+#endif
+
+    return 0;
+
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c linux/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
--- linux.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,1692 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+
+extern pcibr_info_t     pcibr_info_get(devfs_handle_t);
+extern int              pcibr_widget_to_bus(int);
+extern pcibr_info_t     pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
+extern void             pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
+extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+#if 0
+int pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
+#endif
+
+int pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+		 pciio_slot_t slot, int drv_flags);
+int pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+		 pciio_slot_t slot, int drv_flags);
+int pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot, int drv_flags);
+int pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *);
+void		 pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
+extern uint64_t  do_pcibr_config_get(cfg_p, unsigned, unsigned);
+
+#ifdef LATER
+int pcibr_slot_attach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,
+                int drv_flags, char *l1_msg, int *sub_errorp);
+int pcibr_slot_pwr(devfs_handle_t, pciio_slot_t, int, char *);
+int pcibr_slot_startup(devfs_handle_t, pcibr_slot_req_t);
+int pcibr_slot_shutdown(devfs_handle_t, pcibr_slot_req_t);
+void pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh, int func,
+                 pcibr_slot_func_info_resp_t funcp);
+int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot,
+                 pcibr_slot_info_resp_t respp);
+int pcibr_slot_query(devfs_handle_t, pcibr_slot_req_t);
+#endif	/* LATER */
+
+extern devfs_handle_t baseio_pci_vhdl;
+int scsi_ctlr_nums_add(devfs_handle_t, devfs_handle_t);
+
+/* For now .... */
+/*
+ * PCI Hot-Plug Capability Flags
+ */
+#define D_PCI_HOT_PLUG_ATTACH  0x200  /* Driver supports PCI hot-plug attach */
+#define D_PCI_HOT_PLUG_DETACH  0x400  /* Driver supports PCI hot-plug detach */
+
+
+/*==========================================================================
+ *	BRIDGE PCI SLOT RELATED IOCTLs
+ */
+
+#ifdef LATER
+
+/*
+ * pcibr_slot_startup
+ *	Software start-up the PCI slot.
+ */
+int
+pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+{
+    pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    pciio_slot_t                   slot = reqp->req_slot;
+    int                            error = 0;
+    char                           l1_msg[BRL1_QSIZE+1];
+    struct pcibr_slot_up_resp_s    tmp_up_resp;
+
+    /* Make sure that we are dealing with a bridge device vertex */
+    if (!pcibr_soft) {
+        return(PCI_NOT_A_BRIDGE);
+    }
+
+    /* Do not allow start-up of a slot in a shoehorn */
+    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
+       return(PCI_SLOT_IN_SHOEHORN);
+    }
+ 
+    /* Check for the valid slot */
+    if (!PCIBR_VALID_SLOT(slot))
+        return(PCI_NOT_A_SLOT);
+
+    /* Acquire update access to the bus */
+    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
+
+    if (pcibr_soft->bs_slot[slot].slot_status & SLOT_STARTUP_CMPLT) {
+        error = PCI_SLOT_ALREADY_UP;
+        goto startup_unlock;
+    }
+
+    error = pcibr_slot_attach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_ATTACH,
+                              l1_msg, &tmp_up_resp.resp_sub_errno);
+
+    strncpy(tmp_up_resp.resp_l1_msg, l1_msg, L1_QSIZE);
+    tmp_up_resp.resp_l1_msg[L1_QSIZE] = '\0';
+
+    if (COPYOUT(&tmp_up_resp, reqp->req_respp.up, reqp->req_size)) {
+        return(EFAULT);
+    }
+
+    startup_unlock:
+
+    /* Release the bus lock */
+    mrunlock(pcibr_soft->bs_bus_lock);
+
+    return(error);
+}
+
+/*
+ * pcibr_slot_shutdown
+ *	Software shut-down the PCI slot
+ */
+int
+pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+{
+    pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    bridge_t                      *bridge;
+    pciio_slot_t                   slot = reqp->req_slot;
+    int                            error = 0;
+    char                           l1_msg[BRL1_QSIZE+1];
+    struct pcibr_slot_down_resp_s  tmp_down_resp;
+    pciio_slot_t                   tmp_slot;
+
+    /* Make sure that we are dealing with a bridge device vertex */
+    if (!pcibr_soft) {
+        return(PCI_NOT_A_BRIDGE);
+    }
+
+    bridge = pcibr_soft->bs_base;
+
+    /* Check for valid slot */
+    if (!PCIBR_VALID_SLOT(slot))
+        return(PCI_NOT_A_SLOT);
+
+    /* Do not allow shut-down of a slot in a shoehorn */
+    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
+       return(PCI_SLOT_IN_SHOEHORN);
+    }
+
+    /* Acquire update access to the bus */
+    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
+
+    if ((pcibr_soft->bs_slot[slot].slot_status & SLOT_SHUTDOWN_CMPLT) ||
+        ((pcibr_soft->bs_slot[slot].slot_status & SLOT_STATUS_MASK) == 0)) {
+        error = PCI_SLOT_ALREADY_DOWN;
+        /*
+         * RJR - Should we invoke an L1 slot power-down command just in case
+         *       a previous shut-down failed to power-down the slot?
+         */
+        goto shutdown_unlock;
+    }
+
+    /* Do not allow the last 33 MHz card to be removed */
+    if ((bridge->b_wid_control & BRIDGE_CTRL_BUS_SPEED_MASK) ==
+         BRIDGE_CTRL_BUS_SPEED_33) {
+        for (tmp_slot = pcibr_soft->bs_first_slot;
+             tmp_slot <= pcibr_soft->bs_last_slot; tmp_slot++)
+            if (tmp_slot != slot)
+                if (pcibr_soft->bs_slot[tmp_slot].slot_status & SLOT_POWER_UP) {
+                    error++;
+                    break;
+                }
+        if (!error) {
+            error = PCI_EMPTY_33MHZ;
+            goto shutdown_unlock;
+        }
+    }
+
+    error = pcibr_slot_detach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_DETACH,
+                              l1_msg, &tmp_down_resp.resp_sub_errno);
+
+    strncpy(tmp_down_resp.resp_l1_msg, l1_msg, L1_QSIZE);
+    tmp_down_resp.resp_l1_msg[L1_QSIZE] = '\0';
+
+    if (COPYOUT(&tmp_down_resp, reqp->req_respp.down, reqp->req_size)) {
+        return(EFAULT);
+    }
+
+    shutdown_unlock:
+
+    /* Release the bus lock */
+    mrunlock(pcibr_soft->bs_bus_lock);
+
+    return(error);
+}
+
+char *pci_space_name[] = {"NONE", 
+			  "ROM",
+			  "IO",
+			  "",
+			  "MEM",
+			  "MEM32",
+			  "MEM64",
+			  "CFG",
+			  "WIN0",
+			  "WIN1",
+			  "WIN2",
+			  "WIN3",
+			  "WIN4",
+			  "WIN5",
+			  "",
+			  "BAD"};
+
+void
+pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh,
+                            int func,
+                            pcibr_slot_func_info_resp_t funcp)
+{
+    pcibr_info_t                 pcibr_info = pcibr_infoh[func];
+    int                          win;
+
+    funcp->resp_f_status = 0;
+
+    if (!pcibr_info) {
+        return;
+    }
+
+    funcp->resp_f_status |= FUNC_IS_VALID;
+    sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
+
+    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {
+        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;
+    }
+
+    funcp->resp_f_bus = pcibr_info->f_bus;
+    funcp->resp_f_slot = pcibr_info->f_slot;
+    funcp->resp_f_func = pcibr_info->f_func;
+    sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);
+    funcp->resp_f_pops = pcibr_info->f_pops;
+    funcp->resp_f_efunc = pcibr_info->f_efunc;
+    funcp->resp_f_einfo = pcibr_info->f_einfo;
+
+    funcp->resp_f_vendor = pcibr_info->f_vendor;
+    funcp->resp_f_device = pcibr_info->f_device;
+
+    for(win = 0 ; win < 6 ; win++) {
+        funcp->resp_f_window[win].resp_w_base =
+                                  pcibr_info->f_window[win].w_base;
+        funcp->resp_f_window[win].resp_w_size =
+                                  pcibr_info->f_window[win].w_size;
+        sprintf(funcp->resp_f_window[win].resp_w_space,
+                "%s",
+                pci_space_name[pcibr_info->f_window[win].w_space]);
+    }
+
+    funcp->resp_f_rbase = pcibr_info->f_rbase;
+    funcp->resp_f_rsize = pcibr_info->f_rsize;
+
+    for (win = 0 ; win < 4; win++) {
+        funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];
+    }
+
+    funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;
+
+}
+
+int
+pcibr_slot_info_return(pcibr_soft_t             pcibr_soft,
+                       pciio_slot_t             slot,
+                       pcibr_slot_info_resp_t   respp)
+{
+    pcibr_soft_slot_t            pss;
+    int                          func;
+    bridge_t                    *bridge = pcibr_soft->bs_base;
+    reg_p                        b_respp;
+    pcibr_slot_info_resp_t       slotp;
+    pcibr_slot_func_info_resp_t  funcp;
+
+    slotp = kmem_zalloc(sizeof(*slotp), KM_SLEEP);
+    if (slotp == NULL) {
+        return(ENOMEM);
+    }
+
+    pss = &pcibr_soft->bs_slot[slot];
+
+    slotp->resp_has_host = pss->has_host;
+    slotp->resp_host_slot = pss->host_slot;
+    sprintf(slotp->resp_slot_conn_name, "%v", pss->slot_conn);
+    slotp->resp_slot_status = pss->slot_status;
+
+    slotp->resp_l1_bus_num = io_path_map_widget(pcibr_soft->bs_vhdl);
+
+    if (is_sys_critical_vertex(pss->slot_conn)) {
+        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;
+    }
+
+    slotp->resp_bss_ninfo = pss->bss_ninfo;
+
+    for (func = 0; func < pss->bss_ninfo; func++) {
+        funcp = &(slotp->resp_func[func]);
+        pcibr_slot_func_info_return(pss->bss_infos, func, funcp);
+    }
+
+    sprintf(slotp->resp_bss_devio_bssd_space, "%s",
+            pci_space_name[pss->bss_devio.bssd_space]);
+    slotp->resp_bss_devio_bssd_base = pss->bss_devio.bssd_base;
+    slotp->resp_bss_device = pss->bss_device;
+
+    slotp->resp_bss_pmu_uctr = pss->bss_pmu_uctr;
+    slotp->resp_bss_d32_uctr = pss->bss_d32_uctr;
+    slotp->resp_bss_d64_uctr = pss->bss_d64_uctr;
+
+    slotp->resp_bss_d64_base = pss->bss_d64_base;
+    slotp->resp_bss_d64_flags = pss->bss_d64_flags;
+    slotp->resp_bss_d32_base = pss->bss_d32_base;
+    slotp->resp_bss_d32_flags = pss->bss_d32_flags;
+
+    slotp->resp_bss_ext_ates_active = pss->bss_ext_ates_active;
+
+    slotp->resp_bss_cmd_pointer = pss->bss_cmd_pointer;
+    slotp->resp_bss_cmd_shadow = pss->bss_cmd_shadow;
+
+    slotp->resp_bs_rrb_valid = pcibr_soft->bs_rrb_valid[slot];
+    slotp->resp_bs_rrb_valid_v = pcibr_soft->bs_rrb_valid[slot +
+                                                      PCIBR_RRB_SLOT_VIRTUAL];
+    slotp->resp_bs_rrb_res = pcibr_soft->bs_rrb_res[slot];
+
+    if (slot & 1) {
+        b_respp = &bridge->b_odd_resp;
+    } else {
+        b_respp = &bridge->b_even_resp;
+    }
+
+    slotp->resp_b_resp = *b_respp;
+
+    slotp->resp_b_wid_control = bridge->b_wid_control;
+    slotp->resp_b_int_device = bridge->b_int_device;
+    slotp->resp_b_int_enable = bridge->b_int_enable;
+    slotp->resp_b_int_host = bridge->b_int_addr[slot].addr;
+
+    if (COPYOUT(slotp, respp, sizeof(*respp))) {
+        return(EFAULT);
+    }
+
+    kmem_free(slotp, sizeof(*slotp));
+
+    return(0);
+}
+
+/*
+ * pcibr_slot_query
+ *	Return information about the PCI slot maintained by the infrastructure.
+ *	Information is requested in the request structure.
+ *
+ *      Information returned in the response structure:
+ *		Slot hwgraph name
+ *		Vendor/Device info
+ *		Base register info
+ *		Interrupt mapping from device pins to the bridge pins
+ *		Devio register
+ *		Software RRB info
+ *		RRB register info
+ *		Host/Gues info
+ *		PCI Bus #,slot #, function #
+ *		Slot provider hwgraph name
+ *		Provider Functions
+ *		Error handler
+ *		DMA mapping usage counters
+ *		DMA direct translation info
+ *		External SSRAM workaround info
+ */
+int
+pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+{
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    pciio_slot_t            slot = reqp->req_slot;
+    pciio_slot_t            tmp_slot;
+    pcibr_slot_info_resp_t  respp = reqp->req_respp.query;
+    int                     size = reqp->req_size;
+    int                     error;
+
+    /* Make sure that we are dealing with a bridge device vertex */
+    if (!pcibr_soft) {
+        return(PCI_NOT_A_BRIDGE);
+    }
+
+    /* Make sure that we have a valid PCI slot number or PCIIO_SLOT_NONE */
+    if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE)) {
+        return(PCI_NOT_A_SLOT);
+    }
+
+    /* Do not allow a query of a slot in a shoehorn */
+    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
+       return(PCI_SLOT_IN_SHOEHORN);
+    }
+
+    /* Return information for the requested PCI slot */
+    if (slot != PCIIO_SLOT_NONE) {
+        if (size < sizeof(*respp)) {
+            return(PCI_RESP_AREA_TOO_SMALL);
+        }
+
+        /* Acquire read access to the bus */
+        mrlock(pcibr_soft->bs_bus_lock, MR_ACCESS, PZERO);
+
+        error = pcibr_slot_info_return(pcibr_soft, slot, respp);
+
+        /* Release the bus lock */
+        mrunlock(pcibr_soft->bs_bus_lock);
+
+        return(error);
+    }
+
+    /* Return information for all the slots */
+    for (tmp_slot = 0; tmp_slot < 8; tmp_slot++) {
+
+        if (size < sizeof(*respp)) {
+            return(PCI_RESP_AREA_TOO_SMALL);
+        }
+
+        /* Acquire read access to the bus */
+        mrlock(pcibr_soft->bs_bus_lock, MR_ACCESS, PZERO);
+
+        error = pcibr_slot_info_return(pcibr_soft, tmp_slot, respp);
+
+        /* Release the bus lock */
+        mrunlock(pcibr_soft->bs_bus_lock);
+
+        if (error) {
+            return(error);
+        }
+
+        ++respp;
+        size -= sizeof(*respp);
+    }
+
+    return(error);
+}
+#endif	/* LATER */
+
+/* FIXME: there should be a better way to do this.
+ * pcibr_attach() needs PCI_ADDR_SPACE_LIMITS_STORE
+ */
+
+/* 
+ * PCI_ADDR_SPACE_LIMITS_LOAD
+ *	Gets the current values of 
+ *		pci io base, 
+ *		pci io last,
+ *		pci low memory base,
+ *		pci low memory last,
+ *		pci high memory base,
+ * 		pci high memory last
+ */
+#define PCI_ADDR_SPACE_LIMITS_LOAD()			\
+    pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base;	\
+    pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last;	\
+    pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base;	\
+    pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last;	\
+    pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base;	\
+    pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last;
+/*
+ * PCI_ADDR_SPACE_LIMITS_STORE
+ *	Sets the current values of
+ *		pci io base, 
+ *		pci io last,
+ *		pci low memory base,
+ *		pci low memory last,
+ *		pci high memory base,
+ * 		pci high memory last
+ */
+#define PCI_ADDR_SPACE_LIMITS_STORE()			\
+    pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;	\
+    pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;	\
+    pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;	\
+    pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;	\
+    pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;	\
+    pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;
+
+#define PCI_ADDR_SPACE_LIMITS_PRINT()			\
+    printf("+++++++++++++++++++++++\n"			\
+	   "IO base 0x%x last 0x%x\n"			\
+	   "SWIN base 0x%x last 0x%x\n"			\
+	   "MEM base 0x%x last 0x%x\n"			\
+	   "+++++++++++++++++++++++\n",			\
+	   pcibr_soft->bs_spinfo.pci_io_base,		\
+	   pcibr_soft->bs_spinfo.pci_io_last,		\
+	   pcibr_soft->bs_spinfo.pci_swin_base,		\
+	   pcibr_soft->bs_spinfo.pci_swin_last,		\
+	   pcibr_soft->bs_spinfo.pci_mem_base,		\
+	   pcibr_soft->bs_spinfo.pci_mem_last);
+
+
+/*
+ * pcibr_slot_info_init
+ *	Probe for this slot and see if it is populated.
+ *	If it is populated initialize the generic PCI infrastructural
+ * 	information associated with this particular PCI device.
+ */
+int
+pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
+		     pciio_slot_t 	slot)
+{
+    pcibr_soft_t	    pcibr_soft;
+    pcibr_info_h	    pcibr_infoh;
+    pcibr_info_t	    pcibr_info;
+    bridge_t		   *bridge;
+    cfg_p                   cfgw;
+    unsigned                idword;
+    unsigned                pfail;
+    unsigned                idwords[8];
+    pciio_vendor_id_t       vendor;
+    pciio_device_id_t       device;
+    unsigned                htype;
+    cfg_p                   wptr;
+    int                     win;
+    pciio_space_t           space;
+    iopaddr_t		    pci_io_fb,	pci_io_fl;
+    iopaddr_t		    pci_lo_fb,  pci_lo_fl;
+    iopaddr_t		    pci_hi_fb,  pci_hi_fl;
+    int			    nfunc;
+    pciio_function_t	    rfunc;
+    int			    func;
+    devfs_handle_t	    conn_vhdl;
+    pcibr_soft_slot_t	    slotp;
+    
+    /* Get the basic software information required to proceed */
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    if (!pcibr_soft)
+	return(EINVAL);
+
+    bridge = pcibr_soft->bs_base;
+    if (!PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization
+     * is done by the host slot then we are done.
+     */
+    if (pcibr_soft->bs_slot[slot].has_host) {
+	return(0);    
+    }
+
+    /* Check for a slot with any system critical functions */
+    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
+        return(EPERM);
+
+    /* Load the current values of allocated PCI address spaces */
+    PCI_ADDR_SPACE_LIMITS_LOAD();
+    
+    /* Try to read the device-id/vendor-id from the config space */
+    cfgw = bridge->b_type0_cfg_dev[slot].l;
+
+    if (pcibr_probe_slot(bridge, cfgw, &idword)) 
+	return(ENODEV);
+
+    slotp = &pcibr_soft->bs_slot[slot];
+    slotp->slot_status |= SLOT_POWER_UP;
+
+    vendor = 0xFFFF & idword;
+    /* If the vendor id is not valid then the slot is not populated
+     * and we are done.
+     */
+    if (vendor == 0xFFFF) 
+	return(ENODEV);			
+    
+    device = 0xFFFF & (idword >> 16);
+    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
+
+    nfunc = 1;
+    rfunc = PCIIO_FUNC_NONE;
+    pfail = 0;
+
+    /* NOTE: if a card claims to be multifunction
+     * but only responds to config space 0, treat
+     * it as a unifunction card.
+     */
+
+    if (htype & 0x80) {		/* MULTIFUNCTION */
+	for (func = 1; func < 8; ++func) {
+	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
+	    if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) {
+		pfail |= 1 << func;
+		continue;
+	    }
+	    vendor = 0xFFFF & idwords[func];
+	    if (vendor == 0xFFFF) {
+		pfail |= 1 << func;
+		continue;
+	    }
+	    nfunc = func + 1;
+	    rfunc = 0;
+	}
+	cfgw = bridge->b_type0_cfg_dev[slot].l;
+    }
+    NEWA(pcibr_infoh, nfunc);
+    
+    pcibr_soft->bs_slot[slot].bss_ninfo = nfunc;
+    pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
+
+    for (func = 0; func < nfunc; ++func) {
+	unsigned                cmd_reg;
+	
+	if (func) {
+	    if (pfail & (1 << func))
+		continue;
+	    
+	    idword = idwords[func];
+	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
+	    
+	    device = 0xFFFF & (idword >> 16);
+	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
+	    rfunc = func;
+	}
+	htype &= 0x7f;
+	if (htype != 0x00) {
+	    printk(KERN_WARNING  "%s pcibr: pci slot %d func %d has strange header type 0x%x\n",
+		    pcibr_soft->bs_name, slot, func, htype);
+	    continue;
+	}
+#if DEBUG && ATTACH_DEBUG
+	printk(KERN_NOTICE   
+		"%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x",
+		pcibr_soft->bs_name, slot, func, vendor, device);
+#endif	
+
+	pcibr_info = pcibr_device_info_new
+	    (pcibr_soft, slot, rfunc, vendor, device);
+	conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
+	if (func == 0)
+	    slotp->slot_conn = conn_vhdl;
+
+#ifdef SN1_LITTLE_ENDIAN
+	cmd_reg = cfgw[(PCI_CFG_COMMAND ^ 4) / 4];
+#else
+	cmd_reg = cfgw[PCI_CFG_COMMAND / 4];
+#endif
+	
+	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
+
+	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) {
+	    iopaddr_t               base, mask, code;
+	    size_t                  size;
+
+	    /*
+	     * GET THE BASE & SIZE OF THIS WINDOW:
+	     *
+	     * The low two or four bits of the BASE register
+	     * determines which address space we are in; the
+	     * rest is a base address. BASE registers
+	     * determine windows that are power-of-two sized
+	     * and naturally aligned, so we can get the size
+	     * of a window by writing all-ones to the
+	     * register, reading it back, and seeing which
+	     * bits are used for decode; the least
+	     * significant nonzero bit is also the size of
+	     * the window.
+	     *
+	     * WARNING: someone may already have allocated
+	     * some PCI space to this window, and in fact
+	     * PIO may be in process at this very moment
+	     * from another processor (or even from this
+	     * one, if we get interrupted)! So, if the BASE
+	     * already has a nonzero address, be generous
+	     * and use the LSBit of that address as the
+	     * size; this could overstate the window size.
+	     * Usually, when one card is set up, all are set
+	     * up; so, since we don't bitch about
+	     * overlapping windows, we are ok.
+	     *
+	     * UNFORTUNATELY, some cards do not clear their
+	     * BASE registers on reset. I have two heuristics
+	     * that can detect such cards: first, if the
+	     * decode enable is turned off for the space
+	     * that the window uses, we can disregard the
+	     * initial value. second, if the address is
+	     * outside the range that we use, we can disregard
+	     * it as well.
+	     *
+	     * This is looking very PCI generic. Except for
+	     * knowing how many slots and where their config
+	     * spaces are, this window loop and the next one
+	     * could probably be shared with other PCI host
+	     * adapters. It would be interesting to see if
+	     * this could be pushed up into pciio, when we
+	     * start supporting more PCI providers.
+	     */
+#ifdef SN1_LITTLE_ENDIAN
+	    base = wptr[((win*4)^4)/4];
+#else
+	    base = wptr[win];
+#endif
+
+	    if (base & PCI_BA_IO_SPACE) {
+		/* BASE is in I/O space. */
+		space = PCIIO_SPACE_IO;
+		mask = -4;
+		code = base & 3;
+		base = base & mask;
+		if (base == 0) {
+		    ;		/* not assigned */
+		} else if (!(cmd_reg & PCI_CMD_IO_SPACE)) {
+		    base = 0;	/* decode not enabled */
+		}
+	    } else {
+		/* BASE is in MEM space. */
+		space = PCIIO_SPACE_MEM;
+		mask = -16;
+		code = base & PCI_BA_MEM_LOCATION;	/* extract BAR type */
+		base = base & mask;
+		if (base == 0) {
+		    ;		/* not assigned */
+		} else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) {
+		    base = 0;	/* decode not enabled */
+		} else if (base & 0xC0000000) {
+		    base = 0;	/* outside permissable range */
+		} else if ((code == PCI_BA_MEM_64BIT) &&
+#ifdef SN1_LITTLE_ENDIAN
+			   (wptr[(((win + 1)*4)^4)/4] != 0)) {
+#else 
+			   (wptr[win + 1] != 0)) {
+#endif /* LITTLE_ENDIAN */
+		    base = 0;	/* outside permissable range */
+		}
+	    }
+
+	    if (base != 0) {	/* estimate size */
+		size = base & -base;
+	    } else {		/* calculate size */
+#ifdef SN1_LITTLE_ENDIAN
+		wptr[((win*4)^4)/4] = ~0;	/* turn on all bits */
+		size = wptr[((win*4)^4)/4];	/* get stored bits */
+#else 
+		wptr[win] = ~0;	/* turn on all bits */
+		size = wptr[win];	/* get stored bits */
+#endif /* LITTLE_ENDIAN */
+		size &= mask;	/* keep addr */
+		size &= -size;	/* keep lsbit */
+		if (size == 0)
+		    continue;
+	    }	
+
+	    pcibr_info->f_window[win].w_space = space;
+	    pcibr_info->f_window[win].w_base = base;
+	    pcibr_info->f_window[win].w_size = size;
+
+	    /*
+	     * If this window already has PCI space
+	     * allocated for it, "subtract" that space from
+	     * our running freeblocks. Don't worry about
+	     * overlaps in existing allocated windows; we
+	     * may be overstating their sizes anyway.
+	     */
+
+	    if (base && size) {
+		if (space == PCIIO_SPACE_IO) {
+		    pcibr_freeblock_sub(&pci_io_fb,
+					&pci_io_fl,
+					base, size);
+		} else {
+		    pcibr_freeblock_sub(&pci_lo_fb,
+					&pci_lo_fl,
+					base, size);
+		    pcibr_freeblock_sub(&pci_hi_fb,
+					&pci_hi_fl,
+					base, size);
+		}	
+	    }
+#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
+	    /*
+	     * IOC3 BASE_ADDR* BUG WORKAROUND
+	     *
+	     
+	     * If we write to BASE1 on the IOC3, the
+	     * data in BASE0 is replaced. The
+	     * original workaround was to remember
+	     * the value of BASE0 and restore it
+	     * when we ran off the end of the BASE
+	     * registers; however, a later
+	     * workaround was added (I think it was
+	     * rev 1.44) to avoid setting up
+	     * anything but BASE0, with the comment
+	     * that writing all ones to BASE1 set
+	     * the enable-parity-error test feature
+	     * in IOC3's SCR bit 14.
+	     *
+	     * So, unless we defer doing any PCI
+	     * space allocation until drivers
+	     * attach, and set up a way for drivers
+	     * (the IOC3 in paricular) to tell us
+	     * generically to keep our hands off
+	     * BASE registers, we gotta "know" about
+	     * the IOC3 here.
+	     *
+	     * Too bad the PCI folks didn't reserve the
+	     * all-zero value for 'no BASE here' (it is a
+	     * valid code for an uninitialized BASE in
+	     * 32-bit PCI memory space).
+	     */
+	    
+	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
+		(device == IOC3_DEVICE_ID_NUM))
+		break;
+#endif
+	    if (code == PCI_BA_MEM_64BIT) {
+		win++;		/* skip upper half */
+#ifdef SN1_LITTLE_ENDIAN
+		wptr[((win*4)^4)/4] = 0;	/* which must be zero */
+#else 
+		wptr[win] = 0;	/* which must be zero */
+#endif /* LITTLE_ENDIAN */
+	    }
+	}				/* next win */
+    }				/* next func */
+
+    /* Store back the values for allocated PCI address spaces */
+    PCI_ADDR_SPACE_LIMITS_STORE();
+    return(0);
+}					
+
+/*
+ * pcibr_slot_info_free
+ *	Remove all the PCI infrastructural information associated
+ * 	with a particular PCI device.
+ */
+int
+pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
+                     pciio_slot_t slot)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    int			nfunc;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+
+    pcibr_device_info_free(pcibr_vhdl, slot);
+
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+    DELA(pcibr_infoh,nfunc);
+    pcibr_soft->bs_slot[slot].bss_ninfo = 0;
+
+    return(0);
+}
+
+int as_debug = 0;
+/*
+ * pcibr_slot_addr_space_init
+ *	Reserve chunks of PCI address space as required by 
+ * 	the base registers in the card.
+ */
+int
+pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
+			   pciio_slot_t	slot)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    bridge_t		*bridge;
+    iopaddr_t		pci_io_fb, pci_io_fl;
+    iopaddr_t		pci_lo_fb, pci_lo_fl;
+    iopaddr_t		pci_hi_fb, pci_hi_fl;
+    size_t              align;
+    iopaddr_t           mask;
+    int		    	nbars;
+    int		       	nfunc;
+    int			func;
+    int			win;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    bridge = pcibr_soft->bs_base;
+
+    /* Get the current values for the allocated PCI address spaces */
+    PCI_ADDR_SPACE_LIMITS_LOAD();
+
+    if (as_debug)
+#ifdef LATER
+    PCI_ADDR_SPACE_LIMITS_PRINT();
+#endif
+
+    /* allocate address space,
+     * for windows that have not been
+     * previously assigned.
+     */
+    if (pcibr_soft->bs_slot[slot].has_host) {
+	return(0);
+    }
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    if (nfunc < 1)
+	return(EINVAL);
+
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+    if (!pcibr_infoh)
+	return(EINVAL);
+
+    /*
+     * Try to make the DevIO windows not
+     * overlap by pushing the "io" and "hi"
+     * allocation areas up to the next one
+     * or two megabyte bound. This also
+     * keeps them from being zero.
+     *
+     * DO NOT do this with "pci_lo" since
+     * the entire "lo" area is only a
+     * megabyte, total ...
+     */
+    align = (slot < 2) ? 0x200000 : 0x100000;
+    mask = -align;
+    pci_io_fb = (pci_io_fb + align - 1) & mask;
+    pci_hi_fb = (pci_hi_fb + align - 1) & mask;
+
+    for (func = 0; func < nfunc; ++func) {
+	cfg_p                   cfgw;
+	cfg_p                   wptr;
+	pciio_space_t           space;
+	iopaddr_t               base;
+	size_t                  size;
+	cfg_p                   pci_cfg_cmd_reg_p;
+	unsigned                pci_cfg_cmd_reg;
+	unsigned                pci_cfg_cmd_reg_add = 0;
+
+	pcibr_info = pcibr_infoh[func];
+
+	if (!pcibr_info)
+	    continue;
+
+	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+	    continue;
+	
+	cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
+	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
+
+	nbars = PCI_CFG_BASE_ADDRS;
+
+	for (win = 0; win < nbars; ++win) {
+
+	    space = pcibr_info->f_window[win].w_space;
+	    base = pcibr_info->f_window[win].w_base;
+	    size = pcibr_info->f_window[win].w_size;
+	    
+	    if (size < 1)
+		continue;
+
+	    if (base >= size) {
+#if DEBUG && PCI_DEBUG
+		printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by prom\n",
+			slot, func, win, space, base, base + size - 1);
+#endif
+		continue;		/* already allocated */
+	    }
+	    align = size;		/* ie. 0x00001000 */
+	    if (align < _PAGESZ)
+		align = _PAGESZ;	/* ie. 0x00004000 */
+	    mask = -align;		/* ie. 0xFFFFC000 */
+
+	    switch (space) {
+	    case PCIIO_SPACE_IO:
+		base = (pci_io_fb + align - 1) & mask;
+		if ((base + size) > pci_io_fl) {
+		    base = 0;
+		    break;
+		}
+		pci_io_fb = base + size;
+		break;
+		
+	    case PCIIO_SPACE_MEM:
+#ifdef SN1_LITTLE_ENDIAN
+		if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) ==
+#else
+		if ((wptr[win] & PCI_BA_MEM_LOCATION) ==
+#endif  /* LITTLE_ENDIAN */
+		    PCI_BA_MEM_1MEG) {
+		    /* allocate from 20-bit PCI space */
+		    base = (pci_lo_fb + align - 1) & mask;
+		    if ((base + size) > pci_lo_fl) {
+			base = 0;
+			break;
+		    }
+		    pci_lo_fb = base + size;
+		} else {
+		    /* allocate from 32-bit or 64-bit PCI space */
+		    base = (pci_hi_fb + align - 1) & mask;
+		    if ((base + size) > pci_hi_fl) {
+			base = 0;
+			break;
+		    }
+		    pci_hi_fb = base + size;
+		}
+		break;
+		
+	    default:
+		base = 0;
+#if DEBUG && PCI_DEBUG
+		printk("pcibr: slot %d window %d had bad space code %d\n",
+			slot, win, space);
+#endif
+	    }
+	    pcibr_info->f_window[win].w_base = base;
+#ifdef SN1_LITTLE_ENDIAN
+	    wptr[((win*4)^4)/4] = base;
+#if DEBUG && PCI_DEBUG
+		printk("Setting base address 0x%p base 0x%x\n", &(wptr[((win*4)^4)/4]), base);
+#endif
+#else
+	    wptr[win] = base;
+#endif  /* LITTLE_ENDIAN */
+
+#if DEBUG && PCI_DEBUG
+	    if (base >= size)
+		printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibr\n",
+			slot, func, win, space, base, base + size - 1);
+	    else
+		printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%p\n",
+			slot, func, win, size, space);
+#endif
+	}				/* next base */
+
+	/*
+	 * Allocate space for the EXPANSION ROM
+	 * NOTE: DO NOT DO THIS ON AN IOC3,
+	 * as it blows the system away.
+	 */
+	base = size = 0;
+	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
+	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
+
+	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
+#ifdef SN1_LITTLE_ENDIAN
+	    wptr[1] = 0xFFFFF000;
+	    mask = wptr[1];
+#else
+	    *wptr = 0xFFFFF000;
+	    mask = *wptr;
+#endif  /* LITTLE_ENDIAN */
+	    if (mask & 0xFFFFF000) {
+		size = mask & -mask;
+		align = size;
+		if (align < _PAGESZ)
+		    align = _PAGESZ;
+		mask = -align;
+		base = (pci_hi_fb + align - 1) & mask;
+		if ((base + size) > pci_hi_fl)
+		    base = size = 0;
+		else {
+		    pci_hi_fb = base + size;
+#ifdef SN1_LITTLE_ENDIAN
+		    wptr[1] = base;
+#else
+		    *wptr = base;
+#endif  /* LITTLE_ENDIAN */
+#if DEBUG && PCI_DEBUG
+		    printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)\n",
+			    pcibr_soft->bs_name, slot,
+			    base, base + size - 1);
+#endif
+		}
+	    }
+	}
+	pcibr_info->f_rbase = base;
+	pcibr_info->f_rsize = size;
+	
+	/*
+	 * if necessary, update the board's
+	 * command register to enable decoding
+	 * in the windows we added.
+	 *
+	 * There are some bits we always want to
+	 * be sure are set.
+	 */
+	pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
+
+	/*
+	 * The Adaptec 1160 FC Controller WAR #767995:
+	 * The part incorrectly ignores the upper 32 bits of a 64 bit
+	 * address when decoding references to it's registers so to
+	 * keep it from responding to a bus cycle that it shouldn't
+	 * we only use I/O space to get at it's registers.  Don't
+	 * enable memory space accesses on that PCI device.
+	 */
+	#define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */
+	#define FCADP_DEVID 0x1160  /* Adaptec 1160 Device ID from fcadp.h */
+
+	if ((pcibr_info->f_vendor != FCADP_VENDID) ||
+	    (pcibr_info->f_device != FCADP_DEVID))
+	    pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE;
+
+	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
+
+	pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4;
+	pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p;
+#if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
+	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
+	    fast_back_to_back_enable = 0;
+#endif
+	pci_cfg_cmd_reg &= 0xFFFF;
+	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
+	    *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add;
+	
+    }				/* next func */
+
+    /* Now that we have allocated new chunks of PCI address spaces to this
+     * card we need to update the bookkeeping values which indicate
+     * the current PCI address space allocations.
+     */
+    PCI_ADDR_SPACE_LIMITS_STORE();
+    return(0);
+}
+
+/*
+ * pcibr_slot_device_init
+ * 	Setup the device register in the bridge for this PCI slot.
+ */
+int
+pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
+		       pciio_slot_t slot)
+{
+    pcibr_soft_t	 pcibr_soft;
+    bridge_t		*bridge;
+    bridgereg_t		 devreg;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    bridge = pcibr_soft->bs_base;
+
+    /*
+     * Adjustments to Device(x)
+     * and init of bss_device shadow
+     */
+    devreg = bridge->b_device[slot].reg;
+    devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS;
+    devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN;
+#ifdef LITTLE_ENDIAN
+    devreg |= BRIDGE_DEV_DEV_SWAP;
+#endif
+    pcibr_soft->bs_slot[slot].bss_device = devreg;
+    bridge->b_device[slot].reg = devreg;
+
+#if DEBUG && PCI_DEBUG
+	printk("pcibr Device(%d): 0x%lx\n", slot, bridge->b_device[slot].reg);
+#endif
+
+#if DEBUG && PCI_DEBUG
+    printk("pcibr: PCI space allocation done.\n");
+#endif
+
+    return(0);
+}
+
+/*
+ * pcibr_slot_guest_info_init
+ *	Setup the host/guest relations for a PCI slot.
+ */
+int
+pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
+			   pciio_slot_t	slot)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    pcibr_soft_slot_t	slotp;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    slotp = &pcibr_soft->bs_slot[slot];
+
+    /* create info and verticies for guest slots;
+     * for compatibilitiy macros, create info
+     * for even unpopulated slots (but do not
+     * build verticies for them).
+     */
+    if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) {
+	NEWA(pcibr_infoh, 1);
+	pcibr_soft->bs_slot[slot].bss_ninfo = 1;
+	pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
+
+	pcibr_info = pcibr_device_info_new
+	    (pcibr_soft, slot, PCIIO_FUNC_NONE,
+	     PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
+
+	if (pcibr_soft->bs_slot[slot].has_host) {
+	    slotp->slot_conn = pciio_device_info_register
+		(pcibr_vhdl, &pcibr_info->f_c);
+	}
+    }
+
+    /* generate host/guest relations
+     */
+    if (pcibr_soft->bs_slot[slot].has_host) {
+	int  host = pcibr_soft->bs_slot[slot].host_slot;
+	pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host];
+
+	hwgraph_edge_add(slotp->slot_conn,
+			 host_slotp->slot_conn,
+			 EDGE_LBL_HOST);
+
+	/* XXX- only gives us one guest edge per
+	 * host. If/when we have a host with more than
+	 * one guest, we will need to figure out how
+	 * the host finds all its guests, and sorts
+	 * out which one is which.
+	 */
+	hwgraph_edge_add(host_slotp->slot_conn,
+			 slotp->slot_conn,
+			 EDGE_LBL_GUEST);
+    }
+
+    return(0);
+}
+
+
+/*
+ * pcibr_slot_call_device_attach
+ *	This calls the associated driver attach routine for the PCI
+ * 	card in this slot.
+ */
+int
+pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+			      pciio_slot_t slot,
+			      int          drv_flags)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    async_attach_t	aa = NULL;
+    int			func;
+    devfs_handle_t	xconn_vhdl,conn_vhdl;
+    int			nfunc;
+    int                 error_func;
+    int                 error_slot = 0;
+    int                 error = ENODEV;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+
+    if (pcibr_soft->bs_slot[slot].has_host) {
+        return(EPERM);
+    }
+    
+    xconn_vhdl = pcibr_soft->bs_conn;
+    aa = async_attach_get_info(xconn_vhdl);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+
+    for (func = 0; func < nfunc; ++func) {
+
+	pcibr_info = pcibr_infoh[func];
+	
+	if (!pcibr_info)
+	    continue;
+
+	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+	    continue;
+
+	conn_vhdl = pcibr_info->f_vertex;
+
+#ifdef LATER
+	/*
+	 * Activate if and when we support cdl.
+	 */
+	if (aa)
+	    async_attach_add_info(conn_vhdl, aa);
+#endif	/* LATER */
+
+	error_func = pciio_device_attach(conn_vhdl, drv_flags);
+
+        pcibr_info->f_att_det_error = error_func;
+
+	if (error_func)
+	    error_slot = error_func;
+
+        error = error_slot;
+
+    }				/* next func */
+
+    if (error) {
+	if ((error != ENODEV) && (error != EUNATCH))
+	    pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
+    } else {
+        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
+    }
+        
+    return(error);
+}
+
+/*
+ * pcibr_slot_call_device_detach
+ *	This calls the associated driver detach routine for the PCI
+ * 	card in this slot.
+ */
+int
+pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+			      pciio_slot_t slot,
+			      int          drv_flags)
+{
+    pcibr_soft_t	pcibr_soft;
+    pcibr_info_h	pcibr_infoh;
+    pcibr_info_t	pcibr_info;
+    int			func;
+    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
+    int			nfunc;
+    int                 error_func;
+    int                 error_slot = 0;
+    int                 error = ENODEV;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
+
+    if (pcibr_soft->bs_slot[slot].has_host)
+        return(EPERM);
+
+    /* Make sure that we do not detach a system critical function vertex */
+    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
+        return(EPERM);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+
+    for (func = 0; func < nfunc; ++func) {
+
+	pcibr_info = pcibr_infoh[func];
+	
+	if (!pcibr_info)
+	    continue;
+
+	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+	    continue;
+
+	conn_vhdl = pcibr_info->f_vertex;
+
+	error_func = pciio_device_detach(conn_vhdl, drv_flags);
+
+        pcibr_info->f_att_det_error = error_func;
+
+	if (error_func)
+	    error_slot = error_func;
+
+	error = error_slot;
+
+    }				/* next func */
+
+    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
+
+    if (error) {
+	if ((error != ENODEV) && (error != EUNATCH))
+            pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
+    } else {
+        if (conn_vhdl != GRAPH_VERTEX_NONE) 
+            pcibr_device_unregister(conn_vhdl);
+        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
+    }
+        
+    return(error);
+}
+
+#ifdef LATER
+
+/*
+ * pcibr_slot_attach
+ *	This is a place holder routine to keep track of all the
+ *	slot-specific initialization that needs to be done.
+ *	This is usually called when we want to initialize a new
+ * 	PCI card on the bus.
+ */
+int
+pcibr_slot_attach(devfs_handle_t pcibr_vhdl,
+		  pciio_slot_t slot,
+		  int          drv_flags,
+		  char        *l1_msg,
+                  int         *sub_errorp)
+{
+    pcibr_soft_t  pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    timespec_t    ts;
+    int		  error;
+
+    if (!(pcibr_soft->bs_slot[slot].slot_status & SLOT_POWER_UP)) { 
+        /* Power-up the slot */
+        error = pcibr_slot_pwr(pcibr_vhdl, slot, L1_REQ_PCI_UP, l1_msg);
+        if (error) {
+            if (sub_errorp)
+                *sub_errorp = error;
+            return(PCI_L1_ERR);
+        } else {
+            pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_POWER_MASK;
+            pcibr_soft->bs_slot[slot].slot_status |= SLOT_POWER_UP;
+        }
+
+#ifdef LATER
+        /*
+         * Allow cards like the Alteon Gigabit Ethernet Adapter to complete
+         * on-card initialization following the slot reset
+         */
+         ts.tv_sec = 0;                      /* 0 secs */
+         ts.tv_nsec = 500 * (1000 * 1000);   /* 500 msecs */
+         nano_delay(&ts);
+#else
+#endif
+#if 0
+        /* Reset the slot */
+        error = pcibr_slot_reset(pcibr_vhdl, slot)
+        if (error) {
+            if (sub_errorp)
+                *sub_errorp = error;
+            return(PCI_SLOT_RESET_ERR);
+        }
+#endif
+
+        /* Find out what is out there */
+        error = pcibr_slot_info_init(pcibr_vhdl, slot);
+        if (error) {
+            if (sub_errorp)
+                *sub_errorp = error;
+            return(PCI_SLOT_INFO_INIT_ERR);
+        }
+
+        /* Set up the address space for this slot in the PCI land */
+        error = pcibr_slot_addr_space_init(pcibr_vhdl, slot);
+        if (error) {
+            if (sub_errorp)
+                *sub_errorp = error;
+            return(PCI_SLOT_ADDR_INIT_ERR);
+        }
+
+        /* Setup the device register */
+        error = pcibr_slot_device_init(pcibr_vhdl, slot);
+        if (error) {
+            if (sub_errorp)
+                *sub_errorp = error;
+            return(PCI_SLOT_DEV_INIT_ERR);
+        }
+
+        /* Setup host/guest relations */
+        error = pcibr_slot_guest_info_init(pcibr_vhdl, slot);
+        if (error) {
+            if (sub_errorp)
+                *sub_errorp = error;
+            return(PCI_SLOT_GUEST_INIT_ERR);
+        }
+
+        /* Initial RRB management */
+        error = pcibr_slot_initial_rrb_alloc(pcibr_vhdl, slot);
+        if (error) {
+            if (sub_errorp)
+                *sub_errorp = error;
+            return(PCI_SLOT_RRB_ALLOC_ERR);
+        }
+
+    }
+
+    /* Call the device attach */
+    error = pcibr_slot_call_device_attach(pcibr_vhdl, slot, drv_flags);
+    if (error) {
+        if (sub_errorp)
+            *sub_errorp = error;
+        if (error == EUNATCH)
+            return(PCI_NO_DRIVER);
+        else
+            return(PCI_SLOT_DRV_ATTACH_ERR);
+    }
+
+    return(0);
+}
+#endif	/* LATER */
+
+/*
+ * pcibr_slot_detach
+ *	This is a place holder routine to keep track of all the
+ *	slot-specific freeing that needs to be done.
+ */
+int
+pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
+		  pciio_slot_t slot,
+		  int          drv_flags)
+{
+    int		  error;
+    
+    /* Call the device detach function */
+    error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
+    return (error);
+
+}
+
+/*
+ * pcibr_is_slot_sys_critical
+ *      Check slot for any functions that are system critical.
+ *      Return 1 if any are system critical or 0 otherwise.
+ *
+ *      This function will always return 0 when called by 
+ *      pcibr_attach() because the system critical vertices 
+ *      have not yet been set in the hwgraph.
+ */
+int
+pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
+                      pciio_slot_t slot)
+{
+    pcibr_soft_t        pcibr_soft;
+    pcibr_info_h        pcibr_infoh;
+    pcibr_info_t        pcibr_info;
+    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
+    int                 nfunc;
+    int                 func;
+    boolean_t		is_sys_critical_vertex(devfs_handle_t);
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+        return(0);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+
+    for (func = 0; func < nfunc; ++func) {
+
+        pcibr_info = pcibr_infoh[func];
+        if (!pcibr_info)
+            continue;
+
+        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+            continue;
+
+        conn_vhdl = pcibr_info->f_vertex;
+        if (is_sys_critical_vertex(conn_vhdl)) { 
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);
+#else
+            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);
+#endif
+            return(1); 
+        }
+
+    }
+
+    return(0);
+}
+
+/*
+ * pcibr_probe_slot: read a config space word
+ * while trapping any errors; reutrn zero if
+ * all went OK, or nonzero if there was an error.
+ * The value read, if any, is passed back
+ * through the valp parameter.
+ */
+int
+pcibr_probe_slot(bridge_t *bridge,
+		 cfg_p cfg,
+		 unsigned *valp)
+{
+    int                     rv;
+    bridgereg_t             old_enable, new_enable;
+    int badaddr_val(volatile void *, int, volatile void *);
+
+    old_enable = bridge->b_int_enable;
+    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
+
+    bridge->b_int_enable = new_enable;
+
+	/*
+	 * The xbridge doesn't clear b_err_int_view unless
+	 * multi-err is cleared...
+	 */
+	if (is_xbridge(bridge))
+	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
+		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
+	    }
+
+    if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
+	bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
+	(void) bridge->b_wid_tflush;	/* flushbus */
+    }
+    rv = badaddr_val((void *) cfg, 4, valp);
+
+	/*
+	 * The xbridge doesn't set master timeout in b_int_status
+	 * here.  Fortunately it's in error_interrupt_view.
+	 */
+	if (is_xbridge(bridge))
+	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
+		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
+		rv = 1;		/* unoccupied slot */
+	    }
+
+    bridge->b_int_enable = old_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
+
+    return rv;
+}
+
+void
+pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
+{
+    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    pcibr_info_t	pcibr_info;
+    pciio_function_t	func;
+    pcibr_soft_slot_t	slotp = &pcibr_soft->bs_slot[slot];
+    int			nfunc = slotp->bss_ninfo;
+    int                 bar;
+    int                 devio_index;
+    int                 s;
+
+
+    for (func = 0; func < nfunc; func++) {
+	pcibr_info = slotp->bss_infos[func];
+
+	if (!pcibr_info) 
+	    continue;
+
+        s = pcibr_lock(pcibr_soft);
+
+        for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) {
+            if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE)
+                continue;
+
+            /* Get index of the DevIO(x) register used to access this BAR */
+            devio_index = pcibr_info->f_window[bar].w_devio_index;
+
+ 
+            /* On last use, clear the DevIO(x) used to access this BAR */
+            if (! --pcibr_soft->bs_slot[devio_index].bss_devio.bssd_ref_cnt) {
+               pcibr_soft->bs_slot[devio_index].bss_devio.bssd_space =
+                                                       PCIIO_SPACE_NONE; 
+               pcibr_soft->bs_slot[devio_index].bss_devio.bssd_base =
+                                                       PCIBR_D32_BASE_UNSET;
+               pcibr_soft->bs_slot[devio_index].bss_device = 0;
+            }
+        }
+
+        pcibr_unlock(pcibr_soft, s);
+
+	slotp->bss_infos[func] = 0;
+	pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);
+	pciio_device_info_free(&pcibr_info->f_c);
+
+	DEL(pcibr_info);
+    }
+
+    /* Reset the mapping usage counters */
+    slotp->bss_pmu_uctr = 0;
+    slotp->bss_d32_uctr = 0;
+    slotp->bss_d64_uctr = 0;
+
+    /* Clear the Direct translation info */
+    slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;
+    slotp->bss_d64_flags = 0;
+    slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;
+    slotp->bss_d32_flags = 0;
+
+    /* Clear out shadow info necessary for the external SSRAM workaround */
+    slotp->bss_ext_ates_active = ATOMIC_INIT(0);
+    slotp->bss_cmd_pointer = 0;
+    slotp->bss_cmd_shadow = 0;
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/shub_intr.c linux/arch/ia64/sn/io/sn2/shub_intr.c
--- linux.orig/arch/ia64/sn/io/sn2/shub_intr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/shub_intr.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,215 @@
+/* $Id: shub_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/xtalk/xtalkaddrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_cpuid.h>
+
+extern void hub_device_desc_update(device_desc_t, ilvl_t, cpuid_t);
+
+/* ARGSUSED */
+void
+hub_intr_init(devfs_handle_t hubv)
+{
+	extern void sn_cpei_handler(int, void *, struct pt_regs *);
+	extern void sn_init_cpei_timer(void);
+
+	if (request_irq(SGI_SHUB_ERROR_VECTOR, sn_cpei_handler, 0, "SN hub error", NULL) ) {
+		printk("hub_intr_init: Couldn't register SGI_SHUB_ERROR_VECTOR = %x\n",SGI_SHUB_ERROR_VECTOR);
+	}
+	sn_init_cpei_timer();
+}
+
+xwidgetnum_t
+hub_widget_id(nasid_t nasid)
+{
+        hubii_wcr_t     ii_wcr; /* the control status register */
+        
+        ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
+        
+        return ii_wcr.wcr_fields_s.wcr_widget_id;
+}
+
+static hub_intr_t
+do_hub_intr_alloc(devfs_handle_t dev,
+		device_desc_t dev_desc,
+		devfs_handle_t owner_dev,
+		int uncond_nothread)
+{
+	cpuid_t		cpu = 0;
+	int		vector;
+	hub_intr_t	intr_hdl;
+	cnodeid_t	cnode;
+	int		cpuphys, slice;
+	int		nasid;
+	iopaddr_t	xtalk_addr;
+	struct xtalk_intr_s	*xtalk_info;
+	xwidget_info_t	xwidget_info;
+	ilvl_t		intr_swlevel = 0;
+
+	cpu = intr_heuristic(dev, dev_desc, -1, 0, owner_dev, NULL, &vector);
+
+	if (cpu == CPU_NONE) {
+		printk("Unable to allocate interrupt for 0x%p\n", (void *)owner_dev);
+		return(0);
+	}
+
+	cpuphys = cpu_physical_id(cpu);
+	slice = cpu_physical_id_to_slice(cpuphys);
+	nasid = cpu_physical_id_to_nasid(cpuphys);
+	cnode = cpuid_to_cnodeid(cpu);
+
+	if (slice) {
+		xtalk_addr = SH_II_INT1 | GLOBAL_MMR_SPACE |
+			((unsigned long)nasid << 36) | (1UL << 47);
+	} else {
+		xtalk_addr = SH_II_INT0 | GLOBAL_MMR_SPACE |
+			((unsigned long)nasid << 36) | (1UL << 47);
+	}
+
+	intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, cnode);
+	ASSERT_ALWAYS(intr_hdl);
+
+	xtalk_info = &intr_hdl->i_xtalk_info;
+	xtalk_info->xi_dev = dev;
+	xtalk_info->xi_vector = vector;
+	xtalk_info->xi_addr = xtalk_addr;
+
+	xwidget_info = xwidget_info_get(dev);
+	if (xwidget_info) {
+		xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info);
+	}
+
+	intr_hdl->i_swlevel = intr_swlevel;
+	intr_hdl->i_cpuid = cpu;
+	intr_hdl->i_bit = vector;
+	intr_hdl->i_flags |= HUB_INTR_IS_ALLOCED;
+
+	hub_device_desc_update(dev_desc, intr_swlevel, cpu);
+	return(intr_hdl);
+}
+
+hub_intr_t
+hub_intr_alloc(devfs_handle_t dev,
+		device_desc_t dev_desc,
+		devfs_handle_t owner_dev)
+{
+	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
+}
+
+hub_intr_t
+hub_intr_alloc_nothd(devfs_handle_t dev,
+		device_desc_t dev_desc,
+		devfs_handle_t owner_dev)
+{
+	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
+}
+
+void
+hub_intr_free(hub_intr_t intr_hdl)
+{
+	cpuid_t		cpu = intr_hdl->i_cpuid;
+	int		vector = intr_hdl->i_bit;
+	xtalk_intr_t	xtalk_info;
+
+	if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) {
+		xtalk_info = &intr_hdl->i_xtalk_info;
+		xtalk_info->xi_dev = NODEV;
+		xtalk_info->xi_vector = 0;
+		xtalk_info->xi_addr = 0;
+		hub_intr_disconnect(intr_hdl);
+	}
+
+	if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED) {
+		kfree(intr_hdl);
+	}
+	intr_unreserve_level(cpu, vector);
+}
+
+int
+hub_intr_connect(hub_intr_t intr_hdl,
+		xtalk_intr_setfunc_t setfunc,
+		void *setfunc_arg)
+{
+	int		rv;
+	cpuid_t		cpu = intr_hdl->i_cpuid;
+	int 		vector = intr_hdl->i_bit;
+
+	ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED);
+
+	rv = intr_connect_level(cpu, vector, intr_hdl->i_swlevel, NULL);
+
+	if (rv < 0) {
+		return rv;
+	}
+
+	intr_hdl->i_xtalk_info.xi_setfunc = setfunc;
+	intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg;
+
+	if (setfunc) {
+		(*setfunc)((xtalk_intr_t)intr_hdl);
+	}
+
+	intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED;
+
+	return 0;
+}
+
+/*
+ * Disassociate handler with the specified interrupt.
+ */
+void
+hub_intr_disconnect(hub_intr_t intr_hdl)
+{
+	/*REFERENCED*/
+	int rv;
+	cpuid_t cpu = intr_hdl->i_cpuid;
+	int bit = intr_hdl->i_bit;
+	xtalk_intr_setfunc_t setfunc;
+
+	setfunc = intr_hdl->i_xtalk_info.xi_setfunc;
+
+	/* TBD: send disconnected interrupts somewhere harmless */
+	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
+
+	rv = intr_disconnect_level(cpu, bit);
+	ASSERT(rv == 0);
+	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
+}
+
+
+/*
+ * Return a hwgraph vertex that represents the CPU currently
+ * targeted by an interrupt.
+ */
+devfs_handle_t
+hub_intr_cpu_get(hub_intr_t intr_hdl)
+{
+	cpuid_t cpuid = intr_hdl->i_cpuid;
+
+	ASSERT(cpuid != CPU_NONE);
+
+	return(cpuid_to_vertex(cpuid));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/sn2/shuberror.c linux/arch/ia64/sn/io/sn2/shuberror.c
--- linux.orig/arch/ia64/sn/io/sn2/shuberror.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/io/sn2/shuberror.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,478 @@
+/* $Id: shuberror.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/smp.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/xtalk/xtalk.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/ioerror.h>
+#include <asm/sn/sn2/shubio.h>
+#include <asm/sn/bte.h>
+
+extern void hubni_eint_init(cnodeid_t cnode);
+extern void hubii_eint_init(cnodeid_t cnode);
+extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
+int hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
+int hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
+extern void bte_crb_error_handler(devfs_handle_t hub_v, int btenum, int crbnum, ioerror_t *ioe);
+
+extern int maxcpus;
+
+#define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
+
+
+void
+hub_error_clear(nasid_t nasid)
+{
+	int i;
+	hubreg_t idsr;
+
+    /*
+     * Make sure spurious write response errors are cleared
+     * (values are from hub_set_prb())
+     */
+    for (i = 0; i <= HUB_WIDGET_ID_MAX - HUB_WIDGET_ID_MIN + 1; i++) {
+        iprb_t prb;
+
+	prb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)));
+
+        /* Clear out some fields */
+        prb.iprb_ovflow = 1;
+        prb.iprb_bnakctr = 0;
+        prb.iprb_anakctr = 0;
+
+        prb.iprb_xtalkctr = 3;  /* approx. PIO credits for the widget */
+
+        REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
+    }
+
+    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
+    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
+    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
+
+}
+
+
+/*
+ * Function	: hub_error_init
+ * Purpose	: initialize the error handling requirements for a given hub.
+ * Parameters	: cnode, the compact nodeid.
+ * Assumptions	: Called only once per hub, either by a local cpu. Or by a 
+ *			remote cpu, when this hub is headless.(cpuless)
+ * Returns	: None
+ */
+
+void
+hub_error_init(cnodeid_t cnode)
+{
+	nasid_t nasid;
+
+    nasid = cnodeid_to_nasid(cnode);
+    hub_error_clear(nasid);
+
+
+    /*
+     * Now setup the hub ii error interrupt handler.
+     */
+
+    hubii_eint_init(cnode);
+
+    return;
+}
+
+/*
+ * Function	: hubii_eint_init
+ * Parameters	: cnode
+ * Purpose	: to initialize the hub iio error interrupt.
+ * Assumptions	: Called once per hub, by the cpu which will ultimately
+ *			handle this interrupt.
+ * Returns	: None.
+ */
+
+
+void
+hubii_eint_init(cnodeid_t cnode)
+{
+    int			bit, rv;
+    ii_iidsr_u_t    	hubio_eint;
+    hubinfo_t		hinfo; 
+    cpuid_t		intr_cpu;
+    devfs_handle_t 	hub_v;
+    ii_ilcsr_u_t	ilcsr;
+    int bit_pos_to_irq(int bit);
+    int synergy_intr_connect(int bit, int cpuid);
+
+
+    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
+    ASSERT_ALWAYS(hub_v);
+    hubinfo_get(hub_v, &hinfo);
+
+    ASSERT(hinfo);
+    ASSERT(hinfo->h_cnodeid == cnode);
+
+    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+
+    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
+	/* 
+	 * HUB II link is not up. 
+	 * Just disable LLP, and don't connect any interrupts.
+	 */
+	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
+	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
+	return;
+    }
+    /* Select a possible interrupt target where there is a free interrupt
+     * bit and also reserve the interrupt bit for this IO error interrupt
+     */
+    intr_cpu = intr_heuristic(hub_v,0,-1,0,hub_v,
+			      "HUB IO error interrupt",&bit);
+    if (intr_cpu == CPU_NONE) {
+	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
+	return;
+    }
+	
+    rv = intr_connect_level(intr_cpu, bit, 0, NULL);
+    request_irq(bit + (intr_cpu << 8), hubii_eint_handler, 0, "SN hub error", (void *)hub_v);
+    ASSERT_ALWAYS(rv >= 0);
+    hubio_eint.ii_iidsr_regval = 0;
+    hubio_eint.ii_iidsr_fld_s.i_enable = 1;
+    hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/
+    hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode);
+    hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu);
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval);
+
+}
+
+
+/*ARGSUSED*/
+void
+hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
+{
+    devfs_handle_t	hub_v;
+    hubinfo_t		hinfo; 
+    ii_wstat_u_t	wstat;
+    hubreg_t		idsr;
+
+
+    /* two levels of casting avoids compiler warning.!! */
+    hub_v = (devfs_handle_t)(long)(arg); 
+    ASSERT(hub_v);
+
+    hubinfo_get(hub_v, &hinfo);
+    
+    /* 
+     * Identify the reason for error. 
+     */
+    wstat.ii_wstat_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_WSTAT);
+
+    if (wstat.ii_wstat_fld_s.w_crazy) {
+	char	*reason;
+	/*
+	 * We can do a couple of things here. 
+	 * Look at the fields TX_MX_RTY/XT_TAIL_TO/XT_CRD_TO to check
+	 * which of these caused the CRAZY bit to be set. 
+	 * You may be able to check if the Link is up really.
+	 */
+	if (wstat.ii_wstat_fld_s.w_tx_mx_rty)
+		reason = "Micro Packet Retry Timeout";
+	else if (wstat.ii_wstat_fld_s.w_xt_tail_to)
+		reason = "Crosstalk Tail Timeout";
+	else if (wstat.ii_wstat_fld_s.w_xt_crd_to)
+		reason = "Crosstalk Credit Timeout";
+	else {
+		hubreg_t	hubii_imem;
+		/*
+		 * Check if widget 0 has been marked as shutdown, or
+		 * if BTE 0/1 has been marked.
+		 */
+		hubii_imem = REMOTE_HUB_L(hinfo->h_nasid, IIO_IMEM);
+		if (hubii_imem & IIO_IMEM_W0ESD)
+			reason = "Hub Widget 0 has been Shutdown";
+		else if (hubii_imem & IIO_IMEM_B0ESD)
+			reason = "BTE 0 has been shutdown";
+		else if (hubii_imem & IIO_IMEM_B1ESD)
+			reason = "BTE 1 has been shutdown";
+		else	reason = "Unknown";
+	
+	}
+	/*
+	 * Note: we may never be able to print this, if the II talking
+	 * to Xbow which hosts the console is dead. 
+	 */
+	printk("Hub %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
+		hinfo->h_cnodeid, reason);
+    }
+
+    /* 
+     * It's a toss as to which one among PRB/CRB to check first. 
+     * Current decision is based on the severity of the errors. 
+     * IO CRB errors tend to be more severe than PRB errors.
+     *
+     * It is possible for BTE errors to have been handled already, so we
+     * may not see any errors handled here. 
+     */
+    (void)hubiio_crb_error_handler(hub_v, hinfo);
+    (void)hubiio_prb_error_handler(hub_v, hinfo);
+    /*
+     * If we reach here, it indicates crb/prb handlers successfully
+     * handled the error. So, re-enable II to send more interrupt
+     * and return.
+     */
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xffffff);
+    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
+}
+
+/*
+ * Free the hub CRB "crbnum" which encountered an error.
+ * Assumption is, error handling was successfully done,
+ * and we now want to return the CRB back to Hub for normal usage.
+ *
+ * In order to free the CRB, all that's needed is to de-allocate it
+ *
+ * Assumption:
+ *      No other processor is mucking around with the hub control register.
+ *      So, upper layer has to single thread this.
+ */
+void
+hubiio_crb_free(hubinfo_t hinfo, int crbnum)
+{
+	ii_icrb0_a_u_t         icrba;
+
+	/*
+	* The hardware does NOT clear the mark bit, so it must get cleared
+	* here to be sure the error is not processed twice.
+	*/
+	icrba.ii_icrb0_a_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ICRB_A(crbnum));
+	icrba.a_valid   = 0;
+	REMOTE_HUB_S(hinfo->h_nasid, IIO_ICRB_A(crbnum), icrba.ii_icrb0_a_regval);
+	/*
+	* Deallocate the register.
+	*/
+
+	REMOTE_HUB_S(hinfo->h_nasid, IIO_ICDR, (IIO_ICDR_PND | crbnum));
+
+	/*
+	* Wait till hub indicates it's done.
+	*/
+	while (REMOTE_HUB_L(hinfo->h_nasid, IIO_ICDR) & IIO_ICDR_PND)
+		us_delay(1);
+
+}
+
+
+/*
+ * Array of error names  that get logged in CRBs
+ */ 
+char *hubiio_crb_errors[] = {
+	"Directory Error",
+	"CRB Poison Error",
+	"I/O Write Error",
+	"I/O Access Error",
+	"I/O Partial Write Error",
+	"I/O Partial Read Error",
+	"I/O Timeout Error",
+	"Xtalk Error Packet"
+};
+
+/*
+ * hubiio_crb_error_handler
+ *
+ *	This routine gets invoked when a hub gets an error 
+ *	interrupt. So, the routine is running in interrupt context
+ *	at error interrupt level.
+ * Action:
+ *	It's responsible for identifying ALL the CRBs that are marked
+ *	with error, and process them. 
+ *	
+ * 	If you find the CRB that's marked with error, map this to the
+ *	reason it caused error, and invoke appropriate error handler.
+ *
+ *	XXX Be aware of the information in the context register.
+ *
+ * NOTE:
+ *	Use REMOTE_HUB_* macro instead of LOCAL_HUB_* so that the interrupt
+ *	handler can be run on any node. (not necessarily the node 
+ *	corresponding to the hub that encountered error).
+ */
+
+int
+hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
+{
+	cnodeid_t	cnode;
+	nasid_t		nasid;
+	ii_icrb0_a_u_t		icrba;		/* II CRB Register A */
+	ii_icrb0_b_u_t		icrbb;		/* II CRB Register B */
+	ii_icrb0_c_u_t		icrbc;		/* II CRB Register C */
+	ii_icrb0_d_u_t		icrbd;		/* II CRB Register D */
+	int		i;
+	int		num_errors = 0;	/* Num of errors handled */
+	ioerror_t	ioerror;
+
+	nasid = hinfo->h_nasid;
+	cnode = NASID_TO_COMPACT_NODEID(nasid);
+
+	/*
+	 * Scan through all CRBs in the Hub, and handle the errors
+	 * in any of the CRBs marked.
+	 */
+	for (i = 0; i < IIO_NUM_CRBS; i++) {
+		icrba.ii_icrb0_a_regval = REMOTE_HUB_L(nasid, IIO_ICRB_A(i));
+
+		IOERROR_INIT(&ioerror);
+
+		/* read other CRB error registers. */
+		icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(nasid, IIO_ICRB_B(i));
+		icrbc.ii_icrb0_c_regval = REMOTE_HUB_L(nasid, IIO_ICRB_C(i));
+		icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
+
+		IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);
+		/* Check if this error is due to BTE operation,
+		* and handle it separately.
+		*/
+		if (icrbd.d_bteop ||
+			((icrbb.b_initiator == IIO_ICRB_INIT_BTE0 ||
+			icrbb.b_initiator == IIO_ICRB_INIT_BTE1) &&
+			(icrbb.b_imsgtype == IIO_ICRB_IMSGT_BTE ||
+			icrbb.b_imsgtype == IIO_ICRB_IMSGT_SN1NET))){
+
+			int bte_num;
+
+			if (icrbd.d_bteop)
+				bte_num = icrbc.c_btenum;
+			else /* b_initiator bit 2 gives BTE number */
+				bte_num = (icrbb.b_initiator & 0x4) >> 2;
+
+			bte_crb_error_handler(hub_v, bte_num,
+					i, &ioerror);
+			hubiio_crb_free(hinfo, i);
+			num_errors++;
+			continue;
+		}
+
+		/*
+		 * XXX
+		 * Assuming the only other error that would reach here is
+		 * crosstalk errors. 
+		 * If CRB times out on a message from Xtalk, it changes 
+		 * the message type to CRB. 
+		 *
+		 * If we get here due to other errors (SN0net/CRB)
+		 * what's the action ?
+		 */
+
+		/*
+		 * Pick out the useful fields in CRB, and
+		 * tuck them away into ioerror structure.
+		 */
+		IOERROR_SETVALUE(&ioerror,xtalkaddr,icrba.a_addr << IIO_ICRB_ADDR_SHFT);
+		IOERROR_SETVALUE(&ioerror,widgetnum,icrba.a_sidn);
+
+
+		if (icrba.a_iow){
+			/*
+			 * XXX We shouldn't really have BRIDGE-specific code
+			 * here, but alas....
+			 *
+			 * The BRIDGE (or XBRIDGE) sets the upper bit of TNUM
+			 * to indicate a WRITE operation.  It sets the next
+			 * bit to indicate an INTERRUPT operation.  The bottom
+			 * 3 bits of TNUM indicate which device was responsible.
+			 */
+			IOERROR_SETVALUE(&ioerror,widgetdev,
+					 TNUM_TO_WIDGET_DEV(icrba.a_tnum));
+
+		}
+
+	}
+	return	num_errors;
+}
+
+/*ARGSUSED*/
+/*
+ * hubii_prb_handler
+ *      Handle the error reported in the PRB for wiget number wnum.
+ *      This typically happens on a PIO write error.
+ *      There is nothing much we can do in this interrupt context for
+ *      PIO write errors. For e.g. QL scsi controller has the
+ *      habit of flaking out on PIO writes.
+ *      Print a message and try to continue for now
+ *      Cleanup involes freeing the PRB register
+ */
+static void
+hubii_prb_handler(devfs_handle_t hub_v, hubinfo_t hinfo, int wnum)
+{
+        nasid_t         nasid;
+
+        nasid = hinfo->h_nasid;
+        /*
+         * Clear error bit by writing to IECLR register.
+         */
+        REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, (1 << wnum));
+        /*
+         * PIO Write to Widget 'i' got into an error.
+         * Invoke hubiio_error_handler with this information.
+         */
+        printk( "Hub nasid %d got a PIO Write error from widget %d, cleaning up and continuing",
+                        nasid, wnum);
+        /*
+         * XXX
+         * It may be necessary to adjust IO PRB counter
+         * to account for any lost credits.
+         */
+}
+
+int
+hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
+{
+        int             wnum;
+        nasid_t         nasid;
+        int             num_errors = 0;
+        iprb_t          iprb;
+
+        nasid = hinfo->h_nasid;
+        /*
+         * Check if IPRB0 has any error first.
+         */
+        iprb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB(0));
+        if (iprb.iprb_error) {
+                num_errors++;
+                hubii_prb_handler(hub_v, hinfo, 0);
+        }
+        /*
+         * Look through PRBs 8 - F to see if any of them has error bit set.
+         * If true, invoke hub iio error handler for this widget.
+         */
+        for (wnum = HUB_WIDGET_ID_MIN; wnum <= HUB_WIDGET_ID_MAX; wnum++) {
+                iprb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB(wnum));
+
+                if (!iprb.iprb_error)
+                        continue;
+
+                num_errors++;
+                hubii_prb_handler(hub_v, hinfo, wnum);
+        }
+
+        return num_errors;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/stubs.c linux/arch/ia64/sn/io/stubs.c
--- linux.orig/arch/ia64/sn/io/stubs.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/stubs.c	2002-07-20 01:08:30.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -21,6 +20,7 @@
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/slotnum.h>
 #include <asm/sn/vector.h>
+#include <asm/sn/nic.h>
 
 /******
  ****** hack defines ......
@@ -61,45 +61,45 @@
 }
 
 void *
-kmem_alloc_node(register size_t size, register int flags, cnodeid_t node)
+snia_kmem_alloc_node(register size_t size, register int flags, cnodeid_t node)
 {
         /* Allocates on node 'node' */
-	FIXME("kmem_alloc_node : use kmalloc");
+	FIXME("snia_kmem_alloc_node : use kmalloc");
 	return(kmalloc(size, GFP_KERNEL));
 }
 
 void *
-kmem_zalloc_node(register size_t size, register int flags, cnodeid_t node)
+snia_kmem_zalloc_node(register size_t size, register int flags, cnodeid_t node)
 {
-	FIXME("kmem_zalloc_node : use kmalloc");
+	FIXME("snia_kmem_zalloc_node : use kmalloc");
 	return(kmalloc(size, GFP_KERNEL));
 }
 
 void
-kmem_free(void *where, int size)
+snia_kmem_free(void *where, int size)
 {
-	FIXME("kmem_free : use kfree");
+	FIXME("snia_kmem_free : use kfree");
 	return(kfree(where));
 }
 
 
 void *
-kmem_zone_alloc(register zone_t *zone, int flags)
+snia_kmem_zone_alloc(register zone_t *zone, int flags)
 {
-	FIXME("kmem_zone_alloc : return null");
+	FIXME("snia_kmem_zone_alloc : return null");
 	return((void *)0);
 }
 
 void
-kmem_zone_free(register zone_t *zone, void *ptr)
+snia_kmem_zone_free(register zone_t *zone, void *ptr)
 {
-	FIXME("kmem_zone_free : no-op");
+	FIXME("snia_kmem_zone_free : no-op");
 }
 
 zone_t *
-kmem_zone_init(register int size, char *zone_name)
+snia_kmem_zone_init(register int size, char *zone_name)
 {
-	FIXME("kmem_zone_free : returns NULL");
+	FIXME("snia_kmem_zone_free : returns NULL");
 	return((zone_t *)0);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/xbow.c linux/arch/ia64/sn/io/xbow.c
--- linux.orig/arch/ia64/sn/io/xbow.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/xbow.c	2002-07-20 01:08:21.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -19,6 +18,7 @@
 #include <asm/sn/hack.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/xtalk/xtalk_private.h>
+#include <asm/sn/simulator.h>
 
 /* #define DEBUG		1 */
 /* #define XBOW_DEBUG	1 */
@@ -102,7 +102,6 @@
 #ifdef LATER
 static void             xbow_setwidint(xtalk_intr_t);
 static void             xbow_errintr_handler(intr_arg_t);
-static error_handler_f  xbow_error_handler;
 #endif
 void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
 
@@ -281,7 +280,7 @@
                         /* &hcl_fops */ (void *)&vhdl, NULL);
     if (!vhdl) {
         printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
-                conn);
+                (void *)conn);
     }
 
     /*
@@ -306,7 +305,7 @@
 
     /*
      * get the name of this xbow vertex and keep the info.
-     * This is needed during errors and interrupts, but as
+     * This is needed during errors and interupts, but as
      * long as we have it, we can use it elsewhere.
      */
     s = dev_to_name(vhdl, devnm, MAXDEVNAME);
@@ -371,36 +370,9 @@
     }
 
     /*
-     * attach the crossbow error interrupt.
-     */
-#ifdef LATER
-    dev_desc = device_desc_dup(vhdl);
-    device_desc_flags_set(dev_desc,
-			  device_desc_flags_get(dev_desc) | D_INTR_ISERR);
-    device_desc_intr_name_set(dev_desc, "Crossbow error");
-
-    intr_hdl = xtalk_intr_alloc(conn, dev_desc, vhdl);
-    ASSERT(intr_hdl != NULL);
-
-    xtalk_intr_connect(intr_hdl,
-		       (intr_func_t) xbow_errintr_handler,
-		       (intr_arg_t) soft,
-		       (xtalk_intr_setfunc_t) xbow_setwidint,
-		       (void *) xbow,
-		       (void *) 0);
-    device_desc_free(dev_desc);
-
-    xwidget_error_register(conn, xbow_error_handler, soft);
-
-#else
-    FIXME("xbow_attach: Fixme: we bypassed attaching xbow error interrupt.\n");
-#endif /* LATER */
-
-    /*
      * Enable xbow error interrupts
      */
-    xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE |
-			    XB_WID_CTRL_XTALK_IE);
+    xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE);
 
     /*
      * take a census of the widgets present,
@@ -918,460 +890,6 @@
     return 1;
 }
 
-/*
- * xbow_errintr_handler will be called if the xbow
- * sends an interrupt request to report an error.
- */
-
-#ifdef LATER
-static void
-xbow_errintr_handler(intr_arg_t arg)
-{
-    ioerror_t               ioe[1];
-    xbow_soft_t             soft = (xbow_soft_t) arg;
-    xbow_t                 *xbow = soft->base;
-    xbowreg_t               wid_control;
-    xbowreg_t               wid_stat;
-    xbowreg_t               wid_err_cmdword;
-    xbowreg_t               wid_err_upper;
-    xbowreg_t               wid_err_lower;
-    w_err_cmd_word_u        wid_err;
-    uint64_t                 wid_err_addr;
-
-    int                     fatal = 0;
-    int                     dump_ioe = 0;
-
-    wid_control = xbow->xb_wid_control;
-    wid_stat = xbow->xb_wid_stat_clr;
-    wid_err_cmdword = xbow->xb_wid_err_cmdword;
-    wid_err_upper = xbow->xb_wid_err_upper;
-    wid_err_lower = xbow->xb_wid_err_lower;
-    xbow->xb_wid_err_cmdword = 0;
-
-    wid_err_addr =
-	wid_err_lower
-	| (((iopaddr_t) wid_err_upper
-	    & WIDGET_ERR_UPPER_ADDR_ONLY)
-	   << 32);
-
-    if (wid_stat & XB_WID_STAT_LINK_INTR_MASK) {
-	int                     port;
-
-	wid_err.r = wid_err_cmdword;
-
-	for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;
-	     port < MAX_PORT_NUM; port++) {
-	    if (wid_stat & XB_WID_STAT_LINK_INTR(port)) {
-		xb_linkregs_t          *link = &(xbow->xb_link(port));
-		xbowreg_t               link_control = link->link_control;
-		xbowreg_t               link_status = link->link_status_clr;
-		xbowreg_t               link_aux_status = link->link_aux_status;
-		xbowreg_t               link_pend;
-
-		link_pend = link_status & link_control &
-		    (XB_STAT_ILLEGAL_DST_ERR
-		     | XB_STAT_OALLOC_IBUF_ERR
-		     | XB_STAT_RCV_CNT_OFLOW_ERR
-		     | XB_STAT_XMT_CNT_OFLOW_ERR
-		     | XB_STAT_XMT_MAX_RTRY_ERR
-		     | XB_STAT_RCV_ERR
-		     | XB_STAT_XMT_RTRY_ERR
-		     | XB_STAT_MAXREQ_TOUT_ERR
-		     | XB_STAT_SRC_TOUT_ERR
-		    );
-
-		if (link_pend & XB_STAT_ILLEGAL_DST_ERR) {
-		    if (wid_err.f.sidn == port) {
-			IOERROR_INIT(ioe);
-			IOERROR_SETVALUE(ioe, widgetnum, port);
-			IOERROR_SETVALUE(ioe, xtalkaddr, wid_err_addr);
-			if (IOERROR_HANDLED ==
-			    xbow_error_handler(soft,
-					       IOECODE_DMA,
-					       MODE_DEVERROR,
-					       ioe)) {
-			    link_pend &= ~XB_STAT_ILLEGAL_DST_ERR;
-			} else {
-			    dump_ioe++;
-			}
-		    }
-		}
-		/* Xbow/Bridge WAR:
-		 * if the bridge signals an LLP Transmitter Retry,
-		 * rewrite its control register.
-		 * If someone else triggers this interrupt,
-		 * ignore (and disable) the interrupt.
-		 */
-		if (link_pend & XB_STAT_XMT_RTRY_ERR) {
-		    if (!xbow_xmit_retry_error(soft, port)) {
-			link_control &= ~XB_CTRL_XMT_RTRY_IE;
-			link->link_control = link_control;
-			link->link_control;	/* stall until written */
-		    }
-		    link_pend &= ~XB_STAT_XMT_RTRY_ERR;
-		}
-		if (link_pend) {
-		    devfs_handle_t	xwidget_vhdl;
-		    char		*xwidget_name;
-		    
-		    /* Get the widget name corresponding to the current
-		     * xbow link.
-		     */
-		    xwidget_vhdl = xbow_widget_lookup(soft->busv,port);
-		    xwidget_name = xwidget_name_get(xwidget_vhdl);
-
-#ifdef	LATER
-		    printk("%s port %X[%s] XIO Bus Error",
-			    soft->name, port, xwidget_name);
-		    if (link_status & XB_STAT_MULTI_ERR)
-			XEM_ADD_STR("\tMultiple Errors\n");
-		    if (link_status & XB_STAT_ILLEGAL_DST_ERR)
-			XEM_ADD_STR("\tInvalid Packet Destination\n");
-		    if (link_status & XB_STAT_OALLOC_IBUF_ERR)
-			XEM_ADD_STR("\tInput Overallocation Error\n");
-		    if (link_status & XB_STAT_RCV_CNT_OFLOW_ERR)
-			XEM_ADD_STR("\tLLP receive error counter overflow\n");
-		    if (link_status & XB_STAT_XMT_CNT_OFLOW_ERR)
-			XEM_ADD_STR("\tLLP transmit retry counter overflow\n");
-		    if (link_status & XB_STAT_XMT_MAX_RTRY_ERR)
-			XEM_ADD_STR("\tLLP Max Transmitter Retry\n");
-		    if (link_status & XB_STAT_RCV_ERR)
-			XEM_ADD_STR("\tLLP Receiver error\n");
-		    if (link_status & XB_STAT_XMT_RTRY_ERR)
-			XEM_ADD_STR("\tLLP Transmitter Retry\n");
-		    if (link_status & XB_STAT_MAXREQ_TOUT_ERR)
-			XEM_ADD_STR("\tMaximum Request Timeout\n");
-		    if (link_status & XB_STAT_SRC_TOUT_ERR)
-			XEM_ADD_STR("\tSource Timeout Error\n");
-#endif	/* LATER */
-		    {
-			int                     other_port;
-
-			for (other_port = 8; other_port < 16; ++other_port) {
-			    if (link_aux_status & (1 << other_port)) {
-				/* XXX- need to go to "other_port"
-				 * and clean up after the timeout?
-				 */
-				XEM_ADD_VAR(other_port);
-			    }
-			}
-		    }
-
-#if !DEBUG
-		    if (kdebug) {
-#endif
-			XEM_ADD_VAR(link_control);
-			XEM_ADD_VAR(link_status);
-			XEM_ADD_VAR(link_aux_status);
-
-			if (dump_ioe) {
-			    XEM_ADD_IOE();
-			    dump_ioe = 0;
-			}
-#if !DEBUG
-		    }
-#endif
-		    fatal++;
-		}
-	    }
-	}
-    }
-    if (wid_stat & wid_control & XB_WID_STAT_WIDGET0_INTR) {
-	/* we have a "widget zero" problem */
-
-	if (wid_stat & (XB_WID_STAT_MULTI_ERR
-			| XB_WID_STAT_XTALK_ERR
-			| XB_WID_STAT_REG_ACC_ERR)) {
-
-	    printk("%s Port 0 XIO Bus Error",
-		    soft->name);
-	    if (wid_stat & XB_WID_STAT_MULTI_ERR)
-		XEM_ADD_STR("\tMultiple Error\n");
-	    if (wid_stat & XB_WID_STAT_XTALK_ERR)
-		XEM_ADD_STR("\tXIO Error\n");
-	    if (wid_stat & XB_WID_STAT_REG_ACC_ERR)
-		XEM_ADD_STR("\tRegister Access Error\n");
-
-	    fatal++;
-	}
-    }
-    if (fatal) {
-	XEM_ADD_VAR(wid_stat);
-	XEM_ADD_VAR(wid_control);
-	XEM_ADD_VAR(wid_err_cmdword);
-	XEM_ADD_VAR(wid_err_upper);
-	XEM_ADD_VAR(wid_err_lower);
-	XEM_ADD_VAR(wid_err_addr);
-	PRINT_PANIC("XIO Bus Error");
-    }
-}
-#endif	/* LATER */
-
-/*
- * XBOW ERROR Handling routines.
- * These get invoked as part of walking down the error handling path
- * from hub/heart towards the I/O device that caused the error.
- */
-
-/*
- * xbow_error_handler
- *      XBow error handling dispatch routine.
- *      This is the primary interface used by external world to invoke
- *      in case of an error related to a xbow.
- *      Only functionality in this layer is to identify the widget handle
- *      given the widgetnum. Otherwise, xbow does not gathers any error
- *      data.
- */
-
-#ifdef LATER
-static int
-xbow_error_handler(
-		      void *einfo,
-		      int error_code,
-		      ioerror_mode_t mode,
-		      ioerror_t *ioerror)
-{
-    int                     retval = IOERROR_WIDGETLEVEL;
-
-    xbow_soft_t             soft = (xbow_soft_t) einfo;
-    int                     port;
-    devfs_handle_t            conn;
-    devfs_handle_t            busv;
-
-    xbow_t                 *xbow = soft->base;
-    xbowreg_t               wid_stat;
-    xbowreg_t               wid_err_cmdword;
-    xbowreg_t               wid_err_upper;
-    xbowreg_t               wid_err_lower;
-    uint64_t                 wid_err_addr;
-
-    xb_linkregs_t          *link;
-    xbowreg_t               link_control;
-    xbowreg_t               link_status;
-    xbowreg_t               link_aux_status;
-
-    ASSERT(soft != 0);
-    busv = soft->busv;
-
-#if DEBUG && ERROR_DEBUG
-    printk("%s: xbow_error_handler\n", soft->name, busv);
-#endif
-
-    port = IOERROR_GETVALUE(ioerror, widgetnum);
-
-    if (port == 0) {
-	/* error during access to xbow:
-	 * do NOT attempt to access xbow regs.
-	 */
-	if (mode == MODE_DEVPROBE)
-	    return IOERROR_HANDLED;
-
-	if (error_code & IOECODE_DMA) {
-	    PRINT_ALERT("DMA error blamed on Crossbow at %s\n"
-		    "\tbut Crosbow never initiates DMA!",
-		    soft->name);
-	}
-	if (error_code & IOECODE_PIO) {
-	    PRINT_ALERt("PIO Error on XIO Bus %s\n"
-		    "\tattempting to access XIO controller\n"
-		    "\twith offset 0x%X",
-		    soft->name,
-		    IOERROR_GETVALUE(ioerror, xtalkaddr));
-	}
-	/* caller will dump contents of ioerror
-	 * in DEBUG and kdebug kernels.
-	 */
-
-	return retval;
-    }
-    /*
-     * error not on port zero:
-     * safe to read xbow registers.
-     */
-    wid_stat = xbow->xb_wid_stat;
-    wid_err_cmdword = xbow->xb_wid_err_cmdword;
-    wid_err_upper = xbow->xb_wid_err_upper;
-    wid_err_lower = xbow->xb_wid_err_lower;
-
-    wid_err_addr =
-	wid_err_lower
-	| (((iopaddr_t) wid_err_upper
-	    & WIDGET_ERR_UPPER_ADDR_ONLY)
-	   << 32);
-
-    if ((port < BASE_XBOW_PORT) ||
-	(port >= MAX_PORT_NUM)) {
-
-	if (mode == MODE_DEVPROBE)
-	    return IOERROR_HANDLED;
-
-	if (error_code & IOECODE_DMA) {
-	    PRINT_ALERT("DMA error blamed on XIO port at %s/%d\n"
-		    "\tbut Crossbow does not support that port",
-		    soft->name, port);
-	}
-	if (error_code & IOECODE_PIO) {
-	    PRINT_ALERT("PIO Error on XIO Bus %s\n"
-		    "\tattempting to access XIO port %d\n"
-		    "\t(which Crossbow does not support)"
-		    "\twith offset 0x%X",
-		    soft->name, port,
-		    IOERROR_GETVALUE(ioerror, xtalkaddr));
-	}
-#if !DEBUG
-	if (kdebug) {
-#endif
-	    XEM_ADD_STR("Raw status values for Crossbow:\n");
-	    XEM_ADD_VAR(wid_stat);
-	    XEM_ADD_VAR(wid_err_cmdword);
-	    XEM_ADD_VAR(wid_err_upper);
-	    XEM_ADD_VAR(wid_err_lower);
-	    XEM_ADD_VAR(wid_err_addr);
-#if !DEBUG
-	}
-#endif
-
-	/* caller will dump contents of ioerror
-	 * in DEBUG and kdebug kernels.
-	 */
-
-	return retval;
-    }
-    /* access to valid port:
-     * ok to check port status.
-     */
-
-    link = &(xbow->xb_link(port));
-    link_control = link->link_control;
-    link_status = link->link_status;
-    link_aux_status = link->link_aux_status;
-
-    /* Check that there is something present
-     * in that XIO port.
-     */
-    if (!(link_aux_status & XB_AUX_STAT_PRESENT)) {
-	/* nobody connected. */
-	if (mode == MODE_DEVPROBE)
-	    return IOERROR_HANDLED;
-
-	if (error_code & IOECODE_DMA) {
-	    PRINT_ALERT("DMA error blamed on XIO port at %s/%d\n"
-		    "\tbut there is no device connected there.",
-		    soft->name, port);
-	}
-	if (error_code & IOECODE_PIO) {
-	    PRINT_ALERT("PIO Error on XIO Bus %s\n"
-		    "\tattempting to access XIO port %d\n"
-		    "\t(which has no device connected)"
-		    "\twith offset 0x%X",
-		    soft->name, port,
-		    IOERROR_GETVALUE(ioerror, xtalkaddr));
-	}
-#if !DEBUG
-	if (kdebug) {
-#endif
-	    XEM_ADD_STR("Raw status values for Crossbow:\n");
-	    XEM_ADD_VAR(wid_stat);
-	    XEM_ADD_VAR(wid_err_cmdword);
-	    XEM_ADD_VAR(wid_err_upper);
-	    XEM_ADD_VAR(wid_err_lower);
-	    XEM_ADD_VAR(wid_err_addr);
-	    XEM_ADD_VAR(port);
-	    XEM_ADD_VAR(link_control);
-	    XEM_ADD_VAR(link_status);
-	    XEM_ADD_VAR(link_aux_status);
-#if !DEBUG
-	}
-#endif
-	return retval;
-
-    }
-    /* Check that the link is alive.
-     */
-    if (!(link_status & XB_STAT_LINKALIVE)) {
-	/* nobody connected. */
-	if (mode == MODE_DEVPROBE)
-	    return IOERROR_HANDLED;
-
-	PRINT_ALERT("%s%sError on XIO Bus %s port %d",
-		(error_code & IOECODE_DMA) ? "DMA " : "",
-		(error_code & IOECODE_PIO) ? "PIO " : "",
-		soft->name, port);
-
-	if ((error_code & IOECODE_PIO) &&
-	    (IOERROR_FIELDVALID(ioerror, xtalkaddr))) {
-	    printk("\tAccess attempted to offset 0x%X\n",
-		    IOERROR_GETVALUE(ioerror, xtalkaddr));
-	}
-	if (link_aux_status & XB_AUX_LINKFAIL_RST_BAD)
-	    XEM_ADD_STR("\tLink never came out of reset\n");
-	else
-	    XEM_ADD_STR("\tLink failed while transferring data\n");
-
-    }
-    /* get the connection point for the widget
-     * involved in this error; if it exists and
-     * is not our connectpoint, cycle back through
-     * xtalk_error_handler to deliver control to
-     * the proper handler (or to report a generic
-     * crosstalk error).
-     *
-     * If the downstream handler won't handle
-     * the problem, we let our upstream caller
-     * deal with it, after (in DEBUG and kdebug
-     * kernels) dumping the xbow state for this
-     * port.
-     */
-    conn = xbow_widget_lookup(busv, port);
-    if ((conn != GRAPH_VERTEX_NONE) &&
-	(conn != soft->conn)) {
-	retval = xtalk_error_handler(conn, error_code, mode, ioerror);
-	if (retval == IOERROR_HANDLED)
-	    return IOERROR_HANDLED;
-    }
-    if (mode == MODE_DEVPROBE)
-	return IOERROR_HANDLED;
-
-    if (retval == IOERROR_UNHANDLED) {
-	retval = IOERROR_PANIC;
-
-	PRINT_ALERT("%s%sError on XIO Bus %s port %d",
-		(error_code & IOECODE_DMA) ? "DMA " : "",
-		(error_code & IOECODE_PIO) ? "PIO " : "",
-		soft->name, port);
-
-	if ((error_code & IOECODE_PIO) &&
-	    (IOERROR_FIELDVALID(ioerror, xtalkaddr))) {
-	    printk("\tAccess attempted to offset 0x%X\n",
-		    IOERROR_GETVALUE(ioerror, xtalkaddr));
-	}
-    }
-
-#if !DEBUG
-    if (kdebug) {
-#endif
-	XEM_ADD_STR("Raw status values for Crossbow:\n");
-	XEM_ADD_VAR(wid_stat);
-	XEM_ADD_VAR(wid_err_cmdword);
-	XEM_ADD_VAR(wid_err_upper);
-	XEM_ADD_VAR(wid_err_lower);
-	XEM_ADD_VAR(wid_err_addr);
-	XEM_ADD_VAR(port);
-	XEM_ADD_VAR(link_control);
-	XEM_ADD_VAR(link_status);
-	XEM_ADD_VAR(link_aux_status);
-#if !DEBUG
-    }
-#endif
-    /* caller will dump raw ioerror data
-     * in DEBUG and kdebug kernels.
-     */
-
-    return retval;
-}
-
-#endif	/* LATER */
-
 void
 xbow_update_perf_counters(devfs_handle_t vhdl)
 {
@@ -1520,7 +1038,7 @@
 
 	if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) {
 #ifdef	LATER
-	    PRINT_WARNING("link %d[%s]: bad status 0x%x\n",
+	    printk(KERN_WARNING  "link %d[%s]: bad status 0x%x\n",
 		    link, xwidget_name, lnk_sts.linkstatus);
 #endif
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/xswitch.c linux/arch/ia64/sn/io/xswitch.c
--- linux.orig/arch/ia64/sn/io/xswitch.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/io/xswitch.c	2002-07-20 01:08:28.000000000 +0000
@@ -4,14 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/io/xtalk.c linux/arch/ia64/sn/io/xtalk.c
--- linux.orig/arch/ia64/sn/io/xtalk.c	2001-04-12 19:16:35.000000000 +0000
+++ linux/arch/ia64/sn/io/xtalk.c	2002-07-20 01:08:26.000000000 +0000
@@ -4,24 +4,22 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
 #include <asm/sn/hcl_util.h>
-
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/xtalk/xswitch.h>
 #include <asm/sn/xtalk/xwidget.h>
-
 #include <asm/sn/xtalk/xtalk_private.h>
 
 /*
@@ -41,7 +39,6 @@
 
 cdl_p                   xtalk_registry = NULL;
 
-#include <asm/sn/agent.h>
 #define	DEV_FUNC(dev,func)	hub_##func
 #define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
 #define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
@@ -72,7 +69,7 @@
 xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
 xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
 void                    xtalk_intr_free(xtalk_intr_t);
-int                     xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *, void *);
+int                     xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *);
 void                    xtalk_intr_disconnect(xtalk_intr_t);
 devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
 int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
@@ -113,8 +110,6 @@
 					 xwidgetnum_t, devfs_handle_t, 
 					 xwidgetnum_t, async_attach_t);
 int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_error_register(devfs_handle_t, error_handler_f *,
-					       error_handler_arg_t);
 void                    xwidget_reset(devfs_handle_t);
 char			*xwidget_name_get(devfs_handle_t);
 #if !defined(DEV_FUNC)
@@ -472,14 +467,11 @@
  */
 int
 xtalk_intr_connect(xtalk_intr_t intr_hdl,	/* xtalk intr resource handle */
-		   intr_func_t intr_func,	/* xtalk intr handler */
-		   intr_arg_t intr_arg,		/* arg to intr handler */
 		   xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-		   void *setfunc_arg,	/* arg to setfunc */
-		   void *thread)
-{				/* intr thread to use */
+		   void *setfunc_arg)	/* arg to setfunc */
+{
     return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl), intr_func, intr_arg, setfunc, setfunc_arg, thread);
+	(CAST_INTR(intr_hdl), setfunc, setfunc_arg);
 }
 
 
@@ -506,85 +498,6 @@
 }
 
 
-/*
- * =====================================================================
- *                      ERROR MANAGEMENT
- */
-
-/*
- * xtalk_error_handler:
- * pass this error on to the handler registered
- * at the specified xtalk connecdtion point,
- * or complain about it here if there is no handler.
- *
- * This routine plays two roles during error delivery
- * to most widgets: first, the external agent (heart,
- * hub, or whatever) calls in with the error and the
- * connect point representing the crosstalk switch,
- * or whatever crosstalk device is directly connected
- * to the agent.
- *
- * If there is a switch, it will generally look at the
- * widget number stashed in the ioerror structure; and,
- * if the error came from some widget other than the
- * switch, it will call back into xtalk_error_handler
- * with the connection point of the offending port.
- */
-int
-xtalk_error_handler(
-		       devfs_handle_t xconn,
-		       int error_code,
-		       ioerror_mode_t mode,
-		       ioerror_t *ioerror)
-{
-    xwidget_info_t          xwidget_info;
-
-#if DEBUG && ERROR_DEBUG
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    printk("%v: xtalk_error_handler\n", xconn);
-#else
-    printk("%x: xtalk_error_handler\n", xconn);
-#endif
-#endif
-
-    xwidget_info = xwidget_info_get(xconn);
-    /* Make sure that xwidget_info is a valid pointer before derefencing it.
-     * We could come in here during very early initialization. 
-     */
-    if (xwidget_info && xwidget_info->w_efunc)
-	return xwidget_info->w_efunc
-	    (xwidget_info->w_einfo,
-	     error_code, mode, ioerror);
-    /*
-     * no error handler registered for
-     * the offending port. it's not clear
-     * what needs to be done, but reporting
-     * it would be a good thing, unless it
-     * is a mode that requires nothing.
-     */
-    if ((mode == MODE_DEVPROBE) || (mode == MODE_DEVUSERERROR) ||
-	(mode == MODE_DEVREENABLE))
-	return IOERROR_HANDLED;
-
-#ifdef	LATER
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    PRINT_WARNING("Xbow at %v encountered Fatal error", xconn);
-#else
-    PRINT_WARNING("Xbow at %x encountered Fatal error", xconn);
-#endif
-#endif	/* LATER */
-    ioerror_dump("xtalk", error_code, mode, ioerror);
-
-    return IOERROR_UNHANDLED;
-}
-
-int
-xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
-{
-    return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code);
-}
-
-
 /* =====================================================================
  *                    CONFIGURATION MANAGEMENT
  */
@@ -977,7 +890,7 @@
     widget_info->w_einfo = 0;
     /*
      * get the name of this xwidget vertex and keep the info.
-     * This is needed during errors and interrupts, but as
+     * This is needed during errors and interupts, but as
      * long as we have it, we can use it elsewhere.
      */
     s = dev_to_name(widget,devnm,MAXDEVNAME);
@@ -1038,19 +951,6 @@
     return(0);
 }
 
-void
-xwidget_error_register(devfs_handle_t xwidget,
-		       error_handler_f *efunc,
-		       error_handler_arg_t einfo)
-{
-    xwidget_info_t          xwidget_info;
-
-    xwidget_info = xwidget_info_get(xwidget);
-    ASSERT(xwidget_info != NULL);
-    xwidget_info->w_efunc = efunc;
-    xwidget_info->w_einfo = einfo;
-}
-
 /*
  * Issue a link reset to a widget.
  */
@@ -1122,15 +1022,3 @@
 	
 	return(0);
 }
-/*
- * xtalk_device_inquiry
- *	Find out hardware information about the xtalk widget.
- */
-int
-xtalk_device_inquiry(devfs_handle_t xbus_vhdl, xwidgetnum_t widget)
-{
-
-	extern void hub_device_inquiry(devfs_handle_t, xwidgetnum_t);
-	hub_device_inquiry(xbus_vhdl, widget);
-	return(0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/Makefile linux/arch/ia64/sn/kernel/Makefile
--- linux.orig/arch/ia64/sn/kernel/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/Makefile	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,62 @@
+# arch/ia64/sn/Makefile
+#
+# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it 
+# under the terms of version 2 of the GNU General Public License 
+# as published by the Free Software Foundation.
+# 
+# This program is distributed in the hope that it would be useful, but 
+# WITHOUT ANY WARRANTY; without even the implied warranty of 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+# 
+# Further, this software is distributed without any warranty that it is 
+# free of the rightful claim of any third person regarding infringement 
+# or the like.  Any license provided herein, whether implied or 
+# otherwise, applies only to this software file.  Patent licenses, if 
+# any, provided herein do not apply to combinations of this program with 
+# other software, or any other product whatsoever.
+# 
+# You should have received a copy of the GNU General Public 
+# License along with this program; if not, write the Free Software 
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+# 
+# Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+# Mountain View, CA  94043, or:
+# 
+# http://www.sgi.com 
+# 
+# For further information regarding this notice, see: 
+# 
+# http://oss.sgi.com/projects/GenInfo/NoticeExplan
+#
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+.S.s:
+	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
+.S.o:
+	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
+
+O_TARGET        = sn.o
+
+ifeq ($(CONFIG_MODULES),y)
+export-objs = sn_ksyms.o
+endif
+
+subdir-$(CONFIG_IA64_SGI_SN1)	= sn1
+subdir-$(CONFIG_IA64_SGI_SN2)	= sn2
+
+obj-y		= probe.o setup.o sn_asm.o sv.o bte.o iomv.o
+obj-$(CONFIG_IA64_SGI_SN1)      += irq.o mca.o
+obj-$(CONFIG_IA64_SGI_SN2)      += irq.o mca.o
+
+obj-$(CONFIG_IA64_SGI_SN1)      += sn1/sn1.a  
+obj-$(CONFIG_IA64_SGI_SN2)      += sn2/sn2.a  
+
+obj-$(CONFIG_IA64_SGI_AUTOTEST) += llsc4.o misctest.o
+obj-$(CONFIG_IA64_GENERIC)      += machvec.o
+obj-$(CONFIG_MODULES)           += sn_ksyms.o
+
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/bte.c linux/arch/ia64/sn/kernel/bte.c
--- linux.orig/arch/ia64/sn/kernel/bte.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/bte.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,263 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <asm/sn/nodepda.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pda.h>
+#include <asm/nodedata.h>
+
+#include <linux/bootmem.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+
+#include <asm/sn/bte_copy.h>
+
+int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 };
+
+/*
+ * bte_init_node(nodepda, cnode, cmdline_p)
+ *
+ * Initialize the nodepda structure with BTE base addresses and
+ * spinlocks.
+ *
+ */
+void
+bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode, char **cmdline_p)
+{
+	int bteTestMode = 0;
+	int cmdoffset = 0;
+	int i;
+
+#ifdef ZZZ
+	if (!cmdoffset) {
+		for (;cmdline_p[cmdoffset]; cmdoffset++) {
+			if (strstr(cmdline_p[cmdoffset], "btetest")) {
+				bteTestMode = 1;
+				break;
+			}
+		}
+	}
+#endif
+
+	/*
+	 * Indicate that all the block transfer engines on this node
+	 * are available.
+	 */
+	for (i = 0; i < BTES_PER_NODE; i++) {
+#ifdef CONFIG_IA64_SGI_SN2
+		/* >>> Don't know why the 0x1800000L is here.  Robin */
+		mynodepda->node_bte_info[i].bte_base_addr =
+		    (char *)LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L);
+#elif CONFIG_IA64_SGI_SN1
+		mynodepda->node_bte_info[i].bte_base_addr =
+		    (char *)LOCAL_HUB_ADDR(bte_offsets[i]);
+#else
+#error BTE Not defined for this hardware platform.
+#endif
+
+#ifdef CONFIG_IA64_SGI_BTE_LOCKING
+		/* Initialize the notification and spinlock */
+		/* so the first transfer can occur. */
+		mynodepda->node_bte_info[i].mostRecentNotification =
+		    &(mynodepda->node_bte_info[i].notify);
+		mynodepda->node_bte_info[i].notify = 0L;
+		spin_lock_init(&mynodepda->node_bte_info[i].spinlock);
+#endif				/* CONFIG_IA64_SGI_BTE_LOCKING */
+
+		if (bteTestMode) {
+			mynodepda->node_bte_info[i].bteTestBuf =
+				alloc_bootmem_node(NODE_DATA(cnode),
+						   BTE_MAX_XFER);
+		}
+	}
+}
+
+/*
+ * bte_init_cpu()
+ *
+ * Initialize the cpupda structure with pointers to the
+ * nodepda bte blocks.
+ *
+ */
+void
+bte_init_cpu(void)
+{
+	/* Called by setup.c as each cpu is being added to the nodepda */
+	if (local_node_data->active_cpu_count & 0x1) {
+		pda.cpubte[0] = &(nodepda->node_bte_info[0]);
+		pda.cpubte[1] = &(nodepda->node_bte_info[1]);
+	} else {
+		pda.cpubte[0] = &(nodepda->node_bte_info[1]);
+		pda.cpubte[1] = &(nodepda->node_bte_info[0]);
+	}
+}
+
+
+/*
+ * bte_unaligned_copy(src, dest, len, mode)
+ *
+ * use the block transfer engine to move kernel
+ * memory from src to dest using the assigned mode.
+ *
+ * Paramaters:
+ *   src - physical address of the transfer source.
+ *   dest - physical address of the transfer destination.
+ *   len - number of bytes to transfer from source to dest.
+ *   mode - hardware defined.  See reference information
+ *          for IBCT0/1 in the SGI documentation.
+ *   bteBlock - kernel virtual address of a temporary
+ *              buffer used during unaligned transfers.
+ *
+ * NOTE: If the source, dest, and len are all cache line aligned,
+ * then it would be _FAR_ preferrable to use bte_copy instead.
+ */
+bte_result_t
+bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode, char *bteBlock)
+{
+	int destFirstCacheOffset;
+	u64 headBteSource;
+	u64 headBteLen;
+	u64 headBcopySrcOffset;
+	u64 headBcopyDest;
+	u64 headBcopyLen;
+	u64 footBteSource;
+	u64 footBteLen;
+	u64 footBcopyDest;
+	u64 footBcopyLen;
+	bte_result_t rv;
+
+	if (len == 0) {
+		return (BTE_SUCCESS);
+	}
+
+	headBcopySrcOffset = src & L1_CACHE_MASK;
+	destFirstCacheOffset = dest & L1_CACHE_MASK;
+
+	/*
+	 * At this point, the transfer is broken into
+	 * (up to) three sections.  The first section is
+	 * from the start address to the first physical
+	 * cache line, the second is from the first physical
+	 * cache line to the last complete cache line,
+	 * and the third is from the last cache line to the
+	 * end of the buffer.  The first and third sections
+	 * are handled by bte copying into a temporary buffer
+	 * and then bcopy'ing the necessary section into the
+	 * final location.  The middle section is handled with
+	 * a standard bte copy.
+	 *
+	 * One nasty exception to the above rule is when the
+	 * source and destination are not symetrically
+	 * mis-aligned.  If the source offset from the first
+	 * cache line is different from the destination offset,
+	 * we make the first section be the entire transfer
+	 * and the bcopy the entire block into place.
+	 */
+	if (headBcopySrcOffset == destFirstCacheOffset) {
+
+		/*
+		 * Both the source and destination are the same
+		 * distance from a cache line boundary so we can
+		 * use the bte to transfer the bulk of the
+		 * data.
+		 */
+		headBteSource = src & ~L1_CACHE_MASK;
+		headBcopyDest = dest;
+		if (headBcopySrcOffset) {
+			headBcopyLen =
+			    (len >
+			     (L1_CACHE_BYTES -
+			      headBcopySrcOffset) ? L1_CACHE_BYTES
+			     - headBcopySrcOffset : len);
+			headBteLen = L1_CACHE_BYTES;
+		} else {
+			headBcopyLen = 0;
+			headBteLen = 0;
+		}
+
+		if (len > headBcopyLen) {
+			footBcopyLen =
+			    (len - headBcopyLen) & L1_CACHE_MASK;
+			footBteLen = L1_CACHE_BYTES;
+
+			footBteSource = src + len - footBcopyLen;
+			footBcopyDest = dest + len - footBcopyLen;
+
+			if (footBcopyDest ==
+			    (headBcopyDest + headBcopyLen)) {
+				/*
+				 * We have two contigous bcopy
+				 * blocks.  Merge them.
+				 */
+				headBcopyLen += footBcopyLen;
+				headBteLen += footBteLen;
+			} else if (footBcopyLen > 0) {
+				rv = bte_copy(footBteSource,
+					      __pa(bteBlock),
+					      footBteLen, mode, NULL);
+				if (rv != BTE_SUCCESS) {
+					return (rv);
+				}
+
+
+				memcpy(__va(footBcopyDest),
+				       (char *)bteBlock, footBcopyLen);
+			}
+		} else {
+			footBcopyLen = 0;
+			footBteLen = 0;
+		}
+
+		if (len > (headBcopyLen + footBcopyLen)) {
+			/* now transfer the middle. */
+			rv = bte_copy((src + headBcopyLen),
+				      (dest +
+				       headBcopyLen),
+				      (len - headBcopyLen -
+				       footBcopyLen), mode, NULL);
+			if (rv != BTE_SUCCESS) {
+				return (rv);
+			}
+
+		}
+	} else {
+
+
+		/*
+		 * The transfer is not symetric, we will
+		 * allocate a buffer large enough for all the
+		 * data, bte_copy into that buffer and then
+		 * bcopy to the destination.
+		 */
+
+		/* Add the leader from source */
+		headBteLen = len + (src & L1_CACHE_MASK);
+		/* Add the trailing bytes from footer. */
+		headBteLen +=
+		    L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK);
+		headBteSource = src & ~L1_CACHE_MASK;
+		headBcopySrcOffset = src & L1_CACHE_MASK;
+		headBcopyDest = dest;
+		headBcopyLen = len;
+	}
+
+	if (headBcopyLen > 0) {
+		rv = bte_copy(headBteSource,
+			      __pa(bteBlock), headBteLen, mode, NULL);
+		if (rv != BTE_SUCCESS) {
+			return (rv);
+		}
+
+		memcpy(__va(headBcopyDest), ((char *)bteBlock +
+					     headBcopySrcOffset),
+		       headBcopyLen);
+	}
+	return (BTE_SUCCESS);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/iomv.c linux/arch/ia64/sn/kernel/iomv.c
--- linux.orig/arch/ia64/sn/kernel/iomv.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/iomv.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,119 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <asm/io.h>
+
+#if 1	/* ##jh */
+#ifdef CONFIG_IA64_SGI_SN1
+#define mmiob sn1_mmiob
+#else
+#define mmiob sn2_mmiob
+#endif
+extern void mmiob(void);
+#endif /* ##jh */
+
+extern void * sn_io_addr(unsigned long port); /* defined in sn[12]/iomv.c */
+
+/**
+ * sn_inb - read a byte from a port
+ * @port: port to read from
+ *
+ * Reads a byte from @port and returns it to the caller.
+ */
+unsigned int
+sn_inb (unsigned long port)
+{
+	volatile unsigned char *addr = sn_io_addr(port);
+	unsigned char ret;
+
+	ret = *addr;
+	__ia64_mf_a();
+	return ret;
+}
+
+/**
+ * sn_inw - read a word from a port
+ * @port: port to read from
+ *
+ * Reads a word from @port and returns it to the caller.
+ */
+unsigned int
+sn_inw (unsigned long port)
+{
+	volatile unsigned short *addr = sn_io_addr(port);
+	unsigned short ret;
+
+	ret = *addr;
+	__ia64_mf_a();
+	return ret;
+}
+
+/**
+ * sn_inl - read a word from a port
+ * @port: port to read from
+ *
+ * Reads a word from @port and returns it to the caller.
+ */
+unsigned int
+sn_inl (unsigned long port)
+{
+	volatile unsigned int *addr = sn_io_addr(port);
+	unsigned int ret;
+
+	ret = *addr;
+	__ia64_mf_a();
+	return ret;
+}
+
+/**
+ * sn_outb - write a byte to a port
+ * @port: port to write to
+ * @val: value to write
+ *
+ * Writes @val to @port.
+ */
+void
+sn_outb (unsigned char val, unsigned long port)
+{
+	volatile unsigned char *addr = sn_io_addr(port);
+
+	*addr = val;
+	mmiob();
+}
+
+/**
+ * sn_outw - write a word to a port
+ * @port: port to write to
+ * @val: value to write
+ *
+ * Writes @val to @port.
+ */
+void
+sn_outw (unsigned short val, unsigned long port)
+{
+	volatile unsigned short *addr = sn_io_addr(port);
+
+	*addr = val;
+	mmiob();
+}
+
+/**
+ * sn_outl - write a word to a port
+ * @port: port to write to
+ * @val: value to write
+ *
+ * Writes @val to @port.
+ */
+void
+sn_outl (unsigned int val, unsigned long port)
+{
+	volatile unsigned int *addr = sn_io_addr(port);
+
+	*addr = val;
+	mmiob();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/irq.c linux/arch/ia64/sn/kernel/irq.c
--- linux.orig/arch/ia64/sn/kernel/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/irq.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,343 @@
+/*
+ * Platform dependent support for SGI SN1
+ *
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <asm/current.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/types.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pciio_private.h>
+#ifdef ajmtestintr
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#endif /* ajmtestintr */
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/io.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/arch.h>
+
+int irq_to_bit_pos(int irq);
+
+
+
+static unsigned int
+sn_startup_irq(unsigned int irq)
+{
+        return(0);
+}
+
+static void
+sn_shutdown_irq(unsigned int irq)
+{
+}
+
+static void
+sn_disable_irq(unsigned int irq)
+{
+}
+
+static void
+sn_enable_irq(unsigned int irq)
+{
+}
+
+static void
+sn_ack_irq(unsigned int irq)
+{
+#ifdef CONFIG_IA64_SGI_SN1
+	int bit = -1;
+	unsigned long long intpend_val;
+	int subnode;
+#endif
+#ifdef CONFIG_IA64_SGI_SN2
+	unsigned long event_occurred, mask = 0;
+#endif
+	int nasid;
+
+	irq = irq & 0xff;
+	nasid = smp_physical_node_id();
+#ifdef CONFIG_IA64_SGI_SN1
+	subnode = cpuid_to_subnode(smp_processor_id());
+	if (irq == SGI_UART_IRQ) {
+		intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0);
+		if (intpend_val & (1L<<GFX_INTR_A) ) {
+			bit = GFX_INTR_A;
+			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
+		}
+		if ( intpend_val & (1L<<GFX_INTR_B) ) {
+			bit = GFX_INTR_B;
+			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
+		}
+		if (intpend_val & (1L<<PG_MIG_INTR) ) {
+			bit = PG_MIG_INTR;
+			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
+		}
+		if (intpend_val & (1L<<CC_PEND_A)) {
+			bit = CC_PEND_A;
+			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
+		}
+		if (intpend_val & (1L<<CC_PEND_B)) {
+			bit = CC_PEND_B;
+			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
+		}
+		return;
+	}
+	bit = irq_to_bit_pos(irq);
+	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
+#endif
+
+#ifdef CONFIG_IA64_SGI_SN2
+	event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
+	if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) {
+		mask |= (1 << SH_EVENT_OCCURRED_UART_INT_SHFT);
+	}
+	if (event_occurred & SH_EVENT_OCCURRED_IPI_INT_MASK) {
+		mask |= (1 << SH_EVENT_OCCURRED_IPI_INT_SHFT);
+	}
+	if (event_occurred & SH_EVENT_OCCURRED_II_INT0_MASK) {
+		mask |= (1 << SH_EVENT_OCCURRED_II_INT0_SHFT);
+	}
+	if (event_occurred & SH_EVENT_OCCURRED_II_INT1_MASK) {
+		mask |= (1 << SH_EVENT_OCCURRED_II_INT1_SHFT);
+	}
+	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS), mask );
+#endif
+}
+
+static void
+sn_end_irq(unsigned int irq)
+{
+#ifdef CONFIG_IA64_SGI_SN1
+	unsigned long long intpend_val, mask = 0x70L;
+	int subnode;
+#endif
+	int nasid;
+#ifdef CONFIG_IA64_SGI_SN2
+	unsigned long event_occurred;
+#endif
+
+	irq = irq & 0xff;
+#ifdef CONFIG_IA64_SGI_SN1
+	if (irq == SGI_UART_IRQ) {
+		nasid = smp_physical_node_id();
+		subnode = cpuid_to_subnode(smp_processor_id());
+		intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0);
+		if (intpend_val & mask) {
+			platform_send_ipi(smp_processor_id(), SGI_UART_IRQ, IA64_IPI_DM_INT, 0);
+		}
+	}
+#endif
+#ifdef CONFIG_IA64_SGI_SN2
+	if (irq == SGI_UART_VECTOR) {
+		nasid = smp_physical_node_id();
+		event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
+		// If the UART bit is set here, we may have received an interrupt from the
+		// UART that the driver missed.  To make sure, we IPI ourselves to force us
+		// to look again.
+		if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) {
+				platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR, IA64_IPI_DM_INT, 0);
+		}
+	}
+#endif
+
+}
+
+static void
+sn_set_affinity_irq(unsigned int irq, unsigned long mask)
+{
+}
+
+
+struct hw_interrupt_type irq_type_iosapic_level = {
+	"SN hub",
+	sn_startup_irq,
+	sn_shutdown_irq,
+	sn_enable_irq,
+	sn_disable_irq,
+	sn_ack_irq, 
+	sn_end_irq,
+	sn_set_affinity_irq
+};
+
+
+#define irq_type_sn irq_type_iosapic_level
+struct irq_desc *_sn_irq_desc[NR_CPUS];
+
+struct irq_desc *
+sn_irq_desc(unsigned int irq) {
+	int cpu = irq >> 8;
+
+	irq = irq & 0xff;
+
+	return(_sn_irq_desc[cpu] + irq);
+}
+
+u8
+sn_irq_to_vector(u8 irq) {
+	return(irq & 0xff);
+}
+
+unsigned int
+sn_local_vector_to_irq(u8 vector) {
+	return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
+}
+
+int
+sn_valid_irq(u8 irq) {
+
+	return( ((irq & 0xff) < NR_IRQS) && ((irq >> 8) < NR_CPUS) );
+}
+
+void *kmalloc(size_t, int);
+
+void
+sn_irq_init (void)
+{
+	int i;
+	irq_desc_t *base_desc = _irq_desc;
+
+	for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IRQS; i++) {
+		if (base_desc[i].handler == &no_irq_type) {
+			base_desc[i].handler = &irq_type_sn;
+		}
+	}
+}
+
+void
+sn_init_irq_desc(void) {
+	int i;
+	irq_desc_t *base_desc = _irq_desc, *p;
+
+	for (i=0; i < NR_CPUS; i++) {
+		p =  page_address(alloc_pages_node(local_cnodeid(), GFP_KERNEL,
+			get_order(sizeof(struct irq_desc) * NR_IRQS) ) );
+		ASSERT(p);
+		memcpy(p, base_desc, sizeof(struct irq_desc) * NR_IRQS);
+		_sn_irq_desc[i] = p;
+	}
+}
+
+
+#if !defined(CONFIG_IA64_SGI_SN)
+void
+sn_pci_fixup(void)
+{
+}
+#endif
+
+int
+bit_pos_to_irq(int bit) {
+#define BIT_TO_IRQ 64
+	if (bit > 118) bit = 118;
+
+#ifdef CONFIG_IA64_SGI_SN1
+	if (bit >= GFX_INTR_A && bit <= CC_PEND_B) {
+		return SGI_UART_IRQ;
+	}
+#endif
+
+        return bit + BIT_TO_IRQ;
+}
+
+int
+irq_to_bit_pos(int irq) {
+#define IRQ_TO_BIT 64
+	int bit = irq - IRQ_TO_BIT;
+
+        return bit;
+}
+
+#ifdef ajmtestintr
+
+#include <linux/timer.h>
+struct timer_list intr_test_timer;
+int intr_test_icount[NR_IRQS];
+struct intr_test_reg_struct {
+	pcibr_soft_t pcibr_soft;
+	int slot;
+};
+struct intr_test_reg_struct intr_test_registered[NR_IRQS];
+
+void
+intr_test_handle_timer(unsigned long data) {
+	int i;
+	bridge_t	*bridge;
+
+	for (i=0;i<NR_IRQS;i++) {
+		if (intr_test_registered[i].pcibr_soft) {
+			pcibr_soft_t pcibr_soft = intr_test_registered[i].pcibr_soft;
+			xtalk_intr_t intr = pcibr_soft->bs_intr[intr_test_registered[i].slot].bsi_xtalk_intr;
+			/* send interrupt */
+			bridge = pcibr_soft->bs_base;
+			bridge->b_force_always[intr_test_registered[i].slot].intr = 1;
+		}
+	}
+	del_timer(&intr_test_timer);
+	intr_test_timer.expires = jiffies + HZ/100;
+	add_timer(&intr_test_timer);
+}
+
+void
+intr_test_set_timer(void) {
+	intr_test_timer.expires = jiffies + HZ/100;
+	intr_test_timer.function = intr_test_handle_timer;
+	add_timer(&intr_test_timer);
+}
+
+void
+intr_test_register_irq(int irq, pcibr_soft_t pcibr_soft, int slot) {
+	irq = irq & 0xff;
+	intr_test_registered[irq].pcibr_soft = pcibr_soft;
+	intr_test_registered[irq].slot = slot;
+}
+
+void
+intr_test_handle_intr(int irq, void *junk, struct pt_regs *morejunk) {
+	intr_test_icount[irq]++;
+	printk("RECEIVED %d INTERRUPTS ON IRQ %d\n",intr_test_icount[irq], irq);
+}
+#endif /* ajmtestintr */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/llsc4.c linux/arch/ia64/sn/kernel/llsc4.c
--- linux.orig/arch/ia64/sn/kernel/llsc4.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/llsc4.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,1044 @@
+/* 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <asm/efi.h>
+#include <asm/page.h>
+#include <linux/threads.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/leds.h>
+
+#include "llsc4.h"
+
+
+#ifdef STANDALONE
+#include "lock.h"
+#endif
+
+#ifdef INTTEST
+static int	inttest=0;
+#endif
+
+#ifdef IA64_SEMFIX_INSN
+#undef IA64_SEMFIX_INSN
+#endif
+#ifdef IA64_SEMFIX
+#undef IA64_SEMFIX
+#endif
+# define IA64_SEMFIX_INSN
+# define IA64_SEMFIX    ""
+
+#define NOLOCK		0xdead
+#define BGUARD(linei)	(0xbbbb0000 | (linei));
+#define EGUARD(linei)	(0xeeee0000 | (linei));
+#define GUARDLINE(v)	((v)&0xffff)
+
+/*
+ * Test parameter table for AUTOTEST
+ */
+typedef struct {
+	int	passes;
+	int	linecount;
+	int	linepad;
+} autotest_table_t;
+
+autotest_table_t autotest_table[] = {
+	{50000000,	2,	0x2b4		},
+	{50000000,	16,	0,		},
+	{50000000,	16,	4,		},
+	{50000000,	128,	0x44		},
+	{50000000,	128,	0x84		},
+	{50000000,	128,	0x200		},
+	{50000000,	128,	0x204		},
+	{50000000,	128,	0x2b4		},
+	{50000000,	2,	8*MB+0x2b4	},
+	{50000000,	16,	8*MB+0		},
+	{50000000,	16,	8*MB+4		},
+	{50000000,	128,	8*MB+0x44	},
+	{50000000,	128,	8*MB+0x84	},
+	{50000000,	128,	8*MB+0x200	},
+	{50000000,	128,	8*MB+0x204	},
+	{50000000,	128,	8*MB+0x2b4	},
+	{0}};
+
+/*
+ * Array of virtual addresses available for test purposes.
+ */
+
+typedef struct {
+	long	vstart;
+	long	vend;
+	long	nextaddr;
+	long	nextinit;
+	int	wrapcount;
+} memmap_t;
+
+#define MAPCHUNKS		128
+memmap_t 	memmap[MAPCHUNKS];
+int		memmapx=0;
+
+typedef struct {
+	void	*addr;
+	long	data[16];
+	long	data_fc[16];
+} capture_line_t;
+
+typedef struct {
+	int	size;
+	void	*blockaddr;
+	void	*shadaddr;
+	long	blockdata[48];
+	long	shaddata[48];
+	long	blockdata_fc[48];
+	long	shaddata_fc[48];
+	long	synerr;
+} capture_t;
+
+/*
+ * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and
+ * the rest of the tables have to start at 1MB to skip PROM tables.
+ */
+#define THREADPRIVATESZ()	((sizeof(threadprivate_t)+511)/512*512)
+#define THREADPRIVATE(t)	((threadprivate_t*)(((long)mbase)+4096+t*THREADPRIVATESZ()))
+
+#define k_capture		mbase->sk_capture
+#define k_go			mbase->sk_go
+#define k_linecount		mbase->sk_linecount
+#define k_passes		mbase->sk_passes
+#define k_napticks		mbase->sk_napticks
+#define k_stop_on_error		mbase->sk_stop_on_error
+#define k_verbose		mbase->sk_verbose
+#define k_threadprivate		mbase->sk_threadprivate
+#define k_blocks		mbase->sk_blocks
+#define k_iter_msg		mbase->sk_iter_msg
+#define k_vv			mbase->sk_vv
+#define k_linepad		mbase->sk_linepad
+#define k_options		mbase->sk_options
+#define k_testnumber		mbase->sk_testnumber
+#define k_currentpass		mbase->sk_currentpass
+
+static long		blocks[MAX_LINECOUNT];		/* addresses of data blocks */
+static control_t	*mbase;
+static vint		initialized=0;
+
+static unsigned int ran_conf_llsc(int);
+static int  rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int);
+static void dumpline(void *, char *, char *, void *, void *, int);
+static int  checkstop(int, int, uint);
+static void spin(int);
+static void capturedata(capture_t *, uint, void *, void *, int);
+static int  randn(uint max, uint *seed);
+static uint zrandom (uint *zranseed);
+static int  set_lock(uint *, uint);
+static int  clr_lock(uint *, uint);
+static void Speedo(void);
+
+int autotest_enabled=0;
+static int llsctest_number=-1;
+static int errstop_enabled=0;
+static int fail_enabled=0;
+static int l4_opt=0;
+static int selective_trigger=0;
+static int dump_block_addrs_opt=0;
+static lock_t errlock=NOLOCK;
+static private_t init_private[LLSC_MAXCPUS];
+
+static int __init autotest_enable(char *str)
+{
+        autotest_enabled = 1;
+	return 1;
+}
+static int __init set_llscblkadr(char *str)
+{
+	dump_block_addrs_opt = 1;
+	return 1;
+}
+static int __init set_llscselt(char *str)
+{
+	selective_trigger = 1;
+	return 1;
+}
+static int __init set_llsctest(char *str)
+{
+        llsctest_number = simple_strtol(str, &str, 10);
+	if (llsctest_number < 0 || llsctest_number > 15)
+		llsctest_number = -1;
+	return 1;
+}
+static int __init set_llscerrstop(char *str)
+{
+        errstop_enabled = 1;
+	return 1;
+}
+static int __init set_llscfail(char *str)
+{
+        fail_enabled = 8;
+	return 1;
+}
+static int __init set_llscl4(char *str)
+{
+        l4_opt = 1;
+	return 1;
+}
+
+static void print_params(void)
+{
+	printk ("********* Enter AUTOTEST facility on master cpu *************\n");
+	printk ("  Test options:\n");
+	printk ("     llsctest=<n>\t%d\tTest number to run (all = -1)\n", llsctest_number);
+	printk ("     llscerrstop \t%s\tStop on error\n", errstop_enabled ? "on" : "off");
+	printk ("     llscfail    \t%s\tForce a failure to test the trigger & error messages\n", fail_enabled ? "on" : "off");
+	printk ("     llscselt    \t%s\tSelective triger on failures\n", selective_trigger ? "on" : "off");
+	printk ("     llscblkadr  \t%s\tDump data block addresses\n", dump_block_addrs_opt ? "on" : "off");
+	printk ("     llscl4      \t%s\tRun only tests that evict from L4\n", l4_opt ? "on" : "off");
+	printk ("  SEMFIX: %s\n", IA64_SEMFIX);
+	printk ("\n");
+}
+__setup("autotest", autotest_enable);
+__setup("llsctest=", set_llsctest);
+__setup("llscerrstop", set_llscerrstop);
+__setup("llscfail", set_llscfail);
+__setup("llscselt", set_llscselt);
+__setup("llscblkadr", set_llscblkadr);
+__setup("llscl4", set_llscl4);
+
+
+
+static inline int
+set_lock(uint *lock, uint id)
+{
+	uint	old;
+	old = cmpxchg_acq(lock, NOLOCK, id);
+	return (old == NOLOCK);
+}
+
+static inline int
+clr_lock(uint *lock, uint id)
+{
+	uint	old;
+	old = cmpxchg_rel(lock, id, NOLOCK);
+	return (old == id);
+}
+
+static inline void
+init_lock(uint *lock)
+{
+	*lock = NOLOCK;
+}
+
+/*------------------------------------------------------------------------+
+| Routine  :  ran_conf_llsc - ll/sc shared data test                      |
+| Description: This test checks the coherency of shared data              |
++------------------------------------------------------------------------*/
+static unsigned int
+ran_conf_llsc(int thread)
+{
+	private_t	pval;
+	share_t		sval, sval2;
+	uint		vv, linei, slinei, sharei, pass;
+	long		t;
+	lock_t		lockpat;
+	share_t		*sharecopy;
+	long		verbose, napticks, passes, linecount, lcount;
+	dataline_t	*linep, *slinep;
+	int		s, seed;
+	threadprivate_t	*tp;
+	uint		iter_msg, iter_msg_i=0;
+	int		vv_mask;
+	int		correct_errors;
+	int		errs=0;
+	int		stillbad;
+	capture_t	capdata;
+	private_t	*privp;
+	share_t		*sharep;
+
+
+	linecount = k_linecount;
+	napticks = k_napticks;
+	verbose = k_verbose;
+	passes = k_passes;
+	iter_msg = k_iter_msg;
+	seed = (thread + 1) * 647;
+	tp = THREADPRIVATE(thread);
+	vv_mask = (k_vv>>((thread%16)*4)) & 0xf;
+	correct_errors = k_options&0xff;
+
+	memset (&capdata, 0, sizeof(capdata));
+	for (linei=0; linei<linecount; linei++)
+		tp->private[linei] = thread;	
+
+	for (pass = 1; passes == 0 || pass < passes; pass++) {
+		lockpat = (pass & 0x0fffffff) + (thread <<28);
+		if (lockpat == NOLOCK)
+			continue;
+		tp->threadpasses = pass;
+		if (checkstop(thread, pass, lockpat))
+			return 0;
+		iter_msg_i++;
+		if (iter_msg && iter_msg_i > iter_msg) {
+			printk("Thread %d, Pass %d\n", thread, pass);
+			iter_msg_i = 0;
+		}
+		lcount = 0;
+
+		/*
+		 * Select line to perform operations on.
+		 */
+		linei = randn(linecount, &seed);
+		sharei = randn(2, &seed);
+		slinei = (linei + (linecount/2))%linecount;		/* I dont like this - fix later */
+
+		linep = (dataline_t *)blocks[linei];
+		slinep = (dataline_t *)blocks[slinei];
+		if (sharei == 0)
+			sharecopy = &slinep->share0;
+		else
+			sharecopy = &slinep->share1;
+
+
+		vv = randn(4, &seed);
+		if ((vv_mask & (1<<vv)) == 0)
+			continue;
+
+		if (napticks) {
+			t = randn(napticks, &seed);
+			udelay(t);
+		}
+		privp = &linep->private[thread];
+		sharep = &linep->share[sharei];
+		
+		switch(vv) {
+		case 0:
+			/* Read and verify private count on line. */
+			pval = *privp;
+			if (verbose)
+				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
+			if (pval != tp->private[linei]) {
+				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
+				stillbad = (*privp != tp->private[linei]);
+				if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
+					return 1;
+				}
+				if (correct_errors) {
+					tp->private[linei] = *privp;
+				}
+				errs++;
+			}
+			break;
+
+		case 1:
+			/* Read, verify, and increment private count on line. */
+			pval = *privp;
+			if (verbose)
+				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
+			if (pval != tp->private[linei]) {
+				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
+				stillbad = (*privp != tp->private[linei]);
+				if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
+					return 1;
+				}
+				errs++;
+			}
+			pval = (pval==255) ? 0 : pval+1;
+			*privp = pval;
+			tp->private[linei] = pval;
+			break;
+
+		case 2:
+			/* Lock line, read and verify shared data. */
+			if (verbose)
+				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
+			lcount = 0;
+			while (LOCK(sharei) != 1) {
+				if (checkstop(thread, pass, lockpat))
+					return 0;
+				if (lcount++>1000000) {
+					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
+					stillbad = (GETLOCK(sharei) != 0);
+					rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
+					return 1;
+				}
+				if ((lcount&0x3fff) == 0)
+					udelay(1000);
+			}
+
+			sval = *sharep;
+			sval2 = *sharecopy;
+			if (pass > 12 && thread == 0 && fail_enabled == 1)
+				sval++;
+			if (sval != sval2) {
+				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
+				stillbad = (*sharep != *sharecopy);
+				if (!stillbad && *sharep != sval && *sharecopy == sval2)
+					stillbad = 2;
+				if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
+					return 1;
+				}
+				if (correct_errors)
+					*sharep = *sharecopy;
+				errs++;
+			}
+
+
+			if ( (s=UNLOCK(sharei)) != 1) {
+				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
+				stillbad = (GETLOCK(sharei) != lockpat);
+				if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad))
+					return 1;
+				if (correct_errors)
+					ZEROLOCK(sharei);	
+				errs++;
+			}
+			break;
+
+		case 3:
+			/* Lock line, read and verify shared data, modify shared data. */
+			if (verbose)
+				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
+			lcount = 0;
+			while (LOCK(sharei) != 1) {
+				if (checkstop(thread, pass, lockpat))
+					return 0;
+				if (lcount++>1000000) {
+					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
+					stillbad = (GETLOCK(sharei) != 0);
+					rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
+					return 1;
+				}
+				if ((lcount&0x3fff) == 0)
+					udelay(1000);
+			}
+			sval = *sharep;
+			sval2 = *sharecopy;
+			if (sval != sval2) {
+				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
+				stillbad = (*sharep != *sharecopy);
+				if (!stillbad && *sharep != sval && *sharecopy == sval2)
+					stillbad = 2;
+				if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
+					return 1;
+				}
+				errs++;
+			}
+
+			*sharep = lockpat;
+			*sharecopy = lockpat;
+
+
+			if ( (s=UNLOCK(sharei)) != 1) {
+				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
+				stillbad = (GETLOCK(sharei) != lockpat);
+				if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad))
+					return 1;
+				if (correct_errors)
+					ZEROLOCK(sharei);	
+				errs++;
+			}
+			break;
+		}
+	}
+
+	return (errs > 0);
+}
+
+static void
+trigger_la(long val)
+{
+	long	*p;
+
+	p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */
+	*p = val;
+}
+
+static long
+getsynerr(void)
+{
+	long	err, *errp;
+
+	errp = (long*)0xc0000e0000000340L;	/* SYN_ERR */
+	err = *errp;
+	if (err)
+		*errp = -1L;
+	return (err & ~0x60);
+}
+
+static int
+rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int badlinei, int exp, int found, int stillbad)
+{
+	int		cpu, i, linei;
+	long 		synerr;
+	int		selt;
+
+
+	selt = selective_trigger && stillbad > 1 && 
+			memcmp(cap->blockdata, cap->blockdata_fc, 128) != 0 &&
+			memcmp(cap->shaddata, cap->shaddata_fc, 128) == 0;
+	if (selt) {
+		trigger_la(pass);
+	} else if (selective_trigger) {
+		k_go = ST_STOP;
+		return k_stop_on_error;;
+	}
+
+	spin(1);
+	i = 100;
+	while (i && set_lock(&errlock, 1) != 1) {
+		spin(1);
+		i--;
+	}
+	printk ("\nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%x\n",
+	    msg, k_testnumber, thread, badlinei, pass, pass, jiffies, exp, found);
+
+	dumpline (lp, "Corrupted data", "D ", cap->blockaddr, cap->blockdata, cap->size);
+#ifdef ZZZ
+	if (memcmp(cap->blockdata, cap->blockdata_fc, 128))
+		dumpline (lp, "Corrupted data", "DF", cap->blockaddr, cap->blockdata_fc, cap->size);
+#endif
+
+	if (cap->shadaddr) {
+		dumpline (slp, "Shadow    data", "S ", cap->shadaddr, cap->shaddata, cap->size);
+#ifdef ZZZ
+		if (memcmp(cap->shaddata, cap->shaddata_fc, 128))
+			dumpline (slp, "Shadow    data", "SF", cap->shadaddr, cap->shaddata_fc, cap->size);
+#endif
+	}
+	
+	printk("Threadpasses: ");
+	for (cpu=0,i=0; cpu<LLSC_MAXCPUS; cpu++)
+		if (k_threadprivate[cpu]->threadpasses) {
+			if (i && (i%8) == 0)
+				printk("\n            : ");
+			printk("  %d:0x%x", cpu, k_threadprivate[cpu]->threadpasses);
+			i++;
+		}
+	printk("\n");
+	
+	for (linei=0; linei<k_linecount; linei++) {
+		int		slinei, g1linei, g2linei, g1err, g2err, sh0err, sh1err;
+		dataline_t	*linep, *slinep;
+
+		slinei = (linei + (k_linecount/2))%k_linecount;
+		linep = (dataline_t *)blocks[linei];
+		slinep = (dataline_t *)blocks[slinei];
+
+		g1linei = GUARDLINE(linep->guard1);
+		g2linei = GUARDLINE(linep->guard2);
+		g1err = (g1linei != linei);
+		g2err = (g2linei != linei);
+		sh0err = (linep->share[0] != slinep->share0);
+		sh1err = (linep->share[1] != slinep->share1);
+
+		if (g1err || g2err || sh0err || sh1err) {
+			printk("Line 0x%lx (%03d), %sG1 0x%lx (%03d), %sG2 0x%lx (%03d), %sSH0 %08x (%08x), %sSH1 %08x (%08x)\n",
+				blocks[linei], linei, 
+				g1err ? "*" : " ", blocks[g1linei], g1linei,
+				g2err ? "*" : " ", blocks[g2linei], g2linei,
+				sh0err ? "*" : " ", linep->share[0], slinep->share0,
+				sh1err ? "*" : " ", linep->share[1], slinep->share1);
+
+
+		}
+	}
+
+	printk("\nData was %sfixed by flushcache\n", (stillbad == 1 ? "**** NOT **** " : " "));
+	synerr = getsynerr();
+	if (synerr)
+		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
+	spin(2);
+	printk("\n\n");
+	clr_lock(&errlock, 1);
+
+	if (errstop_enabled) {
+		local_irq_disable();
+		while(1);
+	}
+	return k_stop_on_error;
+}
+
+
+static void
+dumpline(void *lp, char *str1, char *str2, void *addr, void *data, int size)
+{
+	long *p;
+	int i, off;
+
+	printk("%s at 0x%lx, size %d, block starts at 0x%lx\n", str1, (long)addr, size, (long)lp);
+	p = (long*) data;
+	for (i=0; i<48; i++, p++) {
+		if (i%8 == 0) printk("%2s", i==16 ? str2 : "  ");
+		printk(" %016lx", *p);
+		if ((i&7)==7) printk("\n");
+	}
+	printk("   ");
+	off = (((long)addr) ^ size) & 63L;
+	for (i=0; i<off+size; i++) {
+		printk("%s", (i>=off) ? "--" : "  ");
+		if ((i%8) == 7)
+			printk(" ");
+	}
+
+	off = ((long)addr) & 127;
+	printk(" (line %d)\n", 2+off/64+1);
+}
+
+
+static int
+randn(uint max, uint *seedp)
+{
+	if (max == 1)
+		return(0);
+	else
+		return((int)(zrandom(seedp)>>10) % max);
+}
+
+
+static int
+checkstop(int thread, int pass, uint lockpat)
+{
+	long	synerr;
+
+	if (k_go == ST_RUN)
+		return 0;
+	if (k_go == ST_STOP)
+		return 1;
+
+	if (errstop_enabled) {
+		local_irq_disable();
+		while(1);
+	}
+	synerr = getsynerr();
+	spin(2);
+	if (k_go == ST_STOP)
+		return 1;
+	if (synerr)
+		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
+	return 1;
+}
+
+
+static void
+spin(int j)
+{
+	udelay(j * 500000);
+}
+
+static void
+capturedata(capture_t *cap, uint pass, void *blockaddr, void *shadaddr, int size)
+{
+
+	if (!selective_trigger)
+		trigger_la (pass);
+
+	memcpy (cap->blockdata, CACHEALIGN(blockaddr)-128, 3*128);
+	if (shadaddr) 
+		memcpy (cap->shaddata, CACHEALIGN(shadaddr)-128, 3*128);
+
+	if (k_stop_on_error) {
+		k_go = ST_ERRSTOP;
+	}
+
+ 	cap->size = size;
+	cap->blockaddr = blockaddr;
+	cap->shadaddr = shadaddr;
+
+	asm volatile ("fc %0" :: "r"(blockaddr) : "memory");
+	ia64_sync_i();
+	ia64_srlz_d();
+	memcpy (cap->blockdata_fc, CACHEALIGN(blockaddr)-128, 3*128);
+
+	if (shadaddr) {
+		asm volatile ("fc %0" :: "r"(shadaddr) : "memory");
+		ia64_sync_i();
+		ia64_srlz_d();
+		memcpy (cap->shaddata_fc, CACHEALIGN(shadaddr)-128, 3*128);
+	}
+}
+
+int             zranmult = 0x48c27395;
+
+static uint  
+zrandom (uint *seedp)
+{
+        *seedp = (*seedp * zranmult) & 0x7fffffff;
+        return (*seedp);
+}
+
+
+void
+set_autotest_params(void)
+{
+	static int	testnumber=-1;
+
+	if (llsctest_number >= 0) {
+		testnumber = llsctest_number;
+	} else {
+		testnumber++;
+		if (autotest_table[testnumber].passes == 0) {
+			testnumber = 0;
+			dump_block_addrs_opt = 0;
+		}
+	}
+	if (testnumber == 0 && l4_opt) testnumber = 9;
+
+	k_passes = autotest_table[testnumber].passes;
+	k_linepad = autotest_table[testnumber].linepad;
+	k_linecount = autotest_table[testnumber].linecount;
+	k_testnumber = testnumber;
+
+	if (IS_RUNNING_ON_SIMULATOR()) {
+		printk ("llsc start test %ld\n", k_testnumber);
+		k_passes = 1000;
+	}
+}
+
+
+static void
+set_leds(int errs)
+{
+	unsigned char	leds=0;
+
+	/*
+	 * Leds are:
+	 * 	ppppeee-  
+	 *   where
+	 *      pppp = test number
+	 *       eee = error count but top bit is stick
+	 */
+
+	leds =  ((errs&7)<<1) | ((k_testnumber&15)<<4) | (errs ? 0x08 : 0);
+	set_led_bits(leds, LED_MASK_AUTOTEST);
+}
+
+static void
+setup_block_addresses(void)
+{
+	int			i, stride, memmapi;
+	dataline_t		*dp;
+	long			*ip, *ipe;
+
+
+	stride = k_linepad + sizeof(dataline_t);
+	memmapi = 0;
+	for (i=0; i<memmapx; i++) {
+		memmap[i].nextaddr = memmap[i].vstart;
+		memmap[i].nextinit = memmap[i].vstart;
+		memmap[i].wrapcount = 0;
+	}
+
+	for (i=0; i<k_linecount; i++) {
+		blocks[i] = memmap[memmapi].nextaddr;
+		dp = (dataline_t*)blocks[i];
+		memmap[memmapi].nextaddr += (stride & 0xffff);
+		if (memmap[memmapi].nextaddr + sizeof(dataline_t) >= memmap[memmapi].vend) {
+			memmap[memmapi].wrapcount++;
+			memmap[memmapi].nextaddr = memmap[memmapi].vstart + 
+					memmap[memmapi].wrapcount * sizeof(dataline_t);
+		}
+
+		ip = (long*)((memmap[memmapi].nextinit+7)&~7);
+		ipe = (long*)(memmap[memmapi].nextaddr+2*sizeof(dataline_t)+8);
+		while(ip <= ipe && ip < ((long*)memmap[memmapi].vend-8))
+			*ip++ = (long)ip;
+		memmap[memmapi].nextinit = (long) ipe;
+		dp->guard1 = BGUARD(i);
+		dp->guard2 = EGUARD(i);
+		dp->lock[0] = dp->lock[1] = NOLOCK;
+		dp->share[0] = dp->share0 = 0x1111;
+		dp->share[1] = dp->share1 = 0x2222;
+		memcpy(dp->private, init_private, LLSC_MAXCPUS*sizeof(private_t));
+
+
+		if (stride > 16384) {
+			memmapi++;
+			if (memmapi == memmapx)
+				memmapi = 0;
+		}
+	}
+
+}
+
+static void
+dump_block_addrs(void)
+{
+	int	i;
+
+	printk("LLSC TestNumber %ld\n", k_testnumber);
+
+	for (i=0; i<k_linecount; i++) {
+		printk("  %lx", blocks[i]);
+		if (i%4 == 3)
+			printk("\n");
+	}
+	printk("\n");
+}
+
+
+static void
+set_thread_state(int cpuid, int state)
+{
+	if (k_threadprivate[cpuid]->threadstate == TS_KILLED) {
+		set_led_bits(LED_MASK_AUTOTEST, LED_MASK_AUTOTEST);
+		while(1);
+	}
+	k_threadprivate[cpuid]->threadstate = state;
+}
+
+#define MINBLK	(16*1024*1024)
+static int
+build_mem_map(unsigned long start, unsigned long end, void *arg)
+{
+	long	lstart, lend;
+	long	align = 8*MB;
+
+	printk ("LLSC memmap: start 0x%lx, end 0x%lx, (0x%lx - 0x%lx)\n", 
+		start, end, (long) virt_to_page(start), (long) virt_to_page(end-PAGE_SIZE));
+
+	if (memmapx >= MAPCHUNKS || (end-start) < MINBLK)
+		return 0;
+
+	/*
+	 * Start in the middle of the range & find the first non-free page in both directions
+	 * from the midpoint. This is likely to be the bigest free block.
+	 */
+	lend = lstart = start + (end-start)/2;
+	while (lend < end && !PageReserved(virt_to_page(lend)) && virt_to_page(lend)->count.counter == 0)
+		lend += PAGE_SIZE;
+	lend -= PAGE_SIZE;
+
+	while (lstart >= start && !PageReserved(virt_to_page(lstart)) && virt_to_page(lstart)->count.counter == 0)
+		lstart -= PAGE_SIZE;
+	lstart += PAGE_SIZE;
+
+	lstart = (lstart + align -1) /align * align;
+	end = end / align * align;
+	if (lstart >= end)
+		return 0;
+	printk ("     memmap: start 0x%lx, end 0x%lx\n", lstart, end);
+
+	memmap[memmapx].vstart = lstart;
+	memmap[memmapx].vend = end;
+	memmapx++;
+	return 0;
+}
+
+void int_test(void);
+
+int
+llsc_main (int cpuid)
+{
+	int		i, cpu, is_master, repeatcnt=0;
+	unsigned int	preverr=0, errs=0, pass=0;
+	int		automode=0;
+
+#ifdef INTTEST
+	if (inttest)
+		int_test();
+#endif
+
+	if (!autotest_enabled)
+		return 0;
+
+#ifdef CONFIG_SMP
+	is_master = !smp_processor_id();
+#else
+	is_master = 1;
+#endif
+
+
+	if (is_master) {
+		mbase = (control_t*) __get_free_pages(GFP_KERNEL, get_order(4096+THREADPRIVATESZ()*LLSC_MAXCPUS));
+		printk("LLSC: mbase 0x%lx\n", (long)mbase);
+		print_params();
+		if(!IS_RUNNING_ON_SIMULATOR())
+			spin(10);
+		k_currentpass = 0;
+		k_go = ST_IDLE;
+		k_passes = DEF_PASSES;
+		k_napticks = DEF_NAPTICKS;
+		k_stop_on_error = DEF_STOP_ON_ERROR;
+		k_verbose = DEF_VERBOSE;
+		k_linecount = DEF_LINECOUNT;
+		k_iter_msg = DEF_ITER_MSG;
+		k_vv = DEF_VV;
+		k_linepad = DEF_LINEPAD;
+		k_blocks = (void*)blocks;
+		efi_memmap_walk(build_mem_map, 0);
+	
+#ifdef CONFIG_IA64_SGI_AUTOTEST
+		automode = 1;
+#endif
+
+		for (i=0; i<LLSC_MAXCPUS; i++) {
+			k_threadprivate[i] = THREADPRIVATE(i);
+			memset(k_threadprivate[i], 0, sizeof(*k_threadprivate[i]));
+			init_private[i] = i;
+		}
+		mb();
+		initialized = 1;
+	} else {
+		while (initialized == 0)
+			udelay(100);
+	}
+
+loop:
+	if (is_master) {
+		if (automode) {
+			if (!preverr || repeatcnt++ > 5) {
+				set_autotest_params();
+				repeatcnt = 0;
+			}
+		} else {
+			while (k_go == ST_IDLE);
+		}
+
+		k_go = ST_INIT;
+		if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT;
+		k_linecount = k_linecount & ~1;
+		setup_block_addresses();
+		if (!preverr && dump_block_addrs_opt)
+			dump_block_addrs();
+
+		k_currentpass = pass++;
+		k_go = ST_RUN;
+		if (fail_enabled)
+			fail_enabled--;
+
+	} else {
+		while (k_go != ST_RUN || k_currentpass != pass);
+		pass++;
+	}
+
+
+	set_leds(errs);
+	set_thread_state(cpuid, TS_RUNNING);
+
+	errs += ran_conf_llsc(cpuid);
+	preverr = (k_go == ST_ERRSTOP);
+
+	set_leds(errs);
+	set_thread_state(cpuid, TS_STOPPED);
+
+	if (is_master) {
+		Speedo();
+		for (i=0, cpu=0; cpu<LLSC_MAXCPUS; cpu++) {
+			while (k_threadprivate[cpu]->threadstate == TS_RUNNING) {
+				i++;
+				if (i == 10000) { 
+					k_go = ST_STOP;
+					printk ("  llsc master stopping test number %ld\n", k_testnumber);
+				}
+				if (i > 100000) {
+					k_threadprivate[cpu]->threadstate = TS_KILLED;
+					printk ("  llsc: master killing cpuid %d, running test number %ld\n", 
+							cpu, k_testnumber);
+				}
+				udelay(1000);
+			}
+		}
+	}
+
+	goto loop;
+}
+
+
+static void
+Speedo(void)
+{
+	static int i = 0;
+
+	switch (++i%4) {
+	case 0:
+		printk("|\b");
+		break;
+	case 1:
+		printk("\\\b");
+		break;
+	case 2:
+		printk("-\b");
+		break;
+	case 3:
+		printk("/\b");
+		break;
+	}
+}
+
+#ifdef INTTEST
+
+/* ======================================================================================================== 
+ *
+ * Some test code to verify that interrupts work
+ *
+ * Add the following to the arch/ia64/kernel/smp.c after the comment "Reschedule callback"
+ * 		if (zzzprint_resched) printk("  cpu %d got interrupt\n", smp_processor_id());
+ *
+ * Enable the code in arch/ia64/sn/sn1/smp.c to print sending IPIs.
+ *
+ */
+
+static int __init set_inttest(char *str)
+{
+        inttest = 1;
+	autotest_enabled = 1;
+
+	return 1;
+}	
+
+__setup("inttest=", set_inttest);
+
+int	zzzprint_resched=0;
+
+void
+int_test() {
+	int			mycpu, cpu;
+	static volatile int	control_cpu=0;
+
+	mycpu = smp_processor_id();
+	zzzprint_resched = 2;
+
+	printk("Testing cross interrupts\n");
+	
+	while (control_cpu != smp_num_cpus) {
+		if (mycpu == cpu_logical_map(control_cpu)) {
+			for (cpu=0; cpu<smp_num_cpus; cpu++) {
+				printk("Sending interrupt from %d to %d\n", mycpu, cpu_logical_map(cpu));
+				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
+				smp_send_reschedule(cpu_logical_map(cpu));
+				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
+				smp_send_reschedule(cpu_logical_map(cpu));
+				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
+			}
+			control_cpu++;
+		}
+	}
+
+	zzzprint_resched = 1;
+
+	if (mycpu == cpu_logical_map(smp_num_cpus-1)) {
+		printk("\nTight loop of cpu %d sending ints to cpu 0 (every 100 us)\n", mycpu);
+		udelay(IS_RUNNING_ON_SIMULATOR ? 1000 : 1000000);
+		__cli();
+		while (1) {
+			smp_send_reschedule(0);
+			udelay(100);
+		}
+
+	}
+
+	while(1);
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/llsc4.h linux/arch/ia64/sn/kernel/llsc4.h
--- linux.orig/arch/ia64/sn/kernel/llsc4.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/llsc4.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,107 @@
+/* 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifdef STANDALONE
+#include "lock.h"
+#endif
+
+
+#define DEF_NAPTICKS		0
+#define DEF_PASSES		0
+#define DEF_AUTO_PASSES		1000000
+#define DEF_STOP_ON_ERROR	1
+#define DEF_VERBOSE		0
+#define DEF_LINECOUNT		2
+#define DEF_ITER_MSG		0
+#define DEF_VV			0xffffffff
+#define DEF_LINEPAD		0x234
+
+
+
+#define LLSC_MAXCPUS		64
+#define CACHELINE		64
+#define MAX_LINECOUNT		1024
+#define K			1024
+#define	MB			(K*K)
+
+
+#define	uint 		unsigned int
+#define	ushort		unsigned short
+#define	uchar		unsigned char
+#define vint		volatile int
+#define vlong		volatile long
+
+#define LOCKADDR(i)	&linep->lock[(i)]
+#define LOCK(i)		set_lock(LOCKADDR(i), lockpat)
+#define UNLOCK(i)	clr_lock(LOCKADDR(i), lockpat)
+#define GETLOCK(i)	*LOCKADDR(i)
+#define ZEROLOCK(i)	init_lock(LOCKADDR(i))
+
+#define CACHEALIGN(a)	((char*)((long)(a) & ~127L))
+
+typedef uint		guard_t;
+typedef uint		lock_t;
+typedef uint		share_t;
+typedef uchar		private_t;
+
+typedef struct {
+	guard_t		guard1;
+	lock_t		lock[2];
+	share_t		share[2];
+	private_t	private[LLSC_MAXCPUS];
+	share_t		share0;
+	share_t		share1;
+	guard_t		guard2;
+} dataline_t ;
+
+
+#define LINEPAD			k_linepad
+#define LINESTRIDE		(((sizeof(dataline_t)+CACHELINE-1)/CACHELINE)*CACHELINE + LINEPAD)
+
+
+typedef struct {
+	vint		threadstate;
+	uint		threadpasses;
+	private_t	private[MAX_LINECOUNT];
+} threadprivate_t;
+
+typedef struct {
+	vlong		sk_go;		/* 0=idle, 1=init, 2=run */
+	long		sk_linecount;
+	long		sk_passes;
+	long		sk_napticks;
+	long		sk_stop_on_error;
+	long		sk_verbose;
+	long		sk_iter_msg;
+	long		sk_vv;
+	long		sk_linepad;
+	long		sk_options;
+	long		sk_testnumber;
+	vlong		sk_currentpass;
+	void 		*sk_blocks;
+	threadprivate_t	*sk_threadprivate[LLSC_MAXCPUS];
+} control_t;
+
+/* Run state (k_go) constants */
+#define ST_IDLE		0
+#define ST_INIT		1
+#define ST_RUN		2
+#define ST_STOP		3
+#define ST_ERRSTOP	4
+
+
+/* Threadstate constants */
+#define TS_STOPPED	0
+#define	TS_RUNNING	1
+#define TS_KILLED	2
+
+
+
+int llsc_main (int cpuid);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/machvec.c linux/arch/ia64/sn/kernel/machvec.c
--- linux.orig/arch/ia64/sn/kernel/machvec.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/machvec.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_IA64_SGI_SN1
+#define MACHVEC_PLATFORM_NAME	sn1
+#else CONFIG_IA64_SGI_SN1
+#define MACHVEC_PLATFORM_NAME	sn2
+#else
+#error "unknown platform"
+#endif
+
+#include <asm/machvec_init.h>
+#include <asm/io.h>
+#include <linux/pci.h>
+void*
+sn_mk_io_addr_MACRO
+
+dma_addr_t
+sn_pci_map_single_MACRO
+
+int
+sn_pci_map_sg_MACRO
+
+unsigned long
+sn_virt_to_phys_MACRO
+
+void *
+sn_phys_to_virt_MACRO
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/mca.c linux/arch/ia64/sn/kernel/mca.c
--- linux.orig/arch/ia64/sn/kernel/mca.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/mca.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,280 @@
+/*
+ * File:	mca.c
+ * Purpose:	SN specific MCA code.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/smp_lock.h>
+#include <linux/kdb.h>
+
+#include <asm/machvec.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/sal.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/mca.h>
+#include <asm/sn/mca.h>
+
+#include <asm/irq.h>
+#include <asm/hw_irq.h>
+#include <asm/acpi-ext.h>
+#include <asm/smp.h>
+#include <asm/sn/sn_cpuid.h>
+
+static char *shub_mmr_names[] = {
+	"sh_event_occurred",
+	"sh_first_error",
+	"sh_event_overflow",
+
+/* PI */
+	"sh_pi_first_error",
+	"sh_pi_error_summary",
+	"sh_pi_error_overflow",
+
+/* PI HW */
+	"sh_pi_error_detail_1",
+	"sh_pi_error_detail_2",
+	"sh_pi_hw_time_stamp",
+
+/* PI UCE */
+	"sh_pi_uncorrected_detail_1",
+	"sh_pi_uncorrected_detail_2",
+	"sh_pi_uncorrected_detail_3",
+	"sh_pi_uncorrected_detail_4",
+	"sh_pi_uncor_time_stamp",
+
+/* PI CE */
+	"sh_pi_corrected_detail_1",
+	"sh_pi_corrected_detail_2",
+	"sh_pi_corrected_detail_3",
+	"sh_pi_corrected_detail_4",
+	"sh_pi_cor_time_stamp",
+
+/* MD */
+	"sh_mem_error_summary",
+	"sh_mem_error_overflow",
+/* MD HW */
+	"sh_misc_err_hdr_upper",
+	"sh_misc_err_hdr_lower",
+	"sh_md_dqlp_mmr_xperr_val",
+	"sh_md_dqlp_mmr_yperr_val",
+	"sh_md_dqrp_mmr_xperr_val",
+	"sh_md_dqrp_mmr_yperr_val",
+	"sh_md_hw_time_stamp",
+
+/* MD UCE */
+	"sh_dir_uc_err_hdr_lower",
+	"sh_dir_uc_err_hdr_upper",
+	"sh_md_dqlp_mmr_xuerr1",
+	"sh_md_dqlp_mmr_xuerr2",
+	"sh_md_dqlp_mmr_yuerr1",
+	"sh_md_dqlp_mmr_yuerr2",
+	"sh_md_dqrp_mmr_xuerr1",
+	"sh_md_dqrp_mmr_xuerr2",
+	"sh_md_dqrp_mmr_yuerr1",
+	"sh_md_dqrp_mmr_yuerr2",
+	"sh_md_uncor_time_stamp",
+
+/* MD CE */
+	"sh_dir_cor_err_hdr_lower",
+	"sh_dir_cor_err_hdr_upper",
+	"sh_md_dqlp_mmr_xcerr1",
+	"sh_md_dqlp_mmr_xcerr2",
+	"sh_md_dqlp_mmr_ycerr1",
+	"sh_md_dqlp_mmr_ycerr2",
+	"sh_md_dqrp_mmr_xcerr1",
+	"sh_md_dqrp_mmr_xcerr2",
+	"sh_md_dqrp_mmr_ycerr1",
+	"sh_md_dqrp_mmr_ycerr2",
+	"sh_md_cor_time_stamp",
+
+/* MD CE, UCE */
+	"sh_md_dqls_mmr_xamopw_err",
+	"sh_md_dqrs_mmr_yamopw_err",
+
+/* XN */
+	"sh_xn_error_summary",
+	"sh_xn_first_error",
+	"sh_xn_error_overflow",
+
+/* XN HW */
+	"sh_xniilb_error_summary",
+	"sh_xniilb_first_error",
+	"sh_xniilb_error_overflow",
+	"sh_xniilb_error_detail_1",
+	"sh_xniilb_error_detail_2",
+	"sh_xniilb_error_detail_3",
+
+	"sh_ni0_error_summary_1",
+	"sh_ni0_first_error_1",
+	"sh_ni0_error_overflow_1",
+
+	"sh_ni0_error_summary_2",
+	"sh_ni0_first_error_2",
+	"sh_ni0_error_overflow_2",
+	"sh_ni0_error_detail_1",
+	"sh_ni0_error_detail_2",
+	"sh_ni0_error_detail_3",
+
+	"sh_ni1_error_summary_1",
+	"sh_ni1_first_error_1",
+	"sh_ni1_error_overflow_1",
+
+	"sh_ni1_error_summary_2",
+	"sh_ni1_first_error_2",
+	"sh_ni1_error_overflow_2",
+
+	"sh_ni1_error_detail_1",
+	"sh_ni1_error_detail_2",
+	"sh_ni1_error_detail_3",
+
+	"sh_xn_hw_time_stamp",
+
+/* XN HW & UCE & SBE */
+	"sh_xnpi_error_summary",
+	"sh_xnpi_first_error",
+	"sh_xnpi_error_overflow",
+	"sh_xnpi_error_detail_1",
+
+	"sh_xnmd_error_summary",
+	"sh_xnmd_first_error",
+	"sh_xnmd_error_overflow",
+	"sh_xnmd_ecc_err_report",
+	"sh_xnmd_error_detail_1",
+
+/* XN UCE */
+	"sh_xn_uncorrected_detail_1",
+	"sh_xn_uncorrected_detail_2",
+	"sh_xn_uncorrected_detail_3",
+	"sh_xn_uncorrected_detail_4",
+	"sh_xn_uncor_time_stamp",
+
+/* XN CE */
+	"sh_xn_corrected_detail_1",
+	"sh_xn_corrected_detail_2",
+	"sh_xn_corrected_detail_3",
+	"sh_xn_corrected_detail_4",
+	"sh_xn_cor_time_stamp",
+
+/* LB HW */
+	"sh_lb_error_summary",
+	"sh_lb_first_error",
+	"sh_lb_error_overflow",
+	"sh_lb_error_detail_1",
+	"sh_lb_error_detail_2",
+	"sh_lb_error_detail_3",
+	"sh_lb_error_detail_4",
+	"sh_lb_error_detail_5",
+	"sh_junk_error_status",
+};
+
+void 
+sal_log_plat_print(int header_len, int sect_len, u8 *p_data, prfunc_t prfunc) 
+{
+	sal_log_plat_info_t *sh_info = (sal_log_plat_info_t *) p_data;
+	u64 *mmr_val = (u64 *)&(sh_info->shub_state);
+	char **mmr_name = shub_mmr_names;
+	int mmr_count = sizeof(sal_log_shub_state_t)>>3;
+
+	while(mmr_count) {
+		if(*mmr_val) {
+			prfunc("%-40s: %#016lx\n",*mmr_name, *mmr_val);
+		}
+		mmr_name++;
+		mmr_val++;
+		mmr_count--;
+	}
+
+}
+
+sn_cpei_handler(int irq, void *devid, struct pt_regs *regs)
+{
+	struct ia64_sal_retval isrv;
+
+	/*
+	 * this function's sole purpose is to call SAL when we receive
+	 * a CE interrupt from SHUB or when the timer routine decides
+	 * we need to call SAL to check for CEs.
+	 */
+
+	/* CALL SAL_LOG_CE */
+	SAL_CALL(isrv, SN_SAL_LOG_CE, irq, 0, 0, 0, 0, 0, 0);
+}
+
+#include <linux/timer.h>
+
+#define CPEI_INTERVAL   (HZ/100)
+struct timer_list sn_cpei_timer;
+void sn_init_cpei_timer(void);
+
+void
+sn_cpei_timer_handler(unsigned long dummy) {
+        sn_cpei_handler(-1, NULL, NULL);
+        del_timer(&sn_cpei_timer);
+        sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
+        add_timer(&sn_cpei_timer);
+}
+
+void
+sn_init_cpei_timer() {
+        sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
+        sn_cpei_timer.function = sn_cpei_timer_handler;
+        add_timer(&sn_cpei_timer);
+}
+
+#ifdef ajmtestceintr
+
+struct timer_list sn_ce_timer;
+
+void
+sn_ce_timer_handler(long dummy) {
+        unsigned long *pi_ce_error_inject_reg = 0xc00000092fffff00;
+
+        *pi_ce_error_inject_reg = 0x0000000000000100;
+        del_timer(&sn_ce_timer);
+        sn_ce_timer.expires = jiffies + CPEI_INTERVAL;
+        add_timer(&sn_ce_timer);
+}
+
+sn_init_ce_timer() {
+        sn_ce_timer.expires = jiffies + CPEI_INTERVAL;
+        sn_ce_timer.function = sn_ce_timer_handler;
+        add_timer(&sn_ce_timer);
+}
+#endif /* ajmtestceintr */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/misctest.c linux/arch/ia64/sn/kernel/misctest.c
--- linux.orig/arch/ia64/sn/kernel/misctest.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/misctest.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,122 @@
+/* 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+
+
+extern	int autotest_enabled;
+int	mcatest=0;
+
+
+
+/* 
+ * mcatest
+ *	1 = expected MCA
+ *	2 = unexpected MCA
+ *	3 = expected MCA + unexpected MCA
+ *	4 = INIT
+ *	5 = speculative load to garbage memory address
+ *	6 = speculative load with ld8.s (needs poison hack in PROM)
+ *	7 = speculative load from mis-predicted branch (needs poison hack in PROM)
+ */
+static int __init set_mcatest(char *str)
+{
+	get_option(&str, &mcatest);
+	return 1;
+}
+
+__setup("mcatest=", set_mcatest);
+
+void
+sgi_mcatest(void)
+{
+	if (mcatest == 1 || mcatest == 3) {
+		long	*p, result, adrs[] = {0xc0000a000f021004UL, 0xc0000a000f026004UL, 0x800000000, 0x500000, 0};
+		long	size[] = {1,2,4,8};
+		int	r, i, j;
+		p = (long*)0xc000000000000000UL;
+		ia64_fc(p);
+		*p = 0x0123456789abcdefL;
+		for (i=0; i<5; i++) {
+			for (j=0; j<4; j++) {
+				printk("Probing 0x%lx, size %ld\n", adrs[i], size[j]);
+				result = -1;
+				r = ia64_sn_probe_io_slot (adrs[i], size[j], &result);
+				printk("    status %d, val 0x%lx\n", r, result); 
+			}
+		}
+	}
+	if (mcatest == 2 || mcatest == 3) {
+		void zzzmca(int, int, int);
+		printk("About to cause unexpected MCA\n");
+		zzzmca(mcatest, 0x32dead, 0x33dead);
+	}
+	if (mcatest == 4) {
+		long	*p;
+		int	delivery_mode = 5;
+		printk("About to try to cause an INIT on cpu 0\n");
+		p = (long*)((0xc0000a0000000000LL | ((long)get_nasid())<<33) | 0x1800080);
+		*p = (delivery_mode << 8);
+		udelay(10000);
+		printk("Returned from INIT\n");
+	}
+	if (mcatest == 5) {
+		int zzzspec(long);
+		int	i;
+		long	flags, dcr, res, val, addr=0xff00000000UL;
+
+		dcr = ia64_get_dcr();
+		for (i=0; i<5; i++) {
+			printk("Default DCR: 0x%lx\n", ia64_get_dcr());
+			printk("zzzspec: 0x%x\n", zzzspec(addr));
+			ia64_set_dcr(0);
+			printk("New     DCR: 0x%lx\n", ia64_get_dcr());
+			printk("zzzspec: 0x%x\n", zzzspec(addr));
+			ia64_set_dcr(dcr);
+			res = ia64_sn_probe_io_slot(0xff00000000UL, 8, &val);
+			printk("zzzspec: probe %ld, 0x%lx\n", res, val);
+			ia64_clear_ic(flags);
+			ia64_itc(0x2, 0xe00000ff00000000UL,
+			          pte_val(mk_pte_phys(0xff00000000UL,
+				  __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RW))), _PAGE_SIZE_256M);
+			local_irq_restore(flags);
+			ia64_srlz_i ();
+		}
+
+	}
+	if (mcatest == 6) {
+		int zzzspec(long);
+		int	i;
+		long	dcr, addr=0xe000000008000000UL;
+
+		dcr = ia64_get_dcr();
+		for (i=0; i<5; i++) {
+			printk("zzzspec: 0x%x\n", zzzspec(addr));
+			ia64_set_dcr(0);
+		}
+		ia64_set_dcr(dcr);
+	}
+	if (mcatest == 7) {
+		int zzzspec2(long, long);
+		int	i;
+		long	addr=0xe000000008000000UL;
+		long	addr2=0xe000000007000000UL;
+
+		for (i=0; i<5; i++) {
+			printk("zzzspec2\n");
+			zzzspec2(addr, addr2);
+		}
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/probe.c linux/arch/ia64/sn/kernel/probe.c
--- linux.orig/arch/ia64/sn/kernel/probe.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/probe.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,81 @@
+/*
+ * Platform dependent support for IO probing.
+ *
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <asm/sn/sn_sal.h>
+
+/**
+ * ia64_sn_probe_io_slot - test a memory location for readability
+ * @paddr: physical address to probe
+ * @size: number bytes to read (1,2,4,8)
+ * @data_ptr: address to store value read by probe (-1 returned if probe fails)
+ *
+ * This function will probe a physical address to determine if
+ * the address can be read. If reading the address causes a BUS
+ * error, an error is returned. If the probe succeeds, the contents 
+ * of the memory location is returned.
+ *
+ * Return values:
+ *  0 - probe successful
+ *  1 - probe failed (generated MCA)
+ *  2 - Bad arg
+ * <0 - PAL error
+ */
+u64
+ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr)
+{
+	struct ia64_sal_retval isrv;
+
+	SAL_CALL(isrv, SN_SAL_PROBE, paddr, size, 0, 0, 0, 0, 0);
+
+	if (data_ptr) {
+		switch (size) {
+			case 1:
+				*((u8*)data_ptr) = (u8)isrv.v0;
+				break;
+			case 2:
+				*((u16*)data_ptr) = (u16)isrv.v0;
+				break;
+			case 4:
+				*((u32*)data_ptr) = (u32)isrv.v0;
+				break;
+			case 8:
+				*((u64*)data_ptr) = (u64)isrv.v0;
+				break;
+			default:
+				isrv.status = 2;	
+		}
+	}
+
+	return isrv.status;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/setup.c linux/arch/ia64/sn/kernel/setup.c
--- linux.orig/arch/ia64/sn/kernel/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/setup.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/timex.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/serial.h>
+#include <linux/irq.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/sal.h>
+#include <asm/machvec.h>
+#include <asm/system.h>
+#ifdef CONFIG_IA64_MCA
+#include <asm/acpi-ext.h>
+#endif
+#include <asm/processor.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/pda.h>
+#include <asm/sn/nodepda.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/leds.h>
+#include <asm/sn/bte.h>
+#include <asm/sn/clksupport.h>
+
+#ifdef CONFIG_IA64_SGI_SN2
+#include <asm/sn/sn2/shub.h>
+#endif
+
+extern void bte_init_node (nodepda_t *, cnodeid_t, char **);
+extern void bte_init_cpu (void);
+
+long sn_rtc_cycles_per_second;   
+
+/*
+ * This is the address of the RRegs in the HSpace of the global
+ * master.  It is used by a hack in serial.c (serial_[in|out],
+ * printk.c (early_printk), and kdb_io.c to put console output on that
+ * node's Bedrock UART.  It is initialized here to 0, so that
+ * early_printk won't try to access the UART before
+ * master_node_bedrock_address is properly calculated.
+ */
+u64 master_node_bedrock_address = 0UL;
+
+static void sn_init_pdas(char **);
+
+extern struct irq_desc *_sn_irq_desc[];
+
+#if defined(CONFIG_IA64_SGI_SN1)
+extern synergy_da_t	*Synergy_da_indr[];
+#endif
+
+static nodepda_t	*nodepdaindr[MAX_COMPACT_NODES];
+
+#ifdef CONFIG_IA64_SGI_SN2
+irqpda_t		*irqpdaindr[NR_CPUS];
+#endif /* CONFIG_IA64_SGI_SN2 */
+
+
+/*
+ * The format of "screen_info" is strange, and due to early i386-setup
+ * code. This is just enough to make the console code think we're on a
+ * VGA color display.
+ */
+struct screen_info sn_screen_info = {
+	orig_x:			 0,
+	orig_y:			 0,
+	orig_video_mode:	 3,
+	orig_video_cols:	80,
+	orig_video_ega_bx:	 3,
+	orig_video_lines:	25,
+	orig_video_isVGA:	 1,
+	orig_video_points:	16
+};
+
+/*
+ * This is here so we can use the CMOS detection in ide-probe.c to
+ * determine what drives are present.  In theory, we don't need this
+ * as the auto-detection could be done via ide-probe.c:do_probe() but
+ * in practice that would be much slower, which is painful when
+ * running in the simulator.  Note that passing zeroes in DRIVE_INFO
+ * is sufficient (the IDE driver will autodetect the drive geometry).
+ */
+char drive_info[4*16];
+
+/**
+ * sn_map_nr - return the mem_map entry for a given kernel address
+ * @addr: kernel address to query
+ *
+ * Finds the mem_map entry for the kernel address given.  Used by
+ * virt_to_page() (asm-ia64/page.h), among other things.
+ */
+unsigned long
+sn_map_nr (unsigned long addr)
+{
+	return MAP_NR_DISCONTIG(addr);
+}
+
+/**
+ * early_sn_setup - early setup routine for SN platforms
+ *
+ * Sets up an intial console to aid debugging.  Intended primarily
+ * for bringup, it's only called if %BRINGUP and %CONFIG_IA64_EARLY_PRINTK
+ * are turned on.  See start_kernel() in init/main.c.
+ */
+#if defined(CONFIG_IA64_EARLY_PRINTK) && defined(CONFIG_IA64_SGI_SN)
+void __init
+early_sn_setup(void)
+{
+	if ( IS_RUNNING_ON_SIMULATOR() ) {
+#if defined(CONFIG_IA64_SGI_SN1)
+		master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
+#else
+		master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
+#endif
+		printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
+	}
+}
+#endif /* CONFIG_IA64_EARLY_PRINTK && CONFIG_IA64_SGI_SN */
+
+#ifdef NOT_YET_CONFIG_IA64_MCA
+extern void ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs);
+static struct irqaction mca_cpe_irqaction = { 
+	handler:    ia64_mca_cpe_int_handler,
+	flags:      SA_INTERRUPT,
+	name:       "cpe_hndlr"
+};
+#endif
+#ifdef CONFIG_IA64_MCA
+extern int platform_irq_list[];
+#endif
+
+extern nasid_t master_nasid;
+
+/**
+ * sn_setup - SN platform setup routine
+ * @cmdline_p: kernel command line
+ *
+ * Handles platform setup for SN machines.  This includes determining
+ * the RTC frequency (via a SAL call), initializing secondary CPUs, and
+ * setting up per-node data areas.  The console is also initialized here.
+ */
+void __init
+sn_setup(char **cmdline_p)
+{
+	long status, ticks_per_sec, drift;
+	int i;
+
+	master_nasid = get_nasid();
+	(void)get_console_nasid();
+
+	status = ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, &drift);
+	if (status != 0 || ticks_per_sec < 100000)
+		printk(KERN_WARNING "unable to determine platform RTC clock frequency\n");
+	else
+		sn_rtc_cycles_per_second = ticks_per_sec;
+		
+	for (i=0;i<NR_CPUS;i++)
+		_sn_irq_desc[i] = _irq_desc;
+
+#ifdef CONFIG_IA64_MCA
+	platform_irq_list[ACPI20_ENTRY_PIS_CPEI] = IA64_PCE_VECTOR;
+#endif
+
+
+	if ( IS_RUNNING_ON_SIMULATOR() )
+	{
+#ifdef CONFIG_IA64_SGI_SN2
+		master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
+#else
+		master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
+#endif
+		printk(KERN_DEBUG "sn_setup: setting master_node_bedrock_address to 0x%lx\n",
+		       master_node_bedrock_address);
+	}
+
+	/*
+	 * we set the default root device to /dev/hda
+	 * to make simulation easy
+	 */
+	ROOT_DEV = to_kdev_t(0x0301);
+
+	/*
+	 * Create the PDAs and NODEPDAs for all the cpus.
+	 */
+	sn_init_pdas(cmdline_p);
+
+
+	/* 
+	 * For the bootcpu, we do this here. All other cpus will make the
+	 * call as part of cpu_init in slave cpu initialization.
+	 */
+	sn_cpu_init();
+
+
+#ifdef CONFIG_SMP
+	init_smp_config();
+#endif
+	screen_info = sn_screen_info;
+
+	/*
+	 * Turn off "floating-point assist fault" warnings by default.
+	 */
+	current->thread.flags |= IA64_THREAD_FPEMU_NOPRINT;
+}
+
+/**
+ * sn_init_pdas - setup node data areas
+ *
+ * One time setup for Node Data Area.  Called by sn_setup().
+ */
+void
+sn_init_pdas(char **cmdline_p)
+{
+	cnodeid_t	cnode;
+
+	/*
+	 * Make sure that the PDA fits entirely in the same page as the 
+	 * cpu_data area.
+	 */
+	if ((PDAADDR&~PAGE_MASK)+sizeof(pda_t) > PAGE_SIZE)
+		panic("overflow of cpu_data page");
+
+        /*
+         * Allocate & initalize the nodepda for each node.
+         */
+        for (cnode=0; cnode < numnodes; cnode++) {
+		nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
+		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
+
+#if defined(CONFIG_IA64_SGI_SN1)
+		Synergy_da_indr[cnode * 2] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
+		Synergy_da_indr[cnode * 2 + 1] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
+		memset(Synergy_da_indr[cnode * 2], 0, sizeof(synergy_da_t));
+		memset(Synergy_da_indr[cnode * 2 + 1], 0, sizeof(synergy_da_t));
+#endif
+        }
+
+	/*
+	 * Now copy the array of nodepda pointers to each nodepda.
+	 */
+        for (cnode=0; cnode < numnodes; cnode++)
+		memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr, sizeof(nodepdaindr));
+
+
+	/*
+	 * Set up IO related platform-dependent nodepda fields.
+	 * The following routine actually sets up the hubinfo struct
+	 * in nodepda.
+	 */
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		init_platform_nodepda(nodepdaindr[cnode], cnode);
+		bte_init_node (nodepdaindr[cnode], cnode, cmdline_p);
+	}
+}
+
+/**
+ * sn_cpu_init - initialize per-cpu data areas
+ * @cpuid: cpuid of the caller
+ *
+ * Called during cpu initialization on each cpu as it starts.
+ * Currently, initializes the per-cpu data area for SNIA.
+ * Also sets up a few fields in the nodepda.  Also known as
+ * platform_cpu_init() by the ia64 machvec code.
+ */
+void __init
+sn_cpu_init(void)
+{
+	int	cpuid;
+	int	cpuphyid;
+	int	nasid;
+	int	slice;
+	int	cnode;
+
+	/*
+	 * The boot cpu makes this call again after platform initialization is
+	 * complete.
+	 */
+	if (nodepdaindr[0] == NULL)
+		return;
+
+	cpuid = smp_processor_id();
+	cpuphyid = ((ia64_get_lid() >> 16) & 0xffff);
+	nasid = cpu_physical_id_to_nasid(cpuphyid);
+	cnode = nasid_to_cnodeid(nasid);
+	slice = cpu_physical_id_to_slice(cpuphyid);
+
+	pda.p_nodepda = nodepdaindr[cnode];
+	pda.led_address = (long*) (LED0 + (slice<<LED_CPU_SHIFT));
+	pda.led_state = 0;
+	pda.hb_count = HZ/2;
+	pda.hb_state = 0;
+	pda.idle_flag = 0;
+	
+	if (local_node_data->active_cpu_count == 1)
+		nodepda->node_first_cpu = cpuid;
+
+#ifdef CONFIG_IA64_SGI_SN1
+	{
+		int	synergy;
+		synergy = cpu_physical_id_to_synergy(cpuphyid);
+		pda.p_subnodepda = &nodepdaindr[cnode]->snpda[synergy];
+	}
+#endif
+
+#ifdef CONFIG_IA64_SGI_SN2
+
+	/*
+	 * We must use different memory allocators for first cpu (bootmem 
+	 * allocator) than for the other cpus (regular allocator).
+	 */
+	if (cpuid == 0)
+		irqpdaindr[cpuid] = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t));
+	else
+		irqpdaindr[cpuid] = page_address(alloc_pages_node(local_cnodeid(), GFP_KERNEL, get_order(sizeof(irqpda_t))));
+	memset(irqpdaindr[cpuid], 0, sizeof(irqpda_t));
+	pda.p_irqpda = irqpdaindr[cpuid];
+	pda.pio_write_status_addr = (volatile unsigned long *)LOCAL_MMR_ADDR((slice < 2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ) );
+#endif
+
+#ifdef CONFIG_IA64_SGI_SN1
+	pda.bedrock_rev_id = (volatile unsigned long *) LOCAL_HUB(LB_REV_ID);
+	if (cpuid_to_synergy(cpuid))
+		/* CPU B */
+		pda.pio_write_status_addr = (volatile unsigned long *) GBL_PERF_B_ADDR;
+	else
+		/* CPU A */
+		pda.pio_write_status_addr = (volatile unsigned long *) GBL_PERF_A_ADDR;
+#endif
+
+
+	bte_init_cpu();
+}
+
+
+/**
+ * cnodeid_to_cpuid - convert a cnode to a cpuid of a cpu on the node.
+ * @cnode: node to get a cpuid from
+ *	
+ * Returns -1 if no cpus exist on the node.
+ * NOTE:BRINGUP ZZZ This is NOT a good way to find cpus on the node.
+ * Need a better way!!
+ */
+int
+cnodeid_to_cpuid(int cnode) {
+	int cpu;
+
+	for (cpu = 0; cpu < smp_num_cpus; cpu++)
+		if (cpuid_to_cnodeid(cpu) == cnode)
+			break;
+
+	if (cpu == smp_num_cpus) 
+		cpu = -1;
+
+	return cpu;
+}
+
+#if 0 /* ##jh */
+/**
+ * get_cycles - return a non-decreasing timestamp
+ *
+ * On SN, we use an RTC read for this function
+ */
+cycles_t
+get_cycles (void)
+{
+	return GET_RTC_COUNTER();
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn1/Makefile linux/arch/ia64/sn/kernel/sn1/Makefile
--- linux.orig/arch/ia64/sn/kernel/sn1/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn1/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,51 @@
+#
+# ia64/platform/sn/sn1/Makefile
+#
+# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify it 
+# under the terms of version 2 of the GNU General Public License 
+# as published by the Free Software Foundation.
+# 
+# This program is distributed in the hope that it would be useful, but 
+# WITHOUT ANY WARRANTY; without even the implied warranty of 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+# 
+# Further, this software is distributed without any warranty that it is 
+# free of the rightful claim of any third person regarding infringement 
+# or the like.  Any license provided herein, whether implied or 
+# otherwise, applies only to this software file.  Patent licenses, if 
+# any, provided herein do not apply to combinations of this program with 
+# other software, or any other product whatsoever.
+# 
+# You should have received a copy of the GNU General Public 
+# License along with this program; if not, write the Free Software 
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+# 
+# Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+# Mountain View, CA  94043, or:
+# 
+# http://www.sgi.com 
+# 
+# For further information regarding this notice, see: 
+# 
+# http://oss.sgi.com/projects/GenInfo/NoticeExplan
+#
+
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+.S.s:
+	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
+.S.o:
+	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
+
+all: sn1.a
+
+O_TARGET        = sn1.a
+
+obj-y          = cache.o error.o iomv.o synergy.o sn1_smp.o
+
+clean::
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn1/cache.c linux/arch/ia64/sn/kernel/sn1/cache.c
--- linux.orig/arch/ia64/sn/kernel/sn1/cache.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn1/cache.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,81 @@
+/*
+ * 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <asm/pgalloc.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/sn1/synergy.h>
+#include <asm/delay.h>
+
+#ifndef MB
+#define	MB	(1024*1024)
+#endif
+
+/*
+ * Lock for protecting SYN_TAG_DISABLE_WAY.
+ * Consider making this a per-FSB lock. 
+ */
+static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED;
+
+/**
+ * sn_flush_all_caches - flush a range of addresses from all caches (incl. L4)
+ * @flush_addr: identity mapped region 7 address to start flushing
+ * @bytes: number of bytes to flush
+ *
+ * Flush a range of addresses from all caches including L4.  All addresses 
+ * fully or partially contained within @flush_addr to @flush_addr + @bytes 
+ * are flushed from the all caches.
+ */
+void
+sn_flush_all_caches(long flush_addr, long bytes)
+{
+	ulong 	addr, baddr, eaddr, bitbucket;
+	int	way, alias;
+
+	/*
+	 * Because of the way synergy implements "fc", this flushes the
+	 * data from all caches on all cpus & L4's on OTHER FSBs. It also
+	 * flushes both cpus on the local FSB. It does NOT flush it from 
+	 * the local FSB.
+	 */
+	flush_icache_range(flush_addr, flush_addr+bytes);
+
+	/*
+	 * Memory DIMMs are a minimum of 256MB and start on 256MB
+	 * boundaries. Convert the start address to an address
+	 * that is between +0MB & +128 of the same DIMM. 
+	 * Then add 8MB to skip the uncached MinState areas if the address
+	 * is on the master node.
+	 */
+	if (bytes > SYNERGY_L4_BYTES_PER_WAY)
+		bytes = SYNERGY_L4_BYTES_PER_WAY;
+	baddr = TO_NODE(smp_physical_node_id(), PAGE_OFFSET + (flush_addr & (128*MB-1)) + 8*MB); 
+	eaddr = (baddr+bytes+SYNERGY_BLOCK_SIZE-1) & ~(SYNERGY_BLOCK_SIZE-1);
+	baddr = baddr & ~(SYNERGY_BLOCK_SIZE-1);
+
+	/*
+	 * Now flush the local synergy.
+	 */
+	spin_lock(&flush_lock);
+	for(way=0; way<SYNERGY_L4_WAYS; way++) {
+		WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0xffL ^ (1L<<way));
+		mb();
+		for(alias=0; alias < 9; alias++)
+			for(addr=baddr; addr<eaddr; addr+=SYNERGY_BLOCK_SIZE)
+				bitbucket = *(volatile ulong *)(addr+alias*8*MB);
+		mb();
+	}
+	WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0);
+	spin_unlock(&flush_lock);
+
+}
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn1/error.c linux/arch/ia64/sn/kernel/sn1/error.c
--- linux.orig/arch/ia64/sn/kernel/sn1/error.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn1/error.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,187 @@
+/*
+ * SN1 Platform specific error Support
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/ptrace.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/smp.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/sn1/bedrock.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/addrs.h>
+
+/**
+ * snia_error_intr_handler - handle SN specific error interrupts
+ * @irq: error interrupt received
+ * @devid: device causing the interrupt
+ * @pt_regs: saved register state
+ *
+ * This routine is called when certain interrupts occur on SN systems.
+ * It will either recover from the situations that caused the interrupt
+ * or panic.
+ */
+void
+snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs)
+{
+	unsigned long long intpend_val;
+	unsigned long long bit;
+
+	switch (irq) {
+	case SGI_UART_IRQ:
+		/*
+		 * This isn't really an error interrupt.  We're just
+		 * here because we have to do something with them.
+		 * This is probably wrong, and this code will be
+		 * removed.
+		 */
+		intpend_val = LOCAL_HUB_L(PI_INT_PEND0);
+		if ( (bit = ~(1L<<GFX_INTR_A)) ==
+			(intpend_val & ~(1L<<GFX_INTR_A)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<GFX_INTR_B)) ==
+			(intpend_val & ~(1L<<GFX_INTR_B)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<PG_MIG_INTR)) ==
+			(intpend_val & ~(1L<<PG_MIG_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<UART_INTR)) ==
+			(intpend_val & ~(1L<<UART_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<CC_PEND_A)) ==
+			(intpend_val & ~(1L<<CC_PEND_A)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<CC_PEND_B)) ==
+			(intpend_val & ~(1L<<CC_PEND_B)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		printk("Received SGI_UART_IRQ (65), but no intpend0 bits were set???\n");
+		return;
+	case SGI_HUB_ERROR_IRQ:
+		/*
+		 * These are mostly error interrupts of various
+		 * sorts.  We need to do more than panic here, but
+		 * what the heck, this is bring up.
+		 */
+		intpend_val = LOCAL_HUB_L(PI_INT_PEND1);
+		
+		if ( (bit = ~(1L<<XB_ERROR)) ==
+			(intpend_val & ~(1L<<XB_ERROR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED XB_ERROR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<LB_ERROR)) ==
+			(intpend_val & ~(1L<<LB_ERROR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED LB_ERROR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<NACK_INT_A)) ==
+			(intpend_val & ~(1L<<NACK_INT_A)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED NACK_INT_A on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<NACK_INT_B)) ==
+			(intpend_val & ~(1L<<NACK_INT_B)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED NACK_INT_B on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<CLK_ERR_INTR)) ==
+			(intpend_val & ~(1L<<CLK_ERR_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED CLK_ERR_INTR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<COR_ERR_INTR_A)) ==
+			(intpend_val & ~(1L<<COR_ERR_INTR_A)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED COR_ERR_INTR_A on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<COR_ERR_INTR_B)) ==
+			(intpend_val & ~(1L<<COR_ERR_INTR_B)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED COR_ERR_INTR_B on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<MD_COR_ERR_INTR)) ==
+			(intpend_val & ~(1L<<MD_COR_ERR_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED MD_COR_ERR_INTR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<NI_ERROR_INTR)) ==
+			(intpend_val & ~(1L<<NI_ERROR_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED NI_ERROR_INTR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<MSC_PANIC_INTR)) ==
+			(intpend_val & ~(1L<<MSC_PANIC_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED MSC_PANIC_INTR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		printk("Received SGI_XB_ERROR_IRQ (182) but no intpend1 bits are set???\n");
+		return;
+	default:
+		printk("Received invalid irq in snia_error_intr_handler()\n");
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn1/iomv.c linux/arch/ia64/sn/kernel/sn1/iomv.c
--- linux.orig/arch/ia64/sn/kernel/sn1/iomv.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn1/iomv.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,65 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/sn/simulator.h>
+#include <asm/delay.h>
+#include <asm/sn/pda.h>
+
+/**
+ * sn_io_addr - convert an in/out port to an i/o address
+ * @port: port to convert
+ *
+ * Legacy in/out instructions are converted to ld/st instructions
+ * on IA64.  This routine will convert a port number into a valid 
+ * SN i/o address.  Used by sn_in*() and sn_out*().
+ */
+void *
+sn_io_addr(unsigned long port)
+{
+	if (!IS_RUNNING_ON_SIMULATOR()) {
+		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
+	} else {
+		unsigned long io_base;
+		unsigned long addr;
+ 
+		/*
+ 		 * word align port, but need more than 10 bits
+ 		 * for accessing registers in bedrock local block
+ 		 * (so we don't do port&0xfff)
+ 		 */
+		if ((port >= 0x1f0 && port <= 0x1f7) ||
+			port == 0x3f6 || port == 0x3f7) {
+			io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000;
+			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
+		} else {
+			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
+		}
+		return(void *) addr;
+	}
+}
+
+/**
+ * sn1_mmiob - I/O space memory barrier
+ *
+ * Acts as a memory mapped I/O barrier for platforms that queue writes to 
+ * I/O space.  This ensures that subsequent writes to I/O space arrive after
+ * all previous writes.  For most ia64 platforms, this is a simple
+ * 'mf.a' instruction.  For other platforms, mmiob() may have to read
+ * a chipset register to ensure ordering.
+ *
+ * On SN1, we wait for the PIO_WRITE_STATUS Bedrock register to clear.
+ */
+void
+sn1_mmiob (void)
+{
+	(volatile unsigned long) (*pda.bedrock_rev_id);
+	while (!(volatile unsigned long) (*pda.pio_write_status_addr))
+		udelay(5);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn1/sn1_smp.c linux/arch/ia64/sn/kernel/sn1/sn1_smp.c
--- linux.orig/arch/ia64/sn/kernel/sn1/sn1_smp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn1/sn1_smp.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,474 @@
+/*
+ * SN1 Platform specific SMP Support
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mmzone.h>
+
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/sal.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/hw_irq.h>
+#include <asm/current.h>
+#include <asm/delay.h>
+#include <asm/sn/sn_cpuid.h>
+
+/*
+ * The following structure is used to pass params thru smp_call_function
+ * to other cpus for flushing TLB ranges.
+ */
+typedef struct {
+	unsigned long	start;
+	unsigned long	end;
+	unsigned long	nbits;
+	unsigned int	rid;
+	atomic_t	unfinished_count;
+} ptc_params_t;
+
+#define NUMPTC	512
+
+static ptc_params_t	ptcParamArray[NUMPTC] __attribute__((__aligned__(128)));
+
+/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */
+static ptc_params_t	*ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128)));
+static volatile ptc_params_t	*ptcParamsEmpty __cacheline_aligned;
+
+/*REFERENCED*/
+static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+
+static int ptcInit = 0;
+#ifdef PTCDEBUG
+static int ptcParamsAllBusy = 0;		/* debugging/statistics */
+static int ptcCountBacklog = 0;
+static int ptcBacklog[NUMPTC+1];
+static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
+static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
+#endif
+
+/*
+ * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference,
+ * so that we get a clean compile with the ia64 patch without the
+ * actual SN1 specific code in arch/ia64/kernel/smp.c.
+ */
+extern void smp_send_flush_tlb (void) __attribute((weak));
+
+/*
+ * The following table/struct is for remembering PTC coherency domains. It
+ * is also used to translate sapicid into cpuids. We dont want to start 
+ * cpus unless we know their cache domain.
+ */
+#ifdef PTC_NOTYET
+sn_sapicid_info_t	sn_sapicid_info[NR_CPUS];
+#endif
+
+/**
+ * sn1_ptc_l_range - purge local translation cache
+ * @start: start of virtual address range
+ * @end: end of virtual address range
+ * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
+ *
+ * Purges the range specified from the local processor's translation cache
+ * (as opposed to the translation registers).  Note that more than the specified
+ * range *may* be cleared from the cache by some processors.
+ *
+ * This is probably not good enough, but I don't want to try to make it better 
+ * until I get some statistics on a running system. At a minimum, we should only 
+ * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's 
+ * own FSB. Also, we only have to serialize per FSB, not globally.
+ *
+ * More likely, we will have to do some work to reduce the frequency of calls to
+ * this routine.
+ */
+static inline void
+sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits)
+{
+	do {
+		__asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
+		start += (1UL << nbits);
+	} while (start < end);
+	ia64_srlz_d();
+}
+
+/**
+ * sn1_received_flush_tlb - cpu tlb flush routine
+ *
+ * Flushes the TLB of a given processor.
+ */
+void
+sn1_received_flush_tlb(void)
+{
+	unsigned long	start, end, nbits;
+	unsigned int	rid, saved_rid;
+	int		cpu = smp_processor_id();
+	int		result;
+	ptc_params_t	*ptcParams;
+
+	ptcParams = ptcParamsNextByCpu[cpu*16];
+	if (ptcParams == ptcParamsEmpty)
+		return;
+
+	do {
+		start = ptcParams->start;
+		saved_rid = (unsigned int) ia64_get_rr(start);
+		end = ptcParams->end;
+		nbits = ptcParams->nbits;
+		rid = ptcParams->rid;
+
+		if (saved_rid != rid) {
+			ia64_set_rr(start, (unsigned long)rid);
+			ia64_srlz_d();
+		}
+
+		sn1_ptc_l_range(start, end, nbits);
+
+		if (saved_rid != rid) 
+			ia64_set_rr(start, (unsigned long)saved_rid);
+
+		ia64_srlz_i();
+
+		result = atomic_dec(&ptcParams->unfinished_count);
+#ifdef PTCDEBUG
+		{
+		    int i = ptcParams-&ptcParamArray[0];
+		    ptcParamsResults[cpu][i] = (char) result;
+		    ptcParamsCounts[cpu][i]++;
+		}
+#endif /* PTCDEBUG */
+
+		if (++ptcParams == &ptcParamArray[NUMPTC])
+			ptcParams = &ptcParamArray[0];
+
+	} while (ptcParams != ptcParamsEmpty);
+
+	ptcParamsNextByCpu[cpu*16] = ptcParams;
+}
+
+/**
+ * sn1_global_tlb_purge - flush a translation cache range on all processors
+ * @start: start of virtual address range to flush
+ * @end: end of virtual address range
+ * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
+ *
+ * Flushes the translation cache of all processors from @start to @end.
+ */
+void
+sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
+{
+	ptc_params_t	*params;
+	ptc_params_t	*next;
+	unsigned long	irqflags;
+#ifdef PTCDEBUG
+	ptc_params_t	*nextnext;
+	int		backlog = 0;
+#endif
+
+	if (smp_num_cpus == 1) {
+		sn1_ptc_l_range(start, end, nbits);
+		return;
+	}
+
+	if (in_interrupt()) {
+		/*
+		 *  If at interrupt level and cannot get spinlock, 
+		 *  then do something useful by flushing own tlbflush queue
+		 *  so as to avoid a possible deadlock.
+		 */
+		while (!spin_trylock(&ptcParamsLock)) {
+			local_irq_save(irqflags);
+			sn1_received_flush_tlb();
+			local_irq_restore(irqflags);
+			udelay(10);	/* take it easier on the bus */	
+		}
+	} else {
+		spin_lock(&ptcParamsLock);
+	}
+
+	if (!ptcInit) {
+		int cpu;
+		ptcInit = 1;
+		memset(ptcParamArray, 0, sizeof(ptcParamArray));
+		ptcParamsEmpty = &ptcParamArray[0];
+		for (cpu=0; cpu<NR_CPUS; cpu++)
+			ptcParamsNextByCpu[cpu*16] = &ptcParamArray[0];
+
+#ifdef PTCDEBUG
+		memset(ptcBacklog, 0, sizeof(ptcBacklog));
+		memset(ptcParamsCounts, 0, sizeof(ptcParamsCounts));
+		memset(ptcParamsResults, 0, sizeof(ptcParamsResults));
+#endif	/* PTCDEBUG */
+	}
+
+	params = (ptc_params_t *) ptcParamsEmpty;
+	next = (ptc_params_t *) ptcParamsEmpty + 1;
+	if (next == &ptcParamArray[NUMPTC])
+		next = &ptcParamArray[0];
+
+#ifdef PTCDEBUG
+	nextnext = next + 1;
+	if (nextnext == &ptcParamArray[NUMPTC])
+		nextnext = &ptcParamArray[0];
+
+	if (ptcCountBacklog) {
+		/* quick count of backlog */
+		ptc_params_t *ptr;
+
+		/* check the current pointer to the beginning */
+		ptr = params;
+		while(--ptr >= &ptcParamArray[0]) {
+			if (atomic_read(&ptr->unfinished_count) == 0)
+				break;
+			++backlog;
+		}
+
+		if (backlog) {
+			/* check the end of the array */
+			ptr = &ptcParamArray[NUMPTC];
+			while (--ptr > params) {
+				if (atomic_read(&ptr->unfinished_count) == 0)
+					break;
+				++backlog;
+			}
+		}
+		ptcBacklog[backlog]++;
+	}
+#endif	/* PTCDEBUG */
+
+	/* wait for the next entry to clear...should be rare */
+	if (atomic_read(&next->unfinished_count) > 0) {
+#ifdef PTCDEBUG
+		ptcParamsAllBusy++;
+
+		if (atomic_read(&nextnext->unfinished_count) == 0) {
+		    if (atomic_read(&next->unfinished_count) > 0) {
+			panic("\nnonzero next zero nextnext %lx %lx\n",
+			    (long)next, (long)nextnext);
+		    }
+		}
+#endif
+
+		/* it could be this cpu that is behind */
+		local_irq_save(irqflags);
+		sn1_received_flush_tlb();
+		local_irq_restore(irqflags);
+
+		/* now we know it's not this cpu, so just wait */
+		while (atomic_read(&next->unfinished_count) > 0) {
+			barrier();
+		}
+	}
+
+	params->start = start;
+	params->end = end;
+	params->nbits = nbits;
+	params->rid = (unsigned int) ia64_get_rr(start);
+	atomic_set(&params->unfinished_count, smp_num_cpus);
+
+	/* The atomic_set above can hit memory *after* the update
+	 * to ptcParamsEmpty below, which opens a timing window
+	 * that other cpus can squeeze into!
+	 */
+	mb();
+
+	/* everything is ready to process:
+	 *	-- global lock is held
+	 *	-- new entry + 1 is free
+	 *	-- new entry is set up
+	 * so now:
+	 *	-- update the global next pointer
+	 *	-- unlock the global lock
+	 *	-- send IPI to notify other cpus
+	 *	-- process the data ourselves
+	 */
+	ptcParamsEmpty = next;
+	spin_unlock(&ptcParamsLock);
+	smp_send_flush_tlb();
+
+	local_irq_save(irqflags);
+	sn1_received_flush_tlb();
+	local_irq_restore(irqflags);
+
+	/* Currently we don't think global TLB purges need to be atomic.
+	 * All CPUs get sent IPIs, so if they haven't done the purge,
+	 * they're busy with interrupts that are at the IPI level, which is
+	 * priority 15.  We're asserting that any code at that level
+	 * shouldn't be using user TLB entries.  To change this to wait
+	 * for all the flushes to complete, enable the following code.
+	 */
+#ifdef SN1_SYNCHRONOUS_GLOBAL_TLB_PURGE
+	/* this code is not tested */
+	/* wait for the flush to complete */
+	while (atomic_read(&params.unfinished_count) > 1)
+		barrier();
+
+	atomic_set(&params->unfinished_count, 0);
+#endif
+}
+
+/**
+ * sn_send_IPI_phys - send an IPI to a Nasid and slice
+ * @physid: physical cpuid to receive the interrupt.
+ * @vector: command to send
+ * @delivery_mode: delivery mechanism
+ *
+ * Sends an IPI (interprocessor interrupt) to the processor specified by
+ * @physid
+ *
+ * @delivery_mode can be one of the following
+ *
+ * %IA64_IPI_DM_INT - pend an interrupt
+ * %IA64_IPI_DM_PMI - pend a PMI
+ * %IA64_IPI_DM_NMI - pend an NMI
+ * %IA64_IPI_DM_INIT - pend an INIT interrupt
+ */
+void
+sn_send_IPI_phys(long physid, int vector, int delivery_mode)
+{
+	long		*p;
+	long		nasid, slice;
+
+	static int 	off[4] = {0x1800080, 0x1800088, 0x1a00080, 0x1a00088};
+
+	nasid = cpu_physical_id_to_nasid(physid);
+        slice = cpu_physical_id_to_slice(physid);
+
+	p = (long*)(0xc0000a0000000000LL | (nasid<<33) | off[slice]);
+
+#if defined(ZZZBRINGUP)
+	{
+	static int count=0;
+	if (count++ < 10) printk("ZZ sendIPI 0x%x vec %d, nasid 0x%lx, slice %ld, adr 0x%lx\n",
+		smp_processor_id(), vector, nasid, slice, (long)p);
+	}
+#endif
+	mb();
+	*p = (delivery_mode << 8) | (vector & 0xff);
+}
+
+
+/**
+ * sn1_send_IPI - send an IPI to a processor
+ * @cpuid: target of the IPI
+ * @vector: command to send
+ * @delivery_mode: delivery mechanism
+ * @redirect: redirect the IPI?
+ *
+ * Sends an IPI (interprocessor interrupt) to the processor specified by
+ * @cpuid.  @delivery_mode can be one of the following
+ *
+ * %IA64_IPI_DM_INT - pend an interrupt
+ * %IA64_IPI_DM_PMI - pend a PMI
+ * %IA64_IPI_DM_NMI - pend an NMI
+ * %IA64_IPI_DM_INIT - pend an INIT interrupt
+ */
+void
+sn1_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
+{
+	long		physid;
+
+	physid = cpu_physical_id(cpuid);
+
+	sn_send_IPI_phys(physid, vector, delivery_mode);
+}
+#ifdef CONFIG_SMP
+
+#ifdef PTC_NOTYET
+static void __init
+process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain)
+{
+	ia64_sal_ptc_domain_proc_entry_t	*pe;
+	int 					i, sapicid, cpuid;
+
+	pe = __va(di->proc_list);
+	for (i=0; i<di->proc_count; i++, pe++) {
+		sapicid = id_eid_to_sapicid(pe->id, pe->eid);
+		cpuid = cpu_logical_id(sapicid);
+		sn_sapicid_info[cpuid].domain = domain;
+		sn_sapicid_info[cpuid].sapicid = sapicid;
+	}
+}
+
+
+static void __init
+process_sal_desc_ptc(ia64_sal_desc_ptc_t *ptc)
+{
+	ia64_sal_ptc_domain_info_t	*di;
+	int i;
+
+	di = __va(ptc->domain_info);
+	for (i=0; i<ptc->num_domains; i++, di++) {
+		process_sal_ptc_domain_info(di, i);	
+	}
+}
+#endif /* PTC_NOTYET */
+
+/**
+ * init_sn1_smp_config - setup PTC domains per processor
+ */
+void __init
+init_sn1_smp_config(void)
+{
+	if (!ia64_ptc_domain_info)  {
+		printk("SMP: Can't find PTC domain info. Forcing UP mode\n");
+		smp_num_cpus = 1;
+		return;
+	}
+
+#ifdef PTC_NOTYET
+	memset (sn_sapicid_info, -1, sizeof(sn_sapicid_info));
+	process_sal_desc_ptc(ia64_ptc_domain_info);
+#endif
+}
+
+#else /* CONFIG_SMP */
+
+void __init
+init_sn1_smp_config(void)
+{
+
+#ifdef PTC_NOTYET
+	sn_sapicid_info[0].sapicid = hard_smp_processor_id();
+#endif
+}
+
+#endif /* CONFIG_SMP */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn1/synergy.c linux/arch/ia64/sn/kernel/sn1/synergy.c
--- linux.orig/arch/ia64/sn/kernel/sn1/synergy.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn1/synergy.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,532 @@
+/*
+ * SN1 Platform specific synergy Support
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/proc_fs.h>
+
+#include <asm/ptrace.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/smp.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/sn1/bedrock.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/nodepda.h>
+#include <asm/sn/sn1/synergy.h>
+#include <asm/sn/sndrv.h>
+
+int bit_pos_to_irq(int bit);
+void setclear_mask_b(int irq, int cpuid, int set);
+void setclear_mask_a(int irq, int cpuid, int set);
+void * kmalloc(size_t size, int flags);
+
+static int synergy_perf_initialized = 0;
+
+void
+synergy_intr_alloc(int bit, int cpuid) {
+	return;
+}
+
+int
+synergy_intr_connect(int bit, 
+		int cpuid)
+{
+	int irq;
+	unsigned is_b;
+
+	irq = bit_pos_to_irq(bit);
+
+	is_b = (cpuid_to_slice(cpuid)) & 1;
+	if (is_b) {
+		setclear_mask_b(irq,cpuid,1);
+		setclear_mask_a(irq,cpuid, 0);
+	} else {
+		setclear_mask_a(irq, cpuid, 1);
+		setclear_mask_b(irq, cpuid, 0);
+	}
+	return 0;
+}
+void
+setclear_mask_a(int irq, int cpuid, int set)
+{
+	int synergy;
+	int nasid;
+	int reg_num;
+	unsigned long mask;
+	unsigned long addr;
+	unsigned long reg;
+	unsigned long val;
+	int my_cnode, my_synergy;
+	int target_cnode, target_synergy;
+
+        /*
+         * Perform some idiot checks ..
+         */
+        if ( (irq < 0) || (irq > 255) ||
+                (cpuid < 0) || (cpuid > 512) ) {
+                printk("clear_mask_a: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
+		return;
+	}
+
+	target_cnode = cpuid_to_cnodeid(cpuid);
+	target_synergy = cpuid_to_synergy(cpuid);
+	my_cnode = cpuid_to_cnodeid(smp_processor_id());
+	my_synergy = cpuid_to_synergy(smp_processor_id());
+
+	reg_num = irq / 64;
+	mask = 1;
+	mask <<= (irq % 64);
+	switch (reg_num) {
+		case 0: 
+			reg = VEC_MASK0A;
+			addr = VEC_MASK0A_ADDR;
+			break;
+		case 1: 
+			reg = VEC_MASK1A;
+			addr = VEC_MASK1A_ADDR;
+			break;
+		case 2: 
+			reg = VEC_MASK2A;
+			addr = VEC_MASK2A_ADDR;
+			break;
+		case 3: 
+			reg = VEC_MASK3A;
+			addr = VEC_MASK3A_ADDR;
+			break;
+		default:
+			reg = addr = 0;
+			break;
+	}
+	if (my_cnode == target_cnode && my_synergy == target_synergy) {
+		// local synergy
+		val = READ_LOCAL_SYNERGY_REG(addr);
+		if (set) {
+			val |= mask;
+		} else {
+			val &= ~mask;
+		}
+		WRITE_LOCAL_SYNERGY_REG(addr, val);
+		val = READ_LOCAL_SYNERGY_REG(addr);
+	} else { /* remote synergy */
+		synergy = cpuid_to_synergy(cpuid);
+		nasid = cpuid_to_nasid(cpuid);
+		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
+		if (set) {
+			val |= mask;
+		} else {
+			val &= ~mask;
+		}
+		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
+	}
+}
+
+void
+setclear_mask_b(int irq, int cpuid, int set)
+{
+	int synergy;
+	int nasid;
+	int reg_num;
+	unsigned long mask;
+	unsigned long addr;
+	unsigned long reg;
+	unsigned long val;
+	int my_cnode, my_synergy;
+	int target_cnode, target_synergy;
+
+	/*
+	 * Perform some idiot checks ..
+	 */
+	if ( (irq < 0) || (irq > 255) ||
+		(cpuid < 0) || (cpuid > 512) ) {
+		printk("clear_mask_b: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
+		return;
+	}
+
+	target_cnode = cpuid_to_cnodeid(cpuid);
+	target_synergy = cpuid_to_synergy(cpuid);
+	my_cnode = cpuid_to_cnodeid(smp_processor_id());
+	my_synergy = cpuid_to_synergy(smp_processor_id());
+
+	reg_num = irq / 64;
+	mask = 1;
+	mask <<= (irq % 64);
+	switch (reg_num) {
+		case 0: 
+			reg = VEC_MASK0B;
+			addr = VEC_MASK0B_ADDR;
+			break;
+		case 1: 
+			reg = VEC_MASK1B;
+			addr = VEC_MASK1B_ADDR;
+			break;
+		case 2: 
+			reg = VEC_MASK2B;
+			addr = VEC_MASK2B_ADDR;
+			break;
+		case 3: 
+			reg = VEC_MASK3B;
+			addr = VEC_MASK3B_ADDR;
+			break;
+		default:
+			reg = addr = 0;
+			break;
+	}
+	if (my_cnode == target_cnode && my_synergy == target_synergy) {
+		// local synergy
+		val = READ_LOCAL_SYNERGY_REG(addr);
+		if (set) {
+			val |= mask;
+		} else {
+			val &= ~mask;
+		}
+		WRITE_LOCAL_SYNERGY_REG(addr, val);
+		val = READ_LOCAL_SYNERGY_REG(addr);
+	} else { /* remote synergy */
+		synergy = cpuid_to_synergy(cpuid);
+		nasid = cpuid_to_nasid(cpuid);
+		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
+		if (set) {
+			val |= mask;
+		} else {
+			val &= ~mask;
+		}
+		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
+	}
+}
+
+/*
+ * Synergy perf stats. Multiplexed via timer_interrupt.
+ */
+
+static int
+synergy_perf_append(uint64_t modesel)
+{
+	int		cnode;
+	nodepda_t       *npdap;
+	synergy_perf_t	*p;
+	int		checked = 0;
+	int		err = 0;
+
+	/* bit 45 is enable */
+	modesel |= (1UL << 45);
+
+	for (cnode=0; cnode < numnodes; cnode++) {
+		/* for each node, insert a new synergy_perf entry */
+		if ((npdap = NODEPDA(cnode)) == NULL) {
+			printk("synergy_perf_append: cnode=%d NODEPDA(cnode)==NULL, nodepda=%p\n", cnode, (void *)nodepda);
+			continue;
+		}
+
+		if (npdap->synergy_perf_enabled) {
+			/* user must disable counting to append new events */
+			err = -EBUSY;
+			break;
+		}
+
+		if (!checked && npdap->synergy_perf_data != NULL) {
+			checked = 1;
+			for (p = npdap->synergy_perf_first; ;) {
+				if (p->modesel == modesel)
+					return 0; /* event already registered */
+				if ((p = p->next) == npdap->synergy_perf_first)
+					break;
+			}
+		}
+
+		/* XX use kmem_alloc_node() when it is implemented */
+		p = (synergy_perf_t *)kmalloc(sizeof(synergy_perf_t), GFP_KERNEL);
+		if ((((uint64_t)p) & 7UL) != 0)
+			BUG(); /* bad alignment */
+		if (p == NULL) {
+			err = -ENOMEM;
+			break;
+		}
+		else {
+			memset(p, 0, sizeof(synergy_perf_t));
+			p->modesel = modesel;
+
+			spin_lock_irq(&npdap->synergy_perf_lock);
+			if (npdap->synergy_perf_data == NULL) {
+				/* circular list */
+				p->next = p;
+				npdap->synergy_perf_first = p;
+				npdap->synergy_perf_data = p;
+			}
+			else {
+				p->next = npdap->synergy_perf_data->next;
+				npdap->synergy_perf_data->next = p;
+			}
+			spin_unlock_irq(&npdap->synergy_perf_lock);
+		}
+	}
+
+	return err;
+}
+
+static void
+synergy_perf_set_freq(int freq)
+{
+	int		cnode;
+	nodepda_t	*npdap;
+
+	for (cnode=0; cnode < numnodes; cnode++) {
+		if ((npdap = NODEPDA(cnode)) != NULL)
+			npdap->synergy_perf_freq = freq;
+	}
+}
+
+static void
+synergy_perf_set_enable(int enable)
+{
+	int		cnode;
+	nodepda_t	*npdap;
+
+	for (cnode=0; cnode < numnodes; cnode++) {
+		if ((npdap = NODEPDA(cnode)) != NULL)
+			npdap->synergy_perf_enabled = enable;
+	}
+	printk("NOTICE: synergy perf counting %sabled on all nodes\n", enable ? "en" : "dis");
+}
+
+static int
+synergy_perf_size(nodepda_t *npdap)
+{
+	synergy_perf_t	*p;
+	int		n;
+
+	if (npdap->synergy_perf_enabled == 0) {
+		/* no stats to return */
+		return 0;
+	}
+
+	spin_lock_irq(&npdap->synergy_perf_lock);
+	for (n=0, p = npdap->synergy_perf_first; p;) {
+		n++;
+		p = p->next;
+		if (p == npdap->synergy_perf_first)
+			break;
+	}
+	spin_unlock_irq(&npdap->synergy_perf_lock);
+
+	/* bytes == n pairs of {event,counter} */
+	return n * 2 * sizeof(uint64_t);
+}
+
+static int
+synergy_perf_ioctl(struct inode *inode, struct file *file,
+        unsigned int cmd, unsigned long arg)
+{
+	int             cnode;
+	nodepda_t       *npdap;
+	synergy_perf_t	*p;
+	int		intarg;
+	int		fsb;
+	uint64_t	longarg;
+	uint64_t	*stats;
+	int		n;
+	devfs_handle_t	d;
+	arbitrary_info_t info;
+	
+	if ((d = devfs_get_handle_from_inode(inode)) == NULL)
+		return -ENODEV;
+	info = hwgraph_fastinfo_get(d);
+
+	cnode = SYNERGY_PERF_INFO_CNODE(info);
+	fsb = SYNERGY_PERF_INFO_FSB(info);
+	npdap = NODEPDA(cnode);
+
+	switch (cmd) {
+	case SNDRV_GET_SYNERGY_VERSION:
+		/* return int, version of data structure for SNDRV_GET_SYNERGYINFO */
+		intarg = 1; /* version 1 */
+		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
+		    return -EFAULT;
+		break;
+
+	case SNDRV_GET_INFOSIZE:
+		/* return int, sizeof buf needed for SYNERGY_PERF_GET_STATS */
+		intarg = synergy_perf_size(npdap);
+		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
+		    return -EFAULT;
+		break;
+
+	case SNDRV_GET_SYNERGYINFO:
+		/* return array of event/value pairs, this node only */
+		if ((intarg = synergy_perf_size(npdap)) <= 0)
+			return -ENODATA;
+		if ((stats = (uint64_t *)kmalloc(intarg, GFP_KERNEL)) == NULL)
+			return -ENOMEM;
+		spin_lock_irq(&npdap->synergy_perf_lock);
+		for (n=0, p = npdap->synergy_perf_first; p;) {
+			stats[n++] = p->modesel;
+			if (p->intervals > 0)
+			    stats[n++] = p->counts[fsb] * p->total_intervals / p->intervals;
+			else
+			    stats[n++] = 0;
+			p = p->next;
+			if (p == npdap->synergy_perf_first)
+				break;
+		}
+		spin_unlock_irq(&npdap->synergy_perf_lock);
+
+		if (copy_to_user((void *)arg, stats, intarg)) {
+		    kfree(stats);
+		    return -EFAULT;
+		}
+
+		kfree(stats);
+		break;
+
+	case SNDRV_SYNERGY_APPEND:
+		/* reads 64bit event, append synergy perf event to all nodes  */
+		if (copy_from_user(&longarg, (void *)arg, sizeof(longarg)))
+		    return -EFAULT;
+		return synergy_perf_append(longarg);
+		break;
+
+	case SNDRV_GET_SYNERGY_STATUS:
+		/* return int, 1 if enabled else 0 */
+		intarg = npdap->synergy_perf_enabled;
+		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
+		    return -EFAULT;
+		break;
+
+	case SNDRV_SYNERGY_ENABLE:
+		/* read int, if true enable counting else disable */
+		if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
+		    return -EFAULT;
+		synergy_perf_set_enable(intarg);
+		break;
+
+	case SNDRV_SYNERGY_FREQ:
+		/* read int, set jiffies per update */ 
+		if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
+		    return -EFAULT;
+		if (intarg < 0 || intarg >= HZ)
+			return -EINVAL;
+		synergy_perf_set_freq(intarg);
+		break;
+
+	default:
+		printk("Warning: invalid ioctl %d on synergy mon for cnode=%d fsb=%d\n", cmd, cnode, fsb);
+		return -EINVAL;
+	}
+	return(0);
+}
+
+struct file_operations synergy_mon_fops = {
+        ioctl:		synergy_perf_ioctl,
+};
+
+void
+synergy_perf_update(int cpu)
+{
+	nasid_t		nasid;
+	cnodeid_t       cnode;
+	struct nodepda_s *npdap;
+
+	/*
+	 * synergy_perf_initialized is set by synergy_perf_init()
+	 * which is called last thing by sn_mp_setup(), i.e. well
+	 * after nodepda has been initialized.
+	 */
+	if (!synergy_perf_initialized)
+		return;
+
+	cnode = cpuid_to_cnodeid(cpu);
+	npdap = NODEPDA(cnode);
+
+	if (npdap == NULL || cnode < 0 || cnode >= numnodes)
+		/* this should not happen: still in early io init */
+		return;
+
+#if 0
+	/* use this to check nodepda initialization */
+	if (((uint64_t)npdap) & 0x7) {
+		printk("\nERROR on cpu %d : cnode=%d, npdap == %p, not aligned\n", cpu, cnode, npdap);
+		BUG();
+	}
+#endif
+
+	if (npdap->synergy_perf_enabled == 0 || npdap->synergy_perf_data == NULL) {
+		/* Not enabled, or no events to monitor */
+		return;
+	}
+
+	if (npdap->synergy_inactive_intervals++ % npdap->synergy_perf_freq != 0) {
+		/* don't multiplex on every timer interrupt */
+		return;
+	}
+
+	/*
+	 * Read registers for last interval and increment counters.
+	 * Hold the per-node synergy_perf_lock so concurrent readers get
+	 * consistent values.
+	 */
+	spin_lock_irq(&npdap->synergy_perf_lock);
+
+	nasid = cpuid_to_nasid(cpu);
+	npdap->synergy_active_intervals++;
+	npdap->synergy_perf_data->intervals++;
+	npdap->synergy_perf_data->total_intervals = npdap->synergy_active_intervals;
+
+	npdap->synergy_perf_data->counts[0] += 0xffffffffffUL &
+		REMOTE_SYNERGY_LOAD(nasid, 0, PERF_CNTR0_A);
+
+	npdap->synergy_perf_data->counts[1] += 0xffffffffffUL &
+		REMOTE_SYNERGY_LOAD(nasid, 1, PERF_CNTR0_B);
+
+	/* skip to next in circular list */
+	npdap->synergy_perf_data = npdap->synergy_perf_data->next;
+
+	spin_unlock_irq(&npdap->synergy_perf_lock);
+
+	/* set the counter 0 selection modes for both A and B */
+	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTL0_A, npdap->synergy_perf_data->modesel);
+	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTL0_B, npdap->synergy_perf_data->modesel);
+
+	/* and reset the counter registers to zero */
+	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTR0_A, 0UL);
+	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTR0_B, 0UL);
+}
+
+void
+synergy_perf_init(void)
+{
+	printk("synergy_perf_init(), counting is initially disabled\n");
+	synergy_perf_initialized++;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn2/Makefile linux/arch/ia64/sn/kernel/sn2/Makefile
--- linux.orig/arch/ia64/sn/kernel/sn2/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn2/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,51 @@
+#
+# ia64/platform/sn/sn1/Makefile
+#
+# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify it 
+# under the terms of version 2 of the GNU General Public License 
+# as published by the Free Software Foundation.
+# 
+# This program is distributed in the hope that it would be useful, but 
+# WITHOUT ANY WARRANTY; without even the implied warranty of 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+# 
+# Further, this software is distributed without any warranty that it is 
+# free of the rightful claim of any third person regarding infringement 
+# or the like.  Any license provided herein, whether implied or 
+# otherwise, applies only to this software file.  Patent licenses, if 
+# any, provided herein do not apply to combinations of this program with 
+# other software, or any other product whatsoever.
+# 
+# You should have received a copy of the GNU General Public 
+# License along with this program; if not, write the Free Software 
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+# 
+# Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+# Mountain View, CA  94043, or:
+# 
+# http://www.sgi.com 
+# 
+# For further information regarding this notice, see: 
+# 
+# http://oss.sgi.com/projects/GenInfo/NoticeExplan
+#
+
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+.S.s:
+	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
+.S.o:
+	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
+
+all: sn2.a
+
+O_TARGET        = sn2.a
+
+obj-y          = cache.o iomv.o sn2_smp.o
+
+clean::
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn2/cache.c linux/arch/ia64/sn/kernel/sn2/cache.c
--- linux.orig/arch/ia64/sn/kernel/sn2/cache.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn2/cache.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,29 @@
+/*
+ * 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ *
+ */
+
+#include <asm/pgalloc.h>
+
+/**
+ * sn_flush_all_caches - flush a range of address from all caches (incl. L4)
+ * @flush_addr: identity mapped region 7 address to start flushing
+ * @bytes: number of bytes to flush
+ *
+ * Flush a range of addresses from all caches including L4. 
+ * All addresses fully or partially contained within 
+ * @flush_addr to @flush_addr + @bytes are flushed
+ * from the all caches.
+ */
+void
+sn_flush_all_caches(long flush_addr, long bytes)
+{
+	flush_icache_range(flush_addr, flush_addr+bytes);
+}
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn2/iomv.c linux/arch/ia64/sn/kernel/sn2/iomv.c
--- linux.orig/arch/ia64/sn/kernel/sn2/iomv.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn2/iomv.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,65 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/pda.h>
+#include <asm/sn/sn_cpuid.h>
+
+/**
+ * sn_io_addr - convert an in/out port to an i/o address
+ * @port: port to convert
+ *
+ * Legacy in/out instructions are converted to ld/st instructions
+ * on IA64.  This routine will convert a port number into a valid 
+ * SN i/o address.  Used by sn_in*() and sn_out*().
+ */
+void *
+sn_io_addr(unsigned long port)
+{
+	if (!IS_RUNNING_ON_SIMULATOR()) {
+		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
+	} else {
+		unsigned long io_base;
+		unsigned long addr;
+ 
+		/*
+ 		 * word align port, but need more than 10 bits
+ 		 * for accessing registers in bedrock local block
+ 		 * (so we don't do port&0xfff)
+ 		 */
+		if ((port >= 0x1f0 && port <= 0x1f7) ||
+			port == 0x3f6 || port == 0x3f7) {
+			io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38));
+			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
+		} else {
+			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
+		}
+		return(void *) addr;
+	}
+}
+
+/**
+ * sn2_mmiob - I/O space memory barrier
+ *
+ * Acts as a memory mapped I/O barrier for platforms that queue writes to 
+ * I/O space.  This ensures that subsequent writes to I/O space arrive after
+ * all previous writes.  For most ia64 platforms, this is a simple
+ * 'mf.a' instruction.  For other platforms, mmiob() may have to read
+ * a chipset register to ensure ordering.
+ *
+ * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear.
+ */
+void
+sn2_mmiob (void)
+{
+	while ( !((volatile unsigned long) (*pda.pio_write_status_addr)) & 0x8000000000000000)
+		udelay(5);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn2/sn2_smp.c linux/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- linux.orig/arch/ia64/sn/kernel/sn2/sn2_smp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn2/sn2_smp.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,184 @@
+/*
+ * SN2 Platform specific SMP Support
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mmzone.h>
+
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/sal.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/hw_irq.h>
+#include <asm/current.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn2/shub_mmr.h>
+
+/**
+ * sn2_global_tlb_purge - globally purge translation cache of virtual address range
+ * @start: start of virtual address range
+ * @end: end of virtual address range
+ * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
+ *
+ * Purges the translation caches of all processors of the given virtual address
+ * range.
+ */
+void
+sn2_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
+{
+	int		cnode, nasid;
+	volatile long	*ptc0, *ptc1, *piows;
+	unsigned long	ws, next, data0, data1;
+
+	piows = (long*)LOCAL_MMR_ADDR(get_slice() ? SH_PIO_WRITE_STATUS_1 : SH_PIO_WRITE_STATUS_0);
+	data0 = (1UL<<SH_PTC_0_A_SHFT) |
+		(nbits<<SH_PTC_0_PS_SHFT) |
+		((ia64_get_rr(start)>>8)<<SH_PTC_0_RID_SHFT) |
+		(1UL<<SH_PTC_0_START_SHFT);
+
+	ptc0 = (long*)GLOBAL_MMR_ADDR(0, SH_PTC_0);
+	ptc1 = (long*)GLOBAL_MMR_ADDR(0, SH_PTC_1);
+	do {
+		*(piows+1) = -1;	/* use alias address to clear bits*/
+		next = start;
+		do {
+			for (cnode = 0; cnode < numnodes; cnode++) {
+				nasid = cnodeid_to_nasid(cnode);
+				ptc0 = CHANGE_NASID(nasid, ptc0);
+				ptc1 = CHANGE_NASID(nasid, ptc1);
+				data1 = next | (1UL<<SH_PTC_1_START_SHFT);
+				*ptc0 = data0;
+				*ptc1 = data1;
+			}
+			next += (1UL << nbits);
+		} while (next < end);
+
+		while ((ws = *piows) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
+			;
+
+	} while (ws & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK);
+
+	
+}
+
+/**
+ * sn_send_IPI_phys - send an IPI to a Nasid and slice
+ * @physid: physical cpuid to receive the interrupt.
+ * @vector: command to send
+ * @delivery_mode: delivery mechanism
+ *
+ * Sends an IPI (interprocessor interrupt) to the processor specified by
+ * @physid
+ *
+ * @delivery_mode can be one of the following
+ *
+ * %IA64_IPI_DM_INT - pend an interrupt
+ * %IA64_IPI_DM_PMI - pend a PMI
+ * %IA64_IPI_DM_NMI - pend an NMI
+ * %IA64_IPI_DM_INIT - pend an INIT interrupt
+ */
+void
+sn_send_IPI_phys(long physid, int vector, int delivery_mode)
+{
+	long		nasid, slice;
+	long		*p, val;
+
+	nasid = cpu_physical_id_to_nasid(physid);
+        slice = cpu_physical_id_to_slice(physid);
+
+	p = (long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT);
+	val =   (1UL<<SH_IPI_INT_SEND_SHFT) | 
+		(physid<<SH_IPI_INT_PID_SHFT) | 
+	        ((long)delivery_mode<<SH_IPI_INT_TYPE_SHFT) | 
+		((long)vector<<SH_IPI_INT_IDX_SHFT) |
+		(0x000feeUL<<SH_IPI_INT_BASE_SHFT);
+
+#if defined(BRINGUP)
+	{
+	static int count=0;
+	if (count++ < 10) printk("ZZ sendIPI 0x%x vec %d, nasid 0x%lx, slice %ld, adr 0x%lx, val 0x%lx\n",
+		smp_processor_id(), vector, nasid, slice, (long)p, val);
+	}
+#endif
+	mb();
+	*p = val;
+	
+}
+
+/**
+ * sn2_send_IPI - send an IPI to a processor
+ * @cpuid: target of the IPI
+ * @vector: command to send
+ * @delivery_mode: delivery mechanism
+ * @redirect: redirect the IPI?
+ *
+ * Sends an IPI (InterProcessor Interrupt) to the processor specified by
+ * @cpuid.  @vector specifies the command to send, while @delivery_mode can 
+ * be one of the following
+ *
+ * %IA64_IPI_DM_INT - pend an interrupt
+ * %IA64_IPI_DM_PMI - pend a PMI
+ * %IA64_IPI_DM_NMI - pend an NMI
+ * %IA64_IPI_DM_INIT - pend an INIT interrupt
+ */
+void
+sn2_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
+{
+	long		physid;
+
+	physid = cpu_physical_id(cpuid);
+
+	sn_send_IPI_phys(physid, vector, delivery_mode);
+}
+
+
+/**
+ * init_sn2_smp_config - initialize SN2 smp configuration
+ *
+ * currently a NOP.
+ */
+void __init
+init_sn2_smp_config(void)
+{
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn_asm.S linux/arch/ia64/sn/kernel/sn_asm.S
--- linux.orig/arch/ia64/sn/kernel/sn_asm.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn_asm.S	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,148 @@
+
+/*
+ * Copyright (c) 2000-2001 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/config.h>
+#ifdef CONFIG_IA64_SGI_AUTOTEST
+
+// Testing only.
+// Routine will cause MCAs
+//   zzzmsa(n)
+//      n=0 MCA via duplicate TLB dropin
+//      n=0 MCA via read of garbage address
+//
+
+#define ITIR(key, ps)           ((key<<8) | (ps<<2))
+#define TLB_PAGESIZE            28                      // Use 256MB pages for now.
+
+                        .global zzzmca
+                        .proc   zzzmca
+zzzmca:
+                        alloc   loc4       = ar.pfs,2,8,1,0;;
+                        cmp.ne  p6,p0=r32,r0;;
+                        movl    r2=0x2dead
+                        movl    r3=0x3dead
+                        movl    r15=0x15dead
+                        movl    r16=0x16dead
+                        movl    r31=0x31dead
+                        movl    loc0=0x34beef
+                        movl    loc1=0x35beef
+                        movl    loc2=0x36beef
+                        movl    loc3=0x37beef
+                        movl    out0=0x42beef
+
+                        movl    r20=0x32feed;;
+                        mov     ar32=r20
+                        movl    r20=0x36feed;;
+                        mov     ar36=r20
+                        movl    r20=0x65feed;;
+                        mov     ar65=r20
+                        movl    r20=0x66feed;;
+                        mov     ar66=r20
+
+(p6)                    br.cond.sptk    1f
+
+                        rsm      0x2000;;
+                        srlz.d;
+                        mov      r11      = 1
+                        mov      r3       = ITIR(0,TLB_PAGESIZE);;
+                        mov      cr.itir  = r3
+                        mov      r10      = 0;;
+                        itr.d    dtr[r11] = r10;;
+                        mov      r11      = 2
+
+                        itr.d    dtr[r11] = r10;;
+                        br      9f
+
+1:                      movl    r8=0xfe00000048;;
+                        ld8     r9=[r8];;
+                        mf
+                        mf.a
+                        srlz.d
+
+9:                      mov     ar.pfs=loc4
+                        br.ret.sptk     rp
+
+                        .endp   zzzmca
+
+                        .global zzzspec
+                        .proc   zzzspec
+zzzspec:
+			mov	r8=r32
+			movl	r9=0xe000000000000000
+			movl	r10=0x4000;;
+			ld8.s	r16=[r8];;
+			ld8.s	r17=[r9];;
+			add	r8=r8,r10;;
+			ld8.s	r18=[r8];;
+			add	r8=r8,r10;;
+			ld8.s	r19=[r8];;
+			add	r8=r8,r10;;
+			ld8.s	r20=[r8];;
+			mov	r8=r0
+			tnat.nz	p6,p0=r16
+			tnat.nz	p7,p0=r17
+			tnat.nz	p8,p0=r18
+			tnat.nz	p9,p0=r19
+			tnat.nz	p10,p0=r20;;
+		(p6)	dep	r8=-1,r8,0,1;;
+		(p7)	dep	r8=-1,r8,1,1;;
+		(p8)	dep	r8=-1,r8,2,1;;
+		(p9)	dep	r8=-1,r8,3,1;;
+		(p10)	dep	r8=-1,r8,4,1;;
+                        br.ret.sptk     rp
+                        .endp   zzzspec
+
+                        .global zzzspec2
+                        .proc   zzzspec2
+zzzspec2:
+			cmp.eq	p6,p7=r2,r2
+			movl	r16=0xc0000a0001000020
+			;;
+			mf
+			;;
+			ld8	r9=[r16]
+		(p6)	br.spnt	1f
+			ld8	r10=[r32]
+			;;
+		1:	mf.a
+			mf
+
+			ld8	r9=[r16];;
+			cmp.ne	p6,p7=r9,r16
+		(p6)	br.spnt	1f
+			ld8	r10=[r32]
+			;;
+		1:	mf.a
+			mf
+
+			ld8	r9=[r33];;
+			cmp.ne	p6,p7=r9,r33
+		(p6)	br.spnt	1f
+			ld8	r10=[r32]
+			;;
+		1:	mf.a
+			mf
+
+			tpa	r23=r32
+			add	r20=512,r33
+			add	r21=1024,r33;;
+			ld8	r9=[r20]
+			ld8	r10=[r21];;
+			nop.i	0
+			{ .mib
+			nop.m 0
+			cmp.ne	p6,p7=r10,r33
+		(p6)	br.spnt	1f
+			}
+			ld8	r10=[r32]
+			;;
+		1:	mf.a
+			mf
+			br.ret.sptk     rp
+
+                        .endp   zzzspec
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sn_ksyms.c linux/arch/ia64/sn/kernel/sn_ksyms.c
--- linux.orig/arch/ia64/sn/kernel/sn_ksyms.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sn_ksyms.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,67 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+/*
+ * Architecture-specific kernel symbols
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <asm/machvec.h>
+#include <asm/sn/intr.h>
+
+/*
+ * other stuff (more to be added later, cleanup then)
+ */
+EXPORT_SYMBOL(sn_pci_map_sg);
+EXPORT_SYMBOL(sn_pci_unmap_sg);
+EXPORT_SYMBOL(sn_pci_alloc_consistent);
+EXPORT_SYMBOL(sn_pci_free_consistent);
+EXPORT_SYMBOL(sn_dma_address);
+
+#include <linux/mm.h>
+#include <linux/devfs_fs_kernel.h>
+extern devfs_handle_t          base_io_scsi_ctlr_vhdl[];
+#include <asm/sn/types.h>
+extern cnodeid_t master_node_get(devfs_handle_t vhdl);
+#include <asm/sn/arch.h>
+EXPORT_SYMBOL(base_io_scsi_ctlr_vhdl);
+EXPORT_SYMBOL(master_node_get);
+
+
+/*
+ * symbols referenced by the PCIBA module
+ */
+#include <asm/sn/invent.h>
+#include <asm/sn/hack.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/pci/pciio.h>
+
+devfs_handle_t
+devfn_to_vertex(unsigned char busnum, unsigned int devfn);
+EXPORT_SYMBOL(devfn_to_vertex);
+EXPORT_SYMBOL(hwgraph_vertex_unref);
+EXPORT_SYMBOL(pciio_config_get);
+EXPORT_SYMBOL(pciio_info_slot_get);
+EXPORT_SYMBOL(hwgraph_edge_add);
+EXPORT_SYMBOL(pciio_info_master_get);
+EXPORT_SYMBOL(pciio_info_get);
+#ifdef CONFIG_IA64_SGI_SN_DEBUG
+EXPORT_SYMBOL(__pa_debug);
+EXPORT_SYMBOL(__va_debug);
+#endif
+
+/* Support IPIs for loaded modules. */
+EXPORT_SYMBOL(sn_send_IPI_phys);
+
+#include <linux/mmzone.h>
+EXPORT_SYMBOL(sn_pci_unmap_single);
+EXPORT_SYMBOL(sn_pci_map_single);
+EXPORT_SYMBOL(sn_pci_dma_sync_single);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/kernel/sv.c linux/arch/ia64/sn/kernel/sv.c
--- linux.orig/arch/ia64/sn/kernel/sv.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ia64/sn/kernel/sv.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,552 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc.  All rights reserved
+ *
+ * This implemenation of synchronization variables is heavily based on
+ * one done by Steve Lord <lord@sgi.com>
+ *
+ * Paul Cassella <pwc@sgi.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+
+#include <asm/sn/sv.h>
+
+/* Define this to have sv_test() run some simple tests.
+   kernel_thread() must behave as expected when this is called.  */
+#undef RUN_SV_TEST
+
+#define DEBUG
+
+/* Set up some macros so sv_wait(), sv_signal(), and sv_broadcast()
+   can sanity check interrupt state on architectures where we know
+   how. */
+#ifdef DEBUG
+ #define SV_DEBUG_INTERRUPT_STATE
+ #ifdef __mips64
+  #define SV_TEST_INTERRUPTS_ENABLED(flags) ((flags & 0x1) != 0)
+  #define SV_TEST_INTERRUPTS_DISABLED(flags) ((flags & 0x1) == 0)
+  #define SV_INTERRUPT_TEST_WORKERS 31
+ #elif defined(__ia64)
+  #define SV_TEST_INTERRUPTS_ENABLED(flags) ((flags & 0x4000) != 0)
+  #define SV_TEST_INTERRUPTS_DISABLED(flags) ((flags & 0x4000) == 0)
+  #define SV_INTERRUPT_TEST_WORKERS 4 /* simulator's slow */
+ #else
+  #undef  SV_DEBUG_INTERRUPT_STATE
+  #define SV_INTERRUPT_TEST_WORKERS 4 /* reasonable? default. */
+ #endif /* __mips64 */
+#endif /* DEBUG */
+
+
+/* XXX FIXME hack hack hack.  Our mips64 tree is from before the
+   switch to WQ_FLAG_EXCLUSIVE, and our ia64 tree is from after it. */
+#ifdef TASK_EXCLUSIVE
+  #undef EXCLUSIVE_IN_QUEUE
+#else
+  #define EXCLUSIVE_IN_QUEUE
+  #define TASK_EXCLUSIVE 0 /* for the set_current_state() in sv_wait() */
+#endif
+
+
+static inline void sv_lock(sv_t *sv) {
+	spin_lock(&sv->sv_lock);
+}
+
+static inline void sv_unlock(sv_t *sv) {
+	spin_unlock(&sv->sv_lock);
+}
+
+/* up() is "extern inline", so we can't pass its address to sv_wait.
+   Use this function's address instead. */
+static void up_wrapper(struct semaphore *sem) {
+	up(sem);
+}
+
+/* spin_unlock() is sometimes a macro. */
+static void spin_unlock_wrapper(spinlock_t *s) {
+	spin_unlock(s);
+}
+
+/* XXX Perhaps sv_wait() should do the switch() each time and avoid
+   the extra indirection and the need for the _wrapper functions? */
+
+static inline void sv_set_mon_type(sv_t *sv, int type) {
+	switch (type) {
+	case SV_MON_SPIN:
+		sv->sv_mon_unlock_func =
+		  (sv_mon_unlock_func_t)spin_unlock_wrapper;
+		break;
+	case SV_MON_SEMA:
+		sv->sv_mon_unlock_func =
+		  (sv_mon_unlock_func_t)up_wrapper;
+		if(sv->sv_flags & SV_INTS) {
+			printk(KERN_ERR "sv_set_mon_type: The monitor lock "
+			       "cannot be shared with interrupts if it is a "
+			       "semaphore!\n");
+			BUG();
+		}
+		if(sv->sv_flags & SV_BHS) {
+			printk(KERN_ERR "sv_set_mon_type: The monitor lock "
+			       "cannot be shared with bottom-halves if it is "
+			       "a semaphore!\n");
+			BUG();
+		}
+		break;
+#if 0 
+	/*
+	 * If needed, and will need to think about interrupts.  This
+	 * may be needed, for example, if someone wants to use sv's
+	 * with something like dev_base; writers need to hold two
+	 * locks. 
+	 */
+	case SV_MON_CUSTOM: 
+		{
+		struct sv_mon_custom *c = lock;
+		sv->sv_mon_unlock_func = c->sv_mon_unlock_func;
+		sv->sv_mon_lock        = c->sv_mon_lock;
+		break;
+		}
+#endif
+		
+	default:
+		printk(KERN_ERR "sv_set_mon_type: unknown type %d (0x%x)! "
+		       "(flags 0x%x)\n", type, type, sv->sv_flags);
+		BUG();
+		break;
+	}
+	sv->sv_flags |= type;
+}
+
+static inline void sv_set_ord(sv_t *sv, int ord) {
+	if (!ord)
+		ord = SV_ORDER_DEFAULT;
+
+	if (ord != SV_ORDER_FIFO && ord != SV_ORDER_LIFO) {
+		printk(KERN_EMERG "sv_set_ord: unknown order %d (0x%x)! ",
+		       ord, ord);
+		BUG();
+	}
+
+	sv->sv_flags |= ord;
+}
+
+void sv_init(sv_t *sv, sv_mon_lock_t *lock, int flags) 
+{
+	int ord = flags & SV_ORDER_MASK;
+	int type = flags & SV_MON_MASK;
+
+	/* Copy all non-order, non-type flags */
+	sv->sv_flags = (flags & ~(SV_ORDER_MASK | SV_MON_MASK));
+
+	if((sv->sv_flags & (SV_INTS | SV_BHS)) == (SV_INTS | SV_BHS)) {
+	  printk(KERN_ERR "sv_init: do not set both SV_INTS and SV_BHS, only SV_INTS.\n");
+	  BUG();
+	}
+
+	sv_set_ord(sv, ord);
+	sv_set_mon_type(sv, type);
+
+	/* If lock is NULL, we'll get it from sv_wait_compat() (and
+           ignore it in sv_signal() and sv_broadcast()). */
+	sv->sv_mon_lock = lock;
+
+	spin_lock_init(&sv->sv_lock);
+	init_waitqueue_head(&sv->sv_waiters);
+}
+
+/*
+ * The associated lock must be locked on entry.  It is unlocked on return.
+ *
+ * Return values:
+ *
+ * n < 0 : interrupted,  -n jiffies remaining on timeout, or -1 if timeout == 0
+ * n = 0 : timeout expired
+ * n > 0 : sv_signal()'d, n jiffies remaining on timeout, or 1 if timeout == 0
+ */
+signed long sv_wait(sv_t *sv, int sv_wait_flags, unsigned long timeout) 
+{
+	DECLARE_WAITQUEUE( wait, current );
+	unsigned long flags;
+	signed long ret = 0;
+
+#ifdef SV_DEBUG_INTERRUPT_STATE
+	{
+	unsigned long flags;
+	__save_flags(flags);
+
+	if(sv->sv_flags & SV_INTS) {
+		if(SV_TEST_INTERRUPTS_ENABLED(flags)) {
+			printk(KERN_ERR "sv_wait: SV_INTS and interrupts "
+			       "enabled (flags: 0x%lx)\n", flags);
+			BUG();
+		}
+	} else {
+		if (SV_TEST_INTERRUPTS_DISABLED(flags)) {
+			printk(KERN_WARNING "sv_wait: !SV_INTS and interrupts "
+			       "disabled! (flags: 0x%lx)\n", flags);
+		}
+	}
+	}
+#endif  /* SV_DEBUG_INTERRUPT_STATE */
+
+	sv_lock(sv);
+
+	sv->sv_mon_unlock_func(sv->sv_mon_lock);
+
+	/* Add ourselves to the wait queue and set the state before
+	 * releasing the sv_lock so as to avoid racing with the
+	 * wake_up() in sv_signal() and sv_broadcast(). 
+	 */
+
+	/* don't need the _irqsave part, but there is no wq_write_lock() */
+	wq_write_lock_irqsave(&sv->sv_waiters.lock, flags);
+
+#ifdef EXCLUSIVE_IN_QUEUE
+	wait.flags |= WQ_FLAG_EXCLUSIVE;
+#endif
+
+	switch(sv->sv_flags & SV_ORDER_MASK) {
+	case SV_ORDER_FIFO:
+		__add_wait_queue_tail(&sv->sv_waiters, &wait);
+		break;
+	case SV_ORDER_FILO:
+		__add_wait_queue(&sv->sv_waiters, &wait);
+		break;
+	default:
+		printk(KERN_ERR "sv_wait: unknown order!  (sv: 0x%p, flags: 0x%x)\n",
+					(void *)sv, sv->sv_flags);
+		BUG();
+	}
+	wq_write_unlock_irqrestore(&sv->sv_waiters.lock, flags);
+
+	if(sv_wait_flags & SV_WAIT_SIG)
+		set_current_state(TASK_EXCLUSIVE | TASK_INTERRUPTIBLE  );
+	else
+		set_current_state(TASK_EXCLUSIVE | TASK_UNINTERRUPTIBLE);
+
+	spin_unlock(&sv->sv_lock);
+
+	if(sv->sv_flags & SV_INTS)
+		local_irq_enable();
+	else if(sv->sv_flags & SV_BHS)
+		local_bh_enable();
+
+	if (timeout)
+		ret = schedule_timeout(timeout);
+	else
+		schedule();
+
+	if(current->state != TASK_RUNNING) /* XXX Is this possible? */ {
+		printk(KERN_ERR "sv_wait: state not TASK_RUNNING after "
+		       "schedule().\n");
+		set_current_state(TASK_RUNNING);
+	}
+
+	remove_wait_queue(&sv->sv_waiters, &wait);
+
+	/* Return cases:
+	   - woken by a sv_signal/sv_broadcast
+	   - woken by a signal
+	   - woken by timeout expiring
+	*/
+
+	/* XXX This isn't really accurate; we may have been woken
+           before the signal anyway.... */
+	if(signal_pending(current))
+		return timeout ? -ret : -1;
+	return timeout ? ret : 1;
+}
+
+
+void sv_signal(sv_t *sv) 
+{
+	/* If interrupts can acquire this lock, they can also acquire the
+	   sv_mon_lock, which we must already have to have called this, so
+	   interrupts must be disabled already.  If interrupts cannot
+	   contend for this lock, we don't have to worry about it. */
+
+#ifdef SV_DEBUG_INTERRUPT_STATE
+	if(sv->sv_flags & SV_INTS) {
+		unsigned long flags;
+		__save_flags(flags);
+		if(SV_TEST_INTERRUPTS_ENABLED(flags))
+			printk(KERN_ERR "sv_signal: SV_INTS and "
+			"interrupts enabled! (flags: 0x%lx)\n", flags);
+	}
+#endif /* SV_DEBUG_INTERRUPT_STATE */
+
+	sv_lock(sv);
+	wake_up(&sv->sv_waiters);
+	sv_unlock(sv);
+}
+
+void sv_broadcast(sv_t *sv) 
+{
+#ifdef SV_DEBUG_INTERRUPT_STATE
+	if(sv->sv_flags & SV_INTS) {
+		unsigned long flags;
+		__save_flags(flags);
+		if(SV_TEST_INTERRUPTS_ENABLED(flags))
+			printk(KERN_ERR "sv_broadcast: SV_INTS and "
+			       "interrupts enabled! (flags: 0x%lx)\n", flags);
+	}
+#endif /* SV_DEBUG_INTERRUPT_STATE */
+
+	sv_lock(sv);
+	wake_up_all(&sv->sv_waiters);
+	sv_unlock(sv);
+}
+
+void sv_destroy(sv_t *sv) 
+{
+	if(!spin_trylock(&sv->sv_lock)) {
+		printk(KERN_ERR "sv_destroy: someone else has sv 0x%p locked!\n", (void *)sv);
+		BUG();
+	}
+
+	/* XXX Check that the waitqueue is empty? 
+	       Mark the sv destroyed?
+	*/
+}
+
+
+#ifdef RUN_SV_TEST
+
+static DECLARE_MUTEX_LOCKED(talkback);
+static DECLARE_MUTEX_LOCKED(sem);
+sv_t sv;
+sv_t sv_filo;
+
+static int sv_test_1_w(void *arg) 
+{
+	printk("sv_test_1_w: acquiring spinlock 0x%p...\n", arg);
+
+	spin_lock((spinlock_t*)arg);
+	printk("sv_test_1_w: spinlock acquired, waking sv_test_1_s.\n");
+
+	up(&sem);
+
+	printk("sv_test_1_w: sv_spin_wait()'ing.\n");
+
+	sv_spin_wait(&sv, arg);
+
+	printk("sv_test_1_w: talkback.\n");
+	up(&talkback);
+
+	printk("sv_test_1_w: exiting.\n");
+	return 0;
+}
+
+static int sv_test_1_s(void *arg) 
+{
+	printk("sv_test_1_s: waiting for semaphore.\n");
+	down(&sem);
+	printk("sv_test_1_s: semaphore acquired.  Acquiring spinlock.\n");
+	spin_lock((spinlock_t*)arg);
+	printk("sv_test_1_s: spinlock acquired.  sv_signaling.\n");
+	sv_signal(&sv);
+	printk("sv_test_1_s: talkback.\n");
+	up(&talkback);
+	printk("sv_test_1_s: exiting.\n");
+	return 0;
+
+}
+
+static int count;
+static DECLARE_MUTEX(monitor);
+
+static int sv_test_2_w(void *arg) 
+{
+	int dummy = count++;
+	sv_t *sv = (sv_t *)arg;
+
+	down(&monitor);
+	up(&talkback);
+	printk("sv_test_2_w: thread %d started, sv_waiting.\n", dummy);
+	sv_sema_wait(sv, &monitor);
+	printk("sv_test_2_w: thread %d woken, exiting.\n", dummy);
+	up(&sem);
+	return 0;
+}
+
+static int sv_test_2_s_1(void *arg) 
+{
+	int i;
+	sv_t *sv = (sv_t *)arg;
+
+	down(&monitor);
+	for(i = 0; i < 3; i++) {
+		printk("sv_test_2_s_1: waking one thread.\n");
+		sv_signal(sv);
+		down(&sem);
+	}
+
+	printk("sv_test_2_s_1: signaling and broadcasting again.  Nothing should happen.\n");
+	sv_signal(sv);
+	sv_broadcast(sv);
+	sv_signal(sv);
+	sv_broadcast(sv);
+
+	printk("sv_test_2_s_1: talkbacking.\n");
+	up(&talkback);
+	up(&monitor);
+	return 0;
+}
+
+static int sv_test_2_s(void *arg) 
+{
+	int i;
+	sv_t *sv = (sv_t *)arg;
+
+	down(&monitor);
+	for(i = 0; i < 3; i++) {
+		printk("sv_test_2_s: waking one thread (should be %d.)\n", i);
+		sv_signal(sv);
+		down(&sem);
+	}
+
+	printk("sv_test_3_s: waking remaining threads with broadcast.\n");
+	sv_broadcast(sv);
+	for(; i < 10; i++)
+		down(&sem);
+
+	printk("sv_test_3_s: sending talkback.\n");
+	up(&talkback);
+
+	printk("sv_test_3_s: exiting.\n");
+	up(&monitor);
+	return 0;
+}
+
+
+static void big_test(sv_t *sv) 
+{
+	int i;
+
+	count = 0;
+
+	for(i = 0; i < 3; i++) {
+		printk("big_test: spawning thread %d.\n", i);
+		kernel_thread(sv_test_2_w, sv, 0);
+		down(&talkback);
+	}
+
+	printk("big_test: spawning first wake-up thread.\n");
+	kernel_thread(sv_test_2_s_1, sv, 0);
+
+	down(&talkback);
+	printk("big_test: talkback happened.\n");
+
+
+	for(i = 3; i < 13; i++) {
+		printk("big_test: spawning thread %d.\n", i);
+		kernel_thread(sv_test_2_w, sv, 0);
+		down(&talkback);
+	}
+
+	printk("big_test: spawning wake-up thread.\n");
+	kernel_thread(sv_test_2_s, sv, 0);
+
+	down(&talkback);
+}
+
+sv_t int_test_sv;
+spinlock_t int_test_spin = SPIN_LOCK_UNLOCKED;
+int int_test_ready;
+static int irqtestcount;
+
+static int interrupt_test_worker(void *unused) 
+{
+	int id = ++irqtestcount;
+	int it = 0;
+			unsigned long flags, flags2;
+
+	printk("ITW: thread %d started.\n", id);
+
+	while(1) {
+		__save_flags(flags2);
+		if(jiffies % 3) {
+			printk("ITW %2d %5d: irqsaving          (%lx)\n", id, it, flags2);
+			spin_lock_irqsave(&int_test_spin, flags);
+		} else {
+			printk("ITW %2d %5d: spin_lock_irqing   (%lx)\n", id, it, flags2);
+			spin_lock_irq(&int_test_spin);
+		}
+
+		__save_flags(flags2);
+		printk("ITW %2d %5d: locked, sv_waiting (%lx).\n", id, it, flags2);
+		sv_wait(&int_test_sv, 0, 0);
+
+		__save_flags(flags2);
+		printk("ITW %2d %5d: wait finished      (%lx), pausing\n", id, it, flags2);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(jiffies & 0xf);
+		if(current->state != TASK_RUNNING)
+		  printk("ITW:  current->state isn't RUNNING after schedule!\n");
+		it++;
+	}
+}
+
+static void interrupt_test(void) 
+{
+	int i;
+
+	printk("interrupt_test: initing sv.\n");
+	sv_init(&int_test_sv, &int_test_spin, SV_MON_SPIN | SV_INTS);
+
+	for(i = 0; i < SV_INTERRUPT_TEST_WORKERS; i++) {
+		printk("interrupt_test: starting test thread %d.\n", i);
+		kernel_thread(interrupt_test_worker, 0, 0);
+	}
+	printk("interrupt_test: done with init part.\n");
+	int_test_ready = 1;
+}
+
+int sv_test(void) 
+{
+	spinlock_t s = SPIN_LOCK_UNLOCKED;
+
+	sv_init(&sv, &s, SV_MON_SPIN);
+	printk("sv_test: starting sv_test_1_w.\n");
+	kernel_thread(sv_test_1_w, &s, 0);
+	printk("sv_test: starting sv_test_1_s.\n");
+	kernel_thread(sv_test_1_s, &s, 0);
+
+	printk("sv_test: waiting for talkback.\n");
+	down(&talkback); down(&talkback);
+	printk("sv_test: talkback happened, sv_destroying.\n");
+	sv_destroy(&sv);
+
+	count = 0;
+
+	printk("sv_test: beginning big_test on sv.\n");
+
+	sv_init(&sv, &monitor, SV_MON_SEMA);
+	big_test(&sv);
+	sv_destroy(&sv);
+
+	printk("sv_test: beginning big_test on sv_filo.\n");
+	sv_init(&sv_filo, &monitor, SV_MON_SEMA | SV_ORDER_FILO);
+	big_test(&sv_filo);
+	sv_destroy(&sv_filo);
+
+	interrupt_test();
+
+	printk("sv_test: done.\n");
+	return 0;
+}
+
+__initcall(sv_test);
+
+#endif /* RUN_SV_TEST */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/Makefile linux/arch/ia64/sn/sn1/Makefile
--- linux.orig/arch/ia64/sn/sn1/Makefile	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,31 +0,0 @@
-#
-# ia64/platform/sn/sn1/Makefile
-#
-# Copyright (C) 1999 Silicon Graphics, Inc.
-# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
-#
-
-EXTRA_CFLAGS	:= -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \
-		   -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \
-		   -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \
-		   -DNEW_INTERRUPTS
-
-.S.s:
-	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
-.S.o:
-	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
-
-all: sn1.a
-
-O_TARGET        = sn1.a
-
-obj-y          = irq.o setup.o iomv.o mm.o smp.o synergy.o sn1_asm.o \
-		discontig.o probe.o error.o sv.o
-
-obj-$(CONFIG_IA64_SGI_AUTOTEST)	+= llsc4.o
-obj-$(CONFIG_IA64_GENERIC)	+= machvec.o
-obj-$(CONFIG_MODULES)		+= sn1_ksyms.o
-
-clean::
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/discontig.c linux/arch/ia64/sn/sn1/discontig.c
--- linux.orig/arch/ia64/sn/sn1/discontig.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/discontig.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,159 +0,0 @@
-/*
- * Copyright 2000, Silicon Graphics, sprasad@engr.sgi.com
- * Copyright 2000, Kanoj Sarcar, kanoj@sgi.com
- */
-
-/*
- * Contains common definitions and globals for NUMA platform
- * support. For now, SN-IA64 and SN-MIPS are the NUMA platforms.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <asm/sn/mmzone.h>
-#include <asm/efi.h>
-
-extern int numnodes ;
-
-plat_pg_data_t plat_node_data[MAXNODES];
-bootmem_data_t bdata[MAXNODES];
-int chunktonid[MAXCHUNKS];
-int nasid_map[MAXNASIDS];
-
-void __init
-init_chunktonid(void)
-{
-	memset(chunktonid, -1, sizeof(chunktonid)) ;
-}
-
-void __init
-init_nodeidmap(void)
-{
-	memset(nasid_map, -1, sizeof(nasid_map)) ;
-}
-
-int		cnodeid_map[MAXNODES] ;
-void __init
-init_cnodeidmap(void)
-{
-	memset(cnodeid_map, -1, sizeof(cnodeid_map)) ;
-}
-
-int
-numa_debug(void)
-{
-       panic("NUMA debug\n");
-       return(0);
-}
-
-int __init
-build_cnodeid_map(void)
-{
-	int	i,j ;
-
-	for (i=0,j=0;i<MAXNASIDS;i++) {
-		if (nasid_map[i] >= 0)
-			cnodeid_map[j++] = i ;
-	}
-	return j ;
-}
-
-/*
- * Since efi_memmap_walk merges contiguous banks, this code will need
- * to find all the nasids covered by the input memory descriptor.
- */
-static int __init
-build_nasid_map(unsigned long start, unsigned long end, void *arg)
-{
-	unsigned long vaddr = start;
-	int nasid = GetNasId(__pa(vaddr));
-
-	while (vaddr < end) {
-		if (nasid < MAXNASIDS)
-			nasid_map[nasid] = 0;
-		else
-			panic("build_nasid_map");
-		vaddr = (unsigned long)__va((unsigned long)(++nasid) << 
-							SN1_NODE_ADDR_SHIFT);
-	}
-	return 0;
-}
-
-void __init
-fix_nasid_map(void)
-{
-	int	i ;
-	int		j ;
-
-	/* For every nasid */
-	for (j=0;j<MAXNASIDS;j++) {
-		for (i=0;i<MAXNODES;i++) {
-			if (CNODEID_TO_NASID(i) == j)
-				break ;
-		}
-		if (i<MAXNODES)
-			nasid_map[j] = i ;
-	}
-}
-
-static void __init
-dump_bootmem_info(void)
-{
-        int     i;
-        struct bootmem_data *bdata ;
-
-	printk("CNODE INFO ....\n") ;
-        for (i=0;i<numnodes;i++) {
-		printk("%d ", CNODEID_TO_NASID(i)) ;
-	}
-	printk("\n") ;
-
-	printk("BOOT MEM INFO ....\n") ;
-        printk("Node   Start                LowPfn               BootmemMap\n") ;
-        for (i=0;i<numnodes;i++) {
-                bdata = NODE_DATA(i)->bdata ;
-                printk("%d      0x%016lx   0x%016lx   0x%016lx\n", i,
-                        bdata->node_boot_start, bdata->node_low_pfn,
-                        (unsigned long)bdata->node_bootmem_map) ;
-        }
-}
-
-void __init
-discontig_mem_init(void)
-{
-	extern void setup_sn1_bootmem(int);
-	int		maxnodes ;
-
-        init_chunktonid() ;
-	init_nodeidmap() ;
-	init_cnodeidmap() ;
-	efi_memmap_walk(build_nasid_map, 0) ;
-	maxnodes = build_cnodeid_map() ;
-	fix_nasid_map() ;
-#ifdef CONFIG_DISCONTIGMEM
-	setup_sn1_bootmem(maxnodes) ;
-#endif
-	numnodes = maxnodes;
-	dump_bootmem_info() ;
-}
-
-void
-dump_node_data(void)
-{
-        int     i;
-
-	printk("NODE DATA ....\n") ;
-	printk("Node, Start, Size, MemMap, BitMap, StartP, Mapnr, Size, Id\n") ;
-        for (i=0;i<numnodes;i++) {
-		printk("%d, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, %d\n", 
-			CNODEID_TO_NASID(i), NODE_START(i), NODE_SIZE(i), 
-			(long)NODE_MEM_MAP(i), (long)NODE_DATA(i)->valid_addr_bitmap, 
-			NODE_DATA(i)->node_start_paddr, 
-			NODE_DATA(i)->node_start_mapnr,
-			NODE_DATA(i)->node_size,
-			NODE_DATA(i)->node_id)  ;
-	}
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/error.c linux/arch/ia64/sn/sn1/error.c
--- linux.orig/arch/ia64/sn/sn1/error.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/error.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,149 +0,0 @@
-
-
-/*
- * SN1 Platform specific error Support
- *
- * Copyright (C) 2001 Silicon Graphics, Inc.
- * Copyright (C) 2001 Alan Mayer (ajm@sgi.com)
- */
-
-
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-
-void
-snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs) {
-	unsigned long long intpend_val;
-	unsigned long long bit;
-
-	switch (irq) {
-	case SGI_UART_IRQ:
-		// This isn't really an error interrupt.  We're just
-		// here because we have to do something with them.
-		// This is probably wrong, and this code will be
-		// removed.
-		intpend_val = LOCAL_HUB_L(PI_INT_PEND0);
-		if ( (bit = ~(1L<<GFX_INTR_A)) ==
-			(intpend_val & ~(1L<<GFX_INTR_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<GFX_INTR_B)) ==
-			(intpend_val & ~(1L<<GFX_INTR_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<PG_MIG_INTR)) ==
-			(intpend_val & ~(1L<<PG_MIG_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<UART_INTR)) ==
-			(intpend_val & ~(1L<<UART_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<CC_PEND_A)) ==
-			(intpend_val & ~(1L<<CC_PEND_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<CC_PEND_B)) ==
-			(intpend_val & ~(1L<<CC_PEND_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		printk("Received SGI_UART_IRQ (65), but no intpend0 bits were set???\n");
-		return;
-	case SGI_HUB_ERROR_IRQ:
-		// These are mostly error interrupts of various
-		// sorts.  We need to do more than panic here, but
-		// what the heck, this is bring up.
-		intpend_val = LOCAL_HUB_L(PI_INT_PEND1);
-		
-		if ( (bit = ~(1L<<XB_ERROR)) ==
-			(intpend_val & ~(1L<<XB_ERROR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED XB_ERROR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<LB_ERROR)) ==
-			(intpend_val & ~(1L<<LB_ERROR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED LB_ERROR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NACK_INT_A)) ==
-			(intpend_val & ~(1L<<NACK_INT_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NACK_INT_A on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NACK_INT_B)) ==
-			(intpend_val & ~(1L<<NACK_INT_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NACK_INT_B on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<CLK_ERR_INTR)) ==
-			(intpend_val & ~(1L<<CLK_ERR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED CLK_ERR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<COR_ERR_INTR_A)) ==
-			(intpend_val & ~(1L<<COR_ERR_INTR_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED COR_ERR_INTR_A on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<COR_ERR_INTR_B)) ==
-			(intpend_val & ~(1L<<COR_ERR_INTR_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED COR_ERR_INTR_B on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<MD_COR_ERR_INTR)) ==
-			(intpend_val & ~(1L<<MD_COR_ERR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED MD_COR_ERR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NI_ERROR_INTR)) ==
-			(intpend_val & ~(1L<<NI_ERROR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NI_ERROR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<MSC_PANIC_INTR)) ==
-			(intpend_val & ~(1L<<MSC_PANIC_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED MSC_PANIC_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		printk("Received SGI_XB_ERROR_IRQ (182) but no intpend1 bits are set???\n");
-		return;
-	default:
-		printk("Received invalid irq in snia_error_intr_handler()/n");
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/iomv.c linux/arch/ia64/sn/sn1/iomv.c
--- linux.orig/arch/ia64/sn/sn1/iomv.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/iomv.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,97 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
- * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
- */
-
-#include <asm/io.h>
-#include <linux/pci.h>
-
-static inline void *
-sn1_io_addr(unsigned long port)
-{
-	if (!IS_RUNNING_ON_SIMULATOR()) {
-		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
-	} else {
-		unsigned long io_base;
-		unsigned long addr;
- 
-		/*
- 		 * word align port, but need more than 10 bits
- 		 * for accessing registers in bedrock local block
- 		 * (so we don't do port&0xfff)
- 		 */
-		if (port >= 0x1f0 && port <= 0x1f7 ||
-			port == 0x3f6 || port == 0x3f7) {
-			io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000;
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
-		return(void *) addr;
-	}
-}
-
-unsigned int
-sn1_inb (unsigned long port)
-{
-	volatile unsigned char *addr = sn1_io_addr(port);
-	unsigned char ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-unsigned int
-sn1_inw (unsigned long port)
-{
-	volatile unsigned short *addr = sn1_io_addr(port);
-	unsigned short ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-unsigned int
-sn1_inl (unsigned long port)
-{
-	volatile unsigned int *addr = sn1_io_addr(port);
-	unsigned int ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-void
-sn1_outb (unsigned char val, unsigned long port)
-{
-	volatile unsigned char *addr = sn1_io_addr(port);
-
-	*addr = val;
-	__ia64_mf_a();
-}
-
-void
-sn1_outw (unsigned short val, unsigned long port)
-{
-	volatile unsigned short *addr = sn1_io_addr(port);
-
-	*addr = val;
-	__ia64_mf_a();
-}
-
-void
-sn1_outl (unsigned int val, unsigned long port)
-{
-	volatile unsigned int *addr = sn1_io_addr(port);
-
-	*addr = val;
-	__ia64_mf_a();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/irq.c linux/arch/ia64/sn/sn1/irq.c
--- linux.orig/arch/ia64/sn/sn1/irq.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/irq.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,183 +0,0 @@
-/*
- * Platform dependent support for SGI SN1
- *
- * Copyright (C) 2000   Silicon Graphics
- * Copyright (C) 2000   Jack Steiner (steiner@sgi.com)
- * Copyright (C) 2000   Alan Mayer (ajm@sgi.com)
- * Copyright (C) 2000   Kanoj Sarcar (kanoj@sgi.com)
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <asm/current.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/types.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pciio_private.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn1/addrs.h>
-#include <asm/sn/iobus.h>
-#include <asm/sn/sn1/arch.h>
-#include <asm/sn/synergy.h>
-
-#define IRQ_BIT_OFFSET 64
-
-int bit_pos_to_irq(int bit)
-{
-	if (bit > 118)
-		bit = 118;
-	return (bit + IRQ_BIT_OFFSET);
-}
-
-static inline int irq_to_bit_pos(int irq)
-{
-	int bit = irq - IRQ_BIT_OFFSET;
-
-	if (bit > 63)
-		bit -= 64;
-	return bit;
-}
-
-static unsigned int
-sn1_startup_irq(unsigned int irq)
-{
-        return(0);
-}
-
-static void
-sn1_shutdown_irq(unsigned int irq)
-{
-}
-
-static void
-sn1_disable_irq(unsigned int irq)
-{
-}
-
-static void
-sn1_enable_irq(unsigned int irq)
-{
-}
-
-static void
-sn1_ack_irq(unsigned int irq)
-{
-}
-
-static void
-sn1_end_irq(unsigned int irq)
-{
-	int bit;
-
-	bit = irq_to_bit_pos(irq);
-	LOCAL_HUB_CLR_INTR(bit);
-}
-
-static void
-sn1_set_affinity_irq(unsigned int irq, unsigned long mask)
-{
-}
-
-struct hw_interrupt_type irq_type_sn1 = {
-        "sn1_irq",
-        sn1_startup_irq,
-        sn1_shutdown_irq,
-        sn1_enable_irq,
-        sn1_disable_irq,
-        sn1_ack_irq,
-        sn1_end_irq,
-        sn1_set_affinity_irq
-};
-
-
-void
-sn1_irq_init (void)
-{
-	int i;
-
-	for (i = 0; i <= NR_IRQS; ++i) {
-		if (idesc_from_vector(i)->handler == &no_irq_type) {
-			idesc_from_vector(i)->handler = &irq_type_sn1;
-		}
-	}
-}
-
-
-
-#if !defined(CONFIG_IA64_SGI_SN1)
-void
-sn1_pci_fixup(int arg)
-{
-}
-#endif
-
-#ifdef CONFIG_PERCPU_IRQ
-
-extern irq_desc_t irq_descX[NR_IRQS];
-irq_desc_t *irq_desc_ptr[NR_CPUS] = { irq_descX };
-
-/*
- * Each slave AP allocates its own irq table.
- */
-int __init cpu_irq_init(void)
-{
-	irq_desc_ptr[smp_processor_id()] = (irq_desc_t *)kmalloc(sizeof(irq_descX), GFP_KERNEL);
-	if (irq_desc_ptr[smp_processor_id()] == 0)
-		return(-1);
-	memcpy(irq_desc_ptr[smp_processor_id()], irq_desc_ptr[0], 
-							sizeof(irq_descX));
-	return(0);
-}
-
-/*
- * This can also allocate the irq tables for the other cpus, specifically
- * on their nodes.
- */
-int __init master_irq_init(void)
-{
-	return(0);
-}
-
-/*
- * The input is an ivt level.
- */
-irq_desc_t *idesc_from_vector(unsigned int ivnum)
-{
-	return(irq_desc_ptr[smp_processor_id()] + ivnum);
-}
-
-/*
- * The input is a "soft" level, that we encoded in.
- */
-irq_desc_t *idesc_from_irq(unsigned int irq)
-{
-	return(irq_desc_ptr[irq >> 8] + (irq & 0xff));
-}
-
-unsigned int ivector_from_irq(unsigned int irq)
-{
-	return(irq & 0xff);
-}
-
-/*
- * This should return the Linux irq # for the i/p vector on the
- * i/p cpu. We currently do not track this.
- */
-unsigned int irq_from_cpuvector(int cpunum, unsigned int vector)
-{
-	return (vector);
-}
-
-#endif /* CONFIG_PERCPU_IRQ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/llsc4.c linux/arch/ia64/sn/sn1/llsc4.c
--- linux.orig/arch/ia64/sn/sn1/llsc4.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/sn/sn1/llsc4.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,952 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/kernel_stat.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <asm/efi.h>
-#include <asm/page.h>
-#include <linux/threads.h>
-
-extern void bringup_set_led_bits(u8 bits, u8 mask);
-
-#include "llsc4.h"
-
-
-#ifdef STANDALONE
-#include "lock.h"
-#endif
-
-#ifdef INTTEST
-static int	inttest=0;
-#endif
-
-/*
- * Test parameter table for AUTOTEST
- */
-typedef struct {
-	int	passes;
-	int	linecount;
-	int	linepad;
-} autotest_table_t;
-
-autotest_table_t autotest_table[] = {
-	{5000000,	2,	0x2b4		},
-	{5000000,	16,	0,		},
-	{5000000,	16,	4,		},
-	{5000000,	128,	0x44		},
-	{5000000,	128,	0x84		},
-	{5000000,	128,	0x200		},
-	{5000000,	128,	0x204		},
-	{5000000,	128,	0x2b4		},
-	{5000000,	2,	8*MB+0x2b4	},
-	{5000000,	16,	8*MB+0		},
-	{5000000,	16,	8*MB+4		},
-	{5000000,	128,	8*MB+0x44	},
-	{5000000,	128,	8*MB+0x84	},
-	{5000000,	128,	8*MB+0x200	},
-	{5000000,	128,	8*MB+0x204	},
-	{5000000,	128,	8*MB+0x2b4	},
-	{0}};
-
-/*
- * Array of virtual addresses available for test purposes.
- */
-
-typedef struct {
-	long	vstart;
-	long	vend;
-	long	nextaddr;
-	int	wrapcount;
-} memmap_t;
-
-memmap_t 	memmap[MAXCHUNKS];
-int		memmapx=0;
-
-typedef struct {
-	void	*addr;
-	long	data[16];
-	long	data_fc[16];
-} capture_line_t;
-
-typedef struct {
-	int	size;
-	void	*blockaddr;
-	void	*shadaddr;
-	long	blockdata[16];
-	long	shaddata[16];
-	long	blockdata_fc[16];
-	long	shaddata_fc[16];
-	long	synerr;
-} capture_t;
-
-/*
- * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and
- * the rest of the tables have to start at 1MB to skip PROM tables.
- */
-#define THREADPRIVATE(t)	((threadprivate_t*)(((long)mbase)+1024*1024+t*((sizeof(threadprivate_t)+511)/512*512)))
-
-#define k_capture		mbase->sk_capture
-#define k_go			mbase->sk_go
-#define k_linecount		mbase->sk_linecount
-#define k_passes		mbase->sk_passes
-#define k_napticks		mbase->sk_napticks
-#define k_stop_on_error		mbase->sk_stop_on_error
-#define k_verbose		mbase->sk_verbose
-#define k_threadprivate		mbase->sk_threadprivate
-#define k_blocks		mbase->sk_blocks
-#define k_iter_msg		mbase->sk_iter_msg
-#define k_vv			mbase->sk_vv
-#define k_linepad		mbase->sk_linepad
-#define k_options		mbase->sk_options
-#define k_testnumber		mbase->sk_testnumber
-#define k_currentpass		mbase->sk_currentpass
-
-static long		blocks[MAX_LINECOUNT];		/* addresses of data blocks */
-static control_t	*mbase;
-static vint		initialized=0;
-
-static unsigned int ran_conf_llsc(int);
-static int  rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int);
-static void dumpline(void *, char *, char *, void *, void *, int);
-static int  checkstop(int, int, uint);
-static void spin(int);
-static void capturedata(capture_t *, uint, void *, void *, int);
-static int  randn(uint max, uint *seed);
-static uint zrandom (uint *zranseed);
-static int  set_lock(uint *, uint);
-static int  clr_lock(uint *, uint);
-static void Speedo(void);
-
-int autotest_enabled=0;
-static int llsctest_number=-1;
-static int errstop_enabled=0;
-static int fail_enabled=0;
-static int selective_trigger=0;
-static int dump_block_addrs_opt=0;
-static uint errlock=0;
-
-static int __init autotest_enable(char *str)
-{
-        autotest_enabled = 1;
-	return 1;
-}
-static int __init set_llscblkadr(char *str)
-{
-	dump_block_addrs_opt = 1;
-	return 1;
-}
-static int __init set_llscselt(char *str)
-{
-	selective_trigger = 1;
-	return 1;
-}
-static int __init set_llsctest(char *str)
-{
-        llsctest_number = simple_strtol(str, &str, 10);
-	if (llsctest_number < 0 || llsctest_number > 15)
-		llsctest_number = -1;
-	return 1;
-}
-static int __init set_llscerrstop(char *str)
-{
-        errstop_enabled = 1;
-	return 1;
-}
-static int __init set_llscfail(char *str)
-{
-        fail_enabled = 8;
-	return 1;
-}
-
-static void print_params(void)
-{
-	printk ("********* Enter AUTOTEST facility on master cpu *************\n");
-	printk ("  Test options:\n");
-	printk ("     llsctest=<n>\t%d\tTest number to run (all = -1)\n", llsctest_number);
-	printk ("     llscerrstop \t%s\tStop on error\n", errstop_enabled ? "on" : "off");
-	printk ("     llscfail    \t%s\tForce a failure to test the trigger & error messages\n", fail_enabled ? "on" : "off");
-	printk ("     llscselt    \t%s\tSelective triger on failures\n", selective_trigger ? "on" : "off");
-	printk ("     llscblkadr  \t%s\tDump data block addresses\n", dump_block_addrs_opt ? "on" : "off");
-	printk ("\n");
-}
-__setup("autotest", autotest_enable);
-__setup("llsctest=", set_llsctest);
-__setup("llscerrstop", set_llscerrstop);
-__setup("llscfail", set_llscfail);
-__setup("llscselt", set_llscselt);
-__setup("llscblkadr", set_llscblkadr);
-
-
-extern inline int
-set_lock(uint *lock, uint id)
-{
-	uint	old;
-	old = cmpxchg_acq(lock, 0, id);
-	return (old == 0);
-}
-
-extern inline int
-clr_lock(uint *lock, uint id)
-{
-	uint	old;
-	old = cmpxchg_rel(lock, id, 0);
-	return (old == id);
-}
-
-extern inline void
-zero_lock(uint *lock)
-{
-	*lock = 0;
-}
-
-/*------------------------------------------------------------------------+
-| Routine  :  ran_conf_llsc - ll/sc shared data test                      |
-| Description: This test checks the coherency of shared data              |
-+------------------------------------------------------------------------*/
-static unsigned int
-ran_conf_llsc(int thread)
-{
-	private_t	pval;
-	share_t		sval, sval2;
-	uint		vv, linei, slinei, sharei, pass;
-	long		t;
-	lock_t		lockpat;
-	share_t		*sharecopy;
-	long		verbose, napticks, passes, linecount, lcount;
-	dataline_t	*linep, *slinep;
-	int		s, seed;
-	threadprivate_t	*tp;
-	uint		iter_msg, iter_msg_i=0;
-	int		vv_mask;
-	int		correct_errors;
-	int		errs=0;
-	int		stillbad;
-	capture_t	capdata;
-	private_t	*privp;
-	share_t		*sharep;
-
-
-	linecount = k_linecount;
-	napticks = k_napticks;
-	verbose = k_verbose;
-	passes = k_passes;
-	iter_msg = k_iter_msg;
-	seed = (thread + 1) * 647;
-	tp = THREADPRIVATE(thread);
-	vv_mask = (k_vv>>((thread%16)*4)) & 0xf;
-	correct_errors = k_options&0xff;
-
-	memset (&tp->private, 0, sizeof(tp->private));
-	memset (&capdata, 0, sizeof(capdata));
-
-	for (pass = 1; passes == 0 || pass < passes; pass++) {
-		lockpat = (pass & 0x0fffffff) + (thread <<28);
-		tp->threadpasses = pass;
-		if (checkstop(thread, pass, lockpat))
-			return 0;
-		iter_msg_i++;
-		if (iter_msg && iter_msg_i > iter_msg) {
-			printk("Thread %d, Pass %d\n", thread, pass);
-			iter_msg_i = 0;
-		}
-		lcount = 0;
-
-		/*
-		 * Select line to perform operations on.
-		 */
-		linei = randn(linecount, &seed);
-		sharei = randn(2, &seed);
-		slinei = (linei + (linecount/2))%linecount;		/* I dont like this - fix later */
-
-		linep = (dataline_t *)blocks[linei];
-		slinep = (dataline_t *)blocks[slinei];
-		if (sharei == 0)
-			sharecopy = &slinep->share0;
-		else
-			sharecopy = &slinep->share1;
-
-
-		vv = randn(4, &seed);
-		if ((vv_mask & (1<<vv)) == 0)
-			continue;
-
-		if (napticks) {
-			t = randn(napticks, &seed);
-			udelay(t);
-		}
-		privp = &linep->private[thread];
-		sharep = &linep->share[sharei];
-		
-		switch(vv) {
-		case 0:
-			/* Read and verify private count on line. */
-			pval = *privp;
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
-			if (pval != tp->private[linei]) {
-				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
-				stillbad = (*privp != tp->private[linei]);
-				if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
-					return 1;
-				}
-				if (correct_errors) {
-					tp->private[linei] = *privp;
-				}
-				errs++;
-			}
-			break;
-
-		case 1:
-			/* Read, verify, and increment private count on line. */
-			pval = *privp;
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
-			if (pval != tp->private[linei]) {
-				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
-				stillbad = (*privp != tp->private[linei]);
-				if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
-					return 1;
-				}
-				errs++;
-			}
-			pval++;
-			*privp = pval;
-			tp->private[linei] = pval;
-			break;
-
-		case 2:
-			/* Lock line, read and verify shared data. */
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
-			lcount = 0;
-			while (LOCK(sharei) != 1) {
-				if (checkstop(thread, pass, lockpat))
-					return 0;
-				if (lcount++>1000000) {
-					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
-					stillbad = (GETLOCK(sharei) != 0);
-					rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
-					return 1;
-				}
-				if ((lcount&0x3fff) == 0)
-					udelay(1000);
-			}
-
-			sval = *sharep;
-			sval2 = *sharecopy;
-			if (pass > 12 && thread == 0 && fail_enabled == 1)
-				sval++;
-			if (sval != sval2) {
-				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
-				stillbad = (*sharep != *sharecopy);
-				if (!stillbad && *sharep != sval && *sharecopy == sval2)
-					stillbad = 2;
-				if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
-					return 1;
-				}
-				if (correct_errors)
-					*sharep = *sharecopy;
-				errs++;
-			}
-
-
-			if ( (s=UNLOCK(sharei)) != 1) {
-				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
-				stillbad = (GETLOCK(sharei) != lockpat);
-				if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad))
-					return 1;
-				if (correct_errors)
-					ZEROLOCK(sharei);	
-				errs++;
-			}
-			break;
-
-		case 3:
-			/* Lock line, read and verify shared data, modify shared data. */
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
-			lcount = 0;
-			while (LOCK(sharei) != 1) {
-				if (checkstop(thread, pass, lockpat))
-					return 0;
-				if (lcount++>1000000) {
-					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
-					stillbad = (GETLOCK(sharei) != 0);
-					rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
-					return 1;
-				}
-				if ((lcount&0x3fff) == 0)
-					udelay(1000);
-			}
-			sval = *sharep;
-			sval2 = *sharecopy;
-			if (sval != sval2) {
-				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
-				stillbad = (*sharep != *sharecopy);
-				if (!stillbad && *sharep != sval && *sharecopy == sval2)
-					stillbad = 2;
-				if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
-					return 1;
-				}
-				errs++;
-			}
-
-			*sharep = lockpat;
-			*sharecopy = lockpat;
-
-
-			if ( (s=UNLOCK(sharei)) != 1) {
-				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
-				stillbad = (GETLOCK(sharei) != lockpat);
-				if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad))
-					return 1;
-				if (correct_errors)
-					ZEROLOCK(sharei);	
-				errs++;
-			}
-			break;
-		}
-	}
-
-	return (errs > 0);
-}
-
-static void
-trigger_la(long val)
-{
-	long	*p;
-
-	p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */
-	*p = val;
-}
-
-static long
-getsynerr(void)
-{
-	long	err, *errp;
-
-	errp = (long*)0xc0000e0000000340L;	/* SYN_ERR */
-	err = *errp;
-	if (err)
-		*errp = -1L;
-	return (err & ~0x60);
-}
-
-static int
-rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int linei, int exp, int found, int stillbad)
-{
-	int		cpu, i;
-	long 		synerr;
-	int		selt;
-
-
-	selt = selective_trigger && stillbad > 1 && 
-			memcmp(cap->blockdata, cap->blockdata_fc, 128) != 0 &&
-			memcmp(cap->shaddata, cap->shaddata_fc, 128) == 0;
-	if (selt) {
-		trigger_la(pass);
-	} else if (selective_trigger) {
-		k_go = ST_STOP;
-		return k_stop_on_error;;
-	}
-
-	spin(1);
-	i = 100;
-	while (i && set_lock(&errlock, 1) != 1) {
-		spin(1);
-		i--;
-	}
-	printk ("\nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%x\n",
-	    msg, k_testnumber, thread, linei, pass, pass, jiffies, exp, found);
-
-	dumpline (lp, "Corrupted data", "D ", cap->blockaddr, cap->blockdata, cap->size);
-	if (memcmp(cap->blockdata, cap->blockdata_fc, 128))
-		dumpline (lp, "Corrupted data", "DF", cap->blockaddr, cap->blockdata_fc, cap->size);
-
-	if (cap->shadaddr) {
-		dumpline (slp, "Shadow    data", "S ", cap->shadaddr, cap->shaddata, cap->size);
-		if (memcmp(cap->shaddata, cap->shaddata_fc, 128))
-			dumpline (slp, "Shadow    data", "SF", cap->shadaddr, cap->shaddata_fc, cap->size);
-	}
-	
-	printk("Threadpasses: ");
-	for (cpu=0; cpu<MAXCPUS; cpu++)
-		if (k_threadprivate[cpu]->threadpasses)
-			printk("  %d:0x%x", cpu, k_threadprivate[cpu]->threadpasses);
-
-
-	printk("\nData was %sfixed by flushcache\n", (stillbad == 1 ? "**** NOT **** " : " "));
-	synerr = getsynerr();
-	if (synerr)
-		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
-	spin(2);
-	printk("\n\n");
-	clr_lock(&errlock, 1);
-
-	if (errstop_enabled) {
-		local_irq_disable();
-		while(1);
-	}
-	return k_stop_on_error;
-}
-
-
-static void
-dumpline(void *lp, char *str1, char *str2, void *addr, void *data, int size)
-{
-	long *p;
-	int i, off;
-
-	printk("%s at 0x%lx, size %d, block starts at 0x%lx\n", str1, (long)addr, size, (long)lp);
-	p = (long*) data;
-	for (i=0; i<16; i++, p++) {
-		if (i==0) printk("%2s", str2);
-		if (i==8) printk("  ");
-		printk(" %016lx", *p);
-		if ((i&7)==7) printk("\n");
-	}
-	printk("   ");
-	off = (((long)addr) ^ size) & 63L;
-	for (i=0; i<off+size; i++) {
-		printk("%s", (i>=off) ? "--" : "  ");
-		if ((i%8) == 7)
-			printk(" ");
-	}
-
-	off = ((long)addr) & 127;
-	printk(" (line %d)\n", off/64+1);
-}
-
-
-static int
-randn(uint max, uint *seedp)
-{
-	if (max == 1)
-		return(0);
-	else
-		return((int)(zrandom(seedp)>>10) % max);
-}
-
-
-static int
-checkstop(int thread, int pass, uint lockpat)
-{
-	long	synerr;
-
-	if (k_go == ST_RUN)
-		return 0;
-	if (k_go == ST_STOP)
-		return 1;
-
-	if (errstop_enabled) {
-		local_irq_disable();
-		while(1);
-	}
-	synerr = getsynerr();
-	spin(2);
-	if (k_go == ST_STOP)
-		return 1;
-	if (synerr)
-		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
-	return 1;
-}
-
-
-static void
-spin(int j)
-{
-	udelay(j * 500000);
-}
-
-static void
-capturedata(capture_t *cap, uint pass, void *blockaddr, void *shadaddr, int size)
-{
-
-	if (!selective_trigger)
-		trigger_la (pass);
-
-	memcpy (cap->blockdata, CACHEALIGN(blockaddr), 128);
-	if (shadaddr) 
-		memcpy (cap->shaddata, CACHEALIGN(shadaddr), 128);
-
-	if (k_stop_on_error) {
-		k_go = ST_ERRSTOP;
-	}
-
- 	cap->size = size;
-	cap->blockaddr = blockaddr;
-	cap->shadaddr = shadaddr;
-
-	asm volatile ("fc %0" :: "r"(blockaddr) : "memory");
-	ia64_sync_i();
-	ia64_srlz_d();
-	memcpy (cap->blockdata_fc, CACHEALIGN(blockaddr), 128);
-
-	if (shadaddr) {
-		asm volatile ("fc %0" :: "r"(shadaddr) : "memory");
-		ia64_sync_i();
-		ia64_srlz_d();
-		memcpy (cap->shaddata_fc, CACHEALIGN(shadaddr), 128);
-	}
-}
-
-int             zranmult = 0x48c27395;
-
-static uint  
-zrandom (uint *seedp)
-{
-        *seedp = (*seedp * zranmult) & 0x7fffffff;
-        return (*seedp);
-}
-
-
-void
-set_autotest_params(void)
-{
-	static int	testnumber=-1;
-
-	if (llsctest_number >= 0) {
-		testnumber = llsctest_number;
-	} else {
-		testnumber++;
-		if (autotest_table[testnumber].passes == 0) {
-			testnumber = 0;
-			dump_block_addrs_opt = 0;
-		}
-	}
-	k_passes = autotest_table[testnumber].passes;
-	k_linepad = autotest_table[testnumber].linepad;
-	k_linecount = autotest_table[testnumber].linecount;
-	k_testnumber = testnumber;
-
-	if (IS_RUNNING_ON_SIMULATOR()) {
-		printk ("llsc start test %ld\n", k_testnumber);
-		k_passes = 1000;
-	}
-}
-
-
-static void
-set_leds(int errs)
-{
-	unsigned char	leds=0;
-
-	/*
-	 * Leds are:
-	 * 	ppppeee-  
-	 *   where
-	 *      pppp = test number
-	 *       eee = error count but top bit is stick
-	 */
-
-	leds =  ((errs&7)<<1) | ((k_testnumber&15)<<4) | (errs ? 0x08 : 0);
-	bringup_set_led_bits(leds, 0xfe);
-}
-
-static void
-setup_block_addresses(void)
-{
-	int		i, stride, memmapi;
-
-	stride = LINESTRIDE;
-	memmapi = 0;
-	for (i=0; i<memmapx; i++) {
-		memmap[i].nextaddr = memmap[i].vstart;
-		memmap[i].wrapcount = 0;
-	}
-
-	for (i=0; i<k_linecount; i++) {
-		blocks[i] = memmap[memmapi].nextaddr;
-		memmap[memmapi].nextaddr += stride;
-		if (memmap[memmapi].nextaddr + sizeof(dataline_t) >= memmap[memmapi].vend) {
-			memmap[memmapi].wrapcount++;
-			memmap[memmapi].nextaddr = memmap[memmapi].vstart + 
-					memmap[memmapi].wrapcount * sizeof(dataline_t);
-		}
-
-		memset((void*)blocks[i], 0, sizeof(dataline_t));
-
-		if (stride > 16384) {
-			memmapi++;
-			if (memmapi == memmapx)
-				memmapi = 0;
-		}
-	}
-
-}
-
-static void
-dump_block_addrs(void)
-{
-	int	i;
-
-	printk("LLSC TestNumber %ld\n", k_testnumber);
-
-	for (i=0; i<k_linecount; i++) {
-		printk("  %lx", blocks[i]);
-		if (i%4 == 3)
-			printk("\n");
-	}
-	printk("\n");
-}
-
-
-static void
-set_thread_state(int cpuid, int state)
-{
-	if (k_threadprivate[cpuid]->threadstate == TS_KILLED) {
-		bringup_set_led_bits(0xfe, 0xfe);
-		while(1);
-	}
-	k_threadprivate[cpuid]->threadstate = state;
-}
-
-static int
-build_mem_map(unsigned long start, unsigned long end, void *arg)
-{
-	long	lstart;
-	long	align = 8*MB;
-	/*
-	 * HACK - skip the kernel on the first node 
-	 */
-
-	printk ("LLSC memmap: start 0x%lx, end 0x%lx, (0x%lx - 0x%lx)\n", 
-		start, end, (long) virt_to_page(start), (long) virt_to_page(end-PAGE_SIZE));
-
-	while (end > start && (PageReserved(virt_to_page(end-PAGE_SIZE)) || virt_to_page(end-PAGE_SIZE)->count.counter > 0))
-		end -= PAGE_SIZE;
-
-	lstart = end;
-	while (lstart > start && (!PageReserved(virt_to_page(lstart-PAGE_SIZE)) && virt_to_page(lstart-PAGE_SIZE)->count.counter == 0))
-		lstart -= PAGE_SIZE;
-
-	lstart = (lstart + align -1) /align * align;
-	end = end / align * align;
-	if (lstart >= end)
-		return 0;
-	printk ("     memmap: start 0x%lx, end 0x%lx\n", lstart, end);
-
-	memmap[memmapx].vstart = lstart;
-	memmap[memmapx].vend = end;
-	memmapx++;
-	return 0;
-}
-
-void int_test(void);
-
-int
-llsc_main (int cpuid, long mbasex)
-{
-	int		i, cpu, is_master, repeatcnt=0;
-	unsigned int	preverr=0, errs=0, pass=0;
-	int		automode=0;
-
-#ifdef INTTEST
-	if (inttest)
-		int_test();
-#endif
-
-	if (!autotest_enabled)
-		return 0;
-
-#ifdef CONFIG_SMP
-	is_master = !smp_processor_id();
-#else
-	is_master = 1;
-#endif
-
-
-	if (is_master) {
-		print_params();
-		if(!IS_RUNNING_ON_SIMULATOR())
-			spin(10);
-		mbase = (control_t*)mbasex;
-		k_currentpass = 0;
-		k_go = ST_IDLE;
-		k_passes = DEF_PASSES;
-		k_napticks = DEF_NAPTICKS;
-		k_stop_on_error = DEF_STOP_ON_ERROR;
-		k_verbose = DEF_VERBOSE;
-		k_linecount = DEF_LINECOUNT;
-		k_iter_msg = DEF_ITER_MSG;
-		k_vv = DEF_VV;
-		k_linepad = DEF_LINEPAD;
-		k_blocks = (void*)blocks;
-		efi_memmap_walk(build_mem_map, 0);
-	
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-		automode = 1;
-#endif
-
-		for (i=0; i<MAXCPUS; i++) {
-			k_threadprivate[i] = THREADPRIVATE(i);
-			memset(k_threadprivate[i], 0, sizeof(*k_threadprivate[i]));
-		}
-		initialized = 1;
-	} else {
-		while (initialized == 0)
-			udelay(100);
-	}
-
-loop:
-	if (is_master) {
-		if (automode) {
-			if (!preverr || repeatcnt++ > 5) {
-				set_autotest_params();
-				repeatcnt = 0;
-			}
-		} else {
-			while (k_go == ST_IDLE);
-		}
-
-		k_go = ST_INIT;
-		if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT;
-		k_linecount = k_linecount & ~1;
-		setup_block_addresses();
-		if (dump_block_addrs_opt)
-			dump_block_addrs();
-
-		k_currentpass = pass++;
-		k_go = ST_RUN;
-		if (fail_enabled)
-			fail_enabled--;
-
-	} else {
-		while (k_go != ST_RUN || k_currentpass != pass);
-		pass++;
-	}
-
-
-	set_leds(errs);
-	set_thread_state(cpuid, TS_RUNNING);
-
-	errs += ran_conf_llsc(cpuid);
-	preverr = (k_go == ST_ERRSTOP);
-
-	set_leds(errs);
-	set_thread_state(cpuid, TS_STOPPED);
-
-	if (is_master) {
-		Speedo();
-		for (i=0, cpu=0; cpu<MAXCPUS; cpu++) {
-			while (k_threadprivate[cpu]->threadstate == TS_RUNNING) {
-				i++;
-				if (i == 10000) { 
-					k_go = ST_STOP;
-					printk ("  llsc master stopping test number %ld\n", k_testnumber);
-				}
-				if (i > 100000) {
-					k_threadprivate[cpu]->threadstate = TS_KILLED;
-					printk ("  llsc: master killing cpuid %d, running test number %ld\n", 
-							cpu, k_testnumber);
-				}
-				udelay(1000);
-			}
-		}
-	}
-
-	goto loop;
-}
-
-
-static void
-Speedo(void)
-{
-	static int i = 0;
-
-	switch (++i%4) {
-	case 0:
-		printk("|\b");
-		break;
-	case 1:
-		printk("\\\b");
-		break;
-	case 2:
-		printk("-\b");
-		break;
-	case 3:
-		printk("/\b");
-		break;
-	}
-}
-
-#ifdef INTTEST
-
-/* ======================================================================================================== 
- *
- * Some test code to verify that interrupts work
- *
- * Add the following to the arch/ia64/kernel/smp.c after the comment "Reschedule callback"
- * 		if (zzzprint_resched) printk("  cpu %d got interrupt\n", smp_processor_id());
- *
- * Enable the code in arch/ia64/sn/sn1/smp.c to print sending IPIs.
- *
- */
-
-static int __init set_inttest(char *str)
-{
-        inttest = 1;
-	autotest_enabled = 1;
-
-	return 1;
-}	
-
-__setup("inttest=", set_inttest);
-
-int	zzzprint_resched=0;
-
-void
-int_test() {
-	int			mycpu, cpu;
-	static volatile int	control_cpu=0;
-
-	mycpu = smp_processor_id();
-	zzzprint_resched = 2;
-
-	printk("Testing cross interrupts\n");
-	
-	while (control_cpu != smp_num_cpus) {
-		if (mycpu == cpu_logical_map(control_cpu)) {
-			for (cpu=0; cpu<smp_num_cpus; cpu++) {
-				printk("Sending interrupt from %d to %d\n", mycpu, cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-				smp_send_reschedule(cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-				smp_send_reschedule(cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-			}
-			control_cpu++;
-		}
-	}
-
-	zzzprint_resched = 1;
-
-	if (mycpu == cpu_logical_map(smp_num_cpus-1)) {
-		printk("\nTight loop of cpu %d sending ints to cpu 0 (every 100 us)\n", mycpu);
-		udelay(IS_RUNNING_ON_SIMULATOR ? 1000 : 1000000);
-		__cli();
-		while (1) {
-			smp_send_reschedule(0);
-			udelay(100);
-		}
-
-	}
-
-	while(1);
-}
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/llsc4.h linux/arch/ia64/sn/sn1/llsc4.h
--- linux.orig/arch/ia64/sn/sn1/llsc4.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/arch/ia64/sn/sn1/llsc4.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,104 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
- */
-
-#ifdef STANDALONE
-#include "lock.h"
-#endif
-
-
-#define DEF_NAPTICKS		0
-#define DEF_PASSES		0
-#define DEF_AUTO_PASSES		1000000
-#define DEF_STOP_ON_ERROR	1
-#define DEF_VERBOSE		0
-#define DEF_LINECOUNT		2
-#define DEF_ITER_MSG		0
-#define DEF_VV			0xffffffff
-#define DEF_LINEPAD		0x234
-
-
-
-#define MAXCPUS			16
-#define CACHELINE		64
-#define MAX_LINECOUNT		1024
-#define K			1024
-#define	MB			(K*K)
-
-
-#define	uint 		unsigned int
-#define	ushort		unsigned short
-#define vint		volatile int
-#define vlong		volatile long
-
-#define LOCKADDR(i)	&linep->lock[(i)]
-#define LOCK(i)		set_lock(LOCKADDR(i), lockpat)
-#define UNLOCK(i)	clr_lock(LOCKADDR(i), lockpat)
-#define GETLOCK(i)	*LOCKADDR(i)
-#define ZEROLOCK(i)	zero_lock(LOCKADDR(i))
-
-#define CACHEALIGN(a)	((void*)((long)(a) & ~127L))
-
-typedef uint		lock_t;
-typedef uint		share_t;
-typedef uint		private_t;
-
-typedef struct {
-	lock_t		lock[2];
-	share_t		share[2];
-	private_t	private[MAXCPUS];
-	share_t		share0;
-	share_t		share1;
-} dataline_t ;
-
-
-#define LINEPAD			k_linepad
-#define LINESTRIDE		(((sizeof(dataline_t)+CACHELINE-1)/CACHELINE)*CACHELINE + LINEPAD)
-
-
-typedef struct {
-	vint		threadstate;
-	uint		threadpasses;
-	private_t	private[MAX_LINECOUNT];
-} threadprivate_t;
-
-typedef struct {
-	vlong		sk_go;		/* 0=idle, 1=init, 2=run */
-	long		sk_linecount;
-	long		sk_passes;
-	long		sk_napticks;
-	long		sk_stop_on_error;
-	long		sk_verbose;
-	long		sk_iter_msg;
-	long		sk_vv;
-	long		sk_linepad;
-	long		sk_options;
-	long		sk_testnumber;
-	vlong		sk_currentpass;
-	void 		*sk_blocks;
-	threadprivate_t	*sk_threadprivate[MAXCPUS];
-} control_t;
-
-/* Run state (k_go) constants */
-#define ST_IDLE		0
-#define ST_INIT		1
-#define ST_RUN		2
-#define ST_STOP		3
-#define ST_ERRSTOP	4
-
-
-/* Threadstate constants */
-#define TS_STOPPED	0
-#define	TS_RUNNING	1
-#define TS_KILLED	2
-
-
-
-int llsc_main (int cpuid, long mbasex);
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/machvec.c linux/arch/ia64/sn/sn1/machvec.c
--- linux.orig/arch/ia64/sn/sn1/machvec.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/machvec.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,18 +0,0 @@
-#define MACHVEC_PLATFORM_NAME	sn1
-#include <asm/machvec_init.h>
-#include <asm/io.h>
-#include <linux/pci.h>
-void*
-sn1_mk_io_addr_MACRO
-
-dma_addr_t
-sn1_pci_map_single_MACRO
-
-int
-sn1_pci_map_sg_MACRO
-
-unsigned long
-sn1_virt_to_phys_MACRO
-
-void *
-sn1_phys_to_virt_MACRO
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/mm.c linux/arch/ia64/sn/sn1/mm.c
--- linux.orig/arch/ia64/sn/sn1/mm.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/mm.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,394 +0,0 @@
-/*
- * Copyright, 2000-2001, Silicon Graphics.
- * Copyright Srinivasa Thirumalachar (sprasad@engr.sgi.com)
- * Copyright 2000-2001 Kanoj Sarcar (kanoj@sgi.com)
- */
-
-#include <linux/config.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <asm/page.h>
-#include <asm/efi.h>
-#include <asm/sn/mmzone_sn1.h>
-
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-#define MAX(a,b)	((a) > (b) ? (a) : (b))
-
-#define DONE_NOTHING	0
-#define DONE_FINDING	1
-#define DONE_BUILDING	2
-
-struct nodemem_s {
-        u64     start;	/* start of kernel usable memory */
-        u64     end;	/* end of kernel usable memory */
-	u64	mtot;	/* total kernel usable memory */
-	u64	done;	/* state of bootmem initialization */
-	u64	bstart;	/* where should the bootmem area be */
-	u64	bsize;	/* bootmap size */
-        u64 	hole[SN1_MAX_BANK_PER_NODE];
-} nodemem[MAXNODES];
-
-static int nodemem_valid = 0;
-
-static int __init
-free_unused_memmap_hole(int nid, unsigned long start, unsigned long end)
-{
-        struct page * page, *pageend;
-        unsigned long count = 0;
-
-	if (start >= end)
-		return 0;
-
-	/*
-	 * Get the memmap ptrs to the start and end of the holes.
-	 * virt_to_page(start) will panic, if start is in hole.
-	 * Can we do virt_to_page(end), if end is on the next node?
-	 */
-
-	page = virt_to_page(start - 1);
-	page++;
-	pageend = virt_to_page(end);
-
-	printk("hpage=0x%lx, hpageend=0x%lx\n", (u64)page, (u64)pageend) ;
-	free_bootmem_node(NODE_DATA(nid), __pa(page), (u64)pageend - (u64)page);
-
-	return count;
-}
-
-static void __init
-free_unused_memmap_node(int nid)
-{
-	u64	i = 0;
-	u64	holestart = -1;
-	u64	start = nodemem[nid].start;
-
-	start = ((start >> SN1_NODE_ADDR_SHIFT) << SN1_NODE_ADDR_SHIFT);
-	do {
-		holestart = nodemem[nid].hole[i];
-		i++;
-		while ((i < SN1_MAX_BANK_PER_NODE) && 
-					(nodemem[nid].hole[i] == (u64)-1))
-			i++;
-		if (i < SN1_MAX_BANK_PER_NODE)
-			free_unused_memmap_hole(nid, holestart, 
-				start + (i<<SN1_BANK_ADDR_SHIFT));
-	} while (i<SN1_MAX_BANK_PER_NODE);
-}
-
-/*
- * Since efi_memmap_walk merges contiguous banks, this code will need
- * to find all the nasid/banks covered by the input memory descriptor.
- */
-static int __init
-build_nodemem_map(unsigned long start, unsigned long end, void *arg)
-{
-	unsigned long vaddr = start;
-	unsigned long nvaddr;
-	int nasid = GetNasId(__pa(vaddr));
-	int cnodeid, bankid;
-
-	while (vaddr < end) {
-		cnodeid = NASID_TO_CNODEID(nasid);
-		bankid = GetBankId(__pa(vaddr));
-		nodemem[cnodeid].start = MIN(nodemem[cnodeid].start, vaddr);
-		nvaddr = (unsigned long)__va((unsigned long)(++nasid) << 
-							SN1_NODE_ADDR_SHIFT);
-		nodemem[cnodeid].end = MAX(nodemem[cnodeid].end, MIN(end, nvaddr));
-		while ((bankid < SN1_MAX_BANK_PER_NODE) && 
-					(vaddr < nodemem[cnodeid].end)) {
-			nvaddr = nodemem[cnodeid].start + 
-			  ((unsigned long)(bankid + 1) << SN1_BANK_ADDR_SHIFT);
-			nodemem[cnodeid].hole[bankid++] = MIN(nvaddr, end);
-			vaddr = nvaddr;
-		}
-	}
-
-	return 0;
-}
-
-static int __init
-pgtbl_size_ok(int nid)
-{
-	unsigned long numpfn, bank0size, nodesize ;
-	unsigned long start = nodemem[nid].start;
-
-	start = ((start >> SN1_NODE_ADDR_SHIFT) << SN1_NODE_ADDR_SHIFT);
-	
-	nodesize 	= nodemem[nid].end - start ;
-	numpfn 		= nodesize >> PAGE_SHIFT;
-
-	bank0size 	= nodemem[nid].hole[0] - start ;
-	/* If nid == master node && no kernel text replication */
-	bank0size      -= 0xA00000 ;	/* Kernel text + stuff */
-	bank0size      -= ((numpfn + 7) >> 3);
-
-	if ((numpfn * sizeof(mem_map_t)) > bank0size) {
-		printk("nid = %d, ns=0x%lx, npfn=0x%lx, bank0size=0x%lx\n", 
-			nid, nodesize, numpfn, bank0size) ;
-		return 0 ;
-	}
-
-	return 1 ;
-}
-
-static void __init
-check_pgtbl_size(int nid)
-{
-	int	bank = SN1_MAX_BANK_PER_NODE - 1 ;
-
-	/* Find highest bank with valid memory */
-        while ((nodemem[nid].hole[bank] == -1) && (bank))
-               bank-- ;
-
-	while (!pgtbl_size_ok(nid)) {
-		/* Remove that bank of memory */
-		/* Collect some numbers later */
-		printk("Ignoring node %d bank %d\n", nid, bank) ;
-		nodemem[nid].hole[bank--] = -1 ;
-		/* Get to the next populated bank */
-		while ((nodemem[nid].hole[bank] == -1) && (bank))
-			bank-- ;
-		printk("Using only upto bank %d on node %d\n", bank,nid) ;
-		nodemem[nid].end = nodemem[nid].hole[bank] ; 
-		if (!bank) break ;
-	}
-}
-
-void dump_nodemem_map(int) ;
-
-#ifdef CONFIG_DISCONTIGMEM
-
-extern bootmem_data_t bdata[];
-
-/*
- * This assumes there will be a hole in kernel-usable memory between nodes
- * (due to prom). The memory descriptors invoked via efi_memmap_walk are 
- * in increasing order. It tries to identify first suitable free area to 
- * put the bootmem for the node in. When presented with the md holding
- * the kernel, it only searches at the end of the kernel area.
- */
-static int __init
-find_node_bootmem(unsigned long start, unsigned long end, void *arg)
-{
-	int nasid = GetNasId(__pa(start));
-	int cnodeid = NASID_TO_CNODEID(nasid);
-	unsigned long nodesize;
-	extern char _end;
-	unsigned long kaddr = (unsigned long)&_end;
-
-	/*
-	 * Track memory available to kernel.
-	 */
-	nodemem[cnodeid].mtot += ((end - start) >> PAGE_SHIFT);
-	if (nodemem[cnodeid].done != DONE_NOTHING)
-		return(0);
-	nodesize = nodemem[cnodeid].end - ((nodemem[cnodeid].start >> 
-				SN1_NODE_ADDR_SHIFT) << SN1_NODE_ADDR_SHIFT);
-	nodesize >>= PAGE_SHIFT;
-
-	/*
-	 * Adjust limits for the md holding the kernel.
-	 */
-	if ((start < kaddr) && (end > kaddr))
-		start = PAGE_ALIGN(kaddr);
-
-	/*
-	 * We need space for mem_map, bootmem map plus a few more pages
-	 * to satisfy alloc_bootmems out of node 0.
-	 */
-	if ((end - start) > ((nodesize * sizeof(struct page)) + (nodesize/8)
-						+ (10 * PAGE_SIZE))) {
-		nodemem[cnodeid].bstart = start;
-		nodemem[cnodeid].done = DONE_FINDING;
-	}
-	return(0);
-}
-
-/*
- * This assumes there will be a hole in kernel-usable memory between nodes
- * (due to prom). The memory descriptors invoked via efi_memmap_walk are 
- * in increasing order.
- */
-static int __init
-build_node_bootmem(unsigned long start, unsigned long end, void *arg)
-{
-	int nasid = GetNasId(__pa(start));
-	int curnodeid = NASID_TO_CNODEID(nasid);
-	int i;
-	unsigned long pstart, pend;
-	extern char _end, _stext;
-	unsigned long kaddr = (unsigned long)&_end;
-
-	if (nodemem[curnodeid].done == DONE_FINDING) {
-		/*
-		 * This is where we come to know the node is present.
-		 * Do node wide tasks.
-		 */
-		nodemem[curnodeid].done = DONE_BUILDING;
-		NODE_DATA(curnodeid)->bdata = &(bdata[curnodeid]);
-
-		/*
-	 	 * Update the chunktonid array as a node wide task. There
-		 * are too many smalls mds on first node to do this per md.
-	 	 */
-		pstart = __pa(nodemem[curnodeid].start);
-		pend = __pa(nodemem[curnodeid].end);
-		pstart &= CHUNKMASK;
-		pend = (pend + CHUNKSZ - 1) & CHUNKMASK;
-		/* Possible check point to enforce minimum node size */
-		if (nodemem[curnodeid].bstart == -1) {
-			printk("No valid bootmem area on node %d\n", curnodeid);
-			while(1);
-		}
-		for (i = PCHUNKNUM(pstart); i <= PCHUNKNUM(pend - 1); i++)
-			chunktonid[i] = curnodeid;
-		if ((CHUNKTONID(PCHUNKNUM(pend)) > MAXCHUNKS) || 
-				(PCHUNKNUM(pstart) >= PCHUNKNUM(pend))) {
-			printk("Ign 0x%lx-0x%lx, ", __pa(start), __pa(end));
-			return(0);
-		}
-
-		/*
-		 * NODE_START and NODE_SIZE determine the physical range
-		 * on the node that mem_map array needs to be set up for.
-		 */
-		NODE_START(curnodeid) = ((nodemem[curnodeid].start >> 
-				SN1_NODE_ADDR_SHIFT) << SN1_NODE_ADDR_SHIFT);
-		NODE_SIZE(curnodeid) = (nodemem[curnodeid].end - 
-							NODE_START(curnodeid));
-
-        	nodemem[curnodeid].bsize = 
-			init_bootmem_node(NODE_DATA(curnodeid),
-			(__pa(nodemem[curnodeid].bstart) >> PAGE_SHIFT),
-			(__pa((nodemem[curnodeid].start >> SN1_NODE_ADDR_SHIFT)
-			<< SN1_NODE_ADDR_SHIFT) >> PAGE_SHIFT),
-			(__pa(nodemem[curnodeid].end) >> PAGE_SHIFT));
-
-	} else if (nodemem[curnodeid].done == DONE_NOTHING) {
-		printk("build_node_bootmem: node %d weirdness\n", curnodeid);
-		while(1);		/* Paranoia */
-	}
-
-	/*
-	 * Free the entire md.
-	 */
-	free_bootmem_node(NODE_DATA(curnodeid), __pa(start), (end - start));
-
-	/*
-	 * Reclaim back the bootmap and kernel areas.
-	 */
-	if ((start <= nodemem[curnodeid].bstart) && (end >
-						nodemem[curnodeid].bstart))
-		reserve_bootmem_node(NODE_DATA(curnodeid),
-		    __pa(nodemem[curnodeid].bstart), nodemem[curnodeid].bsize);
-	if ((start <= kaddr) && (end > kaddr))
-		reserve_bootmem_node(NODE_DATA(curnodeid),
-		    __pa(&_stext), (&_end - &_stext));
-
-	return(0);
-}
-
-void __init
-setup_sn1_bootmem(int maxnodes)
-{
-        int     i;
-
-        for (i = 0; i < MAXNODES; i++) {
-                nodemem[i].start = nodemem[i].bstart = -1;
-                nodemem[i].end = nodemem[i].bsize = nodemem[i].mtot = 0;
-		nodemem[i].done = DONE_NOTHING;
-		memset(&nodemem[i].hole, -1, sizeof(nodemem[i].hole));
-        }
-        efi_memmap_walk(build_nodemem_map, 0);
-
-	nodemem_valid = 1;
-
-	/* 
-	 * After building the nodemem map, check if the node memmap
-	 * will fit in the first bank of each node. If not change
-	 * the node end addr till it fits.
- 	 */
-
-        for (i = 0; i < maxnodes; i++)
-		check_pgtbl_size(i);
-
-	dump_nodemem_map(maxnodes);
-
-	efi_memmap_walk(find_node_bootmem, 0);
-	efi_memmap_walk(build_node_bootmem, 0);
-}
-#endif
-
-void __init
-discontig_paging_init(void)
-{
-	int i;
-	unsigned long max_dma, zones_size[MAX_NR_ZONES], holes_size[MAX_NR_ZONES];
-	extern void dump_node_data(void);
-
-	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-	for (i = 0; i < numnodes; i++) {
-		unsigned long startpfn = __pa((void *)NODE_START(i)) >> PAGE_SHIFT;
-		unsigned long numpfn = NODE_SIZE(i) >> PAGE_SHIFT;
-		memset(zones_size, 0, sizeof(zones_size));
-		memset(holes_size, 0, sizeof(holes_size));
-		holes_size[ZONE_DMA] = numpfn - nodemem[i].mtot;
-
-		if ((startpfn + numpfn) < max_dma) {
-			zones_size[ZONE_DMA] = numpfn;
-		} else if (startpfn > max_dma) {
-			zones_size[ZONE_NORMAL] = numpfn;
-			panic("discontig_paging_init: %d\n", i);
-		} else {
-			zones_size[ZONE_DMA] = (max_dma - startpfn);
-			zones_size[ZONE_NORMAL] = numpfn - zones_size[ZONE_DMA];
-			panic("discontig_paging_init: %d\n", i);
-		}
-		free_area_init_node(i, NODE_DATA(i), NULL, zones_size, startpfn<<PAGE_SHIFT, holes_size);
-		free_unused_memmap_node(i);
-	}
-	dump_node_data();
-}
-
-/*
- * This used to be invoked from an SN1 specific hack in efi_memmap_walk.
- * It tries to ignore banks which the kernel is ignoring because bank 0 
- * is too small to hold the memmap entries for this bank.
- * The current SN1 efi_memmap_walk callbacks do not need this. That 
- * leaves the generic ia64 callbacks find_max_pfn, count_pages and
- * count_reserved_pages, of which the first can probably get by without
- * this, the last two probably need this, although they also can probably
- * get by. 
- */
-int
-sn1_bank_ignore(u64 start, u64 end)
-{
-	int 	nid = NASID_TO_CNODEID(GetNasId(__pa(end))) ;
-	int	bank = GetBankId(__pa(end)) ;
-
-	if (!nodemem_valid)
-		return 0 ;
-
-	if (nodemem[nid].hole[bank] == -1)
-		return 1 ;
-	else
-		return 0 ;
-}
-
-void
-dump_nodemem_map(int maxnodes)
-{
-	int	i,j;
-
-        printk("NODEMEM_S info ....\n") ;
-        printk("Node         start                end\n");
-        for (i=0;i<maxnodes;i++) {
-                printk("%d      0x%lx   0x%lx\n",
-                       i, nodemem[i].start, nodemem[i].end);
-                printk("Holes -> ") ;
-                for (j=0;j<SN1_MAX_BANK_PER_NODE;j++)
-                        printk("0x%lx ", nodemem[i].hole[j]) ;
-		printk("\n");
-        }
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/probe.c linux/arch/ia64/sn/sn1/probe.c
--- linux.orig/arch/ia64/sn/sn1/probe.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/probe.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,62 +0,0 @@
-/*
- * Platform dependent support for IO probing.
- *
- * Copyright (C) 2000   Silicon Graphics
- * Copyright (C) 2000   Jack Steiner (steiner@sgi.com)
- */
-
-#include <asm/sn/sn_sal.h>
-
-/*
- * ia64_sn_probe_io_slot
- *	This function will probe a physical address to determine if
- *	the address can be read. If reading the address causes a BUS
- *	error, an error is returned. If the probe succeeds, the contents 
- *	of the memory location is returned.
- *
- *   Calling sequence:
- *		ia64_probe_io_slot(paddr, size, data_ptr)
- *
- *   Input:
- *	paddr		Physical address to probe
- *	size		Number bytes to read (1,2,4,8)
- *	data_ptr	Address to store value read by probe
- *		          (-1 returned if probe fails)
- *
- *   Output:
- *	Status
- *		 0 - probe successful
- *		 1 - probe failed (generated MCA)
- *		 2 - Bad arg
- *		<0 - PAL error
- */
-
-
-u64
-ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr)
-{
-	struct ia64_sal_retval isrv;
-
-	SAL_CALL(isrv, SN_SAL_PROBE, paddr, size, 0, 0, 0, 0, 0);
-
-	if (data_ptr) {
-		switch (size) {
-			case 1:
-				*((u8*)data_ptr) = (u8)isrv.v0;
-				break;
-			case 2:
-				*((u16*)data_ptr) = (u16)isrv.v0;
-				break;
-			case 4:
-				*((u32*)data_ptr) = (u32)isrv.v0;
-				break;
-			case 8:
-				*((u64*)data_ptr) = (u64)isrv.v0;
-				break;
-			default:
-				isrv.status = 2;	
-		}
-	}
-
-	return isrv.status;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/setup.c linux/arch/ia64/sn/sn1/setup.c
--- linux.orig/arch/ia64/sn/sn1/setup.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,254 +0,0 @@
-/*
- *
- * Copyright (C) 1999 Silicon Graphics, Inc.
- * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/kdev_t.h>
-#include <linux/string.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/timex.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/serial.h>
-
-#include <asm/sn/mmzone_sn1.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/machvec.h>
-#include <asm/system.h>
-#include <asm/processor.h>
-#include <asm-ia64/sn/arch.h>
-#include <asm-ia64/sn/addrs.h>
-
-
-/*
- * This is the address of the RRegs in the HSpace of the global
- * master.  It is used by a hack in serial.c (serial_[in|out],
- * printk.c (early_printk), and kdb_io.c to put console output on that
- * node's Bedrock UART.  It is initialized here to 0, so that
- * early_printk won't try to access the UART before
- * master_node_bedrock_address is properly calculated.
- */
-u64 master_node_bedrock_address = 0UL;
-
-static void sn_fix_ivt_for_partitioned_system(void);
-
-
-/*
- * The format of "screen_info" is strange, and due to early i386-setup
- * code. This is just enough to make the console code think we're on a
- * VGA color display.
- */
-struct screen_info sn1_screen_info = {
-	orig_x:			 0,
-	orig_y:			 0,
-	orig_video_mode:	 3,
-	orig_video_cols:	80,
-	orig_video_ega_bx:	 3,
-	orig_video_lines:	25,
-	orig_video_isVGA:	 1,
-	orig_video_points:	16
-};
-
-/*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present.  In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator.  Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-char drive_info[4*16];
-
-unsigned long
-sn1_map_nr (unsigned long addr)
-{
-#ifdef CONFIG_DISCONTIGMEM
-	return MAP_NR_SN1(addr);
-#else
-	return MAP_NR_DENSE(addr);
-#endif
-}
-
-#if defined(BRINGUP) && defined(CONFIG_IA64_EARLY_PRINTK)
-void __init
-early_sn1_setup(void)
-{
-	master_node_bedrock_address = 
-		(u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-	printk("early_sn1_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
-}
-#endif /* BRINGUP && CONFIG_IA64_EARLY_PRINTK */
-
-void __init
-sn1_setup(char **cmdline_p)
-{
-#if defined(CONFIG_SERIAL) && !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-	struct serial_struct req;
-#endif
-
-	MAX_DMA_ADDRESS = PAGE_OFFSET + 0x10000000000UL;
-	master_node_bedrock_address = 
-		(u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-	printk("sn1_setup: setting master_node_bedrock_address to 0x%lx\n",
-		   master_node_bedrock_address);
-
-#if defined(CONFIG_SERIAL) && !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-	/*
-	 * We do early_serial_setup() to clean out the rs-table[] from the
-	 * statically compiled in version.
-	 */
-	memset(&req, 0, sizeof(struct serial_struct));
-	req.line = 0;
-	req.baud_base = 124800;
-	req.port = 0;
-	req.port_high = 0;
-	req.irq = 0;
-	req.flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST);
-	req.io_type = SERIAL_IO_MEM;
-	req.hub6 = 0;
-	req.iomem_base = (u8 *)(master_node_bedrock_address + 0x80);
-	req.iomem_reg_shift = 3;
-	req.type = 0;
-	req.xmit_fifo_size = 0;
-	req.custom_divisor = 0;
-	req.closing_wait = 0;
-	early_serial_setup(&req);
-#endif /* CONFIG_SERIAL && !CONFIG_SERIAL_SGI_L1_PROTOCOL */
-
-	ROOT_DEV = to_kdev_t(0x0301);		/* default to first IDE drive */
-	sn_fix_ivt_for_partitioned_system();
-
-#ifdef CONFIG_SMP
-	init_smp_config();
-#endif
-	screen_info = sn1_screen_info;
-}
-
-
-/* 
- * sn_fix_ivt_for_partitioned_system
- *
- * This is an ugly hack that is needed for partitioned systems.
- *
- * On a partitioned system, most partitions do NOT have a physical address 0.
- * Unfortunately, the exception handling code in ivt.S has a couple of physical
- * addresses of kernel structures hardcoded into "movl" instructions.
- * These addresses are correct on partition 0 only. On all other partitions,
- * the addresses must be changed to reference the correct address.
- *
- * This routine scans the ivt code and replaces the hardcoded addresses with 
- * the correct address.
- *
- * Note that we could have made the ivt.S code dynamically determine the correct
- * address but this would add code to performance critical pathes. This option
- * was rejected.
- */
-
-#define TEMP_mlx	4		/* template type that contains movl instruction */
-#define TEMP_mlX	5		/* template type that contains movl instruction */
-
-typedef union {				/* Instruction encoding for movl instruction */
-	struct {
-		unsigned long	qp:6;
-		unsigned long	r1:7;
-		unsigned long	imm7b:7;
-		unsigned long	vc:1;
-		unsigned long	ic:1;
-		unsigned long	imm5c:5;
-		unsigned long	imm9d:9;
-		unsigned long	i:1;
-		unsigned long	op:4;
-		unsigned long	fill:23;
-	} b;
-	unsigned long	l;
-} movl_instruction_t;
-
-#define MOVL_OPCODE	6
-#define MOVL_ARG(a,b)	(((long)a.i<<63) | ((long)b<<22) | ((long)a.ic<<21) | \
-			((long)a.imm5c<<16) | ((long)a.imm9d<<7) | ((long)a.imm7b))
-
-typedef struct {				/* Instruction bundle */
-	unsigned long template:5;
-	unsigned long ins2:41;
-	unsigned long ins1l:18;
-	unsigned long ins1u:23;
-	unsigned long ins0:41;
-} instruction_bundle_t;
-
-
-static void __init
-sn_fix_ivt_for_partitioned_system(void)
-{
-	extern int		ia64_ivt;
-	instruction_bundle_t	*p, *pend;
-	movl_instruction_t	ins0, ins1, ins2;
-	long			new_ins1, phys_offset;
-	unsigned long		val;
-
-	/*
-	 * Setup to scan the ivt code.
-	 */
-	p = (instruction_bundle_t*)&ia64_ivt;
-	pend = p + 0x8000/sizeof(instruction_bundle_t);
-	phys_offset = __pa(p) & ~0x1ffffffffUL;
-
-	/*
-	 * Hunt for movl instructions that contain the node 0 physical address 
-	 * of "SWAPPER_PGD_ADDR".  These addresses must be relocated to reference the 
-	 * actual node that the kernel is loaded on.
-	 */
-	for (; p < pend; p++) {
-		if (p->template != TEMP_mlx && p->template != TEMP_mlX)
-			continue;
-		ins0.l =  p->ins0;
-		if (ins0.b.op != MOVL_OPCODE)
-			continue;
-		ins1.l =  ((long)p->ins1u<<18) | p->ins1l;
-		ins2.l =  p->ins2;
-		val = MOVL_ARG(ins0.b, ins1.l);
-
-		/*
-		 * Test for correct address. SWAPPER_PGD_ADDR will
-		 * always be a node 0 virtual address. Note that we cant
-		 * use the __pa or __va macros here since they may contain
-		 * debug code that gets fooled here.
-		 */
-		if ((PAGE_OFFSET | val)  != SWAPPER_PGD_ADDR)
-			continue;
-
-		/*
-		 * We found an instruction that needs to be fixed. The following
-		 * inserts the NASID of the ivt into the movl instruction.
-		 */
-		new_ins1 = ins1.l | (phys_offset>>22);
-		p->ins1l = new_ins1 & 0x3ffff;
-		p->ins1u = (new_ins1>>18) & 0x7fffff;
-		ia64_fc(p);
-	}
-
-	/*
-	 * Do necessary serialization.
-	 */
-	ia64_sync_i();
-	ia64_srlz_i();
-
-}
-
-int
-IS_RUNNING_ON_SIMULATOR(void)
-{
-#ifdef CONFIG_IA64_SGI_SN1_SIM
-	long sn;
-	asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2));
-	return(sn == SNMAGIC);
-#else
-	return(0);
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/smp.c linux/arch/ia64/sn/sn1/smp.c
--- linux.orig/arch/ia64/sn/sn1/smp.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/smp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,186 +0,0 @@
-/*
- * SN1 Platform specific SMP Support
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 Jack Steiner <steiner@sgi.com>
- */
-
-
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-
-#include <asm/sn/mmzone_sn1.h>
-#include <asm/sal.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/current.h>
-#include <asm/sn/sn_cpuid.h>
-
-
-
-
-/*
- * The following structure is used to pass params thru smp_call_function
- * to other cpus for flushing TLB ranges.
- */
-typedef struct {
-	unsigned long	start;
-	unsigned long	end;
-	unsigned long	nbits;
-} ptc_params_t;
-
-
-/*
- * The following table/struct is for remembering PTC coherency domains. It
- * is also used to translate sapicid into cpuids. We dont want to start 
- * cpus unless we know their cache domain.
- */
-#ifdef PTC_NOTYET
-sn_sapicid_info_t	sn_sapicid_info[NR_CPUS];
-#endif
-
-
-
-#ifdef PTC_NOTYET
-/*
- * NOTE: This is probably not good enough, but I dont want to try to make
- * it better until I get some statistics on a running system. 
- * At a minimum, we should only send IPIs to 1 processor in each TLB domain
- * & have it issue a ptc.g on it's own FSB. Also, serialize per FSB, not 
- * globally.
- *
- * More likely, we will have to do some work to reduce the frequency of calls to
- * this routine.
- */
-
-static void
-sn1_ptc_local(void *arg)
-{
-	ptc_params_t	*params = arg;
-	unsigned long	start, end, nbits;
-
-	start = params->start;
-	end = params->end;
-	nbits = params->nbits;
-
-	do {
-		__asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
-		start += (1UL << nbits);
-	} while (start < end);
-}
-
-
-void
-sn1_ptc_global (unsigned long start, unsigned long end, unsigned long nbits)
-{
-	ptc_params_t	params;
-
-	params.start = start;
-	params.end = end;
-	params.nbits = nbits;
-
-	if (smp_call_function(sn1_ptc_local, &params, 1, 0) != 0)
-		panic("Unable to do ptc_global - timed out");
-
-	sn1_ptc_local(&params);
-}
-#endif
-
-
-
-
-void
-sn1_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
-{
-	long		*p, nasid, slice;
-	static int 	off[4] = {0x1800080, 0x1800088, 0x1a00080, 0x1a00088};
-
-	/*
-	 * ZZZ - Replace with standard macros when available.
-	 */
-	nasid = cpuid_to_nasid(cpuid);
-	slice = cpuid_to_slice(cpuid);
-	p = (long*)(0xc0000a0000000000LL | (nasid<<33) | off[slice]);
-
-#if defined(ZZZBRINGUP)
-	{
-	static int count=0;
-	if (count++ < 10) printk("ZZ sendIPI 0x%x->0x%x, vec %d, nasid 0x%lx, slice %ld, adr 0x%lx\n",
-		smp_processor_id(), cpuid, vector, nasid, slice, (long)p);
-	}
-#endif
-	mb();
-	*p = (delivery_mode << 8) | (vector & 0xff);
-	
-}
-
-
-#ifdef CONFIG_SMP
-
-#ifdef PTC_NOTYET
-static void __init
-process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain)
-{
-	ia64_sal_ptc_domain_proc_entry_t	*pe;
-	int 					i, sapicid, cpuid;
-
-	pe = __va(di->proc_list);
-	for (i=0; i<di->proc_count; i++, pe++) {
-		sapicid = id_eid_to_sapicid(pe->id, pe->eid);
-		cpuid = cpu_logical_id(sapicid);
-		sn_sapicid_info[cpuid].domain = domain;
-		sn_sapicid_info[cpuid].sapicid = sapicid;
-	}
-}
-
-
-static void __init
-process_sal_desc_ptc(ia64_sal_desc_ptc_t *ptc)
-{
-	ia64_sal_ptc_domain_info_t	*di;
-	int i;
-
-	di = __va(ptc->domain_info);
-	for (i=0; i<ptc->num_domains; i++, di++) {
-		process_sal_ptc_domain_info(di, i);	
-	}
-}
-#endif
-
-
-void __init
-init_sn1_smp_config(void)
-{
-
-	if (!ia64_ptc_domain_info)  {
-		printk("SMP: Can't find PTC domain info. Forcing UP mode\n");
-		smp_num_cpus = 1;
-		return;
-	}
-
-#ifdef PTC_NOTYET
-	memset (sn_sapicid_info, -1, sizeof(sn_sapicid_info));
-	process_sal_desc_ptc(ia64_ptc_domain_info);
-#endif
-
-}
-
-#else /* CONFIG_SMP */
-
-void __init
-init_sn1_smp_config(void)
-{
-
-#ifdef PTC_NOTYET
-	sn_sapicid_info[0].sapicid = hard_smp_processor_id();
-#endif
-}
-
-#endif /* CONFIG_SMP */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/sn1_asm.S linux/arch/ia64/sn/sn1/sn1_asm.S
--- linux.orig/arch/ia64/sn/sn1/sn1_asm.S	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/sn1_asm.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,149 +0,0 @@
-
-/*
- * Copyright (C) 2000 Silicon Graphics
- * Copyright (C) 2000 Jack Steiner (steiner@sgi.com)
- */
-
-#include <linux/config.h>
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-
-// Testing only.
-// Routine will cause MCAs
-//   zzzmsa(n)
-//      n=0 MCA via duplicate TLB dropin
-//      n=0 MCA via read of garbage address
-//
-
-#define ITIR(key, ps)           ((key<<8) | (ps<<2))
-#define TLB_PAGESIZE            28                      // Use 256MB pages for now.
-
-                        .global zzzmca
-                        .proc   zzzmca
-zzzmca:
-                        alloc   loc4       = ar.pfs,2,8,1,0;;
-                        cmp.ne  p6,p0=r32,r0;;
-                        movl    r2=0x2dead
-                        movl    r3=0x3dead
-                        movl    r15=0x15dead
-                        movl    r16=0x16dead
-                        movl    r31=0x31dead
-                        movl    loc0=0x34beef
-                        movl    loc1=0x35beef
-                        movl    loc2=0x36beef
-                        movl    loc3=0x37beef
-                        movl    out0=0x42beef
-
-                        movl    r20=0x32feed;;
-                        mov     ar32=r20
-                        movl    r20=0x36feed;;
-                        mov     ar36=r20
-                        movl    r20=0x65feed;;
-                        mov     ar65=r20
-                        movl    r20=0x66feed;;
-                        mov     ar66=r20
-
-(p6)                    br.cond.sptk    1f
-
-                        rsm      0x2000;;
-                        srlz.d;
-                        mov      r11      = 1
-                        mov      r3       = ITIR(0,TLB_PAGESIZE);;
-                        mov      cr.itir  = r3
-                        mov      r10      = 0;;
-                        itr.d    dtr[r11] = r10;;
-                        mov      r11      = 2
-
-                        itr.d    dtr[r11] = r10;;
-                        br      9f
-
-1:                      movl    r8=0xfe00000048;;
-                        ld8     r9=[r8];;
-                        mf
-                        mf.a
-                        srlz.d
-
-9:                      mov     ar.pfs=loc4
-                        br.ret.sptk     rp
-
-                        .endp   zzzmca
-
-                        .global zzzspec
-                        .proc   zzzspec
-zzzspec:
-			mov	r8=r32
-			movl	r9=0xe000000000000000
-			movl	r10=0x4000;;
-			ld8.s	r16=[r8];;
-			ld8.s	r17=[r9];;
-			add	r8=r8,r10;;
-			ld8.s	r18=[r8];;
-			add	r8=r8,r10;;
-			ld8.s	r19=[r8];;
-			add	r8=r8,r10;;
-			ld8.s	r20=[r8];;
-			mov	r8=r0
-			tnat.nz	p6,p0=r16
-			tnat.nz	p7,p0=r17
-			tnat.nz	p8,p0=r18
-			tnat.nz	p9,p0=r19
-			tnat.nz	p10,p0=r20;;
-		(p6)	dep	r8=-1,r8,0,1;;
-		(p7)	dep	r8=-1,r8,1,1;;
-		(p8)	dep	r8=-1,r8,2,1;;
-		(p9)	dep	r8=-1,r8,3,1;;
-		(p10)	dep	r8=-1,r8,4,1;;
-                        br.ret.sptk     rp
-                        .endp   zzzspec
-
-                        .global zzzspec2
-                        .proc   zzzspec2
-zzzspec2:
-			cmp.eq	p6,p7=r2,r2
-			movl	r16=0xc0000a0001000020
-			;;
-			mf
-			;;
-			ld8	r9=[r16]
-		(p6)	br.spnt	1f
-			ld8	r10=[r32]
-			;;
-		1:	mf.a
-			mf
-
-			ld8	r9=[r16];;
-			cmp.ne	p6,p7=r9,r16
-		(p6)	br.spnt	1f
-			ld8	r10=[r32]
-			;;
-		1:	mf.a
-			mf
-
-			ld8	r9=[r33];;
-			cmp.ne	p6,p7=r9,r33
-		(p6)	br.spnt	1f
-			ld8	r10=[r32]
-			;;
-		1:	mf.a
-			mf
-
-			tpa	r23=r32
-			add	r20=512,r33
-			add	r21=1024,r33;;
-			ld8	r9=[r20]
-			ld8	r10=[r21];;
-			nop.i	0
-			{ .mib
-			nop.m 0
-			cmp.ne	p6,p7=r10,r33
-		(p6)	br.spnt	1f
-			}
-			ld8	r10=[r32]
-			;;
-		1:	mf.a
-			mf
-			br.ret.sptk     rp
-
-                        .endp   zzzspec
-
-#endif
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/sn1_ksyms.c linux/arch/ia64/sn/sn1/sn1_ksyms.c
--- linux.orig/arch/ia64/sn/sn1/sn1_ksyms.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/sn1_ksyms.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,39 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 Jesse Barnes (jbarnes@sgi.com)
- */
-
-
-/*
- * Architecture-specific kernel symbols
- */
-
-#include <linux/module.h>
-
-#include <asm/machvec.h>
-
-/*
- * I/O routines
- */
-EXPORT_SYMBOL(sn1_outb);
-EXPORT_SYMBOL(sn1_outl);
-EXPORT_SYMBOL(sn1_outw);
-EXPORT_SYMBOL(sn1_inw);
-EXPORT_SYMBOL(sn1_inb);
-EXPORT_SYMBOL(sn1_inl);
-
-/*
- * other stuff (more to be added later, cleanup then)
- */
-EXPORT_SYMBOL(sn1_pci_map_sg);
-EXPORT_SYMBOL(sn1_pci_unmap_sg);
-EXPORT_SYMBOL(sn1_pci_alloc_consistent);
-EXPORT_SYMBOL(sn1_pci_free_consistent);
-EXPORT_SYMBOL(sn1_dma_address);
-
-#include <linux/mm.h>
-EXPORT_SYMBOL(alloc_pages);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/sv.c linux/arch/ia64/sn/sn1/sv.c
--- linux.orig/arch/ia64/sn/sn1/sv.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/sv.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,551 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.  All rights reserved
- *
- * This implemenation of synchronization variables is heavily based on
- * one done by Steve Lord <lord@sgi.com>
- *
- * Paul Cassella <pwc@sgi.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-
-#include <asm/semaphore.h>
-#include <asm/hardirq.h>
-#include <asm/softirq.h>
-#include <asm/current.h>
-
-#include <asm/sn/sv.h>
-
-/* Define this to have sv_test() run some simple tests.
-   kernel_thread() must behave as expected when this is called.  */
-#undef RUN_SV_TEST
-
-#define DEBUG
-
-/* Set up some macros so sv_wait(), sv_signal(), and sv_broadcast()
-   can sanity check interrupt state on architectures where we know
-   how. */
-#ifdef DEBUG
- #define SV_DEBUG_INTERRUPT_STATE
- #ifdef __mips64
-  #define SV_TEST_INTERRUPTS_ENABLED(flags) ((flags & 0x1) != 0)
-  #define SV_TEST_INTERRUPTS_DISABLED(flags) ((flags & 0x1) == 0)
-  #define SV_INTERRUPT_TEST_WORKERS 31
- #elif defined(__ia64)
-  #define SV_TEST_INTERRUPTS_ENABLED(flags) ((flags & 0x4000) != 0)
-  #define SV_TEST_INTERRUPTS_DISABLED(flags) ((flags & 0x4000) == 0)
-  #define SV_INTERRUPT_TEST_WORKERS 4 /* simulator's slow */
- #else
-  #undef  SV_DEBUG_INTERRUPT_STATE
-  #define SV_INTERRUPT_TEST_WORKERS 4 /* reasonable? default. */
- #endif /* __mips64 */
-#endif /* DEBUG */
-
-
-/* XXX FIXME hack hack hack.  Our mips64 tree is from before the
-   switch to WQ_FLAG_EXCLUSIVE, and our ia64 tree is from after it. */
-#ifdef TASK_EXCLUSIVE
-  #undef EXCLUSIVE_IN_QUEUE
-#else
-  #define EXCLUSIVE_IN_QUEUE
-  #define TASK_EXCLUSIVE 0 /* for the set_current_state() in sv_wait() */
-#endif
-
-
-static inline void sv_lock(sv_t *sv) {
-	spin_lock(&sv->sv_lock);
-}
-
-static inline void sv_unlock(sv_t *sv) {
-	spin_unlock(&sv->sv_lock);
-}
-
-/* up() is "extern inline", so we can't pass its address to sv_wait.
-   Use this function's address instead. */
-static void up_wrapper(struct semaphore *sem) {
-	up(sem);
-}
-
-/* spin_unlock() is sometimes a macro. */
-static void spin_unlock_wrapper(spinlock_t *s) {
-	spin_unlock(s);
-}
-
-/* XXX Perhaps sv_wait() should do the switch() each time and avoid
-   the extra indirection and the need for the _wrapper functions? */
-
-static inline void sv_set_mon_type(sv_t *sv, int type) {
-	switch (type) {
-	case SV_MON_SPIN:
-		sv->sv_mon_unlock_func =
-		  (sv_mon_unlock_func_t)spin_unlock_wrapper;
-		break;
-	case SV_MON_SEMA:
-		sv->sv_mon_unlock_func =
-		  (sv_mon_unlock_func_t)up_wrapper;
-		if(sv->sv_flags & SV_INTS) {
-			printk(KERN_ERR "sv_set_mon_type: The monitor lock "
-			       "cannot be shared with interrupts if it is a "
-			       "semaphore!\n");
-			BUG();
-		}
-		if(sv->sv_flags & SV_BHS) {
-			printk(KERN_ERR "sv_set_mon_type: The monitor lock "
-			       "cannot be shared with bottom-halves if it is "
-			       "a semaphore!\n");
-			BUG();
-		}
-		break;
-#if 0 
-	/*
-	 * If needed, and will need to think about interrupts.  This
-	 * may be needed, for example, if someone wants to use sv's
-	 * with something like dev_base; writers need to hold two
-	 * locks. 
-	 */
-	case SV_MON_CUSTOM: 
-		{
-		struct sv_mon_custom *c = lock;
-		sv->sv_mon_unlock_func = c->sv_mon_unlock_func;
-		sv->sv_mon_lock        = c->sv_mon_lock;
-		break;
-		}
-#endif
-		
-	default:
-		printk(KERN_ERR "sv_set_mon_type: unknown type %d (0x%x)! "
-		       "(flags 0x%x)\n", type, type, sv->sv_flags);
-		BUG();
-		break;
-	}
-	sv->sv_flags |= type;
-}
-
-static inline void sv_set_ord(sv_t *sv, int ord) {
-	if (!ord)
-		ord = SV_ORDER_DEFAULT;
-
-	if (ord != SV_ORDER_FIFO && ord != SV_ORDER_LIFO) {
-		printk(KERN_EMERG "sv_set_ord: unknown order %d (0x%x)! ",
-		       ord, ord);
-		BUG();
-	}
-
-	sv->sv_flags |= ord;
-}
-
-void sv_init(sv_t *sv, sv_mon_lock_t *lock, int flags) 
-{
-	int ord = flags & SV_ORDER_MASK;
-	int type = flags & SV_MON_MASK;
-
-	/* Copy all non-order, non-type flags */
-	sv->sv_flags = (flags & ~(SV_ORDER_MASK | SV_MON_MASK));
-
-	if((sv->sv_flags & (SV_INTS | SV_BHS)) == (SV_INTS | SV_BHS)) {
-	  printk(KERN_ERR "sv_init: do not set both SV_INTS and SV_BHS, only SV_INTS.\n");
-	  BUG();
-	}
-
-	sv_set_ord(sv, ord);
-	sv_set_mon_type(sv, type);
-
-	/* If lock is NULL, we'll get it from sv_wait_compat() (and
-           ignore it in sv_signal() and sv_broadcast()). */
-	sv->sv_mon_lock = lock;
-
-	spin_lock_init(&sv->sv_lock);
-	init_waitqueue_head(&sv->sv_waiters);
-}
-
-/*
- * The associated lock must be locked on entry.  It is unlocked on return.
- *
- * Return values:
- *
- * n < 0 : interrupted,  -n jiffies remaining on timeout, or -1 if timeout == 0
- * n = 0 : timeout expired
- * n > 0 : sv_signal()'d, n jiffies remaining on timeout, or 1 if timeout == 0
- */
-signed long sv_wait(sv_t *sv, int sv_wait_flags, unsigned long timeout) 
-{
-	DECLARE_WAITQUEUE( wait, current );
-	unsigned long flags;
-	signed long ret = 0;
-
-#ifdef SV_DEBUG_INTERRUPT_STATE
-	{
-	unsigned long flags;
-	__save_flags(flags);
-
-	if(sv->sv_flags & SV_INTS) {
-		if(SV_TEST_INTERRUPTS_ENABLED(flags)) {
-			printk(KERN_ERR "sv_wait: SV_INTS and interrupts "
-			       "enabled (flags: 0x%lx)\n", flags);
-			BUG();
-		}
-	} else {
-		if (SV_TEST_INTERRUPTS_DISABLED(flags)) {
-			printk(KERN_WARNING "sv_wait: !SV_INTS and interrupts "
-			       "disabled! (flags: 0x%lx)\n", flags);
-		}
-	}
-	}
-#endif  /* SV_DEBUG_INTERRUPT_STATE */
-
-	sv_lock(sv);
-
-	sv->sv_mon_unlock_func(sv->sv_mon_lock);
-
-	/* Add ourselves to the wait queue and set the state before
-	 * releasing the sv_lock so as to avoid racing with the
-	 * wake_up() in sv_signal() and sv_broadcast(). 
-	 */
-
-	/* don't need the _irqsave part, but there is no wq_write_lock() */
-	wq_write_lock_irqsave(&sv->sv_waiters.lock, flags);
-
-#ifdef EXCLUSIVE_IN_QUEUE
-	wait.flags |= WQ_FLAG_EXCLUSIVE;
-#endif
-
-	switch(sv->sv_flags & SV_ORDER_MASK) {
-	case SV_ORDER_FIFO:
-		__add_wait_queue_tail(&sv->sv_waiters, &wait);
-		break;
-	case SV_ORDER_FILO:
-		__add_wait_queue(&sv->sv_waiters, &wait);
-		break;
-	default:
-		printk(KERN_ERR "sv_wait: unknown order!  (sv: 0x%p, flags: 0x%x)\n",
-					sv, sv->sv_flags);
-		BUG();
-	}
-	wq_write_unlock_irqrestore(&sv->sv_waiters.lock, flags);
-
-	if(sv_wait_flags & SV_WAIT_SIG)
-		set_current_state(TASK_EXCLUSIVE | TASK_INTERRUPTIBLE  );
-	else
-		set_current_state(TASK_EXCLUSIVE | TASK_UNINTERRUPTIBLE);
-
-	spin_unlock(&sv->sv_lock);
-
-	if(sv->sv_flags & SV_INTS)
-		local_irq_enable();
-	else if(sv->sv_flags & SV_BHS)
-		local_bh_enable();
-
-	if (timeout)
-		ret = schedule_timeout(timeout);
-	else
-		schedule();
-
-	if(current->state != TASK_RUNNING) /* XXX Is this possible? */ {
-		printk(KERN_ERR "sv_wait: state not TASK_RUNNING after "
-		       "schedule().\n");
-		set_current_state(TASK_RUNNING);
-	}
-
-	remove_wait_queue(&sv->sv_waiters, &wait);
-
-	/* Return cases:
-	   - woken by a sv_signal/sv_broadcast
-	   - woken by a signal
-	   - woken by timeout expiring
-	*/
-
-	/* XXX This isn't really accurate; we may have been woken
-           before the signal anyway.... */
-	if(signal_pending(current))
-		return timeout ? -ret : -1;
-	return timeout ? ret : 1;
-}
-
-
-void sv_signal(sv_t *sv) 
-{
-	/* If interrupts can acquire this lock, they can also acquire the
-	   sv_mon_lock, which we must already have to have called this, so
-	   interrupts must be disabled already.  If interrupts cannot
-	   contend for this lock, we don't have to worry about it. */
-
-#ifdef SV_DEBUG_INTERRUPT_STATE
-	if(sv->sv_flags & SV_INTS) {
-		unsigned long flags;
-		__save_flags(flags);
-		if(SV_TEST_INTERRUPTS_ENABLED(flags))
-			printk(KERN_ERR "sv_signal: SV_INTS and "
-			"interrupts enabled! (flags: 0x%lx)\n", flags);
-	}
-#endif /* SV_DEBUG_INTERRUPT_STATE */
-
-	sv_lock(sv);
-	wake_up(&sv->sv_waiters);
-	sv_unlock(sv);
-}
-
-void sv_broadcast(sv_t *sv) 
-{
-#ifdef SV_DEBUG_INTERRUPT_STATE
-	if(sv->sv_flags & SV_INTS) {
-		unsigned long flags;
-		__save_flags(flags);
-		if(SV_TEST_INTERRUPTS_ENABLED(flags))
-			printk(KERN_ERR "sv_broadcast: SV_INTS and "
-			       "interrupts enabled! (flags: 0x%lx)\n", flags);
-	}
-#endif /* SV_DEBUG_INTERRUPT_STATE */
-
-	sv_lock(sv);
-	wake_up_all(&sv->sv_waiters);
-	sv_unlock(sv);
-}
-
-void sv_destroy(sv_t *sv) 
-{
-	if(!spin_trylock(&sv->sv_lock)) {
-		printk(KERN_ERR "sv_destroy: someone else has sv 0x%p locked!\n", sv);
-		BUG();
-	}
-
-	/* XXX Check that the waitqueue is empty? 
-	       Mark the sv destroyed?
-	*/
-}
-
-
-#ifdef RUN_SV_TEST
-
-static DECLARE_MUTEX_LOCKED(talkback);
-static DECLARE_MUTEX_LOCKED(sem);
-sv_t sv;
-sv_t sv_filo;
-
-static int sv_test_1_w(void *arg) 
-{
-	printk("sv_test_1_w: acquiring spinlock 0x%p...\n", arg);
-
-	spin_lock((spinlock_t*)arg);
-	printk("sv_test_1_w: spinlock acquired, waking sv_test_1_s.\n");
-
-	up(&sem);
-
-	printk("sv_test_1_w: sv_spin_wait()'ing.\n");
-
-	sv_spin_wait(&sv, arg);
-
-	printk("sv_test_1_w: talkback.\n");
-	up(&talkback);
-
-	printk("sv_test_1_w: exiting.\n");
-	return 0;
-}
-
-static int sv_test_1_s(void *arg) 
-{
-	printk("sv_test_1_s: waiting for semaphore.\n");
-	down(&sem);
-	printk("sv_test_1_s: semaphore acquired.  Acquiring spinlock.\n");
-	spin_lock((spinlock_t*)arg);
-	printk("sv_test_1_s: spinlock acquired.  sv_signaling.\n");
-	sv_signal(&sv);
-	printk("sv_test_1_s: talkback.\n");
-	up(&talkback);
-	printk("sv_test_1_s: exiting.\n");
-	return 0;
-
-}
-
-static int count;
-static DECLARE_MUTEX(monitor);
-
-static int sv_test_2_w(void *arg) 
-{
-	int dummy = count++;
-	sv_t *sv = (sv_t *)arg;
-
-	down(&monitor);
-	up(&talkback);
-	printk("sv_test_2_w: thread %d started, sv_waiting.\n", dummy);
-	sv_sema_wait(sv, &monitor);
-	printk("sv_test_2_w: thread %d woken, exiting.\n", dummy);
-	up(&sem);
-	return 0;
-}
-
-static int sv_test_2_s_1(void *arg) 
-{
-	int i;
-	sv_t *sv = (sv_t *)arg;
-
-	down(&monitor);
-	for(i = 0; i < 3; i++) {
-		printk("sv_test_2_s_1: waking one thread.\n");
-		sv_signal(sv);
-		down(&sem);
-	}
-
-	printk("sv_test_2_s_1: signaling and broadcasting again.  Nothing should happen.\n");
-	sv_signal(sv);
-	sv_broadcast(sv);
-	sv_signal(sv);
-	sv_broadcast(sv);
-
-	printk("sv_test_2_s_1: talkbacking.\n");
-	up(&talkback);
-	up(&monitor);
-	return 0;
-}
-
-static int sv_test_2_s(void *arg) 
-{
-	int i;
-	sv_t *sv = (sv_t *)arg;
-
-	down(&monitor);
-	for(i = 0; i < 3; i++) {
-		printk("sv_test_2_s: waking one thread (should be %d.)\n", i);
-		sv_signal(sv);
-		down(&sem);
-	}
-
-	printk("sv_test_3_s: waking remaining threads with broadcast.\n");
-	sv_broadcast(sv);
-	for(; i < 10; i++)
-		down(&sem);
-
-	printk("sv_test_3_s: sending talkback.\n");
-	up(&talkback);
-
-	printk("sv_test_3_s: exiting.\n");
-	up(&monitor);
-	return 0;
-}
-
-
-static void big_test(sv_t *sv) 
-{
-	int i;
-
-	count = 0;
-
-	for(i = 0; i < 3; i++) {
-		printk("big_test: spawning thread %d.\n", i);
-		kernel_thread(sv_test_2_w, sv, 0);
-		down(&talkback);
-	}
-
-	printk("big_test: spawning first wake-up thread.\n");
-	kernel_thread(sv_test_2_s_1, sv, 0);
-
-	down(&talkback);
-	printk("big_test: talkback happened.\n");
-
-
-	for(i = 3; i < 13; i++) {
-		printk("big_test: spawning thread %d.\n", i);
-		kernel_thread(sv_test_2_w, sv, 0);
-		down(&talkback);
-	}
-
-	printk("big_test: spawning wake-up thread.\n");
-	kernel_thread(sv_test_2_s, sv, 0);
-
-	down(&talkback);
-}
-
-sv_t int_test_sv;
-spinlock_t int_test_spin = SPIN_LOCK_UNLOCKED;
-int int_test_ready;
-static int irqtestcount;
-
-static int interrupt_test_worker(void *unused) 
-{
-	int id = ++irqtestcount;
-	int it = 0;
-			unsigned long flags, flags2;
-
-	printk("ITW: thread %d started.\n", id);
-
-	while(1) {
-		__save_flags(flags2);
-		if(jiffies % 3) {
-			printk("ITW %2d %5d: irqsaving          (%lx)\n", id, it, flags2);
-			spin_lock_irqsave(&int_test_spin, flags);
-		} else {
-			printk("ITW %2d %5d: spin_lock_irqing   (%lx)\n", id, it, flags2);
-			spin_lock_irq(&int_test_spin);
-		}
-
-		__save_flags(flags2);
-		printk("ITW %2d %5d: locked, sv_waiting (%lx).\n", id, it, flags2);
-		sv_wait(&int_test_sv, 0, 0);
-
-		__save_flags(flags2);
-		printk("ITW %2d %5d: wait finished      (%lx), pausing\n", id, it, flags2);
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(jiffies & 0xf);
-		if(current->state != TASK_RUNNING)
-		  printk("ITW:  current->state isn't RUNNING after schedule!\n");
-		it++;
-	}
-}
-
-static void interrupt_test(void) 
-{
-	int i;
-
-	printk("interrupt_test: initing sv.\n");
-	sv_init(&int_test_sv, &int_test_spin, SV_MON_SPIN | SV_INTS);
-
-	for(i = 0; i < SV_INTERRUPT_TEST_WORKERS; i++) {
-		printk("interrupt_test: starting test thread %d.\n", i);
-		kernel_thread(interrupt_test_worker, 0, 0);
-	}
-	printk("interrupt_test: done with init part.\n");
-	int_test_ready = 1;
-}
-
-int sv_test(void) 
-{
-	spinlock_t s = SPIN_LOCK_UNLOCKED;
-
-	sv_init(&sv, &s, SV_MON_SPIN);
-	printk("sv_test: starting sv_test_1_w.\n");
-	kernel_thread(sv_test_1_w, &s, 0);
-	printk("sv_test: starting sv_test_1_s.\n");
-	kernel_thread(sv_test_1_s, &s, 0);
-
-	printk("sv_test: waiting for talkback.\n");
-	down(&talkback); down(&talkback);
-	printk("sv_test: talkback happened, sv_destroying.\n");
-	sv_destroy(&sv);
-
-	count = 0;
-
-	printk("sv_test: beginning big_test on sv.\n");
-
-	sv_init(&sv, &monitor, SV_MON_SEMA);
-	big_test(&sv);
-	sv_destroy(&sv);
-
-	printk("sv_test: beginning big_test on sv_filo.\n");
-	sv_init(&sv_filo, &monitor, SV_MON_SEMA | SV_ORDER_FILO);
-	big_test(&sv_filo);
-	sv_destroy(&sv_filo);
-
-	interrupt_test();
-
-	printk("sv_test: done.\n");
-	return 0;
-}
-
-__initcall(sv_test);
-
-#endif /* RUN_SV_TEST */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/sn1/synergy.c linux/arch/ia64/sn/sn1/synergy.c
--- linux.orig/arch/ia64/sn/sn1/synergy.c	2001-04-05 19:51:47.000000000 +0000
+++ linux/arch/ia64/sn/sn1/synergy.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,429 +0,0 @@
-
-/*
- * SN1 Platform specific synergy Support
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 Alan Mayer (ajm@sgi.com)
- */
-
-
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/synergy.h>
-
-int bit_pos_to_irq(int bit);
-void setclear_mask_b(int irq, int cpuid, int set);
-void setclear_mask_a(int irq, int cpuid, int set);
-void * kmalloc(size_t size, int flags);
-
-
-void
-synergy_intr_alloc(int bit, int cpuid) {
-	return;
-}
-
-int
-synergy_intr_connect(int bit, 
-		int cpuid)
-{
-	int irq;
-	unsigned is_b;
-
-	irq = bit_pos_to_irq(bit);
-
-	is_b = (cpuid_to_slice(cpuid)) & 1;
-	if (is_b) {
-		setclear_mask_b(irq,cpuid,1);
-		setclear_mask_a(irq,cpuid, 0);
-	} else {
-		setclear_mask_a(irq, cpuid, 1);
-		setclear_mask_b(irq, cpuid, 0);
-	}
-	return 0;
-}
-void
-setclear_mask_a(int irq, int cpuid, int set)
-{
-	int synergy;
-	int nasid;
-	int reg_num;
-	unsigned long mask;
-	unsigned long addr;
-	unsigned long reg;
-	unsigned long val;
-	int my_cnode, my_synergy;
-	int target_cnode, target_synergy;
-
-        /*
-         * Perform some idiot checks ..
-         */
-        if ( (irq < 0) || (irq > 255) ||
-                (cpuid < 0) || (cpuid > 512) ) {
-                printk("clear_mask_a: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
-		return;
-	}
-
-	target_cnode = cpuid_to_cnodeid(cpuid);
-	target_synergy = cpuid_to_synergy(cpuid);
-	my_cnode = cpuid_to_cnodeid(smp_processor_id());
-	my_synergy = cpuid_to_synergy(smp_processor_id());
-
-	reg_num = irq / 64;
-	mask = 1;
-	mask <<= (irq % 64);
-	switch (reg_num) {
-		case 0: 
-			reg = VEC_MASK0A;
-			addr = VEC_MASK0A_ADDR;
-			break;
-		case 1: 
-			reg = VEC_MASK1A;
-			addr = VEC_MASK1A_ADDR;
-			break;
-		case 2: 
-			reg = VEC_MASK2A;
-			addr = VEC_MASK2A_ADDR;
-			break;
-		case 3: 
-			reg = VEC_MASK3A;
-			addr = VEC_MASK3A_ADDR;
-			break;
-		default:
-			reg = addr = 0;
-			break;
-	}
-	if (my_cnode == target_cnode && my_synergy == target_synergy) {
-		// local synergy
-		val = READ_LOCAL_SYNERGY_REG(addr);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		WRITE_LOCAL_SYNERGY_REG(addr, val);
-		val = READ_LOCAL_SYNERGY_REG(addr);
-	} else { /* remote synergy */
-		synergy = cpuid_to_synergy(cpuid);
-		nasid = cpuid_to_nasid(cpuid);
-		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
-	}
-}
-
-void
-setclear_mask_b(int irq, int cpuid, int set)
-{
-	int synergy;
-	int nasid;
-	int reg_num;
-	unsigned long mask;
-	unsigned long addr;
-	unsigned long reg;
-	unsigned long val;
-	int my_cnode, my_synergy;
-	int target_cnode, target_synergy;
-
-	/*
-	 * Perform some idiot checks ..
-	 */
-	if ( (irq < 0) || (irq > 255) ||
-		(cpuid < 0) || (cpuid > 512) ) {
-		printk("clear_mask_b: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
-		return;
-	}
-
-	target_cnode = cpuid_to_cnodeid(cpuid);
-	target_synergy = cpuid_to_synergy(cpuid);
-	my_cnode = cpuid_to_cnodeid(smp_processor_id());
-	my_synergy = cpuid_to_synergy(smp_processor_id());
-
-	reg_num = irq / 64;
-	mask = 1;
-	mask <<= (irq % 64);
-	switch (reg_num) {
-		case 0: 
-			reg = VEC_MASK0B;
-			addr = VEC_MASK0B_ADDR;
-			break;
-		case 1: 
-			reg = VEC_MASK1B;
-			addr = VEC_MASK1B_ADDR;
-			break;
-		case 2: 
-			reg = VEC_MASK2B;
-			addr = VEC_MASK2B_ADDR;
-			break;
-		case 3: 
-			reg = VEC_MASK3B;
-			addr = VEC_MASK3B_ADDR;
-			break;
-		default:
-			reg = addr = 0;
-			break;
-	}
-	if (my_cnode == target_cnode && my_synergy == target_synergy) {
-		// local synergy
-		val = READ_LOCAL_SYNERGY_REG(addr);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		WRITE_LOCAL_SYNERGY_REG(addr, val);
-		val = READ_LOCAL_SYNERGY_REG(addr);
-	} else { /* remote synergy */
-		synergy = cpuid_to_synergy(cpuid);
-		nasid = cpuid_to_nasid(cpuid);
-		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
-	}
-}
-
-#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
-
-/*
- * Synergy perf registers. Multiplexed via timer_interrupt
- */
-static struct proc_dir_entry *synergy_perf_proc = NULL;
-
-/*
- * read handler for /proc/synergy
- */
-static int
-synergy_perf_read_proc (char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
-{
-	cnodeid_t       cnode;
-	nodepda_t       *npdap;
-	synergy_perf_t	*p;
-	int		len = 0;
-
-	len += sprintf(page+len, "# cnode module slot event synergy-A synergy-B\n");
-
-	/* walk the event list for each node */
-	for (cnode=0; cnode < numnodes; cnode++) {
-		npdap = NODEPDA(cnode);
-		if (npdap->synergy_perf_enabled == 0) {
-			len += sprintf(page+len, "# DISABLED\n");
-			break;
-		}
-
-		spin_lock_irq(&npdap->synergy_perf_lock);
-		for (p = npdap->synergy_perf_first; p;) {
-			uint64_t cnt_a=0, cnt_b=0;
-
-			if (p->intervals > 0) {
-				cnt_a = p->counts[0] * npdap->synergy_active_intervals / p->intervals;
-				cnt_b = p->counts[1] * npdap->synergy_active_intervals / p->intervals;
-			}
-
-			len += sprintf(page+len, "%d %d %d %12lx %lu %lu\n",
-				(int)cnode, (int)npdap->module_id, (int)npdap->slotdesc,
-				p->modesel, cnt_a, cnt_b);
-
-			p = p->next;
-			if (p == npdap->synergy_perf_first)
-				break;
-		}
-		spin_unlock_irq(&npdap->synergy_perf_lock);
-	}
-
-	if (len <= off+count) *eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-
-	return len;
-}
-
-static int
-synergy_perf_append(uint64_t modesel)
-{
-	int		cnode;
-	nodepda_t       *npdap;
-	synergy_perf_t	*p;
-	int		err = 0;
-
-	/* bit 45 is enable */
-	modesel |= (1UL << 45);
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		/* for each node, insert a new synergy_perf entry */
-		if ((npdap = NODEPDA(cnode)) == NULL) {
-			printk("synergy_perf_append: cnode=%d NODEPDA(cnode)==NULL, nodepda=%p\n", cnode, nodepda);
-			continue;
-		}
-
-		/* XX use kmem_alloc_node() when it is implemented */
-		p = (synergy_perf_t *)kmalloc(sizeof(synergy_perf_t), GFP_KERNEL);
-		if (p == NULL)
-			err = -ENOMEM;
-		else {
-			memset(p, 0, sizeof(synergy_perf_t));
-			p->modesel = modesel;
-			if (npdap->synergy_perf_data == NULL) {
-				/* circular list */
-				p->next = p;
-				npdap->synergy_perf_data = p;
-				npdap->synergy_perf_first = p;
-			}
-			else {
-				/*
-				 * Jumble up the insertion order so we get better sampling.
-				 * Once the list is complete, "first" stays the same so the
-				 * reporting order is consistent.
-				 */
-				p->next = npdap->synergy_perf_first->next;
-				npdap->synergy_perf_first->next = p;
-				npdap->synergy_perf_first = p->next;
-			}
-		}
-	}
-
-	return err;
-}
-
-static int
-synergy_perf_write_proc (struct file *file, const char *buffer,
-                                unsigned long count, void *data)
-{
-	int		cnode;
-	nodepda_t       *npdap;
-	uint64_t	modesel;
-	char		cmd[64];
-	extern long	atoi(char *);
-    
-	if (count == sizeof(uint64_t)) {
-	    if (copy_from_user(&modesel, buffer, sizeof(uint64_t)))
-		    return -EFAULT;
-	    synergy_perf_append(modesel);
-	}
-	else {
-	    if (copy_from_user(cmd, buffer, count < sizeof(cmd) ? count : sizeof(cmd)))
-		    return -EFAULT;
-	    if (strncmp(cmd, "enable", 6) == 0) {
-		/* enable counting */
-		for (cnode=0; cnode < numnodes; cnode++) {
-			npdap = NODEPDA(cnode);
-			npdap->synergy_perf_enabled = 1;
-		}
-		printk("NOTICE: synergy perf counting enabled\n");
-	    }
-	    else
-	    if (strncmp(cmd, "disable", 7) == 0) {
-		/* disable counting */
-		for (cnode=0; cnode < numnodes; cnode++) {
-			npdap = NODEPDA(cnode);
-			npdap->synergy_perf_enabled = 0;
-		}
-		printk("NOTICE: synergy perf counting disabled\n");
-	    }
-	    else
-	    if (strncmp(cmd, "frequency", 9) == 0) {
-		/* set the update frequency (timer-interrupts per update) */
-		int freq;
-
-		if (count < 12)
-			return -EINVAL;
-		freq = atoi(cmd + 10);
-		if (freq <= 0 || freq > 100)
-			return -EINVAL;
-		for (cnode=0; cnode < numnodes; cnode++) {
-			npdap = NODEPDA(cnode);
-			npdap->synergy_perf_freq = (uint64_t)freq;
-		}
-		printk("NOTICE: synergy perf freq set to %d\n", freq);
-	    }
-	    else
-		return -EINVAL;
-	}
-	
-	return count;
-}
-
-void
-synergy_perf_update(int cpu)
-{
-	nasid_t		nasid;
-	cnodeid_t       cnode = cpuid_to_cnodeid(cpu);
-	struct nodepda_s *npdap;
-	extern struct nodepda_s *nodepda;
-
-	if (nodepda == NULL || (npdap=NODEPDA(cnode)) == NULL || npdap->synergy_perf_enabled == 0 ||
-		npdap->synergy_perf_data == NULL) {
-		/* I/O not initialized, or not enabled, or no events to monitor */
-		return;
-	}
-
-	if (npdap->synergy_inactive_intervals++ % npdap->synergy_perf_freq != 0) {
-		/* don't multiplex on every timer interrupt */
-		return;
-	}
-
-	/*
-	 * Read registers for last interval and increment counters.
-	 * Hold the per-node synergy_perf_lock so concurrent readers get
-	 * consistent values.
-	 */
-	spin_lock_irq(&npdap->synergy_perf_lock);
-
-	nasid = cpuid_to_nasid(cpu);
-	npdap->synergy_active_intervals++;
-	npdap->synergy_perf_data->intervals++;
-
-	npdap->synergy_perf_data->counts[0] += 0xffffffffffUL &
-		REMOTE_SYNERGY_LOAD(nasid, 0, PERF_CNTR0_A);
-
-	npdap->synergy_perf_data->counts[1] += 0xffffffffffUL &
-		REMOTE_SYNERGY_LOAD(nasid, 1, PERF_CNTR0_B);
-
-	/* skip to next in circular list */
-	npdap->synergy_perf_data = npdap->synergy_perf_data->next;
-
-	spin_unlock_irq(&npdap->synergy_perf_lock);
-
-	/* set the counter 0 selection modes for both A and B */
-	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTL0_A, npdap->synergy_perf_data->modesel);
-	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTL0_B, npdap->synergy_perf_data->modesel);
-
-	/* and reset the counter registers to zero */
-	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTR0_A, 0UL);
-	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTR0_B, 0UL);
-}
-
-void
-synergy_perf_init(void)
-{
-        if ((synergy_perf_proc = create_proc_entry("synergy", 0644, NULL)) != NULL) {
-                synergy_perf_proc->read_proc = synergy_perf_read_proc;
-                synergy_perf_proc->write_proc = synergy_perf_write_proc;
-                printk("markgw: synergy_perf_init()\n");
-        }
-}
-
-#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/sn/tools/make_textsym linux/arch/ia64/sn/tools/make_textsym
--- linux.orig/arch/ia64/sn/tools/make_textsym	2001-01-04 21:00:15.000000000 +0000
+++ linux/arch/ia64/sn/tools/make_textsym	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,14 @@
 #!/bin/sh
+#
 # Build a textsym file for use in the Arium ITP probe.
+#
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+#
 
 help() {
 cat <<END
@@ -30,108 +39,132 @@
 
 LINUX=${1:-vmlinux}
 TEXTSYM=${2:-${LINUX}.sym}
+TMPSYM=${2:-${LINUX}.sym.tmp}
+trap "/bin/rm -f $TMPSYM" 0
 
 [ -f $VMLINUX ] || help
 
+$OBJDUMP -t $LINUX | sort > $TMPSYM
+SN1=`egrep "dig_setup|Synergy_da_indr" $TMPSYM|wc -l`
+
+# Dataprefix and textprefix correspond to the VGLOBAL_BASE and VPERNODE_BASE.
+# Eventually, these values should be:
+#	dataprefix	ffffffff
+#	textprefix	fffffffe
+# but right now they're still changing, so make them dynamic.
+dataprefix=`awk ' / \.data	/ { print substr($1, 0, 8) ; exit ; }' $TMPSYM`
+textprefix=`awk ' / \.text	/ { print substr($1, 0, 8) ; exit ; }' $TMPSYM`
 
 # pipe everything thru sort
 echo "TEXTSYM V1.0"
 (cat <<END 
-GLOBAL | e000000000500000 | CODE | VEC_VHPT_Translation_0000
-GLOBAL | e000000000500400 | CODE | VEC_ITLB_0400
-GLOBAL | e000000000500800 | CODE | VEC_DTLB_0800
-GLOBAL | e000000000500c00 | CODE | VEC_Alt_ITLB_0c00
-GLOBAL | e000000000501000 | CODE | VEC_Alt_DTLB_1000
-GLOBAL | e000000000501400 | CODE | VEC_Data_nested_TLB_1400
-GLOBAL | e000000000501800 | CODE | VEC_Instruction_Key_Miss_1800
-GLOBAL | e000000000501c00 | CODE | VEC_Data_Key_Miss_1c00
-GLOBAL | e000000000502000 | CODE | VEC_Dirty-bit_2000
-GLOBAL | e000000000502400 | CODE | VEC_Instruction_Access-bit_2400
-GLOBAL | e000000000502800 | CODE | VEC_Data_Access-bit_2800
-GLOBAL | e000000000502c00 | CODE | VEC_Break_instruction_2c00
-GLOBAL | e000000000503000 | CODE | VEC_External_Interrupt_3000
-GLOBAL | e000000000503400 | CODE | VEC_Reserved_3400
-GLOBAL | e000000000503800 | CODE | VEC_Reserved_3800
-GLOBAL | e000000000503c00 | CODE | VEC_Reserved_3c00
-GLOBAL | e000000000504000 | CODE | VEC_Reserved_4000
-GLOBAL | e000000000504400 | CODE | VEC_Reserved_4400
-GLOBAL | e000000000504800 | CODE | VEC_Reserved_4800
-GLOBAL | e000000000504c00 | CODE | VEC_Reserved_4c00
-GLOBAL | e000000000505000 | CODE | VEC_Page_Not_Present_5000
-GLOBAL | e000000000505100 | CODE | VEC_Key_Permission_5100
-GLOBAL | e000000000505200 | CODE | VEC_Instruction_Access_Rights_5200
-GLOBAL | e000000000505300 | CODE | VEC_Data_Access_Rights_5300
-GLOBAL | e000000000505400 | CODE | VEC_General_Exception_5400
-GLOBAL | e000000000505500 | CODE | VEC_Disabled_FP-Register_5500
-GLOBAL | e000000000505600 | CODE | VEC_Nat_Consumption_5600
-GLOBAL | e000000000505700 | CODE | VEC_Speculation_5700
-GLOBAL | e000000000505800 | CODE | VEC_Reserved_5800
-GLOBAL | e000000000505900 | CODE | VEC_Debug_5900
-GLOBAL | e000000000505a00 | CODE | VEC_Unaligned_Reference_5a00
-GLOBAL | e000000000505b00 | CODE | VEC_Unsupported_Data_Reference_5b00
-GLOBAL | e000000000505c00 | CODE | VEC_Floating-Point_Fault_5c00
-GLOBAL | e000000000505d00 | CODE | VEC_Floating_Point_Trap_5d00
-GLOBAL | e000000000505e00 | CODE | VEC_Lower_Privilege_Tranfer_Trap_5e00
-GLOBAL | e000000000505f00 | CODE | VEC_Taken_Branch_Trap_5f00
-GLOBAL | e000000000506000 | CODE | VEC_Single_Step_Trap_6000
-GLOBAL | e000000000506100 | CODE | VEC_Reserved_6100
-GLOBAL | e000000000506200 | CODE | VEC_Reserved_6200
-GLOBAL | e000000000506300 | CODE | VEC_Reserved_6300
-GLOBAL | e000000000506400 | CODE | VEC_Reserved_6400
-GLOBAL | e000000000506500 | CODE | VEC_Reserved_6500
-GLOBAL | e000000000506600 | CODE | VEC_Reserved_6600
-GLOBAL | e000000000506700 | CODE | VEC_Reserved_6700
-GLOBAL | e000000000506800 | CODE | VEC_Reserved_6800
-GLOBAL | e000000000506900 | CODE | VEC_IA-32_Exeception_6900
-GLOBAL | e000000000506a00 | CODE | VEC_IA-32_Intercept_6a00
-GLOBAL | e000000000506b00 | CODE | VEC_IA-32_Interrupt_6b00
-GLOBAL | e000000000506c00 | CODE | VEC_Reserved_6c00
-GLOBAL | e000000000506d00 | CODE | VEC_Reserved_6d00
-GLOBAL | e000000000506e00 | CODE | VEC_Reserved_6e00
-GLOBAL | e000000000506f00 | CODE | VEC_Reserved_6f00
-GLOBAL | e000000000507000 | CODE | VEC_Reserved_7000
-GLOBAL | e000000000507100 | CODE | VEC_Reserved_7100
-GLOBAL | e000000000507200 | CODE | VEC_Reserved_7200
-GLOBAL | e000000000507300 | CODE | VEC_Reserved_7300
-GLOBAL | e000000000507400 | CODE | VEC_Reserved_7400
-GLOBAL | e000000000507500 | CODE | VEC_Reserved_7500
-GLOBAL | e000000000507600 | CODE | VEC_Reserved_7600
-GLOBAL | e000000000507700 | CODE | VEC_Reserved_7700
-GLOBAL | e000000000507800 | CODE | VEC_Reserved_7800
-GLOBAL | e000000000507900 | CODE | VEC_Reserved_7900
-GLOBAL | e000000000507a00 | CODE | VEC_Reserved_7a00
-GLOBAL | e000000000507b00 | CODE | VEC_Reserved_7b00
-GLOBAL | e000000000507c00 | CODE | VEC_Reserved_7c00
-GLOBAL | e000000000507d00 | CODE | VEC_Reserved_7d00
-GLOBAL | e000000000507e00 | CODE | VEC_Reserved_7e00
-GLOBAL | e000000000507f00 | CODE | VEC_Reserved_7f00
+GLOBAL | ${textprefix}00400000 | CODE | VEC_VHPT_Translation_0000
+GLOBAL | ${textprefix}00400400 | CODE | VEC_ITLB_0400
+GLOBAL | ${textprefix}00400800 | CODE | VEC_DTLB_0800
+GLOBAL | ${textprefix}00400c00 | CODE | VEC_Alt_ITLB_0c00
+GLOBAL | ${textprefix}00401000 | CODE | VEC_Alt_DTLB_1000
+GLOBAL | ${textprefix}00401400 | CODE | VEC_Data_nested_TLB_1400
+GLOBAL | ${textprefix}00401800 | CODE | VEC_Instruction_Key_Miss_1800
+GLOBAL | ${textprefix}00401c00 | CODE | VEC_Data_Key_Miss_1c00
+GLOBAL | ${textprefix}00402000 | CODE | VEC_Dirty-bit_2000
+GLOBAL | ${textprefix}00402400 | CODE | VEC_Instruction_Access-bit_2400
+GLOBAL | ${textprefix}00402800 | CODE | VEC_Data_Access-bit_2800
+GLOBAL | ${textprefix}00402c00 | CODE | VEC_Break_instruction_2c00
+GLOBAL | ${textprefix}00403000 | CODE | VEC_External_Interrupt_3000
+GLOBAL | ${textprefix}00403400 | CODE | VEC_Reserved_3400
+GLOBAL | ${textprefix}00403800 | CODE | VEC_Reserved_3800
+GLOBAL | ${textprefix}00403c00 | CODE | VEC_Reserved_3c00
+GLOBAL | ${textprefix}00404000 | CODE | VEC_Reserved_4000
+GLOBAL | ${textprefix}00404400 | CODE | VEC_Reserved_4400
+GLOBAL | ${textprefix}00404800 | CODE | VEC_Reserved_4800
+GLOBAL | ${textprefix}00404c00 | CODE | VEC_Reserved_4c00
+GLOBAL | ${textprefix}00405000 | CODE | VEC_Page_Not_Present_5000
+GLOBAL | ${textprefix}00405100 | CODE | VEC_Key_Permission_5100
+GLOBAL | ${textprefix}00405200 | CODE | VEC_Instruction_Access_Rights_5200
+GLOBAL | ${textprefix}00405300 | CODE | VEC_Data_Access_Rights_5300
+GLOBAL | ${textprefix}00405400 | CODE | VEC_General_Exception_5400
+GLOBAL | ${textprefix}00405500 | CODE | VEC_Disabled_FP-Register_5500
+GLOBAL | ${textprefix}00405600 | CODE | VEC_Nat_Consumption_5600
+GLOBAL | ${textprefix}00405700 | CODE | VEC_Speculation_5700
+GLOBAL | ${textprefix}00405800 | CODE | VEC_Reserved_5800
+GLOBAL | ${textprefix}00405900 | CODE | VEC_Debug_5900
+GLOBAL | ${textprefix}00405a00 | CODE | VEC_Unaligned_Reference_5a00
+GLOBAL | ${textprefix}00405b00 | CODE | VEC_Unsupported_Data_Reference_5b00
+GLOBAL | ${textprefix}00405c00 | CODE | VEC_Floating-Point_Fault_5c00
+GLOBAL | ${textprefix}00405d00 | CODE | VEC_Floating_Point_Trap_5d00
+GLOBAL | ${textprefix}00405e00 | CODE | VEC_Lower_Privilege_Tranfer_Trap_5e00
+GLOBAL | ${textprefix}00405f00 | CODE | VEC_Taken_Branch_Trap_5f00
+GLOBAL | ${textprefix}00406000 | CODE | VEC_Single_Step_Trap_6000
+GLOBAL | ${textprefix}00406100 | CODE | VEC_Reserved_6100
+GLOBAL | ${textprefix}00406200 | CODE | VEC_Reserved_6200
+GLOBAL | ${textprefix}00406300 | CODE | VEC_Reserved_6300
+GLOBAL | ${textprefix}00406400 | CODE | VEC_Reserved_6400
+GLOBAL | ${textprefix}00406500 | CODE | VEC_Reserved_6500
+GLOBAL | ${textprefix}00406600 | CODE | VEC_Reserved_6600
+GLOBAL | ${textprefix}00406700 | CODE | VEC_Reserved_6700
+GLOBAL | ${textprefix}00406800 | CODE | VEC_Reserved_6800
+GLOBAL | ${textprefix}00406900 | CODE | VEC_IA-32_Exeception_6900
+GLOBAL | ${textprefix}00406a00 | CODE | VEC_IA-32_Intercept_6a00
+GLOBAL | ${textprefix}00406b00 | CODE | VEC_IA-32_Interrupt_6b00
+GLOBAL | ${textprefix}00406c00 | CODE | VEC_Reserved_6c00
+GLOBAL | ${textprefix}00406d00 | CODE | VEC_Reserved_6d00
+GLOBAL | ${textprefix}00406e00 | CODE | VEC_Reserved_6e00
+GLOBAL | ${textprefix}00406f00 | CODE | VEC_Reserved_6f00
+GLOBAL | ${textprefix}00407000 | CODE | VEC_Reserved_7000
+GLOBAL | ${textprefix}00407100 | CODE | VEC_Reserved_7100
+GLOBAL | ${textprefix}00407200 | CODE | VEC_Reserved_7200
+GLOBAL | ${textprefix}00407300 | CODE | VEC_Reserved_7300
+GLOBAL | ${textprefix}00407400 | CODE | VEC_Reserved_7400
+GLOBAL | ${textprefix}00407500 | CODE | VEC_Reserved_7500
+GLOBAL | ${textprefix}00407600 | CODE | VEC_Reserved_7600
+GLOBAL | ${textprefix}00407700 | CODE | VEC_Reserved_7700
+GLOBAL | ${textprefix}00407800 | CODE | VEC_Reserved_7800
+GLOBAL | ${textprefix}00407900 | CODE | VEC_Reserved_7900
+GLOBAL | ${textprefix}00407a00 | CODE | VEC_Reserved_7a00
+GLOBAL | ${textprefix}00407b00 | CODE | VEC_Reserved_7b00
+GLOBAL | ${textprefix}00407c00 | CODE | VEC_Reserved_7c00
+GLOBAL | ${textprefix}00407d00 | CODE | VEC_Reserved_7d00
+GLOBAL | ${textprefix}00407e00 | CODE | VEC_Reserved_7e00
+GLOBAL | ${textprefix}00407f00 | CODE | VEC_Reserved_7f00
 END
 
-$OBJDUMP -t $LINUX | sort | awk '
-/empty_zero_page/ {start=1}
-/e0000000/ {
+
+awk '
+/__start_gate_section/ {start=1}
+/^'${dataprefix}\|${textprefix}'/ {
 	if ($4 == ".kdb")
 		next
 	if (start && substr($NF,1,1) != "0") {
 		type = substr($0,26,5)
 		if (type == ".text")
 			printf "GLOBAL | %s | CODE | %s\n", $1, $NF
-		else
-			printf "GLOBAL | %s | DATA | %s | %d\n", $1, $NF, $(NF-1)
+		else {
+			n = 0
+			s = $(NF-1)
+			while (length(s) > 0) {
+				n = n*16 + substr(s,1,1)
+				s = substr(s,2)
+			}
+			printf "GLOBAL | %s | DATA | %s | %d\n", $1, $NF, n
+		}
 	}
 	if($NF == "_end") 
 		exit
 
 }
-' ) | egrep -v " __device| __vendor" | awk '
+' $TMPSYM ) | egrep -v " __device| __vendor" | awk -v sn1="$SN1" '
 /GLOBAL/ {
 	print $0
-	print substr($0,1,9) substr($0,18,18) "Phy_" substr($0,36)
+	if (sn1 != 0) {
+		/* 32 bits of sn1 physical addrs, */
+		print substr($0,1,9) substr($0,18,18) "Phy_" substr($0,36)
+	} else {
+		/* 38 bits of sn2 physical addrs, need addr space bits */
+		print substr($0,1,9) "30" substr($0,18,18) "Phy_" substr($0,36)
+	}
 
 } ' | sort -k3
 
-
-
 N=`wc -l $TEXTSYM|awk '{print $1}'`
 echo "Generated TEXTSYM file" >&2
 echo "  $LINUX --> $TEXTSYM" >&2
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/tools/print_offsets.c linux/arch/ia64/tools/print_offsets.c
--- linux.orig/arch/ia64/tools/print_offsets.c	2001-11-09 22:26:17.000000000 +0000
+++ linux/arch/ia64/tools/print_offsets.c	2002-07-20 01:08:39.000000000 +0000
@@ -2,7 +2,7 @@
  * Utility to generate asm-ia64/offsets.h.
  *
  * Copyright (C) 1999-2001 Hewlett-Packard Co
- * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Note that this file has dual use: when building the kernel
  * natively, the file is translated into a binary and executed.  When
@@ -58,7 +58,7 @@
     { "IA64_TASK_THREAD_OFFSET",	offsetof (struct task_struct, thread) },
     { "IA64_TASK_THREAD_KSP_OFFSET",	offsetof (struct task_struct, thread.ksp) },
 #ifdef CONFIG_PERFMON
-    { "IA64_TASK_PFM_MUST_BLOCK_OFFSET",offsetof(struct task_struct, thread.pfm_must_block) },
+    { "IA64_TASK_PFM_OVFL_BLOCK_RESET_OFFSET",offsetof(struct task_struct, thread.pfm_ovfl_block_reset) },
 #endif
     { "IA64_TASK_PID_OFFSET",		offsetof (struct task_struct, pid) },
     { "IA64_TASK_MM_OFFSET",		offsetof (struct task_struct, mm) },
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/vmlinux.lds.S linux/arch/ia64/vmlinux.lds.S
--- linux.orig/arch/ia64/vmlinux.lds.S	2001-07-31 17:30:09.000000000 +0000
+++ linux/arch/ia64/vmlinux.lds.S	2002-07-20 01:08:31.000000000 +0000
@@ -13,6 +13,8 @@
 	*(.text.exit)
 	*(.data.exit)
 	*(.exitcall.exit)
+	*(.IA_64.unwind.text.exit)
+	*(.IA_64.unwind_info.text.exit)
 	}
 
   v = PAGE_OFFSET;	/* this symbol is here to make debugging easier... */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c
--- linux.orig/arch/m68k/amiga/config.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/arch/m68k/amiga/config.c	2002-07-20 01:08:23.000000000 +0000
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/rtc.h>
 #include <linux/init.h>
 #ifdef CONFIG_ZORRO
 #include <linux/zorro.h>
@@ -91,14 +92,13 @@
 static unsigned long amiga_gettimeoffset (void);
 static void a3000_gettod (int *, int *, int *, int *, int *, int *);
 static void a2000_gettod (int *, int *, int *, int *, int *, int *);
-static int amiga_hwclk (int, struct hwclk_time *);
+static int amiga_hwclk (int, struct rtc_time *);
 static int amiga_set_clock_mmss (unsigned long);
 extern void amiga_mksound( unsigned int count, unsigned int ticks );
 #ifdef CONFIG_AMIGA_FLOPPY
 extern void amiga_floppy_setup(char *, int *);
 #endif
 static void amiga_reset (void);
-static int amiga_wait_key (struct console *co);
 extern void amiga_init_sound(void);
 static void amiga_savekmsg_init(void);
 static void amiga_mem_console_write(struct console *co, const char *b,
@@ -112,7 +112,6 @@
 
 static struct console amiga_console_driver = {
 	name:		"debug",
-	wait_key:	amiga_wait_key,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
 };
@@ -615,7 +614,7 @@
 	tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
 }
 
-static int amiga_hwclk(int op, struct hwclk_time *t)
+static int amiga_hwclk(int op, struct rtc_time *t)
 {
 	if (AMIGAHW_PRESENT(A3000_CLK)) {
 		volatile struct tod3000 *tod = TOD_3000;
@@ -623,32 +622,32 @@
 		tod->cntrl1 = TOD3000_CNTRL1_HOLD;
 
 		if (!op) { /* read */
-			t->sec  = tod->second1 * 10 + tod->second2;
-			t->min  = tod->minute1 * 10 + tod->minute2;
-			t->hour = tod->hour1   * 10 + tod->hour2;
-			t->day  = tod->day1    * 10 + tod->day2;
-			t->wday = tod->weekday;
-			t->mon  = tod->month1  * 10 + tod->month2 - 1;
-			t->year = tod->year1   * 10 + tod->year2;
-			if (t->year <= 69)
-				t->year += 100;
+			t->tm_sec  = tod->second1 * 10 + tod->second2;
+			t->tm_min  = tod->minute1 * 10 + tod->minute2;
+			t->tm_hour = tod->hour1   * 10 + tod->hour2;
+			t->tm_mday = tod->day1    * 10 + tod->day2;
+			t->tm_wday = tod->weekday;
+			t->tm_mon  = tod->month1  * 10 + tod->month2 - 1;
+			t->tm_year = tod->year1   * 10 + tod->year2;
+			if (t->tm_year <= 69)
+				t->tm_year += 100;
 		} else {
-			tod->second1 = t->sec / 10;
-			tod->second2 = t->sec % 10;
-			tod->minute1 = t->min / 10;
-			tod->minute2 = t->min % 10;
-			tod->hour1   = t->hour / 10;
-			tod->hour2   = t->hour % 10;
-			tod->day1    = t->day / 10;
-			tod->day2    = t->day % 10;
-			if (t->wday != -1)
-				tod->weekday = t->wday;
-			tod->month1  = (t->mon + 1) / 10;
-			tod->month2  = (t->mon + 1) % 10;
-			if (t->year >= 100)
-				t->year -= 100;
-			tod->year1   = t->year / 10;
-			tod->year2   = t->year % 10;
+			tod->second1 = t->tm_sec / 10;
+			tod->second2 = t->tm_sec % 10;
+			tod->minute1 = t->tm_min / 10;
+			tod->minute2 = t->tm_min % 10;
+			tod->hour1   = t->tm_hour / 10;
+			tod->hour2   = t->tm_hour % 10;
+			tod->day1    = t->tm_mday / 10;
+			tod->day2    = t->tm_mday % 10;
+			if (t->tm_wday != -1)
+				tod->weekday = t->tm_wday;
+			tod->month1  = (t->tm_mon + 1) / 10;
+			tod->month2  = (t->tm_mon + 1) % 10;
+			if (t->tm_year >= 100)
+				t->tm_year -= 100;
+			tod->year1   = t->tm_year / 10;
+			tod->year2   = t->tm_year % 10;
 		}
 
 		tod->cntrl1 = TOD3000_CNTRL1_FREE;
@@ -661,45 +660,45 @@
 			;
 
 		if (!op) { /* read */
-			t->sec  = tod->second1     * 10 + tod->second2;
-			t->min  = tod->minute1     * 10 + tod->minute2;
-			t->hour = (tod->hour1 & 3) * 10 + tod->hour2;
-			t->day  = tod->day1        * 10 + tod->day2;
-			t->wday = tod->weekday;
-			t->mon  = tod->month1      * 10 + tod->month2 - 1;
-			t->year = tod->year1       * 10 + tod->year2;
-			if (t->year <= 69)
-				t->year += 100;
+			t->tm_sec  = tod->second1     * 10 + tod->second2;
+			t->tm_min  = tod->minute1     * 10 + tod->minute2;
+			t->tm_hour = (tod->hour1 & 3) * 10 + tod->hour2;
+			t->tm_mday = tod->day1        * 10 + tod->day2;
+			t->tm_wday = tod->weekday;
+			t->tm_mon  = tod->month1      * 10 + tod->month2 - 1;
+			t->tm_year = tod->year1       * 10 + tod->year2;
+			if (t->tm_year <= 69)
+				t->tm_year += 100;
 
 			if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){
-				if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
-					t->hour = 0;
-				else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
-					t->hour += 12;
+				if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12)
+					t->tm_hour = 0;
+				else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12)
+					t->tm_hour += 12;
 			}
 		} else {
-			tod->second1 = t->sec / 10;
-			tod->second2 = t->sec % 10;
-			tod->minute1 = t->min / 10;
-			tod->minute2 = t->min % 10;
+			tod->second1 = t->tm_sec / 10;
+			tod->second2 = t->tm_sec % 10;
+			tod->minute1 = t->tm_min / 10;
+			tod->minute2 = t->tm_min % 10;
 			if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE)
-				tod->hour1 = t->hour / 10;
-			else if (t->hour >= 12)
+				tod->hour1 = t->tm_hour / 10;
+			else if (t->tm_hour >= 12)
 				tod->hour1 = TOD2000_HOUR1_PM +
-					(t->hour - 12) / 10;
+					(t->tm_hour - 12) / 10;
 			else
-				tod->hour1 = t->hour / 10;
-			tod->hour2   = t->hour % 10;
-			tod->day1    = t->day / 10;
-			tod->day2    = t->day % 10;
-			if (t->wday != -1)
-				tod->weekday = t->wday;
-			tod->month1  = (t->mon + 1) / 10;
-			tod->month2  = (t->mon + 1) % 10;
-			if (t->year >= 100)
-				t->year -= 100;
-			tod->year1   = t->year / 10;
-			tod->year2   = t->year % 10;
+				tod->hour1 = t->tm_hour / 10;
+			tod->hour2   = t->tm_hour % 10;
+			tod->day1    = t->tm_mday / 10;
+			tod->day2    = t->tm_mday % 10;
+			if (t->tm_wday != -1)
+				tod->weekday = t->tm_wday;
+			tod->month1  = (t->tm_mon + 1) / 10;
+			tod->month2  = (t->tm_mon + 1) % 10;
+			if (t->tm_year >= 100)
+				t->tm_year -= 100;
+			tod->year1   = t->tm_year / 10;
+			tod->year2   = t->tm_year % 10;
 		}
 
 		tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
@@ -742,33 +741,6 @@
 	return 0;
 }
 
-static int amiga_wait_key (struct console *co)
-{
-    int i;
-
-    while (1) {
-	while (ciaa.pra & 0x40);
-
-	/* debounce */
-	for (i = 0; i < 1000; i++);
-
-	if (!(ciaa.pra & 0x40))
-	    break;
-    }
-
-    /* wait for button up */
-    while (1) {
-	while (!(ciaa.pra & 0x40));
-
-	/* debounce */
-	for (i = 0; i < 1000; i++);
-
-	if (ciaa.pra & 0x40)
-	    break;
-    }
-    return 0;
-}
-
 static NORET_TYPE void amiga_reset( void )
     ATTRIB_NORET;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/apollo/config.c linux/arch/m68k/apollo/config.c
--- linux.orig/arch/m68k/apollo/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/apollo/config.c	2002-07-20 01:08:31.000000000 +0000
@@ -4,6 +4,7 @@
 #include <linux/mm.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/rtc.h>
 
 #include <asm/setup.h>
 #include <asm/bootinfo.h>
@@ -34,7 +35,7 @@
 extern int dn_get_irq_list(char *);
 extern unsigned long dn_gettimeoffset(void);
 extern void dn_gettod(int *, int *, int *, int *, int *, int *);
-extern int dn_dummy_hwclk(int, struct hwclk_time *);
+extern int dn_dummy_hwclk(int, struct rtc_time *);
 extern int dn_dummy_set_clock_mmss(unsigned long);
 extern void dn_mksound(unsigned int count, unsigned int ticks);
 extern void dn_dummy_reset(void);
@@ -254,26 +255,26 @@
 
 }
 
-int dn_dummy_hwclk(int op, struct hwclk_time *t) {
+int dn_dummy_hwclk(int op, struct rtc_time *t) {
 
 
   if(!op) { /* read */
-    t->sec=rtc->second;
-    t->min=rtc->minute;
-    t->hour=rtc->hours;
-    t->day=rtc->day_of_month;
-    t->wday=rtc->day_of_week;
-    t->mon=rtc->month;
-    t->year=rtc->year;
+    t->tm_sec=rtc->second;
+    t->tm_min=rtc->minute;
+    t->tm_hour=rtc->hours;
+    t->tm_mday=rtc->day_of_month;
+    t->tm_wday=rtc->day_of_week;
+    t->tm_mon=rtc->month;
+    t->tm_year=rtc->year;
   } else {
-    rtc->second=t->sec;
-    rtc->minute=t->min;
-    rtc->hours=t->hour;
-    rtc->day_of_month=t->day;
-    if(t->wday!=-1)
-      rtc->day_of_week=t->wday;
-    rtc->month=t->mon;
-    rtc->year=t->year;
+    rtc->second=t->tm_sec;
+    rtc->minute=t->tm_min;
+    rtc->hours=t->tm_hour;
+    rtc->day_of_month=t->tm_mday;
+    if(t->tm_wday!=-1)
+      rtc->day_of_week=t->tm_wday;
+    rtc->month=t->tm_mon;
+    rtc->year=t->tm_year;
   }
 
   return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/atari/ataints.c linux/arch/m68k/atari/ataints.c
--- linux.orig/arch/m68k/atari/ataints.c	2000-08-04 23:15:37.000000000 +0000
+++ linux/arch/m68k/atari/ataints.c	2002-07-20 01:08:27.000000000 +0000
@@ -168,7 +168,7 @@
 void atari_slow_irq_##n##_dummy (void) {				   \
 __asm__ (__ALIGN_STR "\n"						   \
 SYMBOL_NAME_STR(atari_slow_irq_) #n "_handler:\t"			   \
-"	addql	#1,"SYMBOL_NAME_STR(irq_stat)"+8\n" /* local_irq_count */  \
+"	addql	#1,%5\n"		/* local_irq_count++ */		   \
 	SAVE_ALL_INT "\n"						   \
 	GET_CURRENT(%%d0) "\n"						   \
 "	andb	#~(1<<(%c3&7)),%a4:w\n"	/* mask this interrupt */	   \
@@ -193,8 +193,10 @@
 	 : : "i" (&kstat.irqs[0][n+8]), "i" (&irq_handler[n+8]),	   \
 	     "n" (PT_OFF_SR), "n" (n),					   \
 	     "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &mfp.int_mk_a)	   \
-		        : (n & 16 ? &tt_mfp.int_mk_b : &mfp.int_mk_b))	   \
+		        : (n & 16 ? &tt_mfp.int_mk_b : &mfp.int_mk_b)),	   \
+	     "m" (local_irq_count(0))					   \
 );									   \
+	for (;;);			/* fake noreturn */		   \
 }
 
 BUILD_SLOW_IRQ(0);
@@ -274,7 +276,7 @@
 SYMBOL_NAME_STR(atari_fast_irq_handler) ":
 	orw 	#0x700,%%sr		/* disable all interrupts */
 "SYMBOL_NAME_STR(atari_prio_irq_handler) ":\t
-	addql	#1,"SYMBOL_NAME_STR(irq_stat)"+8\n" /* local_irq_count */
+	addql	#1,%2\n"		/* local_irq_count++ */
 	SAVE_ALL_INT "\n"
 	GET_CURRENT(%%d0) "
 	/* get vector number from stack frame and convert to source */
@@ -294,8 +296,10 @@
 	addql	#8,%%sp
 	addql	#4,%%sp
 	jbra	"SYMBOL_NAME_STR(ret_from_interrupt)
-	 : : "i" (&kstat.irqs[0]), "n" (PT_OFF_FORMATVEC)
+	 : : "i" (&kstat.irqs[0]), "n" (PT_OFF_FORMATVEC),
+	     "m" (local_irq_count(0))
 );
+	for (;;);
 }
 
 /* GK:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/atari/config.c linux/arch/m68k/atari/config.c
--- linux.orig/arch/m68k/atari/config.c	2000-11-28 01:57:34.000000000 +0000
+++ linux/arch/m68k/atari/config.c	2002-07-20 01:08:24.000000000 +0000
@@ -38,6 +38,7 @@
 #include <asm/atariints.h>
 #include <asm/atari_stram.h>
 #include <asm/system.h>
+#include <asm/keyboard.h>
 #include <asm/machdep.h>
 #include <asm/hwtest.h>
 #include <asm/io.h>
@@ -81,8 +82,8 @@
 extern unsigned long atari_gettimeoffset (void);
 extern void atari_mste_gettod (int *, int *, int *, int *, int *, int *);
 extern void atari_tt_gettod (int *, int *, int *, int *, int *, int *);
-extern int atari_mste_hwclk (int, struct hwclk_time *);
-extern int atari_tt_hwclk (int, struct hwclk_time *);
+extern int atari_mste_hwclk (int, struct rtc_time *);
+extern int atari_tt_hwclk (int, struct rtc_time *);
 extern int atari_mste_set_clock_mmss (unsigned long);
 extern int atari_tt_set_clock_mmss (unsigned long);
 
@@ -256,7 +257,9 @@
     mach_keyb_init       = atari_keyb_init;
     mach_kbdrate         = atari_kbdrate;
     mach_kbd_translate   = atari_kbd_translate;
+#ifdef CONFIG_MAGIC_SYSRQ
     SYSRQ_KEY            = 0xff;
+#endif
     mach_kbd_leds        = atari_kbd_leds;
     mach_init_IRQ        = atari_init_IRQ;
     mach_request_irq     = atari_request_irq;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/atari/stram.c linux/arch/m68k/atari/stram.c
--- linux.orig/arch/m68k/atari/stram.c	2001-02-09 19:29:44.000000000 +0000
+++ linux/arch/m68k/atari/stram.c	2002-07-20 01:08:28.000000000 +0000
@@ -236,8 +236,8 @@
 static void do_stram_request(request_queue_t *);
 static int stram_open( struct inode *inode, struct file *filp );
 static int stram_release( struct inode *inode, struct file *filp );
-#endif
 static void reserve_region(void *start, void *end);
+#endif
 static BLOCK *add_region( void *addr, unsigned long size );
 static BLOCK *find_region( void *addr );
 static int remove_region( BLOCK *block );
@@ -296,7 +296,7 @@
 		max_swap_size =
 			(!MACH_IS_HADES &&
 			 (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
-			  (high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
+			  ((unsigned long)high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
 	DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
 #endif
 
@@ -759,7 +759,7 @@
 			/* Get a page for the entry, using the existing
 			   swap cache page if there is one.  Otherwise,
 			   get a clean page and read the swap into it. */
-			page = read_swap_cache(entry);
+			page = read_swap_cache_async(entry);
 			if (!page) {
 				swap_free(entry);
 				return -ENOMEM;
@@ -768,7 +768,7 @@
 			for_each_task(p)
 				unswap_process(p->mm, entry, page);
 			read_unlock(&tasklist_lock);
-			shm_unuse(entry, page);
+			shmem_unuse(entry, page);
 			/* Now get rid of the extra reference to the
 			   temporary page we've been using. */
 			if (PageSwapCache(page))
@@ -1072,7 +1072,6 @@
 	return( 0 );
 }
 
-#endif /* CONFIG_STRAM_SWAP */
 
 
 /* ------------------------------------------------------------------------ */
@@ -1085,6 +1084,7 @@
 	reserve_bootmem (virt_to_phys(start), end - start);
 }
 
+#endif /* CONFIG_STRAM_SWAP */
 
 
 /* ------------------------------------------------------------------------ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/atari/time.c linux/arch/m68k/atari/time.c
--- linux.orig/arch/m68k/atari/time.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/atari/time.c	2002-07-20 01:08:29.000000000 +0000
@@ -14,6 +14,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/rtc.h>
 
 #include <asm/rtc.h>
 
@@ -83,14 +84,14 @@
 
 #define	RTC_READ(reg)				\
     ({	unsigned char	__val;			\
-		(void) writeb(reg,&tt_rtc.regsel);	\
+		(void) atari_writeb(reg,&tt_rtc.regsel);	\
 		__val = tt_rtc.data;		\
 		__val;				\
 	})
 
 #define	RTC_WRITE(reg,val)			\
     do {					\
-		writeb(reg,&tt_rtc.regsel);	\
+		atari_writeb(reg,&tt_rtc.regsel);	\
 		tt_rtc.data = (val);		\
 	} while(0)
 
@@ -164,7 +165,7 @@
 
 #define HWCLK_POLL_INTERVAL	5
 
-int atari_mste_hwclk( int op, struct hwclk_time *t )
+int atari_mste_hwclk( int op, struct rtc_time *t )
 {
     int hour, year;
     int hr24=0;
@@ -177,11 +178,11 @@
     if (op) {
         /* write: prepare values */
         
-        val.sec_ones = t->sec % 10;
-        val.sec_tens = t->sec / 10;
-        val.min_ones = t->min % 10;
-        val.min_tens = t->min / 10;
-        hour = t->hour;
+        val.sec_ones = t->tm_sec % 10;
+        val.sec_tens = t->tm_sec / 10;
+        val.min_ones = t->tm_min % 10;
+        val.min_tens = t->tm_min / 10;
+        hour = t->tm_hour;
         if (!hr24) {
 	    if (hour > 11)
 		hour += 20 - 12;
@@ -190,14 +191,14 @@
         }
         val.hr_ones = hour % 10;
         val.hr_tens = hour / 10;
-        val.day_ones = t->day % 10;
-        val.day_tens = t->day / 10;
-        val.mon_ones = (t->mon+1) % 10;
-        val.mon_tens = (t->mon+1) / 10;
-        year = t->year - 80;
+        val.day_ones = t->tm_mday % 10;
+        val.day_tens = t->tm_mday / 10;
+        val.mon_ones = (t->tm_mon+1) % 10;
+        val.mon_tens = (t->tm_mon+1) / 10;
+        year = t->tm_year - 80;
         val.year_ones = year % 10;
         val.year_tens = year / 10;
-        val.weekday = t->wday;
+        val.weekday = t->tm_wday;
         mste_write(&val);
         mste_rtc.mode=(mste_rtc.mode | 1);
         val.year_ones = (year % 4);	/* leap year register */
@@ -205,8 +206,8 @@
     }
     else {
         mste_read(&val);
-        t->sec = val.sec_ones + val.sec_tens * 10;
-        t->min = val.min_ones + val.min_tens * 10;
+        t->tm_sec = val.sec_ones + val.sec_tens * 10;
+        t->tm_min = val.min_ones + val.min_tens * 10;
         hour = val.hr_ones + val.hr_tens * 10;
 	if (!hr24) {
 	    if (hour == 12 || hour == 12 + 20)
@@ -214,16 +215,16 @@
 	    if (hour >= 20)
                 hour += 12 - 20;
         }
-	t->hour = hour;
-	t->day = val.day_ones + val.day_tens * 10;
-        t->mon = val.mon_ones + val.mon_tens * 10 - 1;
-        t->year = val.year_ones + val.year_tens * 10 + 80;
-        t->wday = val.weekday;
+	t->tm_hour = hour;
+	t->tm_mday = val.day_ones + val.day_tens * 10;
+        t->tm_mon  = val.mon_ones + val.mon_tens * 10 - 1;
+        t->tm_year = val.year_ones + val.year_tens * 10 + 80;
+        t->tm_wday = val.weekday;
     }
     return 0;
 }
 
-int atari_tt_hwclk( int op, struct hwclk_time *t )
+int atari_tt_hwclk( int op, struct rtc_time *t )
 {
     int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0; 
     unsigned long 	flags;
@@ -236,13 +237,13 @@
     if (op) {
         /* write: prepare values */
         
-        sec  = t->sec;
-        min  = t->min;
-        hour = t->hour;
-        day  = t->day;
-        mon  = t->mon + 1;
-        year = t->year - atari_rtc_year_offset;
-        wday = t->wday + (t->wday >= 0);
+        sec  = t->tm_sec;
+        min  = t->tm_min;
+        hour = t->tm_hour;
+        day  = t->tm_mday;
+        mon  = t->tm_mon + 1;
+        year = t->tm_year - atari_rtc_year_offset;
+        wday = t->tm_wday + (t->tm_wday >= 0);
         
         if (!(ctrl & RTC_24H)) {
 	    if (hour > 11) {
@@ -331,13 +332,13 @@
 		hour += 12;
         }
 
-        t->sec  = sec;
-        t->min  = min;
-        t->hour = hour;
-        t->day  = day;
-        t->mon  = mon - 1;
-        t->year = year + atari_rtc_year_offset;
-        t->wday = wday - 1;
+        t->tm_sec  = sec;
+        t->tm_min  = min;
+        t->tm_hour = hour;
+        t->tm_mday = day;
+        t->tm_mon  = mon - 1;
+        t->tm_year = year + atari_rtc_year_offset;
+        t->tm_wday = wday - 1;
     }
 
     return( 0 );
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/bvme6000/config.c linux/arch/m68k/bvme6000/config.c
--- linux.orig/arch/m68k/bvme6000/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/bvme6000/config.c	2002-07-20 01:08:24.000000000 +0000
@@ -22,6 +22,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/major.h>
+#include <linux/rtc.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -48,7 +49,7 @@
 extern unsigned long bvme6000_gettimeoffset (void);
 extern void bvme6000_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
-extern int bvme6000_hwclk (int, struct hwclk_time *);
+extern int bvme6000_hwclk (int, struct rtc_time *);
 extern int bvme6000_set_clock_mmss (unsigned long);
 extern void bvme6000_check_partition (struct gendisk *hd, unsigned int dev);
 extern void bvme6000_mksound( unsigned int count, unsigned int ticks );
@@ -181,8 +182,8 @@
         unsigned long *old = (unsigned long *)0xf8000000;
 
         /* Wait for button release */
-	while (*config_reg_ptr & BVME_ABORT_STATUS)
-		;
+        while (*(volatile unsigned char *)BVME_LOCAL_IRQ_STAT & BVME_ABORT_STATUS)
+                ;
 
         *(new+4) = *(old+4);            /* Illegal instruction */
         *(new+9) = *(old+9);            /* Trace */
@@ -330,7 +331,7 @@
  * };
  */
 
-int bvme6000_hwclk(int op, struct hwclk_time *t)
+int bvme6000_hwclk(int op, struct rtc_time *t)
 {
 	volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
 	unsigned char msr = rtc->msr & 0xc0;
@@ -339,31 +340,31 @@
 				 * are accessible */
 	if (op)
 	{	/* Write.... */
-		rtc->t0cr_rtmr = t->year%4;
+		rtc->t0cr_rtmr = t->tm_year%4;
 		rtc->bcd_tenms = 0;
-		rtc->bcd_sec = bin2bcd(t->sec);
-		rtc->bcd_min = bin2bcd(t->min);
-		rtc->bcd_hr  = bin2bcd(t->hour);
-		rtc->bcd_dom = bin2bcd(t->day);
-		rtc->bcd_mth = bin2bcd(t->mon + 1);
-		rtc->bcd_year = bin2bcd(t->year%100);
-		if (t->wday >= 0)
-			rtc->bcd_dow = bin2bcd(t->wday+1);
-		rtc->t0cr_rtmr = t->year%4 | 0x08;
+		rtc->bcd_sec = bin2bcd(t->tm_sec);
+		rtc->bcd_min = bin2bcd(t->tm_min);
+		rtc->bcd_hr  = bin2bcd(t->tm_hour);
+		rtc->bcd_dom = bin2bcd(t->tm_mday);
+		rtc->bcd_mth = bin2bcd(t->tm_mon + 1);
+		rtc->bcd_year = bin2bcd(t->tm_year%100);
+		if (t->tm_wday >= 0)
+			rtc->bcd_dow = bin2bcd(t->tm_wday+1);
+		rtc->t0cr_rtmr = t->tm_year%4 | 0x08;
 	}
 	else
 	{	/* Read....  */
 		do {
-			t->sec =  bcd2bin(rtc->bcd_sec);
-			t->min =  bcd2bin(rtc->bcd_min);
-			t->hour = bcd2bin(rtc->bcd_hr);
-			t->day =  bcd2bin(rtc->bcd_dom);
-			t->mon =  bcd2bin(rtc->bcd_mth)-1;
-			t->year = bcd2bin(rtc->bcd_year);
-			if (t->year < 70)
-				t->year += 100;
-			t->wday = bcd2bin(rtc->bcd_dow)-1;
-		} while (t->sec != bcd2bin(rtc->bcd_sec));
+			t->tm_sec  = bcd2bin(rtc->bcd_sec);
+			t->tm_min  = bcd2bin(rtc->bcd_min);
+			t->tm_hour = bcd2bin(rtc->bcd_hr);
+			t->tm_mday = bcd2bin(rtc->bcd_dom);
+			t->tm_mon  = bcd2bin(rtc->bcd_mth)-1;
+			t->tm_year = bcd2bin(rtc->bcd_year);
+			if (t->tm_year < 70)
+				t->tm_year += 100;
+			t->tm_wday = bcd2bin(rtc->bcd_dow)-1;
+		} while (t->tm_sec != bcd2bin(rtc->bcd_sec));
 	}
 
 	rtc->msr = msr;
@@ -419,55 +420,3 @@
 {
 	return 0;
 }
-
-/*-------------------  Serial console stuff ------------------------*/
-
-static void bvme_scc_write(struct console *co, const char *str, unsigned cnt);
-
-
-void bvme6000_init_console_port (struct console *co, int cflag)
-{
-        co->write = bvme_scc_write;
-}
-
-
-static void scc_delay (void)
-{
-        int n;
-	volatile int trash;
-
-        for (n = 0; n < 20; n++)
-		trash = n;
-}
-
-static void scc_write (char ch)
-{
-        volatile char *p = (volatile char *)BVME_SCC_A_ADDR;
-
-        do {
-                scc_delay();
-        }
-        while (!(*p & 4));
-        scc_delay();
-        *p = 8;
-        scc_delay();
-        *p = ch;
-}
-
-
-static void bvme_scc_write (struct console *co, const char *str, unsigned count)
-{
-        unsigned long   flags;
-
-        save_flags(flags);
-        cli();
-
-        while (count--)
-        {
-                if (*str == '\n')
-                        scc_write ('\r');
-                scc_write (*str++);
-        }
-        restore_flags(flags);
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/bvme6000/rtc.c linux/arch/m68k/bvme6000/rtc.c
--- linux.orig/arch/m68k/bvme6000/rtc.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/bvme6000/rtc.c	2002-07-20 01:08:23.000000000 +0000
@@ -14,7 +14,7 @@
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/poll.h>
-#include <linux/mc146818rtc.h>	/* For struct rtc_time and ioctls, etc */
+#include <linux/rtc.h>	/* For struct rtc_time and ioctls, etc */
 #include <linux/smp_lock.h>
 #include <asm/bvme6000hw.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/config.in linux/arch/m68k/config.in
--- linux.orig/arch/m68k/config.in	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/config.in	2002-07-20 01:08:38.000000000 +0000
@@ -26,7 +26,6 @@
 mainmenu_option next_comment
 comment 'Platform dependent setup'
 
-define_bool CONFIG_ISA n
 define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
 define_bool CONFIG_PCMCIA n
@@ -146,11 +145,18 @@
    fi
 fi
 
+if [ "$CONFIG_Q40" = "y" -o "$CONFIG_AMIGA_PCMCIA" = "y" \
+      -o "$CONFIG_GG2" = "y" ]; then
+   define_bool CONFIG_ISA y
+else
+   define_bool CONFIG_ISA n
+fi
+
 source drivers/pci/Config.in
 source drivers/zorro/Config.in
 
 if [ "$CONFIG_Q40" = "y" ]; then
-source drivers/pnp/Config.in
+   source drivers/pnp/Config.in
 fi
 
 endmenu
@@ -297,9 +303,17 @@
 	 bool '    Keepalive and linefill' CONFIG_SLIP_SMART
 	 bool '    Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
       fi
-      tristate '  PPP (point-to-point) support' CONFIG_PPP
+      tristate 'PPP (point-to-point protocol) support' CONFIG_PPP
       if [ ! "$CONFIG_PPP" = "n" ]; then
-	 comment 'CCP compressors for PPP are only built as modules.'
+         dep_bool '  PPP multilink support (EXPERIMENTAL)' CONFIG_PPP_MULTILINK $CONFIG_EXPERIMENTAL
+         dep_bool '  PPP filtering' CONFIG_PPP_FILTER $CONFIG_FILTER
+         dep_tristate '  PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
+         dep_tristate '  PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
+         dep_tristate '  PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
+         dep_tristate '  PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
+         if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+             dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
+         fi
       fi
       tristate '  EQL (serial line load balancing) support' CONFIG_EQUALIZER
       if [ "$CONFIG_ZORRO" = "y" ]; then
@@ -352,7 +366,7 @@
          if [  "$CONFIG_PARPORT" != "n" ]; then
 	    dep_tristate '  PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT
 	 fi
-         tristate 'NE2000/NE1000 support' CONFIG_NE2000
+         dep_tristate 'NE2000/NE1000 support' CONFIG_NE2000 m
       fi
    fi
    endmenu
@@ -367,7 +381,6 @@
 fi
 
 if [ "$CONFIG_SERIAL" = "y" ]; then
-   bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
    bool '  Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED
 fi
 
@@ -477,7 +490,8 @@
         "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
         "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
         "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" -o \
-        "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" ]; then
+        "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" -o \
+	"$CONFIG_SERIAL" = "y" ]; then
       bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
    fi
 fi
@@ -543,6 +557,11 @@
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
-#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
-bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
+if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
+   bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
+   bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
+   bool '  Verbose BUG() reporting' CONFIG_DEBUG_BUGVERBOSE
+fi
+
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/hp300/time.c linux/arch/m68k/hp300/time.c
--- linux.orig/arch/m68k/hp300/time.c	1999-08-26 19:42:31.000000000 +0000
+++ linux/arch/m68k/hp300/time.c	2002-07-20 01:08:39.000000000 +0000
@@ -41,7 +41,7 @@
   unsigned long tmp;
   void (*vector)(int, void *, struct pt_regs *) = dev_id;
   readb(CLOCKBASE + CLKSR);
-  asm volatile ("movpw %1@(5),%0" : "=r" (tmp) : "a" (CLOCKBASE));
+  asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE));
   vector(irq, NULL, regs);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/kernel/entry.S linux/arch/m68k/kernel/entry.S
--- linux.orig/arch/m68k/kernel/entry.S	2001-10-08 17:39:18.000000000 +0000
+++ linux/arch/m68k/kernel/entry.S	2002-07-20 01:08:22.000000000 +0000
@@ -184,7 +184,7 @@
 #if 0
 #if CONFIG_AMIGA
 SYMBOL_NAME_LABEL(ami_inthandler)
-	addql	#1,SYMBOL_NAME(irq_stat)+8	| local_irq_count
+	addql	#1,SYMBOL_NAME(irq_stat)+4	| local_irq_count
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
 
@@ -216,7 +216,7 @@
 SYMBOL_NAME_LABEL(inthandler)
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
-	addql	#1,SYMBOL_NAME(irq_stat)+8	| local_irq_count
+	addql	#1,SYMBOL_NAME(irq_stat)+4	| local_irq_count
 					|  put exception # in d0
 	bfextu %sp@(PT_VECTOR){#4,#10},%d0
 
@@ -235,7 +235,7 @@
 3:     	addql	#8,%sp			|  pop parameters off stack
 
 SYMBOL_NAME_LABEL(ret_from_interrupt)
-	subql	#1,SYMBOL_NAME(irq_stat)+8	| local_irq_count
+	subql	#1,SYMBOL_NAME(irq_stat)+4	| local_irq_count
 	jeq	1f
 2:
 	RESTORE_ALL
@@ -248,11 +248,8 @@
 	jhi	2b
 #endif
 	/* check if we need to do software interrupts */
-
-	movel	SYMBOL_NAME(irq_stat),%d0	| softirq_active
-	andl	SYMBOL_NAME(irq_stat)+4,%d0	| softirq_mask
+	tstl	SYMBOL_NAME(irq_stat)	| softirq_pending ?
 	jeq	SYMBOL_NAME(ret_from_exception)
-
 	pea	SYMBOL_NAME(ret_from_exception)
 	jra	SYMBOL_NAME(do_softirq)
 
@@ -642,10 +639,12 @@
 	.long SYMBOL_NAME(sys_setgid)
 	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
 	.long SYMBOL_NAME(sys_setfsgid)
-	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_pivot_root)
 	.long SYMBOL_NAME(sys_ni_syscall)
 	.long SYMBOL_NAME(sys_ni_syscall)
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_tkill)
 
 	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
--- linux.orig/arch/m68k/kernel/process.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/m68k/kernel/process.c	2002-07-20 01:08:37.000000000 +0000
@@ -136,6 +136,7 @@
 	register long retval __asm__ ("d0");
 	register long clone_arg __asm__ ("d1") = flags | CLONE_VM;
 
+	retval = __NR_clone;
 	__asm__ __volatile__
 	  ("clrl %%d2\n\t"
 	   "trap #0\n\t"		/* Linux/m68k system call */
@@ -145,14 +146,15 @@
 	   "movel %3,%%sp@-\n\t"	/* push argument */
 	   "jsr %4@\n\t"		/* call fn */
 	   "movel %0,%%d1\n\t"		/* pass exit value */
-	   "movel %2,%0\n\t"		/* exit */
+	   "movel %2,%%d0\n\t"		/* exit */
 	   "trap #0\n"
 	   "1:"
-	   : "=d" (retval)
-	   : "0" (__NR_clone), "i" (__NR_exit),
+	   : "+d" (retval)
+	   : "i" (__NR_clone), "i" (__NR_exit),
 	     "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
 	     "i" (-KTHREAD_SIZE)
-	   : "d0", "d2");
+	   : "d2");
+
 	pid = retval;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
--- linux.orig/arch/m68k/kernel/ptrace.c	2001-09-19 00:03:51.000000000 +0000
+++ linux/arch/m68k/kernel/ptrace.c	2002-07-20 01:08:30.000000000 +0000
@@ -103,7 +103,6 @@
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 {
 	struct task_struct *child;
-	unsigned long flags;
 	int ret;
 
 	lock_kernel();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/kernel/setup.c linux/arch/m68k/kernel/setup.c
--- linux.orig/arch/m68k/kernel/setup.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/kernel/setup.c	2002-07-20 01:08:40.000000000 +0000
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/seq_file.h>
 #include <linux/module.h>
 
 #include <asm/bootinfo.h>
@@ -85,7 +86,7 @@
 /* machine dependent timer functions */
 unsigned long (*mach_gettimeoffset) (void);
 void (*mach_gettod) (int*, int*, int*, int*, int*, int*);
-int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
+int (*mach_hwclk) (int, struct rtc_time*) = NULL;
 int (*mach_set_clock_mmss) (unsigned long) = NULL;
 void (*mach_reset)( void );
 void (*mach_halt)( void ) = NULL;
@@ -93,7 +94,6 @@
 long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
 #if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY) 
 void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
-void (*mach_floppy_eject) (void) = NULL;
 #endif
 #ifdef CONFIG_HEARTBEAT
 void (*mach_heartbeat) (int) = NULL;
@@ -110,7 +110,7 @@
 char *mach_sysrq_xlate = NULL;
 #endif
 
-#if defined(CONFIG_ISA)
+#if defined(CONFIG_ISA) && defined(MULTI_ISA)
 int isa_type;
 int isa_sex;
 #endif
@@ -388,7 +388,7 @@
 	paging_init();
 
 /* set ISA defs early as possible */
-#if defined(CONFIG_ISA)
+#if defined(CONFIG_ISA) && defined(MULTI_ISA)
 #if defined(CONFIG_Q40) 
 	if (MACH_IS_Q40) {
 	    isa_type = Q40_ISA;
@@ -408,7 +408,7 @@
 #endif
 }
 
-int get_cpuinfo(char * buffer)
+static int show_cpuinfo(struct seq_file *m, void *v)
 {
     const char *cpu, *mmu, *fpu;
     unsigned long clockfreq, clockfactor;
@@ -469,7 +469,7 @@
 
     clockfreq = loops_per_jiffy*HZ*clockfactor;
 
-    return(sprintf(buffer, "CPU:\t\t%s\n"
+    seq_printf(m, "CPU:\t\t%s\n"
 		   "MMU:\t\t%s\n"
 		   "FPU:\t\t%s\n"
 		   "Clocking:\t%lu.%1luMHz\n"
@@ -478,9 +478,28 @@
 		   cpu, mmu, fpu,
 		   clockfreq/1000000,(clockfreq/100000)%10,
 		   loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100,
-		   loops_per_jiffy));
+		   loops_per_jiffy);
+    return 0;
+}
 
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < 1 ? (void *)1 : NULL;
+}
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return NULL;
 }
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
 
 int get_hardware_list(char *buffer)
 {
@@ -495,7 +514,7 @@
 	strcpy(model, "Unknown m68k");
 
     len += sprintf(buffer+len, "Model:\t\t%s\n", model);
-    len += get_cpuinfo(buffer+len);
+    //len += get_cpuinfo(buffer+len);
     for (mem = 0, i = 0; i < m68k_num_memory; i++)
 	mem += m68k_memory[i].size;
     len += sprintf(buffer+len, "System Memory:\t%ldK\n", mem>>10);
@@ -514,11 +533,6 @@
 		mach_floppy_setup (str, ints);
 }
 
-void floppy_eject(void)
-{
-	if (mach_floppy_eject)
-		mach_floppy_eject();
-}
 #endif
 
 /* for "kbd-reset" cmdline param */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/kernel/signal.c linux/arch/m68k/kernel/signal.c
--- linux.orig/arch/m68k/kernel/signal.c	2001-01-24 23:21:28.000000000 +0000
+++ linux/arch/m68k/kernel/signal.c	2002-07-20 01:08:27.000000000 +0000
@@ -38,6 +38,7 @@
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/highuid.h>
+#include <linux/personality.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
@@ -1118,14 +1119,17 @@
 					continue;
 				/* FALLTHRU */
 
-			case SIGSTOP:
+			case SIGSTOP: {
+				struct signal_struct *sig;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if (!(current->p_pptr->sig->action[SIGCHLD-1]
-				      .sa.sa_flags & SA_NOCLDSTOP))
-					notify_parent(current, SIGCHLD);
+                                sig = current->p_pptr->sig;
+                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags 
+& SA_NOCLDSTOP))
+                                        notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
+			}
 
 			case SIGQUIT: case SIGILL: case SIGTRAP:
 			case SIGIOT: case SIGFPE: case SIGSEGV:
@@ -1135,10 +1139,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/m68k/kernel/sun3-head.S linux/arch/m68k/kernel/sun3-head.S
--- linux.orig/arch/m68k/kernel/sun3-head.S	2000-12-29 22:07:20.000000000 +0000
+++ linux/arch/m68k/kernel/sun3-head.S	2002-07-20 01:08:21.000000000 +0000
@@ -15,9 +15,6 @@
 .globl SYMBOL_NAME(bootup_user_stack)
 .globl SYMBOL_NAME(bootup_kernel_stack)
 .globl SYMBOL_NAME(pg0)
-.globl SYMBOL_NAME(empty_bad_page)
-.globl SYMBOL_NAME(empty_bad_page_table)
-.globl SYMBOL_NAME(empty_zero_page)
 .globl SYMBOL_NAME(swapper_pg_dir)
 .globl SYMBOL_NAME(kernel_pmd_table)
 .globl SYMBOL_NAME(availmem)
@@ -26,10 +23,7 @@
 | todo: all these should be in bss!
 SYMBOL_NAME(swapper_pg_dir):                .skip 0x2000
 SYMBOL_NAME(pg0):                           .skip 0x2000
-SYMBOL_NAME(empty_bad_page):                .skip 0x2000
-SYMBOL_NAME(empty_bad_page_table):          .skip 0x2000
 SYMBOL_NAME(kernel_pmd_table):              .skip 0x2000
-SYMBOL_NAME(empty_zero_page):               .skip 0x2000
 
 .globl SYMBOL_NAME(kernel_pg_dir)
 .equ    SYMBOL_NAME(kernel_pg_dir),SYMBOL_NAME(kernel_pmd_table)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/kernel/traps.c linux/arch/m68k/kernel/traps.c
--- linux.orig/arch/m68k/kernel/traps.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/kernel/traps.c	2002-07-20 01:08:37.000000000 +0000
@@ -23,7 +23,7 @@
 #include <linux/signal.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/types.h>
+#include <linux/module.h>
 #include <linux/a.out.h>
 #include <linux/user.h>
 #include <linux/string.h>
@@ -224,7 +224,7 @@
 		unsigned long addr = fp->un.fmt4.effaddr;
 
 		if (fslw & MMU060_MA)
-			addr = (addr + 7) & -8;
+			addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
 
 		errorcode = 1;
 		if (fslw & MMU060_DESC_ERR) {
@@ -258,16 +258,12 @@
 
 	set_fs(MAKE_MM_SEG(wbs));
 
-	asm volatile (".chip 68040");
-
 	if (iswrite)
-		asm volatile ("ptestw (%0)" : : "a" (addr));
+                asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
 	else
-		asm volatile ("ptestr (%0)" : : "a" (addr));
+                asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
 
-	asm volatile ("movec %%mmusr,%0" : "=r" (mmusr));
-
-	asm volatile (".chip 68k");
+        asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
 
 	set_fs(old_fs); 
 
@@ -816,15 +812,71 @@
 
 
 int kstack_depth_to_print = 48;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(unsigned long addr)
+{
+	struct module *mod;
+	int retval = 0;
+	extern char _stext, _etext;
+
+	if (addr >= (unsigned long) &_stext &&
+	    addr <= (unsigned long) &_etext)
+		return 1;
+
+#ifdef CONFIG_MODULES
+	for (mod = module_list; mod != &kernel_module; mod = mod->next) {
+		/* mod_bound tests for addr being inside the vmalloc'ed
+		 * module area. Of course it'd be better to test only
+		 * for the .text subset... */
+		if (mod_bound(addr, 0, mod)) {
+			retval = 1;
+			break;
+		}
+	}
+#endif
+
+	return retval;
+}
+
+void show_trace(unsigned long *stack)
+{
+	unsigned long *endstack;
+	unsigned long addr;
+	int i;
+
+	printk("Call Trace:");
+	addr = (unsigned long)stack + THREAD_SIZE - 1;
+	endstack = (unsigned long *)(addr & -THREAD_SIZE);
+	i = 0;
+	while (stack + 1 <= endstack) {
+		addr = *stack++;
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+		if (kernel_text_address(addr)) {
+			if (i % 4 == 0)
+				printk("\n       ");
+			printk(" [<%08lx>]", addr);
+			i++;
+		}
+	}
+	printk("\n");
+}
 
-/* MODULE_RANGE is a guess of how much space is likely to be
-   vmalloced.  */
-#define MODULE_RANGE (8*1024*1024)
+void show_trace_task(struct task_struct *tsk)
+{
+	show_trace((unsigned long *)tsk->thread.esp0);
+}
 
 static void dump_stack(struct frame *fp)
 {
-	unsigned long *stack, *endstack, addr, module_start, module_end;
-	extern char _start, _etext;
+	unsigned long *stack, *endstack, addr;
 	int i;
 
 	addr = (unsigned long)&fp->un;
@@ -881,7 +933,7 @@
 	}
 
 	stack = (unsigned long *)addr;
-	endstack = (unsigned long *)PAGE_ALIGN(addr);
+	endstack = (unsigned long *)((addr + THREAD_SIZE - 1) & -THREAD_SIZE);
 
 	printk("Stack from %08lx:", (unsigned long)stack);
 	for (i = 0; i < kstack_depth_to_print; i++) {
@@ -891,32 +943,10 @@
 			printk("\n       ");
 		printk(" %08lx", *stack++);
 	}
+	printk("\n");
+	show_trace((unsigned long *)addr);
 
-	printk ("\nCall Trace:");
-	stack = (unsigned long *) addr;
-	i = 0;
-	module_start = VMALLOC_START;
-	module_end = module_start + MODULE_RANGE;
-	while (stack + 1 <= endstack) {
-		addr = *stack++;
-		/*
-		 * If the address is either in the text segment of the
-		 * kernel, or in the region which contains vmalloc'ed
-		 * memory, it *may* be the address of a calling
-		 * routine; if so, print it so that someone tracing
-		 * down the cause of the crash will be able to figure
-		 * out the call path that was taken.
-		 */
-		if (((addr >= (unsigned long) &_start) &&
-		     (addr <= (unsigned long) &_etext)) ||
-		    ((addr >= module_start) && (addr <= module_end))) {
-			if (i % 4 == 0)
-				printk("\n       ");
-			printk(" [<%08lx>]", addr);
-			i++;
-		}
-	}
-	printk("\nCode: ");
+	printk("Code: ");
 	for (i = 0; i < 10; i++)
 		printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);
 	printk ("\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/mac/config.c linux/arch/m68k/mac/config.c
--- linux.orig/arch/m68k/mac/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/mac/config.c	2002-07-20 01:08:34.000000000 +0000
@@ -64,7 +64,7 @@
 /* Mac specific timer functions */
 extern void mac_gettod (int *, int *, int *, int *, int *, int *);
 extern unsigned long mac_gettimeoffset (void);
-extern int mac_hwclk (int, struct hwclk_time *);
+extern int mac_hwclk (int, struct rtc_time *);
 extern int mac_set_clock_mmss (unsigned long);
 extern int mac_get_irq_list(char *);
 extern void iop_preinit(void);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/mac/debug.c linux/arch/m68k/mac/debug.c
--- linux.orig/arch/m68k/mac/debug.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/mac/debug.c	2002-07-20 01:08:40.000000000 +0000
@@ -235,32 +235,6 @@
     }
 }
 
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(DEBUG_SERIAL)
-int mac_sccb_console_wait_key(struct console *co)
-{
-    int i;
-    do {
-	for( i = uSEC; i > 0; --i )
-		barrier();
-    } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */
-    for( i = uSEC; i > 0; --i )
-	barrier();
-    return( scc.cha_b_data );
-}
-
-int mac_scca_console_wait_key(struct console *co)
-{
-    int i;
-    do {
-	for( i = uSEC; i > 0; --i )
-		barrier();
-    } while( !(scc.cha_a_ctrl & 0x01) ); /* wait for rx buf filled */
-    for( i = uSEC; i > 0; --i )
-	barrier();
-    return( scc.cha_a_data );
-}
-#endif
-
 /* The following two functions do a quick'n'dirty initialization of the MFP or
  * SCC serial ports. They're used by the debugging interface, kgdb, and the
  * serial console code. */
@@ -395,18 +369,12 @@
 	/* Mac modem port */
 	mac_init_scc_port( B9600|CS8, 0 );
 	mac_console_driver.write = mac_scca_console_write;
-#ifdef CONFIG_SERIAL_CONSOLE
-	mac_console_driver.wait_key = mac_scca_console_wait_key;
-#endif
 	scc_port = 0;
     }
     else if (!strcmp( m68k_debug_device, "ser2" )) {
 	/* Mac printer port */
 	mac_init_scc_port( B9600|CS8, 1 );
 	mac_console_driver.write = mac_sccb_console_write;
-#ifdef CONFIG_SERIAL_CONSOLE
-	mac_console_driver.wait_key = mac_sccb_console_wait_key;
-#endif
 	scc_port = 1;
     }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/mac/misc.c linux/arch/m68k/mac/misc.c
--- linux.orig/arch/m68k/mac/misc.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/mac/misc.c	2002-07-20 01:08:37.000000000 +0000
@@ -11,7 +11,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/time.h>
-
+#include <linux/rtc.h>
 #include <linux/mm.h>
 
 #include <linux/adb.h>
@@ -595,7 +595,7 @@
  * Read/write the hardware clock.
  */
 
-int mac_hwclk(int op, struct hwclk_time *t)
+int mac_hwclk(int op, struct rtc_time *t)
 {
 	unsigned long now;
 
@@ -613,19 +613,19 @@
 			now = 0;
 		}
 
-		t->wday = 0;
+		t->tm_wday = 0;
 		unmktime(now, 0,
-			 &t->year, &t->mon, &t->day,
-			 &t->hour, &t->min, &t->sec);
+			 &t->tm_year, &t->tm_mon, &t->tm_mday,
+			 &t->tm_hour, &t->tm_min, &t->tm_sec);
 		printk("mac_hwclk: read %04d-%02d-%-2d %02d:%02d:%02d\n",
-			t->year + 1900, t->mon + 1, t->day, t->hour, t->min, t->sec);
+			t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
 	} else { /* write */
 		printk("mac_hwclk: tried to write %04d-%02d-%-2d %02d:%02d:%02d\n",
-			t->year + 1900, t->mon + 1, t->day, t->hour, t->min, t->sec);
+			t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
 
 #if 0	/* it trashes my rtc */
-		now = mktime(t->year + 1900, t->mon + 1, t->day,
-			     t->hour, t->min, t->sec);
+		now = mktime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+			     t->tm_hour, t->tm_min, t->tm_sec);
 
 		if (macintosh_config->adb_type == MAC_ADB_II) {
 			via_write_time(now);
@@ -648,11 +648,11 @@
 
 int mac_set_clock_mmss (unsigned long nowtime)
 {
-	struct hwclk_time now;
+	struct rtc_time now;
 
 	mac_hwclk(0, &now);
-	now.sec = nowtime % 60;
-	now.min = (nowtime / 60) % 60;
+	now.tm_sec = nowtime % 60;
+	now.tm_min = (nowtime / 60) % 60;
 	mac_hwclk(1, &now);
 
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/math-emu/fp_emu.h linux/arch/m68k/math-emu/fp_emu.h
--- linux.orig/arch/m68k/math-emu/fp_emu.h	2001-02-13 22:13:43.000000000 +0000
+++ linux/arch/m68k/math-emu/fp_emu.h	2002-07-20 01:08:22.000000000 +0000
@@ -38,7 +38,9 @@
 #ifndef _FP_EMU_H
 #define _FP_EMU_H
 
+#ifdef __ASSEMBLY__
 #include "../kernel/m68k_defs.h"
+#endif
 #include <asm/math-emu.h>
 
 #ifndef __ASSEMBLY__
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/math-emu/multi_arith.h linux/arch/m68k/math-emu/multi_arith.h
--- linux.orig/arch/m68k/math-emu/multi_arith.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/math-emu/multi_arith.h	2002-07-20 01:08:33.000000000 +0000
@@ -376,7 +376,7 @@
 	asm ("divu.l %2,%1:%0" : "=d" (quot), "=d" (rem)		\
 		: "dm" (div), "1" (srch), "0" (srcl))
 #define fp_add64(dest1, dest2, src1, src2) ({				\
-	asm ("add.l %1,%0" : "=d,=dm" (dest2)				\
+	asm ("add.l %1,%0" : "=d,dm" (dest2)				\
 		: "dm,d" (src2), "0,0" (dest2));			\
 	asm ("addx.l %1,%0" : "=d" (dest1)				\
 		: "d" (src1), "0" (dest1));				\
@@ -391,14 +391,14 @@
 		: "d" (0), "0" (dest->m32[0]));				\
 })
 #define fp_sub64(dest, src) ({						\
-	asm ("sub.l %1,%0" : "=d,=dm" (dest.m32[1])			\
+	asm ("sub.l %1,%0" : "=d,dm" (dest.m32[1])			\
 		: "dm,d" (src.m32[1]), "0,0" (dest.m32[1]));		\
 	asm ("subx.l %1,%0" : "=d" (dest.m32[0])			\
 		: "d" (src.m32[0]), "0" (dest.m32[0]));			\
 })
 #define fp_sub96c(dest, srch, srcm, srcl) ({				\
 	char carry;							\
-	asm ("sub.l %1,%0" : "=d,=dm" (dest.m32[2])			\
+	asm ("sub.l %1,%0" : "=d,dm" (dest.m32[2])			\
 		: "dm,d" (srcl), "0,0" (dest.m32[2]));			\
 	asm ("subx.l %1,%0" : "=d" (dest.m32[1])			\
 		: "d" (srcm), "0" (dest.m32[1]));			\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/mm/fault.c linux/arch/m68k/mm/fault.c
--- linux.orig/arch/m68k/mm/fault.c	2001-03-19 20:35:10.000000000 +0000
+++ linux/arch/m68k/mm/fault.c	2002-07-20 01:08:35.000000000 +0000
@@ -152,22 +152,25 @@
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
+
+ survive:
 	fault = handle_mm_fault(mm, vma, address, write);
 #ifdef DEBUG
  	printk("handle_mm_fault returns %d\n",fault);
 #endif
-	if (fault < 0)
-		goto out_of_memory;
-	if (!fault)
+	switch (fault) {
+	case 1:
+		current->min_flt++;
+		break;
+	case 2:
+		current->maj_flt++;
+		break;
+	case 0:
 		goto bus_err;
+	default:
+		goto out_of_memory;
+	}
 
-	/* There seems to be a missing invalidate somewhere in do_no_page.
-	 * Until I found it, this one cures the problem and makes
-	 * 1.2 run on the 68040 (Martin Apel).
-	 */
-	#warning should be obsolete now...
-	if (CPU_IS_040_OR_060)
-		flush_tlb_page(vma, address);
 	up_read(&mm->mmap_sem);
 	return 0;
 
@@ -176,6 +179,14 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
+	up_read(&mm->mmap_sem);
+	if (current->pid == 1) {
+		current->policy |= SCHED_YIELD;
+		schedule();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c
--- linux.orig/arch/m68k/mm/memory.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/mm/memory.c	2002-07-20 01:08:25.000000000 +0000
@@ -253,10 +253,6 @@
 	if (voff == 0)
 		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
 
-	/* As a special case allow `__pa(high_memory)'.  */
-	if (voff == 0)
-		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
-
 	return mm_vtop_fallback(vaddr);
 }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/mvme147/config.c linux/arch/m68k/mvme147/config.c
--- linux.orig/arch/m68k/mvme147/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/mvme147/config.c	2002-07-20 01:08:29.000000000 +0000
@@ -48,7 +48,7 @@
 extern unsigned long mvme147_gettimeoffset (void);
 extern void mvme147_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
-extern int mvme147_hwclk (int, struct hwclk_time *);
+extern int mvme147_hwclk (int, struct rtc_time *);
 extern int mvme147_set_clock_mmss (unsigned long);
 extern void mvme147_check_partition (struct gendisk *hd, unsigned int dev);
 extern void mvme147_reset (void);
@@ -184,7 +184,7 @@
 	return ((b>>4)*10 + (b&15));
 }
 
-int mvme147_hwclk(int op, struct hwclk_time *t)
+int mvme147_hwclk(int op, struct rtc_time *t)
 {
 	return 0;
 }
@@ -241,31 +241,7 @@
 	restore_flags(flags);
 }
 
-
-static int m147_scc_wait_key (struct console *co)
-{
-	volatile unsigned char *p = (volatile char *)M147_SCC_A_ADDR;
-	unsigned long	flags;
-	int		c;
-
-	/* wait for rx buf filled */
-	while ((*p & 0x01) == 0)
-		;
-
-	save_flags(flags);
-	cli();
-
-	*p = 8;
-	scc_delay();
-	c = *p;
-
-	restore_flags(flags);
-	return c;
-}
-
-
 void mvme147_init_console_port (struct console *co, int cflag)
 {
 	co->write    = m147_scc_write;
-	co->wait_key = m147_scc_wait_key;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/mvme16x/config.c linux/arch/m68k/mvme16x/config.c
--- linux.orig/arch/m68k/mvme16x/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/mvme16x/config.c	2002-07-20 01:08:31.000000000 +0000
@@ -52,7 +52,7 @@
 extern unsigned long mvme16x_gettimeoffset (void);
 extern void mvme16x_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
-extern int mvme16x_hwclk (int, struct hwclk_time *);
+extern int mvme16x_hwclk (int, struct rtc_time *);
 extern int mvme16x_set_clock_mmss (unsigned long);
 extern void mvme16x_check_partition (struct gendisk *hd, unsigned int dev);
 extern void mvme16x_mksound( unsigned int count, unsigned int ticks );
@@ -291,7 +291,7 @@
 	return ((b>>4)*10 + (b&15));
 }
 
-int mvme16x_hwclk(int op, struct hwclk_time *t)
+int mvme16x_hwclk(int op, struct rtc_time *t)
 {
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/q40/config.c linux/arch/m68k/q40/config.c
--- linux.orig/arch/m68k/q40/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/q40/config.c	2002-07-20 01:08:37.000000000 +0000
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/major.h>
 #include <linux/serial_reg.h>
+#include <linux/rtc.h>
 
 #include <asm/io.h>
 #include <asm/rtc.h>
@@ -36,7 +37,6 @@
 #include <asm/q40_master.h>
 #include <asm/keyboard.h>
 
-extern void floppy_eject(void);
 extern void floppy_setup(char *str, int *ints);
 
 extern int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
@@ -56,7 +56,7 @@
 extern unsigned long q40_gettimeoffset (void);
 extern void q40_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
-extern int q40_hwclk (int, struct hwclk_time *);
+extern int q40_hwclk (int, struct rtc_time *);
 extern int q40_set_clock_mmss (unsigned long);
 extern void q40_reset (void);
 void q40_halt(void);
@@ -73,10 +73,8 @@
 
 extern int ql_ticks;
 
-static int q40_wait_key(struct console *co){return 0;}
 static struct console q40_console_driver = {
 	name:		"debug",
-	wait_key:	q40_wait_key,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
 };
@@ -298,14 +296,14 @@
 extern void q40_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec)
 {
-	RTC_CTRL |= RTC_READ;
-	*year = bcd2bin (RTC_YEAR);
-	*mon = bcd2bin (RTC_MNTH);
-	*day = bcd2bin (RTC_DATE);
-	*hour = bcd2bin (RTC_HOUR);
-	*min = bcd2bin (RTC_MINS);
-	*sec = bcd2bin (RTC_SECS);
-	RTC_CTRL &= ~(RTC_READ);
+	Q40_RTC_CTRL |= Q40_RTC_READ;
+	*year = bcd2bin (Q40_RTC_YEAR);
+	*mon = bcd2bin (Q40_RTC_MNTH);
+	*day = bcd2bin (Q40_RTC_DATE);
+	*hour = bcd2bin (Q40_RTC_HOUR);
+	*min = bcd2bin (Q40_RTC_MINS);
+	*sec = bcd2bin (Q40_RTC_SECS);
+	Q40_RTC_CTRL &= ~(Q40_RTC_READ);
 
 }
 
@@ -326,39 +324,39 @@
  * };
  */
 
-int q40_hwclk(int op, struct hwclk_time *t)
+int q40_hwclk(int op, struct rtc_time *t)
 {
         if (op)
 	{	/* Write.... */
-	        RTC_CTRL |= RTC_WRITE;
+	        Q40_RTC_CTRL |= Q40_RTC_WRITE;
 
-		RTC_SECS = bin2bcd(t->sec);
-		RTC_MINS = bin2bcd(t->min);
-		RTC_HOUR = bin2bcd(t->hour);
-		RTC_DATE = bin2bcd(t->day);
-		RTC_MNTH = bin2bcd(t->mon + 1);
-		RTC_YEAR = bin2bcd(t->year%100);
-		if (t->wday >= 0)
-			RTC_DOW = bin2bcd(t->wday+1);
+		Q40_RTC_SECS = bin2bcd(t->tm_sec);
+		Q40_RTC_MINS = bin2bcd(t->tm_min);
+		Q40_RTC_HOUR = bin2bcd(t->tm_hour);
+		Q40_RTC_DATE = bin2bcd(t->tm_mday);
+		Q40_RTC_MNTH = bin2bcd(t->tm_mon + 1);
+		Q40_RTC_YEAR = bin2bcd(t->tm_year%100);
+		if (t->tm_wday >= 0)
+			Q40_RTC_DOW = bin2bcd(t->tm_wday+1);
 
-	        RTC_CTRL &= ~(RTC_WRITE);
+	        Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
 	}
 	else
 	{	/* Read....  */
-	  RTC_CTRL |= RTC_READ;
+	  Q40_RTC_CTRL |= Q40_RTC_READ;
 
-	  t->year = bcd2bin (RTC_YEAR);
-	  t->mon  = bcd2bin (RTC_MNTH)-1;
-	  t->day  = bcd2bin (RTC_DATE);
-	  t->hour = bcd2bin (RTC_HOUR);
-	  t->min  = bcd2bin (RTC_MINS);
-	  t->sec  = bcd2bin (RTC_SECS);
+	  t->tm_year = bcd2bin (Q40_RTC_YEAR);
+	  t->tm_mon  = bcd2bin (Q40_RTC_MNTH)-1;
+	  t->tm_mday = bcd2bin (Q40_RTC_DATE);
+	  t->tm_hour = bcd2bin (Q40_RTC_HOUR);
+	  t->tm_min  = bcd2bin (Q40_RTC_MINS);
+	  t->tm_sec  = bcd2bin (Q40_RTC_SECS);
 
-	  RTC_CTRL &= ~(RTC_READ);
+	  Q40_RTC_CTRL &= ~(Q40_RTC_READ);
 	  
-	  if (t->year < 70)
-	    t->year += 100;
-	  t->wday = bcd2bin(RTC_DOW)-1;
+	  if (t->tm_year < 70)
+	    t->tm_year += 100;
+	  t->tm_wday = bcd2bin(Q40_RTC_DOW)-1;
 
 	}
 
@@ -378,16 +376,16 @@
 	int rtc_minutes;
 
 
-	rtc_minutes = bcd2bin (RTC_MINS);
+	rtc_minutes = bcd2bin (Q40_RTC_MINS);
 
 	if ((rtc_minutes < real_minutes
 		? real_minutes - rtc_minutes
 			: rtc_minutes - real_minutes) < 30)
 	{	   
-	        RTC_CTRL |= RTC_WRITE;
-		RTC_MINS = bin2bcd(real_minutes);
-		RTC_SECS = bin2bcd(real_seconds);
-		RTC_CTRL &= ~(RTC_WRITE);
+	        Q40_RTC_CTRL |= Q40_RTC_WRITE;
+		Q40_RTC_MINS = bin2bcd(real_minutes);
+		Q40_RTC_SECS = bin2bcd(real_seconds);
+		Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
 	}
 	else
 		retval = -1;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/q40/q40ints.c linux/arch/m68k/q40/q40ints.c
--- linux.orig/arch/m68k/q40/q40ints.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/q40/q40ints.c	2002-07-20 01:08:31.000000000 +0000
@@ -231,7 +231,6 @@
 
 static void q40_timer_int (int irq, void * dev, struct pt_regs * regs)
 {
-#if (HZ==100)
     ql_ticks = ql_ticks ? 0 : 1;
     if (sound_ticks)
       {
@@ -240,16 +239,9 @@
 	*DAC_LEFT=sval;
 	*DAC_RIGHT=sval;
       }
-#if defined(CONFIG_Q40RTC) || defined(CONFIG_GEN_RTC)
-    if (gen_rtc_irq_ctrl && (q40rtc_oldsecs != RTC_SECS))
-      {
-	q40rtc_oldsecs = RTC_SECS;
-	gen_rtc_irq_flags = RTC_UIE;
-	gen_rtc_interrupt(0);
-      }
-#endif
+
     if (ql_ticks) return;
-#endif
+
     q40_timer_routine(irq, dev, regs);
 }
 
@@ -258,30 +250,14 @@
     int timer_irq;
 
     q40_timer_routine = timer_routine;
-
-#if (HZ==10000)
-    timer_irq=Q40_IRQ_SAMPLE;
-#else
     timer_irq=Q40_IRQ_FRAME;
-#endif
-
-    /*printk("registering sched/timer IRQ %d, handler %p\n", timer_irq,q40_timer_int);*/
-    /*printk("timer routine %p\n",q40_timer_routine);*/
 
     if (request_irq(timer_irq, q40_timer_int, 0,
 				"timer", q40_timer_int))
 	panic ("Couldn't register timer int");
 
-#if (HZ==10000)
-    master_outb(SAMPLE_LOW,SAMPLE_RATE_REG);
-    master_outb(-1,SAMPLE_CLEAR_REG);
-    master_outb(1,SAMPLE_ENABLE_REG);
-#else
-    master_outb(-1,FRAME_CLEAR_REG);   /* not necessary ? */
-#if (HZ==100)
+    master_outb(-1,FRAME_CLEAR_REG);
     master_outb( 1,FRAME_RATE_REG);
-#endif
-#endif
 }
 
 
@@ -294,20 +270,20 @@
 struct IRQ_TABLE{ unsigned mask; int irq ;};
 #if 0
 static struct IRQ_TABLE iirqs[]={
-  {IRQ_FRAME_MASK,Q40_IRQ_FRAME},
-  {IRQ_KEYB_MASK,Q40_IRQ_KEYBOARD},
+  {Q40_IRQ_FRAME_MASK,Q40_IRQ_FRAME},
+  Q40_{IRQ_KEYB_MASK,Q40_IRQ_KEYBOARD},
   {0,0}};
 #endif
 static struct IRQ_TABLE eirqs[]={
-  {IRQ3_MASK,3},                   /* ser 1 */
-  {IRQ4_MASK,4},                   /* ser 2 */
-  {IRQ14_MASK,14},                 /* IDE 1 */
-  {IRQ15_MASK,15},                 /* IDE 2 */
-  {IRQ6_MASK,6},                   /* floppy */
-  {IRQ7_MASK,7},                   /* par */
+  {Q40_IRQ3_MASK,3},                   /* ser 1 */
+  {Q40_IRQ4_MASK,4},                   /* ser 2 */
+  {Q40_IRQ14_MASK,14},                 /* IDE 1 */
+  {Q40_IRQ15_MASK,15},                 /* IDE 2 */
+  {Q40_IRQ6_MASK,6},                   /* floppy, handled elsewhere */
+  {Q40_IRQ7_MASK,7},                   /* par */
 
-  {IRQ5_MASK,5},
-  {IRQ10_MASK,10},
+  {Q40_IRQ5_MASK,5},
+  {Q40_IRQ10_MASK,10},
 
 
 
@@ -322,7 +298,7 @@
 
 #define IRQ_INPROGRESS 1
 /*static unsigned short saved_mask;*/
-static int do_tint=0;
+//static int do_tint=0;
 
 #define DEBUG_Q40INT
 /*#define IP_USE_DISABLE *//* would be nice, but crashes ???? */
@@ -334,101 +310,82 @@
 /* got level 2 interrupt, dispatch to ISA or keyboard/timer IRQs */
 void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
 {
-  unsigned mir;
-	unsigned mer;
-	int irq,i;
+  unsigned mir, mer;
+  int irq,i;
 
  repeat:
   mir=master_inb(IIRQ_REG);
-  if (mir&IRQ_FRAME_MASK) 
-    { /* dont loose  ticks */
-      do_tint++;
-      master_outb(-1,FRAME_CLEAR_REG);
-    }
-	if ((mir&IRQ_SER_MASK) || (mir&IRQ_EXT_MASK)) 
-	  {
-	    /* some ISA dev caused the int */
-	    mer=master_inb(EIRQ_REG);
-	    for (i=0; eirqs[i].mask; i++)
-	      {
-		if (mer&(eirqs[i].mask)) 
-		  {
-		    irq=eirqs[i].irq;
+  if (mir&Q40_IRQ_FRAME_MASK) {
+	  irq_tab[Q40_IRQ_FRAME].count++;
+	  irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);   
+	  master_outb(-1,FRAME_CLEAR_REG);
+  }
+  if ((mir&Q40_IRQ_SER_MASK) || (mir&Q40_IRQ_EXT_MASK)) {
+	  mer=master_inb(EIRQ_REG);
+	  for (i=0; eirqs[i].mask; i++) {
+		  if (mer&(eirqs[i].mask)) {
+			  irq=eirqs[i].irq;
 /*
  * There is a little mess wrt which IRQ really caused this irq request. The
  * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they
  * are read - which is long after the request came in. In theory IRQs should
  * not just go away but they occassionally do
  */
-	      if (irq>4 && irq<=15 && mext_disabled) 
-		{
-		  /*aliased_irq++;*/
-		  goto iirq;
-		}
-		    if (irq_tab[irq].handler == q40_defhand )
-		      {
-			printk("handler for IRQ %d not defined\n",irq);
-			continue; /* ignore uninited INTs :-( */
-		      }
-		    if ( irq_tab[irq].state & IRQ_INPROGRESS )
-		      {
-		  /* some handlers do sti() for irq latency reasons, */
-		  /* however reentering an active irq handler is not permitted */
+			  if (irq>4 && irq<=15 && mext_disabled) {
+				  /*aliased_irq++;*/
+				  goto iirq;
+			  }
+			  if (irq_tab[irq].handler == q40_defhand ) {
+				  printk("handler for IRQ %d not defined\n",irq);
+				  continue; /* ignore uninited INTs :-( */
+			  }
+			  if ( irq_tab[irq].state & IRQ_INPROGRESS ) {
+				  /* some handlers do sti() for irq latency reasons, */
+				  /* however reentering an active irq handler is not permitted */
 #ifdef IP_USE_DISABLE
-		  /* in theory this is the better way to do it because it still */
-		  /* lets through eg the serial irqs, unfortunately it crashes */
-		  disable_irq(irq);
-		  disabled=1;
+				  /* in theory this is the better way to do it because it still */
+				  /* lets through eg the serial irqs, unfortunately it crashes */
+				  disable_irq(irq);
+				  disabled=1;
 #else
-			/*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */
-		  fp->sr = (((fp->sr) & (~0x700))+0x200);
-			disabled=1;
-#endif
-		  goto iirq;
-		      }
-	      irq_tab[irq].count++; 
-		    irq_tab[irq].state |= IRQ_INPROGRESS;
-		    irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
-	      irq_tab[irq].state &= ~IRQ_INPROGRESS;
-
-		    /* naively enable everything, if that fails than    */
-		    /* this function will be reentered immediately thus */
-		    /* getting another chance to disable the IRQ        */
-
-		    if ( disabled ) 
-		      {
+				  /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */
+				  fp->sr = (((fp->sr) & (~0x700))+0x200);
+				  disabled=1;
+#endif
+				  goto iirq;
+			  }
+			  irq_tab[irq].count++; 
+			  irq_tab[irq].state |= IRQ_INPROGRESS;
+			  irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
+			  irq_tab[irq].state &= ~IRQ_INPROGRESS;
+			  
+			  /* naively enable everything, if that fails than    */
+			  /* this function will be reentered immediately thus */
+			  /* getting another chance to disable the IRQ        */
+			  
+			  if ( disabled ) {
 #ifdef IP_USE_DISABLE
-			if (irq>4){
-			  disabled=0;
-			  enable_irq(irq);}
+				  if (irq>4){
+					  disabled=0;
+					  enable_irq(irq);}
 #else
-			disabled=0;
-			/*printk("reenabling irq %d\n",irq); */
+				  disabled=0;
+				  /*printk("reenabling irq %d\n",irq); */
 #endif
-		      }
-	      goto repeat;  /* return;  */
+			  }
+// used to do 'goto repeat;' her, this delayed bh processing too long
+			  return;
 		  }
-	      }
-	    if (mer && ccleirq>0 && !aliased_irq) 
-	      printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
-	  } 
- iirq:
-	mir=master_inb(IIRQ_REG);
-	if (mir&IRQ_FRAME_MASK) 
-	  {
-	    do_tint++;
-	    master_outb(-1,FRAME_CLEAR_REG);
-	  }
-	for(;do_tint>0;do_tint--) 
-	  {
-	    irq_tab[Q40_IRQ_FRAME].count++;
-	    irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);    
-	  }
-	if (mir&IRQ_KEYB_MASK) /* may handle it even if actually disabled*/
-	  {
-	    irq_tab[Q40_IRQ_KEYBOARD].count++;
-	    irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
 	  }
+	  if (mer && ccleirq>0 && !aliased_irq) 
+		  printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
+  } 
+ iirq:
+  mir=master_inb(IIRQ_REG);
+  if (mir&Q40_IRQ_KEYB_MASK) {
+	  irq_tab[Q40_IRQ_KEYBOARD].count++;
+	  irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
+  }
 }
 
 int q40_get_irq_list (char *buf)
@@ -451,25 +408,16 @@
 
 static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
 {
-#if 0
 	printk ("Unknown q40 interrupt 0x%02x\n", irq);
-#endif
 }
 static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs)
 {
-#if 0
-        if (ints_inited)
-#endif
-	  printk ("Uninitialised interrupt level %d\n", lev);
-#if 0
-	else
-	  printk ("Interrupt before interrupt initialisation\n");
-#endif
+	printk ("Uninitialised interrupt level %d\n", lev);
 }
 
  void (*q40_sys_default_handler[SYS_IRQS]) (int, void *, struct pt_regs *) = {
-   sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler,
-   sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler
+	 sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler,
+	 sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler
  };
 
 
@@ -489,16 +437,15 @@
 void q40_disable_irq (unsigned int irq)
 {
   /* disable ISA iqs : only do something if the driver has been
-  * verified to be Q40 "compatible" - right now IDE, NE2K
-  * Any driver should not attempt to sleep accross disable_irq !!
-  */
+   * verified to be Q40 "compatible" - right now IDE, NE2K
+   * Any driver should not attempt to sleep accross disable_irq !!
+   */
 
-  if ( irq>=5 && irq<=15 ) 
-    {
+  if ( irq>=5 && irq<=15 ) {
     master_outb(0,EXT_ENABLE_REG);
-      mext_disabled++;
-      if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled);
-    }
+    mext_disabled++;
+    if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled);
+  }
 }
 
 unsigned long q40_probe_irq_on (void)
@@ -513,4 +460,5 @@
 /*
  * Local variables:
  * compile-command: "m68k-linux-gcc -D__KERNEL__ -I/home/rz/lx/linux-2.2.6/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -ffixed-a2 -m68040   -c -o q40ints.o q40ints.c"
+ * End:
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/sun3/config.c linux/arch/m68k/sun3/config.c
--- linux.orig/arch/m68k/sun3/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/sun3/config.c	2002-07-20 01:08:38.000000000 +0000
@@ -42,7 +42,7 @@
 extern void idprom_init (void);
 extern void sun3_gettod (int *yearp, int *monp, int *dayp,
                    int *hourp, int *minp, int *secp);
-extern int sun3_hwclk(int set, struct hwclk_time *t);
+extern int sun3_hwclk(int set, struct rtc_time *t);
 
 extern void sun_serial_setup(void);
 volatile char* clock_va; 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/sun3/intersil.c linux/arch/m68k/sun3/intersil.c
--- linux.orig/arch/m68k/sun3/intersil.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/sun3/intersil.c	2002-07-20 01:08:22.000000000 +0000
@@ -11,6 +11,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/rtc.h>
 
 #include <asm/system.h>
 #include <asm/rtc.h>
@@ -57,7 +58,7 @@
 
 /* get/set hwclock */
 
-int sun3_hwclk(int set, struct hwclk_time *t)
+int sun3_hwclk(int set, struct rtc_time *t)
 {
 	volatile struct intersil_dt *todintersil;
 	unsigned long flags;
@@ -71,23 +72,23 @@
 	/* set or read the clock */
 	if(set) {
 		todintersil->csec = 0;
-		todintersil->hour = t->hour;
-		todintersil->minute = t->min;
-		todintersil->second = t->sec;
-		todintersil->month = t->mon;
-		todintersil->day = t->day;
-		todintersil->year = t->year - 68;
-		todintersil->weekday = t->wday;
+		todintersil->hour = t->tm_hour;
+		todintersil->minute = t->tm_min;
+		todintersil->second = t->tm_sec;
+		todintersil->month = t->tm_mon;
+		todintersil->day = t->tm_mday;
+		todintersil->year = t->tm_year - 68;
+		todintersil->weekday = t->tm_wday;
 	} else {
 		/* read clock */
-		t->sec = todintersil->csec;
-		t->hour = todintersil->hour;
-		t->min = todintersil->minute;
-		t->sec = todintersil->second;
-		t->mon = todintersil->month;
-		t->day = todintersil->day;
-		t->year = todintersil->year + 68;
-		t->wday = todintersil->weekday;
+		t->tm_sec = todintersil->csec;
+		t->tm_hour = todintersil->hour;
+		t->tm_min = todintersil->minute;
+		t->tm_sec = todintersil->second;
+		t->tm_mon = todintersil->month;
+		t->tm_mday = todintersil->day;
+		t->tm_year = todintersil->year + 68;
+		t->tm_wday = todintersil->weekday;
 	}
 
 	intersil_clock->cmd_reg = START_VAL;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/sun3/sun3dvma.c linux/arch/m68k/sun3/sun3dvma.c
--- linux.orig/arch/m68k/sun3/sun3dvma.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/sun3/sun3dvma.c	2002-07-20 01:08:28.000000000 +0000
@@ -14,6 +14,8 @@
 #include <asm/pgtable.h>
 #include <asm/dvma.h>
 
+#undef DVMA_DEBUG
+
 #ifdef CONFIG_SUN3X
 extern void dvma_unmap_iommu(unsigned long baddr, int len);
 #else
@@ -22,6 +24,10 @@
 }
 #endif
 
+#ifdef CONFIG_SUN3
+extern void sun3_dvma_init(void);
+#endif
+
 unsigned long iommu_use[IOMMU_TOTAL_ENTRIES];
 
 #define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT)
@@ -39,6 +45,60 @@
 static struct list_head hole_cache;
 static struct hole initholes[64];
 
+#ifdef DVMA_DEBUG
+
+static unsigned long dvma_allocs = 0;
+static unsigned long dvma_frees = 0;
+static unsigned long long dvma_alloc_bytes = 0;
+static unsigned long long dvma_free_bytes = 0;
+
+static void print_use(void) 
+{
+	
+	int i;
+	int j = 0;
+
+	printk("dvma entry usage:\n");
+	
+	for(i = 0; i < IOMMU_TOTAL_ENTRIES; i++) {
+		if(!iommu_use[i])
+			continue;
+		
+		j++;
+
+		printk("dvma entry: %08lx len %08lx\n", 
+		       ( i << DVMA_PAGE_SHIFT) + DVMA_START,
+		       iommu_use[i]);
+	}
+
+	printk("%d entries in use total\n", j);
+
+	printk("allocation/free calls: %lu/%lu\n", dvma_allocs, dvma_frees);
+	printk("allocation/free bytes: %Lx/%Lx\n", dvma_alloc_bytes, 
+	       dvma_free_bytes);
+}
+
+static void print_holes(struct list_head *holes)
+{
+	
+	struct list_head *cur;
+	struct hole *hole;
+
+	printk("listing dvma holes\n");
+	list_for_each(cur, holes) {
+		hole = list_entry(cur, struct hole, list);
+		
+		if((hole->start == 0) && (hole->end == 0) && (hole->size == 0))
+			continue;
+		
+		printk("hole: start %08lx end %08lx size %08lx\n", hole->start, hole->end, hole->size);
+	}
+	
+	printk("end of hole listing...\n");
+	
+}
+#endif DVMA_DEBUG
+
 static inline int refill(void)
 {
 
@@ -93,7 +153,11 @@
 	struct hole *hole;
 
 	if(list_empty(&hole_list)) {
-		printk("out of dvma holes!\n");
+#ifdef DVMA_DEBUG
+		printk("out of dvma holes! (printing hole cache)\n");
+		print_holes(&hole_cache);
+		print_use();
+#endif
 		BUG();
 	}
 
@@ -111,11 +175,19 @@
 			hole->end -= newlen;
 			hole->size -= newlen;
 			dvma_entry_use(hole->end) = newlen;
+#ifdef DVMA_DEBUG
+			dvma_allocs++;
+			dvma_alloc_bytes += newlen;
+#endif
 			return hole->end;
 		} else if(hole->size == newlen) {
 			list_del(&(hole->list));
 			list_add(&(hole->list), &hole_cache);
 			dvma_entry_use(hole->start) = newlen;
+#ifdef DVMA_DEBUG
+			dvma_allocs++;
+			dvma_alloc_bytes += newlen;
+#endif
 			return hole->start;
 		}
 
@@ -140,6 +212,11 @@
 	baddr &= DVMA_PAGE_MASK;
 	dvma_unmap_iommu(baddr, len);
 
+#ifdef DVMA_DEBUG
+	dvma_frees++;
+	dvma_free_bytes += len;
+#endif
+
 	list_for_each(cur, &hole_list) {
 		hole = list_entry(cur, struct hole, list);
 		
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/sun3x/prom.c linux/arch/m68k/sun3x/prom.c
--- linux.orig/arch/m68k/sun3x/prom.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/sun3x/prom.c	2002-07-20 01:08:35.000000000 +0000
@@ -96,7 +96,6 @@
 	sun3x_prom_write,  	/* write */
 	NULL,			/* read */
 	NULL,			/* device */
-	NULL,			/* wait_key */
 	NULL,			/* unblank */
 	NULL,			/* setup */
 	CON_PRINTBUFFER,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/sun3x/time.c linux/arch/m68k/sun3x/time.c
--- linux.orig/arch/m68k/sun3x/time.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/sun3x/time.c	2002-07-20 01:08:24.000000000 +0000
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/rtc.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -59,7 +60,7 @@
     *(eeprom + M_CONTROL) &= ~C_READ;
 }
 
-int sun3x_hwclk(int set, struct hwclk_time *t)
+int sun3x_hwclk(int set, struct rtc_time *t)
 {
 	volatile struct mostek_dt *h = 
 		(unsigned char *)(SUN3X_EEPROM+M_CONTROL);
@@ -69,23 +70,23 @@
 	
 	if(set) {
 		h->csr |= C_WRITE;
-		h->sec = BIN_TO_BCD(t->sec);
-		h->min = BIN_TO_BCD(t->min);
-		h->hour = BIN_TO_BCD(t->hour);
-		h->wday = BIN_TO_BCD(t->wday);
-		h->mday = BIN_TO_BCD(t->day);
-		h->month = BIN_TO_BCD(t->mon);
-		h->year = BIN_TO_BCD(t->year);
+		h->sec = BIN_TO_BCD(t->tm_sec);
+		h->min = BIN_TO_BCD(t->tm_min);
+		h->hour = BIN_TO_BCD(t->tm_hour);
+		h->wday = BIN_TO_BCD(t->tm_wday);
+		h->mday = BIN_TO_BCD(t->tm_mday);
+		h->month = BIN_TO_BCD(t->tm_mon);
+		h->year = BIN_TO_BCD(t->tm_year);
 		h->csr &= ~C_WRITE;
 	} else {
 		h->csr |= C_READ;
-		t->sec = BCD_TO_BIN(h->sec);
-		t->min = BCD_TO_BIN(h->min);
-		t->hour = BCD_TO_BIN(h->hour);
-		t->wday = BCD_TO_BIN(h->wday);
-		t->day = BCD_TO_BIN(h->mday);
-		t->mon = BCD_TO_BIN(h->month);
-		t->year = BCD_TO_BIN(h->year);
+		t->tm_sec = BCD_TO_BIN(h->sec);
+		t->tm_min = BCD_TO_BIN(h->min);
+		t->tm_hour = BCD_TO_BIN(h->hour);
+		t->tm_wday = BCD_TO_BIN(h->wday);
+		t->tm_mday = BCD_TO_BIN(h->mday);
+		t->tm_mon = BCD_TO_BIN(h->month);
+		t->tm_year = BCD_TO_BIN(h->year);
 		h->csr &= ~C_READ;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/m68k/sun3x/time.h linux/arch/m68k/sun3x/time.h
--- linux.orig/arch/m68k/sun3x/time.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/m68k/sun3x/time.h	2002-07-20 01:08:39.000000000 +0000
@@ -3,7 +3,7 @@
 
 extern void sun3x_gettod (int *yearp, int *monp, int *dayp,
                    int *hourp, int *minp, int *secp);
-extern int sun3x_hwclk(int set, struct hwclk_time *t);
+extern int sun3x_hwclk(int set, struct rtc_time *t);
 unsigned long sun3x_gettimeoffset (void);
 void sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *));
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/Makefile linux/arch/mips/Makefile
--- linux.orig/arch/mips/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/Makefile	2002-07-20 01:08:22.000000000 +0000
@@ -5,6 +5,7 @@
 #
 # Copyright (C) 1994, 1995, 1996 by Ralf Baechle
 # DECStation modifications by Paul M. Antoine, 1996
+# Copyright (C) 2002  Maciej W. Rozycki
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
@@ -22,7 +23,7 @@
 endif
 
 ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE  = $(tool-prefix)
+CROSS_COMPILE	= $(tool-prefix)
 endif
 
 #
@@ -35,13 +36,13 @@
 # machines may also.  Since BFD is incredibly buggy with respect to
 # crossformat linking we rely on the elf2ecoff tool for format conversion.
 #
-GCCFLAGS	:= -G 0 -mno-abicalls -fno-pic
-LINKFLAGS	+= -static
+GCCFLAGS	:= -I $(TOPDIR)/include/asm/gcc
+GCCFLAGS	+= -G 0 -mno-abicalls -fno-pic -pipe
+LINKFLAGS	+= -G 0 -static # -N
 MODFLAGS	+= -mlong-calls
-LD		:= $(LD) -G 0
 
 ifdef CONFIG_REMOTE_DEBUG
-CFLAGS		:= $(CFLAGS) -g
+GCCFLAGS	+= -g
 endif
 
 #
@@ -50,6 +51,9 @@
 ifdef CONFIG_CPU_R3000
 GCCFLAGS	+= -mcpu=r3000 -mips1
 endif
+ifdef CONFIG_CPU_TX39XX
+GCCFLAGS	+= -mcpu=r3000 -mips1
+endif
 ifdef CONFIG_CPU_R6000
 GCCFLAGS	+= -mcpu=r6000 -mips2 -Wa,--trap
 endif
@@ -62,6 +66,9 @@
 ifdef CONFIG_CPU_R4X00
 GCCFLAGS	+= -mcpu=r4600 -mips2 -Wa,--trap
 endif
+ifdef CONFIG_CPU_TX49XX
+GCCFLAGS	+= -mcpu=r4600 -mips2 -Wa,--trap
+endif
 ifdef CONFIG_CPU_MIPS32
 GCCFLAGS	+= -mcpu=r4600 -mips2 -Wa,--trap
 endif
@@ -72,7 +79,7 @@
 GCCFLAGS	+= -mcpu=r5000 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_R5432
-GCCFLAGS        += -mcpu=r5000 -mips2 -Wa,--trap
+GCCFLAGS	+= -mcpu=r5000 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_NEVADA
 # Cannot use -mmad with currently recommended tools
@@ -83,184 +90,296 @@
 endif
 ifdef CONFIG_CPU_SB1
 GCCFLAGS	+= -mcpu=sb1 -mips2 -Wa,--trap
+ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+MODFLAGS	+= -msb1-pass1-workarounds
+endif
 endif
 
-GCCFLAGS	+= -pipe
-
-CFLAGS		:= -I $(TOPDIR)/include/asm/gcc $(CFLAGS) $(GCCFLAGS)
 AFLAGS		+= $(GCCFLAGS)
-ASFLAGS		+= $(GCCFLAGS)
+CFLAGS		+= $(GCCFLAGS)
+
 
 #
 # We unconditionally build the math emulator
 #
-CORE_FILES	+=arch/mips/math-emu/fpu_emulator.o
-SUBDIRS		+=arch/mips/math-emu
+CORE_FILES	+= arch/mips/math-emu/fpu_emulator.o
+SUBDIRS		+= arch/mips/math-emu
+
+#
+# ramdisk/initrd support
+# You need a compressed ramdisk image, named ramdisk.gz in
+# arch/mips/ramdisk
+#
+ifdef CONFIG_EMBEDDED_RAMDISK
+CORE_FILES	+= arch/mips/ramdisk/ramdisk.o
+SUBDIRS		+= arch/mips/ramdisk
+endif
+
 
 #
 # Board-dependent options and extra files
 #
+
+#
+# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
+#
+ifdef CONFIG_MIPS_JAZZ
+CORE_FILES	+= arch/mips/jazz/jazz.o
+SUBDIRS		+= arch/mips/jazz arch/mips/arc
+LIBS		+= arch/mips/arc/arclib.a
+LOADADDR	:= 0x80080000
+endif
+
+#
+# Au1000 (Alchemy Semi PB1000) eval board
+#
+ifdef CONFIG_MIPS_PB1000
+LIBS		+= arch/mips/au1000/pb1000/pb1000.o \
+		   arch/mips/au1000/common/au1000.o
+SUBDIRS		+= arch/mips/au1000/pb1000 arch/mips/au1000/common
+LOADADDR	:= 0x80100000
+endif
+
+#
+# Au1000 (Alchemy Semi PB1500) eval board
+#
+ifdef CONFIG_MIPS_PB1500
+LIBS		+= arch/mips/au1000/pb1500/pb1500.o \
+		   arch/mips/au1000/common/au1000.o
+SUBDIRS		+= arch/mips/au1000/pb1500 arch/mips/au1000/common
+LOADADDR	:= 0x80100000
+endif
+
+#
+# Algorithmics P4032
+#
 ifdef CONFIG_ALGOR_P4032
-CORE_FILES    += arch/mips/algor/algor.o
-SUBDIRS       += arch/mips/algor
-LOADADDR      += 0x80000000
+CORE_FILES	+= arch/mips/algor/algor.o
+SUBDIRS		+= arch/mips/algor
+LOADADDR	:= 0x80000000
+endif
+
+#
+# Baget/MIPS
+#
+ifdef CONFIG_BAGET_MIPS
+SUBDIRS		+= arch/mips/baget arch/mips/baget/prom
+LIBS		+= arch/mips/baget/baget.a arch/mips/baget/prom/bagetlib.a
+LOADADDR	:= 0x80001000
+endif
+
+#
+# Cobalt Server
+#
+ifdef CONFIG_MIPS_COBALT
+SUBDIRS		+= arch/mips/cobalt
+CORE_FILES	+= arch/mips/cobalt/cobalt.o
+LOADADDR	:= 0x80080000
 endif
 
 #
 # DECstation family
 #
 ifdef CONFIG_DECSTATION
-CORE_FILES    += arch/mips/dec/dec.o
-SUBDIRS       += arch/mips/dec arch/mips/dec/prom
-LIBS          += arch/mips/dec/prom/rexlib.a
-LOADADDR      += 0x80040000
+CORE_FILES	+= arch/mips/dec/dec.o
+SUBDIRS		+= arch/mips/dec arch/mips/dec/prom
+LIBS		+= arch/mips/dec/prom/rexlib.a
+LOADADDR	:= 0x80040000
 endif
 
-ifdef CONFIG_MIPS_ATLAS
-LIBS          += arch/mips/mips-boards/atlas/atlas.o arch/mips/mips-boards/generic/mipsboards.o
-SUBDIRS       += arch/mips/mips-boards/generic arch/mips/mips-boards/atlas
-LOADADDR      += 0x80100000
+#
+# Galileo EV64120 Board
+#
+ifdef CONFIG_MIPS_EV64120
+LIBS		+= arch/mips/galileo-boards/ev64120/ev64120.o
+SUBDIRS		+= arch/mips/galileo-boards/ev64120
+LOADADDR	:= 0x80100000
 endif
 
-ifdef CONFIG_MIPS_MALTA
-LIBS          += arch/mips/mips-boards/malta/malta.o arch/mips/mips-boards/generic/mipsboards.o
-SUBDIRS       += arch/mips/mips-boards/malta arch/mips/mips-boards/generic
-LOADADDR      += 0x80100000
+#
+# Galileo EV96100 Board
+#
+ifdef CONFIG_MIPS_EV96100
+LIBS		+= arch/mips/galileo-boards/ev96100/ev96100.o \
+		   arch/mips/galileo-boards/generic/galboards.o
+SUBDIRS		+= arch/mips/galileo-boards/generic \
+		   arch/mips/galileo-boards/ev96100
+LOADADDR	:= 0x80100000
 endif
 
 #
-# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
+# Globespan IVR eval board with QED 5231 CPU
 #
-ifdef CONFIG_MIPS_JAZZ
-CORE_FILES    += arch/mips/jazz/jazz.o
-SUBDIRS       += arch/mips/jazz arch/mips/arc
-LIBS          += arch/mips/arc/arclib.a
-LOADADDR      += 0x80080000
+ifdef CONFIG_MIPS_IVR
+LIBS		+= arch/mips/ite-boards/ivr/ivr.o \
+		   arch/mips/ite-boards/generic/it8172.o
+SUBDIRS		+= arch/mips/ite-boards/generic arch/mips/ite-boards/ivr
+LOADADDR	:= 0x80100000
 endif
 
-ifdef CONFIG_SNI_RM200_PCI
-CORE_FILES    += arch/mips/sni/sni.o
-SUBDIRS       += arch/mips/sni arch/mips/arc
-LIBS          += arch/mips/arc/arclib.a
-LOADADDR      += 0x80080000
+#
+# HP LaserJet
+#
+ifdef CONFIG_HP_LASERJET
+SUBDIRS		+= arch/mips/hp-lj
+LIBS		+= arch/mips/hp-lj/hp-lj.o
+LOADADDR	:= 0x80030000
 endif
 
-ifdef CONFIG_SGI_IP22
-CORE_FILES    += arch/mips/sgi/kernel/ip22-kern.o
-LIBS          += arch/mips/arc/arclib.a
-SUBDIRS       += arch/mips/sgi/kernel arch/mips/arc
 #
-# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
-# 0x88002000 for production kernels.  Note that the value must be
-# 8kb aligned or the handling of the current variable will break.
+# ITE 8172 eval board with QED 5231 CPU
 #
-LOADADDR      += 0x88002000
+ifdef CONFIG_MIPS_ITE8172
+LIBS		+= arch/mips/ite-boards/qed-4n-s01b/ite.o \
+		   arch/mips/ite-boards/generic/it8172.o
+SUBDIRS		+= arch/mips/ite-boards/generic arch/mips/ite-boards/qed-4n-s01b
+LOADADDR	:= 0x80100000
 endif
 
 #
-# Baget/MIPS
+# MIPS Atlas board
 #
-ifdef CONFIG_BAGET_MIPS
-SUBDIRS       += arch/mips/baget arch/mips/baget/prom
-LIBS          += arch/mips/baget/baget.a arch/mips/baget/prom/bagetlib.a
-LOADADDR      += 0x80001000
+ifdef CONFIG_MIPS_ATLAS
+LIBS		+= arch/mips/mips-boards/atlas/atlas.o \
+		   arch/mips/mips-boards/generic/mipsboards.o
+SUBDIRS		+= arch/mips/mips-boards/generic arch/mips/mips-boards/atlas
+LOADADDR	:= 0x80100000
+endif
+
+#
+# MIPS Malta board
+#
+ifdef CONFIG_MIPS_MALTA
+LIBS		+= arch/mips/mips-boards/malta/malta.o \
+		   arch/mips/mips-boards/generic/mipsboards.o
+SUBDIRS		+= arch/mips/mips-boards/malta arch/mips/mips-boards/generic
+LOADADDR	:= 0x80100000
+endif
+
+#
+# Momentum Ocelot board
+#
+ifdef CONFIG_MOMENCO_OCELOT
+# The Ocelot setup.o must be linked early - it does the ioremap() for the
+# mips_io_port_base.
+CORE_FILES	+= arch/mips/gt64120/common/gt64120.o \
+		   arch/mips/gt64120/momenco_ocelot/momenco_ocelot.o
+SUBDIRS		+= arch/mips/gt64120/common arch/mips/gt64120/momenco_ocelot
+LOADADDR	:= 0x80100000
 endif
 
 #
 # NEC DDB Vrc-5074
 #
 ifdef CONFIG_DDB5074
-SUBDIRS       += arch/mips/ddb5074
-LIBS          += arch/mips/ddb5074/ddb5074.a
-LOADADDR      += 0x80080000
+SUBDIRS		+= arch/mips/ddb5074
+LIBS		+= arch/mips/ddb5074/ddb5074.a
+LOADADDR	:= 0x80080000
 endif
 
 #
-#
 # NEC DDB Vrc-5476
 #
 ifdef CONFIG_DDB5476
-SUBDIRS       += arch/mips/ddb5476
-LIBS          += arch/mips/ddb5476/ddb5476.a
-LOADADDR      += 0x80080000
+SUBDIRS		+= arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5476
+LIBS		+= arch/mips/ddb5xxx/common/ddb5xxx.o \
+		   arch/mips/ddb5xxx/ddb5476/ddb5476.o
+LOADADDR	:= 0x80080000
 endif
 
 #
-#
 # NEC DDB Vrc-5477
 #
 ifdef CONFIG_DDB5477
-SUBDIRS       += arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5477
-LIBS          += arch/mips/ddb5xxx/common/ddb5xxx.o \
-                 arch/mips/ddb5xxx/ddb5477/ddb5477.o
-LOADADDR      += 0x80080000
+SUBDIRS		+= arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5477
+LIBS		+= arch/mips/ddb5xxx/common/ddb5xxx.o \
+		   arch/mips/ddb5xxx/ddb5477/ddb5477.o
+LOADADDR	:= 0x80080000
 endif
 
 #
-# Galileo EV64120 Board
+# NEC Osprey (vr4181) board
 #
-ifdef CONFIG_MIPS_EV64120
-LIBS          += arch/mips/galileo-boards/ev64120/ev64120.o
-SUBDIRS       += arch/mips/galileo-boards/ev64120
-LOADADDR      += 0x80100000
+ifdef CONFIG_NEC_OSPREY
+SUBDIRS		+= arch/mips/vr4181/common arch/mips/vr4181/osprey
+LIBS		+= arch/mips/vr4181/common/vr4181.o \
+		   arch/mips/vr4181/osprey/osprey.o
+LOADADDR	:= 0x80002000
 endif
 
 #
-# Galileo EV96100 Board
+# Philips Nino
 #
-ifdef CONFIG_MIPS_EV96100
-LIBS          += arch/mips/galileo-boards/ev96100/ev96100.o arch/mips/galileo-boards/generic/galboards.o
-SUBDIRS       += arch/mips/galileo-boards/generic arch/mips/galileo-boards/ev96100
-LOADADDR      += 0x80100000
+ifdef CONFIG_NINO
+CORE_FILES	+= arch/mips/philips/nino/nino.o
+SUBDIRS		+= arch/mips/philips/nino
+LOADADDR	:= 0x80000000
 endif
 
 #
-# Momentum Ocelot board
+# SGI IP22 (Indy/Indigo2)
 #
-ifdef CONFIG_MOMENCO_OCELOT
-# The Ocelot setup.o must be linked early - it does the ioremap() for the
-# mips_io_port_base.
-CORE_FILES    += arch/mips/gt64120/common/gt64120.o arch/mips/gt64120/momenco_ocelot/momenco_ocelot.o
-SUBDIRS       += arch/mips/gt64120/common arch/mips/gt64120/momenco_ocelot
-LOADADDR      += 0x80100000
+ifdef CONFIG_SGI_IP22
+CORE_FILES	+= arch/mips/sgi-ip22/ip22-kern.o
+LIBS		+= arch/mips/arc/arclib.a
+SUBDIRS		+= arch/mips/sgi-ip22 arch/mips/arc
+#
+# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
+# 0x88002000 for production kernels.  Note that the value must be
+# 8kb aligned or the handling of the current variable will break.
+#
+LOADADDR	:= 0x88002000
 endif
 
 #
-# Philips Nino
+# Sibyte SB1250 SOC
 #
-ifdef CONFIG_NINO
-CORE_FILES    += arch/mips/philips/nino/nino.o
-SUBDIRS       += arch/mips/philips/nino
-LOADADDR      += 0x80000000
+ifdef CONFIG_SIBYTE_SB1250
+# This is a LIB so that it links at the end, and initcalls are later
+# the sequence; but it is built as an object so that modules don't get
+# removed (as happens, even if they have __initcall/module_init)
+LIBS		+= arch/mips/sibyte/sb1250/sb1250.o
+SUBDIRS		+= arch/mips/sibyte/sb1250
 endif
 
 #
-# ITE 8172 eval board with QED 5231 CPU
+# Sibyte SWARM board
 #
-ifdef CONFIG_MIPS_ITE8172
-LIBS          += arch/mips/ite-boards/qed-4n-s01b/ite.o arch/mips/ite-boards/generic/it8172.o
-SUBDIRS       += arch/mips/ite-boards/generic arch/mips/ite-boards/qed-4n-s01b
-LOADADDR      += 0x80100000
+ifdef CONFIG_SIBYTE_SWARM
+LIBS		+= arch/mips/sibyte/swarm/sbswarm.a
+SUBDIRS		+= arch/mips/sibyte/swarm
+LOADADDR	:= 0x80100000
 endif
 
 #
-# Globespan IVR eval board with QED 5231 CPU
+# SB1 Cache Error handler
 #
-ifdef CONFIG_MIPS_IVR
-LIBS          += arch/mips/ite-boards/ivr/ivr.o arch/mips/ite-boards/generic/it8172.o
-SUBDIRS       += arch/mips/ite-boards/generic arch/mips/ite-boards/ivr
-LOADADDR      += 0x80100000
+ifdef CONFIG_SB1_CACHE_ERROR
+LIBS		+= arch/mips/sibyte/sb1/sb1kern.a
+SUBDIRS		+= arch/mips/sibyte/sb1
 endif
 
 #
-# Au1000 eval board
+# SNI RM200 PCI
 #
-ifdef CONFIG_MIPS_PB1000
-LIBS          += arch/mips/au1000/pb1000/pb1000.o arch/mips/au1000/common/au1000.o
-SUBDIRS       += arch/mips/au1000/pb1000 arch/mips/au1000/common
-LOADADDR      += 0x80100000
+ifdef CONFIG_SNI_RM200_PCI
+CORE_FILES	+= arch/mips/sni/sni.o
+SUBDIRS		+= arch/mips/sni arch/mips/arc
+LIBS		+= arch/mips/arc/arclib.a
+LOADADDR	:= 0x80080000
+endif
+
+#
+# Toshiba JMR-TX3927 board
+#
+ifdef CONFIG_TOSHIBA_JMR3927
+CORE_FILES	+= arch/mips/jmr3927/rbhma3100/jmr3927.o \
+		   arch/mips/jmr3927/common/tx3927.o
+SUBDIRS		+= arch/mips/jmr3927/rbhma3100 arch/mips/jmr3927/common
+LOADADDR	:= 0x80050000
 endif
 
+
 #
 # Choosing incompatible machines durings configuration will result in
 # error messages during linking.  Select a default linkscript if
@@ -282,7 +401,7 @@
 
 BAGETBOOT = $(MAKE) -C arch/$(ARCH)/baget
 
-balo:  vmlinux
+balo: vmlinux
 	$(BAGETBOOT) balo
 
 endif
@@ -291,7 +410,7 @@
 GALILEOBOOT = $(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120
 
 gboot: vmlinux
-	$(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120/compressed 
+	$(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120/compressed
 endif
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
@@ -311,6 +430,6 @@
 
 archdep:
 	if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \
-	 touch $(TOPDIR)/include/asm-$(ARCH)/offset.h; \
+		touch $(TOPDIR)/include/asm-$(ARCH)/offset.h; \
 	fi;
 	@$(MAKEBOOT) dep
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/cmdline.c linux/arch/mips/arc/cmdline.c
--- linux.orig/arch/mips/arc/cmdline.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/arc/cmdline.c	2002-07-20 01:08:40.000000000 +0000
@@ -12,7 +12,7 @@
 
 #undef DEBUG_CMDLINE
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
 
 char * __init prom_getcmdline(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/console.c linux/arch/mips/arc/console.c
--- linux.orig/arch/mips/arc/console.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/arc/console.c	2002-07-20 01:08:36.000000000 +0000
@@ -6,7 +6,6 @@
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  * Compability with board caches, Ulf Carlsson
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <asm/sgialib.h>
@@ -31,7 +30,7 @@
 	char it = c;
 
 	bc_disable();
-	romvec->write(1, &it, 1, &cnt);
+	ArcWrite(1, &it, 1, &cnt);
 	bc_enable();
 }
 
@@ -41,7 +40,7 @@
 	char c;
 
 	bc_disable();
-	romvec->read(0, &c, 1, &cnt);
+	ArcRead(0, &c, 1, &cnt);
 	bc_enable();
 
 	return c;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/env.c linux/arch/mips/arc/env.c
--- linux.orig/arch/mips/arc/env.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/arc/env.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,24 +1,27 @@
 /*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * env.c: ARCS environment variable routines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: env.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 
+#include <asm/arc/types.h>
 #include <asm/sgialib.h>
 
 PCHAR __init
 ArcGetEnvironmentVariable(CHAR *name)
 {
-	return romvec->get_evar(name);
+	return (CHAR *) ARC_CALL1(get_evar, name);
 }
 
 LONG __init
 ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
 {
-	return romvec->set_evar(name, value);
+	return ARC_CALL2(set_evar, name, value);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/file.c linux/arch/mips/arc/file.c
--- linux.orig/arch/mips/arc/file.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/arc/file.c	2002-07-20 01:08:26.000000000 +0000
@@ -1,59 +1,75 @@
 /*
- * file.c: ARCS firmware interface to files.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * ARC firmware interface.
  *
- * $Id: file.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
+ * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #include <linux/init.h>
+
+#include <asm/arc/types.h>
 #include <asm/sgialib.h>
 
-long __init prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt)
+LONG __init
+ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
+                     ULONG N, ULONG *Count)
 {
-	return romvec->get_vdirent(fd, ent, num, cnt);
+	return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
 }
 
-long __init prom_open(char *name, enum linux_omode md, unsigned long *fd)
+LONG __init
+ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
 {
-	return romvec->open(name, md, fd);
+	return ARC_CALL3(open, Path, OpenMode, FileID);
 }
 
-long __init prom_close(unsigned long fd)
+LONG __init
+ArcClose(ULONG FileID)
 {
-	return romvec->close(fd);
+	return ARC_CALL1(close, FileID);
 }
 
-long __init prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt)
+LONG __init
+ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
 {
-	return romvec->read(fd, buf, num, cnt);
+	return ARC_CALL4(read, FileID, Buffer, N, Count);
 }
 
-long __init prom_getrstatus(unsigned long fd)
+LONG __init
+ArcGetReadStatus(ULONG FileID)
 {
-	return romvec->get_rstatus(fd);
+	return ARC_CALL1(get_rstatus, FileID);
 }
 
-long __init prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt)
+LONG __init
+ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
 {
-	return romvec->write(fd, buf, num, cnt);
+	return ARC_CALL4(write, FileID, Buffer, N, Count);
 }
 
-long __init prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm)
+LONG __init
+ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
 {
-	return romvec->seek(fd, off, sm);
+	return ARC_CALL3(seek, FileID, Position, SeekMode);
 }
 
-long __init prom_mount(char *name, enum linux_mountops op)
+LONG __init
+ArcMount(char *name, enum linux_mountops op)
 {
-	return romvec->mount(name, op);
+	return ARC_CALL2(mount, name, op);
 }
 
-long __init prom_getfinfo(unsigned long fd, struct linux_finfo *buf)
+LONG __init
+ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
 {
-	return romvec->get_finfo(fd, buf);
+	return ARC_CALL2(get_finfo, FileID, Information);
 }
 
-long __init prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk)
+LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
+                                  ULONG AttributeMask)
 {
-	return romvec->set_finfo(fd, flags, msk);
+	return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/identify.c linux/arch/mips/arc/identify.c
--- linux.orig/arch/mips/arc/identify.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/arc/identify.c	2002-07-20 01:08:28.000000000 +0000
@@ -7,6 +7,7 @@
  * 
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -17,49 +18,81 @@
 #include <asm/bootinfo.h>
 
 struct smatch {
-	char *name;
+	char *arcname;
+	char *liname;
 	int group;
 	int type;
 	int flags;
 };
 
 static struct smatch mach_table[] = {
-	{"SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS},
-	{"Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0},
-	{"PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0},
-	{"RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0}
+	{	"SGI-IP22",
+		"SGI Indy",
+		MACH_GROUP_SGI,
+		MACH_SGI_INDY,
+		PROM_FLAG_ARCS
+	}, {	"Microsoft-Jazz",
+		"Jazz MIPS_Magnum_4000",
+		MACH_GROUP_JAZZ,
+		MACH_MIPS_MAGNUM_4000,
+		0
+	}, {	"PICA-61",
+		"Jazz Acer_PICA_61",
+		MACH_GROUP_JAZZ,
+		MACH_ACER_PICA_61,
+		0
+	}, {	"RM200PCI",
+		"SNI RM200_PCI",
+		MACH_GROUP_SNI_RM,
+		MACH_SNI_RM200_PCI,
+		0
+	}
 };
 
 int prom_flags;
 
-static struct smatch *__init string_to_mach(char *s)
+static struct smatch *__init string_to_mach(const char *s)
 {
 	int i;
 
 	for (i = 0; i < (sizeof(mach_table) / sizeof (mach_table[0])); i++) {
-		if (!strcmp(s, mach_table[i].name))
+		if (!strcmp(s, mach_table[i].arcname))
 			return &mach_table[i];
 	}
-	prom_printf("\nYeee, could not determine architecture type <%s>\n",
-		    s);
-	prom_printf("press a key to reboot\n");
-	prom_getchar();
-	romvec->imode();
-	return NULL;
+
+	panic("Yeee, could not determine architecture type <%s>", s);
+}
+
+char *system_type;
+
+const char *get_system_type(void)
+{
+	return system_type;
 }
 
 void __init prom_identify_arch(void)
 {
 	pcomponent *p;
 	struct smatch *mach;
+	const char *iname;
 
 	/*
 	 * The root component tells us what machine architecture we
 	 * have here.
 	 */
-	p = prom_getchild(PROM_NULL_COMPONENT);
-	printk("ARCH: %s\n", p->iname);
-	mach = string_to_mach(p->iname);
+	p = ArcGetChild(PROM_NULL_COMPONENT);
+	if (p == NULL) {
+#ifdef CONFIG_SGI_IP27
+	/* IP27 PROM bisbehaves, seems to not implement ARC
+	   GetChild().  So we just assume it's an IP27.  */
+		iname = "SGI-IP27";
+#endif
+	} else
+		iname = (char *) (long) p->iname;
+
+	printk(KERN_INFO "ARCH: %s\n", iname);
+	mach = string_to_mach(iname);
+	system_type = mach->liname;
 
 	mips_machgroup = mach->group;
 	mips_machtype = mach->type;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/init.c linux/arch/mips/arc/init.c
--- linux.orig/arch/mips/arc/init.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/arc/init.c	2002-07-20 01:08:34.000000000 +0000
@@ -16,38 +16,22 @@
 
 /* Master romvec interface. */
 struct linux_romvec *romvec;
-struct linux_promblock *sgi_pblock;
 int prom_argc;
 char **prom_argv, **prom_envp;
-unsigned short prom_vers, prom_rev;
 
 extern void prom_testtree(void);
 
-extern void arc_setup_console(void);
-
 void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
 {
-	struct linux_promblock *pb;
+	PSYSTEM_PARAMETER_BLOCK pb;
+	unsigned short prom_vers, prom_rev;
 
 	romvec = ROMVECTOR;
-	pb = sgi_pblock = PROMBLOCK;
+	pb = PROMBLOCK;
 	prom_argc = argc;
 	prom_argv = argv;
 	prom_envp = envp;
 
-#if 0
-	/* arc_printf should not use prom_printf as soon as we free
-	 * the prom buffers - This horribly breaks on Indys with framebuffer
-	 * as it simply stops after initialising swap - On the Indigo2 serial
-	 * console you will get A LOT illegal instructions - Only enable
-	 * this for early init crashes - This also brings up artefacts of
-	 * printing everything twice on serial console and on GFX Console
-	 * this has the effect of having the prom printing everything
-	 * in the small rectangle and the kernel printing around.
-	 */
-
-	arc_setup_console();
-#endif
 	if (pb->magic != 0x53435241) {
 		prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
 		while(1)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/memory.c linux/arch/mips/arc/memory.c
--- linux.orig/arch/mips/arc/memory.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/arc/memory.c	2002-07-20 01:08:26.000000000 +0000
@@ -22,7 +22,7 @@
 struct linux_mdesc * __init
 ArcGetMemoryDescriptor(struct linux_mdesc *Current)
 {
-	return romvec->get_mdesc(Current);
+	return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
 }
 
 #ifdef DEBUG /* convenient for debugging */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/misc.c linux/arch/mips/arc/misc.c
--- linux.orig/arch/mips/arc/misc.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/arc/misc.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,13 +1,21 @@
 /*
- * misc.c: Miscellaneous ARCS PROM routines.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Miscellaneous ARCS PROM routines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 
 #include <asm/bcache.h>
+
+#include <asm/arc/types.h>
 #include <asm/sgialib.h>
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -15,68 +23,81 @@
 extern void *sgiwd93_host;
 extern void reset_wd33c93(void *instance);
 
-void prom_halt(void)
+VOID
+ArcHalt(VOID)
 {
 	bc_disable();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
 #endif
-	romvec->halt();
+	ARC_CALL0(halt);
+never:	goto never;
 }
 
-void prom_powerdown(void)
+VOID
+ArcPowerDown(VOID)
 {
 	bc_disable();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
 #endif
-	romvec->pdown();
+	ARC_CALL0(pdown);
+never:	goto never;
 }
 
 /* XXX is this a soft reset basically? XXX */
-void prom_restart(void)
+VOID
+ArcRestart(VOID)
 {
 	bc_disable();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
 #endif
-	romvec->restart();
+	ARC_CALL0(restart);
+never:	goto never;
 }
 
-void prom_reboot(void)
+VOID
+ArcReboot(VOID)
 {
 	bc_disable();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
 #endif
-	romvec->reboot();
+	ARC_CALL0(reboot);
+never:	goto never;
 }
 
-void ArcEnterInteractiveMode(void)
+VOID
+ArcEnterInteractiveMode(VOID)
 {
 	bc_disable();
 	cli();
 #if CONFIG_SCSI_SGIWD93
 	reset_wd33c93(sgiwd93_host);
 #endif
-	romvec->imode();
+	ARC_CALL0(imode);
+never:	goto never;
 }
 
-long prom_cfgsave(void)
+LONG
+ArcSaveConfiguration(VOID)
 {
-	return romvec->cfg_save();
+	return ARC_CALL0(cfg_save);
 }
 
-struct linux_sysid *prom_getsysid(void)
+struct linux_sysid *
+ArcGetSystemId(VOID)
 {
-	return romvec->get_sysid();
+	return (struct linux_sysid *) ARC_CALL0(get_sysid);
 }
 
-void __init prom_cacheflush(void)
+VOID __init
+ArcFlushAllCaches(VOID)
 {
-	romvec->cache_flush();
+	ARC_CALL0(cache_flush);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/salone.c linux/arch/mips/arc/salone.c
--- linux.orig/arch/mips/arc/salone.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/arc/salone.c	2002-07-20 01:08:40.000000000 +0000
@@ -3,8 +3,6 @@
  *           program images using ARCS PROM firmware.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: salone.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/time.c linux/arch/mips/arc/time.c
--- linux.orig/arch/mips/arc/time.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/arc/time.c	2002-07-20 01:08:35.000000000 +0000
@@ -1,19 +1,25 @@
 /*
- * time.c: Extracting time information from ARCS prom.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Extracting time information from ARCS prom.
  *
- * $Id: time.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  */
 #include <linux/init.h>
+
+#include <asm/arc/types.h>
 #include <asm/sgialib.h>
 
-struct linux_tinfo * __init prom_gettinfo(void)
+struct linux_tinfo * __init
+ArcGetTime(VOID)
 {
-	return romvec->get_tinfo();
+	return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
 }
 
-unsigned long __init prom_getrtime(void)
+ULONG __init
+ArcGetRelativeTime(VOID)
 {
-	return romvec->get_rtime();
+	return ARC_CALL0(get_rtime);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/arc/tree.c linux/arch/mips/arc/tree.c
--- linux.orig/arch/mips/arc/tree.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/arc/tree.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,72 +1,88 @@
 /*
- * tree.c: PROM component device tree code.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * PROM component device tree code.
  *
- * $Id: tree.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #include <linux/init.h>
+#include <asm/arc/types.h>
 #include <asm/sgialib.h>
 
-#define DEBUG_PROM_TREE
+#undef DEBUG_PROM_TREE
 
-pcomponent * __init prom_getsibling(pcomponent *this)
+pcomponent * __init
+ArcGetPeer(pcomponent *Current)
 {
-	if(this == PROM_NULL_COMPONENT)
+	if (Current == PROM_NULL_COMPONENT)
 		return PROM_NULL_COMPONENT;
-	return romvec->next_component(this);
+
+	return (pcomponent *) ARC_CALL1(next_component, Current);
 }
 
-pcomponent * __init prom_getchild(pcomponent *this)
+pcomponent * __init
+ArcGetChild(pcomponent *Current)
 {
-	return romvec->child_component(this);
+	return (pcomponent *) ARC_CALL1(child_component, Current);
 }
 
-pcomponent * __init prom_getparent(pcomponent *child)
+pcomponent * __init
+ArcGetParent(pcomponent *Current)
 {
-	if(child == PROM_NULL_COMPONENT)
+	if (Current == PROM_NULL_COMPONENT)
 		return PROM_NULL_COMPONENT;
-	return romvec->parent_component(child);
+
+	return (pcomponent *) ARC_CALL1(parent_component, Current);
 }
 
-long __init prom_getcdata(void *buffer, pcomponent *this)
+LONG __init
+ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
 {
-	return romvec->component_data(buffer, this);
+	return ARC_CALL2(component_data, Buffer, Current);
 }
 
-pcomponent * __init prom_childadd(pcomponent *this, pcomponent *tmp, void *data)
+pcomponent * __init
+ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
 {
-	return romvec->child_add(this, tmp, data);
+	return (pcomponent *)
+	       ARC_CALL3(child_add, Current, Template, ConfigurationData);
 }
 
-long __init prom_delcomponent(pcomponent *this)
+LONG __init
+ArcDeleteComponent(pcomponent *ComponentToDelete)
 {
-	return romvec->comp_del(this);
+	return ARC_CALL1(comp_del, ComponentToDelete);
 }
 
-pcomponent * __init prom_componentbypath(char *path)
+pcomponent * __init
+ArcGetComponent(CHAR *Path)
 {
-	return romvec->component_by_path(path);
+	return (pcomponent *)ARC_CALL1(component_by_path, Path);
 }
 
 #ifdef DEBUG_PROM_TREE
+
 static char *classes[] = {
 	"system", "processor", "cache", "adapter", "controller", "peripheral",
 	"memory"
 };
 
 static char *types[] = {
-	"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache", "sccache",
-	"memdev", "eisa adapter", "tc adapter", "scsi adapter", "dti adapter",
-	"multi-func adapter", "disk controller", "tp controller",
-	"cdrom controller", "worm controller", "serial controller",
-	"net controller", "display controller", "parallel controller",
-	"pointer controller", "keyboard controller", "audio controller",
-	"misc controller", "disk peripheral", "floppy peripheral",
-	"tp peripheral", "modem peripheral", "monitor peripheral",
-	"printer peripheral", "pointer peripheral", "keyboard peripheral",
-	"terminal peripheral", "line peripheral", "net peripheral",
-	"misc peripheral", "anonymous"
+	"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
+	"sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
+	"dti adapter", "multi-func adapter", "disk controller",
+	"tp controller", "cdrom controller", "worm controller",
+	"serial controller", "net controller", "display controller",
+	"parallel controller", "pointer controller", "keyboard controller",
+	"audio controller", "misc controller", "disk peripheral",
+	"floppy peripheral", "tp peripheral", "modem peripheral",
+	"monitor peripheral", "printer peripheral", "pointer peripheral",
+	"keyboard peripheral", "terminal peripheral", "line peripheral",
+	"net peripheral", "misc peripheral", "anonymous"
 };
 
 static char *iflags[] = {
@@ -74,7 +90,8 @@
 	"input", "output"
 };
 
-static void __init dump_component(pcomponent *p)
+static void __init
+dump_component(pcomponent *p)
 {
 	prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
 		    p, classes[p->class], types[p->type],
@@ -83,27 +100,28 @@
 		    p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
 }
 
-static void __init traverse(pcomponent *p, int op)
+static void __init
+traverse(pcomponent *p, int op)
 {
 	dump_component(p);
-	if(prom_getchild(p))
-		traverse(prom_getchild(p), 1);
-	if(prom_getsibling(p) && op)
-		traverse(prom_getsibling(p), 1);
+	if(ArcGetChild(p))
+		traverse(ArcGetChild(p), 1);
+	if(ArcGetPeer(p) && op)
+		traverse(ArcGetPeer(p), 1);
 }
 
-void __init prom_testtree(void)
+void __init
+prom_testtree(void)
 {
 	pcomponent *p;
 
-	p = prom_getchild(PROM_NULL_COMPONENT);
+	p = ArcGetChild(PROM_NULL_COMPONENT);
 	dump_component(p);
-	p = prom_getchild(p);
+	p = ArcGetChild(p);
 	while(p) {
 		dump_component(p);
-		p = prom_getsibling(p);
+		p = ArcGetPeer(p);
 	}
-	prom_printf("press a key\n");
-	prom_getchar();
 }
-#endif
+
+#endif /* DEBUG_PROM_TREE  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/Makefile linux/arch/mips/au1000/common/Makefile
--- linux.orig/arch/mips/au1000/common/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/common/Makefile	2002-07-20 01:08:40.000000000 +0000
@@ -19,13 +19,13 @@
 
 O_TARGET := au1000.o
 
-obj-y := prom.o dbg_io.o int-handler.o irq.o puts.o time.o reset.o
+export-objs		= prom.o serial.o clocks.o
+
+obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o power.o clocks.o
 
 obj-$(CONFIG_AU1000_UART) += serial.o             
+obj-$(CONFIG_AU1000_USB_DEVICE) += usbdev.o
 obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o             
-obj-$(CONFIG_BLK_DEV_INITRD) += ramdisk.o
-
-ramdisk.o: 
-	mkramobj ramdisk ramdisk.o
+obj-$(CONFIG_RTC) += rtc.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/clocks.c linux/arch/mips/au1000/common/clocks.c
--- linux.orig/arch/mips/au1000/common/clocks.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/common/clocks.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,98 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Simple Au1000 clocks routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *		ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <asm/au1000.h>
+
+static unsigned int au1000_clock; // Hz
+static unsigned int lcd_clock;    // KHz
+static unsigned long uart_baud_base;
+
+/*
+ * Set the au1000_clock
+ */
+void set_au1000_speed(unsigned int new_freq)
+{
+	au1000_clock = new_freq;
+}
+
+unsigned int get_au1000_speed(void)
+{
+	return au1000_clock;
+}
+
+
+
+/*
+ * The UART baud base is not known at compile time ... if
+ * we want to be able to use the same code on different
+ * speed CPUs.
+ */
+unsigned long get_au1000_uart_baud_base(void)
+{
+	return uart_baud_base;
+}
+
+void set_au1000_uart_baud_base(unsigned long new_baud_base)
+{
+	uart_baud_base = new_baud_base;
+}
+
+/*
+ * Calculate the Au1000's LCD clock based on the current
+ * cpu clock and the system bus clock, and try to keep it
+ * below 40 MHz (the Pb1000 board can lock-up if the LCD
+ * clock is over 40 MHz).
+ */
+void set_au1000_lcd_clock(void)
+{
+	unsigned int static_cfg0;
+	unsigned int sys_busclk =
+		(get_au1000_speed()/1000) /
+		((int)(inl(SYS_POWERCTRL)&0x03) + 2);
+
+	static_cfg0 = inl(MEM_STCFG0);
+
+	if (static_cfg0 & (1<<11))
+		lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
+	else
+		lcd_clock = sys_busclk / 4;
+
+	if (lcd_clock > 50000) /* Epson MAX */
+			printk(__FUNCTION__
+			       ": warning: LCD clock too high (%d KHz)\n",
+			       lcd_clock);
+}
+
+unsigned int get_au1000_lcd_clock(void)
+{
+	return lcd_clock;
+}
+
+EXPORT_SYMBOL(get_au1000_lcd_clock);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/dbg_io.c linux/arch/mips/au1000/common/dbg_io.c
--- linux.orig/arch/mips/au1000/common/dbg_io.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/common/dbg_io.c	2002-07-20 01:08:34.000000000 +0000
@@ -53,8 +53,11 @@
 #define UART_MOD_CNTRL	0x100	/* Module Control */
 
 /* memory-mapped read/write of the port */
-#define UART16550_READ(y)    (inl(DEBUG_BASE + y) & 0xff)
-#define UART16550_WRITE(y,z) (outl(z&0xff, DEBUG_BASE + y))
+#define UART16550_READ(y)    (readl(DEBUG_BASE + y) & 0xff)
+#define UART16550_WRITE(y,z) (writel(z&0xff, DEBUG_BASE + y))
+
+extern unsigned long get_au1000_uart_baud_base(void);
+extern unsigned long cal_r4koff(void);
 
 void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
 {
@@ -72,12 +75,12 @@
 		uint32 divisor;
 
 		/* set divisor */
-		divisor = get_au1000_uart_baud() / baud;
+		divisor = get_au1000_uart_baud_base() / baud;
 		UART16550_WRITE(UART_CLK, divisor & 0xffff);
 	}
 
 	/* set data format */
-	UART16550_WRITE(UART_LCR, data | parity | stop);
+	UART16550_WRITE(UART_LCR, (data | parity | stop));
 }
 
 static int remoteDebugInitialized = 0;
@@ -99,7 +102,8 @@
 
 int putDebugChar(uint8 byte)
 {
-	int i;
+//	int i;
+
 	if (!remoteDebugInitialized) {
 		remoteDebugInitialized = 1;
 		debugInit(UART16550_BAUD_115200,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/dma.c linux/arch/mips/au1000/common/dma.c
--- linux.orig/arch/mips/au1000/common/dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/common/dma.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,195 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *      A DMA channel allocator for Au1000. API is modeled loosely off of
+ *      linux/kernel/dma.c.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	stevel@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <asm/au1000.h>
+#include <asm/au1000_dma.h>
+#include <asm/system.h>
+
+
+
+/*
+ * A note on resource allocation:
+ *
+ * All drivers needing DMA channels, should allocate and release them
+ * through the public routines `request_dma()' and `free_dma()'.
+ *
+ * In order to avoid problems, all processes should allocate resources in
+ * the same sequence and release them in the reverse order.
+ *
+ * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ.
+ * When releasing them, first release the IRQ, then release the DMA. The
+ * main reason for this order is that, if you are requesting the DMA buffer
+ * done interrupt, you won't know the irq number until the DMA channel is
+ * returned from request_dma.
+ */
+
+
+spinlock_t au1000_dma_spin_lock = SPIN_LOCK_UNLOCKED;
+
+struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
+      {dev_id:-1,},
+      {dev_id:-1,},
+      {dev_id:-1,},
+      {dev_id:-1,},
+      {dev_id:-1,},
+      {dev_id:-1,},
+      {dev_id:-1,},
+      {dev_id:-1,}
+};
+
+// Device FIFO addresses and default DMA modes
+static const struct {
+	unsigned int fifo_addr;
+	unsigned int dma_mode;
+} dma_dev_table[DMA_NUM_DEV] = {
+	{
+	UART0_ADDR + UART_TX, 0}, {
+	UART0_ADDR + UART_RX, 0}, {
+	0, 0}, {
+	0, 0}, {
+	AC97C_DATA, DMA_DW16 | DMA_NC}, {
+	AC97C_DATA, DMA_DR | DMA_DW16 | DMA_NC}, {
+	UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC}, {
+	UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC}, {
+	USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC}, {
+	USBD_EP0WR, DMA_DW8 | DMA_NC}, {
+	USBD_EP2WR, DMA_DW8 | DMA_NC}, {
+	USBD_EP3WR, DMA_DW8 | DMA_NC}, {
+	USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC}, {
+	USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC}, {
+	I2S_DATA, DMA_DW32 | DMA_NC}, {
+	I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC}
+};
+
+
+int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
+			 int length, int *eof, void *data)
+{
+	int i, len = 0;
+	struct dma_chan *chan;
+
+	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
+		if ((chan = get_dma_chan(i)) != NULL) {
+			len +=
+			    sprintf(buf + len, "%2d: %s\n", i,
+				    chan->dev_str);
+		}
+	}
+
+	if (fpos >= len) {
+		*start = buf;
+		*eof = 1;
+		return 0;
+	}
+	*start = buf + fpos;
+	if ((len -= fpos) > length)
+		return length;
+	*eof = 1;
+	return len;
+}
+
+
+void dump_au1000_dma_channel(unsigned int dmanr)
+{
+	struct dma_chan *chan;
+
+	if (dmanr > NUM_AU1000_DMA_CHANNELS)
+		return;
+	chan = &au1000_dma_table[dmanr];
+
+	printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr);
+	printk(KERN_INFO "  mode = 0x%08x\n",
+	       inl(chan->io + DMA_MODE_SET));
+	printk(KERN_INFO "  addr = 0x%08x\n",
+	       inl(chan->io + DMA_PERIPHERAL_ADDR));
+	printk(KERN_INFO "  start0 = 0x%08x\n",
+	       inl(chan->io + DMA_BUFFER0_START));
+	printk(KERN_INFO "  start1 = 0x%08x\n",
+	       inl(chan->io + DMA_BUFFER1_START));
+	printk(KERN_INFO "  count0 = 0x%08x\n",
+	       inl(chan->io + DMA_BUFFER0_COUNT));
+	printk(KERN_INFO "  count1 = 0x%08x\n",
+	       inl(chan->io + DMA_BUFFER1_COUNT));
+}
+
+
+/*
+ * Finds a free channel, and binds the requested device to it.
+ * Returns the allocated channel number, or negative on error.
+ */
+int request_au1000_dma(int dev_id, const char *dev_str)
+{
+	struct dma_chan *chan;
+	int i;
+
+	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
+		return -EINVAL;
+
+	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
+		if (au1000_dma_table[i].dev_id < 0)
+			break;
+	}
+	if (i == NUM_AU1000_DMA_CHANNELS)
+		return -ENODEV;
+
+	chan = &au1000_dma_table[i];
+
+	// fill it in
+	chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
+	chan->irq = AU1000_DMA_INT_BASE + i;
+	chan->dev_id = dev_id;
+	chan->dev_str = dev_str;
+	chan->fifo_addr = dma_dev_table[dev_id].fifo_addr;
+	chan->mode = dma_dev_table[dev_id].dma_mode;
+
+	return i;
+}
+
+
+void free_au1000_dma(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan) {
+		printk("Trying to free DMA%d\n", dmanr);
+		return;
+	}
+
+	disable_dma(dmanr);
+
+	chan->dev_id = -1;
+}				/* free_dma */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/int-handler.S linux/arch/mips/au1000/common/int-handler.S
--- linux.orig/arch/mips/au1000/common/int-handler.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/common/int-handler.S	2002-07-20 01:08:31.000000000 +0000
@@ -65,7 +65,5 @@
 
 5:	
 	move	a0, sp
-	jal	mips_spurious_interrupt
-done:
-	j	ret_from_irq
+	j	spurious_interrupt
 END(au1000_IRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/irq.c linux/arch/mips/au1000/common/irq.c
--- linux.orig/arch/mips/au1000/common/irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/common/irq.c	2002-07-20 01:08:33.000000000 +0000
@@ -47,7 +47,13 @@
 #include <asm/system.h>
 #include <asm/au1000.h>
 
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+#if defined(CONFIG_MIPS_PB1000)
+#include <asm/pb1000.h>
+#elif defined(CONFIG_MIPS_PB1500)
+#include <asm/pb1500.h>
+#else
+#error unsupported alchemy board
+#endif
 
 #undef DEBUG_IRQ
 #ifdef DEBUG_IRQ
@@ -68,11 +74,8 @@
 #endif
 
 extern asmlinkage void au1000_IRQ(void);
-
 extern void set_debug_traps(void);
-extern irq_cpustat_t irq_stat [];
-extern irq_desc_t irq_desc[NR_IRQS];
-
+extern irq_cpustat_t irq_stat [NR_CPUS];
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
 
@@ -82,147 +85,106 @@
 static inline void mask_and_ack_level_irq(unsigned int irq_nr);
 static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr);
 static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr);
-static inline void local_enable_irq(unsigned int irq_nr);
-static inline void local_disable_irq(unsigned int irq_nr);
+inline void local_enable_irq(unsigned int irq_nr);
+inline void local_disable_irq(unsigned int irq_nr);
 
-unsigned long spurious_interrupts;
 extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
 extern void __init init_generic_irq(void);
 
-static inline void sync(void)
-{
-	__asm volatile ("sync");
-}
-
-
-/* Function for careful CP0 interrupt mask access */
-static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
-{
-	unsigned long status = read_32bit_cp0_register(CP0_STATUS);
-	status &= ~((clr_mask & 0xFF) << 8);
-	status |=   (set_mask & 0xFF) << 8;
-	write_32bit_cp0_register(CP0_STATUS, status);
-}
-
-
-static inline void mask_cpu_irq_input(unsigned int irq_nr)
-{
-	modify_cp0_intmask(irq_nr, 0);
-}
-
-
-static inline void unmask_cpu_irq_input(unsigned int irq_nr)
-{
-	modify_cp0_intmask(0, irq_nr);
-}
-
-
-static void disable_cpu_irq_input(unsigned int irq_nr)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	mask_cpu_irq_input(irq_nr);
-	restore_flags(flags);
-}
-
-
-static void enable_cpu_irq_input(unsigned int irq_nr)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	unmask_cpu_irq_input(irq_nr);
-	restore_flags(flags);
-}
+#ifdef CONFIG_PM
+extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
+#endif
 
 
 static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
 {
+	if (irq_nr > AU1000_MAX_INTR) return;
 	/* Config2[n], Config1[n], Config0[n] */
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
 		switch (type) {
 			case INTC_INT_RISE_EDGE: /* 0:0:1 */
-				outl(1<<irq_nr,INTC1_CONFIG2_CLEAR);
-				outl(1<<irq_nr, INTC1_CONFIG1_CLEAR);
-				outl(1<<irq_nr, INTC1_CONFIG0_SET);
+				outl(1<<(irq_nr-32), IC1_CFG2CLR);
+				outl(1<<(irq_nr-32), IC1_CFG1CLR);
+				outl(1<<(irq_nr-32), IC1_CFG0SET);
 				break;
 			case INTC_INT_FALL_EDGE: /* 0:1:0 */
-				outl(1<<irq_nr, INTC1_CONFIG2_CLEAR);
-				outl(1<<irq_nr, INTC1_CONFIG1_SET);
-				outl(1<<irq_nr, INTC1_CONFIG0_CLEAR);
+				outl(1<<(irq_nr-32), IC1_CFG2CLR);
+				outl(1<<(irq_nr-32), IC1_CFG1SET);
+				outl(1<<(irq_nr-32), IC1_CFG0CLR);
 				break;
 			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
-				outl(1<<irq_nr, INTC1_CONFIG2_SET);
-				outl(1<<irq_nr, INTC1_CONFIG1_CLEAR);
-				outl(1<<irq_nr, INTC1_CONFIG0_SET);
+				outl(1<<(irq_nr-32), IC1_CFG2SET);
+				outl(1<<(irq_nr-32), IC1_CFG1CLR);
+				outl(1<<(irq_nr-32), IC1_CFG0SET);
 				break;
 			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
-				outl(1<<irq_nr, INTC1_CONFIG2_SET);
-				outl(1<<irq_nr, INTC1_CONFIG1_SET);
-				outl(1<<irq_nr, INTC1_CONFIG0_CLEAR);
+				outl(1<<(irq_nr-32), IC1_CFG2SET);
+				outl(1<<(irq_nr-32), IC1_CFG1SET);
+				outl(1<<(irq_nr-32), IC1_CFG0CLR);
 				break;
 			case INTC_INT_DISABLED: /* 0:0:0 */
-				outl(1<<irq_nr, INTC1_CONFIG0_CLEAR);
-				outl(1<<irq_nr, INTC1_CONFIG1_CLEAR);
-				outl(1<<irq_nr, INTC1_CONFIG2_CLEAR);
+				outl(1<<(irq_nr-32), IC1_CFG0CLR);
+				outl(1<<(irq_nr-32), IC1_CFG1CLR);
+				outl(1<<(irq_nr-32), IC1_CFG2CLR);
 				break;
 			default: /* disable the interrupt */
 				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
-				outl(1<<irq_nr, INTC1_CONFIG0_CLEAR);
-				outl(1<<irq_nr, INTC1_CONFIG1_CLEAR);
-				outl(1<<irq_nr, INTC1_CONFIG2_CLEAR);
+				outl(1<<(irq_nr-32), IC1_CFG0CLR);
+				outl(1<<(irq_nr-32), IC1_CFG1CLR);
+				outl(1<<(irq_nr-32), IC1_CFG2CLR);
 				return;
 		}
 		if (int_req) /* assign to interrupt request 1 */
-			outl(1<<irq_nr, INTC1_ASSIGN_REQ_CLEAR);
+			outl(1<<(irq_nr-32), IC1_ASSIGNCLR);
 		else	     /* assign to interrupt request 0 */
-			outl(1<<irq_nr, INTC1_ASSIGN_REQ_SET);
-		outl(1<<irq_nr, INTC1_SOURCE_SET);
-		outl(1<<irq_nr, INTC1_MASK_CLEAR);
+			outl(1<<(irq_nr-32), IC1_ASSIGNSET);
+		outl(1<<(irq_nr-32), IC1_SRCSET);
+		outl(1<<(irq_nr-32), IC1_MASKCLR);
+		outl(1<<(irq_nr-32), IC1_WAKECLR);
 	}
 	else {
 		switch (type) {
 			case INTC_INT_RISE_EDGE: /* 0:0:1 */
-				outl(1<<irq_nr,INTC0_CONFIG2_CLEAR);
-				outl(1<<irq_nr, INTC0_CONFIG1_CLEAR);
-				outl(1<<irq_nr, INTC0_CONFIG0_SET);
+				outl(1<<irq_nr, IC0_CFG2CLR);
+				outl(1<<irq_nr, IC0_CFG1CLR);
+				outl(1<<irq_nr, IC0_CFG0SET);
 				break;
 			case INTC_INT_FALL_EDGE: /* 0:1:0 */
-				outl(1<<irq_nr, INTC0_CONFIG2_CLEAR);
-				outl(1<<irq_nr, INTC0_CONFIG1_SET);
-				outl(1<<irq_nr, INTC0_CONFIG0_CLEAR);
+				outl(1<<irq_nr, IC0_CFG2CLR);
+				outl(1<<irq_nr, IC0_CFG1SET);
+				outl(1<<irq_nr, IC0_CFG0CLR);
 				break;
 			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
-				outl(1<<irq_nr, INTC0_CONFIG2_SET);
-				outl(1<<irq_nr, INTC0_CONFIG1_CLEAR);
-				outl(1<<irq_nr, INTC0_CONFIG0_SET);
+				outl(1<<irq_nr, IC0_CFG2SET);
+				outl(1<<irq_nr, IC0_CFG1CLR);
+				outl(1<<irq_nr, IC0_CFG0SET);
 				break;
 			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
-				outl(1<<irq_nr, INTC0_CONFIG2_SET);
-				outl(1<<irq_nr, INTC0_CONFIG1_SET);
-				outl(1<<irq_nr, INTC0_CONFIG0_CLEAR);
+				outl(1<<irq_nr, IC0_CFG2SET);
+				outl(1<<irq_nr, IC0_CFG1SET);
+				outl(1<<irq_nr, IC0_CFG0CLR);
 				break;
 			case INTC_INT_DISABLED: /* 0:0:0 */
-				outl(1<<irq_nr, INTC0_CONFIG0_CLEAR);
-				outl(1<<irq_nr, INTC0_CONFIG1_CLEAR);
-				outl(1<<irq_nr, INTC0_CONFIG2_CLEAR);
+				outl(1<<irq_nr, IC0_CFG0CLR);
+				outl(1<<irq_nr, IC0_CFG1CLR);
+				outl(1<<irq_nr, IC0_CFG2CLR);
 				break;
 			default: /* disable the interrupt */
 				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
-				outl(1<<irq_nr, INTC0_CONFIG0_CLEAR);
-				outl(1<<irq_nr, INTC0_CONFIG1_CLEAR);
-				outl(1<<irq_nr, INTC0_CONFIG2_CLEAR);
+				outl(1<<irq_nr, IC0_CFG0CLR);
+				outl(1<<irq_nr, IC0_CFG1CLR);
+				outl(1<<irq_nr, IC0_CFG2CLR);
 				return;
 		}
 		if (int_req) /* assign to interrupt request 1 */
-			outl(1<<irq_nr, INTC0_ASSIGN_REQ_CLEAR);
+			outl(1<<irq_nr, IC0_ASSIGNCLR);
 		else	     /* assign to interrupt request 0 */
-			outl(1<<irq_nr, INTC0_ASSIGN_REQ_SET);
-		outl(1<<irq_nr, INTC0_SOURCE_SET);
-		outl(1<<irq_nr, INTC0_MASK_CLEAR);
+			outl(1<<irq_nr, IC0_ASSIGNSET);
+		outl(1<<irq_nr, IC0_SRCSET);
+		outl(1<<irq_nr, IC0_MASKCLR);
+		outl(1<<irq_nr, IC0_WAKECLR);
 	}
-	sync();
+	au_sync();
 }
 
 
@@ -240,71 +202,136 @@
 }
 
 
-static inline void local_enable_irq(unsigned int irq_nr)
+inline void local_enable_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<irq_nr, INTC1_MASK_SET);
+		outl(1<<(irq_nr-32), IC1_MASKSET);
+		outl(1<<(irq_nr-32), IC1_WAKESET);
 	}
 	else {
-		outl(1<<irq_nr, INTC0_MASK_SET);
+		outl(1<<irq_nr, IC0_MASKSET);
+		outl(1<<irq_nr, IC0_WAKESET);
 	}
-	sync();
+	au_sync();
 }
 
 
-static inline void local_disable_irq(unsigned int irq_nr)
+inline void local_disable_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<irq_nr, INTC1_MASK_CLEAR);
+		outl(1<<(irq_nr-32), IC1_MASKCLR);
+		outl(1<<(irq_nr-32), IC1_WAKECLR);
 	}
 	else {
-		outl(1<<irq_nr, INTC0_MASK_CLEAR);
+		outl(1<<irq_nr, IC0_MASKCLR);
+		outl(1<<irq_nr, IC0_WAKECLR);
 	}
-	sync();
+	au_sync();
 }
 
 
 static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<irq_nr, INTC1_R_EDGE_DETECT_CLEAR);
-		outl(1<<irq_nr, INTC1_MASK_CLEAR);
+		outl(1<<(irq_nr-32), IC1_RISINGCLR);
+		outl(1<<(irq_nr-32), IC1_MASKCLR);
 	}
 	else {
-		outl(1<<irq_nr, INTC0_R_EDGE_DETECT_CLEAR);
-		outl(1<<irq_nr, INTC0_MASK_CLEAR);
+		outl(1<<irq_nr, IC0_RISINGCLR);
+		outl(1<<irq_nr, IC0_MASKCLR);
 	}
-	sync();
+	au_sync();
 }
 
 
 static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<irq_nr, INTC1_F_EDGE_DETECT_CLEAR);
-		outl(1<<irq_nr, INTC1_MASK_CLEAR);
+		outl(1<<(irq_nr-32), IC1_FALLINGCLR);
+		outl(1<<(irq_nr-32), IC1_MASKCLR);
 	}
 	else {
-		outl(1<<irq_nr, INTC0_F_EDGE_DETECT_CLEAR);
-		outl(1<<irq_nr, INTC0_MASK_CLEAR);
+		outl(1<<irq_nr, IC0_FALLINGCLR);
+		outl(1<<irq_nr, IC0_MASKCLR);
 	}
+	au_sync();
 }
 
 
 static inline void mask_and_ack_level_irq(unsigned int irq_nr)
 {
+
 	local_disable_irq(irq_nr);
-	sync();
+	au_sync();
+#if defined(CONFIG_MIPS_PB1000)
+	if (irq_nr == AU1000_GPIO_15) {
+		writew(0x8000, PB1000_MDR); /* ack int */
+		au_sync();
+	}
+#endif
 	return;
 }
 
 
 static void end_irq(unsigned int irq_nr)
 {
-	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
 		local_enable_irq(irq_nr);
+	}
+	else {
+		printk("warning: end_irq %d did not enable (%x)\n", 
+				irq_nr, irq_desc[irq_nr].status);
+	}
+#if defined(CONFIG_MIPS_PB1000)
+	if (irq_nr == AU1000_GPIO_15) {
+		writew(0x4000, PB1000_MDR); /* enable int */
+		au_sync();
+	}
+#endif
+}
+
+unsigned long save_local_and_disable(int controller)
+{
+	int i;
+	unsigned long flags, mask;
+	save_and_cli(flags);
+
+	if (controller) {
+		mask = readl(IC1_MASKSET);
+		for (i=32; i<64; i++) {
+			local_disable_irq(i);
+		}
+	}
+	else {
+		mask = readl(IC0_MASKSET);
+		for (i=0; i<32; i++) {
+			local_disable_irq(i);
+		}
+	}
+	restore_flags(flags);
+	return mask;
+}
+
+void restore_local_and_enable(int controller, unsigned long mask)
+{
+	int i;
+	unsigned long flags, new_mask;
+	save_and_cli(flags);
+
+	for (i=0; i<32; i++) {
+		if (mask & (1<<i)) {
+			if (controller)
+				local_enable_irq(i+32);
+			else
+				local_enable_irq(i);
+		}
+	}
+	if (controller)
+		new_mask = readl(IC1_MASKSET);
 	else
-		printk("warning: end_irq %d did not enable\n", irq_nr);
+		new_mask = readl(IC0_MASKSET);
+
+	restore_flags(flags);
 }
 
 
@@ -343,37 +370,104 @@
 	NULL
 };
 
-
-void enable_cpu_timer(void)
+#ifdef CONFIG_PM
+void startup_match20_interrupt(void)
 {
-	enable_cpu_irq_input(1<<MIPS_TIMER_IP); /* timer interrupt */
+	local_enable_irq(AU1000_TOY_MATCH2_INT);
 }
+#endif
 
 
 void __init init_IRQ(void)
 {
 	int i;
 	unsigned long cp0_status;
+	extern char except_vec0_au1000;
 
 	cp0_status = read_32bit_cp0_register(CP0_STATUS);
 	memset(irq_desc, 0, sizeof(irq_desc));
 	set_except_vector(0, au1000_IRQ);
 
 	init_generic_irq();
+
+	/* override the generic vec0 handler */
+	memcpy((void *)KSEG0, &except_vec0_au1000, 0x80);
+	flush_icache_range(KSEG0, KSEG0 + 0x200);
 	
-	/* 
-	 * Setup high priority interrupts on int_request0; low priority on
-	 * int_request1
-	 */
-	for (i = 0; i <= NR_IRQS; i++) {
+	for (i = 0; i <= AU1000_MAX_INTR; i++) {
 		switch (i) {
+			case AU1000_UART0_INT:
+			case AU1000_UART3_INT:
+#ifdef CONFIG_MIPS_PB1000
+			case AU1000_UART1_INT:
+			case AU1000_UART2_INT:
+
+			case AU1000_SSI0_INT:
+			case AU1000_SSI1_INT:
+#endif
+
+		        case AU1000_DMA_INT_BASE:
+		        case AU1000_DMA_INT_BASE+1:
+		        case AU1000_DMA_INT_BASE+2:
+		        case AU1000_DMA_INT_BASE+3:
+		        case AU1000_DMA_INT_BASE+4:
+		        case AU1000_DMA_INT_BASE+5:
+		        case AU1000_DMA_INT_BASE+6:
+		        case AU1000_DMA_INT_BASE+7:
+
+			case AU1000_IRDA_TX_INT:
+			case AU1000_IRDA_RX_INT:
+
 			case AU1000_MAC0_DMA_INT:
 			case AU1000_MAC1_DMA_INT:
+
+			case AU1500_GPIO_204:
 				setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
 				irq_desc[i].handler = &level_irq_type;
 				break;
+
+#ifdef CONFIG_MIPS_PB1000
+			case AU1000_GPIO_15:
+#endif
+		        case AU1000_USB_HOST_INT:
+#ifdef CONFIG_MIPS_PB1500
+			case AU1000_PCI_INTA:
+			case AU1000_PCI_INTB:
+			case AU1000_PCI_INTC:
+			case AU1000_PCI_INTD:
+			case AU1500_GPIO_201:
+			case AU1500_GPIO_202:
+			case AU1500_GPIO_203:
+			case AU1500_GPIO_205:
+			case AU1500_GPIO_207:
+#endif
+				setup_local_irq(i, INTC_INT_LOW_LEVEL, 0);
+				irq_desc[i].handler = &level_irq_type;
+                                break;
+			case AU1000_ACSYNC_INT:
+			case AU1000_AC97C_INT:
+		        case AU1000_USB_DEV_REQ_INT:
+		        case AU1000_USB_DEV_SUS_INT:
+			case AU1000_TOY_INT:
+			case AU1000_TOY_MATCH0_INT:
+			case AU1000_TOY_MATCH1_INT:
+			case AU1000_RTC_INT:
+			case AU1000_RTC_MATCH0_INT:
+			case AU1000_RTC_MATCH1_INT:
+			case AU1000_RTC_MATCH2_INT:
+			        setup_local_irq(i, INTC_INT_RISE_EDGE, 0);
+                                irq_desc[i].handler = &rise_edge_irq_type;
+                                break;
+
+				 // Careful if you change match 2 request!
+				 // The interrupt handler is called directly
+				 // from the low level dispatch code.
+			case AU1000_TOY_MATCH2_INT:
+				 setup_local_irq(i, INTC_INT_RISE_EDGE, 1);
+				 irq_desc[i].handler = &rise_edge_irq_type;
+				  break;
 			default: /* active high, level interrupt */
-				setup_local_irq(i, INTC_INT_HIGH_LEVEL, 1);
+				setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
 				irq_desc[i].handler = &level_irq_type;
 				break;
 		}
@@ -389,27 +483,28 @@
 }
 
 
-void mips_spurious_interrupt(struct pt_regs *regs)
-{
-	spurious_interrupts++;
-}
-
+/*
+ * Interrupts are nested. Even if an interrupt handler is registered
+ * as "fast", we might get another interrupt before we return from
+ * intcX_reqX_irqdispatch().
+ */
 
 void intc0_req0_irqdispatch(struct pt_regs *regs)
 {
 	int irq = 0, i;
-	unsigned long int_request;
+	static unsigned long intc0_req0 = 0;
 
-	int_request = inl(INTC0_REQ0_INT);
+	intc0_req0 |= inl(IC0_REQ0INT);
 
-	if (!int_request) return;
+	if (!intc0_req0) return;
 
 	for (i=0; i<32; i++) {
-		if ((int_request & 0x1)) {
+		if ((intc0_req0 & (1<<i))) {
+			intc0_req0 &= ~(1<<i);
 			do_IRQ(irq, regs);
+			break;
 		}
 		irq++;
-		int_request >>= 1;
 	}
 }
 
@@ -417,55 +512,86 @@
 void intc0_req1_irqdispatch(struct pt_regs *regs)
 {
 	int irq = 0, i;
-	unsigned long int_request;
+	static unsigned long intc0_req1 = 0;
 
-	int_request = inl(INTC0_REQ1_INT);
+	intc0_req1 = inl(IC0_REQ1INT);
 
-	if (!int_request) return;
+	if (!intc0_req1) return;
 
 	for (i=0; i<32; i++) {
-		if ((int_request & 0x1)) {
-			do_IRQ(irq, regs);
+		if ((intc0_req1 & (1<<i))) {
+			intc0_req1 &= ~(1<<i);
+#ifdef CONFIG_PM
+			if (i == AU1000_TOY_MATCH2_INT) {
+				mask_and_ack_rise_edge_irq(irq);
+				counter0_irq(irq, NULL, regs);
+				local_enable_irq(irq);
+			}
+			else 
+#endif
+			{
+				do_IRQ(irq, regs);
+			}
+			break;
 		}
 		irq++;
-		int_request >>= 1;
 	}
 }
 
 
+/*
+ * Interrupt Controller 1:
+ * interrupts 32 - 63
+ */
 void intc1_req0_irqdispatch(struct pt_regs *regs)
 {
 	int irq = 0, i;
-	unsigned long int_request;
+	static unsigned long intc1_req0 = 0;
+	volatile unsigned short levels, mdr;
+	unsigned char ide_status;
 
-	int_request = inl(INTC1_REQ0_INT);
+	intc1_req0 |= inl(IC1_REQ0INT);
 
-	if (!int_request) return;
+	if (!intc1_req0) return;
 
+#ifdef CONFIG_MIPS_PB1000
+	writew(1, CPLD_AUX0); /* debug led 0 */
+#endif
 	for (i=0; i<32; i++) {
-		if ((int_request & 0x1)) {
-			do_IRQ(irq, regs);
+		if ((intc1_req0 & (1<<i))) {
+			intc1_req0 &= ~(1<<i);
+#ifdef CONFIG_MIPS_PB1000
+			writew(2, CPLD_AUX0); /* turn on debug led 1  */
+			do_IRQ(irq+32, regs);
+			writew(0, CPLD_AUX0); /* turn off debug led 1 */
+#else
+			do_IRQ(irq+32, regs);
+#endif
+			break;
 		}
 		irq++;
-		int_request >>= 1;
 	}
+#ifdef CONFIG_MIPS_PB1000
+	writew(0, CPLD_AUX0);
+#endif
 }
 
 
 void intc1_req1_irqdispatch(struct pt_regs *regs)
 {
 	int irq = 0, i;
-	unsigned long int_request;
+	static unsigned long intc1_req1 = 0;
 
-	int_request = inl(INTC1_REQ1_INT);
+	intc1_req1 |= inl(IC1_REQ1INT);
 
-	if (!int_request) return;
+	if (!intc1_req1) return;
 
 	for (i=0; i<32; i++) {
-		if ((int_request & 0x1)) {
-			do_IRQ(irq, regs);
+		if ((intc1_req1 & (1<<i))) {
+			intc1_req1 &= ~(1<<i);
+			do_IRQ(irq+32, regs);
+			break;
 		}
 		irq++;
-		int_request >>= 1;
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/power.c linux/arch/mips/au1000/common/power.c
--- linux.orig/arch/mips/au1000/common/power.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/common/power.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,341 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 Power Management routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *		ppopov@mvista.com or source@mvista.com
+ *
+ *  Some of the routines are right out of init/main.c, whose
+ *  copyrights apply here.
+ *
+ *  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  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/sysctl.h>
+#include <linux/acpi.h>
+
+#include <asm/string.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/au1000.h>
+
+#define DEBUG 1
+#ifdef DEBUG
+#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
+inline void au1_wait(void);
+static void calibrate_delay(void);
+
+extern void set_au1000_speed(unsigned int new_freq);
+extern unsigned int get_au1000_speed(void);
+extern unsigned long get_au1000_uart_baud_base(void);
+extern void set_au1000_uart_baud_base(unsigned long new_baud_base);
+extern unsigned long save_local_and_disable(int controller);
+extern void restore_local_and_enable(int controller, unsigned long mask);
+extern void local_enable_irq(unsigned int irq_nr);
+
+/* Quick acpi hack. This will have to change! */
+#define	CTL_ACPI 9999
+#define	ACPI_S1_SLP_TYP 19
+#define	ACPI_SLEEP 21
+
+#ifdef CONFIG_PM
+
+unsigned long suspend_mode;
+
+void wakeup_from_suspend(void)
+{
+	suspend_mode = 0;
+}
+
+int au_sleep(void)
+{
+	unsigned long wakeup, flags;
+	save_and_cli(flags);
+
+	flush_cache_all();
+	/* pin 6 is gpio */
+	writel(readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
+
+	/* gpio 6 can cause a wake up event */
+	wakeup = readl(SYS_WAKEMSK);
+	wakeup &= ~(1 << 8);	/* turn off match20 wakeup */
+	wakeup |= 1 << 6;	/* turn on gpio 6 wakeup   */
+	writel(wakeup, SYS_WAKEMSK);
+
+	writel(1, SYS_WAKESRC);	/* clear cause */
+	writel(1, SYS_SLPPWR);	/* prepare to sleep */
+
+	__asm__("la $4, 1f\n\t"
+		"lui $5, 0xb190\n\t"
+		"ori $5, 0x18\n\t"
+		"sw $4, 0($5)\n\t"
+		"li $4, 1\n\t"
+		"lui $5, 0xb190\n\t"
+		"ori $5, 0x7c\n\t"
+		"sw $4, 0($5)\n\t" "sync\n\t" "1:\t\n\t" "nop\n\t");
+
+	/* after a wakeup, the cpu vectors back to 0x1fc00000 so
+	 * it's up to the boot code to get us back here.
+	 */
+	restore_flags(flags);
+	return 0;
+}
+
+static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
+		       void *buffer, size_t * len)
+{
+	int retval = 0;
+
+	if (!write) {
+		*len = 0;
+	} else {
+		retval = pm_send_all(PM_SUSPEND, (void *) 2);
+		if (retval)
+			return retval;
+
+		au_sleep();
+		retval = pm_send_all(PM_RESUME, (void *) 0);
+	}
+	return retval;
+}
+
+static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
+			 void *buffer, size_t * len)
+{
+	int retval = 0;
+
+	if (!write) {
+		*len = 0;
+	} else {
+		retval = pm_send_all(PM_SUSPEND, (void *) 2);
+		if (retval)
+			return retval;
+		suspend_mode = 1;
+		au1_wait();
+		retval = pm_send_all(PM_RESUME, (void *) 0);
+	}
+	return retval;
+}
+
+
+static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
+		      void *buffer, size_t * len)
+{
+	int retval = 0, i;
+	unsigned long val, pll;
+#define TMPBUFLEN 64
+#define MAX_CPU_FREQ 396
+	char buf[8], *p;
+	unsigned long flags, intc0_mask, intc1_mask;
+	unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
+	    old_refresh;
+	unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
+
+	save_and_cli(flags);
+	if (!write) {
+		*len = 0;
+	} else {
+		/* Parse the new frequency */
+		if (*len > TMPBUFLEN - 1) {
+			restore_flags(flags);
+			return -EFAULT;
+		}
+		if (copy_from_user(buf, buffer, *len)) {
+			restore_flags(flags);
+			return -EFAULT;
+		}
+		buf[*len] = 0;
+		p = buf;
+		val = simple_strtoul(p, &p, 0);
+		if (val > MAX_CPU_FREQ) {
+			restore_flags(flags);
+			return -EFAULT;
+		}
+
+		pll = val / 12;
+		if ((pll > 33) || (pll < 7)) {	/* 396 MHz max, 84 MHz min */
+			/* revisit this for higher speed cpus */
+			restore_flags(flags);
+			return -EFAULT;
+		}
+
+		old_baud_base = get_au1000_uart_baud_base();
+		old_cpu_freq = get_au1000_speed();
+
+		new_cpu_freq = pll * 12 * 1000000;
+		new_baud_base = (new_cpu_freq / 4) / 16;
+		set_au1000_speed(new_cpu_freq);
+		set_au1000_uart_baud_base(new_baud_base);
+
+		old_refresh = readl(MEM_SDREFCFG) & 0x1ffffff;
+		new_refresh =
+		    ((old_refresh * new_cpu_freq) /
+		     old_cpu_freq) | (readl(MEM_SDREFCFG) & ~0x1ffffff);
+
+		writel(pll, SYS_CPUPLL);
+		au_sync_delay(1);
+		writel(new_refresh, MEM_SDREFCFG);
+		au_sync_delay(1);
+
+		for (i = 0; i < 4; i++) {
+			if (readl
+			    (UART_BASE + UART_MOD_CNTRL +
+			     i * 0x00100000) == 3) {
+				old_clk =
+				    readl(UART_BASE + UART_CLK +
+					  i * 0x00100000);
+				// baud_rate = baud_base/clk
+				baud_rate = old_baud_base / old_clk;
+				/* we won't get an exact baud rate and the error
+				 * could be significant enough that our new
+				 * calculation will result in a clock that will
+				 * give us a baud rate that's too far off from
+				 * what we really want.
+				 */
+				if (baud_rate > 100000)
+					baud_rate = 115200;
+				else if (baud_rate > 50000)
+					baud_rate = 57600;
+				else if (baud_rate > 30000)
+					baud_rate = 38400;
+				else if (baud_rate > 17000)
+					baud_rate = 19200;
+				else
+					(baud_rate = 9600);
+				// new_clk = new_baud_base/baud_rate
+				new_clk = new_baud_base / baud_rate;
+				writel(new_clk,
+				       UART_BASE + UART_CLK +
+				       i * 0x00100000);
+				au_sync_delay(10);
+			}
+		}
+	}
+
+
+	/* We don't want _any_ interrupts other than
+	 * match20. Otherwise our calibrate_delay()
+	 * calculation will be off, potentially a lot.
+	 */
+	intc0_mask = save_local_and_disable(0);
+	intc1_mask = save_local_and_disable(1);
+	local_enable_irq(AU1000_TOY_MATCH2);
+	restore_flags(flags);
+	calibrate_delay();
+	restore_local_and_enable(0, intc0_mask);
+	restore_local_and_enable(1, intc1_mask);
+	return retval;
+}
+
+
+static struct ctl_table pm_table[] = {
+	{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, &pm_do_suspend},
+	{ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &pm_do_sleep},
+	{CTL_ACPI, "freq", NULL, 0, 0600, NULL, &pm_do_freq},
+	{0}
+};
+
+static struct ctl_table pm_dir_table[] = {
+	{CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
+	{0}
+};
+
+/*
+ * Initialize power interface
+ */
+static int __init pm_init(void)
+{
+	register_sysctl_table(pm_dir_table, 1);
+	return 0;
+}
+
+__initcall(pm_init);
+
+inline void au1_wait(void)
+{
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		"nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0");
+}
+
+
+/*
+ * This is right out of init/main.c
+ */
+
+/* This is the number of bits of precision for the loops_per_jiffy.  Each
+   bit takes on average 1.5/HZ seconds.  This (like the original) is a little
+   better than 1% */
+#define LPS_PREC 8
+
+static void calibrate_delay(void)
+{
+	unsigned long ticks, loopbit;
+	int lps_precision = LPS_PREC;
+
+	loops_per_jiffy = (1 << 12);
+
+	while (loops_per_jiffy <<= 1) {
+		/* wait for "start of" clock tick */
+		ticks = jiffies;
+		while (ticks == jiffies)
+			/* nothing */ ;
+		/* Go .. */
+		ticks = jiffies;
+		__delay(loops_per_jiffy);
+		ticks = jiffies - ticks;
+		if (ticks)
+			break;
+	}
+
+/* Do a binary approximation to get loops_per_jiffy set to equal one clock
+   (up to lps_precision bits) */
+	loops_per_jiffy >>= 1;
+	loopbit = loops_per_jiffy;
+	while (lps_precision-- && (loopbit >>= 1)) {
+		loops_per_jiffy |= loopbit;
+		ticks = jiffies;
+		while (ticks == jiffies);
+		ticks = jiffies;
+		__delay(loops_per_jiffy);
+		if (jiffies != ticks)	/* longer than 1 tick */
+			loops_per_jiffy &= ~loopbit;
+	}
+}
+
+
+#else				/* CONFIG_PM */
+
+void au1_wait(void)
+{
+	__asm__("nop\n\t" "nop\n\t");
+}
+
+#endif				/* CONFIG_PM */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/prom.c linux/arch/mips/au1000/common/prom.c
--- linux.orig/arch/mips/au1000/common/prom.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/common/prom.c	2002-07-20 01:08:27.000000000 +0000
@@ -4,7 +4,7 @@
  *    PROM library initialisation code, assuming a version of
  *    pmon is the boot code.
  *
- * Copyright 2000 MontaVista Software Inc.
+ * Copyright 2000,2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
@@ -35,7 +35,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/string.h>
@@ -44,22 +44,23 @@
 
 /* #define DEBUG_CMDLINE */
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
-int prom_argc;
-char **prom_argv, **prom_envp;
+char arcs_cmdline[CL_SIZE];
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
 
-typedef struct {
-	char *name;
-/*	char *val; */
-} t_env_var;
+typedef struct
+{
+    char *name;
+/*    char *val; */
+}t_env_var;
 
 
-char * __init prom_getcmdline(void)
+char * prom_getcmdline(void)
 {
 	return &(arcs_cmdline[0]);
 }
 
-void  __init prom_init_cmdline(void)
+void  prom_init_cmdline(void)
 {
 	char *cp;
 	int actr;
@@ -101,7 +102,7 @@
 	return(NULL);
 }
 
-static inline unsigned char str2hexnum(unsigned char c)
+inline unsigned char str2hexnum(unsigned char c)
 {
 	if(c >= '0' && c <= '9')
 	return c - '0';
@@ -110,11 +111,43 @@
 	return 0; /* foo */
 }
 
-int __init page_is_ram(unsigned long pagenr)
+inline void str2eaddr(unsigned char *ea, unsigned char *str)
 {
-	return 1;
-}
+	int i;
 
-void prom_free_prom_memory (void)
+	for(i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if((*str == '.') || (*str == ':'))
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+ 
+int get_ethernet_addr(char *ethernet_addr)
 {
+	int i;
+        char *ethaddr_str;
+
+        ethaddr_str = prom_getenv("ethaddr");
+	if (!ethaddr_str) {
+	        printk("ethaddr not set in boot prom\n");
+		return -1;
+	}
+	str2eaddr(ethernet_addr, ethaddr_str);
+
+#if 0
+	printk("get_ethernet_addr: ");
+	for (i=0; i<5; i++)
+		printk("%02x:", (unsigned char)*(ethernet_addr+i));
+	printk("%02x\n", *(ethernet_addr+i));
+#endif
+
+	return 0;
 }
+
+void prom_free_prom_memory (void) {}
+EXPORT_SYMBOL(prom_getcmdline);
+EXPORT_SYMBOL(get_ethernet_addr);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/reset.c linux/arch/mips/au1000/common/reset.c
--- linux.orig/arch/mips/au1000/common/reset.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/common/reset.c	2002-07-20 01:08:24.000000000 +0000
@@ -36,8 +36,56 @@
 #include <asm/reboot.h>
 #include <asm/system.h>
 
+extern int au_sleep(void);
+
 void au1000_restart(char *command)
 {
+	/* Set all integrated peripherals to disabled states */
+	u32 prid = read_32bit_cp0_register(CP0_PRID);
+
+	printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
+	switch (prid & 0xFF000000)
+	{
+	case 0x00000000: /* Au1000 */
+		outl(0x02, 0xb0000010); /* ac97_enable */
+		outl(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		asm("sync");
+		outl(0x00, 0xb017fffc); /* usbh_enable */
+		outl(0x00, 0xb0200058); /* usbd_enable */
+		outl(0x00, 0xb0300040); /* ir_enable */
+		outl(0x00, 0xb0520000); /* macen0 */
+		outl(0x00, 0xb0520004); /* macen1 */
+		outl(0x00, 0xb1000008); /* i2s_enable  */
+		outl(0x00, 0xb1100100); /* uart0_enable */
+		outl(0x00, 0xb1200100); /* uart1_enable */
+		outl(0x00, 0xb1300100); /* uart2_enable */
+		outl(0x00, 0xb1400100); /* uart3_enable */
+		outl(0x02, 0xb1600100); /* ssi0_enable */
+		outl(0x02, 0xb1680100); /* ssi1_enable */
+		outl(0x00, 0xb1900020); /* sys_freqctrl0 */
+		outl(0x00, 0xb1900024); /* sys_freqctrl1 */
+		outl(0x00, 0xb1900028); /* sys_clksrc */
+		outl(0x00, 0xb1900100); /* sys_pininputen */
+		break;
+	case 0x01000000: /* Au1500 */
+		outl(0x02, 0xb0000010); /* ac97_enable */
+		outl(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		asm("sync");
+		outl(0x00, 0xb017fffc); /* usbh_enable */
+		outl(0x00, 0xb0200058); /* usbd_enable */
+		outl(0x00, 0xb1520000); /* macen0 */
+		outl(0x00, 0xb1520004); /* macen1 */
+		outl(0x00, 0xb1100100); /* uart0_enable */
+		outl(0x00, 0xb1400100); /* uart3_enable */
+		outl(0x00, 0xb1900020); /* sys_freqctrl0 */
+		outl(0x00, 0xb1900024); /* sys_freqctrl1 */
+		outl(0x00, 0xb1900028); /* sys_clksrc */
+		outl(0x00, 0xb1900100); /* sys_pininputen */
+
+	default:
+		break;
+	}
+
 	set_cp0_status(ST0_BEV | ST0_ERL);
 	set_cp0_config(CONF_CM_UNCACHED);
 	flush_cache_all();
@@ -48,10 +96,18 @@
 void au1000_halt(void)
 {
 	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+#ifdef CONFIG_PM
+	au_sleep();
+
+	/* should not get here */
+	printk(KERN_ERR "Unable to put cpu in sleep mode\n");
+	while(1);
+#else
 	while (1)
 		__asm__(".set\tmips3\n\t"
 	                "wait\n\t"
 			".set\tmips0");
+#endif
 }
 
 void au1000_power_off(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/rtc.c linux/arch/mips/au1000/common/rtc.c
--- linux.orig/arch/mips/au1000/common/rtc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/common/rtc.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * RTC routines for PC style attached Dallas chip.
+ *
+ * Copyright (C) 1998, 2001 by Ralf Baechle
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/io.h>
+
+#define PB1500_RTC_ADDR 0xAC000000
+
+static unsigned char std_rtc_read_data(unsigned long addr)
+{
+	addr <<= 2;
+	return readb(addr + PB1500_RTC_ADDR);
+}
+
+static void std_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	addr <<= 2;
+	writeb(data, addr + PB1500_RTC_ADDR);
+}
+
+static int std_rtc_bcd_mode(void)
+{
+	return 1;
+}
+
+struct rtc_ops pb1500_rtc_ops = {
+	&std_rtc_read_data,
+	&std_rtc_write_data,
+	&std_rtc_bcd_mode
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/serial.c linux/arch/mips/au1000/common/serial.c
--- linux.orig/arch/mips/au1000/common/serial.c	2001-10-05 19:06:51.000000000 +0000
+++ linux/arch/mips/au1000/common/serial.c	2002-07-20 01:08:31.000000000 +0000
@@ -131,7 +131,7 @@
 
 static struct timer_list serial_timer;
 
-extern unsigned long get_au1000_uart_baud(void);
+extern unsigned long get_au1000_uart_baud_base(void);
 
 /* serial subtype definitions */
 #ifndef SERIAL_TYPE_NORMAL
@@ -241,12 +241,12 @@
 
 static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
 {
-	return (inl(info->port+offset) & 0xff);
+	return (inl(info->port+offset) & 0xffff);
 }
 
 static _INLINE_ void serial_out(struct async_struct *info, int offset, int value)
 {
-	outl(value & 0xff, info->port+offset);
+	outl(value & 0xffff, info->port+offset);
 }
 
 
@@ -752,6 +752,7 @@
 
 	if (inl(UART_MOD_CNTRL + state->port) != 0x3) {
 		outl(3, UART_MOD_CNTRL + state->port);
+		au_sync_delay(10);
 	}
 #ifdef SERIAL_DEBUG_OPEN
 	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
@@ -986,6 +987,10 @@
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
 	info->flags &= ~ASYNC_INITIALIZED;
+#ifndef CONFIG_REMOTE_DEBUG
+	outl(0, UART_MOD_CNTRL + state->port);
+	au_sync_delay(10);
+#endif
 	restore_flags(flags);
 }
 
@@ -1037,7 +1042,8 @@
 	if (!baud) {
 		baud = 9600;	/* B0 transition handled in rs_set_termios */
 	}
-	baud_base = info->state->baud_base;
+	baud_base = get_au1000_uart_baud_base();
+
 	//if (baud == 38400 &&
 	if (((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
 		quot = info->state->custom_divisor;
@@ -2511,6 +2517,7 @@
 
 	if (inl(UART_MOD_CNTRL + state->port) != 0x3) {
 		outl(3, UART_MOD_CNTRL + state->port);
+		au_sync_delay(10);
 	}
 		
 	state->type = PORT_16550;
@@ -2541,7 +2548,11 @@
 	serial_outp(info, UART_FCR, 0);
 	(void)serial_in(info, UART_RX);
 	serial_outp(info, UART_IER, 0);
-	
+
+#ifndef CONFIG_REMOTE_DEBUG
+	outl(0, UART_MOD_CNTRL + state->port);
+	au_sync_delay(10);
+#endif
 	restore_flags(flags);
 }
 
@@ -2643,12 +2654,12 @@
 	callout_driver.proc_entry = 0;
 
 	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register serial driver\n");
+		panic("Couldn't register serial driver");
 	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
+		panic("Couldn't register callout driver");
 	
 	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
-		state->baud_base = get_au1000_uart_baud();
+		state->baud_base = get_au1000_uart_baud_base();
 		state->magic = SSTATE_MAGIC;
 		state->line = i;
 		state->type = PORT_UNKNOWN;
@@ -2922,35 +2933,6 @@
 	serial_out(info, UART_IER, ier);
 }
 
-/*
- *	Receive character from the serial port
- */
-static int serial_console_wait_key(struct console *co)
-{
-	static struct async_struct *info;
-	int ier, c;
-
-	info = &async_sercons;
-
-	/*
-	 *	First save the IER then disable the interrupts so
-	 *	that the real driver for the port does not get the
-	 *	character.
-	 */
-	ier = serial_in(info, UART_IER);
-	serial_out(info, UART_IER, 0x00);
- 
-	while ((serial_in(info, UART_LSR) & UART_LSR_DR) == 0);
-	c = serial_in(info, UART_RX);
-
-	/*
-	 *	Restore the interrupts
-	 */
-	serial_out(info, UART_IER, ier);
-
-	return c;
-}
-
 static kdev_t serial_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
@@ -3044,7 +3026,7 @@
 	info->io_type = state->io_type;
 	info->iomem_base = state->iomem_base;
 	info->iomem_reg_shift = state->iomem_reg_shift;
-	state->baud_base = get_au1000_uart_baud();
+	state->baud_base = get_au1000_uart_baud_base();
 	quot = state->baud_base / baud;
 
 	cval = cflag & (CSIZE | CSTOPB);
@@ -3075,7 +3057,6 @@
 	name:		"ttyS",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/time.c linux/arch/mips/au1000/common/time.c
--- linux.orig/arch/mips/au1000/common/time.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/common/time.c	2002-07-20 01:08:32.000000000 +0000
@@ -1,4 +1,5 @@
 /*
+ * 
  * Copyright (C) 2001 MontaVista Software, ppopov@mvista.com
  * Copied and modified Carsten Langgaard's time.c
  *
@@ -23,7 +24,10 @@
  * ########################################################################
  *
  * Setting up the clock on the MIPS boards.
+ *
  */
+
+#include <linux/types.h>
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
@@ -32,28 +36,38 @@
 
 #include <asm/mipsregs.h>
 #include <asm/ptrace.h>
+#include <asm/time.h>
+#include <asm/hardirq.h>
 #include <asm/div64.h>
 #include <asm/au1000.h>
 
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 
+extern void startup_match20_interrupt(void);
+
 extern volatile unsigned long wall_jiffies;
 unsigned long missed_heart_beats = 0;
-unsigned long uart_baud_base;
 
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
 extern rwlock_t xtime_lock;
+unsigned int mips_counter_frequency = 0;
+
+/* Cycle counter value at the previous timer interrupt.. */
+static unsigned int timerhi = 0, timerlo = 0;
 
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+#ifdef CONFIG_PM
+#define MATCH20_INC 328
+extern void startup_match20_interrupt(void);
+static unsigned long last_pc0, last_match20;
+#endif
 
 static inline void ack_r4ktimer(unsigned long newval)
 {
 	write_32bit_cp0_register(CP0_COMPARE, newval);
 }
 
-
 /*
  * There are a lot of conceptually broken versions of the MIPS timer interrupt
  * handler floating around.  This one is rather different, but the algorithm
@@ -62,12 +76,27 @@
 unsigned long wtimer;
 void mips_timer_interrupt(struct pt_regs *regs)
 {
-	int irq = 7;
+	int irq = 63;
+	unsigned long count;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+
+#ifdef CONFIG_PM
+	printk(KERN_ERR "Unexpected CP0 interrupt\n");
+	regs->cp0_status &= ~IE_IRQ5; /* disable CP0 interrupt */
+	return;
+#endif
 
 	if (r4k_offset == 0)
 		goto null;
 
 	do {
+		count = read_32bit_cp0_register(CP0_COUNT);
+		timerhi += (count < timerlo);   /* Wrap around */
+		timerlo = count;
+
 		kstat.irqs[0][irq]++;
 		do_timer(regs);
 		r4k_cur += r4k_offset;
@@ -76,12 +105,61 @@
 	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
 	         - r4k_cur) < 0x7fffffff);
 
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
 	return;
 
 null:
 	ack_r4ktimer(0);
 }
 
+#ifdef CONFIG_PM
+void counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long pc0;
+	int time_elapsed;
+	static int jiffie_drift = 0;
+
+	kstat.irqs[0][irq]++;
+	if (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
+		/* should never happen! */
+		printk(KERN_WARNING "counter 0 w status eror\n");
+		return;
+	}
+
+	pc0 = inl(SYS_TOYREAD);
+	if (pc0 < last_match20) {
+		/* counter overflowed */
+		time_elapsed = (0xffffffff - last_match20) + pc0;
+	}
+	else {
+		time_elapsed = pc0 - last_match20;
+	}
+
+	while (time_elapsed > 0) {
+		do_timer(regs);
+		time_elapsed -= MATCH20_INC;
+		last_match20 += MATCH20_INC;
+		jiffie_drift++;
+	}
+
+	last_pc0 = pc0;
+	outl(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+	au_sync();
+
+	/* our counter ticks at 10.009765625 ms/tick, we we're running
+	 * almost 10uS too slow per tick.
+	 */
+	 
+	if (jiffie_drift >= 999) {
+		jiffie_drift -= 999;
+		do_timer(regs); /* increment jiffies by one */
+	}
+}
+#endif
+
 /* 
  * Figure out the r4k offset, the amount to increment the compare
  * register for each time tick. 
@@ -90,49 +168,48 @@
 unsigned long cal_r4koff(void)
 {
 	unsigned long count;
-	unsigned long cpu_pll;
 	unsigned long cpu_speed;
 	unsigned long start, end;
 	unsigned long counter;
-	int i;
 	int trim_divide = 16;
+	unsigned long flags;
 
-	counter = inl(PC_COUNTER_CNTRL);
-	outl(counter | PC_CNTRL_EN1, PC_COUNTER_CNTRL);
+	save_and_cli(flags);
 
-	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T1S);
-	outl(trim_divide-1, PC1_TRIM);    /* RTC now ticks at 32.768/16 kHz */
-	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T1S);
-
-	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_C1S);
-	outl (0, PC1_COUNTER_WRITE);
-	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_C1S);
+	counter = inl(SYS_COUNTER_CNTRL);
+	outl(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);
 
-	start = inl(PC1_COUNTER_READ);
+	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+	outl(trim_divide-1, SYS_RTCTRIM); /* RTC now ticks at 32.768/16 kHz */
+	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+
+	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+	outl (0, SYS_TOYWRITE);
+	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+
+	start = inl(SYS_RTCREAD);
 	start += 2;
 	/* wait for the beginning of a new tick */
-	while (inl(PC1_COUNTER_READ) < start);
+	while (inl(SYS_RTCREAD) < start);
 
 	/* Start r4k counter. */
 	write_32bit_cp0_register(CP0_COUNT, 0);
 	end = start + (32768 / trim_divide)/2; /* wait 0.5 seconds */
 
-	while (end > inl(PC1_COUNTER_READ));
+	while (end > inl(SYS_RTCREAD));
 
 	count = read_32bit_cp0_register(CP0_COUNT);
 	cpu_speed = count * 2;
-	uart_baud_base = (((cpu_speed) / 4) / 16);
+	mips_counter_frequency = count;
+	set_au1000_uart_baud_base(((cpu_speed) / 4) / 16);
+	restore_flags(flags);
 	return (cpu_speed / HZ);
 }
 
-static unsigned long __init get_mips_time(void)
-{
-	return inl(PC0_COUNTER_READ);
-}
 
 void __init time_init(void)
 {
-        unsigned int est_freq, flags;
+        unsigned int est_freq;
 
 	printk("calculating r4koff... ");
 	r4k_offset = cal_r4koff();
@@ -144,25 +221,51 @@
 	est_freq -= est_freq%10000;
 	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
 	       (est_freq%1000000)*100/1000000);
+	set_au1000_speed(est_freq);
+	set_au1000_lcd_clock(); // program the LCD clock
 	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
 
 	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
-	set_cp0_status(ALLINTS);
 
-	/* Read time from the RTC chipset. */
-	write_lock_irqsave (&xtime_lock, flags);
-	xtime.tv_sec = get_mips_time();
+	/* no RTC on the pb1000 */
+	xtime.tv_sec = 0;
 	xtime.tv_usec = 0;
-	write_unlock_irqrestore(&xtime_lock, flags);
+
+#ifdef CONFIG_PM
+	/*
+	 * setup counter 0, since it keeps ticking after a
+	 * 'wait' instruction has been executed. The CP0 timer and
+	 * counter 1 do NOT continue running after 'wait'
+	 *
+	 * It's too early to call request_irq() here, so we handle
+	 * counter 0 interrupt as a special irq and it doesn't show
+	 * up under /proc/interrupts.
+	 */
+	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+	writel(0, SYS_TOYWRITE);
+	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+
+	writel(readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
+	writel(~0, SYS_WAKESRC);
+	au_sync();
+	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+
+	/* setup match20 to interrupt once every 10ms */
+	last_pc0 = last_match20 = readl(SYS_TOYREAD);
+	writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+	au_sync();
+	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+	startup_match20_interrupt();
+#endif
+
+	//set_cp0_status(ALLINTS);
+	au_sync();
 }
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
-
-/* Cycle counter value at the previous timer interrupt.. */
+#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff)
 
-static unsigned int timerhi = 0, timerlo = 0;
 
 static unsigned long
 div64_32(unsigned long v1, unsigned long v2, unsigned long v3)
@@ -173,11 +276,28 @@
 }
 
 
-/*
- * FIXME: Does playing with the RP bit in c0_status interfere with this code?
- */
 static unsigned long do_fast_gettimeoffset(void)
 {
+#ifdef CONFIG_PM
+	unsigned long pc0;
+	unsigned long offset;
+
+	pc0 = readl(SYS_TOYREAD);
+	if (pc0 < last_pc0) {
+		offset = 0xffffffff - last_pc0 + pc0;
+		printk("offset over: %x\n", (unsigned)offset);
+	}
+	else {
+		offset = (unsigned long)(((pc0 - last_pc0) * 305) / 10);
+	}
+	if ((pc0-last_pc0) > 2*MATCH20_INC) {
+		printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", 
+				(unsigned)offset, (unsigned)last_pc0, 
+				(unsigned)last_match20, (unsigned)pc0);
+	}
+	au_sync();
+	return offset;
+#else
 	u32 count;
 	unsigned long res, tmp;
 	unsigned long r0;
@@ -225,6 +345,7 @@
 		res = USECS_PER_JIFFY-1;
 
 	return res;
+#endif
 }
 
 void do_gettimeofday(struct timeval *tv)
@@ -274,13 +395,3 @@
 
 	write_unlock_irq (&xtime_lock);
 }
-
-/*
- * The UART baud base is not known at compile time ... if
- * we want to be able to use the same code on different
- * speed CPUs.
- */
-unsigned long get_au1000_uart_baud()
-{
-	return uart_baud_base;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/common/usbdev.c linux/arch/mips/au1000/common/usbdev.c
--- linux.orig/arch/mips/au1000/common/usbdev.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/common/usbdev.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,1844 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 USB Device-Side Serial TTY Driver
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *		stevel@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/fcntl.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/smp_lock.h>
+#define DEBUG
+#include <linux/usb.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/au1000.h>
+#include <asm/au1000_dma.h>
+
+/* Module information */
+MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com, www.mvista.com");
+MODULE_DESCRIPTION("Au1000 USB Device-Side Serial TTY Driver");
+
+#undef USBDEV_PIO
+
+#define SERIAL_TTY_MAJOR 189
+
+#define MAX(a,b)	(((a)>(b))?(a):(b))
+
+#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL)
+
+#define MAX_NUM_PORTS 2
+
+#define NUM_PORTS 1
+#define NUM_EP 2*NUM_PORTS
+
+#define EP0_MAX_PACKET_SIZE 64
+#define EP2_MAX_PACKET_SIZE 64
+#define EP3_MAX_PACKET_SIZE 64
+#define EP4_MAX_PACKET_SIZE 64
+#define EP5_MAX_PACKET_SIZE 64
+
+#ifdef USBDEV_PIO
+#define EP_FIFO_DEPTH 8
+#endif
+
+typedef enum {
+	ATTACHED = 0,
+	POWERED,
+	DEFAULT,
+	ADDRESS,
+	CONFIGURED
+} dev_state_t;
+
+/* local function prototypes */
+static int serial_open(struct tty_struct *tty, struct file *filp);
+static void serial_close(struct tty_struct *tty, struct file *filp);
+static int serial_write(struct tty_struct *tty, int from_user,
+			const unsigned char *buf, int count);
+static int serial_write_room(struct tty_struct *tty);
+static int serial_chars_in_buffer(struct tty_struct *tty);
+static void serial_throttle(struct tty_struct *tty);
+static void serial_unthrottle(struct tty_struct *tty);
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+			unsigned int cmd, unsigned long arg);
+static void serial_set_termios (struct tty_struct *tty, struct termios * old);
+
+typedef struct {
+	int read_fifo;
+	int write_fifo;
+	int ctrl_stat;
+	int read_fifo_status;
+	int write_fifo_status;
+} endpoint_reg_t;
+
+typedef struct pkt {
+	int size;
+	u8 *bufptr;
+	struct pkt *next;
+	u8 buf[0];
+} pkt_t;
+
+typedef struct {
+	pkt_t *head;
+	pkt_t *tail;
+	int count;
+} pkt_list_t;
+
+typedef struct {
+	struct usb_endpoint_descriptor *desc;
+	endpoint_reg_t *reg;
+	// Only one of these are used, unless this is a control ep
+	pkt_list_t inlist;
+	pkt_list_t outlist;
+	unsigned int indma, outdma;	// DMA channel numbers for IN, OUT
+	int inirq, outirq;	// DMA buffer done irq numbers
+	int max_pkt_size;
+	spinlock_t lock;
+} endpoint_t;
+
+struct usb_serial_port {
+	struct usb_serial *serial;	/* ptr back to the owner of this port */
+	struct tty_struct *tty;	/* the coresponding tty for this port */
+	unsigned char number;
+	char active;		/* someone has this device open */
+	spinlock_t port_lock;
+
+	endpoint_t ep_bulkin;
+	endpoint_t ep_bulkout;
+
+	wait_queue_head_t write_wait;
+
+	/* task queue for line discipline waking up on send packet complete */
+	struct tq_struct send_complete_tq;
+	/* task queue for line discipline wakeup on receive packet complete */
+	struct tq_struct receive_complete_tq;
+
+	int open_count;		/* number of times this port has been opened */
+};
+
+struct usb_serial {
+	struct tty_driver *tty_driver;	/* the tty_driver for this device */
+	unsigned char minor;	/* the minor number for this device */
+
+	endpoint_t ep_ctrl;
+
+	struct usb_device_descriptor *dev_desc;
+	struct usb_interface_descriptor *if_desc;
+	struct usb_config_descriptor *conf_desc;
+	struct usb_string_descriptor *str_desc[6];
+
+	struct usb_serial_port port[NUM_PORTS];
+
+	dev_state_t state;	// device state
+	int suspended;		// suspended flag
+	int address;		// device address
+	int interface;
+	u8 alternate_setting;
+	u8 configuration;	// configuration value
+	int remote_wakeup_en;
+};
+
+
+static struct usb_device_descriptor dev_desc = {
+	bLength:USB_DT_DEVICE_SIZE,
+	bDescriptorType:USB_DT_DEVICE,
+	bcdUSB:0x0110,		//usb rev 1.0
+	bDeviceClass:USB_CLASS_PER_INTERFACE,	//class    (none)
+	bDeviceSubClass:0x00,	//subclass (none)
+	bDeviceProtocol:0x00,	//protocol (none)
+	bMaxPacketSize0:EP0_MAX_PACKET_SIZE,	//max packet size for ep0
+	idVendor:0x6d04,	//vendor  id
+	idProduct:0x0bc0,	//product id
+	bcdDevice:0x0001,	//BCD rev 0.1
+	iManufacturer:0x01,	//manufactuer string index
+	iProduct:0x02,		//product string index
+	iSerialNumber:0x03,	//serial# string index
+	bNumConfigurations:0x01	//num configurations
+};
+
+static struct usb_endpoint_descriptor ep_desc[] = {
+	{
+	 // EP2, Bulk IN for Port 0
+	      bLength:USB_DT_ENDPOINT_SIZE,
+	      bDescriptorType:USB_DT_ENDPOINT,
+	      bEndpointAddress:USB_DIR_IN | 0x02,
+	      bmAttributes:USB_ENDPOINT_XFER_BULK,
+	      wMaxPacketSize:EP2_MAX_PACKET_SIZE,
+	      bInterval:0x00	// ignored for bulk
+	 },
+	{
+	 // EP4, Bulk OUT for Port 0
+	      bLength:USB_DT_ENDPOINT_SIZE,
+	      bDescriptorType:USB_DT_ENDPOINT,
+	      bEndpointAddress:USB_DIR_OUT | 0x04,
+	      bmAttributes:USB_ENDPOINT_XFER_BULK,
+	      wMaxPacketSize:EP4_MAX_PACKET_SIZE,
+	      bInterval:0x00	// ignored for bulk
+	 },
+	{
+	 // EP3, Bulk IN for Port 1
+	      bLength:USB_DT_ENDPOINT_SIZE,
+	      bDescriptorType:USB_DT_ENDPOINT,
+	      bEndpointAddress:USB_DIR_IN | 0x03,
+	      bmAttributes:USB_ENDPOINT_XFER_BULK,
+	      wMaxPacketSize:EP3_MAX_PACKET_SIZE,
+	      bInterval:0x00	// ignored for bulk
+	 },
+	{
+	 // EP5, Bulk OUT for Port 1
+	      bLength:USB_DT_ENDPOINT_SIZE,
+	      bDescriptorType:USB_DT_ENDPOINT,
+	      bEndpointAddress:USB_DIR_OUT | 0x05,
+	      bmAttributes:USB_ENDPOINT_XFER_BULK,
+	      wMaxPacketSize:EP5_MAX_PACKET_SIZE,
+	      bInterval:0x00	// ignored for bulk
+	 },
+};
+
+static struct usb_interface_descriptor if_desc = {
+	bLength:USB_DT_INTERFACE_SIZE,
+	bDescriptorType:USB_DT_INTERFACE,
+	bInterfaceNumber:0x00,
+	bAlternateSetting:0x00,
+	bNumEndpoints:NUM_EP,
+	bInterfaceClass:0xff,
+	bInterfaceSubClass:0xab,
+	bInterfaceProtocol:0x00,
+	iInterface:0x05
+};
+
+#define CONFIG_DESC_LEN \
+ USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE
+
+static struct usb_config_descriptor config_desc = {
+	bLength:USB_DT_CONFIG_SIZE,
+	bDescriptorType:USB_DT_CONFIG,
+	wTotalLength:CONFIG_DESC_LEN,
+	bNumInterfaces:0x01,
+	bConfigurationValue:0x01,
+	iConfiguration:0x04,	// configuration string
+	bmAttributes:0xc0,	// self-powered
+	MaxPower:20		// 40 mA
+};
+
+// These strings will be converted to Unicode before sending
+static char *strings[5] = {
+	"Alchemy Semiconductor",
+	"Alchemy Au1000",
+	"1.0",
+	"Au1000 UART Config",
+	"Au1000 UART Interface"
+};
+
+// String[0] is a list of Language IDs supported by this device
+static struct usb_string_descriptor string_desc0 = {
+	bLength:4,
+	bDescriptorType:USB_DT_STRING,
+	wData:{0x0409}		// English, US
+};
+
+
+static endpoint_reg_t ep_reg[] = {
+	// FIFO's 0 and 1 are EP0 default control
+	{USBD_EP0RD, USBD_EP0WR, USBD_EP0CS, USBD_EP0RDSTAT, USBD_EP0WRSTAT},
+	// FIFO 2 is EP2, Port 0, bulk IN
+	{ -1, USBD_EP2WR, USBD_EP2CS, -1, USBD_EP2WRSTAT },
+	// FIFO 4 is EP4, Port 0, bulk OUT
+	    {USBD_EP4RD, -1, USBD_EP4CS, USBD_EP3WR, -1},
+	// FIFO 3 is EP3, Port 1, bulk IN
+	{ -1, USBD_EP3WRSTAT, USBD_EP3CS, -1, USBD_EP3WRSTAT },
+	// FIFO 5 is EP5, Port 1, bulk OUT
+	    {USBD_EP5RD, -1, USBD_EP5CS, USBD_EP5RDSTAT, -1}
+};
+
+static struct {
+	unsigned int id;
+	const char *str;
+} ep_dma_id[] = {
+	{ DMA_ID_USBDEV_EP0_TX, "USBDev EP0 IN" },
+	{ DMA_ID_USBDEV_EP0_RX, "USBDev EP0 OUT" },
+	{ DMA_ID_USBDEV_EP2_TX, "USBDev EP2 IN" },
+	{ DMA_ID_USBDEV_EP4_RX, "USBDev EP4 OUT" },
+	{ DMA_ID_USBDEV_EP3_TX, "USBDev EP3 IN" },
+	{ DMA_ID_USBDEV_EP5_RX, "USBDev EP5 OUT" }
+};
+
+static int serial_refcount;
+static struct tty_driver serial_tty_driver;
+static struct tty_struct *serial_tty[1];
+static struct termios *serial_termios[1];
+static struct termios *serial_termios_locked[1];
+static struct usb_serial usbserial;
+
+#define DIR_OUT 0
+#define DIR_IN  (1<<3)
+
+static const u32 au1000_config_table[25] __devinitdata = {
+	0x00,
+	    ((EP0_MAX_PACKET_SIZE & 0x380) >> 7) |
+	    (USB_ENDPOINT_XFER_CONTROL << 4),
+	(EP0_MAX_PACKET_SIZE & 0x7f) << 1,
+	0x00,
+	0x01,
+
+	0x10,
+	    ((EP2_MAX_PACKET_SIZE & 0x380) >> 7) | DIR_IN |
+	    (USB_ENDPOINT_XFER_BULK << 4),
+	(EP2_MAX_PACKET_SIZE & 0x7f) << 1,
+	0x00,
+	0x02,
+
+	0x20,
+	    ((EP3_MAX_PACKET_SIZE & 0x380) >> 7) | DIR_IN |
+	    (USB_ENDPOINT_XFER_BULK << 4),
+	(EP3_MAX_PACKET_SIZE & 0x7f) << 1,
+	0x00,
+	0x03,
+
+	0x30,
+	    ((EP4_MAX_PACKET_SIZE & 0x380) >> 7) | DIR_OUT |
+	    (USB_ENDPOINT_XFER_BULK << 4),
+	(EP4_MAX_PACKET_SIZE & 0x7f) << 1,
+	0x00,
+	0x04,
+
+	0x40,
+	    ((EP5_MAX_PACKET_SIZE & 0x380) >> 7) | DIR_OUT |
+	    (USB_ENDPOINT_XFER_BULK << 4),
+	(EP5_MAX_PACKET_SIZE & 0x7f) << 1,
+	0x00,
+	0x05
+};
+
+static inline endpoint_t *
+fifonum_to_ep(struct usb_serial* serial, int fifo_num)
+{
+	switch (fifo_num) {
+	case 0:
+	case 1:
+		return &serial->ep_ctrl;
+	case 2:
+		return &serial->port[0].ep_bulkin;
+	case 3:
+		return &serial->port[1].ep_bulkin;
+	case 4:
+		return &serial->port[0].ep_bulkout;
+	case 5:
+		return &serial->port[1].ep_bulkout;
+	}
+
+	return NULL;
+}
+
+static inline struct usb_serial_port *
+fifonum_to_port(struct usb_serial* serial, int fifo_num)
+{
+	switch (fifo_num) {
+	case 2:
+	case 4:
+		return &serial->port[0];
+	case 3:
+	case 5:
+		return &serial->port[1];
+	}
+
+	return NULL;
+}
+
+static inline endpoint_t *
+epnum_to_ep(struct usb_serial* serial, int ep_num)
+{
+	switch (ep_num) {
+	case 0:
+		return &serial->ep_ctrl;
+	case 2:
+		return &serial->port[0].ep_bulkin;
+	case 3:
+		return &serial->port[1].ep_bulkin;
+	case 4:
+		return &serial->port[0].ep_bulkout;
+	case 5:
+		return &serial->port[1].ep_bulkout;
+	}
+
+	return NULL;
+}
+
+
+static inline int
+port_paranoia_check(struct usb_serial_port *port, const char *function)
+{
+	if (!port) {
+		dbg("%s - port == NULL", function);
+		return -1;
+	}
+	if (!port->serial) {
+		dbg("%s - port->serial == NULL", function);
+		return -1;
+	}
+	if (!port->tty) {
+		dbg("%s - port->tty == NULL", function);
+		return -1;
+	}
+
+	return 0;
+}
+
+static inline struct usb_serial*
+get_usb_serial (struct usb_serial_port *port, const char *function)
+{
+	/* if no port was specified, or it fails a paranoia check */
+	if (!port || port_paranoia_check(port, function)) {
+		/* then say that we dont have a valid usb_serial thing,
+		 * which will end up genrating -ENODEV return values */
+		return NULL;
+	}
+
+	return port->serial;
+}
+
+
+static inline pkt_t *
+alloc_packet(int data_size)
+{
+	pkt_t* pkt = (pkt_t *)kmalloc(sizeof(pkt_t) + data_size, ALLOC_FLAGS);
+	if (!pkt)
+		return NULL;
+	pkt->size = data_size;
+	pkt->bufptr = pkt->buf;
+#ifndef USBDEV_PIO
+	pkt->bufptr = KSEG1ADDR(pkt->bufptr);
+#endif
+	pkt->next = NULL;
+	return pkt;
+}
+
+
+/*
+ * Link a packet to the tail of the enpoint's packet list.
+ */
+static void
+link_packet(endpoint_t * ep, pkt_list_t * list, pkt_t * pkt)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ep->lock, flags);
+
+	if (!list->tail) {
+		list->head = list->tail = pkt;
+		list->count = 1;
+	} else {
+		list->tail->next = pkt;
+		list->tail = pkt;
+		list->count++;
+	}
+
+	spin_unlock_irqrestore(&ep->lock, flags);
+}
+
+/*
+ * Unlink and return a packet from the head of the enpoint's packet list.
+ */
+static pkt_t *
+unlink_packet(endpoint_t * ep, pkt_list_t * list)
+{
+	unsigned long flags;
+	pkt_t *pkt;
+
+	spin_lock_irqsave(&ep->lock, flags);
+
+	pkt = list->head;
+	if (!pkt || !list->count) {
+		spin_unlock_irqrestore(&ep->lock, flags);
+		return NULL;
+	}
+
+	list->head = pkt->next;
+	if (!list->head) {
+		list->head = list->tail = NULL;
+		list->count = 0;
+	} else
+		list->count--;
+
+	spin_unlock_irqrestore(&ep->lock, flags);
+
+	return pkt;
+}
+
+/*
+ * Create and attach a new packet to the tail of the enpoint's
+ * packet list.
+ */
+static pkt_t *
+add_packet(endpoint_t * ep, pkt_list_t * list, int size)
+{
+	pkt_t *pkt = alloc_packet(size);
+	if (!pkt)
+		return NULL;
+
+	link_packet(ep, list, pkt);
+	return pkt;
+}
+
+
+/*
+ * Unlink and free a packet from the head of the enpoint's
+ * packet list.
+ */
+static inline void
+free_packet(endpoint_t * ep, pkt_list_t * list)
+{
+	kfree(unlink_packet(ep, list));
+}
+
+static inline void
+flush_pkt_list(endpoint_t * ep, pkt_list_t * list)
+{
+	while (list->count)
+		free_packet(ep, list);
+}
+
+
+static inline void
+flush_write_fifo(endpoint_t * ep)
+{
+	if (ep->reg->write_fifo_status >= 0) {
+		outl_sync(USBDEV_FSTAT_FLUSH, ep->reg->write_fifo_status);
+		udelay(100);
+		outl_sync(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+			  ep->reg->write_fifo_status);
+	}
+}
+
+
+static inline void
+flush_read_fifo(endpoint_t * ep)
+{
+	if (ep->reg->read_fifo_status >= 0) {
+		outl_sync(USBDEV_FSTAT_FLUSH, ep->reg->read_fifo_status);
+		udelay(100);
+		outl_sync(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+			  ep->reg->read_fifo_status);
+	}
+}
+
+
+static void
+endpoint_flush(endpoint_t * ep)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ep->lock, flags);
+
+	// First, flush all packets
+	flush_pkt_list(ep, &ep->inlist);
+	flush_pkt_list(ep, &ep->outlist);
+
+	// Now flush the endpoint's h/w FIFO(s)
+	flush_write_fifo(ep);
+	flush_read_fifo(ep);
+
+	spin_unlock_irqrestore(&ep->lock, flags);
+}
+
+
+static void
+endpoint_stall(endpoint_t * ep)
+{
+	unsigned long flags;
+	u32 cs;
+
+	dbg(__FUNCTION__);
+
+	spin_lock_irqsave(&ep->lock, flags);
+
+	cs = inl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
+	outl_sync(cs, ep->reg->ctrl_stat);
+
+	spin_unlock_irqrestore(&ep->lock, flags);
+}
+
+static void
+endpoint_unstall(endpoint_t * ep)
+{
+	unsigned long flags;
+	u32 cs;
+
+	dbg(__FUNCTION__);
+
+	spin_lock_irqsave(&ep->lock, flags);
+
+	cs = inl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
+	outl_sync(cs, ep->reg->ctrl_stat);
+
+	spin_unlock_irqrestore(&ep->lock, flags);
+}
+
+static void
+endpoint_reset_datatoggle(endpoint_t * ep)
+{
+	// FIXME: is this possible?
+}
+
+
+#ifdef USBDEV_PIO
+static int
+endpoint_fifo_read(endpoint_t * ep)
+{
+	unsigned long flags;
+	int read_count = 0;
+	u8 *bufptr;
+	pkt_t *pkt = ep->outlist.tail;
+
+	if (!pkt)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->lock, flags);
+
+	bufptr = pkt->bufptr;
+	while (inl(ep->reg->read_fifo_status) & USBDEV_FSTAT_FCNT_MASK) {
+		*bufptr++ = inl(ep->reg->read_fifo) & 0xff;
+		read_count++;
+		pkt->size++;
+	}
+	pkt->bufptr = bufptr;
+
+	spin_unlock_irqrestore(&ep->lock, flags);
+	return read_count;
+}
+
+
+static int
+endpoint_fifo_write(endpoint_t * ep)
+{
+	unsigned long flags;
+	int write_count = 0;
+	u8 *bufptr;
+	pkt_t *pkt = ep->inlist.head;
+
+	if (!pkt)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->lock, flags);
+
+	bufptr = pkt->bufptr;
+	while ((inl(ep->reg->write_fifo_status) & USBDEV_FSTAT_FCNT_MASK) <
+	       EP_FIFO_DEPTH) {
+		if (bufptr < pkt->buf + pkt->size) {
+			outl_sync(*bufptr++, ep->reg->write_fifo);
+			write_count++;
+		} else {
+			break;
+		}
+	}
+	pkt->bufptr = bufptr;
+
+	spin_unlock_irqrestore(&ep->lock, flags);
+	return write_count;
+}
+#endif				// USBDEV_PIO
+
+/*
+ * This routine is called to restart transmission of a packet.
+ * The endpoint's TSIZE must be set to the new packet's size,
+ * and DMA to the write FIFO needs to be restarted.
+ */
+static void
+kickstart_send_packet(endpoint_t * ep)
+{
+	u32 cs;
+	pkt_t *pkt = ep->inlist.head;
+
+	dbg(__FUNCTION__ ": pkt=%p", pkt);
+
+	if (!pkt)
+		return;
+
+	/*
+	 * The write fifo should already be drained if things are
+	 * working right, but flush it anyway just in case.
+	 */
+	flush_write_fifo(ep);
+	cs = inl(ep->reg->ctrl_stat) & USBDEV_CS_STALL;
+	cs |= (pkt->size << USBDEV_CS_TSIZE_BIT);
+	outl_sync(cs, ep->reg->ctrl_stat);
+#ifdef USBDEV_PIO
+	endpoint_fifo_write(ep);
+#else
+	disable_dma(ep->indma);
+	if (get_dma_active_buffer(ep->indma)) {
+		set_dma_count1(ep->indma, pkt->size);
+		set_dma_addr1(ep->indma, virt_to_phys(pkt->bufptr));
+		enable_dma_buffer1(ep->indma);	// reenable
+	} else {
+		set_dma_count0(ep->indma, pkt->size);
+		set_dma_addr0(ep->indma, virt_to_phys(pkt->bufptr));
+		enable_dma_buffer0(ep->indma);	// reenable
+	}
+	enable_dma(ep->indma);
+#endif
+}
+
+
+/*
+ * This routine is called when a packet in the inlist has been
+ * completed. Frees the completed packet and starts sending the
+ * next.
+ */
+static void
+send_packet_complete(endpoint_t * ep)
+{
+	if (ep->inlist.head)
+		dbg(__FUNCTION__ ": pkt=%p, ab=%d",
+		    ep->inlist.head, get_dma_active_buffer(ep->indma));
+
+	outl_sync(inl(ep->reg->ctrl_stat) & USBDEV_CS_STALL,
+		  ep->reg->ctrl_stat);
+	//disable_dma(ep->indma);
+	free_packet(ep, &ep->inlist);
+	// begin transmitting next packet in the inlist
+	if (ep->inlist.count)
+		kickstart_send_packet(ep);
+}
+
+
+/*
+ * Unlink and return a packet from the head of the given ep's packet
+ * outlist. It is the responsibility of the caller to free the packet.
+ * The receive complete interrupt adds packets to the tail of this list. 
+ */
+static pkt_t *
+receive_packet(endpoint_t * ep)
+{
+	pkt_t *pkt = unlink_packet(ep, &ep->outlist);
+	//dma_cache_inv((unsigned long)pkt->buf, pkt->size);
+	return pkt;
+}
+
+/*
+ * This routine is called to restart reception of a packet.
+ */
+static void
+kickstart_receive_packet(endpoint_t * ep)
+{
+	pkt_t *pkt;
+
+	// get and link a new packet for next reception
+	if (!(pkt = add_packet(ep, &ep->outlist, ep->max_pkt_size))) {
+		err(__FUNCTION__ ": could not alloc new packet");
+		return;
+	}
+
+	/*
+	 * The read fifo should already be drained if things are
+	 * working right, but flush it anyway just in case.
+	 */
+	flush_read_fifo(ep);
+#ifndef USBDEV_PIO
+	if (get_dma_active_buffer(ep->outdma)) {
+		set_dma_count1(ep->outdma, ep->max_pkt_size);
+		set_dma_addr1(ep->outdma, virt_to_phys(pkt->bufptr));
+		enable_dma_buffer1(ep->outdma);	// reenable
+	} else {
+		set_dma_count0(ep->outdma, ep->max_pkt_size);
+		set_dma_addr0(ep->outdma, virt_to_phys(pkt->bufptr));
+		enable_dma_buffer0(ep->outdma);	// reenable
+	}
+	enable_dma(ep->outdma);
+#endif
+}
+
+
+/*
+ * This routine is called when a packet in the outlist has been
+ * completed (received) and we need to prepare for a new packet
+ * to be received. Halts DMA and computes the packet size from the
+ * remaining DMA counter. Then prepares a new packet for reception
+ * and restarts DMA. FIXME: what if another packet comes in
+ * on top of the completed packet? Counter would be wrong.
+ */
+static void
+receive_packet_complete(endpoint_t * ep)
+{
+	pkt_t *pkt = ep->outlist.tail;
+
+	if (!pkt)
+		return;
+
+	disable_dma(ep->outdma);
+	pkt->size = ep->max_pkt_size - get_dma_residue(ep->outdma);
+#ifdef USBDEV_PIO
+	pkt->bufptr = pkt->buf;	// reset bufptr
+#endif
+	dbg(__FUNCTION__ ": size=%d", pkt->size);
+
+	kickstart_receive_packet(ep);
+}
+
+
+
+/*
+ * Add a new packet to the tail of the given ep's packet
+ * inlist. The transmit complete interrupt frees packets from
+ * the head of this list.
+ */
+static int
+send_packet(endpoint_t * ep, u8 * data, int data_len, int from_user)
+{
+	unsigned long flags;
+	pkt_list_t *list = &ep->inlist;
+	pkt_t *pkt;
+
+	if (!data || !data_len)
+		return 0;
+
+	if (!(pkt = alloc_packet(data_len))) {
+		err(__FUNCTION__ ": could not alloc new packet");
+		return -ENOMEM;
+	}
+
+	if (from_user)
+		copy_from_user(pkt->bufptr, data, data_len);
+	else
+		memcpy(pkt->bufptr, data, data_len);
+	au_sync();
+
+	//dma_cache_wback_inv((unsigned long)pkt->buf, data_len);
+
+	link_packet(ep, list, pkt);
+
+	spin_lock_irqsave(&ep->lock, flags);
+
+	dbg(__FUNCTION__ ": size=%d, list count=%d", pkt->size, list->count);
+
+	if (list->count == 1) {
+		/*
+		 * if the packet count is one, it means the list was empty,
+		 * and no more data will go out this ep until we kick-start
+		 * it again.
+		 */
+		kickstart_send_packet(ep);
+	}
+
+	spin_unlock_irqrestore(&ep->lock, flags);
+	return data_len;
+}
+
+
+// SETUP packet request parser
+static void
+process_setup (struct usb_serial* serial, devrequest* setup)
+{
+	int desc_len, strnum;
+
+	dbg(__FUNCTION__ ": req %d", setup->request);
+
+	switch (setup->request) {
+	case USB_REQ_SET_ADDRESS:
+		serial->address = le16_to_cpu(setup->value);
+		dbg(__FUNCTION__ ": our address=%d", serial->address);
+		if (serial->address > 127 || serial->state == CONFIGURED) {
+			// usb spec doesn't tell us what to do, so just go to
+			// default state
+			serial->state = DEFAULT;
+			serial->address = 0;
+		} else if (serial->address)
+			serial->state = ADDRESS;
+		else
+			serial->state = DEFAULT;
+		break;
+	case USB_REQ_GET_DESCRIPTOR:
+		desc_len = le16_to_cpu(setup->length);
+		switch (le16_to_cpu(setup->value) >> 8) {
+		case USB_DT_DEVICE:
+			// send device descriptor!
+			desc_len = desc_len > serial->dev_desc->bLength ?
+			    serial->dev_desc->bLength : desc_len;
+			dbg("sending device desc, size=%d", desc_len);
+			send_packet(&serial->ep_ctrl, (u8*)serial->dev_desc,
+				    desc_len, 0);
+			break;
+		case USB_DT_CONFIG:
+			// If the config descr index in low-byte of
+			// setup->value	is valid, send config descr,
+			// otherwise stall ep0.
+			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
+				// send config descriptor!
+				if (desc_len <= USB_DT_CONFIG_SIZE) {
+					dbg("sending partial config desc, size=%d",
+					     desc_len);
+					send_packet(&serial->ep_ctrl,
+						    (u8*)serial->conf_desc,
+						    desc_len, 0);
+				} else {
+					u8 full_conf_desc[CONFIG_DESC_LEN];
+					int i, index = 0;
+					memcpy(&full_conf_desc[index],
+					       serial->conf_desc,
+					       USB_DT_CONFIG_SIZE);
+					index += USB_DT_CONFIG_SIZE;
+					memcpy(&full_conf_desc[index],
+					       serial->if_desc,
+					       USB_DT_INTERFACE_SIZE);
+					index += USB_DT_INTERFACE_SIZE;
+					for (i = 0; i < NUM_PORTS; i++) {
+						memcpy(&full_conf_desc[index],
+						       serial->port[i].ep_bulkin.desc,
+						       USB_DT_ENDPOINT_SIZE);
+						index += USB_DT_ENDPOINT_SIZE;
+						memcpy(&full_conf_desc[index],
+						       serial->port[i].ep_bulkout.desc,
+						       USB_DT_ENDPOINT_SIZE);
+						index += USB_DT_ENDPOINT_SIZE;
+					}
+					dbg("sending whole config desc, size=%d, our size=%d",
+					     desc_len, CONFIG_DESC_LEN);
+					desc_len = desc_len > CONFIG_DESC_LEN ?
+					    CONFIG_DESC_LEN : desc_len;
+					send_packet(&serial->ep_ctrl,
+						    full_conf_desc, desc_len, 0);
+				}
+			} else
+				endpoint_stall(&serial->ep_ctrl);
+			break;
+		case USB_DT_STRING:
+			// If the string descr index in low-byte of setup->value
+			// is valid, send string descr, otherwise stall ep0.
+			strnum = le16_to_cpu(setup->value) & 0xff;
+			if (strnum >= 0 && strnum < 6) {
+				struct usb_string_descriptor *desc =
+				    serial->str_desc[strnum];
+				desc_len = desc_len > desc->bLength ?
+					desc->bLength : desc_len;
+				dbg("sending string desc %d", strnum);
+				send_packet(&serial->ep_ctrl, (u8 *) desc,
+					    desc_len, 0);
+			} else
+				endpoint_stall(&serial->ep_ctrl);
+			break;
+		default:	// Invalid request
+			dbg("invalid get desc=%d, stalled",
+			    le16_to_cpu(setup->value) >> 8);
+			endpoint_stall(&serial->ep_ctrl);	// Stall endpoint 0
+			break;
+		}
+		break;
+	case USB_REQ_SET_DESCRIPTOR:
+		// FIXME: anything to set here?
+		break;
+	case USB_REQ_GET_INTERFACE:
+		// interface must be zero.
+		if ((le16_to_cpu(setup->index) & 0xff) ||
+		    serial->state == ADDRESS) {
+			// FIXME: respond with "request error". how?
+		} else if (serial->state == CONFIGURED) {
+			// send serial->alternate_setting
+			dbg("sending alt setting");
+			send_packet(&serial->ep_ctrl,
+				    &serial->alternate_setting, 1, 0);
+		}
+		break;
+	case USB_REQ_SET_INTERFACE:
+		if (serial->state == ADDRESS) {
+			// FIXME: respond with "request error". how?
+		} else if (serial->state == CONFIGURED) {
+			serial->interface = le16_to_cpu(setup->index) & 0xff;
+			serial->alternate_setting =
+			    le16_to_cpu(setup->value) & 0xff;
+			// interface and alternate_setting must be zero
+			if (serial->interface || serial->alternate_setting) {
+				// FIXME: respond with "request error". how?
+			}
+		}
+		break;
+	case USB_REQ_SET_CONFIGURATION:
+		// set active config to low-byte of serial.value
+		serial->configuration = le16_to_cpu(setup->value) & 0xff;
+		dbg("set config, config=%d", serial->configuration);
+		if (!serial->configuration && serial->state > DEFAULT)
+			serial->state = ADDRESS;
+		else if (serial->configuration == 1)
+			serial->state = CONFIGURED;
+		else {
+			// FIXME: "respond with request error" - how?
+		}
+		break;
+	case USB_REQ_GET_CONFIGURATION:
+		// send serial->configuration
+		dbg("sending config");
+		send_packet(&serial->ep_ctrl, &serial->configuration, 1, 0);
+		break;
+	case USB_REQ_GET_STATUS:
+		// FIXME: looks like the h/w handles this one
+		switch (setup->requesttype) {
+		case 0x80:	// Device
+			// FIXME: send device status
+			break;
+		case 0x81:	// Interface
+			// FIXME: send interface status
+			break;
+		case 0x82:	// End Point
+			// FIXME: send endpoint status
+			break;
+		default:	// Invalid Command
+			endpoint_stall(&serial->ep_ctrl);	// Stall End Point 0
+			break;
+		}
+		break;
+	case USB_REQ_CLEAR_FEATURE:
+		switch (setup->requesttype) {
+		case 0x00:	// Device
+			if ((le16_to_cpu(setup->value) & 0xff) == 1)
+				serial->remote_wakeup_en = 0;
+			else
+				endpoint_stall(&serial->ep_ctrl);
+			break;
+		case 0x02:	// End Point
+			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
+				endpoint_t *ep =
+				    epnum_to_ep(serial,
+						    le16_to_cpu(setup->index) & 0xff);
+
+				endpoint_unstall(ep);
+				endpoint_reset_datatoggle(ep);
+			} else
+				endpoint_stall(&serial->ep_ctrl);
+			break;
+		}
+		break;
+	case USB_REQ_SET_FEATURE:
+		switch (setup->requesttype) {
+		case 0x00:	// Device
+			if ((le16_to_cpu(setup->value) & 0xff) == 1)
+				serial->remote_wakeup_en = 1;
+			else
+				endpoint_stall(&serial->ep_ctrl);
+			break;
+		case 0x02:	// End Point
+			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
+				endpoint_t *ep =
+				    epnum_to_ep(serial,
+						    le16_to_cpu(setup->index) & 0xff);
+
+				endpoint_stall(ep);
+			} else
+				endpoint_stall(&serial->ep_ctrl);
+			break;
+		}
+		break;
+	default:
+		endpoint_stall(&serial->ep_ctrl);	// Stall End Point 0
+		break;
+	}
+}
+
+
+/*
+ * A complete packet (SETUP, DATA0, or DATA1) has been received
+ * on the given endpoint's fifo.
+ */
+static void
+process_complete (struct usb_serial* serial, int fifo_num)
+{
+	endpoint_t *ep = fifonum_to_ep(serial, fifo_num);
+	struct usb_serial_port *port = NULL;
+	pkt_t *pkt = 0;
+	u32 cs;
+
+	cs = inl(ep->reg->ctrl_stat);
+
+	switch (fifo_num) {
+	case 0:
+		spin_lock(&ep->lock);
+		// complete packet and prepare a new packet
+		receive_packet_complete(ep);
+
+		// Get it immediately from endpoint.
+		if (!(pkt = receive_packet(ep))) {
+			spin_unlock(&ep->lock);
+			return;
+		}
+	
+		// SETUP packet received ?
+		//if (cs & USBDEV_CS_SU) { FIXME: uncomment!
+			if (pkt->size == sizeof(devrequest)) {
+				devrequest setup;
+			if ((cs & (USBDEV_CS_NAK | USBDEV_CS_ACK)) ==
+			    USBDEV_CS_ACK)
+					dbg("got SETUP");
+				else
+					dbg("got NAK SETUP, cs=%08x", cs);
+			memcpy(&setup, pkt->bufptr, sizeof(devrequest));
+				process_setup(serial, &setup);
+			//} else  FIXME: uncomment!
+			//dbg(__FUNCTION__ ": wrong size SETUP received");
+		} else {
+			// DATAx packet received on endpoint 0
+			// FIXME: will need a state machine for control
+			// OUT transactions
+			dbg("got DATAx on EP0, size=%d, cs=%08x",
+			    pkt->size, cs);
+		}
+
+		spin_unlock(&ep->lock);
+		// we're done processing the packet, free it
+		kfree(pkt);
+		break;
+
+	case 4:
+	case 5:
+		port = fifonum_to_port(serial, fifo_num);
+		dbg("got DATAx on port %d, cs=%08x", port->number, cs);
+		spin_lock(&ep->lock);
+		receive_packet_complete(ep);
+		spin_unlock(&ep->lock);
+		// mark a bh to push this data up to the tty
+		queue_task(&port->receive_complete_tq, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+		break;
+
+	default:
+		break;
+	}
+}
+
+
+
+// This ISR needs to ack both the complete and suspend events
+static void
+req_sus_intr (int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct usb_serial *serial = (struct usb_serial *) dev_id;
+	int i;
+	u32 status;
+
+	status = inl(USB_DEV_INT_STATUS);
+	outl_sync(status, USB_DEV_INT_STATUS);	// ack'em
+
+#ifdef USBDEV_PIO
+	for (i = 0; i < 6; i++) {
+		if (status & (1 << (USBDEV_INT_HF_BIT + i))) {
+			endpoint_t *ep = fifonum_to_ep(serial, i);
+
+			if (ep->desc->bEndpointAddress & USB_DIR_IN)
+				endpoint_fifo_write(ep);
+			else
+				endpoint_fifo_read(ep);
+		}
+	}
+#endif
+
+	for (i = 0; i < 6; i++) {
+		if (status & (1 << i))
+			process_complete(serial, i);
+	}
+}
+
+
+static void
+dma_done_ctrl(struct usb_serial* serial)
+{
+	endpoint_t *ep = &serial->ep_ctrl;
+	u32 cs0, buff_done;
+
+	spin_lock(&ep->lock);
+	cs0 = inl(ep->reg->ctrl_stat);
+
+	// first check packet transmit done
+	if ((buff_done = get_dma_buffer_done(ep->indma)) != 0) {
+		// transmitted a DATAx packet on control endpoint 0
+		// clear DMA done bit
+		if (buff_done == DMA_D0)
+			clear_dma_done0(ep->indma);
+		else
+			clear_dma_done1(ep->indma);
+
+		send_packet_complete(ep);
+	}
+
+	/*
+	 * Now check packet receive done. Shouldn't get these,
+	 * the receive packet complete intr should happen
+	 * before the DMA done intr occurs.
+	 */
+	if ((buff_done = get_dma_buffer_done(ep->outdma)) != 0) {
+		// clear DMA done bit
+		if (buff_done == DMA_D0)
+			clear_dma_done0(ep->outdma);
+		else
+			clear_dma_done1(ep->outdma);
+	}
+
+	spin_unlock(&ep->lock);
+}
+
+static void
+dma_done_port(struct usb_serial_port * port)
+{
+	endpoint_t *ep;
+	u32 buff_done;
+
+	// first check packet transmit done (bulk IN ep)
+	ep = &port->ep_bulkin;
+	spin_lock(&ep->lock);
+	if ((buff_done = get_dma_buffer_done(ep->indma)) != 0) {
+		// transmitted a DATAx packet on the port's bulk IN endpoint
+		// clear DMA done bit
+		if (buff_done == DMA_D0)
+			clear_dma_done0(ep->indma);
+		else
+			clear_dma_done1(ep->indma);
+
+		send_packet_complete(ep);
+		// mark a bh to wakeup any tty write system call on the port.
+		queue_task(&port->send_complete_tq, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+	}
+	spin_unlock(&ep->lock);
+
+	/*
+	 * Now check packet receive done (bulk OUT ep). Shouldn't
+	 * get these, the receive packet complete intr should happen
+	 * before the DMA done intr occurs.
+	 */
+	ep = &port->ep_bulkout;
+	spin_lock(&ep->lock);
+	if ((buff_done = get_dma_buffer_done(ep->outdma)) != 0) {
+		// received a DATAx packet on the port's bulk OUT endpoint
+		// clear DMA done bit
+		if (buff_done == DMA_D0)
+			clear_dma_done0(ep->outdma);
+		else
+			clear_dma_done1(ep->outdma);
+	}
+	spin_unlock(&ep->lock);
+}
+
+
+// This ISR needs to handle dma done events for ALL endpoints!
+static void
+dma_done_intr (int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct usb_serial *serial = (struct usb_serial *) dev_id;
+	int i;
+
+	dma_done_ctrl(serial);
+	for (i = 0; i < NUM_PORTS; i++)
+		dma_done_port(&serial->port[i]);
+}
+
+
+
+/*****************************************************************************
+ * Here begins the tty driver interface functions
+ *****************************************************************************/
+
+static int serial_open(struct tty_struct *tty, struct file *filp)
+{
+	int portNumber;
+	struct usb_serial_port *port;
+	struct usb_serial *serial = &usbserial;
+	unsigned long flags;
+
+	/* initialize the pointer incase something fails */
+	tty->driver_data = NULL;
+
+	MOD_INC_USE_COUNT;
+
+	/* set up our port structure making the tty driver remember
+	   our port object, and us it */
+	portNumber = MINOR(tty->device) - serial->minor;
+	port = &serial->port[portNumber];
+	tty->driver_data = port;
+	port->tty = tty;
+
+	if (port_paranoia_check(port, __FUNCTION__))
+		return -ENODEV;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	spin_lock_irqsave(&port->port_lock, flags);
+
+	++port->open_count;
+
+	if (!port->active) {
+		port->active = 1;
+
+		/*
+		 * force low_latency on so that our tty_push actually forces
+		 * the data through, otherwise it is scheduled, and with high
+		 * data rates (like with OHCI) data can get lost.
+		 */
+		port->tty->low_latency = 1;
+
+	}
+
+	spin_unlock_irqrestore(&port->port_lock, flags);
+
+	return 0;
+}
+
+
+static void serial_close(struct tty_struct *tty, struct file *filp)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+	unsigned long flags;
+
+	if (!serial)
+		return;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not opened");
+		return;
+	}
+
+	spin_lock_irqsave(&port->port_lock, flags);
+
+	--port->open_count;
+
+	if (port->open_count <= 0) {
+		port->active = 0;
+		port->open_count = 0;
+	}
+
+	spin_unlock_irqrestore(&port->port_lock, flags);
+	MOD_DEC_USE_COUNT;
+}
+
+
+static int serial_write(struct tty_struct *tty, int from_user,
+			const unsigned char *buf, int count)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+	endpoint_t *ep = &port->ep_bulkin;
+
+	if (!serial)
+		return -ENODEV;
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not opened");
+		return -EINVAL;
+	}
+
+	if (count == 0) {
+		dbg(__FUNCTION__ " - write request of 0 bytes");
+		return (0);
+	}
+
+	count = (count > ep->max_pkt_size) ? ep->max_pkt_size : count;
+	send_packet(ep, (u8 *) buf, count, from_user);
+
+	return (count);
+}
+
+
+static int serial_write_room(struct tty_struct *tty)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+	endpoint_t *ep = &port->ep_bulkin;
+
+	if (!serial)
+		return -ENODEV;
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not open");
+		return -EINVAL;
+	}
+
+	return ep->max_pkt_size;
+}
+
+
+static int serial_chars_in_buffer(struct tty_struct *tty)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+	endpoint_t *ep = &port->ep_bulkin;
+	pkt_list_t *list = &ep->inlist;
+	pkt_t *scan;
+	unsigned long flags;
+	int chars = 0;
+
+	if (!serial)
+		return -ENODEV;
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not open");
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&ep->lock, flags);
+	for (scan = list->head; scan; scan = scan->next)
+		chars += scan->size;
+	spin_unlock_irqrestore(&ep->lock, flags);
+
+	return (chars);
+}
+
+
+static void serial_throttle(struct tty_struct *tty)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+
+	if (!serial)
+		return;
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not open");
+		return;
+	}
+	// FIXME: anything to do?
+}
+
+
+static void serial_unthrottle(struct tty_struct *tty)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+
+	if (!serial)
+		return;
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not open");
+		return;
+	}
+	// FIXME: anything to do?
+}
+
+
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+
+	if (!serial)
+		return -ENODEV;
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not open");
+		return -ENODEV;
+	}
+	// FIXME: need any IOCTLs?
+
+	return -ENOIOCTLCMD;
+}
+
+
+static void serial_set_termios(struct tty_struct *tty, struct termios *old)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+
+	if (!serial)
+		return;
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not open");
+		return;
+	}
+	// FIXME: anything to do?
+}
+
+
+static void serial_break(struct tty_struct *tty, int break_state)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+
+	if (!serial)
+		return;
+
+	if (!port->active) {
+		dbg(__FUNCTION__ " - port not open");
+		return;
+	}
+	// FIXME: anything to do?
+}
+
+
+static void port_send_complete(void *private)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *) private;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+	struct tty_struct *tty;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	if (!serial) {
+		return;
+	}
+
+	tty = port->tty;
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup) {
+		dbg(__FUNCTION__ " - write wakeup call.");
+		(tty->ldisc.write_wakeup) (tty);
+	}
+
+	wake_up_interruptible(&tty->write_wait);
+}
+
+
+static void port_receive_complete(void *private)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *) private;
+	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+	struct tty_struct *tty = port->tty;
+	pkt_t *pkt;
+	int i;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	if (!serial) {
+		return;
+	}
+
+	if (!(pkt = receive_packet(&port->ep_bulkout)))
+		return;
+
+	for (i = 0; i < pkt->size; i++) {
+		/* if we insert more than TTY_FLIPBUF_SIZE characters,
+		   we drop them. */
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty_flip_buffer_push(tty);
+		}
+		/* this doesn't actually push the data through
+		   unless tty->low_latency is set */
+		tty_insert_flip_char(tty, pkt->bufptr[i], 0);
+	}
+	tty_flip_buffer_push(tty);
+
+	// we're done processing the packet, free it
+	kfree(pkt);
+}
+
+
+static struct tty_driver serial_tty_driver = {
+	magic:TTY_DRIVER_MAGIC,
+	driver_name:"usbdev-serial",
+	name:"usb/ttsdev/%d",
+	major:SERIAL_TTY_MAJOR,
+	minor_start:0,
+	num:1,
+	type:TTY_DRIVER_TYPE_SERIAL,
+	subtype:SERIAL_TYPE_NORMAL,
+	flags:TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+	refcount:&serial_refcount,
+	table:serial_tty,
+	termios:serial_termios,
+	termios_locked:serial_termios_locked,
+
+	open:serial_open,
+	close:serial_close,
+	write:serial_write,
+	write_room:serial_write_room,
+	ioctl:serial_ioctl,
+	set_termios:serial_set_termios,
+	throttle:serial_throttle,
+	unthrottle:serial_unthrottle,
+	break_ctl:serial_break,
+	chars_in_buffer:serial_chars_in_buffer,
+};
+
+
+void usbdev_serial_exit(void)
+{
+	endpoint_t *ep;
+	int i;
+
+	outl_sync(0, USB_DEV_INT_ENABLE);	// disable usb dev ints
+	outl_sync(0, USB_DEV_ENABLE);	// disable usb dev
+
+	// first free all control endpoint resources
+	ep = &usbserial.ep_ctrl;
+	free_irq(AU1000_USB_DEV_REQ_INT, &usbserial);
+	free_irq(AU1000_USB_DEV_SUS_INT, &usbserial);
+	free_irq(ep->inirq, &usbserial);
+	//free_irq(ep->outirq, &usbserial);
+	free_au1000_dma(ep->indma);
+	free_au1000_dma(ep->outdma);
+	endpoint_flush(ep);
+
+	// now free all port resources
+	for (i = 0; i < NUM_PORTS; i++) {
+		// free port's bulk IN endpoint resources
+		ep = &usbserial.port[i].ep_bulkin;
+		free_irq(ep->inirq, &usbserial);
+		free_au1000_dma(ep->indma);
+		endpoint_flush(ep);
+
+		// free port's bulk OUT endpoint resources
+		ep = &usbserial.port[i].ep_bulkout;
+		//free_irq(ep->outirq, &usbserial);
+		free_au1000_dma(ep->outdma);
+		endpoint_flush(ep);
+
+		tty_unregister_devfs(&serial_tty_driver, i);
+		info("usbdev serial converter now disconnected from ttyUSBdev%d",
+		     i);
+	}
+
+	kfree(usbserial.str_desc[0]);
+	tty_unregister_driver(&serial_tty_driver);
+}
+
+int usbdev_serial_init(void)
+{
+	struct usb_serial_port *port;
+	endpoint_t *ep;
+	void *str_desc_buf;
+	int str_desc_len;
+	int i;
+
+	/* register the tty driver */
+	serial_tty_driver.init_termios = tty_std_termios;
+	serial_tty_driver.init_termios.c_cflag =
+	    B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+
+	if (tty_register_driver(&serial_tty_driver)) {
+		err(__FUNCTION__ ": failed to register tty driver");
+		return -1;
+	}
+
+	memset(&usbserial, 0, sizeof(struct usb_serial));
+	usbserial.minor = 0;
+
+	usbserial.state = DEFAULT;
+
+	usbserial.dev_desc = &dev_desc;
+	usbserial.if_desc = &if_desc;
+	usbserial.conf_desc = &config_desc;
+
+	/*
+	 * initialize the string descriptors
+	 */
+
+	/* alloc buffer big enough for all string descriptors */
+	str_desc_len = string_desc0.bLength;
+	for (i = 0; i < 5; i++)
+		str_desc_len += 2 + 2 * strlen(strings[i]);
+	str_desc_buf = (void *) kmalloc(str_desc_len, ALLOC_FLAGS);
+	if (!str_desc_buf) {
+		err(__FUNCTION__ ": failed to alloc string descriptors");
+		return -1;
+	}
+
+	usbserial.str_desc[0] = (struct usb_string_descriptor *)str_desc_buf;
+	memcpy(usbserial.str_desc[0], &string_desc0, string_desc0.bLength);
+	usbserial.str_desc[1] = (struct usb_string_descriptor *)
+	    (str_desc_buf + string_desc0.bLength);
+	for (i = 1; i < 6; i++) {
+		struct usb_string_descriptor *desc = usbserial.str_desc[i];
+		char *str = strings[i - 1];
+		int j, str_len = strlen(str);
+
+		desc->bLength = 2 + 2 * str_len;
+		desc->bDescriptorType = USB_DT_STRING;
+		for (j = 0; j < str_len; j++) {
+			desc->wData[j] = (u16) str[j];
+		}
+		if (i < 5)
+			usbserial.str_desc[i + 1] =
+			    (struct usb_string_descriptor *)
+			    ((u8 *) desc + desc->bLength);
+	}
+
+	// request the USB device transfer complete interrupt
+	if (request_irq(AU1000_USB_DEV_REQ_INT, req_sus_intr, SA_SHIRQ,
+			"USBdev req", &usbserial)) {
+		err("Can't get device request intr\n");
+		goto err_out;
+	}
+	// request the USB device suspend interrupt
+	if (request_irq(AU1000_USB_DEV_SUS_INT, req_sus_intr, SA_SHIRQ,
+			"USBdev sus", &usbserial)) {
+		err("Can't get device suspend intr\n");
+		goto err_out;
+	}
+
+	// Initialize default control endpoint
+	ep = &usbserial.ep_ctrl;
+	spin_lock_init(&ep->lock);
+	ep->desc = NULL;	// ep0 has no ep descriptor
+	ep->reg = &ep_reg[0];
+	ep->max_pkt_size = usbserial.dev_desc->bMaxPacketSize0;
+	ep->indma = ep->outdma = -1;
+	if ((ep->indma = request_au1000_dma(ep_dma_id[0].id,
+					    ep_dma_id[0].str)) < 0) {
+		err("Can't get %s DMA\n", ep_dma_id[0].str);
+		goto err_out;
+	}
+	if ((ep->outdma = request_au1000_dma(ep_dma_id[1].id,
+					     ep_dma_id[1].str)) < 0) {
+		err("Can't get %s DMA\n", ep_dma_id[1].str);
+		goto err_out;
+	}
+	ep->inirq = get_dma_done_irq(ep->indma);
+	ep->outirq = get_dma_done_irq(ep->outdma);
+	// allocate EP0's DMA done interrupts.
+	if (request_irq(ep->inirq, dma_done_intr, SA_INTERRUPT,
+			"USBdev ep0 IN", &usbserial)) {
+		err("Can't get ep0 IN dma done irq\n");
+		goto err_out;
+	}
+#if 0
+	if (request_irq(ep->outirq, dma_done_intr, SA_INTERRUPT,
+			"USBdev ep0 OUT", &usbserial)) {
+		err("Can't get ep0 OUT dma done irq\n");
+		goto err_out;
+	}
+#endif
+
+	/* initialize the devfs nodes for this device and let the user
+	   know what ports we are bound to */
+	for (i = 0; i < NUM_PORTS; ++i) {
+		tty_register_devfs(&serial_tty_driver, 0, i);
+		info("usbdev serial attached to ttyUSBdev%d (or devfs usb/ttsdev/%d)", 
+		     i, i);
+		port = &usbserial.port[i];
+		port->serial = &usbserial;
+		port->number = i;
+		port->send_complete_tq.routine = port_send_complete;
+		port->send_complete_tq.data = port;
+		port->receive_complete_tq.routine = port_receive_complete;
+		port->receive_complete_tq.data = port;
+		spin_lock_init(&port->port_lock);
+
+		// Initialize the port's bulk IN endpoint
+		ep = &port->ep_bulkin;
+		spin_lock_init(&ep->lock);
+		ep->desc = &ep_desc[NUM_PORTS * i];
+		ep->reg = &ep_reg[1 + NUM_PORTS * i];
+		ep->max_pkt_size = ep->desc->wMaxPacketSize;
+		ep->indma = ep->outdma = -1;
+		if ((ep->indma =
+		     request_au1000_dma(ep_dma_id[2+NUM_PORTS*i].id,
+				 ep_dma_id[2 + NUM_PORTS * i].str)) < 0) {
+			err("Can't get %s DMA\n",
+			    ep_dma_id[2 + NUM_PORTS * i].str);
+			goto err_out;
+		}
+		ep->inirq = get_dma_done_irq(ep->indma);
+		if (request_irq(ep->inirq, dma_done_intr, SA_INTERRUPT,
+				"USBdev bulk IN", &usbserial)) {
+			err("Can't get port %d bulk IN dma done irq\n", i);
+			goto err_out;
+		}
+		// Initialize the port's bulk OUT endpoint
+		ep = &port->ep_bulkout;
+		spin_lock_init(&ep->lock);
+		ep->desc = &ep_desc[NUM_PORTS * i + 1];
+		ep->reg = &ep_reg[1 + NUM_PORTS * i + 1];
+		ep->max_pkt_size = ep->desc->wMaxPacketSize;
+		ep->indma = ep->outdma = -1;
+		if ((ep->outdma =
+		     request_au1000_dma(ep_dma_id[2+NUM_PORTS*i + 1].id,
+					ep_dma_id[2+NUM_PORTS*i + 1].str)) < 0) {
+			err("Can't get %s DMA\n",
+			    ep_dma_id[2 + NUM_PORTS * i + 1].str);
+			goto err_out;
+		}
+		ep->outirq = get_dma_done_irq(ep->outdma);
+#if 0
+		if (request_irq(ep->outirq, dma_done_intr, SA_INTERRUPT,
+				"USBdev bulk OUT", &usbserial)) {
+			err("Can't get port %d bulk OUT dma done irq\n", i);
+			goto err_out;
+		}
+#endif
+	}
+
+	// enable device controller
+	outl_sync(0x0002, USB_DEV_ENABLE);
+	udelay(100);
+	outl_sync(0x0003, USB_DEV_ENABLE);
+	udelay(100);
+	for (i = 0; i < sizeof(au1000_config_table) / sizeof(u32); ++i)
+		outl_sync(au1000_config_table[i], USB_DEV_CONFIG);
+
+	// Flush the endpoint buffers and FIFOs
+	ep = &usbserial.ep_ctrl;
+	endpoint_flush(ep);
+	// start packet reception on control ep
+	kickstart_receive_packet(ep);
+
+	for (i = 0; i < NUM_PORTS; ++i) {
+		struct usb_serial_port *port = &usbserial.port[i];
+		endpoint_flush(&port->ep_bulkin);
+		endpoint_flush(&port->ep_bulkout);
+		// start packet reception on bulk OUT endpoint
+		kickstart_receive_packet(&port->ep_bulkout);
+	}
+
+	/*
+	 * Enable Receive FIFO Complete interrupts only. Transmit
+	 * complete is being handled by the DMA done interrupts.
+	 */
+	outl_sync(0x31, USB_DEV_INT_ENABLE);
+
+	return 0;
+
+      err_out:
+	usbdev_serial_exit();
+	return -1;
+}
+
+
+module_init(usbdev_serial_init);
+module_exit(usbdev_serial_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1000/Makefile linux/arch/mips/au1000/pb1000/Makefile
--- linux.orig/arch/mips/au1000/pb1000/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/pb1000/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -15,10 +15,10 @@
 .S.o:
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
-all: pb1000.o
-
 O_TARGET := pb1000.o
 
 obj-y := init.o setup.o
 
+obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o
+
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1000/init.c linux/arch/mips/au1000/pb1000/init.c
--- linux.orig/arch/mips/au1000/pb1000/init.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/pb1000/init.c	2002-07-20 01:08:29.000000000 +0000
@@ -27,6 +27,7 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
@@ -38,12 +39,21 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
-extern int prom_argc;
-extern char **prom_argv, **prom_envp;
+int prom_argc;
+char **prom_argv, **prom_envp;
 extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "Alchemy Pb1000";
+}
 
 int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
 {
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
 	prom_argc = argc;
 	prom_argv = argv;
 	prom_envp = envp;
@@ -52,8 +62,12 @@
 	mips_machtype = MACH_PB1000;  
 
 	prom_init_cmdline();
-
-	add_memory_region(1, 64 << 20, BOOT_MEM_RAM);
-
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		memsize = 0x04000000;
+	} else {
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1000/pci_fixup.c linux/arch/mips/au1000/pb1000/pci_fixup.c
--- linux.orig/arch/mips/au1000/pb1000/pci_fixup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/pb1000/pci_fixup.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,90 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/au1000.h>
+#include <asm/pb1000.h>
+
+#undef	DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+	/* will need to fixup IO resources */
+}
+
+void __init pcibios_fixup(void)
+{
+	unsigned long pci_mem_start = (unsigned long) PCI_MEM_START;
+
+	writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+	writel(0, SDRAM_MBAR);        // set mbar to 0
+	writel(0x2, SDRAM_CMD);       // enable memory accesses
+	au_sync_delay(1);
+
+	// set extend byte to mbar of ext slot
+	writel(((pci_mem_start >> 24) & 0xff) |
+	       (1 << 8 | 1 << 9 | 1 << 10 | 1 << 27), PCI_BRIDGE_CONFIG);
+	DBG("Set bridge config to %x\n", readl(PCI_BRIDGE_CONFIG));
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	unsigned int slot, func;
+	unsigned char pin;
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number != 0)
+		return;
+
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		slot = PCI_SLOT(dev->devfn);
+		func = PCI_FUNC(dev->devfn);
+		dev->irq = AU1000_GPIO_15;
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+		DBG("slot %d func %d irq %d\n", slot, func, dev->irq);
+	}
+}
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1000/pci_ops.c linux/arch/mips/au1000/pb1000/pci_ops.c
--- linux.orig/arch/mips/au1000/pb1000/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/pb1000/pci_ops.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,200 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	PB1000 specific pci support.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/au1000.h>
+#include <asm/pb1000.h>
+#include <asm/pci_channel.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+#undef DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+static struct resource pci_io_resource = {
+	"pci IO space", 
+	PCI_IO_START,
+	PCI_IO_END,
+	IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+	"pci memory space", 
+	PCI_MEM_START,
+	PCI_MEM_END,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops pb1000_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{&pb1000_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 1},
+	{(struct pci_ops *) NULL, (struct resource *) NULL,
+	 (struct resource *) NULL, (int) NULL, (int) NULL}
+};
+
+
+/*
+ * "Bus 2" is really the first and only external slot on the pb1000.
+ * We'll call that bus 0, and limit the accesses to that single 
+ * external slot only. The SDRAM is already initialized in setup.c.
+ */
+static int config_access(unsigned char access_type, struct pci_dev *dev, 
+			 unsigned char where, u32 * data)
+{
+	unsigned char bus = dev->bus->number;
+	unsigned char dev_fn = dev->devfn;
+	unsigned long config;
+
+	if (((dev_fn >> 3) != 0) || (bus != 0)) {
+		*data = 0xffffffff;
+		return -1;
+	}
+
+	config = PCI_CONFIG_BASE | (where & ~0x3);
+
+	if (access_type == PCI_ACCESS_WRITE) {
+		outl(*data, config);
+	} else {
+		*data = inl(config);
+	}
+	au_sync_udelay(1);
+
+	DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n", 
+			access_type, bus, dev_fn, where, *data, config);
+
+	DBG("bridge config reg: %x (%x)\n", inl(PCI_BRIDGE_CONFIG), *data);
+
+	if (inl(PCI_BRIDGE_CONFIG) & (1 << 16)) {
+		*data = 0xffffffff;
+		return -1;
+	} else {
+		return PCIBIOS_SUCCESSFUL;
+	}
+}
+
+
+static int read_config_byte(struct pci_dev *dev, int where, u8 * val)
+{
+	u32 data;
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
+	*val = data & 0xff;
+	return ret; 
+}
+
+
+static int read_config_word(struct pci_dev *dev, int where, u16 * val)
+{
+	u32 data;
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
+	*val = data & 0xffff;
+	return ret; 
+}
+
+static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
+{
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, dev, where, val);
+	return ret; 
+}
+
+
+static int write_config_byte(struct pci_dev *dev, int where, u8 val)
+{
+	u32 data = 0;
+       
+	if (config_access(PCI_ACCESS_READ, dev, where, &data))
+		return -1;
+
+	data = (data & ~(0xff << ((where & 3) << 3))) |
+	       (val << ((where & 3) << 3));
+
+	if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+        u32 data = 0;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+       
+        if (config_access(PCI_ACCESS_READ, dev, where, &data))
+	       return -1;
+
+	data = (data & ~(0xffff << ((where & 3) << 3))) | 
+	       (val << ((where & 3) << 3));
+
+	if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
+	       return -1;
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (config_access(PCI_ACCESS_WRITE, dev, where, &val))
+	       return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops pb1000_pci_ops = {
+	read_config_byte,
+        read_config_word,
+	read_config_dword,
+	write_config_byte,
+	write_config_word,
+	write_config_dword
+};
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1000/setup.c linux/arch/mips/au1000/pb1000/setup.c
--- linux.orig/arch/mips/au1000/pb1000/setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/au1000/pb1000/setup.c	2002-07-20 01:08:31.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *	Au1000-based board setup.
+ *	Alchemy Pb1000 board setup.
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
@@ -31,45 +31,51 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/ioport.h>
+#include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/mc146818rtc.h>
+#include <linux/delay.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
+#include <asm/keyboard.h>
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
+#include <asm/pgtable.h>
 #include <asm/au1000.h>
+#include <asm/pb1000.h>
+
+#ifdef CONFIG_USB_OHCI
+// Enable the workaround for the OHCI DoneHead
+// register corruption problem.
+#define CONFIG_AU1000_OHCI_FIX
+#endif
 
 #if defined(CONFIG_AU1000_SERIAL_CONSOLE)
 extern void console_setup(char *, int *);
 char serial_console[20];
 #endif
 
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+extern void * __rd_start, * __rd_end;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops std_ide_ops;
+extern struct ide_ops *ide_ops;
+#endif
+
 void (*__wbflush) (void);
 extern struct rtc_ops no_rtc_ops;
 extern char * __init prom_getcmdline(void);
-extern void au1000_restart(void);
+extern void au1000_restart(char *);
 extern void au1000_halt(void);
 extern void au1000_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
 
-struct {
-    struct resource ram;
-    struct resource io;
-    struct resource sram;
-    struct resource flash;
-    struct resource boot;
-    struct resource pcmcia;
-    struct resource lcd;
-} au1000_resources = {
-    { "RAM",           0,          0x3FFFFFF,  IORESOURCE_MEM },
-    { "I/O",           0x10000000, 0x119FFFFF                 },
-    { "SRAM",          0x1e000000, 0x1E03FFFF                 },
-    { "System Flash",  0x1F800000, 0x1FBFFFFF                 },
-    { "Boot ROM",      0x1FC00000, 0x1FFFFFFF                 },
-    { "PCMCIA",        0x20000000, 0x27FFFFFF                 },
-    { "LCD",           0x60000000, 0x603FFFFF                 },
-};
 
 void au1000_wbflush(void)
 {
@@ -79,39 +85,223 @@
 void __init au1000_setup(void)
 {
 	char *argptr;
-
+	u32 pin_func, static_cfg0;
+	u32 sys_freqctrl, sys_clksrc;
+	u32 prid = read_32bit_cp0_register(CP0_PRID);
+	
 	argptr = prom_getcmdline();
 
+	/* Various early Au1000 Errata corrected by this */
+	set_cp0_config(1<<19); /* Config[OD] */
+
 #ifdef CONFIG_AU1000_SERIAL_CONSOLE
-	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
 #endif	  
 
-	//set_cp0_status(ST0_FR,0);
 	rtc_ops = &no_rtc_ops;
         __wbflush = au1000_wbflush;
 	_machine_restart = au1000_restart;
 	_machine_halt = au1000_halt;
 	_machine_power_off = au1000_power_off;
 
-	/*
-	 * IO/MEM resources. 
-	 */
-	mips_io_port_base = KSEG1;
-	ioport_resource.start = au1000_resources.io.start;
-	ioport_resource.end = au1000_resources.lcd.end;
+	// IO/MEM resources. 
+	set_io_port_base(0);
+	ioport_resource.start = 0x10000000;
+	ioport_resource.end = 0xffffffff;
+	iomem_resource.start = 0x10000000;
+	iomem_resource.end = 0xffffffff;
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
 #endif
 
-	outl(PC_CNTRL_E0 | PC_CNTRL_EN0 | PC_CNTRL_EN0, PC_COUNTER_CNTRL);
-	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T0S);
-	outl(0x8000-1, PC0_TRIM);
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	outl(8, SYS_AUXPLL);
+	outl(0, SYS_PINSTATERD);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+#ifdef CONFIG_USB_OHCI
+	if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) {
+	        char usb_args[80];
+		argptr = prom_getcmdline();
+		memset(usb_args, 0, sizeof(usb_args));
+		sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d",
+			USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT);
+		strcat(argptr, usb_args);
+	}
+#endif
 
-	printk("Alchemy Semi PB1000 Board\n");
-	printk("Au1000/PB1000 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
-}
+	/* zero and disable FREQ2 */
+	sys_freqctrl = inl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	outl(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD clocks */
+	sys_clksrc = inl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+	outl(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = inl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = inl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+
+	switch (prid & 0x000000FF)
+	{
+	case 0x00: /* DA */
+	case 0x01: /* HA */
+	case 0x02: /* HB */
+	/* CPU core freq to 48MHz to slow it way down... */
+	outl(4, SYS_CPUPLL);
+
+	/*
+	 * Setup 48MHz FREQ2 from CPUPLL for USB Host
+	 */
+	/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
+	sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
+	outl(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* CPU core freq to 384MHz */
+	outl(0x20, SYS_CPUPLL);
+
+	printk("Au1000: 48MHz OHCI workaround enabled\n");
+		break;
+
+	default:  /* HC and newer */
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	outl(sys_freqctrl, SYS_FREQCTRL0);
+		break;
+	}
 
+	/*
+	 * Route 48MHz FREQ2 into USB Host and/or Device
+	 */
+#ifdef CONFIG_USB_OHCI
+	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+#endif
+#ifdef CONFIG_AU1000_USB_DEVICE
+	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
+#endif
+	outl(sys_clksrc, SYS_CLKSRC);
+
+#ifdef CONFIG_USB_OHCI
+	// enable host controller and wait for reset done
+	outl(0x08, USB_HOST_CONFIG);
+	udelay(1000);
+	outl(0x0E, USB_HOST_CONFIG);
+	udelay(1000);
+	inl(USB_HOST_CONFIG); // throw away first read
+	while (!(inl(USB_HOST_CONFIG) & 0x10))
+		inl(USB_HOST_CONFIG);
+#endif
+	
+	// configure pins GPIO[14:9] as GPIO
+	pin_func = inl(SYS_PINFUNC) & (u32)(~0x8080);
+
+#ifndef CONFIG_AU1000_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	outl(pin_func, SYS_PINFUNC);
+	outl(0x2800, SYS_TRIOUTCLR);
+	outl(0x0030, SYS_OUTPUTCLR);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+
+	// make gpio 15 an input (for interrupt line) 
+	pin_func = inl(SYS_PINFUNC) & (u32)(~0x100);
+	// we don't need I2S, so make it available for GPIO[31:29] 
+	pin_func |= (1<<5);
+	outl(pin_func, SYS_PINFUNC);
+
+	outl(0x8000, SYS_TRIOUTCLR);
+	
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+	static_cfg0 = inl(MEM_STCFG0) & (u32)(~0xc00);
+	outl(static_cfg0, MEM_STCFG0);
+
+	// configure RCE2* for LCD
+	outl(0x00000004, MEM_STCFG2);
+
+	// MEM_STTIME2
+	outl(0x09000000, MEM_STTIME2);
+
+	// Set 32-bit base address decoding for RCE2*
+	outl(0x10003ff0, MEM_STADDR2);
+
+	// PCI CPLD setup
+	// expand CE0 to cover PCI
+	outl(0x11803e40, MEM_STADDR1);
+
+	// burst visibility on 
+	outl(inl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
+
+	outl(0x83, MEM_STCFG1);         // ewait enabled, flash timing
+	outl(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
+
+#ifdef CONFIG_FB_E1356
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1");
+	}
+#endif // CONFIG_FB_E1356
+
+
+#ifdef CONFIG_PCI
+	outl(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+	outl(0, SDRAM_MBAR);        // set mbar to 0
+	outl(0x2, SDRAM_CMD);       // enable memory accesses
+	au_sync_delay(1);
+#endif
+
+#ifndef CONFIG_SERIAL_NONSTANDARD
+	/* don't touch the default serial console */
+	outl(0, UART0_ADDR + UART_CLK);
+#endif
+	outl(0, UART1_ADDR + UART_CLK);
+	outl(0, UART2_ADDR + UART_CLK);
+	outl(0, UART3_ADDR + UART_CLK);
+
+#ifdef CONFIG_BLK_DEV_IDE
+	{
+		argptr = prom_getcmdline();
+		strcat(argptr, " ide0=noprobe");
+	}
+	ide_ops = &std_ide_ops;
+#endif
+
+	// setup irda clocks
+	// aux clock, divide by 2, clock from 2/4 divider
+	writel(readl(SYS_CLKSRC) | 0x7, SYS_CLKSRC);
+	pin_func = inl(SYS_PINFUNC) & (u32)(~(1<<2)); // clear IRTXD
+	outl(pin_func, SYS_PINFUNC);
+
+	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	outl(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	au_sync();
+	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	outl(0, SYS_TOYTRIM);
+
+	/* Enable Au1000 BCLK switching - note: sed1356 must not use
+	 * its BCLK (Au1000 LCLK) for any timings */
+	switch (prid & 0x000000FF)
+	{
+	case 0x00: /* DA */
+	case 0x01: /* HA */
+	case 0x02: /* HB */
+		break;
+	default:  /* HC and newer */
+		outl(0x00000060, 0xb190003c);
+		break;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1500/Makefile linux/arch/mips/au1000/pb1500/Makefile
--- linux.orig/arch/mips/au1000/pb1500/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/pb1500/Makefile	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,24 @@
+#
+#  Copyright 2000,2001 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor Pb1500 board.
+#
+# 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).
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET := pb1500.o
+
+obj-y := init.o setup.o
+
+obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1500/init.c linux/arch/mips/au1000/pb1500/init.c
--- linux.orig/arch/mips/au1000/pb1500/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/pb1500/init.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,73 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	PB1500 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "Alchemy Pb1500";
+}
+
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = argc;
+	prom_argv = argv;
+	prom_envp = envp;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_PB1500;  
+
+	prom_init_cmdline();
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		memsize = 0x04000000;
+	} else {
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1500/pci_fixup.c linux/arch/mips/au1000/pb1500/pci_fixup.c
--- linux.orig/arch/mips/au1000/pb1500/pci_fixup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/pb1500/pci_fixup.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,119 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/au1000.h>
+#include <asm/pb1500.h>
+
+#undef	DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+static void fixup_resource(int r_num, struct pci_dev *dev) ;
+static unsigned long virt_io_addr;
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+	/* will need to fixup IO resources */
+}
+
+void __init pcibios_fixup(void)
+{
+	int i;
+	struct pci_dev *dev;
+	
+	virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, 
+			Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1);
+
+	if (!virt_io_addr) {
+		printk(KERN_ERR "Unable to ioremap pci space\n");
+		return;
+	}
+
+	pci_for_each_dev(dev) {
+		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
+			if (dev->resource[i].start) {
+				fixup_resource(i, dev);
+			}
+		}
+	}
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	unsigned int slot, func;
+	unsigned char pin;
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number != 0)
+			return;
+
+		dev->irq = 0xff;
+		slot = PCI_SLOT(dev->devfn);
+		switch (slot) {
+			case 12:
+			case 13:
+				dev->irq = AU1000_PCI_INTA;
+				break;
+
+		}
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+		DBG("slot %d irq %d\n", slot, dev->irq);
+	}
+}
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+
+static void fixup_resource(int r_num, struct pci_dev *dev) 
+{
+	unsigned long start, size, new_start;
+
+	if (dev->resource[r_num].flags & IORESOURCE_IO) {
+		start = dev->resource[r_num].start;
+		size = dev->resource[r_num].end - start;
+		new_start = virt_io_addr + (start - Au1500_PCI_IO_START);
+		dev->resource[r_num].start = new_start;
+		dev->resource[r_num].end = new_start + size;
+	}
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1500/pci_ops.c linux/arch/mips/au1000/pb1500/pci_ops.c
--- linux.orig/arch/mips/au1000/pb1500/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/pb1500/pci_ops.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,241 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Pb1500 specific pci support.
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/au1000.h>
+#include <asm/pb1500.h>
+#include <asm/pci_channel.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+#undef DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+/* TBD */
+static struct resource pci_io_resource = {
+	"pci IO space", 
+	Au1500_PCI_IO_START,
+	Au1500_PCI_IO_END,
+	IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+	"pci memory space", 
+	Au1500_PCI_MEM_START,
+	Au1500_PCI_MEM_END,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops pb1500_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{&pb1500_pci_ops, &pci_io_resource, &pci_mem_resource, (10<<3),(16<<3)},
+	{(struct pci_ops *) NULL, (struct resource *) NULL,
+	 (struct resource *) NULL, (int) NULL, (int) NULL}
+};
+
+static unsigned long cfg_addr;
+static int config_access(unsigned char access_type, struct pci_dev *dev, 
+			 unsigned char where, u32 * data)
+{
+	unsigned char bus = dev->bus->number;
+	unsigned int dev_fn = dev->devfn;
+	unsigned int device, function;
+	unsigned long config, status;
+	static int first = 1;
+
+	/* 
+ 	 * 7:3 = slot
+ 	 * 2:0 = function
+	 */
+
+	if (bus != 0) {
+		*data = 0xffffffff;
+		return -1;
+	}
+
+	if (first) {
+		first = 0;
+		cfg_addr = ioremap(Au1500_EXT_CFG, 0x10000000);
+		if (!cfg_addr) 
+			printk (KERN_ERR "PCI unable to ioremap cfg space\n");
+	}
+
+	device = (dev_fn >> 3) & 0x1f;
+	function = dev_fn & 0x7;
+
+#if 1
+	//if (!cfg_addr || (device < 10) || (device > 16)) {
+	if (!cfg_addr || (device > 16)) {
+		*data = 0xffffffff;
+		return -1;
+	}
+#endif
+
+	writel(((0x2000 << 16) | (readl(Au1500_PCI_STATCMD) & 0xffff)),
+			Au1500_PCI_STATCMD);
+	//writel(readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG);
+	au_sync_udelay(1);
+
+	/* setup the lower 31 bits of the 36 bit address */
+	config = cfg_addr | 
+		((1<<device)<<11) | (function << 8) | (where & ~0x3);
+
+#if 0
+	printk("cfg access: config %x, dev_fn %x, device %x function %x\n",
+			config, dev_fn, device, function);
+#endif
+
+	if (access_type == PCI_ACCESS_WRITE) {
+		writel(*data, config);
+	} else {
+		*data = readl(config);
+	}
+	au_sync_udelay(1);
+
+	DBG("config_access: %d bus %d device %d at %x *data %x, conf %x\n", 
+			access_type, bus, device, where, *data, config);
+
+	/* check master abort */
+	status = readl(Au1500_PCI_STATCMD);
+	if (status & (1<<29)) { 
+		*data = 0xffffffff;
+		return -1;
+	} else if ((status >> 28) & 0xf) {
+		DBG("PCI ERR detected: status %x\n", status);
+		*data = 0xffffffff;
+		return -1;
+	}
+	else {
+		return PCIBIOS_SUCCESSFUL;
+	}
+}
+
+
+static int read_config_byte(struct pci_dev *dev, int where, u8 * val)
+{
+	u32 data;
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
+        if (where & 1) data >>= 8;
+        if (where & 2) data >>= 16;
+        *val = data & 0xff;
+	return ret; 
+}
+
+
+static int read_config_word(struct pci_dev *dev, int where, u16 * val)
+{
+	u32 data;
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
+        if (where & 2) data >>= 16;
+        *val = data & 0xffff;
+	return ret; 
+}
+
+static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
+{
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, dev, where, val);
+	return ret; 
+}
+
+
+static int write_config_byte(struct pci_dev *dev, int where, u8 val)
+{
+	u32 data = 0;
+       
+	if (config_access(PCI_ACCESS_READ, dev, where, &data))
+		return -1;
+
+	data = (data & ~(0xff << ((where & 3) << 3))) |
+	       (val << ((where & 3) << 3));
+
+	if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+        u32 data = 0;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+       
+        if (config_access(PCI_ACCESS_READ, dev, where, &data))
+	       return -1;
+
+	data = (data & ~(0xffff << ((where & 3) << 3))) | 
+	       (val << ((where & 3) << 3));
+
+	if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
+	       return -1;
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (config_access(PCI_ACCESS_WRITE, dev, where, &val))
+	       return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops pb1500_pci_ops = {
+	read_config_byte,
+        read_config_word,
+	read_config_dword,
+	write_config_byte,
+	write_config_word,
+	write_config_dword
+};
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/au1000/pb1500/setup.c linux/arch/mips/au1000/pb1500/setup.c
--- linux.orig/arch/mips/au1000/pb1500/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/au1000/pb1500/setup.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,256 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy Pb1000 board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/keyboard.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/au1000.h>
+#include <asm/pb1500.h>
+
+#ifdef CONFIG_USB_OHCI
+// Enable the workaround for the OHCI DoneHead
+// register corruption problem.
+#define CONFIG_AU1000_OHCI_FIX
+#endif
+
+#if defined(CONFIG_AU1000_SERIAL_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+extern void * __rd_start, * __rd_end;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops std_ide_ops;
+extern struct ide_ops *ide_ops;
+#endif
+
+#ifdef CONFIG_RTC
+extern struct rtc_ops pb1500_rtc_ops;
+#endif
+
+void (*__wbflush) (void);
+extern char * __init prom_getcmdline(void);
+extern void au1000_restart(char *);
+extern void au1000_halt(void);
+extern void au1000_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+
+
+void au1500_wbflush(void)
+{
+	__asm__ volatile ("sync");
+}
+
+void __init au1500_setup(void)
+{
+	char *argptr;
+	u32 pin_func, static_cfg0;
+	u32 sys_freqctrl, sys_clksrc;
+	
+	argptr = prom_getcmdline();
+
+	/* NOTE: The memory map is established by YAMON 2.08+ */
+
+	/* Various early Au1500 Errata corrected by this */
+	set_cp0_config(1<<19); /* Config[OD] */
+
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS0,115200");
+	}
+#endif	  
+
+#ifdef CONFIG_SOUND_AU1000
+	strcat(argptr, " au1000_audio=vra");
+	argptr = prom_getcmdline();
+#endif
+
+        __wbflush = au1500_wbflush;
+	_machine_restart = au1000_restart;
+	_machine_halt = au1000_halt;
+	_machine_power_off = au1000_power_off;
+
+	// IO/MEM resources. 
+	set_io_port_base(0);
+	ioport_resource.start = 0x10000000;
+	ioport_resource.end = 0xffffffff;
+	iomem_resource.start = 0x10000000;
+	iomem_resource.end = 0xffffffff;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
+#endif
+
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	writel(8, SYS_AUXPLL);
+	outl(0, SYS_PINSTATERD);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+#ifdef CONFIG_USB_OHCI
+	if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) {
+	        char usb_args[80];
+		argptr = prom_getcmdline();
+		memset(usb_args, 0, sizeof(usb_args));
+		sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d",
+			USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT);
+		strcat(argptr, usb_args);
+	}
+#endif
+
+	/* zero and disable FREQ2 */
+	sys_freqctrl = readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD clocks */
+	sys_clksrc = readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+	writel(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/*
+	 * Route 48MHz FREQ2 into USB Host and/or Device
+	 */
+#ifdef CONFIG_USB_OHCI
+	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+#endif
+#ifdef CONFIG_AU1000_USB_DEVICE
+	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
+#endif
+	writel(sys_clksrc, SYS_CLKSRC);
+
+
+	pin_func = readl(SYS_PINFUNC) & (u32)(~0x8000);
+#ifndef CONFIG_AU1000_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	writel(pin_func, SYS_PINFUNC);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+
+
+#ifdef CONFIG_USB_OHCI
+	// enable host controller and wait for reset done
+	writel(0x08, USB_HOST_CONFIG);
+	udelay(1000);
+	writel(0x0c, USB_HOST_CONFIG);
+	udelay(1000);
+	readl(USB_HOST_CONFIG);
+	while (!(readl(USB_HOST_CONFIG) & 0x10))
+	    ;
+	readl(USB_HOST_CONFIG);
+#endif
+	
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_FB_E1356
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " video=e1356fb:system:pb1500,mmunalign:1");
+	}
+#endif // CONFIG_FB_E1356
+
+#ifndef CONFIG_SERIAL_NONSTANDARD
+	/* don't touch the default serial console */
+	writel(0, UART0_ADDR + UART_CLK);
+#endif
+	writel(0, UART3_ADDR + UART_CLK);
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+
+#ifdef CONFIG_PCI
+	// Setup PCI bus controller
+	writel(0, Au1500_PCI_CMEM);
+	writel(0x00003fff, Au1500_CFG_BASE);
+	writel(0xf, Au1500_PCI_CFG);
+	writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
+	writel(0, Au1500_PCI_MWBASE_REV_CCL);
+	writel(0x02a00356, Au1500_PCI_STATCMD);
+	writel(0x00003c04, Au1500_PCI_HDRTYPE);	
+	writel(0x00000008, Au1500_PCI_MBAR);
+	au_sync();
+#endif
+
+	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	au_sync();
+	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	outl(0, SYS_TOYTRIM);
+
+	/* Enable BCLK switching */
+	writel(0x00000060, 0xb190003c);
+
+#ifdef CONFIG_RTC
+	rtc_ops = &pb1500_rtc_ops;
+	// Enable the RTC if not already enabled 
+	if (!(readb(0xac000028) & 0x20)) {
+		writeb(readb(0xac000028) | 0x20, 0xac000028);
+	}
+	// Put the clock in BCD mode
+	if (readb(0xac00002C) & 0x4) { /* reg B */
+		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
+		au_sync();
+	}
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/baget.c linux/arch/mips/baget/baget.c
--- linux.orig/arch/mips/baget/baget.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/baget/baget.c	2002-07-20 01:08:38.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: baget.c,v 1.1 1999/01/17 03:49:37 ralf Exp $
- *
+/*
  * baget.c: Baget low level stuff
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/bagetIRQ.S linux/arch/mips/baget/bagetIRQ.S
--- linux.orig/arch/mips/baget/bagetIRQ.S	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/baget/bagetIRQ.S	2002-07-20 01:08:29.000000000 +0000
@@ -1,9 +1,8 @@
-/* $Id: bagetIRQ.S,v 1.1 1999/01/17 03:49:37 ralf Exp $
+/*
  * bagetIRQ.S: Interrupt exception dispatch code for Baget/MIPS
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  */
-
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/balo.c linux/arch/mips/baget/balo.c
--- linux.orig/arch/mips/baget/balo.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/baget/balo.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,9 +1,7 @@
-/* $Id$
- *
+/*
  * balo.c: BAget LOader
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- *
  */
 #include <linux/kernel.h>
 #include <asm/system.h>
@@ -42,27 +40,29 @@
 
 static __inline__ void reset_and_jump(int start, int mem_upper)
 {
+	unsigned long tmp;
+
 	__asm__ __volatile__(
                 ".set\tnoreorder\n\t"
                 ".set\tnoat\n\t"
-                "mfc0\t$1,$12\n\t"
+                "mfc0\t$1, $12\n\t"
                 "nop\n\t"
                 "nop\n\t"
                 "nop\n\t"
-                "ori\t$1,$1,0xff00\n\t"
-                "xori\t$1,$1,0xff00\n\t"
-                "mtc0\t$1,$12\n\t"
+                "ori\t$1, $1, 0xff00\n\t"
+                "xori\t$1, $1, 0xff00\n\t"
+                "mtc0\t$1, $12\n\t"
                 "nop\n\t"
                 "nop\n\t"
                 "nop\n\t"
-		"move\t$4,%1\n\t"
-		"jr\t%0\n\t"
+		"move\t%0, %2\n\t"
+		"jr\t%1\n\t"
 		"nop\n\t"
                 ".set\tat\n\t"
                 ".set\treorder"           
-                : /* no outputs */
-                :"Ir" (start), "Ir" (mem_upper)
-                :"$1", "$4", "memory");
+                : "=&r" (tmp)
+                : "Ir" (start), "Ir" (mem_upper)
+                : "memory");
 }
 
 static void start_kernel(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/balo_supp.S linux/arch/mips/baget/balo_supp.S
--- linux.orig/arch/mips/baget/balo_supp.S	2000-02-28 15:18:20.000000000 +0000
+++ linux/arch/mips/baget/balo_supp.S	2002-07-20 01:08:22.000000000 +0000
@@ -1,9 +1,8 @@
-/* $Id: balo_supp.S,v 1.1 1999/01/17 03:49:38 ralf Exp $
+/*
  * balo_supp.S: BAget Loader supplement
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  */
-
 #include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/irq.c linux/arch/mips/baget/irq.c
--- linux.orig/arch/mips/baget/irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/baget/irq.c	2002-07-20 01:08:38.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include <asm/baget/baget.h>
 
-unsigned long spurious_count = 0;
+volatile unsigned long irq_err_count;
 
 /*
  * This table is a correspondence between IRQ numbers and CPU PILs
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/print.c linux/arch/mips/baget/print.c
--- linux.orig/arch/mips/baget/print.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/baget/print.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,9 +1,7 @@
-/* $Id: print.c,v 1.1 1999/01/17 03:49:38 ralf Exp $
- *
+/*
  * print.c: Simple print fascility
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- *
  */
 #include <stdarg.h>
 #include <linux/kernel.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/prom/init.c linux/arch/mips/baget/prom/init.c
--- linux.orig/arch/mips/baget/prom/init.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/baget/prom/init.c	2002-07-20 01:08:31.000000000 +0000
@@ -7,7 +7,13 @@
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	/* Should probably return one of "BT23-201", "BT23-202" */
+	return "Baget";
+}
 
 void __init prom_init(unsigned int mem_upper)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/setup.c linux/arch/mips/baget/setup.c
--- linux.orig/arch/mips/baget/setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/baget/setup.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,9 +1,7 @@
-/* $Id: setup.c,v 1.4 1999/10/09 00:00:57 ralf Exp $
- *
+/*
  * setup.c: Baget/MIPS specific setup, including init of the feature struct.
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- *
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/baget/vacserial.c linux/arch/mips/baget/vacserial.c
--- linux.orig/arch/mips/baget/vacserial.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/baget/vacserial.c	2002-07-20 01:08:25.000000000 +0000
@@ -1785,7 +1785,7 @@
 		schedule_timeout(char_time);
 		if (signal_pending(current))
 			break;
-		if (timeout && ((orig_jiffies + timeout) < jiffies))
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
 			break;
 	}
 	current->state = TASK_RUNNING;
@@ -2406,9 +2406,9 @@
 	callout_driver.proc_entry = 0;
 
 	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register serial driver\n");
+		panic("Couldn't register serial driver");
 	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
+		panic("Couldn't register callout driver");
 	
 	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
 		state->magic = SSTATE_MAGIC;
@@ -2622,43 +2622,6 @@
 	serial_outp(&scr_info, VAC_UART_INT_MASK, ier);
 }
 
-/*
- *	Receive character from the serial port
- */
-static int serial_console_wait_key(struct console *co)
-{
-	struct serial_state *ser;
-	int ier;
-	int lsr;
-	int c;
-	struct async_struct scr_info; /* serial_{in,out} because HUB6 */
-
-	ser = rs_table + co->index;
-	scr_info.magic = SERIAL_MAGIC;
-	scr_info.port = ser->port;
-	scr_info.flags = ser->flags;
-
-	/*
-	 *	First save the IER then disable the interrupts so
-	 *	that the real driver for the port does not get the
-	 *	character.
-	 */
-	ier = serial_inp(&scr_info, VAC_UART_INT_MASK);
-	serial_outp(&scr_info, VAC_UART_INT_MASK, 0x00);
-
-	do {
-		lsr = serial_inp(&scr_info, VAC_UART_INT_STATUS);
-	} while (!(lsr & VAC_UART_STATUS_RX_READY));
-	c = serial_inp(&scr_info, VAC_UART_RX);
-
-	/*
-	 *	Restore the interrupts
-	 */
-	serial_outp(&scr_info, VAC_UART_INT_MASK, ier);
-
-	return c;
-}
-
 static kdev_t serial_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
@@ -2812,7 +2775,6 @@
 	name:		"ttyS",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/boot/Makefile linux/arch/mips/boot/Makefile
--- linux.orig/arch/mips/boot/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/boot/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -6,10 +6,7 @@
 # Copyright (C) 1995, 1998, 2001 by Ralf Baechle
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 OBJS  = milo.o a.out.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/boot/addinitrd.c linux/arch/mips/boot/addinitrd.c
--- linux.orig/arch/mips/boot/addinitrd.c	1999-06-26 00:40:12.000000000 +0000
+++ linux/arch/mips/boot/addinitrd.c	2002-07-20 01:08:27.000000000 +0000
@@ -8,6 +8,8 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <stdio.h>
+#include <netinet/in.h>
 
 #include "ecoff.h"
 
@@ -44,7 +46,7 @@
 	char buf[1024];
 	unsigned long loadaddr;
 	unsigned long initrd_header[2];
-	int i;
+	int i,cnt;
 	int swab = 0;
 
 	if (argc != 4) {
@@ -60,7 +62,6 @@
 		die ("read aout header");
 	if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
 		die ("read section headers");
-
 	/*
 	 * check whether the file is good for us
 	 */
@@ -98,9 +99,20 @@
 		die ("write aout header");
 	if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
 		die ("write section headers");
-	while ((i = read (fd_vmlinux, buf, sizeof buf)) > 0)
+	/* skip padding */
+	if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
+		die ("lseek vmlinux");
+	if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
+		die ("lseek outfile");
+	/* copy text segment */
+	cnt = SWAB(eaout.tsize);
+	while (cnt) {
+		if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0)
+			die ("read vmlinux");
 		if (write (fd_outfile, buf, i) != i)
 			die ("write vmlinux");
+		cnt -= i;
+	}
 	if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
 		die ("write initrd header");
 	while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/boot/elf2ecoff.c linux/arch/mips/boot/elf2ecoff.c
--- linux.orig/arch/mips/boot/elf2ecoff.c	2001-03-07 03:44:36.000000000 +0000
+++ linux/arch/mips/boot/elf2ecoff.c	2002-07-20 01:08:35.000000000 +0000
@@ -41,6 +41,8 @@
 #include <unistd.h>
 #include <elf.h>
 #include <limits.h>
+#include <netinet/in.h>
+#include <stdlib.h>
 
 #include "ecoff.h"
 
@@ -56,9 +58,10 @@
   unsigned long len;
 };
 
+void combine (struct sect* base, struct sect* new, int pad);
 int phcmp ();
 char *saveRead (int file, off_t offset, off_t len, char *name);
-int copy (int, int, off_t, off_t);
+void copy (int, int, off_t, off_t);
 int translate_syms (int, int, off_t, off_t, off_t, off_t);
 void convert_elf_hdr (Elf32_Ehdr *);
 void convert_elf_phdrs (Elf32_Phdr *, int);
@@ -71,14 +74,13 @@
 int must_convert_endian = 0;
 int format_bigendian = 0;
 
+int
 main (int argc, char **argv, char **envp)
 {
   Elf32_Ehdr ex;
   Elf32_Phdr *ph;
   Elf32_Shdr *sh;
-  Elf32_Sym *symtab;
   char *shstrtab;
-  int strtabix, symtabix;
   int i, pad;
   struct sect text, data, bss;
   struct filehdr efh;
@@ -168,7 +170,8 @@
       /* Section types we can't handle... */
       else if (ph [i].p_type != PT_LOAD)
         {
-	  fprintf (stderr, "Program header %d type %d can't be converted.\n");
+	  fprintf (stderr, "Program header %d type %d can't be converted.\n", 
+			  	ex.e_phnum, ph[i].p_type );
 	  exit (1);
 	}
       /* Writable (data) segment? */
@@ -330,7 +333,7 @@
 
     for (i = 0; i < nosecs; i++)
       {
-        printf ("Section %d: %s phys %x  size %x  file offset %x\n", 
+        printf ("Section %d: %s phys %lx  size %lx  file offset %lx\n", 
 	      i, esecs [i].s_name, esecs [i].s_paddr,
 	      esecs [i].s_size, esecs [i].s_scnptr);
       }
@@ -384,11 +387,11 @@
 	      char obuf [1024];
 	      if (gap > 65536)
 		{
-		  fprintf (stderr, "Intersegment gap (%d bytes) too large.\n",
+		  fprintf (stderr, "Intersegment gap (%ld bytes) too large.\n",
 			   gap);
 		  exit (1);
 		}
-	      fprintf (stderr, "Warning: %d byte intersegment gap.\n", gap);
+	      fprintf (stderr, "Warning: %ld byte intersegment gap.\n", gap);
 	      memset (obuf, 0, sizeof obuf);
 	      while (gap)
 		{
@@ -428,6 +431,7 @@
   exit (0);
 }
 
+void
 copy (out, in, offset, size)
      int out, in;
      off_t offset, size;
@@ -465,6 +469,7 @@
 
 /* Combine two segments, which must be contiguous.   If pad is true, it's
    okay for there to be padding between. */
+void
 combine (base, new, pad)
      struct sect *base, *new;
      int pad;
@@ -488,6 +493,7 @@
     }
 }
 
+int
 phcmp (h1, h2)
      Elf32_Phdr *h1, *h2;
 {
@@ -511,7 +517,7 @@
     }
   if (!(tmp = (char *)malloc (len)))
     {
-      fprintf (stderr, "%s: Can't allocate %d bytes.\n", name, len);
+      fprintf (stderr, "%s: Can't allocate %ld bytes.\n", name, len);
       exit (1);
     }
   count = read (file, tmp, len);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/cobalt/Makefile linux/arch/mips/cobalt/Makefile
--- linux.orig/arch/mips/cobalt/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/cobalt/Makefile	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,16 @@
+#
+# Makefile for the Cobalt micro systems family specific parts of the 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 := cobalt.o
+
+obj-y	 := irq.o int-handler.o pci.o reset.o setup.o via.o promcon.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/cobalt/int-handler.S linux/arch/mips/cobalt/int-handler.S
--- linux.orig/arch/mips/cobalt/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/cobalt/int-handler.S	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,103 @@
+/*
+ * Cobalt interrupt handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/cobalt/cobalt.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * cobalt_handle_int: Interrupt handler for Cobalt boards
+ */
+		.text
+		.set	noreorder
+		.set	noat
+		.align	5
+		NESTED(cobalt_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+	
+		/* 
+		 * Get pending Interrupts
+		 */
+		mfc0	s0,CP0_CAUSE	# get irq mask
+
+		andi	a0,s0,CAUSEF_IP2	/* Check for Galileo timer */
+		beq	a0,zero,1f
+		 andi	a0,s0,CAUSEF_IP6	/* Check for Via chip */
+
+		/* Galileo interrupt */
+		jal	galileo_irq
+		 move	a0,sp
+		j	ret_from_irq
+		 nop
+
+1:
+		beq	a0,zero,1f		/* Check IP6 */
+		 andi	a0,s0,CAUSEF_IP3
+
+		/* Via interrupt */
+		jal	via_irq
+		 move	a0,sp
+		j	ret_from_irq
+		 nop
+
+1:	
+		beq	a0,zero,1f		/* Check IP3 */
+		 andi	a0,s0,CAUSEF_IP4
+
+		/* Ethernet 0 interrupt */
+		li	a0,4
+		jal     do_IRQ
+		 move	a1,sp
+
+		j	ret_from_irq
+		 nop
+
+1:	
+		beq	a0,zero,1f		/* Check IP4 */
+		 andi	a0,s0,CAUSEF_IP5
+
+		/* Ethernet 1 interrupt */
+		li	a0,13
+		jal     do_IRQ
+		 move	a1,sp
+
+		j	ret_from_irq
+		 nop
+1:	
+		beq	a0,zero,1f		/* Check IP5 */
+		 andi	a0,s0,CAUSEF_IP7
+
+		/* Serial interrupt */
+		li	a0,7
+		jal     do_IRQ
+		 move	a1,sp
+
+		j	ret_from_irq
+		 nop
+1:	
+		beq	a0,zero,1f		/* Check IP7 */
+		  nop
+
+		/* PCI interrupt */
+		li	a0,9
+		jal     do_IRQ
+		 move	a1,sp
+
+1:
+		j	ret_from_irq
+		 nop
+
+		END(cobalt_handle_int)
+	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/cobalt/irq.c linux/arch/mips/cobalt/irq.c
--- linux.orig/arch/mips/cobalt/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/cobalt/irq.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,223 @@
+/*
+ * IRQ vector handles
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/cobalt/cobalt.h>
+
+/* Cobalt Exception handler */
+extern void cobalt_handle_int(void);
+
+/* Via masking routines */
+extern void unmask_irq(unsigned int irqr);
+extern void mask_irq(unsigned int irq);
+
+
+/*
+ * We have two types of interrupts that we handle, ones that come
+ *  in through the CPU interrupt lines, and ones that come in on
+ *  the via chip. The CPU mappings are:
+ *    0,1 - S/W (ignored)
+ *    2   - Galileo chip (timer)
+ *    3   - Tulip 0 + NCR SCSI
+ *    4   - Tulip 1
+ *    5   - 16550 UART
+ *    6   - VIA southbridge PIC
+ *    7   - PCI
+ *
+ * The VIA chip is a master/slave 8259 setup and has the 
+ *  following interrupts
+ *    8   - RTC
+ *    14  - IDE0
+ *    15  - IDE1
+ *
+ * In the table we use a 1 to indicate that we use a VIA interrupt
+ *  line, and IE_IRQx to indicate that we use a CPU interrupt line
+ *
+ * We map all of these onto linux IRQ #s 0-15 and forget the rest
+ */
+#define NOINT_LINE	0
+#define CPUINT_LINE(x)	IE_IRQ##x
+#define VIAINT_LINE	1
+
+#define COBALT_IRQS	16
+
+static unsigned short irqnr_to_type[COBALT_IRQS] = 
+{ CPUINT_LINE(0),  NOINT_LINE,      VIAINT_LINE,  NOINT_LINE, 
+  CPUINT_LINE(1),  NOINT_LINE,      NOINT_LINE,   CPUINT_LINE(3),
+  VIAINT_LINE,     VIAINT_LINE,     NOINT_LINE,   NOINT_LINE,
+  NOINT_LINE,      CPUINT_LINE(2),  VIAINT_LINE,  VIAINT_LINE };
+
+/*
+ * Cobalt CPU irq
+ */
+
+static void enable_cpu_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	change_cp0_status(irqnr_to_type[irq], irqnr_to_type[irq]);
+	restore_flags(flags);
+}
+
+static unsigned startup_cpu_irq(unsigned int irq)
+{
+	enable_cpu_irq(irq);
+
+	return 0;
+}
+
+static void disable_cpu_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	change_cp0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq]));
+	restore_flags(flags);
+}
+
+#define shutdown_cpu_irq	disable_cpu_irq
+#define mask_and_ack_cpu_irq	disable_cpu_irq
+
+static void end_cpu_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_cpu_irq(irq);
+}
+
+static struct hw_interrupt_type cobalt_cpu_irq_type = {
+	"Cobalt CPU",
+	startup_cpu_irq,
+	shutdown_cpu_irq,
+	enable_cpu_irq,
+	disable_cpu_irq,
+	mask_and_ack_cpu_irq,
+	end_cpu_irq,
+	NULL
+};
+
+
+/*
+ * Cobalt VIA irq
+ */
+
+static void enable_via_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	unmask_irq(irq);
+	restore_flags(flags);
+}
+
+static unsigned startup_via_irq(unsigned int irq)
+{
+	enable_via_irq(irq);
+
+	return 0;
+}
+
+static void disable_via_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	mask_irq(irq);
+	restore_flags(flags);
+}
+
+#define shutdown_via_irq	disable_via_irq
+#define mask_and_ack_via_irq	disable_via_irq
+
+static void end_via_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_via_irq(irq);
+}
+
+static struct hw_interrupt_type cobalt_via_irq_type = {
+	"Cobalt VIA",
+	startup_via_irq,
+	shutdown_via_irq,
+	enable_via_irq,
+	disable_via_irq,
+	mask_and_ack_via_irq,
+	end_via_irq,
+	NULL
+};
+
+
+static struct irqaction via_irq2 = {
+	no_action, 0, 0, "slave cascade", NULL, NULL
+};
+
+static struct resource pic1_io_resource = {
+	"VIA PIC Master", 0x20, 0x3f, IORESOURCE_BUSY
+};
+
+static struct resource pic2_io_resource = {
+	"VIA PIC Slave", 0xa0, 0xbf, IORESOURCE_BUSY
+};
+
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	/* Initialise all of the IRQ descriptors */
+	init_generic_irq();
+
+	/* Map the irqnr to the type int we have */
+	for (i=0; i < COBALT_IRQS; i++) {
+		if (irqnr_to_type[i] >= CPUINT_LINE(0))
+			/* cobalt_cpu_irq_type */
+			irq_desc[i].handler = &cobalt_cpu_irq_type;
+		else if (irqnr_to_type[i] == VIAINT_LINE)
+			/* VIA/8259 irq_type */
+			irq_desc[i].handler = &cobalt_via_irq_type;
+		else {} /* Leave it as disabled/no handler */
+	}
+
+	/* Setup the VIA interrupts */
+	request_resource(&ioport_resource, &pic1_io_resource);
+	request_resource(&ioport_resource, &pic2_io_resource);
+	setup_irq(2, &via_irq2);
+
+	/* This may be too simple.. FIX it later */
+	VIA_PORT_WRITE(0x20, 0x10);
+	VIA_PORT_WRITE(0x21, 0x00);
+	VIA_PORT_WRITE(0x21, 0x00);
+
+	VIA_PORT_WRITE(0xa0, 0x10);
+	VIA_PORT_WRITE(0xa1, 0x00);
+	VIA_PORT_WRITE(0xa1, 0x00);
+
+	/* Mask all cpu interrupts
+	    (except IE4, we already masked those at VIA level) */
+	clear_cp0_status(ST0_IM);
+	set_cp0_status(IE_IRQ4);
+
+	cli();
+
+	set_except_vector(0, cobalt_handle_int);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/cobalt/pci.c linux/arch/mips/cobalt/pci.c
--- linux.orig/arch/mips/cobalt/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/cobalt/pci.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,429 @@
+/*
+ * Cobalt Qube/Raq PCI support
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/cobalt/cobalt.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+ 
+#ifdef CONFIG_PCI
+
+static void qube_expansion_slot_bist(struct pci_dev *dev)
+{
+	unsigned char ctrl;
+	int timeout = 100000;
+
+	pci_read_config_byte(dev, PCI_BIST, &ctrl);
+	if(!(ctrl & PCI_BIST_CAPABLE))
+		return;
+
+	pci_write_config_byte(dev, PCI_BIST, ctrl|PCI_BIST_START);
+	do {
+		pci_read_config_byte(dev, PCI_BIST, &ctrl);
+		if(!(ctrl & PCI_BIST_START))
+			break;
+	} while(--timeout > 0);
+	if((timeout <= 0) || (ctrl & PCI_BIST_CODE_MASK))
+		printk("PCI: Expansion slot card failed BIST with code %x\n",
+		       (ctrl & PCI_BIST_CODE_MASK));
+}
+
+static void qube_expansion_slot_fixup(struct pci_dev *dev)
+{
+	unsigned short pci_cmd;
+	unsigned long ioaddr_base = 0x10108000; /* It's magic, ask Doug. */
+	unsigned long memaddr_base = 0x12000000;
+	int i;
+
+	/* Enable bits in COMMAND so driver can talk to it. */
+	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+	pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+	/* Give it a working IRQ. */
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_QUBE_SLOT_IRQ);
+
+	/* Fixup base addresses, we only support I/O at the moment. */
+	for(i = 0; i <= 5; i++) {
+		unsigned int regaddr = (PCI_BASE_ADDRESS_0 + (i * 4));
+		unsigned int rval, mask, size, alignme, aspace;
+		unsigned long *basep = &ioaddr_base;
+
+		/* Check type first, punt if non-IO. */
+		pci_read_config_dword(dev, regaddr, &rval);
+		aspace = (rval & PCI_BASE_ADDRESS_SPACE);
+		if(aspace != PCI_BASE_ADDRESS_SPACE_IO)
+			basep = &memaddr_base;
+
+		/* Figure out how much it wants, if anything. */
+		pci_write_config_dword(dev, regaddr, 0xffffffff);
+		pci_read_config_dword(dev, regaddr, &rval);
+
+		/* Unused? */
+		if(rval == 0)
+			continue;
+
+		rval &= PCI_BASE_ADDRESS_IO_MASK;
+		mask = (~rval << 1) | 0x1;
+		size = (mask & rval) & 0xffffffff;
+		alignme = size;
+		if(alignme < 0x400)
+			alignme = 0x400;
+		rval = ((*basep + (alignme - 1)) & ~(alignme - 1));
+		*basep = (rval + size);
+		pci_write_config_dword(dev, regaddr, rval | aspace);
+		dev->resource[i].start = rval;
+		dev->resource[i].end = *basep - 1;
+		if(aspace == PCI_BASE_ADDRESS_SPACE_IO) {
+			dev->resource[i].start -= 0x10000000;
+			dev->resource[i].end -= 0x10000000;
+		}
+	}
+	qube_expansion_slot_bist(dev);
+}
+
+static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
+{
+	unsigned short cfgword;
+	unsigned char lt;
+
+	/* Enable Bus Mastering and fast back to back. */
+	pci_read_config_word(dev, PCI_COMMAND, &cfgword);
+	cfgword |= (PCI_COMMAND_FAST_BACK | PCI_COMMAND_MASTER);
+	pci_write_config_word(dev, PCI_COMMAND, cfgword);
+
+	/* Enable both ide interfaces. ROM only enables primary one.  */
+	pci_write_config_byte(dev, 0x40, 0xb);
+
+	/* Set latency timer to reasonable value. */
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lt);
+	if(lt < 64)
+		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+}
+
+static void qube_raq_tulip_fixup(struct pci_dev *dev)
+{
+	unsigned short pci_cmd;
+	extern int cobalt_is_raq;
+
+	/* Fixup the first tulip located at device PCICONF_ETH0 */
+	if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH0) {
+		/*
+		 * Now tell the Ethernet device that we expect an interrupt at
+		 * IRQ 13 and not the default 189.
+		 *
+		 * The IRQ of the first Tulip is different on Qube and RaQ
+		 */
+		if (!cobalt_is_raq) {
+			/* All Qube's route this the same way. */
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+                                              COBALT_QUBE_ETH_IRQ);
+		} else {
+			/* Setup the first Tulip on the RAQ */
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+                                              COBALT_RAQ_ETH0_IRQ);
+		}
+		dev->resource[0].start = 0x100000;
+		dev->resource[0].end = 0x10007f;
+		if (dev->resource[1].start < 0x10000000) {
+			dev->resource[1].start = 0xe9ffec00;
+			dev->resource[1].end = 0xe9ffefff;
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0xe9ffec00);
+		}
+	/* Fixup the second tulip located at device PCICONF_ETH1 */
+	} else if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH1) {
+
+		/* Enable the second Tulip device. */
+		pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+		pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MASTER);
+		pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+		/* Give it it's IRQ. */
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+                                      COBALT_RAQ_ETH1_IRQ);
+
+		/* And finally, a usable I/O space allocation, right after what
+		 * the first Tulip uses.
+		 */
+		dev->resource[0].start = 0x101000;
+		dev->resource[0].end = 0x10107f;
+	}
+}
+
+static void qube_raq_scsi_fixup(struct pci_dev *dev)
+{
+	unsigned short pci_cmd;
+	extern int cobalt_is_raq;
+
+        /*
+         * Tell the SCSI device that we expect an interrupt at
+         * IRQ 7 and not the default 0.
+         */
+        pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_SCSI_IRQ);
+
+	if (cobalt_is_raq) {
+
+		/* Enable the device. */
+		pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+
+		pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
+			| PCI_COMMAND_INVALIDATE);
+		pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+		/* Give it it's RAQ IRQ. */
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 4);
+
+		/* And finally, a usable I/O space allocation, right after what
+		 * the second Tulip uses.
+		 */
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x10102001);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x00002000);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0x00100000);
+	}
+}
+
+static void qube_raq_galileo_fixup(struct pci_dev *dev)
+{
+	unsigned short galileo_id;
+
+	/* Fix PCI latency-timer and cache-line-size values in Galileo
+	 * host bridge.
+	 */
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+
+	/* On all machines prior to Q2, we had the STOP line disconnected
+	 * from Galileo to VIA on PCI.  The new Galileo does not function
+	 * correctly unless we have it connected.
+	 *
+	 * Therefore we must set the disconnect/retry cycle values to
+	 * something sensible when using the new Galileo.
+	 */
+	pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
+	galileo_id &= 0xff;     /* mask off class info */
+	if (galileo_id == 0x10) {
+		/* New Galileo, assumes PCI stop line to VIA is connected. */
+		*((volatile unsigned int *)0xb4000c04) = 0x00004020;
+	} else if (galileo_id == 0x1 || galileo_id == 0x2) {
+		signed int timeo;
+		/* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
+		timeo = *((volatile unsigned int *)0xb4000c04);
+		/* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
+		*((volatile unsigned int *)0xb4000c04) = 0x0000ffff;
+	}
+}
+
+static void
+qube_pcibios_fixup(struct pci_dev *dev)
+{
+	if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_PCISLOT) {
+		unsigned int tmp;
+
+		/* See if there is a device in the expansion slot, if so
+		 * discover its resources and fixup whatever we need to
+		 */
+		pci_read_config_dword(dev, PCI_VENDOR_ID, &tmp);
+		if(tmp != 0xffffffff && tmp != 0x00000000)
+			qube_expansion_slot_fixup(dev);
+	}
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, qube_raq_via_bmIDE_fixup },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, qube_raq_tulip_fixup },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_GALILEO, PCI_ANY_ID, qube_raq_galileo_fixup },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C860, qube_raq_scsi_fixup },
+	{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, qube_pcibios_fixup }
+};
+
+
+static __inline__ int pci_range_ck(struct pci_dev *dev) 
+{
+       if ((dev->bus->number == 0) 
+           && ((PCI_SLOT (dev->devfn) == 0) 
+               || ((PCI_SLOT (dev->devfn) > 6) 
+                   && (PCI_SLOT (dev->devfn) <= 12))))
+		return 0;  /* OK device number  */
+
+	return -1;  /* NOT ok device number */
+}
+
+#define PCI_CFG_DATA	((volatile unsigned long *)0xb4000cfc)
+#define PCI_CFG_CTRL	((volatile unsigned long *)0xb4000cf8)
+
+#define PCI_CFG_SET(dev,where) \
+       ((*PCI_CFG_CTRL) = (0x80000000 | (PCI_SLOT ((dev)->devfn) << 11) | \
+                           (PCI_FUNC ((dev)->devfn) << 8) | (where)))
+
+static int qube_pci_read_config_dword (struct pci_dev *dev,
+                                          int where,
+                                          u32 *val)
+{
+	if (where & 0x3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (pci_range_ck (dev)) {
+		*val = 0xFFFFFFFF;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	PCI_CFG_SET(dev, where);
+	*val = *PCI_CFG_DATA;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int qube_pci_read_config_word (struct pci_dev *dev,
+                                         int where,
+                                         u16 *val)
+{
+        if (where & 0x1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (pci_range_ck (dev)) {
+		*val = 0xffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	PCI_CFG_SET(dev, (where & ~0x3));
+	*val = *PCI_CFG_DATA >> ((where & 3) * 8);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int qube_pci_read_config_byte (struct pci_dev *dev,
+                                         int where,
+                                         u8 *val)
+{
+	if (pci_range_ck (dev)) {
+		*val = 0xff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	PCI_CFG_SET(dev, (where & ~0x3));
+	*val = *PCI_CFG_DATA >> ((where & 3) * 8);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int qube_pci_write_config_dword (struct pci_dev *dev,
+                                           int where,
+                                           u32 val)
+{
+	if(where & 0x3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (pci_range_ck (dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	PCI_CFG_SET(dev, where);
+	*PCI_CFG_DATA = val;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+qube_pci_write_config_word (struct pci_dev *dev,
+                                int where, 
+                               u16 val)
+{
+	unsigned long tmp;
+
+	if (where & 0x1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (pci_range_ck (dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	PCI_CFG_SET(dev, (where & ~0x3));
+	tmp = *PCI_CFG_DATA;
+	tmp &= ~(0xffff << ((where & 0x3) * 8));
+	tmp |=  (val << ((where & 0x3) * 8));
+	*PCI_CFG_DATA = tmp;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+qube_pci_write_config_byte (struct pci_dev *dev,
+                                int where, 
+                               u8 val)
+{
+	unsigned long tmp;
+
+	if (pci_range_ck (dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	PCI_CFG_SET(dev, (where & ~0x3));
+	tmp = *PCI_CFG_DATA;
+	tmp &= ~(0xff << ((where & 0x3) * 8));
+	tmp |=  (val << ((where & 0x3) * 8));
+	*PCI_CFG_DATA = tmp;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops qube_pci_ops = {
+	qube_pci_read_config_byte,
+	qube_pci_read_config_word,
+	qube_pci_read_config_dword,
+	qube_pci_write_config_byte,
+	qube_pci_write_config_word,
+	qube_pci_write_config_dword
+};
+
+void __init pcibios_init(void)
+{
+	printk("PCI: Probing PCI hardware\n");
+
+	ioport_resource.start = 0x00000000;
+	ioport_resource.end = 0x0fffffff;
+
+	iomem_resource.start = 0x01000000;
+	iomem_resource.end = 0xffffffff;
+
+	pci_scan_bus(0, &qube_pci_ops, NULL);
+}
+
+char *pcibios_setup(char *str)
+{
+	return str;
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	u16 cmd, status;
+	
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	pci_read_config_word(dev, PCI_STATUS, &status);
+	printk("PCI: Enabling device %s (%04x  %04x)\n", dev->slot_name, cmd, status);
+	/* We'll sort this out when we know it isn't enabled ;) */
+
+	return 0;
+}
+
+void pcibios_align_resource(void *data, struct resource *res,
+		unsigned long size)
+{
+
+	panic("Uhhoh called pcibios_align_resource\n");
+}
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root, 
+		struct resource *res, int resource)
+{
+
+	panic("Uhhoh called pcibios_update_resource\n");
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	/* We don't have sub-busses to fixup here */
+}
+
+unsigned int __init pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/cobalt/promcon.c linux/arch/mips/cobalt/promcon.c
--- linux.orig/arch/mips/cobalt/promcon.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/cobalt/promcon.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,91 @@
+/*
+ * PROM console for Cobalt Raq2
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/serial_reg.h>
+
+#include <asm/delay.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+
+static unsigned long port = 0xc800000;
+
+static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr)
+{
+	char lsr;
+
+	do {
+		lsr = inb(ioaddr + UART_LSR);
+	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+	outb(ch, ioaddr + UART_TX);
+}
+
+static __inline__ char ns16550_cons_get_char(unsigned long ioaddr)
+{
+	while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
+		udelay(1);
+	return inb(ioaddr + UART_RX);
+}
+
+void ns16550_console_write(struct console *co, const char *s, unsigned count)
+{
+	char lsr, ier;
+	unsigned i;
+
+	ier = inb(port + UART_IER);
+	outb(0x00, port + UART_IER);
+	for (i=0; i < count; i++, s++) {
+
+		if(*s == '\n')
+			ns16550_cons_put_char('\r', port);
+		ns16550_cons_put_char(*s, port);
+	}
+
+	do {
+		lsr = inb(port + UART_LSR);
+   	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+
+	outb(ier, port + UART_IER);
+}
+
+char getDebugChar(void)
+{
+	return ns16550_cons_get_char(port);
+}
+
+void putDebugChar(char kgdb_char)
+{
+	ns16550_cons_put_char(kgdb_char, port);
+}
+
+static kdev_t 
+ns16550_console_dev(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static struct console ns16550_console = {
+    name:	"prom",
+    setup:	NULL,
+    write:	ns16550_console_write,
+    device:	ns16550_console_dev,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
+};
+
+void __init ns16550_setup_console(void)
+{
+	register_console(&ns16550_console);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/cobalt/reset.c linux/arch/mips/cobalt/reset.c
--- linux.orig/arch/mips/cobalt/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/cobalt/reset.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,69 @@
+/*
+ * Cobalt Reset operations
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+
+void cobalt_machine_restart(char *command)
+{
+	*(volatile char *)0xbc000000 = 0x0f;
+
+	/*
+	 * Ouch, we're still alive ... This time we take the silver bullet ...
+	 * ... and find that we leave the hardware in a state in which the
+	 * kernel in the flush locks up somewhen during of after the PCI
+	 * detection stuff.
+	 */
+	set_cp0_status(ST0_BEV | ST0_ERL);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	__asm__ __volatile__(
+		"jr\t%0"
+		:
+		: "r" (0xbfc00000));
+}
+
+extern int led_state;
+#define kLED            0xBC000000
+#define LEDSet(x)       (*(volatile unsigned char *) kLED) = (( unsigned char)x)
+
+void cobalt_machine_halt(void)
+{
+	int mark;
+
+	/* Blink our cute? little LED (number 3)... */
+	while (1) {
+		led_state = led_state | ( 1 << 3 );
+		LEDSet(led_state);  
+		mark = jiffies;
+		while (jiffies<(mark+HZ));
+		led_state = led_state & ~( 1 << 3 );
+		LEDSet(led_state);
+		mark = jiffies;
+		while (jiffies<(mark+HZ));
+	} 
+}
+
+/*
+ * This triggers the luser mode device driver for the power switch ;-)
+ */
+void cobalt_machine_power_off(void)
+{
+	printk("You can switch the machine off now.\n");
+	cobalt_machine_halt();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/cobalt/setup.c linux/arch/mips/cobalt/setup.c
--- linux.orig/arch/mips/cobalt/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/cobalt/setup.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,127 @@
+/*
+ * Setup pointers to hardware dependent routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/mc146818rtc.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/cobalt/cobalt.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/traps.h>
+
+extern void cobalt_machine_restart(char *command);
+extern void cobalt_machine_halt(void);
+extern void cobalt_machine_power_off(void);
+
+extern struct rtc_ops std_rtc_ops;
+extern struct ide_ops std_ide_ops;
+
+
+char arcs_cmdline[CL_SIZE] = { "console=ttyS0,115200 root=/dev/hda1" };
+
+const char *get_system_type(void)
+{
+	return "MIPS Cobalt";
+}
+
+
+#define GALILEO_T0_VAL		0xb4000850
+#define GALILEO_TIMER_CTRL	0xb4000864
+#define GALILEO_CPU_MASK	0xb4000c1c
+
+#define GALILEO_ENTC0		0x01
+#define GALILEO_SELTC0		0x02
+
+static void __init cobalt_time_init(void)
+{
+	rtc_ops = &std_rtc_ops;
+}
+
+static void __init cobalt_timer_setup(struct irqaction *irq)
+{
+	/* Load timer value for 150 Hz */
+	volatile unsigned long *timer_reg = (volatile unsigned long *)GALILEO_T0_VAL;
+
+	*timer_reg = 500000;
+
+	/* Register our timer interrupt */
+	setup_irq(0, irq);
+
+	/* Enable timer ints */
+	*((volatile unsigned long *) GALILEO_TIMER_CTRL) = 
+			(unsigned long) (GALILEO_ENTC0 | GALILEO_SELTC0);
+	/* Unmask timer int */
+	*((volatile unsigned long *) GALILEO_CPU_MASK) = (unsigned long) 0x00000100; 
+}
+
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
+int cobalt_serial_present;
+int cobalt_serial_type;
+int cobalt_is_raq;
+
+void __init cobalt_setup(void)
+{
+
+	_machine_restart = cobalt_machine_restart;
+	_machine_halt = cobalt_machine_halt;
+	_machine_power_off = cobalt_machine_power_off;
+
+	board_time_init = cobalt_time_init;
+	board_timer_setup = cobalt_timer_setup;
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+        set_io_port_base(0xb0000000);
+
+	/* 
+	 * This is a prom style console. We just poke at the
+	 *  UART to make it talk.
+	 * Only use this console if you really screw up and can't
+	 *  get to the stage of setting up a real serial console.
+	 */
+	/*ns16550_setup_console();*/
+
+	/* We have to do this early, here, before the value could
+	 * possibly be overwritten by the bootup sequence.
+	 */
+	cobalt_serial_present = *((unsigned long *) 0xa020001c);
+	cobalt_serial_type    = *((unsigned long *) 0xa0200020);
+	cobalt_is_raq         = (cobalt_serial_present != 0x0
+				 && cobalt_serial_type == 0x1);
+}
+
+/* Prom init. We read our one and only communication with the
+    firmware. Grab the amount of installed memory */
+void __init prom_init(int argc)
+{
+	mips_machgroup = MACH_GROUP_COBALT;
+	
+	add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
+}
+
+void __init prom_free_prom_memory(void)
+{
+	/* Nothing to do! */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/cobalt/via.c linux/arch/mips/cobalt/via.c
--- linux.orig/arch/mips/cobalt/via.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/cobalt/via.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,99 @@
+/*
+ * VIA chipset irq handling
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <asm/cobalt/cobalt.h>
+#include <asm/ptrace.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+
+extern void do_IRQ(int irq, struct pt_regs * regs);
+
+/* Cached values of VIA PIC masks, we start with cascade enabled */
+static unsigned int cached_irq_mask = 0xfffb;
+
+#define __byte(x,y)	(((unsigned char *)&(y))[x])
+#define cached_21	(__byte(0,cached_irq_mask))
+#define cached_A1	(__byte(1,cached_irq_mask))
+
+
+void mask_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << irq;
+
+	cached_irq_mask |= mask;
+	if (irq & 8) {
+		VIA_PORT_WRITE(0xA1, cached_A1);
+	} else {
+		VIA_PORT_WRITE(0x21, cached_21);
+	}
+}
+
+void unmask_irq(unsigned int irq)
+{
+	unsigned int mask = ~(1 << irq);
+
+	cached_irq_mask &= mask;
+	if (irq & 8) {
+		VIA_PORT_WRITE(0xA1, cached_A1);
+	} else {
+		VIA_PORT_WRITE(0x21, cached_21);
+	}
+}
+
+asmlinkage void via_irq(struct pt_regs *regs)
+{
+	char mstat, sstat;
+  
+	/* Read Master Status */
+	VIA_PORT_WRITE(0x20, 0x0C);
+	mstat = VIA_PORT_READ(0x20);
+ 
+	if (mstat < 0) {
+		mstat &= 0x7f;
+		if (mstat != 2) {     	
+			do_IRQ(mstat, regs);
+			VIA_PORT_WRITE(0x20, mstat | 0x20);
+		} else {
+			sstat = VIA_PORT_READ(0xA0);
+
+			/* Slave interrupt */
+			VIA_PORT_WRITE(0xA0, 0x0C);
+			sstat = VIA_PORT_READ(0xA0);
+   
+			if (sstat < 0) {
+				do_IRQ((sstat + 8) & 0x7f, regs);
+				VIA_PORT_WRITE(0x20, 0x22);       
+				VIA_PORT_WRITE(0xA0, (sstat & 0x7f) | 0x20);
+			} else {
+				printk("Spurious slave interrupt...\n");
+			}
+		}
+	} else
+		printk("Spurious master interrupt...");
+}
+
+#define GALILEO_INTCAUSE	0xb4000c18
+#define GALILEO_T0EXP		0x00000100
+
+asmlinkage void galileo_irq(struct pt_regs *regs)
+{
+	unsigned long irq_src = *((unsigned long *) GALILEO_INTCAUSE); 
+
+	/* Check for timer irq ... */
+	if (irq_src & GALILEO_T0EXP) {
+		/* Clear the int line */
+		*((volatile unsigned long *) GALILEO_INTCAUSE) = 0;
+		do_IRQ(0, regs);
+	} else
+		printk("Spurious Galileo interrupt...\n");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/config.in linux/arch/mips/config.in
--- linux.orig/arch/mips/config.in	2001-10-15 20:41:34.000000000 +0000
+++ linux/arch/mips/config.in	2002-07-20 01:08:38.000000000 +0000
@@ -3,9 +3,9 @@
 # see Documentation/kbuild/config-language.txt.
 #
 define_bool CONFIG_MIPS y
-define_bool CONFIG_SMP n
+define_bool CONFIG_MIPS32 y
 
-mainmenu_name "Linux Kernel Configuration"
+mainmenu_name "Linux/MIPS Kernel Configuration"
 
 mainmenu_option next_comment
 comment 'Code maturity level options'
@@ -13,99 +13,181 @@
 endmenu
 
 mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
 comment 'Machine selection'
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61
-   bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032
-   bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS
-   bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION
-   bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074
-   bool 'Support for Galileo EV96100 Evaluation board' CONFIG_MIPS_EV96100
-   bool 'Support for Galileo EV64120 Evaluation board' CONFIG_MIPS_EV64120
-   if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
-		  bool 'Enable Second PCI (PCI1)' CONFIG_EVB_PCI1
-      choice 'Galileo Chip Clock' \
-        "75 CONFIG_SYSCLK_75\
-         83.3 CONFIG_SYSCLK_83\
-         100 CONFIG_SYSCLK_100" CONFIG_SYSCLK_83
-   fi
-   bool 'Support for MIPS Atlas board' CONFIG_MIPS_ATLAS
-   bool 'Support for MIPS Malta board' CONFIG_MIPS_MALTA
-   bool 'Support for Philips Nino (EXPERIMENTAL)' CONFIG_NINO
-   if [ "$CONFIG_NINO" = "y" ]; then
-      choice 'Nino Model Number' \
-        "Model-300/301/302/319 CONFIG_NINO_4MB \
-         Model-200/210/312/320/325/350/390 CONFIG_NINO_8MB \
-         Model-500/510 CONFIG_NINO_16MB" CONFIG_NINO_8MB
-   fi
+dep_bool 'Support for Acer PICA 1 chipset (EXPERIMENTAL)' CONFIG_ACER_PICA_61 $CONFIG_EXPERIMENTAL
+bool 'Support for Alchemy Semi PB1000 board' CONFIG_MIPS_PB1000
+if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
+   bool '  Support for PCI AUTO Config' CONFIG_PCI_AUTO
+fi
+bool 'Support for Alchemy Semi PB1500 board' CONFIG_MIPS_PB1500
+dep_bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_MIPS_COBALT $CONFIG_EXPERIMENTAL
+bool 'Support for DECstations' CONFIG_DECSTATION
+dep_bool 'Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV64120 $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
+   bool '  Enable Second PCI (PCI1)' CONFIG_EVB_PCI1
+   choice '  Galileo Chip Clock' \
+	"75	CONFIG_SYSCLK_75 \
+	 83.3	CONFIG_SYSCLK_83 \
+	 100	CONFIG_SYSCLK_100" 83.3
+fi
+dep_bool 'Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV96100 $CONFIG_EXPERIMENTAL
+bool 'Support for Globespan IVR board' CONFIG_MIPS_IVR
+bool 'Support for Hewlett Packard LaserJet board' CONFIG_HP_LASERJET
+bool 'Support for ITE 8172G board' CONFIG_MIPS_ITE8172
+if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
+   bool '  Support for older IT8172 (Rev C)' CONFIG_IT8172_REVC
 fi
-bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000
+dep_bool 'Support for MIPS Atlas board (EXPERIMENTAL)' CONFIG_MIPS_ATLAS $CONFIG_EXPERIMENTAL
+bool 'Support for MIPS Magnum 4000' CONFIG_MIPS_MAGNUM_4000
+dep_bool 'Support for MIPS Malta board (EXPERIMENTAL)' CONFIG_MIPS_MALTA $CONFIG_EXPERIMENTAL
 bool 'Support for Momentum Ocelot board' CONFIG_MOMENCO_OCELOT
+dep_bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 $CONFIG_EXPERIMENTAL
 bool 'Support for NEC DDB Vrc-5476' CONFIG_DDB5476
 bool 'Support for NEC DDB Vrc-5477' CONFIG_DDB5477
+bool 'Support for NEC Osprey board' CONFIG_NEC_OSPREY
 bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
-bool 'Support for SGI IP22' CONFIG_SGI_IP22
-bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
-bool 'Support for ITE 8172G board' CONFIG_MIPS_ITE8172
-   if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
-       bool '    Support for older IT8172 (Rev C)' CONFIG_IT8172_REVC
-       bool '    Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD
-       if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then
-	   define_bool CONFIG_IT8172_CIR y
-       else
-           bool '    Enable PS2 Keyboard Support ' CONFIG_PC_KEYB
-       fi
-       bool '    Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0
-       bool '    Enable Smart Card Reader 1 Support ' CONFIG_IT8172_SCR1
-   fi
-   bool 'Support for Globespan IVR board' CONFIG_MIPS_IVR
-   if [ "$CONFIG_MIPS_IVR" = "y" ]; then
-       bool '    Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD
-       if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then
-	   define_bool CONFIG_IT8172_CIR y
-       fi
-       bool '    Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0
+dep_bool 'Support for Philips Nino (EXPERIMENTAL)' CONFIG_NINO $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_NINO" = "y" ]; then
+   choice 'Nino Model Number' \
+	"Model-300/301/302/319			CONFIG_NINO_4MB \
+	 Model-200/210/312/320/325/350/390	CONFIG_NINO_8MB \
+	 Model-500/510				CONFIG_NINO_16MB" Model-200
+fi
+bool 'Support for SGI IP22 (Indy/Indigo2)' CONFIG_SGI_IP22
+dep_bool 'Support for SiByte SB1250 SOC (EXPERIMENTAL)' CONFIG_SIBYTE_SB1250 $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+   bool '  Support for SB1250 onchip PCI controller' CONFIG_PCI
+   bool '  Support for SB1250 profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF
+   bool '  Support for BCM1250 profiling using trace buffer' CONFIG_BCM1250_TBPROF
+   bool '  Remote debugging (kgdb over UART 1)' CONFIG_REMOTE_DEBUG
+   bool '  Support for SiByte SWARM board' CONFIG_SIBYTE_SWARM
+   if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
+      bool '    Running under simulation' CONFIG_SIMULATION
+      bool '    Configure for L3proc Demo' CONFIG_L3DEMO
+      int '    Maximum memory chunks' CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS 16
+      bool '    Multi-Processing support' CONFIG_SMP
    fi
-bool 'Support for Alchemy Semi PB1000 board' CONFIG_MIPS_PB1000
+fi
+bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
+bool 'Support for Toshiba JMR-TX3927 board' CONFIG_TOSHIBA_JMR3927
+
+dep_bool 'High Memory Support (EXPERIMENTAL)' CONFIG_HIGHMEM $CONFIG_EXPERIMENTAL
 
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
 
 #
-# Select some configuration options automatically for certain systems.
+# Select some configuration options automatically based on user selections.
 #
-unset CONFIG_ARC32
-unset CONFIG_BOARD_SCACHE
-unset CONFIG_COHERENT_IO
-unset CONFIG_HAVE_STD_PC_SERIAL_PORT
-unset CONFIG_I8259
-unset CONFIG_ISA
-unset CONFIG_PCI
-unset CONFIG_MIPS_JAZZ
-unset CONFIG_SWAP_IO_SPACE
-unset CONFIG_VIDEO_G364
-unset CONFIG_PC_KEYB
 
-define_bool CONFIG_MCA n
-define_bool CONFIG_SBUS n
-
-if [ "$CONFIG_MIPS_EV96100" = "y" ]; then
+if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_I8259 y
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_MIPS_JAZZ y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_ROTTEN_IRQ y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 y
+   define_bool CONFIG_NEW_IRQ y
    define_bool CONFIG_PCI y
-   define_bool CONFIG_MIPS_GT96100 y
-   define_bool CONFIG_SWAP_IO_SPACE y
    define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_int  MAX_HWIFS 1
+fi
+if [ "$CONFIG_MIPS_PB1500" = "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_PCI y
    define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+fi
+if [ "$CONFIG_ALGOR_P4032" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MIPS_COBALT" = "y" ]; then
+   define_bool CONFIG_COBALT_LCD y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+fi
+if [ "$CONFIG_DECSTATION" = "y" ]; then
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NONCOHERENT_IO y
 fi
 if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
    define_bool CONFIG_PCI y
    define_bool CONFIG_ISA n
    define_bool CONFIG_MIPS_GT64120 y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_OLD_TIME_C y
 fi
-
-if [ "$CONFIG_ALGOR_P4032" = "y" ]; then
+if [ "$CONFIG_MIPS_EV96100" = "y" ]; then
    define_bool CONFIG_PCI y
-   define_bool CONFIG_OLD_TIME_C y
+   define_bool CONFIG_MIPS_GT96100 y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_SWAP_IO_SPACE y
+fi
+if [ "$CONFIG_MIPS_IVR" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_IT8172_CIR y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+fi
+if [ "$CONFIG_HP_LASERJET" = "y" ]; then
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI y
+   #not yet define_bool CONFIG_PCI_AUTO y
+fi
+if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_IT8712 y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_IT8172_CIR y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+fi
+if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_SWAP_IO_SPACE y
 fi
 if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
      "$CONFIG_OLIVETTI_M700" = "y" ]; then
@@ -113,118 +195,120 @@
    define_bool CONFIG_I8259 y
    define_bool CONFIG_ISA y
    define_bool CONFIG_FB y
-   define_bool CONFIG_FB_G364 y	
-   define_bool CONFIG_MIPS_JAZZ y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_I8259 y
-   define_bool CONFIG_ISA y
+   define_bool CONFIG_FB_G364 y
    define_bool CONFIG_MIPS_JAZZ y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_ROTTEN_IRQ y
    define_bool CONFIG_OLD_TIME_C y
 fi
-if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_SWAP_IO_SPACE y
-fi
 if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
    define_bool CONFIG_I8259 y
    define_bool CONFIG_PCI y
    define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
    define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_PC_KEYB y
 fi
 if [ "$CONFIG_MOMENCO_OCELOT" = "y" ]; then
    define_bool CONFIG_PCI y
    define_bool CONFIG_SYSCLK_100 y
    define_bool CONFIG_SWAP_IO_SPACE y
    define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_BOARD_SCACHE y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_SGI y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_I8259 y
-   define_bool CONFIG_ISA y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_ROTTEN_IRQ y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_OLD_TIME_C y
 fi
 if [ "$CONFIG_DDB5074" = "y" ]; then
+   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
    define_bool CONFIG_I8259 y
    define_bool CONFIG_ISA y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_ROTTEN_IRQ y
-   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
    define_bool CONFIG_OLD_TIME_C y
 fi
 if [ "$CONFIG_DDB5476"  = "y" ]; then
    define_bool CONFIG_ISA y
    define_bool CONFIG_PCI y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_ROTTEN_IRQ y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_I8259 y
    define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
 fi
 if [ "$CONFIG_DDB5477" = "y" ]; then
-   define_bool CONFIG_CPU_LITTLE_ENDIAN y
    define_bool CONFIG_PCI y
    define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NEW_IRQ y
-fi
-if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_IT8712 y
-   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_DUMMY_KEYB y
 fi
-if [ "$CONFIG_MIPS_IVR" = "y" ]; then
-   define_bool CONFIG_PCI y
-fi
-if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
-   define_bool CONFIG_MIPS_AU1000 y
+if [ "$CONFIG_NEC_OSPREY" = "y" ]; then
+   define_bool CONFIG_VR4181 y
+   define_bool CONFIG_SERIAL y
+   define_bool CONFIG_SERIAL_MANY_PORTS y
    define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_DUMMY_KEYB y
+   define_bool CONFIG_SCSI n
 fi
 if [ "$CONFIG_NINO" = "y" ]; then
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
 fi
-
-if [ "$CONFIG_ISA" != "y" ]; then
-   define_bool CONFIG_ISA n
-   define_bool CONFIG_EISA n
-else
-   define_bool CONFIG_EISA y
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_SGI y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
 fi
-
-if [ "$CONFIG_PCI" != "y" ]; then
-   define_bool CONFIG_PCI n
+if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_DUMMY_KEYB y
+   define_bool CONFIG_SWAP_IO_SPACE y
 fi
-
-if [ "$CONFIG_I8259" != "y" ]; then
-   define_bool CONFIG_I8259 n
+if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_I8259 y
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_OLD_TIME_C y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_PCI y
+fi
+if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
+   define_bool CONFIG_TOSHIBA_BOARDS y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_PC_KEYB y
 fi
-endmenu
 
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
+if [ "$CONFIG_MIPS_AU1000" != "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 n
 fi
 endmenu
 
@@ -232,29 +316,63 @@
 comment 'CPU selection'
 
 choice 'CPU type' \
-	"R3000 CONFIG_CPU_R3000	\
-	 R6000 CONFIG_CPU_R6000	\
-	 R41xx CONFIG_CPU_VR41XX \
-	 R4300 CONFIG_CPU_R4300	\
-	 R4x00 CONFIG_CPU_R4X00	\
-	 R5000 CONFIG_CPU_R5000	\
-	 R5432 CONFIG_CPU_R5432 \
-	 RM7000 CONFIG_CPU_RM7000 \
-	 R52xx CONFIG_CPU_NEVADA \
-	 R10000 CONFIG_CPU_R10000 \
-	 SB1    CONFIG_CPU_SB1    \
-	 MIPS32 CONFIG_CPU_MIPS32 \
-	 MIPS64 CONFIG_CPU_MIPS64" R4x00
+	"R3000	CONFIG_CPU_R3000 \
+	 R39XX	CONFIG_CPU_TX39XX \
+	 R6000	CONFIG_CPU_R6000 \
+	 R41xx	CONFIG_CPU_VR41XX \
+	 R4300	CONFIG_CPU_R4300 \
+	 R4x00	CONFIG_CPU_R4X00 \
+	 R49XX	CONFIG_CPU_TX49XX \
+	 R5000	CONFIG_CPU_R5000 \
+	 R5432	CONFIG_CPU_R5432 \
+	 RM7000	CONFIG_CPU_RM7000 \
+	 R52xx	CONFIG_CPU_NEVADA \
+	 R10000	CONFIG_CPU_R10000 \
+	 SB1	CONFIG_CPU_SB1 \
+	 MIPS32	CONFIG_CPU_MIPS32 \
+	 MIPS64	CONFIG_CPU_MIPS64" R4x00
+
+if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_PREFETCH y
+   bool '  Support for Virtual Tagged I-cache' CONFIG_VTAG_ICACHE
+fi
+
+if [ "$CONFIG_CPU_MIPS64" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_PREFETCH y
+   bool '  Support for Virtual Tagged I-cache' CONFIG_VTAG_ICACHE
+fi
+
+if [ "$CONFIG_CPU_RM7000" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_PREFETCH y
+fi
+
+if [ "$CONFIG_CPU_SB1" = "y" ]; then
+   bool '  Workarounds for pass 1 sb1 bugs' CONFIG_SB1_PASS_1_WORKAROUNDS
+   bool '  Support for SB1 Cache Error handler' CONFIG_SB1_CACHE_ERROR
+   define_bool CONFIG_VTAG_ICACHE y
+   define_bool CONFIG_CPU_HAS_PREFETCH y
+fi
+
+if [ "$CONFIG_CPU_R4X00"  = "y" -o \
+     "$CONFIG_CPU_R5000" = "y" -o \
+     "$CONFIG_CPU_RM7000" = "y" -o \
+     "$CONFIG_CPU_R10000" = "y" -o \
+     "$CONFIG_CPU_SB1" = "y" -o \
+     "$CONFIG_CPU_MIPS32" = "y" -o \
+     "$CONFIG_CPU_MIPS64" = "y" ]; then
+   bool '  Support for 64-bit physical address space' CONFIG_64BIT_PHYS_ADDR
+fi
 
 bool 'Override CPU Options' CONFIG_CPU_ADVANCED
-
 if [ "$CONFIG_CPU_ADVANCED" = "y" ]; then
    bool '  ll/sc Instructions available' CONFIG_CPU_HAS_LLSC
    bool '  lld/scd Instructions available' CONFIG_CPU_HAS_LLDSCD
    bool '  Writeback Buffer available' CONFIG_CPU_HAS_WB
 else
-   if [ "$CONFIG_CPU_R3000" = "y" -o "$CONFIG_CPU_VR41XX" = "y" ]; then
-      if [ "CONFIG_DECSTATION" = "y" ]; then
+   if [ "$CONFIG_CPU_R3000" = "y" -o \
+        "$CONFIG_CPU_VR41XX" = "y" -o    \
+        "$CONFIG_CPU_TX39XX" = "y" ]; then
+      if [ "$CONFIG_DECSTATION" = "y" ]; then
 	 define_bool CONFIG_CPU_HAS_LLSC n
 	 define_bool CONFIG_CPU_HAS_LLDSCD n
 	 define_bool CONFIG_CPU_HAS_WB y
@@ -281,64 +399,82 @@
 comment 'General setup'
 if [ "$CONFIG_DECSTATION" = "y" -o \
      "$CONFIG_DDB5074" = "y" -o    \
-     "$CONFIG_DDB5476" = "y" -o    \
-     "$CONFIG_NINO" = "y" ]; then
+     "$CONFIG_NINO" = "y" -o       \
+     "$CONFIG_MIPS_COBALT" = "y" ]; then
    define_bool CONFIG_CPU_LITTLE_ENDIAN y
 else
    bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
 fi
 
-if [ "$CONFIG_PROC_FS" = "y" ]; then
-   define_bool CONFIG_KCORE_ELF y
+if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
+       bool 'DS1742 BRAM/RTC support' CONFIG_RTC_DS1742
 fi
-define_bool CONFIG_ELF_KERNEL y
 
 if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
-   bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX 
-   bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD 
+   bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX
+   bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD
 fi
 
 if [ "$CONFIG_ARC32" = "y" ]; then
    bool 'ARC console support' CONFIG_ARC_CONSOLE
 fi
 
-define_bool CONFIG_BINFMT_AOUT n
-define_bool CONFIG_BINFMT_ELF y
-tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-
 bool 'Networking support' CONFIG_NET
 
+if [ "$CONFIG_PCI" != "y" ]; then
+   define_bool CONFIG_PCI n
+fi
+
 source drivers/pci/Config.in
 
+if [ "$CONFIG_ISA" != "y" ]; then
+   define_bool CONFIG_ISA n
+   define_bool CONFIG_EISA n
+else
+   define_bool CONFIG_EISA y
+fi
+
+dep_bool 'TURBOchannel support' CONFIG_TC $CONFIG_DECSTATION
+#dep_bool 'Access.Bus support' CONFIG_ACCESSBUS $CONFIG_TC
+
+define_bool CONFIG_MCA n
+define_bool CONFIG_SBUS n
+
 bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
 
 if [ "$CONFIG_HOTPLUG" = "y" ] ; then
    source drivers/pcmcia/Config.in
+   source drivers/hotplug/Config.in
 else
    define_bool CONFIG_PCMCIA n
+   define_bool CONFIG_HOTPLUG_PCI n
 fi
 
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+define_bool CONFIG_KCORE_ELF y
+define_bool CONFIG_KCORE_AOUT n
+define_bool CONFIG_BINFMT_AOUT n
+define_bool CONFIG_BINFMT_ELF y
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
-if [ "$CONFIG_DECSTATION" = "y" ]; then
-    bool 'TURBOchannel support' CONFIG_TC
-#    if [ "$CONFIG_TC" = "y" ]; then
-#	bool ' Access.Bus support' CONFIG_ACCESSBUS
-#    fi
-fi
+dep_bool 'Power Management support (EXPERIMENTAL)' CONFIG_PM $CONFIG_EXPERIMENTAL $CONFIG_MIPS_AU1000
 endmenu
 
-if [ "$CONFIG_ISA" = "y" ]; then
-   source drivers/pnp/Config.in
-fi
-
 source drivers/mtd/Config.in
 
 source drivers/parport/Config.in
 
+source drivers/pnp/Config.in
+
 source drivers/block/Config.in
+if [ "$CONFIG_BLK_DEV_INITRD" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'MIPS initrd options'
+   bool '  Embed root filesystem ramdisk into the kernel' CONFIG_EMBEDDED_RAMDISK
+   endmenu
+fi
 
 source drivers/md/Config.in
 
@@ -348,14 +484,13 @@
 
 source drivers/telephony/Config.in
 
-if [ "$CONFIG_SGI_IP22" != "y" -a \
-     "$CONFIG_DECSTATION" != "y" ]; then
+if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" ]; then
 
    mainmenu_option next_comment
    comment 'ATA/IDE/MFM/RLL support'
-    
+
    tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
-    
+
    if [ "$CONFIG_IDE" != "n" ]; then
       source drivers/ide/Config.in
    else
@@ -375,8 +510,7 @@
 fi
 endmenu
 
-if [ "$CONFIG_DECSTATION" != "y" -a \
-     "$CONFIG_SGI_IP22" != "y" ]; then
+if [ "$CONFIG_PCI" = "y" ]; then
    source drivers/message/i2o/Config.in
 fi
 
@@ -388,7 +522,7 @@
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
       if [ "$CONFIG_ATM" = "y" ]; then
-         source drivers/atm/Config.in
+	 source drivers/atm/Config.in
       fi
    fi
    endmenu
@@ -398,77 +532,56 @@
 
 source net/irda/Config.in
 
-mainmenu_option next_comment
-comment 'ISDN subsystem'
 if [ "$CONFIG_NET" != "n" ]; then
+   mainmenu_option next_comment
+   comment 'ISDN subsystem'
+
    tristate 'ISDN support' CONFIG_ISDN
    if [ "$CONFIG_ISDN" != "n" ]; then
       source drivers/isdn/Config.in
    fi
+   endmenu
 fi
-endmenu
 
-mainmenu_option next_comment
-comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+if [ "$CONFIG_ISA" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
-bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
-if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-   source drivers/cdrom/Config.in
+   bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+   if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+      source drivers/cdrom/Config.in
+   fi
+   endmenu
 fi
-endmenu
 
 source drivers/char/Config.in
 
+#source drivers/misc/Config.in
+
 source drivers/media/Config.in
 
 if [ "$CONFIG_DECSTATION" = "y" ]; then
    mainmenu_option next_comment
    comment 'DECStation Character devices'
 
-   bool 'Virtual terminal' CONFIG_VT
-   if [ "$CONFIG_VT" = "y" ]; then
-      bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
-   fi
    tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
-   if [ "$CONFIG_SERIAL" = "y" ]; then
-      bool 'DZ11 Serial Support' CONFIG_DZ
-      if [ "$CONFIG_TC" = "y" ]; then
-	 bool 'Z85C30 Serial Support' CONFIG_ZS
-      fi
-   bool '   Support for console on serial port' CONFIG_SERIAL_CONSOLE
-   fi
-   bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
-   if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
-      int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
-   fi
-#   if [ "$CONFIG_ACCESSBUS" = "y" ]; then
-#      bool 'MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE
-#   fi
+   dep_bool '  DZ11 Serial Support' CONFIG_DZ $CONFIG_SERIAL
+   dep_bool '  Z85C30 Serial Support' CONFIG_ZS $CONFIG_SERIAL $CONFIG_TC
+   dep_bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE $CONFIG_SERIAL
+#   dep_bool 'MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS
    bool 'Enhanced Real Time Clock Support' CONFIG_RTC
-
    endmenu
 fi
 
 if [ "$CONFIG_SGI_IP22" = "y" ]; then
    mainmenu_option next_comment
    comment 'SGI Character devices'
-   bool 'Virtual terminal' CONFIG_VT
    if [ "$CONFIG_VT" = "y" ]; then
-      bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
       tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
-      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
-	 define_bool CONFIG_DUMMY_CONSOLE y
-      else
+      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then
 	 define_bool CONFIG_FONT_8x16 y
       fi
-   fi
-   bool 'PS/2 mouse support' CONFIG_PSMOUSE
-   if [ "$CONFIG_PSMOUSE" != "n" ]; then
-      define_bool CONFIG_MOUSE y
-   fi
-   bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
-   if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
-      int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
+      define_bool CONFIG_DUMMY_CONSOLE y
    fi
    endmenu
 fi
@@ -486,22 +599,23 @@
    endmenu
 fi
 
-if [ "$CONFIG_DECSTATION" != "y" ]; then
-   mainmenu_option next_comment
-   comment 'Sound'
+mainmenu_option next_comment
+comment 'Sound'
 
-   tristate 'Sound card support' CONFIG_SOUND
-   if [ "$CONFIG_SOUND" != "n" ]; then
-      source drivers/sound/Config.in
-   fi
-   endmenu
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
 fi
+endmenu
 
 if [ "$CONFIG_SGI_IP22" = "y" ]; then
    source drivers/sgi/Config.in
 fi
 
 source drivers/usb/Config.in
+
+source net/bluetooth/Config.in
+
 source drivers/input/Config.in
 
 mainmenu_option next_comment
@@ -512,9 +626,7 @@
   bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
   dep_bool 'Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_DEBUG
 fi
-if [ "$CONFIG_SERIAL" = "y" ]; then
-  bool 'Low-level debugging' CONFIG_LL_DEBUG
-fi
+bool 'Enable run-time debugging' CONFIG_DEBUG
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 if [ "$CONFIG_SMP" != "y" ]; then
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5074/prom.c linux/arch/mips/ddb5074/prom.c
--- linux.orig/arch/mips/ddb5074/prom.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ddb5074/prom.c	2002-07-20 01:08:25.000000000 +0000
@@ -13,7 +13,12 @@
 #include <asm/bootinfo.h>
 
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	return "NEC DDB Vrc-5074";
+}
 
 void __init prom_init(const char *s)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5074/setup.c linux/arch/mips/ddb5074/setup.c
--- linux.orig/arch/mips/ddb5074/setup.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ddb5074/setup.c	2002-07-20 01:08:28.000000000 +0000
@@ -96,7 +96,7 @@
 	extern int panic_timeout;
 
 	irq_setup = ddb_irq_setup;
-	mips_io_port_base = NILE4_PCI_IO_BASE;
+	set_io_port_base(NILE4_PCI_IO_BASE);
 	isa_slot_offset = NILE4_PCI_MEM_BASE;
 	request_region(0x00, 0x20, "dma1");
 	request_region(0x40, 0x20, "timer");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/Makefile linux/arch/mips/ddb5476/Makefile
--- linux.orig/arch/mips/ddb5476/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ddb5476/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,23 +0,0 @@
-#
-# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines
-# under Linux.
-#
-# 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).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-#
-
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-O_TARGET = ddb5476.a
-
-obj-y				+= setup.o irq.o time.o prom.o pci.o \
-				   int-handler.o nile4.o
-obj-$(CONFIG_REMOTE_DEBUG)	+= dbg_io.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/dbg_io.c linux/arch/mips/ddb5476/dbg_io.c
--- linux.orig/arch/mips/ddb5476/dbg_io.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ddb5476/dbg_io.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,125 +0,0 @@
-
-#include <linux/config.h>
-
-#if (defined(CONFIG_DDB5476) && defined(CONFIG_REMOTE_DEBUG))
-
-/* --- CONFIG --- */
-
-/* we need uint32 uint8 */
-/* #include "types.h" */
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-
-/* --- END OF CONFIG --- */
-
-#define         UART16550_BAUD_2400             2400
-#define         UART16550_BAUD_4800             4800
-#define         UART16550_BAUD_9600             9600
-#define         UART16550_BAUD_19200            19200
-#define         UART16550_BAUD_38400            38400
-#define         UART16550_BAUD_57600            57600
-#define         UART16550_BAUD_115200           115200
-
-#define         UART16550_PARITY_NONE           0
-#define         UART16550_PARITY_ODD            0x08
-#define         UART16550_PARITY_EVEN           0x18
-#define         UART16550_PARITY_MARK           0x28
-#define         UART16550_PARITY_SPACE          0x38
-
-#define         UART16550_DATA_5BIT             0x0
-#define         UART16550_DATA_6BIT             0x1
-#define         UART16550_DATA_7BIT             0x2
-#define         UART16550_DATA_8BIT             0x3
-
-#define         UART16550_STOP_1BIT             0x0
-#define         UART16550_STOP_2BIT             0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-
-/* [jsun] we use the second serial port for kdb */
-#define         BASE                    0xa60002f8
-#define         MAX_BAUD                115200
-
-/* === END OF CONFIG === */
-
-/* register offset */
-#define         OFS_RCV_BUFFER          0
-#define         OFS_TRANS_HOLD          0
-#define         OFS_SEND_BUFFER         0
-#define         OFS_INTR_ENABLE         1
-#define         OFS_INTR_ID             2
-#define         OFS_DATA_FORMAT         3
-#define         OFS_LINE_CONTROL        3
-#define         OFS_MODEM_CONTROL       4
-#define         OFS_RS232_OUTPUT        4
-#define         OFS_LINE_STATUS         5
-#define         OFS_MODEM_STATUS        6
-#define         OFS_RS232_INPUT         6
-#define         OFS_SCRATCH_PAD         7
-
-#define         OFS_DIVISOR_LSB         0
-#define         OFS_DIVISOR_MSB         1
-
-
-/* memory-mapped read/write of the port */
-#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
-#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
-
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
-{
-	/* disable interrupts */
-	UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
-	/* set up buad rate */
-	{
-		uint32 divisor;
-
-		/* set DIAB bit */
-		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
-		/* set divisor */
-		divisor = MAX_BAUD / baud;
-		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
-		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
-		/* clear DIAB bit */
-		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
-	}
-
-	/* set data format */
-	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized = 0;
-
-uint8 getDebugChar(void)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_38400,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-	}
-
-	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
-	return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-
-int putDebugChar(uint8 byte)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_9600,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-	}
-
-	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
-	UART16550_WRITE(OFS_SEND_BUFFER, byte);
-	return 1;
-}
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/int-handler.S linux/arch/mips/ddb5476/int-handler.S
--- linux.orig/arch/mips/ddb5476/int-handler.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5476/int-handler.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,136 +0,0 @@
-/*
- *  arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
- *
- *  Based on arch/mips/sgi/kernel/indyIRQ.S
- *
- *  Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * A lot of complication here is taken away because:
- *
- * 1) We handle one interrupt and return, sitting in a loop and moving across
- *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
- *    common case is one pending IRQ so optimize in that direction.
- *
- * 2) We need not check against bits in the status register IRQ mask, that
- *    would make this routine slow as hell.
- *
- * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
- *    between like BSD spl() brain-damage.
- *
- * Furthermore, the IRQs on the INDY look basically (barring software IRQs
- * which we don't use at all) like:
- *
- *	MIPS IRQ	Source
- *      --------        ------
- *             0	Software (ignored)
- *             1        Software (ignored)
- *             2        Local IRQ level zero
- *             3        Local IRQ level one
- *             4        8254 Timer zero
- *             5        8254 Timer one
- *             6        Bus Error
- *             7        R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ----     R4k Timer
- *                  Local IRQ zero
- *                  Local IRQ one
- *                  Bus Error
- *                  8254 Timer zero
- * Lowest  ----     8254 Timer one
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
-	.text
-	.set	noreorder
-	.set	noat
-	.align	5
-	NESTED(ddbIRQ, PT_SIZE, sp)
-	SAVE_ALL
-	CLI
-	.set	at
-	mfc0	s1, CP0_CAUSE		# get irq mask
-
-#if 1
-	mfc0	t2,CP0_STATUS		# get enabled interrupts
-	and	s0, s1, t2		# isolate allowed ones
-#endif
-	/* First we check for r4k counter/timer IRQ. */
-	andi	a0, s0, CAUSEF_IP7	# cpu timer */
-	bnez	a0, cpu_timer_irq
-	andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
-
-	/* Wheee, local level zero interrupt. */
-	jal	ddb_local0_irqdispatch
-	 move	a0, sp			# delay slot
-
-	j	ret_from_irq
-	 nop				# delay slot
-
-1:
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
-
-	/* Wheee, local level one interrupt. */
-	move	a0, sp
-	jal	ddb_local1_irqdispatch
-	 nop
-
-	j	ret_from_irq
-	 nop
-
-1:
-	beq	a0, zero, 1f
-	 nop
-
-	/* Wheee, an asynchronous bus error... */
-	move	a0, sp
-	jal	ddb_buserror_irq
-	 nop
-
-	j	ret_from_irq
-	 nop
-
-1:
-	/* Here by mistake?  This is possible, what can happen
-	 * is that by the time we take the exception the IRQ
-	 * pin goes low, so just leave if this is the case.
-	 */
-	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
-	beq	a0, zero, 1f
-
-	/* Must be one of the 8254 timers... */
-	move	a0, sp
-	jal	ddb_8254timer_irq
-	 nop
-1:
-	/* phamtom interrupt */
-	move 	a0, s1
-	jal	ddb_phantom_irq
-	nop
-	j	ret_from_irq
-	nop
-
-cpu_timer_irq:
-	li	a0, 0
-	move	a1, sp
-	jal	do_IRQ 
-	/* jal	ll_timer_interrupt */
-	nop
-	j	ret_from_irq
-	nop
-	END(ddbIRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/irq.c linux/arch/mips/ddb5476/irq.c
--- linux.orig/arch/mips/ddb5476/irq.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ddb5476/irq.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,251 +0,0 @@
-/*
- *  arch/mips/ddb5476/irq.c -- NEC DDB Vrc-5476 interrupt routines
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/ptrace.h>
-#include <asm/nile4.h>
-
-extern void __init i8259_init(void);
-extern void i8259_disable_irq(unsigned int irq_nr);
-extern void i8259_enable_irq(unsigned int irq_nr);
-
-extern asmlinkage void ddbIRQ(void);
-extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs);
-extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
-
-
-void no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
-}
-
-
-#define M1543_PNP_CONFIG	0x03f0	/* PnP Config Port */
-#define M1543_PNP_INDEX		0x03f0	/* PnP Index Port */
-#define M1543_PNP_DATA		0x03f1	/* PnP Data Port */
-
-#define M1543_PNP_ALT_CONFIG	0x0370	/* Alternative PnP Config Port */
-#define M1543_PNP_ALT_INDEX	0x0370	/* Alternative PnP Index Port */
-#define M1543_PNP_ALT_DATA	0x0371	/* Alternative PnP Data Port */
-
-#define M1543_INT1_MASTER_CTRL	0x0020	/* INT_1 (master) Control Register */
-#define M1543_INT1_MASTER_MASK	0x0021	/* INT_1 (master) Mask Register */
-
-#define M1543_INT1_SLAVE_CTRL	0x00a0	/* INT_1 (slave) Control Register */
-#define M1543_INT1_SLAVE_MASK	0x00a1	/* INT_1 (slave) Mask Register */
-
-#define M1543_INT1_MASTER_ELCR	0x04d0	/* INT_1 (master) Edge/Level Control */
-#define M1543_INT1_SLAVE_ELCR	0x04d1	/* INT_1 (slave) Edge/Level Control */
-
-static struct {
-	struct resource m1543_config;
-	struct resource pic_elcr;
-} m1543_ioport = {
-	{ "M1543 config", M1543_PNP_CONFIG, M1543_PNP_CONFIG + 1,
-	  IORESOURCE_BUSY},
-	{ "pic ELCR", M1543_INT1_MASTER_ELCR, M1543_INT1_MASTER_ELCR + 1,
-	  IORESOURCE_BUSY}
-};
-
-static void m1543_irq_setup(void)
-{
-	/*
-	 *  The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13.  Not all
-	 *  the possible IO sources in the M1543 are in use by us.  We will
-	 *  use the following mapping:
-	 *
-	 *      IRQ1  - keyboard (default set by M1543)
-	 *      IRQ3  - reserved for UART B (default set by M1543) (note that
-	 *              the schematics for the DDB Vrc-5476 board seem to 
-	 *              indicate that IRQ3 is connected to the DS1386 
-	 *              watchdog timer interrupt output so we might have 
-	 *              a conflict)
-	 *      IRQ4  - reserved for UART A (default set by M1543)
-	 *      IRQ5  - parallel (default set by M1543)
-	 *      IRQ8  - DS1386 time of day (RTC) interrupt
-	 *      IRQ9  - USB (hardwired in ddb_setup)
-	 *      IRQ10 - PMU (hardwired in ddb_setup)
-	 *      IRQ12 - mouse
-	 *      IRQ14,15 - IDE controller (need to be confirmed, jsun)
-	 */
-
-	/*
-	 *  Assing mouse interrupt to IRQ12 
-	 */
-
-	/* Enter configuration mode */
-	outb(0x51, M1543_PNP_CONFIG);
-	outb(0x23, M1543_PNP_CONFIG);
-
-	/* Select logical device 7 (Keyboard) */
-	outb(0x07, M1543_PNP_INDEX);
-	outb(0x07, M1543_PNP_DATA);
-
-	/* Select IRQ12 */
-	outb(0x72, M1543_PNP_INDEX);
-	outb(0x0c, M1543_PNP_DATA);
-
-	/* Leave configration mode */
-	outb(0xbb, M1543_PNP_CONFIG);
-
-
-	/* Initialize the 8259 PIC in the M1543 */
-	i8259_init();
-
-	/* Enable the interrupt cascade from M1543 */
-	nile4_enable_irq(NILE4_INT_INTC);
-
-	/* request io ports */
-	if (request_resource(&ioport_resource, &m1543_ioport.m1543_config)
-	    || request_resource(&ioport_resource, &m1543_ioport.pic_elcr)) {
-		printk("m1543_irq_setup : requesting io ports failed.\n");
-		for (;;);
-	}
-}
-
-static void nile4_irq_setup(void)
-{
-	int i;
-
-	/* Map all interrupts to CPU int #0 */
-	nile4_map_irq_all(0);
-
-	/* PCI INTA#-E# must be level triggered */
-	nile4_set_pci_irq_level_or_edge(0, 1);
-	nile4_set_pci_irq_level_or_edge(1, 1);
-	nile4_set_pci_irq_level_or_edge(2, 1);
-	nile4_set_pci_irq_level_or_edge(3, 1);
-
-	/* PCI INTA#, B#, D# must be active low, INTC# must be active high */
-	nile4_set_pci_irq_polarity(0, 0);
-	nile4_set_pci_irq_polarity(1, 0);
-	nile4_set_pci_irq_polarity(2, 1);
-	nile4_set_pci_irq_polarity(3, 0);
-
-	for (i = 0; i < 16; i++)
-		nile4_clear_irq(i);
-
-	/* Enable CPU int #0 */
-	nile4_enable_irq_output(0);
-
-	/* memory resource acquire in ddb_setup */
-}
-
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL };
-
-
-void disable_irq(unsigned int irq_nr)
-{
-	if (is_i8259_irq(irq_nr))
-		i8259_disable_irq(irq_nr);
-	else
-		nile4_disable_irq(irq_to_nile4(irq_nr));
-}
-
-void enable_irq(unsigned int irq_nr)
-{
-	if (is_i8259_irq(irq_nr))
-		i8259_enable_irq(irq_nr);
-	else
-		nile4_enable_irq(irq_to_nile4(irq_nr));
-}
-
-int table[16] = { 0, };
-
-void ddb_local0_irqdispatch(struct pt_regs *regs)
-{
-	u32 mask;
-	int nile4_irq;
-#if 0
-	volatile static int nesting = 0;
-	if (nesting++ == 0)
-		ddb5476_led_d3(1);
-	ddb5476_led_hex(nesting < 16 ? nesting : 15);
-#endif
-
-	mask = nile4_get_irq_stat(0);
-	nile4_clear_irq_mask(mask);
-
-	/* Handle the timer interrupt first */
-	if (mask & (1 << NILE4_INT_GPT)) {
-		nile4_disable_irq(NILE4_INT_GPT);
-		do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs);
-		nile4_enable_irq(NILE4_INT_GPT);
-		mask &= ~(1 << NILE4_INT_GPT);
-	}
-	for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1)
-		if (mask & 1) {
-			nile4_disable_irq(nile4_irq);
-			if (nile4_irq == NILE4_INT_INTC) {
-				int i8259_irq = nile4_i8259_iack();
-				i8259_do_irq(i8259_irq, regs);
-			} else {
-				do_IRQ(nile4_to_irq(nile4_irq), regs);
-			}
-			nile4_enable_irq(nile4_irq);
-		}
-#if 0
-	if (--nesting == 0)
-		ddb5476_led_d3(0);
-	ddb5476_led_hex(nesting < 16 ? nesting : 15);
-#endif
-}
-
-void ddb_local1_irqdispatch(void)
-{
-	printk("ddb_local1_irqdispatch called\n");
-}
-
-void ddb_buserror_irq(void)
-{
-	printk("ddb_buserror_irq called\n");
-}
-
-void ddb_8254timer_irq(void)
-{
-	printk("ddb_8254timer_irq called\n");
-}
-
-void ddb_phantom_irq(unsigned long cause)
-{
-	printk("phantom interrupts detected : \n");
-	printk("\tcause \t\t0x%08x\n", cause);
-	printk("\tcause reg\t0x%08x\n",
-	       read_32bit_cp0_register(CP0_CAUSE));
-	printk("\tstatus reg\t0x%08x\n",
-	       read_32bit_cp0_register(CP0_STATUS));
-}
-
-void __init ddb_irq_setup(void)
-{
-#ifdef CONFIG_REMOTE_DEBUG
-	printk("Wait for gdb client connection ...\n");
-	set_debug_traps();
-	breakpoint();		/* you may move this line to whereever you want :-) */
-#endif
-	i8259_setup_irq(2, &irq2);
-
-	nile4_irq_setup();
-	m1543_irq_setup();
-
-	/* we pin #0 - #4 (no internal timer) */
-	change_cp0_status(ST0_IM,
-	                  IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
-
-	set_except_vector(0, ddbIRQ);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/nile4.c linux/arch/mips/ddb5476/nile4.c
--- linux.orig/arch/mips/ddb5476/nile4.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ddb5476/nile4.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,293 +0,0 @@
-/*
- *  arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include <asm/nile4.h>
-
-
-/*
- *  Physical Device Address Registers
- *
- *  Note: 32 bit addressing only!
- */
-void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width,
-		    int on_memory_bus, int visible)
-{
-	u32 maskbits;
-	u32 widthbits;
-
-	if (pdar > NILE4_BOOTCS || (pdar & 7)) {
-		printk("nile4_set_pdar: invalid pdar %d\n", pdar);
-		return;
-	}
-	if (pdar == NILE4_INTCS && size != 0x00200000) {
-		printk("nile4_set_pdar: INTCS size must be 2 MB\n");
-		return;
-	}
-	switch (size) {
-#if 0				/* We don't support 4 GB yet */
-	case 0x100000000:	/* 4 GB */
-		maskbits = 4;
-		break;
-#endif
-	case 0x80000000:	/* 2 GB */
-		maskbits = 5;
-		break;
-	case 0x40000000:	/* 1 GB */
-		maskbits = 6;
-		break;
-	case 0x20000000:	/* 512 MB */
-		maskbits = 7;
-		break;
-	case 0x10000000:	/* 256 MB */
-		maskbits = 8;
-		break;
-	case 0x08000000:	/* 128 MB */
-		maskbits = 9;
-		break;
-	case 0x04000000:	/* 64 MB */
-		maskbits = 10;
-		break;
-	case 0x02000000:	/* 32 MB */
-		maskbits = 11;
-		break;
-	case 0x01000000:	/* 16 MB */
-		maskbits = 12;
-		break;
-	case 0x00800000:	/* 8 MB */
-		maskbits = 13;
-		break;
-	case 0x00400000:	/* 4 MB */
-		maskbits = 14;
-		break;
-	case 0x00200000:	/* 2 MB */
-		maskbits = 15;
-		break;
-	case 0:		/* OFF */
-		maskbits = 0;
-		break;
-	default:
-		printk("nile4_set_pdar: unsupported size %p\n",
-		       (void *) size);
-		return;
-	}
-	switch (width) {
-	case 8:
-		widthbits = 0;
-		break;
-	case 16:
-		widthbits = 1;
-		break;
-	case 32:
-		widthbits = 2;
-		break;
-	case 64:
-		widthbits = 3;
-		break;
-	default:
-		printk("nile4_set_pdar: unsupported width %d\n", width);
-		return;
-	}
-	nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) |
-		    (visible ? 0x20 : 0) | (widthbits << 6) |
-		    (phys & 0xffe00000));
-	nile4_out32(pdar + 4, 0);
-	/*
-	 * When programming a PDAR, the register should be read immediately
-	 * after writing it. This ensures that address decoders are properly
-	 * configured.
-	 */
-	nile4_in32(pdar);
-	nile4_in32(pdar + 4);
-}
-
-
-/*
- *  PCI Master Registers
- *
- *  Note: 32 bit addressing only!
- */
-void nile4_set_pmr(u32 pmr, u32 type, u32 addr)
-{
-	if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) {
-		printk("nile4_set_pmr: invalid pmr %d\n", pmr);
-		return;
-	}
-	switch (type) {
-	case NILE4_PCICMD_IACK:	/* PCI Interrupt Acknowledge */
-	case NILE4_PCICMD_IO:	/* PCI I/O Space */
-	case NILE4_PCICMD_MEM:	/* PCI Memory Space */
-	case NILE4_PCICMD_CFG:	/* PCI Configuration Space */
-		break;
-	default:
-		printk("nile4_set_pmr: invalid type %d\n", type);
-		return;
-	}
-	nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000));
-	nile4_out32(pmr + 4, 0);
-}
-
-
-/*
- *  Interrupt Programming
- */
-void nile4_map_irq(int nile4_irq, int cpu_irq)
-{
-	u32 offset, t;
-
-	offset = NILE4_INTCTRL;
-	if (nile4_irq >= 8) {
-		offset += 4;
-		nile4_irq -= 8;
-	}
-	t = nile4_in32(offset);
-	t &= ~(7 << (nile4_irq * 4));
-	t |= cpu_irq << (nile4_irq * 4);
-	nile4_out32(offset, t);
-}
-
-void nile4_map_irq_all(int cpu_irq)
-{
-	u32 all, t;
-
-	all = cpu_irq;
-	all |= all << 4;
-	all |= all << 8;
-	all |= all << 16;
-	t = nile4_in32(NILE4_INTCTRL);
-	t &= 0x88888888;
-	t |= all;
-	nile4_out32(NILE4_INTCTRL, t);
-	t = nile4_in32(NILE4_INTCTRL + 4);
-	t &= 0x88888888;
-	t |= all;
-	nile4_out32(NILE4_INTCTRL + 4, t);
-}
-
-void nile4_enable_irq(int nile4_irq)
-{
-	u32 offset, t;
-
-	offset = NILE4_INTCTRL;
-	if (nile4_irq >= 8) {
-		offset += 4;
-		nile4_irq -= 8;
-	}
-	t = nile4_in32(offset);
-	t |= 8 << (nile4_irq * 4);
-	nile4_out32(offset, t);
-}
-
-void nile4_disable_irq(int nile4_irq)
-{
-	u32 offset, t;
-
-	offset = NILE4_INTCTRL;
-	if (nile4_irq >= 8) {
-		offset += 4;
-		nile4_irq -= 8;
-	}
-	t = nile4_in32(offset);
-	t &= ~(8 << (nile4_irq * 4));
-	nile4_out32(offset, t);
-}
-
-void nile4_disable_irq_all(void)
-{
-	nile4_out32(NILE4_INTCTRL, 0);
-	nile4_out32(NILE4_INTCTRL + 4, 0);
-}
-
-u16 nile4_get_irq_stat(int cpu_irq)
-{
-	return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2);
-}
-
-void nile4_enable_irq_output(int cpu_irq)
-{
-	u32 t;
-
-	t = nile4_in32(NILE4_INTSTAT1 + 4);
-	t |= 1 << (16 + cpu_irq);
-	nile4_out32(NILE4_INTSTAT1, t);
-}
-
-void nile4_disable_irq_output(int cpu_irq)
-{
-	u32 t;
-
-	t = nile4_in32(NILE4_INTSTAT1 + 4);
-	t &= ~(1 << (16 + cpu_irq));
-	nile4_out32(NILE4_INTSTAT1, t);
-}
-
-void nile4_set_pci_irq_polarity(int pci_irq, int high)
-{
-	u32 t;
-
-	t = nile4_in32(NILE4_INTPPES);
-	if (high)
-		t &= ~(1 << (pci_irq * 2));
-	else
-		t |= 1 << (pci_irq * 2);
-	nile4_out32(NILE4_INTPPES, t);
-}
-
-void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
-{
-	u32 t;
-
-	t = nile4_in32(NILE4_INTPPES);
-	if (level)
-		t |= 2 << (pci_irq * 2);
-	else
-		t &= ~(2 << (pci_irq * 2));
-	nile4_out32(NILE4_INTPPES, t);
-}
-
-void nile4_clear_irq(int nile4_irq)
-{
-	nile4_out32(NILE4_INTCLR, 1 << nile4_irq);
-}
-
-void nile4_clear_irq_mask(u32 mask)
-{
-	nile4_out32(NILE4_INTCLR, mask);
-}
-
-u8 nile4_i8259_iack(void)
-{
-	u8 irq;
-
-	/* Set window 0 for interrupt acknowledge */
-	nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0);
-	irq = *(volatile u8 *) NILE4_PCI_IACK_BASE;
-	/* Set window 0 for PCI I/O space */
-	nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
-	return irq;
-}
-
-#if 0
-void nile4_dump_irq_status(void)
-{
-	printk("CPUSTAT = %p:%p\n", (void *) nile4_in32(NILE4_CPUSTAT + 4),
-	       (void *) nile4_in32(NILE4_CPUSTAT));
-	printk("INTCTRL = %p:%p\n", (void *) nile4_in32(NILE4_INTCTRL + 4),
-	       (void *) nile4_in32(NILE4_INTCTRL));
-	printk("INTSTAT0 = %p:%p\n",
-	       (void *) nile4_in32(NILE4_INTSTAT0 + 4),
-	       (void *) nile4_in32(NILE4_INTSTAT0));
-	printk("INTSTAT1 = %p:%p\n",
-	       (void *) nile4_in32(NILE4_INTSTAT1 + 4),
-	       (void *) nile4_in32(NILE4_INTSTAT1));
-	printk("INTCLR = %p:%p\n", (void *) nile4_in32(NILE4_INTCLR + 4),
-	       (void *) nile4_in32(NILE4_INTCLR));
-	printk("INTPPES = %p:%p\n", (void *) nile4_in32(NILE4_INTPPES + 4),
-	       (void *) nile4_in32(NILE4_INTPPES));
-}
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/pci.c linux/arch/mips/ddb5476/pci.c
--- linux.orig/arch/mips/ddb5476/pci.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5476/pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,499 +0,0 @@
-/*
- *  arch/mips/ddb5476/pci.c -- NEC DDB Vrc-5074 PCI access routines
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Albert Dorofeev <albert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-
-#include <asm-mips/nile4.h>
-
-static u32 nile4_pre_pci_access0(int slot_num)
-{
-	u32 pci_addr = 0;
-	u32 virt_addr = NILE4_PCI_CFG_BASE;
-
-	/* work around the bug for Vrc5476 */
-	if (slot_num == 13)
-		return NILE4_BASE + NILE4_PCI_BASE;
-
-	/* Set window 1 address 08000000 - 32 bit - 128 MB (PCI config space) */
-	nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x08000000, 32, 0,
-		       0);
-
-	// [jsun] we start scanning from addr:10, 
-	// with 128M we can go up to addr:26 (slot 16)
-	if (slot_num <= 16) {
-		virt_addr += 0x00000400 << slot_num;
-	} else {
-		/* for high slot, we have to set higher PCI base addr */
-		pci_addr = 0x00000400 << slot_num;
-	}
-	nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr);
-	return virt_addr;
-}
-
-static void nile4_post_pci_access0(void)
-{
-	/*
-	 * Set window 1 back to address 08000000 - 32 bit - 128 MB
-	 * (PCI IO space)
-	 */
-	nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE),
-		       0x08000000, 32, 1, 1);
-	// nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
-	nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000);
-}
-
-
-static int nile4_pci_read_config_dword(struct pci_dev *dev,
-				       int where, u32 * val)
-{
-	int slot_num, func_num;
-	u32 base;
-	u32 addr;
-
-	/*
-	 *  Do we need to generate type 1 configure transaction?
-	 */
-	if (dev->bus->number) {
-		/* FIXME - not working yet */
-		return PCIBIOS_FUNC_NOT_SUPPORTED;
-
-		/*
-		 * the largest type 1 configuration addr is 16M, < 256M
-		 * config space
-		 */
-		slot_num = 0;
-		addr =
-		    (dev->bus->number << 16) | (dev->devfn <
-						8) | where | 1;
-	} else {
-		slot_num = PCI_SLOT(dev->devfn);
-		func_num = PCI_FUNC(dev->devfn);
-		addr = (func_num << 8) + where;
-	}
-
-	base = nile4_pre_pci_access0(slot_num);
-	*val = *(volatile u32 *) (base + addr);
-	nile4_post_pci_access0();
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int nile4_pci_write_config_dword(struct pci_dev *dev, int where,
-					u32 val)
-{
-	int slot_num, func_num;
-	u32 base;
-	u32 addr;
-
-	/*
-	 *  Do we need to generate type 1 configure transaction?
-	 */
-	if (dev->bus->number) {
-		/* FIXME - not working yet */
-		return PCIBIOS_FUNC_NOT_SUPPORTED;
-
-		/* the largest type 1 configuration addr is 16M, < 256M config space */
-		slot_num = 0;
-		addr =
-		    (dev->bus->number << 16) | (dev->devfn <
-						8) | where | 1;
-	} else {
-		slot_num = PCI_SLOT(dev->devfn);
-		func_num = PCI_FUNC(dev->devfn);
-		addr = (func_num << 8) + where;
-	}
-
-	base = nile4_pre_pci_access0(slot_num);
-	*(volatile u32 *) (base + addr) = val;
-	nile4_post_pci_access0();
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int nile4_pci_read_config_word(struct pci_dev *dev, int where,
-				      u16 * val)
-{
-	int status;
-	u32 result;
-
-	status = nile4_pci_read_config_dword(dev, where & ~3, &result);
-	if (status != PCIBIOS_SUCCESSFUL)
-		return status;
-	if (where & 2)
-		result >>= 16;
-	*val = result & 0xffff;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int nile4_pci_read_config_byte(struct pci_dev *dev, int where,
-				      u8 * val)
-{
-	int status;
-	u32 result;
-
-	status = nile4_pci_read_config_dword(dev, where & ~3, &result);
-	if (status != PCIBIOS_SUCCESSFUL)
-		return status;
-	if (where & 1)
-		result >>= 8;
-	if (where & 2)
-		result >>= 16;
-	*val = result & 0xff;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int nile4_pci_write_config_word(struct pci_dev *dev, int where,
-				       u16 val)
-{
-	int status, shift = 0;
-	u32 result;
-
-	status = nile4_pci_read_config_dword(dev, where & ~3, &result);
-	if (status != PCIBIOS_SUCCESSFUL)
-		return status;
-	if (where & 2)
-		shift += 16;
-	result &= ~(0xffff << shift);
-	result |= val << shift;
-	return nile4_pci_write_config_dword(dev, where & ~3, result);
-}
-
-static int nile4_pci_write_config_byte(struct pci_dev *dev, int where,
-				       u8 val)
-{
-	int status, shift = 0;
-	u32 result;
-
-	status = nile4_pci_read_config_dword(dev, where & ~3, &result);
-	if (status != PCIBIOS_SUCCESSFUL)
-		return status;
-	if (where & 2)
-		shift += 16;
-	if (where & 1)
-		shift += 8;
-	result &= ~(0xff << shift);
-	result |= val << shift;
-	return nile4_pci_write_config_dword(dev, where & ~3, result);
-}
-
-struct pci_ops nile4_pci_ops = {
-	nile4_pci_read_config_byte,
-	nile4_pci_read_config_word,
-	nile4_pci_read_config_dword,
-	nile4_pci_write_config_byte,
-	nile4_pci_write_config_word,
-	nile4_pci_write_config_dword
-};
-
-struct {
-	struct resource ram;
-	struct resource flash;
-	struct resource isa_io;
-	struct resource pci_io;
-	struct resource isa_mem;
-	struct resource pci_mem;
-	struct resource nile4;
-	struct resource boot;
-} ddb5476_resources = {
-	// { "RAM", 0x00000000, 0x03ffffff, IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64 },
-	{
-	"RAM", 0x00000000, 0x03ffffff, IORESOURCE_MEM}, {
-	"Flash ROM", 0x04000000, 0x043fffff}, {
-	"Nile4 ISA I/O", 0x06000000, 0x060fffff}, {
-	"Nile4 PCI I/O", 0x06100000, 0x07ffffff}, {
-	"Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM}, {
-	"Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM},
-	    // { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64 },
-	{
-	"Nile4 ctrl", 0x1fa00000, 0x1fbfffff, IORESOURCE_MEM}, {
-	"Boot ROM", 0x1fc00000, 0x1fffffff}
-};
-
-struct resource M5229_resources[5] = {
-	{"M5229 BAR0", 0x1f0, 0x1f3, IORESOURCE_IO},
-	{"M5229 BAR1", 0x3f4, 0x3f7, IORESOURCE_IO},
-	{"M5229 BAR2", 0x170, 0x173, IORESOURCE_IO},
-	{"M5229 BAR3", 0x374, 0x377, IORESOURCE_IO},
-	{"M5229 BAR4", 0xf000, 0xf00f, IORESOURCE_IO}
-};
-
-static void __init ddb5476_pci_fixup(void)
-{
-	struct pci_dev *dev;
-
-	pci_for_each_dev(dev) {
-		if (dev->vendor == PCI_VENDOR_ID_NEC &&
-		    dev->device == PCI_DEVICE_ID_NEC_VRC5476) {
-			/*
-			 * The first 64-bit PCI base register should point to
-			 * the Nile4 control registers. Unfortunately this
-			 * isn't the case, so we fix it ourselves. This allows
-			 * the serial driver to find the UART.
-			 */
-			dev->resource[0] = ddb5476_resources.nile4;
-			request_resource(&iomem_resource,
-					 &dev->resource[0]);
-			/*
-			 * The second 64-bit PCI base register points to the
-			 * first memory bank. Unfortunately the address is
-			 * wrong, so we fix it (again).
-			 */
-
-			/* [jsun] We cannot request the resource anymore,
-			 * because kernel/setup.c has already reserved "System 
-			 * RAM" resource at the same spot.  
-			 * The fundamental problem here is that PCI host 
-			 * controller should not put system RAM mapping in BAR
-			 * and make subject to PCI resource assignement.
-			 * Current fix is a total hack.  We set parent to 1 so
-                         * so that PCI resource assignement code is fooled to 
-                         * think the resource is assigned, and will not attempt
-                         * to mess with it.
-			 */
-			dev->resource[2] = ddb5476_resources.ram;
-			if (request_resource(&iomem_resource,
-			                     &dev->resource[2]) ) {
-				dev->resource[2].parent = 0x1;
-                        }
-
-		} else if (dev->vendor == PCI_VENDOR_ID_AL
-			   && dev->device == PCI_DEVICE_ID_AL_M7101) {
-			/*
-			 * It's nice to have the LEDs on the GPIO pins
-			 * available for debugging
-			 */
-			extern struct pci_dev *pci_pmu;
-			u8 t8;
-
-			pci_pmu = dev;	/* for LEDs D2 and D3 */
-			/* Program the lines for LEDs D2 and D3 to output */
-			nile4_pci_read_config_byte(dev, 0x7d, &t8);
-			t8 |= 0xc0;
-			nile4_pci_write_config_byte(dev, 0x7d, t8);
-			/* Turn LEDs D2 and D3 off */
-			nile4_pci_read_config_byte(dev, 0x7e, &t8);
-			t8 |= 0xc0;
-			nile4_pci_write_config_byte(dev, 0x7e, t8);
-		} else if (dev->vendor == PCI_VENDOR_ID_AL &&
-			   dev->device == 0x5229) {
-			int i;
-			for (i = 0; i < 5; i++) {
-				dev->resource[i] = M5229_resources[i];
-				request_resource(&ioport_resource,
-						 &dev->resource[i]);
-			}
-		}
-	}
-}
-
-static void __init pcibios_fixup_irqs(void)
-{
-	struct pci_dev *dev;
-	int slot_num;
-
-	pci_for_each_dev(dev) {
-		slot_num = PCI_SLOT(dev->devfn);
-		switch (slot_num) {
-		case 3:	/* re-programmed to USB */
-			dev->irq = 9;	/* hard-coded; see irq.c */
-			break;
-		case 4:	/* re-programmed to PMU */
-			dev->irq = 10;	/* hard-coded; see irq.c */
-			break;
-		case 6:	/* on-board pci-pci bridge */
-			dev->irq = 0xff;
-			break;
-		case 7:	/* on-board ether */
-			dev->irq = nile4_to_irq(NILE4_INT_INTB);
-			break;
-		case 8:	/* ISA-PCI bridge  */
-			dev->irq = nile4_to_irq(NILE4_INT_INTC);
-			break;
-		case 9:	/* ext slot #3 */
-			dev->irq = nile4_to_irq(NILE4_INT_INTD);
-			break;
-		case 10:	/* ext slot #4 */
-			dev->irq = nile4_to_irq(NILE4_INT_INTA);
-			break;
-		case 13:	/* Vrc5476 */
-			dev->irq = 0xff;
-			break;
-		case 14:	/* HD controller, M5229 */
-			dev->irq = 14;
-			break;
-		default:
-			printk
-			    ("JSUN : in pcibios_fixup_irqs - unkown slot %d\n",
-			     slot_num);
-			panic
-			    ("JSUN : in pcibios_fixup_irqs - unkown slot.\n");
-		}
-	}
-}
-
-void __init pcibios_init(void)
-{
-	printk("PCI: Emulate bios initialization \n");
-	/* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
-	*(long *) (NILE4_BASE + NILE4_BAR0) = 0x8;
-
-	printk("PCI: Probing PCI hardware\n");
-	ioport_resource.end = 0x1ffffff;	/*  32 MB */
-	iomem_resource.end = 0x1fffffff;	/* 512 MB */
-
-	/* `ram' and `nile4' are requested through the Nile4 pci_dev */
-	request_resource(&iomem_resource, &ddb5476_resources.flash);
-	request_resource(&iomem_resource, &ddb5476_resources.isa_io);
-	request_resource(&iomem_resource, &ddb5476_resources.pci_io);
-	request_resource(&iomem_resource, &ddb5476_resources.isa_mem);
-	request_resource(&iomem_resource, &ddb5476_resources.pci_mem);
-	request_resource(&iomem_resource, &ddb5476_resources.boot);
-
-	pci_scan_bus(0, &nile4_pci_ops, NULL);
-	ddb5476_pci_fixup();
-	pci_assign_unassigned_resources();
-	pcibios_fixup_irqs();
-}
-
-void __init pcibios_fixup_bus(struct pci_bus *bus)
-{
-	/* [jsun] we don't know how to fix sub-buses yet */
-	if (bus->number == 0) {
-		bus->resource[1] = &ddb5476_resources.pci_mem;
-	}
-}
-
-char *pcibios_setup(char *str)
-{
-	return str;
-}
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus,
-				      struct pbus_set_ranges_data *ranges)
-{
-	/*
-	 * our caller figure out range by going through the dev structures.  
-	 * I guess this is the place to fix things up if the bus is using a 
-	 * different view of the addressing space.
-	 */
-
-#if 0	/*  original DDB5074 code */
-	   if (bus->number == 0) {
-	   ranges->io_start -= bus->resource[0]->start;
-	   ranges->io_end -= bus->resource[0]->start;
-	   ranges->mem_start -= bus->resource[1]->start;
-	   ranges->mem_end -= bus->resource[1]->start;
-	   }
-#endif
-}
-
-int pcibios_enable_resources(struct pci_dev *dev)
-{
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	/*
-	 *  Don't touch the Nile 4
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_NEC &&
-	    dev->device == PCI_DEVICE_ID_NEC_VRC5476) return 0;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for (idx = 0; idx < 6; idx++) {
-		r = &dev->resource[idx];
-		if (!r->start && r->end) {
-			printk(KERN_ERR "PCI: Device %s not available because "
-			       "of resource collisions\n", dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (cmd != old_cmd) {
-		printk("PCI: Enabling device %s (%04x -> %04x)\n",
-		       dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-}
-
-int pcibios_enable_device(struct pci_dev *dev)
-{
-	return pcibios_enable_resources(dev);
-}
-
-void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			     struct resource *res, int resource)
-{
-	u32 new, check;
-	int reg;
-
-	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
-	if (resource < 6) {
-		reg = PCI_BASE_ADDRESS_0 + 4 * resource;
-	} else if (resource == PCI_ROM_RESOURCE) {
-		res->flags |= PCI_ROM_ADDRESS_ENABLE;
-		reg = dev->rom_base_reg;
-	} else {
-		/*
-		 * Somebody might have asked allocation of a non-standard
-		 * resource
-		 */
-		return;
-	}
-
-	pci_write_config_dword(dev, reg, new);
-	pci_read_config_dword(dev, reg, &check);
-	if ((new ^ check) &
-	    ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
-	     PCI_BASE_ADDRESS_MEM_MASK)) {
-		printk(KERN_ERR "PCI: Error while updating region "
-		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
-		       new, check);
-	}
-}
-
-void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
-{
-	struct pci_dev *dev = data;
-
-	if (res->flags & IORESOURCE_IO) {
-		unsigned long start = res->start;
-
-		/* We need to avoid collisions with `mirrored' VGA ports
-		   and other strange ISA hardware, so we always want the
-		   addresses kilobyte aligned.  */
-		if (size > 0x100) {
-			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
-			       " (%ld bytes)\n", dev->slot_name,
-			       dev->resource - res, size);
-		}
-
-		start = (start + 1024 - 1) & ~(1024 - 1);
-		res->start = start;
-	}
-}
-
-unsigned __init int pcibios_assign_all_busses(void)
-{
-	return 1;
-}
-
-struct pci_fixup pcibios_fixups[] = { {0} };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/prom.c linux/arch/mips/ddb5476/prom.c
--- linux.orig/arch/mips/ddb5476/prom.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ddb5476/prom.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,43 +0,0 @@
-/*
- *  arch/mips/ddb5476/prom.c -- NEC DDB Vrc-5476 PROM routines
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- *
- *   	Jun Sun - modified for DDB5476.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-
-
-char arcs_cmdline[COMMAND_LINE_SIZE];
-
-/* [jsun@junsun.net] PMON passes arguments in C main() style */
-void __init prom_init(int argc, const char **arg)
-{
-	int i;
-
-	/* arg[0] is "g", the rest is boot parameters */
-	arcs_cmdline[0] = '\0';
-	for (i = 1; i < argc; i++) {
-		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
-		    >= sizeof(arcs_cmdline))
-			break;
-		strcat(arcs_cmdline, arg[i]);
-		strcat(arcs_cmdline, " ");
-	}
-
-	mips_machgroup = MACH_GROUP_NEC_DDB;
-	mips_machtype = MACH_NEC_DDB5476;
-	/* 64 MB non-upgradable */
-	add_memory_region(0, 64 << 20, BOOT_MEM_RAM);
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/setup.c linux/arch/mips/ddb5476/setup.c
--- linux.orig/arch/mips/ddb5476/setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5476/setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,393 +0,0 @@
-/*
- *  arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kbd_ll.h>
-#include <linux/kernel.h>
-#include <linux/kdev_t.h>
-#include <linux/types.h>
-#include <linux/console.h>
-#include <linux/sched.h>
-#include <linux/mc146818rtc.h>
-#include <linux/pc_keyb.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-#include <asm/addrspace.h>
-#include <asm/bcache.h>
-#include <asm/keyboard.h>
-#include <asm/irq.h>
-#include <asm/reboot.h>
-#include <asm/gdb-stub.h>
-#include <asm/nile4.h>
-#include <asm/time.h>
-
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void rs_kgdb_hook(int);
-extern void breakpoint(void);
-#endif
-
-#if defined(CONFIG_SERIAL_CONSOLE)
-extern void console_setup(char *);
-#endif
-
-extern struct ide_ops std_ide_ops;
-extern struct rtc_ops ddb_rtc_ops;
-extern struct kbd_ops std_kbd_ops;
-
-static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
-
-static void ddb_machine_restart(char *command)
-{
-	u32 t;
-
-	/* PCI cold reset */
-	t = nile4_in32(NILE4_PCICTRL + 4);
-	t |= 0x40000000;
-	nile4_out32(NILE4_PCICTRL + 4, t);
-	/* CPU cold reset */
-	t = nile4_in32(NILE4_CPUSTAT);
-	t |= 1;
-	nile4_out32(NILE4_CPUSTAT, t);
-	/* Call the PROM */
-	back_to_prom();
-}
-
-static void ddb_machine_halt(void)
-{
-	printk("DDB Vrc-5476 halted.\n");
-	while (1);
-}
-
-static void ddb_machine_power_off(void)
-{
-	printk("DDB Vrc-5476 halted. Please turn off the power.\n");
-	while (1);
-}
-
-extern void ddb_irq_setup(void);
-
-static void __init ddb_time_init(struct irqaction *irq)
-{
-	printk("ddb_time_init invoked.\n");
-	mips_counter_frequency = 83000000;
-}
-
-static void __init ddb_timer_setup(struct irqaction *irq)
-{
-	unsigned int count;
-
-	/* we are using the cpu counter for timer interrupts */
-	i8259_setup_irq(0, irq);
-	set_cp0_status(IE_IRQ5);
-
-	/* to generate the first timer interrupt */
-	count = read_32bit_cp0_register(CP0_COUNT);
-	write_32bit_cp0_register(CP0_COMPARE, count + 1000);
-
-#if 0		/* the old way to do timer interrupt */
-	/* set the clock to 100 Hz */
-	nile4_out32(NILE4_T2CTRL, 830000);
-	/* enable the General-Purpose Timer */
-	nile4_out32(NILE4_T2CTRL + 4, 0x00000001);
-	/* reset timer */
-	nile4_out32(NILE4_T2CNTR, 0);
-	/* enable interrupt */
-	nile4_enable_irq(NILE4_INT_GPT);
-	i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
-#endif
-}
-
-static struct {
-	struct resource dma1;
-	struct resource pic1;
-	struct resource timer;
-	struct resource rtc;
-	struct resource dma_page_reg;
-	struct resource pic2;
-	struct resource dma2;
-} ddb5476_ioport = {
-	{
-	"dma1", 0x00, 0x1f, IORESOURCE_BUSY}, {
-	"pic1", 0x20, 0x3f, IORESOURCE_BUSY}, {
-	"timer", 0x40, 0x5f, IORESOURCE_BUSY}, {
-	"rtc", 0x70, 0x7f, IORESOURCE_BUSY}, {
-	"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, {
-	"pic2", 0xa0, 0xbf, IORESOURCE_BUSY}, {
-	"dma2", 0xc0, 0xdf, IORESOURCE_BUSY}
-};
-
-static struct {
-	struct resource nile4;
-} ddb5476_iomem = {
-	{ "Nile 4", NILE4_BASE, NILE4_BASE + NILE4_SIZE - 1, IORESOURCE_BUSY}
-};
-
-void __init ddb_setup(void)
-{
-	extern int panic_timeout;
-
-	irq_setup = ddb_irq_setup;
-	mips_io_port_base = NILE4_PCI_IO_BASE;
-	isa_slot_offset = NILE4_PCI_MEM_BASE;
-
-	board_time_init = ddb_time_init;
-	board_timer_setup = ddb_timer_setup;
-
-	_machine_restart = ddb_machine_restart;
-	_machine_halt = ddb_machine_halt;
-	_machine_power_off = ddb_machine_power_off;
-
-	/* request io port/mem resources  */
-	if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) ||
-	    request_resource(&ioport_resource, &ddb5476_ioport.pic1) ||
-	    request_resource(&ioport_resource, &ddb5476_ioport.timer) ||
-	    request_resource(&ioport_resource, &ddb5476_ioport.rtc) ||
-	    request_resource(&ioport_resource,
-			     &ddb5476_ioport.dma_page_reg)
-	    || request_resource(&ioport_resource, &ddb5476_ioport.pic2)
-	    || request_resource(&ioport_resource, &ddb5476_ioport.dma2)
-	    || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) {
-		printk
-		    ("ddb_setup - requesting oo port resources failed.\n");
-		for (;;);
-	}
-#ifdef CONFIG_BLK_DEV_IDE
-	ide_ops = &std_ide_ops;
-#endif
-	rtc_ops = &ddb_rtc_ops;
-
-#ifdef CONFIG_PC_KEYB
-	kbd_ops = &std_kbd_ops;
-#endif
-
-	/* Reboot on panic */
-	panic_timeout = 180;
-
-	/* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
-	/* *(long*)0xbfa00218 = 0x8; */
-
-#ifdef CONFIG_FB
-	conswitchp = &dummy_con;
-#endif
-
-
-	/* board initialization stuff - non-fundamental, but need to be set
-	 * before kernel runs */
-
-	/* setup I/O space */
-	nile4_set_pdar(NILE4_PCIW0,
-		       PHYSADDR(NILE4_PCI_IO_BASE), 0x02000000, 32, 0, 0);
-	nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
-
-	/* map config space to 0xa8000000, 128MB */
-	nile4_set_pdar(NILE4_PCIW1,
-		       PHYSADDR(NILE4_PCI_CFG_BASE), 0x08000000, 32, 0, 0);
-	nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, 0x0);
-
-	/* ----- M1543 PCI setup ------ */
-
-	/* we know M1543 PCI-ISA controller is at addr:18 */
-	/* xxxx1010 makes USB at addr:13 and PMU at addr:14 */
-	*(volatile unsigned char *) 0xa8040072 &= 0xf0;
-	*(volatile unsigned char *) 0xa8040072 |= 0xa;
-
-	/* setup USB interrupt to IRQ 9, (bit 0:3 - 0001)
-	 * no IOCHRDY signal, (bit 7 - 1)
-	 * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1)
-	 * Bypass USB Master INTAJ level to edge conversion (bit 4 - 0)
-	 */
-	*(unsigned char *) 0xa8040074 = 0xc1;
-
-	/* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011)
-	 * SCI routing to IRQ 13 disabled (bit 7 - 1)
-	 * SCI interrupt level to edge conversion bypassed (bit 4 - 0)
-	 */
-	*(unsigned char *) 0xa8040076 = 0x83;
-
-	/* setup IDE controller
-	 * enable IDE controller (bit 6 - 1)
-	 * IDE IDSEL to be addr:24 (bit 4:5 - 11)
-	 * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
-	 * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0)
-	 * primary IRQ is 14, secondary is 15 (bit 1:0 - 01
-	 */
-	// *(unsigned char*)0xa8040058 = 0x71;
-	// *(unsigned char*)0xa8040058 = 0x79;
-	// *(unsigned char*)0xa8040058 = 0x74;              // use SIRQ, primary tri-state
-	*(unsigned char *) 0xa8040058 = 0x75;	// primary tri-state
-
-#if 0
-	/* this is not necessary if M5229 does not use SIRQ */
-	*(unsigned char *) 0xa8040044 = 0x0d;	// primary to IRQ 14
-	*(unsigned char *) 0xa8040075 = 0x0d;	// secondary to IRQ 14
-#endif
-
-	/* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */
-	/* M5229 IDSEL is addr:24; see above setting */
-	*(unsigned char *) 0xa9000050 |= 0x1;
-
-	/* enable bus master (bit 2)  and IO decoding  (bit 0) */
-	*(unsigned char *) 0xa9000004 |= 0x5;
-
-	/* enable native, copied from arch/ppc/k2boot/head.S */
-	/* TODO - need volatile, need to be portable */
-	*(unsigned char *) 0xa9000009 = 0xff;
-
-	/* ----- end of M1543 PCI setup ------ */
-
-	/* ----- reset on-board ether chip  ------ */
-	*((volatile u32 *) 0xa8020004) |= 1;	/* decode I/O */
-	*((volatile u32 *) 0xa8020010) = 0;	/* set BAR address */
-
-	/* send reset command */
-	*((volatile u32 *) 0xa6000000) = 1;	/* do a soft reset */
-
-	/* disable ether chip */
-	*((volatile u32 *) 0xa8020004) = 0;	/* disable any decoding */
-
-	/* put it into sleep */
-	*((volatile u32 *) 0xa8020040) = 0x80000000;
-
-	/* ----- end of reset on-board ether chip  ------ */
-
-	/* ----- set pci window 1 to pci memory space -------- */
-	nile4_set_pdar(NILE4_PCIW1,
-		       PHYSADDR(NILE4_PCI_MEM_BASE), 0x08000000, 32, 0, 0);
-	// nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
-	nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000);
-
-}
-
-#define USE_NILE4_SERIAL	0
-
-#if USE_NILE4_SERIAL
-#define ns16550_in(reg)		nile4_in8((reg)*8)
-#define ns16550_out(reg, val)	nile4_out8((reg)*8, (val))
-#else
-#define NS16550_BASE		(NILE4_PCI_IO_BASE+0x03f8)
-static inline u8 ns16550_in(u32 reg)
-{
-	return *(volatile u8 *) (NS16550_BASE + reg);
-}
-
-static inline void ns16550_out(u32 reg, u8 val)
-{
-	*(volatile u8 *) (NS16550_BASE + reg) = val;
-}
-#endif
-
-#define NS16550_RBR		0
-#define NS16550_THR		0
-#define NS16550_DLL		0
-#define NS16550_IER		1
-#define NS16550_DLM		1
-#define NS16550_FCR		2
-#define NS16550_IIR		2
-#define NS16550_LCR		3
-#define NS16550_MCR		4
-#define NS16550_LSR		5
-#define NS16550_MSR		6
-#define NS16550_SCR		7
-
-#define NS16550_LSR_DR		0x01	/* Data ready */
-#define NS16550_LSR_OE		0x02	/* Overrun */
-#define NS16550_LSR_PE		0x04	/* Parity error */
-#define NS16550_LSR_FE		0x08	/* Framing error */
-#define NS16550_LSR_BI		0x10	/* Break */
-#define NS16550_LSR_THRE	0x20	/* Xmit holding register empty */
-#define NS16550_LSR_TEMT	0x40	/* Xmitter empty */
-#define NS16550_LSR_ERR		0x80	/* Error */
-
-
-void _serinit(void)
-{
-#if USE_NILE4_SERIAL
-	ns16550_out(NS16550_LCR, 0x80);
-	ns16550_out(NS16550_DLM, 0x00);
-	ns16550_out(NS16550_DLL, 0x36);	/* 9600 baud */
-	ns16550_out(NS16550_LCR, 0x00);
-	ns16550_out(NS16550_LCR, 0x03);
-	ns16550_out(NS16550_FCR, 0x47);
-#else
-	/* done by PMON */
-#endif
-}
-
-void _putc(char c)
-{
-	while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
-	ns16550_out(NS16550_THR, c);
-	if (c == '\n') {
-		while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
-		ns16550_out(NS16550_THR, '\r');
-	}
-}
-
-void _puts(const char *s)
-{
-	char c;
-
-	while ((c = *s++))
-		_putc(c);
-}
-
-char _getc(void)
-{
-	while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR));
-
-	return ns16550_in(NS16550_RBR);
-}
-
-int _testc(void)
-{
-	return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0;
-}
-
-
-/*
- *  Hexadecimal 7-segment LED
- */
-void ddb5476_led_hex(int hex)
-{
-	outb(hex, 0x80);
-}
-
-
-/*
- *  LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543
- */
-struct pci_dev *pci_pmu = NULL;
-
-void ddb5476_led_d2(int on)
-{
-	u8 t;
-
-	if (pci_pmu) {
-		pci_read_config_byte(pci_pmu, 0x7e, &t);
-		if (on)
-			t &= 0x7f;
-		else
-			t |= 0x80;
-		pci_write_config_byte(pci_pmu, 0x7e, t);
-	}
-}
-
-void ddb5476_led_d3(int on)
-{
-	u8 t;
-
-	if (pci_pmu) {
-		pci_read_config_byte(pci_pmu, 0x7e, &t);
-		if (on)
-			t &= 0xbf;
-		else
-			t |= 0x40;
-		pci_write_config_byte(pci_pmu, 0x7e, t);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5476/time.c linux/arch/mips/ddb5476/time.c
--- linux.orig/arch/mips/ddb5476/time.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ddb5476/time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,32 +0,0 @@
-/*
- *  arch/mips/ddb5074/time.c -- Timer routines
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- */
-#include <linux/init.h>
-
-#include <asm/mc146818rtc.h>
-
-static unsigned char ddb_rtc_read_data(unsigned long addr)
-{
-	outb_p(addr, RTC_PORT(0));
-	return inb_p(RTC_PORT(1));
-}
-
-static void ddb_rtc_write_data(unsigned char data, unsigned long addr)
-{
-	outb_p(addr, RTC_PORT(0));
-	outb_p(data, RTC_PORT(1));
-}
-
-static int ddb_rtc_bcd_mode(void)
-{
-	return 1;
-}
-
-struct rtc_ops ddb_rtc_ops = {
-	ddb_rtc_read_data,
-	ddb_rtc_write_data,
-	ddb_rtc_bcd_mode
-};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/common/Makefile linux/arch/mips/ddb5xxx/common/Makefile
--- linux.orig/arch/mips/ddb5xxx/common/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/common/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -13,6 +13,6 @@
 
 O_TARGET:= ddb5xxx.o
 
-obj-y	 += irq.o irq_cpu.o nile4.o prom.o pci.o pci_auto.o rtc_ds1386.o
+obj-y	 += irq.o nile4.o prom.o rtc_ds1386.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/common/irq.c linux/arch/mips/ddb5xxx/common/irq.c
--- linux.orig/arch/mips/ddb5xxx/common/irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/common/irq.c	2002-07-20 01:08:39.000000000 +0000
@@ -26,6 +26,8 @@
 	set_debug_traps();
 	breakpoint();
 #endif
+	/* set up default irq controller */
+	init_generic_irq();
 
 	/* invoke board-specific irq setup */
 	irq_setup();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/common/irq_cpu.c linux/arch/mips/ddb5xxx/common/irq_cpu.c
--- linux.orig/arch/mips/ddb5xxx/common/irq_cpu.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/common/irq_cpu.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,115 +0,0 @@
-/***********************************************************************
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- *  arch/mips/ddb5xxx/common/irq_cpu.c
- *     This file define the irq handler for MIPS CPU interrupts.
- *
- * 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.
- ***********************************************************************
- */
-
-/*
- * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
- * level triggered (i.e., cannot be cleared from CPU; must be cleared from
- * device).  The first two are software interrupts.  The last one is 
- * usually cpu timer interrupt if coutner register is present.
- *
- * This file exports one global function:
- *	mips_cpu_irq_init(u32 irq_base);
- */
-
-#include <linux/irq.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <asm/mipsregs.h>
-
-/* [jsun] sooner or later we should move this debug stuff to MIPS common */
-#include <asm/ddb5xxx/debug.h>
-
-static int mips_cpu_irq_base=-1;
-
-static void 
-mips_cpu_irq_enable(unsigned int irq)
-{
-	MIPS_ASSERT(mips_cpu_irq_base != -1);
-	MIPS_ASSERT(irq >= mips_cpu_irq_base);
-	MIPS_ASSERT(irq < mips_cpu_irq_base+8);
-
-	clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8));
-	set_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
-}
-
-static void 
-mips_cpu_irq_disable(unsigned int irq)
-{
-	MIPS_ASSERT(mips_cpu_irq_base != -1);
-	MIPS_ASSERT(irq >= mips_cpu_irq_base);
-	MIPS_ASSERT(irq < mips_cpu_irq_base+8);
-
-	clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
-}
-
-static unsigned int mips_cpu_irq_startup(unsigned int irq)
-{
-	mips_cpu_irq_enable(irq);
-	return 0;
-}
-
-#define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
-
-static void
-mips_cpu_irq_ack(unsigned int irq)
-{
-	MIPS_ASSERT(mips_cpu_irq_base != -1);
-	MIPS_ASSERT(irq >= mips_cpu_irq_base);
-	MIPS_ASSERT(irq < mips_cpu_irq_base+8);
-
-	/* although we attemp to clear the IP bit in cause reigster, I think
-	 * usually it is cleared by device (irq source)
-	 */
-	clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8));
-
-	/* I am not fully convinced that I should disable irq here */
-}
-
-static void
-mips_cpu_irq_end(unsigned int irq)
-{
-	MIPS_ASSERT(mips_cpu_irq_base != -1);
-	MIPS_ASSERT(irq >= mips_cpu_irq_base);
-	MIPS_ASSERT(irq < mips_cpu_irq_base+8);
-	/* I am not fully convinced that I should enable irq here */
-}
-
-static hw_irq_controller mips_cpu_irq_controller = {
-	"CPU_irq",
-	mips_cpu_irq_startup,
-	mips_cpu_irq_shutdown,
-	mips_cpu_irq_enable,
-	mips_cpu_irq_disable,
-	mips_cpu_irq_ack,
-	mips_cpu_irq_end,
-	NULL			/* no affinity stuff for UP */
-};
-
-
-void 
-mips_cpu_irq_init(u32 irq_base)
-{
-	extern irq_desc_t irq_desc[];
-	u32 i;
-
-	for (i= irq_base; i< irq_base+8; i++) {
-		irq_desc[i].status = IRQ_DISABLED;
-		irq_desc[i].action = NULL;
-		irq_desc[i].depth = 1;
-		irq_desc[i].handler = &mips_cpu_irq_controller;
-	}
-
-	mips_cpu_irq_base = irq_base;
-} 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/common/nile4.c linux/arch/mips/ddb5xxx/common/nile4.c
--- linux.orig/arch/mips/ddb5xxx/common/nile4.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/common/nile4.c	2002-07-20 01:08:38.000000000 +0000
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
-#include <asm/ddb5xxx/debug.h>
 
 u32
 ddb_calc_pdar(u32 phys, u32 size, int width, 
@@ -73,7 +72,7 @@
                 maskbits = 0;
                 break;
         default:
-                panic("nile4_set_pdar: unsupported size %p\n", (void *) size);
+                panic("nile4_set_pdar: unsupported size %p", (void *) size);
         }
         switch (width) {
         case 8:
@@ -89,7 +88,7 @@
                 widthbits = 3;
                 break;
         default:
-                panic("nile4_set_pdar: unsupported width %d\n", width);
+                panic("nile4_set_pdar: unsupported width %d", width);
         }
 
 	return maskbits | (on_memory_bus ? 0x10 : 0) |
@@ -128,7 +127,7 @@
         case DDB_PCICMD_CFG:  /* PCI Configuration Space */
                 break;
         default:
-                panic("nile4_set_pmr: invalid type %d\n", type);
+                panic("nile4_set_pmr: invalid type %d", type);
         }
         ddb_out32(pmr, (type << 1) | (addr & 0xffe00000) | options );
         ddb_out32(pmr + 4, 0);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/common/pci.c linux/arch/mips/ddb5xxx/common/pci.c
--- linux.orig/arch/mips/ddb5xxx/common/pci.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/common/pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,179 +0,0 @@
-/***********************************************************************
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * arch/mips/ddb5xxx/common/pci.c
- *     Common PCI routines for DDB5xxx - as a matter of fact, meant for all 
- *	MIPS machines.
- *
- * 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 file contains common PCI routines meant to be shared for
- * all MIPS machines.
- *
- * Strategies:
- *
- * . We rely on pci_auto.c file to assign PCI resources (MEM and IO)
- *   TODO: this shold be optional for some machines where they do have
- *   a real "pcibios" that does resource assignment.
- *
- * . We then use pci_scan_bus() to "discover" all the resources for
- *   later use by Linux.
- *
- * . We finally reply on a board supplied function, pcibios_fixup_irq(), to 
- *   to assign the interrupts.  We may use setup-irq.c under drivers/pci
- *   later.
- *
- * . Specifically, we will *NOT* use pci_assign_unassigned_resources(),
- *   because we assume all PCI devices should have the resources correctly
- *   assigned and recorded.
- *
- * Limitations:
- *
- * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus 
- *   into a contiguous range.  
- * 
- * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical
- *   address space.
- *
- * . In the case of IO space, it starts from 0, and the beginning address
- *   is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address.
- *
- * . These are the current MIPS limitations (by ioremap, etc).  In the
- *   future, we may remove them.
- *
- * Credits:
- *	Most of the code are derived from the pci routines from PPC and Alpha,
- *	which were mostly writtne by
- *		Cort Dougan, cort@fsmlabs.com
- *		Matt Porter, mporter@mvista.com
- *		Dave Rusling david.rusling@reo.mts.dec.com
- *		David Mosberger davidm@cs.arizona.edu
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-#include <asm/ddb5xxx/pci.h>
-#include <asm/ddb5xxx/debug.h>
-
-
-struct pci_fixup pcibios_fixups[] = { {0} };
-
-
-extern int pciauto_assign_resources(int busno, struct pci_channel * hose);
-void __init pcibios_init(void)
-{
-	struct pci_channel *p;
-	struct pci_bus *bus;
-	int busno;
-
-	/* assign resources */
-	busno=0;
-	for (p= mips_pci_channels; p->pci_ops != NULL; p++) {
-		busno = pciauto_assign_resources(busno, p) + 1;
-	}
-
-	/* scan the buses */
-	busno = 0;
-	for (p= mips_pci_channels; p->pci_ops != NULL; p++) {
-		bus = pci_scan_bus(busno, p->pci_ops, p);
-		busno = bus->subordinate+1;
-	}
-
-	/* fixup irqs (board specific routines) */
-	pcibios_fixup_irqs();
-
-	/* 
-	 * should we do a fixup of ioport_resource and iomem_resource
-	 * based on mips_pci_channels?  
-	 * Let us wait and see if this is a common need and whether there
-	 * are exceptions.  Until then, each board should adjust them
-	 * perhaps in their setup() function.
-	 */
-}
-
-int pcibios_enable_device(struct pci_dev *dev)
-{
-	/* pciauto_assign_resources() will enable all devices found */
-	return 0;
-}
-
-unsigned long __init
-pci_bridge_check_io(struct pci_dev *bridge)
-{
-        u16 io;
-
-        pci_read_config_word(bridge, PCI_IO_BASE, &io);
-        if (!io) {
-                pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
-                pci_read_config_word(bridge, PCI_IO_BASE, &io);
-                pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
-        }
-        if (io)
-                return IORESOURCE_IO;
-        printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n",
-                                bridge->name);
-        return 0;
-}
-
-void __init pcibios_fixup_bus(struct pci_bus *bus)
-{
-        /* Propogate hose info into the subordinate devices.  */
-
-        struct pci_channel *hose = bus->sysdata;
-        struct pci_dev *dev = bus->self;
-
-        if (!dev) {
-                /* Root bus */
-                bus->resource[0] = hose->io_resource;
-                bus->resource[1] = hose->mem_resource;
-        } else {
-                /* This is a bridge. Do not care how it's initialized,
-                   just link its resources to the bus ones */
-                int i;
-
-                for(i=0; i<3; i++) {
-                        bus->resource[i] =
-                                &dev->resource[PCI_BRIDGE_RESOURCES+i];
-                        bus->resource[i]->name = bus->name;
-                }
-                bus->resource[0]->flags |= pci_bridge_check_io(dev);
-                bus->resource[1]->flags |= IORESOURCE_MEM;
-                /* For now, propogate hose limits to the bus;
-                   we'll adjust them later. */
-                bus->resource[0]->end = hose->io_resource->end;
-                bus->resource[1]->end = hose->mem_resource->end;
-                /* Turn off downstream PF memory address range by default */
-                bus->resource[2]->start = 1024*1024;
-                bus->resource[2]->end = bus->resource[2]->start - 1;
-        }
-}
-
-char *pcibios_setup(char *str)
-{
-	return str;
-}
-
-void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
-{
-	/* this should not be called */
-	MIPS_ASSERT(1 == 0);
-}
-
-void
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-                             struct resource *res, int resource)
-{
-	/* this should not be called */
-	MIPS_ASSERT(1 == 0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/common/pci_auto.c linux/arch/mips/ddb5xxx/common/pci_auto.c
--- linux.orig/arch/mips/ddb5xxx/common/pci_auto.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/common/pci_auto.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,396 +0,0 @@
-/*
- * arch/ppc/kernel/pci_auto.c
- * 
- * PCI autoconfiguration library
- *
- * Author: Matt Porter <mporter@mvista.com>
- *
- * Copyright 2000, 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-/*
- * Modified for MIPS by Jun Sun, jsun@mvista.com
- *
- * . Simplify the interface between pci_auto and the rest: a single function.
- * . Assign resources from low address to upper address.
- * . change most int to u32.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-#include <asm/ddb5xxx/pci.h>
-#include <asm/ddb5xxx/debug.h>
-
-#define	DEBUG
-#ifdef 	DEBUG
-#define	DBG(x...)	printk(x)
-#else
-#define	DBG(x...)	
-#endif
-
-/* These are used for config access before all the PCI probing
-   has been done. */
-int early_read_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 *val);
-int early_read_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 *val);
-int early_read_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 *val);
-int early_write_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 val);
-int early_write_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 val);
-int early_write_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 val);
-
-static u32 pciauto_lower_iospc;
-static u32 pciauto_upper_iospc;
-
-static u32 pciauto_lower_memspc;
-static u32 pciauto_upper_memspc;
-
-void __init 
-pciauto_setup_bars(struct pci_channel *hose,
-		   int current_bus,
-		   int pci_devfn)
-{
-	u32 bar_response, bar_size, bar_value;
-	u32 bar, addr_mask, bar_nr = 0;
-	u32 * upper_limit;
-	u32 * lower_limit;
-	int found_mem64 = 0;
-
-	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
-	    current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
-
-	for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4)
-	{
-		/* Tickle the BAR and get the response */
-		early_write_config_dword(hose,
-					 current_bus,
-					 pci_devfn,
-					 bar,
-					 0xffffffff);
-		early_read_config_dword(hose,
-					current_bus,
-					pci_devfn,
-					bar,
-					&bar_response);
-
-		/* If BAR is not implemented go to the next BAR */
-		if (!bar_response)
-			continue;
-
-		/* Check the BAR type and set our address mask */
-		if (bar_response & PCI_BASE_ADDRESS_SPACE)
-		{
-			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
-			upper_limit = &pciauto_upper_iospc;
-			lower_limit = &pciauto_lower_iospc;
-			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
-		}
-		else
-		{
-			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-			     PCI_BASE_ADDRESS_MEM_TYPE_64)
-				found_mem64 = 1;
-
-			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
-			upper_limit = &pciauto_upper_memspc;
-			lower_limit = &pciauto_lower_memspc;
-			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
-		}
-
-		/* Calculate requested size */
-		bar_size = ~(bar_response & addr_mask) + 1;
-
-		/* Allocate a base address */
-		bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
-		MIPS_ASSERT(bar_value + bar_size <= *upper_limit);
-
-		/* Write it out and update our limit */
-		early_write_config_dword(hose,
-					 current_bus,
-					 pci_devfn,
-					 bar,
-					 bar_value);
-
-		*lower_limit = bar_value + bar_size;
-
-		/*
-		 * If we are a 64-bit decoder then increment to the
-		 * upper 32 bits of the bar and force it to locate
-		 * in the lower 4GB of memory.
-		 */ 
-		if (found_mem64)
-		{
-			bar += 4;
-			early_write_config_dword(hose,
-						 current_bus,
-						 pci_devfn,
-						 bar,
-						 0x00000000);
-		}
-
-		bar_nr++;
-
-		DBG("size=0x%x, address=0x%x\n",
-		    bar_size, bar_value);
-	}
-
-}
-
-void __init
-pciauto_prescan_setup_bridge(struct pci_channel *hose,
-			     int current_bus,
-			     int pci_devfn,
-			     int sub_bus)
-{
-	int cmdstat;
-
-	/* Configure bus number registers */
-	early_write_config_byte(hose,
-				current_bus,
-				pci_devfn,
-				PCI_PRIMARY_BUS,
-				current_bus);
-	early_write_config_byte(hose,
-				current_bus,
-				pci_devfn,
-				PCI_SECONDARY_BUS,
-				sub_bus + 1);
-	early_write_config_byte(hose,
-				current_bus,
-				pci_devfn,
-				PCI_SUBORDINATE_BUS,
-				0xff);
-
-	/* Round memory allocator to 1MB boundary */
-	pciauto_upper_memspc &= ~(0x100000 - 1);
-
-	/* Round I/O allocator to 4KB boundary */
-	pciauto_upper_iospc &= ~(0x1000 - 1);
-
-	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
-	early_write_config_word(hose,
-				current_bus,
-				pci_devfn,
-				PCI_MEMORY_LIMIT,
-				((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
-	early_write_config_byte(hose,
-				current_bus,
-				pci_devfn,
-				PCI_IO_LIMIT,
-				((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
-	early_write_config_word(hose,
-				current_bus,
-				pci_devfn,
-				PCI_IO_LIMIT_UPPER16,
-				((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
-			
-	/* We don't support prefetchable memory for now, so disable */
-	early_write_config_word(hose,
-				current_bus,
-				pci_devfn,
-				PCI_PREF_MEMORY_BASE,
-				0x1000);
-	early_write_config_word(hose,
-				current_bus,
-				pci_devfn,
-				PCI_PREF_MEMORY_LIMIT,
-				0x1000);
-
-	/* Enable memory and I/O accesses, enable bus master */
-	early_read_config_dword(hose,
-				current_bus,
-				pci_devfn,
-				PCI_COMMAND,
-				&cmdstat);
-	early_write_config_dword(hose,
-				 current_bus,
-				 pci_devfn,
-				 PCI_COMMAND,
-				 cmdstat |
-				 PCI_COMMAND_IO |
-				 PCI_COMMAND_MEMORY |
-				 PCI_COMMAND_MASTER);
-}
-
-void __init
-pciauto_postscan_setup_bridge(struct pci_channel *hose,
-			      int current_bus,
-			      int pci_devfn,
-			      int sub_bus)
-{
-	/* Configure bus number registers */
-	early_write_config_byte(hose,
-				current_bus,
-				pci_devfn,
-				PCI_SUBORDINATE_BUS,
-				sub_bus);
-
-	/* Round memory allocator to 1MB boundary */
-	pciauto_upper_memspc &= ~(0x100000 - 1);
-	early_write_config_word(hose,
-				current_bus,
-				pci_devfn,
-				PCI_MEMORY_BASE,
-				pciauto_upper_memspc >> 16);
-
-	/* Round I/O allocator to 4KB boundary */
-	pciauto_upper_iospc &= ~(0x1000 - 1);
-	early_write_config_byte(hose,
-				current_bus,
-				pci_devfn,
-				PCI_IO_BASE,
-				(pciauto_upper_iospc & 0x0000f000) >> 8);
-	early_write_config_word(hose,
-				current_bus,
-				pci_devfn,
-				PCI_IO_BASE_UPPER16,
-				pciauto_upper_iospc >> 16);
-}
-
-#define      PCIAUTO_IDE_MODE_MASK           0x05
-
-int __init
-pciauto_bus_scan(struct pci_channel *hose, int current_bus)
-{
-	int sub_bus;
-	u32 pci_devfn, pci_class, cmdstat, found_multi=0;
-	unsigned short vid;
-	unsigned char header_type;
-
-	sub_bus = current_bus;
-	
-	for (pci_devfn=0; pci_devfn<0xff; pci_devfn++) {
-
-		if (PCI_FUNC(pci_devfn) && !found_multi)
-			continue;
-
-		early_read_config_byte(hose,
-				       current_bus,
-				       pci_devfn,
-				       PCI_HEADER_TYPE,
-				       &header_type);
-
-		if (!PCI_FUNC(pci_devfn))
-			found_multi = header_type & 0x80;
-
-		early_read_config_word(hose,
-				       current_bus,
-				       pci_devfn,
-				       PCI_VENDOR_ID,
-				       &vid);
-
-		if (vid == 0xffff) continue;
-
-		early_read_config_dword(hose,
-					current_bus,
-					pci_devfn,
-					PCI_CLASS_REVISION, &pci_class);
-		if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI ) {
-			DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
-			pciauto_prescan_setup_bridge(hose,
-						     current_bus,
-						     pci_devfn,
-						     sub_bus);
-			sub_bus = pciauto_bus_scan(hose, sub_bus+1);
-			pciauto_postscan_setup_bridge(hose,
-						      current_bus,
-						      pci_devfn,
-						      sub_bus);
-
-		} else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
-
-			unsigned char prg_iface;
-
-			early_read_config_byte(hose,
-					       current_bus,
-					       pci_devfn,
-					       PCI_CLASS_PROG,
-					       &prg_iface);
-			if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
-				DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
-				continue;
-			}
-		}
-
-		/*
-		 * Found a peripheral, enable some standard
-		 * settings
-		 */
-		early_read_config_dword(hose,
-					current_bus,
-					pci_devfn,
-					PCI_COMMAND,
-					&cmdstat);
-		early_write_config_dword(hose,
-					 current_bus,
-					 pci_devfn,
-					 PCI_COMMAND,
-					 cmdstat |
-					 PCI_COMMAND_IO |
-					 PCI_COMMAND_MEMORY |
-					 PCI_COMMAND_MASTER);
-		early_write_config_byte(hose,
-					current_bus,
-					pci_devfn,
-					PCI_LATENCY_TIMER,
-					0x80);
-
-                /* Allocate PCI I/O and/or memory space */
-		pciauto_setup_bars(hose,
-				   current_bus,
-				   pci_devfn);
-	}
-	return sub_bus;
-}
-
-int __init
-pciauto_assign_resources(int busno, struct pci_channel *hose)
-{
-	/* setup resource limits */
-	pciauto_lower_iospc = hose->io_resource->start;
-	pciauto_upper_iospc = hose->io_resource->end + 1;
-	pciauto_lower_memspc = hose->mem_resource->start;
-	pciauto_upper_memspc = hose->mem_resource->end + 1;
-
-	return pciauto_bus_scan(hose, busno);
-}
-
-
-/*
- * These functions are used early on before PCI scanning is done
- * and all of the pci_dev and pci_bus structures have been created.
- */
-static struct pci_dev *
-fake_pci_dev(struct pci_channel *hose, int busnr, int devfn)
-{
-        static struct pci_dev dev;
-        static struct pci_bus bus;
-
-        dev.bus = &bus;
-        dev.sysdata = hose;
-        dev.devfn = devfn;
-        bus.number = busnr;
-        bus.ops = hose->pci_ops;
-        return &dev;
-}
-
-#define EARLY_PCI_OP(rw, size, type)                                    \
-int early_##rw##_config_##size(struct pci_channel *hose, int bus,    \
-                               int devfn, int offset, type value)       \
-{                                                                       \
-        return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn), \
-                                        offset, value);                 \
-}
-
-EARLY_PCI_OP(read, byte, u8 *)
-EARLY_PCI_OP(read, word, u16 *)
-EARLY_PCI_OP(read, dword, u32 *)
-EARLY_PCI_OP(write, byte, u8)
-EARLY_PCI_OP(write, word, u16)
-EARLY_PCI_OP(write, dword, u32)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/common/prom.c linux/arch/mips/ddb5xxx/common/prom.c
--- linux.orig/arch/mips/ddb5xxx/common/prom.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/common/prom.c	2002-07-20 01:08:31.000000000 +0000
@@ -22,8 +22,19 @@
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 #include <asm/ddb5xxx/ddb5xxx.h>
+#include <asm/debug.h>
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	switch (mips_machtype) {
+	case MACH_NEC_DDB5074:		return "NEC DDB Vrc-5074";
+	case MACH_NEC_DDB5476:		return "NEC DDB Vrc-5476";
+	case MACH_NEC_DDB5477:		return "NEC DDB Vrc-5477";
+	case MACH_NEC_ROCKHOPPER:	return "NEC Rockhopper";
+	}
+}
 
 /* [jsun@junsun.net] PMON passes arguments in C main() style */
 void __init prom_init(int argc, const char **arg)
@@ -40,19 +51,84 @@
 		strcat(arcs_cmdline, " ");
 	}
 
+	/* by default all these boards use dhcp/nfs root fs */
+	strcat(arcs_cmdline, "ip=bootp");
+
 	mips_machgroup = MACH_GROUP_NEC_DDB;
 
 #if defined(CONFIG_DDB5074)
 	mips_machtype = MACH_NEC_DDB5074;
+	add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM);
 #elif defined(CONFIG_DDB5476)
 	mips_machtype = MACH_NEC_DDB5476;
+	add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM);
 #elif defined(CONFIG_DDB5477)
-	mips_machtype = MACH_NEC_DDB5477;
+	ddb5477_runtime_detection();
+	add_memory_region(0, board_ram_size, BOOT_MEM_RAM);
 #endif
-
-	add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM);
 }
 
 void __init prom_free_prom_memory(void)
 {
 }
+
+#if defined(CONFIG_DDB5477)
+
+#define DEFAULT_LCS1_BASE 0x19000000
+#define TESTVAL1 'K'
+#define TESTVAL2 'S'
+
+int board_ram_size;
+void ddb5477_runtime_detection(void)
+{
+	volatile char *test_offset;
+	char saved_test_byte;
+
+        /* Determine if this is a DDB5477 board, or a BSB-VR0300
+           base board.  We can tell by checking for the location of
+           the NVRAM.  It lives at the beginning of LCS1 on the DDB5477,
+           and the beginning of LCS1 on the BSB-VR0300 is flash memory.
+           The first 2K of the NVRAM are reserved, so don't we'll poke
+           around just after that.
+         */
+
+        test_offset = (char *)KSEG1ADDR(DEFAULT_LCS1_BASE + 0x800);
+        saved_test_byte = *test_offset;
+
+        *test_offset = TESTVAL1;
+        if (*test_offset != TESTVAL1) {
+                /* We couldn't set our test value, so it must not be NVRAM,
+                   so it's a BSB_VR0300 */
+		mips_machtype = MACH_NEC_ROCKHOPPER;
+        } else {
+                /* We may have gotten lucky, and the TESTVAL1 was already
+                   stored at the test location, so we must check a second
+                   test value */
+                *test_offset = TESTVAL2;
+                if (*test_offset != TESTVAL2) {
+                        /* OK, we couldn't set this value either, so it must
+                           definately be a BSB_VR0300 */
+			mips_machtype = MACH_NEC_ROCKHOPPER;
+                } else {
+                        /* We could change the value twice, so it must be
+                        NVRAM, so it's a DDB_VRC5477 */
+			mips_machtype = MACH_NEC_DDB5477;
+                }
+        }
+        /* Restore the original byte */
+        *test_offset = saved_test_byte;
+
+	/* before we know a better way, we will trust PMON for getting
+	 * RAM size 
+	 */
+	board_ram_size = 1 << (36 - (ddb_in32(DDB_SDRAM0) & 0xf));
+
+	db_run(printk("DDB run-time detection : %s, %d MB RAM\n",
+				mips_machtype == MACH_NEC_DDB5477 ?
+				"DDB5477" : "Rockhopper",
+				board_ram_size >> 20));
+
+	/* we can't handle ram size > 128 MB */
+	db_assert(board_ram_size <= (128 << 20));
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/common/rtc_ds1386.c linux/arch/mips/ddb5xxx/common/rtc_ds1386.c
--- linux.orig/arch/mips/ddb5xxx/common/rtc_ds1386.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/common/rtc_ds1386.c	2002-07-20 01:08:30.000000000 +0000
@@ -24,7 +24,7 @@
 #include <asm/time.h>
 #include <asm/addrspace.h>
 
-#include <asm/ddb5xxx/debug.h>
+#include <asm/debug.h>
 
 #define	EPOCH		2000
 
@@ -101,7 +101,7 @@
 	}
 
 	temp = READ_RTC(0x9);
-	month = BIN_TO_BCD(tm.tm_mon);
+	month = BIN_TO_BCD(tm.tm_mon+1);	/* tm_mon starts from 0 to 11 */
 	if (month != (temp & 0x1f)) {
 		WRITE_RTC( 0x9,
 			   (month & 0x1f) | (temp & ~0x1f) );
@@ -147,7 +147,7 @@
 	
 	/* remember the base */
 	rtc_base = base;
-	MIPS_ASSERT((rtc_base & 0xe0000000) == KSEG1);
+	db_assert((rtc_base & 0xe0000000) == KSEG1);
 
 	/* turn on RTC if it is not on */
 	byte = READ_RTC(0x9);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/Makefile linux/arch/mips/ddb5xxx/ddb5476/Makefile
--- linux.orig/arch/mips/ddb5xxx/ddb5476/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/Makefile	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,23 @@
+#
+# Makefile for the NEC DDB Vrc-5476 specific kernel interface routines
+# under Linux.
+#
+# 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).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET = ddb5476.o
+
+obj-y				+= setup.o irq.o int-handler.o pci.o pci_ops.o \
+				   nile4_pic.o vrc5476_irq.o
+obj-$(CONFIG_REMOTE_DEBUG)	+= dbg_io.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/dbg_io.c linux/arch/mips/ddb5xxx/ddb5476/dbg_io.c
--- linux.orig/arch/mips/ddb5xxx/ddb5476/dbg_io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/dbg_io.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,136 @@
+/*
+ * kgdb io functions for DDB5476.  We use the second serial port.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * 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.
+ *
+ */
+
+/* ======================= CONFIG ======================== */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    0xa60002f8
+#define         MAX_BAUD                115200
+
+/* distance in bytes between two serial registers */
+#define         REG_OFFSET              1
+
+/*
+ * 0 - kgdb does serial init
+ * 1 - kgdb skip serial init
+ */
+static int remoteDebugInitialized = 0;
+
+/*
+ * the default baud rate *if* kgdb does serial init
+ */
+#define		BAUD_DEFAULT		UART16550_BAUD_38400
+
+/* ======================= END OF CONFIG ======================== */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+        /* disable interrupts */
+        UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+        /* set up buad rate */
+        {
+                uint32 divisor;
+
+                /* set DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+                /* set divisor */
+                divisor = MAX_BAUD / baud;
+                UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+                UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+                /* clear DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+        }
+
+        /* set data format */
+        UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+
+uint8 getDebugChar(void)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+        return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+        UART16550_WRITE(OFS_SEND_BUFFER, byte);
+        return 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/int-handler.S linux/arch/mips/ddb5xxx/ddb5476/int-handler.S
--- linux.orig/arch/mips/ddb5xxx/ddb5476/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/int-handler.S	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ddb5476
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#include <asm/ddb5xxx/ddb5476.h>
+
+/*
+ * first level interrupt dispatcher for ocelot board -
+ * We check for the timer first, then check PCI ints A and D.
+ * Then check for serial IRQ and fall through.
+ */
+	.align	5
+	NESTED(ddb5476_handle_int, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	.set	noreorder
+	mfc0	t0, CP0_CAUSE  
+	mfc0	t2, CP0_STATUS
+
+	and	t0, t2
+
+        andi    t1, t0, STATUSF_IP7     /* cpu timer */
+        bnez    t1, ll_cpu_ip7
+        andi    t1, t0, STATUSF_IP2	/* vrc5476 & i8259 */
+        bnez    t1, ll_cpu_ip2
+        andi    t1, t0, STATUSF_IP3
+        bnez    t1, ll_cpu_ip3
+        andi    t1, t0, STATUSF_IP4
+        bnez    t1, ll_cpu_ip4
+        andi    t1, t0, STATUSF_IP5
+        bnez    t1, ll_cpu_ip5
+        andi    t1, t0, STATUSF_IP6
+        bnez    t1, ll_cpu_ip6
+        andi    t1, t0, STATUSF_IP0     /* software int 0 */
+        bnez    t1, ll_cpu_ip0
+        andi    t1, t0, STATUSF_IP1     /* software int 1 */
+        bnez    t1, ll_cpu_ip1
+        nop
+
+	.set	reorder
+
+	/* wrong alarm or masked ... */
+	// j	spurious_interrupt
+	move 	a0, sp
+	jal	vrc5476_irq_dispatch
+	j	ret_from_irq
+	nop
+
+	.align	5
+
+ll_cpu_ip0:	
+	li	a0, CPU_IRQ_BASE + 0
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip1:	
+	li	a0, CPU_IRQ_BASE + 1
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip2:		/* jump to second-level dispatching */
+	move	a0, sp
+	jal	vrc5476_irq_dispatch
+	j	ret_from_irq
+
+ll_cpu_ip3:	
+	li	a0, CPU_IRQ_BASE + 3
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip4:	
+	li	a0, CPU_IRQ_BASE + 4
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip5:	
+	li	a0, CPU_IRQ_BASE + 5
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip6:	
+	li	a0, CPU_IRQ_BASE + 6
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip7:
+	li	a0, CPU_IRQ_BASE + 7
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+	END(ddb5476_handle_int)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/irq.c linux/arch/mips/ddb5xxx/ddb5476/irq.c
--- linux.orig/arch/mips/ddb5xxx/ddb5476/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/irq.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,148 @@
+/*
+ *  arch/mips/ddb5476/irq.c -- NEC DDB Vrc-5476 interrupt routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ *
+ * Re-write the whole thing to use new irq.c file.
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/ptrace.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+#define M1543_PNP_CONFIG	0x03f0	/* PnP Config Port */
+#define M1543_PNP_INDEX		0x03f0	/* PnP Index Port */
+#define M1543_PNP_DATA		0x03f1	/* PnP Data Port */
+
+#define M1543_PNP_ALT_CONFIG	0x0370	/* Alternative PnP Config Port */
+#define M1543_PNP_ALT_INDEX	0x0370	/* Alternative PnP Index Port */
+#define M1543_PNP_ALT_DATA	0x0371	/* Alternative PnP Data Port */
+
+#define M1543_INT1_MASTER_CTRL	0x0020	/* INT_1 (master) Control Register */
+#define M1543_INT1_MASTER_MASK	0x0021	/* INT_1 (master) Mask Register */
+
+#define M1543_INT1_SLAVE_CTRL	0x00a0	/* INT_1 (slave) Control Register */
+#define M1543_INT1_SLAVE_MASK	0x00a1	/* INT_1 (slave) Mask Register */
+
+#define M1543_INT1_MASTER_ELCR	0x04d0	/* INT_1 (master) Edge/Level Control */
+#define M1543_INT1_SLAVE_ELCR	0x04d1	/* INT_1 (slave) Edge/Level Control */
+
+static void m1543_irq_setup(void)
+{
+	/*
+	 *  The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13.  Not all
+	 *  the possible IO sources in the M1543 are in use by us.  We will
+	 *  use the following mapping:
+	 *
+	 *      IRQ1  - keyboard (default set by M1543)
+	 *      IRQ3  - reserved for UART B (default set by M1543) (note that
+	 *              the schematics for the DDB Vrc-5476 board seem to 
+	 *              indicate that IRQ3 is connected to the DS1386 
+	 *              watchdog timer interrupt output so we might have 
+	 *              a conflict)
+	 *      IRQ4  - reserved for UART A (default set by M1543)
+	 *      IRQ5  - parallel (default set by M1543)
+	 *      IRQ8  - DS1386 time of day (RTC) interrupt
+	 *      IRQ9  - USB (hardwired in ddb_setup)
+	 *      IRQ10 - PMU (hardwired in ddb_setup)
+	 *      IRQ12 - mouse
+	 *      IRQ14,15 - IDE controller (need to be confirmed, jsun)
+	 */
+
+	/*
+	 *  Assing mouse interrupt to IRQ12 
+	 */
+
+	/* Enter configuration mode */
+	outb(0x51, M1543_PNP_CONFIG);
+	outb(0x23, M1543_PNP_CONFIG);
+
+	/* Select logical device 7 (Keyboard) */
+	outb(0x07, M1543_PNP_INDEX);
+	outb(0x07, M1543_PNP_DATA);
+
+	/* Select IRQ12 */
+	outb(0x72, M1543_PNP_INDEX);
+	outb(0x0c, M1543_PNP_DATA);
+
+	/* Leave configration mode */
+	outb(0xbb, M1543_PNP_CONFIG);
+}
+
+static void nile4_irq_setup(void)
+{
+	int i;
+
+	/* Map all interrupts to CPU int #0 (IP2) */
+	nile4_map_irq_all(0);
+
+	/* PCI INTA#-E# must be level triggered */
+	nile4_set_pci_irq_level_or_edge(0, 1);
+	nile4_set_pci_irq_level_or_edge(1, 1);
+	nile4_set_pci_irq_level_or_edge(2, 1);
+	nile4_set_pci_irq_level_or_edge(3, 1);
+
+	/* PCI INTA#, B#, D# must be active low, INTC# must be active high */
+	nile4_set_pci_irq_polarity(0, 0);
+	nile4_set_pci_irq_polarity(1, 0);
+	nile4_set_pci_irq_polarity(2, 1);
+	nile4_set_pci_irq_polarity(3, 0);
+
+	for (i = 0; i < 16; i++)
+		nile4_clear_irq(i);
+
+	/* Enable CPU int #0 */
+	nile4_enable_irq_output(0);
+
+	/* memory resource acquire in ddb_setup */
+}
+
+static void error_action(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(KERN_ERR "Error interrupt happend: %d\n", irq);
+}
+
+static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
+static struct irqaction irq_error = { no_action, 0, 0, "error", NULL, NULL };
+
+extern asmlinkage void ddb5476_handle_int(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+extern void mips_cpu_irq_init(u32 irq_base);
+extern void vrc5476_irq_init(u32 irq_base);
+
+void __init ddb5476_irq_setup(void)
+{
+	/* hardware initialization */
+	nile4_irq_setup();
+	m1543_irq_setup();
+
+	/* controller setup */
+	init_i8259_irqs();
+	vrc5476_irq_init(VRC5476_IRQ_BASE);
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+
+	/* setup cascade interrupts */
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_I8259_CASCADE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_VRC5476_CASCADE, &irq_cascade);
+
+	/* setup error interrupts for debugging */
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CPCE, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CNTD, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_MCE, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error);
+
+	/* setup the grandpa intr vector */
+	set_except_vector(0, ddb5476_handle_int);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/nile4_pic.c linux/arch/mips/ddb5xxx/ddb5476/nile4_pic.c
--- linux.orig/arch/mips/ddb5xxx/ddb5476/nile4_pic.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/nile4_pic.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,189 @@
+/*
+ *  arch/mips/ddb5476/nile4.c -- 
+ *  	low-level PIC code for NEC Vrc-5476 (Nile 4)
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ *
+ *  Copyright 2001 MontaVista Software Inc.
+ *  Author: jsun@mvista.com or jsun@junsun.net
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+
+/*
+ *  Interrupt Programming
+ */
+void nile4_map_irq(int nile4_irq, int cpu_irq)
+{
+	u32 offset, t;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t &= ~(7 << (nile4_irq * 4));
+	t |= cpu_irq << (nile4_irq * 4);
+	ddb_out32(offset, t);
+}
+
+void nile4_map_irq_all(int cpu_irq)
+{
+	u32 all, t;
+
+	all = cpu_irq;
+	all |= all << 4;
+	all |= all << 8;
+	all |= all << 16;
+	t = ddb_in32(DDB_INTCTRL);
+	t &= 0x88888888;
+	t |= all;
+	ddb_out32(DDB_INTCTRL, t);
+	t = ddb_in32(DDB_INTCTRL + 4);
+	t &= 0x88888888;
+	t |= all;
+	ddb_out32(DDB_INTCTRL + 4, t);
+}
+
+void nile4_enable_irq(int nile4_irq)
+{
+	u32 offset, t;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t |= 8 << (nile4_irq * 4);
+	ddb_out32(offset, t);
+}
+
+void nile4_disable_irq(int nile4_irq)
+{
+	u32 offset, t;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t &= ~(8 << (nile4_irq * 4));
+	ddb_out32(offset, t);
+}
+
+void nile4_disable_irq_all(void)
+{
+	ddb_out32(DDB_INTCTRL, 0);
+	ddb_out32(DDB_INTCTRL + 4, 0);
+}
+
+u16 nile4_get_irq_stat(int cpu_irq)
+{
+	return ddb_in16(DDB_INTSTAT0 + cpu_irq * 2);
+}
+
+void nile4_enable_irq_output(int cpu_irq)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTSTAT1 + 4);
+	t |= 1 << (16 + cpu_irq);
+	ddb_out32(DDB_INTSTAT1, t);
+}
+
+void nile4_disable_irq_output(int cpu_irq)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTSTAT1 + 4);
+	t &= ~(1 << (16 + cpu_irq));
+	ddb_out32(DDB_INTSTAT1, t);
+}
+
+void nile4_set_pci_irq_polarity(int pci_irq, int high)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTPPES);
+	if (high)
+		t &= ~(1 << (pci_irq * 2));
+	else
+		t |= 1 << (pci_irq * 2);
+	ddb_out32(DDB_INTPPES, t);
+}
+
+void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTPPES);
+	if (level)
+		t |= 2 << (pci_irq * 2);
+	else
+		t &= ~(2 << (pci_irq * 2));
+	ddb_out32(DDB_INTPPES, t);
+}
+
+void nile4_clear_irq(int nile4_irq)
+{
+	ddb_out32(DDB_INTCLR, 1 << nile4_irq);
+}
+
+void nile4_clear_irq_mask(u32 mask)
+{
+	ddb_out32(DDB_INTCLR, mask);
+}
+
+u8 nile4_i8259_iack(void)
+{
+	u8 irq;
+	u32 reg;
+
+	/* Set window 0 for interrupt acknowledge */
+	reg = ddb_in32(DDB_PCIINIT0);
+
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
+	irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
+	/* restore window 0 for PCI I/O space */
+	// ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
+	ddb_out32(DDB_PCIINIT0, reg);
+
+	/* i8269.c set the base vector to be 0x0 */
+	return irq + I8259_IRQ_BASE;
+}
+
+#if defined(CONFIG_LL_DEBUG)
+void nile4_dump_irq_status(void)
+{
+	printk(KERN_DEBUG "
+	       CPUSTAT = %p:%p\n", (void *) ddb_in32(DDB_CPUSTAT + 4),
+	       (void *) ddb_in32(DDB_CPUSTAT));
+	printk(KERN_DEBUG "
+	       INTCTRL = %p:%p\n", (void *) ddb_in32(DDB_INTCTRL + 4),
+	       (void *) ddb_in32(DDB_INTCTRL));
+	printk(KERN_DEBUG
+	       "INTSTAT0 = %p:%p\n",
+	       (void *) ddb_in32(DDB_INTSTAT0 + 4),
+	       (void *) ddb_in32(DDB_INTSTAT0));
+	printk(KERN_DEBUG
+	       "INTSTAT1 = %p:%p\n",
+	       (void *) ddb_in32(DDB_INTSTAT1 + 4),
+	       (void *) ddb_in32(DDB_INTSTAT1));
+	printk(KERN_DEBUG
+	       "INTCLR = %p:%p\n", (void *) ddb_in32(DDB_INTCLR + 4),
+	       (void *) ddb_in32(DDB_INTCLR));
+	printk(KERN_DEBUG
+	       "INTPPES = %p:%p\n", (void *) ddb_in32(DDB_INTPPES + 4),
+	       (void *) ddb_in32(DDB_INTPPES));
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/pci.c linux/arch/mips/ddb5xxx/ddb5476/pci.c
--- linux.orig/arch/mips/ddb5xxx/ddb5476/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/pci.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,138 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/pci_channel.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static struct resource extpci_io_resource = {
+	"pci IO space", 
+	0x1000,				/* leave some room for ISA bus */
+	DDB_PCI_IO_SIZE -1,
+	IORESOURCE_IO};
+
+static struct resource extpci_mem_resource = {
+	"pci memory space", 
+	DDB_PCI_MEM_BASE + 0x00100000,	/* leave 1 MB for RTC */
+	DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE -1,
+	IORESOURCE_MEM};
+
+extern struct pci_ops ddb5476_ext_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{ &ddb5476_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource },
+	{ NULL, NULL, NULL}
+};
+
+
+/*
+ * we fix up irqs based on the slot number.
+ * The first entry is at AD:11.
+ * 
+ * This does not work for devices on sub-buses yet.
+ */
+
+/*
+ * temporary
+ */
+
+#define		PCI_EXT_INTA		8
+#define		PCI_EXT_INTB		9
+#define		PCI_EXT_INTC		10
+#define		PCI_EXT_INTD		11
+#define		PCI_EXT_INTE		12
+
+/*
+ * based on ddb5477 manual page 11
+ */
+#define		MAX_SLOT_NUM		21
+static unsigned char irq_map[MAX_SLOT_NUM] = {
+	/* SLOT:  0, AD:11 */ 0xff,
+	/* SLOT:  1, AD:12 */ 0xff,
+	/* SLOT:  2, AD:13 */ 9,		/* USB */
+	/* SLOT:  3, AD:14 */ 10,		/* PMU */
+	/* SLOT:  4, AD:15 */ 0xff,
+	/* SLOT:  5, AD:16 */ 0x0,		/* P2P bridge */
+	/* SLOT:  6, AD:17 */ nile4_to_irq(PCI_EXT_INTB),
+	/* SLOT:  7, AD:18 */ nile4_to_irq(PCI_EXT_INTC),
+	/* SLOT:  8, AD:19 */ nile4_to_irq(PCI_EXT_INTD),
+	/* SLOT:  9, AD:20 */ nile4_to_irq(PCI_EXT_INTA),
+	/* SLOT: 10, AD:21 */ 0xff,
+	/* SLOT: 11, AD:22 */ 0xff,
+	/* SLOT: 12, AD:23 */ 0xff,
+	/* SLOT: 13, AD:24 */ 14,		/* HD controller, M5229 */
+	/* SLOT: 14, AD:25 */ 0xff,
+	/* SLOT: 15, AD:26 */ 0xff,
+	/* SLOT: 16, AD:27 */ 0xff,
+	/* SLOT: 17, AD:28 */ 0xff,
+	/* SLOT: 18, AD:29 */ 0xff,
+	/* SLOT: 19, AD:30 */ 0xff,
+	/* SLOT: 20, AD:31 */ 0xff
+};
+
+extern int vrc5477_irq_to_irq(int irq);
+void __init pcibios_fixup_irqs(void)
+{
+        struct pci_dev *dev;
+        int slot_num;
+
+	pci_for_each_dev(dev) {
+		slot_num = PCI_SLOT(dev->devfn);
+
+		/* we don't do IRQ fixup for sub-bus yet */
+		if (dev->bus->parent != NULL) {
+			db_run(printk("Don't know how to fixup irq for PCI device %d on sub-bus %d\n",
+				slot_num, dev->bus->number));
+			continue;
+		}
+
+		db_assert(slot_num < MAX_SLOT_NUM);
+		db_assert(irq_map[slot_num] != 0xff);
+
+		pci_write_config_byte(dev, 
+				      PCI_INTERRUPT_LINE,
+				      irq_map[slot_num]);
+		dev->irq = irq_map[slot_num];
+	}
+}
+
+#if defined(CONFIG_DEBUG)
+extern void jsun_scan_pci_bus(void);
+#endif
+
+void __init ddb_pci_reset_bus(void)
+{	
+	u32 temp;
+
+	/*
+	 * I am not sure about the "official" procedure, the following
+	 * steps work as far as I know:
+	 * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
+	 * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
+	 * The same is true for both PCI channels.
+	 */
+	temp = ddb_in32(DDB_PCICTRL+4);
+	temp |= 0x80000000;
+	ddb_out32(DDB_PCICTRL+4, temp);
+	temp &= ~0xc0000000;
+	ddb_out32(DDB_PCICTRL+4, temp);
+
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	/* we hope pci_auto has assigned the bus numbers to all buses */
+	return 1;
+}
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/pci_ops.c linux/arch/mips/ddb5xxx/ddb5476/pci_ops.c
--- linux.orig/arch/mips/ddb5xxx/ddb5476/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/pci_ops.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5476/pci_ops.c
+ *     Define the pci_ops for DB5477.
+ *
+ * Much of the code is derived from the original DDB5074 port by 
+ * Geert Uytterhoeven <geert@sonycom.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.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/*
+ * config_swap structure records what set of pdar/pmr are used
+ * to access pci config space.  It also provides a place hold the
+ * original values for future restoring.
+ */
+struct pci_config_swap {
+	u32 	pdar;
+	u32	pmr;
+	u32	config_base;
+	u32	config_size;
+	u32	pdar_backup;
+	u32	pmr_backup;
+};
+
+/*
+ * On DDB5476, we have one set of swap registers
+ */
+struct pci_config_swap ext_pci_swap = {
+	DDB_PCIW0,  
+	DDB_PCIINIT0,
+	DDB_PCI_CONFIG_BASE,
+	DDB_PCI_CONFIG_SIZE
+};
+
+static int pci_config_workaround=1;
+
+/*
+ * access config space
+ */	
+static inline u32 ddb_access_config_base(struct pci_config_swap *swap,
+					 u32 bus,/* 0 means top level bus */
+					 u32 slot_num)
+{
+	u32 pci_addr = 0;
+	u32 pciinit_offset = 0;
+        u32 virt_addr = swap->config_base;
+	u32 option;
+
+	if (pci_config_workaround) {
+		/* [jsun] work around Vrc5476 controller itself, returnning
+		 * slot 0 essentially makes vrc5476 invisible
+		 */ 
+		if (slot_num == 12) slot_num = 0;
+
+#if 0
+		/* BUG : skip P2P bridge for now */
+		if (slot_num == 5) slot_num = 0;
+#endif
+
+	} else {
+		/* now we have to be hornest, returning the true
+		 * PCI config headers for vrc5476
+		 */ 
+		if (slot_num == 12) {
+			swap->pdar_backup = ddb_in32(swap->pdar);
+			swap->pmr_backup = ddb_in32(swap->pmr);
+			return DDB_BASE + DDB_PCI_BASE;
+		}
+	}
+
+	/* minimum pdar (window) size is 2MB */
+	db_assert(swap->config_size >= (2 << 20));
+
+	db_assert(slot_num < (1 << 5));
+	db_assert(bus < (1 << 8));
+
+	/* backup registers */
+	swap->pdar_backup = ddb_in32(swap->pdar);
+	swap->pmr_backup = ddb_in32(swap->pmr);
+
+	/* set the pdar (pci window) register */
+	ddb_set_pdar(swap->pdar,
+		     swap->config_base,
+		     swap->config_size,
+		     32,	/* 32 bit wide */
+		     0,		/* not on local memory bus */
+		     0);	/* not visible from PCI bus (N/A) */
+
+	/* 
+	 * calcuate the absolute pci config addr; 
+	 * according to the spec, we start scanning from adr:11 (0x800)
+	 */ 
+	if (bus == 0) {
+		/* type 0 config */
+		pci_addr = 0x800 << slot_num;
+	} else {
+		/* type 1 config */
+		pci_addr = (bus << 16) | (slot_num << 11);
+		/* panic("ddb_access_config_base: we don't support type 1 config Yet"); */
+	}
+
+	/*
+	 * if pci_addr is less than pci config window size,  we set
+	 * pciinit_offset to 0 and adjust the virt_address.
+	 * Otherwise we will try to adjust pciinit_offset.
+	 */
+	if (pci_addr < swap->config_size) {
+		virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
+		pciinit_offset = 0;
+	} else {
+		db_assert( (pci_addr & (swap->config_size - 1)) == 0);
+		virt_addr = KSEG1ADDR(swap->config_base);
+		pciinit_offset = pci_addr;
+	}
+
+	/* set the pmr register */
+	option = DDB_PCI_ACCESS_32;
+	if (bus != 0) option |= DDB_PCI_CFGTYPE1;
+	ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
+
+	return virt_addr;
+}
+
+static inline void ddb_close_config_base(struct pci_config_swap *swap)
+{
+	ddb_out32(swap->pdar, swap->pdar_backup);
+	ddb_out32(swap->pmr, swap->pmr_backup);
+}
+
+static int read_config_dword(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u32 *val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*val = *(volatile u32*) (base + (func_num << 8) + where);
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int read_config_word(struct pci_config_swap *swap,
+			    struct pci_dev *dev,
+			    u32 where,
+			    u16 *val)
+{
+        int status;
+        u32 result;
+
+	db_assert((where & 1) == 0);
+
+        status = read_config_dword(swap, dev, where & ~3, &result);
+        if (where & 2) result >>= 16;
+        *val = result & 0xffff;
+        return status;
+}
+
+static int read_config_byte(struct pci_config_swap *swap,
+			    struct pci_dev *dev,
+			    u32 where,
+			    u8 *val)
+{
+        int status;
+        u32 result;
+
+        status = read_config_dword(swap, dev, where & ~3, &result);
+        if (where & 1) result >>= 8;
+        if (where & 2) result >>= 16;
+        *val = result & 0xff;
+        return status;
+}
+
+static int write_config_dword(struct pci_config_swap *swap,
+			      struct pci_dev *dev,
+			      u32 where,
+			      u32 val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*(volatile u32*) (base + (func_num << 8) + where) = val; 
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u16 val)
+{
+	int status, shift=0;
+	u32 result;
+
+	db_assert((where & 1) == 0);
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL) return status;
+
+        if (where & 2)
+                shift += 16;
+        result &= ~(0xffff << shift);
+        result |= val << shift;
+        return write_config_dword(swap, dev, where & ~3, result);
+}
+
+static int write_config_byte(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u8 val)
+{
+	int status, shift=0;
+	u32 result;
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL) return status;
+
+        if (where & 2)
+                shift += 16;
+        if (where & 1)
+                shift += 8;
+        result &= ~(0xff << shift);
+        result |= val << shift;
+        return write_config_dword(swap, dev, where & ~3, result);
+}
+
+#define	MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
+static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
+{ \
+     return rw##_config_##unitname(pciswap, \
+                                   dev, \
+                                   where, \
+                                   val); \
+}
+
+MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
+
+MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
+
+struct pci_ops ddb5476_ext_pci_ops ={
+	extpci_read_config_byte,
+	extpci_read_config_word,
+	extpci_read_config_dword,
+	extpci_write_config_byte,
+	extpci_write_config_word,
+	extpci_write_config_dword
+};
+
+
+#if defined(CONFIG_DEBUG)
+void jsun_scan_pci_bus(void)
+{
+	struct pci_bus bus;
+	struct pci_dev dev;
+	unsigned int devfn;
+	int j;
+
+	pci_config_workaround = 0;
+
+	bus.parent = NULL;	/* we scan the top level only */
+	dev.bus = &bus;
+	dev.sysdata = NULL;
+
+	/* scan ext pci bus and io pci bus*/
+	for (j=0; j< 1; j++) {
+		printk(KERN_INFO "scan ddb5476 external PCI bus:\n");
+		bus.ops = &ddb5476_ext_pci_ops;
+	
+		for (devfn = 0; devfn < 0x100; devfn += 8) {
+			u32 temp;
+			u16 temp16;
+			u8 temp8;
+			int i;
+
+			dev.devfn = devfn;
+			db_verify(pci_read_config_dword(&dev, 0, &temp),
+				    == PCIBIOS_SUCCESSFUL);
+			if (temp == 0xffffffff) continue;
+
+			printk(KERN_INFO "slot %d: (addr %d) \n", devfn/8,
+			       11+devfn/8);
+
+			/* verify read word and byte */
+			db_verify(pci_read_config_word(&dev, 2, &temp16),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp16 == (temp >> 16));
+			db_verify(pci_read_config_byte(&dev, 3, &temp8),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp8 == (temp >> 24));
+			db_verify(pci_read_config_byte(&dev, 1, &temp8),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp8 == ((temp >> 8) & 0xff));
+
+			for (i=0; i < 16; i++) {
+				if ((i%4) == 0)
+					printk(KERN_INFO);
+				db_verify(pci_read_config_dword(&dev, i*4, &temp),
+					  == PCIBIOS_SUCCESSFUL);
+				printk("\t%08X", temp);
+				if ((i%4) == 3)
+					printk("\n");
+			}
+		}
+	}
+
+	pci_config_workaround = 1;
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/setup.c linux/arch/mips/ddb5xxx/ddb5476/setup.c
--- linux.orig/arch/mips/ddb5xxx/ddb5476/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/setup.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,331 @@
+/*
+ *  arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/mc146818rtc.h>
+#include <linux/pc_keyb.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/keyboard.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/time.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+// #define USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
+
+#ifdef USE_CPU_COUNTER_TIMER
+
+#define CPU_COUNTER_FREQUENCY           83000000
+#else
+/* otherwise we use general purpose timer */
+#define TIMER_FREQUENCY			83000000
+#define TIMER_BASE			DDB_T2CTRL
+#define TIMER_IRQ			(VRC5476_IRQ_BASE + VRC5476_IRQ_GPT)
+#endif
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void breakpoint(void);
+#endif
+
+extern struct ide_ops std_ide_ops;
+extern struct kbd_ops std_kbd_ops;
+
+static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
+
+static void ddb_machine_restart(char *command)
+{
+	u32 t;
+
+	/* PCI cold reset */
+	t = ddb_in32(DDB_PCICTRL + 4);
+	t |= 0x40000000;
+	ddb_out32(DDB_PCICTRL + 4, t);
+	/* CPU cold reset */
+	t = ddb_in32(DDB_CPUSTAT);
+	t |= 1;
+	ddb_out32(DDB_CPUSTAT, t);
+	/* Call the PROM */
+	back_to_prom();
+}
+
+static void ddb_machine_halt(void)
+{
+	printk(KERN_NOTICE "DDB Vrc-5476 halted.\n");
+	while (1);
+}
+
+static void ddb_machine_power_off(void)
+{
+	printk(KERN_NOTICE "DDB Vrc-5476 halted. Please turn off the power.\n");
+	while (1);
+}
+
+extern void ddb_irq_setup(void);
+extern void rtc_ds1386_init(unsigned long base);
+
+static void __init ddb_time_init(void)
+{
+#if defined(USE_CPU_COUNTER_TIMER)
+	mips_counter_frequency = CPU_COUNTER_FREQUENCY;
+#endif
+
+	/* we have ds1396 RTC chip */
+	rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE));
+}
+
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+static void __init ddb_timer_setup(struct irqaction *irq)
+{
+#if defined(USE_CPU_COUNTER_TIMER)
+
+	unsigned int count;
+
+	/* we are using the cpu counter for timer interrupts */
+	setup_irq(CPU_IRQ_BASE + 7, irq);
+
+	/* to generate the first timer interrupt */
+	count = read_32bit_cp0_register(CP0_COUNT);
+	write_32bit_cp0_register(CP0_COMPARE, count + 1000);
+
+#else
+
+	ddb_out32(TIMER_BASE, TIMER_FREQUENCY/HZ);
+	ddb_out32(TIMER_BASE+4, 0x1);	/* enable timer */
+	setup_irq(TIMER_IRQ, irq);
+#endif
+}
+
+static struct {
+	struct resource dma1;
+	struct resource pic1;
+	struct resource timer;
+	struct resource rtc;
+	struct resource dma_page_reg;
+	struct resource pic2;
+	struct resource dma2;
+} ddb5476_ioport = {
+	{
+	"dma1", 0x00, 0x1f, IORESOURCE_BUSY}, {
+	"pic1", 0x20, 0x3f, IORESOURCE_BUSY}, {
+	"timer", 0x40, 0x5f, IORESOURCE_BUSY}, {
+	"rtc", 0x70, 0x7f, IORESOURCE_BUSY}, {
+	"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, {
+	"pic2", 0xa0, 0xbf, IORESOURCE_BUSY}, {
+	"dma2", 0xc0, 0xdf, IORESOURCE_BUSY}
+};
+
+static struct {
+	struct resource nile4;
+} ddb5476_iomem = {
+	{ "Nile 4", DDB_BASE, DDB_BASE + DDB_SIZE - 1, IORESOURCE_BUSY}
+};
+
+static void ddb5476_board_init(void);
+extern void ddb5476_irq_setup(void);
+extern void (*irq_setup)(void);
+
+void __init 
+ddb_setup(void)
+{
+	extern int panic_timeout;
+
+	irq_setup = ddb5476_irq_setup;
+	set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
+
+	board_time_init = ddb_time_init;
+	board_timer_setup = ddb_timer_setup;
+
+	_machine_restart = ddb_machine_restart;
+	_machine_halt = ddb_machine_halt;
+	_machine_power_off = ddb_machine_power_off;
+
+	/* request io port/mem resources  */
+	if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) ||
+	    request_resource(&ioport_resource, &ddb5476_ioport.pic1) ||
+	    request_resource(&ioport_resource, &ddb5476_ioport.timer) ||
+	    request_resource(&ioport_resource, &ddb5476_ioport.rtc) ||
+	    request_resource(&ioport_resource,
+			     &ddb5476_ioport.dma_page_reg)
+	    || request_resource(&ioport_resource, &ddb5476_ioport.pic2)
+	    || request_resource(&ioport_resource, &ddb5476_ioport.dma2)
+	    || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) {
+		printk
+		    ("ddb_setup - requesting oo port resources failed.\n");
+		for (;;);
+	}
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+
+#ifdef CONFIG_PC_KEYB
+	kbd_ops = &std_kbd_ops;
+#endif
+
+	/* Reboot on panic */
+	panic_timeout = 180;
+
+	/* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
+	/* *(long*)0xbfa00218 = 0x8; */
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+	/* board initialization stuff */
+	ddb5476_board_init();
+}
+
+/*
+ * We don't trust bios.  We essentially does hardware re-initialization
+ * as complete as possible, as far as we know we can safely do.
+ */
+static void 
+ddb5476_board_init(void)
+{
+	/* ----------- setup PDARs ------------ */
+	/* check SDRAM0, whether we are on MEM bus does not matter */
+	db_assert((ddb_in32(DDB_SDRAM0) & 0xffffffef) ==
+		  ddb_calc_pdar(DDB_SDRAM_BASE, DDB_SDRAM_SIZE, 32, 0, 1));
+
+	/* SDRAM1 should be turned off.  What is this for anyway ? */
+	db_assert( (ddb_in32(DDB_SDRAM1) & 0xf) == 0);
+
+	/* flash 1&2, DDB status, DDB control */
+	ddb_set_pdar(DDB_DCS2, DDB_DCS2_BASE, DDB_DCS2_SIZE, 16, 0, 0);
+	ddb_set_pdar(DDB_DCS3, DDB_DCS3_BASE, DDB_DCS3_SIZE, 16, 0, 0);
+	ddb_set_pdar(DDB_DCS4, DDB_DCS4_BASE, DDB_DCS4_SIZE, 8, 0, 0);
+	ddb_set_pdar(DDB_DCS5, DDB_DCS5_BASE, DDB_DCS5_SIZE, 8, 0, 0);
+
+	/* shut off other pdar so they don't accidentally get into the way */
+	ddb_set_pdar(DDB_DCS6, 0xffffffff, 0, 32, 0, 0);
+	ddb_set_pdar(DDB_DCS7, 0xffffffff, 0, 32, 0, 0);
+	ddb_set_pdar(DDB_DCS8, 0xffffffff, 0, 32, 0, 0);
+
+	/* verify VRC5477 base addr */
+	/* don't care about some details */
+	db_assert((ddb_in32(DDB_INTCS) & 0xffffff0f) ==
+		  ddb_calc_pdar(DDB_INTCS_BASE, DDB_INTCS_SIZE, 8, 0, 0));
+
+	/* verify BOOT ROM addr */
+	/* don't care about some details */
+	db_assert((ddb_in32(DDB_BOOTCS) & 0xffffff0f) ==
+		  ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0));
+
+	/* setup PCI windows - window1 for MEM/config, window0 for IO */
+	ddb_set_pdar(DDB_PCIW0, DDB_PCI_IO_BASE, DDB_PCI_IO_SIZE, 32, 0, 1);
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
+
+	ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32);
+
+	/* ----------- setup PDARs ------------ */
+	/* this is problematic - it will reset Aladin which cause we loose
+	 * serial port, and we don't know how to set up Aladin chip again.
+	 */
+	// ddb_pci_reset_bus(); 
+
+	ddb_out32(DDB_BAR0, 0x00000008);
+
+	ddb_out32(DDB_BARC, 0xffffffff);
+	ddb_out32(DDB_BARB, 0xffffffff);
+	ddb_out32(DDB_BAR1, 0xffffffff);
+	ddb_out32(DDB_BAR2, 0xffffffff);
+	ddb_out32(DDB_BAR3, 0xffffffff);
+	ddb_out32(DDB_BAR4, 0xffffffff);
+	ddb_out32(DDB_BAR5, 0xffffffff);
+	ddb_out32(DDB_BAR6, 0xffffffff);
+	ddb_out32(DDB_BAR7, 0xffffffff);
+	ddb_out32(DDB_BAR8, 0xffffffff);
+
+	/* ----------- switch PCI1 to PCI CONFIG space  ------------ */
+	ddb_set_pdar(DDB_PCIW1, DDB_PCI_CONFIG_BASE, DDB_PCI_CONFIG_SIZE, 32, 0, 1);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_CFG, 0x0, DDB_PCI_ACCESS_32);
+
+	/* ----- M1543 PCI setup ------ */
+
+	/* we know M1543 PCI-ISA controller is at addr:18 */
+	/* xxxx1010 makes USB at addr:13 and PMU at addr:14 */
+	*(volatile unsigned char *) 0xa8040072 &= 0xf0;
+	*(volatile unsigned char *) 0xa8040072 |= 0xa;
+
+	/* setup USB interrupt to IRQ 9, (bit 0:3 - 0001)
+	 * no IOCHRDY signal, (bit 7 - 1)
+	 * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1)
+	 * Make USB Master INTAJ level to edge conversion (bit 4 - 1)
+	 */
+	*(unsigned char *) 0xa8040074 = 0xd1;
+
+	/* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011)
+	 * SCI routing to IRQ 13 disabled (bit 7 - 1)
+	 * SCI interrupt level to edge conversion bypassed (bit 4 - 0)
+	 */
+	*(unsigned char *) 0xa8040076 = 0x83;
+
+	/* setup IDE controller
+	 * enable IDE controller (bit 6 - 1)
+	 * IDE IDSEL to be addr:24 (bit 4:5 - 11)
+	 * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
+	 * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0)
+	 * primary IRQ is 14, secondary is 15 (bit 1:0 - 01
+	 */
+	// *(unsigned char*)0xa8040058 = 0x71;
+	// *(unsigned char*)0xa8040058 = 0x79;
+	// *(unsigned char*)0xa8040058 = 0x74;              // use SIRQ, primary tri-state
+	*(unsigned char *) 0xa8040058 = 0x75;	// primary tri-state
+
+#if 0
+	/* this is not necessary if M5229 does not use SIRQ */
+	*(unsigned char *) 0xa8040044 = 0x0d;	// primary to IRQ 14
+	*(unsigned char *) 0xa8040075 = 0x0d;	// secondary to IRQ 14
+#endif
+
+	/* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */
+	/* M5229 IDSEL is addr:24; see above setting */
+	*(unsigned char *) 0xa9000050 |= 0x1;
+
+	/* enable bus master (bit 2)  and IO decoding  (bit 0) */
+	*(unsigned char *) 0xa9000004 |= 0x5;
+
+	/* enable native, copied from arch/ppc/k2boot/head.S */
+	/* TODO - need volatile, need to be portable */
+	*(unsigned char *) 0xa9000009 = 0xff;
+
+	/* ----- end of M1543 PCI setup ------ */
+
+	/* ----- reset on-board ether chip  ------ */
+	*((volatile u32 *) 0xa8020004) |= 1;	/* decode I/O */
+	*((volatile u32 *) 0xa8020010) = 0;	/* set BAR address */
+
+	/* send reset command */
+	*((volatile u32 *) 0xa6000000) = 1;	/* do a soft reset */
+
+	/* disable ether chip */
+	*((volatile u32 *) 0xa8020004) = 0;	/* disable any decoding */
+
+	/* put it into sleep */
+	*((volatile u32 *) 0xa8020040) = 0x80000000;
+
+	/* ----- end of reset on-board ether chip  ------ */
+
+	/* ----------- switch PCI1 back to PCI MEM space  ------------ */
+	ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c linux/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
--- linux.orig/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,113 @@
+/*
+ * The irq controller for vrc5476.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static int irq_base;
+
+static void vrc5476_irq_enable(uint irq)
+{
+	nile4_enable_irq(irq - irq_base);
+}
+
+static void vrc5476_irq_disable(uint irq)
+{
+	nile4_disable_irq(irq - irq_base);
+}
+
+static unsigned int vrc5476_irq_startup(uint irq)
+{
+	nile4_enable_irq(irq - irq_base);
+	return 0;
+}
+
+#define vrc5476_irq_shutdown	vrc5476_irq_disable
+
+static void vrc5476_irq_ack(uint irq)
+{
+	nile4_clear_irq(irq - irq_base);
+	nile4_disable_irq(irq - irq_base);
+}
+
+static void vrc5476_irq_end(uint irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		vrc5476_irq_enable(irq);
+}
+
+static hw_irq_controller vrc5476_irq_controller = {
+	"vrc5476",
+	vrc5476_irq_startup,
+	vrc5476_irq_shutdown,
+	vrc5476_irq_enable,
+	vrc5476_irq_disable,
+	vrc5476_irq_ack,
+	vrc5476_irq_end,
+	NULL				/* no affinity stuff for UP */
+};
+
+void __init 
+vrc5476_irq_init(u32 base)
+{
+	extern irq_desc_t irq_desc[];
+	u32 i;
+
+	irq_base = base;
+	for (i= base; i< base + NUM_VRC5476_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		 irq_desc[i].depth = 1;
+		 irq_desc[i].handler = &vrc5476_irq_controller;
+	}
+}
+
+
+asmlinkage void 
+vrc5476_irq_dispatch(struct pt_regs *regs)
+{
+	extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
+	extern void spurious_interrupt(void);
+
+	u32 mask;
+	int nile4_irq;
+
+	mask = nile4_get_irq_stat(0);
+
+	/* quick check for possible time interrupt */
+	if (mask & (1 << VRC5476_IRQ_GPT)) {
+		do_IRQ(VRC5476_IRQ_BASE + VRC5476_IRQ_GPT, regs);
+		return;
+	}
+
+	/* check for i8259 interrupts */
+	if (mask & (1 << VRC5476_I8259_CASCADE)) {
+		int i8259_irq = nile4_i8259_iack();
+		do_IRQ(I8259_IRQ_BASE + i8259_irq, regs);
+		return;
+	}
+
+	/* regular nile4 interrupts (we should not really have any */
+	for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) {
+		if (mask & 1) {
+			do_IRQ(VRC5476_IRQ_BASE + nile4_irq, regs);
+			return;
+		}
+	}
+	spurious_interrupt();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/Makefile linux/arch/mips/ddb5xxx/ddb5477/Makefile
--- linux.orig/arch/mips/ddb5xxx/ddb5477/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/Makefile	2002-07-20 01:08:31.000000000 +0000
@@ -13,9 +13,9 @@
 
 O_TARGET:= ddb5477.o
 
-obj-y	 += int-handler.o irq.o irq_5477.o setup.o pci.o pci_ops.o
+obj-y	 += int-handler.o irq.o irq_5477.o setup.o pci.o pci_ops.o lcd44780.o
 
-obj-$(CONFIG_LL_DEBUG) 		+= debug.o
+obj-$(CONFIG_DEBUG) 		+= debug.o
 obj-$(CONFIG_REMOTE_DEBUG)	+= kgdb_io.o
 obj-$(CONFIG_BLK_DEV_INITRD)	+= ramdisk.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/debug.c linux/arch/mips/ddb5xxx/ddb5477/debug.c
--- linux.orig/arch/mips/ddb5xxx/ddb5477/debug.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/debug.c	2002-07-20 01:08:27.000000000 +0000
@@ -15,8 +15,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/signal.h>		/* SA_INTERRUPT */
 
 #include <asm/mipsregs.h>
 #include <asm/ddb5xxx/ddb5xxx.h>
@@ -64,9 +62,9 @@
 static Register pdar_regs[] = {
         {"DDB_SDRAM0", DDB_BASE + DDB_SDRAM0},
         {"DDB_SDRAM1", DDB_BASE + DDB_SDRAM1},
-        {"DDB_LDCS0", DDB_BASE + DDB_LDCS0},
-        {"DDB_LDCS1", DDB_BASE + DDB_LDCS1},
-        {"DDB_LDCS2", DDB_BASE + DDB_LDCS2},
+        {"DDB_LCS0", DDB_BASE + DDB_LCS0},
+        {"DDB_LCS1", DDB_BASE + DDB_LCS1},
+        {"DDB_LCS2", DDB_BASE + DDB_LCS2},
         {"DDB_INTCS", DDB_BASE + DDB_INTCS},
         {"DDB_BOOTCS", DDB_BASE + DDB_BOOTCS},
         {"DDB_PCIW0", DDB_BASE + DDB_PCIW0},
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/irq.c linux/arch/mips/ddb5xxx/ddb5477/irq.c
--- linux.orig/arch/mips/ddb5xxx/ddb5477/irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/irq.c	2002-07-20 01:08:26.000000000 +0000
@@ -12,16 +12,16 @@
  */
 #include <linux/config.h>
 #include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
 
 #include <asm/system.h>
 #include <asm/mipsregs.h>
+#include <asm/debug.h>
+
 #include <asm/ddb5xxx/ddb5xxx.h>
 
-/* [jsun] sooner or later we should move this debug stuff to MIPS common */
-#include <asm/ddb5xxx/debug.h>
 
 /*
  * IRQ mapping
@@ -76,7 +76,7 @@
 void
 ddb5477_irq_setup(void)
 {
-	MIPS_DEBUG(printk("ddb5477_irq_setup invoked.\n"));
+	db_run(printk("ddb5477_irq_setup invoked.\n"));
 
 	/* by default, we disable all interrupts and route all vrc5477 
 	 * interrupts to pin 0 (irq 2) */
@@ -141,16 +141,16 @@
 	u32 bitmask;
 	u32 i;
 
-	MIPS_ASSERT(ddb_in32(DDB_INT2STAT) == 0);
-	MIPS_ASSERT(ddb_in32(DDB_INT3STAT) == 0);
-	MIPS_ASSERT(ddb_in32(DDB_INT4STAT) == 0);
-	MIPS_ASSERT(ddb_in32(DDB_NMISTAT) == 0);
+	db_assert(ddb_in32(DDB_INT2STAT) == 0);
+	db_assert(ddb_in32(DDB_INT3STAT) == 0);
+	db_assert(ddb_in32(DDB_INT4STAT) == 0);
+	db_assert(ddb_in32(DDB_NMISTAT) == 0);
 
 	if (ddb_in32(DDB_INT1STAT) != 0) {
-#if defined(CONFIG_LL_DEBUG)
+#if defined(CONFIG_DEBUG)
 		vrc5477_show_int_regs();
 #endif
-		panic("error interrupt has happened.\n");
+		panic("error interrupt has happened.");
 	}
 
 	intStatus = ddb_in32(DDB_INT0STAT);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/irq_5477.c linux/arch/mips/ddb5xxx/ddb5477/irq_5477.c
--- linux.orig/arch/mips/ddb5xxx/ddb5477/irq_5477.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/irq_5477.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,4 +1,4 @@
-/***********************************************************************
+/*
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
@@ -9,7 +9,7 @@
  * 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.
- ***********************************************************************
+ *
  */
 
 /*
@@ -18,28 +18,26 @@
  * This file exports one function:
  *	vrc5477_irq_init(u32 irq_base);
  */
-
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
 
-#include <asm/ddb5xxx/ddb5xxx.h>
+#include <asm/debug.h>
 
-/* [jsun] sooner or later we should move this debug stuff to MIPS common */
-#include <asm/ddb5xxx/debug.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
 
 /* number of total irqs supported by Vrc5477 */
 #define	NUM_5477_IRQ		32
 
-static int vrc5477_irq_base=-1;
+static int vrc5477_irq_base = -1;
 
 
 static void 
 vrc5477_irq_enable(unsigned int irq)
 {
-	MIPS_ASSERT(vrc5477_irq_base != -1);
-	MIPS_ASSERT(irq >= vrc5477_irq_base);
-	MIPS_ASSERT(irq < vrc5477_irq_base+ NUM_5477_IRQ);
+	db_assert(vrc5477_irq_base != -1);
+	db_assert(irq >= vrc5477_irq_base);
+	db_assert(irq < vrc5477_irq_base+ NUM_5477_IRQ);
 
 	ll_vrc5477_irq_enable(irq - vrc5477_irq_base);
 }
@@ -47,9 +45,9 @@
 static void 
 vrc5477_irq_disable(unsigned int irq)
 {
-	MIPS_ASSERT(vrc5477_irq_base != -1);
-	MIPS_ASSERT(irq >= vrc5477_irq_base);
-	MIPS_ASSERT(irq < vrc5477_irq_base + NUM_5477_IRQ);
+	db_assert(vrc5477_irq_base != -1);
+	db_assert(irq >= vrc5477_irq_base);
+	db_assert(irq < vrc5477_irq_base + NUM_5477_IRQ);
 
 	ll_vrc5477_irq_disable(irq - vrc5477_irq_base);
 }
@@ -65,9 +63,9 @@
 static void
 vrc5477_irq_ack(unsigned int irq)
 {
-	MIPS_ASSERT(vrc5477_irq_base != -1);
-	MIPS_ASSERT(irq >= vrc5477_irq_base);
-	MIPS_ASSERT(irq < vrc5477_irq_base+ NUM_5477_IRQ);
+	db_assert(vrc5477_irq_base != -1);
+	db_assert(irq >= vrc5477_irq_base);
+	db_assert(irq < vrc5477_irq_base+ NUM_5477_IRQ);
 
 	/* clear the interrupt bit */
 	/* some irqs require the driver to clear the sources */
@@ -82,11 +80,12 @@
 static void
 vrc5477_irq_end(unsigned int irq)
 {
-	MIPS_ASSERT(vrc5477_irq_base != -1);
-	MIPS_ASSERT(irq >= vrc5477_irq_base);
-	MIPS_ASSERT(irq < vrc5477_irq_base + NUM_5477_IRQ);
+	db_assert(vrc5477_irq_base != -1);
+	db_assert(irq >= vrc5477_irq_base);
+	db_assert(irq < vrc5477_irq_base + NUM_5477_IRQ);
 
-	ll_vrc5477_irq_enable( irq - vrc5477_irq_base);
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		ll_vrc5477_irq_enable( irq - vrc5477_irq_base);
 }
 
 hw_irq_controller vrc5477_irq_controller = {
@@ -119,8 +118,8 @@
 
 int vrc5477_irq_to_irq(int irq)
 {
-	MIPS_ASSERT(irq >= 0);
-	MIPS_ASSERT(irq < NUM_5477_IRQ);
+	db_assert(irq >= 0);
+	db_assert(irq < NUM_5477_IRQ);
 
 	return irq + vrc5477_irq_base;
 }
@@ -131,10 +130,10 @@
 	u32 reg_bitmask;
 	u32 reg_index;
 
-	MIPS_ASSERT(vrc5477_irq >= 0);
-	MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ);
-	MIPS_ASSERT(ip >= 0);
-	MIPS_ASSERT((ip < 5) || (ip == 6));
+	db_assert(vrc5477_irq >= 0);
+	db_assert(vrc5477_irq < NUM_5477_IRQ);
+	db_assert(ip >= 0);
+	db_assert((ip < 5) || (ip == 6));
 
 	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
 	reg_value = ddb_in32(reg_index);
@@ -150,13 +149,13 @@
 	u32 reg_bitmask;
 	u32 reg_index;
 
-	MIPS_ASSERT(vrc5477_irq >= 0);
-	MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ);
+	db_assert(vrc5477_irq >= 0);
+	db_assert(vrc5477_irq < NUM_5477_IRQ);
 
 	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
 	reg_value = ddb_in32(reg_index);
 	reg_bitmask = 8 << (vrc5477_irq % 8 * 4);
-	MIPS_ASSERT((reg_value & reg_bitmask) == 0);
+	db_assert((reg_value & reg_bitmask) == 0);
 	ddb_out32(reg_index, reg_value | reg_bitmask);
 }
 
@@ -166,14 +165,14 @@
 	u32 reg_bitmask;
 	u32 reg_index;
 
-	MIPS_ASSERT(vrc5477_irq >= 0);
-	MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ);
+	db_assert(vrc5477_irq >= 0);
+	db_assert(vrc5477_irq < NUM_5477_IRQ);
 
 	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
 	reg_value = ddb_in32(reg_index);
 	reg_bitmask = 8 << (vrc5477_irq % 8 * 4);
 
 	/* we assert that the interrupt is enabled (perhaps over-zealous) */
-	MIPS_ASSERT( (reg_value & reg_bitmask) != 0);
+	db_assert( (reg_value & reg_bitmask) != 0);
 	ddb_out32(reg_index, reg_value & ~reg_bitmask);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/kgdb_io.c linux/arch/mips/ddb5xxx/ddb5477/kgdb_io.c
--- linux.orig/arch/mips/ddb5xxx/ddb5477/kgdb_io.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/kgdb_io.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,17 +1,41 @@
+/*
+ * kgdb io functions for DDB5477.  We use the second serial port (upper one).
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
 
-#include <linux/config.h>
+/* ======================= CONFIG ======================== */
 
-#if (defined(CONFIG_DDB5477) && defined(CONFIG_REMOTE_DEBUG))
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    0xbfa04240
+#define         MAX_BAUD                115200
 
-/* --- CONFIG --- */
+/* distance in bytes between two serial registers */
+#define         REG_OFFSET              8
+
+/*
+ * 0 - kgdb does serial init
+ * 1 - kgdb skip serial init
+ */
+static int remoteDebugInitialized = 0;
+
+/*
+ * the default baud rate *if* kgdb does serial init
+ */
+#define		BAUD_DEFAULT		UART16550_BAUD_38400
+
+/* ======================= END OF CONFIG ======================== */
 
-/* we need uint32 uint8 */
-/* #include "types.h" */
 typedef unsigned char uint8;
 typedef unsigned int uint32;
 
-/* --- END OF CONFIG --- */
-
 #define         UART16550_BAUD_2400             2400
 #define         UART16550_BAUD_4800             4800
 #define         UART16550_BAUD_9600             9600
@@ -34,21 +58,10 @@
 #define         UART16550_STOP_1BIT             0x0
 #define         UART16550_STOP_2BIT             0x4
 
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-
-/* [jsun] we use the second serial port for kdb */
-#define         BASE                    0xbfa04240
-#define         MAX_BAUD                115200
-#define		REG_OFFSET		8
-
-/* === END OF CONFIG === */
-
 /* register offset */
-#define         OFS_RCV_BUFFER          (0*REG_OFFSET)
-#define         OFS_TRANS_HOLD          (0*REG_OFFSET)
-#define         OFS_SEND_BUFFER         (0*REG_OFFSET)
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
 #define         OFS_INTR_ENABLE         (1*REG_OFFSET)
 #define         OFS_INTR_ID             (2*REG_OFFSET)
 #define         OFS_DATA_FORMAT         (3*REG_OFFSET)
@@ -70,73 +83,54 @@
 
 void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
 {
-	/* disable interrupts */
-	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+        /* disable interrupts */
+        UART16550_WRITE(OFS_INTR_ENABLE, 0);
 
-	/* set up buad rate */
-	{
-		uint32 divisor;
-
-		/* set DIAB bit */
-		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
-		/* set divisor */
-		divisor = MAX_BAUD / baud;
-		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
-		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
-		/* clear DIAB bit */
-		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
-	}
+        /* set up buad rate */
+        {
+                uint32 divisor;
+
+                /* set DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+                /* set divisor */
+                divisor = MAX_BAUD / baud;
+                UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+                UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+                /* clear DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+        }
 
-	/* set data format */
-	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+        /* set data format */
+        UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
 }
 
-static int remoteDebugInitialized = 0;
-
-int debug_state = -1;
 
 uint8 getDebugChar(void)
 {
-	uint8 c;
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_38400,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-	}
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
 
-	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
-	c= UART16550_READ(OFS_RCV_BUFFER);
-/*
-	if (state != 1) {
-		state = 1;
-		debug_out("\ngetDebugChar: ", 15);
-	}
-	debug_out(&c, 1);
-*/
-	return c;
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+        return UART16550_READ(OFS_RCV_BUFFER);
 }
 
 
 int putDebugChar(uint8 byte)
 {
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_9600,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-	}
-
-	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
-	UART16550_WRITE(OFS_SEND_BUFFER, byte);
-	if (debug_state != 2) {
-		debug_state = 2;
-		// debug_out("\nputDebugChar: ", 15);
-	}
-	// debug_out(&byte, 1);
-	return 1;
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+        UART16550_WRITE(OFS_SEND_BUFFER, byte);
+        return 1;
 }
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/lcd44780.c linux/arch/mips/ddb5xxx/ddb5477/lcd44780.c
--- linux.orig/arch/mips/ddb5xxx/ddb5477/lcd44780.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/lcd44780.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,92 @@
+/*
+ * lcd44780.c
+ * Simple "driver" for a memory-mapped 44780-style LCD display.
+ *
+ * Copyright 2001 Bradley D. LaRonde <brad@ltc.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.
+ *
+ */
+
+#define LCD44780_COMMAND   ((volatile unsigned char *)0xbe020000)
+#define LCD44780_DATA      ((volatile unsigned char *)0xbe020001)
+
+#define LCD44780_4BIT_1LINE        0x20
+#define LCD44780_4BIT_2LINE        0x28
+#define LCD44780_8BIT_1LINE        0x30
+#define LCD44780_8BIT_2LINE        0x38
+#define LCD44780_MODE_DEC          0x04
+#define LCD44780_MODE_DEC_SHIFT    0x05
+#define LCD44780_MODE_INC          0x06
+#define LCD44780_MODE_INC_SHIFT    0x07
+#define LCD44780_SCROLL_LEFT       0x18
+#define LCD44780_SCROLL_RIGHT      0x1e
+#define LCD44780_CURSOR_UNDERLINE  0x0e
+#define LCD44780_CURSOR_BLOCK      0x0f
+#define LCD44780_CURSOR_OFF        0x0c
+#define LCD44780_CLEAR             0x01
+#define LCD44780_BLANK             0x08
+#define LCD44780_RESTORE           0x0c  // Same as CURSOR_OFF
+#define LCD44780_HOME              0x02
+#define LCD44780_LEFT              0x10
+#define LCD44780_RIGHT             0x14
+
+void lcd44780_wait(void)
+{
+	int i, j;
+	for(i=0; i < 400; i++)
+		for(j=0; j < 10000; j++);
+}
+
+void lcd44780_command(unsigned char c)
+{
+	*LCD44780_COMMAND = c;
+	lcd44780_wait();
+}
+
+void lcd44780_data(unsigned char c)
+{
+	*LCD44780_DATA = c;
+	lcd44780_wait();
+}
+
+void lcd44780_puts(const char* s)
+{
+	int i,j;
+	int pos = 0;
+
+	lcd44780_command(LCD44780_CLEAR);
+	while(*s) {
+		lcd44780_data(*s);
+		s++;
+		pos++;
+		if (pos == 8) {
+		  /* We must write 32 of spaces to get cursor to 2nd line */
+		  for (j=0; j<32; j++) {
+		    lcd44780_data(' ');
+		  }
+		}
+		if (pos == 16) {
+		  /* We have filled all 16 character positions, so stop
+		     outputing data */
+		  break;
+		}
+	}
+#ifdef LCD44780_PUTS_PAUSE
+	for(i = 1; i < 2000; i++)
+		lcd44780_wait();
+#endif
+}
+
+void lcd44780_init(void)
+{
+	// The display on the RockHopper is physically a single
+	// 16 char line (two 8 char lines concatenated).  bdl
+	lcd44780_command(LCD44780_8BIT_2LINE);
+	lcd44780_command(LCD44780_MODE_INC);
+	lcd44780_command(LCD44780_CURSOR_BLOCK);
+	lcd44780_command(LCD44780_CLEAR);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/lcd44780.h linux/arch/mips/ddb5xxx/ddb5477/lcd44780.h
--- linux.orig/arch/mips/ddb5xxx/ddb5477/lcd44780.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/lcd44780.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,15 @@
+/*
+ * lcd44780.h
+ * Simple "driver" for a memory-mapped 44780-style LCD display.
+ *
+ * Copyright 2001 Bradley D. LaRonde <brad@ltc.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.
+ *
+ */
+
+void lcd44780_puts(const char* s);
+void lcd44780_init(void);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/pci.c linux/arch/mips/ddb5xxx/ddb5477/pci.c
--- linux.orig/arch/mips/ddb5xxx/ddb5477/pci.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/pci.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,11 +1,25 @@
+/*
+ * PCI code for DDB5477.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 
+#include <asm/pci_channel.h>
+#include <asm/debug.h>
+
 #include <asm/ddb5xxx/ddb5xxx.h>
-#include <asm/ddb5xxx/debug.h>
-#include <asm/ddb5xxx/pci.h>
 
 static struct resource extpci_io_resource = {
 	"ext pci IO space", 
@@ -103,8 +117,16 @@
 
 	pci_for_each_dev(dev) {
 		slot_num = PCI_SLOT(dev->devfn);
-		MIPS_ASSERT(slot_num < MAX_SLOT_NUM);
-		MIPS_ASSERT(irq_map[slot_num] != 0xff);
+
+               /* we don't do IRQ fixup for sub-bus yet */
+               if (dev->bus->parent != NULL) {
+                       db_run(printk("Don't know how to fixup irq for PCI device %d on sub-bus %d\n",
+                                       slot_num, dev->bus->number));
+                       continue;
+               }
+
+		db_assert(slot_num < MAX_SLOT_NUM);
+		db_assert(irq_map[slot_num] != 0xff);
 
 		pci_write_config_byte(dev, 
 				      PCI_INTERRUPT_LINE,
@@ -113,7 +135,7 @@
 	}
 }
 
-#if defined(CONFIG_LL_DEBUG)
+#if defined(CONFIG_DEBUG)
 extern void jsun_scan_pci_bus(void);
 extern void jsun_assign_pci_resource(void);
 #endif
@@ -143,5 +165,15 @@
 
 unsigned __init int pcibios_assign_all_busses(void)
 {
+	/* we hope pci_auto has assigned the bus numbers to all buses */
 	return 1;
 }
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/pci_ops.c linux/arch/mips/ddb5xxx/ddb5477/pci_ops.c
--- linux.orig/arch/mips/ddb5xxx/ddb5477/pci_ops.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/pci_ops.c	2002-07-20 01:08:22.000000000 +0000
@@ -26,7 +26,8 @@
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
-#include <asm/ddb5xxx/debug.h>
+#include <asm/debug.h>
+
 #include <asm/ddb5xxx/ddb5xxx.h>
 
 /*
@@ -72,14 +73,11 @@
         u32 virt_addr = swap->config_base;
 	u32 option;
 
-	/* [jsun] hack for testing */
-	// if (slot_num == 4) slot_num = 0;
-
 	/* minimum pdar (window) size is 2MB */
-	MIPS_ASSERT(swap->config_size >= (2 << 20));
+	db_assert(swap->config_size >= (2 << 20));
 
-	MIPS_ASSERT(slot_num < (1 << 5));
-	MIPS_ASSERT(bus < (1 << 8));
+	db_assert(slot_num < (1 << 5));
+	db_assert(bus < (1 << 8));
 
 	/* backup registers */
 	swap->pdar_backup = ddb_in32(swap->pdar);
@@ -103,7 +101,6 @@
 	} else {
 		/* type 1 config */
 		pci_addr = (bus << 16) | (slot_num << 11);
-		panic("ddb_access_config_base: we don't support type 1 config Yet");
 	}
 
 	/*
@@ -115,7 +112,7 @@
 		virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
 		pciinit_offset = 0;
 	} else {
-		MIPS_ASSERT( (pci_addr & (swap->config_size - 1)) == 0);
+		db_assert( (pci_addr & (swap->config_size - 1)) == 0);
 		virt_addr = KSEG1ADDR(swap->config_base);
 		pciinit_offset = pci_addr;
 	}
@@ -142,13 +139,13 @@
 	u32 bus, slot_num, func_num;
 	u32 base;
 
-	MIPS_ASSERT((where & 3) == 0);
-	MIPS_ASSERT(where < (1 << 8));
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
 
 	/* check if the bus is top-level */
 	if (dev->bus->parent != NULL) {
 		bus = dev->bus->number;
-		MIPS_ASSERT(bus != 0);
+		db_assert(bus != 0);
 	} else {
 		bus = 0;
 	}
@@ -169,7 +166,7 @@
         int status;
         u32 result;
 
-	MIPS_ASSERT((where & 1) == 0);
+	db_assert((where & 1) == 0);
 
         status = read_config_dword(swap, dev, where & ~3, &result);
         if (where & 2) result >>= 16;
@@ -200,13 +197,13 @@
 	u32 bus, slot_num, func_num;
 	u32 base;
 
-	MIPS_ASSERT((where & 3) == 0);
-	MIPS_ASSERT(where < (1 << 8));
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
 
 	/* check if the bus is top-level */
 	if (dev->bus->parent != NULL) {
 		bus = dev->bus->number;
-		MIPS_ASSERT(bus != 0);
+		db_assert(bus != 0);
 	} else {
 		bus = 0;
 	}
@@ -227,7 +224,7 @@
 	int status, shift=0;
 	u32 result;
 
-	MIPS_ASSERT((where & 1) == 0);
+	db_assert((where & 1) == 0);
 
 	status = read_config_dword(swap, dev, where & ~3, &result);
 	if (status != PCIBIOS_SUCCESSFUL) return status;
@@ -303,7 +300,7 @@
 	iopci_write_config_dword
 };
 
-#if defined(CONFIG_LL_DEBUG)
+#if defined(CONFIG_DEBUG)
 void jsun_scan_pci_bus(void)
 {
 	struct pci_bus bus;
@@ -332,26 +329,26 @@
 			int i;
 
 			dev.devfn = devfn;
-			MIPS_VERIFY(pci_read_config_dword(&dev, 0, &temp),
-				    == PCIBIOS_SUCCESSFUL);
+			db_verify(pci_read_config_dword(&dev, 0, &temp),
+				  == PCIBIOS_SUCCESSFUL);
 			if (temp == 0xffffffff) continue;
 
 			printk("slot %d: (addr %d) \n", devfn/8, 11+devfn/8);
 
 			/* verify read word and byte */
-			MIPS_VERIFY(pci_read_config_word(&dev, 2, &temp16),
-				    == PCIBIOS_SUCCESSFUL);
-			MIPS_ASSERT(temp16 == (temp >> 16));
-			MIPS_VERIFY(pci_read_config_byte(&dev, 3, &temp8),
-				    == PCIBIOS_SUCCESSFUL);
-			MIPS_ASSERT(temp8 == (temp >> 24));
-			MIPS_VERIFY(pci_read_config_byte(&dev, 1, &temp8),
-				    == PCIBIOS_SUCCESSFUL);
-			MIPS_ASSERT(temp8 == ((temp >> 8) & 0xff));
+			db_verify(pci_read_config_word(&dev, 2, &temp16),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp16 == (temp >> 16));
+			db_verify(pci_read_config_byte(&dev, 3, &temp8),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp8 == (temp >> 24));
+			db_verify(pci_read_config_byte(&dev, 1, &temp8),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp8 == ((temp >> 8) & 0xff));
 
 			for (i=0; i < 16; i++) {
-				MIPS_VERIFY(pci_read_config_dword(&dev, i*4, &temp),
-					    == PCIBIOS_SUCCESSFUL);
+				db_verify(pci_read_config_dword(&dev, i*4, &temp),
+					  == PCIBIOS_SUCCESSFUL);
 				printk("\t%08X", temp);
 				if ((i%4) == 3) printk("\n");
 			}
@@ -374,7 +371,7 @@
 	/* for slot 5 (ext pci 1) eepro card */
 	dev.devfn = 5*8;
 	pci_read_config_dword(&dev, 0, &temp);
-	MIPS_ASSERT(temp == 0x12298086);
+	db_assert(temp == 0x12298086);
 
 	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_0, DDB_PCI0_MEM_BASE);
 	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_1, 0);
@@ -396,7 +393,7 @@
 	/* for slot 4 on board ether chip */
 	dev.devfn = 4*8;
 	pci_read_config_dword(&dev, 0, &temp);
-	MIPS_ASSERT(temp == 0x00191011);
+	db_assert(temp == 0x00191011);
 
 	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_0, 0x1000);
 	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_1, DDB_PCI0_MEM_BASE);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ddb5xxx/ddb5477/setup.c linux/arch/mips/ddb5xxx/ddb5477/setup.c
--- linux.orig/arch/mips/ddb5xxx/ddb5477/setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ddb5xxx/ddb5477/setup.c	2002-07-20 01:08:31.000000000 +0000
@@ -10,10 +10,7 @@
  * under  the terms of  the GNU General  Public License as published by the
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
- *
- ***********************************************************************
  */
-
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -27,18 +24,21 @@
 #include <linux/ioport.h>
 #include <linux/param.h>	/* for HZ */
 
+#include <asm/bootinfo.h>
 #include <asm/addrspace.h>
 #include <asm/time.h>
 #include <asm/bcache.h>
 #include <asm/irq.h>
 #include <asm/reboot.h>
 #include <asm/gdb-stub.h>
+#include <asm/debug.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
+#include "lcd44780.h"
 
 
-#define	USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
+// #define	USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
 
 #ifdef USE_CPU_COUNTER_TIMER
 #define	CPU_COUNTER_FREQUENCY		83000000
@@ -60,7 +60,7 @@
 
 	/* CPU cold reset */
 	t = ddb_in32(DDB_CPUSTAT);
-	MIPS_ASSERT((t&1));
+	db_assert((t&1));
 	ddb_out32(DDB_CPUSTAT, t);
 
 	/* Call the PROM */
@@ -87,13 +87,13 @@
 #endif
 
 	/* we have ds1396 RTC chip */
-	rtc_ds1386_init(KSEG1ADDR(DDB_LCS1_BASE));
+	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+		rtc_ds1386_init(KSEG1ADDR(DDB_LCS2_BASE));
+	} else {
+		rtc_ds1386_init(KSEG1ADDR(DDB_LCS1_BASE));
+	}
 }
 
-#if defined(CONFIG_LL_DEBUG)
-int  board_init_done_flag = 0;
-#endif
-
 extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
 static void __init ddb_timer_setup(struct irqaction *irq)
 {
@@ -115,9 +115,6 @@
 	setup_irq(SP_TIMER_IRQ, irq);
 
 #endif
-	
-	/* this is the last board dependent code */
-	MIPS_DEBUG(board_init_done_flag = 1);
 }
 
 static void ddb5477_board_init(void);
@@ -132,7 +129,7 @@
 	extern int panic_timeout;
 
 	irq_setup = ddb5477_irq_setup;
-	mips_io_port_base = KSEG1ADDR(DDB_PCI_IO_BASE);
+	set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
 
 	board_time_init = ddb_time_init;
 	board_timer_setup = ddb_timer_setup;
@@ -148,6 +145,10 @@
 	/* Reboot on panic */
 	panic_timeout = 180;
 
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
 	/* initialize board - we don't trust the loader */
 	ddb5477_board_init();
 
@@ -156,7 +157,6 @@
 	initrd_start = (unsigned long)&__rd_start;
 	initrd_end = (unsigned long)&__rd_end;
 #endif
-
 }
 
 static void __init ddb5477_board_init()
@@ -164,27 +164,41 @@
 	/* ----------- setup PDARs ------------ */
 
 	/* SDRAM should have been set */
-	MIPS_ASSERT(ddb_in32(DDB_SDRAM0) == 
-		    ddb_calc_pdar(DDB_SDRAM_BASE, DDB_SDRAM_SIZE, 32, 0, 1));
+	db_assert(ddb_in32(DDB_SDRAM0) == 
+		    ddb_calc_pdar(DDB_SDRAM_BASE, board_ram_size, 32, 0, 1));
 
 	/* SDRAM1 should be turned off.  What is this for anyway ? */
-	MIPS_ASSERT( (ddb_in32(DDB_SDRAM1) & 0xf) == 0);
+	db_assert( (ddb_in32(DDB_SDRAM1) & 0xf) == 0);
+
+	/* Setup local bus. */
 
-	/* Set LDCSs */
-	/* flash */
+	/* Flash U12 PDAR and timing. */
 	ddb_set_pdar(DDB_LCS0, DDB_LCS0_BASE, DDB_LCS0_SIZE, 16, 0, 0);
-	/* misc */
-	ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 8, 0, 0);
-	/* mezzanie (?) */
-	ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 16, 0, 0);
+	ddb_out32(DDB_LCST0, 0x00090842);
+
+	/* We need to setup LCS1 and LCS2 differently based on the
+	   board_version */
+	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+		/* Flash U13 PDAR and timing. */
+		ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 16, 0, 0);
+		ddb_out32(DDB_LCST1, 0x00090842);
+
+		/* EPLD (NVRAM, switch, LCD, and mezzanie). */
+		ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 8, 0, 0);
+	} else {
+		/* misc */
+		ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 8, 0, 0);
+		/* mezzanie (?) */
+		ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 16, 0, 0);
+	}
 
 	/* verify VRC5477 base addr */
-	MIPS_ASSERT(ddb_in32(DDB_VRC5477) == 
-		    ddb_calc_pdar(DDB_VRC5477_BASE, DDB_VRC5477_SIZE, 32, 0, 1));
+	db_assert(ddb_in32(DDB_VRC5477) == 
+		  ddb_calc_pdar(DDB_VRC5477_BASE, DDB_VRC5477_SIZE, 32, 0, 1));
 	
 	/* verify BOOT ROM addr */
-	MIPS_ASSERT(ddb_in32(DDB_BOOTCS) == 
-		    ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0));
+	db_assert(ddb_in32(DDB_BOOTCS) == 
+		  ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0));
 
 	/* setup PCI windows - window0 for MEM/config, window1 for IO */
 	ddb_set_pdar(DDB_PCIW0, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1);
@@ -248,4 +262,10 @@
 	/* For dual-function pins, make them all non-GPIO */
 	ddb_out32(DDB_GIUFUNSEL, 0x0);
 	// ddb_out32(DDB_GIUFUNSEL, 0xfe0fcfff);  /* NEC recommanded value */
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+		printk("lcd44780: initializing\n");
+		lcd44780_init();
+		lcd44780_puts("Linux/MIPS rolls");
+	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/Makefile linux/arch/mips/dec/Makefile
--- linux.orig/arch/mips/dec/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/dec/Makefile	2002-07-20 01:08:31.000000000 +0000
@@ -6,17 +6,15 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(AFLAGS) $< -o $@
-.S.o:
-	$(CC) $(AFLAGS) -c $< -o $@
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := dec.o
 
 all: dec.o
 
-export-objs := wbflush.o
-obj-y	 := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o
+export-objs := setup.o wbflush.o
+obj-y	 := int-handler.o ioasic-irq.o kn02-irq.o reset.o rtc-dec.o setup.o \
+	time.o wbflush.o
 
 obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/boot/Makefile linux/arch/mips/dec/boot/Makefile
--- linux.orig/arch/mips/dec/boot/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/dec/boot/Makefile	2002-07-20 01:08:38.000000000 +0000
@@ -6,10 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 netboot: all
 	mipsel-linux-ld -N -G 0 -T ld.ecoff ../../boot/zImage \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/int-handler.S linux/arch/mips/dec/int-handler.S
--- linux.orig/arch/mips/dec/int-handler.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/dec/int-handler.S	2002-07-20 01:08:26.000000000 +0000
@@ -2,7 +2,7 @@
  * arch/mips/dec/int-handler.S
  *
  * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
- * Copyright (C) 2000  Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2002  Maciej W. Rozycki
  *
  * Written by Ralf Baechle and Andreas Busse, modified for DECStation
  * support by Paul Antoine and Harald Koerfgen.
@@ -10,6 +10,8 @@
  * completly rewritten:
  * Copyright (C) 1998 Harald Koerfgen
  *
+ * Rewritten extensively for controller-driven IRQ support
+ * by Maciej W. Rozycki.
  */
 #include <asm/asm.h>
 #include <asm/regdef.h>
@@ -17,12 +19,13 @@
 #include <asm/stackframe.h>
 #include <asm/addrspace.h>
 
+#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/ioasic_ints.h>
 #include <asm/dec/kn01.h>
 #include <asm/dec/kn02.h>
 #include <asm/dec/kn02xa.h>
 #include <asm/dec/kn03.h>
-#include <asm/dec/ioasic_addrs.h>
-#include <asm/dec/interrupts.h>
 
 
 		.text
@@ -84,7 +87,7 @@
  *             4        TurboChannel Slot 2
  *             5        TurboChannel Slot 3 (ASIC)
  *             6        Halt button
- *             7        FPU
+ *             7        FPU/R4k timer
  *
  * DS5000/2x's, aka kn02ca, aka maxine:
  *
@@ -97,7 +100,7 @@
  *             4        I/O write timeout
  *             5        TurboChannel (ASIC)
  *             6        Halt Keycode from Access.Bus keyboard (CTRL-ALT-ENTER)
- *             7        FPU
+ *             7        FPU/R4k timer
  *
  * DS5000/2xx's, aka kn03, aka 3maxplus:
  *
@@ -110,22 +113,11 @@
  *             4        Reserved
  *             5        Memory
  *             6        Halt Button
- *             7        FPU
- *
- * We handle the IRQ according to _our_ priority.
- * Priority is:
- *
- * Highest ----     RTC
- *                  SCSI (if separate from TC)
- *                  Ethernet (if separate from TC)
- *		    Serial (if separate from TC)
- *                  TurboChannel (if there is one!)
- *                  Memory Controller (execept kmin)
- * Lowest  ----     Halt (if there is one!)
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
+ *             7        FPU/R4k timer
  *
+ * We handle the IRQ according to _our_ priority (see setup.c),
+ * then we just return.  If multiple IRQs are pending then we will
+ * just take another exception, big deal.
  */
 		.align	5
 		NESTED(decstation_handle_int, PT_SIZE, ra)
@@ -139,226 +131,157 @@
 		 * Get pending Interrupts
 		 */
 		mfc0	t0,CP0_CAUSE		# get pending interrupts
-		mfc0	t2,CP0_STATUS
-		la	t1,cpu_mask_tbl
-		and	t0,t2			# isolate allowed ones
+		mfc0	t1,CP0_STATUS
+		lw	t2,cpu_fpu_mask
+		andi	t0,ST0_IM		# CAUSE.CE may be non-zero!
+		and	t0,t1			# isolate allowed ones
 
 		beqz	t0,spurious
 
+		 and	t2,t0
+		bnez	t2,fpu			# handle FPU immediately
+
 		/*
 		 * Find irq with highest priority
 		 */
-1:		 lw	t2,(t1)
-		move	t3,t0
-		and	t3,t2
-		beq	t3,zero,1b
-		 addu	t1,PTRSIZE		# delay slot
+		 la	t1,cpu_mask_nr_tbl
+1:		lw	t2,(t1)
+		nop
+		and	t2,t0
+		beqz	t2,1b
+		 addu	t1,2*PTRSIZE		# delay slot
 
 		/*
 		 * Do the low-level stuff
 		 */
-		lw	a0,%lo(cpu_irq_nr-cpu_mask_tbl-PTRSIZE)(t1)
-		lw	t0,%lo(cpu_ivec_tbl-cpu_mask_tbl-PTRSIZE)(t1)
-		bgez	a0, handle_it		# irq_nr >= 0?
-						# irq_nr < 0: t0 contains an address
+		lw	a0,(-PTRSIZE)(t1)
+		nop
+		bgez	a0,handle_it		# irq_nr >= 0?
+						# irq_nr < 0: it is an address
 		 nop
-		jr	t0
-		 nop				# delay slot
+		jr	a0
+						# a trick to save a branch:
+		 lui	t2,KN03_IOASIC_BASE>>16	# upper part of IOASIC Address
 
 /*
  * Handle "IRQ Controller" Interrupts
  * Masked Interrupts are still visible and have to be masked "by hand".
  */
-		EXPORT(kn02_io_int)
-kn02_io_int:					# 3max
+		FEXPORT(kn02_io_int)		# 3max
 		lui	t0,KN02_CSR_ADDR>>16	# get interrupt status and mask
 		lw	t0,(t0)
-		la	t1,asic_mask_tbl
-		move	t3,t0
-		sll	t3,16			# shift interrupt status
-		b	find_int
-		 and	t0,t3			# mask out allowed ones
-
-		EXPORT(kn03_io_int)
-kn03_io_int:					# 3max+
-		lui	t2,KN03_IOASIC_BASE>>16	# upper part of IOASIC Address
-		lw	t0,SIR(t2)		# get status: IOASIC isr
-		lw	t3,SIMR(t2)		# get mask:   IOASIC isrm
-		la	t1,asic_mask_tbl
-		b	find_int
-		 and	t0,t3			# mask out allowed ones
-
-		EXPORT(kn02xa_io_int)
-kn02xa_io_int:					# 3min/maxine
-		lui	t2,KN02XA_IOASIC_BASE>>16		
-						# upper part of IOASIC Address
+		nop
+		andi	t1,t0,KN02_IRQ_ALL
+		b	1f
+		 srl	t0,16			# shift interrupt mask
+
+		FEXPORT(kn02xa_io_int)		# 3min/maxine
+		lui	t2,KN02XA_IOASIC_BASE>>16 # upper part of IOASIC Address
+
+		FEXPORT(kn03_io_int)		# 3max+ (t2 loaded earlier)
 		lw	t0,SIR(t2)		# get status: IOASIC isr
-		lw	t3,SIMR(t2)		# get mask:   IOASIC isrm
-		la	t1,asic_mask_tbl
-		and	t0,t3
+		lw	t1,SIMR(t2)		# get mask:   IOASIC isrm
+		nop
+
+1:		and	t0,t1			# mask out allowed ones
+
+		beqz	t0,spurious
 
 		/*
 		 * Find irq with highest priority
 		 */
-find_int:	beqz	t0,spurious
-
-1:		 lw	t2,(t1)
-		move	t3,t0
-		and	t3,t2
-		beq	zero,t3,1b
-		 addu	t1,PTRSIZE		# delay slot
+		 la	t1,asic_mask_nr_tbl
+2:		lw	t2,(t1)
+		nop
+		and	t2,t0
+		beq	zero,t2,2b
+		 addu	t1,2*PTRSIZE		# delay slot
 
 		/*
 		 * Do the low-level stuff
 		 */
-		lw	a0,%lo(asic_irq_nr-asic_mask_tbl-PTRSIZE)(t1)
-                nop
+		lw	a0,%lo(-PTRSIZE)(t1)
+		nop
+		bgez	a0,handle_it		# irq_nr >= 0?
+						# irq_nr < 0: it is an address
+		 nop
+		jr	a0
+		 nop				# delay slot
+
+/*
+ * Dispatch low-priority interrupts.  We reconsider all status
+ * bits again, which looks like a lose, but it makes the code
+ * simple and O(log n), so it gets compensated.
+ */
+		FEXPORT(cpu_all_int)		# HALT, timers, software junk
+		li	a0,DEC_CPU_IRQ_BASE
+		srl	t0,CAUSEB_IP
+		li	t1,CAUSEF_IP>>CAUSEB_IP	# mask
+		b	1f
+		 li	t2,4			# nr of bits / 2
+
+		FEXPORT(kn02_all_int)		# impossible ?
+		li	a0,KN02_IRQ_BASE
+		li	t1,KN02_IRQ_ALL		# mask
+		b	1f
+		 li	t2,4			# nr of bits / 2
+
+		FEXPORT(asic_all_int)		# various I/O ASIC junk
+		li	a0,IO_IRQ_BASE
+		li	t1,IO_IRQ_ALL		# mask
+		b	1f
+		 li	t2,8			# nr of bits / 2
+
+/*
+ * Dispatch DMA interrupts -- O(log n).
+ */
+		FEXPORT(asic_dma_int)		# I/O ASIC DMA events
+		li	a0,IO_IRQ_BASE+IO_INR_DMA
+		srl	t0,IO_INR_DMA
+		li	t1,IO_IRQ_DMA>>IO_INR_DMA # mask
+		li	t2,8			# nr of bits / 2
+		
+		/*
+		 * Find irq with highest priority.
+		 * Highest irq number takes precedence.
+		 */
+1:		srlv	t3,t1,t2
+2:		xor	t1,t3
+		and	t3,t0,t1
+		beqz	t3,3f
+		 nop
+		move	t0,t3
+		addu	a0,t2
+3:		srl	t2,1
+		bnez	t2,2b
+		 srlv	t3,t1,t2
 
-handle_it:	jal	do_IRQ
+handle_it:
+		jal	do_IRQ
 		 move	a1,sp
+
 		j	ret_from_irq
 		 nop
 
+fpu:
+		j	handle_fpe_int
+		 nop
+
 spurious:
 		j	spurious_interrupt
 		 nop
 		END(decstation_handle_int)
-/*
-  * Interrupt routines common to all DECStations first.
- */
-		EXPORT(dec_intr_fpu)
-dec_intr_fpu:	PANIC("Unimplemented FPU interrupt handler")
 
 /*
- * Generic unimplemented interrupt routines - ivec_tbl is initialised to
- * point all interrupts here.  The table is then filled in by machine-specific
- * initialisation in dec_setup().
+ * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
+ * and asic_mask_nr_tbl are initialized to point all interrupts here.
+ * The tables are then filled in by machine-specific initialisation
+ * in dec_setup().
  */
-		EXPORT(dec_intr_unimplemented)
-dec_intr_unimplemented:
-		mfc0	a1,CP0_CAUSE		# cheats way of printing an arg!
-		nop				# to be sure...
-		PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%x");
-
-		EXPORT(asic_intr_unimplemented)
-asic_intr_unimplemented:
+		FEXPORT(dec_intr_unimplemented)
 		move	a1,t0			# cheats way of printing an arg!
-		PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%x");
+		PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%08x");
 
-/*
- * FIXME: This interrupt vector table is experimental.  It is initialised with 
- *	  *_intr_unimplemented and filled in with the addresses of
- *	  machine-specific interrupt routines in dec_setup()  Paul 10/5/97.
- *
- *	  The mask_tbls contain the interrupt masks which are used. It is 
- *	  initialised with all possible interrupt status bits set, so that 
- * 	  unused Interrupts are catched.				Harald
- */
-		.data
-		EXPORT(cpu_mask_tbl)
-cpu_mask_tbl:
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000		# these two are unlikely 
-		.word	0x00000000		# to be used
-		.word	0x0000ff00		# End of list
-
-		EXPORT(cpu_irq_nr)
-cpu_irq_nr:
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000
-		.word	0x00000000		# these two are unlikely 
-		.word	0x00000000		# to be used
-		.word	0x00ffffff		# End of list
-
-		EXPORT(cpu_ivec_tbl)
-cpu_ivec_tbl:
-		PTR	dec_intr_unimplemented
-		PTR	dec_intr_unimplemented
-		PTR	dec_intr_unimplemented
-		PTR	dec_intr_unimplemented
-		PTR	dec_intr_unimplemented
-		PTR	dec_intr_unimplemented
-		PTR	dec_intr_unimplemented	# these two are unlikely
-		PTR	dec_intr_unimplemented	# to be used
-		PTR	dec_intr_unimplemented	# EOL
-
-		EXPORT(asic_mask_tbl)
-asic_mask_tbl:
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0xffffffff			# EOL
-
-		EXPORT(asic_irq_nr)
-asic_irq_nr:
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0
-		.word	0xffffffff		# EOL
+		FEXPORT(asic_intr_unimplemented)
+		move	a1,t0			# cheats way of printing an arg!
+		PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%08x");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/ioasic-irq.c linux/arch/mips/dec/ioasic-irq.c
--- linux.orig/arch/mips/dec/ioasic-irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/dec/ioasic-irq.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,160 @@
+/*
+ *	linux/arch/mips/dec/ioasic-irq.c
+ *
+ *	DEC I/O ASIC interrupts.
+ *
+ *	Copyright (c) 2002  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/ioasic_ints.h>
+
+
+static spinlock_t ioasic_lock = SPIN_LOCK_UNLOCKED;
+
+static int ioasic_irq_base;
+
+
+static inline void unmask_ioasic_irq(unsigned int irq)
+{
+	u32 simr;
+
+	simr = ioasic_read(SIMR);
+	simr |= (1 << (irq - ioasic_irq_base));
+	ioasic_write(SIMR, simr);
+}
+
+static inline void mask_ioasic_irq(unsigned int irq)
+{
+	u32 simr;
+
+	simr = ioasic_read(SIMR);
+	simr &= ~(1 << (irq - ioasic_irq_base));
+	ioasic_write(SIMR, simr);
+}
+
+static inline void clear_ioasic_irq(unsigned int irq)
+{
+	u32 sir;
+
+	sir = ~(1 << (irq - ioasic_irq_base));
+	ioasic_write(SIR, sir);
+}
+
+static inline void enable_ioasic_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioasic_lock, flags);
+	unmask_ioasic_irq(irq);
+	spin_unlock_irqrestore(&ioasic_lock, flags);
+}
+
+static inline void disable_ioasic_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioasic_lock, flags);
+	mask_ioasic_irq(irq);
+	spin_unlock_irqrestore(&ioasic_lock, flags);
+}
+
+
+static inline unsigned int startup_ioasic_irq(unsigned int irq)
+{
+	enable_ioasic_irq(irq);
+	return 0;
+}
+
+#define shutdown_ioasic_irq disable_ioasic_irq
+
+static inline void ack_ioasic_irq(unsigned int irq)
+{
+	spin_lock(&ioasic_lock);
+	mask_ioasic_irq(irq);
+	spin_unlock(&ioasic_lock);
+}
+
+static inline void end_ioasic_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_ioasic_irq(irq);
+}
+
+#define set_ioasic_affinity NULL
+
+static struct hw_interrupt_type ioasic_irq_type = {
+	"IO-ASIC",
+	startup_ioasic_irq,
+	shutdown_ioasic_irq,
+	enable_ioasic_irq,
+	disable_ioasic_irq,
+	ack_ioasic_irq,
+	end_ioasic_irq,
+	set_ioasic_affinity,
+};
+
+
+#define startup_ioasic_dma_irq startup_ioasic_irq
+
+#define shutdown_ioasic_dma_irq shutdown_ioasic_irq
+
+#define enable_ioasic_dma_irq enable_ioasic_irq
+
+#define disable_ioasic_dma_irq disable_ioasic_irq
+
+#define ack_ioasic_dma_irq ack_ioasic_irq
+
+static inline void end_ioasic_dma_irq(unsigned int irq)
+{
+	clear_ioasic_irq(irq);
+	end_ioasic_irq(irq);
+}
+
+#define set_ioasic_dma_affinity set_ioasic_affinity
+
+static struct hw_interrupt_type ioasic_dma_irq_type = {
+	"IO-ASIC-DMA",
+	startup_ioasic_dma_irq,
+	shutdown_ioasic_dma_irq,
+	enable_ioasic_dma_irq,
+	disable_ioasic_dma_irq,
+	ack_ioasic_dma_irq,
+	end_ioasic_dma_irq,
+	set_ioasic_dma_affinity,
+};
+
+
+void __init init_ioasic_irqs(int base)
+{
+	int i;
+
+	/* Mask interrupts. */
+	ioasic_write(SIMR, 0);
+
+	for (i = base; i < base + IO_INR_DMA; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &ioasic_irq_type;
+	}
+	for (; i < base + IO_IRQ_LINES; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &ioasic_dma_irq_type;
+	}
+
+	ioasic_irq_base = base;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/irq.c linux/arch/mips/dec/irq.c
--- linux.orig/arch/mips/dec/irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/dec/irq.c	2002-07-20 01:08:22.000000000 +0000
@@ -19,7 +19,6 @@
 #include <asm/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
@@ -34,48 +33,52 @@
 
 extern asmlinkage void decstation_handle_int(void);
 
-unsigned long spurious_count = 0;
+atomic_t irq_err_count;
 
 static inline void mask_irq(unsigned int irq_nr)
 {
-    unsigned int dummy;
+	unsigned int dummy;
 
-    if (dec_interrupt[irq_nr].iemask) {		/* This is an ASIC interrupt    */
-	*imr &= ~dec_interrupt[irq_nr].iemask;
-	dummy = *imr;
-	dummy = *imr;
-    } else			/* This is a cpu interrupt        */
-	change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) & ~dec_interrupt[irq_nr].cpu_mask);
+	if (dec_interrupt[irq_nr].iemask) {	/* This is an ASIC interrupt    */
+		*imr &= ~dec_interrupt[irq_nr].iemask;
+		dummy = *imr;
+		dummy = *imr;
+	} else			/* This is a cpu interrupt        */
+		change_cp0_status(ST0_IM,
+				  read_32bit_cp0_register(CP0_STATUS) &
+				  ~dec_interrupt[irq_nr].cpu_mask);
 }
 
 static inline void unmask_irq(unsigned int irq_nr)
 {
-    unsigned int dummy;
+	unsigned int dummy;
 
-    if (dec_interrupt[irq_nr].iemask) {		/* This is an ASIC interrupt    */
-	*imr |= dec_interrupt[irq_nr].iemask;
-	dummy = *imr;
-	dummy = *imr;
-    }
-    change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) | dec_interrupt[irq_nr].cpu_mask);
+	if (dec_interrupt[irq_nr].iemask) {	/* This is an ASIC interrupt    */
+		*imr |= dec_interrupt[irq_nr].iemask;
+		dummy = *imr;
+		dummy = *imr;
+	}
+	change_cp0_status(ST0_IM,
+			  read_32bit_cp0_register(CP0_STATUS) |
+			  dec_interrupt[irq_nr].cpu_mask);
 }
 
 void disable_irq(unsigned int irq_nr)
 {
-    unsigned long flags;
+	unsigned long flags;
 
-    save_and_cli(flags);
-    mask_irq(irq_nr);
-    restore_flags(flags);
+	save_and_cli(flags);
+	mask_irq(irq_nr);
+	restore_flags(flags);
 }
 
 void enable_irq(unsigned int irq_nr)
 {
-    unsigned long flags;
+	unsigned long flags;
 
-    save_and_cli(flags);
-    unmask_irq(irq_nr);
-    restore_flags(flags);
+	save_and_cli(flags);
+	unmask_irq(irq_nr);
+	restore_flags(flags);
 }
 
 /*
@@ -84,35 +87,35 @@
  */
 extern void interrupt(void);
 
-static struct irqaction *irq_action[32] =
-{
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+static struct irqaction *irq_action[32] = {
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
 int get_irq_list(char *buf)
 {
-    int i, len = 0;
-    struct irqaction *action;
+	int i, len = 0;
+	struct irqaction *action;
 
-    for (i = 0; i < 32; i++) {
-	action = irq_action[i];
-	if (!action)
-	    continue;
-	len += sprintf(buf + len, "%2d: %8d %c %s",
-		       i, kstat.irqs[0][i],
-		       (action->flags & SA_INTERRUPT) ? '+' : ' ',
-		       action->name);
-	for (action = action->next; action; action = action->next) {
-	    len += sprintf(buf + len, ",%s %s",
-			   (action->flags & SA_INTERRUPT) ? " +" : "",
-			   action->name);
+	for (i = 0; i < 32; i++) {
+		action = irq_action[i];
+		if (!action)
+			continue;
+		len += sprintf(buf + len, "%2d: %8d %c %s",
+			       i, kstat.irqs[0][i],
+			       (action->flags & SA_INTERRUPT) ? '+' : ' ',
+			       action->name);
+		for (action = action->next; action; action = action->next) {
+			len += sprintf(buf + len, ",%s %s",
+				       (action->
+					flags & SA_INTERRUPT) ? " +" : "",
+				       action->name);
+		}
+		len += sprintf(buf + len, "\n");
 	}
-	len += sprintf(buf + len, "\n");
-    }
-    return len;
+	return len;
 }
 
 /*
@@ -124,33 +127,34 @@
  */
 asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
 {
-    struct irqaction *action;
-    int do_random, cpu;
+	struct irqaction *action;
+	int do_random, cpu;
 
-    cpu = smp_processor_id();
-    irq_enter(cpu, irq);
-    kstat.irqs[cpu][irq]++;
-
-    mask_irq(irq);
-    action = *(irq + irq_action);
-    if (action) {
-	if (!(action->flags & SA_INTERRUPT))
-	    __sti();
+	cpu = smp_processor_id();
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+
+	mask_irq(irq);
 	action = *(irq + irq_action);
-	do_random = 0;
-	do {
-	    do_random |= action->flags;
-	    action->handler(irq, action->dev_id, regs);
-	    action = action->next;
-	} while (action);
-	if (do_random & SA_SAMPLE_RANDOM)
-	    add_interrupt_randomness(irq);
-	__cli();
-	unmask_irq(irq);
-    }
-    irq_exit(cpu, irq);
+	if (action) {
+		if (!(action->flags & SA_INTERRUPT))
+			__sti();
+		action = *(irq + irq_action);
+		do_random = 0;
+		do {
+			do_random |= action->flags;
+			action->handler(irq, action->dev_id, regs);
+			action = action->next;
+		} while (action);
+		if (do_random & SA_SAMPLE_RANDOM)
+			add_interrupt_randomness(irq);
+		__cli();
+		unmask_irq(irq);
+	}
+	irq_exit(cpu, irq);
 
-    /* unmasking and bottom half handling is done magically for us. */
+	if (softirq_pending(cpu))
+		do_softirq();
 }
 
 /*
@@ -159,139 +163,145 @@
  */
 int setup_dec_irq(int irq, struct irqaction *new)
 {
-    int shared = 0;
-    struct irqaction *old, **p;
-    unsigned long flags;
-
-    p = irq_action + irq;
-    if ((old = *p) != NULL) {
-	/* Can't share interrupts unless both agree to */
-	if (!(old->flags & new->flags & SA_SHIRQ))
-	    return -EBUSY;
-
-	/* Can't share interrupts unless both are same type */
-	if ((old->flags ^ new->flags) & SA_INTERRUPT)
-	    return -EBUSY;
-
-	/* add new interrupt at end of irq queue */
-	do {
-	    p = &old->next;
-	    old = *p;
-	} while (old);
-	shared = 1;
-    }
-    if (new->flags & SA_SAMPLE_RANDOM)
-	rand_initialize_irq(irq);
-
-    save_and_cli(flags);
-    *p = new;
-
-    if (!shared) {
-	unmask_irq(irq);
-    }
-    restore_flags(flags);
-    return 0;
+	int shared = 0;
+	struct irqaction *old, **p;
+	unsigned long flags;
+
+	p = irq_action + irq;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ))
+			return -EBUSY;
+
+		/* Can't share interrupts unless both are same type */
+		if ((old->flags ^ new->flags) & SA_INTERRUPT)
+			return -EBUSY;
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+	if (new->flags & SA_SAMPLE_RANDOM)
+		rand_initialize_irq(irq);
+
+	save_and_cli(flags);
+	*p = new;
+
+	if (!shared) {
+		unmask_irq(irq);
+	}
+	restore_flags(flags);
+	return 0;
 }
 
 int request_irq(unsigned int irq,
 		void (*handler) (int, void *, struct pt_regs *),
-		unsigned long irqflags,
-		const char *devname,
-		void *dev_id)
-{
-    int retval;
-    struct irqaction *action;
-
-    if (irq >= 32)
-	return -EINVAL;
-    if (!handler)
-	return -EINVAL;
-
-    action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-    if (!action)
-	return -ENOMEM;
-
-    action->handler = handler;
-    action->flags = irqflags;
-    action->mask = 0;
-    action->name = devname;
-    action->next = NULL;
-    action->dev_id = dev_id;
-
-    retval = setup_dec_irq(irq, action);
-
-    if (retval)
-	kfree(action);
-    return retval;
+		unsigned long irqflags, const char *devname, void *dev_id)
+{
+	int retval;
+	struct irqaction *action;
+
+	if (irq >= 32)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action =
+	    (struct irqaction *) kmalloc(sizeof(struct irqaction),
+					 GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_dec_irq(irq, action);
+
+	if (retval)
+		kfree(action);
+	return retval;
 }
 
 void free_irq(unsigned int irq, void *dev_id)
 {
-    struct irqaction *action, **p;
-    unsigned long flags;
-
-    if (irq > 39) {
-	printk("Trying to free IRQ%d\n", irq);
-	return;
-    }
-    for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
-	if (action->dev_id != dev_id)
-	    continue;
+	struct irqaction *action, **p;
+	unsigned long flags;
 
-	/* Found it - now free it */
-	save_and_cli(flags);
-	*p = action->next;
-	if (!irq[irq_action])
-	    mask_irq(irq);
-	restore_flags(flags);
-	kfree(action);
-	return;
-    }
-    printk("Trying to free free IRQ%d\n", irq);
+	if (irq > 39) {
+		printk("Trying to free IRQ%d\n", irq);
+		return;
+	}
+	for (p = irq + irq_action; (action = *p) != NULL;
+	     p = &action->next) {
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* Found it - now free it */
+		save_and_cli(flags);
+		*p = action->next;
+		if (!irq[irq_action])
+			mask_irq(irq);
+		restore_flags(flags);
+		kfree(action);
+		return;
+	}
+	printk("Trying to free free IRQ%d\n", irq);
 }
 
 unsigned long probe_irq_on(void)
 {
-    /* TODO */
-    return 0;
+	/* TODO */
+	return 0;
 }
 
 int probe_irq_off(unsigned long irqs)
 {
-    /* TODO */
-    return 0;
+	/* TODO */
+	return 0;
+}
+
+void init_irq_proc(void)
+{
+	/* Nothing, for now.  */
 }
 
 void __init init_IRQ(void)
 {
-    switch (mips_machtype) {
-    case MACH_DS23100:
-	dec_init_kn01();
-	break;
-    case MACH_DS5100:		/*  DS5100 MIPSMATE */
-	dec_init_kn230();
-	break;
-    case MACH_DS5000_200:	/* DS5000 3max */
-	dec_init_kn02();
-	break;
-    case MACH_DS5000_1XX:	/* DS5000/100 3min */
-	dec_init_kn02ba();
-	break;
-    case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
-	dec_init_kn03();
-	break;
-    case MACH_DS5000_XX:	/* Personal DS5000/2x */
-	dec_init_kn02ca();
-	break;
-    case MACH_DS5800:		/* DS5800 Isis */
-	panic("Don't know how to set this up!");
-	break;
-    case MACH_DS5400:		/* DS5400 MIPSfair */
-	panic("Don't know how to set this up!");
-	break;
-    case MACH_DS5500:		/* DS5500 MIPSfair-2 */
-	panic("Don't know how to set this up!");
-	break;
-    }
-    set_except_vector(0, decstation_handle_int);
+	switch (mips_machtype) {
+	case MACH_DS23100:
+		dec_init_kn01();
+		break;
+	case MACH_DS5100:	/*  DS5100 MIPSMATE */
+		dec_init_kn230();
+		break;
+	case MACH_DS5000_200:	/* DS5000 3max */
+		dec_init_kn02();
+		break;
+	case MACH_DS5000_1XX:	/* DS5000/100 3min */
+		dec_init_kn02ba();
+		break;
+	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+		dec_init_kn03();
+		break;
+	case MACH_DS5000_XX:	/* Personal DS5000/2x */
+		dec_init_kn02ca();
+		break;
+	case MACH_DS5800:	/* DS5800 Isis */
+		panic("Don't know how to set this up!");
+		break;
+	case MACH_DS5400:	/* DS5400 MIPSfair */
+		panic("Don't know how to set this up!");
+		break;
+	case MACH_DS5500:	/* DS5500 MIPSfair-2 */
+		panic("Don't know how to set this up!");
+		break;
+	}
+	set_except_vector(0, decstation_handle_int);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/kn02-irq.c linux/arch/mips/dec/kn02-irq.c
--- linux.orig/arch/mips/dec/kn02-irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/dec/kn02-irq.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,125 @@
+/*
+ *	linux/arch/mips/dec/kn02-irq.c
+ *
+ *	DECstation 5000/200 (KN02) Control and Status Register
+ *	interrupts.
+ *
+ *	Copyright (c) 2002  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/dec/kn02.h>
+
+
+/*
+ * Bits 7:0 of the Control Register are write-only -- the
+ * corresponding bits of the Status Register have a different
+ * meaning.  Hence we use a cache.  It speeds up things a bit
+ * as well.
+ *
+ * There is no default value -- it has to be initialized.
+ */
+u32 cached_kn02_csr;
+spinlock_t kn02_lock = SPIN_LOCK_UNLOCKED;
+
+
+static int kn02_irq_base;
+
+
+static inline void unmask_kn02_irq(unsigned int irq)
+{
+	volatile u32 *csr = (volatile u32 *)KN02_CSR_ADDR;
+
+	cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16));
+	*csr = cached_kn02_csr;
+}
+
+static inline void mask_kn02_irq(unsigned int irq)
+{
+	volatile u32 *csr = (volatile u32 *)KN02_CSR_ADDR;
+
+	cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16));
+	*csr = cached_kn02_csr;
+}
+
+static inline void enable_kn02_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kn02_lock, flags);
+	unmask_kn02_irq(irq);
+	spin_unlock_irqrestore(&kn02_lock, flags);
+}
+
+static inline void disable_kn02_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kn02_lock, flags);
+	mask_kn02_irq(irq);
+	spin_unlock_irqrestore(&kn02_lock, flags);
+}
+
+
+static unsigned int startup_kn02_irq(unsigned int irq)
+{
+	enable_kn02_irq(irq);
+	return 0;
+}
+
+#define shutdown_kn02_irq disable_kn02_irq
+
+static void ack_kn02_irq(unsigned int irq)
+{
+	spin_lock(&kn02_lock);
+	mask_kn02_irq(irq);
+	spin_unlock(&kn02_lock);
+}
+
+static void end_kn02_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_kn02_irq(irq);
+}
+
+#define set_kn02_affinity NULL
+
+static struct hw_interrupt_type kn02_irq_type = {
+	"KN02-CSR",
+	startup_kn02_irq,
+	shutdown_kn02_irq,
+	enable_kn02_irq,
+	disable_kn02_irq,
+	ack_kn02_irq,
+	end_kn02_irq,
+	set_kn02_affinity,
+};
+
+
+void __init init_kn02_irqs(int base)
+{
+	volatile u32 *csr = (volatile u32 *)KN02_CSR_ADDR;
+	int i;
+
+	/* Mask interrupts and preset write-only bits. */
+	cached_kn02_csr = (*csr & ~0xff0000) | 0xff;
+	*csr = cached_kn02_csr;
+
+	for (i = base; i < base + KN02_IRQ_LINES; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &kn02_irq_type;
+	}
+
+	kn02_irq_base = base;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/prom/Makefile linux/arch/mips/dec/prom/Makefile
--- linux.orig/arch/mips/dec/prom/Makefile	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/dec/prom/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.1 1999/01/17 03:49:44 ralf Exp $
+#
 # Makefile for the DECstation prom monitor library routines
 # under Linux.
 #
@@ -8,22 +8,10 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-OBJS  = init.o memory.o cmdline.o identify.o locore.o
-
-all: 	rexlib.a
-
-rexlib.a: $(OBJS)
-	$(AR) rcs rexlib.a $(OBJS)
-	sync
+USE_STANDARD_AS_RULE := true
 
-locore.o: locore.S
+L_TARGET  = rexlib.a
 
-dep:
-	$(CPP) $(CPPFLAGS) -M *.c > .depend
+obj-y +=  init.o memory.o cmdline.o identify.o locore.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/prom/cmdline.c linux/arch/mips/dec/prom/cmdline.c
--- linux.orig/arch/mips/dec/prom/cmdline.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/dec/prom/cmdline.c	2002-07-20 01:08:29.000000000 +0000
@@ -17,7 +17,7 @@
 extern int (*prom_printf)(char *, ...);
 #endif
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
 
 void __init prom_init_cmdline(int argc, char **argv, unsigned long magic)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/prom/identify.c linux/arch/mips/dec/prom/identify.c
--- linux.orig/arch/mips/dec/prom/identify.c	2000-02-28 15:18:20.000000000 +0000
+++ linux/arch/mips/dec/prom/identify.c	2002-07-20 01:08:33.000000000 +0000
@@ -2,8 +2,6 @@
  * identify.c: machine identification code.
  *
  * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
- *
- * $Id: identify.c,v 1.2 1999/10/09 00:00:58 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -21,6 +19,26 @@
 extern unsigned long mips_machgroup;
 extern unsigned long mips_machtype;
 
+extern unsigned long mips_machtype;
+const char *get_system_type(void)
+{ 
+	static char system[32];
+	int called = 0;
+	const char *dec_system_strings[] = { "unknown", "DECstation 2100/3100",
+        	"DECstation 5100", "DECstation 5000/200", "DECstation 5000/1xx",
+		"Personal DECstation 5000/xx", "DECstation 5000/2x0",
+		"DECstation 5400", "DECstation 5500", "DECstation 5800"
+	};
+
+	if (called == 0) {
+		called = 1;
+		strcpy(system, "Digital ");
+		strcat(system, dec_system_strings[mips_machtype]);
+	}
+
+	return system;
+}
+
 void __init prom_identify_arch (unsigned int magic)
 {
 	unsigned char dec_cpunum, dec_firmrev, dec_etc;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/prom/memory.c linux/arch/mips/dec/prom/memory.c
--- linux.orig/arch/mips/dec/prom/memory.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/dec/prom/memory.c	2002-07-20 01:08:21.000000000 +0000
@@ -3,8 +3,6 @@
  *
  * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine
  * Copyright (C) 2000 Maciej W. Rozycki
- *
- * $Id: memory.c,v 1.3 1999/10/09 00:00:58 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/config.h>
@@ -118,7 +116,7 @@
 	 * the first page reserved for the exception handlers.
 	 */
 
-#ifdef CONFIG_DECLANCE
+#if defined(CONFIG_DECLANCE) || defined(CONFIG_DECLANCE_MODULE)
 	/*
 	 * Leave 128 KB reserved for Lance memory for
 	 * IOASIC DECstations.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/promcon.c linux/arch/mips/dec/promcon.c
--- linux.orig/arch/mips/dec/promcon.c	2000-10-12 21:20:48.000000000 +0000
+++ linux/arch/mips/dec/promcon.c	2002-07-20 01:08:38.000000000 +0000
@@ -30,11 +30,6 @@
     }
 }
 
-static int prom_console_wait_key(struct console *co)
-{
-    return prom_getchar();
-}
-
 static int __init prom_console_setup(struct console *co, char *options)
 {
     return 0;
@@ -50,7 +45,6 @@
     name:	"ttyS",
     write:	prom_console_write,
     device:	prom_console_device,
-    wait_key:	prom_console_wait_key,
     setup:	prom_console_setup,
     flags:	CON_PRINTBUFFER,
     index:	-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/reset.c linux/arch/mips/dec/reset.c
--- linux.orig/arch/mips/dec/reset.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/dec/reset.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,8 +1,5 @@
 /*
- *  $Id: $
- *
- *  Reset a DECstation machine.
- *
+ * Reset a DECstation machine.
  */
 
 void (*back_to_prom)(void) = (void (*)(void))0xBFC00000;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/setup.c linux/arch/mips/dec/setup.c
--- linux.orig/arch/mips/dec/setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/dec/setup.c	2002-07-20 01:08:33.000000000 +0000
@@ -6,478 +6,758 @@
  * for more details.
  *
  * Copyright (C) 1998 Harald Koerfgen
- * Copyright (C) 2000 Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2002  Maciej W. Rozycki
  */
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/param.h>
 #include <linux/console.h>
-#include <asm/mipsregs.h>
-#include <asm/bootinfo.h>
 #include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
 #include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
 #include <asm/reboot.h>
+#include <asm/traps.h>
 
 #include <asm/dec/interrupts.h>
 #include <asm/dec/kn01.h>
 #include <asm/dec/kn02.h>
-#include <asm/dec/kn02xa.h>
+#include <asm/dec/kn02ba.h>
+#include <asm/dec/kn02ca.h>
 #include <asm/dec/kn03.h>
+#include <asm/dec/kn230.h>
 #include <asm/dec/ioasic.h>
 #include <asm/dec/ioasic_addrs.h>
 #include <asm/dec/ioasic_ints.h>
 
 
-char *dec_rtc_base = (void *) KN01_RTC_BASE;	/* Assume DS2100/3100 initially */
+extern void dec_machine_restart(char *command);
+extern void dec_machine_halt(void);
+extern void dec_machine_power_off(void);
+extern void dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
+
+extern asmlinkage void decstation_handle_int(void);
 
-volatile unsigned int *ioasic_base;
 
-decint_t dec_interrupt[NR_INTS];
+char *dec_rtc_base = (void *) KN01_RTC_BASE; /* Assume DS2100/3100 initially */
+
+volatile u32 *ioasic_base;
 
 /*
- * Information regarding the IRQ Controller
+ * IRQ routing and priority tables.  Priorites are set as follows:
+ *
+ * 		KN01	KN230	KN02	KN02-BA	KN02-CA	KN03
+ *
+ * MEMORY	CPU	CPU	CPU	ASIC	CPU	CPU
+ * RTC		CPU	CPU	CPU	ASIC	CPU	CPU
+ * DMA		-	-	-	ASIC	ASIC	ASIC
+ * SERIAL0	CPU	CPU	CSR	ASIC	ASIC	ASIC
+ * SERIAL1	-	-	-	ASIC	-	ASIC
+ * SCSI		CPU	CPU	CSR	ASIC	ASIC	ASIC
+ * ETHERNET	CPU	*	CSR	ASIC	ASIC	ASIC
+ * other	-	-	-	ASIC	-	-
+ * TC2		-	-	CSR	CPU	ASIC	ASIC
+ * TC1		-	-	CSR	CPU	ASIC	ASIC
+ * TC0		-	-	CSR	CPU	ASIC	ASIC
+ * other	-	CPU	-	CPU	ASIC	ASIC
+ * other	-	-	-	-	CPU	CPU
+ *
+ * * -- shared with SCSI
  */
+ 
+int dec_interrupt[DEC_NR_INTS] = {
+	[0 ... DEC_NR_INTS - 1] = -1
+};
+int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2] = {
+	{ { i: ~0 }, { p: dec_intr_unimplemented } },
+};
+int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2] = {
+	{ { i: ~0 }, { p: asic_intr_unimplemented } },
+};
+int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU);
 
-volatile unsigned int *isr = 0L;	/* address of the interrupt status register     */
-volatile unsigned int *imr = 0L;	/* address of the interrupt mask register       */
+static struct irqaction ioirq = {NULL, 0, 0, "cascade", NULL, NULL};
+static struct irqaction fpuirq = {NULL, 0, 0, "fpu", NULL, NULL};
+
+static struct irqaction haltirq = {dec_intr_halt, 0, 0, "halt", NULL, NULL};
 
-extern void dec_machine_restart(char *command);
-extern void dec_machine_halt(void);
-extern void dec_machine_power_off(void);
-extern void dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
 
 extern void wbflush_setup(void);
 
 extern struct rtc_ops dec_rtc_ops;
 
-extern int setup_dec_irq(int, struct irqaction *);
-
 void (*board_time_init) (struct irqaction * irq);
 
-static struct irqaction irq10 = {dec_intr_halt, 0, 0, "halt", NULL, NULL};
 
 /*
  * enable the periodic interrupts
  */
 static void __init dec_time_init(struct irqaction *irq)
 {
-    /*
-     * Here we go, enable periodic rtc interrupts.
-     */
+	/*
+	* Here we go, enable periodic rtc interrupts.
+	*/
 
 #ifndef LOG_2_HZ
 #  define LOG_2_HZ 7
 #endif
 
-    CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A);
-    CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B);
-    setup_dec_irq(CLOCK, irq);
+	CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A);
+	CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B);
+	setup_irq(dec_interrupt[DEC_IRQ_RTC], irq);
 }
 
+
 /*
- * Enable the halt interrupt.
+ * Bus error (DBE/IBE exceptions and memory interrupts) handling
+ * setup.  Nothing for now.
  */
-static void __init dec_halt_init(struct irqaction *irq)
+void __init bus_error_init(void)
 {
-    setup_dec_irq(HALT, irq);
 }
 
+
 void __init decstation_setup(void)
 {
-    board_time_init = dec_time_init;
+	board_time_init = dec_time_init;
 
-    wbflush_setup();
+	wbflush_setup();
 
-    _machine_restart = dec_machine_restart;
-    _machine_halt = dec_machine_halt;
-    _machine_power_off = dec_machine_power_off;
+	_machine_restart = dec_machine_restart;
+	_machine_halt = dec_machine_halt;
+	_machine_power_off = dec_machine_power_off;
 
 #ifdef CONFIG_FB
-    conswitchp = &dummy_con;
+	conswitchp = &dummy_con;
 #endif
 
-    rtc_ops = &dec_rtc_ops;
+	rtc_ops = &dec_rtc_ops;
 }
 
+
 /*
- * Machine-specific initialisation for kn01, aka Pmax, aka DS2100, DS3100,
- * and possibly also the DS5100.
+ * Machine-specific initialisation for KN01, aka DS2100 (aka Pmin)
+ * or DS3100 (aka Pmax).
  */
+static int kn01_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= -1,
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11),
+	[DEC_IRQ_ASC]		= -1,
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= -1,
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE),
+	[DEC_IRQ_MEMORY]	= DEC_CPU_IRQ_NR(KN01_CPU_INR_MEMORY),
+	[DEC_IRQ_PSU]		= -1,
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= -1,
+	[DEC_IRQ_SCC1]		= -1,
+	[DEC_IRQ_SII]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_SII),
+	[DEC_IRQ_TC0]		= -1,
+	[DEC_IRQ_TC1]		= -1,
+	[DEC_IRQ_TC2]		= -1,
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_VIDEO),
+	[DEC_IRQ_ASC_MERR]	= -1,
+	[DEC_IRQ_ASC_ERR]	= -1,
+	[DEC_IRQ_ASC_DMA]	= -1,
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= -1,
+	[DEC_IRQ_SCC0A_RXERR]	= -1,
+	[DEC_IRQ_SCC0A_RXDMA]	= -1,
+	[DEC_IRQ_SCC0A_TXERR]	= -1,
+	[DEC_IRQ_SCC0A_TXDMA]	= -1,
+	[DEC_IRQ_SCC0B_RXERR]	= -1,
+	[DEC_IRQ_SCC0B_RXDMA]	= -1,
+	[DEC_IRQ_SCC0B_TXERR]	= -1,
+	[DEC_IRQ_SCC0B_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= -1,
+	[DEC_IRQ_SCC1A_RXDMA]	= -1,
+	[DEC_IRQ_SCC1A_TXERR]	= -1,
+	[DEC_IRQ_SCC1A_TXDMA]	= -1,
+};
+
+static int_ptr kn01_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_MEMORY) },
+		{ i: DEC_CPU_IRQ_NR(KN01_CPU_INR_MEMORY) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_RTC) },
+		{ i: DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_DZ11) },
+		{ i: DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_SII) },
+		{ i: DEC_CPU_IRQ_NR(KN01_CPU_INR_SII) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN01_CPU_INR_LANCE) },
+		{ i: DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE) } },
+	{ { i: DEC_CPU_IRQ_ALL },
+		{ p: cpu_all_int } },
+};
+
 void __init dec_init_kn01(void)
 {
-    /*
-     * Setup some memory addresses.
-     */
-    dec_rtc_base = (char *) KN01_RTC_BASE;
-
-    /*
-     * Setup interrupt structure
-     */
-    dec_interrupt[CLOCK].cpu_mask = IE_IRQ3;
-    dec_interrupt[CLOCK].iemask = 0;
-    cpu_mask_tbl[0] = IE_IRQ3;
-    cpu_irq_nr[0] = CLOCK;
-
-    dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0;
-    dec_interrupt[SCSI_INT].iemask = 0;
-    cpu_mask_tbl[1] = IE_IRQ0;
-    cpu_irq_nr[1] = SCSI_INT;
-
-    dec_interrupt[ETHER].cpu_mask = IE_IRQ1;
-    dec_interrupt[ETHER].iemask = 0;
-    cpu_mask_tbl[2] = IE_IRQ1;
-    cpu_irq_nr[2] = ETHER;
-
-    dec_interrupt[SERIAL].cpu_mask = IE_IRQ2;
-    dec_interrupt[SERIAL].iemask = 0;
-    cpu_mask_tbl[3] = IE_IRQ2;
-    cpu_irq_nr[3] = SERIAL;
-
-    dec_interrupt[MEMORY].cpu_mask = IE_IRQ4;
-    dec_interrupt[MEMORY].iemask = 0;
-    cpu_mask_tbl[4] = IE_IRQ4;
-    cpu_irq_nr[4] = MEMORY;
-
-    dec_interrupt[FPU].cpu_mask = IE_IRQ5;
-    dec_interrupt[FPU].iemask = 0;
-    cpu_mask_tbl[5] = IE_IRQ5;
-    cpu_irq_nr[5] = FPU;
+	/* Setup some memory addresses. */
+	dec_rtc_base = (char *) KN01_RTC_BASE;
+
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn01_interrupt,
+		sizeof(kn01_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn01_cpu_mask_nr_tbl,
+		sizeof(kn01_cpu_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+
 }				/* dec_init_kn01 */
 
+
 /*
- * Machine-specific initialisation for kn230, aka MIPSmate, aka DS5100
- *
- * There are a lot of experiments to do, this is definitely incomplete.
+ * Machine-specific initialisation for KN230, aka DS5100, aka MIPSmate.
  */
+static int kn230_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= -1,
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11),
+	[DEC_IRQ_ASC]		= -1,
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_HALT),
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_LANCE),
+	[DEC_IRQ_MEMORY]	= DEC_CPU_IRQ_NR(KN230_CPU_INR_MEMORY),
+	[DEC_IRQ_PSU]		= -1,
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= -1,
+	[DEC_IRQ_SCC1]		= -1,
+	[DEC_IRQ_SII]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_SII),
+	[DEC_IRQ_TC0]		= -1,
+	[DEC_IRQ_TC1]		= -1,
+	[DEC_IRQ_TC2]		= -1,
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= -1,
+	[DEC_IRQ_ASC_MERR]	= -1,
+	[DEC_IRQ_ASC_ERR]	= -1,
+	[DEC_IRQ_ASC_DMA]	= -1,
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= -1,
+	[DEC_IRQ_SCC0A_RXERR]	= -1,
+	[DEC_IRQ_SCC0A_RXDMA]	= -1,
+	[DEC_IRQ_SCC0A_TXERR]	= -1,
+	[DEC_IRQ_SCC0A_TXDMA]	= -1,
+	[DEC_IRQ_SCC0B_RXERR]	= -1,
+	[DEC_IRQ_SCC0B_RXDMA]	= -1,
+	[DEC_IRQ_SCC0B_TXERR]	= -1,
+	[DEC_IRQ_SCC0B_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= -1,
+	[DEC_IRQ_SCC1A_RXDMA]	= -1,
+	[DEC_IRQ_SCC1A_TXERR]	= -1,
+	[DEC_IRQ_SCC1A_TXDMA]	= -1,
+};
+
+static int_ptr kn230_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { i: DEC_CPU_IRQ_MASK(KN230_CPU_INR_MEMORY) },
+		{ i: DEC_CPU_IRQ_NR(KN230_CPU_INR_MEMORY) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN230_CPU_INR_RTC) },
+		{ i: DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN230_CPU_INR_DZ11) },
+		{ i: DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN230_CPU_INR_SII) },
+		{ i: DEC_CPU_IRQ_NR(KN230_CPU_INR_SII) } },
+	{ { i: DEC_CPU_IRQ_ALL },
+		{ p: cpu_all_int } },
+};
+
 void __init dec_init_kn230(void)
 {
-    /*
-     * Setup some memory addresses.
-     */
-    dec_rtc_base = (char *) KN01_RTC_BASE;
-
-    /*
-     * Setup interrupt structure
-     */
-    dec_interrupt[CLOCK].cpu_mask = IE_IRQ2;
-    dec_interrupt[CLOCK].iemask = 0;
-    cpu_mask_tbl[0] = IE_IRQ2;
-    cpu_irq_nr[0] = CLOCK;
-
-    dec_interrupt[FPU].cpu_mask = IE_IRQ5;
-    dec_interrupt[FPU].iemask = 0;
-    cpu_mask_tbl[5] = IE_IRQ5;
-    cpu_irq_nr[5] = FPU;
+	/* Setup some memory addresses. */
+	dec_rtc_base = (char *) KN01_RTC_BASE;
+
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn230_interrupt,
+		sizeof(kn230_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn230_cpu_mask_nr_tbl,
+		sizeof(kn230_cpu_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+
 }				/* dec_init_kn230 */
 
+
 /*
- * Machine-specific initialisation for kn02, aka 3max, aka DS5000/2xx.
+ * Machine-specific initialisation for KN02, aka DS5000/200, aka 3max.
  */
+static int kn02_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= DEC_CPU_IRQ_NR(KN02_CPU_INR_CASCADE),
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= KN02_IRQ_NR(KN02_CSR_INR_DZ11),
+	[DEC_IRQ_ASC]		= KN02_IRQ_NR(KN02_CSR_INR_ASC),
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= -1,
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= KN02_IRQ_NR(KN02_CSR_INR_LANCE),
+	[DEC_IRQ_MEMORY]	= DEC_CPU_IRQ_NR(KN02_CPU_INR_MEMORY),
+	[DEC_IRQ_PSU]		= -1,
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= -1,
+	[DEC_IRQ_SCC1]		= -1,
+	[DEC_IRQ_SII]		= -1,
+	[DEC_IRQ_TC0]		= KN02_IRQ_NR(KN02_CSR_INR_TC0),
+	[DEC_IRQ_TC1]		= KN02_IRQ_NR(KN02_CSR_INR_TC1),
+	[DEC_IRQ_TC2]		= KN02_IRQ_NR(KN02_CSR_INR_TC2),
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= -1,
+	[DEC_IRQ_ASC_MERR]	= -1,
+	[DEC_IRQ_ASC_ERR]	= -1,
+	[DEC_IRQ_ASC_DMA]	= -1,
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= -1,
+	[DEC_IRQ_SCC0A_RXERR]	= -1,
+	[DEC_IRQ_SCC0A_RXDMA]	= -1,
+	[DEC_IRQ_SCC0A_TXERR]	= -1,
+	[DEC_IRQ_SCC0A_TXDMA]	= -1,
+	[DEC_IRQ_SCC0B_RXERR]	= -1,
+	[DEC_IRQ_SCC0B_RXDMA]	= -1,
+	[DEC_IRQ_SCC0B_TXERR]	= -1,
+	[DEC_IRQ_SCC0B_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= -1,
+	[DEC_IRQ_SCC1A_RXDMA]	= -1,
+	[DEC_IRQ_SCC1A_TXERR]	= -1,
+	[DEC_IRQ_SCC1A_TXDMA]	= -1,
+};
+
+static int_ptr kn02_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { i: DEC_CPU_IRQ_MASK(KN02_CPU_INR_MEMORY) },
+		{ i: DEC_CPU_IRQ_NR(KN02_CPU_INR_MEMORY) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN02_CPU_INR_RTC) },
+		{ i: DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN02_CPU_INR_CASCADE) },
+		{ p: kn02_io_int } },
+	{ { i: DEC_CPU_IRQ_ALL },
+		{ p: cpu_all_int } },
+};
+
+static int_ptr kn02_asic_mask_nr_tbl[][2] __initdata = {
+	{ { i: KN02_IRQ_MASK(KN02_CSR_INR_DZ11) },
+		{ i: KN02_IRQ_NR(KN02_CSR_INR_DZ11) } },
+	{ { i: KN02_IRQ_MASK(KN02_CSR_INR_ASC) },
+		{ i: KN02_IRQ_NR(KN02_CSR_INR_ASC) } },
+	{ { i: KN02_IRQ_MASK(KN02_CSR_INR_LANCE) },
+		{ i: KN02_IRQ_NR(KN02_CSR_INR_LANCE) } },
+	{ { i: KN02_IRQ_MASK(KN02_CSR_INR_TC2) },
+		{ i: KN02_IRQ_NR(KN02_CSR_INR_TC2) } },
+	{ { i: KN02_IRQ_MASK(KN02_CSR_INR_TC1) },
+		{ i: KN02_IRQ_NR(KN02_CSR_INR_TC1) } },
+	{ { i: KN02_IRQ_MASK(KN02_CSR_INR_TC0) },
+		{ i: KN02_IRQ_NR(KN02_CSR_INR_TC0) } },
+	{ { i: KN02_IRQ_ALL },
+		{ p: kn02_all_int } },
+};
+
 void __init dec_init_kn02(void)
 {
-    /*
-     * Setup some memory addresses. FIXME: probably incomplete!
-     */
-    dec_rtc_base = (char *) KN02_RTC_BASE;
-    isr = (void *) KN02_CSR_ADDR;
-    imr = (void *) KN02_CSR_ADDR;
-
-    /*
-     * Setup IOASIC interrupt
-     */
-    cpu_ivec_tbl[1] = kn02_io_int;
-    cpu_mask_tbl[1] = IE_IRQ0;
-    cpu_irq_nr[1] = -1;
-    *imr = *imr & 0xff00ff00;
-
-    /*
-     * Setup interrupt structure
-     */
-    dec_interrupt[CLOCK].cpu_mask = IE_IRQ1;
-    dec_interrupt[CLOCK].iemask = 0;
-    cpu_mask_tbl[0] = IE_IRQ1;
-    cpu_irq_nr[0] = CLOCK;
-
-    dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0;
-    dec_interrupt[SCSI_INT].iemask = KN02_SLOT5;
-    asic_mask_tbl[0] = KN02_SLOT5;
-    asic_irq_nr[0] = SCSI_INT;
-
-    dec_interrupt[ETHER].cpu_mask = IE_IRQ0;
-    dec_interrupt[ETHER].iemask = KN02_SLOT6;
-    asic_mask_tbl[1] = KN02_SLOT6;
-    asic_irq_nr[1] = ETHER;
-
-    dec_interrupt[SERIAL].cpu_mask = IE_IRQ0;
-    dec_interrupt[SERIAL].iemask = KN02_SLOT7;
-    asic_mask_tbl[2] = KN02_SLOT7;
-    asic_irq_nr[2] = SERIAL;
-
-    dec_interrupt[TC0].cpu_mask = IE_IRQ0;
-    dec_interrupt[TC0].iemask = KN02_SLOT0;
-    asic_mask_tbl[3] = KN02_SLOT0;
-    asic_irq_nr[3] = TC0;
-
-    dec_interrupt[TC1].cpu_mask = IE_IRQ0;
-    dec_interrupt[TC1].iemask = KN02_SLOT1;
-    asic_mask_tbl[4] = KN02_SLOT1;
-    asic_irq_nr[4] = TC1;
-
-    dec_interrupt[TC2].cpu_mask = IE_IRQ0;
-    dec_interrupt[TC2].iemask = KN02_SLOT2;
-    asic_mask_tbl[5] = KN02_SLOT2;
-    asic_irq_nr[5] = TC2;
-
-    dec_interrupt[MEMORY].cpu_mask = IE_IRQ3;
-    dec_interrupt[MEMORY].iemask = 0;
-    cpu_mask_tbl[2] = IE_IRQ3;
-    cpu_irq_nr[2] = MEMORY;
-
-    dec_interrupt[FPU].cpu_mask = IE_IRQ5;
-    dec_interrupt[FPU].iemask = 0;
-    cpu_mask_tbl[3] = IE_IRQ5;
-    cpu_irq_nr[3] = FPU;
+	/* Setup some memory addresses. */
+	dec_rtc_base = (char *) KN02_RTC_BASE;
+
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn02_interrupt,
+		sizeof(kn02_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn02_cpu_mask_nr_tbl,
+		sizeof(kn02_cpu_mask_nr_tbl));
+
+	/* KN02 CSR IRQ priorities. */
+	memcpy(&asic_mask_nr_tbl, &kn02_asic_mask_nr_tbl,
+		sizeof(kn02_asic_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+	init_kn02_irqs(KN02_IRQ_BASE);
 
 }				/* dec_init_kn02 */
 
+
 /*
- * Machine-specific initialisation for kn02ba, aka 3min, aka DS5000/1xx.
+ * Machine-specific initialisation for KN02-BA, aka DS5000/1xx
+ * (xx = 20, 25, 33), aka 3min.  Also applies to KN04(-BA), aka
+ * DS5000/150, aka 4min.
  */
+static int kn02ba_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_CASCADE),
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= -1,
+	[DEC_IRQ_ASC]		= IO_IRQ_NR(KN02BA_IO_INR_ASC),
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_HALT),
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= IO_IRQ_NR(KN02BA_IO_INR_LANCE),
+	[DEC_IRQ_MEMORY]	= IO_IRQ_NR(KN02BA_IO_INR_MEMORY),
+	[DEC_IRQ_PSU]		= IO_IRQ_NR(KN02BA_IO_INR_PSU),
+	[DEC_IRQ_RTC]		= IO_IRQ_NR(KN02BA_IO_INR_RTC),
+	[DEC_IRQ_SCC0]		= IO_IRQ_NR(KN02BA_IO_INR_SCC0),
+	[DEC_IRQ_SCC1]		= IO_IRQ_NR(KN02BA_IO_INR_SCC1),
+	[DEC_IRQ_SII]		= -1,
+	[DEC_IRQ_TC0]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0),
+	[DEC_IRQ_TC1]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1),
+	[DEC_IRQ_TC2]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2),
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= -1,
+	[DEC_IRQ_ASC_MERR]	= IO_IRQ_NR(IO_INR_LANCE_MERR),
+	[DEC_IRQ_ASC_ERR]	= IO_IRQ_NR(IO_INR_ASC_ERR),
+	[DEC_IRQ_ASC_DMA]	= IO_IRQ_NR(IO_INR_ASC_DMA),
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= IO_IRQ_NR(IO_INR_LANCE_MERR),
+	[DEC_IRQ_SCC0A_RXERR]	= IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+	[DEC_IRQ_SCC0A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+	[DEC_IRQ_SCC0A_TXERR]	= IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+	[DEC_IRQ_SCC0A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+	[DEC_IRQ_SCC0B_RXERR]	= -1,
+	[DEC_IRQ_SCC0B_RXDMA]	= -1,
+	[DEC_IRQ_SCC0B_TXERR]	= -1,
+	[DEC_IRQ_SCC0B_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= IO_IRQ_NR(IO_INR_SCC1A_RXERR),
+	[DEC_IRQ_SCC1A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC1A_RXDMA),
+	[DEC_IRQ_SCC1A_TXERR]	= IO_IRQ_NR(IO_INR_SCC1A_TXERR),
+	[DEC_IRQ_SCC1A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC1A_TXDMA),
+};
+
+static int_ptr kn02ba_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { i: DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_CASCADE) },
+		{ p: kn02xa_io_int } },
+	{ { i: DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC2) },
+		{ i: DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC1) },
+		{ i: DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC0) },
+		{ i: DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0) } },
+	{ { i: DEC_CPU_IRQ_ALL },
+		{ p: cpu_all_int } },
+};
+
+static int_ptr kn02ba_asic_mask_nr_tbl[][2] __initdata = {
+	{ { i: IO_IRQ_MASK(KN02BA_IO_INR_MEMORY) },
+		{ i: IO_IRQ_NR(KN02BA_IO_INR_MEMORY) } },
+	{ { i: IO_IRQ_MASK(KN02BA_IO_INR_RTC) },
+		{ i: IO_IRQ_NR(KN02BA_IO_INR_RTC) } },
+	{ { i: IO_IRQ_DMA },
+		{ p: asic_dma_int } },
+	{ { i: IO_IRQ_MASK(KN02BA_IO_INR_SCC0) },
+		{ i: IO_IRQ_NR(KN02BA_IO_INR_SCC0) } },
+	{ { i: IO_IRQ_MASK(KN02BA_IO_INR_SCC1) },
+		{ i: IO_IRQ_NR(KN02BA_IO_INR_SCC1) } },
+	{ { i: IO_IRQ_MASK(KN02BA_IO_INR_ASC) },
+		{ i: IO_IRQ_NR(KN02BA_IO_INR_ASC) } },
+	{ { i: IO_IRQ_MASK(KN02BA_IO_INR_LANCE) },
+		{ i: IO_IRQ_NR(KN02BA_IO_INR_LANCE) } },
+	{ { i: IO_IRQ_ALL },
+		{ p: asic_all_int } },
+};
+
 void __init dec_init_kn02ba(void)
 {
-    /*
-     * Setup some memory addresses.
-     */
-    ioasic_base = (void *) KN02XA_IOASIC_BASE;
-    dec_rtc_base = (char *) KN02XA_RTC_BASE;
-    isr = (void *) KN02XA_IOASIC_REG(SIR);
-    imr = (void *) KN02XA_IOASIC_REG(SIMR);
-
-    /*
-     * Setup IOASIC interrupt
-     */
-    cpu_mask_tbl[0] = IE_IRQ3;
-    cpu_irq_nr[0] = -1;
-    cpu_ivec_tbl[0] = kn02xa_io_int;
-    *imr = 0;
-
-    /*
-     * Setup interrupt structure
-     */
-    dec_interrupt[CLOCK].cpu_mask = IE_IRQ3;
-    dec_interrupt[CLOCK].iemask = KMIN_CLOCK;
-    asic_mask_tbl[0] = KMIN_CLOCK;
-    asic_irq_nr[0] = CLOCK;
-
-    dec_interrupt[SCSI_DMA_INT].cpu_mask = IE_IRQ3;
-    dec_interrupt[SCSI_DMA_INT].iemask = SCSI_DMA_INTS;
-    asic_mask_tbl[1] = SCSI_DMA_INTS;
-    asic_irq_nr[1] = SCSI_DMA_INT;
-
-    dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ3;
-    dec_interrupt[SCSI_INT].iemask = SCSI_CHIP;
-    asic_mask_tbl[2] = SCSI_CHIP;
-    asic_irq_nr[2] = SCSI_INT;
-
-    dec_interrupt[ETHER].cpu_mask = IE_IRQ3;
-    dec_interrupt[ETHER].iemask = LANCE_INTS;
-    asic_mask_tbl[3] = LANCE_INTS;
-    asic_irq_nr[3] = ETHER;
-
-    dec_interrupt[SERIAL].cpu_mask = IE_IRQ3;
-    dec_interrupt[SERIAL].iemask = SERIAL_INTS;
-    asic_mask_tbl[4] = SERIAL_INTS;
-    asic_irq_nr[4] = SERIAL;
-
-    dec_interrupt[MEMORY].cpu_mask = IE_IRQ3;
-    dec_interrupt[MEMORY].iemask = KMIN_TIMEOUT;
-    asic_mask_tbl[5] = KMIN_TIMEOUT;
-    asic_irq_nr[5] = MEMORY;
-
-    dec_interrupt[TC0].cpu_mask = IE_IRQ0;
-    dec_interrupt[TC0].iemask = 0;
-    cpu_mask_tbl[1] = IE_IRQ0;
-    cpu_irq_nr[1] = TC0;
-
-    dec_interrupt[TC1].cpu_mask = IE_IRQ1;
-    dec_interrupt[TC1].iemask = 0;
-    cpu_mask_tbl[2] = IE_IRQ1;
-    cpu_irq_nr[2] = TC1;
-
-    dec_interrupt[TC2].cpu_mask = IE_IRQ2;
-    dec_interrupt[TC2].iemask = 0;
-    cpu_mask_tbl[3] = IE_IRQ2;
-    cpu_irq_nr[3] = TC2;
-
-    dec_interrupt[HALT].cpu_mask = IE_IRQ4;
-    dec_interrupt[HALT].iemask = 0;
-    cpu_mask_tbl[4] = IE_IRQ4;
-    cpu_irq_nr[4] = HALT;
-
-    dec_interrupt[FPU].cpu_mask = IE_IRQ5;
-    dec_interrupt[FPU].iemask = 0;
-    cpu_mask_tbl[5] = IE_IRQ5;
-    cpu_irq_nr[5] = FPU;
+	/* Setup some memory addresses. */
+	ioasic_base = (void *) KN02BA_IOASIC_BASE;
+	dec_rtc_base = (char *) KN02BA_RTC_BASE;
+
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn02ba_interrupt,
+		sizeof(kn02ba_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn02ba_cpu_mask_nr_tbl,
+		sizeof(kn02ba_cpu_mask_nr_tbl));
+
+	/* I/O ASIC IRQ priorities. */
+	memcpy(&asic_mask_nr_tbl, &kn02ba_asic_mask_nr_tbl,
+		sizeof(kn02ba_asic_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+	init_ioasic_irqs(IO_IRQ_BASE);
 
-    dec_halt_init(&irq10);
 }				/* dec_init_kn02ba */
 
+
 /*
- * Machine-specific initialisation for kn02ca, aka maxine, aka DS5000/2x.
+ * Machine-specific initialisation for KN02-CA, aka DS5000/xx,
+ * (xx = 20, 25, 33), aka MAXine.  Also applies to KN04(-CA), aka
+ * DS5000/50, aka 4MAXine.
  */
+static int kn02ca_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_CASCADE),
+	[DEC_IRQ_AB_RECV]	= IO_IRQ_NR(KN02CA_IO_INR_AB_RECV),
+	[DEC_IRQ_AB_XMIT]	= IO_IRQ_NR(KN02CA_IO_INR_AB_XMIT),
+	[DEC_IRQ_DZ11]		= -1,
+	[DEC_IRQ_ASC]		= IO_IRQ_NR(KN02CA_IO_INR_ASC),
+	[DEC_IRQ_FLOPPY]	= IO_IRQ_NR(KN02CA_IO_INR_FLOPPY),
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_HALT),
+	[DEC_IRQ_ISDN]		= IO_IRQ_NR(KN02CA_IO_INR_ISDN),
+	[DEC_IRQ_LANCE]		= IO_IRQ_NR(KN02CA_IO_INR_LANCE),
+	[DEC_IRQ_MEMORY]	= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_MEMORY),
+	[DEC_IRQ_PSU]		= -1,
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= IO_IRQ_NR(KN02CA_IO_INR_SCC0),
+	[DEC_IRQ_SCC1]		= -1,
+	[DEC_IRQ_SII]		= -1,
+	[DEC_IRQ_TC0]		= IO_IRQ_NR(KN02CA_IO_INR_TC0),
+	[DEC_IRQ_TC1]		= IO_IRQ_NR(KN02CA_IO_INR_TC1),
+	[DEC_IRQ_TC2]		= -1,
+	[DEC_IRQ_TIMER]		= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_TIMER),
+	[DEC_IRQ_VIDEO]		= IO_IRQ_NR(KN02CA_IO_INR_VIDEO),
+	[DEC_IRQ_ASC_MERR]	= IO_IRQ_NR(IO_INR_ASC_MERR),
+	[DEC_IRQ_ASC_ERR]	= IO_IRQ_NR(IO_INR_ASC_ERR),
+	[DEC_IRQ_ASC_DMA]	= IO_IRQ_NR(IO_INR_ASC_DMA),
+	[DEC_IRQ_FLOPPY_ERR]	= IO_IRQ_NR(IO_INR_FLOPPY_ERR),
+	[DEC_IRQ_ISDN_ERR]	= IO_IRQ_NR(IO_INR_ISDN_ERR),
+	[DEC_IRQ_ISDN_RXDMA]	= IO_IRQ_NR(IO_INR_ISDN_RXDMA),
+	[DEC_IRQ_ISDN_TXDMA]	= IO_IRQ_NR(IO_INR_ISDN_TXDMA),
+	[DEC_IRQ_LANCE_MERR]	= IO_IRQ_NR(IO_INR_LANCE_MERR),
+	[DEC_IRQ_SCC0A_RXERR]	= IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+	[DEC_IRQ_SCC0A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+	[DEC_IRQ_SCC0A_TXERR]	= IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+	[DEC_IRQ_SCC0A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+	[DEC_IRQ_SCC0B_RXERR]	= IO_IRQ_NR(IO_INR_SCC0B_RXERR),
+	[DEC_IRQ_SCC0B_RXDMA]	= IO_IRQ_NR(IO_INR_SCC0B_RXDMA),
+	[DEC_IRQ_SCC0B_TXERR]	= IO_IRQ_NR(IO_INR_SCC0B_TXERR),
+	[DEC_IRQ_SCC0B_TXDMA]	= IO_IRQ_NR(IO_INR_SCC0B_TXDMA),
+	[DEC_IRQ_SCC1A_RXERR]	= -1,
+	[DEC_IRQ_SCC1A_RXDMA]	= -1,
+	[DEC_IRQ_SCC1A_TXERR]	= -1,
+	[DEC_IRQ_SCC1A_TXDMA]	= -1,
+};
+
+static int_ptr kn02ca_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { i: DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_MEMORY) },
+		{ i: DEC_CPU_IRQ_NR(KN02CA_CPU_INR_MEMORY) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_RTC) },
+		{ i: DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_CASCADE) },
+		{ p: kn02xa_io_int } },
+	{ { i: DEC_CPU_IRQ_ALL },
+		{ p: cpu_all_int } },
+};
+
+static int_ptr kn02ca_asic_mask_nr_tbl[][2] __initdata = {
+	{ { i: IO_IRQ_DMA },
+		{ p: asic_dma_int } },
+	{ { i: IO_IRQ_MASK(KN02CA_IO_INR_SCC0) },
+		{ i: IO_IRQ_NR(KN02CA_IO_INR_SCC0) } },
+	{ { i: IO_IRQ_MASK(KN02CA_IO_INR_ASC) },
+		{ i: IO_IRQ_NR(KN02CA_IO_INR_ASC) } },
+	{ { i: IO_IRQ_MASK(KN02CA_IO_INR_LANCE) },
+		{ i: IO_IRQ_NR(KN02CA_IO_INR_LANCE) } },
+	{ { i: IO_IRQ_MASK(KN02CA_IO_INR_TC1) },
+		{ i: IO_IRQ_NR(KN02CA_IO_INR_TC1) } },
+	{ { i: IO_IRQ_MASK(KN02CA_IO_INR_TC0) },
+		{ i: IO_IRQ_NR(KN02CA_IO_INR_TC0) } },
+	{ { i: IO_IRQ_ALL },
+		{ p: asic_all_int } },
+};
+
 void __init dec_init_kn02ca(void)
 {
-    /*
-     * Setup some memory addresses. FIXME: probably incomplete!
-     */
-    ioasic_base = (void *) KN02XA_IOASIC_BASE;
-    dec_rtc_base = (char *) KN02XA_RTC_BASE;
-    isr = (void *) KN02XA_IOASIC_REG(SIR);
-    imr = (void *) KN02XA_IOASIC_REG(SIMR);
-
-    /*
-     * Setup IOASIC interrupt
-     */
-    cpu_ivec_tbl[1] = kn02xa_io_int;
-    cpu_irq_nr[1] = -1;
-    cpu_mask_tbl[1] = IE_IRQ3;
-    *imr = 0;
-
-    /*
-     * Setup interrupt structure
-     */
-    dec_interrupt[CLOCK].cpu_mask = IE_IRQ1;
-    dec_interrupt[CLOCK].iemask = 0;
-    cpu_mask_tbl[0] = IE_IRQ1;
-    cpu_irq_nr[0] = CLOCK;
-
-    dec_interrupt[SCSI_DMA_INT].cpu_mask = IE_IRQ3;
-    dec_interrupt[SCSI_DMA_INT].iemask = SCSI_DMA_INTS;
-    asic_mask_tbl[0] = SCSI_DMA_INTS;
-    asic_irq_nr[0] = SCSI_DMA_INT;
-
-    dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ3;
-    dec_interrupt[SCSI_INT].iemask = SCSI_CHIP;
-    asic_mask_tbl[1] = SCSI_CHIP;
-    asic_irq_nr[1] = SCSI_INT;
-
-    dec_interrupt[ETHER].cpu_mask = IE_IRQ3;
-    dec_interrupt[ETHER].iemask = LANCE_INTS;
-    asic_mask_tbl[2] = LANCE_INTS;
-    asic_irq_nr[2] = ETHER;
-
-    dec_interrupt[SERIAL].cpu_mask = IE_IRQ3;
-    dec_interrupt[SERIAL].iemask = XINE_SERIAL_INTS;
-    asic_mask_tbl[3] = XINE_SERIAL_INTS;
-    asic_irq_nr[3] = SERIAL;
-
-    dec_interrupt[TC0].cpu_mask = IE_IRQ3;
-    dec_interrupt[TC0].iemask = MAXINE_TC0;
-    asic_mask_tbl[4] = MAXINE_TC0;
-    asic_irq_nr[4] = TC0;
-
-    dec_interrupt[TC1].cpu_mask = IE_IRQ3;
-    dec_interrupt[TC1].iemask = MAXINE_TC1;
-    asic_mask_tbl[5] = MAXINE_TC1;
-    asic_irq_nr[5] = TC1;
-
-    dec_interrupt[MEMORY].cpu_mask = IE_IRQ2;
-    dec_interrupt[MEMORY].iemask = 0;
-    cpu_mask_tbl[2] = IE_IRQ2;
-    cpu_irq_nr[2] = MEMORY;
-
-    dec_interrupt[HALT].cpu_mask = IE_IRQ4;
-    dec_interrupt[HALT].iemask = 0;
-    cpu_mask_tbl[3] = IE_IRQ4;
-    cpu_irq_nr[3] = HALT;
-
-    dec_interrupt[FPU].cpu_mask = IE_IRQ5;
-    dec_interrupt[FPU].iemask = 0;
-    cpu_mask_tbl[4] = IE_IRQ5;
-    cpu_irq_nr[4] = FPU;
+	/* Setup some memory addresses. */
+	ioasic_base = (void *) KN02CA_IOASIC_BASE;
+	dec_rtc_base = (char *) KN02CA_RTC_BASE;
+
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn02ca_interrupt,
+		sizeof(kn02ca_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn02ca_cpu_mask_nr_tbl,
+		sizeof(kn02ca_cpu_mask_nr_tbl));
+
+	/* I/O ASIC IRQ priorities. */
+	memcpy(&asic_mask_nr_tbl, &kn02ca_asic_mask_nr_tbl,
+		sizeof(kn02ca_asic_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+	init_ioasic_irqs(IO_IRQ_BASE);
 
-    dec_halt_init(&irq10);
 }				/* dec_init_kn02ca */
 
+
 /*
- * Machine-specific initialisation for kn03, aka 3max+, aka DS5000/240.
+ * Machine-specific initialisation for KN03, aka DS5000/240,
+ * aka 3max+ and DS5900, aka BIGmax.  Also applies to KN05, aka
+ * DS5000/260, aka 4max+ and DS5900-260.
  */
+static int kn03_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= DEC_CPU_IRQ_NR(KN03_CPU_INR_CASCADE),
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= -1,
+	[DEC_IRQ_ASC]		= IO_IRQ_NR(KN03_IO_INR_ASC),
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= DEC_CPU_IRQ_NR(KN03_CPU_INR_HALT),
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= IO_IRQ_NR(KN03_IO_INR_LANCE),
+	[DEC_IRQ_MEMORY]	= DEC_CPU_IRQ_NR(KN03_CPU_INR_MEMORY),
+	[DEC_IRQ_PSU]		= IO_IRQ_NR(KN03_IO_INR_PSU),
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= IO_IRQ_NR(KN03_IO_INR_SCC0),
+	[DEC_IRQ_SCC1]		= IO_IRQ_NR(KN03_IO_INR_SCC1),
+	[DEC_IRQ_SII]		= -1,
+	[DEC_IRQ_TC0]		= IO_IRQ_NR(KN03_IO_INR_TC0),
+	[DEC_IRQ_TC1]		= IO_IRQ_NR(KN03_IO_INR_TC1),
+	[DEC_IRQ_TC2]		= IO_IRQ_NR(KN03_IO_INR_TC2),
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= -1,
+	[DEC_IRQ_ASC_MERR]	= IO_IRQ_NR(IO_INR_ASC_MERR),
+	[DEC_IRQ_ASC_ERR]	= IO_IRQ_NR(IO_INR_ASC_ERR),
+	[DEC_IRQ_ASC_DMA]	= IO_IRQ_NR(IO_INR_ASC_DMA),
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= IO_IRQ_NR(IO_INR_LANCE_MERR),
+	[DEC_IRQ_SCC0A_RXERR]	= IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+	[DEC_IRQ_SCC0A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+	[DEC_IRQ_SCC0A_TXERR]	= IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+	[DEC_IRQ_SCC0A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+	[DEC_IRQ_SCC0B_RXERR]	= -1,
+	[DEC_IRQ_SCC0B_RXDMA]	= -1,
+	[DEC_IRQ_SCC0B_TXERR]	= -1,
+	[DEC_IRQ_SCC0B_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= IO_IRQ_NR(IO_INR_SCC1A_RXERR),
+	[DEC_IRQ_SCC1A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC1A_RXDMA),
+	[DEC_IRQ_SCC1A_TXERR]	= IO_IRQ_NR(IO_INR_SCC1A_TXERR),
+	[DEC_IRQ_SCC1A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC1A_TXDMA),
+};
+
+static int_ptr kn03_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_MEMORY) },
+		{ i: DEC_CPU_IRQ_NR(KN03_CPU_INR_MEMORY) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_RTC) },
+		{ i: DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC) } },
+	{ { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) }, 
+		{ p: kn03_io_int } },
+	{ { i: DEC_CPU_IRQ_ALL }, 
+		{ p: cpu_all_int } },
+};
+
+static int_ptr kn03_asic_mask_nr_tbl[][2] __initdata = {
+	{ { i: IO_IRQ_DMA },
+		{ p: asic_dma_int } },
+	{ { i: IO_IRQ_MASK(KN03_IO_INR_SCC0) },
+		{ i: IO_IRQ_NR(KN03_IO_INR_SCC0) } },
+	{ { i: IO_IRQ_MASK(KN03_IO_INR_SCC1) },
+		{ i: IO_IRQ_NR(KN03_IO_INR_SCC1) } },
+	{ { i: IO_IRQ_MASK(KN03_IO_INR_ASC) },
+		{ i: IO_IRQ_NR(KN03_IO_INR_ASC) } },
+	{ { i: IO_IRQ_MASK(KN03_IO_INR_LANCE) },
+		{ i: IO_IRQ_NR(KN03_IO_INR_LANCE) } },
+	{ { i: IO_IRQ_MASK(KN03_IO_INR_TC2) },
+		{ i: IO_IRQ_NR(KN03_IO_INR_TC2) } },
+	{ { i: IO_IRQ_MASK(KN03_IO_INR_TC1) },
+		{ i: IO_IRQ_NR(KN03_IO_INR_TC1) } },
+	{ { i: IO_IRQ_MASK(KN03_IO_INR_TC0) },
+		{ i: IO_IRQ_NR(KN03_IO_INR_TC0) } },
+	{ { i: IO_IRQ_ALL },
+		{ p: asic_all_int } },
+};
+
 void __init dec_init_kn03(void)
 {
-    /*
-     * Setup some memory addresses. FIXME: probably incomplete!
-     */
-    ioasic_base = (void *) KN03_IOASIC_BASE;
-    dec_rtc_base = (char *) KN03_RTC_BASE;
-    isr = (void *) KN03_IOASIC_REG(SIR);
-    imr = (void *) KN03_IOASIC_REG(SIMR);
-
-    /*
-     * Setup IOASIC interrupt
-     */
-    cpu_ivec_tbl[1] = kn03_io_int;
-    cpu_mask_tbl[1] = IE_IRQ0;
-    cpu_irq_nr[1] = -1;
-    *imr = 0;
-
-    /*
-     * Setup interrupt structure
-     */
-    dec_interrupt[CLOCK].cpu_mask = IE_IRQ1;
-    dec_interrupt[CLOCK].iemask = 0;
-    cpu_mask_tbl[0] = IE_IRQ1;
-    cpu_irq_nr[0] = CLOCK;
-
-    dec_interrupt[SCSI_DMA_INT].cpu_mask = IE_IRQ0;
-    dec_interrupt[SCSI_DMA_INT].iemask = SCSI_DMA_INTS;
-    asic_mask_tbl[0] = SCSI_DMA_INTS;
-    asic_irq_nr[0] = SCSI_DMA_INT;
-
-    dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0;
-    dec_interrupt[SCSI_INT].iemask = SCSI_CHIP;
-    asic_mask_tbl[1] = SCSI_CHIP;
-    asic_irq_nr[1] = SCSI_INT;
-
-    dec_interrupt[ETHER].cpu_mask = IE_IRQ0;
-    dec_interrupt[ETHER].iemask = LANCE_INTS;
-    asic_mask_tbl[2] = LANCE_INTS;
-    asic_irq_nr[2] = ETHER;
-
-    dec_interrupt[SERIAL].cpu_mask = IE_IRQ0;
-    dec_interrupt[SERIAL].iemask = SERIAL_INTS;
-    asic_mask_tbl[3] = SERIAL_INTS;
-    asic_irq_nr[3] = SERIAL;
-
-    dec_interrupt[TC0].cpu_mask = IE_IRQ0;
-    dec_interrupt[TC0].iemask = KN03_TC0;
-    asic_mask_tbl[4] = KN03_TC0;
-    asic_irq_nr[4] = TC0;
-
-    dec_interrupt[TC1].cpu_mask = IE_IRQ0;
-    dec_interrupt[TC1].iemask = KN03_TC1;
-    asic_mask_tbl[5] = KN03_TC1;
-    asic_irq_nr[5] = TC1;
-
-    dec_interrupt[TC2].cpu_mask = IE_IRQ0;
-    dec_interrupt[TC2].iemask = KN03_TC2;
-    asic_mask_tbl[6] = KN03_TC2;
-    asic_irq_nr[6] = TC2;
-
-    dec_interrupt[MEMORY].cpu_mask = IE_IRQ3;
-    dec_interrupt[MEMORY].iemask = 0;
-    cpu_mask_tbl[2] = IE_IRQ3;
-    cpu_irq_nr[2] = MEMORY;
-
-    dec_interrupt[HALT].cpu_mask = IE_IRQ4;
-    dec_interrupt[HALT].iemask = 0;
-    cpu_mask_tbl[3] = IE_IRQ4;
-    cpu_irq_nr[3] = HALT;
-
-    dec_interrupt[FPU].cpu_mask = IE_IRQ5;
-    dec_interrupt[FPU].iemask = 0;
-    cpu_mask_tbl[4] = IE_IRQ5;
-    cpu_irq_nr[4] = FPU;
+	/* Setup some memory addresses.  */
+	ioasic_base = (void *) KN03_IOASIC_BASE;
+	dec_rtc_base = (char *) KN03_RTC_BASE;
+
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn03_interrupt,
+		sizeof(kn03_interrupt));	
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn03_cpu_mask_nr_tbl,
+		sizeof(kn03_cpu_mask_nr_tbl));
+
+	/* I/O ASIC IRQ priorities. */
+	memcpy(&asic_mask_nr_tbl, &kn03_asic_mask_nr_tbl,
+		sizeof(kn03_asic_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+	init_ioasic_irqs(IO_IRQ_BASE);
 
-    dec_halt_init(&irq10);
 }				/* dec_init_kn03 */
+
+
+void __init init_IRQ(void)
+{
+	switch (mips_machtype) {
+	case MACH_DS23100:	/* DS2100/DS3100 Pmin/Pmax */
+		dec_init_kn01();
+		break;
+	case MACH_DS5100:	/* DS5100 MIPSmate */
+		dec_init_kn230();
+		break;
+	case MACH_DS5000_200:	/* DS5000/200 3max */
+		dec_init_kn02();
+		break;
+	case MACH_DS5000_1XX:	/* DS5000/1xx 3min */
+		dec_init_kn02ba();
+		break;
+	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+		dec_init_kn03();
+		break;
+	case MACH_DS5000_XX:	/* Personal DS5000/xx */
+		dec_init_kn02ca();
+		break;
+	case MACH_DS5800:	/* DS5800 Isis */
+		panic("Don't know how to set this up!");
+		break;
+	case MACH_DS5400:	/* DS5400 MIPSfair */
+		panic("Don't know how to set this up!");
+		break;
+	case MACH_DS5500:	/* DS5500 MIPSfair-2 */
+		panic("Don't know how to set this up!");
+		break;
+	}
+	set_except_vector(0, decstation_handle_int);
+
+	/* Free the FPU interrupt if the exception is present. */
+	if (!(mips_cpu.options & MIPS_CPU_NOFPUEX)) {
+		cpu_fpu_mask = 0;
+		dec_interrupt[DEC_IRQ_FPU] = -1;
+	}
+
+	/* Register board interrupts: FPU and cascade. */
+	if (dec_interrupt[DEC_IRQ_FPU] >= 0)
+		setup_irq(dec_interrupt[DEC_IRQ_FPU], &fpuirq);
+	if (dec_interrupt[DEC_IRQ_CASCADE] >= 0)
+		setup_irq(dec_interrupt[DEC_IRQ_CASCADE], &ioirq);
+
+	/* Register the HALT interrupt. */
+	if (dec_interrupt[DEC_IRQ_HALT] >= 0)
+		setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
+}
+
+EXPORT_SYMBOL(dec_interrupt);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/dec/time.c linux/arch/mips/dec/time.c
--- linux.orig/arch/mips/dec/time.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/dec/time.c	2002-07-20 01:08:30.000000000 +0000
@@ -8,6 +8,7 @@
  * found in some MIPS systems.
  *
  */
+#include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/sched.h>
@@ -44,7 +45,7 @@
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
+#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ))
 
 /* Cycle counter value at the previous timer interrupt.. */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig linux/arch/mips/defconfig
--- linux.orig/arch/mips/defconfig	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig	2002-07-20 01:08:26.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -10,58 +10,64 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 CONFIG_SGI_IP22=y
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_PB1000 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 CONFIG_ARC32=y
 CONFIG_BOARD_SCACHE=y
+CONFIG_IRQ_CPU=y
 CONFIG_PC_KEYB=y
 CONFIG_SGI=y
 CONFIG_NEW_IRQ=y
-CONFIG_OLD_TIME_C=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_PCI is not set
-# CONFIG_I8259 is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
@@ -70,6 +76,7 @@
 # CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_MIPS32 is not set
 # CONFIG_CPU_MIPS64 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -79,20 +86,28 @@
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
 CONFIG_BINFMT_IRIX=y
 CONFIG_FORWARD_KEYBOARD=y
 # CONFIG_ARC_CONSOLE is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=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
 
 #
 # Memory Technology Devices (MTD)
@@ -105,6 +120,12 @@
 # CONFIG_PARPORT 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
@@ -112,7 +133,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -127,6 +150,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
 
 #
@@ -134,8 +158,6 @@
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK=y
-CONFIG_RTNETLINK=y
 CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -156,12 +178,18 @@
 # 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -179,6 +207,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -219,6 +252,7 @@
 # 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
@@ -238,7 +272,6 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
@@ -273,7 +306,6 @@
 # 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
@@ -294,6 +326,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -334,11 +367,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 CONFIG_VT=y
@@ -358,7 +386,11 @@
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -377,14 +409,32 @@
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+CONFIG_INDYDOG=y
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+CONFIG_INDYDOG=y
 # 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
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -401,13 +451,9 @@
 #
 # SGI Character devices
 #
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
 CONFIG_SGI_NEWPORT_CONSOLE=y
 CONFIG_FONT_8x16=y
-# CONFIG_PSMOUSE is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_DUMMY_CONSOLE=y
 
 #
 # File systems
@@ -423,7 +469,6 @@
 # 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_JBD_DEBUG is not set
@@ -436,11 +481,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_FREEVXFS_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
@@ -481,6 +527,8 @@
 # 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
@@ -533,98 +581,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
@@ -639,5 +598,6 @@
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-atlas linux/arch/mips/defconfig-atlas
--- linux.orig/arch/mips/defconfig-atlas	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig-atlas	2002-07-20 01:08:32.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -10,51 +10,59 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 CONFIG_MIPS_ATLAS=y
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_PB1000 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_SWAP_IO_SPACE=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_I8259 is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
@@ -63,6 +71,7 @@
 # CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_MIPS32 is not set
 # CONFIG_CPU_MIPS64 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -72,20 +81,27 @@
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
 CONFIG_BINFMT_IRIX=y
 # CONFIG_FORWARD_KEYBOARD is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_SYSCTL 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
 
 #
 # Memory Technology Devices (MTD)
@@ -98,6 +114,12 @@
 # CONFIG_PARPORT 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
@@ -105,7 +127,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -121,13 +145,14 @@
 # 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_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -140,17 +165,24 @@
 # CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -168,6 +200,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -213,6 +250,7 @@
 # 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
@@ -233,8 +271,8 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 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
@@ -253,6 +291,16 @@
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -265,6 +313,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -274,7 +323,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -295,6 +343,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -335,11 +384,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -379,13 +423,11 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -413,7 +455,6 @@
 # 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_JBD_DEBUG is not set
@@ -426,11 +467,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS 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_FREEVXFS_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
@@ -471,6 +513,8 @@
 # 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
@@ -491,98 +535,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
@@ -599,6 +554,6 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_GDB_CONSOLE is not set
-# CONFIG_LL_DEBUG is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-cobalt linux/arch/mips/defconfig-cobalt
--- linux.orig/arch/mips/defconfig-cobalt	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-cobalt	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,609 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+CONFIG_MIPS_COBALT=y
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_COBALT_LCD=y
+CONFIG_PCI=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+CONFIG_CPU_NEVADA=y
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# 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_IDEDISK_STROKE 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 is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL 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_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CMD680 is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# 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_PCI 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
+
+#
+# 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_TC35815 is not set
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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_LAN_SAA9730 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_TIGON3 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=16
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_NVRAM is not set
+CONFIG_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=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_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=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-ddb5476 linux/arch/mips/defconfig-ddb5476
--- linux.orig/arch/mips/defconfig-ddb5476	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/defconfig-ddb5476	2002-07-20 01:08:34.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -15,23 +15,30 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
 # CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_NINO is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MOMENCO_OCELOT is not set
 CONFIG_DDB5476=y
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_IVR is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
@@ -39,11 +46,15 @@
 CONFIG_ISA=y
 CONFIG_PCI=y
 CONFIG_PC_KEYB=y
-CONFIG_ROTTEN_IRQ=y
+CONFIG_NEW_IRQ=y
+CONFIG_IRQ_CPU=y
+CONFIG_I8259=y
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_NEW_PCI=y
+CONFIG_PCI_AUTO=y
 CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
 CONFIG_EISA=y
-# CONFIG_I8259 is not set
 
 #
 # Loadable module support
@@ -54,10 +65,12 @@
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 CONFIG_CPU_R5432=y
 # CONFIG_CPU_RM7000 is not set
@@ -84,6 +97,7 @@
 # CONFIG_PCI_NAMES is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -93,7 +107,6 @@
 #
 # CONFIG_PNP is not set
 # CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -128,6 +141,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
 
 #
@@ -135,7 +149,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -148,11 +162,13 @@
 # CONFIG_IP_PNP_RARP 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
 
 #
 #  
@@ -266,6 +282,16 @@
 # CONFIG_SCSI is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -278,6 +304,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -287,7 +314,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -304,6 +330,7 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
+# CONFIG_TC35815 is not set
 # CONFIG_TULIP_MWI is not set
 # CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
@@ -316,15 +343,18 @@
 CONFIG_NE2K_PCI=y
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # 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_LAN_SAA9730 is not set
 # CONFIG_NET_POCKET is not set
@@ -433,7 +463,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -461,7 +490,6 @@
 # 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_JBD_DEBUG is not set
@@ -477,8 +505,9 @@
 # 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_FREEVXFS_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
@@ -519,6 +548,8 @@
 # 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
@@ -543,13 +574,14 @@
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_E1355 is not set
 # CONFIG_FB_MATROX is not set
 # CONFIG_FB_ATY is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_SIS is not set
 CONFIG_FB_3DFX=y
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -582,13 +614,19 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # 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_JUMPSHOT 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
 
@@ -616,12 +654,10 @@
 #
 #   Video4Linux support is needed for USB Multimedia device support
 #
-# CONFIG_USB_DABUSB is not set
 
 #
 # USB Network adaptors
 #
-# CONFIG_USB_PLUSB is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
@@ -644,25 +680,30 @@
 # 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_IPAQ 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_KLSI 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
 
 #
-# Miscellaneous USB drivers
+# USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
 
 #
 # Input core support
@@ -679,6 +720,6 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_GDB_CONSOLE is not set
-# CONFIG_LL_DEBUG is not set
+CONFIG_DEBUG=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-ddb5477 linux/arch/mips/defconfig-ddb5477
--- linux.orig/arch/mips/defconfig-ddb5477	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/defconfig-ddb5477	2002-07-20 01:08:29.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -15,34 +15,44 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
 # CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_NINO is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MOMENCO_OCELOT is not set
 # CONFIG_DDB5476 is not set
 CONFIG_DDB5477=y
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_IVR is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_PCI=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NEW_IRQ=y
+CONFIG_IRQ_CPU=y
+CONFIG_NEW_PCI=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PCI_AUTO=y
+CONFIG_DUMMY_KEYB=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
-# CONFIG_I8259 is not set
 
 #
 # Loadable module support
@@ -53,10 +63,12 @@
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 CONFIG_CPU_R5432=y
 # CONFIG_CPU_RM7000 is not set
@@ -83,6 +95,7 @@
 # CONFIG_PCI_NAMES is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -120,6 +133,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
 
 #
@@ -127,7 +141,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -140,11 +154,13 @@
 # CONFIG_IP_PNP_RARP 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
 
 #
 #  
@@ -187,6 +203,16 @@
 # CONFIG_SCSI is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -199,6 +225,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -208,7 +235,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -222,6 +248,7 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
+# CONFIG_TC35815 is not set
 # CONFIG_TULIP_MWI is not set
 # CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
@@ -234,15 +261,18 @@
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # 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_LAN_SAA9730 is not set
 # CONFIG_NET_POCKET is not set
@@ -309,7 +339,8 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -346,7 +377,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -374,7 +404,6 @@
 # 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_JBD_DEBUG is not set
@@ -390,8 +419,9 @@
 # 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_FREEVXFS_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
@@ -399,7 +429,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_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
@@ -432,6 +462,8 @@
 # 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
@@ -444,7 +476,30 @@
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+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_HAL2 is not set
+CONFIG_SOUND_VRC5477=y
+# 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_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
 
 #
 # USB support
@@ -463,13 +518,19 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # 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_JUMPSHOT 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
 
@@ -497,12 +558,10 @@
 #
 #   Video4Linux support is needed for USB Multimedia device support
 #
-# CONFIG_USB_DABUSB is not set
 
 #
 # USB Network adaptors
 #
-# CONFIG_USB_PLUSB is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
@@ -525,25 +584,30 @@
 # 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_IPAQ 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_KLSI 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
 
 #
-# Miscellaneous USB drivers
+# USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
 
 #
 # Input core support
@@ -560,6 +624,6 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_GDB_CONSOLE is not set
-CONFIG_LL_DEBUG=y
+CONFIG_DEBUG=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-decstation linux/arch/mips/defconfig-decstation
--- linux.orig/arch/mips/defconfig-decstation	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/defconfig-decstation	2002-07-20 01:08:37.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -10,52 +10,59 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 CONFIG_DECSTATION=y
-# CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_PB1000 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_PCI is not set
-# CONFIG_I8259 is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+CONFIG_IRQ_CPU=y
+CONFIG_NEW_IRQ=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
 CONFIG_CPU_R3000=y
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
@@ -67,24 +74,31 @@
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
-# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_WB=y
 
 #
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+CONFIG_TC=y
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_TC=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
 
 #
 # Memory Technology Devices (MTD)
@@ -97,6 +111,12 @@
 # CONFIG_PARPORT 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
@@ -104,7 +124,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -119,6 +141,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
 
 #
@@ -126,7 +149,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -139,17 +162,24 @@
 # CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -167,6 +197,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -206,6 +241,7 @@
 # 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
@@ -225,7 +261,6 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
@@ -251,6 +286,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -259,7 +295,6 @@
 # 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
@@ -280,6 +315,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -320,11 +356,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -364,13 +395,11 @@
 # 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
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -387,13 +416,10 @@
 #
 # DECStation Character devices
 #
-# CONFIG_VT is not set
 CONFIG_SERIAL=y
 # CONFIG_DZ is not set
 CONFIG_ZS=y
 CONFIG_SERIAL_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_RTC is not set
 
 #
@@ -410,7 +436,6 @@
 # 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_JBD_DEBUG is not set
@@ -423,11 +448,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS 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_FREEVXFS_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
@@ -468,6 +494,8 @@
 # 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
@@ -491,103 +519,19 @@
 # CONFIG_NLS is not set
 
 #
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-
-#
-# USB Device Class drivers
+# Sound
 #
-# 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
+# CONFIG_SOUND is not set
 
 #
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
+# USB 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_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_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_OMNINET is not set
+# CONFIG_USB is not set
 
 #
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
@@ -604,6 +548,6 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_GDB_CONSOLE is not set
-# CONFIG_LL_DEBUG is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-ev64120 linux/arch/mips/defconfig-ev64120
--- linux.orig/arch/mips/defconfig-ev64120	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-ev64120	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,534 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+CONFIG_MIPS_EV64120=y
+# CONFIG_EVB_PCI1 is not set
+# CONFIG_SYSCLK_75 is not set
+# CONFIG_SYSCLK_83 is not set
+CONFIG_SYSCLK_100=y
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_PCI=y
+# CONFIG_ISA is not set
+CONFIG_MIPS_GT64120=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_OLD_TIME_C=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+CONFIG_NET=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# 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 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=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA 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
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+CONFIG_NE2K_PCI=y
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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_LAN_SAA9730 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_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 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 is not set
+# CONFIG_JFFS2_FS is not set
+# 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_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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-ev96100 linux/arch/mips/defconfig-ev96100
--- linux.orig/arch/mips/defconfig-ev96100	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-ev96100	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,529 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+CONFIG_MIPS_EV96100=y
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_PCI=y
+CONFIG_MIPS_GT96100=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_PCI=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PCI_AUTO=y
+CONFIG_SWAP_IO_SPACE=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+CONFIG_CPU_RM7000=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# 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 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=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA 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
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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=y
+CONFIG_MIPS_GT96100ETH=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_TC35815 is not set
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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_LAN_SAA9730 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_TIGON3 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 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 is not set
+# CONFIG_JFFS2_FS is not set
+# 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_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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-hp-lj linux/arch/mips/defconfig-hp-lj
--- linux.orig/arch/mips/defconfig-hp-lj	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-hp-lj	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,668 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_ATLAS is not set
+CONFIG_MIPS_MALTA=y
+# CONFIG_NINO is not set
+# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_I8259=y
+CONFIG_PCI=y
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_SWAP_IO_SPACE=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_KCORE_ELF=y
+CONFIG_ELF_KERNEL=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+# 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 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 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=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA 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=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_CPQFCTS 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_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
+# 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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_LAN_SAA9730 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+CONFIG_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=y
+# 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=y
+# 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 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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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_IPAQ 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_KLSI 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
+
+#
+# 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-ip22 linux/arch/mips/defconfig-ip22
--- linux.orig/arch/mips/defconfig-ip22	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig-ip22	2002-07-20 01:08:40.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -10,58 +10,64 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 CONFIG_SGI_IP22=y
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_PB1000 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 CONFIG_ARC32=y
 CONFIG_BOARD_SCACHE=y
+CONFIG_IRQ_CPU=y
 CONFIG_PC_KEYB=y
 CONFIG_SGI=y
 CONFIG_NEW_IRQ=y
-CONFIG_OLD_TIME_C=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_PCI is not set
-# CONFIG_I8259 is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
@@ -70,6 +76,7 @@
 # CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_MIPS32 is not set
 # CONFIG_CPU_MIPS64 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -79,20 +86,28 @@
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
 CONFIG_BINFMT_IRIX=y
 CONFIG_FORWARD_KEYBOARD=y
 # CONFIG_ARC_CONSOLE is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=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
 
 #
 # Memory Technology Devices (MTD)
@@ -105,6 +120,12 @@
 # CONFIG_PARPORT 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
@@ -112,7 +133,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -127,6 +150,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
 
 #
@@ -134,8 +158,6 @@
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK=y
-CONFIG_RTNETLINK=y
 CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -156,12 +178,18 @@
 # 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -179,6 +207,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -219,6 +252,7 @@
 # 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
@@ -238,7 +272,6 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
@@ -273,7 +306,6 @@
 # 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
@@ -294,6 +326,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -334,11 +367,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 CONFIG_VT=y
@@ -358,7 +386,11 @@
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -377,14 +409,32 @@
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+CONFIG_INDYDOG=y
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+CONFIG_INDYDOG=y
 # 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
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -401,13 +451,9 @@
 #
 # SGI Character devices
 #
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
 CONFIG_SGI_NEWPORT_CONSOLE=y
 CONFIG_FONT_8x16=y
-# CONFIG_PSMOUSE is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_DUMMY_CONSOLE=y
 
 #
 # File systems
@@ -423,7 +469,6 @@
 # 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_JBD_DEBUG is not set
@@ -436,11 +481,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_FREEVXFS_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
@@ -481,6 +527,8 @@
 # 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
@@ -533,98 +581,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
@@ -639,5 +598,6 @@
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-it8172 linux/arch/mips/defconfig-it8172
--- linux.orig/arch/mips/defconfig-it8172	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig-it8172	2002-07-20 01:08:33.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -15,28 +15,31 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
 # CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_NINO is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MOMENCO_OCELOT is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SNI_RM200_PCI is not set
 CONFIG_MIPS_ITE8172=y
 # CONFIG_IT8172_REVC is not set
-CONFIG_QTRONIX_KEYBOARD=y
-CONFIG_IT8172_CIR=y
-# CONFIG_IT8172_SCR0 is not set
-# CONFIG_IT8172_SCR1 is not set
 # CONFIG_MIPS_IVR is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
@@ -45,26 +48,31 @@
 CONFIG_IT8712=y
 CONFIG_PC_KEYB=y
 CONFIG_NEW_PCI=y
+CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI_AUTO=y
+CONFIG_IT8172_CIR=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
-# CONFIG_I8259 is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
 
 #
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
@@ -91,6 +99,7 @@
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_SYSCTL=y
@@ -102,7 +111,6 @@
 # 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
 
 #
 # User Modules And Translation Layers
@@ -117,14 +125,17 @@
 # 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 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
 
 #
@@ -134,16 +145,9 @@
 CONFIG_MTD_PHYSMAP_START=8000000
 CONFIG_MTD_PHYSMAP_LEN=2000000
 CONFIG_MTD_PHYSMAP_BUSWIDTH=4
-# CONFIG_MTD_PNC2000 is not set
-# CONFIG_MTD_RPXLITE is not set
-# CONFIG_MTD_SBC_GXX is not set
-# CONFIG_MTD_ELAN_104NC is not set
-# CONFIG_MTD_DBOX2 is not set
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_CFI_FLAGADM is not set
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_VMAX is not set
 # CONFIG_MTD_OCELOT is not set
 
 #
@@ -152,6 +156,7 @@
 # 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
@@ -180,7 +185,7 @@
 # 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_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -194,16 +199,18 @@
 # 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_PACKET=y
+CONFIG_PACKET_MMAP=y
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
-# CONFIG_UNIX is not set
+CONFIG_UNIX=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -213,11 +220,13 @@
 # CONFIG_IP_PNP_RARP 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
 
 #
 #  
@@ -347,6 +356,16 @@
 # CONFIG_SCSI is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -359,6 +378,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -368,7 +388,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -382,6 +401,7 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
+# CONFIG_TC35815 is not set
 # CONFIG_TULIP_MWI is not set
 # CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
@@ -394,15 +414,18 @@
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
 CONFIG_8139TOO=y
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # 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_LAN_SAA9730 is not set
 # CONFIG_NET_POCKET is not set
@@ -469,8 +492,8 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_QTRONIX_KEYBOARD=y
-CONFIG_IT8172_CIR=y
+# CONFIG_QTRONIX_KEYBOARD is not set
+CONFIG_PC_KEYB=y
 # CONFIG_IT8172_SCR0 is not set
 # CONFIG_IT8172_SCR1 is not set
 CONFIG_UNIX98_PTYS=y
@@ -507,11 +530,10 @@
 # CONFIG_WATCHDOG is not set
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
+CONFIG_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -540,7 +562,6 @@
 # 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_JBD_DEBUG is not set
@@ -556,8 +577,9 @@
 # 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_FREEVXFS_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
@@ -598,6 +620,8 @@
 # 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
@@ -610,7 +634,31 @@
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+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_IT8172=y
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_HAL2 is not set
+CONFIG_SOUND_IT8172=y
+# 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_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
 
 #
 # USB support
@@ -629,13 +677,19 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # 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_JUMPSHOT 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
 
@@ -663,12 +717,10 @@
 #
 #   Video4Linux support is needed for USB Multimedia device support
 #
-# CONFIG_USB_DABUSB is not set
 
 #
 # USB Network adaptors
 #
-# CONFIG_USB_PLUSB is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
@@ -691,25 +743,30 @@
 # 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_IPAQ 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_KLSI 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
 
 #
-# Miscellaneous USB drivers
+# USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
 
 #
 # Input core support
@@ -726,6 +783,6 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_GDB_CONSOLE is not set
-# CONFIG_LL_DEBUG is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-ivr linux/arch/mips/defconfig-ivr
--- linux.orig/arch/mips/defconfig-ivr	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-ivr	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,763 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+CONFIG_MIPS_IVR=y
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_PCI=y
+CONFIG_PC_KEYB=y
+CONFIG_NEW_PCI=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PCI_AUTO=y
+CONFIG_IT8172_CIR=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+CONFIG_CPU_NEVADA=y
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# 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=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# 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_IDEDISK_STROKE 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 is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL 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_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CMD680 is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+CONFIG_BLK_DEV_IT8172=y
+CONFIG_IT8172_TUNING=y
+CONFIG_BLK_DEV_IT8172=y
+CONFIG_IT8172_TUNING=y
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# 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_PCI 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
+
+#
+# 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_TC35815 is not set
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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_LAN_SAA9730 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_TIGON3 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_QTRONIX_KEYBOARD=y
+CONFIG_IT8172_CIR=y
+# CONFIG_IT8172_SCR0 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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_NVRAM is not set
+CONFIG_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=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_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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+CONFIG_USB_OHCI=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# 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
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT is not set
+# CONFIG_USB_HIDDEV is not set
+# 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_RTL8150 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_IPAQ 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_KLSI 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
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-jmr3927 linux/arch/mips/defconfig-jmr3927
--- linux.orig/arch/mips/defconfig-jmr3927	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-jmr3927	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,671 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
+# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+CONFIG_TOSHIBA_JMR3927=y
+# CONFIG_HP_LASERJET is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_NONCOHERENT_IO=y
+CONFIG_TOSHIBA_BOARDS=y
+CONFIG_PCI=y
+CONFIG_NEW_PCI=y
+CONFIG_PCI_AUTO=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_PC_KEYB=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+CONFIG_CPU_TX39XX=y
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+# CONFIG_CPU_HAS_LLSC is not set
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_RTC_DS1742=y
+CONFIG_KCORE_ELF=y
+CONFIG_ELF_KERNEL=y
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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 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=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA 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
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+CONFIG_TC35815=y
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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_LAN_SAA9730 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI 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=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+# CONFIG_AU1000_UART is not set
+CONFIG_TXX927_SERIAL=y
+CONFIG_TXX927_SERIAL_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 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 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 is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW 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_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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+CONFIG_FBCON_MFB=y
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# 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
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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 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_IPAQ 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_KLSI 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
+
+#
+# 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-malta linux/arch/mips/defconfig-malta
--- linux.orig/arch/mips/defconfig-malta	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig-malta	2002-07-20 01:08:30.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -10,53 +10,62 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
-CONFIG_MIPS_MALTA=y
-# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+CONFIG_MIPS_MALTA=y
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_PB1000 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 CONFIG_I8259=y
 CONFIG_PCI=y
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
 CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
 CONFIG_SWAP_IO_SPACE=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
+CONFIG_PC_KEYB=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
@@ -65,6 +74,9 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_CPU_MIPS32=y
 # CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -74,18 +86,25 @@
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_SYSCTL 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
 
 #
 # Memory Technology Devices (MTD)
@@ -98,6 +117,12 @@
 # CONFIG_PARPORT is not set
 
 #
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
 # Block devices
 #
 CONFIG_BLK_DEV_FD=y
@@ -105,7 +130,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -121,13 +148,14 @@
 # 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_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -140,17 +168,24 @@
 # CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -168,6 +203,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -213,6 +253,7 @@
 # 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
@@ -233,8 +274,8 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 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
@@ -253,6 +294,16 @@
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -265,6 +316,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -274,7 +326,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -288,6 +339,7 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
@@ -298,15 +350,18 @@
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # 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_LAN_SAA9730 is not set
 # CONFIG_NET_POCKET is not set
@@ -321,6 +376,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -361,11 +417,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -405,13 +456,11 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -439,7 +488,6 @@
 # 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_JBD_DEBUG is not set
@@ -452,11 +500,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS 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_FREEVXFS_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
@@ -497,6 +546,8 @@
 # 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
@@ -517,98 +568,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
@@ -625,6 +587,6 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_GDB_CONSOLE is not set
-# CONFIG_LL_DEBUG is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-nino linux/arch/mips/defconfig-nino
--- linux.orig/arch/mips/defconfig-nino	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig-nino	2002-07-20 01:08:26.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -15,35 +15,43 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
 # CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 CONFIG_NINO=y
 # CONFIG_NINO_4MB is not set
 CONFIG_NINO_8MB=y
 # CONFIG_NINO_16MB is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MOMENCO_OCELOT is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_IVR is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
-# CONFIG_PCI is not set
-# CONFIG_I8259 is not set
 
 #
 # Loadable module support
@@ -56,10 +64,12 @@
 # CPU selection
 #
 CONFIG_CPU_R3000=y
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
@@ -81,10 +91,11 @@
 CONFIG_ELF_KERNEL=y
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=y
-# CONFIG_NET is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_SYSCTL is not set
@@ -111,10 +122,15 @@
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_BLK_DEV_RAM_SIZE=512
 CONFIG_BLK_DEV_INITRD=y
 
 #
+# MIPS initrd options
+#
+# CONFIG_EMBEDDED_RAMDISK is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -123,9 +139,54 @@
 # 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
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -145,13 +206,33 @@
 # 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
+
+#
+# Network device support
+#
+# CONFIG_NETDEVICES is not set
+
+#
 # Amateur Radio support
 #
 # CONFIG_HAMRADIO is not set
 
 #
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
 # ISDN subsystem
 #
+# CONFIG_ISDN is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -161,7 +242,8 @@
 #
 # Character devices
 #
-# CONFIG_VT is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 CONFIG_SERIAL_NONSTANDARD=y
@@ -184,8 +266,8 @@
 CONFIG_SERIAL_TX3912=y
 CONFIG_SERIAL_TX3912_CONSOLE=y
 # CONFIG_AU1000_UART is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_TXX927_SERIAL is not set
+# CONFIG_UNIX98_PTYS is not set
 
 #
 # I2C support
@@ -222,7 +304,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -250,7 +331,6 @@
 # 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_JBD_DEBUG is not set
@@ -266,8 +346,9 @@
 # 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_FREEVXFS_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
@@ -275,7 +356,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -285,8 +366,31 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
-# CONFIG_NCPFS_NLS 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
@@ -297,6 +401,50 @@
 # CONFIG_NLS is not set
 
 #
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+CONFIG_FB_TX3912=y
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+CONFIG_FBCON_MFB=y
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_CFB8 is not set
+# CONFIG_FBCON_CFB16 is not set
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# 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
@@ -318,13 +466,19 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # 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_JUMPSHOT 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
 
@@ -352,15 +506,15 @@
 #
 #   Video4Linux support is needed for USB Multimedia device support
 #
-# CONFIG_USB_DABUSB is not set
 
 #
 # USB Network adaptors
 #
-
-#
-#   Networking support is needed for USB Networking device support
-#
+# 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
 
 #
 # USB port drivers
@@ -378,25 +532,30 @@
 # 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_IPAQ 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_KLSI 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
 
 #
-# Miscellaneous USB drivers
+# USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
 
 #
 # Input core support
@@ -411,5 +570,6 @@
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-ocelot linux/arch/mips/defconfig-ocelot
--- linux.orig/arch/mips/defconfig-ocelot	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig-ocelot	2002-07-20 01:08:35.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -15,23 +15,30 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
 # CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_NINO is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 CONFIG_MOMENCO_OCELOT=y
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_IVR is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
@@ -40,10 +47,10 @@
 CONFIG_SYSCLK_100=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_NEW_IRQ=y
+CONFIG_NONCOHERENT_IO=y
 CONFIG_OLD_TIME_C=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
-# CONFIG_I8259 is not set
 
 #
 # Loadable module support
@@ -54,10 +61,12 @@
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
 CONFIG_CPU_RM7000=y
@@ -66,6 +75,8 @@
 # CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_MIPS32 is not set
 # CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -86,6 +97,7 @@
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -123,13 +135,14 @@
 # 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_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -142,11 +155,13 @@
 # CONFIG_IP_PNP_RARP 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
 
 #
 #  
@@ -189,6 +204,16 @@
 # CONFIG_SCSI is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -201,6 +226,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -210,7 +236,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -224,6 +249,7 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
@@ -234,15 +260,18 @@
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # 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_LAN_SAA9730 is not set
 # CONFIG_NET_POCKET is not set
@@ -347,7 +376,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -375,7 +403,6 @@
 # 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_JBD_DEBUG is not set
@@ -391,8 +418,9 @@
 # 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_FREEVXFS_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
@@ -433,6 +461,8 @@
 # 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
@@ -464,13 +494,19 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # 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_JUMPSHOT 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
 
@@ -498,12 +534,10 @@
 #
 #   Video4Linux support is needed for USB Multimedia device support
 #
-# CONFIG_USB_DABUSB is not set
 
 #
 # USB Network adaptors
 #
-# CONFIG_USB_PLUSB is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
@@ -526,25 +560,30 @@
 # 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_IPAQ 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_KLSI 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
 
 #
-# Miscellaneous USB drivers
+# USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
 
 #
 # Input core support
@@ -561,6 +600,6 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_GDB_CONSOLE is not set
-# CONFIG_LL_DEBUG is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-osprey linux/arch/mips/defconfig-osprey
--- linux.orig/arch/mips/defconfig-osprey	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-osprey	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,489 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+CONFIG_NEC_OSPREY=y
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_VR4181=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_MANY_PORTS=y
+CONFIG_NEW_IRQ=y
+CONFIG_IRQ_CPU=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_DUMMY_KEYB=y
+# CONFIG_SCSI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_R6000 is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+# CONFIG_CPU_HAS_LLSC is not set
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# 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=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_NE2000=y
+
+#
+# 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_TIGON3 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 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 is not set
+# CONFIG_JFFS2_FS is not set
+# 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_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=y
+# 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 is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-pb1000 linux/arch/mips/defconfig-pb1000
--- linux.orig/arch/mips/defconfig-pb1000	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig-pb1000	2002-07-20 01:08:32.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -10,52 +10,63 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+CONFIG_MIPS_PB1000=y
+CONFIG_PCI_AUTO=y
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-CONFIG_MIPS_PB1000=y
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 CONFIG_MIPS_AU1000=y
 CONFIG_NEW_IRQ=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_PCI is not set
-# CONFIG_I8259 is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
+CONFIG_PCI=y
+CONFIG_NEW_PCI=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+MAX_HWIFS=1
 
 #
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
@@ -64,6 +75,9 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_CPU_MIPS32=y
 # CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_ADVANCED=y
 CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -73,22 +87,107 @@
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
-# CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
+CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_CARDBUS is not set
+# CONFIG_TCIC is not set
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+CONFIG_PCMCIA_AU1000=m
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=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
 
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_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
+# 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_PB1000=y
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_MS02NV 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
 
 #
 # Parallel port support
@@ -96,6 +195,12 @@
 # CONFIG_PARPORT 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
@@ -103,8 +208,10 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -118,6 +225,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
 
 #
@@ -125,7 +233,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -138,17 +246,24 @@
 # CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -166,6 +281,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -175,9 +295,52 @@
 #
 # ATA/IDE/MFM/RLL support
 #
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
+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_IDEDISK_STROKE 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
+# CONFIG_IDE_TASK_IOCTL 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_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI 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
@@ -185,6 +348,16 @@
 # CONFIG_SCSI is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -197,6 +370,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -204,14 +378,15 @@
 CONFIG_NET_ETHERNET=y
 CONFIG_MIPS_AU1000_ENET=y
 # CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
 # CONFIG_NET_VENDOR_RACAL 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
@@ -226,6 +401,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -251,6 +427,11 @@
 # CONFIG_WAN is not set
 
 #
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
 # Amateur Radio support
 #
 # CONFIG_HAMRADIO is not set
@@ -266,11 +447,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -285,6 +461,7 @@
 # CONFIG_ESPSERIAL is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
@@ -296,6 +473,7 @@
 # CONFIG_SERIAL_TX3912_CONSOLE is not set
 CONFIG_AU1000_UART=y
 CONFIG_AU1000_SERIAL_CONSOLE=y
+# CONFIG_TXX927_SERIAL is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -328,13 +506,11 @@
 # 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
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -344,6 +520,13 @@
 # CONFIG_DRM is not set
 
 #
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+CONFIG_AU1000_GPIO=y
+# CONFIG_TS_AU1000_ADS7846 is not set
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -362,7 +545,6 @@
 # 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_JBD_DEBUG is not set
@@ -372,14 +554,16 @@
 # 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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
-CONFIG_ISO9660_FS=y
+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_FREEVXFS_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
@@ -387,7 +571,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_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
@@ -420,32 +604,43 @@
 # 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_PARTITION_ADVANCED 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=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+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_AU1000=y
+# 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_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
 
 #
 # USB support
@@ -453,98 +648,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
@@ -561,5 +667,6 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-pb1500 linux/arch/mips/defconfig-pb1500
--- linux.orig/arch/mips/defconfig-pb1500	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-pb1500	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,1002 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_MIPS_PB1500=y
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_MIPS_AU1000=y
+CONFIG_NEW_IRQ=y
+CONFIG_PCI=y
+CONFIG_PCI_AUTO=y
+CONFIG_NEW_PCI=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+CONFIG_CPU_HAS_WB=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_CARDBUS is not set
+# CONFIG_TCIC is not set
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_PCMCIA_AU1000 is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=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
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_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=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_PB1000 is not set
+CONFIG_MTD_PB1500=y
+CONFIG_MTD_PB1500_BOOT=y
+# CONFIG_MTD_PB1500_USER is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_MS02NV 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
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# 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=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# 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=y
+# CONFIG_IDEDISK_STROKE 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
+# CONFIG_IDE_TASK_IOCTL 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_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_OFFBOARD=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CMD680 is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# 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_PCI 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
+
+#
+# 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=y
+CONFIG_MIPS_AU1000_ENET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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_LAN_SAA9730 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_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# 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=m
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS 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 is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN 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=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+CONFIG_AU1000_UART=y
+CONFIG_AU1000_SERIAL_CONSOLE=y
+# CONFIG_TXX927_SERIAL is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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_NVRAM is not set
+CONFIG_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
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_AU1000_GPIO is not set
+# CONFIG_TS_AU1000_ADS7846 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_REISERFS_FS=m
+# 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=y
+CONFIG_JBD=y
+# 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=m
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=m
+CONFIG_TMPFS=y
+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_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=m
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=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 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 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
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT 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_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# 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_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_AU1000=y
+# 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_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+CONFIG_USB_OHCI=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# 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
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT is not set
+# CONFIG_USB_HIDDEV is not set
+# 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_RTL8150 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_IPAQ 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_KLSI 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
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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=y
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-rm200 linux/arch/mips/defconfig-rm200
--- linux.orig/arch/mips/defconfig-rm200	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/defconfig-rm200	2002-07-20 01:08:40.000000000 +0000
@@ -2,7 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
-# CONFIG_SMP is not set
+CONFIG_MIPS32=y
 
 #
 # Code maturity level options
@@ -10,57 +10,65 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SIBYTE_SB1250 is not set
 CONFIG_SNI_RM200_PCI=y
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_PB1000 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 CONFIG_ARC32=y
 CONFIG_I8259=y
 CONFIG_ISA=y
+CONFIG_NEW_IRQ=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_OLD_TIME_C=y
 CONFIG_PC_KEYB=y
 CONFIG_PCI=y
-CONFIG_ROTTEN_IRQ=y
-CONFIG_OLD_TIME_C=y
-CONFIG_EISA=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-CONFIG_CPU_R5000=y
+CONFIG_CPU_R4X00=y
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_NEVADA is not set
@@ -68,6 +76,7 @@
 # CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_MIPS32 is not set
 # CONFIG_CPU_MIPS64 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -77,26 +86,25 @@
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
 # CONFIG_ARC_CONSOLE is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
+CONFIG_EISA=y
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS 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
 
 #
 # Memory Technology Devices (MTD)
@@ -109,6 +117,12 @@
 # CONFIG_PARPORT is not set
 
 #
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
 # Block devices
 #
 CONFIG_BLK_DEV_FD=y
@@ -116,7 +130,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -131,6 +147,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
 
 #
@@ -138,7 +155,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -148,17 +165,24 @@
 # 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -176,6 +200,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -195,6 +224,16 @@
 # CONFIG_SCSI is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 # CONFIG_NETDEVICES is not set
@@ -259,13 +298,11 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -293,7 +330,6 @@
 # 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_JBD_DEBUG is not set
@@ -306,11 +342,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS 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_FREEVXFS_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
@@ -351,6 +388,8 @@
 # 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
@@ -395,98 +434,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
@@ -501,5 +451,6 @@
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/defconfig-sb1250-swarm linux/arch/mips/defconfig-sb1250-swarm
--- linux.orig/arch/mips/defconfig-sb1250-swarm	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/defconfig-sb1250-swarm	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,507 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SIBYTE_SB1250=y
+# CONFIG_PCI is not set
+# CONFIG_SIBYTE_SB1250_PROF is not set
+# CONFIG_BCM1250_TBPROF is not set
+# CONFIG_REMOTE_DEBUG is not set
+CONFIG_SIBYTE_SWARM=y
+# CONFIG_SIMULATION is not set
+# CONFIG_L3DEMO is not set
+CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS=16
+CONFIG_SMP=y
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_DUMMY_KEYB=y
+CONFIG_SWAP_IO_SPACE=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+CONFIG_CPU_SB1=y
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+CONFIG_SB1_PASS_1_WORKAROUNDS=y
+CONFIG_SB1_CACHE_ERROR=y
+CONFIG_VTAG_ICACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL 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
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# 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 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI 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=y
+CONFIG_NET_SB1250_MAC=y
+CONFIG_NET_SB1250_MAC=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_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_TIGON3 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+# CONFIG_AU1000_UART is not set
+# CONFIG_TXX927_SERIAL is not set
+CONFIG_SIBYTE_SB1250_DUART=y
+CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE=1024
+# CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 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=y
+CONFIG_JBD=y
+# 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=y
+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_QNX4FS_RW 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_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=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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 is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/Makefile linux/arch/mips/galileo-boards/ev64120/Makefile
--- linux.orig/arch/mips/galileo-boards/ev64120/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,26 @@
+#
+#  Copyright 2000 RidgeRun, Inc.
+#  Author: RidgeRun, Inc.
+#     	glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+#
+# Makefile for the Galileo EV64120 board.
+#
+# 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
+
+all:	ev64120.o int-handler.o
+
+O_TARGET := ev64120.o
+
+export-objs		= i2o.o
+
+obj-y	:= serialGT.o int-handler.o promcon.o reset.o setup.o irq.o \
+	   irq-handler.o i2o.o pci_bios.o
+
+int-handler.o: int-handler.S
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/cntmr.c linux/arch/mips/galileo-boards/ev64120/cntmr.c
--- linux.orig/arch/mips/galileo-boards/ev64120/cntmr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/cntmr.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,207 @@
+/* cntmr.c - GT counters/timers functions */
+
+/* Copyright - Galileo technology. 9/3/2000 */
+
+/*
+DESCRIPTION
+This file contains function which serves the user with a complete interface
+to the GT internal counters and timers, please advise: each counter/timer unit
+can function only as a counter or a timer at current time.
+Counter/timer 0 is 32 bit wide.
+Counters/timers 1-3 are 24 bit wide.
+*/
+
+/* includes */
+
+#ifdef __linux__
+#include <asm/galileo/evb64120A/cntmr.h>
+#include <asm/galileo/evb64120A/core.h>
+#else
+#include "cntmr.h"
+#include "core.h"
+#endif
+
+/********************************************************************
+* cntTmrStart - Starts a counter/timer with given an initiate value.
+*
+* INPUTS:  unsigned int countNum - Selects one of the 8 counters/timers.
+*          unsigned int countValue - Initial value for count down. 
+*          CNT_TMR_OP_MODES opMode - Set Mode, Counter or Timer.
+*
+* RETURNS: false if one of the parameters is erroneous, true otherwise.
+*********************************************************************/
+
+bool cntTmrStart(CNTMR_NUM countNum, unsigned int countValue,
+		 CNT_TMR_OP_MODES opMode)
+{
+	unsigned int command = 1;
+	unsigned int value;
+
+	if (countNum > LAST_CNTMR)
+		return false;
+	else {
+		GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+		cntTmrDisable(countNum);
+		GT_REG_WRITE((TIMER_COUNTER0 + (4 * countNum)),
+			     countValue);
+		command = command << countNum * 2;
+		value = value | command;
+		command = command << 1;
+		switch (opMode) {
+		case TIMER:	/* The Timer/Counter bit set to logic '1' */
+			value = value | command;
+			break;
+		case COUNTER:	/* The Timer/Counter bit set to logic '0' */
+			value = value & ~command;
+			break;
+		default:
+			return false;
+		}
+		GT_REG_WRITE(TIMER_COUNTER_CONTROL, value);
+		return true;
+	}
+}
+
+/********************************************************************
+* cntTmrDisable - Disables the timer/counter operation and return its 
+*                 value.
+*
+* INPUTS:  unsigned int countNum - Selects one of the 8 counters/timers.
+* RETURNS: The counter/timer value (unsigned int), if any of the arguments are 
+*          erroneous return 0.
+*********************************************************************/
+
+unsigned int cntTmrDisable(CNTMR_NUM countNum)
+{
+	unsigned int command = 1;
+	unsigned int regValue;
+	unsigned int value;
+
+	GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+	if (countNum > LAST_CNTMR)
+		return 0;
+	GT_REG_READ(TIMER_COUNTER0 + 4 * countNum, &regValue);
+	command = command << countNum * 2;	/* Disable the timer/counter */
+	value = value & ~command;
+	GT_REG_WRITE(TIMER_COUNTER_CONTROL, value);
+	return regValue;
+}
+
+/********************************************************************
+* cntTmrRead - Reads a timer or a counter value. (This operation can be
+*              perform while the counter/timer is active).
+*
+* RETURNS: The counter/timer value. If wrong input value, return 0.
+*********************************************************************/
+
+unsigned int cntTmrRead(CNTMR_NUM countNum)
+{
+	unsigned int value;
+	if (countNum > LAST_CNTMR)
+		return 0;
+	else
+		GT_REG_READ(TIMER_COUNTER0 + countNum * 4, &value);
+	return value;
+}
+
+/********************************************************************
+* cntTmrEnable - Set enable-bit of timer/counter.
+*                Be aware: If the counter/timer is active, this function
+*                          will terminate with an false.
+*
+* INPUTS:  unsigned int countNum - Selects one of the 8 counters/timers.
+* RETURNS: false if one of the parameters is erroneous, true otherwise.
+*********************************************************************/
+
+bool cntTmrEnable(CNTMR_NUM countNum)
+{
+	unsigned int command = 1;
+	unsigned int value;
+	GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+	if (countNum > LAST_CNTMR)
+		return false;
+	else {
+		command = command << countNum * 2;
+		if ((command & value) != 0)	/* ==> The counter/timer is enabled */
+			return false;	/* doesn't make sense to Enable an "enabled" counter */
+		value = value | command;
+		GT_REG_WRITE(TIMER_COUNTER_CONTROL, value);
+		return true;
+	}
+}
+
+/********************************************************************
+* cntTmrLoad - loading value for timer number countNum.
+*              Be aware: If this function try to load value to an enabled
+*                        counter/timer it terminate with false.
+*
+* INPUTS:  unsigned int countNum - Selects one of the 8 counters/timers.
+*          unsigned int countValue - The value for load the register.
+* RETURNS: false if one of the parameters is erroneous, true otherwise.
+*********************************************************************/
+
+bool cntTmrLoad(unsigned int countNum, unsigned int countValue)
+{
+	unsigned int command = 1;
+	unsigned int value;
+	GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+	if (countNum > LAST_CNTMR)
+		return false;
+	else {
+		command = command << countNum * 2;
+		value = value & command;
+		if (value != 0) {	/* ==> The counter/timer is enabled */
+			return false;	/* can't reload value when counter/timer is enabled */
+		} else {
+			GT_REG_WRITE((TIMER_COUNTER0 + (4 * countNum)),
+				     countValue);
+			return true;
+		}
+
+	}
+}
+
+/********************************************************************
+* cntTmrSetMode - Configurate the Mode of the channel to work as a counter
+*                 or as a timer. (for more details on the different between
+*                 those two modes is written in the Data Sheet).
+*                 NOTE: This function only set the counter/timer mode and
+*                 don't enable it. 
+*                 Be aware: If this function try to load value to an enabled
+*                           counter/timer it terminate with false.
+* 
+* INPUTS:  unsigned int countNum - Selects one of the 8 counters/timers.
+*          CNT_TMR_OP_MODES opMode - TIMER or COUNTER mode.
+* RETURNS: false if one of the parameters is erroneous true otherwise .
+*********************************************************************/
+
+bool cntTmrSetMode(CNTMR_NUM countNum, CNT_TMR_OP_MODES opMode)
+{
+	unsigned int command = 1;
+	unsigned int value;
+
+	GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+	if (countNum > LAST_CNTMR)
+		return false;
+	else {
+		command = command << countNum * 2;
+		value = value & command;
+		if (value != 0) {	/* ==> The counter/timer is enabled */
+			return false;	/* can't set the Mode when counter/timer is enabled */
+		} else {
+			command = command << 1;
+			switch (opMode) {
+			case TIMER:
+				value = value | command;	/* The Timer/Counter bit set to logic '1' */
+				break;
+			case COUNTER:
+				value = value & ~command;	/*The Timer/Counter bit set to logic '0' */
+				break;
+			default:
+				return false;
+			}
+			GT_REG_WRITE(TIMER_COUNTER_CONTROL, value);
+			return true;
+		}
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/Makefile linux/arch/mips/galileo-boards/ev64120/compressed/Makefile
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,177 @@
+# =============================================================
+#
+# linux/arch/mips/galileo/compressed/Makefile
+#
+# By RidgeRun Inc.
+#
+# Description:
+#   Create a system containing a copy of the compressed vmlinux kernel.
+#   The system knows how to decompress the contained kernel and then
+#   jump to it resulting in a linux kernel boot.
+#
+#   The system comes in three forms:
+#
+#       1. - ramsys - 
+#          to be loaded into ram then run. When run
+#          it decompresses the kernel housed in its internal
+#          data structures and then jumps to the image which
+#          results in a linux kernel boot.
+#
+#       2. - flashsys - 
+#          to be loaded into ram so that it can be
+#          burned into the onboard flash. Then the board jumpers
+#          can be switched so that the next power cycle caused
+#          the system in flash to run which then proceeds as
+#          described by #1 above.
+#          Note: burner.srec is the utility that will allow
+#          the user to get this image into flash.
+#
+#       3. - flashsys2 - 
+#          to be loaded into ram so that it can be
+#          burned into the onboard flash. Then on each power
+#          cycle when the standard PMON prompt is presented 
+#          the user can type `call 0xbf000000` to invoke
+#          the system in flash which then proceeds as
+#          described by #1 above.
+#          Note: burner.srec is the utility that will allow
+#          the user to get this image into flash.
+#
+#       4. - burner.srec -
+#          related to #2 and #3 above.
+#
+# =============================================================
+
+USE_STANDARD_AS_RULE := true
+
+all: ramsys.srec \
+     flashsys.srec \
+     flashsys2.srec \
+     burner.srec
+
+SYSTEM = $(TOPDIR)/vmlinux
+
+CFLAGS_2 = -DCONSOLE_SERIAL -DDELIMITERLINES -DGALILEO_PORT \
+           -DANSIESC -DELF_IMAGE -DELF_IMAGE -DDOWNLOAD_PROTO_TFTP \
+           -DEVB64120A -D__MIPSEB__ -DINCLUDE_EEPRO100 \
+           -DINCLUDE_GETH0 -DNOPRINTK -DPROM -DCOMPRESSEDVMLINUX
+
+sbdreset_evb64120A.o:
+	$(CC) $(CFLAGS) $(CFLAGS_2) -c sbdreset_evb64120A.S -o $*.o
+memory.o:
+	$(CC) $(CFLAGS) $(CFLAGS_2) -c memory.c -o $*.o
+pci.o:
+	$(CC) $(CFLAGS) $(CFLAGS_2) -c pci.c -o $*.o
+pci_etherboot.o:
+	$(CC) $(CFLAGS) $(CFLAGS_2) -c pci_etherboot.c -o $*.o
+load.o:
+	$(CC) $(CFLAGS) $(CFLAGS_2) -c load.c -o $*.o
+flashdrv.o:
+	$(CC) $(CFLAGS) $(CFLAGS_2) -c flashdrv.c -o $*.o
+
+gz2asm: gz2asm.c
+	g++ -o gz2asm gz2asm.c
+
+doit: doit.c
+	gcc -o doit doit.c
+
+piggy.gz: $(SYSTEM)
+	rm -f piggy piggy.gz 
+	$(OBJCOPY) -S -O binary $(SYSTEM) piggy
+	gzip -f -9 < piggy > piggy.gz
+
+piggy.S: doit fixit piggy.gz
+	./doit < piggy.gz > piggy.S; . ./fixit piggy.S
+
+OBJECTS_ramsys    = head.o misc.o piggy.o ../serialGT.o
+OBJECTS_flashsys  = sbdreset_evb64120A.o evb64120A_Setup.o pci_etherboot.o memory.o pci.o head.o misc.o piggy.o ../serialGT.o
+OBJECTS_flashsys2 = xfer.o head.o misc.o piggy.o ../serialGT.o
+OBJECTS_burner    = burner.o load.o flashdrv.o
+
+ramsys.srec : $(OBJECTS_ramsys) ld.script.gal
+	@# Note: this image is intended to run out of ram. No flash involved.
+	$(LD) -T ld.script.gal -o ramsys $(OBJECTS_ramsys) 
+	$(NM) ramsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_ramsys.map
+	$(OBJCOPY) -O srec ramsys ramsys.srec
+	cp ramsys.srec $(TOPDIR)/.
+
+flashsys.srec : $(OBJECTS_flashsys) ld.sys.big.Flash
+	@# Note1: Use the burn utility to get this image into flash.
+	@# Note2: This image is intended to run out of flash as invoked
+	@# directly at powerup when EVB64120A jumpers are configured to 
+	@# bypass the onboard eprom.
+	@# Assumes that 0xBFC00000 is the bootup run address (normal MIPS).
+	@# And assumes that EVB64120A jumber J11 is added to the board and jumber
+	@# J20 is moved from the 2&3 position to the 1&2 position instead. Without
+	@# the jumper settings the system will execute at address 0xBFC00000,
+	@# as normal, yet that address will map to the onboard eeprom instead
+	@# of the onboard flash.
+	@# 
+	$(LD) -T ld.sys.big.Flash -o flashsys $(OBJECTS_flashsys) 
+	$(NM) flashsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys.map
+	@#
+	@# Next, Create the image that we want to place in the flash part.
+	$(OBJCOPY)  -S -g --strip-unneeded \
+	      --adjust-section-vma=.text+0x3f820000 \
+	      --adjust-section-vma=.rodata+0x3f820000 \
+	      --adjust-section-vma=.reginfo+0x3f820000 \
+	      --adjust-section-vma=.data+0x3f820000  \
+	      --remove-section=.bss \
+	      --remove-section=.scommon \
+	      --remove-section=.note \
+	      --remove-section=.comment \
+	      flashsys flashsys.temp
+	@#
+	@# Next, change the addresses so that when we download to
+	@# to the board's ram it will land starting at address 0xA0300000
+	@# because this is where we have choosen to have the image temporarily sit
+	@# while we subsequently burn it (using some method not revealed here) into
+	@# the board's flash. After the burn the system can be setup (via jumpers) 
+	@# to boot this image directory from the flash part.
+	$(OBJCOPY) -O srec --adjust-vma=0xe0700000 flashsys.temp flashsys.srec
+	cp flashsys.srec $(TOPDIR)/.
+
+flashsys2.srec : $(OBJECTS_flashsys2) ld.sys.big.Flash2
+	@# Note1: Use the burn utility to get this image into flash.
+	@# Note2: This image is intended to be run out of flash as invoked
+	@# manually from the standard PMON running in eprom. This means that
+	@# the image will be set to run from location 0xBF000000 which is the
+	@# location the flash is mapped to when the board jumpers are set to
+	@# the standard location such that the board boots out of onboard
+	@# eprom. From the PMON prompt the user can type `call 0xbf000000`
+	@# to transfer control to the image we are constructing here.
+	@# 
+	$(LD) -T ld.sys.big.Flash2 -o flashsys2 $(OBJECTS_flashsys2) 
+	$(NM) flashsys2 | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys2.map
+	@#
+	@# Next, Create the image that we want to place in the flash part.
+	$(OBJCOPY)  -S -g --strip-unneeded \
+	      --adjust-section-vma=.text+0x3ec20000 \
+	      --adjust-section-vma=.rodata+0x3ec20000 \
+	      --adjust-section-vma=.reginfo+0x3ec20000 \
+	      --adjust-section-vma=.data+0x3ec20000  \
+	      --remove-section=.bss \
+	      --remove-section=.scommon \
+	      --remove-section=.note \
+	      --remove-section=.comment \
+	      flashsys2 flashsys2.temp
+	@#
+	@# Next, change the addresses so that when we download to
+	@# to the board's ram it will land starting at address 0xA0300000
+	@# because this is where we have choosen to have the image temporarily sit
+	@# while we subsequently burn it (using some method not revealed here) into
+	@# the board's flash. After the burn a user will then be able to type
+	@# `call 0xbf000000` at the PMON prompt (following a power cycle) to invoke
+	@# the linux kernel.
+	$(OBJCOPY) -O srec --adjust-vma=0xe1300000 flashsys2.temp flashsys2.srec
+	cp flashsys2.srec $(TOPDIR)/.
+
+burner.srec : $(OBJECTS_burner) ld.sys.big.burner
+	@# This utility can be used to burn the flashsys.srec or flashsys2.srec
+	@# into the EVB64120A's on board flash part (1Meg minimum).
+	$(LD) -T ld.sys.big.burner -o burner $(OBJECTS_burner) 
+	$(NM) burner | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_burner.map
+	$(OBJCOPY) -O srec burner burner.srec
+	cp burner.srec $(TOPDIR)/.
+
+clean:
+	rm -f doit piggy.S piggy.gz piggy burner *.o ramsys* flashsys* System*.map *.srec
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/README linux/arch/mips/galileo-boards/ev64120/compressed/README
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/README	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/README	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,131 @@
++------------------------------------------------+
+|  $TOPDIR/arch/mips/galileo/compressed/README   |
+|                                                |
+|  By RidgeRun Inc,                              |
+|  Aug, 2000                                     |
++------------------------------------------------+
+
+Description:
+============
+  It is intended that this makefile be wired in to run as
+  part of a top level linux build. For example, at the
+  time of this writing, if the user types "make gboot" at
+  the top level then in addition to building vmlinux the
+  build system's makefiles will descend into this
+  directory and build the "all:" target of this
+  Makefile. This will have the result of compressing the
+  vmlinux system and producing four separate systems. The
+  following snippet is pulled from this directory's
+  Makefile and describes each system.
+
+  Four systems are availalbe for download to the EVB64120A
+  board.
+
+   1. - ramsys - 
+      To be loaded into ram then run. When run
+      it decompresses the "vmlinux" kernel housed in its internal
+      data structures and then jumps to the image which
+      results in a linux kernel boot.
+
+   2. - flashsys - 
+      To be loaded into ram so that it can be
+      burned into the onboard flash. Then the board jumpers
+      can be switched so that the next power cycle caused
+      the system in flash to run which then proceeds as
+      described by #1 above.
+      Note: burner.srec is the utility that will allow
+      the user to get this image into flash.
+
+   3. - flashsys2 - 
+      To be loaded into ram so that it can be
+      burned into the onboard flash. Then on each power
+      cycle when the standard PMON prompt is presented 
+      the user can type `call 0xbf000000` to invoke
+      the system in flash which then proceeds as
+      described by #1 above.
+      Note: burner.srec is the utility that will allow
+      the user to get this image into flash.
+
+   4. - burner.srec -
+      Related to #2 and #3 above.
+
+Example: Running from Ram
+==========================
+
+  In this scenario the compressed system is downloaded
+  into ram and run directly from there. No flash is involved 
+  in this scenario. Naturally, the download must be repeated 
+  on every power cycle.
+
+  1. At the PMON prompt type `load`
+  2. Assuming you have your host connected to /dev/ttyS0
+     type the following command in a host shell window.
+     `cat ramsys.srec > /dev/ttyS0`
+  3. When the download completes type the following
+     at the PMON prompt: `g`
+
+
+Example: Running from flash: Scenario #1
+========================================
+
+  In this scenario vmlinux runs out of flash code
+  automatically on every power up. This means that 
+  standard PMON code (of eprom) never runs.
+
+  1. Place the boot jumpers in the Boot-from-eprom
+     state. This is the normal state and how the jumpers
+     are found when booting PMON.
+
+     Jumper settings. J11 - Removed
+                      J20 - Moved from the 1&2 position to 
+                            the 2&3 position instead
+
+  2. Use PMON to "load" the burner.srec image and then
+     run it. This utility will prompt you to download
+     the image that you want burned into the flash
+     part.
+
+  3. Send the flashsys.srec image to the running burner
+     utility. The utililty will indicate when the burn
+     process has completed.
+
+  4. Now switch off power and change the jumpers to 
+     the boot-from-flash position. The next power cycle
+     will run the flash based system automatically.
+
+     Jumper settings. J11 - Added.
+                      J20 - Moved from the 2&3 position to 
+                            the 1&2 position instead
+
+Example: Running from flash: Scenario #2
+========================================
+
+  In this scenario vmlinux runs out of flash only if the
+  PMON user decides to jump there by issuing a command to
+  PMON. Every power cycle would continue to bring up PMON
+  and a user will have to reissue the jump command to
+  force control transfer to the flash system.
+
+  1. Insure that the boot jumpers are in the Boot-from-eprom
+     state. This is the normal state and how the jumpers
+     are found when booting PMON.
+
+     Jumper settings. J11 - Removed
+                      J20 - Moved from the 1&2 position to 
+                            the 2&3 position instead
+
+  2. Use PMON to "load" the burner.srec image and then
+     run it. This utility will prompt you to download
+     the image that you want burned into the flash
+     part.
+
+  3. Send the flashsys2.srec image to the running burner
+     utility. The utililty will indicate when the burn
+     process has completed.
+
+  4. Now that the image is in flash the user can invoke
+     the following PMON command whenever a vmlinux
+     boot is desired:
+
+     call 0xbf000000
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/burner.c linux/arch/mips/galileo-boards/ev64120/compressed/burner.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/burner.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/burner.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,230 @@
+/*
+ *  arch/mips/galileo/compressed/burner.c
+ *
+ *  By RidgeRun Inc (Leveraged from Galileo's main.c, misc.c, etc).
+ *
+ *  Burn image from ram to flash 
+ *  For use with Galileo EVB64120A MIPS eval board.
+ */
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <asm/galileo-boards/evb64120A/eeprom_param.h>
+#include <asm/galileo-boards/evb64120A/flashdrv.h>
+
+#define IMAGEOFFSET 0x00300000
+
+static void burn_image_from_memory(void);
+static char *sprintf(char *buf, const char *fmt, ...);
+static void printf(const char *fmt, ...);
+
+unsigned int FlashSize;
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+int main(void)
+{
+	printf("\n");
+	printf("\n");
+	printf("\n");
+	printf("\n");
+	printf("       +--------------------+\n");
+	printf("       |                    |\n");
+	printf("       | Flash Burn Utility |\n");
+	printf("       |                    |\n");
+	printf("       +--------------------+\n");
+	printf("\n");
+	printf("Please send your *.srec image to the parallel port\n");
+	printf("\n");
+	printf("Note: The *.srec image should be setup to\n");
+	printf("      load into address 0xa0300000 where\n");
+	printf("      it will then be transferred to flash\n");
+	printf("\n");
+
+	SET_REG_BITS(0x468, BIT20);	// Set Flash to be 16 bit wide
+	FlashSize = flashInit(0xbf000000, 2, X16);
+
+	galileo_dl();		// read in the users *.srec image.
+	burn_image_from_memory();	// put it in flash.
+
+	printf("\n");
+	printf("\n");
+	printf("+---------------+\n");
+	printf("|     Done      |\n");
+	printf("|(please reboot)|\n");
+	printf("+---------------+\n");
+	printf("\n");
+
+	while (1) {
+	}
+	return 0;
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static void burn_image_from_memory(void)
+{
+	unsigned int count, delta, temp, temp1;
+	unsigned int to_sector, last_sector;
+
+	/* Find how many sectors needed to be erased */
+	to_sector = flashInWhichSector(FlashSize - 4);	// skranz, modified.
+	if (to_sector == 0xffffffff) {
+		printf
+		    ("Flash Burning Error - Flash too small - Cannot burn image\n");	// skranz, modified.
+		return;
+	}
+
+	/* Which is the last sector */
+	last_sector = flashInWhichSector(FlashSize - 4);
+	delta = 0;
+	printf("\nErasing first %d sectors\n", to_sector);
+	for (count = 0; count < to_sector + 1; count++) {
+		printf("Erasing sector %d\n", count);
+		flashEraseSector(count);
+	}
+	printf("flash region size = %d\n", FlashSize);	// skranz, added
+	printf("Sdram IMAGEOFFSET = %d\n", IMAGEOFFSET);	// skranz, added
+
+	printf("Burning from Sdram to %d mark; full burn.\n", FlashSize);
+	for (count = 0; count < (FlashSize - delta); count = count + 4) {
+		flashWriteWord(count,
+			       *(unsigned int *) ((count | NONE_CACHEABLE)
+						  + IMAGEOFFSET));	// skranz, modified.
+		temp = flashReadWord(count);
+		temp1 = *(unsigned int *) ((count | NONE_CACHEABLE) + IMAGEOFFSET);	// skranz, modified.
+		if (((unsigned int) temp) != ((unsigned int) temp1)) {
+			printf
+			    ("Burning error at address %X : flash(%X) sdram(%X)\n",
+			     count, flashReadWord(count),
+			     *(unsigned int *) ((count | NONE_CACHEABLE) + IMAGEOFFSET));	// skranz, modified.
+			printf("Aborting Prematurally.\n");
+			break;
+		}
+	}
+	printf("Finished burning Image\n");
+}
+
+/******************************
+ Routine:
+ Description:
+	Formats:
+		%X	- 4 byte ASCII (8 hex digits)
+		%x	- 2 byte ASCII (4 hex digits)
+		%b	- 1 byte ASCII (2 hex digits)
+		%d	- decimal (also %i)
+		%c	- ASCII char
+		%s	- ASCII string
+		%I	- Internet address in x.x.x.x notation
+ ******************************/
+static char hex[] = "0123456789ABCDEF";
+static char *do_printf(char *buf, const char *fmt, const int *dp)
+{
+	register char *p;
+	char tmp[16];
+	while (*fmt) {
+		if (*fmt == '%') {	/* switch() uses more space */
+			fmt++;
+
+			if (*fmt == 'X') {
+				const long *lp = (const long *) dp;
+				register long h = *lp++;
+				dp = (const int *) lp;
+				*(buf++) = hex[(h >> 28) & 0x0F];
+				*(buf++) = hex[(h >> 24) & 0x0F];
+				*(buf++) = hex[(h >> 20) & 0x0F];
+				*(buf++) = hex[(h >> 16) & 0x0F];
+				*(buf++) = hex[(h >> 12) & 0x0F];
+				*(buf++) = hex[(h >> 8) & 0x0F];
+				*(buf++) = hex[(h >> 4) & 0x0F];
+				*(buf++) = hex[h & 0x0F];
+			}
+			if (*fmt == 'x') {
+				register int h = *(dp++);
+				*(buf++) = hex[(h >> 12) & 0x0F];
+				*(buf++) = hex[(h >> 8) & 0x0F];
+				*(buf++) = hex[(h >> 4) & 0x0F];
+				*(buf++) = hex[h & 0x0F];
+			}
+			if (*fmt == 'b') {
+				register int h = *(dp++);
+				*(buf++) = hex[(h >> 4) & 0x0F];
+				*(buf++) = hex[h & 0x0F];
+			}
+			if ((*fmt == 'd') || (*fmt == 'i')) {
+				register int dec = *(dp++);
+				p = tmp;
+				if (dec < 0) {
+					*(buf++) = '-';
+					dec = -dec;
+				}
+				do {
+					*(p++) = '0' + (dec % 10);
+					dec = dec / 10;
+				} while (dec);
+				while ((--p) >= tmp)
+					*(buf++) = *p;
+			}
+			if (*fmt == 'I') {
+				union {
+					long l;
+					unsigned char c[4];
+				} u;
+				const long *lp = (const long *) dp;
+				u.l = *lp++;
+				dp = (const int *) lp;
+				buf = sprintf(buf, "%d.%d.%d.%d",
+					      u.c[0], u.c[1], u.c[2],
+					      u.c[3]);
+			}
+			if (*fmt == 'c')
+				*(buf++) = *(dp++);
+			if (*fmt == 's') {
+				p = (char *) *dp++;
+				while (*p)
+					*(buf++) = *p++;
+			}
+		} else
+			*(buf++) = *fmt;
+		fmt++;
+	}
+	*buf = 0;
+	return (buf);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static char *sprintf(char *buf, const char *fmt, ...)
+{
+	return do_printf(buf, fmt, ((const int *) &fmt) + 1);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void putchar(int c)
+{
+	if (c == '\n') {
+		serial_putc('\r');
+	}
+	serial_putc(c);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static void printf(const char *fmt, ...)
+{
+	char buf[256], *p;
+	p = buf;
+	do_printf(buf, fmt, ((const int *) &fmt) + 1);
+	while (*p)
+		putchar(*p++);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/doit.c linux/arch/mips/galileo-boards/ev64120/compressed/doit.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/doit.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/doit.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,75 @@
+/*
+ *    By RidgeRun Inc.
+ *
+ *    The input to this program is intended to be
+ *    a compressed linux kernel. The output of this
+ *    program is then a constructed *.S file which
+ *    defines a large data structure -- the contents
+ *    of which represent the compressed kernel which
+ *    can subsequently be used in a program designed
+ *    to access that struture for decompression at
+ *    runtime and then subsequent kernel bootup.
+ *
+ *    Example Usage:
+ *       ./doit < piggy.gz > piggy.S
+ *       
+ */
+
+#include <stdio.h>
+
+void printval(int i)
+{
+	int tth, th, h, t, d;
+
+	if (i > 99999) {
+		printf("Error - printval outofbounds\n");
+		return;
+	}
+
+	tth = 0;
+	th = 0;
+	//tth = (i) / 10000;
+	//th  = (i - (tth * 10000)) / 1000;
+	h = (i - ((tth * 10000) + (th * 1000))) / 100;
+	t = (i - ((tth * 10000) + (th * 1000) + (h * 100))) / 10;
+	d = (i - ((tth * 10000) + (th * 1000) + (h * 100) + (t * 10)));
+	//putchar(tth + '0');
+	//putchar(th + '0');
+	putchar(h + '0');
+	putchar(t + '0');
+	putchar(d + '0');
+}
+
+main(int argc, char **argv)
+{
+	int val;
+	int size = 0;
+	unsigned char c;
+
+	printf("gcc2_compiled.:\n");
+	printf("__gnu_compiled_c:\n");
+	printf("\t.globl linux_compressed_start\n");
+	printf("\t.text\n");
+	printf("\t.align 2\n");
+	printf("\t.type linux_compressed_start,@object\n");
+	printf("linux_compressed_start:\n");
+
+
+	val = getchar();
+	while (val != EOF) {
+		size++;
+		c = (unsigned char) (val & 0x00ff);
+		printf("\t.byte  ");
+		printval((int) c);
+		printf("\n");
+		val = getchar();
+	}
+	printf("\t.size linux_compressed_start,%d\n", size);
+	printf("\t.globl linux_compressed_size\n");
+	printf("\t.text\n");
+	printf("\t.align 2\n");
+	printf("\t.type linux_compressed_size,@object\n");
+	printf("\t.size linux_compressed_size,4\n");
+	printf("linux_compressed_size:\n");
+	printf("\t.word %d\n", size);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/etherboot.h linux/arch/mips/galileo-boards/ev64120/compressed/etherboot.h
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/etherboot.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/etherboot.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,566 @@
+/**************************************************************************
+ETHERBOOT -  BOOTP/TFTP Bootstrap Program
+
+Author: Martin Renters
+  Date: Dec/93
+
+**************************************************************************/
+
+#include "osdep.h"
+
+/* These could be customised for different languages perhaps */
+#define	ASK_PROMPT	"Boot from (N)etwork or from (L)ocal? "
+#define	ANS_NETWORK	'N'
+#define	ANS_LOCAL	'L'
+#ifndef	ANS_DEFAULT		/* in case left out in Makefile */
+#define	ANS_DEFAULT	ANS_NETWORK
+#endif
+
+#define	TAGGED_IMAGE		/* eventually optional */
+#if	!defined(TAGGED_IMAGE) && !defined(AOUT_IMAGE) && !defined(ELF_IMAGE)
+#define	TAGGED_IMAGE		/* choose at least one */
+#endif
+
+#define ESC		0x1B
+
+#ifndef	DEFAULT_BOOTFILE
+#define DEFAULT_BOOTFILE	"/tftpboot/kernel"
+#endif
+
+/* Clean up console settings... mainly CONSOLE_CRT and CONSOLE_SERIAL are used
+ * in the sources (except start.S and serial.S which cannot include
+ * etherboot.h).  At least one of the CONSOLE_xxx has to be set, and
+ * CONSOLE_DUAL sets both CONSOLE_CRT and CONSOLE_SERIAL.  If none is set,
+ * CONSOLE_CRT is assumed.  */
+#ifdef	CONSOLE_DUAL
+#undef CONSOLE_CRT
+#define CONSOLE_CRT
+#undef CONSOLE_SERIAL
+#define CONSOLE_SERIAL
+#endif
+#if	defined(CONSOLE_CRT) && defined(CONSOLE_SERIAL)
+#undef CONSOLE_DUAL
+#define CONSOLE_DUAL
+#endif
+#if	!defined(CONSOLE_CRT) && !defined(CONSOLE_SERIAL)
+#define CONSOLE_CRT
+#endif
+
+#ifndef	DOWNLOAD_PROTO_NFS
+#undef DOWNLOAD_PROTO_TFTP
+#define DOWNLOAD_PROTO_TFTP	/* default booting protocol */
+#endif
+
+#ifdef	DOWNLOAD_PROTO_TFTP
+#define download(fname,loader) tftp((fname),(loader))
+#endif
+#ifdef	DOWNLOAD_PROTO_NFS
+#define download(fname,loader) nfs((fname),(loader))
+#endif
+
+#ifndef	MAX_TFTP_RETRIES
+#define MAX_TFTP_RETRIES	20
+#endif
+
+#ifndef	MAX_BOOTP_RETRIES
+#define MAX_BOOTP_RETRIES	20
+#endif
+
+#ifndef	MAX_BOOTP_EXTLEN
+#if	(RELOC < 0x94000)
+/* Force internal buffer (if external buffer would overlap with our code...) */
+#undef INTERNAL_BOOTP_DATA
+#define INTERNAL_BOOTP_DATA
+#endif
+/* sizeof(struct bootp_t) == 0x240 */
+#if	defined(INTERNAL_BOOTP_DATA) || (RELOC >= 0x94240)
+#define MAX_BOOTP_EXTLEN	1024
+#else
+#define MAX_BOOTP_EXTLEN	(1024-sizeof(struct bootp_t))
+#endif
+#endif
+
+#ifndef	MAX_ARP_RETRIES
+#define MAX_ARP_RETRIES		20
+#endif
+
+#ifndef	MAX_RPC_RETRIES
+#define MAX_RPC_RETRIES		20
+#endif
+
+#define	TICKS_PER_SEC		18
+
+/* Inter-packet retry in ticks */
+#define TIMEOUT			(10*TICKS_PER_SEC)
+
+/* These settings have sense only if compiled with -DCONGESTED */
+/* total retransmission timeout in ticks */
+#define TFTP_TIMEOUT		(30*TICKS_PER_SEC)
+/* packet retransmission timeout in ticks */
+#define TFTP_REXMT		(3*TICKS_PER_SEC)
+
+#ifndef	NULL
+#define NULL	((void *)0)
+#endif
+
+#define TRUE		1
+#define FALSE		0
+
+#define ETHER_ADDR_SIZE		6	/* Size of Ethernet address */
+#define ETHER_HDR_SIZE		14	/* Size of ethernet header */
+#define ETH_MIN_PACKET		64
+#define ETH_MAX_PACKET		1518
+
+#define VENDOR_NONE	0
+#define VENDOR_WD	1
+#define VENDOR_NOVELL	2
+#define VENDOR_3COM	3
+#define VENDOR_3C509	4
+#define VENDOR_CS89x0	5
+
+#define FLAG_PIO	0x01
+#define FLAG_16BIT	0x02
+#define FLAG_790	0x04
+
+#define ARP_CLIENT	0
+#define ARP_SERVER	1
+#define ARP_GATEWAY	2
+#define ARP_ROOTSERVER	3
+#define ARP_SWAPSERVER	4
+#define MAX_ARP		ARP_SWAPSERVER+1
+
+#define	RARP_REQUEST	3
+#define	RARP_REPLY	4
+
+#define IP		0x0800
+#define ARP		0x0806
+#define	RARP		0x8035
+
+#define BOOTP_SERVER	67
+#define BOOTP_CLIENT	68
+#define TFTP_PORT	69
+#define SUNRPC_PORT	111
+
+#define IP_UDP		17
+/* Same after going through htonl */
+#define IP_BROADCAST	0xFFFFFFFF
+
+#define ARP_REQUEST	1
+#define ARP_REPLY	2
+
+#define BOOTP_REQUEST	1
+#define BOOTP_REPLY	2
+
+#define TAG_LEN(p)		(*((p)+1))
+#define RFC1533_COOKIE		99, 130, 83, 99
+#define RFC1533_PAD		0
+#define RFC1533_NETMASK		1
+#define RFC1533_TIMEOFFSET	2
+#define RFC1533_GATEWAY		3
+#define RFC1533_TIMESERVER	4
+#define RFC1533_IEN116NS	5
+#define RFC1533_DNS		6
+#define RFC1533_LOGSERVER	7
+#define RFC1533_COOKIESERVER	8
+#define RFC1533_LPRSERVER	9
+#define RFC1533_IMPRESSSERVER	10
+#define RFC1533_RESOURCESERVER	11
+#define RFC1533_HOSTNAME	12
+#define RFC1533_BOOTFILESIZE	13
+#define RFC1533_MERITDUMPFILE	14
+#define RFC1533_DOMAINNAME	15
+#define RFC1533_SWAPSERVER	16
+#define RFC1533_ROOTPATH	17
+#define RFC1533_EXTENSIONPATH	18
+#define RFC1533_IPFORWARDING	19
+#define RFC1533_IPSOURCEROUTING	20
+#define RFC1533_IPPOLICYFILTER	21
+#define RFC1533_IPMAXREASSEMBLY	22
+#define RFC1533_IPTTL		23
+#define RFC1533_IPMTU		24
+#define RFC1533_IPMTUPLATEAU	25
+#define RFC1533_INTMTU		26
+#define RFC1533_INTLOCALSUBNETS	27
+#define RFC1533_INTBROADCAST	28
+#define RFC1533_INTICMPDISCOVER	29
+#define RFC1533_INTICMPRESPOND	30
+#define RFC1533_INTROUTEDISCOVER 31
+#define RFC1533_INTROUTESOLICIT	32
+#define RFC1533_INTSTATICROUTES	33
+#define RFC1533_LLTRAILERENCAP	34
+#define RFC1533_LLARPCACHETMO	35
+#define RFC1533_LLETHERNETENCAP	36
+#define RFC1533_TCPTTL		37
+#define RFC1533_TCPKEEPALIVETMO	38
+#define RFC1533_TCPKEEPALIVEGB	39
+#define RFC1533_NISDOMAIN	40
+#define RFC1533_NISSERVER	41
+#define RFC1533_NTPSERVER	42
+#define RFC1533_VENDOR		43
+#define RFC1533_NBNS		44
+#define RFC1533_NBDD		45
+#define RFC1533_NBNT		46
+#define RFC1533_NBSCOPE		47
+#define RFC1533_XFS		48
+#define RFC1533_XDM		49
+#ifndef	NO_DHCP_SUPPORT
+#define RFC2132_REQ_ADDR	50
+#define RFC2132_MSG_TYPE	53
+#define RFC2132_SRV_ID		54
+#define RFC2132_PARAM_LIST	55
+#define RFC2132_MAX_SIZE	57
+
+#define DHCPDISCOVER		1
+#define DHCPOFFER		2
+#define DHCPREQUEST		3
+#define DHCPACK			5
+#endif				/* NO_DHCP_SUPPORT */
+
+#define RFC1533_VENDOR_MAJOR	0
+#define RFC1533_VENDOR_MINOR	0
+
+#define RFC1533_VENDOR_MAGIC	128
+#define RFC1533_VENDOR_ADDPARM	129
+#ifdef	IMAGE_FREEBSD
+#define RFC1533_VENDOR_HOWTO    132
+#endif
+#define RFC1533_VENDOR_MNUOPTS	160
+#define RFC1533_VENDOR_SELECTION 176
+#define RFC1533_VENDOR_MOTD	184
+#define RFC1533_VENDOR_NUMOFMOTD 8
+#define RFC1533_VENDOR_IMG	192
+#define RFC1533_VENDOR_NUMOFIMG	16
+
+#define RFC1533_END		255
+#define BOOTP_VENDOR_LEN	64
+#ifndef	NO_DHCP_SUPPORT
+#define DHCP_OPT_LEN		312
+#endif				/* NO_DHCP_SUPPORT */
+
+#define	TFTP_DEFAULTSIZE_PACKET	512
+#define	TFTP_MAX_PACKET		1432	/* 512 */
+
+#define TFTP_RRQ	1
+#define TFTP_WRQ	2
+#define TFTP_DATA	3
+#define TFTP_ACK	4
+#define TFTP_ERROR	5
+#define TFTP_OACK	6
+
+#define TFTP_CODE_EOF	1
+#define TFTP_CODE_MORE	2
+#define TFTP_CODE_ERROR	3
+#define TFTP_CODE_BOOT	4
+#define TFTP_CODE_CFG	5
+
+#define AWAIT_ARP	0
+#define AWAIT_BOOTP	1
+#define AWAIT_TFTP	2
+#define AWAIT_RARP	3
+#define AWAIT_RPC	4
+#define AWAIT_QDRAIN	5	/* drain queue, process ARP requests */
+
+typedef struct {
+	unsigned long s_addr;
+} in_addr;
+
+struct arptable_t {
+	in_addr ipaddr;
+	unsigned char node[6];
+};
+
+/*
+ * A pity sipaddr and tipaddr are not longword aligned or we could use
+ * in_addr. No, I don't want to use #pragma packed.
+ */
+struct arprequest {
+	unsigned short hwtype;
+	unsigned short protocol;
+	char hwlen;
+	char protolen;
+	unsigned short opcode;
+	char shwaddr[6];
+	char sipaddr[4];
+	char thwaddr[6];
+	char tipaddr[4];
+};
+
+struct iphdr {
+	char verhdrlen;
+	char service;
+	unsigned short len;
+	unsigned short ident;
+	unsigned short frags;
+	char ttl;
+	char protocol;
+	unsigned short chksum;
+	in_addr src;
+	in_addr dest;
+};
+
+struct udphdr {
+	unsigned short src;
+	unsigned short dest;
+	unsigned short len;
+	unsigned short chksum;
+};
+
+struct bootp_t {
+	struct iphdr ip;
+	struct udphdr udp;
+	char bp_op;
+	char bp_htype;
+	char bp_hlen;
+	char bp_hops;
+	unsigned long bp_xid;
+	unsigned short bp_secs;
+	unsigned short unused;
+	in_addr bp_ciaddr;
+	in_addr bp_yiaddr;
+	in_addr bp_siaddr;
+	in_addr bp_giaddr;
+	char bp_hwaddr[16];
+	char bp_sname[64];
+	char bp_file[128];
+#ifdef	NO_DHCP_SUPPORT
+	char bp_vend[BOOTP_VENDOR_LEN];
+#else
+	char bp_vend[DHCP_OPT_LEN];
+#endif				/* NO_DHCP_SUPPORT */
+};
+
+struct bootpd_t {
+	struct bootp_t bootp_reply;
+	unsigned char bootp_extension[MAX_BOOTP_EXTLEN];
+};
+
+struct tftp_t {
+	struct iphdr ip;
+	struct udphdr udp;
+	unsigned short opcode;
+	union {
+		char rrq[TFTP_DEFAULTSIZE_PACKET];
+		struct {
+			unsigned short block;
+			char download[TFTP_MAX_PACKET];
+		} data;
+		struct {
+			unsigned short block;
+		} ack;
+		struct {
+			unsigned short errcode;
+			char errmsg[TFTP_DEFAULTSIZE_PACKET];
+		} err;
+		struct {
+			char data[TFTP_DEFAULTSIZE_PACKET + 2];
+		} oack;
+	} u;
+};
+
+#define TFTP_MIN_PACKET	(sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
+
+struct rpc_t {
+	struct iphdr ip;
+	struct udphdr udp;
+	union {
+		char data[300];	/* longest RPC call must fit!!!! */
+		struct {
+			long id;
+			long type;
+			long rpcvers;
+			long prog;
+			long vers;
+			long proc;
+			long data[1];
+		} call;
+		struct {
+			long id;
+			long type;
+			long rstatus;
+			long verifier;
+			long v2;
+			long astatus;
+			long data[1];
+		} reply;
+	} u;
+};
+
+#define PROG_PORTMAP	100000
+#define PROG_NFS	100003
+#define PROG_MOUNT	100005
+
+#define MSG_CALL	0
+#define MSG_REPLY	1
+
+#define PORTMAP_GETPORT	3
+
+#define MOUNT_ADDENTRY	1
+#define MOUNT_UMOUNTALL	4
+
+#define NFS_LOOKUP	4
+#define NFS_READ	6
+
+#define NFS_FHSIZE	32
+
+#define NFSERR_PERM	1
+#define NFSERR_NOENT	2
+#define NFSERR_ACCES	13
+
+/* Block size used for NFS read accesses.  A RPC reply packet (including  all
+ * headers) must fit within a single Ethernet frame to avoid fragmentation.
+ * Chosen to be a power of two, as most NFS servers are optimized for this.  */
+#define NFS_READ_SIZE	1024
+
+#define	FLOPPY_BOOT_LOCATION	0x7c00
+
+#define	ROM_INFO_LOCATION	0x7dfa
+/* at end of floppy boot block */
+
+struct rom_info {
+	unsigned short rom_segment;
+	unsigned short rom_length;
+};
+
+/***************************************************************************
+External prototypes
+***************************************************************************/
+/* main.c */
+extern void print_bytes P((unsigned char *bytes, int len));
+extern void load P((void));
+extern int load_linux P((int root_mount_port, int swap_mount_port,
+			 int root_nfs_port, char *kernel_handle));
+extern int downloadkernel P((unsigned char *, int, int, int));
+extern int tftp
+P((const char *name, int (*)(unsigned char *, int, int, int)));
+extern void rpc_init(void);
+extern int nfs
+P((const char *name, int (*)(unsigned char *, int, int, int)));
+extern void nfs_umountall P((int));
+extern int bootp P((void));
+extern int rarp P((void));
+extern int udp_transmit P((unsigned long destip, unsigned int srcsock,
+			   unsigned int destsock, int len,
+			   const void *buf));
+
+extern int await_reply P((int type, int ival, void *ptr, int timeout));
+extern int decode_rfc1533 P((unsigned char *, int, int, int));
+extern unsigned short ipchksum P((unsigned short *, int len));
+extern void rfc951_sleep P((int));
+extern void cleanup_net P((void));
+extern void cleanup P((void));
+
+/* config.c */
+extern void print_config(void);
+extern void eth_reset(void);
+extern int eth_probe(void);
+extern int eth_poll(void);
+extern void eth_transmit(const char *d, unsigned int t, unsigned int s,
+			 const void *p);
+extern void eth_disable(void);
+
+/* bootmenu.c */
+extern int execute P((char *string));
+extern void bootmenu P((int));
+extern void show_motd P((void));
+extern void parse_menuopts P((char *, int));
+extern int getoptvalue P((char **, int *, int *));
+extern void selectImage P((char **));
+
+/* osloader.c */
+#if	defined(AOUT_IMAGE) || defined(ELF_IMAGE)
+extern int howto;
+#endif
+extern int os_download P((unsigned int, unsigned char *, unsigned int));
+
+/* misc.c */
+extern void twiddle P((void));
+extern void sleep P((int secs));
+extern int strcasecmp P((char *a, char *b));
+extern char *substr P((char *a, char *b));
+extern int getdec P((char **));
+extern void printf P((const char *, ...));
+extern char *sprintf P((char *, const char *, ...));
+extern int inet_aton P((char *p, in_addr * i));
+extern void gateA20_set P((void));
+extern void gateA20_unset P((void));
+extern void putchar P((int));
+extern int getchar P((void));
+extern int iskey P((void));
+
+/* start*.S */
+extern int getc P((void));
+extern void putc P((int));
+extern int ischar P((void));
+extern int getshift P((void));
+extern unsigned int memsize P((void));
+extern unsigned short basememsize P((void));
+extern void disk_init P((void));
+extern unsigned int disk_read P((int drv, int c, int h, int s, char *buf));
+extern void xstart P((unsigned long, unsigned long, char *));
+extern unsigned long currticks P((void));
+extern int setjmp P((void *jmpbuf));
+extern void longjmp P((void *jmpbuf, int where));
+extern void exit P((int status));
+extern void slowdownio P((void));
+
+/* serial.S */
+extern int serial_getc P((void));
+extern void serial_putc P((int));
+extern int serial_ischar P((void));
+extern int serial_init P((void));
+
+/* ansiesc.c */
+extern void ansi_reset P((void));
+extern void enable_cursor P((int));
+extern void handleansi P((unsigned char));
+
+/* md5.c */
+extern void md5_put P((unsigned int ch));
+extern void md5_done P((unsigned char *buf));
+
+/* floppy.c */
+extern int bootdisk P((int dev, int part));
+
+/***************************************************************************
+External variables
+***************************************************************************/
+/* main.c */
+extern const char *kernel;
+extern char kernel_buf[128];
+extern struct rom_info rom;
+extern int hostnamelen;
+extern unsigned long netmask;
+extern int jmp_bootmenu[10];
+extern struct arptable_t arptable[MAX_ARP];
+#ifdef	IMAGE_MENU
+extern char *motd[RFC1533_VENDOR_NUMOFMOTD];
+extern int menutmo, menudefault;
+extern unsigned char *defparams;
+extern int defparams_max;
+#endif
+#if	defined(ETHERBOOT32) && !defined(INTERNAL_BOOTP_DATA)
+#define	BOOTP_DATA_ADDR	((struct bootpd_t *)0x93C00)
+#else
+extern struct bootpd_t bootp_data;
+#define	BOOTP_DATA_ADDR	(&bootp_data)
+#endif
+extern unsigned char *end_of_rfc1533;
+#ifdef	IMAGE_FREEBSD
+extern int freebsd_howto;
+#endif
+
+/* config.c */
+extern struct nic nic;
+
+/* bootmenu.c */
+
+/* osloader.c */
+
+/* created by linker */
+extern char _start[], _edata[], _end[];
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c linux/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,197 @@
+/*
+ *  arch/mips/galileo/compressed/evb64120A_memSetup.c
+ *
+ *  By RidgeRun Inc, (Leveraged from Galileo's sbd.c)
+ *
+ *  Xfer an image from flash to ram.
+ *  For use with Galileo EVB64120A MIPS eval board.
+ */
+#include "ns16550.h"
+#include <linux/serial_reg.h>
+#include <asm/galileo-boards/evb64120A/pci.h>
+#include <asm/galileo-boards/evb64120A/core.h>
+
+void XferToRam(void);
+bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length,
+			 unsigned int bank1Base, unsigned int bank1Length);
+bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length,
+			 unsigned int bank3Base, unsigned int bank3Length);
+bool mapDevices0_1and2MemorySpace(unsigned int device0Base,
+				  unsigned int device0Length,
+				  unsigned int device1Base,
+				  unsigned int device1Length,
+				  unsigned int device2Base,
+				  unsigned int device2Length);
+
+#define RUNNINGFROMFLASH
+#include "./xfer.c"
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+unsigned int readWord(unsigned int addr)
+{
+	unsigned int tmp;
+	tmp = *(unsigned int *) (addr | NONE_CACHEABLE);
+	return WORDSWAP(tmp);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void writeWord(unsigned int addr, unsigned int data)
+{
+	*((unsigned int *) (addr | NONE_CACHEABLE)) = WORDSWAP(data);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+unsigned int GetExtendedMemorySize(void)
+{
+	unsigned int address, data = 0x11223344, type;
+	unsigned int bank1_ef = false, bank2_ef = false, bank3_ef = false;
+	unsigned int bank0_size, bank2_size, bank3_size, total_size = 0;
+
+	mapMemoryBanks0and1(0, 0x800000, 0x800000, 0x800000);
+	mapMemoryBanks2and3(0x1000000, 0x800000, 0x1800000, 0x800000);
+	type = readWord(0x14000810);
+	switch (type) {
+	case 16:
+		bank0_size = 0x1000000;
+		break;
+	case 64:
+		bank0_size = 0x4000000;
+		break;
+	case 128:
+		bank0_size = 0x8000000;
+		break;
+	case 256:
+		bank0_size = 0x10000000;
+		break;
+	default:
+		bank0_size = 0x1000000;
+		break;
+	}
+
+	type = readWord(0x14000814);
+	switch (type) {
+	case 16:
+		bank2_size = 0x1000000;
+		bank3_size = 0x1000000;
+		break;
+	case 64:
+		bank2_size = 0x4000000;
+		bank3_size = 0x4000000;
+		break;
+	case 128:
+		bank2_size = 0x8000000;
+		bank3_size = 0x8000000;
+		break;
+	case 256:
+		bank2_size = 0x10000000;
+		bank3_size = 0x10000000;
+		break;
+	default:
+		bank2_size = 0x1000000;
+		bank3_size = 0x1000000;
+		break;
+	}
+
+	/* Check which banks exist */
+	/* Bank 1 */
+	for (address = 0xffff00; address < 0x1000000; address += 4)
+		writeWord(address, data);
+	for (address = 0xffff00; address < 0x1000000; address += 4) {
+		if (readWord(address) != data)
+			break;
+	}
+	if (address == 0x1000000)
+		bank1_ef = true;
+	// Bank 2
+	for (address = 0x17fff00; address < 0x1800000; address += 4)
+		writeWord(address, data);
+	for (address = 0x17fff00; address < 0x1800000; address += 4) {
+		if (readWord(address) != data)
+			break;
+	}
+	if (address == 0x1800000)
+		bank2_ef = true;
+	else
+		bank2_size = 0x0;
+	// Bank 3
+	for (address = 0x1ffff00; address < 0x2000000; address += 4)
+		writeWord(address, data);
+	for (address = 0x1ffff00; address < 0x2000000; address += 4) {
+		if (readWord(address) != data)
+			break;
+	}
+	if (address == 0x2000000)
+		bank3_ef = true;
+
+	// Reconfig the system with the new bank0 (and maybe bank1) size.
+	if (bank0_size == 0x10000000)
+		bank1_ef = false;
+	if (bank1_ef == true) {
+		mapMemoryBanks0and1(0, bank0_size, bank0_size, bank0_size);
+		// Fix the PCI bars
+		pci0MapMemoryBanks0_1(0, bank0_size * 2);
+		pci1MapMemoryBanks0_1(0, bank0_size * 2);
+		total_size += bank0_size * 2;
+	} else {
+		mapMemoryBanks0and1(0, bank0_size, bank0_size, 0);
+		// Fix the PCI bars
+		pci0MapMemoryBanks0_1(0, bank0_size);
+		pci1MapMemoryBanks0_1(0, bank0_size);
+		total_size += bank0_size;
+	}
+	if (total_size == 0x10000000) {
+		bank2_ef = false;
+		bank3_ef = false;
+	} else {
+		if ((total_size + bank2_size) > 0x10000000) {
+			bank2_size = 0x10000000 - total_size;
+			bank3_ef = false;
+		} else {
+			if (bank3_size + total_size + bank2_size >
+			    0x10000000) {
+				bank3_size =
+				    0x10000000 - (total_size + bank2_size);
+			}
+		}
+	}
+	if (bank2_ef == true) {
+		if (bank3_ef == true) {
+			mapMemoryBanks2and3(total_size, bank2_size,
+					    total_size + bank2_size,
+					    bank3_size);
+			// Fix the PCI bars
+			pci0MapMemoryBanks2_3(total_size,
+					      bank2_size + bank3_size);
+			pci1MapMemoryBanks2_3(total_size,
+					      bank2_size + bank3_size);
+			total_size += (bank2_size + bank3_size);
+		} else {
+			mapMemoryBanks2and3(total_size, bank2_size,
+					    total_size + bank2_size, 0);
+			// Fix the PCI bars
+			pci0MapMemoryBanks2_3(total_size, bank2_size);
+			pci1MapMemoryBanks2_3(total_size, bank2_size);
+			total_size += bank2_size;
+		}
+	} else {
+		mapMemoryBanks2and3(total_size, 0, total_size, 0);
+		pci0MapMemoryBanks2_3(total_size, 0);
+		pci1MapMemoryBanks2_3(total_size, 0);
+	}
+	/* Reorganize the devices memory map */
+	mapDevices0_1and2MemorySpace(0x1c000000, 0x800000, 0x1a000000,
+				     0xc00000, 0x1d000000, 0x800000);
+
+	XferToRam();
+	return 0;		// Not that we'll ever get to this line of code, but
+	// it does satisfy a compiler warning.
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/fixit linux/arch/mips/galileo-boards/ev64120/compressed/fixit
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/fixit	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/fixit	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,17 @@
+#!/bin/ksh
+
+# By RidgeRun Inc.
+#
+# The input to this script is
+# intended to be a *.S file which
+# was previously created by the doit
+# program. That program constructs
+# a *.S file which has a defined data
+# table containing values with leading
+# zeroes. To satisfy our assembler those
+# leading zeroes need to be stripped off
+# and that is the purpose of this script.
+
+echo "Removing leading zeros"
+sed -e "s/ 0\(.\)/ \1/g" $1 | sed -e "s/ 0\(.\)/ \1/g" > $1.new
+mv $1.new $1
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c linux/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,1560 @@
+/* flashdrv.c - FLASH memory functions and definitions*/
+
+/* Copyright Galileo Technology. */
+
+/*
+DESCRIPTION
+This flash driver gives the user a convenient interface to FLASH memory located
+on the user`s board, it supports various layout configurations such as:
+1. One pure 8 bit device (Such as AMD`s AM29LV040B).
+2. 1,2,4 or 8 devices 16 bit wide configured to operate in 8 bit mode.
+3. 1,2 or 4 devices each 16 bit wide.
+Before using the driver you must call the initialization function at least once
+or when ever you are changing the FLASH base address.
+The list bellow contains the supported FLASH memory devices, new devices can be
+added easily in the future.
+*/
+
+/*includes*/
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/flashdrv.h>
+#else
+#include "flashdrv.h"
+#endif
+/* locals */
+
+#ifdef __MIPSEB__		// skranz, add
+#define BE			// skranz, add
+#endif				// skranz, add
+
+/******************************************************************************
+* Those two tables contain the supported flash devices information needed by
+* the driver: 
+* The first table "flashParametrs" starts with 10 shared fields 
+*  (currently 6 are reserved):
+*   index 0 => Pointer to an entry in the second table list
+*   index 1 => baseAddress - Flash memory device base address.
+*   index 2 => width - 1, 2, 4 or 8 Bytes. 
+*   index 3 => mode - PURE8, X8 or X16 flash configuration (for X16 devices only)
+* The second table (flashTypes) contains: 
+* Entry`s structure:
+*   Manufacture ID,Device ID,number of sectors,list of sector`s sizes
+*   (in Kbytes starting with sector number 0).
+* The end of the list is pointed with a zero.
+******************************************************************************/
+unsigned int flashParametrs[10];	/* 0  Entry pointer */
+				 /* 0  Base address  */
+				 /* 0  Width         */
+				 /* 0  Mode          */
+				 /* 0,0,0,0,0,0, spare entries. */
+unsigned int flashTypes[] = {
+
+	/* 0 */ AMD_FLASH, AM29F400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64,
+	    64, 64, 64,
+	/* 1 */ AMD_FLASH, AM29F400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32,
+	    8, 8, 16,
+	/* 2 */ ST_FLASH, M29W040, 8, 64, 64, 64, 64, 64, 64, 64, 64,
+	/* 3 */ AMD_FLASH, AM29LV040B, 8, 64, 64, 64, 64, 64, 64, 64, 64,
+	/* 4 */ AMD_FLASH, AM29LV800BT, 19, 64, 64, 64, 64, 64, 64, 64, 64,
+	    64, 64,
+	64, 64, 64, 64, 64, 32, 8, 8, 16,
+	/* 5 */ INTEL_FLASH, I28F320J3A, 32, 128, 128, 128, 128, 128, 128,
+	    128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128,
+	/* 6 */ INTEL_FLASH, I28F640J3A, 64, 128, 128, 128, 128, 128, 128,
+	    128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128,
+	/* 7 */ INTEL_FLASH, I28F128J3A, 128, 128, 128, 128, 128, 128, 128,
+	    128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+	/* 8 */ AMD_FLASH, AM29LV400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64,
+	    64, 64, 64,
+	/* 9 */ AMD_FLASH, AM29LV400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32,
+	    8, 8, 16,
+	/* 10 */ INTEL_FLASH, I28F320B3_T, 71, 64, 64, 64, 64, 64, 64, 64,
+	    64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 8, 8, 8, 8, 8, 8, 8, 8,
+	/* 11 */ INTEL_FLASH, I28F320B3_B, 71, 8, 8, 8, 8, 8, 8, 8, 8, 64,
+	    64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	/* 12 */ INTEL_FLASH, I28F160B3_B, 39, 8, 8, 8, 8, 8, 8, 8, 8, 64,
+	    64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64,
+	/* 13 */ INTEL_FLASH, I28F160B3_T, 39, 64, 64, 64, 64, 64, 64, 64,
+	    64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+	64, 64, 8, 8, 8, 8, 8, 8, 8, 8,
+
+	0			/* End of list indicator */
+};
+
+/********************************************************************
+* flashInit - Initializes the FLASH memory driver`s parameters, this function 
+*             must be called at least once before using the FLASH memory.
+*             If you are changing the FLASH base address call this function
+*             again.
+*
+* INPUTS:     unsigned int flashBaseAddress - The flash base Address.
+*             unsigned int flashWidth - Flash bus width in Bytes: 1,2,4 or 8.
+*             flashMode - PURE8, X8 or X16. 
+* RETURNS:    Flash Size, zero when operation (flashInit) failed.
+*********************************************************************/
+unsigned int flashInit(unsigned int flashBaseAddress,
+		       unsigned int flashWidth, FLASHmode flashMode)
+{
+	unsigned short mfrId = 0;
+	unsigned short devId = 0xffff;
+	unsigned int FirstAddr, SecondAddr, ThirdAddr;
+	unsigned int pArray = 0;
+	unsigned int counter;
+	unsigned int flashSize = 0;
+
+	/* update the list with relevant parametrs */
+	flashParametrs[0] = 0;	/* Default initialization */
+	flashParametrs[1] = flashBaseAddress;
+	flashParametrs[2] = flashWidth;
+	flashParametrs[3] = flashMode;
+	/* Get the FLASH`s ID */
+	switch (FLASH_WIDTH) {
+	case 1:
+		/* AMD or ST ?? * */
+		if (flashMode == PURE8) {	/* Boot Flash */
+			FirstAddr = 0x5555;
+			SecondAddr = 0x2aaa;
+			ThirdAddr = 0x5555;
+		} else {	/* X16 device configured to 8bit Mode */
+
+			FirstAddr = 0xaaaa;
+			SecondAddr = 0x5555;
+			ThirdAddr = 0xaaaa;
+		}
+		flashReset();
+		WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+		WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+		WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90);
+		READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId);
+		if (mfrId == AMD_FLASH || mfrId == ST_FLASH) {
+			flashReset();
+			WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90);
+			READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId);
+			break;
+		}
+		/* Micron or Intel ?? * */
+		WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff);	/* Read Array */
+		/* Flash reset for Intel/Micron */
+		WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90);	/* IDENTIFY Device */
+		READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId);	/*Address for ManufactureID */
+		if (mfrId == INTEL_FLASH || mfrId == MICRON_FLASH) {
+			WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff);	/* Read Array */
+			/*Flash reset for Intel/Micron */
+			WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90);	/* IDENTIFY Device */
+			READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId);	/*Address for DeviceID */
+		}
+		break;
+	case 2:
+	case 4:
+	case 8:
+		/* AMD or ST ??? */
+		flashReset();
+		WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH,
+			    0xaa);
+		WRITE_SHORT(FLASH_BASE_ADDRESS + 0x2aaa * FLASH_WIDTH,
+			    0x55);
+		WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH,
+			    0x90);
+		READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+		flashReset();
+		/* Read the device ID */
+		if (mfrId == AMD_FLASH || mfrId == ST_FLASH) {
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    0x5555 * FLASH_WIDTH, 0xaa);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    0x2aaa * FLASH_WIDTH, 0x55);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    0x5555 * FLASH_WIDTH, 0x90);
+			READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH,
+				   &devId);
+			break;
+		}
+		/* Micron or Intel ?? * */
+		WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff);
+		WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090);
+		if ((FLASH_WIDTH == 4) || (FLASH_WIDTH == 8)) {	/* 32 or 64 bit */
+			READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+		} else {	/* FLASH_WIDTH = 2 */
+
+			READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+		}
+		if ((mfrId == INTEL_FLASH) || (mfrId == MICRON_FLASH)) {
+			/* Flash reset for Intel/Micron */
+			flashReset();
+			WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff);
+			WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090);
+			READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH,
+				   &devId);
+		}
+		break;
+
+	}
+	/* Try to locate the device in the supported flashes list (FLASH_TYPE). 
+	   according to the keys: 
+	   1) mfrId - manufactor ID.
+	   2) devId - device ID.  
+	 */
+
+	while (true) {
+		if (flashTypes[pArray] == 0) {
+			flashReset();
+			return 0;	/* Device not in the list */
+		}
+		if ((flashTypes[pArray] == mfrId) &&
+		    (flashTypes[pArray + 1] == devId)) {
+			POINTER_TO_FLASH = pArray;
+			for (counter = 0;
+			     counter < flashTypes[NUMBER_OF_SECTORS];
+			     counter++) {
+				flashSize =
+				    flashSize +
+				    flashTypes[FIRST_SECTOR_SIZE +
+					       counter];
+			}
+			if (FLASH_MODE != PURE8) {
+				flashReset();
+				return (flashSize * _1K *
+					(FLASH_WIDTH / (FLASH_MODE / 8)));
+			} else {
+				flashReset();
+				return (flashSize * _1K * FLASH_WIDTH);
+			}
+		}
+		pArray += (3 + flashTypes[pArray + 2]);	/* Move to next entry */
+	}
+}
+
+/********************************************************************
+* flashReset - Resets the Flash memory (FLASH`s internal protocol reset).
+*                
+* INTPUTS:  N/A    
+* OUTPUT:   N/A  
+*********************************************************************/
+void flashReset()
+{
+	unsigned char ucData;
+	unsigned short usData;
+	unsigned int uiData;
+
+	if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) ||
+	    (flashTypes[POINTER_TO_FLASH]) == ST_FLASH) {
+		if (FLASH_MODE == X16) {
+			ucData = 0xf0;
+			usData = 0xf0;
+			uiData = 0x00f000f0;
+		} else {	/* case of PURE8 or X8 */
+
+			ucData = 0xf0;
+			usData = 0xf0f0;
+			uiData = 0xf0f0f0f0;
+		}
+	} else {
+		if (FLASH_MODE == X16) {
+			ucData = 0xff;
+			usData = 0xff;
+			uiData = 0x00ff00ff;
+		} else {	/* case of PURE8 or X8 */
+
+			ucData = 0xff;
+			usData = 0xffff;
+			uiData = 0xffffffff;
+		}
+	}
+	switch (FLASH_WIDTH) {
+	case 1:
+		WRITE_CHAR(FLASH_BASE_ADDRESS, ucData);
+		break;
+	case 2:
+		WRITE_SHORT(FLASH_BASE_ADDRESS, usData);
+		break;
+	case 4:
+		WRITE_WORD(FLASH_BASE_ADDRESS, uiData);
+		break;
+	case 8:
+		WRITE_WORD(FLASH_BASE_ADDRESS, uiData);
+		WRITE_WORD(FLASH_BASE_ADDRESS + 0x4, uiData);
+		break;
+	}
+}
+
+/********************************************************************
+* flashErase - The function erases the WHOLE flash memory.
+*
+*
+* RETURNS: true on success,false on failure
+*********************************************************************/
+bool flashErase()
+{
+	unsigned int totalFlashSize;
+	unsigned int address;
+	unsigned int readData;
+	unsigned int nextSector;
+
+	flashReset();
+	totalFlashSize = flashGetSize();
+	/* scan all flash memory space. */
+	address = 0;
+	while (address < totalFlashSize) {
+		readData = flashReadWord(address);
+		if (readData != 0xffffffff) {	/* offset with dirty data. */
+			flashEraseSector(flashInWhichSector(address));
+			nextSector = flashInWhichSector(address) + 1;
+			if (nextSector < flashTypes[NUMBER_OF_SECTORS])
+				/* jump to next sector. */
+				address = flashGetSectorOffset(nextSector);
+			else
+				/* end of erasing. */
+				address = totalFlashSize;
+		} else
+			address += 4;
+	}
+	return true;
+}
+
+/********************************************************************
+* flashEraseSector - The function erases a specific sector in the flash memory.
+*
+* INPUTS:  Sector number.
+* RETURNS: true on success,false on failure.
+*********************************************************************/
+bool flashEraseSector(unsigned int sectorNumber)
+{
+	volatile unsigned int spin;
+	unsigned int regValue;
+	unsigned int sectorBaseAddress = 0;
+	unsigned int i;
+	unsigned int data20, dataD0, data70;
+	unsigned int dataPoll;
+	unsigned int FirstAddr, SecondAddr, ThirdAddr, FourthAddr,
+	    FifthAddr;
+	unsigned int FirstData, SecondData, ThirdData;
+	unsigned int FourthData, FifthData, SixthData;
+
+	/* calculate the sector base Address according to the following parametrs:
+	   1: FLASH_WIDTH
+	   2: the size of each sector which it detailed in the table */
+
+	/* checking the if the sectorNumber is legal. */
+	if (sectorNumber > flashTypes[NUMBER_OF_SECTORS] - 1)
+		return false;
+	/* now the calculation begining of the sector Address */
+	for (i = 0; i < sectorNumber; i++) {
+		sectorBaseAddress =
+		    sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i];
+	}
+	/* In case of X8 wide the address should be */
+	if (FLASH_MODE == PURE8)
+		sectorBaseAddress = _1K * sectorBaseAddress;
+	if (FLASH_MODE == X8)
+		sectorBaseAddress = _1K * sectorBaseAddress;
+	/* In case of X16 wide the address should be */
+	if (FLASH_MODE == X16)
+		sectorBaseAddress = _1K * sectorBaseAddress / 2;
+	flashReset();
+	if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \
+	    (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) {
+		switch (FLASH_WIDTH) {
+		case 1:
+			if (FLASH_MODE == PURE8) {	/* Boot Flash PURE8 */
+				FirstAddr = 0x5555;
+				SecondAddr = 0x2aaa;
+				ThirdAddr = 0x5555;
+				FourthAddr = 0x5555;
+				FifthAddr = 0x2aaa;
+			} else {
+				FirstAddr = 0xaaaa;
+				SecondAddr = 0x5555;
+				ThirdAddr = 0xaaaa;
+				FourthAddr = 0xaaaa;
+				FifthAddr = 0x5555;
+			}
+			WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x80);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + FourthAddr, 0xAA);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + FifthAddr, 0x55);
+			WRITE_CHAR(
+				   (FLASH_BASE_ADDRESS +
+				    (sectorBaseAddress & 0xffffff00)),
+				   0x30);
+			/* Poll on the flash */
+			do {
+				READ_CHAR(FLASH_BASE_ADDRESS +
+					  sectorBaseAddress, &regValue);
+			} while ((regValue & 0x80) != 0x80);
+
+			break;
+		case 2:
+			if (FLASH_MODE == X16) {
+				FirstData = 0xaa;	/* Data for the First  Cycle */
+				SecondData = 0x55;	/* Data for the Second Cycle */
+				ThirdData = 0x80;	/* Data for the Third  Cycle */
+				FourthData = 0xaa;	/* Data for the Fourth Cycle */
+				FifthData = 0x55;	/* Data for the Fifth  Cycle */
+				SixthData = 0x30;	/* Data for the Sixth  Cycle */
+				FirstAddr = 0x5555;	/* Address for the First  Cycle */
+				SecondAddr = 0x2aaa;	/* Address for the Second Cycle */
+				ThirdAddr = 0x5555;	/* Address for the Third  Cycle */
+				FourthAddr = 0x5555;	/* Address for the Fourth Cycle */
+				FifthAddr = 0x2aaa;	/* Address for the Fifth  Cycle */
+			} else {	/* (FLASH_MODE = 8) */
+
+				FirstData = 0xaaaa;	/* Data for the First  Cycle */
+				SecondData = 0x5555;	/* Data for the Second Cycle */
+				ThirdData = 0x8080;	/* Data for the Third  Cycle */
+				FourthData = 0xaaaa;	/* Data for the Fourth Cycle */
+				FifthData = 0x5555;	/* Data for the Fifth  Cycle */
+				SixthData = 0x3030;	/* Data for the Sixth  Cycle */
+				FirstAddr = 0xaaaa;	/* Address for the First  Cycle */
+				SecondAddr = 0x5555;	/* Address for the Second Cycle */
+				ThirdAddr = 0xaaaa;	/* Address for the Third  Cycle */
+				FourthAddr = 0xaaaa;	/* Address for the Fourth Cycle */
+				FifthAddr = 0x5555;	/* Address for the Fifth  Cycle */
+			}
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    FirstAddr * FLASH_WIDTH, FirstData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    SecondAddr * FLASH_WIDTH, SecondData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    ThirdAddr * FLASH_WIDTH, ThirdData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    FourthAddr * FLASH_WIDTH, FourthData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    FifthAddr * FLASH_WIDTH, FifthData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    (sectorBaseAddress & 0xffffff00) *
+				    FLASH_WIDTH, SixthData);
+			/* Poll on the flash */
+			if (FLASH_MODE == X16) {	/* 1 device of 16 bit */
+				dataPoll = 0x0080;
+			} else {	/* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */
+
+				dataPoll = 0x8080;
+			}
+			do {
+				READ_SHORT(FLASH_BASE_ADDRESS +
+					   sectorBaseAddress * FLASH_WIDTH,
+					   &regValue);
+				for (spin = 0; spin < 100; spin++) {
+				}	// skranz, added spin loop.
+			} while ((regValue & dataPoll) != dataPoll);
+			break;
+		case 4:
+			if (FLASH_MODE == X16) {
+				FirstData = 0x00aa00aa;	/* Data for the First  Cycle */
+				SecondData = 0x00550055;	/* Data for the Second Cycle */
+				ThirdData = 0x00800080;	/* Data for the Third  Cycle */
+				FourthData = 0x00aa00aa;	/* Data for the Fourth Cycle */
+				FifthData = 0x00550055;	/* Data for the Fifth  Cycle */
+				SixthData = 0x00300030;	/* Data for the Sixth  Cycle */
+				FirstAddr = 0x5555;	/* Address for the First  Cycle */
+				SecondAddr = 0x2aaa;	/* Address for the Second Cycle */
+				ThirdAddr = 0x5555;	/* Address for the Third  Cycle */
+				FourthAddr = 0x5555;	/* Address for the Fourth Cycle */
+				FifthAddr = 0x2aaa;	/* Address for the Fifth  Cycle */
+			} else {	/* if (FLASH_MODE == 8) */
+
+				FirstData = 0xaaaaaaaa;	/* Data for the First  Cycle */
+				SecondData = 0x55555555;	/* Data for the Second Cycle */
+				ThirdData = 0x80808080;	/* Data for the Third  Cycle */
+				FourthData = 0xAAAAAAAA;	/* Data for the Fourth Cycle */
+				FifthData = 0x55555555;	/* Data for the Fifth  Cycle */
+				SixthData = 0x30303030;	/* Data for the Sixth  Cycle */
+				FirstAddr = 0xaaaa;	/* Address for the First  Cycle */
+				SecondAddr = 0x5555;	/* Address for the Second Cycle */
+				ThirdAddr = 0xaaaa;	/* Address for the Third  Cycle */
+				FourthAddr = 0xaaaa;	/* Address for the Fourth Cycle */
+				FifthAddr = 0x5555;	/* Address for the Fifth  Cycle */
+			}
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FirstAddr * FLASH_WIDTH, FirstData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   SecondAddr * FLASH_WIDTH, SecondData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   ThirdAddr * FLASH_WIDTH, ThirdData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FourthAddr * FLASH_WIDTH, FourthData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FifthAddr * FLASH_WIDTH, FifthData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   (sectorBaseAddress & 0xffffff00) *
+				   FLASH_WIDTH, SixthData);
+			/* Poll on the flash */
+			if (FLASH_MODE == X16) {	/* 4 devices , 16 bit each => 64bit */
+				dataPoll = 0x00800080;
+			} else {	/* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+				dataPoll = 0x80808080;
+			}
+			do {
+				READ_WORD(FLASH_BASE_ADDRESS +
+					  sectorBaseAddress * FLASH_WIDTH,
+					  &regValue);
+			} while ((regValue & dataPoll) != dataPoll);
+			break;
+		case 8:	/* In case of 64bit width the transformation is 1->8 */
+			if (FLASH_MODE == X16) {
+				FirstData = 0x00aa00aa;	/* Data for the First  Cycle */
+				SecondData = 0x00550055;	/* Data for the Second Cycle */
+				ThirdData = 0x00800080;	/* Data for the Third  Cycle */
+				FourthData = 0x00aa00aa;	/* Data for the Fourth Cycle */
+				FifthData = 0x00550055;	/* Data for the Fifth  Cycle */
+				SixthData = 0x00300030;	/* Data for the Sixth  Cycle */
+				FirstAddr = 0x5555;	/* Address for the First  Cycle */
+				SecondAddr = 0x2aaa;	/* Address for the Second Cycle */
+				ThirdAddr = 0x5555;	/* Address for the Third  Cycle */
+				FourthAddr = 0x5555;	/* Address for the Fourth Cycle */
+				FifthAddr = 0x2aaa;	/* Address for the Fifth  Cycle */
+			} else {	/* (FLASH_MODE = 8 */
+
+				FirstData = 0xaaaaaaaa;	/* Data for the First  Cycle */
+				SecondData = 0x55555555;	/* Data for the Second Cycle */
+				ThirdData = 0x80808080;	/* Data for the Third  Cycle */
+				FourthData = 0xAAAAAAAA;	/* Data for the Fourth Cycle */
+				FifthData = 0x55555555;	/* Data for the Fifth  Cycle */
+				SixthData = 0x30303030;	/* Data for the Sixth  Cycle */
+				FirstAddr = 0xaaaa;	/* Address for the First  Cycle */
+				SecondAddr = 0x5555;	/* Address for the Second Cycle */
+				ThirdAddr = 0xaaaa;	/* Address for the Third  Cycle */
+				FourthAddr = 0xaaaa;	/* Address for the Fourth Cycle */
+				FifthAddr = 0x5555;	/* Address for the Fifth  Cycle */
+			}
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FirstAddr * FLASH_WIDTH, FirstData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   SecondAddr * FLASH_WIDTH, SecondData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   ThirdAddr * FLASH_WIDTH, ThirdData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FourthAddr * FLASH_WIDTH, FourthData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FifthAddr * FLASH_WIDTH, FifthData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   (sectorBaseAddress & 0xffffff00) *
+				   FLASH_WIDTH, SixthData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FirstAddr * FLASH_WIDTH + 4, FirstData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   SecondAddr * FLASH_WIDTH + 4,
+				   SecondData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   ThirdAddr * FLASH_WIDTH + 4, ThirdData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FourthAddr * FLASH_WIDTH + 4,
+				   FourthData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   FifthAddr * FLASH_WIDTH + 4, FifthData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   (sectorBaseAddress & 0xffffff00)
+				   * FLASH_WIDTH + 4, SixthData);
+			/* Poll on the flash */
+			if (FLASH_MODE == X16) {	/* 4 devices , 16 bit each => 64bit */
+				dataPoll = 0x00800080;
+			} else {	/* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+				dataPoll = 0x80808080;
+			}
+			do {
+				READ_WORD(FLASH_BASE_ADDRESS +
+					  sectorBaseAddress * FLASH_WIDTH,
+					  &regValue);
+			} while ((regValue & dataPoll) != dataPoll);
+			do {
+				READ_WORD(FLASH_BASE_ADDRESS +
+					  sectorBaseAddress * FLASH_WIDTH +
+					  4, &regValue);
+			} while ((regValue & dataPoll) != dataPoll);
+			break;
+		default:
+			return false;
+		}
+	} /* End of 'flash erase sector' for AMD/ST */
+	else {			/* Intel/Micron */
+
+		switch (FLASH_WIDTH) {
+		case 1:
+			WRITE_CHAR(FLASH_BASE_ADDRESS, 0x20);
+			WRITE_CHAR(
+				   (FLASH_BASE_ADDRESS +
+				    (sectorBaseAddress & 0xffffff00)),
+				   0xd0);
+			/* Poll on the flash */
+			while (true) {
+				WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+				READ_CHAR(FLASH_BASE_ADDRESS, &regValue);
+				if ((regValue & 0x80) == 0x80)
+					break;
+			}
+			break;
+		case 2:
+			if (FLASH_MODE == X16) {	/* 1 device 16 bit.  */
+				data20 = 0x0020;;
+				dataD0 = 0x00d0;;
+			} else {	/* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */
+
+				data20 = 0x2020;
+				dataD0 = 0xd0d0;
+			}
+			WRITE_SHORT(FLASH_BASE_ADDRESS, data20);
+			WRITE_SHORT(
+				    (FLASH_BASE_ADDRESS +
+				     ((sectorBaseAddress * 2) &
+				      0xffffff00)), dataD0);
+			/* Poll on the flash */
+			if (FLASH_MODE == X16) {
+				dataPoll = 0x0080;
+				data70 = 0x0070;
+			} else {	/* (FLASH_MODE = 8) */
+
+				dataPoll = 0x8080;
+				data70 = 0x7070;
+			}
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS +
+					    sectorBaseAddress * 2, data70);
+				READ_SHORT(FLASH_BASE_ADDRESS +
+					   sectorBaseAddress * 2,
+					   &regValue);
+				if ((regValue & 0x0080) == 0x0080)
+					break;
+			}
+			break;
+		case 4:
+			if (FLASH_MODE == X16) {	/* 2 devices , 16 bit each => 32bit */
+				data20 = 0x00200020;
+				dataD0 = 0x00d000d0;
+			} else {	/* (FLASH_MODE = 8) ==> 4 devices , 8 bit each => 32bit */
+
+				data20 = 0x20202020;
+				dataD0 = 0xd0d0d0d0;
+			}
+			WRITE_WORD(FLASH_BASE_ADDRESS, data20);
+			WRITE_WORD(
+				   (FLASH_BASE_ADDRESS +
+				    ((sectorBaseAddress * 4) &
+				     0xffffff00)), dataD0);
+			/* Poll on the flash */
+			if (FLASH_MODE == X16) {
+				dataPoll = 0x0080;
+				data70 = 0x0070;
+			} else {	/* (FLASH_MODE = 8) */
+
+				dataPoll = 0x8080;
+				data70 = 0x7070;
+			}
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS, data70);
+				READ_SHORT(FLASH_BASE_ADDRESS, &regValue);
+				if ((regValue & dataPoll) == dataPoll)
+					break;
+			}
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+					    data70);
+				READ_SHORT(FLASH_BASE_ADDRESS + 2,
+					   &regValue);
+				if ((regValue & dataPoll) == dataPoll)
+					break;
+			}
+			break;
+		case 8:
+			if (FLASH_MODE == X16) {	/* 4 devices , 16 bit each => 64bit */
+				data20 = 0x00200020;
+				dataD0 = 0x00d000d0;
+			} else {	/* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+				data20 = 0x20202020;
+				dataD0 = 0xd0d0d0d0;
+			}
+			WRITE_WORD(FLASH_BASE_ADDRESS, data20);
+			WRITE_WORD(
+				   (FLASH_BASE_ADDRESS +
+				    ((sectorBaseAddress * 8) &
+				     0xffffff00)), dataD0);
+			WRITE_WORD(FLASH_BASE_ADDRESS + 4, data20);
+			WRITE_WORD(
+				   (FLASH_BASE_ADDRESS +
+				    ((sectorBaseAddress * 8) & 0xffffff00 +
+				     4)), dataD0);
+			/* Poll on the flash */
+			if (FLASH_MODE == X16) {
+				dataPoll = 0x0080;
+				data70 = 0x0070;
+			} else {	/* (FLASH_MODE = 8) */
+
+				dataPoll = 0x8080;
+				data70 = 0x7070;
+			}
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS +
+					    sectorBaseAddress * 8, data70);
+				READ_SHORT(FLASH_BASE_ADDRESS +
+					   sectorBaseAddress * 8,
+					   &regValue);
+				if ((regValue & dataPoll) == dataPoll)
+					break;
+			}
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+					    data70);
+				READ_SHORT(FLASH_BASE_ADDRESS + 2,
+					   &regValue);
+				if ((regValue & dataPoll) == dataPoll)
+					break;
+			}
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS + 4,
+					    data70);
+				READ_SHORT(FLASH_BASE_ADDRESS + 4,
+					   &regValue);
+				if ((regValue & dataPoll) == dataPoll)
+					break;
+			}
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS + 6,
+					    data70);
+				READ_SHORT(FLASH_BASE_ADDRESS + 6,
+					   &regValue);
+				if ((regValue & dataPoll) == dataPoll)
+					break;
+			}
+			break;
+		default:
+			return false;
+		}
+	}
+	flashReset();
+	return true;
+}
+
+/********************************************************************
+* flashWriteWord - Write 32Bit to the FLASH memory at the given offset from the
+*                  FLASH base address.
+*   			   address 0 = 0x00000000 !!
+*				   Attention!!! data "0" cannot be programed back to 
+*                  "1" (only by first performing an earase operation).
+*                  The function takes care of Big/Little endian conversion
+*
+* INPUTS:  offset - The offset from the flash`s base address.
+*          data   - The data that should be written.
+* RETURNS: true on success,false on failure
+*********************************************************************/
+bool flashWriteWord(unsigned int offset, unsigned int data)
+{
+	unsigned char c, rc;
+	unsigned short s, rs;
+	register unsigned int rw;
+	register unsigned int regValue;
+	register unsigned int FirstAddr, SecondAddr, ThirdAddr;
+	register unsigned int FirstData, SecondData, ThirdData;
+	register unsigned int data10, data20, data70, data80;
+
+	if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \
+	    (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) {
+		switch (FLASH_WIDTH) {
+		case 1:	/* Split the 32 bit write into four 8bit Writings */
+			if (FLASH_MODE == PURE8) {	/* Boot Flash */
+				FirstAddr = 0x5555;
+				SecondAddr = 0x2aaa;
+				ThirdAddr = 0x5555;
+			} else {
+				FirstAddr = 0xaaaa;
+				SecondAddr = 0x5555;
+				ThirdAddr = 0xaaaa;
+			}
+			WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+			c = (data >> 24);
+#else
+			c = data;
+#endif
+			WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c);
+			/* Writing first Byte */
+			while (true) {
+				READ_CHAR(FLASH_BASE_ADDRESS + offset,
+					  &rc);
+				if ((rc & 0x80) == (c & 0x80))	/* DQ7 =? DATA */
+					break;	/* DQ7 =  DATA */
+				if ((rc & 0x20) == 0x20) {	/* DQ5 =? '1'  */
+					READ_CHAR(FLASH_BASE_ADDRESS +
+						  offset, &rc);
+					if ((rc & 0x80) == (c & 0x80))
+						break;	/* DQ7 = DATA  */
+					else
+						return false;	/* DQ7 != DATA */
+				}
+			}
+			WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+			c = (data >> 16);
+#else
+			c = (data >> 8);
+#endif
+			WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c);
+			/* Writing second Byte */
+			while (true) {
+				READ_CHAR(FLASH_BASE_ADDRESS + offset + 1,
+					  &rc);
+				if ((rc & 0x80) == (c & 0x80))	/* DQ7 =? DATA */
+					break;	/* DQ7 = DATA  */
+				if ((rc & 0x20) == 0x20) {	/* DQ5 =? '1'  */
+					READ_CHAR(FLASH_BASE_ADDRESS +
+						  offset + 1, &rc);
+					if ((rc & 0x80) == (c & 0x80))
+						break;	/* DQ7 = DATA  */
+					else
+						return false;	/* DQ7 != DATA */
+				}
+			}
+			WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+			c = (data >> 8);
+#else
+			c = (data >> 16);
+#endif
+			WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c);
+			/* Writing third Byte */
+			while (true) {
+				READ_CHAR(FLASH_BASE_ADDRESS + offset + 2,
+					  &rc);
+				if ((rc & 0x80) == (c & 0x80))	/* DQ7 =? DATA */
+					break;	/* DQ7 = DATA  */
+				if ((rc & 0x20) == 0x20) {	/* DQ5 =? '1'  */
+					READ_CHAR(FLASH_BASE_ADDRESS +
+						  offset + 2, &rc);
+					if ((rc & 0x80) == (c & 0x80))
+						break;	/* DQ7 = DATA  */
+					else
+						return false;	/* DQ7 != DATA */
+				}
+			}
+			WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+			WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+			c = data;
+#else
+			c = (data >> 24);
+#endif
+			WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c);
+			/* Writing fourth Byte */
+			while (true) {
+				READ_CHAR(FLASH_BASE_ADDRESS + offset + 3,
+					  &rc);
+				if ((rc & 0x80) == (c & 0x80))	/* DQ7 =? DATA */
+					break;	/* DQ7 = DATA  */
+				if ((rc & 0x20) == 0x20) {	/* DQ5 =? '1'  */
+					READ_CHAR(FLASH_BASE_ADDRESS +
+						  offset + 3, &rc);
+					if ((rc & 0x80) == (c & 0x80))
+						break;	/* DQ7 = DATA  */
+					else
+						return false;	/* DQ7 != DATA */
+				}
+			}
+			break;
+		case 2:	/* Split the 32 bit write into two 8/16 bit Writings 
+				   (16bit width). */
+			if (FLASH_MODE == X16) {
+				FirstData = 0xaa;	/* Data for the First  Cycle    */
+				SecondData = 0x55;	/* Data for the Second Cycle    */
+				ThirdData = 0xa0;	/* Data for the Third  Cycle    */
+				FirstAddr = 0x5555;	/* Address for the First  Cycle */
+				SecondAddr = 0x2aaa;	/* Address for the Second Cycle */
+				ThirdAddr = 0x5555;	/* Address for the Third  Cycle */
+			} else {	/* if (FLASH_MODE == 8) */
+
+				FirstData = 0xaaaa;	/* Data for the First  Cycle    */
+				SecondData = 0x5555;	/* Data for the Second Cycle    */
+				ThirdData = 0xa0a0;	/* Data for the Third  Cycle    */
+				FirstAddr = 0xaaaa;	/* Address for the First  Cycle */
+				SecondAddr = 0x5555;	/* Address for the Second Cycle */
+				ThirdAddr = 0xaaaa;	/* Address for the Third  Cycle */
+			}
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    FirstAddr * FLASH_WIDTH, FirstData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    SecondAddr * FLASH_WIDTH, SecondData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    ThirdAddr * FLASH_WIDTH, ThirdData);
+#ifdef BE
+			s = (data >> 16);
+#else
+			s = data;
+#endif
+			WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s);
+			/* Writing Two Bytes */
+			if (FLASH_MODE == X16) {
+				data80 = 0x80;;
+				data20 = 0x20;;
+			} else {	/* if (FLASH_MODE == 8) */
+
+				data80 = 0x8080;
+				data20 = 0x2020;
+			}
+			while (true) {
+				READ_SHORT(FLASH_BASE_ADDRESS + offset,
+					   &rs);
+				if ((rs & data80) == (s & data80))	/* DQ7 =? DATA */
+					break;	/* DQ7 =  DATA */
+				if ((rs & data20) == data20) {	/* DQ5 =? DATA */
+					READ_SHORT(FLASH_BASE_ADDRESS +
+						   offset, &rs);
+					if ((rs & data80) == (s & data80))
+						break;	/* DQ7 = DATA  */
+					else {
+						flashReset();
+						return false;	/* DQ7 != DATA */
+					}
+				}
+			}
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    FirstAddr * FLASH_WIDTH, FirstData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    SecondAddr * FLASH_WIDTH, SecondData);
+			WRITE_SHORT(FLASH_BASE_ADDRESS +
+				    ThirdAddr * FLASH_WIDTH, ThirdData);
+#ifdef BE
+			s = data;
+#else
+			s = (data >> 16);
+#endif
+			WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s);
+			/* Writing Two Bytes */
+			while (true) {
+				READ_SHORT(FLASH_BASE_ADDRESS + offset + 2,
+					   &rs);
+				if ((rs & data80) == (s & data80))	/* DQ7 =? DATA */
+					break;	/* DQ7 =  DATA */
+				if ((rs & data20) == data20) {	/* DQ5 =? '1'  */
+					READ_SHORT(FLASH_BASE_ADDRESS +
+						   offset + 2, &rs);
+					if ((rs & data80) == (s & data80))
+						break;	/* DQ7 = DATA  */
+					else {
+						flashReset();
+						return false;	/* DQ7 != DATA */
+					}
+				}
+			}
+			return true;
+		case 4:
+		case 8:
+			if (FLASH_MODE == X16) {
+				FirstData = 0x00aa00aa;
+				SecondData = 0x00550055;
+				ThirdData = 0x00a000a0;
+				FirstAddr = 0x5555;
+				SecondAddr = 0x2aaa;
+				ThirdAddr = 0x5555;
+			} else {	/* (FLASH_MODE == 8) */
+
+				FirstData = 0xaaaaaaaa;	/* Data for the First  Cycle    */
+				SecondData = 0x55555555;	/* Data for the Second Cycle    */
+				ThirdData = 0xa0a0a0a0;	/* Data for the Third  Cycle    */
+				FirstAddr = 0xaaaaaaaa;	/* Address for the First  Cycle */
+				SecondAddr = 0x55555555;	/* Address for the Second Cycle */
+				ThirdAddr = 0xaaaaaaaa;	/* Address for the Third  Cycle */
+			}
+			WRITE_WORD(FLASH_BASE_ADDRESS + FirstAddr *
+				   FLASH_WIDTH + offset % FLASH_WIDTH,
+				   FirstData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   SecondAddr * FLASH_WIDTH +
+				   offset % FLASH_WIDTH, SecondData);
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   ThirdAddr * FLASH_WIDTH +
+				   offset % FLASH_WIDTH, ThirdData);
+			/* writting the word. */
+			WRITE_WORD(FLASH_BASE_ADDRESS + offset, data);
+			/* preparing the polling patterns. */
+			if (FLASH_MODE == X16) {
+				data80 = 0x00800080;
+				data20 = 0x00200020;
+			} else {	/* (FLASH_MODE == 8) */
+
+				data80 = 0x80808080;
+				data20 = 0x20202020;
+			}
+			while (true) {	/* polling loop. */
+				rw = READWORD(FLASH_BASE_ADDRESS + offset);
+				/* DQ7 =? DATA */
+				if ((rw & data80) == (data & data80))
+					break;	/* DQ7 =  DATA */
+				if ((rw & data20) == data20) {	/* DQ5 =? '1'  */
+					rw =
+					    READWORD(FLASH_BASE_ADDRESS +
+						     offset);
+					if ((rw & data80) ==
+					    (data & data80)) break;	/* DQ7 = DATA  */
+					else
+						return false;	/* DQ7 != DATA */
+				}
+			}
+			return true;
+		default:
+			return false;	/* case of invalid flash Width. */
+		}
+	} else {		/* Intel/Micron */
+
+		switch (FLASH_WIDTH) {
+		case 1:
+			/* Writing First Byte */
+			WRITE_CHAR(FLASH_BASE_ADDRESS, 0x10);
+#ifdef BE
+			c = (data >> 24);
+#else
+			c = data;
+#endif
+			WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c);
+			while (true) {
+				/* Reading STATUS Register */
+				WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+				regValue = READCHAR(FLASH_BASE_ADDRESS);
+				if ((regValue & 0x80) == 0x80)
+					break;	/* Case of Write-Operation had Ended */
+			}
+			/* Reading STATUS Register for Writing Verification */
+			WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+			regValue = READCHAR(FLASH_BASE_ADDRESS);
+			if ((regValue & 0x10) == 0x10)
+				return false;	/* Write failure */
+
+			/* Writing Second Byte */
+			WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x10);
+#ifdef BE
+			c = (data >> 16);
+#else
+			c = (data >> 8);
+#endif
+			WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c);
+			while (true) {
+				/* Reading STATUS Register */
+				WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70);
+				regValue =
+				    READCHAR(FLASH_BASE_ADDRESS + 1);
+				if ((regValue & 0x80) == 0x80)
+					break;	/* Write operation ended */
+			}
+			/* Reading STATUS Register for Writing verification */
+			WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70);
+			regValue = READCHAR(FLASH_BASE_ADDRESS + 1);
+			if ((regValue & 0x10) == 0x10)
+				return false;	/* Write failure */
+
+			/* Writing Third Byte */
+			WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x10);
+#ifdef BE
+			c = (data >> 8);
+#else
+			c = (data >> 16);
+#endif
+			WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c);
+			while (true) {
+				/* Reading STATUS Register */
+				WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70);
+				regValue =
+				    READCHAR(FLASH_BASE_ADDRESS + 2);
+				if ((regValue & 0x80) == 0x80)
+					break;	/* Write operation ended */
+			}
+			/* Reading STATUS Register for Writing Verification */
+			WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70);
+			regValue = READCHAR(FLASH_BASE_ADDRESS + 2);
+			if ((regValue & 0x10) == 0x10)
+				return false;	/* Write failure */
+
+			/* Writing Fourth Byte */
+			WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x10);
+#ifdef BE
+			c = data;
+#else
+			c = (data >> 24);
+#endif
+			WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c);
+			while (true) {
+				/* Reading STATUS Register */
+				WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70);
+				regValue =
+				    READCHAR(FLASH_BASE_ADDRESS + 3);
+				if ((regValue & 0x80) == 0x80)
+					break;	/* Write operation ended */
+			}
+			/* Reading STATUS Register for Writing Verification */
+			WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70);
+			regValue = READCHAR(FLASH_BASE_ADDRESS + 3);
+			if ((regValue & 0x10) == 0x10)
+				return false;	/* Write failure */
+			flashReset();
+			return true;
+		case 2:
+			if (FLASH_MODE == X16) {	/* Case of one X16 bit device */
+				FirstData = 0x0010;	/* Data for the First  Cycle  */
+			} else {	/* if (FLASH_MODE == 8) ==> Case of two X8 bit devices */
+
+				FirstData = 0x1010;	/* Data for the First  Cycle  */
+			}
+			/* Writing First two Bytes */
+			WRITE_SHORT(FLASH_BASE_ADDRESS, FirstData);
+#ifdef BE
+			s = (data >> 16);
+#else
+			s = data;
+#endif
+			WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s);
+			if (FLASH_MODE == X16) {
+				data70 = 0x0070;
+				data80 = 0x0080;
+				data10 = 0x0010;
+			} else {	/* case of (FLASH_MODE == X8) */
+
+				data70 = 0x7070;
+				data80 = 0x8080;
+				data10 = 0x1010;
+			}
+			/* polling on writing action => when done break. */
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS, data70);
+				regValue = READSHORT(FLASH_BASE_ADDRESS);
+				if ((regValue & data80) == data80)
+					break;
+			}
+			/* Reading STATUS Register for Writing Verification */
+			WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+			regValue = READCHAR(FLASH_BASE_ADDRESS);
+			if ((regValue & data10) == data10)
+				return false;	/* Write failure */
+			/* Writing Last two Bytes */
+			WRITE_SHORT(FLASH_BASE_ADDRESS + 2, FirstData);
+#ifdef BE
+			s = data;
+#else
+			s = (data >> 16);
+#endif
+			WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s);
+			/* polling on writing action => when done break. */
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+					    data70);
+				regValue =
+				    READSHORT(FLASH_BASE_ADDRESS + 2);
+				if ((regValue & data80) == data80)
+					break;
+			}
+			/* Reading STATUS Register for Writing Verification */
+			WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+			regValue = READCHAR(FLASH_BASE_ADDRESS);
+			if ((regValue & data10) == data10)
+				return false;	/* Write failure */
+			flashReset();
+			return true;
+		case 4:
+		case 8:
+			if (FLASH_MODE == X16) {	/* Case of one X16 bit device */
+				FirstData = 0x00100010;	/* Data for the First  Cycle  */
+			} else {	/* (FLASH_MODE == 8) ==> Case of two X8 bit devices */
+
+				FirstData = 0x10101010;	/* Data for the First  Cycle  */
+			}
+			/* Writing First two Bytes */
+			WRITE_WORD(FLASH_BASE_ADDRESS +
+				   offset % FLASH_WIDTH, FirstData);
+#ifdef BE
+			s = (data >> 16);
+#else
+			s = data;
+#endif
+			/* writing the 32-bit data to flash. */
+			WRITE_WORD(FLASH_BASE_ADDRESS + offset, data);
+			if (FLASH_MODE == X16) {
+				data70 = 0x0070;
+				data80 = 0x0080;
+				data10 = 0x0010;
+			} else {	/* (FLASH_MODE == 8) */
+
+				data70 = 0x7070;
+				data80 = 0x8080;
+				data10 = 0x1010;
+			}
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS +
+					    offset % FLASH_WIDTH, data70);
+				regValue = READSHORT(FLASH_BASE_ADDRESS);
+				if ((regValue & data80) == data80)
+					break;
+			}
+			/* Reading STATUS Register for Writing Verification */
+			WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+			regValue = READCHAR(FLASH_BASE_ADDRESS);
+			if ((regValue & data10) == data10)
+				return false;	/* Write failure */
+
+			/* Writing Last two Bytes */
+#ifdef BE
+			s = data;
+#else
+			s = (data >> 16);
+#endif
+			while (true) {
+				WRITE_SHORT(FLASH_BASE_ADDRESS +
+					    offset % FLASH_WIDTH + 2,
+					    data70);
+				regValue =
+				    READSHORT(FLASH_BASE_ADDRESS +
+					      offset % FLASH_WIDTH + 2);
+				if ((regValue & data80) == data80)
+					break;
+			}
+			/* Reading STATUS Register for Writing Verification */
+			WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+			regValue = READCHAR(FLASH_BASE_ADDRESS);
+			if ((regValue & data10) == data10)
+				return false;	/* Write failure */
+
+			flashReset();
+			return true;
+		default:
+			flashReset();
+			return false;
+		}
+	}
+	flashReset();
+	return true;
+}
+
+/********************************************************************
+* flashReadWord - Read 32Bit from the FLASH memory at a given offset 
+*                 from the FLASH base address.
+* 				  address 0 = 0x00000000 !!
+*                 The function takes care of Big/Little endian conversion
+* INPUTS:  offset,the offset from the flash`s base address
+* RETURNS: data
+*********************************************************************/
+unsigned int flashReadWord(unsigned int offset)
+{
+	unsigned int regValue;
+	flashReset();
+	READ_WORD(FLASH_BASE_ADDRESS + offset, &regValue);
+	return regValue;
+}
+
+/********************************************************************
+* flashInWhichSector - Returns the sector`s number at which offset is at.
+*
+* INPUTS:  Offset
+* RETURNS: Sector number,or 0xffffffff in case the address is out of range or 
+*          flash wasn't initialize.
+*********************************************************************/
+unsigned int flashInWhichSector(unsigned int offset)
+{
+	unsigned int sectorNumber, numberOfDevices;
+	unsigned int accMemory = 0;
+
+	if ((FLASH_MODE == PURE8) || (FLASH_MODE == X8)) {
+		numberOfDevices = FLASH_WIDTH;
+	} else {		/* X16 mode */
+
+		numberOfDevices = FLASH_WIDTH / 2;
+	}
+	for (sectorNumber = 0;
+	     sectorNumber < flashTypes[NUMBER_OF_SECTORS]; sectorNumber++) {
+		accMemory =
+		    accMemory + flashTypes[FIRST_SECTOR_SIZE +
+					   sectorNumber];
+		if (offset < accMemory * numberOfDevices * 1024)
+			return sectorNumber;
+	}
+	return 0xffffffff;
+}
+
+/********************************************************************
+* flashGetSectorSize - When given a Valid sector Number returns its Size.
+*
+* INPUTS:  unsigned int sectorNumber.
+* RETURNS: Sector size. (if Sector number isn't valid or flash wasn't 
+*          initialize return 0.)
+*********************************************************************/
+unsigned int flashGetSectorSize(unsigned int sectorNumber)
+{
+	if (sectorNumber >= flashTypes[NUMBER_OF_SECTORS])
+		return 0;
+	else {
+		if (FLASH_MODE != PURE8)
+			return (flashTypes
+				[FIRST_SECTOR_SIZE +
+				 sectorNumber] * _1K * (FLASH_WIDTH * 8 /
+							FLASH_MODE));
+		else		/* in case of PUR8 */
+			return (flashTypes
+				[FIRST_SECTOR_SIZE +
+				 sectorNumber] * _1K * FLASH_WIDTH);
+	}
+}
+
+/********************************************************************
+* getFlashSize - Return Total flash size.
+*
+* INPUTS:  N/A.
+* RETURNS: Flash size. (If flash wasn't initialize return 0)
+*********************************************************************/
+unsigned int flashGetSize()
+{
+	unsigned int sectorNum;
+	unsigned int totalSize = 0;
+
+	if (POINTER_TO_FLASH == 0)
+		return 0;	/* case of flash not initialize */
+	for (sectorNum = 0; sectorNum < flashTypes[NUMBER_OF_SECTORS];
+	     sectorNum++) {
+		totalSize += flashGetSectorSize(sectorNum);
+	}
+	return (totalSize);
+
+}
+
+/********************************************************************
+* flashGetSectorOffset - Returns sector base address.
+*
+* INPUTS:  unsigned int sectorNum.
+* RETURNS: Sector Base Address.
+*********************************************************************/
+unsigned int flashGetSectorOffset(unsigned int sectorNum)
+{
+	unsigned int i;
+	unsigned int sectorBaseAddress = 0;
+	unsigned int numOfDevices;
+
+	if (sectorNum > (flashParametrs[NUMBER_OF_SECTORS] - 1))
+		return 0xffffffff;
+	for (i = 0; i < sectorNum; i++) {
+		sectorBaseAddress =
+		    sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i];
+	}
+	if (FLASH_MODE == X16)
+		numOfDevices = FLASH_WIDTH * 8 / FLASH_MODE;
+	else
+		numOfDevices = FLASH_WIDTH;
+	return (_1K * sectorBaseAddress * numOfDevices);
+
+}
+
+/********************************************************************
+* flashWriteBlock - Write block of chars to flash.
+*
+* INPUTS:  unsigned int offset - flash destination address.
+*          unsigned int numOfByte - block size.
+*          unsigned char * blockAddress - block source address.
+* RETURNS: Number of Bytes written.
+*********************************************************************/
+unsigned int flashWriteBlock(unsigned int offset, unsigned int numOfByte,
+			     unsigned char *blockAddress)
+{
+	register unsigned int flashWrite;
+	register unsigned int align;
+	register unsigned int num;
+	register unsigned int i;
+
+	if ((offset + numOfByte) > flashGetSize())
+		numOfByte = flashGetSize() - offset;	/* getting to flash boundary. */
+	num = numOfByte;
+	align = offset % 4;	/* alignment toward flash.    */
+	/* writes chars until the offset toward flash will be align. */
+	for (i = align; (i < 4) && (numOfByte > 0) && (align != 0); i++) {
+		flashWriteChar(offset, blockAddress[0]);
+		numOfByte--;
+		offset++;
+		blockAddress++;
+	}
+	while (numOfByte > 3) {
+#ifdef LE
+		flashWrite = blockAddress[0] | (blockAddress[1] << 8) |
+		    (blockAddress[2] << 16) | (blockAddress[3] << 24);
+#else
+		flashWrite = blockAddress[3] | (blockAddress[2] << 8) |
+		    (blockAddress[1] << 16) | (blockAddress[0] << 24);
+#endif
+		if (flashWrite != 0xffffffff)	/* for optimization. */
+			flashWriteWord(offset, flashWrite);
+		numOfByte -= 4;
+		blockAddress += 4;
+		offset += 4;
+	}
+	while (numOfByte > 0) {
+		flashWriteChar(offset, blockAddress[0]);
+		numOfByte--;
+		blockAddress++;
+		offset++;
+	}
+	return num;
+}
+
+/********************************************************************
+* flashReadBlock - Read block of chars from flash.
+*
+* INPUTS:  unsigned int offset - flash source address.
+*          unsigned int numOfByte - block size.
+*          unsigned char * blockAddress - block destination address.
+* RETURNS: Number of Bytes written.
+*********************************************************************/
+unsigned int flashReadBlock(unsigned int offset, unsigned int numOfByte,
+			    unsigned char *blockAddress)
+{
+	unsigned int i;
+	for (i = 0; i < numOfByte; i++) {
+		blockAddress[i] = flashReadChar(offset + i);
+	}
+	return numOfByte;
+}
+
+/********************************************************************
+* flashReadChar - read one charecter form given flash offset.
+*
+* INPUTS:  unsigned int offset - required offset to be read from.
+* RETURNS: read charecter.
+*********************************************************************/
+unsigned char flashReadChar(unsigned int offset)
+{
+	unsigned char regValue;
+
+	flashReset();
+	READ_CHAR(FLASH_BASE_ADDRESS + offset, &regValue);
+	return regValue;
+}
+
+/********************************************************************
+* flashReadShort - read 16bit form given flash offset.
+*
+* INPUTS:  unsigned int offset - required offset to be read from.
+* RETURNS: 16bit data.
+*********************************************************************/
+unsigned short flashReadShort(unsigned int offset)
+{
+	unsigned short regValue;
+
+	flashReset();
+	READ_SHORT(FLASH_BASE_ADDRESS + offset, &regValue);
+	return regValue;
+}
+
+/********************************************************************
+* flashWriteShort - write 16bit data to a given flash offset.
+*                  It reads the whole word 32bit wide, modify the  short 
+*                  and write back the word.
+*
+* INPUTS:  unsigned int offset - required offset to be write to.
+*          unsigned short sdata - data to be written.
+* RETURNS: true if writting successesed false otherwise.
+*********************************************************************/
+bool flashWriteShort(unsigned int offset, unsigned short sdata)
+{
+	unsigned int align;
+	unsigned int flashWrite;
+	unsigned int flashRead;
+
+	align = offset % 4;
+	if ((align == 1) || (align == 3))
+		return false;	/* offset misaligned. */
+	flashRead = flashReadWord(offset - align);
+	if (align == 0)
+#ifdef BE
+		flashWrite = (flashRead & 0x0000ffff) | (sdata << 16);
+#else
+		flashWrite = (flashRead & 0xffff0000) | sdata;
+#endif
+	else			/* (align == 2) */
+#ifdef BE
+		flashWrite = (flashRead & 0xffff0000) | sdata;
+#else
+		flashWrite = (flashRead & 0x0000ffff) | (sdata << 16);
+#endif
+	flashWriteWord(offset - align, flashWrite);
+	return true;
+
+}
+
+/********************************************************************
+* flashWriteChar - write one charecter (8 bit) to a given flash offset.
+*                  It reads the whole word 32bit wide, modify the charecter 
+*                  and write back the word.
+*
+* INPUTS:  unsigned int offset - required offset to be write to.
+*          unsigned short sdata - data to be written.
+* RETURNS: true if writting successed.
+*********************************************************************/
+bool flashWriteChar(unsigned int offset, unsigned char cdata)
+{
+	unsigned int align;
+	unsigned int flashWrite;
+	unsigned int flashRead;
+
+	align = offset % 4;
+	flashRead = flashReadWord(offset - align);
+#ifdef BE
+	flashWrite = (flashRead & ~(0xff000000 >> (8 * align))) |
+	    (cdata << (8 * (3 - align)));
+#else
+	flashWrite = (flashRead & ~(0xff000000 << (8 * align))) |
+	    (cdata << (8 * align));
+#endif
+	flashWriteWord(offset - align, flashWrite);
+	return true;
+}
+
+/********************************************************************
+* flashGetNumOfSectors - write one charecter (8 bit) to a given flash offset.
+*                        It reads the whole word 32bit wide, modify the  
+*                        charecter and write back the word.
+*
+* INPUTS:  N/A.
+* RETURNS: Number of sectors.
+*********************************************************************/
+unsigned int flashGetNumOfSectors(void)
+{
+	return (flashTypes[NUMBER_OF_SECTORS]);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h linux/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,8 @@
+#define GFP_KERNEL 0
+#define GFP_ATOMIC 1
+#define KERN_ERR ""
+
+void *kmalloc(unsigned int, int);
+void *memset(void *, char, unsigned int);
+int memcmp(char *, char *, unsigned int);
+void *memcpy(void *to, const void *from, unsigned int);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/gt64011.h linux/arch/mips/galileo-boards/ev64120/compressed/gt64011.h
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/gt64011.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/gt64011.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,279 @@
+/*
+ * gt64011.h: Galileo PCI system controller
+ * Copyright (c) 1998 Algorithmics Ltd
+ */
+
+#ifdef __ASSEMBLY__
+
+/* offsets from base register */
+#define GT64011(x)		(x)
+
+/* device is littleendian, so data may need to be swapped */
+#ifdef GALILEO_PORT
+#define htoll(x) ((((x) & 0x00ff) << 24) | \
+		  (((x) & 0xff00) <<  8) | \
+		  (((x) >> 8)  & 0xff00) | \
+		  (((x) >> 24) & 0x00ff))
+/*#define ltohl(x) htoll(x)*/
+#else
+#define htoll(x) (x)
+/* #define ltohl(x) (x) */
+#endif
+
+#else /* !__ASSEMBLY__ */
+
+/* offsets from base pointer, this construct allows optimisation */
+static char *const _gt64011p = (char *) PA_TO_KVA1(GT64011_BASE);
+
+#define GT64011(x)		*(volatile unsigned long *)(_gt64011p + (x))
+
+/* device is littleendian, so data may need to be swapped */
+#ifdef GALILEO_PORT
+#define htoll(x)     ({			\
+  unsigned int v = (unsigned int)(x);	\
+  v = (((v & 0x00ff) << 24) |		\
+       ((v & 0xff00) <<  8) |		\
+       ((v >>  8) & 0xff00) |		\
+       ((v >> 24) & 0x00ff));		\
+    v;					\
+    })
+#define ltohl(x) htoll(x)
+
+#else
+asjdsajd
+#define htoll(x) (x)
+#define ltohl(x) (x)
+#endif
+#endif /* __ASSEMBLY__ */
+/* CPU configuration */
+#define GT_CPU_CFG	GT64011(0x000)
+#define GT_CPU_CFG_WriteMode	(1<<11)
+#define GT_CPU_CFG_Endianess	(1<<12)
+/* Processor Address Space */
+#define GT_PAS_RAS10LO	GT64011(0x008)
+#define GT_PAS_RAS10HI	GT64011(0x010)
+#define GT_PAS_RAS32LO	GT64011(0x018)
+#define GT_PAS_RAS32HI	GT64011(0x020)
+#define GT_PAS_CS20LO	GT64011(0x028)
+#define GT_PAS_CS20HI	GT64011(0x030)
+#define GT_PAS_CS3BOOTLO GT64011(0x038)
+#define GT_PAS_CS3BOOTHI GT64011(0x040)
+#define GT_PAS_PCIIOLO	GT64011(0x048)
+#define GT_PAS_PCIIOHI	GT64011(0x050)
+#define GT_PAS_PCIMEMLO	GT64011(0x058)
+#define GT_PAS_PCIMEMHI	GT64011(0x060)
+#define GT_PAS_INTDEC	GT64011(0x068)
+#define GT_PAS_BUSERRLO	GT64011(0x070)
+#define GT_PAS_PCIMEM1LO GT64011(0x080)
+#define GT_PAS_PCIMEM1HI GT64011(0x088)
+#define GT_PAS_LOMASK_Low	0x7ff
+#define GT_PAS_LOSHIFT_Low	0
+#define GT_PAS_HIMASK_High	0x07f
+#define GT_PAS_HISHIFT_High	0
+/* DRAM and  Device Address Space */
+#define GT_DDAS_RAS0LO	GT64011(0x400)
+#define GT_DDAS_RAS0HI	GT64011(0x404)
+#define GT_DDAS_RAS1LO	GT64011(0x408)
+#define GT_DDAS_RAS1HI	GT64011(0x40c)
+#define GT_DDAS_RAS2LO	GT64011(0x410)
+#define GT_DDAS_RAS2HI	GT64011(0x414)
+#define GT_DDAS_RAS3LO	GT64011(0x418)
+#define GT_DDAS_RAS3HI	GT64011(0x41c)
+#define GT_DDAS_CS0LO	GT64011(0x420)
+#define GT_DDAS_CS0HI	GT64011(0x424)
+#define GT_DDAS_CS1LO	GT64011(0x428)
+#define GT_DDAS_CS1HI	GT64011(0x42c)
+#define GT_DDAS_CS2LO	GT64011(0x430)
+#define GT_DDAS_CS2HI	GT64011(0x434)
+#define GT_DDAS_CS3LO	GT64011(0x438)
+#define GT_DDAS_CS3HI	GT64011(0x43c)
+#define GT_DDAS_BOOTCSLO	GT64011(0x440)
+#define GT_DDAS_BOOTCSHI	GT64011(0x444)
+#define GT_DDAS_ERROR	GT64011(0x470)
+#define GT_DDAS_LOMASK_Low	0xff
+#define GT_DDAS_LOSHIFT_Low	0
+#define GT_DDAS_HIMASK_High	0xff
+#define GT_DDAS_HISHIFT_High	0
+/* DRAM Configuration */
+#define GT_DRAM_CFG	GT64011(0x448)
+#define GT_DRAM_CFG_RefIntCntMASK	0x00003fff
+#define GT_DRAM_CFG_RefIntCntSHIFT	0
+#define GT_DRAM_CFG_RefIntCnt(x)	(((x)<<GT_DRAM_CFG_RefIntCntSHIFT)&\
+					 GT_DRAM_CFG_RefIntCntMASK)
+#define GT_DRAM_CFG_StagRef		(1<<16)
+#define GT_DRAM_CFG_StagRefOn		0
+#define GT_DRAM_CFG_StagRefAll		GT_DRAM_CFG_StagRef
+#define GT_DRAM_CFG_ADSFunct		(1<<17)
+#define GT_DRAM_CFG_ADSFunctDRAM	0
+#define GT_DRAM_CFG_ADSFunctOnly	GT_DRAM_CFG_ADSFunct
+#define GT_DRAM_CFG_DRAMLatch		(1<<18)
+#define GT_DRAM_CFG_DRAMLatchActive	0
+#define GT_DRAM_CFG_DRAMLatchTransparent GT_DRAM_CFG_DRAMLatch
+/* DRAM Parameters */
+#define GT_DRAMPAR_BANK0 GT64011(0x44c)
+#define GT_DRAMPAR_BANK1 GT64011(0x450)
+#define GT_DRAMPAR_BANK2 GT64011(0x454)
+#define GT_DRAMPAR_BANK3 GT64011(0x458)
+#define GT_DRAMPAR_CASWr		(1<<0)
+#define GT_DRAMPAR_CASWr1		0
+#define GT_DRAMPAR_CASWr2		GT_DRAMPAR_CASWr
+#define GT_DRAMPAR_RAStoCASWr		(1<<1)
+#define GT_DRAMPAR_RAStoCASWr2		0
+#define GT_DRAMPAR_RAStoCASWr3		GT_DRAMPAR_RAStoCASWr
+#define GT_DRAMPAR_CASRd		(1<<2)
+#define GT_DRAMPAR_CASRd1		0
+#define GT_DRAMPAR_CASRd2		GT_DRAMPAR_CASRd
+#define GT_DRAMPAR_RAStoCASRd		(1<<3)
+#define GT_DRAMPAR_RAStoCASRd2		0
+#define GT_DRAMPAR_RAStoCASRd3		GT_DRAMPAR_RAStoCASRd
+#define GT_DRAMPAR_RefreshSHIFT		4
+#define GT_DRAMPAR_RefreshMASK		(3<<4)
+#define GT_DRAMPAR_Refresh512		(0<<4)
+#define GT_DRAMPAR_Refresh1024		(1<<4)
+#define GT_DRAMPAR_Refresh2048		(2<<4)
+#define GT_DRAMPAR_Refresh4096		(3<<4)
+#define GT_DRAMPAR_BankWidth		(1<<6)
+#define GT_DRAMPAR_BankWidth32		0
+#define GT_DRAMPAR_BankWidth64		GT_DRAMPAR_BankWidth
+#define GT_DRAMPAR_BankLoc		(1<<7)
+#define GT_DRAMPAR_BankLocEven		0
+#define GT_DRAMPAR_BankLocOdd		GT_DRAMPAR_BankLoc
+#define GT_DRAMPAR_Parity		(1<<8)
+#define GT_DRAMPAR_ParityDisable	0
+#define GT_DRAMPAR_ParityEnable		GT_DRAMPAR_Parity
+#define GT_DRAMPAR_MBZ			(1<<9)
+/* Device Parameters */
+#define GT_DEVPAR_BANK0	GT64011(0x45c)
+#define GT_DEVPAR_BANK1	GT64011(0x460)
+#define GT_DEVPAR_BANK2	GT64011(0x464)
+#define GT_DEVPAR_BANK3	GT64011(0x468)
+#define GT_DEVPAR_BOOT	GT64011(0x46c)
+#define GT_DEVPAR_TurnOffMASK		(7<<0)
+#define GT_DEVPAR_TurnOffSHIFT		0
+#define GT_DEVPAR_TurnOff(x)		((x)<<0)
+#define GT_DEVPAR_AccToFirstMASK	(15<<3)
+#define GT_DEVPAR_AccToFirstSHIFT	3
+#define GT_DEVPAR_AccToFirst(x)		((x)<<3)
+#define GT_DEVPAR_AccToNextMASK		(15<<7)
+#define GT_DEVPAR_AccToNextSHIFT	7
+#define GT_DEVPAR_AccToNext(x)		((x)<<7)
+#define GT_DEVPAR_ADStoWrMASK		(7<<11)
+#define GT_DEVPAR_ADStoWrSHIFT		11
+#define GT_DEVPAR_ADStoWr(x)		((x)<<11)
+#define GT_DEVPAR_WrActiveMASK		(7<<14)
+#define GT_DEVPAR_WrActiveSHIFT		14
+#define GT_DEVPAR_WrActive(x)		((x)<<14)
+#define GT_DEVPAR_WrHighMASK		(7<<17)
+#define GT_DEVPAR_WrHighSHIFT		17
+#define GT_DEVPAR_WrHigh(x)		((x)<<17)
+#define GT_DEVPAR_DevWidthMASK		(3<<20)
+#define GT_DEVPAR_DevWidthSHIFT		20
+#define GT_DEVPAR_DevWidth8		(0<<20)
+#define GT_DEVPAR_DevWidth16		(1<<20)
+#define GT_DEVPAR_DevWidth32		(2<<20)
+#define GT_DEVPAR_DevWidth64		(3<<20)
+#define GT_DEVPAR_DevLoc		(1<<23)
+#define GT_DEVPAR_DevLocEven		0
+#define GT_DEVPAR_DevLocOdd		GT_DEVPAR_DevLoc
+#define GT_DEVPAR_LatchFunct		(1<<25)
+#define GT_DEVPAR_LatchFunctTransparent 0
+#define GT_DEVPAR_LatchFunctEnable	GT_DEVPAR_LatchFunct
+#define GT_DEVPAR_Parity		(1<<30)
+#define GT_DEVPAR_ParityDisable		0
+#define GT_DEVPAR_ParityEnable		GT_DEVPAR_Parity
+#define GT_DEVPAR_ReservedMASK		0x3d400000
+#define GT_DEVPAR_Reserved		0x14400000
+/* PCI Internal */
+#define GT_IPCI_CMD GT64011(0xc00)
+#define GT_IPCI_CMD_ByteSwap		(1<<0)
+#define GT_IPCI_CMD_ByteSwapOn		0
+#define GT_IPCI_CMD_ByteSwapOff		GT_INTPCI_CMD_ByteSwap
+#define GT_IPCI_CMD_SyncModeMASK	(3<<1)
+#define GT_IPCI_CMD_SyncModeSHIFT	1
+#define GT_IPCI_CMD_SyncModeStd		(0<<1)
+#define GT_IPCI_CMD_SyncMode1		(1<<1)
+#define GT_IPCI_CMD_SyncMode2		(2<<1)
+#define GT_IPCI_TOR	GT64011(0xc04)
+#define GT_IPCI_TOR_Timeout0MASK	(255<<0)
+#define GT_IPCI_TOR_Timeout0SHIFT	0
+#define GT_IPCI_TOR_Timeout0(x)	((x)<<0)
+#define GT_IPCI_TOR_Timeout1MASK	(255<<8)
+#define GT_IPCI_TOR_Timeout1SHIFT	8
+#define GT_IPCI_TOR_Timeout1(x)	((x)<<8)
+#define GT_IPCI_TOR_RetryCtrMASK	(255<<16)
+#define GT_IPCI_TOR_RetryCtrSHIFT	16
+#define GT_IPCI_TOR_RetryCtr(x)		((x)<<16)
+#define GT_IPCI_RAS10SIZE	GT64011(0xc08)
+#define GT_IPCI_RAS32SIZE	GT64011(0xc0c)
+#define GT_IPCI_CS20SIZE	GT64011(0xc10)
+#define GT_IPCI_CS3BOOTSIZE	GT64011(0xc14)
+#define GT_IPCI_SIZE_BankSizeMASK	(0xfffff<<12)
+#define GT_IPCI_SIZE_BankSizeSHIFT	12
+#define GT_IPCI_INTRCAUSE	GT64011(0xc18)
+#define GT_IPCI_INTRMASK	GT64011(0xc1c)
+#define  GT_INTR_INTSUM			0x0000001
+#define  GT_INTR_MEMOUT			0x0000002
+#define  GT_INTR_DMAOUT			0x0000004
+#define  GT_INTR_CPUOUT			0x0000008
+#define  GT_INTR_DMA0COMP		0x0000010
+#define  GT_INTR_DMA1COMP		0x0000020
+#define  GT_INTR_DMA2COMP		0x0000040
+#define  GT_INTR_DMA3COMP		0x0000080
+#define  GT_INTR_T0EXP			0x0000100
+#define  GT_INTR_T1EXP			0x0000200
+#define  GT_INTR_T2EXP			0x0000400
+#define  GT_INTR_T3EXP			0x0000800
+#define  GT_INTR_MASRDERR		0x0001000
+#define  GT_INTR_SLVWRERR		0x0002000
+#define  GT_INTR_MASWRERR		0x0004000
+#define  GT_INTR_SLVRDERR		0x0008000
+#define  GT_INTR_ADDRERR		0x0010000
+#define  GT_INTR_MEMERR			0x0020000
+#define  GT_INTR_MASABORT		0x0040000
+#define  GT_INTR_TARABORT		0x0080000
+#define  GT_INTR_RETRYCTR		0x0010000
+#define  GT_INTR_CPU2PCIA		0x0020000
+#define  GT_INTR_CPU2PCIB		0x0040000
+#define  GT_INTR_CPU2PCIC		0x0080000
+#define  GT_INTR_CPU2PCID		0x0100000
+#define  GT_INTR_CPU2PCIE		0x0200000
+#define  GT_INTR_PCI2CPUA		0x0400000
+#define  GT_INTR_PCI2CPUB		0x0800000
+#define  GT_INTR_PCI2CPUC		0x1000000
+#define  GT_INTR_PCI2CPUD		0x2000000
+#define  GT_INTR_CPUINTSUM		0x4000000
+#define  GT_INTR_PCIINTSUM		0x8000000
+#define GT_IPCI_PCIINTMASK	GT64011(0xc24)
+#define GT_IPCI_SERMASK		GT64011(0xc28)
+#define GT_IPCI_SERMASK_AddrErr		(1<<0)
+#define GT_IPCI_SERMASK_MasWrErr	(1<<1)
+#define GT_IPCI_SERMASK_MasRdErr	(1<<2)
+#define GT_IPCI_SERMASK_MemErr		(1<<3)
+#define GT_IPCI_SERMASK_MasAbort	(1<<4)
+#define GT_IPCI_SERMASK_TarAbort	(1<<5)
+#define GT_IPCI_INTACK		GT64011(0xc34)
+#define GT_IPCI_BAREN		GT64011(0xc3c)
+#define GT_IPCI_BAREN_SwCs3BootDis	(1<<0)
+#define GT_IPCI_BAREN_SwRas32Dis	(1<<1)
+#define GT_IPCI_BAREN_SwRas10Dis	(1<<2)
+#define GT_IPCI_BAREN_IntIODis		(1<<3)
+#define GT_IPCI_BAREN_IntMemDis		(1<<4)
+#define GT_IPCI_BAREN_Cs3BootDis	(1<<5)
+#define GT_IPCI_BAREN_Cs20Dis		(1<<6)
+#define GT_IPCI_BAREN_Ras32Dis		(1<<7)
+#define GT_IPCI_BAREN_Ras10Dis		(1<<8)
+#define GT_IPCI_CFGADDR		GT64011(0xcf8)
+#define GT_IPCI_CFGDATA		GT64011(0xcfc)
+#define GT_IPCI_CFGADDR_RegNumMASK	(0x3f<<2)
+#define GT_IPCI_CFGADDR_RegNumSHIFT	2
+#define GT_IPCI_CFGADDR_RegNum(x)	((x)<<2)
+#define GT_IPCI_CFGADDR_FunctNumMASK	(0x7<<8)
+#define GT_IPCI_CFGADDR_FunctNumSHIFT	8
+#define GT_IPCI_CFGADDR_FunctNum(x)	((x)<<8)
+#define GT_IPCI_CFGADDR_DevNumMASK	(0x1f<<11)
+#define GT_IPCI_CFGADDR_DevNumSHIFT	11
+#define GT_IPCI_CFGADDR_DevNum(x)	((x)<<11)
+#define GT_IPCI_CFGADDR_BusNumMASK	(0xff<<16)
+#define GT_IPCI_CFGADDR_BusNumSHIFT	16
+#define GT_IPCI_CFGADDR_BusNum(x)	((x)<<16)
+#define GT_IPCI_CFGADDR_ConfigEn	(1<<31)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/head.S linux/arch/mips/galileo-boards/ev64120/compressed/head.S
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/head.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/head.S	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,19 @@
+/*
+ *  arch/mips/galileo/compressed/head.S
+ *
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+	.text
+NESTED(startup, 16, sp)
+	.set	noreorder
+        
+	jal decompress_kernel
+	nop
+        
+        jal kernel_location_start+0x584
+        nop
+        
+	END(startup)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal linux/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,19 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(startup)
+SECTIONS 
+{ 
+  kernel_location_start = 0x80100000;
+  . = 0x80400000;
+  .text : {
+  *(.text)
+  }
+  .bss : {
+  *(.bss)
+  }
+  .data :{
+  *(.data)
+  }
+  malloc_start = .;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash linux/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,29 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(sbdreset)
+
+SECTIONS
+{
+  . = 0xBFC00000;
+  .got : {*(.got)}
+  .reset : { 
+    sbdreset = ABSOLUTE(.);
+    sbdreset_evb64120A.o
+    evb64120A_Setup.o /* <-- Note: contains xfer.c contents as well.. */
+    pci_etherboot.o
+    memory.o
+    pci.o
+  }
+  kernel_location_start = 0x80100000;
+  . = 0x80400000;
+  .text : {
+  *(.text)
+  }
+  .bss : {
+  *(.bss)
+  }
+  .data :{
+  *(.data)
+  }
+  malloc_start = .;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 linux/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,24 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(XferToRam)
+
+SECTIONS
+{
+  . = 0xBF000000;
+  .got : {*(.got)}
+  .reset : { 
+    xfer.o
+  }
+  kernel_location_start = 0x80100000;
+  . = 0x80400000;
+  .text : {
+  *(.text)
+  }
+  .bss : {
+  *(.bss)
+  }
+  .data :{
+  *(.data)
+  }
+  malloc_start = .;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner linux/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,11 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(main)
+
+SECTIONS
+{
+ . = 0xA0400000;
+ .text : {*(.text)}
+ .data : {*(.data)}
+ .bss  : {*(.bss)}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/load.c linux/arch/mips/galileo-boards/ev64120/compressed/load.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/load.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/load.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,244 @@
+
+/* control character used for download */
+#define ETX	CNTRL('c')
+#define ACK	CNTRL('f')
+#define NAK	CNTRL('u')
+#define XON	CNTRL('q')
+#define XOFF	CNTRL('s')
+
+unsigned int csum;
+unsigned int dl_entry;
+
+static const unsigned char hextab[256] = {
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
+	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	    255, 255, 255,
+};
+
+
+unsigned char ascii_to_bin(unsigned char c)
+{
+	return hextab[c];
+}
+
+unsigned char read_char_direct(void)
+{
+	unsigned char c, *cp;
+	cp = (unsigned char *) 0xbd000020;
+	while (1) {
+		if (*(cp + 0x14) & 0x01) {
+			c = (volatile unsigned char) *cp;
+			return c;
+		}
+		cp++;
+		cp--;
+	}
+}
+
+unsigned char get_pair(void)
+{
+	unsigned char byte;
+
+	byte = ascii_to_bin(read_char_direct()) << 4;
+	byte |= ascii_to_bin(read_char_direct());
+	csum += byte;
+	return (byte);
+}
+
+
+void serial_putc(int ch)
+{
+	unsigned long temp;
+	for (temp = 0; temp < 1000; temp++) {
+	}
+	*(char *) 0xbd000020 = (char) ch;
+}
+
+
+int inline serial_getc(void)
+{
+	return read_char_direct();
+}
+
+int serial_ischar(void)
+{
+
+	unsigned char c, *cp;
+	unsigned count;
+	cp = (unsigned char *) 0xbd000020;
+	count = 0;
+	while (count != 100) {
+		if (*(cp + 0x14) & 0x01) {
+			c = (volatile unsigned char) *cp;
+			return c;
+		}
+		cp++;
+		cp--;
+		count++;
+	}
+	return 0;
+}
+
+int serial_init(void)
+{
+	return 0;
+}
+
+
+int galileo_dl(void)
+{
+#define display_char '.'
+#define display_error 'E'
+#define display_error_bad_7 '7'
+#define display_error_unknown 'U'
+#define display_error_length 'L'
+
+	register int length, address, save_csum;
+	int i, first, done, eof, reccount, type, client_pc;
+	int src, dbl_length;
+	unsigned char *buffptr, databuff[258], tempo;
+	register int display_counter, chunks, leftovers, putter,
+	    bytes_per_chunk;
+	display_counter = 0;
+	bytes_per_chunk = 16;
+	csum = 0;
+
+	reccount = 1;
+	for (first = 1, done = 0; !done; first = 0, reccount++) {
+		while (read_char_direct() != 'S')
+			continue;
+		csum = 0;
+		type = read_char_direct();
+		length = get_pair();
+		if (length < 0 || length >= 256) {
+			*(char *) 0xbd000020 = display_error_length;
+			//      *(char*)0xbd00000c = display_error_length;
+			return 0;
+		}
+		length--;
+		switch (type) {
+		case '0':
+			while (length-- > 0)
+				get_pair();
+			break;
+		case '3':
+			address = 0;
+			for (i = 0; i < 4; i++) {
+				address <<= 8;
+				address |= get_pair();
+				length--;
+			}
+			if (address == -1) {
+				eof = 1;
+				continue;
+			}
+			buffptr = &databuff[0];
+			dbl_length = length << 1;
+			chunks = dbl_length / bytes_per_chunk;
+			leftovers = dbl_length % bytes_per_chunk;
+			putter = bytes_per_chunk >> 1;
+			while (chunks--) {
+				for (i = 0; i < bytes_per_chunk; i++)
+					databuff[i] = read_char_direct();
+				src = i = 0;
+				while (i++ < putter) {
+					tempo =
+					    (ascii_to_bin(databuff[src++])
+					     << 4) |
+					    ascii_to_bin(databuff[src++]);
+					csum += tempo;
+					*(char *) address++ = tempo;
+				}
+			}
+			if (leftovers) {
+				putter = leftovers / 2;
+				for (i = 0; i < leftovers; i++)
+					databuff[i] = read_char_direct();
+				src = i = 0;
+				while (i++ < putter) {
+					tempo =
+					    (ascii_to_bin(databuff[src++])
+					     << 4) |
+					    ascii_to_bin(databuff[src++]);
+					csum += tempo;
+					*(char *) address++ = tempo;
+				}
+			}
+			break;
+
+		case '7':
+			address = 0;
+			for (i = 0; i < 4; i++) {
+				address <<= 8;
+				address |= get_pair();
+				length--;
+			}
+			if (address == -1) {
+				eof = 1;
+				continue;
+			}
+			client_pc = address;
+			if (length) {
+				*(char *) 0xbd000020 = display_error_bad_7;
+				//                      *(char*)0xbd00000c = display_error_bad_7;
+			}
+
+			done = 1;
+			break;
+
+		default:
+			*(char *) 0xbd000020 = display_error_unknown;
+			//              *(char*)0xbd00000c = display_error_unknown;
+
+			break;
+		}
+		save_csum = (~csum) & 0xff;
+		if ((csum = get_pair()) < 0) {
+			eof = 1;
+			continue;
+		}
+		if (csum != save_csum) {
+			*(char *) 0xbd000020 = display_error;
+			//                *(char*)0xbd00000c = display_error;
+		} else {
+
+			if (display_counter % 50 == 0) {
+				*(char *) 0xbd000020 = display_char;
+				display_counter = 0;
+			}
+			display_counter++;
+
+		}
+	}
+	--reccount;
+	dl_entry = client_pc;
+	return dl_entry;	/* Success */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/meminit.S linux/arch/mips/galileo-boards/ev64120/compressed/meminit.S
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/meminit.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/meminit.S	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,187 @@
+/* 
+ * Define BUSWIDTH to usually be real buswidth X 2 (i.e assuming 
+ * 2-way interleaving).  This is so that the test pattern and
+ * inverted pattern are written to the same bank of memory, which
+ * prevents us reading back data sitting in the dram buffers and 
+ * getting a false match.
+ */
+
+#ifndef BUSWIDTH
+# if #cpu(r3000) || #cpu(r4300) || #cpu(r4650)
+#  define BUSWIDTH	8		/* 32 bit memory, bank interleaved */
+# elif #cpu(r4000)
+#  define BUSWIDTH	16		/* 64 bit memory, bank interleaved */
+# endif
+#endif
+
+#ifndef RAM_BASE
+#define RAM_BASE	KSEG1_BASE
+#endif
+			
+#ifndef MEMSTART
+#define MEMSTART	0x0		/* start of physical memory */
+#endif
+		
+#ifndef MEMINCR
+# define MEMINCR	0x10000		/* work up in 64Kb increments */
+#endif
+
+SLEAF(size_mem)
+	mfc0	t8,C0_STATUS
+#if #cpu(r4000)
+	/* disable cache and memory parity checking */
+	or	t0,t8,SR_DE
+	mtc0	t0,C0_STATUS
+#endif
+
+	li	t0,RAM_BASE+MEMSTART	# start at bottom of phys mem
+	move	t1,t0			# remember start address
+	li	t2,0xaa55aa55		# pattern 
+	not	t3,t2			# ~pattern
+
+	move	t7,k0
+	la	t4,.fail		# bus error exception catcher
+	addu	k0,t4,s8		# RELOC 
+	
+	/* fill first 64Kb with zero (for cache init) */
+	move	t4,t0
+	li	t5,0x10000
+1:	sw	zero,0(t4)
+	sw	zero,4(t4)
+	sw	zero,8(t4)
+	sw	zero,12(t4)
+	subu	t5,16
+	addu	t4,16
+	bnez	t5,1b
+
+.loop:
+        addu    t0,MEMINCR		
+	move	t4,t0
+
+	/* store pattern in bank 0, line 0 */
+	sw	t2,0(t4)
+	addu	t4,4
+
+#if BUSWIDTH > 4
+	/* fill remainder of line with zeros */
+	li	t5,BUSWIDTH-4
+1:	sw	zero,0(t4)
+	subu	t5,4
+	addu	t4,4
+	bnez	t5,1b
+#endif
+
+	/* store inverse pattern in bank 0, line 1 */
+	sw	t3,0(t4)
+	addu	t4,4
+
+#if BUSWIDTH > 4
+	/* fill remainder of line with zeros */
+	li	t5,BUSWIDTH-4
+1:	sw	zero,0(t4)
+	subu	t5,4
+	addu	t4,4
+	bnez	t5,1b
+#endif
+
+	/* defeat write buffering */
+#if #cpu(r4000)
+	sync
+#else
+	lw	zero,-4(t4)
+#endif
+
+	lw	t4,0(t0)		# read first word of line
+	lw	t5,0(t1)		# read start of memory (should be zero)
+	bne	t4,t2,.fail		# this line wrong?
+        beq     t5,zero,.loop		# start of mem overwritten?
+
+.fail:
+	move	k0,t7			# clear exception catcher
+
+	/* restore Status register */
+	mtc0	t8,C0_STATUS
+
+	/* return top of memory offset (normally == size) */
+	subu 	v0,t0,RAM_BASE
+	j	ra
+END(size_mem)
+
+
+/*
+ * We must often initialise memory so that it has good parity/ecc, 
+ * and this must be done before the caches are used.
+ */
+
+/*
+	clear_mem (size)
+	  - clear memory from RAM_BASE+MEMSTART to RAM_BASE+MEMSTART+size
+	clear_mem_range (size, start)  
+	  - clear memory from start to start+size
+*/
+
+SLEAF(clear_mem)
+	li	a1,RAM_BASE+MEMSTART	# start at bottom of phys mem
+clear_mem_range:	
+	beqz	a0,9f
+	addu	a0,a1			# end of memory 
+	
+	/* XXX should run cached, but caches may not be initialised yet */
+	.set noreorder	
+#if __mips >= 3
+1:	sd	zero,0(a1)
+	sd	zero,8(a1)
+	sd	zero,16(a1)
+	sd	zero,24(a1)
+	sd	zero,32(a1)
+	sd	zero,40(a1)
+	sd	zero,48(a1)
+	addu	a1,64
+	bne	a1,a0,1b
+	sd	zero,-8(a1)		# BDSLOT
+#else	
+1:	sw	zero,0(a1)
+	sw	zero,4(a1)
+	sw	zero,8(a1)
+	sw	zero,12(a1)
+	sw	zero,16(a1)
+	sw	zero,20(a1)
+	sw	zero,24(a1)
+	sw	zero,28(a1)
+	sw	zero,32(a1)
+	sw	zero,36(a1)
+	sw	zero,40(a1)
+	sw	zero,44(a1)
+	sw	zero,48(a1)
+	sw	zero,52(a1)
+	sw	zero,56(a1)
+	addu	a1,64
+	bne	a1,a0,1b
+	sw	zero,-4(a1)		# BDSLOT
+#endif	
+	.set	reorder
+
+9:	j	ra
+END(clear_mem)
+
+
+SLEAF(init_tlb)
+	/* initialise tlb */
+	mtc0	zero,C0_TLBLO0		/* tlblo0 = invalid */
+	mtc0	zero,C0_TLBLO1		/* tlblo1 = invalid */
+        mtc0	zero,C0_PGMASK
+	li	t8,K1BASE		/* tlbhi  = impossible vpn */
+	li	t9,(NTLBENTRIES-1)	/* index */
+	
+	.set noreorder
+	nop
+1:	mtc0	t8,C0_TLBHI
+	mtc0	t9,C0_INX
+	addu	t8,0x2000		/* inc vpn */
+	tlbwi
+	bnez	t9,1b
+	subu	t9,1			# BDSLOT
+	.set reorder
+
+	j	ra
+END(init_tlb)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/memory.c linux/arch/mips/galileo-boards/ev64120/compressed/memory.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/memory.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/memory.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,593 @@
+/* Memory.c - Memory mappings and remapping functions */
+
+/* Copyright - Galileo technology. */
+
+/*
+DESCRIPTION
+This file contains function which gives the user the ability to remap the
+SDRAM memory and devices windows, please pay attention to overlapping windows
+since the function do not take care of that for you.
+When remapping the SDRAM or devices memory space pay attention to the PCI
+mappings and make sure to coordinate between the two interfaces!!!           
+*/
+
+/* includes */
+
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/core.h>
+#include <asm/galileo-boards/evb64120A/memory.h>
+#else
+#include "Core.h"
+#include "Memory.h"
+#endif
+
+/********************************************************************
+* getMemoryBankBaseAddress - Extract the base address of a memory bank
+*      - If the memory bank size is 0 then this base address has no meaning !!!
+*
+* INPUTS:  MEMORY_BANK bank - SDRAM Bank number.
+* OUTPUT:  N/A  
+* RETURNS: Memory bank base address.
+*********************************************************************/
+unsigned int getMemoryBankBaseAddress(MEMORY_BANK bank)
+{
+	unsigned int base, regBase;
+	GT_REG_READ((SCS_1_0_LOW_DECODE_ADDRESS + (bank / 2) * 0x10),
+		    &base);
+	base = base << 21;
+	GT_REG_READ((SCS_0_LOW_DECODE_ADDRESS + bank * 8), &regBase);
+	base = base | (regBase << 20);
+	return base;
+}
+
+/********************************************************************
+* getDeviceBaseAddress - Extract the base address of a device.
+*           - If the device size is 0 then this base address has no meaning!!!
+*
+* INPUT:   DEVICE device - Bank number.
+* OUTPUT:  N/A  
+* RETURNS: Device base address.
+*********************************************************************/
+unsigned int getDeviceBaseAddress(DEVICE device)
+{
+	unsigned int base, regBase;
+	GT_REG_READ((CS_2_0_LOW_DECODE_ADDRESS + (device / 3) * 0x10),
+		    &base);
+	base = base << 21;
+	GT_REG_READ((CS_0_LOW_DECODE_ADDRESS + device * 0x8), &regBase);
+	base = base | (regBase << 20);
+	return base;
+}
+
+/********************************************************************
+* getMemoryBankSize - Extract the size of a memory bank.
+*
+* INPUT:   MEMORY_BANK bank - Bank number
+* OUTPUT:  N/A
+* RETURNS: Memory bank size.
+*********************************************************************/
+unsigned int getMemoryBankSize(MEMORY_BANK bank)
+{
+	unsigned int size, base, value;
+	base = getMemoryBankBaseAddress(bank);
+	GT_REG_READ((SCS_0_HIGH_DECODE_ADDRESS + bank * 8), &size);
+	size = ((size + 1) << 20) - (base & 0x0fffffff);
+	GT_REG_READ((SCS_0_HIGH_DECODE_ADDRESS + bank * 8), &value);
+	if (value == 0)
+		return 0;
+	else
+		return size;
+}
+
+/********************************************************************
+* getDeviceSize - Extract the size of a device memory space
+*
+* INPUT:    DEVICE device - Device number
+* OUTPUT:   N/A  
+* RETURNS:  Size of a device memory space.
+*********************************************************************/
+unsigned int getDeviceSize(DEVICE device)
+{
+	unsigned int size, base, value;
+	base = getDeviceBaseAddress(device);
+	GT_REG_READ((CS_0_HIGH_DECODE_ADDRESS + device * 8), &size);
+	size = ((size + 1) << 20) - (base & 0x0fffffff);
+	GT_REG_READ((CS_0_HIGH_DECODE_ADDRESS + device * 8), &value);
+	if ((value + 1) == 0)
+		return 0;
+	else
+		return size;
+}
+
+/********************************************************************
+* getDeviceWidth - A device can be with: 1,2,4 or 8 Bytes data width.
+*                  The width is determine in registers: 'Device Parameters'
+*                  registers (0x45c, 0x460, 0x464, 0x468, 0x46c - for each device.
+*                  at bits: [21:20].                  
+*
+* INPUT:    DEVICE device - Device number
+* OUTPUT:   N/A  
+* RETURNS:  Device width in Bytes (1,2,4, or 8), 0 if error had occurred.
+*********************************************************************/
+unsigned int getDeviceWidth(DEVICE device)
+{
+	unsigned int width;
+	unsigned int regValue;
+
+	GT_REG_READ(DEVICE_BANK0PARAMETERS + device * 4, &regValue);
+	width = (regValue & 0x00300000) >> 20;
+	switch (width) {
+	case 0:
+		return 1;
+	case 1:
+		return 2;
+	case 2:
+		return 4;
+	case 3:
+		return 8;
+	default:
+		return 0;
+	}
+}
+
+/********************************************************************
+* mapMemoryBanks0and1 - Sets new bases and boundaries for memory banks 0 and 1
+*                     - Pay attention to the PCI mappings and make sure to 
+*                       coordinate between the two interfaces!!!
+*                     - It is the programmer`s responsibility to make sure 
+*                       there are no conflicts with other memory spaces!!!
+*                     - If a bank needs to be closed , give it a 0 length
+*
+*
+* INPUTS: unsigned int bank0Base - required bank 0 base address.
+*         unsigned int bank0Length - required bank 0 size.
+*         unsigned int bank1Base - required bank 1 base address.
+*         unsigned int bank1Length - required bank 1 size.
+* RETURNS: true on success, false on failure or if one of the parameters is 
+*          erroneous.
+*********************************************************************/
+bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length,
+			 unsigned int bank1Base, unsigned int bank1Length)
+{
+	unsigned int mainBank0Top = bank0Base + bank0Length;
+	unsigned int mainBank1Top = bank1Base + bank1Length;
+	unsigned int memBank0Base, bank0Top;
+	unsigned int memBank1Base, bank1Top;
+
+	if (bank0Base <= bank1Base) {
+		if ((bank0Base + bank0Length) > bank1Base)
+			return false;
+	} else {
+		if ((bank1Base + bank1Length) > bank0Base)
+			return false;
+	}
+
+	if (bank0Length == 0)
+		mainBank0Top++;
+	if (bank1Length == 0)
+		mainBank1Top++;
+
+	memBank0Base = ((unsigned int) (bank0Base & 0x0fffffff)) >> 20;
+	bank0Top = ((unsigned int) (mainBank0Top & 0x0fffffff)) >> 20;
+	memBank1Base = ((unsigned int) (bank1Base & 0x0fffffff)) >> 20;
+	bank1Top = ((unsigned int) (mainBank1Top & 0x0fffffff)) >> 20;
+
+	if (mainBank1Top > mainBank0Top) {
+		bank0Base >>= 21;
+		mainBank0Top =
+		    ((unsigned int) (mainBank1Top & 0x0fffffff)) >> 21;
+	} else {
+		bank0Base = bank1Base >> 21;
+		mainBank0Top =
+		    ((unsigned int) (mainBank0Top & 0x0fffffff)) >> 21;
+	}
+	GT_REG_WRITE(SCS_1_0_LOW_DECODE_ADDRESS, bank0Base);
+	if ((bank0Length + bank1Length) != 0) {
+		GT_REG_WRITE(SCS_1_0_HIGH_DECODE_ADDRESS,
+			     mainBank0Top - 1);
+	} else {
+		GT_REG_WRITE(SCS_1_0_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	if (bank1Length != 0) {
+		GT_REG_WRITE(SCS_1_HIGH_DECODE_ADDRESS, bank1Top - 1);
+	} else {
+		GT_REG_WRITE(SCS_1_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(SCS_1_LOW_DECODE_ADDRESS, memBank1Base);
+	if (bank0Length != 0) {
+		GT_REG_WRITE(SCS_0_HIGH_DECODE_ADDRESS, bank0Top - 1);
+	} else {
+		GT_REG_WRITE(SCS_0_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(SCS_0_LOW_DECODE_ADDRESS, memBank0Base);
+	return true;
+}
+
+/********************************************************************
+* mapMemoryBanks2and3 - Sets new bases and boundaries for memory banks 2 and 3
+*                     - Pay attention to the PCI mappings and make sure to  
+*                       coordinate between the two interfaces!!!
+*                     - It`s the programmer`s responsibility to make sure there
+*                       are no conflicts with other memory spaces!!!
+*                     - If a bank needs to be closed , give it a 0 length.
+*
+*
+* INPUTS: unsigned int bank2Base - required bank 2 base address.
+*         unsigned int bank2Length - required bank 2 size.
+*         unsigned int bank3Base - required bank 3 base address.
+*         unsigned int bank3Length - required bank 3 size.
+* RETURNS: true on success, false on failure or if one of the parameters is 
+*          erroneous.
+*********************************************************************/
+bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length,
+			 unsigned int bank3Base, unsigned int bank3Length)
+{
+	unsigned int mainBank2Top =
+	    (unsigned int) (bank2Base + bank2Length);
+	unsigned int mainBank3Top =
+	    (unsigned int) (bank3Base + bank3Length);
+	unsigned int memBank2Base, bank2Top;
+	unsigned int memBank3Base, bank3Top;
+
+	if (bank2Base <= bank3Base) {
+		if ((bank2Base + bank2Length) > bank3Base)
+			return false;
+	} else {
+		if ((bank3Base + bank3Length) > bank2Base)
+			return false;
+	}
+	if (bank2Length == 0)
+		mainBank2Top++;
+	if (bank3Length == 0)
+		mainBank3Top++;
+
+	memBank2Base = ((unsigned int) (bank2Base & 0x0fffffff)) >> 20;
+	bank2Top = ((unsigned int) (mainBank2Top & 0x0fffffff)) >> 20;
+	memBank3Base = ((unsigned int) (bank3Base & 0x0fffffff)) >> 20;
+	bank3Top = ((unsigned int) (mainBank3Top & 0x0fffffff)) >> 20;
+
+	if (mainBank3Top > mainBank2Top) {
+		bank2Base >>= 21;
+		mainBank2Top =
+		    ((unsigned int) (mainBank3Top & 0x0fffffff)) >> 21;
+	} else {
+		bank2Base = bank3Base >> 21;
+		mainBank2Top =
+		    ((unsigned int) (mainBank2Top & 0x0fffffff)) >> 21;
+	}
+	GT_REG_WRITE(SCS_3_2_LOW_DECODE_ADDRESS, bank2Base);
+	if ((bank2Length + bank3Length) != 0) {
+		GT_REG_WRITE(SCS_3_2_HIGH_DECODE_ADDRESS,
+			     mainBank2Top - 1);
+	} else {
+		GT_REG_WRITE(SCS_3_2_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	if (bank3Length != 0) {
+		GT_REG_WRITE(SCS_3_HIGH_DECODE_ADDRESS, bank3Top - 1);
+	} else {
+		GT_REG_WRITE(SCS_3_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(SCS_3_LOW_DECODE_ADDRESS, memBank3Base);
+	if (bank2Length != 0) {
+		GT_REG_WRITE(SCS_2_HIGH_DECODE_ADDRESS, bank2Top - 1);
+	} else {
+		GT_REG_WRITE(SCS_2_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(SCS_2_LOW_DECODE_ADDRESS, memBank2Base);
+	return true;
+}
+
+/********************************************************************
+* mapDevices0_1and2MemorySpace - Sets new bases and boundaries for devices 0,1 
+*                                and 2
+*                     - Pay attention to the PCI mappings and make sure to 
+*                        coordinate between the two interfaces!!!
+*                     - It`s the programmer`s responsibility to make sure there
+*                       are no conflicts with other memory spaces!!!
+*                     - If a device needs to be closed , give it a 0 length
+*
+*
+* INPUTS: unsigned int device0Base - required cs_0 base address.
+*         unsigned int device0Length - required cs_0 size.
+*         unsigned int device1Base - required cs_1 base address. 
+*         unsigned int device1Length - required cs_0 size.       
+*         unsigned int device2Base - required cs_2 base address. 
+*         unsigned int device2Length - required cs_2 size.       
+* RETURNS: true on success, false on failure or if one of the parameters is 
+*          erroneous.
+*********************************************************************/
+bool mapDevices0_1and2MemorySpace(unsigned int device0Base,
+				  unsigned int device0Length,
+				  unsigned int device1Base,
+				  unsigned int device1Length,
+				  unsigned int device2Base,
+				  unsigned int device2Length)
+{
+	unsigned int deviceBank0Top =
+	    (unsigned int) (device0Base + device0Length);
+	unsigned int deviceBank1Top =
+	    (unsigned int) (device1Base + device1Length);
+	unsigned int deviceBank2Top =
+	    (unsigned int) (device2Base + device2Length);
+	unsigned int device0BaseTemp = 0, device0TopTemp = 0;
+	unsigned int bank0Base, bank0Top;
+	unsigned int bank1Base, bank1Top;
+	unsigned int bank2Base, bank2Top;
+	bank0Base = ((unsigned int) (device0Base & 0x0fffffff)) >> 20;
+	bank0Top = ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 20;
+	bank1Base = ((unsigned int) (device1Base & 0x0fffffff)) >> 20;
+	bank1Top = ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 20;
+	bank2Base = ((unsigned int) (device2Base & 0x0fffffff)) >> 20;
+	bank2Top = ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 20;
+
+	if (device0Length == 0)
+		deviceBank0Top++;
+	if (device1Length == 0)
+		deviceBank1Top++;
+	if (device2Length == 0)
+		deviceBank2Top++;
+
+	if (device0Base <= device1Base && device0Base <= device2Base) {
+		if ((device0Base + device0Length) > device1Base || \
+		    (device0Base + device0Length) > device2Base)
+			return false;
+		if (device1Base <= device2Base) {
+			if ((device1Base + device1Length) > device2Base)
+				return false;
+		} else {
+			if ((device2Base + device2Length) > device1Base)
+				return false;
+		}
+	}
+
+	if (device1Base <= device0Base && device1Base <= device2Base) {
+		if ((device1Base + device1Length) > device0Base ||
+		    (device1Base + device1Length) > device2Base)
+			return false;
+		if (device0Base <= device2Base) {
+			if ((device0Base + device0Length) > device2Base)
+				return false;
+		} else {
+			if ((device2Base + device2Length) > device0Base)
+				return false;
+		}
+	}
+
+	if (device2Base <= device1Base && device2Base <= device0Base) {
+		if ((device2Base + device2Length) > device1Base ||
+		    (device2Base + device2Length) > device0Base)
+			return false;
+		if (device0Base <= device1Base) {
+			if ((device0Base + device0Length) > device1Base)
+				return false;
+		} else {
+			if ((device1Base + device1Length) > device0Base)
+				return false;
+		}
+	}
+
+	if ((deviceBank2Top > deviceBank1Top) && (deviceBank1Top >
+						  deviceBank0Top)) {
+		device0BaseTemp = device0Base >> 21;
+		device0TopTemp =
+		    ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 21;
+	}
+	if ((deviceBank2Top > deviceBank0Top)
+	    && (deviceBank0Top > deviceBank1Top)) {
+		device0BaseTemp = device1Base >> 21;
+		device0TopTemp =
+		    ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 21;
+	}
+	if ((deviceBank1Top > deviceBank2Top)
+	    && (deviceBank2Top > deviceBank0Top)) {
+		device0BaseTemp = device0Base >> 21;
+		device0TopTemp =
+		    ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 21;
+	}
+	if ((deviceBank1Top > deviceBank0Top)
+	    && (deviceBank0Top > deviceBank2Top)) {
+		device0BaseTemp = device2Base >> 21;
+		device0TopTemp =
+		    ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 21;
+	}
+	if ((deviceBank0Top > deviceBank2Top)
+	    && (deviceBank2Top > deviceBank1Top)) {
+		device0BaseTemp = device1Base >> 21;
+		device0TopTemp =
+		    ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 21;
+	}
+	if ((deviceBank0Top > deviceBank1Top)
+	    && (deviceBank1Top > deviceBank2Top)) {
+		device0BaseTemp = device2Base >> 21;
+		device0TopTemp =
+		    ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 21;
+	}
+	GT_REG_WRITE(CS_2_0_LOW_DECODE_ADDRESS, device0BaseTemp);
+	if ((device0Length + device1Length + device2Length) != 0) {
+		GT_REG_WRITE(CS_2_0_HIGH_DECODE_ADDRESS,
+			     device0TopTemp - 1);
+	} else {
+		GT_REG_WRITE(CS_2_0_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(CS_0_LOW_DECODE_ADDRESS, bank0Base);
+	if (device0Length != 0) {
+		GT_REG_WRITE(CS_0_HIGH_DECODE_ADDRESS, bank0Top - 1);
+	} else {
+		GT_REG_WRITE(CS_0_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(CS_1_LOW_DECODE_ADDRESS, bank1Base);
+	if (device1Length != 0) {
+		GT_REG_WRITE(CS_1_HIGH_DECODE_ADDRESS, bank1Top - 1);
+	} else {
+		GT_REG_WRITE(CS_1_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(CS_2_LOW_DECODE_ADDRESS, bank2Base);
+	if (device2Length != 0) {
+		GT_REG_WRITE(CS_2_HIGH_DECODE_ADDRESS, bank2Top - 1);
+	} else {
+		GT_REG_WRITE(CS_2_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	return true;
+}
+
+/********************************************************************
+* mapDevices3andBootMemorySpace - Sets new bases and boundaries for devices: 
+*                                 3 and boot
+*                     - Pay attention to the PCI mappings and make sure to 
+*                       coordinate between the two interfaces!!!
+*                     - It is the programmer`s responsibility to make sure 
+*                       there are no conflicts with other memory spaces!!!
+*                     - If a device needs to be closed , give it a 0 length.
+*
+* INPUTS: base and length of device 3and boot
+* RETURNS: true on success, false on failure
+*********************************************************************/
+bool mapDevices3andBootMemorySpace(unsigned int device3Base,
+				   unsigned int device3Length,
+				   unsigned int bootDeviceBase,
+				   unsigned int bootDeviceLength)
+{
+	unsigned int deviceBank3Top =
+	    (unsigned int) (device3Base + device3Length);
+	unsigned int deviceBankBootTop =
+	    (unsigned int) (bootDeviceBase + bootDeviceLength);
+	unsigned int bank3Base, bank3Top;
+	unsigned int bank4Base, bank4Top;
+	unsigned int Device1Base, Device1Top;
+
+	bank3Top = ((unsigned int) (deviceBank3Top & 0x0fffffff)) >> 20;
+	bank4Top = ((unsigned int) (deviceBankBootTop & 0x0fffffff)) >> 20;
+	bank3Base = ((unsigned int) (device3Base & 0x0fffffff)) >> 20;
+	bank4Base = ((unsigned int) (bootDeviceBase & 0x0fffffff)) >> 20;
+
+	if (device3Base <= bootDeviceBase) {
+		if (deviceBank3Top > bootDeviceBase)
+			return false;
+	} else {
+		if (deviceBankBootTop > device3Base)
+			return false;
+	}
+
+	if (deviceBankBootTop > deviceBank3Top) {
+		Device1Base = device3Base >> 21;
+		Device1Top =
+		    ((unsigned int) (deviceBankBootTop & 0x0fffffff)) >>
+		    21;
+	} else {
+		Device1Base = bootDeviceBase >> 21;
+		Device1Top =
+		    ((unsigned int) (deviceBank3Top & 0x0fffffff)) >> 21;
+	}
+	GT_REG_WRITE(CS_3_BOOTCS_LOW_DECODE_ADDRESS, Device1Base);
+	if ((device3Length + bootDeviceLength) != 0) {
+		GT_REG_WRITE(CS_3_BOOTCS_HIGH_DECODE_ADDRESS,
+			     Device1Top - 1);
+	} else {
+		GT_REG_WRITE(CS_3_BOOTCS_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(CS_3_LOW_DECODE_ADDRESS, bank3Base);
+	if (device3Length != 0) {
+		GT_REG_WRITE(CS_3_HIGH_DECODE_ADDRESS, bank3Top - 1);
+	} else {
+		GT_REG_WRITE(CS_3_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	GT_REG_WRITE(BOOTCS_LOW_DECODE_ADDRESS, bank4Base);
+	if (bootDeviceLength != 0) {
+		GT_REG_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, bank4Top - 1);
+	} else {
+		GT_REG_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, 0x0);
+	}
+	return true;
+}
+
+/********************************************************************
+* modifyDeviceParameters - This function can be used to modify a device`s 
+*                          parameters.
+*                        - Be advised to check the spec before modifying them.
+* Inputs:
+* Returns: false if one of the parameters is erroneous,true otherwise.
+*********************************************************************/
+bool modifyDeviceParameters(DEVICE device, unsigned int turnOff,
+			    unsigned int accToFirst,
+			    unsigned int accToNext, unsigned int aleToWr,
+			    unsigned int wrActive, unsigned int wrHigh,
+			    unsigned int width, bool paritySupport)
+{
+	unsigned int data, oldValue;
+
+	if ((turnOff > 0x7 && turnOff != DONT_MODIFY)
+	    || (accToFirst > 0xf && accToFirst != DONT_MODIFY)
+	    || (accToNext > 0xf && accToNext != DONT_MODIFY)
+	    || (aleToWr > 0x7 && aleToWr != DONT_MODIFY)
+	    || (wrActive > 0x7 && wrActive != DONT_MODIFY)
+	    || (wrHigh > 0x7 && wrHigh != DONT_MODIFY)) {
+		return false;
+	}
+
+	GT_REG_READ((DEVICE_BANK0PARAMETERS + device * 4), &oldValue);
+	if (turnOff == DONT_MODIFY)
+		turnOff = oldValue & 0x00000007;
+	else
+		turnOff = turnOff;
+
+	if (accToFirst == DONT_MODIFY)
+		accToFirst = oldValue & 0x00000078;
+	else
+		accToFirst = accToFirst << 3;
+
+	if (accToNext == DONT_MODIFY)
+		accToNext = oldValue & 0x00000780;
+	else
+		accToNext = accToNext << 7;
+
+	if (aleToWr == DONT_MODIFY)
+		aleToWr = oldValue & 0x00003800;
+	else
+		aleToWr = aleToWr << 11;
+
+	if (wrActive == DONT_MODIFY)
+		wrActive = oldValue & 0x0001c000;
+	else
+		wrActive = wrActive << 14;
+
+	if (wrHigh == DONT_MODIFY)
+		wrHigh = oldValue & 0x000e0000;
+	else
+		wrHigh = wrHigh << 17;
+
+	data =
+	    turnOff | accToFirst | accToNext | aleToWr | wrActive | wrHigh;
+	switch (width) {
+	case _8BIT:
+		break;
+	case _16BIT:
+		data = data | _16BIT;
+		break;
+	case _32BIT:
+		data = data | _32BIT;
+		break;
+	case _64BIT:
+		data = data | _64BIT;
+		break;
+	default:
+		return false;
+	}
+	if (paritySupport == true)
+		data = data | PARITY_SUPPORT;
+	GT_REG_WRITE(DEVICE_BANK0PARAMETERS + device * 4, data);
+	return true;
+}
+
+/********************************************************************
+* remapAddress - This fubction used for address remapping 
+* Inputs:      - regOffset: remap register 
+*                remapHeader : remapped address
+* Returns: false if one of the parameters is erroneous,true otherwise.
+*********************************************************************/
+bool remapAddress(unsigned int remapReg, unsigned int remapValue)
+{
+	unsigned int valueForReg;
+	valueForReg = (remapValue & 0xffe00000) >> 21;
+	GT_REG_WRITE(remapReg, valueForReg);
+	return true;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/misc.c linux/arch/mips/galileo-boards/ev64120/compressed/misc.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/misc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/misc.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,313 @@
+/*
+ * arch/mips/galileo/misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ *
+ * Modified by RidgeRun Inc.
+ */
+
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+#define channel 1
+
+#undef memset
+#undef memcpy
+#define memzero(s, n)     memset ((s), 0, (n))
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+			     /* and a power of two */
+
+static uch *inbuf;		/* input buffer */
+static uch window[WSIZE];	/* Sliding window buffer */
+
+static unsigned insize = 0;	/* valid bytes in inbuf */
+static unsigned inptr = 0;	/* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0;	/* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01	/* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
+#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
+#define COMMENT      0x10	/* bit 4 set: file comment present */
+#define ENCRYPTED    0x20	/* bit 5 set: file is encrypted */
+#define RESERVED     0xC0	/* bit 6,7:   reserved */
+
+void variable_init();
+static void puts(const char *);
+
+void int2hex(int i)
+{
+	int tth, th, h, t, d;
+
+	if (i > 99999) {
+		serial_putc(channel, "Error - int2hex outofbounds");
+		return;
+	}
+
+	tth = (i) / 10000;
+	th = (i - (tth * 10000)) / 1000;
+	h = (i - ((tth * 10000) + (th * 1000))) / 100;
+	t = (i - ((tth * 10000) + (th * 1000) + (h * 100))) / 10;
+	d = (i - ((tth * 10000) + (th * 1000) + (h * 100) + (t * 10)));
+	serial_putc(channel, tth + '0');
+	serial_putc(channel, th + '0');
+	serial_putc(channel, h + '0');
+	serial_putc(channel, t + '0');
+	serial_putc(channel, d + '0');
+}
+
+int checksum;
+int byte_count;
+static unsigned char *input_data;
+
+static int printCnt = 0;
+
+int get_byte()
+{
+	unsigned char c = (inptr < insize ? inbuf[inptr++] : fill_inbuf());
+	byte_count++;
+	checksum += c;
+
+	// if (printCnt++ < 150)
+	// {
+	//   puts("\n");
+	//   puts("byte count = ");
+	//   int2hex(byte_count & 0xff);
+	//   puts(" byte val = ");
+	//   int2hex(c);
+	//   puts(" checksum = ");
+	//   int2hex(checksum & 0xff);
+	//   puts("\n");
+	// }
+	return c;
+}
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+/*
+ * This is set up by the setup-routine at boot-time
+ */
+
+
+#define STACK_SIZE (4096)
+long user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+extern int linux_compressed_start;
+extern int linux_compressed_size;
+extern int malloc_start;
+
+static int input_len;
+
+static long bytes_out = 0;
+extern int kernel_location_start;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#include "../../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size < 0)
+		error("Malloc error\n");
+	//      if (free_mem_ptr <= 0) error("Memory error\n");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *) free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= free_mem_end_ptr)
+		error("\nOut of memory\n");
+
+	return p;
+}
+
+static void free(void *where)
+{				/* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+
+static void puts(const char *s)
+{
+	while (*s) {
+		if (*s == 10)
+			serial_putc(channel, 13);
+		serial_putc(channel, *s++);
+	}
+}
+
+void *memset(void *s, int c, size_t n)
+{
+	int i;
+	char *ss = (char *) s;
+
+	for (i = 0; i < n; i++)
+		ss[i] = c;
+	return s;
+}
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+	int i;
+	char *d = (char *) __dest, *s = (char *) __src;
+
+	for (i = 0; i < __n; i++)
+		d[i] = s[i];
+	return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+	if (insize != 0) {
+		error("ran out of input data\n");
+	}
+
+	inbuf = input_data;
+	insize = input_len;
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+	ulg c = crc;		/* temporary variable */
+	unsigned n;
+	uch *in, *out, ch;
+
+	in = window;
+	out = &output_data[output_ptr];
+	for (n = 0; n < outcnt; n++) {
+		ch = *out++ = *in++;
+		c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += (ulg) outcnt;
+	output_ptr += (ulg) outcnt;
+	outcnt = 0;
+}
+
+check_mem()
+{
+	int i;
+
+	puts("\ncplens = ");
+	for (i = 0; i < 10; i++) {
+		int2hex(cplens[i]);
+		puts(" ");
+	}
+	puts("\ncplext = ");
+	for (i = 0; i < 10; i++) {
+		int2hex(cplext[i]);
+		puts(" ");
+	}
+	puts("\nborder = ");
+	for (i = 0; i < 10; i++) {
+		int2hex(border[i]);
+		puts(" ");
+	}
+	puts("\n");
+}
+
+static void error(char *x)
+{
+	check_mem();
+	puts("\n\n");
+	puts(x);
+	puts("byte_count = ");
+	int2hex(byte_count);
+	puts("\n");
+	puts("\n\n -- System halted");
+	while (1);		/* Halt */
+}
+
+void variable_init()
+{
+	byte_count = 0;
+	checksum = 0;
+	input_data = (unsigned char *) &linux_compressed_start;
+	input_len = linux_compressed_size;
+	output_data = &kernel_location_start;
+	free_mem_ptr = (long) &malloc_start;
+	free_mem_end_ptr = (long) ((char *) &malloc_start + 0x400000);
+}
+
+int decompress_kernel()
+{
+	//check_mem();
+
+	variable_init();
+
+	makecrc();
+	puts("Uncompressing Linux... \n");
+	gunzip();		// ...see inflate.c
+	puts("Ok, booting the kernel.\n");
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/ns16550.h linux/arch/mips/galileo-boards/ev64120/compressed/ns16550.h
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/ns16550.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/ns16550.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,126 @@
+/*  NS16550 UART registers  */
+
+#ifndef NS16550H
+#define NS16550H
+
+#define UART_BASE		0xbd000000
+#define NS16550_CHANA   PHYS_TO_K1(UART_BASE + 0x20)
+#define NS16550_CHANB   PHYS_TO_K1(UART_BASE)
+
+#ifndef NS16550_HZ
+#define NS16550_HZ      3686400
+#endif
+
+#ifdef __ASSEMBLY__
+
+#ifndef NSREG
+#define NSREG(x) ((x)*4)
+#endif
+
+#define DATA	NSREG(0)	/* data register (R/W) */
+#define IER	    NSREG(1)	/* interrupt enable (W) */
+#define IIR	    NSREG(2)	/* interrupt identification (R) */
+#define	FIFO	IIR		/* 16550 fifo control (W) */
+#define CFCR	NSREG(3)	/* line control register (R/W) */
+#define MCR	    NSREG(4)	/* modem control register (R/W) */
+#define LSR	    NSREG(5)	/* line status register (R/W) */
+#define MSR	    NSREG(6)	/* modem status register (R/W) */
+#define SCR	    NSREG(7)	/* scratch register (R/W) */
+
+#else
+
+#ifndef nsreg
+#if #endian(little)
+#define nsreg(x)	unsigned :24; unsigned char x;
+#else
+/*#define nsreg(x)	unsigned char x; unsigned :24;*/
+#define nsreg(x) unsigned int x:8;unsigned int :24;
+#endif
+#endif
+
+typedef struct {
+	nsreg(data);		/* data register (R/W) */
+	nsreg(ier);		/* interrupt enable (W) */
+	nsreg(iir);		/* interrupt identification (R) */
+#define	fifo	iir		/* 16550 fifo control (W) */
+	nsreg(cfcr);		/* line control register (R/W) */
+	nsreg(mcr);		/* modem control register (R/W) */
+	nsreg(lsr);		/* line status register (R/W) */
+	nsreg(msr);		/* modem status register (R/W) */
+	nsreg(scr);		/* scratch register (R/W) */
+} ns16550dev;
+#endif
+
+
+/* 16 bit baud rate divisor (lower byte in dca_data, upper in dca_ier) */
+#define BRTC(x)         (NS16550_HZ / (16*(x)))
+
+/* interrupt enable register */
+#define IER_ERXRDY      0x1	/* int on rx ready */
+#define IER_ETXRDY      0x2	/* int on tx ready */
+#define IER_ERLS        0x4	/* int on line status change */
+#define IER_EMSC        0x8	/* int on modem status change */
+
+/* interrupt identification register */
+#define IIR_IMASK       0xf	/* mask */
+#define IIR_RXTOUT      0xc	/* receive timeout */
+#define IIR_RLS         0x6	/* receive line status */
+#define IIR_RXRDY       0x4	/* receive ready */
+#define IIR_TXRDY       0x2	/* transmit ready */
+#define IIR_NOPEND      0x1	/* nothing */
+#define IIR_MLSC        0x0	/* modem status */
+#define IIR_FIFO_MASK   0xc0	/* set if FIFOs are enabled */
+
+/* fifo control register */
+#define FIFO_ENABLE     0x01	/* enable fifo */
+#define FIFO_RCV_RST    0x02	/* reset receive fifo */
+#define FIFO_XMT_RST    0x04	/* reset transmit fifo */
+#define FIFO_DMA_MODE   0x08	/* enable dma mode */
+#define FIFO_TRIGGER_1  0x00	/* trigger at 1 char */
+#define FIFO_TRIGGER_4  0x40	/* trigger at 4 chars */
+#define FIFO_TRIGGER_8  0x80	/* trigger at 8 chars */
+#define FIFO_TRIGGER_14 0xc0	/* trigger at 14 chars */
+
+/* character format control register */
+#define CFCR_DLAB       0x80	/* divisor latch */
+#define CFCR_SBREAK     0x40	/* send break */
+#define CFCR_PZERO      0x30	/* zero parity */
+#define CFCR_PONE       0x20	/* one parity */
+#define CFCR_PEVEN      0x10	/* even parity */
+#define CFCR_PODD       0x00	/* odd parity */
+#define CFCR_PENAB      0x08	/* parity enable */
+#define CFCR_STOPB      0x04	/* 2 stop bits */
+#define CFCR_8BITS      0x03	/* 8 data bits */
+#define CFCR_7BITS      0x02	/* 7 data bits */
+#define CFCR_6BITS      0x01	/* 6 data bits */
+#define CFCR_5BITS      0x00	/* 5 data bits */
+
+/* modem control register */
+#define MCR_LOOPBACK    0x10	/* loopback */
+#define MCR_IENABLE     0x08	/* output 2 = int enable */
+#define MCR_DRS         0x04	/* output 1 = xxx */
+#define MCR_RTS         0x02	/* enable RTS */
+#define MCR_DTR         0x01	/* enable DTR */
+
+/* line status register */
+#define LSR_RCV_FIFO    0x80	/* error in receive fifo */
+#define LSR_TSRE        0x40	/* transmitter empty */
+#define LSR_TXRDY       0x20	/* transmitter ready */
+#define LSR_BI          0x10	/* break detected */
+#define LSR_FE          0x08	/* framing error */
+#define LSR_PE          0x04	/* parity error */
+#define LSR_OE          0x02	/* overrun error */
+#define LSR_RXRDY       0x01	/* receiver ready */
+#define LSR_RCV_MASK    0x1f
+
+/* modem status register */
+#define MSR_DCD         0x80	/* DCD active */
+#define MSR_RI          0x40	/* RI  active */
+#define MSR_DSR         0x20	/* DSR active */
+#define MSR_CTS         0x10	/* CTS active */
+#define MSR_DDCD        0x08	/* DCD changed */
+#define MSR_TERI        0x04	/* RI  changed */
+#define MSR_DDSR        0x02	/* DSR changed */
+#define MSR_DCTS        0x01	/* CTS changed */
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/osdep.h linux/arch/mips/galileo-boards/ev64120/compressed/osdep.h
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/osdep.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/osdep.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,36 @@
+#ifndef	__OSDEP_H__
+#define __OSDEP_H__
+
+/*
+ * 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, or (at
+ * your option) any later version.
+ */
+
+#if	defined(__linux__) || defined(__FreeBSD__) || defined (__MIPSEB__)
+#define	ETHERBOOT32
+#define ntohl(x) (x)
+#define htonl(x) (x)
+#define ntohs(x) (x)
+#define htons(x) (x)
+
+#endif
+
+
+
+
+/* ANSI prototyping macro */
+#ifdef	__STDC__
+#define	P(x)	x
+#else
+#define	P(x)	()
+#endif
+
+#endif
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/pci.c linux/arch/mips/galileo-boards/ev64120/compressed/pci.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/pci.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,1336 @@
+/* PCI.c - PCI functions */
+
+/* Copyright - Galileo technology. */
+
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/core.h>
+#include <asm/galileo-boards/evb64120A/pci.h>
+#ifndef PROM
+#include <linux/kernel.h>
+#endif
+
+#undef PCI_DEBUG
+
+#ifdef PCI_DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#else
+#include "core.h"
+#include "pci.h"
+#include <string.h>
+#endif
+
+/********************************************************************
+* pci0ScanDevices   - This function scan PCI0 bus, if found any device on
+*                     this bus it interrogate the Device for the information 
+*                     it can discover.
+*                     The fields with all information are the following: 
+*    char            type[20];
+*    unsigned int    deviceNum;
+*    unsigned int    venID;                                            
+*    unsigned int    deviceID;
+*    unsigned int    bar0Base;
+*    unsigned int    bar0Size;
+*    unsigned int    bar1Base;
+*    unsigned int    bar1Size;
+*    unsigned int    bar2Base;
+*    unsigned int    bar2Size;
+*    unsigned int    bar3Base;
+*    unsigned int    bar3Size;
+*    unsigned int    bar4Base;
+*    unsigned int    bar4Size;
+*    unsigned int    bar5Base;
+*    unsigned int    bar5Size;
+* 
+* Inputs:   PCI0_DEVICE* pci0Detect - Pointer to an array of STRUCT PCI0_DEVICE.
+*           unsigned int numberOfElment - The PCI0_DEVICE Array length.
+* Output:   None.
+*********************************************************************/
+
+void pci0ScanDevices(PCI_DEVICE * pci0Detect, unsigned int numberOfElment)
+{
+	PCI_DEVICE *pci0ArrayPointer = pci0Detect;
+	unsigned int id;	/* PCI Configuration register 0x0. */
+	unsigned int device;	/* device`s Counter. */
+	unsigned int classCode;	/* PCI Configuration register 0x8 */
+	unsigned int arrayCounter = 0;
+	unsigned int memBaseAddress;
+	unsigned int memSize;
+	unsigned int c18RegValue;
+
+	PCI0_MASTER_ENABLE(SELF);
+	/* According to PCI REV 2.1 MAX agents on the bus are -21- */
+	for (device = 6; device < 8; device++) {
+		id = pci0ReadConfigReg(PCI_0DEVICE_AND_VENDOR_ID, device);
+		GT_REG_READ(INTERRUPT_CAUSE_REGISTER, &c18RegValue);
+		/* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */
+		GT_REG_WRITE(INTERRUPT_CAUSE_REGISTER,
+			     c18RegValue & 0xfffbffff);
+		if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) {
+			classCode =
+			    pci0ReadConfigReg
+			    (PCI_0CLASS_CODE_AND_REVISION_ID, device);
+			pci0ArrayPointer->deviceNum = device;
+			pci0ArrayPointer->venID = (id & 0xffff);
+			pci0ArrayPointer->deviceID =
+			    ((id & 0xffff0000) >> 16);
+			DBG("\nrr: venID %x devID %x\n",
+			    pci0ArrayPointer->venID,
+			    pci0ArrayPointer->deviceID);
+			DBG("rr: device found %x\n",
+			    pci0ArrayPointer->deviceNum);
+			/* BAR0 parameters */
+			memBaseAddress = pci0ReadConfigReg(BAR0, device);
+			pci0ArrayPointer->bar0Type = memBaseAddress & 1;
+			pci0ArrayPointer->bar0Base =
+			    memBaseAddress & 0xfffff000;
+			pci0WriteConfigReg(BAR0, device, 0xffffffff);
+			memSize = pci0ReadConfigReg(BAR0, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci0ArrayPointer->bar0Size = 0;
+			} else {
+				if (pci0ArrayPointer->bar0Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci0ArrayPointer->bar0Size = memSize;
+			}
+			DBG("rr: device BAR0 size %x\n", memSize);
+			DBG("rr: device BAR0 address %x\n",
+			    memBaseAddress);
+			pci0WriteConfigReg(BAR0, device, memBaseAddress);
+			/* BAR1 parameters */
+			memBaseAddress = pci0ReadConfigReg(BAR1, device);
+			pci0ArrayPointer->bar1Type = memBaseAddress & 1;
+			pci0ArrayPointer->bar1Base =
+			    memBaseAddress & 0xfffff000;
+			pci0WriteConfigReg(BAR1, device, 0xffffffff);
+			memSize = pci0ReadConfigReg(BAR1, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci0ArrayPointer->bar1Size = 0;
+			} else {
+				if (pci0ArrayPointer->bar1Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci0ArrayPointer->bar1Size = memSize;
+			}
+			DBG("rr: device BAR1 size %x\n", memSize);
+			DBG("rr: device BAR1 address %x\n",
+			    memBaseAddress);
+			pci0WriteConfigReg(BAR1, device, memBaseAddress);
+			/* BAR2 parameters */
+			memBaseAddress = pci0ReadConfigReg(BAR2, device);
+			pci0ArrayPointer->bar2Type = memBaseAddress & 1;
+			pci0ArrayPointer->bar2Base =
+			    memBaseAddress & 0xfffff000;
+			pci0WriteConfigReg(BAR2, device, 0xffffffff);
+			memSize = pci0ReadConfigReg(BAR2, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci0ArrayPointer->bar2Size = 0;
+			} else {
+				if (pci0ArrayPointer->bar2Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci0ArrayPointer->bar2Size = memSize;
+			}
+			DBG("rr: device BAR2 size %x\n", memSize);
+			DBG("rr: device BAR2 address %x\n",
+			    memBaseAddress);
+			pci0WriteConfigReg(BAR2, device, memBaseAddress);
+			/* BAR3 parameters */
+			memBaseAddress = pci0ReadConfigReg(BAR3, device);
+			pci0ArrayPointer->bar3Type = memBaseAddress & 1;
+			pci0ArrayPointer->bar3Base =
+			    memBaseAddress & 0xfffff000;
+			pci0WriteConfigReg(BAR3, device, 0xffffffff);
+			memSize = pci0ReadConfigReg(BAR3, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci0ArrayPointer->bar3Size = 0;
+			} else {
+				if (pci0ArrayPointer->bar3Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci0ArrayPointer->bar3Size = memSize;
+			}
+			DBG("rr: device BAR3 size %x\n", memSize);
+			DBG("rr: device BAR3 address %x\n",
+			    memBaseAddress);
+			pci0WriteConfigReg(BAR3, device, memBaseAddress);
+			/* BAR4 parameters */
+			memBaseAddress = pci0ReadConfigReg(BAR4, device);
+			pci0ArrayPointer->bar4Type = memBaseAddress & 1;
+			pci0ArrayPointer->bar4Base =
+			    memBaseAddress & 0xfffff000;
+			pci0WriteConfigReg(BAR4, device, 0xffffffff);
+			memSize = pci0ReadConfigReg(BAR4, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci0ArrayPointer->bar4Size = 0;
+			} else {
+				if (pci0ArrayPointer->bar4Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci0ArrayPointer->bar4Size = memSize;
+			}
+			DBG("rr: device BAR4 size %x\n", memSize);
+			DBG("rr: device BAR4 address %x\n",
+			    memBaseAddress);
+			pci0WriteConfigReg(BAR4, device, memBaseAddress);
+			/* BAR5 parameters */
+			memBaseAddress = pci0ReadConfigReg(BAR5, device);
+			pci0ArrayPointer->bar5Type = memBaseAddress & 1;
+			pci0ArrayPointer->bar5Base =
+			    memBaseAddress & 0xfffff000;
+			pci0WriteConfigReg(BAR5, device, 0xffffffff);
+			memSize = pci0ReadConfigReg(BAR5, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci0ArrayPointer->bar5Size = 0;
+			} else {
+				if (pci0ArrayPointer->bar5Type == 1)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci0ArrayPointer->bar5Size = memSize;
+			}
+			DBG("rr: device BAR5 size %x\n", memSize);
+			DBG("rr: device BAR5 address %x\n",
+			    memBaseAddress);
+			pci0WriteConfigReg(BAR5, device, memBaseAddress);
+			/* End of BARs Detection. */
+
+			classCode = ((classCode & 0xff000000) >> 24);
+			switch (classCode) {
+			case 0x0:
+				strcpy(pci0ArrayPointer->type,
+				       "Old generation device");
+				break;
+			case 0x1:
+				strcpy(pci0ArrayPointer->type,
+				       "Mass storage controller");
+				break;
+			case 0x2:
+				strcpy(pci0ArrayPointer->type,
+				       "Network controller");
+				break;
+			case 0x3:
+				strcpy(pci0ArrayPointer->type,
+				       "Display controller");
+				break;
+			case 0x4:
+				strcpy(pci0ArrayPointer->type,
+				       "Multimedia device");
+				break;
+			case 0x5:
+				strcpy(pci0ArrayPointer->type,
+				       "Memory controller");
+				break;
+			case 0x6:
+				strcpy(pci0ArrayPointer->type,
+				       "Bridge Device");
+				break;
+			case 0x7:
+				strcpy(pci0ArrayPointer->type,
+				       "Simple Communication controllers");
+				break;
+			case 0x8:
+				strcpy(pci0ArrayPointer->type,
+				       "Base system peripherals");
+				break;
+			case 0x9:
+				strcpy(pci0ArrayPointer->type,
+				       "Input Devices");
+				break;
+			case 0xa:
+				strcpy(pci0ArrayPointer->type,
+				       "Docking stations");
+				break;
+			case 0xb:
+				strcpy(pci0ArrayPointer->type,
+				       "Processors");
+				break;
+			case 0xc:
+				strcpy(pci0ArrayPointer->type,
+				       "Serial bus controllers");
+				break;
+			case 0xd:
+				strcpy(pci0ArrayPointer->type,
+				       "Wireless controllers");
+				break;
+			case 0xe:
+				strcpy(pci0ArrayPointer->type,
+				       "Intelligent I/O controllers");
+				break;
+			case 0xf:
+				strcpy(pci0ArrayPointer->type,
+				       "Satellite communication controllers");
+				break;
+			case 0x10:
+				strcpy(pci0ArrayPointer->type,
+				       "Encryption/Decryption controllers");
+				break;
+			case 0x11:
+				strcpy(pci0ArrayPointer->type,
+				       "Data acquisition and signal processing controllers");
+				break;
+			default:
+				break;
+
+			}
+			arrayCounter++;	/* point to the next element in the Array. */
+			if (arrayCounter == numberOfElment)
+				return;	/* When the Array is fully used, return. */
+			/* Else, points to next free Element. */
+			pci0ArrayPointer = &pci0Detect[arrayCounter];
+		}
+	}
+	pci0ArrayPointer->deviceNum = 0;	/* 0 => End of List */
+}
+
+
+/********************************************************************
+* pci1ScanDevices   - This function scan PCI1 bus, if found any device on
+*                     this bus it interrogate the Device for the information 
+*                     it can discover.
+*                     The fields with all information are the following: 
+*    char            type[20];
+*    unsigned int    deviceNum;
+*    unsigned int    venID;                                            
+*    unsigned int    deviceID;
+*    unsigned int    bar0Base;
+*    unsigned int    bar0Size;
+*    unsigned int    bar1Base;
+*    unsigned int    bar1Size;
+*    unsigned int    bar2Base;
+*    unsigned int    bar2Size;
+*    unsigned int    bar3Base;
+*    unsigned int    bar3Size;
+*    unsigned int    bar4Base;
+*    unsigned int    bar4Size;
+*    unsigned int    bar5Base;
+*    unsigned int    bar5Size;
+* 
+* Inputs:   Pointer to an array of STRUCT PCI1_DEVICE. 
+* Output:   None.
+*********************************************************************/
+
+void pci1ScanDevices(PCI_DEVICE * pci1Detect, unsigned int numberOfElment)
+{
+	PCI_DEVICE *pci1ArrayPointer = pci1Detect;
+	unsigned int id;	/* PCI Configuration register 0x0. */
+	unsigned int device;	/* device`s Counter. */
+	unsigned int classCode;	/* PCI Configuration register 0x8 */
+	unsigned int arrayCounter = 0;
+	unsigned int memBaseAddress;
+	unsigned int memSize;
+	unsigned int c98RegValue;
+
+	PCI1_MASTER_ENABLE(SELF);
+	/* According to PCI REV 2.1 MAX agents on the bus are -21- */
+	for (device = 1; device < 22; device++) {
+		id = pci1ReadConfigReg(PCI_0DEVICE_AND_VENDOR_ID, device);
+		GT_REG_READ(HIGH_INTERRUPT_CAUSE_REGISTER, &c98RegValue);
+		/* Clearing bit 18 of in the High Cause Register 0xc98 */
+		GT_REG_WRITE(HIGH_INTERRUPT_CAUSE_REGISTER,
+			     c98RegValue & 0xfffbffff);
+		if ((id != 0xffffffff) && !(c98RegValue & 0x40000)) {
+			classCode =
+			    pci1ReadConfigReg
+			    (PCI_0CLASS_CODE_AND_REVISION_ID, device);
+			pci1ArrayPointer->deviceNum = device;
+			pci1ArrayPointer->venID = (id & 0xffff);
+			pci1ArrayPointer->deviceID =
+			    ((id & 0xffff0000) >> 16);
+
+			/* BAR0 parameters */
+			memBaseAddress = pci1ReadConfigReg(BAR0, device);
+			pci1ArrayPointer->bar0Type = memBaseAddress & 1;
+			pci1ArrayPointer->bar0Base =
+			    memBaseAddress & 0xfffff000;
+			pci1WriteConfigReg(BAR0, device, 0xffffffff);
+			memSize = pci1ReadConfigReg(BAR0, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci1ArrayPointer->bar0Size = 0;
+			} else {
+				if (pci1ArrayPointer->bar0Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci1ArrayPointer->bar0Size = memSize;
+			}
+			pci1WriteConfigReg(BAR0, device, memBaseAddress);
+			/* BAR1 parameters */
+			memBaseAddress = pci1ReadConfigReg(BAR1, device);
+			pci1ArrayPointer->bar1Type = memBaseAddress & 1;
+			pci1ArrayPointer->bar1Base =
+			    memBaseAddress & 0xfffff000;
+			pci1WriteConfigReg(BAR1, device, 0xffffffff);
+			memSize = pci1ReadConfigReg(BAR1, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci1ArrayPointer->bar1Size = 0;
+			} else {
+				if (pci1ArrayPointer->bar1Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci1ArrayPointer->bar1Size = memSize;
+			}
+			pci1WriteConfigReg(BAR1, device, memBaseAddress);
+			/* BAR2 parameters */
+			memBaseAddress = pci1ReadConfigReg(BAR2, device);
+			pci1ArrayPointer->bar2Type = memBaseAddress & 1;
+			pci1ArrayPointer->bar2Base =
+			    memBaseAddress & 0xfffff000;
+			pci1WriteConfigReg(BAR2, device, 0xffffffff);
+			memSize = pci1ReadConfigReg(BAR2, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci1ArrayPointer->bar2Size = 0;
+			} else {
+				if (pci1ArrayPointer->bar2Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci1ArrayPointer->bar2Size = memSize;
+			}
+			pci1WriteConfigReg(BAR2, device, memBaseAddress);
+			/* BAR3 parameters */
+			memBaseAddress = pci1ReadConfigReg(BAR3, device);
+			pci1ArrayPointer->bar3Type = memBaseAddress & 1;
+			pci1ArrayPointer->bar3Base =
+			    memBaseAddress & 0xfffff000;
+			pci1WriteConfigReg(BAR3, device, 0xffffffff);
+			memSize = pci1ReadConfigReg(BAR3, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci1ArrayPointer->bar3Size = 0;
+			} else {
+				if (pci1ArrayPointer->bar3Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci1ArrayPointer->bar3Size = memSize;
+			}
+			pci1WriteConfigReg(BAR3, device, memBaseAddress);
+			/* BAR4 parameters */
+			memBaseAddress = pci1ReadConfigReg(BAR4, device);
+			pci1ArrayPointer->bar4Type = memBaseAddress & 1;
+			pci1ArrayPointer->bar4Base =
+			    memBaseAddress & 0xfffff000;
+			pci1WriteConfigReg(BAR4, device, 0xffffffff);
+			memSize = pci1ReadConfigReg(BAR4, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci1ArrayPointer->bar4Size = 0;
+			} else {
+				if (pci1ArrayPointer->bar4Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci1ArrayPointer->bar4Size = memSize;
+			}
+			pci1WriteConfigReg(BAR4, device, memBaseAddress);
+			/* BAR5 parameters */
+			memBaseAddress = pci1ReadConfigReg(BAR5, device);
+			pci1ArrayPointer->bar5Type = memBaseAddress & 1;
+			pci1ArrayPointer->bar5Base =
+			    memBaseAddress & 0xfffff000;
+			pci1WriteConfigReg(BAR5, device, 0xffffffff);
+			memSize = pci1ReadConfigReg(BAR5, device);
+			if (memSize == 0) {	/* case of an empty BAR */
+				pci1ArrayPointer->bar5Size = 0;
+			} else {
+				if (pci1ArrayPointer->bar5Type == 0)	/* memory space */
+					memSize =
+					    ~(memSize & 0xfffffff0) + 1;
+				else	/* IO space */
+					memSize =
+					    ~(memSize & 0xfffffffc) + 1;
+				pci1ArrayPointer->bar5Size = memSize;
+			}
+			pci1WriteConfigReg(BAR5, device, memBaseAddress);
+			/* End of BARs Detection. */
+
+			classCode = ((classCode & 0xff000000) >> 24);
+			switch (classCode) {
+			case 0x0:
+				strcpy(pci1ArrayPointer->type,
+				       "Old generation device");
+				break;
+			case 0x1:
+				strcpy(pci1ArrayPointer->type,
+				       "Mass storage controller");
+				break;
+			case 0x2:
+				strcpy(pci1ArrayPointer->type,
+				       "Network controller");
+				break;
+			case 0x3:
+				strcpy(pci1ArrayPointer->type,
+				       "Display controller");
+				break;
+			case 0x4:
+				strcpy(pci1ArrayPointer->type,
+				       "Multimedia device");
+				break;
+			case 0x5:
+				strcpy(pci1ArrayPointer->type,
+				       "Memory controller");
+				break;
+			case 0x6:
+				strcpy(pci1ArrayPointer->type,
+				       "Bridge Device");
+				break;
+			case 0x7:
+				strcpy(pci1ArrayPointer->type,
+				       "Simple Communication controllers");
+				break;
+			case 0x8:
+				strcpy(pci1ArrayPointer->type,
+				       "Base system peripherals");
+				break;
+			case 0x9:
+				strcpy(pci1ArrayPointer->type,
+				       "Input Devices");
+				break;
+			case 0xa:
+				strcpy(pci1ArrayPointer->type,
+				       "Docking stations");
+				break;
+			case 0xb:
+				strcpy(pci1ArrayPointer->type,
+				       "Processors");
+				break;
+			case 0xc:
+				strcpy(pci1ArrayPointer->type,
+				       "Serial bus controllers");
+				break;
+			case 0xd:
+				strcpy(pci1ArrayPointer->type,
+				       "Wireless controllers");
+				break;
+			case 0xe:
+				strcpy(pci1ArrayPointer->type,
+				       "Intelligent I/O controllers");
+				break;
+			case 0xf:
+				strcpy(pci1ArrayPointer->type,
+				       "Satellite communication controllers");
+				break;
+			case 0x10:
+				strcpy(pci1ArrayPointer->type,
+				       "Encryption/Decryption controllers");
+				break;
+			case 0x11:
+				strcpy(pci1ArrayPointer->type,
+				       "Data acquisition and signal processing controllers");
+				break;
+			}
+			arrayCounter++;	/* point to the next element in the Array. */
+			if (arrayCounter == numberOfElment)
+				return;	/* When the Array is fully used, return. */
+			/* Else, points to next free Element. */
+			pci1ArrayPointer = &pci1Detect[arrayCounter];
+		}
+	}
+	pci1ArrayPointer->deviceNum = 0;	/* 0 => End of List */
+}
+
+/********************************************************************
+* pci0WriteConfigReg - Write to a PCI configuration register
+*                    - Make sure the GT is configured as a master before 
+*                      writingto another device on the PCI.
+*                    - The function takes care of Big/Little endian conversion.
+* Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec 
+*                   (or any other PCI device spec)
+*           pciDevNum: The device number needs to be addressed.                
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|00|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+
+void pci0WriteConfigReg(unsigned int regOffset, unsigned int pciDevNum,
+			unsigned int data)
+{
+	unsigned int DataForRegCf8;
+	unsigned int functionNum;
+
+	functionNum = regOffset & 0x00000700;
+	pciDevNum = pciDevNum << 11;
+	regOffset = regOffset & 0x0fffffff;
+	DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31;
+	GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8);
+	if (pciDevNum == SELF) {	/* This board */
+		GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+			     data);
+	} else {		/* configuration Transaction over the pci. */
+
+		/* The PCI is working in LE Mode So it swap the Data. */
+		GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+			     WORDSWAP(data));
+	}
+}
+
+/********************************************************************
+* pci1WriteConfigReg - Write to a PCI configuration register
+*                   - Make sure the GT is configured as a master before writing
+*                     to another device on the PCI.
+*                   - The function takes care of Big/Little endian conversion.
+* Inputs:   unsigned int regOffset: The register offset as it apears in the  
+*           GT spec (or any other PCI device spec)
+*           pciDevNum: The device number needs to be addressed.                
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|00|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+
+void pci1WriteConfigReg(unsigned int regOffset, unsigned int pciDevNum,
+			unsigned int data)
+{
+	unsigned int DataForRegCf8;
+	unsigned int functionNum;
+
+	functionNum = regOffset & 0x00000700;
+	pciDevNum = pciDevNum << 11;
+	regOffset = regOffset & 0x0fffffff;
+	if (pciDevNum == SELF) {	/* This board */
+		/* when configurating our own PCI 1 L-unit the access is through  
+		   the PCI 0 interface with reg number = reg number + 0x80 */
+		DataForRegCf8 =
+		    (regOffset | pciDevNum | functionNum | 0x80) | BIT31;
+		GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8);
+	} else {
+		DataForRegCf8 =
+		    (regOffset | pciDevNum | functionNum) | BIT31;
+		GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS, DataForRegCf8);
+	}
+	if (pciDevNum == SELF) {	/* This board */
+		GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+			     data);
+	} else {
+		GT_REG_WRITE(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,
+			     WORDSWAP(data));
+	}
+}
+
+/********************************************************************
+* pci0ReadConfigReg  - Read from a PCI0 configuration register
+*                    - Make sure the GT is configured as a master before 
+*                      reading from another device on the PCI.
+*                   - The function takes care of Big/Little endian conversion.
+* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+*                        spec)
+*           pciDevNum: The device number needs to be addressed.                
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
+*                 cause register to make sure the data is valid
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|00|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+
+unsigned int pci0ReadConfigReg(unsigned int regOffset,
+			       unsigned int pciDevNum)
+{
+	unsigned int DataForRegCf8;
+	unsigned int data;
+	unsigned int functionNum;
+
+	functionNum = regOffset & 0x00000700;
+	pciDevNum = pciDevNum << 11;
+	regOffset = regOffset & 0x0fffffff;
+	DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31;
+	GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8);
+	if (pciDevNum == SELF) {	/* This board */
+		GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+			    &data);
+		return data;
+	} else {		/* The PCI is working in LE Mode So it swap the Data. */
+
+		GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+			    &data);
+		return WORDSWAP(data);
+	}
+}
+
+/********************************************************************
+* pci1ReadConfigReg  - Read from a PCI1 configuration register
+*                    - Make sure the GT is configured as a master before 
+*                      reading from another device on the PCI.
+*                   - The function takes care of Big/Little endian conversion.
+* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+*                        spec)
+*           pciDevNum: The device number needs to be addressed.                
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
+*                 cause register to make sure the data is valid
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|00|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+
+unsigned int pci1ReadConfigReg(unsigned int regOffset,
+			       unsigned int pciDevNum)
+{
+	unsigned int DataForRegCf8;
+	unsigned int data;
+	unsigned int functionNum;
+
+	functionNum = regOffset & 0x00000700;
+	pciDevNum = pciDevNum << 11;
+	regOffset = regOffset & 0x0fffffff;
+	if (pciDevNum == SELF) {	/* This board */
+		/* when configurating our own PCI 1 L-unit the access is through  
+		   the PCI 0 interface with reg number = reg number + 0x80 */
+		DataForRegCf8 =
+		    (regOffset | pciDevNum | functionNum | 0x80) | BIT31;
+		GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8);
+	} else {
+		DataForRegCf8 =
+		    (regOffset | pciDevNum | functionNum) | BIT31;
+		GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS, DataForRegCf8);
+	}
+	if (pciDevNum == SELF) {	/* This board */
+		GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+			    &data);
+		return data;
+	} else {
+		GT_REG_READ(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,
+			    &data);
+		return WORDSWAP(data);
+	}
+}
+
+/********************************************************************
+* pci0MapIOspace - Maps PCI0 IO space for the master.
+* Inputs: base and length of pci0Io
+*********************************************************************/
+
+void pci0MapIOspace(unsigned int pci0IoBase, unsigned int pci0IoLength)
+{
+	unsigned int pci0IoTop =
+	    (unsigned int) (pci0IoBase + pci0IoLength);
+
+	if (pci0IoLength == 0)
+		pci0IoTop++;
+
+	pci0IoBase = (unsigned int) (pci0IoBase >> 21);
+	pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21);
+	GT_REG_WRITE(PCI_0I_O_LOW_DECODE_ADDRESS, pci0IoBase);
+	GT_REG_WRITE(PCI_0I_O_HIGH_DECODE_ADDRESS, pci0IoTop);
+}
+
+/********************************************************************
+* pci1MapIOspace - Maps PCI1 IO space for the master.
+* Inputs: base and length of pci1Io
+*********************************************************************/
+
+void pci1MapIOspace(unsigned int pci1IoBase, unsigned int pci1IoLength)
+{
+	unsigned int pci1IoTop =
+	    (unsigned int) (pci1IoBase + pci1IoLength);
+
+	if (pci1IoLength == 0)
+		pci1IoTop++;
+
+	pci1IoBase = (unsigned int) (pci1IoBase >> 21);
+	pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21);
+	GT_REG_WRITE(PCI_1I_O_LOW_DECODE_ADDRESS, pci1IoBase);
+	GT_REG_WRITE(PCI_1I_O_HIGH_DECODE_ADDRESS, pci1IoTop);
+}
+
+/********************************************************************
+* pci0MapMemory0space - Maps PCI0 memory0 space for the master.
+* Inputs: base and length of pci0Mem0
+*********************************************************************/
+
+
+void pci0MapMemory0space(unsigned int pci0Mem0Base,
+			 unsigned int pci0Mem0Length)
+{
+	unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length;
+
+	if (pci0Mem0Length == 0)
+		pci0Mem0Top++;
+
+	pci0Mem0Base = pci0Mem0Base >> 21;
+	pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21;
+	GT_REG_WRITE(PCI_0MEMORY0_LOW_DECODE_ADDRESS, pci0Mem0Base);
+	GT_REG_WRITE(PCI_0MEMORY0_HIGH_DECODE_ADDRESS, pci0Mem0Top);
+}
+
+/********************************************************************
+* pci1MapMemory0space - Maps PCI1 memory0 space for the master.
+* Inputs: base and length of pci1Mem0
+*********************************************************************/
+
+void pci1MapMemory0space(unsigned int pci1Mem0Base,
+			 unsigned int pci1Mem0Length)
+{
+	unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length;
+
+	if (pci1Mem0Length == 0)
+		pci1Mem0Top++;
+
+	pci1Mem0Base = pci1Mem0Base >> 21;
+	pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21;
+	GT_REG_WRITE(PCI_1MEMORY0_LOW_DECODE_ADDRESS, pci1Mem0Base);
+	GT_REG_WRITE(PCI_1MEMORY0_HIGH_DECODE_ADDRESS, pci1Mem0Top);
+}
+
+/********************************************************************
+* pci0MapMemory1space - Maps PCI0 memory1 space for the master.
+* Inputs: base and length of pci0Mem1
+*********************************************************************/
+
+void pci0MapMemory1space(unsigned int pci0Mem1Base,
+			 unsigned int pci0Mem1Length)
+{
+	unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length;
+
+	if (pci0Mem1Length == 0)
+		pci0Mem1Top++;
+
+	pci0Mem1Base = pci0Mem1Base >> 21;
+	pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21;
+	GT_REG_WRITE(PCI_0MEMORY1_LOW_DECODE_ADDRESS, pci0Mem1Base);
+	GT_REG_WRITE(PCI_0MEMORY1_HIGH_DECODE_ADDRESS, pci0Mem1Top);
+#ifndef PROM
+	DBG(KERN_INFO "pci0Mem1Base %x\n", pci0Mem1Base);
+	DBG(KERN_INFO "pci0Mem1Top %x\n", pci0Mem1Top);
+	GT_REG_READ(PCI_0MEMORY0_ADDRESS_REMAP, &pci0Mem1Base);
+	DBG(KERN_INFO "Mem 0/0 remap %x\n", pci0Mem1Base);
+	GT_REG_READ(PCI_0MEMORY1_ADDRESS_REMAP, &pci0Mem1Base);
+	DBG(KERN_INFO "Mem 0/1 remap %x\n", pci0Mem1Base);
+	GT_REG_WRITE(PCI_0MEMORY1_ADDRESS_REMAP, 0x500);
+	GT_REG_READ(PCI_0MEMORY1_ADDRESS_REMAP, &pci0Mem1Base);
+	DBG(KERN_INFO "Mem 0/1 remapped %x\n", pci0Mem1Base);
+#endif
+}
+
+/********************************************************************
+* pci1MapMemory1space - Maps PCI1 memory1 space for the master.
+* Inputs: base and length of pci1Mem1
+*********************************************************************/
+
+void pci1MapMemory1space(unsigned int pci1Mem1Base,
+			 unsigned int pci1Mem1Length)
+{
+	unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length;
+
+	if (pci1Mem1Length == 0)
+		pci1Mem1Top++;
+
+	pci1Mem1Base = pci1Mem1Base >> 21;
+	pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21;
+	GT_REG_WRITE(PCI_1MEMORY1_LOW_DECODE_ADDRESS, pci1Mem1Base);
+	GT_REG_WRITE(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, pci1Mem1Top);
+}
+
+/********************************************************************
+* pci0GetIOspaceBase - Return PCI0 IO Base Address.
+* Inputs: N/A
+* Returns: PCI0 IO Base Address.
+*********************************************************************/
+
+unsigned int pci0GetIOspaceBase()
+{
+	unsigned int base;
+	GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	return base;
+}
+
+/********************************************************************
+* pci0GetIOspaceSize - Return PCI0 IO Bar Size.
+* Inputs: N/A
+* Returns: PCI0 IO Bar Size.
+*********************************************************************/
+
+unsigned int pci0GetIOspaceSize()
+{
+	unsigned int top, base, size;
+	GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	GT_REG_READ(PCI_0I_O_HIGH_DECODE_ADDRESS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/********************************************************************
+* pci0GetMemory0Base - Return PCI0 Memory 0 Base Address.
+* Inputs: N/A
+* Returns: PCI0 Memory 0 Base Address.
+*********************************************************************/
+
+unsigned int pci0GetMemory0Base()
+{
+	unsigned int base;
+	GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	return base;
+}
+
+/********************************************************************
+* pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size.
+* Inputs: N/A
+* Returns: PCI0 Memory 0 Bar Size.
+*********************************************************************/
+
+unsigned int pci0GetMemory0Size()
+{
+	unsigned int top, base, size;
+	GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	GT_REG_READ(PCI_0MEMORY0_HIGH_DECODE_ADDRESS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/********************************************************************
+* pci0GetMemory1Base - Return PCI0 Memory 1 Base Address.
+* Inputs: N/A
+* Returns: PCI0 Memory 1 Base Address.
+*********************************************************************/
+
+unsigned int pci0GetMemory1Base()
+{
+	unsigned int base;
+	GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	return base;
+}
+
+/********************************************************************
+* pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size.
+* Inputs: N/A
+* Returns: PCI0 Memory 1 Bar Size.
+*********************************************************************/
+
+unsigned int pci0GetMemory1Size()
+{
+	unsigned int top, base, size;
+	GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	GT_REG_READ(PCI_0MEMORY1_HIGH_DECODE_ADDRESS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/********************************************************************
+* pci1GetIOspaceBase - Return PCI1 IO Base Address.
+* Inputs: N/A
+* Returns: PCI1 IO Base Address.
+*********************************************************************/
+
+unsigned int pci1GetIOspaceBase()
+{
+	unsigned int base;
+	GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	return base;
+}
+
+/********************************************************************
+* pci1GetIOspaceSize - Return PCI1 IO Bar Size.
+* Inputs: N/A
+* Returns: PCI1 IO Bar Size.
+*********************************************************************/
+
+unsigned int pci1GetIOspaceSize()
+{
+	unsigned int top, base, size;
+	GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	GT_REG_READ(PCI_1I_O_HIGH_DECODE_ADDRESS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/********************************************************************
+* pci1GetMemory0Base - Return PCI1 Memory 0 Base Address.
+* Inputs: N/A
+* Returns: PCI1 Memory 0 Base Address.
+*********************************************************************/
+
+unsigned int pci1GetMemory0Base()
+{
+	unsigned int base;
+	GT_REG_READ(PCI_1MEMORY0_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	return base;
+}
+
+/********************************************************************
+* pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size.
+* Inputs: N/A
+* Returns: PCI1 Memory 0 Bar Size.
+*********************************************************************/
+
+unsigned int pci1GetMemory0Size()
+{
+	unsigned int top, base, size;
+	GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/********************************************************************
+* pci1GetMemory1Base - Return PCI1 Memory 1 Base Address.
+* Inputs: N/A
+* Returns: PCI1 Memory 1 Base Address.
+*********************************************************************/
+
+unsigned int pci1GetMemory1Base()
+{
+	unsigned int base;
+	GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	return base;
+}
+
+/********************************************************************
+* pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size.
+* Inputs: N/A
+* Returns: PCI1 Memory 1 Bar Size.
+*********************************************************************/
+
+unsigned int pci1GetMemory1Size()
+{
+	unsigned int top, base, size;
+	GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base);
+	base = base << 21;
+	GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/********************************************************************
+* pci0MapInternalRegSpace - Maps the internal registers memory space for the 
+*                           slave.
+*                           Stays the same for all GT devices Disco include
+* Inputs: base of pci0 internal register
+*********************************************************************/
+
+void pci0MapInternalRegSpace(unsigned int pci0InternalBase)
+{
+	pci0InternalBase = pci0InternalBase & 0xfffff000;
+	pci0InternalBase =
+	    pci0InternalBase |
+	    (pci0ReadConfigReg
+	     (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,
+	      SELF) & 0x00000fff);
+	pci0WriteConfigReg
+	    (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, SELF,
+	     pci0InternalBase);
+}
+
+/********************************************************************
+* pci1MapInternalRegSpace - Maps the internal registers memory space for the 
+*                           slave.
+*                           Stays the same for all GT devices Disco include
+* Inputs: base of pci1 internal register
+*********************************************************************/
+
+void pci1MapInternalRegSpace(unsigned int pci1InternalBase)
+{
+	pci1InternalBase = pci1InternalBase & 0xfffff000;
+	pci1InternalBase =
+	    pci1InternalBase |
+	    (pci1ReadConfigReg
+	     (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,
+	      SELF) & 0x00000fff);
+	pci1WriteConfigReg
+	    (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, SELF,
+	     pci1InternalBase);
+}
+
+/********************************************************************
+* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the 
+*                             slave.
+*                             Stays the same for all GT devices Disco include
+* Inputs: base of pci0 internal io register
+*********************************************************************/
+
+void pci0MapInternalRegIOSpace(unsigned int pci0InternalBase)
+{
+	pci0InternalBase = pci0InternalBase & 0xfffff000;
+	pci0InternalBase =
+	    pci0InternalBase |
+	    (pci0ReadConfigReg
+	     (PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,
+	      0) & 0x00000fff);
+	pci0WriteConfigReg(PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,
+			   SELF, pci0InternalBase);
+}
+
+/********************************************************************
+* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the 
+*                             slave.
+*                             Stays the same for all GT devices Disco include
+* Inputs: base of pci1 internal io register
+*********************************************************************/
+
+void pci1MapInternalRegIOSpace(unsigned int pci1InternalBase)
+{
+	pci1InternalBase = pci1InternalBase & 0xfffff000;
+	pci1InternalBase =
+	    pci1InternalBase |
+	    (pci1ReadConfigReg
+	     (PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,
+	      SELF) & 0x00000fff);
+	pci1WriteConfigReg(PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,
+			   SELF, pci1InternalBase);
+}
+
+/********************************************************************
+* pci0MapMemoryBanks0_1 - Maps PCI0 memory banks 0 and 1 for the slave.
+*                         for Discovery we need two function: SCS0 & SCS1 
+*                         (instead of SCS[1:0])
+* Inputs: base and size of pci0 dram
+*********************************************************************/
+
+
+void pci0MapMemoryBanks0_1(unsigned int pci0Dram0_1Base,
+			   unsigned int pci0Dram0_1Size)
+{
+	pci0Dram0_1Base = pci0Dram0_1Base & 0xfffff000;
+	pci0Dram0_1Base =
+	    pci0Dram0_1Base |
+	    (pci0ReadConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF) &
+	     0x00000fff);
+	pci0WriteConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF,
+			   pci0Dram0_1Base);
+	/* swapped Bar */
+	pci0WriteConfigReg(PCI_0SWAPPED_SCS_1_0_BASE_ADDRESS, SELF,
+			   pci0Dram0_1Base);
+	if (pci0Dram0_1Size == 0)
+		pci0Dram0_1Size++;
+	GT_REG_WRITE(PCI_0SCS_1_0_BANK_SIZE, pci0Dram0_1Size - 1);
+}
+
+/********************************************************************
+* pci1MapMemoryBanks0_1 - Maps PCI1 memory banks 0 and 1 for the slave.
+*                         for Discovery we need two function: SCS0 & SCS1 
+*                         (instead of SCS[1:0])
+* Inputs: base and size of pci1 dram
+*********************************************************************/
+
+void pci1MapMemoryBanks0_1(unsigned int pci1Dram0_1Base,
+			   unsigned int pci1Dram0_1Size)
+{
+	pci1Dram0_1Base = pci1Dram0_1Base & 0xfffff000;
+	pci1Dram0_1Base =
+	    pci1Dram0_1Base |
+	    (pci1ReadConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF) &
+	     0x00000fff);
+	pci1WriteConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF,
+			   pci1Dram0_1Base);
+	/* swapped Bar */
+	pci1WriteConfigReg(PCI_0SWAPPED_SCS_1_0_BASE_ADDRESS, SELF,
+			   pci1Dram0_1Base);
+	if (pci1Dram0_1Size == 0)
+		pci1Dram0_1Size++;
+	GT_REG_WRITE(PCI_1SCS_1_0_BANK_SIZE, pci1Dram0_1Size - 1);
+}
+
+/********************************************************************
+* pci0MapMemoryBanks2_3 - Maps PCI0 memory banks 2 and 3 for the slave.
+*                         for Discovery we need two function: SCS2 & SCS3 
+*                         (instead of SCS[3:2])
+* Inputs: base and size of pci0 dram
+*********************************************************************/
+
+void pci0MapMemoryBanks2_3(unsigned int pci0Dram2_3Base,
+			   unsigned int pci0Dram2_3Size)
+{
+	pci0Dram2_3Base = pci0Dram2_3Base & 0xfffff000;
+	pci0Dram2_3Base =
+	    pci0Dram2_3Base |
+	    (pci0ReadConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF) &
+	     0x00000fff);
+	pci0WriteConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF,
+			   pci0Dram2_3Base);
+	/* swapped Bar */
+	pci0WriteConfigReg(PCI_0SWAPPED_SCS_3_2_BASE_ADDRESS, SELF,
+			   pci0Dram2_3Base);
+	if (pci0Dram2_3Size == 0)
+		pci0Dram2_3Size++;
+	GT_REG_WRITE(PCI_0SCS_3_2_BANK_SIZE, pci0Dram2_3Size - 1);
+}
+
+/********************************************************************
+* pci1MapMemoryBanks2_3 - Maps PCI1 memory banks 2 and 3 for the slave.
+*                         for Discovery we need two function: SCS2 & SCS3 
+*                         (instead of SCS[3:2])
+* Inputs: base and size of pci1 dram
+*********************************************************************/
+
+void pci1MapMemoryBanks2_3(unsigned int pci1Dram2_3Base,
+			   unsigned int pci1Dram2_3Size)
+{
+	pci1Dram2_3Base = pci1Dram2_3Base & 0xfffff000;
+	pci1Dram2_3Base =
+	    pci1Dram2_3Base |
+	    (pci1ReadConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF) &
+	     0x00000fff);
+	pci1WriteConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF,
+			   pci1Dram2_3Base);
+	/* swapped Bar */
+	pci1WriteConfigReg(PCI_0SWAPPED_SCS_3_2_BASE_ADDRESS, SELF,
+			   pci1Dram2_3Base);
+	if (pci1Dram2_3Size == 0)
+		pci1Dram2_3Size++;
+	GT_REG_WRITE(PCI_1SCS_3_2_BANK_SIZE, pci1Dram2_3Size - 1);
+}
+
+/********************************************************************
+* pci0MapDevices0_1and2MemorySpace - Maps PCI0 devices 0,1 and 2 memory spaces 
+*                                    for the slave.
+*                                    For the Discovery there are 3 separate
+*                                    fucnction's
+* Inputs: base and lengthof pci0 devises012
+*********************************************************************/
+
+
+void pci0MapDevices0_1and2MemorySpace(unsigned int pci0Dev012Base,
+				      unsigned int pci0Dev012Length)
+{
+	pci0Dev012Base = pci0Dev012Base & 0xfffff000;
+	pci0Dev012Base =
+	    pci0Dev012Base |
+	    (pci0ReadConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF) &
+	     0x00000fff);
+	pci0WriteConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF, pci0Dev012Base);
+	if (pci0Dev012Length == 0)
+		pci0Dev012Length++;
+	GT_REG_WRITE(PCI_0CS_2_0_BANK_SIZE, pci0Dev012Length - 1);
+}
+
+/********************************************************************
+* pci1MapDevices0_1and2MemorySpace - Maps PCI1 devices 0,1 and 2 memory spaces 
+*                                    for the slave.
+*                                    For the Discovery there are 3 separate
+*                                    fucnction's
+* Inputs: base and lengthof pci1 devises012
+*********************************************************************/
+
+void pci1MapDevices0_1and2MemorySpace(unsigned int pci1Dev012Base,
+				      unsigned int pci1Dev012Length)
+{
+	pci1Dev012Base = pci1Dev012Base & 0xfffff000;
+	pci1Dev012Base =
+	    pci1Dev012Base |
+	    (pci1ReadConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF) &
+	     0x00000fff);
+	pci1WriteConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF, pci1Dev012Base);
+	if (pci1Dev012Length == 0)
+		pci1Dev012Length++;
+	GT_REG_WRITE(PCI_1CS_2_0_BANK_SIZE, pci1Dev012Length - 1);
+}
+
+/********************************************************************
+* pci0MapDevices3andBootMemorySpace - Maps PCI0 devices 3 and boot memory 
+*                                     spaces for the slave.
+*                                     For the Discovery there are 2 separate 
+*                                     fucnction's
+* Inputs: base and length of pci0 device3/ boot
+*********************************************************************/
+
+void pci0MapDevices3andBootMemorySpace(unsigned int pci0Dev3andBootBase,
+				       unsigned int pci0Dev3andBootLength)
+{
+	pci0Dev3andBootBase = pci0Dev3andBootBase & 0xfffff000;
+	pci0Dev3andBootBase =
+	    pci0Dev3andBootBase |
+	    (pci0ReadConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF) &
+	     0x00000fff);
+	pci0WriteConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF,
+			   pci0Dev3andBootBase);
+	/* swapped Bar */
+	pci0WriteConfigReg(PCI_0SWAPPED_CS_3_BOOTCS_BASE_ADDRESS, SELF,
+			   pci0Dev3andBootBase);
+	if (pci0Dev3andBootLength == 0)
+		pci0Dev3andBootLength++;
+	GT_REG_WRITE(PCI_0CS_3_BOOTCS_BANK_SIZE,
+		     pci0Dev3andBootLength - 1);
+}
+
+/********************************************************************
+* pci1MapDevices3andBootMemorySpace - Maps PCI1 devices 3 and boot memory 
+*                                     spaces for the slave.
+*                                     For the Discovery there are 2 separate 
+*                                     fucnction's
+* Inputs: base and length of pci1 device3/ boot
+*********************************************************************/
+
+void pci1MapDevices3andBootMemorySpace(unsigned int pci1Dev3andBootBase,
+				       unsigned int pci1Dev3andBootLength)
+{
+	pci1Dev3andBootBase = pci1Dev3andBootBase & 0xfffff000;
+	pci1Dev3andBootBase =
+	    pci1Dev3andBootBase |
+	    (pci1ReadConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF) &
+	     0x00000fff);
+	pci1WriteConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF,
+			   pci1Dev3andBootBase);
+	/* swapped Bar */
+	pci1WriteConfigReg(PCI_0SWAPPED_CS_3_BOOTCS_BASE_ADDRESS, SELF,
+			   pci1Dev3andBootBase);
+	if (pci1Dev3andBootLength == 0)
+		pci1Dev3andBootLength++;
+	GT_REG_WRITE(PCI_1CS_3_BOOTCS_BANK_SIZE,
+		     pci1Dev3andBootLength - 1);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c linux/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,318 @@
+/*
+ * 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, or (at
+ * your option) any later version.
+ */
+#include <linux/config.h>
+#include <asm/galileo-boards/evb64120A/pci.h>
+#include <asm/byteorder.h>
+
+#include "etherboot.h"
+#include "pci_etherboot.h"
+#include "galileo_port.h"
+
+#define MAX_PCI_DEVS 10
+PCI_DEVICE pci0_devices[MAX_PCI_DEVS];
+PCI_DEVICE pci1_devices[MAX_PCI_DEVS];
+
+static int pci_range_ck(unsigned char bus, unsigned char dev)
+{
+	if ((bus == 0) && (dev >= 0) && (dev < 30))
+		return 0;	// Bus/Device Number OK
+
+	return -1;		// Bus/Device Number not OK  
+}
+
+/********************************************************************
+ * pcibios_(read/write)_config_(byte/word/dword)
+ *
+ *Inputs :
+ *bus - bus number
+ *dev - device number
+ *offset - register offset in the configuration space
+ *val - value to be written / read
+ *
+ *Outputs :
+ *Sucees/Failure
+ *********************************************************************/
+#define PCI_CFG_DATA    ((volatile unsigned long *)0xb4000cfc)
+#define PCI_CFG_CTRL    ((volatile unsigned long *)0xb4000cf8)
+
+#define PCI_CFG_SET(dev,fun,off) \
+        ((*PCI_CFG_CTRL) = cpu_to_le32((0x80000000 | ((dev)<<11) | ((fun)<<8) | (off))))
+
+int pcibios_read_config_dword(unsigned char bus, unsigned char dev,
+			      unsigned char offset, unsigned int *val)
+{
+
+	if (offset & 0x3) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xFFFFFFFF;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	PCI_CFG_SET(dev, 0, offset);
+	if (dev != 0) {
+		*val = *PCI_CFG_DATA;
+	} else {
+		*val = cpu_to_le32(*PCI_CFG_DATA);
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_read_config_word(unsigned char bus, unsigned char dev,
+			     unsigned char offset, unsigned short *val)
+{
+	if (offset & 0x1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	PCI_CFG_SET(dev, 0, (offset & ~0x3));
+	if (dev != 0) {
+		*val = *PCI_CFG_DATA >> ((offset & 3) * 8);
+	} else {
+		*val = cpu_to_le32(*PCI_CFG_DATA) >> ((offset & 3) * 8);
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_read_config_byte(unsigned char bus, unsigned char dev,
+			     unsigned char offset, unsigned char *val)
+{
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	PCI_CFG_SET(dev, 0, (offset & ~0x3));
+	if (dev != 0) {
+		*val = *PCI_CFG_DATA >> ((offset & 3) * 8);
+	} else {
+		*val = cpu_to_le32(*PCI_CFG_DATA >> ((offset & 3) * 8));
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_dword(unsigned char bus, unsigned char dev,
+			       unsigned char offset, unsigned int val)
+{
+	if (offset & 0x3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	PCI_CFG_SET(dev, 0, offset);
+	if (dev != 0) {
+		*PCI_CFG_DATA = val;
+	} else {
+		*PCI_CFG_DATA = cpu_to_le32(val);
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_word(unsigned char bus, unsigned char dev,
+			      unsigned char offset, unsigned short val)
+{
+	unsigned long tmp;
+
+	if (offset & 0x1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	PCI_CFG_SET(dev, 0, (offset & ~0x3));
+	if (dev != 0) {
+		tmp = *PCI_CFG_DATA;
+	} else {
+		tmp = cpu_to_le32(*PCI_CFG_DATA);
+	}
+	tmp &= ~(0xffff << ((offset & 0x3) * 8));
+	tmp |= (val << ((offset & 0x3) * 8));
+	if (dev != 0) {
+		*PCI_CFG_DATA = tmp;
+	} else {
+		*PCI_CFG_DATA = cpu_to_le32(tmp);
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_byte(unsigned char bus, unsigned char dev,
+			      unsigned char offset, unsigned char val)
+{
+	unsigned long tmp;
+
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	PCI_CFG_SET(dev, 0, (offset & ~0x3));
+	if (dev != 0) {
+		tmp = *PCI_CFG_DATA;
+	} else {
+		tmp = cpu_to_le32(*PCI_CFG_DATA);
+	}
+	tmp &= ~(0xff << ((offset & 0x3) * 8));
+	tmp |= (val << ((offset & 0x3) * 8));
+	*PCI_CFG_DATA = cpu_to_le32(tmp);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+/********************************************************************
+ * eth_pci_init - Fill pci_devi
+ *
+ *Inputs :
+ *bus - bus number
+ *dev - device number
+ *offset - register offset in the configuration space
+ *val - value to be written / read
+ *
+ *Outputs :
+ *Sucees/Failure
+ *********************************************************************/
+void eth_pci_init(struct pci_device *pcidev)
+{
+	int i, count;
+	pcibios_write_config_word(0, 0, 4, 0x7);
+	pcibios_write_config_dword(0, 8, BAR0, 0x12000000);
+	pcibios_write_config_dword(0, 8, BAR1, 0x10000001);
+	pcibios_write_config_dword(0, 8, BAR2, 0x12100000);
+	strcpy(pci0_devices[0].type, "Network Controller");
+	pci0_devices[0].deviceNum = 8;
+	pci0_devices[0].venID = 0x8086;
+	pci0_devices[0].deviceID = 0x1229;
+
+	pci0_devices[0].bar0Base = 0x12000000;
+	pci0_devices[0].bar0Size = 0x00001000;
+	pci0_devices[0].bar0Type = 0;
+	pci0_devices[0].bar1Base = 0x10000000;
+	pci0_devices[0].bar1Size = 0x40;
+	pci0_devices[0].bar1Type = 1;
+	pci0_devices[0].bar2Base = 0x12100000;
+	pci0_devices[0].bar2Size = 0x00100000;
+	pci0_devices[0].bar2Type = 0;
+	for (i = 0; pcidev[i].vendor != 0; i++) {
+		/* Look for device in PCI0 first */
+		for (count = 0; count < MAX_PCI_DEVS; count++) {
+			if ((pci0_devices[count].type[0] != 0)
+			    && ((unsigned short) pci0_devices[count].
+				venID == (unsigned short) pcidev[i].vendor)
+			    && ((unsigned short) pci0_devices[count].
+				deviceID ==
+				(unsigned short) pcidev[i].dev_id)) {
+				if ((pci0_devices[count].bar0Type == 1)
+				    && (pci0_devices[count].bar0Size != 0))
+					pcidev[i].ioaddr =
+					    pci0_devices[count].bar0Base;
+				if ((pci0_devices[count].bar1Type == 1)
+				    && (pci0_devices[count].bar1Size != 0))
+					pcidev[i].ioaddr =
+					    pci0_devices[count].bar1Base;
+				if ((pci0_devices[count].bar2Type == 1)
+				    && (pci0_devices[count].bar2Size != 0))
+					pcidev[i].ioaddr =
+					    pci0_devices[count].bar2Base;
+				if ((pci0_devices[count].bar3Type == 1)
+				    && (pci0_devices[count].bar3Size != 0))
+					pcidev[i].ioaddr =
+					    pci0_devices[count].bar3Base;
+				if ((pci0_devices[count].bar4Type == 1)
+				    && (pci0_devices[count].bar4Size != 0))
+					pcidev[i].ioaddr =
+					    pci0_devices[count].bar4Base;
+				if ((pci0_devices[count].bar5Type == 1)
+				    && (pci0_devices[count].bar5Size != 0))
+					pcidev[i].ioaddr =
+					    pci0_devices[count].bar5Base;
+
+				if ((pci0_devices[count].bar0Type == 0)
+				    && (pci0_devices[count].bar0Size != 0))
+					pcidev[i].membase =
+					    pci0_devices[count].bar0Base;
+				if ((pci0_devices[count].bar1Type == 0)
+				    && (pci0_devices[count].bar1Size != 0))
+					pcidev[i].membase =
+					    pci0_devices[count].bar1Base;
+				if ((pci0_devices[count].bar2Type == 0)
+				    && (pci0_devices[count].bar2Size != 0))
+					pcidev[i].membase =
+					    pci0_devices[count].bar2Base;
+				if ((pci0_devices[count].bar3Type == 0)
+				    && (pci0_devices[count].bar3Size != 0))
+					pcidev[i].membase =
+					    pci0_devices[count].bar3Base;
+				if ((pci0_devices[count].bar4Type == 0)
+				    && (pci0_devices[count].bar4Size != 0))
+					pcidev[i].membase =
+					    pci0_devices[count].bar4Base;
+				if ((pci0_devices[count].bar5Type == 0)
+				    && (pci0_devices[count].bar5Size != 0))
+					pcidev[i].membase =
+					    pci0_devices[count].bar5Base;
+				pcidev[i].bus = 0;
+				pcidev[i].devfn =
+				    pci0_devices[count].deviceNum;
+			}
+#ifdef CONFIG_EVB_PCI1
+			if ((pci1_devices[count].type[0] != 0)
+			    && (pci1_devices[count].venID ==
+				pcidev[i].vendor)
+			    && (pci1_devices[count].deviceID ==
+				pcidev[i].dev_id)) {
+				if ((pci1_devices[count].bar0Type == 1)
+				    && (pci1_devices[count].bar0Size != 0))
+					pcidev[i].ioaddr =
+					    pci1_devices[count].bar0Base;
+				if ((pci1_devices[count].bar1Type == 1)
+				    && (pci1_devices[count].bar1Size != 0))
+					pcidev[i].ioaddr =
+					    pci1_devices[count].bar1Base;
+				if ((pci1_devices[count].bar2Type == 1)
+				    && (pci1_devices[count].bar2Size != 0))
+					pcidev[i].ioaddr =
+					    pci1_devices[count].bar2Base;
+				if ((pci1_devices[count].bar3Type == 1)
+				    && (pci1_devices[count].bar3Size != 0))
+					pcidev[i].ioaddr =
+					    pci1_devices[count].bar3Base;
+				if ((pci1_devices[count].bar4Type == 1)
+				    && (pci1_devices[count].bar4Size != 0))
+					pcidev[i].ioaddr =
+					    pci1_devices[count].bar4Base;
+				if ((pci1_devices[count].bar5Type == 1)
+				    && (pci1_devices[count].bar5Size != 0))
+					pcidev[i].ioaddr =
+					    pci1_devices[count].bar5Base;
+
+				if ((pci1_devices[count].bar0Type == 0)
+				    && (pci1_devices[count].bar0Size != 0))
+					pcidev[i].membase =
+					    pci1_devices[count].bar0Base;
+				if ((pci1_devices[count].bar1Type == 0)
+				    && (pci1_devices[count].bar1Size != 0))
+					pcidev[i].membase =
+					    pci1_devices[count].bar1Base;
+				if ((pci1_devices[count].bar2Type == 0)
+				    && (pci1_devices[count].bar2Size != 0))
+					pcidev[i].membase =
+					    pci1_devices[count].bar2Base;
+				if ((pci1_devices[count].bar3Type == 0)
+				    && (pci1_devices[count].bar3Size != 0))
+					pcidev[i].membase =
+					    pci1_devices[count].bar3Base;
+				if ((pci1_devices[count].bar4Type == 0)
+				    && (pci1_devices[count].bar4Size != 0))
+					pcidev[i].membase =
+					    pci1_devices[count].bar4Base;
+				if ((pci1_devices[count].bar5Type == 0)
+				    && (pci1_devices[count].bar5Size != 0))
+					pcidev[i].membase =
+					    pci1_devices[count].bar5Base;
+
+				pcidev[i].bus = 1;
+				pcidev[i].devfn =
+				    pci1_devices[count].deviceNum;
+			}
+#endif
+		}
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h linux/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,144 @@
+#ifndef	PCI_H
+#define PCI_H
+
+/*
+** Support for NE2000 PCI clones added David Monro June 1997
+** Generalised for other PCI NICs by Ken Yap July 1997
+**
+** Most of this is taken from:
+**
+** /usr/src/linux/drivers/pci/pci.c
+** /usr/src/linux/include/linux/pci.h
+** /usr/src/linux/arch/i386/bios32.c
+** /usr/src/linux/include/linux/bios32.h
+** /usr/src/linux/drivers/net/ne.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, or (at
+ * your option) any later version.
+ */
+
+#define PCI_COMMAND_IO			0x1	/* Enable response in I/O space */
+#define PCI_COMMAND_MASTER		0x4	/* Enable bus mastering */
+#define PCI_LATENCY_TIMER		0x0d	/* 8 bits */
+
+
+#define PCI_VENDOR_ID           0x00	/* 16 bits */
+#define PCI_DEVICE_ID           0x02	/* 16 bits */
+#define PCI_COMMAND             0x04	/* 16 bits */
+
+#define PCI_CLASS_CODE          0x0b	/* 8 bits */
+#define PCI_SUBCLASS_CODE       0x0a	/* 8 bits */
+#define PCI_HEADER_TYPE         0x0e	/* 8 bits */
+
+#define PCI_BASE_ADDRESS_0      0x10	/* 32 bits */
+#define PCI_BASE_ADDRESS_1      0x14	/* 32 bits */
+#define PCI_BASE_ADDRESS_2      0x18	/* 32 bits */
+#define PCI_BASE_ADDRESS_3      0x1c	/* 32 bits */
+#define PCI_BASE_ADDRESS_4      0x20	/* 32 bits */
+#define PCI_BASE_ADDRESS_5      0x24	/* 32 bits */
+
+#ifndef	PCI_BASE_ADDRESS_IO_MASK
+#define	PCI_BASE_ADDRESS_IO_MASK       (~0x03)
+#endif
+#define	PCI_BASE_ADDRESS_SPACE_IO	0x01
+#define	PCI_ROM_ADDRESS		0x30	/* 32 bits */
+#define	PCI_ROM_ADDRESS_ENABLE	0x01	/* Write 1 to enable ROM,
+					   bits 31..11 are address,
+					   10..2 are reserved */
+
+#define PCI_FUNC(devfn)           ((devfn) & 0x07)
+
+#define BIOS32_SIGNATURE        (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
+
+/* PCI signature: "PCI " */
+#define PCI_SIGNATURE           (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
+
+/* PCI service signature: "$PCI" */
+#define PCI_SERVICE             (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
+
+#define KERN_CODE_SEG	0x8	/* This _MUST_ match start.S */
+
+#define PCI_VENDOR_ID_REALTEK           0x10ec
+#define PCI_DEVICE_ID_REALTEK_8029      0x8029
+#define PCI_DEVICE_ID_REALTEK_8139      0x8139
+#define PCI_VENDOR_ID_WINBOND2          0x1050
+#define PCI_DEVICE_ID_WINBOND2_89C940   0x0940
+#define PCI_VENDOR_ID_COMPEX            0x11f6
+#define PCI_DEVICE_ID_COMPEX_RL2000     0x1401
+#define PCI_VENDOR_ID_KTI               0x8e2e
+#define PCI_DEVICE_ID_KTI_ET32P2        0x3000
+#define PCI_VENDOR_ID_NETVIN            0x4a14
+#define PCI_DEVICE_ID_NETVIN_NV5000SC   0x5000
+#define PCI_VENDOR_ID_3COM		0x10b7
+#define PCI_DEVICE_ID_3COM_3C900TPO	0x9000
+#define PCI_DEVICE_ID_3COM_3C900COMBO	0x9001
+#define PCI_DEVICE_ID_3COM_3C905TX	0x9050
+#define PCI_DEVICE_ID_3COM_3C905T4	0x9051
+#define PCI_DEVICE_ID_3COM_3C905B_TX	0x9055
+#define PCI_DEVICE_ID_3COM_3C905C_TXM	0x9200
+#define PCI_VENDOR_ID_INTEL		0x8086
+#define PCI_DEVICE_ID_INTEL_82557	0x1229
+#define PCI_VENDOR_ID_AMD		0x1022
+#define PCI_DEVICE_ID_AMD_LANCE		0x2000
+#define PCI_VENDOR_ID_SMC_1211          0x1113
+#define PCI_DEVICE_ID_SMC_1211          0x1211
+#define PCI_VENDOR_ID_DEC		0x1011
+#define PCI_DEVICE_ID_DEC_TULIP		0x0002
+#define PCI_DEVICE_ID_DEC_TULIP_FAST	0x0009
+#define PCI_DEVICE_ID_DEC_TULIP_PLUS	0x0014
+#define PCI_DEVICE_ID_DEC_21142		0x0019
+#define PCI_VENDOR_ID_SMC		0x10B8
+#ifndef	PCI_DEVICE_ID_SMC_EPIC100
+# define PCI_DEVICE_ID_SMC_EPIC100	0x0005
+#endif
+#define PCI_VENDOR_ID_MACRONIX		0x10d9
+#define PCI_DEVICE_ID_MX987x5		0x0531
+#define PCI_VENDOR_ID_LINKSYS		0x11AD
+#define PCI_DEVICE_ID_LC82C115		0xC115
+#define PCI_VENDOR_ID_VIATEC		0x1106
+#define PCI_DEVICE_ID_VIA_RHINE_I	0x3043
+#define PCI_DEVICE_ID_VIA_86C100A	0x6100
+#define PCI_VENDOR_ID_DAVICOM		0x1282
+#define PCI_DEVICE_ID_DM9102		0x9102
+
+struct pci_device {
+	unsigned short vendor, dev_id;
+	const char *name;
+	unsigned int membase;
+	unsigned int ioaddr;
+	unsigned short devfn;
+	unsigned short bus;
+};
+
+extern void eth_pci_init(struct pci_device *);
+int pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
+			     unsigned char where, unsigned char *val);
+int pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+			     unsigned char where, unsigned short *val);
+int pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
+			      unsigned char where, unsigned int *val);
+int pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
+			      unsigned char where, unsigned char val);
+int pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+			      unsigned char where, unsigned short val);
+int pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
+			       unsigned char where, unsigned int val);
+
+/*
+ * Error values that may be returned by the PCI bios.
+ */
+#define PCIBIOS_SUCCESSFUL              0x00
+#define PCIBIOS_FUNC_NOT_SUPPORTED      0x81
+#define PCIBIOS_BAD_VENDOR_ID           0x83
+#define PCIBIOS_DEVICE_NOT_FOUND        0x86
+#define PCIBIOS_BAD_REGISTER_NUMBER     0x87
+#define PCIBIOS_SET_FAILED              0x88
+#define PCIBIOS_BUFFER_TOO_SMALL        0x89
+
+
+
+#endif				/* PCI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/sbd.h linux/arch/mips/galileo-boards/ev64120/compressed/sbd.h
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/sbd.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/sbd.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,52 @@
+/*
+ * sbd.h: cpu board definitions for Galileo-9
+ * Copyright (c) 1997	Algorithmics Ltd
+ */
+
+#ifndef MHZ
+/* fastest possible pipeline clock */
+#define MHZ		150
+#endif
+
+/* FIXME These timings are completely fictional */
+#define RAMCYCLE	60	/* 60ns dram cycle */
+#define ROMCYCLE	750	/* ~750ns rom cycle */
+#define CACHECYCLE	(1000/MHZ)	/* internal clock */
+#define CYCLETIME	CACHECYCLE
+#define CACHEMISS	(CYCLETIME * 6)
+
+/*
+ * rough scaling factors for 2 instruction DELAY loop to get 1ms and 1us delays
+ */
+#define ASMDELAY(ns,icycle)	\
+	(((ns) + (icycle)) / ((icycle) * 2))
+
+#define CACHEUS		ASMDELAY(1000, CACHECYCLE)
+#define RAMUS		ASMDELAY(1000, CACHEMISS+RAMCYCLE)
+#define ROMUS		ASMDELAY(1000, CACHEMISS+ROMCYCLE)
+#define CACHEMS		ASMDELAY(1000000, CACHECYCLE)
+#define RAMMS		ASMDELAY(1000000, CACHEMISS+RAMCYCLE)
+#define ROMMS		ASMDELAY(1000000, CACHEMISS+ROMCYCLE)
+
+#ifndef __ASSEMBLY__
+#define nsdelay(ns)	mips_cycle (ASMDELAY (ns, CACHECYCLE))
+#define usdelay(us)	mips_cycle (ASMDELAY ((us)*1000, CACHECYCLE))
+#endif
+
+#define DRAM_BASE		0x00000000
+#define PCI_IO_BASE		0x10000000
+#define PCI_IO_SIZE		0x02000000
+#define PCI_MEM_BASE		0x12000000
+#define PCI_MEM_SIZE		0x02000000
+#define GT64011_BASE		0x14000000
+#define DUART_BASE		0x1d000000
+#define FLASH_BASE		0x1f000000
+#define PROM_BASE		0x1fc00000
+
+
+#define LOCAL_MEM		DRAM_BASE
+#define LOCAL_MEM_SIZE		(128*1024*1024)	/* SDRAM size (16MB) */
+
+#define BOOTPROM_BASE		PROM_BASE
+
+#define DUART_CLOCK		3686400
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S linux/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,1049 @@
+/*
+ * Copyright 1997 Algorithmics Ltd
+ *	All Rights Reserved
+ *	
+ * gal9/sbdreset.sx -- low level board dependent routines
+ */
+
+#ifdef EVB64120A
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/cacheops.h>
+#include <asm/current.h>
+#include <asm/offset.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/cachectl.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/cpu.h>
+#include "sbd.h"
+
+
+#include "gt64011.h"
+#include "ns16550.h"
+			
+#ifdef GALILEO_PORT // miniBios crack
+#define C0_CONFIG CP0_CONFIG
+#define C0_STATUS CP0_STATUS
+#define C0_TLBLO0 CP0_ENTRYLO0
+#define C0_TLBLO1 CP0_ENTRYLO1
+#define C0_PGMASK CP0_PAGEMASK
+#define C0_TLBHI CP0_ENTRYHI 
+#define C0_INX CP0_INDEX
+#define NTLBENTRIES     48
+        
+        
+#define CFG_IB CONF_IB
+#define CFG_DB CONF_DB
+#define CFG_C_NONCOHERENT CONF_CM_CACHABLE_NONCOHERENT
+#define C0_SR CP0_STATUS        
+#define SR_DE ST0_DE
+
+        
+        #define SLEAF(x) LEAF(x)
+        #define SEND(x) END(x)
+        #define XLEAF(x) LEAF(x)
+        #define SBD_DISPLAY(a,b,c,d,e) ; 
+
+#define K0BASE          0x80000000
+#define K0SIZE          0x20000000
+#define K1BASE          0xa0000000
+#define K1SIZE          0x20000000
+#define K2BASE          0xc0000000
+
+#define PHYS_TO_K0(pa)  ((pa)|K0BASE)
+#define PHYS_TO_K1(pa)  ((pa)|K1BASE)
+#define K0_TO_PHYS(va)  ((va)&(K0SIZE-1))
+#define K1_TO_PHYS(va)  ((va)&(K1SIZE-1))
+#define K0_TO_K1(va)    ((va)|K1SIZE)
+#define K1_TO_K0(va)    ((va)&~K1SIZE)
+
+#define PA_TO_KVA0(pa)  PHYS_TO_K0(pa)
+#define PA_TO_KVA1(pa)  PHYS_TO_K1(pa)
+#define KVA_TO_PA(pa)   K1_TO_PHYS(pa)
+#define KSEG0_BASE      K0BASE
+#define KSEG1_BASE      K1BASE
+
+
+#endif
+
+#define MB	0x100000
+				
+#define MemTypeNone		0x8000
+#define MemRasMask		0x0f00
+#define MemRasShift		8
+#define MemCasMask		0x000f
+#define MemCasShift 		0
+
+#define rasave	s0
+#define p64011	s1
+#define bank0	s2
+#define bank1	s3
+#define bank2	s4
+#define bank3	s5
+#define memtop	s6
+#define membase	s7
+	
+/*#if #endian(big)	*/
+#ifdef __MIPSEB__
+
+#define HTOLL(sr,tr) \
+	.set noat ; \
+	srl	AT,sr,24 ; \
+	srl	tr,sr,8 ; \
+	and	tr,0xff00 ; \
+	or	AT,tr ; \
+	and	tr,sr,0xff00 ; \
+	sll	tr,8 ; \
+	or	AT,tr ; \
+	sll	tr,sr,24 ; \
+	or	sr,AT,tr ; \
+	.set at
+#else
+#define HTOLL(sr,tr)
+#endif
+				
+#undef DBGSBD
+	
+#ifdef DBGSBD
+#define DBG(s) \
+	.rdata ; \
+88:	.asciiz	s ; \
+	.text ; \
+	la	a0, 88b ; \
+	jal	_dbgmsg
+	
+LEAF(_dbgmsg)
+	.set noat
+	li	AT,PHYS_TO_K1(NS16550_CHANB)
+waitrdy:
+	lbu	v1,LSR(AT)
+	.set noreorder;	nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+	and	v1,LSR_TXRDY
+	beqz	v1,waitrdy
+	
+	lbu	v1,(a0)
+	addu	a0,1
+	beqz	v1,9f
+	sb	v1,DATA(AT)
+	.set noreorder;	nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+	b	waitrdy	
+9:	j	ra
+	.set at
+END(_dbgmsg)
+
+LEAF(_dbghex)
+	li	a1,PHYS_TO_K1(NS16550_CHANB)
+	li	t0,8
+1:
+	lbu	t1,LSR(a1)
+	.set noreorder;	nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+	and	t1,LSR_TXRDY
+	beqz	t1,1b
+	
+	srl	t1,a0,28
+	addu	t1,'0'
+	ble	t1,'9',2f
+	addu	t1,'a'-'0'-10
+2:	sb	t1,DATA(a1)
+	.set noreorder;	nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+
+	sll	a0,4
+	sub	t0,1
+	bnez	t0,1b
+		
+	j	ra
+	.set at
+END(_dbghex)
+	
+	.rdata
+initb_str:
+	.byte	9,0x40	/* Reset CH B */
+	.byte	1,0x00	/* Interrupt disabled */
+	.byte	3,0xc1	/* 8 bits/char rx enable */
+	.byte	4,0x44	/* x16 clk mode 1 stop bit */
+	.byte	5,0x6a	/* tx 8/bit RTS & tx enable */
+	.byte	9,0x0a	/* MIE Master int enab. and NV No Vector */
+	.byte	11,0x50	/* Select BR gen. out for both rx and ts */
+	.byte	0,0x10
+	.byte	0,0x10
+	.byte	14,0x01	/* enable baud rate gen. */
+	.byte	15,0x00	/* known state for reg 15 */
+	
+	.byte	14,0x00	/* disable baud rate gen. */
+	.byte	12,0x0a /* 0x0a	= 9600 baud time const. - lower 8 bits */
+	.byte	13,0x00	/* 9600 buad time const. - upper 8 bits */
+	.byte	14,0x01	/* enable baud rate gen. */
+	.byte	0xff
+
+	.text
+	
+SLEAF(_dbginit)
+        /*
+        li	v0,PHYS_TO_K1(NS16550_CHANB)
+	la	a0,initb_str
+	or	a0,K1BASE
+1:	lbu	t0,0(a0)
+	beq	t0,0xff,1f
+	sb	t0,LSR(v0)
+	.set noreorder;	nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+	addu	a0,1
+	b	1b
+        */
+        jal     init_ns16550_chan_b # Debug channel
+	j	ra
+SEND(_dbginit)		
+#else
+#define DBG(s)		
+#endif
+		
+LEAF(sbdreset)
+	move	rasave,ra
+
+	/* if launched by ITROM, leave Config alone */
+#ifndef ITBASE	
+	/* set config register for 32b/32b cachelines, kseg0 cacheable */
+	mfc0	t1,C0_CONFIG
+	and	t1,~0x3f		# set bits 5..0 only
+	or	t1,CFG_IB | CFG_DB | CFG_C_NONCOHERENT
+	mtc0	t1,C0_CONFIG
+#endif	
+
+       /* Initialize stack pointer to 6MB address */        
+         li sp,0xa0600000 
+
+        
+        /*
+	 * slight amount of kludgery here to stop RAM resident
+	 * program from overwriting itself...
+	 */
+//	li	v1,0x1fc00000		/* check return address is in ROM */
+//	and	v0,ra,v1
+//	bne	v0,v1,.noinit
+
+        /* table driven hardware register initialization */
+        la      a0, reginittab
+        or      a0, K1BASE              /* force to kseg1 */
+
+1:      lw      v0,0(a0)
+        lw      v1,4(a0)
+        addu    a0,8
+        beqz    v0,8f
+
+        sw      v1,0(v0)
+        b       1b
+8:
+
+#ifdef DBGSBD
+	jal     init_ns16550_chan_b   # was - _dbginit
+	DBG("sbdreset\r\n")
+#endif
+#define DEVICE_BANK0PARAMETERS                                                          0x45C
+#define DEVICE_BANK1PARAMETERS                                                          0x460
+#define DEVICE_BANK2PARAMETERS                                                          0x464
+#define DEVICE_BANK3PARAMETERS                                                          0x468
+#define DEVICE_BOOT_BANK_PARAMETERS                                                     0x46C
+#define GT_INTERNAL_REG_BASE 0xb4000000
+
+        li      p64011, PA_TO_KVA1(GT64011_BASE)
+         
+        li  v0,0xb400046c       /* Boot Device */
+        lw  t0,0(v0)
+        and t0,0x00003000       /* Keep the correct boot size */
+	or  t0,htoll(0x3847de70)
+	sw  t0,0(v0)
+        
+        li  v0,0xb4000468       /* CS3 Device - 16 bit FLASH memory */
+        li  t0,htoll(0x3859e6e8)
+	sw  t0,0(v0)
+        
+                
+        li  v0,0xb4000c84       /* PCI 1 timeout register */
+        li  t0,htoll(0xffff)
+	sw  t0,0(v0)
+        
+                
+        li  v0,0xb4000c3c       /* Enable I/O response on PCI0 */
+        li  t0,htoll(0x7)
+	sw  t0,0(v0)
+
+        li  v0,0xb4000cbc       /* Enable I/O response on PCI1 */
+        li  t0,htoll(0x7)
+	sw  t0,0(v0)
+
+        /* GT-64120 Initialization */
+        
+        li      p64011, PA_TO_KVA1(GT64011_BASE)	
+
+        /*********************************************************************/
+        /************************* SDRAM initializing ************************/
+        /******************************* START *******************************/
+        
+        
+                                        /* SDRAM banks 0,1,2,3 parameters               */
+        li      t0,htoll(0x01908200)    /* - Standard Monitor: Interleave enabled       */
+        li      v0,0xb4000448           /* - Registered SDRAM (Bit 23)                  */
+        sw      t0,0(v0)                /* - Duplicate Dadr11,BankSel1 and Dadr12       */
+                                        /* - Cas latency: 2 Cycles                      */
+                                        /* - Flow Through enable: One sample            */
+                                        /* - SRAS - precharge time: 3 Cycles            */
+                                        /* - No ECC                                     */
+                                        /* - No ByPass                                  */
+                                        /* - Burst length: 8                            */
+        
+        /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM0 */
+        /* Set bank0`s range to: 0 - 0x10000000 (256 MByte)     */
+_DIMM0:
+        li  v0,0xb4000008      
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)
+        
+        li  v0,0xb4000010      
+	li  t0,htoll(0x7f)
+	sw  t0,0(v0)
+        
+        /* Close banks 2 and 3 */
+        li  v0,0xb4000018      
+	li  t0,htoll(0x7ff)
+	sw  t0,0(v0)
+        li  v0,0xb4000020      
+	li  t0,htoll(0x00)
+	sw  t0,0(v0)
+        
+        /* Extend bank0 to 0x10000000 and Close bank1,2 and 3 */
+        DBG("Extend bank0 to 0x10000000 and Close bank1,2 and 3...\r\n")
+        li  v0,0xb4000400      
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)
+        li  v0,0xb4000404      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)
+        li  v0,0xb4000408      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)   
+        li  v0,0xb400040c      
+	li  t0,htoll(0x00)
+	sw  t0,0(v0)
+        li  v0,0xb4000410      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)   
+        li  v0,0xb4000414      
+	li  t0,htoll(0x00)
+	sw  t0,0(v0)
+        li  v0,0xb4000418      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)   
+        li  v0,0xb400041c      
+	li  t0,htoll(0x00)
+	sw  t0,0(v0)        
+
+        /* Configure bank0 to 256 Mbit */
+        DBG("Configure bank0 to 256 Mbit...\r\n")
+        li  v0,0xb400044c      
+	li  t0,htoll(0x00004c69)
+        sw  t0,0(v0)
+        
+        /* Config the SDRAM banks decode system */
+	li  v0,0xb400047c      
+	li  t0,htoll(2)
+	sw  t0,0(v0)
+ 
+        li  v0,0xb4000474        
+	li  t0,htoll(0x3)
+	sw  t0,0(v0)
+        
+        li  v0,0xa0000000
+        li  t0,0
+        sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)      
+        
+        /* Write to address 0x2000000 and check if 0x00000000 is being written too */
+        DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n")
+        li  v0,0xa0000000
+        li  t1,0xa0000010
+        li  t0,htoll(0x0)
+1:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,1b
+
+        /* The address should activate Dadr12 */
+        li  v0,0xa2000000      
+	li  t0,0x11111111
+        sw  t0,0(v0)
+        li  v0,0xa0000010
+        li  t1,0xa0000100
+        li  t0,0x22222222
+2:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,2b
+
+        DBG("Check address 0x00000000 for duplications...\r\n")
+        li    t0,0xa0000000
+        li    v0,0x11111111
+        lw    t0,(t0)
+        bne   t0,v0,_256MBIT
+        
+        /* Write to address 0x1000 and check if 0x00000000 is being written too */
+        DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n")
+        li  v0,0xa0000000
+        li  t1,0xa0000010
+        li  t0,htoll(0x0)
+1:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,1b
+
+        /* The address should activate bank select1*/
+        li  v0,0xa0001000      
+	li  t0,0x11111111
+        sw  t0,0(v0)
+        li  v0,0xa0000010
+        li  t1,0xa0000100
+        li  t0,0x22222222
+2:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,2b
+
+        DBG("Check address 0x00000000 for duplications...\r\n")
+        li    t0,0xa0000000
+        li    v0,0x11111111
+        lw    t0,(t0)
+        beq   t0,v0,_16MBIT
+
+        /* Write to address 0x8000000 and check if 0x00000000 is being written too */
+        DBG("Write to address 0x8000000 and check if 0x00000000 is being written too...\r\n")
+        li  v0,0xa0000000
+        li  t1,0xa0000010
+        li  t0,htoll(0x0)
+1:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,1b
+
+        /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit
+           device */
+        li  v0,0xa8000000      
+	li  t0,0x11111111
+        sw  t0,0(v0)
+        li  v0,0xa0000010
+        li  t1,0xa0000100
+        li  t0,0x22222222
+2:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,2b
+
+        DBG("Check address 0x00000000 for duplications...\r\n")
+        li    t0,0xa0000000
+        li    v0,0x11111111
+        lw    t0,(t0)
+        beq   t0,v0,_64MBIT
+        b     _128MBIT
+        
+_16MBIT:
+        DBG("16 Mbit SDRAM detected...\r\n")
+        /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */
+        li  v0,0xb4000810      
+	li  t0,htoll(16)
+	sw  t0,0(v0)
+        li  t1,htoll(0x00000449)
+        b   _DIMM1
+
+_64MBIT:
+        DBG("64 Mbit SDRAM detected...\r\n")
+        /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */
+        li  v0,0xb4000810      
+	li  t0,htoll(64)
+	sw  t0,0(v0)
+        li  t1,htoll(0x00000c69)
+        b   _DIMM1
+
+_128MBIT:
+        DBG("128 Mbit SDRAM detected...\r\n")
+        /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */
+        li  v0,0xb4000810      
+	li  t0,htoll(128)
+	sw  t0,0(v0)
+        li  t1,htoll(0x00000c69)
+        b   _DIMM1
+
+_256MBIT:
+        DBG("256 Mbit SDRAM detected...\r\n")
+        /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */
+        li  v0,0xb4000810      
+	li  t0,htoll(256)
+	sw  t0,0(v0)
+        li  t1,htoll(0x00004c69)
+        b   _DIMM1
+        
+_DIMM1:        
+        li  v0,0xb400044c
+        sw  t1,0(v0)  # Bank0
+        sw  t1,4(v0)  # Bank1           
+        
+        /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM1 */
+        /* Close banks 0 and 1 */
+        li  v0,0xb4000008      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)
+        
+        li  v0,0xb4000010      
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)
+        
+        /* Set bank2`s range to: 0 - 0x10000000 (256 MByte)     */
+        li  v0,0xb4000018      
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)
+        li  v0,0xb4000020      
+	li  t0,htoll(0x7f)
+	sw  t0,0(v0)
+        
+        /* Extend bank2 to 0x10000000 and Close bank0,1 and 3 */
+        DBG("Extend bank2 to 0x10000000 and Close banks 0,1 and 3...\r\n")
+        li  v0,0xb4000400      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)
+        li  v0,0xb4000404      
+	li  t0,htoll(0x00)
+	sw  t0,0(v0)
+        li  v0,0xb4000408      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)   
+        li  v0,0xb400040c      
+	li  t0,htoll(0x00)
+	sw  t0,0(v0)
+        li  v0,0xb4000410      
+	li  t0,htoll(0x00)
+	sw  t0,0(v0)   
+        li  v0,0xb4000414      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)
+        li  v0,0xb4000418      
+	li  t0,htoll(0xff)
+	sw  t0,0(v0)   
+        li  v0,0xb400041c      
+	li  t0,htoll(0x00)
+	sw  t0,0(v0)        
+
+        /* Configure bank2 to 256 Mbit */
+        DBG("Configure bank2 to 256 Mbit...\r\n")
+        li  v0,0xb4000454      
+	li  t0,htoll(0x00004c69)
+        sw  t0,0(v0)
+        
+        /* Config the SDRAM banks decode system */
+	li  v0,0xb400047c      
+	li  t0,htoll(2)
+	sw  t0,0(v0)
+ 
+        li  v0,0xb4000474        
+	li  t0,htoll(0x3)
+	sw  t0,0(v0)
+        
+        li  v0,0xa0000000
+        li  t0,0
+        sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)      
+        
+        /* Write to address 0x2000000 and check if 0x00000000 is being written too */
+        DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n")
+        li  v0,0xa0000000
+        li  t1,0xa0000010
+        li  t0,htoll(0x0)
+1:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,1b
+
+        /* The address should activate Dadr12 */
+        li  v0,0xa2000000      
+	li  t0,0x11111111
+        sw  t0,0(v0)
+        li  v0,0xa0000010
+        li  t1,0xa0000100
+        li  t0,0x22222222
+2:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,2b
+
+        DBG("Check address 0x00000000 for duplications...\r\n")
+        li    t0,0xa0000000
+        li    v0,0x11111111
+        lw    t0,(t0)
+        bne   t0,v0,_256MBIT2
+        
+        /* Write to address 0x1000 and check if 0x00000000 is being written too */
+        DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n")
+        li  v0,0xa0000000
+        li  t1,0xa0000010
+        li  t0,htoll(0x0)
+1:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,1b
+
+        /* The address should activate bank select1*/
+        li  v0,0xa0001000      
+	li  t0,0x11111111
+        sw  t0,0(v0)
+        li  v0,0xa0000010
+        li  t1,0xa0000100
+        li  t0,0x22222222
+2:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,2b
+
+        DBG("Check address 0x00000000 for duplications...\r\n")
+        li    t0,0xa0000000
+        li    v0,0x11111111
+        lw    t0,(t0)
+        beq   t0,v0,_16MBIT2
+
+        /* Write to address 0x8000000 and check if 0x00000000 is being written too */
+        DBG("Write to address 0x8000000 and check if 0x00000000 is being written too...\r\n")
+        li  v0,0xa0000000
+        li  t1,0xa0000010
+        li  t0,htoll(0x0)
+1:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,1b
+
+        /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit
+           device */
+        li  v0,0xa8000000      
+	li  t0,0x11111111
+        sw  t0,0(v0)
+        li  v0,0xa0000010
+        li  t1,0xa0000100
+        li  t0,0x22222222
+2:      sw  t0,0(v0)
+        addu v0,4
+        bne t1,v0,2b
+
+        DBG("Check address 0x00000000 for duplications...\r\n")
+        li    t0,0xa0000000
+        li    v0,0x11111111
+        lw    t0,(t0)
+        beq   t0,v0,_64MBIT2
+        b     _128MBIT2
+        
+_16MBIT2:
+        DBG("16 Mbit SDRAM detected...\r\n")
+        /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */
+        li  v0,0xb4000814      
+	li  t0,htoll(16)
+	sw  t0,0(v0)
+        li  t1,htoll(0x00000449)
+        b   _INIT_SDRAM
+
+_64MBIT2:
+        DBG("64 Mbit SDRAM detected...\r\n")
+        /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */
+        li  v0,0xb4000814      
+	li  t0,htoll(64)
+	sw  t0,0(v0)
+        li  t1,htoll(0x00000c69)
+        b   _INIT_SDRAM
+
+_128MBIT2:
+        DBG("128 Mbit SDRAM detected...\r\n")
+        /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */
+        li  v0,0xb4000814      
+	li  t0,htoll(128)
+	sw  t0,0(v0)
+        li  t1,htoll(0x00000c69)
+        b   _INIT_SDRAM
+
+_256MBIT2:
+        DBG("256 Mbit SDRAM detected...\r\n")
+        /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */
+        li  v0,0xb4000814      
+	li  t0,htoll(256)
+	sw  t0,0(v0)
+        li  t1,htoll(0x00004c69)
+        b   _INIT_SDRAM
+
+_INIT_SDRAM:        
+        /* Restore defaults */
+        DBG("Restoring defaults...\r\n")
+        li  v0,0xb4000404      
+	li  t0,htoll(0x07)
+	sw  t0,0(v0)
+        li  v0,0xb4000408      
+	li  t0,htoll(0x08)
+	sw  t0,0(v0)
+        li  v0,0xb400040c      
+	li  t0,htoll(0x0f)
+	sw  t0,0(v0)
+        li  v0,0xb4000410      
+	li  t0,htoll(0x10)
+	sw  t0,0(v0)   
+        li  v0,0xb4000414      
+	li  t0,htoll(0x17)
+	sw  t0,0(v0)
+        li  v0,0xb4000418      
+	li  t0,htoll(0x18)
+	sw  t0,0(v0)   
+        li  v0,0xb400041c      
+	li  t0,htoll(0x1f)
+	sw  t0,0(v0)
+        li  v0,0xb4000010      
+	li  t0,htoll(0x07)
+	sw  t0,0(v0)
+        li  v0,0xb4000018      
+	li  t0,htoll(0x008)
+	sw  t0,0(v0)
+        li  v0,0xb4000020      
+	li  t0,htoll(0x0f)
+	sw  t0,0(v0)        
+        
+        li  v0,0xb400044c
+        sw  t1,8(v0)  # Bank2
+        sw  t1,12(v0) # Bank3
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x3)
+	sw  t0,0(v0)
+        
+        li  v0,0xa0000000
+        li  t0,0
+        sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x3)
+	sw  t0,0(v0)
+        
+        li  v0,0xa0800000
+        li  t0,0
+        sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x3)
+	sw  t0,0(v0)
+        
+        li  v0,0xa1000000
+        li  t0,0
+        sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x3)
+	sw  t0,0(v0)
+        
+        li  v0,0xa1800000
+        li  t0,0
+        sw  t0,0(v0)
+        
+        li  v0,0xb4000474        
+	li  t0,htoll(0x0)
+	sw  t0,0(v0)
+        
+        /*********************************************************************/
+        /************************* SDRAM initializing ************************/
+        /******************************* END *********************************/
+        
+        li      p64011, PA_TO_KVA1(GT64011_BASE)
+        
+        li      t0,htoll(0x00000000)    /* RAS[1:0] low decode address */
+        sw      t0,0x008(p64011)
+
+        li      t0,htoll(0x00000007)    /* RAS[1:0] high decode address */
+        sw      t0,0x010(p64011)
+
+        li      t0,htoll(0x00000000)    /* RAS[0] Low decode address */
+        sw      t0,0x400(p64011)
+
+        li      t0,htoll(0x0000000f)    /* RAS[0] High decode address */
+        sw      t0,0x404(p64011)
+
+        li      t0,htoll(0x00000008)    /* RAS[3:2] low decode address */
+        sw      t0,0x018(p64011)
+
+        li      t0,htoll(0x0000000f)    /* RAS[3:2] high decode address */
+        sw      t0,0x020(p64011)
+
+        li      t0,htoll(0x0000000f)    /* RAS[1] Low Decode Address */
+        sw      t0,0x408(p64011)
+
+        li      t0,htoll(0x00000008)    /* RAS[1] High Decode Address */
+        sw      t0,0x40c(p64011)
+
+        li      t0,htoll(0x00000010)    /* RAS[2] Low Decode Address */
+        sw      t0,0x410(p64011)
+
+        li      t0,htoll(0x00000017)    /* RAS[2] High Decode Address */
+        sw      t0,0x414(p64011)
+
+        li      t0,htoll(0x00000018)    /* RAS[3] Low Decode Address */
+        sw      t0,0x418(p64011)
+
+        li      t0,htoll(0x0000001f)    /* RAS[3] High Decode Address <<<<<< 1*/
+        sw      t0,0x41c(p64011)
+	
+#ifdef DBGSBD	
+#define DREG(str,rname) \
+	DBG(str); \
+	DBG(":\t") ;			\
+	lw	a0,rname(p64011) ;	\
+	HTOLL(a0,t0) ;			\
+	jal	_dbghex ;		\
+	DBG("\r\n")
+	
+	DBG("GT-64120 settings:\r\n")
+        DREG("DRAMPAR_BANK0   (44c)",GT_DRAMPAR_BANK0)
+        DREG("DRAMPAR_BANK1   (450)",GT_DRAMPAR_BANK1)
+        DREG("DRAMPAR_BANK2   (454)",GT_DRAMPAR_BANK2)
+        DREG("DRAMPAR_BANK3   (458)",GT_DRAMPAR_BANK3)
+        DREG("PAS_RAS10LO     (008)",GT_PAS_RAS10LO)
+        DREG("PAS_RAS10HI     (010)",GT_PAS_RAS10HI)
+        DREG("PAS_RAS32LO     (018)",GT_PAS_RAS32LO)
+        DREG("PAS_RAS32HI     (020)",GT_PAS_RAS32HI)
+        DREG("DDAS_RAS0LO     (400)",GT_DDAS_RAS0LO)
+        DREG("DDAS_RAS0HI     (404)",GT_DDAS_RAS0HI)
+        DREG("DDAS_RAS1LO     (408)",GT_DDAS_RAS1LO)
+        DREG("DDAS_RAS1HI     (40c)",GT_DDAS_RAS1HI)
+        DREG("DDAS_RAS2LO     (410)",GT_DDAS_RAS2LO)
+        DREG("DDAS_RAS2HI     (414)",GT_DDAS_RAS2HI)
+        DREG("DDAS_RAS3LO     (418)",GT_DDAS_RAS3LO)
+        DREG("DDAS_RAS3HI     (41c)",GT_DDAS_RAS3HI)
+        DREG("GT_DRAM_CFG     (448)",GT_DRAM_CFG)
+        DREG("GT_DEVPAR_BANK0 (45c)",GT_DEVPAR_BANK0)
+        DREG("GT_DEVPAR_BANK1 (460)",GT_DEVPAR_BANK1)
+        DREG("GT_DEVPAR_BANK2 (464)",GT_DEVPAR_BANK2)
+        DREG("GT_DEVPAR_BANK3 (468)",GT_DEVPAR_BANK3)
+        DREG("GT_IPCI_TOR     (c04)",GT_IPCI_TOR)
+#endif
+		
+	/* we can now initialise the caches for a fast clear_mem */
+	SBD_DISPLAY ('C','A','C','H',CHKPNT_CACH)
+	DBG("init_cache\r\n")
+//	jal	mips_init_cache
+
+.noinit:
+
+	/* initialise tlb */
+	SBD_DISPLAY ('I','T','L','B', CHKPNT_ITLB)
+	DBG("init_tlb\r\n")
+//	bal	init_tlb 
+
+//	DBG("sbdreset completed\r\n")
+//	move	ra,rasave
+        j       GetExtendedMemorySize
+        nop
+
+END(sbdreset)
+
+LEAF(_sbd_memfail)
+	SBD_DISPLAY ('!','M','E','M',CHKPNT_0MEM)
+1:	b	1b
+	j	ra
+END(_sbd_memfail)
+
+	.rdata
+RefreshBits:
+	.word	htoll(GT_DRAMPAR_Refresh512)
+	.word	htoll(GT_DRAMPAR_Refresh1024)
+	.word	htoll(GT_DRAMPAR_Refresh2048)
+	.word	htoll(GT_DRAMPAR_Refresh4096)
+	.text
+
+/* DRAM: */
+#define GT_DRAM_CFG_INIT \
+        GT_DRAM_CFG_RefIntCnt(160) | \
+        GT_DRAM_CFG_StagRefOn | \
+        GT_DRAM_CFG_ADSFunctDRAM | \
+        GT_DRAM_CFG_DRAMLatchActive
+
+/* serial port:  widest timings even 8 bit bus, latch enabled no parity */
+#define GT_DEVPAR_SERIALINIT \
+        GT_DEVPAR_TurnOff(7) | \
+        GT_DEVPAR_AccToFirst(15) | \
+        GT_DEVPAR_AccToNext(15) | \
+        GT_DEVPAR_ADStoWr(7) | \
+        GT_DEVPAR_WrActive(7) | \
+        GT_DEVPAR_WrHigh(7) | \
+        GT_DEVPAR_DevWidth8 | \
+        GT_DEVPAR_DevLocEven | \
+        GT_DEVPAR_LatchFunctTransparent | \
+        GT_DEVPAR_ParityDisable | \
+        GT_DEVPAR_Reserved
+
+/* PCI: */
+#define GT_IPCI_TOR_INIT \
+        GT_IPCI_TOR_Timeout0(255) | \
+        GT_IPCI_TOR_Timeout1(255) | \
+        GT_IPCI_TOR_RetryCtr(0)
+
+#define INIT(addr,val) \
+        .word   addr, val
+#define GTINIT(addr,val) \
+        INIT(PHYS_TO_K1(GT64011_BASE+(addr)), htoll(val))
+
+        .rdata
+reginittab:
+
+        /* disable ras1:0 and ras3:2 decodes */
+        GTINIT(GT_PAS_RAS10LO,  GT_PAS_LOMASK_Low);
+        GTINIT(GT_PAS_RAS10HI,  0);
+        GTINIT(GT_PAS_RAS32LO,  GT_PAS_LOMASK_Low);
+        GTINIT(GT_PAS_RAS32HI,  0);
+
+        /* disable RAS[0123] */
+        GTINIT(GT_DDAS_RAS0LO,  GT_DDAS_LOMASK_Low)
+        GTINIT(GT_DDAS_RAS0HI,  0);
+        GTINIT(GT_DDAS_RAS1LO,  GT_DDAS_LOMASK_Low)
+        GTINIT(GT_DDAS_RAS1HI,  0);
+        GTINIT(GT_DDAS_RAS2LO,  GT_DDAS_LOMASK_Low)
+        GTINIT(GT_DDAS_RAS2HI,  0);
+        GTINIT(GT_DDAS_RAS3LO,  GT_DDAS_LOMASK_Low)
+        GTINIT(GT_DDAS_RAS3HI,  0);
+
+        /* 0x45c, 0x460, 0x464, 0x468 */
+	/*GTINIT(GT_DEVPAR_BANK0, GT_DEVPAR_SERIALINIT)*/
+        GTINIT(GT_DEVPAR_BANK0, 0x3847de60)
+        GTINIT(GT_DEVPAR_BANK1, 0x146fffff)
+        GTINIT(GT_DEVPAR_BANK2, 0x144fffff)
+        GTINIT(GT_DEVPAR_BANK3, 0x167fffff)
+
+        GTINIT(GT_IPCI_TOR,     GT_IPCI_TOR_INIT)
+        INIT(0,0)
+        .text
+
+        .globl sbddelay
+
+LEAF(sbdberrenb)
+	mfc0	v0,C0_SR
+	li	t0,SR_DE	
+	bnez	a0,1f
+	or	t1,v0,t0	# disable cache/parity errors (SR_DE = 1)
+	b	2f
+1:	not	t1,t0		# enable cache/parity errors (SR_DE = 0)
+	and	t1,v0
+2:	mtc0	t1,C0_SR
+	and	v0,t0		# get old SR_DE bit
+	xor	v0,t0		# and invert to make it an enable bit
+	j	ra
+END(sbdberrenb)
+
+
+LEAF(sbdberrcnt)
+	move	v0,zero
+	j	ra
+END(sbdberrcnt)
+
+	.lcomm	wbfltmp,4
+
+LEAF(wbflush)
+//XLEAF(mips_wbflush)
+	sync
+	la	t0,wbfltmp
+	or	t0,K1BASE
+	lw	zero,0(t0)
+	j	ra
+END(wbflush)
+
+
+LEAF(sbddelay)
+	li	t1,CACHEUS
+	and	t0,ra,0x20000000
+	beqz	t0,1f
+	li	t1,ROMUS
+1:	mul	a0,t1
+	subu	a0,15		# approx number of loops so far
+
+	.set	noreorder	
+	.set	nomacro
+	nop
+2:	bgtz	a0,2b
+	subu	a0,1
+	.set	macro
+	.set	reorder
+
+	j	ra
+END(sbddelay)
+
+#include "meminit.S"
+
+
+LEAF(mips_cycle)
+	.set	noreorder	
+	.set	nomacro
+1:	bgtz	a0,1b
+	subu	a0,1
+	.set	macro
+	.set	reorder
+	j	ra
+END(mips_cycle)
+
+LEAF(init_ns16550_chan_b)
+	# enable 16550 fifo if it is there
+        li      a0,NS16550_CHANB 
+        li	t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
+	sb	t0,FIFO(a0)
+
+	/* convert baud rate in a1 into register value */
+        li	t2,NS16550_HZ/(16*115200)	# brtc = CLK/16/speed
+
+	li	t0,CFCR_DLAB			# select brtc divisor
+	sb	t0,CFCR(a0)
+	sb	t2,DATA(a0)			# store divisor lsb
+	srl	t2,8	
+	sb	t2,IER(a0)			# store divisor msb
+
+	li	t0,CFCR_8BITS			# set 8N1 mode
+	sb	t0,CFCR(a0)
+
+	li	t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE	# enable DTR & RTS 
+  	sb	t0,MCR(a0)
+ 	li	t0,0 # Galileo IER_ERXRDY			# enable receive interrupt(!) 
+	sb	t0,IER(a0)
+
+	move	v0,zero				# indicate success
+	j	ra
+	
+END(init_ns16550_chan_b)
+
+LEAF(init_ns16550_chan_a)
+	# enable 16550 fifo if it is there
+        li      a0,NS16550_CHANA 
+        li	t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
+	sb	t0,FIFO(a0)
+
+	/* convert baud rate in a1 into register value */
+        li	t2,NS16550_HZ/(16*9600)		# brtc = CLK/16/speed
+
+	li	t0,CFCR_DLAB			# select brtc divisor
+	sb	t0,CFCR(a0)
+	sb	t2,DATA(a0)			# store divisor lsb
+	srl	t2,8	
+	sb	t2,IER(a0)			# store divisor msb
+
+	li	t0,CFCR_8BITS			# set 8N1 mode
+	sb	t0,CFCR(a0)
+
+	li	t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE	# enable DTR & RTS 
+  	sb	t0,MCR(a0)
+ 	li	t0,0 # Galileo IER_ERXRDY			# enable receive interrupt(!) 
+	sb	t0,IER(a0)
+
+	move	v0,zero				# indicate success
+	j	ra
+	
+END(init_ns16550_chan_a)
+
+#endif /* EVB64120A */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/compressed/xfer.c linux/arch/mips/galileo-boards/ev64120/compressed/xfer.c
--- linux.orig/arch/mips/galileo-boards/ev64120/compressed/xfer.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/compressed/xfer.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,114 @@
+/*
+ *  arch/mips/galileo/compressed/xfer.c
+ *
+ *  By RidgeRun Inc,
+ *
+ *  Xfer an image from flash to ram.
+ *  For use with Galileo EVB64120A MIPS eval board.
+ */
+
+#include "linux/serial_reg.h"
+
+#define port 0xbd000000
+#define inb(addr) (*(volatile unsigned char *) ((unsigned long)(addr)))
+#define outb(b,addr) (*(volatile unsigned char *) ((unsigned long)(addr)) = (b))
+
+#ifdef RUNNINGFROMFLASH
+// This is where our image of interest is mapped to
+// when the jumbers are set for booting out of flash.
+// (flash part starts at address 0xbfC00000)
+#define srcAddr 0xbfC20000
+#else
+// This is where our image of interest is mapped to
+// when the jumbers are set for booting out of eprom.
+// (flash part starts at address 0xbf000000)
+#define srcAddr 0xbf020000
+#endif
+
+static int PortAddress(unsigned int channel, unsigned char reg);
+static void inline cons_hook(void);
+static void print_message(const char *string);
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void XferToRam(void)
+{
+	unsigned int temp;
+	void (*entry_point) (void);
+
+	cons_hook();
+
+	print_message("Copying image from Flash to Ram.\n");
+	for (temp = 0; temp < (0x100000 - 0x20000); temp = temp + 4) {
+		*(volatile unsigned int *) (temp + 0xa0400000) =
+		    *(volatile unsigned int *) (temp + srcAddr);
+		if (*(volatile unsigned int *) (temp + 0xa0400000) !=
+		    *(volatile unsigned int *) (temp + srcAddr)) {
+			print_message
+			    ("Error!: copy verification failed.\n");
+			break;
+		}
+	}
+
+	print_message("Now jumping to the code just xferred to ram.\n");
+	entry_point = (void *) 0x80400000;
+	entry_point();
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static int PortAddress(unsigned int channel, unsigned char reg)
+{
+	unsigned int channelOffset = 0x20;
+	unsigned int regDelta = 4;
+	return (port + (channel * channelOffset) + (reg * regDelta));
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static void cons_hook(void)
+{
+	register int comstat;
+	unsigned temp;
+	unsigned int channel = 1;	// Channel 1 is the main serial
+	// connector of the EVB64120A. Channel 0
+	// is the secondary serial port (typically
+	// the unsoldered connector of the board).
+
+	temp = *(unsigned int *) 0xb4000464;
+	*(unsigned int *) 0xb4000464 = 0xffff4f14;
+
+	// Set Baud Rate, baud=115K
+	outb(0x83, PortAddress(channel, UART_LCR));
+	outb(0x00, PortAddress(channel, UART_DLM));
+	outb(0x02, PortAddress(channel, UART_DLL));
+	outb(0x03, PortAddress(channel, UART_LCR));
+
+	comstat = inb(PortAddress(channel, UART_LSR));
+	comstat = inb(PortAddress(channel, UART_RX));
+	outb(0x00, PortAddress(channel, UART_IER));
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static void print_message(const char *string)
+{
+	register int count, loop;
+	/* Display Opening Message */
+	for (count = 0; string[count]; count++) {
+		if (string[count] == '\n') {
+			*(char *) 0xbd000020 = '\r';
+		}
+		*(char *) 0xbd000020 = string[count];
+		for (loop = 0; loop < 2000; loop++) {
+		}
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/dma.c linux/arch/mips/galileo-boards/ev64120/dma.c
--- linux.orig/arch/mips/galileo-boards/ev64120/dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/dma.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,168 @@
+/* DMA.C - DMA functions and definitions */
+
+/* Copyright Galileo Technology. */
+
+/*
+DESCRIPTION
+This file gives the user a complete interface to the powerful DMA engines,
+including functions for controling the priority mechanism.
+To fully understand the capabilities of the DMA engines please spare some 
+time to go trough the spec.
+*/
+
+/* includes */
+
+#ifdef __linux__
+#include <asm/galileo/evb64120A/core.h>
+#include <asm/galileo/evb64120A/dma.h>
+#else
+#include "Core.h"
+#include "DMA.h"
+#endif
+/********************************************************************
+* dmaCommand - Write a command to a DMA channel 
+*
+* Inputs: DMA_ENGINE channel - choosing one of the four engine.
+*         unsigned int command - The command to be written to the control register.
+* Returns: false if one of the parameters is erroneous else returns true. 
+*********************************************************************/
+
+bool dmaCommand(DMA_ENGINE channel, unsigned int command)
+{
+	if (channel > LAST_DMA_ENGINE)
+		return false;
+	GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command);
+	return true;
+}
+
+/********************************************************************
+* dmaTransfer - transfer data from sourceAddr to destAddr on DMA channel
+* Inputs:
+*   DMA_RECORED *nextRecoredPointer: If we are using chain mode DMA transfer,
+*   then this pointer should point to the next recored,otherwise it should be 
+*   NULL.
+*   VERY IMPORTANT !!! When using chain mode, the records must be 16 Bytes 
+*   aligned, the function will take care of that for you, but you need to 
+*   allocate one more record for that, meaning: if you are having 3 records ,
+*   declare 4 (see the example bellow) and start using the second one.
+*   Example:
+*   Performing a chain mode DMA transfer(Copy a 1/4 mega of data using 
+*   chain mode DMA):
+*    DMA_RECORED dmaRecoredArray[4];
+*    dmaRecoredArray[1].ByteCnt = _64KB;
+*    dmaRecoredArray[1].DestAdd = destAddress + _64KB;
+*    dmaRecoredArray[1].SrcAdd  = sourceAddress + _64KB;
+*    dmaRecoredArray[1].NextRecPtr = &dmaRecoredArray[2];
+*    dmaRecoredArray[2].ByteCnt = _64KB;
+*    dmaRecoredArray[2].DestAdd = destAddress + 2*_64KB;
+*    dmaRecoredArray[2].SrcAdd  = sourceAddress + 2*_64KB;
+*    dmaRecoredArray[2].NextRecPtr = &dmaRecoredArray[3];
+*    dmaRecoredArray[3].ByteCnt = _64KB;
+*    dmaRecoredArray[3].DestAdd = destAddress + 3*_64KB;
+*    dmaRecoredArray[3].SrcAdd  = sourceAddress + 3*_64KB;
+*    dmaRecoredArray[3].NextRecPtr = NULL;
+*    performCmDma(0,sourceAddress,destAddress,_64KB,PLAIN,WAIT_TO_END,
+*                            &dmaRecoredArray[1]);
+* Returns: NO_SUCH_CHANNEL if channel does not exist, CHANNEL_BUSY if channel
+*          is active and true if the transfer ended successfully
+*********************************************************************/
+
+DMA_STATUS dmaTransfer(DMA_ENGINE channel, unsigned int sourceAddr,
+		       unsigned int destAddr, unsigned int numOfBytes,
+		       unsigned int command,
+		       DMA_RECORED * nextRecoredPointer)
+{
+	unsigned int tempData, checkBits, alignmentOffset = 0;
+	DMA_RECORED *next = nextRecoredPointer;
+
+	if (channel > LAST_DMA_ENGINE)
+		return NO_SUCH_CHANNEL;
+	if (numOfBytes > 0xffff)
+		return GENERAL_ERROR;
+	if (isDmaChannelActive(channel))
+		return CHANNEL_BUSY;
+	if (next != NULL) {	/* case of chain Mode */
+		alignmentOffset = ((unsigned int) next % 16);
+	}
+	checkBits = command & 0x6000000;
+	if (checkBits == 0) {
+		while (next != NULL) {
+			WRITE_WORD((unsigned int) next - alignmentOffset,
+				   next->ByteCnt);
+			tempData = (unsigned int) next->SrcAdd;
+			WRITE_WORD((unsigned int) next + 4 -
+				   alignmentOffset, tempData & 0x5fffffff);
+			tempData = (unsigned int) next->DestAdd;
+			WRITE_WORD((unsigned int) next + 8 -
+				   alignmentOffset, tempData & 0x5fffffff);
+			tempData = (unsigned int) next->NextRecPtr;
+			WRITE_WORD((unsigned int) next + 12 -
+				   alignmentOffset,
+				   tempData & 0x5fffffff -
+				   alignmentOffset);
+			next = (DMA_RECORED *) tempData;
+			if (next == nextRecoredPointer)
+				next = NULL;
+		}
+	}
+	GT_REG_WRITE(CHANNEL0_DMA_BYTE_COUNT + channel * 4, numOfBytes);
+	tempData = sourceAddr;
+	GT_REG_WRITE(CHANNEL0_DMA_SOURCE_ADDRESS + channel * 4,
+		     tempData & 0x5fffffff);
+	tempData = destAddr;
+	GT_REG_WRITE(CHANNEL0_DMA_DESTINATION_ADDRESS + channel * 4,
+		     tempData & 0x5fffffff);
+	if (nextRecoredPointer != NULL) {
+		tempData =
+		    (unsigned int) nextRecoredPointer - alignmentOffset;
+		GT_REG_WRITE(CHANNEL0NEXT_RECORD_POINTER + 4 * channel,
+			     tempData & 0x5fffffff);
+		command = command | CHANNEL_ENABLE;
+	} else {
+		command = command | CHANNEL_ENABLE | NON_CHAIN_MOD;
+	}
+	/* Activate DMA engine By writting to dmaControlRegister */
+	GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command);
+
+	return DMA_OK;
+}
+
+/********************************************************************
+* isDmaChannelActive - check if channel is busy
+*
+* Inputs: channel number
+* RETURNS: True if the channel is busy, false otherwise.
+*********************************************************************/
+
+bool isDmaChannelActive(DMA_ENGINE channel)
+{
+	unsigned int data;
+
+	if (channel > LAST_DMA_ENGINE)
+		return false;
+	GT_REG_READ(CHANNEL0CONTROL + 4 * channel, &data);
+	if (data & DMA_ACTIVITY_STATUS)
+		return true;
+	else
+		return false;
+}
+
+
+/********************************************************************
+* changeDmaPriority - update the arbiter`s priority for channels 0-3 
+*
+* Inputs: priority  for channels 0-1, priority  for channels 2-3, 
+          priority for groups and other priority options   
+* RETURNS: false if one of the parameters is erroneous and true else
+*********************************************************************/
+
+bool changeDmaPriority(PRIO_CHAN_0_1 prio_01, PRIO_CHAN_2_3 prio_23,
+		       PRIO_GROUP prioGrp, PRIO_OPT prioOpt)
+{
+	unsigned int prioReg = 0;
+
+	prioReg = (prio_01 & 0x3) + ((prio_23 & 0x3) << 2) +
+	    ((prioGrp & 0x3) << 4) + (prioOpt << 6);
+	GT_REG_WRITE(ARBITER_CONTROL, prioReg);
+	return true;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/i2o.c linux/arch/mips/galileo-boards/ev64120/i2o.c
--- linux.orig/arch/mips/galileo-boards/ev64120/i2o.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/i2o.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,689 @@
+/* i2o.c - Drivers for the I2O */
+
+/* Copyright - Galileo technology. */
+
+/*includes*/
+
+#include <linux/module.h>
+
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/core.h>
+#include <asm/galileo-boards/evb64120A/i2o.h>
+#else
+#include "Core.h"
+#include "i2o.h"
+#endif
+
+/********************************************************************
+* getInBoundMessage - When the GT is configured for I2O support
+*                     it can receive a message from an agent on the pci bus.
+*                     This message is a 32 bit wide and can be read by
+*                     the CPU.
+*                     The messaging unit contains two sets of registers
+*                     so, actually it can receive a 64 bit message.
+* 
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: Data received from the remote agent.
+*********************************************************************/
+unsigned int getInBoundMessage(I2O_MESSAGE_REG messageRegNum)
+{
+	unsigned int regValue;
+
+	GT_REG_READ(INBOUND_MESSAGE_REGISTER0_CPU_SIDE + 4 * messageRegNum,
+		    &regValue);
+	return (regValue);
+}
+
+
+/********************************************************************
+* checkInboundIntAndClear - When a message is received an interrupt is 
+*                           generated, to enable polling instead the use of
+*                           an interrupt handler the user can use this fuction.
+*                           You will need to mask the incomming interrupt for
+*                           proper use.
+* 
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+*          false.
+*********************************************************************/
+bool checkInBoundIntAndClear(I2O_MESSAGE_REG messageRegNum)
+{
+	unsigned int regValue;
+
+	GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regValue);
+	/* clears bit 0 for message register 0 or bit 1 for message register 1 */
+	GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE,
+		     BIT1 * messageRegNum);
+	switch (messageRegNum) {
+	case MESSAGE_REG_0:
+		if (regValue & BIT0)
+			return true;
+		break;
+	case MESSAGE_REG_1:
+		if (regValue & BIT1)
+			return true;
+		break;
+	}
+	return false;
+}
+
+/********************************************************************
+* sendOutBoundMessage - When the GT is configured for I2O support
+*                     it can send a message to an agent on the pci bus.
+*                     This message is a 32 bit wide and can be read by
+*                     the PCI agent.
+*                     The messaging unit contains two sets of registers
+*                     so, actually it can send a 64 bit message.
+* 
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+*         unsigned int message - Message to be sent.   
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool sendOutBoundMessage(I2O_MESSAGE_REG messageRegNum,
+			 unsigned int message)
+{
+	GT_REG_WRITE(OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE +
+		     4 * messageRegNum, message);
+	return true;
+}
+
+/********************************************************************
+* checkOutboundInt - When the CPU sends a message to the Outbound
+*                    register it generates an interrupt which is refelcted on
+*                    the Outbound Interrupt cause register, the interrupt can
+*                    be cleard only by the PCI agent which read the message. 
+*                    After sending the message you can acknowledge it by
+*                    monitoring the corresponding bit in the cause register.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+*          false.
+*********************************************************************/
+bool outBoundMessageAcknowledge(I2O_MESSAGE_REG messageRegNum)
+{
+	unsigned int regValue;
+
+	GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regValue);
+	switch (messageRegNum) {
+	case MESSAGE_REG_0:
+		if (regValue & BIT0)
+			return true;
+		break;
+	case MESSAGE_REG_1:
+		if (regValue & BIT1)
+			return true;
+		break;
+	}
+	return false;
+}
+
+/********************************************************************
+* maskInBoundMessageInterrupt - Mask the inbound interrupt, when masking
+*                               the interrupt you can work in polling mode
+*                               using the checkInboundIntAndClear function. 
+* 
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool maskInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
+{
+	switch (messageRegNum) {
+	case MESSAGE_REG_0:
+		SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+			     BIT0);
+		break;
+	case MESSAGE_REG_1:
+		SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+			     BIT1);
+		break;
+	}
+	return true;
+}
+
+/********************************************************************
+* enableInBoundMessageInterrupt - unMask the inbound interrupt. 
+* 
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool enableInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
+{
+	switch (messageRegNum) {
+	case MESSAGE_REG_0:
+		RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+			       BIT0);
+		break;
+	case MESSAGE_REG_1:
+		RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+			       BIT1);
+		break;
+	}
+	return true;
+}
+
+/********************************************************************
+* maskOutboundMessageInterrupt - Mask the out bound interrupt, when doing so
+*                           the PCI agent needs to poll on the interrupt
+*                           cause register to monitor an incoming message. 
+* 
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool maskOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
+{
+	switch (messageRegNum) {
+	case MESSAGE_REG_0:
+		SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+			     BIT0);
+		break;
+	case MESSAGE_REG_1:
+		SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+			     BIT1);
+		break;
+	}
+	return true;
+}
+
+/********************************************************************
+* enableOutboundMessageInterrupt - Mask the out bound interrupt, when doing so
+*                           the PCI agent needs to poll on the interrupt
+*                           cause register to monitor an incoming message. 
+* 
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool enableOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
+{
+	switch (messageRegNum) {
+	case MESSAGE_REG_0:
+		RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+			       BIT0);
+		break;
+	case MESSAGE_REG_1:
+		RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+			       BIT1);
+		break;
+	}
+	return true;
+}
+
+/********************************************************************
+* initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the 
+*                       CPU generates a PCI interrupt (if it is not masked by
+*                       the Outbound interrupt Mask register)
+*                       Only the PCI agent which recieved the interrupt can
+*                       clear it, only after clearing all the bits the
+*                       interrupt will be de-asserted.
+* 
+* INPUTS: unsigned int data - Requested interrupt bits.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool initiateOutBoundDoorBellInt(unsigned int data)
+{
+	GT_REG_WRITE(OUTBOUND_DOORBELL_REGISTER_CPU_SIDE, data);
+	return true;
+}
+
+/********************************************************************
+* readInBoundDoorBellInt - Read the in bound door bell interrupt cause
+*                          register.
+* 
+* OUTPUT:  N/A.
+* RETURNS: The 32 bit interrupt cause register.
+*********************************************************************/
+unsigned int readInBoundDoorBellInt()
+{
+	unsigned int regData;
+	GT_REG_READ(INBOUND_DOORBELL_REGISTER_CPU_SIDE, &regData);
+	return regData;
+}
+
+/********************************************************************
+* clearInBoundDoorBellInt - An interrupt generated by a PCI agent through
+*                           the in bound door bell mechanisem can be cleared
+*                           only by the CPU. The interrupt will be de-asserted
+*                           only if all the bits which where set by the PCI
+*                           agent are cleared.
+* 
+* INPUTS:  unsigned int data - Bits to be cleared.
+* OUTPUT:  N/A.
+* RETURNS: true.
+*********************************************************************/
+bool clearInBoundDoorBellInt(unsigned int data)
+{
+	GT_REG_WRITE(INBOUND_DOORBELL_REGISTER_CPU_SIDE, data);
+	return true;
+}
+
+/********************************************************************
+* isInBoundDoorBellInterruptSet - Check if Inbound Doorbell Interrupt is set,
+*                                 can be used for polling mode.
+*
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+*          false.
+*********************************************************************/
+bool isInBoundDoorBellInterruptSet()
+{
+	unsigned int regData;
+
+	GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
+	return (regData & BIT2);
+}
+
+/********************************************************************
+* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is 
+*                                  set, can be used for acknowledging interrupt
+*                                  handling by the agent who recieived the
+*                                  interrupt. 
+* 
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+*          false.
+*********************************************************************/
+bool isOutBoundDoorBellInterruptSet()
+{
+	unsigned int regData;
+
+	GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
+	return (regData & BIT2);
+}
+
+/********************************************************************
+* maskInboundDoorBellInterrupt - Mask the Inbound Doorbell Interrupt.
+*
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true.
+*********************************************************************/
+bool maskInBoundDoorBellInterrupt()
+{
+	SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
+	return true;
+}
+
+/********************************************************************
+* enableInboundDoorBellInterrupt - unMask the Inbound Doorbell Interrupt.
+*
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true.
+*********************************************************************/
+bool enableInBoundDoorBellInterrupt()
+{
+	RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
+	return true;
+}
+
+/********************************************************************
+* maskOutboundDoorBellInterrupt - Mask the Outbound Doorbell Interrupt.
+*
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true.
+*********************************************************************/
+bool maskOutBoundDoorBellInterrupt()
+{
+	SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
+	return true;
+}
+
+/********************************************************************
+* enableOutboundDoorBellInterrupt - unMask the Outbound Doorbell Interrupt.
+*
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true.
+*********************************************************************/
+bool enableOutBoundDoorBellInterrupt()
+{
+	RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
+	return true;
+}
+
+/********************************************************************
+* circularQueueEnable - Initialize the I2O messaging mechanism.
+* 
+* INPUTS:   CIRCULE_QUEUE_SIZE cirQueSize - Bits 5:1 in the:
+*           Queue Control Register, Offset 0x50 (0x1c50).
+*           Defines the queues size (refer to the data sheet
+*           for more information)
+*          unsigned int queueBaseAddr - The base address for the first queue.
+*           The other queues base Address will be determined as follows:
+*           Inbound Free = queueBaseAddr
+*           Inbound Post = queueBaseAddr + cirQueSize
+*           Outbound Post = queueBaseAddr + cirQueSize
+*           
+* OUTPUT:  N/A.
+* RETURNS: true.
+*
+*  The Circular Queue Starting Addresses as written in the spec:
+*  ----------------------------------------
+*  |    Queue       |  Starting Address   |
+*  |----------------|---------------------|
+*  | Inbound Free   |       QBAR          |
+*  | Inbound Post   | QBAR + Queue Size   |
+*  | Outbound Post  | QBAR + 2*Queue Size |
+*  | Outbound Free  | QBAR + 3*Queue Size |
+*  ----------------------------------------
+*********************************************************************/
+bool circularQueueEnable(CIRCULAR_QUEUE_SIZE cirQueSize,
+			 unsigned int queueBaseAddr)
+{
+	unsigned int regData;
+
+	regData = BIT0 | (cirQueSize << 1);
+	/* Enable Queue Operation */
+	GT_REG_WRITE(QUEUE_CONTROL_REGISTER_CPU_SIDE, regData);
+	/* Writing The base Address for the 4 Queues */
+	GT_REG_WRITE(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, queueBaseAddr);
+	/* Update The Inbound Free Queue Base Address, offset=0 */
+	GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, 0);
+	GT_REG_WRITE(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, 0);
+	/* Update The Inbound Post Queue Base Address, offset=_16K*cirQueSize */
+	GT_REG_WRITE(INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
+		     _16K * cirQueSize);
+	GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
+		     _16K * cirQueSize);
+	/* Update The Outbound Post Queue Base Address, offset=2*_16K*cirQueSize */
+	GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
+		     2 * _16K * cirQueSize);
+	GT_REG_WRITE(OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
+		     2 * _16K * cirQueSize);
+	/* Update The Outbound Free Queue Base Address, offset=3*_16K*cirQueSize */
+	GT_REG_WRITE(OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+		     3 * _16K * cirQueSize);
+	GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+		     3 * _16K * cirQueSize);
+	return true;
+}
+
+/********************************************************************
+* inBoundPostQueuePop - Two actions are being taken upon pop: 
+*           1) Getting out the data from the Queue`s head.
+*           2) Increment the tail pointer in a cyclic way (The HEAD is
+*              incremented automaticaly by the GT) 
+*
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: Data pointed by tail.
+*********************************************************************/
+unsigned int inBoundPostQueuePop()
+{
+	unsigned int tailAddrPointer;
+	unsigned int data;
+	unsigned int cirQueSize;
+	unsigned int qBar;
+	unsigned int inBoundPostQbase;
+
+	/* Gets the Inbound Post TAIL pointer */
+	GT_REG_READ(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
+		    &tailAddrPointer);
+	/* Gets the Data From the pointer Address */
+	READ_WORD(tailAddrPointer, &data);
+	/* incrementing head process: */
+	/* Gets the fifo's base Address */
+	GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
+	qBar = qBar & 0xfff00000;
+	/* Gets the fifo's size */
+	GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
+	cirQueSize = 0x1f && (cirQueSize >> 1);
+	/* calculating The Inbound Post Queue Base Address */
+	inBoundPostQbase = qBar + 1 * cirQueSize * _16K;
+	/* incrementing Inbound Post queue TAIL in a cyclic loop */
+	tailAddrPointer = inBoundPostQbase + ((tailAddrPointer + 4) %
+					      (_16K * cirQueSize));
+	/* updating the pointer back to INBOUND_POST_TAIL_POINTER_REGISTER */
+	GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
+		     tailAddrPointer);
+	return data;
+}
+
+/********************************************************************
+* isInBoundPostQueueInterruptSet - Check if in bound interrupt is set.
+*                                  can be used for polling mode.
+*
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+*          false.
+*********************************************************************/
+bool isInBoundPostQueueInterruptSet()
+{
+	unsigned int regData;
+
+	GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
+	return (regData & BIT4);	/* if set return '1' (true), else '0' (false) */
+}
+
+/********************************************************************
+* clearInBoundPostQueueInterrupt - Clears the Post queue interrupt.
+* 
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true.
+*********************************************************************/
+bool clearInBoundPostQueueInterrupt()
+{
+	GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, BIT4);
+	return true;
+}
+
+/********************************************************************
+* maskInBoundPostQueueInterrupt - Mask the inbound interrupt, when masking
+*                                 the interrupt you can work in polling mode.
+*
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: 
+*********************************************************************/
+void maskInBoundPostQueueInterrupt()
+{
+	unsigned int regData;
+
+	GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, &regData);
+	GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+		     regData | BIT4);
+
+}
+
+/********************************************************************
+* enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new
+*                                   message from the PCI agent.
+* 
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS:
+*********************************************************************/
+void enableInBoundPostQueueInterrupt()
+{
+	unsigned int regData;
+
+	GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, &regData);
+	GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+		     regData & 0xfffffffb);
+}
+
+/********************************************************************
+* inBoundFreeQueuePush - Two actions are being taken upon push: 
+*           1) Place the user`s data on the Queue`s head.
+*           2) Increment the haed pointer in a cyclic way (The tail is
+*              decremented automaticaly by the GT)
+* 
+* INPUTS:  unsigned int data - Data to be placed in the queue.
+* OUTPUT:  N/A.
+* RETURNS: true.
+*********************************************************************/
+bool inBoundFreeQueuePush(unsigned int data)
+{
+	unsigned int headPointer;
+	unsigned int cirQueSize;
+	unsigned int qBar;
+	unsigned int inBoundFreeQbase;
+
+	GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+		    &headPointer);
+	/* placing the data in the queue */
+	WRITE_WORD(headPointer, data);
+	/* incrementing head process: */
+	/* Gets the fifo's base Address */
+	GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
+	qBar = qBar & 0xfff00000;
+	/* Gets the fifo's size */
+	GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
+	cirQueSize = 0x1f && (cirQueSize >> 1);
+	/* calculating The Inbound Free Queue Base Address */
+	inBoundFreeQbase = qBar;
+	/* incrementing Inbound Free queue HEAD in a cyclic loop */
+	headPointer =
+	    inBoundFreeQbase + ((headPointer + 4) % (_16K * cirQueSize));
+	/* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */
+	GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+		     headPointer);
+	return true;
+}
+
+/********************************************************************
+* isInBoundFreeQueueEmpty - Check if Inbound Free Queue Empty.
+*                           Can be used for acknowledging the messages
+*                           being sent by us to the PCI agent.
+* 
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true if the queue is empty , otherwise false.
+*********************************************************************/
+bool isInBoundFreeQueueEmpty()
+{
+	unsigned int inBoundFreeQueHead;
+	unsigned int inBoundFreeQueTail;
+
+	GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+		    &inBoundFreeQueHead);
+	GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+		    &inBoundFreeQueTail);
+	if (inBoundFreeQueHead == inBoundFreeQueTail) {
+		return true;
+	} else
+		return false;
+}
+
+/********************************************************************
+* outBoundPostQueuePush  - Two actions are being taken upon push: 
+*           1) Place the user`s data on the Queue`s head.
+*           2) Increment the haed pointer in a cyclic way (The tail is
+*              decremented automaticaly by the GT when the Agent on the
+*              PCI have read data from the Outbound Port).
+* 
+* INPUTS:  unsigned int data - Data to be placed in the queue`s head.
+* OUTPUT:  N/A.
+* RETURNS: true.
+*********************************************************************/
+bool outBoundPostQueuePush(unsigned int data)
+{
+	unsigned int headPointer;
+	unsigned int cirQueSize;
+	unsigned int qBar;
+	unsigned int outBoundPostQbase;
+
+	GT_REG_READ(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
+		    &headPointer);
+	/* placing the data in the queue (where the head point to..) */
+	WRITE_WORD(headPointer, data);
+	/* incrementing head process: */
+	/* Gets the fifo's base Address */
+	GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
+	qBar = qBar & 0xfff00000;
+	/* Gets the fifo's size */
+	GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
+	cirQueSize = 0x1f && (cirQueSize >> 1);
+	/* calculating The Outbound Post Queue Base Address */
+	outBoundPostQbase = qBar + 2 * cirQueSize * _16K;
+	/* incrementing Outbound Post queue in a cyclic loop */
+	headPointer =
+	    outBoundPostQbase + ((headPointer + 4) % (_16K * cirQueSize));
+	/* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */
+	GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
+		     headPointer);
+	return true;
+}
+
+/********************************************************************
+* isOutBoundPostQueueEmpty - Check if Outbound Post Queue Empty.
+*                            Can be used for acknowledging the messages
+*                            being sent by us to the PCI agent.
+* 
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: true if the queue is empty , otherwise false.
+*********************************************************************/
+bool isOutBoundPostQueueEmpty()
+{
+	unsigned int outBoundPostQueHead;
+	unsigned int outBoundPostQueTail;
+
+	GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+		    &outBoundPostQueHead);
+	GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+		    &outBoundPostQueTail);
+	if (outBoundPostQueHead == outBoundPostQueTail) {
+		return true;
+	} else
+		return false;
+}
+
+/********************************************************************
+* outBoundFreeQueuePop - Two actions are being taken upon pop: 
+*           1) Getting out the data from the Queue`s head.
+*           2) Increment the tail pointer in a cyclic way (The HEAD is
+*              incremented automaticaly by the GT)
+* 
+* INPUTS:  N/A.
+* OUTPUT:  N/A.
+* RETURNS: Data pointed by tail.
+*********************************************************************/
+unsigned int outBoundFreeQueuePop()
+{
+	unsigned int tailAddrPointer;
+	unsigned int data;
+	unsigned int cirQueSize;
+	unsigned int qBar;
+	unsigned int outBoundFreeQbase;
+
+	/* Gets the Inbound Post TAIL pointer */
+	GT_REG_READ(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+		    &tailAddrPointer);
+	/* Gets the Data From the pointer Address */
+	READ_WORD(tailAddrPointer, &data);
+	/* incrementing head process: */
+	/* Gets the fifo's base Address */
+	GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
+	qBar = qBar & 0xfff00000;
+	/* Gets the fifo's size */
+	GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
+	cirQueSize = 0x1f && (cirQueSize >> 1);
+	/* calculating The Inbound Post Queue Base Address */
+	outBoundFreeQbase = qBar + 3 * cirQueSize * _16K;
+	/* incrementing Outbound Free queue TAlL in a cyclic loop */
+	tailAddrPointer = outBoundFreeQbase + ((tailAddrPointer + 4) %
+					       (_16K * cirQueSize));
+	/* updating the pointer back to OUTBOUND_FREE_TAIL_POINTER_REGISTER */
+	GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+		     tailAddrPointer);
+	return data;
+}
+
+
+EXPORT_SYMBOL(isInBoundDoorBellInterruptSet);
+EXPORT_SYMBOL(initiateOutBoundDoorBellInt);
+EXPORT_SYMBOL(clearInBoundDoorBellInt);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/int-handler.S linux/arch/mips/galileo-boards/ev64120/int-handler.S
--- linux.orig/arch/mips/galileo-boards/ev64120/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/int-handler.S	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,113 @@
+/*
+ * int-handler.S
+ *
+ * Based on the cobalt handler.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * galileo_handle_int -
+ *      We check for the timer first, then check PCI ints A and D.
+ *      Then check for serial IRQ and fall through.
+ */
+		.align	5
+		.set	reorder
+		.set	noat
+		NESTED(galileo_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0,CP0_CAUSE  
+		mfc0	t2,CP0_STATUS
+
+		and	t0,t2
+        
+		andi	t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */
+		bnez	t1,ll_galileo_irq
+		andi	t1,t0,STATUSF_IP2 /* int0 hardware line */
+		bnez	t1,ll_pci_intA
+		andi	t1,t0,STATUSF_IP5 /* int3 hardware line */
+		bnez	t1,ll_pci_intD
+		andi	t1,t0,STATUSF_IP6 /* int4 hardware line */
+		bnez	t1,ll_serial_irq
+		andi	t1,t0,STATUSF_IP7 /* compare int */
+		bnez	t1,ll_compare_irq
+		nop
+
+    /* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(galileo_handle_int)
+	
+
+		.align	5
+		.set	reorder
+ll_galileo_irq:
+		li	a0,4
+		move	a1,sp
+		jal	do_IRQ
+		nop
+		j	ret_from_irq
+		nop
+
+		.align	5
+		.set	reorder
+ll_compare_irq:
+		li 	a0,7	
+		move	a1,sp
+		jal	do_IRQ
+		nop
+		j	ret_from_irq
+		nop
+
+		.align	5
+		.set	reorder
+ll_pci_intA:
+		move	a0,sp
+		jal	pci_intA
+		nop
+		j	ret_from_irq
+		nop
+
+#if 0
+		.align	5
+		.set	reorder
+ll_pci_intB:	
+		move 	a0,sp
+		jal	pci_intB
+		nop
+		j	ret_from_irq
+		nop
+
+		.align	5
+		.set	reorder
+ll_pci_intC:	
+		move 	a0,sp
+		jal	pci_intC
+		nop
+		j	ret_from_irq
+		nop
+#endif
+        
+		.align	5
+		.set	reorder
+ll_pci_intD:
+		move 	a0,sp
+		jal	pci_intD
+		nop
+		j	ret_from_irq
+		nop
+	
+		.align	5
+		.set	reorder
+ll_serial_irq:	
+		li	a0,6
+		move	a1,sp
+		jal	do_IRQ
+		nop
+		j	ret_from_irq
+		nop
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/irq-handler.c linux/arch/mips/galileo-boards/ev64120/irq-handler.c
--- linux.orig/arch/mips/galileo-boards/ev64120/irq-handler.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/irq-handler.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,270 @@
+/*
+ * Galileo Technology chip interrupt handler
+ *
+ *  Modified by RidgeRun, Inc.
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <asm/gt64120.h>
+#include <asm/galileo-boards/ev64120.h>
+#include <asm/galileo-boards/ev64120int.h>
+
+/*
+ * These are interrupt handlers for the GT on-chip interrupts.  They all come
+ * in to the MIPS on a single interrupt line, and have to be handled and ack'ed
+ * differently than other MIPS interrupts.
+ */
+
+#if CURRENTLY_UNUSED
+
+struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
+
+/*
+ * hook_irq_handler
+ *
+ * Hooks IRQ handler to the system. When the system is interrupted
+ * the interrupt service routine is called.
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters 
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. 
+ * bit_num   - Indicates which bit number in the cause register
+ * isr_ptr   - Pointer to the interrupt service routine
+ *
+ * Outputs :
+ */
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
+{
+	irq_handlers[int_cause][bit_num].routine = isr_ptr;
+}
+
+
+/*
+ * enable_galileo_irq
+ *
+ * Enables the IRQ on Galileo Chip
+ *
+ * Inputs :
+ * int_cause -  The interrupt cause number. In EVB64120 two parameters 
+ *            are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ *
+ * Outputs :
+ * 1 if succesful, 0 if failure
+ */
+int enable_galileo_irq(int int_cause, int bit_num)
+{
+	if (int_cause == INT_CAUSE_MAIN)
+		SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
+	else if (int_cause == INT_CAUSE_HIGH)
+		SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+			     (1 << bit_num));
+	else
+		return 0;
+	return 1;
+}
+
+/*
+ * disable_galileo_irq
+ *
+ * Disables the IRQ on Galileo Chip
+ *
+ * Inputs :
+ * int_cause -  The interrupt cause number. In EVB64120 two parameters 
+ *            are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ *
+ * Outputs :
+ * 1 if succesful, 0 if failure
+ */
+int disable_galileo_irq(int int_cause, int bit_num)
+{
+	if (int_cause == INT_CAUSE_MAIN)
+		RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
+			       (1 << bit_num));
+	else if (int_cause == INT_CAUSE_HIGH)
+		RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+			       (1 << bit_num));
+	else
+		return 0;
+	return 1;
+}
+
+#endif				/*  UNUSED  */
+
+/*
+ * galileo_irq -
+ *
+ * Interrupt handler for interrupts coming from the Galileo chip.
+ * It could be timer interrupt, built in ethernet ports etc...
+ *
+ * Inputs :
+ *
+ * Outputs :
+ *
+ */
+static void galileo_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int irq_src, int_high_src, irq_src_mask,
+	    int_high_src_mask;
+	int handled;
+	unsigned int count;
+	static int counter = 0;
+
+	GT_READ(GT_INTRCAUSE_OFS, &irq_src);
+	GT_READ(GT_INTRMASK_OFS, &irq_src_mask);
+	GT_READ(GT_HINTRCAUSE_OFS, &int_high_src);
+	GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask);
+	irq_src = irq_src & irq_src_mask;
+	int_high_src = int_high_src & int_high_src_mask;
+
+	handled = 0;
+
+	/* Execute all interrupt handlers */
+	/* Check for timer interrupt */
+	if (irq_src & 0x00000800) {
+		handled = 1;
+		irq_src &= ~0x00000800;
+		//    RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8);
+		do_timer(regs);
+	}
+
+	if (irq_src) {
+		printk(KERN_INFO
+		       "Other Galileo interrupt received irq_src %x\n",
+		       irq_src);
+#if CURRENTLY_UNUSED
+		for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) {
+			if (irq_src & (1 << count)) {
+				if (irq_handlers[INT_CAUSE_MAIN][count].
+				    routine) {
+					queue_task(&irq_handlers
+						   [INT_CAUSE_MAIN][count],
+						   &tq_immediate);
+					mark_bh(IMMEDIATE_BH);
+					handled = 1;
+				}
+			}
+		}
+#endif				/*  UNUSED  */
+	}
+	GT_WRITE(GT_INTRCAUSE_OFS, 0);
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0);
+
+#undef GALILEO_I2O
+#ifdef GALILEO_I2O
+	/*
+	   Future I2O support.  We currently attach I2O interrupt handlers to the
+	   Galileo interrupt (int 4) and handle them in do_IRQ.
+	 */
+	if (isInBoundDoorBellInterruptSet()) {
+		printk(KERN_INFO "I2O doorbell interrupt received.\n");
+		handled = 1;
+	}
+
+	if (isInBoundPostQueueInterruptSet()) {
+		printk(KERN_INFO "I2O Queue interrupt received.\n");
+		handled = 1;
+	}
+
+	/*
+	   This normally would be outside of the ifdef, but since
+	   we're handling I2O outside of this handler, this
+	   printk shows up every time we get a valid I2O
+	   interrupt.  So turn this off for now.
+	 */
+	if (handled == 0) {
+		if (counter < 50) {
+			printk("Spurious Galileo interrupt...\n");
+			counter++;
+		}
+	}
+#endif
+}
+
+/*
+ * galileo_time_init -
+ *
+ * Initializes timer using galileo's built in timer.
+ *
+ *
+ * Inputs :
+ * irq - number of irq to be used by the timer
+ *
+ * Outpus :
+ *
+ */
+#ifdef CONFIG_SYSCLK_100
+#define Sys_clock (100 * 1000000)	// 100 MHz
+#endif
+#ifdef CONFIG_SYSCLK_83
+#define Sys_clock (83.333 * 1000000)	// 83.333 MHz
+#endif
+#ifdef CONFIG_SYSCLK_75
+#define Sys_clock (75 * 1000000)	// 75 MHz
+#endif
+
+/*
+ * This will ignore the standard MIPS timer interrupt handler that is passed
+ * in as *irq (=irq0 in ../kernel/time.c).  We will do our own timer interrupt
+ * handling.
+ */
+void galileo_time_init(struct irqaction *irq)
+{
+	extern irq_desc_t irq_desc[NR_IRQS];
+	static struct irqaction timer;
+
+	/* Disable timer first */
+	GT_WRITE(GT_TC_CONTROL_OFS, 0);
+	/* Load timer value for 100 Hz */
+	GT_WRITE(GT_TC3_OFS, Sys_clock / 100);
+
+	/*
+	 * Create the IRQ structure entry for the timer.  Since we're too early
+	 * in the boot process to use the "request_irq()" call, we'll hard-code
+	 * the values to the correct interrupt line.
+	 */
+	timer.handler = &galileo_irq;
+	timer.flags = SA_SHIRQ;
+	timer.name = "timer";
+	timer.dev_id = NULL;
+	timer.next = NULL;
+	timer.mask = 0;
+	irq_desc[TIMER].action = &timer;
+
+	/* Enable timer ints */
+	GT_WRITE(GT_TC_CONTROL_OFS, 0xc0);
+	/* clear Cause register first */
+	GT_WRITE(GT_INTRCAUSE_OFS, 0x0);
+	/* Unmask timer int */
+	GT_WRITE(GT_INTRMASK_OFS, 0x800);
+	/* Clear High int register */
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0x0);
+	/* Mask All interrupts at High cause interrupt */
+	GT_WRITE(GT_HINTRMASK_OFS, 0x0);
+
+}
+
+void galileo_irq_init(void)
+{
+	int i, j;
+
+#if CURRENTLY_UNUSED
+	/* Reset irq handlers pointers to NULL */
+	for (i = 0; i < MAX_CAUSE_REGS; i++) {
+		for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
+			irq_handlers[i][j].next = NULL;
+			irq_handlers[i][j].sync = 0;
+			irq_handlers[i][j].routine = NULL;
+			irq_handlers[i][j].data = NULL;
+		}
+	}
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/irq.c linux/arch/mips/galileo-boards/ev64120/irq.c
--- linux.orig/arch/mips/galileo-boards/ev64120/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/irq.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,456 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Code to handle irqs on GT64120A boards
+ *  Derived from mips/orion and Cort <cort@fsmlabs.com>
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/galileo-boards/ev64120int.h>
+
+#undef IRQ_DEBUG
+
+#ifdef IRQ_DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+
+asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
+
+#define MAX_AGENTS_PER_INT 21	/*  Random number  */
+unsigned char pci_int_irq[MAX_AGENTS_PER_INT];
+static int max_interrupts = 0;
+
+/*  Duplicate interrupt handlers.  */
+/********************************************************************
+ *pci_int(A/B/C/D) -
+ *	
+ *Calls all the handlers connected to PCI interrupt A/B/C/D
+ *
+ *Inputs :
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+asmlinkage __inline__ void pci_intA(struct pt_regs *regs)
+{
+	unsigned int count = 0;
+	DBG(KERN_INFO "pci_intA, max_interrupts %d\n", max_interrupts);
+	for (count = 0; count < max_interrupts; count++) {
+		do_IRQ(pci_int_irq[count], regs);
+	}
+}
+
+asmlinkage __inline__ void pci_intD(struct pt_regs *regs)
+{
+	unsigned int count = 0;
+	DBG(KERN_INFO "pci_intD, max_interrupts %d\n", max_interrupts);
+	for (count = 0; count < max_interrupts; count++) {
+		do_IRQ(pci_int_irq[count], regs);
+	}
+}
+
+
+/* Function for careful CP0 interrupt mask access */
+static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
+{
+	unsigned long status = read_32bit_cp0_register(CP0_STATUS);
+	DBG(KERN_INFO "modify_cp0_intmask clr %x, set %x\n", clr_mask,
+	    set_mask);
+	DBG(KERN_INFO "modify_cp0_intmask status %x\n", status);
+	status &= ~((clr_mask & 0xFF) << 8);
+	status |= (set_mask & 0xFF) << 8;
+	DBG(KERN_INFO "modify_cp0_intmask status %x\n", status);
+	write_32bit_cp0_register(CP0_STATUS, status);
+}
+
+static inline void mask_irq(unsigned int irq_nr)
+{
+	modify_cp0_intmask(irq_nr, 0);
+}
+
+static inline void unmask_irq(unsigned int irq_nr)
+{
+	modify_cp0_intmask(0, irq_nr);
+}
+
+void disable_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	DBG(KERN_INFO "disable_irq, irq %d\n", irq_nr);
+	save_and_cli(flags);
+	if (irq_nr >= 8) {	// All PCI interrupts are on line 5 or 2
+		mask_irq(9 << 2);
+	} else {
+		mask_irq(1 << irq_nr);
+	}
+	restore_flags(flags);
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	DBG(KERN_INFO "enable_irq, irq %d\n", irq_nr);
+	save_and_cli(flags);
+	if (irq_nr >= 8) {	// All PCI interrupts are on line 5 or 2
+		DBG(KERN_INFO __FUNCTION__ " pci interrupt %d\n", irq_nr);
+		unmask_irq(9 << 2);
+	} else {
+		DBG(KERN_INFO __FUNCTION__ " interrupt set mask %d\n",
+		    1 << irq_nr);
+		unmask_irq(1 << irq_nr);
+	}
+	restore_flags(flags);
+}
+
+/*
+ * Generic no controller code
+ */
+
+static void no_irq_enable_disable(unsigned int irq)
+{
+}
+static unsigned int no_irq_startup(unsigned int irq)
+{
+	return 0;
+}
+
+#if 0
+static void no_irq_ack(unsigned int irq)
+{
+	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
+}
+#endif
+
+struct hw_interrupt_type no_irq_type = {
+	typename:"none",
+	startup:no_irq_startup,
+	shutdown:no_irq_enable_disable,
+	enable:no_irq_enable_disable,
+	disable:no_irq_enable_disable,
+	ack:NULL,
+	end:no_irq_enable_disable,
+};
+
+//      ack:            no_irq_ack,                re-enable later -- SKJ  
+
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS];
+
+atomic_t irq_err_count;
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0, j;
+	struct irqaction *action;
+
+	len += sprintf(buf + len, "           ");
+	for (j = 0; j < smp_num_cpus; j++)
+		len += sprintf(buf + len, "CPU%d       ", j);
+	*(char *) (buf + len++) = '\n';
+
+	for (i = 0; i < NR_IRQS; i++) {
+		action = irq_desc[i].action;
+		if (!action || !action->handler)
+			continue;
+		len += sprintf(buf + len, "%3d: ", i);
+		len += sprintf(buf + len, "%10u ", kstat_irqs(i));
+		if (irq_desc[i].handler)
+			len +=
+			    sprintf(buf + len, " %s ",
+				    irq_desc[i].handler->typename);
+		else
+			len += sprintf(buf + len, "  None      ");
+		len += sprintf(buf + len, "    %s", action->name);
+		for (action = action->next; action; action = action->next) {
+			len += sprintf(buf + len, ", %s", action->name);
+		}
+		len += sprintf(buf + len, "\n");
+	}
+	len += sprintf(buf + len, "BAD: %10lu\n", atomic_read(&irq_err_count));
+	return len;
+}
+
+asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
+{
+	struct irqaction *action;
+	int cpu;
+
+#ifdef IRQ_DEBUG
+	if (irq != TIMER)
+		DBG(KERN_INFO __FUNCTION__ " irq = %d\n", irq);
+	if (irq != TIMER)
+		DBG(KERN_INFO "cause register = %x\n",
+		    read_32bit_cp0_register(CP0_CAUSE));
+	if (irq != TIMER)
+		DBG(KERN_INFO "status register = %x\n",
+		    read_32bit_cp0_register(CP0_STATUS));
+#endif
+
+	cpu = smp_processor_id();
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+
+	if (irq_desc[irq].handler->ack) {
+		irq_desc[irq].handler->ack(irq);
+	}
+
+	disable_irq(irq);
+
+	action = irq_desc[irq].action;
+	if (action && action->handler) {
+#ifdef IRQ_DEBUG
+		if (irq != TIMER)
+			DBG(KERN_INFO
+			    "rr: irq %d action %p and handler %p\n", irq,
+			    action, action->handler);
+#endif
+		if (!(action->flags & SA_INTERRUPT))
+			__sti();
+		do {
+			action->handler(irq, action->dev_id, regs);
+			action = action->next;
+		} while (action);
+		__cli();
+		if (irq_desc[irq].handler) {
+			if (irq_desc[irq].handler->end)
+				irq_desc[irq].handler->end(irq);
+			else if (irq_desc[irq].handler->enable)
+				irq_desc[irq].handler->enable(irq);
+		}
+	}
+
+	enable_irq(irq);
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+
+	/* unmasking and bottom half handling is done magically for us. */
+}
+
+int request_irq(unsigned int irq,
+		void (*handler) (int, void *, struct pt_regs *),
+		unsigned long irqflags, const char *devname, void *dev_id)
+{
+	struct irqaction *old, **p, *action;
+	unsigned long flags;
+
+	DBG(KERN_INFO "rr:dev %s irq %d handler %x\n", devname, irq,
+	    handler);
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+
+	action = (struct irqaction *)
+	    kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->dev_id = dev_id;
+	action->next = NULL;
+
+	save_flags(flags);
+	cli();
+
+	p = &irq_desc[irq].action;
+
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & action->flags & SA_SHIRQ))
+			return -EBUSY;
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+	}
+	*p = action;
+
+	restore_flags(flags);
+	if (irq >= 8) {
+		DBG(KERN_INFO "request_irq, max_interrupts %d\n",
+		    max_interrupts);
+		pci_int_irq[max_interrupts++] = irq;	// NOTE:  Add error-handling if > max
+	}
+	enable_irq(irq);
+	return 0;
+}
+
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction *p, *old = NULL;
+	unsigned long flags;
+	int count, tmp, removed = 0;
+
+	for (p = irq_desc[irq].action; p != NULL; old = p, p = p->next) {
+		/* Found the IRQ, is it the correct dev_id?  */
+		if (dev_id == p->dev_id) {
+			save_flags(flags);
+			cli();
+
+			// remove link from list
+			if (old)
+				old->next = p->next;
+			else
+				irq_desc[irq].action = p->next;
+
+			restore_flags(flags);
+			kfree(p);
+			removed = 1;
+			break;
+		}
+	}
+
+	/*
+	   Remove PCI interrupts from the pci_int_irq list.  Make sure
+	   that some handler was removed before decrementing max_interrupts.
+	 */
+	if ((irq >= 8) && (removed)) {
+		for (count = 0; count < max_interrupts; count++) {
+			if (pci_int_irq[count] == irq) {
+				for (tmp = count; tmp < max_interrupts;
+				     tmp++) {
+					pci_int_irq[tmp] =
+					    pci_int_irq[tmp + 1];
+				}
+			}
+		}
+		max_interrupts--;
+		DBG(KERN_INFO "free_irq, max_interrupts %d\n",
+		    max_interrupts);
+	}
+}
+
+unsigned long probe_irq_on(void)
+{
+	printk(KERN_INFO "probe_irq_on\n");
+	return 0;
+}
+
+int probe_irq_off(unsigned long irqs)
+{
+	printk(KERN_INFO "probe_irq_off\n");
+	return 0;
+}
+
+/********************************************************************
+ *galileo_irq_setup -
+ *
+ *Initializes CPU interrupts
+ *
+ *
+ *Inputs :
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+void galileo_irq_setup(void)
+{
+	extern asmlinkage void galileo_handle_int(void);
+	extern void galileo_irq_init(void);
+
+	DBG(KERN_INFO "rr: galileo_irq_setup entry\n");
+
+	galileo_irq_init();
+
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 */
+	clear_cp0_status(ST0_IM);
+
+	/* Sets the exception_handler array. */
+	set_except_vector(0, galileo_handle_int);
+
+	cli();
+
+	/*
+	 * Enable timer.  Other interrupts will be enabled as they are
+	 * registered.
+	 */
+	set_cp0_status(IE_IRQ2);
+
+
+#ifdef CONFIG_REMOTE_DEBUG
+	{
+		extern int DEBUG_CHANNEL;
+		serial_init(DEBUG_CHANNEL);
+		serial_set(DEBUG_CHANNEL, 115200);
+		set_debug_traps();
+		breakpoint();	/* you may move this line to whereever you want :-) */
+	}
+#endif
+}
+
+void init_irq_proc(void)
+{
+	/* Nothing, for now.  */
+}
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	DBG(KERN_INFO "rr:init_IRQ\n");
+
+	/*  Let's initialize our IRQ descriptors  */
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status = 0;
+		irq_desc[i].handler = &no_irq_type;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 0;
+		irq_desc[i].lock = SPIN_LOCK_UNLOCKED;
+	}
+
+	galileo_irq_setup();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/pci_bios.c linux/arch/mips/galileo-boards/ev64120/pci_bios.c
--- linux.orig/arch/mips/galileo-boards/ev64120/pci_bios.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/pci_bios.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,1236 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Galileo Evaluation Boards PCI support.
+ *
+ * The general-purpose functions to read/write and configure the GT64120A's
+ * PCI registers (function names start with pci0 or pci1) are either direct
+ * copies of functions written by Galileo Technology, or are modifications
+ * of their functions to work with Linux 2.4 vs Linux 2.2.  These functions
+ * are Copyright - Galileo Technology.
+ *
+ * Other functions are derived from other MIPS PCI implementations, or were
+ * written by RidgeRun, Inc,  Copyright (C) 2000 RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/galileo-boards/ev64120.h>
+#include <asm/gt64120.h>
+
+#include <linux/init.h>
+
+#undef PCI_DEBUG
+
+#ifdef PCI_DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#ifdef CONFIG_PCI
+
+#define SELF 0
+
+/*
+ * These functions and structures provide the BIOS scan and mapping of the PCI
+ * devices.
+ */
+
+#define MAX_PCI_DEVS 10
+
+struct pci_device {
+	u32 slot;
+	u32 BARtype[6];
+	u32 BARsize[6];
+};
+
+static void __init scan_and_initialize_pci(void);
+static u32 __init scan_pci_bus(struct pci_device *pci_devices);
+static void __init allocate_pci_space(struct pci_device *pci_devices);
+
+static void __init galileo_pcibios_fixup_bus(struct pci_bus *bus);
+
+/*
+ * The functions that actually read and write to the controller.
+ * Copied from or modified from Galileo Technology code.
+ */
+static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device);
+static void pci0WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data);
+static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device);
+static void pci1WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data);
+
+static void pci0MapIOspace(unsigned int pci0IoBase,
+			   unsigned int pci0IoLength);
+static void pci1MapIOspace(unsigned int pci1IoBase,
+			   unsigned int pci1IoLength);
+static void pci0MapMemory0space(unsigned int pci0Mem0Base,
+				unsigned int pci0Mem0Length);
+static void pci1MapMemory0space(unsigned int pci1Mem0Base,
+				unsigned int pci1Mem0Length);
+static void pci0MapMemory1space(unsigned int pci0Mem1Base,
+				unsigned int pci0Mem1Length);
+static void pci1MapMemory1space(unsigned int pci1Mem1Base,
+				unsigned int pci1Mem1Length);
+static unsigned int pci0GetIOspaceBase(void);
+static unsigned int pci0GetIOspaceSize(void);
+static unsigned int pci0GetMemory0Base(void);
+static unsigned int pci0GetMemory0Size(void);
+static unsigned int pci0GetMemory1Base(void);
+static unsigned int pci0GetMemory1Size(void);
+static unsigned int pci1GetIOspaceBase(void);
+static unsigned int pci1GetIOspaceSize(void);
+static unsigned int pci1GetMemory0Base(void);
+static unsigned int pci1GetMemory0Size(void);
+static unsigned int pci1GetMemory1Base(void);
+static unsigned int pci1GetMemory1Size(void);
+
+
+/*  Functions to implement "pci ops"  */
+static int galileo_pcibios_read_config_word(struct pci_dev *dev,
+					    int offset, u16 * val);
+static int galileo_pcibios_read_config_byte(struct pci_dev *dev,
+					    int offset, u8 * val);
+static int galileo_pcibios_read_config_dword(struct pci_dev *dev,
+					     int offset, u32 * val);
+static int galileo_pcibios_write_config_byte(struct pci_dev *dev,
+					     int offset, u8 val);
+static int galileo_pcibios_write_config_word(struct pci_dev *dev,
+					     int offset, u16 val);
+static int galileo_pcibios_write_config_dword(struct pci_dev *dev,
+					      int offset, u32 val);
+static void galileo_pcibios_set_master(struct pci_dev *dev);
+
+/*
+ * General-purpose PCI functions.
+ */
+
+/*
+ * pci0MapIOspace - Maps PCI0 IO space for the master.
+ * Inputs: base and length of pci0Io
+ */
+static void pci0MapIOspace(unsigned int pci0IoBase, unsigned int pci0IoLength)
+{
+	unsigned int pci0IoTop =
+	    (unsigned int) (pci0IoBase + pci0IoLength);
+
+	if (pci0IoLength == 0)
+		pci0IoTop++;
+
+	pci0IoBase = (unsigned int) (pci0IoBase >> 21);
+	pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21);
+	GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase);
+	GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop);
+}
+
+/*
+ * pci1MapIOspace - Maps PCI1 IO space for the master.
+ * Inputs: base and length of pci1Io
+ */
+
+static void pci1MapIOspace(unsigned int pci1IoBase,
+			   unsigned int pci1IoLength)
+{
+	unsigned int pci1IoTop =
+	    (unsigned int) (pci1IoBase + pci1IoLength);
+
+	if (pci1IoLength == 0)
+		pci1IoTop++;
+
+	pci1IoBase = (unsigned int) (pci1IoBase >> 21);
+	pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21);
+	GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase);
+	GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop);
+}
+
+/*
+ * pci0MapMemory0space - Maps PCI0 memory0 space for the master.
+ * Inputs: base and length of pci0Mem0
+ */
+
+static void pci0MapMemory0space(unsigned int pci0Mem0Base,
+				unsigned int pci0Mem0Length)
+{
+	unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length;
+
+	if (pci0Mem0Length == 0)
+		pci0Mem0Top++;
+
+	pci0Mem0Base = pci0Mem0Base >> 21;
+	pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21;
+	GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base);
+	GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top);
+}
+
+/*
+ * pci1MapMemory0space - Maps PCI1 memory0 space for the master.
+ * Inputs: base and length of pci1Mem0
+ */
+
+static void pci1MapMemory0space(unsigned int pci1Mem0Base,
+				unsigned int pci1Mem0Length)
+{
+	unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length;
+
+	if (pci1Mem0Length == 0)
+		pci1Mem0Top++;
+
+	pci1Mem0Base = pci1Mem0Base >> 21;
+	pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21;
+	GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base);
+	GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top);
+}
+
+/*
+ * pci0MapMemory1space - Maps PCI0 memory1 space for the master.
+ * Inputs: base and length of pci0Mem1
+ */
+
+static void pci0MapMemory1space(unsigned int pci0Mem1Base,
+				unsigned int pci0Mem1Length)
+{
+	unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length;
+
+	if (pci0Mem1Length == 0)
+		pci0Mem1Top++;
+
+	pci0Mem1Base = pci0Mem1Base >> 21;
+	pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21;
+	GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base);
+	GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top);
+
+}
+
+/*
+ * pci1MapMemory1space - Maps PCI1 memory1 space for the master.
+ * Inputs: base and length of pci1Mem1
+ */
+
+static void pci1MapMemory1space(unsigned int pci1Mem1Base,
+				unsigned int pci1Mem1Length)
+{
+	unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length;
+
+	if (pci1Mem1Length == 0)
+		pci1Mem1Top++;
+
+	pci1Mem1Base = pci1Mem1Base >> 21;
+	pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21;
+	GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base);
+	GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top);
+}
+
+/*
+ * pci0GetIOspaceBase - Return PCI0 IO Base Address.
+ * Inputs: N/A
+ * Returns: PCI0 IO Base Address.
+ */
+
+static unsigned int pci0GetIOspaceBase(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI0IOLD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci0GetIOspaceSize - Return PCI0 IO Bar Size.
+ * Inputs: N/A
+ * Returns: PCI0 IO Bar Size.
+ */
+static unsigned int pci0GetIOspaceSize(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI0IOLD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI0IOHD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address.
+ * Inputs: N/A
+ * Returns: PCI0 Memory 0 Base Address.
+ */
+static unsigned int pci0GetMemory0Base(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI0M0LD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size.
+ * Inputs: N/A
+ * Returns: PCI0 Memory 0 Bar Size.
+ */
+static unsigned int pci0GetMemory0Size(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI0M0LD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI0M0HD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address.
+ * Inputs: N/A
+ * Returns: PCI0 Memory 1 Base Address.
+ */
+static unsigned int pci0GetMemory1Base(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI0M1LD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size.
+ * Inputs: N/A
+ * Returns: PCI0 Memory 1 Bar Size.
+ */
+
+static unsigned int pci0GetMemory1Size(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI0M1LD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI0M1HD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci1GetIOspaceBase - Return PCI1 IO Base Address.
+ * Inputs: N/A
+ * Returns: PCI1 IO Base Address.
+ */
+
+static unsigned int pci1GetIOspaceBase(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI1IOLD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci1GetIOspaceSize - Return PCI1 IO Bar Size.
+ * Inputs: N/A
+ * Returns: PCI1 IO Bar Size.
+ */
+
+static unsigned int pci1GetIOspaceSize(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI1IOLD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI1IOHD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address.
+ * Inputs: N/A
+ * Returns: PCI1 Memory 0 Base Address.
+ */
+
+static unsigned int pci1GetMemory0Base(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI1M0LD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size.
+ * Inputs: N/A
+ * Returns: PCI1 Memory 0 Bar Size.
+ */
+
+static unsigned int pci1GetMemory0Size(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI1M1LD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI1M1HD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address.
+ * Inputs: N/A
+ * Returns: PCI1 Memory 1 Base Address.
+ */
+
+static unsigned int pci1GetMemory1Base(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI1M1LD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size.
+ * Inputs: N/A
+ * Returns: PCI1 Memory 1 Bar Size.
+ */
+
+static unsigned int pci1GetMemory1Size(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI1M1LD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI1M1HD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+
+
+/*
+ * pci_range_ck -
+ *
+ * Check if the pci device that are trying to access does really exists
+ * on the evaluation board.  
+ *
+ * Inputs :
+ * bus - bus number (0 for PCI 0 ; 1 for PCI 1)
+ * dev - number of device on the specific pci bus
+ *
+ * Outpus :
+ * 0 - if OK , 1 - if failure
+ */
+static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev)
+{
+	//DBG(KERN_INFO "p_r_c %d %d\n",bus,dev);
+	if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8))
+		return 0;	// Bus/Device Number OK
+	return -1;		// Bus/Device Number not OK  
+}
+
+/*
+ * pciXReadConfigReg  - Read from a PCI configuration register
+ *                    - Make sure the GT is configured as a master before 
+ *                      reading from another device on the PCI.
+ *                   - The function takes care of Big/Little endian conversion.
+ * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+ *                        spec)
+ *           pciDevNum: The device number needs to be addressed.                
+ * RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
+ *                 cause register to make sure the data is valid
+ *
+ *  Configuration Address 0xCF8:
+ *
+ *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+ *  |congif|Reserved|  Bus |Device|Function|Register|00|
+ *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+ *
+ */
+static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device)
+{
+	unsigned int DataForRegCf8;
+	unsigned int data;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+
+	/*  The casual observer might wonder why the READ is duplicated here,
+	   rather than immediately following the WRITE, and just have the
+	   swap in the "if".  That's because there is a latency problem
+	   with trying to read immediately after setting up the address
+	   register.  The "if" check gives enough time for the address
+	   to stabilize, so the READ can work.
+	 */
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+		return data;
+	} else {	/* The PCI is working in LE Mode so swap the Data. */
+		GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+		return cpu_to_le32(data);
+	}
+}
+
+static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device)
+{
+	unsigned int DataForRegCf8;
+	unsigned int data;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	/*  The casual observer might wonder why the READ is duplicated here,
+	   rather than immediately following the WRITE, and just have the
+	   swap in the "if".  That's because there is a latency problem
+	   with trying to read immediately after setting up the address
+	   register.  The "if" check gives enough time for the address
+	   to stabilize, so the READ can work.
+	 */
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		/* when configurating our own PCI 1 L-unit the access is through  
+		   the PCI 0 interface with reg number = reg number + 0x80 */
+		DataForRegCf8 |= 0x80;
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+	} else {		/* The PCI is working in LE Mode so swap the Data. */
+		GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);
+	}
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+		return data;
+	} else {
+		GT_READ(GT_PCI1_CFGDATA_OFS, &data);
+		return cpu_to_le32(data);
+	}
+}
+
+
+
+/*
+ * pciXWriteConfigReg - Write to a PCI configuration register
+ *                    - Make sure the GT is configured as a master before 
+ *                      writingto another device on the PCI.
+ *                    - The function takes care of Big/Little endian conversion.
+ * Inputs:   unsigned int regOffset: The register offset as it apears in the
+ *           GT spec 
+ *                   (or any other PCI device spec)
+ *           pciDevNum: The device number needs to be addressed.                
+ *
+ *  Configuration Address 0xCF8:
+ *
+ *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+ *  |congif|Reserved|  Bus |Device|Function|Register|00|
+ *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+ *
+ */
+static void pci0WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data)
+{
+	unsigned int DataForRegCf8;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+	} else {		/* configuration Transaction over the pci. */
+		/* The PCI is working in LE Mode so swap the Data. */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data));
+	}
+}
+
+static void pci1WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data)
+{
+	unsigned int DataForRegCf8;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	/*  There is a latency problem
+	   with trying to read immediately after setting up the address
+	   register.  The "if" check gives enough time for the address
+	   to stabilize, so the WRITE can work.
+	 */
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		/* when configurating our own PCI 1 L-unit the access is through  
+		   the PCI 0 interface with reg number = reg number + 0x80 */
+		DataForRegCf8 |= 0x80;
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+	} else {		/* configuration Transaction over the pci. */
+		/* The PCI is working in LE Mode so swap the Data. */
+		GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);
+	}
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+	} else {		/* configuration Transaction over the pci. */
+		GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data));
+	}
+}
+
+
+/*
+ * galileo_pcibios_(read/write)_config_(dword/word/byte) -
+ *
+ * reads/write a dword/word/byte register from the configuration space
+ * of a device.
+ *
+ * Inputs :
+ * bus - bus number
+ * dev - device number
+ * offset - register offset in the configuration space
+ * val - value to be written / read
+ *
+ * Outputs :
+ * PCIBIOS_SUCCESSFUL when operation was succesfull
+ * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous
+ * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned
+ */
+
+static int galileo_pcibios_read_config_dword(struct pci_dev *device,
+					     int offset, u32 * val)
+{
+	int dev, bus;
+	//DBG(KERN_INFO "rcd entry \n",offset,val);
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	if (offset & 0x3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (bus == 0)
+		*val = pci0ReadConfigReg(offset, device);
+//  if (bus == 1) *val = pci1ReadConfigReg (offset,device);
+	DBG(KERN_INFO "rr: rcd dev %d offset %x %x\n", dev, offset, *val);
+
+	/*
+	 * This is so that the upper PCI layer will get the correct return
+	 * value if we're not attached to anything.
+	 */
+	if ((offset == 0) && (*val == 0xffffffff)) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_read_config_word(struct pci_dev *device,
+					    int offset, u16 * val)
+{
+	int dev, bus;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	if (offset & 0x1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (bus == 0)
+		*val = (unsigned short) (pci0ReadConfigReg(offset, device) >>
+				         ((offset & ~0x3) * 8));
+//  if (bus == 1) *val = (unsigned short) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8));
+
+	DBG(KERN_INFO "rr: rcw dev %d offset %x %x\n", dev, offset, *val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_read_config_byte(struct pci_dev *device,
+					    int offset, u8 * val)
+{
+	int dev, bus;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	if (bus == 0)
+		*val =
+		    (unsigned char) (pci0ReadConfigReg(offset, device) >>
+				     ((offset & ~0x3) * 8));
+//  if (bus == 1) *val = (unsigned char) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8));
+
+	DBG(KERN_INFO "rr: rcb dev %d offset %x %x\n", dev, offset, *val);
+
+	/*  This is so that the upper PCI layer will get the correct return value if
+	   we're not attached to anything.  */
+	if ((offset == 0xe) && (*val == 0xff)) {
+		u32 MasterAbort;
+		GT_READ(GT_INTRCAUSE_OFS, &MasterAbort);
+		if (MasterAbort & 0x40000) {
+			DBG(KERN_INFO "PCI Master Abort, ICR %x\n",
+			    MasterAbort);
+			GT_WRITE(GT_INTRCAUSE_OFS,
+				 (MasterAbort & 0xfffbffff));
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_dword(struct pci_dev *device,
+					      int offset, u32 val)
+{
+	int dev, bus;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (offset & 0x3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (bus == 0)
+		pci0WriteConfigReg(offset, device, val);
+//  if (bus == 1) pci1WriteConfigReg (offset,device,val);
+
+	DBG(KERN_INFO "rr: wcd dev %d, offset %x, val %x\n", dev, offset,
+	    val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_pcibios_write_config_word(struct pci_dev *device,
+					     int offset, u16 val)
+{
+	int dev, bus;
+	unsigned long tmp;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (offset & 0x1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (bus == 0)
+		tmp = pci0ReadConfigReg(offset, device);
+//  if (bus == 1) tmp = pci1ReadConfigReg (offset,device);
+
+	if ((offset % 4) == 0)
+		tmp = (tmp & 0xffff0000) | (val & 0xffff);
+	if ((offset % 4) == 2)
+		tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16);
+
+	if (bus == 0)
+		pci0WriteConfigReg(offset, device, tmp);
+//  if (bus == 1) pci1WriteConfigReg (offset,device,tmp);
+	DBG(KERN_INFO "rr: wcw dev %d, offset %x, val %x\n", dev, offset,
+	    val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_byte(struct pci_dev *device,
+					     int offset, u8 val)
+{
+	int dev, bus;
+	unsigned long tmp;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (bus == 0)
+		tmp = pci0ReadConfigReg(offset, device);
+//  if (bus == 1) tmp = pci1ReadConfigReg (offset,device);
+
+	if ((offset % 4) == 0)
+		tmp = (tmp & 0xffffff00) | (val & 0xff);
+	if ((offset % 4) == 1)
+		tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8);
+	if ((offset % 4) == 2)
+		tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16);
+	if ((offset % 4) == 3)
+		tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24);
+
+	if (bus == 0)
+		pci0WriteConfigReg(offset, device, tmp);
+//  if (bus == 1) pci1WriteConfigReg (offset,device,tmp);
+	DBG(KERN_INFO "rr: wcb dev %d, offset %x, val %x\n", dev, offset,
+	    val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void galileo_pcibios_set_master(struct pci_dev *dev)
+{
+	u16 cmd;
+
+	DBG(KERN_INFO "rr: galileo_pcibios_set_master\n");
+
+	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MASTER;
+	galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+	DBG("PCI: Enabling device %s (%04x)\n", dev->slot_name, cmd);
+}
+
+/*  Externally-expected functions.  Do not change function names  */
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	u16 tmp;
+	u8 tmp1;
+	int idx;
+	struct resource *r;
+
+	DBG(KERN_INFO "rr: pcibios_enable_resources\n");
+
+	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = &dev->resource[idx];
+		DBG(KERN_INFO
+		    "rr: BAR %d, start %lx, end %lx, flags %lx\n", idx,
+		    r->start, r->end, r->flags);
+		if (!r->start && r->end) {
+			printk(KERN_ERR
+			       "PCI: Device %s not available because of resource collisions\n",
+			       dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		DBG(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n",
+		    dev->slot_name, old_cmd, cmd);
+		galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+
+	/*
+	   Let's fix up the latency timer and cache line size here.  Cache line size =
+	   32 bytes / sizeof dword (4) = 8.
+	   Latency timer must be > 8.  32 is random but appears to work.
+	 */
+	galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+	if (tmp1 != 8) {
+		DBG(KERN_INFO
+		    "rr: PCI setting cache line size to 8 from %d\n",
+		    tmp1);
+		galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+						  8);
+	}
+	galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+	if (tmp1 < 32) {
+		DBG(KERN_INFO
+		    "rr: PCI setting latency timer to 32 from %d\n", tmp1);
+		galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER,
+						  32);
+	}
+
+	return 0;
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	DBG(KERN_INFO "rr: pcibios_enable_device\n");
+	return pcibios_enable_resources(dev);
+}
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			     struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	DBG(KERN_INFO "rr: pcibios_update_resource\n");
+	return;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) &
+	    ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+	     PCI_BASE_ADDRESS_MEM_MASK)) {
+		DBG(KERN_ERR "PCI: Error while updating region "
+		    "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		    new, check);
+	}
+}
+
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size)
+{
+	struct pci_dev *dev = data;
+
+	DBG(KERN_INFO "pcibios_align_resource\n");
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		/* We need to avoid collisions with `mirrored' VGA ports
+		   and other strange ISA hardware, so we always want the
+		   addresses kilobyte aligned.  */
+		if (size > 0x100) {
+			DBG(KERN_ERR "PCI: I/O Region %s/%d too large"
+			    " (%ld bytes)\n", dev->slot_name,
+			    dev->resource - res, size);
+		}
+
+		start = (start + 1024 - 1) & ~(1024 - 1);
+		res->start = start;
+	}
+}
+
+/*
+ * structure galileo_pci_ops
+ *
+ * This structure holds the pointers for the PCI configuration space
+ * access, and the fixup for the interrupts.
+ * This structure is registered to the operating system in boot time
+ */
+struct pci_ops galileo_pci_ops = {
+	galileo_pcibios_read_config_byte,
+	galileo_pcibios_read_config_word,
+	galileo_pcibios_read_config_dword,
+	galileo_pcibios_write_config_byte,
+	galileo_pcibios_write_config_word,
+	galileo_pcibios_write_config_dword
+};
+
+/*
+ * galileo_pcibios_fixup_bus -
+ *
+ * After detecting all agents over the PCI , this function is called
+ * in order to give an interrupt number for each PCI device starting
+ * from IRQ 20. It does also enables master for each device.
+ *
+ * Inputs :
+ * mem_start , mem_end are not relevant in MIPS architecture.
+ *
+ * Outpus :
+ * return always mem_start
+ */
+static void __init galileo_pcibios_fixup_bus(struct pci_bus *bus)
+{
+	unsigned int Current_IRQ = 20;
+	struct pci_bus *current_bus = bus;
+	struct pci_dev *devices;
+	struct list_head *devices_link;
+
+	list_for_each(devices_link, &(current_bus->devices)) {
+		devices = pci_dev_b(devices_link);
+		if (devices != NULL) {
+			devices->irq = Current_IRQ++;
+
+			/* Assign an interrupt number for the device */
+			galileo_pcibios_write_config_byte(devices,
+							  PCI_INTERRUPT_LINE,
+							  Current_IRQ);
+			galileo_pcibios_set_master(devices);
+
+		}
+	}
+
+}
+
+struct pci_fixup pcibios_fixups[] = {
+//    { PCI_FIXUP_HEADER, 0x4620, 0x11ab, galileo_pcibios_fixup },
+	{0}
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+	DBG(KERN_INFO "rr: pcibios_fixup_bus\n");
+	galileo_pcibios_fixup_bus(c);
+}
+
+/*
+ * This code was derived from Galileo Technology's example
+ * and significantly reworked.
+ *
+ * This is very simple.  It does not scan multiple function devices.  It does
+ * not scan behind bridges.  Those would be simple to implement, but we don't
+ * currently need this.
+ */
+static void __init scan_and_initialize_pci(void)
+{
+	struct pci_device pci_devices[MAX_PCI_DEVS];
+
+	if (scan_pci_bus(pci_devices)) {
+		allocate_pci_space(pci_devices);
+	}
+}
+
+/*
+ * This is your basic PCI scan.  It goes through each slot and checks to
+ * see if there's something that responds.  If so, then get the size and
+ * type of each of the responding BARs.  Save them for later.
+ */
+
+static u32 __init scan_pci_bus(struct pci_device *pci_devices)
+{
+	u32 arrayCounter = 0;
+	u32 memType;
+	u32 memSize;
+	u32 pci_slot, bar;
+	u32 id;
+	u32 c18RegValue;
+	struct pci_dev device;
+
+	DBG(KERN_INFO "rr: scan_pci_bus\n");
+
+	/*
+	   According to PCI REV 2.1 MAX agents on the bus are 21.
+	   We don't bother scanning ourselves (slot 0).
+	 */
+	for (pci_slot = 1; pci_slot < 22; pci_slot++) {
+
+		device.devfn = PCI_DEVFN(pci_slot, 0);
+		id = pci0ReadConfigReg(PCI_VENDOR_ID, &device);
+
+		/*  Check for a PCI Master Abort (nothing responds in the slot) */
+		GT_READ(GT_INTRCAUSE_OFS, &c18RegValue);
+		/* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */
+		GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff));
+		if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) {
+			DBG(KERN_INFO "rr: found device %x, slot %d\n", id,
+			    pci_slot);
+			pci_devices[arrayCounter].slot = pci_slot;
+			for (bar = 0; bar < 6; bar++) {
+				memType =
+				    pci0ReadConfigReg(PCI_BASE_ADDRESS_0 +
+						      (bar * 4), &device);
+				pci_devices[arrayCounter].BARtype[bar] =
+				    memType & 1;
+				pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+						   (bar * 4), &device,
+						   0xffffffff);
+				memSize =
+				    pci0ReadConfigReg(PCI_BASE_ADDRESS_0 +
+						      (bar * 4), &device);
+				if (memType & 1) {	/*  IO space  */
+					pci_devices[arrayCounter].
+					    BARsize[bar] =
+					    ~(memSize & 0xfffffffc) + 1;
+				} else {	/*  memory space */
+					pci_devices[arrayCounter].
+					    BARsize[bar] =
+					    ~(memSize & 0xfffffff0) + 1;
+				}
+				DBG(KERN_INFO
+				    "rr: BAR %d, type %d, size %x\n", bar,
+				    (memType & 1),
+				    pci_devices[arrayCounter].
+				    BARsize[bar]);
+			}	/*  BAR counter  */
+
+			arrayCounter++;
+		}
+		/*  found a device  */
+	}			/*  slot counter  */
+
+	DBG(KERN_INFO "rr: found %d devices\n", arrayCounter);
+	if (arrayCounter < MAX_PCI_DEVS) {
+		pci_devices[arrayCounter].slot = -1;
+	}
+	return (arrayCounter);
+}
+
+#define ALIGN(val,align)        (((val) + ((align) - 1)) & ~((align) - 1))
+#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
+
+/*
+ * This function goes through the list of devices and allocates the BARs in
+ * either IO or MEM space.  It does it in order of size, which will limit the
+ * amount of fragmentation we have in the IO and MEM spaces.
+ */
+
+static void __init allocate_pci_space(struct pci_device *pci_devices)
+{
+	u32 count, maxcount, bar;
+	u32 maxSize, maxDevice, maxBAR;
+	u32 alignto;
+	u32 base;
+	u32 pci0_mem_base = pci0GetMemory0Base();
+	u32 pci0_io_base = pci0GetIOspaceBase();
+	struct pci_dev device;
+
+	DBG(KERN_INFO "rr: allocate_pci_space\n");
+
+	DBG(KERN_INFO "pci0_io_base %x\n", pci0_io_base);
+	DBG(KERN_INFO "pci0_mem_base %x\n", pci0_mem_base);
+
+	/*  How many PCI devices do we have?  */
+	maxcount = MAX_PCI_DEVS;
+	for (count = 0; count < MAX_PCI_DEVS; count++) {
+		if (pci_devices[count].slot == -1) {
+			maxcount = count;
+			break;
+		}
+	}
+
+//    DBG(KERN_INFO "Found %d devices\n", maxcount);
+
+	do {
+		/*  Find the largest size BAR we need to allocate  */
+		maxSize = 0;
+		for (count = 0; count < maxcount; count++) {
+			for (bar = 0; bar < 6; bar++) {
+				if (pci_devices[count].BARsize[bar] >
+				    maxSize) {
+					maxSize =
+					    pci_devices[count].
+					    BARsize[bar];
+					maxDevice = count;
+					maxBAR = bar;
+				}
+			}
+		}
+
+		/*
+		   We've found the largest BAR.  Allocate it into IO or
+		   mem space.  We don't idiot check the bases to make
+		   sure they haven't overflowed the current size for that aperture.
+
+		   Don't bother to enable the device's IO or MEM space here.  That will
+		   be done in pci_enable_resources if the device is activated by a driver.
+		 */
+		if (maxSize) {
+			device.devfn =
+			    PCI_DEVFN(pci_devices[maxDevice].slot, 0);
+			if (pci_devices[maxDevice].BARtype[maxBAR] == 1) {
+				alignto = MAX(0x1000, maxSize);
+				base = ALIGN(pci0_io_base, alignto);
+				pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+						   (maxBAR * 4), &device,
+						   base | 0x1);
+				pci0_io_base = base + alignto;
+				DBG(KERN_INFO
+				    "Device %d BAR %d address %x\n",
+				    pci_devices[maxDevice].slot, maxBAR,
+				    base);
+				DBG(KERN_INFO "New IO base %x\n",
+				    pci0_io_base);
+			} else {
+				alignto = MAX(0x1000, maxSize);
+				base = ALIGN(pci0_mem_base, alignto);
+				pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+						   (maxBAR * 4), &device,
+						   base);
+				pci0_mem_base = base + alignto;
+				DBG(KERN_INFO
+				    "Device %d BAR %d address %x\n",
+				    pci_devices[maxDevice].slot, maxBAR,
+				    base);
+				DBG(KERN_INFO "New mem base %x\n",
+				    pci0_mem_base);
+			}
+			/*
+			   This entry is finished.  Remove it from the list we'll scan.
+			 */
+			pci_devices[maxDevice].BARsize[maxBAR] = 0;
+		}
+	} while (maxSize);
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
+void __init pcibios_init(void)
+{
+
+	u32 tmp;
+	struct pci_dev controller;
+
+	controller.devfn = SELF;
+
+	DBG(KERN_INFO "rr: pcibios_init\n");
+	GT_READ(GT_PCI0_CMD_OFS, &tmp);
+	DBG(KERN_INFO "rr: PCI0 command - %x\n", tmp);
+	GT_READ(GT_PCI0_BARE_OFS, &tmp);
+	DBG(KERN_INFO "rr: BAR0 - %x\n", tmp);
+
+	/*
+	 * You have to enable bus mastering to configure any other
+	 * card on the bus.
+	 */
+	tmp = pci0ReadConfigReg(PCI_COMMAND, &controller);
+	DBG(KERN_INFO "rr: command/status - %x\n", tmp);
+	tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+	DBG(KERN_INFO "rr: new command/status - %x\n", tmp);
+	pci0WriteConfigReg(PCI_COMMAND, &controller, tmp);
+
+	/*  This scans the PCI bus and sets up initial values.  */
+	scan_and_initialize_pci();
+
+	/*
+	 * Reset PCI I/O and PCI MEM values to ones supported by EVM.
+	 */
+	ioport_resource.start = 0x10000000;
+	ioport_resource.end = 0x11ffffff;	/*  32 MB */
+	iomem_resource.start = 0x12000000;
+	iomem_resource.end = 0x13ffffff;	/* 32 MB */
+
+	pci_scan_bus(0, &galileo_pci_ops, NULL);
+
+}
+
+char *pcibios_setup(char *str)
+{
+	printk(KERN_INFO "rr: pcibios_setup\n");
+	/* Nothing to do for now.  */
+
+	return str;
+}
+
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/promcon.c linux/arch/mips/galileo-boards/ev64120/promcon.c
--- linux.orig/arch/mips/galileo-boards/ev64120/promcon.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/promcon.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,58 @@
+/*
+ * Wrap-around code for a console using the
+ * SGI PROM io-routines.
+ *
+ * Copyright (c) 1999 Ulf Carlsson
+ *
+ * Derived from DECstation promcon.c
+ * Copyright (c) 1998 Harald Koerfgen 
+ */
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+
+static void prom_console_write(struct console *co, const char *s,
+			       unsigned count)
+{
+	extern int CONSOLE_CHANNEL;	// The default serial port
+	unsigned i;
+
+	for (i = 0; i < count; i++) {
+		if (*s == 10)
+			serial_putc(CONSOLE_CHANNEL, 13);
+		serial_putc(CONSOLE_CHANNEL, *s++);
+	}
+}
+
+int prom_getchar(void)
+{
+	return 0;
+}
+
+static kdev_t prom_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static struct console sercons = {
+    name:	"ttyS",
+    write:	prom_console_write,
+    device:	prom_console_device,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
+};
+
+/*
+ *    Register console.
+ */
+
+void gal_serial_console_init(void)
+{
+	//  serial_init(); 
+	//serial_set(115200); 
+
+	register_console(&sercons);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/reset.c linux/arch/mips/galileo-boards/ev64120/reset.c
--- linux.orig/arch/mips/galileo-boards/ev64120/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/reset.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,45 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997 Ralf Baechle
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void galileo_machine_restart(char *command)
+{
+	*(volatile char *) 0xbc000000 = 0x0f;
+	/*
+	 * Ouch, we're still alive ... This time we take the silver bullet ...
+	 * ... and find that we leave the hardware in a state in which the
+	 * kernel in the flush locks up somewhen during of after the PCI
+	 * detection stuff.
+	 */
+	set_cp0_status(ST0_BEV | ST0_ERL);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void galileo_machine_halt(void)
+{
+	printk(KERN_NOTICE "You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+
+}
+
+void galileo_machine_power_off(void)
+{
+	galileo_machine_halt();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/serialGT.c linux/arch/mips/galileo-boards/ev64120/serialGT.c
--- linux.orig/arch/mips/galileo-boards/ev64120/serialGT.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/serialGT.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,212 @@
+/*
+ * serialGT.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *  Low Level Serial Port control for use
+ *  with the Galileo EVB64120A MIPS eval board and 
+ *  its on board two channel 16552 Uart.
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+// Note:
+//   Serial CHANNELS - 0 is the bottom connector of evb64120A.
+//                       (The one that maps to the "B" channel of the
+//                       board's uart)
+//                     1 is the top connector of evb64120A.
+//                       (The one that maps to the "A" channel of the
+//                       board's uart)
+int DEBUG_CHANNEL = 0;		// See Note Above
+int CONSOLE_CHANNEL = 1;	// See Note Above
+
+#define DUART 0xBD000000	/* Base address of Uart. */
+#define CHANNELOFFSET 0x20	/* DUART+CHANNELOFFSET gets you to the ChanA
+				   register set of the 16552 Uart device.
+				   DUART+0 gets you to the ChanB register set.
+				 */
+#define DUART_DELTA 0x4
+#define FIFO_ENABLE 0x07
+#define INT_ENABLE  0x04	/* default interrupt mask */
+
+#define RBR 0x00
+#define THR 0x00
+#define DLL 0x00
+#define IER 0x01
+#define DLM 0x01
+#define IIR 0x02
+#define FCR 0x02
+#define LCR 0x03
+#define MCR 0x04
+#define LSR 0x05
+#define MSR 0x06
+#define SCR 0x07
+
+#define LCR_DLAB 0x80
+#define XTAL 1843200
+#define LSR_THRE 0x20
+#define LSR_BI   0x10
+#define LSR_DR   0x01
+#define MCR_LOOP 0x10
+#define ACCESS_DELAY 0x10000
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+int inreg(int channel, int reg)
+{
+	int val;
+	val =
+	    *((volatile unsigned char *) DUART +
+	      (channel * CHANNELOFFSET) + (reg * DUART_DELTA));
+	return val;
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void outreg(int channel, int reg, unsigned char val)
+{
+	*((volatile unsigned char *) DUART + (channel * CHANNELOFFSET)
+	  + (reg * DUART_DELTA)) = val;
+}
+
+/******************************
+ Routine:
+ Description:
+   Initialize the device driver.
+ ******************************/
+void serial_init(int channel)
+{
+	/*
+	 * Configure active port, (CHANNELOFFSET already set.)
+	 *
+	 * Set 8 bits, 1 stop bit, no parity.
+	 *
+	 * LCR<7>       0       divisor latch access bit
+	 * LCR<6>       0       break control (1=send break)
+	 * LCR<5>       0       stick parity (0=space, 1=mark)
+	 * LCR<4>       0       parity even (0=odd, 1=even)
+	 * LCR<3>       0       parity enable (1=enabled)
+	 * LCR<2>       0       # stop bits (0=1, 1=1.5)
+	 * LCR<1:0>     11      bits per character(00=5, 01=6, 10=7, 11=8)
+	 */
+	outreg(channel, LCR, 0x3);
+
+	outreg(channel, FCR, FIFO_ENABLE);	/* Enable the FIFO */
+
+	outreg(channel, IER, INT_ENABLE);	/* Enable appropriate interrupts */
+}
+
+/******************************
+ Routine:
+ Description:
+   Set the baud rate.
+ ******************************/
+void serial_set(int channel, unsigned long baud)
+{
+	unsigned char sav_lcr;
+
+	/*
+	 * Enable access to the divisor latches by setting DLAB in LCR.
+	 *
+	 */
+	sav_lcr = inreg(channel, LCR);
+
+#if 0
+	/*
+	 * Set baud rate 
+	 */
+	outreg(channel, LCR, LCR_DLAB | sav_lcr);
+	//  outreg(DLL,(XTAL/(16*2*(baud))-2));
+	outreg(channel, DLL, XTAL / (16 * baud));
+	//  outreg(DLM,(XTAL/(16*2*(baud))-2)>>8);
+	outreg(channel, DLM, (XTAL / (16 * baud)) >> 8);
+#else
+	/*
+	 * Note: Set baud rate, hardcoded here for rate of 115200
+	 * since became unsure of above "buad rate" algorithm (??). 
+	 */
+	outreg(channel, LCR, 0x83);
+	outreg(channel, DLM, 0x00);	// See note above
+	outreg(channel, DLL, 0x02);	// See note above.
+	outreg(channel, LCR, 0x03);
+#endif
+
+	/*
+	 * Restore line control register
+	 */
+	outreg(channel, LCR, sav_lcr);
+}
+
+
+/******************************
+ Routine:
+ Description:
+   Transmit a character.
+ ******************************/
+void serial_putc(int channel, int c)
+{
+	while ((inreg(channel, LSR) & LSR_THRE) == 0);
+	outreg(channel, THR, c);
+}
+
+/******************************
+ Routine:
+ Description:
+    Read a received character if one is
+    available.  Return -1 otherwise.
+ ******************************/
+int serial_getc(int channel)
+{
+	if (inreg(channel, LSR) & LSR_DR) {
+		return inreg(channel, RBR);
+	}
+	return -1;
+}
+
+/******************************
+ Routine:
+ Description:
+   Used by embedded gdb client. (example; gdb-stub.c)
+ ******************************/
+char getDebugChar()
+{
+	int val;
+	while ((val = serial_getc(DEBUG_CHANNEL)) == -1);	// loop until we get a character in.
+	return (char) val;
+}
+
+/******************************
+ Routine:
+ Description:
+   Used by embedded gdb target. (example; gdb-stub.c)
+ ******************************/
+void putDebugChar(char c)
+{
+	serial_putc(DEBUG_CHANNEL, (int) c);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev64120/setup.c linux/arch/mips/galileo-boards/ev64120/setup.c
--- linux.orig/arch/mips/galileo-boards/ev64120/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev64120/setup.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,188 @@
+/*
+ * setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Galileo Evaluation Boards - board dependent boot routines
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/mc146818rtc.h>
+#include <asm/traps.h>
+#include <linux/version.h>
+#include <linux/bootmem.h>
+
+extern struct rtc_ops no_rtc_ops;
+
+/* These functions are used for rebooting or halting the machine*/
+extern void galileo_machine_restart(char *command);
+extern void galileo_machine_halt(void);
+extern void galileo_machine_power_off(void);
+/* 
+ *This structure holds pointers to the pci configuration space accesses
+ *and interrupts allocating routine for device over the PCI
+ */
+extern struct pci_ops galileo_pci_ops;
+
+extern unsigned long mips_machgroup;
+
+char arcs_cmdline[CL_SIZE] = { "console=ttyS0,115200 "
+	    "root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal "
+	    "ip=192.168.1.211:192.168.1.1:::gt::"
+};
+
+//struct eeprom_parameters eeprom_param;
+
+/*
+ * This function is added because arch/mips/mm/init.c needs it
+ * basically it does nothing
+ */
+void prom_free_prom_memory(void)
+{
+}
+
+extern void (*board_time_init) (struct irqaction * irq);
+
+static unsigned char galileo_rtc_read_data(unsigned long addr)
+{
+	return 0;
+}
+
+static void galileo_rtc_write_data(unsigned char data, unsigned long addr)
+{
+}
+
+static int galileo_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops galileo_rtc_ops = {
+	&galileo_rtc_read_data,
+	&galileo_rtc_write_data,
+	&galileo_rtc_bcd_mode
+};
+
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
+/********************************************************************
+ *ev64120_setup -
+ *
+ *Initializes basic routines and structures pointers, memory size (as
+ *given by the bios and saves the command line.
+ *
+ *
+ *Inputs :
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+extern void galileo_time_init();
+void ev64120_setup(void)
+{
+	unsigned int i, j;
+
+	//printk(KERN_INFO "ev64120_setup\n");
+
+	_machine_restart = galileo_machine_restart;
+	_machine_halt = galileo_machine_halt;
+	_machine_power_off = galileo_machine_power_off;
+
+	rtc_ops = &galileo_rtc_ops;
+
+	board_time_init = galileo_time_init;
+	set_io_port_base(KSEG1);
+
+#ifdef CONFIG_L2_L3_CACHE
+#error "external cache not implemented yet"
+	config_register = read_32bit_cp0_register(CP0_CONFIG);
+	printk("\n\n\nchecking second level cache cp0_config = %08lx\n",
+	       config_register);
+	if (config_register & CONF_SC) {	// second/third level cache available
+		config_register = config_register & (1 << 12);
+		write_32bit_cp0_register(CP0_CONFIG, config_register);
+		printk
+		    ("\n\n\nchecking second level cache cp0_config = %08lx\n",
+		     config_register);
+	}
+#endif
+
+}
+
+const char *get_system_type(void)
+{
+	return "Galileo EV64120A";
+}
+
+/*
+ * SetUpBootInfo -
+ *
+ * This function is called at very first stages of kernel startup.
+ * It specifies for the kernel the evaluation board that the linux
+ * is running on. Then it saves the eprom parameters that holds the
+ * command line, memory size etc...
+ *
+ * Inputs :
+ * argc - nothing
+ * argv - holds a pointer to the eprom parameters
+ * envp - nothing
+ */
+
+void SetUpBootInfo(int argc, char **argv, char **envp)
+{
+	mips_machgroup = MACH_GROUP_GALILEO;
+	mips_machtype = MACH_EV64120A;
+}
+
+void __init prom_init(int a, char **b, char **c, int *d)
+{
+	unsigned long free_start, free_end, start_pfn, bootmap_size;
+
+	mips_machgroup = MACH_GROUP_GALILEO;
+	add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/Makefile linux/arch/mips/galileo-boards/ev96100/Makefile
--- linux.orig/arch/mips/galileo-boards/ev96100/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/Makefile	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,20 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Galileo EV96100 board.
+#
+# 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:= ev96100.o
+
+obj-y	:= init.o pci_ops.o pci_fixups.o time.o irq.o int-handler.o setup.o \
+	    puts.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/init.c linux/arch/mips/galileo-boards/ev96100/init.c
--- linux.orig/arch/mips/galileo-boards/ev96100/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/init.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's 
+ * arch/mips/mips-boards/generic/generic.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/galileo-boards/ev96100.h>
+
+
+/* Environment variable */
+
+typedef struct {
+	char *name;
+	char *val;
+} t_env_var;
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+char arcs_cmdline[CL_SIZE];
+
+int init_debug = 0;
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+void prom_free_prom_memory (void)
+{
+}
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv[actr]);
+		cp += strlen(prom_argv[actr]);
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+}
+
+char *prom_getenv(char *envname)
+{
+	/*
+	 * Return a pointer to the given environment variable.
+	 */
+
+	t_env_var *env = (t_env_var *) prom_envp;
+	int i;
+
+	i = strlen(envname);
+
+	while (env->name) {
+		if (strncmp(envname, env->name, i) == 0) {
+			return (env->val);
+		}
+		env++;
+	}
+	return (NULL);
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return 0;		/* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if ((*str == '.') || (*str == ':'))
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+	char *ethaddr_str;
+
+	ethaddr_str = prom_getenv("ethaddr");
+	if (!ethaddr_str) {
+		printk("ethaddr not set in boot prom\n");
+		return -1;
+	}
+	str2eaddr(ethernet_addr, ethaddr_str);
+
+	if (init_debug > 1) {
+		int i;
+		printk("get_ethernet_addr: ");
+		for (i = 0; i < 5; i++)
+			printk("%02x:",
+			       (unsigned char) *(ethernet_addr + i));
+		printk("%02x\n", *(ethernet_addr + i));
+	}
+
+	return 0;
+}
+
+const char *get_system_type(void)
+{
+	return "Galileo EV96100";
+}
+
+void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	volatile unsigned char *uart;
+	char ppbuf[8];
+
+	prom_argc = argc;
+	prom_argv = argv;
+	prom_envp = envp;
+
+	mips_machgroup = MACH_GROUP_GALILEO;
+	mips_machtype = MACH_EV96100;
+
+	prom_init_cmdline();
+
+	/* 32 MB upgradable */
+	add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/int-handler.S linux/arch/mips/galileo-boards/ev96100/int-handler.S
--- linux.orig/arch/mips/galileo-boards/ev96100/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/int-handler.S	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,32 @@
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.set	noat
+	.align	5
+
+NESTED(ev96100IRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI				# Important: mark KERNEL mode !
+
+	mfc0	t0, CP0_CAUSE		# get pending interrupts
+	mfc0	t1, CP0_STATUS		# get enabled interrupts
+	and	t0, t1			# isolate allowed ones
+
+	# FIX ME add R7000 extensions
+	andi	t0,0xff00		# isolate pending bits
+	andi	a0, t0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	move	a0, sp
+	jal	mips_timer_interrupt
+	j	ret_from_irq
+
+1:	beqz	t0, 3f			# spurious interrupt
+	move	a0, t0
+	move	a1, sp			# delay slot
+	jal	ev96100_cpu_irq
+	j	ret_from_irq
+
+3:	j	spurious_interrupt
+	END(ev96100IRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/irq.c linux/arch/mips/galileo-boards/ev96100/irq.c
--- linux.orig/arch/mips/galileo-boards/ev96100/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/irq.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's 
+ * arch/mips/mips-boards/atlas/atlas_int.c.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/galileo-boards/ev96100int.h>
+
+extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
+extern asmlinkage void ev96100IRQ(void);
+
+static void disable_ev96100_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	clear_cp0_status(0x100 << irq_nr);
+	restore_flags(flags);
+}
+
+static inline void enable_ev96100_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	set_cp0_status(0x100 << irq_nr);
+	restore_flags(flags);
+}
+
+static unsigned int startup_ev96100_irq(unsigned int irq)
+{
+	enable_ev96100_irq(irq);
+
+	return 0;	/* never anything pending */
+}
+
+#define shutdown_ev96100_irq		disable_ev96100_irq
+#define mask_and_ack_ev96100_irq	disable_ev96100_irq
+
+static void end_ev96100_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_ev96100_irq(irq);
+}
+
+static inline unsigned int ffz8(unsigned int word)
+{
+	unsigned long k;
+
+	k = 7;
+	if (word & 0x0fUL) { k -= 4;  word <<= 4;  }
+	if (word & 0x30UL) { k -= 2;  word <<= 2;  }
+	if (word & 0x40UL) { k -= 1; }
+
+	return k;
+}
+
+asmlinkage void ev96100_cpu_irq(unsigned long cause, struct pt_regs * regs)
+{
+	if (!(cause & 0xff00))
+		return;
+
+	do_IRQ(ffz8((cause >> 8) & 0xff), regs);
+}
+
+static struct hw_interrupt_type ev96100_irq_type = {
+	"EV96100",
+	startup_ev96100_irq,
+	shutdown_ev96100_irq,
+	enable_ev96100_irq,
+	disable_ev96100_irq,
+	mask_and_ack_ev96100_irq,
+	end_ev96100_irq
+};
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	set_except_vector(0, ev96100IRQ);
+	init_generic_irq();
+
+	for (i = 0; i < 8; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &ev96100_irq_type;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/pci_fixups.c linux/arch/mips/galileo-boards/ev96100/pci_fixups.c
--- linux.orig/arch/mips/galileo-boards/ev96100/pci_fixups.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/pci_fixups.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,96 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	EV96100 Board specific pci fixups.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci_ids.h>
+
+#include <asm/gt64120.h>
+#include <asm/galileo-boards/ev96100.h>
+
+extern unsigned short get_gt_devid(void);
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev;
+	unsigned int slot;
+	u32 vendor;
+	unsigned short gt_devid = get_gt_devid();
+
+	/*
+	** EV96100/A interrupt routing for pci bus 0
+	**
+	** Note: EV96100A board with irq jumper set on 'VxWorks'
+	** for EV96100 compatibility.
+	*/
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number != 0)
+			return;
+
+		slot = PCI_SLOT(dev->devfn);
+		pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
+
+#ifdef DEBUG
+		printk("devfn %x, slot %d devid %x\n", 
+				dev->devfn, slot, gt_devid);
+#endif
+
+		/* fixup irq line based on slot # */
+		if (slot == 8) {
+			dev->irq = 5;
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 
+					dev->irq);
+		}
+		else if (slot == 9) {
+			dev->irq = 2;
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 
+					dev->irq);
+		}
+	}
+}
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/pci_ops.c linux/arch/mips/galileo-boards/ev96100/pci_ops.c
--- linux.orig/arch/mips/galileo-boards/ev96100/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/pci_ops.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,274 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Galileo EV96100 board specific pci support.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's 
+ * arch/mips/mips-boards/generic/pci.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/delay.h>
+#include <asm//gt64120.h>
+#include <asm/galileo-boards/ev96100.h>
+#include <asm/pci_channel.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#define GT_PCI_MEM_BASE    0x12000000
+#define GT_PCI_MEM_SIZE    0x02000000
+#define GT_PCI_IO_BASE     0x10000000
+#define GT_PCI_IO_SIZE     0x02000000
+static struct resource pci_io_resource = {
+	"io pci IO space", 
+	0x10000000,
+	0x10000000 + 0x02000000,
+	IORESOURCE_IO};
+
+static struct resource pci_mem_resource = {
+	"ext pci memory space", 
+	0x12000000,
+	0x12000000 + 0x02000000,
+	IORESOURCE_MEM};
+
+extern struct pci_ops gt96100_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{ &gt96100_pci_ops, &pci_io_resource, &pci_mem_resource, 1, 0xff },
+	{ NULL, NULL, NULL, NULL, NULL}
+};
+
+int
+static gt96100_config_access(unsigned char access_type, struct pci_dev *dev,
+                           unsigned char where, u32 *data)
+{
+	unsigned char bus = dev->bus->number;
+	unsigned char dev_fn = dev->devfn;
+        u32 intr;
+
+
+	if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) {
+            return -1; /* Because of a bug in the galileo (for slot 31). */
+        }
+
+	/* Clear cause register bits */
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+	                             GT_INTRCAUSE_TARABORT0_BIT));
+
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+		 (bus         << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
+		 (dev_fn      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+	udelay(2);
+
+
+	if (access_type == PCI_ACCESS_WRITE) {
+		if (dev_fn != 0) {
+		*data = le32_to_cpu(*data);
+		}
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+	} 
+        else {
+		GT_READ(GT_PCI0_CFGDATA_OFS, *data);
+		if (dev_fn != 0) {
+		*data = le32_to_cpu(*data);
+		}
+	}
+
+	udelay(2);
+
+	/* Check for master or target abort */
+	GT_READ(GT_INTRCAUSE_OFS, intr);
+
+	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT))
+	{
+		//printk("config access error:  %x:%x\n", dev_fn,where);
+	        /* Error occured */
+
+	        /* Clear bits */
+	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+					      GT_INTRCAUSE_TARABORT0_BIT) );
+
+		if (access_type == PCI_ACCESS_READ) {
+			*data = 0xffffffff;
+		}
+		return -1;
+	}
+	return 0;
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int
+read_config_byte (struct pci_dev *dev, int where, u8 *val)
+{
+	u32 data = 0;
+
+	if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) {
+		*val = 0xff;
+		return -1;
+	}
+
+	*val = (data >> ((where & 3) << 3)) & 0xff;
+        DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", 
+                dev->bus->number, dev->devfn, where, *val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+read_config_word (struct pci_dev *dev, int where, u16 *val)
+{
+	u32 data = 0;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) {
+		*val = 0xffff;
+		return -1;
+	}
+
+	*val = (data >> ((where & 3) << 3)) & 0xffff;
+        DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", 
+                dev->bus->number, dev->devfn, where, *val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+read_config_dword (struct pci_dev *dev, int where, u32 *val)
+{
+	u32 data = 0;
+
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	
+	if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) {
+		*val = 0xffffffff;
+		return -1;
+	}
+
+	*val = data;
+        DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", 
+                dev->bus->number, dev->devfn, where, *val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+write_config_byte (struct pci_dev *dev, int where, u8 val)
+{
+	u32 data = 0;
+       
+	if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data))
+		return -1;
+
+	data = (data & ~(0xff << ((where & 3) << 3))) |
+	       (val << ((where & 3) << 3));
+        DBG("cfg write byte: bus %d dev_fn %x where %x: val %x\n", 
+                dev->bus->number, dev->devfn, where, val);
+
+	if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+write_config_word (struct pci_dev *dev, int where, u16 val)
+{
+        u32 data = 0;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+       
+        if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data))
+	       return -1;
+
+	data = (data & ~(0xffff << ((where & 3) << 3))) | 
+	       (val << ((where & 3) << 3));
+        DBG("cfg write word: bus %d dev_fn %x where %x: val %x\n", 
+                dev->bus->number, dev->devfn, where, val);
+
+	if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
+	       return -1;
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val))
+	       return -1;
+        DBG("cfg write dword: bus %d dev_fn %x where %x: val %x\n", 
+                dev->bus->number, dev->devfn, where, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops gt96100_pci_ops = {
+	read_config_byte,
+        read_config_word,
+	read_config_dword,
+	write_config_byte,
+	write_config_word,
+	write_config_dword
+};
+
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/puts.c linux/arch/mips/galileo-boards/ev96100/puts.c
--- linux.orig/arch/mips/galileo-boards/ev96100/puts.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/puts.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,144 @@
+
+/*
+ * Debug routines which directly access the uart.
+ */
+
+#include <linux/types.h>
+#include <asm/galileo-boards/ev96100.h>
+
+
+//#define SERIAL_BASE    EV96100_UART0_REGS_BASE
+#define SERIAL_BASE    0xBD000020
+#define NS16550_BASE   SERIAL_BASE
+
+#define SERA_CMD       0x0D
+#define SERA_DATA      0x08
+//#define SERB_CMD       0x05
+#define SERB_CMD       20
+#define SERB_DATA      0x00
+#define TX_BUSY        0x20
+
+#define TIMEOUT    0xffff
+#undef SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+static volatile unsigned char * const com1 = (unsigned char *)SERIAL_BASE;
+
+
+#ifdef SLOW_DOWN
+static inline void slow_down()
+{
+    int k;
+    for (k=0; k<10000; k++);
+}
+#else
+#define slow_down()
+#endif
+
+void
+putch(const unsigned char c)
+{
+    unsigned char ch;
+    int i = 0;
+
+    do {
+        ch = com1[SERB_CMD];
+        slow_down();
+        i++;
+        if (i>TIMEOUT) {
+            break;
+        }
+    } while (0 == (ch & TX_BUSY));
+    com1[SERB_DATA] = c;
+}
+
+void
+putchar(const unsigned char c)
+{
+    unsigned char ch;
+    int i = 0;
+
+    do {
+        ch = com1[SERB_CMD];
+        slow_down();
+        i++;
+        if (i>TIMEOUT) {
+            break;
+        }
+    } while (0 == (ch & TX_BUSY));
+    com1[SERB_DATA] = c;
+}
+
+void
+puts(unsigned char *cp)
+{
+    unsigned char ch;
+    int i = 0;
+
+    while (*cp) {
+        do {
+             ch = com1[SERB_CMD];
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (0 == (ch & TX_BUSY));
+        com1[SERB_DATA] = *cp++;
+    }
+    putch('\r');
+    putch('\n');
+}
+
+void
+fputs(unsigned char *cp)
+{
+    unsigned char ch;
+    int i = 0;
+
+    while (*cp) {
+
+        do {
+             ch = com1[SERB_CMD];
+             slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (0 == (ch & TX_BUSY));
+        com1[SERB_DATA] = *cp++;
+    }
+}
+
+
+void
+put64(uint64_t ul)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 16;            /* 16 nibbles in a 64 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
+
+void
+put32(unsigned u)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 8;            /* 8 nibbles in a 32 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(u >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/setup.c linux/arch/mips/galileo-boards/ev96100/setup.c
--- linux.orig/arch/mips/galileo-boards/ev96100/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/setup.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,213 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Galileo EV96100 setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's 
+ * arch/mips/mips-boards/atlas/atlas_setup.c.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/pci.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+#include <asm/gt64120.h>
+#include <asm/galileo-boards/ev96100.h>
+#include <asm/galileo-boards/ev96100int.h>
+
+
+void (*__wbflush) (void);
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+extern char * __init prom_getcmdline(void);
+
+extern void mips_reboot_setup(void);
+extern struct rtc_ops no_rtc_ops;
+extern struct resource ioport_resource;
+
+static void rm7000_wbflush(void)
+{
+	 __asm__ __volatile__ ("sync");
+}
+
+unsigned char mac_0_1[12];
+
+
+void __init ev96100_setup(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+	unsigned long status = read_32bit_cp0_register(CP0_STATUS);
+	unsigned long info = read_32bit_cp0_register(CP0_INFO);
+	u32 tmp;
+
+	char *argptr;
+
+	clear_cp0_status(ST0_FR);
+        __wbflush = rm7000_wbflush;
+
+        if (config & 0x8) {
+            printk("Secondary cache is enabled\n");
+        }
+        else {
+            printk("Secondary cache is disabled\n");
+        }
+
+        if (status & (1<<27)) {
+            printk("User-mode cache ops enabled\n");
+        }
+        else {
+            printk("User-mode cache ops disabled\n");
+        }
+
+        printk("CP0 info reg: %x\n", (unsigned)info);
+        if (info & (1<<28)) {
+            printk("burst mode Scache RAMS\n");
+        }
+        else {
+            printk("pipelined Scache RAMS\n");
+        }
+
+        if ((info & (0x3<<26)) >> 26 == 0) {
+            printk("67 percent drive strength\n");
+        }
+        else if ((info & (0x3<<26)) >> 26 == 1) {
+            printk("50 percent drive strength\n");
+        }
+        else if ((info & (0x3<<26)) >> 26 == 2) {
+            printk("100 percent drive strength\n");
+        }
+        else if ((info & (0x3<<26)) >> 26 == 3) {
+            printk("83 percent drive strength\n");
+        }
+
+
+        if ((info & (0x3<<23)) >> 23 == 0) {
+            printk("Write Protocol: R4000 compatible\n");
+        }
+        else if ((info & (0x3<<23)) >> 23 == 1) {
+            printk("Write Protocol: Reserved\n");
+        }
+        else if ((info & (0x3<<23)) >> 23 == 2) {
+            printk("Write Protocol: Pipelined\n");
+        }
+        else if ((info & (0x3<<23)) >> 23 == 3) {
+            printk("Write Protocol: Write re-issue\n");
+        }
+
+        if (info & 0x1) {
+            printk("Atomic Enable is set\n");
+        }
+
+	argptr = prom_getcmdline();
+#ifdef CONFIG_SERIAL_CONSOLE
+	if (strstr(argptr, "console=") == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS0,115200");
+	}
+#endif	  
+
+	rtc_ops = &no_rtc_ops;
+	mips_reboot_setup();
+	set_io_port_base(KSEG1);
+	ioport_resource.start = GT_PCI_IO_BASE;
+	ioport_resource.end   = GT_PCI_IO_BASE + 0x01ffffff;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+#endif
+
+
+	/* 
+	 * setup gt controller master bit so we can do config cycles 
+	 */
+
+	/* Clear cause register bits */
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+	                             GT_INTRCAUSE_TARABORT0_BIT));
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+		 (0      << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
+		 (0      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	udelay(2);
+	tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS));
+
+	tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 
+		PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+		 (0      << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
+		 (0      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+	udelay(2);
+	*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS) = cpu_to_le32(tmp);
+
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+		 (0      << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
+		 (0      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	udelay(2);
+	tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS));
+}
+
+unsigned short get_gt_devid() 
+{
+	u32 gt_devid;
+
+	/* Figure out if this is a gt96100 or gt96100A */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+		 (0      << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
+		 (0      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	udelay(4);
+	gt_devid = le32_to_cpu(*(volatile u32 *)
+			(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS));
+	return (unsigned short)(gt_devid>>16);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/ev96100/time.c linux/arch/mips/galileo-boards/ev96100/time.c
--- linux.orig/arch/mips/galileo-boards/ev96100/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/ev96100/time.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,269 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Galileo EV96100 rtc routines.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's 
+ * arch/mips/mips-boards/atlas/atlas_rtc.c.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/timex.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+
+extern volatile unsigned long wall_jiffies;
+unsigned long missed_heart_beats = 0;
+
+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+static unsigned long r4k_cur;    /* What counter should be at next timer irq */
+extern rwlock_t xtime_lock;
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+	write_32bit_cp0_register(CP0_COMPARE, newval);
+}
+
+static int set_rtc_mmss(unsigned long nowtime)
+{
+    /* EV96100 does not have a real time clock */
+    int retval = 0;
+
+    return retval;
+}
+
+
+
+/* 
+ * Figure out the r4k offset, the amount to increment the compare
+ * register for each time tick. 
+ * Use the RTC to calculate offset.
+ */
+static unsigned long __init cal_r4koff(void)
+{
+	unsigned long count;
+        count = 300000000/2;
+	return (count / HZ);
+}
+
+
+static unsigned long __init get_mips_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+        year = 2000;
+        mon = 10;
+        day = 31;
+        hour = 0;
+        min = 0;
+        sec = 0;
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+
+/*
+ * called from start_kernel()
+ */
+void __init time_init(void)
+{
+
+        unsigned int est_freq;
+
+	r4k_offset = cal_r4koff();
+
+	est_freq = 2*r4k_offset*HZ;	
+	est_freq += 5000;    /* round */
+	est_freq -= est_freq%10000;
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	       (est_freq%1000000)*100/1000000);
+	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+
+	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+
+        /* FIX ME */
+	change_cp0_status(ST0_IM, IE_IRQ5);
+}
+
+/* This is for machines which generate the exact clock. */
+#define USECS_PER_JIFFY (1000000/HZ)
+
+/* Cycle counter value at the previous timer interrupt.. */
+
+static unsigned int timerhi = 0, timerlo = 0;
+
+/*
+ * FIXME: Does playing with the RP bit in c0_status interfere with this code?
+ */
+static unsigned long do_fast_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+
+	/* Last jiffy when do_fast_gettimeoffset() was called. */
+	static unsigned long last_jiffies=0;
+	unsigned long quotient;
+
+	/*
+	 * Cached "1/(clocks per usec)*2^32" value.
+	 * It has to be recalculated once each jiffy.
+	 */
+	static unsigned long cached_quotient=0;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (tmp && last_jiffies != tmp) {
+		last_jiffies = tmp;
+		__asm__(".set\tnoreorder\n\t"
+			".set\tnoat\n\t"
+			".set\tmips3\n\t"
+			"lwu\t%0,%2\n\t"
+			"dsll32\t$1,%1,0\n\t"
+			"or\t$1,$1,%0\n\t"
+			"ddivu\t$0,$1,%3\n\t"
+			"mflo\t$1\n\t"
+			"dsll32\t%0,%4,0\n\t"
+			"nop\n\t"
+			"ddivu\t$0,%0,$1\n\t"
+			"mflo\t%0\n\t"
+			".set\tmips0\n\t"
+			".set\tat\n\t"
+			".set\treorder"
+			:"=&r" (quotient)
+			:"r" (timerhi),
+			 "m" (timerlo),
+			 "r" (tmp),
+			 "r" (USECS_PER_JIFFY));
+		cached_quotient = quotient;
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+		"mfhi\t%0"
+		:"=r" (res)
+		:"r" (count),
+		 "r" (quotient));
+
+	/*
+ 	 * Due to possible jiffies inconsistencies, we need to check 
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned int flags;
+
+	read_lock_irqsave (&xtime_lock, flags);
+	*tv = xtime;
+	tv->tv_usec += do_fast_gettimeoffset();
+
+	/*
+	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+	 * is nonzero if the timer bottom half hasnt executed yet.
+	 */
+	if (jiffies - wall_jiffies)
+		tv->tv_usec += USECS_PER_JIFFY;
+
+	read_unlock_irqrestore (&xtime_lock, flags);
+
+	if (tv->tv_usec >= 1000000) {
+		tv->tv_usec -= 1000000;
+		tv->tv_sec++;
+	}
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq (&xtime_lock);
+
+	/* This is revolting. We need to set the xtime.tv_usec correctly.
+	 * However, the value in this location is is value at the last tick.
+	 * Discover what correction gettimeofday would have done, and then
+	 * undo it!
+	 */
+	tv->tv_usec -= do_fast_gettimeoffset();
+
+	if (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
+	write_unlock_irq (&xtime_lock);
+}
+
+/*
+ * There are a lot of conceptually broken versions of the MIPS timer interrupt
+ * handler floating around.  This one is rather different, but the algorithm
+ * is probably more robust.
+ */
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+        int irq = 7; /* FIX ME */
+
+	if (r4k_offset == 0) {
+            goto null;
+        }
+
+	do {
+		kstat.irqs[0][irq]++;
+		do_timer(regs);
+		r4k_cur += r4k_offset;
+		ack_r4ktimer(r4k_cur);
+
+	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) 
+                    - r4k_cur) < 0x7fffffff);
+	return;
+
+null:
+	ack_r4ktimer(0);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/generic/Makefile linux/arch/mips/galileo-boards/generic/Makefile
--- linux.orig/arch/mips/galileo-boards/generic/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/generic/Makefile	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,36 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+# 
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# #######################################################################
+#
+# Makefile for the MIPS boards generic routines under Linux.
+#
+# 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).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET:= galboards.o
+
+obj-y := reset.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/galileo-boards/generic/reset.c linux/arch/mips/galileo-boards/generic/reset.c
--- linux.orig/arch/mips/galileo-boards/generic/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/galileo-boards/generic/reset.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,72 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Galileo EV96100 reset routines.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's 
+ * arch/mips/mips-boards/generic/reset.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+#include <asm/reboot.h>
+#include <asm/galileo-boards/ev96100.h>
+
+static void mips_machine_restart(char *command);
+static void mips_machine_halt(void);
+
+static void mips_machine_restart(char *command)
+{
+	set_cp0_status(ST0_BEV | ST0_ERL);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+	while (1);
+}
+
+static void mips_machine_halt(void)
+{
+	printk(KERN_NOTICE "You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void mips_reboot_setup(void)
+{
+	_machine_restart = mips_machine_restart;
+	_machine_halt = mips_machine_halt;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/gt64120/momenco_ocelot/dbg_io.c linux/arch/mips/gt64120/momenco_ocelot/dbg_io.c
--- linux.orig/arch/mips/gt64120/momenco_ocelot/dbg_io.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/gt64120/momenco_ocelot/dbg_io.c	2002-07-20 01:08:35.000000000 +0000
@@ -2,6 +2,8 @@
 
 #if defined(CONFIG_REMOTE_DEBUG)
 
+#include <asm/serial.h> /* For the serial port location and base baud */
+
 /* --- CONFIG --- */
 
 typedef unsigned char uint8;
@@ -36,8 +38,8 @@
 /* === CONFIG === */
 
 /* [jsun] we use the second serial port for kdb */
-#define         BASE                    0xbd000020
-#define         MAX_BAUD                115200
+#define         BASE                    OCELOT_SERIAL1_BASE
+#define         MAX_BAUD                OCELOT_BASE_BAUD
 
 /* === END OF CONFIG === */
 
@@ -111,7 +113,7 @@
 {
 	if (!remoteDebugInitialized) {
 		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_9600,
+		debugInit(UART16550_BAUD_38400,
 			  UART16550_DATA_8BIT,
 			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/gt64120/momenco_ocelot/irq.c linux/arch/mips/gt64120/momenco_ocelot/irq.c
--- linux.orig/arch/mips/gt64120/momenco_ocelot/irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/gt64120/momenco_ocelot/irq.c	2002-07-20 01:08:22.000000000 +0000
@@ -40,7 +40,6 @@
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/random.h>
-#include <linux/irq.h>
 #include <asm/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
@@ -144,9 +143,8 @@
 
 	/*
 	 * Clear all of the interrupts while we change the able around a bit.
-	 * int-handler is not on bootstrap
 	 */
-	clear_cp0_status(ST0_IM | ST0_BEV);
+	clear_cp0_status(ST0_IM);
 	__cli();
 
 	/* Sets the first-level interrupt dispatcher. */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h linux/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h
--- linux.orig/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h	2002-07-20 01:08:39.000000000 +0000
@@ -1,14 +1,10 @@
 /*
- * $Id$
- *
  * Ocelot Board Register Definitions
  *
  * (C) 2001 Red Hat, Inc.
  *
  * GPL'd
- *
  */
-
 #ifndef __MOMENCO_OCELOT_PLD_H__
 #define __MOMENCO_OCELOT_PLD_H__
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/gt64120/momenco_ocelot/prom.c linux/arch/mips/gt64120/momenco_ocelot/prom.c
--- linux.orig/arch/mips/gt64120/momenco_ocelot/prom.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/gt64120/momenco_ocelot/prom.c	2002-07-20 01:08:22.000000000 +0000
@@ -32,7 +32,12 @@
 
 #define PLD_REG(x)	((uint8_t*)(PLD_BASE+(x)))
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	return "Momentum Ocelot";
+}
 
 /* [jsun@junsun.net] PMON passes arguments in C main() style */
 void __init prom_init(int argc, const char **arg)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/gt64120/momenco_ocelot/reset.c linux/arch/mips/gt64120/momenco_ocelot/reset.c
--- linux.orig/arch/mips/gt64120/momenco_ocelot/reset.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/gt64120/momenco_ocelot/reset.c	2002-07-20 01:08:26.000000000 +0000
@@ -15,22 +15,21 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/system.h>
+#include <linux/delay.h>
 
 void momenco_ocelot_restart(char *command)
 {
-	*(volatile char *) 0xbc000000 = 0x0f;
+	void *nvram = ioremap_nocache(0x2c807000, 0x1000);
 
-	/*
-	 * Ouch, we're still alive ... This time we take the silver bullet ...
-	 * ... and find that we leave the hardware in a state in which the
-	 * kernel in the flush locks up somewhen during of after the PCI
-	 * detection stuff.
-	 */
-	clear_cp0_status(ST0_BEV | ST0_ERL);
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-	flush_cache_all();
-	write_32bit_cp0_register(CP0_WIRED, 0);
-	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+	if (!nvram) {
+		printk(KERN_NOTICE "ioremap of reset register failed\n");
+		return;
+	}
+	writeb(0x84, nvram + 0xff7); /* Ask the NVRAM/RTC/watchdog chip to
+					assert reset in 1/16 second */
+	mdelay(10+(1000/16));
+	iounmap(nvram);
+	printk(KERN_NOTICE "Watchdog reset failed\n");
 }
 
 void momenco_ocelot_halt(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/gt64120/momenco_ocelot/setup.c linux/arch/mips/gt64120/momenco_ocelot/setup.c
--- linux.orig/arch/mips/gt64120/momenco_ocelot/setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/gt64120/momenco_ocelot/setup.c	2002-07-20 01:08:37.000000000 +0000
@@ -2,11 +2,12 @@
  * setup.c
  *
  * BRIEF MODULE DESCRIPTION
- * Galileo Evaluation Boards - board dependent boot routines
+ * Momentum Computer Ocelot (CP7000) - board dependent boot routines
  *
  * Copyright (C) 1996, 1997, 2001  Ralf Baechle
  * Copyright (C) 2000 RidgeRun, Inc.
  * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2002 Momentum Computer
  *
  * Author: RidgeRun, Inc.
  *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
@@ -116,8 +117,7 @@
 
 	/* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
 	   in the CS[012] region. We can't use ioremap() yet. The NVRAM
-	   appears to be one of the variants of ST M48T35 - see 
-	   http://www.st.com/stonline/bin/sftab.exe?table=172&filter0=M48T35
+	   is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.
 
 		Ocelot PLD (CS0)	0x2c000000	0xe0020000
 		NVRAM			0x2c800000	0xe0030000
@@ -155,6 +155,7 @@
 	GT_WRITE(GT_PCI1M0LD_OFS, 0x32000000 >> 21);
 	GT_WRITE(GT_PCI1M1LD_OFS, 0x34000000 >> 21);
 
+	/* For the initial programming, we assume 512MB configuration */
 	/* Relocate the CPU's view of the RAM... */
 	GT_WRITE(GT_SCS10LD_OFS, 0);
 	GT_WRITE(GT_SCS10HD_OFS, 0x0fe00000 >> 21);
@@ -207,17 +208,66 @@
 	switch(tmpword &3) {
 	case 3:
 		/* 512MiB */
-		add_memory_region(256<<20, 256<<20, BOOT_MEM_RAM);
+		/* Decoders are allready set -- just add the
+		 * appropriate region */
+		add_memory_region( 0x40<<20,  0xC0<<20, BOOT_MEM_RAM);
+		add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM);
+		break;
 	case 2:
-		/* 256MiB */
-		/* FIXME: Is it actually here, or at 0x10000000? */
-		add_memory_region(128<<20, 128<<20, BOOT_MEM_RAM);
+		/* 256MiB -- two banks of 128MiB */
+		GT_WRITE(GT_SCS10HD_OFS, 0x07e00000 >> 21);
+		GT_WRITE(GT_SCS32LD_OFS, 0x08000000 >> 21);
+		GT_WRITE(GT_SCS32HD_OFS, 0x0fe00000 >> 21);
+
+		GT_WRITE(GT_SCS0HD_OFS, 0x7f);
+		GT_WRITE(GT_SCS2LD_OFS, 0x80);
+		GT_WRITE(GT_SCS2HD_OFS, 0xff);
+
+		/* reconfigure the PCI0 interface view of memory */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014);
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x08000000);
+		GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x0ffff000);
+		GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x0ffff000);
+
+		add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
+		add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM);
+		break;
 	case 1:
-		/* 128MiB */
-		add_memory_region(64<<20, 64<<20, BOOT_MEM_RAM);
+		/* 128MiB -- 64MiB per bank */
+		GT_WRITE(GT_SCS10HD_OFS, 0x03e00000 >> 21);
+		GT_WRITE(GT_SCS32LD_OFS, 0x04000000 >> 21);
+		GT_WRITE(GT_SCS32HD_OFS, 0x07e00000 >> 21);
+
+		GT_WRITE(GT_SCS0HD_OFS, 0x3f);
+		GT_WRITE(GT_SCS2LD_OFS, 0x40);
+		GT_WRITE(GT_SCS2HD_OFS, 0x7f);
+
+		/* reconfigure the PCI0 interface view of memory */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014);
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x04000000);
+		GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x03fff000);
+		GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x03fff000);
+
+		/* add the appropriate region */
+		add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
+		break;
 	case 0:
 		/* 64MiB */
-		;
+		GT_WRITE(GT_SCS10HD_OFS, 0x01e00000 >> 21);
+		GT_WRITE(GT_SCS32LD_OFS, 0x02000000 >> 21);
+		GT_WRITE(GT_SCS32HD_OFS, 0x03e00000 >> 21);
+
+		GT_WRITE(GT_SCS0HD_OFS, 0x1f);
+		GT_WRITE(GT_SCS2LD_OFS, 0x20);
+		GT_WRITE(GT_SCS2HD_OFS, 0x3f);
+
+		/* reconfigure the PCI0 interface view of memory */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014);
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x04000000);
+		GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x01fff000);
+		GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x01fff000);
+
+		break;
 	}
 
 	/* Fix up the DiskOnChip mapping */
@@ -272,11 +322,13 @@
 static int io_base_ioremap(void)
 {
 	void *io_remap_range = ioremap(GT_PCI_IO_BASE, GT_PCI_IO_SIZE);
+
 	if (!io_remap_range) {
-		panic("Could not ioremap I/O port range\n");
+		panic("Could not ioremap I/O port range");
 	}
-	mips_io_port_base = io_remap_range - GT_PCI_IO_BASE;
+	set_io_port_base(io_remap_range - GT_PCI_IO_BASE);
+
 	return 0;
 }
-module_init(io_base_ioremap);
 
+module_init(io_base_ioremap);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/Makefile linux/arch/mips/hp-lj/Makefile
--- linux.orig/arch/mips/hp-lj/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/Makefile	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,42 @@
+#
+# Makefile for the HP specific kernel interface routines
+# under Linux.
+#
+# 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
+
+all: hp-lj.o
+
+O_TARGET := hp-lj.o
+
+export-objs := utils.o
+
+obj-y   := init.o setup.o irq.o int-handler.o pci.o utils.o asic.o
+
+obj-$(CONFIG_REMOTE_DEBUG) += gdb_hook.o
+obj-$(CONFIG_DIRECT_PRINTK) += gdb_hook.o
+
+obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
+
+clean:
+	rm *.o
+
+forceit:
+
+# package filesystem from rootfs directory into binary package
+romfs.bin: forceit ./rootfs
+	@genromfs -d ./rootfs -f $@
+
+# transform rootfs.bin into object file format for linking
+initrd.o: romfs.bin
+	@echo "" | $(CROSS_COMPILE)as -o $@
+	@$(CROSS_COMPILE)objcopy --add-section .initrd=$< $@
+
+
+include $(TOPDIR)/Rules.make
+
+.PHONY: forceit
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/asic.c linux/arch/mips/hp-lj/asic.c
--- linux.orig/arch/mips/hp-lj/asic.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/asic.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,28 @@
+
+
+#include "asm/hp-lj/asic.h"
+
+AsicId GetAsicId(void)
+{
+   static int asic = IllegalAsic;
+
+   if (asic == IllegalAsic) {
+      if (*(unsigned int *)0xbff70000 == 0x1114103c)
+         asic = HarmonyAsic;
+      else if (*(unsigned int *)0xbff80000 == 0x110d103c)
+         asic = AndrosAsic;
+      else
+	 asic = UnknownAsic;
+   }
+   return asic;
+}
+
+
+const char* const GetAsicName(void)
+{
+   static const char* const Names[] = 
+        { "Illegal", "Unknown", "Andros", "Harmony" };
+
+   return Names[(int)GetAsicId()];
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/gdb_hook.c linux/arch/mips/hp-lj/gdb_hook.c
--- linux.orig/arch/mips/hp-lj/gdb_hook.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/gdb_hook.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,100 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * This is the interface to the remote debugger stub.
+ *
+ */
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#include <asm/serial.h>
+#include <asm/io.h>
+#include <asm/hp-lj/asic.h>
+
+
+int putDebugChar(char c);
+char getDebugChar(void);
+
+
+///////////////////////  andros values ///////////////////////////////////////////////////////
+#define SERIAL_REG(offset) (*((volatile unsigned int*)(HPSR_BASE_ADDR|offset)))
+
+// Register set base address
+#define HPSR_BASE_ADDR   0xbfe00000UL
+
+// Transmit / Receive Data
+#define HPSR_DATA_OFFSET    0x00020010UL
+// Transmit control / status
+#define HPSR_TX_STAT_OFFSET 0x0002000CUL
+// Receive status
+#define HPSR_RX_STAT_OFFSET 0x00020008UL
+
+#define HPSR_TX_STAT_READY  0x8UL
+#define HPSR_RX_DATA_AVAIL  0x4UL
+
+
+///////////////////////  harmony values ///////////////////////////////////////////////////////
+// Transmit / Receive Data
+#define H_HPSR_DATA_TX       *((volatile unsigned int*)0xbff65014)
+// Transmit / Receive Data
+#define H_HPSR_DATA_RX       *((volatile unsigned int*)0xbff65018)
+// Status
+#define H_HPSR_STAT          *((volatile unsigned int*)0xbff65004)
+
+// harmony serial status bits
+#define H_SER_STAT_TX_EMPTY       0x04
+#define H_SER_STAT_RX_EMPTY       0x10
+
+
+
+
+int putDebugChar(char c)
+{
+	if (GetAsicId() == HarmonyAsic) {
+		while (!( ( (H_HPSR_STAT) & H_SER_STAT_TX_EMPTY) != 0));
+
+		H_HPSR_DATA_TX = (unsigned int) c;
+
+	} else if (GetAsicId() == AndrosAsic) {
+        	while (((SERIAL_REG(HPSR_TX_STAT_OFFSET) & HPSR_TX_STAT_READY) == 0))
+             		;
+        	SERIAL_REG(HPSR_DATA_OFFSET) = (unsigned int) c;
+        } 
+	return 1;
+}
+
+char getDebugChar(void)
+{
+	if (GetAsicId() == HarmonyAsic) {
+		while (!(((H_HPSR_STAT) & H_SER_STAT_RX_EMPTY) == 0));
+
+	        return H_HPSR_DATA_RX;
+        
+	} else if (GetAsicId() == AndrosAsic) {
+        	while ((SERIAL_REG(HPSR_RX_STAT_OFFSET) & HPSR_RX_DATA_AVAIL) == 0)
+              		;
+
+        	return (SERIAL_REG(HPSR_DATA_OFFSET));
+
+	}
+}
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/init.c linux/arch/mips/hp-lj/init.c
--- linux.orig/arch/mips/hp-lj/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/init.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ * init.c: PROM library initialisation code.
+ *
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov 
+ */
+
+#include <linux/mm.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/hp-lj/asic.h>
+#include <linux/bootmem.h>
+
+#include "utils.h"
+
+
+#define Delimiter "CMDLINE="
+const char CommandLine[] = Delimiter
+  "root=/dev/hda3                                                                                                                                                                                                                                            ";
+
+char arcs_cmdline[CL_SIZE];
+
+int __init prom_init(int argc, char ** argv, char **envp)
+{
+	ulong mem_size = get_mem_avail();
+        int reserve_size = 0;
+
+	printk("Total Memory: %ld bytes\n", mem_size);
+
+	reserve_buffer(CommandLine, mem_size);
+
+	reserve_size = get_reserved_buffer_size();
+	mem_size -= reserve_size;
+
+	add_memory_region(0x0,mem_size, BOOT_MEM_RAM);
+        add_memory_region(mem_size,reserve_size, BOOT_MEM_RESERVED);
+
+	printk("Main Memory: %ld bytes\n", mem_size);
+	printk("Reserved Memory: %ld bytes at 0x%08x\n", 
+		get_reserved_buffer_size(), (ulong)get_reserved_buffer());
+
+	printk("Detected %s ASIC\n", GetAsicName());
+	mips_machgroup  = MACH_GROUP_HP_LJ;
+	mips_machtype   = MACH_UNKNOWN;
+
+	strcpy(arcs_cmdline, CommandLine+strlen(Delimiter));
+
+	return 0;
+}
+
+
+void prom_free_prom_memory (void)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/int-handler.S linux/arch/mips/hp-lj/int-handler.S
--- linux.orig/arch/mips/hp-lj/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/int-handler.S	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,70 @@
+#include <asm/asm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set    mips1
+	.set    reorder
+	.set    macro
+	.set    noat
+	.align	5
+
+# MIPS has 16 exception vectors numbered 0 to 15
+# vector number 0 is for interrupts and the others are for various exceptions
+# The following code is installed as the handler for exception 0
+# There are 8 possible interrupts that can cause this exception.
+# The cause register indicates which are pending
+# The status register indicates which are enabled
+# This code segment basically will decipher which interrup occurred (7 downto 0)
+# and pass an integer indicating which was the highest priority pending interrupt
+# to the do_IRQ routine.
+
+NESTED(hpIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI				# Important: mark KERNEL mode !
+	/*
+	 * Get pending interrupts
+	 */
+
+	mfc0	t0,CP0_CAUSE		# get pending interrupts
+	mfc0	t1,CP0_STATUS		# get enabled interrupts
+	and	t0,t1			# isolate allowed ones
+	andi	t0,0xff00		# isolate pending bits
+	sll	t0,16			# shift the pending bits down
+	beqz	t0,3f			# no pending intrs, then spurious
+	nop				# delay slot
+
+	/*
+	 * Find irq with highest priority
+	 * FIXME: This is slow - use binary search
+	 */
+
+	la	a0,7
+1:	bltz	t0,2f			# found pending irq
+	subu	a0,1
+	sll	t0,1
+	b	1b
+	nop				# delay slot
+
+
+call_do_IRQ:
+2:	move	a1,sp
+	jal	do_IRQ
+	nop				# delay slot
+	j       ret_from_irq
+	nop
+
+/*
+	mfc0	t0,CP0_STATUS		# disable interrupts
+	ori	t0,1
+	xori	t0,1
+	mtc0	t0,CP0_STATUS
+
+	la      a1, ret_from_irq
+	jr	a1
+*/	
+3:	j	spurious_interrupt
+END(hpIRQ)
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/irq.c linux/arch/mips/hp-lj/irq.c
--- linux.orig/arch/mips/hp-lj/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/irq.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,41 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/gdb-stub.h>
+
+
+/* install the handler for exception 0 */
+void __init init_IRQ(void)
+{
+    extern void hpIRQ(void);
+    extern void mips_cpu_irq_init(u32 base);
+    mips_cpu_irq_init(0);
+    set_except_vector(0, hpIRQ);
+
+#ifdef CONFIG_REMOTE_DEBUG
+    { 
+       extern void breakpoint(void);
+       extern int remote_debug;
+
+       if (remote_debug) {
+          set_debug_traps();
+          breakpoint();
+       }
+    }
+#endif
+        
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/pci-dma.c linux/arch/mips/hp-lj/pci-dma.c
--- linux.orig/arch/mips/hp-lj/pci-dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/pci-dma.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2000   Ani Joshi <ajoshi@unixbox.com>
+ *
+ *
+ * Dynamic DMA mapping support.
+ *
+ * swiped from i386, and cloned for MIPS by Geert.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t *dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+
+	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+		gfp |= GFP_DMA;
+	ret = (void *)__get_free_pages(gfp, get_order(size));
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_bus(ret);
+
+
+                // REVISIT  this needs reviewal as mentioned in bug report
+                // currently we bump kseg0 allocates to kseg1 uncacheable space
+
+                if ((((unsigned int) ret) & 0xe0000000) == 0x80000000) {
+	           //flush the cache to eliminate coherency problems
+	           // and assure dirty lines won't later get written over any dma, etc.
+                   flush_cache_all();
+		   ret = (void*)((unsigned int)ret | 0x20000000); 
+                }
+
+                
+	}
+	return ret;
+}
+
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long)vaddr, get_order(size));
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/pci.c linux/arch/mips/hp-lj/pci.c
--- linux.orig/arch/mips/hp-lj/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/pci.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,230 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SNI specific PCI support for RM200/RM300.
+ *
+ * Copyright (C) 1997 - 2000 Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/pci_channel.h>
+#include <asm/hp-lj/asic.h>
+
+#ifdef CONFIG_PCI
+
+volatile u32* pci_config_address_reg = (volatile u32*)0xfdead000;
+volatile u32* pci_config_data_reg = (volatile u32*)0xfdead000;
+
+
+
+#define cfgaddr(dev, where) (((dev->bus->number & 0xff) << 0x10) |  \
+                             ((dev->devfn & 0xff) << 0x08) |        \
+                             (where & 0xfc))
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int pcimt_read_config_byte (struct pci_dev *dev,
+                                   int where, unsigned char *val)
+{
+        *pci_config_address_reg = cfgaddr(dev, where);
+	*val = (le32_to_cpu(*pci_config_data_reg) >> ((where&3)<<3)) & 0xff;
+	//printk("pci_read_byte 0x%x == 0x%x\n", where, *val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pcimt_read_config_word (struct pci_dev *dev,
+                                   int where, unsigned short *val)
+{
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*val = (le32_to_cpu(*pci_config_data_reg) >> ((where&3)<<3)) & 0xffff;
+	//printk("pci_read_word 0x%x == 0x%x\n", where, *val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int pcimt_read_config_dword (struct pci_dev *dev,
+                                    int where, unsigned int *val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*val = le32_to_cpu(*pci_config_data_reg);
+	//printk("pci_read_dword 0x%x == 0x%x\n", where, *val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pcimt_write_config_byte (struct pci_dev *dev,
+                                    int where, unsigned char val)
+{
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*(volatile u8 *)(((int)pci_config_data_reg) + (where & 3)) = val;
+	//printk("pci_write_byte 0x%x = 0x%x\n", where, val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pcimt_write_config_word (struct pci_dev *dev,
+                                    int where, unsigned short val)
+{
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*(volatile u16 *)(((int)pci_config_data_reg) + (where & 2)) = 
+                  le16_to_cpu(val);
+	//printk("pci_write_word 0x%x = 0x%x\n", where, val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int pcimt_write_config_dword (struct pci_dev *dev,
+                                     int where, unsigned int val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*pci_config_data_reg = le32_to_cpu(val);
+	//printk("pci_write_dword 0x%x = 0x%x\n", where, val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+
+struct pci_ops hp_pci_ops = {
+	pcimt_read_config_byte,
+	pcimt_read_config_word,
+	pcimt_read_config_dword,
+	pcimt_write_config_byte,
+	pcimt_write_config_word,
+	pcimt_write_config_dword
+};
+
+
+struct pci_channel mips_pci_channels[] = {
+	{ &hp_pci_ops, &ioport_resource, &iomem_resource },
+	{ NULL, NULL, NULL }
+};
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+        return 1;
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+
+void __init pcibios_fixup_irqs(void)
+{
+   struct pci_dev *dev;
+   int slot_num;
+
+
+   pci_for_each_dev(dev) {
+      slot_num = PCI_SLOT(dev->devfn);
+      switch(slot_num) {
+         case 2: dev->irq = 3;  break;
+         case 3: dev->irq = 4;  break;
+         case 4: dev->irq = 5;  break;
+         default: break;
+      }
+   }
+}
+
+#define IO_MEM_LOGICAL_START   0x3e000000
+#define IO_MEM_LOGICAL_END     0x3fefffff
+
+#define IO_PORT_LOGICAL_START  0x3ff00000
+#define IO_PORT_LOGICAL_END    0x3fffffff
+
+
+#define IO_MEM_VIRTUAL_OFFSET  0xb0000000
+#define IO_PORT_VIRTUAL_OFFSET 0xb0000000
+
+#define ONE_MEG   (1024 * 1024)
+
+void __init pci_setup(void)
+{
+   u32 pci_regs_base_offset = 0xfdead000;
+
+   switch(GetAsicId()) {
+      case AndrosAsic:   pci_regs_base_offset = 0xbff80000;   break;
+      case HarmonyAsic:  pci_regs_base_offset = 0xbff70000;   break;
+      default:
+         printk("ERROR: PCI does not support %s Asic\n", GetAsicName()); 
+	 while(1);
+         break; 
+   }
+
+   // set bus stat/command reg
+   // REVIST this setting may need vary depending on the hardware
+   *((volatile unsigned int*)(pci_regs_base_offset | 0x0004)) =  0x38000007;
+
+
+   iomem_resource.start =  IO_MEM_LOGICAL_START + IO_MEM_VIRTUAL_OFFSET;
+   iomem_resource.end =    IO_MEM_LOGICAL_END + IO_MEM_VIRTUAL_OFFSET;
+
+   ioport_resource.start = IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET;
+   ioport_resource.end =   IO_PORT_LOGICAL_END + IO_PORT_VIRTUAL_OFFSET;
+
+   // KLUDGE (mips_io_port_base is screwed up, we've got to work around it here)
+   // by letting both low (illegal) and high (legal) addresses appear in pci io space
+   ioport_resource.start = 0x0; 
+
+   set_io_port_base(IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET);
+
+   // map the PCI address space
+   // global map - all levels & processes can access
+   // except that the range is outside user space
+   // parameters: lo0, lo1, hi, pagemask
+   // lo indicates physical page, hi indicates virtual address
+   add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17, 
+                   ((IO_MEM_LOGICAL_START + (16 * ONE_MEG)) >> 6) | 0x17,
+                   0xee000000, PM_16M);
+
+
+   // These are used in pci r/w routines so need to preceed bus scan
+   pci_config_data_reg = (u32*) (((u32)mips_io_port_base) | 0xcfc);
+   pci_config_address_reg = (u32*) (((u32)pci_regs_base_offset) | 0xcf8);
+
+}
+
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+    int pos;
+    int bases;
+
+    printk("adjusting pci device: %s\n", dev->name);
+ 
+    switch (dev->hdr_type) {
+       case PCI_HEADER_TYPE_NORMAL: bases = 6; break;
+       case PCI_HEADER_TYPE_BRIDGE: bases = 2; break;
+       case PCI_HEADER_TYPE_CARDBUS: bases = 1; break;
+       default: bases = 0; break;
+    }
+    for (pos=0; pos < bases; pos++) {
+       struct resource* res = &dev->resource[pos];
+       if (res->start >= IO_MEM_LOGICAL_START && 
+           res->end <= IO_MEM_LOGICAL_END) {
+              res->start += IO_MEM_VIRTUAL_OFFSET;
+              res->end += IO_MEM_VIRTUAL_OFFSET;
+       }
+       if (res->start >= IO_PORT_LOGICAL_START && 
+           res->end <= IO_PORT_LOGICAL_END) {
+              res->start += IO_PORT_VIRTUAL_OFFSET;
+              res->end += IO_PORT_VIRTUAL_OFFSET;
+       }
+    }
+
+}
+
+
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/setup.c linux/arch/mips/hp-lj/setup.c
--- linux.orig/arch/mips/hp-lj/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/setup.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,161 @@
+/*
+ * Setup pointers to hardware-dependent routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/hdreg.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/ide.h>
+#include <linux/bootmem.h>
+#include <asm/mc146818rtc.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/hp-lj/asic.h>
+#include "utils.h"
+
+#ifdef CONFIG_REMOTE_DEBUG
+int remote_debug = 0;
+#endif
+
+const char *get_system_type(void)
+{
+	return "HP LaserJet";		/* But which exactly?  */
+}
+
+static void (*timer_interrupt_service)(int irq, void *dev_id, struct pt_regs * regs) = NULL;
+
+
+static void andros_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+   if (!(*((volatile unsigned int*)0xbfea0010) & 0x20))  // mask = pend & en
+      return;
+
+   /* clear timer interrupt */
+   {
+      unsigned int tmr = *((volatile unsigned int*)0xbfe90040);   // ctl bits
+      *((volatile unsigned int*)0xbfe90040) = tmr;     // write to ack
+      *((volatile unsigned int*)0xbfea000c) = 0x20;    // sys int ack
+   }
+
+   /* service interrupt */
+   timer_interrupt_service(irq, dev_id, regs);
+}
+
+static void harmony_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+   if (!(*((volatile unsigned int*)0xbff63000) & 0x01))
+      return;  // big sys     int reg, 01-timer  did it
+   if (!(*((volatile unsigned int*)0xbff610a4) & 0x01))
+      return;  // local small int reg, 01-timer0 did it
+
+   *((volatile unsigned int*)0xbff610a4) = 1;   // ack local timer0 bit
+   *((volatile unsigned int*)0xbff63000) = 1;   // ack global timer bit
+
+   /* service interrupt */
+   timer_interrupt_service(irq, dev_id, regs);
+}
+
+
+#define ASIC_IRQ_NUMBER  2
+
+
+static void __init hp_time_init(struct irqaction *irq)
+{
+    timer_interrupt_service = irq->handler;
+
+    if (GetAsicId() == AndrosAsic) {
+       //*((volatile unsigned int*)0xbfe90000) = 0x2f;  // set by bootloader to 0x20              // prescaler
+       *((volatile unsigned int*)0xbfe90040) = 0x21;    // 20-res of 1kHz,1-int ack                // control
+       *((volatile unsigned int*)0xbfe90048) = 0x09;    // 09-reload val                          // reload
+       *((volatile unsigned int*)0xbfe90044) = 0x09;    // 09-count val                           // count
+       *((volatile unsigned int*)0xbfe90040) = 0x2f;    // 8-int enable,4-reload en,2-count down en,1-int-ack
+
+       irq->handler = andros_timer_interrupt;
+       irq->flags |= SA_INTERRUPT | SA_SHIRQ;
+       printk("setting up timer in hp_time_init\n");
+       setup_irq(ASIC_IRQ_NUMBER, irq); 
+    
+       // enable timer interrupt
+       *((volatile unsigned int*)0xbfea0000) = 0x20;
+
+    } else if (GetAsicId() == HarmonyAsic) {
+
+        *((volatile unsigned int*)0xbff61000) = 99;  // prescaler, 100Mz sys clk
+        *((volatile unsigned int*)0xbff61028) = 0x09;  // reload reg
+        *((volatile unsigned int*)0xbff61024) = 0x09;  // count reg
+        *((volatile unsigned int*)0xbff61020) = 0x0b;  // 80-1khz res on timer, 2 reload en, 1 - count down en
+
+        irq->handler = harmony_timer_interrupt;
+        irq->flags |= SA_INTERRUPT | SA_SHIRQ;
+        setup_irq(ASIC_IRQ_NUMBER, irq);
+
+        *((volatile unsigned int*)0xbff610a0) |= 1;    // turn on timer0
+
+    } else if (GetAsicId() == UnknownAsic) 
+        printk("Unknown asic in hp_time_init()\n");
+    else
+        printk("Unsupported asic in hp_time_init()\n");
+}
+
+
+static void hplj_restart(void)
+{
+   if (GetAsicId() == AndrosAsic) 
+       *((volatile unsigned int *) 0xbfe900c0) = 0;
+
+
+    if (GetAsicId() == HarmonyAsic)
+        *((volatile unsigned int *) 0xbff62030) = 0;
+
+   printk("Restart Failed ... halting instead\n");
+   while(1);
+}
+
+static void hplj_halt(void)
+{
+   while(1);
+}
+
+
+void __init hp_setup(void)
+{
+#ifdef CONFIG_PCI
+   extern void pci_setup(void);
+   pci_setup();
+#endif
+
+#ifdef CONFIG_IDE
+   {
+      extern struct ide_ops std_ide_ops;
+      ide_ops = &std_ide_ops;
+   }
+#endif
+
+   _machine_restart =(void (*)(char *)) hplj_restart;
+   _machine_halt = hplj_halt;
+   _machine_power_off = hplj_halt;
+
+   board_timer_setup = hp_time_init;
+
+#ifdef CONFIG_REMOTE_DEBUG
+   {
+      extern char CommandLine[];
+      remote_debug = (strstr(CommandLine, "kgdb") != NULL);
+   }
+#endif
+
+   printk("HP SETUP\n");
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+	return 1;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/utils.c linux/arch/mips/hp-lj/utils.c
--- linux.orig/arch/mips/hp-lj/utils.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/utils.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,69 @@
+/*
+ *
+ *
+ *
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include "utils.h"
+
+
+#define  miu_chan_cfg(x)      ((volatile unsigned long  *)(0xbff40000+x*4))       /* for andros */
+
+int mbsize[8] = {1,2,4,8,16,32,64,128};
+
+unsigned long get_mem_avail(void) {
+
+    unsigned long  cfg[10],i,total_mem=0;
+
+	for(i=0;i<10;i++)  
+		cfg[i] = *miu_chan_cfg(i); 
+
+	for(i=0;i<10;i++){
+		if(cfg[i]==0x1fc160c2) continue;                           // skip empties 
+		if(   ( (cfg[i]>>12) & 0xf )   <=  0xb ) continue;         // skip roms
+        total_mem += mbsize[(cfg[i]>>16)&0x7] *1024*1024;
+	}
+    return total_mem;
+}
+
+
+
+
+static ulong* buffer_ptr = NULL;
+static ulong buffer_size = 0;
+
+ulong* get_reserved_buffer(void) {return KSEG0ADDR(buffer_ptr);}
+ulong* get_reserved_buffer_virtual(void) {return (ulong*)ReservedMemVirtualAddr;}
+ulong get_reserved_buffer_size(void) {return buffer_size;}
+
+#define MIN_GEN_MEM (4 << 20)
+
+	
+void  reserve_buffer(const char* cl, ulong base_mem) 
+{
+	char* pos = strstr(cl, "reserved_buffer=");
+ 	if (pos) {
+		buffer_size = simple_strtol(pos+strlen("reserved_buffer="), 
+					    0, 10);
+		buffer_size <<= 20;
+		if (buffer_size + MIN_GEN_MEM > base_mem)
+			buffer_size = base_mem - MIN_GEN_MEM;
+		if (buffer_size > 0) 
+			buffer_ptr = (ulong*)(base_mem - buffer_size);
+		else 
+			buffer_size = 0;
+	}
+}
+
+
+
+EXPORT_SYMBOL(get_reserved_buffer);
+EXPORT_SYMBOL(get_reserved_buffer_virtual);
+EXPORT_SYMBOL(get_reserved_buffer_size);
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/hp-lj/utils.h linux/arch/mips/hp-lj/utils.h
--- linux.orig/arch/mips/hp-lj/utils.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/hp-lj/utils.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,19 @@
+/*
+ *
+ *
+ *
+ */
+
+#include <linux/types.h>
+
+#define ReservedMemVirtualAddr  0x50000000
+
+unsigned long get_mem_avail(void);
+
+ulong* get_reserved_buffer(void);
+ulong* get_reserved_buffer_virtual(void);
+ulong get_reserved_buffer_size(void);
+
+void  reserve_buffer(const char* cl, ulong base_mem);
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/generic/Makefile linux/arch/mips/ite-boards/generic/Makefile
--- linux.orig/arch/mips/ite-boards/generic/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/generic/Makefile	2002-07-20 01:08:28.000000000 +0000
@@ -21,16 +21,8 @@
 
 obj-y := it8172_rtc.o it8172_setup.o irq.o int-handler.o pmon_prom.o time.o lpc.o puts.o reset.o
 
-ifdef CONFIG_PCI
-obj-y += it8172_pci.o
-endif
-
-ifdef CONFIG_IT8172_CIR
-obj-y += it8172_cir.o 
-endif
-
-ifdef CONFIG_REMOTE_DEBUG
- obj-y += dbg_io.o             
-endif
+obj-$(CONFIG_PCI) += it8172_pci.o
+obj-$(CONFIG_IT8172_CIR) += it8172_cir.o 
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o             
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/generic/int-handler.S linux/arch/mips/ite-boards/generic/int-handler.S
--- linux.orig/arch/mips/ite-boards/generic/int-handler.S	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/ite-boards/generic/int-handler.S	2002-07-20 01:08:28.000000000 +0000
@@ -27,7 +27,7 @@
         andi    a0, t0, CAUSEF_IP7
         beq     a0, zero, 1f
         move    a0, sp
-        jal     mips_timer_interrupt
+        jal     local_timer_interrupt
 	j	ret_from_irq
         nop
         
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/generic/irq.c linux/arch/mips/ite-boards/generic/irq.c
--- linux.orig/arch/mips/ite-boards/generic/irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/generic/irq.c	2002-07-20 01:08:38.000000000 +0000
@@ -72,17 +72,17 @@
 #define EXT_IRQ0_TO_IP 2 /* IP 2 */
 #define EXT_IRQ5_TO_IP 7 /* IP 7 */
 
-extern void set_debug_traps(void);
-extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
-extern asmlinkage void it8172_IRQ(void);
+#define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
+
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
-unsigned long spurious_count = 0;
-irq_desc_t irq_desc[NR_IRQS];
-irq_desc_t *irq_desc_base=&irq_desc[0];
 void disable_it8172_irq(unsigned int irq_nr);
 void enable_it8172_irq(unsigned int irq_nr);
 
+extern void set_debug_traps(void);
+extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
+extern asmlinkage void it8172_IRQ(void);
+
 struct it8172_intc_regs volatile *it8172_hw0_icregs
 	= (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
 
@@ -105,7 +105,7 @@
         modify_cp0_intmask(0, irq_nr);
 }
 
-void disable_irq(unsigned int irq_nr)
+void local_disable_irq(unsigned int irq_nr)
 {
         unsigned long flags;
 
@@ -114,7 +114,7 @@
         restore_flags(flags);
 }
 
-void enable_irq(unsigned int irq_nr)
+void local_enable_irq(unsigned int irq_nr)
 {
 	unsigned long flags;
 
@@ -130,63 +130,70 @@
 
 	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
 		/* LPC interrupt */
-		DPRINTK("disable, before lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
-		it8172_hw0_icregs->lpc_mask |= (1 << (irq_nr - IT8172_LPC_IRQ_BASE));
-		DPRINTK("disable, after lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
+		DPRINTK("DB lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
+		it8172_hw0_icregs->lpc_mask |= 
+			(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
+		DPRINTK("DA lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
 	}
 	else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
 		/* Local Bus interrupt */
-		DPRINTK("before lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
-		it8172_hw0_icregs->lb_mask |= (1 << (irq_nr - IT8172_LB_IRQ_BASE));
-		DPRINTK("after lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
+		DPRINTK("DB lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
+		it8172_hw0_icregs->lb_mask |= 
+			(1 << (irq_nr - IT8172_LB_IRQ_BASE));
+		DPRINTK("DA lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
 	}
 	else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
 		/* PCI and other interrupts */
-		DPRINTK("before pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
-		it8172_hw0_icregs->pci_mask |= (1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
-		DPRINTK("after pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
+		DPRINTK("DB pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
+		it8172_hw0_icregs->pci_mask |= 
+			(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
+		DPRINTK("DA pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
 	}
 	else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
 		/* NMI interrupts */
-		DPRINTK("before nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
-		it8172_hw0_icregs->nmi_mask |= (1 << (irq_nr - IT8172_NMI_IRQ_BASE));
-		DPRINTK("after nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
+		DPRINTK("DB nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
+		it8172_hw0_icregs->nmi_mask |= 
+			(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
+		DPRINTK("DA nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
 	}
 	else {
-		panic("disable_it8172_irq: bad irq %d\n", irq_nr);
+		panic("disable_it8172_irq: bad irq %d", irq_nr);
 	}
 }
 
-
 void enable_it8172_irq(unsigned int irq_nr)
 {
 	DPRINTK("enable_it8172_irq %d\n", irq_nr);
 	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
 		/* LPC interrupt */
-		DPRINTK("enable, before lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
-		it8172_hw0_icregs->lpc_mask &= ~(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
-		DPRINTK("enable, after lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
+		DPRINTK("EB before lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
+		it8172_hw0_icregs->lpc_mask &= 
+			~(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
+		DPRINTK("EA after lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
 	}
 	else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
 		/* Local Bus interrupt */
-		DPRINTK("before lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
-		it8172_hw0_icregs->lb_mask &= ~(1 << (irq_nr - IT8172_LB_IRQ_BASE));
-		DPRINTK("after lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
+		DPRINTK("EB lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
+		it8172_hw0_icregs->lb_mask &= 
+			~(1 << (irq_nr - IT8172_LB_IRQ_BASE));
+		DPRINTK("EA lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
 	}
 	else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
 		/* PCI and other interrupts */
-		DPRINTK("before pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
-		it8172_hw0_icregs->pci_mask &= ~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
-		DPRINTK("after pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
+		DPRINTK("EB pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
+		it8172_hw0_icregs->pci_mask &= 
+			~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
+		DPRINTK("EA pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
 	}
 	else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
 		/* NMI interrupts */
-		DPRINTK("before nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
-		it8172_hw0_icregs->nmi_mask &= ~(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
-		DPRINTK("after nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
+		DPRINTK("EB nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
+		it8172_hw0_icregs->nmi_mask &= 
+			~(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
+		DPRINTK("EA nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
 	}
 	else {
-		panic("enable_it8172_irq: bad irq %d\n", irq_nr);
+		panic("enable_it8172_irq: bad irq %d", irq_nr);
 	}
 }
 
@@ -217,160 +224,25 @@
 };
 
 
-int get_irq_list(char *buf)
-{
-        int i, len = 0, j;
-        struct irqaction * action;
-
-        len += sprintf(buf+len, "           ");
-        for (j=0; j<smp_num_cpus; j++)
-                len += sprintf(buf+len, "CPU%d       ",j);
-        *(char *)(buf+len++) = '\n';
-
-        for (i = 0 ; i < NR_IRQS ; i++) {
-                action = irq_desc[i].action;
-                if ( !action || !action->handler )
-                        continue;
-                len += sprintf(buf+len, "%3d: ", i);		
-                len += sprintf(buf+len, "%10u ", kstat_irqs(i));
-                if ( irq_desc[i].handler )		
-                        len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
-                else
-                        len += sprintf(buf+len, "  None      ");
-                len += sprintf(buf+len, "    %s",action->name);
-                for (action=action->next; action; action = action->next) {
-                        len += sprintf(buf+len, ", %s", action->name);
-                }
-                len += sprintf(buf+len, "\n");
-        }
-        len += sprintf(buf+len, "BAD: %10lu\n", spurious_count);
-        return len;
-}
-
-asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
-{
-	struct irqaction *action;
-	int cpu;
-
-	cpu = smp_processor_id();
-	irq_enter(cpu, irq);
-
-	kstat.irqs[cpu][irq]++;
-#if 0
-	if (irq_desc[irq].handler && irq_desc[irq].handler->ack) {
-	//	printk("invoking ack handler\n");
-		irq_desc[irq].handler->ack(irq);
-	}
-#endif
-
-	action = irq_desc[irq].action;
-
-	if (action && action->handler)
-	{
-		//mask_irq(1<<irq);
-		//printk("action->handler %x\n", action->handler);
-		disable_it8172_irq(irq);
-		//if (!(action->flags & SA_INTERRUPT)) __sti(); /* reenable ints */
-		do { 
-			action->handler(irq, action->dev_id, regs);
-			action = action->next;
-		} while ( action );
-		//__cli(); /* disable ints */
-		if (irq_desc[irq].handler)
-		{
-		}
-		//unmask_irq(1<<irq);
-		enable_it8172_irq(irq);
-	}
-	else
-	{
-		spurious_count++;
-		printk("Unhandled interrupt %d, cause %x, disabled\n", 
-				(unsigned)irq, (unsigned)regs->cp0_cause);
-		disable_it8172_irq(irq);
-	}
-	irq_exit(cpu, irq);
-}
-
-int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-	unsigned long irqflags, const char * devname, void *dev_id)
-{
-        struct irqaction *old, **p, *action;
-        unsigned long flags;
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq) { }
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+static struct hw_interrupt_type cp0_irq_type = {
+	"CP0 Count",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
 
-        /*
-         * IP0 and IP1 are software interrupts. IP7 is typically the timer interrupt.
-	 *
-	 * The ITE QED-4N-S01B board has one single interrupt line going from
-	 * the system controller to the CPU. It's connected to the CPU external
-	 * irq pin 1, which is IP2.  The interrupt numbers are listed in it8172_int.h;
-	 * the ISA interrupts are numbered from 0 to 15, and the rest go from
-	 * there.  
-         */
-
-	//printk("request_irq: %d handler %x\n", irq, handler);
-        if (irq >= NR_IRQS) 
-                return -EINVAL;
-
-        if (!handler)
-        {
-                /* Free */
-                for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next)
-                {
-                        /* Found it - now free it */
-                        save_flags(flags);
-                        cli();
-                        *p = action->next;
-			disable_it8172_irq(irq);
-                        restore_flags(flags);
-                        kfree(action);
-                        return 0;
-                }
-                return -ENOENT;
-        }
-        
-        action = (struct irqaction *)
-                kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-        if (!action)
-                return -ENOMEM;
-        memset(action, 0, sizeof(struct irqaction));
-        
-        save_flags(flags);
-        cli();
-        
-        action->handler = handler;
-        action->flags = irqflags;					
-        action->mask = 0;
-        action->name = devname;
-        action->dev_id = dev_id;
-        action->next = NULL;
-
-        p = &irq_desc[irq].action;
-        
-        if ((old = *p) != NULL) {
-                /* Can't share interrupts unless both agree to */
-                if (!(old->flags & action->flags & SA_SHIRQ))
-                        return -EBUSY;
-                /* add new interrupt at end of irq queue */
-                do {
-                        p = &old->next;
-                        old = *p;
-                } while (old);
-        }
-        *p = action;
-	enable_it8172_irq(irq);
-        restore_flags(flags);	
-#if 0
-	printk("request_irq: status %x cause %x\n", 
-			read_32bit_cp0_register(CP0_STATUS), read_32bit_cp0_register(CP0_CAUSE));
-#endif
-        return 0;
-}
-		
-void free_irq(unsigned int irq, void *dev_id)
-{
-        request_irq(irq, NULL, 0, NULL, dev_id);
-}
 
 void enable_cpu_timer(void)
 {
@@ -381,26 +253,17 @@
         restore_flags(flags);
 }
 
-unsigned long probe_irq_on (void)
-{
-        return 0;
-}
-
-int probe_irq_off (unsigned long irqs)
-{
-        return 0;
-}
-
 
 void __init init_IRQ(void)
 {
 	int i;
         unsigned long flags;
 
-
         memset(irq_desc, 0, sizeof(irq_desc));
         set_except_vector(0, it8172_IRQ);
 
+	init_generic_irq();
+
 	/* mask all interrupts */
 	it8172_hw0_icregs->lb_mask  = 0xffff;
 	it8172_hw0_icregs->lpc_mask = 0xffff;
@@ -431,20 +294,11 @@
 		~(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
 #endif
 
-	for (i = 0; i <= IT8172_INT_END; i++) {
-		irq_desc[i].status	= IRQ_DISABLED;
-		irq_desc[i].action	= 0;
-		irq_desc[i].depth	= 1;
-		irq_desc[i].handler	= &it8172_irq_type;
+	for (i = 0; i <= IT8172_LAST_IRQ; i++) {
+		irq_desc[i].handler = &it8172_irq_type;
 	}
-
-	/*
-	 * Enable external int line 2
-	 * All ITE interrupts are masked for now.
-	 */
-        save_and_cli(flags);
-	unmask_irq(1<<EXT_IRQ0_TO_IP);
-        restore_flags(flags);
+	irq_desc[MIPS_CPU_TIMER_IRQ].handler = &cp0_irq_type;
+	set_cp0_status(ALLINTS_NOTIMER);
 
 #ifdef CONFIG_REMOTE_DEBUG
 	/* If local serial I/O used for debug port, enter kgdb at once */
@@ -473,16 +327,16 @@
 void it8172_hw0_irqdispatch(struct pt_regs *regs)
 {
 	int irq;
-	unsigned short intstatus, status;
+	unsigned short intstatus = 0, status = 0;
 
 	intstatus = it8172_hw0_icregs->intstatus;
 	if (intstatus & 0x8) {
-		panic("Got NMI interrupt\n");
+		panic("Got NMI interrupt");
 	}
 	else if (intstatus & 0x4) {
 		/* PCI interrupt */
 		irq = 0;
-		status = it8172_hw0_icregs->pci_req;
+		status |= it8172_hw0_icregs->pci_req;
 		while (!(status & 0x1)) {
 			irq++;
 			status >>= 1;
@@ -493,7 +347,7 @@
 	else if (intstatus & 0x1) {
 		/* Local Bus interrupt */
 		irq = 0;
-		status = it8172_hw0_icregs->lb_req;
+		status |= it8172_hw0_icregs->lb_req;
 		while (!(status & 0x1)) {
 			irq++;
 			status >>= 1;
@@ -507,7 +361,7 @@
 		 * we could lose an interrupt this way because
 		 * we acknowledge all ints at onces. Revisit.
 		 */
-		status = it8172_hw0_icregs->lpc_req;
+		status |= it8172_hw0_icregs->lpc_req;
 		it8172_hw0_icregs->lpc_req = 0; /* acknowledge ints */
 		irq = 0;
 		while (!(status & 0x1)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/generic/it8172_pci.c linux/arch/mips/ite-boards/generic/it8172_pci.c
--- linux.orig/arch/mips/ite-boards/generic/it8172_pci.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/generic/it8172_pci.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,4 +1,5 @@
 /*
+ *
  * BRIEF MODULE DESCRIPTION
  *	IT8172 system controller specific pci support.
  *
@@ -35,6 +36,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
+#include <asm/pci_channel.h>
 #include <asm/it8172/it8172.h>
 #include <asm/it8172/it8172_pci.h>
 
@@ -42,7 +44,47 @@
 #define PCI_ACCESS_WRITE 1
 
 #undef DEBUG
-#undef DEBUG_CONFIG_CYCLES
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+static struct resource pci_mem_resource_1;
+
+static struct resource pci_io_resource = {
+	"io pci IO space", 
+	0x14000000,
+	0x17FFFFFF,
+	IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource_0 = {
+	"ext pci memory space 0/1", 
+	0x0C000000,
+	0x13FFFFFF,
+	IORESOURCE_MEM,
+	&pci_mem_resource_0,
+	NULL,
+	&pci_mem_resource_1
+};
+
+static struct resource pci_mem_resource_1 = {
+	"ext pci memory space 2/3", 
+	0x1A000000,
+	0x1FBFFFFF,
+	IORESOURCE_MEM,
+	&pci_mem_resource_0,
+	NULL,
+	NULL
+};
+
+extern struct pci_ops it8172_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{ &it8172_pci_ops, &pci_io_resource, &pci_mem_resource_0, 0, 0xff },
+	{ NULL, NULL, NULL, NULL, NULL}
+};
 
 static int
 it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
@@ -54,12 +96,9 @@
 	unsigned char bus = dev->bus->number;
 	unsigned char dev_fn = dev->devfn;
 
-#ifdef DEBUG_CONFIG_CYCLES
-	printk("it config: type %d dev %x bus %d dev_fn %x data %x\n",
+	DBG("it config: type %d dev %x bus %d dev_fn %x data %x\n",
 			access_type, dev, bus, dev_fn, *data);
 
-#endif
-
 	/* Setup address */
 	IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | 
 			(dev_fn << IT_FUNCNUM_SHF) | (where & ~0x3));
@@ -86,7 +125,7 @@
  * read/write a 32bit word and mask/modify the data we actually want.
  */
 static int
-it8172_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val)
+read_config_byte (struct pci_dev *dev, int where, u8 *val)
 {
 	u32 data = 0;
 
@@ -94,17 +133,15 @@
 		return -1;
 
 	*val = (data >> ((where & 3) << 3)) & 0xff;
-#ifdef DEBUG
-        printk("cfg read byte: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", 
                 dev->bus->number, dev->devfn, where, *val);
-#endif
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
 
 static int
-it8172_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
+read_config_word (struct pci_dev *dev, int where, u16 *val)
 {
 	u32 data = 0;
 
@@ -115,16 +152,14 @@
 	       return -1;
 
 	*val = (data >> ((where & 3) << 3)) & 0xffff;
-#ifdef DEBUG
-        printk("cfg read word: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", 
                 dev->bus->number, dev->devfn, where, *val);
-#endif
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
 static int
-it8172_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
+read_config_dword (struct pci_dev *dev, int where, u32 *val)
 {
 	u32 data = 0;
 
@@ -135,17 +170,15 @@
 		return -1;
 
 	*val = data;
-#ifdef DEBUG
-        printk("cfg read dword: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", 
                 dev->bus->number, dev->devfn, where, *val);
-#endif
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
 
 static int
-it8172_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val)
+write_config_byte (struct pci_dev *dev, int where, u8 val)
 {
 	u32 data = 0;
        
@@ -162,7 +195,7 @@
 }
 
 static int
-it8172_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
+write_config_word (struct pci_dev *dev, int where, u16 val)
 {
         u32 data = 0;
 
@@ -183,7 +216,7 @@
 }
 
 static int
-it8172_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
+write_config_dword(struct pci_dev *dev, int where, u32 val)
 {
 	if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -195,87 +228,16 @@
 }
 
 struct pci_ops it8172_pci_ops = {
-	it8172_pcibios_read_config_byte,
-        it8172_pcibios_read_config_word,
-	it8172_pcibios_read_config_dword,
-	it8172_pcibios_write_config_byte,
-	it8172_pcibios_write_config_word,
-	it8172_pcibios_write_config_dword
+	read_config_byte,
+        read_config_word,
+	read_config_dword,
+	write_config_byte,
+	write_config_word,
+	write_config_dword
 };
 
-void __init pcibios_init(void)
-{
-
-	printk("PCI: Probing PCI hardware on host bus 0.\n");
-	pci_scan_bus(0, &it8172_pci_ops, NULL);
-}
-
-int __init
-pcibios_enable_device(struct pci_dev *dev)
-{
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for(idx=0; idx<6; idx++) {
-		r = &dev->resource[idx];
-		if (!r->start && r->end) {
-			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (dev->resource[PCI_ROM_RESOURCE].start)
-		cmd |= PCI_COMMAND_MEMORY;
-	if (cmd != old_cmd) {
-		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-}
-
-
-void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
-{
-    printk("pcibios_align_resource\n");
-}
-
-char * __init
-pcibios_setup(char *str)
-{
-	/* Nothing to do for now.  */
-
-	return str;
-}
-
-void __init
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-                        struct resource *res, int resource)
-{
-	unsigned long where, size;
-	u32 reg;
-
-	where = PCI_BASE_ADDRESS_0 + (resource * 4);
-	size = res->end - res->start;
-	pci_read_config_dword(dev, where, &reg);
-	reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
-	pci_write_config_dword(dev, where, reg);
-}
-
-void __init pcibios_fixup_bus(struct pci_bus *b)
-{
-	//printk("pcibios_fixup_bus\n");
-}
-
 unsigned __init int pcibios_assign_all_busses(void)
 {
-	return 1;
+       return 1;
 }
-
 #endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/generic/it8172_setup.c linux/arch/mips/ite-boards/generic/it8172_setup.c
--- linux.orig/arch/mips/ite-boards/generic/it8172_setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/generic/it8172_setup.c	2002-07-20 01:08:34.000000000 +0000
@@ -53,7 +53,6 @@
 
 extern struct rtc_ops it8172_rtc_ops;
 extern struct resource ioport_resource;
-extern unsigned long mips_io_port_base;
 #ifdef CONFIG_BLK_DEV_IDE
 extern struct ide_ops std_ide_ops;
 extern struct ide_ops *ide_ops;
@@ -70,6 +69,14 @@
 extern void it8172_halt(void);
 extern void it8172_power_off(void);
 
+extern void (*board_time_init)(void);
+extern void (*board_timer_setup)(struct irqaction *irq);
+extern unsigned long (*rtc_get_time)(void);
+extern int (*rtc_set_time)(unsigned long);
+extern void it8172_time_init(void);
+extern void it8172_timer_setup(struct irqaction *irq);
+extern unsigned long it8172_rtc_get_time(void);
+
 #ifdef CONFIG_IT8172_REVC
 struct {
     struct resource ram;
@@ -116,6 +123,7 @@
 {
 	unsigned short dsr;
 	char *argptr;
+	u32 it_ver;
 
 	argptr = prom_getcmdline();
 #ifdef CONFIG_SERIAL_CONSOLE
@@ -128,6 +136,11 @@
 	clear_cp0_status(ST0_FR);
 	rtc_ops = &it8172_rtc_ops;
 
+	board_time_init = it8172_time_init;
+	board_timer_setup = it8172_timer_setup;
+	rtc_get_time = it8172_rtc_get_time;
+	//rtc_set_time = it8172_rtc_set_time;
+
 	_machine_restart = it8172_restart;
 	_machine_halt = it8172_halt;
 	_machine_power_off = it8172_power_off;
@@ -137,7 +150,7 @@
 	*
 	* revisit this area.
 	*/
-	mips_io_port_base = KSEG1;
+	set_io_port_base(KSEG1);
 	ioport_resource.start = it8172_resources.pci_io.start;
 	ioport_resource.end = it8172_resources.pci_io.end;
 #ifdef CONFIG_IT8172_REVC
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/generic/pmon_prom.c linux/arch/mips/ite-boards/generic/pmon_prom.c
--- linux.orig/arch/mips/ite-boards/generic/pmon_prom.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/generic/pmon_prom.c	2002-07-20 01:08:21.000000000 +0000
@@ -44,7 +44,7 @@
 
 /* #define DEBUG_CMDLINE */
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
 extern int prom_argc;
 extern char **prom_argv, **prom_envp;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/generic/time.c linux/arch/mips/ite-boards/generic/time.c
--- linux.orig/arch/mips/ite-boards/generic/time.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/generic/time.c	2002-07-20 01:08:34.000000000 +0000
@@ -28,135 +28,18 @@
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
 
 #include <asm/mipsregs.h>
 #include <asm/ptrace.h>
 #include <asm/it8172/it8172_int.h>
+#include <asm/debug.h>
 
-#include <linux/mc146818rtc.h>
-#include <linux/timex.h>
-
-extern void enable_cpu_timer(void);
-extern volatile unsigned long wall_jiffies;
-extern rwlock_t xtime_lock;
-
-unsigned long missed_heart_beats = 0;
-static long last_rtc_update = 0;
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-static unsigned int timer_tick_count=0;
-
-static inline void ack_r4ktimer(unsigned long newval)
-{
-	write_32bit_cp0_register(CP0_COMPARE, newval);
-}
-
-
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you won't notice until after reboot!
- */
-static int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned char save_control, save_freq_select;
-
-	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-	cmos_minutes = CMOS_READ(RTC_MINUTES);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
- 		retval = -1;
-	}
-
-	/* The following flags have to be released exactly in this order,
-	 * otherwise the DS12887 (popular MC146818A clone with integrated
-	 * battery and quartz) will not reset the oscillator and will not
-	 * update precisely 500 ms later. You won't find this mentioned in
-	 * the Dallas Semiconductor data sheets, but who believes data
-	 * sheets anyway ...                           -- Markus Kuhn
-	 */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
-	return retval;
-}
-
-
-/*
- * There are a lot of conceptually broken versions of the MIPS timer interrupt
- * handler floating around.  This one is rather different, but the algorithm
- * is provably more robust.
- */
-void mips_timer_interrupt(struct pt_regs *regs)
-{
-	if (r4k_offset == 0)
-		goto null;
-
-	do {
-		kstat.irqs[0][MIPS_CPU_TIMER_IRQ]++;
-		do_timer(regs);
-
-		/* Historical comment/code:
- 		 * RTC time of day s updated approx. every 11 
- 		 * minutes.  Because of how the numbers work out 
- 		 * we need to make absolutely sure we do this update
- 		 * within 500ms before the * next second starts, 
- 		 * thus the following code.
- 		 */
-		read_lock(&xtime_lock);
-		if ((time_status & STA_UNSYNC) == 0 
-		    && xtime.tv_sec > last_rtc_update + 660 
-		    && xtime.tv_usec >= 500000 - (tick >> 1) 
-		    && xtime.tv_usec <= 500000 + (tick >> 1))
-			if (set_rtc_mmss(xtime.tv_sec) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else {
-				/* do it again in 60 s */
-	    			last_rtc_update = xtime.tv_sec - 600; 
-			}
-		read_unlock(&xtime_lock);
-
-		r4k_cur += r4k_offset;
-		ack_r4ktimer(r4k_cur);
-
-	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
-	         - r4k_cur) < 0x7fffffff);
-
-	return;
-
-null:
-	ack_r4ktimer(0);
-}
+extern unsigned int mips_counter_frequency;
+extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
 
 /* 
  * Figure out the r4k offset, the amount to increment the compare
@@ -165,7 +48,6 @@
  */
 static unsigned long __init cal_r4koff(void)
 {
-	unsigned long count;
 	unsigned int flags;
 
 	__save_and_cli(flags);
@@ -181,15 +63,15 @@
 	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
 	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 
-	count = read_32bit_cp0_register(CP0_COUNT);
+	mips_counter_frequency = read_32bit_cp0_register(CP0_COUNT);
 
 	/* restore interrupts */
 	__restore_flags(flags);
 		
-	return (count / HZ);
+	return (mips_counter_frequency / HZ);
 }
 
-static unsigned long __init get_mips_time(void)
+unsigned long it8172_rtc_get_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
 	unsigned char save_control;
@@ -224,10 +106,11 @@
 	return mktime(year, mon, day, hour, min, sec);
 }
 
-void __init time_init(void)
+void __init it8172_time_init(void)
 {
         unsigned int est_freq, flags;
 
+	__save_and_cli(flags);
         /* Set Data mode - binary. */ 
         CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
 
@@ -240,140 +123,25 @@
 	est_freq -= est_freq%10000;
 	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
 	       (est_freq%1000000)*100/1000000);
-	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
-
-	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
-
-	enable_cpu_timer();
-
-	/* Read time from the RTC chipset. */
-	write_lock_irqsave (&xtime_lock, flags);
-	xtime.tv_sec = get_mips_time();
-	xtime.tv_usec = 0;
-	write_unlock_irqrestore(&xtime_lock, flags);
-}
-
-/* This is for machines which generate the exact clock. */
-#define USECS_PER_JIFFY (1000000/HZ)
-
-/* Cycle counter value at the previous timer interrupt.. */
-
-static unsigned int timerhi = 0, timerlo = 0;
-
-/*
- * FIXME: Does playing with the RP bit in c0_status interfere with this code?
- */
-static unsigned long do_fast_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res, tmp;
-
-	/* Last jiffy when do_fast_gettimeoffset() was called. */
-	static unsigned long last_jiffies=0;
-	unsigned long quotient;
-
-	/*
-	 * Cached "1/(clocks per usec)*2^32" value.
-	 * It has to be recalculated once each jiffy.
-	 */
-	static unsigned long cached_quotient=0;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-
-	if (tmp && last_jiffies != tmp) {
-		last_jiffies = tmp;
-		__asm__(".set\tnoreorder\n\t"
-			".set\tnoat\n\t"
-			".set\tmips3\n\t"
-			"lwu\t%0,%2\n\t"
-			"dsll32\t$1,%1,0\n\t"
-			"or\t$1,$1,%0\n\t"
-			"ddivu\t$0,$1,%3\n\t"
-			"mflo\t$1\n\t"
-			"dsll32\t%0,%4,0\n\t"
-			"nop\n\t"
-			"ddivu\t$0,%0,$1\n\t"
-			"mflo\t%0\n\t"
-			".set\tmips0\n\t"
-			".set\tat\n\t"
-			".set\treorder"
-			:"=&r" (quotient)
-			:"r" (timerhi),
-			 "m" (timerlo),
-			 "r" (tmp),
-			 "r" (USECS_PER_JIFFY)
-			:"$1");
-		cached_quotient = quotient;
-	}
-
-	/* Get last timer tick in absolute kernel time */
-	count = read_32bit_cp0_register(CP0_COUNT);
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu\t%1,%2\n\t"
-		"mfhi\t%0"
-		:"=r" (res)
-		:"r" (count),
-		 "r" (quotient));
-
-	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY-1;
-
-	return res;
+	__restore_flags(flags);
 }
 
-void do_gettimeofday(struct timeval *tv)
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+void __init it8172_timer_setup(struct irqaction *irq)
 {
-	unsigned int flags;
+	puts("timer_setup\n");
+	put32(NR_IRQS);
+	puts("");
+        /* we are using the cpu counter for timer interrupts */
+	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
 
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_fast_gettimeoffset();
-
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
-
-	read_unlock_irqrestore (&xtime_lock, flags);
-
-	if (tv->tv_usec >= 1000000) {
-		tv->tv_usec -= 1000000;
-		tv->tv_sec++;
-	}
+        /* to generate the first timer interrupt */
+	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+	set_cp0_status(ALLINTS);
 }
 
-void do_settimeofday(struct timeval *tv)
+void local_timer_interrupt(struct pt_regs *regs)
 {
-	write_lock_irq (&xtime_lock);
-
-	/* This is revolting. We need to set the xtime.tv_usec correctly.
-	 * However, the value in this location is is value at the last tick.
-	 * Discover what correction gettimeofday would have done, and then
-	 * undo it!
-	 */
-	tv->tv_usec -= do_fast_gettimeoffset();
-
-	if (tv->tv_usec < 0) {
-		tv->tv_usec += 1000000;
-		tv->tv_sec--;
-	}
-
-	xtime = *tv;
-	time_adjust = 0;		/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-
-	write_unlock_irq (&xtime_lock);
+	do_IRQ(MIPS_CPU_TIMER_IRQ, regs);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/ivr/Makefile linux/arch/mips/ite-boards/ivr/Makefile
--- linux.orig/arch/mips/ite-boards/ivr/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/ivr/Makefile	2002-07-20 01:08:36.000000000 +0000
@@ -22,7 +22,6 @@
 
 obj-y := init.o 
 
-obj-CONFIG_PCI += pci_fixup.o
-obj-CONFIG_BLK_DEV_INITRD += le_ramdisk.o
+obj-$(CONFIG_PCI) += pci_fixup.o 
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/ivr/init.c linux/arch/mips/ite-boards/ivr/init.c
--- linux.orig/arch/mips/ite-boards/ivr/init.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/ivr/init.c	2002-07-20 01:08:35.000000000 +0000
@@ -52,6 +52,10 @@
 #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 #define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
 
+const char *get_system_type(void)
+{
+	return "Globespan IVR";
+}
 
 int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/ivr/pci_fixup.c linux/arch/mips/ite-boards/ivr/pci_fixup.c
--- linux.orig/arch/mips/ite-boards/ivr/pci_fixup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/ivr/pci_fixup.c	2002-07-20 01:08:30.000000000 +0000
@@ -40,10 +40,19 @@
 #include <asm/it8172/it8172_pci.h>
 #include <asm/it8172/it8172_int.h>
 
-void __init board_int_line_fixup(struct pci_dev *dev)     
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
 {
 	unsigned int slot, func;
 	unsigned char pin;
+	struct pci_dev *dev;
         const int internal_func_irqs[7] = {
             IT8172_AC97_IRQ,
             IT8172_DMA_IRQ,
@@ -54,57 +63,51 @@
             IT8172_MC68K_IRQ
         };
 
-#ifdef DEBUG
-	printk("board_int_line_fixup bus %d\n", dev->bus->number);
-#endif
-	if (dev->bus->number != 0)
-		return;
-
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-
-#ifdef DEBUG
-	pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
-#endif
-
-	slot = PCI_SLOT(dev->devfn);
-        func = PCI_FUNC(dev->devfn);
+	pci_for_each_dev(dev) {
+		if (dev->bus->number != 0)
+			return;
 
-	switch (slot) {
-                case 0x01:
-                    /*
-                     * Internal device 1 is actually 7 different internal
-                     * devices on the IT8172G (a multi-function device).
-                     */
-                    if (func < 7)
-                        dev->irq = internal_func_irqs[func];
-                    break;
-		case 0x11:
-			switch (pin) {
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		slot = PCI_SLOT(dev->devfn);
+		func = PCI_FUNC(dev->devfn);
+
+		switch (slot) {
+			case 0x01:
+			    /*
+			     * Internal device 1 is actually 7 different 
+			     * internal devices on the IT8172G (multi-function 
+			     * device).
+			     */
+			    if (func < 7)
+				dev->irq = internal_func_irqs[func];
+			    break;
+			case 0x11:   // Realtek RTL-8139
+				switch (pin) {
+					case 0: /* pin A, hardware bug */
+					case 1: /* pin A */
+						dev->irq = IT8172_PCI_INTC_IRQ;
+						break;
+					case 2: /* pin B */
+						dev->irq = IT8172_PCI_INTD_IRQ;
+						break;
+					case 3: /* pin C */
+						dev->irq = IT8172_PCI_INTA_IRQ;
+						break;
+					case 4: /* pin D */
+						dev->irq = IT8172_PCI_INTB_IRQ;
+						break;
+					default:
+						dev->irq = 0xff; 
+						break;
+
+				}
+				break;
+			case 0x12:   // ivr slot
+				switch (pin) {
 				case 0: /* pin A, hardware bug */
 				case 1: /* pin A */
-					dev->irq = IT8172_PCI_INTC_IRQ;
-					break;
-				case 2: /* pin B */
-					dev->irq = IT8172_PCI_INTD_IRQ;
-					break;
-				case 3: /* pin C */
-					dev->irq = IT8172_PCI_INTA_IRQ;
-					break;
-				case 4: /* pin D */
 					dev->irq = IT8172_PCI_INTB_IRQ;
 					break;
-				default:
-					dev->irq = 0xff; 
-					break;
-
-			}
-			break;
-		case 0x13:
-			switch (pin) {
-				case 0: /* pin A, hardware bug */
-				case 1: /* pin A */
-					dev->irq = IT8172_PCI_INTA_IRQ;
-					break;
 				case 2: /* pin B */
 					dev->irq = IT8172_PCI_INTB_IRQ;
 					break;
@@ -118,22 +121,37 @@
 					dev->irq = 0xff; 
 					break;
 
-			}
-			break;
-		default:
-			return;
-	}
-
+				}
+				break;
+			case 0x13:   // expansion slot
+				switch (pin) {
+					case 0: /* pin A, hardware bug */
+					case 1: /* pin A */
+						dev->irq = IT8172_PCI_INTA_IRQ;
+						break;
+					case 2: /* pin B */
+						dev->irq = IT8172_PCI_INTB_IRQ;
+						break;
+					case 3: /* pin C */
+						dev->irq = IT8172_PCI_INTC_IRQ;
+						break;
+					case 4: /* pin D */
+						dev->irq = IT8172_PCI_INTD_IRQ;
+						break;
+					default:
+						dev->irq = 0xff; 
+						break;
+
+				}
+				break;
+			default:
+				break;
+		}
 #ifdef DEBUG
-	printk("irq fixup: slot %d, vendor %x, int line %d, int number %d\n",
-			slot, vendor, pin, dev->irq);
+		printk("irq fixup: slot %d, int line %d, int number %d\n",
+			slot, pin, dev->irq);
 #endif
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	}
 }
-
-struct pci_fixup pcibios_fixups[] = {
-	{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, board_int_line_fixup },
-	{ 0 }
-};
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/qed-4n-s01b/Makefile linux/arch/mips/ite-boards/qed-4n-s01b/Makefile
--- linux.orig/arch/mips/ite-boards/qed-4n-s01b/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/qed-4n-s01b/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -16,22 +16,11 @@
 .S.o:
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
-all: ite.o
-
 O_TARGET := ite.o
 
 obj-y := init.o 
 
-ifdef CONFIG_PCI
-obj-y += pci_fixup.o
-endif
-
-ifdef CONFIG_BLK_DEV_INITRD
-obj-y += le_ramdisk.o
-endif
-
-
-dep:
-	$(CPP) -M *.c > .depend
+obj-$(CONFIG_PCI) += pci_fixup.o
+obj-$(CONFIG_BLK_DEV_INITRD) += le_ramdisk.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/qed-4n-s01b/init.c linux/arch/mips/ite-boards/qed-4n-s01b/init.c
--- linux.orig/arch/mips/ite-boards/qed-4n-s01b/init.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/qed-4n-s01b/init.c	2002-07-20 01:08:40.000000000 +0000
@@ -52,6 +52,10 @@
 #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 #define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
 
+const char *get_system_type(void)
+{
+	return "ITE QED-4N-S01B";
+}
 
 int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c linux/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c
--- linux.orig/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c	2002-07-20 01:08:29.000000000 +0000
@@ -40,10 +40,19 @@
 #include <asm/it8172/it8172_pci.h>
 #include <asm/it8172/it8172_int.h>
 
-void __init board_int_line_fixup(struct pci_dev *dev)     
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
 {
 	unsigned int slot, func;
 	unsigned char pin;
+	struct pci_dev *dev;
         const int internal_func_irqs[7] = {
             IT8172_AC97_IRQ,
             IT8172_DMA_IRQ,
@@ -54,144 +63,133 @@
             IT8172_MC68K_IRQ
         };
 
-#ifdef DEBUG
-	printk("board_int_line_fixup bus %d\n", dev->bus->number);
-#endif
-	if (dev->bus->number != 0)
-		return;
-
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-
-#ifdef DEBUG
-	pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
-#endif
-
-	slot = PCI_SLOT(dev->devfn);
-        func = PCI_FUNC(dev->devfn);
-
-	switch (slot) {
-                case 0x01:
-                    /*
-                     * Internal device 1 is actually 7 different internal
-                     * devices on the IT8172G (a multi-function device).
-                     */
-                    if (func < 7)
-                        dev->irq = internal_func_irqs[func];
-                    break;
-		case 0x10:
-			switch (pin) {
-				case 1: /* pin A */
-					dev->irq = IT8172_PCI_INTA_IRQ;
-					break;
-				case 2: /* pin B */
-					dev->irq = IT8172_PCI_INTB_IRQ;
-					break;
-				case 3: /* pin C */
-					dev->irq = IT8172_PCI_INTC_IRQ;
-					break;
-				case 4: /* pin D */
-					dev->irq = IT8172_PCI_INTD_IRQ;
-					break;
-				default:
-					dev->irq = 0xff; 
-					break;
-
-			}
-			break;
-		case 0x11:
-			switch (pin) {
-				case 1: /* pin A */
-					dev->irq = IT8172_PCI_INTA_IRQ;
-					break;
-				case 2: /* pin B */
-					dev->irq = IT8172_PCI_INTB_IRQ;
-					break;
-				case 3: /* pin C */
-					dev->irq = IT8172_PCI_INTC_IRQ;
-					break;
-				case 4: /* pin D */
-					dev->irq = IT8172_PCI_INTD_IRQ;
-					break;
-				default:
-					dev->irq = 0xff; 
-					break;
-
-			}
-			break;
-		case 0x12:
-			switch (pin) {
-				case 1: /* pin A */
-					dev->irq = IT8172_PCI_INTB_IRQ;
-					break;
-				case 2: /* pin B */
-					dev->irq = IT8172_PCI_INTC_IRQ;
-					break;
-				case 3: /* pin C */
-					dev->irq = IT8172_PCI_INTD_IRQ;
-					break;
-				case 4: /* pin D */
-					dev->irq = IT8172_PCI_INTA_IRQ;
-					break;
-				default:
-					dev->irq = 0xff; 
-					break;
-
-			}
-			break;
-		case 0x13:
-			switch (pin) {
-				case 1: /* pin A */
-					dev->irq = IT8172_PCI_INTC_IRQ;
-					break;
-				case 2: /* pin B */
-					dev->irq = IT8172_PCI_INTD_IRQ;
-					break;
-				case 3: /* pin C */
-					dev->irq = IT8172_PCI_INTA_IRQ;
-					break;
-				case 4: /* pin D */
-					dev->irq = IT8172_PCI_INTB_IRQ;
-					break;
-				default:
-					dev->irq = 0xff; 
-					break;
-
-			}
-			break;
-		case 0x14:
-			switch (pin) {
-				case 1: /* pin A */
-					dev->irq = IT8172_PCI_INTD_IRQ;
-					break;
-				case 2: /* pin B */
-					dev->irq = IT8172_PCI_INTA_IRQ;
-					break;
-				case 3: /* pin C */
-					dev->irq = IT8172_PCI_INTB_IRQ;
-					break;
-				case 4: /* pin D */
-					dev->irq = IT8172_PCI_INTC_IRQ;
-					break;
-				default:
-					dev->irq = 0xff; 
-					break;
-
-			}
-			break;
-		default:
+	pci_for_each_dev(dev) {
+		if (dev->bus->number != 0) {
 			return;
-	}
+		}
 
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		slot = PCI_SLOT(dev->devfn);
+		func = PCI_FUNC(dev->devfn);
+
+		switch (slot) {
+			case 0x01:
+			    /*
+			     * Internal device 1 is actually 7 different 
+			     * internal devices on the IT8172G (a multi-
+			     * function device).
+			     */
+			    if (func < 7)
+				dev->irq = internal_func_irqs[func];
+			    break;
+			case 0x10:
+				switch (pin) {
+					case 1: /* pin A */
+						dev->irq = IT8172_PCI_INTA_IRQ;
+						break;
+					case 2: /* pin B */
+						dev->irq = IT8172_PCI_INTB_IRQ;
+						break;
+					case 3: /* pin C */
+						dev->irq = IT8172_PCI_INTC_IRQ;
+						break;
+					case 4: /* pin D */
+						dev->irq = IT8172_PCI_INTD_IRQ;
+						break;
+					default:
+						dev->irq = 0xff; 
+						break;
+
+				}
+				break;
+			case 0x11:
+				switch (pin) {
+					case 1: /* pin A */
+						dev->irq = IT8172_PCI_INTA_IRQ;
+						break;
+					case 2: /* pin B */
+						dev->irq = IT8172_PCI_INTB_IRQ;
+						break;
+					case 3: /* pin C */
+						dev->irq = IT8172_PCI_INTC_IRQ;
+						break;
+					case 4: /* pin D */
+						dev->irq = IT8172_PCI_INTD_IRQ;
+						break;
+					default:
+						dev->irq = 0xff; 
+						break;
+
+				}
+				break;
+			case 0x12:
+				switch (pin) {
+					case 1: /* pin A */
+						dev->irq = IT8172_PCI_INTB_IRQ;
+						break;
+					case 2: /* pin B */
+						dev->irq = IT8172_PCI_INTC_IRQ;
+						break;
+					case 3: /* pin C */
+						dev->irq = IT8172_PCI_INTD_IRQ;
+						break;
+					case 4: /* pin D */
+						dev->irq = IT8172_PCI_INTA_IRQ;
+						break;
+					default:
+						dev->irq = 0xff; 
+						break;
+
+				}
+				break;
+			case 0x13:
+				switch (pin) {
+					case 1: /* pin A */
+						dev->irq = IT8172_PCI_INTC_IRQ;
+						break;
+					case 2: /* pin B */
+						dev->irq = IT8172_PCI_INTD_IRQ;
+						break;
+					case 3: /* pin C */
+						dev->irq = IT8172_PCI_INTA_IRQ;
+						break;
+					case 4: /* pin D */
+						dev->irq = IT8172_PCI_INTB_IRQ;
+						break;
+					default:
+						dev->irq = 0xff; 
+						break;
+
+				}
+				break;
+			case 0x14:
+				switch (pin) {
+					case 1: /* pin A */
+						dev->irq = IT8172_PCI_INTD_IRQ;
+						break;
+					case 2: /* pin B */
+						dev->irq = IT8172_PCI_INTA_IRQ;
+						break;
+					case 3: /* pin C */
+						dev->irq = IT8172_PCI_INTB_IRQ;
+						break;
+					case 4: /* pin D */
+						dev->irq = IT8172_PCI_INTC_IRQ;
+						break;
+					default:
+						dev->irq = 0xff; 
+						break;
+
+				}
+				break;
+			default:
+				continue; /* do nothing */
+		}
 #ifdef DEBUG
-	printk("irq fixup: slot %d, vendor %x, int line %d, int number %d\n",
-			slot, vendor, pin, dev->irq);
+		printk("irq fixup: slot %d, int line %d, int number %d\n",
+			slot, pin, dev->irq);
 #endif
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	}
 }
-
-struct pci_fixup pcibios_fixups[] = {
-	{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, board_int_line_fixup },
-	{ 0 }
-};
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/common/Makefile linux/arch/mips/jmr3927/common/Makefile
--- linux.orig/arch/mips/jmr3927/common/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/common/Makefile	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,18 @@
+#
+# Makefile for the common code of TOSHIBA JMR-TX3927 board
+#
+# 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).
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET:= tx3927.o
+
+obj-y	 += prom.o puts.o rtc_ds1742.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/common/prom.c linux/arch/mips/jmr3927/common/prom.c
--- linux.orig/arch/mips/jmr3927/common/prom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/common/prom.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,91 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *    PROM library initialisation code, assuming a version of
+ *    pmon is the boot code.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * Based on arch/mips/au1000/common/prom.c
+ *
+ * This file was derived from Carsten Langgaard's 
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+/* #define DEBUG_CMDLINE */
+
+char arcs_cmdline[CL_SIZE];
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
+
+typedef struct
+{
+    char *name;
+/*    char *val; */
+}t_env_var;
+
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv[actr]);
+		cp += strlen(prom_argv[actr]);
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+    return 1;
+}
+
+void prom_free_prom_memory (void)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/common/puts.c linux/arch/mips/jmr3927/common/puts.c
--- linux.orig/arch/mips/jmr3927/common/puts.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/common/puts.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,168 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Low level uart routines to directly access a TX[34]927 SIO.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ahennessy@mvista.com or source@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation 
+ *
+ * Based on arch/mips/au1000/common/puts.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <asm/jmr3927/txx927.h>
+#include <asm/jmr3927/tx3927.h>
+#include <asm/jmr3927/jmr3927.h>
+
+#define TIMEOUT       0xffffff
+#define SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+
+#ifdef SLOW_DOWN
+#define slow_down() { int k; for (k=0; k<10000; k++); }
+#else
+#define slow_down()
+#endif
+
+void
+putch(const unsigned char c)
+{
+        int i = 0;
+	
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS));
+	tx3927_sioptr(1)->tfifo = c;
+	return;
+}
+
+unsigned char getch(void)
+{
+        int i = 0;
+	int dicr;
+	char c;
+	
+	/* diable RX int. */
+	dicr = tx3927_sioptr(1)->dicr;
+	tx3927_sioptr(1)->dicr = 0;
+
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (tx3927_sioptr(1)->disr & TXx927_SIDISR_UVALID)
+		;
+	c = tx3927_sioptr(1)->rfifo;
+
+	/* clear RX int. status */
+	tx3927_sioptr(1)->disr &= ~TXx927_SIDISR_RDIS;
+	/* enable RX int. */
+	tx3927_sioptr(1)->dicr = dicr;
+
+	return c;
+}
+void
+do_jmr3927_led_set(char n)
+{
+    /* and with current leds */
+    jmr3927_led_and_set(n);
+}
+
+void
+puts(unsigned char *cp)
+{
+    int i = 0;
+
+    while (*cp) {
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS));
+	tx3927_sioptr(1)->tfifo = *cp++;
+    }
+    putch('\r');
+    putch('\n');
+}
+
+void
+fputs(unsigned char *cp)
+{
+    int i = 0;
+
+    while (*cp) {
+        do {
+             slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS));
+	tx3927_sioptr(1)->tfifo = *cp++;
+    }
+}
+
+
+void
+put64(uint64_t ul)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 16;            /* 16 nibbles in a 64 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
+
+void
+put32(unsigned u)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 8;            /* 8 nibbles in a 32 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(u >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/common/rtc_ds1742.c linux/arch/mips/jmr3927/common/rtc_ds1742.c
--- linux.orig/arch/mips/jmr3927/common/rtc_ds1742.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/common/rtc_ds1742.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,173 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * arch/mips/jmr3927/common/rtc_ds1742.c
+ * Based on arch/mips/ddb5xxx/common/rtc_ds1386.c
+ *     low-level RTC hookups for s for Dallas 1742 chip.
+ *
+ * Copyright (C) 2000-2001 Toshiba 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************
+ */
+
+
+/*
+ * This file exports a function, rtc_ds1386_init(), which expects an
+ * uncached base address as the argument.  It will set the two function
+ * pointers expected by the MIPS generic timer code.
+ */
+
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+
+#include <asm/jmr3927/ds1742rtc.h>
+#include <asm/debug.h>
+
+#define	EPOCH		2000
+
+#undef BCD_TO_BIN
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+
+#undef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+
+static unsigned long rtc_base;
+
+static unsigned long
+rtc_ds1742_get_time(void)
+{
+	unsigned int year, month, day, hour, minute, second;
+	unsigned int century;
+
+	CMOS_WRITE(RTC_READ, RTC_CONTROL);
+	second = BCD_TO_BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
+	minute = BCD_TO_BIN(CMOS_READ(RTC_MINUTES));
+	hour = BCD_TO_BIN(CMOS_READ(RTC_HOURS));
+	day = BCD_TO_BIN(CMOS_READ(RTC_DATE));
+	month = BCD_TO_BIN(CMOS_READ(RTC_MONTH));
+	year = BCD_TO_BIN(CMOS_READ(RTC_YEAR));
+	century = BCD_TO_BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK);
+	CMOS_WRITE(0, RTC_CONTROL);
+
+	year += century * 100;
+
+	return mktime(year, month, day, hour, minute, second);
+}
+extern void to_tm(unsigned long tim, struct rtc_time * tm);
+
+static int 
+rtc_ds1742_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+	u8 year, month, day, hour, minute, second;
+	u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second;
+	int cmos_century;
+
+	CMOS_WRITE(RTC_READ, RTC_CONTROL);
+	cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
+	cmos_minute = (u8)CMOS_READ(RTC_MINUTES);
+	cmos_hour = (u8)CMOS_READ(RTC_HOURS);
+	cmos_day = (u8)CMOS_READ(RTC_DATE);
+	cmos_month = (u8)CMOS_READ(RTC_MONTH);
+	cmos_year = (u8)CMOS_READ(RTC_YEAR);
+	cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK;
+
+	CMOS_WRITE(RTC_WRITE, RTC_CONTROL);
+
+	/* convert */
+	to_tm(t, &tm);
+
+	/* check each field one by one */
+	year = BIN_TO_BCD(tm.tm_year - EPOCH);
+	if (year != cmos_year) {
+		CMOS_WRITE(year,RTC_YEAR);
+	}
+
+	month = BIN_TO_BCD(tm.tm_mon);
+	if (month != (cmos_month & 0x1f)) {
+		CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH);
+	}
+
+	day = BIN_TO_BCD(tm.tm_mday);
+	if (day != cmos_day) {
+	
+		CMOS_WRITE(day, RTC_DATE);
+	}
+
+	if (cmos_hour & 0x40) {
+		/* 12 hour format */
+		hour = 0x40;
+		if (tm.tm_hour > 12) {
+			hour |= 0x20 | (BIN_TO_BCD(hour-12) & 0x1f);
+		} else {
+			hour |= BIN_TO_BCD(tm.tm_hour);
+		}
+	} else {
+		/* 24 hour format */
+		hour = BIN_TO_BCD(tm.tm_hour) & 0x3f;
+	}
+	if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS);
+
+	minute = BIN_TO_BCD(tm.tm_min);
+	if (minute !=  cmos_minute) {
+		CMOS_WRITE(minute, RTC_MINUTES);
+	}
+
+	second = BIN_TO_BCD(tm.tm_sec);
+	if (second !=  cmos_second) {
+		CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS);
+	}
+	
+	/* RTC_CENTURY and RTC_CONTROL share same address... */
+	CMOS_WRITE(cmos_century, RTC_CONTROL);
+
+	return 0;
+}
+
+void
+rtc_ds1742_init(unsigned long base)
+{
+	u8  cmos_second;
+
+	/* remember the base */
+	rtc_base = base;
+	db_assert((rtc_base & 0xe0000000) == KSEG1);
+
+	/* set the function pointers */
+	rtc_get_time = rtc_ds1742_get_time;
+	rtc_set_time = rtc_ds1742_set_time;
+
+	/* clear oscillator stop bit */
+	CMOS_WRITE(RTC_READ, RTC_CONTROL);
+	cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
+	CMOS_WRITE(RTC_WRITE, RTC_CONTROL);
+	CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */
+	CMOS_WRITE(0, RTC_CONTROL);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/Makefile linux/arch/mips/jmr3927/rbhma3100/Makefile
--- linux.orig/arch/mips/jmr3927/rbhma3100/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/Makefile	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,21 @@
+#
+# Makefile for TOSHIBA JMR-TX3927 board
+#
+# 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).
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET:= jmr3927.o
+
+obj-y	 += init.o int-handler.o irq.o setup.o rtc.o pci_fixup.o pci_ops.o
+
+obj-$(CONFIG_LL_DEBUG) 		+= debug.o
+obj-$(CONFIG_REMOTE_DEBUG)	+= kgdb_io.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/init.c linux/arch/mips/jmr3927/rbhma3100/init.c
--- linux.orig/arch/mips/jmr3927/rbhma3100/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/init.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,80 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * arch/mips/jmr3927/common/init.c
+ *
+ * Copyright (C) 2000-2001 Toshiba 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/jmr3927/jmr3927.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+unsigned long mips_nofpu = 0;
+
+const char *get_system_type(void)
+{
+	return "Toshiba"
+#ifdef CONFIG_TOSHIBA_JMR3927
+	       " JMR_TX3927"
+#endif
+	;
+}
+
+extern void puts(unsigned char *cp);
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+#ifdef CONFIG_TOSHIBA_JMR3927
+	/* CCFG */
+	if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0)
+		puts("Warning: TX3927 TLB off\n");
+#endif
+	prom_argc = argc;
+	prom_argv = argv;
+	prom_envp = envp;     
+
+	mips_machgroup = MACH_GROUP_TOSHIBA;
+
+#ifdef CONFIG_TOSHIBA_JMR3927
+	mips_machtype = MACH_TOSHIBA_JMR3927;
+#endif
+
+	prom_init_cmdline();
+	add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM);
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/int-handler.S linux/arch/mips/jmr3927/rbhma3100/int-handler.S
--- linux.orig/arch/mips/jmr3927/rbhma3100/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/int-handler.S	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * Based on arch/mips/tsdb/kernel/int-handler.S
+ *
+ * Copyright (C) 2000-2001 Toshiba 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/jmr3927/jmr3927.h>
+
+	/* A lot of complication here is taken away because:
+	 *
+	 * 1) We handle one interrupt and return, sitting in a loop
+	 *    and moving across all the pending IRQ bits in the cause
+	 *    register is _NOT_ the answer, the common case is one
+	 *    pending IRQ so optimize in that direction.
+	 *
+	 * 2) We need not check against bits in the status register
+	 *    IRQ mask, that would make this routine slow as hell.
+	 *
+	 * 3) Linux only thinks in terms of all IRQs on or all IRQs
+	 *    off, nothing in between like BSD spl() brain-damage.
+	 *
+	 */
+
+/* Flush write buffer (needed?)
+ * NOTE: TX39xx performs "non-blocking load", so explicitly use the target
+ * register of LBU to flush immediately.
+ */
+#define FLUSH_WB(tmp)	\
+	la	tmp, JMR3927_IOC_REV_ADDR; \
+	lbu	tmp, (tmp); \
+	move	tmp, zero;
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(jmr3927_IRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	jal	jmr3927_irc_irqdispatch
+	 move	a0, sp
+	FLUSH_WB(t0)
+	j	ret_from_irq
+	 nop
+	END(jmr3927_IRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/irq.c linux/arch/mips/jmr3927/rbhma3100/irq.c
--- linux.orig/arch/mips/jmr3927/rbhma3100/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/irq.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,515 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Toshiba 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/jmr3927/irq.h>
+#include <asm/debug.h>
+#include <asm/jmr3927/jmr3927.h>
+
+#if JMR3927_IRQ_END > NR_IRQS
+#error JMR3927_IRQ_END > NR_IRQS
+#endif
+
+struct tb_irq_space* tb_irq_spaces;
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+
+static int jmr3927_irq_base=-1;
+
+#ifdef CONFIG_PCI
+static int jmr3927_gen_iack(void)
+{
+	/* generate ACK cycle */
+#ifdef __BIG_ENDIAN
+	return (tx3927_pcicptr->iiadp >> 24) & 0xff;
+#else
+	return tx3927_pcicptr->iiadp & 0xff;
+#endif
+}
+#endif
+
+extern asmlinkage void jmr3927_IRQ(void);
+
+#define irc_dlevel	0
+#define irc_elevel	1
+static unsigned char irc_level[TX3927_NUM_IR] = {
+	5, 5, 5, 5, 5, 5,	/* INT[5:0] */
+	7, 7,			/* SIO */
+	5, 5, 5, 0, 0,		/* DMA, PIO, PCI */
+	6, 6, 6			/* TMR */
+};
+
+static inline void mask_irq(unsigned int irq_nr)
+{
+	struct tb_irq_space* sp;
+	for (sp = tb_irq_spaces; sp; sp = sp->next) {
+		if (sp->start_irqno <= irq_nr &&
+		    irq_nr < sp->start_irqno + sp->nr_irqs) {
+			if (sp->mask_func)
+				sp->mask_func(irq_nr - sp->start_irqno,
+					      sp->space_id);
+			break;
+		}
+	}
+}
+
+static inline void unmask_irq(unsigned int irq_nr)
+{
+	struct tb_irq_space* sp;
+	for (sp = tb_irq_spaces; sp; sp = sp->next) {
+		if (sp->start_irqno <= irq_nr &&
+		    irq_nr < sp->start_irqno + sp->nr_irqs) {
+			if (sp->unmask_func)
+				sp->unmask_func(irq_nr - sp->start_irqno,
+						sp->space_id);
+			break;
+		}
+	}
+}
+
+static void jmr3927_irq_disable(unsigned int irq_nr);
+static void jmr3927_irq_enable(unsigned int irq_nr);
+
+static unsigned int jmr3927_irq_startup(unsigned int irq)
+{
+	jmr3927_irq_enable(irq);
+	return 0;
+}
+
+#define	jmr3927_irq_shutdown	jmr3927_irq_disable
+
+static void jmr3927_irq_ack(unsigned int irq)
+{
+	db_assert(jmr3927_irq_base != -1);
+	db_assert(irq >= jmr3927_irq_base);
+	db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC);
+
+	if (irq == JMR3927_IRQ_IRC_TMR0) {
+		jmr3927_tmrptr->tisr = 0;       /* ack interrupt */  
+	}
+
+	jmr3927_irq_disable(irq);
+}
+
+static void jmr3927_irq_end(unsigned int irq)
+{
+	db_assert(jmr3927_irq_base != -1);
+	db_assert(irq >= jmr3927_irq_base);
+	db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC);
+
+	jmr3927_irq_enable(irq);
+}
+
+static void jmr3927_irq_disable(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	db_assert(jmr3927_irq_base != -1);
+	db_assert(irq >= jmr3927_irq_base);
+	db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC);
+
+	save_and_cli(flags);
+	mask_irq(irq_nr);
+	restore_flags(flags);
+}
+
+static void jmr3927_irq_enable(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	db_assert(jmr3927_irq_base != -1);
+	db_assert(irq >= jmr3927_irq_base);
+	db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC);
+
+	save_and_cli(flags);
+	unmask_irq(irq_nr);
+	restore_flags(flags);
+}
+
+/*
+ * CP0_STATUS is a thread's resource (saved/restored on context switch).
+ * So disable_irq/enable_irq MUST handle IOC/ISAC/IRC registers.
+ */
+static void mask_irq_isac(int irq_nr, int space_id)
+{
+	/* 0: mask */
+	unsigned char imask =
+		jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR);
+	unsigned int bit  = 1 << irq_nr;
+	jmr3927_isac_reg_out(imask & ~bit, JMR3927_ISAC_INTM_ADDR);
+	/* flush write buffer */
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+static void unmask_irq_isac(int irq_nr, int space_id)
+{
+	/* 0: mask */
+	unsigned char imask =
+		jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR);
+	unsigned int bit  = 1 << irq_nr;
+	jmr3927_isac_reg_out(imask | bit, JMR3927_ISAC_INTM_ADDR);
+	/* flush write buffer */
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+
+static void mask_irq_ioc(int irq_nr, int space_id)
+{
+	/* 0: mask */
+	unsigned char imask =
+		jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
+	unsigned int bit = 1 << irq_nr;
+	jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR);
+	/* flush write buffer */
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+static void unmask_irq_ioc(int irq_nr, int space_id)
+{
+	/* 0: mask */
+	unsigned char imask =
+		jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
+	unsigned int bit = 1 << irq_nr;
+	jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR);
+	/* flush write buffer */
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+
+static void mask_irq_irc(int irq_nr, int space_id)
+{
+	volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2];
+	if (irq_nr & 1)
+		*ilrp = (*ilrp & 0x00ff) | (irc_dlevel << 8);
+	else
+		*ilrp = (*ilrp & 0xff00) | irc_dlevel;
+	/* update IRCSR */
+	tx3927_ircptr->imr = 0;
+	tx3927_ircptr->imr = irc_elevel;
+}
+static void unmask_irq_irc(int irq_nr, int space_id)
+{
+	volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2];
+	if (irq_nr & 1)
+		*ilrp = (*ilrp & 0x00ff) | (irc_level[irq_nr] << 8);
+	else
+		*ilrp = (*ilrp & 0xff00) | irc_level[irq_nr];
+	/* update IRCSR */
+	tx3927_ircptr->imr = 0;
+	tx3927_ircptr->imr = irc_elevel;
+}
+
+struct tb_irq_space jmr3927_isac_irqspace = {
+	next: NULL,
+	start_irqno: JMR3927_IRQ_ISAC,
+	nr_irqs : JMR3927_NR_IRQ_ISAC,
+	mask_func: mask_irq_isac,
+	unmask_func: unmask_irq_isac,
+	name: "ISAC",
+	space_id: 0,
+	can_share : 0
+};
+struct tb_irq_space jmr3927_ioc_irqspace = {
+	next: NULL,
+	start_irqno: JMR3927_IRQ_IOC,
+	nr_irqs : JMR3927_NR_IRQ_IOC,
+	mask_func: mask_irq_ioc,
+	unmask_func: unmask_irq_ioc,
+	name: "IOC",
+	space_id: 0,
+	can_share : 1
+};
+struct tb_irq_space jmr3927_irc_irqspace = {
+	next: NULL,
+	start_irqno: JMR3927_IRQ_IRC,
+	nr_irqs : JMR3927_NR_IRQ_IRC,
+	mask_func: mask_irq_irc,
+	unmask_func: unmask_irq_irc,
+	name: "on-chip",
+	space_id: 0,
+	can_share : 0
+};
+
+void jmr3927_spurious(struct pt_regs *regs)
+{
+#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
+	tx_branch_likely_bug_fixup(regs);
+#endif
+	printk(KERN_WARNING "spurious interrupt (cause 0x%lx, pc 0x%lx, ra 0x%lx).\n",
+	       regs->cp0_cause, regs->cp0_epc, regs->regs[31]);
+}
+
+extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
+void jmr3927_irc_irqdispatch(struct pt_regs *regs)
+{
+	int irq;
+	
+#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
+	tx_branch_likely_bug_fixup(regs);
+#endif
+	if ((regs->cp0_cause & CAUSEF_IP7) == 0) {
+#if 0
+		jmr3927_spurious(regs);
+#endif
+		return;
+	}
+	irq = (regs->cp0_cause >> CAUSEB_IP2) & 0x0f;
+
+	do_IRQ(irq + JMR3927_IRQ_IRC, regs);
+}
+
+static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);
+	int i;
+
+	for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) {
+		if (istat & (1 << i)) {
+			irq = JMR3927_IRQ_IOC + i;
+			do_IRQ(irq, regs);
+		}
+	}
+}
+
+static struct irqaction ioc_action = {
+	jmr3927_ioc_interrupt, 0, 0, "IOC", NULL, NULL,
+};
+
+static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR);
+	int i;
+
+	for (i = 0; i < JMR3927_NR_IRQ_ISAC; i++) {
+		if (istat & (1 << i)) {
+			irq = JMR3927_IRQ_ISAC + i;
+			do_IRQ(irq, regs);
+		}
+	}
+}
+
+static struct irqaction isac_action = {
+	jmr3927_isac_interrupt, 0, 0, "ISAC", NULL, NULL,
+};
+
+
+static void jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+	printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq);
+}
+static struct irqaction isaerr_action = {
+	jmr3927_isaerr_interrupt, 0, 0, "ISA error", NULL, NULL,
+};
+
+static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+	printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq);
+	printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
+	       tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
+}
+static struct irqaction pcierr_action = {
+	jmr3927_pcierr_interrupt, 0, 0, "PCI error", NULL, NULL,
+};
+
+int jmr3927_ether1_irq = 0;
+
+void jmr3927_irq_init(u32 irq_base);
+void jmr3927_irq_setup(void)
+{
+	/* look for io board's presence */
+	int have_isac = jmr3927_have_isac();
+
+	/* Now, interrupt control disabled, */
+	/* all IRC interrupts are masked, */
+	/* all IRC interrupt mode are Low Active. */
+
+	if (have_isac) {
+
+		/* ETHER1 (NE2000 compatible 10M-Ether) parameter setup */
+		/* temporary enable interrupt control */
+		tx3927_ircptr->cer = 1;
+		/* ETHER1 Int. Is High-Active. */
+		if (tx3927_ircptr->ssr & (1 << 0))
+			jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT0;
+#if 0	/* INT3 may be asserted by ether0 (even after reboot...) */
+		else if (tx3927_ircptr->ssr & (1 << 3))
+			jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT3;
+#endif
+		/* disable interrupt control */
+		tx3927_ircptr->cer = 0;
+
+		/* Ether1: High Active */
+		if (jmr3927_ether1_irq) {
+			int ether1_irc = jmr3927_ether1_irq - JMR3927_IRQ_IRC;
+			tx3927_ircptr->cr[ether1_irc / 8] |=
+				TX3927_IRCR_HIGH << ((ether1_irc % 8) * 2);
+		}
+	}
+
+	/* mask all IOC interrupts */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR);
+	/* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */
+	jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR);
+
+	if (have_isac) {
+		/* mask all ISAC interrupts */
+		jmr3927_isac_reg_out(0, JMR3927_ISAC_INTM_ADDR);
+		/* setup ISAC interrupt mode (ISAIRQ3,ISAIRQ5:Low Active ???) */
+		jmr3927_isac_reg_out(JMR3927_ISAC_INTF_IRQ3|JMR3927_ISAC_INTF_IRQ5, JMR3927_ISAC_INTP_ADDR);
+	}
+
+	/* clear PCI Soft interrupts */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR);
+	/* clear PCI Reset interrupts */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+
+	/* enable interrupt control */
+	tx3927_ircptr->cer = TX3927_IRCER_ICE;
+	tx3927_ircptr->imr = irc_elevel;
+
+	jmr3927_irq_init(NR_ISA_IRQS);
+
+	set_except_vector(0, jmr3927_IRQ);
+
+	/* setup irq space */
+	add_tb_irq_space(&jmr3927_isac_irqspace);
+	add_tb_irq_space(&jmr3927_ioc_irqspace);
+	add_tb_irq_space(&jmr3927_irc_irqspace);
+
+	/* setup IOC interrupt 1 (PCI, MODEM) */
+	setup_irq(JMR3927_IRQ_IOCINT, &ioc_action);
+
+	if (have_isac) {
+		setup_irq(JMR3927_IRQ_ISACINT, &isac_action);
+		setup_irq(JMR3927_IRQ_ISAC_ISAER, &isaerr_action);
+	}
+
+#ifdef CONFIG_PCI
+	setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action);
+#endif
+
+	/* enable all CPU interrupt bits. */
+	set_cp0_status(ST0_IM);	/* IE bit is still 0. */
+}
+
+void (*irq_setup)(void);
+void __init init_IRQ(void)
+{
+
+#ifdef CONFIG_REMOTE_DEBUG
+        extern void breakpoint(void);
+        extern void set_debug_traps(void);
+
+        puts("Wait for gdb client connection ...\n");
+        set_debug_traps();
+        breakpoint();
+#endif
+
+        /* invoke board-specific irq setup */
+        irq_setup();
+}
+
+hw_irq_controller jmr3927_irq_controller = {
+	"jmr3927_irq",
+	jmr3927_irq_startup,
+	jmr3927_irq_shutdown,
+	jmr3927_irq_enable,
+	jmr3927_irq_disable,
+	jmr3927_irq_ack,
+	jmr3927_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+void 
+jmr3927_irq_init(u32 irq_base)
+{
+	extern irq_desc_t irq_desc[];
+	u32 i;
+
+	for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &jmr3927_irq_controller;
+	}
+	
+	jmr3927_irq_base = irq_base;
+}
+
+#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
+static int tx_branch_likely_bug_count = 0;
+static int have_tx_branch_likely_bug = 0;
+void tx_branch_likely_bug_fixup(struct pt_regs *regs)
+{
+	/* TX39/49-BUG: Under this condition, the insn in delay slot
+           of the branch likely insn is executed (not nullified) even
+           the branch condition is false. */
+	if (!have_tx_branch_likely_bug)
+		return;
+	if ((regs->cp0_epc & 0xfff) == 0xffc &&
+	    KSEGX(regs->cp0_epc) != KSEG0 &&
+	    KSEGX(regs->cp0_epc) != KSEG1) {
+		unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4);
+		/* beql,bnel,blezl,bgtzl */
+		/* bltzl,bgezl,blezall,bgezall */
+		/* bczfl, bcztl */
+		if ((insn & 0xf0000000) == 0x50000000 ||
+		    (insn & 0xfc0e0000) == 0x04020000 ||
+		    (insn & 0xf3fe0000) == 0x41020000) {
+			regs->cp0_epc -= 4;
+			tx_branch_likely_bug_count++;
+			printk(KERN_INFO
+			       "fix branch-likery bug in %s (insn %08x)\n",
+			       current->comm, insn);
+		}
+	}
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/kgdb_io.c linux/arch/mips/jmr3927/rbhma3100/kgdb_io.c
--- linux.orig/arch/mips/jmr3927/rbhma3100/kgdb_io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/kgdb_io.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,155 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Low level uart routines to directly access a TX[34]927 SIO.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ahennessy@mvista.com or source@mvista.com
+ *
+ * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c
+ *
+ * Copyright (C) 2000-2001 Toshiba 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <asm/jmr3927/txx927.h>
+#include <asm/jmr3927/tx3927.h>
+#include <asm/jmr3927/jmr3927.h>
+
+#define TIMEOUT       0xffffff
+#define SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+
+#ifdef SLOW_DOWN
+#define slow_down() { int k; for (k=0; k<10000; k++); }
+#else
+#define slow_down()
+#endif
+
+static int remoteDebugInitialized = 0;
+
+int putDebugChar(unsigned char c)
+{
+        int i = 0;
+	
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(38400);
+	}
+
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (!(tx3927_sioptr(0)->cisr & TXx927_SICISR_TXALS));
+	tx3927_sioptr(0)->tfifo = c;
+
+	return 1;
+}
+
+unsigned char getDebugChar(void)
+{
+        int i = 0;
+	int dicr;
+	char c;
+	
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(38400);
+	}
+
+	/* diable RX int. */
+	dicr = tx3927_sioptr(0)->dicr;
+	tx3927_sioptr(0)->dicr = 0;
+
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (tx3927_sioptr(0)->disr & TXx927_SIDISR_UVALID)
+		;
+	c = tx3927_sioptr(0)->rfifo;
+
+	/* clear RX int. status */
+	tx3927_sioptr(0)->disr &= ~TXx927_SIDISR_RDIS;
+	/* enable RX int. */
+	tx3927_sioptr(0)->dicr = dicr;
+
+	return c;
+}
+
+void debugInit(int baud)
+{
+	/*
+	volatile unsigned long lcr;
+	volatile unsigned long dicr;
+	volatile unsigned long disr;
+	volatile unsigned long cisr;
+	volatile unsigned long fcr;
+	volatile unsigned long flcr;
+	volatile unsigned long bgr;
+	volatile unsigned long tfifo;
+	volatile unsigned long rfifo;
+	*/
+
+	tx3927_sioptr(0)->lcr = 0x020;
+	tx3927_sioptr(0)->dicr = 0;
+	tx3927_sioptr(0)->disr = 0x4100;
+	tx3927_sioptr(0)->cisr = 0x014;
+	tx3927_sioptr(0)->fcr = 0;
+	tx3927_sioptr(0)->flcr = 0x02;
+	tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) |
+		TXx927_SIBGR_BCLK_T0;
+#if 0
+	/*
+	 * Reset the UART.
+	 */
+	tx3927_sioptr(0)->fcr = TXx927_SIFCR_SWRST;
+	while (tx3927_sioptr(0)->fcr & TXx927_SIFCR_SWRST)
+		;
+
+	/*
+	 * and set the speed of the serial port
+	 * (currently hardwired to 9600 8N1
+	 */
+
+	tx3927_sioptr(0)->lcr = TXx927_SILCR_UMODE_8BIT |
+		TXx927_SILCR_USBL_1BIT |
+		TXx927_SILCR_SCS_IMCLK_BG;
+	tx3927_sioptr(0)->bgr =
+		((JMR3927_BASE_BAUD + baud / 2) / baud) |
+		TXx927_SIBGR_BCLK_T0;
+
+	/* HW RTS/CTS control */
+	if (ser->flags & ASYNC_HAVE_CTS_LINE)
+		tx3927_sioptr(0)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES |
+			TXx927_SIFLCR_RTSTL_MAX /* 15 */;
+	/* Enable RX/TX */
+	tx3927_sioptr(0)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE);
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/pci_fixup.c linux/arch/mips/jmr3927/rbhma3100/pci_fixup.c
--- linux.orig/arch/mips/jmr3927/rbhma3100/pci_fixup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/pci_fixup.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,140 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/jmr3927/jmr3927.h>
+
+#undef	DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+	/* will need to fixup IO resources */
+}
+
+void __init pcibios_fixup(void)
+{
+	/* nothing to do here */
+}
+
+int pci_get_irq(struct pci_dev *dev, int pin)
+{
+	unsigned char irq = pin;
+
+	/* IRQ rotation (PICMG) */
+	irq--;	/* 0-3 */
+	if (dev->bus->parent == NULL &&
+	    PCI_SLOT(dev->devfn) == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) {
+		/* PCI CardSlot (IDSEL=A23, DevNu=12) */
+		/* PCIA => PCIC (IDSEL=A23) */
+		/* NOTE: JMR3927 JP1 must be set to OPEN */
+		irq = (irq + 2) % 4;
+	} else if (dev->bus->parent == NULL &&
+		   PCI_SLOT(dev->devfn) == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) {
+		/* PCI CardSlot (IDSEL=A22, DevNu=11) */
+		/* PCIA => PCIA (IDSEL=A22) */
+		/* NOTE: JMR3927 JP1 must be set to OPEN */
+		irq = (irq + 0) % 4;
+	} else {
+		/* PCI Backplane */
+		irq = (irq + 3 + PCI_SLOT(dev->devfn)) % 4;
+#if 0	/* ??? */
+		for (bus = dev->bus; bus->parent != NULL; bus = bus->parent) {
+			irq = (irq + 3 + PCI_SLOT(bus->self->devfn)) % 4;
+		}
+#endif
+	}
+	irq++;	/* 1-4 */
+
+	switch (irq) {
+	case 1:
+		irq = JMR3927_IRQ_IOC_PCIA;
+		break;
+	case 2:
+		// wrong for backplane irq = JMR3927_IRQ_IOC_PCIB;
+		irq = JMR3927_IRQ_IOC_PCID;
+		break;
+	case 3:
+		irq = JMR3927_IRQ_IOC_PCIC;
+		break;
+	case 4:
+		// wrong for backplane irq = JMR3927_IRQ_IOC_PCID;
+		irq = JMR3927_IRQ_IOC_PCIB;
+		break;
+	}
+
+	/* Check OnBoard Ethernet (IDSEL=A24, DevNu=13) */
+	if (dev->bus->parent == NULL &&
+	    PCI_SLOT(dev->devfn) == TX3927_PCIC_IDSEL_AD_TO_SLOT(24)) {
+		extern int jmr3927_ether1_irq;
+		/* check this irq line was reserved for ether1 */
+		if (jmr3927_ether1_irq != JMR3927_IRQ_ETHER0)
+			irq = JMR3927_IRQ_ETHER0;
+		else
+			irq = 0;	/* disable */
+	}
+	return irq;
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	unsigned char irq;
+        struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq);
+		if (irq == 0)
+			return;
+
+		/* SMSC SLC90E66 IDE uses irq 14, 15 (default) */
+		if (!(dev->vendor == PCI_VENDOR_ID_EFAR &&
+		      dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1)) {
+			irq = pci_get_irq(dev, irq);
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+		}
+
+		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+		printk(KERN_INFO "PCI: %02x:%02x IRQ %02x\n",
+		       dev->bus->number, dev->devfn, irq);
+		dev->irq = irq;
+	}
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/pci_ops.c linux/arch/mips/jmr3927/rbhma3100/pci_ops.c
--- linux.orig/arch/mips/jmr3927/rbhma3100/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/pci_ops.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,471 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation 
+ *
+ * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
+ *
+ *     Define the pci_ops for JMR3927.
+ *
+ * Much of the code is derived from the original DDB5074 port by 
+ * Geert Uytterhoeven <geert@sonycom.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ ***********************************************************************
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+
+#include <asm/addrspace.h>
+#include <asm/pci_channel.h>
+#include <asm/jmr3927/jmr3927.h>
+#include <asm/debug.h>
+
+struct resource pci_io_resource = {
+	"pci IO space", 
+	0x1000,  /* reserve regacy I/O space */
+	0x1000 + JMR3927_PCIIO_SIZE -1,
+	IORESOURCE_IO};
+
+struct resource pci_mem_resource = {
+	"pci memory space", 
+	JMR3927_PCIMEM,
+	JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE -1,
+	IORESOURCE_MEM};
+
+extern struct pci_ops jmr3927_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{ &jmr3927_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 0xff },
+	{ NULL, NULL, NULL, NULL, NULL}
+};
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 1;
+}                           
+
+static int
+mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, int *flagsp)
+{
+	if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
+		return -1;
+
+	tx3927_pcicptr->ica = ((bus    & 0xff) << 0x10) |
+	                      ((dev_fn & 0xff) << 0x08) |
+	                      (where  & 0xfc);
+	/* clear M_ABORT and Disable M_ABORT Int. */
+	tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
+	tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
+	return 0;
+}
+
+static int
+check_abort(int flags)
+{
+	int code = PCIBIOS_SUCCESSFUL;
+	if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) {
+		tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
+		tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
+		code =PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	return code;
+}
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int jmr3927_pcibios_read_config_byte (struct pci_dev *dev,
+					     int where,
+					     unsigned char *val)
+{
+	int flags;
+	unsigned char bus, func_num;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));  
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}                               
+
+	func_num = PCI_FUNC(dev->devfn);
+	if (mkaddr(bus, dev->devfn, where, &flags))
+		return -1;
+	*val = *(volatile u8 *)((ulong)&tx3927_pcicptr->icd | (where&3));
+	return check_abort(flags);
+}
+
+static int jmr3927_pcibios_read_config_word (struct pci_dev *dev,
+					     int where,
+					     unsigned short *val)
+{
+	int flags;
+	unsigned char bus, func_num;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));  
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}                               
+
+	func_num = PCI_FUNC(dev->devfn);
+	if (mkaddr(bus, dev->devfn, where, &flags))
+		return -1;
+	*val = le16_to_cpu(*(volatile u16 *)((ulong)&tx3927_pcicptr->icd | (where&3)));
+	return check_abort(flags);
+}
+
+static int jmr3927_pcibios_read_config_dword (struct pci_dev *dev,
+					      int where,
+					      unsigned int *val)
+{
+	int flags;
+	unsigned char bus, func_num;
+
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));  
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}                               
+
+	func_num = PCI_FUNC(dev->devfn);
+	if (mkaddr(bus, dev->devfn, where, &flags))
+		return -1;
+	*val = le32_to_cpu(tx3927_pcicptr->icd);
+	return check_abort(flags);
+}
+
+static int jmr3927_pcibios_write_config_byte (struct pci_dev *dev,
+					      int where,
+					      unsigned char val)
+{
+	int flags;
+	unsigned char bus, func_num;
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}                               
+
+	func_num = PCI_FUNC(dev->devfn);
+	if (mkaddr(bus, dev->devfn, where, &flags))
+		return -1;
+	*(volatile u8 *)((ulong)&tx3927_pcicptr->icd | (where&3)) = val;
+	return check_abort(flags);
+}
+
+static int jmr3927_pcibios_write_config_word (struct pci_dev *dev,
+					      int where,
+					      unsigned short val)
+{
+	int flags;
+	unsigned char bus, func_num;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}                               
+
+	func_num = PCI_FUNC(dev->devfn);
+	if (mkaddr(bus, dev->devfn, where, &flags))
+		return -1;
+	*(volatile u16 *)((ulong)&tx3927_pcicptr->icd | (where&3)) = cpu_to_le16(val);
+	return check_abort(flags);
+}
+
+static int jmr3927_pcibios_write_config_dword (struct pci_dev *dev,
+					       int where,
+					       unsigned int val)
+{
+	int flags;
+	unsigned char bus, func_num;
+
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}                               
+
+	func_num = PCI_FUNC(dev->devfn);
+	if (mkaddr(bus, dev->devfn, where, &flags))
+		return -1;
+	tx3927_pcicptr->icd = cpu_to_le32(val);
+	return check_abort(flags);
+}
+struct pci_ops jmr3927_pci_ops = {
+	jmr3927_pcibios_read_config_byte,
+	jmr3927_pcibios_read_config_word,
+	jmr3927_pcibios_read_config_dword,
+	jmr3927_pcibios_write_config_byte,
+	jmr3927_pcibios_write_config_word,
+	jmr3927_pcibios_write_config_dword
+};
+
+#ifndef JMR3927_INIT_INDIRECT_PCI
+inline unsigned long tc_readl(volatile __u32 *addr)
+{
+	return readl(addr);
+}
+inline void tc_writel(unsigned long data, volatile __u32 *addr)
+{
+	writel(data, addr);
+}
+#else
+unsigned long tc_readl(volatile __u32 *addr)
+{
+	unsigned long val;
+
+	addr = PHYSADDR(addr);
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)addr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
+	    (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
+	val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+	return val;
+}
+void tc_writel(unsigned long data, volatile __u32 *addr)
+{
+	addr = PHYSADDR(addr);
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data);
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)addr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
+	    (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT)  | PCI_IPCIBE_IBE_LONG;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+}
+unsigned char tx_ioinb(unsigned char *addr)
+{
+	unsigned long val;
+	__u32 ioaddr;
+	int offset;
+	int byte;
+
+	ioaddr = (unsigned long)addr;
+        offset = ioaddr & 0x3;
+	if (offset == 0)
+		byte = 0x7;
+	else if (offset == 1)
+		byte = 0xb;
+	else if (offset == 2)
+		byte = 0xd;
+	else if (offset == 3)
+		byte = 0xe;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
+	    (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
+	val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
+	val = val & 0xff;
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+	return val;
+}
+void tx_iooutb(unsigned long data, unsigned char *addr)
+{
+	__u32 ioaddr;
+	int offset;
+	int byte;
+
+	data = data | (data << 8) | (data << 16) | (data << 24);
+	ioaddr = (unsigned long)addr;
+        offset = ioaddr & 0x3;
+	if (offset == 0)
+		byte = 0x7;
+	else if (offset == 1)
+		byte = 0xb;
+	else if (offset == 2)
+		byte = 0xd;
+	else if (offset == 3)
+		byte = 0xe;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
+	    (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | byte;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+}
+unsigned short tx_ioinw(unsigned short *addr)
+{
+	unsigned long val;
+	__u32 ioaddr;
+	int offset;
+	int byte;
+
+	ioaddr = (unsigned long)addr;
+        offset = ioaddr & 0x3;
+	if (offset == 0)
+		byte = 0x3;
+	else if (offset == 2)
+		byte = 0xc;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
+	    (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
+	val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
+	val = val & 0xffff;
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+	return val;
+
+}
+void tx_iooutw(unsigned long data, unsigned short *addr)
+{
+	__u32 ioaddr;
+	int offset;
+	int byte;
+
+	data = data | (data << 16);
+	ioaddr = (unsigned long)addr;
+        offset = ioaddr & 0x3;
+	if (offset == 0)
+		byte = 0x3;
+	else if (offset == 2)
+		byte = 0xc;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
+	    (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | byte;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+}
+unsigned long tx_ioinl(unsigned int *addr)
+{
+	unsigned long val;
+	__u32 ioaddr;
+
+	ioaddr = (unsigned long)addr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
+	    (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
+	val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+	return val;
+}
+void tx_iooutl(unsigned long data, unsigned int *addr)
+{
+	__u32 ioaddr;
+
+	ioaddr = (unsigned long)addr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data);
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
+	*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
+	    (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | PCI_IPCIBE_IBE_LONG;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+}
+void tx_insbyte(unsigned char *addr,void *buffer,unsigned int count)
+{
+	unsigned char *ptr = (unsigned char *) buffer;
+
+	while (count--) {
+		*ptr++ = tx_ioinb(addr);
+	}
+}
+void tx_insword(unsigned short *addr,void *buffer,unsigned int count)
+{
+	unsigned short *ptr = (unsigned short *) buffer;
+
+	while (count--) {
+		*ptr++ = tx_ioinw(addr);
+	}
+}
+void tx_inslong(unsigned int *addr,void *buffer,unsigned int count)
+{
+	unsigned long *ptr = (unsigned long *) buffer;
+
+	while (count--) {
+		*ptr++ = tx_ioinl(addr);
+	}
+}
+void tx_outsbyte(unsigned char *addr,void *buffer,unsigned int count)
+{
+	unsigned char *ptr = (unsigned char *) buffer;
+
+	while (count--) {
+		tx_iooutb(*ptr++,addr);
+	}
+}
+void tx_outsword(unsigned short *addr,void *buffer,unsigned int count)
+{
+	unsigned short *ptr = (unsigned short *) buffer;
+
+	while (count--) {
+		tx_iooutw(*ptr++,addr);
+	}
+}
+void tx_outslong(unsigned int *addr,void *buffer,unsigned int count)
+{
+	unsigned long *ptr = (unsigned long *) buffer;
+
+	while (count--) {
+		tx_iooutl(*ptr++,addr);
+	}
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/rtc.c linux/arch/mips/jmr3927/rbhma3100/rtc.c
--- linux.orig/arch/mips/jmr3927/rbhma3100/rtc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/rtc.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * RTC routines for Dallas chip.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 200-2001 Toshiba 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <asm/mc146818rtc.h>	/* bad name... */
+#include <asm/jmr3927/jmr3927.h>
+
+static unsigned char jmr3927_rtc_read_data(unsigned long addr)
+{
+	return jmr3927_nvram_in(addr);
+}
+
+static void jmr3927_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	jmr3927_nvram_out(data, addr);
+}
+
+static int jmr3927_rtc_bcd_mode(void)
+{
+	return 1;
+}
+
+struct rtc_ops jmr3927_rtc_ops = {
+	&jmr3927_rtc_read_data,
+	&jmr3927_rtc_write_data,
+	&jmr3927_rtc_bcd_mode
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/jmr3927/rbhma3100/setup.c linux/arch/mips/jmr3927/rbhma3100/setup.c
--- linux.orig/arch/mips/jmr3927/rbhma3100/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/jmr3927/rbhma3100/setup.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,525 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * Based on arch/mips/ddb5xxx/ddb5477/setup.c
+ *
+ *     Setup file for JMR3927.
+ *
+ * Copyright (C) 2000-2001 Toshiba 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/fs.h>		/* for ROOT_DEV */
+#include <linux/ioport.h>
+#include <linux/param.h>	/* for HZ */
+#include <linux/delay.h>
+
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/jmr3927/jmr3927.h>
+#include <asm/mipsregs.h>
+
+/* Tick Timer divider */
+#define JMR3927_TIMER_CCD	0	/* 1/2 */
+#define JMR3927_TIMER_CLK	(JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD))
+
+unsigned char led_state = 0xf;
+
+struct {
+    struct resource ram0;
+    struct resource ram1;
+    struct resource pcimem;
+    struct resource iob;
+    struct resource ioc;
+    struct resource pciio;
+    struct resource jmy1394;
+    struct resource rom1;
+    struct resource rom0;
+    struct resource sio0;
+    struct resource sio1;
+} jmr3927_resources = {
+    { "RAM0",           0,         0x01FFFFFF,  IORESOURCE_MEM },
+    { "RAM1",          0x02000000, 0x03FFFFFF,  IORESOURCE_MEM },
+    { "PCIMEM",        0x08000000, 0x07FFFFFF,  IORESOURCE_MEM },
+    { "IOB",           0x10000000, 0x13FFFFFF                  },
+    { "IOC",           0x14000000, 0x14FFFFFF                  },
+    { "PCIIO",         0x15000000, 0x15FFFFFF                  },
+    { "JMY1394",       0x1D000000, 0x1D3FFFFF                  },
+    { "ROM1",          0x1E000000, 0x1E3FFFFF                  },
+    { "ROM0",          0x1FC00000, 0x1FFFFFFF                  },
+    { "SIO0",          0xFFFEF300, 0xFFFEF3FF                  },
+    { "SIO1",          0xFFFEF400, 0xFFFEF4FF                  },
+};
+
+/* don't enable - see errata */
+int jmr3927_ccfg_toeon = 0;
+
+static inline void do_reset(void)
+{
+#ifdef CONFIG_TC35815
+	extern void tc35815_killall(void);
+	tc35815_killall();
+#endif
+#if 1	/* Resetting PCI bus */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+	jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR);
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR);	/* flush WB */
+	mdelay(1);
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+#endif
+	jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR);
+}
+
+static void jmr3927_machine_restart(char *command)
+{
+	cli();
+	puts("Rebooting...");
+	do_reset();
+}
+
+static void jmr3927_machine_halt(void)
+{
+	puts("JMR-TX3927 halted.\n");
+	while (1);
+}
+
+static void jmr3927_machine_power_off(void)
+{
+	puts("JMR-TX3927 halted. Please turn off the power.\n");
+	while (1);
+}
+
+#define USE_RTC_DS1742
+#ifdef USE_RTC_DS1742
+extern void rtc_ds1742_init(unsigned long base);
+#endif
+static void __init jmr3927_time_init(void)
+{
+#ifdef USE_RTC_DS1742
+	if (jmr3927_have_nvram()) {
+	        rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR);
+	}
+#endif
+}
+
+unsigned long jmr3927_do_gettimeoffset(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+static void __init jmr3927_timer_setup(struct irqaction *irq)
+{
+	do_gettimeoffset = jmr3927_do_gettimeoffset;
+
+	jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
+	jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
+	jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
+	jmr3927_tmrptr->tcr =
+		TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL;
+
+	setup_irq(JMR3927_IRQ_TICK, irq);
+}
+
+#define USECS_PER_JIFFY (1000000/HZ)
+unsigned long jmr3927_do_gettimeoffset(void)
+{
+       unsigned long count;
+       unsigned long res = 0;
+
+       /* MUST read TRR before TISR. */
+       count = jmr3927_tmrptr->trr;
+
+       if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) {
+               /* timer interrupt is pending.  use Max value. */
+               res = USECS_PER_JIFFY - 1;
+       } else {
+               /* convert to usec */
+               /* res = count / (JMR3927_TIMER_CLK / 1000000); */
+               res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000);
+
+               /*
+                * Due to possible jiffies inconsistencies, we need to check
+                * the result so that we'll get a timer that is monotonic.
+                */
+               if (res >= USECS_PER_JIFFY)
+                       res = USECS_PER_JIFFY-1;
+       }
+
+       return res;
+}                                         
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end;
+#endif 
+
+//#undef DO_WRITE_THROUGH
+#define DO_WRITE_THROUGH
+#define DO_ENABLE_CACHE
+
+extern char * __init prom_getcmdline(void);
+static void jmr3927_board_init(void);
+extern void jmr3927_irq_setup(void);
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
+void __init jmr3927_setup(void)
+{
+	extern int panic_timeout;
+	char *argptr;
+
+	irq_setup = jmr3927_irq_setup;
+	mips_io_port_base = JMR3927_PORT_BASE + JMR3927_PCIIO;
+
+	board_time_init = jmr3927_time_init;
+	board_timer_setup = jmr3927_timer_setup;
+
+	_machine_restart = jmr3927_machine_restart;
+	_machine_halt = jmr3927_machine_halt;
+	_machine_power_off = jmr3927_machine_power_off;
+
+	/*
+	 * IO/MEM resources. 
+	 */
+	ioport_resource.start = pci_io_resource.start;
+	ioport_resource.end = pci_io_resource.end;
+	iomem_resource.start = pci_mem_resource.start;
+	iomem_resource.end = pci_mem_resource.end;
+	
+	/* Reboot on panic */
+	panic_timeout = 180;
+
+	{
+		unsigned int conf;
+		conf = read_32bit_cp0_register(CP0_CONF);
+	}
+
+#if 1
+	/* cache setup */
+	{
+		unsigned int conf;
+#ifdef DO_ENABLE_CACHE
+		int mips_ic_disable = 0, mips_dc_disable = 0;
+#else
+		int mips_ic_disable = 1, mips_dc_disable = 1;
+#endif
+#ifdef DO_WRITE_THROUGH
+		int mips_config_cwfon = 0;
+		int mips_config_wbon = 0;
+#else
+		int mips_config_cwfon = 1;
+		int mips_config_wbon = 1;
+#endif
+
+		conf = read_32bit_cp0_register(CP0_CONF);
+		conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON);
+		conf |= mips_ic_disable ? 0 : TX39_CONF_ICE;
+		conf |= mips_dc_disable ? 0 : TX39_CONF_DCE;
+		conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
+		conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;
+
+		write_32bit_cp0_register(CP0_CONF, conf);
+		write_32bit_cp0_register(CP0_TX39_CACHE, 0);
+	}
+#endif
+
+	/* initialize board */
+	jmr3927_board_init();
+
+	argptr = prom_getcmdline();
+
+	if ((argptr = strstr(argptr, "toeon")) != NULL) {
+			jmr3927_ccfg_toeon = 1;
+	}
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "ip=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " ip=bootp");
+	}
+
+#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS1,115200");
+	}
+#endif                                             
+}
+ 
+
+static void tx3927_setup(void);
+
+#ifdef CONFIG_PCI
+unsigned long mips_pci_io_base;
+unsigned long mips_pci_io_size;
+unsigned long mips_pci_mem_base;
+unsigned long mips_pci_mem_size;
+/* for legacy I/O, PCI I/O PCI Bus address must be 0 */
+unsigned long mips_pci_io_pciaddr = 0;
+#endif
+extern struct rtc_ops *rtc_ops;
+extern struct rtc_ops jmr3927_rtc_ops;
+static void jmr3927_board_init()
+{
+	char *argptr;
+
+#ifdef CONFIG_PCI
+	mips_pci_io_base = JMR3927_PCIIO;
+	mips_pci_io_size = JMR3927_PCIIO_SIZE;
+	mips_pci_mem_base = JMR3927_PCIMEM;
+	mips_pci_mem_size = JMR3927_PCIMEM_SIZE;
+#endif
+
+	tx3927_setup();
+
+#ifdef CONFIG_VT
+	conswitchp = &dummy_con;
+#endif
+
+	if (jmr3927_have_isac()) {
+
+#ifdef CONFIG_FB_E1355
+		argptr = prom_getcmdline();
+		if ((argptr = strstr(argptr, "video=")) == NULL) {
+			argptr = prom_getcmdline();
+			strcat(argptr, " video=e1355fb:crt16h");
+		}
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+		/* overrides PCI-IDE */
+#endif
+
+#ifdef CONFIG_PC_KEYB
+		//not yet kbd_ops = &jmr3927_kbd_ops;
+#endif
+	}
+#ifdef USE_RTC_DS1742
+	if (jmr3927_have_nvram()) {
+		rtc_ops = &jmr3927_rtc_ops;
+	}
+#endif
+
+	/* SIO0 DTR on */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR);
+
+	jmr3927_led_set(0);
+
+
+	if (jmr3927_have_isac()) 
+		jmr3927_io_led_set(0);
+	printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n",
+	       jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK,
+	       jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK,
+	       jmr3927_dipsw1(), jmr3927_dipsw2(),
+	       jmr3927_dipsw3(), jmr3927_dipsw4());
+	if (jmr3927_have_isac())
+		printk("JMI-3927IO2 --- ISAC(Rev %d) DIPSW:%01x\n",
+		       jmr3927_isac_reg_in(JMR3927_ISAC_REV_ADDR) & JMR3927_REV_MASK,
+		       jmr3927_io_dipsw());
+}
+static void tx3927_setup(void)
+{
+	int i;
+
+	/* SDRAMC are configured by PROM */
+
+	/* ROMC */
+	tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048;
+	tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8;
+	tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698;
+	tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218;
+
+	/* CCFG */
+	/* enable Timeout BusError */
+	if (jmr3927_ccfg_toeon)
+		tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE;
+
+	/* clear BusErrorOnWrite flag */
+	tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW;
+	/* Disable PCI snoop */
+	tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP;
+
+#ifdef DO_WRITE_THROUGH
+	/* Enable PCI SNOOP - with write through only */
+	tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP;
+#endif
+
+	/* Pin selection */
+	tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL;
+	tx3927_ccfgptr->pcfg |=
+		TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL |
+		(TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1));
+
+	printk("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n",
+	       tx3927_ccfgptr->crir,
+	       tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg);
+
+	/* IRC */
+	/* disable interrupt control */
+	tx3927_ircptr->cer = 0;
+	/* mask all IRC interrupts */
+	tx3927_ircptr->imr = 0;
+	for (i = 0; i < TX3927_NUM_IR / 2; i++) {
+		tx3927_ircptr->ilr[i] = 0;
+	}
+	/* setup IRC interrupt mode (Low Active) */
+	for (i = 0; i < TX3927_NUM_IR / 8; i++) {
+		tx3927_ircptr->cr[i] = 0;
+	}
+
+	/* TMR */
+	/* disable all timers */
+	for (i = 0; i < TX3927_NR_TMR; i++) {
+		tx3927_tmrptr(i)->tcr = TXx927_TMTCR_CRE;
+		tx3927_tmrptr(i)->tisr = 0;
+		tx3927_tmrptr(i)->cpra = 0xffffffff;
+		tx3927_tmrptr(i)->itmr = 0;
+		tx3927_tmrptr(i)->ccdr = 0;
+		tx3927_tmrptr(i)->pgmr = 0;
+	}
+
+	/* DMA */
+	tx3927_dmaptr->mcr = 0;
+	for (i = 0; i < sizeof(tx3927_dmaptr->ch) / sizeof(tx3927_dmaptr->ch[0]); i++) {
+		/* reset channel */
+		tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST;
+		tx3927_dmaptr->ch[i].ccr = 0;
+	}
+	/* enable DMA */
+#ifdef __BIG_ENDIAN
+	tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN;
+#else
+	tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE;
+#endif
+
+#ifdef CONFIG_PCI
+	/* PCIC */
+	printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:",
+	       tx3927_pcicptr->did, tx3927_pcicptr->vid,
+	       tx3927_pcicptr->rid);
+	if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) {
+		printk("External\n");
+		/* XXX */
+	} else {
+		printk("Internal\n");
+
+		/* Reset PCI Bus */
+		jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+		udelay(100);
+		jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI,
+				    JMR3927_IOC_RESET_ADDR);
+		udelay(100);
+		jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+
+
+		/* Disable External PCI Config. Access */
+		tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD;
+#ifdef __BIG_ENDIAN
+		tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE |
+			TX3927_PCIC_LBC_TIBSE |
+			TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE;
+#endif
+		/* LB->PCI mappings */
+		tx3927_pcicptr->iomas = ~(mips_pci_io_size - 1);
+		tx3927_pcicptr->ilbioma = mips_pci_io_base;
+		tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr;
+		tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1);
+		tx3927_pcicptr->ilbmma = mips_pci_mem_base;
+		tx3927_pcicptr->ipbmma = mips_pci_mem_base;
+		/* PCI->LB mappings */
+		tx3927_pcicptr->iobas = 0xffffffff;
+		tx3927_pcicptr->ioba = 0;
+		tx3927_pcicptr->tlbioma = 0;
+		tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1);
+		tx3927_pcicptr->mba = 0;
+		tx3927_pcicptr->tlbmma = 0;
+#ifndef JMR3927_INIT_INDIRECT_PCI
+		/* Enable Direct mapping Address Space Decoder */
+		tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE;
+#endif
+
+		/* Clear All Local Bus Status */
+		tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL;
+		/* Enable All Local Bus Interrupts */
+		tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL;
+		/* Clear All PCI Status Error */
+		tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL;
+		/* Enable All PCI Status Error Interrupts */
+		tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL;
+
+		/* PCIC Int => IRC IRQ10 */
+		tx3927_pcicptr->il = TX3927_IR_PCI;
+#if 1
+		/* Target Control (per errata) */
+		tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E;
+#endif
+
+		/* Enable Bus Arbiter */
+#if 0
+		tx3927_pcicptr->req_trace = 0x73737373;
+#endif
+		tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN;
+
+		tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER |
+			PCI_COMMAND_MEMORY |
+#if 1
+			PCI_COMMAND_IO |
+#endif
+			PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+	}
+#endif /* CONFIG_PCI */
+
+	/* PIO */
+	/* PIO[15:12] connected to LEDs */
+	tx3927_pioptr->dir = 0x0000f000;
+	tx3927_pioptr->maskcpu = 0;
+	tx3927_pioptr->maskext = 0;
+	{
+		unsigned int conf;
+
+	conf = read_32bit_cp0_register(CP0_CONF);
+               if (!(conf & TX39_CONF_ICE))
+                       printk("TX3927 I-Cache disabled.\n");
+               if (!(conf & TX39_CONF_DCE))
+                       printk("TX3927 D-Cache disabled.\n");
+               else if (!(conf & TX39_CONF_WBON))
+                       printk("TX3927 D-Cache WriteThrough.\n");
+               else if (!(conf & TX39_CONF_CWFON))
+                       printk("TX3927 D-Cache WriteBack.\n");
+               else
+                       printk("TX3927 D-Cache WriteBack (CWF) .\n");
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile
--- linux.orig/arch/mips/kernel/Makefile	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -6,41 +6,45 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(AFLAGS) $< -o $@
-.S.o:
-	$(CC) $(AFLAGS) -c $< -o $@
-
-EXTRA_AFLAGS = -mips3 -mcpu=r4000
+USE_STANDARD_AS_RULE := true
 
 all:	kernel.o head.o init_task.o
 
 O_TARGET := kernel.o
 
+export-objs			= irq.o pci-dma.o setup.o smp.o mips_ksyms.o \
+				  old-irq.o
+
 obj-y				+= branch.o process.o signal.o entry.o \
 				   traps.o ptrace.o vm86.o ioport.o reset.o \
 				   semaphore.o setup.o syscall.o sysmips.o \
 				   ipc.o scall_o32.o unaligned.o
 obj-$(CONFIG_MODULES)		+= mips_ksyms.o
 
-ifdef CONFIG_CPU_R3000
-obj-y	+= r2300_misc.o r2300_fpu.o r2300_switch.o
-else
-obj-y	+= r4k_misc.o r4k_switch.o 
-ifdef CONFIG_CPU_R6000
-obj-y	+= r6000_fpu.o
-else
-obj-y	+= r4k_fpu.o
-endif
-endif
+obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
+obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
+obj-$(CONFIG_CPU_TX49XX)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4000)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_VR41XX)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4300)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4X00)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R5000)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R5432)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_RM7000)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_NEVADA)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R10000)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_SB1)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_MIPS32)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_MIPS64)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o r4k_switch.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 
 # Old style irq support, going to die in 2.5.
-export-objs			+= old-irq.o
 obj-$(CONFIG_NEW_IRQ)		+= irq.o
 obj-$(CONFIG_ROTTEN_IRQ)	+= old-irq.o
 obj-$(CONFIG_I8259)		+= i8259.o
+obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
 
 # transition from old time.c to new time.c
 # some boards uses old-time.c, some use time.c, and some use their own ones
@@ -51,13 +55,13 @@
 obj-$(CONFIG_BINFMT_IRIX)	+= irixelf.o irixioctl.o irixsig.o sysirix.o \
 				   irixinv.o
 obj-$(CONFIG_REMOTE_DEBUG)	+= gdb-low.o gdb-stub.o 
-obj-$(CONFIG_PCI)		+= pci-dma.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
 
-ifdef CONFIG_PCI
-obj-$(CONFIG_NEW_PCI)          += pci.o
-obj-$(CONFIG_PCI_AUTO)         += pci_auto.o
+obj-$(CONFIG_NEW_PCI)		+= pci.o
+ifndef CONFIG_MAPPED_PCI_IO
+obj-y				+= pci-dma.o
 endif
+obj-$(CONFIG_PCI_AUTO)		+= pci_auto.o
 
 entry.o: entry.S
 head.o: head.S
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/branch.c linux/arch/mips/kernel/branch.c
--- linux.orig/arch/mips/kernel/branch.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/branch.c	2002-07-20 01:08:37.000000000 +0000
@@ -16,7 +16,6 @@
 #include <asm/inst.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
-#include <asm/bootinfo.h>
 #include <asm/processor.h>
 
 /*
@@ -164,10 +163,10 @@
 	 * And now the FPA/cp1 branch instructions.
 	 */
 	case cop1_op:
-		if(!(mips_cpu.options & MIPS_CPU_FPU))
+		if (!(mips_cpu.options & MIPS_CPU_FPU))
 			fcr31 = current->thread.fpu.soft.sr;
 		else
-			asm ("cfc1\t%0,$31":"=r" (fcr31));
+			asm("cfc1\t%0,$31":"=r" (fcr31));
 		bit = (insn.i_format.rt >> 2);
 		bit += (bit != 0);
 		bit += 23;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/entry.S linux/arch/mips/kernel/entry.S
--- linux.orig/arch/mips/kernel/entry.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/entry.S	2002-07-20 01:08:27.000000000 +0000
@@ -1,5 +1,4 @@
 /*
-/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -9,15 +8,17 @@
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/sys.h>
 
 #include <asm/addrspace.h>
 #include <asm/asm.h>
+#include <asm/cacheops.h>
 #include <asm/current.h>
 #include <asm/errno.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgtable-bits.h>
 #include <asm/stackframe.h>
 #include <asm/processor.h>
 #include <asm/regdef.h>
@@ -66,6 +67,7 @@
 		lw	v1, TASK_SIGPENDING($28)
 		bnez	v0, reschedule
 		bnez	v1, signal_return
+		FEXPORT(restore_all)
 restore_all:	.set	noat
 		RESTORE_ALL_AND_RET
 		.set	at
@@ -93,15 +95,89 @@
 		 * Someone tried to fool us by sending an interrupt but we
 		 * couldn't find a cause for it.
 		 */
-		lui     t1,%hi(spurious_count)
-		.set	reorder
-		lw      t0,%lo(spurious_count)(t1)
-		.set	noreorder
+		lui     t1,%hi(irq_err_count)
+		lw      t0,%lo(irq_err_count)(t1)
 		addiu   t0,1
-		sw      t0,%lo(spurious_count)(t1)
+		sw      t0,%lo(irq_err_count)(t1)
 		j	ret_from_irq
 		END(spurious_interrupt)
 
+		__INIT
+
+		.set	reorder
+
+		NESTED(except_vec1_generic, 0, sp)
+		PANIC("Exception vector 1 called")
+		END(except_vec1_generic)
+
+		/*
+		 * General exception vector.  Used for all CPUs except R4000
+		 * and R4400 SC and MC versions.
+		 */
+		NESTED(except_vec3_generic, 0, sp)
+		mfc0	k1, CP0_CAUSE
+		la	k0, exception_handlers
+		andi	k1, k1, 0x7c
+		addu	k0, k0, k1
+		lw	k0, (k0)
+		jr	k0
+		END(except_vec3_generic)
+		.set	at
+
+		/* General exception vector R4000 version. */
+		NESTED(except_vec3_r4000, 0, sp)
+		.set	push
+		.set    mips3
+		.set	noat
+		mfc0	k1, CP0_CAUSE
+		li	k0, 31<<2
+		andi	k1, k1, 0x7c
+		.set	noreorder
+		beq	k1, k0, handle_vced
+		 li	k0, 14<<2
+		beq	k1, k0, handle_vcei
+		 la	k0, exception_handlers
+		.set	reorder
+		addu	k0, k0, k1
+		lw	k0, (k0)
+		jr	k0
+
+		/*
+		 * Big shit, we now may have two dirty primary cache lines for
+		 * the same physical address.  We can savely invalidate the
+		 * line pointed to by c0_badvaddr because after return from
+		 * this exception handler the load / store will be re-executed.
+		 */
+handle_vced:
+		mfc0	k0, CP0_BADVADDR
+		li	k1, -4
+		and	k0, k1
+		mtc0	zero, CP0_TAGLO
+		cache	Index_Store_Tag_D,(k0)
+		cache	Hit_Writeback_Inv_SD,(k0)
+#ifdef CONFIG_PROC_FS
+		lui	k0, %hi(vced_count)
+		lw	k1, %lo(vced_count)(k0)
+		addiu	k1, 1
+		sw	k1, %lo(vced_count)(k0)
+#endif
+		eret
+
+handle_vcei:
+		mfc0	k0, CP0_BADVADDR
+		cache	Hit_Writeback_Inv_SD, (k0)	# also cleans pi
+#ifdef CONFIG_PROC_FS
+		lui	k0, %hi(vcei_count)
+		lw	k1, %lo(vcei_count)(k0)
+		addiu	k1, 1
+		sw	k1, %lo(vcei_count)(k0)
+#endif
+		eret
+		.set    pop
+		END(except_vec3_r4000)
+
+		__FINIT
+
 /*
  * Build a default exception handler for the exceptions that don't need
  * special handlers.  If you didn't know yet - I *like* playing games with
@@ -148,6 +224,7 @@
 		NESTED(handle_##exception, PT_SIZE, sp);                \
 		.set	noat;                                           \
 		SAVE_ALL;                                               \
+		FEXPORT(handle_##exception##_int);			\
 		__BUILD_clear_##clear(exception);                       \
 		.set	at;                                             \
 		__BUILD_##verbose(exception);                           \
@@ -159,16 +236,17 @@
 
 		BUILD_HANDLER(adel,ade,ade,silent)		/* #4  */
 		BUILD_HANDLER(ades,ade,ade,silent)		/* #5  */
-		BUILD_HANDLER(ibe,ibe,cli,verbose)		/* #6  */
-		BUILD_HANDLER(dbe,dbe,cli,silent)		/* #7  */
+		BUILD_HANDLER(ibe,be,cli,silent)		/* #6  */
+		BUILD_HANDLER(dbe,be,cli,silent)		/* #7  */
 		BUILD_HANDLER(bp,bp,sti,silent)			/* #9  */
 		BUILD_HANDLER(ri,ri,sti,silent)			/* #10 */
 		BUILD_HANDLER(cpu,cpu,sti,silent)		/* #11 */
 		BUILD_HANDLER(ov,ov,sti,silent)			/* #12 */
 		BUILD_HANDLER(tr,tr,sti,silent)			/* #13 */
 		BUILD_HANDLER(fpe,fpe,fpe,silent)		/* #15 */
-		BUILD_HANDLER(watch,watch,sti,verbose)		/* #23 */
-		BUILD_HANDLER(reserved,reserved,sti,verbose)	/* others */
+		BUILD_HANDLER(watch,watch,sti,silent)		/* #23 */
+		BUILD_HANDLER(mcheck,mcheck,cli,silent)		/* #24 */
+		BUILD_HANDLER(reserved,reserved,sti,silent)	/* others */
 
 		.set	pop
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/gdb-low.S linux/arch/mips/kernel/gdb-low.S
--- linux.orig/arch/mips/kernel/gdb-low.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/gdb-low.S	2002-07-20 01:08:28.000000000 +0000
@@ -145,9 +145,9 @@
  * FPU control registers
  */
 
-		mfc1	v0,CP1_STATUS
+		cfc1	v0,CP1_STATUS
 		sw	v0,GDB_FR_FSR(sp)
-		mfc1	v0,CP1_REVISION
+		cfc1	v0,CP1_REVISION
 		sw	v0,GDB_FR_FIR(sp)
 
 /*
@@ -304,7 +304,7 @@
 		lw	v1,GDB_FR_REG3(sp)
 		lw	v0,GDB_FR_REG2(sp)
 		lw	$1,GDB_FR_REG1(sp)
-#ifdef CONFIG_CPU_R3000
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 		lw	k0, GDB_FR_EPC(sp)
 		lw	sp, GDB_FR_REG29(sp)		/* Deallocate stack */
 		jr	k0
@@ -321,11 +321,7 @@
 		END(trap_low)
 
 LEAF(kgdb_read_byte)
-		.set push
-		.set noreorder
-		.set nomacro
 4:		lb	t0, (a0)
-		.set pop
 		sb	t0, (a1)
 		li	v0, 0
 		jr	ra
@@ -335,11 +331,7 @@
 		END(kgdb_read_byte)
 
 LEAF(kgdb_write_byte)
-		.set push
-		.set noreorder
-		.set nomacro
 5:		sb	a0, (a1)
-		.set pop
 		li	v0, 0
 		jr	ra
 		.section __ex_table,"a"
@@ -349,6 +341,7 @@
 
 		.type	kgdbfault@function
 		.ent	kgdbfault
+
 kgdbfault:	li	v0, -EFAULT
 		jr	ra
 		.end	kgdbfault
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/gdb-stub.c linux/arch/mips/kernel/gdb-stub.c
--- linux.orig/arch/mips/kernel/gdb-stub.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/gdb-stub.c	2002-07-20 01:08:40.000000000 +0000
@@ -11,8 +11,6 @@
  *  Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
  *
  *  Copyright (C) 1995 Andreas Busse
- *
- * $Id: gdb-stub.c,v 1.6 1999/05/01 22:40:35 ralf Exp $
  */
 
 /*
@@ -121,6 +119,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
@@ -578,7 +577,7 @@
 	async_bp.addr = epc;
 	async_bp.val  = *(unsigned *)epc;
 	*(unsigned *)epc = BP;
-	flush_cache_all();
+	__flush_cache_all();
 }
 
 
@@ -805,7 +804,7 @@
 			 * NB: We flush both caches, just to be sure...
 			 */
 
-			flush_cache_all();
+			__flush_cache_all();
 			return;
 			/* NOTREACHED */
 			break;
@@ -834,7 +833,7 @@
 			 * use breakpoints and continue, instead.
 			 */
 			single_step(regs);
-			flush_cache_all();
+			__flush_cache_all();
 			return;
 			/* NOTREACHED */
 
@@ -925,9 +924,8 @@
 
 #ifdef CONFIG_GDB_CONSOLE
 
-void gdb_puts(const char *str)
+void gdb_putsn(const char *str, int l)
 {
-	int l = strlen(str);
 	char outbuf[18];
 
 	outbuf[0]='O';
@@ -949,7 +947,7 @@
 
 static void gdb_console_write(struct console *con, const char *s, unsigned n)
 {
-	gdb_puts(s);
+	gdb_putsn(s, n);
 }
 
 static struct console gdb_console = {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/head.S linux/arch/mips/kernel/head.S
--- linux.orig/arch/mips/kernel/head.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/head.S	2002-07-20 01:08:25.000000000 +0000
@@ -1,6 +1,4 @@
 /*
- * arch/mips/kernel/head.S
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -13,550 +11,214 @@
  * Further modifications by David S. Miller and Harald Koerfgen
  * Copyright (C) 1999 Silicon Graphics, Inc.
  *
- * Head.S contains the MIPS exception handler and startup code.
- *
- **************************************************************************
- *  9 Nov, 2000.
- *  Added Cache Error exception handler and SBDDP EJTAG debug exception.
- *
- *  Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- **************************************************************************
+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  */
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/threads.h>
 
 #include <asm/asm.h>
-#include <asm/cacheops.h>
 #include <asm/current.h>
 #include <asm/offset.h>
+#include <asm/pgtable-bits.h>
 #include <asm/processor.h>
 #include <asm/regdef.h>
 #include <asm/cachectl.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
-#include <asm/bootinfo.h>
-
-	.text
-	/*
-	 * Reserved space for exception handlers.
-	 * Necessary for machines which link their kernels at KSEG0.
-	 * FIXME: Use the initcode feature to get rid of unused handler
-	 * variants.
-	 */
-	.fill	0x280
-/*	
- * This is space for the interrupt handlers.
- * After trap_init() they are located at virtual address KSEG0.
- *
- * These handlers much be written in a relocatable manner
- * because based upon the cpu type an arbitrary one of the
- * following pieces of code will be copied to the KSEG0
- * vector location.
- */
-	/* TLB refill, EXL == 0, R4xx0, non-R4600 version */
-	.set	noreorder
-	.set	noat
-	LEAF(except_vec0_r4000)
-	.set	mips3
-#ifdef CONFIG_SMP
-	mfc0	k1, CP0_CONTEXT
-	la	k0, current_pgd
-	srl	k1, 23
-	sll	k1, 2
-	addu	k1, k0, k1
-	lw	k1, (k1)
-#else 
-	lw	k1, current_pgd			# get pgd pointer
-#endif	
-	mfc0	k0, CP0_BADVADDR		# Get faulting address
-	srl	k0, k0, 22			# get pgd only bits
-
-	sll	k0, k0, 2
-	addu	k1, k1, k0			# add in pgd offset
-	mfc0	k0, CP0_CONTEXT			# get context reg
-	lw	k1, (k1)
-#if defined(CONFIG_CPU_VR41XX)
-	srl	k0, k0, 3			# get pte offset
-#else
-	srl	k0, k0, 1			# get pte offset
-#endif
-	and	k0, k0, 0xff8
-	addu	k1, k1, k0			# add in offset
-	lw	k0, 0(k1)			# get even pte
-	lw	k1, 4(k1)			# get odd pte
-	srl	k0, k0, 6			# convert to entrylo0
-	mtc0	k0, CP0_ENTRYLO0		# load it
-	srl	k1, k1, 6			# convert to entrylo1
-	mtc0	k1, CP0_ENTRYLO1		# load it
-	b	1f
-	tlbwr					# write random tlb entry
-1:
-	nop
-	eret					# return from trap
-	END(except_vec0_r4000)
-
-	/* TLB refill, EXL == 0, R4600 version */
-	LEAF(except_vec0_r4600)
-	.set	mips3
-	mfc0	k0, CP0_BADVADDR
-	srl	k0, k0, 22
-	lw	k1, current_pgd			# get pgd pointer
-	sll	k0, k0, 2
-	addu	k1, k1, k0
-	mfc0	k0, CP0_CONTEXT
-	lw	k1, (k1)
-	srl	k0, k0, 1
-	and	k0, k0, 0xff8
-	addu	k1, k1, k0
-	lw	k0, 0(k1)
-	lw	k1, 4(k1)
-	srl	k0, k0, 6
-	mtc0	k0, CP0_ENTRYLO0
-	srl	k1, k1, 6
-	mtc0	k1, CP0_ENTRYLO1
-	nop
-	tlbwr
-	nop
-	eret
-	END(except_vec0_r4600)
-
-	/* TLB refill, EXL == 0, R52x0 "Nevada" version */
-        /*
-         * This version has a bug workaround for the Nevada.  It seems
-         * as if under certain circumstances the move from cp0_context
-         * might produce a bogus result when the mfc0 instruction and
-         * it's consumer are in a different cacheline or a load instruction,
-         * probably any memory reference, is between them.  This is
-         * potencially slower than the R4000 version, so we use this
-         * special version.
-         */
-	.set	noreorder
-	.set	noat
-	LEAF(except_vec0_nevada)
-	.set	mips3
-	mfc0	k0, CP0_BADVADDR		# Get faulting address
-	srl	k0, k0, 22			# get pgd only bits
-	lw	k1, current_pgd			# get pgd pointer
-	sll	k0, k0, 2
-	addu	k1, k1, k0			# add in pgd offset
-	lw	k1, (k1)
-	mfc0	k0, CP0_CONTEXT			# get context reg
-	srl	k0, k0, 1			# get pte offset
-	and	k0, k0, 0xff8
-	addu	k1, k1, k0			# add in offset
-	lw	k0, 0(k1)			# get even pte
-	lw	k1, 4(k1)			# get odd pte
-	srl	k0, k0, 6			# convert to entrylo0
-	mtc0	k0, CP0_ENTRYLO0		# load it
-	srl	k1, k1, 6			# convert to entrylo1
-	mtc0	k1, CP0_ENTRYLO1		# load it
-	nop					# QED specified nops
-	nop
-	tlbwr					# write random tlb entry
-	nop					# traditional nop
-	eret					# return from trap
-	END(except_vec0_nevada)
-
-	/* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */
-	LEAF(except_vec0_r45k_bvahwbug)
-	.set	mips3
-	mfc0	k0, CP0_BADVADDR
-	srl	k0, k0, 22
-	lw	k1, current_pgd			# get pgd pointer
-	sll	k0, k0, 2
-	addu	k1, k1, k0
-	mfc0	k0, CP0_CONTEXT
-	lw	k1, (k1)
-	srl	k0, k0, 1
-	and	k0, k0, 0xff8
-	addu	k1, k1, k0
-	lw	k0, 0(k1)
-	lw	k1, 4(k1)
-	nop				/* XXX */
-	tlbp
-	srl	k0, k0, 6
-	mtc0	k0, CP0_ENTRYLO0
-	srl	k1, k1, 6
-	mfc0	k0, CP0_INDEX
-	mtc0	k1, CP0_ENTRYLO1
-	bltzl	k0, 1f
-	tlbwr
-1:
-	nop
-	eret
-	END(except_vec0_r45k_bvahwbug)
-
-#ifdef CONFIG_SMP
-	/* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */
-	LEAF(except_vec0_r4k_mphwbug)
-	.set	mips3
-	mfc0	k0, CP0_BADVADDR
-	srl	k0, k0, 22
-	lw	k1, current_pgd			# get pgd pointer
-	sll	k0, k0, 2
-	addu	k1, k1, k0
-	mfc0	k0, CP0_CONTEXT
-	lw	k1, (k1)
-	srl	k0, k0, 1
-	and	k0, k0, 0xff8
-	addu	k1, k1, k0
-	lw	k0, 0(k1)
-	lw	k1, 4(k1)
-	nop				/* XXX */
-	tlbp
-	srl	k0, k0, 6
-	mtc0	k0, CP0_ENTRYLO0
-	srl	k1, k1, 6
-	mfc0	k0, CP0_INDEX
-	mtc0	k1, CP0_ENTRYLO1
-	bltzl	k0, 1f
-	tlbwr
-1:
-	nop
-	eret
-	END(except_vec0_r4k_mphwbug)
-#endif
-
-	/* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */
-	LEAF(except_vec0_r4k_250MHZhwbug)
-	.set	mips3
-	mfc0	k0, CP0_BADVADDR
-	srl	k0, k0, 22
-	lw	k1, current_pgd			# get pgd pointer
-	sll	k0, k0, 2
-	addu	k1, k1, k0
-	mfc0	k0, CP0_CONTEXT
-	lw	k1, (k1)
-	srl	k0, k0, 1
-	and	k0, k0, 0xff8
-	addu	k1, k1, k0
-	lw	k0, 0(k1)
-	lw	k1, 4(k1)
-	srl	k0, k0, 6
-	mtc0	zero, CP0_ENTRYLO0
-	mtc0	k0, CP0_ENTRYLO0
-	srl	k1, k1, 6
-	mtc0	zero, CP0_ENTRYLO1
-	mtc0	k1, CP0_ENTRYLO1
-	b	1f
-	tlbwr
-1:
-	nop
-	eret
-	END(except_vec0_r4k_250MHZhwbug)
-
-#ifdef CONFIG_SMP
-	/* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */
-	LEAF(except_vec0_r4k_MP250MHZhwbug)
-	.set	mips3
-	mfc0	k0, CP0_BADVADDR
-	srl	k0, k0, 22
-	lw	k1, current_pgd			# get pgd pointer
-	sll	k0, k0, 2
-	addu	k1, k1, k0
-	mfc0	k0, CP0_CONTEXT
-	lw	k1, (k1)
-	srl	k0, k0, 1
-	and	k0, k0, 0xff8
-	addu	k1, k1, k0
-	lw	k0, 0(k1)
-	lw	k1, 4(k1)
-	nop				/* XXX */
-	tlbp
-	srl	k0, k0, 6
-	mtc0	zero, CP0_ENTRYLO0
-	mtc0	k0, CP0_ENTRYLO0
-	mfc0	k0, CP0_INDEX
-	srl	k1, k1, 6
-	mtc0	zero, CP0_ENTRYLO1
-	mtc0	k1, CP0_ENTRYLO1
-	bltzl	k0, 1f
-	tlbwr
-1:
-	nop
-	eret
-	END(except_vec0_r4k_MP250MHZhwbug)
-#endif
-
-	/* TLB refill, R[23]00 version */
-	LEAF(except_vec0_r2300)
-	.set	noat
-	.set	mips1
-	mfc0	k0, CP0_BADVADDR
-	lw	k1, current_pgd			# get pgd pointer
-	srl	k0, k0, 22
-	sll	k0, k0, 2
-	addu	k1, k1, k0
-	mfc0	k0, CP0_CONTEXT
-	lw	k1, (k1)
-	and	k0, k0, 0xffc
-	addu	k1, k1, k0
-	lw	k0, (k1)
-	nop
-	mtc0	k0, CP0_ENTRYLO0
-	mfc0	k1, CP0_EPC
-	tlbwr
-	jr	k1
-	rfe
-	END(except_vec0_r2300)
-
-
-	/* XTLB refill, EXL == 0, R4xx0 cpus only use this... */
-	NESTED(except_vec1_generic, 0, sp)
-	.set	noat
-	.set	mips3
-	/* Register saving is delayed as long as we don't know
-	 * which registers really need to be saved.
-	 */
-	mfc0	k1, CP0_CONTEXT
-	dsra	k1, 1
-	lwu	k0,  (k1)		# May cause another exception
-	lwu	k1, 4(k1)
-	dsrl	k0, 6			# Convert to EntryLo format
-	dsrl	k1, 6			# Convert to EntryLo format
-	dmtc0	k0, CP0_ENTRYLO0
-	dmtc0	k1, CP0_ENTRYLO1
-	nop				# Needed for R4[04]00 pipeline
-	tlbwr
-	nop				# Needed for R4[04]00 pipeline
-	nop
-	nop
-	eret
-	nop				/* Workaround for R4000 bug. */
-	eret
-	END(except_vec1_generic)
-
-	/* Cache Error */
-	LEAF(except_vec2_generic)
-	.set	noat
-	.set    mips0
-	/*
-	 * This is a very bad place to be.  Our cache error
-	 * detection has triggered.  If we have write-back data
-	 * in the cache, we may not be able to recover.  As a
-	 * first-order desperate measure, turn off KSEG0 cacheing.
-	 */
-	mfc0	k0,CP0_CONFIG
-	li	k1,~CONF_CM_CMASK
-	and	k0,k0,k1
-	ori	k0,k0,CONF_CM_UNCACHED
-	mtc0	k0,CP0_CONFIG
-	/* Give it a few cycles to sink in... */
-	nop
-	nop
-	nop
-
-	j	cache_parity_error
-	nop
-	END(except_vec2_generic)
-
-	/* General exception vector R4000 version. */
-	NESTED(except_vec3_r4000, 0, sp)
-	.set	noat
-	mfc0	k1, CP0_CAUSE
-	andi	k1, k1, 0x7c
-	li	k0, 31<<2
-	beq	k1, k0, handle_vced
-	 li	k0, 14<<2
-	beq	k1, k0, handle_vcei
-	 la	k0, exception_handlers
-	addu	k0, k0, k1
-	lw	k0, (k0)
-	nop
-	jr	k0
-	 nop
-
-/*
- * Big shit, we now may have two dirty primary cache lines for the same
- * physical address.  We can savely invalidate the line pointed to by
- * c0_badvaddr because after return from this exception handler the load /
- * store will be re-executed.
- */
-	.set    mips3
-handle_vced:
-	mfc0	k0, CP0_BADVADDR
- li k1, -4
- and k0, k1
-	mtc0	zero, CP0_TAGLO
-	cache	Index_Store_Tag_D,(k0)
-	cache	Hit_Writeback_Inv_SD,(k0)
-#ifdef CONFIG_PROC_FS
-	lui	k0, %hi(vced_count)
-	lw	k1, %lo(vced_count)(k0)
-	addiu	k1, 1
-	sw	k1, %lo(vced_count)(k0)
-#endif
-	eret
-
-handle_vcei:
-	mfc0	k0, CP0_BADVADDR
-	cache	Hit_Writeback_Inv_SD,(k0)		# also cleans pi
-#ifdef CONFIG_PROC_FS
-	lui	k0, %hi(vcei_count)
-	lw	k1, %lo(vcei_count)(k0)
-	addiu	k1, 1
-	sw	k1, %lo(vcei_count)(k0)
-#endif
-	eret
-
-	END(except_vec3_r4000)
-	.set	at
-
-	/* General exception vector. */
-	NESTED(except_vec3_generic, 0, sp)
-	.set	noat
-	.set	mips0
-	mfc0	k1, CP0_CAUSE
-	la	k0, exception_handlers
-	andi	k1, k1, 0x7c
-	addu	k0, k0, k1
-	lw	k0, (k0)
-	nop
-	jr	k0
-	 nop
-	END(except_vec3_generic)
-	.set	at
-
-	/*
-	 * Special interrupt vector for embedded MIPS.  This is a
-	 * dedicated interrupt vector which reduces interrupt processing
-	 * overhead.  The jump instruction will be inserted here at
-	 * initialization time.  This handler may only be 8 bytes in size!
-	 */
-	NESTED(except_vec4, 0, sp)
-1:	j	1b			/* Dummy, will be replaced */
-	 nop
-	END(except_vec4)
-
-	/*
-	 * SBDDP EJTAG debug exception handler.
-	 * The EJTAG debug exception entry point is 0xbfc00480, which
-	 * normally is in the boot PROM, so the boot PROM must do a
-	 * unconditional jump to this vector.
-	 */	
-	NESTED(except_vec_ejtag_debug, 0, sp)
-	j	ejtag_debug_handler
-	 nop
-	END(except_vec_ejtag_debug)
-
-	/*
-	 * EJTAG debug exception handler.
-	 */
-	NESTED(ejtag_debug_handler, PT_SIZE, sp)
-	.set	noat
-	.set	noreorder
-	SAVE_ALL
-	PRINT("SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
-	mfc0	k0, $23         # Get EJTAG Debug register.
-	mfc0    k1, $24         # Get DEPC register.
-	bgez	k0, 1f
-	 addiu	k1, k1, 4	# SBDDP inst. in delay slot.
-	addiu	k1, k1, 4
-1:	mtc0	k1, $24
-	RESTORE_ALL
-	.word	0x4200001f      # deret, return EJTAG debug exception.
-	 nop
-	.set	at
-	END(ejtag_debug_handler)
 
-		
-/*
- * Kernel entry point
- */
-NESTED(kernel_entry, 16, sp)
-	.set	noreorder
-	/* The following two symbols are used for kernel profiling. */
-	EXPORT(stext)
-	EXPORT(_stext)
-
-	/*
-	 * Stack for kernel and init, current variable
-	 */
-	la	$28, init_task_union
-	addiu	t0, $28, KERNEL_STACK_SIZE-32
-	subu	sp, t0, 4*SZREG
-
-	sw	t0, kernelsp
-	/* The firmware/bootloader passes argc/argp/envp
-	 * to us as arguments.  But clear bss first because
-	 * the romvec and other important info is stored there
-	 * by prom_init().
-	 */
-	la	t0, _edata
-	sw	zero, (t0)
-	la	t1, (_end - 4)
-1:
-	addiu	t0, 4
-	bne	t0, t1, 1b
-	 sw	zero, (t0)
-
-	jal	init_arch
-	 nop
-	END(kernel_entry)
+		.text
+		/*
+		 * Reserved space for exception handlers.
+		 * Necessary for machines which link their kernels at KSEG0.
+		 */
+		.fill	0x400
+
+		__INIT
+
+		/* Cache Error */
+		LEAF(except_vec2_generic)
+		.set	noreorder
+		.set	noat
+		.set    mips0
+		/*
+		 * This is a very bad place to be.  Our cache error
+		 * detection has triggered.  If we have write-back data
+		 * in the cache, we may not be able to recover.  As a
+		 * first-order desperate measure, turn off KSEG0 cacheing.
+		 */
+		mfc0	k0,CP0_CONFIG
+		li	k1,~CONF_CM_CMASK
+		and	k0,k0,k1
+		ori	k0,k0,CONF_CM_UNCACHED
+		mtc0	k0,CP0_CONFIG
+		/* Give it a few cycles to sink in... */
+		nop
+		nop
+		nop
+
+		j	cache_parity_error
+		nop
+		END(except_vec2_generic)
+
+		.set	at
+
+		/*
+		 * Special interrupt vector for embedded MIPS.  This is a
+		 * dedicated interrupt vector which reduces interrupt processing
+		 * overhead.  The jump instruction will be inserted here at
+		 * initialization time.  This handler may only be 8 bytes in
+		 * size!
+		 */
+		NESTED(except_vec4, 0, sp)
+1:		j	1b			/* Dummy, will be replaced */
+		 nop
+		END(except_vec4)
+
+		/*
+		 * EJTAG debug exception handler.
+		 * The EJTAG debug exception entry point is 0xbfc00480, which
+		 * normally is in the boot PROM, so the boot PROM must do a
+		 * unconditional jump to this vector.
+		 */	
+		NESTED(except_vec_ejtag_debug, 0, sp)
+		j	ejtag_debug_handler
+		 nop
+		END(except_vec_ejtag_debug)
+
+		/*
+		 * EJTAG debug exception handler.
+		 */
+		NESTED(ejtag_debug_handler, PT_SIZE, sp)
+		.set	noat
+		.set	noreorder
+		mtc0	k0, CP0_DESAVE
+		mfc0	k0, CP0_DEBUG	
+
+		sll	k0, k0, 30	# Check for SDBBP.
+		bgez	k0, ejtag_return
+
+		la	k0, ejtag_debug_buffer
+		sw	k1, 0(k0)
+		SAVE_ALL
+		jal	ejtag_exception_handler
+		 move	a0, sp
+		RESTORE_ALL
+		la	k0, ejtag_debug_buffer
+		lw	k1, 0(k0)	
+
+ejtag_return:
+		mfc0	k0, CP0_DESAVE	
+		.word	0x4200001f     # DERET, return from EJTAG debug exception.
+		 nop
+		.set	at
+		END(ejtag_debug_handler)
+	
+		/*
+		* NMI debug exception handler for MIPS reference boards.
+		* The NMI debug exception entry point is 0xbfc00000, which
+		* normally is in the boot PROM, so the boot PROM must do a
+		* unconditional jump to this vector.
+		*/
+		NESTED(except_vec_nmi, 0, sp)
+		j       nmi_handler
+		 nop
+		END(except_vec_nmi)
+
+		NESTED(nmi_handler, PT_SIZE, sp)
+		.set    noat
+		.set    noreorder
+		.set    mips3
+		SAVE_ALL
+		jal     nmi_exception_handler
+		 move   a0, sp
+		RESTORE_ALL
+		eret
+		.set    at
+		.set    mips0
+		END(nmi_handler)	
+
+		/*
+		 * Kernel entry point
+		 */
+		NESTED(kernel_entry, 16, sp)
+		.set	noreorder
+		/* The following two symbols are used for kernel profiling. */
+		EXPORT(stext)
+		EXPORT(_stext)
+
+		/*
+		 * Stack for kernel and init, current variable
+		 */
+		la	$28, init_task_union
+		addiu	t0, $28, KERNEL_STACK_SIZE-32
+		subu	sp, t0, 4*SZREG
+
+		sw	t0, kernelsp
+		/* The firmware/bootloader passes argc/argp/envp
+		 * to us as arguments.  But clear bss first because
+		 * the romvec and other important info is stored there
+		 * by prom_init().
+		 */
+		la	t0, _edata
+		sw	zero, (t0)
+		la	t1, (_end - 4)
+1:
+		addiu	t0, 4
+		bne	t0, t1, 1b
+		 sw	zero, (t0)
+
+		jal	init_arch
+		 nop
+		END(kernel_entry)
 
 
 #ifdef CONFIG_SMP
 
 /*
- * SMP slave cpus entry point.  Board specific code
- * for bootstrap calls this function after setting up
- * the stack and gp registers. 
- */
-	LEAF(smp_bootstrap)
-	.set push
-	.set noreorder
-	mtc0	zero, CP0_WIRED
-	CLI
-	mfc0	t0, CP0_STATUS
-	li	t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); 
-	and	t0, t1
-	or	t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR);
-	addiu	a0, zero, 0
-	jal	start_secondary
-         mtc0	t0, CP0_STATUS
-	.set pop
-	END(smp_bootstrap)
-#endif
-	
-/*
- * This buffer is reserved for the use of the cache error handler.
+ * SMP slave cpus entry point.  Board specific code for bootstrap calls this
+ * function after setting up the stack and gp registers. 
  */
+		LEAF(smp_bootstrap)
+		.set push
+		.set noreorder
+		mtc0	zero, CP0_WIRED
+		CLI
+		mfc0	t0, CP0_STATUS
+		li	t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX)
+		and	t0, t1
+		or	t0, (ST0_CU0);
+		jal	start_secondary
+		mtc0	t0, CP0_STATUS
+		.set pop
+		END(smp_bootstrap)
+#endif
+
+		__FINIT
+
+		/*
+		 * This buffer is reserved for the use of the EJTAG debug 
+		 * handler.
+		 */
 		.data
-		EXPORT(cache_error_buffer)
-		.fill	32*4,1,0
-
-#ifndef CONFIG_SMP
-EXPORT(kernelsp)
-		PTR	0
-EXPORT(current_pgd)
-		PTR     0
-#else
-		/* There's almost certainly a better way to do this with the macros...*/
-		.globl kernelsp
-		.comm  kernelsp,     NR_CPUS * 8, 8
-		.globl current_pgd
-		.comm	current_pgd, NR_CPUS * 8, 8
-#endif
-		.text
-		.org	0x1000
-EXPORT(swapper_pg_dir)
-
-		.org	0x2000
-EXPORT(empty_bad_page)
-
-		.org	0x3000
-EXPORT(empty_bad_page_table)
+		EXPORT(ejtag_debug_buffer)
+		.fill	4
+	
+		.comm	kernelsp,    NR_CPUS * 8, 8
+		.comm	pgd_current, NR_CPUS * 8, 8
 
-		.org	0x4000
-EXPORT(invalid_pte_table)
-
-		.org	0x5000
-/* XXX This label is required to keep GAS trying to be too clever ...
-   Bug?  */
-dummy:
-/*
- * Align to 8kb boundary for init_task_union which follows in the
- * .text segment.
- */
-		.align	13
+	.macro	page name, order=0
+	.globl	\name
+\name:	.size	\name, (_PAGE_SIZE << \order)
+	.org	. + (_PAGE_SIZE << \order)
+	.type	\name, @object
+	.endm
+
+	.data
+	.align	12
+
+	page	swapper_pg_dir, _PGD_ORDER
+	page	empty_bad_page, 0
+	page	empty_bad_page_table, 0
+	page	invalid_pte_table, 0
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/i8259.c linux/arch/mips/kernel/i8259.c
--- linux.orig/arch/mips/kernel/i8259.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/i8259.c	2002-07-20 01:08:26.000000000 +0000
@@ -11,7 +11,6 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
@@ -30,7 +29,7 @@
  * moves to arch independent land
  */
 
-spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
 
 static void end_8259A_irq (unsigned int irq)
 {
@@ -69,9 +68,8 @@
  */
 static unsigned int cached_irq_mask = 0xffff;
 
-#define __byte(x,y) 	(((unsigned char *)&(y))[x])
-#define cached_21	(__byte(0,cached_irq_mask))
-#define cached_A1	(__byte(1,cached_irq_mask))
+#define cached_21	(cached_irq_mask)
+#define cached_A1	(cached_irq_mask >> 8)
 
 void disable_8259A_irq(unsigned int irq)
 {
@@ -211,7 +209,7 @@
 			printk("spurious 8259A interrupt: IRQ%d.\n", irq);
 			spurious_irq_mask |= irqmask;
 		}
-		irq_err_count++;
+		atomic_inc(&irq_err_count);
 		/*
 		 * Theoretically we do not have to handle this IRQ,
 		 * but in Linux this does not cause problems and is
@@ -234,7 +232,7 @@
 	 * outb_p - this has to work on a wide range of PC hardware.
 	 */
 	outb_p(0x11, 0x20);	/* ICW1: select 8259A-1 init */
-	outb_p(0x20 + 0, 0x21);	/* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
+	outb_p(0x00, 0x21);	/* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */
 	outb_p(0x04, 0x21);	/* 8259A-1 (the master) has a slave on IR2 */
 	if (auto_eoi)
 		outb_p(0x03, 0x21);	/* master does Auto EOI */
@@ -242,7 +240,7 @@
 		outb_p(0x01, 0x21);	/* master expects normal EOI */
 
 	outb_p(0x11, 0xA0);	/* ICW1: select 8259A-2 init */
-	outb_p(0x20 + 8, 0xA1);	/* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
+	outb_p(0x08, 0xA1);	/* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */
 	outb_p(0x02, 0xA1);	/* 8259A-2 is a slave on master's IR2 */
 	outb_p(0x01, 0xA1);	/* (slave's support for AEOI in flat mode
 				    is to be investigated) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/init_task.c linux/arch/mips/kernel/init_task.c
--- linux.orig/arch/mips/kernel/init_task.c	2001-09-17 22:29:09.000000000 +0000
+++ linux/arch/mips/kernel/init_task.c	2002-07-20 01:08:29.000000000 +0000
@@ -20,5 +20,5 @@
  * The things we do for performance..
  */
 union task_union init_task_union
-	__attribute__((__section__(".text"))) =
+	__attribute__((__section__(".data.init_task"))) =
 		{ INIT_TASK(init_task_union.task) };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/irix5sys.h linux/arch/mips/kernel/irix5sys.h
--- linux.orig/arch/mips/kernel/irix5sys.h	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/kernel/irix5sys.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: irix5sys.h,v 1.2 1998/08/17 10:16:25 ralf Exp $
- *
+/*
  * irix5sys.h: 32-bit IRIX5 ABI system call table.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c
--- linux.orig/arch/mips/kernel/irixelf.c	2001-03-19 20:35:09.000000000 +0000
+++ linux/arch/mips/kernel/irixelf.c	2002-07-20 01:08:37.000000000 +0000
@@ -23,7 +23,6 @@
 #include <linux/string.h>
 #include <linux/file.h>
 #include <linux/fcntl.h>
-#include <linux/ptrace.h>
 #include <linux/slab.h>
 #include <linux/shm.h>
 #include <linux/personality.h>
@@ -32,6 +31,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
+#include <asm/ptrace.h>
 #include <asm/mipsregs.h>
 #include <asm/prctl.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/irixinv.c linux/arch/mips/kernel/irixinv.c
--- linux.orig/arch/mips/kernel/irixinv.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/kernel/irixinv.c	2002-07-20 01:08:24.000000000 +0000
@@ -4,8 +4,6 @@
  * use the linked lists for the inventory yet. 
  *
  * Miguel de Icaza, 1997.
- *
- * $Id: irixinv.c,v 1.3 1998/04/05 11:23:51 ralf Exp $
  */
 #include <linux/mm.h>
 #include <linux/init.h>
@@ -79,3 +77,5 @@
 	add_to_inventory (2, 2, 0, 1, 0);
 	add_to_inventory (7, 14, 0, 0, 6);
 }
+
+module_init(init_inventory);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c
--- linux.orig/arch/mips/kernel/irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/irq.c	2002-07-20 01:08:26.000000000 +0000
@@ -8,17 +8,22 @@
  * Copyright (C) 1992 Linus Torvalds
  * Copyright (C) 1994 - 2000 Ralf Baechle
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
-#include <linux/irq.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/random.h>
 #include <linux/sched.h>
 
+#include <asm/atomic.h>
 #include <asm/system.h>
+#include <asm/uaccess.h>
 
 /*
  * Controller mappings for all interrupt sources:
@@ -63,7 +68,7 @@
 	end_none
 };
 
-volatile unsigned long irq_err_count, spurious_count;
+atomic_t irq_err_count;
 
 /*
  * Generic, controller-independent functions:
@@ -71,13 +76,13 @@
 
 int get_irq_list(char *buf)
 {
+	int i, j;
 	struct irqaction * action;
 	char *p = buf;
-	int i;
 
 	p += sprintf(p, "           ");
-	for (i=0; i < 1 /*smp_num_cpus*/; i++)
-		p += sprintf(p, "CPU%d       ", i);
+	for (j=0; j<smp_num_cpus; j++)
+		p += sprintf(p, "CPU%d       ",j);
 	*p++ = '\n';
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
@@ -85,7 +90,13 @@
 		if (!action) 
 			continue;
 		p += sprintf(p, "%3d: ",i);
+#ifndef CONFIG_SMP
 		p += sprintf(p, "%10u ", kstat_irqs(i));
+#else
+		for (j = 0; j < smp_num_cpus; j++)
+			p += sprintf(p, "%10u ",
+				kstat.irqs[cpu_logical_map(j)][i]);
+#endif
 		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
 		p += sprintf(p, "  %s", action->name);
 
@@ -93,10 +104,182 @@
 			p += sprintf(p, ", %s", action->name);
 		*p++ = '\n';
 	}
-	p += sprintf(p, "ERR: %10lu\n", irq_err_count);
+	p += sprintf(p, "\n");
+	p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
 	return p - buf;
 }
 
+#ifdef CONFIG_SMP
+int global_irq_holder = NO_PROC_ID;
+spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Most of this code is take from the mips64 tree (ip27-irq.c).  It's virtually
+ * identical to the i386 implentation in arh/i386/irq.c, with translations for
+ * the interrupt enable bit
+ */
+
+#define MAXCOUNT 		100000000
+#define SYNC_OTHER_CORES(x)	udelay(x+1)
+
+static inline void wait_on_irq(int cpu)
+{
+	int count = MAXCOUNT;
+
+	for (;;) {
+
+		/*
+		 * Wait until all interrupts are gone. Wait
+		 * for bottom half handlers unless we're
+		 * already executing in one..
+		 */
+		if (!irqs_running())
+			if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
+				break;
+
+		/* Duh, we have to loop. Release the lock to avoid deadlocks */
+		spin_unlock(&global_irq_lock);
+
+		for (;;) {
+			if (!--count) {
+				printk("Count spun out.  Huh?\n");
+				count = ~0;
+			}
+			__sti();
+			SYNC_OTHER_CORES(cpu);
+			__cli();
+			if (irqs_running())
+				continue;
+			if (spin_is_locked(&global_irq_lock))
+				continue;
+			if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
+				continue;
+			if (spin_trylock(&global_irq_lock))
+				break;
+		}
+	}
+}
+
+/*
+ * This is called when we want to synchronize with
+ * interrupts. We may for example tell a device to
+ * stop sending interrupts: but to make sure there
+ * are no interrupts that are executing on another
+ * CPU we need to call this function.
+ */
+void synchronize_irq(void)
+{
+	if (irqs_running()) {
+		/* Stupid approach */
+		cli();
+		sti();
+	}
+}
+
+static inline void get_irqlock(int cpu)
+{
+	if (!spin_trylock(&global_irq_lock)) {
+		/* do we already hold the lock? */
+		if ((unsigned char) cpu == global_irq_holder)
+			return;
+		/* Uhhuh.. Somebody else got it. Wait.. */
+		spin_lock(&global_irq_lock);
+	}
+	/*
+	 * We also to make sure that nobody else is running
+	 * in an interrupt context.
+	 */
+	wait_on_irq(cpu);
+
+	/*
+	 * Ok, finally..
+	 */
+	global_irq_holder = cpu;
+}
+
+/*
+ * A global "cli()" while in an interrupt context turns into just a local 
+ * cli(). Interrupts should use spinlocks for the (very unlikely) case that 
+ * they ever want to protect against each other.
+ * 
+ * If we already have local interrupts disabled, this will not turn a local 
+ * disable into a global one (problems with spinlocks: this makes 
+ * save_flags+cli+sti usable inside a spinlock).
+ */
+
+void __global_cli(void)
+{
+	unsigned int flags;
+
+	__save_flags(flags);
+	if (flags & ST0_IE) {
+		int cpu = smp_processor_id();
+		__cli();
+		if (!local_irq_count(cpu))
+			get_irqlock(cpu);
+	}
+}
+
+void __global_sti(void)
+{
+	int cpu = smp_processor_id();
+
+	if (!local_irq_count(cpu))
+		release_irqlock(cpu);
+	__sti();
+}
+
+/*
+ * SMP flags value to restore to:
+ * 0 - global cli
+ * 1 - global sti
+ * 2 - local cli
+ * 3 - local sti
+ */
+unsigned long __global_save_flags(void)
+{
+	int retval;
+	int local_enabled;
+	unsigned long flags;
+	int cpu = smp_processor_id();
+
+	__save_flags(flags);
+	local_enabled = (flags & ST0_IE);
+	/* default to local */
+	retval = 2 + local_enabled;
+
+	/* check for global flags if we're not in an interrupt */
+	if (!local_irq_count(cpu)) {
+		if (local_enabled)
+			retval = 1;
+		if (global_irq_holder == cpu)
+			retval = 0;
+	}
+
+	return retval;
+}
+
+void __global_restore_flags(unsigned long flags)
+{
+	switch (flags) {
+		case 0:
+			__global_cli();
+			break;
+		case 1:
+			__global_sti();
+			break;
+		case 2:
+			__cli();
+			break;
+		case 3:
+			__sti();
+			break;
+		default:
+			printk("global_restore_flags: %08lx\n", flags);
+	}
+}
+#endif /* CONFIG_SMP */
+
 /*
  * This should really return information about whether
  * we should do bottom half handling etc. Right now we
@@ -690,7 +873,7 @@
 	}
 	spin_unlock_irqrestore(&desc->lock,flags);
 
-	/* register_irq_proc(irq); */
+	register_irq_proc(irq);
 	return 0;
 }
 
@@ -705,3 +888,176 @@
 		irq_desc[i].handler = &no_irq_type;
 	}
 }
+
+EXPORT_SYMBOL(disable_irq_nosync);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(probe_irq_mask);
+
+static struct proc_dir_entry * root_irq_dir;
+static struct proc_dir_entry * irq_dir [NR_IRQS];
+
+#define HEX_DIGITS 8
+
+static unsigned int parse_hex_value (const char *buffer,
+		unsigned long count, unsigned long *ret)
+{
+	unsigned char hexnum [HEX_DIGITS];
+	unsigned long value;
+	int i;
+
+	if (!count)
+		return -EINVAL;
+	if (count > HEX_DIGITS)
+		count = HEX_DIGITS;
+	if (copy_from_user(hexnum, buffer, count))
+		return -EFAULT;
+
+	/*
+	 * Parse the first 8 characters as a hex string, any non-hex char
+	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+	 */
+	value = 0;
+
+	for (i = 0; i < count; i++) {
+		unsigned int c = hexnum[i];
+
+		switch (c) {
+			case '0' ... '9': c -= '0'; break;
+			case 'a' ... 'f': c -= 'a'-10; break;
+			case 'A' ... 'F': c -= 'A'-10; break;
+		default:
+			goto out;
+		}
+		value = (value << 4) | c;
+	}
+out:
+	*ret = value;
+	return 0;
+}
+
+#if CONFIG_SMP
+
+static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+
+static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
+static int irq_affinity_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
+}
+
+static int irq_affinity_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	int irq = (long) data, full_count = count, err;
+	unsigned long new_value;
+
+	if (!irq_desc[irq].handler->set_affinity)
+		return -EIO;
+
+	err = parse_hex_value(buffer, count, &new_value);
+
+	/*
+	 * Do not allow disabling IRQs completely - it's a too easy
+	 * way to make the system unusable accidentally :-) At least
+	 * one online CPU still has to be targeted.
+	 */
+	if (!(new_value & cpu_online_map))
+		return -EINVAL;
+
+	irq_affinity[irq] = new_value;
+	irq_desc[irq].handler->set_affinity(irq, new_value);
+
+	return full_count;
+}
+
+#endif
+
+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	unsigned long *mask = (unsigned long *) data;
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", *mask);
+}
+
+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	unsigned long *mask = (unsigned long *) data, full_count = count, err;
+	unsigned long new_value;
+
+	err = parse_hex_value(buffer, count, &new_value);
+	if (err)
+		return err;
+
+	*mask = new_value;
+	return full_count;
+}
+
+#define MAX_NAMELEN 10
+
+static void register_irq_proc (unsigned int irq)
+{
+	char name [MAX_NAMELEN];
+
+	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
+			irq_dir[irq])
+		return;
+
+	memset(name, 0, MAX_NAMELEN);
+	sprintf(name, "%d", irq);
+
+	/* create /proc/irq/1234 */
+	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+
+#if CONFIG_SMP
+	{
+		struct proc_dir_entry *entry;
+
+		/* create /proc/irq/1234/smp_affinity */
+		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
+
+		if (entry) {
+			entry->nlink = 1;
+			entry->data = (void *)(long)irq;
+			entry->read_proc = irq_affinity_read_proc;
+			entry->write_proc = irq_affinity_write_proc;
+		}
+
+		smp_affinity_entry[irq] = entry;
+	}
+#endif
+}
+
+unsigned long prof_cpu_mask = -1;
+
+void init_irq_proc (void)
+{
+	struct proc_dir_entry *entry;
+	int i;
+
+	/* create /proc/irq */
+	root_irq_dir = proc_mkdir("irq", 0);
+
+	/* create /proc/irq/prof_cpu_mask */
+	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
+
+	if (!entry)
+	    return;
+
+	entry->nlink = 1;
+	entry->data = (void *)&prof_cpu_mask;
+	entry->read_proc = prof_cpu_mask_read_proc;
+	entry->write_proc = prof_cpu_mask_write_proc;
+
+	/*
+	 * Create entries for all existing IRQs.
+	 */
+	for (i = 0; i < NR_IRQS; i++)
+		register_irq_proc(i);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/irq_cpu.c linux/arch/mips/kernel/irq_cpu.c
--- linux.orig/arch/mips/kernel/irq_cpu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/kernel/irq_cpu.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This file define the irq handler for MIPS CPU interrupts.
+ *
+ * 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.
+ */
+
+/*
+ * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
+ * level triggered (i.e., cannot be cleared from CPU; must be cleared from
+ * device).  The first two are software interrupts.  The last one is 
+ * usually the CPU timer interrupt if counter register is present or, for
+ * CPUs with an external FPU, by convention it's the FPU exception interrupt.
+ *
+ * This file exports one global function:
+ *	void mips_cpu_irq_init(int irq_base);
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+static int mips_cpu_irq_base = -1;
+
+static void mips_cpu_irq_enable(unsigned int irq)
+{
+	clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8));
+	set_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+}
+
+static void mips_cpu_irq_disable(unsigned int irq)
+{
+	clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+}
+
+static unsigned int mips_cpu_irq_startup(unsigned int irq)
+{
+	mips_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
+
+static void mips_cpu_irq_ack(unsigned int irq)
+{
+	/* although we attemp to clear the IP bit in cause reigster, I think
+	 * usually it is cleared by device (irq source)
+	 */
+	clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8));
+
+	/* disable this interrupt - so that we safe proceed to the handler */
+	mips_cpu_irq_disable(irq);
+}
+
+static void mips_cpu_irq_end(unsigned int irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		mips_cpu_irq_enable(irq);
+}
+
+static hw_irq_controller mips_cpu_irq_controller = {
+	"MIPS",
+	mips_cpu_irq_startup,
+	mips_cpu_irq_shutdown,
+	mips_cpu_irq_enable,
+	mips_cpu_irq_disable,
+	mips_cpu_irq_ack,
+	mips_cpu_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+
+void __init mips_cpu_irq_init(int irq_base)
+{
+	int i;
+
+	for (i = irq_base; i < irq_base + 8; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &mips_cpu_irq_controller;
+	}
+
+	mips_cpu_irq_base = irq_base;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/mips_ksyms.c linux/arch/mips/kernel/mips_ksyms.c
--- linux.orig/arch/mips/kernel/mips_ksyms.c	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/mips/kernel/mips_ksyms.c	2002-07-20 01:08:28.000000000 +0000
@@ -25,6 +25,7 @@
 #include <asm/pgalloc.h>
 #include <asm/semaphore.h>
 #include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgimc.h>
 #include <asm/softirq.h>
 #include <asm/uaccess.h>
 #ifdef CONFIG_BLK_DEV_FD
@@ -62,8 +63,6 @@
 EXPORT_SYMBOL_NOVERS(strtok);
 
 EXPORT_SYMBOL(_clear_page);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(kernel_thread);
 
 /*
@@ -87,8 +86,6 @@
  */
 EXPORT_SYMBOL(_flush_page_to_ram);
 EXPORT_SYMBOL(_flush_cache_all);
-EXPORT_SYMBOL(_dma_cache_wback_inv);
-EXPORT_SYMBOL(_dma_cache_inv);
 
 EXPORT_SYMBOL(invalid_pte_table);
 
@@ -101,11 +98,6 @@
 EXPORT_SYMBOL(__up);
 
 /*
- * Base address of ports for Intel style I/O.
- */
-EXPORT_SYMBOL(mips_io_port_base);
-
-/*
  * Architecture specific stuff.
  */
 #ifdef CONFIG_MIPS_JAZZ
@@ -116,6 +108,8 @@
 
 #ifdef CONFIG_SGI_IP22
 EXPORT_SYMBOL(hpc3c0);
+EXPORT_SYMBOL(hpc3c1);
+EXPORT_SYMBOL(mcmisc_regs);
 #endif
 
 /*
@@ -124,9 +118,6 @@
 #include <asm/branch.h>
 #include <linux/sched.h>
 
-int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
-int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
-
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
@@ -136,4 +127,3 @@
 #endif
 
 EXPORT_SYMBOL(get_wchan);
-EXPORT_SYMBOL(flush_tlb_page);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/old-irq.c linux/arch/mips/kernel/old-irq.c
--- linux.orig/arch/mips/kernel/old-irq.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/old-irq.c	2002-07-20 01:08:37.000000000 +0000
@@ -69,7 +69,7 @@
 #define cached_21       (__byte(0,cached_irq_mask))
 #define cached_A1       (__byte(1,cached_irq_mask))
 
-unsigned long spurious_count = 0;
+volatile unsigned long irq_err_count;
 
 /*
  * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and
@@ -403,3 +403,6 @@
 	/* i8259_init(); */
 	irq_setup();
 }
+
+EXPORT_SYMBOL(free_irq);
+EXPORT_SYMBOL(request_irq);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/old-time.c linux/arch/mips/kernel/old-time.c
--- linux.orig/arch/mips/kernel/old-time.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/old-time.c	2002-07-20 01:08:27.000000000 +0000
@@ -89,8 +89,7 @@
 			:"r" (timerhi),
 			 "m" (timerlo),
 			 "r" (tmp),
-			 "r" (USECS_PER_JIFFY)
-			:"$1");
+			 "r" (USECS_PER_JIFFY));
 		cached_quotient = quotient;
 	}
 
@@ -389,15 +388,19 @@
 	    xtime.tv_sec > last_rtc_update + 660 &&
 	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
 	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
-	  if (set_rtc_mmss(xtime.tv_sec) == 0)
-	    last_rtc_update = xtime.tv_sec;
-	  else
-	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			/* do it again in 60 s */
+			last_rtc_update = xtime.tv_sec - 600;
 	}
-	/* As we return to user mode fire off the other CPU schedulers.. this is 
-	   basically because we don't yet share IRQ's around. This message is
-	   rigged to be safe on the 386 - basically it's a hack, so don't look
-	   closely for now.. */
+
+	/*
+	 * As we return to user mode fire off the other CPU schedulers.. this
+	 * is basically because we don't yet share IRQ's around. This message
+	 * is rigged to be safe on the 386 - basically it's a hack, so don't
+	 * look closely for now..
+	 */
 	/*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
 	read_unlock (&xtime_lock); 
 }
@@ -442,10 +445,12 @@
 
 void indy_r4k_timer_interrupt (struct pt_regs *regs)
 {
-	static const int INDY_R4K_TIMER_IRQ = 7;
 	int cpu = smp_processor_id();
+	int irq = 7;
 
-	r4k_timer_interrupt (INDY_R4K_TIMER_IRQ, NULL, regs);
+	irq_enter(cpu, irq);
+	r4k_timer_interrupt(irq, NULL, regs);
+	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
 		do_softirq();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/pci-dma.c linux/arch/mips/kernel/pci-dma.c
--- linux.orig/arch/mips/kernel/pci-dma.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/pci-dma.c	2002-07-20 01:08:25.000000000 +0000
@@ -10,6 +10,7 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/pci.h>
 
@@ -27,7 +28,7 @@
 
 	if (ret != NULL) {
 		memset(ret, 0, size);
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 		dma_cache_wback_inv((unsigned long) ret, size);
 		ret = KSEG1ADDR(ret);
 #endif
@@ -42,8 +43,11 @@
 {
 	unsigned long addr = (unsigned long) vaddr;
 
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	addr = KSEG0ADDR(addr);
 #endif
 	free_pages(addr, get_order(size));
 }
+
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/pci.c linux/arch/mips/kernel/pci.c
--- linux.orig/arch/mips/kernel/pci.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/pci.c	2002-07-20 01:08:27.000000000 +0000
@@ -55,6 +55,7 @@
  *		Dave Rusling david.rusling@reo.mts.dec.com
  *		David Mosberger davidm@cs.arizona.edu
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/pci_auto.c linux/arch/mips/kernel/pci_auto.c
--- linux.orig/arch/mips/kernel/pci_auto.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/pci_auto.c	2002-07-20 01:08:40.000000000 +0000
@@ -4,6 +4,7 @@
  * Author: Matt Porter <mporter@mvista.com>
  *
  * Copyright 2000, 2001 MontaVista Software Inc.
+ * Copyright 2001 Bradley D. LaRonde <brad@ltc.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
@@ -19,6 +20,15 @@
  * . change most int to u32.
  *
  * Further modified to include it as mips generic code, ppopov@mvista.com.
+ *
+ * 2001-10-26  Bradley D. LaRonde <brad@ltc.com>
+ * - Add a top_bus argument to the "early config" functions so that
+ *   they can set a fake parent bus pointer to convince the underlying
+ *   pci ops to use type 1 configuration for sub busses.
+ * - Set bridge base and limit registers correctly.
+ * - Align io and memory base properly before and after bridge setup.
+ * - Don't fall through to pci_setup_bars for bridge.
+ * - Reformat the debug output to look more like lspci's output.
  */
 
 #include <linux/kernel.h>
@@ -35,13 +45,49 @@
 #define	DBG(x...)	
 #endif
 
-/* These are used for config access before all the PCI probing has been done. */
-int early_read_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 *val);
-int early_read_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 *val);
-int early_read_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 *val);
-int early_write_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 val);
-int early_write_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 val);
-int early_write_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 val);
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
+	int top_bus, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose->pci_ops;
+
+	if(busnr != top_bus)
+		/* Fake a parent bus structure. */
+		bus.parent = &bus;
+	else
+		bus.parent = NULL;
+
+	return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_channel *hose,		\
+	int top_bus, int bus, int devfn, int offset, type value)	\
+{									\
+	return pci_##rw##_config_##size(				\
+		fake_pci_dev(hose, top_bus, bus, devfn),		\
+		offset, value);						\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+static struct resource *io_resource_inuse;
+static struct resource *mem_resource_inuse;
 
 static u32 pciauto_lower_iospc;
 static u32 pciauto_upper_iospc;
@@ -51,6 +97,7 @@
 
 void __init 
 pciauto_setup_bars(struct pci_channel *hose,
+		   int top_bus,
 		   int current_bus,
 		   int pci_devfn)
 {
@@ -60,17 +107,14 @@
 	u32 * lower_limit;
 	int found_mem64 = 0;
 
-	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
-	    current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
-
 	for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4) {
 		/* Tickle the BAR and get the response */
-		early_write_config_dword(hose,
+		early_write_config_dword(hose, top_bus,
 					 current_bus,
 					 pci_devfn,
 					 bar,
 					 0xffffffff);
-		early_read_config_dword(hose,
+		early_read_config_dword(hose, top_bus,
 					current_bus,
 					pci_devfn,
 					bar,
@@ -80,12 +124,21 @@
 		if (!bar_response)
 			continue;
 
+		/*
+		 * Workaround for a BAR that doesn't use its upper word,
+		 * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457).
+		 * bdl <brad@ltc.com>
+		 */
+		if (!(bar_response & 0xffff0000))
+			bar_response |= 0xffff0000;
+
+retry:
 		/* Check the BAR type and set our address mask */
 		if (bar_response & PCI_BASE_ADDRESS_SPACE) {
 			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
 			upper_limit = &pciauto_upper_iospc;
 			lower_limit = &pciauto_lower_iospc;
-			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+			DBG("        I/O");
 		} else {
 			if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
 			    PCI_BASE_ADDRESS_MEM_TYPE_64)
@@ -94,17 +147,45 @@
 			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
 			upper_limit = &pciauto_upper_memspc;
 			lower_limit = &pciauto_lower_memspc;
-			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+			DBG("        Mem");
 		}
 
+
 		/* Calculate requested size */
 		bar_size = ~(bar_response & addr_mask) + 1;
 
 		/* Allocate a base address */
 		bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
 
+		if ((bar_value + bar_size) > *upper_limit) {
+			if (bar_response & PCI_BASE_ADDRESS_SPACE) {
+				if (io_resource_inuse->child) {
+					io_resource_inuse = 
+						io_resource_inuse->child;
+					pciauto_lower_iospc = 
+						io_resource_inuse->start;
+					pciauto_upper_iospc = 
+						io_resource_inuse->end + 1;
+					goto retry;
+				}
+
+			} else {
+				if (mem_resource_inuse->child) {
+					mem_resource_inuse = 
+						mem_resource_inuse->child;
+					pciauto_lower_memspc = 
+						mem_resource_inuse->start;
+					pciauto_upper_memspc = 
+						mem_resource_inuse->end + 1;
+					goto retry;
+				}
+			}
+			DBG(" unavailable -- skipping\n");
+			continue;
+		}
+
 		/* Write it out and update our limit */
-		early_write_config_dword(hose, current_bus, pci_devfn,
+		early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
 					 bar, bar_value);
 
 		*lower_limit = bar_value + bar_size;
@@ -116,97 +197,99 @@
 		 */ 
 		if (found_mem64) {
 			bar += 4;
-			early_write_config_dword(hose,
+			early_write_config_dword(hose, top_bus,
 						 current_bus,
 						 pci_devfn,
 						 bar,
 						 0x00000000);
 		}
 
-		bar_nr++;
+		DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size);
 
-		DBG("size=0x%x, address=0x%x\n",
-		    bar_size, bar_value);
+		bar_nr++;
 	}
 
 }
 
 void __init
 pciauto_prescan_setup_bridge(struct pci_channel *hose,
+			     int top_bus,
 			     int current_bus,
 			     int pci_devfn,
 			     int sub_bus)
 {
-	int cmdstat;
-
 	/* Configure bus number registers */
-	early_write_config_byte(hose, current_bus, pci_devfn,
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
 	                        PCI_PRIMARY_BUS, current_bus);
-	early_write_config_byte(hose, current_bus, pci_devfn,
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
 				PCI_SECONDARY_BUS, sub_bus + 1);
-	early_write_config_byte(hose, current_bus, pci_devfn,
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
 				PCI_SUBORDINATE_BUS, 0xff);
 
-	/* Round memory allocator to 1MB boundary */
-	pciauto_upper_memspc &= ~(0x100000 - 1);
+	/* Align memory and I/O to 1MB and 4KB boundaries. */
+	pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
+		& ~(0x100000 - 1);
+	pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
+		& ~(0x1000 - 1);
+
+	/* Set base (lower limit) of address range behind bridge. */
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+		PCI_MEMORY_BASE, pciauto_lower_memspc >> 16);
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+		PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+		PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16);
 
-	/* Round I/O allocator to 4KB boundary */
-	pciauto_upper_iospc &= ~(0x1000 - 1);
-
-	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
-	early_write_config_word(hose, current_bus, pci_devfn, PCI_MEMORY_LIMIT,
-				((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
-	early_write_config_byte(hose, current_bus, pci_devfn, PCI_IO_LIMIT,
-				((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
-	early_write_config_word(hose, current_bus, pci_devfn,
-				PCI_IO_LIMIT_UPPER16,
-				((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
-			
 	/* We don't support prefetchable memory for now, so disable */
-	early_write_config_word(hose, current_bus, pci_devfn,
-				PCI_PREF_MEMORY_BASE, 0x1000);
-	early_write_config_word(hose, current_bus, pci_devfn,
-				PCI_PREF_MEMORY_LIMIT, 0x1000);
-
-	/* Enable memory and I/O accesses, enable bus master */
-	early_read_config_dword(hose, current_bus, pci_devfn, PCI_COMMAND,
-				&cmdstat);
-	early_write_config_dword(hose, current_bus, pci_devfn, PCI_COMMAND,
-				 cmdstat | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-				 PCI_COMMAND_MASTER);
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+				PCI_PREF_MEMORY_BASE, 0);
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+				PCI_PREF_MEMORY_LIMIT, 0);
 }
 
 void __init
 pciauto_postscan_setup_bridge(struct pci_channel *hose,
+			      int top_bus,
 			      int current_bus,
 			      int pci_devfn,
 			      int sub_bus)
 {
+	u32 temp;
+
 	/* Configure bus number registers */
-	early_write_config_byte(hose, current_bus, pci_devfn,
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
 				PCI_SUBORDINATE_BUS, sub_bus);
 
-	/* Round memory allocator to 1MB boundary */
-	pciauto_upper_memspc &= ~(0x100000 - 1);
-	early_write_config_word(hose, current_bus, pci_devfn, PCI_MEMORY_BASE,
-				pciauto_upper_memspc >> 16);
-
-	/* Round I/O allocator to 4KB boundary */
-	pciauto_upper_iospc &= ~(0x1000 - 1);
-	early_write_config_byte(hose, current_bus, pci_devfn, PCI_IO_BASE,
-				(pciauto_upper_iospc & 0x0000f000) >> 8);
-	early_write_config_word(hose, current_bus, pci_devfn,
-				PCI_IO_BASE_UPPER16, pciauto_upper_iospc >> 16);
+	/* Set upper limit of address range behind bridge. */
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+		PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16);
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+		PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+		PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16);
+
+	/* Align memory and I/O to 1MB and 4KB boundaries. */
+	pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
+		& ~(0x100000 - 1);
+	pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
+		& ~(0x1000 - 1);
+
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_COMMAND, &temp);
+	early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY
+		| PCI_COMMAND_MASTER);
 }
 
 #define      PCIAUTO_IDE_MODE_MASK           0x05
 
 int __init
-pciauto_bus_scan(struct pci_channel *hose, int current_bus)
+pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
 {
 	int sub_bus;
 	u32 pci_devfn, pci_class, cmdstat, found_multi=0;
-	unsigned short vid;
+	unsigned short vid, did;
 	unsigned char header_type;
 	int devfn_start = 0;
 	int devfn_stop = 0xff;
@@ -223,54 +306,70 @@
 		if (PCI_FUNC(pci_devfn) && !found_multi)
 			continue;
 
-		early_read_config_byte(hose, current_bus, pci_devfn,
+		early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+				       PCI_VENDOR_ID, &vid);
+
+		if (vid == 0xffff) continue;
+
+		early_read_config_byte(hose, top_bus, current_bus, pci_devfn,
 				       PCI_HEADER_TYPE, &header_type);
 
 		if (!PCI_FUNC(pci_devfn))
 			found_multi = header_type & 0x80;
 
-		early_read_config_word(hose, current_bus, pci_devfn,
-				       PCI_VENDOR_ID, &vid);
-
-		if (vid == 0xffff) continue;
+		early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+				       PCI_DEVICE_ID, &did);
 
-		early_read_config_dword(hose, current_bus, pci_devfn,
+		early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
 					PCI_CLASS_REVISION, &pci_class);
+
+		DBG("%.2x:%.2x.%x Class %.4x: %.4x:%.4x",
+			current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn),
+			pci_class >> 16, vid, did);
+		if (pci_class & 0xff)
+			DBG(" (rev %.2x)", pci_class & 0xff);
+		DBG("\n");
+
 		if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
-			DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
-			pciauto_prescan_setup_bridge(hose, current_bus,
+			DBG("        Bridge: primary=%.2x, secondary=%.2x\n",
+				current_bus, sub_bus + 1);
+			pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
 						     pci_devfn, sub_bus);
-			sub_bus = pciauto_bus_scan(hose, sub_bus+1);
-			pciauto_postscan_setup_bridge(hose, current_bus,
+			DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
+				sub_bus + 1,
+				pciauto_lower_iospc, pciauto_lower_memspc);
+			sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
+			DBG("Back to bus %.2x\n", current_bus);
+			pciauto_postscan_setup_bridge(hose, top_bus, current_bus,
 						      pci_devfn, sub_bus);
-
+			continue;
 		} else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
 
 			unsigned char prg_iface;
 
-			early_read_config_byte(hose, current_bus, pci_devfn,
-					       PCI_CLASS_PROG, &prg_iface);
+			early_read_config_byte(hose, top_bus, current_bus,
+				pci_devfn, PCI_CLASS_PROG, &prg_iface);
 			if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
-				DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+				DBG("Skipping legacy mode IDE controller\n");
 				continue;
 			}
 		}
 
-		/*
+ 		/*
 		 * Found a peripheral, enable some standard
 		 * settings
 		 */
-		early_read_config_dword(hose, current_bus, pci_devfn,
+		early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
 					PCI_COMMAND, &cmdstat);
-		early_write_config_dword(hose, current_bus, pci_devfn,
+		early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
 					 PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
 					 PCI_COMMAND_MEMORY |
 					 PCI_COMMAND_MASTER);
-		early_write_config_byte(hose, current_bus, pci_devfn,
+		early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
 					PCI_LATENCY_TIMER, 0x80);
 
 		/* Allocate PCI I/O and/or memory space */
-		pciauto_setup_bars(hose, current_bus, pci_devfn);
+		pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn);
 	}
 	return sub_bus;
 }
@@ -279,45 +378,17 @@
 pciauto_assign_resources(int busno, struct pci_channel *hose)
 {
 	/* setup resource limits */
-	pciauto_lower_iospc = hose->io_resource->start;
-	pciauto_upper_iospc = hose->io_resource->end + 1;
-	pciauto_lower_memspc = hose->mem_resource->start;
-	pciauto_upper_memspc = hose->mem_resource->end + 1;
-
-	return pciauto_bus_scan(hose, busno);
-}
-
-
-/*
- * These functions are used early on before PCI scanning is done
- * and all of the pci_dev and pci_bus structures have been created.
- */
-static struct pci_dev *fake_pci_dev(struct pci_channel *hose, int busnr,
-                                    int devfn)
-{
-	static struct pci_dev dev;
-	static struct pci_bus bus;
-
-	dev.bus = &bus;
-	dev.sysdata = hose;
-	dev.devfn = devfn;
-	bus.number = busnr;
-	bus.ops = hose->pci_ops;
+	io_resource_inuse = hose->io_resource;
+	mem_resource_inuse = hose->mem_resource;
 
-	return &dev;
-}
+	pciauto_lower_iospc = io_resource_inuse->start;
+	pciauto_upper_iospc = io_resource_inuse->end + 1;
+	pciauto_lower_memspc = mem_resource_inuse->start;
+	pciauto_upper_memspc = mem_resource_inuse->end + 1;
+	DBG("Autoconfig PCI channel 0x%p\n", hose);
+	DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n",
+		busno, pciauto_lower_iospc, pciauto_upper_iospc, 
+		pciauto_lower_memspc, pciauto_upper_memspc);
 
-#define EARLY_PCI_OP(rw, size, type)					\
-int early_##rw##_config_##size(struct pci_channel *hose, int bus,	\
-                               int devfn, int offset, type value)	\
-{									\
-	return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),	\
-	                                offset, value);			\
+	return pciauto_bus_scan(hose, busno, busno);
 }
-
-EARLY_PCI_OP(read, byte, u8 *)
-EARLY_PCI_OP(read, word, u16 *)
-EARLY_PCI_OP(read, dword, u32 *)
-EARLY_PCI_OP(write, byte, u8)
-EARLY_PCI_OP(write, word, u16)
-EARLY_PCI_OP(write, dword, u32)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/proc.c linux/arch/mips/kernel/proc.c
--- linux.orig/arch/mips/kernel/proc.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/proc.c	2002-07-20 01:08:29.000000000 +0000
@@ -8,102 +8,139 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
 #include <asm/watch.h>
 
-extern unsigned long unaligned_instructions;
 unsigned int vced_count, vcei_count;
+
 #ifndef CONFIG_CPU_HAS_LLSC
 unsigned long ll_ops, sc_ops;
 #endif
 
-/*
- * BUFFER is PAGE_SIZE bytes long.
- *
- * Currently /proc/cpuinfo is being abused to print data about the
- * number of date/instruction cacheflushes.
- */
-int get_cpuinfo(char *buffer)
+static const char *cpu_name[] = {
+	[CPU_UNKNOWN]	"unknown",
+	[CPU_R2000]	"R2000",
+	[CPU_R3000]	"R3000",
+	[CPU_R3000A]	"R3000A",
+	[CPU_R3041]	"R3041",
+	[CPU_R3051]	"R3051",
+	[CPU_R3052]	"R3052",
+	[CPU_R3081]	"R3081",
+	[CPU_R3081E]	"R3081E",
+	[CPU_R4000PC]	"R4000PC",
+	[CPU_R4000SC]	"R4000SC",
+	[CPU_R4000MC]	"R4000MC",
+        [CPU_R4200]	"R4200",
+	[CPU_R4400PC]	"R4400PC",
+	[CPU_R4400SC]	"R4400SC",
+	[CPU_R4400MC]	"R4400MC",
+	[CPU_R4600]	"R4600",
+	[CPU_R6000]	"R6000",
+        [CPU_R6000A]	"R6000A",
+	[CPU_R8000]	"R8000",
+	[CPU_R10000]	"R10000",
+	[CPU_R4300]	"R4300",
+	[CPU_R4650]	"R4650",
+	[CPU_R4700]	"R4700",
+	[CPU_R5000]	"R5000",
+        [CPU_R5000A]	"R5000A",
+	[CPU_R4640]	"R4640",
+	[CPU_NEVADA]	"Nevada",
+	[CPU_RM7000]	"RM7000",
+	[CPU_R5432]	"R5432",
+	[CPU_4KC]	"MIPS 4Kc",
+        [CPU_5KC]	"MIPS 5Kc",
+	[CPU_R4310]	"R4310",
+	[CPU_SB1]	"SiByte SB1",
+	[CPU_TX3912]	"TX3912",
+	[CPU_TX3922]	"TX3922",
+	[CPU_TX3927]	"TX3927",
+	[CPU_AU1000]	"Au1000",
+	[CPU_AU1500]	"Au1500",
+	[CPU_4KEC]	"MIPS 4KEc",
+	[CPU_4KSC]	"MIPS 4KSc",
+	[CPU_VR41XX]	"NEC Vr41xx",
+	[CPU_R5500]	"R5500",
+	[CPU_TX49XX]	"TX49xx",
+	[CPU_TX39XX]	"TX39xx",
+	[CPU_20KC]	"MIPS 20Kc"
+};
+
+
+static int show_cpuinfo(struct seq_file *m, void *v)
 {
+	unsigned int version = mips_cpu.processor_id;
+	unsigned int fp_vers = mips_cpu.fpu_id;
+	unsigned long n = (unsigned long) v - 1;
 	char fmt [64];
-	const char *cpu_name[] = CPU_NAMES;
-	const char *mach_group_names[] = GROUP_NAMES;
-	const char *mach_unknown_names[] = GROUP_UNKNOWN_NAMES;
-	const char *mach_jazz_names[] = GROUP_JAZZ_NAMES;
-	const char *mach_dec_names[] = GROUP_DEC_NAMES;
-	const char *mach_arc_names[] = GROUP_ARC_NAMES;
-	const char *mach_sni_rm_names[] = GROUP_SNI_RM_NAMES;
-	const char *mach_acn_names[] = GROUP_ACN_NAMES;
-	const char *mach_sgi_names[] = GROUP_SGI_NAMES;
-	const char *mach_cobalt_names[] = GROUP_COBALT_NAMES;
-	const char *mach_nec_ddb_names[] = GROUP_NEC_DDB_NAMES;
-	const char *mach_baget_names[] = GROUP_BAGET_NAMES;
-	const char *mach_cosine_names[] = GROUP_COSINE_NAMES;
-	const char *mach_galileo_names[] = GROUP_GALILEO_NAMES;
-	const char *mach_momenco_names[] = GROUP_MOMENCO_NAMES;
- 	const char *mach_ite_names[] = GROUP_ITE_NAMES;
-	const char *mach_philips_names[] = GROUP_PHILIPS_NAMES;
- 	const char *mach_globespan_names[] = GROUP_GLOBESPAN_NAMES;
-	const char *mach_sibyte_names[] = GROUP_SIBYTE_NAMES;
-	const char *mach_toshiba_names[] = GROUP_TOSHIBA_NAMES;
-	const char *mach_alchemy_names[] = GROUP_ALCHEMY_NAMES;
-	const char **mach_group_to_name[] = { mach_unknown_names,
-		mach_jazz_names, mach_dec_names, mach_arc_names,
-		mach_sni_rm_names, mach_acn_names, mach_sgi_names,
-		mach_cobalt_names, mach_nec_ddb_names, mach_baget_names,
-		mach_cosine_names, mach_galileo_names, mach_momenco_names, 
-		mach_ite_names, mach_philips_names, mach_globespan_names,
-		mach_sibyte_names, mach_toshiba_names, mach_alchemy_names};
-	unsigned int version = read_32bit_cp0_register(CP0_PRID);
-	int len;
-
-	len = sprintf(buffer, "cpu\t\t\t: MIPS\n");
-	len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n",
-	               cpu_name[mips_cpu.cputype <= CPU_LAST ?
-	                        mips_cpu.cputype : CPU_UNKNOWN],
-	               (version >> 4) & 0x0f, version & 0x0f);
-	len += sprintf(buffer + len, "system type\t\t: %s %s\n",
-		       mach_group_names[mips_machgroup],
-		       mach_group_to_name[mips_machgroup][mips_machtype]);
-	len += sprintf(buffer + len, "BogoMIPS\t\t: %lu.%02lu\n",
-		       loops_per_jiffy/(500000/HZ),
-		       (loops_per_jiffy/(5000/HZ)) % 100);
 
-#if defined (__MIPSEB__)
-	len += sprintf(buffer + len, "byteorder\t\t: big endian\n");
-#endif
-#if defined (__MIPSEL__)
-	len += sprintf(buffer + len, "byteorder\t\t: little endian\n");
+#ifdef CONFIG_SMP
+	if (!CPUMASK_TSTB(cpu_online_map, n))
+		return 0;
 #endif
-	len += sprintf(buffer + len, "unaligned accesses\t: %lu\n",
-		       unaligned_instructions);
-	len += sprintf(buffer + len, "wait instruction\t: %s\n",
-	               cpu_wait ? "yes" : "no");
-	len += sprintf(buffer + len, "microsecond timers\t: %s\n",
-	               (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no");
-	len += sprintf(buffer + len, "extra interrupt vector\t: %s\n",
-	               (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no");
-	len += sprintf(buffer + len, "hardware watchpoint\t: %s\n",
-	               watch_available ? "yes" : "no");
+
+	/*
+	 * For the first processor also print the system type
+	 */
+	if (n == 0)
+		seq_printf(m, "system type\t\t: %s\n", get_system_type());
+
+	seq_printf(m, "processor\t\t: %ld\n", n);
+	sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
+	        (mips_cpu.options & MIPS_CPU_FPU) ? "  FPU V%d.%d" : "");
+	seq_printf(m, fmt, cpu_name[mips_cpu.cputype <= CPU_LAST ?
+	                            mips_cpu.cputype : CPU_UNKNOWN],
+	                           (version >> 4) & 0x0f, version & 0x0f,
+	                           (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
+	seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
+	              loops_per_jiffy / (500000/HZ),
+	              (loops_per_jiffy / (5000/HZ)) % 100);
+	seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
+	seq_printf(m, "microsecond timers\t: %s\n",
+	              (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no");
+	seq_printf(m, "tlb_entries\t\t: %d\n", mips_cpu.tlbsize);
+	seq_printf(m, "extra interrupt vector\t: %s\n",
+	              (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no");
+	seq_printf(m, "hardware watchpoint\t: %s\n",
+	              watch_available ? "yes" : "no");
 
 	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
 	        (mips_cpu.options & MIPS_CPU_VCE) ? "%d" : "not available");
-	len += sprintf(buffer + len, fmt, 'D', vced_count);
-	len += sprintf(buffer + len, fmt, 'I', vcei_count);
+	seq_printf(m, fmt, 'D', vced_count);
+	seq_printf(m, fmt, 'I', vcei_count);
 
 #ifndef CONFIG_CPU_HAS_LLSC
-	len += sprintf(buffer + len, "ll emulations\t\t: %lu\n",
-		       ll_ops);
-	len += sprintf(buffer + len, "sc emulations\t\t: %lu\n",
-		       sc_ops);
+	seq_printf(m, "ll emulations\t\t: %lu\n", ll_ops);
+	seq_printf(m, "sc emulations\t\t: %lu\n", sc_ops);
 #endif
-	return len;
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	unsigned long i = *pos;
+
+	return i < NR_CPUS ? (void *) (i + 1) : NULL;
 }
 
-void init_irq_proc(void)
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	/* Nothing, for now.  */
+	++*pos;
+	return c_start(m, pos);
 }
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c
--- linux.orig/arch/mips/kernel/process.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/process.c	2002-07-20 01:08:34.000000000 +0000
@@ -6,14 +6,13 @@
  * Copyright (C) 1994 - 2000 by Ralf Baechle and others.
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
-#include <linux/ptrace.h>
+#include <linux/personality.h>
 #include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/sys.h>
@@ -26,13 +25,13 @@
 #include <asm/system.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
-#include <asm/stackframe.h>
+#include <asm/ptrace.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/elf.h>
 #include <asm/isadep.h>
 
-void cpu_idle(void)
+ATTRIB_NORET void cpu_idle(void)
 {
 	/* endless idle loop with no priority at all */
 	current->nice = 20;
@@ -55,8 +54,8 @@
 void exit_thread(void)
 {
 	/* Forget lazy fpu state */
-	if (last_task_used_math == current) {
-		set_cp0_status(ST0_CU1);
+	if (last_task_used_math == current && mips_cpu.options & MIPS_CPU_FPU) {
+		__enable_fpu();
 		__asm__ __volatile__("cfc1\t$0,$31");
 		last_task_used_math = NULL;
 	}
@@ -65,8 +64,8 @@
 void flush_thread(void)
 {
 	/* Forget lazy fpu state */
-	if (last_task_used_math == current) {
-		set_cp0_status(ST0_CU1);
+	if (last_task_used_math == current && mips_cpu.options & MIPS_CPU_FPU) {
+		__enable_fpu();
 		__asm__ __volatile__("cfc1\t$0,$31");
 		last_task_used_math = NULL;
 	}
@@ -84,7 +83,7 @@
 
 	if (last_task_used_math == current)
 		if (mips_cpu.options & MIPS_CPU_FPU) {
-			set_cp0_status(ST0_CU1);
+			__enable_fpu();
 			save_fp(p);
 		}
 	/* set up new TSS. */
@@ -174,16 +173,15 @@
 		"1:  addiu   $sp,32           \n"
 		"    move    %0,$2            \n"
 		".set reorder"
-		:"=r" (retval)
-		:"i" (__NR_clone), "i" (__NR_exit),
-		 "r" (arg), "r" (fn),
-		 "r" (flags | CLONE_VM)
+		: "=r" (retval)
+		: "i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn),
+		  "r" (flags | CLONE_VM)
 		 /*
 		  * The called subroutine might have destroyed any of the
 		  * at, result, argument or temporary registers ...
 		  */
-		:"$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8",
-		 "$9","$10","$11","$12","$13","$14","$15","$24","$25");
+		: "$2", "$3", "$4", "$5", "$6", "$7", "$8",
+		  "$9","$10","$11","$12","$13","$14","$15","$24","$25");
 
 	return retval;
 }
@@ -196,7 +194,7 @@
 #define first_sched	((unsigned long) scheduling_functions_start_here)
 #define last_sched	((unsigned long) scheduling_functions_end_here)
 
-/* get_wchan - a maintenance nightmare ...  */
+/* get_wchan - a maintenance nightmare^W^Wpain in the ass ...  */
 unsigned long get_wchan(struct task_struct *p)
 {
 	unsigned long frame, pc;
@@ -217,26 +215,29 @@
 		goto schedule_timeout_caller;
 	if (pc >= (unsigned long)interruptible_sleep_on)
 		goto schedule_caller;
-	goto schedule_timeout_caller;
+	/* Fall through */
 
 schedule_caller:
-	frame = ((unsigned long *)p->thread.reg30)[9];
-	pc    = ((unsigned long *)frame)[11];
+	pc = ((unsigned long *)p->thread.reg30)[13];
+
 	return pc;
 
 schedule_timeout_caller:
-	/* Must be schedule_timeout ...  */
-	pc    = ((unsigned long *)p->thread.reg30)[10];
-	frame = ((unsigned long *)p->thread.reg30)[9];
-
-	/* The schedule_timeout frame ...  */
-	pc    = ((unsigned long *)frame)[14];
-	frame = ((unsigned long *)frame)[13];
+	/*
+	 * The schedule_timeout frame
+	 */
+	frame = ((unsigned long *)p->thread.reg30)[13];
+
+	/*
+	 * frame now points to sleep_on_timeout's frame
+	 */
+	frame = ((unsigned long *)frame)[9];
+	pc    = ((unsigned long *)frame)[10];
 
 	if (pc >= first_sched && pc < last_sched) {
 		/* schedule_timeout called by interruptible_sleep_on_timeout */
-		pc    = ((unsigned long *)frame)[11];
-		frame = ((unsigned long *)frame)[10];
+		frame = ((unsigned long *)frame)[9];
+		pc    = ((unsigned long *)frame)[10];
 	}
 
 	return pc;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
--- linux.orig/arch/mips/kernel/ptrace.c	2001-09-18 23:56:19.000000000 +0000
+++ linux/arch/mips/kernel/ptrace.c	2002-07-20 01:08:36.000000000 +0000
@@ -20,7 +20,6 @@
 #include <linux/smp_lock.h>
 #include <linux/user.h>
 
-#include <asm/fp.h>
 #include <asm/mipsregs.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -42,7 +41,7 @@
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 {
 	struct task_struct *child;
-	int res;
+	int ret;
 	extern void save_fp(struct task_struct *);
 
 	lock_kernel();
@@ -54,15 +53,15 @@
 	if (request == PTRACE_TRACEME) {
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED) {
-			res = -EPERM;
+			ret = -EPERM;
 			goto out;
 		}
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
-		res = 0;
+		ret = 0;
 		goto out;
 	}
-	res = -ESRCH;
+	ret = -ESRCH;
 	read_lock(&tasklist_lock);
 	child = find_task_by_pid(pid);
 	if (child)
@@ -71,23 +70,19 @@
 	if (!child)
 		goto out;
 
-	res = -EPERM;
+	ret = -EPERM;
 	if (pid == 1)		/* you may not mess with init */
 		goto out;
 
 	if (request == PTRACE_ATTACH) {
-		res = ptrace_attach(child);
+		ret = ptrace_attach(child);
 		goto out_tsk;
 	}
-	res = -ESRCH;
-	if (!(child->ptrace & PT_PTRACED))
-		goto out_tsk;
-	if (child->state != TASK_STOPPED) {
-		if (request != PTRACE_KILL)
-			goto out_tsk;
-	}
-	if (child->p_pptr != current)
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
 		goto out_tsk;
+
 	switch (request) {
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
 	case PTRACE_PEEKDATA: {
@@ -95,10 +90,10 @@
 		int copied;
 
 		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-		res = -EIO;
+		ret = -EIO;
 		if (copied != sizeof(tmp))
 			break;
-		res = put_user(tmp,(unsigned long *) data);
+		ret = put_user(tmp,(unsigned long *) data);
 
 		goto out;
 		}
@@ -126,9 +121,9 @@
 						child->thread.fpu.soft.regs;
 				} else 
 					if (last_task_used_math == child) {
-						enable_cp1();
+						__enable_fpu();
 						save_fp(child);
-						disable_cp1();
+						__disable_fpu();
 						last_task_used_math = NULL;
 						regs->cp0_status &= ~ST0_CU1;
 					}
@@ -174,33 +169,37 @@
 		case FPC_EIR: {	/* implementation / version register */
 			unsigned int flags;
 
+			if (!(mips_cpu.options & MIPS_CPU_FPU)) {
+				break;
+			}
+
 			__save_flags(flags);
-			enable_cp1();
+			__enable_fpu();
 			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
 			__restore_flags(flags);
 			break;
 		}
 		default:
 			tmp = 0;
-			res = -EIO;
+			ret = -EIO;
 			goto out;
 		}
-		res = put_user(tmp, (unsigned long *) data);
+		ret = put_user(tmp, (unsigned long *) data);
 		goto out;
 		}
 
 	case PTRACE_POKETEXT: /* write the word at location addr. */
 	case PTRACE_POKEDATA:
-		res = 0;
+		ret = 0;
 		if (access_process_vm(child, addr, &data, sizeof(data), 1)
 		    == sizeof(data))
 			break;
-		res = -EIO;
+		ret = -EIO;
 		goto out;
 
 	case PTRACE_POKEUSR: {
 		struct pt_regs *regs;
-		res = 0;
+		ret = 0;
 		regs = (struct pt_regs *) ((unsigned long) child +
 		       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
 
@@ -217,9 +216,9 @@
 						fregs = (unsigned long long *)
 						child->thread.fpu.soft.regs;
 					} else {
-						enable_cp1();
+						__enable_fpu();
 						save_fp(child);
-						disable_cp1();
+						__disable_fpu();
 						last_task_used_math = NULL;
 						regs->cp0_status &= ~ST0_CU1;
 					}
@@ -266,7 +265,7 @@
 			break;
 		default:
 			/* The rest are not allowed. */
-			res = -EIO;
+			ret = -EIO;
 			break;
 		}
 		break;
@@ -274,7 +273,7 @@
 
 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
 	case PTRACE_CONT: { /* restart after signal. */
-		res = -EIO;
+		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			break;
 		if (request == PTRACE_SYSCALL)
@@ -283,7 +282,7 @@
 			child->ptrace &= ~PT_TRACESYS;
 		child->exit_code = data;
 		wake_up_process(child);
-		res = 0;
+		ret = 0;
 		break;
 		}
 
@@ -293,7 +292,7 @@
 	 * exit.
 	 */
 	case PTRACE_KILL:
-		res = 0;
+		ret = 0;
 		if (child->state == TASK_ZOMBIE)	/* already dead */
 			break;
 		child->exit_code = SIGKILL;
@@ -301,7 +300,7 @@
 		break;
 
 	case PTRACE_DETACH: /* detach a process that was attached. */
-		res = ptrace_detach(child, data);
+		ret = ptrace_detach(child, data);
 		break;
 
 	case PTRACE_SETOPTIONS:
@@ -309,18 +308,18 @@
 			child->ptrace |= PT_TRACESYSGOOD;
 		else
 			child->ptrace &= ~PT_TRACESYSGOOD;
-		res = 0;
+		ret = 0;
 		break;
 
 	default:
-		res = -EIO;
+		ret = -EIO;
 		goto out;
 	}
 out_tsk:
 	free_task_struct(child);
 out:
 	unlock_kernel();
-	return res;
+	return ret;
 }
 
 asmlinkage void syscall_trace(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/r2300_misc.S linux/arch/mips/kernel/r2300_misc.S
--- linux.orig/arch/mips/kernel/r2300_misc.S	2000-02-28 15:18:20.000000000 +0000
+++ linux/arch/mips/kernel/r2300_misc.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,199 +0,0 @@
-/* $Id: r2300_misc.S,v 1.8 1999/12/08 22:05:10 harald Exp $
- * misc.S: Misc. exception handling code for R3000/R2000.
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * Multi-CPU abstraction reworking:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Further modifications to make this work:
- * Copyright (c) 1998 Harald Koerfgen
- * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov
- */
-#include <asm/asm.h>
-#include <asm/current.h>
-#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/regdef.h>
-#include <asm/segment.h>
-#include <asm/stackframe.h>
-
-	.text
-	.set	mips1
-	.set	noreorder
-
-#undef NOTLB_OPTIMIZE /* If you are paranoid, define this. */
-
-	/* ABUSE of CPP macros 101. */
-
-	/* After this macro runs, the pte faulted on is
-	 * in register PTE, a ptr into the table in which
-	 * the pte belongs is in PTR.
-	 */
-#define LOAD_PTE(pte, ptr) \
-	mfc0	pte, CP0_BADVADDR; \
-	lw	ptr, current_pgd; \
-	srl	pte, pte, 22; \
-	sll	pte, pte, 2; \
-	addu	ptr, ptr, pte; \
-	mfc0	pte, CP0_CONTEXT; \
-	lw	ptr, (ptr); \
-	andi	pte, pte, 0xffc; \
-	addu	ptr, ptr, pte; \
-	lw	pte, (ptr); \
-	nop;
-
-	/* This places the even/odd pte pair in the page
-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
-	 * TMP as a scratch register.
-	 */
-#define PTE_RELOAD(ptr) \
-	lw	ptr, (ptr)	; \
-	nop			; \
-	mtc0	ptr, CP0_ENTRYLO0; \
-	nop;
-
-#define DO_FAULT(write) \
-	.set	noat; \
-	.set	macro; \
-	SAVE_ALL; \
-	mfc0	a2, CP0_BADVADDR; \
-	STI; \
-	.set	at; \
-	move	a0, sp; \
-	jal	do_page_fault; \
-	 li	a1, write; \
-	j	ret_from_sys_call; \
-	 nop; \
-	.set	noat; \
-	.set	nomacro;
-
-	/* Check is PTE is present, if not then jump to LABEL.
-	 * PTR points to the page table where this PTE is located,
-	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
-	 */
-#define PTE_PRESENT(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	bnez	pte, label; \
-	.set	push;       \
-	.set	reorder;    \
-	 lw	pte, (ptr); \
-	.set	pop; 
-
-	/* Make PTE valid, store result in PTR. */
-#define PTE_MAKEVALID(pte, ptr) \
-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
-	sw	pte, (ptr);
-
-	/* Check if PTE can be written to, if not branch to LABEL.
-	 * Regardless restore PTE with value from PTR when done.
-	 */
-#define PTE_WRITABLE(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	bnez	pte, label; \
-	.set    push;       \
-	.set    reorder;    \
-	lw      pte, (ptr); \
-	.set    pop;
- 
-
-	/* Make PTE writable, update software status bits as well,
-	 * then store at PTR.
-	 */
-#define PTE_MAKEWRITE(pte, ptr) \
-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
-			   _PAGE_VALID | _PAGE_DIRTY); \
-	sw	pte, (ptr);
-
-/*
- * The index register may have the probe fail bit set,
- * because we would trap on access kseg2, i.e. without refill.
- */
-#define TLB_WRITE(reg) \
-	mfc0	reg, CP0_INDEX; \
-	nop; \
-	bltz    reg, 1f; \
-	 nop; \
-	tlbwi; \
-	j	2f; \
-	 nop; \
-1:	tlbwr; \
-2:
-
-#define RET(reg) \
-	mfc0	reg, CP0_EPC; \
-	nop; \
-	jr	reg; \
-	 rfe
-			
-	.set	noreorder
-
-	.align	5
-NESTED(handle_tlbl, PT_SIZE, sp)
-	.set	noat
-
-#ifndef NOTLB_OPTIMIZE
-	/* Test present bit in entry. */
-	LOAD_PTE(k0, k1)
-        tlbp
-        PTE_PRESENT(k0, k1, nopage_tlbl)
-        PTE_MAKEVALID(k0, k1)
-        PTE_RELOAD(k1)
-	TLB_WRITE(k0)
-	RET(k0)
-nopage_tlbl:
-#endif
-
-	DO_FAULT(0)
-END(handle_tlbl)
-
-NESTED(handle_tlbs, PT_SIZE, sp)
-	.set	noat
-
-#ifndef NOTLB_OPTIMIZE
-	LOAD_PTE(k0, k1)
-	tlbp                            # find faulting entry
-	PTE_WRITABLE(k0, k1, nopage_tlbs)
-	PTE_MAKEWRITE(k0, k1)
-	PTE_RELOAD(k1)
-	TLB_WRITE(k0)
-	RET(k0)
-nopage_tlbs:
-#endif
-
-	DO_FAULT(1)
-END(handle_tlbs)
-
-	.align	5
-NESTED(handle_mod, PT_SIZE, sp)
-	.set	noat
-#ifndef NOTLB_OPTIMIZE
-	LOAD_PTE(k0, k1)
-	tlbp					# find faulting entry
-	andi	k0, k0, _PAGE_WRITE
-	beqz	k0, nowrite_mod
-	.set	push
-	.set    reorder
-	lw	k0, (k1)
-	.set    pop
-
-	/* Present and writable bits set, set accessed and dirty bits. */
-	PTE_MAKEWRITE(k0, k1)
-
-	/* Now reload the entry into the tlb. */
-	PTE_RELOAD(k1)
-	tlbwi
-	RET(k0)
-#endif
-
-nowrite_mod:
-	DO_FAULT(1)
-END(handle_mod)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/r2300_switch.S linux/arch/mips/kernel/r2300_switch.S
--- linux.orig/arch/mips/kernel/r2300_switch.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/r2300_switch.S	2002-07-20 01:08:30.000000000 +0000
@@ -10,15 +10,15 @@
  * Further modifications to make this work:
  * Copyright (c) 1998-2000 Harald Koerfgen
  */
+#include <linux/config.h>
 #include <asm/asm.h>
-#include <asm/bootinfo.h>
 #include <asm/cachectl.h>
 #include <asm/current.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/offset.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgtable-bits.h>
 #include <asm/processor.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
@@ -72,7 +72,7 @@
 
 LEAF(lazy_fpu_switch)
 	mfc0	t0, CP0_STATUS			# enable cp1
-	li	t3, 0x20000000
+	li	t3, ST0_CU1
 	or	t0, t3
 	mtc0	t0, CP0_STATUS
 
@@ -118,7 +118,7 @@
 
 LEAF(init_fpu)
 	mfc0	t0, CP0_STATUS
-	li	t1, 0x20000000
+	li	t1, ST0_CU1
 	or	t0, t1
 	mtc0	t0, CP0_STATUS
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/r4k_misc.S linux/arch/mips/kernel/r4k_misc.S
--- linux.orig/arch/mips/kernel/r4k_misc.S	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/kernel/r4k_misc.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,236 +0,0 @@
-/* $Id: r4k_misc.S,v 1.8 1999/10/09 00:00:58 ralf Exp $
- *
- * r4k_misc.S: Misc. exception handling code for r4k.
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * Multi-cpu abstraction and reworking:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-/**************************************************************************
- *  14 Nov, 2000.
- *  Made support for MIPS32 CPUs.
- *
- *  Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *************************************************************************/
-#include <asm/asm.h>
-#include <asm/current.h>
-#include <asm/offset.h>
-#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-#undef NOTLB_OPTIMIZE /* If you are paranoid, define this. */
-
-	/* ABUSE of CPP macros 101. */
-
-	/* After this macro runs, the pte faulted on is
-	 * in register PTE, a ptr into the table in which
-	 * the pte belongs is in PTR.
-	 */
-
-#ifdef CONFIG_SMP
-#define GET_PGD(scratch, ptr)        \
-	mfc0    ptr, CP0_CONTEXT;    \
-	la      scratch, current_pgd;\
-	srl     ptr, 23;             \
-	sll     ptr, 2;              \
-	addu    ptr, scratch, ptr;   \
-	lw      ptr, (ptr);          
-#else
-#define GET_PGD(scratch, ptr)    \
-	lw	ptr, current_pgd;
-#endif
-	
-	
-#define LOAD_PTE(pte, ptr) \
-	GET_PGD(pte, ptr)          \
-	mfc0	pte, CP0_BADVADDR; \
-	srl	pte, pte, 22; \
-	sll	pte, pte, 2; \
-	addu	ptr, ptr, pte; \
-	mfc0	pte, CP0_BADVADDR; \
-	lw	ptr, (ptr); \
-	srl	pte, pte, 10; \
-	and	pte, pte, 0xffc; \
-	addu	ptr, ptr, pte; \
-	lw	pte, (ptr);
-
-	/* This places the even/odd pte pair in the page
-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
-	 * TMP as a scratch register.
-	 */
-#define PTE_RELOAD(ptr, tmp) \
-	ori	ptr, ptr, 0x4; \
-	xori	ptr, ptr, 0x4; \
-	lw	tmp, 4(ptr); \
-	lw	ptr, 0(ptr); \
-	srl	tmp, tmp, 6; \
-	mtc0	tmp, CP0_ENTRYLO1; \
-	srl	ptr, ptr, 6; \
-	mtc0	ptr, CP0_ENTRYLO0;
-
-#define DO_FAULT(write) \
-	.set	noat; \
-	SAVE_ALL; \
-	mfc0	a2, CP0_BADVADDR; \
-	STI; \
-	.set	at; \
-	move	a0, sp; \
-	jal	do_page_fault; \
-	 li	a1, write; \
-	j	ret_from_sys_call; \
-	 nop; \
-	.set	noat;
-
-	/* Check is PTE is present, if not then jump to LABEL.
-	 * PTR points to the page table where this PTE is located,
-	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
-	 */
-#define PTE_PRESENT(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	bnez	pte, label; \
-	 lw	pte, (ptr);
-
-	/* Make PTE valid, store result in PTR. */
-#define PTE_MAKEVALID(pte, ptr) \
-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
-	sw	pte, (ptr);
-
-	/* Check if PTE can be written to, if not branch to LABEL.
-	 * Regardless restore PTE with value from PTR when done.
-	 */
-#define PTE_WRITABLE(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	bnez	pte, label; \
-	 lw	pte, (ptr);
-
-	/* Make PTE writable, update software status bits as well,
-	 * then store at PTR.
-	 */
-#define PTE_MAKEWRITE(pte, ptr) \
-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
-			   _PAGE_VALID | _PAGE_DIRTY); \
-	sw	pte, (ptr);
-
-	.set	noreorder
-
-/*
- * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
- * 2. A timing hazard exists for the TLBP instruction.
- *
- *      stalling_instruction
- *      TLBP
- *
- * The JTLB is being read for the TLBP throughout the stall generated by the
- * previous instruction. This is not really correct as the stalling instruction
- * can modify the address used to access the JTLB.  The failure symptom is that
- * the TLBP instruction will use an address created for the stalling instruction
- * and not the address held in C0_ENHI and thus report the wrong results.
- *
- * The software work-around is to not allow the instruction preceding the TLBP
- * to stall - make it an NOP or some other instruction guaranteed not to stall.
- *
- * Errata 2 will not be fixed.  This errata is also on the R5000.
- *
- * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
- */
-#define R5K_HAZARD nop
-
-	/*
-	 * Note for many R4k variants tlb probes cannot be executed out
-	 * of the instruction cache else you get bogus results.
-	 */
-	.align	5
-	NESTED(handle_tlbl, PT_SIZE, sp)
-	.set	noat
-invalid_tlbl:
-#ifndef NOTLB_OPTIMIZE
-	/* Test present bit in entry. */
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp
-	PTE_PRESENT(k0, k1, nopage_tlbl)
-	PTE_MAKEVALID(k0, k1)
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3	
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbl:
-	DO_FAULT(0)
-	END(handle_tlbl)
-
-	.align	5
-	NESTED(handle_tlbs, PT_SIZE, sp)
-	.set	noat
-#ifndef NOTLB_OPTIMIZE
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp				# find faulting entry
-	PTE_WRITABLE(k0, k1, nopage_tlbs)
-	PTE_MAKEWRITE(k0, k1)
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3	
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbs:
-	DO_FAULT(1)
-	END(handle_tlbs)
-
-	.align	5
-	NESTED(handle_mod, PT_SIZE, sp)
-	.set	noat
-#ifndef NOTLB_OPTIMIZE
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp					# find faulting entry
-	andi	k0, k0, _PAGE_WRITE
-	beqz	k0, nowrite_mod
-	 lw	k0, (k1)
-
-	/* Present and writable bits set, set accessed and dirty bits. */
-	PTE_MAKEWRITE(k0, k1)
-#if 0
-	ori	k0, k0, (_PAGE_ACCESSED | _PAGE_DIRTY)
-	sw	k0, (k1)
-#endif
-
-	/* Now reload the entry into the tlb. */
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nowrite_mod:
-	DO_FAULT(1)
-	END(handle_mod)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/r4k_switch.S linux/arch/mips/kernel/r4k_switch.S
--- linux.orig/arch/mips/kernel/r4k_switch.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/r4k_switch.S	2002-07-20 01:08:40.000000000 +0000
@@ -12,14 +12,13 @@
  */
 #include <linux/config.h>
 #include <asm/asm.h>
-#include <asm/bootinfo.h>
 #include <asm/cachectl.h>
 #include <asm/current.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/offset.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgtable-bits.h>
 #include <asm/processor.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
@@ -78,7 +77,7 @@
 
 LEAF(lazy_fpu_switch)
 	mfc0	t0, CP0_STATUS			# enable cp1
-	li	t3, 0x20000000
+	li	t3, ST0_CU1
 	or	t0, t3
 	mtc0	t0, CP0_STATUS
 
@@ -127,7 +126,7 @@
 LEAF(init_fpu)
 	.set	mips3
 	mfc0	t0, CP0_STATUS
-	li	t1, 0x20000000
+	li	t1, ST0_CU1
 	or	t0, t1
 	mtc0	t0, CP0_STATUS
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/scall_o32.S linux/arch/mips/kernel/scall_o32.S
--- linux.orig/arch/mips/kernel/scall_o32.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/scall_o32.S	2002-07-20 01:08:39.000000000 +0000
@@ -3,23 +3,20 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
-#include <asm/asm.h>
+#include <linux/config.h>
 #include <linux/errno.h>
+#include <asm/asm.h>
 #include <asm/current.h>
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
 #include <asm/isadep.h>
+#include <asm/sysmips.h>
 #include <asm/unistd.h>
 
-/* This duplicates the definition from <linux/sched.h> */
-#define PT_TRACESYS	0x00000002	/* tracing system calls */
-
-/* This duplicates the definition from <asm/signal.h> */
-#define SIGILL		4		/* Illegal instruction (ANSI).  */
-
 /* Highest syscall used of any syscall flavour */
 #define MAX_SYSCALL_NO	__NR_Linux + __NR_Linux_syscalls
 
@@ -86,13 +83,13 @@
 	ori	t0, t0, 1
 	mtc0	t0, CP0_STATUS
 
+	SAVE_STATIC
 	move	a0, zero
 	move	a1, sp
 	jal	do_signal
 	b	restore_all
 
 o32_reschedule:
-	SAVE_STATIC
 	jal	schedule
 	b	o32_ret_from_sys_call
 
@@ -192,3 +189,146 @@
 	sw	t0, PT_R7(sp)
 	j	ret_from_sys_call
 	END(handle_sys)
+
+	LEAF(mips_atomic_set)
+	andi	v0, a1, 3			# must be word aligned
+	bnez	v0, bad_alignment
+
+	lw	v1, THREAD_CURDS($28)		# in legal address range?
+	addiu	a0, a1, 4
+	or	a0, a0, a1
+	and	a0, a0, v1
+	bltz	a0, bad_address
+
+#ifdef CONFIG_CPU_HAS_LLSC
+	/* Ok, this is the ll/sc case.  World is sane :-)  */
+1:	ll	v0, (a1)
+	move	a0, a2
+2:	sc	a0, (a1)
+	beqz	a0, 1b
+
+	.section __ex_table,"a"
+	PTR	1b, bad_stack
+	PTR	2b, bad_stack
+	.previous
+#else
+	sw	a1, 16(sp)
+	sw	a2, 20(sp)
+
+	move	a0, sp
+	move	a2, a1
+	li	a1, 1
+	jal	do_page_fault
+
+	lw	a1, 16(sp)
+	lw	a2, 20(sp)
+
+	/*
+	 * At this point the page should be readable and writable unless
+	 * there was no more memory available.
+	 */
+1:	lw	v0, (a1)
+2:	sw	a2, (a1)
+
+	.section __ex_table,"a"
+	PTR	1b, no_mem
+	PTR	2b, no_mem
+	.previous
+#endif
+
+	sw	v0, PT_R2(sp)		# result
+1:
+
+	/* Success, so skip usual error handling garbage.  */
+	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+	andi	t0, PT_TRACESYS
+	bnez	t0, 1f
+	b	o32_ret_from_sys_call
+
+1:	SAVE_STATIC
+	jal	syscall_trace
+	li	a3, 0			# success
+	j	ret_from_sys_call
+
+no_mem:	li	v0, -ENOMEM
+	jr	ra
+
+bad_address:
+	li	v0, -EFAULT
+	jr	ra
+
+bad_alignment:
+	li	v0, -EINVAL
+	jr	ra
+	END(mips_atomic_set)	
+
+	LEAF(sys_sysmips)
+	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
+	j	_sys_sysmips
+	END(sys_sysmips)
+
+	LEAF(sys_syscall)
+	lw	t0, PT_R29(sp)			# user sp
+
+	sltu	v0, a0, __NR_Linux + __NR_Linux_syscalls + 1
+	beqz	v0, enosys
+
+	sll	v0, t1, 2
+	la	v1, sys_syscall
+	lw	t2, sys_call_table(v0)		# function pointer
+	lbu	t4, sys_narg_table(t1)		# number of arguments
+
+	li	v0, -EINVAL
+	beq	t2, v1, out			# do not recurse
+
+	beqz	t2, enosys			# null function pointer?
+
+	andi	v0, t0, 0x3			# unaligned stack pointer?
+	bnez	v0, sigsegv
+
+	addu	v0, t0, 16			# v0 = usp + 16
+	addu	t1, v0, 12			# 3 32-bit arguments
+	lw	v1, THREAD_CURDS($28)
+	or	v0, v0, t1
+	and	v1, v1, v0
+	bltz	v1, efault
+
+	move	a0, a1				# shit argument registers
+	move	a1, a2
+	move	a2, a3
+
+1:	lw	a3, 16(t0)
+2:	lw	t3, 20(t0)
+3:	lw	t4, 24(t0)
+
+	.section	__ex_table, "a"
+	.word	1b, efault
+	.word	2b, efault
+	.word	3b, efault
+	.previous
+
+	sw	t3, 16(sp)			# put into new stackframe
+	sw	t4, 20(sp)
+
+	bnez	t4, 1f				# zero arguments?
+	addu	a0, sp, 32			# then pass sp in a0
+1:
+
+	sw	t3, 16(sp)
+	sw	v1, 20(sp)
+	jr	t2
+	/* Unreached */
+
+enosys:	li	v0, -ENOSYS
+	b	out
+
+sigsegv:
+	li	a0, _SIGSEGV
+	move	a1, $28
+	jal	force_sig
+	/* Fall through */
+
+efault:	li	v0, -EFAULT
+
+out:	jr	ra
+	END(sys_syscall)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
--- linux.orig/arch/mips/kernel/setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/setup.c	2002-07-20 01:08:27.000000000 +0000
@@ -4,9 +4,10 @@
  * for more details.
  *
  * Copyright (C) 1995  Linus Torvalds
- * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000  Ralf Baechle
+ * Copyright (C) 1995  Waldorf Electronics
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001  Ralf Baechle
  * Copyright (C) 1996  Stoned Elipot
- * Copyright (C) 2000  Maciej W. Rozycki
+ * Copyright (C) 2000, 2001  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -16,10 +17,10 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/stddef.h>
 #include <linux/string.h>
 #include <linux/unistd.h>
-#include <linux/ptrace.h>
 #include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/utsname.h>
@@ -35,14 +36,12 @@
 #include <asm/cachectl.h>
 #include <asm/cpu.h>
 #include <asm/io.h>
-#include <asm/stackframe.h>
+#include <asm/ptrace.h>
 #include <asm/system.h>
-#ifdef CONFIG_SGI_IP22
-#include <asm/sgialib.h>
-#endif
 
-
-struct mips_cpuinfo boot_cpu_data = { 0, NULL, NULL, 0 };
+#ifndef CONFIG_SMP
+struct cpuinfo_mips cpu_data[1];
+#endif
 
 /*
  * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
@@ -95,21 +94,24 @@
 unsigned char aux_device_present;
 extern char _ftext, _etext, _fdata, _edata, _end;
 
-static char command_line[COMMAND_LINE_SIZE];
-       char saved_command_line[COMMAND_LINE_SIZE];
-extern char arcs_cmdline[COMMAND_LINE_SIZE];
+static char command_line[CL_SIZE];
+       char saved_command_line[CL_SIZE];
+extern char arcs_cmdline[CL_SIZE];
 
 /*
  * mips_io_port_base is the begin of the address space to which x86 style
  * I/O ports are mapped.
  */
-unsigned long mips_io_port_base;
+const unsigned long mips_io_port_base = -1;
+EXPORT_SYMBOL(mips_io_port_base);
+
 
 /*
  * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
  * for the processor.
  */
 unsigned long isa_slot_offset;
+EXPORT_SYMBOL(isa_slot_offset);
 
 extern void sgi_sysinit(void);
 extern void SetUpBootInfo(void);
@@ -120,6 +122,49 @@
 static struct resource code_resource = { "Kernel code" };
 static struct resource data_resource = { "Kernel data" };
 
+static inline void check_wait(void)
+{
+	printk("Checking for 'wait' instruction... ");
+	switch(mips_cpu.cputype) {
+	case CPU_R3081:
+	case CPU_R3081E:
+		cpu_wait = r3081_wait;
+		printk(" available.\n");
+		break;
+	case CPU_TX3927:
+	case CPU_TX39XX:
+		cpu_wait = r39xx_wait;
+		printk(" available.\n");
+		break;
+	case CPU_R4200: 
+/*	case CPU_R4300: */
+	case CPU_R4600: 
+	case CPU_R4640: 
+	case CPU_R4650: 
+	case CPU_R4700: 
+	case CPU_R5000: 
+	case CPU_NEVADA:
+	case CPU_RM7000:
+	case CPU_TX49XX:
+	case CPU_4KC:
+	case CPU_4KEC:
+	case CPU_4KSC:
+	case CPU_5KC:
+/*	case CPU_20KC:*/
+		cpu_wait = r4k_wait;
+		printk(" available.\n");
+		break;
+	default:
+		printk(" unavailable.\n");
+		break;
+	}
+}
+
+void __init check_bugs(void)
+{
+	check_wait();
+}
+
 /*
  * Probe whether cpu has config register by trying to play with
  * alternate cache bit and see whether it matters.
@@ -142,9 +187,34 @@
 #endif
 }
 
+/*
+ * Get the FPU Implementation/Revision.
+ */
+static inline unsigned long cpu_get_fpu_id(void)
+{
+	unsigned long tmp, fpu_id;
+
+	tmp = read_32bit_cp0_register(CP0_STATUS);
+	__enable_fpu();
+	fpu_id = read_32bit_cp1_register(CP1_REVISION);
+	write_32bit_cp0_register(CP0_STATUS, tmp);
+	return fpu_id;
+}
+
+/*
+ * Check the CPU has an FPU the official way.
+ */
+static inline int cpu_has_fpu(void)
+{
+	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
+}
+
 /* declaration of the global struct */
-struct mips_cpu mips_cpu = {PRID_IMP_UNKNOWN, CPU_UNKNOWN, 0, 0, 0,
-			    {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}};
+struct mips_cpu mips_cpu = {
+    processor_id:	PRID_IMP_UNKNOWN,
+    fpu_id:		FPIR_IMP_NONE,
+    cputype:		CPU_UNKNOWN
+};
 
 /* Shortcut for assembler access to mips_cpu.options */
 int *cpuoptions = &mips_cpu.options;
@@ -154,11 +224,27 @@
 
 static inline void cpu_probe(void)
 {
-
 #ifdef CONFIG_CPU_MIPS32
+	unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG);
 	unsigned long config1;
-#endif
 
+        if (config0 & (1 << 31)) {
+		/* MIPS32 compliant CPU. Read Config 1 register. */
+		mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+			MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC;
+		config1 = read_mips32_cp0_config1();
+		if (config1 & (1 << 3))
+			mips_cpu.options |= MIPS_CPU_WATCH;
+		if (config1 & (1 << 2))
+			mips_cpu.options |= MIPS_CPU_MIPS16;
+		if (config1 & (1 << 1))
+			mips_cpu.options |= MIPS_CPU_EJTAG;
+		if (config1 & 1)
+			mips_cpu.options |= MIPS_CPU_FPU;
+		mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+	}
+#endif
 	mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID);
 	switch (mips_cpu.processor_id & 0xff0000) {
 	case PRID_COMP_LEGACY:
@@ -166,7 +252,9 @@
 		case PRID_IMP_R2000:
 			mips_cpu.cputype = CPU_R2000;
 			mips_cpu.isa_level = MIPS_CPU_ISA_I;
-			mips_cpu.options = MIPS_CPU_TLB;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
 			mips_cpu.tlbsize = 64;
 			break;
 		case PRID_IMP_R3000:
@@ -178,7 +266,9 @@
 			else
 				mips_cpu.cputype = CPU_R3000;
 			mips_cpu.isa_level = MIPS_CPU_ISA_I;
-			mips_cpu.options = MIPS_CPU_TLB;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
 			mips_cpu.tlbsize = 64;
 			break;
 		case PRID_IMP_R4000:
@@ -187,8 +277,9 @@
 			else
 				mips_cpu.cputype = CPU_R4000SC;
 			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
-				           MIPS_CPU_WATCH | MIPS_CPU_VCE;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH |
+			                   MIPS_CPU_VCE;
 			mips_cpu.tlbsize = 48;
 			break;
                 case PRID_IMP_VR41XX:
@@ -197,67 +288,101 @@
                         mips_cpu.options = R4K_OPTS;
                         mips_cpu.tlbsize = 32;
                         break;
+		case PRID_IMP_R4300:
+			mips_cpu.cputype = CPU_R4300;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+					   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 32;
+			break;
 		case PRID_IMP_R4600:
 			mips_cpu.cputype = CPU_R4600;
 			mips_cpu.isa_level = MIPS_CPU_ISA_III;
 			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
 			mips_cpu.tlbsize = 48;
 			break;
-/*
- * This processor doesn't have an MMU, so it's not "real easy" to
- * run Linux on it. It is left purely for documentation.
- *		case PRID_IMP_R4650:
+		#if 0
+ 		case PRID_IMP_R4650:
+			/*
+			 * This processor doesn't have an MMU, so it's not
+			 * "real easy" to run Linux on it. It is left purely
+			 * for documentation.  Commented out because it shares
+			 * it's c0_prid id number with the TX3900.
+			 */
 	 		mips_cpu.cputype = CPU_R4650;
 		 	mips_cpu.isa_level = MIPS_CPU_ISA_III;
 			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
 		        mips_cpu.tlbsize = 48;
 			break;
-*/
+		#endif
 		case PRID_IMP_TX39:
 			mips_cpu.isa_level = MIPS_CPU_ISA_I;
 			mips_cpu.options = MIPS_CPU_TLB;
 
-			switch (mips_cpu.processor_id & 0xff) {
-			case PRID_REV_TX3912:
-				mips_cpu.cputype = CPU_TX3912;
-				mips_cpu.tlbsize = 32;
-				break;
-			case PRID_REV_TX3922:
-				mips_cpu.cputype = CPU_TX3922;
-				mips_cpu.tlbsize = 64;
-				break;
-			case PRID_REV_TX3927:
+			if ((mips_cpu.processor_id & 0xf0) ==
+			    (PRID_REV_TX3927 & 0xf0)) {
 				mips_cpu.cputype = CPU_TX3927;
 				mips_cpu.tlbsize = 64;
-				break;
-			default:
-				mips_cpu.cputype = CPU_UNKNOWN;
-				break;
+				mips_cpu.icache.ways = 2;
+				mips_cpu.dcache.ways = 2;
+			} else {
+				switch (mips_cpu.processor_id & 0xff) {
+				case PRID_REV_TX3912:
+					mips_cpu.cputype = CPU_TX3912;
+					mips_cpu.tlbsize = 32;
+					break;
+				case PRID_REV_TX3922:
+					mips_cpu.cputype = CPU_TX3922;
+					mips_cpu.tlbsize = 64;
+					break;
+				default:
+					mips_cpu.cputype = CPU_UNKNOWN;
+					break;
+				}
 			}
 			break;
 		case PRID_IMP_R4700:
 			mips_cpu.cputype = CPU_R4700;
 			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
 			mips_cpu.tlbsize = 48;
 			break;
+		case PRID_IMP_TX49:
+			mips_cpu.cputype = CPU_TX49XX;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			mips_cpu.icache.ways = 4;
+			mips_cpu.dcache.ways = 4;
+			break;
 		case PRID_IMP_R5000:
 			mips_cpu.cputype = CPU_R5000;
 			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
 			mips_cpu.tlbsize = 48;
 			break;
 		case PRID_IMP_R5432:
 			mips_cpu.cputype = CPU_R5432;
 			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_R5500:
+			mips_cpu.cputype = CPU_R5500;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
 			mips_cpu.tlbsize = 48;
 			break;
 		case PRID_IMP_NEVADA:
 			mips_cpu.cputype = CPU_NEVADA;
 			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 
-				           MIPS_CPU_DIVEC;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_DIVEC;
 			mips_cpu.tlbsize = 48;
 			mips_cpu.icache.ways = 2;
 			mips_cpu.dcache.ways = 2;
@@ -277,7 +402,17 @@
 		case PRID_IMP_RM7000:
 			mips_cpu.cputype = CPU_RM7000;
 			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			/*
+			 * Undocumented RM7000:  Bit 29 in the info register of
+			 * the RM7000 v2.0 indicates if the TLB has 48 or 64
+			 * entries.
+			 *
+			 * 29      1 =>    64 entry JTLB
+			 *         0 =>    48 entry JTLB
+			 */
+			mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48;
 			break;
 		case PRID_IMP_R8000:
 			mips_cpu.cputype = CPU_R8000;
@@ -294,6 +429,14 @@
 				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
 			mips_cpu.tlbsize = 64;
 			break;
+		case PRID_IMP_R12000:
+			mips_cpu.cputype = CPU_R12000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR | 
+				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 64;
+			break;
 		default:
 			mips_cpu.cputype = CPU_UNKNOWN;
 			break;
@@ -304,80 +447,53 @@
 		switch (mips_cpu.processor_id & 0xff00) {
 		case PRID_IMP_4KC:
 			mips_cpu.cputype = CPU_4KC;
-			goto cpu_4kc;
+			break;
 		case PRID_IMP_4KEC:
 			mips_cpu.cputype = CPU_4KEC;
-			goto cpu_4kc;
+			break;
 		case PRID_IMP_4KSC:
 			mips_cpu.cputype = CPU_4KSC;
-cpu_4kc:
-			/* Why do we set all these options by default, THEN query them?? */
-			mips_cpu.cputype = MIPS_CPU_ISA_M32;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-				           MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | 
-				           MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
-			config1 = read_mips32_cp0_config1();
-			if (config1 & (1 << 3))
-				mips_cpu.options |= MIPS_CPU_WATCH;
-			if (config1 & (1 << 2))
-				mips_cpu.options |= MIPS_CPU_MIPS16;
-			if (config1 & 1)
-				mips_cpu.options |= MIPS_CPU_FPU;
-			mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
 			break;
 		case PRID_IMP_5KC:
 			mips_cpu.cputype = CPU_5KC;
-			mips_cpu.cputype = MIPS_CPU_ISA_M64;
-			/* See comment above about querying options */
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-				           MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | 
-				           MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
-			config1 = read_mips32_cp0_config1();
-			if (config1 & (1 << 3))
-				mips_cpu.options |= MIPS_CPU_WATCH;
-			if (config1 & (1 << 2))
-				mips_cpu.options |= MIPS_CPU_MIPS16;
-			if (config1 & 1)
-				mips_cpu.options |= MIPS_CPU_FPU;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			break;
+		case PRID_IMP_20KC:
+			mips_cpu.cputype = CPU_20KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
 			break;
-			mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
 		default:
 			mips_cpu.cputype = CPU_UNKNOWN;
 			break;
 		}		
 		break;
-#endif
 	case PRID_COMP_ALCHEMY:
 		switch (mips_cpu.processor_id & 0xff00) {
-#ifdef CONFIG_CPU_MIPS32
-		case PRID_IMP_AU1000:
-			mips_cpu.cputype = CPU_AU1000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-					   MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | 
-					   MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
-			config1 = read_mips32_cp0_config1();
-			if (config1 & (1 << 3))
-				mips_cpu.options |= MIPS_CPU_WATCH;
-			if (config1 & (1 << 2))
-				mips_cpu.options |= MIPS_CPU_MIPS16;
-			if (config1 & 1)
-				mips_cpu.options |= MIPS_CPU_FPU;
-			mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+		case PRID_IMP_AU1_REV1:
+		case PRID_IMP_AU1_REV2:
+			if (mips_cpu.processor_id & 0xff000000)
+				mips_cpu.cputype = CPU_AU1500;
+			else
+				mips_cpu.cputype = CPU_AU1000;
 			break;
-#endif
 		default:
 			mips_cpu.cputype = CPU_UNKNOWN;
 			break;
 		}
 		break;
+#endif /* CONFIG_CPU_MIPS32 */
 	case PRID_COMP_SIBYTE:
 		switch (mips_cpu.processor_id & 0xff00) {
 		case PRID_IMP_SB1:
 			mips_cpu.cputype = CPU_SB1;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-				           MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | MIPS_CPU_FPU |
-		      	           MIPS_CPU_VCE;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+			                   MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
+			                   MIPS_CPU_MCHECK;
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+			/* FPU in pass1 is known to have issues. */
+			mips_cpu.options |= MIPS_CPU_FPU;
+#endif
 			break;
 		default:
 			mips_cpu.cputype = CPU_UNKNOWN;
@@ -387,6 +503,15 @@
 	default:
 		mips_cpu.cputype = CPU_UNKNOWN;
 	}
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		mips_cpu.fpu_id = cpu_get_fpu_id();
+}
+
+static inline void cpu_report(void)
+{
+	printk("CPU revision is: %08x\n", mips_cpu.processor_id);
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		printk("FPU revision is: %08x\n", mips_cpu.fpu_id);
 }
 
 asmlinkage void __init
@@ -403,6 +528,8 @@
 	sgi_sysinit();
 #endif
 
+	cpu_report();
+
 	/*
 	 * Determine the mmu/cache attached to this machine,
 	 * then flush the tlb and caches.  On the r4xx0
@@ -410,16 +537,14 @@
 	 */
 	loadmmu();
 
-	/* Disable coprocessors and set FPU for 16 FPRs */
-	s = read_32bit_cp0_register(CP0_STATUS);
-	s &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR);
-	s |= ST0_CU0;
-	write_32bit_cp0_register(CP0_STATUS, s);
+	/* Disable coprocessors and set FPU for 16/32 FPR register model */
+	clear_cp0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR);
+	set_cp0_status(ST0_CU0);
 
 	start_kernel();
 }
 
-void __init add_memory_region(unsigned long start, unsigned long size,
+void __init add_memory_region(phys_t start, phys_t size,
 			      long type)
 {
 	int x = boot_mem_map.nr_map;
@@ -440,8 +565,10 @@
 	int i;
 
 	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		printk(" memory: %08lx @ %08lx ",
-			boot_mem_map.map[i].size, boot_mem_map.map[i].addr);
+		printk(" memory: %08Lx @ %08Lx ",
+			(u64) boot_mem_map.map[i].size,
+		        (u64) boot_mem_map.map[i].addr);
+
 		switch (boot_mem_map.map[i].type) {
 		case BOOT_MEM_RAM:
 			printk("(usable)\n");
@@ -498,7 +625,7 @@
 		c = *(from++);
 		if (!c)
 			break;
-		if (COMMAND_LINE_SIZE <= ++len)
+		if (CL_SIZE <= ++len)
 			break;
 		*(to++) = c;
 	}
@@ -514,19 +641,30 @@
 {
 	void atlas_setup(void);
 	void baget_setup(void);
+	void cobalt_setup(void);
 	void ddb_setup(void);
 	void decstation_setup(void);
 	void deskstation_setup(void);
 	void jazz_setup(void);
 	void sni_rm200_pci_setup(void);
-	void sgi_setup(void);
+	void ip22_setup(void);
         void ev96100_setup(void);
 	void malta_setup(void);
+	void ikos_setup(void);
 	void momenco_ocelot_setup(void);
 	void nino_setup(void);
+	void nec_osprey_setup(void);
+	void jmr3927_setup(void);
+ 	void it8172_setup(void);
+	void swarm_setup(void);
+	void hp_setup(void);
 
 	unsigned long bootmap_size;
-	unsigned long start_pfn, max_pfn, first_usable_pfn;
+	unsigned long start_pfn, max_pfn, max_low_pfn, first_usable_pfn;
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long tmp;
+	unsigned long* initrd_header;
+#endif
 
 	int i;
 
@@ -551,6 +689,11 @@
 		baget_setup();
 		break;
 #endif
+#ifdef CONFIG_MIPS_COBALT
+        case MACH_GROUP_COBALT:
+                cobalt_setup();
+                break;
+#endif
 #ifdef CONFIG_DECSTATION
 	case MACH_GROUP_DEC:
 		decstation_setup();
@@ -579,7 +722,7 @@
 #ifdef CONFIG_SGI_IP22
 	/* As of now this is only IP22.  */
 	case MACH_GROUP_SGI:
-		sgi_setup();
+		ip22_setup();
 		break;
 #endif
 #ifdef CONFIG_SNI_RM200_PCI
@@ -602,6 +745,11 @@
                ddb_setup();
                break;
 #endif
+#ifdef CONFIG_NEC_OSPREY
+	case MACH_GROUP_NEC_VR41XX:
+		nec_osprey_setup();
+		break;
+#endif
 #ifdef CONFIG_MIPS_EV96100
 	case MACH_GROUP_GALILEO:
 		ev96100_setup();
@@ -628,6 +776,26 @@
 		au1000_setup();
 		break;
 #endif
+#ifdef CONFIG_MIPS_PB1500
+	case MACH_GROUP_ALCHEMY:
+		au1500_setup();
+		break;
+#endif
+#ifdef CONFIG_TOSHIBA_JMR3927
+	case MACH_GROUP_TOSHIBA:
+		jmr3927_setup();
+		break;
+#endif
+#ifdef CONFIG_SIBYTE_SWARM
+	case MACH_GROUP_SIBYTE:
+		swarm_setup();
+		break;
+#endif
+#ifdef CONFIG_HP_LASERJET
+        case MACH_GROUP_HP_LJ:
+                hp_setup();
+                break;
+#endif
 	default:
 		panic("Unsupported architecture");
 	}
@@ -643,11 +811,26 @@
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
 
+#define MAXMEM		HIGHMEM_START
+#define MAXMEM_PFN	PFN_DOWN(MAXMEM)
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; 
+	if (tmp < (unsigned long)&_end) 
+		tmp += PAGE_SIZE;
+	initrd_header = (unsigned long *)tmp;
+	if (initrd_header[0] == 0x494E5244) {
+		initrd_start = (unsigned long)&initrd_header[2];
+		initrd_end = initrd_start + initrd_header[1];
+	}
+	start_pfn = PFN_UP(__pa((&_end)+(initrd_end - initrd_start) + PAGE_SIZE));
+#else
 	/*
 	 * Partially used pages are not usable - thus
 	 * we are rounding upwards.
 	 */
 	start_pfn = PFN_UP(__pa(&_end));
+#endif	/* CONFIG_BLK_DEV_INITRD */
 
 	/* Find the highest page frame number we have available.  */
 	max_pfn = 0;
@@ -674,9 +857,36 @@
 			}
 		}
 	}
-	
-	/* Initialize the boot-time allocator.  */
-	bootmap_size = init_bootmem(first_usable_pfn, max_pfn);
+
+	/*
+	 * Determine low and high memory ranges
+	 */
+	max_low_pfn = max_pfn;
+	if (max_low_pfn > MAXMEM_PFN) {
+		max_low_pfn = MAXMEM_PFN;
+#ifndef CONFIG_HIGHMEM
+		/* Maximum memory usable is what is directly addressable */
+		printk(KERN_WARNING "Warning only %ldMB will be used.\n",
+		       MAXMEM>>20);
+		printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
+#endif
+	}
+
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * Crude, we really should make a better attempt at detecting
+	 * highstart_pfn
+	 */
+	highstart_pfn = highend_pfn = max_pfn;
+	if (max_pfn > MAXMEM_PFN) {
+		highstart_pfn = MAXMEM_PFN;
+		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+		       (highend_pfn - highstart_pfn) >> (20 - PAGE_SHIFT));
+	}
+#endif
+
+	/* Initialize the boot-time allocator with low memory only.  */
+	bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
 
 	/*
 	 * Register fully available low RAM pages with the bootmem allocator.
@@ -694,7 +904,7 @@
 		 * We are rounding up the start address of usable memory:
 		 */
 		curr_pfn = PFN_UP(boot_mem_map.map[i].addr);
-		if (curr_pfn >= max_pfn)
+		if (curr_pfn >= max_low_pfn)
 			continue;
 		if (curr_pfn < start_pfn)
 			curr_pfn = start_pfn;
@@ -705,8 +915,19 @@
 		last_pfn = PFN_DOWN(boot_mem_map.map[i].addr
 				    + boot_mem_map.map[i].size);
 
-		if (last_pfn > max_pfn)
-			last_pfn = max_pfn;
+		if (last_pfn > max_low_pfn)
+			last_pfn = max_low_pfn;
+
+		/*
+		 * Only register lowmem part of lowmem segment with bootmem.
+		 */
+		size = last_pfn - curr_pfn;
+		if (curr_pfn > PFN_DOWN(HIGHMEM_START))
+			continue;
+		if (curr_pfn + size - 1 > PFN_DOWN(HIGHMEM_START))
+			size = PFN_DOWN(HIGHMEM_START) - curr_pfn;
+		if (!size)
+			continue;
 
 		/*
 		 * ... finally, did all the rounding and playing
@@ -715,7 +936,7 @@
 		if (last_pfn <= curr_pfn)
 			continue;
 
-		size = last_pfn - curr_pfn;
+		/* Register lowmem ranges */
 		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
 	}
 
@@ -725,7 +946,7 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Board specific code should have set up initrd_start and initrd_end */
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	if( __rd_start != __rd_end ) {
+	if (&__rd_start != &__rd_end) {
 		initrd_start = (unsigned long)&__rd_start;
 		initrd_end = (unsigned long)&__rd_end;
 	}
@@ -757,6 +978,7 @@
 	 */
 	for (i = 0; i < boot_mem_map.nr_map; i++) {
 		struct resource *res;
+		unsigned long addr_pfn, end_pfn;
 
 		res = alloc_bootmem(sizeof(struct resource));
 		switch (boot_mem_map.map[i].type) {
@@ -768,8 +990,16 @@
 		default:
 			res->name = "reserved";
 		}
+		addr_pfn = PFN_UP(boot_mem_map.map[i].addr);
+		end_pfn = PFN_UP(boot_mem_map.map[i].addr+boot_mem_map.map[i].size);
+		if (addr_pfn > max_low_pfn)
+			continue;
 		res->start = boot_mem_map.map[i].addr;
-		res->end = res->start + boot_mem_map.map[i].size - 1;
+		if (end_pfn < max_low_pfn) {
+			res->end = res->start + boot_mem_map.map[i].size - 1;
+		} else {
+			res->end = max_low_pfn - 1;
+		}
 		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 		request_resource(&iomem_resource, res);
 
@@ -789,9 +1019,22 @@
 	write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
 }
 
+void r39xx_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT);
+}
+
 void r4k_wait(void)
 {
 	__asm__(".set\tmips3\n\t"
 		"wait\n\t"
 		".set\tmips0");
 }
+
+static int __init fpu_disable(char *s)
+{
+	mips_cpu.options &= ~MIPS_CPU_FPU;
+	return 1;
+}
+__setup("nofpu", fpu_disable);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/signal.c linux/arch/mips/kernel/signal.c
--- linux.orig/arch/mips/kernel/signal.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/signal.c	2002-07-20 01:08:39.000000000 +0000
@@ -13,6 +13,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/kernel.h>
+#include <linux/personality.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
@@ -21,6 +22,7 @@
 
 #include <asm/asm.h>
 #include <asm/bitops.h>
+#include <asm/cpu.h>
 #include <asm/pgalloc.h>
 #include <asm/stackframe.h>
 #include <asm/uaccess.h>
@@ -76,8 +78,7 @@
  * Atomically swap in the new signal mask, and wait for a signal.
  */
 save_static_function(sys_sigsuspend);
-static_unused int
-_sys_sigsuspend(struct pt_regs regs)
+static_unused int _sys_sigsuspend(struct pt_regs regs)
 {
 	sigset_t *uset, saveset, newset;
 
@@ -102,10 +103,8 @@
 	}
 }
 
-
 save_static_function(sys_rt_sigsuspend);
-static_unused int
-_sys_rt_sigsuspend(struct pt_regs regs)
+static_unused int _sys_rt_sigsuspend(struct pt_regs regs)
 {
 	sigset_t *unewset, saveset, newset;
         size_t sigsetsize;
@@ -136,8 +135,8 @@
 	}
 }
 
-asmlinkage int 
-sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
+asmlinkage int sys_sigaction(int sig, const struct sigaction *act,
+	struct sigaction *oact)
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
@@ -177,8 +176,7 @@
 	return ret;
 }
 
-asmlinkage int
-sys_sigaltstack(struct pt_regs regs)
+asmlinkage int sys_sigaltstack(struct pt_regs regs)
 {
 	const stack_t *uss = (const stack_t *) regs.regs[4];
 	stack_t *uoss = (stack_t *) regs.regs[5];
@@ -187,8 +185,57 @@
 	return do_sigaltstack(uss, uoss, usp);
 }
 
-asmlinkage int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+static inline int restore_thread_fp_context(struct sigcontext *sc)
+{
+	u64 *pfreg = &current->thread.fpu.soft.regs[0];
+	int err = 0;
+
+	/* 
+	 * Copy all 32 64-bit values, for two reasons.  First, the R3000 and
+	 * R4000/MIPS32 kernels use the thread FP register storage differently,
+	 * such that a full copy is essentially necessary to support both.
+	 */
+
+#define restore_fpr(i) 						\
+	do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0)
+
+	restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3);
+	restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7);
+	restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11);
+	restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15);
+	restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19);
+	restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23);
+	restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27);
+	restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31);
+
+	err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
+
+	return err;
+}
+
+static inline int save_thread_fp_context(struct sigcontext *sc)
+{
+	u64 *pfreg = &current->thread.fpu.soft.regs[0];
+	int err = 0;
+
+#define save_fpr(i) 							\
+	do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0)
+
+	save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3);
+	save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7);
+	save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11);
+	save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15);
+	save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19);
+	save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23);
+	save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27);
+	save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31);
+
+	err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
+
+	return err;
+}
+
+static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
 	int owned_fp;
 	int err = 0;
@@ -204,7 +251,7 @@
 #define restore_gp_reg(i) do {						\
 	err |= __get_user(reg, &sc->sc_regs[i]);			\
 	regs->regs[i] = reg;						\
-} while(0);
+} while(0)
 	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
 	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
 	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
@@ -219,11 +266,24 @@
 #undef restore_gp_reg
 
 	err |= __get_user(owned_fp, &sc->sc_ownedfp);
+	err |= __get_user(current->used_math, &sc->sc_used_math);
+
 	if (owned_fp) {
 		err |= restore_fp_context(sc);
-		last_task_used_math = current;
+		goto out;
 	}
 
+	if (current == last_task_used_math) {
+		/* Signal handler acquired FPU - give it back */
+		last_task_used_math = NULL;
+		regs->cp0_status &= ~ST0_CU1;
+	}
+	if (current->used_math) {
+		/* Undo possible contamination of thread state */
+		err |= restore_thread_fp_context(sc);
+	}
+
+out:
 	return err;
 }
 
@@ -241,8 +301,7 @@
 	struct ucontext rs_uc;
 };
 
-asmlinkage void
-sys_sigreturn(struct pt_regs regs)
+asmlinkage void sys_sigreturn(struct pt_regs regs)
 {
 	struct sigframe *frame;
 	sigset_t blocked;
@@ -278,8 +337,7 @@
 	force_sig(SIGSEGV, current);
 }
 
-asmlinkage void
-sys_rt_sigreturn(struct pt_regs regs)
+asmlinkage void sys_rt_sigreturn(struct pt_regs regs)
 {
 	struct rt_sigframe *frame;
 	sigset_t set;
@@ -320,21 +378,21 @@
 	force_sig(SIGSEGV, current);
 }
 
-static int inline
-setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+static int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
 	int owned_fp;
 	int err = 0;
 	u64 reg;
 
-	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	reg = regs->cp0_epc; err |= __put_user(reg, &sc->sc_pc);
 	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
 #define save_gp_reg(i) {						\
 	reg = regs->regs[i];						\
 	err |= __put_user(reg, &sc->sc_regs[i]);			\
 } while(0)
-	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+	reg = 0; err |= __put_user(reg, &sc->sc_regs[0]);
+	save_gp_reg(1); save_gp_reg(2);
 	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
 	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
 	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
@@ -345,36 +403,53 @@
 	save_gp_reg(31);
 #undef save_gp_reg
 
-	err |= __put_user(regs->hi, &sc->sc_mdhi);
-	err |= __put_user(regs->lo, &sc->sc_mdlo);
+	reg = regs->hi; err |= __put_user(reg, &sc->sc_mdhi);
+	reg = regs->lo; err |= __put_user(reg, &sc->sc_mdlo);
 	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
 	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
 
 	owned_fp = (current == last_task_used_math);
 	err |= __put_user(owned_fp, &sc->sc_ownedfp);
+	err |= __put_user(current->used_math, &sc->sc_used_math);
 
-	if (current->used_math) {	/* fp is active.  */
-		set_cp0_status(ST0_CU1);
+	if (!current->used_math)
+		goto out;
+
+	/* There exists FP thread state that may be trashed by signal */
+	if (owned_fp) {	
+		/* fp is active.  Save context from FPU */
 		err |= save_fp_context(sc);
-		last_task_used_math = NULL;
-		regs->cp0_status &= ~ST0_CU1;
-		current->used_math = 0;
+		goto out;
 	}
 
+	/* 
+	 * Someone else has FPU. 
+	 * Copy Thread context into signal context 
+	 */
+	err |= save_thread_fp_context(sc);
+
+out:
 	return err;
 }
 
 /*
  * Determine which stack to use..
  */
-static inline void *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+	size_t frame_size)
 {
 	unsigned long sp;
 
 	/* Default to using normal stack */
 	sp = regs->regs[29];
 
+	/* 
+ 	 * FPU emulator may have it's own trampoline active just
+ 	 * above the user stack, 16-bytes before the next lowest
+ 	 * 16 byte boundary.  Try to avoid trashing it.
+ 	 */
+ 	sp -= 32;
+
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
                 sp = current->sas_ss_sp + current->sas_ss_size;
@@ -382,9 +457,8 @@
 	return (void *)((sp - frame_size) & ALMASK);
 }
 
-static void inline
-setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-            int signr, sigset_t *set)
+static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+	int signr, sigset_t *set)
 {
 	struct sigframe *frame;
 	int err = 0;
@@ -445,9 +519,8 @@
 	force_sig(SIGSEGV, current);
 }
 
-static void inline
-setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-               int signr, sigset_t *set, siginfo_t *info)
+static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+	int signr, sigset_t *set, siginfo_t *info)
 {
 	struct rt_sigframe *frame;
 	int err = 0;
@@ -521,8 +594,7 @@
 	force_sig(SIGSEGV, current);
 }
 
-static inline void
-handle_signal(unsigned long sig, struct k_sigaction *ka,
+static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
 	siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 {
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -541,8 +613,7 @@
 	}
 }
 
-static inline void
-syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 {
 	switch(regs->regs[0]) {
 	case ERESTARTNOHAND:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/smp.c linux/arch/mips/kernel/smp.c
--- linux.orig/arch/mips/kernel/smp.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/mips/kernel/smp.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,11 +1,4 @@
 /*
- *
- *  arch/mips/kernel/smp.c
- *
- *  Copyright (C) 2000 Sibyte
- * 
- *  Written by Justin Carlson (carlson@sibyte.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
@@ -20,20 +13,24 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
+ * Copyright (C) 2000, 2001 Kanoj Sarcar
+ * Copyright (C) 2000, 2001 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2000, 2001 Broadcom Corporation
  */ 
-
-
-#include <linux/config.h>
+#include <linux/cache.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/threads.h>
 #include <linux/time.h>
+#include <linux/module.h>
 #include <linux/timex.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
-#include <linux/cache.h>
+#include <linux/mm.h>
 
 #include <asm/atomic.h>
+#include <asm/cpu.h>
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/hardirq.h>
@@ -42,38 +39,29 @@
 #include <asm/delay.h>
 #include <asm/smp.h>
 
-/*
- * This was written with the BRCM12500 MP SOC in mind, but tries to
- * be generic.  It's modelled on the mips64 smp.c code, which is
- * derived from Sparc, I'm guessing, which is derived from...
- * 
- * It's probably horribly designed for very large ccNUMA systems
- * as it doesn't take any node clustering into account.  
-*/
-
-
 /* Ze Big Kernel Lock! */
 spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
-int smp_threads_ready;  /* Not used */
-int smp_num_cpus;    
-int global_irq_holder = NO_PROC_ID;
-spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
-struct mips_cpuinfo cpu_data[NR_CPUS];
-
-struct smp_fn_call_struct smp_fn_call = 
-{ SPIN_LOCK_UNLOCKED, ATOMIC_INIT(0), NULL, NULL};
+int smp_threads_ready;
+atomic_t smp_commenced = ATOMIC_INIT(0);
+int smp_num_cpus = 1;			/* Number that came online.  */
+cpumask_t cpu_online_map;		/* Bitmask of currently online CPUs */
+int __cpu_number_map[NR_CPUS];
+int __cpu_logical_map[NR_CPUS];
+struct cpuinfo_mips cpu_data[NR_CPUS];
+void (*volatile smp_cpu0_finalize)(void);
 
-static atomic_t cpus_booted = ATOMIC_INIT(0);
+// static atomic_t cpus_booted = ATOMIC_INIT(0);
+atomic_t cpus_booted = ATOMIC_INIT(0);
 
 
 /* These are defined by the board-specific code. */
 
-/* Cause the function described by smp_fn_call 
-   to be executed on the passed cpu.  When the function
-   has finished, increment the finished field of
-   smp_fn_call. */
-
-void core_call_function(int cpu);
+/*
+ * Cause the function described by call_data to be executed on the passed
+ * cpu.  When the function has finished, increment the finished field of
+ * call_data.
+ */
+void core_send_ipi(int cpu, unsigned int action);
 
 /*
  * Clear all undefined state in the cpu, set up sp and gp to the passed
@@ -85,108 +73,54 @@
  *  After we've done initial boot, this function is called to allow the
  *  board code to clean up state, if needed 
  */
-
 void prom_init_secondary(void);
 
-
-void cpu_idle(void);
-
-/* Do whatever setup needs to be done for SMP at the board level.  Return
-   the number of cpus in the system, including this one */
+/*
+ * Do whatever setup needs to be done for SMP at the board level.  Return
+ * the number of cpus in the system, including this one
+ */
 int prom_setup_smp(void);
 
-int start_secondary(void *unused)
+/*
+ * Hook for doing final board-specific setup after the generic smp setup
+ * is done
+ */
+asmlinkage void start_secondary(void)
 {
+	unsigned int cpu = smp_processor_id();
+
 	prom_init_secondary();
-	write_32bit_cp0_register(CP0_CONTEXT, smp_processor_id()<<23);
-	current_pgd[smp_processor_id()] = init_mm.pgd;
+	per_cpu_trap_init();
+
+	/*
+	 * XXX parity protection should be folded in here when it's converted
+	 * to an option instead of something based on .cputype
+	 */
+
+	pgd_current[cpu] = init_mm.pgd;
+	cpu_data[cpu].udelay_val = loops_per_jiffy;
+	prom_smp_finish();
 	printk("Slave cpu booted successfully\n");
+	CPUMASK_SETB(cpu_online_map, cpu);
 	atomic_inc(&cpus_booted);
+	while (!atomic_read(&smp_commenced));
 	cpu_idle();
-	return 0;
-}
-
-void __init smp_boot_cpus(void)
-{
-	int i;
-
-	smp_num_cpus = prom_setup_smp();
-	init_new_context(current, &init_mm);
-	current->processor = 0;
-	atomic_set(&cpus_booted, 1);  /* Master CPU is already booted... */
-	init_idle();
-	for (i = 1; i < smp_num_cpus; i++) {
-		struct task_struct *p;
-		struct pt_regs regs;
-		printk("Starting CPU %d... ", i);
-
-		/* Spawn a new process normally.  Grab a pointer to
-		   its task struct so we can mess with it */
-		do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
-		p = init_task.prev_task;
-
-		/* Schedule the first task manually */
-		p->processor = i;
-		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
-
-		/* Attach to the address space of init_task. */
-		atomic_inc(&init_mm.mm_count);
-		p->active_mm = &init_mm;
-		init_tasks[i] = p;
-
-		del_from_runqueue(p);
-		unhash_process(p);
-
-		prom_boot_secondary(i,
-				    (unsigned long)p + KERNEL_STACK_SIZE - 32,
-				    (unsigned long)p);
-
-#if 0
-
-		/* This is copied from the ip-27 code in the mips64 tree */
-
-		struct task_struct *p;
-
-		/*
-		 * The following code is purely to make sure
-		 * Linux can schedule processes on this slave.
-		 */
-		kernel_thread(0, NULL, CLONE_PID);
-		p = init_task.prev_task;
-		sprintf(p->comm, "%s%d", "Idle", i);
-		init_tasks[i] = p;
-		p->processor = i;
-		p->cpus_runnable = 1 << i; /* we schedule the first task manually *
-		del_from_runqueue(p);
-		unhash_process(p);
-		/* Attach to the address space of init_task. */
-		atomic_inc(&init_mm.mm_count);
-		p->active_mm = &init_mm;
-		prom_boot_secondary(i, 
-				    (unsigned long)p + KERNEL_STACK_SIZE - 32,
-				    (unsigned long)p);
-#endif
-	}
-
-	/* Wait for everyone to come up */
-	while (atomic_read(&cpus_booted) != smp_num_cpus);
 }
 
 void __init smp_commence(void)
 {
-	/* Not sure what to do here yet */
+	wmb();
+	atomic_set(&smp_commenced, 1);
 }
 
-static void reschedule_this_cpu(void *dummy)
+void smp_send_reschedule(int cpu)
 {
-	current->need_resched = 1;
+	core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);
 }
 
-void FASTCALL(smp_send_reschedule(int cpu))
-{
-	smp_call_function(reschedule_this_cpu, NULL, 0, 0);
-}
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
 
+struct call_data_struct *call_data;
 
 /*
  * The caller of this wants the passed function to run on every cpu.  If wait
@@ -196,43 +130,76 @@
 int smp_call_function (void (*func) (void *info), void *info, int retry, 
 								int wait)
 {
-	int cpus = smp_num_cpus - 1;
-	int i;
+	struct call_data_struct data;
+	int i, cpus = smp_num_cpus - 1;
+	int cpu = smp_processor_id();
 
-	if (smp_num_cpus < 2) {
+	if (!cpus)
 		return 0;
-	}
 
-	spin_lock_bh(&smp_fn_call.lock);
+	data.func = func;
+	data.info = info;
+	atomic_set(&data.started, 0);
+	data.wait = wait;
+	if (wait)
+		atomic_set(&data.finished, 0);
+
+	spin_lock(&call_lock);
+	call_data = &data;
+
+	/* Send a message to all other CPUs and wait for them to respond */
+	for (i = 0; i < smp_num_cpus; i++)
+		if (i != cpu)
+			core_send_ipi(i, SMP_CALL_FUNCTION);
+
+	/* Wait for response */
+	/* FIXME: lock-up detection, backtrace on lock-up */
+	while (atomic_read(&data.started) != cpus)
+		barrier();
+
+	if (wait)
+		while (atomic_read(&data.finished) != cpus)
+			barrier();
+	spin_unlock(&call_lock);
 
-	atomic_set(&smp_fn_call.finished, 0);
-	smp_fn_call.fn = func;
-	smp_fn_call.data = info;
-
-	for (i = 0; i < smp_num_cpus; i++) {
-		if (i != smp_processor_id()) {
-			/* Call the board specific routine */
-			core_call_function(i);
-		}
-	}
-
-	if (wait) {
-		while(atomic_read(&smp_fn_call.finished) != cpus) {}
-	}
-
-	spin_unlock_bh(&smp_fn_call.lock);
 	return 0;
 }
 
-void synchronize_irq(void)
+void smp_call_function_interrupt(void)
 {
-	panic("synchronize_irq");
+	void (*func) (void *info) = call_data->func;
+	void *info = call_data->info;
+	int wait = call_data->wait;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, 0);	/* XXX choose an irq number? */
+	/*
+	 * Notify initiating CPU that I've grabbed the data
+	 * and am about to execute the function
+	 */
+	mb();
+	atomic_inc(&call_data->started);
+
+	/*
+	 * At this point the info structure may be out of scope unless wait==1
+	 */
+	(*func)(info);
+	if (wait) {
+		mb();
+		atomic_inc(&call_data->finished);
+	}
+	irq_exit(cpu, 0);	/* XXX choose an irq number? */
 }
 
 static void stop_this_cpu(void *dummy)
 {
-	printk("Cpu stopping\n");
-	for (;;);
+	int cpu = smp_processor_id();
+	if (cpu)
+		for (;;);		/* XXX Use halt like i386 */
+
+	/* XXXKW this isn't quite there yet */
+	while (!smp_cpu0_finalize) ;
+	smp_cpu0_finalize();
 }
 
 void smp_send_stop(void)
@@ -247,157 +214,110 @@
 	return 0;
 }
 
+static void flush_tlb_all_ipi(void *info)
+{
+	local_flush_tlb_all();
+}
 
-/*
- * Most of this code is take from the mips64 tree (ip27-irq.c).  It's virtually
- * identical to the i386 implentation in arh/i386/irq.c, with translations for
- * the interrupt enable bit
- */
-
-#define MAXCOUNT 		100000000
-#define SYNC_OTHER_CORES(x)	udelay(x+1)
+void flush_tlb_all(void)
+{
+	smp_call_function(flush_tlb_all_ipi, 0, 1, 1);
+	local_flush_tlb_all();
+}
 
-static inline void wait_on_irq(int cpu)
+static void flush_tlb_mm_ipi(void *mm)
 {
-	int count = MAXCOUNT;
+	local_flush_tlb_mm((struct mm_struct *)mm);
+}
 
-	for (;;) {
+/*
+ * The following tlb flush calls are invoked when old translations are 
+ * being torn down, or pte attributes are changing. For single threaded
+ * address spaces, a new context is obtained on the current cpu, and tlb
+ * context on other cpus are invalidated to force a new context allocation
+ * at switch_mm time, should the mm ever be used on other cpus. For 
+ * multithreaded address spaces, intercpu interrupts have to be sent.
+ * Another case where intercpu interrupts are required is when the target
+ * mm might be active on another cpu (eg debuggers doing the flushes on
+ * behalf of debugees, kswapd stealing pages from another process etc).
+ * Kanoj 07/00.
+ */
 
-		/*
-		 * Wait until all interrupts are gone. Wait
-		 * for bottom half handlers unless we're
-		 * already executing in one..
-		 */
-		if (!irqs_running())
-			if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
-				break;
-
-		/* Duh, we have to loop. Release the lock to avoid deadlocks */
-		spin_unlock(&global_irq_lock);
-
-		for (;;) {
-			if (!--count) {
-				printk("Count spun out.  Huh?\n");
-				count = ~0;
-			}
-			__sti();
-			SYNC_OTHER_CORES(cpu);
-			__cli();
-			if (irqs_running())
-				continue;
-			if (spin_is_locked(&global_irq_lock))
-				continue;
-			if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
-				continue;
-			if (spin_trylock(&global_irq_lock))
-				break;
-		}
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
+		smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1);
+	} else {
+		int i;
+		for (i = 0; i < smp_num_cpus; i++)
+			if (smp_processor_id() != i)
+				CPU_CONTEXT(i, mm) = 0;
 	}
+	local_flush_tlb_mm(mm);
 }
 
+struct flush_tlb_data {
+	struct mm_struct *mm;
+	struct vm_area_struct *vma;
+	unsigned long addr1;
+	unsigned long addr2;
+};
 
-static inline void get_irqlock(int cpu)
+static void flush_tlb_range_ipi(void *info)
 {
-	if (!spin_trylock(&global_irq_lock)) {
-		/* do we already hold the lock? */
-		if ((unsigned char) cpu == global_irq_holder)
-			return;
-		/* Uhhuh.. Somebody else got it. Wait.. */
-		spin_lock(&global_irq_lock);
-	}
-	/*
-	 * We also to make sure that nobody else is running
-	 * in an interrupt context.
-	 */
-	wait_on_irq(cpu);
+	struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
 
-	/*
-	 * Ok, finally..
-	 */
-	global_irq_holder = cpu;
+	local_flush_tlb_range(fd->mm, fd->addr1, fd->addr2);
 }
 
-
-/*
- * A global "cli()" while in an interrupt context
- * turns into just a local cli(). Interrupts
- * should use spinlocks for the (very unlikely)
- * case that they ever want to protect against
- * each other.
- *
- * If we already have local interrupts disabled,
- * this will not turn a local disable into a
- * global one (problems with spinlocks: this makes
- * save_flags+cli+sti usable inside a spinlock).
- */
-void __global_cli(void)
+void flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
 {
-	unsigned int flags;
+	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
+		struct flush_tlb_data fd;
 
-	__save_flags(flags);
-	if (flags & ST0_IE) {
-		int cpu = smp_processor_id();
-		__cli();
-		if (!local_irq_count(cpu))
-			get_irqlock(cpu);
+		fd.mm = mm;
+		fd.addr1 = start;
+		fd.addr2 = end;
+		smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1);
+	} else {
+		int i;
+		for (i = 0; i < smp_num_cpus; i++)
+			if (smp_processor_id() != i)
+				CPU_CONTEXT(i, mm) = 0;
 	}
+	local_flush_tlb_range(mm, start, end);
 }
 
-void __global_sti(void)
+static void flush_tlb_page_ipi(void *info)
 {
-	int cpu = smp_processor_id();
+	struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
 
-	if (!local_irq_count(cpu))
-		release_irqlock(cpu);
-	__sti();
+	local_flush_tlb_page(fd->vma, fd->addr1);
 }
 
-/*
- * SMP flags value to restore to:
- * 0 - global cli
- * 1 - global sti
- * 2 - local cli
- * 3 - local sti
- */
-unsigned long __global_save_flags(void)
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
-	int retval;
-	int local_enabled;
-	unsigned long flags;
-	int cpu = smp_processor_id();
+	if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) {
+		struct flush_tlb_data fd;
 
-	__save_flags(flags);
-	local_enabled = (flags & ST0_IE);
-	/* default to local */
-	retval = 2 + local_enabled;
-
-	/* check for global flags if we're not in an interrupt */
-	if (!local_irq_count(cpu)) {
-		if (local_enabled)
-			retval = 1;
-		if (global_irq_holder == cpu)
-			retval = 0;
+		fd.vma = vma;
+		fd.addr1 = page;
+		smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1);
+	} else {
+		int i;
+		for (i = 0; i < smp_num_cpus; i++)
+			if (smp_processor_id() != i)
+				CPU_CONTEXT(i, vma->vm_mm) = 0;
 	}
-
-	return retval;
+	local_flush_tlb_page(vma, page);
 }
 
-void __global_restore_flags(unsigned long flags)
-{
-	switch (flags) {
-		case 0:
-			__global_cli();
-			break;
-		case 1:
-			__global_sti();
-			break;
-		case 2:
-			__cli();
-			break;
-		case 3:
-			__sti();
-			break;
-		default:
-			printk("global_restore_flags: %08lx\n", flags);
-	}
-}
+EXPORT_SYMBOL(smp_num_cpus);
+EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(cpu_data);
+EXPORT_SYMBOL(synchronize_irq);
+EXPORT_SYMBOL(kernel_flag);
+EXPORT_SYMBOL(__global_sti);
+EXPORT_SYMBOL(__global_cli);
+EXPORT_SYMBOL(__global_save_flags);
+EXPORT_SYMBOL(__global_restore_flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/syscall.c linux/arch/mips/kernel/syscall.c
--- linux.orig/arch/mips/kernel/syscall.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/kernel/syscall.c	2002-07-20 01:08:29.000000000 +0000
@@ -14,6 +14,7 @@
 #undef CONF_DEBUG_IRIX
 
 #include <linux/config.h>
+#include <linux/compiler.h>
 #include <linux/linkage.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -28,7 +29,7 @@
 #include <asm/offset.h>
 #include <asm/ptrace.h>
 #include <asm/signal.h>
-#include <asm/stackframe.h>
+#include <asm/shmparam.h>
 #include <asm/uaccess.h>
 
 extern asmlinkage void syscall_trace(void);
@@ -54,6 +55,59 @@
 	return res;
 }
 
+#define COLOUR_ALIGN(addr,pgoff)		\
+	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
+	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct * vmm;
+	int do_color_align;
+
+	if (flags & MAP_FIXED) {
+		/*
+		 * We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+	do_color_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+	if (addr) {
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+		vmm = find_vma(current->mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vmm || addr + len <= vmm->vm_start))
+			return addr;
+	}
+	addr = TASK_UNMAPPED_BASE;
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
+		/* At this point:  (!vmm || addr < vmm->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vmm || addr + len <= vmm->vm_start)
+			return addr;
+		addr = vmm->vm_end;
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+	}
+}
+
 /* common code for old and new mmaps */
 static inline long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
@@ -82,7 +136,16 @@
 asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
                                   int flags, int fd, off_t offset)
 {
-	return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	int result;
+
+	result = -EINVAL;
+	if (offset & ~PAGE_MASK)
+		goto out;
+
+	result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+
+out:
+	return result;
 }
 
 asmlinkage long
@@ -175,76 +238,6 @@
 }
 
 /*
- * Do the indirect syscall syscall.
- * Don't care about kernel locking; the actual syscall will do it.
- *
- * XXX This is borken.
- */
-asmlinkage int sys_syscall(struct pt_regs regs)
-{
-	syscall_t syscall;
-	unsigned long syscallnr = regs.regs[4];
-	unsigned long a0, a1, a2, a3, a4, a5, a6;
-	int nargs, errno;
-
-	if (syscallnr > __NR_Linux + __NR_Linux_syscalls)
-		return -ENOSYS;
-
-	syscall = sys_call_table[syscallnr];
-	nargs = sys_narg_table[syscallnr];
-	/*
-	 * Prevent stack overflow by recursive
-	 * syscall(__NR_syscall, __NR_syscall,...);
-	 */
-	if (syscall == (syscall_t) sys_syscall) {
-		return -EINVAL;
-	}
-
-	if (syscall == NULL) {
-		return -ENOSYS;
-	}
-
-	if(nargs > 3) {
-		unsigned long usp = regs.regs[29];
-		unsigned long *sp = (unsigned long *) usp;
-		if(usp & 3) {
-			printk("unaligned usp -EFAULT\n");
-			force_sig(SIGSEGV, current);
-			return -EFAULT;
-		}
-		errno = verify_area(VERIFY_READ, (void *) (usp + 16),
-		                    (nargs - 3) * sizeof(unsigned long));
-		if(errno) {
-			return -EFAULT;
-		}
-		switch(nargs) {
-		case 7:
-			a3 = sp[4]; a4 = sp[5]; a5 = sp[6]; a6 = sp[7];
-			break;
-		case 6:
-			a3 = sp[4]; a4 = sp[5]; a5 = sp[6]; a6 = 0;
-			break;
-		case 5:
-			a3 = sp[4]; a4 = sp[5]; a5 = a6 = 0;
-			break;
-		case 4:
-			a3 = sp[4]; a4 = a5 = a6 = 0;
-			break;
-
-		default:
-			a3 = a4 = a5 = a6 = 0;
-			break;
-		}
-	} else {
-		a3 = a4 = a5 = a6 = 0;
-	}
-	a0 = regs.regs[5]; a1 = regs.regs[6]; a2 = regs.regs[7];
-	if(nargs == 0)
-		a0 = (unsigned long) &regs;
-	return syscall((void *)a0, a1, a2, a3, a4, a5, a6);
-}
-
-/*
  * If we ever come here the user sp is bad.  Zap the process right away.
  * Due to the bad stack signaling wouldn't work.
  * XXX kernel locking???
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/syscalls.h linux/arch/mips/kernel/syscalls.h
--- linux.orig/arch/mips/kernel/syscalls.h	2001-10-08 17:39:18.000000000 +0000
+++ linux/arch/mips/kernel/syscalls.h	2002-07-20 01:08:23.000000000 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001, 2002 by Ralf Baechle
  */
 
 /*
@@ -20,7 +20,7 @@
 SYS(sys_read, 3)
 SYS(sys_write, 3)
 SYS(sys_open, 3)				/* 4005 */
-SYS(sys_close, 3)
+SYS(sys_close, 1)
 SYS(sys_waitpid, 3)
 SYS(sys_creat, 2)
 SYS(sys_link, 2)
@@ -235,3 +235,23 @@
 SYS(sys_madvise, 3)
 SYS(sys_getdents64, 3)
 SYS(sys_fcntl64, 3)				/* 4220 */
+SYS(sys_ni_syscall, 0)
+SYS(sys_gettid, 0)
+SYS(sys_readahead, 5)
+SYS(sys_ni_syscall, 0)				/* reserved for setxattr */
+SYS(sys_ni_syscall, 0)				/* 4225 res. for lsetxattr */
+SYS(sys_ni_syscall, 0)				/* reserved for fsetxattr */
+SYS(sys_ni_syscall, 0)				/* reserved for getxattr */
+SYS(sys_ni_syscall, 0)				/* reserved for lgetxattr */
+SYS(sys_ni_syscall, 0)				/* reserved for fgetxattr */
+SYS(sys_ni_syscall, 0)				/* 4230 res. for listxattr */
+SYS(sys_ni_syscall, 0)				/* reserved for llistxattr */
+SYS(sys_ni_syscall, 0)				/* reserved for flistxattr */
+SYS(sys_ni_syscall, 0)				/* reserved for removexattr */
+SYS(sys_ni_syscall, 0)				/* reserved for lremovexattr */
+SYS(sys_ni_syscall, 0)				/* 4235 res. for fremovexattr */
+SYS(sys_tkill, 2)
+SYS(sys_ni_syscall, 0)				/* res. for sendfile64 */
+SYS(sys_ni_syscall, 0)				/* res. for futex */
+SYS(sys_ni_syscall, 0)				/* res. for sched_setaffinity */
+SYS(sys_ni_syscall, 0)				/* 4240 res. for sched_getaffinity */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c
--- linux.orig/arch/mips/kernel/sysirix.c	2001-08-12 22:05:26.000000000 +0000
+++ linux/arch/mips/kernel/sysirix.c	2002-07-20 01:08:33.000000000 +0000
@@ -1876,7 +1876,8 @@
 	return 0;
 }
 
-asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob)
+asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
+	unsigned int count, int *eob)
 {
 	struct file *file;
 	struct irix_dirent32 *lastdirent;
@@ -1900,6 +1901,7 @@
 	error = vfs_readdir(file, irix_filldir32, &buf);
 	if (error < 0)
 		goto out_putf;
+
 	error = buf.error;
 	lastdirent = buf.previous;
 	if (lastdirent) {
@@ -1908,11 +1910,10 @@
 	}
 
 	if (put_user(0, eob) < 0) {
-		error = EFAULT;
+		error = -EFAULT;
 		goto out_putf;
 	}
 
-
 #ifdef DEBUG_GETDENTS
 	printk("eob=%d returning %d\n", *eob, count - buf.count);
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/sysmips.c linux/arch/mips/kernel/sysmips.c
--- linux.orig/arch/mips/kernel/sysmips.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/kernel/sysmips.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,13 +1,11 @@
 /*
- * MIPS specific syscalls
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997, 2000 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/linkage.h>
 #include <linux/mm.h>
@@ -48,11 +46,10 @@
 }
 
 asmlinkage int
-sys_sysmips(int cmd, int arg1, int arg2, int arg3)
+_sys_sysmips(int cmd, int arg1, int arg2, int arg3)
 {
-	int	*p;
 	char	*name;
-	int	tmp, len, retval, errno;
+	int	tmp, len, retval;
 
 	switch(cmd) {
 	case SETNAME: {
@@ -74,55 +71,10 @@
 		return 0;
 	}
 
-	case MIPS_ATOMIC_SET: {
-#ifdef CONFIG_CPU_HAS_LLSC
-		unsigned int tmp;
-
-		p = (int *) arg1;
-		errno = verify_area(VERIFY_WRITE, p, sizeof(*p));
-		if (errno)
-			return errno;
-		errno = 0;
-
-		__asm__(".set\tpush\t\t\t# sysmips(MIPS_ATOMIC, ...)\n\t"
-			".set\tmips2\n\t"
-			".set\tnoat\n\t"
-			"1:\tll\t%0, %4\n\t"
-			"move\t$1, %3\n\t"
-			"2:\tsc\t$1, %1\n\t"
-			"beqz\t$1, 1b\n\t"
-			".set\tpop\n\t"
-			".section\t.fixup,\"ax\"\n"
-			"3:\tli\t%2, 1\t\t\t# error\n\t"
-			".previous\n\t"
-			".section\t__ex_table,\"a\"\n\t"
-			".word\t1b, 3b\n\t"
-			".word\t2b, 3b\n\t"
-			".previous\n\t"
-			: "=&r" (tmp), "=o" (* (u32 *) p), "=r" (errno)
-			: "r" (arg2), "o" (* (u32 *) p), "2" (errno)
-			: "$1");
-
-		if (errno)
-			return -EFAULT;
-
-		/* We're skipping error handling etc.  */
-		if (current->ptrace & PT_TRACESYS)
-			syscall_trace();
-
-		((struct pt_regs *)&cmd)->regs[2] = tmp;
-		((struct pt_regs *)&cmd)->regs[7] = 0;
-
-		__asm__ __volatile__(
-			"move\t$29, %0\n\t"
-			"j\to32_ret_from_sys_call"
-			: /* No outputs */
-			: "r" (&cmd));
-		/* Unreached */
-#else
-	printk("sys_sysmips(MIPS_ATOMIC_SET, ...) not ready for !CONFIG_CPU_HAS_LLSC\n");
-#endif
-	}
+	case MIPS_ATOMIC_SET:
+		printk(KERN_CRIT "How did I get here?\n");
+		retval = -EINVAL;
+		goto out;
 
 	case MIPS_FIXADE:
 		tmp = current->thread.mflags & ~3;
@@ -131,7 +83,7 @@
 		goto out;
 
 	case FLUSH_CACHE:
-		flush_cache_all();
+		__flush_cache_all();
 		retval = 0;
 		goto out;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c
--- linux.orig/arch/mips/kernel/time.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/time.c	2002-07-20 01:08:34.000000000 +0000
@@ -30,7 +30,7 @@
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
+#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ))
 
 /*
  * forward reference
@@ -39,6 +39,11 @@
 extern volatile unsigned long wall_jiffies;
 
 /*
+ * whether we emulate local_timer_interrupts for SMP machines.
+ */
+int emulate_local_timer_interrupt;
+
+/*
  * By default we provide the null RTC ops
  */
 static unsigned long null_rtc_get_time(void)
@@ -255,8 +260,7 @@
 	        :"r" (timerhi),
 	         "m" (timerlo),
 	         "r" (tmp),
-	         "r" (USECS_PER_JIFFY)
-	        :"$1");
+	         "r" (USECS_PER_JIFFY));
 	        cached_quotient = quotient;
 	}
 
@@ -284,6 +288,42 @@
 
 
 /*
+ * local_timer_interrupt() does profiling and process accounting
+ * on a per-CPU basis.  
+ *
+ * In UP mode, it is invoked from the (global) timer_interrupt.  
+ *
+ * In SMP mode, it might invoked by per-CPU timer interrupt, or
+ * a broadcasted inter-processor interrupt which itself is triggered
+ * by the global timer interrupt.
+ */
+void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (!user_mode(regs)) {
+		if (prof_buffer && current->pid) {
+			extern int _stext;
+			unsigned long pc = regs->cp0_epc;
+
+			pc -= (unsigned long) &_stext;
+			pc >>= prof_shift;
+			/*
+			 * Dont ignore out-of-bounds pc values silently,
+			 * put them into the last histogram slot, so if
+			 * present, they will show up as a sharp peak.
+			 */
+			if (pc > prof_len-1)
+			pc = prof_len-1;
+			atomic_inc((atomic_t *)&prof_buffer[pc]);
+		}
+	}
+
+#ifdef CONFIG_SMP
+	/* in UP mode, update_process_times() is invoked by do_timer() */
+	update_process_times(user_mode(regs));
+#endif
+}
+
+/*
  * high-level timer interrupt service routines.  This function
  * is set as irqaction->handler and is invoked through do_IRQ.
  */
@@ -310,24 +350,6 @@
 
 	}
 
-	if(!user_mode(regs)) {
-		if (prof_buffer && current->pid) {
-			extern int _stext;
-			unsigned long pc = regs->cp0_epc;
-
-			pc -= (unsigned long) &_stext;
-			pc >>= prof_shift;
-			/*
-			 * Dont ignore out-of-bounds pc values silently,
-			 * put them into the last histogram slot, so if
-			 * present, they will show up as a sharp peak.
-			 */
-			if (pc > prof_len-1)
-			pc = prof_len-1;
-			atomic_inc((atomic_t *)&prof_buffer[pc]);
-		}
-	}
-
 	/*
 	 * call the generic timer interrupt handling
 	 */
@@ -360,6 +382,31 @@
 	if (!jiffies) {
 		timerhi = timerlo = 0;
 	}
+
+#if !defined(CONFIG_SMP)
+	/* 
+	 * In UP mode, we call local_timer_interrupt() to do profiling
+	 * and process accouting.  
+	 *
+	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
+	 * low-level local timer interrupt handler.
+	 */
+	local_timer_interrupt(0, NULL, regs);
+
+#else	/* CONFIG_SMP */
+
+	if (emulate_local_timer_interrupt) {
+		/* 
+		 * this is the place where we send out inter-process
+		 * interrupts and let each CPU do its own profiling
+		 * and process accouting.
+		 *
+		 * Obviously we need to call local_timer_interrupt() for
+		 * the current CPU too.
+		 */
+		panic("Not implemented yet!!!");
+	}
+#endif	/* CONFIG_SMP */
 }
 
 asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)
@@ -378,6 +425,21 @@
 		do_softirq();
 }
 
+asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+
+	/* we keep interrupt disabled all the time */
+	local_timer_interrupt(irq, NULL, regs);
+	
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+}
 
 /*
  * time_init() - it does the following things.
@@ -407,7 +469,8 @@
 	0,
 	"timer",
 	NULL,
-	NULL};
+	NULL
+};
 
 void __init time_init(void)
 {
@@ -475,10 +538,10 @@
 
 void to_tm(unsigned long tim, struct rtc_time * tm)
 {
-	long hms, day;
+	long hms, day, gday;
 	int i;
 
-	day = tim / SECDAY;
+	gday = day = tim / SECDAY;
 	hms = tim % SECDAY;
 
 	/* Hours, minutes, seconds are easy */
@@ -497,7 +560,7 @@
 	for (i = 1; day >= days_in_month(i); i++)
 	day -= days_in_month(i);
 	days_in_month(FEBRUARY) = 28;
-	tm->tm_mon = i;
+	tm->tm_mon = i-1;	/* tm_mon starts from 0 to 11 */
 
 	/* Days are what is left over (+1) from all that. */
 	tm->tm_mday = day + 1;
@@ -505,5 +568,5 @@
 	/*
 	 * Determine the day of week
 	 */
-	tm->tm_wday = (day + 3) % 7;
+	tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c
--- linux.orig/arch/mips/kernel/traps.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/traps.c	2002-07-20 01:08:34.000000000 +0000
@@ -10,6 +10,7 @@
  *
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -32,6 +33,7 @@
 #include <asm/siginfo.h>
 #include <asm/watch.h>
 #include <asm/system.h>
+#include <asm/traps.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 
@@ -66,8 +68,7 @@
 
 char watch_available = 0;
 
-void (*ibe_board_handler)(struct pt_regs *regs);
-void (*dbe_board_handler)(struct pt_regs *regs);
+int (*be_board_handler)(struct pt_regs *regs, int is_fixup);
 
 int kstack_depth_to_print = 24;
 
@@ -77,12 +78,9 @@
  */
 #define MODULE_RANGE (8*1024*1024)
 
-#ifndef CONFIG_CPU_HAS_LLSC
 /*
  * This stuff is needed for the userland ll-sc emulation for R2300
  */
-void simulate_ll(struct pt_regs *regs, unsigned int opcode);
-void simulate_sc(struct pt_regs *regs, unsigned int opcode);
 
 #define OPCODE 0xfc000000
 #define BASE   0x03e00000
@@ -90,8 +88,97 @@
 #define OFFSET 0x0000ffff
 #define LL     0xc0000000
 #define SC     0xe0000000
+
+/*
+ * The ll_bit is cleared by r*_switch.S
+ */
+
+unsigned long ll_bit;
+#ifdef CONFIG_PROC_FS
+extern unsigned long ll_ops;
+extern unsigned long sc_ops;
+#endif
+
+static struct task_struct *ll_task = NULL;
+
+static inline void simulate_ll(struct pt_regs *regp, unsigned int opcode)
+{
+	unsigned long value, *vaddr;
+	long offset;
+	int signal = 0;
+
+	/*
+	 * analyse the ll instruction that just caused a ri exception
+	 * and put the referenced address to addr.
+	 */
+
+	/* sign extend offset */
+	offset = opcode & OFFSET;
+	offset <<= 16;
+	offset >>= 16;
+
+	vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset);
+
+#ifdef CONFIG_PROC_FS
+	ll_ops++;
+#endif
+
+	if ((unsigned long)vaddr & 3)
+		signal = SIGBUS;
+	else if (get_user(value, vaddr))
+		signal = SIGSEGV;
+	else {
+		if (ll_task == NULL || ll_task == current) {
+			ll_bit = 1;
+		} else {
+			ll_bit = 0;
+		}
+		ll_task = current;
+		regp->regs[(opcode & RT) >> 16] = value;
+	}
+	if (compute_return_epc(regp))
+		return;
+	if (signal)
+		send_sig(signal, current, 1);
+}
+
+static inline void simulate_sc(struct pt_regs *regp, unsigned int opcode)
+{
+	unsigned long *vaddr, reg;
+	long offset;
+	int signal = 0;
+
+	/*
+	 * analyse the sc instruction that just caused a ri exception
+	 * and put the referenced address to addr.
+	 */
+
+	/* sign extend offset */
+	offset = opcode & OFFSET;
+	offset <<= 16;
+	offset >>= 16;
+
+	vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset);
+	reg = (opcode & RT) >> 16;
+
+#ifdef CONFIG_PROC_FS
+	sc_ops++;
 #endif
 
+	if ((unsigned long)vaddr & 3)
+		signal = SIGBUS;
+	else if (ll_bit == 0 || ll_task != current)
+		regp->regs[reg] = 0;
+	else if (put_user(regp->regs[reg], vaddr))
+		signal = SIGSEGV;
+	else
+		regp->regs[reg] = 1;
+	if (compute_return_epc(regp))
+		return;
+	if (signal)
+		send_sig(signal, current, 1);
+}
+
 /*
  * This routine abuses get_user()/put_user() to reference pointers
  * with at least a bit of error checking ...
@@ -101,7 +188,7 @@
 	int i;
 	unsigned int *stack;
 
-	stack = sp;
+	stack = sp ? sp : (unsigned int *)&sp;
 	i = 0;
 
 	printk("Stack:");
@@ -128,12 +215,13 @@
 void show_trace(unsigned int *sp)
 {
 	int i;
+	int column = 0;
 	unsigned int *stack;
 	unsigned long kernel_start, kernel_end;
 	unsigned long module_start, module_end;
 	extern char _stext, _etext;
 
-	stack = sp;
+	stack = sp ? sp : (unsigned int *) &sp;
 	i = 0;
 
 	kernel_start = (unsigned long) &_stext;
@@ -164,12 +252,23 @@
 		    (addr >= module_start && addr < module_end)) { 
 
 			printk(" [<%08lx>]", addr);
+			if (column++ == 5) {
+				printk("\n");
+				column = 0;
+			}
 			if (++i > 40) {
 				printk(" ...");
 				break;
 			}
 		}
 	}
+	if (column != 0)
+		printk("\n");
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	show_trace((unsigned int *)tsk->thread.reg29);
 }
 
 void show_code(unsigned int *pc)
@@ -188,17 +287,36 @@
 	}
 }
 
-spinlock_t die_lock;
+void show_regs(struct pt_regs * regs)
+{
+	/*
+	 * Saved main processor registers
+	 */
+	printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+	       0,             regs->regs[1], regs->regs[2], regs->regs[3],
+	       regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+	       regs->regs[8],  regs->regs[9],  regs->regs[10], regs->regs[11],
+               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19],
+               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk("$24: %08lx %08lx                   %08lx %08lx %08lx %08lx\n",
+	       regs->regs[24], regs->regs[25],
+	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+	printk("Hi : %08lx\n", regs->hi);
+	printk("Lo : %08lx\n", regs->lo);
 
-extern void __die(const char * str, struct pt_regs * regs, const char *where,
-                  unsigned long line)
+	/*
+	 * Saved cp0 registers
+	 */
+	printk("epc  : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, print_tainted(), regs->cp0_status,
+	       regs->cp0_cause);
+}
+
+void show_registers(struct pt_regs *regs)
 {
-	console_verbose();
-	spin_lock_irq(&die_lock);
-	printk("%s", str);
-	if (where)
-		printk(" in %s, line %ld", where, line);
-	printk(":\n");
 	show_regs(regs);
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, (unsigned long) current);
@@ -206,6 +324,20 @@
 	show_trace((unsigned int *) regs->regs[29]);
 	show_code((unsigned int *) regs->cp0_epc);
 	printk("\n");
+}
+
+static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+
+void __die(const char * str, struct pt_regs * regs, const char *where,
+           unsigned long line)
+{
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	printk("%s", str);
+	if (where)
+		printk(" in %s, line %ld", where, line);
+	printk(":\n");
+	show_registers(regs);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
@@ -286,20 +418,35 @@
 #endif
 }
 
-static void default_be_board_handler(struct pt_regs *regs)
+asmlinkage void do_be(struct pt_regs *regs)
 {
 	unsigned long new_epc;
-	unsigned long fixup;
+	unsigned long fixup = 0;
 	int data = regs->cp0_cause & 4;
+	int action = MIPS_BE_FATAL;
 
-	if (data && !user_mode(regs)) {
+	if (data && !user_mode(regs))
 		fixup = search_dbe_table(regs->cp0_epc);
+
+	if (fixup)
+		action = MIPS_BE_FIXUP;
+
+	if (be_board_handler)
+		action = be_board_handler(regs, fixup != 0);
+
+	switch (action) {
+	case MIPS_BE_DISCARD:
+		return;
+	case MIPS_BE_FIXUP:
 		if (fixup) {
 			new_epc = fixup_exception(dpf_reg, fixup,
 						  regs->cp0_epc);
 			regs->cp0_epc = new_epc;
 			return;
 		}
+		break;
+	default:
+		break;
 	}
 
 	/*
@@ -312,16 +459,6 @@
 	force_sig(SIGBUS, current);
 }
 
-asmlinkage void do_ibe(struct pt_regs *regs)
-{
-	ibe_board_handler(regs);
-}
-
-asmlinkage void do_dbe(struct pt_regs *regs)
-{
-	dbe_board_handler(regs);
-}
-
 asmlinkage void do_ov(struct pt_regs *regs)
 {
 	if (compute_return_epc(regs))
@@ -356,26 +493,31 @@
 		sig = fpu_emulator_cop1Handler(regs);
 
 		/* 
-		 * We can't allow the emulated instruction to leave the
-		 * Unimplemented Operation bit set in $fcr31.
+		 * We can't allow the emulated instruction to leave any of 
+		 * the cause bit set in $fcr31.
 		 */
-		current->thread.fpu.soft.sr &= ~FPU_CSR_UNI_X;
+		current->thread.fpu.soft.sr &= ~FPU_CSR_ALL_X;
 
 		/* Restore the hardware register state */
 		restore_fp(current);
 
 		/* If something went wrong, signal */
 		if (sig)
+		{
+			/* 
+			 * Return EPC is not calculated in the FPU emulator, 
+			 * if a signal is being send. So we calculate it here.
+			 */
+			compute_return_epc(regs);
 			force_sig(sig, current);
+		}
 
 		return;
 	}
 
 	if (compute_return_epc(regs))
 		return;
-
 	force_sig(SIGFPE, current);
-	printk(KERN_DEBUG "Sent send SIGFPE to %s\n", current->comm);
 }
 
 static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
@@ -424,7 +566,7 @@
 			info.si_code = FPE_INTOVF;
 		info.si_signo = SIGFPE;
 		info.si_errno = 0;
-		info.si_addr = (void *)compute_return_epc(regs);
+		info.si_addr = (void *)regs->cp0_epc;
 		force_sig_info(SIGFPE, &info, current);
 		break;
 	default:
@@ -464,7 +606,7 @@
 			info.si_code = FPE_INTOVF;
 		info.si_signo = SIGFPE;
 		info.si_errno = 0;
-		info.si_addr = (void *)compute_return_epc(regs);
+		info.si_addr = (void *)regs->cp0_epc;
 		force_sig_info(SIGFPE, &info, current);
 		break;
 	default:
@@ -476,12 +618,6 @@
 	force_sig(SIGSEGV, current);
 }
 
-#ifndef CONFIG_CPU_HAS_LLSC
-
-#ifdef CONFIG_SMP
-#error "ll/sc emulation is not SMP safe"
-#endif
-
 /*
  * userland emulation for R2300 CPUs
  * needed for the multithreading part of glibc
@@ -491,11 +627,18 @@
  */
 asmlinkage void do_ri(struct pt_regs *regs)
 {
-	unsigned int opcode;
-
 	if (!user_mode(regs))
 		BUG();
 
+#ifndef CONFIG_CPU_HAS_LLSC
+
+#ifdef CONFIG_SMP
+#error "ll/sc emulation is not SMP safe"
+#endif
+
+	{
+	unsigned int opcode;
+
 	if (!get_insn_opcode(regs, &opcode)) {
 		if ((opcode & OPCODE) == LL) {
 			simulate_ll(regs, opcode);
@@ -506,121 +649,19 @@
 			return;
 		}
 	}
-
-	if (compute_return_epc(regs))
-		return;
-	force_sig(SIGILL, current);
-}
-
-/*
- * The ll_bit is cleared by r*_switch.S
- */
-
-unsigned long ll_bit;
-#ifdef CONFIG_PROC_FS
-extern unsigned long ll_ops;
-extern unsigned long sc_ops;
-#endif
-
-static struct task_struct *ll_task = NULL;
-
-void simulate_ll(struct pt_regs *regp, unsigned int opcode)
-{
-	unsigned long value, *vaddr;
-	long offset;
-	int signal = 0;
-
-	/*
-	 * analyse the ll instruction that just caused a ri exception
-	 * and put the referenced address to addr.
-	 */
-
-	/* sign extend offset */
-	offset = opcode & OFFSET;
-	offset <<= 16;
-	offset >>= 16;
-
-	vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset);
-
-#ifdef CONFIG_PROC_FS
-	ll_ops++;
-#endif
-
-	if ((unsigned long)vaddr & 3)
-		signal = SIGBUS;
-	else if (get_user(value, vaddr))
-		signal = SIGSEGV;
-	else {
-		if (ll_task == NULL || ll_task == current) {
-			ll_bit = 1;
-		} else {
-			ll_bit = 0;
-		}
-		ll_task = current;
-		regp->regs[(opcode & RT) >> 16] = value;
 	}
-	if (compute_return_epc(regp))
-		return;
-	if (signal)
-		send_sig(signal, current, 1);
-}
-
-void simulate_sc(struct pt_regs *regp, unsigned int opcode)
-{
-	unsigned long *vaddr, reg;
-	long offset;
-	int signal = 0;
-
-	/*
-	 * analyse the sc instruction that just caused a ri exception
-	 * and put the referenced address to addr.
-	 */
+#endif /* CONFIG_CPU_HAS_LLSC */
 
-	/* sign extend offset */
-	offset = opcode & OFFSET;
-	offset <<= 16;
-	offset >>= 16;
-
-	vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset);
-	reg = (opcode & RT) >> 16;
-
-#ifdef CONFIG_PROC_FS
-	sc_ops++;
-#endif
-
-	if ((unsigned long)vaddr & 3)
-		signal = SIGBUS;
-	else if (ll_bit == 0 || ll_task != current)
-		regp->regs[reg] = 0;
-	else if (put_user(regp->regs[reg], vaddr))
-		signal = SIGSEGV;
-	else
-		regp->regs[reg] = 1;
-	if (compute_return_epc(regp))
-		return;
-	if (signal)
-		send_sig(signal, current, 1);
-}
-
-#else /* MIPS 2 or higher */
-
-asmlinkage void do_ri(struct pt_regs *regs)
-{
-	unsigned int opcode;
-
-	get_insn_opcode(regs, &opcode);
 	if (compute_return_epc(regs))
 		return;
-
 	force_sig(SIGILL, current);
 }
 
-#endif
-
 asmlinkage void do_cpu(struct pt_regs *regs)
 {
 	unsigned int cpid;
 	extern void lazy_fpu_switch(void *);
+	extern void save_fp(struct task_struct *);
 	extern void init_fpu(void);
 	void fpu_emulator_init_fpu(void);
 	int sig;
@@ -639,10 +680,13 @@
 	if (current->used_math) {		/* Using the FPU again.  */
 		lazy_fpu_switch(last_task_used_math);
 	} else {				/* First time FPU user.  */
+		if (last_task_used_math != NULL)
+			save_fp(last_task_used_math);
 		init_fpu();
 		current->used_math = 1;
 	}
 	last_task_used_math = current;
+
 	return;
 
 fp_emul:
@@ -655,19 +699,38 @@
 	sig = fpu_emulator_cop1Handler(regs);
 	last_task_used_math = current;
 	if (sig)
+	{
+		/* 
+		 * Return EPC is not calculated in the FPU emulator, if 
+		 * a signal is being send. So we calculate it here.
+		 */
+		compute_return_epc(regs);
 		force_sig(sig, current);
+	}
 	return;
 
 bad_cid:
+#ifndef CONFIG_CPU_HAS_LLSC
+	switch (mips_cpu.cputype) {
+	case CPU_TX3927:
+	case CPU_TX39XX:
+		do_ri(regs);
+		return;
+	}
+#endif
+	compute_return_epc(regs);
 	force_sig(SIGILL, current);
 }
 
 asmlinkage void do_watch(struct pt_regs *regs)
 {
+	extern void dump_tlb_all(void);
+
 	/*
 	 * We use the watch exception where available to detect stack
 	 * overflows.
 	 */
+	dump_tlb_all();
 	show_regs(regs);
 	panic("Caught WATCH exception - probably caused by stack overflow.");
 }
@@ -753,6 +816,50 @@
 	panic("Can't handle the cache error!");
 }
 
+/*
+ * SDBBP EJTAG debug exception handler.
+ * We skip the instruction and return to the next instruction.
+ */
+void ejtag_exception_handler(struct pt_regs *regs)
+{
+        unsigned int depc, old_epc, debug;
+
+        printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
+        depc = read_32bit_cp0_register(CP0_DEPC);
+        debug = read_32bit_cp0_register(CP0_DEBUG);
+        printk("DEPC = %08x, DEBUG = %08x\n", depc, debug); 
+        if (debug & 0x80000000) {
+                /* 
+                 * In branch delay slot.
+                 * We cheat a little bit here and use EPC to calculate the
+                 * debug return address (DEPC). EPC is restored after the
+                 * calculation.
+                 */
+                old_epc = regs->cp0_epc;
+                regs->cp0_epc = depc;
+                __compute_return_epc(regs);
+                depc = regs->cp0_epc;
+                regs->cp0_epc = old_epc;
+        } else
+                depc += 4;
+        write_32bit_cp0_register(CP0_DEPC, depc);
+
+#if 0
+	printk("\n\n----- Enable EJTAG single stepping ----\n\n");
+	write_32bit_cp0_register(CP0_DEBUG, debug | 0x100);
+#endif
+}
+
+/*
+ * NMI exception handler.
+ */
+void nmi_exception_handler(struct pt_regs *regs)
+{
+        printk("NMI taken!!!!\n");
+        die("NMI", regs);
+        while(1) ;  /* We die here. */
+}
+
 unsigned long exception_handlers[32];
 
 /*
@@ -782,24 +889,39 @@
 extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc);
 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc);
 
+void __init per_cpu_trap_init(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	/* Some firmware leaves the BEV flag set, clear it.  */
+	clear_cp0_status(ST0_BEV);
+
+	/*
+	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+	 * interrupt processing overhead.  Use it where available.
+	 */
+	if (mips_cpu.options & MIPS_CPU_DIVEC)
+		set_cp0_cause(CAUSEF_IV);
+
+	cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
+	set_context(cpu << 23);
+}
+
 void __init trap_init(void)
 {
-	extern char except_vec0_nevada, except_vec0_r4000;
-	extern char except_vec0_r4600, except_vec0_r2300;
 	extern char except_vec1_generic, except_vec2_generic;
 	extern char except_vec3_generic, except_vec3_r4000;
 	extern char except_vec4;
 	extern char except_vec_ejtag_debug;
 	unsigned long i;
 
-	/* Some firmware leaves the BEV flag set, clear it.  */
-	clear_cp0_status(ST0_BEV);
+	per_cpu_trap_init();
 
 	/* Copy the generic exception handler code to it's final destination. */
 	memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
 	memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
 	memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
-	flush_icache_range(KSEG0 + 0x80, KSEG0 + 0x200);
+
 	/*
 	 * Setup default vectors
 	 */
@@ -810,7 +932,8 @@
 	 * Copy the EJTAG debug exception vector handler code to it's final 
 	 * destination.
 	 */
-	memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
+	if (mips_cpu.options & MIPS_CPU_EJTAG)
+		memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
 
 	/*
 	 * Only some CPUs have the watch exceptions or a dedicated
@@ -833,21 +956,21 @@
 	 */
 	parity_protection_init();
 
+	/*
+	 * The Data Bus Errors / Instruction Bus Errors are signaled
+	 * by external hardware.  Therefore these two exceptions
+	 * may have board specific handlers.
+	 */
+	bus_error_init();
+
 	set_except_vector(1, handle_mod);
 	set_except_vector(2, handle_tlbl);
 	set_except_vector(3, handle_tlbs);
 	set_except_vector(4, handle_adel);
 	set_except_vector(5, handle_ades);
 
-	/*
-	 * The Data Bus Error/ Instruction Bus Errors are signaled
-	 * by external hardware.  Therefore these two expection have
-	 * board specific handlers.
-	 */
 	set_except_vector(6, handle_ibe);
 	set_except_vector(7, handle_dbe);
-	ibe_board_handler = default_be_board_handler;
-	dbe_board_handler = default_be_board_handler;
 
 	set_except_vector(8, handle_sys);
 	set_except_vector(9, handle_bp);
@@ -856,37 +979,22 @@
 	set_except_vector(12, handle_ov);
 	set_except_vector(13, handle_tr);
 
-	if (mips_cpu.options & MIPS_CPU_FPU)
+	if ((mips_cpu.options & MIPS_CPU_FPU) &&
+	    !(mips_cpu.options & MIPS_CPU_NOFPUEX))
 		set_except_vector(15, handle_fpe);
+	if (mips_cpu.options & MIPS_CPU_MCHECK)
+		set_except_vector(24, handle_mcheck);
 
 	/*
 	 * Handling the following exceptions depends mostly of the cpu type
 	 */
 	if ((mips_cpu.options & MIPS_CPU_4KEX)
 	    && (mips_cpu.options & MIPS_CPU_4KTLB)) {
-		if (mips_cpu.cputype == CPU_NEVADA) {
-			memcpy((void *)KSEG0, &except_vec0_nevada, 0x80);
-		} else if (mips_cpu.cputype == CPU_R4600)
-			memcpy((void *)KSEG0, &except_vec0_r4600, 0x80);
-		else
-			memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
-
 		/* Cache error vector already set above.  */
 
 		if (mips_cpu.options & MIPS_CPU_VCE) {
 			memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
 			       0x80);
-		} else {
-			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
-			       0x80);
-		}
-
-		if (mips_cpu.options & MIPS_CPU_FPU) {
-		        save_fp_context = _save_fp_context;
-			restore_fp_context = _restore_fp_context;
-		} else {
-		        save_fp_context = fpu_emulator_save_context;
-			restore_fp_context = fpu_emulator_restore_context;
 		}
 	} else switch (mips_cpu.cputype) {
 	case CPU_SB1:
@@ -894,10 +1002,15 @@
 		 * XXX - This should be folded in to the "cleaner" handling,
 		 * above
 		 */
-		memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
 		memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80);
-		save_fp_context = _save_fp_context;
-		restore_fp_context = _restore_fp_context;
+#ifdef CONFIG_SB1_CACHE_ERROR
+		{
+		/* Special cache error handler for SB1 */
+		extern char except_vec2_sb1;
+		memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80);
+		memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80);
+		}
+#endif
 
 		/* Enable timer interrupt and scd mapped interrupt */
 		clear_cp0_status(0xf000);
@@ -905,9 +1018,6 @@
 		break;
 	case CPU_R6000:
 	case CPU_R6000A:
-	        save_fp_context = _save_fp_context;
-		restore_fp_context = _restore_fp_context;
-		
 		/*
 		 * The R6000 is the only R-series CPU that features a machine
 		 * check exception (similar to the R4000 cache error) and
@@ -929,9 +1039,7 @@
 	case CPU_TX3912:
 	case CPU_TX3922:
 	case CPU_TX3927:
-	        save_fp_context = _save_fp_context;
-		restore_fp_context = _restore_fp_context;
-		memcpy((void *)KSEG0, &except_vec0_r2300, 0x80);
+	case CPU_TX39XX:
 		memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
 		break;
 
@@ -939,13 +1047,24 @@
 	default:
 		panic("Unknown CPU type");
 	}
-	flush_icache_range(KSEG0, KSEG0 + 0x200);
+
+	flush_icache_range(KSEG0, KSEG0 + 0x400);
+
+	if (mips_cpu.options & MIPS_CPU_FPU) {
+	        save_fp_context = _save_fp_context;
+		restore_fp_context = _restore_fp_context;
+	} else {
+		save_fp_context = fpu_emulator_save_context;
+		restore_fp_context = fpu_emulator_restore_context;
+	}
 
 	if (mips_cpu.isa_level == MIPS_CPU_ISA_IV)
 		set_cp0_status(ST0_XX);
 
 	atomic_inc(&init_mm.mm_count);	/* XXX  UP?  */
 	current->active_mm = &init_mm;
-	write_32bit_cp0_register(CP0_CONTEXT, smp_processor_id()<<23);
-	current_pgd[0] = init_mm.pgd;
+
+	/* XXX Must be done for all CPUs  */
+	current_cpu_data.asid_cache = ASID_FIRST_VERSION;
+	TLBMISS_HANDLER_SETUP();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/kernel/unaligned.c linux/arch/mips/kernel/unaligned.c
--- linux.orig/arch/mips/kernel/unaligned.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/kernel/unaligned.c	2002-07-20 01:08:23.000000000 +0000
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1998 by Ralf Baechle
+ * Copyright (C) 1996, 1998, 2002 by Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  *
  * This file contains exception handler for address error exception with the
@@ -96,13 +96,12 @@
 	if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0)	\
 		goto sigbus;
 
-static inline void
-emulate_load_store_insn(struct pt_regs *regs,
-                        unsigned long addr,
-                        unsigned long pc)
+static inline int emulate_load_store_insn(struct pt_regs *regs,
+	unsigned long addr, unsigned long pc)
 {
 	union mips_instruction insn;
 	unsigned long value, fixup;
+	unsigned int res;
 
 	regs->regs[0] = 0;
 	/*
@@ -145,116 +144,96 @@
 	 */
 	case lh_op:
 		check_axs(pc, addr, 2);
-		__asm__(
-			".set\tnoat\n"
+		__asm__(".set\tnoat\n"
 #ifdef __BIG_ENDIAN
-			"1:\tlb\t%0,0(%1)\n"
-			"2:\tlbu\t$1,1(%1)\n\t"
+			"1:\tlb\t%0, 0(%2)\n"
+			"2:\tlbu\t$1, 1(%2)\n\t"
 #endif
 #ifdef __LITTLE_ENDIAN
-			"1:\tlb\t%0,1(%1)\n"
-			"2:\tlbu\t$1,0(%1)\n\t"
+			"1:\tlb\t%0, 1(%2)\n"
+			"2:\tlbu\t$1, 0(%2)\n\t"
 #endif
-			"sll\t%0,0x8\n\t"
-			"or\t%0,$1\n\t"
-			".set\tat\n\t"
+			"sll\t%0, 0x8\n\t"
+			"or\t%0, $1\n\t"
+			"li\t%1, 0\n"
+			"3:\t.set\tat\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%1, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
 			".section\t__ex_table,\"a\"\n\t"
-			STR(PTR)"\t1b,%2\n\t"
-			STR(PTR)"\t2b,%2\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
 			".previous"
-			:"=&r" (value)
-			:"r" (addr), "i" (&&fault)
-			:"$1");
+			: "=&r" (value), "=r" (res)
+			: "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
 		regs->regs[insn.i_format.rt] = value;
-		return;
+		return 0;
 
 	case lw_op:
 		check_axs(pc, addr, 4);
 		__asm__(
 #ifdef __BIG_ENDIAN
-			"1:\tlwl\t%0,(%1)\n"
-			"2:\tlwr\t%0,3(%1)\n\t"
+			"1:\tlwl\t%0, (%2)\n"
+			"2:\tlwr\t%0, 3(%2)\n\t"
 #endif
 #ifdef __LITTLE_ENDIAN
-			"1:\tlwl\t%0,3(%1)\n"
-			"2:\tlwr\t%0,(%1)\n\t"
+			"1:\tlwl\t%0, 3(%2)\n"
+			"2:\tlwr\t%0, (%2)\n\t"
 #endif
+			"li\t%1, 0\n"
+			"3:\t.section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%1, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
 			".section\t__ex_table,\"a\"\n\t"
-			STR(PTR)"\t1b,%2\n\t"
-			STR(PTR)"\t2b,%2\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
 			".previous"
-			:"=&r" (value)
-			:"r" (addr), "i" (&&fault));
-			regs->regs[insn.i_format.rt] = value;
-			return;
+			: "=&r" (value), "=r" (res)
+			: "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		regs->regs[insn.i_format.rt] = value;
+		return 0;
 
 	case lhu_op:
 		check_axs(pc, addr, 2);
 		__asm__(
 			".set\tnoat\n"
 #ifdef __BIG_ENDIAN
-			"1:\tlbu\t%0,0(%1)\n"
-			"2:\tlbu\t$1,1(%1)\n\t"
+			"1:\tlbu\t%0, 0(%2)\n"
+			"2:\tlbu\t$1, 1(%2)\n\t"
 #endif
 #ifdef __LITTLE_ENDIAN
-			"1:\tlbu\t%0,1(%1)\n"
-			"2:\tlbu\t$1,0(%1)\n\t"
+			"1:\tlbu\t%0, 1(%2)\n"
+			"2:\tlbu\t$1, 0(%2)\n\t"
 #endif
-			"sll\t%0,0x8\n\t"
-			"or\t%0,$1\n\t"
-			".set\tat\n\t"
+			"sll\t%0, 0x8\n\t"
+			"or\t%0, $1\n\t"
+			"li\t%1, 0\n"
+			"3:\t.set\tat\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%1, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
 			".section\t__ex_table,\"a\"\n\t"
-			STR(PTR)"\t1b,%2\n\t"
-			STR(PTR)"\t2b,%2\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
 			".previous"
-			:"=&r" (value)
-			:"r" (addr), "i" (&&fault)
-			:"$1");
+			: "=&r" (value), "=r" (res)
+			: "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
 		regs->regs[insn.i_format.rt] = value;
-		return;
+		return 0;
 
 	case lwu_op:
-		check_axs(pc, addr, 4);
-		__asm__(
-#ifdef __BIG_ENDIAN
-			"1:\tlwl\t%0,(%1)\n"
-			"2:\tlwr\t%0,3(%1)\n\t"
-#endif
-#ifdef __LITTLE_ENDIAN
-			"1:\tlwl\t%0,3(%1)\n"
-			"2:\tlwr\t%0,(%1)\n\t"
-#endif
-			".section\t__ex_table,\"a\"\n\t"
-			STR(PTR)"\t1b,%2\n\t"
-			STR(PTR)"\t2b,%2\n\t"
-			".previous"
-			:"=&r" (value)
-			:"r" (addr), "i" (&&fault));
-		value &= 0xffffffff;
-		regs->regs[insn.i_format.rt] = value;
-		return;
-
 	case ld_op:
-		check_axs(pc, addr, 8);
-		__asm__(
-			".set\tmips3\n"
-#ifdef __BIG_ENDIAN
-			"1:\tldl\t%0,(%1)\n"
-			"2:\tldr\t%0,7(%1)\n\t"
-#endif
-#ifdef __LITTLE_ENDIAN
-			"1:\tldl\t%0,7(%1)\n"
-			"2:\tldr\t%0,(%1)\n\t"
-#endif
-			".set\tmips0\n\t"
-			".section\t__ex_table,\"a\"\n\t"
-			STR(PTR)"\t1b,%2\n\t"
-			STR(PTR)"\t2b,%2\n\t"
-			".previous"
-			:"=&r" (value)
-			:"r" (addr), "i" (&&fault));
-		regs->regs[insn.i_format.rt] = value;
-		return;
+		/* Cannot handle 64-bit instructions in 32-bit kernel */
+		goto sigill;
 
 	case sh_op:
 		check_axs(pc, addr, 2);
@@ -262,68 +241,65 @@
 		__asm__(
 #ifdef __BIG_ENDIAN
 			".set\tnoat\n"
-			"1:\tsb\t%0,1(%1)\n\t"
-			"srl\t$1,%0,0x8\n"
-			"2:\tsb\t$1,0(%1)\n\t"
+			"1:\tsb\t%1, 1(%2)\n\t"
+			"srl\t$1, %1, 0x8\n"
+			"2:\tsb\t$1, 0(%2)\n\t"
 			".set\tat\n\t"
 #endif
 #ifdef __LITTLE_ENDIAN
 			".set\tnoat\n"
-			"1:\tsb\t%0,0(%1)\n\t"
-			"srl\t$1,%0,0x8\n"
-			"2:\tsb\t$1,1(%1)\n\t"
+			"1:\tsb\t%1, 0(%2)\n\t"
+			"srl\t$1,%1, 0x8\n"
+			"2:\tsb\t$1, 1(%2)\n\t"
 			".set\tat\n\t"
 #endif
+			"li\t%0, 0\n"
+			"3:\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%0, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
 			".section\t__ex_table,\"a\"\n\t"
-			STR(PTR)"\t1b,%2\n\t"
-			STR(PTR)"\t2b,%2\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
 			".previous"
-			: /* no outputs */
-			:"r" (value), "r" (addr), "i" (&&fault)
-			:"$1");
-		return;
+			: "=r" (res)
+			: "r" (value), "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		return 0;
 
 	case sw_op:
 		check_axs(pc, addr, 4);
 		value = regs->regs[insn.i_format.rt];
 		__asm__(
 #ifdef __BIG_ENDIAN
-			"1:\tswl\t%0,(%1)\n"
-			"2:\tswr\t%0,3(%1)\n\t"
+			"1:\tswl\t%1,(%2)\n"
+			"2:\tswr\t%1, 3(%2)\n\t"
 #endif
 #ifdef __LITTLE_ENDIAN
-			"1:\tswl\t%0,3(%1)\n"
-			"2:\tswr\t%0,(%1)\n\t"
+			"1:\tswl\t%1, 3(%2)\n"
+			"2:\tswr\t%1, (%2)\n\t"
 #endif
+			"li\t%0, 0\n"
+			"3:\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%0, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
 			".section\t__ex_table,\"a\"\n\t"
-			STR(PTR)"\t1b,%2\n\t"
-			STR(PTR)"\t2b,%2\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
 			".previous"
-			: /* no outputs */
-			:"r" (value), "r" (addr), "i" (&&fault));
-		return;
+		: "=r" (res)
+		: "r" (value), "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		return 0;
 
 	case sd_op:
-		check_axs(pc, addr, 8);
-		value = regs->regs[insn.i_format.rt];
-		__asm__(
-			".set\tmips3\n"
-#ifdef __BIG_ENDIAN
-			"1:\tsdl\t%0,(%1)\n"
-			"2:\tsdr\t%0,7(%1)\n\t"
-#endif
-#ifdef __LITTLE_ENDIAN
-			"1:\tsdl\t%0,7(%1)\n"
-			"2:\tsdr\t%0,(%1)\n\t"
-#endif
-			".set\tmips0\n\t"
-			".section\t__ex_table,\"a\"\n\t"
-			STR(PTR)"\t1b,%2\n\t"
-			STR(PTR)"\t2b,%2\n\t"
-			".previous"
-			: /* no outputs */
-			:"r" (value), "r" (addr), "i" (&&fault));
-		return;
+		/* Cannot handle 64-bit instructions in 32-bit kernel */
+		goto sigill;
 
 	case lwc1_op:
 	case ldc1_op:
@@ -352,31 +328,35 @@
 		 */
 		goto sigill;
 	}
-	return;
+	return 0;
 
 fault:
 	/* Did we have an exception handler installed? */
-	fixup = search_exception_table(regs->cp0_epc);
+	fixup = search_exception_table(exception_epc(regs));
 	if (fixup) {
 		long new_epc;
 		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
 		printk(KERN_DEBUG "%s: Forwarding exception at [<%lx>] (%lx)\n",
 		       current->comm, regs->cp0_epc, new_epc);
 		regs->cp0_epc = new_epc;
-		return;
+		return 1;
 	}
 
 	die_if_kernel ("Unhandled kernel unaligned access", regs);
 	send_sig(SIGSEGV, current, 1);
-	return;
+
+	return 0;
+
 sigbus:
-	die_if_kernel ("Unhandled kernel unaligned access", regs);
+	die_if_kernel("Unhandled kernel unaligned access", regs);
 	send_sig(SIGBUS, current, 1);
-	return;
+
+	return 0;
+
 sigill:
-	die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs);
+	die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs);
 	send_sig(SIGILL, current, 1);
-	return;
+	return 0;
 }
 
 #ifdef CONFIG_PROC_FS
@@ -394,11 +374,11 @@
 	 * of the CPU after executing the instruction
 	 * in the delay slot of an emulated branch.
 	 */
-
-	if ((unsigned long)regs->cp0_epc == current->thread.dsemul_aerpc) {
-		do_dsemulret(regs);
+	/* Terminate if exception was recognized as a delay slot return */
+	if (do_dsemulret(regs))
 		return;
-	}
+
+	/* Otherwise handle as normal */
 
 	/*
 	 * Did we catch a fault trying to load an instruction?
@@ -409,12 +389,16 @@
 		goto sigbus;
 
 	pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
-	if (compute_return_epc(regs))
-		return;
 	if ((current->thread.mflags & MF_FIXADE) == 0)
 		goto sigbus;
 
-	emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
+	/*
+	 * Do branch emulation only if we didn't forward the exception.
+	 * This is all so but ugly ...
+	 */
+	if (!emulate_load_store_insn(regs, regs->cp0_badvaddr, pc))
+		compute_return_epc(regs);
+
 #ifdef CONFIG_PROC_FS
 	unaligned_instructions++;
 #endif
@@ -422,8 +406,12 @@
 	return;
 
 sigbus:
-	die_if_kernel ("Kernel unaligned instruction access", regs);
+	die_if_kernel("Kernel unaligned instruction access", regs);
 	force_sig(SIGBUS, current);
 
+	/*
+	 * XXX On return from the signal handler we should advance the epc
+	 */
+
 	return;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/Makefile linux/arch/mips/lib/Makefile
--- linux.orig/arch/mips/lib/Makefile	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/lib/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -2,10 +2,7 @@
 # Makefile for MIPS-specific library files..
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 L_TARGET = lib.a
 
@@ -14,7 +11,7 @@
 				   watch.o strlen_user.o strncpy_user.o \
 				   strnlen_user.o
 
-ifdef CONFIG_CPU_R3000
+ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y)
   obj-y	+= r3k_dump_tlb.o 
 else
   obj-y	+= dump_tlb.o 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/csum_partial.S linux/arch/mips/lib/csum_partial.S
--- linux.orig/arch/mips/lib/csum_partial.S	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/csum_partial.S	2002-07-20 01:08:33.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: csum_partial.S,v 1.1 1998/05/04 09:12:52 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/csum_partial_copy.c linux/arch/mips/lib/csum_partial_copy.c
--- linux.orig/arch/mips/lib/csum_partial_copy.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/csum_partial_copy.c	2002-07-20 01:08:37.000000000 +0000
@@ -13,8 +13,6 @@
  *		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.
- *
- * $Id: csum_partial_copy.c,v 1.2 1998/09/19 19:16:17 ralf Exp $
  */
 #include <net/checksum.h>
 #include <linux/types.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/dump_tlb.c linux/arch/mips/lib/dump_tlb.c
--- linux.orig/arch/mips/lib/dump_tlb.c	2000-02-25 06:52:30.000000000 +0000
+++ linux/arch/mips/lib/dump_tlb.c	2002-07-20 01:08:21.000000000 +0000
@@ -4,30 +4,47 @@
  * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
  * Copyright (C) 1999 by Silicon Graphics, Inc.
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
+#include <asm/cpu.h>
 #include <asm/cachectl.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-#define mips_tlb_entries 48
+static inline const char *msg2str(unsigned int mask)
+{
+	switch (mask) {
+	case PM_4K:	return "4kb";
+	case PM_16K:	return "16kb";
+	case PM_64K:	return "64kb";
+	case PM_256K:	return "256kb";
+#ifndef CONFIG_CPU_VR41XX
+	case PM_1M:	return "1Mb";
+	case PM_4M:	return "4Mb";
+	case PM_16M:	return "16Mb";
+	case PM_64M:	return "64Mb";
+	case PM_256M:	return "256Mb";
+#endif
+	}
+}
 
-void
-dump_tlb(int first, int last)
+void dump_tlb(int first, int last)
 {
 	int	i;
 	unsigned int pagemask, c0, c1, asid;
-	unsigned long entryhi, entrylo0, entrylo1;
+	unsigned long long entrylo0, entrylo1;
+	unsigned long entryhi;
 
 	asid = get_entryhi() & 0xff;
 
-	for(i=first;i<=last;i++)
-	{
+	printk("\n");
+	for(i=first;i<=last;i++) {
 		write_32bit_cp0_register(CP0_INDEX, i);
 		__asm__ __volatile__(
 			".set\tmips3\n\t"
@@ -39,49 +56,45 @@
 			".set\tmips0\n\t");
 		pagemask = read_32bit_cp0_register(CP0_PAGEMASK);
 		entryhi  = read_32bit_cp0_register(CP0_ENTRYHI);
-		entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0);
-		entrylo1 = read_32bit_cp0_register(CP0_ENTRYLO1);
+		entrylo0 = get_entrylo0();
+		entrylo1 = get_entrylo1();
 
-		/* Unused entries have a virtual address of KSEG0.  */
-		if ((entryhi & 0xffffe000) != 0x80000000
+		/* Unused entries have a virtual address in KSEG0.  */
+		if ((entryhi & 0xf0000000) != 0x80000000
 		    && (entryhi & 0xff) == asid) {
 			/*
 			 * Only print entries in use
 			 */
-			printk("Index: %2d pgmask=%08x ", i, pagemask);
+			printk("Index: %2d pgmask=%s ", i, msg2str(pagemask));
 
 			c0 = (entrylo0 >> 3) & 7;
 			c1 = (entrylo1 >> 3) & 7;
 
-			printk("va=%08lx asid=%08lx"
-			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]"
-			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]",
-			       (entryhi & 0xffffe000),
-			       entryhi & 0xff,
-			       entrylo0 & PAGE_MASK, c0,
+			printk("va=%08lx asid=%02lx\n",
+			       (entryhi & 0xffffe000), (entryhi & 0xff));
+			printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
+			       (entrylo0 << 6) & PAGE_MASK, c0,
 			       (entrylo0 & 4) ? 1 : 0,
 			       (entrylo0 & 2) ? 1 : 0,
-			       (entrylo0 & 1),
-			       entrylo1 & PAGE_MASK, c1,
+			       (entrylo0 & 1));
+			printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
+			       (entrylo1 << 6) & PAGE_MASK, c1,
 			       (entrylo1 & 4) ? 1 : 0,
 			       (entrylo1 & 2) ? 1 : 0,
 			       (entrylo1 & 1));
-			       
+			printk("\n");
 		}
 	}
-	printk("\n");
 
 	set_entryhi(asid);
 }
 
-void
-dump_tlb_all(void)
+void dump_tlb_all(void)
 {
-	dump_tlb(0, mips_tlb_entries - 1);
+	dump_tlb(0, mips_cpu.tlbsize - 1);
 }
 
-void
-dump_tlb_wired(void)
+void dump_tlb_wired(void)
 {
 	int	wired;
 
@@ -125,7 +138,7 @@
 void
 dump_tlb_nonwired(void)
 {
-	dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1);
+	dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_cpu.tlbsize - 1);
 }
 
 void
@@ -140,12 +153,20 @@
 	addr = (unsigned int) address;
 
 	printk("Addr                 == %08x\n", addr);
-	printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
-
-	page_dir = pgd_offset(t->mm, 0);
+	printk("task                 == %08p\n", t);
+	printk("task->mm             == %08p\n", t->mm);
+	//printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
+
+	if (addr > KSEG0)
+		page_dir = pgd_offset_k(0);
+	else
+		page_dir = pgd_offset(t->mm, 0);
 	printk("page_dir == %08x\n", (unsigned int) page_dir);
 
-	pgd = pgd_offset(t->mm, addr);
+	if (addr > KSEG0)
+		pgd = pgd_offset_k(addr);
+	else
+		pgd = pgd_offset(t->mm, addr);
 	printk("pgd == %08x, ", (unsigned int) pgd);
 
 	pmd = pmd_offset(pgd, addr);
@@ -155,7 +176,11 @@
 	printk("pte == %08x, ", (unsigned int) pte);
 
 	page = *pte;
-	printk("page == %08x\n", (unsigned int) pte_val(page));
+#ifdef CONFIG_64BIT_PHYS_ADDR
+	printk("page == %08Lx\n", (unsigned long long) pte_val(page));
+#else
+	printk("page == %08lx\n", (unsigned int) pte_val(page));
+#endif
 
 	val = pte_val(page);
 	if (val & _PAGE_PRESENT) printk("present ");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/floppy-no.c linux/arch/mips/lib/floppy-no.c
--- linux.orig/arch/mips/lib/floppy-no.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/floppy-no.c	2002-07-20 01:08:32.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: floppy-no.c,v 1.1 1998/05/07 18:38:32 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/floppy-std.c linux/arch/mips/lib/floppy-std.c
--- linux.orig/arch/mips/lib/floppy-std.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/floppy-std.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: floppy-std.c,v 1.2 1999/01/04 16:03:51 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/ide-no.c linux/arch/mips/lib/ide-no.c
--- linux.orig/arch/mips/lib/ide-no.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/ide-no.c	2002-07-20 01:08:32.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: ide-no.c,v 1.2 1998/06/30 00:21:54 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/kbd-no.c linux/arch/mips/lib/kbd-no.c
--- linux.orig/arch/mips/lib/kbd-no.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/kbd-no.c	2002-07-20 01:08:32.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: kbd-no.c,v 1.1 1998/10/28 12:38:14 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/kbd-std.c linux/arch/mips/lib/kbd-std.c
--- linux.orig/arch/mips/lib/kbd-std.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/lib/kbd-std.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: kbd-std.c,v 1.2 1999/06/11 14:29:45 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -8,6 +7,7 @@
  *
  * Copyright (C) 1998, 1999 by Ralf Baechle
  */
+#include <linux/config.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/pc_keyb.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/memcpy.S linux/arch/mips/lib/memcpy.S
--- linux.orig/arch/mips/lib/memcpy.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/lib/memcpy.S	2002-07-20 01:08:23.000000000 +0000
@@ -4,407 +4,445 @@
  * for more details.
  *
  * Unified implementation of memcpy, memmove and the __copy_user backend.
- * For __rmemcpy and memmove an exception is always a kernel bug, therefore
- * they're not protected.  In order to keep the exception fixup routine
- * simple all memory accesses in __copy_user to src rsp. dst are stricly
- * incremental.  The fixup routine depends on $at not being changed.
+ *
+ * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Broadcom, Inc.
+ *   memcpy/copy_user author: Mark Vandevoorde
+ *
+ * Mnemonic names for arguments to memcpy/__copy_user
  */
+#include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/offset.h>
 #include <asm/regdef.h>
 
+#define dst a0
+#define src a1
+#define len a2
+
 /*
- * The fixup routine for copy_to_user depends on copying strictly in
- * increasing order.  Gas expands the ulw/usw macros in the wrong order for
- * little endian machines, so we cannot depend on them.
+ * Spec
+ *
+ * memcpy copies len bytes from src to dst and sets v0 to dst.
+ * It assumes that
+ *   - src and dst don't overlap
+ *   - src is readable
+ *   - dst is writable
+ * memcpy uses the standard calling convention
+ *
+ * __copy_user copies up to len bytes from src to dst and sets a2 (len) to
+ * the number of uncopied bytes due to an exception caused by a read or write.
+ * __copy_user assumes that src and dst don't overlap, and that the call is
+ * implementing one of the following:
+ *   copy_to_user
+ *     - src is readable  (no exceptions when reading src)
+ *   copy_from_user
+ *     - dst is writable  (no exceptions when writing dst)
+ * __copy_user uses a non-standard calling convention; see
+ * include/asm-mips/uaccess.h
+ *
+ * When an exception happens on a load, the handler must
+ # ensure that all of the destination buffer is overwritten to prevent
+ * leaking information to user mode programs.
  */
-#ifdef __MIPSEB__
-#define uswL	swl
-#define uswU	swr
-#define ulwL	lwl
-#define ulwU	lwr
-#endif
-#ifdef __MIPSEL__
-#define uswL	swr
-#define uswU	swl
-#define ulwL	lwr
-#define ulwU	lwl
-#endif
 
-#define EX(insn,reg,addr,handler)			\
-9:	insn	reg, addr;				\
-	.section __ex_table,"a"; 			\
-	PTR	9b, handler; 				\
-	.previous
+/*
+ * Implementation
+ */
 
-#define UEX(insn,reg,addr,handler)			\
-9:	insn ## L reg, addr;				\
-10:	insn ## U reg, 3 + addr;			\
-	.section __ex_table,"a"; 			\
-	PTR	9b, handler; 				\
-	PTR	10b, handler; 				\
+/*
+ * The exception handler for loads requires that:
+ *  1- AT contain the address of the byte just past the end of the source
+ *     of the copy,
+ *  2- src_entry <= src < AT, and
+ *  3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores adjust len (if necessary) and return.
+ * These handlers do not need to overwrite any data.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.
+ */
+
+#define EXC(inst_reg,addr,handler)		\
+9:	inst_reg, addr;				\
+	.section __ex_table,"a";		\
+	PTR	9b, handler;			\
 	.previous
 
-/* ascending order, destination aligned  */
-#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
-	EX(lw, t0, (offset + 0x00)(src), l_fixup); \
-	EX(lw, t1, (offset + 0x04)(src), l_fixup); \
-	EX(lw, t2, (offset + 0x08)(src), l_fixup); \
-	EX(lw, t3, (offset + 0x0c)(src), l_fixup); \
-	EX(sw, t0, (offset + 0x00)(dst), s_fixup); \
-	EX(sw, t1, (offset + 0x04)(dst), s_fixup); \
-	EX(sw, t2, (offset + 0x08)(dst), s_fixup); \
-	EX(sw, t3, (offset + 0x0c)(dst), s_fixup); \
-	EX(lw, t0, (offset + 0x10)(src), l_fixup); \
-	EX(lw, t1, (offset + 0x14)(src), l_fixup); \
-	EX(lw, t2, (offset + 0x18)(src), l_fixup); \
-	EX(lw, t3, (offset + 0x1c)(src), l_fixup); \
-	EX(sw, t0, (offset + 0x10)(dst), s_fixup); \
-	EX(sw, t1, (offset + 0x14)(dst), s_fixup); \
-	EX(sw, t2, (offset + 0x18)(dst), s_fixup); \
-	EX(sw, t3, (offset + 0x1c)(dst), s_fixup)
-
-/* ascending order, destination unaligned  */
-#define UMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
-	EX(lw, t0, (offset + 0x00)(src), l_fixup); \
-	EX(lw, t1, (offset + 0x04)(src), l_fixup); \
-	EX(lw, t2, (offset + 0x08)(src), l_fixup); \
-	EX(lw, t3, (offset + 0x0c)(src), l_fixup); \
-	UEX(usw, t0, (offset + 0x00)(dst), s_fixup); \
-	UEX(usw, t1, (offset + 0x04)(dst), s_fixup); \
-	UEX(usw, t2, (offset + 0x08)(dst), s_fixup); \
-	UEX(usw, t3, (offset + 0x0c)(dst), s_fixup); \
-	EX(lw, t0, (offset + 0x10)(src), l_fixup); \
-	EX(lw, t1, (offset + 0x14)(src), l_fixup); \
-	EX(lw, t2, (offset + 0x18)(src), l_fixup); \
-	EX(lw, t3, (offset + 0x1c)(src), l_fixup); \
-	UEX(usw, t0, (offset + 0x10)(dst), s_fixup); \
-	UEX(usw, t1, (offset + 0x14)(dst), s_fixup); \
-	UEX(usw, t2, (offset + 0x18)(dst), s_fixup); \
-	UEX(usw, t3, (offset + 0x1c)(dst), s_fixup)
+/*
+ * In the mips (not mips64) tree, so we can't use doubles
+ */
+#undef USE_DOUBLE
+
+#if defined(USE_DOUBLE)
+
+#define LOAD   ld
+#define LOADL  ldl
+#define LOADR  ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE  sd
+#define ADD    daddu
+#define SUB    dsubu
+#define SRL    dsrl
+#define SRA    dsra
+#define SLL    dsll
+#define SLLV   dsllv
+#define SRLV   dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+#else
+
+#define LOAD   lw
+#define LOADL  lwl
+#define LOADR  lwr
+#define STOREL swl
+#define STORER swr
+#define STORE  sw
+#define ADD    addu
+#define SUB    subu
+#define SRL    srl
+#define SLL    sll
+#define SRA    sra
+#define SLLV   sllv
+#define SRLV   srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST  LOADL
+#define STFIRST STORER
+#define STREST  STOREL
+#define SHIFT_DISCARD SLLV
+#else
+#define LDFIRST LOADL
+#define LDREST  LOADR
+#define STFIRST STOREL
+#define STREST  STORER
+#define SHIFT_DISCARD SRLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit)  (FIRST(unit)+NBYTES-1)
+#define UNIT(unit)  FIRST(unit)
+
+#define ADDRMASK (NBYTES-1)
 
 	.text
 	.set	noreorder
 	.set	noat
 
+/*
+ * A combined memcpy/__copy_user
+ * __copy_user sets len to 0 for success; else to an upper bound of
+ * the number of uncopied bytes.
+ * memcpy sets v0 to dst.
+ */
 	.align	5
 LEAF(memcpy)					/* a0=dst a1=src a2=len */
-	move	v0, a0				/* return value */
+	move	v0, dst				/* return value */
 __memcpy:
-EXPORT(__copy_user)
-	xor	t0, a0, a1
-	andi	t0, t0, 0x3
-	move	t7, a0
-	beqz	t0, can_align
-	 sltiu	t8, a2, 0x8
-
-	b	memcpy_u_src			# bad alignment
-	 move	t2, a2
-
-can_align:
-	bnez	t8, small_memcpy		# < 8 bytes to copy
-	 move	t2, a2
-
-	beqz	a2, out
-	 andi	t8, a1, 0x1
-
-hword_align:
-	beqz	t8, word_align
-	 andi	t8, a1, 0x2
-
-	EX(lb, t0, (a1), l_fixup)
-	subu	a2, a2, 0x1
-	EX(sb, t0, (a0), s_fixup)
-	addu	a1, a1, 0x1
-	addu	a0, a0, 0x1
-	andi	t8, a1, 0x2
-
-word_align:
-	beqz	t8, dword_align
-	 sltiu	t8, a2, 56
-	
-	EX(lh, t0, (a1), l_fixup)
-	subu	a2, a2, 0x2
-	EX(sh, t0, (a0), s_fixup)
-	sltiu	t8, a2, 56
-	addu	a0, a0, 0x2
-	addu	a1, a1, 0x2
-
-dword_align:
-	bnez	t8, do_end_words
-	 move	t8, a2
-
-	andi	t8, a1, 0x4
-	beqz	t8, qword_align
-	 andi	t8, a1, 0x8
-
-	EX(lw, t0, 0x00(a1), l_fixup)
-	subu	a2, a2, 0x4
-	EX(sw, t0, 0x00(a0), s_fixup)
-	addu	a1, a1, 0x4
-	addu	a0, a0, 0x4
-	andi	t8, a1, 0x8
-
-qword_align:
-	beqz	t8, oword_align
-	 andi	t8, a1, 0x10
-
-	EX(lw, t0, 0x00(a1), l_fixup)
-	EX(lw, t1, 0x04(a1), l_fixup)
-	subu	a2, a2, 0x8
-	EX(sw, t0, 0x00(a0), s_fixup)
-	EX(sw, t1, 0x04(a0), s_fixup)
-	addu	a1, a1, 0x8
-	andi	t8, a1, 0x10
-	addu	a0, a0, 0x8
-
-oword_align:
-	beqz	t8, begin_movement
-	 srl	t8, a2, 0x7
-
-	EX(lw, t3, 0x00(a1), l_fixup)
-	EX(lw, t4, 0x04(a1), l_fixup)
-	EX(lw, t0, 0x08(a1), l_fixup)
-	EX(lw, t1, 0x0c(a1), l_fixup)
-	EX(sw, t3, 0x00(a0), s_fixup)
-	EX(sw, t4, 0x04(a0), s_fixup)
-	EX(sw, t0, 0x08(a0), s_fixup)
-	EX(sw, t1, 0x0c(a0), s_fixup)
-	subu	a2, a2, 0x10
-	addu	a1, a1, 0x10
-	srl	t8, a2, 0x7
-	addu	a0, a0, 0x10
-
-begin_movement:
-	beqz	t8, 0f
-	 andi	t2, a2, 0x40
-
-move_128bytes:
-	MOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-	MOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4)
-	MOVE_BIGCHUNK(a1, a0, 0x40, t0, t1, t3, t4)
-	MOVE_BIGCHUNK(a1, a0, 0x60, t0, t1, t3, t4)
-	subu	t8, t8, 0x01
-	addu	a1, a1, 0x80
-	bnez	t8, move_128bytes
-	 addu	a0, a0, 0x80
-
-0:
-	beqz	t2, 1f
-	 andi	t2, a2, 0x20
-
-move_64bytes:
-	MOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-	MOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4)
-	addu	a1, a1, 0x40
-	addu	a0, a0, 0x40
-
+FEXPORT(__copy_user)
+	/*
+	 * Note: dst & src may be unaligned, len may be 0
+	 * Temps
+	 */
+#define rem t8
+
+	/*
+	 * The "issue break"s below are very approximate.
+	 * Issue delays for dcache fills will perturb the schedule, as will
+	 * load queue full replay traps, etc.
+	 *
+	 * If len < NBYTES use byte operations.
+	 */
+	PREF(	0, 0(src) )
+	PREF(	1, 0(dst) )
+	sltu	t2, len, NBYTES
+	and	t1, dst, ADDRMASK
+	PREF(	0, 1*32(src) )
+	PREF(	1, 1*32(dst) )
+	bnez	t2, copy_bytes_checklen
+	 and	t0, src, ADDRMASK
+	PREF(	0, 2*32(src) )
+	PREF(	1, 2*32(dst) )
+	bnez	t1, dst_unaligned
+	 nop
+	bnez	t0, src_unaligned_dst_aligned
+	/*
+	 * use delay slot for fall-through
+	 * src and dst are aligned; need to compute rem
+	 */
+both_aligned:
+	 SRL	t0, len, LOG_NBYTES+3    # +3 for 8 units/iter
+	beqz	t0, cleanup_both_aligned # len < 8*NBYTES
+	 and	rem, len, (8*NBYTES-1)	 # rem = len % (8*NBYTES)
+	PREF(	0, 3*32(src) )
+	PREF(	1, 3*32(dst) )
+	.align	4
 1:
-	beqz	t2, do_end_words
-	 andi	t8, a2, 0x1c
-
-move_32bytes:
-	MOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-	andi	t8, a2, 0x1c
-	addu	a1, a1, 0x20
-	addu	a0, a0, 0x20
-
-do_end_words:
-	beqz	t8, maybe_end_cruft
-	 srl	t8, t8, 0x2
-
-end_words:
-	EX(lw, t0, (a1), l_fixup)
-	subu	t8, t8, 0x1
-	EX(sw, t0, (a0), s_fixup)
-	addu	a1, a1, 0x4
-	bnez	t8, end_words
-	 addu	a0, a0, 0x4
-
-maybe_end_cruft:
-	andi	t2, a2, 0x3
-
-small_memcpy:
-	beqz	t2, out
-	 move	a2, t2
-
-end_bytes:
-	EX(lb, t0, (a1), l_fixup)
-	subu	a2, a2, 0x1
-	EX(sb, t0, (a0), s_fixup)
-	addu	a1, a1, 0x1
-	bnez	a2, end_bytes
-	 addu	a0, a0, 0x1
-
-out:	jr	ra
-	 move	a2, zero
-
-/* ------------------------------------------------------------------------- */
+EXC(	LOAD	t0, UNIT(0)(src),	l_exc)
+EXC(	LOAD	t1, UNIT(1)(src),	l_exc_copy)
+EXC(	LOAD	t2, UNIT(2)(src),	l_exc_copy)
+EXC(	LOAD	t3, UNIT(3)(src),	l_exc_copy)
+	SUB	len, len, 8*NBYTES
+EXC(	LOAD	t4, UNIT(4)(src),	l_exc_copy)
+EXC(	LOAD	t7, UNIT(5)(src),	l_exc_copy)
+EXC(	STORE	t0, UNIT(0)(dst),	s_exc_p8u)
+EXC(	STORE	t1, UNIT(1)(dst),	s_exc_p7u)
+EXC(	LOAD	t0, UNIT(6)(src),	l_exc_copy)
+EXC(	LOAD	t1, UNIT(7)(src),	l_exc_copy)
+	ADD	src, src, 8*NBYTES
+	ADD	dst, dst, 8*NBYTES
+EXC(	STORE	t2, UNIT(-6)(dst),	s_exc_p6u)
+EXC(	STORE	t3, UNIT(-5)(dst),	s_exc_p5u)
+EXC(	STORE	t4, UNIT(-4)(dst),	s_exc_p4u)
+EXC(	STORE	t7, UNIT(-3)(dst),	s_exc_p3u)
+EXC(	STORE	t0, UNIT(-2)(dst),	s_exc_p2u)
+EXC(	STORE	t1, UNIT(-1)(dst),	s_exc_p1u)
+	PREF(	0, 8*32(src) )
+	PREF(	1, 8*32(dst) )
+	bne	len, rem, 1b
+	 nop
 
-/* Bad, bad.  At least try to align the source  */
+	/*
+	 * len == rem == the number of bytes left to copy < 8*NBYTES
+	 */
+cleanup_both_aligned:
+	beqz	len, done
+	 sltu	t0, len, 4*NBYTES
+	bnez	t0, less_than_4units
+	 and	rem, len, (NBYTES-1)	# rem = len % NBYTES
+	/*
+	 * len >= 4*NBYTES
+	 */
+EXC(	LOAD	t0, UNIT(0)(src),	l_exc)
+EXC(	LOAD	t1, UNIT(1)(src),	l_exc_copy)
+EXC(	LOAD	t2, UNIT(2)(src),	l_exc_copy)
+EXC(	LOAD	t3, UNIT(3)(src),	l_exc_copy)
+	SUB	len, len, 4*NBYTES
+	ADD	src, src, 4*NBYTES
+EXC(	STORE	t0, UNIT(0)(dst),	s_exc_p4u)
+EXC(	STORE	t1, UNIT(1)(dst),	s_exc_p3u)
+EXC(	STORE	t2, UNIT(2)(dst),	s_exc_p2u)
+EXC(	STORE	t3, UNIT(3)(dst),	s_exc_p1u)
+	beqz	len, done
+	 ADD	dst, dst, 4*NBYTES
+less_than_4units:
+	/*
+	 * rem = len % NBYTES
+	 */
+	beq	rem, len, copy_bytes
+	 nop
+1:
+EXC(	LOAD	 t0, 0(src),		l_exc)
+	ADD	src, src, NBYTES
+	SUB	len, len, NBYTES
+EXC(	STORE	t0, 0(dst),		s_exc)
+	bne	rem, len, 1b
+	 ADD	dst, dst, NBYTES
+
+	/*
+	 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
+	 * A loop would do only a byte at a time with possible branch
+	 * mispredicts.  Can't do an explicit LOAD dst,mask,or,STORE
+	 * because can't assume read-access to dst.  Instead, use
+	 * STREST dst, which doesn't require read access to dst.
+	 *
+	 * This code should perform better than a simple loop on modern,
+	 * wide-issue mips processors because the code has fewer branches and
+	 * more instruction-level parallelism.
+	 */
+#define bits t2
+	beqz	len, done
+	 ADD	t1, dst, len	# t1 is just past last byte of dst
+	li	bits, 8*NBYTES
+	SLL	rem, len, 3	# rem = number of bits to keep
+EXC(	LOAD	t0, 0(src),		l_exc)
+	SUB	bits, bits, rem	# bits = number of bits to discard
+	SHIFT_DISCARD t0, t0, bits
+EXC(	STREST	t0, -1(t1),		s_exc)
+	jr	ra
+	 move	len, zero
+dst_unaligned:
+	/*
+	 * dst is unaligned
+	 * t0 = src & ADDRMASK
+	 * t1 = dst & ADDRMASK; T1 > 0
+	 * len >= NBYTES
+	 *
+	 * Copy enough bytes to align dst
+	 * Set match = (src and dst have same alignment)
+	 */
+#define match rem
+EXC(	LDFIRST	t3, FIRST(0)(src),	l_exc)
+	ADD	t2, zero, NBYTES
+EXC(	LDREST	t3, REST(0)(src),	l_exc_copy)
+	SUB	t2, t2, t1	# t2 = number of bytes copied
+	xor	match, t0, t1
+EXC(	STFIRST t3, FIRST(0)(dst),	s_exc)
+	beq	len, t2, done
+	 SUB	len, len, t2
+	ADD	dst, dst, t2
+	beqz	match, both_aligned
+	 ADD	src, src, t2
+
+src_unaligned_dst_aligned:
+	SRL	t0, len, LOG_NBYTES+2    # +2 for 4 units/iter
+	PREF(	0, 3*32(src) )
+	beqz	t0, cleanup_src_unaligned
+	 and	rem, len, (4*NBYTES-1)   # rem = len % 4*NBYTES
+	PREF(	1, 3*32(dst) )
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC(	LDFIRST	t0, FIRST(0)(src),	l_exc)
+EXC(	LDFIRST	t1, FIRST(1)(src),	l_exc_copy)
+	SUB     len, len, 4*NBYTES
+EXC(	LDREST	t0, REST(0)(src),	l_exc_copy)
+EXC(	LDREST	t1, REST(1)(src),	l_exc_copy)
+EXC(	LDFIRST	t2, FIRST(2)(src),	l_exc_copy)
+EXC(	LDFIRST	t3, FIRST(3)(src),	l_exc_copy)
+EXC(	LDREST	t2, REST(2)(src),	l_exc_copy)
+EXC(	LDREST	t3, REST(3)(src),	l_exc_copy)
+	PREF(	0, 9*32(src) )	   	# 0 is PREF_LOAD  (not streamed)
+	ADD	src, src, 4*NBYTES
+#ifdef CONFIG_CPU_SB1
+	nop			   	# improves slotting
+#endif
+EXC(	STORE	t0, UNIT(0)(dst),	s_exc_p4u)
+EXC(	STORE	t1, UNIT(1)(dst),	s_exc_p3u)
+EXC(	STORE	t2, UNIT(2)(dst),	s_exc_p2u)
+EXC(	STORE	t3, UNIT(3)(dst),	s_exc_p1u)
+	PREF(	1, 9*32(dst) )     	# 1 is PREF_STORE (not streamed)
+	bne	len, rem, 1b
+	 ADD	dst, dst, 4*NBYTES
+
+cleanup_src_unaligned:
+	beqz	len, done
+	 and	rem, len, NBYTES-1  # rem = len % NBYTES
+	beq	rem, len, copy_bytes
+1:
+EXC(	 LDFIRST t0, FIRST(0)(src),	l_exc)
+EXC(	LDREST	t0, REST(0)(src),	l_exc_copy)
+	ADD	src, src, NBYTES
+	SUB	len, len, NBYTES
+EXC(	STORE	t0, 0(dst),		s_exc_p1u)
+	bne	len, rem, 1b
+	 ADD	dst, dst, NBYTES
 
-memcpy_u_src:
-	bnez	t8, small_memcpy		# < 8 bytes?
-	 move	t2, a2
-
-	addiu	t0, a1, 7			# t0: how much to align
-	ori	t0, 7
-	xori	t0, 7
-	subu	t0, a1
-
-	UEX(ulw, t1, 0(a1), l_fixup)		# dword alignment
-	UEX(ulw, t2, 4(a1), l_fixup)
-	UEX(usw, t1, 0(a0), s_fixup)
-	UEX(usw, t2, 4(a0), s_fixup)
-
-	addu	a1, t0				# src
-	addu	a0, t0				# dst
-	subu	a2, t0				# len
-
-	sltiu	t8, a2, 56
-	bnez	t8, u_do_end_words
-	 andi	t8, a2, 0x3c
-
-	andi	t8, a1, 8			# now qword aligned?
-
-u_qword_align:
-	beqz	t8, u_oword_align
-	 andi	t8, a1, 0x10
-
-	EX(lw, t0, 0x00(a1), l_fixup)
-	EX(lw, t1, 0x04(a1), l_fixup)
-	subu	a2, a2, 0x8
-	UEX(usw, t0, 0x00(a0), s_fixup)
-	UEX(usw, t1, 0x04(a0), s_fixup)
-	addu	a1, a1, 0x8
-	andi	t8, a1, 0x10
-	addu	a0, a0, 0x8
-
-u_oword_align:
-	beqz	t8, u_begin_movement
-	 srl	t8, a2, 0x7
-
-	EX(lw, t3, 0x08(a1), l_fixup)
-	EX(lw, t4, 0x0c(a1), l_fixup)
-	EX(lw, t0, 0x00(a1), l_fixup)
-	EX(lw, t1, 0x04(a1), l_fixup)
-	UEX(usw, t3, 0x08(a0), s_fixup)
-	UEX(usw, t4, 0x0c(a0), s_fixup)
-	UEX(usw, t0, 0x00(a0), s_fixup)
-	UEX(usw, t1, 0x04(a0), s_fixup)
-	subu	a2, a2, 0x10
-	addu	a1, a1, 0x10
-	srl	t8, a2, 0x7
-	addu	a0, a0, 0x10
-
-u_begin_movement:
-	beqz	t8, 0f
-	 andi	t2, a2, 0x40
-
-u_move_128bytes:
-	UMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-	UMOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4)
-	UMOVE_BIGCHUNK(a1, a0, 0x40, t0, t1, t3, t4)
-	UMOVE_BIGCHUNK(a1, a0, 0x60, t0, t1, t3, t4)
-	subu	t8, t8, 0x01
-	addu	a1, a1, 0x80
-	bnez	t8, u_move_128bytes
-	 addu	a0, a0, 0x80
-
-0:
-	beqz	t2, 1f
-	 andi	t2, a2, 0x20
-
-u_move_64bytes:
-	UMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-	UMOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4)
-	addu	a1, a1, 0x40
-	addu	a0, a0, 0x40
+copy_bytes_checklen:
+	beqz	len, done
+	 nop
+copy_bytes:
+	/* 0 < len < NBYTES  */
+#define COPY_BYTE(N)			\
+EXC(	lb	t0, N(src), l_exc);	\
+	SUB	len, len, 1;		\
+	beqz	len, done;		\
+EXC(	 sb	t0, N(dst), s_exc_p1)
+
+	COPY_BYTE(0)
+	COPY_BYTE(1)
+#ifdef USE_DOUBLE
+	COPY_BYTE(2)
+	COPY_BYTE(3)
+	COPY_BYTE(4)
+	COPY_BYTE(5)
+#endif
+EXC(	lb	t0, NBYTES-2(src), l_exc)
+	SUB	len, len, 1
+	jr	ra
+EXC(	 sb	t0, NBYTES-2(dst), s_exc_p1)
+done:
+	jr	ra
+	 nop
+	END(memcpy)
 
+l_exc_copy:
+	/*
+	 * Copy bytes from src until faulting load address (or until a
+	 * lb faults)
+	 *
+	 * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+	 * may be more than a byte beyond the last address.
+	 * Hence, the lb below may get an exception.
+	 *
+	 * Assumes src < THREAD_BUADDR($28)
+	 */
+	lw	t0, THREAD_BUADDR($28)
 1:
-	beqz	t2, u_do_end_words
-	 andi	t8, a2, 0x1c
+EXC(	lb	t1, 0(src),	l_exc)
+	ADD	src, src, 1
+	sb	t1, 0(dst)	# can't fault -- we're copy_from_user
+	bne	src, t0, 1b
+	 ADD	dst, dst, 1
+l_exc:
+	lw	t0, THREAD_BUADDR($28)	# t0 is just past last good address
+	 nop
+	subu	len, AT, t0		# len number of uncopied bytes
+	/*
+	 * Here's where we rely on src and dst being incremented in tandem,
+	 *   See (3) above.
+	 * dst += (fault addr - src) to put dst at first byte to clear
+	 */
+	addu	dst, t0			# compute start address in a1
+	subu	dst, src
+	/*
+	 * Clear len bytes starting at dst.  Can't call __bzero because it
+	 * might modify len.  An inefficient loop for these rare times...
+	 */
+	beqz	len, done
+	 SUB	src, len, 1
+1:	sb	zero, 0(dst)
+	ADD	dst, dst, 1
+	bnez	src, 1b
+	 SUB	src, src, 1
+	jr	ra
+	 nop
 
-u_move_32bytes:
-	UMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-	andi	t8, a2, 0x1c
-	addu	a1, a1, 0x20
-	addu	a0, a0, 0x20
-
-u_do_end_words:
-	beqz	t8, u_maybe_end_cruft
-	 srl	t8, t8, 0x2
-
-u_end_words:
-	EX(lw, t0, 0x00(a1), l_fixup)
-	subu	t8, t8, 0x1
-	UEX(usw, t0, 0x00(a0), s_fixup)
-	addu	a1, a1, 0x4
-	bnez	t8, u_end_words
-	 addu	a0, a0, 0x4
-
-u_maybe_end_cruft:
-	andi	t2, a2, 0x3
-
-u_cannot_optimize:
-	beqz	t2, out
-	 move	a2, t2
 
-u_end_bytes:
-	EX(lb, t0, (a1), l_fixup)
-	subu	a2, a2, 0x1
-	EX(sb, t0, (a0), s_fixup)
-	addu	a1, a1, 0x1
-	bnez	a2, u_end_bytes
-	 addu	a0, a0, 0x1
+#define SEXC(n)				\
+s_exc_p ## n ## u:			\
+	jr	ra;			\
+	 ADD	len, len, n*NBYTES
+
+SEXC(8)
+SEXC(7)
+SEXC(6)
+SEXC(5)
+SEXC(4)
+SEXC(3)
+SEXC(2)
+SEXC(1)
 
+s_exc_p1:
 	jr	ra
-	 move	a2, zero
-	END(memcpy)
-
-/* descending order, destination aligned  */
-#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
-	lw	t0, (offset + 0x10)(src); \
-	lw	t1, (offset + 0x14)(src); \
-	lw	t2, (offset + 0x18)(src); \
-	lw	t3, (offset + 0x1c)(src); \
-	sw	t0, (offset + 0x10)(dst); \
-	sw	t1, (offset + 0x14)(dst); \
-	sw	t2, (offset + 0x18)(dst); \
-	sw	t3, (offset + 0x1c)(dst); \
-	lw	t0, (offset + 0x00)(src); \
-	lw	t1, (offset + 0x04)(src); \
-	lw	t2, (offset + 0x08)(src); \
-	lw	t3, (offset + 0x0c)(src); \
-	sw	t0, (offset + 0x00)(dst); \
-	sw	t1, (offset + 0x04)(dst); \
-	sw	t2, (offset + 0x08)(dst); \
-	sw	t3, (offset + 0x0c)(dst)
-
-/* descending order, destination ununaligned  */
-#define RUMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
-	lw	t0, (offset + 0x10)(src); \
-	lw	t1, (offset + 0x14)(src); \
-	lw	t2, (offset + 0x18)(src); \
-	lw	t3, (offset + 0x1c)(src); \
-	usw	t0, (offset + 0x10)(dst); \
-	usw	t1, (offset + 0x14)(dst); \
-	usw	t2, (offset + 0x18)(dst); \
-	usw	t3, (offset + 0x1c)(dst); \
-	lw	t0, (offset + 0x00)(src); \
-	lw	t1, (offset + 0x04)(src); \
-	lw	t2, (offset + 0x08)(src); \
-	lw	t3, (offset + 0x0c)(src); \
-	usw	t0, (offset + 0x00)(dst); \
-	usw	t1, (offset + 0x04)(dst); \
-	usw	t2, (offset + 0x08)(dst); \
-	usw	t3, (offset + 0x0c)(dst)
+	 ADD	len, len, 1
+s_exc:
+	jr	ra
+	 nop
 
 	.align	5
 LEAF(memmove)
 	addu	t0, a0, a2
-	sltu	t0, a1, t0			# dst + len <= src -> memcpy
 	addu	t1, a1, a2
+	sltu	t0, a1, t0			# dst + len <= src -> memcpy
 	sltu	t1, a0, t1			# dst >= src + len -> memcpy
 	and	t0, t1
 	beqz	t0, __memcpy
@@ -412,152 +450,14 @@
 	beqz	a2, r_out
 	END(memmove)
 
+	/* fall through to __rmemcpy */
 LEAF(__rmemcpy)					/* a0=dst a1=src a2=len */
-	sltu	t0, a1, a0
+	 sltu	t0, a1, a0
 	beqz	t0, r_end_bytes_up		# src >= dst
 	 nop
 	addu	a0, a2				# dst = dst + len
 	addu	a1, a2				# src = src + len
 
-#if 0 /* Horror fix */
-	xor	t0, a0, a1
-	andi	t0, t0, 0x3
-	move	t7, a0
-	beqz	t0, r_can_align
-	 sltiu	t8, a2, 0x8
-
-	b	r_memcpy_u_src			# bad alignment
-	 move	t2, a2
-
-r_can_align:
-	bnez	t8, r_small_memcpy		# < 8 bytes to copy
-	 move	t2, a2
-
-	beqz	a2, r_out
-	 andi	t8, a1, 0x1
-
-r_hword_align:
-	beqz	t8, r_word_align
-	 andi	t8, a1, 0x2
-
-	lb	t0, -1(a1)
-	subu	a2, a2, 0x1
-	sb	t0, -1(a0)
-	subu	a1, a1, 0x1
-	subu	a0, a0, 0x1
-	andi	t8, a1, 0x2
-
-r_word_align:
-	beqz	t8, r_dword_align
-	 sltiu	t8, a2, 56
-	
-	lh	t0, -2(a1)
-	subu	a2, a2, 0x2
-	sh	t0, -2(a0)
-	sltiu	t8, a2, 56
-	subu	a0, a0, 0x2
-	subu	a1, a1, 0x2
-
-r_dword_align:
-	bnez	t8, r_do_end_words
-	 move	t8, a2
-
-	andi	t8, a1, 0x4
-	beqz	t8, r_qword_align
-	 andi	t8, a1, 0x8
-
-	lw	t0, -4(a1)
-	subu	a2, a2, 0x4
-	sw	t0, -4(a0)
-	subu	a1, a1, 0x4
-	subu	a0, a0, 0x4
-	andi	t8, a1, 0x8
-
-r_qword_align:
-	beqz	t8, r_oword_align
-	 andi	t8, a1, 0x10
-
-	subu	a1, a1, 0x8
-	lw	t0, 0x04(a1)
-	lw	t1, 0x00(a1)
-	subu	a0, a0, 0x8
-	sw	t0, 0x04(a0)
-	sw	t1, 0x00(a0)
-	subu	a2, a2, 0x8
-
-	andi	t8, a1, 0x10
-
-r_oword_align:
-	beqz	t8, r_begin_movement
-	 srl	t8, a2, 0x7
-
-	subu	a1, a1, 0x10
-	lw	t3, 0x08(a1)			# assumes subblock ordering
-	lw	t4, 0x0c(a1)
-	lw	t0, 0x00(a1)
-	lw	t1, 0x04(a1)
-	subu	a0, a0, 0x10
-	sw	t3, 0x08(a0)
-	sw	t4, 0x0c(a0)
-	sw	t0, 0x00(a0)
-	sw	t1, 0x04(a0)
-	subu	a2, a2, 0x10
-	srl	t8, a2, 0x7
-
-r_begin_movement:
-	beqz	t8, 0f
-	 andi	t2, a2, 0x40
-
-r_move_128bytes:
-	RMOVE_BIGCHUNK(a1, a0, -0x80, t0, t1, t3, t4)
-	RMOVE_BIGCHUNK(a1, a0, -0x60, t0, t1, t3, t4)
-	RMOVE_BIGCHUNK(a1, a0, -0x40, t0, t1, t3, t4)
-	RMOVE_BIGCHUNK(a1, a0, -0x20, t0, t1, t3, t4)
-	subu	t8, t8, 0x01
-	subu	a1, a1, 0x80
-	bnez	t8, r_move_128bytes
-	 subu	a0, a0, 0x80
-
-0:
-	beqz	t2, 1f
-	 andi	t2, a2, 0x20
-
-r_move_64bytes:
-	subu	a1, a1, 0x40
-	subu	a0, a0, 0x40
-	RMOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4)
-	RMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-
-1:
-	beqz	t2, r_do_end_words
-	 andi	t8, a2, 0x1c
-
-r_move_32bytes:
-	subu	a1, a1, 0x20
-	subu	a0, a0, 0x20
-	RMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-	andi	t8, a2, 0x1c
-
-r_do_end_words:
-	beqz	t8, r_maybe_end_cruft
-	 srl	t8, t8, 0x2
-
-r_end_words:
-	lw	t0, -4(a1)
-	subu	t8, t8, 0x1
-	sw	t0, -4(a0)
-	subu	a1, a1, 0x4
-	bnez	t8, r_end_words
-	 subu	a0, a0, 0x4
-
-r_maybe_end_cruft:
-	andi	t2, a2, 0x3
-
-r_small_memcpy:
-	beqz	t2, r_out
-	 move	a2, t2
-#endif /* Horror fix */
-
 r_end_bytes:
 	lb	t0, -1(a1)
 	subu	a2, a2, 0x1
@@ -580,140 +480,4 @@
 
 	jr	ra
 	 move	a2, zero
-
-#if 0 /* Horror fix */
-/* ------------------------------------------------------------------------- */
-
-/* Bad, bad.  At least try to align the source  */
-
-r_memcpy_u_src:
-	bnez	t8, r_small_memcpy		# < 8 bytes?
-	 move	t2, a2
-
-	andi	t0, a1, 7			# t0: how much to align
-
-	ulw	t1, -8(a1)			# dword alignment
-	ulw	t2, -4(a1)
-	usw	t1, -8(a0)
-	usw	t2, -4(a0)
-
-	subu	a1, t0				# src
-	subu	a0, t0				# dst
-	subu	a2, t0				# len
-
-	sltiu	t8, a2, 56
-	bnez	t8, ru_do_end_words
-	 andi	t8, a2, 0x3c
-
-	andi	t8, a1, 8			# now qword aligned?
-
-ru_qword_align:
-	beqz	t8, ru_oword_align
-	 andi	t8, a1, 0x10
-
-	subu	a1, a1, 0x8
-	lw	t0, 0x00(a1)
-	lw	t1, 0x04(a1)
-	subu	a0, a0, 0x8
-	usw	t0, 0x00(a0)
-	usw	t1, 0x04(a0)
-	subu	a2, a2, 0x8
-
-	andi	t8, a1, 0x10
-
-ru_oword_align:
-	beqz	t8, ru_begin_movement
-	 srl	t8, a2, 0x7
-
-	subu	a1, a1, 0x10
-	lw	t3, 0x08(a1)			# assumes subblock ordering
-	lw	t4, 0x0c(a1)
-	lw	t0, 0x00(a1)
-	lw	t1, 0x04(a1)
-	subu	a0, a0, 0x10
-	usw	t3, 0x08(a0)
-	usw	t4, 0x0c(a0)
-	usw	t0, 0x00(a0)
-	usw	t1, 0x04(a0)
-	subu	a2, a2, 0x10
-
-	srl	t8, a2, 0x7
-
-ru_begin_movement:
-	beqz	t8, 0f
-	 andi	t2, a2, 0x40
-
-ru_move_128bytes:
-	RUMOVE_BIGCHUNK(a1, a0, -0x80, t0, t1, t3, t4)
-	RUMOVE_BIGCHUNK(a1, a0, -0x60, t0, t1, t3, t4)
-	RUMOVE_BIGCHUNK(a1, a0, -0x40, t0, t1, t3, t4)
-	RUMOVE_BIGCHUNK(a1, a0, -0x20, t0, t1, t3, t4)
-	subu	t8, t8, 0x01
-	subu	a1, a1, 0x80
-	bnez	t8, ru_move_128bytes
-	 subu	a0, a0, 0x80
-
-0:
-	beqz	t2, 1f
-	 andi	t2, a2, 0x20
-
-ru_move_64bytes:
-	subu	a1, a1, 0x40
-	subu	a0, a0, 0x40
-	RUMOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4)
-	RUMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-
-1:
-	beqz	t2, ru_do_end_words
-	 andi	t8, a2, 0x1c
-
-ru_move_32bytes:
-	subu	a1, a1, 0x20
-	subu	a0, a0, 0x20
-	RUMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4)
-	andi	t8, a2, 0x1c
-
-ru_do_end_words:
-	beqz	t8, ru_maybe_end_cruft
-	 srl	t8, t8, 0x2
-
-ru_end_words:
-	lw	t0, -4(a1)
-	usw	t0, -4(a0)
-	subu	t8, t8, 0x1
-	subu	a1, a1, 0x4
-	bnez	t8, ru_end_words
-	 subu	a0, a0, 0x4
-
-ru_maybe_end_cruft:
-	andi	t2, a2, 0x3
-
-ru_cannot_optimize:
-	beqz	t2, r_out
-	 move	a2, t2
-
-ru_end_bytes:
-	lb	t0, -1(a1)
-	subu	a2, a2, 0x1
-	sb	t0, -1(a0)
-	subu	a1, a1, 0x1
-	bnez	a2, ru_end_bytes
-	 subu	a0, a0, 0x1
-
-	jr	ra
-	 move	a2, zero
-#endif /* Horror fix */
 	END(__rmemcpy)
-
-l_fixup:					# clear the rest of the buffer
-	lw	t0, THREAD_BUADDR($28)
-	 nop
-	subu	a2, AT, t0			# a2 bytes to go
-	addu	a0, t0				# compute start address in a1
-	subu	a0, a1
-	j	__bzero
-	 move	a1, zero
-
-s_fixup:
-	jr	ra
-	 nop
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/r3k_dump_tlb.c linux/arch/mips/lib/r3k_dump_tlb.c
--- linux.orig/arch/mips/lib/r3k_dump_tlb.c	2000-07-10 05:18:15.000000000 +0000
+++ linux/arch/mips/lib/r3k_dump_tlb.c	2002-07-20 01:08:25.000000000 +0000
@@ -12,11 +12,12 @@
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
+#include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-#define mips_tlb_entries 64
+extern int r3k_have_wired_reg;	/* defined in tlb-r3k.c */
 
 void
 dump_tlb(int first, int last)
@@ -65,16 +66,16 @@
 void
 dump_tlb_all(void)
 {
-	dump_tlb(0, mips_tlb_entries - 1);
+	dump_tlb(0, mips_cpu.tlbsize - 1);
 }
 
 void
 dump_tlb_wired(void)
 {
-	int	wired = 7;
+	int wired = r3k_have_wired_reg ? get_wired() : 8;
 
 	printk("Wired: %d", wired);
-	dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
+	dump_tlb(0, wired - 1);
 }
 
 void
@@ -103,7 +104,8 @@
 void
 dump_tlb_nonwired(void)
 {
-	dump_tlb(8, mips_tlb_entries - 1);
+	int wired = r3k_have_wired_reg ? get_wired() : 8;
+	dump_tlb(wired, mips_cpu.tlbsize - 1);
 }
 
 void
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/strlen_user.S linux/arch/mips/lib/strlen_user.S
--- linux.orig/arch/mips/lib/strlen_user.S	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/strlen_user.S	2002-07-20 01:08:40.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: strlen_user.S,v 1.3 1999/08/21 22:19:11 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -35,7 +34,7 @@
 	bnez	t0, 1b
 	subu	v0, a0
 	jr	ra
-	END(__strlen_user_nocheck_asm)
+	END(__strlen_user_asm)
 
 	.section __ex_table,"a"
 	PTR	1b, fault
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/strncpy_user.S linux/arch/mips/lib/strncpy_user.S
--- linux.orig/arch/mips/lib/strncpy_user.S	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/strncpy_user.S	2002-07-20 01:08:38.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: strncpy_user.S,v 1.3 1999/08/21 22:19:11 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/strnlen_user.S linux/arch/mips/lib/strnlen_user.S
--- linux.orig/arch/mips/lib/strnlen_user.S	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/strnlen_user.S	2002-07-20 01:08:30.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: strnlen_user.S,v 1.2 1999/11/19 20:35:21 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/lib/watch.S linux/arch/mips/lib/watch.S
--- linux.orig/arch/mips/lib/watch.S	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/lib/watch.S	2002-07-20 01:08:29.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/Makefile linux/arch/mips/math-emu/Makefile
--- linux.orig/arch/mips/math-emu/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/Makefile	2002-07-20 01:08:22.000000000 +0000
@@ -6,10 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-EXTRA_ASFLAGS = -mips2 -mcpu=r4000
+USE_STANDARD_AS_RULE := true
 
 O_TARGET:= fpu_emulator.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/cp1emu.c linux/arch/mips/math-emu/cp1emu.c
--- linux.orig/arch/mips/math-emu/cp1emu.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips/math-emu/cp1emu.c	2002-07-20 01:08:39.000000000 +0000
@@ -34,6 +34,7 @@
  * Note if you know that you won't have an fpu, then you'll get much 
  * better performance by compiling with -msoft-float!
  */
+#include <linux/compiler.h>
 #include <linux/mm.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -66,7 +67,7 @@
 
 /* Function which emulates the instruction in a branch delay slot. */
 
-static int mips_dsemul(struct pt_regs *, mips_instruction, vaddr_t);
+static int mips_dsemul(struct pt_regs *, mips_instruction, unsigned long);
 
 /* Function which emulates a floating point instruction. */
 
@@ -167,54 +168,6 @@
 #define REG_TO_VA (vaddr_t)
 #define VA_TO_REG (unsigned long)
 
-static unsigned long mips_get_word(struct pt_regs *xcp, void *va, int *perr)
-{
-	unsigned long temp;
-
-	if (!user_mode(xcp)) {
-		*perr = 0;
-		return (*(unsigned long *) va);
-	}
-
-	*perr = (int) get_user(temp, (unsigned long *) va);
-	return temp;
-}
-
-static unsigned long long
-mips_get_dword(struct pt_regs *xcp, void *va, int *perr)
-{
-	unsigned long long temp;
-
-	if (!user_mode(xcp)) {
-		*perr = 0;
-		return (*(unsigned long long *) va);
-	}
-
-	*perr = (int) get_user(temp, (unsigned long long *) va);
-	return temp;
-}
-
-static int mips_put_word(struct pt_regs *xcp, void *va, unsigned long val)
-{
-	if (!user_mode(xcp)) {
-		*(unsigned long *) va = val;
-		return 0;
-	}
-
-	return put_user(val, (unsigned long *) va);
-}
-
-static int mips_put_dword(struct pt_regs *xcp, void *va, long long val)
-{
-	if (!user_mode(xcp)) {
-		*(unsigned long long *) va = val;
-		return 0;
-	}
-
-	return put_user(val, (unsigned long long *) va);
-}
-
-
 /*
  * In the Linux kernel, we support selection of FPR format on the
  * basis of the Status.FR bit.  This does imply that, if a full 32
@@ -230,25 +183,24 @@
  * Two instructions if the instruction is in a branch delay slot.
  */
 
-static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
+static int cop1Emulate(struct pt_regs *regs, struct mips_fpu_soft_struct *ctx)
 {
+	vaddr_t emulpc, contpc;
 	mips_instruction ir;
-	vaddr_t emulpc;
-	vaddr_t contpc;
 	unsigned int cond;
 	int err = 0;
 
-	ir = mips_get_word(xcp, REG_TO_VA xcp->cp0_epc, &err);
+	err = get_user(ir, (mips_instruction *) regs->cp0_epc);
 	if (err) {
 		fpuemuprivate.stats.errors++;
 		return SIGBUS;
 	}
 
 	/* XXX NEC Vr54xx bug workaround */
-	if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
-		xcp->cp0_cause &= ~CAUSEF_BD;
+	if ((regs->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
+		regs->cp0_cause &= ~CAUSEF_BD;
 
-	if (xcp->cp0_cause & CAUSEF_BD) {
+	if (regs->cp0_cause & CAUSEF_BD) {
 		/*
 		 * The instruction to be emulated is in a branch delay slot
 		 * which means that we have to  emulate the branch instruction
@@ -261,24 +213,27 @@
 		 * Linux MIPS branch emulator operates on context, updating the
 		 * cp0_epc.
 		 */
-		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
+		emulpc = REG_TO_VA(regs->cp0_epc + 4);	/* Snapshot emulation target */
 
-		if (__compute_return_epc(xcp)) {
+		if (__compute_return_epc(regs)) {
 #ifdef CP1DBG
 			printk("failed to emulate branch at %p\n",
-				    REG_TO_VA(xcp->cp0_epc));
+				    REG_TO_VA(regs->cp0_epc));
 #endif
-			return SIGILL;;
+			return SIGILL;
 		}
-		ir = mips_get_word(xcp, emulpc, &err);
+		err = get_user(ir, (mips_instruction *) emulpc);
 		if (err) {
 			fpuemuprivate.stats.errors++;
 			return SIGBUS;
 		}
-		contpc = REG_TO_VA xcp->cp0_epc;
+		/* __computer_return_epc() will have updated cp0_epc */
+		contpc = REG_TO_VA regs->cp0_epc;
+		/* In order not to confuse ptrace() et al, tweak context */
+		regs->cp0_epc = VA_TO_REG emulpc - 4;
 	} else {
-		emulpc = REG_TO_VA xcp->cp0_epc;
-		contpc = REG_TO_VA xcp->cp0_epc + 4;
+		emulpc = REG_TO_VA regs->cp0_epc;
+		contpc = REG_TO_VA regs->cp0_epc + 4;
 	}
 
 emul:
@@ -289,12 +244,13 @@
 #ifndef SINGLE_ONLY_FPU
 	case ldc1_op:
 		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
+			u64 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
+			          MIPSInst_SIMM(ir);
 			int ft = MIPSInst_RT(ir);
-			if (!(xcp->cp0_status & ST0_FR))
+
+			if (!(regs->cp0_status & ST0_FR))
 				ft &= ~1;
-			ctx->regs[ft] = mips_get_dword(xcp, va, &err);
+			err = get_user(ctx->regs[ft], va);
 			fpuemuprivate.stats.loads++;
 			if (err) {
 				fpuemuprivate.stats.errors++;
@@ -305,13 +261,14 @@
 
 	case sdc1_op:
 		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
+			fpureg_t *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
+			               MIPSInst_SIMM(ir);
 			int ft = MIPSInst_RT(ir);
-			if (!(xcp->cp0_status & ST0_FR))
+
+			if (!(regs->cp0_status & ST0_FR))
 				ft &= ~1;
 			fpuemuprivate.stats.stores++;
-			if (mips_put_dword(xcp, va, ctx->regs[ft])) {
+			if (put_user(ctx->regs[ft], va)) {
 				fpuemuprivate.stats.errors++;
 				return SIGBUS;
 			}
@@ -321,19 +278,20 @@
 
 	case lwc1_op:
 		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			fpureg_t val;
+			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
+			               MIPSInst_SIMM(ir);
 			int ft = MIPSInst_RT(ir);
+			u32 val;
+
 			fpuemuprivate.stats.loads++;
-			val = mips_get_word(xcp, va, &err);
+			err = get_user(val, va);
 			if (err) {
 				fpuemuprivate.stats.errors++;
 				return SIGBUS;
 			}
-			if (xcp->cp0_status & ST0_FR) {
+			if (regs->cp0_status & ST0_FR) {
 				/* load whole register */
-				ctx->regs[ft] = val;
+				ctx->regs[ft] = (s64) val;
 			} else if (ft & 1) {
 				/* load to m.s. 32 bits */
 #ifdef SINGLE_ONLY_FPU
@@ -341,7 +299,7 @@
 				return SIGILL;
 #else
 				ctx->regs[(ft & ~1)] &= 0xffffffff;
-				ctx->regs[(ft & ~1)] |= val << 32;
+				ctx->regs[(ft & ~1)] |= (fpureg_t) val << 32;
 #endif
 			} else {
 				/* load to l.s. 32 bits */
@@ -353,12 +311,13 @@
 
 	case swc1_op:
 		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
+			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
+			          MIPSInst_SIMM(ir);
 			unsigned int val;
 			int ft = MIPSInst_RT(ir);
+
 			fpuemuprivate.stats.stores++;
-			if (xcp->cp0_status & ST0_FR) {
+			if (regs->cp0_status & ST0_FR) {
 				/* store whole register */
 				val = ctx->regs[ft];
 			} else if (ft & 1) {
@@ -373,7 +332,7 @@
 				/* store from l.s. 32 bits */
 				val = ctx->regs[ft];
 			}
-			if (mips_put_word(xcp, va, val)) {
+			if (put_user(val, va)) {
 				fpuemuprivate.stats.errors++;
 				return SIGBUS;
 			}
@@ -382,10 +341,10 @@
 #else				/* old 32-bit fpu registers */
 	case lwc1_op:
 		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			ctx->regs[MIPSInst_RT(ir)] =
-			    mips_get_word(xcp, va, &err);
+			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
+			          MIPSInst_SIMM(ir);
+			err = get_user(ctx->regs[MIPSInst_RT(ir)], va);
+
 			fpuemuprivate.stats.loads++;
 			if (err) {
 				fpuemuprivate.stats.errors++;
@@ -396,11 +355,10 @@
 
 	case swc1_op:
 		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
+			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
+			          MIPSInst_SIMM(ir);
 			fpuemuprivate.stats.stores++;
-			if (mips_put_word
-			    (xcp, va, ctx->regs[MIPSInst_RT(ir)])) {
+			if (put_user(ctx->regs[MIPSInst_RT(ir)], va)) {
 				fpuemuprivate.stats.errors++;
 				return SIGBUS;
 			}
@@ -408,25 +366,17 @@
 		break;
 	case ldc1_op:
 		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
+			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)])
 			    + MIPSInst_SIMM(ir);
 			unsigned int rt = MIPSInst_RT(ir) & ~1;
 			int errs = 0;
 			fpuemuprivate.stats.loads++;
 #if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-			ctx->regs[rt + 1] =
-			    mips_get_word(xcp, va + 0, &err);
-			errs += err;
-			ctx->regs[rt + 0] =
-			    mips_get_word(xcp, va + 4, &err);
-			errs += err;
+			err = get_user(ctx->regs[rt + 1], va + 0);
+			err |= get_user(ctx->regs[rt + 0], va + 1);
 #else
-			ctx->regs[rt + 0] =
-			    mips_get_word(xcp, va + 0, &err);
-			errs += err;
-			ctx->regs[rt + 1] =
-			    mips_get_word(xcp, va + 4, &err);
-			errs += err;
+			err = get_user(ctx->regs[rt + 0], va + 0);
+			err |= get_user(ctx->regs[rt + 1], va + 1);
 #endif
 			if (err)
 				return SIGBUS;
@@ -435,19 +385,18 @@
 
 	case sdc1_op:
 		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
+			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
+			          MIPSInst_SIMM(ir);
 			unsigned int rt = MIPSInst_RT(ir) & ~1;
+
 			fpuemuprivate.stats.stores++;
 #if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-			if (mips_put_word(xcp, va + 0, ctx->regs[rt + 1]))
-				return SIGBUS;
-			if (mips_put_word(xcp, va + 4, ctx->regs[rt + 0]))
+			if (put_user(ctx->regs[rt + 1], va + 0)
+			    || put_user(ctx->regs[rt + 0], va + 1))
 				return SIGBUS;
 #else
-			if (mips_put_word(xcp, va + 0, ctx->regs[rt + 0]))
-				return SIGBUS;
-			if (mips_put_word(xcp, va + 4, ctx->regs[rt + 1]))
+			if (put_user(ctx->regs[rt + 0], va + 0)
+			    || put_user(ctx->regs[rt + 1], va + 1))
 				return SIGBUS;
 #endif
 		}
@@ -463,9 +412,9 @@
 			/* copregister fs -> gpr[rt] */
 			if (MIPSInst_RT(ir) != 0) {
 				int fs = MIPSInst_RD(ir);
-				if (!(xcp->cp0_status & ST0_FR))
+				if (!(regs->cp0_status & ST0_FR))
 					fs &= ~1;
-				xcp->regs[MIPSInst_RT(ir)] = ctx->regs[fs];
+				regs->regs[MIPSInst_RT(ir)] = ctx->regs[fs];
 			}
 			break;
 
@@ -473,11 +422,11 @@
 			/* copregister fs <- rt */
 				fpureg_t value;
 				int fs = MIPSInst_RD(ir);
-				if (!(xcp->cp0_status & ST0_FR))
+				if (!(regs->cp0_status & ST0_FR))
 					fs &= ~1;
 				value =
 				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
+				     0) ? 0 : regs->regs[MIPSInst_RT(ir)];
 				ctx->regs[fs] = value;
 			break;
 		}
@@ -493,7 +442,7 @@
 					/* illegal register in single-float mode */
 					return SIGILL;
 #else
-					if (!(xcp->cp0_status & ST0_FR)) {
+					if (!(regs->cp0_status & ST0_FR)) {
 						/* move from m.s. 32 bits */
 						value =
 						    ctx->
@@ -502,7 +451,7 @@
 					}
 #endif
 				}
-				xcp->regs[MIPSInst_RT(ir)] = value;
+				regs->regs[MIPSInst_RT(ir)] = value;
 			}
 			break;
 
@@ -514,14 +463,14 @@
 					value = 0;
 				else
 					value =
-					    (unsigned int) xcp->
+					    (unsigned int) regs->
 					    regs[MIPSInst_RT(ir)];
 				if (MIPSInst_RD(ir) & 1) {
 #ifdef SINGLE_ONLY_FPU
 					/* illegal register in single-float mode */
 					return SIGILL;
 #else
-					if (!(xcp->cp0_status & ST0_FR)) {
+					if (!(regs->cp0_status & ST0_FR)) {
 						/* move to m.s. 32 bits */
 						ctx->
 						    regs[
@@ -550,7 +499,7 @@
 			if (MIPSInst_RT(ir) != 0) {
 				unsigned value =
 				    ctx->regs[MIPSInst_RD(ir)];
-				xcp->regs[MIPSInst_RT(ir)] = value;
+				regs->regs[MIPSInst_RT(ir)] = value;
 			}
 			break;
 
@@ -560,7 +509,7 @@
 				unsigned value;
 				value =
 				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
+				     0) ? 0 : regs->regs[MIPSInst_RT(ir)];
 				ctx->regs[MIPSInst_RD(ir)] = value;
 			}
 			break;
@@ -576,7 +525,7 @@
 #ifdef CSRTRACE
 					printk
 					    ("%p gpr[%d]<-csr=%08x\n",
-					     REG_TO_VA(xcp->cp0_epc),
+					     REG_TO_VA(regs->cp0_epc),
 					     MIPSInst_RT(ir), value);
 #endif
 				} else if (MIPSInst_RD(ir) == FPCREG_RID)
@@ -584,7 +533,7 @@
 				else
 					value = 0;
 				if (MIPSInst_RT(ir))
-					xcp->regs[MIPSInst_RT(ir)] = value;
+					regs->regs[MIPSInst_RT(ir)] = value;
 			}
 			break;
 
@@ -596,7 +545,7 @@
 				if (MIPSInst_RT(ir) == 0)
 					value = 0;
 				else
-					value = xcp->regs[MIPSInst_RT(ir)];
+					value = regs->regs[MIPSInst_RT(ir)];
 
 				/* we only have one writable control reg
 				 */
@@ -604,11 +553,14 @@
 #ifdef CSRTRACE
 					printk
 					    ("%p gpr[%d]->csr=%08x\n",
-					     REG_TO_VA(xcp->cp0_epc),
+					     REG_TO_VA(regs->cp0_epc),
 					     MIPSInst_RT(ir), value);
 #endif
 					ctx->sr = value;
-					/* copy new rounding mode to ieee library state! */
+					/* copy new rounding mode and
+					   flush bit to ieee library state! */
+					ieee754_csr.nod =
+					    (ctx->sr & 0x1000000) != 0;
 					ieee754_csr.rm =
 					    ieee_rm[value & 0x3];
 				}
@@ -618,7 +570,7 @@
 		case bc_op: {
 			int likely = 0;
 
-			if (xcp->cp0_cause & CAUSEF_BD)
+			if (regs->cp0_cause & CAUSEF_BD)
 				return SIGILL;
 
 #if __mips >= 4
@@ -641,15 +593,15 @@
 				return SIGILL;
 			}
 
-			xcp->cp0_cause |= CAUSEF_BD;
+			regs->cp0_cause |= CAUSEF_BD;
 			if (cond) {
 				/* branch taken: emulate dslot instruction */
-				xcp->cp0_epc += 4;
-				contpc = REG_TO_VA xcp->cp0_epc +
-				         (MIPSInst_SIMM(ir) << 2);
+				regs->cp0_epc += 4;
+				contpc = REG_TO_VA regs->cp0_epc +
+				                   (MIPSInst_SIMM(ir) << 2);
 
-				ir = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc),
-				      &err);
+				err = get_user(ir,
+					(mips_instruction *)regs->cp0_epc);
 				if (err) {
 					fpuemuprivate.stats.errors++;
 					return SIGBUS;
@@ -680,16 +632,21 @@
 				 * Single step the non-cp1 instruction in the
 				 * dslot
 				 */
-				return mips_dsemul(xcp, ir, contpc);
+				return mips_dsemul(regs, ir, contpc);
 			} else {
 				/* branch not taken */
-				if (likely)
+				if (likely) {
 					/*
 					 * branch likely nullifies dslot if not
 					 * taken
 					 */
-					xcp->cp0_epc += 4;
-					/* else continue & execute dslot as normal insn */
+					regs->cp0_epc += 4;
+					contpc += 4;
+					/*
+					 * else continue & execute dslot as
+					 * normal insn
+					 */
+				}
 			}
 			break;
 		}
@@ -701,7 +658,7 @@
 				return SIGILL;
 
 			/* a real fpu computation instruction */
-				if ((sig = fpu_emu(xcp, ctx, ir)))
+				if ((sig = fpu_emu(regs, ctx, ir)))
 					return sig;
 			}
 		}
@@ -711,7 +668,7 @@
 	case cop1x_op:
 		{
 			int sig;
-			if ((sig = fpux_emu(xcp, ctx, ir)))
+			if ((sig = fpux_emu(regs, ctx, ir)))
 				return sig;
 		}
 		break;
@@ -722,9 +679,9 @@
 		if (MIPSInst_FUNC(ir) != movc_op)
 			return SIGILL;
 		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
-		if (((ctx->sr & cond) != 0) !=
-		    ((MIPSInst_RT(ir) & 1) != 0)) return 0;
-		xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RS(ir)];
+		if (((ctx->sr & cond) != 0) != ((MIPSInst_RT(ir) & 1) != 0))
+			return 0;
+		regs->regs[MIPSInst_RD(ir)] = regs->regs[MIPSInst_RS(ir)];
 		break;
 #endif
 
@@ -733,8 +690,8 @@
 	}
 
 	/* we did it !! */
-	xcp->cp0_epc = VA_TO_REG(contpc);
-	xcp->cp0_cause &= ~CAUSEF_BD;
+	regs->cp0_epc = VA_TO_REG(contpc);
+	regs->cp0_cause &= ~CAUSEF_BD;
 	return 0;
 }
 
@@ -755,59 +712,100 @@
  *  execution of delay-slot instruction execution.
  */
 
+/* Instruction inserted following delay slot instruction to force trap */
+#define AdELOAD 0x8c000001	/* lw $0,1($0) */
+
+/* Instruction inserted following the AdELOAD to further tag the sequence */
+#define BD_COOKIE 0x0000bd36	/* tne $0,$0 with baggage */
+
+struct emuframe {
+	mips_instruction	emul;
+	mips_instruction	adel;
+	mips_instruction	cookie;
+	unsigned long	epc;
+};
+
 int do_dsemulret(struct pt_regs *xcp)
 {
+	struct emuframe *fr;
+	unsigned long epc;
+	u32 insn, cookie;
+	int err = 0;
+
+	fr = (struct emuframe *) (xcp->cp0_epc - sizeof(mips_instruction));
+
+	/* 
+	 * If we can't even access the area, something is very wrong, but we'll
+	 * leave that to the default handling
+	 */
+	if (verify_area(VERIFY_READ, fr, sizeof(struct emuframe)))
+		return 0;
+
+	/*
+	 * Do some sanity checking on the stackframe:
+	 *
+	 *  - Is the instruction pointed to by the EPC an AdELOAD?
+	 *  - Is the following memory word the BD_COOKIE?
+	 */
+	err = __get_user(insn, &fr->adel);
+	err |= __get_user(cookie, &fr->cookie);
+
+	if (unlikely(err || (insn != AdELOAD) || (cookie != BD_COOKIE))) {
+		fpuemuprivate.stats.errors++;
+
+		return 0;
+	}
+
+	/* 
+	 * At this point, we are satisfied that it's a BD emulation trap.  Yes,
+	 * a user might have deliberately put two malformed and useless
+	 * instructions in a row in his program, in which case he's in for a
+	 * nasty surprise - the next instruction will be treated as a
+	 * continuation address!  Alas, this seems to be the only way that we
+	 * can handle signals, recursion, and longjmps() in the context of
+	 * emulating the branch delay instruction.
+	 */
+
 #ifdef DSEMUL_TRACE
 	printk("desemulret\n");
 #endif
-	/* Set EPC to return to post-branch instruction */
-	xcp->cp0_epc = current->thread.dsemul_epc;
-	/*
-	 * Clear the state that got us here.
-	 */
-	current->thread.dsemul_aerpc = (unsigned long) 0;
+	if (__get_user(epc, &fr->epc)) {		/* Saved EPC */
+		/* This is not a good situation to be in */
+		force_sig(SIGBUS, current);
 
-	return 0;
-}
+		return 1;
+	}
 
+	/* Set EPC to return to post-branch instruction */
+	xcp->cp0_epc = epc;
 
-#define AdELOAD 0x8c000001	/* lw $0,1($0) */
+	return 1;
+}
 
-static int
-mips_dsemul(struct pt_regs *xcp, mips_instruction ir, vaddr_t cpc)
+static int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
+	unsigned long cpc)
 {
-	mips_instruction *dsemul_insns;
-	mips_instruction forcetrap;
 	extern asmlinkage void handle_dsemulret(void);
+	mips_instruction *dsemul_insns;
+	struct emuframe *fr;
+	int err;
 
 	if (ir == 0) {		/* a nop is easy */
-		xcp->cp0_epc = VA_TO_REG(cpc);
+		regs->cp0_epc = cpc;
+		regs->cp0_cause &= ~CAUSEF_BD;
 		return 0;
 	}
 #ifdef DSEMUL_TRACE
-	printk("desemul %p %p\n", REG_TO_VA(xcp->cp0_epc), cpc);
-#endif
+	printk("desemul %lx %lx\n", regs->cp0_epc, cpc);
 
+#endif
+ 
 	/* 
 	 * The strategy is to push the instruction onto the user stack 
 	 * and put a trap after it which we can catch and jump to 
 	 * the required address any alternative apart from full 
 	 * instruction emulation!!.
-	 */
-	dsemul_insns = (mips_instruction *) (xcp->regs[29] & ~3);
-	dsemul_insns -= 3;	/* Two instructions, plus one for luck ;-) */
-
-	/* Verify that the stack pointer is not competely insane */
-	if (verify_area(VERIFY_WRITE, dsemul_insns,
-	                sizeof(mips_instruction) * 2))
-		return SIGBUS;
-
-	if (mips_put_word(xcp, &dsemul_insns[0], ir)) {
-		fpuemuprivate.stats.errors++;
-		return SIGBUS;
-	}
-
-	/* 
+	 *
 	 * Algorithmics used a system call instruction, and
 	 * borrowed that vector.  MIPS/Linux version is a bit
 	 * more heavyweight in the interests of portability and
@@ -816,22 +814,28 @@
 	 * address error excpetion.
 	 */
 
-	/* If one is *really* paranoid, one tests for a bad stack pointer */
-	if ((xcp->regs[29] & 0x3) == 0x3)
-		forcetrap = AdELOAD - 1;
-	else
-		forcetrap = AdELOAD;
+	/* Ensure that the two instructions are in the same cache line */
+	dsemul_insns = (mips_instruction *) (regs->regs[29] & ~0xf);
+	dsemul_insns -= 4;	/* Retain 16-byte alignment */
+	fr = (struct emuframe *) dsemul_insns;
+
+	/* Verify that the stack pointer is not competely insane */
+	if (unlikely(verify_area(VERIFY_WRITE, fr, sizeof(struct emuframe))))
+		return SIGBUS;
+
+	err = __put_user(ir, &dsemul_insns[0]);
+	err |= __put_user((mips_instruction)AdELOAD, &fr->adel);
+	err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
+	err |= __put_user(cpc, &fr->epc);
 
-	if (mips_put_word(xcp, &dsemul_insns[1], forcetrap)) {
+	if (unlikely(err)) {
 		fpuemuprivate.stats.errors++;
-		return (SIGBUS);
+		return SIGBUS;
 	}
 
-	/* Set thread state to catch and handle the exception */
-	current->thread.dsemul_epc = (unsigned long) cpc;
-	current->thread.dsemul_aerpc = (unsigned long) &dsemul_insns[1];
-	xcp->cp0_epc = VA_TO_REG & dsemul_insns[0];
-	flush_cache_sigtramp((unsigned long) dsemul_insns);
+	regs->cp0_epc = VA_TO_REG & dsemul_insns[0];
+
+	flush_cache_sigtramp((unsigned long)&fr->adel);
 
 	return SIGILL;		/* force out of emulation loop */
 }
@@ -864,15 +868,15 @@
 
 #ifdef CP0_STATUS_FR_SUPPORT
 #define DPFROMREG(dp,x)	((dp).bits = \
-			ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)])
-#define DPTOREG(dp,x)	(ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)]\
-			= (dp).bits)
+	ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)])
+#define DPTOREG(dp,x)	(ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)] \
+	= (dp).bits)
 #else
 /* Beware: MIPS COP1 doubles are always little_word endian in registers */
 #define DPFROMREG(dp,x)	\
-  ((dp).bits = ((unsigned long long)ctx->regs[(x)+1] << 32) | ctx->regs[x])
+	((dp).bits = ((u64)ctx->regs[(x)+1] << 32) | ctx->regs[x])
 #define DPTOREG(dp,x) \
-  (ctx->regs[x] = (dp).bits, ctx->regs[(x)+1] = (dp).bits >> 32)
+	(ctx->regs[x] = (dp).bits, ctx->regs[(x)+1] = (dp).bits >> 32)
 #endif
 
 #if __mips >= 4 && __mips != 32
@@ -881,6 +885,22 @@
  * Additional MIPS4 instructions
  */
 
+#define DEF3OP(name, p, f1, f2, f3) \
+static ieee754##p fpemu_##p##_##name (ieee754##p r, ieee754##p s, \
+    ieee754##p t) \
+{ \
+    struct ieee754_csr ieee754_csr_save; \
+    s = f1 (s, t); \
+    ieee754_csr_save = ieee754_csr; \
+    s = f2 (s, r); \
+    ieee754_csr_save.cx |= ieee754_csr.cx; \
+    ieee754_csr_save.sx |= ieee754_csr.sx; \
+    s = f3 (s); \
+    ieee754_csr.cx |= ieee754_csr_save.cx; \
+    ieee754_csr.sx |= ieee754_csr_save.sx; \
+    return s; \
+}    
+
 static ieee754dp fpemu_dp_recip(ieee754dp d)
 {
 	return ieee754dp_div(ieee754dp_one(0), d);
@@ -901,47 +921,14 @@
 	return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
 }
 
-
-static ieee754dp fpemu_dp_madd(ieee754dp r, ieee754dp s, ieee754dp t)
-{
-	return ieee754dp_add(ieee754dp_mul(s, t), r);
-}
-
-static ieee754dp fpemu_dp_msub(ieee754dp r, ieee754dp s, ieee754dp t)
-{
-	return ieee754dp_sub(ieee754dp_mul(s, t), r);
-}
-
-static ieee754dp fpemu_dp_nmadd(ieee754dp r, ieee754dp s, ieee754dp t)
-{
-	return ieee754dp_neg(ieee754dp_add(ieee754dp_mul(s, t), r));
-}
-
-static ieee754dp fpemu_dp_nmsub(ieee754dp r, ieee754dp s, ieee754dp t)
-{
-	return ieee754dp_neg(ieee754dp_sub(ieee754dp_mul(s, t), r));
-}
-
-
-static ieee754sp fpemu_sp_madd(ieee754sp r, ieee754sp s, ieee754sp t)
-{
-	return ieee754sp_add(ieee754sp_mul(s, t), r);
-}
-
-static ieee754sp fpemu_sp_msub(ieee754sp r, ieee754sp s, ieee754sp t)
-{
-	return ieee754sp_sub(ieee754sp_mul(s, t), r);
-}
-
-static ieee754sp fpemu_sp_nmadd(ieee754sp r, ieee754sp s, ieee754sp t)
-{
-	return ieee754sp_neg(ieee754sp_add(ieee754sp_mul(s, t), r));
-}
-
-static ieee754sp fpemu_sp_nmsub(ieee754sp r, ieee754sp s, ieee754sp t)
-{
-	return ieee754sp_neg(ieee754sp_sub(ieee754sp_mul(s, t), r));
-}
+DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
+DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
+DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
+DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
+DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
+DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
+DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
+DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
 
 static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
                     mips_instruction ir)
@@ -960,25 +947,18 @@
 			switch (MIPSInst_FUNC(ir)) {
 			case lwxc1_op:
 				{
-					void *va =
-					    REG_TO_VA(xcp->
-						      regs[MIPSInst_FR(ir)]
-						      +
-						      xcp->
-						      regs[MIPSInst_FT
-							   (ir)]);
+					u32 *va = REG_TO_VA(
+						xcp->regs[MIPSInst_FR(ir)] +
+						xcp->regs[MIPSInst_FT(ir)]);
 					fpureg_t val;
-					int err = 0;
-					val = mips_get_word(xcp, va, &err);
-					if (err) {
-						fpuemuprivate.stats.
-						    errors++;
+
+					if (get_user(val, va)) {
+						fpuemuprivate.stats.errors++;
 						return SIGBUS;
 					}
 					if (xcp->cp0_status & ST0_FR) {
 						/* load whole register */
-						ctx->
-						    regs[MIPSInst_FD(ir)] =
+						ctx->regs[MIPSInst_FD(ir)] =
 						    val;
 					} else if (MIPSInst_FD(ir) & 1) {
 						/* load to m.s. 32 bits */
@@ -1011,30 +991,21 @@
 
 			case swxc1_op:
 				{
-					void *va =
-					    REG_TO_VA(xcp->
-						      regs[MIPSInst_FR(ir)]
-						      +
-						      xcp->
-						      regs[MIPSInst_FT
-							   (ir)]);
+					u32 *va = REG_TO_VA(
+						xcp->regs[MIPSInst_FR(ir)] +
+						xcp->regs[MIPSInst_FT(ir)]);
 					unsigned int val;
+
 					if (xcp->cp0_status & ST0_FR) {
 						/* store whole register */
-						val =
-						    ctx->
-						    regs[MIPSInst_FS(ir)];
+						val = ctx->regs[MIPSInst_FS(ir)];
 					} else if (MIPSInst_FS(ir) & 1) {
 #if defined(SINGLE_ONLY_FPU)
 						/* illegal register in single-float mode */
 						return SIGILL;
 #else
 						/* store from m.s. 32 bits */
-						val =
-						    ctx->
-						    regs[
-							 (MIPSInst_FS(ir) &
-							  ~1)] >> 32;
+						val = ctx->regs[(MIPSInst_FS(ir) & ~1)] >> 32;
 #endif
 					} else {
 						/* store from l.s. 32 bits */
@@ -1042,9 +1013,8 @@
 						    ctx->
 						    regs[MIPSInst_FS(ir)];
 					}
-					if (mips_put_word(xcp, va, val)) {
-						fpuemuprivate.stats.
-						    errors++;
+					if (put_user(val, va)) {
+						fpuemuprivate.stats.errors++;
 						return SIGBUS;
 					}
 				}
@@ -1086,6 +1056,8 @@
 
 				ctx->sr =
 				    (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
+				if (ieee754_csr.nod)
+				    ctx->sr |= 0x1000000;
 				if ((ctx->sr >> 5) & ctx->
 				    sr & FPU_CSR_ALL_E) {
 		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */
@@ -1110,38 +1082,29 @@
 			switch (MIPSInst_FUNC(ir)) {
 			case ldxc1_op:
 				{
-					void *va =
-					    REG_TO_VA(xcp->
-						      regs[MIPSInst_FR(ir)]
-						      +
-						      xcp->
-						      regs[MIPSInst_FT
-							   (ir)]);
-					int err = 0;
-					ctx->regs[MIPSInst_FD(ir)] =
-					    mips_get_dword(xcp, va, &err);
-					if (err) {
-						fpuemuprivate.stats.
-						    errors++;
+					u64 *va = REG_TO_VA(
+						xcp->regs[MIPSInst_FR(ir)] +
+						xcp->regs[MIPSInst_FT(ir)]);
+					u64 val;
+
+					if (get_user(val, va)) {
+						fpuemuprivate.stats.errors++;
 						return SIGBUS;
 					}
+					ctx->regs[MIPSInst_FD(ir)] = val;
 				}
 				break;
 
 			case sdxc1_op:
 				{
-					void *va =
-					    REG_TO_VA(xcp->
-						      regs[MIPSInst_FR(ir)]
-						      +
-						      xcp->
-						      regs[MIPSInst_FT
-							   (ir)]);
-					if (mips_put_dword
-					    (xcp, va,
-					     ctx->regs[MIPSInst_FS(ir)])) {
-						fpuemuprivate.stats.
-						    errors++;
+					u64 *va = REG_TO_VA(
+						xcp->regs[MIPSInst_FR(ir)] +
+						xcp->regs[MIPSInst_FT(ir)]);
+					u64 val;
+
+					val = ctx->regs[MIPSInst_FS(ir)];
+					if (put_user(val, va)) {
+						fpuemuprivate.stats.errors++;
 						return SIGBUS;
 					}
 				}
@@ -1150,12 +1113,15 @@
 			case madd_d_op:
 				handler = fpemu_dp_madd;
 				goto dcoptop;
+
 			case msub_d_op:
 				handler = fpemu_dp_msub;
 				goto dcoptop;
+
 			case nmadd_d_op:
 				handler = fpemu_dp_nmadd;
 				goto dcoptop;
+
 			case nmsub_d_op:
 				handler = fpemu_dp_nmsub;
 				goto dcoptop;
@@ -1274,7 +1240,8 @@
 		case fmov_op:
 			/* an easy one */
 			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
+			goto copcsr;
+
 			/* binary op on handler */
 scopbop:
 			{
@@ -1386,13 +1353,16 @@
 				rfmt = -1;
 				if ((cmpop & 0x8) && ieee754_cxtest(IEEE754_INVALID_OPERATION))
 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
-				} else {
-					return SIGILL;
-				}
-				break;
+				else
+					goto copcsr;
+
+			} else {
+				return SIGILL;
 			}
 			break;
 		}
+		break;
+	}
 
 #if !defined(SINGLE_ONLY_FPU)
 	case d_fmt: {
@@ -1456,7 +1426,7 @@
 		case fmov_op:
 			/* an easy one */
 			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
+			goto copcsr;
 
 			/* binary op on handler */
 dcopbop:
@@ -1553,6 +1523,9 @@
 				rfmt = -1;
 				if ((cmpop & 0x8) && ieee754_cxtest (IEEE754_INVALID_OPERATION))
 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
+				else
+					goto copcsr;
+
 			} else {
 				return SIGILL;
 			}
@@ -1668,29 +1641,42 @@
 {
 	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
 	unsigned long oldepc, prevepc;
-	unsigned int insn;
+	mips_instruction insn, *insnp;
 	int sig = 0;
-	int err = 0;
 
 	oldepc = xcp->cp0_epc;
 	do {
-		if (current->need_resched)
-			schedule();
-
 		prevepc = xcp->cp0_epc;
-		insn = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc), &err);
-		if (err) {
+
+		/*
+		 * This is a braindead way to do it but the only sane way I
+		 * found to keep the 64-bit egcs 1.1.2 from crashing.
+		 */
+		insnp = (mips_instruction *) xcp->cp0_epc;
+		if (verify_area(VERIFY_READ, insnp, 4) ||
+		    __get_user(insn, insnp)) {
 			fpuemuprivate.stats.errors++;
 			return SIGBUS;
 		}
-		if (insn != 0)
-			sig = cop1Emulate(xcp, ctx);
-		else
+		if (insn == 0)
 			xcp->cp0_epc += 4;	/* skip nops */
+		else {
+			/* Update ieee754_csr. Only relevant if we have a
+			   h/w FPU */
+			ieee754_csr.nod = (ctx->sr & 0x1000000) != 0;
+			ieee754_csr.rm = ieee_rm[ctx->sr & 0x3];
+			ieee754_csr.cx = (ctx->sr >> 12) & 0x1f;
+			sig = cop1Emulate(xcp, ctx);
+		}
 
 		if (mips_cpu.options & MIPS_CPU_FPU)
 			break;
-	} while (xcp->cp0_epc > prevepc && sig == 0);
+		if (sig)
+			break;
+
+		if (current->need_resched)
+			schedule();
+	} while (xcp->cp0_epc > prevepc);
 
 	/* SIGILL indicates a non-fpu instruction */
 	if (sig == SIGILL && xcp->cp0_epc != oldepc)
@@ -1699,80 +1685,3 @@
 
 	return sig;
 }
-
-
-#ifdef NOTDEF
-/*
- * Patch up the hardware fpu state when an f.p. exception occurs.  
- */
-static int cop1Patcher(int xcptno, struct pt_regs *xcp)
-{
-	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
-	unsigned sr;
-	int sig;
-
-	/* reenable Cp1, else fpe_save() will get nested exception */
-	sr = mips_bissr(ST0_CU1);
-
-	/* get fpu registers and status, then clear pending exceptions */
-	fpe_save(ctx);
-	fpe_setsr(ctx->sr &= ~FPU_CSR_ALL_X);
-
-	/* get current rounding mode for IEEE library, and emulate insn */
-	ieee754_csr.rm = ieee_rm[ctx->sr & 0x3];
-	sig = cop1Emulate(xcp, ctx);
-
-	/* don't return with f.p. exceptions pending */
-	ctx->sr &= ~FPU_CSR_ALL_X;
-	fpe_restore(ctx);
-
-	mips_setsr(sr);
-	return sig;
-}
-
-void _cop1_init(int emulate)
-{
-	extern int _nofpu;
-
-	if (emulate) {
-		/* 
-		 * Install cop1 emulator to handle "coprocessor unusable" exception
-		 */
-		xcption(XCPTCPU, cop1Handler);
-		fpuemuactive = 1;	/* tell dbg.c that we are in charge */
-		_nofpu = 0;	/* tell setjmp() it "has" an fpu */
-	} else {
-		/* 
-		 * Install cop1 emulator for floating point exceptions only,
-		 * i.e. denormalised results, underflow, overflow etc, which
-		 * must be emulated in s/w.
-		 */
-#ifdef 1
-		/* r4000 or above use dedicate exception */
-		xcption(XCPTFPE, cop1Patcher);
-#else
-		/* r3000 et al use interrupt */
-		extern int _sbd_getfpuintr(void);
-		int intno = _sbd_getfpuintr();
-		intrupt(intno, cop1Patcher, 0);
-		mips_bissr(SR_IM0 << intno);
-#endif
-
-#if (#cpu(r4640) || #cpu(r4650)) && !defined(SINGLE_ONLY_FPU)
-		/* For R4640/R4650 compiled *without* the -msingle-float flag,
-		   then we share responsibility: the h/w handles the single
-		   precision operations, and the trap emulator handles the
-		   double precision. We set fpuemuactive so that dbg.c first
-		   fetches the s/w state before saving the h/w state. */
-		fpuemuactive = 1;
-		{
-			int i;
-			/* initialise the unused d.p high order words to be NaN */
-			for (i = 0; i < 32; i++)
-				current->thread.fpu.soft.regs[i] =
-				    0x7ff80bad00000000LL;
-		}
-#endif				/* (r4640 || r4650) && !fpu(single) */
-	}
-}
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_add.c linux/arch/mips/math-emu/dp_add.c
--- linux.orig/arch/mips/math-emu/dp_add.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_add.c	2002-07-20 01:08:30.000000000 +0000
@@ -38,27 +38,23 @@
 
 	CLEARCX;
 
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "add", x,
-					 y);
+	FLUSHXDP;
+	FLUSHYDP;
 
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y, "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x, "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754dp_bestnan(x, y);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "add", x, y);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -66,6 +62,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return y;
 
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_cmp.c linux/arch/mips/math-emu/dp_cmp.c
--- linux.orig/arch/mips/math-emu/dp_cmp.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_cmp.c	2002-07-20 01:08:30.000000000 +0000
@@ -29,9 +29,18 @@
 
 int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp)
 {
-	CLEARCX;
+	COMPXDP;
+	COMPYDP;
+
+	EXPLODEXDP;
+	EXPLODEYDP;
+	FLUSHXDP;
+	FLUSHYDP;
+	CLEARCX;	/* Even clear inexact flag here */
 
 	if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
+		if (xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+			SETCX(IEEE754_INVALID_OPERATION);
 		if (cmp & IEEE754_CUN)
 			return 1;
 		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_div.c linux/arch/mips/math-emu/dp_div.c
--- linux.orig/arch/mips/math-emu/dp_div.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_div.c	2002-07-20 01:08:24.000000000 +0000
@@ -32,32 +32,28 @@
 	COMPXDP;
 	COMPYDP;
 
-	CLEARCX;
-
 	EXPLODEXDP;
 	EXPLODEYDP;
 
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "div", x,
-					 y);
+	CLEARCX;
+
+	FLUSHXDP;
+	FLUSHYDP;
 
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y, "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x, "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754dp_bestnan(x, y);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "div", x, y);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -65,6 +61,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return y;
 
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_fsp.c linux/arch/mips/math-emu/dp_fsp.c
--- linux.orig/arch/mips/math-emu/dp_fsp.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_fsp.c	2002-07-20 01:08:26.000000000 +0000
@@ -31,13 +31,17 @@
 {
 	COMPXSP;
 
+	EXPLODEXSP;
+
 	CLEARCX;
 
-	EXPLODEXSP;
+	FLUSHXSP;
 
 	switch (xc) {
-	case IEEE754_CLASS_QNAN:
 	case IEEE754_CLASS_SNAN:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "fsp");
+	case IEEE754_CLASS_QNAN:
 		return ieee754dp_nanxcpt(builddp(xs,
 						 DP_EMAX + 1 + DP_EBIAS,
 						 ((unsigned long long) xm
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_mul.c linux/arch/mips/math-emu/dp_mul.c
--- linux.orig/arch/mips/math-emu/dp_mul.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_mul.c	2002-07-20 01:08:34.000000000 +0000
@@ -32,32 +32,28 @@
 	COMPXDP;
 	COMPYDP;
 
-	CLEARCX;
-
 	EXPLODEXDP;
 	EXPLODEYDP;
 
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "mul", x,
-					 y);
+	CLEARCX;
+
+	FLUSHXDP;
+	FLUSHYDP;
 
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y, "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x, "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754dp_bestnan(x, y);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "mul", x, y);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -65,6 +61,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return y;
 
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_simple.c linux/arch/mips/math-emu/dp_simple.c
--- linux.orig/arch/mips/math-emu/dp_simple.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_simple.c	2002-07-20 01:08:29.000000000 +0000
@@ -42,7 +42,16 @@
 
 ieee754dp ieee754dp_neg(ieee754dp x)
 {
+	COMPXDP;
+
+	EXPLODEXDP;
 	CLEARCX;
+	FLUSHXDP;
+
+	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
+	}
 
 	if (ieee754dp_isnan(x))	/* but not infinity */
 		return ieee754dp_nanxcpt(x, "neg", x);
@@ -55,7 +64,16 @@
 
 ieee754dp ieee754dp_abs(ieee754dp x)
 {
+	COMPXDP;
+
+	EXPLODEXDP;
 	CLEARCX;
+	FLUSHXDP;
+
+	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
+	}
 
 	if (ieee754dp_isnan(x))	/* but not infinity */
 		return ieee754dp_nanxcpt(x, "abs", x);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_sqrt.c linux/arch/mips/math-emu/dp_sqrt.c
--- linux.orig/arch/mips/math-emu/dp_sqrt.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_sqrt.c	2002-07-20 01:08:31.000000000 +0000
@@ -27,16 +27,6 @@
 
 #include "ieee754dp.h"
 
-static const struct ieee754dp_konst knan = {
-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
-	0, 0, DP_EBIAS + DP_EMAX + 1, 0
-#else
-	0, DP_EBIAS + DP_EMAX + 1, 0, 0
-#endif
-};
-
-#define nan	((ieee754dp)knan)
-
 static const unsigned table[] = {
 	0, 1204, 3062, 5746, 9193, 13348, 18162, 23592,
 	29598, 36145, 43202, 50740, 58733, 67158, 75992,
@@ -53,29 +43,37 @@
 	COMPXDP;
 
 	EXPLODEXDP;
+	CLEARCX;
+	FLUSHXDP;
 
 	/* x == INF or NAN? */
 	switch (xc) {
 	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
 		/* sqrt(Nan) = Nan */
 		return ieee754dp_nanxcpt(x, "sqrt");
+	case IEEE754_CLASS_SNAN:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
 	case IEEE754_CLASS_ZERO:
 		/* sqrt(0) = 0 */
 		return x;
 	case IEEE754_CLASS_INF:
-		if (xs)
+		if (xs) {
 			/* sqrt(-Inf) = Nan */
-			return ieee754dp_nanxcpt(nan, "sqrt");
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
+		}
 		/* sqrt(+Inf) = Inf */
 		return x;
 	case IEEE754_CLASS_DNORM:
 		DPDNORMX;
 		/* fall through */
 	case IEEE754_CLASS_NORM:
-		if (xs)
+		if (xs) {
 			/* sqrt(-x) = Nan */
-			return ieee754dp_nanxcpt(nan, "sqrt");
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
+		}
 		break;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_sub.c linux/arch/mips/math-emu/dp_sub.c
--- linux.orig/arch/mips/math-emu/dp_sub.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/math-emu/dp_sub.c	2002-07-20 01:08:27.000000000 +0000
@@ -32,32 +32,28 @@
 	COMPXDP;
 	COMPYDP;
 
-	CLEARCX;
-
 	EXPLODEXDP;
 	EXPLODEYDP;
 
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "sub", x,
-					 y);
+	CLEARCX;
+
+	FLUSHXDP;
+	FLUSHYDP;
 
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y, "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x, "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754dp_bestnan(x, y);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "sub", x, y);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -65,6 +61,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return y;
 
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_tint.c linux/arch/mips/math-emu/dp_tint.c
--- linux.orig/arch/mips/math-emu/dp_tint.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_tint.c	2002-07-20 01:08:24.000000000 +0000
@@ -35,38 +35,76 @@
 	CLEARCX;
 
 	EXPLODEXDP;
+	FLUSHXDP;
 
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_QNAN:
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754si_xcpt(ieee754si_indef(), "fixdp", x);
 	case IEEE754_CLASS_INF:
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754si_xcpt(ieee754si_indef(), "fixdp", x);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
 	case IEEE754_CLASS_ZERO:
 		return 0;
-	case IEEE754_CLASS_DNORM:	/* much to small */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754si_xcpt(0, "fixdp", x);
+	case IEEE754_CLASS_DNORM:
 	case IEEE754_CLASS_NORM:
 		break;
 	}
 	if (xe >= 31) {
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754si_xcpt(ieee754si_indef(), "fix", x);
-	}
-	if (xe < 0) {
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754si_xcpt(0, "fix", x);
+		/* look for valid corner case */
+		if (xe == 31 && xs && xm == DP_HIDDEN_BIT)
+			return -2147483648;
+		/* Set invalid. We will only use overflow for floating
+		   point overflow */
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
 	}
 	/* oh gawd */
 	if (xe > DP_MBITS) {
 		xm <<= xe - DP_MBITS;
 	} else if (xe < DP_MBITS) {
-		/* XXX no rounding 
-		 */
-		xm >>= DP_MBITS - xe;
+		unsigned long long residue;
+		int round;
+		int sticky;
+		int odd;
+
+		if (xe < -1) {
+			residue = xm;
+			round = 0;
+			sticky = residue != 0;
+			xm = 0;
+		}
+		else {
+			residue = xm << (64 - DP_MBITS + xe);
+			round = (residue >> 63) != 0;
+			sticky = (residue << 1) != 0;
+			xm >>= DP_MBITS - xe;
+		}
+		/* Note: At this point upper 32 bits of xm are guaranteed
+		   to be zero */
+		odd = (xm & 0x1) != 0x0;
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			if (round && (sticky || odd))
+				xm++;
+			break;
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if ((round || sticky) && !xs)
+				xm++;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if ((round || sticky) && xs)
+				xm++;
+			break;
+		}
+		if ((xm >> 31) != 0) {
+			/* This can happen after rounding */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
+		}
+		if (round || sticky)
+			SETCX(IEEE754_INEXACT);
 	}
 	if (xs)
 		return -xm;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/dp_tlong.c linux/arch/mips/math-emu/dp_tlong.c
--- linux.orig/arch/mips/math-emu/dp_tlong.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/dp_tlong.c	2002-07-20 01:08:34.000000000 +0000
@@ -34,92 +34,74 @@
 	CLEARCX;
 
 	EXPLODEXDP;
+	FLUSHXDP;
 
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_QNAN:
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
 	case IEEE754_CLASS_INF:
-		SETCX(IEEE754_OVERFLOW);
+		SETCX(IEEE754_INVALID_OPERATION);
 		return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
 	case IEEE754_CLASS_ZERO:
 		return 0;
-	case IEEE754_CLASS_DNORM:	/* much too small */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754di_xcpt(0, "dp_tlong", x);
+	case IEEE754_CLASS_DNORM:
 	case IEEE754_CLASS_NORM:
 		break;
 	}
 	if (xe >= 63) {
-		SETCX(IEEE754_OVERFLOW);
+		/* look for valid corner case */ 
+		if (xe == 63 && xs && xm == DP_HIDDEN_BIT)
+			return -9223372036854775808LL;
+		/* Set invalid. We will only use overflow for floating
+		   point overflow */
+		SETCX(IEEE754_INVALID_OPERATION);
 		return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
 	}
-	if (xe < 0) {
-		if (ieee754_csr.rm == IEEE754_RU) {
-			if (xs) {	/* Negative  */
-				return 0x0000000000000000LL;
-			} else {	/* Positive */
-				return 0x0000000000000001LL;
-			}
-		} else if (ieee754_csr.rm == IEEE754_RD) {
-			if (xs) {	/* Negative , return -1 */
-				return 0xffffffffffffffffLL;
-			} else {	/* Positive */
-				return 0x0000000000000000LL;
-			}
-		} else {
-			SETCX(IEEE754_UNDERFLOW);
-			return ieee754di_xcpt(0, "dp_tlong", x);
-		}
-	}
 	/* oh gawd */
 	if (xe > DP_MBITS) {
 		xm <<= xe - DP_MBITS;
 	} else if (xe < DP_MBITS) {
 		unsigned long long residue;
-		unsigned long long mask = 0;
-		int i;
 		int round;
 		int sticky;
 		int odd;
 
-		/* compute mask */
-		for (i = 0; i < DP_MBITS - xe; i++) {
-			mask = mask << 1;
-			mask = mask | 0x1;
+		if (xe < -1) {
+			residue = xm;
+			round = 0;
+			sticky = residue != 0;
+			xm = 0;
 		}
-		residue = (xm & mask) << (64 - (DP_MBITS - xe));
-		round =
-		    ((0x8000000000000000LL & residue) !=
-		     0x0000000000000000LL);
-		sticky =
-		    ((0x7fffffffffffffffLL & residue) !=
-		     0x0000000000000000LL);
-
-		xm >>= DP_MBITS - xe;
-
-		odd = ((xm & 0x1) != 0x0000000000000000LL);
-
-		/* Do the rounding */
-		if (!round && sticky) {
-			if ((ieee754_csr.rm == IEEE754_RU && !xs)
-			    || (ieee754_csr.rm == IEEE754_RD && xs)) {
+		else {
+			residue = xm << (64 - DP_MBITS + xe);
+			round = (residue >> 63) != 0;
+			sticky = (residue << 1) != 0;
+			xm >>= DP_MBITS - xe;
+		}
+		odd = (xm & 0x1) != 0x0;
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			if (round && (sticky || odd))
 				xm++;
-			}
-		} else if (round && !sticky) {
-			if ((ieee754_csr.rm == IEEE754_RU && !xs)
-			    || (ieee754_csr.rm == IEEE754_RD && xs)
-			    || (ieee754_csr.rm == IEEE754_RN && odd)) {
+			break;
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if ((round || sticky) && !xs)
 				xm++;
-			}
-		} else if (round && sticky) {
-			if ((ieee754_csr.rm == IEEE754_RU && !xs)
-			    || (ieee754_csr.rm == IEEE754_RD && xs)
-			    || (ieee754_csr.rm == IEEE754_RN)) {
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if ((round || sticky) && xs)
 				xm++;
-			}
+			break;
+		}
+		if ((xm >> 63) != 0) {
+			/* This can happen after rounding */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
 		}
+		if (round || sticky)
+			SETCX(IEEE754_INEXACT);
 	}
 	if (xs)
 		return -xm;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/ieee754.c linux/arch/mips/math-emu/ieee754.c
--- linux.orig/arch/mips/math-emu/ieee754.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/ieee754.c	2002-07-20 01:08:23.000000000 +0000
@@ -77,7 +77,7 @@
 	DPSTR(1, 3 + DP_EBIAS, 0x40000, 0),	/* - 10.0   */
 	DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0),	/* + infinity */
 	DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0),	/* - infinity */
-	DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0x40000, 0),	/* + indef quiet Nan */
+	DPSTR(0,DP_EMAX+1+DP_EBIAS,0x7FFFF,0xFFFFFFFF), /* + indef quiet Nan */
 	DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* + max */
 	DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* - max */
 	DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0),	/* + min normal */
@@ -97,7 +97,7 @@
 	SPSTR(1, 3 + SP_EBIAS, 0x200000),	/* - 10.0   */
 	SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0),	/* + infinity */
 	SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0),	/* - infinity */
-	SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0x200000),	/* + indef quiet Nan  */
+	SPSTR(0,SP_EMAX+1+SP_EBIAS,0x3FFFFF),     /* + indef quiet Nan  */
 	SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* + max normal */
 	SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* - max normal */
 	SPSTR(0, SP_EMIN + SP_EBIAS, 0),	/* + min normal */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/ieee754.h linux/arch/mips/math-emu/ieee754.h
--- linux.orig/arch/mips/math-emu/ieee754.h	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/ieee754.h	2002-07-20 01:08:26.000000000 +0000
@@ -325,7 +325,6 @@
 */
 struct ieee754_csr {
 	unsigned pad:13;
-	unsigned noq:1;		/* set 1 for no quiet NaN's */
 	unsigned nod:1;		/* set 1 for no denormalised numbers */
 	unsigned cx:5;		/* exceptions this operation */
 	unsigned mx:5;		/* exception enable  mask */
@@ -453,11 +452,11 @@
 
 /* indefinite integer value 
 */
-#define ieee754si_indef()	INT_MIN
-#ifdef LONG_LONG_MIN
-#define ieee754di_indef()	LONG_LONG_MIN
+#define ieee754si_indef()	INT_MAX
+#ifdef LONG_LONG_MAX
+#define ieee754di_indef()	LONG_LONG_MAX
 #else
-#define ieee754di_indef()	(-9223372036854775807LL-1)
+#define ieee754di_indef()	((long long)(~0ULL>>1))
 #endif
 
 /* IEEE exception context, passed to handler */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/ieee754d.c linux/arch/mips/math-emu/ieee754d.c
--- linux.orig/arch/mips/math-emu/ieee754d.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/ieee754d.c	2002-07-20 01:08:32.000000000 +0000
@@ -1,12 +1,11 @@
-/* some debug functions
-*/
 /*
+ * Some debug functions
+ *
  * MIPS floating point support
+ *
  * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
  * http://www.algor.co.uk
  *
- * ########################################################################
- *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
  *  published by the Free Software Foundation.
@@ -20,17 +19,14 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
- * ########################################################################
- */
-
-/**************************************************************************
  *  Nov 7, 2000
  *  Modified to build and operate in Linux kernel environment. 
  *
  *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *************************************************************************/
+ */
 
+#include <linux/kernel.h>
 #include "ieee754.h"
 
 #define DP_EBIAS	1023
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/ieee754dp.c linux/arch/mips/math-emu/ieee754dp.c
--- linux.orig/arch/mips/math-emu/ieee754dp.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/ieee754dp.c	2002-07-20 01:08:26.000000000 +0000
@@ -42,9 +42,7 @@
 int ieee754dp_issnan(ieee754dp x)
 {
 	assert(ieee754dp_isnan(x));
-	if (ieee754_csr.noq)
-		return 1;
-	return !(DPMANT(x) & DP_MBIT(DP_MBITS - 1));
+	return ((DPMANT(x) & DP_MBIT(DP_MBITS-1)) == DP_MBIT(DP_MBITS-1));
 }
 
 
@@ -73,10 +71,11 @@
 
 	if (!SETCX(IEEE754_INVALID_OPERATION)) {
 		/* not enabled convert to a quiet NaN */
-		if (ieee754_csr.noq)
+		DPMANT(r) &= (~DP_MBIT(DP_MBITS-1));
+		if (ieee754dp_isnan(r))
 			return r;
-		DPMANT(r) |= DP_MBIT(DP_MBITS - 1);
-		return r;
+		else
+			return ieee754dp_indef();
 	}
 
 	ax.op = op;
@@ -99,6 +98,32 @@
 }
 
 
+static unsigned long long get_rounding(int sn, unsigned long long xm)
+{
+	/* inexact must round of 3 bits 
+	 */
+	if (xm & (DP_MBIT(3) - 1)) {
+		switch (ieee754_csr.rm) {
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RN:
+			xm += 0x3 + ((xm >> 3) & 1);
+			/* xm += (xm&0x8)?0x4:0x3 */
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if (!sn)	/* ?? */
+				xm += 0x8;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if (sn)	/* ?? */
+				xm += 0x8;
+			break;
+		}
+	}
+	return xm;
+}
+
+
 /* generate a normal/denormal number with over,under handeling
  * sn is sign
  * xe is an unbiased exponent
@@ -117,40 +142,59 @@
 
 		if (ieee754_csr.nod) {
 			SETCX(IEEE754_UNDERFLOW);
-			return ieee754dp_zero(sn);
-		}
+			SETCX(IEEE754_INEXACT);
 
-		/* sticky right shift es bits 
-		 */
-		xm = XDPSRS(xm, es);
-		xe += es;
+			switch(ieee754_csr.rm) {
+			case IEEE754_RN:
+				return ieee754dp_zero(sn);
+			case IEEE754_RZ:
+				return ieee754dp_zero(sn);
+			case IEEE754_RU:    /* toward +Infinity */
+				if(sn == 0)
+					return ieee754dp_min(0);
+				else
+					return ieee754dp_zero(1);
+			case IEEE754_RD:    /* toward -Infinity */
+				if(sn == 0)
+					return ieee754dp_zero(0);
+				else
+					return ieee754dp_min(1);
+			}
+		}
 
-		assert((xm & (DP_HIDDEN_BIT << 3)) == 0);
-		assert(xe == DP_EMIN);
+		if (xe == DP_EMIN - 1
+				&& get_rounding(sn, xm) >> (DP_MBITS + 1 + 3))
+		{
+			/* Not tiny after rounding */
+			SETCX(IEEE754_INEXACT);
+			xm = get_rounding(sn, xm);
+			xm >>= 1;
+			/* Clear grs bits */
+			xm &= ~(DP_MBIT(3) - 1);
+			xe++;
+		}
+		else {
+			/* sticky right shift es bits 
+			 */
+			xm = XDPSRS(xm, es);
+			xe += es;
+			assert((xm & (DP_HIDDEN_BIT << 3)) == 0);
+			assert(xe == DP_EMIN);
+		}
 	}
 	if (xm & (DP_MBIT(3) - 1)) {
 		SETCX(IEEE754_INEXACT);
+		if ((xm & (DP_HIDDEN_BIT << 3)) == 0) {
+			SETCX(IEEE754_UNDERFLOW);
+		}
+
 		/* inexact must round of 3 bits 
 		 */
-		switch (ieee754_csr.rm) {
-		case IEEE754_RZ:
-			break;
-		case IEEE754_RN:
-			xm += 0x3 + ((xm >> 3) & 1);
-			/* xm += (xm&0x8)?0x4:0x3 */
-			break;
-		case IEEE754_RU:	/* toward +Infinity */
-			if (!sn)	/* ?? */
-				xm += 0x8;
-			break;
-		case IEEE754_RD:	/* toward -Infinity */
-			if (sn)	/* ?? */
-				xm += 0x8;
-			break;
-		}
+		xm = get_rounding(sn, xm);
 		/* adjust exponent for rounding add overflowing 
 		 */
-		if (xm >> (DP_MBITS + 3 + 1)) {	/* add causes mantissa overflow */
+		if (xm >> (DP_MBITS + 3 + 1)) {
+			/* add causes mantissa overflow */
 			xm >>= 1;
 			xe++;
 		}
@@ -163,6 +207,7 @@
 
 	if (xe > DP_EMAX) {
 		SETCX(IEEE754_OVERFLOW);
+		SETCX(IEEE754_INEXACT);
 		/* -O can be table indexed by (rm,sn) */
 		switch (ieee754_csr.rm) {
 		case IEEE754_RN:
@@ -186,7 +231,8 @@
 	if ((xm & DP_HIDDEN_BIT) == 0) {
 		/* we underflow (tiny/zero) */
 		assert(xe == DP_EMIN);
-		SETCX(IEEE754_UNDERFLOW);
+		if (ieee754_csr.mx & IEEE754_UNDERFLOW)
+			SETCX(IEEE754_UNDERFLOW);
 		return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm);
 	} else {
 		assert((xm >> (DP_MBITS + 1)) == 0);	/* no execess */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/ieee754int.h linux/arch/mips/math-emu/ieee754int.h
--- linux.orig/arch/mips/math-emu/ieee754int.h	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/ieee754int.h	2002-07-20 01:08:38.000000000 +0000
@@ -82,9 +82,9 @@
 	if(vm == 0)\
 	  vc = IEEE754_CLASS_INF;\
 	else if(vm & SP_MBIT(SP_MBITS-1)) \
-	  vc = IEEE754_CLASS_QNAN;\
-	else \
 	  vc = IEEE754_CLASS_SNAN;\
+	else \
+	  vc = IEEE754_CLASS_QNAN;\
     } else if(ve == SP_EMIN-1+SP_EBIAS) {\
 	if(vm) {\
 	    ve = SP_EMIN;\
@@ -116,9 +116,9 @@
 	if(vm == 0)\
 	  vc = IEEE754_CLASS_INF;\
 	else if(vm & DP_MBIT(DP_MBITS-1)) \
-	  vc = IEEE754_CLASS_QNAN;\
-	else \
 	  vc = IEEE754_CLASS_SNAN;\
+	else \
+	  vc = IEEE754_CLASS_QNAN;\
     } else if(ve == DP_EMIN-1+DP_EBIAS) {\
 	if(vm) {\
 	    ve = DP_EMIN;\
@@ -133,3 +133,30 @@
 }
 #define EXPLODEXDP EXPLODEDP(x,xc,xs,xe,xm)
 #define EXPLODEYDP EXPLODEDP(y,yc,ys,ye,ym)
+
+#define FLUSHDP(v,vc,vs,ve,vm) \
+	if(vc==IEEE754_CLASS_DNORM) {\
+	    if(ieee754_csr.nod) {\
+		SETCX(IEEE754_INEXACT);\
+		vc = IEEE754_CLASS_ZERO;\
+		ve = DP_EMIN-1+DP_EBIAS;\
+		vm = 0;\
+		v = ieee754dp_zero(vs);\
+	    }\
+	}
+
+#define FLUSHSP(v,vc,vs,ve,vm) \
+	if(vc==IEEE754_CLASS_DNORM) {\
+	    if(ieee754_csr.nod) {\
+		SETCX(IEEE754_INEXACT);\
+		vc = IEEE754_CLASS_ZERO;\
+		ve = SP_EMIN-1+SP_EBIAS;\
+		vm = 0;\
+		v = ieee754sp_zero(vs);\
+	    }\
+	}
+
+#define FLUSHXDP FLUSHDP(x,xc,xs,xe,xm)
+#define FLUSHYDP FLUSHDP(y,yc,ys,ye,ym)
+#define FLUSHXSP FLUSHSP(x,xc,xs,xe,xm)
+#define FLUSHYSP FLUSHSP(y,yc,ys,ye,ym)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/ieee754sp.c linux/arch/mips/math-emu/ieee754sp.c
--- linux.orig/arch/mips/math-emu/ieee754sp.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/ieee754sp.c	2002-07-20 01:08:32.000000000 +0000
@@ -42,9 +42,7 @@
 int ieee754sp_issnan(ieee754sp x)
 {
 	assert(ieee754sp_isnan(x));
-	if (ieee754_csr.noq)
-		return 1;
-	return !(SPMANT(x) & SP_MBIT(SP_MBITS - 1));
+	return (SPMANT(x) & SP_MBIT(SP_MBITS-1));
 }
 
 
@@ -74,10 +72,11 @@
 
 	if (!SETCX(IEEE754_INVALID_OPERATION)) {
 		/* not enabled convert to a quiet NaN */
-		if (ieee754_csr.noq)
+		SPMANT(r) &= (~SP_MBIT(SP_MBITS-1));
+		if (ieee754sp_isnan(r))
 			return r;
-		SPMANT(r) |= SP_MBIT(SP_MBITS - 1);
-		return r;
+		else
+			return ieee754sp_indef();
 	}
 
 	ax.op = op;
@@ -100,6 +99,32 @@
 }
 
 
+static unsigned get_rounding(int sn, unsigned xm)
+{
+	/* inexact must round of 3 bits 
+	 */
+	if (xm & (SP_MBIT(3) - 1)) {
+		switch (ieee754_csr.rm) {
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RN:
+			xm += 0x3 + ((xm >> 3) & 1);
+			/* xm += (xm&0x8)?0x4:0x3 */
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if (!sn)	/* ?? */
+				xm += 0x8;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if (sn)	/* ?? */
+				xm += 0x8;
+			break;
+		}
+	}
+	return xm;
+}
+
+
 /* generate a normal/denormal number with over,under handeling
  * sn is sign
  * xe is an unbiased exponent
@@ -118,39 +143,58 @@
 
 		if (ieee754_csr.nod) {
 			SETCX(IEEE754_UNDERFLOW);
-			return ieee754sp_zero(sn);
-		}
+			SETCX(IEEE754_INEXACT);
 
-		/* sticky right shift es bits 
-		 */
-		SPXSRSXn(es);
+			switch(ieee754_csr.rm) {
+			case IEEE754_RN:
+				return ieee754sp_zero(sn);
+			case IEEE754_RZ:
+				return ieee754sp_zero(sn);
+			case IEEE754_RU:      /* toward +Infinity */
+				if(sn == 0)
+					return ieee754sp_min(0);
+				else
+					return ieee754sp_zero(1);
+			case IEEE754_RD:      /* toward -Infinity */
+				if(sn == 0)
+					return ieee754sp_zero(0);
+				else
+					return ieee754sp_min(1);
+			}
+		}
 
-		assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
-		assert(xe == SP_EMIN);
+		if (xe == SP_EMIN - 1
+				&& get_rounding(sn, xm) >> (SP_MBITS + 1 + 3))
+		{
+			/* Not tiny after rounding */
+			SETCX(IEEE754_INEXACT);
+			xm = get_rounding(sn, xm);
+			xm >>= 1;
+			/* Clear grs bits */
+			xm &= ~(SP_MBIT(3) - 1);
+			xe++;
+		}
+		else {
+			/* sticky right shift es bits 
+			 */
+			SPXSRSXn(es);
+			assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
+			assert(xe == SP_EMIN);
+		}
 	}
 	if (xm & (SP_MBIT(3) - 1)) {
 		SETCX(IEEE754_INEXACT);
+		if ((xm & (SP_HIDDEN_BIT << 3)) == 0) {
+			SETCX(IEEE754_UNDERFLOW);
+		}
+
 		/* inexact must round of 3 bits 
 		 */
-		switch (ieee754_csr.rm) {
-		case IEEE754_RZ:
-			break;
-		case IEEE754_RN:
-			xm += 0x3 + ((xm >> 3) & 1);
-			/* xm += (xm&0x8)?0x4:0x3 */
-			break;
-		case IEEE754_RU:	/* toward +Infinity */
-			if (!sn)	/* ?? */
-				xm += 0x8;
-			break;
-		case IEEE754_RD:	/* toward -Infinity */
-			if (sn)	/* ?? */
-				xm += 0x8;
-			break;
-		}
+		xm = get_rounding(sn, xm);
 		/* adjust exponent for rounding add overflowing 
 		 */
-		if (xm >> (SP_MBITS + 1 + 3)) {	/* add causes mantissa overflow */
+		if (xm >> (SP_MBITS + 1 + 3)) {
+			/* add causes mantissa overflow */
 			xm >>= 1;
 			xe++;
 		}
@@ -163,6 +207,7 @@
 
 	if (xe > SP_EMAX) {
 		SETCX(IEEE754_OVERFLOW);
+		SETCX(IEEE754_INEXACT);
 		/* -O can be table indexed by (rm,sn) */
 		switch (ieee754_csr.rm) {
 		case IEEE754_RN:
@@ -186,7 +231,8 @@
 	if ((xm & SP_HIDDEN_BIT) == 0) {
 		/* we underflow (tiny/zero) */
 		assert(xe == SP_EMIN);
-		SETCX(IEEE754_UNDERFLOW);
+		if (ieee754_csr.mx & IEEE754_UNDERFLOW)
+			SETCX(IEEE754_UNDERFLOW);
 		return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm);
 	} else {
 		assert((xm >> (SP_MBITS + 1)) == 0);	/* no execess */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/kernel_linkage.c linux/arch/mips/math-emu/kernel_linkage.c
--- linux.orig/arch/mips/math-emu/kernel_linkage.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/kernel_linkage.c	2002-07-20 01:08:23.000000000 +0000
@@ -20,13 +20,10 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
- *************************************************************************/
-/*
  * Routines corresponding to Linux kernel FP context
  * manipulation primitives for the Algorithmics MIPS
  * FPU Emulator
  */
-
 #include <linux/sched.h>
 #include <asm/processor.h>
 #include <asm/signal.h>
@@ -45,7 +42,7 @@
  
 	if (first) {
 		first = 0;
-		printk("Algorithmics/MIPS FPU Emulator v1.4\n");
+		printk("Algorithmics/MIPS FPU Emulator v1.5\n");
 	}
 
 	current->thread.fpu.soft.sr = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_add.c linux/arch/mips/math-emu/sp_add.c
--- linux.orig/arch/mips/math-emu/sp_add.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_add.c	2002-07-20 01:08:29.000000000 +0000
@@ -37,27 +37,23 @@
 
 	CLEARCX;
 
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "add", x,
-					 y);
+	FLUSHXSP;
+	FLUSHYSP;
 
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y, "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x, "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754sp_bestnan(x, y);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "add", x, y);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -65,6 +61,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return y;
 
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_cmp.c linux/arch/mips/math-emu/sp_cmp.c
--- linux.orig/arch/mips/math-emu/sp_cmp.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_cmp.c	2002-07-20 01:08:21.000000000 +0000
@@ -29,9 +29,18 @@
 
 int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp)
 {
-	CLEARCX;
+	COMPXSP;
+	COMPYSP;
+
+	EXPLODEXSP;
+	EXPLODEYSP;
+	FLUSHXSP;
+	FLUSHYSP;
+	CLEARCX;	/* Even clear inexact flag here */
 
 	if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
+		if (xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+			SETCX(IEEE754_INVALID_OPERATION);
 		if (cmp & IEEE754_CUN)
 			return 1;
 		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_div.c linux/arch/mips/math-emu/sp_div.c
--- linux.orig/arch/mips/math-emu/sp_div.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_div.c	2002-07-20 01:08:29.000000000 +0000
@@ -32,32 +32,28 @@
 	COMPXSP;
 	COMPYSP;
 
-	CLEARCX;
-
 	EXPLODEXSP;
 	EXPLODEYSP;
 
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "div", x,
-					 y);
+	CLEARCX;
+
+	FLUSHXSP;
+	FLUSHYSP;
 
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y, "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x, "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754sp_bestnan(x, y);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "div", x, y);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -65,6 +61,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return y;
 
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_fdp.c linux/arch/mips/math-emu/sp_fdp.c
--- linux.orig/arch/mips/math-emu/sp_fdp.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_fdp.c	2002-07-20 01:08:36.000000000 +0000
@@ -30,20 +30,24 @@
 ieee754sp ieee754sp_fdp(ieee754dp x)
 {
 	COMPXDP;
+	ieee754sp nan;
+
+	EXPLODEXDP;
 
 	CLEARCX;
 
-	EXPLODEXDP;
+	FLUSHXDP;
 
 	switch (xc) {
-	case IEEE754_CLASS_QNAN:
 	case IEEE754_CLASS_SNAN:
-		return ieee754sp_nanxcpt(buildsp(xs,
-						 SP_EMAX + 1 + SP_EBIAS,
-						 (unsigned long)
-						 (xm >>
-						  (DP_MBITS - SP_MBITS))),
-					 "fdp", x);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp");
+	case IEEE754_CLASS_QNAN:
+		nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (unsigned long)
+				(xm >> (DP_MBITS - SP_MBITS)));
+		if (!ieee754sp_isnan(nan))
+			nan = ieee754sp_indef();
+		return ieee754sp_nanxcpt(nan, "fdp", x);
 	case IEEE754_CLASS_INF:
 		return ieee754sp_inf(xs);
 	case IEEE754_CLASS_ZERO:
@@ -51,6 +55,10 @@
 	case IEEE754_CLASS_DNORM:
 		/* cant possibly be sp representable */
 		SETCX(IEEE754_UNDERFLOW);
+		SETCX(IEEE754_INEXACT);
+		if ((ieee754_csr.rm == IEEE754_RU && !xs) ||
+		    (ieee754_csr.rm == IEEE754_RD && xs))
+			return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x);
 		return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
 	case IEEE754_CLASS_NORM:
 		break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_mul.c linux/arch/mips/math-emu/sp_mul.c
--- linux.orig/arch/mips/math-emu/sp_mul.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_mul.c	2002-07-20 01:08:38.000000000 +0000
@@ -32,32 +32,28 @@
 	COMPXSP;
 	COMPYSP;
 
-	CLEARCX;
-
 	EXPLODEXSP;
 	EXPLODEYSP;
 
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "mul", x,
-					 y);
+	CLEARCX;
+
+	FLUSHXSP;
+	FLUSHYSP;
 
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y, "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x, "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754sp_bestnan(x, y);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "mul", x, y);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -65,6 +61,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return y;
 
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_simple.c linux/arch/mips/math-emu/sp_simple.c
--- linux.orig/arch/mips/math-emu/sp_simple.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_simple.c	2002-07-20 01:08:22.000000000 +0000
@@ -42,7 +42,16 @@
 
 ieee754sp ieee754sp_neg(ieee754sp x)
 {
+	COMPXSP;
+
+	EXPLODEXSP;
 	CLEARCX;
+	FLUSHXSP;
+
+	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "neg");
+	}
 
 	if (ieee754sp_isnan(x))	/* but not infinity */
 		return ieee754sp_nanxcpt(x, "neg", x);
@@ -55,7 +64,16 @@
 
 ieee754sp ieee754sp_abs(ieee754sp x)
 {
+	COMPXSP;
+
+	EXPLODEXSP;
 	CLEARCX;
+	FLUSHXSP;
+
+	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
+	}
 
 	if (ieee754sp_isnan(x))	/* but not infinity */
 		return ieee754sp_nanxcpt(x, "abs", x);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_sqrt.c linux/arch/mips/math-emu/sp_sqrt.c
--- linux.orig/arch/mips/math-emu/sp_sqrt.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_sqrt.c	2002-07-20 01:08:25.000000000 +0000
@@ -27,43 +27,45 @@
 
 #include "ieee754sp.h"
 
-static const struct ieee754sp_konst knan = {
-	0, SP_EBIAS + SP_EMAX + 1, 0
-};
-
-#define nan	((ieee754sp)knan)
-
 ieee754sp ieee754sp_sqrt(ieee754sp x)
 {
 	int sign = (int) 0x80000000;
 	int ix, s, q, m, t, i;
 	unsigned int r;
-	COMPXDP;
+	COMPXSP;
 
 	/* take care of Inf and NaN */
 
-	EXPLODEXDP;
+	EXPLODEXSP;
+	CLEARCX;
+	FLUSHXSP;
 
 	/* x == INF or NAN? */
 	switch (xc) {
 	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
 		/* sqrt(Nan) = Nan */
 		return ieee754sp_nanxcpt(x, "sqrt");
+	case IEEE754_CLASS_SNAN:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
 	case IEEE754_CLASS_ZERO:
 		/* sqrt(0) = 0 */
 		return x;
 	case IEEE754_CLASS_INF:
-		if (xs)
+		if (xs) {
 			/* sqrt(-Inf) = Nan */
-			return ieee754sp_nanxcpt(nan, "sqrt");
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
+		}
 		/* sqrt(+Inf) = Inf */
 		return x;
 	case IEEE754_CLASS_DNORM:
 	case IEEE754_CLASS_NORM:
-		if (xs)
+		if (xs) {
 			/* sqrt(-x) = Nan */
-			return ieee754sp_nanxcpt(nan, "sqrt");
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
+		}
 		break;
 	}
 
@@ -99,6 +101,7 @@
 	}
 
 	if (ix != 0) {
+		SETCX(IEEE754_INEXACT);
 		switch (ieee754_csr.rm) {
 		case IEEE754_RP:
 			q += 2;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_sub.c linux/arch/mips/math-emu/sp_sub.c
--- linux.orig/arch/mips/math-emu/sp_sub.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_sub.c	2002-07-20 01:08:32.000000000 +0000
@@ -32,32 +32,28 @@
 	COMPXSP;
 	COMPYSP;
 
-	CLEARCX;
-
 	EXPLODEXSP;
 	EXPLODEYSP;
 
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "sub", x,
-					 y);
+	CLEARCX;
+
+	FLUSHXSP;
+	FLUSHYSP;
 
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y, "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x, "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754sp_bestnan(x, y);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "sub", x, y);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -65,6 +61,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return y;
 
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_tint.c linux/arch/mips/math-emu/sp_tint.c
--- linux.orig/arch/mips/math-emu/sp_tint.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_tint.c	2002-07-20 01:08:36.000000000 +0000
@@ -35,38 +35,74 @@
 	CLEARCX;
 
 	EXPLODEXSP;
+	FLUSHXSP;
 
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_QNAN:
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754si_xcpt(ieee754si_indef(), "fixsp", x);
 	case IEEE754_CLASS_INF:
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754si_xcpt(ieee754si_indef(), "fixsp", x);
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
 	case IEEE754_CLASS_ZERO:
 		return 0;
-	case IEEE754_CLASS_DNORM:	/* much to small */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754si_xcpt(0, "fixsp", x);
+	case IEEE754_CLASS_DNORM:
 	case IEEE754_CLASS_NORM:
 		break;
 	}
 	if (xe >= 31) {
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754si_xcpt(ieee754si_indef(), "fix", x);
-	}
-	if (xe < 0) {
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754si_xcpt(0, "fix", x);
+		/* look for valid corner case */
+		if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
+			return -2147483648;
+		/* Set invalid. We will only use overflow for floating
+		   point overflow */
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
 	}
 	/* oh gawd */
 	if (xe > SP_MBITS) {
 		xm <<= xe - SP_MBITS;
-	} else if (xe < SP_MBITS) {
-		/* XXX no rounding 
-		 */
-		xm >>= SP_MBITS - xe;
+	} else {
+		unsigned long residue;
+		int round;
+		int sticky;
+		int odd;
+
+		if (xe < -1) {
+			residue = xm;
+			round = 0;
+			sticky = residue != 0;
+			xm = 0;
+		}
+		else {
+			residue = xm << (32 - SP_MBITS + xe);
+			round = (residue >> 31) != 0;
+			sticky = (residue << 1) != 0;
+			xm >>= SP_MBITS - xe;
+		}
+		odd = (xm & 0x1) != 0x0;
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			if (round && (sticky || odd))
+				xm++;
+			break;
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if ((round || sticky) && !xs)
+				xm++;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if ((round || sticky) && xs)
+				xm++;
+			break;
+		}
+		if ((xm >> 31) != 0) {
+			/* This can happen after rounding */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
+		}
+		if (round || sticky)
+			SETCX(IEEE754_INEXACT);
 	}
 	if (xs)
 		return -xm;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/math-emu/sp_tlong.c linux/arch/mips/math-emu/sp_tlong.c
--- linux.orig/arch/mips/math-emu/sp_tlong.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/math-emu/sp_tlong.c	2002-07-20 01:08:36.000000000 +0000
@@ -34,38 +34,74 @@
 	CLEARCX;
 
 	EXPLODEXSP;
+	FLUSHXSP;
 
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_QNAN:
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
 	case IEEE754_CLASS_INF:
-		SETCX(IEEE754_OVERFLOW);
+		SETCX(IEEE754_INVALID_OPERATION);
 		return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
 	case IEEE754_CLASS_ZERO:
 		return 0;
-	case IEEE754_CLASS_DNORM:	/* much to small */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754di_xcpt(0, "sp_tlong", x);
+	case IEEE754_CLASS_DNORM:
 	case IEEE754_CLASS_NORM:
 		break;
 	}
 	if (xe >= 63) {
-		SETCX(IEEE754_OVERFLOW);
+		/* look for valid corner case */
+		if (xe == 63 && xs && xm == SP_HIDDEN_BIT)
+			return -9223372036854775808LL;
+		/* Set invalid. We will only use overflow for floating
+		   point overflow */
+		SETCX(IEEE754_INVALID_OPERATION);
 		return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
 	}
-	if (xe < 0) {
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754di_xcpt(0, "sp_tlong", x);
-	}
 	/* oh gawd */
 	if (xe > SP_MBITS) {
 		xm <<= xe - SP_MBITS;
 	} else if (xe < SP_MBITS) {
-		/* XXX no rounding 
-		 */
-		xm >>= SP_MBITS - xe;
+		unsigned long residue;
+		int round;
+		int sticky;
+		int odd;
+
+		if (xe < -1) {
+			residue = xm;
+			round = 0;
+			sticky = residue != 0;
+			xm = 0;
+		}
+		else {
+			residue = xm << (32 - SP_MBITS + xe);
+			round = (residue >> 31) != 0;
+			sticky = (residue << 1) != 0;
+			xm >>= SP_MBITS - xe;
+		}
+		odd = (xm & 0x1) != 0x0;
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			if (round && (sticky || odd))
+				xm++;
+			break;
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if ((round || sticky) && !xs)
+				xm++;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if ((round || sticky) && xs)
+				xm++;
+			break;
+		}
+		if ((xm >> 63) != 0) {
+			/* This can happen after rounding */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754si_xcpt(ieee754di_indef(), "sp_tlong", x);
+		}
+		if (round || sticky)
+			SETCX(IEEE754_INEXACT);
 	}
 	if (xs)
 		return -xm;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/atlas/Makefile linux/arch/mips/mips-boards/atlas/Makefile
--- linux.orig/arch/mips/mips-boards/atlas/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/mips-boards/atlas/Makefile	2002-07-20 01:08:40.000000000 +0000
@@ -28,10 +28,7 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 all: atlas.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/atlas/atlas_int.c linux/arch/mips/mips-boards/atlas/atlas_int.c
--- linux.orig/arch/mips/mips-boards/atlas/atlas_int.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mips-boards/atlas/atlas_int.c	2002-07-20 01:08:26.000000000 +0000
@@ -42,20 +42,12 @@
 extern asmlinkage void mipsIRQ(void);
 extern void do_IRQ(int irq, struct pt_regs *regs);
 
-unsigned long spurious_count = 0;
-irq_desc_t irq_desc[NR_IRQS];
-
 #if 0
 #define DEBUG_INT(x...) printk(x)
 #else
 #define DEBUG_INT(x...)
 #endif
 
-void inline disable_irq_nosync(unsigned int irq_nr)
-{
-	disable_atlas_irq(irq_nr);
-}
-
 void disable_atlas_irq(unsigned int irq_nr)
 {
 	atlas_hw0_icregs->intrsten = (1 << irq_nr);
@@ -93,76 +85,6 @@
 	NULL
 };
 
-int get_irq_list(char *buf)
-{
-	int i, len = 0;
-	int num = 0;
-	struct irqaction *action;
-
-	for (i = 0; i < ATLASINT_END; i++, num++) {
-		action = irq_desc[i].action;
-		if (!action) 
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
-			(action->flags & SA_INTERRUPT) ? '+' : ' ',
-			action->name);
-		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ",%s %s",
-				(action->flags & SA_INTERRUPT) ? " +" : "",
-				action->name);
-		}
-		len += sprintf(buf+len, " [hw0]\n");
-	}
-	return len;
-}
-
-int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
-{  
-        struct irqaction *action;
-
-	DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname);
-
-	if (irq >= ATLASINT_END)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
-
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if(!action)
-		return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->mask = 0;
-	action->name = devname;
-	action->dev_id = dev_id;
-	action->next = 0;
-	irq_desc[irq].action = action;
-	enable_atlas_irq(irq);
-
-	return 0;
-}
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-	struct irqaction *action;
-
-	if (irq >= ATLASINT_END) {
-		printk("Trying to free IRQ%d\n",irq);
-		return;
-	}
-
-	action = irq_desc[irq].action;
-	irq_desc[irq].action = NULL;
-	disable_atlas_irq(irq);
-	kfree(action);
-}
-
 static inline int ls1bit32(unsigned int x)
 {
 	int b = 31, s;
@@ -194,9 +116,9 @@
 	DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
 
 	/* if action == NULL, then we don't have a handler for the irq */
-	if ( action == NULL ) {
+	if (action == NULL) {
 		printk("No handler for hw0 irq: %i\n", irq);
-		spurious_count++;
+		atomic_inc(&irq_err_count);
 		return;
 	}
 
@@ -208,17 +130,6 @@
 	return;		
 }
 
-unsigned long probe_irq_on (void)
-{
-	return 0;
-}
-
-
-int probe_irq_off (unsigned long irqs)
-{
-	return 0;
-}
-
 #ifdef CONFIG_REMOTE_DEBUG
 extern void breakpoint(void);
 extern int remote_debug;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/atlas/atlas_setup.c linux/arch/mips/mips-boards/atlas/atlas_setup.c
--- linux.orig/arch/mips/mips-boards/atlas/atlas_setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mips-boards/atlas/atlas_setup.c	2002-07-20 01:08:22.000000000 +0000
@@ -28,8 +28,10 @@
 #include <asm/irq.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/prom.h>
-#include <asm/gt64120.h>
 #include <asm/mips-boards/atlasint.h>
+#include <asm/gt64120.h>
+#include <asm/time.h>
+#include <asm/traps.h>
 
 #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
 extern void console_setup(char *, int *);
@@ -47,6 +49,17 @@
 
 extern void mips_reboot_setup(void);
 
+const char *get_system_type(void)
+{
+	return "MIPS Atlas";
+}
+
+void __init bus_error_init(void)
+{
+}
+
+extern void mips_time_init(void);
+
 void __init atlas_setup(void)
 {
 #ifdef CONFIG_REMOTE_DEBUG
@@ -110,6 +123,7 @@
 		mips_cpu.options &= ~MIPS_CPU_FPU;
 
 	rtc_ops = &atlas_rtc_ops;
+	board_time_init = mips_time_init;
 
 	mips_reboot_setup();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/generic/Makefile linux/arch/mips/mips-boards/generic/Makefile
--- linux.orig/arch/mips/mips-boards/generic/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/mips-boards/generic/Makefile	2002-07-20 01:08:39.000000000 +0000
@@ -2,8 +2,6 @@
 # Carsten Langgaard, carstenl@mips.com
 # Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
 #
-# ########################################################################
-#
 # This program is free software; you can distribute it and/or modify it
 # under the terms of the GNU General Public License (Version 2) as
 # published by the Free Software Foundation.
@@ -17,8 +15,6 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 #
-# #######################################################################
-#
 # Makefile for the MIPS boards generic routines under Linux.
 #
 # Note! Dependencies are done automagically by 'make dep', which also
@@ -27,15 +23,13 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := mipsboards.o
 
-obj-y				:= mipsIRQ.o pci.o reset.o display.o init.o \
+obj-y				:= mipsIRQ.o reset.o display.o init.o \
 				   memory.o printf.o cmdline.o time.o
+obj-$(CONFIG_PCI)		+= pci.o
 obj-$(CONFIG_REMOTE_DEBUG)	+= gdb_hook.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/generic/cmdline.c linux/arch/mips/mips-boards/generic/cmdline.c
--- linux.orig/arch/mips/mips-boards/generic/cmdline.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mips-boards/generic/cmdline.c	2002-07-20 01:08:29.000000000 +0000
@@ -17,16 +17,21 @@
  *
  * Kernel command line creation using the prom monitor (YAMON) argc/argv.
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
 
 extern int prom_argc;
-extern char **prom_argv;
+extern int *_prom_argv;
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
+
+char arcs_cmdline[CL_SIZE];
 
 char * __init prom_getcmdline(void)
 {
@@ -43,8 +48,8 @@
 
 	cp = &(arcs_cmdline[0]);
 	while(actr < prom_argc) {
-	        strcpy(cp, prom_argv[actr]);
-		cp += strlen(prom_argv[actr]);
+	        strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
 		*cp++ = ' ';
 		actr++;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/generic/gdb_hook.c linux/arch/mips/mips-boards/generic/gdb_hook.c
--- linux.orig/arch/mips/mips-boards/generic/gdb_hook.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mips-boards/generic/gdb_hook.c	2002-07-20 01:08:33.000000000 +0000
@@ -22,7 +22,7 @@
  * This is the interface to the remote debugger stub.
  *
  */
-
+#include <linux/config.h>
 #include <linux/serialP.h>
 #include <linux/serial_reg.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/generic/init.c linux/arch/mips/mips-boards/generic/init.c
--- linux.orig/arch/mips/mips-boards/generic/init.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/mips-boards/generic/init.c	2002-07-20 01:08:23.000000000 +0000
@@ -27,6 +27,8 @@
 #include <asm/mips-boards/generic.h>
 #include <asm/gt64120.h>
 #include <asm/mips-boards/malta.h>
+#include <asm/mips-boards/msc01_pci.h>
+#include <asm/mips-boards/bonito64.h>
 
 /* Environment variable */
 typedef struct
@@ -36,27 +38,37 @@
 } t_env_var;
 
 int prom_argc;
-char **prom_argv, **prom_envp;
+int *_prom_argv, *_prom_envp;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension, if running in 64-bit mode.
+ */
+#define prom_envp(index) ((char *)(((int *)(int)_prom_envp)[(index)]))
 
 int init_debug = 0;
 
+unsigned int mips_revision_corid;
+
 char *prom_getenv(char *envname)
 {
-        /*
+	/*
 	 * Return a pointer to the given environment variable.
+	 * In 64-bit mode: we're using 64-bit pointers, but all pointers 
+	 * in the PROM structures are only 32-bit, so we need some 
+	 * workarounds, if we are running in 64-bit mode.
 	 */
-
-	t_env_var *env = (t_env_var *)prom_envp;
-	int i;
+	int i, index=0;
 
 	i = strlen(envname);
 
-	while(env->name) {
-		if(strncmp(envname, env->name, i) == 0) {
-			return(env->val);
+	while(prom_envp(index)) {
+		if(strncmp(envname, prom_envp(index), i) == 0) {
+			return(prom_envp(index+1));
 		}
-		env++;
+		index += 2;
 	}
+
 	return(NULL);
 }
 
@@ -109,26 +121,83 @@
 int __init prom_init(int argc, char **argv, char **envp)
 {
 	prom_argc = argc;
-	prom_argv = argv;
-	prom_envp = envp;
+	_prom_argv = (int *)argv;
+	_prom_envp = (int *)envp;
 
 	mips_display_message("LINUX");
 
-	/*
-	 * Setup the North bridge to do Master byte-lane swapping when 
-	 * running in bigendian.
-	 */
+#ifdef CONFIG_MIPS_SEAD
+	set_io_port_base(KSEG1);
+#else
+	mips_revision_corid = MIPS_REVISION_CORID;
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+		/*
+		 * Setup the North bridge to do Master byte-lane swapping 
+		 * when running in bigendian.
+		 */
+#if defined(__MIPSEL__)
+		GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
+			 GT_PCI0_CMD_SBYTESWAP_BIT);
+#else
+		GT_WRITE(GT_PCI0_CMD_OFS, 0);
+#endif
+
+#if defined(CONFIG_MIPS_MALTA)
+		set_io_port_base(MALTA_GT_PORT_BASE);
+#else
+		set_io_port_base(KSEG1);
+#endif		
+
+		break;
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+		/* 
+		 * Disable Bonito IOBC.
+		 */
+		BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & 
+			~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
+			  BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
+
+		/*
+		 * Setup the North bridge to do Master byte-lane swapping
+		 * when running in bigendian.
+		 */
 #if defined(__MIPSEL__)
-	GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
-		 GT_PCI0_CMD_SBYTESWAP_BIT);
+		BONITO_BONGENCFG = BONITO_BONGENCFG & 
+			~(BONITO_BONGENCFG_MSTRBYTESWAP | 
+			  BONITO_BONGENCFG_BYTESWAP);
 #else
-	GT_WRITE(GT_PCI0_CMD_OFS, 0);
+		BONITO_BONGENCFG = BONITO_BONGENCFG | 
+			BONITO_BONGENCFG_MSTRBYTESWAP | 
+			BONITO_BONGENCFG_BYTESWAP;
 #endif
 
 #if defined(CONFIG_MIPS_MALTA)
-	mips_io_port_base = MALTA_PORT_BASE;
+                set_io_port_base(MALTA_BONITO_PORT_BASE);
 #else
-	mips_io_port_base = KSEG1;
+                set_io_port_base(KSEG1);
+#endif
+		break;
+
+	case MIPS_REVISION_CORID_CORE_MSC:
+	        set_io_port_base(MALTA_MSC_PORT_BASE);
+#if defined(__MIPSEL__)
+		MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
+#else
+		MSC_WRITE(MSC01_PCI_SWAP, 
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
+#endif
+		break;
+	default:
+		/* Unknown Core card */
+		mips_display_message("CC Error");
+		while(1);   /* We die here... */
+	}
 #endif
 	setup_prom_printf(0);
 	prom_printf("\nLINUX started...\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/generic/mipsIRQ.S linux/arch/mips/mips-boards/generic/mipsIRQ.S
--- linux.orig/arch/mips/mips-boards/generic/mipsIRQ.S	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/mips-boards/generic/mipsIRQ.S	2002-07-20 01:08:31.000000000 +0000
@@ -56,6 +56,10 @@
  *             6        Hardware (ignored)
  *             7        R4k timer (what we use)
  *
+ * Note: On the SEAD board thing are a little bit different.
+ *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
+ *       wired to UART1.
+ *	
  * We handle the IRQ according to _our_ priority which is:
  *
  * Highest ----     R4k Timer
@@ -90,14 +94,21 @@
 	 nop
 
 1:
+#if defined(CONFIG_MIPS_SEAD) 	
 	beq	a0, zero, 1f
-	 nop
-
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check hw1 interrupt
+#else
+	beq	a0, zero, 1f		# delay slot, check hw3 interrupt
+ 	 andi	a0, s0, CAUSEF_IP5	
+#endif
+	
 	/* Wheee, combined hardware level zero interrupt. */
 #if defined(CONFIG_MIPS_ATLAS)
 	jal	atlas_hw0_irqdispatch
 #elif defined(CONFIG_MIPS_MALTA)
 	jal	malta_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_SEAD)
+	jal	sead_hw0_irqdispatch
 #else
 #error "MIPS board not supported\n"	
 #endif
@@ -107,6 +118,24 @@
 	 nop				# delay slot
 
 1:
+#if defined(CONFIG_MIPS_SEAD) 	
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP5	# delay slot, check hw3 interrupt
+	jal	sead_hw1_irqdispatch
+	 move	a0, sp			# delay slot	
+	j	ret_from_irq
+	 nop				# delay slot
+1:	
+#endif	
+
+	beq	a0, zero, 1f            # check hw3 (coreHI) interrupt
+	 nop
+	jal	corehi_irqdispatch
+	 move	a0, sp			
+	j	ret_from_irq
+	 nop				
+1:	
+
 	/*
 	 * Here by mistake?  This is possible, what can happen is that by the
 	 * time we take the exception the IRQ pin goes low, so just leave if
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/generic/pci.c linux/arch/mips/mips-boards/generic/pci.c
--- linux.orig/arch/mips/mips-boards/generic/pci.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mips-boards/generic/pci.c	2002-07-20 01:08:33.000000000 +0000
@@ -29,66 +29,229 @@
 
 #include <asm/mips-boards/generic.h>
 #include <asm/gt64120.h>
+#include <asm/mips-boards/bonito64.h>
 #ifdef CONFIG_MIPS_MALTA
 #include <asm/mips-boards/malta.h>
 #endif
+#include <asm/mips-boards/msc01_pci.h>
 
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
+/*
+ *  PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF           0
+#define PCI_CFG_TYPE0_FUNC_SHF          8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF           0
+#define PCI_CFG_TYPE1_FUNC_SHF          8
+#define PCI_CFG_TYPE1_DEV_SHF           11
+#define PCI_CFG_TYPE1_BUS_SHF           16
+
 static int
 mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
                            unsigned char where, u32 *data)
 {
 	unsigned char bus = dev->bus->number;
 	unsigned char dev_fn = dev->devfn;
-        u32 intr;
+	unsigned char type;
+	u32 intr, dummy;
+	u64 pci_addr;
+
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	        /* Galileo GT64120 system controller. */
+
+		if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0)))
+			return -1; /* Because of a bug in the galileo (for slot 31). */
+
+		/* Clear cause register bits */
+		GT_READ(GT_INTRCAUSE_OFS, intr);
+		GT_WRITE(GT_INTRCAUSE_OFS, intr & 
+			 ~(GT_INTRCAUSE_MASABORT0_BIT | 
+			   GT_INTRCAUSE_TARABORT0_BIT));
+
+		/* Setup address */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, 
+			 (bus         << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
+			 (dev_fn      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+			 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
+			 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+		if (access_type == PCI_ACCESS_WRITE) {
+			if (bus == 0 && dev_fn == 0) {
+				/* 
+				 * The Galileo system controller is acting 
+				 * differently than other devices. 
+				 */
+				GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+			} else {
+				GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+			}
+		} else {
+			if (bus == 0 && dev_fn == 0) {
+				/* 
+				 * The Galileo system controller is acting 
+				 * differently than other devices. 
+				 */
+				GT_READ(GT_PCI0_CFGDATA_OFS, *data);
+			} else {
+				GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data);
+			}
+		}
 
-	if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0)))
-	        return -1; /* Because of a bug in the galileo (for slot 31). */
+		/* Check for master or target abort */
+		GT_READ(GT_INTRCAUSE_OFS, intr);
 
-	/* Clear cause register bits */
-	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
-	                             GT_INTRCAUSE_TARABORT0_BIT));
-
-	/* Setup address */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS, 
-		 (bus         << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
-		 (dev_fn      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
-		 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
-		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
-
-	if (access_type == PCI_ACCESS_WRITE) {
-	        if (bus == 0 && dev_fn == 0) {
-		        /* 
-			 * Galileo is acting differently than other devices. 
-			 */
-		        GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+		if (intr & (GT_INTRCAUSE_MASABORT0_BIT | 
+			    GT_INTRCAUSE_TARABORT0_BIT))
+		{
+			/* Error occured */
+
+			/* Clear bits */
+			GT_READ(GT_INTRCAUSE_OFS, intr);
+			GT_WRITE(GT_INTRCAUSE_OFS, intr & 
+				 ~(GT_INTRCAUSE_MASABORT0_BIT | 
+				   GT_INTRCAUSE_TARABORT0_BIT));
+
+			return -1;
+		}
+
+		break;
+
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+	        /* Algorithmics Bonito64 system controller. */
+
+	        if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) {
+		        return -1;
+		}
+
+		/* Clear cause register bits */
+		BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | 
+				  BONITO_PCICMD_MTABORT_CLR);
+
+		/* 
+		 * Setup pattern to be used as PCI "address" for 
+		 * Type 0 cycle 
+		 */
+		if (bus == 0) {
+		        /* IDSEL */
+		        pci_addr = (u64)1 << (PCI_SLOT(dev_fn) + 10);
 		} else {
-		        GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+		        /* Bus number */
+		        pci_addr = bus << PCI_CFG_TYPE1_BUS_SHF;
+
+			/* Device number */
+			pci_addr |= PCI_SLOT(dev_fn) << PCI_CFG_TYPE1_DEV_SHF;
 		}
-	} else {
-	        if (bus == 0 && dev_fn == 0) {
-		        /* 
-			 * Galileo is acting differently than other devices. 
-			 */
-		        GT_READ(GT_PCI0_CFGDATA_OFS, *data);
+
+		/* Function (same for Type 0/1) */
+		pci_addr |= PCI_FUNC(dev_fn) << PCI_CFG_TYPE0_FUNC_SHF;
+		
+		/* Register number (same for Type 0/1) */
+		pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF;
+		
+		if (bus == 0) {
+		        /* Type 0 */
+		        BONITO_PCIMAP_CFG = pci_addr >> 16;
 		} else {
-		        GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data);
+		        /* Type 1 */
+		        BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000;
+		}
+	  
+		/* Flush Bonito register block */
+		dummy = BONITO_PCIMAP_CFG;
+		__asm__ __volatile__(
+				     ".set\tnoreorder\n\t"
+				     ".set\tnoat\n\t"
+				     "sync\n\t"
+				     ".set\tat\n\t"
+				     ".set\treorder");
+
+		/* Perform access */
+		if (access_type == PCI_ACCESS_WRITE) {
+		        *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + 
+					  (pci_addr & 0xffff))) = *(u32 *)data;
+
+			/* Wait till done */
+			while (BONITO_PCIMSTAT & 0xF)
+			        ;
+		} else {
+		        *(u32 *)data = 
+			  *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + 
+					    (pci_addr & 0xffff)));
+		}
+
+		/* Detect Master/Target abort */
+		if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | 
+				     BONITO_PCICMD_MTABORT_CLR) )
+		{
+		        /* Error occurred */
+
+		        /* Clear bits */
+		        BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | 
+					  BONITO_PCICMD_MTABORT_CLR);
+    
+			return -1;
+		}
+	        break;
+
+	case MIPS_REVISION_CORID_CORE_MSC:
+	        /* MIPS system controller. */
+
+	        if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) {
+		        return -1;
 		}
-	}
 
-	/* Check for master or target abort */
-	GT_READ(GT_INTRCAUSE_OFS, intr);
+		/* Clear status register bits. */
+		MSC_WRITE(MSC01_PCI_INTSTAT, 
+			  (MSC01_PCI_INTCFG_MA_BIT | 
+			   MSC01_PCI_INTCFG_TA_BIT));
+
+		/* Setup address */
+		if (bus == 0)
+			type = 0;  /* Type 0 */
+		else
+			type = 1;  /* Type 1 */
+
+		MSC_WRITE(MSC01_PCI_CFGADDR,
+			  ((bus              << MSC01_PCI_CFGADDR_BNUM_SHF) |
+			   (PCI_SLOT(dev_fn) << MSC01_PCI_CFGADDR_DNUM_SHF) |
+			   (PCI_FUNC(dev_fn) << MSC01_PCI_CFGADDR_FNUM_SHF) |
+			   ((where /4 )      << MSC01_PCI_CFGADDR_RNUM_SHF) |
+			   (type)));
+
+		/* Perform access */
+		if (access_type == PCI_ACCESS_WRITE) {
+		        MSC_WRITE(MSC01_PCI_CFGDATA, *data);
+		} else {
+			MSC_READ(MSC01_PCI_CFGDATA, *data);
+		}
 
-	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT))
-	{
-	        /* Error occured */
-
-	        /* Clear bits */
-	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
-					      GT_INTRCAUSE_TARABORT0_BIT) );
+		/* Detect Master/Target abort */
+		MSC_READ(MSC01_PCI_INTSTAT, intr);
+		if (intr & (MSC01_PCI_INTCFG_MA_BIT | 
+			    MSC01_PCI_INTCFG_TA_BIT))
+		{
+		        /* Error occurred */
+
+		        /* Clear bits */
+			MSC_READ(MSC01_PCI_INTSTAT, intr);
+			MSC_WRITE(MSC01_PCI_INTSTAT,
+				  (MSC01_PCI_INTCFG_MA_BIT | 
+				   MSC01_PCI_INTCFG_TA_BIT));
 
+			return -1;
+		}
+	        break;
+	default:
+	        printk("Unknown Core card, don't know the system controller.\n");
 		return -1;
 	}
 
@@ -216,21 +379,28 @@
 	printk("PCI: Probing PCI hardware on host bus 0.\n");
 	pci_scan_bus(0, &mips_pci_ops, NULL);
 
-	/* 
-	 * Due to a bug in the Galileo system controller, we need to setup 
-	 * the PCI BAR for the Galileo internal registers.
-	 * This should be done in the bios/bootprom and will be fixed in
-	 * a later revision of YAMON (the MIPS boards boot prom).
-	 */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,
-		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF)   |  /* Local bus */
-		 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF)   |  /* GT64120 device */
-		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |  /* Function 0 */
-		 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) |  /* BAR 4 */
-		 GT_PCI0_CFGADDR_CONFIGEN_BIT );
-
-	/* Perform the write */
-	GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); 
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+		/* 
+		 * Due to a bug in the Galileo system controller, we need 
+		 * to setup the PCI BAR for the Galileo internal registers.
+		 * This should be done in the bios/bootprom and will be 
+		 * fixed in a later revision of YAMON (the MIPS boards 
+		 * boot prom).
+		 */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS,
+			 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
+			 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
+			 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
+			 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
+			 GT_PCI0_CFGADDR_CONFIGEN_BIT );
+
+		/* Perform the write */
+		GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); 
+		break;
+	}
 
 #ifdef CONFIG_MIPS_MALTA
 	pci_for_each_dev(pdev) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/generic/printf.c linux/arch/mips/mips-boards/generic/printf.c
--- linux.orig/arch/mips/mips-boards/generic/printf.c	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/mips-boards/generic/printf.c	2002-07-20 01:08:28.000000000 +0000
@@ -40,12 +40,12 @@
  */
 unsigned int atlas_serial_in(struct async_struct *info, int offset)
 {
-	return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff);
+	return inl(info->port + offset*8) & 0xff;
 }
 
 void atlas_serial_out(struct async_struct *info, int offset, int value)
 {
-	*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value;
+	outl(value, info->port + offset*8);
 }
 
 #define serial_in  atlas_serial_in
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/generic/time.c linux/arch/mips/mips-boards/generic/time.c
--- linux.orig/arch/mips/mips-boards/generic/time.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mips-boards/generic/time.c	2002-07-20 01:08:38.000000000 +0000
@@ -23,6 +23,7 @@
  *
  */
 
+#include <linux/types.h>
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
@@ -31,21 +32,21 @@
 
 #include <asm/mipsregs.h>
 #include <asm/ptrace.h>
+#include <asm/hardirq.h>
 #include <asm/div64.h>
+#include <asm/cpu.h>
 
+#include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/prom.h>
 
-extern volatile unsigned long wall_jiffies;
-static long last_rtc_update = 0;
-unsigned long missed_heart_beats = 0;
-
-static unsigned long r4k_offset; /* Amount to increment compare reg each time */
-static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-extern rwlock_t xtime_lock;
+static unsigned int r4k_offset; /* Amount to increment compare reg each time */
+static unsigned int r4k_cur;    /* What counter should be at next timer irq */
+
+extern unsigned int mips_counter_frequency;
 
 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
 
@@ -58,125 +59,36 @@
 static unsigned int display_count = 0;
 #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) 
 
+#define MIPS_CPU_TIMER_IRQ 7
+
 static unsigned int timer_tick_count=0;
 
 
-static inline void ack_r4ktimer(unsigned long newval)
+static inline void ack_r4ktimer(unsigned int newval)
 {
 	write_32bit_cp0_register(CP0_COMPARE, newval);
 }
 
-
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you won't notice until after reboot!
- */
-static int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned char save_control, save_freq_select;
-
-	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-	cmos_minutes = CMOS_READ(RTC_MINUTES);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
- 		retval = -1;
-	}
-
-	/* The following flags have to be released exactly in this order,
-	 * otherwise the DS12887 (popular MC146818A clone with integrated
-	 * battery and quartz) will not reset the oscillator and will not
-	 * update precisely 500 ms later. You won't find this mentioned in
-	 * the Dallas Semiconductor data sheets, but who believes data
-	 * sheets anyway ...                           -- Markus Kuhn
-	 */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
-	return retval;
-}
-
-/*
- * There are a lot of conceptually broken versions of the MIPS timer interrupt
- * handler floating around.  This one is rather different, but the algorithm
- * is provably more robust.
- */
 void mips_timer_interrupt(struct pt_regs *regs)
 {
-	int irq = 7;
-
-	if (r4k_offset == 0)
-		goto null;
+	int cpu = smp_processor_id();
+	int irq = MIPS_CPU_TIMER_IRQ;
 
-	do {
-		kstat.irqs[0][irq]++;
-		do_timer(regs);
-
-		/* Historical comment/code:
- 		 * RTC time of day s updated approx. every 11 
- 		 * minutes.  Because of how the numbers work out 
- 		 * we need to make absolutely sure we do this update
- 		 * within 500ms before the * next second starts, 
- 		 * thus the following code.
- 		 */
-		read_lock(&xtime_lock);
-		if ((time_status & STA_UNSYNC) == 0 
-		    && xtime.tv_sec > last_rtc_update + 660 
-		    && xtime.tv_usec >= 500000 - (tick >> 1) 
-		    && xtime.tv_usec <= 500000 + (tick >> 1))
-			if (set_rtc_mmss(xtime.tv_sec) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else
-				/* do it again in 60 s */
-	    			last_rtc_update = xtime.tv_sec - 600; 
-		read_unlock(&xtime_lock);
-
-		if ((timer_tick_count++ % HZ) == 0) {
-		    mips_display_message(&display_string[display_count++]);
-		    if (display_count == MAX_DISPLAY_COUNT)
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+	timer_interrupt(irq, NULL, regs);
+
+	if ((timer_tick_count++ % HZ) == 0) {
+		mips_display_message(&display_string[display_count++]);
+		if (display_count == MAX_DISPLAY_COUNT)
 		        display_count = 0;
-		}
-
-		r4k_cur += r4k_offset;
-		ack_r4ktimer(r4k_cur);
 
-	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
-	         - r4k_cur) < 0x7fffffff);
+	}
 
-	return;
+	irq_exit(cpu, irq);
 
-null:
-	ack_r4ktimer(0);
+	if (softirq_pending(cpu))
+		do_softirq();
 }
 
 /* 
@@ -184,9 +96,8 @@
  * register for each time tick. 
  * Use the RTC to calculate offset.
  */
-static unsigned long __init cal_r4koff(void)
+static unsigned int __init cal_r4koff(void)
 {
-	unsigned long count;
 	unsigned int flags;
 
 	__save_and_cli(flags);
@@ -202,15 +113,15 @@
 	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
 	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 
-	count = read_32bit_cp0_register(CP0_COUNT);
+	mips_counter_frequency = read_32bit_cp0_register(CP0_COUNT);
 
 	/* restore interrupts */
 	__restore_flags(flags);
 
-	return (count / HZ);
+	return (mips_counter_frequency / HZ);
 }
 
-static unsigned long __init get_mips_time(void)
+unsigned long __init mips_rtc_get_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
 	unsigned char save_control;
@@ -245,166 +156,41 @@
 	return mktime(year, mon, day, hour, min, sec);
 }
 
-void __init time_init(void)
+void __init mips_time_init(void)
 {
         unsigned int est_freq, flags;
 
+	__save_and_cli(flags);
+
         /* Set Data mode - binary. */ 
         CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
 
 	printk("calculating r4koff... ");
 	r4k_offset = cal_r4koff();
-	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+	printk("%08x(%d)\n", r4k_offset, r4k_offset);
+
+        if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == 
+	    (PRID_COMP_MIPS | PRID_IMP_20KC))
+		est_freq = r4k_offset*HZ;
+	else
+		est_freq = 2*r4k_offset*HZ;
 
-	est_freq = 2*r4k_offset*HZ;	
 	est_freq += 5000;    /* round */
 	est_freq -= est_freq%10000;
 	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
 	       (est_freq%1000000)*100/1000000);
-	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
-
-	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
-	change_cp0_status(ST0_IM, ALLINTS);
-
-	/* Read time from the RTC chipset. */
-	write_lock_irqsave (&xtime_lock, flags);
-	xtime.tv_sec = get_mips_time();
-	xtime.tv_usec = 0;
-	write_unlock_irqrestore(&xtime_lock, flags);
-}
 
-/* This is for machines which generate the exact clock. */
-#define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC ((1000000 << 32) / HZ & 0xffffffff)
-
-/* Cycle counter value at the previous timer interrupt.. */
-
-static unsigned int timerhi = 0, timerlo = 0;
-
-/*
- * FIXME: Does playing with the RP bit in c0_status interfere with this code?
- */
-static unsigned long do_fast_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res, tmp;
-
-	/* Last jiffy when do_fast_gettimeoffset() was called. */
-	static unsigned long last_jiffies=0;
-	unsigned long quotient;
-
-	/*
-	 * Cached "1/(clocks per usec)*2^32" value.
-	 * It has to be recalculated once each jiffy.
-	 */
-	static unsigned long cached_quotient=0;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-
-	if (tmp && last_jiffies != tmp) {
-		last_jiffies = tmp;
-#ifdef CONFIG_CPU_MIPS32
-		if (last_jiffies != 0) {
-			unsigned long r0;
-			do_div64_32(r0, timerhi, timerlo, tmp);
-			do_div64_32(quotient, USECS_PER_JIFFY,
-				    USECS_PER_JIFFY_FRAC, r0);
-			cached_quotient = quotient;
-		}
-#else
-		__asm__(".set\tnoreorder\n\t"
-			".set\tnoat\n\t"
-			".set\tmips3\n\t"
-			"lwu\t%0,%2\n\t"
-			"dsll32\t$1,%1,0\n\t"
-			"or\t$1,$1,%0\n\t"
-			"ddivu\t$0,$1,%3\n\t"
-			"mflo\t$1\n\t"
-			"dsll32\t%0,%4,0\n\t"
-			"nop\n\t"
-			"ddivu\t$0,%0,$1\n\t"
-			"mflo\t%0\n\t"
-			".set\tmips0\n\t"
-			".set\tat\n\t"
-			".set\treorder"
-			:"=&r" (quotient)
-			:"r" (timerhi),
-			 "m" (timerlo),
-			 "r" (tmp),
-			 "r" (USECS_PER_JIFFY)
-			:"$1");
-		cached_quotient = quotient;
-#endif
-	}
-
-	/* Get last timer tick in absolute kernel time */
-	count = read_32bit_cp0_register(CP0_COUNT);
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu\t%1,%2\n\t"
-		"mfhi\t%0"
-		:"=r" (res)
-		:"r" (count),
-		 "r" (quotient));
-
-	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY-1;
-
-	return res;
-}
-
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned int flags;
-
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_fast_gettimeoffset();
-
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
-
-	read_unlock_irqrestore (&xtime_lock, flags);
-
-	if (tv->tv_usec >= 1000000) {
-		tv->tv_usec -= 1000000;
-		tv->tv_sec++;
-	}
+	__restore_flags(flags);
 }
 
-void do_settimeofday(struct timeval *tv)
+void __init mips_timer_setup(struct irqaction *irq)
 {
-	write_lock_irq (&xtime_lock);
-
-	/* This is revolting. We need to set the xtime.tv_usec correctly.
-	 * However, the value in this location is is value at the last tick.
-	 * Discover what correction gettimeofday would have done, and then
-	 * undo it!
-	 */
-	tv->tv_usec -= do_fast_gettimeoffset();
-
-	if (tv->tv_usec < 0) {
-		tv->tv_usec += 1000000;
-		tv->tv_sec--;
-	}
+	/* we are using the cpu counter for timer interrupts */
+	irq->handler = no_action;     /* we use our own handler */
+	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
 
-	xtime = *tv;
-	time_adjust = 0;		/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-
-	write_unlock_irq (&xtime_lock);
+        /* to generate the first timer interrupt */
+	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+	set_cp0_status(ALLINTS);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/malta/Makefile linux/arch/mips/mips-boards/malta/Makefile
--- linux.orig/arch/mips/mips-boards/malta/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/mips-boards/malta/Makefile	2002-07-20 01:08:21.000000000 +0000
@@ -28,10 +28,7 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := malta.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/malta/malta_int.c linux/arch/mips/mips-boards/malta/malta_int.c
--- linux.orig/arch/mips/mips-boards/malta/malta_int.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mips-boards/malta/malta_int.c	2002-07-20 01:08:29.000000000 +0000
@@ -36,40 +36,290 @@
 #include <asm/mips-boards/piix4.h>
 #include <asm/gt64120.h>
 #include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/msc01_pci.h>
 
 extern asmlinkage void mipsIRQ(void);
+extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
+extern void init_i8259_irqs (void);
+
+void enable_mips_irq(unsigned int irq);
+void disable_mips_irq(unsigned int irq);
+
+static spinlock_t mips_irq_lock = SPIN_LOCK_UNLOCKED;
+
+static void end_mips_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_mips_irq(irq);
+}
+
+#define shutdown_mips_irq	disable_mips_irq
+
+void mask_and_ack_mips_irq(unsigned int irq);
+
+static unsigned int startup_mips_irq(unsigned int irq)
+{ 
+	enable_mips_irq(irq);
+
+	return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type mips_irq_type = {
+	"XT-PIC",
+	startup_mips_irq,
+	shutdown_mips_irq,
+	enable_mips_irq,
+	disable_mips_irq,
+	mask_and_ack_mips_irq,
+	end_mips_irq,
+	NULL
+};
+
+/*
+ * This contains the interrupt mask for both 82C59 interrupt controllers.
+ */
+static unsigned int cached_int_mask = 0xffff;
+
+void disable_mips_irq(unsigned int irq_nr)
+{
+        unsigned long flags;
+
+	if(irq_nr >= MALTAINT_END) {
+		printk("whee, invalid irq_nr %d\n", irq_nr);
+		panic("IRQ, you lose...");
+	}
+
+	spin_lock_irqsave(&mips_irq_lock, flags);
+	cached_int_mask |= (1 << irq_nr);
+	if (irq_nr & 8) {
+	        outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
+	} else {
+		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
+	}
+	spin_unlock_irqrestore(&mips_irq_lock, flags);
+}
+
+void enable_mips_irq(unsigned int irq_nr)
+{
+        unsigned long flags;
+
+	if(irq_nr >= MALTAINT_END) {
+		printk("whee, invalid irq_nr %d\n", irq_nr);
+		panic("IRQ, you lose...");
+	}
+
+	spin_lock_irqsave(&mips_irq_lock, flags);
+	cached_int_mask &= ~(1 << irq_nr);
+	if (irq_nr & 8) {
+		outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
+
+		/* Enable irq 2 (cascade interrupt). */
+	        cached_int_mask &= ~(1 << 2); 
+		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
+	} else {
+		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
+	}	
+	spin_unlock_irqrestore(&mips_irq_lock, flags);
+}
+
+void mask_and_ack_mips_irq(unsigned int irq)
+{
+        unsigned long flags;
+
+	spin_lock_irqsave(&mips_irq_lock, flags);
+	if (irq & 8) {
+	        /* Non specific EOI to cascade */
+		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI | PIIX4_OCW2_ILS_2, 
+		     PIIX4_ICTLR1_OCW2);
+
+		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR2_OCW2);
+	} else {
+		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR1_OCW2);
+	}
+	spin_unlock_irqrestore(&mips_irq_lock, flags);
+}
+
+static inline int get_int(int *irq)
+{
+	unsigned char irr;
+	
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_MSC:
+		/*  
+		 * Determine highest priority pending interrupt by performing
+		 * a PCI Interrupt Acknowledge cycle.
+		 */
+		if (mips_revision_corid == MIPS_REVISION_CORID_CORE_MSC)
+			MSC_READ(MSC01_PCI_IACK, *irq);
+		else
+			GT_READ(GT_PCI0_IACK_OFS, *irq);
+		*irq &= 0xFF;
+
+		/*  
+		 * IRQ7 is used to detect spurious interrupts.
+		 * The interrupt acknowledge cycle returns IRQ7, if no 
+		 * interrupts is requested.
+		 * We can differentiate between this situation and a
+		 * "Normal" IRQ7 by reading the ISR.
+		 */
+		if (*irq == 7) 
+		{
+			outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, 
+			     PIIX4_ICTLR1_OCW3);
+			if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
+				printk("We got a spurious interrupt from PIIX4.\n");
+				atomic_inc(&irq_err_count);
+				return -1;    /* Spurious interrupt. */
+			}
+		}
+		break;
+
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+	        /*
+		 * Determine highest priority pending interrupt by reading 
+		 * the IRR register of controller 1.
+		 */
+
+		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_IRR, PIIX4_ICTLR1_OCW3);
+		irr = inb(PIIX4_ICTLR1_OCW3) & ~(cached_int_mask & 0xff);
+
+		if (!irr) {
+		        printk("We got a spurious interrupt from PIIX4.\n");
+			atomic_inc(&irq_err_count);
+			return -1;   /* Spurious interrupt. */
+		}
+		*irq = 0;
+		while ((*irq < 7) && !(irr & 0x01)) {
+		        (*irq)++;
+			irr >>= 1;
+		}
+
+		if (*irq == 2)
+		{
+		        /*
+			 * Determine highest priority pending interrupt by 
+			 * reading the IRR register of controller 1.
+			 */
+		        outb(PIIX4_OCW3_SEL | PIIX4_OCW3_IRR, 
+			     PIIX4_ICTLR2_OCW3);
+			irr = inb(PIIX4_ICTLR2_OCW3) & 
+			~((cached_int_mask >> 8) & 0xff);
+
+			*irq = 8;
+			while ((*irq < 15) && !(irr & 0x01)) {
+			        (*irq)++;
+				irr >>= 1;
+			}
+		}
+		break;
+	default:
+	        printk("Unknown Core card, don't know the system controller.\n");
+		return -1;
+	}
+
+	return 0;
+}
 
 void malta_hw0_irqdispatch(struct pt_regs *regs)
 {
 	int irq;
+	struct irqaction *action;
 
-	/*  
-	 * Determine highest priority pending interrupt by performing a PCI
-	 * Interrupt Acknowledge cycle.
-	 */
-	GT_READ(GT_PCI0_IACK_OFS, irq);
-	irq &= 0xFF;
-
-	/*  
-	 * IRQ7 is used to detect spurious interrupts.  The interrupt
-	 * acknowledge cycle returns IRQ7, if no interrupts is requested.  We
-	 * can differentiate between this situation and a "normal" IRQ7 by
-	 * reading the ISR.
-	 */
-	if (irq == 7) {
-		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, PIIX4_ICTLR1_OCW3);
-		if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7)))
-		        return;    /* Spurious interrupt. */
-	}
+	if (get_int(&irq))
+	        return;  /* interrupt has already been cleared */
 
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+		action = irq_desc[irq].action;
+		if (!action)
+			return;
+		action->flags |= SA_INTERRUPT;
+		break;
+	}
+	
 	do_IRQ(irq, regs);
 }
 
+void corehi_irqdispatch(struct pt_regs *regs)
+{
+        unsigned int data,datahi;
+
+        printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n");
+        printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n"
+, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr);
+        switch(mips_revision_corid) {
+        case MIPS_REVISION_CORID_CORE_MSC:
+                break;
+        case MIPS_REVISION_CORID_QED_RM5261:
+        case MIPS_REVISION_CORID_CORE_LV:
+        case MIPS_REVISION_CORID_CORE_FPGA:
+                GT_READ(GT_INTRCAUSE_OFS, data);
+                printk("GT_INTRCAUSE = %08x\n", data);
+                GT_READ(0x70, data);
+                GT_READ(0x78, datahi);
+                printk("GT_CPU_ERR_ADDR = %0x2%08x\n", datahi,data);
+                break;
+        case MIPS_REVISION_CORID_BONITO64:
+        case MIPS_REVISION_CORID_CORE_20K:
+                data = BONITO_INTISR;
+                printk("BONITO_INTISR = %08x\n", data);
+                data = BONITO_INTEN;
+                printk("BONITO_INTEN = %08x\n", data);
+                data = BONITO_INTPOL;
+                printk("BONITO_INTPOL = %08x\n", data);
+                data = BONITO_INTEDGE;
+                printk("BONITO_INTEDGE = %08x\n", data);
+                data = BONITO_INTSTEER;
+                printk("BONITO_INTSTEER = %08x\n", data);
+                data = BONITO_PCICMD;
+                printk("BONITO_PCICMD = %08x\n", data);
+                break;
+        }
+
+        /* We die here*/
+        die("CoreHi interrupt", regs);
+        while (1) ;
+}
+
 void __init init_IRQ(void)
 {
+	unsigned int i;
+
 	set_except_vector(0, mipsIRQ);
 	init_generic_irq();
-	init_i8259_irqs();
+	
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_MSC:
+		init_i8259_irqs();
+		break;
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+		/* 
+		 * Mask out all interrupt by writing "1" to all bit position 
+		 * in the IMR register. 
+		 */
+		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
+		outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
+
+		for (i = 0; i < 16; i++) {
+			irq_desc[i].status = IRQ_DISABLED;
+			irq_desc[i].action = 0;
+			irq_desc[i].depth = 1;
+			irq_desc[i].handler = &mips_irq_type;
+		}
+		break;
+	default:
+	        printk("Unknown Core card, don't know the system controller.\n");
+		return;
+	}
 
 #ifdef CONFIG_REMOTE_DEBUG
 	if (remote_debug) {
@@ -78,3 +328,5 @@
 	}
 #endif
 }
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mips-boards/malta/malta_setup.c linux/arch/mips/mips-boards/malta/malta_setup.c
--- linux.orig/arch/mips/mips-boards/malta/malta_setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mips-boards/malta/malta_setup.c	2002-07-20 01:08:37.000000000 +0000
@@ -36,6 +36,14 @@
 #include <asm/floppy.h>
 #endif
 #include <asm/dma.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+#ifdef CONFIG_PC_KEYB
+#include <asm/keyboard.h>
+#endif
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#endif
 
 #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
 extern void console_setup(char *, int *);
@@ -56,6 +64,13 @@
 
 extern void mips_reboot_setup(void);
 
+extern void (*board_time_init)(void);
+extern void (*board_timer_setup)(struct irqaction *irq);
+extern unsigned long (*rtc_get_time)(void);
+extern void mips_time_init(void);
+extern void mips_timer_setup(struct irqaction *irq);
+extern unsigned long mips_rtc_get_time(void);
+
 struct resource standard_io_resources[] = {
 	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
 	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
@@ -65,13 +80,22 @@
 
 #define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
 
+const char *get_system_type(void)
+{
+	return "MIPS Malta";
+}
+
+void __init bus_error_init(void)
+{
+}
+
 void __init malta_setup(void)
 {
 #ifdef CONFIG_REMOTE_DEBUG
 	int rs_putDebugChar(char);
 	char rs_getDebugChar(void);
-	extern int (*generic_putDebugChar)(char);
-	extern char (*generic_getDebugChar)(void);
+	extern int (*putDebugChar)(char);
+	extern char (*getDebugChar)(void);
 #endif
 	char *argptr;
 	int i;
@@ -106,8 +130,8 @@
 		       line ? 1 : 0);
 
 		rs_kgdb_hook(line);
-		generic_putDebugChar = rs_putDebugChar;
-		generic_getDebugChar = rs_getDebugChar;
+		putDebugChar = rs_putDebugChar;
+		getDebugChar = rs_getDebugChar;
 
 		prom_printf("KGDB: Using serial line /dev/ttyS%d for session, "
 			    "please connect your debugger\n", line ? 1 : 0);
@@ -120,8 +144,17 @@
 	argptr = prom_getcmdline();
 	if ((argptr = strstr(argptr, "nofpu")) != NULL)
 		mips_cpu.options &= ~MIPS_CPU_FPU;
+
+        /* 
+	 * For some reason the irq probing doesn't work on the 
+	 * Bonito controller.
+	 * For now this work just fine.
+	 */
+	argptr = prom_getcmdline();
+	strcat(argptr, " ide0=0x1f0,0x3f6,14");
 		
 	rtc_ops = &malta_rtc_ops;
+
 #ifdef CONFIG_BLK_DEV_IDE
         ide_ops = &std_ide_ops;
 #endif
@@ -131,5 +164,28 @@
 #ifdef CONFIG_PC_KEYB
 	kbd_ops = &std_kbd_ops;
 #endif
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+        conswitchp = &vga_con;
+
+	screen_info = (struct screen_info) {
+		0, 25,			/* orig-x, orig-y */
+		0,			/* unused */
+		0,			/* orig-video-page */
+		0,			/* orig-video-mode */
+		80,			/* orig-video-cols */
+		0,0,0,			/* ega_ax, ega_bx, ega_cx */
+		25,			/* orig-video-lines */
+		1,			/* orig-video-isVGA */
+		16			/* orig-video-points */
+	};
+#elif defined(CONFIG_DUMMY_CONSOLE)
+        conswitchp = &dummy_con;
+#endif
+#endif
 	mips_reboot_setup();
+
+	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+	rtc_get_time = mips_rtc_get_time;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/Makefile linux/arch/mips/mm/Makefile
--- linux.orig/arch/mips/mm/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mm/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -5,23 +5,30 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (ie not a .c file).
 #
-# Note 2! The CFLAGS definition is now in the main makefile...
+
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := mm.o
 
-export-objs			+= ioremap.o umap.o
+export-objs			+= ioremap.o loadmmu.o umap.o
 obj-y				+= extable.o init.o ioremap.o fault.o loadmmu.o
 
-obj-$(CONFIG_CPU_R3000)		+= r2300.o
-obj-$(CONFIG_CPU_R4300)		+= r4xx0.o
-obj-$(CONFIG_CPU_R4X00)		+= r4xx0.o
-obj-$(CONFIG_CPU_VR41XX)	+= r4xx0.o
-obj-$(CONFIG_CPU_R5000)		+= r4xx0.o
-obj-$(CONFIG_CPU_NEVADA)	+= r4xx0.o
-obj-$(CONFIG_CPU_R5432)		+= r5432.o
-obj-$(CONFIG_CPU_RM7000)	+= rm7k.o
-obj-$(CONFIG_CPU_MIPS32)	+= mips32.o
-obj-$(CONFIG_CPU_MIPS64)	+= mips32.o
+obj-$(CONFIG_CPU_R3000)		+= pg-r3k.o c-r3k.o c-tx39.o tlb-r3k.o \
+				   tlbex-r3k.o
+obj-$(CONFIG_CPU_TX39XX)	+= pg-r3k.o c-tx39.o tlb-r3k.o tlbex-r3k.o
+obj-$(CONFIG_CPU_TX49XX)	+= pg-r4k.o c-tx49.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_R4300)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_R4X00)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_VR41XX)	+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_R5000)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_NEVADA)	+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_R5432)		+= pg-r5432.o c-r5432.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_RM7000)	+= pg-rm7k.o c-rm7k.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_R10000)	+= pg-andes.o c-andes.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_MIPS32)	+= pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_MIPS64)	+= pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_SB1)		+= pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o
+
 obj-$(CONFIG_SGI_IP22)		+= umap.o
 obj-$(CONFIG_BAGET_MIPS)	+= umap.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/andes.c linux/arch/mips/mm/andes.c
--- linux.orig/arch/mips/mm/andes.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mm/andes.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,196 +0,0 @@
-/*
- * andes.c: MMU and cache operations for the R10000 (ANDES).
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/sgialib.h>
-#include <asm/mmu_context.h>
-
-/* page functions */
-void andes_clear_page(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"addiu\t$1,%0,%2\n"
-		"1:\tsw\t$0,(%0)\n\t"
-		"sw\t$0,4(%0)\n\t"
-		"sw\t$0,8(%0)\n\t"
-		"sw\t$0,12(%0)\n\t"
-		"addiu\t%0,32\n\t"
-		"sw\t$0,-16(%0)\n\t"
-		"sw\t$0,-12(%0)\n\t"
-		"sw\t$0,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t$0,-4(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE)
-		:"$1","memory");
-}
-
-static void andes_copy_page(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"addiu\t$1,%0,%8\n"
-		"1:\tlw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"addiu\t%0,64\n\t"
-		"addiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE));
-}
-
-/* Cache operations. XXX Write these dave... */
-static inline void andes_flush_cache_all(void)
-{
-	/* XXX */
-}
-
-static void andes_flush_cache_mm(struct mm_struct *mm)
-{
-	/* XXX */
-}
-
-static void andes_flush_cache_range(struct mm_struct *mm,
-				    unsigned long start,
-				    unsigned long end)
-{
-	/* XXX */
-}
-
-static void andes_flush_cache_page(struct vm_area_struct *vma,
-				   unsigned long page)
-{
-	/* XXX */
-}
-
-static void andes_flush_page_to_ram(struct page * page)
-{
-	/* XXX */
-}
-
-static void __andes_flush_icache_range(unsigned long start, unsigned long end)
-{
-	/* XXX */
-}
-
-static void andes_flush_icache_page(struct vm_area_struct *vma,
-                                    struct page *page)
-{
-	/* XXX */
-}
-
-static void andes_flush_cache_sigtramp(unsigned long page)
-{
-	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
-	protected_flush_icache_line(addr & ~(ic_lsize - 1));
-}
-
-/* TLB operations. XXX Write these dave... */
-void flush_tlb_all(void)
-{
-	/* XXX */
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	/* XXX */
-}
-
-void flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				  unsigned long end)
-{
-	/* XXX */
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	/* XXX */
-}
-
-void pgd_init(unsigned long page)
-{
-}
-
-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-				  unsigned long entryhi, unsigned long pagemask)
-{
-        /* XXX */
-}
-
-void __init ld_mmu_andes(void)
-{
-	_clear_page = andes_clear_page;
-	_copy_page = andes_copy_page;
-
-	_flush_cache_all = andes_flush_cache_all;
-	___flush_cache_all = andes_flush_cache_all;
-	_flush_cache_mm = andes_flush_cache_mm;
-	_flush_cache_range = andes_flush_cache_range;
-	_flush_cache_page = andes_flush_cache_page;
-	_flush_cache_sigtramp = andes_flush_cache_sigtramp;
-	_flush_page_to_ram = andes_flush_page_to_ram;
-	_flush_icache_page = andes_flush_icache_page;
-	_flush_icache_range = andes_flush_icache_range;
-
-	write_32bit_cp0_register(CP0_FRAMEMASK, 0);
-
-	flush_cache_all();
-	flush_tlb_all();
-
-	/*
-	 * The R10k might even work for Linux/MIPS - but we're paranoid
-	 * and refuse to run until this is tested on real silicon
-	 */
-	panic("CPU too expensive - making holiday in the ANDES!");
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-andes.c linux/arch/mips/mm/c-andes.c
--- linux.orig/arch/mips/mm/c-andes.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-andes.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,129 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/r10kcache.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
+
+static int scache_lsz64;
+
+static void andes_flush_cache_all(void)
+{
+}
+
+static void andes_flush_cache_mm(struct mm_struct *mm)
+{
+}
+
+static void andes_flush_cache_range(struct mm_struct *mm, unsigned long start,
+                                    unsigned long end)
+{
+}
+
+static void andes_flush_cache_page(struct vm_area_struct *vma,
+                                   unsigned long page)
+{
+}
+
+static void andes_flush_page_to_ram(struct page *page)
+{
+}
+
+/* Cache operations.  These are only used with the virtual memory system,
+   not for non-coherent I/O so it's ok to ignore the secondary caches.  */
+static void
+andes_flush_cache_l1(void)
+{
+	blast_dcache32(); blast_icache64();
+}
+
+/*
+ * This is only used during initialization time. vmalloc() also calls
+ * this, but that will be changed pretty soon.
+ */
+static void
+andes_flush_cache_l2(void)
+{
+	switch (sc_lsize()) {
+		case 64:
+			blast_scache64();
+			break;
+		case 128:
+			blast_scache128();
+			break;
+		default:
+			printk("Unknown L2 line size\n");
+			while(1);
+	}
+}
+
+static void andes___flush_cache_all(void)
+{
+	andes_flush_cache_l1();
+	andes_flush_cache_l2();
+}
+
+void
+andes_flush_icache_page(unsigned long page)
+{
+	if (scache_lsz64)
+		blast_scache64_page(page);
+	else
+		blast_scache128_page(page);
+}
+
+static void
+andes_flush_cache_sigtramp(unsigned long addr)
+{
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+}
+
+void __init ld_mmu_andes(void)
+{
+	printk("Primary instruction cache %dkb, linesize %d bytes\n",
+	       icache_size >> 10, ic_lsize);
+	printk("Primary data cache %dkb, linesize %d bytes\n",
+	       dcache_size >> 10, dc_lsize);
+	printk("Secondary cache sized at %ldK, linesize %ld\n",
+	       scache_size() >> 10, sc_lsize());
+
+	_clear_page = andes_clear_page;
+	_copy_page = andes_copy_page;
+
+	_flush_cache_all = andes_flush_cache_all;
+	___flush_cache_all = andes___flush_cache_all;
+	_flush_cache_mm = andes_flush_cache_mm;
+	_flush_cache_page = andes_flush_cache_page;
+	_flush_page_to_ram = andes_flush_page_to_ram;
+	_flush_cache_l1 = andes_flush_cache_l1;
+	_flush_cache_l2 = andes_flush_cache_l2;
+	_flush_cache_sigtramp = andes_flush_cache_sigtramp;
+
+	switch (sc_lsize()) {
+		case 64:
+			scache_lsz64 = 1;
+			break;
+		case 128:
+			scache_lsz64 = 0;
+			break;
+		default:
+			printk("Unknown L2 line size\n");
+			while(1);
+	}
+    
+        flush_cache_l1();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-mips32.c linux/arch/mips/mm/c-mips32.c
--- linux.orig/arch/mips/mm/c-mips32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-mips32.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,675 @@
+/*
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS32 CPU variant specific MMU/Cache routines.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/bcache.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+/* Primary cache parameters. */
+int icache_size, dcache_size; 			/* Size in bytes */
+int ic_lsize, dc_lsize;				/* LineSize in bytes */
+
+/* Secondary cache (if present) parameters. */
+unsigned int scache_size, sc_lsize;		/* Again, in bytes */
+
+#include <asm/cacheops.h>
+#include <asm/mips32_cache.h>
+
+#undef DEBUG_CACHE
+
+/*
+ * Dummy cache handling routines for machines without boardcaches
+ */
+static void no_sc_noop(void) {}
+
+static struct bcache_ops no_sc_ops = {
+	(void *)no_sc_noop, (void *)no_sc_noop,
+	(void *)no_sc_noop, (void *)no_sc_noop
+};
+
+struct bcache_ops *bcops = &no_sc_ops;
+
+static inline void mips32_flush_cache_all_sc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache(); blast_scache();
+	__restore_flags(flags);
+}
+
+static inline void mips32_flush_cache_all_pc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache();
+	__restore_flags(flags);
+}
+
+static void
+mips32_flush_cache_range_sc(struct mm_struct *mm,
+			 unsigned long start,
+			 unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			mips32_flush_cache_all_sc();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			__save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache_page(start);
+				start += PAGE_SIZE;
+			}
+			__restore_flags(flags);
+		}
+	}
+}
+
+static void mips32_flush_cache_range_pc(struct mm_struct *mm,
+				     unsigned long start,
+				     unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		__save_and_cli(flags);
+		blast_dcache(); blast_icache();
+		__restore_flags(flags);
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void mips32_flush_cache_mm_sc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips32_flush_cache_all_sc();
+	}
+}
+
+static void mips32_flush_cache_mm_pc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips32_flush_cache_all_pc();
+	}
+}
+
+static void mips32_flush_cache_page_sc(struct vm_area_struct *vma,
+				    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache_page_indexed(page);
+		blast_scache_page_indexed(page);
+	} else
+		blast_scache_page(page);
+out:
+	__restore_flags(flags);
+}
+
+static void mips32_flush_cache_page_pc(struct vm_area_struct *vma,
+				    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since Mips32 caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm == current->active_mm) {
+		blast_dcache_page(page);
+	} else {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache_page_indexed(page);
+	}
+out:
+	__restore_flags(flags);
+}
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ *    addresses all the time in kernel mode we can do a direct
+ *    flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void mips32_flush_page_to_ram_sc(struct page *page)
+{
+	blast_scache_page((unsigned long)page_address(page));
+}
+
+static void mips32_flush_page_to_ram_pc(struct page *page)
+{
+	blast_dcache_page((unsigned long)page_address(page));
+}
+
+static void
+mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
+{
+	/*
+	 * We did an scache flush therefore PI is already clean.
+	 */
+}
+
+static void
+mips32_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+static void
+mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	int address;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1));
+	blast_icache_page_indexed(address);
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ */
+static void
+mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+	bc_wback_inv(addr, size);
+}
+
+static void
+mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips32_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("mips32_dma_cache called - should not happen.");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void mips32_flush_cache_sigtramp(unsigned long addr)
+{
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+}
+
+static void mips32_flush_icache_all(void)
+{
+	if (mips_cpu.cputype == CPU_20KC) {
+		blast_icache();
+	}
+}
+
+/* Detect and size the various caches. */
+static void __init probe_icache(unsigned long config)
+{
+        unsigned long config1;
+	unsigned int lsize;
+
+        if (!(config & (1 << 31))) {
+	        /* 
+		 * Not a MIPS32 complainant CPU. 
+		 * Config 1 register not supported, we assume R4k style.
+		 */
+	        icache_size = 1 << (12 + ((config >> 9) & 7));
+		ic_lsize = 16 << ((config >> 5) & 1);
+		mips_cpu.icache.linesz = ic_lsize;
+		
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
+		mips_cpu.icache.sets = 
+			(icache_size / ic_lsize) / mips_cpu.icache.ways;
+	} else {
+	       config1 = read_mips32_cp0_config1(); 
+
+	       if ((lsize = ((config1 >> 19) & 7)))
+		       mips_cpu.icache.linesz = 2 << lsize;
+	       else 
+		       mips_cpu.icache.linesz = lsize;
+	       mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
+	       mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
+
+	       ic_lsize = mips_cpu.icache.linesz;
+	       icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * 
+		             ic_lsize;
+	}
+	printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
+	       icache_size >> 10, ic_lsize, mips_cpu.icache.ways);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+        unsigned long config1;
+	unsigned int lsize;
+
+        if (!(config & (1 << 31))) {
+	        /* 
+		 * Not a MIPS32 complainant CPU. 
+		 * Config 1 register not supported, we assume R4k style.
+		 */  
+		dcache_size = 1 << (12 + ((config >> 6) & 7));
+		dc_lsize = 16 << ((config >> 4) & 1);
+		mips_cpu.dcache.linesz = dc_lsize;
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
+		mips_cpu.dcache.sets = 
+			(dcache_size / dc_lsize) / mips_cpu.dcache.ways;
+	} else {
+	        config1 = read_mips32_cp0_config1();
+
+		if ((lsize = ((config1 >> 10) & 7)))
+		        mips_cpu.dcache.linesz = 2 << lsize;
+		else 
+		        mips_cpu.dcache.linesz= lsize;
+		mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
+		mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
+
+		dc_lsize = mips_cpu.dcache.linesz;
+		dcache_size = 
+			mips_cpu.dcache.sets * mips_cpu.dcache.ways
+			* dc_lsize;
+	}
+	printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n",
+	       dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways);
+}
+
+
+/* If you even _breathe_ on this function, look at the gcc output
+ * and make sure it does not pop things on and off the stack for
+ * the cache sizing loop that executes in KSEG1 space or else
+ * you will crash and burn badly.  You have been warned.
+ */
+static int __init probe_scache(unsigned long config)
+{
+	extern unsigned long stext;
+	unsigned long flags, addr, begin, end, pow2;
+	int tmp;
+
+	if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT)
+		return 0;
+
+	tmp = ((config >> 17) & 1);
+	if(tmp)
+		return 0;
+	tmp = ((config >> 22) & 3);
+	switch(tmp) {
+	case 0:
+		sc_lsize = 16;
+		break;
+	case 1:
+		sc_lsize = 32;
+		break;
+	case 2:
+		sc_lsize = 64;
+		break;
+	case 3:
+		sc_lsize = 128;
+		break;
+	}
+
+	begin = (unsigned long) &stext;
+	begin &= ~((4 * 1024 * 1024) - 1);
+	end = begin + (4 * 1024 * 1024);
+
+	/* This is such a bitch, you'd think they would make it
+	 * easy to do this.  Away you daemons of stupidity!
+	 */
+	__save_and_cli(flags);
+
+	/* Fill each size-multiple cache line with a valid tag. */
+	pow2 = (64 * 1024);
+	for(addr = begin; addr < end; addr = (begin + pow2)) {
+		unsigned long *p = (unsigned long *) addr;
+		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+		pow2 <<= 1;
+	}
+
+	/* Load first line with zero (therefore invalid) tag. */
+	set_taglo(0);
+	set_taghi(0);
+	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 8, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 9, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 11, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+
+	/* Now search for the wrap around point. */
+	pow2 = (128 * 1024);
+	tmp = 0;
+	for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
+		__asm__ __volatile__("\n\t.set noreorder\n\t"
+				     ".set mips3\n\t"
+				     "cache 7, (%0)\n\t"
+				     ".set mips0\n\t"
+				     ".set reorder\n\t" : : "r" (addr));
+		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+		if(!get_taglo())
+			break;
+		pow2 <<= 1;
+	}
+	__restore_flags(flags);
+	addr -= begin;
+	printk("Secondary cache sized at %dK linesize %d bytes.\n",
+	       (int) (addr >> 10), sc_lsize);
+	scache_size = addr;
+	return 1;
+}
+
+static void __init setup_noscache_funcs(void)
+{
+	_clear_page = (void *)mips32_clear_page_dc;
+	_copy_page = (void *)mips32_copy_page_dc;
+	_flush_cache_all = mips32_flush_cache_all_pc;
+	___flush_cache_all = mips32_flush_cache_all_pc;
+	_flush_cache_mm = mips32_flush_cache_mm_pc;
+	_flush_cache_range = mips32_flush_cache_range_pc;
+	_flush_cache_page = mips32_flush_cache_page_pc;
+	_flush_page_to_ram = mips32_flush_page_to_ram_pc;
+
+	_flush_icache_page = mips32_flush_icache_page;
+
+	_dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc;
+	_dma_cache_wback = mips32_dma_cache_wback;
+	_dma_cache_inv = mips32_dma_cache_inv_pc;
+}
+
+static void __init setup_scache_funcs(void)
+{
+        _flush_cache_all = mips32_flush_cache_all_sc;
+        ___flush_cache_all = mips32_flush_cache_all_sc;
+	_flush_cache_mm = mips32_flush_cache_mm_sc;
+	_flush_cache_range = mips32_flush_cache_range_sc;
+	_flush_cache_page = mips32_flush_cache_page_sc;
+	_flush_page_to_ram = mips32_flush_page_to_ram_sc;
+	_clear_page = (void *)mips32_clear_page_sc;
+	_copy_page = (void *)mips32_copy_page_sc;
+
+	_flush_icache_page = mips32_flush_icache_page_s;
+
+	_dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc;
+	_dma_cache_wback = mips32_dma_cache_wback;
+	_dma_cache_inv = mips32_dma_cache_inv_sc;
+}
+
+typedef int (*probe_func_t)(unsigned long);
+
+static inline void __init setup_scache(unsigned int config)
+{
+	probe_func_t probe_scache_kseg1;
+	int sc_present = 0;
+
+	/* Maybe the cpu knows about a l2 cache? */
+	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
+	sc_present = probe_scache_kseg1(config);
+
+	if (sc_present) {
+	  	mips_cpu.scache.linesz = sc_lsize;
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1;
+		mips_cpu.scache.sets = 
+		  (scache_size / sc_lsize) / mips_cpu.scache.ways;
+
+		setup_scache_funcs();
+		return;
+	}
+
+	setup_noscache_funcs();
+}
+
+void __init ld_mmu_mips32(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+#ifdef CONFIG_MIPS_UNCACHED
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+#else
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif
+
+	probe_icache(config);
+	probe_dcache(config);
+	setup_scache(config);
+
+	_flush_cache_sigtramp = mips32_flush_cache_sigtramp;
+	_flush_icache_range = mips32_flush_icache_range;	/* Ouch */
+	_flush_icache_all = mips32_flush_icache_all;
+
+	__flush_cache_all();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-r3k.c linux/arch/mips/mm/c-r3k.c
--- linux.orig/arch/mips/mm/c-r3k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-r3k.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,347 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/wbflush.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+static unsigned long icache_size, dcache_size;		/* Size in bytes */
+static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
+
+#undef DEBUG_CACHE
+
+unsigned long __init r3k_cache_size(unsigned long ca_flags)
+{
+	unsigned long flags, status, dummy, size;
+	volatile unsigned long *p;
+
+	p = (volatile unsigned long *) KSEG0;
+
+	flags = read_32bit_cp0_register(CP0_STATUS);
+
+	/* isolate cache space */
+	write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC);
+
+	*p = 0xa5a55a5a;
+	dummy = *p;
+	status = read_32bit_cp0_register(CP0_STATUS);
+
+	if (dummy != 0xa5a55a5a || (status & ST0_CM)) {
+		size = 0;
+	} else {
+		for (size = 128; size <= 0x40000; size <<= 1)
+			*(p + size) = 0;
+		*p = -1;
+		for (size = 128; 
+		     (size <= 0x40000) && (*(p + size) == 0); 
+		     size <<= 1)
+			;
+		if (size > 0x40000)
+			size = 0;
+	}
+
+	write_32bit_cp0_register(CP0_STATUS, flags);
+
+	return size * sizeof(*p);
+}
+
+unsigned long __init r3k_cache_lsize(unsigned long ca_flags)
+{
+	unsigned long flags, status, lsize, i;
+	volatile unsigned long *p;
+
+	p = (volatile unsigned long *) KSEG0;
+
+	flags = read_32bit_cp0_register(CP0_STATUS);
+
+	/* isolate cache space */
+	write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC);
+
+	for (i = 0; i < 128; i++)
+		*(p + i) = 0;
+	*(volatile unsigned char *)p = 0;
+	for (lsize = 1; lsize < 128; lsize <<= 1) {
+		*(p + lsize);
+		status = read_32bit_cp0_register(CP0_STATUS);
+		if (!(status & ST0_CM))
+			break;
+	}
+	for (i = 0; i < 128; i += lsize)
+		*(volatile unsigned char *)(p + i) = 0;
+
+	write_32bit_cp0_register(CP0_STATUS, flags);
+
+	return lsize * sizeof(*p);
+}
+
+static void __init r3k_probe_cache(void)
+{
+	dcache_size = r3k_cache_size(ST0_ISC);
+	if (dcache_size)
+		dcache_lsize = r3k_cache_lsize(ST0_ISC);
+	
+
+	icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
+	if (icache_size)
+		icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC);
+}
+
+static void r3k_flush_icache_range(unsigned long start, unsigned long end)
+{
+	unsigned long size, i, flags;
+	volatile unsigned char *p;
+
+	size = end - start;
+	if (size > icache_size || KSEGX(start) != KSEG0) {
+		start = KSEG0;
+		size = icache_size;
+	}
+	p = (char *)start;
+
+	flags = read_32bit_cp0_register(CP0_STATUS);
+
+	/* isolate cache space */
+	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
+
+	for (i = 0; i < size; i += 0x080) {
+		asm ( 	"sb\t$0, 0x000(%0)\n\t"
+			"sb\t$0, 0x004(%0)\n\t"
+			"sb\t$0, 0x008(%0)\n\t"
+			"sb\t$0, 0x00c(%0)\n\t"
+			"sb\t$0, 0x010(%0)\n\t"
+			"sb\t$0, 0x014(%0)\n\t"
+			"sb\t$0, 0x018(%0)\n\t"
+			"sb\t$0, 0x01c(%0)\n\t"
+		 	"sb\t$0, 0x020(%0)\n\t"
+			"sb\t$0, 0x024(%0)\n\t"
+			"sb\t$0, 0x028(%0)\n\t"
+			"sb\t$0, 0x02c(%0)\n\t"
+			"sb\t$0, 0x030(%0)\n\t"
+			"sb\t$0, 0x034(%0)\n\t"
+			"sb\t$0, 0x038(%0)\n\t"
+			"sb\t$0, 0x03c(%0)\n\t"
+			"sb\t$0, 0x040(%0)\n\t"
+			"sb\t$0, 0x044(%0)\n\t"
+			"sb\t$0, 0x048(%0)\n\t"
+			"sb\t$0, 0x04c(%0)\n\t"
+			"sb\t$0, 0x050(%0)\n\t"
+			"sb\t$0, 0x054(%0)\n\t"
+			"sb\t$0, 0x058(%0)\n\t"
+			"sb\t$0, 0x05c(%0)\n\t"
+		 	"sb\t$0, 0x060(%0)\n\t"
+			"sb\t$0, 0x064(%0)\n\t"
+			"sb\t$0, 0x068(%0)\n\t"
+			"sb\t$0, 0x06c(%0)\n\t"
+			"sb\t$0, 0x070(%0)\n\t"
+			"sb\t$0, 0x074(%0)\n\t"
+			"sb\t$0, 0x078(%0)\n\t"
+			"sb\t$0, 0x07c(%0)\n\t"
+			: : "r" (p) );
+		p += 0x080;
+	}
+
+	write_32bit_cp0_register(CP0_STATUS, flags);
+}
+
+static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
+{
+	unsigned long size, i, flags;
+	volatile unsigned char *p;
+
+	size = end - start;
+	if (size > dcache_size || KSEGX(start) != KSEG0) {
+		start = KSEG0;
+		size = dcache_size;
+	}
+	p = (char *)start;
+
+	flags = read_32bit_cp0_register(CP0_STATUS);
+
+	/* isolate cache space */
+	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|flags)&~ST0_IEC);
+
+	for (i = 0; i < size; i += 0x080) {
+		asm ( 	"sb\t$0, 0x000(%0)\n\t"
+			"sb\t$0, 0x004(%0)\n\t"
+			"sb\t$0, 0x008(%0)\n\t"
+			"sb\t$0, 0x00c(%0)\n\t"
+		 	"sb\t$0, 0x010(%0)\n\t"
+			"sb\t$0, 0x014(%0)\n\t"
+			"sb\t$0, 0x018(%0)\n\t"
+			"sb\t$0, 0x01c(%0)\n\t"
+		 	"sb\t$0, 0x020(%0)\n\t"
+			"sb\t$0, 0x024(%0)\n\t"
+			"sb\t$0, 0x028(%0)\n\t"
+			"sb\t$0, 0x02c(%0)\n\t"
+		 	"sb\t$0, 0x030(%0)\n\t"
+			"sb\t$0, 0x034(%0)\n\t"
+			"sb\t$0, 0x038(%0)\n\t"
+			"sb\t$0, 0x03c(%0)\n\t"
+		 	"sb\t$0, 0x040(%0)\n\t"
+			"sb\t$0, 0x044(%0)\n\t"
+			"sb\t$0, 0x048(%0)\n\t"
+			"sb\t$0, 0x04c(%0)\n\t"
+		 	"sb\t$0, 0x050(%0)\n\t"
+			"sb\t$0, 0x054(%0)\n\t"
+			"sb\t$0, 0x058(%0)\n\t"
+			"sb\t$0, 0x05c(%0)\n\t"
+		 	"sb\t$0, 0x060(%0)\n\t"
+			"sb\t$0, 0x064(%0)\n\t"
+			"sb\t$0, 0x068(%0)\n\t"
+			"sb\t$0, 0x06c(%0)\n\t"
+		 	"sb\t$0, 0x070(%0)\n\t"
+			"sb\t$0, 0x074(%0)\n\t"
+			"sb\t$0, 0x078(%0)\n\t"
+			"sb\t$0, 0x07c(%0)\n\t"
+			: : "r" (p) );
+		p += 0x080;
+	}
+
+	write_32bit_cp0_register(CP0_STATUS,flags);
+}
+
+static inline unsigned long get_phys_page (unsigned long addr,
+					   struct mm_struct *mm)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	unsigned long physpage;
+
+	pgd = pgd_offset(mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+
+	if ((physpage = pte_val(*pte)) & _PAGE_VALID)
+		return KSEG0ADDR(physpage & PAGE_MASK);
+
+	return 0;
+}
+
+static inline void r3k_flush_cache_all(void)
+{
+}
+ 
+static inline void r3k___flush_cache_all(void)
+{
+	r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
+}
+
+static void r3k_flush_cache_mm(struct mm_struct *mm)
+{
+}
+
+static void r3k_flush_cache_range(struct mm_struct *mm, unsigned long start,
+				  unsigned long end)
+{
+}
+
+static void r3k_flush_cache_page(struct vm_area_struct *vma,
+				   unsigned long page)
+{
+}
+
+static void r3k_flush_page_to_ram(struct page * page)
+{
+	/*
+	 * Nothing to be done
+	 */
+}
+
+static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long physpage;
+
+	if (mm->context == 0)
+		return;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+
+	physpage = (unsigned long) page_address(page);
+	if (physpage)
+		r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
+}
+
+static void r3k_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long flags;
+
+#ifdef DEBUG_CACHE
+	printk("csigtramp[%08lx]", addr);
+#endif
+
+	flags = read_32bit_cp0_register(CP0_STATUS);
+
+	write_32bit_cp0_register(CP0_STATUS, flags&~ST0_IEC);
+
+	/* Fill the TLB to avoid an exception with caches isolated. */
+	asm ( 	"lw\t$0, 0x000(%0)\n\t"
+		"lw\t$0, 0x004(%0)\n\t"
+		: : "r" (addr) );
+
+	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
+
+	asm ( 	"sb\t$0, 0x000(%0)\n\t"
+		"sb\t$0, 0x004(%0)\n\t"
+		: : "r" (addr) );
+
+	write_32bit_cp0_register(CP0_STATUS, flags);
+}
+
+static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
+{
+	wbflush();
+	r3k_flush_dcache_range(start, start + size);
+}
+
+void __init ld_mmu_r23000(void)
+{
+	unsigned long config;
+
+	_clear_page = r3k_clear_page;
+	_copy_page = r3k_copy_page;
+
+	r3k_probe_cache();
+
+	_flush_cache_all = r3k_flush_cache_all;
+	___flush_cache_all = r3k___flush_cache_all;
+	_flush_cache_mm = r3k_flush_cache_mm;
+	_flush_cache_range = r3k_flush_cache_range;
+	_flush_cache_page = r3k_flush_cache_page;
+	_flush_cache_sigtramp = r3k_flush_cache_sigtramp;
+	_flush_page_to_ram = r3k_flush_page_to_ram;
+	_flush_icache_page = r3k_flush_icache_page;
+	_flush_icache_range = r3k_flush_icache_range;
+
+	_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+
+	printk("Primary instruction cache %dkb, linesize %d bytes\n",
+		(int) (icache_size >> 10), (int) icache_lsize);
+	printk("Primary data cache %dkb, linesize %d bytes\n",
+		(int) (dcache_size >> 10), (int) dcache_lsize);
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-r4k.c linux/arch/mips/mm/c-r4k.c
--- linux.orig/arch/mips/mm/c-r4k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-r4k.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,1496 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
+ *
+ * To do:
+ *
+ *  - this code is a overbloated pig
+ *  - many of the bug workarounds are not efficient at all, but at
+ *    least they are functional ...
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/bcache.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/war.h>
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+static int ic_lsize, dc_lsize;       /* LineSize in bytes */
+
+/* Secondary cache (if present) parameters. */
+static unsigned int scache_size, sc_lsize;	/* Again, in bytes */
+
+#include <asm/cacheops.h>
+#include <asm/r4kcache.h>
+
+#undef DEBUG_CACHE
+
+/*
+ * Dummy cache handling routines for machines without boardcaches
+ */
+static void no_sc_noop(void) {}
+
+static struct bcache_ops no_sc_ops = {
+	(void *)no_sc_noop, (void *)no_sc_noop,
+	(void *)no_sc_noop, (void *)no_sc_noop
+};
+
+struct bcache_ops *bcops = &no_sc_ops;
+
+/*
+ * On processors with QED R4600 style two set assosicative cache
+ * this is the bit which selects the way in the cache for the
+ * indexed cachops.
+ */
+#define icache_waybit (icache_size >> 1)
+#define dcache_waybit (dcache_size >> 1)
+
+/*
+ * If you think for one second that this stuff coming up is a lot
+ * of bulky code eating too many kernel cache lines.  Think _again_.
+ *
+ * Consider:
+ * 1) Taken branches have a 3 cycle penalty on R4k
+ * 2) The branch itself is a real dead cycle on even R4600/R5000.
+ * 3) Only one of the following variants of each type is even used by
+ *    the kernel based upon the cache parameters we detect at boot time.
+ *
+ * QED.
+ */
+
+static inline void r4k_flush_cache_all_s16d16i16(void)
+{
+	blast_dcache16(); blast_icache16(); blast_scache16();
+}
+
+static inline void r4k_flush_cache_all_s32d16i16(void)
+{
+	blast_dcache16(); blast_icache16(); blast_scache32();
+}
+
+static inline void r4k_flush_cache_all_s64d16i16(void)
+{
+	blast_dcache16(); blast_icache16(); blast_scache64();
+}
+
+static inline void r4k_flush_cache_all_s128d16i16(void)
+{
+	blast_dcache16(); blast_icache16(); blast_scache128();
+}
+
+static inline void r4k_flush_cache_all_s32d32i32(void)
+{
+	blast_dcache32(); blast_icache32(); blast_scache32();
+}
+
+static inline void r4k_flush_cache_all_s64d32i32(void)
+{
+	blast_dcache32(); blast_icache32(); blast_scache64();
+}
+
+static inline void r4k_flush_cache_all_s128d32i32(void)
+{
+	blast_dcache32(); blast_icache32(); blast_scache128();
+}
+
+static inline void r4k_flush_cache_all_d16i16(void)
+{
+	blast_dcache16(); blast_icache16();
+}
+
+static inline void r4k_flush_cache_all_d32i32(void)
+{
+	blast_dcache32(); blast_icache32();
+}
+
+static void
+r4k_flush_cache_range_s16d16i16(struct mm_struct *mm,
+                                unsigned long start,
+                                unsigned long end)
+{
+	struct vm_area_struct *vma;
+
+	if (mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if (vma) {
+		if (mm->context != current->active_mm->context) {
+			r4k_flush_cache_all_s16d16i16();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			while (start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache16_page(start);
+				start += PAGE_SIZE;
+			}
+		}
+	}
+}
+
+static void
+r4k_flush_cache_range_s32d16i16(struct mm_struct *mm,
+                                unsigned long start,
+                                unsigned long end)
+{
+	struct vm_area_struct *vma;
+
+	if (mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if (vma) {
+		if (mm->context != current->active_mm->context) {
+			r4k_flush_cache_all_s32d16i16();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache32_page(start);
+				start += PAGE_SIZE;
+			}
+		}
+	}
+}
+
+static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm,
+					    unsigned long start,
+					    unsigned long end)
+{
+	struct vm_area_struct *vma;
+
+	if (mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if (mm->context != current->active_mm->context) {
+			r4k_flush_cache_all_s64d16i16();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache64_page(start);
+				start += PAGE_SIZE;
+			}
+		}
+	}
+}
+
+static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm,
+					     unsigned long start,
+					     unsigned long end)
+{
+	struct vm_area_struct *vma;
+
+	if (mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if (vma) {
+		if (mm->context != current->active_mm->context) {
+			r4k_flush_cache_all_s128d16i16();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache128_page(start);
+				start += PAGE_SIZE;
+			}
+		}
+	}
+}
+
+static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm,
+					    unsigned long start,
+					    unsigned long end)
+{
+	struct vm_area_struct *vma;
+
+	if (mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if (vma) {
+		if (mm->context != current->active_mm->context) {
+			r4k_flush_cache_all_s32d32i32();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache32_page(start);
+				start += PAGE_SIZE;
+			}
+		}
+	}
+}
+
+static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm,
+					    unsigned long start,
+					    unsigned long end)
+{
+	struct vm_area_struct *vma;
+
+	if (mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if (vma) {
+		if (mm->context != current->active_mm->context) {
+			r4k_flush_cache_all_s64d32i32();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache64_page(start);
+				start += PAGE_SIZE;
+			}
+		}
+	}
+}
+
+static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm,
+					     unsigned long start,
+					     unsigned long end)
+{
+	struct vm_area_struct *vma;
+
+	if (mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if (vma) {
+		if (mm->context != current->active_mm->context) {
+			r4k_flush_cache_all_s128d32i32();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache128_page(start);
+				start += PAGE_SIZE;
+			}
+		}
+	}
+}
+
+static void r4k_flush_cache_range_d16i16(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		blast_dcache16(); blast_icache16();
+	}
+}
+
+static void r4k_flush_cache_range_d32i32(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		blast_dcache32(); blast_icache32();
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s16d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s32d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s64d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s128d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s32d32i32();
+	}
+}
+
+static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s64d32i32();
+	}
+}
+
+static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_s128d32i32();
+	}
+}
+
+static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_d16i16();
+	}
+}
+
+static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r4k_flush_cache_all_d32i32();
+	}
+}
+
+static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma,
+					   unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		blast_scache16_page_indexed(page);
+	} else
+		blast_scache16_page(page);
+out:
+}
+
+static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
+					   unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/* If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		blast_scache32_page_indexed(page);
+	} else
+		blast_scache32_page(page);
+out:
+}
+
+static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
+					   unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/* If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		blast_scache64_page_indexed(page);
+	} else
+		blast_scache64_page(page);
+out:
+}
+
+static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
+					    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache16_page_indexed(page);
+		blast_scache128_page_indexed(page);
+	} else
+		blast_scache128_page(page);
+out:
+}
+
+static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
+					   unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		blast_scache32_page_indexed(page);
+	} else
+		blast_scache32_page(page);
+out:
+}
+
+static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
+					   unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		blast_scache64_page_indexed(page);
+	} else
+		blast_scache64_page(page);
+out:
+}
+
+static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
+					    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		blast_scache128_page_indexed(page);
+	} else
+		blast_scache128_page(page);
+out:
+}
+
+static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
+					unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm == current->active_mm) {
+		blast_dcache16_page(page);
+	} else {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache16_page_indexed(page);
+	}
+out:
+}
+
+static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
+					unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache32_page(page);
+	} else {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache32_page_indexed(page);
+	}
+out:
+}
+
+static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
+					      unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache32_page(page);
+	} else {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache32_page_indexed(page);
+		blast_dcache32_page_indexed(page ^ dcache_waybit);
+	}
+out:
+}
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ *    addresses all the time in kernel mode we can do a direct
+ *    flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void r4k_flush_page_to_ram_s16(struct page *page)
+{
+	blast_scache16_page((unsigned long)page_address(page));
+}
+
+static void r4k_flush_page_to_ram_s32(struct page *page)
+{
+	blast_scache32_page((unsigned long)page_address(page));
+}
+
+static void r4k_flush_page_to_ram_s64(struct page *page)
+{
+	blast_scache64_page((unsigned long)page_address(page));
+}
+
+static void r4k_flush_page_to_ram_s128(struct page *page)
+{
+	blast_scache128_page((unsigned long)page_address(page));
+}
+
+static void r4k_flush_page_to_ram_d16(struct page *page)
+{
+	blast_dcache16_page((unsigned long)page_address(page));
+}
+
+static void r4k_flush_page_to_ram_d32(struct page *page)
+{
+	blast_dcache32_page((unsigned long)page_address(page));
+}
+
+static void r4k_flush_page_to_ram_d32_r4600(struct page *page)
+{
+#ifdef R4600_V1_HIT_DCACHE_WAR
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	__asm__ __volatile__("nop;nop;nop;nop");
+#endif
+	blast_dcache32_page((unsigned long)page_address(page));
+#ifdef R4600_V1_HIT_DCACHE_WAR
+	__restore_flags(flags);
+#endif
+}
+
+static void
+r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
+{
+	/*
+	 * We did an scache flush therefore PI is already clean.
+	 */
+}
+
+static void
+r4k_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+/*
+ * Ok, this seriously sucks.  We use them to flush a user page but don't
+ * know the virtual address, so we have to blast away the whole icache
+ * which is significantly more expensive than the real thing.
+ */
+static void
+r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	flush_cache_all();
+}
+
+static void
+r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+#ifdef R4600_V2_HIT_CACHEOP_WAR
+		/* Workaround for R4600 bug.  See comment in <asm/war>. */
+		__save_and_cli(flags);
+		*(volatile unsigned long *)KSEG1;
+#endif
+
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+#ifdef R4600_V2_HIT_CACHEOP_WAR
+		__restore_flags(flags);
+#endif
+	}
+	bc_wback_inv(addr, size);
+}
+
+static void
+r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+#ifdef R4600_V2_HIT_CACHEOP_WAR
+		/* Workaround for R4600 bug.  See comment above. */
+		__save_and_cli(flags);
+		*(volatile unsigned long *)KSEG1;
+#endif
+
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+#ifdef R4600_V2_HIT_CACHEOP_WAR
+		__restore_flags(flags);
+#endif
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+r4k_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("r4k_dma_cache called - should not happen.");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void r4k_flush_cache_sigtramp(unsigned long addr)
+{
+#ifdef R4600_V1_HIT_DCACHE_WAR
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	__asm__ __volatile__("nop;nop;nop;nop");
+#endif
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+#ifdef R4600_V1_HIT_DCACHE_WAR
+	__restore_flags(flags);
+#endif
+}
+
+static void r4600v20k_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned int flags;
+
+#ifdef R4600_V2_HIT_CACHEOP_WAR
+	__save_and_cli(flags);
+
+	/* Clear internal cache refill buffer */
+	*(volatile unsigned int *)KSEG1;
+#endif
+
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+
+#ifdef R4600_V2_HIT_CACHEOP_WAR
+	__restore_flags(flags);
+#endif
+}
+
+/* Detect and size the various r4k caches. */
+static void __init probe_icache(unsigned long config)
+{
+        switch (mips_cpu.cputype) {
+        case CPU_VR41XX:
+                icache_size = 1 << (10 + ((config >> 9) & 7));
+                break;
+        default:
+                icache_size = 1 << (12 + ((config >> 9) & 7));
+                break;
+        }
+	ic_lsize = 16 << ((config >> 5) & 1);
+
+	printk("Primary instruction cache %dkb, linesize %d bytes.\n",
+	       icache_size >> 10, ic_lsize);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+        switch (mips_cpu.cputype) {
+        case CPU_VR41XX:
+                dcache_size = 1 << (10 + ((config >> 6) & 7));
+                break;
+        default:
+                dcache_size = 1 << (12 + ((config >> 6) & 7));
+                break;
+        }
+	dc_lsize = 16 << ((config >> 4) & 1);
+
+	printk("Primary data cache %dkb, linesize %d bytes.\n",
+	       dcache_size >> 10, dc_lsize);
+}
+
+
+/* If you even _breathe_ on this function, look at the gcc output
+ * and make sure it does not pop things on and off the stack for
+ * the cache sizing loop that executes in KSEG1 space or else
+ * you will crash and burn badly.  You have been warned.
+ */
+static int __init probe_scache(unsigned long config)
+{
+	extern unsigned long stext;
+	unsigned long flags, addr, begin, end, pow2;
+	int tmp;
+
+	tmp = ((config >> 17) & 1);
+	if(tmp)
+		return 0;
+	tmp = ((config >> 22) & 3);
+	switch(tmp) {
+	case 0:
+		sc_lsize = 16;
+		break;
+	case 1:
+		sc_lsize = 32;
+		break;
+	case 2:
+		sc_lsize = 64;
+		break;
+	case 3:
+		sc_lsize = 128;
+		break;
+	}
+
+	begin = (unsigned long) &stext;
+	begin &= ~((4 * 1024 * 1024) - 1);
+	end = begin + (4 * 1024 * 1024);
+
+	/* This is such a bitch, you'd think they would make it
+	 * easy to do this.  Away you daemons of stupidity!
+	 */
+	__save_and_cli(flags);
+
+	/* Fill each size-multiple cache line with a valid tag. */
+	pow2 = (64 * 1024);
+	for(addr = begin; addr < end; addr = (begin + pow2)) {
+		unsigned long *p = (unsigned long *) addr;
+		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+		pow2 <<= 1;
+	}
+
+	/* Load first line with zero (therefore invalid) tag. */
+	set_taglo(0);
+	set_taghi(0);
+	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 8, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 9, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 11, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+
+	/* Now search for the wrap around point. */
+	pow2 = (128 * 1024);
+	tmp = 0;
+	for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
+		__asm__ __volatile__("\n\t.set noreorder\n\t"
+				     ".set mips3\n\t"
+				     "cache 7, (%0)\n\t"
+				     ".set mips0\n\t"
+				     ".set reorder\n\t" : : "r" (addr));
+		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+		if(!get_taglo())
+			break;
+		pow2 <<= 1;
+	}
+	__restore_flags(flags);
+	addr -= begin;
+	printk("Secondary cache sized at %dK linesize %d bytes.\n",
+	       (int) (addr >> 10), sc_lsize);
+	scache_size = addr;
+	return 1;
+}
+
+static void __init setup_noscache_funcs(void)
+{
+	unsigned int prid;
+
+	switch(dc_lsize) {
+	case 16:
+		_clear_page = r4k_clear_page_d16;
+		_copy_page = r4k_copy_page_d16;
+		_flush_cache_all = r4k_flush_cache_all_d16i16;
+		_flush_cache_mm = r4k_flush_cache_mm_d16i16;
+		_flush_cache_range = r4k_flush_cache_range_d16i16;
+		_flush_cache_page = r4k_flush_cache_page_d16i16;
+		_flush_page_to_ram = r4k_flush_page_to_ram_d16;
+		break;
+	case 32:
+		prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0;
+		if (prid == 0x2010) {			/* R4600 V1.7 */
+			_clear_page = r4k_clear_page_r4600_v1;
+			_copy_page = r4k_copy_page_r4600_v1;
+			_flush_page_to_ram = r4k_flush_page_to_ram_d32_r4600;
+		} else if (prid == 0x2020) {		/* R4600 V2.0 */
+			_clear_page = r4k_clear_page_r4600_v2;
+			_copy_page = r4k_copy_page_r4600_v2;
+			_flush_page_to_ram = r4k_flush_page_to_ram_d32;
+		} else {
+			_clear_page = r4k_clear_page_d32;
+			_copy_page = r4k_copy_page_d32;
+			_flush_page_to_ram = r4k_flush_page_to_ram_d32;
+		}
+		_flush_cache_all = r4k_flush_cache_all_d32i32;
+		_flush_cache_mm = r4k_flush_cache_mm_d32i32;
+		_flush_cache_range = r4k_flush_cache_range_d32i32;
+		_flush_cache_page = r4k_flush_cache_page_d32i32;
+		break;
+	}
+	___flush_cache_all = _flush_cache_all;
+
+	_flush_icache_page = r4k_flush_icache_page_p;
+
+	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
+	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_inv = r4k_dma_cache_inv_pc;
+}
+
+static void __init setup_scache_funcs(void)
+{
+	switch(sc_lsize) {
+	case 16:
+		switch(dc_lsize) {
+		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s16d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s16d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s16d16i16;
+			break;
+		case 32:
+			panic("Invalid cache configuration detected");
+		};
+		_flush_page_to_ram = r4k_flush_page_to_ram_s16;
+		_clear_page = r4k_clear_page_s16;
+		_copy_page = r4k_copy_page_s16;
+		break;
+	case 32:
+		switch(dc_lsize) {
+		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s32d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s32d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s32d16i16;
+			break;
+		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s32d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s32d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s32d32i32;
+			break;
+		};
+		_flush_page_to_ram = r4k_flush_page_to_ram_s32;
+		_clear_page = r4k_clear_page_s32;
+		_copy_page = r4k_copy_page_s32;
+		break;
+	case 64:
+		switch(dc_lsize) {
+		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s64d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s64d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s64d16i16;
+			break;
+		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s64d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s64d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s64d32i32;
+			break;
+		};
+		_flush_page_to_ram = r4k_flush_page_to_ram_s64;
+		_clear_page = r4k_clear_page_s64;
+		_copy_page = r4k_copy_page_s64;
+		break;
+	case 128:
+		switch(dc_lsize) {
+		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s128d16i16;
+			_flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
+			_flush_cache_range = r4k_flush_cache_range_s128d16i16;
+			_flush_cache_page = r4k_flush_cache_page_s128d16i16;
+			break;
+		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s128d32i32;
+			_flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
+			_flush_cache_range = r4k_flush_cache_range_s128d32i32;
+			_flush_cache_page = r4k_flush_cache_page_s128d32i32;
+			break;
+		};
+		_flush_page_to_ram = r4k_flush_page_to_ram_s128;
+		_clear_page = r4k_clear_page_s128;
+		_copy_page = r4k_copy_page_s128;
+		break;
+	}
+	___flush_cache_all = _flush_cache_all;
+	_flush_icache_page = r4k_flush_icache_page_s;
+	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
+	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_inv = r4k_dma_cache_inv_sc;
+}
+
+typedef int (*probe_func_t)(unsigned long);
+
+static inline void __init setup_scache(unsigned int config)
+{
+	probe_func_t probe_scache_kseg1;
+	int sc_present = 0;
+
+	/* Maybe the cpu knows about a l2 cache? */
+	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
+	sc_present = probe_scache_kseg1(config);
+
+	if (sc_present) {
+		setup_scache_funcs();
+		return;
+	}
+
+	setup_noscache_funcs();
+}
+
+void __init ld_mmu_r4xx0(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+#ifdef CONFIG_MIPS_UNCACHED
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+#else
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif
+
+	probe_icache(config);
+	probe_dcache(config);
+	setup_scache(config);
+
+	switch(mips_cpu.cputype) {
+	case CPU_R4600:			/* QED style two way caches? */
+	case CPU_R4700:
+	case CPU_R5000:
+	case CPU_NEVADA:
+		_flush_cache_page = r4k_flush_cache_page_d32i32_r4600;
+	}
+
+	_flush_cache_sigtramp = r4k_flush_cache_sigtramp;
+	_flush_icache_range = r4k_flush_icache_range;	/* Ouch */
+	if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) {
+		_flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
+	}
+
+	__flush_cache_all();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-r5432.c linux/arch/mips/mm/c-r5432.c
--- linux.orig/arch/mips/mm/c-r5432.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-r5432.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,480 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r5432.c: NEC Vr5432 processor.  We cannot use r4xx0.c because of
+ *      its unique way-selection method for indexed operations.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000 Jun Sun (jsun@mvista.com)
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bcache.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+#include <asm/asm.h>
+#include <asm/cacheops.h>
+
+#undef DEBUG_CACHE
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+static int ic_lsize, dc_lsize;       /* LineSize in bytes */
+
+
+/* -------------------------------------------------------------------- */
+/* #include <asm/r4kcache.h> */
+
+static inline void flush_icache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		"cache %1, 1(%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Index_Invalidate_I));
+}
+
+static inline void flush_dcache_line_indexed(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		"cache %1, 1(%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Index_Writeback_Inv_D));
+}
+
+static inline void flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_I));
+}
+
+static inline void flush_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Writeback_Inv_D));
+}
+
+static inline void invalidate_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n\t"
+		"cache %1, (%0)\n\t"
+		".set mips0\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_D));
+}
+
+
+/*
+ * The next two are for badland addresses like signal trampolines.
+ */
+static inline void protected_flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set mips0\n\t"
+		".set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		STR(PTR)"\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_I));
+}
+
+static inline void protected_writeback_dcache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set mips0\n\t"
+		".set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		STR(PTR)"\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr),
+		  "i" (Hit_Writeback_D));
+}
+
+
+#define cache32_unroll32(base,op)				\
+	__asm__ __volatile__("					\
+		.set noreorder;					\
+		.set mips3;					\
+		cache %1, 0x000(%0); cache %1, 0x020(%0);	\
+		cache %1, 0x040(%0); cache %1, 0x060(%0);	\
+		cache %1, 0x080(%0); cache %1, 0x0a0(%0);	\
+		cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);	\
+		cache %1, 0x100(%0); cache %1, 0x120(%0);	\
+		cache %1, 0x140(%0); cache %1, 0x160(%0);	\
+		cache %1, 0x180(%0); cache %1, 0x1a0(%0);	\
+		cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);	\
+		cache %1, 0x200(%0); cache %1, 0x220(%0);	\
+		cache %1, 0x240(%0); cache %1, 0x260(%0);	\
+		cache %1, 0x280(%0); cache %1, 0x2a0(%0);	\
+		cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);	\
+		cache %1, 0x300(%0); cache %1, 0x320(%0);	\
+		cache %1, 0x340(%0); cache %1, 0x360(%0);	\
+		cache %1, 0x380(%0); cache %1, 0x3a0(%0);	\
+		cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);	\
+		.set mips0;					\
+		.set reorder"					\
+		:						\
+		: "r" (base),					\
+		  "i" (op));
+
+static inline void blast_dcache32(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + dcache_size/2);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Writeback_Inv_D);
+		cache32_unroll32(start+1,Index_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+static inline void blast_dcache32_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Hit_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+static inline void blast_dcache32_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Writeback_Inv_D);
+		cache32_unroll32(start+1,Index_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+static inline void blast_icache32(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size/2);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Invalidate_I);
+		cache32_unroll32(start+1,Index_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+static inline void blast_icache32_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Hit_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+static inline void blast_icache32_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache32_unroll32(start,Index_Invalidate_I);
+		cache32_unroll32(start+1,Index_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * If you think for one second that this stuff coming up is a lot
+ * of bulky code eating too many kernel cache lines.  Think _again_.
+ *
+ * Consider:
+ * 1) Taken branches have a 3 cycle penalty on R4k
+ * 2) The branch itself is a real dead cycle on even R4600/R5000.
+ * 3) Only one of the following variants of each type is even used by
+ *    the kernel based upon the cache parameters we detect at boot time.
+ *
+ * QED.
+ */
+
+static inline void r5432_flush_cache_all_d32i32(void)
+{
+	blast_dcache32(); blast_icache32();
+}
+
+static void r5432_flush_cache_range_d32i32(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		blast_dcache32(); blast_icache32();
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void r5432_flush_cache_mm_d32i32(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r5432_flush_cache_all_d32i32();
+	}
+}
+
+static void r5432_flush_cache_page_d32i32(struct vm_area_struct *vma,
+					unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		return;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache32_page(page);
+	} else {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache32_page_indexed(page);
+	}
+}
+
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ *    addresses all the time in kernel mode we can do a direct
+ *    flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void r5432_flush_page_to_ram_d32(struct page *page)
+{
+	blast_dcache32_page((unsigned long)page_address(page));
+}
+
+static void 
+r5432_flush_icache_range(unsigned long start, unsigned long end)
+{
+	r5432_flush_cache_all_d32i32();
+}
+
+/*
+ * Ok, this seriously sucks.  We use them to flush a user page but don't
+ * know the virtual address, so we have to blast away the whole icache
+ * which is significantly more expensive than the real thing.
+ */
+static void
+r5432_flush_icache_page_i32(struct vm_area_struct *vma, struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	r5432_flush_cache_all_d32i32();
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ */
+static void
+r5432_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+	}
+	bc_wback_inv(addr, size);
+}
+
+static void
+r5432_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+r5432_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("r5432_dma_cache called - should not happen.");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void r5432_flush_cache_sigtramp(unsigned long addr)
+{
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+}
+
+/* Detect and size the various r4k caches. */
+static void __init probe_icache(unsigned long config)
+{
+	icache_size = 1 << (12 + ((config >> 9) & 7));
+	ic_lsize = 16 << ((config >> 5) & 1);
+
+	printk("Primary instruction cache %dkb, linesize %d bytes.\n",
+	       icache_size >> 10, ic_lsize);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+	dcache_size = 1 << (12 + ((config >> 6) & 7));
+	dc_lsize = 16 << ((config >> 4) & 1);
+
+	printk("Primary data cache %dkb, linesize %d bytes.\n",
+	       dcache_size >> 10, dc_lsize);
+}
+
+
+void __init ld_mmu_r5432(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+
+	probe_icache(config);
+	probe_dcache(config);
+
+	_clear_page = r5432_clear_page_d32;
+	_copy_page = r5432_copy_page_d32;
+	_flush_cache_all = r5432_flush_cache_all_d32i32;
+	___flush_cache_all = r5432_flush_cache_all_d32i32;
+	_flush_page_to_ram = r5432_flush_page_to_ram_d32;
+	_flush_cache_mm = r5432_flush_cache_mm_d32i32;
+	_flush_cache_range = r5432_flush_cache_range_d32i32;
+	_flush_cache_page = r5432_flush_cache_page_d32i32;
+	_flush_icache_page = r5432_flush_icache_page_i32;
+	_dma_cache_wback_inv = r5432_dma_cache_wback_inv_pc;
+	_dma_cache_wback = r5432_dma_cache_wback;
+	_dma_cache_inv = r5432_dma_cache_inv_pc;
+
+	_flush_cache_sigtramp = r5432_flush_cache_sigtramp;
+	_flush_icache_range = r5432_flush_icache_range;	/* Ouch */
+
+	__flush_cache_all();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-rm7k.c linux/arch/mips/mm/c-rm7k.c
--- linux.orig/arch/mips/mm/c-rm7k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-rm7k.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,349 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org
+ *
+ * To do:
+ *
+ *  - this code is a overbloated pig
+ *  - many of the bug workarounds are not efficient at all, but at
+ *    least they are functional ...
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+
+#define ic_lsize	32		/* Fixed to 32 byte on RM7000  */
+#define dc_lsize	32		/* Fixed to 32 byte on RM7000  */
+#define sc_lsize	32		/* Fixed to 32 byte on RM7000  */
+#define tc_pagesize	(32*128)
+
+/* Secondary cache parameters. */
+#define scache_size	(256*1024)	/* Fixed to 256KiB on RM7000 */
+
+#include <asm/cacheops.h>
+#include <asm/r4kcache.h>
+
+int rm7k_tcache_enabled = 0;
+
+/*
+ * Not added to asm/r4kcache.h because it seems to be RM7000-specific.
+ */
+#define Page_Invalidate_T 0x16
+
+static inline void invalidate_tcache_page(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\t\t\t# invalidate_tcache_page\n\t"
+		".set\tmips3\n\t"
+		"cache\t%1, (%0)\n\t"
+		".set\tmips0\n\t"
+		".set\treorder"
+		:
+		: "r" (addr),
+		  "i" (Page_Invalidate_T));
+}
+
+static void __flush_cache_all_d32i32(void)
+{
+	blast_dcache32();
+	blast_icache32();
+}
+
+static inline void rm7k_flush_cache_all_d32i32(void)
+{
+	/* Yes! Caches that don't suck ...  */
+}
+
+static void rm7k_flush_cache_range_d32i32(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
+{
+	/* RM7000 caches are sane ...  */
+}
+
+static void rm7k_flush_cache_mm_d32i32(struct mm_struct *mm)
+{
+	/* RM7000 caches are sane ...  */
+}
+
+static void rm7k_flush_cache_page_d32i32(struct vm_area_struct *vma,
+					unsigned long page)
+{
+	/* RM7000 caches are sane ...  */
+}
+
+static void rm7k_flush_page_to_ram_d32i32(struct page * page)
+{
+	/* Yes!  Caches that don't suck!  */
+}
+
+static void rm7k_flush_icache_range(unsigned long start, unsigned long end)
+{
+	/*
+	 * FIXME: This is overdoing things and harms performance.
+	 */
+	__flush_cache_all_d32i32();
+}
+
+static void rm7k_flush_icache_page(struct vm_area_struct *vma,
+                                   struct page *page)
+{
+	/*
+	 * FIXME: We should not flush the entire cache but establish some
+	 * temporary mapping and use hit_invalidate operation to flush out
+	 * the line from the cache.
+	 */
+	__flush_cache_all_d32i32();
+}
+
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ * (XXX These need to be fixed ...)
+ */
+static void
+rm7k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_dcache_line(a);	/* Hit_Writeback_Inv_D */
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+
+	if (!rm7k_tcache_enabled) 
+		return;
+
+	a = addr & ~(tc_pagesize - 1);
+	end = (addr + size) & ~(tc_pagesize - 1);
+	while(1) {
+		invalidate_tcache_page(a);	/* Page_Invalidate_T */
+		if (a == end) break;
+		a += tc_pagesize;
+	}
+}
+	       
+static void
+rm7k_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		invalidate_dcache_line(a);	/* Hit_Invalidate_D */
+		invalidate_scache_line(a);	/* Hit_Invalidate_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+
+	if (!rm7k_tcache_enabled) 
+		return;
+
+	a = addr & ~(tc_pagesize - 1);
+	end = (addr + size) & ~(tc_pagesize - 1);
+	while(1) {
+		invalidate_tcache_page(a);	/* Page_Invalidate_T */
+		if (a == end) break;
+		a += tc_pagesize;
+	}
+}
+
+static void
+rm7k_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("rm7k_dma_cache_wback called - should not happen.");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void rm7k_flush_cache_sigtramp(unsigned long addr)
+{
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+}
+
+/* Detect and size the caches. */
+static inline void probe_icache(unsigned long config)
+{
+	icache_size = 1 << (12 + ((config >> 9) & 7));
+
+	printk(KERN_INFO "Primary instruction cache %dKiB.\n", icache_size >> 10);
+}
+
+static inline void probe_dcache(unsigned long config)
+{
+	dcache_size = 1 << (12 + ((config >> 6) & 7));
+
+	printk(KERN_INFO "Primary data cache %dKiB.\n", dcache_size >> 10);
+}
+
+
+/* 
+ * This function is executed in the uncached segment KSEG1.
+ * It must not touch the stack, because the stack pointer still points
+ * into KSEG0. 
+ *
+ * Three options:
+ *	- Write it in assembly and guarantee that we don't use the stack.
+ *	- Disable caching for KSEG0 before calling it.
+ *	- Pray that GCC doesn't randomly start using the stack.
+ *
+ * This being Linux, we obviously take the least sane of those options -
+ * following DaveM's lead in r4xx0.c
+ *
+ * It seems we get our kicks from relying on unguaranteed behaviour in GCC
+ */
+static __init void setup_scache(void)
+{
+	int register i;
+	
+	set_cp0_config(1<<3 /* CONF_SE */);
+
+	set_taglo(0);
+	set_taghi(0);
+	
+	for (i=0; i<scache_size; i+=sc_lsize) {
+		__asm__ __volatile__ (
+		      ".set noreorder\n\t"
+		      ".set mips3\n\t"
+		      "cache %1, (%0)\n\t"
+		      ".set mips0\n\t"
+		      ".set reorder"
+		      :
+		      : "r" (KSEG0ADDR(i)),
+		        "i" (Index_Store_Tag_SD));
+	}
+
+}
+
+static inline void probe_scache(unsigned long config)
+{
+	void (*func)(void) = KSEG1ADDR(&setup_scache);
+
+	if ((config >> 31) & 1)
+		return;
+
+	printk(KERN_INFO "Secondary cache %dKiB, linesize %d bytes.\n",
+	       (scache_size >> 10), sc_lsize);
+
+	if ((config >> 3) & 1)
+		return;
+
+	printk(KERN_INFO "Enabling secondary cache...");
+	func();
+	printk("Done\n");
+}
+ 
+static inline void probe_tcache(unsigned long config)
+{
+	if ((config >> 17) & 1)
+		return;
+
+	/* We can't enable the L3 cache yet. There may be board-specific
+	 * magic necessary to turn it on, and blindly asking the CPU to
+	 * start using it would may give cache errors.
+	 *
+	 * Also, board-specific knowledge may allow us to use the 
+	 * CACHE Flash_Invalidate_T instruction if the tag RAM supports
+	 * it, and may specify the size of the L3 cache so we don't have
+	 * to probe it. 
+	 */
+	printk(KERN_INFO "Tertiary cache present, %s enabled\n",
+	       config&(1<<12) ? "already" : "not (yet)");
+
+	if ((config >> 12) & 1)
+		rm7k_tcache_enabled = 1;
+}
+
+void __init ld_mmu_rm7k(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+	unsigned long addr;
+
+        change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+
+	/* RM7000 erratum #31. The icache is screwed at startup. */
+	set_taglo(0);
+	set_taghi(0);
+	for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) {
+		__asm__ __volatile__ (
+			".set noreorder\n\t"
+			".set mips3\n\t"
+			"cache\t%1, 0(%0)\n\t"
+			"cache\t%1, 0x1000(%0)\n\t"
+			"cache\t%1, 0x2000(%0)\n\t"
+			"cache\t%1, 0x3000(%0)\n\t"
+			"cache\t%2, 0(%0)\n\t"
+			"cache\t%2, 0x1000(%0)\n\t"
+			"cache\t%2, 0x2000(%0)\n\t"
+			"cache\t%2, 0x3000(%0)\n\t"
+			"cache\t%1, 0(%0)\n\t"
+			"cache\t%1, 0x1000(%0)\n\t"
+			"cache\t%1, 0x2000(%0)\n\t"
+			"cache\t%1, 0x3000(%0)\n\t"
+			".set\tmips0\n\t"
+			".set\treorder\n\t"
+			:
+			: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
+	}
+
+#ifndef CONFIG_MIPS_UNCACHED
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif
+
+	probe_icache(config);
+	probe_dcache(config);
+	probe_scache(config);
+	probe_tcache(config);
+
+	_clear_page = rm7k_clear_page;
+	_copy_page = rm7k_copy_page;
+
+	_flush_cache_all = rm7k_flush_cache_all_d32i32;
+	___flush_cache_all = __flush_cache_all_d32i32;
+	_flush_cache_mm = rm7k_flush_cache_mm_d32i32;
+	_flush_cache_range = rm7k_flush_cache_range_d32i32;
+	_flush_cache_page = rm7k_flush_cache_page_d32i32;
+	_flush_page_to_ram = rm7k_flush_page_to_ram_d32i32;
+	_flush_cache_sigtramp = rm7k_flush_cache_sigtramp;
+	_flush_icache_range = rm7k_flush_icache_range;
+	_flush_icache_page = rm7k_flush_icache_page;
+
+	_dma_cache_wback_inv = rm7k_dma_cache_wback_inv;
+	_dma_cache_wback = rm7k_dma_cache_wback;
+	_dma_cache_inv = rm7k_dma_cache_inv;
+
+	__flush_cache_all_d32i32();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-sb1.c linux/arch/mips/mm/c-sb1.c
--- linux.orig/arch/mips/mm/c-sb1.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-sb1.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,524 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */ 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/mmu_context.h>
+#include <asm/bootinfo.h>
+#include <asm/cacheops.h>
+#include <asm/cpu.h>
+#include <asm/uaccess.h>
+
+/* These are probed at ld_mmu time */
+static unsigned int icache_size;
+static unsigned int dcache_size;
+
+static unsigned int icache_line_size;
+static unsigned int dcache_line_size;
+
+static unsigned int icache_index_mask;
+
+static unsigned int icache_assoc;
+static unsigned int dcache_assoc;
+
+static unsigned int icache_sets;
+static unsigned int dcache_sets;
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
+/*
+ * The dcache is fully coherent to the system, with one
+ * big caveat:  the instruction stream.  In other words,
+ * if we miss in the icache, and have dirty data in the
+ * L1 dcache, then we'll go out to memory (or the L2) and
+ * get the not-as-recent data.
+ * 
+ * So the only time we have to flush the dcache is when
+ * we're flushing the icache.  Since the L2 is fully
+ * coherent to everything, including I/O, we never have
+ * to flush it
+ */
+
+static void sb1_flush_cache_all(void)
+{
+}
+
+static void local_sb1___flush_cache_all(void)
+{
+	/*
+	 * Haven't worried too much about speed here; given that we're flushing
+	 * the icache, the time to invalidate is dwarfed by the time it's going
+	 * to take to refill it.  Register usage:
+	 * 
+	 * $1 - moving cache index
+	 * $2 - set count
+	 */
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %2         \n" /* Start at index 0 */
+		"1:   cache  %3, 0($1)      \n" /* WB/Invalidate this index */
+		"     addiu  %1, %1, -1     \n" /* Decrement loop count */
+		"     bnez   %1, 1b         \n" /* loop test */
+		"      addu   $1, $1, %0    \n" /* Next address */
+		".set pop                   \n"
+		:
+		: "r" (dcache_line_size), "r" (dcache_sets * dcache_assoc),
+		  "r" (KSEG0), "i" (Index_Writeback_Inv_D));
+
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set mips2                 \n"
+		"sync                       \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */			
+		"sync                       \n"
+#endif
+		".set pop                   \n");
+
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %2         \n" /* Start at index 0 */
+		"1:   cache  %3, 0($1)       \n" /* Invalidate this index */
+		"     addiu  %1, %1, -1     \n" /* Decrement loop count */
+		"     bnez   %1, 1b         \n" /* loop test */
+		"      addu   $1, $1, %0    \n" /* Next address */
+		".set pop                   \n"
+		:
+		: "r" (icache_line_size), "r" (icache_sets * icache_assoc),
+		  "r" (KSEG0), "i" (Index_Invalidate_I));
+}
+
+#ifdef CONFIG_SMP
+extern void sb1___flush_cache_all_ipi(void *ignored);
+asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all");
+
+static void sb1___flush_cache_all(void)
+{
+	smp_call_function(sb1___flush_cache_all_ipi, 0, 1, 1);
+	local_sb1___flush_cache_all();
+}
+#else
+extern void sb1___flush_cache_all(void);
+asm("sb1___flush_cache_all = local_sb1___flush_cache_all");
+#endif
+
+
+/*
+ * When flushing a range in the icache, we have to first writeback
+ * the dcache for the same range, so new ifetches will see any
+ * data that was dirty in the dcache.
+ *
+ * The start/end arguments are expected to be Kseg addresses.
+ */
+
+static void local_sb1_flush_icache_range(unsigned long start, unsigned long end)
+{
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	unsigned long flags;
+	local_irq_save(flags);
+#endif
+
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %0         \n" 
+		"1:                         \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+		".align 3                   \n"
+		"     lw     $0,   0($1)    \n" /* Bug 1370, 1368            */
+		"     sync                  \n"
+#endif
+		"     cache  %3, 0($1)      \n" /* Hit-WB{,-inval} this address */
+		"     bne    $1, %1, 1b     \n" /* loop test */
+		"      addu  $1, $1, %2     \n" /* next line */
+		".set pop                   \n"
+		:
+		: "r" (start  & ~(dcache_line_size - 1)),
+		  "r" ((end - 1) & ~(dcache_line_size - 1)),
+		  "r" (dcache_line_size),
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+		  "i" (Hit_Writeback_Inv_D)
+#else
+		  "i" (Hit_Writeback_D)
+#endif
+		);
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set mips2                 \n"
+		"sync                       \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */
+		"sync                       \n"
+#endif
+		".set pop                   \n");
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	local_irq_restore(flags);
+#endif
+
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %0         \n" 
+		".align 3                   \n"
+		"1:   cache  %3, (0<<13)($1) \n" /* Index-inval this address */
+		"     cache  %3, (1<<13)($1) \n" /* Index-inval this address */
+		"     cache  %3, (2<<13)($1) \n" /* Index-inval this address */
+		"     cache  %3, (3<<13)($1) \n" /* Index-inval this address */
+		"     bne    $1, %1, 1b     \n" /* loop test */
+		"      addu  $1, $1, %2     \n" /* next line */
+		".set pop                   \n"
+		:
+		: "r" (start & ~(icache_line_size - 1)),
+		  "r" ((end - 1) & ~(icache_line_size - 1)),
+		  "r" (icache_line_size),
+		  "i" (Index_Invalidate_I));
+}
+
+#ifdef CONFIG_SMP
+struct flush_icache_range_args {
+	unsigned long start;
+	unsigned long end;
+};
+
+static void sb1_flush_icache_range_ipi(void *info)
+{
+	struct flush_icache_range_args *args = info;
+
+	local_sb1_flush_icache_range(args->start, args->end);
+}
+
+void sb1_flush_icache_range(unsigned long start, unsigned long end)
+{
+	struct flush_icache_range_args args;
+
+	args.start = start;
+	args.end = end;
+	smp_call_function(sb1_flush_icache_range_ipi, &args, 1, 1);
+	local_sb1_flush_icache_range(start, end);
+}
+#else
+void sb1_flush_icache_range(unsigned long start, unsigned long end);
+asm("sb1_flush_icache_range = local_sb1_flush_icache_range");
+#endif
+
+/*
+ * If there's no context yet, or the page isn't executable, no icache flush
+ * is needed
+ */
+static void sb1_flush_icache_page(struct vm_area_struct *vma,
+	struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	/*
+	 * We're not sure of the virtual address(es) involved here, so
+	 * conservatively flush the entire caches on all processors
+	 * (ouch).
+	 */
+	sb1___flush_cache_all();
+}
+
+static inline void protected_flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		"    .set push                \n"
+		"    .set noreorder           \n"
+		"    .set mips4               \n"
+		"1:  cache %1, (%0)           \n"
+		"2:  .set pop                 \n"
+		"    .section __ex_table,\"a\"\n"
+		"     .word  1b, 2b          \n"
+		"     .previous"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_I));
+}
+
+static inline void protected_writeback_dcache_line(unsigned long addr)
+{
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	/* Have to be sure the TLB entry exists for the cache op, 
+	   so we have to be sure that nothing happens in between the
+	   lw and the cache op 
+	*/
+	unsigned long flags;
+	local_irq_save(flags);
+#endif
+	__asm__ __volatile__(
+		"    .set push                \n"
+		"    .set noreorder           \n"
+		"    .set mips4               \n"
+		"1:                           \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+		"     lw    $0,   (%0)        \n"
+		"     sync                  \n"
+#endif
+		"     cache  %1, 0(%0)    \n" /* Hit-WB{-inval} this address */
+		/* XXX: should be able to do this after both dcache cache
+		   ops, but there's no guarantee that this will be inlined,
+		   and the pass1 restriction checker can't detect syncs
+		   following cache ops except in the following basic block.
+		*/
+		"     sync                    \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */
+		"     sync                    \n"
+#endif
+		"2:  .set pop                 \n"
+		"    .section __ex_table,\"a\"\n"
+		"     .word  1b, 2b          \n"
+		"     .previous"
+		:
+		: "r" (addr),
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+		  "i" (Hit_Writeback_Inv_D)
+#else
+		  "i" (Hit_Writeback_D)
+#endif
+		  );
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	local_irq_restore(flags);
+#endif
+}
+
+/*
+ * A signal trampoline must fit into a single cacheline.
+ */
+static void local_sb1_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long daddr, iaddr;
+
+	daddr = addr & ~(dcache_line_size - 1);
+	protected_writeback_dcache_line(daddr);
+	iaddr = addr & ~(icache_line_size - 1);
+	protected_flush_icache_line(iaddr);
+}
+
+#ifdef CONFIG_SMP
+
+static void sb1_flush_cache_sigtramp_ipi(void *info)
+{
+	unsigned long iaddr = (unsigned long) info;
+
+	iaddr = iaddr & ~(icache_line_size - 1);
+	protected_flush_icache_line(iaddr);
+}
+
+static void sb1_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long tmp;
+
+	/*
+	 * Flush the local dcache, then load the instruction back into a
+	 * register.  That will make sure that any remote CPU also has
+	 * written back it's data cache to memory.
+	 */
+	local_sb1_flush_cache_sigtramp(addr);
+	__get_user(tmp, (unsigned long *)addr);
+
+	smp_call_function(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
+}
+
+#else
+void sb1_flush_cache_sigtramp(unsigned long addr);
+asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp");
+#endif
+
+static void sb1_flush_icache_all(void)
+{
+	/*
+	 * Haven't worried too much about speed here; given that we're flushing
+	 * the icache, the time to invalidate is dwarfed by the time it's going
+	 * to take to refill it.  Register usage:
+	 * 
+	 * $1 - moving cache index
+	 * $2 - set count
+	 */
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %2         \n" /* Start at index 0 */
+		"1:   cache  %3, 0($1)      \n" /* Invalidate this index */
+		"     addiu  %1, %1, -1     \n" /* Decrement loop count */
+		"     bnez   %1, 1b         \n" /* loop test */
+		"      addu   $1, $1, %0    \n" /* Next address */
+		".set pop                   \n"
+		:
+		: "r" (icache_line_size), "r" (icache_sets * icache_assoc),
+		  "r" (KSEG0), "i" (Index_Invalidate_I));
+}
+
+/*
+ * Anything that just flushes dcache state can be ignored, as we're always
+ * coherent in dcache space.  This is just a dummy function that all the
+ * nop'ed routines point to
+ */
+
+static void sb1_nop(void)
+{
+}
+
+/*
+ * This only needs to make sure stores done up to this
+ * point are visible to other agents outside the CPU.  Given 
+ * the coherent nature of the ZBbus, all that's required here is 
+ * a sync to make sure the data gets out to the caches and is
+ * visible to an arbitrary A Phase from an external agent 
+ *   
+ * Actually, I'm not even sure that's necessary; the semantics
+ * of this function aren't clear.  If it's supposed to serve as
+ * a memory barrier, this is needed.  If it's only meant to 
+ * prevent data from being invisible to non-cpu memory accessors
+ * for some indefinite period of time (e.g. in a non-coherent 
+ * dcache) then this function would be a complete nop.
+ */
+static void sb1_flush_page_to_ram(struct page *page)
+{
+	__asm__ __volatile__(
+		"     sync  \n"  /* Short pipe */
+		:::"memory");	
+}
+
+/*
+ *  Cache set values (from the mips64 spec)
+ * 0 - 64
+ * 1 - 128
+ * 2 - 256
+ * 3 - 512
+ * 4 - 1024
+ * 5 - 2048
+ * 6 - 4096
+ * 7 - Reserved
+ */
+  
+static unsigned int decode_cache_sets(unsigned int config_field)
+{
+	if (config_field == 7) {
+		/* JDCXXX - Find a graceful way to abort. */
+		return 0;
+	} 
+	return (1<<(config_field + 6));
+}
+
+/*
+ *  Cache line size values (from the mips64 spec)
+ * 0 - No cache present.
+ * 1 - 4 bytes
+ * 2 - 8 bytes
+ * 3 - 16 bytes
+ * 4 - 32 bytes
+ * 5 - 64 bytes
+ * 6 - 128 bytes
+ * 7 - Reserved
+ */
+
+static unsigned int decode_cache_line_size(unsigned int config_field)
+{
+	if (config_field == 0) {
+		return 0;
+	} else if (config_field == 7) {
+		/* JDCXXX - Find a graceful way to abort. */
+		return 0;
+	} 
+	return (1<<(config_field + 1));
+}
+
+/*
+ * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs)
+ *
+ * 24:22 Icache sets per way
+ * 21:19 Icache line size
+ * 18:16 Icache Associativity
+ * 15:13 Dcache sets per way
+ * 12:10 Dcache line size
+ * 9:7   Dcache Associativity
+ */
+
+static __init void probe_cache_sizes(void)
+{
+	u32 config1;
+
+	config1 = read_mips32_cp0_config1();
+	icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7);
+	dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7);
+	icache_sets = decode_cache_sets((config1 >> 22) & 0x7);
+	dcache_sets = decode_cache_sets((config1 >> 13) & 0x7);
+	icache_assoc = ((config1 >> 16) & 0x7) + 1;
+	dcache_assoc = ((config1 >> 7) & 0x7) + 1;
+	icache_size = icache_line_size * icache_sets * icache_assoc;
+	dcache_size = dcache_line_size * dcache_sets * dcache_assoc;
+	icache_index_mask = (icache_sets - 1) * icache_line_size;
+}
+
+/*
+ * This is called from loadmmu.c.  We have to set up all the
+ * memory management function pointers, as well as initialize
+ * the caches and tlbs
+ */
+void ld_mmu_sb1(void)
+{
+	probe_cache_sizes();
+
+	_clear_page = sb1_clear_page;
+	_copy_page = sb1_copy_page;
+
+	_flush_cache_all = sb1_flush_cache_all;
+	___flush_cache_all = sb1___flush_cache_all;
+	_flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop;
+	_flush_cache_range = (void *) sb1_nop;
+	_flush_page_to_ram = sb1_flush_page_to_ram;
+	_flush_icache_page = sb1_flush_icache_page;
+	_flush_icache_range = sb1_flush_icache_range;
+
+	/* None of these are needed for the sb1 */
+	_flush_cache_page = (void *) sb1_nop;
+
+	_flush_cache_sigtramp = sb1_flush_cache_sigtramp;
+	_flush_icache_all = sb1_flush_icache_all;
+
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
+	flush_cache_all();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-tx39.c linux/arch/mips/mm/c-tx39.c
--- linux.orig/arch/mips/mm/c-tx39.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-tx39.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,339 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/wbflush.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+/* For R3000 cores with R4000 style caches */
+static unsigned long icache_size, dcache_size;		/* Size in bytes */
+extern long scache_size;
+
+#define icache_lsize	mips_cpu.icache.linesz
+#define dcache_lsize	mips_cpu.dcache.linesz
+
+#include <asm/r4kcache.h>
+
+extern int r3k_have_wired_reg;	/* in r3k-tlb.c */
+
+static void tx39h_flush_page_to_ram(struct page * page)
+{
+}
+
+/* TX39H-style cache flush routines. */
+static void tx39h_flush_icache_all(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size);
+	unsigned long flags, config;
+
+	/* disable icache (set ICE#) */
+	__save_and_cli(flags);
+	config = read_32bit_cp0_register(CP0_CONF);
+
+	/* invalidate icache */
+	while (start < end) {
+		cache16_unroll32(start, Index_Invalidate_I);
+		start += 0x200;
+	}
+
+	write_32bit_cp0_register(CP0_CONF, config);
+	__restore_flags(flags);
+}
+
+static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	wbflush();
+
+	a = addr & ~(dcache_lsize - 1);
+	end = (addr + size) & ~(dcache_lsize - 1);
+	while (1) {
+		invalidate_dcache_line(a); /* Hit_Invalidate_D */
+		if (a == end) break;
+		a += dcache_lsize;
+	}
+}
+
+
+/* TX39H2,TX39H3 */
+static inline void tx39_flush_cache_all(void)
+{
+	unsigned long flags, config;
+
+	__save_and_cli(flags);
+	blast_dcache16_wayLSB();
+	/* disable icache (set ICE#) */
+	config = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE);
+	blast_icache16_wayLSB();
+	write_32bit_cp0_register(CP0_CONF, config);
+	__restore_flags(flags);
+}
+ 
+static void tx39_flush_cache_mm(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		tx39_flush_cache_all();
+	}
+}
+
+static void tx39_flush_cache_range(struct mm_struct *mm,
+				    unsigned long start,
+				    unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags, config;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		__save_and_cli(flags);
+		blast_dcache16_wayLSB();
+		/* disable icache (set ICE#) */
+		config = read_32bit_cp0_register(CP0_CONF);
+		write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE);
+		blast_icache16_wayLSB();
+		write_32bit_cp0_register(CP0_CONF, config);
+		__restore_flags(flags);
+	}
+}
+
+static void tx39_flush_cache_page(struct vm_area_struct *vma,
+				   unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if(mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if(!(pte_val(*ptep) & _PAGE_PRESENT))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache16_page(page);
+	} else {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache16_page_indexed_wayLSB(page);
+	}
+out:
+	__restore_flags(flags);
+}
+
+static void tx39_flush_page_to_ram(struct page * page)
+{
+	blast_dcache16_page((unsigned long)page_address(page));
+}
+
+static void tx39_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	flush_cache_all();
+}
+
+static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		a = addr & ~(dcache_lsize - 1);
+		end = (addr + size) & ~(dcache_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dcache_lsize;
+		}
+	}
+}
+
+static void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		a = addr & ~(dcache_lsize - 1);
+		end = (addr + size) & ~(dcache_lsize - 1);
+		while (1) {
+			invalidate_dcache_line(a); /* Hit_Invalidate_D */
+			if (a == end) break;
+			a += dcache_lsize;
+		}
+	}
+}
+
+static void tx39_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("tx39_dma_cache called - should not happen.");
+}
+
+static void tx39_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long config;
+	unsigned int flags;
+
+	__save_and_cli(flags);
+	protected_writeback_dcache_line(addr & ~(dcache_lsize - 1));
+
+	/* disable icache (set ICE#) */
+	config = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE);
+	protected_flush_icache_line(addr & ~(icache_lsize - 1));
+	write_32bit_cp0_register(CP0_CONF, config);
+	__restore_flags(flags);
+}
+
+static __init void tx39_probe_cache(void)
+{
+	unsigned long config;
+
+	config = read_32bit_cp0_register(CP0_CONF);
+
+	icache_size = 1 << (10 + ((config >> 19) & 3));
+	dcache_size = 1 << (10 + ((config >> 16) & 3));
+
+	icache_lsize = 16;
+	switch (mips_cpu.cputype) {
+	case CPU_TX3912:
+		dcache_lsize = 4;
+		break;
+	case CPU_TX3922:
+	case CPU_TX3927:
+	case CPU_TX39XX:
+	default:
+		dcache_lsize = 16;
+		break;
+	}
+}
+
+void __init ld_mmu_tx39(void)
+{
+	unsigned long config;
+
+	_clear_page = r3k_clear_page;
+	_copy_page = r3k_copy_page;
+
+	config = read_32bit_cp0_register(CP0_CONF);
+	config &= ~TX39_CONF_WBON;
+	write_32bit_cp0_register(CP0_CONF, config);
+
+	tx39_probe_cache();
+
+	switch (mips_cpu.cputype) {
+	case CPU_TX3912:
+		/* TX39/H core (writethru direct-map cache) */
+		_flush_cache_all	= tx39h_flush_icache_all;
+		___flush_cache_all	= tx39h_flush_icache_all;
+		_flush_cache_mm		= (void *) tx39h_flush_icache_all;
+		_flush_cache_range	= (void *) tx39h_flush_icache_all;
+		_flush_cache_page	= (void *) tx39h_flush_icache_all;
+		_flush_cache_sigtramp	= (void *) tx39h_flush_icache_all;
+		_flush_page_to_ram	= tx39h_flush_page_to_ram;
+		_flush_icache_page	= (void *) tx39h_flush_icache_all;
+		_flush_icache_range	= (void *) tx39h_flush_icache_all;
+
+		_dma_cache_wback_inv = tx39h_dma_cache_wback_inv;
+		break;
+
+	case CPU_TX3922:
+	case CPU_TX3927:
+	default:
+		/* TX39/H2,H3 core (writeback 2way-set-associative cache) */
+		r3k_have_wired_reg = 1;
+		set_wired (0);	/* set 8 on reset... */
+		/* board-dependent init code may set WBON */
+
+		_flush_cache_all = tx39_flush_cache_all;
+		___flush_cache_all = tx39_flush_cache_all;
+		_flush_cache_mm = tx39_flush_cache_mm;
+		_flush_cache_range = tx39_flush_cache_range;
+		_flush_cache_page = tx39_flush_cache_page;
+		_flush_cache_sigtramp = tx39_flush_cache_sigtramp;
+		_flush_page_to_ram = tx39_flush_page_to_ram;
+		_flush_icache_page = tx39_flush_icache_page;
+		_flush_icache_range = tx39_flush_icache_range;
+
+		_dma_cache_wback_inv = tx39_dma_cache_wback_inv;
+		_dma_cache_wback = tx39_dma_cache_wback;
+		_dma_cache_inv = tx39_dma_cache_inv;
+
+		break;
+	}
+
+	if (mips_cpu.icache.ways == 0)
+		mips_cpu.icache.ways = 1;
+	if (mips_cpu.dcache.ways == 0)
+		mips_cpu.dcache.ways = 1;
+	mips_cpu.icache.sets =
+		icache_size / mips_cpu.icache.ways / mips_cpu.icache.linesz;
+	mips_cpu.dcache.sets =
+		dcache_size / mips_cpu.dcache.ways / mips_cpu.dcache.linesz;
+
+	printk("Primary instruction cache %dkb, linesize %d bytes\n",
+		(int) (icache_size >> 10), (int) icache_lsize);
+	printk("Primary data cache %dkb, linesize %d bytes\n",
+		(int) (dcache_size >> 10), (int) dcache_lsize);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/c-tx49.c linux/arch/mips/mm/c-tx49.c
--- linux.orig/arch/mips/mm/c-tx49.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/c-tx49.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,439 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r49xx.c: TX49 processor variant specific MMU/Cache routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
+ *
+ * Modified for R4300/TX49xx (Jun/2001)
+ * Copyright (C) 1999-2001 Toshiba Corporation
+ *
+ * To do:
+ *
+ *  - this code is a overbloated pig
+ *  - many of the bug workarounds are not efficient at all, but at
+ *    least they are functional ...
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+#define ic_lsize	mips_cpu.icache.linesz
+#define dc_lsize	mips_cpu.dcache.linesz
+static unsigned long scache_size;
+
+#include <asm/cacheops.h>
+#include <asm/r4kcache.h>
+
+#undef DEBUG_CACHE
+
+/* TX49 does can not flush the line contains the CACHE insn itself... */
+/* r4k_xxx routines are completely same as those in r4xx0.c */
+
+/*
+ * If you think for one second that this stuff coming up is a lot
+ * of bulky code eating too many kernel cache lines.  Think _again_.
+ *
+ * Consider:
+ * 1) Taken branches have a 3 cycle penalty on R4k
+ * 2) The branch itself is a real dead cycle on even R4600/R5000.
+ * 3) Only one of the following variants of each type is even used by
+ *    the kernel based upon the cache parameters we detect at boot time.
+ *
+ * QED.
+ */
+
+static inline void r49_flush_cache_all_d16i32(void)
+{
+	unsigned long flags, config;
+
+	__save_and_cli(flags);
+	blast_dcache16_wayLSB();
+	/* disable icache (set ICE#) */
+	config = read_32bit_cp0_register(CP0_CONFIG);
+	write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
+	blast_icache32_wayLSB();
+	write_32bit_cp0_register(CP0_CONFIG, config);
+	__restore_flags(flags);
+}
+
+static inline void r49_flush_cache_all_d32i32(void)
+{
+	unsigned long flags, config;
+
+	__save_and_cli(flags);
+	blast_dcache32_wayLSB();
+	/* disable icache (set ICE#) */
+	config = read_32bit_cp0_register(CP0_CONFIG);
+	write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
+	blast_icache32_wayLSB();
+	write_32bit_cp0_register(CP0_CONFIG, config);
+	__restore_flags(flags);
+}
+
+static void r49_flush_cache_range_d16i32(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
+{
+	if (mm->context != 0) {
+		unsigned long flags, config;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		__save_and_cli(flags);
+		blast_dcache16_wayLSB();
+		/* disable icache (set ICE#) */
+		config = read_32bit_cp0_register(CP0_CONFIG);
+		write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
+		blast_icache32_wayLSB();
+		write_32bit_cp0_register(CP0_CONFIG, config);
+		__restore_flags(flags);
+	}
+}
+
+static void r49_flush_cache_range_d32i32(struct mm_struct *mm,
+					       unsigned long start,
+					       unsigned long end)
+{
+	if (mm->context != 0) {
+		unsigned long flags, config;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		__save_and_cli(flags);
+		blast_dcache32_wayLSB();
+		/* disable icache (set ICE#) */
+		config = read_32bit_cp0_register(CP0_CONFIG);
+		write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
+		blast_icache32_wayLSB();
+		write_32bit_cp0_register(CP0_CONFIG, config);
+		__restore_flags(flags);
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void r49_flush_cache_mm_d16i32(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r49_flush_cache_all_d16i32();
+	}
+}
+
+static void r49_flush_cache_mm_d32i32(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		r49_flush_cache_all_d32i32();
+	}
+}
+
+static void r49_flush_cache_page_d16i32(struct vm_area_struct *vma,
+					unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache16_page(page);
+	} else {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache16_page_indexed_wayLSB(page);
+	}
+out:
+	__restore_flags(flags);
+}
+
+static void r49_flush_cache_page_d32i32(struct vm_area_struct *vma,
+					      unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		blast_dcache32_page(page);
+	} else {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache32_page_indexed_wayLSB(page);
+	}
+out:
+	__restore_flags(flags);
+}
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ *    addresses all the time in kernel mode we can do a direct
+ *    flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void r4k_flush_page_to_ram_d16(struct page *page)
+{
+	blast_dcache16_page((unsigned long)page_address(page));
+}
+
+static void r4k_flush_page_to_ram_d32(struct page *page)
+{
+	blast_dcache32_page((unsigned long)page_address(page));
+}
+
+static void
+r4k_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+/*
+ * Ok, this seriously sucks.  We use them to flush a user page but don't
+ * know the virtual address, so we have to blast away the whole icache
+ * which is significantly more expensive than the real thing.
+ */
+static void
+r4k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	flush_cache_all();
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ */
+static void
+r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		__save_and_cli(flags);
+
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+}
+
+static void
+r4k_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+		__save_and_cli(flags);
+
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+}
+
+static void
+r4k_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("r4k_dma_cache called - should not happen.");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void r4k_flush_cache_sigtramp(unsigned long addr)
+{
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+}
+
+/* Detect and size the various r4k caches. */
+static void __init probe_icache(unsigned long config)
+{
+	icache_size = 1 << (12 + ((config >> 9) & 7));
+	ic_lsize = 16 << ((config >> 5) & 1);
+
+	printk("Primary instruction cache %dkb, linesize %d bytes.\n",
+	       icache_size >> 10, ic_lsize);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+	dcache_size = 1 << (12 + ((config >> 6) & 7));
+	dc_lsize = 16 << ((config >> 4) & 1);
+
+	printk("Primary data cache %dkb, linesize %d bytes.\n",
+	       dcache_size >> 10, dc_lsize);
+}
+
+int mips_configk0 = -1;	/* board-specific setup routine can override this */
+void __init ld_mmu_tx49(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	if (mips_configk0 != -1)
+		change_cp0_config(CONF_CM_CMASK, mips_configk0);
+	else
+#ifdef CONFIG_MIPS_UNCACHED
+		change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+#else
+		change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif
+
+	probe_icache(config);
+	probe_dcache(config);
+	if (mips_cpu.icache.ways == 0)
+		mips_cpu.icache.ways = 1;
+	if (mips_cpu.dcache.ways == 0)
+		mips_cpu.dcache.ways = 1;
+	mips_cpu.icache.sets =
+		icache_size / mips_cpu.icache.ways / mips_cpu.icache.linesz;
+	mips_cpu.dcache.sets =
+		dcache_size / mips_cpu.dcache.ways / mips_cpu.dcache.linesz;
+
+	switch(dc_lsize) {
+	case 16:
+		_clear_page = r4k_clear_page_d16;
+		_copy_page = r4k_copy_page_d16;
+		_flush_page_to_ram = r4k_flush_page_to_ram_d16;
+		_flush_cache_all = r49_flush_cache_all_d16i32;
+		_flush_cache_mm = r49_flush_cache_mm_d16i32;
+		_flush_cache_range = r49_flush_cache_range_d16i32;
+		_flush_cache_page = r49_flush_cache_page_d16i32;
+		break;
+	case 32:
+		_clear_page = r4k_clear_page_d32;
+		_copy_page = r4k_copy_page_d32;
+		_flush_page_to_ram = r4k_flush_page_to_ram_d32;
+		_flush_cache_all = r49_flush_cache_all_d32i32;
+		_flush_cache_mm = r49_flush_cache_mm_d32i32;
+		_flush_cache_range = r49_flush_cache_range_d32i32;
+		_flush_cache_page = r49_flush_cache_page_d32i32;
+		break;
+	}
+	___flush_cache_all = _flush_cache_all;
+
+	_flush_icache_page = r4k_flush_icache_page;
+
+	_dma_cache_wback_inv = r4k_dma_cache_wback_inv;
+	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_inv = r4k_dma_cache_inv;
+
+	_flush_cache_sigtramp = r4k_flush_cache_sigtramp;
+	_flush_icache_range = r4k_flush_icache_range;	/* Ouch */
+
+	__flush_cache_all();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c
--- linux.orig/arch/mips/mm/fault.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips/mm/fault.c	2002-07-20 01:08:30.000000000 +0000
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1995 - 2000 by Ralf Baechle
  */
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
@@ -19,6 +20,7 @@
 #include <linux/smp_lock.h>
 #include <linux/version.h>
 
+#include <asm/branch.h>
 #include <asm/hardirq.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
@@ -28,13 +30,44 @@
 
 #define development_version (LINUX_VERSION_CODE & 0x100)
 
-unsigned long asid_cache = ASID_FIRST_VERSION;
-
 /*
  * Macro for exception fixup code to access integer registers.
  */
 #define dpf_reg(r) (regs->regs[r])
 
+extern spinlock_t timerlist_lock;
+
+/*
+ * Unlock any spinlocks which will prevent us from getting the
+ * message out (timerlist_lock is acquired through the
+ * console unblank code)
+ */
+void bust_spinlocks(int yes)
+{
+	spin_lock_init(&timerlist_lock);
+	if (yes) {
+		oops_in_progress = 1;
+#ifdef CONFIG_SMP
+		/* Many serial drivers do __global_cli() */
+		global_irq_lock = SPIN_LOCK_UNLOCKED;
+#endif
+	} else {
+		int loglevel_save = console_loglevel;
+#ifdef CONFIG_VT
+		unblank_screen();
+#endif
+		oops_in_progress = 0;
+		/*
+		 * OK, the message is on the console.  Now we call printk()
+		 * without oops_in_progress set so that printk will give klogd
+		 * a poke.  Hold onto your hats...
+		 */
+		console_loglevel = 15;		/* NMI oopser may have shut the console up */
+		printk(" ");
+		console_loglevel = loglevel_save;
+	}
+}
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
@@ -58,7 +91,7 @@
 	 * only copy the information from the master page table,
 	 * nothing more.
 	 */
-	if (address >= TASK_SIZE)
+	if (address >= VMALLOC_START)
 		goto vmalloc_fault;
 
 	info.si_code = SEGV_MAPERR;
@@ -97,6 +130,7 @@
 			goto bad_area;
 	}
 
+survive:
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
@@ -149,7 +183,7 @@
 
 no_context:
 	/* Are we prepared to handle this kernel fault?  */
-	fixup = search_exception_table(regs->cp0_epc);
+	fixup = search_exception_table(exception_epc(regs));
 	if (fixup) {
 		long new_epc;
 
@@ -170,7 +204,7 @@
 	       "address %08lx, epc == %08lx, ra == %08lx\n",
 	       address, regs->cp0_epc, regs->regs[31]);
 	die("Oops", regs);
-	do_exit(SIGKILL);
+	/* Game over.  */
 
 /*
  * We ran out of memory, or some other thing happened to us that made
@@ -178,7 +212,13 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	printk("VM: killing process %s\n", tsk->comm);
+	if (tsk->pid == 1) {
+		tsk->policy |= SCHED_YIELD;
+		schedule();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	printk(KERN_NOTICE "VM: killing process %s\n", tsk->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
@@ -191,7 +231,7 @@
 	 * or user mode.
 	 */
 	tsk->thread.cp0_badvaddr = address;
-	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/mips/mm/init.c linux/arch/mips/mm/init.c
--- linux.orig/arch/mips/mm/init.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips/mm/init.c	2002-07-20 01:08:39.000000000 +0000
@@ -25,9 +25,7 @@
 #include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/swapctl.h>
-#ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
-#endif
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
@@ -37,15 +35,13 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
-#ifdef CONFIG_SGI_IP22
-#include <asm/sgialib.h>
-#endif
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
 
 mmu_gather_t mmu_gathers[NR_CPUS];
-
+unsigned long highstart_pfn, highend_pfn;
 static unsigned long totalram_pages;
+static unsigned long totalhigh_pages;
 
 extern void prom_free_prom_memory(void);
 
@@ -98,19 +94,39 @@
 {
 	int freed = 0;
 
-	if(pgtable_cache_size > high) {
+	if (pgtable_cache_size > high) {
 		do {
-			if(pgd_quicklist)
+			if (pgd_quicklist)
 				free_pgd_slow(get_pgd_fast()), freed++;
-			if(pmd_quicklist)
+			if (pmd_quicklist)
 				free_pmd_slow(get_pmd_fast()), freed++;
-			if(pte_quicklist)
+			if (pte_quicklist)
 				free_pte_slow(get_pte_fast()), freed++;
-		} while(pgtable_cache_size > low);
+		} while (pgtable_cache_size > low);
 	}
 	return freed;
 }
 
+#if CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
+#define kmap_get_fixmap_pte(vaddr)					\
+	pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+
+static void __init kmap_init(void)
+{
+	unsigned long kmap_vstart;
+
+	/* cache the first kmap pte */
+	kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+	kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+
+	kmap_prot = PAGE_KERNEL;
+}
+
+#endif /* CONFIG_HIGHMEM */
+
 void show_mem(void)
 {
 	int i, free = 0, total = 0, reserved = 0;
@@ -145,19 +161,85 @@
 extern char _ftext, _etext, _fdata, _edata;
 extern char __init_begin, __init_end;
 
-void __init paging_init(void)
+static void __init fixrange_init (unsigned long start, unsigned long end,
+	pgd_t *pgd_base)
 {
-	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-	unsigned long max_dma, low;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	int i, j;
+	unsigned long vaddr;
+
+	vaddr = start;
+	i = __pgd_offset(vaddr);
+	j = __pmd_offset(vaddr);
+	pgd = pgd_base + i;
+
+	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+		pmd = (pmd_t *)pgd;
+		for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+			if (pmd_none(*pmd)) {
+				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+				set_pmd(pmd, __pmd(pte));
+				if (pte != pte_offset(pmd, 0))
+					BUG();
+			}
+			vaddr += PMD_SIZE;
+		}
+		j = 0;
+	}
+}
+
+void __init pagetable_init(void)
+{
+	unsigned long vaddr;
+	pgd_t *pgd, *pgd_base;
+	pmd_t *pmd;
+	pte_t *pte;
 
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
-	pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
+	pgd_init((unsigned long)swapper_pg_dir +
+	         sizeof(pgd_t ) * USER_PTRS_PER_PGD);
+
+	pgd_base = swapper_pg_dir;
+
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * Fixed mappings:
+	 */
+	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+	fixrange_init(vaddr, 0, pgd_base);
+
+	/*
+	 * Permanent kmaps:
+	 */
+	vaddr = PKMAP_BASE;
+	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+
+	pgd = swapper_pg_dir + __pgd_offset(vaddr);
+	pmd = pmd_offset(pgd, vaddr);
+	pte = pte_offset(pmd, vaddr);
+	pkmap_page_table = pte;
+#endif
+}
+
+void __init paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	unsigned long max_dma, high, low;
+
+	pagetable_init();
+
+#ifdef CONFIG_HIGHMEM
+	kmap_init();
+#endif
 
 	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 	low = max_low_pfn;
+	high = highend_pfn;
 
-#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+#ifdef CONFIG_ISA
 	if (low < max_dma)
 		zones_size[ZONE_DMA] = low;
 	else {
@@ -167,6 +249,9 @@
 #else
 	zones_size[ZONE_DMA] = low;
 #endif
+#ifdef CONFIG_HIGHMEM
+	zones_size[ZONE_HIGHMEM] = high - low;
+#endif
 
 	free_area_init(zones_size);
 }
@@ -201,8 +286,19 @@
 	unsigned long codesize, reservedpages, datasize, initsize;
 	unsigned long tmp, ram;
 
-	max_mapnr = num_physpages = max_low_pfn;
-	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+#if defined(CONFIG_DISCONTIGMEM) && defined(CONFIG_HIGHMEM)
+#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
+#endif
+
+#ifdef CONFIG_HIGHMEM
+	highstart_pfn = (KSEG1 - KSEG0) >> PAGE_SHIFT;
+	highmem_start_page = mem_map + highstart_pfn;
+	max_mapnr = num_physpages = highend_pfn;
+	num_mappedpages = max_low_pfn;
+#else
+	max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
+#endif
+	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
 	totalram_pages += free_all_bootmem();
 	totalram_pages -= setup_zero_pages();	/* Setup zeroed pages.  */
@@ -215,25 +311,43 @@
 				reservedpages++;
 		}
 
+#ifdef CONFIG_HIGHMEM
+	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
+		struct page *page = mem_map + tmp;
+
+		if (!page_is_ram(tmp)) {
+			SetPageReserved(page);
+			continue;
+		}
+		ClearPageReserved(page);
+		set_bit(PG_highmem, &page->flags);
+		atomic_set(&page->count, 1);
+		__free_page(page);
+		totalhigh_pages++;
+	}
+	totalram_pages += totalhigh_pages;
+#endif
+
 	codesize =  (unsigned long) &_etext - (unsigned long) &_ftext;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
-	       "%ldk data, %ldk init)\n",
+	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
+	       "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
 	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 	       ram << (PAGE_SHIFT-10),
 	       codesize >> 10,
 	       reservedpages << (PAGE_SHIFT-10),
 	       datasize >> 10,
-	       initsize >> 10);
+	       initsize >> 10,
+	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-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",
+		printk(KERN_INFO "Freeing initrd memory: %ldk freed\n",
 		       (end - start) >> 10);
 
 	for (; start < end; start += PAGE_SIZE) {
@@ -262,17 +376,17 @@
 		totalram_pages++;
 		addr += PAGE_SIZE;
 	}
-	printk("Freeing unused kernel memory: %dk freed\n",
+	printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n",
 	       (&__init_end - &__init_begin) >> 10);
 }
 
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = atomic_read(&shmem_nrpages);
+	val->sharedram = 0;
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
-	val->totalhigh = 0;
+	val->totalhigh = totalhigh_pages;
 	val->freehigh = nr_free_highpages();
 	val->mem_unit = PAGE_SIZE;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/ioremap.c linux/arch/mips/mm/ioremap.c
--- linux.orig/arch/mips/mm/ioremap.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips/mm/ioremap.c	2002-07-20 01:08:36.000000000 +0000
@@ -14,10 +14,10 @@
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+	phys_t size, phys_t phys_addr, unsigned long flags)
 {
-	unsigned long end;
+	phys_t end;
 	pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
 	                           | __WRITEABLE | flags);
 
@@ -39,10 +39,10 @@
 	} while (address && (address < end));
 }
 
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+	phys_t size, phys_t phys_addr, unsigned long flags)
 {
-	unsigned long end;
+	phys_t end;
 
 	address &= ~PGDIR_MASK;
 	end = address + size;
@@ -62,8 +62,8 @@
 	return 0;
 }
 
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
-				 unsigned long size, unsigned long flags)
+static int remap_area_pages(unsigned long address, phys_t phys_addr,
+	phys_t size, unsigned long flags)
 {
 	int error;
 	pgd_t * dir;
@@ -107,13 +107,14 @@
  * caller shouldn't need to know that small detail.
  */
 
-#define IS_LOW512(addr) (!((unsigned long)(addr) & ~0x1fffffffUL))
+#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL))
 
-void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
 {
-	void * addr;
 	struct vm_struct * area;
-	unsigned long offset, last_addr;
+	unsigned long offset;
+	phys_t last_addr;
+	void * addr;
 
 	/* Don't allow wraparound or zero size */
 	last_addr = phys_addr + size - 1;
@@ -124,7 +125,7 @@
 	 * Map objects in the low 512mb of address space using KSEG1, otherwise
 	 * map using page tables.
 	 */
-	if (IS_LOW512(phys_addr) && IS_LOW512(phys_addr + size - 1))
+	if (IS_LOW512(phys_addr) && IS_LOW512(last_addr))
 		return (void *) KSEG1ADDR(phys_addr);
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/loadmmu.c linux/arch/mips/mm/loadmmu.c
--- linux.orig/arch/mips/mm/loadmmu.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/mm/loadmmu.c	2002-07-20 01:08:27.000000000 +0000
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
@@ -29,17 +30,30 @@
 			  unsigned long end);
 void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
 void (*_flush_cache_sigtramp)(unsigned long addr);
-void (*_flush_page_to_ram)(struct page * page);
 void (*_flush_icache_range)(unsigned long start, unsigned long end);
 void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page);
 
+void (*_flush_page_to_ram)(struct page * page);
+void (*_flush_icache_all)(void);
+
+#ifdef CONFIG_NONCOHERENT_IO
+
 /* DMA cache operations. */
 void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
 void (*_dma_cache_wback)(unsigned long start, unsigned long size);
 void (*_dma_cache_inv)(unsigned long start, unsigned long size);
 
+EXPORT_SYMBOL(_dma_cache_wback_inv);
+EXPORT_SYMBOL(_dma_cache_wback);
+EXPORT_SYMBOL(_dma_cache_inv);
+
+#endif /* CONFIG_NONCOHERENT_IO */
+
+
 extern void ld_mmu_r23000(void);
 extern void ld_mmu_r4xx0(void);
+extern void ld_mmu_tx39(void);
+extern void ld_mmu_tx49(void);
 extern void ld_mmu_r5432(void);
 extern void ld_mmu_r6000(void);
 extern void ld_mmu_rm7k(void);
@@ -47,53 +61,72 @@
 extern void ld_mmu_andes(void);
 extern void ld_mmu_sb1(void);
 extern void ld_mmu_mips32(void);
+extern void r3k_tlb_init(void);
+extern void r4k_tlb_init(void);
+extern void sb1_tlb_init(void);
 
 void __init loadmmu(void)
 {
-
 	if (mips_cpu.options & MIPS_CPU_4KTLB) {
 #if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \
     defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \
     defined(CONFIG_CPU_NEVADA)
-		printk("Loading R4000 MMU routines.\n");
 		ld_mmu_r4xx0();
+		r4k_tlb_init();
 #endif
 #if defined(CONFIG_CPU_RM7000)
-               printk("Loading RM7000 MMU routines.\n");
-               ld_mmu_rm7k();
+		ld_mmu_rm7k();
+		r4k_tlb_init();
 #endif
-#if defined(CONFIG_CPU_R5432)
-		printk("Loading R5432 MMU routines.\n");
+#if defined(CONFIG_CPU_R5432) || defined(CONFIG_CPU_R5500)
 		ld_mmu_r5432();
+		r4k_tlb_init();
+#endif
+#if defined(CONFIG_CPU_TX49XX)
+		ld_mmu_tx49();
+		r4k_tlb_init();
 #endif
 
 #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-		printk("Loading MIPS32 MMU routines.\n");
 		ld_mmu_mips32();
+		r4k_tlb_init();
 #endif
 	} else switch(mips_cpu.cputype) {
 #ifdef CONFIG_CPU_R3000
 	case CPU_R2000:
 	case CPU_R3000:
 	case CPU_R3000A:
+	case CPU_R3081E:
+		ld_mmu_r23000();
+		r3k_tlb_init();
+		break;
 	case CPU_TX3912:
 	case CPU_TX3922:
 	case CPU_TX3927:
-	case CPU_R3081E:
-		printk("Loading R[23]000 MMU routines.\n");
-		ld_mmu_r23000();
+	case CPU_TX39XX:
+		ld_mmu_tx39();
+		r3k_tlb_init();
+		break;
+#endif
+#ifdef CONFIG_CPU_TX39XX
+	case CPU_TX3912:
+	case CPU_TX3922:
+	case CPU_TX3927:
+	case CPU_TX39XX:
+		ld_mmu_tx39();
+		r3k_tlb_init();
 		break;
 #endif
 #ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
-		printk("Loading R10000 MMU routines.\n");
 		ld_mmu_andes();
+		r4k_tlb_init();
 		break;
 #endif
 #ifdef CONFIG_CPU_SB1
 	case CPU_SB1:
-		printk("Loading SB1 MMU routines.\n");
 		ld_mmu_sb1();
+		sb1_tlb_init();
 		break;
 #endif
 	default:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/mips32.c linux/arch/mips/mm/mips32.c
--- linux.orig/arch/mips/mm/mips32.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/mips/mm/mips32.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1064 +0,0 @@
-/*
- * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * MIPS32 CPU variant specific MMU/Cache routines.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-#include <asm/bcache.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/mmu_context.h>
-
-/* CP0 hazard avoidance. */
-#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
-				     "nop; nop; nop; nop; nop; nop;\n\t" \
-				     ".set reorder\n\t")
-
-/* Primary cache parameters. */
-static int icache_size, dcache_size; /* Size in bytes */
-static int ic_lsize, dc_lsize;       /* LineSize in bytes */
-
-/* Secondary cache (if present) parameters. */
-static unsigned int scache_size, sc_lsize;	/* Again, in bytes */
-
-#include <asm/cacheops.h>
-#include <asm/mips32_cache.h>
-
-#undef DEBUG_CACHE
-
-/*
- * Dummy cache handling routines for machines without boardcaches
- */
-static void no_sc_noop(void) {}
-
-static struct bcache_ops no_sc_ops = {
-	(void *)no_sc_noop, (void *)no_sc_noop,
-	(void *)no_sc_noop, (void *)no_sc_noop
-};
-
-struct bcache_ops *bcops = &no_sc_ops;
-
-
-/*
- * Zero an entire page.
- */
-
-static void mips32_clear_page_dc(unsigned long page)
-{
-	unsigned long i;
-
-        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
-	        for (i=page; i<page+PAGE_SIZE; i+=dc_lsize) {
-		        __asm__ __volatile__(
-			        ".set\tnoreorder\n\t"
-				".set\tnoat\n\t"
-				".set\tmips3\n\t"
-				"cache\t%2,(%0)\n\t"
-				".set\tmips0\n\t"
-				".set\tat\n\t"
-				".set\treorder"
-				:"=r" (i)
-				:"0" (i),
-				"I" (Create_Dirty_Excl_D));
-		}
-	}
-	for (i=page; i<page+PAGE_SIZE; i+=4)
-	        *(unsigned long *)(i) = 0;
-}
-
-static void mips32_clear_page_sc(unsigned long page)
-{
-	unsigned long i;
-
-        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
-	        for (i=page; i<page+PAGE_SIZE; i+=sc_lsize) {
-		        __asm__ __volatile__(
-				".set\tnoreorder\n\t"
-				".set\tnoat\n\t"
-				".set\tmips3\n\t"
-				"cache\t%2,(%0)\n\t"
-				".set\tmips0\n\t"
-				".set\tat\n\t"
-				".set\treorder"
-				:"=r" (i)
-				:"0" (i),
-				"I" (Create_Dirty_Excl_SD));
-		}
-	}
-	for (i=page; i<page+PAGE_SIZE; i+=4)
-	        *(unsigned long *)(i) = 0;
-}
-
-static void mips32_copy_page_dc(unsigned long to, unsigned long from)
-{
-	unsigned long i;
-
-        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
-	        for (i=to; i<to+PAGE_SIZE; i+=dc_lsize) {
-		        __asm__ __volatile__(
-			        ".set\tnoreorder\n\t"
-				".set\tnoat\n\t"
-				".set\tmips3\n\t"
-				"cache\t%2,(%0)\n\t"
-				".set\tmips0\n\t"
-				".set\tat\n\t"
-				".set\treorder"
-				:"=r" (i)
-				:"0" (i),
-				"I" (Create_Dirty_Excl_D));
-		}
-	}
-	for (i=0; i<PAGE_SIZE; i+=4)
-	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
-}
-
-static void mips32_copy_page_sc(unsigned long to, unsigned long from)
-{
-	unsigned long i;
-
-        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
-	        for (i=to; i<to+PAGE_SIZE; i+=sc_lsize) {
-		        __asm__ __volatile__(
-				".set\tnoreorder\n\t"
-				".set\tnoat\n\t"
-				".set\tmips3\n\t"
-				"cache\t%2,(%0)\n\t"
-				".set\tmips0\n\t"
-				".set\tat\n\t"
-				".set\treorder"
-				:"=r" (i)
-				:"0" (i),
-				"I" (Create_Dirty_Excl_SD));
-		}
-	}
-	for (i=0; i<PAGE_SIZE; i+=4)
-	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
-}
-
-static inline void mips32_flush_cache_all_sc(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache(); blast_icache(); blast_scache();
-	__restore_flags(flags);
-}
-
-static inline void mips32_flush_cache_all_pc(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache(); blast_icache();
-	__restore_flags(flags);
-}
-
-static void
-mips32_flush_cache_range_sc(struct mm_struct *mm,
-			 unsigned long start,
-			 unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if(mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if(vma) {
-		if(mm->context != current->mm->context) {
-			mips32_flush_cache_all_sc();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-
-			__save_and_cli(flags);
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID)
-					blast_scache_page(start);
-				start += PAGE_SIZE;
-			}
-			__restore_flags(flags);
-		}
-	}
-}
-
-static void mips32_flush_cache_range_pc(struct mm_struct *mm,
-				     unsigned long start,
-				     unsigned long end)
-{
-	if(mm->context != 0) {
-		unsigned long flags;
-
-#ifdef DEBUG_CACHE
-		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-		__save_and_cli(flags);
-		blast_dcache(); blast_icache();
-		__restore_flags(flags);
-	}
-}
-
-/*
- * On architectures like the Sparc, we could get rid of lines in
- * the cache created only by a certain context, but on the MIPS
- * (and actually certain Sparc's) we cannot.
- */
-static void mips32_flush_cache_mm_sc(struct mm_struct *mm)
-{
-	if(mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		mips32_flush_cache_all_sc();
-	}
-}
-
-static void mips32_flush_cache_mm_pc(struct mm_struct *mm)
-{
-	if(mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		mips32_flush_cache_all_pc();
-	}
-}
-
-
-
-
-
-static void mips32_flush_cache_page_sc(struct vm_area_struct *vma,
-				    unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm->context != current->active_mm->context) {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache_page_indexed(page);
-		blast_scache_page_indexed(page);
-	} else
-		blast_scache_page(page);
-out:
-	__restore_flags(flags);
-}
-
-static void mips32_flush_cache_page_pc(struct vm_area_struct *vma,
-				    unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since Mips32 caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm == current->active_mm) {
-		blast_dcache_page(page);
-	} else {
-		/* Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (dcache_size - 1)));
-		blast_dcache_page_indexed(page);
-	}
-out:
-	__restore_flags(flags);
-}
-
-/* If the addresses passed to these routines are valid, they are
- * either:
- *
- * 1) In KSEG0, so we can do a direct flush of the page.
- * 2) In KSEG2, and since every process can translate those
- *    addresses all the time in kernel mode we can do a direct
- *    flush.
- * 3) In KSEG1, no flush necessary.
- */
-static void mips32_flush_page_to_ram_sc(struct page *page)
-{
-	blast_scache_page((unsigned long)page_address(page));
-}
-
-static void mips32_flush_page_to_ram_pc(struct page *page)
-{
-	blast_dcache_page((unsigned long)page_address(page));
-}
-
-static void
-mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
-{
-	/*
-	 * We did an scache flush therefore PI is already clean.
-	 */
-}
-
-static void
-mips32_flush_icache_range(unsigned long start, unsigned long end)
-{
-	flush_cache_all();
-}
-
-static void
-mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
-	int address;
-
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-
-	address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1));
-	blast_icache_page_indexed(address);
-}
-
-/*
- * Writeback and invalidate the primary cache dcache before DMA.
- */
-static void
-mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-	unsigned int flags;
-
-	if (size >= dcache_size) {
-		flush_cache_all();
-	} else {
-	        __save_and_cli(flags);
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
-		while (1) {
-			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
-			if (a == end) break;
-			a += dc_lsize;
-		}
-		__restore_flags(flags);
-	}
-	bc_wback_inv(addr, size);
-}
-
-static void
-mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-
-	if (size >= scache_size) {
-		flush_cache_all();
-		return;
-	}
-
-	a = addr & ~(sc_lsize - 1);
-	end = (addr + size) & ~(sc_lsize - 1);
-	while (1) {
-		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
-		if (a == end) break;
-		a += sc_lsize;
-	}
-}
-
-static void
-mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-	unsigned int flags;
-
-	if (size >= dcache_size) {
-		flush_cache_all();
-	} else {
-	        __save_and_cli(flags);
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
-		while (1) {
-			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
-			if (a == end) break;
-			a += dc_lsize;
-		}
-		__restore_flags(flags);
-	}
-
-	bc_inv(addr, size);
-}
-
-static void
-mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-
-	if (size >= scache_size) {
-		flush_cache_all();
-		return;
-	}
-
-	a = addr & ~(sc_lsize - 1);
-	end = (addr + size) & ~(sc_lsize - 1);
-	while (1) {
-		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
-		if (a == end) break;
-		a += sc_lsize;
-	}
-}
-
-static void
-mips32_dma_cache_wback(unsigned long addr, unsigned long size)
-{
-	panic("mips32_dma_cache called - should not happen.\n");
-}
-
-/*
- * While we're protected against bad userland addresses we don't care
- * very much about what happens in that case.  Usually a segmentation
- * fault will dump the process later on anyway ...
- */
-static void mips32_flush_cache_sigtramp(unsigned long addr)
-{
-	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
-	protected_flush_icache_line(addr & ~(ic_lsize - 1));
-}
-
-#undef DEBUG_TLB
-#undef DEBUG_TLBUPDATE
-
-void flush_tlb_all(void)
-{
-	unsigned long flags;
-	unsigned long old_ctx;
-	int entry;
-
-#ifdef DEBUG_TLB
-	printk("[tlball]");
-#endif
-
-	__save_and_cli(flags);
-	/* Save old context and create impossible VPN2 value */
-	old_ctx = (get_entryhi() & 0xff);
-	set_entryhi(KSEG0);
-	set_entrylo0(0);
-	set_entrylo1(0);
-	BARRIER;
-
-	entry = get_wired();
-
-	/* Blast 'em all away. */
-	while(entry < mips_cpu.tlbsize) {
-	        /* Make sure all entries differ. */  
-	        set_entryhi(KSEG0+entry*0x2000);
-		set_index(entry);
-		BARRIER;
-		tlb_write_indexed();
-		BARRIER;
-		entry++;
-	}
-	BARRIER;
-	set_entryhi(old_ctx);
-	__restore_flags(flags);
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-		unsigned long flags;
-
-#ifdef DEBUG_TLB
-		printk("[tlbmm<%d>]", mm->context);
-#endif
-		__save_and_cli(flags);
-		get_new_mmu_context(mm, asid_cache);
-		if (mm == current->active_mm)
-			set_entryhi(mm->context & 0xff);
-		__restore_flags(flags);
-	}
-}
-
-void flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				unsigned long end)
-{
-	if(mm->context != 0) {
-		unsigned long flags;
-		int size;
-
-#ifdef DEBUG_TLB
-		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
-		       start, end);
-#endif
-		__save_and_cli(flags);
-		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-		size = (size + 1) >> 1;
-		if(size <= mips_cpu.tlbsize/2) {
-			int oldpid = (get_entryhi() & 0xff);
-			int newpid = (mm->context & 0xff);
-
-			start &= (PAGE_MASK << 1);
-			end += ((PAGE_SIZE << 1) - 1);
-			end &= (PAGE_MASK << 1);
-			while(start < end) {
-				int idx;
-
-				set_entryhi(start | newpid);
-				start += (PAGE_SIZE << 1);
-				BARRIER;
-				tlb_probe();
-				BARRIER;
-				idx = get_index();
-				set_entrylo0(0);
-				set_entrylo1(0);
-				if(idx < 0)
-					continue;
-				/* Make sure all entries differ. */
-				set_entryhi(KSEG0+idx*0x2000);
-				BARRIER;
-				tlb_write_indexed();
-				BARRIER;
-			}
-			set_entryhi(oldpid);
-		} else {
-			get_new_mmu_context(mm, asid_cache);
-			if (mm == current->active_mm)
-				set_entryhi(mm->context & 0xff);
-		}
-		__restore_flags(flags);
-	}
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	if (vma->vm_mm->context != 0) {
-		unsigned long flags;
-		int oldpid, newpid, idx;
-
-#ifdef DEBUG_TLB
-		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
-#endif
-		newpid = (vma->vm_mm->context & 0xff);
-		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
-		oldpid = (get_entryhi() & 0xff);
-		set_entryhi(page | newpid);
-		BARRIER;
-		tlb_probe();
-		BARRIER;
-		idx = get_index();
-		set_entrylo0(0);
-		set_entrylo1(0);
-		if(idx < 0)
-			goto finish;
-		/* Make sure all entries differ. */  
-		set_entryhi(KSEG0+idx*0x2000);
-		BARRIER;
-		tlb_write_indexed();
-
-	finish:
-		BARRIER;
-		set_entryhi(oldpid);
-		__restore_flags(flags);
-	}
-}
-
-void pgd_init(unsigned long page)
-{
-	unsigned long *p = (unsigned long *) page;
-	int i;
-
-	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
-		p[i + 0] = (unsigned long) invalid_pte_table;
-		p[i + 1] = (unsigned long) invalid_pte_table;
-		p[i + 2] = (unsigned long) invalid_pte_table;
-		p[i + 3] = (unsigned long) invalid_pte_table;
-		p[i + 4] = (unsigned long) invalid_pte_table;
-		p[i + 5] = (unsigned long) invalid_pte_table;
-		p[i + 6] = (unsigned long) invalid_pte_table;
-		p[i + 7] = (unsigned long) invalid_pte_table;
-	}
-}
-
-/* 
- * Updates the TLB with the new pte(s).
- */
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
-{
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-	int idx, pid;
-
-	/*
-	 * Handle debugger faulting in for debugee.
-	 */
-	if (current->active_mm != vma->vm_mm)
-		return;
-
-	pid = get_entryhi() & 0xff;
-
-#ifdef DEBUG_TLB
-	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
-		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
-		       (int) (vma->vm_mm->context & 0xff), pid);
-	}
-#endif
-
-	__save_and_cli(flags);
-	address &= (PAGE_MASK << 1);
-	set_entryhi(address | (pid));
-	pgdp = pgd_offset(vma->vm_mm, address);
-	BARRIER;
-	tlb_probe();
-	BARRIER;
-	pmdp = pmd_offset(pgdp, address);
-	idx = get_index();
-	ptep = pte_offset(pmdp, address);
-	BARRIER;
-	set_entrylo0(pte_val(*ptep++) >> 6);
-	set_entrylo1(pte_val(*ptep) >> 6);
-	set_entryhi(address | (pid));
-	BARRIER;
-	if(idx < 0) {
-		tlb_write_random();
-	} else {
-		tlb_write_indexed();
-	}
-	BARRIER;
-	set_entryhi(pid);
-	BARRIER;
-	__restore_flags(flags);
-}
-
-void show_regs(struct pt_regs * regs)
-{
-	/* Saved main processor registers. */
-	printk("$0 : %08lx %08lx %08lx %08lx\n",
-	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
-	printk("$4 : %08lx %08lx %08lx %08lx\n",
-               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
-	printk("$8 : %08lx %08lx %08lx %08lx\n",
-	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
-	printk("$12: %08lx %08lx %08lx %08lx\n",
-               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
-	printk("$16: %08lx %08lx %08lx %08lx\n",
-	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
-	printk("$20: %08lx %08lx %08lx %08lx\n",
-               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
-	printk("$24: %08lx %08lx\n",
-	       regs->regs[24], regs->regs[25]);
-	printk("$28: %08lx %08lx %08lx %08lx\n",
-	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
-
-	/* Saved cp0 registers. */
-	printk("epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
-}
-			
-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-				      unsigned long entryhi, unsigned long pagemask)
-{
-        unsigned long flags;
-        unsigned long wired;
-        unsigned long old_pagemask;
-        unsigned long old_ctx;
-
-        __save_and_cli(flags);
-        /* Save old context and create impossible VPN2 value */
-        old_ctx = (get_entryhi() & 0xff);
-        old_pagemask = get_pagemask();
-        wired = get_wired();
-        set_wired (wired + 1);
-        set_index (wired);
-        BARRIER;    
-        set_pagemask (pagemask);
-        set_entryhi(entryhi);
-        set_entrylo0(entrylo0);
-        set_entrylo1(entrylo1);
-        BARRIER;    
-        tlb_write_indexed();
-        BARRIER;    
-    
-        set_entryhi(old_ctx);
-        BARRIER;    
-        set_pagemask (old_pagemask);
-        flush_tlb_all();    
-        __restore_flags(flags);
-}
-
-/* Detect and size the various caches. */
-static void __init probe_icache(unsigned long config)
-{
-        unsigned long config1;
-	unsigned int lsize;
-
-        if (!(config & (1 << 31))) {
-	        /* 
-		 * Not a MIPS32 complainant CPU. 
-		 * Config 1 register not supported, we assume R4k style.
-		 */
-	        icache_size = 1 << (12 + ((config >> 9) & 7));
-		ic_lsize = 16 << ((config >> 5) & 1);
-		mips_cpu.icache.linesz = ic_lsize;
-		
-		/* 
-		 * We cannot infer associativity - assume direct map
-		 * unless probe template indicates otherwise
-		 */
-		if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
-		mips_cpu.icache.sets = 
-			(icache_size / ic_lsize) / mips_cpu.icache.ways;
-	} else {
-	       config1 = read_mips32_cp0_config1(); 
-
-	       if ((lsize = ((config1 >> 19) & 7)))
-		       mips_cpu.icache.linesz = 2 << lsize;
-	       else 
-		       mips_cpu.icache.linesz = lsize;
-	       mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
-	       mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
-
-	       ic_lsize = mips_cpu.icache.linesz;
-	       icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * 
-		             ic_lsize;
-	}
-	printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
-	       icache_size >> 10, ic_lsize, mips_cpu.icache.ways);
-}
-
-static void __init probe_dcache(unsigned long config)
-{
-        unsigned long config1;
-	unsigned int lsize;
-
-        if (!(config & (1 << 31))) {
-	        /* 
-		 * Not a MIPS32 complainant CPU. 
-		 * Config 1 register not supported, we assume R4k style.
-		 */  
-		dcache_size = 1 << (12 + ((config >> 6) & 7));
-		dc_lsize = 16 << ((config >> 4) & 1);
-		mips_cpu.dcache.linesz = dc_lsize;
-		/* 
-		 * We cannot infer associativity - assume direct map
-		 * unless probe template indicates otherwise
-		 */
-		if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
-		mips_cpu.dcache.sets = 
-			(dcache_size / dc_lsize) / mips_cpu.dcache.ways;
-	} else {
-	        config1 = read_mips32_cp0_config1();
-
-		if ((lsize = ((config1 >> 10) & 7)))
-		        mips_cpu.dcache.linesz = 2 << lsize;
-		else 
-		        mips_cpu.dcache.linesz= lsize;
-		mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
-		mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
-
-		dc_lsize = mips_cpu.dcache.linesz;
-		dcache_size = 
-			mips_cpu.dcache.sets * mips_cpu.dcache.ways
-			* dc_lsize;
-	}
-	printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n",
-	       dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways);
-}
-
-
-/* If you even _breathe_ on this function, look at the gcc output
- * and make sure it does not pop things on and off the stack for
- * the cache sizing loop that executes in KSEG1 space or else
- * you will crash and burn badly.  You have been warned.
- */
-static int __init probe_scache(unsigned long config)
-{
-	extern unsigned long stext;
-	unsigned long flags, addr, begin, end, pow2;
-	int tmp;
-
-	if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT)
-		return 0;
-
-	tmp = ((config >> 17) & 1);
-	if(tmp)
-		return 0;
-	tmp = ((config >> 22) & 3);
-	switch(tmp) {
-	case 0:
-		sc_lsize = 16;
-		break;
-	case 1:
-		sc_lsize = 32;
-		break;
-	case 2:
-		sc_lsize = 64;
-		break;
-	case 3:
-		sc_lsize = 128;
-		break;
-	}
-
-	begin = (unsigned long) &stext;
-	begin &= ~((4 * 1024 * 1024) - 1);
-	end = begin + (4 * 1024 * 1024);
-
-	/* This is such a bitch, you'd think they would make it
-	 * easy to do this.  Away you daemons of stupidity!
-	 */
-	__save_and_cli(flags);
-
-	/* Fill each size-multiple cache line with a valid tag. */
-	pow2 = (64 * 1024);
-	for(addr = begin; addr < end; addr = (begin + pow2)) {
-		unsigned long *p = (unsigned long *) addr;
-		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
-		pow2 <<= 1;
-	}
-
-	/* Load first line with zero (therefore invalid) tag. */
-	set_taglo(0);
-	set_taghi(0);
-	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
-	__asm__ __volatile__("\n\t.set noreorder\n\t"
-			     ".set mips3\n\t"
-			     "cache 8, (%0)\n\t"
-			     ".set mips0\n\t"
-			     ".set reorder\n\t" : : "r" (begin));
-	__asm__ __volatile__("\n\t.set noreorder\n\t"
-			     ".set mips3\n\t"
-			     "cache 9, (%0)\n\t"
-			     ".set mips0\n\t"
-			     ".set reorder\n\t" : : "r" (begin));
-	__asm__ __volatile__("\n\t.set noreorder\n\t"
-			     ".set mips3\n\t"
-			     "cache 11, (%0)\n\t"
-			     ".set mips0\n\t"
-			     ".set reorder\n\t" : : "r" (begin));
-
-	/* Now search for the wrap around point. */
-	pow2 = (128 * 1024);
-	tmp = 0;
-	for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
-		__asm__ __volatile__("\n\t.set noreorder\n\t"
-				     ".set mips3\n\t"
-				     "cache 7, (%0)\n\t"
-				     ".set mips0\n\t"
-				     ".set reorder\n\t" : : "r" (addr));
-		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
-		if(!get_taglo())
-			break;
-		pow2 <<= 1;
-	}
-	__restore_flags(flags);
-	addr -= begin;
-	printk("Secondary cache sized at %dK linesize %d bytes.\n",
-	       (int) (addr >> 10), sc_lsize);
-	scache_size = addr;
-	return 1;
-}
-
-static void __init setup_noscache_funcs(void)
-{
-	_clear_page = (void *)mips32_clear_page_dc;
-	_copy_page = (void *)mips32_copy_page_dc;
-	_flush_cache_all = mips32_flush_cache_all_pc;
-	___flush_cache_all = mips32_flush_cache_all_pc;
-	_flush_cache_mm = mips32_flush_cache_mm_pc;
-	_flush_cache_range = mips32_flush_cache_range_pc;
-	_flush_cache_page = mips32_flush_cache_page_pc;
-	_flush_page_to_ram = mips32_flush_page_to_ram_pc;
-
-	_flush_icache_page = mips32_flush_icache_page;
-
-	_dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc;
-	_dma_cache_wback = mips32_dma_cache_wback;
-	_dma_cache_inv = mips32_dma_cache_inv_pc;
-}
-
-static void __init setup_scache_funcs(void)
-{
-        _flush_cache_all = mips32_flush_cache_all_sc;
-        ___flush_cache_all = mips32_flush_cache_all_sc;
-	_flush_cache_mm = mips32_flush_cache_mm_sc;
-	_flush_cache_range = mips32_flush_cache_range_sc;
-	_flush_cache_page = mips32_flush_cache_page_sc;
-	_flush_page_to_ram = mips32_flush_page_to_ram_sc;
-	_clear_page = (void *)mips32_clear_page_sc;
-	_copy_page = (void *)mips32_copy_page_sc;
-
-	_flush_icache_page = mips32_flush_icache_page_s;
-
-	_dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc;
-	_dma_cache_wback = mips32_dma_cache_wback;
-	_dma_cache_inv = mips32_dma_cache_inv_sc;
-}
-
-typedef int (*probe_func_t)(unsigned long);
-
-static inline void __init setup_scache(unsigned int config)
-{
-	probe_func_t probe_scache_kseg1;
-	int sc_present = 0;
-
-	/* Maybe the cpu knows about a l2 cache? */
-	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
-	sc_present = probe_scache_kseg1(config);
-
-	if (sc_present) {
-	  	mips_cpu.scache.linesz = sc_lsize;
-		/* 
-		 * We cannot infer associativity - assume direct map
-		 * unless probe template indicates otherwise
-		 */
-		if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1;
-		mips_cpu.scache.sets = 
-		  (scache_size / sc_lsize) / mips_cpu.scache.ways;
-
-		setup_scache_funcs();
-		return;
-	}
-
-	setup_noscache_funcs();
-}
-
-static void __init probe_tlb(unsigned long config)
-{
-        unsigned long config1;
-
-        if (!(config & (1 << 31))) {
-	        /* 
-		 * Not a MIPS32 complainant CPU. 
-		 * Config 1 register not supported, we assume R4k style.
-		 */  
-	        mips_cpu.tlbsize = 48;
-	} else {
-	        config1 = read_mips32_cp0_config1();
-		if (!((config >> 7) & 3))
-		        panic("No MMU present");
-		else
-		        mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
-	}	
-
-	printk("Number of TLB entries %d.\n", mips_cpu.tlbsize);
-}
-
-void __init ld_mmu_mips32(void)
-{
-	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
-
-	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
-
-#ifdef CONFIG_MIPS_UNCACHED
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-#else
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif
-
-	probe_icache(config);
-	probe_dcache(config);
-	setup_scache(config);
-	probe_tlb(config);
-
-	_flush_cache_sigtramp = mips32_flush_cache_sigtramp;
-	_flush_icache_range = mips32_flush_icache_range;	/* Ouch */
-
-	__flush_cache_all();
-	write_32bit_cp0_register(CP0_WIRED, 0);
-
-	/*
-	 * You should never change this register:
-	 *   - The entire mm handling assumes the c0_pagemask register to
-	 *     be set for 4kb pages.
-	 */
-	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
-	flush_tlb_all();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/pg-andes.S linux/arch/mips/mm/pg-andes.S
--- linux.orig/arch/mips/mm/pg-andes.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/pg-andes.S	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,66 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997,  1998,  1999,  2000 Ralf Baechle ralf@gnu.org
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/offset.h>
+
+	.text
+	.set	mips4
+	.set	noat
+
+/*
+ * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
+ * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
+ * an Origin 200.
+ */
+
+LEAF(andes_clear_page)
+	LONG_ADDIU	AT, a0, _PAGE_SIZE
+1:	pref		7, 512(a0)
+	LONG_S		zero, 0*SZREG(a0)
+	LONG_S		zero, 1*SZREG(a0)
+	LONG_S		zero, 2*SZREG(a0)
+	LONG_S		zero, 3*SZREG(a0)
+	LONG_ADDIU	a0, a0, 8*SZREG
+	LONG_S		zero, -4*SZREG(a0)
+	LONG_S		zero, -3*SZREG(a0)
+	LONG_S		zero, -2*SZREG(a0)
+	LONG_S		zero, -1*SZREG(a0)
+	bne		AT, a0, 1b
+	j		ra
+	.end		andes_clear_page
+	END(andes_clear_page)
+
+LEAF(andes_copy_page)
+	LONG_ADDIU	AT, a0, _PAGE_SIZE
+1:	pref		0, 2*128(a1)
+	pref		1, 2*128(a0)
+	LONG_L		a3, 0*SZREG(a1)
+	LONG_L		a2, 1*SZREG8(a1)
+	LONG_L		v1, 2*SZREG(a1)
+	LONG_L		v0, 3*SZREG(a1)
+	LONG_S		a3, 0*SZREG(a0)
+	LONG_S		a2, 1*SZREG(a0)
+	LONG_S		v1, 2*SZREG(a0)
+	LONG_S		v0, 3*SZREG(a0)
+	LONG_ADDIU	a0, a0, 8*SZREG
+	LONG_ADDIU	a1, a1, 8*SZREG
+	LONG_L		a3, -4*SZREG(a1)
+	LONG_L		a2, -3*SZREG(a1)
+	LONG_L		v1, -2*SZREG(a1)
+	LONG_L		v0, -1*SZREG(a1)
+	LONG_S		a3, -4*SZREG(a0)
+	LONG_S		a2, -3*SZREG(a0)
+	LONG_S		v1, -2*SZREG(a0)
+	LONG_S		v0, -1*SZREG(a0)
+	bne		AT, a0,1b
+	j		ra
+	END(andes_copy_page)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/pg-mips32.c linux/arch/mips/mm/pg-mips32.c
--- linux.orig/arch/mips/mm/pg-mips32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/pg-mips32.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,140 @@
+/*
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS32 CPU variant specific MMU/Cache routines.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cacheops.h>
+#include <asm/cpu.h>
+
+extern int dc_lsize, ic_lsize, sc_lsize;
+
+/*
+ * Zero an entire page.
+ */
+
+void mips32_clear_page_dc(unsigned long page)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
+	        for (i=page; i<page+PAGE_SIZE; i+=dc_lsize) {
+		        __asm__ __volatile__(
+			        ".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=page; i<page+PAGE_SIZE; i+=4)
+	        *(unsigned long *)(i) = 0;
+}
+
+void mips32_clear_page_sc(unsigned long page)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
+	        for (i=page; i<page+PAGE_SIZE; i+=sc_lsize) {
+		        __asm__ __volatile__(
+				".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=page; i<page+PAGE_SIZE; i+=4)
+	        *(unsigned long *)(i) = 0;
+}
+
+void mips32_copy_page_dc(unsigned long to, unsigned long from)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
+	        for (i=to; i<to+PAGE_SIZE; i+=dc_lsize) {
+		        __asm__ __volatile__(
+			        ".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=4)
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
+
+void mips32_copy_page_sc(unsigned long to, unsigned long from)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
+	        for (i=to; i<to+PAGE_SIZE; i+=sc_lsize) {
+		        __asm__ __volatile__(
+				".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=4)
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/pg-r3k.c linux/arch/mips/mm/pg-r3k.c
--- linux.orig/arch/mips/mm/pg-r3k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/pg-r3k.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+/* page functions */
+void r3k_clear_page(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"addiu\t$1,%0,%2\n"
+		"1:\tsw\t$0,(%0)\n\t"
+		"sw\t$0,4(%0)\n\t"
+		"sw\t$0,8(%0)\n\t"
+		"sw\t$0,12(%0)\n\t"
+		"addiu\t%0,32\n\t"
+		"sw\t$0,-16(%0)\n\t"
+		"sw\t$0,-12(%0)\n\t"
+		"sw\t$0,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t$0,-4(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE)
+		: "memory");
+}
+
+void r3k_copy_page(void * to, void * from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		"addiu\t$1,%0,%8\n"
+		"1:\tlw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"addiu\t%0,64\n\t"
+		"addiu\t%1,64\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: "=r" (dummy1), "=r" (dummy2),
+		  "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		: "0" (to), "1" (from),
+		  "I" (PAGE_SIZE));
+}
+
+/*
+ * Initialize new page directory with pointers to invalid ptes
+ */
+void pgd_init(unsigned long page)
+{
+	unsigned long dummy1, dummy2;
+
+	/*
+	 * The plain and boring version for the R3000.  No cache flushing
+	 * stuff is implemented since the R3000 has physical caches.
+	 */
+	__asm__ __volatile__(
+		".set\tnoreorder\n"
+		"1:\tsw\t%2, (%0)\n\t"
+		"sw\t%2, 4(%0)\n\t"
+		"sw\t%2, 8(%0)\n\t"
+		"sw\t%2, 12(%0)\n\t"
+		"sw\t%2, 16(%0)\n\t"
+		"sw\t%2, 20(%0)\n\t"
+		"sw\t%2, 24(%0)\n\t"
+		"sw\t%2, 28(%0)\n\t"
+		"subu\t%1, 1\n\t"
+		"bnez\t%1, 1b\n\t"
+		"addiu\t%0, 32\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2)
+		:"r" ((unsigned long) invalid_pte_table), "0" (page),
+		 "1" (USER_PTRS_PER_PGD / 8));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/pg-r4k.S linux/arch/mips/mm/pg-r4k.S
--- linux.orig/arch/mips/mm/pg-r4k.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/pg-r4k.S	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,690 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997,  1998,  1999,  2000 Ralf Baechle ralf@gnu.org
+ */
+#include <linux/config.h>
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/cacheops.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define PGD_SIZE	0x2000
+#else
+#define PGD_SIZE	0x1000
+#endif
+
+	.text
+	.set	mips3
+	.set	noat
+
+/*
+ * Zero an entire page.  Basically a simple unrolled loop should do the
+ * job but we want more performance by saving memory bus bandwidth.  We
+ * have five flavours of the routine available for:
+ *
+ * - 16byte cachelines and no second level cache
+ * - 32byte cachelines second level cache
+ * - a version which handles the buggy R4600 v1.x
+ * - a version which handles the buggy R4600 v2.0
+ * - Finally a last version without fancy cache games for the SC and MC
+ *   versions of R4000 and R4400.
+ */
+
+LEAF(r4k_clear_page_d16)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_D, (a0)
+	sd	zero, (a0)
+	sd	zero, 8(a0)
+	cache	Create_Dirty_Excl_D, 16(a0)
+	sd	zero, 16(a0)
+	sd	zero, 24(a0)
+	addiu	a0, 64
+	cache	Create_Dirty_Excl_D, -32(a0)
+	sd	zero, -32(a0)
+	sd	zero, -24(a0)
+	cache	Create_Dirty_Excl_D, -16(a0)
+	sd	zero, -16(a0)
+	sd	zero, -8(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_clear_page_d16)
+
+LEAF(r4k_clear_page_d32)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_D, (a0)
+	sd	zero, (a0)
+	sd	zero, 8(a0)
+	sd	zero, 16(a0)
+	sd	zero, 24(a0)
+	addiu	a0, 64
+	cache	Create_Dirty_Excl_D, -32(a0)
+	sd	zero, -32(a0)
+	sd	zero, -24(a0)
+	sd	zero, -16(a0)
+	sd	zero, -8(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_clear_page_d32)
+
+/*
+ * This flavour of r4k_clear_page is for the R4600 V1.x.  Cite from the
+ * IDT R4600 V1.7 errata:
+ *
+ *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
+ *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
+ *      executed if there is no other dcache activity. If the dcache is
+ *      accessed for another instruction immeidately preceding when these
+ *      cache instructions are executing, it is possible that the dcache 
+ *      tag match outputs used by these cache instructions will be 
+ *      incorrect. These cache instructions should be preceded by at least
+ *      four instructions that are not any kind of load or store 
+ *      instruction.
+ *
+ *      This is not allowed:    lw
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              cache       Hit_Writeback_Invalidate_D
+ *
+ *      This is allowed:        lw
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              cache       Hit_Writeback_Invalidate_D
+ */
+
+LEAF(r4k_clear_page_r4600_v1)
+	addiu	AT, a0, _PAGE_SIZE
+1:	nop
+	nop
+	nop
+	nop
+	cache	Create_Dirty_Excl_D, (a0)
+	sd	zero, (a0)
+	sd	zero, 8(a0)
+	sd	zero, 16(a0)
+	sd	zero, 24(a0)
+	addiu	a0, 64
+	nop
+	nop
+	nop
+	cache	Create_Dirty_Excl_D, -32(a0)
+	sd	zero, -32(a0)
+	sd	zero, -24(a0)
+	sd	zero, -16(a0)
+	sd	zero, -8(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_clear_page_r4600_v1)
+
+LEAF(r4k_clear_page_r4600_v2)
+	mfc0	a1, CP0_STATUS
+	ori	AT, a1, 1
+	xori	AT, 1
+	mtc0	AT, CP0_STATUS
+	nop
+	nop
+	nop
+
+	.set	volatile
+	la	AT, KSEG1
+	lw	zero, (AT)
+	.set	novolatile
+
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_D, (a0)
+	sd	zero, (a0)
+	sd	zero, 8(a0)
+	sd	zero, 16(a0)
+	sd	zero, 24(a0)
+	addiu	a0, 64
+	cache	Create_Dirty_Excl_D, -32(a0)
+	sd	zero, -32(a0)
+	sd	zero, -24(a0)
+	sd	zero, -16(a0)
+	sd	zero, -8(a0)
+	bne	AT, a0, 1b
+
+	mfc0	AT, CP0_STATUS			# __restore_flags
+	andi	a1, 1
+	ori	AT, 1
+	xori	AT, 1
+	or	a1, AT
+	mtc0	a1, CP0_STATUS
+	nop
+	nop
+	nop
+
+	jr	ra
+	END(r4k_clear_page_r4600_v2)
+
+/*
+ * The next 4 versions are optimized for all possible scache configurations
+ * of the SC / MC versions of R4000 and R4400 ...
+ *
+ * Todo: For even better performance we should have a routine optimized for
+ * every legal combination of dcache / scache linesize.  When I (Ralf) tried
+ * this the kernel crashed shortly after mounting the root filesystem.  CPU
+ * bug?  Weirdo cache instruction semantics?
+ */
+
+LEAF(r4k_clear_page_s16)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_SD, (a0)
+	sd	zero, (a0)
+	sd	zero, 8(a0)
+	cache	Create_Dirty_Excl_SD, 16(a0)
+	sd	zero, 16(a0)
+	sd	zero, 24(a0)
+	addiu	a0, 64
+	cache	Create_Dirty_Excl_SD, -32(a0)
+	sd	zero, -32(a0)
+	sd	zero, -24(a0)
+	cache	Create_Dirty_Excl_SD, -16(a0)
+	sd	zero, -16(a0)
+	sd	zero, -8(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_clear_page_s16)
+
+LEAF(r4k_clear_page_s32)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_SD, (a0)
+	sd	zero, (a0)
+	sd	zero, 8(a0)
+	sd	zero, 16(a0)
+	sd	zero, 24(a0)
+	addiu	a0, 64
+	cache	Create_Dirty_Excl_SD, -32(a0)
+	sd	zero, -32(a0)
+	sd	zero, -24(a0)
+	sd	zero, -16(a0)
+	sd	zero, -8(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_clear_page_s32)
+
+LEAF(r4k_clear_page_s64)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_SD, (a0)
+	sd	zero, (a0)
+	sd	zero, 8(a0)
+	sd	zero, 16(a0)
+	sd	zero, 24(a0)
+	addiu	a0, 64
+	sd	zero, -32(a0)
+	sd	zero, -24(a0)
+	sd	zero, -16(a0)
+	sd	zero, -8(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_clear_page_s64)
+
+LEAF(r4k_clear_page_s128)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_SD, (a0)
+	sd	zero, (a0)
+	sd	zero, 8(a0)
+	sd	zero, 16(a0)
+	sd	zero, 24(a0)
+	sd	zero, 32(a0)
+	sd	zero, 40(a0)
+	sd	zero, 48(a0)
+	sd	zero, 56(a0)
+	addiu	a0, 128
+	sd	zero, -64(a0)
+	sd	zero, -56(a0)
+	sd	zero, -48(a0)
+	sd	zero, -40(a0)
+	sd	zero, -32(a0)
+	sd	zero, -24(a0)
+	sd	zero, -16(a0)
+	sd	zero, -8(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_clear_page_s128)
+
+/*
+ * This is still inefficient.  We only can do better if we know the
+ * virtual address where the copy will be accessed.
+ */
+
+LEAF(r4k_copy_page_d16)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_D, (a0)
+	lw	a3, (a1)
+	lw	a2, 4(a1)
+	lw	v1, 8(a1)
+	lw	v0, 12(a1)
+	sw	a3, (a0)
+	sw	a2, 4(a0)
+	sw	v1, 8(a0)
+	sw	v0, 12(a0)
+	cache	Create_Dirty_Excl_D, 16(a0)
+	lw	a3, 16(a1)
+	lw	a2, 20(a1)
+	lw	v1, 24(a1)
+	lw	v0, 28(a1)
+	sw	a3, 16(a0)
+	sw	a2, 20(a0)
+	sw	v1, 24(a0)
+	sw	v0, 28(a0)
+	cache	Create_Dirty_Excl_D, 32(a0)
+	addiu	a0, 64
+	addiu	a1, 64
+	lw	a3, -32(a1)
+	lw	a2, -28(a1)
+	lw	v1, -24(a1)
+	lw	v0, -20(a1)
+	sw	a3, -32(a0)
+	sw	a2, -28(a0)
+	sw	v1, -24(a0)
+	sw	v0, -20(a0)
+	cache	Create_Dirty_Excl_D, -16(a0)
+	lw	a3, -16(a1)
+	lw	a2, -12(a1)
+	lw	v1, -8(a1)
+	lw	v0, -4(a1)
+	sw	a3, -16(a0)
+	sw	a2, -12(a0)
+	sw	v1, -8(a0)
+	sw	v0, -4(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_copy_page_d16)
+
+LEAF(r4k_copy_page_d32)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_D, (a0)
+	lw	a3, (a1)
+	lw	a2, 4(a1)
+	lw	v1, 8(a1)
+	lw	v0, 12(a1)
+	sw	a3, (a0)
+	sw	a2, 4(a0)
+	sw	v1, 8(a0)
+	sw	v0, 12(a0)
+	lw	a3, 16(a1)
+	lw	a2, 20(a1)
+	lw	v1, 24(a1)
+	lw	v0, 28(a1)
+	sw	a3, 16(a0)
+	sw	a2, 20(a0)
+	sw	v1, 24(a0)
+	sw	v0, 28(a0)
+	cache	Create_Dirty_Excl_D, 32(a0)
+	addiu	a0, 64
+	addiu	a1, 64
+	lw	a3, -32(a1)
+	lw	a2, -28(a1)
+	lw	v1, -24(a1)
+	lw	v0, -20(a1)
+	sw	a3, -32(a0)
+	sw	a2, -28(a0)
+	sw	v1, -24(a0)
+	sw	v0, -20(a0)
+	lw	a3, -16(a1)
+	lw	a2, -12(a1)
+	lw	v1, -8(a1)
+	lw	v0, -4(a1)
+	sw	a3, -16(a0)
+	sw	a2, -12(a0)
+	sw	v1, -8(a0)
+	sw	v0, -4(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_copy_page_d32)
+
+/*
+ * Again a special version for the R4600 V1.x
+ */
+
+LEAF(r4k_copy_page_r4600_v1)
+	addiu	AT, a0, _PAGE_SIZE
+1:	nop
+	nop
+	nop
+	nop
+	cache	Create_Dirty_Excl_D, (a0)
+	lw	a3, (a1)
+	lw	a2, 4(a1)
+	lw	v1, 8(a1)
+	lw	v0, 12(a1)
+	sw	a3, (a0)
+	sw	a2, 4(a0)
+	sw	v1, 8(a0)
+	sw	v0, 12(a0)
+	lw	a3, 16(a1)
+	lw	a2, 20(a1)
+	lw	v1, 24(a1)
+	lw	v0, 28(a1)
+	sw	a3, 16(a0)
+	sw	a2, 20(a0)
+	sw	v1, 24(a0)
+	sw	v0, 28(a0)
+	nop
+	nop
+	nop
+	nop
+	cache	Create_Dirty_Excl_D, 32(a0)
+	addiu	a0, 64
+	addiu	a1, 64
+	lw	a3, -32(a1)
+	lw	a2, -28(a1)
+	lw	v1, -24(a1)
+	lw	v0, -20(a1)
+	sw	a3, -32(a0)
+	sw	a2, -28(a0)
+	sw	v1, -24(a0)
+	sw	v0, -20(a0)
+	lw	a3, -16(a1)
+	lw	a2, -12(a1)
+	lw	v1, -8(a1)
+	lw	v0, -4(a1)
+	sw	a3, -16(a0)
+	sw	a2, -12(a0)
+	sw	v1, -8(a0)
+	sw	v0, -4(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_copy_page_r4600_v1)
+
+LEAF(r4k_copy_page_r4600_v2)
+	mfc0	v1, CP0_STATUS
+	ori	AT, v1, 1
+	xori	AT, 1
+
+	mtc0	AT, CP0_STATUS
+	nop
+	nop
+	nop
+
+	addiu	AT, a0, _PAGE_SIZE
+1:	nop
+	nop
+	nop
+	nop
+	cache	Create_Dirty_Excl_D, (a0)
+	lw	t1, (a1)
+	lw	t0, 4(a1)
+	lw	a3, 8(a1)
+	lw	a2, 12(a1)
+	sw	t1, (a0)
+	sw	t0, 4(a0)
+	sw	a3, 8(a0)
+	sw	a2, 12(a0)
+	lw	t1, 16(a1)
+	lw	t0, 20(a1)
+	lw	a3, 24(a1)
+	lw	a2, 28(a1)
+	sw	t1, 16(a0)
+	sw	t0, 20(a0)
+	sw	a3, 24(a0)
+	sw	a2, 28(a0)
+	nop
+	nop
+	nop
+	nop
+	cache	Create_Dirty_Excl_D, 32(a0)
+	addiu	a0, 64
+	addiu	a1, 64
+	lw	t1, -32(a1)
+	lw	t0, -28(a1)
+	lw	a3, -24(a1)
+	lw	a2, -20(a1)
+	sw	t1, -32(a0)
+	sw	t0, -28(a0)
+	sw	a3, -24(a0)
+	sw	a2, -20(a0)
+	lw	t1, -16(a1)
+	lw	t0, -12(a1)
+	lw	a3, -8(a1)
+	lw	a2, -4(a1)
+	sw	t1, -16(a0)
+	sw	t0, -12(a0)
+	sw	a3, -8(a0)
+	sw	a2, -4(a0)
+	bne	AT, a0, 1b
+
+	mfc0	AT, CP0_STATUS			# __restore_flags
+	andi	v1, 1
+	ori	AT, 1
+	xori	AT, 1
+	or	v1, AT
+	mtc0	v1, CP0_STATUS
+	nop
+	nop
+	nop
+	jr	ra
+	END(r4k_copy_page_r4600_v2)
+
+/*
+ * These are for R4000SC / R4400MC
+ */
+
+LEAF(r4k_copy_page_s16)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_SD, (a0)
+	lw	a3, (a1)
+	lw	a2, 4(a1)
+	lw	v1, 8(a1)
+	lw	v0, 12(a1)
+	sw	a3, (a0)
+	sw	a2, 4(a0)
+	sw	v1, 8(a0)
+	sw	v0, 12(a0)
+	cache	Create_Dirty_Excl_SD, 16(a0)
+	lw	a3, 16(a1)
+	lw	a2, 20(a1)
+	lw	v1, 24(a1)
+	lw	v0, 28(a1)
+	sw	a3, 16(a0)
+	sw	a2, 20(a0)
+	sw	v1, 24(a0)
+	sw	v0, 28(a0)
+	cache	Create_Dirty_Excl_SD, 32(a0)
+	addiu	a0, 64
+	addiu	a1, 64
+	lw	a3, -32(a1)
+	lw	a2, -28(a1)
+	lw	v1, -24(a1)
+	lw	v0, -20(a1)
+	sw	a3, -32(a0)
+	sw	a2, -28(a0)
+	sw	v1, -24(a0)
+	sw	v0, -20(a0)
+	cache	Create_Dirty_Excl_SD, -16(a0)
+	lw	a3, -16(a1)
+	lw	a2, -12(a1)
+	lw	v1, -8(a1)
+	lw	v0, -4(a1)
+	sw	a3, -16(a0)
+	sw	a2, -12(a0)
+	sw	v1, -8(a0)
+	sw	v0, -4(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_copy_page_s16)
+
+LEAF(r4k_copy_page_s32)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_SD, (a0)
+	lw	a3, (a1)
+	lw	a2, 4(a1)
+	lw	v1, 8(a1)
+	lw	v0, 12(a1)
+	sw	a3, (a0)
+	sw	a2, 4(a0)
+	sw	v1, 8(a0)
+	sw	v0, 12(a0)
+	lw	a3, 16(a1)
+	lw	a2, 20(a1)
+	lw	v1, 24(a1)
+	lw	v0, 28(a1)
+	sw	a3, 16(a0)
+	sw	a2, 20(a0)
+	sw	v1, 24(a0)
+	sw	v0, 28(a0)
+	cache	Create_Dirty_Excl_SD, 32(a0)
+	addiu	a0, 64
+	addiu	a1, 64
+	lw	a3, -32(a1)
+	lw	a2, -28(a1)
+	lw	v1, -24(a1)
+	lw	v0, -20(a1)
+	sw	a3, -32(a0)
+	sw	a2, -28(a0)
+	sw	v1, -24(a0)
+	sw	v0, -20(a0)
+	lw	a3, -16(a1)
+	lw	a2, -12(a1)
+	lw	v1, -8(a1)
+	lw	v0, -4(a1)
+	sw	a3, -16(a0)
+	sw	a2, -12(a0)
+	sw	v1, -8(a0)
+	sw	v0, -4(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_copy_page_s32)
+
+LEAF(r4k_copy_page_s64)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_SD, (a0)
+	lw	a3, (a1)
+	lw	a2, 4(a1)
+	lw	v1, 8(a1)
+	lw	v0, 12(a1)
+	sw	a3, (a0)
+	sw	a2, 4(a0)
+	sw	v1, 8(a0)
+	sw	v0, 12(a0)
+	lw	a3, 16(a1)
+	lw	a2, 20(a1)
+	lw	v1, 24(a1)
+	lw	v0, 28(a1)
+	sw	a3, 16(a0)
+	sw	a2, 20(a0)
+	sw	v1, 24(a0)
+	sw	v0, 28(a0)
+	addiu	a0, 64
+	addiu	a1, 64
+	lw	a3, -32(a1)
+	lw	a2, -28(a1)
+	lw	v1, -24(a1)
+	lw	v0, -20(a1)
+	sw	a3, -32(a0)
+	sw	a2, -28(a0)
+	sw	v1, -24(a0)
+	sw	v0, -20(a0)
+	lw	a3, -16(a1)
+	lw	a2, -12(a1)
+	lw	v1, -8(a1)
+	lw	v0, -4(a1)
+	sw	a3, -16(a0)
+	sw	a2, -12(a0)
+	sw	v1, -8(a0)
+	sw	v0, -4(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_copy_page_s64)
+
+LEAF(r4k_copy_page_s128)
+	addiu	AT, a0, _PAGE_SIZE
+1:	cache	Create_Dirty_Excl_SD, (a0)
+	lw	a3, (a1)
+	lw	a2, 4(a1)
+	lw	v1, 8(a1)
+	lw	v0, 12(a1)
+	sw	a3, (a0)
+	sw	a2, 4(a0)
+	sw	v1, 8(a0)
+	sw	v0, 12(a0)
+	lw	a3, 16(a1)
+	lw	a2, 20(a1)
+	lw	v1, 24(a1)
+	lw	v0, 28(a1)
+	sw	a3, 16(a0)
+	sw	a2, 20(a0)
+	sw	v1, 24(a0)
+	sw	v0, 28(a0)
+	lw	a3, 32(a1)
+	lw	a2, 36(a1)
+	lw	v1, 40(a1)
+	lw	v0, 44(a1)
+	sw	a3, 32(a0)
+	sw	a2, 36(a0)
+	sw	v1, 40(a0)
+	sw	v0, 44(a0)
+	lw	a3, 48(a1)
+	lw	a2, 52(a1)
+	lw	v1, 56(a1)
+	lw	v0, 60(a1)
+	sw	a3, 48(a0)
+	sw	a2, 52(a0)
+	sw	v1, 56(a0)
+	sw	v0, 60(a0)
+	addiu	a0, 128
+	addiu	a1, 128
+	lw	a3, -64(a1)
+	lw	a2, -60(a1)
+	lw	v1, -56(a1)
+	lw	v0, -52(a1)
+	sw	a3, -64(a0)
+	sw	a2, -60(a0)
+	sw	v1, -56(a0)
+	sw	v0, -52(a0)
+	lw	a3, -48(a1)
+	lw	a2, -44(a1)
+	lw	v1, -40(a1)
+	lw	v0, -36(a1)
+	sw	a3, -48(a0)
+	sw	a2, -44(a0)
+	sw	v1, -40(a0)
+	sw	v0, -36(a0)
+	lw	a3, -32(a1)
+	lw	a2, -28(a1)
+	lw	v1, -24(a1)
+	lw	v0, -20(a1)
+	sw	a3, -32(a0)
+	sw	a2, -28(a0)
+	sw	v1, -24(a0)
+	sw	v0, -20(a0)
+	lw	a3, -16(a1)
+	lw	a2, -12(a1)
+	lw	v1, -8(a1)
+	lw	v0, -4(a1)
+	sw	a3, -16(a0)
+	sw	a2, -12(a0)
+	sw	v1, -8(a0)
+	sw	v0, -4(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(r4k_copy_page_s128)
+
+/* This one still needs to receive cache optimizations  */
+LEAF(pgd_init)
+	addiu	AT, a0, PGD_SIZE / 2
+	la	v0, invalid_pte_table
+1:	sw	v0, (a0)
+	sw	v0, 4(a0)
+	sw	v0, 8(a0)
+	sw	v0, 12(a0)
+	addiu	a0, 32
+	sw	v0, -16(a0)
+	sw	v0, -12(a0)
+	sw	v0, -8(a0)
+	sw	v0, -4(a0)
+	bne	AT, a0, 1b
+	jr	ra
+	END(pgd_init)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/pg-r5432.c linux/arch/mips/mm/pg-r5432.c
--- linux.orig/arch/mips/mm/pg-r5432.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/pg-r5432.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,117 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cacheops.h>
+
+void r5432_clear_page_d32(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"addiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"addiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		: "memory");
+}
+
+/*
+ * This is still inefficient.  We only can do better if we know the
+ * virtual address where the copy will be accessed.
+ */
+
+void r5432_copy_page_d32(void * to, void * from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"addiu\t$1,%0,%8\n"
+		"1:\tcache\t%9,(%0)\n\t"
+		"lw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"cache\t%9,32(%0)\n\t"
+		"addiu\t%0,64\n\t"
+		"addiu\t%1,64\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		:"=r" (dummy1), "=r" (dummy2),
+		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		:"0" (to), "1" (from),
+		 "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D));
+}
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/pg-rm7k.c linux/arch/mips/mm/pg-rm7k.c
--- linux.orig/arch/mips/mm/pg-rm7k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/pg-rm7k.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,120 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cacheops.h>
+
+/*
+ * Zero an entire page.  Note that while the RM7000 has a second level cache
+ * it doesn't have a Create_Dirty_Excl_SD operation.
+ */
+void rm7k_clear_page(void * page)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"addiu\t$1,%0,%2\n"
+		"1:\tcache\t%3,(%0)\n\t"
+		"sd\t$0,(%0)\n\t"
+		"sd\t$0,8(%0)\n\t"
+		"sd\t$0,16(%0)\n\t"
+		"sd\t$0,24(%0)\n\t"
+		"addiu\t%0,64\n\t"
+		"cache\t%3,-32(%0)\n\t"
+		"sd\t$0,-32(%0)\n\t"
+		"sd\t$0,-24(%0)\n\t"
+		"sd\t$0,-16(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sd\t$0,-8(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		: "memory");
+}
+
+/*
+ * Copy an entire page.  Note that while the RM7000 has a second level cache
+ * it doesn't have a Create_Dirty_Excl_SD operation.
+ */
+void rm7k_copy_page(void * to, void * from)
+{
+	unsigned long dummy1, dummy2;
+	unsigned long reg1, reg2, reg3, reg4;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		".set\tnoat\n\t"
+		".set\tmips3\n\t"
+		"addiu\t$1,%0,%8\n"
+		"1:\tcache\t%9,(%0)\n\t"
+		"lw\t%2,(%1)\n\t"
+		"lw\t%3,4(%1)\n\t"
+		"lw\t%4,8(%1)\n\t"
+		"lw\t%5,12(%1)\n\t"
+		"sw\t%2,(%0)\n\t"
+		"sw\t%3,4(%0)\n\t"
+		"sw\t%4,8(%0)\n\t"
+		"sw\t%5,12(%0)\n\t"
+		"lw\t%2,16(%1)\n\t"
+		"lw\t%3,20(%1)\n\t"
+		"lw\t%4,24(%1)\n\t"
+		"lw\t%5,28(%1)\n\t"
+		"sw\t%2,16(%0)\n\t"
+		"sw\t%3,20(%0)\n\t"
+		"sw\t%4,24(%0)\n\t"
+		"sw\t%5,28(%0)\n\t"
+		"cache\t%9,32(%0)\n\t"
+		"addiu\t%0,64\n\t"
+		"addiu\t%1,64\n\t"
+		"lw\t%2,-32(%1)\n\t"
+		"lw\t%3,-28(%1)\n\t"
+		"lw\t%4,-24(%1)\n\t"
+		"lw\t%5,-20(%1)\n\t"
+		"sw\t%2,-32(%0)\n\t"
+		"sw\t%3,-28(%0)\n\t"
+		"sw\t%4,-24(%0)\n\t"
+		"sw\t%5,-20(%0)\n\t"
+		"lw\t%2,-16(%1)\n\t"
+		"lw\t%3,-12(%1)\n\t"
+		"lw\t%4,-8(%1)\n\t"
+		"lw\t%5,-4(%1)\n\t"
+		"sw\t%2,-16(%0)\n\t"
+		"sw\t%3,-12(%0)\n\t"
+		"sw\t%4,-8(%0)\n\t"
+		"bne\t$1,%0,1b\n\t"
+		"sw\t%5,-4(%0)\n\t"
+		".set\tmips0\n\t"
+		".set\tat\n\t"
+		".set\treorder"
+		: "=r" (dummy1), "=r" (dummy2),
+		  "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+		: "0" (to), "1" (from), "I" (PAGE_SIZE),
+		 "i" (Create_Dirty_Excl_D));
+}
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/pg-sb1.c linux/arch/mips/mm/pg-sb1.c
--- linux.orig/arch/mips/mm/pg-sb1.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/pg-sb1.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000 Sibyte
+ * 
+ * Written by Justin Carlson (carlson@sibyte.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 <asm/page.h>
+
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+#define SB1_PREF_LOAD_STREAMED_HINT "0"
+#define SB1_PREF_STORE_STREAMED_HINT "1"
+#else
+#define SB1_PREF_LOAD_STREAMED_HINT "4"
+#define SB1_PREF_STORE_STREAMED_HINT "5"
+#endif
+
+/* These are the functions hooked by the memory management function pointers */
+void sb1_clear_page(void *page)
+{
+	/* JDCXXX - This should be bottlenecked by the write buffer, but these
+	   things tend to be mildly unpredictable...should check this on the
+	   performance model */
+
+	/* We prefetch 4 lines ahead.  We're also "cheating" slightly here...
+	   since we know we're on an SB1, we force the assembler to take 
+	   64-bit operands to speed things up */
+	__asm__ __volatile__(
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     addiu     $1, %0, %2  \n"  /* Calculate the end of the page to clear */
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%0)  \n"  /* Prefetch the first 4 lines */
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 32(%0)  \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 64(%0)  \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%0)  \n"  
+		"1:   sd        $0,  0(%0)  \n"  /* Throw out a cacheline of 0's */
+		"     sd        $0,  8(%0)  \n"
+		"     sd        $0, 16(%0)  \n"
+		"     sd        $0, 24(%0)  \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",128(%0)  \n"  /* Prefetch 4 lines ahead     */
+		"     bne       $1, %0, 1b  \n"
+		"     addiu     %0, %0, 32  \n"  /* Next cacheline (This instruction better be short piped!) */
+		".set pop                   \n"
+		:"=r" (page)
+		:"0" (page),
+		 "I" (PAGE_SIZE-32)
+		:"$1","memory");
+
+}
+
+void sb1_copy_page(void *to, void *from)
+{
+
+	/* This should be optimized in assembly...can't use ld/sd, though,
+	 * because the top 32 bits could be nuked if we took an interrupt
+	 * during the routine.	And this is not a good place to be cli()'ing 
+	 */
+
+	/* The pref's used here are using "streaming" hints, which cause the
+	 * copied data to be kicked out of the cache sooner.  A page copy often
+	 * ends up copying a lot more data than is commonly used, so this seems
+	 * to make sense in terms of reducing cache pollution, but I've no real
+	 * performance data to back this up
+	 */
+
+	__asm__ __volatile__(
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     addiu     $1, %0, %4  \n"  /* Calculate the end of the page to copy */
+		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  0(%0)  \n"  /* Prefetch the first 3 lines */
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%1)  \n"  
+		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  32(%0) \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  32(%1) \n"  
+		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  64(%0) \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \n"  
+		"1:   lw        $2,  0(%0)  \n"  /* Block copy a cacheline */
+		"     lw        $3,  4(%0)  \n"
+		"     lw        $4,  8(%0)  \n"
+		"     lw        $5, 12(%0)  \n"
+		"     lw        $6, 16(%0)  \n"
+		"     lw        $7, 20(%0)  \n"
+		"     lw        $8, 24(%0)  \n"
+		"     lw        $9, 28(%0)  \n"
+		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ", 96(%0)  \n"  /* Prefetch ahead         */
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%1)  \n"
+		"     sw        $2,  0(%1)  \n"  
+		"     sw        $3,  4(%1)  \n"
+		"     sw        $4,  8(%1)  \n"
+		"     sw        $5, 12(%1)  \n"
+		"     sw        $6, 16(%1)  \n"
+		"     sw        $7, 20(%1)  \n"
+		"     sw        $8, 24(%1)  \n"
+		"     sw        $9, 28(%1)  \n"		
+		"     addiu     %1, %1, 32  \n"  /* Next cacheline */
+		"     nop                   \n"  /* Force next add to short pipe */
+		"     nop                   \n"  /* Force next add to short pipe */
+		"     bne       $1, %0, 1b  \n"
+		"     addiu     %0, %0, 32  \n"  /* Next cacheline */
+		".set pop                   \n" 
+		:"=r" (to),
+		"=r" (from)
+		:
+		"0" (from),
+		"1" (to),
+		"I" (PAGE_SIZE-32)
+		:"$1","$2","$3","$4","$5","$6","$7","$8","$9","memory");
+/*
+	unsigned long *src = from;
+	unsigned long *dest = to;
+	unsigned long *target = (unsigned long *) (((unsigned long)src) + PAGE_SIZE);
+	while (src != target) {
+		*dest++ = *src++;
+	}
+*/
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
--- linux.orig/arch/mips/mm/r2300.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/mips/mm/r2300.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,806 +0,0 @@
-/*
- * r2300.c: R2000 and R3000 specific mmu/cache code.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * with a lot of changes to make this thing work for R3000s
- * Tx39XX R4k style caches added. HK
- * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
- * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/mmu_context.h>
-#include <asm/system.h>
-#include <asm/isadep.h>
-#include <asm/io.h>
-#include <asm/wbflush.h>
-#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-
-/*
- * According to the paper written by D. Miller about Linux cache & TLB
- * flush implementation, DMA/Driver coherence should be done at the 
- * driver layer.  Thus, normally, we don't need flush dcache for R3000.
- * Define this if driver does not handle cache consistency during DMA ops.
- */
-
-/* For R3000 cores with R4000 style caches */
-static unsigned long icache_size, dcache_size;		/* Size in bytes */
-static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
-static unsigned long scache_size;
-
-#include <asm/cacheops.h>
-#include <asm/r4kcache.h>
-
-#undef DEBUG_TLB
-#undef DEBUG_CACHE
-
-/* page functions */
-void r3k_clear_page(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"addiu\t$1,%0,%2\n"
-		"1:\tsw\t$0,(%0)\n\t"
-		"sw\t$0,4(%0)\n\t"
-		"sw\t$0,8(%0)\n\t"
-		"sw\t$0,12(%0)\n\t"
-		"addiu\t%0,32\n\t"
-		"sw\t$0,-16(%0)\n\t"
-		"sw\t$0,-12(%0)\n\t"
-		"sw\t$0,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t$0,-4(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE)
-		:"$1","memory");
-}
-
-static void r3k_copy_page(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"addiu\t$1,%0,%8\n"
-		"1:\tlw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"addiu\t%0,64\n\t"
-		"addiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE));
-}
-
-unsigned long __init r3k_cache_size(unsigned long ca_flags)
-{
-	unsigned long flags, status, dummy, size;
-	volatile unsigned long *p;
-
-	p = (volatile unsigned long *) KSEG0;
-
-	flags = read_32bit_cp0_register(CP0_STATUS);
-
-	/* isolate cache space */
-	write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC);
-
-	*p = 0xa5a55a5a;
-	dummy = *p;
-	status = read_32bit_cp0_register(CP0_STATUS);
-
-	if (dummy != 0xa5a55a5a || (status & ST0_CM)) {
-		size = 0;
-	} else {
-		for (size = 128; size <= 0x40000; size <<= 1)
-			*(p + size) = 0;
-		*p = -1;
-		for (size = 128; 
-		     (size <= 0x40000) && (*(p + size) == 0); 
-		     size <<= 1)
-			;
-		if (size > 0x40000)
-			size = 0;
-	}
-
-	write_32bit_cp0_register(CP0_STATUS, flags);
-
-	return size * sizeof(*p);
-}
-
-unsigned long __init r3k_cache_lsize(unsigned long ca_flags)
-{
-	unsigned long flags, status, lsize, i, j;
-	volatile unsigned long *p;
-
-	p = (volatile unsigned long *) KSEG0;
-
-	flags = read_32bit_cp0_register(CP0_STATUS);
-
-	/* isolate cache space */
-	write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC);
-
-	for (i = 0; i < 128; i++)
-		*(p + i) = 0;
-	*(volatile unsigned char *)p = 0;
-	for (lsize = 1; lsize < 128; lsize <<= 1) {
-		*(p + lsize);
-		status = read_32bit_cp0_register(CP0_STATUS);
-		if (!(status & ST0_CM))
-			break;
-	}
-	for (i = 0; i < 128; i += lsize)
-		*(volatile unsigned char *)(p + i) = 0;
-
-	write_32bit_cp0_register(CP0_STATUS, flags);
-
-	return lsize * sizeof(*p);
-}
-
-static void __init r3k_probe_cache(void)
-{
-	dcache_size = r3k_cache_size(ST0_ISC);
-	if (dcache_size)
-		dcache_lsize = r3k_cache_lsize(ST0_ISC);
-	
-
-	icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
-	if (icache_size)
-		icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC);
-}
-
-static void r3k_flush_icache_range(unsigned long start, unsigned long end)
-{
-	unsigned long size, i, flags;
-	volatile unsigned char *p = (char *)start;
-
-	size = end - start;
-	if (size > icache_size)
-		size = icache_size;
-
-	flags = read_32bit_cp0_register(CP0_STATUS);
-
-	/* isolate cache space */
-	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
-
-	for (i = 0; i < size; i += 0x080) {
-		asm ( 	"sb\t$0,0x000(%0)\n\t"
-			"sb\t$0,0x004(%0)\n\t"
-			"sb\t$0,0x008(%0)\n\t"
-			"sb\t$0,0x00c(%0)\n\t"
-			"sb\t$0,0x010(%0)\n\t"
-			"sb\t$0,0x014(%0)\n\t"
-			"sb\t$0,0x018(%0)\n\t"
-			"sb\t$0,0x01c(%0)\n\t"
-		 	"sb\t$0,0x020(%0)\n\t"
-			"sb\t$0,0x024(%0)\n\t"
-			"sb\t$0,0x028(%0)\n\t"
-			"sb\t$0,0x02c(%0)\n\t"
-			"sb\t$0,0x030(%0)\n\t"
-			"sb\t$0,0x034(%0)\n\t"
-			"sb\t$0,0x038(%0)\n\t"
-			"sb\t$0,0x03c(%0)\n\t"
-			"sb\t$0,0x040(%0)\n\t"
-			"sb\t$0,0x044(%0)\n\t"
-			"sb\t$0,0x048(%0)\n\t"
-			"sb\t$0,0x04c(%0)\n\t"
-			"sb\t$0,0x050(%0)\n\t"
-			"sb\t$0,0x054(%0)\n\t"
-			"sb\t$0,0x058(%0)\n\t"
-			"sb\t$0,0x05c(%0)\n\t"
-		 	"sb\t$0,0x060(%0)\n\t"
-			"sb\t$0,0x064(%0)\n\t"
-			"sb\t$0,0x068(%0)\n\t"
-			"sb\t$0,0x06c(%0)\n\t"
-			"sb\t$0,0x070(%0)\n\t"
-			"sb\t$0,0x074(%0)\n\t"
-			"sb\t$0,0x078(%0)\n\t"
-			"sb\t$0,0x07c(%0)\n\t"
-			: : "r" (p) );
-		p += 0x080;
-	}
-
-	write_32bit_cp0_register(CP0_STATUS,flags);
-}
-
-static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
-{
-	unsigned long size, i, flags;
-	volatile unsigned char *p = (char *)start;
-
-	size = end - start;
-	if (size > dcache_size)
-		size = dcache_size;
-
-	flags = read_32bit_cp0_register(CP0_STATUS);
-
-	/* isolate cache space */
-	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|flags)&~ST0_IEC);
-
-	for (i = 0; i < size; i += 0x080) {
-		asm ( 	"sb\t$0,0x000(%0)\n\t"
-			"sb\t$0,0x004(%0)\n\t"
-			"sb\t$0,0x008(%0)\n\t"
-			"sb\t$0,0x00c(%0)\n\t"
-		 	"sb\t$0,0x010(%0)\n\t"
-			"sb\t$0,0x014(%0)\n\t"
-			"sb\t$0,0x018(%0)\n\t"
-			"sb\t$0,0x01c(%0)\n\t"
-		 	"sb\t$0,0x020(%0)\n\t"
-			"sb\t$0,0x024(%0)\n\t"
-			"sb\t$0,0x028(%0)\n\t"
-			"sb\t$0,0x02c(%0)\n\t"
-		 	"sb\t$0,0x030(%0)\n\t"
-			"sb\t$0,0x034(%0)\n\t"
-			"sb\t$0,0x038(%0)\n\t"
-			"sb\t$0,0x03c(%0)\n\t"
-		 	"sb\t$0,0x040(%0)\n\t"
-			"sb\t$0,0x044(%0)\n\t"
-			"sb\t$0,0x048(%0)\n\t"
-			"sb\t$0,0x04c(%0)\n\t"
-		 	"sb\t$0,0x050(%0)\n\t"
-			"sb\t$0,0x054(%0)\n\t"
-			"sb\t$0,0x058(%0)\n\t"
-			"sb\t$0,0x05c(%0)\n\t"
-		 	"sb\t$0,0x060(%0)\n\t"
-			"sb\t$0,0x064(%0)\n\t"
-			"sb\t$0,0x068(%0)\n\t"
-			"sb\t$0,0x06c(%0)\n\t"
-		 	"sb\t$0,0x070(%0)\n\t"
-			"sb\t$0,0x074(%0)\n\t"
-			"sb\t$0,0x078(%0)\n\t"
-			"sb\t$0,0x07c(%0)\n\t"
-			: : "r" (p) );
-		p += 0x080;
-	}
-
-	write_32bit_cp0_register(CP0_STATUS,flags);
-}
-
-static inline unsigned long get_phys_page (unsigned long addr,
-					   struct mm_struct *mm)
-{
-	pgd_t *pgd;
-	pmd_t *pmd;
-	pte_t *pte;
-	unsigned long physpage;
-
-	pgd = pgd_offset(mm, addr);
-	pmd = pmd_offset(pgd, addr);
-	pte = pte_offset(pmd, addr);
-
-	if ((physpage = pte_val(*pte)) & _PAGE_VALID)
-		return KSEG0ADDR(physpage & PAGE_MASK);
-
-	return 0;
-}
-
-static inline void r3k_flush_cache_all(void)
-{
-	r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
-}
- 
-static void r3k_flush_cache_mm(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r3k_flush_cache_all();
-	}
-}
-
-static void r3k_flush_cache_range(struct mm_struct *mm, unsigned long start,
-				  unsigned long end)
-{
-	struct vm_area_struct *vma;
-
-	if (mm->context == 0) 
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if (!vma)
-		return;
-
-	if (mm->context != current->active_mm->context) {
-		flush_cache_all();
-	} else {
-		unsigned long flags, physpage;
-
-		save_and_cli(flags);
-		while (start < end) {
-			if ((physpage = get_phys_page(start, mm)))
-				r3k_flush_icache_range(physpage,
-				                       physpage + PAGE_SIZE);
-			start += PAGE_SIZE;
-		}
-		restore_flags(flags);
-	}
-}
-
-static void r3k_flush_cache_page(struct vm_area_struct *vma,
-				   unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	if (vma->vm_flags & VM_EXEC) {
-		unsigned long physpage;
-
-		if ((physpage = get_phys_page(page, vma->vm_mm)))
-			r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
-	}
-}
-
-static void r3k_flush_page_to_ram(struct page * page)
-{
-	/*
-	 * Nothing to be done
-	 */
-}
-
-static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long physpage;
-
-	if (mm->context == 0)
-		return;
-
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-
-	physpage = (unsigned long) page_address(page);
-	if (physpage)
-		r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
-}
-
-static void r3k_flush_cache_sigtramp(unsigned long addr)
-{
-	unsigned long flags;
-
-#ifdef DEBUG_CACHE
-	printk("csigtramp[%08lx]", addr);
-#endif
-
-	flags = read_32bit_cp0_register(CP0_STATUS);
-
-	write_32bit_cp0_register(CP0_STATUS, flags&~ST0_IEC);
-
-	/* Fill the TLB to avoid an exception with caches isolated. */
-	asm ( 	"lw\t$0,0x000(%0)\n\t"
-		"lw\t$0,0x004(%0)\n\t"
-		: : "r" (addr) );
-
-	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
-
-	asm ( 	"sb\t$0,0x000(%0)\n\t"
-		"sb\t$0,0x004(%0)\n\t"
-		: : "r" (addr) );
-
-	write_32bit_cp0_register(CP0_STATUS, flags);
-}
-
-static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
-{
-	wbflush();
-	r3k_flush_dcache_range(start, start + size);
-}
-
-/* TLB operations. */
-void flush_tlb_all(void)
-{
-	unsigned long flags;
-	unsigned long old_ctx;
-	int entry;
-
-#ifdef DEBUG_TLB
-	printk("[tlball]");
-#endif
-
-	save_and_cli(flags);
-	old_ctx = (get_entryhi() & 0xfc0);
-	write_32bit_cp0_register(CP0_ENTRYLO0, 0);
-	for (entry = 8; entry < mips_cpu.tlbsize; entry++) {
-		write_32bit_cp0_register(CP0_INDEX, entry << 8);
-		write_32bit_cp0_register(CP0_ENTRYHI, ((entry | 0x80000) << 12));
-		__asm__ __volatile__("tlbwi");
-	}
-	set_entryhi(old_ctx);
-	restore_flags(flags);
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-		unsigned long flags;
-
-#ifdef DEBUG_TLB
-		printk("[tlbmm<%lu>]", (unsigned long) mm->context);
-#endif
-		save_and_cli(flags);
-		get_new_mmu_context(mm, asid_cache);
-		if (mm == current->active_mm)
-			set_entryhi(mm->context & 0xfc0);
-		restore_flags(flags);
-	}
-}
-
-void flush_tlb_range(struct mm_struct *mm, unsigned long start,
-                     unsigned long end)
-{
-	if (mm->context != 0) {
-		unsigned long flags;
-		int size;
-
-#ifdef DEBUG_TLB
-		printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
-			(mm->context & 0xfc0), start, end);
-#endif
-		save_and_cli(flags);
-		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-		if(size <= mips_cpu.tlbsize) {
-			int oldpid = (get_entryhi() & 0xfc0);
-			int newpid = (mm->context & 0xfc0);
-
-			start &= PAGE_MASK;
-			end += (PAGE_SIZE - 1);
-			end &= PAGE_MASK;
-			while(start < end) {
-				int idx;
-
-				set_entryhi(start | newpid);
-				start += PAGE_SIZE;
-				tlb_probe();
-				idx = get_index();
-				set_entrylo0(0);
-				set_entryhi(KSEG0);
-				if(idx < 0)
-					continue;
-				tlb_write_indexed();
-			}
-			set_entryhi(oldpid);
-		} else {
-			get_new_mmu_context(mm, asid_cache);
-			if (mm == current->active_mm)
-				set_entryhi(mm->context & 0xfc0);
-		}
-		restore_flags(flags);
-	}
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	if(vma->vm_mm->context != 0) {
-		unsigned long flags;
-		int oldpid, newpid, idx;
-
-#ifdef DEBUG_TLB
-		printk("[tlbpage<%lu,0x%08lx>]", vma->vm_mm->context, page);
-#endif
-		newpid = (vma->vm_mm->context & 0xfc0);
-		page &= PAGE_MASK;
-		save_and_cli(flags);
-		oldpid = (get_entryhi() & 0xfc0);
-		set_entryhi(page | newpid);
-		tlb_probe();
-		idx = get_index();
-		set_entrylo0(0);
-		set_entryhi(KSEG0);
-		if(idx < 0)
-			goto finish;
-		tlb_write_indexed();
-
-finish:
-		set_entryhi(oldpid);
-		restore_flags(flags);
-	}
-}
-
-/*
- * Initialize new page directory with pointers to invalid ptes
- */
-void pgd_init(unsigned long page)
-{
-	unsigned long dummy1, dummy2;
-
-	/*
-	 * The plain and boring version for the R3000.  No cache flushing
-	 * stuff is implemented since the R3000 has physical caches.
-	 */
-	__asm__ __volatile__(
-		".set\tnoreorder\n"
-		"1:\tsw\t%2,(%0)\n\t"
-		"sw\t%2,4(%0)\n\t"
-		"sw\t%2,8(%0)\n\t"
-		"sw\t%2,12(%0)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%2,20(%0)\n\t"
-		"sw\t%2,24(%0)\n\t"
-		"sw\t%2,28(%0)\n\t"
-		"subu\t%1,1\n\t"
-		"bnez\t%1,1b\n\t"
-		"addiu\t%0,32\n\t"
-		".set\treorder"
-		:"=r" (dummy1),
-		 "=r" (dummy2)
-		:"r" ((unsigned long) invalid_pte_table),
-		 "0" (page),
-		 "1" (PAGE_SIZE/(sizeof(pmd_t)*8)));
-}
-
-void update_mmu_cache(struct vm_area_struct * vma, unsigned long address,
-                      pte_t pte)
-{
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-	int idx, pid;
-
-	/*
-	 * Handle debugger faulting in for debugee.
-	 */
-	if (current->active_mm != vma->vm_mm)
-		return;
-
-	pid = get_entryhi() & 0xfc0;
-
-#ifdef DEBUG_TLB
-	if((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) {
-		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n",
-		       (vma->vm_mm->context & 0xfc0), pid);
-	}
-#endif
-
-	save_and_cli(flags);
-	address &= PAGE_MASK;
-	set_entryhi(address | (pid));
-	pgdp = pgd_offset(vma->vm_mm, address);
-	tlb_probe();
-	pmdp = pmd_offset(pgdp, address);
-	idx = get_index();
-	ptep = pte_offset(pmdp, address);
-	set_entrylo0(pte_val(*ptep));
-	set_entryhi(address | (pid));
-	if(idx < 0) {
-		tlb_write_random();
-#if 0
-		printk("[MISS]");
-#endif
-	} else {
-		tlb_write_indexed();
-#if 0
-		printk("[HIT]");
-#endif
-	}
-	set_entryhi(pid);
-	restore_flags(flags);
-}
-
-void show_regs(struct pt_regs * regs)
-{
-	/*
-	 * Saved main processor registers
-	 */
-	printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       0, (unsigned long) regs->regs[1], (unsigned long) regs->regs[2],
-	       (unsigned long) regs->regs[3], (unsigned long) regs->regs[4],
-	       (unsigned long) regs->regs[5], (unsigned long) regs->regs[6],
-	       (unsigned long) regs->regs[7]);
-	printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       (unsigned long) regs->regs[8], (unsigned long) regs->regs[9],
-	       (unsigned long) regs->regs[10], (unsigned long) regs->regs[11],
-               (unsigned long) regs->regs[12], (unsigned long) regs->regs[13],
-	       (unsigned long) regs->regs[14], (unsigned long) regs->regs[15]);
-	printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       (unsigned long) regs->regs[16], (unsigned long) regs->regs[17],
-	       (unsigned long) regs->regs[18], (unsigned long) regs->regs[19],
-               (unsigned long) regs->regs[20], (unsigned long) regs->regs[21],
-	       (unsigned long) regs->regs[22], (unsigned long) regs->regs[23]);
-	printk("$24: %08lx %08lx                   %08lx %08lx %08lx %08lx\n",
-	       (unsigned long) regs->regs[24], (unsigned long) regs->regs[25],
-	       (unsigned long) regs->regs[28], (unsigned long) regs->regs[29],
-               (unsigned long) regs->regs[30], (unsigned long) regs->regs[31]);
-
-	/*
-	 * Saved cp0 registers
-	 */
-	printk("epc  : %08lx    %s\nStatus: %08x\nCause : %08x\n",
-	       (unsigned long) regs->cp0_epc,
-	       print_tainted(),
-	       (unsigned int) regs->cp0_status,
-	       (unsigned int) regs->cp0_cause);
-}
-
-/* Todo: handle r4k-style TX39 TLB */
-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-                     unsigned long entryhi, unsigned long pagemask)
-{
-	unsigned long flags;
-	unsigned long old_ctx;
-	static unsigned long wired = 0;
-	
-	if (wired < 8) {
-		save_and_cli(flags);
-		old_ctx = get_entryhi() & 0xfc0;
-		set_entrylo0(entrylo0);
-		set_entryhi(entryhi);
-		set_index(wired);
-		wired++;
-		tlb_write_indexed();
-		set_entryhi(old_ctx);
-	        flush_tlb_all();    
-		restore_flags(flags);
-	}
-}
-
-static void tx39_flush_icache_all(void )
-{
-
-	unsigned long start = KSEG0;
-	unsigned long end = (start + icache_size);
-	unsigned long dummy = 0;
-
-	/* disable icache and stop streaming */
-	__asm__ __volatile__(
-	".set\tnoreorder\n\t"
-	"mfc0\t%0,$3\n\t"
-	"xori\t%0,32\n\t"
-	"mtc0\t%0,$3\n\t"
-	"j\t1f\n\t"
-	"nop\n\t"
-	"1:\t.set\treorder\n\t"
-	: : "r"(dummy));
-
-	/* invalidate icache */
-	while (start < end) {
-		cache16_unroll32(start,Index_Invalidate_I);
-		start += 0x200;
-	}
-
-	/* enable icache */
-	__asm__ __volatile__(
-	".set\tnoreorder\n\t"
-	"mfc0\t%0,$3\n\t"
-	"xori\t%0,32\n\t"
-	"mtc0\t%0,$3\n\t"
-	".set\treorder\n\t"
-	: : "r"(dummy));
-}
-
-static __init void tx39_probe_cache(void)
-{
-	unsigned long	config;
-
-	config = read_32bit_cp0_register(CP0_CONF);
-
-	icache_size = 1 << (10 + ((config >> 19) & 3));
-	icache_lsize = 16;
-
-	dcache_size = 1 << (10 + ((config >> 16) & 3));
-	dcache_lsize = 4;
-}
-
-void __init ld_mmu_r23000(void)
-{
-	unsigned long config;
-
-	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
-
-	_clear_page = r3k_clear_page;
-	_copy_page = r3k_copy_page;
-
-	switch (mips_cpu.cputype) {
-	case CPU_R2000:
-	case CPU_R3000:
-	case CPU_R3000A:
-	case CPU_R3081:
-	case CPU_R3081E:
-
-		r3k_probe_cache();
-
-		_flush_cache_all = r3k_flush_cache_all;
-		___flush_cache_all = r3k_flush_cache_all;
-		_flush_cache_mm = r3k_flush_cache_mm;
-		_flush_cache_range = r3k_flush_cache_range;
-		_flush_cache_page = r3k_flush_cache_page;
-		_flush_cache_sigtramp = r3k_flush_cache_sigtramp;
-		_flush_page_to_ram = r3k_flush_page_to_ram;
-		_flush_icache_page = r3k_flush_icache_page;
-		_flush_icache_range = r3k_flush_icache_range;
-
-		_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
-		break;
-
-	case CPU_TX3912:
-	case CPU_TX3922:
-	case CPU_TX3927:
-
-		config=read_32bit_cp0_register(CP0_CONF);
-		config &= ~TX39_CONF_WBON;
-		write_32bit_cp0_register(CP0_CONF, config);
-
-		tx39_probe_cache();
-
-		_flush_cache_all = tx39_flush_icache_all;
-		___flush_cache_all = tx39_flush_icache_all;
-		_flush_cache_mm = tx39_flush_icache_all;
-		_flush_cache_range = tx39_flush_icache_all;
-		_flush_cache_page = tx39_flush_icache_all;
-		_flush_cache_sigtramp = tx39_flush_icache_all;
-		_flush_page_to_ram = r3k_flush_page_to_ram;
-		_flush_icache_page = tx39_flush_icache_all;
-		_flush_icache_range = tx39_flush_icache_all;
-
-		_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
-
-		break;
-	}
-
-	printk("Primary instruction cache %dkb, linesize %d bytes\n",
-		(int) (icache_size >> 10), (int) icache_lsize);
-	printk("Primary data cache %dkb, linesize %d bytes\n",
-		(int) (dcache_size >> 10), (int) dcache_lsize);
-
-	flush_tlb_all();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c
--- linux.orig/arch/mips/mm/r4xx0.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/mips/mm/r4xx0.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,2713 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
- *
- * To do:
- *
- *  - this code is a overbloated pig
- *  - many of the bug workarounds are not efficient at all, but at
- *    least they are functional ...
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-#include <asm/bcache.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/mmu_context.h>
-
-/* CP0 hazard avoidance. */
-#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
-				     "nop; nop; nop; nop; nop; nop;\n\t" \
-				     ".set reorder\n\t")
-
-/* Primary cache parameters. */
-static int icache_size, dcache_size; /* Size in bytes */
-static int ic_lsize, dc_lsize;       /* LineSize in bytes */
-
-/* Secondary cache (if present) parameters. */
-static unsigned int scache_size, sc_lsize;	/* Again, in bytes */
-
-#include <asm/cacheops.h>
-#include <asm/r4kcache.h>
-
-#undef DEBUG_CACHE
-
-/*
- * Dummy cache handling routines for machines without boardcaches
- */
-static void no_sc_noop(void) {}
-
-static struct bcache_ops no_sc_ops = {
-	(void *)no_sc_noop, (void *)no_sc_noop,
-	(void *)no_sc_noop, (void *)no_sc_noop
-};
-
-struct bcache_ops *bcops = &no_sc_ops;
-
-/*
- * On processors with QED R4600 style two set assosicative cache
- * this is the bit which selects the way in the cache for the
- * indexed cachops.
- */
-#define icache_waybit (icache_size >> 1)
-#define dcache_waybit (dcache_size >> 1)
-
-/*
- * Zero an entire page.  Basically a simple unrolled loop should do the
- * job but we want more performance by saving memory bus bandwidth.  We
- * have five flavours of the routine available for:
- *
- * - 16byte cachelines and no second level cache
- * - 32byte cachelines second level cache
- * - a version which handles the buggy R4600 v1.x
- * - a version which handles the buggy R4600 v2.0
- * - Finally a last version without fancy cache games for the SC and MC
- *   versions of R4000 and R4400.
- */
-
-static void r4k_clear_page_d16(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"cache\t%3,16(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"cache\t%3,-16(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D)
-		:"$1","memory");
-}
-
-static void r4k_clear_page_d32(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D)
-		:"$1","memory");
-}
-
-
-/*
- * This flavour of r4k_clear_page is for the R4600 V1.x.  Cite from the
- * IDT R4600 V1.7 errata:
- *
- *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
- *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
- *      executed if there is no other dcache activity. If the dcache is
- *      accessed for another instruction immeidately preceding when these
- *      cache instructions are executing, it is possible that the dcache 
- *      tag match outputs used by these cache instructions will be 
- *      incorrect. These cache instructions should be preceded by at least
- *      four instructions that are not any kind of load or store 
- *      instruction.
- *
- *      This is not allowed:    lw
- *                              nop
- *                              nop
- *                              nop
- *                              cache       Hit_Writeback_Invalidate_D
- *
- *      This is allowed:        lw
- *                              nop
- *                              nop
- *                              nop
- *                              nop
- *                              cache       Hit_Writeback_Invalidate_D
- */
-static void r4k_clear_page_r4600_v1(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tnop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"cache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D)
-		:"$1","memory");
-}
-
-/*
- * And this one is for the R4600 V2.0
- */
-static void r4k_clear_page_r4600_v2(void * page)
-{
-	unsigned int flags;
-
-	__save_and_cli(flags);
-	*(volatile unsigned int *)KSEG1;
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D)
-		:"$1","memory");
-	__restore_flags(flags);
-}
-
-/*
- * The next 4 versions are optimized for all possible scache configurations
- * of the SC / MC versions of R4000 and R4400 ...
- *
- * Todo: For even better performance we should have a routine optimized for
- * every legal combination of dcache / scache linesize.  When I (Ralf) tried
- * this the kernel crashed shortly after mounting the root filesystem.  CPU
- * bug?  Weirdo cache instruction semantics?
- */
-static void r4k_clear_page_s16(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"cache\t%3,16(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"cache\t%3,-16(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD)
-		:"$1","memory");
-}
-
-static void r4k_clear_page_s32(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD)
-		:"$1","memory");
-}
-
-static void r4k_clear_page_s64(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD)
-		:"$1","memory");
-}
-
-static void r4k_clear_page_s128(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"sd\t$0,32(%0)\n\t"
-		"sd\t$0,40(%0)\n\t"
-		"sd\t$0,48(%0)\n\t"
-		"sd\t$0,56(%0)\n\t"
-		"daddiu\t%0,128\n\t"
-		"sd\t$0,-64(%0)\n\t"
-		"sd\t$0,-56(%0)\n\t"
-		"sd\t$0,-48(%0)\n\t"
-		"sd\t$0,-40(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD)
-		:"$1","memory");
-}
-
-
-/*
- * This is still inefficient.  We only can do better if we know the
- * virtual address where the copy will be accessed.
- */
-
-static void r4k_copy_page_d16(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"cache\t%9,16(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"cache\t%9,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"cache\t%9,-16(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-}
-
-static void r4k_copy_page_d32(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"cache\t%9,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-}
-
-/*
- * Again a special version for the R4600 V1.x
- */
-static void r4k_copy_page_r4600_v1(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tnop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"cache\t%9,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-}
-
-static void r4k_copy_page_r4600_v2(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-	unsigned int flags;
-
-	__save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tnop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"cache\t%9,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-	__restore_flags(flags);
-}
-
-/*
- * These are for R4000SC / R4400MC
- */
-static void r4k_copy_page_s16(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"cache\t%9,16(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"cache\t%9,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"cache\t%9,-16(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD));
-}
-
-static void r4k_copy_page_s32(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"cache\t%9,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD));
-}
-
-static void r4k_copy_page_s64(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD));
-}
-
-static void r4k_copy_page_s128(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"lw\t%2,32(%1)\n\t"
-		"lw\t%3,36(%1)\n\t"
-		"lw\t%4,40(%1)\n\t"
-		"lw\t%5,44(%1)\n\t"
-		"sw\t%2,32(%0)\n\t"
-		"sw\t%3,36(%0)\n\t"
-		"sw\t%4,40(%0)\n\t"
-		"sw\t%5,44(%0)\n\t"
-		"lw\t%2,48(%1)\n\t"
-		"lw\t%3,52(%1)\n\t"
-		"lw\t%4,56(%1)\n\t"
-		"lw\t%5,60(%1)\n\t"
-		"sw\t%2,48(%0)\n\t"
-		"sw\t%3,52(%0)\n\t"
-		"sw\t%4,56(%0)\n\t"
-		"sw\t%5,60(%0)\n\t"
-		"daddiu\t%0,128\n\t"
-		"daddiu\t%1,128\n\t"
-		"lw\t%2,-64(%1)\n\t"
-		"lw\t%3,-60(%1)\n\t"
-		"lw\t%4,-56(%1)\n\t"
-		"lw\t%5,-52(%1)\n\t"
-		"sw\t%2,-64(%0)\n\t"
-		"sw\t%3,-60(%0)\n\t"
-		"sw\t%4,-56(%0)\n\t"
-		"sw\t%5,-52(%0)\n\t"
-		"lw\t%2,-48(%1)\n\t"
-		"lw\t%3,-44(%1)\n\t"
-		"lw\t%4,-40(%1)\n\t"
-		"lw\t%5,-36(%1)\n\t"
-		"sw\t%2,-48(%0)\n\t"
-		"sw\t%3,-44(%0)\n\t"
-		"sw\t%4,-40(%0)\n\t"
-		"sw\t%5,-36(%0)\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD));
-}
-
-
-/*
- * If you think for one second that this stuff coming up is a lot
- * of bulky code eating too many kernel cache lines.  Think _again_.
- *
- * Consider:
- * 1) Taken branches have a 3 cycle penalty on R4k
- * 2) The branch itself is a real dead cycle on even R4600/R5000.
- * 3) Only one of the following variants of each type is even used by
- *    the kernel based upon the cache parameters we detect at boot time.
- *
- * QED.
- */
-
-static inline void r4k_flush_cache_all_s16d16i16(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache16(); blast_icache16(); blast_scache16();
-	__restore_flags(flags);
-}
-
-static inline void r4k_flush_cache_all_s32d16i16(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache16(); blast_icache16(); blast_scache32();
-	__restore_flags(flags);
-}
-
-static inline void r4k_flush_cache_all_s64d16i16(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache16(); blast_icache16(); blast_scache64();
-	__restore_flags(flags);
-}
-
-static inline void r4k_flush_cache_all_s128d16i16(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache16(); blast_icache16(); blast_scache128();
-	__restore_flags(flags);
-}
-
-static inline void r4k_flush_cache_all_s32d32i32(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache32(); blast_icache32(); blast_scache32();
-	__restore_flags(flags);
-}
-
-static inline void r4k_flush_cache_all_s64d32i32(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache32(); blast_icache32(); blast_scache64();
-	__restore_flags(flags);
-}
-
-static inline void r4k_flush_cache_all_s128d32i32(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache32(); blast_icache32(); blast_scache128();
-	__restore_flags(flags);
-}
-
-static inline void r4k_flush_cache_all_d16i16(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache16(); blast_icache16();
-	__restore_flags(flags);
-}
-
-static inline void r4k_flush_cache_all_d32i32(void)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);
-	blast_dcache32(); blast_icache32();
-	__restore_flags(flags);
-}
-
-static void
-r4k_flush_cache_range_s16d16i16(struct mm_struct *mm,
-                                unsigned long start,
-                                unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if (mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if (vma) {
-		if (mm->context != current->active_mm->context) {
-			r4k_flush_cache_all_s16d16i16();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-
-			__save_and_cli(flags);
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID)
-					blast_scache16_page(start);
-				start += PAGE_SIZE;
-			}
-			__restore_flags(flags);
-		}
-	}
-}
-
-static void
-r4k_flush_cache_range_s32d16i16(struct mm_struct *mm,
-                                unsigned long start,
-                                unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if (mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if (vma) {
-		if (mm->context != current->active_mm->context) {
-			r4k_flush_cache_all_s32d16i16();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-
-			__save_and_cli(flags);
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID)
-					blast_scache32_page(start);
-				start += PAGE_SIZE;
-			}
-			__restore_flags(flags);
-		}
-	}
-}
-
-static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm,
-					    unsigned long start,
-					    unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if (mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if(vma) {
-		if (mm->context != current->active_mm->context) {
-			r4k_flush_cache_all_s64d16i16();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-
-			__save_and_cli(flags);
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID)
-					blast_scache64_page(start);
-				start += PAGE_SIZE;
-			}
-			__restore_flags(flags);
-		}
-	}
-}
-
-static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm,
-					     unsigned long start,
-					     unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if (mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if (vma) {
-		if (mm->context != current->active_mm->context) {
-			r4k_flush_cache_all_s128d16i16();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-
-			__save_and_cli(flags);
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID)
-					blast_scache128_page(start);
-				start += PAGE_SIZE;
-			}
-			__restore_flags(flags);
-		}
-	}
-}
-
-static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm,
-					    unsigned long start,
-					    unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if (mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if (vma) {
-		if (mm->context != current->active_mm->context) {
-			r4k_flush_cache_all_s32d32i32();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-
-			__save_and_cli(flags);
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID)
-					blast_scache32_page(start);
-				start += PAGE_SIZE;
-			}
-			__restore_flags(flags);
-		}
-	}
-}
-
-static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm,
-					    unsigned long start,
-					    unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if (mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if (vma) {
-		if (mm->context != current->active_mm->context) {
-			r4k_flush_cache_all_s64d32i32();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-
-			__save_and_cli(flags);
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID)
-					blast_scache64_page(start);
-				start += PAGE_SIZE;
-			}
-			__restore_flags(flags);
-		}
-	}
-}
-
-static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm,
-					     unsigned long start,
-					     unsigned long end)
-{
-	struct vm_area_struct *vma;
-	unsigned long flags;
-
-	if (mm->context == 0)
-		return;
-
-	start &= PAGE_MASK;
-#ifdef DEBUG_CACHE
-	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-	vma = find_vma(mm, start);
-	if (vma) {
-		if (mm->context != current->active_mm->context) {
-			r4k_flush_cache_all_s128d32i32();
-		} else {
-			pgd_t *pgd;
-			pmd_t *pmd;
-			pte_t *pte;
-
-			__save_and_cli(flags);
-			while(start < end) {
-				pgd = pgd_offset(mm, start);
-				pmd = pmd_offset(pgd, start);
-				pte = pte_offset(pmd, start);
-
-				if(pte_val(*pte) & _PAGE_VALID)
-					blast_scache128_page(start);
-				start += PAGE_SIZE;
-			}
-			__restore_flags(flags);
-		}
-	}
-}
-
-static void r4k_flush_cache_range_d16i16(struct mm_struct *mm,
-					 unsigned long start,
-					 unsigned long end)
-{
-	if (mm->context != 0) {
-		unsigned long flags;
-
-#ifdef DEBUG_CACHE
-		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-		__save_and_cli(flags);
-		blast_dcache16(); blast_icache16();
-		__restore_flags(flags);
-	}
-}
-
-static void r4k_flush_cache_range_d32i32(struct mm_struct *mm,
-					 unsigned long start,
-					 unsigned long end)
-{
-	if (mm->context != 0) {
-		unsigned long flags;
-
-#ifdef DEBUG_CACHE
-		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-		__save_and_cli(flags);
-		blast_dcache32(); blast_icache32();
-		__restore_flags(flags);
-	}
-}
-
-/*
- * On architectures like the Sparc, we could get rid of lines in
- * the cache created only by a certain context, but on the MIPS
- * (and actually certain Sparc's) we cannot.
- */
-static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_s16d16i16();
-	}
-}
-
-static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_s32d16i16();
-	}
-}
-
-static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_s64d16i16();
-	}
-}
-
-static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_s128d16i16();
-	}
-}
-
-static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_s32d32i32();
-	}
-}
-
-static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_s64d32i32();
-	}
-}
-
-static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_s128d32i32();
-	}
-}
-
-static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_d16i16();
-	}
-}
-
-static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r4k_flush_cache_all_d32i32();
-	}
-}
-
-static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma,
-					   unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm->context != current->active_mm->context) {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache16_page_indexed(page);
-		blast_scache16_page_indexed(page);
-	} else
-		blast_scache16_page(page);
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
-					   unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/* If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm->context != current->active_mm->context) {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache16_page_indexed(page);
-		blast_scache32_page_indexed(page);
-	} else
-		blast_scache32_page(page);
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
-					   unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/* If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm->context != current->active_mm->context) {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache16_page_indexed(page);
-		blast_scache64_page_indexed(page);
-	} else
-		blast_scache64_page(page);
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
-					    unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm->context != current->active_mm->context) {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache16_page_indexed(page);
-		blast_scache128_page_indexed(page);
-	} else
-		blast_scache128_page(page);
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
-					   unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm->context != current->active_mm->context) {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache32_page_indexed(page);
-		blast_scache32_page_indexed(page);
-	} else
-		blast_scache32_page(page);
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
-					   unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm->context != current->active_mm->context) {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache32_page_indexed(page);
-		blast_scache64_page_indexed(page);
-	} else
-		blast_scache64_page(page);
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
-					    unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm->context != current->active_mm->context) {
-		/* Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (scache_size - 1)));
-		blast_dcache32_page_indexed(page);
-		blast_scache128_page_indexed(page);
-	} else
-		blast_scache128_page(page);
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
-					unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_VALID))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if (mm == current->active_mm) {
-		blast_dcache16_page(page);
-	} else {
-		/* Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (dcache_size - 1)));
-		blast_dcache16_page_indexed(page);
-	}
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
-					unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_PRESENT))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
-		blast_dcache32_page(page);
-	} else {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (dcache_size - 1)));
-		blast_dcache32_page_indexed(page);
-	}
-out:
-	__restore_flags(flags);
-}
-
-static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
-					      unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	__save_and_cli(flags);
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_PRESENT))
-		goto out;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
-		blast_dcache32_page(page);
-	} else {
-		/* Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (dcache_size - 1)));
-		blast_dcache32_page_indexed(page);
-		blast_dcache32_page_indexed(page ^ dcache_waybit);
-	}
-out:
-	__restore_flags(flags);
-}
-
-/* If the addresses passed to these routines are valid, they are
- * either:
- *
- * 1) In KSEG0, so we can do a direct flush of the page.
- * 2) In KSEG2, and since every process can translate those
- *    addresses all the time in kernel mode we can do a direct
- *    flush.
- * 3) In KSEG1, no flush necessary.
- */
-static void r4k_flush_page_to_ram_s16(struct page *page)
-{
-	blast_scache16_page((unsigned long)page_address(page));
-}
-
-static void r4k_flush_page_to_ram_s32(struct page *page)
-{
-	blast_scache32_page((unsigned long)page_address(page));
-}
-
-static void r4k_flush_page_to_ram_s64(struct page *page)
-{
-	blast_scache64_page((unsigned long)page_address(page));
-}
-
-static void r4k_flush_page_to_ram_s128(struct page *page)
-{
-	blast_scache128_page((unsigned long)page_address(page));
-}
-
-static void r4k_flush_page_to_ram_d16(struct page *page)
-{
-	blast_dcache16_page((unsigned long)page_address(page));
-}
-
-static void r4k_flush_page_to_ram_d32(struct page *page)
-{
-	blast_dcache32_page((unsigned long)page_address(page));
-}
-
-static void r4k_flush_page_to_ram_d32_r4600(struct page *page)
-{
-	unsigned long flags;
-
-	__save_and_cli(flags);			/* For R4600 v1.7 bug.  */
-	blast_dcache32_page((unsigned long)page_address(page));
-	__restore_flags(flags);
-}
-
-static void
-r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
-{
-	/*
-	 * We did an scache flush therefore PI is already clean.
-	 */
-}
-
-static void
-r4k_flush_icache_range(unsigned long start, unsigned long end)
-{
-	flush_cache_all();
-}
-
-/*
- * Ok, this seriously sucks.  We use them to flush a user page but don't
- * know the virtual address, so we have to blast away the whole icache
- * which is significantly more expensive than the real thing.
- */
-static void
-r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page)
-{
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-
-	flush_cache_all();
-}
-
-/*
- * Writeback and invalidate the primary cache dcache before DMA.
- *
- * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
- * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only
- * operate correctly if the internal data cache refill buffer is empty.  These
- * CACHE instructions should be separated from any potential data cache miss
- * by a load instruction to an uncached address to empty the response buffer."
- * (Revision 2.0 device errata from IDT available on http://www.idt.com/
- * in .pdf format.)
- */
-static void
-r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-	unsigned int flags;
-
-	if (size >= dcache_size) {
-		flush_cache_all();
-	} else {
-		/* Workaround for R4600 bug.  See comment above. */
-		__save_and_cli(flags);
-		*(volatile unsigned long *)KSEG1;
-
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
-		while (1) {
-			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
-			if (a == end) break;
-			a += dc_lsize;
-		}
-		__restore_flags(flags);
-	}
-	bc_wback_inv(addr, size);
-}
-
-static void
-r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-
-	if (size >= scache_size) {
-		flush_cache_all();
-		return;
-	}
-
-	a = addr & ~(sc_lsize - 1);
-	end = (addr + size) & ~(sc_lsize - 1);
-	while (1) {
-		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
-		if (a == end) break;
-		a += sc_lsize;
-	}
-}
-
-static void
-r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-	unsigned int flags;
-
-	if (size >= dcache_size) {
-		flush_cache_all();
-	} else {
-		/* Workaround for R4600 bug.  See comment above. */
-		__save_and_cli(flags);
-		*(volatile unsigned long *)KSEG1;
-
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
-		while (1) {
-			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
-			if (a == end) break;
-			a += dc_lsize;
-		}
-		__restore_flags(flags);
-	}
-
-	bc_inv(addr, size);
-}
-
-static void
-r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-
-	if (size >= scache_size) {
-		flush_cache_all();
-		return;
-	}
-
-	a = addr & ~(sc_lsize - 1);
-	end = (addr + size) & ~(sc_lsize - 1);
-	while (1) {
-		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
-		if (a == end) break;
-		a += sc_lsize;
-	}
-}
-
-static void
-r4k_dma_cache_wback(unsigned long addr, unsigned long size)
-{
-	panic("r4k_dma_cache called - should not happen.\n");
-}
-
-/*
- * While we're protected against bad userland addresses we don't care
- * very much about what happens in that case.  Usually a segmentation
- * fault will dump the process later on anyway ...
- */
-static void r4k_flush_cache_sigtramp(unsigned long addr)
-{
-	__asm__ __volatile__("nop;nop;nop;nop");	/* R4600 V1.7 */
-	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
-	protected_flush_icache_line(addr & ~(ic_lsize - 1));
-}
-
-static void r4600v20k_flush_cache_sigtramp(unsigned long addr)
-{
-	unsigned int flags;
-
-	__save_and_cli(flags);
-
-	/* Clear internal cache refill buffer */
-	*(volatile unsigned int *)KSEG1;
-
-	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
-	protected_flush_icache_line(addr & ~(ic_lsize - 1));
-
-	__restore_flags(flags);
-}
-
-#undef DEBUG_TLB
-#undef DEBUG_TLBUPDATE
-
-void flush_tlb_all(void)
-{
-	unsigned long flags;
-	unsigned long old_ctx;
-	int entry;
-
-#ifdef DEBUG_TLB
-	printk("[tlball]");
-#endif
-
-	__save_and_cli(flags);
-	/* Save old context and create impossible VPN2 value */
-	old_ctx = (get_entryhi() & 0xff);
-	set_entryhi(KSEG0);
-	set_entrylo0(0);
-	set_entrylo1(0);
-	BARRIER;
-
-	entry = get_wired();
-
-	/* Blast 'em all away. */
-	while(entry < mips_cpu.tlbsize) {
-		set_index(entry);
-		BARRIER;
-		tlb_write_indexed();
-		BARRIER;
-		entry++;
-	}
-	BARRIER;
-	set_entryhi(old_ctx);
-	__restore_flags(flags);
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-		unsigned long flags;
-
-#ifdef DEBUG_TLB
-		printk("[tlbmm<%d>]", mm->context);
-#endif
-		__save_and_cli(flags);
-		get_new_mmu_context(mm, asid_cache);
-		if (mm == current->active_mm)
-			set_entryhi(mm->context & 0xff);
-		__restore_flags(flags);
-	}
-}
-
-void flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				unsigned long end)
-{
-	if(mm->context != 0) {
-		unsigned long flags;
-		int size;
-
-#ifdef DEBUG_TLB
-		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
-		       start, end);
-#endif
-		__save_and_cli(flags);
-		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-		size = (size + 1) >> 1;
-		if(size <= mips_cpu.tlbsize/2) {
-			int oldpid = (get_entryhi() & 0xff);
-			int newpid = (mm->context & 0xff);
-
-			start &= (PAGE_MASK << 1);
-			end += ((PAGE_SIZE << 1) - 1);
-			end &= (PAGE_MASK << 1);
-			while(start < end) {
-				int idx;
-
-				set_entryhi(start | newpid);
-				start += (PAGE_SIZE << 1);
-				BARRIER;
-				tlb_probe();
-				BARRIER;
-				idx = get_index();
-				set_entrylo0(0);
-				set_entrylo1(0);
-				set_entryhi(KSEG0);
-				BARRIER;
-				if(idx < 0)
-					continue;
-				tlb_write_indexed();
-				BARRIER;
-			}
-			set_entryhi(oldpid);
-		} else {
-			get_new_mmu_context(mm, asid_cache);
-			if (mm == current->active_mm)
-				set_entryhi(mm->context & 0xff);
-		}
-		__restore_flags(flags);
-	}
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	if (vma->vm_mm->context != 0) {
-		unsigned long flags;
-		int oldpid, newpid, idx;
-
-#ifdef DEBUG_TLB
-		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
-#endif
-		newpid = (vma->vm_mm->context & 0xff);
-		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
-		oldpid = (get_entryhi() & 0xff);
-		set_entryhi(page | newpid);
-		BARRIER;
-		tlb_probe();
-		BARRIER;
-		idx = get_index();
-		set_entrylo0(0);
-		set_entrylo1(0);
-		set_entryhi(KSEG0);
-		if(idx < 0)
-			goto finish;
-		BARRIER;
-		tlb_write_indexed();
-
-	finish:
-		BARRIER;
-		set_entryhi(oldpid);
-		__restore_flags(flags);
-	}
-}
-
-void pgd_init(unsigned long page)
-{
-	unsigned long *p = (unsigned long *) page;
-	int i;
-
-	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
-		p[i + 0] = (unsigned long) invalid_pte_table;
-		p[i + 1] = (unsigned long) invalid_pte_table;
-		p[i + 2] = (unsigned long) invalid_pte_table;
-		p[i + 3] = (unsigned long) invalid_pte_table;
-		p[i + 4] = (unsigned long) invalid_pte_table;
-		p[i + 5] = (unsigned long) invalid_pte_table;
-		p[i + 6] = (unsigned long) invalid_pte_table;
-		p[i + 7] = (unsigned long) invalid_pte_table;
-	}
-}
-
-/* We will need multiple versions of update_mmu_cache(), one that just
- * updates the TLB with the new pte(s), and another which also checks
- * for the R4k "end of page" hardware bug and does the needy.
- */
-void update_mmu_cache(struct vm_area_struct * vma,
-				 unsigned long address, pte_t pte)
-{
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-	int idx, pid;
-
-	/*
-	 * Handle debugger faulting in for debugee.
-	 */
-	if (current->active_mm != vma->vm_mm)
-		return;
-
-	pid = get_entryhi() & 0xff;
-
-#ifdef DEBUG_TLB
-	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
-		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
-		       (int) (vma->vm_mm->context & 0xff), pid);
-	}
-#endif
-
-	__save_and_cli(flags);
-	address &= (PAGE_MASK << 1);
-	set_entryhi(address | (pid));
-	pgdp = pgd_offset(vma->vm_mm, address);
-	BARRIER;
-	tlb_probe();
-	BARRIER;
-	pmdp = pmd_offset(pgdp, address);
-	idx = get_index();
-	ptep = pte_offset(pmdp, address);
-	BARRIER;
-	set_entrylo0(pte_val(*ptep++) >> 6);
-	set_entrylo1(pte_val(*ptep) >> 6);
-	set_entryhi(address | (pid));
-	BARRIER;
-	if(idx < 0) {
-		tlb_write_random();
-	} else {
-		tlb_write_indexed();
-	}
-	BARRIER;
-	set_entryhi(pid);
-	BARRIER;
-	__restore_flags(flags);
-}
-
-#if 0
-static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
-				       unsigned long address, pte_t pte)
-{
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-	int idx;
-
-	__save_and_cli(flags);
-	address &= (PAGE_MASK << 1);
-	set_entryhi(address | (get_entryhi() & 0xff));
-	pgdp = pgd_offset(vma->vm_mm, address);
-	tlb_probe();
-	pmdp = pmd_offset(pgdp, address);
-	idx = get_index();
-	ptep = pte_offset(pmdp, address);
-	set_entrylo0(pte_val(*ptep++) >> 6);
-	set_entrylo1(pte_val(*ptep) >> 6);
-	BARRIER;
-	if(idx < 0)
-		tlb_write_random();
-	else
-		tlb_write_indexed();
-	BARRIER;
-	__restore_flags(flags);
-}
-#endif
-
-void show_regs(struct pt_regs * regs)
-{
-	/* Saved main processor registers. */
-	printk("$0 : %08lx %08lx %08lx %08lx\n",
-	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
-	printk("$4 : %08lx %08lx %08lx %08lx\n",
-               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
-	printk("$8 : %08lx %08lx %08lx %08lx\n",
-	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
-	printk("$12: %08lx %08lx %08lx %08lx\n",
-               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
-	printk("$16: %08lx %08lx %08lx %08lx\n",
-	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
-	printk("$20: %08lx %08lx %08lx %08lx\n",
-               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
-	printk("$24: %08lx %08lx\n",
-	       regs->regs[24], regs->regs[25]);
-	printk("$28: %08lx %08lx %08lx %08lx\n",
-	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
-
-	/* Saved cp0 registers. */
-	printk("epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
-}
-			
-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-				      unsigned long entryhi, unsigned long pagemask)
-{
-        unsigned long flags;
-        unsigned long wired;
-        unsigned long old_pagemask;
-        unsigned long old_ctx;
-
-        __save_and_cli(flags);
-        /* Save old context and create impossible VPN2 value */
-        old_ctx = (get_entryhi() & 0xff);
-        old_pagemask = get_pagemask();
-        wired = get_wired();
-        set_wired (wired + 1);
-        set_index (wired);
-        BARRIER;    
-        set_pagemask (pagemask);
-        set_entryhi(entryhi);
-        set_entrylo0(entrylo0);
-        set_entrylo1(entrylo1);
-        BARRIER;    
-        tlb_write_indexed();
-        BARRIER;    
-    
-        set_entryhi(old_ctx);
-        BARRIER;    
-        set_pagemask (old_pagemask);
-        flush_tlb_all();    
-        __restore_flags(flags);
-}
-
-/* Detect and size the various r4k caches. */
-static void __init probe_icache(unsigned long config)
-{
-        switch (mips_cpu.cputype) {
-        case CPU_VR41XX:
-                icache_size = 1 << (10 + ((config >> 9) & 7));
-                break;
-        default:
-                icache_size = 1 << (12 + ((config >> 9) & 7));
-                break;
-        }
-	ic_lsize = 16 << ((config >> 5) & 1);
-
-	printk("Primary instruction cache %dkb, linesize %d bytes.\n",
-	       icache_size >> 10, ic_lsize);
-}
-
-static void __init probe_dcache(unsigned long config)
-{
-        switch (mips_cpu.cputype) {
-        case CPU_VR41XX:
-                dcache_size = 1 << (10 + ((config >> 6) & 7));
-                break;
-        default:
-                dcache_size = 1 << (12 + ((config >> 6) & 7));
-                break;
-        }
-	dc_lsize = 16 << ((config >> 4) & 1);
-
-	printk("Primary data cache %dkb, linesize %d bytes.\n",
-	       dcache_size >> 10, dc_lsize);
-}
-
-
-/* If you even _breathe_ on this function, look at the gcc output
- * and make sure it does not pop things on and off the stack for
- * the cache sizing loop that executes in KSEG1 space or else
- * you will crash and burn badly.  You have been warned.
- */
-static int __init probe_scache(unsigned long config)
-{
-	extern unsigned long stext;
-	unsigned long flags, addr, begin, end, pow2;
-	int tmp;
-
-	tmp = ((config >> 17) & 1);
-	if(tmp)
-		return 0;
-	tmp = ((config >> 22) & 3);
-	switch(tmp) {
-	case 0:
-		sc_lsize = 16;
-		break;
-	case 1:
-		sc_lsize = 32;
-		break;
-	case 2:
-		sc_lsize = 64;
-		break;
-	case 3:
-		sc_lsize = 128;
-		break;
-	}
-
-	begin = (unsigned long) &stext;
-	begin &= ~((4 * 1024 * 1024) - 1);
-	end = begin + (4 * 1024 * 1024);
-
-	/* This is such a bitch, you'd think they would make it
-	 * easy to do this.  Away you daemons of stupidity!
-	 */
-	__save_and_cli(flags);
-
-	/* Fill each size-multiple cache line with a valid tag. */
-	pow2 = (64 * 1024);
-	for(addr = begin; addr < end; addr = (begin + pow2)) {
-		unsigned long *p = (unsigned long *) addr;
-		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
-		pow2 <<= 1;
-	}
-
-	/* Load first line with zero (therefore invalid) tag. */
-	set_taglo(0);
-	set_taghi(0);
-	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
-	__asm__ __volatile__("\n\t.set noreorder\n\t"
-			     ".set mips3\n\t"
-			     "cache 8, (%0)\n\t"
-			     ".set mips0\n\t"
-			     ".set reorder\n\t" : : "r" (begin));
-	__asm__ __volatile__("\n\t.set noreorder\n\t"
-			     ".set mips3\n\t"
-			     "cache 9, (%0)\n\t"
-			     ".set mips0\n\t"
-			     ".set reorder\n\t" : : "r" (begin));
-	__asm__ __volatile__("\n\t.set noreorder\n\t"
-			     ".set mips3\n\t"
-			     "cache 11, (%0)\n\t"
-			     ".set mips0\n\t"
-			     ".set reorder\n\t" : : "r" (begin));
-
-	/* Now search for the wrap around point. */
-	pow2 = (128 * 1024);
-	tmp = 0;
-	for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
-		__asm__ __volatile__("\n\t.set noreorder\n\t"
-				     ".set mips3\n\t"
-				     "cache 7, (%0)\n\t"
-				     ".set mips0\n\t"
-				     ".set reorder\n\t" : : "r" (addr));
-		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
-		if(!get_taglo())
-			break;
-		pow2 <<= 1;
-	}
-	__restore_flags(flags);
-	addr -= begin;
-	printk("Secondary cache sized at %dK linesize %d bytes.\n",
-	       (int) (addr >> 10), sc_lsize);
-	scache_size = addr;
-	return 1;
-}
-
-static void __init setup_noscache_funcs(void)
-{
-	unsigned int prid;
-
-	switch(dc_lsize) {
-	case 16:
-		_clear_page = r4k_clear_page_d16;
-		_copy_page = r4k_copy_page_d16;
-		_flush_cache_all = r4k_flush_cache_all_d16i16;
-		_flush_cache_mm = r4k_flush_cache_mm_d16i16;
-		_flush_cache_range = r4k_flush_cache_range_d16i16;
-		_flush_cache_page = r4k_flush_cache_page_d16i16;
-		_flush_page_to_ram = r4k_flush_page_to_ram_d16;
-		break;
-	case 32:
-		prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0;
-		if (prid == 0x2010) {			/* R4600 V1.7 */
-			_clear_page = r4k_clear_page_r4600_v1;
-			_copy_page = r4k_copy_page_r4600_v1;
-			_flush_page_to_ram = r4k_flush_page_to_ram_d32_r4600;
-		} else if (prid == 0x2020) {		/* R4600 V2.0 */
-			_clear_page = r4k_clear_page_r4600_v2;
-			_copy_page = r4k_copy_page_r4600_v2;
-			_flush_page_to_ram = r4k_flush_page_to_ram_d32;
-		} else {
-			_clear_page = r4k_clear_page_d32;
-			_copy_page = r4k_copy_page_d32;
-			_flush_page_to_ram = r4k_flush_page_to_ram_d32;
-		}
-		_flush_cache_all = r4k_flush_cache_all_d32i32;
-		_flush_cache_mm = r4k_flush_cache_mm_d32i32;
-		_flush_cache_range = r4k_flush_cache_range_d32i32;
-		_flush_cache_page = r4k_flush_cache_page_d32i32;
-		break;
-	}
-	___flush_cache_all = _flush_cache_all;
-
-	_flush_icache_page = r4k_flush_icache_page_p;
-
-	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
-	_dma_cache_wback = r4k_dma_cache_wback;
-	_dma_cache_inv = r4k_dma_cache_inv_pc;
-}
-
-static void __init setup_scache_funcs(void)
-{
-	switch(sc_lsize) {
-	case 16:
-		switch(dc_lsize) {
-		case 16:
-			_flush_cache_all = r4k_flush_cache_all_s16d16i16;
-			_flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
-			_flush_cache_range = r4k_flush_cache_range_s16d16i16;
-			_flush_cache_page = r4k_flush_cache_page_s16d16i16;
-			break;
-		case 32:
-			panic("Invalid cache configuration detected");
-		};
-		_flush_page_to_ram = r4k_flush_page_to_ram_s16;
-		_clear_page = r4k_clear_page_s16;
-		_copy_page = r4k_copy_page_s16;
-		break;
-	case 32:
-		switch(dc_lsize) {
-		case 16:
-			_flush_cache_all = r4k_flush_cache_all_s32d16i16;
-			_flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
-			_flush_cache_range = r4k_flush_cache_range_s32d16i16;
-			_flush_cache_page = r4k_flush_cache_page_s32d16i16;
-			break;
-		case 32:
-			_flush_cache_all = r4k_flush_cache_all_s32d32i32;
-			_flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
-			_flush_cache_range = r4k_flush_cache_range_s32d32i32;
-			_flush_cache_page = r4k_flush_cache_page_s32d32i32;
-			break;
-		};
-		_flush_page_to_ram = r4k_flush_page_to_ram_s32;
-		_clear_page = r4k_clear_page_s32;
-		_copy_page = r4k_copy_page_s32;
-		break;
-	case 64:
-		switch(dc_lsize) {
-		case 16:
-			_flush_cache_all = r4k_flush_cache_all_s64d16i16;
-			_flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
-			_flush_cache_range = r4k_flush_cache_range_s64d16i16;
-			_flush_cache_page = r4k_flush_cache_page_s64d16i16;
-			break;
-		case 32:
-			_flush_cache_all = r4k_flush_cache_all_s64d32i32;
-			_flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
-			_flush_cache_range = r4k_flush_cache_range_s64d32i32;
-			_flush_cache_page = r4k_flush_cache_page_s64d32i32;
-			break;
-		};
-		_flush_page_to_ram = r4k_flush_page_to_ram_s64;
-		_clear_page = r4k_clear_page_s64;
-		_copy_page = r4k_copy_page_s64;
-		break;
-	case 128:
-		switch(dc_lsize) {
-		case 16:
-			_flush_cache_all = r4k_flush_cache_all_s128d16i16;
-			_flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
-			_flush_cache_range = r4k_flush_cache_range_s128d16i16;
-			_flush_cache_page = r4k_flush_cache_page_s128d16i16;
-			break;
-		case 32:
-			_flush_cache_all = r4k_flush_cache_all_s128d32i32;
-			_flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
-			_flush_cache_range = r4k_flush_cache_range_s128d32i32;
-			_flush_cache_page = r4k_flush_cache_page_s128d32i32;
-			break;
-		};
-		_flush_page_to_ram = r4k_flush_page_to_ram_s128;
-		_clear_page = r4k_clear_page_s128;
-		_copy_page = r4k_copy_page_s128;
-		break;
-	}
-	___flush_cache_all = _flush_cache_all;
-	_flush_icache_page = r4k_flush_icache_page_s;
-	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
-	_dma_cache_wback = r4k_dma_cache_wback;
-	_dma_cache_inv = r4k_dma_cache_inv_sc;
-}
-
-typedef int (*probe_func_t)(unsigned long);
-
-static inline void __init setup_scache(unsigned int config)
-{
-	probe_func_t probe_scache_kseg1;
-	int sc_present = 0;
-
-	/* Maybe the cpu knows about a l2 cache? */
-	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
-	sc_present = probe_scache_kseg1(config);
-
-	if (sc_present) {
-		setup_scache_funcs();
-		return;
-	}
-
-	setup_noscache_funcs();
-}
-
-void __init ld_mmu_r4xx0(void)
-{
-	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
-
-	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
-
-#ifdef CONFIG_MIPS_UNCACHED
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-#else
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif
-
-	probe_icache(config);
-	probe_dcache(config);
-	setup_scache(config);
-
-	switch(mips_cpu.cputype) {
-	case CPU_R4600:			/* QED style two way caches? */
-	case CPU_R4700:
-	case CPU_R5000:
-	case CPU_NEVADA:
-		_flush_cache_page = r4k_flush_cache_page_d32i32_r4600;
-	}
-
-	_flush_cache_sigtramp = r4k_flush_cache_sigtramp;
-	_flush_icache_range = r4k_flush_icache_range;	/* Ouch */
-	if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) {
-		_flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
-	}
-
-	__flush_cache_all();
-	write_32bit_cp0_register(CP0_WIRED, 0);
-
-	/*
-	 * You should never change this register:
-	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
-	 *     the value in the c0_pagemask register.
-	 *   - The entire mm handling assumes the c0_pagemask register to
-	 *     be set for 4kb pages.
-	 */
-	set_pagemask(PM_4K);
-	flush_tlb_all();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/r5432.c linux/arch/mips/mm/r5432.c
--- linux.orig/arch/mips/mm/r5432.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/mips/mm/r5432.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,862 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * r5432.c: NEC Vr5432 processor.  We cannot use r4xx0.c because of
- *      its unique way-selection method for indexed operations.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 2000 Jun Sun (jsun@mvista.com)
- *
- */
-
-/*
- * [jsun]
- * In a sense, this is really silly.  We cannot re-use r4xx0.c because
- * the lowest-level indexed cache operation does not take way-selection
- * into account.  So all what I am doing here is to copy all the funcs
- * and macros (in r4kcache.h) relavent to R5432 to this file, and then
- * modify a few indexed cache operations.  *sigh*
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/bcache.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/bootinfo.h>
-#include <asm/mmu_context.h>
-
-/* CP0 hazard avoidance. */
-#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
-				     "nop; nop; nop; nop; nop; nop;\n\t" \
-				     ".set reorder\n\t")
-
-#include <asm/asm.h>
-#include <asm/cacheops.h>
-
-#undef DEBUG_CACHE
-
-/* Primary cache parameters. */
-static int icache_size, dcache_size; /* Size in bytes */
-static int ic_lsize, dc_lsize;       /* LineSize in bytes */
-
-
-/* -------------------------------------------------------------------- */
-/* #include <asm/r4kcache.h> */
-
-extern inline void flush_icache_line_indexed(unsigned long addr)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
-		"cache %1, (%0)\n\t"
-		"cache %1, 1(%0)\n\t"
-		".set mips0\n\t"
-		".set reorder"
-		:
-		: "r" (addr),
-		  "i" (Index_Invalidate_I));
-}
-
-extern inline void flush_dcache_line_indexed(unsigned long addr)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
-		"cache %1, (%0)\n\t"
-		"cache %1, 1(%0)\n\t"
-		".set mips0\n\t"
-		".set reorder"
-		:
-		: "r" (addr),
-		  "i" (Index_Writeback_Inv_D));
-}
-
-extern inline void flush_icache_line(unsigned long addr)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
-		"cache %1, (%0)\n\t"
-		".set mips0\n\t"
-		".set reorder"
-		:
-		: "r" (addr),
-		  "i" (Hit_Invalidate_I));
-}
-
-extern inline void flush_dcache_line(unsigned long addr)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
-		"cache %1, (%0)\n\t"
-		".set mips0\n\t"
-		".set reorder"
-		:
-		: "r" (addr),
-		  "i" (Hit_Writeback_Inv_D));
-}
-
-extern inline void invalidate_dcache_line(unsigned long addr)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n\t"
-		"cache %1, (%0)\n\t"
-		".set mips0\n\t"
-		".set reorder"
-		:
-		: "r" (addr),
-		  "i" (Hit_Invalidate_D));
-}
-
-
-/*
- * The next two are for badland addresses like signal trampolines.
- */
-extern inline void protected_flush_icache_line(unsigned long addr)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n"
-		"1:\tcache %1,(%0)\n"
-		"2:\t.set mips0\n\t"
-		".set reorder\n\t"
-		".section\t__ex_table,\"a\"\n\t"
-		STR(PTR)"\t1b,2b\n\t"
-		".previous"
-		:
-		: "r" (addr),
-		  "i" (Hit_Invalidate_I));
-}
-
-extern inline void protected_writeback_dcache_line(unsigned long addr)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		".set mips3\n"
-		"1:\tcache %1,(%0)\n"
-		"2:\t.set mips0\n\t"
-		".set reorder\n\t"
-		".section\t__ex_table,\"a\"\n\t"
-		STR(PTR)"\t1b,2b\n\t"
-		".previous"
-		:
-		: "r" (addr),
-		  "i" (Hit_Writeback_D));
-}
-
-
-#define cache32_unroll32(base,op)				\
-	__asm__ __volatile__("					\
-		.set noreorder;					\
-		.set mips3;					\
-		cache %1, 0x000(%0); cache %1, 0x020(%0);	\
-		cache %1, 0x040(%0); cache %1, 0x060(%0);	\
-		cache %1, 0x080(%0); cache %1, 0x0a0(%0);	\
-		cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);	\
-		cache %1, 0x100(%0); cache %1, 0x120(%0);	\
-		cache %1, 0x140(%0); cache %1, 0x160(%0);	\
-		cache %1, 0x180(%0); cache %1, 0x1a0(%0);	\
-		cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);	\
-		cache %1, 0x200(%0); cache %1, 0x220(%0);	\
-		cache %1, 0x240(%0); cache %1, 0x260(%0);	\
-		cache %1, 0x280(%0); cache %1, 0x2a0(%0);	\
-		cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);	\
-		cache %1, 0x300(%0); cache %1, 0x320(%0);	\
-		cache %1, 0x340(%0); cache %1, 0x360(%0);	\
-		cache %1, 0x380(%0); cache %1, 0x3a0(%0);	\
-		cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);	\
-		.set mips0;					\
-		.set reorder"					\
-		:						\
-		: "r" (base),					\
-		  "i" (op));
-
-extern inline void blast_dcache32(void)
-{
-	unsigned long start = KSEG0;
-	unsigned long end = (start + dcache_size/2);
-
-	while(start < end) {
-		cache32_unroll32(start,Index_Writeback_Inv_D);
-		cache32_unroll32(start+1,Index_Writeback_Inv_D);
-		start += 0x400;
-	}
-}
-
-extern inline void blast_dcache32_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = (start + PAGE_SIZE);
-
-	while(start < end) {
-		cache32_unroll32(start,Hit_Writeback_Inv_D);
-		start += 0x400;
-	}
-}
-
-extern inline void blast_dcache32_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = (start + PAGE_SIZE);
-
-	while(start < end) {
-		cache32_unroll32(start,Index_Writeback_Inv_D);
-		cache32_unroll32(start+1,Index_Writeback_Inv_D);
-		start += 0x400;
-	}
-}
-
-extern inline void blast_icache32(void)
-{
-	unsigned long start = KSEG0;
-	unsigned long end = (start + icache_size/2);
-
-	while(start < end) {
-		cache32_unroll32(start,Index_Invalidate_I);
-		cache32_unroll32(start+1,Index_Invalidate_I);
-		start += 0x400;
-	}
-}
-
-extern inline void blast_icache32_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = (start + PAGE_SIZE);
-
-	while(start < end) {
-		cache32_unroll32(start,Hit_Invalidate_I);
-		start += 0x400;
-	}
-}
-
-extern inline void blast_icache32_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = (start + PAGE_SIZE);
-
-	while(start < end) {
-		cache32_unroll32(start,Index_Invalidate_I);
-		cache32_unroll32(start+1,Index_Invalidate_I);
-		start += 0x400;
-	}
-}
-
-/* -------------------------------------------------------------------- */
-
-static void r5432_clear_page_d32(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D)
-		:"$1","memory");
-}
-
-
-
-/*
- * This is still inefficient.  We only can do better if we know the
- * virtual address where the copy will be accessed.
- */
-
-static void r5432_copy_page_d32(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"cache\t%9,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-}
-
-
-/*
- * If you think for one second that this stuff coming up is a lot
- * of bulky code eating too many kernel cache lines.  Think _again_.
- *
- * Consider:
- * 1) Taken branches have a 3 cycle penalty on R4k
- * 2) The branch itself is a real dead cycle on even R4600/R5000.
- * 3) Only one of the following variants of each type is even used by
- *    the kernel based upon the cache parameters we detect at boot time.
- *
- * QED.
- */
-
-static inline void r5432_flush_cache_all_d32i32(void)
-{
-	blast_dcache32(); blast_icache32();
-}
-
-static void r5432_flush_cache_range_d32i32(struct mm_struct *mm,
-					 unsigned long start,
-					 unsigned long end)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-		blast_dcache32(); blast_icache32();
-	}
-}
-
-/*
- * On architectures like the Sparc, we could get rid of lines in
- * the cache created only by a certain context, but on the MIPS
- * (and actually certain Sparc's) we cannot.
- */
-static void r5432_flush_cache_mm_d32i32(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-#ifdef DEBUG_CACHE
-		printk("cmm[%d]", (int)mm->context);
-#endif
-		r5432_flush_cache_all_d32i32();
-	}
-}
-
-static void r5432_flush_cache_page_d32i32(struct vm_area_struct *vma,
-					unsigned long page)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (mm->context == 0)
-		return;
-
-#ifdef DEBUG_CACHE
-	printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-	page &= PAGE_MASK;
-	pgdp = pgd_offset(mm, page);
-	pmdp = pmd_offset(pgdp, page);
-	ptep = pte_offset(pmdp, page);
-
-	/*
-	 * If the page isn't marked valid, the page cannot possibly be
-	 * in the cache.
-	 */
-	if (!(pte_val(*ptep) & _PAGE_PRESENT))
-		return;
-
-	/*
-	 * Doing flushes for another ASID than the current one is
-	 * too difficult since stupid R4k caches do a TLB translation
-	 * for every cache flush operation.  So we do indexed flushes
-	 * in that case, which doesn't overly flush the cache too much.
-	 */
-	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
-		blast_dcache32_page(page);
-	} else {
-		/*
-		 * Do indexed flush, too much work to get the (possible)
-		 * tlb refills to work correctly.
-		 */
-		page = (KSEG0 + (page & (dcache_size - 1)));
-		blast_dcache32_page_indexed(page);
-	}
-}
-
-
-/* If the addresses passed to these routines are valid, they are
- * either:
- *
- * 1) In KSEG0, so we can do a direct flush of the page.
- * 2) In KSEG2, and since every process can translate those
- *    addresses all the time in kernel mode we can do a direct
- *    flush.
- * 3) In KSEG1, no flush necessary.
- */
-static void r5432_flush_page_to_ram_d32(struct page *page)
-{
-	blast_dcache32_page((unsigned long)page_address(page));
-}
-
-static void 
-r5432_flush_icache_range(unsigned long start, unsigned long end)
-{
-	r5432_flush_cache_all_d32i32();
-}
-
-/*
- * Ok, this seriously sucks.  We use them to flush a user page but don't
- * know the virtual address, so we have to blast away the whole icache
- * which is significantly more expensive than the real thing.
- */
-static void
-r5432_flush_icache_page_i32(struct vm_area_struct *vma, struct page *page)
-{
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-
-	r5432_flush_cache_all_d32i32();
-}
-
-/*
- * Writeback and invalidate the primary cache dcache before DMA.
- */
-static void
-r5432_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-
-	if (size >= dcache_size) {
-		flush_cache_all();
-	} else {
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
-		while (1) {
-			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
-			if (a == end) break;
-			a += dc_lsize;
-		}
-	}
-	bc_wback_inv(addr, size);
-}
-
-static void
-r5432_dma_cache_inv_pc(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-
-	if (size >= dcache_size) {
-		flush_cache_all();
-	} else {
-		a = addr & ~(dc_lsize - 1);
-		end = (addr + size) & ~(dc_lsize - 1);
-		while (1) {
-			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
-			if (a == end) break;
-			a += dc_lsize;
-		}
-	}
-
-	bc_inv(addr, size);
-}
-
-static void
-r5432_dma_cache_wback(unsigned long addr, unsigned long size)
-{
-	panic("r5432_dma_cache called - should not happen.\n");
-}
-
-/*
- * While we're protected against bad userland addresses we don't care
- * very much about what happens in that case.  Usually a segmentation
- * fault will dump the process later on anyway ...
- */
-static void r5432_flush_cache_sigtramp(unsigned long addr)
-{
-	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
-	protected_flush_icache_line(addr & ~(ic_lsize - 1));
-}
-
-#undef DEBUG_TLB
-#undef DEBUG_TLBUPDATE
-
-#define NTLB_ENTRIES       48  /* Fixed on all R4XX0 variants... */
-
-#define NTLB_ENTRIES_HALF  24  /* Fixed on all R4XX0 variants... */
-
-void flush_tlb_all(void)
-{
-	unsigned long old_ctx;
-	int entry;
-	unsigned long flags;
-
-#ifdef DEBUG_TLB
-	printk("[tlball]");
-#endif
-
-	__save_and_cli(flags);
-	/* Save old context and create impossible VPN2 value */
-	old_ctx = (get_entryhi() & 0xff);
-	set_entryhi(KSEG0);
-	set_entrylo0(0);
-	set_entrylo1(0);
-	BARRIER;
-
-	entry = get_wired();
-
-	/* Blast 'em all away. */
-	while(entry < NTLB_ENTRIES) {
-		set_index(entry);
-		BARRIER;
-		tlb_write_indexed();
-		BARRIER;
-		entry++;
-	}
-	BARRIER;
-	set_entryhi(old_ctx);
-	__restore_flags(flags);
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	if (mm->context != 0) {
-		unsigned long flags;
-
-#ifdef DEBUG_TLB
-		printk("[tlbmm<%d>]", mm->context);
-#endif
-		__save_and_cli(flags);
-		get_new_mmu_context(mm, asid_cache);
-		if (mm == current->active_mm)
-			set_entryhi(mm->context & 0xff);
-		__restore_flags(flags);
-	}
-}
-
-void flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				unsigned long end)
-{
-	if(mm->context != 0) {
-		unsigned long flags;
-		int size;
-
-#ifdef DEBUG_TLB
-		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
-		       start, end);
-#endif
-		__save_and_cli(flags);
-		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-		size = (size + 1) >> 1;
-		if(size <= NTLB_ENTRIES_HALF) {
-			int oldpid = (get_entryhi() & 0xff);
-			int newpid = (mm->context & 0xff);
-
-			start &= (PAGE_MASK << 1);
-			end += ((PAGE_SIZE << 1) - 1);
-			end &= (PAGE_MASK << 1);
-			while(start < end) {
-				int idx;
-
-				set_entryhi(start | newpid);
-				start += (PAGE_SIZE << 1);
-				BARRIER;
-				tlb_probe();
-				BARRIER;
-				idx = get_index();
-				set_entrylo0(0);
-				set_entrylo1(0);
-				set_entryhi(KSEG0);
-				BARRIER;
-				if(idx < 0)
-					continue;
-				tlb_write_indexed();
-				BARRIER;
-			}
-			set_entryhi(oldpid);
-		} else {
-			get_new_mmu_context(mm, asid_cache);
-			if (mm == current->active_mm)
-				set_entryhi(mm->context & 0xff);
-		}
-		__restore_flags(flags);
-	}
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	if (vma->vm_mm->context != 0) {
-		unsigned long flags;
-		int oldpid, newpid, idx;
-
-#ifdef DEBUG_TLB
-		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
-#endif
-		newpid = (vma->vm_mm->context & 0xff);
-		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
-		oldpid = (get_entryhi() & 0xff);
-		set_entryhi(page | newpid);
-		BARRIER;
-		tlb_probe();
-		BARRIER;
-		idx = get_index();
-		set_entrylo0(0);
-		set_entrylo1(0);
-		set_entryhi(KSEG0);
-		if(idx < 0)
-			goto finish;
-		BARRIER;
-		tlb_write_indexed();
-
-	finish:
-		BARRIER;
-		set_entryhi(oldpid);
-		__restore_flags(flags);
-	}
-}
-
-void pgd_init(unsigned long page)
-{
-	unsigned long *p = (unsigned long *) page;
-	int i;
-
-	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
-		p[i + 0] = (unsigned long) invalid_pte_table;
-		p[i + 1] = (unsigned long) invalid_pte_table;
-		p[i + 2] = (unsigned long) invalid_pte_table;
-		p[i + 3] = (unsigned long) invalid_pte_table;
-		p[i + 4] = (unsigned long) invalid_pte_table;
-		p[i + 5] = (unsigned long) invalid_pte_table;
-		p[i + 6] = (unsigned long) invalid_pte_table;
-		p[i + 7] = (unsigned long) invalid_pte_table;
-	}
-}
-
-/* We will need multiple versions of update_mmu_cache(), one that just
- * updates the TLB with the new pte(s), and another which also checks
- * for the R4k "end of page" hardware bug and does the needy.
- */
-void update_mmu_cache(struct vm_area_struct * vma,
-				 unsigned long address, pte_t pte)
-{
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-	int idx, pid;
-
-	/*
-	 * Handle debugger faulting in for debugee.
-	 */
-	if (current->active_mm != vma->vm_mm)
-		return;
-
-	pid = get_entryhi() & 0xff;
-
-#ifdef DEBUG_TLB
-	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
-		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
-		       (int) (vma->vm_mm->context & 0xff), pid);
-	}
-#endif
-
-	__save_and_cli(flags);
-	address &= (PAGE_MASK << 1);
-	set_entryhi(address | (pid));
-	pgdp = pgd_offset(vma->vm_mm, address);
-	BARRIER;
-	tlb_probe();
-	BARRIER;
-	pmdp = pmd_offset(pgdp, address);
-	idx = get_index();
-	ptep = pte_offset(pmdp, address);
-	BARRIER;
-	set_entrylo0(pte_val(*ptep++) >> 6);
-	set_entrylo1(pte_val(*ptep) >> 6);
-	set_entryhi(address | (pid));
-	BARRIER;
-	if(idx < 0) {
-		tlb_write_random();
-	} else {
-		tlb_write_indexed();
-	}
-	BARRIER;
-	set_entryhi(pid);
-	BARRIER;
-	__restore_flags(flags);
-}
-
-void show_regs(struct pt_regs * regs)
-{
-	/* Saved main processor registers. */
-	printk("$0 : %08lx %08lx %08lx %08lx\n",
-	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
-	printk("$4 : %08lx %08lx %08lx %08lx\n",
-               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
-	printk("$8 : %08lx %08lx %08lx %08lx\n",
-	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
-	printk("$12: %08lx %08lx %08lx %08lx\n",
-               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
-	printk("$16: %08lx %08lx %08lx %08lx\n",
-	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
-	printk("$20: %08lx %08lx %08lx %08lx\n",
-               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
-	printk("$24: %08lx %08lx\n",
-	       regs->regs[24], regs->regs[25]);
-	printk("$28: %08lx %08lx %08lx %08lx\n",
-	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
-
-	/* Saved cp0 registers. */
-	printk("epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
-}
-			
-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-		     unsigned long entryhi, unsigned long pagemask)
-{
-        unsigned long flags;
-        unsigned long wired;
-        unsigned long old_pagemask;
-        unsigned long old_ctx;
-
-        __save_and_cli(flags);
-        /* Save old context and create impossible VPN2 value */
-        old_ctx = (get_entryhi() & 0xff);
-        old_pagemask = get_pagemask();
-        wired = get_wired();
-        set_wired (wired + 1);
-        set_index (wired);
-        BARRIER;    
-        set_pagemask (pagemask);
-        set_entryhi(entryhi);
-        set_entrylo0(entrylo0);
-        set_entrylo1(entrylo1);
-        BARRIER;    
-        tlb_write_indexed();
-        BARRIER;    
-    
-        set_entryhi(old_ctx);
-        BARRIER;    
-        set_pagemask (old_pagemask);
-        flush_tlb_all();    
-        __restore_flags(flags);
-}
-
-/* Detect and size the various r4k caches. */
-static void __init probe_icache(unsigned long config)
-{
-	icache_size = 1 << (12 + ((config >> 9) & 7));
-	ic_lsize = 16 << ((config >> 5) & 1);
-
-	printk("Primary instruction cache %dkb, linesize %d bytes.\n",
-	       icache_size >> 10, ic_lsize);
-}
-
-static void __init probe_dcache(unsigned long config)
-{
-	dcache_size = 1 << (12 + ((config >> 6) & 7));
-	dc_lsize = 16 << ((config >> 4) & 1);
-
-	printk("Primary data cache %dkb, linesize %d bytes.\n",
-	       dcache_size >> 10, dc_lsize);
-}
-
-
-void __init ld_mmu_r5432(void)
-{
-	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
-
-	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
-
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-
-	probe_icache(config);
-	probe_dcache(config);
-
-	_clear_page = r5432_clear_page_d32;
-	_copy_page = r5432_copy_page_d32;
-	_flush_cache_all = r5432_flush_cache_all_d32i32;
-	___flush_cache_all = r5432_flush_cache_all_d32i32;
-	_flush_page_to_ram = r5432_flush_page_to_ram_d32;
-	_flush_cache_mm = r5432_flush_cache_mm_d32i32;
-	_flush_cache_range = r5432_flush_cache_range_d32i32;
-	_flush_cache_page = r5432_flush_cache_page_d32i32;
-	_flush_icache_page = r5432_flush_icache_page_i32;
-	_dma_cache_wback_inv = r5432_dma_cache_wback_inv_pc;
-	_dma_cache_wback = r5432_dma_cache_wback;
-	_dma_cache_inv = r5432_dma_cache_inv_pc;
-
-	_flush_cache_sigtramp = r5432_flush_cache_sigtramp;
-	_flush_icache_range = r5432_flush_icache_range;	/* Ouch */
-
-	__flush_cache_all();
-	write_32bit_cp0_register(CP0_WIRED, 0);
-
-	/*
-	 * You should never change this register:
-	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
-	 *     the value in the c0_pagemask register.
-	 *   - The entire mm handling assumes the c0_pagemask register to
-	 *     be set for 4kb pages.
-	 */
-	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
-	flush_tlb_all();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/rm7k.c linux/arch/mips/mm/rm7k.c
--- linux.orig/arch/mips/mm/rm7k.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/mips/mm/rm7k.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,751 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org
- *
- * To do:
- *
- *  - this code is a overbloated pig
- *  - many of the bug workarounds are not efficient at all, but at
- *    least they are functional ...
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/bootinfo.h>
-#include <asm/mmu_context.h>
-
-/* CP0 hazard avoidance. */
-#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
-				     "nop; nop; nop; nop; nop; nop;\n\t" \
-				     ".set reorder\n\t")
-
-/* Primary cache parameters. */
-static int icache_size, dcache_size; /* Size in bytes */
-
-#define ic_lsize	32		/* Fixed to 32 byte on RM7000  */
-#define dc_lsize	32		/* Fixed to 32 byte on RM7000  */
-#define sc_lsize	32		/* Fixed to 32 byte on RM7000  */
-#define tc_pagesize	(32*128)
-
-/* Secondary cache parameters. */
-#define scache_size	(256*1024)	/* Fixed to 256KiB on RM7000 */
-
-#include <asm/cacheops.h>
-#include <asm/r4kcache.h>
-
-int rm7k_tcache_enabled = 0;
-
-/*
- * Not added to asm/r4kcache.h because it seems to be RM7000-specific.
- */
-#define Page_Invalidate_T 0x16
-
-static inline void invalidate_tcache_page(unsigned long addr)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\t\t\t# invalidate_tcache_page\n\t"
-		".set\tmips3\n\t"
-		"cache\t%1, (%0)\n\t"
-		".set\tmips0\n\t"
-		".set\treorder"
-		:
-		: "r" (addr),
-		  "i" (Page_Invalidate_T));
-}
-
-/*
- * Zero an entire page.  Note that while the RM7000 has a second level cache
- * it doesn't have a Create_Dirty_Excl_SD operation.
- */
-static void rm7k_clear_page(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D)
-		:"$1","memory");
-}
-
-
-/*
- * Copy an entire page.  Note that while the RM7000 has a second level cache
- * it doesn't have a Create_Dirty_Excl_SD operation.
- */
-static void rm7k_copy_page(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		".set\tmips3\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"lw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"cache\t%9,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tmips0\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-}
-
-static void __flush_cache_all_d32i32(void)
-{
-	blast_dcache32();
-	blast_icache32();
-}
-
-static inline void rm7k_flush_cache_all_d32i32(void)
-{
-	/* Yes! Caches that don't suck ...  */
-}
-
-static void rm7k_flush_cache_range_d32i32(struct mm_struct *mm,
-					 unsigned long start,
-					 unsigned long end)
-{
-	/* RM7000 caches are sane ...  */
-}
-
-static void rm7k_flush_cache_mm_d32i32(struct mm_struct *mm)
-{
-	/* RM7000 caches are sane ...  */
-}
-
-static void rm7k_flush_cache_page_d32i32(struct vm_area_struct *vma,
-					unsigned long page)
-{
-	/* RM7000 caches are sane ...  */
-}
-
-static void rm7k_flush_page_to_ram_d32i32(struct page * page)
-{
-	/* Yes!  Caches that don't suck!  */
-}
-
-static void rm7k_flush_icache_range(unsigned long start, unsigned long end)
-{
-	/*
-	 * FIXME: This is overdoing things and harms performance.
-	 */
-	__flush_cache_all_d32i32();
-}
-
-static void rm7k_flush_icache_page(struct vm_area_struct *vma,
-                                   struct page *page)
-{
-	/*
-	 * FIXME: We should not flush the entire cache but establish some
-	 * temporary mapping and use hit_invalidate operation to flush out
-	 * the line from the cache.
-	 */
-	__flush_cache_all_d32i32();
-}
-
-
-/*
- * Writeback and invalidate the primary cache dcache before DMA.
- * (XXX These need to be fixed ...)
- */
-static void
-rm7k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-
-	a = addr & ~(sc_lsize - 1);
-	end = (addr + size) & ~(sc_lsize - 1);
-	while (1) {
-		flush_dcache_line(a);	/* Hit_Writeback_Inv_D */
-		flush_icache_line(a);	/* Hit_Invalidate_I */
-		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
-		if (a == end) break;
-		a += sc_lsize;
-	}
-
-	if (!rm7k_tcache_enabled) 
-		return;
-
-	a = addr & ~(tc_pagesize - 1);
-	end = (addr + size) & ~(tc_pagesize - 1);
-	while(1) {
-		invalidate_tcache_page(a);	/* Page_Invalidate_T */
-		if (a == end) break;
-		a += tc_pagesize;
-	}
-}
-	       
-static void
-rm7k_dma_cache_inv(unsigned long addr, unsigned long size)
-{
-	unsigned long end, a;
-
-	a = addr & ~(sc_lsize - 1);
-	end = (addr + size) & ~(sc_lsize - 1);
-	while (1) {
-		invalidate_dcache_line(a);	/* Hit_Invalidate_D */
-		flush_icache_line(a);		/* Hit_Invalidate_I */
-		invalidate_scache_line(a);	/* Hit_Invalidate_SD */
-		if (a == end) break;
-		a += sc_lsize;
-	}
-
-	if (!rm7k_tcache_enabled) 
-		return;
-
-	a = addr & ~(tc_pagesize - 1);
-	end = (addr + size) & ~(tc_pagesize - 1);
-	while(1) {
-		invalidate_tcache_page(a);	/* Page_Invalidate_T */
-		if (a == end) break;
-		a += tc_pagesize;
-	}
-}
-
-static void
-rm7k_dma_cache_wback(unsigned long addr, unsigned long size)
-{
-	panic("rm7k_dma_cache_wback called - should not happen.\n");
-}
-
-/*
- * While we're protected against bad userland addresses we don't care
- * very much about what happens in that case.  Usually a segmentation
- * fault will dump the process later on anyway ...
- */
-static void rm7k_flush_cache_sigtramp(unsigned long addr)
-{
-	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
-	protected_flush_icache_line(addr & ~(ic_lsize - 1));
-}
-
-/*
- * Undocumented RM7000:  Bit 29 in the info register of the RM7000 v2.0
- * indicates if the TLB has 48 or 64 entries.
- *
- * 29      1 =>    64 entry JTLB
- *         0 =>    48 entry JTLB
- */
-static inline int __attribute__((const)) ntlb_entries(void)
-{
-	if (get_info() & (1 << 29))
-		return 64;
-
-	return 48;
-}
-
-void flush_tlb_all(void)
-{
-	unsigned long flags;
-	unsigned long old_ctx;
-	int entry;
-
-	__save_and_cli(flags);
-	/* Save old context and create impossible VPN2 value */
-	old_ctx = get_entryhi() & 0xff;
-	set_entryhi(KSEG0);
-	set_entrylo0(0);
-	set_entrylo1(0);
-	BARRIER;
-
-	entry = get_wired();
-
-	/* Blast 'em all away. */
-	while (entry < ntlb_entries()) {
-		set_index(entry);
-		BARRIER;
-		tlb_write_indexed();
-		BARRIER;
-		entry++;
-	}
-	BARRIER;
-	set_entryhi(old_ctx);
-	__restore_flags(flags);
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	if(mm->context != 0) {
-		unsigned long flags;
-
-		__save_and_cli(flags);
-		get_new_mmu_context(mm, asid_cache);
-		if (mm == current->mm)
-			set_entryhi(mm->context & 0xff);
-		__restore_flags(flags);
-	}
-}
-
-void flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				unsigned long end)
-{
-	if(mm->context != 0) {
-		unsigned long flags;
-		int size;
-
-		__save_and_cli(flags);
-		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-		size = (size + 1) >> 1;
-		if (size <= (ntlb_entries() / 2)) {
-			int oldpid = (get_entryhi() & 0xff);
-			int newpid = (mm->context & 0xff);
-
-			start &= (PAGE_MASK << 1);
-			end += ((PAGE_SIZE << 1) - 1);
-			end &= (PAGE_MASK << 1);
-			while(start < end) {
-				int idx;
-
-				set_entryhi(start | newpid);
-				start += (PAGE_SIZE << 1);
-				BARRIER;
-				tlb_probe();
-				BARRIER;
-				idx = get_index();
-				set_entrylo0(0);
-				set_entrylo1(0);
-				set_entryhi(KSEG0);
-				BARRIER;
-				if(idx < 0)
-					continue;
-				tlb_write_indexed();
-				BARRIER;
-			}
-			set_entryhi(oldpid);
-		} else {
-			get_new_mmu_context(mm, asid_cache);
-			if(mm == current->mm)
-				set_entryhi(mm->context & 0xff);
-		}
-		__restore_flags(flags);
-	}
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	if(vma->vm_mm->context != 0) {
-		unsigned long flags;
-		int oldpid, newpid, idx;
-
-		newpid = (vma->vm_mm->context & 0xff);
-		page &= (PAGE_MASK << 1);
-		__save_and_cli(flags);
-		oldpid = (get_entryhi() & 0xff);
-		set_entryhi(page | newpid);
-		BARRIER;
-		tlb_probe();
-		BARRIER;
-		idx = get_index();
-		set_entrylo0(0);
-		set_entrylo1(0);
-		set_entryhi(KSEG0);
-		if(idx < 0)
-			goto finish;
-		BARRIER;
-		tlb_write_indexed();
-
-	finish:
-		BARRIER;
-		set_entryhi(oldpid);
-		__restore_flags(flags);
-	}
-}
-
-void pgd_init(unsigned long page)
-{
-	unsigned long *p = (unsigned long *) page;
-	int i;
-
-	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
-		p[i + 0] = (unsigned long) invalid_pte_table;
-		p[i + 1] = (unsigned long) invalid_pte_table;
-		p[i + 2] = (unsigned long) invalid_pte_table;
-		p[i + 3] = (unsigned long) invalid_pte_table;
-		p[i + 4] = (unsigned long) invalid_pte_table;
-		p[i + 5] = (unsigned long) invalid_pte_table;
-		p[i + 6] = (unsigned long) invalid_pte_table;
-		p[i + 7] = (unsigned long) invalid_pte_table;
-	}
-}
-
-/*
- * We will need multiple versions of update_mmu_cache(), one that just
- * updates the TLB with the new pte(s), and another which also checks
- * for the R4k "end of page" hardware bug and does the needy.
- */
-void update_mmu_cache(struct vm_area_struct * vma,
-				 unsigned long address, pte_t pte)
-{
-	unsigned long flags;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-	int idx, pid;
-
-	/*
-	 * Handle debugger faulting in for debugee.
-	 */
-	if (current->active_mm != vma->vm_mm)
-		return;
-
-	pid = get_entryhi() & 0xff;
-
-	__save_and_cli(flags);
-	address &= (PAGE_MASK << 1);
-	set_entryhi(address | (pid));
-	pgdp = pgd_offset(vma->vm_mm, address);
-	BARRIER;
-	tlb_probe();
-	BARRIER;
-	pmdp = pmd_offset(pgdp, address);
-	idx = get_index();
-	ptep = pte_offset(pmdp, address);
-	BARRIER;
-	set_entrylo0(pte_val(*ptep++) >> 6);
-	set_entrylo1(pte_val(*ptep) >> 6);
-	set_entryhi(address | (pid));
-	BARRIER;
-	if (idx < 0) {
-		tlb_write_random();
-	} else {
-		tlb_write_indexed();
-	}
-	BARRIER;
-	set_entryhi(pid);
-	BARRIER;
-	__restore_flags(flags);
-}
-
-void show_regs(struct pt_regs * regs)
-{
-	/* Saved main processor registers. */
-	printk(KERN_INFO "$0 : %08lx %08lx %08lx %08lx\n",
-	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
-	printk(KERN_INFO "$4 : %08lx %08lx %08lx %08lx\n",
-               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
-	printk(KERN_INFO "$8 : %08lx %08lx %08lx %08lx\n",
-	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
-	printk(KERN_INFO "$12: %08lx %08lx %08lx %08lx\n",
-               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
-	printk(KERN_INFO "$16: %08lx %08lx %08lx %08lx\n",
-	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
-	printk(KERN_INFO "$20: %08lx %08lx %08lx %08lx\n",
-               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
-	printk(KERN_INFO "$24: %08lx %08lx\n",
-	       regs->regs[24], regs->regs[25]);
-	printk(KERN_INFO "$28: %08lx %08lx %08lx %08lx\n",
-	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
-
-	/* Saved cp0 registers. */
-	printk(KERN_INFO "epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
-}
-
-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-                     unsigned long entryhi, unsigned long pagemask)
-{
-        unsigned long flags;
-        unsigned long wired;
-        unsigned long old_pagemask;
-        unsigned long old_ctx;
-
-        __save_and_cli(flags);
-        /* Save old context and create impossible VPN2 value */
-        old_ctx = (get_entryhi() & 0xff);
-        old_pagemask = get_pagemask();
-        wired = get_wired();
-        set_wired (wired + 1);
-        set_index (wired);
-        BARRIER;    
-        set_pagemask (pagemask);
-        set_entryhi(entryhi);
-        set_entrylo0(entrylo0);
-        set_entrylo1(entrylo1);
-        BARRIER;    
-        tlb_write_indexed();
-        BARRIER;    
-    
-        set_entryhi(old_ctx);
-        BARRIER;    
-        set_pagemask (old_pagemask);
-        flush_tlb_all();    
-        __restore_flags(flags);
-}
-
-/* Used for loading TLB entries before trap_init() has started, when we
-   don't actually want to add a wired entry which remains throughout the
-   lifetime of the system */
-
-static int temp_tlb_entry __initdata;
-
-__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
-                               unsigned long entryhi, unsigned long pagemask)
-{
-	int ret = 0;
-        unsigned long flags;
-        unsigned long wired;
-        unsigned long old_pagemask;
-        unsigned long old_ctx;
-
-        __save_and_cli(flags);
-        /* Save old context and create impossible VPN2 value */
-        old_ctx = (get_entryhi() & 0xff);
-        old_pagemask = get_pagemask();
-        wired = get_wired();
-        if (--temp_tlb_entry < wired) {
-		printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
-		ret = -ENOSPC;
-		goto out;
-	}
-
-        set_index (temp_tlb_entry);
-        BARRIER;    
-        set_pagemask (pagemask);
-        set_entryhi(entryhi);
-        set_entrylo0(entrylo0);
-        set_entrylo1(entrylo1);
-        BARRIER;    
-        tlb_write_indexed();
-        BARRIER;    
-    
-        set_entryhi(old_ctx);
-        BARRIER;    
-        set_pagemask (old_pagemask);
- out:
-        __restore_flags(flags);
-	return ret;
-}
-
-
-
-/* Detect and size the caches. */
-static inline void probe_icache(unsigned long config)
-{
-	icache_size = 1 << (12 + ((config >> 9) & 7));
-
-	printk(KERN_INFO "Primary instruction cache %dKiB.\n", icache_size >> 10);
-}
-
-static inline void probe_dcache(unsigned long config)
-{
-	dcache_size = 1 << (12 + ((config >> 6) & 7));
-
-	printk(KERN_INFO "Primary data cache %dKiB.\n", dcache_size >> 10);
-}
-
-
-/* 
- * This function is executed in the uncached segment KSEG1.
- * It must not touch the stack, because the stack pointer still points
- * into KSEG0. 
- *
- * Three options:
- *	- Write it in assembly and guarantee that we don't use the stack.
- *	- Disable caching for KSEG0 before calling it.
- *	- Pray that GCC doesn't randomly start using the stack.
- *
- * This being Linux, we obviously take the least sane of those options -
- * following DaveM's lead in r4xx0.c
- *
- * It seems we get our kicks from relying on unguaranteed behaviour in GCC
- */
-static __init void setup_scache(void)
-{
-	int register i;
-	
-	set_cp0_config(1<<3 /* CONF_SE */);
-
-	set_taglo(0);
-	set_taghi(0);
-	
-	for (i=0; i<scache_size; i+=sc_lsize) {
-		__asm__ __volatile__ (
-		      ".set noreorder\n\t"
-		      ".set mips3\n\t"
-		      "cache %1, (%0)\n\t"
-		      ".set mips0\n\t"
-		      ".set reorder"
-		      :
-		      : "r" (KSEG0ADDR(i)),
-		        "i" (Index_Store_Tag_SD));
-	}
-
-}
-
-static inline void probe_scache(unsigned long config)
-{
-	void (*func)(void) = KSEG1ADDR(&setup_scache);
-
-	if ((config >> 31) & 1)
-		return;
-
-	printk(KERN_INFO "Secondary cache %dKiB, linesize %d bytes.\n",
-	       (scache_size >> 10), sc_lsize);
-
-	if ((config >> 3) & 1)
-		return;
-
-	printk(KERN_INFO "Enabling secondary cache...");
-	func();
-	printk("Done\n");
-}
- 
-static inline void probe_tcache(unsigned long config)
-{
-	if ((config >> 17) & 1)
-		return;
-
-	/* We can't enable the L3 cache yet. There may be board-specific
-	 * magic necessary to turn it on, and blindly asking the CPU to
-	 * start using it would may give cache errors.
-	 *
-	 * Also, board-specific knowledge may allow us to use the 
-	 * CACHE Flash_Invalidate_T instruction if the tag RAM supports
-	 * it, and may specify the size of the L3 cache so we don't have
-	 * to probe it. 
-	 */
-	printk(KERN_INFO "Tertiary cache present, %s enabled\n",
-	       config&(1<<12) ? "already" : "not (yet)");
-
-	if ((config >> 12) & 1)
-		rm7k_tcache_enabled = 1;
-}
-
-void __init ld_mmu_rm7k(void)
-{
-	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
-	unsigned long addr;
-
-	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
-
-        change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-
-	/* RM7000 erratum #31. The icache is screwed at startup. */
-	set_taglo(0);
-	set_taghi(0);
-	for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) {
-		__asm__ __volatile__ (
-			".set noreorder\n\t"
-			".set mips3\n\t"
-			"cache\t%1, 0(%0)\n\t"
-			"cache\t%1, 0x1000(%0)\n\t"
-			"cache\t%1, 0x2000(%0)\n\t"
-			"cache\t%1, 0x3000(%0)\n\t"
-			"cache\t%2, 0(%0)\n\t"
-			"cache\t%2, 0x1000(%0)\n\t"
-			"cache\t%2, 0x2000(%0)\n\t"
-			"cache\t%2, 0x3000(%0)\n\t"
-			"cache\t%1, 0(%0)\n\t"
-			"cache\t%1, 0x1000(%0)\n\t"
-			"cache\t%1, 0x2000(%0)\n\t"
-			"cache\t%1, 0x3000(%0)\n\t"
-			".set\tmips0\n\t"
-			".set\treorder\n\t"
-			:
-			: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
-	}
-
-#ifndef CONFIG_MIPS_UNCACHED
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif
-
-	probe_icache(config);
-	probe_dcache(config);
-	probe_scache(config);
-	probe_tcache(config);
-
-	printk("TLB has %d entries.\n", ntlb_entries());
-
-	_clear_page = rm7k_clear_page;
-	_copy_page = rm7k_copy_page;
-
-	_flush_cache_all = rm7k_flush_cache_all_d32i32;
-	___flush_cache_all = __flush_cache_all_d32i32;
-	_flush_cache_mm = rm7k_flush_cache_mm_d32i32;
-	_flush_cache_range = rm7k_flush_cache_range_d32i32;
-	_flush_cache_page = rm7k_flush_cache_page_d32i32;
-	_flush_page_to_ram = rm7k_flush_page_to_ram_d32i32;
-	_flush_cache_sigtramp = rm7k_flush_cache_sigtramp;
-	_flush_icache_range = rm7k_flush_icache_range;
-	_flush_icache_page = rm7k_flush_icache_page;
-
-	_dma_cache_wback_inv = rm7k_dma_cache_wback_inv;
-	_dma_cache_wback = rm7k_dma_cache_wback;
-	_dma_cache_inv = rm7k_dma_cache_inv;
-
-	__flush_cache_all_d32i32();
-	write_32bit_cp0_register(CP0_WIRED, 0);
-	temp_tlb_entry = ntlb_entries() - 1;
-	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
-	flush_tlb_all();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/sb1.c linux/arch/mips/mm/sb1.c
--- linux.orig/arch/mips/mm/sb1.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips/mm/sb1.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 2000 Sibyte
- * 
- * Written by Justin Carlson (carlson@sibyte.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.
- */ 
-
-
-/*
- * In this entire file, I'm not sure what the role of the L2 on the sb1250 
- * is.  Since it is coherent to the system, we should never need to flush
- * it...right?...right???  -JDC
- */
-
-#include <asm/mmu_context.h>
-
-/* These are probed at ld_mmu time */
-static unsigned int icache_size;
-static unsigned int dcache_size;
-
-static unsigned int icache_line_size;
-static unsigned int dcache_line_size;
-
-static unsigned int icache_assoc;
-static unsigned int dcache_assoc;
-
-static unsigned int icache_sets;
-static unsigned int dcache_sets;
-static unsigned int tlb_entries;
-
-void pgd_init(unsigned long page)
-{
-	unsigned long *p = (unsigned long *) page;
-	int i;
-
-	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
-		p[i + 0] = (unsigned long) invalid_pte_table;
-		p[i + 1] = (unsigned long) invalid_pte_table;
-		p[i + 2] = (unsigned long) invalid_pte_table;
-		p[i + 3] = (unsigned long) invalid_pte_table;
-		p[i + 4] = (unsigned long) invalid_pte_table;
-		p[i + 5] = (unsigned long) invalid_pte_table;
-		p[i + 6] = (unsigned long) invalid_pte_table;
-		p[i + 7] = (unsigned long) invalid_pte_table;
-	}
-}
-
-void flush_tlb_all(void)
-{
-	unsigned long flags;
-	unsigned long old_ctx;
-	int entry;
-
-	__save_and_cli(flags);
-	/* Save old context and create impossible VPN2 value */
-	old_ctx = (get_entryhi() & 0xff);
-	set_entrylo0(0);
-	set_entrylo1(0);
-	for (entry = 0; entry < tlb_entries; entry++) {
-		set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry);
-		set_index(entry);
-		tlb_write_indexed();
-	}
-	set_entryhi(old_ctx);
-	__restore_flags(flags);	
-}
-
-
-
-/* These are the functions hooked by the memory management function pointers */
-static void sb1_clear_page(void *page)
-{
-	/* JDCXXX - This should be bottlenecked by the write buffer, but these
-	   things tend to be mildly unpredictable...should check this on the
-	   performance model */
-
-	/* We prefetch 4 lines ahead.  We're also "cheating" slightly here...
-	   since we know we're on an SB1, we force the assembler to take 
-	   64-bit operands to speed things up */
-	__asm__ __volatile__(
-		".set push                  \n"
-		".set noreorder             \n"
-		".set noat                  \n"
-		".set mips4                 \n"
-		"     addiu     $1, %0, %2  \n"  /* Calculate the end of the page to clear */
-		"     pref       5,  0(%0)  \n"  /* Prefetch the first 4 lines */
-		"     pref       5, 32(%0)  \n"  
-		"     pref       5, 64(%0)  \n"  
-		"     pref       5, 96(%0)  \n"  
-		"1:   sd        $0,  0(%0)  \n"  /* Throw out a cacheline of 0's */
-		"     sd        $0,  8(%0)  \n"
-		"     sd        $0, 16(%0)  \n"
-		"     sd        $0, 24(%0)  \n"
-		"     pref       5,128(%0)  \n"  /* Prefetch 4 lines ahead     */
-		"     bne       $1, %0, 1b  \n"
-		"     addiu     %0, %0, 32  \n"  /* Next cacheline (This instruction better be short piped!) */
-		".set pop                   \n"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE-32)
-		:"$1","memory");
-
-}
-
-static void sb1_copy_page(void *to, void *from)
-{
-
-	/* This should be optimized in assembly...can't use ld/sd, though,
-	 * because the top 32 bits could be nuked if we took an interrupt
-	 * during the routine.  And this is not a good place to be cli()'ing
-	 */
-
-	/* The pref's used here are using "streaming" hints, which cause the
-	 * copied data to be kicked out of the cache sooner.  A page copy often
-	 * ends up copying a lot more data than is commonly used, so this seems
-	 * to make sense in terms of reducing cache pollution, but I've no real
-	 * performance data to back this up
-	 */ 
-
-	__asm__ __volatile__(
-		".set push                  \n"
-		".set noreorder             \n"
-		".set noat                  \n"
-		".set mips4                 \n"
-		"     addiu     $1, %0, %4  \n"  /* Calculate the end of the page to copy */
-		"     pref       4,  0(%0)  \n"  /* Prefetch the first 3 lines to be read and copied */
-		"     pref       5,  0(%1)  \n"  
-		"     pref       4, 32(%0)  \n"  
-		"     pref       5, 32(%1)  \n"  
-		"     pref       4, 64(%0)  \n"  
-		"     pref       5, 64(%1)  \n"  
-		"1:   lw        $2,  0(%0)  \n"  /* Block copy a cacheline */
-		"     lw        $3,  4(%0)  \n"
-		"     lw        $4,  8(%0)  \n"
-		"     lw        $5, 12(%0)  \n"
-		"     lw        $6, 16(%0)  \n"
-		"     lw        $7, 20(%0)  \n"
-		"     lw        $8, 24(%0)  \n"
-		"     lw        $9, 28(%0)  \n"
-		"     pref       4, 96(%0)  \n"  /* Prefetch ahead         */
-		"     pref       5, 96(%1)  \n"
-		"     sw        $2,  0(%1)  \n"  
-		"     sw        $3,  4(%1)  \n"
-		"     sw        $4,  8(%1)  \n"
-		"     sw        $5, 12(%1)  \n"
-		"     sw        $6, 16(%1)  \n"
-		"     sw        $7, 20(%1)  \n"
-		"     sw        $8, 24(%1)  \n"
-		"     sw        $9, 28(%1)  \n"		
-		"     addiu     %1, %1, 32  \n"  /* Next cacheline */
-		"     nop                   \n"  /* Force next add to short pipe */
-		"     nop                   \n"  /* Force next add to short pipe */
-		"     bne       $1, %0, 1b  \n"
-		"     addiu     %0, %0, 32  \n"  /* Next cacheline */
-		".set pop                   \n" 
-		:"=r" (to),
-		"=r" (from)
-		:
-		"0" (from),
-		"1" (to),
-		"I" (PAGE_SIZE-32)
-		:"$1","$2","$3","$4","$5","$6","$7","$8","$9","memory");
-/*
-	unsigned long *src = from;
-	unsigned long *dest = to;
-	unsigned long *target = (unsigned long *) (((unsigned long)src) + PAGE_SIZE);
-	while (src != target) {
-		*dest++ = *src++;
-	}
-*/
-}
-
-/*
- * The dcache is fully coherent to the system, with one
- * big caveat:  the instruction stream.  In other words,
- * if we miss in the icache, and have dirty data in the
- * L1 dcache, then we'll go out to memory (or the L2) and
- * get the not-as-recent data.
- * 
- * So the only time we have to flush the dcache is when
- * we're flushing the icache.  Since the L2 is fully
- * coherent to everything, including I/O, we never have
- * to flush it
- */
-
-static void sb1_flush_cache_all(void)
-{
-
-	/*
-	 * Haven't worried too much about speed here; given that we're flushing
-	 * the icache, the time to invalidate is dwarfed by the time it's going
-	 * to take to refill it.  Register usage:
-	 * 
-	 * $1 - moving cache index
-	 * $2 - set count
-	 */
-	if (icache_sets) { 
-		__asm__ __volatile__ (
-			".set push                  \n"
-			".set noreorder             \n"
-			".set noat                  \n"
-			".set mips4                 \n"
-			"     move   $1, %2         \n" /* Start at index 0 */
-                        "1:   cache  0, 0($1)       \n" /* Invalidate this index */
-			"     addiu  %1, %1, -1     \n" /* Decrement loop count */
-			"     bnez   %1, 1b         \n" /* loop test */
-			"     addu   $1, $1, %0     \n" /* Next address JDCXXX - Should be short piped */
-			".set pop                   \n"
-			::"r" (icache_line_size),
-			"r" (icache_sets * icache_assoc),
-			"r" (KSEG0)
-			:"$1");
-	}
-	if (dcache_sets) {
-		__asm__ __volatile__ (
-			".set push                  \n"
-			".set noreorder             \n"
-			".set noat                  \n"
-			".set mips4                 \n"
-			"     move   $1, %2         \n" /* Start at index 0 */
-                        "1:   cache  0x1, 0($1)     \n" /* WB/Invalidate this index */
-			"     addiu  %1, %1, -1     \n" /* Decrement loop count */
-			"     bnez   %1, 1b         \n" /* loop test */
-			"     addu   $1, $1, %0     \n" /* Next address JDCXXX - Should be short piped */
-			".set pop                   \n"
-			::"r" (dcache_line_size),
-			"r" (dcache_sets * dcache_assoc),
-			"r" (KSEG0)
-			:"$1");
-	}
-}
-
-/*
- * When flushing a range in the icache, we have to first writeback
- * the dcache for the same range, so new ifetches will see any
- * data that was dirty in the dcache
- */
-
-static void sb1_flush_icache_range(unsigned long start, unsigned long end)
-{
-	
-	/* JDCXXX - Implement me! */
-	sb1_flush_cache_all();
-}
-
-static void sb1_flush_cache_mm(struct mm_struct *mm)
-{
-	/* Don't need to do this, as the dcache is physically tagged */
-}
-
-static void sb1_flush_cache_range(struct mm_struct *mm, 
-				  unsigned long start,
-				  unsigned long end)
-{
-	/* Don't need to do this, as the dcache is physically tagged */
-}
-
-
-static void sb1_flush_cache_sigtramp(unsigned long page)
-{
-	/* JDCXXX - Implement me! */
-	sb1_flush_cache_all();
-}
-
-
-/*
- * This only needs to make sure stores done up to this
- * point are visible to other agents outside the CPU.  Given 
- * the coherent nature of the ZBus, all that's required here is 
- * a sync to make sure the data gets out to the caches and is
- * visible to an arbitrary A Phase from an external agent 
- *   
- * Actually, I'm not even sure that's necessary; the semantics
- * of this function aren't clear.  If it's supposed to serve as
- * a memory barrier, this is needed.  If it's only meant to 
- * prevent data from being invisible to non-cpu memory accessors
- * for some indefinite period of time (e.g. in a non-coherent 
- * dcache) then this function would be a complete nop.
- */
-static void sb1_flush_page_to_ram(struct page *page)
-{
-	__asm__ __volatile__(
-		"     sync  \n"  /* Short pipe */
-		:::"memory");	
-}
-
-
-/* Cribbed from the r2300 code */
-static void sb1_flush_cache_page(struct vm_area_struct *vma,
-				  unsigned long page)
-{
-	sb1_flush_cache_all();
-#if 0
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long physpage;
-
-	/* No icache flush needed without context; */
-	if (mm->context == 0) 
-		return;  
-
-	/* No icache flush needed if the page isn't executable */
-	if (!(vma->vm_flags & VM_EXEC))
-		return;
-
-	physpage = (unsigned long) page_address(page);
-	if (physpage)
-		sb1_flush_icache_range(physpage, physpage + PAGE_SIZE);
-#endif
-}
-
-
-/*
- *  Cache set values (from the mips64 spec)
- * 0 - 64
- * 1 - 128
- * 2 - 256
- * 3 - 512
- * 4 - 1024
- * 5 - 2048
- * 6 - 4096
- * 7 - Reserved
- */
-static unsigned int decode_cache_sets(unsigned int config_field)
-{
-	if (config_field == 7) {
-		/* JDCXXX - Find a graceful way to abort. */
-		return 0;
-	} 
-
-	return (1<<(config_field + 6));
-}
-
-/*
- *  Cache line size values (from the mips64 spec)
- * 0 - No cache present.
- * 1 - 4 bytes
- * 2 - 8 bytes
- * 3 - 16 bytes
- * 4 - 32 bytes
- * 5 - 64 bytes
- * 6 - 128 bytes
- * 7 - Reserved
- */
-static unsigned int decode_cache_line_size(unsigned int config_field)
-{
-	if (config_field == 0) {
-		return 0;
-	} else if (config_field == 7) {
-		/* JDCXXX - Find a graceful way to abort. */
-		return 0;
-	} 
-	return (1<<(config_field + 1));
-}
-
-/*
- * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs)
- *
- * 24:22 Icache sets per way
- * 21:19 Icache line size
- * 18:16 Icache Associativity
- * 15:13 Dcache sets per way
- * 12:10 Dcache line size
- * 9:7   Dcache Associativity
- */
-
-
-static void probe_cache_sizes(void)
-{
-	u32 config1;
-
-	__asm__ __volatile__(
-		".set push                  \n"
-		".set mips64                \n"
-		"     mfc0    %0, $16, 1    \n"  /* Get config1 register */
-		".set pop                   \n"
-		:"=r" (config1));
-	icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7);
-	dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7);
-	icache_sets = decode_cache_sets((config1 >> 22) & 0x7);
-	dcache_sets = decode_cache_sets((config1 >> 13) & 0x7);
-        icache_assoc = ((config1 >> 16) & 0x7) + 1;
-	dcache_assoc = ((config1 >> 7) & 0x7) + 1;
-	icache_size = icache_line_size * icache_sets * icache_assoc;
-	dcache_size = dcache_line_size * dcache_sets * dcache_assoc;
-	tlb_entries = ((config1 >> 25) & 0x3f) + 1;
-}
-
-
-/* This is called from loadmmu.c.  We have to set up all the
-   memory management function pointers, as well as initialize
-   the caches and tlbs */
-void ld_mmu_sb1(void)
-{
-	probe_cache_sizes();
-
-	_clear_page = sb1_clear_page;
-	_copy_page = sb1_copy_page;
-	
-	_flush_cache_all = sb1_flush_cache_all;
-	_flush_cache_mm = sb1_flush_cache_mm;
-	_flush_cache_range = sb1_flush_cache_range;
-	_flush_cache_page = sb1_flush_cache_page;
-	_flush_cache_sigtramp = sb1_flush_cache_sigtramp;
-
-	_flush_page_to_ram = sb1_flush_page_to_ram;
-	_flush_icache_page = sb1_flush_cache_page;
-	_flush_icache_range = sb1_flush_icache_range;
-
-	
-	/*
-	 * JDCXXX I'm not sure whether these are necessary: is this the right 
-	 * place to initialize the tlb?  If it is, why is it done 
-	 * at this level instead of as common code in loadmmu()?
-	 */
-	flush_cache_all();
-	flush_tlb_all();
-	
-	/* Turn on caching in kseg0 */
-	set_cp0_config(CONF_CM_CMASK, 0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/tlb-r3k.c linux/arch/mips/mm/tlb-r3k.c
--- linux.orig/arch/mips/mm/tlb-r3k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/tlb-r3k.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,257 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/wbflush.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+extern char except_vec0_r2300;
+
+#undef DEBUG_TLB
+
+int r3k_have_wired_reg = 0;	/* should be in mips_cpu? */
+
+/* TLB operations. */
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	save_and_cli(flags);
+	old_ctx = (get_entryhi() & 0xfc0);
+	write_32bit_cp0_register(CP0_ENTRYLO0, 0);
+#ifdef CONFIG_CPU_TX39XX
+	entry = r3k_have_wired_reg ? get_wired() : 8;
+#else
+	entry = 8;
+#endif
+	for (; entry < mips_cpu.tlbsize; entry++) {
+		write_32bit_cp0_register(CP0_INDEX, entry << 8);
+		write_32bit_cp0_register(CP0_ENTRYHI, ((entry | 0x80000) << 12));
+		__asm__ __volatile__("tlbwi");
+	}
+	set_entryhi(old_ctx);
+	restore_flags(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%lu>]", (unsigned long) mm->context);
+#endif
+		save_and_cli(flags);
+		get_new_mmu_context(mm, smp_processor_id());
+		if (mm == current->active_mm)
+			set_entryhi(mm->context & 0xfc0);
+		restore_flags(flags);
+	}
+}
+
+void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+                     unsigned long end)
+{
+	if (mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
+			(mm->context & 0xfc0), start, end);
+#endif
+		save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		if (size <= mips_cpu.tlbsize) {
+			int oldpid = (get_entryhi() & 0xfc0);
+			int newpid = (mm->context & 0xfc0);
+
+			start &= PAGE_MASK;
+			end += (PAGE_SIZE - 1);
+			end &= PAGE_MASK;
+			while (start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += PAGE_SIZE;
+				tlb_probe();
+				idx = get_index();
+				set_entrylo0(0);
+				set_entryhi(KSEG0);
+				if (idx < 0)
+					continue;
+				tlb_write_indexed();
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, smp_processor_id());
+			if (mm == current->active_mm)
+				set_entryhi(mm->context & 0xfc0);
+		}
+		restore_flags(flags);
+	}
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if (!vma || vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%lu,0x%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (vma->vm_mm->context & 0xfc0);
+		page &= PAGE_MASK;
+		save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xfc0);
+		set_entryhi(page | newpid);
+		tlb_probe();
+		idx = get_index();
+		set_entrylo0(0);
+		set_entryhi(KSEG0);
+		if (idx < 0)
+			goto finish;
+		tlb_write_indexed();
+
+finish:
+		set_entryhi(oldpid);
+		restore_flags(flags);
+	}
+}
+
+void update_mmu_cache(struct vm_area_struct * vma, unsigned long address,
+                      pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = get_entryhi() & 0xfc0;
+
+#ifdef DEBUG_TLB
+	if ((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n",
+		       (vma->vm_mm->context & 0xfc0), pid);
+	}
+#endif
+
+	save_and_cli(flags);
+	address &= PAGE_MASK;
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	tlb_probe();
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	set_entrylo0(pte_val(*ptep));
+	set_entryhi(address | (pid));
+	if (idx < 0) {
+		tlb_write_random();
+#if 0
+		printk("[MISS]");
+#endif
+	} else {
+		tlb_write_indexed();
+#if 0
+		printk("[HIT]");
+#endif
+	}
+	set_entryhi(pid);
+	restore_flags(flags);
+}
+
+void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+                     unsigned long entryhi, unsigned long pagemask)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	static unsigned long wired = 0;
+	
+#ifdef CONFIG_CPU_TX39XX
+	if (r3k_have_wired_reg) {
+		unsigned long old_pagemask;
+		unsigned long w;
+	
+#ifdef DEBUG_TLB
+		printk("[tlbwired]");
+		printk("ently lo0 %8x, hi %8x\n, pagemask %8x\n",
+		       entrylo0, entryhi, pagemask);
+#endif
+		save_and_cli(flags);
+		/* Save old context and create impossible VPN2 value */
+		old_ctx = (get_entryhi() & 0xff);
+		old_pagemask = get_pagemask();
+		w = get_wired();
+		set_wired (w + 1);
+		if (get_wired() != w + 1) {
+			printk("[tlbwired] No WIRED reg?\n");
+			return;
+		}
+		set_index (w << 8);
+		set_pagemask (pagemask);
+		set_entryhi(entryhi);
+		set_entrylo0(entrylo0);
+		tlb_write_indexed();
+    
+		set_entryhi(old_ctx);
+		set_pagemask (old_pagemask);
+		local_flush_tlb_all();
+		restore_flags(flags);
+		return;
+	}
+#endif
+
+	if (wired < 8) {
+		__save_and_cli(flags);
+		old_ctx = get_entryhi() & 0xfc0;
+		set_entrylo0(entrylo0);
+		set_entryhi(entryhi);
+		set_index(wired);
+		wired++;
+		tlb_write_indexed();
+		set_entryhi(old_ctx);
+	        local_flush_tlb_all();    
+		__restore_flags(flags);
+	}
+}
+
+void __init r3k_tlb_init(void)
+{
+	local_flush_tlb_all();
+	memcpy((void *)KSEG0, &except_vec0_r2300, 0x80);
+	flush_icache_range(KSEG0, KSEG0 + 0x80);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/tlb-r4k.c linux/arch/mips/mm/tlb-r4k.c
--- linux.orig/arch/mips/mm/tlb-r4k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/tlb-r4k.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,383 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
+ *
+ * To do:
+ *
+ *  - this code is a overbloated pig
+ *  - many of the bug workarounds are not efficient at all, but at
+ *    least they are functional ...
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+#undef DEBUG_TLB
+#undef DEBUG_TLBUPDATE
+
+extern char except_vec0_nevada, except_vec0_r4000, except_vec0_r4600;
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	BARRIER;
+
+	entry = get_wired();
+
+	/* Blast 'em all away. */
+	while (entry < mips_cpu.tlbsize) {
+		/*
+		 * Make sure all entries differ.  If they're not different
+		 * MIPS32 will take revenge ...
+		 */
+		set_entryhi(KSEG0 + entry*0x2000);
+		set_index(entry);
+		BARRIER;
+		tlb_write_indexed();
+		BARRIER;
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%d>]", mm->context);
+#endif
+		__save_and_cli(flags);
+		get_new_mmu_context(mm, smp_processor_id());
+		if (mm == current->active_mm)
+			set_entryhi(mm->context & 0xff);
+		__restore_flags(flags);
+	}
+}
+
+void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+				unsigned long end)
+{
+	if (mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+		       start, end);
+#endif
+		__save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if (size <= mips_cpu.tlbsize/2) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (mm->context & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while (start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				BARRIER;
+				tlb_probe();
+				BARRIER;
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				set_entryhi(KSEG0);
+				if (idx < 0)
+					continue;
+				BARRIER;
+				/* Make sure all entries differ. */
+				set_entryhi(KSEG0+idx*0x2000);
+				tlb_write_indexed();
+				BARRIER;
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, smp_processor_id());
+			if (mm == current->active_mm)
+				set_entryhi(mm->context & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if (!vma || vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (vma->vm_mm->context & 0xff);
+		page &= (PAGE_MASK << 1);
+		__save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		BARRIER;
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		if(idx < 0)
+			goto finish;
+		/* Make sure all entries differ. */
+		set_entryhi(KSEG0+idx*0x2000);
+		BARRIER;
+		tlb_write_indexed();
+
+	finish:
+		BARRIER;
+		set_entryhi(oldpid);
+		__restore_flags(flags);
+	}
+}
+
+/* We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+void update_mmu_cache(struct vm_area_struct * vma, unsigned long address,
+		      pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       (int) (vma->vm_mm->context & 0xff), pid);
+	}
+#endif
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	BARRIER;
+	if (idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	BARRIER;
+	set_entryhi(pid);
+	BARRIER;
+	__restore_flags(flags);
+}
+
+#if 0
+static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
+				       unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx;
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (get_entryhi() & 0xff));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	tlb_probe();
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	BARRIER;
+	if (idx < 0)
+		tlb_write_random();
+	else
+		tlb_write_indexed();
+	BARRIER;
+	__restore_flags(flags);
+}
+#endif
+
+void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+		     unsigned long entryhi, unsigned long pagemask)
+{
+	unsigned long flags;
+	unsigned long wired;
+	unsigned long old_pagemask;
+	unsigned long old_ctx;
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = get_entryhi() & 0xff;
+	old_pagemask = get_pagemask();
+	wired = get_wired();
+	set_wired(wired + 1);
+	set_index(wired);
+	BARRIER;    
+	set_pagemask(pagemask);
+	set_entryhi(entryhi);
+	set_entrylo0(entrylo0);
+	set_entrylo1(entrylo1);
+	BARRIER;    
+	tlb_write_indexed();
+	BARRIER;    
+    
+	set_entryhi(old_ctx);
+	BARRIER;    
+	set_pagemask(old_pagemask);
+	local_flush_tlb_all();    
+	__restore_flags(flags);
+}
+
+/*
+ * Used for loading TLB entries before trap_init() has started, when we
+ * don't actually want to add a wired entry which remains throughout the
+ * lifetime of the system
+ */
+
+static int temp_tlb_entry __initdata;
+
+__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
+			       unsigned long entryhi, unsigned long pagemask)
+{
+	int ret = 0;
+	unsigned long flags;
+	unsigned long wired;
+	unsigned long old_pagemask;
+	unsigned long old_ctx;
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = get_entryhi() & 0xff;
+	old_pagemask = get_pagemask();
+	wired = get_wired();
+	if (--temp_tlb_entry < wired) {
+		printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
+		ret = -ENOSPC;
+		goto out;
+	}
+
+	set_index(temp_tlb_entry);
+	BARRIER;    
+	set_pagemask(pagemask);
+	set_entryhi(entryhi);
+	set_entrylo0(entrylo0);
+	set_entrylo1(entrylo1);
+	BARRIER;    
+	tlb_write_indexed();
+	BARRIER;    
+    
+	set_entryhi(old_ctx);
+	BARRIER;    
+	set_pagemask(old_pagemask);
+out:
+	__restore_flags(flags);
+	return ret;
+}
+
+static void __init probe_tlb(unsigned long config)
+{
+	unsigned int prid, config1;
+
+	prid = read_32bit_cp0_register(CP0_PRID) & 0xff00;
+	if (prid == PRID_IMP_RM7000 || !(config & (1 << 31)))
+		/* 
+		 * Not a MIPS32 complianant CPU.  Config 1 register not
+		 * supported, we assume R4k style.  Cpu probing already figured
+		 * out the number of tlb entries.
+		 */  
+		return;
+
+	config1 = read_mips32_cp0_config1();
+	if (!((config >> 7) & 3))
+		panic("No MMU present");
+	else
+		mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
+}
+
+void __init r4k_tlb_init(void)
+{
+	u32 config = read_32bit_cp0_register(CP0_CONFIG);
+
+	/*
+	 * You should never change this register:
+	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
+	 *     the value in the c0_pagemask register.
+	 *   - The entire mm handling assumes the c0_pagemask register to
+	 *     be set for 4kb pages.
+	 */
+	probe_tlb(config);
+	set_pagemask(PM_4K);
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	temp_tlb_entry = mips_cpu.tlbsize - 1;
+	local_flush_tlb_all();
+
+	if ((mips_cpu.options & MIPS_CPU_4KEX)
+	    && (mips_cpu.options & MIPS_CPU_4KTLB)) {
+		if (mips_cpu.cputype == CPU_NEVADA)
+			memcpy((void *)KSEG0, &except_vec0_nevada, 0x80);
+		else if (mips_cpu.cputype == CPU_R4600)
+			memcpy((void *)KSEG0, &except_vec0_r4600, 0x80);
+		else
+			memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
+		flush_icache_range(KSEG0, KSEG0 + 0x80);
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/tlb-sb1.c linux/arch/mips/mm/tlb-sb1.c
--- linux.orig/arch/mips/mm/tlb-sb1.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/tlb-sb1.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */ 
+#include <linux/config.h>
+#include <asm/mmu_context.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+extern char except_vec0_r4000[];
+
+/* Dump the current entry* and pagemask registers */
+static inline void dump_cur_tlb_regs(void)
+{
+	unsigned int entryhihi, entryhilo, entrylo0hi, entrylo0lo, entrylo1hi;
+	unsigned int entrylo1lo, pagemask;
+
+	__asm__ __volatile__ (
+		".set push             \n"
+		".set noreorder        \n"
+		".set mips64           \n"
+		".set noat             \n"
+		"     tlbr             \n"
+		"     dmfc0  $1, $10   \n"
+		"     dsrl32 %0, $1, 0 \n"
+		"     sra    %1, $1, 0 \n"
+		"     dmfc0  $1, $2    \n"
+		"     dsrl32 %2, $1, 0 \n"
+		"     sra    %3, $1, 0 \n"
+		"     dmfc0  $1, $3    \n"
+		"     dsrl32 %4, $1, 0 \n"
+		"     sra    %5, $1, 0 \n"
+		"     mfc0   %6, $5    \n"
+		".set pop              \n"
+		: "=r" (entryhihi),
+		"=r" (entryhilo),
+		"=r" (entrylo0hi),
+		"=r" (entrylo0lo),
+		"=r" (entrylo1hi),
+		"=r" (entrylo1lo),
+		"=r" (pagemask));
+	printk("%08X%08X %08X%08X %08X%08X %08X",
+	       entryhihi, entryhilo,
+	       entrylo0hi, entrylo0lo,
+	       entrylo1hi, entrylo1lo,
+	       pagemask);
+}
+
+void sb1_dump_tlb(void)
+{
+	int entry;
+	printk("Current TLB registers state:\n"
+	       "      EntryHi       EntryLo0          EntryLo1     PageMask  Index\n"
+	       "--------------------------------------------------------------------\n");
+	dump_cur_tlb_regs();
+	printk(" %08X\n", read_32bit_cp0_register(CP0_INDEX));
+	printk("\n\nFull TLB Dump:\n"
+	       "Idx      EntryHi       EntryLo0          EntryLo1     PageMask\n"
+	       "--------------------------------------------------------------\n");
+	for (entry = 0; entry < mips_cpu.tlbsize; entry++) {
+		set_index(entry);
+		printk("\n%02i ", entry);
+		__asm__ __volatile__ (
+			".set push             \n"
+			".set mips64           \n"
+			"     tlbr             \n"
+			".set pop              \n");
+		dump_cur_tlb_regs();
+	}
+	printk("\n");
+}
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	for (entry = 0; entry < mips_cpu.tlbsize; entry++) {
+		set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry);
+		set_index(entry);
+		tlb_write_indexed();
+	}
+	set_entryhi(old_ctx);
+	__restore_flags(flags);	
+}
+
+
+/*
+ * Use a bogus region of memory (starting at 0) to sanitize the TLB's.  
+ * Use increments of the maximum page size (16MB), and check for duplicate
+ * entries before doing a given write.  Then, when we're safe from collisions
+ * with the firmware, go back and give all the entries invalid addresses with
+ * the normal flush routine.
+ */
+void sb1_sanitize_tlb(void)
+{
+	int entry;
+	long addr = 0;
+
+	long inc = 1<<24;  /* 16MB */
+	/* Save old context and create impossible VPN2 value */
+	set_entrylo0(0);
+	set_entrylo1(0);
+	for (entry = 0; entry < mips_cpu.tlbsize; entry++) {
+		do {
+			addr += inc;
+			set_entryhi(addr);
+			tlb_probe();
+		} while ((int)(get_index()) >= 0);
+		set_index(entry);
+		tlb_write_indexed();
+	}
+	/* Now that we know we're safe from collisions, we can safely flush
+	   the TLB with the "normal" routine. */
+	local_flush_tlb_all();
+}
+
+
+void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+                      unsigned long end)
+{
+	unsigned long flags;
+	int cpu;
+
+	__save_and_cli(flags);
+	cpu = smp_processor_id();
+	if(CPU_CONTEXT(cpu, mm) != 0) {
+		int size;
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if(size <= (mips_cpu.tlbsize/2)) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (CPU_CONTEXT(cpu, mm) & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				tlb_probe();
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				set_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1)));
+				if(idx < 0)
+					continue;
+				tlb_write_indexed();
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, cpu);
+			if (mm == current->active_mm)
+				set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff);
+		}
+	}
+	__restore_flags(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	unsigned long flags;
+
+#ifdef CONFIG_SMP
+	/*
+	 * This variable is eliminated from CPU_CONTEXT() if SMP isn't defined,
+	 * so conditional it to get rid of silly "unused variable" compiler
+	 * complaints
+	 */
+	int cpu = smp_processor_id();
+#endif
+
+	__save_and_cli(flags);
+	if (CPU_CONTEXT(cpu, vma->vm_mm) != 0) {
+		int oldpid, newpid, idx;
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", CPU_CONTEXT(cpu, vma->vm_mm), page);
+#endif
+		newpid = (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff);
+		page &= (PAGE_MASK << 1);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi	(page | newpid);
+		tlb_probe();
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		if(idx < 0)
+			goto finish;
+		/* Make sure all entries differ. */  
+		set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1)));
+		tlb_write_indexed();
+	finish:
+		set_entryhi(oldpid);
+	}
+	__restore_flags(flags);
+}
+
+
+/* All entries common to a mm share an asid.  To effectively flush
+   these entries, we just bump the asid. */
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	unsigned long flags;
+	int cpu;
+	__save_and_cli(flags);
+	cpu = smp_processor_id();
+	if (CPU_CONTEXT(cpu, mm) != 0) {
+		get_new_mmu_context(mm, smp_processor_id());
+		if (mm == current->active_mm) {
+			set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff);
+		}
+	}
+	__restore_flags(flags);
+}
+
+/* Stolen from mips32 routines */
+
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
+                      pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	__save_and_cli(flags);
+
+
+	pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+	if((pid != (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff)) || (CPU_CONTEXT(cpu, vma->vm_mm) == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       (int) (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff), pid);
+	}
+#endif
+
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	tlb_probe();
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	if(idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	set_entryhi(pid);
+	__restore_flags(flags);
+}
+
+/*
+ * This is called from loadmmu.c.  We have to set up all the
+ * memory management function pointers, as well as initialize
+ * the caches and tlbs
+ */
+void sb1_tlb_init(void)
+{
+	u32 config1;
+
+	config1 = read_mips32_cp0_config1();
+	mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
+
+	/*
+	 * We don't know what state the firmware left the TLB's in, so this is
+	 * the ultra-conservative way to flush the TLB's and avoid machine
+	 * check exceptions due to duplicate TLB entries 
+	 */
+	sb1_sanitize_tlb();
+
+	memcpy((void *)KSEG0, except_vec0_r4000, 0x80);
+	flush_icache_range(KSEG0, KSEG0 + 0x80);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/tlbex-r3k.S linux/arch/mips/mm/tlbex-r3k.S
--- linux.orig/arch/mips/mm/tlbex-r3k.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/tlbex-r3k.S	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,226 @@
+/*
+ * TLB exception handling code for R2000/R3000.
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+ *
+ * Multi-CPU abstraction reworking:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Further modifications to make this work:
+ * Copyright (c) 1998 Harald Koerfgen
+ * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov
+ * Copyright (c) 2001 Ralf Baechle
+ * Copyright (c) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/init.h>
+#include <asm/asm.h>
+#include <asm/current.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+
+	.text
+	.set	mips1
+	.set	noreorder
+
+	__INIT
+
+	/* TLB refill, R[23]00 version */
+	LEAF(except_vec0_r2300)
+	.set	noat
+	.set	mips1
+	mfc0	k0, CP0_BADVADDR
+	lw	k1, pgd_current			# get pgd pointer
+	srl	k0, k0, 22
+	sll	k0, k0, 2
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+	and	k0, k0, 0xffc
+	addu	k1, k1, k0
+	lw	k0, (k1)
+	nop
+	mtc0	k0, CP0_ENTRYLO0
+	mfc0	k1, CP0_EPC
+	tlbwr
+	jr	k1
+	rfe
+	END(except_vec0_r2300)
+
+	__FINIT
+
+	/* ABUSE of CPP macros 101. */
+
+	/* After this macro runs, the pte faulted on is
+	 * in register PTE, a ptr into the table in which
+	 * the pte belongs is in PTR.
+	 */
+#define LOAD_PTE(pte, ptr) \
+	mfc0	pte, CP0_BADVADDR; \
+	lw	ptr, pgd_current; \
+	srl	pte, pte, 22; \
+	sll	pte, pte, 2; \
+	addu	ptr, ptr, pte; \
+	mfc0	pte, CP0_CONTEXT; \
+	lw	ptr, (ptr); \
+	andi	pte, pte, 0xffc; \
+	addu	ptr, ptr, pte; \
+	lw	pte, (ptr); \
+	nop;
+
+	/* This places the even/odd pte pair in the page
+	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+	 * TMP as a scratch register.
+	 */
+#define PTE_RELOAD(ptr) \
+	lw	ptr, (ptr)	; \
+	nop			; \
+	mtc0	ptr, CP0_ENTRYLO0; \
+	nop;
+
+#define DO_FAULT(write) \
+	.set	noat; \
+	.set	macro; \
+	SAVE_ALL; \
+	mfc0	a2, CP0_BADVADDR; \
+	KMODE; \
+	.set	at; \
+	move	a0, sp; \
+	jal	do_page_fault; \
+	 li	a1, write; \
+	j	ret_from_exception; \
+	 nop; \
+	.set	noat; \
+	.set	nomacro;
+
+	/* Check is PTE is present, if not then jump to LABEL.
+	 * PTR points to the page table where this PTE is located,
+	 * when the macro is done executing PTE will be restored
+	 * with it's original value.
+	 */
+#define PTE_PRESENT(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	bnez	pte, label; \
+	.set	push;       \
+	.set	reorder;    \
+	 lw	pte, (ptr); \
+	.set	pop; 
+
+	/* Make PTE valid, store result in PTR. */
+#define PTE_MAKEVALID(pte, ptr) \
+	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+	sw	pte, (ptr);
+
+	/* Check if PTE can be written to, if not branch to LABEL.
+	 * Regardless restore PTE with value from PTR when done.
+	 */
+#define PTE_WRITABLE(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	bnez	pte, label; \
+	.set    push;       \
+	.set    reorder;    \
+	lw      pte, (ptr); \
+	.set    pop;
+ 
+
+	/* Make PTE writable, update software status bits as well,
+	 * then store at PTR.
+	 */
+#define PTE_MAKEWRITE(pte, ptr) \
+	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+			   _PAGE_VALID | _PAGE_DIRTY); \
+	sw	pte, (ptr);
+
+/*
+ * The index register may have the probe fail bit set,
+ * because we would trap on access kseg2, i.e. without refill.
+ */
+#define TLB_WRITE(reg) \
+	mfc0	reg, CP0_INDEX; \
+	nop; \
+	bltz    reg, 1f; \
+	 nop; \
+	tlbwi; \
+	j	2f; \
+	 nop; \
+1:	tlbwr; \
+2:
+
+#define RET(reg) \
+	mfc0	reg, CP0_EPC; \
+	nop; \
+	jr	reg; \
+	 rfe
+			
+	.set	noreorder
+
+	.align	5
+NESTED(handle_tlbl, PT_SIZE, sp)
+	.set	noat
+
+#ifdef TLB_OPTIMIZE
+	/* Test present bit in entry. */
+	LOAD_PTE(k0, k1)
+        tlbp
+        PTE_PRESENT(k0, k1, nopage_tlbl)
+        PTE_MAKEVALID(k0, k1)
+        PTE_RELOAD(k1)
+	TLB_WRITE(k0)
+	RET(k0)
+nopage_tlbl:
+#endif
+
+	DO_FAULT(0)
+END(handle_tlbl)
+
+NESTED(handle_tlbs, PT_SIZE, sp)
+	.set	noat
+
+#ifdef TLB_OPTIMIZE
+	LOAD_PTE(k0, k1)
+	tlbp                            # find faulting entry
+	PTE_WRITABLE(k0, k1, nopage_tlbs)
+	PTE_MAKEWRITE(k0, k1)
+	PTE_RELOAD(k1)
+	TLB_WRITE(k0)
+	RET(k0)
+nopage_tlbs:
+#endif
+
+	DO_FAULT(1)
+END(handle_tlbs)
+
+	.align	5
+NESTED(handle_mod, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	LOAD_PTE(k0, k1)
+	tlbp					# find faulting entry
+	andi	k0, k0, _PAGE_WRITE
+	beqz	k0, nowrite_mod
+	.set	push
+	.set    reorder
+	lw	k0, (k1)
+	.set    pop
+
+	/* Present and writable bits set, set accessed and dirty bits. */
+	PTE_MAKEWRITE(k0, k1)
+
+	/* Now reload the entry into the tlb. */
+	PTE_RELOAD(k1)
+	tlbwi
+	RET(k0)
+#endif
+
+nowrite_mod:
+	DO_FAULT(1)
+END(handle_mod)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/tlbex-r4k.S linux/arch/mips/mm/tlbex-r4k.S
--- linux.orig/arch/mips/mm/tlbex-r4k.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/mm/tlbex-r4k.S	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,710 @@
+/*
+ * TLB exception handling code for r4k.
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+ *
+ * Multi-cpu abstraction and reworking:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/current.h>
+#include <asm/offset.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define PTE_L		ld
+#define PTE_S		sd
+#define PTE_SRL		dsrl
+#define P_MTC0		dmtc0
+#define PTE_SIZE	8
+#define PTEP_INDX_MSK	0xff0
+#define PTE_INDX_MSK	0xff8
+#define PTE_INDX_SHIFT	9
+#else
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_SIZE	4
+#define PTEP_INDX_MSK	0xff8
+#define PTE_INDX_MSK	0xffc
+#define PTE_INDX_SHIFT	10
+#endif
+
+	__INIT
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define GET_PTE_OFF(reg)
+#elif CONFIG_CPU_VR41XX
+#define GET_PTE_OFF(reg)	srl	reg, reg, 3
+#else
+#define GET_PTE_OFF(reg)	srl	reg, reg, 1
+#endif
+
+/*	
+ * These handlers much be written in a relocatable manner
+ * because based upon the cpu type an arbitrary one of the
+ * following pieces of code will be copied to the KSEG0
+ * vector location.
+ */
+	/* TLB refill, EXL == 0, R4xx0, non-R4600 version */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4000)
+	.set	mips3
+#ifdef CONFIG_SMP
+	mfc0	k1, CP0_CONTEXT
+	la	k0, pgd_current
+	srl	k1, 23
+	sll	k1, 2				# log2(sizeof(pgd_t)
+	addu	k1, k0, k1
+	lw	k1, (k1)
+#else 
+	lw	k1, pgd_current			# get pgd pointer
+#endif	
+	mfc0	k0, CP0_BADVADDR		# Get faulting address
+	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
+
+	sll	k0, k0, 2
+	addu	k1, k1, k0			# add in pgd offset
+	mfc0	k0, CP0_CONTEXT			# get context reg
+	lw	k1, (k1)
+	GET_PTE_OFF(k0)				# get pte offset
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0			# add in offset
+	PTE_L	k0, 0(k1)			# get even pte
+	PTE_L	k1, PTE_SIZE(k1)		# get odd pte
+	PTE_SRL	k0, k0, 6			# convert to entrylo0
+	P_MTC0	k0, CP0_ENTRYLO0		# load it
+	PTE_SRL	k1, k1, 6			# convert to entrylo1
+	P_MTC0	k1, CP0_ENTRYLO1		# load it
+	b	1f
+	tlbwr					# write random tlb entry
+1:
+	nop
+	eret					# return from trap
+	END(except_vec0_r4000)
+
+	/* TLB refill, EXL == 0, R4600 version */
+	LEAF(except_vec0_r4600)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	srl	k0, k0, _PGDIR_SHIFT
+	lw	k1, pgd_current			# get pgd pointer
+	sll	k0, k0, 2			# log2(sizeof(pgd_t)
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+#ifndef CONFIG_64BIT_PHYS_ADDR
+	srl	k0, k0, 1
+#endif
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0
+	PTE_L	k0, 0(k1)
+	PTE_L	k1, PTE_SIZE(k1)
+	PTE_SRL	k0, k0, 6
+	P_MTC0	k0, CP0_ENTRYLO0
+	PTE_SRL	k1, k1, 6
+	P_MTC0	k1, CP0_ENTRYLO1
+	nop
+	tlbwr
+	nop
+	eret
+	END(except_vec0_r4600)
+
+	/* TLB refill, EXL == 0, R52x0 "Nevada" version */
+        /*
+         * This version has a bug workaround for the Nevada.  It seems
+         * as if under certain circumstances the move from cp0_context
+         * might produce a bogus result when the mfc0 instruction and
+         * it's consumer are in a different cacheline or a load instruction,
+         * probably any memory reference, is between them.  This is
+         * potencially slower than the R4000 version, so we use this
+         * special version.
+         */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_nevada)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR		# Get faulting address
+	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
+	lw	k1, pgd_current			# get pgd pointer
+	sll	k0, k0, 2			# log2(sizeof(pgd_t)
+	addu	k1, k1, k0			# add in pgd offset
+	lw	k1, (k1)
+	mfc0	k0, CP0_CONTEXT			# get context reg
+#ifndef CONFIG_64BIT_PHYS_ADDR
+	srl	k0, k0, 1			# get pte offset
+#endif
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0			# add in offset
+	PTE_L	k0, 0(k1)			# get even pte
+	PTE_L	k1, PTE_SIZE(k1)		# get odd pte
+	PTE_SRL	k0, k0, 6			# convert to entrylo0
+	P_MTC0	k0, CP0_ENTRYLO0		# load it
+	PTE_SRL	k1, k1, 6			# convert to entrylo1
+	P_MTC0	k1, CP0_ENTRYLO1		# load it
+	nop					# QED specified nops
+	nop
+	tlbwr					# write random tlb entry
+	nop					# traditional nop
+	eret					# return from trap
+	END(except_vec0_nevada)
+
+	/* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */
+	LEAF(except_vec0_r45k_bvahwbug)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	srl	k0, k0, _PGDIR_SHIFT
+	lw	k1, pgd_current			# get pgd pointer
+	sll	k0, k0, 2			# log2(sizeof(pgd_t)
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+#ifndef CONFIG_64BIT_PHYS_ADDR
+	srl	k0, k0, 1
+#endif
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0
+	PTE_L	k0, 0(k1)
+	PTE_L	k1, PTE_SIZE(k1)
+	nop				/* XXX */
+	tlbp
+	PTE_SRL	k0, k0, 6
+	P_MTC0	k0, CP0_ENTRYLO0
+	PTE_SRL	k1, k1, 6
+	mfc0	k0, CP0_INDEX
+	P_MTC0	k1, CP0_ENTRYLO1
+	bltzl	k0, 1f
+	tlbwr
+1:
+	nop
+	eret
+	END(except_vec0_r45k_bvahwbug)
+
+#ifdef CONFIG_SMP
+	/* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */
+	LEAF(except_vec0_r4k_mphwbug)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	srl	k0, k0, _PGDIR_SHIFT
+	lw	k1, pgd_current			# get pgd pointer
+	sll	k0, k0, 2			# log2(sizeof(pgd_t)
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+#ifndef CONFIG_64BIT_PHYS_ADDR
+	srl	k0, k0, 1
+#endif
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0
+	PTE_L	k0, 0(k1)
+	PTE_L	k1, PTE_SIZE(k1)
+	nop				/* XXX */
+	tlbp
+	PTE_SRL	k0, k0, 6
+	P_MTC0	k0, CP0_ENTRYLO0
+	PTE_SRL	k1, k1, 6
+	mfc0	k0, CP0_INDEX
+	P_MTC0	k1, CP0_ENTRYLO1
+	bltzl	k0, 1f
+	tlbwr
+1:
+	nop
+	eret
+	END(except_vec0_r4k_mphwbug)
+#endif
+
+	/* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */
+	LEAF(except_vec0_r4k_250MHZhwbug)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	srl	k0, k0, _PGDIR_SHIFT
+	lw	k1, pgd_current			# get pgd pointer
+	sll	k0, k0, 2			# log2(sizeof(pgd_t)
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+#ifndef CONFIG_64BIT_PHYS_ADDR
+	srl	k0, k0, 1
+#endif
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0
+	PTE_L	k0, 0(k1)
+	PTE_L	k1, PTE_SIZE(k1)
+	PTE_SRL	k0, k0, 6
+	P_MTC0	zero, CP0_ENTRYLO0
+	P_MTC0	k0, CP0_ENTRYLO0
+	PTE_SRL	k1, k1, 6
+	P_MTC0	zero, CP0_ENTRYLO1
+	P_MTC0	k1, CP0_ENTRYLO1
+	b	1f
+	tlbwr
+1:
+	nop
+	eret
+	END(except_vec0_r4k_250MHZhwbug)
+
+#ifdef CONFIG_SMP
+	/* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */
+	LEAF(except_vec0_r4k_MP250MHZhwbug)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	srl	k0, k0, _PGDIR_SHIFT
+	lw	k1, pgd_current			# get pgd pointer
+	sll	k0, k0, 2			# log2(sizeof(pgd_t)
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+#ifndef CONFIG_64BIT_PHYS_ADDR
+	srl	k0, k0, 1
+#endif
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0
+	PTE_L	k0, 0(k1)
+	PTE_L	k1, PTE_SIZE(k1)
+	nop				/* XXX */
+	tlbp
+	PTE_SRL	k0, k0, 6
+	P_MTC0  zero, CP0_ENTRYLO0
+	P_MTC0  k0, CP0_ENTRYLO0
+	mfc0    k0, CP0_INDEX
+	PTE_SRL	k1, k1, 6
+	P_MTC0	zero, CP0_ENTRYLO1
+	P_MTC0	k1, CP0_ENTRYLO1
+	bltzl	k0, 1f
+	tlbwr
+1:
+	nop
+	eret
+	END(except_vec0_r4k_MP250MHZhwbug)
+#endif
+
+#ifdef CONFIG_MIPS_AU1000
+	/* TLB refill, EXL == 0, Au1000 version */
+        /* we'll worry about smp later */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_au1000)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR		# Get faulting address
+	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
+	lw	k1, pgd_current			# get pgd pointer
+	sll	k0, k0, 2			# log2(sizeof(pgd_t)
+	addu	k1, k1, k0			# add in pgd offset
+	mfc0	k0, CP0_CONTEXT			# get context reg
+	lw	k1, (k1)
+#ifndef CONFIG_64BIT_PHYS_ADDR
+	srl	k0, k0, 1			# get pte offset
+#endif
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0			# add in offset
+	j	translate_pte
+	nop
+	END(except_vec0_au1000)
+#endif
+
+
+	__FINIT
+
+/*
+ * ABUSE of CPP macros 101.
+ *
+ * After this macro runs, the pte faulted on is
+ * in register PTE, a ptr into the table in which
+ * the pte belongs is in PTR.
+ */
+
+#ifdef CONFIG_SMP
+#define GET_PGD(scratch, ptr)        \
+	mfc0    ptr, CP0_CONTEXT;    \
+	la      scratch, pgd_current;\
+	srl     ptr, 23;             \
+	sll     ptr, 2;              \
+	addu    ptr, scratch, ptr;   \
+	lw      ptr, (ptr);          
+#else
+#define GET_PGD(scratch, ptr)    \
+	lw	ptr, pgd_current;
+#endif
+
+#define LOAD_PTE(pte, ptr) \
+	GET_PGD(pte, ptr)          \
+	mfc0	pte, CP0_BADVADDR; \
+	srl	pte, pte, _PGDIR_SHIFT; \
+	sll	pte, pte, 2; \
+	addu	ptr, ptr, pte; \
+	mfc0	pte, CP0_BADVADDR; \
+	lw	ptr, (ptr); \
+	srl	pte, pte, PTE_INDX_SHIFT; \
+	and	pte, pte, PTE_INDX_MSK; \
+	addu	ptr, ptr, pte; \
+	PTE_L	pte, (ptr);
+
+	/* This places the even/odd pte pair in the page
+	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+	 * TMP as a scratch register.
+	 */
+#define PTE_RELOAD(ptr, tmp) \
+	ori	ptr, ptr, PTE_SIZE; \
+	xori	ptr, ptr, PTE_SIZE; \
+	PTE_L	tmp, PTE_SIZE(ptr); \
+	PTE_L	ptr, 0(ptr); \
+	PTE_SRL	tmp, tmp, 6; \
+	P_MTC0	tmp, CP0_ENTRYLO1; \
+	PTE_SRL	ptr, ptr, 6; \
+	P_MTC0	ptr, CP0_ENTRYLO0;
+
+#define DO_FAULT(write) \
+	.set	noat; \
+	SAVE_ALL; \
+	mfc0	a2, CP0_BADVADDR; \
+	KMODE; \
+	.set	at; \
+	move	a0, sp; \
+	jal	do_page_fault; \
+	 li	a1, write; \
+	j	ret_from_exception; \
+	 nop; \
+	.set	noat;
+
+	/* Check is PTE is present, if not then jump to LABEL.
+	 * PTR points to the page table where this PTE is located,
+	 * when the macro is done executing PTE will be restored
+	 * with it's original value.
+	 */
+#define PTE_PRESENT(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	bnez	pte, label; \
+	 PTE_L	pte, (ptr);
+
+	/* Make PTE valid, store result in PTR. */
+#define PTE_MAKEVALID(pte, ptr) \
+	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+	PTE_S	pte, (ptr);
+
+	/* Check if PTE can be written to, if not branch to LABEL.
+	 * Regardless restore PTE with value from PTR when done.
+	 */
+#define PTE_WRITABLE(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	bnez	pte, label; \
+	 PTE_L	pte, (ptr);
+
+	/* Make PTE writable, update software status bits as well,
+	 * then store at PTR.
+	 */
+#define PTE_MAKEWRITE(pte, ptr) \
+	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+			   _PAGE_VALID | _PAGE_DIRTY); \
+	PTE_S	pte, (ptr);
+
+	.set	noreorder
+
+/*
+ * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
+ * 2. A timing hazard exists for the TLBP instruction.
+ *
+ *      stalling_instruction
+ *      TLBP
+ *
+ * The JTLB is being read for the TLBP throughout the stall generated by the
+ * previous instruction. This is not really correct as the stalling instruction
+ * can modify the address used to access the JTLB.  The failure symptom is that
+ * the TLBP instruction will use an address created for the stalling instruction
+ * and not the address held in C0_ENHI and thus report the wrong results.
+ *
+ * The software work-around is to not allow the instruction preceding the TLBP
+ * to stall - make it an NOP or some other instruction guaranteed not to stall.
+ *
+ * Errata 2 will not be fixed.  This errata is also on the R5000.
+ *
+ * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
+ */
+#define R5K_HAZARD nop
+
+	/*
+	 * Note for many R4k variants tlb probes cannot be executed out
+	 * of the instruction cache else you get bogus results.
+	 */
+	.align	5
+	NESTED(handle_tlbl, PT_SIZE, sp)
+	.set	noat
+invalid_tlbl:
+#ifdef TLB_OPTIMIZE
+	/* Test present bit in entry. */
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp
+	PTE_PRESENT(k0, k1, nopage_tlbl)
+	PTE_MAKEVALID(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3	
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbl:
+	DO_FAULT(0)
+	END(handle_tlbl)
+
+	.align	5
+	NESTED(handle_tlbs, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+        li      k0,0
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp				# find faulting entry
+	PTE_WRITABLE(k0, k1, nopage_tlbs)
+	PTE_MAKEWRITE(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbs:
+	DO_FAULT(1)
+	END(handle_tlbs)
+
+	.align	5
+	NESTED(handle_mod, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp					# find faulting entry
+	andi	k0, k0, _PAGE_WRITE
+	beqz	k0, nowrite_mod
+	 PTE_L	k0, (k1)
+
+	/* Present and writable bits set, set accessed and dirty bits. */
+	PTE_MAKEWRITE(k0, k1)
+
+	/* Now reload the entry into the tlb. */
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nowrite_mod:
+	DO_FAULT(1)
+	END(handle_mod)
+
+#ifdef CONFIG_MIPS_AU1000
+
+#ifdef CONFIG_MIPS_PB1500
+#define PSEUDO_ADDR_BASE 0x20000000
+#endif
+
+#ifdef CONFIG_MIPS_PB1000
+#define PSEUDO_ADDR_BASE 0xC0000000
+#endif
+
+/*
+ * On entry k0 contains the pte with the pseudo address.
+ * On exit, k0 contains the "real" address, which is a
+ * 36 bit physicall address.
+ * This function is called only after it has been 
+ * determined that the pte is a pseudo physical address.
+ *
+ * Destroys k0, k1, and at. It's assumed that the calling
+ * function will preserve those.
+ */
+LEAF(get_real_pte)
+	.set	mips3
+	.set	at
+
+	li	k1, 0xe0000000          # check lcd 
+	bltu	k0, k1, check_pcmcia_socket_1
+	nop
+	# lcd pseudo access
+	li	k1, 0x0fffffff
+	and	k0, k0, k1              # get offset
+#ifdef CONFIG_MIPS_PB1500
+	lui	k1, 0x1b00
+	addu	k0, k0, k1
+#endif
+	srl	k0, k0, 6
+	lui	k1, 0xe000>>2
+	or	k0, k0, k1
+	j	ra
+	nop
+check_pcmcia_socket_1:
+	li	k1, 0xD0000000
+	bltu	k0, k1, pcmcia_socket_0
+	nop
+	# famous last words, should not happen ...
+1:	
+	b 1b       # fixme -- to something a little more useful
+	# pcmcia socket 1 pseudo access
+
+pcmcia_socket_0:
+	# check mem access
+	li	k1, 0xC8000000
+	bltu	k0, k1, check_attr
+	# handle pseudo memory access
+	li	k1, 0x00ffffff
+	and	k1, k0, k1              # get access offset
+	lui	k0, 0x8000
+	or	k0, k0, k1              
+	# now we have the correct even pte ... bits 31:0
+	srl	k0, k0, 6
+	lui	k1, 0xf000>>2
+	or	k0, k0, k1
+	j	ra                      # done
+	nop
+check_attr:
+	li	k1, 0xC4000000
+	bltu	k0, k1, io_access
+	# handle pseudo attribute access
+	li	k1, 0x00ffffff
+	and	k1, k0, k1              # get access offset
+	lui	k0, 0x4000
+	or	k0, k0, k1              
+	# now we have the correct even pte ... bits 31:0
+	srl	k0, k0, 6
+	lui	k1, 0xf000>>2
+	or	k0, k0, k1
+	j	ra                      # done
+	nop
+io_access:
+#ifdef CONFIG_MIPS_PB1500
+	li	k1, 0xC0000000
+	bltu	k0, k1, pci_access
+#endif
+	# handle pseudo io access
+	li	k1, 0x00ffffff
+	and	k0, k0, k1              # get access offset
+	# now we have the correct even pte ... bits 31:0
+	srl	k0, k0, 6
+	lui	k1, 0xf000>>2
+	or	k0, k0, k1
+	j	ra                      # done
+	nop
+#ifdef CONFIG_MIPS_PB1500
+pci_access:
+	li	k1, 0x80000000
+	bltu	k0, k1, pci_io_access
+	lui	k1, 0x4000>>2
+	# handle pseudo pci mem access
+	srl	k0, k0, 6
+	or	k0, k0, k1
+	j	ra                      # done
+	nop
+pci_io_access:
+	li	k1, 0x70000000
+	bltu	k0, k1, pci_cfg_access
+	lui	k1, 0x5000>>2
+	# handle pseudo pci io access
+	srl	k0, k0, 6
+	or	k0, k0, k1
+	j	ra                      # done
+	nop
+pci_cfg_access:
+	# handle pseudo pci ext cfg access
+	li	k1, 0x0fffffff
+	and	k0, k0, k1              # get access offset
+	srl	k0, k0, 6
+	lui	k1, 0x6000>>2
+	or	k0, k0, k1
+	j	ra                      # done
+	nop
+#endif
+	.set	noat
+END(get_real_pte)
+
+/*
+ * On entry k1 contains pte pointer. Clobbers only k0 and k1.
+ */
+	LEAF(translate_pte)
+	.set	mips3
+	lui	k0, %hi(__saved_at)
+	.set	noat
+	sw	$at, %lo(__saved_at)(k0)	# save at
+	.set	at
+	sw	k1, %lo(__saved_pte)(k0)	# save pte pointer
+	sw	ra, %lo(__saved_ra)(k0)		# save ra
+	lw	k0, 0(k1)			# get even pte
+
+	li	k1, PSEUDO_ADDR_BASE   		# check pseudo addr
+	bltu	k0, k1, 1f
+	nop
+	bal	get_real_pte
+	nop
+	b	2f
+	nop
+1:
+	srl	k0, k0, 6
+2:
+	mtc0	k0, CP0_ENTRYLO0		# load it
+
+	lui	k1, %hi(__saved_pte)
+	lw	k1, %lo(__saved_pte)(k1)	# recover pte pointer
+	lw	k0, 4(k1)			# get odd pte
+
+	li	k1, PSEUDO_ADDR_BASE   		# check pseudo addr
+	bltu	k0, k1, 1f
+	nop
+	bal	get_real_pte
+	nop
+	b	2f
+	nop
+
+1:
+	srl	k0, k0, 6			# convert to entrylo0
+2:
+	mtc0	k0, CP0_ENTRYLO1		# load it
+	nop
+	b	1f
+	tlbwr					# write random tlb entry
+1:
+	lui	k0, %hi(__saved_at)
+	.set	noat
+	lw	$at, %lo(__saved_at)(k0)	# restore at
+	.set	at
+	lw	ra, %lo(__saved_ra)(k0)		# restore ra
+	eret					# return from trap
+	.set	noat
+	END(translate_pte)
+
+__saved_at:	PTR	0
+__saved_pte:	PTR	0
+__saved_ra:	PTR	0
+#endif	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/mm/umap.c linux/arch/mips/mm/umap.c
--- linux.orig/arch/mips/mm/umap.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips/mm/umap.c	2002-07-20 01:08:32.000000000 +0000
@@ -101,7 +101,7 @@
 		start = (start + PGDIR_SIZE) & PGDIR_MASK;
 		dir++;
 	}
-	flush_tlb_range (task->mm, beg, end);
+	local_flush_tlb_range (task->mm, beg, end);
 	up_write (&task->mm->mmap_sem);
 }
 
@@ -213,6 +213,6 @@
 		from = (from + PGDIR_SIZE) & PGDIR_MASK;
 		dir++;
 	}
-	flush_tlb_range(current->mm, beg, end);
+	local_flush_tlb_range(current->mm, beg, end);
 	return error;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/Makefile linux/arch/mips/philips/nino/Makefile
--- linux.orig/arch/mips/philips/nino/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -11,22 +11,14 @@
 .S.o:
 	$(CC) $(AFLAGS) -c $< -o $@
 
-O_TARGET := nino.o
+O_TARGET	:= nino.o
 
 all: nino.o
 
-obj-y	 := int-handler.o setup.o irq.o time.o reset.o rtc.o prom.o power.o
+obj-y		:= int-handler.o irq.o setup.o prom.o power.o
 
 int-handler.o: int-handler.S
 
-obj-$(CONFIG_REMOTE_DEBUG)	+= kgdb.o
-
-obj-$(CONFIG_BLK_DEV_INITRD)	+= ramdisk.o
-
-ramdisk.o:
-		$(MAKE) -C ramdisk
-		mv ramdisk/ramdisk.o ramdisk.o
-
 clean:
 		rm -f *.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/TODO linux/arch/mips/philips/nino/TODO
--- linux.orig/arch/mips/philips/nino/TODO	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/philips/nino/TODO	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,18 @@
+This is a basic TODO list for the Philips Nino porting effort. Things
+will be added and removed from time to time. Pick an item and help
+me out! Thanks!
+
+- COMPACTFLASH
+  * get IDE/PCMCIA chip interface working to read flash cards and the
+    ethernet card
+- FRAMEBUFFER
+  * complete rewrite to match new framebuffer API
+  * get 2bpp and 4bpp working (use Microwindows driver examples)
+- GPIO
+  * go through all the interrupt sources in status registers 1-5
+    and see what all the different IO pins are hooked to
+- KGDB
+  * get stub working
+- MMU
+  * Use CONFIG_CPU_TX39XX instead of current CONFIG_CPU_R3000 and
+    start using 3912 specific MMU management.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/int-handler.S linux/arch/mips/philips/nino/int-handler.S
--- linux.orig/arch/mips/philips/nino/int-handler.S	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/int-handler.S	2002-07-20 01:08:23.000000000 +0000
@@ -1,137 +1,66 @@
 /*
- *  linux/arch/mips/philips/nino/int-handler.S
+ *  arch/mips/philips/nino/int-handler.S
  *
- *  Copyright (C) 1999 Harald Koerfgen
- *  Copyright (C) 2000 Jim Pick (jim@jimpick.com)
  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.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.
  *
- *  Interrupt handler for Philips Nino.
+ *  Interrupt exception dispatch code for Philips Nino
  */
 #include <asm/asm.h>
-#include <asm/regdef.h>
 #include <asm/mipsregs.h>
+#include <asm/regdef.h>
 #include <asm/stackframe.h>
-#include <asm/tx3912.h>
-
-		.data
-	        .globl  HighPriVect
-
-HighPriVect:	.word   spurious        # Reserved
-	        .word   io_posnegint0   # IOPOSINT(0) or IONEGINT(0)
-	        .word   spurious        # CHIDMACNTINT
-	        .word   spurious        # TELDMACNTINT
-	        .word   spurious        # SNDDMACNTINT
-	        .word   spurious        # Reserved
-	        .word   io_negint56     # IONEGINT(6) or IONEGINT(5)
-	        .word   spurious        # Reserved
-	        .word   io_posint56     # IOPOSINT(6) or IOPOSINT(5)
-	        .word   spurious        # Reserved
-	        .word   spurious        # UARTBRXINT
-	        .word   uarta_rx        # UARTARXINT
-	        .word   spurious        # Reserved
-	        .word   periodic_timer  # PERINT
-	        .word   spurious        # ALARMINT
-	        .word   spurious        # POSPWROKINT or NEGPWROKINT
-
-/*
- *  Here is the entry point to handle all interrupts.
- */
-		.text
-		.set	noreorder
-		.align	5
-		NESTED(nino_handle_int, PT_SIZE, ra)
-		.set	noat
-		SAVE_ALL
-		CLI
-		.set	at
-	
-		/*
-		 * Get pending Interrupts
-		 */
-		mfc0	t0, CP0_CAUSE		# Get pending interrupts
-		andi	t2, t0, IE_IRQ4		# IRQ4 (high priority)
-		bne	t2, IE_IRQ4, low_priority
-		nop
-
-/*
- *  Ok, we've got a high priority interrupt (a.k.a. an external interrupt).
- *  Read Interrupt Status Register 6 to get vector.
- */
-high_priority:
-		lui	t0, %hi(IntStatus6)
-		lw	t1, %lo(IntStatus6)(t0)
-		andi	t1, INT6_INTVECT
-		la	t2, HighPriVect
-		addu	t1, t1, t2
-		lw	t2, 0(t1)
-		jr	t2
-		nop
-
-/*
- * Ok, we've got one of over a hundred other interupts.
- */
-low_priority:
-		lui	t0, %hi(IntStatus1)
-		lw	t1, %lo(IntStatus1)(t0)
-		j	handle_it
-		li	a0, 20
-
-/*
- * We don't currently handle spurious interrupts.
- */
-spurious:	
-		j	spurious_interrupt
-		nop
-
-/*
- * We have the IRQ number, dispatch to the real handler.
- */
-handle_it:	jal	do_IRQ
-		move	a1,sp
-		j	ret_from_irq
-		nop
-
-/************************************
- * High priority interrupt mappings *
- ************************************/
-		
-/* 
- *  Periodic timer - IRQ 0
- */
-periodic_timer:
-		j	handle_it
-		li	a0, 0
-
-/* 
- *  UARTA RX - IRQ 3
- */
-uarta_rx:
-		j	handle_it
-		li	a0, 3
-
-/* 
- *  GPIO Pin 0 transition - IRQ 10
- */
-io_posnegint0:
-		j	handle_it
-		li	a0, 10
-
-/* 
- *  GPIO Pin 5 or 6 transition (0-to-1) - IRQ 11
- */
-io_posint56:
-		j	handle_it
-		li	a0, 11
-
-/*
- *  GPIO Pin 5 or 6 transition (1-to-0) - IRQ 12
- */
-io_negint56:
-		j	handle_it
-		li	a0, 12
 
-		END(nino_handle_int)
+	/*
+	 * Here is the table of interrupts for the Philips Nino
+	 * which uses the Philips PR31700/Toshiba TMPR3912 core.
+	 *
+	 *   MIPS IRQ             Description
+	 *   --------	--------------------------------
+	 *       0	SW0 interrupt (unused)
+	 *       1	SW1 interrupt (unused)
+	 *       2
+	 *       3
+	 *       4	PR31700 low priority interrupts
+	 *       5
+	 *       6	PR31700 high priority interrupts
+	 *       7
+	 */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(ninoIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	mfc0	s0, CP0_CAUSE		# determine cause
+
+	andi	a0, s0, CAUSEF_IP6
+	beq	a0, zero, 1f
+	andi	a0, s0, CAUSEF_IP4	# delay slot
+	move    a0, sp
+	jal	irq6_dispatch
+	nop				# delay slot
+	j	ret_from_irq
+	nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	nop				# delay slot
+	move	a0, sp
+	jal	irq4_dispatch
+	nop				# delay slot
+	j	ret_from_irq
+	nop				# delay slot
+
+1:
+	/* We should never get here */
+	move	a0, sp
+	j	irq_bad
+	nop
+	END(ninoIRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/irq.c linux/arch/mips/philips/nino/irq.c
--- linux.orig/arch/mips/philips/nino/irq.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/irq.c	2002-07-20 01:08:24.000000000 +0000
@@ -1,314 +1,264 @@
 /*
- *  linux/arch/mips/philips/nino/irq.c
+ *  arch/mips/philips/nino/irq.c
  *
- *  Copyright (C) 1992 Linus Torvalds
- *  Copyright (C) 1999 Harald Koerfgen
- *  Copyright (C) 2000 Pavel Machek (pavel@suse.cz)
  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.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.
- *  
- *  Generic interrupt handler for Philips Nino.
+ *
+ *  Interrupt service routines for Philips Nino
  */
-#include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/types.h>
 #include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/mipsregs.h>
-#include <asm/system.h>
 #include <asm/tx3912.h>
 
-unsigned long spurious_count = 0;
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
 
-irq_cpustat_t irq_stat [NR_CPUS];
+extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
 
-static inline void mask_irq(unsigned int irq_nr)
+static void enable_irq6(unsigned int irq)
 {
-	switch (irq_nr) {
-	case 0:  /* Periodic Timer Interrupt */ 
-		IntClear5 = INT5_PERIODICINT;
-		IntClear6 = INT6_PERIODICINT;
-		IntEnable6 &= ~INT6_PERIODICINT;
-		break;
+	if(irq == 0) {
+		outl(inl(TX3912_INT6_ENABLE) |
+			TX3912_INT6_ENABLE_PRIORITYMASK_PERINT,
+			TX3912_INT6_ENABLE);
+		outl(inl(TX3912_INT5_ENABLE) | TX3912_INT5_PERINT,
+			TX3912_INT5_ENABLE);
+	}
+	if(irq == 3) {
+		outl(inl(TX3912_INT6_ENABLE) |
+			TX3912_INT6_ENABLE_PRIORITYMASK_UARTARXINT,
+			TX3912_INT6_ENABLE);
+		outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_RX_BITS,
+			TX3912_INT2_ENABLE);
+	}
+}
 
-	case 3:
-		/* Serial port receive interrupt */
-		break;
+static unsigned int startup_irq6(unsigned int irq)
+{
+	enable_irq6(irq);
 
-	case 2:
-		/* Serial port transmit interrupt */
-		break;
+	return 0;		/* Never anything pending  */
+}
 
-	default:
-		printk( "Attempt to mask unknown IRQ %d?\n", irq_nr );
+static void disable_irq6(unsigned int irq)
+{
+	if(irq == 0) {
+		outl(inl(TX3912_INT6_ENABLE) &
+			~TX3912_INT6_ENABLE_PRIORITYMASK_PERINT,
+			TX3912_INT6_ENABLE);
+		outl(inl(TX3912_INT5_ENABLE) & ~TX3912_INT5_PERINT,
+			TX3912_INT5_ENABLE);
+		outl(inl(TX3912_INT5_CLEAR) | TX3912_INT5_PERINT,
+			TX3912_INT5_CLEAR);
+	}
+	if(irq == 3) {
+		outl(inl(TX3912_INT6_ENABLE) &
+			~TX3912_INT6_ENABLE_PRIORITYMASK_UARTARXINT,
+			TX3912_INT6_ENABLE);
+		outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_RX_BITS,
+			TX3912_INT2_ENABLE);
 	}
 }
 
-static inline void unmask_irq(unsigned int irq_nr)
+#define shutdown_irq6		disable_irq6
+#define mask_and_ack_irq6	disable_irq6
+
+static void end_irq6(unsigned int irq)
 {
-	switch (irq_nr) {
-	case 0:
-		IntEnable6 |= INT6_PERIODICINT;
-		break;
+	if(!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_irq6(irq);
+}
 
-	case 3:
-		/* Serial port receive interrupt */
-		break;
+static struct hw_interrupt_type irq6_type = {
+	"MIPS",
+	startup_irq6,
+	shutdown_irq6,
+	enable_irq6,
+	disable_irq6,
+	mask_and_ack_irq6,
+	end_irq6,
+	NULL
+};
+
+void irq6_dispatch(struct pt_regs *regs)
+{
+	int irq = -1;
 
-	case 2:
-		/* Serial port transmit interrupt */
-		break;
+	if((inl(TX3912_INT6_STATUS) & TX3912_INT6_STATUS_INTVEC_UARTARXINT) ==
+		TX3912_INT6_STATUS_INTVEC_UARTARXINT) {
+		irq = 3;
+		goto done;
+	}
+	if ((inl(TX3912_INT6_STATUS) & TX3912_INT6_STATUS_INTVEC_PERINT) ==
+		TX3912_INT6_STATUS_INTVEC_PERINT) {
+		irq = 0;
+		goto done;
+	}
 
-	default:
-		printk( "Attempt to unmask unknown IRQ %d?\n", irq_nr );
+	/* if irq == -1, then interrupt was cleared or is invalid */
+	if (irq == -1) {
+		panic("Unhandled High Priority PR31700 Interrupt = 0x%08x",
+			inl(TX3912_INT6_STATUS));
 	}
+
+done:
+	do_IRQ(irq, regs);
 }
 
-void disable_irq(unsigned int irq_nr)
+static void enable_irq4(unsigned int irq)
 {
-    unsigned long flags;
-
-    save_and_cli(flags);
-    mask_irq(irq_nr);
-    restore_flags(flags);
+	set_cp0_status(STATUSF_IP4);
+	if (irq == 2) {
+		outl(inl(TX3912_INT2_CLEAR) | TX3912_INT2_UARTA_TX_BITS,
+			TX3912_INT2_CLEAR);
+		outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_TX_BITS,
+			TX3912_INT2_ENABLE);
+	}
 }
 
-void enable_irq(unsigned int irq_nr)
+static unsigned int startup_irq4(unsigned int irq)
 {
-    unsigned long flags;
+	enable_irq4(irq);
 
-    save_and_cli(flags);
-    unmask_irq(irq_nr);
-    restore_flags(flags);
+	return 0;		/* Never anything pending  */
 }
 
-/*
- * Pointers to the low-level handlers: first the general ones, then the
- * fast ones, then the bad ones.
- */
-extern void interrupt(void);
-
-static struct irqaction *irq_action[NR_IRQS] =
+static void disable_irq4(unsigned int irq)
 {
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
+	clear_cp0_status(STATUSF_IP4);
+}
 
-int get_irq_list(char *buf)
-{
-    int i, len = 0;
-    struct irqaction *action;
+#define shutdown_irq4		disable_irq4
+#define mask_and_ack_irq4	disable_irq4
 
-    for (i = 0; i < NR_IRQS; i++) {
-	action = irq_action[i];
-	if (!action)
-	    continue;
-	len += sprintf(buf + len, "%2d: %8d %c %s",
-		       i, kstat.irqs[0][i],
-		       (action->flags & SA_INTERRUPT) ? '+' : ' ',
-		       action->name);
-	for (action = action->next; action; action = action->next) {
-	    len += sprintf(buf + len, ",%s %s",
-			   (action->flags & SA_INTERRUPT) ? " +" : "",
-			   action->name);
-	}
-	len += sprintf(buf + len, "\n");
-    }
-    return len;
+static void end_irq4(unsigned int irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_irq4(irq);
 }
 
-atomic_t __mips_bh_counter;
+static struct hw_interrupt_type irq4_type = {
+	"MIPS",
+	startup_irq4,
+	shutdown_irq4,
+	enable_irq4,
+	disable_irq4,
+	mask_and_ack_irq4,
+	end_irq4,
+	NULL
+};
 
-/*
- * do_IRQ handles IRQ's that have been installed without the
- * SA_INTERRUPT flag: it uses the full signal-handling return
- * and runs with other interrupts enabled. All relatively slow
- * IRQ's should use this format: notably the keyboard/timer
- * routines.
- */
-asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
+void irq4_dispatch(struct pt_regs *regs)
 {
-    struct irqaction *action;
-    int do_random, cpu;
+	int irq = -1;
 
-    if (irq == 20) {
-        if (IntStatus2 & 0xfffff00) {
-		if (IntStatus2 & 0x0f000000)
-		return do_IRQ(2, regs);
-	}
-    }
-
-    cpu = smp_processor_id();
-    irq_enter(cpu, irq);
-    kstat.irqs[cpu][irq]++;
-
-    if (irq == 20) {
-            printk("20 %08lx %08lx\n   %08lx %08lx\n   %08lx\n",
-                   IntStatus1, IntStatus2, IntStatus3,
-                   IntStatus4, IntStatus5 );
-            printk("20 %08lx %08lx\n   %08lx %08lx\n   %08lx\n",
-                   IntEnable1, IntEnable2, IntEnable3,
-                   IntEnable4, IntEnable5 );
-
-    }
-
-    mask_irq(irq);
-    action = *(irq + irq_action);
-    if (action) {
-	if (!(action->flags & SA_INTERRUPT))
-	    __sti();
-	do_random = 0;
-	do {
-	    do_random |= action->flags;
-	    action->handler(irq, action->dev_id, regs);
-	    action = action->next;
-	} while (action);
-	if (do_random & SA_SAMPLE_RANDOM)
-	    add_interrupt_randomness(irq);
-	unmask_irq(irq);
-	__cli();
-    } else {
-            IntClear1 = ~0;
-            IntClear3 = ~0;
-	    IntClear4 = ~0;
-	    IntClear5 = ~0;
-	    unmask_irq(irq);
-    }
-    irq_exit(cpu, irq);
+	if(inl(TX3912_INT2_STATUS) & TX3912_INT2_UARTA_TX_BITS) {
+		irq = 2;
+		goto done;
+	}
 
-    /* unmasking and bottom half handling is done magically for us. */
-}
+	/* if irq == -1, then interrupt was cleared or is invalid */
+	if (irq == -1) {
+		printk("PR31700 Interrupt Status Register 1 = 0x%08x\n",
+			inl(TX3912_INT1_STATUS));
+		printk("PR31700 Interrupt Status Register 2 = 0x%08x\n",
+			inl(TX3912_INT2_STATUS));
+		printk("PR31700 Interrupt Status Register 3 = 0x%08x\n",
+			inl(TX3912_INT3_STATUS));
+		printk("PR31700 Interrupt Status Register 4 = 0x%08x\n",
+			inl(TX3912_INT4_STATUS));
+		printk("PR31700 Interrupt Status Register 5 = 0x%08x\n",
+			inl(TX3912_INT5_STATUS));
+		panic("Unhandled Low Priority PR31700 Interrupt");
+	}
 
-/*
- * Idea is to put all interrupts
- * in a single table and differenciate them just by number.
- */
-int setup_nino_irq(int irq, struct irqaction *new)
-{
-    int shared = 0;
-    struct irqaction *old, **p;
-    unsigned long flags;
-
-    p = irq_action + irq;
-    if ((old = *p) != NULL) {
-	/* Can't share interrupts unless both agree to */
-	if (!(old->flags & new->flags & SA_SHIRQ))
-	    return -EBUSY;
-
-	/* Can't share interrupts unless both are same type */
-	if ((old->flags ^ new->flags) & SA_INTERRUPT)
-	    return -EBUSY;
-
-	/* add new interrupt at end of irq queue */
-	do {
-	    p = &old->next;
-	    old = *p;
-	} while (old);
-	shared = 1;
-    }
-    if (new->flags & SA_SAMPLE_RANDOM)
-	rand_initialize_irq(irq);
-
-    save_and_cli(flags);
-    *p = new;
-
-    if (!shared) {
-	unmask_irq(irq);
-    }
-    restore_flags(flags);
-    return 0;
-}
-
-int request_irq(unsigned int irq,
-		void (*handler) (int, void *, struct pt_regs *),
-		unsigned long irqflags,
-		const char *devname,
-		void *dev_id)
-{
-    int retval;
-    struct irqaction *action;
-
-    if (irq >= NR_IRQS)
-	return -EINVAL;
-    if (!handler)
-	return -EINVAL;
-
-    action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-    if (!action)
-	return -ENOMEM;
-
-    action->handler = handler;
-    action->flags = irqflags;
-    action->mask = 0;
-    action->name = devname;
-    action->next = NULL;
-    action->dev_id = dev_id;
-
-    retval = setup_nino_irq(irq, action);
-
-    if (retval)
-	kfree(action);
-    return retval;
+done:
+	do_IRQ(irq, regs);
+	return;
 }
 
-void free_irq(unsigned int irq, void *dev_id)
+void irq_bad(struct pt_regs *regs)
 {
-    struct irqaction *action, **p;
-    unsigned long flags;
+	/* This should never happen */
+	printk(" CAUSE register = 0x%08lx\n", regs->cp0_cause);
+	printk("STATUS register = 0x%08lx\n", regs->cp0_status);
+	printk("   EPC register = 0x%08lx\n", regs->cp0_epc);
+	panic("Stray interrupt, spinning...");
+}
+
+void __init nino_irq_setup(void)
+{
+	extern asmlinkage void ninoIRQ(void);
+
+	unsigned int i;
+
+	/* Disable all hardware interrupts */
+	change_cp0_status(ST0_IM, 0x00);
+
+	/* Clear interrupts */
+	outl(0xffffffff, TX3912_INT1_CLEAR);
+	outl(0xffffffff, TX3912_INT2_CLEAR);
+	outl(0xffffffff, TX3912_INT3_CLEAR);
+	outl(0xffffffff, TX3912_INT4_CLEAR);
+	outl(0xffffffff, TX3912_INT5_CLEAR);
+
+	/*
+	 * Disable all PR31700 interrupts. We let the various
+	 * device drivers in the system register themselves
+	 * and set the proper hardware bits.
+	 */
+	outl(0x00000000, TX3912_INT1_ENABLE);
+	outl(0x00000000, TX3912_INT2_ENABLE);
+	outl(0x00000000, TX3912_INT3_ENABLE);
+	outl(0x00000000, TX3912_INT4_ENABLE);
+	outl(0x00000000, TX3912_INT5_ENABLE);
+
+	/* Initialize IRQ vector table */
+	init_generic_irq();
+
+	/* Initialize IRQ action handlers */
+	for (i = 0; i < 16; i++) {
+		hw_irq_controller *handler = NULL;
+		if (i == 0 || i == 3)
+			handler		= &irq6_type;
+		else
+			handler		= &irq4_type;
+
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= handler;
+	}
 
-    if (irq >= NR_IRQS) {
-	printk(KERN_CRIT __FUNCTION__ ": trying to free IRQ%d\n", irq);
-	return;
-    }
-    for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
-	if (action->dev_id != dev_id)
-	    continue;
-
-	/* Found it - now free it */
-	save_and_cli(flags);
-	*p = action->next;
-	if (!irq[irq_action])
-	    mask_irq(irq);
-	restore_flags(flags);
-	kfree(action);
-	return;
-    }
-    printk(KERN_CRIT __FUNCTION__ ": trying to free free IRQ%d\n", irq);
-}
+	/* Set up the external interrupt exception vector */
+	set_except_vector(0, ninoIRQ);
 
-unsigned long probe_irq_on(void)
-{
-    /* TODO */
-    return 0;
-}
+	/* Enable high priority interrupts */
+	outl(TX3912_INT6_ENABLE_GLOBALEN | TX3912_INT6_ENABLE_HIGH_PRIORITY,
+		TX3912_INT6_ENABLE);
 
-int probe_irq_off(unsigned long irqs)
-{
-    /* TODO */
-    return 0;
+	/* Enable all interrupts */
+	change_cp0_status(ST0_IM, ALLINTS);
 }
 
+void (*irq_setup)(void);
+
 void __init init_IRQ(void)
 {
-    irq_setup();
+#ifdef CONFIG_REMOTE_DEBUG
+	extern void breakpoint(void);
+	extern void set_debug_traps(void);
+
+	printk("Wait for gdb client connection ...\n");
+	set_debug_traps();
+	breakpoint();
+#endif
+
+	/* Invoke board-specific irq setup */
+	irq_setup();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/kgdb.c linux/arch/mips/philips/nino/kgdb.c
--- linux.orig/arch/mips/philips/nino/kgdb.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/kgdb.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,83 +0,0 @@
-/*
- *  linux/arch/mips/philips/nino/kgdb.c
- *
- *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.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.
- *
- *  Kernel debugging on the Philips Nino.
- */
-#include <asm/system.h>
-#include <asm/tx3912.h>
-
-static int remoteDebugInitialized = 0;
-
-void debugInit(void)
-{
-/*
- * If low-level debugging (before GDB or console operational) is
- * configured, then we do not need to re-initialize the UART.
- */
-#ifndef CONFIG_DEBUG_LL
-	earlyInitUartPR31700();
-#endif
-}
-
-char getDebugChar(void)
-{
-	char buf;
-	unsigned long int2, flags;
-
-	if (!remoteDebugInitialized) {
-		debugInit();
-		remoteDebugInitialized = 1;
-	}
-
-	save_and_cli(flags);
-
-	int2 = IntEnable2;
-
-	IntEnable2 = 0;
-
-	while(!(UartA_Ctrl1 & UART_RX_HOLD_FULL));
-
-	buf = UartA_Data;
-
-	IntEnable2 = int2;
-
-	restore_flags(flags);
-
-	return buf;	
-}
-
-int putDebugChar(char c)
-{
-	int i;
-	unsigned long int2;
-
-	if (!remoteDebugInitialized) {
-		debugInit();
-		remoteDebugInitialized = 1;
-	}
-
-	int2 = IntEnable2;
-
-	IntEnable2 &=
-		~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
-
-	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < 10000); i++);
-
-	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
-
-	UartA_Data = c;
-
-	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < 10000); i++);
-
-	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
-
-	IntEnable2 = int2;
-
-	return 1;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/power.c linux/arch/mips/philips/nino/power.c
--- linux.orig/arch/mips/philips/nino/power.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/power.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/mips/philips/nino/power.c
+ *  arch/mips/philips/nino/power.c
  *
  *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
@@ -8,21 +8,24 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- *  Power management routines on the Philips Nino.
+ *  Power management routines for the Philips Nino
  */
+#include <asm/io.h>
 #include <asm/tx3912.h>
 
 void nino_wait(void)
 {
 	/* We stop the CPU to conserve power */
-	PowerControl |= PWR_STOPCPU;
+	outl(inl(TX3912_POWER_CTRL) | TX3912_POWER_CTRL_STOPCPU,
+		 TX3912_POWER_CTRL);
 
 	/* 
 	 * We wait until an interrupt happens...
 	 */
 
 	/* We resume here */
-	PowerControl &= ~PWR_STOPCPU;
+	outl(inl(TX3912_POWER_CTRL) & ~TX3912_POWER_CTRL_STOPCPU,
+		 TX3912_POWER_CTRL);
 
 	/* Give ourselves a little delay */
 	__asm__ __volatile__(
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/prom.c linux/arch/mips/philips/nino/prom.c
--- linux.orig/arch/mips/philips/nino/prom.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/prom.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/mips/philips/nino/prom.c
+ *  arch/mips/philips/nino/prom.c
  *
  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
  *
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *  
- *  Early initialization code for the Philips Nino.
+ *  Early initialization code for the Philips Nino
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -17,29 +17,25 @@
 #include <asm/addrspace.h>
 #include <asm/page.h>
 
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
 
 #ifdef CONFIG_FB_TX3912
-extern u_long tx3912fb_paddr;
-extern u_long tx3912fb_vaddr;
-extern u_long tx3912fb_size;
+extern unsigned long tx3912fb_paddr;
+extern unsigned long tx3912fb_vaddr;
+extern unsigned long tx3912fb_size;
 #endif
 
+const char *get_system_type(void)
+{
+	return "Philips Nino";
+}
+
 /* Do basic initialization */
-void __init prom_init(int argc, char **argv,
-		unsigned long magic, int *prom_vec)
+void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec)
 {
-	u_long free_end, mem_size;
-	u_int i;
+	unsigned long mem_size;
 
-	/*
-	 * collect args and prepare cmd_line
-	 */
-	for (i = 1; i < argc; i++) {
-		strcat(arcs_cmdline, argv[i]);
-		if (i < (argc - 1))
-			strcat(arcs_cmdline, " ");
-	}
+	strcpy(arcs_cmdline, "console=tty0 console=ttyS0,115200");
 
 	mips_machgroup = MACH_GROUP_PHILIPS;
 	mips_machtype = MACH_PHILIPS_NINO;
@@ -53,6 +49,9 @@
 #endif
 
 #ifdef CONFIG_FB_TX3912
+{
+	unsigned long free_end;
+
 	/*
 	 * The LCD controller requires that the framebuffer
 	 * start address fall within a 1MB segment and is
@@ -70,6 +69,7 @@
 	 */
 	tx3912fb_paddr = PHYSADDR(free_end);
 	tx3912fb_vaddr = KSEG1ADDR(free_end);
+}
 #else
 	add_memory_region(0, mem_size, BOOT_MEM_RAM); 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/ramdisk/Makefile linux/arch/mips/philips/nino/ramdisk/Makefile
--- linux.orig/arch/mips/philips/nino/ramdisk/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/ramdisk/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-#
-# Makefile for the Philips Nino ramdisk
-#
-# 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).
-#
-
-ramdisk.o: ramdisk.gz ld.script
-	$(LD) -T ld.script -b binary -o $@ ramdisk.gz
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/ramdisk/ld.script linux/arch/mips/philips/nino/ramdisk/ld.script
--- linux.orig/arch/mips/philips/nino/ramdisk/ld.script	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/ramdisk/ld.script	1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-OUTPUT_FORMAT("ecoff-littlemips")
-OUTPUT_ARCH(mips)
-SECTIONS
-{
-  .initrd :
-  {
-        *(.data)
-  }
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/reset.c linux/arch/mips/philips/nino/reset.c
--- linux.orig/arch/mips/philips/nino/reset.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/reset.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,37 +0,0 @@
-/*
- *  linux/arch/mips/philips/nino/reset.c
- *
- *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.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.
- *
- *  Generic restart, halt and power off functions for Philips Nino.
- */
-#include <linux/init.h>
-#include <asm/reboot.h>
-
-void (*reset_vector)(void) = (void (*)(void)) 0xBFC00000;
-
-void nino_machine_restart(char *command)
-{
-	reset_vector();
-}
-
-void nino_machine_halt(void)
-{
-	reset_vector();
-}
-
-void nino_machine_power_off(void)
-{
-	reset_vector();
-}
-
-void __init setup_nino_reset_vectors(void)
-{
-	_machine_restart = nino_machine_restart;
-	_machine_halt = nino_machine_halt;
-	_machine_power_off = nino_machine_power_off;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/rtc.c linux/arch/mips/philips/nino/rtc.c
--- linux.orig/arch/mips/philips/nino/rtc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,34 +0,0 @@
-/*
- *  linux/arch/mips/philips/nino/rtc.c
- *
- *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.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.
- *
- *  Functions to access RTC on the Philips Nino.
- */
-#include <linux/spinlock.h>
-#include <linux/mc146818rtc.h>
-
-static unsigned char nino_rtc_read_data(unsigned long addr)
-{
-	return 0;
-}
-
-static void nino_rtc_write_data(unsigned char data, unsigned long addr)
-{
-}
-
-static int nino_rtc_bcd_mode(void)
-{
-	return 0;
-}
-
-struct rtc_ops nino_rtc_ops =
-{
-	&nino_rtc_read_data,
-	&nino_rtc_write_data,
-	&nino_rtc_bcd_mode
-};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/setup.c linux/arch/mips/philips/nino/setup.c
--- linux.orig/arch/mips/philips/nino/setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/setup.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/mips/philips/nino/setup.c
+ *  arch/mips/philips/nino/setup.c
  *
  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
  *
@@ -7,114 +7,99 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- *  Interrupt and exception initialization for Philips Nino.
+ *  Interrupt and exception initialization for Philips Nino
  */
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
 #include <linux/sched.h>
 #include <asm/addrspace.h>
-#include <asm/gdb-stub.h>
+#include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/wbflush.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
 #include <asm/tx3912.h>
 
-extern struct rtc_ops nino_rtc_ops;
-
-extern void nino_wait(void);
-extern void setup_nino_reset_vectors(void);
-extern asmlinkage void nino_handle_int(void);
-extern int setup_nino_irq(int, struct irqaction *);
-void (*board_time_init) (struct irqaction * irq);
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void set_debug_traps(void);
-extern void breakpoint(void);
-static int remote_debug = 0;
-#endif
-
-static void __init nino_irq_setup(void)
+static void nino_machine_restart(char *command)
 {
-	unsigned int tmp;
+	static void (*back_to_prom)(void) = (void (*)(void)) 0xbfc00000;
 
-	/* Turn all interrupts off */
-	IntEnable1 = 0;
-	IntEnable2 = 0;
-	IntEnable3 = 0;
-	IntEnable4 = 0;
-	IntEnable5 = 0;
-	IntEnable6 = 0;
-
-	/* Clear all interrupts */
-	IntClear1 = 0xffffffff;
-	IntClear2 = 0xffffffff;
-	IntClear3 = 0xffffffff;
-	IntClear4 = 0xffffffff;
-	IntClear5 = 0xffffffff;
-	IntClear6 = 0xffffffff;
+	/* Reboot */
+	back_to_prom();
+}
 
-	/*
-	 * Enable only the interrupts for the UART and negative
-	 * edge (1-to-0) triggered multi-function I/O pins.
-	 */
-    	change_cp0_status(ST0_BEV, 0);
-	tmp = read_32bit_cp0_register(CP0_STATUS);
-    	change_cp0_status(ST0_IM, tmp | IE_IRQ2 | IE_IRQ4);
-
-	/* Register the global interrupt handler */
-	set_except_vector(0, nino_handle_int);
-
-#ifdef CONFIG_REMOTE_DEBUG
-	if (remote_debug) {
-		set_debug_traps();
-		breakpoint();
-	}
-#endif
+static void nino_machine_halt(void)
+{
+	printk("Nino halted.\n");
+	while(1);
 }
 
-static __init void nino_time_init(struct irqaction *irq)
+static void nino_machine_power_off(void)
 {
-	unsigned int scratch = 0;
+	printk("Nino halted. Please turn off power.\n");
+	while(1);
+}
 
+static void __init nino_board_init()
+{
 	/*
-	 * Enable periodic interrupts
+	 * Set up the master clock module. The value set in
+	 * the Clock Control Register by WindowsCE is 0x00432ba.
+	 * We set a few values here and let the device drivers
+	 * handle the rest.
+	 *
+	 * NOTE: The UART clocks must be enabled here to provide
+	 *       enough time for them to settle.
 	 */
-	setup_nino_irq(0, irq);
+	outl(0x00000000, TX3912_CLK_CTRL);
+	outl((TX3912_CLK_CTRL_SIBMCLKDIR | TX3912_CLK_CTRL_SIBMCLKDIV_2 |
+		TX3912_CLK_CTRL_ENSIBMCLK | TX3912_CLK_CTRL_CSERSEL |
+		TX3912_CLK_CTRL_CSERDIV_3 | TX3912_CLK_CTRL_ENCSERCLK |
+		TX3912_CLK_CTRL_ENUARTACLK | TX3912_CLK_CTRL_ENUARTBCLK),
+		TX3912_CLK_CTRL);
+}
 
-	RTCperiodTimer = PER_TIMER_COUNT;
-	RTCtimerControl = TIM_ENPERTIMER;
-	IntEnable5 |= INT5_PERIODICINT;
-
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch |= TX3912_CLK_CTRL_ENTIMERCLK;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
+static __init void nino_time_init(void)
+{
+	/* Load the counter and enable the timer */
+	outl(TX3912_SYS_TIMER_VALUE, TX3912_TIMER_PERIOD);
+	outl(TX3912_TIMER_CTRL_ENPERTIMER, TX3912_TIMER_CTRL);
+
+	/* Enable the master timer clock */
+	outl(inl(TX3912_CLK_CTRL) | TX3912_CLK_CTRL_ENTIMERCLK,
+		TX3912_CLK_CTRL);
+
+	/* Enable the interrupt */
+	outl(inl(TX3912_INT5_ENABLE) | TX3912_INT5_PERINT,
+		TX3912_INT5_ENABLE);
+}
 
-	/* Enable all interrupts */
-	IntEnable6 |= INT6_GLOBALEN | INT6_PERIODICINT;
+static __init void nino_timer_setup(struct irqaction *irq)
+{
+	irq->dev_id = (void *) irq;
+	setup_irq(0, irq);
 }
 
 void __init nino_setup(void)
 {
-	irq_setup = nino_irq_setup;
+	extern void nino_irq_setup(void);
+	extern void nino_wait(void);
 
-	board_time_init = nino_time_init;
+	irq_setup = nino_irq_setup;
+	set_io_port_base(KSEG1ADDR(0x10c00000));
 
-	/* Base address to use for PC type I/O accesses */
-	mips_io_port_base = KSEG1ADDR(0xB0C00000);
+	_machine_restart = nino_machine_restart;
+	_machine_halt = nino_machine_halt;
+	_machine_power_off = nino_machine_power_off;
 
-	setup_nino_reset_vectors();
+	board_time_init = nino_time_init;
+	board_timer_setup = nino_timer_setup;
 
-	/* Function called during process idle (cpu_idle) */
 	cpu_wait = nino_wait;
 
 #ifdef CONFIG_FB
 	conswitchp = &dummy_con;
 #endif
 
-#ifdef CONFIG_REMOTE_DEBUG
-	remote_debug = 1;
-#endif
-
-	rtc_ops = &nino_rtc_ops;
+	nino_board_init();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/philips/nino/time.c linux/arch/mips/philips/nino/time.c
--- linux.orig/arch/mips/philips/nino/time.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/philips/nino/time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,216 +0,0 @@
-/*
- *  linux/arch/mips/philips/nino/time.c
- *
- *  Copyright (C) 1999 Harald Koerfgen
- *  Copyright (C) 2000 Pavel Machek (pavel@suse.cz)
- *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.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.
- *
- *  Time handling functinos for Philips Nino.
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/delay.h>
-#include <asm/tx3912.h>
-
-extern volatile unsigned long wall_jiffies;
-extern rwlock_t xtime_lock;
-
-static struct timeval xbase;
-
-#define USECS_PER_JIFFY (1000000/HZ)
-
-/*
- * Poll the Interrupt Status Registers
- */
-#undef POLL_STATUS
-
-static unsigned long do_gettimeoffset(void)
-{
-    /*
-     * This is a kludge
-     */
-    return 0;
-}
-
-static
-void inline readRTC(unsigned long *high, unsigned long *low)
-{
-	/* read twice, and keep reading till we find two
-	 * the same pairs. This is needed in case the RTC
-	 * was updating its registers and we read a old
-	 * High but a new Low. */
-	do {
-		*high = RTChigh & RTC_HIGHMASK;
-		*low = RTClow;
-	} while (*high != (RTChigh & RTC_HIGHMASK) || RTClow!=*low);
-}
-
-/*
- * This version of gettimeofday has near millisecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
-    unsigned long flags;
-    unsigned long high, low;
-
-    read_lock_irqsave(&xtime_lock, flags);
-    // 40 bit RTC, driven by 32khz source:
-    // +-----------+-----------------------------------------+
-    // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM |
-    // +-----------+-----------------------------------------+
-    readRTC(&high,&low);
-    tv->tv_sec  = (high << 17) | (low >> 15);
-    tv->tv_usec = (low % 32768) * 1953 / 64;
-    tv->tv_sec += xbase.tv_sec;
-    tv->tv_usec += xbase.tv_usec;
-
-    tv->tv_usec += do_gettimeoffset();
-
-    /*
-     * xtime is atomically updated in timer_bh. lost_ticks is
-     * nonzero if the timer bottom half hasnt executed yet.
-     */
-    if (jiffies - wall_jiffies)
-	tv->tv_usec += USECS_PER_JIFFY;
-
-    read_unlock_irqrestore(&xtime_lock, flags);
-
-    if (tv->tv_usec >= 1000000) {
-	tv->tv_usec -= 1000000;
-	tv->tv_sec++;
-    }
-}
-
-void do_settimeofday(struct timeval *tv)
-{
-    write_lock_irq(&xtime_lock);
-    /* This is revolting. We need to set the xtime.tv_usec
-     * correctly. However, the value in this location is
-     * is value at the last tick.
-     * Discover what correction gettimeofday
-     * would have done, and then undo it!
-     */
-    tv->tv_usec -= do_gettimeoffset();
-
-    if (tv->tv_usec < 0) {
-	tv->tv_usec += 1000000;
-	tv->tv_sec--;
-    }
-
-    /* reset RTC to 0 (real time is xbase + RTC) */
-    xbase = *tv;
-    RTCtimerControl |=  TIM_RTCCLEAR;
-    RTCtimerControl &= ~TIM_RTCCLEAR;
-    RTCalarmHigh = RTCalarmLow = ~0UL;
-
-    xtime = *tv;
-    time_state = TIME_BAD;
-    time_maxerror = MAXPHASE;
-    time_esterror = MAXPHASE;
-    write_unlock_irq(&xtime_lock);
-}
-
-static int set_rtc_mmss(unsigned long nowtime)
-{
-    int retval = 0;
-
-    return retval;
-}
-
-/* last time the cmos clock got updated */
-static long last_rtc_update = 0;
-
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-
-int do_write = 1;
-
-static void
-timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-#ifdef POLL_STATUS
-    static unsigned long old_IntStatus1 = 0;
-    static unsigned long old_IntStatus3 = 0;
-    static unsigned long old_IntStatus4 = 0;
-    static unsigned long old_IntStatus5 = 0;
-    static int counter = 0;
-    int i;
-
-    new_spircv = SPIData & 0xff;
-    if ((old_spircv != new_spircv) && (new_spircv != 0xff)) {
-	    printk( "SPIData changed: %x\n", new_spircv );
-    }
-    old_spircv = new_spircv;
-    if (do_write)
-	    SPIData = 0;
-#endif
-
-    if (!user_mode(regs)) {
-	if (prof_buffer && current->pid) {
-	    extern int _stext;
-	    unsigned long pc = regs->cp0_epc;
-
-	    pc -= (unsigned long) &_stext;
-	    pc >>= prof_shift;
-	    /*
-	     * Dont ignore out-of-bounds pc values silently,
-	     * put them into the last histogram slot, so if
-	     * present, they will show up as a sharp peak.
-	     */
-	    if (pc > prof_len - 1)
-		pc = prof_len - 1;
-		atomic_inc((atomic_t *) & prof_buffer[pc]);
-	    }
-    }
-
-    /*
-     * aaaand... action!
-     */
-    do_timer(regs);
-
-    /*
-     * If we have an externally syncronized Linux clock, then update
-     * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-     * called as close as possible to 500 ms before the new second starts.
-     */
-    if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
-	xtime.tv_usec > 500000 - (tick >> 1) &&
-	xtime.tv_usec < 500000 + (tick >> 1))
-    {
-	if (set_rtc_mmss(xtime.tv_sec) == 0)
-	    last_rtc_update = xtime.tv_sec;
-	else
-	    last_rtc_update = xtime.tv_sec - 600;  /* do it again in 60 s */
-    }
-}
-
-static struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0,
- 			 "timer", NULL, NULL};
-
-void (*board_time_init) (struct irqaction * irq);
-
-int __init time_init(void)
-{
-    struct timeval starttime;
-
-    starttime.tv_sec = mktime(2000, 1, 1, 0, 0, 0);
-    starttime.tv_usec = 0;
-    do_settimeofday(&starttime);
-
-    board_time_init(&irq0);
-
-    return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ramdisk/Makefile linux/arch/mips/ramdisk/Makefile
--- linux.orig/arch/mips/ramdisk/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ramdisk/Makefile	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,15 @@
+#
+# Makefile for a ramdisk image
+#
+# 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).
+#
+
+O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32)
+ramdisk.o: ramdisk.gz ld.script
+	echo "O_FORMAT:  " $(O_FORMAT)
+	$(LD) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ ramdisk.gz
+
+include $(TOPDIR)/Rules.make
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/ramdisk/ld.script linux/arch/mips/ramdisk/ld.script
--- linux.orig/arch/mips/ramdisk/ld.script	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/ramdisk/ld.script	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,9 @@
+OUTPUT_ARCH(mips)
+SECTIONS
+{
+  .initrd :
+  {
+       *(.data)
+  }
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/Makefile linux/arch/mips/sgi/kernel/Makefile
--- linux.orig/arch/mips/sgi/kernel/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips/sgi/kernel/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,25 +0,0 @@
-#
-# Makefile for the SGI specific kernel interface routines
-# under Linux.
-#
-# 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).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-O_TARGET := ip22-kern.o
-
-all: ip22-kern.o indyIRQ.o
-
-obj-y	+= indy_mc.o indy_sc.o indy_hpc.o indy_int.o indy_rtc.o system.o \
-	   indyIRQ.o reset.o setup.o time.o
-
-indyIRQ.o: indyIRQ.S
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/indyIRQ.S linux/arch/mips/sgi/kernel/indyIRQ.S
--- linux.orig/arch/mips/sgi/kernel/indyIRQ.S	2000-07-10 05:18:15.000000000 +0000
+++ linux/arch/mips/sgi/kernel/indyIRQ.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,126 +0,0 @@
-/*
- * indyIRQ.S: Interrupt exception dispatch code for FullHouse and
- *            Guiness.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-	/* A lot of complication here is taken away because:
-	 *
-	 * 1) We handle one interrupt and return, sitting in a loop
-	 *    and moving across all the pending IRQ bits in the cause
-	 *    register is _NOT_ the answer, the common case is one
-	 *    pending IRQ so optimize in that direction.
-	 *
-	 * 2) We need not check against bits in the status register
-	 *    IRQ mask, that would make this routine slow as hell.
-	 *
-	 * 3) Linux only thinks in terms of all IRQs on or all IRQs
-	 *    off, nothing in between like BSD spl() brain-damage.
-	 *
-	 * Furthermore, the IRQs on the INDY look basically (barring
-	 * software IRQs which we don't use at all) like:
-	 *
-	 *	MIPS IRQ	Source
-	 *      --------        ------
-	 *             0	Software (ignored)
-	 *             1        Software (ignored)
-	 *             2        Local IRQ level zero
-	 *             3        Local IRQ level one
-	 *             4        8254 Timer zero
-	 *             5        8254 Timer one
-	 *             6        Bus Error
-	 *             7        R4k timer (what we use)
-	 *
-	 * We handle the IRQ according to _our_ priority which is:
-	 *
-	 * Highest ----     R4k Timer
-	 *                  Local IRQ zero
-	 *                  Local IRQ one
-	 *                  Bus Error
-	 *                  8254 Timer zero
-	 * Lowest  ----     8254 Timer one
-	 *
-	 * then we just return, if multiple IRQs are pending then
-	 * we will just take another exception, big deal.
-	 */
-
-	.text
-	.set	noreorder
-	.set	noat
-	.align	5
-	NESTED(indyIRQ, PT_SIZE, sp)
-	SAVE_ALL
-	CLI
-	.set	at
-	mfc0	s0, CP0_CAUSE		# get irq mask
-
-	/* First we check for r4k counter/timer IRQ. */
-	andi	a0, s0, CAUSEF_IP7
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
-
-	/* Wheee, a timer interrupt. */
-	move	a0, sp
-	jal	indy_r4k_timer_interrupt
-	 nop				# delay slot
-
-	j	ret_from_irq
-	 nop				# delay slot
-
-1:
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
-
-	/* Wheee, local level zero interrupt. */
-	jal	indy_local0_irqdispatch
-	 move	a0, sp			# delay slot
-
-	j	ret_from_irq
-	 nop				# delay slot
-
-1:
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
-
-	/* Wheee, local level one interrupt. */
-	move	a0, sp
-	jal	indy_local1_irqdispatch
-	 nop
-
-	j	ret_from_irq
-	 nop
-
-1:
-	beq	a0, zero, 1f
-	 nop
-
-	/* Wheee, an asynchronous bus error... */
-	move	a0, sp
-	jal	indy_buserror_irq
-	 nop
-
-	j	ret_from_irq
-	 nop
-
-1:
-	/* Here by mistake?  This is possible, what can happen
-	 * is that by the time we take the exception the IRQ
-	 * pin goes low, so just leave if this is the case.
-	 */
-	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
-	beq	a0, zero, 1f
-
-	/* Must be one of the 8254 timers... */
-	move	a0, sp
-	jal	indy_8254timer_irq
-	 nop
-1:
-	j	ret_from_irq
-	 nop
-	END(indyIRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/indy_hpc.c linux/arch/mips/sgi/kernel/indy_hpc.c
--- linux.orig/arch/mips/sgi/kernel/indy_hpc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sgi/kernel/indy_hpc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,106 +0,0 @@
-/* $Id: indy_hpc.c,v 1.9 1999/12/04 03:59:00 ralf Exp $
- *
- * indy_hpc.c: Routines for generic manipulation of the HPC controllers.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1998 Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <asm/addrspace.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-#include <asm/sgialib.h>
-#include <asm/bootinfo.h>
-
-/* #define DEBUG_SGIHPC */
-
-struct hpc3_regs *hpc3c0, *hpc3c1;
-struct hpc3_miscregs *hpc3mregs;
-
-/* We need software copies of these because they are write only. */
-unsigned int sgi_hpc_write1, sgi_hpc_write2;
-
-/* Machine specific identifier knobs. */
-int sgi_has_ioc2 = 0;
-int sgi_guiness = 0;
-int sgi_boardid;
-
-void __init sgihpc_init(void)
-{
-	unsigned long sid, crev, brev;
-
-	hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE);
-	hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE);
-	hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE);
-	sid = hpc3mregs->sysid;
-
-	sid &= 0xff;
-	crev = (sid & 0xe0) >> 5;
-	brev = (sid & 0x1e) >> 1;
-
-#ifdef DEBUG_SGIHPC
-	prom_printf("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev);
-	prom_printf("sgihpc_init: ");
-#endif
-
-	/* This test works now thanks to William J. Earl */
-	if ((sid & 1) == 0 ) {
-#ifdef DEBUG_SGIHPC
-		prom_printf("GUINESS ");
-#endif
-		sgi_guiness = 1;
-		mips_machtype = MACH_SGI_INDY;
-	} else {
-#ifdef DEBUG_SGIHPC
-		prom_printf("FULLHOUSE ");
-#endif
-                mips_machtype = MACH_SGI_INDIGO2;
-		sgi_guiness = 0;
-	}
-	sgi_boardid = brev;
-
-#ifdef DEBUG_SGIHPC
-	prom_printf("sgi_boardid<%d> ", sgi_boardid);
-#endif
-
-	if(crev == 1) {
-		if((sid & 1) || (brev >= 2)) {
-#ifdef DEBUG_SGIHPC
-			prom_printf("IOC2 ");
-#endif
-			sgi_has_ioc2 = 1;
-		} else {
-#ifdef DEBUG_SGIHPC
-			prom_printf("IOC1 revision 1 ");
-#endif
-		}
-	} else {
-#ifdef DEBUG_SGIHPC
-		prom_printf("IOC1 revision 0 ");
-#endif
-	}
-#ifdef DEBUG_SGIHPC
-	prom_printf("\n");
-#endif
-
-	sgi_hpc_write1 = (HPC3_WRITE1_PRESET |
-		  HPC3_WRITE1_KMRESET |
-		  HPC3_WRITE1_ERESET |
-		  HPC3_WRITE1_LC0OFF);
-
-	sgi_hpc_write2 = (HPC3_WRITE2_EASEL |
-		  HPC3_WRITE2_NTHRESH |
-		  HPC3_WRITE2_TPSPEED |
-		  HPC3_WRITE2_EPSEL |
-		  HPC3_WRITE2_U0AMODE |
-		  HPC3_WRITE2_U1AMODE);
-
-	if(!sgi_guiness)
-		sgi_hpc_write1 |= HPC3_WRITE1_GRESET;
-	hpc3mregs->write1 = sgi_hpc_write1;
-	hpc3mregs->write2 = sgi_hpc_write2;
-
-	hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/indy_int.c linux/arch/mips/sgi/kernel/indy_int.c
--- linux.orig/arch/mips/sgi/kernel/indy_int.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sgi/kernel/indy_int.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,528 +0,0 @@
-/*
- * indy_int.c: Routines for generic manipulation of the INT[23] ASIC
- *             found on INDY workstations..
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) 
- *                    - Indigo2 changes
- *                    - Interrupt handling fixes
- */
-#include <linux/init.h>
-
-#include <linux/errno.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/sgi/sgi.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-#include <asm/sgialib.h>
-#include <asm/gdb-stub.h>
-
-/*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the apropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
-
-/* #define DEBUG_SGINT */
-
-struct sgi_int2_regs *sgi_i2regs;
-struct sgi_int3_regs *sgi_i3regs;
-struct sgi_ioc_ints *ioc_icontrol;
-struct sgi_ioc_timers *ioc_timers;
-volatile unsigned char *ioc_tclear;
-
-static char lc0msk_to_irqnr[256];
-static char lc1msk_to_irqnr[256];
-static char lc2msk_to_irqnr[256];
-static char lc3msk_to_irqnr[256];
-
-extern asmlinkage void indyIRQ(void);
-
-/* Local IRQ's are layed out logically like this:
- *
- * 0  --> 7   ==   local 0 interrupts
- * 8  --> 15  ==   local 1 interrupts
- * 16 --> 23  ==   vectored level 2 interrupts
- * 24 --> 31  ==   vectored level 3 interrupts (not used)
- */
-static void enable_local0_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	ioc_icontrol->imask0 |= (1 << (irq - SGINT_LOCAL0));
-	restore_flags(flags);
-}
-
-static unsigned int startup_local0_irq(unsigned int irq)
-{
-	enable_local0_irq(irq);
-
-	return 0;		/* Never anything pending  */
-}
-
-static void disable_local0_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	ioc_icontrol->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
-	restore_flags(flags);
-}
-
-#define shutdown_local0_irq	disable_local0_irq
-#define mask_and_ack_local0_irq	disable_local0_irq
-
-static void end_local0_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_local0_irq(irq);
-}
-
-static struct hw_interrupt_type ip22_local0_irq_type = {
-	"IP22 local 0",
-	startup_local0_irq,
-	shutdown_local0_irq,
-	enable_local0_irq,
-	disable_local0_irq,
-	mask_and_ack_local0_irq,
-	end_local0_irq,
-	NULL
-};
-
-static void enable_local1_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	ioc_icontrol->imask1 |= (1 << (irq - SGINT_LOCAL1));
-	restore_flags(flags);
-}
-
-static unsigned int startup_local1_irq(unsigned int irq)
-{
-	enable_local1_irq(irq);
-
-	return 0;		/* Never anything pending  */
-}
-
-void disable_local1_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	ioc_icontrol->imask1 &= ~(1 << (irq- SGINT_LOCAL1));
-	restore_flags(flags);
-}
-
-#define shutdown_local1_irq	disable_local1_irq
-#define mask_and_ack_local1_irq	disable_local1_irq
-
-static void end_local1_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_local1_irq(irq);
-}
-
-static struct hw_interrupt_type ip22_local1_irq_type = {
-	"IP22 local 1",
-	startup_local1_irq,
-	shutdown_local1_irq,
-	enable_local1_irq,
-	disable_local1_irq,
-	mask_and_ack_local1_irq,
-	end_local1_irq,
-	NULL
-};
-
-static void enable_local2_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	enable_local0_irq(7);
-	ioc_icontrol->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
-	restore_flags(flags);
-}
-
-static unsigned int startup_local2_irq(unsigned int irq)
-{
-	enable_local2_irq(irq);
-
-	return 0;		/* Never anything pending  */
-}
-
-void disable_local2_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	ioc_icontrol->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
-	restore_flags(flags);
-}
-
-#define shutdown_local2_irq disable_local2_irq
-#define mask_and_ack_local2_irq	disable_local2_irq
-
-static void end_local2_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_local2_irq(irq);
-}
-
-static struct hw_interrupt_type ip22_local2_irq_type = {
-	"IP22 local 2",
-	startup_local2_irq,
-	shutdown_local2_irq,
-	enable_local2_irq,
-	disable_local2_irq,
-	mask_and_ack_local2_irq,
-	end_local2_irq,
-	NULL
-};
-
-static void enable_local3_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	printk("Yeeee, got passed irq_nr %d at enable_local3_irq\n", irq);
-	panic("INVALID IRQ level!");
-	restore_flags(flags);
-}
-
-static unsigned int startup_local3_irq(unsigned int irq)
-{
-	enable_local3_irq(irq);
-
-	return 0;		/* Never anything pending  */
-}
-
-void disable_local3_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	/*
-	 * This way we'll see if anyone would ever want vectored level 3
-	 * interrupts.  Highly unlikely.
-	 */
-	printk("Yeeee, got passed irq_nr %d at disable_local3_irq\n", irq);
-	panic("INVALID IRQ level!");
-	restore_flags(flags);
-}
-
-#define shutdown_local3_irq disable_local3_irq
-#define mask_and_ack_local3_irq	disable_local3_irq
-
-static void end_local3_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_local3_irq(irq);
-}
-
-static struct hw_interrupt_type ip22_local3_irq_type = {
-	"IP22 local 3",
-	startup_local3_irq,
-	shutdown_local3_irq,
-	enable_local3_irq,
-	disable_local3_irq,
-	mask_and_ack_local3_irq,
-	end_local3_irq,
-	NULL
-};
-
-void enable_gio_irq(unsigned int irq)
-{
-	/* XXX TODO XXX */
-}
-
-static unsigned int startup_gio_irq(unsigned int irq)
-{
-	enable_gio_irq(irq);
-
-	return 0;		/* Never anything pending  */
-}
-
-void disable_gio_irq(unsigned int irq)
-{
-	/* XXX TODO XXX */
-}
-
-#define shutdown_gio_irq	disable_gio_irq
-#define mask_and_ack_gio_irq	disable_gio_irq
-
-static void end_gio_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_gio_irq(irq);
-}
-
-static struct hw_interrupt_type ip22_gio_irq_type = {
-	"IP22 GIO",
-	startup_gio_irq,
-	shutdown_gio_irq,
-	enable_gio_irq,
-	disable_gio_irq,
-	mask_and_ack_gio_irq,
-	end_gio_irq,
-	NULL
-};
-
-void enable_hpcdma_irq(unsigned int irq)
-{
-	/* XXX TODO XXX */
-}
-
-static unsigned int startup_hpcdma_irq(unsigned int irq)
-{
-	enable_hpcdma_irq(irq);
-
-	return 0;		/* Never anything pending  */
-}
-
-void disable_hpcdma_irq(unsigned int irq)
-{
-	/* XXX TODO XXX */
-}
-
-#define shutdown_hpcdma_irq	disable_hpcdma_irq
-#define mask_and_ack_hpcdma_irq	disable_hpcdma_irq
-
-static void end_hpcdma_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_hpcdma_irq(irq);
-}
-
-static struct hw_interrupt_type ip22_hpcdma_irq_type = {
-	"IP22 HPC DMA",
-	startup_hpcdma_irq,
-	shutdown_hpcdma_irq,
-	enable_hpcdma_irq,
-	disable_hpcdma_irq,
-	mask_and_ack_hpcdma_irq,
-	end_hpcdma_irq,
-	NULL
-};
-
-static struct irqaction r4ktimer_action = {
-	NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
-};
-
-static struct irqaction indy_berr_action = {
-	NULL, 0, 0, "IP22 Bus Error", NULL, NULL,
-};
-
-static struct irqaction *irq_action[16] = {
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, &indy_berr_action, &r4ktimer_action,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL
-};
-
-void indy_local0_irqdispatch(struct pt_regs *regs)
-{
-	unsigned char mask = ioc_icontrol->istat0;
-	unsigned char mask2 = 0;
-	int irq;
-
-	mask &= ioc_icontrol->imask0;
-	if (mask & ISTAT0_LIO2) {
-		mask2 = ioc_icontrol->vmeistat;
-		mask2 &= ioc_icontrol->cmeimask0;
-		irq = lc2msk_to_irqnr[mask2];
-	} else {
-		irq = lc0msk_to_irqnr[mask];
-	}
-
-	/* if irq == 0, then the interrupt has already been cleared */
-	if (irq == 0)
-		goto end;
-
-	do_IRQ(irq, regs);
-	goto end;
-
-no_handler:
-	printk("No handler for local0 irq: %i\n", irq);
-
-end:	
-	return;
-}
-
-void indy_local1_irqdispatch(struct pt_regs *regs)
-{
-	unsigned char mask = ioc_icontrol->istat1;
-	unsigned char mask2 = 0;
-	int irq;
-
-	mask &= ioc_icontrol->imask1;
-	if (mask & ISTAT1_LIO3) {
-		printk("WHee: Got an LIO3 irq, winging it...\n");
-		mask2 = ioc_icontrol->vmeistat;
-		mask2 &= ioc_icontrol->cmeimask1;
-		irq = lc3msk_to_irqnr[ioc_icontrol->vmeistat];
-	} else {
-		irq = lc1msk_to_irqnr[mask];
-	}
-
-	/* if irq == 0, then the interrupt has already been cleared */
-	/* not sure if it is needed here, but it is needed for local0 */
-	if (irq == 0)
-		goto end;
-
-	do_IRQ(irq, regs);
-	goto end;
-	
-no_handler:
-	printk("No handler for local1 irq: %i\n", irq);
-
-end:	
-	return;	
-}
-
-void indy_buserror_irq(struct pt_regs *regs)
-{
-	int cpu = smp_processor_id();
-	int irq = 6;
-
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
-	printk("Got a bus error IRQ, shouldn't happen yet\n");
-	show_regs(regs);
-	printk("Spinning...\n");
-	while(1);
-	irq_exit(cpu, irq);
-}
-
-void __init init_IRQ(void)
-{
-	int i;
-
-	sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE);
-	sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE);
-
-	/* Init local mask --> irq tables. */
-	for (i = 0; i < 256; i++) {
-		if (i & 0x80) {
-			lc0msk_to_irqnr[i] = 7;
-			lc1msk_to_irqnr[i] = 15;
-			lc2msk_to_irqnr[i] = 23;
-			lc3msk_to_irqnr[i] = 31;
-		} else if (i & 0x40) {
-			lc0msk_to_irqnr[i] = 6;
-			lc1msk_to_irqnr[i] = 14;
-			lc2msk_to_irqnr[i] = 22;
-			lc3msk_to_irqnr[i] = 30;
-		} else if (i & 0x20) {
-			lc0msk_to_irqnr[i] = 5;
-			lc1msk_to_irqnr[i] = 13;
-			lc2msk_to_irqnr[i] = 21;
-			lc3msk_to_irqnr[i] = 29;
-		} else if (i & 0x10) {
-			lc0msk_to_irqnr[i] = 4;
-			lc1msk_to_irqnr[i] = 12;
-			lc2msk_to_irqnr[i] = 20;
-			lc3msk_to_irqnr[i] = 28;
-		} else if (i & 0x08) {
-			lc0msk_to_irqnr[i] = 3;
-			lc1msk_to_irqnr[i] = 11;
-			lc2msk_to_irqnr[i] = 19;
-			lc3msk_to_irqnr[i] = 27;
-		} else if (i & 0x04) {
-			lc0msk_to_irqnr[i] = 2;
-			lc1msk_to_irqnr[i] = 10;
-			lc2msk_to_irqnr[i] = 18;
-			lc3msk_to_irqnr[i] = 26;
-		} else if (i & 0x02) {
-			lc0msk_to_irqnr[i] = 1;
-			lc1msk_to_irqnr[i] = 9;
-			lc2msk_to_irqnr[i] = 17;
-			lc3msk_to_irqnr[i] = 25;
-		} else if (i & 0x01) {
-			lc0msk_to_irqnr[i] = 0;
-			lc1msk_to_irqnr[i] = 8;
-			lc2msk_to_irqnr[i] = 16;
-			lc3msk_to_irqnr[i] = 24;
-		} else {
-			lc0msk_to_irqnr[i] = 0;
-			lc1msk_to_irqnr[i] = 0;
-			lc2msk_to_irqnr[i] = 0;
-			lc3msk_to_irqnr[i] = 0;
-		}
-	}
-
-	/* Indy uses an INT3, Indigo2 uses an INT2 */
-	if (sgi_guiness) {
-		ioc_icontrol = &sgi_i3regs->ints;
-		ioc_timers = &sgi_i3regs->timers;
-		ioc_tclear = &sgi_i3regs->tclear;
-	} else {
-		ioc_icontrol = &sgi_i2regs->ints;
-		ioc_timers = &sgi_i2regs->timers;
-		ioc_tclear = &sgi_i2regs->tclear;
-	}
-
-	/* Mask out all interrupts. */
-	ioc_icontrol->imask0 = 0;
-	ioc_icontrol->imask1 = 0;
-	ioc_icontrol->cmeimask0 = 0;
-	ioc_icontrol->cmeimask1 = 0;
-
-	set_except_vector(0, indyIRQ);
-
-	init_generic_irq();
-
-	for (i = SGINT_LOCAL0; i < SGINT_END; i++) {
-		hw_irq_controller *handler;
-
-		if (i < SGINT_LOCAL1)
-			handler		= &ip22_local0_irq_type;
-		else if (i < SGINT_LOCAL2)
-			handler		= &ip22_local1_irq_type;
-		else if (i < SGINT_LOCAL3)
-			handler		= &ip22_local2_irq_type;
-		else if (i < SGINT_GIO)
-			handler		= &ip22_local3_irq_type;
-		else if (i < SGINT_HPCDMA)
-			handler		= &ip22_gio_irq_type;
-		else if (i < SGINT_END)
-			handler		= &ip22_hpcdma_irq_type;
-
-		irq_desc[i].status	= IRQ_DISABLED;
-		irq_desc[i].action	= 0;
-		irq_desc[i].depth	= 1;
-		irq_desc[i].handler	= handler;
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/indy_mc.c linux/arch/mips/sgi/kernel/indy_mc.c
--- linux.orig/arch/mips/sgi/kernel/indy_mc.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/sgi/kernel/indy_mc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,159 +0,0 @@
-/*
- * indy_mc.c: Routines for manipulating the INDY memory controller.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
- *
- * $Id: indy_mc.c,v 1.7 1999/12/04 03:59:00 ralf Exp $
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/addrspace.h>
-#include <asm/ptrace.h>
-#include <asm/sgi/sgimc.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgialib.h>
-
-/* #define DEBUG_SGIMC */
-
-struct sgimc_misc_ctrl *mcmisc_regs;
-u32 *rpsscounter;
-struct sgimc_dma_ctrl *dmactrlregs;
-
-static inline char *mconfig_string(unsigned long val)
-{
-	switch(val & SGIMC_MCONFIG_RMASK) {
-	case SGIMC_MCONFIG_FOURMB:
-		return "4MB";
-
-	case SGIMC_MCONFIG_EIGHTMB:
-		return "8MB";
-
-	case SGIMC_MCONFIG_SXTEENMB:
-		return "16MB";
-
-	case SGIMC_MCONFIG_TTWOMB:
-		return "32MB";
-
-	case SGIMC_MCONFIG_SFOURMB:
-		return "64MB";
-
-	case SGIMC_MCONFIG_OTEIGHTMB:
-		return "128MB";
-
-	default:
-		return "wheee, unknown";
-	};
-}
-
-void __init sgimc_init(void)
-{
-	unsigned long tmpreg;
-
-	mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
-	rpsscounter = (unsigned int *) (KSEG1 + 0x1fa01004);
-	dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000);
-
-	printk("MC: SGI memory controller Revision %d\n",
-	       (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV);
-
-#if 0 /* XXX Until I figure out what this bit really indicates XXX */
-	/* XXX Is this systemid bit reliable? */
-	if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) {
-		EISA_bus = 1;
-		printk("with EISA\n");
-	} else {
-		EISA_bus = 0;
-		printk("no EISA\n");
-	}
-#endif
-
-#ifdef DEBUG_SGIMC
-	prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n",
-		    mconfig_string(mcmisc_regs->mconfig0),
-		    mconfig_string(mcmisc_regs->mconfig1));
-
-	prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n",
-		    mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1);
-	prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n",
-		    mcmisc_regs->divider, mcmisc_regs->gioparm);
-#endif
-
-	/* Place the MC into a known state.  This must be done before
-	 * interrupts are first enabled etc.
-	 */
-
-	/* Step 1: The CPU/GIO error status registers will not latch
-	 *         up a new error status until the register has been
-	 *         cleared by the cpu.  These status registers are
-	 *         cleared by writing any value to them.
-	 */
-	mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
-
-	/* Step 2: Enable all parity checking in cpu control register
-	 *         zero.
-	 */
-	tmpreg = mcmisc_regs->cpuctrl0;
-	tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
-		   SGIMC_CCTRL0_R4KNOCHKPARR);
-	mcmisc_regs->cpuctrl0 = tmpreg;
-
-	/* Step 3: Setup the MC write buffer depth, this is controlled
-	 *         in cpu control register 1 in the lower 4 bits.
-	 */
-	tmpreg = mcmisc_regs->cpuctrl1;
-	tmpreg &= ~0xf;
-	tmpreg |= 0xd;
-	mcmisc_regs->cpuctrl1 = tmpreg;
-
-	/* Step 4: Initialize the RPSS divider register to run as fast
-	 *         as it can correctly operate.  The register is laid
-	 *         out as follows:
-	 *
-	 *         ----------------------------------------
-	 *         |  RESERVED  |   INCREMENT   | DIVIDER |
-	 *         ----------------------------------------
-	 *          31        16 15            8 7       0
-	 *
-	 *         DIVIDER determines how often a 'tick' happens,
-	 *         INCREMENT determines by how the RPSS increment
-	 *         registers value increases at each 'tick'. Thus,
-	 *         for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
-	 */
-	mcmisc_regs->divider = 0x101;
-
-	/* Step 5: Initialize GIO64 arbitrator configuration register.
-	 *
-	 * NOTE: If you dork with startup code the HPC init code in
-	 *       sgihpc_init() must run before us because of how we
-	 *       need to know Guiness vs. FullHouse and the board
-	 *       revision on this machine.  You have been warned.
-	 */
-
-	/* First the basic invariants across all gio64 implementations. */
-	tmpreg = SGIMC_GIOPARM_HPC64;    /* All 1st HPC's interface at 64bits. */
-	tmpreg |= SGIMC_GIOPARM_ONEBUS;  /* Only one physical GIO bus exists. */
-
-	if(sgi_guiness) {
-		/* Guiness specific settings. */
-		tmpreg |= SGIMC_GIOPARM_EISA64;     /* MC talks to EISA at 64bits */
-		tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */
-	} else {
-		/* Fullhouse specific settings. */
-		if(sgi_boardid < 2) {
-			tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */
-			tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */
-			tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */
-			tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */
-		} else {
-			tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */
-			tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */
-			tmpreg |= SGIMC_GIOPARM_PLINEEXP1;
-			tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */
-			/* someone forgot this poor little guy... */
-			tmpreg |= SGIMC_GIOPARM_GFX64; 	/* GFX at 64 bits */
-		}
-	}
-	mcmisc_regs->gioparm = tmpreg; /* poof */
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/indy_rtc.c linux/arch/mips/sgi/kernel/indy_rtc.c
--- linux.orig/arch/mips/sgi/kernel/indy_rtc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sgi/kernel/indy_rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * RTC routines for Indy style attached Dallas chip.
- *
- * Copyright (C) 1998, 2001 by Ralf Baechle
- */
-#include <linux/mc146818rtc.h>
-#include <asm/sgi/sgihpc.h>
-
-static unsigned char indy_rtc_read_data(unsigned long addr)
-{
-	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
-
-	return rtcregs[addr];
-}
-
-static void indy_rtc_write_data(unsigned char data, unsigned long addr)
-{
-	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
-
-	rtcregs[addr] = data;
-}
-
-static int indy_rtc_bcd_mode(void)
-{
-	return 0;
-}
-
-struct rtc_ops indy_rtc_ops = {
-	&indy_rtc_read_data,
-	&indy_rtc_write_data,
-	&indy_rtc_bcd_mode
-};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/indy_sc.c linux/arch/mips/sgi/kernel/indy_sc.c
--- linux.orig/arch/mips/sgi/kernel/indy_sc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sgi/kernel/indy_sc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,226 +0,0 @@
-/*
- * indy_sc.c: Indy cache management functions.
- *
- * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
- * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/bcache.h>
-#include <asm/sgi/sgi.h>
-#include <asm/sgi/sgimc.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/bootinfo.h>
-#include <asm/sgialib.h>
-#include <asm/mmu_context.h>
-
-/* Secondary cache size in bytes, if present.  */
-static unsigned long scache_size;
-
-#undef DEBUG_CACHE
-
-#define SC_SIZE 0x00080000
-#define SC_LINE 32
-#define CI_MASK (SC_SIZE - SC_LINE)
-#define SC_INDEX(n) ((n) & CI_MASK)
-
-static inline void indy_sc_wipe(unsigned long first, unsigned long last)
-{
-	unsigned long tmp;
-
-	__asm__ __volatile__(
-	".set\tnoreorder\t\t\t# indy_sc_wipe\n\t"
-	".set\tmips3\n\t"
-	".set\tnoat\n\t"
-	"mfc0\t%2, $12\n\t"
-	"li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
-	"mtc0\t$1, $12\n\t"
-
-	"dli\t$1, 0x9000000080000000\n\t"
-	"or\t%0, $1\t\t\t# first line to flush\n\t"
-	"or\t%1, $1\t\t\t# last line to flush\n\t"
-	".set\tat\n\t"
-
-	"1:\tsw\t$0, 0(%0)\n\t"
-	"bne\t%0, %1, 1b\n\t"
-	"daddu\t%0, 32\n\t"
-
-	"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
-	"nop; nop; nop; nop;\n\t"
-	".set\tmips0\n\t"
-	".set\treorder"
-	: "=r" (first), "=r" (last), "=&r" (tmp)
-	: "0" (first), "1" (last)
-	: "$1");
-}
-
-static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size)
-{
-	unsigned long first_line, last_line;
-	unsigned int flags;
-
-#ifdef DEBUG_CACHE
-	printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
-#endif
-
-	if (!size)
-		return;
-
-	/* Which lines to flush?  */
-	first_line = SC_INDEX(addr);
-	last_line = SC_INDEX(addr + size - 1);
-
-	__save_and_cli(flags);
-	if (first_line <= last_line) {
-		indy_sc_wipe(first_line, last_line);
-		goto out;
-	}
-
-	indy_sc_wipe(first_line, SC_SIZE - SC_LINE);
-	indy_sc_wipe(0, last_line);
-out:
-	__restore_flags(flags);
-}
-
-static void indy_sc_enable(void)
-{
-	unsigned long addr, tmp1, tmp2;
-
-	/* This is really cool... */
-#ifdef DEBUG_CACHE
-	printk("Enabling R4600 SCACHE\n");
-#endif
-	__asm__ __volatile__(
-	".set\tpush\n\t"
-	".set\tnoreorder\n\t"
-	".set\tmips3\n\t"
-	"mfc0\t%2, $12\n\t"
-	"nop; nop; nop; nop;\n\t"
-	"li\t%1, 0x80\n\t"
-	"mtc0\t%1, $12\n\t"
-	"nop; nop; nop; nop;\n\t"
-	"li\t%0, 0x1\n\t"
-	"dsll\t%0, 31\n\t"
-	"lui\t%1, 0x9000\n\t"
-	"dsll32\t%1, 0\n\t"
-	"or\t%0, %1, %0\n\t"
-	"sb\t$0, 0(%0)\n\t"
-	"mtc0\t$0, $12\n\t"
-	"nop; nop; nop; nop;\n\t"
-	"mtc0\t%2, $12\n\t"
-	"nop; nop; nop; nop;\n\t"
-	".set\tpop"
-	: "=r" (tmp1), "=r" (tmp2), "=r" (addr));
-}
-
-static void indy_sc_disable(void)
-{
-	unsigned long tmp1, tmp2, tmp3;
-
-#ifdef DEBUG_CACHE
-	printk("Disabling R4600 SCACHE\n");
-#endif
-	__asm__ __volatile__(
-	".set\tpush\n\t"
-	".set\tnoreorder\n\t"
-	".set\tmips3\n\t"
-	"li\t%0, 0x1\n\t"
-	"dsll\t%0, 31\n\t"
-	"lui\t%1, 0x9000\n\t"
-	"dsll32\t%1, 0\n\t"
-	"or\t%0, %1, %0\n\t"
-	"mfc0\t%2, $12\n\t"
-	"nop; nop; nop; nop\n\t"
-	"li\t%1, 0x80\n\t"
-	"mtc0\t%1, $12\n\t"
-	"nop; nop; nop; nop\n\t"
-	"sh\t$0, 0(%0)\n\t"
-	"mtc0\t$0, $12\n\t"
-	"nop; nop; nop; nop\n\t"
-	"mtc0\t%2, $12\n\t"
-	"nop; nop; nop; nop\n\t"
-	".set\tpop"
-	: "=r" (tmp1), "=r" (tmp2), "=r" (tmp3));
-}
-
-static inline int __init indy_sc_probe(void)
-{
-	volatile unsigned int *cpu_control;
-	unsigned short cmd = 0xc220;
-	unsigned long data = 0;
-	int i, n;
-
-#ifdef __MIPSEB__
-	cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00034);
-#else
-	cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00030);
-#endif
-#define DEASSERT(bit) (*(cpu_control) &= (~(bit)))
-#define ASSERT(bit) (*(cpu_control) |= (bit))
-#define DELAY  for(n = 0; n < 100000; n++) __asm__ __volatile__("")
-	DEASSERT(SGIMC_EEPROM_PRE);
-	DEASSERT(SGIMC_EEPROM_SDATAO);
-	DEASSERT(SGIMC_EEPROM_SECLOCK);
-	DEASSERT(SGIMC_EEPROM_PRE);
-	DELAY;
-	ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK);
-	for(i = 0; i < 11; i++) {
-		if(cmd & (1<<15))
-			ASSERT(SGIMC_EEPROM_SDATAO);
-		else
-			DEASSERT(SGIMC_EEPROM_SDATAO);
-		DEASSERT(SGIMC_EEPROM_SECLOCK);
-		ASSERT(SGIMC_EEPROM_SECLOCK);
-		cmd <<= 1;
-	}
-	DEASSERT(SGIMC_EEPROM_SDATAO);
-	for(i = 0; i < (sizeof(unsigned short) * 8); i++) {
-		unsigned int tmp;
-
-		DEASSERT(SGIMC_EEPROM_SECLOCK);
-		DELAY;
-		ASSERT(SGIMC_EEPROM_SECLOCK);
-		DELAY;
-		data <<= 1;
-		tmp = *cpu_control;
-		if(tmp & SGIMC_EEPROM_SDATAI)
-			data |= 1;
-	}
-	DEASSERT(SGIMC_EEPROM_SECLOCK);
-	DEASSERT(SGIMC_EEPROM_CSEL);
-	ASSERT(SGIMC_EEPROM_PRE);
-	ASSERT(SGIMC_EEPROM_SECLOCK);
-
-	data <<= PAGE_SHIFT;
-	if (data == 0)
-		return 0;
-
-	scache_size = data;
-
-	printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n",
-	       scache_size >> 10);
-
-	return 1;
-}
-
-/* XXX Check with wje if the Indy caches can differenciate between
-   writeback + invalidate and just invalidate.  */
-struct bcache_ops indy_sc_ops = {
-	indy_sc_enable,
-	indy_sc_disable,
-	indy_sc_wback_invalidate,
-	indy_sc_wback_invalidate
-};
-
-void __init indy_sc_init(void)
-{
-	if (indy_sc_probe()) {
-		indy_sc_enable();
-		bcops = &indy_sc_ops;
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/reset.c linux/arch/mips/sgi/kernel/reset.c
--- linux.orig/arch/mips/sgi/kernel/reset.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sgi/kernel/reset.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,241 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1997, 1998, 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/notifier.h>
-#include <linux/timer.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/reboot.h>
-#include <asm/sgialib.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-
-/*
- * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds.
- * I'm not shure if this feature is a good idea, for now it's here just to
- * make the power button make behave just like under IRIX.
- */
-#define POWERDOWN_TIMEOUT	120
-
-/*
- * Blink frequency during reboot grace period and when paniced.
- */
-#define POWERDOWN_FREQ		(HZ / 4)
-#define PANIC_FREQ		(HZ / 8)
-
-static unsigned char sgi_volume;
-
-static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer;
-static int shuting_down, has_paniced;
-
-static void sgi_machine_restart(char *command) __attribute__((noreturn));
-static void sgi_machine_halt(void) __attribute__((noreturn));
-static void sgi_machine_power_off(void) __attribute__((noreturn));
-
-/* XXX How to pass the reboot command to the firmware??? */
-static void sgi_machine_restart(char *command)
-{
-	if (shuting_down)
-		sgi_machine_power_off();
-	prom_reboot();
-}
-
-static void sgi_machine_halt(void)
-{
-	if (shuting_down)
-		sgi_machine_power_off();
-	ArcEnterInteractiveMode();
-}
-
-static void sgi_machine_power_off(void)
-{
-	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
-
-	cli();
-
-	clock->cmd |= 0x08;	/* Disable watchdog */
-	clock->whsec = 0;
-	clock->wsec = 0;
-
-	while(1) {
-		hpc3mregs->panel=0xfe;
-		/* Good bye cruel world ...  */
-
-		/* If we're still running, we probably got sent an alarm
-		   interrupt.  Read the flag to clear it.  */
-		clock->halarm;
-	}
-}
-
-static void power_timeout(unsigned long data)
-{
-	sgi_machine_power_off();
-}
-
-static void blink_timeout(unsigned long data)
-{
-	/* XXX fix this for fullhouse  */
-	sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF);
-	hpc3mregs->write1 = sgi_hpc_write1;
-
-	mod_timer(&blink_timer, jiffies+data);
-}
-
-static void debounce(unsigned long data)
-{
-	del_timer(&debounce_timer);
-	if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent.  */
-		debounce_timer.expires = jiffies + 5; /* 0.05s  */
-		add_timer(&debounce_timer);
-
-		hpc3mregs->panel = 0xf3;
-
-		return;
-	}
-
-	if (has_paniced)
-		prom_reboot();
-
-	enable_irq(SGI_PANEL_IRQ);
-}
-
-static inline void power_button(void)
-{
-	if (has_paniced)
-		return;
-
-	if (shuting_down || kill_proc(1, SIGINT, 1)) {
-		/* No init process or button pressed twice.  */
-		sgi_machine_power_off();
-	}
-
-	shuting_down = 1;
-	blink_timer.data = POWERDOWN_FREQ;
-	blink_timeout(POWERDOWN_FREQ);
-
-	init_timer(&power_timer);
-	power_timer.function = power_timeout;
-	power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
-	add_timer(&power_timer);
-}
-
-void inline sgi_volume_set(unsigned char volume)
-{
-	sgi_volume = volume;
-
-	hpc3c0->pbus_extregs[2][0] = sgi_volume;
-	hpc3c0->pbus_extregs[2][1] = sgi_volume;
-}
-
-void inline sgi_volume_get(unsigned char *volume)
-{
-	*volume = sgi_volume;
-}
-
-static inline void volume_up_button(unsigned long data)
-{
-	del_timer(&volume_timer);
-
-	if (sgi_volume < 0xff)
-		sgi_volume++;
-
-	hpc3c0->pbus_extregs[2][0] = sgi_volume;
-	hpc3c0->pbus_extregs[2][1] = sgi_volume;
-
-	if (ioc_icontrol->istat1 & 2) {
-		volume_timer.expires = jiffies + 1;
-		add_timer(&volume_timer);
-	}
-
-}
-
-static inline void volume_down_button(unsigned long data)
-{
-	del_timer(&volume_timer);
-
-	if (sgi_volume > 0)
-		sgi_volume--;
-
-	hpc3c0->pbus_extregs[2][0] = sgi_volume;
-	hpc3c0->pbus_extregs[2][1] = sgi_volume;
-
-	if (ioc_icontrol->istat1 & 2) {
-		volume_timer.expires = jiffies + 1;
-		add_timer(&volume_timer);
-	}
-}
-
-static void panel_int(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned int buttons;
-
-	buttons = hpc3mregs->panel;
-	hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */
-
-	if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */
-		disable_irq(SGI_PANEL_IRQ);
-		init_timer(&debounce_timer);
-		debounce_timer.function = debounce;
-		debounce_timer.expires = jiffies + 5;
-		add_timer(&debounce_timer);
-	}
-
-	if (!(buttons & 2))		/* Power button was pressed */
-		power_button();
-	if (!(buttons & 0x40)) {	/* Volume up button was pressed */
-		init_timer(&volume_timer);
-		volume_timer.function = volume_up_button;
-		volume_timer.expires = jiffies + 1;
-		add_timer(&volume_timer);
-	}
-	if (!(buttons & 0x10)) {	/* Volume down button was pressed */
-		init_timer(&volume_timer);
-		volume_timer.function = volume_down_button;
-		volume_timer.expires = jiffies + 1;
-		add_timer(&volume_timer);
-	}
-}
-
-static int panic_event(struct notifier_block *this, unsigned long event,
-                      void *ptr)
-{
-	if (has_paniced)
-		return NOTIFY_DONE;
-	has_paniced = 1;
-
-	blink_timer.data = PANIC_FREQ;
-	blink_timeout(PANIC_FREQ);
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block panic_block = {
-	panic_event,
-	NULL,
-	0
-};
-
-void indy_reboot_setup(void)
-{
-	static int setup_done;
-
-	if (setup_done)
-		return;
-	setup_done = 1;
-
-	_machine_restart = sgi_machine_restart;
-	_machine_halt = sgi_machine_halt;
-	_machine_power_off = sgi_machine_power_off;
-
-	request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
-	init_timer(&blink_timer);
-	blink_timer.function = blink_timeout;
-	notifier_chain_register(&panic_notifier_list, &panic_block);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/setup.c linux/arch/mips/sgi/kernel/setup.c
--- linux.orig/arch/mips/sgi/kernel/setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sgi/kernel/setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,308 +0,0 @@
-/*
- * setup.c: SGI specific setup, including init of the feature struct.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kbd_ll.h>
-#include <linux/kernel.h>
-#include <linux/kdev_t.h>
-#include <linux/types.h>
-#include <linux/console.h>
-#include <linux/sched.h>
-#include <linux/mc146818rtc.h>
-#include <linux/pc_keyb.h>
-
-#include <asm/addrspace.h>
-#include <asm/bcache.h>
-#include <asm/keyboard.h>
-#include <asm/irq.h>
-#include <asm/reboot.h>
-#include <asm/sgialib.h>
-#include <asm/sgi/sgimc.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-#include <asm/time.h>
-#include <asm/gdb-stub.h>
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void rs_kgdb_hook(int);
-extern void breakpoint(void);
-static int remote_debug = 0;
-#endif
-
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_ARC_CONSOLE)
-extern void console_setup(char *);
-#endif
-
-extern unsigned long r4k_interval; /* Cycle counter ticks per 1/HZ seconds */
-
-extern struct rtc_ops indy_rtc_ops;
-void indy_reboot_setup(void);
-void sgi_volume_set(unsigned char);
-
-#define sgi_kh ((struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64))
-
-#define KBD_STAT_IBF		0x02	/* Keyboard input buffer full */
-
-static void sgi_request_region(void)
-{
-	/* No I/O ports are being used on the Indy.  */
-}
-
-static int sgi_request_irq(void (*handler)(int, void *, struct pt_regs *))
-{
-	/* Dirty hack, this get's called as a callback from the keyboard
-	   driver.  We piggyback the initialization of the front panel
-	   button handling on it even though they're technically not
-	   related with the keyboard driver in any way.  Doing it from
-	   indy_setup wouldn't work since kmalloc isn't initialized yet.  */
-	indy_reboot_setup();
-
-	return request_irq(SGI_KEYBOARD_IRQ, handler, 0, "keyboard", NULL);
-}
-
-static int sgi_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
-{
-	/* Nothing to do, interrupt is shared with the keyboard hw  */
-	return 0;
-}
-
-static void sgi_aux_free_irq(void)
-{
-	/* Nothing to do, interrupt is shared with the keyboard hw  */
-}
-
-static unsigned char sgi_read_input(void)
-{
-	return sgi_kh->data;
-}
-
-static void sgi_write_output(unsigned char val)
-{
-	int status;
-
-	do {
-		status = sgi_kh->command;
-	} while (status & KBD_STAT_IBF);
-	sgi_kh->data = val;
-}
-
-static void sgi_write_command(unsigned char val)
-{
-	int status;
-
-	do {
-		status = sgi_kh->command;
-	} while (status & KBD_STAT_IBF);
-	sgi_kh->command = val;
-}
-
-static unsigned char sgi_read_status(void)
-{
-	return sgi_kh->command;
-}
-
-struct kbd_ops sgi_kbd_ops = {
-	sgi_request_region,
-	sgi_request_irq,
-
-	sgi_aux_request_irq,
-	sgi_aux_free_irq,
-
-	sgi_read_input,
-	sgi_write_output,
-	sgi_write_command,
-	sgi_read_status
-};
-
-static unsigned long dosample(volatile unsigned char *tcwp,
-                              volatile unsigned char *tc2p)
-{
-        unsigned long ct0, ct1;
-        unsigned char msb, lsb;
-
-        /* Start the counter. */
-        *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN);
-        *tc2p = (SGINT_TCSAMP_COUNTER & 0xff);
-        *tc2p = (SGINT_TCSAMP_COUNTER >> 8);
-
-        /* Get initial counter invariant */
-        ct0 = read_32bit_cp0_register(CP0_COUNT);
-
-        /* Latch and spin until top byte of counter2 is zero */
-        do {
-                *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT);
-                lsb = *tc2p;
-                msb = *tc2p;
-                ct1 = read_32bit_cp0_register(CP0_COUNT);
-        } while(msb);
-
-	/* Stop the counter. */
-	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST);
-
-	/*
-	 * Return the difference, this is how far the r4k counter increments
-	 * for every 1/HZ seconds. We round off the nearest 1 MHz of master
-	 * clock (= 1000000 / 100 / 2 = 5000 count).
-	 */
-
-	return ((ct1 - ct0) / 5000) * 5000;
-}
-
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-
-void sgi_time_init (struct irqaction *irq) {
-	/* Here we need to calibrate the cycle counter to at least be close.
-	 * We don't need to actually register the irq handler because that's
-	 * all done in indyIRQ.S.
-	 */
-        struct sgi_ioc_timers *p;
-        volatile unsigned char *tcwp, *tc2p;
-	unsigned long r4k_ticks[3];
-	unsigned long r4k_next;
-
-        /* Figure out the r4k offset, the algorithm is very simple
-         * and works in _all_ cases as long as the 8254 counter
-         * register itself works ok (as an interrupt driving timer
-         * it does not because of bug, this is why we are using
-         * the onchip r4k counter/compare register to serve this
-         * purpose, but for r4k_offset calculation it will work
-         * ok for us).  There are other very complicated ways
-         * of performing this calculation but this one works just
-         * fine so I am not going to futz around. ;-)
-         */
-        p = ioc_timers;
-        tcwp = &p->tcword;
-        tc2p = &p->tcnt2;
-
-        printk("Calibrating system timer... ");
-        dosample(tcwp, tc2p);                   /* Prime cache. */
-        dosample(tcwp, tc2p);                   /* Prime cache. */
-	/* Zero is NOT an option. */
-	do {
-		r4k_ticks[0] = dosample (tcwp, tc2p);
-	} while (!r4k_ticks[0]);
-	do {
-		r4k_ticks[1] = dosample (tcwp, tc2p);
-	} while (!r4k_ticks[1]);
-
-	if (r4k_ticks[0] != r4k_ticks[1]) {
-		printk ("warning: timer counts differ, retrying...");
-		r4k_ticks[2] = dosample (tcwp, tc2p);
-		if (r4k_ticks[2] == r4k_ticks[0] 
-		    || r4k_ticks[2] == r4k_ticks[1])
-			r4k_interval = r4k_ticks[2];
-		else {
-			printk ("disagreement, using average...");
-			r4k_interval = (r4k_ticks[0] + r4k_ticks[1] 
-					+ r4k_ticks[2]) / 3;
-		}
-	} else
-		r4k_interval = r4k_ticks[0];
-
-        printk("%d [%d.%02d MHz CPU]\n", (int) r4k_interval, 
-		(int) (r4k_interval / 5000), (int) (r4k_interval % 5000) / 50);
-
-	/* Set ourselves up for future interrupts */
-        r4k_next = (read_32bit_cp0_register(CP0_COUNT) + r4k_interval);
-        write_32bit_cp0_register(CP0_COMPARE, r4k_next);
-        change_cp0_status(ST0_IM, ALLINTS);
-	sti ();
-}
-
-void __init sgi_setup(void)
-{
-#ifdef CONFIG_SERIAL_CONSOLE
-	char *ctype;
-#endif
-#ifdef CONFIG_REMOTE_DEBUG
-	char *kgdb_ttyd;
-#endif
-
-	board_time_init = sgi_time_init;
-
-	/* Init the INDY HPC I/O controller.  Need to call this before
-	 * fucking with the memory controller because it needs to know the
-	 * boardID and whether this is a Guiness or a FullHouse machine.
-	 */
-	sgihpc_init();
-
-	/* Init INDY memory controller. */
-	sgimc_init();
-
-	/* Now enable boardcaches, if any. */
-	indy_sc_init();
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	/* ARCS console environment variable is set to "g?" for
-	 * graphics console, it is set to "d" for the first serial
-	 * line and "d2" for the second serial line.
-	 */
-	ctype = ArcGetEnvironmentVariable("console");
-	if(*ctype == 'd') {
-		if(*(ctype+1)=='2')
-			console_setup ("ttyS1");
-		else
-			console_setup ("ttyS0");
-	}
-#endif
-
-#ifdef CONFIG_REMOTE_DEBUG
-	kgdb_ttyd = prom_getcmdline();
-	if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) {
-		int line;
-		kgdb_ttyd += strlen("kgdb=ttyd");
-		if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2')
-			printk("KGDB: Uknown serial line /dev/ttyd%c, "
-			       "falling back to /dev/ttyd1\n", *kgdb_ttyd);
-		line = *kgdb_ttyd == '2' ? 0 : 1;
-		printk("KGDB: Using serial line /dev/ttyd%d for session\n",
-		       line ? 1 : 2);
-		rs_kgdb_hook(line);
-
-		printk("KGDB: Using serial line /dev/ttyd%d for session, "
-			    "please connect your debugger\n", line ? 1 : 2);
-
-		remote_debug = 1;
-		/* Breakpoints and stuff are in sgi_irq_setup() */
-	}
-#endif
-
-#ifdef CONFIG_ARC_CONSOLE
-	console_setup("ttyS0");
-#endif
- 
-	sgi_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"), NULL, 10));
-
-#ifdef CONFIG_VT
-#ifdef CONFIG_SGI_NEWPORT_CONSOLE
-	conswitchp = &newport_con;
-
-	screen_info = (struct screen_info) {
-		0, 0,		/* orig-x, orig-y */
-		0,		/* unused */
-		0,		/* orig_video_page */
-		0,		/* orig_video_mode */
-		160,		/* orig_video_cols */
-		0, 0, 0,	/* unused, ega_bx, unused */
-		64,		/* orig_video_lines */
-		0,		/* orig_video_isVGA */
-		16		/* orig_video_points */
-	};
-#else
-	conswitchp = &dummy_con;
-#endif
-#endif
-
-	rtc_ops = &indy_rtc_ops;
-	kbd_ops = &sgi_kbd_ops;
-#ifdef CONFIG_PSMOUSE
-	aux_device_present = 0xaa;
-#endif
-#ifdef CONFIG_VIDEO_VINO
-	init_vino();
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/system.c linux/arch/mips/sgi/kernel/system.c
--- linux.orig/arch/mips/sgi/kernel/system.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/sgi/kernel/system.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,132 +0,0 @@
-/*
- * system.c: Probe the system type using ARCS prom interface library.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: system.c,v 1.8 1999/10/09 00:00:59 ralf Exp $
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-
-#include <asm/sgi/sgi.h>
-#include <asm/sgialib.h>
-#include <asm/bootinfo.h>
-
-enum sgi_mach sgimach;
-
-struct smatch {
-	char *name;
-	int type;
-};
-
-static struct smatch sgi_cputable[] = {
-	{ "MIPS-R2000", CPU_R2000 },
-	{ "MIPS-R3000", CPU_R3000 },
-	{ "MIPS-R3000A", CPU_R3000A },
-	{ "MIPS-R4000", CPU_R4000SC },
-	{ "MIPS-R4400", CPU_R4400SC },
-	{ "MIPS-R4600", CPU_R4600 },
-	{ "MIPS-R8000", CPU_R8000 },
-	{ "MIPS-R5000", CPU_R5000 },
-	{ "MIPS-R5000A", CPU_R5000A }
-};
-
-#define NUM_CPUS 9 /* for now */
-
-static int __init string_to_cpu(char *s)
-{
-	int i;
-
-	for(i = 0; i < NUM_CPUS; i++) {
-		if(!strcmp(s, sgi_cputable[i].name))
-			return sgi_cputable[i].type;
-	}
-	prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s);
-	prom_printf("press a key to reboot\n");
-	prom_getchar();
-	romvec->imode();
-	return 0;
-}
-
-/*
- * We' call this early before loadmmu().  If we do the other way around
- * the firmware will crash and burn.
- */
-void __init sgi_sysinit(void)
-{
-	pcomponent *p, *toplev, *cpup = 0;
-	int cputype = -1;
-
-
-	/* The root component tells us what machine architecture we
-	 * have here.
-	 */
-	p = prom_getchild(PROM_NULL_COMPONENT);
-
-	/* Now scan for cpu(s). */
-	toplev = p = prom_getchild(p);
-	while(p) {
-		int ncpus = 0;
-
-		if(p->type == Cpu) {
-			if(++ncpus > 1) {
-				prom_printf("\nYeee, SGI MP not ready yet\n");
-				prom_printf("press a key to reboot\n");
-				prom_getchar();
-				romvec->imode();
-			}
-			printk("CPU: %s ", p->iname);
-			cpup = p;
-			cputype = string_to_cpu(cpup->iname);
-		}
-		p = prom_getsibling(p);
-	}
-	if(cputype == -1) {
-		prom_printf("\nYeee, could not find cpu ARCS component\n");
-		prom_printf("press a key to reboot\n");
-		prom_getchar();
-		romvec->imode();
-	}
-	p = prom_getchild(cpup);
-	while(p) {
-		switch(p->class) {
-		case processor:
-			switch(p->type) {
-			case Fpu:
-				printk("FPU<%s> ", p->iname);
-				break;
-
-			default:
-				break;
-			};
-			break;
-
-		case cache:
-			switch(p->type) {
-			case picache:
-				printk("ICACHE ");
-				break;
-
-			case pdcache:
-				printk("DCACHE ");
-				break;
-
-			case sccache:
-				printk("SCACHE ");
-				break;
-
-			default:
-				break;
-
-			};
-			break;
-
-		default:
-			break;
-		};
-		p = prom_getsibling(p);
-	}
-	printk("\n");
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi/kernel/time.c linux/arch/mips/sgi/kernel/time.c
--- linux.orig/arch/mips/sgi/kernel/time.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sgi/kernel/time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,21 +0,0 @@
-/*
- * time.c: Generic SGI handler for (spurious) 8254 interrupts
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <asm/sgialib.h>
-
-void indy_8254timer_irq(void)
-{
-	int cpu = smp_processor_id();
-	int irq = 4;
-
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
-	printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
-	prom_getchar();
-	ArcEnterInteractiveMode();
-	irq_exit(cpu, irq);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/Makefile linux/arch/mips/sgi-ip22/Makefile
--- linux.orig/arch/mips/sgi-ip22/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/Makefile	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,24 @@
+#
+# Makefile for the SGI specific kernel interface routines
+# under Linux.
+#
+# 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).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET := ip22-kern.o
+
+all: ip22-kern.o ip22-irq.o
+
+obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-time.o ip22-berr.o \
+         ip22-gio.o ip22-rtc.o ip22-reset.o ip22-system.o ip22-setup.o
+
+obj-$(CONFIG_BOARD_SCACHE)	+= ip22-sc.o
+
+ip22-irq.o: ip22-irq.S
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-berr.c linux/arch/mips/sgi-ip22/ip22-berr.c
--- linux.orig/arch/mips/sgi-ip22/ip22-berr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-berr.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,78 @@
+/*
+ * ip22-berr.c: Bus error handling.
+ *
+ * Copyright (C) 2002 Ladislav Michl
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/branch.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+
+unsigned int cpu_err_stat;	/* Status reg for CPU */
+unsigned int gio_err_stat;	/* Status reg for GIO */
+unsigned int cpu_err_addr;	/* Error address reg for CPU */
+unsigned int gio_err_addr;	/* Error address reg for GIO */
+
+volatile int nofault;
+
+static void save_and_clear_buserr(void)
+{
+	/* save memory controler's error status registers */ 
+	cpu_err_addr = mcmisc_regs->cerr;
+	cpu_err_stat = mcmisc_regs->cstat;
+	gio_err_addr = mcmisc_regs->gerr;
+	gio_err_stat = mcmisc_regs->gstat;
+
+	mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
+}
+
+/*
+ * MC sends an interrupt whenever bus or parity errors occur. In addition, 
+ * if the error happened during a CPU read, it also asserts the bus error 
+ * pin on the R4K. Code in bus error handler save the MC bus error registers
+ * and then clear the interrupt when this happens.
+ */
+
+void be_ip22_interrupt(int irq, struct pt_regs *regs)
+{
+	save_and_clear_buserr();
+	printk(KERN_ALERT "Bus error, epc == %08lx, ra == %08lx\n",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
+	force_sig(SIGBUS, current);
+}
+
+int be_ip22_handler(struct pt_regs *regs, int is_fixup)
+{
+	save_and_clear_buserr();
+	if (nofault) {
+		nofault = 0;
+		compute_return_epc(regs);
+		return MIPS_BE_DISCARD;
+	}
+	return MIPS_BE_FIXUP;
+}
+
+int ip22_baddr(unsigned int *val, unsigned long addr)
+{
+	nofault = 1;
+	*val = *(volatile unsigned int *) addr;
+	__asm__ __volatile__("nop;nop;nop;nop");
+	if (nofault) {
+		nofault = 0;
+		return 0;
+	}
+	return -EFAULT;
+}
+
+void __init bus_error_init(void)
+{
+	be_board_handler = be_ip22_handler;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-gio.c linux/arch/mips/sgi-ip22/ip22-gio.c
--- linux.orig/arch/mips/sgi-ip22/ip22-gio.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-gio.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,152 @@
+/* 
+ * ip22-gio.c: Support for GIO64 bus (inspired by PCI code)
+ * 
+ * Copyright (C) 2002 Ladislav Michl
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgigio.h>
+
+#define GIO_PIO_MAP_BASE	0x1f000000L
+#define GIO_PIO_MAP_SIZE	(16 * 1024*1024)
+
+#define GIO_ADDR_GFX		0x1f000000L
+#define GIO_ADDR_GIO1		0x1f400000L
+#define GIO_ADDR_GIO2		0x1f600000L
+
+#define GIO_GFX_MAP_SIZE	(4 * 1024*1024)
+#define GIO_GIO1_MAP_SIZE	(2 * 1024*1024)
+#define GIO_GIO2_MAP_SIZE	(4 * 1024*1024)
+
+#define GIO_NO_DEVICE		0x80
+
+static struct gio_dev gio_slot[GIO_NUM_SLOTS] = {
+	{
+		0,
+		0,
+		0,
+		GIO_NO_DEVICE,
+		GIO_SLOT_GFX,
+		GIO_ADDR_GFX,
+		GIO_GFX_MAP_SIZE,
+		NULL,
+		"GFX"
+	},
+	{
+		0,
+		0,
+		0,
+		GIO_NO_DEVICE,
+		GIO_SLOT_GIO1,
+		GIO_ADDR_GIO1,
+		GIO_GIO1_MAP_SIZE,
+		NULL,
+		"EXP0"
+	},
+	{
+		0,
+		0,
+		0,
+		GIO_NO_DEVICE,
+		GIO_SLOT_GIO2,
+		GIO_ADDR_GIO2,
+		GIO_GIO2_MAP_SIZE,
+		NULL,
+		"EXP1"
+	}
+};
+
+static int gio_read_proc(char *buf, char **start, off_t off,
+			 int count, int *eof, void *data)
+{
+	int i;
+	char *p = buf;
+	
+	p += sprintf(p, "GIO devices found:\n");
+	for (i = 0; i < GIO_NUM_SLOTS; i++) {
+		if (gio_slot[i].flags & GIO_NO_DEVICE)
+			continue;
+		p += sprintf(p, "  Slot %s, DeviceId 0x%02x\n",
+			     gio_slot[i].slot_name, gio_slot[i].device);
+		p += sprintf(p, "    BaseAddr 0x%08lx, MapSize 0x%08x\n",
+			     gio_slot[i].base_addr, gio_slot[i].map_size);
+	}
+	
+	return p - buf;
+}
+
+void create_gio_proc_entry(void)
+{
+	create_proc_read_entry("gio", 0, NULL, gio_read_proc, NULL);
+}
+
+/**
+ * gio_find_device - begin or continue searching for a GIO device by device id
+ * @device: GIO device id to match, or %GIO_ANY_ID to match all device ids
+ * @from: Previous GIO device found in search, or %NULL for new search.
+ *
+ * Iterates through the list of known GIO devices. If a GIO device is found
+ * with a matching @device, a pointer to its device structure is returned. 
+ * Otherwise, %NULL is returned.
+ * A new search is initiated by passing %NULL to the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from next device.
+ */
+struct gio_dev *
+gio_find_device(unsigned char device, const struct gio_dev *from)
+{
+	int i;
+	
+	for (i = (from) ? from->slot_number : 0; i < GIO_NUM_SLOTS; i++)
+		if (!(gio_slot[i].flags & GIO_NO_DEVICE) && 
+		   (device == GIO_ANY_ID || device == gio_slot[i].device))
+			return &gio_slot[i];
+	
+	return NULL;
+}
+
+#define GIO_IDCODE(x)		(x & 0x7f)
+#define GIO_ALL_BITS_VALID	0x80
+#define GIO_REV(x)		((x >> 8) & 0xff)
+#define GIO_GIO_SIZE_64		0x10000
+#define GIO_ROM_PRESENT		0x20000
+#define GIO_VENDOR_CODE(x)	((x >> 18) & 0x3fff)
+
+extern int ip22_baddr(unsigned int *val, unsigned long addr);
+
+/** 
+ * sgigio_init - scan the GIO space and figure out what hardware is actually
+ * present.
+ */
+void __init sgigio_init(void)
+{
+	unsigned int i, id, found = 0;
+
+	printk("GIO: Scanning for GIO cards...\n");
+	for (i = 0; i < GIO_NUM_SLOTS; i++) {
+		if (ip22_baddr(&id, KSEG1ADDR(gio_slot[i].base_addr)))
+			continue;
+
+		found = 1;
+		gio_slot[i].device = GIO_IDCODE(id);
+		if (id & GIO_ALL_BITS_VALID) {
+			gio_slot[i].revision = GIO_REV(id);
+			gio_slot[i].vendor = GIO_VENDOR_CODE(id);
+			gio_slot[i].flags =
+				(id & GIO_GIO_SIZE_64) ? GIO_IFACE_64 : 0 |
+				(id & GIO_ROM_PRESENT) ? GIO_HAS_ROM : 0;
+		} else
+			gio_slot[i].flags = GIO_VALID_ID_ONLY;
+
+		printk("GIO: Card 0x%02x @ 0x%08lx\n", gio_slot[i].device,
+			gio_slot[i].base_addr);
+	}
+	
+	if (!found)
+		printk("GIO: No GIO cards present.\n");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-hpc.c linux/arch/mips/sgi-ip22/ip22-hpc.c
--- linux.orig/arch/mips/sgi-ip22/ip22-hpc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-hpc.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,92 @@
+/*
+ * ip22-hpc.c: Routines for generic manipulation of the HPC controllers.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1998 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+#if 0
+#define HPC_DEBUG(args...)		printk(args)
+#else
+#define HPC_DEBUG(args...)
+#endif
+
+struct hpc3_regs *hpc3c0, *hpc3c1;
+struct hpc3_miscregs *hpc3mregs;
+
+/* We need software copies of these because they are write only. */
+u32 sgi_hpc_write1, sgi_hpc_write2;
+
+/* Machine specific identifier knobs. */
+int sgi_has_ioc2 = 0;
+int sgi_guiness = 0;
+int sgi_boardid;
+
+extern char *system_type;
+
+void __init sgihpc_init(void)
+{
+	unsigned int sid, crev, brev;
+
+	hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE);
+	hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE);
+	hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE);
+	sid = hpc3mregs->sysid;
+
+	sid &= 0xff;
+	crev = (sid & 0xe0) >> 5;
+	brev = (sid & 0x1e) >> 1;
+
+	HPC_DEBUG("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev);
+	HPC_DEBUG("sgihpc_init: ");
+
+	/* This test works now thanks to William J. Earl */
+	if ((sid & 1) == 0 ) {
+		HPC_DEBUG("GUINESS ");
+		sgi_guiness = 1;
+		mips_machtype = MACH_SGI_INDY;
+		system_type =  "SGI Indy";
+	} else {
+		HPC_DEBUG("FULLHOUSE ");
+		mips_machtype = MACH_SGI_INDIGO2;
+		sgi_guiness = 0;
+		system_type = "SGI Indigo2";
+	}
+	sgi_boardid = brev;
+
+	HPC_DEBUG("sgi_boardid<%d> ", sgi_boardid);
+
+	if(crev == 1) {
+		if((sid & 1) || (brev >= 2)) {
+			HPC_DEBUG("IOC2 ");
+			sgi_has_ioc2 = 1;
+		} else {
+			HPC_DEBUG("IOC1 revision 1 ");
+		}
+	} else {
+		HPC_DEBUG("IOC1 revision 0 ");
+	}
+	HPC_DEBUG("\n");
+
+	sgi_hpc_write1 = (HPC3_WRITE1_PRESET | HPC3_WRITE1_KMRESET |
+			  HPC3_WRITE1_ERESET | HPC3_WRITE1_LC0OFF);
+
+	sgi_hpc_write2 = (HPC3_WRITE2_EASEL   | HPC3_WRITE2_NTHRESH |
+			  HPC3_WRITE2_TPSPEED | HPC3_WRITE2_EPSEL   |
+			  HPC3_WRITE2_U0AMODE | HPC3_WRITE2_U1AMODE);
+
+	if(!sgi_guiness)
+		sgi_hpc_write1 |= HPC3_WRITE1_GRESET;
+	hpc3mregs->write1 = sgi_hpc_write1;
+	hpc3mregs->write2 = sgi_hpc_write2;
+
+	hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-int.c linux/arch/mips/sgi-ip22/ip22-int.c
--- linux.orig/arch/mips/sgi-ip22/ip22-int.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-int.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,418 @@
+/*
+ * ip22-int.c: Routines for generic manipulation of the INT[23] ASIC
+ *             found on INDY and Indigo2 workstations.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) 
+ *                    - Indigo2 changes
+ *                    - Interrupt handling fixes
+ * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz)
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/gdb-stub.h>
+
+#include <asm/sgi/sgint23.h>
+#include <asm/sgi/sgihpc.h>
+
+/* #define DEBUG_SGINT */
+#undef I_REALLY_NEED_THIS_IRQ
+
+struct sgi_int2_regs *sgi_i2regs;
+struct sgi_int3_regs *sgi_i3regs;
+struct sgi_ioc_ints *ioc_icontrol;
+struct sgi_ioc_timers *ioc_timers;
+volatile unsigned char *ioc_tclear;
+
+static char lc0msk_to_irqnr[256];
+static char lc1msk_to_irqnr[256];
+static char lc2msk_to_irqnr[256];
+static char lc3msk_to_irqnr[256];
+
+extern asmlinkage void indyIRQ(void);
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
+static void enable_local0_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	/* don't allow mappable interrupt to be enabled from setup_irq,
+	 * we have our own way to do so */
+	if (irq != SGI_MAP_0_IRQ)
+		ioc_icontrol->imask0 |= (1 << (irq - SGINT_LOCAL0));
+	restore_flags(flags);
+}
+
+static unsigned int startup_local0_irq(unsigned int irq)
+{
+	enable_local0_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+static void disable_local0_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	ioc_icontrol->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
+	restore_flags(flags);
+}
+
+#define shutdown_local0_irq	disable_local0_irq
+#define mask_and_ack_local0_irq	disable_local0_irq
+
+static void end_local0_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local0_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_local0_irq_type = {
+	"IP22 local 0",
+	startup_local0_irq,
+	shutdown_local0_irq,
+	enable_local0_irq,
+	disable_local0_irq,
+	mask_and_ack_local0_irq,
+	end_local0_irq,
+	NULL
+};
+
+static void enable_local1_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	/* don't allow mappable interrupt to be enabled from setup_irq,
+	 * we have our own way to do so */
+	if (irq != SGI_MAP_1_IRQ)
+		ioc_icontrol->imask1 |= (1 << (irq - SGINT_LOCAL1));
+	restore_flags(flags);
+}
+
+static unsigned int startup_local1_irq(unsigned int irq)
+{
+	enable_local1_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+void disable_local1_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	ioc_icontrol->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
+	restore_flags(flags);
+}
+
+#define shutdown_local1_irq	disable_local1_irq
+#define mask_and_ack_local1_irq	disable_local1_irq
+
+static void end_local1_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local1_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_local1_irq_type = {
+	"IP22 local 1",
+	startup_local1_irq,
+	shutdown_local1_irq,
+	enable_local1_irq,
+	disable_local1_irq,
+	mask_and_ack_local1_irq,
+	end_local1_irq,
+	NULL
+};
+
+static void enable_local2_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	ioc_icontrol->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
+	ioc_icontrol->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
+	restore_flags(flags);
+}
+
+static unsigned int startup_local2_irq(unsigned int irq)
+{
+	enable_local2_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+void disable_local2_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	ioc_icontrol->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
+	if (!ioc_icontrol->cmeimask0)
+		ioc_icontrol->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
+	restore_flags(flags);
+}
+
+#define shutdown_local2_irq disable_local2_irq
+#define mask_and_ack_local2_irq	disable_local2_irq
+
+static void end_local2_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local2_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_local2_irq_type = {
+	"IP22 local 2",
+	startup_local2_irq,
+	shutdown_local2_irq,
+	enable_local2_irq,
+	disable_local2_irq,
+	mask_and_ack_local2_irq,
+	end_local2_irq,
+	NULL
+};
+
+static void enable_local3_irq(unsigned int irq)
+{
+#ifdef I_REALLY_NEED_THIS_IRQ
+	unsigned long flags;
+	
+	save_and_cli(flags);
+	ioc_icontrol->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+	ioc_icontrol->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
+	restore_flags(flags);
+#else
+	panic("Who need local 3 irq? see ip22-int.c");
+#endif
+}
+
+static unsigned int startup_local3_irq(unsigned int irq)
+{
+	enable_local3_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+void disable_local3_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	ioc_icontrol->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
+	if (!ioc_icontrol->cmeimask1)
+		ioc_icontrol->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+	restore_flags(flags);
+}
+
+#define shutdown_local3_irq disable_local3_irq
+#define mask_and_ack_local3_irq	disable_local3_irq
+
+static void end_local3_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local3_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_local3_irq_type = {
+	"IP22 local 3",
+	startup_local3_irq,
+	shutdown_local3_irq,
+	enable_local3_irq,
+	disable_local3_irq,
+	mask_and_ack_local3_irq,
+	end_local3_irq,
+	NULL
+};
+
+void indy_local0_irqdispatch(struct pt_regs *regs)
+{
+	unsigned char mask = ioc_icontrol->istat0;
+	unsigned char mask2 = 0;
+	int irq;
+
+	mask &= ioc_icontrol->imask0;
+	if (mask & ISTAT0_LIO2) {
+		mask2 = ioc_icontrol->vmeistat;
+		mask2 &= ioc_icontrol->cmeimask0;
+		irq = lc2msk_to_irqnr[mask2];
+	} else {
+		irq = lc0msk_to_irqnr[mask];
+	}
+
+	/* if irq == 0, then the interrupt has already been cleared */
+	if (irq)
+		do_IRQ(irq, regs);
+	return;
+}
+
+void indy_local1_irqdispatch(struct pt_regs *regs)
+{
+	unsigned char mask = ioc_icontrol->istat1;
+	unsigned char mask2 = 0;
+	int irq;
+
+	mask &= ioc_icontrol->imask1;
+	if (mask & ISTAT1_LIO3) {
+#ifndef I_REALLY_NEED_THIS_IRQ
+		printk("Whee: Got an LIO3 irq, winging it...\n");
+#endif
+		mask2 = ioc_icontrol->vmeistat;
+		mask2 &= ioc_icontrol->cmeimask1;
+		irq = lc3msk_to_irqnr[mask2];
+	} else {
+		irq = lc1msk_to_irqnr[mask];
+	}
+
+	/* if irq == 0, then the interrupt has already been cleared */
+	if (irq)
+		do_IRQ(irq, regs);
+	return;	
+}
+
+extern void be_ip22_interrupt(int irq, struct pt_regs *regs);
+
+void indy_buserror_irq(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int irq = SGI_BUSERR_IRQ;
+
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+	be_ip22_interrupt(irq, regs);
+	irq_exit(cpu, irq);
+}
+
+static struct irqaction local0_cascade = 
+	{ no_action, SA_INTERRUPT, 0, "local0 cascade", NULL, NULL };
+static struct irqaction local1_cascade = 
+	{ no_action, SA_INTERRUPT, 0, "local1 cascade", NULL, NULL };
+static struct irqaction buserr = 
+	{ no_action, SA_INTERRUPT, 0, "Bus Error", NULL, NULL };
+static struct irqaction map0_cascade =
+	{ no_action, SA_INTERRUPT, 0, "mappable0 cascade", NULL, NULL };
+#ifdef I_REALLY_NEED_THIS_IRQ
+static struct irqaction map1_cascade =
+	{ no_action, SA_INTERRUPT, 0, "mappable1 cascade", NULL, NULL };
+#endif
+
+extern void mips_cpu_irq_init(unsigned int irq_base);
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE);
+	sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE);
+
+	/* Init local mask --> irq tables. */
+	for (i = 0; i < 256; i++) {
+		if (i & 0x80) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7;
+		} else if (i & 0x40) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6;
+		} else if (i & 0x20) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5;
+		} else if (i & 0x10) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4;
+		} else if (i & 0x08) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3;
+		} else if (i & 0x04) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2;
+		} else if (i & 0x02) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1;
+		} else if (i & 0x01) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0;
+		} else {
+			lc0msk_to_irqnr[i] = 0;
+			lc1msk_to_irqnr[i] = 0;
+			lc2msk_to_irqnr[i] = 0;
+			lc3msk_to_irqnr[i] = 0;
+		}
+	}
+
+	/* Indy uses an INT3, Indigo2 uses an INT2 */
+	if (sgi_guiness) {
+		ioc_icontrol = &sgi_i3regs->ints;
+		ioc_timers = &sgi_i3regs->timers;
+		ioc_tclear = &sgi_i3regs->tclear;
+	} else {
+		ioc_icontrol = &sgi_i2regs->ints;
+		ioc_timers = &sgi_i2regs->timers;
+		ioc_tclear = &sgi_i2regs->tclear;
+	}
+
+	/* Mask out all interrupts. */
+	ioc_icontrol->imask0 = 0;
+	ioc_icontrol->imask1 = 0;
+	ioc_icontrol->cmeimask0 = 0;
+	ioc_icontrol->cmeimask1 = 0;
+
+	set_except_vector(0, indyIRQ);
+
+	init_generic_irq();
+	/* init CPU irqs */
+	mips_cpu_irq_init(SGINT_CPU);
+
+	for (i = SGINT_LOCAL0; i < SGINT_END; i++) {
+		hw_irq_controller *handler;
+
+		if (i < SGINT_LOCAL1)
+			handler		= &ip22_local0_irq_type;
+		else if (i < SGINT_LOCAL2)
+			handler		= &ip22_local1_irq_type;
+		else if (i < SGINT_LOCAL3)
+			handler		= &ip22_local2_irq_type;
+		else
+			handler		= &ip22_local3_irq_type;
+
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= handler;
+	}
+
+	/* vector handler. this register the IRQ as non-sharable */
+	setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade);
+	setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade);
+	setup_irq(SGI_BUSERR_IRQ, &buserr);
+	
+	/* cascade in cascade. i love Indy ;-) */
+	setup_irq(SGI_MAP_0_IRQ, &map0_cascade);
+#ifdef I_REALLY_NEED_THIS_IRQ
+	setup_irq(SGI_MAP_1_IRQ, &map1_cascade);
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-irq.S linux/arch/mips/sgi-ip22/ip22-irq.S
--- linux.orig/arch/mips/sgi-ip22/ip22-irq.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-irq.S	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,125 @@
+/*
+ * ip22-irq.S: Interrupt exception dispatch code for FullHouse and
+ *             Guiness.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ *    common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ *    would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ *    between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the INDY look basically (barring software IRQs
+ * which we don't use at all) like:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Local IRQ level zero
+ *             3        Local IRQ level one
+ *             4        8254 Timer zero
+ *             5        8254 Timer one
+ *             6        Bus Error
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ *                  Local IRQ zero
+ *                  Local IRQ one
+ *                  Bus Error
+ *                  8254 Timer zero
+ * Lowest  ----     8254 Timer one
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(indyIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	mfc0	s0, CP0_CAUSE		# get irq mask
+
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
+
+	/* Wheee, a timer interrupt. */
+	move	a0, sp
+	jal	indy_r4k_timer_interrupt
+	 nop				# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
+
+	/* Wheee, local level zero interrupt. */
+	jal	indy_local0_irqdispatch
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
+
+	/* Wheee, local level one interrupt. */
+	move	a0, sp
+	jal	indy_local1_irqdispatch
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	beq	a0, zero, 1f
+	 nop
+
+	/* Wheee, an asynchronous bus error... */
+	move	a0, sp
+	jal	indy_buserror_irq
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	/* Here by mistake? It is possible, that by the time we take
+	 * the exception the IRQ pin goes low, so just leave if this 
+	 * is the case.
+	 */
+	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
+	beq	a0, zero, 1f
+
+	/* Must be one of the 8254 timers... */
+	move	a0, sp
+	jal	indy_8254timer_irq
+	 nop
+1:
+	j	ret_from_irq
+	 nop
+	END(indyIRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-mc.c linux/arch/mips/sgi-ip22/ip22-mc.c
--- linux.orig/arch/mips/sgi-ip22/ip22-mc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-mc.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,165 @@
+/*
+ * ip22-mc.c: Routines for manipulating the INDY memory controller.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+
+/* #define DEBUG_SGIMC */
+
+struct sgimc_misc_ctrl *mcmisc_regs;
+struct sgimc_dma_ctrl *dmactrlregs;
+u32 *rpsscounter;
+
+static inline char *mconfig_string(unsigned long val)
+{
+	switch(val & SGIMC_MCONFIG_RMASK) {
+	case SGIMC_MCONFIG_FOURMB:
+		return "4MB";
+
+	case SGIMC_MCONFIG_EIGHTMB:
+		return "8MB";
+
+	case SGIMC_MCONFIG_SXTEENMB:
+		return "16MB";
+
+	case SGIMC_MCONFIG_TTWOMB:
+		return "32MB";
+
+	case SGIMC_MCONFIG_SFOURMB:
+		return "64MB";
+
+	case SGIMC_MCONFIG_OTEIGHTMB:
+		return "128MB";
+
+	default:
+		return "wheee, unknown";
+	}
+}
+
+void __init sgimc_init(void)
+{
+	unsigned long tmpreg;
+
+	mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
+	rpsscounter = (unsigned int *)(KSEG1+0x1fa01004);
+	dmactrlregs = (struct sgimc_dma_ctrl *)(KSEG1+0x1fa02000);
+
+	printk(KERN_INFO "MC: SGI memory controller Revision %d\n",
+	       (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV);
+
+#if 0 /* XXX Until I figure out what this bit really indicates XXX */
+	/* XXX Is this systemid bit reliable? */
+	if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) {
+		EISA_bus = 1;
+		printk("with EISA\n");
+	} else {
+		EISA_bus = 0;
+		printk("no EISA\n");
+	}
+#endif
+
+#ifdef DEBUG_SGIMC
+	prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n",
+		    mconfig_string(mcmisc_regs->mconfig0),
+		    mconfig_string(mcmisc_regs->mconfig1));
+
+	prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n",
+		    mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1);
+	prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n",
+		    mcmisc_regs->divider, mcmisc_regs->gioparm);
+#endif
+
+	/* Place the MC into a known state.  This must be done before
+	 * interrupts are first enabled etc.
+	 */
+	
+	/* Step 0: Make sure we turn off the watchdog in case it's
+	 *         still running (which might be the case after a
+	 *         soft reboot).
+	 */
+	tmpreg = mcmisc_regs->cpuctrl0; 
+	tmpreg &= ~SGIMC_CCTRL0_WDOG;
+	mcmisc_regs->cpuctrl0 = tmpreg;
+
+	/* Step 1: The CPU/GIO error status registers will not latch
+	 *         up a new error status until the register has been
+	 *         cleared by the cpu.  These status registers are
+	 *         cleared by writing any value to them.
+	 */
+	mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
+
+	/* Step 2: Enable all parity checking in cpu control register
+	 *         zero.
+	 */
+	tmpreg = mcmisc_regs->cpuctrl0;
+	tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
+		   SGIMC_CCTRL0_R4KNOCHKPARR);
+	mcmisc_regs->cpuctrl0 = tmpreg;
+
+	/* Step 3: Setup the MC write buffer depth, this is controlled
+	 *         in cpu control register 1 in the lower 4 bits.
+	 */
+	tmpreg = mcmisc_regs->cpuctrl1;
+	tmpreg &= ~0xf;
+	tmpreg |= 0xd;
+	mcmisc_regs->cpuctrl1 = tmpreg;
+
+	/* Step 4: Initialize the RPSS divider register to run as fast
+	 *         as it can correctly operate.  The register is laid
+	 *         out as follows:
+	 *
+	 *         ----------------------------------------
+	 *         |  RESERVED  |   INCREMENT   | DIVIDER |
+	 *         ----------------------------------------
+	 *          31        16 15            8 7       0
+	 *
+	 *         DIVIDER determines how often a 'tick' happens,
+	 *         INCREMENT determines by how the RPSS increment
+	 *         registers value increases at each 'tick'. Thus,
+	 *         for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
+	 */
+	mcmisc_regs->divider = 0x101;
+
+	/* Step 5: Initialize GIO64 arbitrator configuration register.
+	 *
+	 * NOTE: If you dork with startup code the HPC init code in
+	 *       sgihpc_init() must run before us because of how we
+	 *       need to know Guiness vs. FullHouse and the board
+	 *       revision on this machine.  You have been warned.
+	 */
+
+	/* First the basic invariants across all GIO64 implementations. */
+	tmpreg = SGIMC_GIOPARM_HPC64;    /* All 1st HPC's interface at 64bits. */
+	tmpreg |= SGIMC_GIOPARM_ONEBUS;  /* Only one physical GIO bus exists. */
+
+	if(sgi_guiness) {
+		/* Guiness specific settings. */
+		tmpreg |= SGIMC_GIOPARM_EISA64;     /* MC talks to EISA at 64bits */
+		tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */
+	} else {
+		/* Fullhouse specific settings. */
+		if(sgi_boardid < 2) {
+			tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */
+			tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */
+			tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */
+			tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */
+		} else {
+			tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */
+			tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */
+			tmpreg |= SGIMC_GIOPARM_PLINEEXP1;
+			tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */
+			tmpreg |= SGIMC_GIOPARM_GFX64; 	/* GFX at 64 bits */
+		}
+	}
+	mcmisc_regs->gioparm = tmpreg; /* poof */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-reset.c linux/arch/mips/sgi-ip22/ip22-reset.c
--- linux.orig/arch/mips/sgi-ip22/ip22-reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-reset.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,242 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 2001 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/reboot.h>
+#include <asm/ds1286.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+
+/*
+ * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds.
+ * I'm not sure if this feature is a good idea, for now it's here just to
+ * make the power button make behave just like under IRIX.
+ */
+#define POWERDOWN_TIMEOUT	120
+
+/*
+ * Blink frequency during reboot grace period and when paniced.
+ */
+#define POWERDOWN_FREQ		(HZ / 4)
+#define PANIC_FREQ		(HZ / 8)
+
+static unsigned char sgi_volume;
+
+static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer;
+static int shuting_down = 0, has_paniced = 0, setup_done = 0;
+
+static void sgi_machine_restart(char *command) __attribute__((noreturn));
+static void sgi_machine_halt(void) __attribute__((noreturn));
+static void sgi_machine_power_off(void) __attribute__((noreturn));
+
+/* XXX How to pass the reboot command to the firmware??? */
+static void sgi_machine_restart(char *command)
+{
+	if (shuting_down)
+		sgi_machine_power_off();
+	ArcReboot();
+}
+
+static void sgi_machine_halt(void)
+{
+	if (shuting_down)
+		sgi_machine_power_off();
+	ArcEnterInteractiveMode();
+}
+
+static void sgi_machine_power_off(void)
+{
+	unsigned char val;
+	
+	cli();
+
+	/* Disable watchdog */
+	val = CMOS_READ(RTC_CMD);
+	CMOS_WRITE(val|RTC_WAM, RTC_CMD);
+	CMOS_WRITE(0, RTC_WSEC);
+	CMOS_WRITE(0, RTC_WHSEC);
+
+	while(1) {
+		hpc3mregs->panel=0xfe;
+		/* Good bye cruel world ...  */
+
+		/* If we're still running, we probably got sent an alarm
+		   interrupt.  Read the flag to clear it.  */
+		val = CMOS_READ(RTC_HOURS_ALARM);
+	}
+}
+
+static void power_timeout(unsigned long data)
+{
+	sgi_machine_power_off();
+}
+
+static void blink_timeout(unsigned long data)
+{
+	/* XXX fix this for fullhouse  */
+	sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF);
+	hpc3mregs->write1 = sgi_hpc_write1;
+
+	mod_timer(&blink_timer, jiffies+data);
+}
+
+static void debounce(unsigned long data)
+{
+	del_timer(&debounce_timer);
+	if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent.  */
+		debounce_timer.expires = jiffies + 5; /* 0.05s  */
+		add_timer(&debounce_timer);
+
+		hpc3mregs->panel = 0xf3;
+
+		return;
+	}
+
+	if (has_paniced)
+		ArcReboot();
+
+	enable_irq(SGI_PANEL_IRQ);
+}
+
+static inline void power_button(void)
+{
+	if (has_paniced)
+		return;
+
+	if (shuting_down || kill_proc(1, SIGINT, 1)) {
+		/* No init process or button pressed twice.  */
+		sgi_machine_power_off();
+	}
+
+	shuting_down = 1;
+	blink_timer.data = POWERDOWN_FREQ;
+	blink_timeout(POWERDOWN_FREQ);
+
+	init_timer(&power_timer);
+	power_timer.function = power_timeout;
+	power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
+	add_timer(&power_timer);
+}
+
+void inline sgi_volume_set(unsigned char volume)
+{
+	sgi_volume = volume;
+
+	hpc3c0->pbus_extregs[2][0] = sgi_volume;
+	hpc3c0->pbus_extregs[2][1] = sgi_volume;
+}
+
+void inline sgi_volume_get(unsigned char *volume)
+{
+	*volume = sgi_volume;
+}
+
+static inline void volume_up_button(unsigned long data)
+{
+	del_timer(&volume_timer);
+
+	if (sgi_volume < 0xff)
+		sgi_volume++;
+
+	hpc3c0->pbus_extregs[2][0] = sgi_volume;
+	hpc3c0->pbus_extregs[2][1] = sgi_volume;
+
+	if (ioc_icontrol->istat1 & 2) {
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+
+}
+
+static inline void volume_down_button(unsigned long data)
+{
+	del_timer(&volume_timer);
+
+	if (sgi_volume > 0)
+		sgi_volume--;
+
+	hpc3c0->pbus_extregs[2][0] = sgi_volume;
+	hpc3c0->pbus_extregs[2][1] = sgi_volume;
+
+	if (ioc_icontrol->istat1 & 2) {
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+}
+
+static void panel_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int buttons;
+
+	buttons = hpc3mregs->panel;
+	hpc3mregs->panel = 0x03;	/* power_interrupt | power_supply_on */
+
+	if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */
+		disable_irq(SGI_PANEL_IRQ);
+		init_timer(&debounce_timer);
+		debounce_timer.function = debounce;
+		debounce_timer.expires = jiffies + 5;
+		add_timer(&debounce_timer);
+	}
+
+	if (!(buttons & 0x02))		/* Power button was pressed */
+		power_button();
+	if (!(buttons & 0x40)) {	/* Volume up button was pressed */
+		init_timer(&volume_timer);
+		volume_timer.function = volume_up_button;
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+	if (!(buttons & 0x10)) {	/* Volume down button was pressed */
+		init_timer(&volume_timer);
+		volume_timer.function = volume_down_button;
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+}
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+                      void *ptr)
+{
+	if (has_paniced)
+		return NOTIFY_DONE;
+	has_paniced = 1;
+
+	blink_timer.data = PANIC_FREQ;
+	blink_timeout(PANIC_FREQ);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+	panic_event,
+	NULL,
+	0
+};
+
+void indy_reboot_setup(void)
+{
+	if (setup_done)
+		return;
+	setup_done = 1;
+
+	_machine_restart = sgi_machine_restart;
+	_machine_halt = sgi_machine_halt;
+	_machine_power_off = sgi_machine_power_off;
+
+	request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
+	init_timer(&blink_timer);
+	blink_timer.function = blink_timeout;
+	notifier_chain_register(&panic_notifier_list, &panic_block);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-rtc.c linux/arch/mips/sgi-ip22/ip22-rtc.c
--- linux.orig/arch/mips/sgi-ip22/ip22-rtc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-rtc.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * RTC routines for Indy style attached Dallas chip.
+ *
+ * Copyright (C) 1998, 2001 by Ralf Baechle
+ */
+#include <asm/ds1286.h>
+#include <asm/sgi/sgihpc.h>
+
+static unsigned char indy_rtc_read_data(unsigned long addr)
+{
+	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
+
+	return rtcregs[addr];
+}
+
+static void indy_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
+
+	rtcregs[addr] = data;
+}
+
+static int indy_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops indy_rtc_ops = {
+	&indy_rtc_read_data,
+	&indy_rtc_write_data,
+	&indy_rtc_bcd_mode
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-sc.c linux/arch/mips/sgi-ip22/ip22-sc.c
--- linux.orig/arch/mips/sgi-ip22/ip22-sc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-sc.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,225 @@
+/*
+ * ip22-sc.c: Indy cache management functions.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bcache.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#undef DEBUG_CACHE
+
+#define SC_SIZE 0x00080000
+#define SC_LINE 32
+#define CI_MASK (SC_SIZE - SC_LINE)
+#define SC_INDEX(n) ((n) & CI_MASK)
+
+static inline void indy_sc_wipe(unsigned long first, unsigned long last)
+{
+	unsigned long tmp;
+
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# indy_sc_wipe\n\t"
+	".set\tmips3\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t%2, $12\n\t"
+	"li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
+	"mtc0\t$1, $12\n\t"
+
+	"dli\t$1, 0x9000000080000000\n\t"
+	"or\t%0, $1\t\t\t# first line to flush\n\t"
+	"or\t%1, $1\t\t\t# last line to flush\n\t"
+	".set\tat\n\t"
+
+	"1:\tsw\t$0, 0(%0)\n\t"
+	"bne\t%0, %1, 1b\n\t"
+	"daddu\t%0, 32\n\t"
+
+	"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
+	"nop; nop; nop; nop;\n\t"
+	".set\tmips0\n\t"
+	".set\treorder"
+	: "=r" (first), "=r" (last), "=&r" (tmp)
+	: "0" (first), "1" (last));
+}
+
+static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size)
+{
+	unsigned long first_line, last_line;
+	unsigned int flags;
+
+#ifdef DEBUG_CACHE
+	printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
+#endif
+
+	if (!size)
+		return;
+
+	/* Which lines to flush?  */
+	first_line = SC_INDEX(addr);
+	last_line = SC_INDEX(addr + size - 1);
+
+	__save_and_cli(flags);
+	if (first_line <= last_line) {
+		indy_sc_wipe(first_line, last_line);
+		goto out;
+	}
+
+	indy_sc_wipe(first_line, SC_SIZE - SC_LINE);
+	indy_sc_wipe(0, last_line);
+out:
+	__restore_flags(flags);
+}
+
+static void indy_sc_enable(void)
+{
+	unsigned long addr, tmp1, tmp2;
+
+	/* This is really cool... */
+#ifdef DEBUG_CACHE
+	printk("Enabling R4600 SCACHE\n");
+#endif
+	__asm__ __volatile__(
+	".set\tpush\n\t"
+	".set\tnoreorder\n\t"
+	".set\tmips3\n\t"
+	"mfc0\t%2, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"li\t%1, 0x80\n\t"
+	"mtc0\t%1, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"li\t%0, 0x1\n\t"
+	"dsll\t%0, 31\n\t"
+	"lui\t%1, 0x9000\n\t"
+	"dsll32\t%1, 0\n\t"
+	"or\t%0, %1, %0\n\t"
+	"sb\t$0, 0(%0)\n\t"
+	"mtc0\t$0, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"mtc0\t%2, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	".set\tpop"
+	: "=r" (tmp1), "=r" (tmp2), "=r" (addr));
+}
+
+static void indy_sc_disable(void)
+{
+	unsigned long tmp1, tmp2, tmp3;
+
+#ifdef DEBUG_CACHE
+	printk("Disabling R4600 SCACHE\n");
+#endif
+	__asm__ __volatile__(
+	".set\tpush\n\t"
+	".set\tnoreorder\n\t"
+	".set\tmips3\n\t"
+	"li\t%0, 0x1\n\t"
+	"dsll\t%0, 31\n\t"
+	"lui\t%1, 0x9000\n\t"
+	"dsll32\t%1, 0\n\t"
+	"or\t%0, %1, %0\n\t"
+	"mfc0\t%2, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"li\t%1, 0x80\n\t"
+	"mtc0\t%1, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"sh\t$0, 0(%0)\n\t"
+	"mtc0\t$0, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"mtc0\t%2, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	".set\tpop"
+	: "=r" (tmp1), "=r" (tmp2), "=r" (tmp3));
+}
+
+static inline int __init indy_sc_probe(void)
+{
+	volatile unsigned int *cpu_control;
+	unsigned short cmd = 0xc220;
+	unsigned long data = 0;
+	int i, n;
+
+#ifdef __MIPSEB__
+	cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00034);
+#else
+	cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00030);
+#endif
+#define DEASSERT(bit) (*(cpu_control) &= (~(bit)))
+#define ASSERT(bit) (*(cpu_control) |= (bit))
+#define DELAY  for(n = 0; n < 100000; n++) __asm__ __volatile__("")
+	DEASSERT(SGIMC_EEPROM_PRE);
+	DEASSERT(SGIMC_EEPROM_SDATAO);
+	DEASSERT(SGIMC_EEPROM_SECLOCK);
+	DEASSERT(SGIMC_EEPROM_PRE);
+	DELAY;
+	ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK);
+	for(i = 0; i < 11; i++) {
+		if(cmd & (1<<15))
+			ASSERT(SGIMC_EEPROM_SDATAO);
+		else
+			DEASSERT(SGIMC_EEPROM_SDATAO);
+		DEASSERT(SGIMC_EEPROM_SECLOCK);
+		ASSERT(SGIMC_EEPROM_SECLOCK);
+		cmd <<= 1;
+	}
+	DEASSERT(SGIMC_EEPROM_SDATAO);
+	for(i = 0; i < (sizeof(unsigned short) * 8); i++) {
+		unsigned int tmp;
+
+		DEASSERT(SGIMC_EEPROM_SECLOCK);
+		DELAY;
+		ASSERT(SGIMC_EEPROM_SECLOCK);
+		DELAY;
+		data <<= 1;
+		tmp = *cpu_control;
+		if(tmp & SGIMC_EEPROM_SDATAI)
+			data |= 1;
+	}
+	DEASSERT(SGIMC_EEPROM_SECLOCK);
+	DEASSERT(SGIMC_EEPROM_CSEL);
+	ASSERT(SGIMC_EEPROM_PRE);
+	ASSERT(SGIMC_EEPROM_SECLOCK);
+
+	data <<= PAGE_SHIFT;
+	if (data == 0)
+		return 0;
+
+	scache_size = data;
+
+	printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n",
+	       scache_size >> 10);
+
+	return 1;
+}
+
+/* XXX Check with wje if the Indy caches can differenciate between
+   writeback + invalidate and just invalidate.  */
+struct bcache_ops indy_sc_ops = {
+	indy_sc_enable,
+	indy_sc_disable,
+	indy_sc_wback_invalidate,
+	indy_sc_wback_invalidate
+};
+
+void __init indy_sc_init(void)
+{
+	if (indy_sc_probe()) {
+		indy_sc_enable();
+		bcops = &indy_sc_ops;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-setup.c linux/arch/mips/sgi-ip22/ip22-setup.c
--- linux.orig/arch/mips/sgi-ip22/ip22-setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-setup.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,235 @@
+/*
+ * ip22-setup.c: SGI specific setup, including init of the feature struct.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/pc_keyb.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/bootinfo.h>
+#include <asm/keyboard.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/ds1286.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+#include <asm/time.h>
+#include <asm/gdb-stub.h>
+#include <asm/traps.h>
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void rs_kgdb_hook(int);
+extern void breakpoint(void);
+static int remote_debug = 0;
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_ARC_CONSOLE)
+extern void console_setup(char *);
+#endif
+
+extern void sgitime_init(void);
+
+extern struct hpc3_miscregs *hpc3mregs;
+extern struct rtc_ops indy_rtc_ops;
+extern void indy_reboot_setup(void);
+extern void sgi_volume_set(unsigned char);
+extern void create_gio_proc_entry(void);
+
+#define sgi_kh ((struct hpc_keyb *) &(hpc3mregs->kbdmouse0))
+
+#define KBD_STAT_IBF		0x02	/* Keyboard input buffer full */
+
+unsigned long sgi_gfxaddr;
+
+static void sgi_request_region(void)
+{
+	/* No I/O ports are being used on the Indy.  */
+}
+
+static int sgi_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+	/* Dirty hack, this get's called as a callback from the keyboard
+	 * driver.  We piggyback the initialization of the front panel
+	 * button handling on it even though they're technically not
+	 * related with the keyboard driver in any way.  Doing it from
+	 * ip22_setup wouldn't work since kmalloc isn't initialized yet.
+	 */
+	indy_reboot_setup();
+
+	/* Ehm, well... once David used hack above, let's add yet another.
+	 * Register GIO bus proc entry here.
+	 */
+	create_gio_proc_entry();
+
+	return request_irq(SGI_KEYBD_IRQ, handler, 0, "keyboard", NULL);
+}
+
+static int sgi_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+	/* Nothing to do, interrupt is shared with the keyboard hw  */
+	return 0;
+}
+
+static void sgi_aux_free_irq(void)
+{
+	/* Nothing to do, interrupt is shared with the keyboard hw  */
+}
+
+static unsigned char sgi_read_input(void)
+{
+	return sgi_kh->data;
+}
+
+static void sgi_write_output(unsigned char val)
+{
+	int status;
+
+	do {
+		status = sgi_kh->command;
+	} while (status & KBD_STAT_IBF);
+	sgi_kh->data = val;
+}
+
+static void sgi_write_command(unsigned char val)
+{
+	int status;
+
+	do {
+		status = sgi_kh->command;
+	} while (status & KBD_STAT_IBF);
+	sgi_kh->command = val;
+}
+
+static unsigned char sgi_read_status(void)
+{
+	return sgi_kh->command;
+}
+
+struct kbd_ops sgi_kbd_ops = {
+	sgi_request_region,
+	sgi_request_irq,
+
+	sgi_aux_request_irq,
+	sgi_aux_free_irq,
+
+	sgi_read_input,
+	sgi_write_output,
+	sgi_write_command,
+	sgi_read_status
+};
+
+void __init ip22_setup(void)
+{
+#ifdef CONFIG_SERIAL_CONSOLE
+	char *ctype;
+#endif
+#ifdef CONFIG_REMOTE_DEBUG
+	char *kgdb_ttyd;
+#endif
+	sgitime_init();
+	/* Init the INDY HPC I/O controller.  Need to call this before
+	 * fucking with the memory controller because it needs to know the
+	 * boardID and whether this is a Guiness or a FullHouse machine.
+	 */
+	sgihpc_init();
+
+	/* Init INDY memory controller. */
+	sgimc_init();
+
+#ifdef CONFIG_BOARD_SCACHE
+	/* Now enable boardcaches, if any. */
+	indy_sc_init();
+#endif
+	conswitchp = NULL;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+	/* ARCS console environment variable is set to "g?" for
+	 * graphics console, it is set to "d" for the first serial
+	 * line and "d2" for the second serial line.
+	 */
+	ctype = ArcGetEnvironmentVariable("console");
+	if(*ctype == 'd') {
+		if(*(ctype+1)=='2')
+			console_setup ("ttyS1");
+		else
+			console_setup ("ttyS0");
+	}
+#endif
+
+#ifdef CONFIG_REMOTE_DEBUG
+	kgdb_ttyd = prom_getcmdline();
+	if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) {
+		int line;
+		kgdb_ttyd += strlen("kgdb=ttyd");
+		if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2')
+			printk("KGDB: Uknown serial line /dev/ttyd%c, "
+			       "falling back to /dev/ttyd1\n", *kgdb_ttyd);
+		line = *kgdb_ttyd == '2' ? 0 : 1;
+		printk("KGDB: Using serial line /dev/ttyd%d for session\n",
+		       line ? 1 : 2);
+		rs_kgdb_hook(line);
+
+		printk("KGDB: Using serial line /dev/ttyd%d for session, "
+			    "please connect your debugger\n", line ? 1 : 2);
+
+		remote_debug = 1;
+		/* Breakpoints and stuff are in sgi_irq_setup() */
+	}
+#endif
+
+#ifdef CONFIG_ARC_CONSOLE
+	console_setup("ttyS0");
+#endif
+ 
+	sgi_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"), NULL, 10));
+
+	{
+	  unsigned long *gfxinfo;
+	  long (*__vec)(void) = (void *) *(long *)((PROMBLOCK)->pvector + 0x20);
+	  gfxinfo = (unsigned long *)__vec();
+	  sgi_gfxaddr = gfxinfo[1] >= 0xa0000000 && gfxinfo[1] <= 0xc0000000 ? gfxinfo[1] - 0xa0000000 : 0;
+	}
+#ifdef CONFIG_VT
+#ifdef CONFIG_SGI_NEWPORT_CONSOLE
+	/* newport addresses? */
+	if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) {
+		conswitchp = &newport_con;
+
+		screen_info = (struct screen_info) {
+			0, 0,		/* orig-x, orig-y */
+			0,		/* unused */
+			0,		/* orig_video_page */
+			0,		/* orig_video_mode */
+			160,		/* orig_video_cols */
+			0, 0, 0,	/* unused, ega_bx, unused */
+			64,		/* orig_video_lines */
+			0,		/* orig_video_isVGA */
+			16		/* orig_video_points */
+		};
+	} else {
+		conswitchp = &dummy_con;
+	}
+#else
+	conswitchp = &dummy_con;
+#endif
+#endif
+
+	rtc_ops = &indy_rtc_ops;
+	kbd_ops = &sgi_kbd_ops;
+#ifdef CONFIG_PSMOUSE
+	aux_device_present = 0xaa;
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-system.c linux/arch/mips/sgi-ip22/ip22-system.c
--- linux.orig/arch/mips/sgi-ip22/ip22-system.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-system.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,134 @@
+/*
+ * ip22-system.c: Probe the system type using ARCS prom interface library.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/cpu.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgialib.h>
+
+enum sgi_mach sgimach;
+
+struct smatch {
+	char *name;
+	int type;
+};
+
+static struct smatch sgi_cputable[] = {
+	{ "MIPS-R2000", CPU_R2000 },
+	{ "MIPS-R3000", CPU_R3000 },
+	{ "MIPS-R3000A", CPU_R3000A },
+	{ "MIPS-R4000", CPU_R4000SC },
+	{ "MIPS-R4400", CPU_R4400SC },
+	{ "MIPS-R4600", CPU_R4600 },
+	{ "MIPS-R8000", CPU_R8000 },
+	{ "MIPS-R5000", CPU_R5000 },
+	{ "MIPS-R5000A", CPU_R5000A },
+	{ "MIPS-R10000", CPU_R10000 }
+};
+
+static int __init string_to_cpu(char *s)
+{
+	long cnt;
+	char c;
+	int i;
+
+	for(i = 0; i < (sizeof(sgi_cputable) / sizeof(struct smatch)); i++) {
+		if(!strcmp(s, sgi_cputable[i].name))
+			return sgi_cputable[i].type;
+	}
+	prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s);
+	prom_printf("press a key to reboot\n");
+	ArcRead(0, &c, 1, &cnt);
+	ArcEnterInteractiveMode();
+	return 0;
+}
+
+/*
+ * We' call this early before loadmmu().  If we do the other way around
+ * the firmware will crash and burn.
+ */
+void __init sgi_sysinit(void)
+{
+	pcomponent *p, *toplev, *cpup = 0;
+	int cputype = -1;
+	long cnt;
+	char c;
+
+
+	/* The root component tells us what machine architecture we
+	 * have here.
+	 */
+	p = ArcGetChild(PROM_NULL_COMPONENT);
+
+	/* Now scan for cpu(s). */
+	printk(KERN_INFO);
+	toplev = p = ArcGetChild(p);
+	while(p) {
+		int ncpus = 0;
+
+		if(p->type == Cpu) {
+			if(++ncpus > 1) {
+				prom_printf("\nYeee, SGI MP not ready yet\n");
+				prom_printf("press a key to reboot\n");
+				ArcRead(0, &c, 1, &cnt);
+				ArcEnterInteractiveMode();
+			}
+			printk("CPU: %s ", p->iname);
+			cpup = p;
+			cputype = string_to_cpu(cpup->iname);
+		}
+		p = ArcGetPeer(p);
+	}
+	if (cputype == -1) {
+		prom_printf("\nYeee, could not find cpu ARCS component\n");
+		prom_printf("press a key to reboot\n");
+		ArcRead(0, &c, 1, &cnt);
+		ArcEnterInteractiveMode();
+	}
+	p = ArcGetChild(cpup);
+	while(p) {
+		switch(p->class) {
+		case processor:
+			switch(p->type) {
+			case Fpu:
+				printk("FPU<%s> ", p->iname);
+				break;
+
+			default:
+				break;
+			};
+			break;
+
+		case cache:
+			switch(p->type) {
+			case picache:
+				printk("ICACHE ");
+				break;
+
+			case pdcache:
+				printk("DCACHE ");
+				break;
+
+			case sccache:
+				printk("SCACHE ");
+				break;
+
+			default:
+				break;
+
+			};
+			break;
+
+		default:
+			break;
+		};
+		p = ArcGetPeer(p);
+	}
+	printk("\n");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sgi-ip22/ip22-time.c linux/arch/mips/sgi-ip22/ip22-time.c
--- linux.orig/arch/mips/sgi-ip22/ip22-time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sgi-ip22/ip22-time.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,249 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Time operations for IP22 machines. Original code may come from 
+ * Ralf Baechle or David S. Miller (sorry guys, i'm really not sure)
+ *
+ * Copyright (C) 2001 by Ladislav Michl 
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/time.h>
+
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/ds1286.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/sgint23.h>
+#include <asm/sgi/sgigio.h>
+#include <asm/time.h>
+
+/*
+ * note that mktime uses month from 1 to 12 while to_tm
+ * uses 0 to 11.
+ */
+static unsigned long indy_rtc_get_time(void)
+{	
+	unsigned char yrs, mon, day, hrs, min, sec;
+	unsigned char save_control;
+
+	save_control = CMOS_READ(RTC_CMD);
+	CMOS_WRITE((save_control|RTC_TE), RTC_CMD);
+
+	sec = CMOS_READ(RTC_SECONDS);
+	min = CMOS_READ(RTC_MINUTES);
+	hrs = CMOS_READ(RTC_HOURS) & 0x1f;
+	day = CMOS_READ(RTC_DATE);
+	mon = CMOS_READ(RTC_MONTH) & 0x1f;
+	yrs = CMOS_READ(RTC_YEAR);
+
+	CMOS_WRITE(save_control, RTC_CMD);
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hrs);
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(yrs);
+
+	if (yrs < 45)
+		yrs += 30;
+	if ((yrs += 40) < 70)
+		yrs += 100;
+
+	return mktime((int)yrs + 1900, mon, day, hrs, min, sec);
+}
+
+static int indy_rtc_set_time(unsigned long tim)
+{
+	struct rtc_time tm;
+	unsigned char save_control;
+
+	to_tm(tim, &tm);
+
+	tm.tm_mon += 1;		/* tm_mon starts at zero */
+	tm.tm_year -= 1940;
+	if (tm.tm_year >= 100)
+		tm.tm_year -= 100;
+
+	BIN_TO_BCD(tm.tm_sec);
+	BIN_TO_BCD(tm.tm_min);
+	BIN_TO_BCD(tm.tm_hour);
+	BIN_TO_BCD(tm.tm_mday);
+	BIN_TO_BCD(tm.tm_mon);
+	BIN_TO_BCD(tm.tm_year);
+
+	save_control = CMOS_READ(RTC_CMD);
+	CMOS_WRITE((save_control|RTC_TE), RTC_CMD);
+
+	CMOS_WRITE(tm.tm_year, RTC_YEAR);
+	CMOS_WRITE(tm.tm_mon, RTC_MONTH);
+	CMOS_WRITE(tm.tm_mday, RTC_DATE);
+	CMOS_WRITE(tm.tm_hour, RTC_HOURS);
+	CMOS_WRITE(tm.tm_min, RTC_MINUTES);
+	CMOS_WRITE(tm.tm_sec, RTC_SECONDS);
+	CMOS_WRITE(0, RTC_HUNDREDTH_SECOND);
+
+	CMOS_WRITE(save_control, RTC_CMD);
+
+	return 0;
+}
+
+static unsigned long dosample(volatile unsigned char *tcwp,
+			      volatile unsigned char *tc2p)
+{
+	unsigned long ct0, ct1;
+	unsigned char msb, lsb;
+
+	/* Start the counter. */
+	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN);
+	*tc2p = (SGINT_TCSAMP_COUNTER & 0xff);
+	*tc2p = (SGINT_TCSAMP_COUNTER >> 8);
+
+	/* Get initial counter invariant */
+	ct0 = read_32bit_cp0_register(CP0_COUNT);
+
+	/* Latch and spin until top byte of counter2 is zero */
+	do {
+		*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT);
+		lsb = *tc2p;
+		msb = *tc2p;
+		ct1 = read_32bit_cp0_register(CP0_COUNT);
+	} while(msb);
+
+	/* Stop the counter. */
+	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST);
+
+	/*
+	 * Return the difference, this is how far the r4k counter increments
+	 * for every 1/HZ seconds. We round off the nearest 1 MHz of master
+	 * clock (= 1000000 / 100 / 2 = 5000 count).
+	 */
+	return ((ct1 - ct0) / 5000) * 5000;
+}
+
+/* 
+ * Here we need to calibrate the cycle counter to at least be close. 
+ */
+void indy_time_init(void)
+{
+	struct sgi_ioc_timers *p;
+	volatile unsigned char *tcwp, *tc2p;
+	unsigned long r4k_ticks[3];
+	unsigned long r4k_tick;
+
+	/* Figure out the r4k offset, the algorithm is very simple
+	 * and works in _all_ cases as long as the 8254 counter
+	 * register itself works ok (as an interrupt driving timer
+	 * it does not because of bug, this is why we are using
+	 * the onchip r4k counter/compare register to serve this
+	 * purpose, but for r4k_offset calculation it will work
+	 * ok for us).  There are other very complicated ways
+	 * of performing this calculation but this one works just
+	 * fine so I am not going to futz around. ;-)
+	 */
+	p = ioc_timers;
+	tcwp = &p->tcword;
+	tc2p = &p->tcnt2;
+
+	printk(KERN_INFO "Calibrating system timer... ");
+	dosample(tcwp, tc2p);                   /* Prime cache. */
+	dosample(tcwp, tc2p);                   /* Prime cache. */
+	/* Zero is NOT an option. */
+	do {
+		r4k_ticks[0] = dosample (tcwp, tc2p);
+	} while (!r4k_ticks[0]);
+	do {
+		r4k_ticks[1] = dosample (tcwp, tc2p);
+	} while (!r4k_ticks[1]);
+
+	if (r4k_ticks[0] != r4k_ticks[1]) {
+		printk ("warning: timer counts differ, retrying...");
+		r4k_ticks[2] = dosample (tcwp, tc2p);
+		if (r4k_ticks[2] == r4k_ticks[0] 
+		    || r4k_ticks[2] == r4k_ticks[1])
+			r4k_tick = r4k_ticks[2];
+		else {
+			printk ("disagreement, using average...");
+			r4k_tick = (r4k_ticks[0] + r4k_ticks[1]
+				   + r4k_ticks[2]) / 3;
+		}
+	} else
+		r4k_tick = r4k_ticks[0];
+
+	printk("%d [%d.%02d MHz CPU]\n", (int) r4k_tick,
+		(int) (r4k_tick / 5000), (int) (r4k_tick % 5000) / 50);
+
+	mips_counter_frequency = r4k_tick * HZ;	
+	
+	/* HACK ALERT! This get's called after traps initialization
+	 * We piggyback the initialization of GIO bus here even though
+	 * it is technically not related with the timer in any way.
+	 * Doing it from ip22_setup wouldn't work since traps aren't 
+	 * initialized yet.
+	 */
+	sgigio_init();
+}
+
+/* Generic SGI handler for (spurious) 8254 interrupts */
+void indy_8254timer_irq(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int irq = SGI_8254_0_IRQ;
+	long cnt;
+	char c;
+
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+	printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
+	ArcRead(0, &c, 1, &cnt);
+	ArcEnterInteractiveMode();
+	irq_exit(cpu, irq);
+}
+
+void indy_r4k_timer_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int irq = SGI_TIMER_IRQ;
+
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+	timer_interrupt(irq, NULL, regs);
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+}
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+
+static void indy_timer_setup(struct irqaction *irq)
+{
+	unsigned long count;
+	
+	/* over-write the handler, we use our own way */
+	irq->handler = no_action;
+
+	/* set time for first interrupt */
+	count = read_32bit_cp0_register(CP0_COUNT);
+	count += mips_counter_frequency / HZ;
+	write_32bit_cp0_register(CP0_COMPARE, count);
+
+	/* setup irqaction */
+	setup_irq(SGI_TIMER_IRQ, irq);
+}
+
+void sgitime_init(void)
+{
+	/* setup hookup functions */
+	rtc_get_time = indy_rtc_get_time;
+	rtc_set_time = indy_rtc_set_time;
+
+	board_time_init = indy_time_init;
+	board_timer_setup = indy_timer_setup;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1/Makefile linux/arch/mips/sibyte/sb1/Makefile
--- linux.orig/arch/mips/sibyte/sb1/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,7 @@
+USE_STANDARD_AS_RULE := true
+
+L_TARGET = sb1kern.a
+
+obj-$(CONFIG_SB1_CACHE_ERROR) += cache_err_handler.o cache_error.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1/cache_err_handler.S linux/arch/mips/sibyte/sb1/cache_err_handler.S
--- linux.orig/arch/mips/sibyte/sb1/cache_err_handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1/cache_err_handler.S	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+	.text
+	/* Special Cache Error handler for SB1 for now */
+	LEAF(except_vec2_sb1)
+	.set	noat
+	.set	mips0
+	/*
+	 * This is a very bad place to be.  Our cache error detection has
+	 * triggered.  If we have write-back data in the cache, we may not be
+	 * able to recover.  As a first-order desperate measure, turn off KSEG0
+	 * cacheing.
+	 */
+	.set	push
+	#.set	mips64
+	.set	mips4
+	.set	reorder
+	# look for signature of spurious CErr
+	mfc0	k1, $26				# mfc0	k1, $26, 0
+	# check if error was recoverable
+	# XXXKW - count them
+	bltz	k1, leave_cerr
+	 nop
+
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	# look for signature of spurious CErr
+	lui	k0, 0x4000
+	bne	k0, k1, real_cerr
+	.word	0x401Bd801			# mfc0	k1, $27, 1
+	lui	k0, 0xffe0
+	and	k1, k0, k1
+	lui	k0, 0x0200
+	bne	k0, k1, real_cerr
+	 nop
+#else
+	j	real_cerr
+	 nop
+#endif
+	# XXXKW - count spurious errors
+leave_cerr:
+	# clear/unlock the registers
+	mtc0	zero, $26			# mtc0	zero, $26, 0
+	mtc0	zero, $27			# mtc0	zero, $27, 0
+	.word	0x4080d801			# mtc0	zero, $27, 1
+	.word	0x4080d803			# mtc0	zero, $27, 3
+	eret
+
+real_cerr:
+	mfc0	k0, CP0_CONFIG
+	li	k1, ~CONF_CM_CMASK
+	and	k0, k0, k1
+	ori	k0, k0, CONF_CM_UNCACHED
+	mtc0	k0, CP0_CONFIG
+	/* Give it a few cycles to sink in... */
+	sll     zero, zero, 0x1			# ssnop
+	sll     zero, zero, 0x1			# ssnop
+	sll     zero, zero, 0x1			# ssnop
+	sll     zero, zero, 0x1			# ssnop
+	sll     zero, zero, 0x1			# ssnop
+	sll     zero, zero, 0x1			# ssnop
+
+	j	sb1_cache_error
+	 nop
+
+	.set	pop
+	END(except_vec2_sb1)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1/cache_error.c linux/arch/mips/sibyte/sb1/cache_error.c
--- linux.orig/arch/mips/sibyte/sb1/cache_error.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1/cache_error.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+#include <linux/kernel.h>
+#include <asm/mipsregs.h>
+
+/* SB1 definitions */
+#define CP0_ERRCTL_RECOVERABLE (1 << 31)
+#define CP0_ERRCTL_DCACHE      (1 << 30)
+#define CP0_ERRCTL_ICACHE      (1 << 29)
+#define CP0_ERRCTL_MULTIBUS    (1 << 23)
+#define CP0_ERRCTL_MC_TLB      (1 << 15)
+#define CP0_ERRCTL_MC_TIMEOUT  (1 << 14)
+
+#define CP0_CERRI_TAG_PARITY   (1 << 29)
+#define CP0_CERRI_DATA_PARITY  (1 << 28)
+#define CP0_CERRI_EXTERNAL     (1 << 26)
+#define CP0_CERRI_CACHE_IDX    (0xff << 5)
+
+#define CP0_CERRD_MULTIPLE     (1 << 31)
+#define CP0_CERRD_TAG_STATE    (1 << 30)
+#define CP0_CERRD_TAG_ADDRESS  (1 << 29)
+#define CP0_CERRD_DATA_SBE     (1 << 28)
+#define CP0_CERRD_DATA_DBE     (1 << 27)
+#define CP0_CERRD_EXTERNAL     (1 << 26)
+#define CP0_CERRD_LOAD         (1 << 25)
+#define CP0_CERRD_STORE        (1 << 24)
+#define CP0_CERRD_FILLWB       (1 << 23)
+#define CP0_CERRD_COHERENCY    (1 << 22)
+#define CP0_CERRD_DUPTAG       (1 << 21)
+#define CP0_CERRD_CACHE_IDX    (0xff << 5)
+
+asmlinkage void sb1_cache_error(void)
+{
+	unsigned int errctl, cerr_i, cerr_d, cerr_dpa;
+	unsigned long eepc;
+
+	eepc = get_errorepc();
+
+	__asm__ __volatile__ (
+		".set push\n"
+		"#.set mips64\n"
+		".set mips4\n"
+		".word 0x4001D000; move %0, $1; # mfc0 %0, $26, 0\n"
+		".word 0x4001D800; move %1, $1; # mfc0 %1, $27, 0\n"
+		".word 0x4001D801; move %2, $1; # mfc0 %2, $27, 1\n"
+		".word 0x4001D803; move %3, $1; # mfc0 %3, $27, 3\n"
+		".set pop\n"
+		: "=r" (errctl), "=r" (cerr_i),
+		  "=r" (cerr_d), "=r" (cerr_dpa));
+
+	printk("Cache error exception:\n");
+	printk(" cp0_errorepc == 0x%0lx\n", eepc);
+	printk(" cp0_errctl   == 0x%08x\n", errctl);
+
+	if (errctl & CP0_ERRCTL_DCACHE) {
+		printk(" cp0_cerr_d   == 0x%08x\n", cerr_d);
+		printk(" cp0_cerr_dpa == 0x%08x\n", cerr_dpa);
+	}
+	if (errctl & CP0_ERRCTL_ICACHE) {
+		printk(" cp0_cerr_i   == 0x%08x\n", cerr_i);
+	}
+
+	panic("Can't handle the cache error!");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/Makefile linux/arch/mips/sibyte/sb1250/Makefile
--- linux.orig/arch/mips/sibyte/sb1250/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/Makefile	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,12 @@
+USE_STANDARD_AS_RULE := true
+
+O_TARGET := sb1250.o
+
+obj-y := irq.o irq_handler.o time.o
+
+obj-$(CONFIG_PCI)		+= pci.o
+obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_BCM1250_TBPROF)	+= bcm1250_tbprof.o
+obj-$(CONFIG_MIPS32)		+= lib_hssubr.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
--- linux.orig/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+#define SBPROF_TB_DEBUG 0
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/uaccess.h>
+#include <asm/smplock.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/64bit.h>
+#include "bcm1250_tbprof.h"
+
+#define DEVNAME "sb1250_tbprof"
+
+static struct sbprof_tb *sbp;
+
+/************************************************************************
+ * Support for ZBbus sampling using the trace buffer
+ *
+ * We use the SCD performance counter interrupt, caused by a Zclk counter
+ * overflow, to trigger the start of tracing.
+ *
+ * We set the trace buffer to sample everything and freeze on
+ * overflow.
+ *
+ * We map the interrupt for trace_buffer_freeze to handle it on CPU 0.
+ * 
+ ************************************************************************/
+
+/* Once per second on a 500 Mhz 1250 */
+#define TB_PERIOD 250000000ULL
+
+static void arm_tb(void)
+{
+	unsigned long long next = (1ULL << 40) - TB_PERIOD;
+	/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
+	   trigger start of trace.  XXX vary sampling period */
+	out64(0, KSEG1 + A_SCD_PERF_CNT_1);
+	out64(in64(KSEG1 + A_SCD_PERF_CNT_CFG) | // keep counters 0,2,3 as is
+		   M_SPC_CFG_ENABLE |		 // enable counting
+		   V_SPC_CFG_SRC1(1),		 // counter 1 counts cycles
+	      KSEG1 + A_SCD_PERF_CNT_CFG);
+	out64(next, KSEG1 + A_SCD_PERF_CNT_1);
+	/* Reset the trace buffer */
+	out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG);
+	out64(M_SCD_TRACE_CFG_FREEZE_FULL, KSEG1 + A_SCD_TRACE_CFG);
+	sbp->tb_armed = 1;
+}
+
+static void sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int i;
+	DBG(printk(DEVNAME ": tb_intr\n"));
+	if (sbp->next_tb_sample < MAX_TB_SAMPLES) {
+		/* XXX should use XKPHYS to make writes bypass L2 */
+		unsigned long long *p = sbp->sbprof_tbbuf[sbp->next_tb_sample++];
+		/* Read out trace */
+		out64(M_SCD_TRACE_CFG_START_READ, KSEG1 + A_SCD_TRACE_CFG);
+		__asm__ __volatile__ ("sync" : : : "memory");
+		/* Loop runs backwards because bundles are read out in reverse order */
+		for (i = 256 * 6; i > 0; i -= 6) {
+			// Subscripts decrease to put bundle in the order
+			//   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
+			p[i-1] = in64(KSEG1 + A_SCD_TRACE_READ); // read t2 hi
+			p[i-2] = in64(KSEG1 + A_SCD_TRACE_READ); // read t2 lo
+			p[i-3] = in64(KSEG1 + A_SCD_TRACE_READ); // read t1 hi
+			p[i-4] = in64(KSEG1 + A_SCD_TRACE_READ); // read t1 lo
+			p[i-5] = in64(KSEG1 + A_SCD_TRACE_READ); // read t0 hi
+			p[i-6] = in64(KSEG1 + A_SCD_TRACE_READ); // read t0 lo
+		}
+		if (!sbp->tb_enable) {
+			DBG(printk(DEVNAME ": tb_intr shutdown\n"));
+			out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG);
+			sbp->tb_armed = 0;
+			wake_up(&sbp->tb_sync);
+		} else {
+			arm_tb();	// knock down current interrupt and get another one later
+		}
+	} else {
+		/* No more trace buffer samples */
+		DBG(printk(DEVNAME ": tb_intr full\n"));
+		out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG);
+		sbp->tb_armed = 0;
+		if (!sbp->tb_enable) {
+			wake_up(&sbp->tb_sync);
+		}
+	}
+}
+
+static void sbprof_pc_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	panic(DEVNAME ": pc_intr");
+}
+
+static int sbprof_zbprof_start(struct file *filp)
+{
+	if (sbp->tb_enable)
+		return -EBUSY;
+
+	DBG(printk(DEVNAME ": starting\n"));
+
+	sbp->tb_enable = 1;
+	sbp->next_tb_sample = 0;
+	filp->f_pos = 0;
+
+	if (request_irq
+	    (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, "sbprof_tb trace freeze", sbp)) {
+		return -EBUSY;
+	}
+	if (request_irq
+	    (K_INT_PERF_CNT, sbprof_pc_intr, 0, "sbprof_tb scd perfcnt", sbp)) {
+		free_irq(K_INT_TRACE_FREEZE, sbp);
+		return -EBUSY;
+	}
+
+	/* I need the core to mask these, but the interrupt mapper to
+	   pass them through.  I am exploiting my knowledge that
+	   cp0_status masks out IP[5]. krw */
+	out64(K_INT_MAP_I3,
+	      KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_PERF_CNT<<3));
+
+	/* Initialize address traps */
+	out64(0, KSEG1 + A_ADDR_TRAP_UP_0);
+	out64(0, KSEG1 + A_ADDR_TRAP_UP_1);
+	out64(0, KSEG1 + A_ADDR_TRAP_UP_2);
+	out64(0, KSEG1 + A_ADDR_TRAP_UP_3);
+	
+	out64(0, KSEG1 + A_ADDR_TRAP_DOWN_0);
+	out64(0, KSEG1 + A_ADDR_TRAP_DOWN_1);
+	out64(0, KSEG1 + A_ADDR_TRAP_DOWN_2);
+	out64(0, KSEG1 + A_ADDR_TRAP_DOWN_3);
+	
+	out64(0, KSEG1 + A_ADDR_TRAP_CFG_0);
+	out64(0, KSEG1 + A_ADDR_TRAP_CFG_1);
+	out64(0, KSEG1 + A_ADDR_TRAP_CFG_2);
+	out64(0, KSEG1 + A_ADDR_TRAP_CFG_3);
+	
+	/* Initialize Trace Event 0-7 */
+	//				when interrupt
+	out64(M_SCD_TREVT_INTERRUPT, KSEG1 + A_SCD_TRACE_EVENT_0);
+	out64(0, KSEG1 + A_SCD_TRACE_EVENT_1);
+	out64(0, KSEG1 + A_SCD_TRACE_EVENT_2);
+	out64(0, KSEG1 + A_SCD_TRACE_EVENT_3);
+	out64(0, KSEG1 + A_SCD_TRACE_EVENT_4);
+	out64(0, KSEG1 + A_SCD_TRACE_EVENT_5);
+	out64(0, KSEG1 + A_SCD_TRACE_EVENT_6);
+	out64(0, KSEG1 + A_SCD_TRACE_EVENT_7);
+	
+	/* Initialize Trace Sequence 0-7 */
+	//				     Start on event 0 (interrupt)
+	out64(V_SCD_TRSEQ_FUNC_START|0x0fff,
+	      KSEG1 + A_SCD_TRACE_SEQUENCE_0);
+	//			  dsamp when d used | asamp when a used
+	out64(M_SCD_TRSEQ_ASAMPLE|M_SCD_TRSEQ_DSAMPLE|K_SCD_TRSEQ_TRIGGER_ALL,
+	      KSEG1 + A_SCD_TRACE_SEQUENCE_1);
+	out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_2);
+	out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_3);
+	out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_4);
+	out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_5);
+	out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_6);
+	out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_7);
+
+	/* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */
+	out64((1ULL << K_INT_PERF_CNT), KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE));
+
+	arm_tb();
+
+	DBG(printk(DEVNAME ": done starting\n"));
+
+	return 0;
+}
+
+static int sbprof_zbprof_stop(void)
+{
+	DBG(printk(DEVNAME ": stopping\n"));
+
+	if (sbp->tb_enable) {
+		sbp->tb_enable = 0;
+		/* XXXKW there is a window here where the intr handler
+		   may run, see the disable, and do the wake_up before
+		   this sleep happens. */
+		if (sbp->tb_armed) {
+			DBG(printk(DEVNAME ": wait for disarm\n"));
+			interruptible_sleep_on(&sbp->tb_sync);
+			DBG(printk(DEVNAME ": disarm complete\n"));
+		}
+		free_irq(K_INT_TRACE_FREEZE, sbp);
+		free_irq(K_INT_PERF_CNT, sbp);
+	}
+
+	DBG(printk(DEVNAME ": done stopping\n"));
+
+	return 0;
+}
+
+static int sbprof_tb_open(struct inode *inode, struct file *filp)
+{
+	int minor;
+
+	minor = MINOR(inode->i_rdev);
+	if (minor != 0) {
+		return -ENODEV;
+	}
+	if (sbp != NULL) {
+		return -EBUSY;
+	}
+
+	/* XXXKW spinlock? */
+	sbp = kmalloc(sizeof(struct sbprof_tb), GFP_KERNEL);
+	if (!sbp) {
+		return -ENOMEM;
+	}
+	memset(sbp, 0, sizeof(struct sbprof_tb));
+	sbp->sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
+	if (!sbp->sbprof_tbbuf) {
+		kfree(sbp);
+		sbp = NULL;
+		return -ENOMEM;
+	}
+	memset(sbp->sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
+	init_waitqueue_head(&sbp->tb_sync);
+
+	return 0;
+}
+
+static int sbprof_tb_release(struct inode *inode, struct file *filp)
+{
+	int minor;
+	
+	minor = MINOR(inode->i_rdev);
+	if (minor != 0 || sbp == NULL) {
+		return -ENODEV;
+	}
+
+	if (sbp->tb_armed || sbp->tb_enable) {
+		sbprof_zbprof_stop();
+	}
+
+	vfree(sbp->sbprof_tbbuf);
+	kfree(sbp);
+	sbp = NULL;
+
+	return 0;
+}
+
+static ssize_t sbprof_tb_read(struct file *filp, char *buf, 
+			   size_t size, loff_t *offp)
+{
+	int cur_sample, sample_off, cur_count, sample_left;
+	char *src;
+	int   count   =	 0;
+	char *dest    =	 buf;
+	long  cur_off = *offp;
+
+	count = 0;
+	cur_sample = cur_off / TB_SAMPLE_SIZE;
+	sample_off = cur_off % TB_SAMPLE_SIZE;
+	sample_left = TB_SAMPLE_SIZE - sample_off;
+	while (size && (cur_sample < sbp->next_tb_sample)) {
+		cur_count = size < sample_left ? size : sample_left;
+		src = (char *)(((long)sbp->sbprof_tbbuf[cur_sample])+sample_off);
+		copy_to_user(dest, src, cur_count);
+		DBG(printk(DEVNAME ": read from sample %d, %d bytes\n", cur_sample, cur_count));
+		size -= cur_count;
+		sample_left -= cur_count;
+		if (!sample_left) {
+			cur_sample++;
+			sample_off = 0;
+			sample_left = TB_SAMPLE_SIZE;
+		} else {
+			sample_off += cur_count;
+		}
+		cur_off += cur_count;
+		dest += cur_count;
+		count += cur_count;
+	}
+	*offp = cur_off;
+
+	return count;
+}
+
+#define SBPROF_ZBSTART	_IOW('s', 0, int)
+#define SBPROF_ZBSTOP	_IOW('s', 1, int)
+#define SBPROF_ZBFULL	_IOW('s', 2, int)
+
+static int sbprof_tb_ioctl(struct inode *inode, 
+			struct file *filp,
+			unsigned int command, 
+			unsigned long arg)
+{
+	int error = 0;
+	int full;
+
+	switch (command) {
+	case SBPROF_ZBSTART:
+		error = sbprof_zbprof_start(filp);
+		break;
+	case SBPROF_ZBSTOP:
+		error = sbprof_zbprof_stop();
+		break;
+	case SBPROF_ZBFULL:
+		full = (sbp->next_tb_sample == MAX_TB_SAMPLES);
+		return put_user(full, (int *) arg);
+	default:
+		error = -EINVAL;
+		break;
+	}
+
+	return error;
+}
+
+static struct file_operations sbprof_tb_fops = {
+	owner:		THIS_MODULE,
+	open:		sbprof_tb_open,
+	release:	sbprof_tb_release,
+	read:		sbprof_tb_read,
+	ioctl:		sbprof_tb_ioctl,
+	mmap:		NULL,
+};
+
+static devfs_handle_t devfs_handle;
+
+static int __init sbprof_tb_init(void) 
+{
+	if (devfs_register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
+		printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n",
+		       SBPROF_TB_MAJOR);
+		return -EIO;
+	}
+	devfs_handle = devfs_register(NULL, DEVNAME,
+				      DEVFS_FL_DEFAULT, SBPROF_TB_MAJOR, 0,
+				      S_IFCHR | S_IRUGO | S_IWUGO,
+				      &sbprof_tb_fops, NULL);
+	sbp = NULL;
+	printk(KERN_INFO DEVNAME ": initialized\n");
+	return 0;
+}
+
+static void __exit sbprof_tb_cleanup(void)
+{
+	devfs_unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
+	devfs_unregister(devfs_handle);
+}
+
+module_init(sbprof_tb_init);
+module_exit(sbprof_tb_cleanup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/bcm1250_tbprof.h linux/arch/mips/sibyte/sb1250/bcm1250_tbprof.h
--- linux.orig/arch/mips/sibyte/sb1250/bcm1250_tbprof.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/bcm1250_tbprof.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+#ifndef BCM1250_TBPROF_H
+
+#if SBPROF_TB_DEBUG
+#define DBG(a) a
+#else
+#define DBG(a)
+#endif
+
+#define SBPROF_TB_MAJOR 240
+
+typedef u_int64_t tb_sample_t[6*256];
+
+struct sbprof_tb {
+	tb_sample_t *sbprof_tbbuf;
+	int          next_tb_sample;
+
+	volatile int tb_enable;
+	volatile int tb_armed;
+
+	wait_queue_head_t tb_sync;
+};
+
+#define MAX_SAMPLE_BYTES (24*1024*1024)
+#define MAX_TBSAMPLE_BYTES (12*1024*1024)
+
+#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t))
+#define TB_SAMPLE_SIZE (sizeof(tb_sample_t))
+#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE)
+
+/***************************************************************************
+ * Routines for gathering ZBbus profiles using trace buffer
+ ***************************************************************************/
+
+/* Requires: Already called zclk_timer_init with a value that won't
+	     saturate 40 bits.  No subsequent use of SCD performance counters
+	     or trace buffer.
+   Effect:   Starts gathering random ZBbus profiles using trace buffer. */
+static int sbprof_zbprof_start(struct file *filp);
+
+/* Effect: Stops collection of ZBbus profiles */
+static int sbprof_zbprof_stop(void);
+
+
+/***************************************************************************
+ * Routines for using 40-bit SCD cycle counter
+ *
+ * Client responsible for either handling interrupts or making sure
+ * the cycles counter never saturates, e.g., by doing
+ * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs.
+ ***************************************************************************/
+
+/* Configures SCD counter 0 to count ZCLKs starting from val;
+   Configures SCD counters1,2,3 to count nothing.
+   Must not be called while gathering ZBbus profiles.
+
+unsigned long long val; */
+#define zclk_timer_init(val) \
+  __asm__ __volatile__ (".set push;" \
+			".set mips64;" \
+			"la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
+			"sd   %0, 0x10($8);"   /* write val to counter0 */ \
+			"sd   %1, 0($8);"      /* config counter0 for zclks*/ \
+			".set pop" \
+			: /* no outputs */ \
+						     /* enable, counter0 */ \
+			: /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \
+			: /* modifies */ "$8" )
+
+
+/* Reads SCD counter 0 and puts result in value
+   unsigned long long val; */
+#define zclk_get(val) \
+  __asm__ __volatile__ (".set push;" \
+			".set mips64;" \
+			"la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
+			"ld   %0, 0x10($8);"   /* write val to counter0 */ \
+			".set pop" \
+			: /* outputs */ "=r"(val) \
+			: /* inputs */ \
+			: /* modifies */ "$8" )
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/irq.c linux/arch/mips/sibyte/sb1250/irq.c
--- linux.orig/arch/mips/sibyte/sb1250/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/irq.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/errno.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/64bit.h>
+
+/*
+ * These are the routines that handle all the low level interrupt stuff. 
+ * Actions handled here are: initialization of the interrupt map, requesting of
+ * interrupt lines by handlers, dispatching if interrupts to handlers, probing
+ * for interrupt lines 
+ */
+
+
+#define shutdown_sb1250_irq	disable_sb1250_irq
+static void end_sb1250_irq(unsigned int irq);
+static void enable_sb1250_irq(unsigned int irq);
+static void disable_sb1250_irq(unsigned int irq);
+static unsigned int startup_sb1250_irq(unsigned int irq);
+static void ack_sb1250_irq(unsigned int irq);
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void breakpoint(void);
+#endif
+
+#define NR_IRQS 64
+
+static struct hw_interrupt_type sb1250_irq_type = {
+	"SB1250-IMR",
+	startup_sb1250_irq,
+	shutdown_sb1250_irq,
+	enable_sb1250_irq,
+	disable_sb1250_irq,
+	ack_sb1250_irq,
+	end_sb1250_irq,
+	NULL
+};
+
+spinlock_t sb1250_imr_lock = SPIN_LOCK_UNLOCKED;
+
+void sb1250_mask_irq(int cpu, int irq)
+{
+	unsigned long flags;
+	u64 cur_ints;
+
+	spin_lock_irqsave(&sb1250_imr_lock, flags);
+	cur_ints = in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK);
+	cur_ints |= (((u64) 1) << irq);
+	out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK);
+	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+}
+
+void sb1250_unmask_irq(int cpu, int irq)
+{
+	unsigned long flags;
+	u64 cur_ints;
+
+	spin_lock_irqsave(&sb1250_imr_lock, flags);
+	cur_ints = in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK);
+	cur_ints &= ~(((u64) 1) << irq);
+	out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK);
+	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+}
+
+
+
+/* Defined in arch/mips/sibyte/sb1250/irq_handler.S */
+extern void sb1250_irq_handler(void);
+
+/*****************************************************************************/
+
+static unsigned int startup_sb1250_irq(unsigned int irq)
+{
+	sb1250_unmask_irq(0, irq);
+
+	return 0;		/* never anything pending */
+}
+
+
+static void disable_sb1250_irq(unsigned int irq)
+{
+	sb1250_mask_irq(0, irq);
+}
+
+static void enable_sb1250_irq(unsigned int irq)
+{
+	sb1250_unmask_irq(0, irq);
+}
+
+
+static void ack_sb1250_irq(unsigned int irq)
+{
+	u64 pending;
+
+	/*
+	 * If the interrupt was an LDT interrupt, now is the time
+	 * to clear it.
+	 */
+	pending = in64(KSEG1 + A_IMR_REGISTER(0,R_IMR_LDT_INTERRUPT));
+	pending &= ((u64)1 << (irq));
+	if (pending)
+		out64(pending, KSEG1+A_IMR_REGISTER(0,R_IMR_LDT_INTERRUPT_CLR));
+
+	sb1250_mask_irq(0, irq);
+}
+
+
+static void end_sb1250_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		sb1250_unmask_irq(0, irq);
+	}
+}
+
+
+void __init init_sb1250_irqs(void)
+{
+	int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &sb1250_irq_type;
+	}
+}
+
+
+/*
+ *  init_IRQ is called early in the boot sequence from init/main.c.  It
+ *  is responsible for setting up the interrupt mapper and installing the
+ *  handler that will be responsible for dispatching interrupts to the
+ *  "right" place. 
+ */
+/*
+ * For now, map all interrupts to IP[2].  We could save
+ * some cycles by parceling out system interrupts to different
+ * IP lines, but keep it simple for bringup.  We'll also direct
+ * all interrupts to a single CPU; we should probably route
+ * PCI and LDT to one cpu and everything else to the other
+ * to balance the load a bit. 
+ * 
+ * On the second cpu, everything is set to IP5, which is
+ * ignored, EXCEPT the mailbox interrupt.  That one is 
+ * set to IP[2] so it is handled.  This is needed so we
+ * can do cross-cpu function calls, as requred by SMP
+ */
+
+#define IMR_IP2_VAL	K_INT_MAP_I0
+#define IMR_IP3_VAL	K_INT_MAP_I1
+#define IMR_IP4_VAL	K_INT_MAP_I2
+
+void __init init_IRQ(void)
+{
+
+	unsigned int i;
+	u64 tmp;
+
+	/* Default everything to IP2 */
+	for (i = 0; i < NR_IRQS; i++) {	/* was I0 */
+		out64(IMR_IP2_VAL,
+		      KSEG1 + A_IMR_REGISTER(0,
+					     R_IMR_INTERRUPT_MAP_BASE) +
+		      (i << 3));
+		out64(IMR_IP2_VAL,
+		      KSEG1 + A_IMR_REGISTER(1,
+					     R_IMR_INTERRUPT_MAP_BASE) +
+		      (i << 3));
+	}
+
+	init_sb1250_irqs();
+
+	/*
+	 * Map the high 16 bits of the mailbox registers to IP[3], for
+	 * inter-cpu messages
+	 */
+	/* Was I1 */
+	out64(IMR_IP3_VAL, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+	                   (K_INT_MBOX_0 << 3));
+	out64(IMR_IP3_VAL, KSEG1 + A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+	                   (K_INT_MBOX_0 << 3));
+
+	/* Clear the mailboxes.  The firmware may leave them dirty */
+	out64(0xffffffffffffffff,
+	      KSEG1 + A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU));
+	out64(0xffffffffffffffff,
+	      KSEG1 + A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU));
+
+	/* Mask everything except the mailbox registers for both cpus */
+	tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
+	out64(tmp, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK));
+	out64(tmp, KSEG1 + A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK));
+
+	/*
+	 * Note that the timer interrupts are also mapped, but this is 
+	 * done in sb1250_time_init()
+	 */
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+	/* Enable IP[7,4:0], disable the rest */
+	clear_cp0_status(0x6000);
+	set_cp0_status(0x9f00);
+#else
+	/* Enable IP[4:0], disable the rest */
+	clear_cp0_status(0xe000);
+	set_cp0_status(0x1f00);
+#endif
+	set_except_vector(0, sb1250_irq_handler);
+
+#ifdef CONFIG_REMOTE_DEBUG
+	/* If local serial I/O used for debug port, enter kgdb at once */
+//      puts("Waiting for kgdb to connect...");
+	set_debug_traps();
+	breakpoint();
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/irq_handler.S linux/arch/mips/sibyte/sb1250/irq_handler.S
--- linux.orig/arch/mips/sibyte/sb1250/irq_handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/irq_handler.S	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+ 
+/*
+ * sb1250_handle_int() is the routine that is actually called when an interrupt
+ * occurs.  It is installed as the exception vector handler in init_IRQ() in
+ * arch/mips/sibyte/sb1250/irq.c
+ *
+ * In the handle we figure out which interrupts need handling, and use that to
+ * call the dispatcher, which will take care of actually calling registered
+ * handlers 
+ * 
+ * Note that we take care of all raised interrupts in one go at the handler.
+ * This is more BSDish than the Indy code, and also, IMHO, more sane. 
+ */
+#include <linux/config.h>
+
+#include <asm/addrspace.h>
+#include <asm/processor.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+
+/* 
+ * What a pain. We have to be really careful saving the upper 32 bits of any
+ * register across function calls if we don't want them trashed--since were 
+ * running in -o32, the calling routing never saves the full 64 bits of a
+ * register across a function call.  Being the interrupt handler, we're
+ * guaranteed that interrupts are disabled during this code so we don't have
+ * to worry about random interrupts blasting the high 32 bits.
+ */
+ 
+	.text
+	.set	push
+	.set	noreorder
+	.set	noat
+	#.set	mips64
+	.set	mips4
+	.align	5
+	NESTED(sb1250_irq_handler, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+	/* Set compare to count to silence count/compare timer interrupts */
+	mfc0	t1, CP0_COUNT
+	mtc0	t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
+#endif
+	/* Read cause */
+	mfc0	s0, CP0_CAUSE
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+	/* Cpu performance counter interrupt is routed to IP[7] */
+	andi	t1, s0, CAUSEF_IP7
+	beqz	t1, 0f
+	 srl	t1, s0, (CAUSEB_BD-2)  /* Shift BD bit to bit 2 */
+	and	t1, t1, 0x4		/* mask to get just BD bit */
+	mfc0	a0, CP0_EPC
+	jal	sbprof_cpu_intr
+	 addu	a0, a0, t1		/* a0 = EPC + (BD ? 4 :	0) */
+	j	ret_from_irq
+	 nop				# delay slot
+0:
+#endif
+	/* Timer interrupt is routed to IP[4] */
+	andi	t1, s0, CAUSEF_IP4
+	beqz	t1, 1f
+	 nop
+	jal	sb1250_timer_interrupt
+	 move	a0, sp			/* Pass the registers along */
+	j	ret_from_irq
+	 nop				# delay slot
+1:
+
+#ifdef CONFIG_SMP
+	/* Mailbox interrupt is routed to IP[3] */
+	andi	 t1, s0, CAUSEF_IP3
+	beqz	 t1, 2f
+         nop
+	jal	 sb1250_mailbox_interrupt
+	 move    a0, sp		
+	j	ret_from_irq
+	 nop				# delay slot
+2:
+#endif
+
+	and      t1, s0, CAUSEF_IP2
+	beqz     t1, 4f
+	 nop
+
+	/*
+	 * Default...we've hit an IP[2] interrupt, which means we've got to
+	 * check the 1250 interrupt registers to figure out what to do
+	 */
+	la	v0, KSEG1 + A_IMR_CPU0_BASE
+	ld	s0, R_IMR_INTERRUPT_STATUS_BASE(v0)	/* read IP[2] status */
+
+	beqz	s0, 4f		/* No interrupts.  Return */
+	 move	a1, sp
+
+3:	#dclz	s1, s0		/* Find the next interrupt */
+	.word   0x72118824	# dclz s1, s0
+	dsubu	a0, zero, s1
+	daddiu	a0, a0, 63     
+	jal	 do_IRQ
+	 nop
+
+4:	j        ret_from_irq
+	 nop
+
+	.set pop
+	END(sb1250_irq_handler)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/lib_hssubr.S linux/arch/mips/sibyte/sb1250/lib_hssubr.S
--- linux.orig/arch/mips/sibyte/sb1250/lib_hssubr.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/lib_hssubr.S	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+#include <asm/asm.h>
+#include <asm/addrspace.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+
+		 .set mips64
+
+#define HAZARD SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP 
+
+
+/*  *********************************************************************
+    *  hs_read8 - read 8-bit bytes
+    ********************************************************************* */
+
+
+LEAF(hs_read8)
+		mfc0	t2, CP0_STATUS
+		or	t1, t2, ST0_KX
+		mtc0	t1, CP0_STATUS
+		HAZARD
+
+		dli	v0, PHYS_TO_XKSEG_UNCACHED(0)
+		dsll	a0, a0, 32
+		dsrl	a0, a0, 32
+		or	a0, a0,v0
+		lb	v0, (a0)
+		and	v0, 0xFF
+
+		mtc0	t2, CP0_STATUS
+		HAZARD
+		j	ra
+END(hs_read8)
+
+/*  *********************************************************************
+    *  hs_read16 - read 16-bit shorts
+    ********************************************************************* */
+
+LEAF(hs_read16)
+		mfc0	t2, CP0_STATUS
+		or	t1, t2, ST0_KX
+		mtc0	t1, CP0_STATUS
+		HAZARD
+
+		dli	v0, PHYS_TO_XKSEG_UNCACHED(0)
+		dsll	a0, a0, 32
+		dsrl	a0, a0, 32
+		or	a0, a0, v0
+		lh	v0, (a0)
+		and	v0, 0xFFFF
+
+		mtc0	t2, CP0_STATUS
+		HAZARD
+		j	ra
+END(hs_read16)
+
+/*  *********************************************************************
+    *  hs_read32 - read 32-bit ints
+    ********************************************************************* */
+
+LEAF(hs_read32)
+		mfc0	t2, CP0_STATUS
+		or	t1, t2, ST0_KX
+		mtc0	t1, CP0_STATUS
+		HAZARD
+
+		dli	v0, PHYS_TO_XKSEG_UNCACHED(0)
+		dsll	a0, a0, 32
+		dsrl	a0, a0, 32
+		or	a0, a0, v0
+		lw	v0, (a0)
+		and	v0, 0xFFFFFFFF
+
+		mtc0	t2, CP0_STATUS
+		HAZARD
+		j	ra
+END(hs_read32)
+
+/*  *********************************************************************
+    *  hs_read64 - read 64-bit longs
+    ********************************************************************* */
+
+LEAF(hs_read64)
+		mfc0	t2, CP0_STATUS
+		or	t1, t2, ST0_KX
+		mtc0	t1, CP0_STATUS
+		HAZARD
+
+		dli	v0, PHYS_TO_XKSEG_UNCACHED(0)
+		dsll	a0, a0, 32
+		dsrl	a0, a0, 32
+		or	a0, a0, v0
+		ld	v0, (a0)
+
+		mtc0	t2, CP0_STATUS
+		HAZARD
+		j	ra
+END(hs_read64)
+
+/*  *********************************************************************
+    *  hs_write8 - write 8-bit bytes
+    ********************************************************************* */
+
+LEAF(hs_write8)
+		mfc0	t2, CP0_STATUS
+		or	t1, t2, ST0_KX
+		mtc0	t1, CP0_STATUS
+		HAZARD
+
+		dli	v0, PHYS_TO_XKSEG_UNCACHED(0)
+		dsll	a0, a0, 32
+		dsrl	a0, a0, 32
+		or	a0, a0, v0
+		sb	a1, (a0)
+
+		mtc0	t2, CP0_STATUS
+		HAZARD
+		j	ra
+END(hs_write8)
+
+/*  *********************************************************************
+    *  hs_write16 - write 16-bit shorts
+    ********************************************************************* */
+
+LEAF(hs_write16)
+		mfc0	t2, CP0_STATUS
+		or	t1, t2, ST0_KX
+		mtc0	t1, CP0_STATUS
+		HAZARD
+
+		dli	v0, PHYS_TO_XKSEG_UNCACHED(0)
+		dsll	a0, a0, 32
+		dsrl	a0, a0, 32
+		or	a0, a0, v0
+		sh	a1, (a0)
+
+		mtc0	t2, CP0_STATUS
+		HAZARD
+		j	ra
+END(hs_write16)
+
+/*  *********************************************************************
+    *  hs_write32 - write 32-bit longs
+    ********************************************************************* */
+
+LEAF(hs_write32)
+		mfc0	t2, CP0_STATUS
+		or	t1, t2, ST0_KX
+		mtc0	t1, CP0_STATUS
+		HAZARD
+
+		dli	v0, PHYS_TO_XKSEG_UNCACHED(0)
+		dsll	a0, a0, 32
+		dsrl	a0, a0, 32
+		or	a0, a0, v0
+		sw	a1, (a0)
+
+		mtc0	t2, CP0_STATUS
+		HAZARD
+		j	ra
+END(hs_write32)
+
+/*  *********************************************************************
+    *  hs_write64 - write 64-bit longs
+    ********************************************************************* */
+
+LEAF(hs_write64)
+		mfc0	t2, CP0_STATUS
+		or	t1, t2, ST0_KX
+		mtc0	t1, CP0_STATUS
+		HAZARD
+
+		dli	v0, PHYS_TO_XKSEG_UNCACHED(0)
+		dsll	a0, a0, 32
+		dsrl	a0, a0, 32
+		or	a0, a0, v0
+		sd	a1, (a0)
+
+		mtc0	t2, CP0_STATUS
+		HAZARD
+		j	ra
+END(hs_write64)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/lib_hssubr.h linux/arch/mips/sibyte/sb1250/lib_hssubr.h
--- linux.orig/arch/mips/sibyte/sb1250/lib_hssubr.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/lib_hssubr.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+#ifndef _LIB_HSSUBR_H
+#define _LIB_HSSUBR_H
+
+/*
+ * If __long64 we can do this via macros.  Otherwise, call
+ * the magic functions.
+ */
+
+#if __long64
+
+typedef long hsaddr_t;
+
+#define hs_write8(a,b) *((volatile uint8_t *) (a)) = (b)
+#define hs_write16(a,b) *((volatile uint16_t *) (a)) = (b)
+#define hs_write32(a,b) *((volatile uint32_t *) (a)) = (b)
+#define hs_write64(a,b) *((volatile uint32_t *) (a)) = (b)
+#define hs_read8(a) *((volatile uint8_t *) (a))
+#define hs_read16(a) *((volatile uint16_t *) (a))
+#define hs_read32(a) *((volatile uint32_t *) (a))
+#define hs_read64(a) *((volatile uint64_t *) (a))
+
+#else	/* not __long64 */
+
+typedef long hsaddr_t;
+
+extern void hs_write8(hsaddr_t a,uint8_t b);
+extern void hs_write16(hsaddr_t a,uint16_t b);
+extern void hs_write32(hsaddr_t a,uint32_t b);
+extern void hs_write64(hsaddr_t a,uint64_t b);
+extern uint8_t hs_read8(hsaddr_t a);
+extern uint16_t hs_read16(hsaddr_t a);
+extern uint32_t hs_read32(hsaddr_t a);
+extern uint64_t hs_read64(hsaddr_t a);
+#endif
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/pci.c linux/arch/mips/sibyte/sb1250/pci.c
--- linux.orig/arch/mips/sibyte/sb1250/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/pci.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+/*
+ * SB1250-specific PCI support
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware.  We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ * 
+ * To access configuration space, we call some assembly-level
+ * stubs that flip the KX bit on and off in the status
+ * register, and do XKSEG addressed memory accesses there.
+ * It's slow (7 SSNOPs to guarantee that KX is set!) but
+ * fortunately, config space accesses are rare.
+ *
+ * We could use the ioremap functionality for the confguration
+ * space as well as I/O space, but I'm not sure of the
+ * implications of setting aside 16MB of KSEG2 for something
+ * that is used so rarely (how much space in the page tables?)
+ *
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/io.h>
+
+#include "lib_hssubr.h"
+
+/*
+ * This macro calculates the offset into config space where
+ * a given bus, device/function, and offset live on the sb1250
+ */
+
+#define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
+
+/*
+ * Using the above offset, this macro calcuates the actual
+ * address.  Note that the physical address is not accessible
+ * without remapping or setting KX.  We use 'match bits'
+ * as our endian policy to guarantee that 32-bit accesses
+ * look the same from either endianness.
+ */
+#define CFGADDR(dev,where) (A_PHYS_LDTPCI_CFG_MATCH_BITS + \
+			    CFGOFFSET(dev->bus->number,dev->devfn,where))
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+
+#define READCFG32(addr) hs_read32((addr)&~3)
+#define WRITECFG32(addr,data) hs_write32(((addr)&~3),(data))
+
+/*
+ * This variable is the KSEG2 (kernel virtual) mapping
+ * of the ISA/PCI I/O space area.  We map 64K here and
+ * the offsets from this address get treated with "match bytes" 
+ * policy to make everything look little-endian.  So, 
+ * you need to also set CONFIG_SWAP_IO_SPACE, but this is the 
+ * combination that works correctly with most of Linux's drivers.
+ */
+
+#define PCI_BUS_ENABLED	1
+#define LDT_BUS_ENABLED	2
+
+static int sb1250_bus_status = 0;
+
+#define MATCH_BITS	0x20000000	/* really belongs in an include file */
+
+#define LDT_BRIDGE_START ((A_PCI_TYPE01_HEADER|MATCH_BITS)+0x00)
+#define LDT_BRIDGE_END   ((A_PCI_TYPE01_HEADER|MATCH_BITS)+0x20)
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space.
+ */
+
+static int
+sb1250_pci_read_config_byte(struct pci_dev *dev, int where, u8 * val)
+{
+	u32 data = 0;
+	u32 cfgaddr = CFGADDR(dev, where);
+
+	data = READCFG32(cfgaddr);
+
+	/*
+	 * If the LDT was not configured, make it look like the bridge
+	 * header is not there.
+	 */
+	if (!(sb1250_bus_status & LDT_BUS_ENABLED) &&
+	    (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) {
+		data = 0xFFFFFFFF;
+	}
+
+	*val = (data >> ((where & 3) << 3)) & 0xff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+sb1250_pci_read_config_word(struct pci_dev *dev, int where, u16 * val)
+{
+	u32 data = 0;
+	u32 cfgaddr = CFGADDR(dev, where);
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = READCFG32(cfgaddr);
+
+	/*
+	 * If the LDT was not configured, make it look like the bridge
+	 * header is not there.
+	 */
+	if (!(sb1250_bus_status & LDT_BUS_ENABLED) &&
+	    (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) {
+		data = 0xFFFFFFFF;
+	}
+
+	*val = (data >> ((where & 3) << 3)) & 0xffff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+sb1250_pci_read_config_dword(struct pci_dev *dev, int where, u32 * val)
+{
+	u32 data = 0;
+	u32 cfgaddr = CFGADDR(dev, where);
+
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+
+	data = READCFG32(cfgaddr);
+
+	/*
+	 * If the LDT was not configured, make it look like the bridge
+	 * header is not there.
+	 */
+	if (!(sb1250_bus_status & LDT_BUS_ENABLED) &&
+	    (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) {
+		data = 0xFFFFFFFF;
+	}
+
+	*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+sb1250_pci_write_config_byte(struct pci_dev *dev, int where, u8 val)
+{
+	u32 data = 0;
+	u32 cfgaddr = CFGADDR(dev, where);
+
+	data = READCFG32(cfgaddr);
+
+	data = (data & ~(0xff << ((where & 3) << 3))) |
+	    (val << ((where & 3) << 3));
+
+	WRITECFG32(cfgaddr, data);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+sb1250_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+	u32 data = 0;
+	u32 cfgaddr = CFGADDR(dev, where);
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = READCFG32(cfgaddr);
+
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
+	    (val << ((where & 3) << 3));
+
+	WRITECFG32(cfgaddr, data);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+sb1250_pci_write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	u32 cfgaddr = CFGADDR(dev, where);
+
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	WRITECFG32(cfgaddr, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops sb1250_pci_ops = {
+	sb1250_pci_read_config_byte,
+	sb1250_pci_read_config_word,
+	sb1250_pci_read_config_dword,
+	sb1250_pci_write_config_byte,
+	sb1250_pci_write_config_word,
+	sb1250_pci_write_config_dword
+};
+
+
+void __init pcibios_init(void)
+{
+	uint32_t cmdreg;
+
+	/*
+	 * See if the PCI bus has been configured by the firmware.
+	 */
+
+	cmdreg = READCFG32((A_PCI_TYPE00_HEADER | MATCH_BITS) + PCI_COMMAND);
+
+	if (!(cmdreg & PCI_COMMAND_MASTER)) {
+		printk
+		    ("PCI: Skipping PCI probe.  Bus is not initialized.\n");
+		return;
+	}
+
+	sb1250_bus_status |= PCI_BUS_ENABLED;
+
+	/* 
+	 * Establish a mapping from KSEG2 (kernel virtual) to PCI I/O space 
+	 * Use "match bytes", even though this exposes endianness.
+	 * big-endian Linuxes will have CONFIG_SWAP_IO_SPACE set.
+	 */
+
+	set_io_port_base(ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536));
+
+	/*
+	 * Also check the LDT bridge's enable, just in case we didn't
+	 * initialize that one.
+	 */
+
+	cmdreg = READCFG32((A_PCI_TYPE01_HEADER | MATCH_BITS) + PCI_COMMAND);
+
+	if (cmdreg & PCI_COMMAND_MASTER) {
+		sb1250_bus_status |= LDT_BUS_ENABLED;
+	}
+
+	/* Probe for PCI hardware */
+
+	printk("PCI: Probing PCI hardware on host bus 0.\n");
+	pci_scan_bus(0, &sb1250_pci_ops, NULL);
+
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	/* Not needed, since we enable all devices at startup.  */
+	return 0;
+}
+
+void pcibios_align_resource(void *data, struct resource *res,
+                            unsigned long size)
+{
+}
+
+char *__init pcibios_setup(char *str)
+{
+	/* Nothing to do for now.  */
+
+	return str;
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{0}
+};
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	unsigned long where, size;
+	u32 reg;
+
+	where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	size = res->end - res->start;
+	pci_read_config_dword(dev, where, &reg);
+	reg = (reg & size) | (((u32) (res->start - root->start)) & ~size);
+	pci_write_config_dword(dev, where, reg);
+}
+
+/*
+ *  Called after each bus is probed, but before its children
+ *  are examined.
+ */
+void pcibios_fixup_bus(struct pci_bus *b)
+{
+	pci_read_bridge_bases(b);
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/setup.c linux/arch/mips/sibyte/sb1250/setup.c
--- linux.orig/arch/mips/sibyte/sb1250/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/setup.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/* Setup code likely to be common to all SB1250 platforms */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/hdreg.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/utsname.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/bootmem.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/ide.h>
+#ifdef CONFIG_RTC
+#include <linux/timex.h>
+#endif
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/stackframe.h>
+#include <asm/system.h>
+#include <asm/cpu.h>
+#include <asm/mmu_context.h>
+#include <asm/sibyte/swarm.h>
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250_regs.h>
+ 
+
+/* 
+ *
+ */
+
+
+void sb1250_setup(void)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/smp.c linux/arch/mips/sibyte/sb1250/smp.c
--- linux.orig/arch/mips/sibyte/sb1250/smp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/smp.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+#include <asm/sibyte/64bit.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/addrspace.h>
+#include <asm/smp.h>
+#include <linux/sched.h>
+
+/*
+ * These are routines for dealing with the sb1250 smp capabilities
+ * independent of board/firmware
+ */
+
+static u64 mailbox_set_regs[] = {
+	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU, 
+	KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU
+};
+
+static u64 mailbox_clear_regs[] = {
+	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU, 
+	KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU
+};
+
+static u64 mailbox_regs[] = {
+	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU, 
+	KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU
+};
+
+
+/*
+ * Simple enough; everything is set up, so just poke the appropriate mailbox
+ * register, and we should be set
+ */
+void core_send_ipi(int cpu, unsigned int action)
+{
+	out64((((u64)action)<< 48), mailbox_set_regs[cpu]);
+}
+
+
+void sb1250_smp_finish(void)
+{
+	extern void sb1_sanitize_tlb(void);
+
+	sb1_sanitize_tlb();
+	sb1250_time_init();
+}
+
+void sb1250_mailbox_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	unsigned int action;
+	
+	/* Load the mailbox register to figure out what we're supposed to do */
+	action = (in64(mailbox_regs[cpu]) >> 48) & 0xffff;
+
+	/* Clear the mailbox to clear the interrupt */
+	out64(((u64)action)<<48, mailbox_clear_regs[cpu]);
+
+	/*
+	 * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
+	 * interrupt will do the reschedule for us
+	 */
+
+	if (action & SMP_CALL_FUNCTION) {
+		smp_call_function_interrupt();
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/sb1250/time.c linux/arch/mips/sibyte/sb1250/time.c
--- linux.orig/arch/mips/sibyte/sb1250/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/sb1250/time.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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 routines to set up and handle interrupts from the
+ * sb1250 general purpose timer 0.  We're using the timer as a
+ * system clock, so we set it up to run at 100 Hz.  On every
+ * interrupt, we update our idea of what the time of day is, 
+ * then call do_timer() in the architecture-independent kernel
+ * code to do general bookkeeping (e.g. update jiffies, run
+ * bottom halves, etc.)
+ */
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/addrspace.h>
+#include <asm/time.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/64bit.h>
+
+
+#define IMR_IP2_VAL	K_INT_MAP_I0
+#define IMR_IP3_VAL	K_INT_MAP_I1
+#define IMR_IP4_VAL	K_INT_MAP_I2
+
+void sb1250_time_init(void)
+{
+	int cpu = smp_processor_id();
+
+	/* Only have 4 general purpose timers */
+	if (cpu > 3) {
+		BUG();
+	}
+
+	sb1250_mask_irq(cpu, K_INT_TIMER_0 + cpu);
+	
+	/* Map the timer interrupt to ip[4] of this cpu */
+	out64(IMR_IP4_VAL, KSEG1 + A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) 
+	      + ((K_INT_TIMER_0 + cpu)<<3)); 
+
+	/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
+	/* Disable the timer and set up the count */
+	out64(0, KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+	out64(
+#ifndef CONFIG_SIMULATION
+		1000000/HZ
+#else
+		50000/HZ
+#endif
+		, KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+
+	/* Set the timer running */
+	out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+
+	sb1250_unmask_irq(cpu, K_INT_TIMER_0 + cpu);
+	/*
+	 * This interrupt is "special" in that it doesn't use the request_irq
+	 * way to hook the irq line.  The timer interrupt is initialized early
+	 * enough to make this a major pain, and it's also firing enough to
+	 * warrant a bit of special case code.  sb1250_timer_interrupt is
+	 * called directly from irq_handler.S when IP[4] is set during an
+	 * interrupt
+	 */
+}
+
+void sb1250_timer_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+
+	/* Reset the timer */
+	out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));  
+
+	/*
+	 * CPU 0 handles the global timer interrupt job
+	 */
+	if (cpu == 0) {
+		ll_timer_interrupt(0, regs);
+	}
+
+	/*
+	 * every CPU should do profiling and process accouting
+	 */
+	ll_local_timer_interrupt(0, regs);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/Makefile linux/arch/mips/sibyte/swarm/Makefile
--- linux.orig/arch/mips/sibyte/swarm/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/Makefile	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,30 @@
+USE_STANDARD_AS_RULE := true
+
+all: sbswarm.a
+
+OBJS-y                   = setup.o cmdline.o memory.o cfe_api.o rtc_xicor1241.o
+
+OBJS-$(CONFIG_SMP)      += smp.o
+
+OBJS-$(CONFIG_L3DEMO)   += procl3switch.o l3procbootstrap.o l3proc.o
+OBJS-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
+
+#XMITTER=1
+
+ifdef XMITTER
+l3proc.bin: xmitter
+	ln xmitter l3proc.bin
+else
+l3proc.bin: l3proc
+	ln l3proc l3proc.bin
+endif
+
+l3proc.o: l3proc.bin
+	mips-linux-ld -Tl3proc.lds -bbinary -o l3proc.o l3proc.bin
+
+sbswarm.a: $(OBJS-y)
+	$(AR) rcs sbswarm.a $^
+	rm -f l3proc.o l3proc.bin
+
+include $(TOPDIR)/Rules.make
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/cfe_api.c linux/arch/mips/sibyte/swarm/cfe_api.c
--- linux.orig/arch/mips/sibyte/swarm/cfe_api.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/cfe_api.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/*  *********************************************************************
+    *  Broadcom Common Firmware Environment (CFE)
+    *  
+    *  Device Function stubs			File: cfe_api.c
+    *  
+    *  This module contains device function stubs (small routines to
+    *  call the standard "iocb" interface entry point to CFE).
+    *  There should be one routine here per iocb function call.
+    *  
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
+    *  
+    ********************************************************************* */
+
+
+#include "cfe_xiocb.h"
+#include "cfe_api.h"
+#include <linux/string.h>
+
+static long cfe_console_handle = -1;
+static int (*cfe_dispfunc)(long handle,cfe_xiocb_t *xiocb) = 0;
+static cfe_xuint_t cfe_handle = 0;
+
+/*
+ * This macro makes a "signed 64-bit pointer" - basically extending a regular
+ * pointer to its 64-bit compatibility space equivalent. 
+ */
+#define BIGPTR(x) (long long) (long) (x)
+
+typedef unsigned long intptr_t;
+
+int cfe_init(cfe_xuint_t handle)
+{
+	unsigned int *sealloc = (unsigned int *) (intptr_t) (int)  CFE_APISEAL;
+	if (*sealloc != CFE_EPTSEAL) return -1;
+	cfe_dispfunc = (void *) (cfe_xptr_t) (int) CFE_APIENTRY;
+	if (handle) cfe_handle = handle;
+	return 0;
+}
+
+int cfe_iocb_dispatch(cfe_xiocb_t *xiocb);
+int cfe_iocb_dispatch(cfe_xiocb_t *xiocb)
+{
+	if (!cfe_dispfunc) return -1;
+	return (*cfe_dispfunc)(cfe_handle,xiocb);
+}
+
+static int cfe_strlen(char *name)
+{
+	int count = 0;
+	
+	while (*name) {
+		count++;
+		name++;
+	}
+	
+	return count;
+}
+
+int cfe_open(char *name)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = 0;
+	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(name);
+	xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle;
+}
+
+int cfe_close(int handle)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = 0;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return (xiocb.xiocb_status);
+	
+}
+
+int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = offset;
+	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen;
+}
+
+int cfe_read(int handle,unsigned char *buffer,int length)
+{
+	return cfe_readblk(handle,0,buffer,length);
+}
+
+
+int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = offset;
+	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen;
+}
+
+int cfe_write(int handle,unsigned char *buffer,int length)
+{
+	return cfe_writeblk(handle,0,buffer,length);
+}
+
+
+int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_ioctlcmd = (cfe_xint_t) ioctlnum;
+	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	if (retlen) *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
+	return xiocb.xiocb_status;
+}
+
+int cfe_inpstat(int handle)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_inpstat_t);
+	xiocb.plist.xiocb_inpstat.inp_status = 0;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	if (xiocb.xiocb_status < 0) return xiocb.xiocb_status;
+	
+	return xiocb.plist.xiocb_inpstat.inp_status;
+	
+}
+
+long long cfe_getticks(void)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_time_t);
+	xiocb.plist.xiocb_time.ticks = 0;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return xiocb.plist.xiocb_time.ticks;
+	
+}
+
+int cfe_getenv(char *name,char *dest,int destlen)
+{
+	cfe_xiocb_t xiocb;
+	
+	*dest = 0;
+	
+	xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = 0;
+	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
+	xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
+	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(dest);
+	xiocb.plist.xiocb_envbuf.val_length = destlen;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return xiocb.xiocb_status;
+}
+
+int cfe_setenv(char *name,char *val)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = 0;
+	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
+	xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
+	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val);
+	xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val);
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return xiocb.xiocb_status;
+}
+
+int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type)
+{
+	cfe_xiocb_t xiocb;
+	xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_meminfo_t);
+	xiocb.plist.xiocb_meminfo.mi_idx = idx;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	(*addr) = xiocb.plist.xiocb_meminfo.mi_addr;
+	(*size) = xiocb.plist.xiocb_meminfo.mi_size;
+	(*type) = xiocb.plist.xiocb_meminfo.mi_type;
+
+	return xiocb.xiocb_status;
+}
+
+
+int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = idx;
+	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
+	xiocb.plist.xiocb_envbuf.name_length = namelen;
+	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val);
+	xiocb.plist.xiocb_envbuf.val_length = vallen;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return xiocb.xiocb_status;
+}
+
+int cfe_exit(int warm, int status)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
+	xiocb.xiocb_psize = sizeof(xiocb_exitstat_t);
+	xiocb.plist.xiocb_exitstat.status = (cfe_xint_t) status;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return (xiocb.xiocb_status);
+}
+
+int cfe_flushcache(int flg)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = flg;
+	xiocb.xiocb_psize = 0;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return xiocb.xiocb_status;
+}
+
+int cfe_getstdhandle(int flg)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = flg;
+	xiocb.xiocb_psize = 0;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle;
+	
+}
+
+int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags  = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
+	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
+	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
+	xiocb.plist.xiocb_cpuctl.gp_val = gp;
+	xiocb.plist.xiocb_cpuctl.sp_val = sp;
+	xiocb.plist.xiocb_cpuctl.a1_val = a1;
+	xiocb.plist.xiocb_cpuctl.start_addr = (long)fn;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return xiocb.xiocb_status;
+}
+
+
+int cfe_stop_cpu(int cpu)
+{
+	cfe_xiocb_t xiocb;
+	
+	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags  = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
+	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
+	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
+	
+	cfe_iocb_dispatch(&xiocb);
+	
+	return xiocb.xiocb_status;
+}
+
+void cfe_open_console()
+{
+	cfe_console_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
+}
+
+void cfe_console_print(char *str)
+{
+	int len = strlen(str);
+	int res;
+
+	if (cfe_console_handle != -1) {
+		do {
+			res = cfe_writeblk(cfe_console_handle, 0, str, len);
+			if (res < 0)
+				break;
+			str += res;
+			len -= res;
+		} while (len);
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/cfe_api.h linux/arch/mips/sibyte/swarm/cfe_api.h
--- linux.orig/arch/mips/sibyte/swarm/cfe_api.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/cfe_api.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/*  *********************************************************************
+    *  Broadcom Common Firmware Environment (CFE)
+    *  
+    *  Device function prototypes		File: cfe_api.h
+    *  
+    *  This module contains prototypes for cfe_devfuncs.c, a set
+    *  of wrapper routines to the IOCB interface.  This file,
+    *  along with cfe_api.c, can be incorporated into programs
+    *  that need to call CFE.
+    *  
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
+    *  
+    ********************************************************************* */
+
+
+#define CFE_EPTSEAL 0x43464531
+#define CFE_APIENTRY 0x9FC00500
+#define CFE_APISEAL  0x9FC00508
+
+#ifndef __ASSEMBLY__
+int cfe_init(cfe_xuint_t handle);
+int cfe_open(char *name);
+int cfe_close(int handle);
+int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length);
+int cfe_read(int handle,unsigned char *buffer,int length);
+int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length);
+int cfe_write(int handle,unsigned char *buffer,int length);
+int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen);
+int cfe_inpstat(int handle);
+int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen);
+int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type);
+int cfe_setenv(char *name,char *val);
+int cfe_getenv(char *name,char *dest,int destlen);
+long long cfe_getticks(void);
+int cfe_exit(int warm, int status);
+int cfe_flushcache(int flg);
+int cfe_getstdhandle(int flg);
+int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1);
+int cfe_stop_cpu(int cpu);
+
+void cfe_open_console(void);
+void cfe_console_print(char *);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/cfe_error.h linux/arch/mips/sibyte/swarm/cfe_error.h
--- linux.orig/arch/mips/sibyte/swarm/cfe_error.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/cfe_error.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/*  *********************************************************************
+    *  Broadcom Common Firmware Environment (CFE)
+    *  
+    *  Error codes				File: cfe_error.h
+    *  
+    *  CFE's global error code list is here.
+    *  
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
+    *  
+    ********************************************************************* */
+
+
+
+
+#define CFE_OK			 0
+#define CFE_ERR                 -1	/* generic error */
+#define CFE_ERR_INV_COMMAND	-2
+#define CFE_ERR_EOF		-3
+#define CFE_ERR_IOERR		-4
+#define CFE_ERR_NOMEM		-5
+#define CFE_ERR_DEVNOTFOUND	-6
+#define CFE_ERR_DEVOPEN		-7
+#define CFE_ERR_INV_PARAM	-8
+#define CFE_ERR_ENVNOTFOUND	-9
+#define CFE_ERR_ENVREADONLY	-10
+
+#define CFE_ERR_NOTELF		-11
+#define CFE_ERR_NOT32BIT 	-12
+#define CFE_ERR_WRONGENDIAN 	-13
+#define CFE_ERR_BADELFVERS 	-14
+#define CFE_ERR_NOTMIPS 	-15
+#define CFE_ERR_BADELFFMT 	-16
+#define CFE_ERR_BADADDR 	-17
+
+#define CFE_ERR_FILENOTFOUND	-18
+#define CFE_ERR_UNSUPPORTED	-19
+
+#define CFE_ERR_HOSTUNKNOWN	-20
+
+#define CFE_ERR_TIMEOUT		-21
+
+#define CFE_ERR_PROTOCOLERR	-22
+
+#define CFE_ERR_NETDOWN		-23
+#define CFE_ERR_NONAMESERVER	-24
+
+#define CFE_ERR_NOHANDLES	-25
+#define CFE_ERR_ALREADYBOUND	-26
+
+#define CFE_ERR_CANNOTSET	-27
+#define CFE_ERR_NOMORE		-28
+#define CFE_ERR_BADFILESYS	-29
+#define CFE_ERR_FSNOTAVAIL	-30
+
+#define CFE_ERR_INVBOOTBLOCK	-31
+#define CFE_ERR_WRONGDEVTYPE	-32
+#define CFE_ERR_BBCHECKSUM	-33
+#define CFE_ERR_BOOTPROGCHKSUM	-34
+
+
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/cfe_xiocb.h linux/arch/mips/sibyte/swarm/cfe_xiocb.h
--- linux.orig/arch/mips/sibyte/swarm/cfe_xiocb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/cfe_xiocb.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/*  *********************************************************************
+    *  Broadcom Common Firmware Environment (CFE)
+    *  
+    *  IOCB definitions				File: cfe_iocb.h
+    *  
+    *  This module describes CFE's IOCB structure, the main
+    *  data structure used to communicate API requests with CFE.
+    *  
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
+    *  
+    ********************************************************************* */
+
+/*  *********************************************************************
+    *  Constants
+    ********************************************************************* */
+
+#define CFE_CMD_FW_GETINFO	0
+#define CFE_CMD_FW_RESTART	1
+#define CFE_CMD_FW_BOOT		2
+#define CFE_CMD_FW_CPUCTL	3
+#define CFE_CMD_FW_GETTIME      4
+#define CFE_CMD_FW_MEMENUM	5
+#define CFE_CMD_FW_FLUSHCACHE	6
+
+#define CFE_CMD_DEV_GETHANDLE	9
+#define CFE_CMD_DEV_ENUM	10
+#define CFE_CMD_DEV_OPEN	11
+#define CFE_CMD_DEV_INPSTAT	12
+#define CFE_CMD_DEV_READ	13
+#define CFE_CMD_DEV_WRITE	14
+#define CFE_CMD_DEV_IOCTL	15
+#define CFE_CMD_DEV_CLOSE	16
+#define CFE_CMD_DEV_GETINFO	17
+
+#define CFE_CMD_ENV_ENUM	20
+#define CFE_CMD_ENV_GET		22
+#define CFE_CMD_ENV_SET		23
+#define CFE_CMD_ENV_DEL		24
+
+#define CFE_CMD_MAX		32
+
+#define CFE_MI_RESERVED	0		/* memory is reserved, do not use */
+#define CFE_MI_AVAILABLE 1		/* memory is available */
+
+#define CFE_FLG_WARMSTART 0x00000001
+
+#define CFE_FLG_ENV_PERMANENT 0x00000001
+
+#define CFE_CPU_CMD_START 1
+#define CFE_CPU_CMD_STOP 0
+
+#define CFE_STDHANDLE_CONSOLE	0
+
+#define CFE_DEV_NETWORK 	1
+#define CFE_DEV_DISK		2
+#define CFE_DEV_FLASH		3
+#define CFE_DEV_SERIAL		4
+#define CFE_DEV_CPU		5
+#define CFE_DEV_NVRAM		6
+#define CFE_DEV_OTHER		7
+#define CFE_DEV_MASK		0x0F
+
+#define CFE_CACHE_FLUSH_D	1
+#define CFE_CACHE_INVAL_I	2
+#define CFE_CACHE_INVAL_D	4
+#define CFE_CACHE_INVAL_L2	8
+
+/*  *********************************************************************
+    *  Structures
+    ********************************************************************* */
+
+typedef unsigned long long cfe_xuint_t;
+typedef long long cfe_xint_t;
+typedef long long cfe_xptr_t;
+
+typedef struct xiocb_buffer_s {
+    cfe_xuint_t   buf_offset;		/* offset on device (bytes) */
+    cfe_xptr_t 	  buf_ptr;		/* pointer to a buffer */
+    cfe_xuint_t   buf_length;		/* length of this buffer */
+    cfe_xuint_t   buf_retlen;		/* returned length (for read ops) */
+    cfe_xuint_t   buf_ioctlcmd;		/* IOCTL command (used only for IOCTLs) */
+} xiocb_buffer_t;
+
+#define buf_devflags buf_ioctlcmd	/* returned device info flags */
+
+typedef struct xiocb_inpstat_s {
+    cfe_xuint_t inp_status;		/* 1 means input available */
+} xiocb_inpstat_t;
+
+typedef struct xiocb_envbuf_s {
+    cfe_xint_t enum_idx;		/* 0-based enumeration index */
+    cfe_xptr_t name_ptr;		/* name string buffer */
+    cfe_xint_t name_length;		/* size of name buffer */
+    cfe_xptr_t val_ptr;			/* value string buffer */
+    cfe_xint_t val_length;		/* size of value string buffer */
+} xiocb_envbuf_t;
+
+typedef struct xiocb_cpuctl_s {
+    cfe_xuint_t  cpu_number;		/* cpu number to control */
+    cfe_xuint_t  cpu_command;		/* command to issue to CPU */
+    cfe_xuint_t  start_addr;		/* CPU start address */
+    cfe_xuint_t  gp_val;		/* starting GP value */
+    cfe_xuint_t  sp_val;		/* starting SP value */
+    cfe_xuint_t  a1_val;		/* starting A1 value */
+} xiocb_cpuctl_t;
+
+typedef struct xiocb_time_s {
+    cfe_xint_t ticks;			/* current time in ticks */
+} xiocb_time_t;
+
+typedef struct xiocb_exitstat_s {
+    cfe_xint_t status;
+} xiocb_exitstat_t;
+
+typedef struct xiocb_meminfo_s {
+    cfe_xint_t  mi_idx;			/* 0-based enumeration index */
+    cfe_xint_t  mi_type;		/* type of memory block */
+    cfe_xuint_t mi_addr;		/* physical start address */
+    cfe_xuint_t mi_size;		/* block size */
+} xiocb_meminfo_t;
+
+#define CFE_FWI_64BIT		0x00000001
+#define CFE_FWI_32BIT		0x00000002
+#define CFE_FWI_RELOC		0x00000004
+#define CFE_FWI_UNCACHED	0x00000008
+#define CFE_FWI_MULTICPU	0x00000010
+#define CFE_FWI_FUNCSIM		0x00000020
+#define CFE_FWI_RTLSIM		0x00000040
+
+typedef struct xiocb_fwinfo_s {
+    cfe_xint_t fwi_version;		/* major, minor, eco version */
+    cfe_xint_t fwi_totalmem;		/* total installed mem */
+    cfe_xint_t fwi_flags;		/* various flags */
+    cfe_xint_t fwi_boardid;		/* board ID */
+    cfe_xint_t fwi_bootarea_va;		/* VA of boot area */
+    cfe_xint_t fwi_bootarea_pa;		/* PA of boot area */
+    cfe_xint_t fwi_bootarea_size;	/* size of boot area */
+    cfe_xint_t fwi_reserved1;
+    cfe_xint_t fwi_reserved2;
+    cfe_xint_t fwi_reserved3;
+} xiocb_fwinfo_t,cfe_fwinfo_t;
+
+typedef struct cfe_xiocb_s {
+    cfe_xuint_t xiocb_fcode;		/* IOCB function code */
+    cfe_xint_t  xiocb_status;		/* return status */
+    cfe_xint_t  xiocb_handle;		/* file/device handle */
+    cfe_xuint_t xiocb_flags;		/* flags for this IOCB */
+    cfe_xuint_t xiocb_psize;		/* size of parameter list */
+    union {
+	xiocb_buffer_t  xiocb_buffer;	/* buffer parameters */
+	xiocb_inpstat_t xiocb_inpstat;	/* input status parameters */
+	xiocb_envbuf_t  xiocb_envbuf;	/* environment function parameters */
+	xiocb_cpuctl_t  xiocb_cpuctl;	/* CPU control parameters */
+	xiocb_time_t    xiocb_time;	/* timer parameters */
+	xiocb_meminfo_t xiocb_meminfo;	/* memory arena info parameters */
+	xiocb_fwinfo_t  xiocb_fwinfo;	/* firmware information */
+	xiocb_exitstat_t xiocb_exitstat; /* Exit status */
+    } plist;
+} cfe_xiocb_t;
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/cmdline.c linux/arch/mips/sibyte/swarm/cmdline.c
--- linux.orig/arch/mips/sibyte/swarm/cmdline.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/cmdline.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+#include <asm/bootinfo.h>
+
+/*
+ * The naming of this variable is a remnant of the initial mips port to
+ * ARC-firmware based SGI consoles.  We don't really need to do anything for
+ * the variable other than provide an instantiation.  Everything about
+ * arcs_cmdline seems more than a little bit hackish...
+ */
+char arcs_cmdline[CL_SIZE];
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/dbg_io.c linux/arch/mips/sibyte/swarm/dbg_io.c
--- linux.orig/arch/mips/sibyte/swarm/dbg_io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/dbg_io.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,78 @@
+/*
+ * kgdb debug routines for swarm board.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * 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.
+ *
+ */
+
+/* -------------------- BEGINNING OF CONFIG --------------------- */
+
+#include <linux/delay.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/64bit.h>
+#include <asm/addrspace.h>
+
+/*
+ * We use the second serial port for kgdb traffic.
+ * 	115200, 8, N, 1.
+ */
+
+#define	BAUD_RATE		115200
+#define	CLK_DIVISOR		V_DUART_BAUD_RATE(BAUD_RATE)
+#define	DATA_BITS		V_DUART_BITS_PER_CHAR_8		/* or 7    */
+#define	PARITY			V_DUART_PARITY_MODE_NONE	/* or even */
+#define	STOP_BITS		M_DUART_STOP_BIT_LEN_1		/* or 2    */
+
+static int duart_initialized = 0;	/* 0: need to be init'ed by kgdb */
+
+/* -------------------- END OF CONFIG --------------------- */
+
+
+#define	duart_out(reg, val)	out64(val, KSEG1 + A_DUART_CHANREG(1,reg))
+#define duart_in(reg)		in64(KSEG1 + A_DUART_CHANREG(1,reg))
+
+extern void set_async_breakpoint(unsigned int epc);
+
+void putDebugChar(unsigned char c);
+unsigned char getDebugChar(void);
+static void
+duart_init(int clk_divisor, int data, int parity, int stop)
+{
+	duart_out(R_DUART_MODE_REG_1, data | parity);
+	duart_out(R_DUART_MODE_REG_2, stop);
+	duart_out(R_DUART_CLK_SEL, clk_divisor);
+
+	duart_out(R_DUART_CMD, M_DUART_RX_EN | M_DUART_TX_EN);	/* enable rx and tx */
+}
+
+void
+putDebugChar(unsigned char c)
+{
+	if (!duart_initialized) {
+		duart_initialized = 1;
+		duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS);
+	}
+	while ((duart_in(R_DUART_STATUS) & M_DUART_TX_RDY) == 0);
+	duart_out(R_DUART_TX_HOLD, c);
+}
+
+unsigned char
+getDebugChar(void)
+{
+	if (!duart_initialized) {
+		duart_initialized = 1;
+		duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS);
+	}
+	while ((duart_in(R_DUART_STATUS) & M_DUART_RX_RDY) == 0) ;
+	return duart_in(R_DUART_RX_HOLD);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/memory.c linux/arch/mips/sibyte/swarm/memory.c
--- linux.orig/arch/mips/sibyte/swarm/memory.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/memory.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/*
+ * Memory related routines 
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/page.h>
+
+extern phys_t swarm_mem_region_addrs[];
+extern phys_t swarm_mem_region_sizes[];
+extern unsigned int swarm_mem_region_count;
+
+int page_is_ram(unsigned long pagenr)
+{
+	phys_t addr = pagenr << PAGE_SHIFT;
+#ifdef CONFIG_SWARM_STANDALONE
+	if (addr < (CONFIG_SIBYTE_SWARM_RAM_SIZE * 1024 * 1024)) {
+		return 1;
+	}
+#else
+	int i;
+	for (i = 0; i < swarm_mem_region_count; i++) {
+		if ((addr >= swarm_mem_region_addrs[i]) 
+		    && (addr < (swarm_mem_region_addrs[i] + swarm_mem_region_sizes[i]))) {
+			return 1;
+		}
+	}
+#endif
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/rtc.c linux/arch/mips/sibyte/swarm/rtc.c
--- linux.orig/arch/mips/sibyte/swarm/rtc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/rtc.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/*
+ *  Not really sure what is supposed to be here, yet 
+ */
+
+#include <linux/spinlock.h>
+#include <linux/mc146818rtc.h>
+
+static unsigned char swarm_rtc_read_data(unsigned long addr)
+{
+	return 0;
+}
+
+static void swarm_rtc_write_data(unsigned char data, unsigned long addr)
+{
+}
+
+static int swarm_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops swarm_rtc_ops = {
+	&swarm_rtc_read_data,
+	&swarm_rtc_write_data,
+	&swarm_rtc_bcd_mode
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/rtc_xicor1241.c linux/arch/mips/sibyte/swarm/rtc_xicor1241.c
--- linux.orig/arch/mips/sibyte/swarm/rtc_xicor1241.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/rtc_xicor1241.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/time.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+
+#include <asm/sibyte/64bit.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_smbus.h>
+
+
+/* Xicor 1241 definitions */
+
+/*
+ * Register bits
+ */
+
+#define X1241REG_SR_BAT	0x80		/* currently on battery power */
+#define X1241REG_SR_RWEL 0x04		/* r/w latch is enabled, can write RTC */
+#define X1241REG_SR_WEL 0x02		/* r/w latch is unlocked, can enable r/w now */
+#define X1241REG_SR_RTCF 0x01		/* clock failed */
+#define X1241REG_BL_BP2 0x80		/* block protect 2 */
+#define X1241REG_BL_BP1 0x40		/* block protect 1 */
+#define X1241REG_BL_BP0 0x20		/* block protect 0 */
+#define X1241REG_BL_WD1	0x10
+#define X1241REG_BL_WD0	0x08
+#define X1241REG_HR_MIL 0x80		/* military time format */
+
+/*
+ * Register numbers
+ */
+
+#define X1241REG_BL	0x10		/* block protect bits */
+#define X1241REG_INT	0x11		/*  */
+#define X1241REG_SC	0x30		/* Seconds */
+#define X1241REG_MN	0x31		/* Minutes */
+#define X1241REG_HR	0x32		/* Hours */
+#define X1241REG_DT	0x33		/* Day of month */
+#define X1241REG_MO	0x34		/* Month */
+#define X1241REG_YR	0x35		/* Year */
+#define X1241REG_DW	0x36		/* Day of Week */
+#define X1241REG_Y2K	0x37		/* Year 2K */
+#define X1241REG_SR	0x3F		/* Status register */
+
+#define X1241_CCR_ADDRESS	0x6F
+
+#define SMB_CSR(reg) (KSEG1 | A_SMB_REGISTER(1, reg))
+
+static int xicor_read(uint8_t addr)
+{
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	out64((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+	out64((addr & 0xff), SMB_CSR(R_SMB_DATA));
+	out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START));
+
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
+
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                return -1;
+        }
+
+	return (in64(SMB_CSR(R_SMB_DATA)) & 0xff);
+}
+
+static int xicor_write(uint8_t addr, int b)
+{
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	out64(addr, SMB_CSR(R_SMB_CMD));
+	out64((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+	out64(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+	      SMB_CSR(R_SMB_START));
+
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                return -1;
+        } else {
+		return 0;
+	}
+}
+
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+
+int xicor_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+	int tmp;
+
+	to_tm(t, &tm);
+
+	/* unlock writes to the CCR */
+	xicor_write(X1241REG_SR, X1241REG_SR_WEL);
+	xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
+
+	/* trivial ones */
+	BIN_TO_BCD(tm.tm_sec);
+	xicor_write(X1241REG_SC, tm.tm_sec);
+	
+	BIN_TO_BCD(tm.tm_min);
+	xicor_write(X1241REG_MN, tm.tm_min);
+
+	BIN_TO_BCD(tm.tm_mday);
+	xicor_write(X1241REG_DT, tm.tm_mday);
+
+	/* tm_mon starts from 0, *ick* */
+	tm.tm_mon ++;
+	BIN_TO_BCD(tm.tm_mon);
+	xicor_write(X1241REG_MO, tm.tm_mon);
+
+	/* year is split */
+	tmp = tm.tm_year / 100;
+	tm.tm_year %= 100;
+	xicor_write(X1241REG_YR, tm.tm_year);
+	xicor_write(X1241REG_Y2K, tmp);
+
+	/* hour is the most tricky one */
+	tmp = xicor_read(X1241REG_HR);
+	if (tmp & X1241REG_HR_MIL) {
+		/* 24 hour format */
+		BIN_TO_BCD(tm.tm_hour);
+		tmp = (tmp & ~0x3f) | (tm.tm_hour & 0x3f);
+	} else {
+		/* 12 hour format, with 0x2 for pm */
+		tmp = tmp & ~0x3f;
+		if (tm.tm_hour >= 12) {
+			tmp |= 0x20;
+			tm.tm_hour -= 12;
+		}
+		BIN_TO_BCD(tm.tm_hour);
+		tmp |= tm.tm_hour;
+	}
+	xicor_write(X1241REG_HR, tmp);
+
+	xicor_write(X1241REG_SR, 0);
+
+	return 0;
+}
+
+unsigned long xicor_get_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec, y2k;
+
+	sec = xicor_read(X1241REG_SC);
+	min = xicor_read(X1241REG_MN);
+	hour = xicor_read(X1241REG_HR);
+
+	if (hour & X1241REG_HR_MIL) {
+		hour &= 0x3f;
+	} else {
+		if (hour & 0x20)
+			hour = (hour & 0xf) + 0x12;
+	}
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hour);
+
+	day = xicor_read(X1241REG_DT);
+	mon = xicor_read(X1241REG_MO);
+	year = xicor_read(X1241REG_YR);
+	y2k = xicor_read(X1241REG_Y2K);
+ 
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(year);
+	BCD_TO_BIN(y2k);
+
+	year += (y2k * 100);
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/setup.c linux/arch/mips/sibyte/swarm/setup.c
--- linux.orig/arch/mips/sibyte/swarm/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/setup.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/*
+ * Setup code for the SWARM board 
+ */
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/sibyte/swarm.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/swarm_ide.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+
+#include "cfe_xiocb.h"
+#include "cfe_api.h"
+#include "cfe_error.h"
+
+extern int cfe_console_handle;
+
+#ifdef CONFIG_BLK_DEV_IDE_SWARM
+extern struct ide_ops *ide_ops;
+#endif
+
+
+#ifdef CONFIG_L3DEMO
+extern void *l3info;
+#endif
+
+/* Max ram addressable in 32-bit segments */
+#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#define MAX_RAM_SIZE (0xffffffffULL)
+#endif
+#else
+#ifdef CONFIG_MIPS64
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#define MAX_RAM_SIZE (0x1fffffffULL)
+#endif
+#endif
+
+
+#ifndef CONFIG_SWARM_STANDALONE
+
+phys_t swarm_mem_region_addrs[CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS];
+phys_t swarm_mem_region_sizes[CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS];
+unsigned int swarm_mem_region_count;
+
+#endif
+
+const char *get_system_type(void)
+{
+	return "SiByte Swarm";
+}
+
+#ifdef CONFIG_BLK_DEV_IDE_SWARM
+static int swarm_ide_default_irq(ide_ioreg_t base)
+{
+        return 0;
+}
+
+static ide_ioreg_t swarm_ide_default_io_base(int index)
+{
+        return 0;
+}
+
+static void swarm_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port,
+                                     ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
+	}
+	if (irq != NULL)
+		*irq = 0;
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
+}
+
+static int swarm_ide_request_irq(unsigned int irq,
+                                void (*handler)(int,void *, struct pt_regs *),
+                                unsigned long flags, const char *device,
+                                void *dev_id)
+{
+	return request_irq(irq, handler, flags, device, dev_id);
+}			
+
+static void swarm_ide_free_irq(unsigned int irq, void *dev_id)
+{
+	free_irq(irq, dev_id);
+}
+
+static int swarm_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+    /* Note: "check_region" and friends do conflict management on ISA I/O
+       space.  Our disk is not in that space, so this check won't work */
+    /* return check_region(from, extent); */
+    return 0;
+}
+
+static void swarm_ide_request_region(ide_ioreg_t from, unsigned int extent,
+                                    const char *name)
+{
+    /* request_region(from, extent, name); */
+}
+
+static void swarm_ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+    /* release_region(from, extent); */
+}
+
+
+void swarm_ideproc(ide_ide_action_t action, ide_drive_t *drive,
+		   void *buffer, unsigned int count)
+{
+	/*  slow? vlb_sync? */
+	switch (action) {
+	case ideproc_ide_input_data:
+		if (drive->io_32bit) {
+			swarm_insl(IDE_DATA_REG, buffer, count);
+		} else {
+			swarm_insw(IDE_DATA_REG, buffer, count<<1);
+		}
+		break;
+	case ideproc_ide_output_data:
+		if (drive->io_32bit) {
+			swarm_outsl(IDE_DATA_REG, buffer, count);
+		} else {
+			swarm_outsw(IDE_DATA_REG, buffer, count<<1);
+		}
+		break;
+	case ideproc_atapi_input_bytes:
+		count++;
+		if (drive->io_32bit) {
+			swarm_insl(IDE_DATA_REG, buffer, count>>2);
+		} else {
+			swarm_insw(IDE_DATA_REG, buffer, count>>1);
+		}
+		if ((count & 3) >= 2)
+			swarm_insw(IDE_DATA_REG, (char *)buffer + (count & ~3), 1);
+		break;
+	case ideproc_atapi_output_bytes:
+		count++;
+		if (drive->io_32bit) {
+			swarm_outsl(IDE_DATA_REG, buffer, count>>2);
+		} else {
+			swarm_outsw(IDE_DATA_REG, buffer, count>>1);
+		}
+		if ((count & 3) >= 2)
+			swarm_outsw(IDE_DATA_REG, (char *)buffer + (count & ~3), 1);
+		break;
+	}
+}
+
+struct ide_ops swarm_ide_ops = {
+	&swarm_ide_default_irq,
+	&swarm_ide_default_io_base,
+	&swarm_ide_init_hwif_ports,
+	&swarm_ide_request_irq,
+	&swarm_ide_free_irq,
+	&swarm_ide_check_region,
+	&swarm_ide_request_region,
+	&swarm_ide_release_region
+};
+#endif
+
+
+#ifdef CONFIG_SMP
+static void smp_cpu0_exit(void *unused)
+{
+	printk("swarm_linux_exit called (cpu1) - passing control back to CFE\n");
+	cfe_exit(1,0);
+}
+#endif
+
+static void swarm_linux_exit(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_processor_id()) {
+		smp_call_function(smp_cpu0_exit,NULL,1,1);
+		while(1);
+	}
+#endif
+	printk("swarm_linux_exit called...passing control back to CFE\n");
+	cfe_exit(1, 0);
+	printk("cfe_exit returned??\n");
+	while(1);
+}
+
+void __init bus_error_init(void)
+{
+}
+
+void __init swarm_timer_setup(struct irqaction *irq)
+{
+        /* 
+         * we don't set up irqaction, because we will deliver timer
+         * interrupts through low-level (direct) meachanism.
+         */
+
+        /* We only need to setup the generic timer */
+        sb1250_time_init();
+}
+
+extern int xicor_set_time(unsigned long);
+extern unsigned int xicor_get_time(void);
+
+void __init swarm_setup(void)
+{
+	extern int panic_timeout;
+
+	panic_timeout = 5;  /* For debug.  */
+
+        board_timer_setup = swarm_timer_setup;
+
+        rtc_get_time = xicor_get_time;
+        rtc_set_time = xicor_set_time;
+
+	_machine_restart   = (void (*)(char *))swarm_linux_exit;
+	_machine_halt      = swarm_linux_exit;
+	_machine_power_off = swarm_linux_exit;
+
+#ifdef CONFIG_L3DEMO
+	if (l3info != NULL) {
+		printk("\n");
+	}
+#endif
+	printk("This kernel optimized for "
+#ifdef CONFIG_SIMULATION
+	       "simulation"
+#else
+	       "board"
+#endif
+	       " runs\n");
+
+#ifdef CONFIG_BLK_DEV_IDE_SWARM
+	ide_ops = &swarm_ide_ops;
+#endif
+}  
+
+/* This is the kernel command line.  Actually, it's 
+   copied, eventually, to command_line, and looks to be
+   quite redundant.  But not something to fix just now */
+extern char arcs_cmdline[];
+
+#ifdef CONFIG_EMBEDDED_RAMDISK
+/* These are symbols defined by the ramdisk linker script */
+extern unsigned char __rd_start;
+extern unsigned char __rd_end;  
+#endif
+
+static __init void prom_meminit(void)
+{
+	u64 addr, size; /* regardless of 64BIT_PHYS_ADDR */
+	long type;
+	unsigned int idx;
+	int rd_flag;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long initrd_pstart; 
+	unsigned long initrd_pend; 
+
+#ifdef CONFIG_EMBEDDED_RAMDISK
+	/* If we're using an embedded ramdisk, then __rd_start and __rd_end
+	   are defined by the linker to be on either side of the ramdisk
+	   area.  Otherwise, initrd_start should be defined by kernel command
+	   line arguments */
+	if (initrd_start == 0) {
+		initrd_start = (unsigned long)&__rd_start;
+		initrd_end = (unsigned long)&__rd_end;
+	}
+#endif
+
+	initrd_pstart = __pa(initrd_start);
+	initrd_pend = __pa(initrd_end);
+	if (initrd_start &&
+	    ((initrd_pstart > MAX_RAM_SIZE)
+	     || (initrd_pend > MAX_RAM_SIZE))) {
+		setleds("INRD");
+		panic("initrd out of addressable memory");
+	}
+       
+#endif /* INITRD */
+		
+	for (idx = 0; cfe_enummem(idx, &addr, &size, &type) != CFE_ERR_NOMORE;
+	     idx++) {
+		rd_flag = 0;
+		if (type == CFE_MI_AVAILABLE) {
+			/*
+			 * See if this block contains (any portion of) the
+			 * ramdisk
+			 */
+#ifdef CONFIG_BLK_DEV_INITRD
+			if (initrd_start) {
+				if ((initrd_pstart > addr) &&
+				    (initrd_pstart < (addr + size))) {
+					add_memory_region(addr,
+					                  initrd_pstart - addr,
+					                  BOOT_MEM_RAM);
+					rd_flag = 1;
+				}
+				if ((initrd_pend > addr) &&
+				    (initrd_pend < (addr + size))) {
+					add_memory_region(initrd_pend,
+						(addr + size) - initrd_pend,
+						 BOOT_MEM_RAM);
+					rd_flag = 1;
+				}
+			}
+#endif
+			if (!rd_flag) {
+				if (addr > MAX_RAM_SIZE)
+					continue;
+				if (addr+size > MAX_RAM_SIZE)
+					size = MAX_RAM_SIZE - (addr+size) + 1;
+				add_memory_region(addr, size, BOOT_MEM_RAM);
+			}
+			swarm_mem_region_addrs[swarm_mem_region_count] = addr;
+			swarm_mem_region_sizes[swarm_mem_region_count] = size;
+			swarm_mem_region_count++;
+			if (swarm_mem_region_count ==
+			    CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS) {
+				/*
+				 * Too many regions.  Need to configure more
+				 */
+				while(1);
+			}
+		}
+	}
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start) {
+		add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
+		                 BOOT_MEM_RESERVED);
+	}
+#endif
+}
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static int __init initrd_setup(char *str)
+{
+	/* 
+	 *Initrd location comes in the form "<hex size of ramdisk in bytes>@<location in memory>"
+	 *  e.g. initrd=3abfd@80010000.  This is set up by the loader.
+	 */
+	char *tmp, *endptr;
+	unsigned long initrd_size;
+	for (tmp = str; *tmp != '@'; tmp++) {
+		if (!*tmp) {
+			goto fail;
+		}
+	}
+	*tmp = 0;
+	tmp++;
+	if (!*tmp) {
+		goto fail;
+	}
+	initrd_size = simple_strtol(str, &endptr, 16);
+	if (*endptr) {
+		goto fail;
+	}
+	initrd_start = simple_strtol(tmp, &endptr, 16);
+	if (*endptr) {
+		goto fail;
+	}
+	initrd_end = initrd_start + initrd_size;
+	printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start);
+	return 1;
+ fail:
+	printk("Bad initrd argument.  Disabling initrd\n");
+	initrd_start = 0;
+	initrd_end = 0;
+	return 1;
+}
+
+#endif
+
+/*
+ * prom_init is called just after the cpu type is determined, from init_arch()
+ */
+__init int prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	/* 
+	 * This should go away.  Detect if we're booting
+	 * straight from cfe without a loader.  If we
+	 * are, then we've got a prom vector in a0.  Otherwise,
+	 * argc (and argv and envp, for that matter) will be 0) 
+	 */
+	if (argc < 0) {
+		prom_vec = (int *)argc;
+	}
+	cfe_init((long)prom_vec);
+	cfe_open_console();
+	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) {
+		if (argc < 0) {
+			/*
+			 * It's OK for direct boot to not provide a
+			 *  command line
+			 */
+			strcpy(arcs_cmdline, "root=/dev/ram0 ");
+		} else {
+			/* The loader should have set the command line */
+			setleds("CMDL");
+			panic("LINUX_CMDLINE not defined in cfe.");
+		}
+	}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	{
+		char *ptr;
+		/* Need to find out early whether we've got an initrd.  So scan
+		   the list looking now */
+		for (ptr = arcs_cmdline; *ptr; ptr++) {
+			while (*ptr == ' ') {
+				ptr++;
+			}
+			if (!strncmp(ptr, "initrd=", 7)) {
+				initrd_setup(ptr+7);
+				break;
+			} else {
+				while (*ptr && (*ptr != ' ')) {
+					ptr++;
+				}
+			}
+		}
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/* Not sure this is needed, but it's the safe way. */
+	arcs_cmdline[CL_SIZE-1] = 0;
+
+	mips_machgroup = MACH_GROUP_SIBYTE;
+	prom_meminit();
+
+	return 0;
+}
+
+void prom_free_prom_memory(void)
+{
+	/* Not sure what I'm supposed to do here.  Nothing, I think */
+}
+
+static void setled(unsigned int index, char c) 
+{
+	volatile unsigned char *led_ptr;
+
+	led_ptr = (unsigned char *)(IO_SPACE_BASE | LED_BASE_ADDR);
+	if (index < 4) {
+		led_ptr[(3-index)<<3] = c;
+	}
+}
+
+void setleds(char *str)
+{
+	int i;
+	for (i = 0; i < 4; i++) {
+		if (!str[i]) {
+			for (; i < 4; i++) { 
+				setled(' ', str[i]);
+			}
+		} else {
+			setled(i, str[i]);
+		}
+	}
+}
+
+#include <linux/timer.h>
+
+static struct timer_list led_timer;
+static unsigned char default_led_msg[] =
+	"Today: the CSWARM.  Tomorrow: the WORLD!!!!           ";
+static unsigned char *led_msg = default_led_msg;
+static unsigned char *led_msg_ptr = default_led_msg;
+
+void set_led_msg(char *new_msg)
+{
+	led_msg = new_msg;
+	led_msg_ptr = new_msg;
+	setleds("    ");
+}
+
+static void move_leds(unsigned long arg) 
+{
+	int i;
+	unsigned char *tmp = led_msg_ptr;
+	for (i = 0; i < 4; i++) {
+		setled(i, *tmp);
+		tmp++;
+		if (!*tmp) { 
+			tmp = led_msg; 
+		}
+	}
+	led_msg_ptr++;
+	if (!*led_msg_ptr) { 
+ 		led_msg_ptr = led_msg; 
+	}
+	del_timer(&led_timer);
+	led_timer.expires = jiffies + (HZ/8);
+	add_timer(&led_timer);
+}
+
+void hack_leds(void) 
+{
+	init_timer(&led_timer);
+	led_timer.expires = jiffies + (HZ/8);
+	led_timer.data = 0;
+	led_timer.function = move_leds;
+	add_timer(&led_timer);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/smp.c linux/arch/mips/sibyte/swarm/smp.c
--- linux.orig/arch/mips/sibyte/swarm/smp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/smp.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/mipsregs.h>
+#include <asm/mmu_context.h>
+
+#include "cfe_xiocb.h"
+#include "cfe_api.h"
+
+extern void asmlinkage smp_bootstrap(void);
+
+/* Boot all other cpus in the system, initialize them, and
+   bring them into the boot fn */
+int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
+{
+	int retval;
+	
+	retval = cfe_start_cpu(cpu, &smp_bootstrap, sp, gp, 0);
+	if (retval != 0) {
+		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+
+void prom_init_secondary(void)
+{
+	/* Set up kseg0 to be cachable coherent */
+	clear_cp0_config(CONF_CM_CMASK);
+	set_cp0_config(0x5);
+
+	/* Enable interrupts for lines 0-4 */
+	clear_cp0_status(0xe000);
+	set_cp0_status(0x1f01);
+}
+
+
+/*
+ * Set up state, return the total number of cpus in the system, including
+ * the master
+ */
+int prom_setup_smp(void)
+{
+	int i;
+	int num_cpus = 1;
+
+	/* Use CFE to find out how many CPUs are available */
+	for (i=1; i<NR_CPUS; i++) {
+		if (cfe_stop_cpu(i) == 0) {
+			num_cpus++;
+		}
+	}
+	printk("Detected %i available CPU(s)\n", num_cpus);
+	return num_cpus;
+}
+
+void prom_smp_finish(void)
+{
+	extern void sb1250_smp_finish(void);
+	sb1250_smp_finish();
+}
+
+/*
+ * XXX This is really halfway portable code and halfway system specific code.
+ * XXX Seems like some of this is CPU-specific, too - rather than board/system.
+ */
+extern atomic_t cpus_booted;
+
+void __init smp_boot_cpus(void)
+{
+	int i;
+	int cur_cpu = 0;
+
+	smp_num_cpus = prom_setup_smp();
+	init_new_context(current, &init_mm);
+	current->processor = 0;
+	cpu_data[0].udelay_val = loops_per_jiffy;
+	cpu_data[0].asid_cache = ASID_FIRST_VERSION;
+	CPUMASK_CLRALL(cpu_online_map);
+	CPUMASK_SETB(cpu_online_map, 0);
+	atomic_set(&cpus_booted, 1);  /* Master CPU is already booted... */
+	__cpu_number_map[0] = 0;
+	__cpu_logical_map[0] = 0;
+	init_idle();
+
+	/* 
+	 * This loop attempts to compensate for "holes" in the CPU
+	 * numbering.  It's overkill, but general.
+	 */
+	for (i = 1; i < smp_num_cpus; ) {
+		struct task_struct *p;
+		struct pt_regs regs;
+		int retval;
+		printk("Starting CPU %d... ", i);
+
+		/* Spawn a new process normally.  Grab a pointer to
+		   its task struct so we can mess with it */
+		do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
+		p = init_task.prev_task;
+
+		/* Schedule the first task manually */
+		p->processor = i;
+		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
+
+		/* Attach to the address space of init_task. */
+		atomic_inc(&init_mm.mm_count);
+		p->active_mm = &init_mm;
+		init_tasks[i] = p;
+
+		del_from_runqueue(p);
+		unhash_process(p);
+
+		do {
+			/* Iterate until we find a CPU that comes up */
+			cur_cpu++;
+			retval = prom_boot_secondary(cur_cpu,
+					    (unsigned long)p + KERNEL_STACK_SIZE - 32,
+					    (unsigned long)p);
+			__cpu_number_map[i] = i;
+			__cpu_logical_map[i] = i;
+		} while (!retval && (cur_cpu < NR_CPUS));
+		if (retval) {
+			i++;
+		} else {
+			panic("CPU discovery disaster");
+		}
+
+#if 0
+		/* This is copied from the ip-27 code in the mips64 tree */
+
+		struct task_struct *p;
+
+		/*
+		 * The following code is purely to make sure
+		 * Linux can schedule processes on this slave.
+		 */
+		kernel_thread(0, NULL, CLONE_PID);
+		p = init_task.prev_task;
+		sprintf(p->comm, "%s%d", "Idle", i);
+		init_tasks[i] = p;
+		p->processor = i;
+		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
+		del_from_runqueue(p);
+		unhash_process(p);
+		/* Attach to the address space of init_task. */
+		atomic_inc(&init_mm.mm_count);
+		p->active_mm = &init_mm;
+		prom_boot_secondary(i, 
+				    (unsigned long)p + KERNEL_STACK_SIZE - 32,
+				    (unsigned long)p);
+#endif
+	}
+
+	/* Wait for everyone to come up */
+	while (atomic_read(&cpus_booted) != smp_num_cpus);
+
+	smp_threads_ready = 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sibyte/swarm/time.c linux/arch/mips/sibyte/swarm/time.c
--- linux.orig/arch/mips/sibyte/swarm/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/sibyte/swarm/time.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+/* 
+ * Time routines for the swarm board.  We pass all the hard stuff
+ * through to the sb1250 handling code.  Only thing we really keep
+ * track of here is what time of day we think it is.  And we don't
+ * really even do a good job of that...
+ */
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <asm/system.h>
+#include <asm/addrspace.h>
+
+#include <asm/sibyte/64bit.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_smbus.h>
+
+extern rwlock_t xtime_lock;
+
+/* Xicor 1241 definitions */
+
+/*
+ * Register bits
+ */
+
+#define X1241REG_SR_BAT	0x80		/* currently on battery power */
+#define X1241REG_SR_RWEL 0x04		/* r/w latch is enabled, can write RTC */
+#define X1241REG_SR_WEL 0x02		/* r/w latch is unlocked, can enable r/w now */
+#define X1241REG_SR_RTCF 0x01		/* clock failed */
+#define X1241REG_BL_BP2 0x80		/* block protect 2 */
+#define X1241REG_BL_BP1 0x40		/* block protect 1 */
+#define X1241REG_BL_BP0 0x20		/* block protect 0 */
+#define X1241REG_BL_WD1	0x10
+#define X1241REG_BL_WD0	0x08
+#define X1241REG_HR_MIL 0x80		/* military time format */
+
+/*
+ * Register numbers
+ */
+
+#define X1241REG_BL	0x10		/* block protect bits */
+#define X1241REG_INT	0x11		/*  */
+#define X1241REG_SC	0x30		/* Seconds */
+#define X1241REG_MN	0x31		/* Minutes */
+#define X1241REG_HR	0x32		/* Hours */
+#define X1241REG_DT	0x33		/* Day of month */
+#define X1241REG_MO	0x34		/* Month */
+#define X1241REG_YR	0x35		/* Year */
+#define X1241REG_DW	0x36		/* Day of Week */
+#define X1241REG_Y2K	0x37		/* Year 2K */
+#define X1241REG_SR	0x3F		/* Status register */
+
+#define X1241_CCR_ADDRESS	0x6F
+
+#define SMB_CSR(reg) (KSEG1 | A_SMB_REGISTER(1, reg))
+
+static int xicor_read(uint8_t addr)
+{
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	out64((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+	out64((addr & 0xff), SMB_CSR(R_SMB_DATA));
+	out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START));
+
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
+
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                return -1;
+        }
+
+	return (in64(SMB_CSR(R_SMB_DATA)) & 0xff);
+}
+
+static int xicor_write(uint8_t addr, int b)
+{
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	out64(addr, SMB_CSR(R_SMB_CMD));
+	out64((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+	out64(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+	      SMB_CSR(R_SMB_START));
+
+        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                return -1;
+        } else {
+		return 0;
+	}
+}
+
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ *      sets the minutes. Usually you'll only notice that after reboot!
+ */
+int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+
+	cmos_minutes = xicor_read(X1241REG_MN);
+	BCD_TO_BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;		/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	/* unlock writes to the CCR */
+	xicor_write(X1241REG_SR, X1241REG_SR_WEL);
+	xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		BIN_TO_BCD(real_seconds);
+		BIN_TO_BCD(real_minutes);
+		xicor_write(X1241REG_SC, real_seconds);
+		xicor_write(X1241REG_MN, real_minutes);
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	xicor_write(X1241REG_SR, 0);
+
+	printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds);
+
+	return retval;
+}
+
+static unsigned long __init get_swarm_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec, y2k;
+
+	sec = xicor_read(X1241REG_SC);
+	min = xicor_read(X1241REG_MN);
+	hour = xicor_read(X1241REG_HR);
+
+	if (hour & X1241REG_HR_MIL) {
+		hour &= 0x3f;
+	} else {
+		if (hour & 0x20)
+			hour = (hour & 0xf) + 0x12;
+	}
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hour);
+
+	day = xicor_read(X1241REG_DT);
+	mon = xicor_read(X1241REG_MO);
+	year = xicor_read(X1241REG_YR);
+	y2k = xicor_read(X1241REG_Y2K);
+ 
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(year);
+	BCD_TO_BIN(y2k);
+
+	year += (y2k * 100);
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+/*
+ *  Bring up the timer at 100 Hz.  
+ */
+void __init swarm_time_init(void)
+{
+	unsigned int flags;
+	int status;
+
+	/* Set up the scd general purpose timer 0 to cpu 0 */
+	sb1250_time_init();
+
+	/* Establish communication with the Xicor 1241 RTC */
+	/* XXXKW how do I share the SMBus with the I2C subsystem? */
+
+	out64(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
+	out64(0, SMB_CSR(R_SMB_CONTROL));
+
+	if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
+		printk("x1241: couldn't detect on SWARM SMBus 1\n");
+	} else {
+		if (status & X1241REG_SR_RTCF)
+			printk("x1241: battery failed -- time is probably wrong\n");
+		write_lock_irqsave (&xtime_lock, flags);
+		xtime.tv_sec = get_swarm_time();
+		xtime.tv_usec = 0;
+		write_unlock_irqrestore(&xtime_lock, flags);
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sni/int-handler.S linux/arch/mips/sni/int-handler.S
--- linux.orig/arch/mips/sni/int-handler.S	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sni/int-handler.S	2002-07-20 01:08:30.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * SNI RM200 PCI specific interrupt handler code.
  *
- * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle
  */
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
@@ -9,12 +9,13 @@
 #include <asm/sni.h>
 #include <asm/stackframe.h>
 
-/* The PCI ASIC has the nasty property that it may delay writes if it is busy.
-   As a consequence from writes that have not graduated when we exit from the
-   interrupt handler we might catch a spurious interrupt.  To avoid this we
-   force the PCI ASIC to graduate all writes by executing a read from the
-   PCI bus.  */
-
+/*
+ * The PCI ASIC has the nasty property that it may delay writes if it is busy.
+ * As a consequence from writes that have not graduated when we exit from the
+ * interrupt handler we might catch a spurious interrupt.  To avoid this we
+ * force the PCI ASIC to graduate all writes by executing a read from the
+ * PCI bus.
+ */
 		.set	noreorder
 		.set	noat
 		.align	5
@@ -46,7 +47,7 @@
 		bnez	t1, _hwint0
 		 nop
 
-		j	return				# spurious interrupt
+		j	restore_all			# spurious interrupt
 		 nop
 
  ##############################################################################
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sni/io.c linux/arch/mips/sni/io.c
--- linux.orig/arch/mips/sni/io.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/sni/io.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: io.c,v 1.4 1999/08/18 23:37:46 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sni/irq.c linux/arch/mips/sni/irq.c
--- linux.orig/arch/mips/sni/irq.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sni/irq.c	2002-07-20 01:08:31.000000000 +0000
@@ -8,7 +8,6 @@
  */
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
@@ -126,7 +125,7 @@
 
 void __init init_pciasic(void)
 {
-	unsigned int flags;
+	unsigned long flags;
 
 	spin_lock_irqsave(&pciasic_lock, flags);
 	* (volatile u8 *) PCIMT_IRQSEL =
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sni/pci.c linux/arch/mips/sni/pci.c
--- linux.orig/arch/mips/sni/pci.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sni/pci.c	2002-07-20 01:08:37.000000000 +0000
@@ -25,7 +25,7 @@
 		 ((dev->bus->number    & 0xff) << 0x10) |                    \
 	         ((dev->devfn & 0xff) << 0x08) |                             \
 	         (where  & 0xfc);                                            \
-} while(0);
+} while(0)
 
 #if 0
 /* To do:  Bring this uptodate ...  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sni/pcimt_scache.c linux/arch/mips/sni/pcimt_scache.c
--- linux.orig/arch/mips/sni/pcimt_scache.c	2000-05-13 15:29:14.000000000 +0000
+++ linux/arch/mips/sni/pcimt_scache.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: pcimt_scache.c,v 1.4 1999/01/04 16:03:59 ralf Exp $
- *
+/*
  * arch/mips/sni/pcimt_scache.c
  *
  * This file is subject to the terms and conditions of the GNU General Public
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/sni/setup.c linux/arch/mips/sni/setup.c
--- linux.orig/arch/mips/sni/setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips/sni/setup.c	2002-07-20 01:08:35.000000000 +0000
@@ -30,6 +30,7 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/sni.h>
+#include <asm/time.h>
 
 extern void sni_machine_restart(char *command);
 extern void sni_machine_halt(void);
@@ -39,8 +40,6 @@
 extern struct rtc_ops std_rtc_ops;
 extern struct kbd_ops std_kbd_ops;
 
-void (*board_time_init)(struct irqaction *irq);
-
 static void __init sni_rm200_pci_time_init(struct irqaction *irq)
 {
 	/* set the clock to 100 Hz */
@@ -50,7 +49,6 @@
 	setup_irq(0, irq);
 }
 
-unsigned char aux_device_present;
 extern unsigned char sni_map_isa_cache;
 
 /*
@@ -80,7 +78,7 @@
 	sni_pcimt_detect();
 	sni_pcimt_sc_init();
 
-	mips_io_port_base = SNI_PORT_BASE;
+	set_io_port_base(SNI_PORT_BASE);
 
 	/*
 	 * Setup (E)ISA I/O memory access stuff
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/tools/Makefile linux/arch/mips/tools/Makefile
--- linux.orig/arch/mips/tools/Makefile	2000-07-10 05:18:15.000000000 +0000
+++ linux/arch/mips/tools/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -3,14 +3,9 @@
 # Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
 # Copyright (C) 1997 Ralf Baechle (ralf@gnu.ai.mit.edu)
 #
-# $Id: Makefile,v 1.2 1997/09/23 06:23:49 ralf Exp $
-#
 TARGET	:= $(TOPDIR)/include/asm-$(ARCH)/offset.h
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 $(TARGET): offset.h
 	cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/tools/offset.c linux/arch/mips/tools/offset.c
--- linux.orig/arch/mips/tools/offset.c	2001-07-02 20:56:40.000000000 +0000
+++ linux/arch/mips/tools/offset.c	2002-07-20 01:08:28.000000000 +0000
@@ -10,6 +10,7 @@
  */
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <linux/mm.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -19,6 +20,8 @@
 
 #define offset(string, ptr, member) \
 	__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
+#define constant(string, member) \
+	__asm__("\n@@@" string "%x0" : : "i" (member))
 #define size(string, size) \
 	__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
 #define linefeed text("")
@@ -86,7 +89,8 @@
 	offset("#define TASK_NICE          ", struct task_struct, nice);
 	offset("#define TASK_MM            ", struct task_struct, mm);
 	offset("#define TASK_PID           ", struct task_struct, pid);
-	size("#define TASK_STRUCT_SIZE   ", struct task_struct);
+	size(  "#define TASK_STRUCT_SIZE   ", struct task_struct);
+	constant("#define PT_TRACESYS        ", PT_TRACESYS);
 	linefeed;
 }
 
@@ -121,10 +125,6 @@
 	       thread.irix_trampoline);
 	offset("#define THREAD_OLDCTX  ", struct task_struct, \
 	       thread.irix_oldctx);
-	offset("#define THREAD_DSEEPC  ", struct task_struct, \
-	       thread.dsemul_epc);
-	offset("#define THREAD_DSEAERPC ", struct task_struct, \
-	       thread.dsemul_aerpc);
 	linefeed;
 }
 
@@ -135,6 +135,10 @@
 	offset("#define MM_PGD        ", struct mm_struct, pgd);
 	offset("#define MM_CONTEXT    ", struct mm_struct, context);
 	linefeed;
+	constant("#define _PAGE_SIZE     ", PAGE_SIZE);
+	constant("#define _PGD_ORDER     ", PGD_ORDER);
+	constant("#define _PGDIR_SHIFT   ", PGDIR_SHIFT);
+	linefeed;
 }
 
 void output_sc_defines(void)
@@ -154,4 +158,41 @@
 	linefeed;
 }
 
+void output_signal_defined(void)
+{
+	text("/* Linux signal numbers. */");
+	constant("#define _SIGHUP     ", SIGHUP);
+	constant("#define _SIGINT     ", SIGINT);
+	constant("#define _SIGQUIT    ", SIGQUIT);
+	constant("#define _SIGILL     ", SIGILL);
+	constant("#define _SIGTRAP    ", SIGTRAP);
+	constant("#define _SIGIOT     ", SIGIOT);
+	constant("#define _SIGABRT    ", SIGABRT);
+	constant("#define _SIGEMT     ", SIGEMT);
+	constant("#define _SIGFPE     ", SIGFPE);
+	constant("#define _SIGKILL    ", SIGKILL);
+	constant("#define _SIGBUS     ", SIGBUS);
+	constant("#define _SIGSEGV    ", SIGSEGV);
+	constant("#define _SIGSYS     ", SIGSYS);
+	constant("#define _SIGPIPE    ", SIGPIPE);
+	constant("#define _SIGALRM    ", SIGALRM);
+	constant("#define _SIGTERM    ", SIGTERM);
+	constant("#define _SIGUSR1    ", SIGUSR1);
+	constant("#define _SIGUSR2    ", SIGUSR2);
+	constant("#define _SIGCHLD    ", SIGCHLD);
+	constant("#define _SIGPWR     ", SIGPWR);
+	constant("#define _SIGWINCH   ", SIGWINCH);
+	constant("#define _SIGURG     ", SIGURG);
+	constant("#define _SIGIO      ", SIGIO);
+	constant("#define _SIGSTOP    ", SIGSTOP);
+	constant("#define _SIGTSTP    ", SIGTSTP);
+	constant("#define _SIGCONT    ", SIGCONT);
+	constant("#define _SIGTTIN    ", SIGTTIN);
+	constant("#define _SIGTTOU    ", SIGTTOU);
+	constant("#define _SIGVTALRM  ", SIGVTALRM);
+	constant("#define _SIGPROF    ", SIGPROF);
+	constant("#define _SIGXCPU    ", SIGXCPU);
+	constant("#define _SIGXFSZ    ", SIGXFSZ);
+}
+
 text("#endif /* !(_MIPS_OFFSET_H) */");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/common/Makefile linux/arch/mips/vr4181/common/Makefile
--- linux.orig/arch/mips/vr4181/common/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/common/Makefile	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,15 @@
+#
+# Makefile for common code of NEC vr4181 based boards
+#
+# 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:= vr4181.o
+
+obj-y	 := irq.o int_handler.o serial.o time.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/common/int_handler.S linux/arch/mips/vr4181/common/int_handler.S
--- linux.orig/arch/mips/vr4181/common/int_handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/common/int_handler.S	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,206 @@
+/*
+ * arch/mips/vr4181/common/int_handler.S
+ *
+ * Adapted to the VR4181 and almost entirely rewritten:
+ * Copyright (C) 1999 Bradley D. LaRonde and Michael Klar
+ *
+ * Clean up to conform to the new IRQ
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+#include <asm/vr4181/vr4181.h>
+
+/*
+ * [jsun]
+ * See include/asm/vr4181/irq.h for IRQ assignment and strategy.
+ */
+
+	.text
+	.set	noreorder
+
+	.align	5
+	NESTED(vr4181_handle_irq, PT_SIZE, ra)
+
+	.set	noat
+	SAVE_ALL
+	CLI
+
+	.set	at
+	.set	noreorder
+
+	mfc0	t0, CP0_CAUSE
+	mfc0	t2, CP0_STATUS
+
+	and	t0, t2
+
+	/* we check IP3 first; it happens most frequently */
+	andi	t1, t0, STATUSF_IP3
+	bnez	t1, ll_cpu_ip3
+	andi	t1, t0, STATUSF_IP2
+	bnez	t1, ll_cpu_ip2
+	andi	t1, t0, STATUSF_IP7	/* cpu timer */
+	bnez	t1, ll_cputimer_irq
+	andi	t1, t0, STATUSF_IP4
+	bnez	t1, ll_cpu_ip4
+	andi	t1, t0, STATUSF_IP5
+	bnez	t1, ll_cpu_ip5
+	andi	t1, t0, STATUSF_IP6
+	bnez	t1, ll_cpu_ip6
+	andi	t1, t0, STATUSF_IP0	/* software int 0 */
+	bnez	t1, ll_cpu_ip0
+	andi	t1, t0, STATUSF_IP1	/* software int 1 */
+	bnez	t1, ll_cpu_ip1
+	nop
+
+	.set	reorder
+do_spurious:
+	j	spurious_interrupt
+
+/*
+ * regular CPU irqs
+ */
+ll_cputimer_irq:
+	li	a0, VR4181_IRQ_TIMER
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+
+ll_cpu_ip0:
+	li	a0, VR4181_IRQ_SW1
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip1:
+	li	a0, VR4181_IRQ_SW2
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip3:
+	li	a0, VR4181_IRQ_INT1
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip4:
+	li	a0, VR4181_IRQ_INT2
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip5:
+	li	a0, VR4181_IRQ_INT3
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip6:
+	li	a0, VR4181_IRQ_INT4
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+/*
+ *  One of the sys irq has happend.
+ *
+ *  In the interest of speed, we first determine in the following order
+ *  which 16-irq block have pending interrupts:
+ *	sysint1 (16 sources, including cascading intrs from GPIO)
+ *	sysint2
+ *	gpio (16 intr sources)
+ *
+ *  Then we do binary search to find the exact interrupt source.
+ */
+ll_cpu_ip2:
+
+	lui	t3,%hi(VR4181_SYSINT1REG)
+	lhu	t0,%lo(VR4181_SYSINT1REG)(t3)
+	lhu	t2,%lo(VR4181_MSYSINT1REG)(t3)
+	and	t0, 0xfffb		/* hack - remove RTC Long 1 intr */
+	and	t0, t2
+	beqz	t0, check_sysint2
+
+	/* check for GPIO interrupts */
+	andi	t1, t0, 0x0100
+	bnez	t1, check_gpio_int
+
+	/* so we have an interrupt in sysint1 which is not gpio int */
+	li	a0, VR4181_SYS_IRQ_BASE - 1
+	j	check_16
+
+check_sysint2:
+
+	lhu	t0,%lo(VR4181_SYSINT2REG)(t3)
+	lhu	t2,%lo(VR4181_MSYSINT2REG)(t3)
+	and	t0, 0xfffe		/* hack - remove RTC Long 2 intr */
+	and	t0, t2
+	li	a0, VR4181_SYS_IRQ_BASE + 16 - 1
+	j	check_16
+
+check_gpio_int:
+	lui	t3,%hi(VR4181_GPINTMSK)
+	lhu	t0,%lo(VR4181_GPINTMSK)(t3)
+	lhu	t2,%lo(VR4181_GPINTSTAT)(t3)
+	xori	t0, 0xffff			/* why? reverse logic? */
+	and	t0, t2
+	li	a0, VR4181_GPIO_IRQ_BASE - 1
+	j	check_16
+
+/*
+ *  When we reach check_16, we have 16-bit status in t0 and base irq number
+ *  in a0.
+ */
+check_16:
+	andi	t1, t0, 0xff
+	bnez	t1, check_8
+
+	srl	t0, 8
+	addi	a0, 8
+	j	check_8
+
+/*
+ *  When we reach check_8, we have 8-bit status in t0 and base irq number
+ *  in a0.
+ */
+check_8:
+	andi	t1, t0, 0xf
+	bnez	t1, check_4
+
+	srl	t0, 4
+	addi	a0, 4
+	j	check_4
+
+/*
+ *  When we reach check_4, we have 4-bit status in t0 and base irq number
+ *  in a0.
+ */
+check_4:
+	andi	t0, t0, 0xf
+	beqz	t0, do_spurious
+
+loop:
+	andi	t2, t0, 0x1
+	srl	t0, 1
+	addi	a0, 1
+	beqz	t2, loop
+
+found_it:
+	move	a1, sp
+	jal	do_IRQ
+
+	j	ret_from_irq
+
+	END(vr4181_handle_irq)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/common/irq.c linux/arch/mips/vr4181/common/irq.c
--- linux.orig/arch/mips/vr4181/common/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/common/irq.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * linux/arch/mips/vr4181/common/irq.c
+ *	Completely re-written to use the new irq.c
+ *
+ * Credits to Bradley D. LaRonde and Michael Klar for writing the original
+ * irq.c file which was derived from the common irq.c file.
+ *	
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/gdb-stub.h>
+
+#include <asm/vr4181/vr4181.h>
+
+/*
+ * Strategy:
+ *
+ * We essentially have three irq controllers, CPU, system, and gpio.
+ *
+ * CPU irq controller is taken care by arch/mips/kernel/irq_cpu.c and
+ * CONFIG_IRQ_CPU config option.
+ *
+ * We here provide sys_irq and gpio_irq controller code.
+ */
+
+static int sys_irq_base;
+static int gpio_irq_base;
+
+/* ---------------------- sys irq ------------------------ */
+static void
+sys_irq_enable(unsigned int irq)
+{
+	irq -= sys_irq_base;
+	if (irq < 16) {
+		*VR4181_MSYSINT1REG |= (u16)(1 << irq);
+	} else {
+		irq -= 16;
+		*VR4181_MSYSINT2REG |= (u16)(1 << irq);
+	}
+}
+
+static void
+sys_irq_disable(unsigned int irq)
+{
+	irq -= sys_irq_base;
+	if (irq < 16) {
+		*VR4181_MSYSINT1REG &= ~((u16)(1 << irq));
+	} else {
+		irq -= 16;
+		*VR4181_MSYSINT2REG &= ~((u16)(1 << irq));
+	}
+
+}
+
+static unsigned int
+sys_irq_startup(unsigned int irq)
+{
+	sys_irq_enable(irq);
+	return 0;
+}
+
+#define sys_irq_shutdown	sys_irq_disable
+#define sys_irq_ack		sys_irq_disable
+
+static void
+sys_irq_end(unsigned int irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		sys_irq_enable(irq);
+}
+
+static hw_irq_controller sys_irq_controller = {
+	"vr4181_sys_irq",
+	sys_irq_startup,
+	sys_irq_shutdown,
+	sys_irq_enable,
+	sys_irq_disable,
+	sys_irq_ack,
+	sys_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+/* ---------------------- gpio irq ------------------------ */
+/* gpio irq lines use reverse logic */
+static void
+gpio_irq_enable(unsigned int irq)
+{
+	irq -= gpio_irq_base;
+	*VR4181_GPINTMSK &= ~((u16)(1 << irq));
+}
+
+static void
+gpio_irq_disable(unsigned int irq)
+{
+	irq -= gpio_irq_base;
+	*VR4181_GPINTMSK |= (u16)(1 << irq);
+}
+
+static unsigned int
+gpio_irq_startup(unsigned int irq)
+{
+	gpio_irq_enable(irq);
+
+	irq -= gpio_irq_base;
+	*VR4181_GPINTEN |= (u16)(1 << irq );
+
+	return 0;
+}
+
+static void
+gpio_irq_shutdown(unsigned int irq)
+{
+	gpio_irq_disable(irq);
+
+	irq -= gpio_irq_base;
+	*VR4181_GPINTEN &= ~((u16)(1 << irq ));
+}
+
+static void
+gpio_irq_ack(unsigned int irq)
+{
+	u16 irqtype;
+	u16 irqshift;
+
+	gpio_irq_disable(irq);
+
+	/* we clear interrupt if it is edge triggered */
+	irq -= gpio_irq_base;
+	if (irq < 8) {
+		irqtype = *VR4181_GPINTTYPL;
+		irqshift = 2 << (irq*2);
+	} else {
+		irqtype = *VR4181_GPINTTYPH;
+		irqshift = 2 << ((irq-8)*2);
+	}
+	if ( ! (irqtype & irqshift) ) {
+		*VR4181_GPINTSTAT = (u16) (1 << irq);
+	}
+}
+
+static void
+gpio_irq_end(unsigned int irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		gpio_irq_enable(irq);
+}
+
+static hw_irq_controller gpio_irq_controller = {
+	"vr4181_gpio_irq",
+	gpio_irq_startup,
+	gpio_irq_shutdown,
+	gpio_irq_enable,
+	gpio_irq_disable,
+	gpio_irq_ack,
+	gpio_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+/* ---------------------  IRQ init stuff ---------------------- */
+
+extern asmlinkage void vr4181_handle_irq(void);
+extern void breakpoint(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+extern void mips_cpu_irq_init(u32 irq_base);
+
+static struct irqaction cascade = 
+	{ no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL };
+static struct irqaction reserved = 
+	{ no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL };
+
+void __init init_IRQ(void)
+{
+	int i;
+	extern irq_desc_t irq_desc[];
+
+	set_except_vector(0, vr4181_handle_irq);
+
+	/* init CPU irqs */
+	mips_cpu_irq_init(VR4181_CPU_IRQ_BASE);
+
+	/* init sys irqs */
+	sys_irq_base = VR4181_SYS_IRQ_BASE;
+	for (i=sys_irq_base; i < sys_irq_base + VR4181_NUM_SYS_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &sys_irq_controller;
+	}
+
+	/* init gpio irqs */
+	gpio_irq_base = VR4181_GPIO_IRQ_BASE;
+	for (i=gpio_irq_base; i < gpio_irq_base + VR4181_NUM_GPIO_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &gpio_irq_controller;
+	}
+
+	/* Default all ICU IRQs to off ... */
+	*VR4181_MSYSINT1REG = 0;
+	*VR4181_MSYSINT2REG = 0;
+ 
+	/* We initialize the level 2 ICU registers to all bits disabled. */
+	*VR4181_MPIUINTREG = 0;
+	*VR4181_MAIUINTREG = 0;
+	*VR4181_MKIUINTREG = 0;
+
+	/* disable all GPIO intrs */
+	*VR4181_GPINTMSK = 0xffff;
+
+	/* vector handler.  What these do is register the IRQ as non-sharable */
+	setup_irq(VR4181_IRQ_INT0, &cascade);
+	setup_irq(VR4181_IRQ_GIU, &cascade);
+
+	/* 
+	 * RTC interrupts are interesting.  They have two destinations.
+	 * One is at sys irq controller, and the other is at CPU IP3 and IP4.
+	 * RTC timer is used as system timer.
+	 * We enable them here, but timer routine will register later
+	 * with CPU IP3/IP4.
+	 */
+	setup_irq(VR4181_IRQ_RTCL1, &reserved);
+	setup_irq(VR4181_IRQ_RTCL2, &reserved);
+
+#ifdef CONFIG_REMOTE_DEBUG
+	printk("Setting debug traps - please connect the remote debugger.\n");
+
+	set_debug_traps();
+
+	// you may move this line to whereever you want
+	breakpoint();
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/common/serial.c linux/arch/mips/vr4181/common/serial.c
--- linux.orig/arch/mips/vr4181/common/serial.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/common/serial.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/vr4181/common/serial.c
+ *     initialize serial port on vr4181.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * [jsun, 010925]
+ * You need to make sure rs_table has at least one element in 
+ * drivers/char/serial.c file.	There is no good way to do it right
+ * now.	 A workaround is to include CONFIG_SERIAL_MANY_PORTS in your
+ * configure file, which would gives you 64 ports and wastes 11K ram.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+
+#include <asm/vr4181/vr4181.h>
+
+void __init vr4181_init_serial(void)
+{
+	struct serial_struct s;
+
+	/* turn on UART clock */
+	*VR4181_CMUCLKMSK |= VR4181_CMUCLKMSK_MSKSIU;
+
+	/* clear memory */
+	memset(&s, 0, sizeof(s));
+
+	s.line = 0;			/* we set the first one */
+	s.baud_base = 1152000;
+	s.irq = VR4181_IRQ_SIU;
+	s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; /* STD_COM_FLAGS */
+	s.iomem_base = (u8*)VR4181_SIURB;
+	s.iomem_reg_shift = 0;
+	s.io_type = SERIAL_IO_MEM;
+	if (early_serial_setup(&s) != 0) {
+		panic("vr4181_init_serial() failed!");
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/common/time.c linux/arch/mips/vr4181/common/time.c
--- linux.orig/arch/mips/vr4181/common/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/common/time.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * rtc and time ops for vr4181.	 Part of code is drived from 
+ * linux-vr, originally written	 by Bradley D. LaRonde & Michael Klar.
+ *
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/param.h>			/* for HZ */
+#include <linux/time.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+
+#include <asm/vr4181/vr4181.h>
+
+#define COUNTS_PER_JIFFY ((32768 + HZ/2) / HZ)
+
+/*
+ * RTC ops
+ */
+
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+
+/* per VR41xx docs, bad data can be read if between 2 counts */
+static inline unsigned short 
+read_time_reg(volatile unsigned short *reg)
+{
+	unsigned short value;
+	do {
+		value = *reg;
+		barrier();
+	} while (value != *reg);
+	return value;
+}
+
+static unsigned long 
+vr4181_rtc_get_time(void)
+{
+	unsigned short regh, regm, regl;
+
+	// why this crazy order, you ask?  to guarantee that neither m
+	// nor l wrap before all 3 read
+	do {
+		regm = read_time_reg(VR4181_ETIMEMREG);
+		barrier();
+		regh = read_time_reg(VR4181_ETIMEHREG);
+		barrier();
+		regl = read_time_reg(VR4181_ETIMELREG);
+	} while (regm != read_time_reg(VR4181_ETIMEMREG));
+	return ((regh << 17) | (regm << 1) | (regl >> 15));
+}
+
+static int 
+vr4181_rtc_set_time(unsigned long timeval)
+{
+	unsigned short intreg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	intreg = *VR4181_RTCINTREG & 0x05;
+	barrier();
+	*VR4181_ETIMELREG = timeval << 15;
+	*VR4181_ETIMEMREG = timeval >> 1;
+	*VR4181_ETIMEHREG = timeval >> 17;
+	barrier();
+	// assume that any ints that just triggered are invalid, since the
+	// time value is written non-atomically in 3 separate regs
+	*VR4181_RTCINTREG = 0x05 ^ intreg;
+	spin_unlock_irqrestore(&rtc_lock, flags);
+
+	return 0;
+}
+
+
+/* 
+ * timer interrupt routine (wrapper)
+ *
+ * we need our own interrupt routine because we need to clear
+ * RTC1 interrupt.
+ */
+static void 
+vr4181_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Clear the interrupt. */
+	*VR4181_RTCINTREG = 0x2;
+
+	/* call the generic one */
+	timer_interrupt(irq, dev_id, regs);
+}
+
+
+/*
+ * vr4181_time_init:
+ *
+ * We pick the following choices:
+ *   . we use elapsed timer as the RTC.	 We set some reasonable init data since
+ *     it does not persist across reset
+ *   . we use RTC1 as the system timer interrupt source.
+ *   . we use CPU counter for fast_gettimeoffset and we calivrate the cpu
+ *     frequency.  In other words, we use calibrate_div64_gettimeoffset().
+ *   . we use our own timer interrupt routine which clears the interrupt
+ *     and then calls the generic high-level timer interrupt routine.
+ *
+ */
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+
+static void 
+vr4181_timer_setup(struct irqaction *irq)
+{
+	/* over-write the handler to be our own one */
+	irq->handler = vr4181_timer_interrupt;
+
+	/* sets up the frequency */
+	*VR4181_RTCL1LREG = COUNTS_PER_JIFFY;
+	*VR4181_RTCL1HREG = 0;
+
+	/* and ack any pending ints */
+	*VR4181_RTCINTREG = 0x2;
+
+	/* setup irqaction */
+	setup_irq(VR4181_IRQ_INT1, irq);
+
+}
+
+void
+vr4181_init_time(void)
+{
+	/* setup hookup functions */
+	rtc_get_time = vr4181_rtc_get_time;
+	rtc_set_time = vr4181_rtc_set_time;
+
+	board_timer_setup = vr4181_timer_setup;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/osprey/Makefile linux/arch/mips/vr4181/osprey/Makefile
--- linux.orig/arch/mips/vr4181/osprey/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/osprey/Makefile	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,17 @@
+#
+# Makefile for common code of NEC Osprey board
+#
+# 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 := osprey.o
+
+obj-y	 := setup.o prom.o reset.o
+
+obj-$(CONFIG_REMOTE_DEBUG)	+= dbg_io.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/osprey/dbg_io.c linux/arch/mips/vr4181/osprey/dbg_io.c
--- linux.orig/arch/mips/vr4181/osprey/dbg_io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/osprey/dbg_io.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,136 @@
+/*
+ * kgdb io functions for osprey.  We use the serial port on debug board.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * 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.
+ *
+ */
+
+/* ======================= CONFIG ======================== */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    0xb7fffff0
+#define         MAX_BAUD                115200
+
+/* distance in bytes between two serial registers */
+#define         REG_OFFSET              1
+
+/*
+ * 0 - kgdb does serial init
+ * 1 - kgdb skip serial init
+ */
+static int remoteDebugInitialized = 1;
+
+/*
+ * the default baud rate *if* kgdb does serial init
+ */
+#define		BAUD_DEFAULT		UART16550_BAUD_38400
+
+/* ======================= END OF CONFIG ======================== */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+        /* disable interrupts */
+        UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+        /* set up buad rate */
+        {
+                uint32 divisor;
+
+                /* set DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+                /* set divisor */
+                divisor = MAX_BAUD / baud;
+                UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+                UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+                /* clear DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+        }
+
+        /* set data format */
+        UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+
+uint8 getDebugChar(void)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+        return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+        UART16550_WRITE(OFS_SEND_BUFFER, byte);
+        return 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/osprey/prom.c linux/arch/mips/vr4181/osprey/prom.c
--- linux.orig/arch/mips/vr4181/osprey/prom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/osprey/prom.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/vr4181/osprey/prom.c
+ *     prom code for osprey.
+ *
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	return "NEC_Vr41xx Osprey";
+}
+
+/* 
+ * [jsun] right now we assume it is the nec debug monitor, which does
+ * not pass any arguments.
+ */
+void __init prom_init()
+{
+	strcpy(arcs_cmdline, "ip=bootp ");
+	strcat(arcs_cmdline, "ether=46,0x03fe0300,eth0 ");
+	// strcpy(arcs_cmdline, "ether=0,0x0300,eth0 "
+	// strcat(arcs_cmdline, "video=vr4181fb:xres:240,yres:320,bpp:8 ");
+
+	mips_machgroup = MACH_GROUP_NEC_VR41XX;
+	mips_machtype = MACH_NEC_OSPREY;
+
+	/* 16MB fixed */
+	add_memory_region(0, 16 << 20, BOOT_MEM_RAM);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/osprey/reset.c linux/arch/mips/vr4181/osprey/reset.c
--- linux.orig/arch/mips/vr4181/osprey/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/osprey/reset.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void nec_osprey_restart(char *command)
+{
+	set_cp0_status(ST0_ERL);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void nec_osprey_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+			"wait\n\t"
+			".set\tmips0");
+}
+
+void nec_osprey_power_off(void)
+{
+	nec_osprey_halt();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips/vr4181/osprey/setup.c linux/arch/mips/vr4181/osprey/setup.c
--- linux.orig/arch/mips/vr4181/osprey/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips/vr4181/osprey/setup.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,71 @@
+/*
+ * linux/arch/mips/vr4181/setup.c
+ *
+ * VR41xx setup routines
+ *
+ * Copyright (C) 1999 Bradley D. LaRonde
+ * Copyright (C) 1999, 2000 Michael Klar
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/reboot.h>
+#include <asm/vr4181/vr4181.h>
+#include <asm/io.h>
+
+
+extern void nec_osprey_restart(char* c);
+extern void nec_osprey_halt(void);
+extern void nec_osprey_power_off(void);
+
+extern void vr4181_init_serial(void);
+extern void vr4181_init_time(void);
+
+void __init nec_osprey_setup(void)
+{
+	set_io_port_base(VR4181_PORT_BASE);
+	isa_slot_offset = VR4181_ISAMEM_BASE;
+
+	vr4181_init_serial();
+	vr4181_init_time();
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+ 
+	_machine_restart = nec_osprey_restart;
+	_machine_halt = nec_osprey_halt;
+	_machine_power_off = nec_osprey_power_off;
+
+	/* setup resource limit */
+	ioport_resource.end = 0xffffffff;
+	iomem_resource.end = 0xffffffff;
+
+	/* [jsun] hack */
+	/*
+	printk("[jsun] hack to change external ISA control register, %x -> %x\n",
+		(*VR4181_XISACTL),
+		(*VR4181_XISACTL) | 0x2);
+	*VR4181_XISACTL |= 0x2;
+	*/
+
+	// *VR4181_GPHIBSTH = 0x2000;
+	// *VR4181_GPMD0REG = 0x00c0;
+	// *VR4181_GPINTEN	 = 1<<6;
+
+	/* [jsun] I believe this will get the interrupt type right 
+	 * for the ether port.
+	 */
+	*VR4181_GPINTTYPL = 0x3000;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/Makefile linux/arch/mips64/Makefile
--- linux.orig/arch/mips64/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -3,6 +3,8 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
+# Copyright (C) 2002  Maciej W. Rozycki
+#
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
 # for "archclean" and "archdep" for cleaning up and making dependencies for
@@ -12,7 +14,6 @@
 #
 # Select the object file format to substitute into the linker script.
 #
-CPP=$(CC) -E
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 tool-prefix	= mips64el-linux-
 else
@@ -20,7 +21,7 @@
 endif
 
 ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE  = $(tool-prefix)
+CROSS_COMPILE	= $(tool-prefix)
 endif
 
 #
@@ -33,91 +34,162 @@
 # machines may also.  Since BFD is incredibly buggy with respect to
 # crossformat linking we rely on the elf2ecoff tool for format conversion.
 #
-CFLAGS		+= -I $(TOPDIR)/include/asm/gcc $(CFLAGS)
-CFLAGS		+= -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe
+GCCFLAGS	:= -I $(TOPDIR)/include/asm/gcc
+GCCFLAGS	+= -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe
 LINKFLAGS	+= -G 0 -static # -N
 MODFLAGS	+= -mlong-calls
 
 ifdef CONFIG_REMOTE_DEBUG
-CFLAGS		:= $(CFLAGS) -g
+GCCFLAGS	+= -g
 endif
 
 #
 # CPU-dependent compiler/assembler options for optimization.
 #
 ifdef CONFIG_CPU_R4300
-CFLAGS		:= $(CFLAGS) -mcpu=r4300 -mips3
+GCCFLAGS	+= -mcpu=r4300 -mips3
 endif
 ifdef CONFIG_CPU_R4X00
-CFLAGS		:= $(CFLAGS) -mcpu=r4600 -mips3
+GCCFLAGS	+= -mcpu=r4600 -mips3
 endif
 ifdef CONFIG_CPU_R5000
-CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips4
+GCCFLAGS	+= -mcpu=r8000 -mips4
 endif
 ifdef CONFIG_CPU_NEVADA
-CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips3 -mmad
+GCCFLAGS	+= -mcpu=r8000 -mips3 -mmad
 endif
 ifdef CONFIG_CPU_R8000
-CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips4
+GCCFLAGS	+= -mcpu=r8000 -mips4
 endif
 ifdef CONFIG_CPU_R10000
-CFLAGS		:= $(CFLAGS) -mcpu=r8000 -mips4
+GCCFLAGS	+= -mcpu=r8000 -mips4
 endif
-
-ifdef CONFIG_MIPS_FPU_EMULATOR
-CORE_FILES	+= arch/mips64/math-emu/fpu_emulator.o
-SUBDIRS		+= arch/mips64/math-emu
+ifdef CONFIG_CPU_SB1
+GCCFLAGS	+= -mcpu=r8000 -mips4
 endif
 
+AFLAGS		+= $(GCCFLAGS)
+CFLAGS		+= $(GCCFLAGS)
+
+
+#
+# We unconditionally build the math emulator
+#
+CORE_FILES	+= arch/mips/math-emu/fpu_emulator.o
+SUBDIRS		+= arch/mips/math-emu
+
+
 #
 # Board-dependent options and extra files
 #
+
+#
+# MIPS Atlas board
+#
+ifdef CONFIG_MIPS_ATLAS
+LIBS		+= arch/mips/mips-boards/atlas/atlas.o \
+		   arch/mips/mips-boards/generic/mipsboards.o
+SUBDIRS		+= arch/mips/mips-boards/generic arch/mips/mips-boards/atlas
+LOADADDR	:= 0x80100000
+endif
+
+#
+# MIPS Malta board
+#
+ifdef CONFIG_MIPS_MALTA
+LIBS		+= arch/mips/mips-boards/malta/malta.o \
+		   arch/mips/mips-boards/generic/mipsboards.o
+SUBDIRS		+= arch/mips/mips-boards/malta arch/mips/mips-boards/generic
+LOADADDR	:= 0x80100000
+endif
+
+#
+# SGI IP22 (Indy/Indigo2)
+#
 ifdef CONFIG_SGI_IP22
-LIBS          += arch/mips64/sgi-ip22/ip22.a arch/mips64/arc/arclib.a
-SUBDIRS       += arch/mips64/sgi-ip22 arch/mips64/arc
+CORE_FILES	+= arch/mips/sgi-ip22/ip22-kern.o
+LIBS		+= arch/mips64/arc/arclib.a 
+SUBDIRS		+= arch/mips/sgi-ip22 arch/mips64/arc
 #
 # Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
 # 0x88004000 for production kernels.  Note that the value must be
 # 16kb aligned or the handling of the current variable will break.
 #
-LOADADDR      += 0x88004000
+LOADADDR	:= 0x88004000
 endif
 
+#
+# SGI-IP27 (Origin200/2000)
+#
 ifdef CONFIG_SGI_IP27
-CORE_FILES    += arch/mips64/sgi-ip27/ip27.o
-LIBS          += arch/mips64/arc/arclib.a
-SUBDIRS       += arch/mips64/sgi-ip27 arch/mips64/arc
+CORE_FILES	+= arch/mips64/sgi-ip27/ip27.o
+LIBS		+= arch/mips64/arc/arclib.a
+SUBDIRS		+= arch/mips64/sgi-ip27 arch/mips64/arc
 #
 # Set LOADADDR to >= 0xc000000000300000 if you want to leave space for
 # symmon, 0xc00000000001c000 for production kernels.  Note that the value
 # must be 16kb aligned or the handling of the current variable will break.
 #
-#LOADADDR      += 0xa80000000001c000
+#LOADADDR	:= 0xa80000000001c000
 ifdef CONFIG_MAPPED_KERNEL
-LOADADDR      += 0xc001c000
+LOADADDR	:= 0xc001c000
 else
-LOADADDR      += 0x8001c000
+LOADADDR	:= 0x8001c000
 endif
 endif
 
+#
+# SGI-IP32 (O2)
+#
 ifdef CONFIG_SGI_IP32
-LIBS		+= arch/mips64/sgi-ip32/ip32-kern.a arch/mips64/arc/arclib.a
+CORE_FILES	+= arch/mips64/sgi-ip32/ip32-kern.a
+LIBS		+= arch/mips64/arc/arclib.a
 SUBDIRS		+= arch/mips64/sgi-ip32 arch/mips64/arc
 #
 # Set LOADADDR to >= 0x????????? if you want to leave space for symmon,
 # 0x80002000 for production kernels.  Note that the value must be
 # 16kb aligned or the handling of the current variable will break.
 #
-LOADADDR	+= 0x80002000
+LOADADDR	:= 0x80002000
+endif
+
+#
+# Sibyte SB1250 SOC
+#
+ifdef CONFIG_SIBYTE_SB1250
+# This is a LIB so that it links at the end, and initcalls are later
+# the sequence; but it is built as an object so that modules don't get
+# removed (as happens, even if they have __initcall/module_init)
+LIBS		+= arch/mips/sibyte/sb1250/sb1250.o
+SUBDIRS		+= arch/mips/sibyte/sb1250
 endif
 
 #
+# Sibyte SWARM board
+#
+ifdef CONFIG_SIBYTE_SWARM
+LIBS		+= arch/mips/sibyte/swarm/sbswarm.a
+SUBDIRS		+= arch/mips/sibyte/swarm
+LOADADDR	:= 0x80100000
+endif
+
+#
+# SB1 Cache Error handler
+#
+ifdef CONFIG_SB1_CACHE_ERROR
+LIBS		+= arch/mips/sibyte/sb1/sb1kern.a
+SUBDIRS		+= arch/mips/sibyte/sb1
+endif
+
+
+#
 # Some machines like the Indy need 32-bit ELF binaries for booting purposes.
 # Other need ECOFF, so we build a 32-bit ELF binary for them which we then
 # convert to ECOFF using elf2ecoff.
 #
 ifdef CONFIG_BOOT_ELF32
 CFLAGS += -Wa,-32
+AFLAGS += -Wa,-32
 LINKFLAGS += -T arch/mips64/ld.script.elf32
 endif
 #
@@ -126,6 +198,7 @@
 #
 ifdef CONFIG_BOOT_ELF64
 CFLAGS += -Wa,-32
+AFLAGS += -Wa,-32
 LINKFLAGS += -T arch/mips64/ld.script.elf32
 #AS += -64
 #LD += -m elf64bmip
@@ -179,6 +252,6 @@
 
 archdep:
 	if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \
-	 touch $(TOPDIR)/include/asm-$(ARCH)/offset.h; \
+		touch $(TOPDIR)/include/asm-$(ARCH)/offset.h; \
 	fi;
 	@$(MAKEBOOT) dep
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/arc/arc_con.c linux/arch/mips64/arc/arc_con.c
--- linux.orig/arch/mips64/arc/arc_con.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips64/arc/arc_con.c	2002-07-20 01:08:39.000000000 +0000
@@ -39,33 +39,17 @@
 	}
 }
 
-static int prom_console_wait_key(struct console *co)
-{
-	return 0;
-}
-
-static int __init prom_console_setup(struct console *co, char *options)
-{
-	return 0;
-}
-
 static kdev_t prom_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
 }
 
 static struct console arc_cons = {
-	"ttyS",
-	prom_console_write,
-	NULL,
-	prom_console_device,
-	prom_console_wait_key,
-	NULL,
-	prom_console_setup,
-	CON_PRINTBUFFER,
-	-1,
-	0,
-	NULL
+    name:	"ttyS",
+    write:	prom_console_write,
+    device:	prom_console_device,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
 };
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/arc/identify.c linux/arch/mips64/arc/identify.c
--- linux.orig/arch/mips64/arc/identify.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips64/arc/identify.c	2002-07-20 01:08:29.000000000 +0000
@@ -21,38 +21,75 @@
 #include <asm/bootinfo.h>
 
 struct smatch {
-	char *name;
+	char *arcname;
+	char *liname;
 	int group;
 	int type;
 	int flags;
 };
 
 static struct smatch mach_table[] = {
-	{ "SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS },
-	{ "SGI-IP27", MACH_GROUP_SGI, MACH_SGI_IP27, PROM_FLAG_ARCS },
-	{ "Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0 },
-	{ "PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0 },
-	{ "RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0 }
+	{	"SGI-IP22",
+		"SGI Indy",
+		MACH_GROUP_SGI,
+		MACH_SGI_INDY,
+		PROM_FLAG_ARCS
+	}, {	"SGI-IP27",
+		"SGI Origin",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP27,
+		PROM_FLAG_ARCS
+	}, {	"SGI-IP28",
+		"SGI IP28",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP28,
+		PROM_FLAG_ARCS
+	}, {	"SGI-IP32",
+		"SGI IP32",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP32,
+		PROM_FLAG_ARCS
+	}, {	"Microsoft-Jazz",
+		"Jazz MIPS_Magnum_4000",
+		MACH_GROUP_JAZZ,
+		MACH_MIPS_MAGNUM_4000,
+		0
+	}, {	"PICA-61",
+		"Jazz Acer_PICA_61",
+		MACH_GROUP_JAZZ,
+		MACH_ACER_PICA_61,
+		0
+	}, {	"RM200PCI",
+		"SNI RM200_PCI",
+		MACH_GROUP_SNI_RM,
+		MACH_SNI_RM200_PCI,
+		0
+	}
 };
 
 int prom_flags;
 
-static struct smatch * __init
-string_to_mach(const char *s)
+static struct smatch * __init string_to_mach(const char *s)
 {
 	int i;
     
 	for (i = 0; i < (sizeof (mach_table) / sizeof (mach_table[0])); i++) {
-		if(!strcmp(s, mach_table[i].name))
+		if(!strcmp(s, mach_table[i].arcname))
 			return &mach_table[i];
 	}
-	panic("\nYeee, could not determine architecture type <%s>", s);
+	panic("Yeee, could not determine architecture type <%s>", s);
 
 	return NULL;
 }
 
-void __init
-prom_identify_arch(void)
+char *system_type;
+
+const char *get_system_type(void)
+{
+	return system_type;
+}
+
+void __init prom_identify_arch(void)
 {
 	pcomponent *p;
 	struct smatch *mach;
@@ -70,8 +107,9 @@
 	} else
 		iname = (char *) (long) p->iname;
 
-	printk("ARCH: %s\n", iname);
+	printk(KERN_INFO "ARCH: %s\n", iname);
 	mach = string_to_mach(iname);
+	system_type = mach->liname;
 
 	mips_machgroup = mach->group;
 	mips_machtype = mach->type;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/arc/init.c linux/arch/mips64/arc/init.c
--- linux.orig/arch/mips64/arc/init.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/arc/init.c	2002-07-20 01:08:30.000000000 +0000
@@ -16,45 +16,34 @@
 
 /* Master romvec interface. */
 struct linux_romvec *romvec;
-PSYSTEM_PARAMETER_BLOCK sgi_pblock;
 int prom_argc;
 LONG *_prom_argv, *_prom_envp;
-unsigned short prom_vers, prom_rev;
 
-extern void prom_testtree(void);
-
-int __init
-prom_init(int argc, char **argv, char **envp)
+int __init prom_init(int argc, char **argv, char **envp)
 {
-	PSYSTEM_PARAMETER_BLOCK pb;
-
+	PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
 	romvec = ROMVECTOR;
-	pb = sgi_pblock = PROMBLOCK;
 	prom_argc = argc;
 	_prom_argv = (LONG *) argv;
 	_prom_envp = (LONG *) envp;
 
 	if(pb->magic != 0x53435241) {
-		prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
+		prom_printf("Aieee, bad prom vector magic %08lx\n",
+			    pb->magic);
 		while(1)
 			;
 	}
 
 	prom_init_cmdline();
-
-	prom_vers = pb->ver;
-	prom_rev = pb->rev;
 	prom_identify_arch();
-	printk("PROMLIB: ARC firmware Version %d Revision %d\n",
-		    prom_vers, prom_rev);
+	printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
+	       pb->ver, pb->rev);
 	prom_meminit();
 
 #ifdef DEBUG_PROM_INIT
-	{
-		prom_printf("Press a key to reboot\n");
-		(void) prom_getchar();
-		ArcEnterInteractiveMode();
-	}
+	prom_printf("Press a key to reboot\n");
+	prom_getchar();
+	ArcEnterInteractiveMode();
 #endif
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/arc/memory.c linux/arch/mips64/arc/memory.c
--- linux.orig/arch/mips64/arc/memory.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/arc/memory.c	2002-07-20 01:08:36.000000000 +0000
@@ -26,8 +26,7 @@
 
 #undef DEBUG
 
-struct linux_mdesc * __init
-ArcGetMemoryDescriptor(struct linux_mdesc *Current)
+struct linux_mdesc* __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
 {
 	return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
 }
@@ -100,7 +99,7 @@
 
 static int __init prom_memtype_classify (union linux_memtypes type)
 {
-	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ...  */
+	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ... */
 		return memtype_classify_arcs(type);
 
 	return memtype_classify_arc(type);
@@ -114,10 +113,7 @@
 	int i = 0;
 
 	prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
-	i=0;
-	prom_printf ("i=%d\n", i);
 	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
-	prom_printf ("i=%d\n", i);
 	while(p) {
 		prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
 			    i, p, p->base, p->pages, mtypes(p->type));
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/arc/misc.c linux/arch/mips64/arc/misc.c
--- linux.orig/arch/mips64/arc/misc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/arc/misc.c	2002-07-20 01:08:26.000000000 +0000
@@ -20,7 +20,6 @@
 #include <asm/bootinfo.h>
 #include <asm/system.h>
 
-extern unsigned long mips_cputype;
 extern void *sgiwd93_host;
 extern void reset_wd33c93(void *instance);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/arc/tree.c linux/arch/mips64/arc/tree.c
--- linux.orig/arch/mips64/arc/tree.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/arc/tree.c	2002-07-20 01:08:39.000000000 +0000
@@ -10,8 +10,10 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #include <linux/init.h>
+
 #include <asm/arc/types.h>
 #include <asm/sgialib.h>
+#include <asm/sgiarcs.h>
 
 #undef DEBUG_PROM_TREE
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/boot/Makefile linux/arch/mips64/boot/Makefile
--- linux.orig/arch/mips64/boot/Makefile	2001-02-05 05:48:46.000000000 +0000
+++ linux/arch/mips64/boot/Makefile	2002-07-20 01:08:39.000000000 +0000
@@ -6,10 +6,7 @@
 # Copyright (C) 1995, 1998, 1999 by Ralf Baechle
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 #
 # Some DECstations need all possible sections of an ECOFF executable
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/config.in linux/arch/mips64/config.in
--- linux.orig/arch/mips64/config.in	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/config.in	2002-07-20 01:08:26.000000000 +0000
@@ -2,7 +2,10 @@
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
-mainmenu_name "Linux Kernel Configuration"
+define_bool CONFIG_MIPS y
+define_bool CONFIG_MIPS64 y
+
+mainmenu_name "Linux/MIPS64 Kernel Configuration"
 
 mainmenu_option next_comment
 comment 'Code maturity level options'
@@ -10,11 +13,20 @@
 endmenu
 
 mainmenu_option next_comment
-comment 'Machine selection'
-choice 'Machine type'						\
-	"SGI-IP22,Indy/Indigo2 CONFIG_SGI_IP22			\
-	 SGI-IP27,Origin200/2000 CONFIG_SGI_IP27 SGI-IP27,Origin200/2000"
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
 
+mainmenu_option next_comment
+comment 'Machine selection'
+dep_bool 'Support for MIPS Atlas board (EXPERIMENTAL)' CONFIG_MIPS_ATLAS $CONFIG_EXPERIMENTAL
+dep_bool 'Support for MIPS Malta board (EXPERIMENTAL)' CONFIG_MIPS_MALTA $CONFIG_EXPERIMENTAL
+dep_bool 'Support for SGI-IP22 (Indy/Indigo2) (EXPERIMENTAL)' CONFIG_SGI_IP22 $CONFIG_EXPERIMENTAL
+bool 'Support for SGI-IP27 (Origin200/2000)' CONFIG_SGI_IP27
 if [ "$CONFIG_SGI_IP27" = "y" ]; then
    bool '  IP27 N-Mode' CONFIG_SGI_SN0_N_MODE
    bool '  Discontiguous Memory Support' CONFIG_DISCONTIGMEM
@@ -25,69 +37,105 @@
    bool '  Multi-Processing support' CONFIG_SMP
    #bool '  IP27 XXL' CONFIG_SGI_SN0_XXL
 fi
-endmenu
+dep_bool 'Support for SGI-IP32 (O2) (EXPERIMENTAL)' CONFIG_SGI_IP32 $CONFIG_EXPERIMENTAL
+bool 'Support for SiByte SB1250 SOC' CONFIG_SIBYTE_SB1250
+if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+   bool '  Support for SB1250 onchip PCI controller' CONFIG_PCI
+   bool '  Support for SB1250 profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF
+   bool '  Support for BCM1250 profiling using trace buffer' CONFIG_BCM1250_TBPROF
+   bool '  Remote debugging (kgdb over UART 1)' CONFIG_REMOTE_DEBUG
+   bool '  Support for SiByte SWARM board' CONFIG_SIBYTE_SWARM
+   if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
+      bool '    Running under simulation' CONFIG_SIMULATION
+      bool '    Configure for L3proc Demo' CONFIG_L3DEMO
+      int '    Maximum memory chunks' CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS 16
+      bool '    Multi-Processing support' CONFIG_SMP
+   fi
+fi
 
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
 
 #
-# Select some configuration options automatically based on user selections
+# Select some configuration options automatically based on user selections.
 #
-unset CONFIG_ARC32
-unset CONFIG_ARC64
-unset CONFIG_BINFMT_ELF32
-unset CONFIG_BOARD_SCACHE
-unset CONFIG_BOOT_ELF32
-unset CONFIG_BOOT_ELF64
-unset CONFIG_COHERENT_IO
-unset CONFIG_ISA
-unset CONFIG_MAPPED_PCI_IO
-unset CONFIG_PCI
 
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
+if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF32 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_SWAP_IO_SPACE y
+fi
+if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
    define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_I8259 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_SWAP_IO_SPACE y
+fi
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
    define_bool CONFIG_ARC32 y
-   define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_ARC_CONSOLE y
    define_bool CONFIG_ARC_MEMORY y
+   define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_SGI y
    define_int CONFIG_L1_CACHE_SHIFT 5
 fi
-
 if [ "$CONFIG_SGI_IP27" = "y" ]; then
    define_bool CONFIG_BOOT_ELF64 y
    define_bool CONFIG_ARC64 y
-   define_bool CONFIG_COHERENT_IO y
    define_bool CONFIG_MAPPED_PCI_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_QL_ISP_A64 y
    define_int CONFIG_L1_CACHE_SHIFT 7
 fi
-
-if [ "$CONFIG_ISA" != "y" ]; then
-   define_bool CONFIG_ISA n
-   define_bool CONFIG_EISA n
-else
-   define_bool CONFIG_EISA y
+if [ "$CONFIG_SGI_IP32" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_PCI y
+   #define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_MAPPED_PCI_IO n
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_ARC_MEMORY y
+   define_int CONFIG_L1_CACHE_SHIFT 5
 fi
-
-if [ "$CONFIG_PCI" != "y" ]; then
-   define_bool CONFIG_PCI n
+if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_CFE y
+   define_bool CONFIG_SIBYTE_SB1250 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
 fi
-
-define_bool CONFIG_MCA n
-define_bool CONFIG_SBUS n
+endmenu
 
 mainmenu_option next_comment
 comment 'CPU selection'
 
-choice 'CPU type'				\
-	"R4300 CONFIG_CPU_R4300			\
-	 R4x00 CONFIG_CPU_R4X00			\
-	 R5000 CONFIG_CPU_R5000			\
-	 R52x0 CONFIG_CPU_NEVADA		\
-	 R8000 CONFIG_CPU_R8000			\
-	 R10000 CONFIG_CPU_R10000" R4x00
-endmenu
+choice 'CPU type' \
+	"R4300	CONFIG_CPU_R4300 \
+	 R4x00	CONFIG_CPU_R4X00 \
+	 R5000	CONFIG_CPU_R5000 \
+	 R52x0	CONFIG_CPU_NEVADA \
+	 R8000	CONFIG_CPU_R8000 \
+	 R10000	CONFIG_CPU_R10000 \
+	 SB1	CONFIG_CPU_SB1" R4x00
+endmenu
+
+if [ "$CONFIG_CPU_SB1" = "y" ]; then
+   bool '  Workarounds for pass 1 sb1 bugs' CONFIG_SB1_PASS_1_WORKAROUNDS
+   bool '  Support for SB1 Cache Error handler' CONFIG_SB1_CACHE_ERROR
+   define_bool CONFIG_VTAG_ICACHE y
+fi
+
+define_bool CONFIG_CPU_HAS_LLSC y
+define_bool CONFIG_CPU_HAS_LLDSCD y
 
 mainmenu_option next_comment
 comment 'General setup'
@@ -97,55 +145,55 @@
 fi
 bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   bool 'Kernel floating-point emulation' CONFIG_MIPS_FPU_EMULATOR
+if [ "$CONFIG_ARC32" = "y" ]; then
+   bool 'ARC console support' CONFIG_ARC_CONSOLE
 fi
 
 bool 'Networking support' CONFIG_NET
 
+if [ "$CONFIG_PCI" != "y" ]; then
+   define_bool CONFIG_PCI n
+fi
+
 source drivers/pci/Config.in
 
+if [ "$CONFIG_ISA" != "y" ]; then
+   define_bool CONFIG_ISA n
+   define_bool CONFIG_EISA n
+else
+   define_bool CONFIG_EISA y
+fi
+
+define_bool CONFIG_MCA n
+define_bool CONFIG_SBUS n
+
 bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
 
 if [ "$CONFIG_HOTPLUG" = "y" ] ; then
    source drivers/pcmcia/Config.in
+   source drivers/hotplug/Config.in
 else
    define_bool CONFIG_PCMCIA n
+   define_bool CONFIG_HOTPLUG_PCI n
 fi
 
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
-
-if [ "$CONFIG_ARC32" = "y" ]; then
-   bool 'ARC console support' CONFIG_ARC_CONSOLE
-fi
-
+define_bool CONFIG_KCORE_ELF y
+define_bool CONFIG_KCORE_AOUT n
 tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
 bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT
-if [ "$CONFIG_MIPS32_COMPAT" = "y" ]; then
-   define_bool CONFIG_BINFMT_ELF32 y
-fi
+define_bool CONFIG_BINFMT_ELF32 $CONFIG_MIPS32_COMPAT
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-
-endmenu
-
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-   bool 'Kernel module loader' CONFIG_KMOD
-fi
-
-source drivers/pci/Config.in
-
 endmenu
 
 source drivers/mtd/Config.in
 
 source drivers/parport/Config.in
 
+source drivers/pnp/Config.in
+
 source drivers/block/Config.in
 
 source drivers/md/Config.in
@@ -156,18 +204,21 @@
 
 source drivers/telephony/Config.in
 
-mainmenu_option next_comment
-comment 'ATA/IDE/MFM/RLL support'
+if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" ]; then
+
+   mainmenu_option next_comment
+   comment 'ATA/IDE/MFM/RLL support'
 
-tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+   tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
 
-if [ "$CONFIG_IDE" != "n" ]; then
-  source drivers/ide/Config.in
-else
-  define_bool CONFIG_BLK_DEV_IDE_MODES n
-  define_bool CONFIG_BLK_DEV_HD n
+   if [ "$CONFIG_IDE" != "n" ]; then
+      source drivers/ide/Config.in
+   else
+      define_bool CONFIG_BLK_DEV_IDE_MODES n
+      define_bool CONFIG_BLK_DEV_HD n
+   fi
+   endmenu
 fi
-endmenu
 
 mainmenu_option next_comment
 comment 'SCSI support'
@@ -179,7 +230,9 @@
 fi
 endmenu
 
-#source drivers/message/i2o/Config.in
+if [ "$CONFIG_PCI" = "y" ]; then
+   source drivers/message/i2o/Config.in
+fi
 
 if [ "$CONFIG_NET" = "y" ]; then
    mainmenu_option next_comment
@@ -199,25 +252,27 @@
 
 source net/irda/Config.in
 
-mainmenu_option next_comment
-comment 'ISDN subsystem'
-
 if [ "$CONFIG_NET" != "n" ]; then
+   mainmenu_option next_comment
+   comment 'ISDN subsystem'
+
    tristate 'ISDN support' CONFIG_ISDN
    if [ "$CONFIG_ISDN" != "n" ]; then
       source drivers/isdn/Config.in
    fi
+   endmenu
 fi
-endmenu
 
-mainmenu_option next_comment
-comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+if [ "$CONFIG_ISA" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
-bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
-if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-   source drivers/cdrom/Config.in
+   bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+   if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+      source drivers/cdrom/Config.in
+   fi
+   endmenu
 fi
-endmenu
 
 source drivers/char/Config.in
 
@@ -225,25 +280,30 @@
 
 source drivers/media/Config.in
 
-source fs/Config.in
-
-if [ "$CONFIG_VT" = "y" ]; then
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
    mainmenu_option next_comment
-   comment 'Console drivers'
-   source drivers/video/Config.in
-   if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   comment 'SGI Character devices'
+   if [ "$CONFIG_VT" = "y" ]; then
       tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
-      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
-	 define_bool CONFIG_DUMMY_CONSOLE y
-      else
-	 define_bool CONFIG_FONT_8x16 y
+      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then
+         define_bool CONFIG_FONT_8x16 y
       fi
+      define_bool CONFIG_DUMMY_CONSOLE y
    fi
-  endmenu
+   endmenu
 fi
 
-if [ "$CONFIG_PROC_FS" = "y" ]; then
-   define_bool CONFIG_KCORE_ELF y
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   bool 'VGA text console' CONFIG_VGA_CONSOLE
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+      source drivers/video/Config.in
+   fi
+   endmenu
 fi
 
 mainmenu_option next_comment
@@ -260,6 +320,9 @@
 fi
 
 source drivers/usb/Config.in
+
+source net/bluetooth/Config.in
+
 source drivers/input/Config.in
 
 mainmenu_option next_comment
@@ -267,9 +330,6 @@
 
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool ' Build fp execption handler module' CONFIG_MIPS_FPE_MODULE
-fi
 bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 if [ "$CONFIG_SMP" != "y" ]; then
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/defconfig linux/arch/mips64/defconfig
--- linux.orig/arch/mips64/defconfig	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/defconfig	2002-07-20 01:08:28.000000000 +0000
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
 
 #
 # Code maturity level options
@@ -8,8 +10,15 @@
 # CONFIG_EXPERIMENTAL is not set
 
 #
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
 # Machine selection
 #
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
@@ -19,19 +28,16 @@
 # CONFIG_REPLICATE_KTEXT is not set
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_SMP=y
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1250 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
-CONFIG_COHERENT_IO=y
 CONFIG_MAPPED_PCI_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 CONFIG_L1_CACHE_SHIFT=7
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 
 #
 # CPU selection
@@ -42,6 +48,9 @@
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 CONFIG_CPU_R10000=y
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 
 #
 # General setup
@@ -50,23 +59,24 @@
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_NET=y
 CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-CONFIG_PCI_NAMES=y
-
-#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -77,6 +87,12 @@
 # CONFIG_PARPORT 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
@@ -84,7 +100,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -99,6 +117,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
 
 #
@@ -106,8 +125,6 @@
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK=y
-CONFIG_RTNETLINK=y
 CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -124,12 +141,18 @@
 # CONFIG_IP_MROUTE is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
 #  
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 
@@ -139,6 +162,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -204,8 +232,8 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 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
@@ -223,6 +251,16 @@
 # CONFIG_SCSI_U14_34F is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -245,7 +283,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -266,6 +303,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_PLIP is not set
 # CONFIG_PPP is not set
@@ -303,11 +341,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -347,7 +380,6 @@
 # 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
@@ -380,7 +412,6 @@
 # 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_JBD_DEBUG is not set
@@ -393,11 +424,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS 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_FREEVXFS_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
@@ -439,6 +471,8 @@
 # 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
@@ -460,7 +494,6 @@
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
-CONFIG_KCORE_ELF=y
 
 #
 # Sound
@@ -473,98 +506,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/defconfig-atlas linux/arch/mips64/defconfig-atlas
--- linux.orig/arch/mips64/defconfig-atlas	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/defconfig-atlas	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,521 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+CONFIG_MIPS_ATLAS=y
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1250 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BOOT_ELF32=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PCI=y
+CONFIG_SWAP_IO_SPACE=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM 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 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 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=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA 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=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_CPQFCTS 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_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
+# 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_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_TIGON3 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_NVRAM is not set
+CONFIG_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=y
+# 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=y
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# 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_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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/defconfig-ip22 linux/arch/mips64/defconfig-ip22
--- linux.orig/arch/mips64/defconfig-ip22	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/defconfig-ip22	2002-07-20 01:08:23.000000000 +0000
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
 
 #
 # Code maturity level options
@@ -8,23 +10,33 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
 # Machine selection
 #
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
 CONFIG_SGI_IP22=y
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1250 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_BOOT_ELF32=y
 CONFIG_ARC32=y
-CONFIG_BOARD_SCACHE=y
+CONFIG_ARC_CONSOLE=y
 CONFIG_ARC_MEMORY=y
+CONFIG_BOARD_SCACHE=y
+CONFIG_IRQ_CPU=y
+CONFIG_PC_KEYB=y
+CONFIG_BOOT_ELF32=y
+CONFIG_NONCOHERENT_IO=y
 CONFIG_SGI=y
 CONFIG_L1_CACHE_SHIFT=5
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_PCI is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 
 #
 # CPU selection
@@ -35,32 +47,35 @@
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
-# CONFIG_MIPS_FPU_EMULATOR is not set
+CONFIG_ARC_CONSOLE=y
 CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-# CONFIG_ARC_CONSOLE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -71,6 +86,12 @@
 # CONFIG_PARPORT 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
@@ -78,7 +99,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -93,6 +116,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
 
 #
@@ -100,8 +124,6 @@
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK=y
-CONFIG_RTNETLINK=y
 CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -122,12 +144,18 @@
 # 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -145,6 +173,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -152,13 +185,6 @@
 # CONFIG_PHONE_IXJ_PCMCIA 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=y
@@ -192,6 +218,7 @@
 # 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
@@ -211,7 +238,6 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
@@ -246,7 +272,6 @@
 # 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
@@ -267,6 +292,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -307,11 +333,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 CONFIG_VT=y
@@ -350,14 +371,32 @@
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+CONFIG_INDYDOG=y
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+CONFIG_INDYDOG=y
 # 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
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -372,6 +411,13 @@
 # CONFIG_VIDEO_DEV is not set
 
 #
+# SGI Character devices
+#
+CONFIG_SGI_NEWPORT_CONSOLE=y
+CONFIG_FONT_8x16=y
+CONFIG_DUMMY_CONSOLE=y
+
+#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -385,7 +431,6 @@
 # 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_JBD_DEBUG is not set
@@ -398,11 +443,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_FREEVXFS_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
@@ -443,6 +489,8 @@
 # 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
@@ -468,14 +516,13 @@
 #
 # Console drivers
 #
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
 
 #
 # Frame-buffer support
 #
 # CONFIG_FB is not set
-CONFIG_SGI_NEWPORT_CONSOLE=y
-CONFIG_FONT_8x16=y
-CONFIG_KCORE_ELF=y
 
 #
 # Sound
@@ -496,98 +543,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
@@ -602,7 +560,6 @@
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
-# CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/defconfig-ip27 linux/arch/mips64/defconfig-ip27
--- linux.orig/arch/mips64/defconfig-ip27	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/defconfig-ip27	2002-07-20 01:08:36.000000000 +0000
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
 
 #
 # Code maturity level options
@@ -8,8 +10,15 @@
 # CONFIG_EXPERIMENTAL is not set
 
 #
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
 # Machine selection
 #
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
@@ -19,19 +28,16 @@
 # CONFIG_REPLICATE_KTEXT is not set
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_SMP=y
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1250 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
-CONFIG_COHERENT_IO=y
 CONFIG_MAPPED_PCI_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 CONFIG_L1_CACHE_SHIFT=7
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 
 #
 # CPU selection
@@ -42,6 +48,9 @@
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 CONFIG_CPU_R10000=y
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 
 #
 # General setup
@@ -50,23 +59,24 @@
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_NET=y
 CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-CONFIG_PCI_NAMES=y
-
-#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -77,6 +87,12 @@
 # CONFIG_PARPORT 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
@@ -84,7 +100,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -99,6 +117,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
 
 #
@@ -106,8 +125,6 @@
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK=y
-CONFIG_RTNETLINK=y
 CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -124,12 +141,18 @@
 # CONFIG_IP_MROUTE is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
 #  
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 
@@ -139,6 +162,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -204,8 +232,8 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 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
@@ -223,6 +251,16 @@
 # CONFIG_SCSI_U14_34F is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -245,7 +283,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -266,6 +303,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_PLIP is not set
 # CONFIG_PPP is not set
@@ -303,11 +341,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -347,7 +380,6 @@
 # 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
@@ -380,7 +412,6 @@
 # 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_JBD_DEBUG is not set
@@ -393,11 +424,12 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS 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_FREEVXFS_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
@@ -439,6 +471,8 @@
 # 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
@@ -460,7 +494,6 @@
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
-CONFIG_KCORE_ELF=y
 
 #
 # Sound
@@ -473,98 +506,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI 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_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# 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
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PLUSB 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
-
-#
-# 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_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_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_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
+# Bluetooth support
 #
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Input core support
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/defconfig-ip32 linux/arch/mips64/defconfig-ip32
--- linux.orig/arch/mips64/defconfig-ip32	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/defconfig-ip32	2002-07-20 01:08:40.000000000 +0000
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
 
 #
 # Code maturity level options
@@ -8,23 +10,29 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
 # Machine selection
 #
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 CONFIG_SGI_IP32=y
+# CONFIG_SIBYTE_SB1250 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
 CONFIG_ARC32=y
 CONFIG_PC_KEYB=y
 CONFIG_PCI=y
+# CONFIG_MAPPED_PCI_IO is not set
+CONFIG_NONCOHERENT_IO=y
 CONFIG_ARC_MEMORY=y
 CONFIG_L1_CACHE_SHIFT=5
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 
 #
 # CPU selection
@@ -35,32 +43,35 @@
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
-# CONFIG_MIPS_FPU_EMULATOR is not set
+CONFIG_ARC_CONSOLE=y
 CONFIG_NET=y
 CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_SYSCTL=y
-# CONFIG_PROM_CONSOLE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 CONFIG_BINFMT_MISC=y
 
 #
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-CONFIG_PCI_NAMES=y
-
-#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -71,6 +82,12 @@
 # CONFIG_PARPORT 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
@@ -78,7 +95,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -93,6 +112,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
 
 #
@@ -100,7 +120,7 @@
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -113,17 +133,24 @@
 # CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -141,10 +168,16 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
@@ -187,10 +220,13 @@
 # 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=y
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE 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
@@ -209,6 +245,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
@@ -249,60 +286,41 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+CONFIG_SGI_O2MACE_ETH=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
 # 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=y
-# CONFIG_PCNET32 is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-CONFIG_TULIP=y
-# CONFIG_DE4X5 is not set
-# CONFIG_DGRS is not set
-# CONFIG_DM9102 is not set
-CONFIG_EEPRO100=y
-# CONFIG_EEPRO100_PM is not set
-# CONFIG_LNE390 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_NE3210 is not set
-# CONFIG_ES3210 is not set
-# CONFIG_8139TOO is not set
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_LAN_SAA9730 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_TIGON3 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
 
@@ -340,11 +358,6 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -368,11 +381,16 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -383,7 +401,6 @@
 # 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
@@ -410,22 +427,28 @@
 # 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=y
-# CONFIG_RAMFS 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
@@ -441,7 +464,6 @@
 # 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
@@ -451,6 +473,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=y
@@ -469,6 +492,8 @@
 # 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
@@ -480,12 +505,12 @@
 # CONFIG_ATARI_PARTITION is not set
 # CONFIG_MAC_PARTITION is not set
 # CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
-CONFIG_KCORE_ELF=y
 
 #
 # Sound
@@ -498,9 +523,18 @@
 # CONFIG_USB is not set
 
 #
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
 
 #
 # Kernel hacking
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/defconfig-malta linux/arch/mips64/defconfig-malta
--- linux.orig/arch/mips64/defconfig-malta	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/defconfig-malta	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,522 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_ATLAS is not set
+CONFIG_MIPS_MALTA=y
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1250 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BOOT_ELF32=y
+CONFIG_I8259=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PCI=y
+CONFIG_SWAP_IO_SPACE=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R4300 is not set
+CONFIG_CPU_R4X00=y
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+# 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM 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 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 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=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP 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
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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 testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA 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=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_CPQFCTS 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_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
+# 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI 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
+
+#
+# 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=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_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_TIGON3 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 is not set
+# CONFIG_NVRAM is not set
+CONFIG_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=y
+# 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=y
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# 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_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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/defconfig-sb1250-swarm linux/arch/mips64/defconfig-sb1250-swarm
--- linux.orig/arch/mips64/defconfig-sb1250-swarm	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/defconfig-sb1250-swarm	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,467 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_SB1250=y
+# CONFIG_PCI is not set
+# CONFIG_SIBYTE_SB1250_PROF is not set
+# CONFIG_BCM1250_TBPROF is not set
+# CONFIG_REMOTE_DEBUG is not set
+CONFIG_SIBYTE_SWARM=y
+# CONFIG_SIMULATION is not set
+# CONFIG_L3DEMO is not set
+CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS=16
+CONFIG_SMP=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BOOT_ELF32=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_CFE=y
+CONFIG_SIBYTE_SB1250=y
+CONFIG_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+CONFIG_CPU_SB1=y
+CONFIG_SB1_PASS_1_WORKAROUNDS=y
+CONFIG_SB1_CACHE_ERROR=y
+CONFIG_VTAG_ICACHE=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# 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 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=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP 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_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI 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_SB1250_MAC=y
+CONFIG_NET_SB1250_MAC=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_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_TIGON3 is not set
+# CONFIG_FDDI 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
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+# CONFIG_AU1000_UART is not set
+# CONFIG_TXX927_SERIAL is not set
+CONFIG_SIBYTE_SB1250_DUART=y
+CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE=1024
+# CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C 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 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 is not set
+# CONFIG_JFFS2_FS is not set
+# 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 is not set
+# 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=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/Makefile linux/arch/mips64/kernel/Makefile
--- linux.orig/arch/mips64/kernel/Makefile	2001-02-05 05:48:46.000000000 +0000
+++ linux/arch/mips64/kernel/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -6,26 +6,30 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.o:
-	$(CC) $(CFLAGS) $(CFLAGS_$@) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 all:	kernel.o head.o init_task.o
 
 O_TARGET := kernel.o
 
-export-objs = mips64_ksyms.o
+export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o smp.o
 
-obj-y	:= branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \
-	   r4k_genex.o r4k_switch.o r4k_tlb.o r4k_tlb_debug.o r4k_tlb_glue.o \
-	   scall_64.o semaphore.o setup.o signal.o softfp.o syscall.o \
-	   traps.o unaligned.o
+obj-y	:= branch.o entry.o irq.o proc.o process.o ptrace.o r4k_cache.o \
+	   r4k_fpu.o r4k_genex.o r4k_switch.o reset.o scall_64.o semaphore.o \
+	   setup.o signal.o syscall.o time.o traps.o unaligned.o
+
+obj-$(CONFIG_I8259)		+= i8259.o
+obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
 
 obj-$(CONFIG_MODULES)		+= mips64_ksyms.o
 obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o scall_o32.o signal32.o ioctl32.o
 obj-$(CONFIG_BINFMT_ELF32)	+= binfmt_elf32.o
 obj-$(CONFIG_SMP)		+= smp.o
 
+ifndef CONFIG_MAPPED_PCI_IO
+obj-y				+= pci-dma.o
+endif
+
 CFLAGS_r4k_genex.o := -P
-CFLAGS_r4k_tlb_glue.o := -P
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/binfmt_elf32.c linux/arch/mips64/kernel/binfmt_elf32.c
--- linux.orig/arch/mips64/kernel/binfmt_elf32.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/binfmt_elf32.c	2002-07-20 01:08:31.000000000 +0000
@@ -41,7 +41,7 @@
 
 struct timeval32
 {
-	unsigned int tv_sec, tv_usec;
+	int tv_sec, tv_usec;
 };
 
 #define elf_prstatus elf_prstatus32
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/branch.c linux/arch/mips64/kernel/branch.c
--- linux.orig/arch/mips64/kernel/branch.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips64/kernel/branch.c	2002-07-20 01:08:31.000000000 +0000
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <asm/branch.h>
+#include <asm/cpu.h>
 #include <asm/inst.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
@@ -163,7 +164,10 @@
 	 * And now the FPA/cp1 branch instructions.
 	 */
 	case cop1_op:
-		asm ("cfc1\t%0,$31":"=r" (fcr31));
+		if (!(mips_cpu.options & MIPS_CPU_FPU))
+			fcr31 = current->thread.fpu.soft.sr;
+		else
+			asm("cfc1\t%0,$31":"=r" (fcr31));
 		bit = (insn.i_format.rt >> 2);
 		bit += (bit != 0);
 		bit += 23;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/entry.S linux/arch/mips64/kernel/entry.S
--- linux.orig/arch/mips64/kernel/entry.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/entry.S	2002-07-20 01:08:26.000000000 +0000
@@ -9,8 +9,6 @@
  * Copyright (C) 1999, 2000 Silicon Graphics
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
-#include <linux/config.h>
-
 #include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
@@ -37,7 +35,7 @@
 
 EXPORT(ret_from_irq)
 EXPORT(ret_from_exception)
-		lw	t0, PT_STATUS(sp)	# returning to kernel mode?
+		ld	t0, PT_STATUS(sp)	# returning to kernel mode?
 		andi	t0, t0, KU_USER
 		bnez	t0, ret_from_sys_call
 		j	restore_all
@@ -81,9 +79,10 @@
 		 * Someone tried to fool us by sending an interrupt but we
 		 * couldn't find a cause for it.
 		 */
-		lui     t1,%hi(spurious_count)
-		lw      t0,%lo(spurious_count)(t1)
-		addiu   t0,1
-		sw      t0,%lo(spurious_count)(t1)
+		lui     t1, %hi(irq_err_count)
+1:		ll      t0, %lo(irq_err_count)(t1)
+		addiu   t0, 1
+		sc      t0, %lo(irq_err_count)(t1)
+		beqz	t0, 1b
 		j	ret_from_irq
 		END(spurious_interrupt)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/head.S linux/arch/mips64/kernel/head.S
--- linux.orig/arch/mips64/kernel/head.S	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips64/kernel/head.S	2002-07-20 01:08:31.000000000 +0000
@@ -10,7 +10,6 @@
  * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#define __ASSEMBLY__
 #include <linux/config.h>
 #include <linux/init.h>
 #include <asm/asm.h>
@@ -35,13 +34,13 @@
 
 #ifdef CONFIG_SGI_IP27
 	/*
-	 * outputs the local nasid into t1.
+	 * outputs the local nasid into res.  IP27 stuff.
 	 */
-	.macro GET_NASID_ASM
-	dli	t1, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
-	ld	t1, (t1)
-	and	t1, NSRI_NODEID_MASK
-	dsrl	t1, NSRI_NODEID_SHFT
+	.macro GET_NASID_ASM res
+	dli	\res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
+	ld	\res, (\res)
+	and	\res, NSRI_NODEID_MASK
+	dsrl	\res, NSRI_NODEID_SHFT
 	.endm
 #endif /* CONFIG_SGI_IP27 */
 
@@ -97,7 +96,7 @@
 	xori	sp, 0xf
 
 #ifdef CONFIG_SGI_IP27
-	GET_NASID_ASM
+	GET_NASID_ASM	t1
 	move	t2, t1				# text and data are here
 	MAPPED_KERNEL_SETUP_TLB
 #endif /* IP27 */
@@ -106,39 +105,25 @@
 
 	CLI					# disable interrupts
 
-	mfc0	t0, CP0_STATUS
-	/*
-	 * On IP27, I am seeing the TS bit set when the
-	 * kernel is loaded. Maybe because the kernel is
-	 * in ckseg0 and not xkphys? Clear it anyway ...
-	 */
-	li	t1, ~(ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3)
-	and	t0, t1
-	or	t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR) # Bogosity: cu0 indicates kernel
-	mtc0	t0, CP0_STATUS			   # thread in copy_thread.
-
 	la	$28, init_task_union		# init current pointer
-	daddiu	t0, $28, KERNEL_STACK_SIZE-32
-	sd	t0, kernelsp
-	dsubu	sp, t0, 4*SZREG			# init stack pointer
-	move	t0, $28
-#ifdef CONFIG_SMP
-	mtc0	t0, CP0_WATCHLO
-	dsrl32	t0, t0, 0
-	mtc0	t0, CP0_WATCHHI
-#endif
-	/* Note that all firmware passed argument registers still
-	   have their values.  */
-	jal	prom_init			# initialize firmware
+	daddiu	sp, $28, KERNEL_STACK_SIZE-32
+	set_saved_sp	sp, t0
 
-	jal	start_kernel
-1:	b	1b				# just in case ...
+	dsubu	sp, 4*SZREG			# init stack pointer
+
+	j	init_arch
 	END(kernel_entry)
 
+#ifdef CONFIG_SMP
+/*
+ * SMP slave cpus entry point.  Board specific code for bootstrap calls this
+ * function after setting up the stack and gp registers. 
+ */
+NESTED(smp_bootstrap, 16, sp)
 #ifdef CONFIG_SGI_IP27
-NESTED(bootstrap, 16, sp)
-	GET_NASID_ASM
-	li	t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + KLDIR_OFF_POINTER + K0BASE
+	GET_NASID_ASM	t1
+	li	t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
+		    KLDIR_OFF_POINTER + K0BASE
 	dsll	t1, NASID_SHFT
 	or	t0, t0, t1
 	ld	t0, 0(t0)			# t0 points to kern_vars struct
@@ -146,19 +131,29 @@
 	lh	t2, KV_RW_NASID_OFFSET(t0)
 	MAPPED_KERNEL_SETUP_TLB
 	ARC64_TWIDDLE_PC
-	CLI
-	mfc0	t0, CP0_STATUS
-	li	t1, ~(ST0_CU1|ST0_CU2|ST0_CU3)
-	and	t0, t1
-	or	t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR) # Bogosity: cu0 indicates kernel
-	mtc0	t0, CP0_STATUS			   # thread in copy_thread.
-	jal	cboot
-	END(bootstrap)
 #endif /* CONFIG_SGI_IP27 */
 
+	CLI
+
+	/*
+	 * For the moment set ST0_KU so the CPU will not spit fire when
+	 * executing 64-bit instructions.  The full initialization of the
+	 * CPU's status register is done later in per_cpu_trap_init().
+	 */
+        mfc0	t0, CP0_STATUS
+        or	t0, ST0_KX
+	mtc0	t0, CP0_STATUS
+
+	set_saved_sp	sp, t0
+
+	jal	start_secondary			# XXX: IP27: cboot
+
+	END(smp_bootstrap)
+#endif /* CONFIG_SMP */
+
 	__FINIT
 
-	.comm	kernelsp, 8, 8			# current stackpointer
+	declare_saved_sp
 
 #undef PAGE_SIZE
 #define PAGE_SIZE	0x1000
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/i8259.c linux/arch/mips64/kernel/i8259.c
--- linux.orig/arch/mips64/kernel/i8259.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/kernel/i8259.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,307 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+
+void enable_8259A_irq(unsigned int irq);
+void disable_8259A_irq(unsigned int irq);
+
+/*
+ * This is the 'legacy' 8259A Programmable Interrupt Controller,
+ * present in the majority of PC/AT boxes.
+ * plus some generic x86 specific things if generic specifics makes
+ * any sense at all.
+ * this file should become arch/i386/kernel/irq.c when the old irq.c
+ * moves to arch independent land
+ */
+
+static spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+
+static void end_8259A_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_8259A_irq(irq);
+}
+
+#define shutdown_8259A_irq	disable_8259A_irq
+
+void mask_and_ack_8259A(unsigned int);
+
+static unsigned int startup_8259A_irq(unsigned int irq)
+{ 
+	enable_8259A_irq(irq);
+
+	return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type i8259A_irq_type = {
+	"XT-PIC",
+	startup_8259A_irq,
+	shutdown_8259A_irq,
+	enable_8259A_irq,
+	disable_8259A_irq,
+	mask_and_ack_8259A,
+	end_8259A_irq,
+	NULL
+};
+
+/*
+ * 8259A PIC functions to handle ISA devices:
+ */
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static unsigned int cached_irq_mask = 0xffff;
+
+#define cached_21	(cached_irq_mask)
+#define cached_A1	(cached_irq_mask >> 8)
+
+void disable_8259A_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+	cached_irq_mask |= mask;
+	if (irq & 8)
+		outb(cached_A1,0xA1);
+	else
+		outb(cached_21,0x21);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+void enable_8259A_irq(unsigned int irq)
+{
+	unsigned int mask = ~(1 << irq);
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+	cached_irq_mask &= mask;
+	if (irq & 8)
+		outb(cached_A1,0xA1);
+	else
+		outb(cached_21,0x21);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+int i8259A_irq_pending(unsigned int irq)
+{
+	unsigned int mask = 1 << irq;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+	if (irq < 8)
+		ret = inb(0x20) & mask;
+	else
+		ret = inb(0xA0) & (mask >> 8);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+
+	return ret;
+}
+
+void make_8259A_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &i8259A_irq_type;
+	enable_irq(irq);
+}
+
+/*
+ * This function assumes to be called rarely. Switching between
+ * 8259A registers is slow.
+ * This has to be protected by the irq controller spinlock
+ * before being called.
+ */
+static inline int i8259A_irq_real(unsigned int irq)
+{
+	int value;
+	int irqmask = 1 << irq;
+
+	if (irq < 8) {
+		outb(0x0B,0x20);		/* ISR register */
+		value = inb(0x20) & irqmask;
+		outb(0x0A,0x20);		/* back to the IRR register */
+		return value;
+	}
+	outb(0x0B,0xA0);		/* ISR register */
+	value = inb(0xA0) & (irqmask >> 8);
+	outb(0x0A,0xA0);		/* back to the IRR register */
+	return value;
+}
+
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+void mask_and_ack_8259A(unsigned int irq)
+{
+	unsigned int irqmask = 1 << irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+	/*
+	 * Lightweight spurious IRQ detection. We do not want to overdo
+	 * spurious IRQ handling - it's usually a sign of hardware problems, so
+	 * we only do the checks we can do without slowing down good hardware
+	 * nnecesserily.
+	 *
+	 * Note that IRQ7 and IRQ15 (the two spurious IRQs usually resulting
+	 * rom the 8259A-1|2 PICs) occur even if the IRQ is masked in the 8259A.
+	 * Thus we can check spurious 8259A IRQs without doing the quite slow
+	 * i8259A_irq_real() call for every IRQ.  This does not cover 100% of
+	 * spurious interrupts, but should be enough to warn the user that
+	 * there is something bad going on ...
+	 */
+	if (cached_irq_mask & irqmask)
+		goto spurious_8259A_irq;
+	cached_irq_mask |= irqmask;
+
+handle_real_irq:
+	if (irq & 8) {
+		inb(0xA1);		/* DUMMY - (do we need this?) */
+		outb(cached_A1,0xA1);
+		outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */
+		outb(0x62,0x20);	/* 'Specific EOI' to master-IRQ2 */
+	} else {
+		inb(0x21);		/* DUMMY - (do we need this?) */
+		outb(cached_21,0x21);
+		outb(0x60+irq,0x20);	/* 'Specific EOI' to master */
+	}
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+	return;
+
+spurious_8259A_irq:
+	/*
+	 * this is the slow path - should happen rarely.
+	 */
+	if (i8259A_irq_real(irq))
+		/*
+		 * oops, the IRQ _is_ in service according to the
+		 * 8259A - not spurious, go handle it.
+		 */
+		goto handle_real_irq;
+
+	{
+		static int spurious_irq_mask = 0;
+		/*
+		 * At this point we can be sure the IRQ is spurious,
+		 * lets ACK and report it. [once per IRQ]
+		 */
+		if (!(spurious_irq_mask & irqmask)) {
+			printk("spurious 8259A interrupt: IRQ%d.\n", irq);
+			spurious_irq_mask |= irqmask;
+		}
+		atomic_inc(&irq_err_count);
+		/*
+		 * Theoretically we do not have to handle this IRQ,
+		 * but in Linux this does not cause problems and is
+		 * simpler for us.
+		 */
+		goto handle_real_irq;
+	}
+}
+
+void __init init_8259A(int auto_eoi)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+
+	outb(0xff, 0x21);	/* mask all of 8259A-1 */
+	outb(0xff, 0xA1);	/* mask all of 8259A-2 */
+
+	/*
+	 * outb_p - this has to work on a wide range of PC hardware.
+	 */
+	outb_p(0x11, 0x20);	/* ICW1: select 8259A-1 init */
+	outb_p(0x00, 0x21);	/* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */
+	outb_p(0x04, 0x21);	/* 8259A-1 (the master) has a slave on IR2 */
+	if (auto_eoi)
+		outb_p(0x03, 0x21);	/* master does Auto EOI */
+	else
+		outb_p(0x01, 0x21);	/* master expects normal EOI */
+
+	outb_p(0x11, 0xA0);	/* ICW1: select 8259A-2 init */
+	outb_p(0x08, 0xA1);	/* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */
+	outb_p(0x02, 0xA1);	/* 8259A-2 is a slave on master's IR2 */
+	outb_p(0x01, 0xA1);	/* (slave's support for AEOI in flat mode
+				    is to be investigated) */
+
+	if (auto_eoi)
+		/*
+		 * in AEOI mode we just have to mask the interrupt
+		 * when acking.
+		 */
+		i8259A_irq_type.ack = disable_8259A_irq;
+	else
+		i8259A_irq_type.ack = mask_and_ack_8259A;
+
+	udelay(100);		/* wait for 8259A to initialize */
+
+	outb(cached_21, 0x21);	/* restore master IRQ mask */
+	outb(cached_A1, 0xA1);	/* restore slave IRQ mask */
+
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+asmlinkage void i8259_do_irq(int irq, struct pt_regs regs)
+{
+	panic("i8259_do_irq: I want to be implemented");
+}
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = {
+	no_action, 0, 0, "cascade", NULL, NULL
+};
+
+static struct resource pic1_io_resource = {
+	"pic1", 0x20, 0x3f, IORESOURCE_BUSY
+};
+
+static struct resource pic2_io_resource = {
+	"pic2", 0xa0, 0xbf, IORESOURCE_BUSY
+};
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8295
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init init_i8259_irqs (void)
+{
+	int i;
+
+	request_resource(&ioport_resource, &pic1_io_resource);
+	request_resource(&ioport_resource, &pic2_io_resource);
+
+	init_8259A(0);
+
+	for (i = 0; i < 16; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &i8259A_irq_type;
+	}
+
+	setup_irq(2, &irq2);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/ioctl32.c linux/arch/mips64/kernel/ioctl32.c
--- linux.orig/arch/mips64/kernel/ioctl32.c	2001-09-01 18:01:28.000000000 +0000
+++ linux/arch/mips64/kernel/ioctl32.c	2002-07-20 01:08:37.000000000 +0000
@@ -27,6 +27,10 @@
 #include <linux/auto_fs.h>
 #include <linux/ext2_fs.h>
 #include <linux/raid/md_u.h>
+#include <scsi/scsi.h>
+#undef __KERNEL__		/* This file was born to be ugly ...  */
+#include <scsi/scsi_ioctl.h>
+#define __KERNEL__
 #include <asm/types.h>
 #include <asm/uaccess.h>
 
@@ -619,6 +623,7 @@
 	IOCTL32_DEFAULT(FIONBIO),
 	IOCTL32_DEFAULT(FIONREAD),
 
+	/* Big K */
 	IOCTL32_DEFAULT(PIO_FONT),
 	IOCTL32_DEFAULT(GIO_FONT),
 	IOCTL32_DEFAULT(KDSIGACCEPT),
@@ -650,6 +655,17 @@
 	IOCTL32_DEFAULT(PIO_FONTRESET),
 	IOCTL32_DEFAULT(PIO_UNIMAPCLR),
 
+	/* Big S */
+	IOCTL32_DEFAULT(SCSI_IOCTL_GET_IDLUN),
+	IOCTL32_DEFAULT(SCSI_IOCTL_DOORLOCK),
+	IOCTL32_DEFAULT(SCSI_IOCTL_DOORUNLOCK),
+	IOCTL32_DEFAULT(SCSI_IOCTL_TEST_UNIT_READY),
+	IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_ENABLE),
+	IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_DISABLE),
+	IOCTL32_DEFAULT(SCSI_IOCTL_GET_BUS_NUMBER),
+	IOCTL32_DEFAULT(SCSI_IOCTL_SEND_COMMAND),
+
+	/* Big V */
 	IOCTL32_DEFAULT(VT_SETMODE),
 	IOCTL32_DEFAULT(VT_GETMODE),
 	IOCTL32_DEFAULT(VT_GETSTATE),
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/irq.c linux/arch/mips64/kernel/irq.c
--- linux.orig/arch/mips64/kernel/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/kernel/irq.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,1063 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
+
+/*
+ * Special irq handlers.
+ */
+
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * Generic no controller code
+ */
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq)
+{
+	/*
+	 * 'what should we do if we get a hw irq event on an illegal vector'.
+	 * each architecture has to answer this themselves, it doesnt deserve
+	 * a generic callback i think.
+	 */
+	printk("unexpected interrupt %d\n", irq);
+}
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+struct hw_interrupt_type no_irq_type = {
+	"none",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
+
+atomic_t irq_err_count;
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int get_irq_list(char *buf)
+{
+	int i, j;
+	struct irqaction * action;
+	char *p = buf;
+
+	p += sprintf(p, "           ");
+	for (j=0; j<smp_num_cpus; j++)
+		p += sprintf(p, "CPU%d       ",j);
+	*p++ = '\n';
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+		action = irq_desc[i].action;
+		if (!action) 
+			continue;
+		p += sprintf(p, "%3d: ",i);
+#ifndef CONFIG_SMP
+		p += sprintf(p, "%10u ", kstat_irqs(i));
+#else
+		for (j = 0; j < smp_num_cpus; j++)
+			p += sprintf(p, "%10u ",
+				kstat.irqs[cpu_logical_map(j)][i]);
+#endif
+		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
+		p += sprintf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			p += sprintf(p, ", %s", action->name);
+		*p++ = '\n';
+	}
+	p += sprintf(p, "\n");
+	p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+	return p - buf;
+}
+
+#ifdef CONFIG_SMP
+int global_irq_holder = NO_PROC_ID;
+spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Most of this code is take from the mips64 tree (ip27-irq.c).  It's virtually
+ * identical to the i386 implentation in arh/i386/irq.c, with translations for
+ * the interrupt enable bit
+ */
+
+#define MAXCOUNT 		100000000
+#define SYNC_OTHER_CORES(x)	udelay(x+1)
+
+static inline void wait_on_irq(int cpu)
+{
+	int count = MAXCOUNT;
+
+	for (;;) {
+
+		/*
+		 * Wait until all interrupts are gone. Wait
+		 * for bottom half handlers unless we're
+		 * already executing in one..
+		 */
+		if (!irqs_running())
+			if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
+				break;
+
+		/* Duh, we have to loop. Release the lock to avoid deadlocks */
+		spin_unlock(&global_irq_lock);
+
+		for (;;) {
+			if (!--count) {
+				printk("Count spun out.  Huh?\n");
+				count = ~0;
+			}
+			__sti();
+			SYNC_OTHER_CORES(cpu);
+			__cli();
+			if (irqs_running())
+				continue;
+			if (spin_is_locked(&global_irq_lock))
+				continue;
+			if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
+				continue;
+			if (spin_trylock(&global_irq_lock))
+				break;
+		}
+	}
+}
+
+/*
+ * This is called when we want to synchronize with
+ * interrupts. We may for example tell a device to
+ * stop sending interrupts: but to make sure there
+ * are no interrupts that are executing on another
+ * CPU we need to call this function.
+ */
+void synchronize_irq(void)
+{
+	if (irqs_running()) {
+		/* Stupid approach */
+		cli();
+		sti();
+	}
+}
+
+static inline void get_irqlock(int cpu)
+{
+	if (!spin_trylock(&global_irq_lock)) {
+		/* do we already hold the lock? */
+		if ((unsigned char) cpu == global_irq_holder)
+			return;
+		/* Uhhuh.. Somebody else got it. Wait.. */
+		spin_lock(&global_irq_lock);
+	}
+	/*
+	 * We also to make sure that nobody else is running
+	 * in an interrupt context.
+	 */
+	wait_on_irq(cpu);
+
+	/*
+	 * Ok, finally..
+	 */
+	global_irq_holder = cpu;
+}
+
+/*
+ * A global "cli()" while in an interrupt context turns into just a local 
+ * cli(). Interrupts should use spinlocks for the (very unlikely) case that 
+ * they ever want to protect against each other.
+ * 
+ * If we already have local interrupts disabled, this will not turn a local 
+ * disable into a global one (problems with spinlocks: this makes 
+ * save_flags+cli+sti usable inside a spinlock).
+ */
+
+void __global_cli(void)
+{
+	unsigned int flags;
+
+	__save_flags(flags);
+	if (flags & ST0_IE) {
+		int cpu = smp_processor_id();
+		__cli();
+		if (!local_irq_count(cpu))
+			get_irqlock(cpu);
+	}
+}
+
+void __global_sti(void)
+{
+	int cpu = smp_processor_id();
+
+	if (!local_irq_count(cpu))
+		release_irqlock(cpu);
+	__sti();
+}
+
+/*
+ * SMP flags value to restore to:
+ * 0 - global cli
+ * 1 - global sti
+ * 2 - local cli
+ * 3 - local sti
+ */
+unsigned long __global_save_flags(void)
+{
+	int retval;
+	int local_enabled;
+	unsigned long flags;
+	int cpu = smp_processor_id();
+
+	__save_flags(flags);
+	local_enabled = (flags & ST0_IE);
+	/* default to local */
+	retval = 2 + local_enabled;
+
+	/* check for global flags if we're not in an interrupt */
+	if (!local_irq_count(cpu)) {
+		if (local_enabled)
+			retval = 1;
+		if (global_irq_holder == cpu)
+			retval = 0;
+	}
+
+	return retval;
+}
+
+void __global_restore_flags(unsigned long flags)
+{
+	switch (flags) {
+		case 0:
+			__global_cli();
+			break;
+		case 1:
+			__global_sti();
+			break;
+		case 2:
+			__cli();
+			break;
+		case 3:
+			__sti();
+			break;
+		default:
+			printk("global_restore_flags: %08lx\n", flags);
+	}
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * This should really return information about whether
+ * we should do bottom half handling etc. Right now we
+ * end up _always_ checking the bottom half, which is a
+ * waste of time and is not what some drivers would
+ * prefer.
+ */
+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
+{
+	int status;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+
+	status = 1;	/* Force the "do bottom halves" bit */
+
+	if (!(action->flags & SA_INTERRUPT))
+		__sti();
+
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+	__cli();
+
+	irq_exit(cpu, irq);
+
+	return status;
+}
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock. 
+ */
+ 
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void inline disable_irq_nosync(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. That is for two disables you need two enables. This
+ *	function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+ 
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *	providing no disable_irq calls are now in effect.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void enable_irq(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
+	case 1: {
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
+		}
+		desc->handler->enable(irq);
+		/* fall-through */
+	}
+	default:
+		desc->depth--;
+		break;
+	case 0:
+		printk("enable_irq(%u) unbalanced from %p\n", irq,
+		       __builtin_return_address(0));
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
+{
+	/* 
+	 * We ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * 0 return value means that this irq is already being
+	 * handled by some other CPU. (or is disabled)
+	 */
+	int cpu = smp_processor_id();
+	irq_desc_t *desc = irq_desc + irq;
+	struct irqaction * action;
+	unsigned int status;
+
+	kstat.irqs[cpu][irq]++;
+	spin_lock(&desc->lock);
+	desc->handler->ack(irq);
+	/*
+	   REPLAY is when Linux resends an IRQ that was dropped earlier
+	   WAITING is used by probe to mark irqs that are being tested
+	   */
+	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+	status |= IRQ_PENDING; /* we _want_ to handle it */
+
+	/*
+	 * If the IRQ is disabled for whatever reason, we cannot
+	 * use the action we have.
+	 */
+	action = NULL;
+	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		status &= ~IRQ_PENDING; /* we commit to handling */
+		status |= IRQ_INPROGRESS; /* we are handling it */
+	}
+	desc->status = status;
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	   Since we set PENDING, if another processor is handling
+	   a different instance of this same irq, the other processor
+	   will take care of it.
+	 */
+	if (!action)
+		goto out;
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events.
+	 * This applies to any hw interrupts that allow a second
+	 * instance of the same irq to arrive while we are in do_IRQ
+	 * or in the handler. But the code here only handles the _second_
+	 * instance of the irq, not the third or fourth. So it is mostly
+	 * useful for irq hardware that does not mask cleanly in an
+	 * SMP environment.
+	 */
+	for (;;) {
+		spin_unlock(&desc->lock);
+		handle_IRQ_event(irq, regs, action);
+		spin_lock(&desc->lock);
+		
+		if (!(desc->status & IRQ_PENDING))
+			break;
+		desc->status &= ~IRQ_PENDING;
+	}
+	desc->status &= ~IRQ_INPROGRESS;
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+	return 1;
+}
+
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board 
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+ 
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+#if 1
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+	}
+#endif
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)
+			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context. 
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+ 
+void free_irq(unsigned int irq, void *dev_id)
+{
+	irq_desc_t *desc;
+	struct irqaction **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS)
+		return;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	for (;;) {
+		struct irqaction * action = *p;
+		if (action) {
+			struct irqaction **pp = p;
+			p = &action->next;
+			if (action->dev_id != dev_id)
+				continue;
+
+			/* Found it - now remove it from the list of entries */
+			*pp = action->next;
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
+			}
+			spin_unlock_irqrestore(&desc->lock,flags);
+
+#ifdef CONFIG_SMP
+			/* Wait to make sure it's not being used on another CPU */
+			while (desc->status & IRQ_INPROGRESS)
+				barrier();
+#endif
+			kfree(action);
+			return;
+		}
+		printk("Trying to free free IRQ%d\n",irq);
+		spin_unlock_irqrestore(&desc->lock,flags);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that
+ * comes in on to an unassigned handler will get stuck
+ * with "IRQ_WAITING" cleared and the interrupt
+ * disabled.
+ */
+
+static DECLARE_MUTEX(probe_sem);
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+ 
+unsigned long probe_irq_on(void)
+{
+	unsigned int i;
+	irq_desc_t *desc;
+	unsigned long val;
+	unsigned long delay;
+
+	down(&probe_sem);
+	/* 
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious. 
+	 */
+	for (i = NR_IRQS-1; i > 0; i--)  {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!irq_desc[i].action) 
+			irq_desc[i].handler->startup(i);
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ synchronize_irq();
+
+	/*
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
+	 */
+	for (i = NR_IRQS-1; i > 0; i--) {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/*
+	 * Wait for spurious interrupts to trigger
+	 */
+	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+		/* about 100ms delay */ synchronize_irq();
+
+	/*
+	 * Now filter out any obviously spurious interrupts
+	 */
+	val = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	return val;
+}
+
+/*
+ * Return a mask of triggered interrupts (this
+ * can handle only legacy ISA interrupts).
+ */
+ 
+/**
+ *	probe_irq_mask - scan a bitmap of interrupt lines
+ *	@val:	mask of interrupts to consider
+ *
+ *	Scan the ISA bus interrupt lines and return a bitmap of
+ *	active interrupts. The interrupt probe logic state is then
+ *	returned to its previous value.
+ *
+ *	Note: we need to scan all the irq's even though we will
+ *	only return ISA irq numbers - just so that we reset them
+ *	all to a known state.
+ */
+unsigned int probe_irq_mask(unsigned long val)
+{
+	int i;
+	unsigned int mask;
+
+	mask = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (i < 16 && !(status & IRQ_WAITING))
+				mask |= 1 << i;
+
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	return mask & val;
+}
+
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off	- end an interrupt autodetect
+ *	@val: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+ 
+int probe_irq_off(unsigned long val)
+{
+	int i, irq_found, nr_irqs;
+
+	nr_irqs = 0;
+	irq_found = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	if (nr_irqs > 1)
+		irq_found = -irq_found;
+	return irq_found;
+}
+
+/* this was setup_x86_irq but it seems pretty generic */
+int setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	unsigned long flags;
+	struct irqaction *old, **p;
+	irq_desc_t *desc = irq_desc + irq;
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&desc->lock,flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->depth = 0;
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+		desc->handler->startup(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+
+	register_irq_proc(irq);
+	return 0;
+}
+
+void __init init_generic_irq(void)
+{
+	int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status  = IRQ_DISABLED;
+		irq_desc[i].action  = NULL;
+		irq_desc[i].depth   = 1;
+		irq_desc[i].handler = &no_irq_type;
+	}
+}
+
+EXPORT_SYMBOL(disable_irq_nosync);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(probe_irq_mask);
+
+static struct proc_dir_entry * root_irq_dir;
+static struct proc_dir_entry * irq_dir [NR_IRQS];
+
+#define HEX_DIGITS 8
+
+static unsigned int parse_hex_value (const char *buffer,
+		unsigned long count, unsigned long *ret)
+{
+	unsigned char hexnum [HEX_DIGITS];
+	unsigned long value;
+	int i;
+
+	if (!count)
+		return -EINVAL;
+	if (count > HEX_DIGITS)
+		count = HEX_DIGITS;
+	if (copy_from_user(hexnum, buffer, count))
+		return -EFAULT;
+
+	/*
+	 * Parse the first 8 characters as a hex string, any non-hex char
+	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+	 */
+	value = 0;
+
+	for (i = 0; i < count; i++) {
+		unsigned int c = hexnum[i];
+
+		switch (c) {
+			case '0' ... '9': c -= '0'; break;
+			case 'a' ... 'f': c -= 'a'-10; break;
+			case 'A' ... 'F': c -= 'A'-10; break;
+		default:
+			goto out;
+		}
+		value = (value << 4) | c;
+	}
+out:
+	*ret = value;
+	return 0;
+}
+
+#if CONFIG_SMP
+
+static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+
+static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
+static int irq_affinity_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
+}
+
+static int irq_affinity_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	int irq = (long) data, full_count = count, err;
+	unsigned long new_value;
+
+	if (!irq_desc[irq].handler->set_affinity)
+		return -EIO;
+
+	err = parse_hex_value(buffer, count, &new_value);
+
+	/*
+	 * Do not allow disabling IRQs completely - it's a too easy
+	 * way to make the system unusable accidentally :-) At least
+	 * one online CPU still has to be targeted.
+	 */
+	if (!(new_value & cpu_online_map))
+		return -EINVAL;
+
+	irq_affinity[irq] = new_value;
+	irq_desc[irq].handler->set_affinity(irq, new_value);
+
+	return full_count;
+}
+
+#endif
+
+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	unsigned long *mask = (unsigned long *) data;
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", *mask);
+}
+
+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	unsigned long *mask = (unsigned long *) data, full_count = count, err;
+	unsigned long new_value;
+
+	err = parse_hex_value(buffer, count, &new_value);
+	if (err)
+		return err;
+
+	*mask = new_value;
+	return full_count;
+}
+
+#define MAX_NAMELEN 10
+
+static void register_irq_proc (unsigned int irq)
+{
+	char name [MAX_NAMELEN];
+
+	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
+			irq_dir[irq])
+		return;
+
+	memset(name, 0, MAX_NAMELEN);
+	sprintf(name, "%d", irq);
+
+	/* create /proc/irq/1234 */
+	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+
+#if CONFIG_SMP
+	{
+		struct proc_dir_entry *entry;
+
+		/* create /proc/irq/1234/smp_affinity */
+		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
+
+		if (entry) {
+			entry->nlink = 1;
+			entry->data = (void *)(long)irq;
+			entry->read_proc = irq_affinity_read_proc;
+			entry->write_proc = irq_affinity_write_proc;
+		}
+
+		smp_affinity_entry[irq] = entry;
+	}
+#endif
+}
+
+unsigned long prof_cpu_mask = -1;
+
+void init_irq_proc (void)
+{
+	struct proc_dir_entry *entry;
+	int i;
+
+	/* create /proc/irq */
+	root_irq_dir = proc_mkdir("irq", 0);
+
+	/* create /proc/irq/prof_cpu_mask */
+	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
+
+	if (!entry)
+	    return;
+
+	entry->nlink = 1;
+	entry->data = (void *)&prof_cpu_mask;
+	entry->read_proc = prof_cpu_mask_read_proc;
+	entry->write_proc = prof_cpu_mask_write_proc;
+
+	/*
+	 * Create entries for all existing IRQs.
+	 */
+	for (i = 0; i < NR_IRQS; i++)
+		register_irq_proc(i);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/irq_cpu.c linux/arch/mips64/kernel/irq_cpu.c
--- linux.orig/arch/mips64/kernel/irq_cpu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/kernel/irq_cpu.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This file define the irq handler for MIPS CPU interrupts.
+ *
+ * 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.
+ */
+
+/*
+ * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
+ * level triggered (i.e., cannot be cleared from CPU; must be cleared from
+ * device).  The first two are software interrupts.  The last one is 
+ * usually cpu timer interrupt if coutner register is present.
+ *
+ * This file exports one global function:
+ *	mips_cpu_irq_init(u32 irq_base);
+ */
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <asm/mipsregs.h>
+
+static int mips_cpu_irq_base = -1;
+
+static void mips_cpu_irq_enable(unsigned int irq)
+{
+	clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8));
+	set_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+}
+
+static void mips_cpu_irq_disable(unsigned int irq)
+{
+	clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+}
+
+static unsigned int mips_cpu_irq_startup(unsigned int irq)
+{
+	mips_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
+
+static void mips_cpu_irq_ack(unsigned int irq)
+{
+	/* although we attemp to clear the IP bit in cause reigster, I think
+	 * usually it is cleared by device (irq source)
+	 */
+	clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8));
+
+	/* disable this interrupt - so that we safe proceed to the handler */
+	mips_cpu_irq_disable(irq);
+}
+
+static void mips_cpu_irq_end(unsigned int irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		mips_cpu_irq_enable(irq);
+}
+
+static hw_irq_controller mips_cpu_irq_controller = {
+	"CPU_irq",
+	mips_cpu_irq_startup,
+	mips_cpu_irq_shutdown,
+	mips_cpu_irq_enable,
+	mips_cpu_irq_disable,
+	mips_cpu_irq_ack,
+	mips_cpu_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+
+void mips_cpu_irq_init(u32 irq_base)
+{
+	u32 i;
+
+	for (i = irq_base; i < irq_base + 8; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &mips_cpu_irq_controller;
+	}
+
+	mips_cpu_irq_base = irq_base;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/linux32.c linux/arch/mips64/kernel/linux32.c
--- linux.orig/arch/mips64/kernel/linux32.c	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/mips64/kernel/linux32.c	2002-07-20 01:08:24.000000000 +0000
@@ -27,6 +27,7 @@
 #include <linux/personality.h>
 #include <linux/timex.h>
 #include <linux/dnotify.h>
+#include <linux/module.h>
 #include <net/sock.h>
 
 #include <asm/uaccess.h>
@@ -36,6 +37,13 @@
 
 #define A(__x) ((unsigned long)(__x))
 
+#ifdef __MIPSEB__
+#define merge_64(r1,r2)	((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
+#endif
+#ifdef __MIPSEL__
+#define merge_64(r1,r2)	((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
+#endif
+
 /*
  * Revalidate the inode. This is required for proper NFS attribute caching.
  */
@@ -887,9 +895,9 @@
 			          unsigned long offset_low, loff_t * result,
 			          unsigned int origin);
 
-extern asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
-			           unsigned int offset_low, loff_t * result,
-			           unsigned int origin)
+asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
+			    unsigned int offset_low, loff_t * result,
+			    unsigned int origin)
 {
 	return sys_llseek(fd, offset_high, offset_low, result, origin);
 }
@@ -1043,11 +1051,12 @@
    non-seekable files.  */
 
 asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
-			       size_t count, u32 unused, loff_t pos)
+			       size_t count, u32 unused, u64 a4, u64 a5)
 {
 	ssize_t ret;
 	struct file * file;
 	ssize_t (*read)(struct file *, char *, size_t, loff_t *);
+	loff_t pos;
 
 	ret = -EBADF;
 	file = fget(fd);
@@ -1055,6 +1064,7 @@
 		goto bad_file;
 	if (!(file->f_mode & FMODE_READ))
 		goto out;
+	pos = merge_64(a4, a5);
 	ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
 				file, pos, count);
 	if (ret)
@@ -1074,11 +1084,12 @@
 }
 
 asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
-			        size_t count, u32 unused, loff_t pos)
+			        size_t count, u32 unused, u64 a4, u64 a5)
 {
 	ssize_t ret;
 	struct file * file;
 	ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
+	loff_t pos;
 
 	ret = -EBADF;
 	file = fget(fd);
@@ -1086,6 +1097,7 @@
 		goto bad_file;
 	if (!(file->f_mode & FMODE_WRITE))
 		goto out;
+	pos = merge_64(a4, a5);
 	ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode,
 				file, pos, count);
 	if (ret)
@@ -1112,7 +1124,6 @@
 static inline int
 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
 {
-#ifdef __MIPSEB__
 	if (ufdset) {
 		unsigned long odd;
 
@@ -1139,9 +1150,6 @@
 		memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
 	}
 	return 0;
-#else
-	<<Bomb - little endian support must define this>>
-#endif
 }
 
 static inline void
@@ -1600,7 +1608,9 @@
 	if (!p)
 		return -ENOMEM;
 	err = get_user (p->mtype, &up->mtype);
-	err |= __copy_from_user (p->mtext, &up->mtext, second);
+	if (err)
+		goto out;
+	err = __copy_from_user (p->mtext, &up->mtext, second);
 	if (err)
 		goto out;
 	old_fs = get_fs ();
@@ -2329,3 +2339,55 @@
 out:
 	return err;
 }
+
+asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
+
+asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,
+                                   size_t count)
+{
+	return sys_readahead(fd, merge_64(a2, a3), count);
+}
+
+#ifdef CONFIG_MODULES
+
+/* From sparc64 */
+
+struct kernel_sym32 {
+        u32 value;
+        char name[60];
+};
+
+extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
+
+asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
+{
+        int len, i;
+        struct kernel_sym *tbl;
+        mm_segment_t old_fs;
+
+        len = sys_get_kernel_syms(NULL);
+        if (!table) return len;
+        tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
+        if (!tbl) return -ENOMEM;
+        old_fs = get_fs();
+        set_fs (KERNEL_DS);
+        sys_get_kernel_syms(tbl);
+        set_fs (old_fs);
+        for (i = 0; i < len; i++, table++) {
+                if (put_user (tbl[i].value, &table->value) ||
+                    copy_to_user (table->name, tbl[i].name, 60))
+                        break;
+        }
+        kfree (tbl);
+        return i;
+}
+
+#else
+
+asmlinkage long
+sys32_get_kernel_syms(struct kernel_sym *table)
+{
+	return -ENOSYS;
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/mips64_ksyms.c linux/arch/mips64/kernel/mips64_ksyms.c
--- linux.orig/arch/mips64/kernel/mips64_ksyms.c	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/mips64/kernel/mips64_ksyms.c	2002-07-20 01:08:33.000000000 +0000
@@ -13,9 +13,9 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <linux/in6.h>
 #include <linux/pci.h>
+#include <linux/tty.h>
 
 #include <asm/bootinfo.h>
 #include <asm/dma.h>
@@ -58,8 +58,6 @@
 EXPORT_SYMBOL_NOVERS(strpbrk);
 
 EXPORT_SYMBOL(_clear_page);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(kernel_thread);
 
 /*
@@ -83,7 +81,8 @@
  */
 EXPORT_SYMBOL(_flush_page_to_ram);
 EXPORT_SYMBOL(_flush_cache_l1);
-#ifndef CONFIG_COHERENT_IO
+
+#ifdef CONFIG_NONCOHERENT_IO
 EXPORT_SYMBOL(_dma_cache_wback_inv);
 EXPORT_SYMBOL(_dma_cache_inv);
 #endif
@@ -106,15 +105,8 @@
 int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
 int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
 
-#ifdef CONFIG_MIPS_FPE_MODULE
-EXPORT_SYMBOL(__compute_return_epc);
-EXPORT_SYMBOL(register_fpe);
-EXPORT_SYMBOL(unregister_fpe);
-#endif
-
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
 
 EXPORT_SYMBOL(get_wchan);
-EXPORT_SYMBOL(_flush_tlb_page);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/pci-dma.c linux/arch/mips64/kernel/pci-dma.c
--- linux.orig/arch/mips64/kernel/pci-dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/kernel/pci-dma.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,45 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000  Ralf Baechle <ralf@gnu.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/addrspace.h>
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t * dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+
+	if (hwdev != NULL && hwdev->dma_mask != 0xffffffff)
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+#ifdef CONFIG_NONCOHERENT_IO
+		dma_cache_wback_inv((unsigned long) ret, size);
+		ret = KSEG1ADDR(ret);
+#endif
+		*dma_handle = __pa(ret);
+		return ret;
+	}
+	return NULL;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long) KSEG0ADDR(vaddr), get_order(size));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/proc.c linux/arch/mips64/kernel/proc.c
--- linux.orig/arch/mips64/kernel/proc.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/proc.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,76 +1,146 @@
 /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
+ *  linux/arch/mips/kernel/proc.c
  *
- * Copyright (C) 1995, 1996, 1999, 2001 Ralf Baechle
- * Copyright (C) 2001 MIPS Technologies, Inc.
+ *  Copyright (C) 1995, 1996, 2001  Ralf Baechle
+ *  Copyright (C) 2001  MIPS Technologies, Inc.
  */
+#include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/smp.h>
+#include <linux/seq_file.h>
 #include <asm/bootinfo.h>
+#include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
 #include <asm/watch.h>
 
-extern unsigned long unaligned_instructions;
 unsigned int vced_count, vcei_count;
 
-/*
- * BUFFER is PAGE_SIZE bytes long.
- *
- * Currently /proc/cpuinfo is being abused to print data about the
- * number of date/instruction cacheflushes.
- */
-int get_cpuinfo(char *buffer)
+#ifndef CONFIG_CPU_HAS_LLSC
+unsigned long ll_ops, sc_ops;
+#endif
+
+static const char *cpu_name[] = {
+	[CPU_UNKNOWN]	"unknown",
+	[CPU_R2000]	"R2000",
+	[CPU_R3000]	"R3000",
+	[CPU_R3000A]	"R3000A",
+	[CPU_R3041]	"R3041",
+	[CPU_R3051]	"R3051",
+	[CPU_R3052]	"R3052",
+	[CPU_R3081]	"R3081",
+	[CPU_R3081E]	"R3081E",
+	[CPU_R4000PC]	"R4000PC",
+	[CPU_R4000SC]	"R4000SC",
+	[CPU_R4000MC]	"R4000MC",
+        [CPU_R4200]	"R4200",
+	[CPU_R4400PC]	"R4400PC",
+	[CPU_R4400SC]	"R4400SC",
+	[CPU_R4400MC]	"R4400MC",
+	[CPU_R4600]	"R4600",
+	[CPU_R6000]	"R6000",
+        [CPU_R6000A]	"R6000A",
+	[CPU_R8000]	"R8000",
+	[CPU_R10000]	"R10000",
+	[CPU_R4300]	"R4300",
+	[CPU_R4650]	"R4650",
+	[CPU_R4700]	"R4700",
+	[CPU_R5000]	"R5000",
+        [CPU_R5000A]	"R5000A",
+	[CPU_R4640]	"R4640",
+	[CPU_NEVADA]	"Nevada",
+	[CPU_RM7000]	"RM7000",
+	[CPU_R5432]	"R5432",
+	[CPU_4KC]	"MIPS 4Kc",
+        [CPU_5KC]	"MIPS 5Kc",
+	[CPU_R4310]	"R4310",
+	[CPU_SB1]	"SiByte SB1",
+	[CPU_TX3912]	"TX3912",
+	[CPU_TX3922]	"TX3922",
+	[CPU_TX3927]	"TX3927",
+	[CPU_AU1000]	"Au1000",
+	[CPU_AU1500]	"Au1500",
+	[CPU_4KEC]	"MIPS 4KEc",
+	[CPU_4KSC]	"MIPS 4KSc",
+	[CPU_VR41XX]	"NEC Vr41xx",
+	[CPU_R5500]	"R5500",
+	[CPU_TX49XX]	"TX49xx",
+	[CPU_TX39XX]	"TX39xx",
+	[CPU_20KC]	"MIPS 20Kc"
+};
+
+
+static int show_cpuinfo(struct seq_file *m, void *v)
 {
+	unsigned int version = mips_cpu.processor_id;
+	unsigned int fp_vers = mips_cpu.fpu_id;
+	unsigned long n = (unsigned long) v - 1;
 	char fmt [64];
-	size_t len;
 
-	len = sprintf(buffer, "cpu\t\t\t: MIPS\n");
-#if 0
-	len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n",
-	               cpu_name[mips_cputype <= CPU_LAST ?
-	                        mips_cputype :
-	                        CPU_UNKNOWN],
-	               (version >> 4) & 0x0f,
-	               version & 0x0f);
-	len += sprintf(buffer + len, "system type\t\t: %s %s\n",
-		       mach_group_names[mips_machgroup],
-		       mach_group_to_name[mips_machgroup][mips_machtype]);
-#endif
-	len += sprintf(buffer + len, "BogoMIPS\t\t: %lu.%02lu\n",
-		       (loops_per_jiffy + 2500) / (500000/HZ),
-	               ((loops_per_jiffy + 2500) / (5000/HZ)) % 100);
-	len += sprintf(buffer + len, "Number of cpus\t\t: %d\n", smp_num_cpus);
-#if defined (__MIPSEB__)
-	len += sprintf(buffer + len, "byteorder\t\t: big endian\n");
+#ifdef CONFIG_SMP
+	if (!CPUMASK_TSTB(cpu_online_map, n))
+		return 0;
 #endif
-#if defined (__MIPSEL__)
-	len += sprintf(buffer + len, "byteorder\t\t: little endian\n");
-#endif
-	len += sprintf(buffer + len, "unaligned accesses\t: %lu\n",
-		       unaligned_instructions);
-	len += sprintf(buffer + len, "wait instruction\t: %s\n",
-	               wait_available ? "yes" : "no");
-	len += sprintf(buffer + len, "microsecond timers\t: %s\n",
-	               cyclecounter_available ? "yes" : "no");
-	len += sprintf(buffer + len, "extra interrupt vector\t: %s\n",
-	               dedicated_iv_available ? "yes" : "no");
-	len += sprintf(buffer + len, "hardware watchpoint\t: %s\n",
-	               watch_available ? "yes" : "no");
+
+	/*
+	 * For the first processor also print the system type
+	 */
+	if (n == 0)
+		seq_printf(m, "system type\t\t: %s\n", get_system_type());
+
+	seq_printf(m, "processor\t\t: %ld\n", n);
+	sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
+	        (mips_cpu.options & MIPS_CPU_FPU) ? "  FPU V%d.%d" : "");
+	seq_printf(m, fmt, cpu_name[mips_cpu.cputype <= CPU_LAST ?
+	                            mips_cpu.cputype : CPU_UNKNOWN],
+	                           (version >> 4) & 0x0f, version & 0x0f,
+	                           (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
+	seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
+	              loops_per_jiffy / (500000/HZ),
+	              (loops_per_jiffy / (5000/HZ)) % 100);
+	seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
+	seq_printf(m, "microsecond timers\t: %s\n",
+	              (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no");
+	seq_printf(m, "tlb_entries\t\t: %d\n", mips_cpu.tlbsize);
+	seq_printf(m, "extra interrupt vector\t: %s\n",
+	              (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no");
+	seq_printf(m, "hardware watchpoint\t: %s\n",
+	              watch_available ? "yes" : "no");
 
 	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
-	        vce_available ? "%d" : "not available");
-	len += sprintf(buffer + len, fmt, 'D', vced_count);
-	len += sprintf(buffer + len, fmt, 'I', vcei_count);
+	        (mips_cpu.options & MIPS_CPU_VCE) ? "%d" : "not available");
+	seq_printf(m, fmt, 'D', vced_count);
+	seq_printf(m, fmt, 'I', vcei_count);
+
+#ifndef CONFIG_CPU_HAS_LLSC
+	seq_printf(m, "ll emulations\t\t: %lu\n", ll_ops);
+	seq_printf(m, "sc emulations\t\t: %lu\n", sc_ops);
+#endif
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	unsigned long i = *pos;
 
-	return len;
+	return i < NR_CPUS ? (void *) (i + 1) : NULL;
 }
 
-void init_irq_proc(void)
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	/* Nothing, for now.  */
+	++*pos;
+	return c_start(m, pos);
 }
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/process.c linux/arch/mips64/kernel/process.c
--- linux.orig/arch/mips64/kernel/process.c	2001-02-09 19:29:44.000000000 +0000
+++ linux/arch/mips64/kernel/process.c	2002-07-20 01:08:30.000000000 +0000
@@ -15,6 +15,7 @@
 #include <linux/ptrace.h>
 #include <linux/slab.h>
 #include <linux/mman.h>
+#include <linux/personality.h>
 #include <linux/sys.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
@@ -29,7 +30,7 @@
 #include <asm/io.h>
 #include <asm/elf.h>
 
-asmlinkage int cpu_idle(void)
+ATTRIB_NORET void cpu_idle(void)
 {
 	/* endless idle loop with no priority at all */
 	init_idle();
@@ -37,8 +38,8 @@
 	current->counter = -100;
 	while (1) {
 		while (!current->need_resched)
-			if (wait_available)
-				__asm__("wait");
+			if (cpu_wait)
+				(*cpu_wait)();
 		schedule();
 		check_pgt_cache();
 	}
@@ -52,7 +53,7 @@
 {
 	/* Forget lazy fpu state */
 	if (IS_FPU_OWNER()) {
-		set_cp0_status(ST0_CU1, ST0_CU1);
+		__enable_fpu();
 		__asm__ __volatile__("cfc1\t$0,$31");
 		CLEAR_FPU_OWNER();
 	}
@@ -62,17 +63,17 @@
 {
 	/* Forget lazy fpu state */
 	if (IS_FPU_OWNER()) {
-		set_cp0_status(ST0_CU1, ST0_CU1);
+		__enable_fpu();
 		__asm__ __volatile__("cfc1\t$0,$31");
 		CLEAR_FPU_OWNER();
 	}
 }
 
 int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
-		 unsigned long unused,
-                 struct task_struct * p, struct pt_regs * regs)
+		unsigned long unused, struct task_struct *p,
+		struct pt_regs *regs)
 {
-	struct pt_regs * childregs;
+	struct pt_regs *childregs;
 	long childksp;
 
 	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
@@ -84,16 +85,9 @@
 	childregs = (struct pt_regs *) childksp - 1;
 	*childregs = *regs;
 	childregs->regs[7] = 0;	/* Clear error flag */
-	if (current->personality == PER_LINUX) {
-		childregs->regs[2] = 0;	/* Child gets zero as return value */
-		regs->regs[2] = p->pid;
-	} else {
-		/* Under IRIX things are a little different. */
-		childregs->regs[2] = 0;
-		childregs->regs[3] = 1;
-		regs->regs[2] = p->pid;
-		regs->regs[3] = 0;
-	}
+	childregs->regs[2] = 0;	/* Child gets zero as return value */
+	regs->regs[2] = p->pid;
+
 	if (childregs->cp0_status & ST0_CU0) {
 		childregs->regs[28] = (unsigned long) p;
 		childregs->regs[29] = childksp;
@@ -122,10 +116,11 @@
 	/* We actually store the FPU info in the task->thread
 	 * area.
 	 */
-	if(regs->cp0_status & ST0_CU1) {
+	if (regs->cp0_status & ST0_CU1) {
 		memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu));
 		return 1;
 	}
+
 	return 0; /* Task didn't use the fpu at all. */
 }
 
@@ -172,8 +167,8 @@
 
 		 /* The called subroutine might have destroyed any of the
 		  * at, result, argument or temporary registers ...  */
-		:"$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8",
-		 "$9","$10","$11","$12","$13","$14","$15","$24","$25");
+		: "$2", "$3", "$4", "$5", "$6", "$7", "$8",
+		  "$9","$10","$11","$12","$13","$14","$15","$24","$25");
 
 	return retval;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/ptrace.c linux/arch/mips64/kernel/ptrace.c
--- linux.orig/arch/mips64/kernel/ptrace.c	2001-09-18 23:56:19.000000000 +0000
+++ linux/arch/mips64/kernel/ptrace.c	2002-07-20 01:08:29.000000000 +0000
@@ -22,11 +22,13 @@
 #include <linux/smp_lock.h>
 #include <linux/user.h>
 
+#include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/bootinfo.h>
 
 /*
  * Called by kernel/ptrace.c when detaching..
@@ -75,15 +77,11 @@
 		ret = ptrace_attach(child);
 		goto out_tsk;
 	}
-	ret = -ESRCH;
-	if (!(child->ptrace & PT_PTRACED))
-		goto out_tsk;
-	if (child->state != TASK_STOPPED) {
-		if (request != PTRACE_KILL)
-			goto out_tsk;
-	}
-	if (child->p_pptr != current)
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
 		goto out_tsk;
+
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -114,17 +112,23 @@
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
 			if (child->used_math) {
-				unsigned long *fregs =
-					(void *) child->thread.fpu.hard.fp_regs;
-
+				unsigned long long *fregs
+					= (unsigned long long *)
+					    &child->thread.fpu.hard.fp_regs[0];
+				if (mips_cpu.options & MIPS_CPU_FPU) {
 #ifndef CONFIG_SMP
-				if (last_task_used_math == child) {
-					set_cp0_status(ST0_CU1, ST0_CU1);
-					save_fp(child);
-					set_cp0_status(ST0_CU1, 0);
-					last_task_used_math = NULL;
-				}
+					if (last_task_used_math == child) {
+						__enable_fpu();
+						save_fp(child);
+						__disable_fpu();
+						last_task_used_math = NULL;
+					}
 #endif
+				} else {
+					fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+				}
+
 				/*
 				 * The odd registers are actually the high
 				 * order bits of the values stored in the even
@@ -154,12 +158,15 @@
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
-			tmp = child->thread.fpu.hard.control;
+			if (mips_cpu.options & MIPS_CPU_FPU)
+				tmp = child->thread.fpu.hard.control;
+			else
+				tmp = child->thread.fpu.soft.sr;
 			break;
 		case FPC_EIR: { /* implementation / version register */
 			unsigned int flags;
 			__save_flags(flags);
-			set_cp0_status(ST0_CU1, ST0_CU1);
+			__enable_fpu();
 			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
 			__restore_flags(flags);
 			break;
@@ -192,17 +199,21 @@
 			regs->regs[addr] = data;
 			break;
 		case FPR_BASE ... FPR_BASE + 31: {
-			unsigned long *fregs =
-				(void *) child->thread.fpu.hard.fp_regs;
+			unsigned long long *fregs;
+			fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0];
 			if (child->used_math) {
 #ifndef CONFIG_SMP
-				if (last_task_used_math == child) {
-					set_cp0_status(ST0_CU1, ST0_CU1);
-					save_fp(child);
-					set_cp0_status(ST0_CU1, 0);
-					last_task_used_math = NULL;
-					regs->cp0_status &= ~ST0_CU1;
-				}
+				if (last_task_used_math == child) 
+					if (mips_cpu.options & MIPS_CPU_FPU) {
+						__enable_fpu();
+						save_fp(child);
+						__disable_fpu();
+						last_task_used_math = NULL;
+						regs->cp0_status &= ~ST0_CU1;
+					} else {
+						fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+					}
 #endif
 			} else {
 				/* FP not yet used  */
@@ -234,7 +245,10 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			child->thread.fpu.hard.control = data;
+			if (mips_cpu.options & MIPS_CPU_FPU) 
+				child->thread.fpu.hard.control = data;
+			else
+				child->thread.fpu.soft.sr = data;
 			break;
 		default:
 			/* The rest are not allowed. */
@@ -334,14 +348,9 @@
 		ret = ptrace_attach(child);
 		goto out_tsk;
 	}
-	ret = -ESRCH;
-	if (!(child->ptrace & PT_PTRACED))
-		goto out_tsk;
-	if (child->state != TASK_STOPPED) {
-		if (request != PTRACE_KILL)
-			goto out_tsk;
-	}
-	if (child->p_pptr != current)
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
 		goto out_tsk;
 
 	switch (request) {
@@ -377,14 +386,20 @@
 				unsigned long long *fregs
 					= (unsigned long long *)
 					&child->thread.fpu.hard.fp_regs[0];
+				if (mips_cpu.options & MIPS_CPU_FPU) {
 #ifndef CONFIG_SMP
-				if (last_task_used_math == child) {
-					set_cp0_status(ST0_CU1, ST0_CU1);
-					save_fp(child);
-					set_cp0_status(ST0_CU1, 0);
-					last_task_used_math = NULL;
-				}
+					if (last_task_used_math == child) {
+						__enable_fpu();
+						save_fp(child);
+						__disable_fpu();
+						last_task_used_math = NULL;
+					}
 #endif
+				} else {
+					fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+				}
+
 				/*
 				 * The odd registers are actually the high
 				 * order bits of the values stored in the even
@@ -414,12 +429,15 @@
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
-			tmp = child->thread.fpu.hard.control;
+			if (mips_cpu.options & MIPS_CPU_FPU)
+				tmp = child->thread.fpu.hard.control;
+			else
+				tmp = child->thread.fpu.soft.sr;
 			break;
 		case FPC_EIR: { /* implementation / version register */
 			unsigned int flags;
 			__save_flags(flags);
-			set_cp0_status(ST0_CU1, ST0_CU1);
+			__enable_fpu();
 			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
 			__restore_flags(flags);
 			break;
@@ -452,16 +470,22 @@
 			regs->regs[addr] = data;
 			break;
 		case FPR_BASE ... FPR_BASE + 31: {
-			unsigned long *fregs =
-				(void *) child->thread.fpu.hard.fp_regs;
+			unsigned long long *fregs = (unsigned long long *)
+				&child->thread.fpu.hard.fp_regs[0];
+
 			if (child->used_math) {
 #ifndef CONFIG_SMP
-				if (last_task_used_math == child) {
-					set_cp0_status(ST0_CU1, ST0_CU1);
-					save_fp(child);
-					set_cp0_status(ST0_CU1, 0);
-					last_task_used_math = NULL;
-					regs->cp0_status &= ~ST0_CU1;
+				if (mips_cpu.options & MIPS_CPU_FPU) {
+					if (last_task_used_math == child) {
+						__enable_fpu();
+						save_fp(child);
+						__disable_fpu();
+						last_task_used_math = NULL;
+						regs->cp0_status &= ~ST0_CU1;
+					} else {
+						fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+					}
 				}
 #endif
 			} else {
@@ -494,7 +518,10 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			child->thread.fpu.hard.control = data;
+			if (mips_cpu.options & MIPS_CPU_FPU)
+				child->thread.fpu.hard.control = data;
+			else
+				child->thread.fpu.soft.sr = data;
 			break;
 		default:
 			/* The rest are not allowed. */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/r4k_genex.S linux/arch/mips64/kernel/r4k_genex.S
--- linux.orig/arch/mips64/kernel/r4k_genex.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/r4k_genex.S	2002-07-20 01:08:24.000000000 +0000
@@ -8,88 +8,19 @@
  *
  * Low level exception handling
  */
-#define __ASSEMBLY__
 #include <linux/init.h>
 #include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
+#include <asm/exception.h>
 #include <asm/r4kcacheops.h>
 
-	.macro	__build_clear_none
-	.endm
-
-	.macro	__build_clear_sti
-	STI
-	.endm
-
-	.macro	__build_clear_cli
-	CLI
-	.endm
-
-	.macro	__build_clear_fpe
-	cfc1	a1, fcr31
-	li	a2, ~(0x3f << 13)
-	and	a2, a1
-	ctc1	a2, fcr31
-	STI
-	.endm
-
-	.macro	__build_clear_ade
-	dmfc0	t0, CP0_BADVADDR
-	sd	t0, PT_BVADDR(sp)
-	KMODE
-	.endm
-
-	.macro	__BUILD_silent exception
-	.endm
-
-	/* Gas tries to parse the PRINT argument as a string containing
-	   string escapes and emits bogus warnings if it believes to
-	   recognize an unknown escape code.  So make the arguments
-	   start with an n and gas will believe \n is ok ...  */
-	.macro	__BUILD_verbose	nexception
-	ld	a1, PT_EPC(sp)
-	PRINT("Got \nexception at %016lx\012")
-	.endm
-
-	.macro	__BUILD_count exception
-	.set	reorder
-	ld	t0,exception_count_\exception
-	daddiu	t0, 1
-	sd	t0,exception_count_\exception
-	.set	noreorder
-	.comm	exception_count\exception, 8, 8
-	.endm
-
-	.macro	BUILD_HANDLER exception handler clear verbose
-	.align	5
-	NESTED(handle_\exception, PT_SIZE, sp)
-	.set	noat
-	SAVE_ALL
-#if DEBUG_MIPS64
-jal dodebug2
-ld $4, PT_R4(sp)
-ld $5, PT_R5(sp)
-ld $6, PT_R6(sp)
-ld $7, PT_R7(sp)
-ld $2, PT_R2(sp)
-#endif
-	__BUILD_clear_\clear
-	.set	at
-	__BUILD_\verbose \exception
-	move	a0, sp
-	jal	do_\handler
-	j	ret_from_sys_call
-	 nop
-	END(handle_\exception)
-	.endm
-
 	BUILD_HANDLER adel ade ade silent		/* #4  */
 	BUILD_HANDLER ades ade ade silent		/* #5  */
-	BUILD_HANDLER ibe ibe cli silent		/* #6  */
-	BUILD_HANDLER dbe dbe cli silent		/* #7  */
+	BUILD_HANDLER ibe be cli silent			/* #6  */
+	BUILD_HANDLER dbe be cli silent			/* #7  */
 	BUILD_HANDLER bp bp sti silent			/* #9  */
 	BUILD_HANDLER ri ri sti silent			/* #10 */
 	BUILD_HANDLER cpu cpu sti silent		/* #11 */
@@ -97,6 +28,7 @@
 	BUILD_HANDLER tr tr sti silent			/* #13 */
 	BUILD_HANDLER fpe fpe fpe silent		/* #15 */
 	BUILD_HANDLER watch watch sti verbose		/* #23 */
+	BUILD_HANDLER mcheck mcheck cli verbose		/* #24 */
 	BUILD_HANDLER reserved reserved sti verbose	/* others */
 
 	__INIT
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/r4k_switch.S linux/arch/mips64/kernel/r4k_switch.S
--- linux.orig/arch/mips64/kernel/r4k_switch.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/r4k_switch.S	2002-07-20 01:08:22.000000000 +0000
@@ -8,9 +8,7 @@
  * Copyright (C) 1994, 1995, 1996, by Andreas Busse
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#include <linux/config.h>
 #include <asm/asm.h>
-#include <asm/bootinfo.h>
 #include <asm/cachectl.h>
 #include <asm/current.h>
 #include <asm/fpregdef.h>
@@ -43,14 +41,10 @@
 	 */
 	move	$28, a1
 	cpu_restore_nonscratch $28
-#ifndef CONFIG_SMP
-	daddiu	t0, $28, KERNEL_STACK_SIZE-32
-	sd	t0, kernelsp
-#else
-	mtc0	a1, CP0_WATCHLO
-	dsrl32	a1, a1, 0
-	mtc0	a1, CP0_WATCHHI
-#endif
+
+	daddiu	a1, $28, KERNEL_STACK_SIZE-32
+	set_saved_sp	a1 t0
+
 	mfc0	t1, CP0_STATUS		/* Do we really need this? */
 	li	a3, 0xff00
 	and	t1, a3
@@ -72,7 +66,7 @@
 
 LEAF(lazy_fpu_switch)
 	mfc0	t0, CP0_STATUS			# enable cp1
-	li	t3, 0x20000000
+	li	t3, ST0_CU1
 	or	t0, t3
 	mtc0	t0, CP0_STATUS
 
@@ -120,6 +114,23 @@
 	END(save_fp)
 
 /*
+ * Restore a thread's fp context.
+ */
+LEAF(restore_fp)
+	mfc0	t0, CP0_STATUS
+	sll	t1, t0, 5
+	bgez	t0, 1f				# 16 register mode?
+	 nop
+
+	fpu_restore_16odd $28
+1:
+	.set	reorder
+	fpu_restore_16even $28, t0		# clobbers t0
+
+	jr	ra
+	END(restore_fp)
+
+/*
  * Load the FPU with signalling NANS.  This bit pattern we're using has
  * the property that no matter whether considered as single or as double
  * precision represents signaling NANS.
@@ -131,7 +142,7 @@
 
 LEAF(init_fpu)
 	mfc0	t0, CP0_STATUS
-	li	t1, 0x20000000
+	li	t1, ST0_CU1
 	or	t0, t1
 	mtc0	t0, CP0_STATUS
 	sll	t0, t0, 5
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/r4k_tlb.S linux/arch/mips64/kernel/r4k_tlb.S
--- linux.orig/arch/mips64/kernel/r4k_tlb.S	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips64/kernel/r4k_tlb.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,126 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Written by Ulf Carlsson (ulfc@engr.sgi.com)
- */
-#include <linux/config.h>
-#include <linux/threads.h>
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/pgtable.h>
-#include <asm/stackframe.h>
-
-	.data
-	.comm	pgd_current, NR_CPUS * 8, 8
-
-	/*
-	 * After this macro runs we have a pointer to the pte of the address
-	 * that caused the fault in in PTR.
-	 */
-
-	.macro	LOAD_PTE2, ptr, tmp
-#ifdef CONFIG_SMP
-	dmfc0	\tmp, CP0_CONTEXT
-	dla	\ptr, pgd_current
-	dsrl	\tmp, 23
-	daddu	\ptr, \tmp
-#else
-	dla	\ptr, pgd_current
-#endif
-	dmfc0	\tmp, CP0_BADVADDR
-	ld	\ptr, (\ptr)
-	bltz	\tmp, kaddr
-	 dsrl	\tmp, (PGDIR_SHIFT-3)		# get pgd offset in bytes
-	andi	\tmp, ((PTRS_PER_PGD - 1)<<3)
-	daddu	\ptr, \tmp			# add in pgd offset
-	dmfc0	\tmp, CP0_BADVADDR
-	ld	\ptr, (\ptr)			# get pmd pointer
-	dsrl	\tmp, (PMD_SHIFT-3)		# get pmd offset in bytes
-	andi	\tmp, ((PTRS_PER_PMD - 1)<<3)
-	daddu	\ptr, \tmp			# add in pmd offset
-	dmfc0	\tmp, CP0_XCONTEXT
-	ld	\ptr, (\ptr)			# get pte pointer
-	andi	\tmp, 0xff0			# get pte offset
-	daddu	\ptr, \tmp
-	.endm
-
-	/*
-	 * This places the even/odd pte pair in the page table at the pte
-	 * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1.
-	 */
-	.macro	PTE_RELOAD, pte0, pte1
-	dsrl	\pte0, 6			# convert to entrylo0
-	dmtc0	\pte0, CP0_ENTRYLO0		# load it
-	dsrl	\pte1, 6			# convert to entrylo1
-	dmtc0	\pte1, CP0_ENTRYLO1		# load it
-	.endm
-
-	.text
-	.set	noreorder
-	.set	mips3
-
-	.align	5
-FEXPORT(except_vec0)
-	.set	noat
-1:	b	1b
-	 nop
-
-	/* TLB refill handler for the R10000.
-	 * Attention:  We may only use 32 instructions.
-	 */
-
-	.align	5
-FEXPORT(except_vec1_r10k)
-	.set	noat
-	LOAD_PTE2 k1 k0
-	ld	k0, 0(k1)			# get even pte
-	ld	k1, 8(k1)			# get odd pte
-	PTE_RELOAD k0 k1
-	nop
-	tlbwr
-	eret
-kaddr:
-	dla	k0, handle_vmalloc_address	# MAPPED kernel needs this
-	jr	k0
-	 nop
-
-	.align	5
-FEXPORT(handle_vmalloc_address)
-	.set	noat
-	/*
-	 * First, determine that the address is in/above vmalloc range.
-	 */
-	dmfc0	k0, CP0_BADVADDR
-	dli	k1, VMALLOC_START
-
-	/*
-	 * Now find offset into kptbl.
-	 */
-	dsubu	k0, k0, k1
-	dla	k1, kptbl
-	dsrl	k0, (PAGE_SHIFT+1)		# get vpn2
-	dsll	k0, 4				# byte offset of pte
-	daddu	k1, k1, k0
-
-	/*
-	 * Determine that fault address is within vmalloc range.
-	 */
-	dla	k0, ekptbl
-	sltu	k0, k1, k0
-	beqz	k0, not_vmalloc
-
-	/*
-	 * Load cp0 registers.
-	 */
-	ld	k0, 0(k1)			# get even pte
-	ld	k1, 8(k1)			# get odd pte
-
-not_vmalloc:
-	PTE_RELOAD k0 k1
-	nop
-	tlbwr
-	eret
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/r4k_tlb_debug.c linux/arch/mips64/kernel/r4k_tlb_debug.c
--- linux.orig/arch/mips64/kernel/r4k_tlb_debug.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/r4k_tlb_debug.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,71 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- *
- * TLB debugging routines.  These perform horribly slow but can easily be
- * modified for debugging purposes.
- */
-#include <linux/linkage.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/ptrace.h>
-#include <asm/system.h>
-
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
-                              unsigned long address);
-
-asmlinkage void tlb_refill_debug(struct pt_regs regs)
-{
-	show_regs(&regs);
-	panic(__FUNCTION__ " called.  This Does Not Happen (TM).");
-}
-
-asmlinkage void xtlb_refill_debug(struct pt_regs *regs)
-{
-	unsigned long addr;
-	pgd_t *pgd;
-	pmd_t *pmd;
-	pte_t *pte;
-
-	addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1);
-	pgd = pgd_offset(current->active_mm, addr);
-	pmd = pmd_offset(pgd, addr);
-	pte = pte_offset(pmd, addr);
-
-	set_entrylo0(pte_val(pte[0]) >> 6);
-	set_entrylo1(pte_val(pte[1]) >> 6);
-	__asm__ __volatile__("nop;nop;nop");
-
-	tlb_write_random();
-}
-
-asmlinkage void xtlb_mod_debug(struct pt_regs *regs)
-{
-	unsigned long addr;
-
-	addr = regs->cp0_badvaddr;
-	do_page_fault(regs, 1, addr);
-}
-
-asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs)
-{
-	unsigned long addr;
-
-	addr = regs->cp0_badvaddr;
-	do_page_fault(regs, 0, addr);
-}
-
-asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs)
-{
-	unsigned long addr;
-
-	addr = regs->cp0_badvaddr;
-	do_page_fault(regs, 1, addr);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/r4k_tlb_glue.S linux/arch/mips64/kernel/r4k_tlb_glue.S
--- linux.orig/arch/mips64/kernel/r4k_tlb_glue.S	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/r4k_tlb_glue.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,46 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#define __ASSEMBLY__
-#include <linux/init.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-	.macro	__BUILD_cli
-	CLI
-	.endm
-
-	.macro	__BUILD_sti
-	STI
-	.endm
-
-	.macro	tlb_handler name interruptible writebit
-	NESTED(__\name, PT_SIZE, sp)
-	SAVE_ALL
-#if DEBUG_MIPS64
-jal dodebug2
-ld $4, PT_R4(sp)
-ld $5, PT_R5(sp)
-ld $6, PT_R6(sp)
-ld $7, PT_R7(sp)
-ld $2, PT_R2(sp)
-#endif
-	dmfc0	a2, CP0_BADVADDR
-	__BUILD_\interruptible
-	li	a1, \writebit
-	sd	a2, PT_BVADDR(sp)
-	move	a0, sp
-	jal	do_page_fault
-	j	ret_from_sys_call
-	END(__\name)
-	.endm
-
-	tlb_handler	xtlb_mod sti 1
-	tlb_handler	xtlb_tlbl sti 0
-	tlb_handler	xtlb_tlbs sti 1
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/reset.c linux/arch/mips64/kernel/reset.c
--- linux.orig/arch/mips64/kernel/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/kernel/reset.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/reboot.h>
+#include <asm/reboot.h>
+
+/*
+ * Urgs ...  Too many MIPS machines to handle this in a generic way.
+ * So handle all using function pointers to machine specific
+ * functions.
+ */
+void (*_machine_restart)(char *command);
+void (*_machine_halt)(void);
+void (*_machine_power_off)(void);
+
+void machine_restart(char *command)
+{
+	_machine_restart(command);
+}
+
+void machine_halt(void)
+{
+	_machine_halt();
+}
+
+void machine_power_off(void)
+{
+	_machine_power_off();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/scall_64.S linux/arch/mips64/kernel/scall_64.S
--- linux.orig/arch/mips64/kernel/scall_64.S	2001-10-08 17:39:18.000000000 +0000
+++ linux/arch/mips64/kernel/scall_64.S	2002-07-20 01:08:25.000000000 +0000
@@ -347,3 +347,23 @@
 	PTR	sys_mincore
 	PTR	sys_madvise
 	PTR	sys_getdents64
+	PTR	sys_ni_syscall
+	PTR	sys_gettid				/* 5215 */
+	PTR	sys_readahead
+	PTR	sys_ni_syscall			/* reserved for setxattr */
+	PTR	sys_ni_syscall			/* reserved for lsetxattr */
+	PTR	sys_ni_syscall			/* reserved for fsetxattr */
+	PTR	sys_ni_syscall			/* 5220 res. for getxattr */
+	PTR	sys_ni_syscall			/* reserved for lgetxattr */
+	PTR	sys_ni_syscall			/* reserved for fgetxattr */
+	PTR	sys_ni_syscall			/* reserved for listxattr */
+	PTR	sys_ni_syscall			/* reserved for llistxattr */
+	PTR	sys_ni_syscall			/* 5225 res. for flistxattr */
+	PTR	sys_ni_syscall			/* reserved for removexattr */
+	PTR	sys_ni_syscall			/* reserved for lremovexattr */
+	PTR	sys_ni_syscall			/* reserved for fremovexattr */
+	PTR	sys_tkill, 2
+	PTR	sys_ni_syscall, 0		/* res. for sendfile64 */
+	PTR	sys_ni_syscall, 0		/* res. for futex */
+	PTR	sys_ni_syscall, 0		/* res. for sched_setaffinity */
+	PTR	sys_ni_syscall, 0		/* 4240 res. for sched_getaffinity */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/scall_o32.S linux/arch/mips64/kernel/scall_o32.S
--- linux.orig/arch/mips64/kernel/scall_o32.S	2001-10-08 17:39:18.000000000 +0000
+++ linux/arch/mips64/kernel/scall_o32.S	2002-07-20 01:08:28.000000000 +0000
@@ -43,6 +43,12 @@
 	daddiu	t1, 4			# skip to next instruction
 	beqz	t0, not_o32_scall
 	sd	t1, PT_EPC(sp)
+#if 0
+ SAVE_ALL
+ move a1, v0
+ PRINT("Scall %ld\n")
+ RESTORE_ALL
+#endif
 
 	/* XXX Put both in one cacheline, should save a bit. */
 	dsll	t0, v0, 3		# offset into table
@@ -192,12 +198,14 @@
 	END(handle_sys)
 
 	LEAF(mips_atomic_set)
-	ld	v1, THREAD_CURDS($28)
+	andi	v0, a1, 3			# must be word aligned
+	bnez	v0, bad_alignment
+
+	ld	v1, THREAD_CURDS($28)		# in legal address range?
 	daddiu	a0, a1, 4
 	or	a0, a0, a1
-	li	v0, -EFAULT
 	and	a0, a0, v1
-	bltz	a0, 9f
+	bltz	a0, bad_address
 
 	/* Ok, this is the ll/sc case.  World is sane :-)  */
 1:	ll	v0, (a1)
@@ -223,14 +231,19 @@
 	li	a3, 0			# success
 	j	ret_from_sys_call
 
-9:	li	v0, -EFAULT
+bad_address:
+	li	v0, -EFAULT
+	jr	ra
+
+bad_alignment:
+	li	v0, -EINVAL
 	jr	ra
 	END(mips_atomic_set)
 
-	LEAF(sys_sysmips)
+	LEAF(sys32_sysmips)
 	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
-	j	_sys_sysmips
-	END(sys_sysmips)
+	j	sys_sysmips
+	END(sys32_sysmips)
 
 	.macro	syscalltable
 	sys	sys_syscall	0			/* 4000 */
@@ -363,7 +376,7 @@
 	sys	sys_create_module 2
 	sys	sys_init_module	5
 	sys	sys_delete_module 1
-	sys	sys_get_kernel_syms 1			/* 4130 */
+	sys	sys32_get_kernel_syms 1			/* 4130 */
 	sys	sys_quotactl	0
 	sys	sys_getpgid	1
 	sys	sys_fchdir	1
@@ -382,7 +395,7 @@
 	sys	sys32_writev	3
 	sys	sys_cacheflush	3
 	sys	sys_cachectl	3
-	sys	sys_sysmips	4
+	sys	sys32_sysmips	4
 	sys	sys_ni_syscall	0			/* 4150 */
 	sys	sys_getsid	1
 	sys	sys_fdatasync	0
@@ -454,6 +467,27 @@
 	sys	sys_madvise	3
 	sys	sys_getdents64	3
 	sys	sys32_fcntl64	3			/* 4220 */
+	sys	sys_ni_syscall	0
+	sys	sys_gettid	0
+	sys	sys32_readahead	5
+	sys	sys_ni_syscall	0		/* reserved for setxattr */
+	sys	sys_ni_syscall	0		/* 4225 res. for lsetxattr */
+	sys	sys_ni_syscall	0		/* reserved for fsetxattr */
+	sys	sys_ni_syscall	0		/* reserved for getxattr */
+	sys	sys_ni_syscall	0		/* reserved for lgetxattr */
+	sys	sys_ni_syscall	0		/* reserved for fgetxattr */
+	sys	sys_ni_syscall	0		/* 4230 res. for listxattr */
+	sys	sys_ni_syscall	0		/* reserved for llistxattr */
+	sys	sys_ni_syscall	0		/* reserved for flistxattr */
+	sys	sys_ni_syscall	0		/* reserved for removexattr */
+	sys	sys_ni_syscall	0		/* reserved for lremovexattr */
+	sys	sys_ni_syscall	0		/* 4235 res. for fremovexattr */
+	sys	sys_tkill, 2
+	sys	sys_ni_syscall, 0		/* res. for sendfile64 */
+	sys	sys_ni_syscall, 0		/* res. for futex */
+	sys	sys_ni_syscall, 0		/* res. for sched_setaffinity */
+	sys	sys_ni_syscall, 0		/* 4240 res. for sched_getaffinity */
+
 	.endm
 
 	.macro	sys function, nargs
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/setup.c linux/arch/mips64/kernel/setup.c
--- linux.orig/arch/mips64/kernel/setup.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/setup.c	2002-07-20 01:08:22.000000000 +0000
@@ -4,9 +4,11 @@
  * for more details.
  *
  * Copyright (C) 1995 Linus Torvalds
- * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1995 Waldorf Electronics
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Ralf Baechle
  * Copyright (C) 1996 Stoned Elipot
  * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -14,6 +16,7 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/stddef.h>
 #include <linux/string.h>
 #include <linux/unistd.h>
@@ -23,14 +26,15 @@
 #include <linux/utsname.h>
 #include <linux/a.out.h>
 #include <linux/tty.h>
+#include <linux/bootmem.h>
 #ifdef CONFIG_BLK_DEV_RAM
 #include <linux/blk.h>
 #endif
 
-#include <asm/asm.h>
+#include <asm/addrspace.h>
 #include <asm/bootinfo.h>
-#include <asm/cachectl.h>
 #include <asm/cpu.h>
+#include <asm/mipsregs.h>
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #include <asm/pgalloc.h>
@@ -39,6 +43,15 @@
 struct cpuinfo_mips cpu_data[1];
 #endif
 
+/*
+ * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
+ * the implementation of the "wait" feature differs between CPU families. This
+ * points to the function that implements CPU specific wait. 
+ * The wait instruction stops the pipeline and reduces the power consumption of
+ * the CPU very much.
+ */
+void (*cpu_wait)(void) = NULL;
+
 #ifdef CONFIG_VT
 struct screen_info screen_info;
 #endif
@@ -51,11 +64,6 @@
 char wait_available;
 
 /*
- * Do we have a cyclecounter available?
- */
-char cyclecounter_available;
-
-/*
  * Set if box has EISA slots.
  */
 int EISA_bus = 0;
@@ -81,7 +89,6 @@
  *
  * These are initialized so they are in the .data section
  */
-unsigned long mips_cputype = CPU_UNKNOWN;
 unsigned long mips_machtype = MACH_UNKNOWN;
 unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
 
@@ -95,58 +102,648 @@
        char saved_command_line[CL_SIZE];
 extern char arcs_cmdline[CL_SIZE];
 
+/*
+ * mips_io_port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+const unsigned long mips_io_port_base = -1;
+EXPORT_SYMBOL(mips_io_port_base);
+
 extern void ip22_setup(void);
 extern void ip27_setup(void);
+extern void ip32_setup(void);
 
-static inline void cpu_probe(void)
-{
-	unsigned int prid = read_32bit_cp0_register(CP0_PRID);
+extern void sgi_sysinit(void);
+extern void SetUpBootInfo(void);
+extern void load_mmu(void);
+extern ATTRIB_NORET asmlinkage void start_kernel(void);
+extern void prom_init(int, char **, char **, int *);
 
-	switch(prid & 0xff00) {
-	case PRID_IMP_R4000:
-		if((prid & 0xff) == PRID_REV_R4400)
-			mips_cputype = CPU_R4400SC;
-		else
-			mips_cputype = CPU_R4000SC;
+static inline void check_wait(void)
+{
+	printk("Checking for 'wait' instruction... ");
+	switch(mips_cpu.cputype) {
+	case CPU_R3081:
+	case CPU_R3081E:
+		cpu_wait = r3081_wait;
+		printk(" available.\n");
 		break;
-	case PRID_IMP_R4600:
-		mips_cputype = CPU_R4600;
+	case CPU_TX3927:
+	case CPU_TX39XX:
+		cpu_wait = r39xx_wait;
+		printk(" available.\n");
 		break;
-	case PRID_IMP_R4700:
-		mips_cputype = CPU_R4700;
+	case CPU_R4200: 
+/*	case CPU_R4300: */
+	case CPU_R4600: 
+	case CPU_R4640: 
+	case CPU_R4650: 
+	case CPU_R4700: 
+	case CPU_R5000: 
+	case CPU_NEVADA:
+	case CPU_RM7000:
+	case CPU_TX49XX:
+	case CPU_4KC:
+	case CPU_4KEC:
+	case CPU_4KSC:
+	case CPU_5KC:
+/*	case CPU_20KC:*/
+		cpu_wait = r4k_wait;
+		printk(" available.\n");
 		break;
-	case PRID_IMP_R5000:
-		mips_cputype = CPU_R5000;
+	default:
+		printk(" unavailable.\n");
+		break;
+	}
+}
+
+void __init check_bugs(void)
+{
+	check_wait();
+}
+
+/*
+ * Probe whether cpu has config register by trying to play with
+ * alternate cache bit and see whether it matters.
+ * It's used by cpu_probe to distinguish between R3000A and R3081.
+ */
+static inline int cpu_has_confreg(void)
+{
+#ifdef CONFIG_CPU_R3000
+	extern unsigned long r3k_cache_size(unsigned long);
+	unsigned long size1, size2;
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+
+	size1 = r3k_cache_size(ST0_ISC);
+	write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC);
+	size2 = r3k_cache_size(ST0_ISC);
+	write_32bit_cp0_register(CP0_CONF, cfg);
+	return size1 != size2;
+#else
+	return 0;
+#endif
+}
+
+/*
+ * Get the FPU Implementation/Revision.
+ */
+static inline unsigned long cpu_get_fpu_id(void)
+{
+	unsigned long tmp, fpu_id;
+
+	tmp = read_32bit_cp0_register(CP0_STATUS);
+	__enable_fpu();
+	fpu_id = read_32bit_cp1_register(CP1_REVISION);
+	write_32bit_cp0_register(CP0_STATUS, tmp);
+	return fpu_id;
+}
+
+/* declaration of the global struct */
+struct mips_cpu mips_cpu = {
+    processor_id:	PRID_IMP_UNKNOWN,
+    fpu_id:		FPIR_IMP_NONE,
+    cputype:		CPU_UNKNOWN
+};
+
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+                | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
+
+static inline void cpu_probe(void)
+{
+#ifdef CONFIG_CPU_MIPS32
+	unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG);
+	unsigned long config1;
+
+        if (config0 & (1 << 31)) {
+		/* MIPS32 compliant CPU. Read Config 1 register. */
+		mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+			MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC;
+		config1 = read_mips32_cp0_config1();
+		if (config1 & (1 << 3))
+			mips_cpu.options |= MIPS_CPU_WATCH;
+		if (config1 & (1 << 2))
+			mips_cpu.options |= MIPS_CPU_MIPS16;
+		if (config1 & (1 << 1))
+			mips_cpu.options |= MIPS_CPU_EJTAG;
+		if (config1 & 1)
+			mips_cpu.options |= MIPS_CPU_FPU;
+		mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+	}
+#endif
+	mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID);
+	switch (mips_cpu.processor_id & 0xff0000) {
+	case PRID_COMP_LEGACY:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_R2000:
+			mips_cpu.cputype = CPU_R2000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R3000:
+			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
+				if (cpu_has_confreg())
+					mips_cpu.cputype = CPU_R3081E;
+				else
+					mips_cpu.cputype = CPU_R3000A;
+			else
+				mips_cpu.cputype = CPU_R3000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R4000:
+			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400)
+				mips_cpu.cputype = CPU_R4400SC;
+			else
+				mips_cpu.cputype = CPU_R4000SC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH |
+			                   MIPS_CPU_VCE;
+			mips_cpu.tlbsize = 48;
+			break;
+                case PRID_IMP_VR41XX:
+                        mips_cpu.cputype = CPU_VR41XX;
+                        mips_cpu.isa_level = MIPS_CPU_ISA_III;
+                        mips_cpu.options = R4K_OPTS;
+                        mips_cpu.tlbsize = 32;
+                        break;
+		case PRID_IMP_R4300:
+			mips_cpu.cputype = CPU_R4300;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_R4600:
+			mips_cpu.cputype = CPU_R4600;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 48;
+			break;
+		#if 0
+ 		case PRID_IMP_R4650:
+			/*
+			 * This processor doesn't have an MMU, so it's not
+			 * "real easy" to run Linux on it. It is left purely
+			 * for documentation.  Commented out because it shares
+			 * it's c0_prid id number with the TX3900.
+			 */
+	 		mips_cpu.cputype = CPU_R4650;
+		 	mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+		        mips_cpu.tlbsize = 48;
+			break;
+		#endif
+		case PRID_IMP_TX39:
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB;
+
+			if ((mips_cpu.processor_id & 0xf0) ==
+			    (PRID_REV_TX3927 & 0xf0)) {
+				mips_cpu.cputype = CPU_TX3927;
+				mips_cpu.tlbsize = 64;
+				mips_cpu.icache.ways = 2;
+				mips_cpu.dcache.ways = 2;
+			} else {
+				switch (mips_cpu.processor_id & 0xff) {
+				case PRID_REV_TX3912:
+					mips_cpu.cputype = CPU_TX3912;
+					mips_cpu.tlbsize = 32;
+					break;
+				case PRID_REV_TX3922:
+					mips_cpu.cputype = CPU_TX3922;
+					mips_cpu.tlbsize = 64;
+					break;
+				default:
+					mips_cpu.cputype = CPU_UNKNOWN;
+					break;
+				}
+			}
+			break;
+		case PRID_IMP_R4700:
+			mips_cpu.cputype = CPU_R4700;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_TX49:
+			mips_cpu.cputype = CPU_TX49XX;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			mips_cpu.icache.ways = 4;
+			mips_cpu.dcache.ways = 4;
+			break;
+		case PRID_IMP_R5000:
+			mips_cpu.cputype = CPU_R5000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_R5432:
+			mips_cpu.cputype = CPU_R5432;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_R5500:
+			mips_cpu.cputype = CPU_R5500;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_NEVADA:
+			mips_cpu.cputype = CPU_NEVADA;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_DIVEC;
+			mips_cpu.tlbsize = 48;
+			mips_cpu.icache.ways = 2;
+			mips_cpu.dcache.ways = 2;
+			break;
+		case PRID_IMP_R6000:
+			mips_cpu.cputype = CPU_R6000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_II;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_R6000A:
+			mips_cpu.cputype = CPU_R6000A;
+			mips_cpu.isa_level = MIPS_CPU_ISA_II;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_RM7000:
+			mips_cpu.cputype = CPU_RM7000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			/*
+			 * Undocumented RM7000:  Bit 29 in the info register of
+			 * the RM7000 v2.0 indicates if the TLB has 48 or 64
+			 * entries.
+			 *
+			 * 29      1 =>    64 entry JTLB
+			 *         0 =>    48 entry JTLB
+			 */
+			mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48;
+			break;
+		case PRID_IMP_R8000:
+			mips_cpu.cputype = CPU_R8000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 384;      /* has wierd TLB: 3-way x 128 */
+			break;
+		case PRID_IMP_R10000:
+			mips_cpu.cputype = CPU_R10000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR | 
+				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R12000:
+			mips_cpu.cputype = CPU_R12000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR | 
+				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 64;
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
 		break;
-	case PRID_IMP_NEVADA:
-		mips_cputype = CPU_NEVADA;
+#ifdef CONFIG_CPU_MIPS32
+	case PRID_COMP_MIPS:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_4KC:
+			mips_cpu.cputype = CPU_4KC;
+			break;
+		case PRID_IMP_4KEC:
+			mips_cpu.cputype = CPU_4KEC;
+			break;
+		case PRID_IMP_4KSC:
+			mips_cpu.cputype = CPU_4KSC;
+			break;
+		case PRID_IMP_5KC:
+			mips_cpu.cputype = CPU_5KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			break;
+		case PRID_IMP_20KC:
+			mips_cpu.cputype = CPU_20KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}		
 		break;
-	case PRID_IMP_R8000:
-		mips_cputype = CPU_R8000;
+	case PRID_COMP_ALCHEMY:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_AU1_REV1:
+		case PRID_IMP_AU1_REV2:
+			if (mips_cpu.processor_id & 0xff000000)
+				mips_cpu.cputype = CPU_AU1500;
+			else
+				mips_cpu.cputype = CPU_AU1000;
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
 		break;
-	case PRID_IMP_R10000:
-	case PRID_IMP_R12000:
-		mips_cputype = CPU_R10000;
+#endif /* CONFIG_CPU_MIPS32 */
+	case PRID_COMP_SIBYTE:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_SB1:
+			mips_cpu.cputype = CPU_SB1;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+			                   MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
+			                   MIPS_CPU_MCHECK;
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+			/* FPU in pass1 is known to have issues. */
+			mips_cpu.options |= MIPS_CPU_FPU;
+#endif
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
 		break;
 	default:
-		mips_cputype = CPU_UNKNOWN;
+		mips_cpu.cputype = CPU_UNKNOWN;
 	}
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		mips_cpu.fpu_id = cpu_get_fpu_id();
 }
 
-void __init setup_arch(char **cmdline_p)
+static inline void cpu_report(void)
 {
+	printk("CPU revision is: %08x\n", mips_cpu.processor_id);
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		printk("FPU revision is: %08x\n", mips_cpu.fpu_id);
+}
+
+asmlinkage void __init init_arch(int argc, char **argv, char **envp,
+	int *prom_vec)
+{
+	/* Determine which MIPS variant we are running on. */
 	cpu_probe();
+
+	prom_init(argc, argv, envp, prom_vec);
+
+#ifdef CONFIG_SGI_IP22
+	sgi_sysinit();
+#endif
+
+	cpu_report();
+
+	/*
+	 * Determine the mmu/cache attached to this machine, then flush the
+	 * tlb and caches.  On the r4xx0 variants this also sets CP0_WIRED to
+	 * zero.
+	 */
 	load_mmu();
 
+	/*
+	 * On IP27, I am seeing the TS bit set when the kernel is loaded.
+	 * Maybe because the kernel is in ckseg0 and not xkphys? Clear it
+	 * anyway ...
+	 */
+	clear_cp0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3);
+	set_cp0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR);
+
+	start_kernel();
+}
+
+void __init add_memory_region(phys_t start, phys_t size,
+			      long type)
+{
+	int x = boot_mem_map.nr_map;
+
+	if (x == BOOT_MEM_MAP_MAX) {
+		printk("Ooops! Too many entries in the memory map!\n");
+		return;
+	}
+
+	boot_mem_map.map[x].addr = start;
+	boot_mem_map.map[x].size = size;
+	boot_mem_map.map[x].type = type;
+	boot_mem_map.nr_map++;
+}
+
+static void __init print_memory_map(void)
+{
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		printk(" memory: %08Lx @ %08Lx ",
+			(unsigned long long) boot_mem_map.map[i].size,
+			(unsigned long long) boot_mem_map.map[i].addr);
+		switch (boot_mem_map.map[i].type) {
+		case BOOT_MEM_RAM:
+			printk("(usable)\n");
+			break;
+		case BOOT_MEM_ROM_DATA:
+			printk("(ROM data)\n");
+			break;
+		case BOOT_MEM_RESERVED:
+			printk("(reserved)\n");
+			break;
+		default:
+			printk("type %lu\n", boot_mem_map.map[i].type);
+			break;
+		}
+	}
+}
+
+static inline void parse_mem_cmdline(void)
+{
+	char c = ' ', *to = command_line, *from = saved_command_line;
+	unsigned long start_at, mem_size;
+	int len = 0;
+	int usermem = 0;
+
+	printk("Determined physical RAM map:\n");
+	print_memory_map();
+
+	for (;;) {
+		/*
+		 * "mem=XXX[kKmM]" defines a memory region from
+		 * 0 to <XXX>, overriding the determined size.
+		 * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from
+		 * <YYY> to <YYY>+<XXX>, overriding the determined size.
+		 */
+		if (c == ' ' && !memcmp(from, "mem=", 4)) {
+			if (to != command_line)
+				to--;
+			/*
+			 * If a user specifies memory size, we
+			 * blow away any automatically generated
+			 * size.
+			 */
+			if (usermem == 0) {
+				boot_mem_map.nr_map = 0;
+				usermem = 1;
+			}
+			mem_size = memparse(from + 4, &from);
+			if (*from == '@')
+				start_at = memparse(from + 1, &from);
+			else
+				start_at = 0;
+			add_memory_region(start_at, mem_size, BOOT_MEM_RAM);
+		}
+		c = *(from++);
+		if (!c)
+			break;
+		if (CL_SIZE <= ++len)
+			break;
+		*(to++) = c;
+	}
+	*to = '\0';
+
+	if (usermem) {
+		printk("User-defined physical RAM map:\n");
+		print_memory_map();
+	}
+}
+
+void bootmem_init(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long tmp;
+	unsigned long *initrd_header;
+#endif
+	unsigned long bootmap_size;
+	unsigned long start_pfn, max_pfn;
+	int i;
+	extern int _end;
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
+
+	/*
+	 * Partially used pages are not usable - thus
+	 * we are rounding upwards.
+	 * start_pfn = PFN_UP(__pa(&_end));
+	 */
+	start_pfn = PFN_UP((unsigned long)&_end - KSEG0);
+
+	/* Find the highest page frame number we have available.  */
+	max_pfn = 0;
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long start, end;
+
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			continue;
+
+		start = PFN_UP(boot_mem_map.map[i].addr);
+		end = PFN_DOWN(boot_mem_map.map[i].addr
+		      + boot_mem_map.map[i].size);
+
+		if (start >= end)
+			continue;
+		if (end > max_pfn)
+			max_pfn = end;
+	}
+
+	/* Initialize the boot-time allocator.  */
+	bootmap_size = init_bootmem(start_pfn, max_pfn);
+
+	/*
+	 * Register fully available low RAM pages with the bootmem allocator.
+	 */
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long curr_pfn, last_pfn, size;
+
+		/*
+		 * Reserve usable memory.
+		 */
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			continue;
+
+		/*
+		 * We are rounding up the start address of usable memory:
+		 */
+		curr_pfn = PFN_UP(boot_mem_map.map[i].addr);
+		if (curr_pfn >= max_pfn)
+			continue;
+		if (curr_pfn < start_pfn)
+			curr_pfn = start_pfn;
+
+		/*
+		 * ... and at the end of the usable range downwards:
+		 */
+		last_pfn = PFN_DOWN(boot_mem_map.map[i].addr
+				    + boot_mem_map.map[i].size);
+
+		if (last_pfn > max_pfn)
+			last_pfn = max_pfn;
+
+		/*
+		 * ... finally, did all the rounding and playing
+		 * around just make the area go away?
+		 */
+		if (last_pfn <= curr_pfn)
+			continue;
+
+		size = last_pfn - curr_pfn;
+		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
+	}
+
+	/* Reserve the bootmap memory.  */
+	reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#error "Initrd is broken, please fit it."
+	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
+	if (tmp < (unsigned long)&_end)
+		tmp += PAGE_SIZE;
+	initrd_header = (unsigned long *)tmp;
+	if (initrd_header[0] == 0x494E5244) {
+		initrd_start = (unsigned long)&initrd_header[2];
+		initrd_end = initrd_start + initrd_header[1];
+		initrd_below_start_ok = 1;
+		if (initrd_end > memory_end) {
+			printk("initrd extends beyond end of memory "
+			       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+			       initrd_end,memory_end);
+			initrd_start = 0;
+		} else
+			*memory_start_p = initrd_end;
+	}
+#endif
+
+#undef PFN_UP
+#undef PFN_DOWN
+#undef PFN_PHYS
+
+}
+
+void __init setup_arch(char **cmdline_p)
+{
 #ifdef CONFIG_SGI_IP22
 	ip22_setup();
 #endif
 #ifdef CONFIG_SGI_IP27
 	ip27_setup();
 #endif
-
-#ifdef CONFIG_ARC_MEMORY
-	bootmem_init ();
+#ifdef CONFIG_SGI_IP32
+	ip32_setup();
+#endif
+#ifdef CONFIG_SIBYTE_SWARM
+	swarm_setup();
 #endif
 
 	strncpy(command_line, arcs_cmdline, CL_SIZE);
@@ -155,5 +752,35 @@
 
 	*cmdline_p = command_line;
 
+	parse_mem_cmdline();
+
+	bootmem_init();
+
 	paging_init();
 }
+
+void r3081_wait(void) 
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
+}
+
+void r39xx_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT);
+}
+
+void r4k_wait(void)
+{
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		".set\tmips0");
+}
+
+int __init fpu_disable(char *s)
+{
+	mips_cpu.options &= ~MIPS_CPU_FPU;
+	return 1;
+}
+__setup("nofpu", fpu_disable);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/signal.c linux/arch/mips64/kernel/signal.c
--- linux.orig/arch/mips64/kernel/signal.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/signal.c	2002-07-20 01:08:29.000000000 +0000
@@ -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/mips64/kernel/signal32.c linux/arch/mips64/kernel/signal32.c
--- linux.orig/arch/mips64/kernel/signal32.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/signal32.c	2002-07-20 01:08:37.000000000 +0000
@@ -69,11 +69,12 @@
 	unsigned int fcr0;
 	int err = 0;
 
-	err |= __copy_to_user(&sc->sc_fpregs[0], 
-		&current->thread.fpu.hard.fp_regs[0], NUM_FPU_REGS * 
-						sizeof(unsigned long));
-	err |= __copy_to_user(&sc->sc_fpc_csr, &current->thread.fpu.hard.control,
-						sizeof(unsigned int));
+	err |= __copy_to_user(&sc->sc_fpregs[0],
+			      &current->thread.fpu.hard.fp_regs[0],
+			      NUM_FPU_REGS * sizeof(unsigned long));
+	err |= __copy_to_user(&sc->sc_fpc_csr,
+			      &current->thread.fpu.hard.control,
+			      sizeof(unsigned int));
 	__asm__ __volatile__("cfc1 %0, $0\n\t" : "=r" (fcr0));
 	err |= __copy_to_user(&sc->sc_fpc_eir, &fcr0, sizeof(unsigned int));
 
@@ -86,18 +87,18 @@
 
 	if (verify_area(VERIFY_READ, sc, sizeof(*sc)))
 		return -EFAULT;
-	err |= __copy_from_user(&current->thread.fpu.hard.fp_regs[0], 
-			&sc->sc_fpregs[0], NUM_FPU_REGS * sizeof(unsigned long));
-	err |= __copy_from_user(&current->thread.fpu.hard.control, &sc->sc_fpc_csr,
-							sizeof(unsigned int));
+	err |= __copy_from_user(&current->thread.fpu.hard.fp_regs[0],
+				&sc->sc_fpregs[0],
+				NUM_FPU_REGS * sizeof(unsigned long));
+	err |= __copy_from_user(&current->thread.fpu.hard.control,
+				&sc->sc_fpc_csr, sizeof(unsigned int));
 	return err;
 }
 
 extern void __put_sigset_unknown_nsig(void);
 extern void __get_sigset_unknown_nsig(void);
 
-static inline int
-put_sigset(const sigset_t *kbuf, sigset32_t *ubuf)
+static inline int put_sigset(const sigset_t *kbuf, sigset32_t *ubuf)
 {
 	int err = 0;
 
@@ -118,8 +119,7 @@
 	return err;
 }
 
-static inline int
-get_sigset(sigset_t *kbuf, const sigset32_t *ubuf)
+static inline int get_sigset(sigset_t *kbuf, const sigset32_t *ubuf)
 {
 	int err = 0;
 	unsigned long sig[4];
@@ -146,8 +146,7 @@
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
-asmlinkage inline int
-sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs)
+asmlinkage inline int sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs)
 {
 	sigset32_t *uset;
 	sigset_t newset, saveset;
@@ -174,8 +173,7 @@
 	}
 }
 
-asmlinkage int
-sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs)
+asmlinkage int sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs)
 {
 	sigset32_t *uset;
 	sigset_t newset, saveset;
@@ -253,8 +251,7 @@
 	return ret;
 }
 
-asmlinkage int
-sys32_sigaltstack(abi64_no_regargs, struct pt_regs regs)
+asmlinkage int sys32_sigaltstack(abi64_no_regargs, struct pt_regs regs)
 {
 	const stack32_t *uss = (const stack32_t *) regs.regs[4];
 	stack32_t *uoss = (stack32_t *) regs.regs[5];
@@ -292,8 +289,8 @@
 	return ret;
 }
 
-static asmlinkage int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+static asmlinkage int restore_sigcontext(struct pt_regs *regs,
+					 struct sigcontext *sc)
 {
 	int owned_fp;
 	int err = 0;
@@ -345,8 +342,7 @@
 	struct ucontext rs_uc;
 };
 
-asmlinkage void
-sys32_sigreturn(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void sys32_sigreturn(abi64_no_regargs, struct pt_regs regs)
 {
 	struct sigframe *frame;
 	sigset_t blocked;
@@ -373,7 +369,7 @@
 		syscall_trace();
 	__asm__ __volatile__(
 		"move\t$29, %0\n\t"
-		"j\tret_from_sys_call"
+		"j\to32_ret_from_sys_call"
 		:/* no outputs */
 		:"r" (&regs));
 	/* Unreached */
@@ -382,8 +378,7 @@
 	force_sig(SIGSEGV, current);
 }
 
-asmlinkage void
-sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
 {
 	struct rt_sigframe *frame;
 	sigset_t set;
@@ -415,7 +410,7 @@
 	 */
 	__asm__ __volatile__(
 		"move\t$29, %0\n\t"
-		"j\tret_from_sys_call"
+		"j\to32_ret_from_sys_call"
 		:/* no outputs */
 		:"r" (&regs));
 	/* Unreached */
@@ -424,8 +419,8 @@
 	force_sig(SIGSEGV, current);
 }
 
-static int inline
-setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+static int inline setup_sigcontext(struct pt_regs *regs,
+				   struct sigcontext *sc)
 {
 	int err = 0;
 
@@ -470,8 +465,8 @@
 /*
  * Determine which stack to use..
  */
-static inline void *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+				 size_t frame_size)
 {
 	unsigned long sp;
 
@@ -485,9 +480,8 @@
 	return (void *)((sp - frame_size) & ALMASK);
 }
 
-static void inline
-setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-            int signr, sigset_t *set)
+static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+			       int signr, sigset_t *set)
 {
 	struct sigframe *frame;
 	int err = 0;
@@ -537,8 +531,9 @@
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 #if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
-	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->sf_code);
 #endif
         return;
 
@@ -548,9 +543,9 @@
 	force_sig(SIGSEGV, current);
 }
 
-static void inline
-setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-               int signr, sigset_t *set, siginfo_t *info)
+static void inline setup_rt_frame(struct k_sigaction * ka,
+				  struct pt_regs *regs, int signr,
+				  sigset_t *set, siginfo_t *info)
 {
 	struct rt_sigframe *frame;
 	int err = 0;
@@ -613,8 +608,9 @@
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 #if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
-	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->rs_code);
 #endif
 	return;
 
@@ -624,9 +620,9 @@
 	force_sig(SIGSEGV, current);
 }
 
-static inline void
-handle_signal(unsigned long sig, struct k_sigaction *ka,
-	siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
+				 siginfo_t *info, sigset_t *oldset,
+				 struct pt_regs * regs)
 {
 	if (ka->sa.sa_flags & SA_SIGINFO)
 		setup_rt_frame(ka, regs, sig, oldset, info);
@@ -644,8 +640,8 @@
 	}
 }
 
-static inline void
-syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+static inline void syscall_restart(struct pt_regs *regs,
+				   struct k_sigaction *ka)
 {
 	switch(regs->regs[0]) {
 	case ERESTARTNOHAND:
@@ -733,7 +729,7 @@
 				continue;
 
 			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH:
+			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 				continue;
 
 			case SIGTSTP: case SIGTTIN: case SIGTTOU:
@@ -757,10 +753,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 */
 			}
 		}
@@ -915,5 +908,12 @@
 	return ret;
 }
 
-asmlinkage void sys32_rt_sigtimedwait(void) { panic(__FUNCTION__ " called."); }
-asmlinkage void sys32_rt_sigqueueinfo(void) { panic(__FUNCTION__ " called."); }
+asmlinkage void sys32_rt_sigtimedwait(void)
+{
+	panic("%s called.", __FUNCTION__);
+}
+
+asmlinkage void sys32_rt_sigqueueinfo(void)
+{
+	panic("%s called.", __FUNCTION__);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/smp.c linux/arch/mips64/kernel/smp.c
--- linux.orig/arch/mips64/kernel/smp.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/mips64/kernel/smp.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,13 +1,26 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 2001 Kanoj Sarcar
+ * Copyright (C) 2000, 2001 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ */
 #include <linux/config.h>
+#include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/threads.h>
+#include <linux/module.h>
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/sched.h>
 #include <linux/cache.h>
 
 #include <asm/atomic.h>
+#include <asm/cpu.h>
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/hardirq.h>
@@ -15,86 +28,66 @@
 #include <asm/mmu_context.h>
 #include <asm/irq.h>
 
-#ifdef CONFIG_SGI_IP27
-
-#include <asm/sn/arch.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/agent.h>
-#include <asm/sn/sn0/ip27.h>
-
-#define DORESCHED	0xab
-#define DOCALL		0xbc
-
-static void sendintr(int destid, unsigned char status)
-{
-	int irq;
-
-#if (CPUS_PER_NODE == 2)
-	switch (status) {
-		case DORESCHED:	irq = CPU_RESCHED_A_IRQ; break;
-		case DOCALL:	irq = CPU_CALL_A_IRQ; break;
-		default:	panic("sendintr");
-	}
-	irq += cputoslice(destid);
-
-	/*
-	 * Convert the compact hub number to the NASID to get the correct
-	 * part of the address space.  Then set the interrupt bit associated
-	 * with the CPU we want to send the interrupt to.
-	 */
-	REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)),
-			FAST_IRQ_TO_LEVEL(irq));
-#else
-	<< Bomb!  Must redefine this for more than 2 CPUS. >>
-#endif
-}
-
-#endif /* CONFIG_SGI_IP27 */
-
 /* The 'big kernel lock' */
 spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 int smp_threads_ready;	/* Not used */
 atomic_t smp_commenced = ATOMIC_INIT(0);
 struct cpuinfo_mips cpu_data[NR_CPUS];
-int smp_num_cpus = 1;		/* Number that came online.  */
+void (*volatile smp_cpu0_finalize)(void);
+
+// static atomic_t cpus_booted = ATOMIC_INIT(0);
+atomic_t cpus_booted = ATOMIC_INIT(0);
+
+int smp_num_cpus = 1;			/* Number that came online.  */
+cpumask_t cpu_online_map;		/* Bitmask of currently online CPUs */
 int __cpu_number_map[NR_CPUS];
 int __cpu_logical_map[NR_CPUS];
 cycles_t cacheflush_time;
 
-static void smp_tune_scheduling (void)
+// static void smp_tune_scheduling (void)
+void smp_tune_scheduling (void)
 {
 }
 
-void __init smp_boot_cpus(void)
+void __init smp_callin(void)
 {
-	extern void allowboot(void);
-
-	init_new_context(current, &init_mm);
-	current->processor = 0;
-	init_idle();
-	smp_tune_scheduling();
-	allowboot();
+#if 0
+	calibrate_delay();
+	smp_store_cpu_info(cpuid);
+#endif
 }
 
-void __init smp_commence(void)
+#ifndef CONFIG_SGI_IP27
+/*
+ * Hook for doing final board-specific setup after the generic smp setup
+ * is done
+ */
+asmlinkage void start_secondary(void)
 {
-	wmb();
-	atomic_set(&smp_commenced,1);
-}
+	unsigned int cpu = smp_processor_id();
+
+	prom_init_secondary();
+	per_cpu_trap_init();
 
-static void stop_this_cpu(void *dummy)
-{
 	/*
-	 * Remove this CPU
+	 * XXX parity protection should be folded in here when it's converted
+	 * to an option instead of something based on .cputype
 	 */
-	for (;;);
+	pgd_current[cpu] = init_mm.pgd;
+	cpu_data[cpu].udelay_val = loops_per_jiffy;
+	prom_smp_finish();
+	printk("Slave cpu booted successfully\n");
+	CPUMASK_SETB(cpu_online_map, cpu);
+	atomic_inc(&cpus_booted);
+	while (!atomic_read(&smp_commenced));
+	cpu_idle();
 }
+#endif /* CONFIG_SGI_IP27 */
 
-void smp_send_stop(void)
+void __init smp_commence(void)
 {
-	smp_call_function(stop_this_cpu, NULL, 1, 0);
-	smp_num_cpus = 1;
+	wmb();
+	atomic_set(&smp_commenced, 1);
 }
 
 /*
@@ -104,7 +97,7 @@
  */
 void smp_send_reschedule(int cpu)
 {
-	sendintr(cpu, DORESCHED);
+	core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);
 }
 
 /* Not really SMP stuff ... */
@@ -113,6 +106,10 @@
 	return 0;
 }
 
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
+struct call_data_struct *call_data;
+
 /*
  * Run a function on all other CPUs.
  *  <func>      The function to run. This must be fast and non-blocking.
@@ -124,22 +121,15 @@
  * Does not return until remote CPUs are nearly ready to execute <func>
  * or are or have executed.
  */
-static volatile struct call_data_struct {
-	void (*func) (void *info);
-	void *info;
-	atomic_t started;
-	atomic_t finished;
-	int wait;
-} *call_data;
 
 int smp_call_function (void (*func) (void *info), void *info, int retry, 
 								int wait)
 {
 	struct call_data_struct data;
-	int i, cpus = smp_num_cpus-1;
-	static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+	int i, cpus = smp_num_cpus - 1;
+	int cpu = smp_processor_id();
 
-	if (cpus == 0)
+	if (!cpus)
 		return 0;
 
 	data.func = func;
@@ -149,12 +139,13 @@
 	if (wait)
 		atomic_set(&data.finished, 0);
 
-	spin_lock_bh(&lock);
+	spin_lock(&call_lock);
 	call_data = &data;
+
 	/* Send a message to all other CPUs and wait for them to respond */
 	for (i = 0; i < smp_num_cpus; i++)
-		if (smp_processor_id() != i)
-			sendintr(i, DOCALL);
+		if (i != cpu)
+			core_send_ipi(i, SMP_CALL_FUNCTION);
 
 	/* Wait for response */
 	/* FIXME: lock-up detection, backtrace on lock-up */
@@ -164,45 +155,68 @@
 	if (wait)
 		while (atomic_read(&data.finished) != cpus)
 			barrier();
-	spin_unlock_bh(&lock);
+	spin_unlock(&call_lock);
+
 	return 0;
 }
 
-extern void smp_call_function_interrupt(int irq, void *d, struct pt_regs *r)
+void smp_call_function_interrupt(void)
 {
 	void (*func) (void *info) = call_data->func;
 	void *info = call_data->info;
 	int wait = call_data->wait;
+	int cpu = smp_processor_id();
 
+	irq_enter(cpu, 0);	/* XXX choose an irq number? */
 	/*
 	 * Notify initiating CPU that I've grabbed the data and am
 	 * about to execute the function.
 	 */
+	mb();
 	atomic_inc(&call_data->started);
 
 	/*
 	 * At this point the info structure may be out of scope unless wait==1.
 	 */
 	(*func)(info);
-	if (wait)
+	if (wait) {
+		mb();
 		atomic_inc(&call_data->finished);
+	}
+	irq_exit(cpu, 0);	/* XXX choose an irq number? */
+}
+
+static void stop_this_cpu(void *dummy)
+{
+	int cpu = smp_processor_id();
+	if (cpu)
+		for (;;);		/* XXX Use halt like i386 */
+
+	/* XXXKW this isn't quite there yet */
+	while (!smp_cpu0_finalize) ;
+	smp_cpu0_finalize();
+}
+
+void smp_send_stop(void)
+{
+	smp_call_function(stop_this_cpu, NULL, 1, 0);
+	smp_num_cpus = 1;
 }
-	
 
 static void flush_tlb_all_ipi(void *info)
 {
-	_flush_tlb_all();
+	local_flush_tlb_all();
 }
 
 void flush_tlb_all(void)
 {
 	smp_call_function(flush_tlb_all_ipi, 0, 1, 1);
-	_flush_tlb_all();
+	local_flush_tlb_all();
 }
 
 static void flush_tlb_mm_ipi(void *mm)
 {
-	_flush_tlb_mm((struct mm_struct *)mm);
+	local_flush_tlb_mm((struct mm_struct *)mm);
 }
 
 /*
@@ -228,7 +242,7 @@
 			if (smp_processor_id() != i)
 				CPU_CONTEXT(i, mm) = 0;
 	}
-	_flush_tlb_mm(mm);
+	local_flush_tlb_mm(mm);
 }
 
 struct flush_tlb_data {
@@ -242,7 +256,7 @@
 {
 	struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
 
-	_flush_tlb_range(fd->mm, fd->addr1, fd->addr2);
+	local_flush_tlb_range(fd->mm, fd->addr1, fd->addr2);
 }
 
 void flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
@@ -260,14 +274,14 @@
 			if (smp_processor_id() != i)
 				CPU_CONTEXT(i, mm) = 0;
 	}
-	_flush_tlb_range(mm, start, end);
+	local_flush_tlb_range(mm, start, end);
 }
 
 static void flush_tlb_page_ipi(void *info)
 {
 	struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
 
-	_flush_tlb_page(fd->vma, fd->addr1);
+	local_flush_tlb_page(fd->vma, fd->addr1);
 }
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
@@ -284,6 +298,15 @@
 			if (smp_processor_id() != i)
 				CPU_CONTEXT(i, vma->vm_mm) = 0;
 	}
-	_flush_tlb_page(vma, page);
+	local_flush_tlb_page(vma, page);
 }
 
+EXPORT_SYMBOL(smp_num_cpus);
+EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(cpu_data);
+EXPORT_SYMBOL(synchronize_irq);
+EXPORT_SYMBOL(kernel_flag);
+EXPORT_SYMBOL(__global_sti);
+EXPORT_SYMBOL(__global_cli);
+EXPORT_SYMBOL(__global_save_flags);
+EXPORT_SYMBOL(__global_restore_flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/syscall.c linux/arch/mips64/kernel/syscall.c
--- linux.orig/arch/mips64/kernel/syscall.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/syscall.c	2002-07-20 01:08:27.000000000 +0000
@@ -50,12 +50,69 @@
 	return res;
 }
 
+#define COLOUR_ALIGN(addr,pgoff)		\
+	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
+	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct * vmm;
+	int do_color_align;
+
+	if (flags & MAP_FIXED) {
+		/*
+		 * We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+	do_color_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+	if (addr) {
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+		vmm = find_vma(current->mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vmm || addr + len <= vmm->vm_start))
+			return addr;
+	}
+	addr = TASK_UNMAPPED_BASE;
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
+		/* At this point:  (!vmm || addr < vmm->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vmm || addr + len <= vmm->vm_start)
+			return addr;
+		addr = vmm->vm_end;
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+	}
+}
+
 asmlinkage unsigned long
 sys_mmap(unsigned long addr, size_t len, unsigned long prot,
          unsigned long flags, unsigned long fd, off_t offset)
 {
 	struct file * file = NULL;
-	unsigned long error = -EFAULT;
+	unsigned long error;
+
+	error = -EINVAL;
+	if (offset & ~PAGE_MASK)
+		goto out;
 
 	if (!(flags & MAP_ANONYMOUS)) {
 		error = -EBADF;
@@ -70,8 +127,8 @@
 	up_write(&current->mm->mmap_sem);
         if (file)
                 fput(file);
-out:
 
+out:
 	return error;
 }
 
@@ -130,7 +187,7 @@
 }
 
 asmlinkage int
-_sys_sysmips(int cmd, long arg1, int arg2, int arg3)
+sys_sysmips(int cmd, long arg1, int arg2, int arg3)
 {
 	int	*p;
 	char	*name;
@@ -151,8 +208,8 @@
 
 		down_write(&uts_sem);
 		strncpy(system_utsname.nodename, name, len);
-		up_write(&uts_sem);
 		system_utsname.nodename[len] = '\0';
+		up_write(&uts_sem);
 		return 0;
 	}
 
@@ -259,8 +316,7 @@
 /*
  * No implemented yet ...
  */
-asmlinkage int
-sys_cachectl(char *addr, int nbytes, int op)
+asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
 {
 	return -ENOSYS;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/time.c linux/arch/mips64/kernel/time.c
--- linux.orig/arch/mips64/kernel/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/kernel/time.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,571 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Common time service routines for MIPS machines. See 
+ * Documents/MIPS/README.txt. 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/time.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/hardirq.h>
+#include <asm/div64.h>
+
+/* This is for machines which generate the exact clock. */
+#define USECS_PER_JIFFY (1000000/HZ)
+#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ))
+
+/*
+ * forward reference
+ */
+extern rwlock_t xtime_lock;
+extern volatile unsigned long wall_jiffies;
+
+/*
+ * whether we emulate local_timer_interrupts for SMP machines.
+ */
+int emulate_local_timer_interrupt;
+
+/*
+ * By default we provide the null RTC ops
+ */
+static unsigned long null_rtc_get_time(void)
+{
+	return mktime(2000, 1, 1, 0, 0, 0);
+}
+
+static int null_rtc_set_time(unsigned long sec)
+{
+	return 0;
+}
+
+unsigned long (*rtc_get_time)(void) = null_rtc_get_time;
+int (*rtc_set_time)(unsigned long) = null_rtc_set_time;
+
+
+/*
+ * timeofday services, for syscalls.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+
+	read_lock_irqsave (&xtime_lock, flags);
+	*tv = xtime;
+	tv->tv_usec += do_gettimeoffset();
+
+	/*
+	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+	 * is nonzero if the timer bottom half hasnt executed yet.
+	 */
+	if (jiffies - wall_jiffies)
+		tv->tv_usec += USECS_PER_JIFFY;
+
+	read_unlock_irqrestore (&xtime_lock, flags);
+
+	if (tv->tv_usec >= 1000000) {
+		tv->tv_usec -= 1000000;
+		tv->tv_sec++;
+	}
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq (&xtime_lock);
+
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	tv->tv_usec -= do_gettimeoffset();
+
+	if (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+	xtime = *tv;
+	time_adjust = 0;			/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
+	write_unlock_irq (&xtime_lock);
+}
+
+
+/*
+ * Gettimeoffset routines.  These routines returns the time duration
+ * since last timer interrupt in usecs.
+ *
+ * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset.
+ * Otherwise use calibrate_gettimeoffset()
+ *
+ * If the CPU does not have counter register all, you can either supply
+ * your own gettimeoffset() routine, or use null_gettimeoffset() routines,
+ * which gives the same resolution as HZ.
+ */
+
+
+/* This is for machines which generate the exact clock. */
+#define USECS_PER_JIFFY (1000000/HZ)
+
+/* usecs per counter cycle, shifted to left by 32 bits */
+static unsigned int sll32_usecs_per_cycle=0;
+
+/* how many counter cycles in a jiffy */
+static unsigned long cycles_per_jiffy=0;
+
+/* Cycle counter value at the previous timer interrupt.. */
+static unsigned int timerhi, timerlo;
+
+/* last time when xtime and rtc are sync'ed up */
+static long last_rtc_update;
+
+/* the function pointer to one of the gettimeoffset funcs*/
+unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset;
+
+unsigned long null_gettimeoffset(void)
+{
+	return 0;
+}
+
+unsigned long fixed_rate_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res;
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+	        "mfhi\t%0"
+	        :"=r" (res)
+	        :"r" (count),
+	         "r" (sll32_usecs_per_cycle));
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
+}
+
+/*
+ * Cached "1/(clocks per usec)*2^32" value.
+ * It has to be recalculated once each jiffy.
+ */
+static unsigned long cached_quotient;
+
+/* Last jiffy when calibrate_divXX_gettimeoffset() was called. */
+static unsigned long last_jiffies = 0;
+
+
+/*
+ * This is copied from dec/time.c:do_ioasic_gettimeoffset() by Mercij.
+ */
+unsigned long calibrate_div32_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long quotient;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (last_jiffies != tmp) {
+		last_jiffies = tmp;
+		if (last_jiffies != 0) {
+			unsigned long r0;
+			do_div64_32(r0, timerhi, timerlo, tmp);
+			do_div64_32(quotient, USECS_PER_JIFFY,
+			            USECS_PER_JIFFY_FRAC, r0);
+			cached_quotient = quotient;
+		}
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu  %2,%3"
+	        : "=l" (tmp), "=h" (res)
+	        : "r" (count), "r" (quotient));
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY - 1;
+
+	return res;
+}
+
+unsigned long calibrate_div64_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long quotient;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (tmp && last_jiffies != tmp) {
+		last_jiffies = tmp;
+		__asm__(".set\tnoreorder\n\t"
+	        ".set\tnoat\n\t"
+	        ".set\tmips3\n\t"
+	        "lwu\t%0,%2\n\t"
+	        "dsll32\t$1,%1,0\n\t"
+	        "or\t$1,$1,%0\n\t"
+	        "ddivu\t$0,$1,%3\n\t"
+	        "mflo\t$1\n\t"
+	        "dsll32\t%0,%4,0\n\t"
+	        "nop\n\t"
+	        "ddivu\t$0,%0,$1\n\t"
+	        "mflo\t%0\n\t"
+	        ".set\tmips0\n\t"
+	        ".set\tat\n\t"
+	        ".set\treorder"
+	        :"=&r" (quotient)
+	        :"r" (timerhi),
+	         "m" (timerlo),
+	         "r" (tmp),
+	         "r" (USECS_PER_JIFFY));
+	        cached_quotient = quotient;
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+	        "mfhi\t%0"
+	        :"=r" (res)
+	        :"r" (count),
+	         "r" (quotient));
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
+}
+
+
+/*
+ * local_timer_interrupt() does profiling and process accounting
+ * on a per-CPU basis.  
+ *
+ * In UP mode, it is invoked from the (global) timer_interrupt.  
+ *
+ * In SMP mode, it might invoked by per-CPU timer interrupt, or
+ * a broadcasted inter-processor interrupt which itself is triggered
+ * by the global timer interrupt.
+ */
+void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if(!user_mode(regs)) {
+		if (prof_buffer && current->pid) {
+			extern int _stext;
+			unsigned long pc = regs->cp0_epc;
+
+			pc -= (unsigned long) &_stext;
+			pc >>= prof_shift;
+			/*
+			 * Dont ignore out-of-bounds pc values silently,
+			 * put them into the last histogram slot, so if
+			 * present, they will show up as a sharp peak.
+			 */
+			if (pc > prof_len-1)
+			pc = prof_len-1;
+			atomic_inc((atomic_t *)&prof_buffer[pc]);
+		}
+	}
+
+#if defined(CONFIG_SMP)
+	/* in UP mode, update_process_times() is invoked by do_timer() */
+	update_process_times(user_mode(regs));
+#endif
+}
+
+/*
+ * high-level timer interrupt service routines.  This function
+ * is set as irqaction->handler and is invoked through do_IRQ.
+ */
+void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (mips_cpu.options & MIPS_CPU_COUNTER) {
+		unsigned int count;
+
+		/*
+		 * The cycle counter is only 32 bit which is good for about
+		 * a minute at current count rates of upto 150MHz or so.
+		 */
+		count = read_32bit_cp0_register(CP0_COUNT);
+		timerhi += (count < timerlo);   /* Wrap around */
+		timerlo = count;
+
+		/*
+		 * set up for next timer interrupt - no harm if the machine
+		 * is using another timer interrupt source.
+		 * Note that writing to COMPARE register clears the interrupt
+		 */
+		write_32bit_cp0_register (CP0_COMPARE,
+					  count + cycles_per_jiffy);
+
+	}
+
+	/*
+	 * call the generic timer interrupt handling
+	 */
+	do_timer(regs);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	read_lock (&xtime_lock);
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+		if (rtc_set_time(xtime.tv_sec) == 0) {
+			last_rtc_update = xtime.tv_sec;
+		} else {
+			last_rtc_update = xtime.tv_sec - 600; 
+			/* do it again in 60 s */
+		}
+	}
+	read_unlock (&xtime_lock);
+
+	/*
+	 * If jiffies has overflowed in this timer_interrupt we must
+	 * update the timer[hi]/[lo] to make fast gettimeoffset funcs
+	 * quotient calc still valid. -arca
+	 */
+	if (!jiffies) {
+		timerhi = timerlo = 0;
+	}
+
+#if !defined(CONFIG_SMP)
+	/* 
+	 * In UP mode, we call local_timer_interrupt() to do profiling
+	 * and process accouting.  
+	 *
+	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
+	 * low-level local timer interrupt handler.
+	 */
+	local_timer_interrupt(0, NULL, regs);
+
+#else	/* CONFIG_SMP */
+
+	if (emulate_local_timer_interrupt) {
+		/* 
+		 * this is the place where we send out inter-process
+		 * interrupts and let each CPU do its own profiling
+		 * and process accouting.
+		 *
+		 * Obviously we need to call local_timer_interrupt() for
+		 * the current CPU too.
+		 */
+		panic("Not implemented yet!!!");
+	}
+#endif	/* CONFIG_SMP */
+}
+
+asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+
+	/* we keep interrupt disabled all the time */
+	timer_interrupt(irq, NULL, regs);
+	
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+}
+
+asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+
+	/* we keep interrupt disabled all the time */
+	local_timer_interrupt(irq, NULL, regs);
+	
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+}
+
+/*
+ * time_init() - it does the following things.
+ *
+ * 1) board_time_init() - 
+ * 	a) (optional) set up RTC routines, 
+ *      b) (optional) calibrate and set the mips_counter_frequency
+ *	    (only needed if you intended to use fixed_rate_gettimeoffset
+ *	     or use cpu counter as timer interrupt source)
+ * 2) setup xtime based on rtc_get_time().
+ * 3) choose a appropriate gettimeoffset routine.
+ * 4) calculate a couple of cached variables for later usage
+ * 5) board_timer_setup() - 
+ *	a) (optional) over-write any choices made above by time_init().
+ *	b) machine specific code should setup the timer irqaction.
+ *	c) enable the timer interrupt
+ */ 
+
+void (*board_time_init)(void) = NULL;
+void (*board_timer_setup)(struct irqaction *irq) = NULL;
+
+unsigned int mips_counter_frequency = 0;
+
+static struct irqaction timer_irqaction = {
+	timer_interrupt,
+	SA_INTERRUPT,
+	0,
+	"timer",
+	NULL,
+	NULL};
+
+void __init time_init(void)
+{
+	if (board_time_init)
+		board_time_init();
+
+	xtime.tv_sec = rtc_get_time();
+	xtime.tv_usec = 0;
+
+	/* choose appropriate gettimeoffset routine */
+	if (!(mips_cpu.options & MIPS_CPU_COUNTER)) {
+		/* no cpu counter - sorry */
+		do_gettimeoffset = null_gettimeoffset;
+	} else if (mips_counter_frequency != 0) {
+		/* we have cpu counter and know counter frequency! */
+		do_gettimeoffset = fixed_rate_gettimeoffset;
+	} else if ((mips_cpu.isa_level == MIPS_CPU_ISA_M32) ||
+		   (mips_cpu.isa_level == MIPS_CPU_ISA_I) ||
+		   (mips_cpu.isa_level == MIPS_CPU_ISA_II) ) {
+		/* we need to calibrate the counter but we don't have
+		 * 64-bit division. */
+		do_gettimeoffset = calibrate_div32_gettimeoffset;
+	} else {
+		/* we need to calibrate the counter but we *do* have
+		 * 64-bit division. */
+		do_gettimeoffset = calibrate_div64_gettimeoffset;
+	}	
+
+	/* caclulate cache parameters */
+	if (mips_counter_frequency) {
+		cycles_per_jiffy = mips_counter_frequency / HZ;
+
+		/* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */
+		/* any better way to do this? */
+		sll32_usecs_per_cycle = mips_counter_frequency / 100000;
+		sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle;
+		sll32_usecs_per_cycle *= 10;
+	}
+
+	/* 
+	 * Call board specific timer interrupt setup.
+	 *
+	 * this pointer must be setup in machine setup routine. 
+	 *
+	 * Even if the machine choose to use low-level timer interrupt,
+	 * it still needs to setup the timer_irqaction.
+	 * In that case, it might be better to set timer_irqaction.handler 
+	 * to be NULL function so that we are sure the high-level code
+	 * is not invoked accidentally.
+	 */
+	board_timer_setup(&timer_irqaction);
+}
+
+#define FEBRUARY		2
+#define STARTOFTIME		1970
+#define SECDAY			86400L
+#define SECYR			(SECDAY * 365)
+#define leapyear(year)		((year) % 4 == 0)
+#define days_in_year(a)		(leapyear(a) ? 366 : 365)
+#define days_in_month(a)	(month_days[(a) - 1])
+
+static int month_days[12] = {
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+void to_tm(unsigned long tim, struct rtc_time * tm)
+{
+	long hms, day, gday;
+	int i;
+
+	gday = day = tim / SECDAY;
+	hms = tim % SECDAY;
+
+	/* Hours, minutes, seconds are easy */
+	tm->tm_hour = hms / 3600;
+	tm->tm_min = (hms % 3600) / 60;
+	tm->tm_sec = (hms % 3600) % 60;
+
+	/* Number of years in days */
+	for (i = STARTOFTIME; day >= days_in_year(i); i++)
+	day -= days_in_year(i);
+	tm->tm_year = i;
+
+	/* Number of months in days left */
+	if (leapyear(tm->tm_year))
+	days_in_month(FEBRUARY) = 29;
+	for (i = 1; day >= days_in_month(i); i++)
+	day -= days_in_month(i);
+	days_in_month(FEBRUARY) = 28;
+	tm->tm_mon = i-1;	/* tm_mon starts from 0 to 11 */
+
+	/* Days are what is left over (+1) from all that. */
+	tm->tm_mday = day + 1;
+
+	/*
+	 * Determine the day of week
+	 */
+	tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/traps.c linux/arch/mips64/kernel/traps.c
--- linux.orig/arch/mips64/kernel/traps.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/traps.c	2002-07-20 01:08:38.000000000 +0000
@@ -7,25 +7,30 @@
  * Copyright (C) 1995, 1996 Paul M. Antoine
  * Copyright (C) 1998 Ulf Carlsson
  * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 
+#include <asm/bootinfo.h>
 #include <asm/branch.h>
-#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/module.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/bootinfo.h>
 #include <asm/ptrace.h>
 #include <asm/watch.h>
 #include <asm/system.h>
+#include <asm/traps.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
+#include <asm/cachectl.h>
 
 extern asmlinkage void __xtlb_mod(void);
 extern asmlinkage void __xtlb_tlbl(void);
@@ -42,14 +47,16 @@
 extern asmlinkage void handle_tr(void);
 extern asmlinkage void handle_fpe(void);
 extern asmlinkage void handle_watch(void);
+extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
-static char *cpu_names[] = CPU_NAMES;
+extern int fpu_emulator_cop1Handler(struct pt_regs *);
+void fpu_emulator_init_fpu(void);
 
 char watch_available = 0;
 char dedicated_iv_available = 0;
-char vce_available = 0;
-char mips4_available = 0;
+
+int (*be_board_handler)(struct pt_regs *regs, int is_fixup);
 
 int kstack_depth_to_print = 24;
 
@@ -110,7 +117,7 @@
 
 	printk("\nCall Trace:");
 
-	while ((unsigned long) stack & (PAGE_SIZE -1)) {
+	while ((unsigned long) stack & (PAGE_SIZE - 1)) {
 		unsigned long addr;
 
 		if (__get_user(addr, stack++)) {
@@ -143,6 +150,12 @@
 	}
 }
 
+void show_trace_task(struct task_struct *tsk)
+{
+	show_trace((unsigned long *)tsk->thread.reg29);
+}
+
+
 void show_code(unsigned int *pc)
 {
 	long i;
@@ -159,16 +172,60 @@
 	}
 }
 
-spinlock_t die_lock;
+void show_regs(struct pt_regs *regs)
+{
+	printk("Cpu %d\n", smp_processor_id());
+	/* Saved main processor registers. */
+	printk("$0      : %016lx %016lx %016lx %016lx\n",
+	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+	printk("$4      : %016lx %016lx %016lx %016lx\n",
+               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk("$8      : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+	printk("$12     : %016lx %016lx %016lx %016lx\n",
+               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk("$16     : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+	printk("$20     : %016lx %016lx %016lx %016lx\n",
+               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk("$24     : %016lx %016lx\n",
+	       regs->regs[24], regs->regs[25]);
+	printk("$28     : %016lx %016lx %016lx %016lx\n",
+	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+	printk("Hi      : %016lx\n", regs->hi);
+	printk("Lo      : %016lx\n", regs->lo);
+
+	/* Saved cp0 registers. */
+	printk("epc     : %016lx    %s\nbadvaddr: %016lx\n",
+	       regs->cp0_epc, print_tainted(), regs->cp0_badvaddr);
+	printk("Status  : %08x  [ ", (unsigned int) regs->cp0_status);
+	if (regs->cp0_status & ST0_KX) printk("KX ");
+	if (regs->cp0_status & ST0_SX) printk("SX ");
+	if (regs->cp0_status & ST0_UX) printk("UX ");
+	switch (regs->cp0_status & ST0_KSU) {
+		case KSU_USER: printk("USER ");			break;
+		case KSU_SUPERVISOR: printk("SUPERVISOR ");	break;
+		case KSU_KERNEL: printk("KERNEL ");		break;
+		default: printk("BAD_MODE ");			break;
+	}
+	if (regs->cp0_status & ST0_ERL) printk("ERL ");
+	if (regs->cp0_status & ST0_EXL) printk("EXL ");
+	if (regs->cp0_status & ST0_IE) printk("IE ");
+	printk("]\n");
+
+	printk("Cause   : %08x\n", (unsigned int) regs->cp0_cause);
+}
+
+static spinlock_t die_lock;
 
-void die(const char * str, struct pt_regs * regs, unsigned long err)
+void die(const char * str, struct pt_regs * regs)
 {
 	if (user_mode(regs))	/* Just return if in user mode.  */
 		return;
 
 	console_verbose();
 	spin_lock_irq(&die_lock);
-	printk("%s: %04lx\n", str, err & 0xffff);
+	printk("%s\n", str);
 	show_regs(regs);
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, (unsigned long) current);
@@ -180,82 +237,178 @@
 	do_exit(SIGSEGV);
 }
 
-void die_if_kernel(const char * str, struct pt_regs * regs, unsigned long err)
+void die_if_kernel(const char * str, struct pt_regs * regs)
 {
 	if (!user_mode(regs))
-		die(str, regs, err);
+		die(str, regs);
 }
 
-void do_ov(struct pt_regs *regs)
+extern const struct exception_table_entry __start___dbe_table[];
+extern const struct exception_table_entry __stop___dbe_table[];
+
+void __declare_dbe_table(void)
 {
-	if (compute_return_epc(regs))
-		return;
-	force_sig(SIGFPE, current);
+	__asm__ __volatile__(
+	".section\t__dbe_table,\"a\"\n\t"
+	".previous"
+	);
 }
 
-#ifdef CONFIG_MIPS_FPE_MODULE
-static void (*fpe_handler)(struct pt_regs *regs, unsigned int fcr31);
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+		 const struct exception_table_entry *last,
+		 unsigned long value)
+{
+	const struct exception_table_entry *mid;
+	long diff;
 
-/*
- * Register_fpe/unregister_fpe are for debugging purposes only.  To make
- * this hack work a bit better there is no error checking.
- */
-int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31))
+	while (first < last) {
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+		if (diff < 0)
+			first = mid + 1;
+		else
+			last = mid;
+	}
+	return (first == last && first->insn == value) ? first->nextinsn : 0;
+}
+
+extern spinlock_t modlist_lock;
+
+static inline unsigned long
+search_dbe_table(unsigned long addr)
 {
-	fpe_handler = handler;
-	return 0;
+	unsigned long ret = 0;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_end) ||
+        	    !mod_archdata_member_present(mp, struct archdata,
+						 dbe_table_end))
+			continue;
+		ap = (struct archdata *)(mp->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
 }
 
-int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31))
+asmlinkage void do_be(struct pt_regs *regs)
 {
-	fpe_handler = NULL;
-	return 0;
+	unsigned long new_epc;
+	unsigned long fixup = 0;
+	int data = regs->cp0_cause & 4;
+	int action = MIPS_BE_FATAL;
+
+	if (data && !user_mode(regs))
+		fixup = search_dbe_table(regs->cp0_epc);
+
+	if (fixup)
+		action = MIPS_BE_FIXUP;
+
+	if (be_board_handler)
+		action = be_board_handler(regs, fixup != 0);
+
+	switch (action) {
+	case MIPS_BE_DISCARD:
+		return;
+	case MIPS_BE_FIXUP:
+		if (fixup) {
+			new_epc = fixup_exception(dpf_reg, fixup,
+						  regs->cp0_epc);
+			regs->cp0_epc = new_epc;
+			return;
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*
+	 * Assume it would be too dangerous to continue ...
+	 */
+	printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
+	       data ? "Data" : "Instruction",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
+	force_sig(SIGBUS, current);
+}
+
+void do_ov(struct pt_regs *regs)
+{
+	if (compute_return_epc(regs))
+		return;
+	force_sig(SIGFPE, current);
 }
-#endif
 
 /*
  * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
  */
-void do_fpe(struct pt_regs *regs, unsigned long fcr31)
+asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
-	unsigned long pc;
-	unsigned int insn;
-	extern void simfp(unsigned int);
-
-#ifdef CONFIG_MIPS_FPE_MODULE
-	if (fpe_handler != NULL) {
-		fpe_handler(regs, fcr31);
-		return;
-	}
-#endif
-	if (fcr31 & 0x20000) {
-		/* Retry instruction with flush to zero ...  */
-		if (!(fcr31 & (1<<24))) {
-			printk("Setting flush to zero for %s.\n",
-			       current->comm);
-			fcr31 &= ~0x20000;
-			fcr31 |= (1<<24);
-			__asm__ __volatile__(
-				"ctc1\t%0,$31"
-				: /* No outputs */
-				: "r" (fcr31));
-			return;
-		}
-		pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
-		if (get_user(insn, (unsigned int *)pc)) {
-			/* XXX Can this happen?  */
-			force_sig(SIGSEGV, current);
+	if (fcr31 & FPU_CSR_UNI_X) {
+		int sig;
+
+		/*
+	 	 * Unimplemented operation exception.  If we've got the full
+		 * software emulator on-board, let's use it...
+		 *
+		 * Force FPU to dump state into task/thread context.  We're
+		 * moving a lot of data here for what is probably a single
+		 * instruction, but the alternative is to pre-decode the FP
+		 * register operands before invoking the emulator, which seems
+		 * a bit extreme for what should be an infrequent event.
+		 */
+		save_fp(current);
+
+		/* Run the emulator */
+		sig = fpu_emulator_cop1Handler(regs);
+
+		/* 
+		 * We can't allow the emulated instruction to leave any of 
+		 * the cause bit set in $fcr31.
+		 */
+		current->thread.fpu.soft.sr &= ~FPU_CSR_ALL_X;
+
+		/* Restore the hardware register state */
+		restore_fp(current);
+
+		/* If something went wrong, signal */
+		if (sig)
+		{
+			/* 
+			 * Return EPC is not calculated in the FPU emulator, 
+			 * if a signal is being send. So we calculate it here.
+			 */
+			compute_return_epc(regs);
+			force_sig(sig, current);
 		}
 
-		printk(KERN_DEBUG "Unimplemented exception for insn %08x at 0x%08lx in %s.\n",
-		       insn, regs->cp0_epc, current->comm);
-		simfp(insn);
+		return;
 	}
 
 	if (compute_return_epc(regs))
 		return;
-	//force_sig(SIGFPE, current);
-	printk(KERN_DEBUG "Should send SIGFPE to %s\n", current->comm);
+	force_sig(SIGFPE, current);
 }
 
 void do_bp(struct pt_regs *regs)
@@ -291,7 +444,7 @@
 			info.si_code = FPE_INTOVF;
 		info.si_signo = SIGFPE;
 		info.si_errno = 0;
-		info.si_addr = (void *)compute_return_epc(regs);
+		info.si_addr = (void *)regs->cp0_epc;
 		force_sig_info(SIGFPE, &info, current);
 		break;
 	default:
@@ -333,7 +486,7 @@
 			info.si_code = FPE_INTOVF;
 		info.si_signo = SIGFPE;
 		info.si_errno = 0;
-		info.si_addr = (void *)compute_return_epc(regs);
+		info.si_addr = (void *)regs->cp0_epc;
 		force_sig_info(SIGFPE, &info, current);
 		break;
 	default:
@@ -347,24 +500,35 @@
 
 void do_ri(struct pt_regs *regs)
 {
-	printk("Cpu%d[%s:%d] Illegal instruction at %08lx ra=%08lx\n",
-	        smp_processor_id(), current->comm, current->pid, regs->cp0_epc, 
-		regs->regs[31]);
 	if (compute_return_epc(regs))
 		return;
+
 	force_sig(SIGILL, current);
 }
 
 void do_cpu(struct pt_regs *regs)
 {
 	u32 cpid;
+	int sig;
 
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
 	if (cpid != 1)
 		goto bad_cid;
 
+	if (!(mips_cpu.options & MIPS_CPU_FPU))
+		goto fp_emul;
+
 	regs->cp0_status |= ST0_CU1;
-#ifndef CONFIG_SMP
+
+#ifdef CONFIG_SMP
+	if (current->used_math) {
+		lazy_fpu_switch(0, current);
+	} else {
+		init_fpu();
+		current->used_math = 1;
+	}
+	current->flags |= PF_USEDFPU;
+#else
 	if (last_task_used_math == current)
 		return;
 
@@ -376,18 +540,28 @@
 		current->used_math = 1;
 	}
 	last_task_used_math = current;
-#else
-	if (current->used_math) {
-		lazy_fpu_switch(0, current);
-	} else {
-		init_fpu();
+#endif
+	return;
+
+fp_emul:
+	if (!current->used_math) {
+		fpu_emulator_init_fpu();
 		current->used_math = 1;
 	}
-	current->flags |= PF_USEDFPU;
-#endif
+	sig = fpu_emulator_cop1Handler(regs);
+	if (sig)
+	{
+		/* 
+		 * Return EPC is not calculated in the FPU emulator, if 
+		 * a signal is being send. So we calculate it here.
+		 */
+		compute_return_epc(regs);
+		force_sig(sig, current);
+	}
 	return;
 
 bad_cid:
+	compute_return_epc(regs);
 	force_sig(SIGILL, current);
 }
 
@@ -401,6 +575,13 @@
 	panic("Caught WATCH exception - probably caused by stack overflow.");
 }
 
+asmlinkage void do_mcheck(struct pt_regs *regs)
+{
+	show_regs(regs);
+	panic("Caught Machine Check exception - probably caused by multiple "
+	      "matching entries in the TLB.");
+}
+
 void do_reserved(struct pt_regs *regs)
 {
 	/*
@@ -430,23 +611,6 @@
 	}
 }
 
-/*
- * Some MIPS CPUs have a dedicated interrupt vector which reduces the
- * interrupt processing overhead.  Use it where available.
- * FIXME: more CPUs than just the Nevada have this feature.
- */
-static inline void setup_dedicated_int(void)
-{
-	extern void except_vec4(void);
-
-	switch(mips_cputype) {
-	case CPU_NEVADA:
-		memcpy((void *)(KSEG0 + 0x200), except_vec4, 8);
-		set_cp0_cause(CAUSEF_IV, CAUSEF_IV);
-		dedicated_iv_available = 1;
-	}
-}
-
 unsigned long exception_handlers[32];
 
 /*
@@ -458,33 +622,32 @@
 {
 	unsigned long handler = (unsigned long) addr;
 	exception_handlers[n] = handler;
-	if (n == 0 && dedicated_iv_available) {
+
+	if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) {
 		*(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
 		                                 (0x03ffffff & (handler >> 2));
 		flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
 	}
 }
 
-static inline void mips4_setup(void)
+void __init per_cpu_trap_init(void)
 {
-	switch (mips_cputype) {
-	case CPU_R5000:
-	case CPU_R5000A:
-	case CPU_NEVADA:
-	case CPU_R8000:
-	case CPU_R10000:
-		mips4_available = 1;
-		set_cp0_status(ST0_XX, ST0_XX);
-	}
-}
+	unsigned int cpu = smp_processor_id();
 
-static inline void go_64(void)
-{
-	unsigned int bits;
+	/* Some firmware leaves the BEV flag set, clear it.  */
+	clear_cp0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV);
+	set_cp0_status(ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX);
+
+	/*
+	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+	 * interrupt processing overhead.  Use it where available.
+	 */
+	if (mips_cpu.options & MIPS_CPU_DIVEC)
+		set_cp0_cause(CAUSEF_IV);
 
-	bits = ST0_KX|ST0_SX|ST0_UX;
-	set_cp0_status(bits, bits);
-	printk("Entering 64-bit mode.\n");
+	cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
+	set_context(((long)(&pgd_current[cpu])) << 23);
+	set_wired(0);
 }
 
 void __init trap_init(void)
@@ -493,13 +656,13 @@
 	extern char except_vec1_r10k;
 	extern char except_vec2_generic;
 	extern char except_vec3_generic, except_vec3_r4000;
-	extern void bus_error_init(void);
+	extern char except_vec4;
 	unsigned long i;
+	int dummy;
 
-	/* Some firmware leaves the BEV flag set, clear it.  */
-	set_cp0_status(ST0_BEV, 0);
+	per_cpu_trap_init();
 
-	/* Copy the generic exception handler code to it's final destination. */
+	/* Copy the generic exception handlers to their final destination. */
 	memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
 	memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
 
@@ -513,30 +676,47 @@
 	 * Only some CPUs have the watch exceptions or a dedicated
 	 * interrupt vector.
 	 */
-	watch_init(mips_cputype);
-	setup_dedicated_int();
-	mips4_setup();
-	go_64();		/* In memoriam C128 ;-)  */
+	watch_init(mips_cpu.cputype);
+
+	/*
+	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+	 * interrupt processing overhead.  Use it where available.
+	 */
+	memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8);
+
+	if (mips_cpu.options & MIPS_CPU_MCHECK)
+		set_except_vector(24, handle_mcheck);
+
+	/*
+	 * The Data Bus Errors / Instruction Bus Errors are signaled
+	 * by external hardware.  Therefore these two exceptions
+	 * may have board specific handlers.
+	 */
+	bus_error_init();
 
 	/*
 	 * Handling the following exceptions depends mostly of the cpu type
 	 */
-	switch(mips_cputype) {
-	case CPU_R10000:
-		/*
-		 * The R10000 is in most aspects similar to the R4400.  It
-		 * should get some special optimizations.
-		 */
-		write_32bit_cp0_register(CP0_FRAMEMASK, 0);
-		set_cp0_status(ST0_XX, ST0_XX);
-		goto r4k;
+	switch(mips_cpu.cputype) {
+        case CPU_SB1:
+#ifdef CONFIG_SB1_CACHE_ERROR
+		{
+		/* Special cache error handler for SB1 */
+		extern char except_vec2_sb1;
+		memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80);
+		memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80);
+		}
+#endif
+		/* Enable timer interrupt and scd mapped interrupt */
+		clear_cp0_status(0xf000);
+		set_cp0_status(0xc00);
 
+		/* Fall through. */
+	case CPU_R10000:
 	case CPU_R4000MC:
 	case CPU_R4400MC:
 	case CPU_R4000SC:
 	case CPU_R4400SC:
-		vce_available = 1;
-		/* Fall through ...  */
 	case CPU_R4000PC:
 	case CPU_R4400PC:
 	case CPU_R4200:
@@ -544,20 +724,16 @@
 	case CPU_R4600:
 	case CPU_R5000:
 	case CPU_NEVADA:
-r4k:
 		/* Debug TLB refill handler.  */
 		memcpy((void *)KSEG0, &except_vec0, 0x80);
 		memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
 
-		/* Cache error vector  */
-		memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
-
-		if (vce_available) {
+		if (mips_cpu.options & MIPS_CPU_VCE) {
 			memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
-			       0x180);
+			       0x80);
 		} else {
 			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
-			       0x100);
+			       0x80);
 		}
 
 		set_except_vector(1, __xtlb_mod);
@@ -566,8 +742,8 @@
 		set_except_vector(4, handle_adel);
 		set_except_vector(5, handle_ades);
 
-		/* DBE / IBE exception handler are system specific.  */
-		bus_error_init();
+		set_except_vector(6, handle_ibe);
+		set_except_vector(7, handle_dbe);
 
 		set_except_vector(8, handle_sys);
 		set_except_vector(9, handle_bp);
@@ -579,7 +755,7 @@
 		break;
 
 	case CPU_R8000:
-		panic("unsupported CPU type %s.\n", cpu_names[mips_cputype]);
+		panic("R8000 is unsupported");
 		break;
 
 	case CPU_UNKNOWN:
@@ -588,6 +764,9 @@
 	}
 	flush_icache_range(KSEG0, KSEG0 + 0x200);
 
+	if (mips_cpu.isa_level == MIPS_CPU_ISA_IV)
+		set_cp0_status(ST0_XX);
+
 	atomic_inc(&init_mm.mm_count);	/* XXX UP?  */
 	current->active_mm = &init_mm;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/kernel/unaligned.c linux/arch/mips64/kernel/unaligned.c
--- linux.orig/arch/mips64/kernel/unaligned.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/kernel/unaligned.c	2002-07-20 01:08:29.000000000 +0000
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1996, 1998, 1999, 2002 by Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  *
  * This file contains exception handler for address error exception with the
@@ -96,10 +96,8 @@
 	if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0)	\
 		goto sigbus;
 
-static inline void
-emulate_load_store_insn(struct pt_regs *regs,
-                        unsigned long addr,
-                        unsigned long pc)
+static inline int emulate_load_store_insn(struct pt_regs *regs,
+	unsigned long addr, unsigned long pc)
 {
 	union mips_instruction insn;
 	unsigned long value, fixup;
@@ -163,10 +161,9 @@
 			STR(PTR)"\t2b,%2\n\t"
 			".previous"
 			:"=&r" (value)
-			:"r" (addr), "i" (&&fault)
-			:"$1");
+			:"r" (addr), "i" (&&fault));
 		regs->regs[insn.i_format.rt] = value;
-		return;
+		return 0;
 
 	case lw_op:
 		check_axs(pc, addr, 4);
@@ -186,7 +183,7 @@
 			:"=&r" (value)
 			:"r" (addr), "i" (&&fault));
 			regs->regs[insn.i_format.rt] = value;
-			return;
+			return 0;
 
 	case lhu_op:
 		check_axs(pc, addr, 2);
@@ -208,10 +205,9 @@
 			STR(PTR)"\t2b,%2\n\t"
 			".previous"
 			:"=&r" (value)
-			:"r" (addr), "i" (&&fault)
-			:"$1");
+			:"r" (addr), "i" (&&fault));
 		regs->regs[insn.i_format.rt] = value;
-		return;
+		return 0;
 
 	case lwu_op:
 		check_axs(pc, addr, 4);
@@ -232,7 +228,7 @@
 			:"r" (addr), "i" (&&fault));
 		value &= 0xffffffff;
 		regs->regs[insn.i_format.rt] = value;
-		return;
+		return 0;
 
 	case ld_op:
 		check_axs(pc, addr, 8);
@@ -254,7 +250,7 @@
 			:"=&r" (value)
 			:"r" (addr), "i" (&&fault));
 		regs->regs[insn.i_format.rt] = value;
-		return;
+		return 0;
 
 	case sh_op:
 		check_axs(pc, addr, 2);
@@ -279,9 +275,8 @@
 			STR(PTR)"\t2b,%2\n\t"
 			".previous"
 			: /* no outputs */
-			:"r" (value), "r" (addr), "i" (&&fault)
-			:"$1");
-		return;
+			:"r" (value), "r" (addr), "i" (&&fault));
+		return 0;
 
 	case sw_op:
 		check_axs(pc, addr, 4);
@@ -301,7 +296,7 @@
 			".previous"
 			: /* no outputs */
 			:"r" (value), "r" (addr), "i" (&&fault));
-		return;
+		return 0;
 
 	case sd_op:
 		check_axs(pc, addr, 8);
@@ -323,7 +318,7 @@
 			".previous"
 			: /* no outputs */
 			:"r" (value), "r" (addr), "i" (&&fault));
-		return;
+		return 0;
 
 	case lwc1_op:
 	case ldc1_op:
@@ -352,31 +347,31 @@
 		 */
 		goto sigill;
 	}
-	return;
+	return 0;
 
 fault:
 	/* Did we have an exception handler installed? */
-	fixup = search_exception_table(regs->cp0_epc);
+	fixup = search_exception_table(exception_epc(regs));
 	if (fixup) {
 		long new_epc;
 		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
 		printk(KERN_DEBUG "%s: Forwarding exception at [<%lx>] (%lx)\n",
 		       current->comm, regs->cp0_epc, new_epc);
 		regs->cp0_epc = new_epc;
-		return;
+		return 1;
 	}
 
 	die_if_kernel ("Unhandled kernel unaligned access", regs);
 	send_sig(SIGSEGV, current, 1);
-	return;
+	return 0;
 sigbus:
 	die_if_kernel ("Unhandled kernel unaligned access", regs);
 	send_sig(SIGBUS, current, 1);
-	return;
+	return 0;
 sigill:
 	die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs);
 	send_sig(SIGILL, current, 1);
-	return;
+	return 0;
 }
 
 #ifdef CONFIG_PROC_FS
@@ -386,6 +381,24 @@
 asmlinkage void do_ade(struct pt_regs *regs)
 {
 	unsigned long pc;
+	extern int do_dsemulret(struct pt_regs *);
+
+#if 0
+        printk("ade: Cpu%d[%s:%d:%0lx:%0lx]\n", smp_processor_id(),
+                current->comm, current->pid, regs->cp0_badvaddr, regs->cp0_epc);
+#endif
+
+	/*
+	 * Address errors may be deliberately induced
+	 * by the FPU emulator to take retake control
+	 * of the CPU after executing the instruction
+	 * in the delay slot of an emulated branch.
+	 */
+	/* Terminate if exception was recognized as a delay slot return */
+	if (do_dsemulret(regs))
+		return;
+
+        /* Otherwise handle as normal */
 
 	/*
 	 * Did we catch a fault trying to load an instruction?
@@ -396,12 +409,16 @@
 		goto sigbus;
 
 	pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
-	if (compute_return_epc(regs))
-		return;
 	if ((current->thread.mflags & MF_FIXADE) == 0)
 		goto sigbus;
 
-	emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
+	/*
+	 * Do branch emulation only if we didn't forward the exception.
+	 * This is all so but ugly ...
+	 */
+	if (!emulate_load_store_insn(regs, regs->cp0_badvaddr, pc))
+		compute_return_epc(regs);
+
 #ifdef CONFIG_PROC_FS
 	unaligned_instructions++;
 #endif
@@ -409,6 +426,6 @@
 	return;
 
 sigbus:
-	die_if_kernel ("Kernel unaligned instruction access", regs);
+	die_if_kernel("Kernel unaligned instruction access", regs);
 	force_sig(SIGBUS, current);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/ld.script.elf32.S linux/arch/mips64/ld.script.elf32.S
--- linux.orig/arch/mips64/ld.script.elf32.S	2001-07-02 21:40:58.000000000 +0000
+++ linux/arch/mips64/ld.script.elf32.S	2002-07-20 01:08:35.000000000 +0000
@@ -6,6 +6,7 @@
   .init          : { *(.init)		} =0
   .text      :
   {
+    _ftext = .;
     *(.text)
     *(.rodata)
     *(.rodata.*)
@@ -24,6 +25,10 @@
   __dbe_table : { *(__dbe_table) }
   __stop___dbe_table = .;
 
+  __start___ksymtab = .;	/* Kernel symbol table */
+  __ksymtab : { *(__ksymtab) }
+  __stop___ksymtab = .;
+
   _etext = .;
 
   . = ALIGN(16384);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/ld.script.elf64 linux/arch/mips64/ld.script.elf64
--- linux.orig/arch/mips64/ld.script.elf64	2001-07-02 21:40:58.000000000 +0000
+++ linux/arch/mips64/ld.script.elf64	2002-07-20 01:08:31.000000000 +0000
@@ -16,6 +16,7 @@
   /* . = 0xa800000000300000; */
   . = 0xffffffff80300000;
   .text : {
+    _ftext = .;
     *(.text)
     *(.rodata)
     *(.rodata.*)
@@ -34,6 +35,10 @@
   __dbe_table : { *(__dbe_table) }
   __stop___dbe_table = .;
 
+  __start___ksymtab = .;	/* Kernel symbol table */
+  __ksymtab : { *(__ksymtab) }
+  __stop___ksymtab = .;
+
   _etext = .;
 
   . = ALIGN(16384);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/lib/Makefile linux/arch/mips64/lib/Makefile
--- linux.orig/arch/mips64/lib/Makefile	2001-02-05 05:48:46.000000000 +0000
+++ linux/arch/mips64/lib/Makefile	2002-07-20 01:08:31.000000000 +0000
@@ -2,16 +2,16 @@
 # Makefile for MIPS-specific library files..
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 L_TARGET = lib.a
 
-obj-y	+= csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \
-	  floppy-no.o ide-std.o ide-no.o kbd-std.o kbd-no.o rtc-std.o \
+obj-y	+= csum_partial.o csum_partial_copy.o dump_tlb.o rtc-std.o \
 	  rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o \
 	  strnlen_user.o watch.o
 
+obj-$(CONFIG_BLK_DEV_FD)	+= floppy-no.o floppy-std.o
+obj-$(CONFIG_IDE)		+= ide-std.o ide-no.o
+obj-$(CONFIG_PC_KEYB)		+= kbd-std.o kbd-no.o
+
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/lib/dump_tlb.c linux/arch/mips64/lib/dump_tlb.c
--- linux.orig/arch/mips64/lib/dump_tlb.c	2001-09-09 17:43:01.000000000 +0000
+++ linux/arch/mips64/lib/dump_tlb.c	2002-07-20 01:08:39.000000000 +0000
@@ -11,14 +11,27 @@
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
+#include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-#define mips_tlb_entries 64
+static inline const char *msk2str(unsigned int mask)
+{
+	switch (mask) {
+	case PM_4K:	return "4kb";
+	case PM_16K:	return "16kb";
+	case PM_64K:	return "64kb";
+	case PM_256K:	return "256kb";
+	case PM_1M:	return "1Mb";
+	case PM_4M:	return "4Mb";
+	case PM_16M:	return "16Mb";
+	case PM_64M:	return "64Mb";
+	case PM_256M:	return "256Mb";
+	}
+}
 
-void
-dump_tlb(int first, int last)
+void dump_tlb(int first, int last)
 {
 	unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid;
 	unsigned int s_index, pagemask, c0, c1, i;
@@ -46,25 +59,24 @@
 			/*
 			 * Only print entries in use
 			 */
-			printk("Index: %2d pgmask=%08x ", i, pagemask);
+			printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
 
 			c0 = (entrylo0 >> 3) & 7;
 			c1 = (entrylo1 >> 3) & 7;
 
-			printk("va=%08lx asid=%02lx"
-			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]"
-			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]\n",
+			printk("va=%011lx asid=%02lx\n",
 			       (entryhi & ~0x1fffUL),
-			       entryhi & 0xff,
-			       entrylo0 & PAGE_MASK, c0,
+			       entryhi & 0xff);
+			printk("\t[pa=%011lx c=%d d=%d v=%d g=%ld] ",
+			       (entrylo0 << 6) & PAGE_MASK, c0,
 			       (entrylo0 & 4) ? 1 : 0,
 			       (entrylo0 & 2) ? 1 : 0,
-			       (entrylo0 & 1),
-			       entrylo1 & PAGE_MASK, c1,
+			       (entrylo0 & 1));
+			printk("[pa=%011lx c=%d d=%d v=%d g=%ld]\n",
+			       (entrylo1 << 6) & PAGE_MASK, c1,
 			       (entrylo1 & 4) ? 1 : 0,
 			       (entrylo1 & 2) ? 1 : 0,
 			       (entrylo1 & 1));
-			       
 		}
 	}
 	printk("\n");
@@ -73,14 +85,12 @@
 	set_index(s_index);
 }
 
-void
-dump_tlb_all(void)
+void dump_tlb_all(void)
 {
-	dump_tlb(0, mips_tlb_entries - 1);
+	dump_tlb(0, mips_cpu.tlbsize - 1);
 }
 
-void
-dump_tlb_wired(void)
+void dump_tlb_wired(void)
 {
 	int	wired;
 
@@ -95,8 +105,7 @@
 		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
 		".set\treorder");
 
-void
-dump_tlb_addr(unsigned long addr)
+void dump_tlb_addr(unsigned long addr)
 {
 	unsigned int flags, oldpid;
 	int index;
@@ -121,14 +130,12 @@
 	dump_tlb(index, index);
 }
 
-void
-dump_tlb_nonwired(void)
+void dump_tlb_nonwired(void)
 {
-	dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1);
+	dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_cpu.tlbsize - 1);
 }
 
-void
-dump_list_process(struct task_struct *t, void *address)
+void dump_list_process(struct task_struct *t, void *address)
 {
 	pgd_t	*page_dir, *pgd;
 	pmd_t	*pmd;
@@ -194,8 +201,7 @@
 {
 	int i;
 
-	for(i=0;i<8;i++)
-	{
+	for(i = 0; i < 8; i++) {
 		printk("*%08lx == %08lx, ",
 		       (unsigned long)p, (unsigned long)*p);
 		p++;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/lib/floppy-std.c linux/arch/mips64/lib/floppy-std.c
--- linux.orig/arch/mips64/lib/floppy-std.c	2000-07-10 05:18:16.000000000 +0000
+++ linux/arch/mips64/lib/floppy-std.c	2002-07-20 01:08:38.000000000 +0000
@@ -100,23 +100,9 @@
 	return 0x3f0;
 }
 
-/* Pure 2^n version of get_order */
-static int __get_order(unsigned long size)
-{
-	int order;
-
-	size = (size-1) >> (PAGE_SHIFT-1);
-	order = -1;
-	do {
-		size >>= 1;
-		order++;
-	} while (size);
-	return order;
-}
-
 static unsigned long std_fd_dma_mem_alloc(unsigned long size)
 {
-	int order = __get_order(size);
+	int order = get_order(size);
 	unsigned long mem;
 
 	mem = __get_dma_pages(GFP_KERNEL,order);
@@ -126,7 +112,7 @@
 
 static void std_fd_dma_mem_free(unsigned long addr, unsigned long size)
 {       
-	free_pages(addr, __get_order(size));	
+	free_pages(addr, get_order(size));	
 }
 
 static unsigned long std_fd_drive_type(unsigned long n)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/lib/strnlen_user.S linux/arch/mips64/lib/strnlen_user.S
--- linux.orig/arch/mips64/lib/strnlen_user.S	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/lib/strnlen_user.S	2002-07-20 01:08:32.000000000 +0000
@@ -27,7 +27,7 @@
 	and	v0, ta0
 	bltz	v0, fault
 
-EXPORT(__strnlen_user_nocheck_asm)
+FEXPORT(__strnlen_user_nocheck_asm)
 	move	v0, a0
 	daddu	a1, a0			# stop pointer
 1:	beq	v0, a1, 1f		# limit reached?
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/math-emu/cp1emu.c linux/arch/mips64/math-emu/cp1emu.c
--- linux.orig/arch/mips64/math-emu/cp1emu.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/math-emu/cp1emu.c	2002-07-20 01:08:24.000000000 +0000
@@ -29,7 +29,7 @@
  * Notes: 
  *  1) the IEEE754 library (-le) performs the actual arithmetic;
  *  2) if you know that you won't have an fpu, then you'll get much 
- *     better performance by compiling with -msoft-float!  */
+ *     better performance by compiling with -msoft-float!
  *
  *  Nov 7, 2000
  *  Massive changes to integrate with Linux kernel.
@@ -1780,7 +1780,7 @@
 		 * i.e. denormalised results, underflow, overflow etc, which
 		 * must be emulated in s/w.
 		 */
-#ifdef 1
+#if 1
 		/* r4000 or above use dedicate exception */
 		xcption(XCPTFPE, cop1Patcher);
 #else
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/atlas/Makefile linux/arch/mips64/mips-boards/atlas/Makefile
--- linux.orig/arch/mips64/mips-boards/atlas/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/atlas/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,42 +0,0 @@
-#
-# Carsten Langgaard, carstenl@mips.com
-# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-#
-# ########################################################################
-#
-# This program is free software; you can distribute it and/or modify it
-# under the terms of the GNU General Public License (Version 2) as
-# published by the Free Software Foundation.
-# 
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-# 
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-#
-# #######################################################################
-#
-# Makefile for the MIPS Atlas specific kernel interface routines
-# under Linux.
-#
-# 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).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-all: atlas.o
-
-O_TARGET := atlas.o
-
-obj-y   := atlas_int.o atlas_rtc.o atlas_setup.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/atlas/atlas_int.c linux/arch/mips64/mips-boards/atlas/atlas_int.c
--- linux.orig/arch/mips64/mips-boards/atlas/atlas_int.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/atlas/atlas_int.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,249 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Routines for generic manipulation of the interrupts found on the MIPS 
- * Atlas board.
- *
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-
-#include <asm/irq.h>
-#include <asm/mips-boards/atlas.h>
-#include <asm/mips-boards/atlasint.h>
-#ifdef CONFIG_REMOTE_DEBUG
-#include <asm/gdb-stub.h>
-#endif
-
-struct atlas_ictrl_regs *atlas_hw0_icregs
-	= (struct atlas_ictrl_regs *)ATLAS_ICTRL_REGS_BASE;
-
-extern asmlinkage void mipsIRQ(void);
-extern void do_IRQ(int irq, struct pt_regs *regs);
-
-unsigned long spurious_count = 0;
-irq_desc_t irq_desc[NR_IRQS];
-
-#if 0
-#define DEBUG_INT(x...) printk(x)
-#else
-#define DEBUG_INT(x...)
-#endif
-
-void disable_atlas_irq(unsigned int irq_nr)
-{
-	atlas_hw0_icregs->intrsten = (1 << irq_nr);
-}
-
-void enable_atlas_irq(unsigned int irq_nr)
-{
-	atlas_hw0_icregs->intseten = (1 << irq_nr);
-}
-
-static unsigned int startup_atlas_irq(unsigned int irq)
-{
-	enable_atlas_irq(irq);
-	return 0; /* never anything pending */
-}
-
-#define shutdown_atlas_irq	disable_atlas_irq
-
-#define mask_and_ack_atlas_irq disable_atlas_irq
-
-static void end_atlas_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_atlas_irq(irq);
-}
-
-static struct hw_interrupt_type atlas_irq_type = {
-	"Atlas",
-	startup_atlas_irq,
-	shutdown_atlas_irq,
-	enable_atlas_irq,
-	disable_atlas_irq,
-	mask_and_ack_atlas_irq,
-	end_atlas_irq,
-	NULL
-};
-
-int get_irq_list(char *buf)
-{
-	int i, len = 0;
-	int num = 0;
-	struct irqaction *action;
-
-	for (i = 0; i < ATLASINT_END; i++, num++) {
-		action = irq_desc[i].action;
-		if (!action) 
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
-			(action->flags & SA_INTERRUPT) ? '+' : ' ',
-			action->name);
-		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ",%s %s",
-				(action->flags & SA_INTERRUPT) ? " +" : "",
-				action->name);
-		}
-		len += sprintf(buf+len, " [hw0]\n");
-	}
-	return len;
-}
-
-int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
-{  
-        struct irqaction *action;
-
-	DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname);
-
-        if (irq >= ATLASINT_END)
-	        return -EINVAL;
-	if (!handler)
-	        return -EINVAL;
-
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if(!action)
-	        return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->mask = 0;
-	action->name = devname;
-	action->dev_id = dev_id;
-	action->next = 0;
-	irq_desc[irq].action = action;
-	enable_atlas_irq(irq);
-
-	return 0;
-}
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-	struct irqaction *action;
-
-	if (irq >= ATLASINT_END) {
-		printk("Trying to free IRQ%d\n",irq);
-		return;
-	}
-
-	action = irq_desc[irq].action;
-	irq_desc[irq].action = NULL;
-	disable_atlas_irq(irq);
-	kfree(action);
-}
-
-static inline int ls1bit32(unsigned int x)
-{
-	int b = 31, s;
-
-	s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
-	s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
-	s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
-	s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
-	s =  1; if (x <<  1 == 0) s = 0; b -= s;
-
-	return b;
-}
-
-void atlas_hw0_irqdispatch(struct pt_regs *regs)
-{
-	struct irqaction *action;
-	unsigned long int_status;
-	int irq, cpu = smp_processor_id();
-
-	int_status = atlas_hw0_icregs->intstatus; 
-
-	/* if int_status == 0, then the interrupt has already been cleared */
-	if (int_status == 0)
-		return;
-
-	irq = ls1bit32(int_status);
-	action = irq_desc[irq].action;
-
-	DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
-
-	/* if action == NULL, then we don't have a handler for the irq */
-	if ( action == NULL ) {
-	        printk("No handler for hw0 irq: %i\n", irq);
-		spurious_count++;
-		return;
-	}
-
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
-	action->handler(irq, action->dev_id, regs);
-	irq_exit(cpu, irq);
-
-	return;		
-}
-
-unsigned long probe_irq_on (void)
-{
-	return 0;
-}
-
-
-int probe_irq_off (unsigned long irqs)
-{
-	return 0;
-}
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void breakpoint(void);
-extern int remote_debug;
-#endif
-
-void __init init_IRQ(void)
-{
-	int i;
-
-	/* 
-	 * Mask out all interrupt by writing "1" to all bit position in 
-	 * the interrupt reset reg. 
-	 */
-	atlas_hw0_icregs->intrsten = 0xffffffff;    
-
-	/* Now safe to set the exception vector. */
-	set_except_vector(0, mipsIRQ);
-
-	for (i = 0; i <= ATLASINT_END; i++) {
-		irq_desc[i].status	= IRQ_DISABLED;
-		irq_desc[i].action	= 0;
-		irq_desc[i].depth	= 1;
-		irq_desc[i].handler	= &atlas_irq_type;
-	}
-
-#ifdef CONFIG_REMOTE_DEBUG
-	if (remote_debug) {
-		set_debug_traps();
-		breakpoint();
-	}
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/atlas/atlas_rtc.c linux/arch/mips64/mips-boards/atlas/atlas_rtc.c
--- linux.orig/arch/mips64/mips-boards/atlas/atlas_rtc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/atlas/atlas_rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,58 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * RTC routines for Atlas style attached Dallas chip.
- *
- */
-#include <asm/mc146818rtc.h>
-#include <asm/mips-boards/atlas.h>
-
-
-static unsigned char atlas_rtc_read_data(unsigned long addr)
-{
-	volatile unsigned int *rtc_adr_reg = (void *)ATLAS_RTC_ADR_REG;
-	volatile unsigned int *rtc_dat_reg = (void *)ATLAS_RTC_DAT_REG;
-
-	*rtc_adr_reg = addr;
-
-	return *rtc_dat_reg;
-}
-
-static void atlas_rtc_write_data(unsigned char data, unsigned long addr)
-{
-	volatile unsigned int *rtc_adr_reg = (void *)ATLAS_RTC_ADR_REG;
-	volatile unsigned int *rtc_dat_reg = (void *)ATLAS_RTC_DAT_REG;
-
-	*rtc_adr_reg = addr;
-	*rtc_dat_reg = data;
-}
-
-static int atlas_rtc_bcd_mode(void)
-{
-	return 0;
-}
-
-struct rtc_ops atlas_rtc_ops = {
-	&atlas_rtc_read_data,
-	&atlas_rtc_write_data,
-	&atlas_rtc_bcd_mode
-};
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/atlas/atlas_setup.c linux/arch/mips64/mips-boards/atlas/atlas_setup.c
--- linux.orig/arch/mips64/mips-boards/atlas/atlas_setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/atlas/atlas_setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,123 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Atlas specific setup, including init of the feature struct.
- *
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/mc146818rtc.h>
-#include <linux/ioport.h>
-
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/prom.h>
-#include <asm/mips-boards/gt64120.h>
-#include <asm/mips-boards/atlasint.h>
-
-#include <asm/mmu_context.h>
-
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
-extern void console_setup(char *, int *);
-char serial_console[20];
-#endif
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void rs_kgdb_hook(int);
-extern void saa9730_kgdb_hook(void);
-extern void breakpoint(void);
-int remote_debug = 0;
-#endif
-
-extern struct rtc_ops atlas_rtc_ops;
-
-extern void mips_reboot_setup(void);
-
-void __init atlas_setup(void)
-{
-#ifdef CONFIG_REMOTE_DEBUG
-	int rs_putDebugChar(char);
-	char rs_getDebugChar(void);
-	int saa9730_putDebugChar(char);
-	char saa9730_getDebugChar(void);
-	extern int (*putDebugChar)(char);
-	extern char (*getDebugChar)(void);
-#endif
-	char *argptr;
-
-	current_cpu_data.asid_cache = ASID_FIRST_VERSION;
-	TLBMISS_HANDLER_SETUP();
-
-	ioport_resource.end = 0x7fffffff;
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	argptr = prom_getcmdline();
-	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
-		int i = 0;
-		char *s = prom_getenv("modetty0");
-		while(s[i] >= '0' && s[i] <= '9')
-			i++;
-		strcpy(serial_console, "ttyS0,");
-		strncpy(serial_console + 6, s, i);
-		prom_printf("Config serial console: %s\n", serial_console);
-		console_setup(serial_console, NULL);
-	}
-#endif	  
-
-#ifdef CONFIG_REMOTE_DEBUG
-	argptr = prom_getcmdline();
-	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
-		int line;
-		argptr += strlen("kgdb=ttyS");
-		if (*argptr != '0' && *argptr != '1')
-			printk("KGDB: Uknown serial line /dev/ttyS%c, "
-			       "falling back to /dev/ttyS1\n", *argptr);
-		line = *argptr == '0' ? 0 : 1;
-		printk("KGDB: Using serial line /dev/ttyS%d for session\n",
-		       line ? 1 : 0);
-
-		if(line == 0) {
-			rs_kgdb_hook(line);
-			putDebugChar = rs_putDebugChar;
-			getDebugChar = rs_getDebugChar;
-		} else {
-			saa9730_kgdb_hook();
-			putDebugChar = saa9730_putDebugChar;
-			getDebugChar = saa9730_getDebugChar;
-		}
-
-		prom_printf("KGDB: Using serial line /dev/ttyS%d for session, "
-			    "please connect your debugger\n", line ? 1 : 0);
-
-		remote_debug = 1;
-		/* Breakpoints and stuff are in atlas_irq_setup() */
-	}
-#endif
-	argptr = prom_getcmdline();
-
-	if ((argptr = strstr(argptr, "nofpu")) != NULL)
-		mips_cpu.options &= ~MIPS_CPU_FPU;
-
-	rtc_ops = &atlas_rtc_ops;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/Makefile linux/arch/mips64/mips-boards/generic/Makefile
--- linux.orig/arch/mips64/mips-boards/generic/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,43 +0,0 @@
-#
-# Carsten Langgaard, carstenl@mips.com
-# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-#
-# ########################################################################
-#
-# This program is free software; you can distribute it and/or modify it
-# under the terms of the GNU General Public License (Version 2) as
-# published by the Free Software Foundation.
-# 
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-# 
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-#
-# #######################################################################
-#
-# Makefile for the MIPS boards generic routines under Linux.
-#
-# 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).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-all: mipsboards.o
-
-O_TARGET := mipsboards.o
-
-obj-y                           := mipsIRQ.o pci.o reset.o display.o init.o \
-                                   memory.o printf.o cmdline.o time.o
-obj-$(CONFIG_REMOTE_DEBUG)      += gdb_hook.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/cmdline.c linux/arch/mips64/mips-boards/generic/cmdline.c
--- linux.orig/arch/mips64/mips-boards/generic/cmdline.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/cmdline.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,71 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- * 
- * Kernel command line creation using the prom monitor (YAMON) argc/argv.
- *
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/string.h>
-
-#include <asm/bootinfo.h>
-
-/*#define DEBUG_CMDLINE*/
-
-extern int prom_argc;
-extern int *_prom_argv;
-
-/*
- * A 32-bit PROM pass arguments and environment as 32-bit pointer.
- * This macro take care of sign extension.
- */
-#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
-
-char arcs_cmdline[CL_SIZE];
-
-char * __init prom_getcmdline(void)
-{
-	return &(arcs_cmdline[0]);
-}
-
-
-void  __init prom_init_cmdline(void)
-{
-	char *cp;
-	int actr;
-
-	actr = 1; /* Always ignore argv[0] */
-
-	cp = &(arcs_cmdline[0]);
-	while(actr < prom_argc) {
-	        strcpy(cp, prom_argv(actr));
-		cp += strlen(prom_argv(actr));
-		*cp++ = ' ';
-		actr++;
-	}
-	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
-		--cp;
-	*cp = '\0';
-
-#ifdef DEBUG_CMDLINE
-	prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0]));
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/display.c linux/arch/mips64/mips-boards/generic/display.c
--- linux.orig/arch/mips64/mips-boards/generic/display.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/display.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- * 
- * Display routines for display messages in MIPS boards ascii display.
- *
- */
-
-#include <asm/mips-boards/generic.h>
-
-
-void mips_display_message(const char *str)
-{
-        volatile unsigned int *display = (void *)ASCII_DISPLAY_POS_BASE;
-	int i;
-
-	for (i = 0; i <= 14; i=i+2) {
-	         if (*str)
-		         display[i] = *str++;
-		 else
-		         display[i] = ' ';
-	}
-}
-
-void mips_display_word(unsigned int num)
-{
-        volatile unsigned int *display = (void *)ASCII_DISPLAY_WORD_BASE;
-	
-	*display = num;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/gdb_hook.c linux/arch/mips64/mips-boards/generic/gdb_hook.c
--- linux.orig/arch/mips64/mips-boards/generic/gdb_hook.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/gdb_hook.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,202 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * This is the interface to the remote debugger stub.
- *
- */
-
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-
-#include <asm/serial.h>
-#include <asm/io.h>
-
-static struct serial_state rs_table[RS_TABLE_SIZE] = {
-	SERIAL_PORT_DFNS	/* Defined in serial.h */
-};
-
-static struct async_struct kdb_port_info = {0};
-
-
-static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
-{
-	return inb(info->port + offset);
-}
-
-static __inline__ void serial_out(struct async_struct *info, int offset,
-				int value)
-{
-	outb(value, info->port+offset);
-}
-
-void rs_kgdb_hook(int tty_no) {
-	int t;
-	struct serial_state *ser = &rs_table[tty_no];
-
-	kdb_port_info.state = ser;
-	kdb_port_info.magic = SERIAL_MAGIC;
-	kdb_port_info.port = ser->port;
-	kdb_port_info.flags = ser->flags;
-
-	/*
-	 * Clear all interrupts
-	 */
-	serial_in(&kdb_port_info, UART_LSR);
-	serial_in(&kdb_port_info, UART_RX);
-	serial_in(&kdb_port_info, UART_IIR);
-	serial_in(&kdb_port_info, UART_MSR);
-
-	/*
-	 * Now, initialize the UART 
-	 */
-	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
-	if (kdb_port_info.flags & ASYNC_FOURPORT) {
-		kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
-		t = UART_MCR_DTR | UART_MCR_OUT1;
-	} else {
-		kdb_port_info.MCR 
-			= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
-		t = UART_MCR_DTR | UART_MCR_RTS;
-	}
-
-	kdb_port_info.MCR = t;		/* no interrupts, please */
-	serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
-	
-	/*
-	 * and set the speed of the serial port
-	 * (currently hardwired to 9600 8N1
-	 */
-
-	/* baud rate is fixed to 9600 (is this sufficient?)*/
-	t = kdb_port_info.state->baud_base / 9600;	
-	/* set DLAB */
-	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
-	serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
-	serial_out(&kdb_port_info, UART_DLM, t >> 8);  /* MS of divisor */
-	/* reset DLAB */
-	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
-}
-
-int rs_putDebugChar(char c)
-{
-
-	if (!kdb_port_info.state) { 	/* need to init device first */
-		return 0;
-	}
-
-	while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
-		;
-
-	serial_out(&kdb_port_info, UART_TX, c);
-
-	return 1;
-}
-
-char rs_getDebugChar(void)
-{
-	if (!kdb_port_info.state) { 	/* need to init device first */
-		return 0;
-	}
-
-	while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
-		;
-
-	return(serial_in(&kdb_port_info, UART_RX));
-}
-
-
-#ifdef CONFIG_MIPS_ATLAS
-
-#include <asm/mips-boards/atlas.h>
-#include <asm/mips-boards/saa9730_uart.h>
-
-#define INB(a)     inb((unsigned long)a)
-#define OUTB(x,a)  outb(x,(unsigned long)a)
-
-/*
- * This is the interface to the remote debugger stub
- * if the Philips part is used for the debug port,
- * called from the platform setup code.
- *
- * PCI init will not have been done yet, we make a
- * universal assumption about the way the bootloader (YAMON)
- * have located and set up the chip.
- */
-static t_uart_saa9730_regmap *kgdb_uart = (void *)(ATLAS_SAA9730_REG + SAA9730_UART_REGS_ADDR);
-
-static int saa9730_kgdb_active = 0;
-
-void saa9730_kgdb_hook(void) 
-{
-        volatile unsigned char t;
-
-        /*
-         * Clear all interrupts
-         */
-	t = INB(&kgdb_uart->Lsr);
-	t += INB(&kgdb_uart->Msr);
-	t += INB(&kgdb_uart->Thr_Rbr);
-	t += INB(&kgdb_uart->Iir_Fcr);
-
-        /*
-         * Now, initialize the UART
-         */
-	/* 8 data bits, one stop bit, no parity */
-	OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr);
-
-        /* baud rate is fixed to 9600 (is this sufficient?)*/
-	OUTB(0, &kgdb_uart->BaudDivMsb); /* HACK - Assumes standard crystal */
-	OUTB(23, &kgdb_uart->BaudDivLsb); /* HACK - known for MIPS Atlas */
-
-	/* Set RTS/DTR active */
-	OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr);
-	saa9730_kgdb_active = 1;
-}
-
-int saa9730_putDebugChar(char c)
-{
-
-        if (!saa9730_kgdb_active) {     /* need to init device first */
-                return 0;
-        }
-
-        while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE))
-                ;
-	OUTB(c, &kgdb_uart->Thr_Rbr);
-
-        return 1;
-}
-
-char saa9730_getDebugChar(void)
-{
-	char c;
-
-        if (!saa9730_kgdb_active) {     /* need to init device first */
-                return 0;
-        }
-        while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR))
-                ;
-
-	c = INB(&kgdb_uart->Thr_Rbr);
-        return(c);
-}
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/init.c linux/arch/mips64/mips-boards/generic/init.c
--- linux.orig/arch/mips64/mips-boards/generic/init.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/init.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,152 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * PROM library initialisation code.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-#include <asm/io.h>
-#include <asm/mips-boards/prom.h>
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/gt64120.h>
-#include <asm/mips-boards/malta.h>
-
-/* Environment variable */
-typedef struct
-{
-    char *name;
-    char *val;
-}t_env_var;
-
-int prom_argc;
-int *_prom_argv, *_prom_envp;
-
-/*
- * A 32-bit PROM pass arguments and environment as 32-bit pointer.
- * This macro take care of sign extension.
- */
-#define prom_envp(index) ((char *)(((int *)(int)_prom_envp)[(index)]))
-
-int init_debug = 0;
-
-char *prom_getenv(char *envname)
-{
-        /*
-	 * Return a pointer to the given environment variable.
-	 * We're using 64-bit pointers, but all pointers in the PROM 
-	 * structures are only 32-bit, so we need some workarounds.
-	 */
-	int i, index=0;
-
-	i = strlen(envname);
-
-	while(prom_envp(index)) {
-		if(strncmp(envname, prom_envp(index), i) == 0) {
-			return(prom_envp(index+1));
-		}
-		index += 2;
-	}
-
-	return(NULL);
-}
-
-static inline unsigned char str2hexnum(unsigned char c)
-{
-	if(c >= '0' && c <= '9')
-		return c - '0';
-	if(c >= 'a' && c <= 'f')
-		return c - 'a' + 10;
-	return 0; /* foo */
-}
-
-static inline void str2eaddr(unsigned char *ea, unsigned char *str)
-{
-	int i;
-
-	for(i = 0; i < 6; i++) {
-		unsigned char num;
-
-		if((*str == '.') || (*str == ':'))
-			str++;
-		num = str2hexnum(*str++) << 4;
-		num |= (str2hexnum(*str++));
-		ea[i] = num;
-	}
-}
- 
-int get_ethernet_addr(char *ethernet_addr)
-{
-        char *ethaddr_str;
-
-        ethaddr_str = prom_getenv("ethaddr");
-	if (!ethaddr_str) {
-	        printk("ethaddr not set in boot prom\n");
-		return -1;
-	}
-	str2eaddr(ethernet_addr, ethaddr_str);
-
-	if (init_debug > 1)
-	{
-	        int i;
-		printk("get_ethernet_addr: ");
-	        for (i=0; i<5; i++)
-		        printk("%02x:", (unsigned char)*(ethernet_addr+i));
-		printk("%02x\n", *(ethernet_addr+i));
-	}
-
-	return 0;
-}
-
-int __init prom_init(int argc, char **argv, char **envp)
-{
-	prom_argc = argc;
-	_prom_argv = (int *)argv;
-	_prom_envp = (int *)envp;
-
-	mips_display_message("LINUX");
-
-	/*
-	 * Setup the North bridge to do Master byte-lane swapping when 
-	 * running in bigendian.
-	 */
-#if defined(__MIPSEL__)
-	GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
-		 GT_PCI0_CMD_SBYTESWAP_BIT);
-#else
-	GT_WRITE(GT_PCI0_CMD_OFS, 0);
-#endif
-
-#if defined(CONFIG_MIPS_MALTA)
-	mips_io_port_base = MALTA_PORT_BASE;
-#else
-	mips_io_port_base = KSEG1;
-#endif
-
-	setup_prom_printf(0);
-	prom_printf("\nLINUX started...\n");
-	prom_init_cmdline();
-	prom_meminit();
-
-	return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/memory.c linux/arch/mips64/mips-boards/generic/memory.c
--- linux.orig/arch/mips64/mips-boards/generic/memory.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/memory.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,263 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * PROM library functions for acquiring/using memory descriptors given to 
- * us from the YAMON.
- * 
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-
-#include <asm/mips-boards/prom.h>
-
-/*#define DEBUG*/
-
-enum yamon_memtypes {
-	yamon_dontuse,
-	yamon_prom,
-	yamon_free,
-};
-struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
-
-#define MEMTYPE_DONTUSE 0
-#define MEMTYPE_PROM    1
-#define MEMTYPE_FREE    2
-
-#ifdef DEBUG
-static char *mtypes[3] = {
-	"Dont use memory",
-	"YAMON PROM memory",
-	"Free memmory",
-};
-#endif
-
-/* References to section boundaries */
-extern char _end;
-
-#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
-
-struct prom_pmemblock * __init prom_getmdesc(void)
-{
-	char *memsize_str;
-	unsigned int memsize;
-
-	memsize_str = prom_getenv("memsize");
-	if (!memsize_str) {
-		prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
-		memsize = 0x02000000;
-	} else {
-#ifdef DEBUG
-		prom_printf("prom_memsize = %s\n", memsize_str);
-#endif
-		memsize = simple_strtol(memsize_str, NULL, 0);
-	}
-
-	memset(mdesc, 0, sizeof(mdesc));
-
-	mdesc[0].type = yamon_dontuse;
-	mdesc[0].base = 0x00000000;
-	mdesc[0].size = 0x00001000;
-
-	mdesc[1].type = yamon_prom;
-	mdesc[1].base = 0x00001000;
-	mdesc[1].size = 0x000ef000;
-
-#if (CONFIG_MIPS_MALTA)
-	/* 
-	 * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
-	 * south bridge and PCI access always forwarded to the ISA Bus and 
-	 * BIOSCS# is always generated.
-	 * This mean that this area can't be used as DMA memory for PCI 
-	 * devices.
-	 */
-	mdesc[2].type = yamon_dontuse;
-	mdesc[2].base = 0x000f0000;
-	mdesc[2].size = 0x00010000;
-#else
-	mdesc[2].type = yamon_prom;
-	mdesc[2].base = 0x000f0000;
-	mdesc[2].size = 0x00010000;
-#endif
-
-	mdesc[3].type = yamon_dontuse;
-	mdesc[3].base = 0x00100000;
-	mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base;
-
-	mdesc[4].type = yamon_free;
-	mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
-	mdesc[4].size = memsize - mdesc[4].base;
-
-	return &mdesc[0];
-}
-
-int __init page_is_ram(unsigned long pagenr)
-{
-	if ((pagenr << PAGE_SHIFT) < mdesc[4].base + mdesc[4].size)
-		return 1;
-
-	return 0;
-}
-
-static struct prom_pmemblock pblocks[PROM_MAX_PMEMBLOCKS];
-
-static int __init prom_memtype_classify (unsigned int type)
-{
-	switch (type) {
-	case yamon_free:
-		return MEMTYPE_FREE;
-	case yamon_prom:
-		return MEMTYPE_PROM;
-	default:
-		return MEMTYPE_DONTUSE;
-	}
-}
-
-static inline unsigned long find_max_low_pfn(void)
-{
-	struct prom_pmemblock *p, *highest;
-	unsigned long pfn;
-
-	p = pblocks;
-	highest = 0;
-	while (p->size != 0) {
-		if (!highest || p->base > highest->base)
-			highest = p;
-		p++;
-        }
-
-	pfn = (highest->base + highest->size) >> PAGE_SHIFT;
-#ifdef DEBUG
-	prom_printf("find_max_low_pfn: 0x%lx pfns.\n", pfn);
-#endif
-	return pfn;
-}
-
-static inline struct prom_pmemblock *find_largest_memblock(void)
-{
-	struct prom_pmemblock *p, *largest;
-
-	p = pblocks;
-	largest = 0;
-	while (p->size != 0) {
-		if (!largest || p->size > largest->size)
-			largest = p;
-		p++;
-	}
-
-	return largest;
-}
-
-void __init prom_meminit(void)
-{
-	struct prom_pmemblock *largest, *p;
-	unsigned long bootmap_size;
-	int totram;
-	int i = 0;
-
-#ifdef DEBUG
-	prom_printf("YAMON MEMORY DESCRIPTOR dump:\n");
-	p = prom_getmdesc();
-	while (p->size) {
-		prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n",
-			    i, p, p->base, p->size, mtypes[p->type]);
-		p++;
-		i++;
-	}
-#endif
-	totram = 0;
-	i = 0;
-	p = prom_getmdesc();
-
-	while (p->size) {
-		pblocks[i].type = prom_memtype_classify (p->type);
-		pblocks[i].base = p->base;
-		pblocks[i].size = p->size;
-		switch (pblocks[i].type) {
-		case MEMTYPE_FREE:
-			totram += pblocks[i].size;
-#ifdef DEBUG
-			prom_printf("free_chunk[%d]: base=%08lx size=%d\n",
-				    i, pblocks[i].base, pblocks[i].size);
-#endif
-			i++;
-			break;
-		case MEMTYPE_PROM:
-#ifdef DEBUG
-		        prom_printf("prom_chunk[%d]: base=%08lx size=%d\n",
-				    i, pblocks[i].base, pblocks[i].size);
-#endif
-			i++;
-			break;
-		default:
-			break;
-		}
-		p++;
-	}
-	pblocks[i].base = 0xdeadbeef;
-	pblocks[i].size = 0; /* indicates last elem. of array */
-
-	max_low_pfn = find_max_low_pfn();
-	largest = find_largest_memblock();
-	bootmap_size = init_bootmem(largest->base >> PAGE_SHIFT, max_low_pfn);
-
-	for (i = 0; pblocks[i].size; i++)
-		if (pblocks[i].type == MEMTYPE_FREE)
-			free_bootmem(pblocks[i].base, pblocks[i].size);
-
-	/* This test is simpleminded.  It will fail if the bootmem bitmap
-	   falls into multiple adjacent PROM memory areas.  */
-	if (bootmap_size > largest->size) {
-		prom_printf("CRITIAL: overwriting PROM data.\n");
-		BUG();
-	}
-
-	/* Reserve the memory bootmap itself */
-	reserve_bootmem(largest->base, bootmap_size);
-	printk("PROMLIB: Total free ram %d bytes (%dK,%dMB)\n",
-	       totram, (totram/1024), (totram/1024/1024));
-}
-
-void prom_free_prom_memory (void)
-{
-	struct prom_pmemblock *p;
-	unsigned long freed = 0;
-	unsigned long addr;
-
-	for (p = pblocks; p->size != 0; p++) {
-		if (p->type != MEMTYPE_PROM)
-			continue;
-
-		addr = p->base;
-		while (addr < p->base + p->size) {
-		        ClearPageReserved(virt_to_page(__va(addr)));
-			set_page_count(virt_to_page(__va(addr)), 1);
-			free_page(__va(addr));
-			addr += PAGE_SIZE;
-			freed += PAGE_SIZE;
-		}
-	}
-	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/mipsIRQ.S linux/arch/mips64/mips-boards/generic/mipsIRQ.S
--- linux.orig/arch/mips64/mips-boards/generic/mipsIRQ.S	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/mipsIRQ.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,122 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Interrupt exception dispatch code.
- *
- */
-#include <linux/config.h>
-
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/* A lot of complication here is taken away because:
- *
- * 1) We handle one interrupt and return, sitting in a loop and moving across
- *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
- *    common case is one pending IRQ so optimize in that direction.
- *
- * 2) We need not check against bits in the status register IRQ mask, that
- *    would make this routine slow as hell.
- *
- * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
- *    between like BSD spl() brain-damage.
- *
- * Furthermore, the IRQs on the MIPS board look basically (barring software
- * IRQs which we don't use at all and all external interrupt sources are
- * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
- *
- *	MIPS IRQ	Source
- *      --------        ------
- *             0	Software (ignored)
- *             1        Software (ignored)
- *             2        Combined hardware interrupt (hw0)
- *             3        Hardware (ignored)
- *             4        Hardware (ignored)
- *             5        Hardware (ignored)
- *             6        Hardware (ignored)
- *             7        R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ----     R4k Timer
- * Lowest  ----     Combined hardware interrupt
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
-	.text
-	.set	noreorder
-	.set	noat
-	.align	5
-	NESTED(mipsIRQ, PT_SIZE, sp)
-	SAVE_ALL
-	CLI
-	.set	at
-
-	mfc0	s0, CP0_CAUSE		# get irq mask
-
-	/* First we check for r4k counter/timer IRQ. */
-	andi	a0, s0, CAUSEF_IP7
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP2	# delay slot, check hw0 interrupt
-
-	/* Wheee, a timer interrupt. */
-	move	a0, sp
-	jal	mips_timer_interrupt
-	 nop
-
-	j	ret_from_irq
-	 nop
-
-1:
-	beq	a0, zero, 1f
-	 nop
-
-	/* Wheee, combined hardware level zero interrupt. */
-#if defined(CONFIG_MIPS_ATLAS)
-	jal	atlas_hw0_irqdispatch
-#elif defined(CONFIG_MIPS_MALTA)
-	jal	malta_hw0_irqdispatch
-#else
-#error "MIPS board not supported\n"	
-#endif
-	 move	a0, sp			# delay slot
-
-	j	ret_from_irq
-	 nop				# delay slot
-
-1:
-	/*
-	 * Here by mistake?  This is possible, what can happen is that by the
-	 * time we take the exception the IRQ pin goes low, so just leave if
-	 * this is the case.
-	 */
-	move	a1,s0
-	PRINT("Got interrupt: c0_cause = %08x\n")
-	mfc0	a1, CP0_EPC
-	PRINT("c0_epc = %08x\n")
-
-	j	ret_from_irq
-	 nop
-	END(mipsIRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/pci.c linux/arch/mips64/mips-boards/generic/pci.c
--- linux.orig/arch/mips64/mips-boards/generic/pci.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,337 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * MIPS boards specific PCI support.
- *
- */
-#include <linux/config.h>
-
-#ifdef CONFIG_PCI
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/gt64120.h>
-#ifdef CONFIG_MIPS_MALTA
-#include <asm/mips-boards/malta.h>
-#endif
-
-#define PCI_ACCESS_READ  0
-#define PCI_ACCESS_WRITE 1
-
-static int
-mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
-                           unsigned char where, u32 *data)
-{
-	unsigned char bus = dev->bus->number;
-	unsigned char dev_fn = dev->devfn;
-        u32 intr;
-
-	if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0)))
-	        return -1; /* Because of a bug in the galileo (for slot 31). */
-
-	/* Clear cause register bits */
-	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
-	                             GT_INTRCAUSE_TARABORT0_BIT));
-
-	/* Setup address */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS, 
-		 (bus         << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
-		 (dev_fn      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
-		 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
-		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
-
-	if (access_type == PCI_ACCESS_WRITE) {
-	        if (bus == 0 && dev_fn == 0) {
-		        /* 
-			 * Galileo is acting differently than other devices. 
-			 */
-		        GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
-		} else {
-		        GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data);
-		}
-	} else {
-	        if (bus == 0 && dev_fn == 0) {
-		        /* 
-			 * Galileo is acting differently than other devices. 
-			 */
-		        GT_READ(GT_PCI0_CFGDATA_OFS, *data);
-		} else {
-		        GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data);
-		}
-	}
-
-	/* Check for master or target abort */
-	GT_READ(GT_INTRCAUSE_OFS, intr);
-
-	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT))
-	{
-	        /* Error occured */
-
-	        /* Clear bits */
-	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
-					      GT_INTRCAUSE_TARABORT0_BIT) );
-
-		return -1;
-	}
-
-	return 0;
-}
-
-
-/*
- * We can't address 8 and 16 bit words directly.  Instead we have to
- * read/write a 32bit word and mask/modify the data we actually want.
- */
-static int
-mips_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val)
-{
-	u32 data = 0;
-
-	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
-		return -1;
-
-	*val = (data >> ((where & 3) << 3)) & 0xff;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-
-static int
-mips_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
-{
-	u32 data = 0;
-
-	if (where & 1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
-	       return -1;
-
-	*val = (data >> ((where & 3) << 3)) & 0xffff;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-mips_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
-{
-	u32 data = 0;
-
-	if (where & 3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	
-	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
-		return -1;
-
-	*val = data;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-
-static int
-mips_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val)
-{
-	u32 data = 0;
-       
-	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
-		return -1;
-
-	data = (data & ~(0xff << ((where & 3) << 3))) |
-	       (val << ((where & 3) << 3));
-
-	if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
-		return -1;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-mips_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
-{
-        u32 data = 0;
-
-	if (where & 1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-       
-        if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
-	       return -1;
-
-	data = (data & ~(0xffff << ((where & 3) << 3))) | 
-	       (val << ((where & 3) << 3));
-
-	if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
-	       return -1;
-
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-mips_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
-{
-	if (where & 3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val))
-	       return -1;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops mips_pci_ops = {
-	mips_pcibios_read_config_byte,
-        mips_pcibios_read_config_word,
-	mips_pcibios_read_config_dword,
-	mips_pcibios_write_config_byte,
-	mips_pcibios_write_config_word,
-	mips_pcibios_write_config_dword
-};
-
-void __init pcibios_init(void)
-{
-#ifdef CONFIG_MIPS_MALTA
-	struct pci_dev *pdev;
-	unsigned char reg_val;
-#endif
-
-	printk("PCI: Probing PCI hardware on host bus 0.\n");
-	pci_scan_bus(0, &mips_pci_ops, NULL);
-
-	/* 
-	 * Due to a bug in the Galileo system controller, we need to setup 
-	 * the PCI BAR for the Galileo internal registers.
-	 * This should be done in the bios/bootprom and will be fixed in
-	 * a later revision of YAMON (the MIPS boards boot prom).
-	 */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,
-		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF)   |  /* Local bus */
-		 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF)   |  /* GT64120 device */
-		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |  /* Function 0 */
-		 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) |  /* BAR 4 */
-		 GT_PCI0_CFGADDR_CONFIGEN_BIT );
-
-	/* Perform the write */
-	GT_WRITE( GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE)); 
-
-#ifdef CONFIG_MIPS_MALTA
-	pci_for_each_dev(pdev) {
-		if ((pdev->vendor == PCI_VENDOR_ID_INTEL)
-		    && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB)
-		    && (PCI_SLOT(pdev->devfn) == 0x0a)) {
-			/*
-			 * IDE Decode enable.
-			 */
-			pci_read_config_byte(pdev, 0x41, &reg_val);
-        		pci_write_config_byte(pdev, 0x41, reg_val | 0x80);
-			pci_read_config_byte(pdev, 0x43, &reg_val);
-        		pci_write_config_byte(pdev, 0x43, reg_val | 0x80);
-		}
-
-		if ((pdev->vendor == PCI_VENDOR_ID_INTEL)
-		    && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB_0)
-		    && (PCI_SLOT(pdev->devfn) == 0x0a)) {
-			/*
-			 * Set top of main memory accessible by ISA or DMA
-			 * devices to 16 Mb.
-			 */
-			pci_read_config_byte(pdev, 0x69, &reg_val);
-			pci_write_config_byte(pdev, 0x69, reg_val | 0xf0);
-		}
-	}
-
-	/* 
-	 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O 
-	 * Controller.
-	 * This should be done in the bios/bootprom and will be fixed in
-         * a later revision of YAMON (the MIPS boards boot prom).
-	 */
-	/* Entering config state. */
-	SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); 
-       
-	/* Activate floppy controller. */
-	SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG);
-	SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG);
-	SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG);
-	SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG);
-
-	/* Exit config state. */
-	SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG);
-#endif
-}
-
-int __init
-pcibios_enable_device(struct pci_dev *dev)
-{
-	/* Not needed, since we enable all devices at startup.  */
-	return 0;
-}
-
-void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
-{
-}
-
-char * __init
-pcibios_setup(char *str)
-{
-	/* Nothing to do for now.  */
-
-	return str;
-}
-
-struct pci_fixup pcibios_fixups[] = {
-	{ 0 }
-};
-
-void __init
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-                        struct resource *res, int resource)
-{
-	unsigned long where, size;
-	u32 reg;
-
-	where = PCI_BASE_ADDRESS_0 + (resource * 4);
-	size = res->end - res->start;
-	pci_read_config_dword(dev, where, &reg);
-	reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
-	pci_write_config_dword(dev, where, reg);
-}
-
-unsigned __init int pcibios_assign_all_busses(void)
-{
-	return 1;
-}
-
-/*
- *  Called after each bus is probed, but before its children
- *  are examined.
- */
-void __init pcibios_fixup_bus(struct pci_bus *b)
-{
-	pci_read_bridge_bases(b);
-}
-
-#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/printf.c linux/arch/mips64/mips-boards/generic/printf.c
--- linux.orig/arch/mips64/mips-boards/generic/printf.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/printf.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,140 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Putting things on the screen/serial line using YAMONs facilities.
- *
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/serial.h>
-
-
-#ifdef CONFIG_MIPS_ATLAS 
-/* 
- * Atlas registers are memory mapped on 64-bit aligned boundaries and 
- * only word access are allowed.
- * When reading the UART 8 bit registers only the LSB are valid.
- */
-unsigned int atlas_serial_in(struct async_struct *info, int offset)
-{
-	return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff);
-}
-
-void atlas_serial_out(struct async_struct *info, int offset, int value)
-{
-	*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value;
-}
-
-#define serial_in  atlas_serial_in
-#define serial_out atlas_serial_out
-
-#else
-
-static unsigned int serial_in(struct async_struct *info, int offset)
-{
-	return inb(info->port + offset);
-}
-
-static void serial_out(struct async_struct *info, int offset,
-				int value)
-{
-	outb(value, info->port + offset);
-}
-#endif
-
-static struct serial_state rs_table[] = {
-	SERIAL_PORT_DFNS	/* Defined in serial.h */
-};
-
-/*
- * Hooks to fake "prom" console I/O before devices 
- * are fully initialized. 
- */
-static struct async_struct prom_port_info = {0};
-
-void __init setup_prom_printf(int tty_no) {
-	struct serial_state *ser = &rs_table[tty_no];
-
-	prom_port_info.state = ser;
-	prom_port_info.magic = SERIAL_MAGIC;
-	prom_port_info.port = ser->port;
-	prom_port_info.flags = ser->flags;
-
-	/* No setup of UART - assume YAMON left in sane state */
-}
-
-int putPromChar(char c)
-{
-        if (!prom_port_info.state) { 	/* need to init device first */
-		return 0;
-	}
-
-	while ((serial_in(&prom_port_info, UART_LSR) & UART_LSR_THRE) == 0)
-		;
-
-	serial_out(&prom_port_info, UART_TX, c);
-
-	return 1;
-}
-
-char getPromChar(void)
-{
-	if (!prom_port_info.state) { 	/* need to init device first */
-		return 0;
-	}
-
-	while (!(serial_in(&prom_port_info, UART_LSR) & 1))
-		;
-
-	return(serial_in(&prom_port_info, UART_RX));
-}
-
-static char buf[1024];
-
-void __init prom_printf(char *fmt, ...)
-{
-	va_list args;
-	int l;
-	char *p, *buf_end;
-	long flags;
-
-	int putPromChar(char);
-
-	/* Low level, brute force, not SMP safe... */
-	save_and_cli(flags);
-	va_start(args, fmt);
-	l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
-	va_end(args);
-
-	buf_end = buf + l;
-
-	for (p = buf; p < buf_end; p++) {
-		/* Crude cr/nl handling is better than none */
-		if(*p == '\n')putPromChar('\r');
-		putPromChar(*p);
-	}
-	restore_flags(flags);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/reset.c linux/arch/mips64/mips-boards/generic/reset.c
--- linux.orig/arch/mips64/mips-boards/generic/reset.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/reset.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,61 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Reset the MIPS boards.
- *
- */
-#include <linux/config.h>
-
-#include <asm/mips-boards/generic.h>
-#if defined(CONFIG_MIPS_ATLAS)
-#include <asm/mips-boards/atlas.h>
-#endif
-
-void machine_restart(char *command) __attribute__((noreturn));
-void machine_halt(void) __attribute__((noreturn));
-#if defined(CONFIG_MIPS_ATLAS)
-void machine_power_off(void) __attribute__((noreturn));
-#endif
-
-void machine_restart(char *command)
-{
-        volatile unsigned int *softres_reg = (void *)SOFTRES_REG;
-
-	*softres_reg = GORESET;
-}
-
-void machine_halt(void)
-{
-        volatile unsigned int *softres_reg = (void *)SOFTRES_REG;
-
-	*softres_reg = GORESET;
-}
-
-void machine_power_off(void)
-{
-#if defined(CONFIG_MIPS_ATLAS)
-        volatile unsigned int *psustby_reg = (void *)ATLAS_PSUSTBY_REG;
-
-	*psustby_reg = ATLAS_GOSTBY;
-#else
-	machine_halt();
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/generic/time.c linux/arch/mips64/mips-boards/generic/time.c
--- linux.orig/arch/mips64/mips-boards/generic/time.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/generic/time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,399 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Setting up the clock on the MIPS boards.
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-
-#include <asm/mipsregs.h>
-#include <asm/ptrace.h>
-
-#include <linux/mc146818rtc.h>
-#include <linux/timex.h>
-
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/prom.h>
-
-extern volatile unsigned long wall_jiffies;
-static long last_rtc_update = 0;
-unsigned long missed_heart_beats = 0;
-
-static unsigned long r4k_offset; /* Amount to increment compare reg each time */
-static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-extern rwlock_t xtime_lock;
-
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-
-#if defined(CONFIG_MIPS_ATLAS)
-static char display_string[] = "        LINUX ON ATLAS       ";
-#endif
-#if defined(CONFIG_MIPS_MALTA)
-static char display_string[] = "        LINUX ON MALTA       ";
-#endif
-static unsigned int display_count = 0;
-#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) 
-
-static unsigned int timer_tick_count=0;
-
-
-static inline void ack_r4ktimer(unsigned long newval)
-{
-	write_32bit_cp0_register(CP0_COMPARE, newval);
-}
-
-
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you won't notice until after reboot!
- */
-static int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned char save_control, save_freq_select;
-
-	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-	cmos_minutes = CMOS_READ(RTC_MINUTES);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
- 		retval = -1;
-	}
-
-	/* The following flags have to be released exactly in this order,
-	 * otherwise the DS12887 (popular MC146818A clone with integrated
-	 * battery and quartz) will not reset the oscillator and will not
-	 * update precisely 500 ms later. You won't find this mentioned in
-	 * the Dallas Semiconductor data sheets, but who believes data
-	 * sheets anyway ...                           -- Markus Kuhn
-	 */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
-	return retval;
-}
-
-/*
- * There are a lot of conceptually broken versions of the MIPS timer interrupt
- * handler floating around.  This one is rather different, but the algorithm
- * is provably more robust.
- */
-void mips_timer_interrupt(struct pt_regs *regs)
-{
-	int irq = 7;
-
-	if (r4k_offset == 0)
-		goto null;
-
-	do {
-		kstat.irqs[0][irq]++;
-		do_timer(regs);
-
-		/* Historical comment/code:
- 		 * RTC time of day s updated approx. every 11 
- 		 * minutes.  Because of how the numbers work out 
- 		 * we need to make absolutely sure we do this update
- 		 * within 500ms before the * next second starts, 
- 		 * thus the following code.
- 		 */
-		read_lock(&xtime_lock);
-		if ((time_status & STA_UNSYNC) == 0 
-		    && xtime.tv_sec > last_rtc_update + 660 
-		    && xtime.tv_usec >= 500000 - (tick >> 1) 
-		    && xtime.tv_usec <= 500000 + (tick >> 1))
-			if (set_rtc_mmss(xtime.tv_sec) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else
-				/* do it again in 60 s */
-	    			last_rtc_update = xtime.tv_sec - 600; 
-		read_unlock(&xtime_lock);
-
-		if ((timer_tick_count++ % HZ) == 0) {
-		    mips_display_message(&display_string[display_count++]);
-		    if (display_count == MAX_DISPLAY_COUNT)
-		        display_count = 0;
-		}
-
-		r4k_cur += r4k_offset;
-		ack_r4ktimer(r4k_cur);
-
-	} while (((unsigned int)read_32bit_cp0_register(CP0_COUNT)
-	         - (unsigned int)r4k_cur) < 0x7fffffff);
-
-	return;
-
-null:
-	ack_r4ktimer(0);
-}
-
-/* 
- * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick. 
- * Use the RTC to calculate offset.
- */
-static unsigned long __init cal_r4koff(void)
-{
-	unsigned long count;
-	unsigned int flags;
-
-	__save_and_cli(flags);
-
-	/* Start counter exactly on falling edge of update flag */
-	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
-	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
-	/* Start r4k counter. */
-	write_32bit_cp0_register(CP0_COUNT, 0);
-
-	/* Read counter exactly on falling edge of update flag */
-	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
-	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
-	count = read_32bit_cp0_register(CP0_COUNT);
-
-	/* restore interrupts */
-	__restore_flags(flags);
-
-	return (count / HZ);
-}
-
-static unsigned long __init get_mips_time(void)
-{
-	unsigned int year, mon, day, hour, min, sec;
-	unsigned char save_control;
-
-	save_control = CMOS_READ(RTC_CONTROL);
-
-	/* Freeze it. */
-	CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL);
-
-	/* Read regs. */
-	sec = CMOS_READ(RTC_SECONDS);
-	min = CMOS_READ(RTC_MINUTES);
-	hour = CMOS_READ(RTC_HOURS);
-
-	if (!(save_control & RTC_24H))
-	{
-		if ((hour & 0xf) == 0xc)
-		        hour &= 0x80;
-	        if (hour & 0x80)
-		        hour = (hour & 0xf) + 12;     
-	}
-	day = CMOS_READ(RTC_DAY_OF_MONTH);
-	mon = CMOS_READ(RTC_MONTH);
-	year = CMOS_READ(RTC_YEAR);
-
-	/* Unfreeze clock. */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-
-	if ((year += 1900) < 1970)
-	        year += 100;
-
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-void __init time_init(void)
-{
-        unsigned int est_freq, flags;
-
-        /* Set Data mode - binary. */ 
-        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
-
-	printk("calculating r4koff... ");
-	r4k_offset = cal_r4koff();
-	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
-
-	est_freq = 2*r4k_offset*HZ;	
-	est_freq += 5000;    /* round */
-	est_freq -= est_freq%10000;
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
-	       (est_freq%1000000)*100/1000000);
-	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
-
-	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
-	set_cp0_status(ST0_IM, ALLINTS);
-
-	/* Read time from the RTC chipset. */
-	write_lock_irqsave (&xtime_lock, flags);
-	xtime.tv_sec = get_mips_time();
-	xtime.tv_usec = 0;
-	write_unlock_irqrestore(&xtime_lock, flags);
-}
-
-/* This is for machines which generate the exact clock. */
-#define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff)
-
-/* Cycle counter value at the previous timer interrupt.. */
-
-static unsigned int timerhi = 0, timerlo = 0;
-
-/*
- * FIXME: Does playing with the RP bit in c0_status interfere with this code?
- */
-static unsigned long do_fast_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res, tmp;
-
-	/* Last jiffy when do_fast_gettimeoffset() was called. */
-	static unsigned long last_jiffies=0;
-	unsigned long quotient;
-
-	/*
-	 * Cached "1/(clocks per usec)*2^32" value.
-	 * It has to be recalculated once each jiffy.
-	 */
-	static unsigned long cached_quotient=0;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-
-	if (tmp && last_jiffies != tmp) {
-		last_jiffies = tmp;
-		__asm__(".set\tnoreorder\n\t"
-			".set\tnoat\n\t"
-			".set\tmips3\n\t"
-			"lwu\t%0,%2\n\t"
-			"dsll32\t$1,%1,0\n\t"
-			"or\t$1,$1,%0\n\t"
-			"ddivu\t$0,$1,%3\n\t"
-			"mflo\t$1\n\t"
-			"dsll32\t%0,%4,0\n\t"
-			"nop\n\t"
-			"ddivu\t$0,%0,$1\n\t"
-			"mflo\t%0\n\t"
-			".set\tmips0\n\t"
-			".set\tat\n\t"
-			".set\treorder"
-			:"=&r" (quotient)
-			:"r" (timerhi),
-			 "m" (timerlo),
-			 "r" (tmp),
-			 "r" (USECS_PER_JIFFY)
-			:"$1");
-		cached_quotient = quotient;
-	}
-
-	/* Get last timer tick in absolute kernel time */
-	count = read_32bit_cp0_register(CP0_COUNT);
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu\t%1,%2\n\t"
-		"mfhi\t%0"
-		:"=r" (res)
-		:"r" (count),
-		 "r" (quotient));
-
-	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY-1;
-
-	return res;
-}
-
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned int flags;
-
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_fast_gettimeoffset();
-
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
-
-	read_unlock_irqrestore (&xtime_lock, flags);
-
-	if (tv->tv_usec >= 1000000) {
-		tv->tv_usec -= 1000000;
-		tv->tv_sec++;
-	}
-}
-
-void do_settimeofday(struct timeval *tv)
-{
-	write_lock_irq (&xtime_lock);
-
-	/* This is revolting. We need to set the xtime.tv_usec correctly.
-	 * However, the value in this location is is value at the last tick.
-	 * Discover what correction gettimeofday would have done, and then
-	 * undo it!
-	 */
-	tv->tv_usec -= do_fast_gettimeoffset();
-
-	if (tv->tv_usec < 0) {
-		tv->tv_usec += 1000000;
-		tv->tv_sec--;
-	}
-
-	xtime = *tv;
-	time_adjust = 0;		/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-
-	write_unlock_irq (&xtime_lock);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/malta/Makefile linux/arch/mips64/mips-boards/malta/Makefile
--- linux.orig/arch/mips64/mips-boards/malta/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/malta/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,42 +0,0 @@
-#
-# Carsten Langgaard, carstenl@mips.com
-# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-#
-# ########################################################################
-#
-# This program is free software; you can distribute it and/or modify it
-# under the terms of the GNU General Public License (Version 2) as
-# published by the Free Software Foundation.
-# 
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-# 
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-#
-# #######################################################################
-#
-# Makefile for the MIPS Malta specific kernel interface routines
-# under Linux.
-#
-# 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).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-all: malta.o
-
-O_TARGET := malta.o
-
-obj-y := malta_int.o malta_rtc.o malta_setup.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/malta/malta_int.c linux/arch/mips64/mips-boards/malta/malta_int.c
--- linux.orig/arch/mips64/mips-boards/malta/malta_int.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/malta/malta_int.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,383 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Routines for generic manipulation of the interrupts found on the MIPS 
- * Malta board.
- * The interrupt controller is located in the South Bridge a PIIX4 device 
- * with two internal 82C95 interrupt controllers.
- *
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/random.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/mips-boards/malta.h>
-#include <asm/mips-boards/maltaint.h>
-#include <asm/mips-boards/piix4.h>
-#include <asm/mips-boards/gt64120.h>
-#include <asm/mips-boards/generic.h>
-
-extern asmlinkage void mipsIRQ(void);
-
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
-unsigned long spurious_count = 0;
-
-static struct irqaction *hw0_irq_action[MALTAINT_END] = {
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL
-};
-
-static struct irqaction r4ktimer_action = {
-	NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
-};
-
-static struct irqaction *irq_action[8] = {
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, &r4ktimer_action
-};
-
-#if 0
-#define DEBUG_INT(x...) printk(x)
-#else
-#define DEBUG_INT(x...)
-#endif
-
-/*
- * This contains the interrupt mask for both 82C59 interrupt controllers.
- */
-static unsigned int cached_int_mask = 0xffff;
-
-
-void disable_irq(unsigned int irq_nr)
-{
-        unsigned long flags;
-
-	if(irq_nr >= MALTAINT_END) {
-		printk("whee, invalid irq_nr %d\n", irq_nr);
-		panic("IRQ, you lose...");
-	}
-
-	save_and_cli(flags);
-	cached_int_mask |= (1 << irq_nr);
-	if (irq_nr & 8) {
-	        outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-	} else {
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	}
-	restore_flags(flags);
-}
-
-
-void enable_irq(unsigned int irq_nr)
-{
-        unsigned long flags;
-
-	if(irq_nr >= MALTAINT_END) {
-		printk("whee, invalid irq_nr %d\n", irq_nr);
-		panic("IRQ, you lose...");
-	}
-
-	save_and_cli(flags);
-	cached_int_mask &= ~(1 << irq_nr);
-	if (irq_nr & 8) {
-		outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-
-		/* Enable irq 2 (cascade interrupt). */
-	        cached_int_mask &= ~(1 << 2); 
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	} else {
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	}	
-	restore_flags(flags);
-}
-
-
-int get_irq_list(char *buf)
-{
-	int i, len = 0;
-	int num = 0;
-	struct irqaction *action;
-
-	for (i = 0; i < 8; i++, num++) {
-		action = irq_action[i];
-		if (!action) 
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
-			(action->flags & SA_INTERRUPT) ? '+' : ' ',
-			action->name);
-		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ",%s %s",
-				(action->flags & SA_INTERRUPT) ? " +" : "",
-				action->name);
-		}
-		len += sprintf(buf+len, " [on-chip]\n");
-	}
-	for (i = 0; i < MALTAINT_END; i++, num++) {
-		action = hw0_irq_action[i];
-		if (!action) 
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
-			(action->flags & SA_INTERRUPT) ? '+' : ' ',
-			action->name);
-		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ",%s %s",
-				(action->flags & SA_INTERRUPT) ? " +" : "",
-				action->name);
-		}
-		len += sprintf(buf+len, " [hw0]\n");
-	}
-	return len;
-}
-
-int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
-{  
-        struct irqaction *action;
-	int retval;
-
-	DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname);
-
-        if (irq >= MALTAINT_END)
-	        return -EINVAL;
-	if (!handler)
-	        return -EINVAL;
-
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if(!action)
-	        return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->mask = 0;
-	action->name = devname;
-	action->dev_id = dev_id;
-	action->next = 0;
-
-	retval = setup_irq(irq, action);
-	if (retval)
-		kfree(action);
-
-	return retval;	
-}
-
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-	struct irqaction *action, **p;
-
-	if (irq >= MALTAINT_END) {
-		printk("Trying to free IRQ%d\n",irq);
-		return;
-	}
-	
-	for (p = &hw0_irq_action[irq]; (action = *p) != NULL; 
-	     p = &action->next) 
-	{
-		if (action->dev_id != dev_id)
-			continue;
-
-		/* Found it - now free it */
-		*p = action->next;
-		kfree(action);
-		if (!hw0_irq_action[irq])
-			disable_irq(irq);
-		return;
-	}
-	printk("Trying to free IRQ%d\n",irq);
-}
-
-void __init init_IRQ(void)
-{
-	irq_setup();
-}
-
-static int setup_irq(unsigned int irq, struct irqaction * new)
-{
-	int shared = 0;
-	struct irqaction *old, **p;
-
-	p = &hw0_irq_action[irq];
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ))
-			return -EBUSY;
-
-		/* Can't share interrupts unless both are same type */
-		if ((old->flags ^ new->flags) & SA_INTERRUPT)
-			return -EBUSY;
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	if (new->flags & SA_SAMPLE_RANDOM)
-		rand_initialize_irq(irq);
-
-	*p = new;
-	if (!shared)
-		enable_irq(irq);
-
-	return 0;
-}
-
-static inline int get_int(int *irq)
-{
-	/*  
-	 * Determine highest priority pending interrupt by performing
-         * a PCI Interrupt Acknowledge cycle.
-	 */
-	GT_READ(GT_PCI0_IACK_OFS, *irq);
-	*irq &= 0xFF;
-
-	/*  
-	 * IRQ7 is used to detect spurious interrupts.
-	 * The interrupt acknowledge cycle returns IRQ7, if no 
-	 * interrupts is requested.
-	 * We can differentiate between this situation and a
-	 * "Normal" IRQ7 by reading the ISR.
-	 */
-	if (*irq == 7) 
-	{
-		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, PIIX4_ICTLR1_OCW3);
-		if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7)))
-		        return -1;    /* Spurious interrupt. */
-	}
-
-	return 0;
-}
-
-static inline void ack_int(int irq)
-{
-	if (irq & 8) {
-	        /* Specific EOI to cascade */
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI | PIIX4_OCW2_ILS_2, 
-		     PIIX4_ICTLR1_OCW2);
-
-	        /* Non specific EOI to cascade */
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR2_OCW2);
-	} else {
-	        /* Non specific EOI to cascade */
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR1_OCW2);
-	}
-}
-
-void malta_hw0_irqdispatch(struct pt_regs *regs)
-{
-        struct irqaction *action;
-	int irq=0, cpu = smp_processor_id();
-
-	DEBUG_INT("malta_hw0_irqdispatch\n");
-	
-	if (get_int(&irq))
-	        return;  /* interrupt has already been cleared */
-
-	disable_irq(irq);
-	ack_int(irq);
-
-	DEBUG_INT("malta_hw0_irqdispatch: irq=%d\n", irq);
-	action = hw0_irq_action[irq];
-
-	/* 
-	 * if action == NULL, then we don't have a handler 
-	 * for the irq 
-	 */
-	if ( action == NULL )
-		return;
-
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq + 8]++;
-	do {
-	        action->handler(irq, action->dev_id, regs);
-		action = action->next;
-	} while (action);
-
-	enable_irq(irq);
-	irq_exit(cpu, irq);
-}
-
-
-unsigned long probe_irq_on (void)
-{
-	unsigned int i, irqs = 0;
-	unsigned long delay;
-
-	/* first, enable any unassigned irqs */
-	for (i = MALTAINT_END-1; i > 0; i--) {
-		if (!hw0_irq_action[i]) {
-			enable_irq(i);
-			irqs |= (1 << i);
-		}
-	}
-
-	/* wait for spurious interrupts to mask themselves out again */
-	for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
-		/* about 100ms delay */;
-
-	/* now filter out any obviously spurious interrupts */
-	return irqs & ~cached_int_mask;
-}
-
-
-int probe_irq_off (unsigned long irqs)
-{
-	unsigned int i;
-
-	irqs &= cached_int_mask;
-	if (!irqs)
-		return 0;
-	i = ffz(~irqs);
-	if (irqs != (irqs & (1 << i)))
-		i = -i;
-
-	return i;
-}
-
-
-void __init maltaint_init(void)
-{
-        /* 
-	 * Mask out all interrupt by writing "1" to all bit position in 
-	 * the IMR register. 
-	 */
-	outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-
-	/* Now safe to set the exception vector. */
-	set_except_vector(0, mipsIRQ);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/malta/malta_rtc.c linux/arch/mips64/mips-boards/malta/malta_rtc.c
--- linux.orig/arch/mips64/mips-boards/malta/malta_rtc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/malta/malta_rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,50 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * RTC routines for Malta style attached PIIX4 device, which contains a
- * Motorola MC146818A-compatible Real Time Clock.
- *
- */
-#include <asm/mc146818rtc.h>
-#include <asm/mips-boards/malta.h>
-
-static unsigned char malta_rtc_read_data(unsigned long addr)
-{
-	outb(addr, MALTA_RTC_ADR_REG);
-	return inb(MALTA_RTC_DAT_REG);
-}
-
-static void malta_rtc_write_data(unsigned char data, unsigned long addr)
-{
-	outb(addr, MALTA_RTC_ADR_REG);
-	outb(data, MALTA_RTC_DAT_REG);
-}
-
-static int malta_rtc_bcd_mode(void)
-{
-	return 0;
-}
-
-struct rtc_ops malta_rtc_ops = {
-	&malta_rtc_read_data,
-	&malta_rtc_write_data,
-	&malta_rtc_bcd_mode
-};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mips-boards/malta/malta_setup.c linux/arch/mips64/mips-boards/malta/malta_setup.c
--- linux.orig/arch/mips64/mips-boards/malta/malta_setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mips-boards/malta/malta_setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,170 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Malta specific setup, including init of the feature struct.
- *
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/mc146818rtc.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#ifdef CONFIG_BLK_DEV_IDE
-#include <linux/ide.h>
-#endif
-
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/prom.h>
-#include <asm/mips-boards/gt64120.h>
-#include <asm/mips-boards/malta.h>
-#include <asm/mips-boards/maltaint.h>
-#ifdef CONFIG_BLK_DEV_FD
-#include <asm/floppy.h>
-#endif
-#include <asm/dma.h>
-#include <asm/mmu_context.h>
-
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
-extern void console_setup(char *, int *);
-char serial_console[20];
-#endif
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void set_debug_traps(void);
-extern void rs_kgdb_hook(int);
-extern void breakpoint(void);
-static int remote_debug = 0;
-#endif
-
-#ifdef CONFIG_BLK_DEV_IDE
-extern struct ide_ops std_ide_ops;
-#endif
-#ifdef CONFIG_BLK_DEV_FD
-extern struct fd_ops std_fd_ops;
-#endif
-extern struct rtc_ops malta_rtc_ops;
-
-extern void mips_reboot_setup(void);
-
-struct resource standard_io_resources[] = {
-	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
-	{ "pic1", 0x20, 0x3f, IORESOURCE_BUSY },
-	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
-	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
-	{ "pic2", 0xa0, 0xbf, IORESOURCE_BUSY },
-	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
-};
-
-#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
-
-static void __init malta_irq_setup(void)
-{
-  	maltaint_init();
-
-#ifdef CONFIG_REMOTE_DEBUG
-	if (remote_debug) {
-		set_debug_traps();
-		breakpoint(); 
-	}
-#endif
-}
-
-
-void __init malta_setup(void)
-{
-#ifdef CONFIG_REMOTE_DEBUG
-	int rs_putDebugChar(char);
-	char rs_getDebugChar(void);
-	extern int (*putDebugChar)(char);
-	extern char (*getDebugChar)(void);
-#endif
-	char *argptr;
-	int i;
-
-	current_cpu_data.asid_cache = ASID_FIRST_VERSION;
-	TLBMISS_HANDLER_SETUP();
-
-	irq_setup = malta_irq_setup;
-
-	/* Request I/O space for devices used on the Malta board. */
-	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
-		request_resource(&ioport_resource, standard_io_resources+i);
-
-	/* 
-	 * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge.
-	 */
-	enable_dma(4);
-
-#ifdef CONFIG_SERIAL_CONSOLE
-        argptr = prom_getcmdline();
-	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) 
-	{
-	        int i=0;
-	        char *s = prom_getenv("modetty0");
-		while(s[i] >= '0' && s[i] <= '9')
-			i++;
-		strcpy(serial_console, "ttyS0,");
-		strncpy(serial_console + 6, s, i);
-		prom_printf("Config serial console: %s\n", serial_console);
-	        console_setup(serial_console, NULL);
-	}
-#endif	  
-
-#ifdef CONFIG_REMOTE_DEBUG
-	argptr = prom_getcmdline();
-	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
-		int line;
-		argptr += strlen("kgdb=ttyS");
-		if (*argptr != '0' && *argptr != '1')
-			printk("KGDB: Uknown serial line /dev/ttyS%c, "
-			       "falling back to /dev/ttyS1\n", *argptr);
-		line = *argptr == '0' ? 0 : 1;
-		printk("KGDB: Using serial line /dev/ttyS%d for session\n",
-		       line ? 1 : 0);
-
-		rs_kgdb_hook(line);
-		putDebugChar = rs_putDebugChar;
-		getDebugChar = rs_getDebugChar;
-
-		prom_printf("KGDB: Using serial line /dev/ttyS%d for session, "
-			    "please connect your debugger\n", line ? 1 : 0);
-
-		remote_debug = 1;
-		/* Breakpoints and stuff are in malta_irq_setup() */
-	}
-#endif
-
-	argptr = prom_getcmdline();
-	if ((argptr = strstr(argptr, "nofpu")) != NULL)
-		mips_cpu.options &= ~MIPS_CPU_FPU;
-
-	rtc_ops = &malta_rtc_ops;
-#ifdef CONFIG_BLK_DEV_IDE
-        ide_ops = &std_ide_ops;
-#endif
-#ifdef CONFIG_BLK_DEV_FD
-        fd_ops = &std_fd_ops;
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/Makefile linux/arch/mips64/mm/Makefile
--- linux.orig/arch/mips64/mm/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips64/mm/Makefile	2002-07-20 01:08:21.000000000 +0000
@@ -2,16 +2,28 @@
 # Makefile for the Linux/MIPS-specific parts of the memory manager.
 #
 
+USE_STANDARD_AS_RULE := true
+
 O_TARGET := mm.o
 
 export-objs			+= umap.o
 obj-y				:= extable.o init.o fault.o loadmmu.o
 
-obj-$(CONFIG_CPU_R4300)		+= r4xx0.o
-obj-$(CONFIG_CPU_R4X00)		+= r4xx0.o
-obj-$(CONFIG_CPU_R5000)		+= r4xx0.o
-obj-$(CONFIG_CPU_NEVADA)	+= r4xx0.o
-obj-$(CONFIG_CPU_R10000)	+= andes.o
+obj-$(CONFIG_CPU_R4300)		+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o
+obj-$(CONFIG_CPU_R4X00)		+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o
+obj-$(CONFIG_CPU_R5000)		+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o
+obj-$(CONFIG_CPU_NEVADA)	+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o
+obj-$(CONFIG_CPU_R10000)	+= andes.o tlbex-r4k.o tlb-glue-r4k.o
+obj-$(CONFIG_CPU_SB1)		+= pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o \
+				   tlb-glue-r4k.o
+
+#
+# Debug TLB exception handler, currently unused
+#
+#obj-y				+=  tlb-dbg-r4k.o tlb-glue-r4k.o
+
 obj-$(CONFIG_SGI_IP22)		+= umap.o
 
+CFLAGS_tlb-glue-r4k.o := -P
+
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/andes.c linux/arch/mips64/mm/andes.c
--- linux.orig/arch/mips64/mm/andes.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/mips64/mm/andes.c	2002-07-20 01:08:23.000000000 +0000
@@ -15,7 +15,6 @@
 #include <asm/pgtable.h>
 #include <asm/r10kcache.h>
 #include <asm/system.h>
-#include <asm/sgialib.h>
 #include <asm/mmu_context.h>
 
 static int scache_lsz64;
@@ -43,9 +42,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page), "I" (PAGE_SIZE)
-		:"$1", "memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE)
+		: "memory");
 }
 
 /* R10000 has no Create_Dirty type cacheops.  */
@@ -97,8 +96,7 @@
  * This is only used during initialization time. vmalloc() also calls
  * this, but that will be changed pretty soon.
  */
-static void
-andes_flush_cache_l2(void)
+static void andes_flush_cache_l2(void)
 {
 	switch (sc_lsize()) {
 		case 64:
@@ -108,7 +106,7 @@
 			blast_scache128();
 			break;
 		default:
-			printk("Unknown L2 line size\n");
+			printk(KERN_EMERG "Unknown L2 line size\n");
 			while(1);
 	}
 }
@@ -132,8 +130,7 @@
 #define NTLB_ENTRIES       64
 #define NTLB_ENTRIES_HALF  32
 
-static inline void
-andes_flush_tlb_all(void)
+void local_flush_tlb_all(void)
 {
 	unsigned long flags;
 	unsigned long old_ctx;
@@ -145,7 +142,7 @@
 
 	__save_and_cli(flags);
 	/* Save old context and create impossible VPN2 value */
-	old_ctx = get_entryhi() & 0xff;
+	old_ctx = get_entryhi() & ASID_MASK;
 	set_entryhi(CKSEG0);
 	set_entrylo0(0);
 	set_entrylo1(0);
@@ -153,7 +150,7 @@
 	entry = get_wired();
 
 	/* Blast 'em all away. */
-	while(entry < NTLB_ENTRIES) {
+	while (entry < NTLB_ENTRIES) {
 		set_index(entry);
 		tlb_write_indexed();
 		entry++;
@@ -162,7 +159,7 @@
 	__restore_flags(flags);
 }
 
-static void andes_flush_tlb_mm(struct mm_struct *mm)
+void local_flush_tlb_mm(struct mm_struct *mm)
 {
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
 		unsigned long flags;
@@ -171,31 +168,32 @@
 		printk("[tlbmm<%d>]", mm->context);
 #endif
 		__save_and_cli(flags);
-		get_new_cpu_mmu_context(mm, smp_processor_id());
+		get_new_mmu_context(mm, smp_processor_id());
 		if(mm == current->mm)
-			set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
+			set_entryhi(CPU_CONTEXT(smp_processor_id(), mm)
+				    & ASID_MASK);
 		__restore_flags(flags);
 	}
 }
 
-static void
-andes_flush_tlb_range(struct mm_struct *mm, unsigned long start,
-                      unsigned long end)
+void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+                           unsigned long end)
 {
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
 		unsigned long flags;
 		int size;
 
 #ifdef DEBUG_TLB
-		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
-		       start, end);
+		printk("[tlbrange<%02x,%08lx,%08lx>]",
+		       (mm->context & ASID_MASK), start, end);
 #endif
 		__save_and_cli(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
-		if(size <= NTLB_ENTRIES_HALF) {
-			int oldpid = (get_entryhi() & 0xff);
-			int newpid = (CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
+		if (size <= NTLB_ENTRIES_HALF) {
+			int oldpid = (get_entryhi() & ASID_MASK);
+			int newpid = (CPU_CONTEXT(smp_processor_id(), mm)
+				      & ASID_MASK);
 
 			start &= (PAGE_MASK << 1);
 			end += ((PAGE_SIZE << 1) - 1);
@@ -216,17 +214,16 @@
 			}
 			set_entryhi(oldpid);
 		} else {
-			get_new_cpu_mmu_context(mm, smp_processor_id());
+			get_new_mmu_context(mm, smp_processor_id());
 			if(mm == current->mm)
-				set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 
-									0xff);
+				set_entryhi(CPU_CONTEXT(smp_processor_id(), mm)
+					    & ASID_MASK);
 		}
 		__restore_flags(flags);
 	}
 }
 
-static void
-andes_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
 	if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) {
 		unsigned long flags;
@@ -235,17 +232,18 @@
 #ifdef DEBUG_TLB
 		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
 #endif
-		newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff);
+		newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) &
+			  ASID_MASK);
 		page &= (PAGE_MASK << 1);
 		__save_and_cli(flags);
-		oldpid = (get_entryhi() & 0xff);
+		oldpid = (get_entryhi() & ASID_MASK);
 		set_entryhi(page | newpid);
 		tlb_probe();
 		idx = get_index();
 		set_entrylo0(0);
 		set_entrylo1(0);
 		set_entryhi(KSEG0);
-		if(idx < 0)
+		if (idx < 0)
 			goto finish;
 		tlb_write_indexed();
 
@@ -273,16 +271,17 @@
 	if (current->active_mm != vma->vm_mm)
 		return;
 
-	__save_and_cli(flags);
-	pid = get_entryhi() & 0xff;
+	pid = get_entryhi() & ASID_MASK;
 
-	if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) ||
-	   (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) {
-		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d "
-			"tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(),
-			vma->vm_mm) & 0xff), pid);
+	if ((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & ASID_MASK))
+	    || (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) {
+		printk(KERN_WARNING
+		       "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       __FUNCTION__, (int) (CPU_CONTEXT(smp_processor_id(),
+		       vma->vm_mm) & ASID_MASK), pid);
 	}
 
+	__save_and_cli(flags);
 	address &= (PAGE_MASK << 1);
 	set_entryhi(address | (pid));
 	pgdp = pgd_offset(vma->vm_mm, address);
@@ -293,7 +292,7 @@
 	set_entrylo0(pte_val(*ptep++) >> 6);
 	set_entrylo1(pte_val(*ptep) >> 6);
 	set_entryhi(address | (pid));
-	if(idx < 0) {
+	if (idx < 0) {
 		tlb_write_random();
 	} else {
 		tlb_write_indexed();
@@ -302,40 +301,8 @@
 	__restore_flags(flags);
 }
 
-static void andes_show_regs(struct pt_regs *regs)
-{
-	printk("Cpu %d\n", smp_processor_id());
-	/* Saved main processor registers. */
-	printk("$0      : %016lx %016lx %016lx %016lx\n",
-	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
-	printk("$4      : %016lx %016lx %016lx %016lx\n",
-               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
-	printk("$8      : %016lx %016lx %016lx %016lx\n",
-	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
-	printk("$12     : %016lx %016lx %016lx %016lx\n",
-               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
-	printk("$16     : %016lx %016lx %016lx %016lx\n",
-	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
-	printk("$20     : %016lx %016lx %016lx %016lx\n",
-               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
-	printk("$24     : %016lx %016lx\n",
-	       regs->regs[24], regs->regs[25]);
-	printk("$28     : %016lx %016lx %016lx %016lx\n",
-	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
-	printk("Hi      : %016lx\n", regs->hi);
-	printk("Lo      : %016lx\n", regs->lo);
-
-	/* Saved cp0 registers. */
-	printk("epc     : %016lx    %s\nbadvaddr: %016lx\n",
-	       regs->cp0_epc, print_tainted(), regs->cp0_badvaddr);
-	printk("Status  : %08x\nCause   : %08x\n",
-	       (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
-}
-
 void __init ld_mmu_andes(void)
 {
-	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
-
 	printk("Primary instruction cache %dkb, linesize %d bytes\n",
 	       icache_size >> 10, ic_lsize);
 	printk("Primary data cache %dkb, linesize %d bytes\n",
@@ -350,11 +317,6 @@
 	_flush_cache_l2 = andes_flush_cache_l2;
 	_flush_cache_sigtramp = andes_flush_cache_sigtramp;
 
-	_flush_tlb_all = andes_flush_tlb_all;
-	_flush_tlb_mm = andes_flush_tlb_mm;
-	_flush_tlb_range = andes_flush_tlb_range;
-	_flush_tlb_page = andes_flush_tlb_page;
-
 	switch (sc_lsize()) {
 		case 64:
 			scache_lsz64 = 1;
@@ -363,13 +325,11 @@
 			scache_lsz64 = 0;
 			break;
 		default:
-			printk("Unknown L2 line size\n");
+			printk(KERN_EMERG "Unknown L2 line size\n");
 			while(1);
 	}
     
-	update_mmu_cache = andes_update_mmu_cache;
-
-	_show_regs = andes_show_regs;
+	_update_mmu_cache = andes_update_mmu_cache;
 
         flush_cache_l1();
 
@@ -381,9 +341,10 @@
 	 *     be set for 4kb pages.
 	 */
 	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+	write_32bit_cp0_register(CP0_FRAMEMASK, 0);
 
         /* From this point on the ARC firmware is dead.  */
-	_flush_tlb_all();
+	local_flush_tlb_all();
 
-        /* Did I tell you that ARC SUCKS?  */
+	/* Did I tell you that ARC SUCKS?  */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/c-sb1.c linux/arch/mips64/mm/c-sb1.c
--- linux.orig/arch/mips64/mm/c-sb1.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/mm/c-sb1.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */ 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/mmu_context.h>
+#include <asm/bootinfo.h>
+#include <asm/cacheops.h>
+#include <asm/cpu.h>
+#include <asm/uaccess.h>
+
+/* These are probed at ld_mmu time */
+static unsigned long icache_size;
+static unsigned long dcache_size;
+
+static unsigned long icache_line_size;
+static unsigned long dcache_line_size;
+
+static unsigned int icache_index_mask;
+
+static unsigned long icache_assoc;
+static unsigned long dcache_assoc;
+
+static unsigned int icache_sets;
+static unsigned int dcache_sets;
+
+/*
+ * The dcache is fully coherent to the system, with one
+ * big caveat:  the instruction stream.  In other words,
+ * if we miss in the icache, and have dirty data in the
+ * L1 dcache, then we'll go out to memory (or the L2) and
+ * get the not-as-recent data.
+ * 
+ * So the only time we have to flush the dcache is when
+ * we're flushing the icache.  Since the L2 is fully
+ * coherent to everything, including I/O, we never have
+ * to flush it
+ */
+
+static void sb1_flush_cache_all(void)
+{
+}
+
+static inline void local_sb1___flush_dcache_all(void)
+{
+	/*
+	 * Haven't worried too much about speed here; given that we're flushing
+	 * the icache, the time to invalidate is dwarfed by the time it's going
+	 * to take to refill it.  Register usage:
+	 * 
+	 * $1 - moving cache index
+	 * $2 - set count
+	 */
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %2         \n" /* Start at index 0 */
+		"1:   cache  %3, 0($1)      \n" /* WB/Invalidate this index */
+		"     daddiu  %1, %1, -1     \n" /* Decrement loop count */
+		"     bnez   %1, 1b         \n" /* loop test */
+		"      daddu   $1, $1, %0    \n" /* Next address */
+		".set pop                   \n"
+		:
+		: "r" (dcache_line_size), "r" (dcache_sets * dcache_assoc),
+		  "r" (KSEG0), "i" (Index_Writeback_Inv_D));
+
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set mips2                 \n"
+		"sync                       \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */			
+		"sync                       \n"
+#endif
+		".set pop                   \n");
+}
+
+static inline void local_sb1___flush_icache_all(void)
+{
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %2         \n" /* Start at index 0 */
+		"1:   cache  %3, 0($1)       \n" /* Invalidate this index */
+		"     daddiu  %1, %1, -1     \n" /* Decrement loop count */
+		"     bnez   %1, 1b         \n" /* loop test */
+		"      daddu   $1, $1, %0    \n" /* Next address */
+		".set pop                   \n"
+		:
+		: "r" (icache_line_size), "r" (icache_sets * icache_assoc),
+		  "r" (KSEG0), "i" (Index_Invalidate_I));
+}
+
+static void local_sb1___flush_cache_all(void)
+{
+	local_sb1___flush_dcache_all();
+	local_sb1___flush_icache_all();
+}
+
+#ifdef CONFIG_SMP
+extern void sb1___flush_cache_all_ipi(void *ignored);
+asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all");
+
+static void sb1___flush_cache_all(void)
+{
+	smp_call_function(sb1___flush_cache_all_ipi, 0, 1, 1);
+	local_sb1___flush_cache_all();
+}
+#else
+extern void sb1___flush_cache_all(void);
+asm("sb1___flush_cache_all = local_sb1___flush_cache_all");
+#endif
+
+
+/*
+ * When flushing a range in the icache, we have to first writeback
+ * the dcache for the same range, so new ifetches will see any
+ * data that was dirty in the dcache.
+ *
+ * The start/end arguments are expected to be Kseg addresses.
+ */
+
+static void local_sb1_flush_icache_range(unsigned long start,
+	unsigned long end)
+{
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	unsigned long flags;
+	local_irq_save(flags);
+#endif
+
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %0         \n" 
+		"1:                         \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+		".align 3                   \n"
+		"     lw     $0,   0($1)    \n" /* Bug 1370, 1368            */
+		"     sync                  \n"
+#endif
+		"     cache  %3, 0($1)      \n" /* Hit-WB{,-inval} this address */
+		"     bne    $1, %1, 1b     \n" /* loop test */
+		"      daddu  $1, $1, %2    \n" /* next line */
+		".set pop                   \n"
+		:
+		: "r" ((start + dcache_line_size - 1)  & ~(dcache_line_size - 1)),
+		  "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)),
+		  "r" (dcache_line_size),
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+		  "i" (Hit_Writeback_Inv_D)
+#else
+		  "i" (Hit_Writeback_D)
+#endif
+		);
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set mips2                 \n"
+		"sync                       \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */
+		"sync                       \n"
+#endif
+		".set pop                   \n");
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	local_irq_restore(flags);
+#endif
+
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %0         \n" 
+		".align 3                   \n"
+		"1:   cache  %3, (0<<13)($1) \n" /* Index-inval this address */
+		"     cache  %3, (1<<13)($1) \n" /* Index-inval this address */
+		"     cache  %3, (2<<13)($1) \n" /* Index-inval this address */
+		"     cache  %3, (3<<13)($1) \n" /* Index-inval this address */
+		"     bne    $1, %1, 1b     \n" /* loop test */
+		"      daddu  $1, $1, %2     \n" /* next line */
+		".set pop                   \n"
+		:
+		: "r" (start & ~(icache_line_size - 1)),
+		  "r" ((end - 1) & ~(icache_line_size - 1)),
+		  "r" (icache_line_size),
+		  "i" (Index_Invalidate_I));
+}
+
+#ifdef CONFIG_SMP
+struct flush_icache_range_args {
+	unsigned long start;
+	unsigned long end;
+};
+
+static void sb1_flush_icache_range_ipi(void *info)
+{
+	struct flush_icache_range_args *args = info;
+
+	local_sb1_flush_icache_range(args->start, args->end);
+}
+
+void sb1_flush_icache_range(unsigned long start, unsigned long end)
+{
+	struct flush_icache_range_args args;
+
+	args.start = start;
+	args.end = end;
+	smp_call_function(sb1_flush_icache_range_ipi, &args, 1, 1);
+	local_sb1_flush_icache_range(start, end);
+}
+#else
+void sb1_flush_icache_range(unsigned long start, unsigned long end);
+asm("sb1_flush_icache_range = local_sb1_flush_icache_range");
+#endif
+
+/*
+ * If there's no context yet, or the page isn't executable, no icache flush
+ * is needed
+ *
+ * This is broken.  If there is no context yet we still have to writeback
+ * the d-cache to memory.
+ */
+static void sb1_flush_icache_page(struct vm_area_struct *vma,
+	struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC)) {
+		return;
+	}
+
+	/*
+	 * We're not sure of the virtual address(es) involved here, so
+	 * conservatively flush the entire caches on all processors
+	 * (ouch).
+	 *
+	 * Bumping the ASID may well be cheaper, need to experiment ...
+	 */
+	sb1___flush_cache_all();
+}
+
+static inline void protected_flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		"    .set push                \n"
+		"    .set noreorder           \n"
+		"    .set mips4               \n"
+		"1:  cache %1, (%0)           \n"
+		"2:  .set pop                 \n"
+		"    .section __ex_table,\"a\"\n"
+		"     .dword  1b, 2b          \n"
+		"     .previous"
+		:
+		: "r" (addr), "i" (Hit_Invalidate_I));
+}
+
+static inline void protected_writeback_dcache_line(unsigned long addr)
+{
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	/* Have to be sure the TLB entry exists for the cache op, 
+	   so we have to be sure that nothing happens in between the
+	   lw and the cache op 
+	*/
+	unsigned long flags;
+	local_irq_save(flags);
+#endif
+	__asm__ __volatile__(
+		"    .set push                \n"
+		"    .set noreorder           \n"
+		"    .set mips4               \n"
+		"                             \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+		"1:   lw    $0,   (%0)        \n"
+		"     sync                    \n"
+		"     .section __ex_table,\"a\"\n"
+		"     .dword  1b, 3f           \n"
+		"     .previous               \n"
+#endif
+		"2:   cache  %1, 0(%0)    \n" /* Hit-WB{-inval} this address */
+		/* XXX: should be able to do this after both dcache cache
+		   ops, but there's no guarantee that this will be inlined,
+		   and the pass1 restriction checker can't detect syncs
+		   following cache ops except in the following basic block.
+		*/
+		"     sync                    \n"
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */
+		"     sync                    \n"
+#endif
+		"3:  .set pop                 \n"
+		"    .section __ex_table,\"a\"\n"
+		"     .dword  2b, 3b          \n"
+		"     .previous"
+		:
+		: "r" (addr),
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+		  "i" (Hit_Writeback_Inv_D)
+#else
+		  "i" (Hit_Writeback_D)
+#endif
+		  );
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	local_irq_restore(flags);
+#endif
+}
+
+/*
+ * A signal trampoline must fit into a single cacheline.
+ */
+static void local_sb1_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long daddr, iaddr;
+
+	daddr = addr & ~(dcache_line_size - 1);
+	protected_writeback_dcache_line(daddr);
+	iaddr = addr & ~(icache_line_size - 1);
+	protected_flush_icache_line(iaddr);
+}
+
+#ifdef CONFIG_SMP
+static void sb1_flush_cache_sigtramp_ipi(void *info)
+{
+	unsigned long iaddr = (unsigned long) info;
+
+	iaddr = iaddr & ~(icache_line_size - 1);
+	protected_flush_icache_line(iaddr);
+}
+
+static void sb1_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long tmp;
+
+	/*
+	 * Flush the local dcache, then load the instruction back into a
+	 * register.  That will make sure that any remote CPU also has
+	 * written back it's data cache to memory.
+	 */
+	local_sb1_flush_cache_sigtramp(addr);
+	__get_user(tmp, (unsigned long *)addr);
+
+	smp_call_function(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
+}
+#else
+void sb1_flush_cache_sigtramp(unsigned long addr);
+asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp");
+#endif
+
+static void sb1_flush_icache_all(void)
+{
+	/*
+	 * Haven't worried too much about speed here; given that we're flushing
+	 * the icache, the time to invalidate is dwarfed by the time it's going
+	 * to take to refill it.  Register usage:
+	 * 
+	 * $1 - moving cache index
+	 * $2 - set count
+	 */
+	__asm__ __volatile__ (
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     move   $1, %2         \n" /* Start at index 0 */
+		"1:   cache  %3, 0($1)      \n" /* Invalidate this index */
+		"     daddiu  %1, %1, -1     \n" /* Decrement loop count */
+		"     bnez   %1, 1b         \n" /* loop test */
+		"      daddu   $1, $1, %0    \n" /* Next address */
+		".set pop                   \n"
+		:
+		: "r" (icache_line_size), "r" (icache_sets * icache_assoc),
+		  "r" (KSEG0), "i" (Index_Invalidate_I));
+}
+
+/*
+ * Anything that just flushes dcache state can be ignored, as we're always
+ * coherent in dcache space.  This is just a dummy function that all the
+ * nop'ed routines point to
+ */
+
+static void sb1_nop(void)
+{
+}
+
+/*
+ * This only needs to make sure stores done up to this
+ * point are visible to other agents outside the CPU.  Given 
+ * the coherent nature of the ZBbus, all that's required here is 
+ * a sync to make sure the data gets out to the caches and is
+ * visible to an arbitrary A Phase from an external agent 
+ *   
+ * Actually, I'm not even sure that's necessary; the semantics
+ * of this function aren't clear.  If it's supposed to serve as
+ * a memory barrier, this is needed.  If it's only meant to 
+ * prevent data from being invisible to non-cpu memory accessors
+ * for some indefinite period of time (e.g. in a non-coherent 
+ * dcache) then this function would be a complete nop.
+ */
+static void sb1_flush_page_to_ram(struct page *page)
+{
+	__asm__ __volatile__(
+		"     sync  \n"  /* Short pipe */
+		:::"memory");	
+}
+
+/*
+ *  Cache set values (from the mips64 spec)
+ * 0 - 64
+ * 1 - 128
+ * 2 - 256
+ * 3 - 512
+ * 4 - 1024
+ * 5 - 2048
+ * 6 - 4096
+ * 7 - Reserved
+ */
+  
+static unsigned int decode_cache_sets(unsigned int config_field)
+{
+	if (config_field == 7) {
+		/* JDCXXX - Find a graceful way to abort. */
+		return 0;
+	} 
+	return (1<<(config_field + 6));
+}
+
+/*
+ *  Cache line size values (from the mips64 spec)
+ * 0 - No cache present.
+ * 1 - 4 bytes
+ * 2 - 8 bytes
+ * 3 - 16 bytes
+ * 4 - 32 bytes
+ * 5 - 64 bytes
+ * 6 - 128 bytes
+ * 7 - Reserved
+ */
+
+static unsigned int decode_cache_line_size(unsigned int config_field)
+{
+	if (config_field == 0) {
+		return 0;
+	} else if (config_field == 7) {
+		/* JDCXXX - Find a graceful way to abort. */
+		return 0;
+	} 
+	return (1<<(config_field + 1));
+}
+
+/*
+ * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs)
+ *
+ * 24:22 Icache sets per way
+ * 21:19 Icache line size
+ * 18:16 Icache Associativity
+ * 15:13 Dcache sets per way
+ * 12:10 Dcache line size
+ * 9:7   Dcache Associativity
+ */
+
+static __init void probe_cache_sizes(void)
+{
+	u32 config1;
+
+	config1 = read_mips32_cp0_config1();
+	icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7);
+	dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7);
+	icache_sets = decode_cache_sets((config1 >> 22) & 0x7);
+	dcache_sets = decode_cache_sets((config1 >> 13) & 0x7);
+	icache_assoc = ((config1 >> 16) & 0x7) + 1;
+	dcache_assoc = ((config1 >> 7) & 0x7) + 1;
+	icache_size = icache_line_size * icache_sets * icache_assoc;
+	dcache_size = dcache_line_size * dcache_sets * dcache_assoc;
+	icache_index_mask = (icache_sets - 1) * icache_line_size;
+}
+
+/*
+ * This is called from loadmmu.c.  We have to set up all the
+ * memory management function pointers, as well as initialize
+ * the caches and tlbs
+ */
+void ld_mmu_sb1(void)
+{
+	probe_cache_sizes();
+
+	_clear_page = sb1_clear_page;
+	_copy_page = sb1_copy_page;
+
+	_flush_cache_all = sb1_flush_cache_all;
+	___flush_cache_all = sb1___flush_cache_all;
+	_flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop;
+	_flush_cache_range = (void *) sb1_nop;
+	_flush_page_to_ram = sb1_flush_page_to_ram;
+	_flush_icache_page = sb1_flush_icache_page;
+	_flush_icache_range = sb1_flush_icache_range;
+
+	/* None of these are needed for the sb1 */
+	_flush_cache_page = (void *) sb1_nop;
+
+	_flush_cache_sigtramp = sb1_flush_cache_sigtramp;
+	_flush_icache_all = sb1_flush_icache_all;
+
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
+	flush_cache_all();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/fault.c linux/arch/mips64/mm/fault.c
--- linux.orig/arch/mips64/mm/fault.c	2001-09-17 04:22:50.000000000 +0000
+++ linux/arch/mips64/mm/fault.c	2002-07-20 01:08:22.000000000 +0000
@@ -21,6 +21,7 @@
 #include <linux/smp_lock.h>
 #include <linux/version.h>
 
+#include <asm/branch.h>
 #include <asm/hardirq.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
@@ -31,22 +32,19 @@
 
 #define development_version (LINUX_VERSION_CODE & 0x100)
 
-extern void die(char *, struct pt_regs *, unsigned long write);
-
 /*
  * Macro for exception fixup code to access integer registers.
  */
 #define dpf_reg(r) (regs->regs[r])
 
-asmlinkage void
-dodebug(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void dodebug(abi64_no_regargs, struct pt_regs regs)
 {
-	printk("Got syscall %ld, cpu %d proc %s:%d epc 0x%lx\n", regs.regs[2],
-	       smp_processor_id(), current->comm, current->pid, regs.cp0_epc);
+	printk(KERN_DEBUG "Got syscall %ld, cpu %d proc %s:%d epc 0x%lx\n",
+	       regs.regs[2], smp_processor_id(), current->comm, current->pid,
+	       regs.cp0_epc);
 }
 
-asmlinkage void
-dodebug2(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void dodebug2(abi64_no_regargs, struct pt_regs regs)
 {
 	unsigned long retaddr;
 
@@ -55,7 +53,8 @@
 		"add %0,$0,$31\n\t"
 		".set reorder"
 		: "=r" (retaddr));
-	printk("Got exception 0x%lx at 0x%lx\n", retaddr, regs.cp0_epc);
+	printk(KERN_DEBUG "Got exception 0x%lx at 0x%lx\n", retaddr,
+	       regs.cp0_epc);
 }
 
 extern spinlock_t timerlist_lock;
@@ -70,6 +69,10 @@
 	spin_lock_init(&timerlist_lock);
 	if (yes) {
 		oops_in_progress = 1;
+#ifdef CONFIG_SMP
+		/* Many serial drivers do __global_cli() */
+		global_irq_lock = SPIN_LOCK_UNLOCKED;
+#endif
 	} else {
 		int loglevel_save = console_loglevel;
 #ifdef CONFIG_VT
@@ -92,8 +95,8 @@
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  */
-asmlinkage void
-do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address)
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+			      unsigned long address)
 {
 	struct vm_area_struct * vma;
 	struct task_struct *tsk = current;
@@ -101,6 +104,11 @@
 	unsigned long fixup;
 	siginfo_t info;
 
+#if 0
+	printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(),
+		current->comm, current->pid, address, write, regs->cp0_epc);
+#endif
+
 	/*
 	 * We fault-in kernel-space virtual memory on-demand. The
 	 * 'reference' page table is init_mm.pgd.
@@ -110,7 +118,7 @@
 	 * only copy the information from the master page table,
 	 * nothing more.
 	 */
-	if (address >= TASK_SIZE)
+	if (address >= VMALLOC_START)
 		goto vmalloc_fault;
 
 	info.si_code = SEGV_MAPERR;
@@ -120,10 +128,7 @@
 	 */
 	if (in_interrupt() || mm == &init_mm)
 		goto no_context;
-#if DEBUG_MIPS64
-	printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(), current->comm,
-		current->pid, address, write, regs->cp0_epc);
-#endif
+
 	down_read(&mm->mmap_sem);
 	vma = find_vma(mm, address);
 	if (!vma)
@@ -149,6 +154,7 @@
 			goto bad_area;
 	}
 
+survive:
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
@@ -177,7 +183,6 @@
 bad_area:
 	up_read(&mm->mmap_sem);
 
-bad_area_nosemaphore:
 	if (user_mode(regs)) {
 		tsk->thread.cp0_badvaddr = address;
 		tsk->thread.error_code = write;
@@ -189,6 +194,7 @@
 		       address,
 		       (unsigned long) regs->cp0_epc,
 		       (unsigned long) regs->regs[31]);
+while(1);
 #endif
 		info.si_signo = SIGSEGV;
 		info.si_errno = 0;
@@ -200,7 +206,7 @@
 
 no_context:
 	/* Are we prepared to handle this kernel fault?  */
-	fixup = search_exception_table(regs->cp0_epc);
+	fixup = search_exception_table(exception_epc(regs));
 	if (fixup) {
 		long new_epc;
 
@@ -221,12 +227,9 @@
 	bust_spinlocks(1);
 
 	printk(KERN_ALERT "Cpu %d Unable to handle kernel paging request at "
-	       "address %08lx, epc == %08x, ra == %08x\n",
-	       smp_processor_id(), address, (unsigned int) regs->cp0_epc,
-               (unsigned int) regs->regs[31]);
+	       "address %016lx, epc == %016lx, ra == %016lx\n",
+	       smp_processor_id(), address, regs->cp0_epc, regs->regs[31]);
 	die("Oops", regs, write);
-	do_exit(SIGKILL);
-	bust_spinlocks(0);
 
 /*
  * We ran out of memory, or some other thing happened to us that made
@@ -234,7 +237,13 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	printk("VM: killing process %s\n", tsk->comm);
+	if (tsk->pid == 1) {
+		tsk->policy |= SCHED_YIELD;
+		schedule();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	printk(KERN_NOTICE "VM: killing process %s\n", tsk->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
@@ -247,7 +256,7 @@
 	 * or user mode.
 	 */
 	tsk->thread.cp0_badvaddr = address;
-	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/mips64/mm/init.c linux/arch/mips64/mm/init.c
--- linux.orig/arch/mips64/mm/init.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/mips64/mm/init.c	2002-07-20 01:08:26.000000000 +0000
@@ -32,14 +32,11 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
-#ifdef CONFIG_SGI_IP22
-#include <asm/sgialib.h>
-#endif
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
+#include <asm/cpu.h>
 
 mmu_gather_t mmu_gathers[NR_CPUS];
-
 unsigned long totalram_pages;
 
 void pgd_init(unsigned long page)
@@ -135,7 +132,7 @@
 	unsigned long order, size;
 	struct page *page;
 
-	switch (mips_cputype) {
+	switch (mips_cpu.cputype) {
 	case CPU_R4000SC:
 	case CPU_R4000MC:
 	case CPU_R4400SC:
@@ -164,157 +161,6 @@
 	return 1UL << order;
 }
 
-void __init add_memory_region(unsigned long start, unsigned long size,
-                              long type)
-{
-        int x = boot_mem_map.nr_map;
-
-        if (x == BOOT_MEM_MAP_MAX) {
-                printk("Ooops! Too many entries in the memory map!\n");
-                return;
-        }
-
-        boot_mem_map.map[x].addr = start;
-        boot_mem_map.map[x].size = size;
-        boot_mem_map.map[x].type = type;
-        boot_mem_map.nr_map++;
-}
-
-static void __init print_memory_map(void)
-{
-        int i;
-
-        for (i = 0; i < boot_mem_map.nr_map; i++) {
-                printk(" memory: %08lx @ %08lx ",
-                        boot_mem_map.map[i].size, boot_mem_map.map[i].addr);
-                switch (boot_mem_map.map[i].type) {
-                case BOOT_MEM_RAM:
-                        printk("(usable)\n");
-                        break;
-                case BOOT_MEM_ROM_DATA:
-                        printk("(ROM data)\n");
-                        break;
-                case BOOT_MEM_RESERVED:
-                        printk("(reserved)\n");
-                        break;
-                default:
-                        printk("type %lu\n", boot_mem_map.map[i].type);
-                        break;
-                }
-        }
-}
-
-void bootmem_init(void) {
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long tmp;
-	unsigned long *initrd_header;
-#endif
-	unsigned long bootmap_size;
-	unsigned long start_pfn, max_pfn;
-	int i;
-	extern int _end;
-
-#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
-
-	/*
-	 * Partially used pages are not usable - thus
-	 * we are rounding upwards.
-	 */
-	start_pfn = PFN_UP(__pa(&_end));
-
-	/* Find the highest page frame number we have available.  */
-	max_pfn = 0;
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long start, end;
-
-		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
-			continue;
-
-		start = PFN_UP(boot_mem_map.map[i].addr);
-		end = PFN_DOWN(boot_mem_map.map[i].addr
-		      + boot_mem_map.map[i].size);
-
-		if (start >= end)
-			continue;
-		if (end > max_pfn)
-			max_pfn = end;
-	}
-
-	/* Initialize the boot-time allocator.  */
-	bootmap_size = init_bootmem(start_pfn, max_pfn);
-
-	/*
-	 * Register fully available low RAM pages with the bootmem allocator.
-	 */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long curr_pfn, last_pfn, size;
-
-		/*
-		 * Reserve usable memory.
-		 */
-		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
-			continue;
-
-		/*
-		 * We are rounding up the start address of usable memory:
-		 */
-		curr_pfn = PFN_UP(boot_mem_map.map[i].addr);
-		if (curr_pfn >= max_pfn)
-			continue;
-		if (curr_pfn < start_pfn)
-			curr_pfn = start_pfn;
-
-		/*
-		 * ... and at the end of the usable range downwards:
-		 */
-		last_pfn = PFN_DOWN(boot_mem_map.map[i].addr
-				    + boot_mem_map.map[i].size);
-
-		if (last_pfn > max_pfn)
-			last_pfn = max_pfn;
-
-		/*
-		 * ... finally, did all the rounding and playing
-		 * around just make the area go away?
-		 */
-		if (last_pfn <= curr_pfn)
-			continue;
-
-		size = last_pfn - curr_pfn;
-		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
-	}
-
-	/* Reserve the bootmap memory.  */
-	reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size);
-
-#ifdef CONFIG_BLK_DEV_INITRD
-#error "Initrd is broken, please fit it."
-	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
-	if (tmp < (unsigned long)&_end)
-		tmp += PAGE_SIZE;
-	initrd_header = (unsigned long *)tmp;
-	if (initrd_header[0] == 0x494E5244) {
-		initrd_start = (unsigned long)&initrd_header[2];
-		initrd_end = initrd_start + initrd_header[1];
-		initrd_below_start_ok = 1;
-		if (initrd_end > memory_end) {
-			printk("initrd extends beyond end of memory "
-			       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-			       initrd_end,memory_end);
-			initrd_start = 0;
-		} else
-			*memory_start_p = initrd_end;
-	}
-#endif
-
-#undef PFN_UP
-#undef PFN_DOWN
-#undef PFN_PHYS
-
-}
-
 void show_mem(void)
 {
 	int i, free = 0, total = 0, reserved = 0;
@@ -367,7 +213,7 @@
 	max_dma =  virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 	low = max_low_pfn;
 
-#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+#ifdef CONFIG_ISA
 	if (low < max_dma)
 		zones_size[ZONE_DMA] = low;
 	else {
@@ -379,7 +225,7 @@
 #endif
 
 	free_area_init(zones_size);
-	
+
 	memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER);
 	memset((void *)kpmdtbl, 0, PAGE_SIZE);
 	pgd_set(swapper_pg_dir, kpmdtbl);
@@ -387,14 +233,38 @@
 		pmd_val(*pmd) = (unsigned long)pte;
 }
 
-extern int page_is_ram(unsigned long pagenr);
+//extern int page_is_ram(unsigned long pagenr);
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+
+static inline int page_is_ram(unsigned long pagenr)
+{
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+	unsigned long addr, end;
+
+	if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+		/* not usable memory */
+		continue;
+
+	addr = PFN_UP(boot_mem_map.map[i].addr);
+	end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size);
+
+	if (pagenr >= addr && pagenr < end)
+		return 1;
+	}
+
+	return 0;
+}
 
 void __init mem_init(void)
 {
 	unsigned long codesize, reservedpages, datasize, initsize;
 	unsigned long tmp, ram;
 
-	max_mapnr = num_physpages = max_low_pfn;
+	max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
 	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
 
 	totalram_pages += free_all_bootmem();
@@ -412,8 +282,8 @@
 	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
-	       "%ldk data, %ldk init)\n",
+	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
+	       "%ldk reserved, %ldk data, %ldk init)\n",
 	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 	       ram << (PAGE_SHIFT-10),
 	       codesize >> 10,
@@ -432,7 +302,8 @@
 		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
 
@@ -455,7 +326,7 @@
 		totalram_pages++;
 		addr += PAGE_SIZE;
 	}
-	printk("Freeing unused kernel memory: %ldk freed\n",
+	printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n",
 	       (&__init_end - &__init_begin) >> 10);
 }
 
@@ -463,7 +334,7 @@
 si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = atomic_read(&shmem_nrpages);
+	val->sharedram = 0;
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/loadmmu.c linux/arch/mips64/mm/loadmmu.c
--- linux.orig/arch/mips64/mm/loadmmu.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/mm/loadmmu.c	2002-07-20 01:08:21.000000000 +0000
@@ -17,21 +17,26 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/bootinfo.h>
-#include <asm/sgialib.h>
+#include <asm/cpu.h>
 
 /* memory functions */
 void (*_clear_page)(void * page);
 void (*_copy_page)(void * to, void * from);
 
 /* Cache operations. */
+void (*_flush_cache_all)(void);
+void (*___flush_cache_all)(void);
 void (*_flush_cache_mm)(struct mm_struct *mm);
 void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
                            unsigned long end);
 void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
+void (*_flush_cache_sigtramp)(unsigned long addr);
+void (*_flush_icache_range)(unsigned long start, unsigned long end);
+void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page);
 void (*_flush_page_to_ram)(struct page * page);
+void (*_flush_icache_all)(void);
 
 /* MIPS specific cache operations */
-void (*_flush_cache_sigtramp)(unsigned long addr);
 void (*_flush_cache_l2)(void);
 void (*_flush_cache_l1)(void);
 
@@ -41,25 +46,18 @@
 void (*_dma_cache_wback)(unsigned long start, unsigned long size);
 void (*_dma_cache_inv)(unsigned long start, unsigned long size);
 
-/* TLB operations. */
-void (*_flush_tlb_all)(void);
-void (*_flush_tlb_mm)(struct mm_struct *mm);
-void (*_flush_tlb_range)(struct mm_struct *mm, unsigned long start,
-			unsigned long end);
-void (*_flush_tlb_page)(struct vm_area_struct *vma, unsigned long page);
-
 /* Miscellaneous. */
-void (*update_mmu_cache)(struct vm_area_struct * vma,
-			 unsigned long address, pte_t pte);
-
-void (*_show_regs)(struct pt_regs *);
+void (*_update_mmu_cache)(struct vm_area_struct * vma,
+	unsigned long address, pte_t pte);
 
 extern void ld_mmu_r4xx0(void);
 extern void ld_mmu_andes(void);
+extern void ld_mmu_sb1(void);
+extern void sb1_tlb_init(void);
 
 void __init load_mmu(void)
 {
-	switch(mips_cputype) {
+	switch(mips_cpu.cputype) {
 #if defined (CONFIG_CPU_R4300)						\
     || defined (CONFIG_CPU_R4X00)					\
     || defined (CONFIG_CPU_R5000)					\
@@ -79,17 +77,23 @@
 	case CPU_R5000:
 	case CPU_R5000A:
 	case CPU_NEVADA:
-		printk("Loading R4000 MMU routines.\n");
+		printk(KERN_INFO "Loading R4000 MMU routines.\n");
 		ld_mmu_r4xx0();
 		break;
 #endif
-
-#if defined (CONFIG_CPU_R10000)
+#ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
-		printk("Loading R10000 MMU routines.\n");
+		printk(KERN_INFO "Loading R10000 MMU routines.\n");
 		ld_mmu_andes();
 		break;
 #endif
+#if defined CONFIG_CPU_SB1
+	case CPU_SB1:
+		printk(KERN_INFO "Loading SB1 MMU routines.\n");
+		ld_mmu_sb1();
+		sb1_tlb_init();
+		break;
+#endif
 
 	default:
 		/* XXX We need an generic routine in the MIPS port
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/pg-sb1.c linux/arch/mips64/mm/pg-sb1.c
--- linux.orig/arch/mips64/mm/pg-sb1.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/mm/pg-sb1.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000 Sibyte
+ * 
+ * Written by Justin Carlson (carlson@sibyte.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 <asm/page.h>
+
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+#define SB1_PREF_LOAD_STREAMED_HINT "0"
+#define SB1_PREF_STORE_STREAMED_HINT "1"
+#else
+#define SB1_PREF_LOAD_STREAMED_HINT "4"
+#define SB1_PREF_STORE_STREAMED_HINT "5"
+#endif
+
+/* These are the functions hooked by the memory management function pointers */
+void sb1_clear_page(void *page)
+{
+	/*
+	 * JDCXXX - This should be bottlenecked by the write buffer, but these
+	 * things tend to be mildly unpredictable...should check this on the
+	 * performance model
+	 *
+	 * We prefetch 4 lines ahead.  We're also "cheating" slightly here...
+	 * since we know we're on an SB1, we force the assembler to take 
+	 * 64-bit operands to speed things up
+	 */
+	__asm__ __volatile__(
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     daddiu     $1, %0, %2  \n"  /* Calculate the end of the page to clear */
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%0)  \n"  /* Prefetch the first 4 lines */
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 32(%0)  \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 64(%0)  \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%0)  \n"  
+		"1:   sd        $0,  0(%0)  \n"  /* Throw out a cacheline of 0's */
+		"     sd        $0,  8(%0)  \n"
+		"     sd        $0, 16(%0)  \n"
+		"     sd        $0, 24(%0)  \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",128(%0)  \n"  /* Prefetch 4 lines ahead     */
+		"     bne       $1, %0, 1b  \n"
+		"      daddiu     %0, %0, 32\n"  /* Next cacheline (This instruction better be short piped!) */
+		".set pop                   \n"
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE-32)
+		: "memory");
+
+}
+
+void sb1_copy_page(void *to, void *from)
+{
+	/*
+	 * This should be optimized in assembly...can't use ld/sd, though,
+	 * because the top 32 bits could be nuked if we took an interrupt
+	 * during the routine.	And this is not a good place to be cli()'ing 
+	 *
+	 * The pref's used here are using "streaming" hints, which cause the
+	 * copied data to be kicked out of the cache sooner.  A page copy often
+	 * ends up copying a lot more data than is commonly used, so this seems
+	 * to make sense in terms of reducing cache pollution, but I've no real
+	 * performance data to back this up
+	 */
+
+	__asm__ __volatile__(
+		".set push                  \n"
+		".set noreorder             \n"
+		".set noat                  \n"
+		".set mips4                 \n"
+		"     daddiu     $1, %0, %4  \n"  /* Calculate the end of the page to copy */
+		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  0(%0)  \n"  /* Prefetch the first 3 lines */
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%1)  \n"  
+		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  32(%0) \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  32(%1) \n"  
+		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  64(%0) \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \n"  
+		"1:   lw        $2,  0(%0)  \n"  /* Block copy a cacheline */
+		"     lw        $3,  4(%0)  \n"
+		"     lw        $4,  8(%0)  \n"
+		"     lw        $5, 12(%0)  \n"
+		"     lw        $6, 16(%0)  \n"
+		"     lw        $7, 20(%0)  \n"
+		"     lw        $8, 24(%0)  \n"
+		"     lw        $9, 28(%0)  \n"
+		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ", 96(%0)  \n"  /* Prefetch ahead         */
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%1)  \n"
+		"     sw        $2,  0(%1)  \n"  
+		"     sw        $3,  4(%1)  \n"
+		"     sw        $4,  8(%1)  \n"
+		"     sw        $5, 12(%1)  \n"
+		"     sw        $6, 16(%1)  \n"
+		"     sw        $7, 20(%1)  \n"
+		"     sw        $8, 24(%1)  \n"
+		"     sw        $9, 28(%1)  \n"		
+		"     daddiu     %1, %1, 32  \n"  /* Next cacheline */
+		"     nop                   \n"  /* Force next add to short pipe */
+		"     nop                   \n"  /* Force next add to short pipe */
+		"     bne       $1, %0, 1b  \n"
+		"     daddiu     %0, %0, 32  \n"  /* Next cacheline */
+		".set pop                   \n" 
+		: "=r" (to), "=r" (from)
+		: "0" (from), "1" (to), "I" (PAGE_SIZE-32)
+		: "$2","$3","$4","$5","$6","$7","$8","$9","memory");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/r4xx0.c linux/arch/mips64/mm/r4xx0.c
--- linux.orig/arch/mips64/mm/r4xx0.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/arch/mips64/mm/r4xx0.c	2002-07-20 01:08:22.000000000 +0000
@@ -9,6 +9,7 @@
  * Copyright (C) 1997, 1998, 1999, 2000, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -20,8 +21,8 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/bootinfo.h>
-#include <asm/sgialib.h>
 #include <asm/mmu_context.h>
+#include <asm/cpu.h>
 
 /* CP0 hazard avoidance. */
 #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
@@ -40,6 +41,7 @@
 
 #undef DEBUG_CACHE
 
+
 /*
  * Dummy cache handling routines for machines without boardcaches
  */
@@ -95,9 +97,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
-		:"$1", "memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		: "memory");
 }
 
 static void r4k_clear_page_d32(void * page)
@@ -120,9 +122,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
-		:"$1", "memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		: "memory");
 }
 
 
@@ -180,11 +182,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D)
-		:"$1", "memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		: "memory");
 }
 
 /*
@@ -214,9 +214,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
-		:"$1", "memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
+		: "memory");
 	__restore_flags(flags);
 }
 
@@ -251,9 +251,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
-		:"$1","memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
+		: "memory");
 }
 
 static void r4k_clear_page_s32(void * page)
@@ -276,9 +276,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
-		:"$1","memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
+		: "memory");
 }
 
 static void r4k_clear_page_s64(void * page)
@@ -300,11 +300,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD)
-		:"$1","memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
+		: "memory");
 }
 
 static void r4k_clear_page_s128(void * page)
@@ -334,11 +332,9 @@
 		"sd\t$0,-8(%0)\n\t"
 		".set\tat\n\t"
 		".set\treorder"
-		:"=r" (page)
-		:"0" (page),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD)
-		:"$1", "memory");
+		: "=r" (page)
+		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
+		: "memory");
 }
 
 
@@ -697,83 +693,47 @@
 
 static inline void r4k_flush_cache_all_s16d16i16(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache16();
-	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d16i16(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache32();
-	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d16i16(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache64();
-	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d16i16(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache128();
-	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d32i32(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache32();
-	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d32i32(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache64();
-	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d32i32(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache128();
-	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_d16i16(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16();
-	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_d32i32(void)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32();
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_range_s16d16i16(struct mm_struct *mm,
@@ -781,7 +741,6 @@
 					    unsigned long end)
 {
 	struct vm_area_struct *vma;
-	unsigned long flags;
 
 	if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
 		return;
@@ -800,7 +759,6 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -810,7 +768,6 @@
 					blast_scache16_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
 		}
 	}
 }
@@ -820,7 +777,6 @@
 					    unsigned long end)
 {
 	struct vm_area_struct *vma;
-	unsigned long flags;
 
 	if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
 		return;
@@ -839,7 +795,6 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -849,7 +804,6 @@
 					blast_scache32_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
 		}
 	}
 }
@@ -859,7 +813,6 @@
 					    unsigned long end)
 {
 	struct vm_area_struct *vma;
-	unsigned long flags;
 
 	if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
 		return;
@@ -878,7 +831,6 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -888,7 +840,6 @@
 					blast_scache64_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
 		}
 	}
 }
@@ -898,7 +849,6 @@
 					     unsigned long end)
 {
 	struct vm_area_struct *vma;
-	unsigned long flags;
 
 	if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
 		return;
@@ -917,7 +867,6 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -927,7 +876,6 @@
 					blast_scache128_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
 		}
 	}
 }
@@ -937,7 +885,6 @@
 					    unsigned long end)
 {
 	struct vm_area_struct *vma;
-	unsigned long flags;
 
 	if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
 		return;
@@ -956,7 +903,6 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -966,7 +912,6 @@
 					blast_scache32_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
 		}
 	}
 }
@@ -976,7 +921,6 @@
 					    unsigned long end)
 {
 	struct vm_area_struct *vma;
-	unsigned long flags;
 
 	if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
 		return;
@@ -995,7 +939,6 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1005,7 +948,6 @@
 					blast_scache64_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
 		}
 	}
 }
@@ -1015,7 +957,6 @@
 					     unsigned long end)
 {
 	struct vm_area_struct *vma;
-	unsigned long flags;
 
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0)
 		return;
@@ -1034,7 +975,6 @@
 			pmd_t *pmd;
 			pte_t *pte;
 
-			__save_and_cli(flags);
 			while(start < end) {
 				pgd = pgd_offset(mm, start);
 				pmd = pmd_offset(pgd, start);
@@ -1044,7 +984,6 @@
 					blast_scache128_page(start);
 				start += PAGE_SIZE;
 			}
-			__restore_flags(flags);
 		}
 	}
 }
@@ -1054,14 +993,10 @@
 					 unsigned long end)
 {
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		__save_and_cli(flags);
 		blast_dcache16(); blast_icache16();
-		__restore_flags(flags);
 	}
 }
 
@@ -1070,14 +1005,10 @@
 					 unsigned long end)
 {
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
-		unsigned long flags;
-
 #ifdef DEBUG_CACHE
 		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
-		__save_and_cli(flags);
 		blast_dcache32(); blast_icache32();
-		__restore_flags(flags);
 	}
 }
 
@@ -1180,7 +1111,6 @@
 					   unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1195,7 +1125,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1224,14 +1153,12 @@
 	} else
 		blast_scache16_page(page);
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
 					   unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1246,7 +1173,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1274,14 +1200,12 @@
 	} else
 		blast_scache32_page(page);
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
 					   unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1296,7 +1220,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1325,14 +1248,12 @@
 	} else
 		blast_scache64_page(page);
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
 					    unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1347,7 +1268,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1377,14 +1297,12 @@
 	} else
 		blast_scache128_page(page);
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
 					   unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1399,7 +1317,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1430,14 +1347,12 @@
 	} else
 		blast_scache32_page(page);
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
 					   unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1452,7 +1367,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1483,14 +1397,12 @@
 	} else
 		blast_scache64_page(page);
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
 					    unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1505,7 +1417,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1534,14 +1445,12 @@
 	} else
 		blast_scache128_page(page);
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
 					unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1556,7 +1465,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1584,14 +1492,12 @@
 		blast_dcache16_page_indexed(page);
 	}
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
 					unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1606,7 +1512,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1636,14 +1541,12 @@
 		blast_dcache32_page_indexed(page);
 	}
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
 					      unsigned long page)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long flags;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -1658,7 +1561,6 @@
 #ifdef DEBUG_CACHE
 	printk("cpage[%d,%08lx]", (int)mm->context, page);
 #endif
-	__save_and_cli(flags);
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -1688,7 +1590,6 @@
 		blast_dcache32_page_indexed(page ^ dcache_waybit);
 	}
 out:
-	__restore_flags(flags);
 }
 
 static void r4k_flush_page_to_ram_s16(struct page *page)
@@ -1713,20 +1614,40 @@
 
 static void r4k_flush_page_to_ram_d16(struct page *page)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache16_page((unsigned long)page_address(page));
-	__restore_flags(flags);
 }
 
 static void r4k_flush_page_to_ram_d32(struct page *page)
 {
-	unsigned long flags;
-
-	__save_and_cli(flags);
 	blast_dcache32_page((unsigned long)page_address(page));
-	__restore_flags(flags);
+}
+
+static void
+r4k_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+static void
+r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
+{
+	/*
+	 * We did an scache flush therefore PI is already clean.
+	 */
+}
+
+/*
+ * Ok, this seriously sucks.  We use them to flush a user page but don't
+ * know the virtual address, so we have to blast away the whole icache
+ * which is significantly more expensive than the real thing.
+ */
+static void
+r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page)
+{
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	flush_cache_all();
 }
 
 /*
@@ -1827,7 +1748,7 @@
 
 static void r4k_dma_cache_wback(unsigned long addr, unsigned long size)
 {
-	panic("r4k_dma_cache called - should not happen.\n");
+	panic("r4k_dma_cache called - should not happen.");
 }
 
 /*
@@ -1864,7 +1785,7 @@
 
 #define NTLB_ENTRIES_HALF  24  /* Fixed on all R4XX0 variants... */
 
-static inline void r4k_flush_tlb_all(void)
+void local_flush_tlb_all(void)
 {
 	unsigned long flags;
 	unsigned long old_ctx;
@@ -1897,7 +1818,7 @@
 	__restore_flags(flags);
 }
 
-static void r4k_flush_tlb_mm(struct mm_struct *mm)
+void local_flush_tlb_mm(struct mm_struct *mm)
 {
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
 		unsigned long flags;
@@ -1906,14 +1827,14 @@
 		printk("[tlbmm<%d>]", mm->context);
 #endif
 		__save_and_cli(flags);
-		get_new_cpu_mmu_context(mm, smp_processor_id());
+		get_new_mmu_context(mm, smp_processor_id());
 		if(mm == current->mm)
 			set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
 		__restore_flags(flags);
 	}
 }
 
-static void r4k_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
 				unsigned long end)
 {
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
@@ -1954,7 +1875,7 @@
 			}
 			set_entryhi(oldpid);
 		} else {
-			get_new_cpu_mmu_context(mm, smp_processor_id());
+			get_new_mmu_context(mm, smp_processor_id());
 			if(mm == current->mm)
 				set_entryhi(CPU_CONTEXT(smp_processor_id(), 
 								mm) & 0xff);
@@ -1963,7 +1884,7 @@
 	}
 }
 
-static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
 	if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) {
 		unsigned long flags;
@@ -2086,35 +2007,6 @@
 }
 #endif
 
-static void r4k_show_regs(struct pt_regs *regs)
-{
-	/* Saved main processor registers. */
-	printk("$0      : %016lx %016lx %016lx %016lx\n",
-	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
-	printk("$4      : %016lx %016lx %016lx %016lx\n",
-               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
-	printk("$8      : %016lx %016lx %016lx %016lx\n",
-	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
-	printk("$12     : %016lx %016lx %016lx %016lx\n",
-               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
-	printk("$16     : %016lx %016lx %016lx %016lx\n",
-	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
-	printk("$20     : %016lx %016lx %016lx %016lx\n",
-               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
-	printk("$24     : %016lx %016lx\n",
-	       regs->regs[24], regs->regs[25]);
-	printk("$28     : %016lx %016lx %016lx %016lx\n",
-	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
-	printk("Hi      : %016lx\n", regs->hi);
-	printk("Lo      : %016lx\n", regs->lo);
-
-	/* Saved cp0 registers. */
-	printk("epc     : %016lx    %s\nbadvaddr: %016lx\n",
-	       regs->cp0_epc, print_tainted(), regs->cp0_badvaddr);
-	printk("Status  : %08x\nCause   : %08x\n",
-	       (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
-}
-
 /* Detect and size the various r4k caches. */
 static void __init probe_icache(unsigned long config)
 {
@@ -2224,6 +2116,7 @@
 	case 16:
 		_clear_page = r4k_clear_page_d16;
 		_copy_page = r4k_copy_page_d16;
+		_flush_cache_all = r4k_flush_cache_all_d16i16;
 		_flush_cache_l1 = r4k_flush_cache_all_d16i16;
 		_flush_cache_mm = r4k_flush_cache_mm_d16i16;
 		_flush_cache_range = r4k_flush_cache_range_d16i16;
@@ -2241,6 +2134,7 @@
 			_clear_page = r4k_clear_page_d32;
 			_copy_page = r4k_copy_page_d32;
 		}
+		_flush_cache_all = r4k_flush_cache_all_d32i32;
 		_flush_cache_l1 = r4k_flush_cache_all_d32i32;
 		_flush_cache_mm = r4k_flush_cache_mm_d32i32;
 		_flush_cache_range = r4k_flush_cache_range_d32i32;
@@ -2256,7 +2150,7 @@
 		_flush_page_to_ram = r4k_flush_page_to_ram_d32;
 		break;
 	}
-
+	_flush_icache_page = r4k_flush_icache_page_p;
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
 	_dma_cache_wback = r4k_dma_cache_wback;
 	_dma_cache_inv = r4k_dma_cache_inv_pc;
@@ -2268,6 +2162,7 @@
 	case 16:
 		switch(dc_lsize) {
 		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s16d16i16;
 			_flush_cache_l1 = r4k_flush_cache_all_s16d16i16;
 			_flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
 			_flush_cache_range = r4k_flush_cache_range_s16d16i16;
@@ -2283,12 +2178,14 @@
 	case 32:
 		switch(dc_lsize) {
 		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s32d16i16;
 			_flush_cache_l1 = r4k_flush_cache_all_s32d16i16;
 			_flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
 			_flush_cache_range = r4k_flush_cache_range_s32d16i16;
 			_flush_cache_page = r4k_flush_cache_page_s32d16i16;
 			break;
 		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s32d32i32;
 			_flush_cache_l1 = r4k_flush_cache_all_s32d32i32;
 			_flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
 			_flush_cache_range = r4k_flush_cache_range_s32d32i32;
@@ -2302,12 +2199,14 @@
 	case 64:
 		switch(dc_lsize) {
 		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s64d16i16;
 			_flush_cache_l1 = r4k_flush_cache_all_s64d16i16;
 			_flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
 			_flush_cache_range = r4k_flush_cache_range_s64d16i16;
 			_flush_cache_page = r4k_flush_cache_page_s64d16i16;
 			break;
 		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s64d32i32;
 			_flush_cache_l1 = r4k_flush_cache_all_s64d32i32;
 			_flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
 			_flush_cache_range = r4k_flush_cache_range_s64d32i32;
@@ -2321,12 +2220,14 @@
 	case 128:
 		switch(dc_lsize) {
 		case 16:
+			_flush_cache_all = r4k_flush_cache_all_s128d16i16;
 			_flush_cache_l1 = r4k_flush_cache_all_s128d16i16;
 			_flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
 			_flush_cache_range = r4k_flush_cache_range_s128d16i16;
 			_flush_cache_page = r4k_flush_cache_page_s128d16i16;
 			break;
 		case 32:
+			_flush_cache_all = r4k_flush_cache_all_s128d32i32;
 			_flush_cache_l1 = r4k_flush_cache_all_s128d32i32;
 			_flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
 			_flush_cache_range = r4k_flush_cache_range_s128d32i32;
@@ -2338,6 +2239,7 @@
 		_copy_page = r4k_copy_page_s128;
 		break;
 	}
+	_flush_icache_page = r4k_flush_icache_page_s;
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
 	_dma_cache_wback = r4k_dma_cache_wback;
 	_dma_cache_inv = r4k_dma_cache_inv_sc;
@@ -2366,19 +2268,17 @@
 {
 	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
 
-	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
-
 #ifdef CONFIG_MIPS_UNCACHED
-	set_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
 #else
-	set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
 #endif /* UNCACHED */
 
 	probe_icache(config);
 	probe_dcache(config);
 	setup_scache(config);
 
-	switch(mips_cputype) {
+	switch(mips_cpu.cputype) {
 	case CPU_R4600:			/* QED style two way caches? */
 	case CPU_R4700:
 	case CPU_R5000:
@@ -2390,16 +2290,11 @@
 	if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) {
 		_flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
 	}
+	_flush_icache_range = r4k_flush_icache_range;	/* Ouch */
 
-	_flush_tlb_all = r4k_flush_tlb_all;
-	_flush_tlb_mm = r4k_flush_tlb_mm;
-	_flush_tlb_range = r4k_flush_tlb_range;
-	_flush_tlb_page = r4k_flush_tlb_page;
 	_flush_cache_l2 = r4k_flush_cache_l2;
 
-	update_mmu_cache = r4k_update_mmu_cache;
-
-	_show_regs = r4k_show_regs;
+	_update_mmu_cache = r4k_update_mmu_cache;
 
 	flush_cache_l1();
 
@@ -2411,5 +2306,5 @@
 	 *     be set for 4kb pages.
 	 */
 	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
-	_flush_tlb_all();
+	local_flush_tlb_all();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/tlb-dbg-r4k.c linux/arch/mips64/mm/tlb-dbg-r4k.c
--- linux.orig/arch/mips64/mm/tlb-dbg-r4k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/mm/tlb-dbg-r4k.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,71 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * TLB debugging routines.  These perform horribly slow but can easily be
+ * modified for debugging purposes.
+ */
+#include <linux/linkage.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+                              unsigned long address);
+
+asmlinkage void tlb_refill_debug(struct pt_regs regs)
+{
+	show_regs(&regs);
+	panic(__FUNCTION__ " called.  This Does Not Happen (TM).");
+}
+
+asmlinkage void xtlb_refill_debug(struct pt_regs *regs)
+{
+	unsigned long addr;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1);
+	pgd = pgd_offset(current->active_mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+
+	set_entrylo0(pte_val(pte[0]) >> 6);
+	set_entrylo1(pte_val(pte[1]) >> 6);
+	__asm__ __volatile__("nop;nop;nop");
+
+	tlb_write_random();
+}
+
+asmlinkage void xtlb_mod_debug(struct pt_regs *regs)
+{
+	unsigned long addr;
+
+	addr = regs->cp0_badvaddr;
+	do_page_fault(regs, 1, addr);
+}
+
+asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs)
+{
+	unsigned long addr;
+
+	addr = regs->cp0_badvaddr;
+	do_page_fault(regs, 0, addr);
+}
+
+asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs)
+{
+	unsigned long addr;
+
+	addr = regs->cp0_badvaddr;
+	do_page_fault(regs, 1, addr);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/tlb-glue-r4k.S linux/arch/mips64/mm/tlb-glue-r4k.S
--- linux.orig/arch/mips64/mm/tlb-glue-r4k.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/mm/tlb-glue-r4k.S	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.macro	__BUILD_cli
+	CLI
+	.endm
+
+	.macro	__BUILD_sti
+	STI
+	.endm
+
+	.macro	tlb_handler name interruptible writebit
+	NESTED(__\name, PT_SIZE, sp)
+	SAVE_ALL
+	dmfc0	a2, CP0_BADVADDR
+	__BUILD_\interruptible
+	li	a1, \writebit
+	sd	a2, PT_BVADDR(sp)
+	move	a0, sp
+	jal	do_page_fault
+	j	ret_from_exception
+	END(__\name)
+	.endm
+
+	tlb_handler	xtlb_mod sti 1
+	tlb_handler	xtlb_tlbl sti 0
+	tlb_handler	xtlb_tlbs sti 1
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/tlb-sb1.c linux/arch/mips64/mm/tlb-sb1.c
--- linux.orig/arch/mips64/mm/tlb-sb1.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/mm/tlb-sb1.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */ 
+#include <linux/config.h>
+#include <asm/mmu_context.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+/* Dump the current entry* and pagemask registers */
+static inline void dump_cur_tlb_regs(void)
+{
+	unsigned int entryhihi, entryhilo, entrylo0hi, entrylo0lo, entrylo1hi;
+	unsigned int entrylo1lo, pagemask;
+
+	__asm__ __volatile__ (
+		".set push             \n"
+		".set noreorder        \n"
+		"#.set mips64           \n"
+		".set mips4            \n"
+		".set noat             \n"
+		"     tlbr             \n"
+		"     dmfc0  $1, $10   \n"
+		"     dsrl32 %0, $1, 0 \n"
+		"     sra    %1, $1, 0 \n"
+		"     dmfc0  $1, $2    \n"
+		"     dsrl32 %2, $1, 0 \n"
+		"     sra    %3, $1, 0 \n"
+		"     dmfc0  $1, $3    \n"
+		"     dsrl32 %4, $1, 0 \n"
+		"     sra    %5, $1, 0 \n"
+		"     mfc0   %6, $5    \n"
+		".set pop              \n"
+		: "=r" (entryhihi),
+		"=r" (entryhilo),
+		"=r" (entrylo0hi),
+		"=r" (entrylo0lo),
+		"=r" (entrylo1hi),
+		"=r" (entrylo1lo),
+		"=r" (pagemask));
+	printk("%08X%08X %08X%08X %08X%08X %08X",
+	       entryhihi, entryhilo,
+	       entrylo0hi, entrylo0lo,
+	       entrylo1hi, entrylo1lo,
+	       pagemask);
+}
+
+void sb1_dump_tlb(void)
+{
+	int entry;
+	printk("Current TLB registers state:\n"
+	       "      EntryHi       EntryLo0          EntryLo1     PageMask  Index\n"
+	       "--------------------------------------------------------------------\n");
+	dump_cur_tlb_regs();
+	printk(" %08X\n", read_32bit_cp0_register(CP0_INDEX));
+	printk("\n\nFull TLB Dump:\n"
+	       "Idx      EntryHi       EntryLo0          EntryLo1     PageMask\n"
+	       "--------------------------------------------------------------\n");
+	for (entry = 0; entry < mips_cpu.tlbsize; entry++) {
+		set_index(entry);
+		printk("\n%02i ", entry);
+		__asm__ __volatile__ (
+			".set push             \n"
+			"#.set mips64           \n"
+			".set mips4           \n"
+			"     tlbr             \n"
+			".set pop              \n");
+		dump_cur_tlb_regs();
+	}
+	printk("\n");
+}
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	for (entry = 0; entry < mips_cpu.tlbsize; entry++) {
+		set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry);
+		set_index(entry);
+		tlb_write_indexed();
+	}
+	set_entryhi(old_ctx);
+	__restore_flags(flags);	
+}
+
+
+/*
+ * Use a bogus region of memory (starting at 0) to sanitize the TLB's.  
+ * Use increments of the maximum page size (16MB), and check for duplicate
+ * entries before doing a given write.  Then, when we're safe from collisions
+ * with the firmware, go back and give all the entries invalid addresses with
+ * the normal flush routine.
+ */
+void sb1_sanitize_tlb(void)
+{
+	int entry;
+	long addr = 0;
+
+	long inc = 1<<24;  /* 16MB */
+	/* Save old context and create impossible VPN2 value */
+	set_entrylo0(0);
+	set_entrylo1(0);
+	for (entry = 0; entry < mips_cpu.tlbsize; entry++) {
+		do {
+			addr += inc;
+			set_entryhi(addr);
+			tlb_probe();
+		} while ((int)(get_index()) >= 0);
+		set_index(entry);
+		tlb_write_indexed();
+	}
+	/* Now that we know we're safe from collisions, we can safely flush
+	   the TLB with the "normal" routine. */
+	local_flush_tlb_all();
+}
+
+
+void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+                      unsigned long end)
+{
+	unsigned long flags;
+	int cpu;
+
+	__save_and_cli(flags);
+	cpu = smp_processor_id();
+	if(CPU_CONTEXT(cpu, mm) != 0) {
+		int size;
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if(size <= (mips_cpu.tlbsize/2)) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (CPU_CONTEXT(cpu, mm) & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				tlb_probe();
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				set_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1)));
+				if(idx < 0)
+					continue;
+				tlb_write_indexed();
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, cpu);
+			if (mm == current->active_mm)
+				set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff);
+		}
+	}
+	__restore_flags(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	unsigned long flags;
+
+#ifdef CONFIG_SMP
+	/*
+	 * This variable is eliminated from CPU_CONTEXT() if SMP isn't defined,
+	 * so conditional it to get rid of silly "unused variable" compiler
+	 * complaints
+	 */
+	int cpu = smp_processor_id();
+#endif
+
+	__save_and_cli(flags);
+	if (CPU_CONTEXT(cpu, vma->vm_mm) != 0) {
+		int oldpid, newpid, idx;
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", CPU_CONTEXT(cpu, vma->vm_mm), page);
+#endif
+		newpid = (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff);
+		page &= (PAGE_MASK << 1);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi	(page | newpid);
+		tlb_probe();
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		if(idx < 0)
+			goto finish;
+		/* Make sure all entries differ. */  
+		set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1)));
+		tlb_write_indexed();
+	finish:
+		set_entryhi(oldpid);
+	}
+	__restore_flags(flags);
+}
+
+
+/* All entries common to a mm share an asid.  To effectively flush
+   these entries, we just bump the asid. */
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	unsigned long flags;
+	int cpu;
+	__save_and_cli(flags);
+	cpu = smp_processor_id();
+	if (CPU_CONTEXT(cpu, mm) != 0) {
+		get_new_mmu_context(mm, smp_processor_id());
+		if (mm == current->active_mm) {
+			set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff);
+		}
+	}
+	__restore_flags(flags);
+}
+
+/* Stolen from mips32 routines */
+
+void sb1_update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
+                      pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	__save_and_cli(flags);
+
+
+	pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+	if((pid != (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff)) || (CPU_CONTEXT(cpu, vma->vm_mm) == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       (int) (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff), pid);
+	}
+#endif
+
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	tlb_probe();
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	if (idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	set_entryhi(pid);
+	__restore_flags(flags);
+}
+
+/*
+ * This is called from loadmmu.c.  We have to set up all the
+ * memory management function pointers, as well as initialize
+ * the caches and tlbs
+ */
+void sb1_tlb_init(void)
+{
+	u32 config1;
+
+	config1 = read_mips32_cp0_config1();
+	mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
+
+	/*
+	 * We don't know what state the firmware left the TLB's in, so this is
+	 * the ultra-conservative way to flush the TLB's and avoid machine
+	 * check exceptions due to duplicate TLB entries 
+	 */
+	sb1_sanitize_tlb();
+	_update_mmu_cache = sb1_update_mmu_cache;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/mm/tlbex-r4k.S linux/arch/mips64/mm/tlbex-r4k.S
--- linux.orig/arch/mips64/mm/tlbex-r4k.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/mm/tlbex-r4k.S	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,134 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/pgtable.h>
+#include <asm/stackframe.h>
+
+	.data
+	.comm	pgd_current, NR_CPUS * 8, 8
+
+	/*
+	 * After this macro runs we have a pointer to the pte of the address
+	 * that caused the fault in in PTR.
+	 */
+
+	.macro	LOAD_PTE2, ptr, tmp
+#ifdef CONFIG_SMP
+	dmfc0	\ptr, CP0_CONTEXT
+	dmfc0	\tmp, CP0_BADVADDR
+	dsra	\ptr, 23			# get pgd_current[cpu]
+#else
+	dmfc0	\tmp, CP0_BADVADDR
+	dla	\ptr, pgd_current
+#endif
+	bltz	\tmp, kaddr
+	ld	\ptr, (\ptr)
+	dsrl	\tmp, (PGDIR_SHIFT-3)		# get pgd offset in bytes
+	andi	\tmp, ((PTRS_PER_PGD - 1)<<3)
+	daddu	\ptr, \tmp			# add in pgd offset
+	dmfc0	\tmp, CP0_BADVADDR
+	ld	\ptr, (\ptr)			# get pmd pointer
+	dsrl	\tmp, (PMD_SHIFT-3)		# get pmd offset in bytes
+	andi	\tmp, ((PTRS_PER_PMD - 1)<<3)
+	daddu	\ptr, \tmp			# add in pmd offset
+	dmfc0	\tmp, CP0_XCONTEXT
+	ld	\ptr, (\ptr)			# get pte pointer
+	andi	\tmp, 0xff0			# get pte offset
+	daddu	\ptr, \tmp
+	.endm
+
+	/*
+	 * This places the even/odd pte pair in the page table at the pte
+	 * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1.
+	 */
+	.macro	PTE_RELOAD, pte0, pte1
+	dsrl	\pte0, 6			# convert to entrylo0
+	dmtc0	\pte0, CP0_ENTRYLO0		# load it
+	dsrl	\pte1, 6			# convert to entrylo1
+	dmtc0	\pte1, CP0_ENTRYLO1		# load it
+	.endm
+
+	.text
+	.set	noreorder
+	.set	mips3
+
+	__INIT
+
+	.align	5
+FEXPORT(except_vec0)
+	.set	noat
+	PANIC("Unused vector called")
+1:	b	1b
+	 nop
+
+	/*
+	 * TLB refill handler for the R10000.
+	 * Attention:  We may only use 32 instructions / 128 bytes.
+	 */
+
+	.align	5
+LEAF(except_vec1_r10k)
+	.set	noat
+	LOAD_PTE2 k1 k0
+	ld	k0, 0(k1)			# get even pte
+	ld	k1, 8(k1)			# get odd pte
+	PTE_RELOAD k0 k1
+	nop
+	tlbwr
+	eret
+kaddr:
+	dla	k0, handle_vmalloc_address	# MAPPED kernel needs this
+	jr	k0
+	 nop
+	END(except_vec1_r10k)
+
+	__FINIT
+
+	.align	5
+LEAF(handle_vmalloc_address)
+	.set	noat
+	/*
+	 * First, determine that the address is in/above vmalloc range.
+	 */
+	dmfc0	k0, CP0_BADVADDR
+	dli	k1, VMALLOC_START
+
+	/*
+	 * Now find offset into kptbl.
+	 */
+	dsubu	k0, k0, k1
+	dla	k1, kptbl
+	dsrl	k0, (PAGE_SHIFT+1)		# get vpn2
+	dsll	k0, 4				# byte offset of pte
+	daddu	k1, k1, k0
+
+	/*
+	 * Determine that fault address is within vmalloc range.
+	 */
+	dla	k0, ekptbl
+	sltu	k0, k1, k0
+	beqz	k0, not_vmalloc
+
+	/*
+	 * Load cp0 registers.
+	 */
+	ld	k0, 0(k1)			# get even pte
+	ld	k1, 8(k1)			# get odd pte
+
+not_vmalloc:
+	PTE_RELOAD k0 k1
+	nop
+	tlbwr
+	eret
+	END(handle_vmalloc_address)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/Makefile linux/arch/mips64/sgi-ip22/Makefile
--- linux.orig/arch/mips64/sgi-ip22/Makefile	2001-02-05 05:48:46.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,16 +0,0 @@
-#
-# Makefile for the SGI specific kernel interface routines
-# under Linux.
-#
-
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-L_TARGET = ip22.a
-
-obj-y	+= ip22-berr.o ip22-mc.o ip22-sc.o ip22-hpc.o ip22-int.o ip22-rtc.o \
-	   ip22-setup.o system.o ip22-timer.o ip22-irq.o ip22-reset.o time.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-berr.c linux/arch/mips64/sgi-ip22/ip22-berr.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-berr.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-berr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,125 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 by Silicon Graphics
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <asm/module.h>
-#include <asm/uaccess.h>
-#include <asm/paccess.h>
-#include <asm/addrspace.h>
-#include <asm/ptrace.h>
-
-extern asmlinkage void handle_ibe(void);
-extern asmlinkage void handle_dbe(void);
-
-extern const struct exception_table_entry __start___dbe_table[];
-extern const struct exception_table_entry __stop___dbe_table[];
-
-static inline unsigned long
-search_one_table(const struct exception_table_entry *first,
-                 const struct exception_table_entry *last,
-                 unsigned long value)
-{
-	while (first <= last) {
-		const struct exception_table_entry *mid;
-		long diff;
-
-		mid = (last - first) / 2 + first;
-		diff = mid->insn - value;
-		if (diff == 0)
-			return mid->nextinsn;
-		else if (diff < 0)
-			first = mid+1;
-		else
-			last = mid-1;
-	}
-	return 0;
-}
-
-extern spinlock_t modlist_lock;
-
-static inline unsigned long
-search_dbe_table(unsigned long addr)
-{
-	unsigned long ret = 0;
-
-#ifndef CONFIG_MODULES
-	/* There is only the kernel to search.  */
-	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
-	return ret;
-#else
-	unsigned long flags;
-
-	/* The kernel is the last "module" -- no need to treat it special.  */
-	struct module *mp;
-	struct archdata *ap;
-
-	spin_lock_irqsave(&modlist_lock, flags);
-	for (mp = module_list; mp != NULL; mp = mp->next) {
-		if (!mod_member_present(mp, archdata_end) ||
-        	    !mod_archdata_member_present(mp, struct archdata,
-						 dbe_table_end))
-			continue;
-		ap = (struct archdata *)(mod->archdata_start);
-
-		if (ap->dbe_table_start == NULL ||
-		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
-			continue;
-		ret = search_one_table(ap->dbe_table_start,
-				       ap->dbe_table_end - 1, addr);
-		if (ret)
-			break;
-	}
-	spin_unlock_irqrestore(&modlist_lock, flags);
-	return ret;
-#endif
-}
-
-void do_ibe(struct pt_regs *regs)
-{
-	printk("Got ibe at 0x%lx\n", regs->cp0_epc);
-	show_regs(regs);
-	dump_tlb_addr(regs->cp0_epc);
-	force_sig(SIGBUS, current);
-	while(1);
-}
-
-void do_dbe(struct pt_regs *regs)
-{
-	unsigned long fixup;
-
-	fixup = search_dbe_table(regs->cp0_epc);
-	if (fixup) {
-		long new_epc;
-
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
-	}
-
-	printk("Got dbe at 0x%lx\n", regs->cp0_epc);
-	show_regs(regs);
-	dump_tlb_all();
-	while(1);
-	force_sig(SIGBUS, current);
-}
-
-void __init
-bus_error_init(void)
-{
-	int dummy;
-
-	set_except_vector(6, handle_ibe);
-	set_except_vector(7, handle_dbe);
-
-	/* At this time nothing uses the DBE protection mechanism on the
-	   Indy, so this here is needed to make the kernel link.  */
-	get_dbe(dummy, (int *)KSEG0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-hpc.c linux/arch/mips64/sgi-ip22/ip22-hpc.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-hpc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-hpc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,104 +0,0 @@
-/*
- * ip22-hpc.c: Routines for generic manipulation of the HPC controllers.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1998, 1999, 2001 Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <asm/addrspace.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-#include <asm/bootinfo.h>
-
-#undef DEBUG_SGIHPC
-
-struct hpc3_regs *hpc3c0, *hpc3c1;
-struct hpc3_miscregs *hpc3mregs;
-
-/* We need software copies of these because they are write only. */
-unsigned int sgi_hpc_write1, sgi_hpc_write2;
-
-/* Machine specific identifier knobs. */
-int sgi_has_ioc2 = 0;
-int sgi_guiness = 0;
-int sgi_boardid;
-
-void __init sgihpc_init(void)
-{
-	unsigned long sid, crev, brev;
-
-	hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE);
-	hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE);
-	hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE);
-	sid = hpc3mregs->sysid;
-
-	sid &= 0xff;
-	crev = (sid & 0xe0) >> 5;
-	brev = (sid & 0x1e) >> 1;
-
-#ifdef DEBUG_SGIHPC
-	prom_printf("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev);
-	prom_printf("sgihpc_init: ");
-#endif
-
-	/* This test works now thanks to William J. Earl */
-	if ((sid & 1) == 0 ) {
-#ifdef DEBUG_SGIHPC
-		prom_printf("GUINESS ");
-#endif
-		sgi_guiness = 1;
-		mips_machtype = MACH_SGI_INDY;
-	} else {
-#ifdef DEBUG_SGIHPC
-		prom_printf("FULLHOUSE ");
-#endif
-                mips_machtype = MACH_SGI_INDIGO2;
-		sgi_guiness = 0;
-	}
-	sgi_boardid = brev;
-
-#ifdef DEBUG_SGIHPC
-	prom_printf("sgi_boardid<%d> ", sgi_boardid);
-#endif
-
-	if(crev == 1) {
-		if((sid & 1) || (brev >= 2)) {
-#ifdef DEBUG_SGIHPC
-			prom_printf("IOC2 ");
-#endif
-			sgi_has_ioc2 = 1;
-		} else {
-#ifdef DEBUG_SGIHPC
-			prom_printf("IOC1 revision 1 ");
-#endif
-		}
-	} else {
-#ifdef DEBUG_SGIHPC
-		prom_printf("IOC1 revision 0 ");
-#endif
-	}
-#ifdef DEBUG_SGIHPC
-	prom_printf("\n");
-#endif
-
-	sgi_hpc_write1 = (HPC3_WRITE1_PRESET |
-		  HPC3_WRITE1_KMRESET |
-		  HPC3_WRITE1_ERESET |
-		  HPC3_WRITE1_LC0OFF);
-
-	sgi_hpc_write2 = (HPC3_WRITE2_EASEL |
-		  HPC3_WRITE2_NTHRESH |
-		  HPC3_WRITE2_TPSPEED |
-		  HPC3_WRITE2_EPSEL |
-		  HPC3_WRITE2_U0AMODE |
-		  HPC3_WRITE2_U1AMODE);
-
-	if(!sgi_guiness)
-		sgi_hpc_write1 |= HPC3_WRITE1_GRESET;
-	hpc3mregs->write1 = sgi_hpc_write1;
-	hpc3mregs->write2 = sgi_hpc_write2;
-
-	hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-int.c linux/arch/mips64/sgi-ip22/ip22-int.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-int.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-int.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,608 +0,0 @@
-/*
- * indy_int.c: Routines for generic manipulation of the INT[23] ASIC
- *             found on INDY workstations..
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
- */
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <linux/errno.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/sgi/sgi.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-
-/*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the apropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
-
-struct sgi_int2_regs *sgi_i2regs;
-struct sgi_int3_regs *sgi_i3regs;
-struct sgi_ioc_ints *ioc_icontrol;
-struct sgi_ioc_timers *ioc_timers;
-volatile unsigned char *ioc_tclear;
-
-static char lc0msk_to_irqnr[256];
-static char lc1msk_to_irqnr[256];
-static char lc2msk_to_irqnr[256];
-static char lc3msk_to_irqnr[256];
-
-extern asmlinkage void indyIRQ(void);
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void rs_kgdb_hook(int);
-#endif
-
-unsigned long spurious_count = 0;
-
-/* Local IRQ's are layed out logically like this:
- *
- * 0  --> 7   ==   local 0 interrupts
- * 8  --> 15  ==   local 1 interrupts
- * 16 --> 23  ==   vectored level 2 interrupts
- * 24 --> 31  ==   vectored level 3 interrupts (not used)
- */
-void disable_local_irq(unsigned int irq_nr)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	switch(irq_nr) {
-	case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
-		ioc_icontrol->imask0 &= ~(1 << irq_nr);
-		break;
-
-	case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
-		ioc_icontrol->imask1 &= ~(1 << (irq_nr - 8));
-		break;
-
-	case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
-		ioc_icontrol->cmeimask0 &= ~(1 << (irq_nr - 16));
-		break;
-
-	default:
-		/* This way we'll see if anyone would ever want vectored
-		 * level 3 interrupts.  Highly unlikely.
-		 */
-		printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr);
-		panic("INVALID IRQ level!");
-	};
-	restore_flags(flags);
-}
-
-void enable_local_irq(unsigned int irq_nr)
-{
-	unsigned long flags;
-	save_and_cli(flags);
-	switch(irq_nr) {
-	case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
-		ioc_icontrol->imask0 |= (1 << irq_nr);
-		break;
-
-	case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
-		ioc_icontrol->imask1 |= (1 << (irq_nr - 8));
-		break;
-
-	case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
-		enable_local_irq(7);
-		ioc_icontrol->cmeimask0 |= (1 << (irq_nr - 16));
-		break;
-
-	default:
-		printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr);
-		panic("INVALID IRQ level!");
-	};
-	restore_flags(flags);
-}
-
-void disable_gio_irq(unsigned int irq_nr)
-{
-	/* XXX TODO XXX */
-}
-
-void enable_gio_irq(unsigned int irq_nr)
-{
-	/* XXX TODO XXX */
-}
-
-void disable_hpcdma_irq(unsigned int irq_nr)
-{
-	/* XXX TODO XXX */
-}
-
-void enable_hpcdma_irq(unsigned int irq_nr)
-{
-	/* XXX TODO XXX */
-}
-
-void disable_irq(unsigned int irq_nr)
-{
-	unsigned int n = irq_nr;
-	if(n >= SGINT_END) {
-		printk("whee, invalid irq_nr %d\n", irq_nr);
-		panic("IRQ, you lose...");
-	}
-	if(n >= SGINT_LOCAL0 && n < SGINT_GIO) {
-		disable_local_irq(n - SGINT_LOCAL0);
-	} else if(n >= SGINT_GIO && n < SGINT_HPCDMA) {
-		disable_gio_irq(n - SGINT_GIO);
-	} else if(n >= SGINT_HPCDMA && n < SGINT_END) {
-		disable_hpcdma_irq(n - SGINT_HPCDMA);
-	} else {
-		panic("how did I get here?");
-	}
-}
-
-void enable_irq(unsigned int irq_nr)
-{
-	unsigned int n = irq_nr;
-	if(n >= SGINT_END) {
-		printk("whee, invalid irq_nr %d\n", irq_nr);
-		panic("IRQ, you lose...");
-	}
-	if(n >= SGINT_LOCAL0 && n < SGINT_GIO) {
-		enable_local_irq(n - SGINT_LOCAL0);
-	} else if(n >= SGINT_GIO && n < SGINT_HPCDMA) {
-		enable_gio_irq(n - SGINT_GIO);
-	} else if(n >= SGINT_HPCDMA && n < SGINT_END) {
-		enable_hpcdma_irq(n - SGINT_HPCDMA);
-	} else {
-		panic("how did I get here?");
-	}
-}
-
-#if 0
-/*
- * Currently unused.
- */
-static void local_unex(int irq, void *data, struct pt_regs *regs)
-{
-	printk("Whee: unexpected local IRQ at %08lx\n",
-	       (unsigned long) regs->cp0_epc);
-	printk("DUMP: stat0<%x> stat1<%x> vmeistat<%x>\n",
-	       ioc_icontrol->istat0, ioc_icontrol->istat1,
-	       ioc_icontrol->vmeistat);
-}
-#endif
-
-static struct irqaction *local_irq_action[24] = {
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL
-};
-
-int setup_indy_irq(int irq, struct irqaction * new)
-{
-	printk("setup_indy_irq: Yeee, don't know how to setup irq<%d> for %s  %p\n",
-	       irq, new->name, new->handler);
-	return 0;
-}
-
-static struct irqaction r4ktimer_action = {
-	NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
-};
-
-static struct irqaction indy_berr_action = {
-	NULL, 0, 0, "IP22 Bus Error", NULL, NULL,
-};
-
-static struct irqaction *irq_action[16] = {
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, &indy_berr_action, &r4ktimer_action,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL
-};
-
-int get_irq_list(char *buf)
-{
-	int i, len = 0;
-	int num = 0;
-	struct irqaction * action;
-
-	for (i = 0 ; i < 16 ; i++, num++) {
-		action = irq_action[i];
-		if (!action) 
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
-			(action->flags & SA_INTERRUPT) ? '+' : ' ',
-			action->name);
-		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ",%s %s",
-				(action->flags & SA_INTERRUPT) ? " +" : "",
-				action->name);
-		}
-		len += sprintf(buf+len, " [on-chip]\n");
-	}
-	for (i = 0 ; i < 24 ; i++, num++) {
-		action = local_irq_action[i];
-		if (!action) 
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
-			(action->flags & SA_INTERRUPT) ? '+' : ' ',
-			action->name);
-		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ",%s %s",
-				(action->flags & SA_INTERRUPT) ? " +" : "",
-				action->name);
-		}
-		len += sprintf(buf+len, " [local]\n");
-	}
-	return len;
-}
-
-/*
- * do_IRQ handles IRQ's that have been installed without the
- * SA_INTERRUPT flag: it uses the full signal-handling return
- * and runs with other interrupts enabled. All relatively slow
- * IRQ's should use this format: notably the keyboard/timer
- * routines.
- */
-asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
-{
-	struct irqaction *action;
-	int do_random, cpu;
-
-	cpu = smp_processor_id();
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
-
-	panic(KERN_DEBUG "Got irq %d, press a key.", irq);
-
-	/*
-	 * mask and ack quickly, we don't want the irq controller
-	 * thinking we're snobs just because some other CPU has
-	 * disabled global interrupts (we have already done the
-	 * INT_ACK cycles, it's too late to try to pretend to the
-	 * controller that we aren't taking the interrupt).
-	 *
-	 * Commented out because we've already done this in the
-	 * machinespecific part of the handler.  It's reasonable to
-	 * do this here in a highlevel language though because that way
-	 * we could get rid of a good part of duplicated code ...
-	 */
-        /* mask_and_ack_irq(irq); */
-
-	action = *(irq + irq_action);
-	if (action) {
-		if (!(action->flags & SA_INTERRUPT))
-			__sti();
-		action = *(irq + irq_action);
-		do_random = 0;
-		do {
-			do_random |= action->flags;
-			action->handler(irq, action->dev_id, regs);
-			action = action->next;
-		} while (action);
-		if (do_random & SA_SAMPLE_RANDOM)
-			add_interrupt_randomness(irq);
-		__cli();
-	}
-	irq_exit(cpu, irq);
-
-	/* unmasking and bottom half handling is done magically for us. */
-}
-
-int request_local_irq(unsigned int lirq, void (*func)(int, void *, struct pt_regs *),
-		      unsigned long iflags, const char *dname, void *devid)
-{
-	struct irqaction *action;
-
-	lirq -= SGINT_LOCAL0;
-	if(lirq >= 24 || !func)
-		return -EINVAL;
-
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if(!action)
-		return -ENOMEM;
-
-	action->handler = func;
-	action->flags = iflags;
-	action->mask = 0;
-	action->name = dname;
-	action->dev_id = devid;
-	action->next = 0;
-	local_irq_action[lirq] = action;
-	enable_irq(lirq + SGINT_LOCAL0);
-	return 0;
-}
-
-void free_local_irq(unsigned int lirq, void *dev_id)
-{
-	struct irqaction *action;
-
-	lirq -= SGINT_LOCAL0;
-	if(lirq >= 24) {
-		printk("Aieee: trying to free bogus local irq %d\n",
-		       lirq + SGINT_LOCAL0);
-		return;
-	}
-	action = local_irq_action[lirq];
-	local_irq_action[lirq] = NULL;
-	disable_irq(lirq + SGINT_LOCAL0);
-	kfree(action);
-}
-
-int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
-{
-	int retval;
-	struct irqaction * action;
-
-	if (irq >= SGINT_END)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
-
-	if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO))
-		return request_local_irq(irq, handler, irqflags, devname, dev_id);
-
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if (!action)
-		return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->mask = 0;
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-	retval = setup_indy_irq(irq, action);
-
-	if (retval)
-		kfree(action);
-	return retval;
-}
-		
-void free_irq(unsigned int irq, void *dev_id)
-{
-	struct irqaction * action, **p;
-	unsigned long flags;
-
-	if (irq >= SGINT_END) {
-		printk("Trying to free IRQ%d\n",irq);
-		return;
-	}
-	if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO)) {
-		free_local_irq(irq, dev_id);
-		return;
-	}
-	for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
-		if (action->dev_id != dev_id)
-			continue;
-
-		/* Found it - now free it */
-		save_and_cli(flags);
-		*p = action->next;
-		restore_flags(flags);
-		kfree(action);
-		return;
-	}
-	printk("Trying to free free IRQ%d\n",irq);
-}
-
-void indy_local0_irqdispatch(struct pt_regs *regs)
-{
-	struct irqaction *action;
-	unsigned char mask = ioc_icontrol->istat0;
-	unsigned char mask2 = 0;
-	int irq, cpu = smp_processor_id();;
-
-	mask &= ioc_icontrol->imask0;
-	if(mask & ISTAT0_LIO2) {
-		mask2 = ioc_icontrol->vmeistat;
-		mask2 &= ioc_icontrol->cmeimask0;
-		irq = lc2msk_to_irqnr[mask2];
-		action = local_irq_action[irq];
-	} else {
-		irq = lc0msk_to_irqnr[mask];
-		action = local_irq_action[irq];
-	}
-
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq + 16]++;
-	action->handler(irq, action->dev_id, regs);
-	irq_exit(cpu, irq);
-}
-
-void indy_local1_irqdispatch(struct pt_regs *regs)
-{
-	struct irqaction *action;
-	unsigned char mask = ioc_icontrol->istat1;
-	unsigned char mask2 = 0;
-	int irq, cpu = smp_processor_id();;
-
-	mask &= ioc_icontrol->imask1;
-	if(mask & ISTAT1_LIO3) {
-		printk("WHee: Got an LIO3 irq, winging it...\n");
-		mask2 = ioc_icontrol->vmeistat;
-		mask2 &= ioc_icontrol->cmeimask1;
-		irq = lc3msk_to_irqnr[ioc_icontrol->vmeistat];
-		action = local_irq_action[irq];
-	} else {
-		irq = lc1msk_to_irqnr[mask];
-		action = local_irq_action[irq];
-	}
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq + 24]++;
-	action->handler(irq, action->dev_id, regs);
-	irq_exit(cpu, irq);
-}
-
-void indy_buserror_irq(struct pt_regs *regs)
-{
-	int cpu = smp_processor_id();
-	int irq = 6;
-
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
-	printk("Got a bus error IRQ, shouldn't happen yet\n");
-	show_regs(regs);
-	printk("Spinning...\n");
-	while(1);
-	irq_exit(cpu, irq);
-}
-
-/* Misc. crap just to keep the kernel linking... */
-unsigned long probe_irq_on (void)
-{
-	return 0;
-}
-
-int probe_irq_off (unsigned long irqs)
-{
-	return 0;
-}
-
-static inline void sgint_init(void)
-{
-	int i;
-#ifdef CONFIG_REMOTE_DEBUG
-	char *ctype;
-#endif
-
-	sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE);
-	sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE);
-
-	/* Init local mask --> irq tables. */
-	for(i = 0; i < 256; i++) {
-		if(i & 0x80) {
-			lc0msk_to_irqnr[i] = 7;
-			lc1msk_to_irqnr[i] = 15;
-			lc2msk_to_irqnr[i] = 23;
-			lc3msk_to_irqnr[i] = 31;
-		} else if(i & 0x40) {
-			lc0msk_to_irqnr[i] = 6;
-			lc1msk_to_irqnr[i] = 14;
-			lc2msk_to_irqnr[i] = 22;
-			lc3msk_to_irqnr[i] = 30;
-		} else if(i & 0x20) {
-			lc0msk_to_irqnr[i] = 5;
-			lc1msk_to_irqnr[i] = 13;
-			lc2msk_to_irqnr[i] = 21;
-			lc3msk_to_irqnr[i] = 29;
-		} else if(i & 0x10) {
-			lc0msk_to_irqnr[i] = 4;
-			lc1msk_to_irqnr[i] = 12;
-			lc2msk_to_irqnr[i] = 20;
-			lc3msk_to_irqnr[i] = 28;
-		} else if(i & 0x08) {
-			lc0msk_to_irqnr[i] = 3;
-			lc1msk_to_irqnr[i] = 11;
-			lc2msk_to_irqnr[i] = 19;
-			lc3msk_to_irqnr[i] = 27;
-		} else if(i & 0x04) {
-			lc0msk_to_irqnr[i] = 2;
-			lc1msk_to_irqnr[i] = 10;
-			lc2msk_to_irqnr[i] = 18;
-			lc3msk_to_irqnr[i] = 26;
-		} else if(i & 0x02) {
-			lc0msk_to_irqnr[i] = 1;
-			lc1msk_to_irqnr[i] = 9;
-			lc2msk_to_irqnr[i] = 17;
-			lc3msk_to_irqnr[i] = 25;
-		} else if(i & 0x01) {
-			lc0msk_to_irqnr[i] = 0;
-			lc1msk_to_irqnr[i] = 8;
-			lc2msk_to_irqnr[i] = 16;
-			lc3msk_to_irqnr[i] = 24;
-		} else {
-			lc0msk_to_irqnr[i] = 0;
-			lc1msk_to_irqnr[i] = 0;
-			lc2msk_to_irqnr[i] = 0;
-			lc3msk_to_irqnr[i] = 0;
-		}
-	}
-
-	/* Indy uses an INT3, Indigo2 uses an INT2 */
-	if (sgi_guiness) {
-		ioc_icontrol = &sgi_i3regs->ints;
-		ioc_timers = &sgi_i3regs->timers;
-		ioc_tclear = &sgi_i3regs->tclear;
-	} else {
-		ioc_icontrol = &sgi_i2regs->ints;
-		ioc_timers = &sgi_i2regs->timers;
-		ioc_tclear = &sgi_i2regs->tclear;
-	}
-
-	/* Mask out all interrupts. */
-	ioc_icontrol->imask0 = 0;
-	ioc_icontrol->imask1 = 0;
-	ioc_icontrol->cmeimask0 = 0;
-	ioc_icontrol->cmeimask1 = 0;
-
-	/* Now safe to set the exception vector. */
-	set_except_vector(0, indyIRQ);
-
-#ifdef CONFIG_REMOTE_DEBUG
-	ctype = prom_getcmdline();
-	for(i = 0; i < strlen(ctype); i++) {
-		if(ctype[i]=='k' && ctype[i+1]=='g' &&
-		   ctype[i+2]=='d' && ctype[i+3]=='b' &&
-		   ctype[i+4]=='=' && ctype[i+5]=='t' &&
-		   ctype[i+6]=='t' && ctype[i+7]=='y' &&
-		   ctype[i+8]=='d' &&
-		   (ctype[i+9] == '1' || ctype[i+9] == '2')) {
-			printk("KGDB: Using serial line /dev/ttyd%d for "
-			       "session\n", (ctype[i+9] - '0'));
-				if(ctype[i+9]=='1')
-					rs_kgdb_hook(1);
-				else if(ctype[i+9]=='2')
-					rs_kgdb_hook(0);
-				else {
-					printk("KGDB: whoops bogon tty line "
-					       "requested, disabling session\n");
-				}
-
-		}
-	}
-#endif
-}
-
-void __init init_IRQ(void)
-{
-	sgint_init();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-irq.S linux/arch/mips64/sgi-ip22/ip22-irq.S
--- linux.orig/arch/mips64/sgi-ip22/ip22-irq.S	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-irq.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,128 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * indyIRQ.S: Interrupt exception dispatch code for FullHouse and
- *            Guiness.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/* A lot of complication here is taken away because:
- *
- * 1) We handle one interrupt and return, sitting in a loop and moving across
- *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
- *    common case is one pending IRQ so optimize in that direction.
- *
- * 2) We need not check against bits in the status register IRQ mask, that
- *    would make this routine slow as hell.
- *
- * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
- *    between like BSD spl() brain-damage.
- *
- * Furthermore, the IRQs on the INDY look basically (barring software IRQs
- * which we don't use at all) like:
- *
- *	MIPS IRQ	Source
- *      --------        ------
- *             0	Software (ignored)
- *             1        Software (ignored)
- *             2        Local IRQ level zero
- *             3        Local IRQ level one
- *             4        8254 Timer zero
- *             5        8254 Timer one
- *             6        Bus Error
- *             7        R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ----     R4k Timer
- *                  Local IRQ zero
- *                  Local IRQ one
- *                  Bus Error
- *                  8254 Timer zero
- * Lowest  ----     8254 Timer one
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
-	.text
-	.set	noreorder
-	.set	noat
-	.align	5
-	NESTED(indyIRQ, PT_SIZE, sp)
-	SAVE_ALL
-	CLI
-	.set	at
-	mfc0	s0, CP0_CAUSE		# get irq mask
-
-	/* First we check for r4k counter/timer IRQ. */
-	andi	a0, s0, CAUSEF_IP7
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
-
-	/* Wheee, a timer interrupt. */
-	move	a0, sp
-	jal	indy_timer_interrupt
-	 nop				# delay slot
-
-	j	ret_from_irq
-	 nop				# delay slot
-
-1:
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
-
-	/* Wheee, local level zero interrupt. */
-	jal	indy_local0_irqdispatch
-	 move	a0, sp			# delay slot
-
-	j	ret_from_irq
-	 nop				# delay slot
-
-1:
-	beq	a0, zero, 1f
-	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
-
-	/* Wheee, local level one interrupt. */
-	move	a0, sp
-	jal	indy_local1_irqdispatch
-	 nop
-
-	j	ret_from_irq
-	 nop
-
-1:
-	beq	a0, zero, 1f
-	 nop
-
-	/* Wheee, an asynchronous bus error... */
-	move	a0, sp
-	jal	indy_buserror_irq
-	 nop
-
-	j	ret_from_irq
-	 nop
-
-1:
-	/* Here by mistake?  This is possible, what can happen
-	 * is that by the time we take the exception the IRQ
-	 * pin goes low, so just leave if this is the case.
-	 */
-	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
-	beq	a0, zero, 1f
-
-	/* Must be one of the 8254 timers... */
-	move	a0, sp
-	jal	indy_8254timer_irq
-	 nop
-1:
-	j	ret_from_irq
-	 nop
-	END(indyIRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-mc.c linux/arch/mips64/sgi-ip22/ip22-mc.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-mc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-mc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,158 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/addrspace.h>
-#include <asm/ptrace.h>
-#include <asm/sgi/sgimc.h>
-#include <asm/sgi/sgihpc.h>
-
-/* #define DEBUG_SGIMC */
-
-struct sgimc_misc_ctrl *mcmisc_regs;
-u32 *rpsscounter;
-struct sgimc_dma_ctrl *dmactrlregs;
-
-static inline char *mconfig_string(unsigned long val)
-{
-	switch(val & SGIMC_MCONFIG_RMASK) {
-	case SGIMC_MCONFIG_FOURMB:
-		return "4MB";
-
-	case SGIMC_MCONFIG_EIGHTMB:
-		return "8MB";
-
-	case SGIMC_MCONFIG_SXTEENMB:
-		return "16MB";
-
-	case SGIMC_MCONFIG_TTWOMB:
-		return "32MB";
-
-	case SGIMC_MCONFIG_SFOURMB:
-		return "64MB";
-
-	case SGIMC_MCONFIG_OTEIGHTMB:
-		return "128MB";
-
-	default:
-		return "wheee, unknown";
-	};
-}
-
-void __init sgimc_init(void)
-{
-	unsigned long tmpreg;
-
-	mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
-	rpsscounter = (u32 *) (KSEG1 + 0x1fa01004);
-	dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000);
-
-	printk("MC: SGI memory controller Revision %d\n",
-	       (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV);
-
-#if 0 /* XXX Until I figure out what this bit really indicates XXX */
-	/* XXX Is this systemid bit reliable? */
-	if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) {
-		EISA_bus = 1;
-		printk("with EISA\n");
-	} else {
-		EISA_bus = 0;
-		printk("no EISA\n");
-	}
-#endif
-
-#ifdef DEBUG_SGIMC
-	prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n",
-		    mconfig_string(mcmisc_regs->mconfig0),
-		    mconfig_string(mcmisc_regs->mconfig1));
-
-	prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n",
-		    mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1);
-	prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n",
-		    mcmisc_regs->divider, mcmisc_regs->gioparm);
-#endif
-
-	/* Place the MC into a known state.  This must be done before
-	 * interrupts are first enabled etc.
-	 */
-
-	/* Step 1: The CPU/GIO error status registers will not latch
-	 *         up a new error status until the register has been
-	 *         cleared by the cpu.  These status registers are
-	 *         cleared by writing any value to them.
-	 */
-	mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
-
-	/* Step 2: Enable all parity checking in cpu control register
-	 *         zero.
-	 */
-	tmpreg = mcmisc_regs->cpuctrl0;
-	tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
-		   SGIMC_CCTRL0_R4KNOCHKPARR);
-	mcmisc_regs->cpuctrl0 = tmpreg;
-
-	/* Step 3: Setup the MC write buffer depth, this is controlled
-	 *         in cpu control register 1 in the lower 4 bits.
-	 */
-	tmpreg = mcmisc_regs->cpuctrl1;
-	tmpreg &= ~0xf;
-	tmpreg |= 0xd;
-	mcmisc_regs->cpuctrl1 = tmpreg;
-
-	/* Step 4: Initialize the RPSS divider register to run as fast
-	 *         as it can correctly operate.  The register is laid
-	 *         out as follows:
-	 *
-	 *         ----------------------------------------
-	 *         |  RESERVED  |   INCREMENT   | DIVIDER |
-	 *         ----------------------------------------
-	 *          31        16 15            8 7       0
-	 *
-	 *         DIVIDER determines how often a 'tick' happens,
-	 *         INCREMENT determines by how the RPSS increment
-	 *         registers value increases at each 'tick'. Thus,
-	 *         for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
-	 */
-	mcmisc_regs->divider = 0x101;
-
-	/* Step 5: Initialize GIO64 arbitrator configuration register.
-	 *
-	 * NOTE: If you dork with startup code the HPC init code in
-	 *       sgihpc_init() must run before us because of how we
-	 *       need to know Guiness vs. FullHouse and the board
-	 *       revision on this machine.  You have been warned.
-	 */
-
-	/* First the basic invariants across all gio64 implementations. */
-	tmpreg = SGIMC_GIOPARM_HPC64;    /* All 1st HPC's interface at 64bits. */
-	tmpreg |= SGIMC_GIOPARM_ONEBUS;  /* Only one physical GIO bus exists. */
-
-	if(sgi_guiness) {
-		/* Guiness specific settings. */
-		tmpreg |= SGIMC_GIOPARM_EISA64;     /* MC talks to EISA at 64bits */
-		tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */
-	} else {
-		/* Fullhouse specific settings. */
-		if(sgi_boardid < 2) {
-			tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */
-			tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */
-			tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */
-			tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */
-		} else {
-			tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */
-			tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */
-			tmpreg |= SGIMC_GIOPARM_PLINEEXP1;
-			tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */
-			/* someone forgot this poor little guy... */
-			tmpreg |= SGIMC_GIOPARM_GFX64; 	/* GFX at 64 bits */
-		}
-	}
-	mcmisc_regs->gioparm = tmpreg; /* poof */
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-reset.c linux/arch/mips64/sgi-ip22/ip22-reset.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-reset.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-reset.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,238 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Reset an IP22.
- *
- * Copyright (C) 1997, 1998, 1999, 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/notifier.h>
-#include <linux/timer.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/sgialib.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-
-/*
- * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds.
- * I'm not shure if this feature is a good idea, for now it's here just to
- * make the power button make behave just like under IRIX.
- */
-#define POWERDOWN_TIMEOUT	120
-
-/*
- * Blink frequency during reboot grace period and when paniced.
- */
-#define POWERDOWN_FREQ		(HZ / 4)
-#define PANIC_FREQ		(HZ / 8)
-
-static unsigned char sgi_volume;
-
-static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer;
-static int shuting_down, has_paniced;
-
-void machine_restart(char *command) __attribute__((noreturn));
-void machine_halt(void) __attribute__((noreturn));
-void machine_power_off(void) __attribute__((noreturn));
-
-/* XXX How to pass the reboot command to the firmware??? */
-void machine_restart(char *command)
-{
-	if (shuting_down)
-		machine_power_off();
-	ArcReboot();
-}
-
-void machine_halt(void)
-{
-	if (shuting_down)
-		machine_power_off();
-	ArcEnterInteractiveMode();
-}
-
-void machine_power_off(void)
-{
-	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
-
-	cli();
-
-	clock->cmd |= 0x08;	/* Disable watchdog */
-	clock->whsec = 0;
-	clock->wsec = 0;
-
-	while(1) {
-		hpc3mregs->panel=0xfe;
-		/* Good bye cruel world ...  */
-
-		/* If we're still running, we probably got sent an alarm
-		   interrupt.  Read the flag to clear it.  */
-		clock->halarm;
-	}
-}
-
-static void power_timeout(unsigned long data)
-{
-	machine_power_off();
-}
-
-static void blink_timeout(unsigned long data)
-{
-	/* XXX Fix this for Fullhouse  */
-	sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF);
-	hpc3mregs->write1 = sgi_hpc_write1;
-
-	mod_timer(&blink_timer, jiffies+data);
-}
-
-static void debounce(unsigned long data)
-{
-	del_timer(&debounce_timer);
-	if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent.  */
-		debounce_timer.expires = jiffies + 5; /* 0.05s  */
-		add_timer(&debounce_timer);
-
-		hpc3mregs->panel = 0xf3;
-
-		return;
-	}
-
-	if (has_paniced)
-		ArcReboot();
-
-	enable_irq(9);
-}
-
-static inline void power_button(void)
-{
-	if (has_paniced)
-		return;
-
-	if (shuting_down || kill_proc(1, SIGINT, 1)) {
-		/* No init process or button pressed twice.  */
-		machine_power_off();
-	}
-
-	shuting_down = 1;
-	blink_timer.data = POWERDOWN_FREQ;
-	blink_timeout(POWERDOWN_FREQ);
-
-	init_timer(&power_timer);
-	power_timer.function = power_timeout;
-	power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
-	add_timer(&power_timer);
-}
-
-void inline ip22_volume_set(unsigned char volume)
-{
-	sgi_volume = volume;
-
-	hpc3c0->pbus_extregs[2][0] = sgi_volume;
-	hpc3c0->pbus_extregs[2][1] = sgi_volume;
-}
-
-void inline ip22_volume_get(unsigned char *volume)
-{
-	*volume = sgi_volume;
-}
-
-static inline void volume_up_button(unsigned long data)
-{
-	del_timer(&volume_timer);
-
-	if (sgi_volume < 0xff)
-		sgi_volume++;
-
-	hpc3c0->pbus_extregs[2][0] = sgi_volume;
-	hpc3c0->pbus_extregs[2][1] = sgi_volume;
-
-	if (ioc_icontrol->istat1 & 2) {
-		volume_timer.expires = jiffies + 1;
-		add_timer(&volume_timer);
-	}
-
-}
-
-static inline void volume_down_button(unsigned long data)
-{
-	del_timer(&volume_timer);
-
-	if (sgi_volume > 0)
-		sgi_volume--;
-
-	hpc3c0->pbus_extregs[2][0] = sgi_volume;
-	hpc3c0->pbus_extregs[2][1] = sgi_volume;
-
-	if (ioc_icontrol->istat1 & 2) {
-		volume_timer.expires = jiffies + 1;
-		add_timer(&volume_timer);
-	}
-}
-
-static void panel_int(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned int buttons;
-
-	buttons = hpc3mregs->panel;
-	hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */
-
-	if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */
-		disable_irq(9);
-		init_timer(&debounce_timer);
-		debounce_timer.function = debounce;
-		debounce_timer.expires = jiffies + 5;
-		add_timer(&debounce_timer);
-	}
-
-	if (!(buttons & 2))		/* Power button was pressed */
-		power_button();
-	if (!(buttons & 0x40)) {	/* Volume up button was pressed */
-		init_timer(&volume_timer);
-		volume_timer.function = volume_up_button;
-		volume_timer.expires = jiffies + 1;
-		add_timer(&volume_timer);
-	}
-	if (!(buttons & 0x10)) {	/* Volume down button was pressed */
-		init_timer(&volume_timer);
-		volume_timer.function = volume_down_button;
-		volume_timer.expires = jiffies + 1;
-		add_timer(&volume_timer);
-	}
-}
-
-static int panic_event(struct notifier_block *this, unsigned long event,
-                      void *ptr)
-{
-	if (has_paniced)
-		return NOTIFY_DONE;
-	has_paniced = 1;
-
-	blink_timer.data = PANIC_FREQ;
-	blink_timeout(PANIC_FREQ);
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block panic_block = {
-	panic_event,
-	NULL,
-	0
-};
-
-void ip22_reboot_setup(void)
-{
-	static int setup_done;
-
-	if (setup_done)
-		return;
-	setup_done = 1;
-
-	request_irq(9, panel_int, 0, "Front Panel", NULL);
-	init_timer(&blink_timer);
-	blink_timer.function = blink_timeout;
-	notifier_chain_register(&panic_notifier_list, &panic_block);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-rtc.c linux/arch/mips64/sgi-ip22/ip22-rtc.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-rtc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * RTC routines for Indy style attached Dallas chip.
- *
- * Copyright (C) 1998, 2001 by Ralf Baechle
- */
-#include <linux/mc146818rtc.h>
-#include <asm/sgi/sgihpc.h>
-
-static unsigned char indy_rtc_read_data(unsigned long addr)
-{
-	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
-
-	return rtcregs[addr];
-}
-
-static void indy_rtc_write_data(unsigned char data, unsigned long addr)
-{
-	volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS;
-
-	rtcregs[addr] = data;
-}
-
-static int indy_rtc_bcd_mode(void)
-{
-	return 0;
-}
-
-struct rtc_ops indy_rtc_ops = {
-	&indy_rtc_read_data,
-	&indy_rtc_write_data,
-	&indy_rtc_bcd_mode
-};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-sc.c linux/arch/mips64/sgi-ip22/ip22-sc.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-sc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-sc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,164 +0,0 @@
-/*
- * indy_sc.c: Indy cache management functions.
- *
- * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org),
- * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/bcache.h>
-#include <asm/sgi/sgimc.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/bootinfo.h>
-#include <asm/mmu_context.h>
-
-/* Secondary cache size in bytes, if present.  */
-static unsigned long scache_size;
-
-#undef DEBUG_CACHE
-
-#define SC_SIZE 0x00080000
-#define SC_LINE 32
-#define CI_MASK (SC_SIZE - SC_LINE)
-#define SC_INDEX(n) ((n) & CI_MASK)
-
-static inline void indy_sc_wipe(unsigned long first, unsigned long last)
-{
-	__asm__ __volatile__(
-	".set\tnoreorder\n\t"
-	"or\t%0, %4\t\t\t# first line to flush\n\t"
-	"or\t%1, %4\t\t\t# last line to flush\n"
-	"1:\tsw	$0, 0(%0)\n\t"
-	"bne\t%0, %1, 1b\n\t"
-	"daddu\t%0, 32\n\t"
-	".set reorder"
-	: "=r" (first), "=r" (last)
-	: "0" (first), "1" (last), "r" (0x9000000080000000)
-	: "$1");
-}
-
-static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size)
-{
-	unsigned long first_line, last_line;
-	unsigned int flags;
-
-#ifdef DEBUG_CACHE
-	printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
-#endif
-
-	if (!size)
-		return;
-
-	/* Which lines to flush?  */
-	first_line = SC_INDEX(addr);
-	last_line = SC_INDEX(addr + size - 1);
-
-	__save_and_cli(flags);
-	if (first_line <= last_line) {
-		indy_sc_wipe(first_line, last_line);
-		goto out;
-	}
-
-	indy_sc_wipe(first_line, SC_SIZE - SC_LINE);
-	indy_sc_wipe(0, last_line);
-out:
-	__restore_flags(flags);
-}
-
-static void inline indy_sc_enable(void)
-{
-#ifdef DEBUG_CACHE
-	printk("Enabling R4600 SCACHE\n");
-#endif
-	*(volatile unsigned char *) 0x9000000080000000 = 0;
-}
-
-static void indy_sc_disable(void)
-{
-#ifdef DEBUG_CACHE
-	printk("Disabling R4600 SCACHE\n");
-#endif
-	*(volatile unsigned short *) 0x9000000080000000 = 0;
-}
-
-static inline __init int indy_sc_probe(void)
-{
-	volatile u32 *cpu_control;
-	unsigned short cmd = 0xc220;
-	unsigned long data = 0;
-	int i, n;
-
-#ifdef __MIPSEB__
-	cpu_control = (volatile u32 *) KSEG1ADDR(0x1fa00034);
-#else
-	cpu_control = (volatile u32 *) KSEG1ADDR(0x1fa00030);
-#endif
-#define DEASSERT(bit) (*(cpu_control) &= (~(bit)))
-#define ASSERT(bit) (*(cpu_control) |= (bit))
-#define DELAY  for(n = 0; n < 100000; n++) __asm__ __volatile__("")
-	DEASSERT(SGIMC_EEPROM_PRE);
-	DEASSERT(SGIMC_EEPROM_SDATAO);
-	DEASSERT(SGIMC_EEPROM_SECLOCK);
-	DEASSERT(SGIMC_EEPROM_PRE);
-	DELAY;
-	ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK);
-	for(i = 0; i < 11; i++) {
-		if(cmd & (1<<15))
-			ASSERT(SGIMC_EEPROM_SDATAO);
-		else
-			DEASSERT(SGIMC_EEPROM_SDATAO);
-		DEASSERT(SGIMC_EEPROM_SECLOCK);
-		ASSERT(SGIMC_EEPROM_SECLOCK);
-		cmd <<= 1;
-	}
-	DEASSERT(SGIMC_EEPROM_SDATAO);
-	for(i = 0; i < (sizeof(unsigned short) * 8); i++) {
-		unsigned int tmp;
-
-		DEASSERT(SGIMC_EEPROM_SECLOCK);
-		DELAY;
-		ASSERT(SGIMC_EEPROM_SECLOCK);
-		DELAY;
-		data <<= 1;
-		tmp = *cpu_control;
-		if(tmp & SGIMC_EEPROM_SDATAI)
-			data |= 1;
-	}
-	DEASSERT(SGIMC_EEPROM_SECLOCK);
-	DEASSERT(SGIMC_EEPROM_CSEL);
-	ASSERT(SGIMC_EEPROM_PRE);
-	ASSERT(SGIMC_EEPROM_SECLOCK);
-
-	data <<= PAGE_SHIFT;
-	if (data == 0)
-		return 0;
-
-	scache_size = data;
-
-	printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n",
-	       scache_size >> 10);
-
-	return 1;
-}
-
-/* XXX Check with wje if the Indy caches can differenciate between
-   writeback + invalidate and just invalidate.  */
-static struct bcache_ops indy_sc_ops = {
-	indy_sc_enable,
-	indy_sc_disable,
-	indy_sc_wback_invalidate,
-	indy_sc_wback_invalidate
-};
-
-void __init indy_sc_init(void)
-{
-	if (indy_sc_probe()) {
-		indy_sc_enable();
-		bcops = &indy_sc_ops;
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-setup.c linux/arch/mips64/sgi-ip22/ip22-setup.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,189 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * SGI IP22 specific setup.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999 Silcon Graphics, Inc.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kbd_ll.h>
-#include <linux/kernel.h>
-#include <linux/kdev_t.h>
-#include <linux/types.h>
-#include <linux/console.h>
-#include <linux/sched.h>
-#include <linux/mc146818rtc.h>
-#include <linux/pc_keyb.h>
-#include <linux/tty.h>
-
-#include <asm/addrspace.h>
-#include <asm/mmu_context.h>
-#include <asm/bcache.h>
-#include <asm/keyboard.h>
-#include <asm/irq.h>
-#include <asm/sgialib.h>
-#include <asm/sgi/sgi.h>
-#include <asm/sgi/sgimc.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-
-extern struct rtc_ops indy_rtc_ops;
-extern void ip22_reboot_setup(void);
-extern void ip22_volume_set(unsigned char);
-
-#define sgi_kh ((struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64))
-
-#define KBD_STAT_IBF		0x02	/* Keyboard input buffer full */
-
-static void ip22_request_region(void)
-{
-	/* No I/O ports are being used on the Indy.  */
-}
-
-static int ip22_request_irq(void (*handler)(int, void *, struct pt_regs *))
-{
-	/* Dirty hack, this get's called as a callback from the keyboard
-	   driver.  We piggyback the initialization of the front panel
-	   button handling on it even though they're technically not
-	   related with the keyboard driver in any way.  Doing it from
-	   indy_setup wouldn't work since kmalloc isn't initialized yet.  */
-	ip22_reboot_setup();
-
-	return request_irq(SGI_KEYBOARD_IRQ, handler, 0, "keyboard", NULL);
-}
-
-static int ip22_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
-{
-	/* Nothing to do, interrupt is shared with the keyboard hw  */
-	return 0;
-}
-
-static void ip22_aux_free_irq(void)
-{
-	/* Nothing to do, interrupt is shared with the keyboard hw  */
-}
-
-static unsigned char ip22_read_input(void)
-{
-	return sgi_kh->data;
-}
-
-static void ip22_write_output(unsigned char val)
-{
-	int status;
-
-	do {
-		status = sgi_kh->command;
-	} while (status & KBD_STAT_IBF);
-	sgi_kh->data = val;
-}
-
-static void ip22_write_command(unsigned char val)
-{
-	int status;
-
-	do {
-		status = sgi_kh->command;
-	} while (status & KBD_STAT_IBF);
-	sgi_kh->command = val;
-}
-
-static unsigned char ip22_read_status(void)
-{
-	return sgi_kh->command;
-}
-
-struct kbd_ops sgi_kbd_ops = {
-	ip22_request_region,
-	ip22_request_irq,
-
-	ip22_aux_request_irq,
-	ip22_aux_free_irq,
-
-	ip22_read_input,
-	ip22_write_output,
-	ip22_write_command,
-	ip22_read_status
-};
-
-int __init page_is_ram(unsigned long pagenr)
-{
-	if ((pagenr<<PAGE_SHIFT) < 0x2000UL)
-		return 1;
-	if ((pagenr<<PAGE_SHIFT) > 0x08002000)
-		return 1;
-	return 0;
-}
-
-void __init ip22_setup(void)
-{
-#ifdef CONFIG_SERIAL_CONSOLE
-	char *ctype;
-#endif
-	TLBMISS_HANDLER_SETUP();
-
-	/* Init the INDY HPC I/O controller.  Need to call this before
-	 * fucking with the memory controller because it needs to know the
-	 * boardID and whether this is a Guiness or a FullHouse machine.
-	 */
-	sgihpc_init();
-
-	/* Init INDY memory controller. */
-	sgimc_init();
-
-	/* Now enable boardcaches, if any. */
-	indy_sc_init();
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	/* ARCS console environment variable is set to "g?" for
-	 * graphics console, it is set to "d" for the first serial
-	 * line and "d2" for the second serial line.
-	 */
-	ctype = ArcGetEnvironmentVariable("console");
-	if(*ctype == 'd') {
-		if(*(ctype+1)=='2')
-			console_setup ("ttyS1");
-		else
-			console_setup ("ttyS0");
-	}
-#endif
-#ifdef CONFIG_ARC_CONSOLE
-	console_setup("ttyS0");
-#endif
-
-	ip22_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"),
-	                              NULL, 10));
-
-#ifdef CONFIG_VT
-#ifdef CONFIG_SGI_NEWPORT_CONSOLE
-	conswitchp = &newport_con;
-
-	screen_info = (struct screen_info) {
-		0, 0,		/* orig-x, orig-y */
-		0,		/* unused */
-		0,		/* orig_video_page */
-		0,		/* orig_video_mode */
-		160,		/* orig_video_cols */
-		0, 0, 0,	/* unused, ega_bx, unused */
-		64,		/* orig_video_lines */
-		0,		/* orig_video_isVGA */
-		16		/* orig_video_points */
-	};
-#else
-	conswitchp = &dummy_con;
-#endif
-#endif
-	rtc_ops = &indy_rtc_ops;
-	kbd_ops = &sgi_kbd_ops;
-#ifdef CONFIG_PSMOUSE
-	aux_device_present = 0xaa;
-#endif
-#ifdef CONFIG_VIDEO_VINO
-	init_vino();
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/ip22-timer.c linux/arch/mips64/sgi-ip22/ip22-timer.c
--- linux.orig/arch/mips64/sgi-ip22/ip22-timer.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/ip22-timer.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,262 +0,0 @@
-/*
- * indy_timer.c: Setting up the clock on the INDY 8254 controller.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copytight (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/kernel_stat.h>
-
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/ptrace.h>
-#include <asm/system.h>
-#include <asm/sgi/sgi.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-#include <asm/sgialib.h>
-
-
-/* Because of a bug in the i8254 timer we need to use the onchip r4k
- * counter as our system wide timer interrupt running at 100HZ.
- */
-static unsigned long r4k_offset; /* Amount to increment compare reg each time */
-static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-
-extern rwlock_t xtime_lock;
-
-static inline void ack_r4ktimer(unsigned long newval)
-{
-	write_32bit_cp0_register(CP0_COMPARE, newval);
-}
-
-static int set_rtc_mmss(unsigned long nowtime)
-{
-	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
-	int retval = 0;
-	int real_seconds, real_minutes, clock_minutes;
-
-#define FROB_FROM_CLOCK(x) (((x) & 0xf) | ((((x) & 0xf0) >> 4) * 10));
-#define FROB_TO_CLOCK(x)  ((((((x) & 0xff) / 10)<<4) | (((x) & 0xff) % 10)) & 0xff)
-
-	clock->cmd &= ~(0x80);
-	clock_minutes = clock->min;
-	clock->cmd |= (0x80);
-
-	clock_minutes = FROB_FROM_CLOCK(clock_minutes);
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-
-	if(((abs(real_minutes - clock_minutes) + 15)/30) & 1)
-		real_minutes += 30; /* correct for half hour time zone */
-
-	real_minutes %= 60;
-	if(abs(real_minutes - clock_minutes) < 30) {
-		/* Force clock oscillator to be on. */
-		clock->month &= ~(0x80);
-
-		/* Write real_seconds and real_minutes into the Dallas. */
-		clock->cmd &= ~(0x80);
-		clock->sec = real_seconds;
-		clock->min = real_minutes;
-		clock->cmd |= (0x80);
-	} else
-		return -1;
-
-#undef FROB_FROM_CLOCK
-#undef FROB_TO_CLOCK
-
-	return retval;
-}
-
-static long last_rtc_update;
-unsigned long missed_heart_beats;
-
-void indy_timer_interrupt(struct pt_regs *regs)
-{
-	unsigned long count;
-	int irq = 7;
-
-	write_lock(&xtime_lock);
-	/* Ack timer and compute new compare. */
-	count = read_32bit_cp0_register(CP0_COUNT);
-	/* This has races.  */
-	if ((count - r4k_cur) >= r4k_offset) {
-		/* If this happens to often we'll need to compensate.  */
-		missed_heart_beats++;
-		r4k_cur = count + r4k_offset;
-	}
-        else
-            r4k_cur += r4k_offset;
-	ack_r4ktimer(r4k_cur);
-	kstat.irqs[0][irq]++;
-	do_timer(regs);
-
-	/* We update the Dallas time of day approx. every 11 minutes,
-	 * because of how the numbers work out we need to make
-	 * absolutely sure we do this update within 500ms before the
-	 * next second starts, thus the following code.
-	 */
-	if ((time_status & STA_UNSYNC) == 0 &&
-	    xtime.tv_sec > last_rtc_update + 660 &&
-	    xtime.tv_usec >= 500000 - (tick >> 1) &&
-	    xtime.tv_usec <= 500000 + (tick >> 1)) {
-		if (set_rtc_mmss(xtime.tv_sec) == 0)
-			last_rtc_update = xtime.tv_sec;
-		else
-			/* do it again in 60s  */
-			last_rtc_update = xtime.tv_sec - 600;
-	}
-	write_unlock(&xtime_lock);
-}
-
-static unsigned long dosample(volatile unsigned char *tcwp,
-                              volatile unsigned char *tc2p)
-{
-	unsigned long ct0, ct1;
-	unsigned char msb, lsb;
-
-	/* Start the counter. */
-	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN);
-	*tc2p = (SGINT_TCSAMP_COUNTER & 0xff);
-	*tc2p = (SGINT_TCSAMP_COUNTER >> 8);
-
-	/* Get initial counter invariant */
-	ct0 = read_32bit_cp0_register(CP0_COUNT);
-
-	/* Latch and spin until top byte of counter2 is zero */
-	do {
-		*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT);
-		lsb = *tc2p;
-		msb = *tc2p;
-		ct1 = read_32bit_cp0_register(CP0_COUNT);
-	} while(msb);
-
-	/* Stop the counter. */
-	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST);
-
-	/* Return the difference, this is how far the r4k counter increments
-	 * for every one HZ.
-	 */
-	return ct1 - ct0;
-}
-
-static unsigned long __init get_indy_time(void)
-{
-	struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
-	unsigned int year, mon, day, hour, min, sec;
-
-	/* Freeze it. */
-	clock->cmd &= ~(0x80);
-
-	/* Read regs. */
-	sec = clock->sec;
-	min = clock->min;
-	hour = (clock->hr & 0x3f);
-	day = (clock->date & 0x3f);
-	mon = (clock->month & 0x1f);
-	year = clock->year;
-
-	/* Unfreeze clock. */
-	clock->cmd |= 0x80;
-
-	/* Frob the bits. */
-#define FROB1(x)  (((x) & 0xf) + ((((x) & 0xf0) >> 4) * 10));
-#define FROB2(x)  (((x) & 0xf) + (((((x) & 0xf0) >> 4) & 0x3) * 10));
-
-	/* XXX Should really check that secs register is the same
-	 * XXX as when we first read it and if not go back and
-	 * XXX read the regs above again.
-	 */
-	sec = FROB1(sec); min = FROB1(min); day = FROB1(day);
-	mon = FROB1(mon); year = FROB1(year);
-	hour = FROB2(hour);
-
-#undef FROB1
-#undef FROB2
-
-	/* Wheee... */
-	if(year < 45)
-		year += 30;
-	if ((year += 1940) < 1970)
-		year += 100;
-
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-
-void __init indy_timer_init(void)
-{
-	struct sgi_ioc_timers *p;
-	volatile unsigned char *tcwp, *tc2p;
-
-	/* Figure out the r4k offset, the algorithm is very simple and works
-	 * in _all_ cases as long as the 8254 counter register itself works ok
-	 * (as an interrupt driving timer it does not because of bug, this is
-	 * why we are using the onchip r4k counter/compare register to serve
-	 * this purpose, but for r4k_offset calculation it will work ok for us).
-	 * There are other very complicated ways of performing this calculation
-	 * but this one works just fine so I am not going to futz around. ;-)
-	 */
-	p = ioc_timers;
-	tcwp = &p->tcword;
-	tc2p = &p->tcnt2;
-
-	printk("calculating r4koff... ");
-	dosample(tcwp, tc2p);			/* First sample. */
-	dosample(tcwp, tc2p);			/* Eat one.	*/
-	r4k_offset = dosample(tcwp, tc2p);	/* Second sample. */
-
-	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
-
-	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
-	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
-	set_cp0_status(ST0_IM, ALLINTS);
-	sti();
-
-	write_lock_irq(&xtime_lock);
-	xtime.tv_sec = get_indy_time();		/* Read time from RTC. */
-	xtime.tv_usec = 0;
-	write_unlock_irq(&xtime_lock);
-}
-
-void indy_8254timer_irq(void)
-{
-	int cpu = smp_processor_id();
-	int irq = 4;
-
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
-	panic("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
-	irq_exit(cpu, irq);
-}
-
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-
-	read_lock_irqsave(&xtime_lock, flags);
-	*tv = xtime;
-	read_unlock_irqrestore(&xtime_lock, flags);
-}
-
-void do_settimeofday(struct timeval *tv)
-{
-	write_lock_irq(&xtime_lock);
-	xtime = *tv;
-	time_adjust = 0;		/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/system.c linux/arch/mips64/sgi-ip22/system.c
--- linux.orig/arch/mips64/sgi-ip22/system.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/system.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,123 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * system.c: Probe the system type using ARCS prom interface library.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-
-#include <asm/sgi/sgi.h>
-#include <asm/sgialib.h>
-#include <asm/bootinfo.h>
-
-struct smatch {
-	char *name;
-	int type;
-};
-
-static struct smatch sgi_cputable[] = {
-	{ "MIPS-R2000", CPU_R2000 },
-	{ "MIPS-R3000", CPU_R3000 },
-	{ "MIPS-R3000A", CPU_R3000A },
-	{ "MIPS-R4000", CPU_R4000SC },
-	{ "MIPS-R4400", CPU_R4400SC },
-	{ "MIPS-R4600", CPU_R4600 },
-	{ "MIPS-R8000", CPU_R8000 },
-	{ "MIPS-R5000", CPU_R5000 },
-	{ "MIPS-R5000A", CPU_R5000A }
-};
-
-#define NUM_CPUS 9 /* for now */
-
-static int __init string_to_cpu(char *s)
-{
-	int i;
-
-	for(i = 0; i < NUM_CPUS; i++) {
-		if(!strcmp(s, sgi_cputable[i].name))
-			return sgi_cputable[i].type;
-	}
-	panic("\nYeee, could not determine MIPS cpu type <%s>", s);
-	return 0;
-}
-
-/*
- * We' call this early before loadmmu().  If we do the other way around
- * the firmware will crash and burn.
- */
-void __init sgi_sysinit(void)
-{
-	pcomponent *p, *toplev, *cpup = 0;
-	int cputype = -1;
-
-
-	/* The root component tells us what machine architecture we
-	 * have here.
-	 */
-	p = ArcGetChild(PROM_NULL_COMPONENT);
-
-	/* Now scan for cpu(s). */
-	toplev = p = ArcGetChild(p);
-	while(p) {
-		int ncpus = 0;
-
-		if(p->type == Cpu) {
-			if (++ncpus > 1)
-				panic("\nYeee, SGI MP not ready yet");
-			printk("CPU: %s ", p->iname);
-			cpup = p;
-			cputype = string_to_cpu(cpup->iname);
-		}
-		p = ArcGetPeer(p);
-	}
-	if (cputype == -1) {
-		panic("\nYeee, could not find cpu ARCS component");
-	}
-	p = ArcGetChild(cpup);
-	while(p) {
-		switch(p->class) {
-		case processor:
-			switch(p->type) {
-			case Fpu:
-				printk("FPU<%s> ", p->iname);
-				break;
-
-			default:
-				break;
-			};
-			break;
-
-		case cache:
-			switch(p->type) {
-			case picache:
-				printk("ICACHE ");
-				break;
-
-			case pdcache:
-				printk("DCACHE ");
-				break;
-
-			case sccache:
-				printk("SCACHE ");
-				break;
-
-			default:
-				break;
-
-			};
-			break;
-
-		default:
-			break;
-		};
-		p = ArcGetPeer(p);
-	}
-	printk("\n");
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip22/time.c linux/arch/mips64/sgi-ip22/time.c
--- linux.orig/arch/mips64/sgi-ip22/time.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip22/time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * time.c: Generic SGI time_init() code, this will dispatch to the
- *         appropriate per-architecture time/counter init code.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-
-extern void indy_timer_init(void);
-
-void __init time_init(void)
-{
-	/* XXX assume INDY for now XXX */
-	indy_timer_init();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/Makefile linux/arch/mips64/sgi-ip27/Makefile
--- linux.orig/arch/mips64/sgi-ip27/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -2,13 +2,12 @@
 # Makefile for the IP27 specific kernel interface routines under Linux.
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET = ip27.o
 
+export-objs		= ip27-rtc.o
+
 obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
 	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
 	   ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-berr.c linux/arch/mips64/sgi-ip27/ip27-berr.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-berr.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-berr.c	2002-07-20 01:08:29.000000000 +0000
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
  * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -14,86 +15,12 @@
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/sn0/hub.h>
+#include <asm/traps.h>
 #include <asm/uaccess.h>
 
 extern void dump_tlb_addr(unsigned long addr);
 extern void dump_tlb_all(void);
 
-extern asmlinkage void handle_ibe(void);
-extern asmlinkage void handle_dbe(void);
-
-extern const struct exception_table_entry __start___dbe_table[];
-extern const struct exception_table_entry __stop___dbe_table[];
-
-static inline unsigned long
-search_one_table(const struct exception_table_entry *first,
-                 const struct exception_table_entry *last,
-                 unsigned long value)
-{
-	while (first <= last) {
-		const struct exception_table_entry *mid;
-		long diff;
-
-		mid = (last - first) / 2 + first;
-		diff = mid->insn - value;
-		if (diff == 0)
-			return mid->nextinsn;
-		else if (diff < 0)
-			first = mid+1;
-		else
-			last = mid-1;
-	}
-	return 0;
-}
-
-extern spinlock_t modlist_lock;
-
-static inline unsigned long
-search_dbe_table(unsigned long addr)
-{
-	unsigned long ret;
-
-#ifndef CONFIG_MODULES
-	/* There is only the kernel to search.  */
-	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
-	return ret;
-#else
-	unsigned long flags;
-
-	/* The kernel is the last "module" -- no need to treat it special.  */
-	struct module *mp;
-	struct archdata *ap;
-
-	spin_lock_irqsave(&modlist_lock, flags);
-	for (mp = module_list; mp != NULL; mp = mp->next) {
-		if (!mod_member_present(mp, archdata_end) ||
-        	    !mod_archdata_member_present(mp, struct archdata,
-						 dbe_table_end))
-			continue;
-		ap = (struct archdata *)(mod->archdata_start);
-
-		if (ap->dbe_table_start == NULL ||
-		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
-			continue;
-		ret = search_one_table(ap->dbe_table_start,
-				       ap->dbe_table_end - 1, addr);
-		if (ret)
-			break;
-	}
-	spin_unlock_irqrestore(&modlist_lock, flags);
-	return ret;
-#endif
-}
-
-void do_ibe(struct pt_regs *regs)
-{
-	printk("Got ibe at 0x%lx\n", regs->cp0_epc);
-	show_regs(regs);
-	dump_tlb_addr(regs->cp0_epc);
-	force_sig(SIGBUS, current);
-	while(1);
-}
-
 static void dump_hub_information(unsigned long errst0, unsigned long errst1)
 {
 	static char *err_type[2][8] = {
@@ -127,21 +54,17 @@
 		? : "invalid");
 }
 
-void do_dbe(struct pt_regs *regs)
+int be_ip27_handler(struct pt_regs *regs, int is_fixup)
 {
-	unsigned long fixup, errst0, errst1;
+	unsigned long errst0, errst1;
+	int data = regs->cp0_cause & 4;
 	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
 
-	fixup = search_dbe_table(regs->cp0_epc);
-	if (fixup) {
-		long new_epc;
-
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
-	}
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
 
-	printk("Slice %c got dbe at 0x%lx\n", 'A' + cpu, regs->cp0_epc);
+	printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
+	       regs->cp0_epc);
 	printk("Hub information:\n");
 	printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
 	errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
@@ -153,15 +76,13 @@
 	force_sig(SIGBUS, current);
 }
 
-void __init
-bus_error_init(void)
+void __init bus_error_init(void)
 {
 	/* XXX Initialize all the Hub & Bridge error handling here.  */
 	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
 	int cpuoff = cpu << 8;
 
-	set_except_vector(6, handle_ibe);
-	set_except_vector(7, handle_dbe);
+	be_board_handler = be_ip27_handler;
 
 	LOCAL_HUB_S(PI_ERR_INT_PEND,
 	            cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-dbe-glue.S linux/arch/mips64/sgi-ip27/ip27-dbe-glue.S
--- linux.orig/arch/mips64/sgi-ip27/ip27-dbe-glue.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-dbe-glue.S	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,20 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics
+ *
+ * Low level exception handling
+ */
+#define __ASSEMBLY__
+#include <linux/init.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/exception.h>
+
+	BUILD_HANDLER ip27_ibe ip27_ibe cli silent		/* #6  */
+	BUILD_HANDLER ip27_dbe ip27_dbe cli silent		/* #7  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-init.c linux/arch/mips64/sgi-ip27/ip27-init.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-init.c	2001-11-21 18:31:09.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-init.c	2002-07-20 01:08:40.000000000 +0000
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/mmzone.h>	/* for numnodes */
 #include <linux/mm.h>
+#include <asm/cpu.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/sn/types.h>
@@ -359,12 +360,11 @@
 	int cpu = smp_processor_id();
 	cnodeid_t cnode = get_compact_nodeid();
 
-	current_cpu_data.asid_cache = ASID_FIRST_VERSION;
 	TLBMISS_HANDLER_SETUP();
 #if 0
 	intr_init();
 #endif
-	set_cp0_status(ST0_IM, 0);
+	clear_cp0_status(ST0_IM);
 	per_hub_init(cnode);
 	cpu_time_init();
 	if (smp_processor_id())	/* master can't do this early, no kmalloc */
@@ -374,12 +374,12 @@
 #if 0
 	install_tlbintr(cpu);
 #endif
-	set_cp0_status(SRB_DEV0 | SRB_DEV1, SRB_DEV0 | SRB_DEV1);
+	set_cp0_status(SRB_DEV0 | SRB_DEV1);
 	if (is_slave) {
-		set_cp0_status(ST0_BEV, 0);
-		if (mips4_available)
-			set_cp0_status(ST0_XX, ST0_XX);
-		set_cp0_status(ST0_KX|ST0_SX|ST0_UX, ST0_KX|ST0_SX|ST0_UX);
+		clear_cp0_status(ST0_BEV);
+		if (mips_cpu.isa_level == MIPS_CPU_ISA_IV)
+			set_cp0_status(ST0_XX);
+		set_cp0_status(ST0_KX|ST0_SX|ST0_UX);
 		sti();
 		load_mmu();
 		atomic_inc(&numstarted);
@@ -420,47 +420,30 @@
 	cpu_data[cpunum].p_cpuid = cpu;
 }
 
-void __init smp_callin(void)
-{
-#if 0
-	calibrate_delay();
-	smp_store_cpu_info(cpuid);
-#endif
-}
-
-int __init start_secondary(void)
-{
-	extern int cpu_idle(void);
-	extern atomic_t smp_commenced;
-
-	smp_callin();
-	while (!atomic_read(&smp_commenced));
-	return cpu_idle();
-}
-
 static volatile cpumask_t boot_barrier;
 
-void cboot(void)
+void __init start_secondary(void)
 {
 	CPUMASK_CLRB(boot_barrier, getcpuid());	/* needs atomicity */
 	per_cpu_init();
+	per_cpu_trap_init();
 #if 0
 	ecc_init();
 	bte_lateinit();
 	init_mfhi_war();
 #endif
-	_flush_tlb_all();
+	local_flush_tlb_all();
 	flush_cache_l1();
 	flush_cache_l2();
 	start_secondary();
 }
 
-void allowboot(void)
+__init void allowboot(void)
 {
 	int		num_cpus = 0;
 	cpuid_t		cpu, mycpuid = getcpuid();
 	cnodeid_t	cnode;
-	extern void	bootstrap(void);
+	extern void	smp_bootstrap(void);
 
 	sn_mp_setup();
 	/* Master has already done per_cpu_init() */
@@ -502,16 +485,16 @@
 			/* Attach to the address space of init_task. */
 			atomic_inc(&init_mm.mm_count);
 			p->active_mm = &init_mm;
-			
+
 			/*
-		 	 * Launch a slave into bootstrap().
+		 	 * Launch a slave into smp_bootstrap().
 		 	 * It doesn't take an argument, and we
 			 * set sp to the kernel stack of the newly 
 			 * created idle process, gp to the proc struct
 			 * (so that current-> works).
 		 	 */
 			LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus), 
-				(launch_proc_t)MAPPED_KERN_RW_TO_K0(bootstrap),
+				(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
 				0, (void *)((unsigned long)p + 
 				KERNEL_STACK_SIZE - 32), (void *)p);
 
@@ -522,6 +505,7 @@
 			 */
 			__cpu_number_map[cpu] = num_cpus;
 			__cpu_logical_map[num_cpus] = cpu;
+			CPUMASK_SETB(cpu_online_map, cpu);
 			num_cpus++;
 			/*
 			 * Wait this cpu to start up and initialize its hub,
@@ -554,8 +538,22 @@
 	smp_num_cpus = num_cpus;
 }
 
+void __init smp_boot_cpus(void)
+{
+	extern void allowboot(void);
+
+	init_new_context(current, &init_mm);
+	current->processor = 0;
+	init_idle();
+	smp_tune_scheduling();
+	allowboot();
+}
+
 #else /* CONFIG_SMP */
-void cboot(void) {}
+void __init start_secondary(void)
+{
+	/* XXX Why do we need this empty definition at all?  */
+}
 #endif /* CONFIG_SMP */
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-irq.c linux/arch/mips64/sgi-ip27/ip27-irq.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-irq.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-irq.c	2002-07-20 01:08:37.000000000 +0000
@@ -19,7 +19,6 @@
 #include <linux/smp_lock.h>
 #include <linux/kernel_stat.h>
 #include <linux/delay.h>
-#include <linux/irq.h>
 
 #include <asm/bitops.h>
 #include <asm/bootinfo.h>
@@ -33,10 +32,13 @@
 #include <asm/pci/bridge.h>
 #include <asm/sn/sn0/hub.h>
 #include <asm/sn/sn0/ip27.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/agent.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/intr_public.h>
 
+
 #undef DEBUG_IRQ
 #ifdef DEBUG_IRQ
 #define DBG(x...) printk(x)
@@ -66,12 +68,12 @@
  */
 
 extern asmlinkage void ip27_irq(void);
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
 extern int irq_to_bus[], irq_to_slot[], bus_to_cpu[];
 int intr_connect_level(int cpu, int bit);
 int intr_disconnect_level(int cpu, int bit);
 
-unsigned long spurious_count = 0;
-
 /*
  * There is a single intpend register per node, and we want to have
  * distinct levels for intercpu intrs for both cpus A and B on a node.
@@ -122,90 +124,20 @@
 	return(-1);
 }
 
-
-void disable_irq(unsigned int irq_nr)
-{
-	panic("disable_irq() called ...");
-}
-
-void enable_irq(unsigned int irq_nr)
-{
-	panic("enable_irq() called ...");
-}
-
-/* This is stupid for an Origin which can have thousands of IRQs ...  */
-static struct irqaction *irq_action[NR_IRQS];
-
-int get_irq_list(char *buf)
-{
-	int i, len = 0;
-	struct irqaction * action;
-
-	for (i = 0 ; i < NR_IRQS ; i++) {
-		action = irq_action[i];
-		if (!action) 
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.irqs[0][i],
-		               (action->flags & SA_INTERRUPT) ? '+' : ' ',
-		               action->name);
-		for (action=action->next; action; action = action->next) {
-			len += sprintf(buf+len, ",%s %s",
-			               (action->flags & SA_INTERRUPT)
-			                ? " +" : "",
-			                action->name);
-		}
-		len += sprintf(buf+len, "\n");
-	}
-	return len;
-}
-
-/*
- * do_IRQ handles all normal device IRQ's (the special SMP cross-CPU interrupts
- * have their own specific handlers).
- */
-static void do_IRQ(cpuid_t thiscpu, int irq, struct pt_regs * regs)
-{
-	struct irqaction *action;
-	int do_random;
-
-	irq_enter(thiscpu, irq);
-	kstat.irqs[thiscpu][irq]++;
-
-	action = *(irq + irq_action);
-	if (action) {
-		if (!(action->flags & SA_INTERRUPT))
-			__sti();
-		do_random = 0;
-        	do {
-			do_random |= action->flags;
-			action->handler(irq, action->dev_id, regs);
-			action = action->next;
-        	} while (action);
-		if (do_random & SA_SAMPLE_RANDOM)
-			add_interrupt_randomness(irq);
-		__cli();
-	}
-	irq_exit(thiscpu, irq);
-
-	if (softirq_pending(thiscpu))
-		do_softirq();
-}
-
 /*
  * Find first bit set
  */
 static int ms1bit(unsigned long x)
 {
-	int	b;
+	int b = 0, s;
 
-	if (x >> 32) 	b = 32, x >>= 32;
-	else		b  =  0;
-	if (x >> 16)	b += 16, x >>= 16;
-	if (x >>  8)	b +=  8, x >>=  8;
-	if (x >>  4)	b +=  4, x >>=  4;
-	if (x >>  2)	b +=  2, x >>=  2;
+	s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s;
+	s =  8; if (x >>  8 == 0) s = 0; b += s; x >>= s;
+	s =  4; if (x >>  4 == 0) s = 0; b += s; x >>= s;
+	s =  2; if (x >>  2 == 0) s = 0; b += s; x >>= s;
+	s =  1; if (x >>  1 == 0) s = 0; b += s;
 
-	return b + (int) (x >> 1);
+	return b;
 }
 
 /*
@@ -239,7 +171,7 @@
 				LOCAL_HUB_CLR_INTR(swlevel);
 				/* "map" swlevel to irq */
 				irq = LEVEL_TO_IRQ(thiscpu, swlevel);
-				do_IRQ(thiscpu, irq, regs);
+				do_IRQ(irq, regs);
 				/* clear bit in pend0 */
 				pend0 ^= 1ULL << swlevel;
 			} while(pend0);
@@ -252,7 +184,7 @@
 
 
 /* Startup one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int bridge_startup(unsigned int irq)
+static unsigned int startup_bridge_irq(unsigned int irq)
 {
 	bridgereg_t device;
 	bridge_t *bridge;
@@ -260,6 +192,9 @@
 	cpuid_t cpu;
 	nasid_t master = NASID_FROM_PCI_IRQ(irq);
 
+	if (irq < BASE_PCI_IRQ)
+		return 0;
+
         bridge = (bridge_t *) NODE_SWIN_BASE(master, WID_FROM_PCI_IRQ(irq));
 	pin = SLOT_FROM_PCI_IRQ(irq);
 	cpu = IRQ_TO_CPU(irq);
@@ -292,12 +227,15 @@
 }
 
 /* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int bridge_shutdown(unsigned int irq)
+static unsigned int shutdown_bridge_irq(unsigned int irq)
 {
 	bridge_t *bridge;
 	int pin, swlevel;
 	cpuid_t cpu;
 
+	if (irq < BASE_PCI_IRQ)
+		return 0;
+
 	bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_PCI_IRQ(irq), 
 	                                     WID_FROM_PCI_IRQ(irq));
 	DBG("bridge_shutdown: irq 0x%x\n", irq);
@@ -317,312 +255,64 @@
 	return 0;       /* Never anything pending.  */
 }
 
-void irq_debug(void)
+static inline void enable_bridge_irq(unsigned int irq)
 {
-	bridge_t *bridge = (bridge_t *) 0x9200000008000000;
-
-	printk("bridge->b_int_status = 0x%x\n", bridge->b_int_status);
-	printk("bridge->b_int_enable = 0x%x\n", bridge->b_int_enable);
-	printk("PI_INT_PEND0   = 0x%lx\n", LOCAL_HUB_L(PI_INT_PEND0));
-	printk("PI_INT_MASK0_A = 0x%lx\n", LOCAL_HUB_L(PI_INT_MASK0_A));
+	/* All the braindamage happens magically for us in ip27_do_irq */
 }
 
-int setup_irq(unsigned int irq, struct irqaction *new)
+static void disable_bridge_irq(unsigned int irq)
 {
-	int shared = 0;
-	struct irqaction *old, **p;
-	unsigned long flags;
-
-	DBG("setup_irq: 0x%x\n", irq);
-	if (irq >= NR_IRQS) {
-		printk("IRQ array overflow %d\n", irq);
-		while(1);
-	}
-	if (new->flags & SA_SAMPLE_RANDOM)
-		rand_initialize_irq(irq);
-
-	save_and_cli(flags);
-	p = irq_action + irq;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			restore_flags(flags);
-			return -EBUSY;
-		}
-
-		/* Add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	*p = new;
-
-	if ((!shared) && (irq >= BASE_PCI_IRQ)) {
-		bridge_startup(irq);
-	}
-	restore_flags(flags);
-
-	return 0;
+	/* All the braindamage happens magically for us in ip27_do_irq */
 }
 
-int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, const char * devname, void *dev_id)
+static void mask_and_ack_bridge_irq(unsigned int irq)
 {
-	int retval;
-	struct irqaction *action;
-
-	DBG("request_irq(): irq= 0x%x\n", irq);
-	if (!handler)
-		return -EINVAL;
-
-	action = (struct irqaction *)kmalloc(sizeof(*action), GFP_KERNEL);
-	if (!action)
-		return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->mask = 0;
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-	DBG("request_irq(): %s  devid= 0x%x\n", devname, dev_id);
-	retval = setup_irq(irq, action);
-	DBG("request_irq(): retval= %d\n", retval);
-	if (retval)
-		kfree(action);
-	return retval;
+	/* All the braindamage happens magically for us in ip27_do_irq */
 }
 
-void free_irq(unsigned int irq, void *dev_id)
+static void end_bridge_irq (unsigned int irq)
 {
-	struct irqaction * action, **p;
-	unsigned long flags;
-
-	if (irq >= NR_IRQS) {
-		printk("Trying to free IRQ%d\n", irq);
-		return;
-	}
-	for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
-		if (action->dev_id != dev_id)
-			continue;
-
-		/* Found it - now free it */
-		save_and_cli(flags);
-		*p = action->next;
-		if (irq >= BASE_PCI_IRQ)
-			bridge_shutdown(irq);
-		restore_flags(flags);
-		kfree(action);
-		return;
-	}
-	printk("Trying to free free IRQ%d\n",irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_bridge_irq(irq);
 }
 
-/* Useless ISA nonsense.  */
-unsigned long probe_irq_on (void)
-{
-	panic("probe_irq_on called!\n");
-	return 0;
-}
+static struct hw_interrupt_type bridge_irq_type = {
+	"bridge",
+	startup_bridge_irq,
+	shutdown_bridge_irq,
+	enable_bridge_irq,
+	disable_bridge_irq,
+	mask_and_ack_bridge_irq,
+	end_bridge_irq
+};
 
-int probe_irq_off (unsigned long irqs)
+void irq_debug(void)
 {
-	return 0;
-}
+	bridge_t *bridge = (bridge_t *) 0x9200000008000000;
 
-void __init init_IRQ(void)
-{
-	set_except_vector(0, ip27_irq);
+	printk("bridge->b_int_status = 0x%x\n", bridge->b_int_status);
+	printk("bridge->b_int_enable = 0x%x\n", bridge->b_int_enable);
+	printk("PI_INT_PEND0   = 0x%lx\n", LOCAL_HUB_L(PI_INT_PEND0));
+	printk("PI_INT_MASK0_A = 0x%lx\n", LOCAL_HUB_L(PI_INT_MASK0_A));
 }
 
-#ifdef CONFIG_SMP
-
-/*
- * This following are the global intr on off routines, copied almost
- * entirely from i386 code.
- */
-
-int global_irq_holder = NO_PROC_ID;
-spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
-
-extern void show_stack(unsigned long* esp);
-
-static void show(char * str)
+void __init init_IRQ(void)
 {
 	int i;
-	int cpu = smp_processor_id();
-
-	printk("\n%s, CPU %d:\n", str, cpu);
-	printk("irq:  %d [",irqs_running());
-	for(i=0;i < smp_num_cpus;i++)
-		printk(" %d",local_irq_count(i));
-	printk(" ]\nbh:   %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
-	for(i=0;i < smp_num_cpus;i++)
-		printk(" %d",local_bh_count(i));
-
-	printk(" ]\nStack dumps:");
-	for(i = 0; i < smp_num_cpus; i++) {
-		if (i == cpu)
-			continue;
-		printk("\nCPU %d:",i);
-		printk("Code not developed yet\n");
-		/* show_stack(0); */
-	}
-	printk("\nCPU %d:",cpu);
-	printk("Code not developed yet\n");
-	/* show_stack(NULL); */
-	printk("\n");
-}
-
-#define MAXCOUNT 		100000000
-#define SYNC_OTHER_CORES(x)	udelay(x+1)
-
-static inline void wait_on_irq(int cpu)
-{
-	int count = MAXCOUNT;
-
-	for (;;) {
-
-		/*
-		 * Wait until all interrupts are gone. Wait
-		 * for bottom half handlers unless we're
-		 * already executing in one..
-		 */
-		if (!irqs_running())
-			if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
-				break;
-
-		/* Duh, we have to loop. Release the lock to avoid deadlocks */
-		spin_unlock(&global_irq_lock);
-
-		for (;;) {
-			if (!--count) {
-				show("wait_on_irq");
-				count = ~0;
-			}
-			__sti();
-			SYNC_OTHER_CORES(cpu);
-			__cli();
-			if (irqs_running())
-				continue;
-			if (spin_is_locked(&global_irq_lock))
-				continue;
-			if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
-				continue;
-			if (spin_trylock(&global_irq_lock))
-				break;
-		}
-	}
-}
-
-void synchronize_irq(void)
-{
-	if (irqs_running()) {
-		/* Stupid approach */
-		cli();
-		sti();
-	}
-}
 
-static inline void get_irqlock(int cpu)
-{
-	if (!spin_trylock(&global_irq_lock)) {
-		/* do we already hold the lock? */
-		if ((unsigned char) cpu == global_irq_holder)
-			return;
-		/* Uhhuh.. Somebody else got it. Wait.. */
-		spin_lock(&global_irq_lock);
-	}
-	/*
-	 * We also to make sure that nobody else is running
-	 * in an interrupt context.
-	 */
-	wait_on_irq(cpu);
+	set_except_vector(0, ip27_irq);
 
 	/*
-	 * Ok, finally..
+	 * Right now the bridge irq is our kitchen sink interrupt type
 	 */
-	global_irq_holder = cpu;
-}
-
-void __global_cli(void)
-{
-	unsigned int flags;
-
-	__save_flags(flags);
-	if (flags & ST0_IE) {
-		int cpu = smp_processor_id();
-		__cli();
-		if (!local_irq_count(cpu))
-			get_irqlock(cpu);
-	}
-}
-
-void __global_sti(void)
-{
-	int cpu = smp_processor_id();
-
-	if (!local_irq_count(cpu))
-		release_irqlock(cpu);
-	__sti();
-}
-
-/*
- * SMP flags value to restore to:
- * 0 - global cli
- * 1 - global sti
- * 2 - local cli
- * 3 - local sti
- */
-unsigned long __global_save_flags(void)
-{
-	int retval;
-	int local_enabled;
-	unsigned long flags;
-	int cpu = smp_processor_id();
-
-	__save_flags(flags);
-	local_enabled = (flags & ST0_IE);
-	/* default to local */
-	retval = 2 + local_enabled;
-
-	/* check for global flags if we're not in an interrupt */
-	if (!local_irq_count(cpu)) {
-		if (local_enabled)
-			retval = 1;
-		if (global_irq_holder == cpu)
-			retval = 0;
+	for (i = 0; i <= NR_IRQS; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &bridge_irq_type;
 	}
-	return retval;
 }
 
-void __global_restore_flags(unsigned long flags)
-{
-	switch (flags) {
-		case 0:
-			__global_cli();
-			break;
-		case 1:
-			__global_sti();
-			break;
-		case 2:
-			__cli();
-			break;
-		case 3:
-			__sti();
-			break;
-		default:
-			printk("global_restore_flags: %08lx\n", flags);
-	}
-}
-
-#endif /* CONFIG_SMP */
-
 /*
  * Get values that vary depending on which CPU and bit we're operating on.
  */
@@ -697,6 +387,39 @@
 	/* Nothing, the return from intr will work for us */
 }
 
+#ifdef CONFIG_SMP
+
+void core_send_ipi(int destid, unsigned int action)
+{
+	int irq;
+
+#if (CPUS_PER_NODE == 2)
+	switch (action) {
+		case SMP_RESCHEDULE_YOURSELF:
+			irq = CPU_RESCHED_A_IRQ;
+			break;
+		case SMP_CALL_FUNCTION:
+			irq = CPU_CALL_A_IRQ;
+			break;
+		default:
+			panic("sendintr");
+	}
+	irq += cputoslice(destid);
+
+	/*
+	 * Convert the compact hub number to the NASID to get the correct
+	 * part of the address space.  Then set the interrupt bit associated
+	 * with the CPU we want to send the interrupt to.
+	 */
+	REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)),
+			FAST_IRQ_TO_LEVEL(irq));
+#else
+	<< Bomb!  Must redefine this for more than 2 CPUS. >>
+#endif
+}
+
+#endif
+
 extern void smp_call_function_interrupt(void);
 
 void install_cpuintr(int cpu)
@@ -715,16 +438,16 @@
 
 		if (request_irq(CPU_RESCHED_A_IRQ, handle_resched_intr, 
 							0, "resched", 0))
-			panic("intercpu intr unconnectible\n");
+			panic("intercpu intr unconnectible");
 		if (request_irq(CPU_RESCHED_B_IRQ, handle_resched_intr, 
 							0, "resched", 0))
-			panic("intercpu intr unconnectible\n");
+			panic("intercpu intr unconnectible");
 		if (request_irq(CPU_CALL_A_IRQ, smp_call_function_interrupt,
 							0, "callfunc", 0))
-			panic("intercpu intr unconnectible\n");
+			panic("intercpu intr unconnectible");
 		if (request_irq(CPU_CALL_B_IRQ, smp_call_function_interrupt,
 							0, "callfunc", 0))
-			panic("intercpu intr unconnectible\n");
+			panic("intercpu intr unconnectible");
 
 		for (j = 0; j < PERNODE_LEVELS; j++)
 			LEVEL_TO_IRQ(0, j) = -1;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-pci-dma.c linux/arch/mips64/sgi-ip27/ip27-pci-dma.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-pci-dma.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-pci-dma.c	2002-07-20 01:08:27.000000000 +0000
@@ -14,26 +14,12 @@
 #include <linux/pci.h>
 #include <asm/io.h>
 
-/* Pure 2^n version of get_order */
-extern __inline__ int __get_order(unsigned long size)
-{
-	int order;
-
-	size = (size-1) >> (PAGE_SHIFT-1);
-	order = -1;
-	do {
-		size >>= 1;
-		order++;
-	} while (size);
-	return order;
-}
-
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 			   dma_addr_t *dma_handle)
 {
 	void *ret;
 	int gfp = GFP_ATOMIC;
-	int order = __get_order(size);
+	int order = get_order(size);
 
 	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
 		gfp |= GFP_DMA;
@@ -50,7 +36,7 @@
 void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
 {
-	free_pages((unsigned long)vaddr, __get_order(size));
+	free_pages((unsigned long)vaddr, get_order(size));
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-pci.c linux/arch/mips64/sgi-ip27/ip27-pci.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-pci.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-pci.c	2002-07-20 01:08:39.000000000 +0000
@@ -192,7 +192,7 @@
 	if ((dev->bus->number >= MAX_PCI_BUSSES)
 	    || (pin != 1)
 	    || (slot >= MAX_DEVICES_PER_PCIBUS))
-		panic("Increase supported PCI busses %d,%d,%d\n",
+		panic("Increase supported PCI busses %d,%d,%d",
 		      dev->bus->number, slot, pin);
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-reset.c linux/arch/mips64/sgi-ip27/ip27-reset.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-reset.c	2000-07-10 05:18:16.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-reset.c	2002-07-20 01:08:21.000000000 +0000
@@ -14,8 +14,10 @@
 #include <linux/timer.h>
 #include <linux/smp.h>
 #include <linux/mmzone.h>
+
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/reboot.h>
 #include <asm/system.h>
 #include <asm/sgialib.h>
 #include <asm/sn/addrs.h>
@@ -30,7 +32,7 @@
 #define noreturn while(1);				/* Silence gcc.  */
 
 /* XXX How to pass the reboot command to the firmware??? */
-void machine_restart(char *command)
+static void ip27_machine_restart(char *command)
 {
 #if 0
 	int i;
@@ -50,7 +52,7 @@
 	noreturn;
 }
 
-void machine_halt(void)
+static void ip27_machine_halt(void)
 {
 	int i;
 
@@ -64,7 +66,7 @@
 	noreturn;
 }
 
-void machine_power_off(void)
+static void ip27_machine_power_off(void)
 {
 	/* To do ...  */
 	noreturn;
@@ -72,5 +74,7 @@
 
 void ip27_reboot_setup(void)
 {
-	/* Nothing to do on IP27.  */
+	_machine_restart = ip27_machine_restart;
+	_machine_halt = ip27_machine_halt;
+	_machine_power_off = ip27_machine_power_off;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-rtc.c linux/arch/mips64/sgi-ip27/ip27-rtc.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-rtc.c	2000-11-29 05:42:04.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-rtc.c	2002-07-20 01:08:35.000000000 +0000
@@ -61,6 +61,7 @@
 #define RTC_TIMER_ON		0x02	/* missed irq timer active	*/
 
 static unsigned char rtc_status;	/* bitmapped status byte.	*/
+static spinlock_t rtc_status_lock = SPIN_LOCK_UNLOCKED;
 static unsigned long rtc_freq;	/* Current periodic IRQ rate	*/
 static struct m48t35_rtc *rtc;
 
@@ -166,10 +167,16 @@
 
 static int rtc_open(struct inode *inode, struct file *file)
 {
-	if(rtc_status & RTC_IS_OPEN)
+	spin_lock(rtc_status_lock);
+
+	if (rtc_status & RTC_IS_OPEN) {
+		spin_unlock(rtc_status_lock);
 		return -EBUSY;
+	}
 
 	rtc_status |= RTC_IS_OPEN;
+	spin_unlock(rtc_status_lock);
+
 	return 0;
 }
 
@@ -180,9 +187,10 @@
 	 * in use, and clear the data.
 	 */
 
-	lock_kernel();
+	spin_lock(rtc_status_lock);
 	rtc_status &= ~RTC_IS_OPEN;
-	unlock_kernel();
+	spin_unlock(rtc_status_lock);
+
 	return 0;
 }
 
@@ -214,7 +222,8 @@
 	    KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
 
 	printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
-	misc_register(&rtc_dev);
+	if (misc_register(&rtc_dev))
+		return -ENODEV;
 	create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL);
 
 	save_flags(flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-setup.c linux/arch/mips64/sgi-ip27/ip27-setup.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-setup.c	2002-07-20 01:08:33.000000000 +0000
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
+
 #include <asm/io.h>
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
@@ -21,6 +22,7 @@
 #include <asm/sn/sn0/hubio.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/ioc3.h>
+#include <asm/time.h>
 #include <asm/mipsregs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/sn_private.h>
@@ -40,8 +42,6 @@
 #define DBG(x...)
 #endif
 
-unsigned long mips_io_port_base = IO_BASE;
-
 /*
  * get_nasid() returns the physical node id number of the caller.
  */
@@ -275,6 +275,7 @@
 }
 
 extern void ip27_setup_console(void);
+extern void ip27_time_init(void);
 
 void __init ip27_setup(void)
 {
@@ -307,4 +308,7 @@
 	ioc3_sio_init();
 	ioc3_eth_init();
 	per_cpu_init();
+
+	mips_io_port_base = IO_BASE;
+	board_time_init = ip27_time_init;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip27/ip27-timer.c linux/arch/mips64/sgi-ip27/ip27-timer.c
--- linux.orig/arch/mips64/sgi-ip27/ip27-timer.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip27/ip27-timer.c	2002-07-20 01:08:33.000000000 +0000
@@ -12,6 +12,7 @@
 #include <linux/timex.h>
 #include <linux/mm.h>		
 
+#include <asm/time.h>
 #include <asm/pgtable.h>
 #include <asm/sgialib.h>
 #include <asm/sn/ioc3.h>
@@ -91,8 +92,9 @@
 {
 	int cpu = smp_processor_id();
 	int cpuA = ((cputoslice(cpu)) == 0);
-	int irq = 7;				/* XXX Assign number */
+	int irq = 9;				/* XXX Assign number */
 
+	irq_enter(cpu, irq);
 	write_lock(&xtime_lock);
 
 again:
@@ -109,19 +111,7 @@
 		do_timer(regs);
 
 #ifdef CONFIG_SMP
-	{
-		int user = user_mode(regs);
-
-		/*
-		 * update_process_times() expects us to have done irq_enter().
-		 * Besides, if we don't timer interrupts ignore the global
-		 * interrupt lock, which is the WrongThing (tm) to do.
-		 * Picked from i386 code.
-		 */
-		irq_enter(cpu, 0);
-		update_process_times(user);
-		irq_exit(cpu, 0);
-	}
+	update_process_times(user_mode(regs));
 #endif /* CONFIG_SMP */
 	
 	/*
@@ -145,62 +135,19 @@
         }
 
 	write_unlock(&xtime_lock);
+	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
 		do_softirq();
 }
 
-unsigned long inline do_gettimeoffset(void)
+unsigned long ip27_do_gettimeoffset(void)
 {
 	unsigned long ct_cur1;
 	ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
 	return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
 }
 
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-	unsigned long usec, sec;
-
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = do_gettimeoffset();
-	{
-		unsigned long lost = jiffies - wall_jiffies;
-		if (lost)
-			usec += lost * (1000000 / HZ);
-	}
-	sec = xtime.tv_sec;
-	usec += xtime.tv_usec;
-	read_unlock_irqrestore(&xtime_lock, flags);
-
-	while (usec >= 1000000) {
-		usec -= 1000000;
-		sec++;
-	}
-
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
-}
-
-void do_settimeofday(struct timeval *tv)
-{
-	write_lock_irq(&xtime_lock);
-	tv->tv_usec -= do_gettimeoffset();
-	tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
-
-	while (tv->tv_usec < 0) {
-		tv->tv_usec += 1000000;
-		tv->tv_sec--;
-	}
-
-	xtime = *tv;
-	time_adjust = 0;		/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
-}
-
 /* Includes for ioc3_init().  */
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
@@ -239,10 +186,12 @@
         return mktime(year, month, date, hour, min, sec);
 }
 
-void __init time_init(void)
+void __init ip27_time_init(void)
 {
 	xtime.tv_sec = get_m48t35_time();
 	xtime.tv_usec = 0;
+
+	do_gettimeoffset = ip27_do_gettimeoffset;
 }
 
 void __init cpu_time_init(void)
@@ -263,7 +212,7 @@
 
 	printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
 
-	set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK);
+	set_cp0_status(SRB_TIMOCLK);
 }
 
 void __init hub_rtc_init(cnodeid_t cnode)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/Makefile linux/arch/mips64/sgi-ip32/Makefile
--- linux.orig/arch/mips64/sgi-ip32/Makefile	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/Makefile	2002-07-20 01:08:22.000000000 +0000
@@ -8,20 +8,15 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := ip32-kern.a
 
 all: ip32-kern.a ip32-irq-glue.o
 
-obj-y	+= ip32-irq.o ip32-rtc.o ip32-setup.o ip32-irq-glue.o \
-	 ip32-berr.o ip32-timer.o crime.o
+obj-y	+= ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \
+	   ip32-timer.o crime.o ip32-reset.o
 
-ifdef CONFIG_PCI
-obj-y   += ip32-pci.o ip32-pci-dma.o
-endif
+obj-$(CONFIG_PCI)   += ip32-pci.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/crime.c linux/arch/mips64/sgi-ip32/crime.c
--- linux.orig/arch/mips64/sgi-ip32/crime.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/crime.c	2002-07-20 01:08:27.000000000 +0000
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <asm/ip32/crime.h>
 #include <asm/ptrace.h>
-#include <asm/promlib.h>
 
 void __init crime_init (void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/ip32-berr.c linux/arch/mips64/sgi-ip32/ip32-berr.c
--- linux.orig/arch/mips64/sgi-ip32/ip32-berr.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/ip32-berr.c	2002-07-20 01:08:38.000000000 +0000
@@ -5,78 +5,24 @@
  *
  * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
  * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <asm/traps.h>
 #include <asm/uaccess.h>
-#include <asm/paccess.h>
 #include <asm/addrspace.h>
 #include <asm/ptrace.h>
 
-/* XXX I have no idea what this does --kmw */
-
-extern asmlinkage void handle_ibe(void);
-extern asmlinkage void handle_dbe(void);
-
-extern const struct exception_table_entry __start___dbe_table[];
-extern const struct exception_table_entry __stop___dbe_table[];
-
-static inline unsigned long
-search_one_table(const struct exception_table_entry *first,
-                 const struct exception_table_entry *last,
-                 unsigned long value)
+int
+be_ip32_handler(struct pt_regs *regs, int is_fixup)
 {
-	while (first <= last) {
-		const struct exception_table_entry *mid;
-		long diff;
+	int data = regs->cp0_cause & 4;
 
-		mid = (last - first) / 2 + first;
-		diff = mid->insn - value;
-		if (diff == 0)
-			return mid->nextinsn;
-		else if (diff < 0)
-			first = mid+1;
-		else
-			last = mid-1;
-	}
-	return 0;
-}
-
-static inline unsigned long
-search_dbe_table(unsigned long addr)
-{
-	unsigned long ret;
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
 
-	/* There is only the kernel to search.  */
-	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
-	if (ret) return ret;
-
-	return 0;
-}
-
-void do_ibe(struct pt_regs *regs)
-{
-	printk("Got ibe at 0x%lx\n", regs->cp0_epc);
-	show_regs(regs);
-	dump_tlb_addr(regs->cp0_epc);
-	force_sig(SIGBUS, current);
-	while(1);
-}
-
-void do_dbe(struct pt_regs *regs)
-{
-	unsigned long fixup;
-
-	fixup = search_dbe_table(regs->cp0_epc);
-	if (fixup) {
-		long new_epc;
-
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
-	}
-
-	printk("Got dbe at 0x%lx\n", regs->cp0_epc);
+	printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
 	show_regs(regs);
 	dump_tlb_all();
 	while(1);
@@ -86,12 +32,5 @@
 void __init
 bus_error_init(void)
 {
-	int dummy;
-
-	set_except_vector(6, handle_ibe);
-	set_except_vector(7, handle_dbe);
-
-	/* At this time nothing uses the DBE protection mechanism on the
-	   O2, so this here is needed to make the kernel link.  */
-	get_dbe(dummy, (int *)KSEG0);
+	be_board_handler = be_ip27_handler;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/ip32-irq.c linux/arch/mips64/sgi-ip32/ip32-irq.c
--- linux.orig/arch/mips64/sgi-ip32/ip32-irq.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/ip32-irq.c	2002-07-20 01:08:37.000000000 +0000
@@ -12,8 +12,12 @@
 #include <linux/kernel_stat.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
 
 #include <asm/bitops.h>
 #include <asm/mipsregs.h>
@@ -110,30 +114,31 @@
 			       0, "CRIME CPU error", NULL,
 			       NULL };
 
-unsigned long spurious_count = 0;
 extern void ip32_handle_int (void);
-extern void do_IRQ (unsigned int irq, struct pt_regs *regs);
+asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
 
-/* For interrupts wired from a single device to the CPU.  Only the clock
+/*
+ * For interrupts wired from a single device to the CPU.  Only the clock
  * uses this it seems, which is IRQ 0 and IP7.
  */
 
-static void enable_cpu_irq (unsigned int irq)
+static void enable_cpu_irq(unsigned int irq)
 {
-	set_cp0_status (STATUSF_IP7);
+	set_cp0_status(STATUSF_IP7);
 }
 
-static unsigned int startup_cpu_irq (unsigned int irq) {
-	enable_cpu_irq (irq);
+static unsigned int startup_cpu_irq(unsigned int irq)
+{
+	enable_cpu_irq(irq);
 	return 0;
 }
 
-static void disable_cpu_irq (unsigned int irq)
+static void disable_cpu_irq(unsigned int irq)
 {
-	clear_cp0_status (STATUSF_IP7);
+	clear_cp0_status(STATUSF_IP7);
 }
 
-static void end_cpu_irq (unsigned int irq)
+static void end_cpu_irq(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 		enable_cpu_irq (irq);
@@ -158,34 +163,34 @@
  * We get to split the register in half and do faster lookups.
  */
 
-static void enable_crime_irq (unsigned int irq)
+static void enable_crime_irq(unsigned int irq)
 {
 	u64 crime_mask;
 	unsigned long flags;
 
-	save_and_cli (flags);
-	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	save_and_cli(flags);
+	crime_mask = crime_read_64(CRIME_INT_MASK);
 	crime_mask |= 1 << (irq - 1);
-	crime_write_64 (CRIME_INT_MASK, crime_mask);
-	restore_flags (flags);
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
 }
 
-static unsigned int startup_crime_irq (unsigned int irq)
+static unsigned int startup_crime_irq(unsigned int irq)
 {
-	enable_crime_irq (irq);
+	enable_crime_irq(irq);
 	return 0; /* This is probably not right; we could have pending irqs */
 }
 
-static void disable_crime_irq (unsigned int irq)
+static void disable_crime_irq(unsigned int irq)
 {
 	u64 crime_mask;
 	unsigned long flags;
 
-	save_and_cli (flags);
-	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	save_and_cli(flags);
+	crime_mask = crime_read_64(CRIME_INT_MASK);
 	crime_mask &= ~(1 << (irq - 1));
-	crime_write_64 (CRIME_INT_MASK, crime_mask);
-	restore_flags (flags);
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
 }
 
 static void mask_and_ack_crime_irq (unsigned int irq)
@@ -197,16 +202,16 @@
 	if ((irq <= CRIME_GBE0_IRQ && irq >= CRIME_GBE3_IRQ)
 	    || (irq <= CRIME_RE_EMPTY_E_IRQ && irq >= CRIME_RE_IDLE_E_IRQ)
 	    || (irq <= CRIME_SOFT0_IRQ && irq >= CRIME_SOFT2_IRQ)) {
-		save_and_cli (flags);
-		crime_mask = crime_read_64 (CRIME_HARD_INT);
+		save_and_cli(flags);
+		crime_mask = crime_read_64(CRIME_HARD_INT);
 		crime_mask &= ~(1 << (irq - 1));
-		crime_write_64 (CRIME_HARD_INT, crime_mask);
-		restore_flags (flags);
+		crime_write_64(CRIME_HARD_INT, crime_mask);
+		restore_flags(flags);
 	}
-	disable_crime_irq (irq);
+	disable_crime_irq(irq);
 }
-	
-static void end_crime_irq (unsigned int irq)
+
+static void end_crime_irq(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 		enable_crime_irq (irq);
@@ -225,48 +230,52 @@
 	NULL
 };
 
-/* This is for MACE PCI interrupts.  We can decrease bus traffic by masking
+/*
+ * This is for MACE PCI interrupts.  We can decrease bus traffic by masking
  * as close to the source as possible.  This also means we can take the
  * next chunk of the CRIME register in one piece.
  */
 
-static void enable_macepci_irq (unsigned int irq)
+static void enable_macepci_irq(unsigned int irq)
 {
 	u32 mace_mask;
 	u64 crime_mask;
 	unsigned long flags;
 
-	save_and_cli (flags);
-	mace_mask = mace_read_32 (MACEPCI_CONTROL);
-	mace_mask |= MACEPCI_CONTROL_INT (irq - 9);
-	mace_write_32 (MACEPCI_CONTROL, mace_mask);
-	/* In case the CRIME interrupt isn't enabled, we must enable it;
+	save_and_cli(flags);
+	mace_mask = mace_read_32(MACEPCI_CONTROL);
+	mace_mask |= MACEPCI_CONTROL_INT(irq - 9);
+	mace_write_32(MACEPCI_CONTROL, mace_mask);
+	/*
+	 * In case the CRIME interrupt isn't enabled, we must enable it;
 	 * however, we never disable interrupts at that level.
 	 */
-	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask = crime_read_64(CRIME_INT_MASK);
 	crime_mask |= 1 << (irq - 1);
-	crime_write_64 (CRIME_INT_MASK, crime_mask);
-	restore_flags (flags);
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
 }
 
-static unsigned int startup_macepci_irq (unsigned int irq) {
+static unsigned int startup_macepci_irq(unsigned int irq)
+{
 	enable_macepci_irq (irq);
+
 	return 0; /* XXX */
 }
 
-static void disable_macepci_irq (unsigned int irq)
+static void disable_macepci_irq(unsigned int irq)
 {
 	u32 mace_mask;
 	unsigned long flags;
 
-	save_and_cli (flags);
-	mace_mask = mace_read_32 (MACEPCI_CONTROL);
-	mace_mask &= ~MACEPCI_CONTROL_INT (irq - 9);
-	mace_write_32 (MACEPCI_CONTROL, mace_mask);
-	restore_flags (flags);
+	save_and_cli(flags);
+	mace_mask = mace_read_32(MACEPCI_CONTROL);
+	mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9);
+	mace_write_32(MACEPCI_CONTROL, mace_mask);
+	restore_flags(flags);
 }
 
-static void end_macepci_irq (unsigned int irq)
+static void end_macepci_irq(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 		enable_macepci_irq (irq);
@@ -311,34 +320,35 @@
 		break;
 	}
 	DBG ("crime_int %016lx enabled\n", crime_int);
-	save_and_cli (flags);
-	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	save_and_cli(flags);
+	crime_mask = crime_read_64(CRIME_INT_MASK);
 	crime_mask |= crime_int;
-	crime_write_64 (CRIME_INT_MASK, crime_mask);
-	mace_mask = mace_read_32 (MACEISA_INT_MASK);
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	mace_mask = mace_read_32(MACEISA_INT_MASK);
 	mace_mask |= 1 << (irq - 33);
-	mace_write_32 (MACEISA_INT_MASK, mace_mask);
-	restore_flags (flags);
+	mace_write_32(MACEISA_INT_MASK, mace_mask);
+	restore_flags(flags);
 }
 
-static unsigned int startup_maceisa_irq (unsigned int irq) {
-	enable_maceisa_irq (irq);
+static unsigned int startup_maceisa_irq (unsigned int irq)
+{
+	enable_maceisa_irq(irq);
 	return 0;
 }
 
-static void disable_maceisa_irq (unsigned int irq)
+static void disable_maceisa_irq(unsigned int irq)
 {
 	u32 mace_mask;
 	unsigned long flags;
 
 	save_and_cli (flags);
-	mace_mask = mace_read_32 (MACEISA_INT_MASK);
+	mace_mask = mace_read_32(MACEISA_INT_MASK);
 	mace_mask &= ~(1 << (irq - 33));
-	mace_write_32 (MACEISA_INT_MASK, mace_mask);
-	restore_flags (flags);
+	mace_write_32(MACEISA_INT_MASK, mace_mask);
+	restore_flags(flags);
 }
 
-static void mask_and_ack_maceisa_irq (unsigned int irq)
+static void mask_and_ack_maceisa_irq(unsigned int irq)
 {
 	u32 mace_mask;
 	unsigned long flags;
@@ -347,17 +357,17 @@
 	case MACEISA_PARALLEL_IRQ:
 	case MACEISA_SERIAL1_TDMAPR_IRQ:
 	case MACEISA_SERIAL2_TDMAPR_IRQ:
-		save_and_cli (flags);
-		mace_mask = mace_read_32 (MACEISA_INT_STAT);
+		save_and_cli(flags);
+		mace_mask = mace_read_32(MACEISA_INT_STAT);
 		mace_mask &= ~(1 << (irq - 33));
-		mace_write_32 (MACEISA_INT_STAT, mace_mask);
-		restore_flags (flags);
+		mace_write_32(MACEISA_INT_STAT, mace_mask);
+		restore_flags(flags);
 		break;
 	}
-	disable_maceisa_irq (irq);
+	disable_maceisa_irq(irq);
 }
 
-static void end_maceisa_irq (unsigned irq)
+static void end_maceisa_irq(unsigned irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 		enable_maceisa_irq (irq);
@@ -380,7 +390,7 @@
  * bits 0-3 and 7 in the CRIME register.
  */
 
-static void enable_mace_irq (unsigned int irq)
+static void enable_mace_irq(unsigned int irq)
 {
 	u64 crime_mask;
 	unsigned long flags;
@@ -392,13 +402,13 @@
 	restore_flags (flags);
 }
 
-static unsigned int startup_mace_irq (unsigned int irq)
+static unsigned int startup_mace_irq(unsigned int irq)
 {
-	enable_mace_irq (irq);
+	enable_mace_irq(irq);
 	return 0;
 }
 
-static void disable_mace_irq (unsigned int irq)
+static void disable_mace_irq(unsigned int irq)
 {
 	u64 crime_mask;
 	unsigned long flags;
@@ -407,10 +417,10 @@
 	crime_mask = crime_read_64 (CRIME_INT_MASK);
 	crime_mask &= ~(1 << (irq - 1));
 	crime_write_64 (CRIME_INT_MASK, crime_mask);
-	restore_flags (flags);
+	restore_flags(flags);
 }
 
-static void end_mace_irq (unsigned int irq)
+static void end_mace_irq(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 		enable_mace_irq (irq);
@@ -452,56 +462,16 @@
 	mace = mace_read_32 (MACEPCI_CONTROL);
 	printk ("MACE PCI control register: %08x\n", mace);
 
-	printk ("Register dump:\n");
-	show_regs (regs);
+	printk("Register dump:\n");
+	show_regs(regs);
 
-	printk ("Please mail this report to linux-mips@oss.sgi.com\n");
-	printk ("Spinning...");
-	while (1) ;
-}
-
-void __init ip32_irq_init(void)
-{
-	unsigned int irq;
-	extern void init_generic_irq (void);
-	
-	/* Install our interrupt handler, then clear and disable all
-	 * CRIME and MACE interrupts.
-	 */
-	crime_write_64 (CRIME_INT_MASK, 0);
-	crime_write_64 (CRIME_HARD_INT, 0);
-	crime_write_64 (CRIME_SOFT_INT, 0);
-	mace_write_32 (MACEISA_INT_STAT, 0);
-	mace_write_32 (MACEISA_INT_MASK, 0);
-	set_except_vector(0, ip32_handle_int);
-
-	init_generic_irq ();
-
-	for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
-		hw_irq_controller *controller;
-
-		if (irq == CLOCK_IRQ)
-			controller = &ip32_cpu_interrupt;
-		else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
-			controller = &ip32_mace_interrupt;
-		else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
-			controller = &ip32_macepci_interrupt;
-		else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
-			controller = &ip32_crime_interrupt;
-		else
-			controller = &ip32_maceisa_interrupt;
-
-		irq_desc[irq].status = IRQ_DISABLED;
-		irq_desc[irq].action = 0;
-		irq_desc[irq].depth = 0;
-		irq_desc[irq].handler = controller;
-	}
-	setup_irq (CRIME_MEMERR_IRQ, &memerr_irq);
-	setup_irq (CRIME_CPUERR_IRQ, &cpuerr_irq);
+	printk("Please mail this report to linux-mips@oss.sgi.com\n");
+	printk("Spinning...");
+	while(1) ;
 }
 
 /* CRIME 1.1 appears to deliver all interrupts to this one pin. */
-void ip32_irq0 (struct pt_regs *regs)
+void ip32_irq0(struct pt_regs *regs)
 {
 	u64 crime_int = crime_read_64 (CRIME_INT_STAT);
 	int irq = 0;
@@ -525,32 +495,77 @@
 		irq = ffs (crime_int) + 16;
 	}
 	if (irq == 0)
-		ip32_unknown_interrupt (regs);
-	DBG ("*irq %u*\n", irq);
-	do_IRQ (irq, regs);
+		ip32_unknown_interrupt(regs);
+	DBG("*irq %u*\n", irq);
+	do_IRQ(irq, regs);
 }
 
-void ip32_irq1 (struct pt_regs *regs)
+void ip32_irq1(struct pt_regs *regs)
 {
 	ip32_unknown_interrupt (regs);
 }
 
-void ip32_irq2 (struct pt_regs *regs)
+void ip32_irq2(struct pt_regs *regs)
 {
 	ip32_unknown_interrupt (regs);
 }
 
-void ip32_irq3 (struct pt_regs *regs)
+void ip32_irq3(struct pt_regs *regs)
 {
 	ip32_unknown_interrupt (regs);
 }
 
-void ip32_irq4 (struct pt_regs *regs)
+void ip32_irq4(struct pt_regs *regs)
 {
 	ip32_unknown_interrupt (regs);
 }
 
-void ip32_irq5 (struct pt_regs *regs)
+void ip32_irq5(struct pt_regs *regs)
 {
 	do_IRQ (CLOCK_IRQ, regs);
 }
+
+void __init init_IRQ(void)
+{
+	unsigned int irq;
+	int i;
+
+	/* Install our interrupt handler, then clear and disable all
+	 * CRIME and MACE interrupts.
+	 */
+	crime_write_64(CRIME_INT_MASK, 0);
+	crime_write_64(CRIME_HARD_INT, 0);
+	crime_write_64(CRIME_SOFT_INT, 0);
+	mace_write_32(MACEISA_INT_STAT, 0);
+	mace_write_32(MACEISA_INT_MASK, 0);
+	set_except_vector(0, ip32_handle_int);
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status  = IRQ_DISABLED;
+		irq_desc[i].action  = NULL;
+		irq_desc[i].depth   = 1;
+		irq_desc[i].handler = &no_irq_type;
+	}
+
+	for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
+		hw_irq_controller *controller;
+
+		if (irq == CLOCK_IRQ)
+			controller = &ip32_cpu_interrupt;
+		else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
+			controller = &ip32_mace_interrupt;
+		else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
+			controller = &ip32_macepci_interrupt;
+		else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
+			controller = &ip32_crime_interrupt;
+		else
+			controller = &ip32_maceisa_interrupt;
+
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = 0;
+		irq_desc[irq].depth = 0;
+		irq_desc[irq].handler = controller;
+	}
+	setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
+	setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/ip32-pci-dma.c linux/arch/mips64/sgi-ip32/ip32-pci-dma.c
--- linux.orig/arch/mips64/sgi-ip32/ip32-pci-dma.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/ip32-pci-dma.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,41 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000  Ralf Baechle <ralf@gnu.org>
- * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
- */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-
-#include <asm/io.h>
-#include <asm/addrspace.h>
-#include <asm/ip32/mace.h>
-
-void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
-			   dma_addr_t * dma_handle)
-{
-	void *ret;
-	int gfp = GFP_ATOMIC;
-
-	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
-		gfp |= GFP_DMA;
-	ret = (void *) __get_free_pages(gfp, get_order(size));
-
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		dma_cache_wback_inv((unsigned long) ret, size);
-		*dma_handle = virt_to_bus(ret);
-	}
-	return ret;
-}
-
-void pci_free_consistent(struct pci_dev *hwdev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long) vaddr, get_order(size));
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/ip32-pci.c linux/arch/mips64/sgi-ip32/ip32-pci.c
--- linux.orig/arch/mips64/sgi-ip32/ip32-pci.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/ip32-pci.c	2002-07-20 01:08:40.000000000 +0000
@@ -5,7 +5,6 @@
  *
  * Copyright (C) 2000, 2001 Keith M Wesolowski
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -152,7 +151,7 @@
 
 	if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
 			 "MACE PCI error", NULL))
-		panic ("PCI bridge can't get interrupt; can't happen.\n");
+		panic("PCI bridge can't get interrupt; can't happen.");
 
 	pci_scan_bus (0, &macepci_ops, NULL);
 
@@ -221,11 +220,30 @@
 		pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20);
 		pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30);
 		pci_read_config_word (dev, PCI_COMMAND, &cmd);
-		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_PARITY);
+		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
 		pci_write_config_word (dev, PCI_COMMAND, cmd);
 		pci_set_master (dev);
 	}
-
+        /*
+         * Fixup O2 PCI slot. Bad hack.
+         */
+/*        devtag = pci_make_tag(0, 0, 3, 0);
+
+        slot = macepci_conf_read(0, devtag, PCI_COMMAND_STATUS_REG);
+        slot |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE;
+        macepci_conf_write(0, devtag, PCI_COMMAND_STATUS_REG, slot);
+
+        slot = macepci_conf_read(0, devtag, PCI_MAPREG_START);
+        if (slot == 0xffffffe1)
+                macepci_conf_write(0, devtag, PCI_MAPREG_START, 0x00001000);
+
+        slot = macepci_conf_read(0, devtag, PCI_MAPREG_START + (2 << 2));
+        if ((slot & 0xffff0000) == 0) {
+                slot += 0x00010000;
+                macepci_conf_write(0, devtag, PCI_MAPREG_START + (2 << 2),
+                    0x00000000);
+        }
+ */
 #ifdef DEBUG_MACE_PCI
 	printk ("Triggering PCI bridge interrupt...\n");
 	mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST);
@@ -436,3 +454,7 @@
 			       & ~MACEPCI_ERROR_INTERRUPT_TEST);
 	}
 }
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/ip32-reset.c linux/arch/mips64/sgi-ip32/ip32-reset.c
--- linux.orig/arch/mips64/sgi-ip32/ip32-reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/ip32-reset.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,34 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Keith M Wesolowski
+ * Copyright (C) 2001 Paul Mundt
+ */
+#include <linux/init.h>
+
+#include <asm/reboot.h>
+#include <asm/sgialib.h>
+
+static void ip32_machine_restart(char *cmd)
+{
+	ArcReboot();
+}
+
+static inline void ip32_machine_halt(void)
+{
+	ArcEnterInteractiveMode();
+}
+
+static void ip32_machine_power_off(void)
+{
+	ip32_machine_halt();
+}
+
+void __init ip32_reboot_setup(void)
+{
+	_machine_restart = ip32_machine_restart;
+	_machine_halt = ip32_machine_halt;
+	_machine_power_off = ip32_machine_power_off;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/ip32-setup.c linux/arch/mips64/sgi-ip32/ip32-setup.c
--- linux.orig/arch/mips64/sgi-ip32/ip32-setup.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/ip32-setup.c	2002-07-20 01:08:31.000000000 +0000
@@ -7,15 +7,16 @@
  *
  * Copyright (C) 2000 Harald Koerfgen
  */
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/param.h>
 #include <linux/init.h>
-#include <linux/irq.h>
+
+#include <asm/time.h>
 #include <asm/mipsregs.h>
 #include <asm/bootinfo.h>
-#include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm/ip32/crime.h>
 #include <asm/ip32/mace.h>
@@ -25,10 +26,40 @@
 extern struct rtc_ops ip32_rtc_ops;
 extern u32 cc_interval;
 
-void __init ip32_init (int argc, char **argv, char **envp) {
-	arc_meminit ();
+#ifdef CONFIG_SGI_O2MACE_ETH
+
+/*
+ * This is taken care of in here 'cause they say using Arc later on is
+ * problematic
+ */
+extern char o2meth_eaddr[8];
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return 0; /* foo */
 }
 
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if(*str == ':')
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+#endif
+
+extern void ip32_time_init(void);
+
 void __init ip32_setup(void)
 {
 #ifdef CONFIG_SERIAL_CONSOLE
@@ -36,6 +67,8 @@
 #endif
 	TLBMISS_HANDLER_SETUP ();
 
+	mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);;
+
 #ifdef CONFIG_SERIAL_CONSOLE
 	ctype = ArcGetEnvironmentVariable("console");
 	if (*ctype == 'd') {
@@ -45,12 +78,19 @@
 			console_setup ("ttyS0");
 	}
 #endif
+#ifdef CONFIG_SGI_O2MACE_ETH
+	{
+		char *mac=ArcGetEnvironmentVariable("eaddr");
+		str2eaddr(o2meth_eaddr, mac);
+	}
+#endif
 
 #ifdef CONFIG_VT
 	conswitchp = &dummy_con;
 #endif
 
 	rtc_ops = &ip32_rtc_ops;
+	board_time_init = ip32_time_init;
 
 	crime_init ();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/sgi-ip32/ip32-timer.c linux/arch/mips64/sgi-ip32/ip32-timer.c
--- linux.orig/arch/mips64/sgi-ip32/ip32-timer.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/arch/mips64/sgi-ip32/ip32-timer.c	2002-07-20 01:08:30.000000000 +0000
@@ -7,21 +7,46 @@
  *
  * Copyright (C) 2001 Keith M Wesolowski
  */
-#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+
 #include <asm/mipsregs.h>
 #include <asm/param.h>
 #include <asm/ip32/crime.h>
 #include <asm/ip32/ip32_ints.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+extern volatile unsigned long wall_jiffies;
+extern rwlock_t xtime_lock;
 
-extern u32 cc_interval;
+u32 cc_interval;
+
+/* Cycle counter value at the previous timer interrupt.. */
+static unsigned int timerhi, timerlo;
 
 /* An arbitrary time; this can be decreased if reliability looks good */
 #define WAIT_MS 10
 #define PER_MHZ (1000000 / 2 / HZ)
+/*
+ * Change this if you have some constant time drift
+ */
+#define USECS_PER_JIFFY (1000000/HZ)
+
 
-void __init ip32_timer_setup (struct irqaction *irq) {
+void __init ip32_timer_setup (struct irqaction *irq)
+{
 	u64 crime_time;
 	u32 cc_tick;
 
@@ -45,3 +70,169 @@
 
 	setup_irq (CLOCK_IRQ, irq);
 }
+
+struct irqaction irq0  = { NULL, SA_INTERRUPT, 0,
+			   "timer", NULL, NULL};
+
+void cc_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	u32 count;
+
+	/*
+	 * The cycle counter is only 32 bit which is good for about
+	 * a minute at current count rates of upto 150MHz or so.
+	 */
+	count = read_32bit_cp0_register(CP0_COUNT);
+	timerhi += (count < timerlo);	/* Wrap around */
+	timerlo = count;
+
+	write_32bit_cp0_register (CP0_COMPARE, 
+				  (u32) (count + cc_interval));
+	kstat.irqs[0][irq]++;
+	do_timer (regs);
+
+	if (!jiffies)
+	{
+		/*
+		 * If jiffies has overflowed in this timer_interrupt we must
+		 * update the timer[hi]/[lo] to make do_fast_gettimeoffset()
+		 * quotient calc still valid. -arca
+		 */
+		timerhi = timerlo = 0;
+	}
+}
+
+/*
+ * On MIPS only R4000 and better have a cycle counter.
+ *
+ * FIXME: Does playing with the RP bit in c0_status interfere with this code?
+ */
+static unsigned long do_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+
+	/* Last jiffy when do_fast_gettimeoffset() was called. */
+	static unsigned long last_jiffies;
+	u32 quotient;
+
+	/*
+	 * Cached "1/(clocks per usec)*2^32" value.
+	 * It has to be recalculated once each jiffy.
+	 */
+	static u32 cached_quotient;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (tmp && last_jiffies != tmp) {
+		last_jiffies = tmp;
+		__asm__(".set\tnoreorder\n\t"
+			".set\tnoat\n\t"
+			".set\tmips3\n\t"
+			"lwu\t%0,%2\n\t"
+			"dsll32\t$1,%1,0\n\t"
+			"or\t$1,$1,%0\n\t"
+			"ddivu\t$0,$1,%3\n\t"
+			"mflo\t$1\n\t"
+			"dsll32\t%0,%4,0\n\t"
+			"nop\n\t"
+			"ddivu\t$0,%0,$1\n\t"
+			"mflo\t%0\n\t"
+			".set\tmips0\n\t"
+			".set\tat\n\t"
+			".set\treorder"
+			:"=&r" (quotient)
+			:"r" (timerhi),
+			 "m" (timerlo),
+			 "r" (tmp),
+			 "r" (USECS_PER_JIFFY)
+			:"$1");
+		cached_quotient = quotient;
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+		"mfhi\t%0"
+		:"=r" (res)
+		:"r" (count),
+		 "r" (quotient));
+
+	/*
+ 	 * Due to possible jiffies inconsistencies, we need to check 
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
+}
+
+void __init ip32_time_init(void)
+{
+	unsigned int epoch = 0, year, mon, day, hour, min, sec;
+	int i;
+
+	/* The Linux interpretation of the CMOS clock register contents:
+	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+	 * RTC registers show the second which has precisely just started.
+	 * Let's hope other operating systems interpret the RTC the same way.
+	 */
+	/* read RTC exactly on falling edge of update flag */
+	for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
+		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+			break;
+	for (i = 0 ; i < 1000000 ; i++)	/* must try at least 2.228 ms */
+		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+			break;
+	do { /* Isn't this overkill ? UIP above should guarantee consistency */
+		sec = CMOS_READ(RTC_SECONDS);
+		min = CMOS_READ(RTC_MINUTES);
+		hour = CMOS_READ(RTC_HOURS);
+		day = CMOS_READ(RTC_DAY_OF_MONTH);
+		mon = CMOS_READ(RTC_MONTH);
+		year = CMOS_READ(RTC_YEAR);
+	} while (sec != CMOS_READ(RTC_SECONDS));
+	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hour);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(year);
+	}
+
+	/* Attempt to guess the epoch.  This is the same heuristic as in
+	 * rtc.c so no stupid things will happen to timekeeping.  Who knows,
+	 * maybe Ultrix also uses 1952 as epoch ...
+	 */
+	if (year > 10 && year < 44)
+		epoch = 1980;
+	else if (year < 96)
+		epoch = 1952;
+	year += epoch;
+
+	write_lock_irq (&xtime_lock);
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+	write_unlock_irq (&xtime_lock);
+
+	write_32bit_cp0_register(CP0_COUNT, 0);
+	irq0.handler = cc_timer_interrupt;
+
+	ip32_timer_setup (&irq0);
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+	/* Set ourselves up for future interrupts */
+        write_32bit_cp0_register(CP0_COMPARE,
+				 read_32bit_cp0_register(CP0_COUNT)
+				 + cc_interval);
+        change_cp0_status(ST0_IM, ALLINTS);
+	sti ();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/mips64/tools/Makefile linux/arch/mips64/tools/Makefile
--- linux.orig/arch/mips64/tools/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/arch/mips64/tools/Makefile	2002-07-20 01:08:25.000000000 +0000
@@ -7,10 +7,7 @@
 #
 TARGET	:= $(TOPDIR)/include/asm-$(ARCH)/offset.h
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 $(TARGET): offset.h
 	cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET))
@@ -23,8 +20,7 @@
 clean:
 	rm -f offset.[hs] $(TARGET).new
 	
-mrproper:	
-	rm -f offset.[hs] $(TARGET).new
+mrproper: clean
 	rm -f $(TARGET)
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/parisc/kernel/pdc_cons.c linux/arch/parisc/kernel/pdc_cons.c
--- linux.orig/arch/parisc/kernel/pdc_cons.c	2001-09-17 04:23:15.000000000 +0000
+++ linux/arch/parisc/kernel/pdc_cons.c	2002-07-20 01:08:29.000000000 +0000
@@ -105,10 +105,6 @@
 static struct console pdc_cons = {
 	name:		"ttyB",
 	write:		pdc_console_write,
-	read:		NULL,
-	device:		NULL, 
-	wait_key:	pdc_console_wait_key,
-	unblank:	NULL,
 	setup:		pdc_console_setup,
 	flags:		CON_PRINTBUFFER|CON_ENABLED,  // |CON_CONSDEV,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/parisc/kernel/signal.c linux/arch/parisc/kernel/signal.c
--- linux.orig/arch/parisc/kernel/signal.c	2000-12-06 19:46:39.000000000 +0000
+++ linux/arch/parisc/kernel/signal.c	2002-07-20 01:08:35.000000000 +0000
@@ -581,11 +581,7 @@
 				/* FALLTHRU */
 
 			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/parisc/kernel/syscall.S linux/arch/parisc/kernel/syscall.S
--- linux.orig/arch/parisc/kernel/syscall.S	2001-10-08 17:39:18.000000000 +0000
+++ linux/arch/parisc/kernel/syscall.S	2002-07-20 01:08:40.000000000 +0000
@@ -552,6 +552,8 @@
 	ENTRY_UHOH(shmctl)		/* 195 */
 	ENTRY_SAME(ni_syscall)		/* streams1 */
 	ENTRY_SAME(ni_syscall)		/* streams2 */
+	ENTRY_SAME(gettid)
+	ENTRY_SAME(tkill)
 
 .end
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/8260_io/Config.in linux/arch/ppc/8260_io/Config.in
--- linux.orig/arch/ppc/8260_io/Config.in	2000-09-17 16:48:05.000000000 +0000
+++ linux/arch/ppc/8260_io/Config.in	2002-07-20 01:08:23.000000000 +0000
@@ -1,9 +1,10 @@
 #
 # MPC8260 Communication options
 #
+mainmenu_option next_comment
+comment 'MPC8260 Communication Options'
+bool 'Enable SCC Console' CONFIG_SCC_CONSOLE
 if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
-  mainmenu_option next_comment
-  comment 'MPC8260 Communication Options'
   bool 'CPM SCC Ethernet' CONFIG_SCC_ENET
   if [ "$CONFIG_SCC_ENET" = "y" ]; then
   bool 'Ethernet on SCC1' CONFIG_SCC1_ENET
@@ -21,5 +22,5 @@
     bool 'Ethernet on FCC2' CONFIG_FCC2_ENET
     bool 'Ethernet on FCC3' CONFIG_FCC3_ENET
   fi
-  endmenu
 fi
+endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/8260_io/uart.c linux/arch/ppc/8260_io/uart.c
--- linux.orig/arch/ppc/8260_io/uart.c	2002-02-25 19:37:53.000000000 +0000
+++ linux/arch/ppc/8260_io/uart.c	2002-07-20 01:08:24.000000000 +0000
@@ -2216,54 +2216,6 @@
 		info->tx_cur = (cbd_t *)bdp;
 }
 
-/*
- * Receive character from the serial port.  This only works well
- * before the port is initialize for real use.
- */
-static int serial_console_wait_key(struct console *co)
-{
-	struct serial_state		*ser;
-	u_char				c, *cp;
-	ser_info_t			*info;
-	volatile	cbd_t		*bdp;
-	volatile	smc_uart_t	*up;
-
-	ser = rs_table + co->index;
-
-	/* Pointer to UART in parameter ram.
-	*/
-	up = (smc_uart_t *)&immr->im_dprambase[ser->port];
-
-	/* Get the address of the host memory buffer.
-	 * If the port has been initialized for general use, we must
-	 * use information from the port structure.
-	 */
-	if ((info = (ser_info_t *)ser->info))
-		bdp = info->rx_cur;
-	else
-		bdp = (cbd_t *)&immr->im_dprambase[up->smc_rbase];
-
-	/*
-	 * We need to gracefully shut down the receiver, disable
-	 * interrupts, then read the input.
-	 */
-	while (bdp->cbd_sc & BD_SC_EMPTY);	/* Wait for a character */
-	cp = __va(bdp->cbd_bufaddr);
-
-	if (info) {
-		if (bdp->cbd_sc & BD_SC_WRAP) {
-			bdp = info->rx_bd_base;
-		}
-		else {
-			bdp++;
-		}
-		info->rx_cur = (cbd_t *)bdp;
-	}
-
-	c = *cp;
-	return((int)c);
-}
-
 static kdev_t serial_console_device(struct console *c)
 {
 	return MKDEV(TTYAUX_MAJOR, 64 + c->index);
@@ -2274,7 +2226,6 @@
 	name:		"ttyS",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		CONFIG_SERIAL_CONSOLE_PORT,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/8xx_io/uart.c linux/arch/ppc/8xx_io/uart.c
--- linux.orig/arch/ppc/8xx_io/uart.c	2002-02-25 19:37:54.000000000 +0000
+++ linux/arch/ppc/8xx_io/uart.c	2002-07-20 01:08:27.000000000 +0000
@@ -97,7 +97,6 @@
 static void serial_console_write(struct console *c, const char *s,
 				unsigned count);
 static kdev_t serial_console_device(struct console *c);
-static int serial_console_wait_key(struct console *co);
 
 #if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 static unsigned long break_pressed; /* break, really ... */
@@ -218,7 +217,6 @@
 	name:		"ttyS",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		CONFIG_SERIAL_CONSOLE_PORT,
@@ -2402,11 +2400,6 @@
 	return((int)c);
 }
 
-static int serial_console_wait_key(struct console *co)
-{
-	return(my_console_wait_key(co->index, 0, NULL));
-}
-
 #ifdef CONFIG_XMON
 int
 xmon_8xx_read_poll(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c
--- linux.orig/arch/ppc/amiga/config.c	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/ppc/amiga/config.c	2002-07-20 01:08:31.000000000 +0000
@@ -103,7 +103,6 @@
 extern void amiga_floppy_setup(char *, int *);
 #endif
 static void amiga_reset (void);
-static int amiga_wait_key (struct console *co);
 extern void amiga_init_sound(void);
 static void amiga_savekmsg_init(void);
 static void amiga_mem_console_write(struct console *co, const char *b,
@@ -117,7 +116,6 @@
 
 static struct console amiga_console_driver = {
 	name:		"debug",
-	wait_key:	amiga_wait_key,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
 };
@@ -735,33 +733,6 @@
 	return 0;
 }
 
-static int amiga_wait_key (struct console *co)
-{
-    int i;
-
-    while (1) {
-	while (ciaa.pra & 0x40);
-
-	/* debounce */
-	for (i = 0; i < 1000; i++);
-
-	if (!(ciaa.pra & 0x40))
-	    break;
-    }
-
-    /* wait for button up */
-    while (1) {
-	while (!(ciaa.pra & 0x40));
-
-	/* debounce */
-	for (i = 0; i < 1000; i++);
-
-	if (ciaa.pra & 0x40)
-	    break;
-    }
-    return 0;
-}
-
 static NORET_TYPE void amiga_reset( void )
     ATTRIB_NORET;
 
@@ -983,8 +954,9 @@
     AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
     AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");
     if (AMIGAHW_PRESENT(ZORRO))
-	len += sprintf(buffer+len, "\tZorro%s AutoConfig: %d Expansion Device%s\n",
-		       AMIGAHW_PRESENT(ZORRO3) ? " III" : "",
+	len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion "
+				   "Device%s\n",
+		       AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
 		       zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
 
 #undef AMIGAHW_ANNOUNCE
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile
--- linux.orig/arch/ppc/boot/Makefile	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/Makefile	2002-07-20 01:08:23.000000000 +0000
@@ -17,29 +17,24 @@
 AFLAGS	+= -D__BOOTER__
 OBJCOPY_ARGS = -O elf32-powerpc
 
-ifeq ($(CONFIG_SMP),y)
-TFTPSIMAGE=/tftpboot/sImage.smp
-else
-TFTPSIMAGE=/tftpboot/sImage
-endif
+MKIMAGE				:= ./utils/mkimage.wrapper
 
-lib/zlib.a:
+lib/zlib.a: lib/zlib.c
 	$(MAKE) -C lib
 
 images/vmlinux.gz: $(TOPDIR)/vmlinux
 	$(MAKE) -C images vmlinux.gz
 
-# Subdirs and tools needed for each.
-subdir-y			:= lib images common
-subdir-$(CONFIG_ALL_PPC)	+= chrp pmac prep
-tools-$(CONFIG_ALL_PPC)		:= addnote piggyback mknote hack-coff mkprep
-subdir-$(CONFIG_4xx)		+= tree
-subdir-$(CONFIG_8xx)		+= mbx
-subdir-$(CONFIG_8260)		+= mbx
-tools-$(CONFIG_GEMINI)		:= mksimage
-
-# These are dirs we don't want to go into on BOOT_TARGETS
-NONBOOT				:= lib images common
+# Subdirs and tools needed for each.  Assume we always need to go into
+# 'simple' unless told otherwise.
+subdir-y			:= lib common simple
+subdir-$(CONFIG_ALL_PPC)	:= chrp pmac prep
+tools-$(CONFIG_ALL_PPC)		:= addnote mknote hack-coff mkprep
+tools-$(CONFIG_4xx)		:= mktree
+
+# These are dirs we don't want to go into on BOOT_TARGETS.  We have them for
+# the 'depend' stage.
+NONBOOT				:= lib common
 
 # These are the subdirs we want to use
 BOOTDIRS			= $(filter-out $(NONBOOT), $(subdir-y))
@@ -50,37 +45,29 @@
 	$(MAKE) -C utils $(tools-y)
 
 # The targets all boards support for boot images.
-BOOT_TARGETS = zImage
-ifndef CONFIG_GEMINI
-BOOT_TARGETS += zImage.initrd znetboot znetboot.initrd
-endif
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
 
-$(BOOT_TARGETS): sImage vmapus lib/zlib.a images/vmlinux.gz maketools
+$(BOOT_TARGETS): vmapus lib/zlib.a images/vmlinux.gz maketools
 ifneq ($(BOOTDIRS),)
 	for d in $(BOOTDIRS); do $(MAKE) -C $$d $@; done
 endif
 
-sImage: $(TOPDIR)/vmlinux
-ifdef CONFIG_GEMINI
-	$(OBJCOPY) -I elf32-powerpc -O binary $(TOPDIR)/vmlinux images/sImage
-endif
-
 vmapus: $(TOPDIR)/vmlinux
 ifdef CONFIG_APUS
 	$(STRIP) $(TOPDIR)/vmlinux -o images/vmapus
 	gzip $(GZIP_FLAGS) images/vmapus
 endif
 
-ifdef CONFIG_GEMINI
-znetboot : zImage
-	cp images/sImage $(TFTPSIMAGE)
-endif
+# Make an image for PPCBoot
+pImage: images/vmlinux.gz
+	$(MKIMAGE) -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \
+	-n 'Linux-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)' \
+	-d $< images/vmlinux.PPCBoot
+	ln -sf vmlinux.PPCBoot images/pImage
 
-# Clean up after ourselves.  We have to do it like this since only some dirs
-# need to be gone into. -- Tom
+# These are subdirs with files not normally rm'ed. -- Tom
 clean:
 	$(MAKE) -C images clean
-	$(MAKE) -C tree clean
 	$(MAKE) -C utils clean
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/chrp/Makefile linux/arch/ppc/boot/chrp/Makefile
--- linux.orig/arch/ppc/boot/chrp/Makefile	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/chrp/Makefile	2002-07-20 01:08:39.000000000 +0000
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.13 07/27/01 20:24:17 trini
+# BK Id: SCCS/s.Makefile 1.15 01/11/02 10:46:06 trini
 #
 # Makefile for making ELF bootable images for booting on CHRP
 # using Open Firmware.
@@ -7,19 +7,9 @@
 #
 # Based on coffboot by Paul Mackerras
 
-ifeq ($(CONFIG_PPC64BRIDGE),y)
-MSIZE=.64
-AFLAGS += -Wa,-mppc64bridge
-else
-MSIZE=
-endif
-
-.c.o:
-	$(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $<
-.S.o:
-	$(CC) $(AFLAGS) -traditional -c -o $*.o $<
+USE_STANDARD_AS_RULE := true
 
-LD_ARGS = -Ttext 0x00400000
+LD_ARGS = -T ../ld.script -Ttext 0x00400000
 
 OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o \
 	../common/ofcommon.o
@@ -27,23 +17,22 @@
 ADDNOTE = ../utils/addnote
 PIGGYBACK = ../utils/piggyback
 
+ifeq ($(CONFIG_PPC64BRIDGE),y)
+END += .64
+AFLAGS += -Wa,-mppc64bridge
+endif
 ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE)
-else
-TFTPIMAGE=/tftpboot/zImage.chrp$(MSIZE)
+END += .smp
 endif
 
+TFTPIMAGE=/tftpboot/zImage.chrp$(END)
+
+AFLAGS_../common/crt0.o		+= -I$(TOPDIR)/arch/$(ARCH)/kernel
+
 all: zImage
 
 znetboot: zImage
-ifdef CONFIG_SMP
-	cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux.smp
-else
-	cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux
-endif
-ifdef CONFIG_PPC64BRIDGE
-	cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux.64
-endif
+	cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux$(END)
 	cp ../images/zImage.chrp $(TFTPIMAGE)
 
 znetboot.initrd: zImage.initrd
@@ -52,22 +41,28 @@
 floppy: zImage
 	mcopy zImage a:zImage
 
-image.o: $(PIGGYBACK) ../images/vmlinux.gz
-	$(PIGGYBACK) image < ../images/vmlinux.gz | $(AS) -o $@
-
-sysmap.o: $(PIGGYBACK) $(TOPDIR)/System.map
-	$(PIGGYBACK) sysmap < $(TOPDIR)/System.map | $(AS) -o $@
-
-initrd.o: ../images/ramdisk.image.gz $(PIGGYBACK)
-	$(PIGGYBACK) initrd < ../images/ramdisk.image.gz | $(AS) -o $@
+image.o: ../images/vmlinux.gz ../common/dummy.o
+	$(OBJCOPY) ../common/dummy.o $@ \
+		--add-section=.image=../images/vmlinux.gz \
+		--set-section-flags=.image=contents,alloc,load,readonly,data
+ifdef CONFIG_XMON
+	$(OBJCOPY) $@ $@ \
+		--add-section=.sysmap=$(TOPDIR)/System.map \
+		--set-section-flags=.sysmap=contents,alloc,load,readonly,data
+endif
 
-zImage: $(OBJS) $(LIBS) ../common/no_initrd.o $(ADDNOTE) ../images/vmlinux.gz
-	$(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) ../common/no_initrd.o $(LIBS)
+zImage: $(OBJS) $(LIBS) $(ADDNOTE)
+	$(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS)
+	$(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment -R .ramdisk
 	cp ../images/$@.chrp ../images/$@.chrp-rs6k
 	$(ADDNOTE) ../images/$@.chrp-rs6k
 
-zImage.initrd: $(OBJS) $(LIBS) initrd.o $(ADDNOTE) ../images/vmlinux.gz
-	$(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) initrd.o $(LIBS)
+zImage.initrd: $(OBJS) $(LIBS) $(ADDNOTE) ../images/ramdisk.image.gz
+	$(OBJCOPY) image.o image.o \
+		--add-section=.ramdisk=../images/ramdisk.image.gz \
+		--set-section-flags=.ramdisk=contents,alloc,load,readonly,data
+	$(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS)
+	$(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment
 	cp ../images/$@.chrp ../images/$@.chrp-rs6k
 	$(ADDNOTE) ../images/$@.chrp-rs6k
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/chrp/main.c linux/arch/ppc/boot/chrp/main.c
--- linux.orig/arch/ppc/boot/chrp/main.c	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/chrp/main.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.main.c 1.13 07/27/01 20:24:17 trini
+ * BK Id: SCCS/s.main.c 1.16 01/12/02 10:36:33 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -11,15 +11,14 @@
  */
 #include "nonstdio.h"
 #include <asm/processor.h>
+#include <asm/page.h>
+
+/* Passed from the linker */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin[], __ramdisk_end;
+extern char _start, _end;
 
-extern char _end[];
-extern char initrd_data[];
-extern char image_data[];
-extern char sysmap_data[];
 extern int getprop(void *, const char *, void *, int);
-extern int initrd_len;
-extern int image_len;
-extern int sysmap_len;
 extern unsigned int heap_max;
 extern void claim(unsigned int virt, unsigned int size, unsigned int align);
 extern void *finddevice(const char *);
@@ -53,22 +52,27 @@
     unsigned sa, len;
     void *dst;
     unsigned char *im;
-    unsigned initrd_start=0, initrd_size=0;
-    extern char _start;
+    unsigned int initrd_size, initrd_start;
     
     printf("chrpboot starting: loaded at 0x%p\n\r", &_start);
 
-    if (initrd_len) {
-	initrd_size = initrd_len;
+    initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
+    if (initrd_size) {
 	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+	a1 = initrd_start;
+	a2 = initrd_size;
 	claim(initrd_start, RAM_END - initrd_start, 0);
 	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
-	       initrd_start, initrd_data, initrd_size);
-	memcpy((char *)initrd_start, initrd_data, initrd_size);
+	       initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+	memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+    } else {
+	initrd_start = 0;
+	initrd_size = 0;
+	a2 = 0xdeadbeef;
     }
 
-    im = image_data;
-    len = image_len;
+    im = (char *)(&__image_begin);
+    len = (char *)(&__image_end) - (char *)(&__image_begin);
     /* claim 4MB starting at PROG_START */
     claim(PROG_START, PROG_SIZE - PROG_START, 0);
     dst = (void *) PROG_START;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/chrp/start.c linux/arch/ppc/boot/chrp/start.c
--- linux.orig/arch/ppc/boot/chrp/start.c	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/chrp/start.c	2002-07-20 01:08:21.000000000 +0000
@@ -11,7 +11,7 @@
  */
 #include <stdarg.h>
 
-int (*prom)();
+int (*prom)(void *args);
 
 void *chosen_handle;
 void *stdin;
@@ -30,7 +30,7 @@
 void
 start(int a1, int a2, void *promptr)
 {
-    prom = (int (*)()) promptr;
+    prom = promptr;
     chosen_handle = finddevice("/chosen");
     if (chosen_handle == (void *) -1)
 	exit();
@@ -65,7 +65,7 @@
     args.addr = ptr;
     args.len = nb;
     args.actual = -1;
-    (*prom)(&args);
+    prom(&args);
     return args.actual;
 }
 
@@ -211,7 +211,7 @@
 }
 
 int
-readchar()
+readchar(void)
 {
     char ch;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/Makefile linux/arch/ppc/boot/common/Makefile
--- linux.orig/arch/ppc/boot/common/Makefile	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/common/Makefile	2002-07-20 01:08:22.000000000 +0000
@@ -8,20 +8,10 @@
 # Tom Rini	January 2001
 #
 
-.c.s:
-	$(CC) $(CFLAGS) -S -o $*.s $<
-.s.o:
-	$(AS) -o $*.o $<
-.c.o:
-	$(CC) $(CFLAGS) -c -o $*.o $<
-.S.s:
-	$(CPP) $(AFLAGS) -traditional -o $*.o $<
-.S.o:
-	$(CC) $(AFLAGS) -traditional -c -o $*.o $<
-
-OBJCOPY_ARGS = -O elf32-powerpc
+USE_STANDARD_AS_RULE	:= true
 
 coffcrt0.o:
-	$(CC) $(AFLAGS) -DXCOFF -traditional -c -o coffcrt0.o crt0.S
+	$(CC) -I$(TOPDIR)/arch/$(ARCH)/kernel $(AFLAGS) -DXCOFF \
+		-traditional -c -o coffcrt0.o crt0.S
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/crt0.S linux/arch/ppc/boot/common/crt0.S
--- linux.orig/arch/ppc/boot/common/crt0.S	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/common/crt0.S	2002-07-20 01:08:38.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.crt0.S 1.12 08/09/01 17:09:10 paulus
+ * BK Id: SCCS/s.crt0.S 1.14 01/11/02 10:46:07 trini
  */
 /*    Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
  *      Initial Power Macintosh COFF version.
@@ -22,7 +22,7 @@
  */
 
 #include <linux/config.h>
-#include "../../kernel/ppc_asm.tmpl"
+#include "ppc_asm.h"
 
 	.text
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/dummy.c linux/arch/ppc/boot/common/dummy.c
--- linux.orig/arch/ppc/boot/common/dummy.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/common/dummy.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,7 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+int main(void)
+{
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/misc-simple.c linux/arch/ppc/boot/common/misc-simple.c
--- linux.orig/arch/ppc/boot/common/misc-simple.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/common/misc-simple.c	2002-07-20 01:08:29.000000000 +0000
@@ -3,10 +3,10 @@
  *
  * Misc. bootloader code for many machines.  This assumes you have are using
  * a 6xx/7xx/74xx CPU in your machine.  This assumes the chunk of memory
- * below 8MB is free.  Finally, it assumes you have a NS16550-style uart for 
+ * below 8MB is free.  Finally, it assumes you have a NS16550-style uart for
  * your serial console.  If a machine meets these requirements, it can quite
  * likely use this code during boot.
- * 
+ *
  * Author: Matt Porter <mporter@mvista.com>
  * Derived from arch/ppc/boot/prep/misc.c
  *
@@ -25,50 +25,59 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/mmu.h>
+#include <asm/bootinfo.h>
 
 #include "nonstdio.h"
 #include "zlib.h"
 
-unsigned long com_port;
-
-char *avail_ram;
-char *end_avail;
-extern char _end[];
-
+/* Default cmdline */
 #ifdef CONFIG_CMDLINE
 #define CMDLINE CONFIG_CMDLINE
 #else
 #define CMDLINE ""
 #endif
+
+/* Keyboard (and VGA console)? */
+#ifdef CONFIG_VGA_CONSOLE
+#define HAS_KEYB 1
+#else
+#define HAS_KEYB 0
+#endif
+
+char *avail_ram;
+char *end_avail;
+char *zimage_start;
 char cmd_preset[] = CMDLINE;
 char cmd_buf[256];
 char *cmd_line = cmd_buf;
+int keyb_present = HAS_KEYB;
+int zimage_size;
 
-unsigned long initrd_start = 0, initrd_end = 0;
+unsigned long com_port;
+unsigned long initrd_size = 0;
 
-/* These values must be variables.  If not, the compiler optimizer
- * will remove some code, causing the size of the code to vary
- * when these values are zero.  This is bad because we first
- * compile with these zero to determine the size and offsets
- * in an image, than compile again with these set to the proper
- * discovered value.
- */
-unsigned int initrd_offset, initrd_size;
-char *zimage_start;
-int zimage_size;
+/* The linker tells us various locations in the image */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin, __ramdisk_end;
+extern char _end[];
+/* Original location */
+extern unsigned long start;
 
+extern int CRT_tstc(void);
+extern unsigned long serial_init(int chan, void *ignored);
+extern void serial_close(unsigned long com_port);
 extern void gunzip(void *, int, unsigned char *, int *);
-extern unsigned long serial_init(int chan);
+extern void serial_fixups(void);
 
-void
+struct bi_record *
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
 {
-
 	int timer = 0;
-	extern unsigned long start;
 	char *cp, ch;
+	struct bi_record *rec, *birecs;
 
-	com_port = serial_init(0);
+	serial_fixups();
+	com_port = serial_init(0, NULL);
 
 	/* assume the chunk below 8M is free */
 	end_avail = (char *)0x00800000;
@@ -88,42 +97,31 @@
 		puts("\n");
 	}
 
-	/* we have to subtract 0x10000 here to correct for objdump including
-	   the size of the elf header which we strip -- Cort */
-	zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
-	zimage_size = ZIMAGE_SIZE;
-	initrd_offset = INITRD_OFFSET;
-	initrd_size = INITRD_SIZE;
-
-	if ( initrd_offset )
-		initrd_start = load_addr - 0x10000 + initrd_offset;
-	else
-		initrd_start = 0;
-	initrd_end = initrd_size + initrd_start;
+	/*
+	 * We link ourself to 0x00800000.  When we run, we relocate
+	 * ourselves there.  So we just need __image_begin for the
+	 * start. -- Tom
+	 */
+	zimage_start = (char *)(unsigned long)(&__image_begin);
+	zimage_size = (unsigned long)(&__image_end) -
+			(unsigned long)(&__image_begin);
+
+	initrd_size = (unsigned long)(&__ramdisk_end) -
+		(unsigned long)(&__ramdisk_begin);
 
-	/* Relocate the zImage */
+	/*
+	 * The zImage and initrd will be between start and _end, so they've
+	 * already been moved once.  We're good to go now. -- Tom
+	 */
 	avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
 	puts("zimage at:     "); puthex((unsigned long)zimage_start);
 	puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
 	puts("\n");
-	memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size );
-	zimage_start = (char *)avail_ram;
-	puts("relocated to:  "); puthex((unsigned long)zimage_start);
-	puts(" ");
-	puthex((unsigned long)zimage_size+(unsigned long)zimage_start);
-	puts("\n");
 
-	if ( initrd_start ) {
-		puts("initrd at:     "); puthex(initrd_start);
-		puts(" "); puthex(initrd_end); puts("\n");
-		/* relocate initrd */
-		avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_size + 
-				(unsigned long)zimage_start);
-		memcpy( (void *)avail_ram, (void *)initrd_start, initrd_size );
-		initrd_start = (unsigned long)avail_ram;
-		initrd_end = initrd_start + initrd_size;
-		puts("relocated to:  "); puthex(initrd_start);
-		puts(" "); puthex(initrd_end); puts("\n");
+	if ( initrd_size ) {
+		puts("initrd at:     ");
+		puthex((unsigned long)(&__ramdisk_begin));
+		puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
 	}
 
 	avail_ram = (char *)0x00400000;
@@ -131,11 +129,28 @@
 	puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
 	puthex((unsigned long)end_avail); puts("\n");
 
+	if (keyb_present)
+		CRT_tstc();  /* Forces keyboard to be initialized */
+#ifdef CONFIG_GEMINI
+	/*
+	 * If cmd_line is empty and cmd_preset is not, copy cmd_preset
+	 * to cmd_line.  This way we can override cmd_preset with the
+	 * command line from Smon.
+	 */
+
+	if ( (cmd_line[0] == '\0') && (cmd_preset[0] != '\0'))
+		memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
+#endif
+
 	/* Display standard Linux/PPC boot prompt for kernel args */
 	puts("\nLinux/PPC load: ");
 	cp = cmd_line;
 	memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
 	while ( *cp ) putc(*cp++);
+
+#ifndef CONFIG_GEMINI
+	/* Val Henson has requested that Gemini doesn't wait for the
+	 * user to edit the cmdline or not. */
 	while (timer++ < 5*1000) {
 		if (tstc()) {
 			while ((ch = getc()) != '\n' && ch != '\r') {
@@ -161,16 +176,44 @@
 		udelay(1000);  /* 1 msec */
 	}
 	*cp = 0;
+#endif
 	puts("\n");
 
-	/* mappings on early boot can only handle 16M */
-	if ( (u32)(cmd_line) > (16<<20))
-		puts("cmd_line located > 16M\n");
-
 	puts("Uncompressing Linux...");
-
 	gunzip(0, 0x400000, zimage_start, &zimage_size);
 	puts("done.\n");
 
+	/*
+	 * Create bi_recs for cmd_line and initrds
+	 */
+	rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) +
+			(1 << 20) - 1, (1 << 20));
+	birecs = rec;
+
+	rec->tag = BI_FIRST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	rec->tag = BI_CMD_LINE;
+	memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
+	rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	if ( initrd_size ) {
+		rec->tag = BI_INITRD;
+		rec->data[0] = (unsigned long)(&__ramdisk_begin);
+		rec->data[1] = initrd_size;
+		rec->size = sizeof(struct bi_record) + 2 *
+			sizeof(unsigned long);
+		rec = (struct bi_record *)((unsigned long)rec +
+				rec->size);
+	}
+
+	rec->tag = BI_LAST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
 	puts("Now booting the kernel\n");
+	serial_close(com_port);
+
+	return birecs;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/no_initrd.c linux/arch/ppc/boot/common/no_initrd.c
--- linux.orig/arch/ppc/boot/common/no_initrd.c	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/common/no_initrd.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,5 +0,0 @@
-/*
- * BK Id: SCCS/s.no_initrd.c 1.7 05/18/01 15:17:23 cort
- */
-char initrd_data[1];
-int initrd_len = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/ns16550.c linux/arch/ppc/boot/common/ns16550.c
--- linux.orig/arch/ppc/boot/common/ns16550.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/common/ns16550.c	2002-07-20 01:08:34.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ns16550.c 1.12 10/08/01 17:16:50 paulus
+ * BK Id: SCCS/s.ns16550.c 1.16 03/13/02 09:17:06 trini
  */
 /*
  * COM1 NS16550 support
@@ -10,7 +10,6 @@
 #include <linux/serial_reg.h>
 #include <asm/serial.h>
 
-/* Default serial baud rate */
 #define SERIAL_BAUD	9600
 
 extern void outb(int port, unsigned char val);
@@ -23,8 +22,10 @@
 
 static int shift;
 
-unsigned long serial_init(int chan) {
+unsigned long serial_init(int chan, void *ignored)
+{
 	unsigned long com_port;
+	unsigned char lcr, dlm;
 
 	/* We need to find out which type io we're expecting.  If it's
 	 * 'SERIAL_IO_PORT', we get an offset from the isa_io_base.
@@ -43,30 +44,33 @@
 
 	/* How far apart the registers are. */
 	shift = rs_table[chan].iomem_reg_shift;
-
-	/* See if port is present */
-	outb(com_port + (UART_LCR << shift), 0x00);
-	outb(com_port + (UART_IER << shift), 0x00);
+	
+	/* save the LCR */
+	lcr = inb(com_port + (UART_LCR << shift));
 	/* Access baud rate */
 	outb(com_port + (UART_LCR << shift), 0x80);
+	dlm = inb(com_port + (UART_DLM << shift));
 	/*
 	 * Test if serial port is unconfigured.
 	 * We assume that no-one uses less than 110 baud or
 	 * less than 7 bits per character these days.
 	 *  -- paulus.
 	 */
-	if (inb(com_port + (UART_DLM << shift)) > 4
-	    || (inb(com_port + (UART_LCR << shift)) & 2) == 0) {
+
+	if ((dlm <= 4) && (lcr & 2))
+		/* port is configured, put the old LCR back */
+		outb(com_port + (UART_LCR << shift), lcr);
+	else {
 		/* Input clock. */
 		outb(com_port + (UART_DLL << shift),
-		     (BASE_BAUD / SERIAL_BAUD));
+		     (BASE_BAUD / SERIAL_BAUD) & 0xFF);
 		outb(com_port + (UART_DLM << shift),
 		     (BASE_BAUD / SERIAL_BAUD) >> 8);
+		/* 8 data, 1 stop, no parity */
+		outb(com_port + (UART_LCR << shift), 0x03);
+		/* RTS/DTR */
+		outb(com_port + (UART_MCR << shift), 0x03);
 	}
-	 /* 8 data, 1 stop, no parity */
-	outb(com_port + (UART_LCR << shift), 0x03);
-	/* RTS/DTR */
-	outb(com_port + (UART_MCR << shift), 0x03);
 	/* Clear & enable FIFOs */
 	outb(com_port + (UART_FCR << shift), 0x07);
 
@@ -94,3 +98,8 @@
 {
 	return ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0);
 }
+
+void
+serial_close(unsigned long com_port)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/ofcommon.c linux/arch/ppc/boot/common/ofcommon.c
--- linux.orig/arch/ppc/boot/common/ofcommon.c	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/common/ofcommon.c	2002-07-20 01:08:34.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ofcommon.c 1.1 07/27/01 20:24:18 trini
+ * BK Id: SCCS/s.ofcommon.c 1.2 01/11/02 10:46:07 trini
  *
  * Copyright (C) Paul Mackerras 1997.
  *
@@ -14,6 +14,9 @@
 #include <asm/bootinfo.h>
 #include <asm/page.h>
 
+/* Information from the linker */
+extern char __sysmap_begin, __sysmap_end;
+
 extern int strcmp(const char *s1, const char *s2);
 extern char *avail_ram, *avail_high;
 extern char *end_avail;
@@ -126,15 +129,22 @@
     inflateEnd(&s);
 }
 
-/* Make a bi_rec in OF.  We need to be passed a name for BI_BOOTLOADER_ID, 
+/* Make a bi_rec in OF.  We need to be passed a name for BI_BOOTLOADER_ID,
  * a machine type for BI_MACHTYPE, and the location where the end of the
  * bootloader is (PROG_START + PROG_SIZE)
  */
 void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
 		unsigned long progend)
 {
+	unsigned long sysmap_size;
 	struct bi_record *rec;
 
+	/* FIgure out the size of a possible System.map we're going to
+	 * pass along.
+	 * */
+	sysmap_size = (unsigned long)(&__sysmap_end) -
+		(unsigned long)(&__sysmap_begin);
+
 	/* leave a 1MB gap then align to the next 1MB boundary */
 	addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
 	/* oldworld machine seem very unhappy about this. -- Tom */
@@ -150,21 +160,22 @@
 	sprintf( (char *)rec->data, name);
 	rec->size = sizeof(struct bi_record) + strlen(name) + 1;
 	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-	    
+
 	rec->tag = BI_MACHTYPE;
 	rec->data[0] = mach;
 	rec->data[1] = 1;
 	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
 	rec = (struct bi_record *)((unsigned long)rec + rec->size);
 
-#ifdef SYSMAP_OFFSET
-	rec->tag = BI_SYSMAP;
-	rec->data[0] = SYSMAP_OFFSET;
-	rec->data[1] = SYSMAP_SIZE;
-	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-#endif /* SYSMAP_OFFSET */
-	
+	if (sysmap_size) {
+		rec->tag = BI_SYSMAP;
+		rec->data[0] = (unsigned long)(&__sysmap_begin);
+		rec->data[1] = sysmap_size;
+		rec->size = sizeof(struct bi_record) + 2 *
+			sizeof(unsigned long);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	}
+
 	rec->tag = BI_LAST;
 	rec->size = sizeof(struct bi_record);
 	rec = (struct bi_record *)((unsigned long)rec + rec->size);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/relocate.S linux/arch/ppc/boot/common/relocate.S
--- linux.orig/arch/ppc/boot/common/relocate.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/common/relocate.S	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,210 @@
+/*
+ * arch/ppc/boot/simple/relocate.S
+ *
+ * This is the common part of the loader relocation and initialization
+ * process.  All of the board/processor specific initialization is
+ * done before we get here.
+ *
+ * Author: Tom Rini
+ *	   trini@mvista.com
+ * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include "ppc_asm.h"
+
+#define GETSYM(reg, sym)	\
+	lis	reg, sym@h; ori	reg, reg, sym@l	
+	
+	.text
+	/* We get called from the early initialization code.
+	 * Register 3 has the address where we were loaded,
+	 * Register 4 contains any residual data passed from the
+	 * boot rom.
+	 */
+	.globl	relocate
+relocate:
+	/* Save r3, r4 for later.
+	 * The r8/r11 are legacy registers so I don't have to
+	 * rewrite the code below :-).
+	 */
+	mr	r8, r3
+	mr	r11, r4
+
+	/* compute the size of the whole image in words. */
+	GETSYM(r4,start)
+	GETSYM(r5,end)
+
+	addi	r5,r5,3		/* round up */
+	sub	r5,r5,r4	/* end - start */
+	srwi	r5,r5,2
+	mr	r7,r5		/* Save for later use. */
+
+	/*
+	 * Check if we need to relocate ourselves to the link addr or were
+	 * we loaded there to begin with.
+	 */
+	cmp	cr0,r3,r4
+	beq	start_ldr	/* If 0, we don't need to relocate */
+
+	/* Move this code somewhere safe.  This is max(load + size, end) 
+	 * BIG ASSUMPTION:  Addresses below 0x80000000 are assumed to be 
+	 * in RAM, and addresses above 0x80000000 are assumed to be in 
+	 * Flash.  The cmpw instruction below does a signed integer 
+	 * comparison, so when comparing a RAM address to a Flash address
+	 * the RAM address will always be greater.  This allows the 
+	 * relocation to work when the load address is in Flash.
+	 * r8 == load address
+	 */
+	GETSYM(r4, start)
+	GETSYM(r5, end)
+
+	sub	r6,r5,r4
+	add	r6,r8,r6	/* r6 == phys(load + size) */
+
+	cmpw	r5,r6
+	bgt	1f
+	b	2f
+1:	
+	mr	r6, r5	
+2: 
+	/* dest is in r6 */	
+	/* Ensure alignment --- this code is precautionary */
+	addi	r6,r6,4
+	li	r5,0x0003
+	andc	r6,r6,r5
+
+	/* Find physical address and size of do_relocate */
+	GETSYM(r5, __relocate_start)
+	GETSYM(r4, __relocate_end)
+	GETSYM(r3, start)
+
+	/* Size to copy */
+	sub	r4,r4,r5	
+	srwi	r4,r4,2
+	
+	/* Src addr to copy (= __relocate_start - start + where_loaded) */
+	sub	r3,r5,r3
+	add	r5,r8,r3	
+
+	/* Save dest */
+	mr	r3, r6
+
+	/* Do the copy */	
+	mtctr	r4	
+3:	lwz	r4,0(r5)
+	stw	r4,0(r3)	
+	addi	r3,r3,4
+	addi	r5,r5,4
+	bdnz	3b
+
+	GETSYM(r4, __relocate_start)
+	GETSYM(r5, do_relocate)
+
+	sub	r4,r5,r4	/* Get entry point for do_relocate in */
+	add	r6,r6,r4	/* relocated section */
+
+	/* This will return to the relocated do_relocate */
+	mtlr	r6
+	b	flush_instruction_cache
+
+	.section ".relocate_code","xa"
+			
+do_relocate:		
+	/* We have 2 cases --- start < load, or start > load  
+	 * This determines whether we copy from the end, or the start.
+	 * Its easier to have 2 loops than to have paramaterised
+	 * loops.  Sigh.
+	 */
+	li	r6,0		/* Clear checksum */
+	mtctr	r7		/* Setup for a loop */
+			
+	GETSYM(r4, start)
+	mr	r3,r8		/* Get the load addr */
+
+	cmp	cr0,r4,r3	/* If we need to copy from the end, do so */
+	bgt	do_relocate_from_end
+	
+do_relocate_from_start:		
+1:	lwz	r5,0(r3)	/* Load and decrement */
+	stw	r5,0(r4)	/* Store and decrement */
+	addi	r3,r3,4
+	addi	r4,r4,4
+	xor	r6,r6,r5	/* Update checksum */
+	bdnz	1b		/* Are we done? */
+	b	do_relocate_out	/* Finished */
+
+do_relocate_from_end:	
+	GETSYM(r3, end)
+	slwi	r4,r7,2
+	add	r4,r8,r4	/* Get the physical end */
+1:	lwzu	r5,-4(r4)
+	stwu	r5, -4(r3)
+	xor	r6,r6,r5
+	bdnz	1b
+
+do_relocate_out:	
+	GETSYM(r3,start_ldr)
+	mtlr	r3		/* Easiest way to do an absolute jump */
+/* Some boards don't boot up with the I-cache enabled.  Do that
+ * now because the decompress runs much faster that way.
+ * As a side effect, we have to ensure the data cache is not enabled
+ * so we can access the serial I/O without trouble.
+ */
+	b	flush_instruction_cache
+
+	.previous
+		
+start_ldr:
+/* Clear all of BSS and set up stack for C calls */
+	lis	r3,edata@h
+	ori	r3,r3,edata@l
+	lis	r4,end@h
+	ori	r4,r4,end@l
+	subi	r3,r3,4
+	subi	r4,r4,4
+	li	r0,0
+50:	stwu	r0,4(r3)
+	cmp	cr0,r3,r4
+	bne	50b
+90:	mr	r9,r1		/* Save old stack pointer (in case it matters) */
+	lis	r1,.stack@h
+	ori	r1,r1,.stack@l
+	addi	r1,r1,4096*2
+	subi	r1,r1,256
+	li	r2,0x000F	/* Mask pointer to 16-byte boundary */
+	andc	r1,r1,r2
+
+	/*
+	 * Exec kernel loader
+	 */
+	mr	r3,r8		/* Load point */
+	mr	r4,r7		/* Program length */
+	mr	r5,r6		/* Checksum */
+	mr	r6,r11		/* Residual data */
+	bl	decompress_kernel
+
+	/*
+	 * Make sure the kernel knows we don't have things set  in
+	 * registers.  -- Tom
+	 */
+	li	r4,0
+	li	r6,0
+
+	/*
+	 * Start at the begining.
+	 */
+	li	r9,0x0000
+	mtlr	r9
+	blr
+
+	.comm	.stack,4096*2,4
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/common/util.S linux/arch/ppc/boot/common/util.S
--- linux.orig/arch/ppc/boot/common/util.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/common/util.S	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,230 @@
+/*
+ * arch/ppc/boot/common/util.S
+ *
+ * Useful bootup functions, which are more easily done in asm than C.
+ *
+ * NOTE:  Be very very careful about the registers you use here.
+ *	We don't follow any ABI calling convention among the
+ *	assembler functions that call each other, especially early
+ *	in the initialization.  Please preserve at least r3 and r4
+ *	for these early functions, as they often contain information
+ *	passed from boot roms into the C decompress function.
+ *
+ * Author: Tom Rini
+ *	   trini@mvista.com
+ * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include "ppc_asm.h"
+
+
+	.text
+
+	.globl	disable_6xx_mmu
+disable_6xx_mmu:
+	/* Establish default MSR value, exception prefix 0xFFF.
+	 * If necessary, this function must fix up the LR if we
+	 * return to a different address space once the MMU is
+	 * disabled.
+	 */
+	li	r8,MSR_IP|MSR_FP
+	mtmsr	r8
+
+	/* Clear BATs */
+	li	r8,0
+	mtspr	DBAT0U,r8
+	mtspr	DBAT0L,r8
+	mtspr	DBAT1U,r8
+	mtspr	DBAT1L,r8
+	mtspr	DBAT2U,r8
+	mtspr	DBAT2L,r8
+	mtspr	DBAT3U,r8
+	mtspr	DBAT3L,r8
+	mtspr	IBAT0U,r8
+	mtspr	IBAT0L,r8
+	mtspr	IBAT1U,r8
+	mtspr	IBAT1L,r8
+	mtspr	IBAT2U,r8
+	mtspr	IBAT2L,r8
+	mtspr	IBAT3U,r8
+	mtspr	IBAT3L,r8
+	isync
+	sync
+	sync
+
+	/* Set segment registers */
+	li	r8,16		/* load up segment register values */
+	mtctr	r8		/* for context 0 */
+	lis	r8,0x2000	/* Ku = 1, VSID = 0 */
+	li	r10,0
+3:	mtsrin	r8,r10
+	addi	r8,r8,0x111	/* increment VSID */
+	addis	r10,r10,0x1000	/* address of next segment */
+	bdnz	3b
+
+	.globl	disable_6xx_l1cache
+disable_6xx_l1cache:
+	/* Enable, invalidate and then disable the L1 icache/dcache. */
+	li	r8,0
+	ori	r8,r8,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI)
+	mfspr	r11,HID0
+	or	r11,r11,r8
+	andc	r10,r11,r8
+	isync
+	mtspr	HID0,r8
+	sync
+	isync
+	mtspr	HID0,r10
+	sync
+	isync
+	blr
+
+	.globl	_setup_L2CR
+_setup_L2CR:
+/*
+ * We should be skipping this section on CPUs where this results in an
+ * illegal instruction.  If not, please send trini@kernel.crashing.org
+ * the PVR of your CPU.
+ */
+	/* Invalidate/disable L2 cache */
+	sync
+	isync
+	mfspr	r8,L2CR
+	rlwinm	r8,r8,0,1,31
+	oris	r8,r8,0x0020
+	sync
+	isync
+	mtspr	L2CR,r8
+	sync
+	isync
+
+	/* Wait for the invalidation to complete */
+1:	mfspr	r8,L2CR
+	rlwinm.	r9,r8,0,31,31
+	bne	1b
+
+	rlwinm	r8,r8,0,11,9		/* Turn off L2I bit */
+	sync
+	isync
+	mtspr	L2CR,r8
+	sync
+	isync
+	blr
+
+
+/*
+ * Delay for a number of microseconds
+ * -- Use the BUS timer (assumes 66MHz)
+ */
+	.globl	udelay
+udelay:
+	mfspr	r4,PVR
+	srwi	r4,r4,16
+	cmpi	0,r4,1		/* 601 ? */
+	bne	.udelay_not_601
+00:	li	r0,86	/* Instructions / microsecond? */
+	mtctr	r0
+10:	addi	r0,r0,0 /* NOP */
+	bdnz	10b
+	subic.	r3,r3,1
+	bne	00b
+	blr
+
+.udelay_not_601:
+	mulli	r4,r3,1000	/* nanoseconds */
+	addi	r4,r4,59
+	li	r5,60
+	divw	r4,r4,r5	/* BUS ticks */
+1:	mftbu	r5
+	mftb	r6
+	mftbu	r7
+	cmp	0,r5,r7
+	bne	1b		/* Get [synced] base time */
+	addc	r9,r6,r4	/* Compute end time */
+	addze	r8,r5
+2:	mftbu	r5
+	cmp	0,r5,r8
+	blt	2b
+	bgt	3f
+	mftb	r6
+	cmp	0,r6,r9
+	blt	2b
+3:	blr
+
+.globl _put_MSR
+_put_MSR:
+	mtmsr	r3
+	blr
+
+	.section ".relocate_code","xa"
+/*
+ * Flush and enable instruction cache
+ * First, flush the data cache in case it was enabled and may be
+ * holding instructions for copy back.
+ */
+_GLOBAL(flush_instruction_cache)
+	mflr	r6
+	bl	flush_data_cache
+
+#ifdef CONFIG_8xx
+	lis	r3, IDC_INVALL@h
+	mtspr	IC_CST, r3
+	lis	r3, IDC_ENABLE@h
+	mtspr	IC_CST, r3
+	lis	r3, IDC_DISABLE@h
+	mtspr	DC_CST, r3
+#elif CONFIG_4xx
+	lis	r3,start@h		# r9 = &_start
+	lis	r4,_etext@ha
+	addi	r4,r4,_etext@l		# r8 = &_etext
+1:	dcbf	r0,r3			# Flush the data cache
+	icbi	r0,r3			# Invalidate the instruction cache
+	addi	r3,r3,0x10		# Increment by one cache line
+	cmplwi	cr0,r3,r4		# Are we at the end yet?
+	blt	1b			# No, keep flushing and invalidating
+#else
+	/* Enable, invalidate and then disable the L1 icache/dcache. */
+	li	r3,0
+	ori	r3,r3,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI)
+	mfspr	r4,HID0
+	or	r5,r4,r3
+	isync
+	mtspr	HID0,r5
+	sync
+	isync
+	ori	r5,r4,HID0_ICE	/* Enable cache */
+	mtspr	HID0,r5
+	sync
+	isync
+#endif
+	mtlr	r6
+	blr
+
+#define NUM_CACHE_LINES 128*8
+#define cache_flush_buffer 0x1000
+
+/*
+ * Flush data cache
+ * Do this by just reading lots of stuff into the cache.
+ */
+_GLOBAL(flush_data_cache)
+	lis	r3,cache_flush_buffer@h
+	ori	r3,r3,cache_flush_buffer@l
+	li	r4,NUM_CACHE_LINES
+	mtctr	r4
+00:	lwz	r4,0(r3)
+	addi	r3,r3,L1_CACHE_BYTES	/* Next line, please */
+	bdnz	00b
+10:	blr
+
+	.previous
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/images/Makefile linux/arch/ppc/boot/images/Makefile
--- linux.orig/arch/ppc/boot/images/Makefile	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/images/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -5,7 +5,7 @@
 include $(TOPDIR)/Rules.make
 
 vmlinux.gz: $(TOPDIR)/vmlinux
-	$(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
+	$(OBJCOPY) --strip-all -S -O binary $(TOPDIR)/vmlinux vmlinux
 	gzip -vf9 vmlinux
 
 clean:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/ld.script linux/arch/ppc/boot/ld.script
--- linux.orig/arch/ppc/boot/ld.script	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/ld.script	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,83 @@
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+    __relocate_start = .;
+    *(.relocate_code)
+    __relocate_end = .;
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.data.boot)
+    *(.sdata)
+    *(.sdata2)
+    *(.got.plt) *(.got)
+    *(.dynamic)
+    *(.rodata)
+    *(.rodata.*)
+    *(.rodata1)
+    *(.got1)
+    __image_begin = .;
+    *(.image)
+    __image_end = .;
+    . = ALIGN(4096);
+    __ramdisk_begin = .;
+    *(.ramdisk)
+    __ramdisk_end = .;
+    . = ALIGN(4096);
+    __sysmap_begin = .;
+    *(.sysmap)
+    __sysmap_end = .;
+    . = ALIGN(4096);
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/lib/zlib.c linux/arch/ppc/boot/lib/zlib.c
--- linux.orig/arch/ppc/boot/lib/zlib.c	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/lib/zlib.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort
+ * BK Id: SCCS/s.zlib.c 1.9 12/05/01 16:19:42 mporter
  */
 /*
  * This file is derived from various .h and .c files from the zlib-0.95
@@ -651,11 +651,6 @@
 /*   load local pointers */
 #define LOAD {LOADIN LOADOUT}
 
-/*
- * The IBM 150 firmware munges the data right after _etext[].  This
- * protects it. -- Cort
- */
-local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
 /* And'ing with mask[n] masks the lower n bits */
 local uInt inflate_mask[] = {
     0x0000,
@@ -933,7 +928,10 @@
       {
         r = t;
         if (r == Z_DATA_ERROR)
+	{
+          ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
           s->mode = BADB;
+	}
         LEAVE
       }
       s->sub.trees.index = 0;
@@ -969,6 +967,7 @@
           if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
               (c == 16 && i < 1))
           {
+            ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
             s->mode = BADB;
             z->msg = "invalid bit length repeat";
             r = Z_DATA_ERROR;
@@ -996,7 +995,10 @@
         if (t != Z_OK)
         {
           if (t == (uInt)Z_DATA_ERROR)
+	  {
+            ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
             s->mode = BADB;
+	  }
           r = t;
           LEAVE
         }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/Makefile linux/arch/ppc/boot/mbx/Makefile
--- linux.orig/arch/ppc/boot/mbx/Makefile	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/mbx/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,149 +0,0 @@
-# BK Id: SCCS/s.Makefile 1.9 10/15/01 10:53:29 trini
-#
-#
-# arch/ppc/mbxboot/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1994 by Linus Torvalds
-# Adapted for PowerPC by Gary Thomas
-# modified by Cort (cort@cs.nmt.edu)
-#
-.c.s:
-	$(CC) $(CFLAGS) -S -o $*.s $<
-.s.o:
-	$(AS) -o $*.o $<
-.c.o:
-	$(CC) $(CFLAGS) -c -o $*.o $<
-.S.s:
-	$(CPP) $(AFLAGS) -traditional -o $*.o $<
-.S.o:
-	$(CC) $(AFLAGS) -traditional -c -o $*.o $<
-
-TFTPIMAGE	:= /tftpboot/zImage.embedded
-
-OFFSET		:= ../utils/offset
-SIZE		:= ../utils/size
-
-LIBS		:= ../lib/zlib.a
-OBJCOPY_ARGS	:= -O elf32-powerpc
-
-ifdef CONFIG_8xx
-ZLINKFLAGS	:= -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00180000
-OBJECTS		:= head.o m8xx_tty.o
-CFLAGS		+= -DCONFIG_8xx
-endif
-
-ifdef CONFIG_8260
-ZLINKFLAGS	:= -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00400000
-OBJECTS		:= head_8260.o m8260_tty.o embed_config.o
-CFLAGS		+= -DCONFIG_8260
-endif
-
-OBJECTS		+= ../common/misc-common.o misc.o ../common/string.o
-OBJCOPY_ARGS = -O elf32-powerpc
-
-ifeq ($(CONFIG_MBX),y)
-OBJECTS		+= iic.o embed_config.o pci.o qspan_pci.o
-CFLAGS		+= -DCONFIG_MBX
-endif
-ifeq ($(CONFIG_RPXLITE),y)
-CFLAGS		+= -DCONFIG_RPXLITE
-OBJECTS		+= iic.o embed_config.o
-endif
-ifeq ($(CONFIG_RPXCLASSIC),y)
-CFLAGS		+= -DCONFIG_RPXCLASSIC
-OBJECTS		+= iic.o embed_config.o pci.o qspan_pci.o
-endif
-ifeq ($(CONFIG_BSEIP),y)
-CFLAGS		+= -DCONFIG_BSEIP
-OBJECTS		+= iic.o embed_config.o
-endif
-ifeq ($(CONFIG_FADS),y)
-CFLAGS		+= -DCONFIG_FADS
-OBJECTS		+= embed_config.o
-endif
-
-all:	zImage
-
-misc.o: misc.c
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
-		-DZIMAGE_SIZE=0 -c -o $@ $*.c
-
-zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz
-#
-# Recompile misc.o again with more 'correct' bogus offsets
-#
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=0x0008c8e3 -DINITRD_SIZE=0x0000111a \
-		-DZIMAGE_OFFSET=0x00018000 -DZIMAGE_SIZE=0x000748e2 \
-		-c -o misc.o misc.c
-	$(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
-	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=initrd=../images/ramdisk.image.gz \
-		--add-section=image=../images/vmlinux.gz \
-		$@.tmp $@
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \
-		-DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \
-		-DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \
-		-DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \
-		-c -o misc.o misc.c
-	$(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
-	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=initrd=../images/ramdisk.image.gz \
-		--add-section=image=../images/vmlinux.gz \
-		$@.tmp ../images/$@.embedded
-# Remove zvmlinux and zvmlinux.temp, we have ../images/zvmlinux.embedded
-	rm -f $@.tmp $@
-
-zImage: zvmlinux
-ifeq ($(CONFIG_RPXCLASSIC),y)
-	dd if=../images/zvmlinux.embedded of=../images/zImage.embedded bs=65536 skip=1
-else
-	ln -sf ../images/zvmlinux.embedded ../images/zImage.embedded
-endif
-
-zImage.initrd: zvmlinux.initrd
-ifeq ($(CONFIG_RPXCLASSIC),y)
-	dd if=../images/zvmlinux.initrd.embedded of=../images/zImage.initrd.embedded bs=65536 skip=1
-else
-	ln -sf ../images/zvmlinux.initrd.embedded ../images/zImage.initrd.embedded
-endif
-
-zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz
-#
-# Recompile misc.o again with more 'correct' bogus offsets
-#
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
-		-DZIMAGE_OFFSET=0x00018000 -DZIMAGE_SIZE=0x000748e2 \
-		-c -o misc.o misc.c
-#
-# build the boot loader image and then compute the offset into it
-# for the kernel image
-#
-	$(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
-	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=image=../images/vmlinux.gz \
-		$@.tmp $@
-#
-# then with the offset rebuild the bootloader so we know where the kernel is
-#
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
-		-DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \
-		-DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \
-		-c -o misc.o misc.c
-	$(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
-	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=image=../images/vmlinux.gz \
-		$@.tmp ../images/$@.embedded
-# Remove zvmlinux and zvmlinux.temp, we have ../images/zvmlinux.embedded
-	rm -f $@.tmp $@
-
-znetboot : zImage
-	cp ../images/zImage.embedded $(TFTPIMAGE)
-
-znetboot.initrd : zImage.initrd
-	cp ../images/zImage.initrd.embedded $(TFTPIMAGE)
-
-include $(TOPDIR)/Rules.make 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/embed_config.c linux/arch/ppc/boot/mbx/embed_config.c
--- linux.orig/arch/ppc/boot/mbx/embed_config.c	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/mbx/embed_config.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,593 +0,0 @@
-/*
- * BK Id: SCCS/s.embed_config.c 1.7 05/18/01 07:54:04 patch
- */
-
-/* Board specific functions for those embedded 8xx boards that do
- * not have boot monitor support for board information.
- */
-#include <linux/types.h>
-#include <linux/config.h>
-#ifdef CONFIG_8xx
-#include <asm/mpc8xx.h>
-#endif
-#ifdef CONFIG_8260
-#include <asm/mpc8260.h>
-#include <asm/immap_8260.h>
-#endif
-
-
-/* IIC functions.
- * These are just the basic master read/write operations so we can
- * examine serial EEPROM.
- */
-extern void	iic_read(uint devaddr, u_char *buf, uint offset, uint count);
-static u_char	aschex_to_byte(u_char *cp);
-
-/* Supply a default Ethernet address for those eval boards that don't
- * ship with one.  This is an address from the MBX board I have, so
- * it is unlikely you will find it on your network.
- */
-static	ushort	def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
-
-#if defined(CONFIG_MBX)
-
-/* The MBX hands us a pretty much ready to go board descriptor.  This
- * is where the idea started in the first place.
- */
-void
-embed_config(bd_t *bd)
-{
-	u_char	*mp;
-	u_char	eebuf[128];
-	int i;
-
-	/* Read the first 128 bytes of the EEPROM.  There is more,
-	 * but this is all we need.
-	 */
-	iic_read(0xa4, eebuf, 0, 128);
-
-	/* All we are looking for is the Ethernet MAC address.  The
-	 * first 8 bytes are 'MOTOROLA', so check for part of that.
-	 * If it's there, assume we have a valid MAC address.  If not,
-	 * grab our default one.
-	 */
-	if ((*(uint *)eebuf) == 0x4d4f544f)
-		mp = &eebuf[0x4c];
-	else
-		mp = (u_char *)def_enet_addr;
-
-	for (i=0; i<6; i++) {
-		bd->bi_enetaddr[i] = *mp++;
-	}
-
-	/* The boot rom passes these to us in MHz.  Linux now expects
-	 * them to be in Hz.
-	 */
-	bd->bi_intfreq *= 1000000;
-	bd->bi_busfreq *= 1000000;
-
-	/* Stuff a baud rate here as well.
-	*/
-	bd->bi_baudrate = 9600;
-}
-#endif /* CONFIG_MBX */
-
-#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPX6)
-
-/* Helper functions for Embedded Planet boards.
-*/
-static void
-rpx_eth(bd_t *bd, u_char *cp)
-{
-	int	i;
-
-	for (i=0; i<6; i++) {
-		bd->bi_enetaddr[i] = aschex_to_byte(cp);
-		cp += 2;
-	}
-}
-
-static uint
-rpx_baseten(u_char *cp)
-{
-	uint	retval;
-
-	retval = 0;
-
-	while (*cp != '\n') {
-		retval *= 10;
-		retval += (*cp) - '0';
-		cp++;
-	}
-	return(retval);
-}
-
-static void
-rpx_brate(bd_t *bd, u_char *cp)
-{
-	uint	rate;
-
-	rate = 0;
-
-	while (*cp != '\n') {
-		rate *= 10;
-		rate += (*cp) - '0';
-		cp++;
-	}
-
-	bd->bi_baudrate = rate * 100;
-}
-
-static void
-rpx_memsize(bd_t *bd, u_char *cp)
-{
-	uint	size;
-
-	size = 0;
-
-	while (*cp != '\n') {
-		size *= 10;
-		size += (*cp) - '0';
-		cp++;
-	}
-
-	bd->bi_memsize = size * 1024 * 1024;
-}
-
-static void
-rpx_cpuspeed(bd_t *bd, u_char *cp)
-{
-	uint	num, den;
-
-	num = den = 0;
-
-	while (*cp != '\n') {
-		num *= 10;
-		num += (*cp) - '0';
-		cp++;
-		if (*cp == '/') {
-			cp++;
-			den = (*cp) - '0';
-			break;
-		}
-	}
-
-	/* I don't know why the RPX just can't state the actual
-	 * CPU speed.....
-	 */
-	if (den) {
-		num /= den;
-		num *= den;
-	}
-	bd->bi_intfreq = bd->bi_busfreq = num * 1000000;
-
-	/* The 8xx can only run a maximum 50 MHz bus speed (until
-	 * Motorola changes this :-).  Greater than 50 MHz parts
-	 * run internal/2 for bus speed.
-	 */
-	if (num > 50)
-		bd->bi_busfreq /= 2;
-}
-
-/* Because I didn't find anything that would do this.......
-*/
-u_char
-aschex_to_byte(u_char *cp)
-{
-	u_char	byte, c;
-
-	c = *cp++;
-
-	if ((c >= 'A') && (c <= 'F')) {
-		c -= 'A';
-		c += 10;
-	}
-	else if ((c >= 'a') && (c <= 'f')) {
-		c -= 'a';
-		c += 10;
-	}
-	else {
-		c -= '0';
-	}
-	
-	byte = c * 16;
-
-	c = *cp;
-
-	if ((c >= 'A') && (c <= 'F')) {
-		c -= 'A';
-		c += 10;
-	}
-	else if ((c >= 'a') && (c <= 'f')) {
-		c -= 'a';
-		c += 10;
-	}
-	else {
-		c -= '0';
-	}
-	
-	byte += c;
-
-	return(byte);
-}
-#endif
-
-#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
-
-/* Read the EEPROM on the RPX-Lite board.
-*/
-void
-embed_config(bd_t *bd)
-{
-	u_char	eebuf[256], *cp;
-
-	/* Read the first 256 bytes of the EEPROM.  I think this
-	 * is really all there is, and I hope if it gets bigger the
-	 * info we want is still up front.
-	 */
-#if 1
-	iic_read(0xa8, eebuf, 0, 128);
-	iic_read(0xa8, &eebuf[128], 128, 128);
-
-	/* We look for two things, the Ethernet address and the
-	 * serial baud rate.  The records are separated by
-	 * newlines.
-	 */
-	cp = eebuf;
-	for (;;) {
-		if (*cp == 'E') {
-			cp++;
-			if (*cp == 'A') {
-				cp += 2;
-				rpx_eth(bd, cp);
-			}
-		}
-		if (*cp == 'S') {
-			cp++;
-			if (*cp == 'B') {
-				cp += 2;
-				rpx_brate(bd, cp);
-			}
-		}
-		if (*cp == 'D') {
-			cp++;
-			if (*cp == '1') {
-				cp += 2;
-				rpx_memsize(bd, cp);
-			}
-		}
-		if (*cp == 'H') {
-			cp++;
-			if (*cp == 'Z') {
-				cp += 2;
-				rpx_cpuspeed(bd, cp);
-			}
-		}
-
-		/* Scan to the end of the record.
-		*/
-		while ((*cp != '\n') && (*cp != 0xff))
-			cp++;
-
-		/* If the next character is a 0 or ff, we are done.
-		*/
-		cp++;
-		if ((*cp == 0) || (*cp == 0xff))
-			break;
-	}
-	bd->bi_memstart = 0;
-#else
-	/* For boards without initialized EEPROM.
-	*/
-	bd->bi_memstart = 0;
-	bd->bi_memsize = (8 * 1024 * 1024);
-	bd->bi_intfreq = 48000000;
-	bd->bi_busfreq = 48000000;
-	bd->bi_baudrate = 9600;
-#endif
-}
-#endif /* RPXLITE || RPXCLASSIC */
-
-#ifdef CONFIG_BSEIP
-/* Build a board information structure for the BSE ip-Engine.
- * There is more to come since we will add some environment
- * variables and a function to read them.
- */
-void
-embed_config(bd_t *bd)
-{
-	u_char	*cp;
-	int	i;
-
-	/* Baud rate and processor speed will eventually come
-	 * from the environment variables.
-	 */
-	bd->bi_baudrate = 9600;
-
-	/* Get the Ethernet station address from the Flash ROM.
-	*/
-	cp = (u_char *)0xfe003ffa;
-	for (i=0; i<6; i++) {
-		bd->bi_enetaddr[i] = *cp++;
-	}
-
-	/* The rest of this should come from the environment as well.
-	*/
-	bd->bi_memstart = 0;
-	bd->bi_memsize = (16 * 1024 * 1024);
-	bd->bi_intfreq = 48000000;
-	bd->bi_busfreq = 48000000;
-}
-#endif /* BSEIP */
-
-#ifdef CONFIG_FADS
-/* Build a board information structure for the FADS.
- */
-void
-embed_config(bd_t *bd)
-{
-	u_char	*cp;
-	int	i;
-
-	/* Just fill in some known values.
-	 */
-	bd->bi_baudrate = 9600;
-
-	/* Use default enet.
-	*/
-	cp = (u_char *)def_enet_addr;
-	for (i=0; i<6; i++) {
-		bd->bi_enetaddr[i] = *cp++;
-	}
-
-	bd->bi_memstart = 0;
-	bd->bi_memsize = (8 * 1024 * 1024);
-	bd->bi_intfreq = 40000000;
-	bd->bi_busfreq = 40000000;
-}
-#endif /* FADS */
-
-#ifdef CONFIG_8260
-/* Compute 8260 clock values if the rom doesn't provide them.
- * We can't compute the internal core frequency (I don't know how to
- * do that).
- */
-static void
-clk_8260(bd_t *bd)
-{
-	uint	scmr, vco_out, clkin;
-	uint	plldf, pllmf, busdf, brgdf, cpmdf;
-	volatile immap_t	*ip;
-
-	ip = (immap_t *)IMAP_ADDR;
-	scmr = ip->im_clkrst.car_scmr;
-
-	/* The clkin is always bus frequency.
-	*/
-	clkin = bd->bi_busfreq;
-
-	/* Collect the bits from the scmr.
-	*/
-	plldf = (scmr >> 12) & 1;
-	pllmf = scmr & 0xfff;
-	cpmdf = (scmr >> 16) & 0x0f;
-	busdf = (scmr >> 20) & 0x0f;
-
-	/* This is arithmetic from the 8260 manual.
-	*/
-	vco_out = clkin / (plldf + 1);
-	vco_out *= 2 * (pllmf + 1);
-	bd->bi_vco = vco_out;		/* Save for later */
-
-	bd->bi_cpmfreq = vco_out / 2;	/* CPM Freq, in MHz */
-
-	/* Set Baud rate divisor.  The power up default is divide by 16,
-	 * but we set it again here in case it was changed.
-	 */
-	ip->im_clkrst.car_sccr = 1;	/* DIV 16 BRG */
-	bd->bi_brgfreq = vco_out / 16;
-}
-#endif
-
-#ifdef CONFIG_EST8260
-void
-embed_config(bd_t **bdp)
-{
-	u_char	*cp;
-	int	i;
-	bd_t	*bd;
-
-	bd = *bdp;
-#if 0
-	/* This is actually provided by my boot rom.  I have it
-	 * here for those people that may load the kernel with
-	 * a JTAG/COP tool and not the rom monitor.
-	 */
-	bd->bi_baudrate = 115200;
-	bd->bi_intfreq = 200000000;
-	bd->bi_busfreq = 66666666;
-	bd->bi_cpmfreq = 66666666;
-	bd->bi_brgfreq = 33333333;
-	bd->bi_memsize = 16 * 1024 * 1024;
-#else
-	/* The boot rom passes these to us in MHz.  Linux now expects
-	 * them to be in Hz.
-	 */
-	bd->bi_intfreq *= 1000000;
-	bd->bi_busfreq *= 1000000;
-	bd->bi_cpmfreq *= 1000000;
-	bd->bi_brgfreq *= 1000000;
-#endif
-
-	cp = (u_char *)def_enet_addr;
-	for (i=0; i<6; i++) {
-		bd->bi_enetaddr[i] = *cp++;
-	}
-}
-#endif /* EST8260 */
-
-#ifdef CONFIG_SBS8260
-/* We have to fill in everything.
-*/
-static	bd_t	bdinfo;
-
-void
-embed_config(bd_t **bdp)
-{
-	u_char	*cp;
-	int	i;
-	bd_t	*bd;
-
-	/* This should provided by the boot rom.
-	 */
-	bd = &bdinfo;
-	*bdp = bd;
-	bd->bi_baudrate = 9600;
-	bd->bi_memsize = 64 * 1024 * 1024;
-
-	/* Set all of the clocks.  We have to know the speed of the
-	 * external clock.  The development board had 66 MHz.
-	 */
-	bd->bi_busfreq = 66666666;
-	clk_8260(bd);
-
-	/* I don't know how to compute this yet.
-	*/
-	bd->bi_intfreq = 133000000;
-
-
-	cp = (u_char *)def_enet_addr;
-	for (i=0; i<6; i++) {
-		bd->bi_enetaddr[i] = *cp++;
-	}
-}
-#endif /* SBS8260 */
-
-#ifdef CONFIG_RPX6
-/* The pointer we are given is for the string of key values.
- */
-static	bd_t	bdinfo;
-
-void
-embed_config(bd_t **bdp)
-{
-	u_char	*cp, *keyvals;
-	int	i;
-	bd_t	*bd;
-
-	keyvals = (u_char *)*bdp;
-
-	bd = &bdinfo;
-	*bdp = bd;
-
-	/* This is almost identical to the RPX-Lite/Classic functions
-	 * on the 8xx boards.  It would be nice to have a key lookup
-	 * function in a string, but the format of all of the fields
-	 * is slightly different.
-	 */
-	cp = keyvals;
-	for (;;) {
-		if (*cp == 'E') {
-			cp++;
-			if (*cp == 'A') {
-				cp += 2;
-				rpx_eth(bd, cp);
-			}
-		}
-		if (*cp == 'S') {
-			cp++;
-			if (*cp == 'B') {
-				cp += 2;
-				bd->bi_baudrate = rpx_baseten(cp);
-			}
-		}
-		if (*cp == 'D') {
-			cp++;
-			if (*cp == '1') {
-				cp += 2;
-				bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024;
-			}
-		}
-		if (*cp == 'X') {
-			cp++;
-			if (*cp == 'T') {
-				cp += 2;
-				bd->bi_busfreq = rpx_baseten(cp);
-			}
-		}
-		if (*cp == 'N') {
-			cp++;
-			if (*cp == 'V') {
-				cp += 2;
-				bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024;
-			}
-		}
-
-		/* Scan to the end of the record.
-		*/
-		while ((*cp != '\n') && (*cp != 0xff))
-			cp++;
-
-		/* If the next character is a 0 or ff, we are done.
-		*/
-		cp++;
-		if ((*cp == 0) || (*cp == 0xff))
-			break;
-	}
-	bd->bi_memstart = 0;
-
-	/* The memory size includes both the 60x and local bus DRAM.
-	 * I don't want to use the local bus DRAM for real memory,
-	 * so subtract it out.  It would be nice if they were separate
-	 * keys.
-	 */
-	bd->bi_memsize -= 32 * 1024 * 1024;
-
-	/* Set all of the clocks.  We have to know the speed of the
-	 * external clock.
-	 */
-	clk_8260(bd);
-
-	/* I don't know how to compute this yet.
-	*/
-	bd->bi_intfreq = 200000000;
-}
-#endif /* RPX6 for testing */
-
-#ifdef CONFIG_ADS8260
-/* We have to fill in everything.
-*/
-static	bd_t	bdinfo;
-
-void
-embed_config(bd_t **bdp)
-{
-	u_char	*cp;
-	int	i;
-	bd_t	*bd;
-
-	/* This should provided by the boot rom.
-	 */
-	bd = &bdinfo;
-	*bdp = bd;
-	bd->bi_baudrate = 9600;
-	bd->bi_memsize = 16 * 1024 * 1024;
-
-	/* Set all of the clocks.  We have to know the speed of the
-	 * external clock.  The development board had 66 MHz.
-	 */
-	bd->bi_busfreq = 66666666;
-	clk_8260(bd);
-
-	/* I don't know how to compute this yet.
-	*/
-	bd->bi_intfreq = 200000000;
-
-
-	cp = (u_char *)def_enet_addr;
-	for (i=0; i<6; i++) {
-		bd->bi_enetaddr[i] = *cp++;
-	}
-}
-#endif /* ADS8260 */
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/gzimage.c linux/arch/ppc/boot/mbx/gzimage.c
--- linux.orig/arch/ppc/boot/mbx/gzimage.c	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/mbx/gzimage.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,11 +0,0 @@
-/*
- * BK Id: SCCS/s.gzimage.c 1.6 05/18/01 15:17:06 cort
- */
-/*
- * gzimage.c
- *
- * Dummy file to allow a compressed zImage to be added
- * into a linker section, accessed by the boot coode
- */
-
-char dummy_for_gzimage;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/head.S linux/arch/ppc/boot/mbx/head.S
--- linux.orig/arch/ppc/boot/mbx/head.S	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/mbx/head.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,243 +0,0 @@
-/*
- * BK Id: SCCS/s.head.S 1.9 05/18/01 07:54:04 patch
- */
-#include <linux/config.h>
-#include "../../kernel/ppc_defs.h"
-#include "../../kernel/ppc_asm.tmpl"
-#include <asm/processor.h>
-#include <asm/cache.h>
-
-	.text
-
-/*
- * This code is loaded by the ROM loader at some arbitrary location.
- * Move it to high memory so that it can load the kernel at 0x0000.
- *
- * This is a three step process that will also work when booting from
- * a Flash PROM normally located in high memory.
- *
- * First, the entire image is loaded into some high memory address.
- * This is usually at or above 0x02000000.  This is done by a network
- * boot function supported by the board or a debugger over BDM port.
- *
- * Second, the start up function here will relocate the decompress
- * function to run at the link address of 0x01000000.
- *
- * Last, the decompression function will reloate the initrd, zImage, and
- * the residual data to locations under 8 Meg.  This is necessary because
- * the embedded kernel start up uses 8 Meg translations to access physical
- * space before the MMU is enabled.  Finally, the zImage is uncompressed
- * to location 0 and we jump to it.
- *
- * On the MBX,
- *              R1 - Stack pointer at a high memory address.
- *              R3 - Pointer to Board Information Block.
- *              R4 - Pointer to argument string.
- *              Interrupts masked, cache and MMU disabled.
- *
- *		...and the first and second functions listed above are
- *			done for us (it knows ELF images).
- *
- * For other embedded boards we build the Board Information Block.
- */
-
-	.globl	start
-start:
-	bl	start_
-start_:
-#ifndef CONFIG_MBX
-	lis	r11, local_bd_info@h
-	ori	r11, r11, local_bd_info@l
-#else
-	mr	r11, r3
-#endif
-
-	mfmsr	r3		/* Turn off interrupts  */
-	li	r4,0
-	ori	r4,r4,MSR_EE
-	andc	r3,r3,r4
-	mtmsr	r3
-
-	li	r4,0		/* Zero DER to prevent FRZ */
-	mtspr	SPRN_DER,r4
-
-/* check if we need to relocate ourselves to the link addr or were we
-   loaded there to begin with -- Cort */
-	lis	r4,start@h
-	ori	r4,r4,start@l
-	mflr	r3
-	subi	r3,r3,4		/* we get the nip, not the ip of the branch */
-	mr	r8,r3
-#if 0
-	cmp	0,r3,r4
-	beq	start_ldr	/* Branch if loaded OK */
-#endif
-
-/* 
- * no matter where we're loaded, move ourselves to -Ttext address
- * This computes the sizes we need to determine other things.
- */
-	lis	r5,end@h
-	ori	r5,r5,end@l
-	addi	r5,r5,3			/* Round up - just in case */
-	sub	r5,r5,r4		/* Compute # longwords to move */
-	srwi	r5,r5,2
-	mtctr	r5
-	mr	r7,r5
-	li	r6,0
-	subi	r3,r3,4			/* Set up for loop */
-	subi	r4,r4,4
-00:	lwzu	r5,4(r3)
-	stwu	r5,4(r4)
-	xor	r6,r6,r5
-	bdnz	00b
-
-  	lis	r3,start_ldr@h
-	ori	r3,r3,start_ldr@l
-	mtlr	r3			/* Easiest way to do an absolute jump */
-	blr
-
-start_ldr:
-/* Most 8xx boards don't boot up with the I-cache enabled.  Do that
- * now because the decompress runs much faster that way.
- */
-	lis	r3, IDC_INVALL@h
-	mtspr	IC_CST, r3
-	lis	r3, IDC_ENABLE@h
-	mtspr	IC_CST, r3
-
-/* Clear all of BSS */
-	lis	r3,edata@h
-	ori	r3,r3,edata@l
-	lis	r4,end@h
-	ori	r4,r4,end@l
-	subi	r3,r3,4
-	subi	r4,r4,4
-	li	r0,0
-50:	stwu	r0,4(r3)
-	cmp	0,r3,r4
-	bne	50b
-
-	lis	r1,.stack@h
-	ori	r1,r1,.stack@l
-	addi	r1,r1,4096*2
-	subi	r1,r1,256
-	li	r2,0x000F		/* Mask pointer to 16-byte boundary */
-	andc	r1,r1,r2
-
-	/* Perform configuration of the various boards.  This is done
-	 * by reading some configuration data from EEPROM and building
-	 * the board information structure.
-	 */
-	mr	r3, r11
-        mr      r21, r11
-	mr	r22, r8
-	mr	r23, r7
-	mr	r24, r6
-
-	bl	embed_config
-	mr	r3, r21
-	bl      serial_init		/* Init MBX serial port */
-
-	mr      r11, r21
-	mr	r8, r22
-	mr	r7, r23
-	mr	r6, r24
-
-#ifdef CONFIG_MBX
-	/* On the MBX (or anything that will TFTP load an ELF image),
-	 * we have to find the intermediate address.  The ELF loader
-	 * only moves the Linux boostrap/decompress, not the zImage.
-	 */
-#define ILAP_ADDRESS    0xfa000020
-        lis     r8, ILAP_ADDRESS@h
-        lwz     r8, ILAP_ADDRESS@l(r8)
-        addis   r8, r8, 1               /* Add 64K */
-#endif
-
-	mr	r3,r8			/* Load point */
-	mr	r4,r7			/* Program length */
-	mr	r5,r6			/* Checksum */
-	mr	r6,r11			/* Residual data */
-	bl	decompress_kernel
-
-	/* changed to use r3 (as firmware does) for kernel
-	   as ptr to residual -- Cort*/
-	lis	r6,cmd_line@h
-	ori	r6,r6,cmd_line@l
-	lwz	r6, 0(r6)
-	subi	r7,r6,1
-00:	lbzu	r2,1(r7)
-	cmpi	0,r2,0
-	bne	00b
-
-	/* r4,r5 have initrd_start, size */
-	lis	r2,initrd_start@h
-	ori	r2,r2,initrd_start@l
-	lwz	r4,0(r2)
-	lis	r2,initrd_end@h
-	ori	r2,r2,initrd_end@l
-	lwz	r5,0(r2)
-	
-	/* The world starts from the beginning.
-	*/
-	li	r9,0x0
-	mtlr	r9
-
-	/* Invalidate the instruction cache because we just copied a
-	 * bunch of kernel instructions.
-	 */
-	lis	r9, IDC_INVALL@h
-	mtspr	IC_CST, r9
-
-	blr
-hang:
-	b	hang	
-
-/*
- * Delay for a number of microseconds
- * -- Use the BUS timer (assumes 66MHz)
- */
-	.globl	udelay
-udelay:		
-	mulli	r4,r3,1000	/* nanoseconds */
-	addi	r4,r4,59
-	li	r5,60
-	divw	r4,r4,r5	/* BUS ticks */
-1:	mftbu	r5
-	mftb	r6
-	mftbu	r7
-	cmp	0,r5,r7
-	bne	1b		/* Get [synced] base time */
-	addc	r9,r6,r4	/* Compute end time */
-	addze	r8,r5
-2:	mftbu	r5
-	cmp	0,r5,r8
-	blt	2b
-	bgt	3f
-	mftb	r6
-	cmp	0,r6,r9
-	blt	2b
-3:	blr		
-
-.globl _get_MSR
-_get_MSR:		
-	mfmsr	r3
-	blr
-	
-.globl _put_MSR
-_put_MSR:		
-	mtmsr	r3
-	blr
-
-	.comm	.stack,4096*2,4
-#ifndef CONFIG_MBX
-local_bd_info:
-	.long	0
-	.long	0x01000000
-	.long	64
-	.long	64
-	.long	0
-	.long	0
-	.long	0
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/head_8260.S linux/arch/ppc/boot/mbx/head_8260.S
--- linux.orig/arch/ppc/boot/mbx/head_8260.S	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/mbx/head_8260.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,259 +0,0 @@
-/*
- * BK Id: SCCS/s.head_8260.S 1.8 05/18/01 07:54:04 patch
- */
-#include "../../kernel/ppc_defs.h"
-#include "../../kernel/ppc_asm.tmpl"
-#include <asm/processor.h>
-#include <asm/cache.h>
-
-	.text
-
-/*
- * Boot loader philosophy:
- *
- *      ROM loads us to some arbitrary location
- *      ROM loads these registers:
- *	
- *          R3 = Pointer to the board configuration data
- *          R5 = Pointer to Open Firmware data 	
- *		 	
- *      ROM jumps to start/start_
- *      Move the boot code to the link address (4 MB)
- *      Call decompress_kernel()
- *         Relocate the initrd, zimage and residual data to 4 MB
- *         Decompress the kernel to 0
- *      Jump to the kernel entry
- *            -- Cort
- */
-	.globl	start
-start:
-	bl	start_
-start_:
-	mr	r11,r3		/* Save pointer to residual/board data */
-	mr      r25,r5          /* Save OFW pointer */
-	li	r3,MSR_IP	/* Establish default MSR value */
-	mtmsr	r3
-
-/* check if we need to relocate ourselves to the link addr or were we
-   loaded there to begin with -- Cort */
-	lis	r4,start@h
-	ori	r4,r4,start@l
-	mflr	r3
-	subi	r3,r3,4		/* we get the nip, not the ip of the branch */
-	mr	r8,r3
-	cmp	0,r3,r4
-	bne	1010f
-/* compute size of whole image in words.  this should be moved to
- * start_ldr() -- Cort
- */
-	lis	r4,start@h
-	ori	r4,r4,start@l
-	lis	r5,end@h
-	ori	r5,r5,end@l
-	addi	r5,r5,3		/* round up */
-	sub	r5,r5,r4
-	srwi	r5,r5,2
-	mr	r7,r5
-	b	start_ldr
-1010:
-/* 
- * no matter where we're loaded, move ourselves to -Ttext address
- */
-relocate:
-	mflr	r3		/* Compute code bias */
-	subi	r3,r3,4
-	mr	r8,r3
-	lis	r4,start@h
-	ori	r4,r4,start@l
-	lis	r5,end@h
-	ori	r5,r5,end@l
-	addi	r5,r5,3			/* Round up - just in case */
-	sub	r5,r5,r4		/* Compute # longwords to move */
-	srwi	r5,r5,2
-	mtctr	r5
-	mr	r7,r5
-	li	r6,0
-	subi	r3,r3,4			/* Set up for loop */
-	subi	r4,r4,4
-00:	lwzu	r5,4(r3)
-	stwu	r5,4(r4)
-	xor	r6,r6,r5
-	bdnz	00b
-  	lis	r3,start_ldr@h
-	ori	r3,r3,start_ldr@l
-	mtlr	r3			/* Easiest way to do an absolute jump */
-	blr
-start_ldr:
-/* Clear all of BSS */
-	lis	r3,edata@h
-	ori	r3,r3,edata@l
-	lis	r4,end@h
-	ori	r4,r4,end@l
-	subi	r3,r3,4
-	subi	r4,r4,4
-	li	r0,0
-50:	stwu	r0,4(r3)
-	cmp	0,r3,r4
-	bne	50b
-90:	mr	r9,r1			/* Save old stack pointer (in case it matters) */
-	lis	r1,.stack@h
-	ori	r1,r1,.stack@l
-	addi	r1,r1,4096*2
-	subi	r1,r1,256
-	li	r2,0x000F		/* Mask pointer to 16-byte boundary */
-	andc	r1,r1,r2
-
-	/* Speed us up a little.
-	*/
-	bl	flush_instruction_cache
-
-/* Run loader */
-	mr	r3,r8			/* Load point */
-	mr	r4,r7			/* Program length */
-	mr	r5,r6			/* Checksum */
-	mr	r6,r11			/* Residual data */
-	mr      r7,r25                  /* OFW interfaces */
-	bl	decompress_kernel
-	
-	/* changed to use r3 (as firmware does) for kernel
-	   as ptr to residual -- Cort*/
-	lis	r6,cmd_line@h
-	ori	r6,r6,cmd_line@l
-	lwz	r6, 0(r6)
-	subi	r7,r6,1
-00:	lbzu	r2,1(r7)
-	cmpi	0,r2,0
-	bne	00b
-
-	/* r4,r5 have initrd_start, size */
-	lis	r2,initrd_start@h
-	ori	r2,r2,initrd_start@l
-	lwz	r4,0(r2)
-	lis	r2,initrd_end@h
-	ori	r2,r2,initrd_end@l
-	lwz	r5,0(r2)
-	
-	/* tell kernel we're prep */
-	/* 
-	 * get start address of kernel code which is stored as a coff
-	 * entry.  see boot/head.S -- Cort 
-	 */
-	li	r9,0x4
-	mtlr	r9
-	lis	r10,0xdeadc0de@h
-	ori	r10,r10,0xdeadc0de@l
-	li	r9,0
-	stw	r10,0(r9)
-/*
- * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
- * so disable BATs before setting this to avoid a clash
- */
-	li      r8,0
-	mtspr   DBAT0U,r8
-	mtspr   DBAT1U,r8
-	mtspr   DBAT2U,r8
-	mtspr   DBAT3U,r8
-	mtspr   IBAT0U,r8
-	mtspr   IBAT1U,r8
-	mtspr   IBAT2U,r8
-	mtspr   IBAT3U,r8
-
-	blr
-hang:
-	b	hang	
-
-/*
- * Delay for a number of microseconds
- * -- Use the BUS timer (assumes 66MHz)
- */
-	.globl	udelay
-udelay:		
-	mfspr	r4,PVR
-	srwi	r4,r4,16
-	cmpi	0,r4,1		/* 601 ? */
-	bne	.udelay_not_601
-00:	li	r0,86	/* Instructions / microsecond? */
-	mtctr	r0
-10:	addi	r0,r0,0 /* NOP */
-	bdnz	10b
-	subic.	r3,r3,1
-	bne	00b
-	blr
-
-.udelay_not_601:		
-	mulli	r4,r3,1000	/* nanoseconds */
-	addi	r4,r4,59
-	li	r5,60
-	divw	r4,r4,r5	/* BUS ticks */
-1:	mftbu	r5
-	mftb	r6
-	mftbu	r7
-	cmp	0,r5,r7
-	bne	1b		/* Get [synced] base time */
-	addc	r9,r6,r4	/* Compute end time */
-	addze	r8,r5
-2:	mftbu	r5
-	cmp	0,r5,r8
-	blt	2b
-	bgt	3f
-	mftb	r6
-	cmp	0,r6,r9
-	blt	2b
-3:	blr		
-
-.globl _get_HID0
-_get_HID0:		
-	mfspr	r3,HID0
-	blr
-
-.globl _put_HID0
-_put_HID0:		
-	mtspr	HID0,r3
-	blr
-		
-.globl _get_MSR
-_get_MSR:		
-	mfmsr	r3
-	blr
-	
-.globl _put_MSR
-_put_MSR:		
-	mtmsr	r3
-	blr
-
-/*
- * Flush instruction cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_instruction_cache)
-	mflr	r5
-	bl	flush_data_cache
-	mfspr	r3,HID0	/* Caches are controlled by this register */
-	li	r4,0
-	ori	r4,r4,(HID0_ICE|HID0_ICFI)
-	or	r3,r3,r4	/* Need to enable+invalidate to clear */
-	mtspr	HID0,r3
-	andc	r3,r3,r4
-	ori	r3,r3,HID0_ICE	/* Enable cache */
-	mtspr	HID0,r3
-	mtlr	r5
-	blr
-	
-#define NUM_CACHE_LINES 128*8
-#define CACHE_LINE_SIZE 32 
-#define cache_flush_buffer 0x1000
-
-/*
- * Flush data cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_data_cache)
-	lis	r3,cache_flush_buffer@h
-	ori	r3,r3,cache_flush_buffer@l
-	li	r4,NUM_CACHE_LINES
-	mtctr	r4
-00:	lwz	r4,0(r3)
-	addi	r3,r3,CACHE_LINE_SIZE	/* Next line, please */
-	bdnz	00b	
-10:	blr
-	.comm	.stack,4096*2,4
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/iic.c linux/arch/ppc/boot/mbx/iic.c
--- linux.orig/arch/ppc/boot/mbx/iic.c	2001-10-08 18:40:13.000000000 +0000
+++ linux/arch/ppc/boot/mbx/iic.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,218 +0,0 @@
-/*
- * BK Id: SCCS/s.iic.c 1.10 09/14/01 19:30:13 trini
- */
-
-/* Minimal support functions to read configuration from IIC EEPROMS
- * on MPC8xx boards.  Originally written for RPGC RPX-Lite.
- * Dan Malek (dmalek@jlc.net).
- */
-#include <linux/types.h>
-#include <asm/uaccess.h>
-#include <asm/mpc8xx.h>
-#include <asm/commproc.h>
-
-
-/* IIC functions.
- * These are just the basic master read/write operations so we can
- * examine serial EEPROM.
- */
-void	iic_read(uint devaddr, u_char *buf, uint offset, uint count);
-
-static	int	iic_init_done;
-
-static void
-iic_init()
-{
-	volatile iic_t *iip;
-	volatile i2c8xx_t *i2c;
-	volatile cpm8xx_t	*cp;
-	volatile immap_t	*immap;
-	uint	dpaddr;
-
-	immap = (immap_t *)IMAP_ADDR;
-	cp = (cpm8xx_t *)&(immap->im_cpm);
-
-	/* Reset the CPM.  This is necessary on the 860 processors
-	 * that may have started the SCC1 ethernet without relocating
-	 * the IIC.
-	 * This also stops the Ethernet in case we were loaded by a
-	 * BOOTP rom monitor.
-	 */
-	cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
-
-	/* Wait for it.
-	*/
-	while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));
-
-	/* Remove any microcode patches.  We will install our own
-	 * later.
-	 */
-	cp->cp_cpmcr1 = 0;
-	cp->cp_cpmcr2 = 0;
-	cp->cp_cpmcr3 = 0;
-	cp->cp_cpmcr4 = 0;
-	cp->cp_rccr = 0;
-
-	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
-	i2c = (i2c8xx_t *)&(immap->im_i2c);
-
-	/* Initialize Port B IIC pins.
-	*/
-	cp->cp_pbpar |= 0x00000030;
-	cp->cp_pbdir |= 0x00000030;
-	cp->cp_pbodr |= 0x00000030;
-
-	/* Initialize the parameter ram.
-	*/
-
-	/* Allocate space for a two transmit and one receive buffer
-	 * descriptor in the DP ram.
-	 * For now, this address seems OK, but it may have to
-	 * change with newer versions of the firmware.
-	 */
-	dpaddr = 0x0840;
-
-	/* Set up the IIC parameters in the parameter ram.
-	*/
-	iip->iic_tbase = dpaddr;
-	iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t));
-
-	iip->iic_tfcr = SMC_EB;
-	iip->iic_rfcr = SMC_EB;
-
-	/* This should really be done by the reader/writer.
-	*/
-	iip->iic_mrblr = 128;
-
-	/* Initialize Tx/Rx parameters.
-	*/
-	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
-	while (cp->cp_cpcr & CPM_CR_FLG);
-
-	/* Select an arbitrary address.  Just make sure it is unique.
-	*/
-	i2c->i2c_i2add = 0x34;
-
-	/* Make clock run maximum slow.
-	*/
-	i2c->i2c_i2brg = 7;
-
-	/* Disable interrupts.
-	*/
-	i2c->i2c_i2cmr = 0;
-	i2c->i2c_i2cer = 0xff;
-
-	/* Enable SDMA.
-	*/
-	immap->im_siu_conf.sc_sdcr = 1;
-
-	iic_init_done = 1;
-}
-
-/* Read from IIC.
- * Caller provides device address, memory buffer, and byte count.
- */
-static	u_char	iitemp[32];
-
-void
-iic_read(uint devaddr, u_char *buf, uint offset, uint count)
-{
-	volatile iic_t		*iip;
-	volatile i2c8xx_t	*i2c;
-	volatile cbd_t		*tbdf, *rbdf;
-	volatile cpm8xx_t	*cp;
-	volatile immap_t	*immap;
-	u_char			*tb;
-	uint			temp;
-
-	/* If the interface has not been initialized, do that now.
-	*/
-	if (!iic_init_done)
-		iic_init();
-
-	immap = (immap_t *)IMAP_ADDR;
-	cp = (cpm8xx_t *)&(immap->im_cpm);
-
-	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
-	i2c = (i2c8xx_t *)&(immap->im_i2c);
-
-	tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
-	rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
-
-	/* Send a "dummy write" operation.  This is a write request with
-	 * only the offset sent, followed by another start condition.
-	 * This will ensure we start reading from the first location
-	 * of the EEPROM.
-	 */
-	tb = iitemp;
-	tb = (u_char *)(((uint)tb + 15) & ~15);
-	tbdf->cbd_bufaddr = (int)tb;
-	*tb = devaddr & 0xfe;	/* Device address */
-	*(tb+1) = offset;		/* Offset */
-	tbdf->cbd_datlen = 2;		/* Length */
-	tbdf->cbd_sc =
-	      BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
-
-	i2c->i2c_i2mod = 1;	/* Enable */
-	i2c->i2c_i2cer = 0xff;
-	i2c->i2c_i2com = 0x81;	/* Start master */
-
-	/* Wait for IIC transfer.
-	*/
-#if 0
-	while ((i2c->i2c_i2cer & 3) == 0);
-
-	if (tbdf->cbd_sc & BD_SC_READY)
-		printf("IIC ra complete but tbuf ready\n");
-#else
-	temp = 10000000;
-	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
-		temp--;
-#if 0
-	/* We can't do this...there is no serial port yet!
-	*/
-	if (temp == 0) {
-		printf("Timeout reading EEPROM\n");
-		return;
-	}
-#endif
-#endif
-	
-	/* Chip errata, clear enable.
-	*/
-	i2c->i2c_i2mod = 0;
-
-	/* To read, we need an empty buffer of the proper length.
-	 * All that is used is the first byte for address, the remainder
-	 * is just used for timing (and doesn't really have to exist).
-	 */
-	tbdf->cbd_bufaddr = (int)tb;
-	*tb = devaddr | 1;	/* Device address */
-	rbdf->cbd_bufaddr = (uint)buf;		/* Desination buffer */
-	tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1;	/* Length */
-	tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
-	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
-
-	/* Chip bug, set enable here.
-	*/
-	i2c->i2c_i2mod = 1;	/* Enable */
-	i2c->i2c_i2cer = 0xff;
-	i2c->i2c_i2com = 0x81;	/* Start master */
-
-	/* Wait for IIC transfer.
-	*/
-#if 0
-	while ((i2c->i2c_i2cer & 1) == 0);
-
-	if (rbdf->cbd_sc & BD_SC_EMPTY)
-		printf("IIC read complete but rbuf empty\n");
-#else
-	temp = 10000000;
-	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
-		temp--;
-#endif
-	
-	/* Chip errata, clear enable.
-	*/
-	i2c->i2c_i2mod = 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/m8260_tty.c linux/arch/ppc/boot/mbx/m8260_tty.c
--- linux.orig/arch/ppc/boot/mbx/m8260_tty.c	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/mbx/m8260_tty.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,312 +0,0 @@
-/*
- * BK Id: SCCS/s.m8260_tty.c 1.7 05/18/01 07:54:04 patch
- */
-
-
-/* Minimal serial functions needed to send messages out the serial
- * port on SMC1.
- */
-#include <linux/types.h>
-#include <asm/mpc8260.h>
-#include <asm/cpm_8260.h>
-
-uint	no_print;
-extern char	*params[];
-extern int	nparams;
-static		u_char	cons_hold[128], *sgptr;
-static		int	cons_hold_cnt;
-
-/* If defined, enables serial console.  The value (1 through 4)
- * should designate which SCC is used, but this isn't complete.  Only
- * SCC1 is known to work at this time.
- */
-#ifdef CONFIG_SCC_CONSOLE
-#define SCC_CONSOLE 1
-#endif
-
-void
-serial_init(bd_t *bd)
-{
-	volatile smc_t		*sp;
-	volatile smc_uart_t	*up;
-	volatile scc_t		*sccp;
-	volatile scc_uart_t	*sup;
-	volatile cbd_t	*tbdf, *rbdf;
-	volatile immap_t	*ip;
-	volatile iop8260_t	*io;
-	volatile cpm8260_t	*cp;
-	uint	dpaddr, memaddr;
-
-	ip = (immap_t *)IMAP_ADDR;
-	cp = &ip->im_cpm;
-	io = &ip->im_ioport;
-
-	/* Perform a reset.
-	*/
-	cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
-
-	/* Wait for it.
-	*/
-	while (cp->cp_cpcr & CPM_CR_FLG);
-
-#ifdef CONFIG_ADS8260
-	/* Enable the RS-232 transceivers.
-	*/
-	*(volatile uint *)(BCSR_ADDR + 4) &=
-					~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2);
-#endif
-
-#ifdef SCC_CONSOLE
-	sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]);
-	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
-	sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
-	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-
-	/* Use Port D for SCC1 instead of other functions.
-	*/
-	io->iop_ppard |= 0x00000003;
-	io->iop_psord &= ~0x00000001;	/* Rx */
-	io->iop_psord |= 0x00000002;	/* Tx */
-	io->iop_pdird &= ~0x00000001;	/* Rx */
-	io->iop_pdird |= 0x00000002;	/* Tx */
-
-#else
-	sp = (smc_t*)&(ip->im_smc[0]);
-	*(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
-	up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1];
-
-	/* Disable transmitter/receiver.
-	*/
-	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-
-	/* Use Port D for SMC1 instead of other functions.
-	*/
-	io->iop_ppard |= 0x00c00000;
-	io->iop_pdird |= 0x00400000;
-	io->iop_pdird &= ~0x00800000;
-	io->iop_psord &= ~0x00c00000;
-#endif
-
-	/* Allocate space for two buffer descriptors in the DP ram.
-	 * For now, this address seems OK, but it may have to
-	 * change with newer versions of the firmware.
-	 */
-	dpaddr = 0x0800;
-
-	/* Grab a few bytes from the top of memory.
-	 */
-	memaddr = (bd->bi_memsize - 256) & ~15;
-
-	/* Set the physical address of the host memory buffers in
-	 * the buffer descriptors.
-	 */
-	rbdf = (cbd_t *)&ip->im_dprambase[dpaddr];
-	rbdf->cbd_bufaddr = memaddr;
-	rbdf->cbd_sc = 0;
-	tbdf = rbdf + 1;
-	tbdf->cbd_bufaddr = memaddr+128;
-	tbdf->cbd_sc = 0;
-
-	/* Set up the uart parameters in the parameter ram.
-	*/
-#ifdef SCC_CONSOLE
-	sup->scc_genscc.scc_rbase = dpaddr;
-	sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t);
-
-	/* Set up the uart parameters in the
-	 * parameter ram.
-	 */
-	sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB;
-	sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB;
-
-	sup->scc_genscc.scc_mrblr = 128;
-	sup->scc_maxidl = 8;
-	sup->scc_brkcr = 1;
-	sup->scc_parec = 0;
-	sup->scc_frmec = 0;
-	sup->scc_nosec = 0;
-	sup->scc_brkec = 0;
-	sup->scc_uaddr1 = 0;
-	sup->scc_uaddr2 = 0;
-	sup->scc_toseq = 0;
-	sup->scc_char1 = 0x8000;
-	sup->scc_char2 = 0x8000;
-	sup->scc_char3 = 0x8000;
-	sup->scc_char4 = 0x8000;
-	sup->scc_char5 = 0x8000;
-	sup->scc_char6 = 0x8000;
-	sup->scc_char7 = 0x8000;
-	sup->scc_char8 = 0x8000;
-	sup->scc_rccm = 0xc0ff;
-
-	/* Send the CPM an initialize command.
-	*/
-	cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0,
-			CPM_CR_INIT_TRX) | CPM_CR_FLG;
-	while (cp->cp_cpcr & CPM_CR_FLG);
-
-	/* Set UART mode, 8 bit, no parity, one stop.
-	 * Enable receive and transmit.
-	 */
-	sccp->scc_gsmrh = 0;
-	sccp->scc_gsmrl = 
-		(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
-
-	/* Disable all interrupts and clear all pending
-	 * events.
-	 */
-	sccp->scc_sccm = 0;
-	sccp->scc_scce = 0xffff;
-	sccp->scc_dsr = 0x7e7e;
-	sccp->scc_pmsr = 0x3000;
-
-	/* Wire BRG1 to SCC1.  The console driver will take care of
-	 * others.
-	 */
-	ip->im_cpmux.cmx_scr = 0;
-#else
-	up->smc_rbase = dpaddr;
-	up->smc_tbase = dpaddr+sizeof(cbd_t);
-	up->smc_rfcr = CPMFCR_EB;
-	up->smc_tfcr = CPMFCR_EB;
-	up->smc_brklen = 0;
-	up->smc_brkec = 0;
-	up->smc_brkcr = 0;
-	up->smc_mrblr = 128;
-	up->smc_maxidl = 8;
-
-	/* Set UART mode, 8 bit, no parity, one stop.
-	 * Enable receive and transmit.
-	 */
-	sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
-
-	/* Mask all interrupts and remove anything pending.
-	*/
-	sp->smc_smcm = 0;
-	sp->smc_smce = 0xff;
-
-	/* Set up the baud rate generator.
-	 */
-	ip->im_cpmux.cmx_smr = 0;
-#endif
-
-	/* The baud rate divisor needs to be coordinated with clk_8260().
-	*/
-	ip->im_brgc1 =
-		(((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) |
-								CPM_BRG_EN;
-
-	/* Make the first buffer the only buffer.
-	*/
-	tbdf->cbd_sc |= BD_SC_WRAP;
-	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
-
-	/* Initialize Tx/Rx parameters.
-	*/
-#ifdef SCC_CONSOLE
-	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-#else
-	cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
-	while (cp->cp_cpcr & CPM_CR_FLG);
-
-	/* Enable transmitter/receiver.
-	*/
-	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
-#endif
-}
-
-void
-serial_putc(void *ignored, const char c)
-{
-	volatile cbd_t		*tbdf;
-	volatile char		*buf;
-	volatile smc_uart_t	*up;
-	volatile scc_uart_t	*sup;
-	volatile immap_t	*ip;
-	extern bd_t		*board_info;
-
-	ip = (immap_t *)IMAP_ADDR;
-#ifdef SCC_CONSOLE
-	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
-	tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase];
-#else
-	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
-	tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase];
-#endif
-
-	/* Wait for last character to go.
-	*/
-	buf = (char *)tbdf->cbd_bufaddr;
-	while (tbdf->cbd_sc & BD_SC_READY);
-
-	*buf = c;
-	tbdf->cbd_datlen = 1;
-	tbdf->cbd_sc |= BD_SC_READY;
-}
-
-char
-serial_getc(void *ignored)
-{
-	char	c;
-
-	if (cons_hold_cnt <= 0) {
-		cons_hold_cnt = serial_readbuf(cons_hold);
-		sgptr = cons_hold;
-	}
-	c = *sgptr++;
-	cons_hold_cnt--;
-
-	return(c);
-}
-
-int
-serial_readbuf(u_char *cbuf)
-{
-	volatile cbd_t		*rbdf;
-	volatile char		*buf;
-	volatile smc_uart_t	*up;
-	volatile scc_uart_t	*sup;
-	volatile immap_t	*ip;
-	int	i, nc;
-
-	ip = (immap_t *)IMAP_ADDR;
-
-#ifdef SCC_CONSOLE
-	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
-	rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase];
-#else
-	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
-	rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
-#endif
-
-	/* Wait for character to show up.
-	*/
-	buf = (char *)rbdf->cbd_bufaddr;
-	while (rbdf->cbd_sc & BD_SC_EMPTY);
-	nc = rbdf->cbd_datlen;
-	for (i=0; i<nc; i++)
-		*cbuf++ = *buf++;
-	rbdf->cbd_sc |= BD_SC_EMPTY;
-
-	return(nc);
-}
-
-int
-serial_tstc(void *ignored)
-{
-	volatile cbd_t		*rbdf;
-	volatile smc_uart_t	*up;
-	volatile scc_uart_t	*sup;
-	volatile immap_t	*ip;
-
-	ip = (immap_t *)IMAP_ADDR;
-#ifdef SCC_CONSOLE
-	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
-	rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase];
-#else
-	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
-	rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
-#endif
-
-	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/m8xx_tty.c linux/arch/ppc/boot/mbx/m8xx_tty.c
--- linux.orig/arch/ppc/boot/mbx/m8xx_tty.c	2001-10-08 18:40:13.000000000 +0000
+++ linux/arch/ppc/boot/mbx/m8xx_tty.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,288 +0,0 @@
-/*
- * BK Id: SCCS/s.m8xx_tty.c 1.10 09/14/01 19:30:13 trini
- */
-
-
-/* Minimal serial functions needed to send messages out the serial
- * port on the MBX console.
- *
- * The MBX uxes SMC1 for the serial port.  We reset the port and use
- * only the first BD that EPPC-Bug set up as a character FIFO.
- *
- * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
- * use COM1 instead of SMC1 as the console port.  This kinda sucks
- * for the rest of the kernel, so here we force the use of SMC1 again.
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <asm/uaccess.h>
-#include <asm/mpc8xx.h>
-#include <asm/commproc.h>
-
-#ifdef CONFIG_MBX
-#define MBX_CSR1	((volatile u_char *)0xfa100000)
-#define CSR1_COMEN	(u_char)0x02
-#endif
-
-#ifdef TQM_SMC2_CONSOLE
-#define PROFF_CONS	PROFF_SMC2
-#define CPM_CR_CH_CONS	CPM_CR_CH_SMC2
-#define SMC_INDEX	1
-static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport);
-#else
-#define PROFF_CONS	PROFF_SMC1
-#define CPM_CR_CH_CONS	CPM_CR_CH_SMC1
-#define SMC_INDEX	0
-#endif
-
-static cpm8xx_t	*cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
-
-void
-serial_init(bd_t *bd)
-{
-	volatile smc_t		*sp;
-	volatile smc_uart_t	*up;
-	volatile cbd_t	*tbdf, *rbdf;
-	volatile cpm8xx_t	*cp;
-	uint	dpaddr, memaddr, ui;
-
-	cp = cpmp;
-	sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]);
-	up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS];
-
-	/* Disable transmitter/receiver.
-	*/
-	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-
-#ifdef CONFIG_FADS
-	/* Enable SMC1/2 transceivers.
-	*/
-	*((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2);
-#endif
-
-#ifndef CONFIG_MBX
-	{
-	/* Initialize SMCx and use it for the console port.
-	 */
-
-	/* Enable SDMA.
-	*/
-	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
-
-#ifdef TQM_SMC2_CONSOLE
-	/* Use Port A for SMC2 instead of other functions.
-	*/
-	iopp->iop_papar |=  0x00c0;
-	iopp->iop_padir &= ~0x00c0;
-	iopp->iop_paodr &= ~0x00c0;
-#else
-	/* Use Port B for SMCs instead of other functions.
-	*/
-	cp->cp_pbpar |= 0x00000cc0;
-	cp->cp_pbdir &= ~0x00000cc0;
-	cp->cp_pbodr &= ~0x00000cc0;
-#endif
-
-	/* Allocate space for two buffer descriptors in the DP ram.
-	 * For now, this address seems OK, but it may have to
-	 * change with newer versions of the firmware.
-	 */
-	dpaddr = 0x0800;
-
-	/* Grab a few bytes from the top of memory for SMC FIFOs.
-	 */
-	memaddr = (bd->bi_memsize - 32) & ~15;
-
-	/* Set the physical address of the host memory buffers in
-	 * the buffer descriptors.
-	 */
-	rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
-	rbdf->cbd_bufaddr = memaddr;
-	rbdf->cbd_sc = 0;
-	tbdf = rbdf + 1;
-	tbdf->cbd_bufaddr = memaddr+4;
-	tbdf->cbd_sc = 0;
-
-	/* Set up the uart parameters in the parameter ram.
-	*/
-	up->smc_rbase = dpaddr;
-	up->smc_tbase = dpaddr+sizeof(cbd_t);
-	up->smc_rfcr = SMC_EB;
-	up->smc_tfcr = SMC_EB;
-
-	/* Set UART mode, 8 bit, no parity, one stop.
-	 * Enable receive and transmit.
-	 */
-	sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
-
-	/* Mask all interrupts and remove anything pending.
-	*/
-	sp->smc_smcm = 0;
-	sp->smc_smce = 0xff;
-
-	/* Set up the baud rate generator.
-	 * See 8xx_io/commproc.c for details.
-	 * This wires BRG1 to SMC1 and BRG2 to SMC2;
-	 */
-	cp->cp_simode = 0x10000000;
-	ui = bd->bi_intfreq / 16 / bd->bi_baudrate;
-#ifdef TQM_SMC2_CONSOLE
-	cp->cp_brgc2 =
-#else
-	cp->cp_brgc1 =
-#endif
-		((ui - 1) < 4096)
-		? (((ui - 1) << 1) | CPM_BRG_EN)
-		: ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16);
-
-#else /* CONFIG_MBX */
-	if (*MBX_CSR1 & CSR1_COMEN) {
-		/* COM1 is enabled.  Initialize SMC1 and use it for
-		 * the console port.
-		 */
-
-		/* Enable SDMA.
-		*/
-		((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
-
-		/* Use Port B for SMCs instead of other functions.
-		*/
-		cp->cp_pbpar |= 0x00000cc0;
-		cp->cp_pbdir &= ~0x00000cc0;
-		cp->cp_pbodr &= ~0x00000cc0;
-
-		/* Allocate space for two buffer descriptors in the DP ram.
-		 * For now, this address seems OK, but it may have to
-		 * change with newer versions of the firmware.
-		 */
-		dpaddr = 0x0800;
-
-		/* Grab a few bytes from the top of memory.  EPPC-Bug isn't
-		 * running any more, so we can do this.
-		 */
-		memaddr = (bd->bi_memsize - 32) & ~15;
-
-		/* Set the physical address of the host memory buffers in
-		 * the buffer descriptors.
-		 */
-		rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
-		rbdf->cbd_bufaddr = memaddr;
-		rbdf->cbd_sc = 0;
-		tbdf = rbdf + 1;
-		tbdf->cbd_bufaddr = memaddr+4;
-		tbdf->cbd_sc = 0;
-
-		/* Set up the uart parameters in the parameter ram.
-		*/
-		up->smc_rbase = dpaddr;
-		up->smc_tbase = dpaddr+sizeof(cbd_t);
-		up->smc_rfcr = SMC_EB;
-		up->smc_tfcr = SMC_EB;
-
-		/* Set UART mode, 8 bit, no parity, one stop.
-		 * Enable receive and transmit.
-		 */
-		sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
-
-		/* Mask all interrupts and remove anything pending.
-		*/
-		sp->smc_smcm = 0;
-		sp->smc_smce = 0xff;
-
-		/* Set up the baud rate generator.
-		 * See 8xx_io/commproc.c for details.
-		 */
-		cp->cp_simode = 0x10000000;
-		cp->cp_brgc1 =
-			(((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN;
-
-		/* Enable SMC1 for console output.
-		*/
-		*MBX_CSR1 &= ~CSR1_COMEN;
-	}
-	else {
-#endif /* ndef CONFIG_MBX */
-		/* SMCx is used as console port.
-		*/
-		tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];
-		rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];
-
-		/* Issue a stop transmit, and wait for it.
-		*/
-		cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS,
-					CPM_CR_STOP_TX) | CPM_CR_FLG;
-		while (cp->cp_cpcr & CPM_CR_FLG);
-	}
-
-	/* Make the first buffer the only buffer.
-	*/
-	tbdf->cbd_sc |= BD_SC_WRAP;
-	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
-
-	/* Single character receive.
-	*/
-	up->smc_mrblr = 1;
-	up->smc_maxidl = 0;
-
-	/* Initialize Tx/Rx parameters.
-	*/
-	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG;
-	while (cp->cp_cpcr & CPM_CR_FLG);
-
-	/* Enable transmitter/receiver.
-	*/
-	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
-}
-
-void
-serial_putc(void *ignored, const char c)
-{
-	volatile cbd_t		*tbdf;
-	volatile char		*buf;
-	volatile smc_uart_t	*up;
-
-	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
-	tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
-
-	/* Wait for last character to go.
-	*/
-	buf = (char *)tbdf->cbd_bufaddr;
-	while (tbdf->cbd_sc & BD_SC_READY);
-
-	*buf = c;
-	tbdf->cbd_datlen = 1;
-	tbdf->cbd_sc |= BD_SC_READY;
-}
-
-char
-serial_getc(void *ignored)
-{
-	volatile cbd_t		*rbdf;
-	volatile char		*buf;
-	volatile smc_uart_t	*up;
-	char			c;
-
-	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
-	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
-
-	/* Wait for character to show up.
-	*/
-	buf = (char *)rbdf->cbd_bufaddr;
-	while (rbdf->cbd_sc & BD_SC_EMPTY);
-	c = *buf;
-	rbdf->cbd_sc |= BD_SC_EMPTY;
-
-	return(c);
-}
-
-int
-serial_tstc(void *ignored)
-{
-	volatile cbd_t		*rbdf;
-	volatile smc_uart_t	*up;
-
-	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
-	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
-
-	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/misc.c linux/arch/ppc/boot/mbx/misc.c
--- linux.orig/arch/ppc/boot/mbx/misc.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/mbx/misc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,248 +0,0 @@
-/*
- * BK Id: SCCS/s.misc.c 1.15 10/15/01 10:53:29 trini
- */
-/*
- * Adapted for PowerPC by Gary Thomas
- *
- * Rewritten by Cort Dougan (cort@cs.nmt.edu)
- * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include "zlib.h"
-#include <asm/residual.h>
-#include <linux/elf.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/mmu.h>
-#ifdef CONFIG_8xx
-#include <asm/mpc8xx.h>
-#endif
-#ifdef CONFIG_8260
-#include <asm/mpc8260.h>
-#endif
-
-#include "nonstdio.h"
-
-/*
- * The following references are needed to cause the linker to pull in the
- * gzimage.o and rdimage.o files.  These object files are special,
- * since they get placed into the .gzimage and .rdimage ELF sections 
- * of the zvmlinux and zvmlinux.initrd files.
- */
-extern char dummy_for_gzimage;
-extern char dummy_for_rdimage;
-
-/*
- * Please send me load/board info and such data for hardware not
- * listed here so I can keep track since things are getting tricky
- * with the different load addrs with different firmware.  This will
- * help to avoid breaking the load/boot process.
- * -- Cort
- */
-char *avail_ram;
-char *end_avail;
-
-/* Because of the limited amount of memory on embedded, it presents
- * loading problems.  The biggest is that we load this boot program
- * into a relatively low memory address, and the Linux kernel Bss often
- * extends into this space when it get loaded.  When the kernel starts
- * and zeros the BSS space, it also writes over the information we
- * save here and pass to the kernel (command line and board info).
- * On these boards, we grab some known memory holes to hold this information.
- */
-char	cmd_buf[256];
-char	*cmd_line = cmd_buf;
-
-/* We need to pass along a 'dummy' com_port. */
-unsigned long com_port = 0;
-
-/* This is the default cmdline that will be given to the user at boot time..
- * If none was specified at compile time, we'll give it one that should work.
- * -- Tom */
-#ifdef CONFIG_CMDLINE_BOOL
-char	compiled_string[] = CONFIG_CMDLINE;
-#endif
-char	ramroot_string[] = "root=/dev/ram";
-char	netroot_string[] = "root=/dev/nfs rw";
-
-bd_t hold_resid_buf;
-bd_t *hold_residual = &hold_resid_buf;
-unsigned long initrd_start = 0, initrd_end = 0;
-char *zimage_start;
-
-extern void gunzip(void *, int, unsigned char *, int *);
-
-unsigned long
-decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp)
-{
-	int timer, zimage_size = ZIMAGE_SIZE;
-	extern unsigned long start;
-	char *cp, ch;
-
-#ifdef CONFIG_8260
-	/* I don't know why I didn't do it this way on the 8xx.......
-	*/
-	embed_config(&bp);
-	serial_init(bp);
-#endif
-
-	/* Grab some space for the command line and board info.  Since
-	 * we no longer use the ELF header, but it was loaded, grab
-	 * that space.
-	 */
-#ifdef CONFIG_MBX
-	cmd_line = (char *)(load_addr - 0x10000);
-
-	/* To be like everyone else, we need one too, although this
-	 * board information is passed from the boot rom.
-	 */
-	bp->bi_baudrate = 9600;
-#else
-	cmd_line = (char *)(0x200000);
-#endif
-	hold_residual = (bd_t *)(cmd_line + sizeof(cmd_buf));
-	/* copy board data */
-	if (bp)
-		memcpy(hold_residual,bp,sizeof(bd_t));
-
-	/* Set end of memory available to us.  It is always the highest
-	 * memory address provided by the board information.
-	 */
-	end_avail = (char *)(bp->bi_memsize);
-
-	puts("loaded at:     "); puthex(load_addr);
-	puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
-	if ( (unsigned long)load_addr != (unsigned long)&start )
-	{
-		puts("relocated to:  "); puthex((unsigned long)&start);
-		puts(" ");
-		puthex((unsigned long)((unsigned long)&start + (4*num_words)));
-		puts("\n");
-	}
-
-	if ( bp )
-	{
-		puts("board data at: "); puthex((unsigned long)bp);
-		puts(" ");
-		puthex((unsigned long)((unsigned long)bp + sizeof(bd_t)));
-		puts("\n");
-		puts("relocated to:  ");
-		puthex((unsigned long)hold_residual);
-		puts(" ");
-		puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t)));
-		puts("\n");
-	}
-
-	/* we have to subtract 0x10000 here to correct for objdump including the
-	   size of the elf header which we strip -- Cort */
-	zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
-
-	if ( INITRD_OFFSET )
-		initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
-	else
-		initrd_start = 0;
-	initrd_end = INITRD_SIZE + initrd_start;
-
-	/*
-	 * setup avail_ram - this is the first part of ram usable
-	 * by the uncompress code. -- Cort
-	 */
-	avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size);
-	if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram)
-		&& (load_addr <= 0x01000000) )
-		avail_ram = (char *)(load_addr+(num_words*4));
-	if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram)
-		&& (load_addr <= 0x01000000) )
-		avail_ram = (char *)((unsigned long)&start+(num_words*4));
-	
-	/* relocate zimage */
-	puts("zimage at:     "); puthex((unsigned long)zimage_start);
-	puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
-	/*
-	 * There is no reason (yet) to relocate zImage for embedded boards.
-	 * To support boot from flash rom on 8xx embedded boards, I
-	 * assume if zimage start is over 16M we are booting from flash.
-	 * In this case, avilable ram will start just above the space we
-	 * have allocated for the command buffer and board information.
-	 */
-	if ((unsigned long)zimage_start > 0x01000000)
-		avail_ram = (char *)PAGE_ALIGN((unsigned long)hold_residual + sizeof(bd_t));
-
-	/* relocate initrd */
-	if ( initrd_start )
-	{
-		puts("initrd at:     "); puthex(initrd_start);
-		puts(" "); puthex(initrd_end); puts("\n");
-
-		/* We only have to relocate initrd if we find it is in Flash
-		 * rom.  This is because the kernel thinks it can toss the
-		 * pages into the free memory pool after it is done.  Use
-		 * the same 16M test.
-		 */
-		if ((unsigned long)initrd_start > 0x01000000) {
-			memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE),
-				(void *)initrd_start,
-				INITRD_SIZE );
-			initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE);
-			initrd_end = initrd_start + INITRD_SIZE;
-			end_avail = (char *)initrd_start;
-			puts("relocated to:  "); puthex(initrd_start);
-			puts(" "); puthex(initrd_end); puts("\n");
-		}
-		else {
-			avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end);
-		}
-	}
-
-
-	puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
-	puthex((unsigned long)end_avail); puts("\n");
-	puts("\nLinux/PPC load: ");
-	timer = 0;
-	cp = cmd_line;
-	/* This is where we try and pick the right command line for booting.
-	 * If we were given one at compile time, use it.  It Is Right.
-	 * If we weren't, see if we have a ramdisk.  If so, thats root.
-	 * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom */
-#ifdef CONFIG_CMDLINE_BOOL
-	memcpy (cmd_line, compiled_string, sizeof(compiled_string));
-#else
-	if (initrd_start)
-		memcpy (cmd_line, ramroot_string, sizeof(ramroot_string));
-	else
-		memcpy (cmd_line, netroot_string, sizeof(netroot_string));
-#endif
-	while ( *cp ) putc(*cp++);
-	while (timer++ < 5*1000) {
-		if (tstc()) {
-			while ((ch = getc()) != '\n' && ch != '\r') {
-				if (ch == '\b' || ch == '\177') {
-					if (cp != cmd_line) {
-						cp--;
-						puts("\b \b");
-					}
-				} else if (ch == '\030'		/* ^x */
-					   || ch == '\025') {	/* ^u */
-					while (cp != cmd_line) {
-						cp--;
-						puts("\b \b");
-					}
-				} else {
-					*cp++ = ch;
-					putc(ch);
-				}
-			}
-			break;  /* Exit 'timer' loop */
-		}
-		udelay(1000);  /* 1 msec */
-	}
-	*cp = 0;
-	puts("\nUncompressing Linux...");
-
-	gunzip(0, 0x400000, zimage_start, &zimage_size);
-	puts("done.\n");
-	puts("Now booting the kernel\n");
-	return (unsigned long)hold_residual;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/pci.c linux/arch/ppc/boot/mbx/pci.c
--- linux.orig/arch/ppc/boot/mbx/pci.c	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/mbx/pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,255 +0,0 @@
-/*
- * BK Id: SCCS/s.pci.c 1.6 05/18/01 15:17:06 cort
- */
-/* Stand alone funtions for QSpan Tundra support.
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <asm/mpc8xx.h>
-
-/* To map PCI devices, you first write 0xffffffff into the device
- * base address registers.  When the register is read back, the
- * number of most significant '1' bits describes the amount of address
- * space needed for mapping.  If the most significant bit is not set,
- * either the device does not use that address register, or it has
- * a fixed address that we can't change.  After the address is assigned,
- * the command register has to be written to enable the card.
- */
-typedef struct {
-	u_char	pci_bus;
-	u_char	pci_devfn;
-	ushort	pci_command;
-	uint	pci_addrs[6];
-} pci_map_t;
-
-/* We should probably dynamically allocate these structures.
-*/
-#define MAX_PCI_DEVS	32
-int	pci_dev_cnt;
-pci_map_t	pci_map[MAX_PCI_DEVS];
-
-void pci_conf_write(int bus, int device, int func, int reg, uint writeval);
-void pci_conf_read(int bus, int device, int func, int reg, void *readval);
-void probe_addresses(int bus, int devfn);
-void map_pci_addrs(void);
-
-/* This is a really stripped version of PCI bus scan.  All we are
- * looking for are devices that exist.
- */
-pci_scanner(int addr_probe)
-{
-	unsigned int devfn, l, max, class, bus_number;
-	unsigned char cmd, irq, tmp, hdr_type, is_multi;
-	int reg;
-
-	is_multi = 0;
-	bus_number = 0;
-	for (devfn = 0; devfn < 0xff; ++devfn) {
-		/* The device numbers are comprised of upper 5 bits of
-		 * device number and lower 3 bits of multi-function number.
-		 */
-		if ((devfn & 7) && !is_multi) {
-			/* Don't scan multifunction addresses if this is
-			 * not a multifunction device.
-			 */
-			continue;
-		}
-
-		/* Read the header to determine card type.
-		*/
-		qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE,
-								&hdr_type);
-
-		/* If this is a base device number, check the header to
-		 * determine if it is mulifunction.
-		 */
-		if ((devfn & 7) == 0)
-			is_multi = hdr_type & 0x80;
-
-		/* Check to see if the board is really in the slot.
-		*/
-		qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l);
-		/* some broken boards return 0 if a slot is empty: */
-		if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff ||
-							l == 0xffff0000) {
-			/* Nothing there.
-			*/
-			is_multi = 0;
-			continue;
-		}
-
-		/* If we are not performing an address probe,
-		 * just simply print out some information.
-		 */
-		if (!addr_probe) {
-			qs_pci_read_config_dword(bus_number, devfn,
-						PCI_CLASS_REVISION, &class);
-
-			class >>= 8;	    /* upper 3 bytes */
-
-#if 0
-			printf("Found (%3d:%d): vendor 0x%04x, device 0x%04x, class 0x%06x\n",
-				(devfn >> 3), (devfn & 7),
-				(l & 0xffff),  (l >> 16) & 0xffff, class);
-#else
-			puts("Found ("); puthex(devfn >> 3);
-			puts(":"); puthex(devfn & 7);
-			puts("): vendor "); puthex(l & 0xffff);
-			puts(", device "); puthex((l >> 16) & 0xffff);
-			puts(", class "); puthex(class); puts("\n");
-#endif
-		}
-		else {
-			/* If this is a "normal" device, build address list.
-			*/
-			if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL)
-				probe_addresses(bus_number, devfn);
-		}
-	}
-
-	/* Now map the boards.
-	*/
-	if (addr_probe)
-		map_pci_addrs();
-}
-
-/* Probe addresses for the specified device.  This is a destructive
- * operation because it writes the registers.
- */
-void
-probe_addresses(bus, devfn)
-{
-	int	i;
-	uint	pciaddr;
-	ushort	pcicmd;
-	pci_map_t	*pm;
-
-	if (pci_dev_cnt >= MAX_PCI_DEVS) {
-		puts("Too many PCI devices\n");
-		return;
-	}
-
-	pm = &pci_map[pci_dev_cnt++];
-
-	pm->pci_bus = bus;
-	pm->pci_devfn = devfn;
-
-	for (i=0; i<6; i++) {
-		qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1);
-		qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4),
-								&pciaddr);
-		pm->pci_addrs[i] = pciaddr;
-		qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd);
-		pm->pci_command = pcicmd;
-	}
-}
-
-/* Map the cards into the PCI space.  The PCI has separate memory
- * and I/O spaces.  In addition, some memory devices require mapping
- * below 1M.  The least significant 4 bits of the address register
- * provide information.  If this is an I/O device, only the LS bit
- * is used to indicate that, so I/O devices can be mapped to a two byte
- * boundard.  Memory addresses can be mapped to a 32 byte boundary.
- * The QSpan implementations usually have a 1Gbyte space for each
- * memory and I/O spaces.
- *
- * This isn't a terribly fancy algorithm.  I just map the spaces from
- * the top starting with the largest address space.  When finished,
- * the registers are written and the card enabled.
- *
- * While the Tundra can map a large address space on most boards, we
- * need to be careful because it may overlap other devices (like IMMR).
- */
-#define MEMORY_SPACE_SIZE	0x20000000
-#define IO_SPACE_SIZE		0x20000000
-
-void
-map_pci_addrs()
-{
-	uint	pci_mem_top, pci_mem_low;
-	uint	pci_io_top;
-	uint	addr_mask, reg_addr, space;
-	int	i, j;
-	pci_map_t *pm;
-
-	pci_mem_top = MEMORY_SPACE_SIZE;
-	pci_io_top = IO_SPACE_SIZE;
-	pci_mem_low = (1 * 1024 * 1024);	/* Below one meg addresses */
-
-	/* We can't map anything more than the maximum space, but test
-	 * for it anyway to catch devices out of range.
-	 */
-	addr_mask = 0x80000000;
-
-	do {
-		space = (~addr_mask) + 1;	/* Size of the space */
-		for (i=0; i<pci_dev_cnt; i++) {
-			pm = &pci_map[i];
-			for (j=0; j<6; j++) {
-				/* If the MS bit is not set, this has either
-				 * already been mapped, or is not used.
-				 */
-				reg_addr = pm->pci_addrs[j];
-				if ((reg_addr & 0x80000000) == 0)
-					continue;
-				if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) {
-					if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask)
-						continue;
-					if (pci_io_top < space) {
-						puts("Out of PCI I/O space\n");
-					}
-					else {
-						pci_io_top -= space;
-						pm->pci_addrs[j] = pci_io_top;
-						pm->pci_command |= PCI_COMMAND_IO;
-					}
-				}
-				else {
-					if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask)
-						continue;
-
-					/* Memory space.  Test if below 1M.
-					*/
-					if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) {
-						if (pci_mem_low < space) {
-							puts("Out of PCI 1M space\n");
-						}
-						else {
-							pci_mem_low -= space;
-							pm->pci_addrs[j] = pci_mem_low;
-						}
-					}
-					else {
-						if (pci_mem_top < space) {
-							puts("Out of PCI Mem space\n");
-						}
-						else {
-							pci_mem_top -= space;
-							pm->pci_addrs[j] = pci_mem_top;
-						}
-					}
-					pm->pci_command |= PCI_COMMAND_MEMORY;
-				}
-			}
-		}
-		addr_mask >>= 1;
-		addr_mask |= 0x80000000;
-	} while (addr_mask != 0xfffffffe);
-	
-	/* Now, run the list one more time and map everything.
-	*/
-	for (i=0; i<pci_dev_cnt; i++) {
-		pm = &pci_map[i];
-		for (j=0; j<6; j++) {
-			qs_pci_write_config_dword(pm->pci_bus, pm->pci_devfn,
-				PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]);
-		}
-
-		/* Enable memory or address mapping.
-		*/
-		qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND,
-			pm->pci_command);
-	}
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/qspan_pci.c linux/arch/ppc/boot/mbx/qspan_pci.c
--- linux.orig/arch/ppc/boot/mbx/qspan_pci.c	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/mbx/qspan_pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,271 +0,0 @@
-/*
- * BK Id: SCCS/s.qspan_pci.c 1.6 05/18/01 15:17:06 cort
- */
-/*
- * LinuxPPC arch/ppc/kernel/qspan_pci.c   Dan Malek (dmalek@jlc.net)
- *
- * QSpan Motorola bus to PCI bridge.  The config address register
- * is located 0x500 from the base of the bridge control/status registers.
- * The data register is located at 0x504.
- * This is a two step operation.  First, the address register is written,
- * then the data register is read/written as required.
- * I don't know what to do about interrupts (yet).
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <asm/mpc8xx.h>
-
-/*
- * When reading the configuration space, if something does not respond
- * the bus times out and we get a machine check interrupt.  So, the
- * good ol' exception tables come to mind to trap it and return some
- * value.
- *
- * On an error we just return a -1, since that is what the caller wants
- * returned if nothing is present.  I copied this from __get_user_asm,
- * with the only difference of returning -1 instead of EFAULT.
- * There is an associated hack in the machine check trap code.
- *
- * The QSPAN is also a big endian device, that is it makes the PCI
- * look big endian to us.  This presents a problem for the Linux PCI
- * functions, which assume little endian.  For example, we see the
- * first 32-bit word like this:
- *	------------------------
- *	| Device ID | Vendor ID |
- *	------------------------
- * If we read/write as a double word, that's OK.  But in our world,
- * when read as a word, device ID is at location 0, not location 2 as
- * the little endian PCI would believe.  We have to switch bits in
- * the PCI addresses given to us to get the data to/from the correct
- * byte lanes.
- *
- * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5.
- * It always forces the MS bit to zero.  Therefore, dev_fn values
- * greater than 128 are returned as "no device found" errors.
- *
- * The QSPAN can only perform long word (32-bit) configuration cycles.
- * The "offset" must have the two LS bits set to zero.  Read operations
- * require we read the entire word and then sort out what should be
- * returned.  Write operations other than long word require that we
- * read the long word, update the proper word or byte, then write the
- * entire long word back.
- *
- * PCI Bridge hack.  We assume (correctly) that bus 0 is the primary
- * PCI bus from the QSPAN.  If we are called with a bus number other
- * than zero, we create a Type 1 configuration access that a downstream
- * PCI bridge will interpret.
- */
-
-#define __get_pci_config(x, addr, op)		\
-	__asm__ __volatile__(				\
-		"1:	"op" %0,0(%1)\n"		\
-		"	eieio\n"			\
-		"2:\n"					\
-		".section .fixup,\"ax\"\n"		\
-		"3:	li %0,-1\n"			\
-		"	b 2b\n"				\
-		".section __ex_table,\"a\"\n"		\
-		"	.align 2\n"			\
-		"	.long 1b,3b\n"			\
-		".text"					\
-		: "=r"(x) : "r"(addr))
-
-#define QS_CONFIG_ADDR	((volatile uint *)(PCI_CSR_ADDR + 0x500))
-#define QS_CONFIG_DATA	((volatile uint *)(PCI_CSR_ADDR + 0x504))
-
-#define mk_config_addr(bus, dev, offset) \
-	(((bus)<<16) | ((dev)<<8) | (offset & 0xfc))
-
-#define mk_config_type1(bus, dev, offset) \
-	mk_config_addr(bus, dev, offset) | 1;
-
-/* Initialize the QSpan device registers after power up.
-*/
-qspan_init()
-{
-	uint	*qptr;
-
-
-
-	qptr = (uint *)PCI_CSR_ADDR;
-
-	/* PCI Configuration/status.  Upper bits written to clear
-	 * pending interrupt or status.  Lower bits enable QSPAN as
-	 * PCI master, enable memory and I/O cycles, and enable PCI
-	 * parity error checking.
-	 * IMPORTANT:  The last two bits of this word enable PCI
-	 * master cycles into the QBus.  The QSpan is broken and can't
-	 * meet the timing specs of the PQ bus for this to work.  Therefore,
-	 * if you don't have external bus arbitration, you can't use
-	 * this function.
-	 */
-#ifdef EXTERNAL_PQ_ARB
-	qptr[1] = 0xf9000147;
-#else
-	qptr[1] = 0xf9000144;
-#endif
-
-	/* PCI Misc configuration.  Set PCI latency timer resolution
-	 * of 8 cycles, set cache size to 4 x 32.
-	 */
-	qptr[3] = 0;
-
-	/* Set up PCI Target address mapping.  Enable, Posted writes,
-	 * 2Gbyte space (processor memory controller determines actual size).
-	 */
-	qptr[64] = 0x8f000080;
-
-	/* Map processor 0x80000000 to PCI 0x00000000.
-	 * Processor address bit 1 determines I/O type access (0x80000000)
-	 * or memory type access (0xc0000000).
-	 */
-	qptr[65] = 0x80000000;
-
-	/* Enable error logging and clear any pending error status.
-	*/
-	qptr[80] = 0x90000000;
-
-	qptr[512] = 0x000c0003;
-
-	/* Set up Qbus slave image.
-	*/
-	qptr[960] = 0x01000000;
-	qptr[961] = 0x000000d1;
-	qptr[964] = 0x00000000;
-	qptr[965] = 0x000000d1;
-
-}
-
-/* Functions to support PCI bios-like features to read/write configuration
- * space.  If the function fails for any reason, a -1 (0xffffffff) value
- * must be returned.
- */
-#define DEVICE_NOT_FOUND	(-1)
-#define SUCCESSFUL		0
-
-int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
-				  unsigned char offset, unsigned char *val)
-{
-	uint	temp;
-	u_char	*cp;
-
-	if ((bus > 7) || (dev_fn > 127)) {
-		*val = 0xff;
-		return DEVICE_NOT_FOUND;
-	}
-
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
-	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
-	__get_pci_config(temp, QS_CONFIG_DATA, "lwz");
-
-	offset ^= 0x03;
-	cp = ((u_char *)&temp) + (offset & 0x03);
-	*val = *cp;
-	return SUCCESSFUL;
-}
-
-int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
-				  unsigned char offset, unsigned short *val)
-{
-	uint	temp;
-	ushort	*sp;
-
-	if ((bus > 7) || (dev_fn > 127)) {
-		*val = 0xffff;
-		return DEVICE_NOT_FOUND;
-	}
-
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
-	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
-	__get_pci_config(temp, QS_CONFIG_DATA, "lwz");
-	offset ^= 0x02;
-
-	sp = ((ushort *)&temp) + ((offset >> 1) & 1);
-	*val = *sp;
-	return SUCCESSFUL;
-}
-
-int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
-				   unsigned char offset, unsigned int *val)
-{
-	if ((bus > 7) || (dev_fn > 127)) {
-		*val = 0xffffffff;
-		return DEVICE_NOT_FOUND;
-	}
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
-	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
-	__get_pci_config(*val, QS_CONFIG_DATA, "lwz");
-	return SUCCESSFUL;
-}
-
-int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
-				   unsigned char offset, unsigned char val)
-{
-	uint	temp;
-	u_char	*cp;
-
-	if ((bus > 7) || (dev_fn > 127))
-		return DEVICE_NOT_FOUND;
-
-	qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
-
-	offset ^= 0x03;
-	cp = ((u_char *)&temp) + (offset & 0x03);
-	*cp = val;
-
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
-	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
-	*QS_CONFIG_DATA = temp;
-
-	return SUCCESSFUL;
-}
-
-int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
-				   unsigned char offset, unsigned short val)
-{
-	uint	temp;
-	ushort	*sp;
-
-	if ((bus > 7) || (dev_fn > 127))
-		return DEVICE_NOT_FOUND;
-
-	qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
-
-	offset ^= 0x02;
-	sp = ((ushort *)&temp) + ((offset >> 1) & 1);
-	*sp = val;
-
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
-	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
-	*QS_CONFIG_DATA = temp;
-
-	return SUCCESSFUL;
-}
-
-int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
-				    unsigned char offset, unsigned int val)
-{
-	if ((bus > 7) || (dev_fn > 127))
-		return DEVICE_NOT_FOUND;
-
-	if (bus == 0)
-		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
-	else
-		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
-	*(unsigned int *)QS_CONFIG_DATA = val;
-
-	return SUCCESSFUL;
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/mbx/rdimage.c linux/arch/ppc/boot/mbx/rdimage.c
--- linux.orig/arch/ppc/boot/mbx/rdimage.c	2001-05-24 22:02:06.000000000 +0000
+++ linux/arch/ppc/boot/mbx/rdimage.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,11 +0,0 @@
-/*
- * BK Id: SCCS/s.rdimage.c 1.6 05/18/01 15:17:06 cort
- */
-/*
- * rdimage.c
- *
- * Dummy file to allow a compressed initrd to be added
- * into a linker section, accessed by the boot coode
- */
-
-char dummy_for_rdimage;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/pmac/Makefile linux/arch/ppc/boot/pmac/Makefile
--- linux.orig/arch/ppc/boot/pmac/Makefile	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/pmac/Makefile	2002-07-20 01:08:31.000000000 +0000
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.16 09/28/01 07:39:37 trini
+# BK Id: SCCS/s.Makefile 1.19 01/16/02 11:08:07 trini
 #
 # Makefile for making XCOFF bootable images for booting on PowerMacs
 # using Open Firmware.
@@ -9,10 +9,10 @@
 # Tom Rini		January 2001
 
 OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
-COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
-CHRP_LD_ARGS = -Ttext 0x01000000
+COFF_LD_ARGS = -T ../ld.script -e _start -Ttext 0x00500000 -Bstatic
+CHRP_LD_ARGS = -T ../ld.script -Ttext 0x01000000
 
-COMMONOBJS = start.o misc.o ../common/string.o image.o ../common/ofcommon.o
+COMMONOBJS = start.o misc.o ../common/string.o ../common/ofcommon.o
 COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o
 CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o
 LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a
@@ -20,29 +20,31 @@
 MKNOTE := ../utils/mknote
 SIZE := ../utils/size
 OFFSET := ../utils/offset
-PIGGYBACK := ../utils/piggyback
 HACKCOFF := ../utils/hack-coff
 
-ifeq ($(CONFIG_PPC64BRIDGE),y)
-MSIZE=.64
-else
-MSIZE=
+ifdef CONFIG_SMP
+END := .smp
 endif
-
-ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
-else
-TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE)
+ifdef CONFIG_PPC64BRIDGE
+END += .64
 endif
 
-../common/crt0.o:
-	$(MAKE) -C ../common crt0.o
+TFTPIMAGE=/tftpboot/zImage.pmac$(END)
+
+AFLAGS_../common/crt0.o		+= -I$(TOPDIR)/arch/$(ARCH)/kernel
 
 ../common/coffcrt0.o:
 	$(MAKE) -C ../common coffcrt0.o
 
-chrpmain.o: chrpmain.c
-	$(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c
+image.o: ../images/vmlinux.gz ../common/dummy.o
+	$(OBJCOPY) ../common/dummy.o $@ -R .comment \
+		--add-section=.image=../images/vmlinux.gz \
+		--set-section-flags=.image=contents,alloc,load,readonly,data
+ifdef CONFIG_XMON
+	$(OBJCOPY) $@ $@ \
+		--add-section=.sysmap=$(TOPDIR)/System.map \
+		--set-section-flags=.sysmap=contents,alloc,load,readonly,data
+endif
 
 znetboot: vmlinux.coff vmlinux.elf-pmac zImage
 	cp ../images/vmlinux.coff $(TFTPIMAGE)
@@ -52,30 +54,26 @@
 	cp ../images/vmlinux.initrd.coff $(TFTPIMAGE)
 	cp ../images/vmlinux.initrd.elf-pmac $(TFTPIMAGE).elf
 
-#floppy: zImage
-#	mount -t hfs /dev/fd0 /mnt
-#	cp vmlinux.coff /mnt
-#	umount /mnt
-
-miboot.image: dummy.o ../images/vmlinux.gz
+miboot.image: ../common/dummy.o ../images/vmlinux.gz
 	$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=../images/vmlinux.gz \
-		dummy.o ../images/$@
+		../common/dummy.o ../images/$@
 
 miboot.initrd.image: miboot.image ../images/ramdisk.image.gz
 	$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=../images/ramdisk.image.gz \
 		../images/miboot.image ../images/$@
 
-coffboot: $(COFFOBJS) $(LIBS) ../common/no_initrd.o ld.script ../images/vmlinux.gz
-	$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) ../common/no_initrd.o $(LIBS)
-
-coffboot.initrd: $(COFFOBJS) $(LIBS) initrd.o ld.script ../images/vmlinux.gz
-	$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS)
-
-image.o: $(PIGGYBACK) ../images/vmlinux.gz
-	$(PIGGYBACK) image < ../images/vmlinux.gz | $(AS) -o $@
-
-initrd.o: ../images/ramdisk.image.gz $(PIGGYBACK)
-	$(PIGGYBACK) initrd < ../images/ramdisk.image.gz | $(AS) -o $@
+coffboot: $(COFFOBJS) image.o $(LIBS) ../ld.script
+	$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) image.o $(LIBS)
+	$(OBJCOPY) $@ $@ -R .comment
+
+coffboot.initrd: $(COFFOBJS) image.o $(LIBS) ../ld.script \
+		../images/ramdisk.image.gz
+	$(OBJCOPY) image.o image-coff.o \
+		--add-section=.ramdisk=../images/ramdisk.image.gz \
+		--set-section-flags=.ramdisk=contents,alloc,load,readonly,data
+	$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) image-coff.o $(LIBS)
+	$(OBJCOPY) $@ $@ -R .comment
+	rm -f image-coff.o
 
 vmlinux.coff: coffboot $(HACKCOFF)
 	$(OBJCOPY) $(OBJCOPY_ARGS) coffboot ../images/$@
@@ -89,24 +87,23 @@
 	rm -f coffboot.initrd
 	ln -sf vmlinux.initrd.coff ../images/zImage.initrd.pmac
 
-vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) ../common/no_initrd.o $(MKNOTE) ../images/vmlinux.gz
-	$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) ../common/no_initrd.o $(LIBS)
+vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o
+	$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image.o
 	$(MKNOTE) > note
 	$(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \
-		--add-section=sysmap=$(TOPDIR)/System.map -R .comment
-	$(CC) $(CFLAGS) chrpmain.c -c -o chrpmain.o \
-		-DSYSMAP_OFFSET=`sh $(OFFSET) $(OBJDUMP) ../images/$@ sysmap` \
-		-DSYSMAP_SIZE=`sh $(SIZE) $(OBJDUMP) ../images/$@ sysmap`
-	$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) ../common/no_initrd.o $(LIBS)
-	$(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \
-		--add-section=sysmap=$(TOPDIR)/System.map -R .comment
+		-R .comment -R .ramdisk
 	rm -f note
 
-vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) initrd.o $(MKNOTE) ../images/vmlinux.gz
-	$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) initrd.o $(LIBS)
+vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o \
+		../images/ramdisk.image.gz
+	$(OBJCOPY) image.o image-elf.o \
+		--add-section=.ramdisk=../images/ramdisk.image.gz \
+		--set-section-flags=.ramdisk=contents,alloc,load,readonly,data
+	$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image-elf.o
 	$(MKNOTE) > note
-	$(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note -R .comment
-	rm -f note
+	$(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \
+		-R .comment
+	rm -f note image-elf.o
 
 zImage: vmlinux.coff vmlinux.elf-pmac miboot.image
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/pmac/chrpmain.c linux/arch/ppc/boot/pmac/chrpmain.c
--- linux.orig/arch/ppc/boot/pmac/chrpmain.c	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/pmac/chrpmain.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrpmain.c 1.16 07/27/01 20:24:18 trini
+ * BK Id: SCCS/s.chrpmain.c 1.18 01/11/02 10:46:07 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -10,15 +10,17 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include "nonstdio.h"
-#include "zlib.h"
 #include <asm/processor.h>
+#include <asm/page.h>
+
+/* Passed from the linker */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin[], __ramdisk_end;
+extern char _start, _end;
 
-extern char _end[];
-extern char image_data[], initrd_data[];
-extern int image_len, initrd_len;
 extern int getprop(void *, const char *, void *, int);
 extern unsigned int heap_max;
-extern void *claim(unsigned int, unsigned int, unsigned int);
+extern void *claim(unsigned int virt, unsigned int size, unsigned int align);
 extern void *finddevice(const char *);
 extern void flush_cache(void *start, unsigned int len);
 extern void gunzip(void *, int, unsigned char *, int *);
@@ -45,21 +47,23 @@
     void *dst;
     unsigned char *im;
     unsigned initrd_start, initrd_size;
-    extern char _start;
     
     printf("chrpboot starting: loaded at 0x%p\n", &_start);
-    if (initrd_len) {
-	initrd_size = initrd_len;
+
+    initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
+    if (initrd_size) {
 	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
 	a1 = initrd_start;
 	a2 = initrd_size;
 	claim(initrd_start, RAM_END - initrd_start, 0);
-	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n", initrd_start,
-	       initrd_data,initrd_size);
-	memcpy((char *)initrd_start, initrd_data, initrd_size);
-    }
-    im = image_data;
-    len = image_len;
+	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
+	       initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+	memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+    } else
+	a2 = 0xdeadbeef;
+
+    im = (char *)(&__image_begin);
+    len = (char *)(&__image_end) - (char *)(&__image_begin);
     /* claim 3MB starting at PROG_START */
     claim(PROG_START, PROG_SIZE, 0);
     dst = (void *) PROG_START;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/pmac/coffmain.c linux/arch/ppc/boot/pmac/coffmain.c
--- linux.orig/arch/ppc/boot/pmac/coffmain.c	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/pmac/coffmain.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.coffmain.c 1.14 07/27/01 20:24:18 trini
+ * BK Id: SCCS/s.coffmain.c 1.15 01/11/02 10:46:07 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -9,11 +9,17 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
+#include <asm/processor.h>
+#include <asm/page.h>
+
 #include "nonstdio.h"
 #include "zlib.h"
-#include <asm/processor.h>
 
-extern char _start[], _end[];
+/* Passed from the linker */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin[], __ramdisk_end;
+extern char _start, _end;
+
 extern char *claim(unsigned, unsigned, unsigned);
 extern char image_data[], initrd_data[];
 extern int initrd_len, image_len;
@@ -50,18 +56,21 @@
     
     printf("coffboot starting: loaded at 0x%p\n", &_start);
     setup_bats(RAM_START);
-    if (initrd_len) {
-	initrd_size = initrd_len;
+
+    initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
+    if (initrd_size) {
 	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
 	a1 = initrd_start;
 	a2 = initrd_size;
-	claim(initrd_start - RAM_START, RAM_END - initrd_start, 0);
-	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n",
-	       initrd_start, initrd_data, initrd_size);
-	memcpy((char *)initrd_start, initrd_data, initrd_size);
-    }
-    im = image_data;
-    len = image_len;
+	claim(initrd_start, RAM_END - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
+	       initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+	memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+    } else
+	a2 = 0xdeadbeef;
+
+    im = (char *)(&__image_begin);
+    len = (char *)(&__image_end) - (char *)(&__image_begin);
     /* claim 4MB starting at 0 */
     claim(0, PROG_SIZE, 0);
     dst = (void *) RAM_START;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/pmac/dummy.c linux/arch/ppc/boot/pmac/dummy.c
--- linux.orig/arch/ppc/boot/pmac/dummy.c	2001-05-24 22:02:07.000000000 +0000
+++ linux/arch/ppc/boot/pmac/dummy.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-/*
- * BK Id: SCCS/s.dummy.c 1.6 05/18/01 15:17:15 cort
- */
-int main(void)
-{
-	return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/pmac/ld.script linux/arch/ppc/boot/pmac/ld.script
--- linux.orig/arch/ppc/boot/pmac/ld.script	2001-07-02 21:40:58.000000000 +0000
+++ linux/arch/ppc/boot/pmac/ld.script	1970-01-01 00:00:00.000000000 +0000
@@ -1,69 +0,0 @@
-OUTPUT_ARCH(powerpc)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
-/* Do we need any of these for elf?
-   __DYNAMIC = 0;    */
-SECTIONS
-{
-  /* Read-only sections, merged into text segment: */
-  . = + SIZEOF_HEADERS;
-  .interp : { *(.interp) }
-  .hash          : { *(.hash)		}
-  .dynsym        : { *(.dynsym)		}
-  .dynstr        : { *(.dynstr)		}
-  .rel.text      : { *(.rel.text)		}
-  .rela.text     : { *(.rela.text) 	}
-  .rel.data      : { *(.rel.data)		}
-  .rela.data     : { *(.rela.data) 	}
-  .rel.rodata    : { *(.rel.rodata) 	}
-  .rela.rodata   : { *(.rela.rodata) 	}
-  .rel.got       : { *(.rel.got)		}
-  .rela.got      : { *(.rela.got)		}
-  .rel.ctors     : { *(.rel.ctors)	}
-  .rela.ctors    : { *(.rela.ctors)	}
-  .rel.dtors     : { *(.rel.dtors)	}
-  .rela.dtors    : { *(.rela.dtors)	}
-  .rel.bss       : { *(.rel.bss)		}
-  .rela.bss      : { *(.rela.bss)		}
-  .rel.plt       : { *(.rel.plt)		}
-  .rela.plt      : { *(.rela.plt)		}
-  .init          : { *(.init)	} =0
-  .plt : { *(.plt) }
-  .text      :
-  {
-    *(.text)
-    *(.rodata)
-    *(.rodata.*)
-    *(.rodata1)
-    *(.got1)
-  }
-  .fini      : { *(.fini)    } =0
-  .ctors     : { *(.ctors)   }
-  .dtors     : { *(.dtors)   }
-  _etext = .;
-  PROVIDE (etext = .);
-  /* Read-write section, merged into data segment: */
-  . = (. + 0x0FFF) & 0xFFFFF000;
-  .data    :
-  {
-    *(.data)
-    *(.data1)
-    *(.sdata)
-    *(.sdata2)
-    *(.got.plt) *(.got)
-    *(.dynamic)
-    CONSTRUCTORS
-  }
-  _edata  =  .;
-  PROVIDE (edata = .);
-  __bss_start = .;
-  .bss       :
-  {
-   *(.sbss) *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-  }
-  _end = . ;
-  PROVIDE (end = .);
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/prep/Makefile linux/arch/ppc/boot/prep/Makefile
--- linux.orig/arch/ppc/boot/prep/Makefile	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/prep/Makefile	2002-07-20 01:08:39.000000000 +0000
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.28 10/21/01 20:47:58 trini
+# BK Id: SCCS/s.Makefile 1.30 01/26/02 12:27:41 trini
 #
 # arch/ppc/boot/Makefile
 #
@@ -17,16 +17,15 @@
 
 USE_STANDARD_AS_RULE		:= true
 
-ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE			= /tftpboot/zImage.prep.smp
-else
 TFTPIMAGE			= /tftpboot/zImage.prep
+ifeq ($(CONFIG_SMP),y)
+TFTPIMAGE			= $(TFTPBOOT).smp
 endif
 
-ZLINKFLAGS			= -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds \
-					-Ttext 0x00800000
-obj-y				:= head.o misc.o ../common/misc-common.o \
-					../common/string.o of1275.o
+LD_ARGS				= -T ../ld.script -Ttext 0x00800000 -Bstatic
+obj-y				:= head.o ../simple/legacy.o misc.o of1275.o \
+					../common/util.o ../common/string.o \
+					../common/misc-common.o
 OBJCOPY_ARGS			= -O elf32-powerpc
 LIBS 				= ../lib/zlib.a
 
@@ -38,69 +37,38 @@
 SIZE				:= ../utils/size
 OFFSET				:= ../utils/offset
 
-all:	zImage
+# Extra include search dirs
+CFLAGS_kbd.o			+= -I$(TOPDIR)/drivers/char
+AFLAGS_head.o			+= -I$(TOPDIR)/arch/$(ARCH)/kernel
+AFLAGS_../common/util.o			+= -I$(TOPDIR)/arch/$(ARCH)/kernel
+AFLAGS_../common/relocate.o	+= -I$(TOPDIR)/arch/$(ARCH)/kernel
+AFLAGS_../simple/legacy.o	+= -I$(TOPDIR)/arch/$(ARCH)/kernel
 
-misc.o: misc.c
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
-		-DZIMAGE_SIZE=0 -c -o $@ $*.c
+all: zImage
 
-zvmlinux.initrd: $(obj-y) $(LIBS) ../images/vmlinux.gz
-#
-# Recompile misc.oagain with more 'correct' bogus offsets
-#
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=0x00138466 -DINITRD_SIZE=0x0000111a \
-		-DZIMAGE_OFFSET=0x0001b000 -DZIMAGE_SIZE=0x0011d460 \
-		-c -o misc.o misc.c
-	$(LD) $(ZLINKFLAGS) -o $@.tmp $(obj-y) $(LIBS)
-	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=initrd=../images/ramdisk.image.gz \
-		--add-section=image=../images/vmlinux.gz \
-		$@.tmp $@
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \
-		-DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \
-		-DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \
-		-DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \
-		-c -o misc.o misc.c
-	$(LD) $(ZLINKFLAGS) -o $@.tmp $(obj-y) $(LIBS)
+zImage: $(obj-y) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o \
+		$(MKPREP)
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=initrd=../images/ramdisk.image.gz \
-		--add-section=image=../images/vmlinux.gz \
-		$@.tmp $@
-	rm -f $@.tmp
-
-zImage: zvmlinux $(MKPREP)
-	$(MKPREP) -pbp zvmlinux ../images/$@.prep
-	rm -f zvmlinux
-
-zImage.initrd: zvmlinux.initrd $(MKPREP)
-	$(MKPREP) -pbp zvmlinux.initrd ../images/$@.prep
-	rm -f zvmlinux.initrd
+		--add-section=.image=../images/vmlinux.gz \
+		--set-section-flags=.image=contents,alloc,load,readonly,data \
+		../common/dummy.o image.o
+	$(LD) $(LD_ARGS) -o $@ $(obj-y) image.o $(LIBS)
+	$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr
+	$(MKPREP) -pbp $@ ../images/$@.prep
+	rm -f $@
 
-zvmlinux: $(obj-y) $(LIBS) ../images/vmlinux.gz
-#
-# Recompile misc.oagain with more 'correct' bogus offsets
-#
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
-		-DZIMAGE_OFFSET=0x0001b000 -DZIMAGE_SIZE=0x0011d460 \
-		-c -o misc.o misc.c
-#
-# build the boot loader image and then compute the offset into it
-# for the kernel image
-#
-	$(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(obj-y) $(LIBS)
-	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=image=../images/vmlinux.gz zvmlinux.tmp $@
-#
-# then with the offset rebuild the bootloader so we know where the kernel is
-#
-	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
-		-DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) zvmlinux image` \
-		-DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) zvmlinux image` \
-		-c -o misc.o misc.c
-	$(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(obj-y) $(LIBS)
+zImage.initrd: $(obj-y) $(LIBS) ../ld.script ../images/vmlinux.gz $(MKPREP) \
+		../common/dummy.o
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=image=../images/vmlinux.gz $@.tmp $@
-	rm -f $@.tmp
+		--add-section=.ramdisk=../images/ramdisk.image.gz \
+		--set-section-flags=.ramdisk=contents,alloc,load,readonly,data \
+		--add-section=.image=../images/vmlinux.gz \
+		--set-section-flags=.image=contents,alloc,load,readonly,data \
+		../common/dummy.o image.o
+	$(LD) $(LD_ARGS) -o $@ $(obj-y) image.o $(LIBS)
+	$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr
+	$(MKPREP) -pbp $@ ../images/$@.prep
+	rm -f $@
 
 floppy: zImage
 	dd if=../images/zImage.prep of=/dev/fd0H1440 bs=64b
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/prep/head.S linux/arch/ppc/boot/prep/head.S
--- linux.orig/arch/ppc/boot/prep/head.S	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/prep/head.S	2002-07-20 01:08:26.000000000 +0000
@@ -1,8 +1,8 @@
 /*
- * BK Id: SCCS/s.head.S 1.11 07/31/01 16:36:06 trini
+ * BK Id: SCCS/s.head.S 1.13 01/11/02 10:46:07 trini
  */
-#include "../../kernel/ppc_defs.h"
-#include "../../kernel/ppc_asm.tmpl"
+
+#include "ppc_asm.h"
 #include <asm/processor.h>
 #include <asm/cache.h>
 
@@ -22,34 +22,49 @@
 start:
 	bl	start_
 start_:
+
+        /* Enable, invalidate, Disable L1 icache/dcache */
+	li	r8, 0
+	ori	r8, r8, (HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI)
+	mfspr	r11,HID0
+	or	r11,r11,r8
+	andc	r10,r11,r8
+	isync
+	mtspr	HID0,r8
+	sync
+	isync
+	mtspr	HID0,r10
+	sync
+	isync
+
 	mr	r11,r3		/* Save pointer to residual/board data */
-	mr      r25,r5          /* Save OFW pointer */
-	li	r3,MSR_IP	/* Establish default MSR value */
+	mr      r25,r5		/* Save OFW pointer */
+
+	/* Save the original MSR value */
+	mfmsr	r26
+
+	/* Establish default MSR value */
+	li	r3,MSR_IP|MSR_FP
 	mtmsr	r3
 
-/* check if we need to relocate ourselves to the link addr or were we
-   loaded there to begin with -- Cort */
-	lis	r4,start@h
-	ori	r4,r4,start@l
-	mflr	r3
-	subi	r3,r3,4		/* we get the nip, not the ip of the branch */
-	mr	r8,r3
-	cmp	0,r3,r4
-	bne	1010f
-/* compute size of whole image in words.  this should be moved to
- * start_ldr() -- Cort
- */
+	/* compute the size of the whole image in words. */
 	lis	r4,start@h
 	ori	r4,r4,start@l
 	lis	r5,end@h
 	ori	r5,r5,end@l
 	addi	r5,r5,3		/* round up */
-	sub	r5,r5,r4
+	sub	r5,r5,r4	/* end - start */
 	srwi	r5,r5,2
-	mr	r7,r5
-	b	start_ldr
-1010:
-/* 
+	mr	r7,r5		/* Save for later use. */
+
+	/* check if we need to relocate ourselves to the link addr or were
+	 * we loaded there to begin with -- Cort */
+	mflr	r3
+	subi	r3,r3,4		/* we get the nip, not the ip of the branch */
+	mr	r8,r3
+	cmp	0,r3,r4
+	beq	start_ldr	/* If 0, we don't need to relocate */
+/*
  * no matter where we're loaded, move ourselves to -Ttext address
  */
 relocate:
@@ -58,15 +73,10 @@
 	mr	r8,r3
 	lis	r4,start@h
 	ori	r4,r4,start@l
-	lis	r5,end@h
-	ori	r5,r5,end@l
-	addi	r5,r5,3			/* Round up - just in case */
-	sub	r5,r5,r4		/* Compute # longwords to move */
-	srwi	r5,r5,2
-	mtctr	r5
-	mr	r7,r5
+	mr	r5,r7		/* Get the # of longwords again */
+	mtctr	r5		/* Setup for loop */
 	li	r6,0
-	subi	r3,r3,4			/* Set up for loop */
+	subi	r3,r3,4
 	subi	r4,r4,4
 00:	lwzu	r5,4(r3)
 	stwu	r5,4(r4)
@@ -74,9 +84,17 @@
 	bdnz	00b
   	lis	r3,start_ldr@h
 	ori	r3,r3,start_ldr@l
-	mtlr	r3			/* Easiest way to do an absolute jump */
+	mtlr	r3		/* Easiest way to do an absolute jump */
 	blr
+
 start_ldr:
+/* Some boards don't boot up with the I-cache enabled.  Do that
+ * now because the decompress runs much faster that way.
+ * As a side effect, we have to ensure the data cache is not enabled
+ * so we can access the serial I/O without trouble.
+ */
+	bl	flush_instruction_cache
+
 /* Clear all of BSS */
 	lis	r3,edata@h
 	ori	r3,r3,edata@l
@@ -95,11 +113,12 @@
 	subi	r1,r1,256
 	li	r2,0x000F		/* Mask pointer to 16-byte boundary */
 	andc	r1,r1,r2
-/* Setup ISA_io */
-	lis	r3,ISA_io@h
-	ori	r3,r3,ISA_io@l
-	lis	r4,0x8000
-	stw	r4,0(r3)
+
+	/* Store the original MSR into 'orig_MSR' */
+	lis	r3,orig_MSR@h
+	ori	r3,r3,orig_MSR@l
+	stw	r26,0(r3)
+
 /* Run loader */
 	mr	r3,r8			/* Load point */
 	mr	r4,r7			/* Program length */
@@ -107,147 +126,61 @@
 	mr	r6,r11			/* Residual data */
 	mr      r7,r25                  /* OFW interfaces */
 	bl	decompress_kernel
-	
-	/* changed to use r3 (as firmware does) for kernel
-	   as ptr to residual -- Cort*/
-	lis	r6,cmd_line@h
-	ori	r6,r6,cmd_line@l
-	lwz	r6, 0(r6)
-	subi	r7,r6,1
-00:	lbzu	r2,1(r7)
-	cmpi	0,r2,0
-	bne	00b
-
-	/* r4,r5 have initrd_start, size */
-	lis	r2,initrd_start@h
-	ori	r2,r2,initrd_start@l
-	lwz	r4,0(r2)
-	lis	r2,initrd_end@h
-	ori	r2,r2,initrd_end@l
-	lwz	r5,0(r2)
-
-
-	/* tell kernel we're prep */
-	/* 
-	 * get start address of kernel code which is stored as a coff
-	 * entry.  see boot/head.S -- Cort 
+
+	/*
+	 * We have to do this after decompress_kernel, just to make
+	 * sure we don't wipe out things mapped in BATs which we need.
+	 * -- Tom
 	 */
-	li	r9,0x4
+	li      r6,0
+	/* Test for a 601 */
+	mfspr	r9,PVR
+	srwi	r9,r9,16
+	cmpi	0,r9,1          /* 601 ? */
+	beq	.clearbats_601
+
+	/* Clear BATS */
+	mtspr   DBAT0U,r6
+	mtspr	DBAT0L,r6
+	mtspr   DBAT1U,r6
+	mtspr	DBAT1L,r6
+	mtspr   DBAT2U,r6
+	mtspr	DBAT2L,r6
+	mtspr   DBAT3U,r6
+	mtspr	DBAT3L,r6
+.clearbats_601:
+	mtspr   IBAT0U,r6
+	mtspr	IBAT0L,r6
+	mtspr   IBAT1U,r6
+	mtspr	IBAT1L,r6
+	mtspr	IBAT2U,r6
+	mtspr   IBAT2L,r6
+	mtspr   IBAT3U,r6
+	mtspr	IBAT3L,r6
+	isync
+	sync
+	sync
+
+	/* Set segment registers */
+	li	r6,16		/* load up segment register values */
+	mtctr	r6		/* for context 0 */
+	lis	r6,0x2000	/* Ku = 1, VSID = 0 */
+	li	r10,0
+3:	mtsrin	r6,r10
+	addi	r6,r6,0x111	/* increment VSID */
+	addis	r10,r10,0x1000	/* address of next segment */
+	bdnz	3b
+
+	/* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD,
+	 * and tell the kernel to start on the 4th instruction since we
+	 * overwrite the first 3 sometimes (which are 'nop').
+	 */
+	li	r9,0xc
 	mtlr	r9
 	lis	r10,0xdeadc0de@h
 	ori	r10,r10,0xdeadc0de@l
 	li	r9,0
 	stw	r10,0(r9)
-/*
- * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
- * so disable BATs before setting this to avoid a clash
- */
-	li      r8,0
-	mtspr   DBAT0U,r8
-	mtspr   DBAT1U,r8
-	mtspr   DBAT2U,r8
-	mtspr   DBAT3U,r8
-	mtspr   IBAT0U,r8
-	mtspr   IBAT1U,r8
-	mtspr   IBAT2U,r8
-	mtspr   IBAT3U,r8
-
-	blr
-hang:
-	b	hang	
-
-/*
- * Delay for a number of microseconds
- * -- Use the BUS timer (assumes 66MHz)
- */
-	.globl	udelay
-udelay:		
-	mfspr	r4,PVR
-	srwi	r4,r4,16
-	cmpi	0,r4,1		/* 601 ? */
-	bne	.udelay_not_601
-00:	li	r0,86	/* Instructions / microsecond? */
-	mtctr	r0
-10:	addi	r0,r0,0 /* NOP */
-	bdnz	10b
-	subic.	r3,r3,1
-	bne	00b
-	blr
-
-.udelay_not_601:		
-	mulli	r4,r3,1000	/* nanoseconds */
-	addi	r4,r4,59
-	li	r5,60
-	divw	r4,r4,r5	/* BUS ticks */
-1:	mftbu	r5
-	mftb	r6
-	mftbu	r7
-	cmp	0,r5,r7
-	bne	1b		/* Get [synced] base time */
-	addc	r9,r6,r4	/* Compute end time */
-	addze	r8,r5
-2:	mftbu	r5
-	cmp	0,r5,r8
-	blt	2b
-	bgt	3f
-	mftb	r6
-	cmp	0,r6,r9
-	blt	2b
-3:	blr		
-
-.globl _get_HID0
-_get_HID0:		
-	mfspr	r3,HID0
-	blr
-
-.globl _put_HID0
-_put_HID0:		
-	mtspr	HID0,r3
-	blr
-		
-.globl _get_MSR
-_get_MSR:		
-	mfmsr	r3
-	blr
-	
-.globl _put_MSR
-_put_MSR:		
-	mtmsr	r3
 	blr
 
-/*
- * Flush instruction cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_instruction_cache)
-	mflr	r5
-	bl	flush_data_cache
-	mfspr	r3,HID0	/* Caches are controlled by this register */
-	li	r4,0
-	ori	r4,r4,(HID0_ICE|HID0_ICFI)
-	or	r3,r3,r4	/* Need to enable+invalidate to clear */
-	mtspr	HID0,r3
-	andc	r3,r3,r4
-	ori	r3,r3,HID0_ICE	/* Enable cache */
-	mtspr	HID0,r3
-	mtlr	r5
-	blr
-	
-#define NUM_CACHE_LINES 128*8
-#define CACHE_LINE_SIZE 32 
-#define cache_flush_buffer 0x1000
-
-/*
- * Flush data cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_data_cache)
-	lis	r3,cache_flush_buffer@h
-	ori	r3,r3,cache_flush_buffer@l
-	li	r4,NUM_CACHE_LINES
-	mtctr	r4
-00:	lwz	r4,0(r3)
-	addi	r3,r3,CACHE_LINE_SIZE	/* Next line, please */
-	bdnz	00b	
-10:	blr
 	.comm	.stack,4096*2,4
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/prep/kbd.c linux/arch/ppc/boot/prep/kbd.c
--- linux.orig/arch/ppc/boot/prep/kbd.c	2001-05-24 22:02:07.000000000 +0000
+++ linux/arch/ppc/boot/prep/kbd.c	2002-07-20 01:08:24.000000000 +0000
@@ -1,9 +1,10 @@
 /*
- * BK Id: SCCS/s.kbd.c 1.7 05/18/01 06:20:29 patch
+ * BK Id: SCCS/s.kbd.c 1.9 01/11/02 10:46:07 trini
  */
+
 #include <linux/keyboard.h>
 
-#include <../drivers/char/defkeymap.c>	/* yeah I know it's bad -- Cort */
+#include "defkeymap.c"	/* yeah I know it's bad -- Cort */
 
 
 unsigned char shfts, ctls, alts, caps;
@@ -130,20 +131,29 @@
 	goto loop;
 }
 
-static void kbdreset(void)
+static int __kbdreset(void)
 {
 	unsigned char c;
-	int i;
+	int i, t;
 
 	/* flush input queue */
+	t = 2000;
 	while ((inb(KBSTATP) & KBINRDY))
 	{
 		(void)inb(KBDATAP);
+		if (--t == 0)
+			return 1;
 	}
 	/* Send self-test */
-	while (inb(KBSTATP) & KBOUTRDY) ;
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0)
+			return 2;
 	outb(KBSTATP,0xAA);
-	while ((inb(KBSTATP) & KBINRDY) == 0) ;	/* wait input ready */
+	t = 200000;
+	while ((inb(KBSTATP) & KBINRDY) == 0)	/* wait input ready */
+		if (--t == 0)
+			return 3;
 	if ((c = inb(KBDATAP)) != 0x55)
 	{
 		puts("Keyboard self test failed - result:");
@@ -151,15 +161,23 @@
 		puts("\n");
 	}
 	/* Enable interrupts and keyboard controller */
-	while (inb(KBSTATP) & KBOUTRDY) ;
-	outb(KBSTATP,0x60);	
-	while (inb(KBSTATP) & KBOUTRDY) ;
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0) return 4;
+	outb(KBSTATP,0x60);
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0) return 5;
 	outb(KBDATAP,0x45);
 	for (i = 0;  i < 10000;  i++) udelay(1);
-	
-	while (inb(KBSTATP) & KBOUTRDY) ;
+
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0) return 6;
 	outb(KBSTATP,0x20);
-	while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */
+	t = 200000;
+	while ((inb(KBSTATP) & KBINRDY) == 0)	/* wait input ready */
+		if (--t == 0) return 7;
 	if (! (inb(KBDATAP) & 0x40)) {
 		/*
 		 * Quote from PS/2 System Reference Manual:
@@ -169,15 +187,31 @@
 		 * output-buffer-full bit in the Controller Status
 		 * register are set 0." (KBINRDY and KBOUTRDY)
 		 */
-		
-		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ;
+		t = 200000;
+		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
+			if (--t == 0) return 8;
 		outb(KBDATAP,0xF0);
-		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ;
+		t = 200000;
+		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
+			if (--t == 0) return 9;
 		outb(KBDATAP,0x01);
 	}
-	
-	while (inb(KBSTATP) & KBOUTRDY) ;
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0) return 10;
 	outb(KBSTATP,0xAE);
+	return 0;
+}
+
+static void kbdreset(void)
+{
+	int ret = __kbdreset();
+
+	if (ret) {
+		puts("__kbdreset failed: ");
+		puthex(ret);
+		puts("\n");
+	}
 }
 
 /* We have to actually read the keyboard when CRT_tstc is called,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/prep/misc.c linux/arch/ppc/boot/prep/misc.c
--- linux.orig/arch/ppc/boot/prep/misc.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/prep/misc.c	2002-07-20 01:08:26.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.misc.c 1.22 10/15/01 17:46:21 trini
+ * BK Id: SCCS/s.misc.c 1.25 01/26/02 12:27:41 trini
  *
  * arch/ppc/boot/prep/misc.c
  *
@@ -32,12 +32,16 @@
  */
 char *avail_ram;
 char *end_avail;
+
+/* The linker tells us where the image is. */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin, __ramdisk_end;
 extern char _end[];
 
 #ifdef CONFIG_CMDLINE
 #define CMDLINE CONFIG_CMDLINE
 #else
-#define CMDLINE "";
+#define CMDLINE ""
 #endif
 char cmd_preset[] = CMDLINE;
 char cmd_buf[256];
@@ -46,7 +50,8 @@
 int keyb_present = 1;	/* keyboard controller is present by default */
 RESIDUAL hold_resid_buf;
 RESIDUAL *hold_residual = &hold_resid_buf;
-unsigned long initrd_start = 0, initrd_end = 0;
+unsigned long initrd_size = 0;
+unsigned long orig_MSR;
 
 char *zimage_start;
 int zimage_size;
@@ -63,16 +68,14 @@
 extern int CRT_tstc(void);
 extern void of_init(void *handler);
 extern int of_finddevice(const char *device_specifier, int *phandle);
-extern int of_getprop(int phandle, const char *name, void *buf, int buflen, 
+extern int of_getprop(int phandle, const char *name, void *buf, int buflen,
 		int *size);
 extern int vga_init(unsigned char *ISA_mem);
 extern void gunzip(void *, int, unsigned char *, int *);
 
-extern void _put_HID0(unsigned int val);
 extern void _put_MSR(unsigned int val);
-extern unsigned int _get_HID0(void);
-extern unsigned int _get_MSR(void);
-extern unsigned long serial_init(int chan);
+extern unsigned long serial_init(int chan, void *ignored);
+extern void serial_fixups(void);
 
 void
 writel(unsigned int val, unsigned int address)
@@ -82,7 +85,7 @@
 	*(unsigned int *)address = cpu_to_le32(val);
 }
 
-unsigned int 
+unsigned int
 readl(unsigned int address)
 {
 	/* Ensure I/O operations complete */
@@ -90,8 +93,8 @@
 	return le32_to_cpu(*(unsigned int *)address);
 }
 
-#define PCI_CFG_ADDR(dev,off)	((0x80<<24) | (dev<<8) | (off&0xfc)) 
-#define PCI_CFG_DATA(off)	(0x80000cfc+(off&3))  
+#define PCI_CFG_ADDR(dev,off)	((0x80<<24) | (dev<<8) | (off&0xfc))
+#define PCI_CFG_DATA(off)	(0x80000cfc+(off&3))
 
 static void
 pci_read_config_32(unsigned char devfn,
@@ -115,38 +118,14 @@
 }
 #endif /* CONFIG_VGA_CONSOLE */
 
-/*
- * This routine is used to control the second processor on the 
- * Motorola dual processor platforms.  
- */
-void
-park_cpus(void)
-{
-	volatile void (*go)(RESIDUAL *, int, int, char *, int);
-	unsigned int i;
-	volatile unsigned long *smp_iar = &(hold_residual->VitalProductData.SmpIar);
-
-	/* Wait for indication to continue.  If the kernel
-	   was not compiled with SMP support then the second 
-	   processor will spin forever here makeing the kernel
-	   multiprocessor safe. */
-	while (*smp_iar == 0) {
-                for (i=0; i < 512; i++);
-	}
-
-	(unsigned long)go = hold_residual->VitalProductData.SmpIar;
-	go(hold_residual, 0, 0, cmd_line, sizeof(cmd_preset));
-}
-
 unsigned long
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
 		  RESIDUAL *residual, void *OFW_interface)
 {
-	int timer;
+	int timer = 0;
 	extern unsigned long start;
 	char *cp, ch;
 	unsigned long TotalMemory;
-	unsigned long orig_MSR;
 	int dev_handle;
 	int mem_info[2];
 	int res, size;
@@ -154,26 +133,42 @@
 	unsigned char base_mod;
 	int start_multi = 0;
 	unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base;
-	
-	/*
-	 * IBM's have the MMU on, so we have to disable it or
-	 * things get really unhappy in the kernel when
-	 * trying to setup the BATs with the MMU on
-	 * -- Cort
-	 */
-	flush_instruction_cache();
-	_put_HID0(_get_HID0() & ~0x0000C000);
-	_put_MSR((orig_MSR = _get_MSR()) & ~0x0030);
 
+	serial_fixups();
 #if defined(CONFIG_SERIAL_CONSOLE)
-	com_port = serial_init(0);
+	com_port = serial_init(0, NULL);
 #endif /* CONFIG_SERIAL_CONSOLE */
 #if defined(CONFIG_VGA_CONSOLE)
 	vga_init((unsigned char *)0xC0000000);
 #endif /* CONFIG_VGA_CONSOLE */
 
-	if (residual)
-	{
+	/*
+	 * Tell the user where we were loaded at and where we were relocated
+	 * to for debugging this process.
+	 */
+	puts("loaded at:     "); puthex(load_addr);
+	puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
+	if ( (unsigned long)load_addr != (unsigned long)&start ) {
+		puts("relocated to:  "); puthex((unsigned long)&start);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)&start + (4*num_words)));
+		puts("\n");
+	}
+
+	if (residual) {
+		/*
+		 * Tell the user where the residual data is.
+		 */
+		puts("board data at: "); puthex((unsigned long)residual);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)residual +
+					sizeof(RESIDUAL)));
+		puts("\nrelocated to:  ");puthex((unsigned long)hold_residual);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)hold_residual +
+					sizeof(RESIDUAL)));
+		puts("\n");
+
 		/* Is this Motorola PPCBug? */
 		if ((1 & residual->VitalProductData.FirmwareSupports) &&
 		    (1 == residual->VitalProductData.FirmwareSupplier)) {
@@ -190,8 +185,7 @@
 				((pci_did == PCI_DEVICE_ID_DEC_TULIP_FAST) ||
 				(pci_did == PCI_DEVICE_ID_DEC_TULIP) ||
 				(pci_did == PCI_DEVICE_ID_DEC_TULIP_PLUS) ||
-				(pci_did == PCI_DEVICE_ID_DEC_21142)))
-			{
+				(pci_did == PCI_DEVICE_ID_DEC_21142))) {
 				pci_read_config_32(0x70,
 						0x10,
 						&tulip_pci_base);
@@ -205,7 +199,7 @@
 			/* If this is genesis 2 board then check for no
 			 * keyboard controller and more than one processor.
 			 */
-			if (board_type == 0xe0) {	
+			if (board_type == 0xe0) {
 				base_mod = inb(0x803);
 				/* if a MVME2300/2400 or a Sitka then no keyboard */
 				if((base_mod == 0xFA) || (base_mod == 0xF9) ||
@@ -217,14 +211,17 @@
 			 * park the other processor so that the
 			 * kernel knows where to find them.
 			 */
-			if (residual->MaxNumCpus > 1) {
+			if (residual->MaxNumCpus > 1)
 				start_multi = 1;
-			}
 		}
 		memcpy(hold_residual,residual,sizeof(RESIDUAL));
 	} else {
+		/* Tell the user we didn't find anything. */
+		puts("No residual data found.\n");
+
 		/* Assume 32M in the absence of more info... */
 		TotalMemory = 0x02000000;
+
 		/*
 		 * This is a 'best guess' check.  We want to make sure
 		 * we don't try this on a PReP box without OF
@@ -232,116 +229,66 @@
 		 */
 		while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) )
 		{
-			/* The MMU needs to be on when we call OFW */
+			/* We need to restore the slightly inaccurate
+			 * MSR so that OpenFirmware will behave. -- Tom
+			 */
 			_put_MSR(orig_MSR);
 			of_init(OFW_interface);
 
 			/* get handle to memory description */
-			res = of_finddevice("/memory@0", 
+			res = of_finddevice("/memory@0",
 					    &dev_handle);
-			// puthex(res);  puts("\n");
-			if (res) break;
-			
+			if (res)
+				break;
+
 			/* get the info */
-			// puts("get info = ");
-			res = of_getprop(dev_handle, 
-					 "reg", 
-					 mem_info, 
-					 sizeof(mem_info), 
+			res = of_getprop(dev_handle,
+					 "reg",
+					 mem_info,
+					 sizeof(mem_info),
 					 &size);
-			// puthex(res);  puts(", info = "); puthex(mem_info[0]);  
-			// puts(" ");  puthex(mem_info[1]);   puts("\n");
-			if (res) break;
-			
+			if (res)
+				break;
+
 			TotalMemory = mem_info[1];
 			break;
 		}
+
 		hold_residual->TotalMemory = TotalMemory;
 		residual = hold_residual;
-		/* Turn MMU back off */
-		_put_MSR(orig_MSR & ~0x0030);
-        }
 
-	if (start_multi) {
-		hold_residual->VitalProductData.SmpIar = 0;
-		hold_residual->Cpus[1].CpuState = CPU_GOOD_FW;
-		residual->VitalProductData.SmpIar = (unsigned long)park_cpus;
-		residual->Cpus[1].CpuState = CPU_GOOD;
-		hold_residual->VitalProductData.Reserved5 = 0xdeadbeef;
-	}
+		/* Enforce a sane MSR for booting. */
+		_put_MSR(MSR_IP);
+        }
 
 	/* assume the chunk below 8M is free */
 	end_avail = (char *)0x00800000;
 
-	/* tell the user where we were loaded at and where we
-	 * were relocated to for debugging this process
+	/*
+	 * We link ourself to 0x00800000.  When we run, we relocate
+	 * ourselves there.  So we just need __image_begin for the
+	 * start. -- Tom
 	 */
-	puts("loaded at:     "); puthex(load_addr);
-	puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
-	if ( (unsigned long)load_addr != (unsigned long)&start )
-	{
-		puts("relocated to:  "); puthex((unsigned long)&start);
-		puts(" ");
-		puthex((unsigned long)((unsigned long)&start + (4*num_words)));
-		puts("\n");
-	}
-
-	if ( residual )
-	{
-		puts("board data at: "); puthex((unsigned long)residual);
-		puts(" ");
-		puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL)));
-		puts("\n");
-		puts("relocated to:  ");
-		puthex((unsigned long)hold_residual);
-		puts(" ");
-		puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL)));
-		puts("\n");
-	}
+	zimage_start = (char *)(unsigned long)(&__image_begin);
+	zimage_size = (unsigned long)(&__image_end) -
+			(unsigned long)(&__image_begin);
 
-	/* we have to subtract 0x10000 here to correct for objdump including the
-	   size of the elf header which we strip -- Cort */
-	zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
-	zimage_size = ZIMAGE_SIZE;
-
-	if ( INITRD_OFFSET )
-		initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
-	else
-		initrd_start = 0;
-	initrd_end = INITRD_SIZE + initrd_start;
+	initrd_size = (unsigned long)(&__ramdisk_end) -
+		(unsigned long)(&__ramdisk_begin);
 
 	/*
-	 * Find a place to stick the zimage and initrd and 
-	 * relocate them if we have to. -- Cort
+	 * The zImage and initrd will be between start and _end, so they've
+	 * already been moved once.  We're good to go now. -- Tom
 	 */
 	avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
 	puts("zimage at:     "); puthex((unsigned long)zimage_start);
-	puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
-	if ( (unsigned long)zimage_start <= 0x00800000 )
-	{
-		memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size );
-		zimage_start = (char *)avail_ram;
-		puts("relocated to:  "); puthex((unsigned long)zimage_start);
-		puts(" ");
-		puthex((unsigned long)zimage_size+(unsigned long)zimage_start);
-		puts("\n");
+	puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
+	puts("\n");
 
-		/* relocate initrd */
-		if ( initrd_start )
-		{
-			puts("initrd at:     "); puthex(initrd_start);
-			puts(" "); puthex(initrd_end); puts("\n");
-			avail_ram = (char *)PAGE_ALIGN(
-				(unsigned long)zimage_size+(unsigned long)zimage_start);
-			memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE );
-			initrd_start = (unsigned long)avail_ram;
-			initrd_end = initrd_start + INITRD_SIZE;
-			puts("relocated to:  "); puthex(initrd_start);
-			puts(" "); puthex(initrd_end); puts("\n");
-		}
-	} else if ( initrd_start ) {
-		puts("initrd at:     "); puthex(initrd_start);
-		puts(" "); puthex(initrd_end); puts("\n");
+	if ( initrd_size ) {
+		puts("initrd at:     ");
+		puthex((unsigned long)(&__ramdisk_begin));
+		puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
 	}
 
 	avail_ram = (char *)0x00400000;
@@ -353,10 +300,10 @@
 		CRT_tstc();  /* Forces keyboard to be initialized */
 
 	puts("\nLinux/PPC load: ");
-	timer = 0;
 	cp = cmd_line;
 	memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
-	while ( *cp ) putc(*cp++);
+	while ( *cp )
+		putc(*cp++);
 	while (timer++ < 5*1000) {
 		if (tstc()) {
 			while ((ch = getc()) != '\n' && ch != '\r') {
@@ -382,26 +329,24 @@
 		udelay(1000);  /* 1 msec */
 	}
 	*cp = 0;
-	puts("\n");
+	puts("\nUncompressing Linux...");
 
-	/* mappings on early boot can only handle 16M */
-	if ( (int)(cmd_line) > (16<<20))
-		puts("cmd_line located > 16M\n");
-	if ( (int)hold_residual > (16<<20))
-		puts("hold_residual located > 16M\n");
-	if ( initrd_start > (16<<20))
-		puts("initrd_start located > 16M\n");
-
-	puts("Uncompressing Linux...");
-	
 	gunzip(0, 0x400000, zimage_start, &zimage_size);
 	puts("done.\n");
-	
+
+	if (start_multi) {
+		puts("Parking cpu1 at 0xc0\n");
+		residual->VitalProductData.SmpIar = (unsigned long)0xc0;
+		residual->Cpus[1].CpuState = CPU_GOOD;
+		hold_residual->VitalProductData.Reserved5 = 0xdeadbeef;
+	}
+
 	{
 		struct bi_record *rec;
-	    
-		rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size)+(1<<20)-1,(1<<20));
-	    
+		
+		rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) +
+				(1 << 20) - 1, (1 << 20));
+
 		rec->tag = BI_FIRST;
 		rec->size = sizeof(struct bi_record);
 		rec = (struct bi_record *)((unsigned long)rec + rec->size);
@@ -410,18 +355,29 @@
 		memcpy( (void *)rec->data, "prepboot", 9);
 		rec->size = sizeof(struct bi_record) + 8 + 1;
 		rec = (struct bi_record *)((unsigned long)rec + rec->size);
-	    
+
 		rec->tag = BI_MACHTYPE;
 		rec->data[0] = _MACH_prep;
 		rec->data[1] = 0;
-		rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
+		rec->size = sizeof(struct bi_record) + 2 *
+			sizeof(unsigned long);
 		rec = (struct bi_record *)((unsigned long)rec + rec->size);
-	    
+
 		rec->tag = BI_CMD_LINE;
 		memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
 		rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
-		rec = (struct bi_record *)((ulong)rec + rec->size);
-		
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+		if ( initrd_size ) {
+			rec->tag = BI_INITRD;
+			rec->data[0] = (unsigned long)(&__ramdisk_begin);
+			rec->data[1] = initrd_size;
+			rec->size = sizeof(struct bi_record) + 2 *
+				sizeof(unsigned long);
+			rec = (struct bi_record *)((unsigned long)rec +
+					rec->size);
+		}
+
 		rec->tag = BI_LAST;
 		rec->size = sizeof(struct bi_record);
 		rec = (struct bi_record *)((unsigned long)rec + rec->size);
@@ -429,12 +385,3 @@
 	puts("Now booting the kernel\n");
 	return (unsigned long)hold_residual;
 }
-
-/*
- * PCI/ISA I/O support
- */
-unsigned long
-local_to_PCI(unsigned long addr)
-{
-	return (addr | 0x80000000);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/prep/vreset.c linux/arch/ppc/boot/prep/vreset.c
--- linux.orig/arch/ppc/boot/prep/vreset.c	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/boot/prep/vreset.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.vreset.c 1.11 07/25/01 18:13:07 trini
+ * BK Id: SCCS/s.vreset.c 1.13 01/11/02 10:46:08 trini
  */
 /*
  * vreset.c
@@ -29,7 +29,7 @@
 struct VaRegs;
 
 /*
- * VGA Register  
+ * VGA Register
  */
 struct VgaRegs
 {
@@ -108,51 +108,6 @@
 	{ ENDMK }
 };
 
-struct VgaRegs S3TextRegs[NREGS+1] = {
-	/* port		index	value */
-	/* SR Regs */
-	{ 0x3c4,	0x1,	0x0 },
-	{ 0x3c4,	0x2,	0x3 },
-	{ 0x3c4,	0x3,	0x0 },
-	{ 0x3c4,	0x4,	0x2 },
-	/* CR Regs */
-	{ 0x3d4,	0x0,	0x5f },
-	{ 0x3d4,	0x1,	0x4f },
-	{ 0x3d4,	0x2,	0x50 },
-	{ 0x3d4,	0x3,	0x82 },
-	{ 0x3d4,	0x4,	0x55 },
-	{ 0x3d4,	0x5,	0x81 },
-	{ 0x3d4,	0x6,	0xbf },
-	{ 0x3d4,	0x7,	0x1f },
-	{ 0x3d4,	0x8,	0x00 },
-	{ 0x3d4,	0x9,	0x4f },
-	{ 0x3d4,	0xa,	0x0d },
-	{ 0x3d4,	0xb,	0x0e },
-	{ 0x3d4,	0xc,	0x00 },
-	{ 0x3d4,	0xd,	0x00 },
-	{ 0x3d4,	0xe,	0x00 },
-	{ 0x3d4,	0xf,	0x00 },
-	{ 0x3d4,	0x10,	0x9c },
-	{ 0x3d4,	0x11,	0x8e },
-	{ 0x3d4,	0x12,	0x8f },
-	{ 0x3d4,	0x13,	0x28 },
-	{ 0x3d4,	0x14,	0x1f },
-	{ 0x3d4,	0x15,	0x96 },
-	{ 0x3d4,	0x16,	0xb9 },
-	{ 0x3d4,	0x17,	0xa3 },
-	/* GR Regs */
-	{ 0x3ce,	0x0,	0x0 },
-	{ 0x3ce,	0x1,	0x0 },
-	{ 0x3ce,	0x2,	0x0 },
-	{ 0x3ce,	0x3,	0x0 },
-	{ 0x3ce,	0x4,	0x0 },
-	{ 0x3ce,	0x5,	0x10 },
-	{ 0x3ce,	0x6,	0xe },
-	{ 0x3ce,	0x7,	0x0 },
-	{ 0x3ce,	0x8,	0xff },
-	{ ENDMK }
-};
-
 struct RGBColors
 {
   unsigned char r, g, b;
@@ -161,9 +116,9 @@
 /*
  * Default console text mode color table.
  * These values were obtained by booting Linux with
- * text mode firmware & then dumping the registers.  
+ * text mode firmware & then dumping the registers.
  */
-struct RGBColors TextCLUT[256] = 
+struct RGBColors TextCLUT[256] =
 {
 	/* red	green	blue  */
 	{ 0x0,	0x0,	0x0 },
@@ -424,8 +379,8 @@
 };
 
 unsigned char AC[21] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 
-    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
     0x0C, 0x00, 0x0F, 0x08, 0x00};
 
 static int scanPCI(int start_slt);
@@ -443,20 +398,13 @@
 	outb(port, val >> 8);
 	outb(port+1, val);
 }
- 
-#define PPC_601 1
 
 int
 vga_init(unsigned char *ISA_mem)
 {
 	int slot;
 	struct VgaRegs *VgaTextRegs;
-#if 0
-	if ((_get_PVR()>>16) == PPC_601) {
-		return(old_vga_init(ISA_mem));
-	}
-#endif
-	
+
 	/* See if VGA already in TEXT mode - exit if so! */
 	outb(0x3CE, 0x06);
 	if ((inb(0x3CF) & 0x01) == 0){
@@ -470,20 +418,19 @@
 	while((slot = scanPCI(slot)) > -1) { /* find video card in use  */
 		unlockVideo(slot);           /* enable I/O to card      */
 		VgaTextRegs = GenVgaTextRegs;
-	
+
 		switch (PCIVendor(slot)) {
 		default:
 			break;
 		case(S3Vendor):
 			unlockS3();
-			VgaTextRegs = S3TextRegs;
 			break;
-	
+
 		case(CirrusVendor):
 			outw(0x3C4, 0x0612);       /* unlock ext regs */
 			outw(0x3C4, 0x0700);       /* reset ext sequence mode */
 			break;
-	
+
 		case(ParadiseVendor):                 /* IBM Portable 850 */
 			outw(0x3ce, 0x0f05);      /* unlock pardise registers */
 			outw(0x3c4, 0x0648);
@@ -508,7 +455,7 @@
 			}
 			outw(0x3d4, 0x34a0);
 			break;
-	
+
 	#if 0 /* Untested - probably doesn't work */
 		case(MatroxVendor):
 		case(DiamondVendor):
@@ -518,7 +465,7 @@
 			mdelay(1000);
 	#endif
 		};
-	
+
 		outw(0x3C4, 0x0120);           /* disable video              */
 		setTextRegs(VgaTextRegs);      /* initial register setup     */
 		setTextCLUT(0);                /* load color lookup table    */
@@ -526,23 +473,23 @@
 		setTextRegs(VgaTextRegs);      /* reload registers           */
 		outw(0x3C4, 0x0100);           /* re-enable video            */
 		clearVideoMemory();
-	
+
 		if (PCIVendor(slot) == S3Vendor) {
 			outb(0x3c2, 0x63);                  /* MISC */
 		} /* endif */
-	
+
 	#ifdef DEBUG
 		printslots();
 		mdelay(5000);
 	#endif
-	
+
 		mdelay(1000);	/* give time for the video monitor to come up */
         }
 	return (1);  /* 'CRT' I/O supported */
 }
 
 /*
- * Write to VGA Attribute registers.  
+ * Write to VGA Attribute registers.
  */
 void
 writeAttr(unsigned char index, unsigned char data, unsigned char videoOn)
@@ -563,18 +510,18 @@
 
 	/*
 	 *  saved settings
-	 */ 
+	 */
 	while( svp->io_port != ENDMK ) {
 		outb(svp->io_port,   svp->io_index);
 		outb(svp->io_port+1, svp->io_value);
-		svp++; 
+		svp++;
 	}
 
 	outb(0x3c2, 0x67);  /* MISC */
 	outb(0x3c6, 0xff);  /* MASK */
 
 	for ( i = 0; i < 0x10; i++)
-		writeAttr(i, AC[i], 0);  /* pallete */ 
+		writeAttr(i, AC[i], 0);  /* pallete */
 	writeAttr(0x10, 0x0c, 0);    /* text mode */
 	writeAttr(0x11, 0x00, 0);    /* overscan color (border) */
 	writeAttr(0x12, 0x0f, 0);    /* plane enable */
@@ -587,9 +534,9 @@
 {
 	int i;
 
-	outb(0x3C6, 0xFF); 
+	outb(0x3C6, 0xFF);
 	i = inb(0x3C7);
-	outb(0x3C8, 0); 
+	outb(0x3C8, 0);
 	i = inb(0x3C7);
 
 	for ( i = 0; i < 256; i++) {
@@ -604,14 +551,14 @@
 {
 	int i, j;
 	unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000];
-    
+
 	outb(0x3C2, 0x67);
-	/* 
-	 * Load font 
+	/*
+	 * Load font
 	 */
 	i = inb(0x3DA);  /* Reset Attr toggle */
 
-	outb(0x3C0,0x30); 
+	outb(0x3C0,0x30);
 	outb(0x3C0, 0x01);      /* graphics mode */
 
 	outw(0x3C4, 0x0001);    /* reset sequencer */
@@ -706,7 +653,7 @@
 }
 
 /*
- * cursor() sets an offset (0-1999) into the 80x25 text area   
+ * cursor() sets an offset (0-1999) into the 80x25 text area.
  */
 void
 cursor(int x, int y)
@@ -737,14 +684,14 @@
 #define NPCIREGS  5
 
 
-/* 
- should use devfunc number/indirect method to be totally safe on 
- all machines, this works for now on 3 slot Moto boxes 
+/*
+ should use devfunc number/indirect method to be totally safe on
+ all machines, this works for now on 3 slot Moto boxes
 */
 
 struct PCI_ConfigInfo {
   unsigned long * config_addr;
-  unsigned long regs[NPCIREGS];  
+  unsigned long regs[NPCIREGS];
 } PCI_slots [NSLOTS] = {
 
     { (unsigned long *)0x80808000, 0xDEADBEEF },   /* onboard */
@@ -761,10 +708,10 @@
 
 /*
  * The following code modifies the PCI Command register
- * to enable memory and I/O accesses.    
- */ 
+ * to enable memory and I/O accesses.
+ */
 void
-unlockVideo(int slot)        
+unlockVideo(int slot)
 {
        volatile unsigned char * ppci;
 
@@ -811,13 +758,13 @@
 			pslot->regs[r] = SwapBytes ( pslot->config_addr[r] );
 		}
 		/* card in slot ? */
-		if ( pslot->regs[DEVID] != 0xFFFFFFFF ) {     
+		if ( pslot->regs[DEVID] != 0xFFFFFFFF ) {
 			/* VGA ? */
-			if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) || 
+			if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) ||
 			     ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) {
 				highVgaSlot = slt;
 				/* did firmware enable it ? */
-				if ( (pslot->regs[CMD] & 0x03) ) { 
+				if ( (pslot->regs[CMD] & 0x03) ) {
 					theSlot = slt;
 					break;
 				}
@@ -840,7 +787,7 @@
 
 #ifdef DEBUG
 static
-void printslots(void) 
+void printslots(void)
 {
 	int i;
 #if 0
@@ -853,7 +800,7 @@
 		       i, pslot->config_addr, pslot->regs[0], pslot->regs[2]);
 #else
 		puts("PCI Slot number: "); puthex(i);
-		puts(" Vendor ID: "); 
+		puts(" Vendor ID: ");
 		puthex(PCIVendor(i)); puts("\n");
 #endif
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/Makefile linux/arch/ppc/boot/simple/Makefile
--- linux.orig/arch/ppc/boot/simple/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/Makefile	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,135 @@
+# This is far from simple, but I couldn't think of a good name.  This is
+# for making the 'zImage' or 'zImage.initrd' on a number of targets.
+#
+# Author: Tom Rini <trini@mvista.com>
+#
+# Copyright 2001 MontaVista Software Inc.
+#
+# Notes: For machine targets which produce more than one image, define
+# ZNETBOOT and ZNETBOOTRD to the image which should be available for
+# 'znetboot' and 'znetboot.initrd`
+#
+# 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.
+
+USE_STANDARD_AS_RULE		:= true
+
+# Normally, we use the 'misc-simple.c' file for decompress_kernel and
+# whatnot.  Sometimes we need to override this however.
+MISC				:= ../common/misc-simple.o
+ifeq ($(CONFIG_EMBEDDEDBOOT),y)
+ZIMAGE				:= zImage-EMBEDDED
+ZIMAGEINITRD			:= zImage.initrd-EMBEDDED
+TFTPIMAGE			:= /tftpboot/zImage.embedded
+MISC				:= misc-embedded.o
+endif
+ifeq ($(CONFIG_GEMINI),y)
+ZIMAGE				:= zImage-SMON
+ZIMAGEINITRD			:= zImage.initrd-SMON
+HEADHELP			:= direct.o
+TFTPIMAGE			:= /tftpboot/zImage.gemini
+endif
+ifeq ($(CONFIG_SMP),y)
+TFTPIMAGE			+= .smp
+endif
+
+# Setup a default address to put ourselves, change it as needed.
+LD_ARGS				= -T ../ld.script -Ttext 0x00800000 -Bstatic
+ifdef CONFIG_8xx
+LD_ARGS				:= -T ../ld.script -Ttext 0x00180000 -Bstatic
+endif
+ifeq ($(CONFIG_8260)$(CONFIG_4xx),y)
+LD_ARGS				:= -T ../ld.script -Ttext 0x00400000 -Bstatic
+endif
+OBJCOPY_ARGS			:= -O elf32-powerpc
+
+# head.o and ../common/relocate.o must be at the start.
+obj-y				:= head.o ../common/relocate.o $(HEADHELP) \
+				$(MISC) ../common/misc-common.o \
+				../common/string.o ../common/util.o
+obj-$(CONFIG_4xx)		+= embed_config.o
+obj-$(CONFIG_8xx)		+= embed_config.o
+obj-$(CONFIG_8260)		+= embed_config.o
+obj-$(CONFIG_BSEIP)		+= iic.o
+obj-$(CONFIG_MBX)		+= iic.o
+obj-$(CONFIG_RPXCLASSIC)	+= iic.o
+obj-$(CONFIG_RPXLITE)		+= iic.o
+# Different boards need different serial implementations.
+ifeq ($(CONFIG_SERIAL_CONSOLE),y)
+obj-$(CONFIG_8xx)		+= m8xx_tty.o
+obj-$(CONFIG_8260)		+= m8260_tty.o
+obj-$(CONFIG_SERIAL)		+= ../common/ns16550.o
+endif
+
+LIBS				:= ../lib/zlib.a
+
+# Tools
+MKPREP				:= ../utils/mkprep
+MKTREE				:= ../utils/mktree
+
+AFLAGS_head.o			+= -I$(TOPDIR)/arch/$(ARCH)/kernel
+AFLAGS_../common/util.o		+= -I$(TOPDIR)/arch/$(ARCH)/kernel
+AFLAGS_../common/relocate.o	+= -I$(TOPDIR)/arch/$(ARCH)/kernel
+
+zvmlinux: $(obj-y) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o
+	$(OBJCOPY) $(OBJCOPY_ARGS) \
+		--add-section=.image=../images/vmlinux.gz \
+		--set-section-flags=.image=contents,alloc,load,readonly,data \
+		../common/dummy.o image.o
+	$(LD) $(LD_ARGS) -o $@ $(obj-y) image.o $(LIBS)
+	$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \
+		-R .ramdisk -R .sysmap
+
+zvmlinux.initrd: $(obj-y) $(LIBS) ../ld.script ../images/vmlinux.gz \
+		../common/dummy.o
+	$(OBJCOPY) $(OBJCOPY_ARGS) \
+		--add-section=.ramdisk=../images/ramdisk.image.gz \
+		--set-section-flags=.ramdisk=contents,alloc,load,readonly,data \
+		--add-section=.image=../images/vmlinux.gz \
+		--set-section-flags=.image=contents,alloc,load,readonly,data \
+		../common/dummy.o image.o
+	$(LD) $(LD_ARGS) -o $@ $(obj-y) image.o $(LIBS)
+	$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \
+		-R .sysmap
+
+# Sort-of dummy rules, that let us format the image we want.
+zImage: $(ZIMAGE)
+	rm -f zvmlinux
+zImage.initrd: $(ZIMAGEINITRD)
+	rm -f zvmlinux.initrd
+
+znetboot: zImage
+ifneq ($(ZNETBOOT),)
+	cp ../images/$(ZNETBOOT) $(TFTPIMAGE)
+else
+	cp ../images/zImage.* $(TFTPIMAGE)
+endif
+
+znetboot.initrd: zImage.initrd
+ifneq ($(ZNETBOOTRD),)
+	cp ../images/$(ZNETBOOTRD) $(TFTPIMAGE)
+else
+	cp ../images/zImage.* $(TFTPIMAGE)
+endif
+
+zImage-EMBEDDED: zvmlinux
+	mv zvmlinux ../images/zImage.embedded
+
+zImage.initrd-EMBEDDED: zvmlinux.initrd
+	mv zvmlinux.initrd ../images/zImage.initrd.embedded
+
+zImage-SMON: zvmlinux
+	dd if=zvmlinux of=../images/zImage.gemini skip=64 bs=1k
+
+zImage.initrd-SMON: zvmlinux.initrd
+	dd if=zvmlinux.initrd of=../images/zImage.initrd.gemini skip=64 bs=1k
+
+zImage-TREE: zvmlinux
+	$(MKTREE) zvmlinux ../images/zImage.treeboot
+
+zImage.initrd-TREE: zvmlinux.initrd
+	$(MKTREE) zvmlinux.initrd ../images/zImage.initrd.treeboot
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/direct.S linux/arch/ppc/boot/simple/direct.S
--- linux.orig/arch/ppc/boot/simple/direct.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/direct.S	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,15 @@
+/*
+ * arch/ppc/boot/simple/direct.S
+ *
+ * Author: Tom Rini <trini@mvista.com>
+ *
+ * This is an empty function for machines which use SERIAL_IO_MEM
+ * and don't need ISA_io set to anything but 0, or perform any other
+ * serial fixups.
+ */
+
+	.text
+
+	.globl serial_fixups
+serial_fixups:
+	blr
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/embed_config.c linux/arch/ppc/boot/simple/embed_config.c
--- linux.orig/arch/ppc/boot/simple/embed_config.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/embed_config.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,761 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+
+/* Board specific functions for those embedded 8xx boards that do
+ * not have boot monitor support for board information.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#ifdef CONFIG_8xx
+#include <asm/mpc8xx.h>
+#endif
+#ifdef CONFIG_8260
+#include <asm/mpc8260.h>
+#include <asm/immap_8260.h>
+#endif
+#ifdef CONFIG_4xx
+#include <asm/io.h>
+#endif
+#if defined(CONFIG_405GP) || defined(CONFIG_NP405H) || defined(CONFIG_NP405L)
+#include <linux/netdevice.h>
+#endif
+
+/* For those boards that don't provide one.
+*/
+#if !defined(CONFIG_MBX)
+static	bd_t	bdinfo;
+#endif
+
+/* IIC functions.
+ * These are just the basic master read/write operations so we can
+ * examine serial EEPROM.
+ */
+extern void	iic_read(uint devaddr, u_char *buf, uint offset, uint count);
+
+/* Supply a default Ethernet address for those eval boards that don't
+ * ship with one.  This is an address from the MBX board I have, so
+ * it is unlikely you will find it on your network.
+ */
+static	ushort	def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
+
+#if defined(CONFIG_MBX)
+
+/* The MBX hands us a pretty much ready to go board descriptor.  This
+ * is where the idea started in the first place.
+ */
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*mp;
+	u_char	eebuf[128];
+	int i;
+	bd_t    *bd;
+
+	bd = *bdp;
+
+	/* Read the first 128 bytes of the EEPROM.  There is more,
+	 * but this is all we need.
+	 */
+	iic_read(0xa4, eebuf, 0, 128);
+
+	/* All we are looking for is the Ethernet MAC address.  The
+	 * first 8 bytes are 'MOTOROLA', so check for part of that.
+	 * If it's there, assume we have a valid MAC address.  If not,
+	 * grab our default one.
+	 */
+	if ((*(uint *)eebuf) == 0x4d4f544f)
+		mp = &eebuf[0x4c];
+	else
+		mp = (u_char *)def_enet_addr;
+
+	for (i=0; i<6; i++)
+		bd->bi_enetaddr[i] = *mp++;
+
+	/* The boot rom passes these to us in MHz.  Linux now expects
+	 * them to be in Hz.
+	 */
+	bd->bi_intfreq *= 1000000;
+	bd->bi_busfreq *= 1000000;
+
+	/* Stuff a baud rate here as well.
+	*/
+	bd->bi_baudrate = 9600;
+}
+#endif /* CONFIG_MBX */
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \
+	defined(CONFIG_RPX6) || defined(CONFIG_EP405)
+/* Helper functions for Embedded Planet boards.
+*/
+/* Because I didn't find anything that would do this.......
+*/
+u_char
+aschex_to_byte(u_char *cp)
+{
+	u_char	byte, c;
+
+	c = *cp++;
+
+	if ((c >= 'A') && (c <= 'F')) {
+		c -= 'A';
+		c += 10;
+	} else if ((c >= 'a') && (c <= 'f')) {
+		c -= 'a';
+		c += 10;
+	} else
+		c -= '0';
+
+	byte = c * 16;
+
+	c = *cp;
+
+	if ((c >= 'A') && (c <= 'F')) {
+		c -= 'A';
+		c += 10;
+	} else if ((c >= 'a') && (c <= 'f')) {
+		c -= 'a';
+		c += 10;
+	} else
+		c -= '0';
+
+	byte += c;
+
+	return(byte);
+}
+
+static void
+rpx_eth(bd_t *bd, u_char *cp)
+{
+	int	i;
+
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = aschex_to_byte(cp);
+		cp += 2;
+	}
+}
+
+#ifdef CONFIG_RPX6
+static uint
+rpx_baseten(u_char *cp)
+{
+	uint	retval;
+
+	retval = 0;
+
+	while (*cp != '\n') {
+		retval *= 10;
+		retval += (*cp) - '0';
+		cp++;
+	}
+	return(retval);
+}
+#endif
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+static void
+rpx_brate(bd_t *bd, u_char *cp)
+{
+	uint	rate;
+
+	rate = 0;
+
+	while (*cp != '\n') {
+		rate *= 10;
+		rate += (*cp) - '0';
+		cp++;
+	}
+
+	bd->bi_baudrate = rate * 100;
+}
+
+static void
+rpx_cpuspeed(bd_t *bd, u_char *cp)
+{
+	uint	num, den;
+
+	num = den = 0;
+
+	while (*cp != '\n') {
+		num *= 10;
+		num += (*cp) - '0';
+		cp++;
+		if (*cp == '/') {
+			cp++;
+			den = (*cp) - '0';
+			break;
+		}
+	}
+
+	/* I don't know why the RPX just can't state the actual
+	 * CPU speed.....
+	 */
+	if (den) {
+		num /= den;
+		num *= den;
+	}
+	bd->bi_intfreq = bd->bi_busfreq = num * 1000000;
+
+	/* The 8xx can only run a maximum 50 MHz bus speed (until
+	 * Motorola changes this :-).  Greater than 50 MHz parts
+	 * run internal/2 for bus speed.
+	 */
+	if (num > 50)
+		bd->bi_busfreq /= 2;
+}
+#endif
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405)
+static void
+rpx_memsize(bd_t *bd, u_char *cp)
+{
+	uint	size;
+
+	size = 0;
+
+	while (*cp != '\n') {
+		size *= 10;
+		size += (*cp) - '0';
+		cp++;
+	}
+
+	bd->bi_memsize = size * 1024 * 1024;
+}
+#endif /* LITE || CLASSIC || EP405 */
+
+#endif	/* Embedded Planet boards */
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+
+/* Read the EEPROM on the RPX-Lite board.
+*/
+void
+embed_config(bd_t **bdp)
+{
+	u_char	eebuf[256], *cp;
+	bd_t	*bd;
+
+	/* Read the first 256 bytes of the EEPROM.  I think this
+	 * is really all there is, and I hope if it gets bigger the
+	 * info we want is still up front.
+	 */
+	bd = &bdinfo;
+	*bdp = bd;
+
+#if 1
+	iic_read(0xa8, eebuf, 0, 128);
+	iic_read(0xa8, &eebuf[128], 128, 128);
+
+	/* We look for two things, the Ethernet address and the
+	 * serial baud rate.  The records are separated by
+	 * newlines.
+	 */
+	cp = eebuf;
+	for (;;) {
+		if (*cp == 'E') {
+			cp++;
+			if (*cp == 'A') {
+				cp += 2;
+				rpx_eth(bd, cp);
+			}
+		}
+		if (*cp == 'S') {
+			cp++;
+			if (*cp == 'B') {
+				cp += 2;
+				rpx_brate(bd, cp);
+			}
+		}
+		if (*cp == 'D') {
+			cp++;
+			if (*cp == '1') {
+				cp += 2;
+				rpx_memsize(bd, cp);
+			}
+		}
+		if (*cp == 'H') {
+			cp++;
+			if (*cp == 'Z') {
+				cp += 2;
+				rpx_cpuspeed(bd, cp);
+			}
+		}
+
+		/* Scan to the end of the record.
+		*/
+		while ((*cp != '\n') && (*cp != 0xff))
+			cp++;
+
+		/* If the next character is a 0 or ff, we are done.
+		*/
+		cp++;
+		if ((*cp == 0) || (*cp == 0xff))
+			break;
+	}
+	bd->bi_memstart = 0;
+#else
+	/* For boards without initialized EEPROM.
+	*/
+	bd->bi_memstart = 0;
+	bd->bi_memsize = (8 * 1024 * 1024);
+	bd->bi_intfreq = 48000000;
+	bd->bi_busfreq = 48000000;
+	bd->bi_baudrate = 9600;
+#endif
+}
+#endif /* RPXLITE || RPXCLASSIC */
+
+#ifdef CONFIG_BSEIP
+/* Build a board information structure for the BSE ip-Engine.
+ * There is more to come since we will add some environment
+ * variables and a function to read them.
+ */
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	bd = &bdinfo;
+	*bdp = bd;
+
+	/* Baud rate and processor speed will eventually come
+	 * from the environment variables.
+	 */
+	bd->bi_baudrate = 9600;
+
+	/* Get the Ethernet station address from the Flash ROM.
+	*/
+	cp = (u_char *)0xfe003ffa;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+
+	/* The rest of this should come from the environment as well.
+	*/
+	bd->bi_memstart = 0;
+	bd->bi_memsize = (16 * 1024 * 1024);
+	bd->bi_intfreq = 48000000;
+	bd->bi_busfreq = 48000000;
+}
+#endif /* BSEIP */
+
+#ifdef CONFIG_FADS
+/* Build a board information structure for the FADS.
+ */
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	bd = &bdinfo;
+	*bdp = bd;
+
+	/* Just fill in some known values.
+	 */
+	bd->bi_baudrate = 9600;
+
+	/* Use default enet.
+	*/
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+
+	bd->bi_memstart = 0;
+	bd->bi_memsize = (8 * 1024 * 1024);
+	bd->bi_intfreq = 40000000;
+	bd->bi_busfreq = 40000000;
+}
+#endif /* FADS */
+
+#ifdef CONFIG_8260
+/* Compute 8260 clock values if the rom doesn't provide them.
+ * We can't compute the internal core frequency (I don't know how to
+ * do that).
+ */
+static void
+clk_8260(bd_t *bd)
+{
+	uint	scmr, vco_out, clkin;
+	uint	plldf, pllmf, busdf, brgdf, cpmdf;
+	volatile immap_t	*ip;
+
+	ip = (immap_t *)IMAP_ADDR;
+	scmr = ip->im_clkrst.car_scmr;
+
+	/* The clkin is always bus frequency.
+	*/
+	clkin = bd->bi_busfreq;
+
+	/* Collect the bits from the scmr.
+	*/
+	plldf = (scmr >> 12) & 1;
+	pllmf = scmr & 0xfff;
+	cpmdf = (scmr >> 16) & 0x0f;
+	busdf = (scmr >> 20) & 0x0f;
+
+	/* This is arithmetic from the 8260 manual.
+	*/
+	vco_out = clkin / (plldf + 1);
+	vco_out *= 2 * (pllmf + 1);
+	bd->bi_vco = vco_out;		/* Save for later */
+
+	bd->bi_cpmfreq = vco_out / 2;	/* CPM Freq, in MHz */
+
+	/* Set Baud rate divisor.  The power up default is divide by 16,
+	 * but we set it again here in case it was changed.
+	 */
+	ip->im_clkrst.car_sccr = 1;	/* DIV 16 BRG */
+	bd->bi_brgfreq = vco_out / 16;
+}
+#endif
+
+#ifdef CONFIG_EST8260
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	bd = *bdp;
+#if 0
+	/* This is actually provided by my boot rom.  I have it
+	 * here for those people that may load the kernel with
+	 * a JTAG/COP tool and not the rom monitor.
+	 */
+	bd->bi_baudrate = 115200;
+	bd->bi_intfreq = 200000000;
+	bd->bi_busfreq = 66666666;
+	bd->bi_cpmfreq = 66666666;
+	bd->bi_brgfreq = 33333333;
+	bd->bi_memsize = 16 * 1024 * 1024;
+#else
+	/* The boot rom passes these to us in MHz.  Linux now expects
+	 * them to be in Hz.
+	 */
+	bd->bi_intfreq *= 1000000;
+	bd->bi_busfreq *= 1000000;
+	bd->bi_cpmfreq *= 1000000;
+	bd->bi_brgfreq *= 1000000;
+#endif
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+}
+#endif /* EST8260 */
+
+#ifdef CONFIG_SBS8260
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	/* This should provided by the boot rom.
+	 */
+	bd = &bdinfo;
+	*bdp = bd;
+	bd->bi_baudrate = 9600;
+	bd->bi_memsize = 64 * 1024 * 1024;
+
+	/* Set all of the clocks.  We have to know the speed of the
+	 * external clock.  The development board had 66 MHz.
+	 */
+	bd->bi_busfreq = 66666666;
+	clk_8260(bd);
+
+	/* I don't know how to compute this yet.
+	*/
+	bd->bi_intfreq = 133000000;
+
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+}
+#endif /* SBS8260 */
+
+#ifdef CONFIG_RPX6
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp, *keyvals;
+	int	i;
+	bd_t	*bd;
+
+	keyvals = (u_char *)*bdp;
+
+	bd = &bdinfo;
+	*bdp = bd;
+
+	/* This is almost identical to the RPX-Lite/Classic functions
+	 * on the 8xx boards.  It would be nice to have a key lookup
+	 * function in a string, but the format of all of the fields
+	 * is slightly different.
+	 */
+	cp = keyvals;
+	for (;;) {
+		if (*cp == 'E') {
+			cp++;
+			if (*cp == 'A') {
+				cp += 2;
+				rpx_eth(bd, cp);
+			}
+		}
+		if (*cp == 'S') {
+			cp++;
+			if (*cp == 'B') {
+				cp += 2;
+				bd->bi_baudrate = rpx_baseten(cp);
+			}
+		}
+		if (*cp == 'D') {
+			cp++;
+			if (*cp == '1') {
+				cp += 2;
+				bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024;
+			}
+		}
+		if (*cp == 'X') {
+			cp++;
+			if (*cp == 'T') {
+				cp += 2;
+				bd->bi_busfreq = rpx_baseten(cp);
+			}
+		}
+		if (*cp == 'N') {
+			cp++;
+			if (*cp == 'V') {
+				cp += 2;
+				bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024;
+			}
+		}
+
+		/* Scan to the end of the record.
+		*/
+		while ((*cp != '\n') && (*cp != 0xff))
+			cp++;
+
+		/* If the next character is a 0 or ff, we are done.
+		*/
+		cp++;
+		if ((*cp == 0) || (*cp == 0xff))
+			break;
+	}
+	bd->bi_memstart = 0;
+
+	/* The memory size includes both the 60x and local bus DRAM.
+	 * I don't want to use the local bus DRAM for real memory,
+	 * so subtract it out.  It would be nice if they were separate
+	 * keys.
+	 */
+	bd->bi_memsize -= 32 * 1024 * 1024;
+
+	/* Set all of the clocks.  We have to know the speed of the
+	 * external clock.
+	 */
+	clk_8260(bd);
+
+	/* I don't know how to compute this yet.
+	*/
+	bd->bi_intfreq = 200000000;
+}
+#endif /* RPX6 for testing */
+
+#ifdef CONFIG_ADS8260
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	/* This should provided by the boot rom.
+	 */
+	bd = &bdinfo;
+	*bdp = bd;
+	bd->bi_baudrate = 9600;
+	bd->bi_memsize = 16 * 1024 * 1024;
+
+	/* Set all of the clocks.  We have to know the speed of the
+	 * external clock.  The development board had 66 MHz.
+	 */
+	bd->bi_busfreq = 66666666;
+	clk_8260(bd);
+
+	/* I don't know how to compute this yet.
+	*/
+	bd->bi_intfreq = 200000000;
+
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+}
+#endif /* ADS8260 */
+
+#ifdef CONFIG_WILLOW
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	/* Willow has Open Firmware....I should learn how to get this
+	 * information from it.
+	 */
+	bd = &bdinfo;
+	*bdp = bd;
+	bd->bi_baudrate = 9600;
+	bd->bi_memsize = 32 * 1024 * 1024;
+
+	/* Set all of the clocks.  We have to know the speed of the
+	 * external clock.  The development board had 66 MHz.
+	 */
+	bd->bi_busfreq = 66666666;
+	clk_8260(bd);
+
+	/* I don't know how to compute this yet.
+	*/
+	bd->bi_intfreq = 200000000;
+
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+}
+#endif /* WILLOW */
+
+#ifdef CONFIG_TREEBOOT
+/* This could possibly work for all treeboot roms.
+*/
+#define	BOARD_INFO_VECTOR	0xFFFE0B50
+
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd, *treeboot_bd;
+	bd_t *(*get_board_info)(void) =
+	    (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
+#if !defined(CONFIG_STB03xxx)
+	volatile emac_t *emacp;
+	emacp = (emac_t *)EMAC0_BASE;  /* assume 1st emac - armin */
+
+	/* shut down the Ethernet controller that the boot rom
+	 * sometimes leaves running.
+	 */
+	mtdcr(DCRN_MALCR, MALCR_MMSR);                /* 1st reset MAL */
+	while (mfdcr(DCRN_MALCR) & MALCR_MMSR) {};    /* wait for the reset */
+	emacp->em0mr0 = 0x20000000;        /* then reset EMAC */
+	eieio();
+#endif
+
+	bd = &bdinfo;
+	*bdp = bd;
+	if ((treeboot_bd = get_board_info()) != NULL) {
+		memcpy(bd, treeboot_bd, sizeof(bd_t));
+	}
+	else {
+		/* Hmmm...better try to stuff some defaults.
+		*/
+		bd->bi_memsize = 16 * 1024 * 1024;
+		cp = (u_char *)def_enet_addr;
+		for (i=0; i<6; i++) {
+			/* I should probably put different ones here,
+			 * hopefully only one is used.
+			 */
+			bd->BD_EMAC_ADDR(0,i) = *cp;
+
+#ifdef CONFIG_PCI
+			bd->bi_pci_enetaddr[i] = *cp++;
+#endif
+		}
+		bd->bi_intfreq = 200000000;
+		bd->bi_busfreq = 100000000;
+#ifdef CONFIG_PCI
+		bd->bi_pci_busfreq = 66666666;
+#endif
+		/* Yeah, this look weird, but on Redwood 4 they are
+		 * different object in the structure.  When RW5 uses
+		 * OpenBIOS, it requires a special value.
+		 */
+#ifdef CONFIG_REDWOOD_5
+	bd->bi_intfreq = 200 * 1000 * 1000;
+	bd->bi_busfreq = 0;
+
+		bd->bi_tbfreq = 27 * 1000 * 1000;
+#elif CONFIG_REDWOOD_4
+		bd->bi_tbfreq = bd->bi_intfreq;
+#endif
+	}
+}
+#endif
+
+#ifdef CONFIG_EP405
+void
+embed_config(bd_t **bdp)
+{
+	u_char *cp;
+	bd_t	*bd;
+
+	bd = &bdinfo;
+	*bdp = bd;
+#if 1
+	        cp = (u_char *)0xF0000EE0;
+	        for (;;) {
+	                if (*cp == 'E') {
+	                        cp++;
+	                        if (*cp == 'A') {
+                                  cp += 2;
+                                  rpx_eth(bd, cp);
+	                        }
+		         }
+
+	         	if (*cp == 'D') {
+	                        	cp++;
+	                        	if (*cp == '1') {
+		                                cp += 2;
+		                                rpx_memsize(bd, cp);
+	        	                }
+                	}
+
+			while ((*cp != '\n') && (*cp != 0xff))
+			      cp++;
+
+	                cp++;
+	                if ((*cp == 0) || (*cp == 0xff))
+	                   break;
+	       }
+	bd->bi_intfreq   = 200000000;
+	bd->bi_busfreq   = 100000000;
+	bd->bi_pci_busfreq= 33000000 ;
+#else
+
+	bd->bi_memsize   = 64000000;
+	bd->bi_intfreq   = 200000000;
+	bd->bi_busfreq   = 100000000;
+	bd->bi_pci_busfreq= 33000000 ;
+#endif
+}
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/head.S linux/arch/ppc/boot/simple/head.S
--- linux.orig/arch/ppc/boot/simple/head.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/head.S	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,120 @@
+/*
+ * arch/ppc/boot/simple/head.S
+ *
+ * Initial board bringup code for many different boards.
+ *
+ * Author: Tom Rini
+ *	   trini@mvista.com
+ * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include "ppc_asm.h"
+
+	.text
+
+/*
+ *      Begin at some arbitrary location in RAM or Flash
+ *	  Initialize core registers
+ *	  Configure memory controller (Not executing from RAM)
+ *	Move the boot code to the link address (8M)
+ *	  Setup C stack
+ *	  Initialize UART
+ *      Decompress the kernel to 0x0
+ *      Jump to the kernel entry
+ *
+ */
+
+	.globl	start
+start:
+	bl	start_
+#ifdef CONFIG_TREEBOOT
+	/* The IBM "Tree" bootrom knows that the address of the bootrom
+	 * read only structure is 4 bytes after _start.
+	 */
+	.long	0x62726f6d		# structure ID - "brom"
+	.long	0x5f726f00		#              - "_ro\0"
+	.long	1			# structure version
+	.long	bootrom_cmdline		# address of *bootrom_cmdline
+#endif
+
+start_:
+#ifdef CONFIG_FORCE
+	/* We have some really bad firmware.  We must disable the L1
+	 * icache/dcache now or the board won't boot.
+	 */
+	li	r4,0x0000
+	isync
+	mtspr	HID0,r4
+	sync
+	isync
+#endif
+
+#if defined(CONFIG_MBX) || defined(CONFIG_RPX6)
+	mr	r29,r3	/* On the MBX860, r3 is the board info pointer.
+			 * On the RPXSUPER, r3 points to the
+			 * NVRAM configuration keys.
+			 */
+#endif
+
+	mflr	r3	/* Save our actual starting address. */
+
+	/* The following functions we call must not modify r3 or r4.....
+	*/
+#ifdef CONFIG_6xx
+	bl	disable_6xx_mmu
+	bl	disable_6xx_l1cache
+#if defined(CONFIG_FORCE) || defined(CONFIG_K2) || defined(CONFIG_EV64260)
+	bl	_setup_L2CR
+#endif
+#endif
+
+#ifdef CONFIG_8xx
+	mfmsr	r8		/* Turn off interrupts */
+	li	r9,0
+	ori	r9,r9,MSR_EE
+	andc	r8,r8,r9
+	mtmsr	r8
+
+	/* We do this because some boot roms don't initialize the
+	 * processor correctly. Don't do this if you want to debug
+	 * using a BDM device.
+	 */
+	li	r4,0		/* Zero DER to prevent FRZ */
+	mtspr	SPRN_DER,r4
+#endif
+
+#ifdef CONFIG_REDWOOD_4
+	/* All of this Redwood 4 stuff will soon disappear when the
+	 * boot rom is straightened out.
+	 */
+	mr	r29, r3		/* Easier than changing the other code */
+	bl	HdwInit
+	mr	r3, r29
+#endif
+
+#if defined(CONFIG_MBX) || defined(CONFIG_RPX6)
+	mr	r4,r29	/* put the board info pointer where the relocate
+			 * routine will find it
+			 */
+#endif
+
+#ifdef	CONFIG_EV64260
+	/* Move 64260's base regs & CS window for external UART */
+	bl	ev64260_init
+#endif
+
+	/* Get the load address.
+	*/
+	subi	r3, r3, 4	/* Get the actual IP, not NIP */
+	b	relocate
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/iic.c linux/arch/ppc/boot/simple/iic.c
--- linux.orig/arch/ppc/boot/simple/iic.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/iic.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,218 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+
+/* Minimal support functions to read configuration from IIC EEPROMS
+ * on MPC8xx boards.  Originally written for RPGC RPX-Lite.
+ * Dan Malek (dmalek@jlc.net).
+ */
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+
+
+/* IIC functions.
+ * These are just the basic master read/write operations so we can
+ * examine serial EEPROM.
+ */
+void	iic_read(uint devaddr, u_char *buf, uint offset, uint count);
+
+static	int	iic_init_done;
+
+static void
+iic_init(void)
+{
+	volatile iic_t *iip;
+	volatile i2c8xx_t *i2c;
+	volatile cpm8xx_t	*cp;
+	volatile immap_t	*immap;
+	uint	dpaddr;
+
+	immap = (immap_t *)IMAP_ADDR;
+	cp = (cpm8xx_t *)&(immap->im_cpm);
+
+	/* Reset the CPM.  This is necessary on the 860 processors
+	 * that may have started the SCC1 ethernet without relocating
+	 * the IIC.
+	 * This also stops the Ethernet in case we were loaded by a
+	 * BOOTP rom monitor.
+	 */
+	cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
+
+	/* Wait for it.
+	*/
+	while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));
+
+	/* Remove any microcode patches.  We will install our own
+	 * later.
+	 */
+	cp->cp_cpmcr1 = 0;
+	cp->cp_cpmcr2 = 0;
+	cp->cp_cpmcr3 = 0;
+	cp->cp_cpmcr4 = 0;
+	cp->cp_rccr = 0;
+
+	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
+	i2c = (i2c8xx_t *)&(immap->im_i2c);
+
+	/* Initialize Port B IIC pins.
+	*/
+	cp->cp_pbpar |= 0x00000030;
+	cp->cp_pbdir |= 0x00000030;
+	cp->cp_pbodr |= 0x00000030;
+
+	/* Initialize the parameter ram.
+	*/
+
+	/* Allocate space for a two transmit and one receive buffer
+	 * descriptor in the DP ram.
+	 * For now, this address seems OK, but it may have to
+	 * change with newer versions of the firmware.
+	 */
+	dpaddr = 0x0840;
+
+	/* Set up the IIC parameters in the parameter ram.
+	*/
+	iip->iic_tbase = dpaddr;
+	iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t));
+
+	iip->iic_tfcr = SMC_EB;
+	iip->iic_rfcr = SMC_EB;
+
+	/* This should really be done by the reader/writer.
+	*/
+	iip->iic_mrblr = 128;
+
+	/* Initialize Tx/Rx parameters.
+	*/
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Select an arbitrary address.  Just make sure it is unique.
+	*/
+	i2c->i2c_i2add = 0x34;
+
+	/* Make clock run maximum slow.
+	*/
+	i2c->i2c_i2brg = 7;
+
+	/* Disable interrupts.
+	*/
+	i2c->i2c_i2cmr = 0;
+	i2c->i2c_i2cer = 0xff;
+
+	/* Enable SDMA.
+	*/
+	immap->im_siu_conf.sc_sdcr = 1;
+
+	iic_init_done = 1;
+}
+
+/* Read from IIC.
+ * Caller provides device address, memory buffer, and byte count.
+ */
+static	u_char	iitemp[32];
+
+void
+iic_read(uint devaddr, u_char *buf, uint offset, uint count)
+{
+	volatile iic_t		*iip;
+	volatile i2c8xx_t	*i2c;
+	volatile cbd_t		*tbdf, *rbdf;
+	volatile cpm8xx_t	*cp;
+	volatile immap_t	*immap;
+	u_char			*tb;
+	uint			temp;
+
+	/* If the interface has not been initialized, do that now.
+	*/
+	if (!iic_init_done)
+		iic_init();
+
+	immap = (immap_t *)IMAP_ADDR;
+	cp = (cpm8xx_t *)&(immap->im_cpm);
+
+	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
+	i2c = (i2c8xx_t *)&(immap->im_i2c);
+
+	tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
+	rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
+
+	/* Send a "dummy write" operation.  This is a write request with
+	 * only the offset sent, followed by another start condition.
+	 * This will ensure we start reading from the first location
+	 * of the EEPROM.
+	 */
+	tb = iitemp;
+	tb = (u_char *)(((uint)tb + 15) & ~15);
+	tbdf->cbd_bufaddr = (int)tb;
+	*tb = devaddr & 0xfe;	/* Device address */
+	*(tb+1) = offset;		/* Offset */
+	tbdf->cbd_datlen = 2;		/* Length */
+	tbdf->cbd_sc =
+	      BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
+
+	i2c->i2c_i2mod = 1;	/* Enable */
+	i2c->i2c_i2cer = 0xff;
+	i2c->i2c_i2com = 0x81;	/* Start master */
+
+	/* Wait for IIC transfer.
+	*/
+#if 0
+	while ((i2c->i2c_i2cer & 3) == 0);
+
+	if (tbdf->cbd_sc & BD_SC_READY)
+		printf("IIC ra complete but tbuf ready\n");
+#else
+	temp = 10000000;
+	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
+		temp--;
+#if 0
+	/* We can't do this...there is no serial port yet!
+	*/
+	if (temp == 0) {
+		printf("Timeout reading EEPROM\n");
+		return;
+	}
+#endif
+#endif
+	
+	/* Chip errata, clear enable.
+	*/
+	i2c->i2c_i2mod = 0;
+
+	/* To read, we need an empty buffer of the proper length.
+	 * All that is used is the first byte for address, the remainder
+	 * is just used for timing (and doesn't really have to exist).
+	 */
+	tbdf->cbd_bufaddr = (int)tb;
+	*tb = devaddr | 1;	/* Device address */
+	rbdf->cbd_bufaddr = (uint)buf;		/* Desination buffer */
+	tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1;	/* Length */
+	tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
+	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+
+	/* Chip bug, set enable here.
+	*/
+	i2c->i2c_i2mod = 1;	/* Enable */
+	i2c->i2c_i2cer = 0xff;
+	i2c->i2c_i2com = 0x81;	/* Start master */
+
+	/* Wait for IIC transfer.
+	*/
+#if 0
+	while ((i2c->i2c_i2cer & 1) == 0);
+
+	if (rbdf->cbd_sc & BD_SC_EMPTY)
+		printf("IIC read complete but rbuf empty\n");
+#else
+	temp = 10000000;
+	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
+		temp--;
+#endif
+	
+	/* Chip errata, clear enable.
+	*/
+	i2c->i2c_i2mod = 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/legacy.S linux/arch/ppc/boot/simple/legacy.S
--- linux.orig/arch/ppc/boot/simple/legacy.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/legacy.S	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,19 @@
+/*
+ * arch/ppc/boot/simple/legacy.S
+ *
+ * Author: Tom Rini <trini@mvista.com>
+ *
+ * This will go and setup ISA_io to 0x8000000 and return.
+ */
+
+#include "ppc_asm.h"
+
+	.text
+
+	.globl serial_fixups
+serial_fixups:
+	lis	r3,ISA_io@h	/* Load ISA_io */
+	ori	r3,r3,ISA_io@l
+	lis	r4,0x8000	/* Load the value, 0x8000000 */
+	stw	r4,0(r3)	/* store */
+	blr
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/m8260_tty.c linux/arch/ppc/boot/simple/m8260_tty.c
--- linux.orig/arch/ppc/boot/simple/m8260_tty.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/m8260_tty.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,323 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+
+
+/* Minimal serial functions needed to send messages out the serial
+ * port on SMC1.
+ */
+#include <linux/types.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm_8260.h>
+
+uint	no_print;
+extern char	*params[];
+extern int	nparams;
+static		u_char	cons_hold[128], *sgptr;
+static		int	cons_hold_cnt;
+
+/* If defined, enables serial console.  The value (1 through 4)
+ * should designate which SCC is used, but this isn't complete.  Only
+ * SCC1 is known to work at this time.
+ */
+#ifdef CONFIG_SCC_CONSOLE
+#define SCC_CONSOLE 1
+#endif
+
+unsigned long
+serial_init(int ignored, bd_t *bd)
+{
+	volatile smc_t		*sp;
+	volatile smc_uart_t	*up;
+#ifdef SCC_CONSOLE
+	volatile scc_t		*sccp;
+	volatile scc_uart_t	*sup;
+#endif
+	volatile cbd_t	*tbdf, *rbdf;
+	volatile immap_t	*ip;
+	volatile iop8260_t	*io;
+	volatile cpm8260_t	*cp;
+	uint	dpaddr, memaddr;
+
+	ip = (immap_t *)IMAP_ADDR;
+	cp = &ip->im_cpm;
+	io = &ip->im_ioport;
+
+	/* Perform a reset.
+	*/
+	cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
+
+	/* Wait for it.
+	*/
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+#ifdef CONFIG_ADS8260
+	/* Enable the RS-232 transceivers.
+	*/
+	*(volatile uint *)(BCSR_ADDR + 4) &=
+					~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2);
+#endif
+
+#ifdef SCC_CONSOLE
+	sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]);
+	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+	sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
+	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	/* Use Port D for SCC1 instead of other functions.
+	*/
+	io->iop_ppard |= 0x00000003;
+	io->iop_psord &= ~0x00000001;	/* Rx */
+	io->iop_psord |= 0x00000002;	/* Tx */
+	io->iop_pdird &= ~0x00000001;	/* Rx */
+	io->iop_pdird |= 0x00000002;	/* Tx */
+
+#else
+	sp = (smc_t*)&(ip->im_smc[0]);
+	*(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+	up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1];
+
+	/* Disable transmitter/receiver.
+	*/
+	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+	/* Use Port D for SMC1 instead of other functions.
+	*/
+	io->iop_ppard |= 0x00c00000;
+	io->iop_pdird |= 0x00400000;
+	io->iop_pdird &= ~0x00800000;
+	io->iop_psord &= ~0x00c00000;
+#endif
+
+	/* Allocate space for two buffer descriptors in the DP ram.
+	 * For now, this address seems OK, but it may have to
+	 * change with newer versions of the firmware.
+	 */
+	dpaddr = 0x0800;
+
+	/* Grab a few bytes from the top of memory.
+	 */
+	memaddr = (bd->bi_memsize - 256) & ~15;
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+	rbdf = (cbd_t *)&ip->im_dprambase[dpaddr];
+	rbdf->cbd_bufaddr = memaddr;
+	rbdf->cbd_sc = 0;
+	tbdf = rbdf + 1;
+	tbdf->cbd_bufaddr = memaddr+128;
+	tbdf->cbd_sc = 0;
+
+	/* Set up the uart parameters in the parameter ram.
+	*/
+#ifdef SCC_CONSOLE
+	sup->scc_genscc.scc_rbase = dpaddr;
+	sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t);
+
+	/* Set up the uart parameters in the
+	 * parameter ram.
+	 */
+	sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB;
+	sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB;
+
+	sup->scc_genscc.scc_mrblr = 128;
+	sup->scc_maxidl = 8;
+	sup->scc_brkcr = 1;
+	sup->scc_parec = 0;
+	sup->scc_frmec = 0;
+	sup->scc_nosec = 0;
+	sup->scc_brkec = 0;
+	sup->scc_uaddr1 = 0;
+	sup->scc_uaddr2 = 0;
+	sup->scc_toseq = 0;
+	sup->scc_char1 = 0x8000;
+	sup->scc_char2 = 0x8000;
+	sup->scc_char3 = 0x8000;
+	sup->scc_char4 = 0x8000;
+	sup->scc_char5 = 0x8000;
+	sup->scc_char6 = 0x8000;
+	sup->scc_char7 = 0x8000;
+	sup->scc_char8 = 0x8000;
+	sup->scc_rccm = 0xc0ff;
+
+	/* Send the CPM an initialize command.
+	*/
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0,
+			CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Set UART mode, 8 bit, no parity, one stop.
+	 * Enable receive and transmit.
+	 */
+	sccp->scc_gsmrh = 0;
+	sccp->scc_gsmrl =
+		(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+	/* Disable all interrupts and clear all pending
+	 * events.
+	 */
+	sccp->scc_sccm = 0;
+	sccp->scc_scce = 0xffff;
+	sccp->scc_dsr = 0x7e7e;
+	sccp->scc_pmsr = 0x3000;
+
+	/* Wire BRG1 to SCC1.  The console driver will take care of
+	 * others.
+	 */
+	ip->im_cpmux.cmx_scr = 0;
+#else
+	up->smc_rbase = dpaddr;
+	up->smc_tbase = dpaddr+sizeof(cbd_t);
+	up->smc_rfcr = CPMFCR_EB;
+	up->smc_tfcr = CPMFCR_EB;
+	up->smc_brklen = 0;
+	up->smc_brkec = 0;
+	up->smc_brkcr = 0;
+	up->smc_mrblr = 128;
+	up->smc_maxidl = 8;
+
+	/* Set UART mode, 8 bit, no parity, one stop.
+	 * Enable receive and transmit.
+	 */
+	sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+	/* Mask all interrupts and remove anything pending.
+	*/
+	sp->smc_smcm = 0;
+	sp->smc_smce = 0xff;
+
+	/* Set up the baud rate generator.
+	 */
+	ip->im_cpmux.cmx_smr = 0;
+#endif
+
+	/* The baud rate divisor needs to be coordinated with clk_8260().
+	*/
+	ip->im_brgc1 =
+		(((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) |
+								CPM_BRG_EN;
+
+	/* Make the first buffer the only buffer.
+	*/
+	tbdf->cbd_sc |= BD_SC_WRAP;
+	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+	/* Initialize Tx/Rx parameters.
+	*/
+#ifdef SCC_CONSOLE
+	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#else
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Enable transmitter/receiver.
+	*/
+	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+#endif
+
+	/* This is ignored.
+	*/
+	return 0;
+}
+
+int
+serial_readbuf(u_char *cbuf)
+{
+	volatile cbd_t		*rbdf;
+	volatile char		*buf;
+	volatile smc_uart_t	*up;
+	volatile scc_uart_t	*sup;
+	volatile immap_t	*ip;
+	int	i, nc;
+
+	ip = (immap_t *)IMAP_ADDR;
+
+#ifdef SCC_CONSOLE
+	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+	rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase];
+#else
+	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+	rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
+#endif
+
+	/* Wait for character to show up.
+	*/
+	buf = (char *)rbdf->cbd_bufaddr;
+	while (rbdf->cbd_sc & BD_SC_EMPTY);
+	nc = rbdf->cbd_datlen;
+	for (i=0; i<nc; i++)
+		*cbuf++ = *buf++;
+	rbdf->cbd_sc |= BD_SC_EMPTY;
+
+	return(nc);
+}
+
+void
+serial_putc(void *ignored, const char c)
+{
+	volatile cbd_t		*tbdf;
+	volatile char		*buf;
+	volatile smc_uart_t	*up;
+	volatile scc_uart_t	*sup;
+	volatile immap_t	*ip;
+	extern bd_t		*board_info;
+
+	ip = (immap_t *)IMAP_ADDR;
+#ifdef SCC_CONSOLE
+	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+	tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase];
+#else
+	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+	tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase];
+#endif
+
+	/* Wait for last character to go.
+	*/
+	buf = (char *)tbdf->cbd_bufaddr;
+	while (tbdf->cbd_sc & BD_SC_READY);
+
+	*buf = c;
+	tbdf->cbd_datlen = 1;
+	tbdf->cbd_sc |= BD_SC_READY;
+}
+
+char
+serial_getc(void *ignored)
+{
+	char	c;
+
+	if (cons_hold_cnt <= 0) {
+		cons_hold_cnt = serial_readbuf(cons_hold);
+		sgptr = cons_hold;
+	}
+	c = *sgptr++;
+	cons_hold_cnt--;
+
+	return(c);
+}
+
+int
+serial_tstc(void *ignored)
+{
+	volatile cbd_t		*rbdf;
+	volatile smc_uart_t	*up;
+	volatile scc_uart_t	*sup;
+	volatile immap_t	*ip;
+
+	ip = (immap_t *)IMAP_ADDR;
+#ifdef SCC_CONSOLE
+	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+	rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase];
+#else
+	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+	rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
+#endif
+
+	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+}
+
+void
+serial_close(unsigned long com_port)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/m8xx_tty.c linux/arch/ppc/boot/simple/m8xx_tty.c
--- linux.orig/arch/ppc/boot/simple/m8xx_tty.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/m8xx_tty.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,300 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+
+
+/* Minimal serial functions needed to send messages out the serial
+ * port on the MBX console.
+ *
+ * The MBX uxes SMC1 for the serial port.  We reset the port and use
+ * only the first BD that EPPC-Bug set up as a character FIFO.
+ *
+ * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
+ * use COM1 instead of SMC1 as the console port.  This kinda sucks
+ * for the rest of the kernel, so here we force the use of SMC1 again.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+
+#ifdef CONFIG_MBX
+#define MBX_CSR1	((volatile u_char *)0xfa100000)
+#define CSR1_COMEN	(u_char)0x02
+#endif
+
+#ifdef TQM_SMC2_CONSOLE
+#define PROFF_CONS	PROFF_SMC2
+#define CPM_CR_CH_CONS	CPM_CR_CH_SMC2
+#define SMC_INDEX	1
+static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport);
+#else
+#define PROFF_CONS	PROFF_SMC1
+#define CPM_CR_CH_CONS	CPM_CR_CH_SMC1
+#define SMC_INDEX	0
+#endif
+
+static cpm8xx_t	*cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+
+unsigned long
+serial_init(int ignored, bd_t *bd)
+{
+	volatile smc_t		*sp;
+	volatile smc_uart_t	*up;
+	volatile cbd_t	*tbdf, *rbdf;
+	volatile cpm8xx_t	*cp;
+	uint	dpaddr, memaddr;
+#ifndef CONFIG_MBX
+	uint	ui;
+#endif
+
+	cp = cpmp;
+	sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]);
+	up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS];
+
+	/* Disable transmitter/receiver.
+	*/
+	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+#ifdef CONFIG_FADS
+	/* Enable SMC1/2 transceivers.
+	*/
+	*((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2);
+#endif
+
+#ifndef CONFIG_MBX
+	{
+	/* Initialize SMCx and use it for the console port.
+	 */
+
+	/* Enable SDMA.
+	*/
+	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
+
+#ifdef TQM_SMC2_CONSOLE
+	/* Use Port A for SMC2 instead of other functions.
+	*/
+	iopp->iop_papar |=  0x00c0;
+	iopp->iop_padir &= ~0x00c0;
+	iopp->iop_paodr &= ~0x00c0;
+#else
+	/* Use Port B for SMCs instead of other functions.
+	*/
+	cp->cp_pbpar |= 0x00000cc0;
+	cp->cp_pbdir &= ~0x00000cc0;
+	cp->cp_pbodr &= ~0x00000cc0;
+#endif
+
+	/* Allocate space for two buffer descriptors in the DP ram.
+	 * For now, this address seems OK, but it may have to
+	 * change with newer versions of the firmware.
+	 */
+	dpaddr = 0x0800;
+
+	/* Grab a few bytes from the top of memory for SMC FIFOs.
+	 */
+	memaddr = (bd->bi_memsize - 32) & ~15;
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+	rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
+	rbdf->cbd_bufaddr = memaddr;
+	rbdf->cbd_sc = 0;
+	tbdf = rbdf + 1;
+	tbdf->cbd_bufaddr = memaddr+4;
+	tbdf->cbd_sc = 0;
+
+	/* Set up the uart parameters in the parameter ram.
+	*/
+	up->smc_rbase = dpaddr;
+	up->smc_tbase = dpaddr+sizeof(cbd_t);
+	up->smc_rfcr = SMC_EB;
+	up->smc_tfcr = SMC_EB;
+
+	/* Set UART mode, 8 bit, no parity, one stop.
+	 * Enable receive and transmit.
+	 */
+	sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+	/* Mask all interrupts and remove anything pending.
+	*/
+	sp->smc_smcm = 0;
+	sp->smc_smce = 0xff;
+
+	/* Set up the baud rate generator.
+	 * See 8xx_io/commproc.c for details.
+	 * This wires BRG1 to SMC1 and BRG2 to SMC2;
+	 */
+	cp->cp_simode = 0x10000000;
+	ui = bd->bi_intfreq / 16 / bd->bi_baudrate;
+#ifdef TQM_SMC2_CONSOLE
+	cp->cp_brgc2 =
+#else
+	cp->cp_brgc1 =
+#endif
+		((ui - 1) < 4096)
+		? (((ui - 1) << 1) | CPM_BRG_EN)
+		: ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16);
+
+#else /* CONFIG_MBX */
+	if (*MBX_CSR1 & CSR1_COMEN) {
+		/* COM1 is enabled.  Initialize SMC1 and use it for
+		 * the console port.
+		 */
+
+		/* Enable SDMA.
+		*/
+		((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
+
+		/* Use Port B for SMCs instead of other functions.
+		*/
+		cp->cp_pbpar |= 0x00000cc0;
+		cp->cp_pbdir &= ~0x00000cc0;
+		cp->cp_pbodr &= ~0x00000cc0;
+
+		/* Allocate space for two buffer descriptors in the DP ram.
+		 * For now, this address seems OK, but it may have to
+		 * change with newer versions of the firmware.
+		 */
+		dpaddr = 0x0800;
+
+		/* Grab a few bytes from the top of memory.  EPPC-Bug isn't
+		 * running any more, so we can do this.
+		 */
+		memaddr = (bd->bi_memsize - 32) & ~15;
+
+		/* Set the physical address of the host memory buffers in
+		 * the buffer descriptors.
+		 */
+		rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
+		rbdf->cbd_bufaddr = memaddr;
+		rbdf->cbd_sc = 0;
+		tbdf = rbdf + 1;
+		tbdf->cbd_bufaddr = memaddr+4;
+		tbdf->cbd_sc = 0;
+
+		/* Set up the uart parameters in the parameter ram.
+		*/
+		up->smc_rbase = dpaddr;
+		up->smc_tbase = dpaddr+sizeof(cbd_t);
+		up->smc_rfcr = SMC_EB;
+		up->smc_tfcr = SMC_EB;
+
+		/* Set UART mode, 8 bit, no parity, one stop.
+		 * Enable receive and transmit.
+		 */
+		sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+		/* Mask all interrupts and remove anything pending.
+		*/
+		sp->smc_smcm = 0;
+		sp->smc_smce = 0xff;
+
+		/* Set up the baud rate generator.
+		 * See 8xx_io/commproc.c for details.
+		 */
+		cp->cp_simode = 0x10000000;
+		cp->cp_brgc1 =
+			(((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN;
+
+		/* Enable SMC1 for console output.
+		*/
+		*MBX_CSR1 &= ~CSR1_COMEN;
+	}
+	else {
+#endif /* ndef CONFIG_MBX */
+		/* SMCx is used as console port.
+		*/
+		tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];
+		rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];
+
+		/* Issue a stop transmit, and wait for it.
+		*/
+		cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS,
+					CPM_CR_STOP_TX) | CPM_CR_FLG;
+		while (cp->cp_cpcr & CPM_CR_FLG);
+	}
+
+	/* Make the first buffer the only buffer.
+	*/
+	tbdf->cbd_sc |= BD_SC_WRAP;
+	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+	/* Single character receive.
+	*/
+	up->smc_mrblr = 1;
+	up->smc_maxidl = 0;
+
+	/* Initialize Tx/Rx parameters.
+	*/
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Enable transmitter/receiver.
+	*/
+	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+
+	/* This is ignored.
+	*/
+	return 0;
+}
+
+void
+serial_putc(void *ignored, const char c)
+{
+	volatile cbd_t		*tbdf;
+	volatile char		*buf;
+	volatile smc_uart_t	*up;
+
+	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+	tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+
+	/* Wait for last character to go.
+	*/
+	buf = (char *)tbdf->cbd_bufaddr;
+	while (tbdf->cbd_sc & BD_SC_READY);
+
+	*buf = c;
+	tbdf->cbd_datlen = 1;
+	tbdf->cbd_sc |= BD_SC_READY;
+}
+
+char
+serial_getc(void *ignored)
+{
+	volatile cbd_t		*rbdf;
+	volatile char		*buf;
+	volatile smc_uart_t	*up;
+	char			c;
+
+	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+
+	/* Wait for character to show up.
+	*/
+	buf = (char *)rbdf->cbd_bufaddr;
+	while (rbdf->cbd_sc & BD_SC_EMPTY);
+	c = *buf;
+	rbdf->cbd_sc |= BD_SC_EMPTY;
+
+	return(c);
+}
+
+int
+serial_tstc(void *ignored)
+{
+	volatile cbd_t		*rbdf;
+	volatile smc_uart_t	*up;
+
+	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+
+	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+}
+
+void
+serial_close(unsigned long com_port)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/simple/misc-embedded.c linux/arch/ppc/boot/simple/misc-embedded.c
--- linux.orig/arch/ppc/boot/simple/misc-embedded.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/simple/misc-embedded.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,237 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ *
+ * Originally adapted by Gary Thomas.  Much additional work by
+ * Cort Dougan <cort@fsmlabs.com>.  On top of that still more work by
+ * Dan Malek <dmalek@jlc.net>.
+ *
+ * Currently maintained by: Tom Rini <trini@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/elf.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu.h>
+#include <asm/mpc8xx.h>
+#include <asm/mpc8260.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/residual.h>
+
+#include "nonstdio.h"
+#include "zlib.h"
+
+/* The linker tells us where the image is. */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin, __ramdisk_end;
+extern char _end[];
+
+/* Because of the limited amount of memory on embedded, it presents
+ * loading problems.  The biggest is that we load this boot program
+ * into a relatively low memory address, and the Linux kernel Bss often
+ * extends into this space when it get loaded.  When the kernel starts
+ * and zeros the BSS space, it also writes over the information we
+ * save here and pass to the kernel (usually board info).
+ * On these boards, we grab some known memory holes to hold this information.
+ */
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
+char *avail_ram;
+char *end_avail;
+char *zimage_start;
+
+/* This is for 4xx treeboot.  It provides a place for the bootrom
+ * give us a pointer to a rom environment command line.
+ */
+char *bootrom_cmdline = "";
+
+/* This is the default cmdline that will be given to the user at boot time..
+ * If none was specified at compile time, we'll give it one that should work.
+ * -- Tom */
+#ifdef CONFIG_CMDLINE_BOOL
+char compiled_string[] = CONFIG_CMDLINE;
+#endif
+char ramroot_string[] = "root=/dev/ram";
+char netroot_string[] = "root=/dev/nfs rw ip=auto";
+
+/* Serial port to use. */
+unsigned long com_port;
+
+/* We need to make sure that this is before the images to ensure
+ * that it's in a mapped location. - Tom */
+bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
+bd_t *hold_residual = &hold_resid_buf;
+
+extern unsigned long serial_init(int chan, bd_t *bp);
+extern void serial_close(unsigned long com_port);
+extern unsigned long start;
+extern void flush_instruction_cache(void);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void embed_config(bd_t **bp);
+
+unsigned long
+decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp)
+{
+	char *cp, ch;
+	int timer = 0, zimage_size;
+	unsigned long initrd_size;
+
+	/* First, capture the embedded board information.  Then
+	 * initialize the serial console port.
+	 */
+	embed_config(&bp);
+#ifdef CONFIG_SERIAL_CONSOLE
+	com_port = serial_init(0, bp);
+#endif
+
+	/* copy board data */
+	if (bp)
+		memcpy(hold_residual,bp,sizeof(bd_t));
+
+	/* Set end of memory available to us.  It is always the highest
+	 * memory address provided by the board information.
+	 */
+	end_avail = (char *)(bp->bi_memsize);
+
+	puts("\nloaded at:     "); puthex(load_addr);
+	puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
+	if ( (unsigned long)load_addr != (unsigned long)&start ) {
+		puts("relocated to:  "); puthex((unsigned long)&start);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)&start + (4*num_words)));
+		puts("\n");
+	}
+
+	if ( bp ) {
+		puts("board data at: "); puthex((unsigned long)bp);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)bp + sizeof(bd_t)));
+		puts("\nrelocated to:  ");
+		puthex((unsigned long)hold_residual);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t)));
+		puts("\n");
+	}
+
+	/*
+	 * We link ourself to an arbitrary low address.  When we run, we
+	 * relocate outself to that address.  __image_being points to
+	 * the part of the image where the zImage is. -- Tom
+	 */
+	zimage_start = (char *)(unsigned long)(&__image_begin);
+	zimage_size = (unsigned long)(&__image_end) -
+			(unsigned long)(&__image_begin);
+
+	initrd_size = (unsigned long)(&__ramdisk_end) -
+		(unsigned long)(&__ramdisk_begin);
+
+	/*
+	 * The zImage and initrd will be between start and _end, so they've
+	 * already been moved once.  We're good to go now. -- Tom
+	 */
+	puts("zimage at:     "); puthex((unsigned long)zimage_start);
+	puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
+	puts("\n");
+
+	if ( initrd_size ) {
+		puts("initrd at:     ");
+		puthex((unsigned long)(&__ramdisk_begin));
+		puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
+	}
+
+	/*
+	 * setup avail_ram - this is the first part of ram usable
+	 * by the uncompress code.  Anything after this program in RAM
+	 * is now fair game. -- Tom
+	 */
+	avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
+
+	puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
+	puthex((unsigned long)end_avail); puts("\n");
+	puts("\nLinux/PPC load: ");
+	cp = cmd_line;
+	/* This is where we try and pick the right command line for booting.
+	 * If we were given one at compile time, use it.  It Is Right.
+	 * If we weren't, see if we have a ramdisk.  If so, thats root.
+	 * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom
+	 */
+#ifdef CONFIG_CMDLINE_BOOL
+	memcpy (cmd_line, compiled_string, sizeof(compiled_string));
+#else
+	if ( initrd_size )
+		memcpy (cmd_line, ramroot_string, sizeof(ramroot_string));
+	else
+		memcpy (cmd_line, netroot_string, sizeof(netroot_string));
+#endif
+	while ( *cp )
+		putc(*cp++);
+	while (timer++ < 5*1000) {
+		if (tstc()) {
+			while ((ch = getc()) != '\n' && ch != '\r') {
+				if (ch == '\b' || ch == '\177') {
+					if (cp != cmd_line) {
+						cp--;
+						puts("\b \b");
+					}
+				} else if (ch == '\030'		/* ^x */
+					   || ch == '\025') {	/* ^u */
+					while (cp != cmd_line) {
+						cp--;
+						puts("\b \b");
+					}
+				} else {
+					*cp++ = ch;
+					putc(ch);
+				}
+			}
+			break;  /* Exit 'timer' loop */
+		}
+		udelay(1000);  /* 1 msec */
+	}
+	*cp = 0;
+	puts("\nUncompressing Linux...");
+
+	gunzip(0, 0x400000, zimage_start, &zimage_size);
+	flush_instruction_cache();
+	puts("done.\n");
+	{
+		struct bi_record *rec;
+
+		rec = (struct bi_record *)_ALIGN((unsigned long)zimage_size +
+				(1 << 20) - 1,(1 << 20));
+
+		rec->tag = BI_FIRST;
+		rec->size = sizeof(struct bi_record);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+		rec->tag = BI_CMD_LINE;
+		memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
+		rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+		if ( initrd_size ) {
+			rec->tag = BI_INITRD;
+			rec->data[0] = (unsigned long)(&__ramdisk_begin);
+			rec->data[1] = initrd_size;
+			rec->size = sizeof(struct bi_record) + 2 *
+				sizeof(unsigned long);
+			rec = (struct bi_record *)((unsigned long)rec +
+					rec->size);
+		}
+
+		rec->tag = BI_LAST;
+		rec->size = sizeof(struct bi_record);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	}
+	puts("Now booting the kernel\n");
+	serial_close(com_port);
+
+	return (unsigned long)hold_residual;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/tree/Makefile linux/arch/ppc/boot/tree/Makefile
--- linux.orig/arch/ppc/boot/tree/Makefile	2001-07-02 21:34:57.000000000 +0000
+++ linux/arch/ppc/boot/tree/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,66 +0,0 @@
-# BK Id: SCCS/s.Makefile 1.7 06/15/01 13:16:10 paulus
-#
-#
-#    Module name: Makefile
-#
-#    Description:
-#      Makefile for the IBM "tree" evaluation board Linux kernel
-#      boot loaders.
-#
-#
-#    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
-# 
-#    PPC-405 modification
-#    	Copyright 2000-2001 MontaVista Software Inc.
-#    	Author: MontaVista Software, Inc.
-#          	frank_rowand@mvista.com or source@mvista.com
-#  	   	debbie_chu@mvista.com
-# 
-
-HOSTCFLAGS = -O -I$(TOPDIR)/include
-
-CC      = $(CROSS_COMPILE)gcc
-LD      = $(CROSS_COMPILE)ld
-OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJDUMP = $(CROSS_COMPILE)objdump
-
-GZIP	= gzip -vf9
-RM	= rm -f
-MKEVIMG	= ../utils/mkevimg -l -c
-MKIRIMG	= ../utils/mkirimg
-CFLAGS	+= -I$(TOPDIR)/drivers/net
-LD_ARGS = -e _start -T ld.script -Ttext 0x00200000 -Bstatic
-
-OBJS	= ../common/crt0.o main.o misc.o irSect.o ../common/string.o \
-		../common/misc-common.o ../common/ns16550.o
-LIBS	= ../lib/zlib.a
-
-treeboot: $(OBJS) $(LIBS) ld.script
-	$(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS)
-
-zImage:	vmlinux.img
-
-zImage.initrd: vmlinux.initrd.img
-
-treeboot.image: treeboot
-	$(OBJCOPY) --add-section=image=../images/vmlinux.gz treeboot $@
-
-treeboot.initrd: treeboot.image ramdisk.image.gz
-	$(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@
-
-vmlinux.img: treeboot.image
-	$(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt
-	$(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt
-	$(MKEVIMG) treeboot.image.out ../images/vmlinux.tree.img
-	$(RM) treeboot.image treeboot.image.out irSectStart.txt
-
-vmlinux.initrd.img: treeboot.initrd
-	$(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt
-	$(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt
-	$(MKEVIMG) treeboot.initrd.out ../images/vmlinux.tree.initrd.img
-	$(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt
-
-clean:
-	rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.*
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/tree/irSect.c linux/arch/ppc/boot/tree/irSect.c
--- linux.orig/arch/ppc/boot/tree/irSect.c	2001-05-24 22:02:07.000000000 +0000
+++ linux/arch/ppc/boot/tree/irSect.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,39 +0,0 @@
-/*
- * BK Id: SCCS/s.irSect.c 1.6 05/18/01 15:17:22 cort
- */
-/*
- *
- *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- *
- *    Module name: irSect.c
- *
- *    Description:
- *      Defines variables to hold the absolute starting address and size
- *      of the Linux kernel "image" and the initial RAM disk "initrd"
- *      sections within the boot loader.
- *
- */
-
-#include "irSect.h"
-
-
-/*
- * The order of globals below must not change. If more globals are added,
- * you must change the script 'mkirimg' accordingly.
- *
- */
-
-/* 
- * irSectStart must be at beginning of file 
- */
-unsigned int irSectStart = 0xdeadbeaf;
-
-unsigned int imageSect_start	= 0;
-unsigned int imageSect_size	= 0;
-unsigned int initrdSect_start	= 0;
-unsigned int initrdSect_size	= 0;
-
-/* 
- * irSectEnd must be at end of file 
- */
-unsigned int irSectEnd   = 0xdeadbeaf;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/tree/irSect.h linux/arch/ppc/boot/tree/irSect.h
--- linux.orig/arch/ppc/boot/tree/irSect.h	2001-05-24 22:02:07.000000000 +0000
+++ linux/arch/ppc/boot/tree/irSect.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,35 +0,0 @@
-/*
- * BK Id: SCCS/s.irSect.h 1.6 05/18/01 15:17:22 cort
- */
-/*
- *
- *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- *
- *    Module name: irSect.h
- *    
- *    Description:
- *      Defines variables to hold the absolute starting address and size
- *      of the Linux kernel "image" and the initial RAM disk "initrd"   
- *      sections within the boot loader.
- *      
- */
-
-#ifndef __IRSECT_H__
-#define __IRSECT_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern unsigned int imageSect_start;
-extern unsigned int imageSect_size;
-
-extern unsigned int initrdSect_start;
-extern unsigned int initrdSect_size;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __IRSECT_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/tree/ld.script linux/arch/ppc/boot/tree/ld.script
--- linux.orig/arch/ppc/boot/tree/ld.script	2001-07-02 21:40:58.000000000 +0000
+++ linux/arch/ppc/boot/tree/ld.script	1970-01-01 00:00:00.000000000 +0000
@@ -1,69 +0,0 @@
-OUTPUT_ARCH(powerpc)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
-/* Do we need any of these for elf?
-   __DYNAMIC = 0;    */
-SECTIONS
-{
-  /* Read-only sections, merged into text segment: */
-  . = + SIZEOF_HEADERS;
-  .interp : { *(.interp) }
-  .hash          : { *(.hash)		}
-  .dynsym        : { *(.dynsym)		}
-  .dynstr        : { *(.dynstr)		}
-  .rel.text      : { *(.rel.text)		}
-  .rela.text     : { *(.rela.text) 	}
-  .rel.data      : { *(.rel.data)		}
-  .rela.data     : { *(.rela.data) 	}
-  .rel.rodata    : { *(.rel.rodata) 	}
-  .rela.rodata   : { *(.rela.rodata) 	}
-  .rel.got       : { *(.rel.got)		}
-  .rela.got      : { *(.rela.got)		}
-  .rel.ctors     : { *(.rel.ctors)	}
-  .rela.ctors    : { *(.rela.ctors)	}
-  .rel.dtors     : { *(.rel.dtors)	}
-  .rela.dtors    : { *(.rela.dtors)	}
-  .rel.bss       : { *(.rel.bss)		}
-  .rela.bss      : { *(.rela.bss)		}
-  .rel.plt       : { *(.rel.plt)		}
-  .rela.plt      : { *(.rela.plt)		}
-  .init          : { *(.init)	} =0
-  .plt : { *(.plt) }
-  .text      :
-  {
-    *(.text)
-    *(.rodata)
-    *(.rodata.*)
-    *(.rodata1)
-    *(.got1)
-  }
-  .fini      : { *(.fini)    } =0
-  .ctors     : { *(.ctors)   }
-  .dtors     : { *(.dtors)   }
-  _etext = .;
-  PROVIDE (etext = .);
-  /* Read-write section, merged into data segment: */
-  . = (. + 0x0FFF) & 0xFFFFF000;
-  .data    :
-  {
-    *(.data)
-    *(.data1)
-    *(.sdata)
-    *(.sdata2)
-    *(.got.plt) *(.got)
-    *(.dynamic)
-    CONSTRUCTORS
-  }
-  _edata  =  .;
-  PROVIDE (edata = .);
-  __bss_start = .;
-  .bss       :
-  {
-   *(.sbss) *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-  }
-  _end = . ;
-  PROVIDE (end = .);
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/tree/main.c linux/arch/ppc/boot/tree/main.c
--- linux.orig/arch/ppc/boot/tree/main.c	2001-07-02 21:34:57.000000000 +0000
+++ linux/arch/ppc/boot/tree/main.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,212 +0,0 @@
-/*
- * BK Id: SCCS/s.main.c 1.9 06/15/01 13:16:10 paulus
- */
-/*
- *    Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
- *      Initial Power Macintosh COFF version.
- *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- *      Modifications for an ELF-based IBM evaluation board version.
- *    Copyright 2000-2001 MontaVista Software Inc.
- *	PPC405GP modifications
- * 	Author: MontaVista Software, Inc.
- *         	frank_rowand@mvista.com or source@mvista.com
- * 	   	debbie_chu@mvista.com
- *
- *    Module name: main.c
- *
- *    Description:
- *      This module does most of the real work for the boot loader. It
- *      checks the variables holding the absolute start address and size
- *      of the Linux kernel "image" and initial RAM disk "initrd" sections
- *      and if they are present, moves them to their "proper" locations.
- *
- *      For the Linux kernel, "proper" is physical address 0x00000000.
- *      For the RAM disk, "proper" is the image's size below the top
- *      of physical memory. The Linux kernel may be in either raw
- *      binary form or compressed with GNU zip (aka gzip).
- *
- *    This program is free software; you can redistribute it and/or
- *    modify it under the terms of the GNU General Public License 
- *    as published by the Free Software Foundation; either version
- *    2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <asm/ppc4xx.h>
-
-#include "nonstdio.h"
-#include "irSect.h"
-#if defined(CONFIG_SERIAL_CONSOLE)
-#include "ns16550.h"
-#endif /* CONFIG_SERIAL_CONSOLE */
-
-
-/* Preprocessor Defines */
-
-/*
- * Location of the IBM boot ROM function pointer address for retrieving
- * the board information structure.
- */
-
-#define	BOARD_INFO_VECTOR	0xFFFE0B50
-
-/* 
- * Warning: the board_info doesn't contain valid data until get_board_info() 
- * 	    gets called in start().
- */
-#define RAM_SIZE        board_info.bi_memsize 
-
-#define	RAM_PBASE	0x00000000
-#define	RAM_PEND	(RAM_PBASE + RAM_SIZE)
-
-#define	RAM_VBASE	0xC0000000
-#define	RAM_VEND	(RAM_VBASE + RAM_SIZE)
-
-#define	RAM_START	RAM_PBASE
-#define	RAM_END		RAM_PEND
-#define	RAM_FREE	(imageSect_start + imageSect_size + initrdSect_size)
-
-#define	PROG_START	RAM_START
-
-
-/* Function Macros */
-
-#define	ALIGN_UP(x, align)	(((x) + ((align) - 1)) & ~((align) - 1))
-
-/* Global Variables */
-
-/* Needed by zalloc and zfree for allocating memory */
-
-char *avail_ram;	/* Indicates start of RAM available for heap */
-char *end_avail;	/* Indicates end of RAM available for heap */
-
-/* Needed for serial I/O.
-*/
-extern unsigned long *com_port;
-
-bd_t	board_info;
-
-/*
-** The bootrom may change bootrom_cmdline to point to a buffer in the
-** bootrom.
-*/
-char *bootrom_cmdline = "";
-char treeboot_bootrom_cmdline[512];
-
-#ifdef CONFIG_CMDLINE
-char *cmdline = CONFIG_CMDLINE;
-#else
-char *cmdline = "";
-#endif
-
-/* Function Prototypes */
-
-extern void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp);
-
-void
-kick_watchdog(void)
-{
-#ifdef CONFIG_405GP
-    mtspr(SPRN_TSR, (TSR_ENW | TSR_WIS));
-#endif
-}
-
-void start(void)
-{
-    void *options;
-    int ns, oh, i;
-    unsigned long sa, len;
-    void *dst;
-    unsigned char *im;
-    unsigned long initrd_start, initrd_size;
-    bd_t *(*get_board_info)(void) = 
-	    (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
-    bd_t *bip = NULL;
-
-
-    com_port = (struct NS16550 *)serial_init(0);
-
-#ifdef CONFIG_405GP
-    /* turn off on-chip ethernet */
-    /* This is to fix a problem with early walnut bootrom. */
- 
-    {
-	/* Physical mapping of ethernet register space. */
-	static struct   ppc405_enet_regs *ppc405_enet_regp =
-	(struct ppc405_enet_regs *)PPC405_EM0_REG_ADDR;
-
-	mtdcr(DCRN_MALCR, MALCR_MMSR);                /* 1st reset MAL */
-
-	while (mfdcr(DCRN_MALCR) & MALCR_MMSR) {};    /* wait for the reset */
-    
-	ppc405_enet_regp->em0mr0 = 0x20000000;        /* then reset EMAC */
-    }
-#endif
-
-    if ((bip = get_board_info()) != NULL)
-	    memcpy(&board_info, bip, sizeof(bd_t));
-
-    /* Init RAM disk (initrd) section */
-
-    kick_watchdog();
-
-    if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) {
-        initrd_start = (RAM_END - initrd_size) & ~0xFFF;
-
-	_printk("Initial RAM disk at 0x%08x (%u bytes)\n",
-	       initrd_start, initrd_size);
-
-	memcpy((char *)initrd_start,
-	       (char *)(initrdSect_start),
-	       initrdSect_size);
-
-	end_avail = (char *)initrd_start;
-    } else {
-	initrd_start = initrd_size = 0;
-	end_avail = (char *)RAM_END;
-    }
-
-    /* Linux kernel image section */
-	
-    kick_watchdog();
-
-    im = (unsigned char *)(imageSect_start);
-    len = imageSect_size;
-    dst = (void *)PROG_START;
-
-    /* Check for the gzip archive magic numbers */
-
-    if (im[0] == 0x1f && im[1] == 0x8b) {
-
-        /* The gunzip routine needs everything nice and aligned */
-
-	void *cp = (void *)ALIGN_UP(RAM_FREE, 8);
-	avail_ram = (void *)(cp + ALIGN_UP(len, 8));	/* used by zalloc() */
-	memcpy(cp, im, len);
-
-	/* I'm not sure what the 0x200000 parameter is for, but it works. */
-	/* It tells gzip the end of the area you wish to reserve, and it
-	 * can use data past that point....unfortunately, this value
-	 * isn't big enough (luck ran out).  -- Dan
-	 */
-
-	gunzip(dst, 0x400000, cp, (int *)&len);
-    } else {
-	memmove(dst, im, len);
-    }
-
-    kick_watchdog();
-
-    flush_cache(dst, len);
-
-    sa = (unsigned long)dst;
-
-    (*(void (*)())sa)(&board_info,
-		      initrd_start,
-		      initrd_start + initrd_size,
-		      cmdline,
-		      cmdline + strlen(cmdline));
-
-    pause();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/tree/misc.S linux/arch/ppc/boot/tree/misc.S
--- linux.orig/arch/ppc/boot/tree/misc.S	2001-05-24 22:02:07.000000000 +0000
+++ linux/arch/ppc/boot/tree/misc.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,43 +0,0 @@
-/*
- * BK Id: SCCS/s.misc.S 1.7 05/18/01 06:20:29 patch
- */
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include "../../kernel/ppc_asm.tmpl"
-
-	.text
-
-/*
- * Flush the dcache and invalidate the icache for a range of addresses.
- *
- * flush_cache(addr, len)
- */
-	.global	flush_cache
-flush_cache:
-	mfpvr	r5			# Get processor version register
-	extrwi	r5,r5,16,0		# Get the version bits
-	cmpwi	cr0,r5,0x0020		# Is this a 403-based processor?
-	beq	1f			# Yes, it is
-	li	r5,32			# It is not a 403, set to 32 bytes
-	addi	r4,r4,32-1		# len += line_size - 1
-	srwi.	r4,r4,5			# Convert from bytes to lines
-	b	2f
-1:	li	r5,16			# It is a 403, set to 16 bytes
-	addi	r4,r4,16-1		# len += line_size - 1
-	srwi.	r4,r4,4			# Convert from bytes to lines
-2:	mtctr	r4			# Set-up the counter register
-	beqlr				# If it is 0, we are done
-3:	dcbf	r0,r3			# Flush and invalidate the data line
-	icbi	r0,r3			# Invalidate the instruction line
-	add	r3,r3,r5		# Move to the next line
-	bdnz	3b			# Are we done yet?
-	sync
-	isync
-	blr				# Return to the caller
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/Makefile linux/arch/ppc/boot/utils/Makefile
--- linux.orig/arch/ppc/boot/utils/Makefile	2001-07-18 14:14:01.000000000 +0000
+++ linux/arch/ppc/boot/utils/Makefile	2002-07-20 01:08:31.000000000 +0000
@@ -10,7 +10,7 @@
 all: dummy
 
 # Simple programs with 1 file and no extra CFLAGS
-UTILS = addnote hack-coff mkprep mksimage mknote piggyback mkpmon mkbugboot
+UTILS = addnote hack-coff mkprep mknote mktree
 
 $(UTILS):
 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $@.c
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/mkevimg linux/arch/ppc/boot/utils/mkevimg
--- linux.orig/arch/ppc/boot/utils/mkevimg	2001-07-02 21:34:57.000000000 +0000
+++ linux/arch/ppc/boot/utils/mkevimg	1970-01-01 00:00:00.000000000 +0000
@@ -1,488 +0,0 @@
-#!/usr/bin/perl
-
-#
-#    Copyright (c) 1998-1999 TiVo, Inc.
-#    All rights reserved.
-#
-#    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
-#      Major syntactic and usability rework.
-#
-#    Module name: mkevimg
-#
-#    Description:
-#      Converts an ELF output file from the linker into the format used by
-#      the IBM evaluation board ROM Monitor to load programs from a host
-#      onto the evaluation board. The ELF file must be an otherwise execut-
-#      able file (with the text and data addresses bound at link time) and
-#      have space reserved after the entry point for the load information
-#      block:
-#
-#      typedef struct boot_block {
-#        unsigned long magic;	        0x0052504F
-#	 unsigned long dest;	        Target address of the image
-#	 unsigned long num_512blocks;   Size, rounded-up, in 512 byte blocks
-#	 unsigned long debug_flag;      Run the debugger or image after load
-#        unsigned long entry_point;	The image address to jump to after load
-#	 unsigned long checksum; 	32 bit checksum including header
-#	 unsigned long reserved[2];
-#      } boot_block_t;
-#
-#   
-
-use File::Basename;
-use Getopt::Std;
-
-#
-# usage()
-#
-# Description:
-#   This routine prints out the proper command line usage for this program
-#
-# Input(s):
-#   status - Flag determining what usage information will be printed and what
-#            the exit status of the program will be after the information is
-#            printed.
-#
-# Output(s):
-#   N/A
-#
-# Returns:
-#   This subroutine does not return.
-#
-
-sub usage {
-  my($status);
-  $status = $_[0];
-
-  printf("Usage: %s [-hlvV] <ELF input file> <Evaluation board output file>\n",
-	$program);
-
-  if ($status != 0) {
-    printf("Try `%s -h' for more information.\n", $program);
-  }
-
-  if ($status != 1) {
-    print("  -c         Put checksum in load information block.\n");
-    print("  -h         Print out this message and exit.\n");
-    print("  -l         Linux mode; if present, copy 'image' and 'initrd' sections.\n");
-    print("  -v         Verbose. Print out lots of ELF information.\n");
-    print("  -V         Print out version information and exit.\n");
-  }
-
-  exit($status);
-}
-
-#
-# version()
-#
-# Description:
-#   This routine prints out program version information
-#
-# Input(s):
-#   N/A
-#
-# Output(s):
-#   N/A
-#
-# Returns:
-#   This subroutine does not return.
-#
-
-sub version {
-  print("mkevimg Version 1.1.0\n");
-  print("Copyright (c) 1998-1999 TiVo, Inc.\n");
-  print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
-
-  exit (0);
-}
-
-#
-# file_check()
-#
-# Description:
-#   This routine checks an input file to ensure that it exists, is a
-#   regular file, and is readable.
-#
-# Input(s):
-#   file - Input file to be checked.
-#
-# Output(s):
-#   N/A
-#
-# Returns:
-#   0 if the file exists, is a regular file, and is readable, otherwise -1.
-#
-
-sub file_check {
-  my($file);
-  $file = $_[0];
-
-  if (!(-e $file)) {
-    printf("The file \"%s\" does not exist.\n", $file);
-    return (-1);
-  } elsif (!(-f $file)) {
-    printf("The file \"%s\" is not a regular file.\n", $file);
-    return (-1);
-  } elsif (!(-r $file)) {
-    printf("The file \"%s\" is not readable.\n", $file);
-    return (-1);
-  }
-
-  return (0);
-}
-
-#
-# decode_options()
-#
-# Description:
-#   This routine steps through the command-line arguments, parsing out
-#   recognzied options.
-#
-# Input(s):
-#   N/A
-#
-# Output(s):
-#   N/A
-#
-# Returns:
-#   N/A
-#
-
-sub decode_options {
-
-  if (!getopts("chlvV")) {
-    usage(1);
-  }
-
-  if ($opt_c) {
-    $do_checksum = 1;
-  }
-
-  if ($opt_h) {
-    usage(0);
-  }
-
-  if ($opt_l) {
-    $linux = 1;
-  }
-
-  if ($opt_V) {
-    version();
-    exit (0);
-  }
-
-  if ($opt_v) {
-    $verbose = 1;
-  }
-
-  if (!($ifile = shift(@ARGV))) {
-    usage(1);
-  }
-
-  if (!($ofile = shift(@ARGV))) {
-    usage (1);
-  }
-
-  if (file_check($ifile)) {
-    exit(1);
-  }
-
-}
-
-#
-# ELF file and section header field numbers
-#
-
-require '../utils/elf.pl';
-
-#
-# Main program body
-#
-
-{
-  $program = basename($0);
-
-  decode_options();
-
-  open(ELF, "<$ifile") || die "Cannot open input file";
-
-  $ifilesize = (-s $ifile);
-
-  if ($verbose) {
-    print("Output file: $ofile\n");
-    print("Input file: $ifile, $ifilesize bytes.\n");
-  }
-
-  if (read(ELF, $ibuf, $ifilesize) != $ifilesize) {
-    print("Failed to read input file!\n");
-    exit(1);
-  }
-
-  # 
-  # Parse ELF header
-  #
-
-  @eh = unpack("a16n2N5n6", $ibuf);
-
-  #
-  # Make sure this is actually a PowerPC ELF file.
-  #
-
-  if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
-    printf("The file \"%s\" is not an ELF file.\n", $ifile);
-    exit (1);
-  } elsif ($eh[$e_machine] != 20) {
-    printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile);
-    exit (1);
-  }
-
-  if ($verbose) {
-    print("File header:\n");
-    printf("  Identifier:            %s\n",	$eh[$e_ident]);
-    printf("  Type:                  %d\n",	$eh[$e_type]);
-    printf("  Machine:               %d\n",	$eh[$e_machine]);
-    printf("  Version:               %d\n",	$eh[$e_version]);
-    printf("  Entry point:           0x%08x\n", $eh[$e_entry]);
-    printf("  Program header offset: 0x%x\n",	$eh[$e_phoff]);
-    printf("  Section header offset: 0x%x\n",	$eh[$e_shoff]);
-    printf("  Flags:                 0x%08x\n", $eh[$e_flags]);
-    printf("  Header size:           %d\n", $eh[$e_ehsize]);
-    printf("  Program entry size:    %d\n", $eh[$e_phentsize]);
-    printf("  Program table entries: %d\n", $eh[$e_phnum]);
-    printf("  Section header size:   %d\n", $eh[$e_shentsize]);
-    printf("  Section table entries: %d\n", $eh[$e_shnum]);
-    printf("  String table section:  %d\n", $eh[$e_shstrndx]);
-  }
-
-  #
-  # Find the section header for the string table.
-  #
-
-  $strtable_section_offset =  $eh[$e_shoff] +
-    $eh[$e_shstrndx] * $eh[$e_shentsize];
-
-  if ($verbose) {
-    printf("String table section header offset: 0x%x\n",
-	   $strtable_section_offset);
-  }
-  
-  #
-  # Find the start of the string table.
-  #
-
-  @strh = unpack("N10", substr($ibuf, $strtable_section_offset, 
-			       $eh[$e_shentsize]));
-
-  if ($verbose) {
-    printf("Section name strings start at: 0x%x, %d bytes.\n",
-	   $strh[$sh_offset], $strh[$sh_size]);
-  }
-
-  $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
-
-  # Grab each section header and find '.text' and '.bss' sections in
-  # particular.
-
-  if ($verbose) {
-  print("Section headers:\n");
-  print("Idx  Name                      Size      Address   File off  Algn\n");
-  print("---  ------------------------  --------  --------  --------  ----\n");
-  }
-
-  $off = $eh[$e_shoff];
-
-  for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
-    @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
-
-    # Take the first section name from the array returned by split.
-
-    ($name) = split(/\000/, substr($names, $sh[$sh_name]));
-    
-    if ($verbose) {
-      printf("%3d  %-24s  %8x  %08x  %08x  %4d\n", 
-	     $i, $name, $sh[$sh_size], $sh[$sh_addr], 
-	     $sh[$sh_offset], $sh[$sh_addralign]);
-    }
-
-    # Attempt to find the .text and .bss sections
-
-    if ($name =~ /^\.bss$/) {
-      ($bss_addr, $bss_offset, $bss_size) =
-	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
-    } elsif ($name =~ /^\.text$/) {
-      ($text_addr, $text_offset, $text_size) = 
-	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
-    } elsif ($linux && ($name =~ /^\image$/)) {
-      $image_found = 1;
-
-      ($image_addr, $image_offset, $image_size) = 
-	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
-    } elsif ($linux && ($name =~ /^\initrd$/)) {
-      $initrd_found = 1;
-
-      ($initrd_addr, $initrd_offset, $initrd_size) = 
-	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
-    }
-  }
-
-  printf("Text section   - Address: 0x%08x, Size: 0x%08x\n",
-	 $text_addr, $text_size);
-  printf("Bss  section   - Address: 0x%08x, Size: 0x%08x\n",
-	 $bss_addr, $bss_size);
-
-  if ($linux) {
-    if ($image_found) {
-      printf("Image section  - Address: 0x%08x, Size: 0x%08x\n",
-	     $image_addr, $image_size);
-    }
-
-    if ($initrd_found) {
-      printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
-	     $initrd_addr, $initrd_size);
-    }
-  }
-
-  #
-  # Open output file
-  #
-
-  open(BOOT, ">$ofile") || die "Cannot open output file";
-
-  #
-  # Compute image size
-  #
-
-  $output_size = $bss_offset - $text_offset + $bss_size;
-
-  if ($linux && $image_found) {
-    $output_size += $image_size;
-  }
-
-  if ($linux && $initrd_found) {
-    $output_size += $initrd_size;
-  }
-
-  # 
-  # Compute size with header 
-  #
-
-  $header = pack("H8N7", "0052504f", 0, 0, 0, 0, 0, 0, 0);
-  $num_blocks = ($output_size + length($header) + 511) / 512;
-
-  #
-  # Write IBM PowerPC evaluation board boot_block_t header
-  #
-
-  $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0,
-                 $text_addr, 0, 0, 0);
-
-
-  $bytes = length($header);
-  
-  if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) {
-    die("Could not write boot image header to output file.");
-  }
-
-  printf("Entry point = 0x%08x\n", $text_addr);
-  printf("Image size  = 0x%08x (%d bytes) (%d blocks).\n", 
-	 $output_size, $output_size, $num_blocks);
-
-  #
-  # Write image starting after ELF and program headers and 
-  # continuing to beginning of bss
-  #
-
-  $bytes = $bss_offset - $text_offset + $bss_size;
-
-  if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) {
-    die("Could not write boot image to output file.\n");
-  }
-
-  #
-  # If configured, write out the image and initrd sections as well
-  #
-
-  if ($linux) {
-    if ($image_found) {
-      $bytes = $image_size;
-      if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) {
-	die("Could not write boot image to output file.\n");
-      }
-    }
-
-    if ($initrd_found) {
-      $bytes = $initrd_size;
-      if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) {
-	die("Could not write boot image to output file.\n");
-      }
-    }
-  }
-
-  #
-  # Pad to a multiple of 512 bytes
-  #  If the (size of the boot image mod 512) is between 509 and 511 bytes
-  #  then the tftp to the Walnut fails.  This may be fixed in more recent
-  #  Walnut bootrom.
-  #
-
-  $pad_size = 512 - ((length($header) + $output_size) % 512);
-  if ($pad_size == 512) {
-    $pad_size = 0;
-  }
-
-  if ($pad_size != 0) {
-  
-    if ($verbose) {
-      print("Padding boot image by an additional $pad_size bytes.\n");
-    }
-
-    $pad_string = pack("H8","deadbeef") x 128;
-
-    syswrite(BOOT, $pad_string, $pad_size) or
-      die "Could not pad boot image in output file.\n";
-
-  }
-
-  # 
-  # Compute 32 bit checksum over entire file.
-  #
-
-  if ($do_checksum) {
-
-    close(BOOT);
-    open(BOOT, "+<$ofile") || die "Cannot open output file";
-    undef $/;
-    $temp = unpack("%32N*", <BOOT>);
-    # Solaris and PPC Linux return 0x80000000 for "-$temp" when $temp
-    # is negative.  "~($temp - 1)" negates $temp properly.
-    $csum = ~($temp - 1);
-    printf("Checksum    = 0x%08x\r\n", $csum);
-
-    #
-    # Rewrite IBM PowerPC evaluation board boot_block_t header,
-    # this time with the checksum included
-    #
-
-    $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0,
-                    $text_addr, $csum, 0, 0);
-
-    seek(BOOT, 0, 0);
-    syswrite(BOOT, $header, length($header)) or
-         die("Could not write boot image header to output file.");
-
-  }
-
-  #
-  # Clean-up and leave
-  #
-
-  close(BOOT);
-
-  print("\nBoot image file \"$ofile\" built successfully.\n\n");
-
-  exit(0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/mkimage.wrapper linux/arch/ppc/boot/utils/mkimage.wrapper
--- linux.orig/arch/ppc/boot/utils/mkimage.wrapper	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/utils/mkimage.wrapper	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+#
+# Build PPCBoot image when `mkimage' tool is available.
+#
+
+MKIMAGE=$(type -path mkimage)
+
+if [ -z "${MKIMAGE}" ]; then
+	# Doesn't exist
+	echo '"mkimage" command not found - PPCBoot images will not be built' >&2
+	exit 0;
+fi
+
+# Call "mkimage" to create PPCBoot image
+${MKIMAGE} "$@"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/mkirimg linux/arch/ppc/boot/utils/mkirimg
--- linux.orig/arch/ppc/boot/utils/mkirimg	2001-05-24 22:02:07.000000000 +0000
+++ linux/arch/ppc/boot/utils/mkirimg	1970-01-01 00:00:00.000000000 +0000
@@ -1,367 +0,0 @@
-#!/usr/bin/perl
-#
-#    Copyright (c) 1998-1999 TiVo, Inc.
-#      Original ELF parsing code.
-#
-#    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
-#      Original code from 'mkevimg'.
-#
-#    Module name: mkirimg
-#
-#    Description:
-#      Reads an ELF file and assigns global variables 'imageSect_start',
-#      'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from
-#      the "image" and "initrd" section header information. It then
-#      rewrites the input ELF file with assigned globals to an output
-#      file.
-#
-#      An input file, "irSectStart.txt" has the memory address of
-#      'irSectStart'. The irSectStart memory address is used to find
-#      the global variables in the ".data" section of the ELF file.
-#      The 'irSectStart' and the above global variables are defined
-#      in "irSect.c".
-#
-#
-
-use File::Basename;
-use Getopt::Std;
-
-#
-# usage()
-#
-# Description:
-#   This routine prints out the proper command line usage for this program
-#
-# Input(s):
-#   status - Flag determining what usage information will be printed and what
-#            the exit status of the program will be after the information is
-#            printed.
-#
-# Output(s):
-#   N/A
-#
-# Returns:
-#   This subroutine does not return.
-#
-
-sub usage {
-  my($status);
-  $status = $_[0];
-
-  printf("Usage: %s [-hvV] <ELF input file> <Evaluation board output file> <irSectStart.txt file>\n",
-	 $program);
-
-  if ($status != 0) {
-    printf("Try `%s -h' for more information.\n", $program);
-  }
-
-  if ($status != 1) {
-    print("  -h             Print out this message and exit.\n");
-    print("  -v             Verbose. Print out lots of ELF information.\n");
-    print("  -V             Print out version information and exit.\n");
-  }
-
-  exit($status);
-}
-
-#
-# version()
-#
-# Description:
-#   This routine prints out program version information
-#
-# Input(s):
-#   N/A
-#
-# Output(s):
-#   N/A
-#
-# Returns:
-#   This subroutine does not return.
-#
-
-sub version {
-  print("mkirimg Version 1.1.0\n");
-  print("Copyright (c) 1998-1999 TiVo, Inc.\n");
-  print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
-
-  exit (0);
-}
-
-#
-# file_check()
-#
-# Description:
-#   This routine checks an input file to ensure that it exists, is a
-#   regular file, and is readable.
-#
-# Input(s):
-#   file - Input file to be checked.
-#
-# Output(s):
-#   N/A
-#
-# Returns:
-#   0 if the file exists, is a regular file, and is readable, otherwise -1.
-#
-
-sub file_check {
-  my($file);
-  $file = $_[0];
-
-  if (!(-e $file)) {
-     printf("The file \"%s\" does not exist.\n", $file);
-     return (-1);
-  } elsif (!(-f $file)) {
-     printf("The file \"%s\" is not a regular file.\n", $file);
-     return (-1);
-  } elsif (!(-r $file)) {
-     printf("The file \"%s\" is not readable.\n", $file);
-     return (-1);
-  }
-
-  return (0);
-}
-
-#
-# decode_options()
-#
-# Description:
-#   This routine steps through the command-line arguments, parsing out
-#   recognzied options.
-#
-# Input(s):
-#   N/A
-#
-# Output(s):
-#   N/A
-#
-# Returns:
-#   N/A
-#
-
-sub decode_options {
-
-  if (!getopts("hvV")) {
-      usage(1);
-  }
-
-  if ($opt_h) {
-      usage(0);
-  }
-
-  if ($opt_V) {
-      version();
-      exit (0);
-  }
-
-  if ($opt_v) {
-      $verbose = 1;
-  }
-
-  if (!($ElfFile = shift(@ARGV))) {
-      usage(1);
-  }
-
-  if (!($OutputFile = shift(@ARGV))) {
-      usage (1);
-  }
-
-  if (!($IrFile = shift(@ARGV))) {
-      usage (1);
-  }
-
-  if (file_check($ElfFile)) {
-      exit(1);
-  }
-
-  if (file_check($IrFile)) {
-      exit(1);
-  }
-}
-
-#
-# ELF file and section header field numbers
-#
-
-require '../utils/elf.pl';
-
-#
-# Main program body
-#
-
-{
-  $program = basename($0);
-  decode_options();
-
-  open(ELF, "<$ElfFile") || die "Cannot open input file";
-  open(OUTPUT, ">$OutputFile") || die "Cannot open output file";
-  open(IR, "$IrFile") || die "Cannot open input file";
-
-  $ElfFilesize = (-s $ElfFile);
-
-  if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) {
-    print("Failed to read ELF input file!\n");
-    exit(1);
-  }
-
-  if (read(IR, $irbuf, 8) != 8) {
-      print("Failed to read Ir input file!\n");
-      exit(1);
-  }
-
-  #
-  # Parse ELF header
-  #
-
-  @eh = unpack("a16n2N5n6", $ibuf);
-
-  #
-  # Make sure this is actually a PowerPC ELF file.
-  #
-
-  if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
-      printf("The file \"%s\" is not an ELF file.\n", $ElfFile);
-      exit (1);
-  } elsif ($eh[$e_machine] != 20) {
-      printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile);
-      exit (1);
-  }
-
-  #
-  # Find the section header for the string table.
-  #
-
-  $strtable_section_offset =  $eh[$e_shoff] +
-
-  $eh[$e_shstrndx] * $eh[$e_shentsize];
-
-  if ($verbose) {
-     printf("String table section header offset: 0x%x\n",
-     $strtable_section_offset);
-  }
-
-  #
-  # Find the start of the string table.
-  #
-
-  @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
-			       $eh[$e_shentsize]));
-
-  if ($verbose) {
-     printf("Section name strings start at: 0x%x, %d bytes.\n",
-     $strh[$sh_offset], $strh[$sh_size]);
-  }
-
-  $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
-
-  # Grab each section header and find '.data', 'image', and 
-  # 'initrd' sections in particular.
-
-  $off = $eh[$e_shoff];
-  $imageFound = 0;
-  $initrdFound = 0;
-  
-  for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
-    @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
-
-    # Take the first section name from the array returned by split.
-
-    ($name) = split(/\000/, substr($names, $sh[$sh_name]));
-
-    # Attempt to find the .data, image, and initrd sections
-
-    if ($name =~ /^\image$/) {
-      ($image_addr, $image_offset, $image_size) =
-	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-      $imageFound = 1;
-
-    } elsif ($name =~ /^\initrd$/) {
-      ($initrd_addr, $initrd_offset, $initrd_size) =
-	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-      $initrdFound = 1;
-
-    } elsif ($name =~ /^\.data$/) {
-      ($data_addr, $data_offset, $data_size) =
-	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
-    } elsif ($name =~ /^\.bss$/) {
-      ($bss_addr, $bss_offset, $bss_size) =
-	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
-    }
-   }
-
-  if ($verbose) {
-    printf("Data section   - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
-	   $data_addr, $data_size, $data_offset);
-    printf("Bss  section   - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
-	 $bss_addr, $bss_size, $bss_offset);
-   }
-
-  if ($verbose) {
-    if ($imageFound) {
-      printf("Image section  - Address: 0x%08x, Size: 0x%08x\n",
-	     $image_addr, $image_size);
-    } else {
-      printf("Image section not found in file: $ElfFile\n");
-    }
-
-    if ($initrdFound) {
-      printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
-	     $initrd_addr, $initrd_size);
-    } else {
-      printf("Initrd section not found in file: $ElfFile\n");
-    }
-  }
-
-  # get file offset of irSectStart
-
-  $irSectStartoffset = hex ($irbuf);
-
-  if ($verbose) {
-    printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset);
-  }
-
-  # get the offset of global variables 
-
-  $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4;
-
-  # write modified values to OUTPUT file
-
-  syswrite(OUTPUT, $ibuf, $initialOffset);
-
-  if ($imageFound) {
-    $testN = pack ("N2", $bss_addr + $bss_size, $image_size);
-    syswrite(OUTPUT, $testN, length($testN));
-    printf("Updated symbol \"imageSect_start\" to 0x%08x\n",
-	   $bss_addr + $bss_size);
-    printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size);
-  } else {
-    syswrite(OUTPUT, $ibuf, 8, $initialOffset);
-  }
-
-  if ($initrdFound) {
-    $testN = pack ("N2", $bss_addr + $bss_size + $image_size, $initrd_size);
-    syswrite(OUTPUT, $testN, length($testN));
-    printf("Updated symbol \"initrdSect_start\" to 0x%08x\n",
-	   $bss_addr + $bss_size + $image_size);
-    printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size);
-  } else {
-    syswrite(OUTPUT, $ibuf,8, $initialOffset + 8);
-  }
-
-  syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16),
-	   $initialOffset + 16);
-
-  #
-  # Clean-up and leave
-  #
-
-  close (ELF);
-  close (OUTPUT);
-  close (IR);
-
-  exit (0);
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/mksimage.c linux/arch/ppc/boot/utils/mksimage.c
--- linux.orig/arch/ppc/boot/utils/mksimage.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/utils/mksimage.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,127 +0,0 @@
-/*
- * BK Id: SCCS/s.mksimage.c 1.7 10/11/01 11:59:05 trini
- */
-/*
- *
- *
- *
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-
-#define SIZE 1024
-#define BLOCK_ALIGN(x)  (((x)+SIZE-1)&(~(SIZE-1)))
-
-static void
-die(const char *fmt, ...)
-{
-	va_list args;
-	va_start(args, fmt);
-	vfprintf(stderr, fmt, args);
-	fputc('\n', stderr);
-	exit(1);
-}
-
-static void
-usage(void)
-{
-	printf("Usage: mkbinimg <bootstrap> <kernel> <ramdisk> -o <binary>\n");
-	exit(1);
-}
-
-static int
-copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size)
-{
-	off_t cur;
-	int amt;
-	unsigned long len = 0;
-	char buffer[SIZE];
-
-	cur = lseek(ofd, 0, SEEK_CUR);
-
-	if (cur % SIZE) {
-		cur = BLOCK_ALIGN(cur);
-		cur = lseek(ofd, cur, SEEK_SET);
-	}
-
-	*offset = (unsigned long) cur;
-	while((amt = read(ifd, buffer, SIZE)) > 0) {
-		write(ofd, buffer, amt);
-		len += amt;
-	}
-	*size = len;
-	return 0;
-}
-
-
-int
-main(int argc, char *argv[])
-{
-	char *kernel, *loader, *rdimage = NULL;
-	unsigned long ld_off, kern_off, rd_off;
-	unsigned long ld_size, kern_size, rd_size;
-	int fd, ofd, len;
-	char buffer[500];
-
-	if (argc < 5 && !strcmp(argv[argc-2], "-o"))
-		usage();
-
-	if (argc > 5)
-		rdimage = argv[3];
-
-	kernel = argv[2];
-	loader = argv[1];
-
-	ofd = open(argv[argc-1], (O_RDWR|O_CREAT), 0755);
-	if (ofd < 0) {
-		die("can't open %s: %s", argv[5], strerror(errno));
-	}
-
-	ld_off = kern_off = rd_off = 0;
-	ld_size = kern_size = rd_size = 0;
-	memset(buffer, 0, 500);
-	len = 0;
-
-	fd = open(loader, O_RDONLY);
-	if (fd < 0) 
-		die("can't open loader: %s", strerror(errno));
-
-	copy_blocks(fd, ofd, &ld_off, &ld_size);
-	len = sprintf(buffer, "bootloader: %lx %lx\n", ld_off, ld_size);
-	close(fd);
-
-	fd = open(kernel, O_RDONLY);
-	if (fd < 0)
-		die("can't open kernel: %s", strerror(errno));
-
-	copy_blocks(fd, ofd, &kern_off, &kern_size);
-	len += sprintf(buffer+len, "zimage: %lx %lx\n", kern_off, kern_size);
-	close(fd);
-	
-	if (rdimage) {
-		fd = open(rdimage, O_RDONLY);
-		if (fd < 0)
-			die("can't get ramdisk: %s", strerror(errno));
-		
-		copy_blocks(fd, ofd, &rd_off, &rd_size);
-		close(fd);
-	}
-
-	len += sprintf(buffer+len, "initrd: %lx %lx", rd_off, rd_size);
-
-	close(ofd);
-
-	printf("%s\n", buffer);
-
-	return 0;
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/mktree.c linux/arch/ppc/boot/utils/mktree.c
--- linux.orig/arch/ppc/boot/utils/mktree.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/boot/utils/mktree.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,149 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ * 
+ * Makes a tree bootable image for IBM Evaluation boards.
+ * Basically, just take a zImage, skip the ELF header, and stuff
+ * a 32 byte header on the front.
+ *
+ * We use htonl, which is a network macro, to make sure we're doing
+ * The Right Thing on an LE machine.  It's non-obvious, but it should
+ * work on anything BSD'ish.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+/* This gets tacked on the front of the image.  There are also a few
+ * bytes allocated after the _start label used by the boot rom (see
+ * head.S for details).
+ */
+typedef struct boot_block {
+	unsigned long bb_magic;		/* 0x0052504F */
+	unsigned long bb_dest;		/* Target address of the image */
+	unsigned long bb_num_512blocks;	/* Size, rounded-up, in 512 byte blks */
+	unsigned long bb_debug_flag;	/* Run debugger or image after load */
+	unsigned long bb_entry_point;	/* The image address to start */
+	unsigned long bb_checksum;	/* 32 bit checksum including header */
+	unsigned long reserved[2];
+} boot_block_t;
+
+#define IMGBLK	512
+char	tmpbuf[IMGBLK];
+
+int main(int argc, char *argv[])
+{
+	int	in_fd, out_fd;
+	int	nblks, i;
+	uint	cksum, *cp;
+	struct	stat	st;
+	boot_block_t	bt;
+
+	if (argc < 3) {
+		fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]\n",argv[0]);
+		exit(1);
+	}
+
+	if (stat(argv[1], &st) < 0) {
+		perror("stat");
+		exit(2);
+	}
+
+	nblks = (st.st_size + IMGBLK) / IMGBLK;
+
+	bt.bb_magic = htonl(0x0052504F);
+
+	/* If we have the optional entry point parameter, use it */
+	if (argc == 4)
+		bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0));
+	else
+		bt.bb_dest = bt.bb_entry_point = htonl(0x500000);
+
+	/* We know these from the linker command.
+	 * ...and then move it up into memory a little more so the
+	 * relocation can happen.
+	 */
+	bt.bb_num_512blocks = htonl(nblks);
+	bt.bb_debug_flag = 0;
+
+	bt.bb_checksum = 0;
+
+	/* To be neat and tidy :-).
+	*/
+	bt.reserved[0] = 0;
+	bt.reserved[1] = 0;
+
+	if ((in_fd = open(argv[1], O_RDONLY)) < 0) {
+		perror("zImage open");
+		exit(3);
+	}
+
+	if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) {
+		perror("bootfile open");
+		exit(3);
+	}
+
+	cksum = 0;
+	cp = (uint *)&bt;
+	for (i=0; i<sizeof(bt)/sizeof(uint); i++)
+		cksum += *cp++;
+	
+	/* Assume zImage is an ELF file, and skip the 64K header.
+	*/
+	if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) {
+		fprintf(stderr, "%s is too small to be an ELF image\n",
+				argv[1]);
+		exit(4);
+	}
+
+	if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) {
+		fprintf(stderr, "%s is not an ELF image\n", argv[1]);
+		exit(4);
+	}
+
+	if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) {
+		fprintf(stderr, "%s failed to seek in ELF image\n", argv[1]);
+		exit(4);
+	}
+
+	nblks -= (64 * 1024) / IMGBLK;
+
+	/* And away we go......
+	*/
+	if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
+		perror("boot-image write");
+		exit(5);
+	}
+
+	while (nblks-- > 0) {
+		if (read(in_fd, tmpbuf, IMGBLK) < 0) {
+			perror("zImage read");
+			exit(5);
+		}
+		cp = (uint *)tmpbuf;
+		for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++)
+			cksum += *cp++;
+		if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
+			perror("boot-image write");
+			exit(5);
+		}
+	}
+
+	/* rewrite the header with the computed checksum.
+	*/
+	bt.bb_checksum = htonl(cksum);
+	if (lseek(out_fd, 0, SEEK_SET) < 0) {
+		perror("rewrite seek");
+		exit(1);
+	}
+	if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
+		perror("boot-image rewrite");
+		exit(1);
+	}
+
+	exit(0);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/offset linux/arch/ppc/boot/utils/offset
--- linux.orig/arch/ppc/boot/utils/offset	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/utils/offset	1970-01-01 00:00:00.000000000 +0000
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $6}'`
-echo "0x"$OFFSET
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/piggyback.c linux/arch/ppc/boot/utils/piggyback.c
--- linux.orig/arch/ppc/boot/utils/piggyback.c	2001-05-24 22:02:07.000000000 +0000
+++ linux/arch/ppc/boot/utils/piggyback.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,69 +0,0 @@
-/*
- * BK Id: SCCS/s.piggyback.c 1.7 05/18/01 15:17:23 cort
- */
-#include <stdio.h>
-#include <unistd.h>
-
-extern long ce_exec_config[];
-
-int main(int argc, char *argv[])
-{
-	int i, cnt, pos, len;
-	unsigned int cksum, val;
-	unsigned char *lp;
-	unsigned char buf[8192];
-	if (argc != 2)
-	{
-		fprintf(stderr, "usage: %s name <in-file >out-file\n",
-			argv[0]);
-		exit(1);
-	}
-	fprintf(stdout, "#\n");
-	fprintf(stdout, "# Miscellaneous data structures:\n");
-	fprintf(stdout, "# WARNING - this file is automatically generated!\n");
-	fprintf(stdout, "#\n");
-	fprintf(stdout, "\n");
-	fprintf(stdout, "\t.data\n");
-	fprintf(stdout, "\t.globl %s_data\n", argv[1]);
-	fprintf(stdout, "%s_data:\n", argv[1]);
-	pos = 0;
-	cksum = 0;
-	while ((len = read(0, buf, sizeof(buf))) > 0)
-	{
-		cnt = 0;
-		lp = (unsigned char *)buf;
-		len = (len + 3) & ~3;  /* Round up to longwords */
-		for (i = 0;  i < len;  i += 4)
-		{
-			if (cnt == 0)
-			{
-				fprintf(stdout, "\t.long\t");
-			}
-			fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
-			val = *(unsigned long *)lp;
-			cksum ^= val;
-			lp += 4;
-			if (++cnt == 4)
-			{
-				cnt = 0;
-				fprintf(stdout, " # %x \n", pos+i-12);
-				fflush(stdout);
-			} else
-			{
-				fprintf(stdout, ",");
-			}
-		}
-		if (cnt)
-		{
-			fprintf(stdout, "0\n");
-		}
-		pos += len;
-	}
-	fprintf(stdout, "\t.globl %s_len\n", argv[1]);
-	fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
-	fflush(stdout);
-	fclose(stdout);
-	fprintf(stderr, "cksum = %x\n", cksum);
-	exit(0);
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/sioffset linux/arch/ppc/boot/utils/sioffset
--- linux.orig/arch/ppc/boot/utils/sioffset	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/utils/sioffset	1970-01-01 00:00:00.000000000 +0000
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-OFFSET=`grep $1 sImage.map | awk '{print $2}'`
-echo "0x"$OFFSET
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/sisize linux/arch/ppc/boot/utils/sisize
--- linux.orig/arch/ppc/boot/utils/sisize	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/utils/sisize	1970-01-01 00:00:00.000000000 +0000
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-OFFSET=`grep $1 sImage.map | awk '{print $3}'`
-echo "0x"$OFFSET
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/boot/utils/size linux/arch/ppc/boot/utils/size
--- linux.orig/arch/ppc/boot/utils/size	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/boot/utils/size	1970-01-01 00:00:00.000000000 +0000
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'`
-echo "0x"$OFFSET
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/config.in linux/arch/ppc/config.in
--- linux.orig/arch/ppc/config.in	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/config.in	2002-07-20 01:08:21.000000000 +0000
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.config.in 1.47 12/01/01 20:09:06 benh
+# BK Id: SCCS/s.config.in 1.51 03/07/02 13:36:31 trini
 #
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
@@ -122,6 +122,9 @@
   bool 'Math emulation' CONFIG_MATH_EMULATION
 fi
 
+if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then
+    define_bool CONFIG_EMBEDDEDBOOT y
+fi
 endmenu
 
 mainmenu_option next_comment
@@ -194,6 +197,7 @@
   bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS
   bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT
   bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL
+  dep_bool '  Support for reading of PReP Residual Data in /proc' CONFIG_PROC_PREPRESIDUAL $CONFIG_PREP_RESIDUAL
 fi
 
 bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL
@@ -389,9 +393,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'
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/IVMS8_defconfig linux/arch/ppc/configs/IVMS8_defconfig
--- linux.orig/arch/ppc/configs/IVMS8_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/IVMS8_defconfig	2002-07-20 01:08:25.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -48,6 +49,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -96,6 +98,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -119,8 +122,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -134,6 +135,7 @@
 # CONFIG_IP_PNP_RARP 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
@@ -146,6 +148,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -242,7 +256,6 @@
 # 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
@@ -394,11 +407,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 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
@@ -411,6 +428,7 @@
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # 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
@@ -435,6 +453,7 @@
 # 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
@@ -452,6 +471,8 @@
 # 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
@@ -509,6 +530,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -571,6 +596,7 @@
 # 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_IPAQ 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
@@ -584,6 +610,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/SM850_defconfig linux/arch/ppc/configs/SM850_defconfig
--- linux.orig/arch/ppc/configs/SM850_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/SM850_defconfig	2002-07-20 01:08:33.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -49,6 +50,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -97,6 +99,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -120,8 +123,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -135,6 +136,7 @@
 # CONFIG_IP_PNP_RARP 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
@@ -147,6 +149,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -200,7 +214,6 @@
 # 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
@@ -352,11 +365,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 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
@@ -369,6 +386,7 @@
 # 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
@@ -393,6 +411,7 @@
 # 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
@@ -410,6 +429,8 @@
 # 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
@@ -471,6 +492,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -533,6 +558,7 @@
 # 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_IPAQ 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
@@ -546,6 +572,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/SPD823TS_defconfig linux/arch/ppc/configs/SPD823TS_defconfig
--- linux.orig/arch/ppc/configs/SPD823TS_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/SPD823TS_defconfig	2002-07-20 01:08:35.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -48,6 +49,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -96,6 +98,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -119,8 +122,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -134,6 +135,7 @@
 # CONFIG_IP_PNP_RARP 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
@@ -146,6 +148,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -199,7 +213,6 @@
 # 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
@@ -351,11 +364,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 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
@@ -368,6 +385,7 @@
 # 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
@@ -392,6 +410,7 @@
 # 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
@@ -409,6 +428,8 @@
 # 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
@@ -470,6 +491,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -532,6 +557,7 @@
 # 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_IPAQ 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
@@ -545,6 +571,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/TQM823L_defconfig linux/arch/ppc/configs/TQM823L_defconfig
--- linux.orig/arch/ppc/configs/TQM823L_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/TQM823L_defconfig	2002-07-20 01:08:28.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -49,6 +50,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -97,6 +99,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -120,8 +123,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -135,6 +136,7 @@
 # CONFIG_IP_PNP_RARP 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
@@ -147,6 +149,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -200,7 +214,6 @@
 # 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
@@ -352,11 +365,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 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
@@ -369,6 +386,7 @@
 # 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
@@ -393,6 +411,7 @@
 # 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
@@ -410,6 +429,8 @@
 # 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
@@ -471,6 +492,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -533,6 +558,7 @@
 # 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_IPAQ 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
@@ -546,6 +572,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/TQM850L_defconfig linux/arch/ppc/configs/TQM850L_defconfig
--- linux.orig/arch/ppc/configs/TQM850L_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/TQM850L_defconfig	2002-07-20 01:08:22.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -49,6 +50,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -97,6 +99,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -120,8 +123,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -135,6 +136,7 @@
 # CONFIG_IP_PNP_RARP 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
@@ -147,6 +149,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -200,7 +214,6 @@
 # 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
@@ -352,11 +365,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 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
@@ -369,6 +386,7 @@
 # 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
@@ -393,6 +411,7 @@
 # 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
@@ -410,6 +429,8 @@
 # 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
@@ -471,6 +492,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -533,6 +558,7 @@
 # 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_IPAQ 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
@@ -546,6 +572,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/TQM860L_defconfig linux/arch/ppc/configs/TQM860L_defconfig
--- linux.orig/arch/ppc/configs/TQM860L_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/TQM860L_defconfig	2002-07-20 01:08:31.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -49,6 +50,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -97,6 +99,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -120,8 +123,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -135,6 +136,7 @@
 # CONFIG_IP_PNP_RARP 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
@@ -147,6 +149,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -243,7 +257,6 @@
 # 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
@@ -395,11 +408,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 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
@@ -412,6 +429,7 @@
 # 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
@@ -436,6 +454,7 @@
 # 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
@@ -453,6 +472,8 @@
 # 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
@@ -518,6 +539,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -580,6 +605,7 @@
 # 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_IPAQ 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
@@ -593,6 +619,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/apus_defconfig linux/arch/ppc/configs/apus_defconfig
--- linux.orig/arch/ppc/configs/apus_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/apus_defconfig	2002-07-20 01:08:29.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -66,6 +67,7 @@
 CONFIG_PARPORT_AMIGA=m
 # 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
@@ -115,6 +117,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
@@ -139,8 +142,6 @@
 #
 CONFIG_PACKET=m
 CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 CONFIG_NETLINK_DEV=m
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -152,6 +153,7 @@
 # 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=y
 
@@ -168,6 +170,7 @@
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
 CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_TCPMSS=m
@@ -188,6 +191,7 @@
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_MARK=m
 CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_NAT_NEEDED=y
@@ -202,6 +206,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -304,6 +320,7 @@
 # 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
@@ -327,6 +344,7 @@
 # CONFIG_SCSI_IMM 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
@@ -392,7 +410,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -483,6 +500,7 @@
 # CONFIG_FB_PM2_FIFO_DISCONNECT is not set
 # CONFIG_FB_PM2_PCI is not set
 CONFIG_FB_PM2_CVPPC=y
+# CONFIG_FB_PM3 is not set
 CONFIG_FB_CYBER2000=y
 CONFIG_FB_AMIGA=y
 CONFIG_FB_AMIGA_OCS=y
@@ -507,6 +525,7 @@
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 CONFIG_FBCON_ADVANCED=y
 # CONFIG_FBCON_MFB is not set
@@ -650,11 +669,15 @@
 CONFIG_AUTOFS4_FS=m
 # 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=y
 CONFIG_HFS_FS=y
 # CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
@@ -667,6 +690,7 @@
 CONFIG_RAMFS=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -691,6 +715,7 @@
 # Network File Systems
 #
 CONFIG_CODA_FS=m
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
@@ -710,6 +735,8 @@
 # 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=y
 
 #
 # Partition Types
@@ -757,6 +784,7 @@
 CONFIG_NLS_CODEPAGE_949=m
 CONFIG_NLS_CODEPAGE_874=m
 CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
 CONFIG_NLS_CODEPAGE_1251=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_ISO8859_2=m
@@ -910,6 +938,7 @@
 # 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_IPAQ 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
@@ -923,6 +952,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/bseip_defconfig linux/arch/ppc/configs/bseip_defconfig
--- linux.orig/arch/ppc/configs/bseip_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/bseip_defconfig	2002-07-20 01:08:28.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -46,6 +47,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -94,6 +96,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -118,8 +121,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -134,6 +135,7 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
@@ -146,6 +148,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -199,7 +213,6 @@
 # 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
@@ -351,11 +364,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=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
@@ -368,6 +385,7 @@
 # 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
@@ -392,6 +410,7 @@
 # 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
@@ -409,6 +428,8 @@
 # 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
@@ -470,6 +491,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -532,6 +557,7 @@
 # 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_IPAQ 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
@@ -545,6 +571,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/common_defconfig linux/arch/ppc/configs/common_defconfig
--- linux.orig/arch/ppc/configs/common_defconfig	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/configs/common_defconfig	2002-07-20 01:08:30.000000000 +0000
@@ -74,6 +74,7 @@
 CONFIG_PPC_RTAS=y
 CONFIG_BOOTX_TEXT=y
 CONFIG_PREP_RESIDUAL=y
+CONFIG_PROC_PREPRESIDUAL=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2"
 
@@ -96,6 +97,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -149,6 +151,7 @@
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
 CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_TCPMSS=m
@@ -167,6 +170,7 @@
 CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
 # CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_NAT_NEEDED=y
@@ -181,6 +185,18 @@
 #
 # CONFIG_IPX is not set
 CONFIG_ATALK=m
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -316,6 +332,7 @@
 # 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=m
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
@@ -380,13 +397,6 @@
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_LTPC is not set
-# CONFIG_COPS is not set
-# CONFIG_IPDDP is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
@@ -405,7 +415,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -436,6 +445,7 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -530,6 +540,7 @@
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_OF=y
 CONFIG_FB_CONTROL=y
@@ -554,6 +565,7 @@
 # CONFIG_FB_SIS is not set
 CONFIG_FB_3DFX=y
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -812,6 +824,7 @@
 # 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=m
 # CONFIG_NLS_CODEPAGE_1251 is not set
 CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_ISO8859_2 is not set
@@ -944,6 +957,7 @@
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
 CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_IPAQ 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
@@ -957,6 +971,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/est8260_defconfig linux/arch/ppc/configs/est8260_defconfig
--- linux.orig/arch/ppc/configs/est8260_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/est8260_defconfig	2002-07-20 01:08:37.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -30,6 +31,7 @@
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_EST8260=y
 # CONFIG_SMP is not set
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -77,6 +79,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -101,8 +104,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -117,6 +118,7 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
@@ -129,6 +131,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -182,7 +196,6 @@
 # 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
@@ -335,11 +348,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 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
@@ -352,6 +369,7 @@
 # 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
@@ -376,6 +394,7 @@
 # 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
@@ -393,6 +412,8 @@
 # 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
@@ -419,6 +440,7 @@
 #
 # MPC8260 Communication Options
 #
+# CONFIG_SCC_CONSOLE is not set
 CONFIG_SCC_ENET=y
 CONFIG_SCC1_ENET=y
 # CONFIG_FEC_ENET is not set
@@ -440,6 +462,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -502,6 +528,7 @@
 # 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_IPAQ 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
@@ -515,6 +542,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/gemini_defconfig linux/arch/ppc/configs/gemini_defconfig
--- linux.orig/arch/ppc/configs/gemini_defconfig	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/configs/gemini_defconfig	2002-07-20 01:08:34.000000000 +0000
@@ -86,6 +86,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -143,6 +144,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -200,6 +213,7 @@
 # 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
@@ -272,7 +286,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -600,6 +613,7 @@
 # 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_IPAQ 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
@@ -613,6 +627,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/ibmchrp_defconfig linux/arch/ppc/configs/ibmchrp_defconfig
--- linux.orig/arch/ppc/configs/ibmchrp_defconfig	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/configs/ibmchrp_defconfig	2002-07-20 01:08:36.000000000 +0000
@@ -68,6 +68,7 @@
 CONFIG_PPC_RTAS=y
 # CONFIG_BOOTX_TEXT is not set
 # CONFIG_PREP_RESIDUAL is not set
+# CONFIG_PROC_PREPRESIDUAL is not set
 # CONFIG_CMDLINE_BOOL is not set
 
 #
@@ -89,6 +90,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -142,6 +144,7 @@
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
 CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_TCPMSS=m
@@ -160,6 +163,7 @@
 CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
 # CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_NAT_NEEDED=y
@@ -174,6 +178,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -231,6 +247,7 @@
 # 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
@@ -305,7 +322,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -334,6 +350,7 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -413,6 +430,7 @@
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_OF=y
 # CONFIG_FB_CONTROL is not set
@@ -434,6 +452,7 @@
 # CONFIG_FB_SIS is not set
 CONFIG_FB_3DFX=y
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -681,6 +700,7 @@
 # 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=m
 # CONFIG_NLS_ISO8859_2 is not set
@@ -782,6 +802,7 @@
 # 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_IPAQ 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
@@ -795,6 +816,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/mbx_defconfig linux/arch/ppc/configs/mbx_defconfig
--- linux.orig/arch/ppc/configs/mbx_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/mbx_defconfig	2002-07-20 01:08:21.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -46,6 +47,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -94,6 +96,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -116,7 +119,7 @@
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -129,6 +132,7 @@
 # CONFIG_IP_PNP_RARP 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
@@ -141,6 +145,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -182,6 +198,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -193,7 +210,6 @@
 # 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
@@ -344,11 +360,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 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
@@ -361,6 +381,7 @@
 # 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
@@ -385,6 +406,7 @@
 # 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
@@ -402,6 +424,8 @@
 # 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
@@ -463,6 +487,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -525,6 +553,7 @@
 # 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_IPAQ 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
@@ -538,6 +567,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/oak_defconfig linux/arch/ppc/configs/oak_defconfig
--- linux.orig/arch/ppc/configs/oak_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/oak_defconfig	2002-07-20 01:08:24.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -79,6 +80,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -102,7 +104,7 @@
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -116,6 +118,7 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
@@ -128,6 +131,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -169,6 +184,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -180,7 +196,6 @@
 # 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
@@ -332,11 +347,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 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
@@ -349,6 +368,7 @@
 # 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
@@ -373,6 +393,7 @@
 # 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
@@ -390,6 +411,8 @@
 # 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
@@ -421,6 +444,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -483,6 +510,7 @@
 # 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_IPAQ 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
@@ -496,6 +524,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/pmac_defconfig linux/arch/ppc/configs/pmac_defconfig
--- linux.orig/arch/ppc/configs/pmac_defconfig	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/configs/pmac_defconfig	2002-07-20 01:08:30.000000000 +0000
@@ -78,6 +78,7 @@
 CONFIG_PPC_RTAS=y
 CONFIG_BOOTX_TEXT=y
 # CONFIG_PREP_RESIDUAL is not set
+# CONFIG_PROC_PREPRESIDUAL is not set
 # CONFIG_CMDLINE_BOOL is not set
 
 #
@@ -99,6 +100,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -152,6 +154,7 @@
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
 CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_TCPMSS=m
@@ -170,6 +173,7 @@
 CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
 # CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_NAT_NEEDED=y
@@ -184,6 +188,18 @@
 #
 # CONFIG_IPX is not set
 CONFIG_ATALK=m
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -319,6 +335,7 @@
 # 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=m
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
@@ -404,13 +421,6 @@
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_LTPC is not set
-# CONFIG_COPS is not set
-# CONFIG_IPDDP is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
@@ -429,7 +439,6 @@
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 CONFIG_SUNGEM=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -460,6 +469,7 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -566,7 +576,13 @@
 CONFIG_IRNET=m
 CONFIG_IRCOMM=m
 # CONFIG_IRDA_ULTRA is not set
-# CONFIG_IRDA_OPTIONS is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
 
 #
 # Infrared-port device drivers
@@ -617,6 +633,7 @@
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_OF=y
 CONFIG_FB_CONTROL=y
@@ -641,6 +658,7 @@
 # CONFIG_FB_SIS is not set
 CONFIG_FB_3DFX=y
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -908,6 +926,7 @@
 # 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=m
 # CONFIG_NLS_ISO8859_2 is not set
@@ -1040,6 +1059,7 @@
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
 CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_IPAQ 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
@@ -1053,6 +1073,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/power3_defconfig linux/arch/ppc/configs/power3_defconfig
--- linux.orig/arch/ppc/configs/power3_defconfig	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/configs/power3_defconfig	2002-07-20 01:08:28.000000000 +0000
@@ -76,6 +76,7 @@
 CONFIG_PPC_RTAS=y
 # CONFIG_BOOTX_TEXT is not set
 # CONFIG_PREP_RESIDUAL is not set
+# CONFIG_PROC_PREPRESIDUAL is not set
 # CONFIG_CMDLINE_BOOL is not set
 
 #
@@ -97,6 +98,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -145,6 +147,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -202,6 +216,7 @@
 # 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
@@ -278,7 +293,6 @@
 # CONFIG_HAPPYMEAL 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
@@ -307,6 +321,7 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -386,6 +401,7 @@
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_OF=y
 # CONFIG_FB_CONTROL is not set
@@ -409,6 +425,7 @@
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -652,6 +669,7 @@
 # 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=y
 # CONFIG_NLS_ISO8859_2 is not set
@@ -804,6 +822,7 @@
 # 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_IPAQ 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
@@ -817,6 +836,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/rpxcllf_defconfig linux/arch/ppc/configs/rpxcllf_defconfig
--- linux.orig/arch/ppc/configs/rpxcllf_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/rpxcllf_defconfig	2002-07-20 01:08:30.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -46,6 +47,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -94,6 +96,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -118,8 +121,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -134,6 +135,7 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
@@ -146,6 +148,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -199,7 +213,6 @@
 # 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
@@ -351,11 +364,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 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
@@ -368,6 +385,7 @@
 # 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
@@ -392,6 +410,7 @@
 # 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
@@ -409,6 +428,8 @@
 # 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
@@ -471,6 +492,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -533,6 +558,7 @@
 # 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_IPAQ 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
@@ -546,6 +572,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/rpxlite_defconfig linux/arch/ppc/configs/rpxlite_defconfig
--- linux.orig/arch/ppc/configs/rpxlite_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/rpxlite_defconfig	2002-07-20 01:08:28.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -46,6 +47,7 @@
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 CONFIG_MATH_EMULATION=y
+CONFIG_EMBEDDEDBOOT=y
 
 #
 # General setup
@@ -94,6 +96,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -118,8 +121,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -134,6 +135,7 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
@@ -146,6 +148,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -199,7 +213,6 @@
 # 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
@@ -351,11 +364,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 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
@@ -368,6 +385,7 @@
 # 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
@@ -392,6 +410,7 @@
 # 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
@@ -409,6 +428,8 @@
 # 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
@@ -468,6 +489,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -530,6 +555,7 @@
 # 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_IPAQ 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
@@ -543,6 +569,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/configs/walnut_defconfig linux/arch/ppc/configs/walnut_defconfig
--- linux.orig/arch/ppc/configs/walnut_defconfig	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/configs/walnut_defconfig	2002-07-20 01:08:30.000000000 +0000
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -79,6 +80,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
@@ -102,7 +104,7 @@
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -116,6 +118,7 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
@@ -128,6 +131,18 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+# CONFIG_IPDDP is not set
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -169,6 +184,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -180,7 +196,6 @@
 # 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
@@ -336,11 +351,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 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
@@ -353,6 +372,7 @@
 # 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
@@ -377,6 +397,7 @@
 # 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
@@ -394,6 +415,8 @@
 # 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
@@ -425,6 +448,10 @@
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -487,6 +514,7 @@
 # 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_IPAQ 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
@@ -500,6 +528,7 @@
 # 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_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- linux.orig/arch/ppc/kernel/Makefile	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/Makefile	2002-07-20 01:08:32.000000000 +0000
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.36 12/01/01 20:09:06 benh
+# BK Id: SCCS/s.Makefile 1.41 04/16/02 20:08:22 paulus
 #
 #
 # Makefile for the linux kernel.
@@ -15,6 +15,13 @@
 EXTRA_AFLAGS		:= -Wa,-mppc64bridge
 endif
 
+# Extra CFLAGS so we don't have to do relative includes
+CFLAGS_pmac_setup.o	+= -I$(TOPDIR)/arch/$(ARCH)/mm -I$(TOPDIR)/drivers/scsi
+
+# Code in these files is used before the kernel is moved to its final position
+CFLAGS_prom_init.o	+= -mrelocatable-lib
+CFLAGS_btext.o		+= -mrelocatable-lib
+
 # Start off with 'head.o', change as needed.
 HEAD-y				:= head.o
 HEAD-$(CONFIG_4xx)		:= head_4xx.o
@@ -56,10 +63,11 @@
 obj-$(CONFIG_PCI)		+= apus_pci.o
 endif
 obj-$(CONFIG_ALL_PPC)		+= pmac_pic.o pmac_setup.o pmac_time.o prom.o \
-					pmac_feature.o pmac_pci.o chrp_setup.o \
-					chrp_time.o chrp_pci.o 	open_pic.o \
-					indirect_pci.o i8259.o prep_pci.o \
-					prep_time.o prep_nvram.o prep_setup.o
+					prom_init.o pmac_feature.o pmac_pci.o \
+					chrp_setup.o chrp_time.o chrp_pci.o \
+					open_pic.o indirect_pci.o i8259.o \
+					prep_pci.o prep_time.o prep_nvram.o \
+					prep_setup.o
 obj-$(CONFIG_NVRAM)		+= pmac_nvram.o
 obj-$(CONFIG_PMAC_BACKLIGHT)	+= pmac_backlight.o
 obj-$(CONFIG_PMAC_PBOOK)	+= sleep.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c
--- linux.orig/arch/ppc/kernel/apus_setup.c	2001-11-16 18:10:08.000000000 +0000
+++ linux/arch/ppc/kernel/apus_setup.c	2002-07-20 01:08:38.000000000 +0000
@@ -106,7 +106,6 @@
 long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
 #if defined(CONFIG_AMIGA_FLOPPY)
 void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
-void (*mach_floppy_eject) (void) = NULL;
 #endif
 #ifdef CONFIG_HEARTBEAT
 void (*mach_heartbeat) (int) = NULL;
@@ -404,12 +403,6 @@
 	if (mach_floppy_setup)
 		mach_floppy_setup (str, ints);
 }
-
-void floppy_eject(void)
-{
-	if (mach_floppy_eject)
-		mach_floppy_eject();
-}
 #endif
 
 /*********************************************************** MEMORY */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/btext.c linux/arch/ppc/kernel/btext.c
--- linux.orig/arch/ppc/kernel/btext.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/btext.c	2002-07-20 01:08:22.000000000 +0000
@@ -44,10 +44,9 @@
 
 static unsigned char vga_font[cmapsz];
 
-int boot_text_mapped = 1;
+int boot_text_mapped;
 
-boot_infos_t *disp_bi;
-boot_infos_t fake_bi;
+boot_infos_t disp_bi;
 
 extern char *klimit;
 
@@ -69,48 +68,47 @@
 void __init
 btext_init(boot_infos_t *bi)
 {
-	unsigned long offset = reloc_offset();
-
-	RELOC(g_loc_X) = 0;
-	RELOC(g_loc_Y) = 0;
-	RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
-	RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
-	RELOC(disp_bi) = PTRUNRELOC(bi);
+	g_loc_X = 0;
+	g_loc_Y = 0;
+	g_max_loc_X = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
+	g_max_loc_Y = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
+	disp_bi = *bi;
+	boot_text_mapped = 1;
 }
 
 void __init
-btext_welcome(boot_infos_t* bi)
+btext_welcome(void)
 {
-	unsigned long offset = reloc_offset();
 	unsigned long flags;
 	unsigned long pvr;
-	
-	btext_drawstring(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
-	btext_drawstring(RELOC("\nlinked at        : 0x"));
+	boot_infos_t* bi = &disp_bi;
+
+	btext_drawstring("Welcome to Linux, kernel " UTS_RELEASE "\n");
+	btext_drawstring("\nlinked at        : 0x");
 	btext_drawhex(KERNELBASE);
-	btext_drawstring(RELOC("\nframe buffer at  : 0x"));
+	btext_drawstring("\nframe buffer at  : 0x");
 	btext_drawhex((unsigned long)bi->dispDeviceBase);
-	btext_drawstring(RELOC(" (phys), 0x"));
+	btext_drawstring(" (phys), 0x");
 	btext_drawhex((unsigned long)bi->logicalDisplayBase);
-	btext_drawstring(RELOC(" (log)"));
-	btext_drawstring(RELOC("\nklimit           : 0x"));
-	btext_drawhex((unsigned long)RELOC(klimit));
-	btext_drawstring(RELOC("\nMSR              : 0x"));
+	btext_drawstring(" (log)");
+	btext_drawstring("\nklimit           : 0x");
+	btext_drawhex((unsigned long)klimit);
+	btext_drawstring("\nMSR              : 0x");
 	__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
 	btext_drawhex(flags);
 	__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
 	pvr >>= 16;
 	if (pvr > 1) {
-	    btext_drawstring(RELOC("\nHID0             : 0x"));
+	    btext_drawstring("\nHID0             : 0x");
 	    __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
 	    btext_drawhex(flags);
 	}
 	if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
-	    btext_drawstring(RELOC("\nICTC             : 0x"));
+	    btext_drawstring("\nICTC             : 0x");
 	    __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
 	    btext_drawhex(flags);
 	}
-	btext_drawstring(RELOC("\n\n"));
+	btext_drawstring("\n\n");
 }
 
 /* Calc BAT values for mapping the display and store them
@@ -131,33 +129,28 @@
 void __init
 btext_prepare_BAT(void)
 {
-	unsigned long offset = reloc_offset();
-	boot_infos_t* bi = PTRRELOC(RELOC(disp_bi));
+	boot_infos_t* bi = &disp_bi;
 	unsigned long vaddr = KERNELBASE + 0x10000000;
 	unsigned long addr;
 	unsigned long lowbits;
 
-	if (!RELOC(disp_bi)) {
-		RELOC(boot_text_mapped) = 0;
-		return;
-	}
 	addr = (unsigned long)bi->dispDeviceBase;
 	if (!addr) {
-		RELOC(boot_text_mapped) = 0;
+		boot_text_mapped = 0;
 		return;
 	}
 	if (PVR_VER(mfspr(PVR)) != 1) {
 		/* 603, 604, G3, G4, ... */
 		lowbits = addr & ~0xFF000000UL;
 		addr &= 0xFF000000UL;
-		RELOC(disp_BAT[0]) = vaddr | (BL_16M<<2) | 2;
-		RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);		
+		disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
+		disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);		
 	} else {
 		/* 601 */
 		lowbits = addr & ~0xFF800000UL;
 		addr &= 0xFF800000UL;
-		RELOC(disp_BAT[0]) = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
-		RELOC(disp_BAT[1]) = addr | BL_8M | 0x40;
+		disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
+		disp_BAT[1] = addr | BL_8M | 0x40;
 	}
 	bi->logicalDisplayBase = (void *) (vaddr + lowbits);
 }
@@ -169,15 +162,12 @@
 btext_setup_display(int width, int height, int depth, int pitch,
 		    unsigned long address)
 {
-	unsigned long offset = reloc_offset();
-	boot_infos_t* bi;
+	boot_infos_t* bi = &disp_bi;
 
-	RELOC(disp_bi) = &fake_bi;
-	bi = PTRRELOC((&fake_bi));
-	RELOC(g_loc_X) = 0;
-	RELOC(g_loc_Y) = 0;
-	RELOC(g_max_loc_X) = width / 8;
-	RELOC(g_max_loc_Y) = height / 16;
+	g_loc_X = 0;
+	g_loc_Y = 0;
+	g_max_loc_X = width / 8;
+	g_max_loc_Y = height / 16;
 	bi->logicalDisplayBase = (unsigned char *)address;
 	bi->dispDeviceBase = (unsigned char *)address;
 	bi->dispDeviceRowBytes = pitch;
@@ -185,6 +175,7 @@
 	bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
 	bi->dispDeviceRect[2] = width;
 	bi->dispDeviceRect[3] = height;
+	boot_text_mapped = 1;
 }
 
 /* Here's a small text engine to use during early boot
@@ -202,16 +193,18 @@
 map_boot_text(void)
 {
 	unsigned long base, offset, size;
-	if (disp_bi == 0)
+	boot_infos_t *bi = &disp_bi;
+
+	if (bi->dispDeviceBase == 0)
 		return;
-	base = ((unsigned long) disp_bi->dispDeviceBase) & 0xFFFFF000UL;
-	offset = ((unsigned long) disp_bi->dispDeviceBase) - base;
-	size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset
-		+ disp_bi->dispDeviceRect[0];
-	disp_bi->logicalDisplayBase = ioremap(base, size);
-	if (disp_bi->logicalDisplayBase == 0)
+	base = ((unsigned long) bi->dispDeviceBase) & 0xFFFFF000UL;
+	offset = ((unsigned long) bi->dispDeviceBase) - base;
+	size = bi->dispDeviceRowBytes * bi->dispDeviceRect[3] + offset
+		+ bi->dispDeviceRect[0];
+	bi->logicalDisplayBase = ioremap(base, size);
+	if (bi->logicalDisplayBase == 0)
 		return;
-	disp_bi->logicalDisplayBase += offset;
+	bi->logicalDisplayBase += offset;
 	boot_text_mapped = 1;
 }
 
@@ -234,22 +227,24 @@
 btext_update_display(unsigned long phys, int width, int height,
 		     int depth, int pitch)
 {
-	if (disp_bi == 0)
+	boot_infos_t *bi = &disp_bi;
+
+	if (bi->dispDeviceBase == 0)
 		return;
 
 	/* check it's the same frame buffer (within 256MB) */
-	if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xf0000000)
+	if ((phys ^ (unsigned long)bi->dispDeviceBase) & 0xf0000000)
 		return;
 
-	disp_bi->dispDeviceBase = (__u8 *) phys;
-	disp_bi->dispDeviceRect[0] = 0;
-	disp_bi->dispDeviceRect[1] = 0;
-	disp_bi->dispDeviceRect[2] = width;
-	disp_bi->dispDeviceRect[3] = height;
-	disp_bi->dispDeviceDepth = depth;
-	disp_bi->dispDeviceRowBytes = pitch;
+	bi->dispDeviceBase = (__u8 *) phys;
+	bi->dispDeviceRect[0] = 0;
+	bi->dispDeviceRect[1] = 0;
+	bi->dispDeviceRect[2] = width;
+	bi->dispDeviceRect[3] = height;
+	bi->dispDeviceDepth = depth;
+	bi->dispDeviceRowBytes = pitch;
 	if (boot_text_mapped) {
-		iounmap(disp_bi->logicalDisplayBase);
+		iounmap(bi->logicalDisplayBase);
 		boot_text_mapped = 0;
 	}
 	map_boot_text();
@@ -261,8 +256,7 @@
 
 void BTEXT btext_clearscreen(void)
 {
-	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
+	boot_infos_t* bi	= &disp_bi;
 	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);
 	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
 					(bi->dispDeviceDepth >> 3)) >> 2;
@@ -284,8 +278,7 @@
 
 void BTEXT btext_flushscreen(void)
 {
-	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
+	boot_infos_t* bi	= &disp_bi;
 	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);
 	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
 					(bi->dispDeviceDepth >> 3)) >> 2;
@@ -306,8 +299,7 @@
 static BTEXT void
 scrollscreen(void)
 {
-	unsigned long offset		= reloc_offset();
-	boot_infos_t* bi		= PTRRELOC(RELOC(disp_bi));
+	boot_infos_t* bi		= &disp_bi;
 	unsigned long *src		= (unsigned long *)calc_base(bi,0,16);
 	unsigned long *dst		= (unsigned long *)calc_base(bi,0,0);
 	unsigned long width		= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
@@ -341,49 +333,48 @@
 
 void BTEXT btext_drawchar(char c)
 {
-	unsigned long offset = reloc_offset();
 	int cline = 0, x;
 
-	if (!RELOC(boot_text_mapped))
+	if (!boot_text_mapped)
 		return;
 
 	switch (c) {
 	case '\b':
-		if (RELOC(g_loc_X) > 0)
-			--RELOC(g_loc_X);
+		if (g_loc_X > 0)
+			--g_loc_X;
 		break;
 	case '\t':
-		RELOC(g_loc_X) = (RELOC(g_loc_X) & -8) + 8;
+		g_loc_X = (g_loc_X & -8) + 8;
 		break;
 	case '\r':
-		RELOC(g_loc_X) = 0;
+		g_loc_X = 0;
 		break;
 	case '\n':
-		RELOC(g_loc_X) = 0;
-		RELOC(g_loc_Y)++;
+		g_loc_X = 0;
+		g_loc_Y++;
 		cline = 1;
 		break;
 	default:
-		draw_byte(c, RELOC(g_loc_X)++, RELOC(g_loc_Y));
+		draw_byte(c, g_loc_X++, g_loc_Y);
 	}
-	if (RELOC(g_loc_X) >= RELOC(g_max_loc_X)) {
-		RELOC(g_loc_X) = 0;
-		RELOC(g_loc_Y)++;
+	if (g_loc_X >= g_max_loc_X) {
+		g_loc_X = 0;
+		g_loc_Y++;
 		cline = 1;
 	}
 #ifndef NO_SCROLL
-	while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) {
+	while (g_loc_Y >= g_max_loc_Y) {
 		scrollscreen();
-		RELOC(g_loc_Y)--;
+		g_loc_Y--;
 	}
 #else
 	/* wrap around from bottom to top of screen so we don't
 	   waste time scrolling each line.  -- paulus. */
-	if (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y))
-		RELOC(g_loc_Y) = 0;
+	if (g_loc_Y >= g_max_loc_Y)
+		g_loc_Y = 0;
 	if (cline) {
-		for (x = 0; x < RELOC(g_max_loc_X); ++x)
-			draw_byte(' ', x, RELOC(g_loc_Y));
+		for (x = 0; x < g_max_loc_X; ++x)
+			draw_byte(' ', x, g_loc_Y);
 	}
 #endif
 }
@@ -391,9 +382,7 @@
 void BTEXT
 btext_drawstring(const char *c)
 {
-	unsigned long offset	= reloc_offset();
-
-	if (!RELOC(boot_text_mapped))
+	if (!boot_text_mapped)
 		return;
 	while (*c)
 		btext_drawchar(*c++);
@@ -403,28 +392,26 @@
 btext_drawhex(unsigned long v)
 {
 	static char hex_table[] = "0123456789abcdef";
-	unsigned long offset	= reloc_offset();
 	
-	if (!RELOC(boot_text_mapped))
+	if (!boot_text_mapped)
 		return;
-	btext_drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]);
-	btext_drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]);
-	btext_drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]);
-	btext_drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]);
-	btext_drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]);
-	btext_drawchar(RELOC(hex_table)[(v >>  8) & 0x0000000FUL]);
-	btext_drawchar(RELOC(hex_table)[(v >>  4) & 0x0000000FUL]);
-	btext_drawchar(RELOC(hex_table)[(v >>  0) & 0x0000000FUL]);
+	btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
+	btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
+	btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
+	btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
+	btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
+	btext_drawchar(hex_table[(v >>  8) & 0x0000000FUL]);
+	btext_drawchar(hex_table[(v >>  4) & 0x0000000FUL]);
+	btext_drawchar(hex_table[(v >>  0) & 0x0000000FUL]);
 	btext_drawchar(' ');
 }
 
 static void BTEXT
 draw_byte(unsigned char c, long locX, long locY)
 {
-	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
+	boot_infos_t* bi	= &disp_bi;
 	unsigned char *base	= calc_base(bi, locX << 3, locY << 4);
-	unsigned char *font	= &RELOC(vga_font)[((unsigned long)c) * 16];
+	unsigned char *font	= &vga_font[((unsigned long)c) * 16];
 	int rb			= bi->dispDeviceRowBytes;
 	
 	switch(bi->dispDeviceDepth) {
@@ -497,8 +484,7 @@
 	int l, bits;	
 	int fg = 0xFFFFFFFFUL;
 	int bg = 0x00000000UL;
-	unsigned long offset = reloc_offset();
-	unsigned long *eb = RELOC(expand_bits_16);
+	unsigned long *eb = expand_bits_16;
 
 	for (l = 0; l < 16; ++l)
 	{
@@ -517,8 +503,7 @@
 	int l, bits;	
 	int fg = 0x0F0F0F0FUL;
 	int bg = 0x00000000UL;
-	unsigned long offset = reloc_offset();
-	unsigned long *eb = RELOC(expand_bits_8);
+	unsigned long *eb = expand_bits_8;
 
 	for (l = 0; l < 16; ++l)
 	{
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
--- linux.orig/arch/ppc/kernel/chrp_setup.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/chrp_setup.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_setup.c 1.40 12/19/01 09:45:54 trini
+ * BK Id: SCCS/s.chrp_setup.c 1.42 04/09/02 21:43:09 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -374,7 +374,7 @@
 	openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq);
 	for ( i = 0 ; i < NUM_8259_INTERRUPTS  ; i++ )
 		irq_desc[i].handler = &i8259_pic;
-	i8259_init(NULL);
+	i8259_init(0);
 #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
 	/* see if there is a keyboard in the device tree
 	   with a parent of type "adb" */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/cputable.c linux/arch/ppc/kernel/cputable.c
--- linux.orig/arch/ppc/kernel/cputable.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/cputable.c	2002-07-20 01:08:37.000000000 +0000
@@ -28,6 +28,8 @@
 extern void __setup_cpu_7400(int cpu_nr);
 extern void __setup_cpu_7410(int cpu_nr);
 extern void __setup_cpu_7450(int cpu_nr);
+extern void __setup_cpu_7450_23(int cpu_nr);
+extern void __setup_cpu_7455(int cpu_nr);
 extern void __setup_cpu_power3(int cpu_nr);
 extern void __setup_cpu_power4(int cpu_nr);
 extern void __setup_cpu_8xx(int cpu_nr);
@@ -63,21 +65,24 @@
     },
     {	/* 603 */
     	0xffff0000, 0x00030000, "603",
-    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+    	CPU_FTR_CAN_NAP,
 	COMMON_PPC,
     	32, 32,
 	__setup_cpu_603
     },
     {	/* 603e */
     	0xffff0000, 0x00060000, "603e",
-    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+    	CPU_FTR_CAN_NAP,
 	COMMON_PPC,
 	32, 32,
 	__setup_cpu_603
     },
     {	/* 603ev */
     	0xffff0000, 0x00070000, "603ev",
-    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+    	CPU_FTR_CAN_NAP,
 	COMMON_PPC,
 	32, 32,
 	__setup_cpu_603
@@ -117,7 +122,7 @@
     {	/* 740/750 (0x4202, don't support TAU ?) */
     	0xffffffff, 0x00084202, "740/750",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE,
+	CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
 	COMMON_PPC,
 	32, 32,
 	__setup_cpu_750
@@ -125,7 +130,7 @@
     {	/* 745/755 */
     	0xfffff000, 0x00083000, "745/755",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
 	COMMON_PPC,
 	32, 32,
 	__setup_cpu_750
@@ -133,7 +138,15 @@
     {	/* 750CX */
     	0xffffff00, 0x00082200, "750CX",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_750
+    },
+    {	/* 750FX (All revs for now) */
+    	0xffff0000, 0x70000000, "750FX",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
 	COMMON_PPC,
 	32, 32,
 	__setup_cpu_750
@@ -141,7 +154,7 @@
     {	/* 740/750 (L2CR bit need fixup for 740) */
     	0xffff0000, 0x00080000, "740/750",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
 	COMMON_PPC,
 	32, 32,
 	__setup_cpu_750
@@ -149,7 +162,8 @@
     {	/* 7400 rev 1.1 ? (no TAU) */
     	0xffffffff, 0x000c1101, "7400 (1.1)",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+	CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+	CPU_FTR_CAN_NAP,
 	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
 	32, 32,
 	__setup_cpu_7400
@@ -157,7 +171,8 @@
     {	/* 7400 */
     	0xffff0000, 0x000c0000, "7400",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+	CPU_FTR_CAN_NAP,
 	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
 	32, 32,
 	__setup_cpu_7400
@@ -165,7 +180,8 @@
     {	/* 7410 */
     	0xffff0000, 0x800c0000, "7410",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+	CPU_FTR_CAN_NAP,
 	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
 	32, 32,
 	__setup_cpu_7410
@@ -173,21 +189,39 @@
     {	/* 7450 2.0 - no doze/nap */
     	0xffffffff, 0x80000200, "7450",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
 	CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
 	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
 	32, 32,
 	__setup_cpu_7450
     },
-    {	/* 7450 others */
-    	0xffff0000, 0x80000000, "7450",
-    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
-	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP |
+    {	/* 7450 2.1 */
+    	0xffffffff, 0x80000201, "7450",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
 	CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
 	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
 	32, 32,
 	__setup_cpu_7450
     },
+    {	/* 7450 2.3 and newer */
+    	0xffff0000, 0x80000000, "7450",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+	CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
+	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
+	32, 32,
+	__setup_cpu_7450_23
+    },
+    {	/* 7455 */
+    	0xffff0000, 0x80010000, "7455",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+	CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
+	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
+	32, 32,
+	__setup_cpu_7455
+    },
     {	/* 82xx (8240, 8245, 8260 are all 603e cores) */
 	0x7fff0000, 0x00810000, "82xx",
 	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- linux.orig/arch/ppc/kernel/head.S	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/head.S	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.head.S 1.34 12/02/01 11:35:27 benh
+ * BK Id: SCCS/s.head.S 1.43 06/25/02 17:24:29 benh
  */
 /*
  *  PowerPC version 
@@ -217,11 +217,17 @@
 	SYNC
 	RFI				/* enables MMU */
 
-#ifdef CONFIG_SMP
+/*
+ * We need __secondary_hold as a place to hold the other cpus on
+ * an SMP machine, even when we are running a UP kernel.
+ */
+	. = 0xc0			/* for prep bootloader */
+	li	r3,1			/* MTX only has 1 cpu */
 	.globl	__secondary_hold
 __secondary_hold:
 	/* tell the master we're here */
 	stw	r3,4(0)
+#ifdef CONFIG_SMP
 100:	lwz	r4,0(0)
 	/* wait until we're told to start */
 	cmpw	0,r4,r3
@@ -229,7 +235,9 @@
 	/* our cpu # was at addr 0 - go */
 	mr	r24,r3			/* cpu # */
 	b	__secondary_start
-#endif
+#else
+	b	.
+#endif /* CONFIG_SMP */
 
 /*
  * Exception entry code.  This code runs with address translation
@@ -301,6 +309,10 @@
 #endif
 
 /* Machine check */
+BEGIN_FTR_SECTION
+	DSSALL
+	sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
 
 /* Data access exception. */
@@ -313,11 +325,13 @@
 	EXCEPTION_PROLOG
 #endif /* CONFIG_PPC64BRIDGE */
 	mfspr	r20,DSISR
+BEGIN_FTR_SECTION
 	andis.	r0,r20,0xa470		/* weird error? */
 	bne	1f			/* if not, try to put a PTE */
 	mfspr	r4,DAR			/* into the hash table */
 	rlwinm	r3,r20,32-15,21,21	/* DSISR_STORE -> _PAGE_RW */
 	bl	hash_page
+END_FTR_SECTION_IFSET(CPU_FTR_HPTE_TABLE)
 1:	stw	r20,_DSISR(r21)
 	mr	r5,r20
 	mfspr	r4,DAR
@@ -354,11 +368,13 @@
 InstructionAccess:
 	EXCEPTION_PROLOG
 #endif /* CONFIG_PPC64BRIDGE */
+BEGIN_FTR_SECTION
 	andis.	r0,r23,0x4000		/* no pte found? */
 	beq	1f			/* if so, try to put a PTE */
 	li	r3,0			/* into the hash table */
 	mr	r4,r22			/* SRR0 is fault address */
 	bl	hash_page
+END_FTR_SECTION_IFSET(CPU_FTR_HPTE_TABLE)
 1:	addi	r3,r1,STACK_FRAME_OVERHEAD
 	mr	r4,r22
 	mr	r5,r23
@@ -1361,6 +1377,18 @@
 	bl	setup_7450_hid0
 	mtlr	r4
 	blr
+_GLOBAL(__setup_cpu_7450_23)
+	mflr	r4
+	bl	setup_common_caches
+	bl	setup_7450_23_hid0
+	mtlr	r4
+	blr
+_GLOBAL(__setup_cpu_7455)
+	mflr	r4
+	bl	setup_common_caches
+	bl	setup_7455_hid0
+	mtlr	r4
+	blr
 _GLOBAL(__setup_cpu_power3)
 	blr
 _GLOBAL(__setup_cpu_power4)
@@ -1430,21 +1458,53 @@
  */
 setup_7450_hid0:
 	/* We check for the presence of an L3 cache setup by
-	 * the firmware. If any, we disable DOZE capability
+	 * the firmware. If any, we disable NAP capability as
+	 * it's known to be bogus on rev 2.1 and earlier
 	 */
 	mfspr	r11,SPRN_L3CR
 	andis.	r11,r11,L3CR_L3E@h
 	beq	1f
-	li	r7,CPU_FTR_CAN_DOZE
+	li	r7,CPU_FTR_CAN_NAP
 	lwz	r6,CPU_SPEC_FEATURES(r5)
 	andc	r6,r6,r7
 	stw	r6,CPU_SPEC_FEATURES(r5)
 1:	
+setup_7450_23_hid0:
+	mfspr	r11,HID0
+
+	/* All of the bits we have to set.....
+	*/
+	ori	r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC | HID0_LRSTK
+	oris	r11,r11,HID0_DPM@h	/* enable dynamic power mgmt */
+
+	/* All of the bits we have to clear....
+	*/
+	li	r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI
+	andc	r11,r11,r3		/* clear SPD: enable speculative */
+ 	li	r3,0
+
+ 	mtspr	ICTC,r3			/* Instruction Cache Throttling off */
+	isync
+	mtspr	HID0,r11
+	sync
+	isync
+	blr
+
+/* 7450
+ * Enable Store Gathering (SGE), Branch Folding (FOLD)
+ * Branch History Table (BHTE), Branch Target ICache (BTIC)
+ * Dynamic Power Management (DPM), Speculative (SPD)
+ * Ensure our data cache instructions really operate.
+ * Timebase has to be running or we wouldn't have made it here,
+ * just ensure we don't disable it.
+ * Clear Instruction cache throttling (ICTC)
+ */
+setup_7455_hid0:
 	mfspr	r11,HID0
 
 	/* All of the bits we have to set.....
 	*/
-	ori	r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC
+	ori	r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC | HID0_LRSTK
 	oris	r11,r11,HID0_DPM@h	/* enable dynamic power mgmt */
 
 	/* All of the bits we have to clear....
@@ -1592,6 +1652,10 @@
 	li	r0,NUM_USER_SEGMENTS
 	mtctr	r0
 	li	r4,0
+BEGIN_FTR_SECTION
+	DSSALL
+	sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 3:
 #ifdef CONFIG_PPC64BRIDGE
 	slbie	r4
@@ -1601,7 +1665,7 @@
 	rlwinm	r3,r3,0,8,3	/* clear out any overflow from VSID field */
 	addis	r4,r4,0x1000	/* address of next segment */
 	bdnz	3b
-	SYNC_601
+	sync
 	isync
 	blr
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/head_8xx.S linux/arch/ppc/kernel/head_8xx.S
--- linux.orig/arch/ppc/kernel/head_8xx.S	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/kernel/head_8xx.S	2002-07-20 01:08:36.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.head_8xx.S 1.23 09/16/01 19:32:54 trini
+ * BK Id: SCCS/s.head_8xx.S 1.25 01/08/02 16:41:27 trini
  */
 /*
  *  arch/ppc/kernel/except_8xx.S
@@ -521,6 +521,34 @@
 	andis.	r21, r20, 0x0200	/* If set, indicates store op */
 	beq	2f
 
+	/* The EA of a data TLB miss is automatically stored in the MD_EPN 
+	 * register.  The EA of a data TLB error is automatically stored in 
+	 * the DAR, but not the MD_EPN register.  We must copy the 20 most 
+	 * significant bits of the EA from the DAR to MD_EPN before we 
+	 * start walking the page tables.  We also need to copy the CASID 
+	 * value from the M_CASID register.
+	 * Addendum:  The EA of a data TLB error is _supposed_ to be stored 
+	 * in DAR, but it seems that this doesn't happen in some cases, such 
+	 * as when the error is due to a dcbi instruction to a page with a 
+	 * TLB that doesn't have the changed bit set.  In such cases, there 
+	 * does not appear to be any way  to recover the EA of the error 
+	 * since it is neither in DAR nor MD_EPN.  As a workaround, the 
+	 * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs 
+	 * are initialized in mapin_ram().  This will avoid the problem, 
+	 * assuming we only use the dcbi instruction on kernel addresses.
+	 */
+	mfspr	r20, DAR
+	rlwinm	r21, r20, 0, 0, 19
+	ori	r21, r21, MD_EVALID
+	mfspr	r20, M_CASID
+	rlwimi	r21, r20, 0, 28, 31
+#ifdef CONFIG_8xx_CPU6
+	li	r3, 0x3780
+	stw	r3, 12(r0)
+	lwz	r3, 12(r0)
+#endif
+	mtspr	MD_EPN, r21
+
 	mfspr	r20, M_TWB	/* Get level 1 table entry address */
 
 	/* If we are faulting a kernel address, we have to use the
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/idle.c linux/arch/ppc/kernel/idle.c
--- linux.orig/arch/ppc/kernel/idle.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/idle.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.idle.c 1.18 12/01/01 20:09:06 benh
+ * BK Id: SCCS/s.idle.c 1.20 03/19/02 15:04:39 benh
  */
 /*
  * Idle daemon for PowerPC.  Idle daemon will handle any action
@@ -49,7 +49,9 @@
 {
 	int do_power_save = 0;
 
-	if (cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_CAN_DOZE)
+	/* Check if CPU can powersave */
+	if (cur_cpu_spec[smp_processor_id()]->cpu_features &
+		(CPU_FTR_CAN_DOZE | CPU_FTR_CAN_NAP))
 		do_power_save = 1;
 
 	/* endless loop with no priority at all */
@@ -227,6 +229,8 @@
 }
 #endif /* 0 */
 
+#define DSSALL		.long	(0x1f<<26)+(0x10<<21)+(0x336<<1)
+
 void power_save(void)
 {
 	unsigned long hid0;
@@ -235,7 +239,7 @@
 	/* 7450 has no DOZE mode mode, we return if powersave_nap
 	 * isn't enabled
 	 */
-	if (!nap &&  cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_SPEC7450)
+	if (!(nap || (cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_CAN_DOZE)))
 		return;
 	/*
 	 * Disable interrupts to prevent a lost wakeup
@@ -252,10 +256,23 @@
 	_nmask_and_or_msr(MSR_EE, 0);
 	if (!current->need_resched)
 	{
-		asm("mfspr %0,1008" : "=r" (hid0) :);
+		__asm__ __volatile__("mfspr %0,1008" : "=r" (hid0) :);
 		hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE);
 		hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM;
-		asm("mtspr 1008,%0" : : "r" (hid0));
+		__asm__ __volatile__("mtspr 1008,%0" : : "r" (hid0));
+		/* Flush pending data streams, consider this instruction
+		 * exist on all altivec capable CPUs
+		 */
+		__asm__ __volatile__(
+			"98:	" stringify(DSSALL) "\n"
+			"	sync\n"
+			"99:\n"
+			".section __ftr_fixup,\"a\"\n"
+			"	.long %0\n"
+			"	.long %1\n"
+			"	.long 98b\n"
+			"	.long 99b\n"
+			".previous" : : "i" (CPU_FTR_ALTIVEC), "i" (CPU_FTR_ALTIVEC));
 		
 		/* set the POW bit in the MSR, and enable interrupts
 		 * so we wake up sometime! */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- linux.orig/arch/ppc/kernel/irq.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/irq.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.irq.c 1.34 12/01/01 20:09:06 benh
+ * BK Id: %F% %I% %G% %U% %#%
  */
 /*
  *  arch/ppc/kernel/irq.c
@@ -985,7 +985,7 @@
 	struct proc_dir_entry *entry;
 	char name [MAX_NAMELEN];
 
-	if (!root_irq_dir || (irq_desc[irq].handler == NULL))
+	if (!root_irq_dir || (irq_desc[irq].handler == NULL) || irq_dir[irq])
 		return;
 
 	memset(name, 0, MAX_NAMELEN);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/l2cr.S linux/arch/ppc/kernel/l2cr.S
--- linux.orig/arch/ppc/kernel/l2cr.S	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/l2cr.S	2002-07-20 01:08:22.000000000 +0000
@@ -134,6 +134,8 @@
 	       The bit moved on the 7450.....
 	  ****/
 
+	/* TODO: use HW flush assist when available */
+
 	lis	r4,0x0002
 	mtctr	r4
 	li	r4,0
@@ -154,10 +156,18 @@
 
 2:
 	/* Set up the L2CR configuration bits (and switch L2 off) */
+	/* CPU errata: Make sure the mtspr below is already in the
+	 * L1 icache
+	 */
+	b	20f
+21:
 	sync
 	mtspr	L2CR,r3
 	sync
-
+	b	22f
+20:
+	b	21b
+22:
 	/* Before we perform the global invalidation, we must disable dynamic
 	 * power management via HID0[DPM] to work around a processor bug where
 	 * DPM can possibly interfere with the state machine in the processor
@@ -223,5 +233,147 @@
 END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
 	blr
 
+
+/*
+ * Here is a similar routine for dealing with the L3 cache
+ * on the 745x family of chips
+ */
+ 
+_GLOBAL(_set_L3CR)
+	/* Make sure this is a 745x chip */
+BEGIN_FTR_SECTION
+	li	r3,-1
+	blr
+END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
+
+	/* Turn off interrupts and data relocation. */
+	mfmsr	r7		/* Save MSR in r7 */
+	rlwinm	r4,r7,0,17,15
+	rlwinm	r4,r4,0,28,26	/* Turn off DR bit */
+	sync
+	mtmsr	r4
+	isync
+
+	/* Stop DST streams */
+	DSSALL
+	
+	/* Get the current enable bit of the L3CR into r4 */
+	mfspr	r4,SPRN_L3CR
+	
+	/* Tweak some bits */
+	rlwinm	r5,r3,0,0,0		/* r5 contains the new enable bit */
+	rlwinm	r3,r3,0,22,20		/* Turn off the invalidate bit */
+	rlwinm	r3,r3,0,1,31		/* Turn off the enable bit */
+	rlwinm	r3,r3,0,5,3		/* Turn off the clken bit */
+	/* Check to see if we need to flush */
+	rlwinm.	r4,r4,0,0,0
+	beq	2f
+
+	/* Flush the cache. First, read the first 4MB of memory (physical) to
+	 * put new data in the cache.  (Actually we only need
+	 * the size of the L3 cache plus the size of the L1+L2 cache, but 4MB will
+	 * cover everything just to be safe).
+	 */
+		
+	/* TODO: use HW flush assist */
+
+	lis	r4,0x0002
+	mtctr	r4
+	li	r4,0
+1:
+	lwzx	r0,r0,r4
+	addi	r4,r4,32		/* Go to start of next cache line */
+	bdnz	1b
+	
+	/* Now, flush the first 4MB of memory */
+	lis	r4,0x0002
+	mtctr	r4
+	li	r4,0
+	sync
+1:
+	dcbf	r0,r4
+	addi	r4,r4,32		/* Go to start of next cache line */
+	bdnz	1b
+
+2:
+	/* Set up the L3CR configuration bits (and switch L3 off) */
+	sync
+	mtspr	SPRN_L3CR,r3
+	sync
+
+	/* Before we perform the global invalidation, we must disable dynamic
+	 * power management via HID0[DPM] to work around a processor bug where
+	 * DPM can possibly interfere with the state machine in the processor
+	 * that invalidates the L3 cache tags. Hrm... This is necessary for L2,
+	 * is it for L3 as well ? --BenH.
+	 */
+	mfspr	r8,HID0			/* Save HID0 in r8 */
+	rlwinm	r4,r8,0,12,10		/* Turn off HID0[DPM] */
+	sync
+	mtspr	HID0,r4			/* Disable DPM */
+	sync
+
+	oris	r3,r3,L3CR_L3RES@h		/* Set reserved bit 5 */
+	mtspr	SPRN_L3CR,r3
+	sync
+	oris	r3,r3,L3CR_L3CLKEN@h		/* Set clken */
+	mtspr	SPRN_L3CR,r3
+	sync
+
+	/* Wait for stabilize */
+	li	r0,128
+	mtctr	r0
+1:	bdnz	1b
+	
+	/* Perform a global invalidation */
+	ori	r3,r3,0x0400
+	sync
+	mtspr	SPRN_L3CR,r3
+	sync
+	isync
+
+	/* We wait for the L3I bit to clear...... */
+10:	mfspr	r3,SPRN_L3CR
+	andi.	r4,r3,0x0400
+	bne	10b
+
+	/* Clear CLKEN */
+	rlwinm	r3,r3,0,5,3		/* Turn off the clken bit */
+	mtspr	SPRN_L3CR,r3
+	sync
+
+	/* Wait for stabilize */
+	li	r0,128
+	mtctr	r0
+1:	bdnz	1b
+	
+	/* Restore HID0[DPM] to whatever it was before */
+	sync
+	mtspr	1008,r8
+	sync
+
+	/* See if we need to enable the cache */
+	cmplwi	r5,0
+	beq	4f
+
+	/* Enable the cache */
+	oris	r3,r3,(L3CR_L3E | L3CR_L3CLKEN)@h
+	mtspr	SPRN_L3CR,r3
+	sync
+
+	/* Restore MSR (restores EE and DR bits to original state) */
+4:	SYNC
+	mtmsr	r7
+	isync
+	blr
+
+_GLOBAL(_get_L3CR)
+	/* Return the L3CR contents */
+	li	r3,0
+BEGIN_FTR_SECTION
+	mfspr	r3,SPRN_L3CR
+END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
+	blr
+
 /* --- End of PowerLogix code ---
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/m8xx_setup.c linux/arch/ppc/kernel/m8xx_setup.c
--- linux.orig/arch/ppc/kernel/m8xx_setup.c	2001-11-16 18:10:08.000000000 +0000
+++ linux/arch/ppc/kernel/m8xx_setup.c	2002-07-20 01:08:34.000000000 +0000
@@ -55,12 +55,6 @@
 
 extern void m8xx_ide_init(void);
 
-#ifdef CONFIG_BLK_DEV_RAM
-extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
-extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
-extern int rd_image_start;	/* starting block # of image */
-#endif
-
 extern unsigned long find_available_memory(void);
 extern void m8xx_cpm_reset(uint);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- linux.orig/arch/ppc/kernel/misc.S	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/misc.S	2002-07-20 01:08:32.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.misc.S 1.36 12/01/01 20:09:06 benh
+ * BK Id: SCCS/s.misc.S 1.44 06/25/02 17:24:30 benh
  */
 /*
  * This file contains miscellaneous low-level functions.
@@ -39,7 +39,6 @@
  * Returns (address we're running at) - (address we were linked at)
  * for use before the text and data are mapped to KERNELBASE.
  */
-
 _GLOBAL(reloc_offset)
 	mflr	r0
 	bl	1f
@@ -51,6 +50,62 @@
 	blr
 
 /*
+ * add_reloc_offset(x) returns x + reloc_offset().
+ */
+_GLOBAL(add_reloc_offset)
+	mflr	r0
+	bl	1f
+1:	mflr	r5
+	lis	r4,1b@ha
+	addi	r4,r4,1b@l
+	subf	r5,r4,r5
+	add	r3,r3,r5
+	mtlr	r0
+	blr
+
+/*
+ * sub_reloc_offset(x) returns x - reloc_offset().
+ */
+_GLOBAL(sub_reloc_offset)
+	mflr	r0
+	bl	1f
+1:	mflr	r5
+	lis	r4,1b@ha
+	addi	r4,r4,1b@l
+	subf	r5,r4,r5
+	subf	r3,r5,r3
+	mtlr	r0
+	blr
+
+/*
+ * reloc_got2 runs through the .got2 section adding an offset
+ * to each entry.
+ */
+_GLOBAL(reloc_got2)
+	mflr	r11
+	lis	r7,__got2_start@ha
+	addi	r7,r7,__got2_start@l
+	lis	r8,__got2_end@ha
+	addi	r8,r8,__got2_end@l
+	subf	r8,r7,r8
+	srwi.	r8,r8,2
+	beqlr
+	mtctr	r8
+	bl	1f
+1:	mflr	r0
+	lis	r4,1b@ha
+	addi	r4,r4,1b@l
+	subf	r0,r4,r0
+	add	r7,r0,r7
+2:	lwz	r0,0(r7)
+	add	r0,r0,r3
+	stw	r0,0(r7)
+	addi	r7,r7,4
+	bdnz	2b
+	mtlr	r11
+	blr
+
+/*
  * identify_cpu,
  * called with r3 = data offset and r4 = CPU number
  * doesn't change r3
@@ -281,7 +336,8 @@
 	mfmsr	r0		/* Get current msr */
 	andc	r0,r0,r3	/* And off the bits set in r3 (first parm) */
 	or	r0,r0,r4	/* Or on the bits in r4 (second parm) */
-	SYNC			/* Some chip revs have problems here... */
+	sync			/* Some chip revs have problems here... */
+	isync
 	mtmsr	r0		/* Update machine state */
 	isync
 	blr			/* Done */
@@ -307,7 +363,7 @@
 	stwcx.	r8,0,r9
 	bne-	10b
 #endif /* CONFIG_SMP */
-	sync
+	isync
 	tlbia
 	sync
 #ifdef CONFIG_SMP
@@ -316,7 +372,7 @@
 	stw	r0,0(r9)		/* clear hash_table_lock */
 	mtmsr	r10
 	SYNC
-#endif
+#endif /* CONFIG_SMP */
 	blr	
 
 /*
@@ -338,8 +394,8 @@
 	bne-	10b
 	stwcx.	r8,0,r9
 	bne-	10b
-	eieio
 #endif /* CONFIG_SMP */
+	isync
 	tlbie	r3
 	sync
 #ifdef CONFIG_SMP
@@ -478,9 +534,9 @@
  * snoop from the data cache.
  * This is a no-op on the 601 which has a unified cache.
  *
- *	void __flush_page_to_ram(void *page)
+ *	void __flush_dcache_icache(void *page)
  */
-_GLOBAL(__flush_page_to_ram)
+_GLOBAL(__flush_dcache_icache)
 	mfspr	r5,PVR
 	rlwinm	r5,r5,16,16,31
 	cmpi	0,r5,1
@@ -500,28 +556,6 @@
 	sync
 	isync
 	blr
-
-/*
- * Flush a particular page from the instruction cache.
- * Note: this is necessary because the instruction cache does *not*
- * snoop from the data cache.
- * This is a no-op on the 601 which has a unified cache.
- *
- *	void __flush_icache_page(void *page)
- */
-_GLOBAL(__flush_icache_page)
-	mfspr	r5,PVR
-	rlwinm	r5,r5,16,16,31
-	cmpi	0,r5,1
-	beqlr					/* for 601, do nothing */
-	li	r4,4096/L1_CACHE_LINE_SIZE	/* Number of lines in a page */
-	mtctr	r4
-1:	icbi	0,r3
-	addi	r3,r3,L1_CACHE_LINE_SIZE
-	bdnz	1b
-	sync
-	isync
-	blr
 	
 /*
  * Clear a page using the dcbz instruction, which doesn't cause any
@@ -1122,6 +1156,7 @@
 	.long sys_madvise	/* 205 */
 	.long sys_mincore
 	.long sys_gettid
+	.long sys_tkill
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
 	.endr
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c
--- linux.orig/arch/ppc/kernel/pci.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/pci.c	2002-07-20 01:08:36.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pci.c 1.40 01/25/02 15:15:24 benh
+ * BK Id: SCCS/s.pci.c 1.43 05/08/02 15:01:15 benh
  */
 /*
  * Common pmac/prep/chrp pci routines. -- Cort
@@ -46,6 +46,7 @@
 static void pcibios_fixup_resources(struct pci_dev* dev);
 static void fixup_broken_pcnet32(struct pci_dev* dev);
 static void fixup_rev1_53c810(struct pci_dev* dev);
+static void fixup_cpc710_pci64(struct pci_dev* dev);
 #ifdef CONFIG_ALL_PPC
 static void pcibios_fixup_cardbus(struct pci_dev* dev);
 static u8* pci_to_OF_bus_map;
@@ -64,6 +65,7 @@
 struct pci_fixup pcibios_fixups[] = {
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_TRIDENT,	PCI_ANY_ID,			fixup_broken_pcnet32 },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_NCR,	PCI_DEVICE_ID_NCR_53C810,	fixup_rev1_53c810 },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CPC710_PCI64,	fixup_cpc710_pci64},
 	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,		PCI_ANY_ID,			pcibios_fixup_resources },
 #ifdef CONFIG_ALL_PPC
 	/* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */
@@ -95,6 +97,18 @@
 	}
 }
 
+static void
+fixup_cpc710_pci64(struct pci_dev* dev)
+{
+	/* Hide the PCI64 BARs from the kernel as their content doesn't
+	 * fit well in the resource management
+	 */
+	dev->resource[0].start = dev->resource[0].end = 0;
+	dev->resource[0].flags = 0;
+	dev->resource[1].start = dev->resource[1].end = 0;
+	dev->resource[1].flags = 0;
+}
+
 void
 pcibios_update_resource(struct pci_dev *dev, struct resource *root,
 			     struct resource *res, int resource)
@@ -179,14 +193,24 @@
 	if (_machine != _MACH_Pmac)
 		return;
 	/*
-	 * Fix the interrupt routing on the TI1211 chip on the 1999
-	 * G3 powerbook, which doesn't get initialized properly by OF.
-	 * Same problem with the 1410 of the new titanium pbook which
-	 * has the same register.
+	 * Fix the interrupt routing on the various cardbus bridges
+	 * used on powerbooks
 	 */
-	if (dev->vendor == PCI_VENDOR_ID_TI
-	    && (dev->device == PCI_DEVICE_ID_TI_1211 ||
-	        dev->device == PCI_DEVICE_ID_TI_1410)) {
+	if (dev->vendor != PCI_VENDOR_ID_TI)
+		return;
+	if (dev->device == PCI_DEVICE_ID_TI_1130 ||
+	    dev->device == PCI_DEVICE_ID_TI_1131) {
+		u8 val;
+	    	/* Enable PCI interrupt */
+		if (pci_read_config_byte(dev, 0x91, &val) == 0)
+			pci_write_config_byte(dev, 0x91, val | 0x30);
+		/* Disable ISA interrupt mode */	
+		if (pci_read_config_byte(dev, 0x92, &val) == 0)
+			pci_write_config_byte(dev, 0x92, val & ~0x06);
+	}
+	if (dev->device == PCI_DEVICE_ID_TI_1210 ||
+	    dev->device == PCI_DEVICE_ID_TI_1211 ||
+	    dev->device == PCI_DEVICE_ID_TI_1410) {
 		u8 val;
 		/* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
 		   signal out the MFUNC0 pin */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/pmac_feature.c linux/arch/ppc/kernel/pmac_feature.c
--- linux.orig/arch/ppc/kernel/pmac_feature.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/pmac_feature.c	2002-07-20 01:08:28.000000000 +0000
@@ -193,13 +193,14 @@
 }
 
 static int __pmac
-generic_scc_enable(struct device_node* node, u32 enable_mask, u32 reset_mask,
-	int param, int value)
+ohare_htw_scc_enable(struct device_node* node, int param, int value)
 {
 	struct macio_chip*	macio;
 	unsigned long		chan_mask;
 	unsigned long		fcr;
 	unsigned long		flags;
+	int			htw, trans;
+	unsigned long		rmask;
 	
 	macio = macio_find(node, 0);
 	if (!macio)
@@ -211,20 +212,41 @@
 	else
 		return -ENODEV;
 
+	htw = (macio->type == macio_heathrow || macio->type == macio_paddington
+		|| macio->type == macio_gatwick);
+	/* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
+	trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
+	    	 pmac_mb.model_id != PMAC_TYPE_YIKES);
 	if (value) {
+#ifdef CONFIG_ADB_PMU
+		if ((param & 0xfff) == PMAC_SCC_IRDA)
+			pmu_enable_irled(1);
+#endif /* CONFIG_ADB_PMU */		
 		LOCK(flags);
 		fcr = MACIO_IN32(OHARE_FCR);
 		/* Check if scc cell need enabling */
 		if (!(fcr & OH_SCC_ENABLE)) {
-			fcr |= enable_mask;
-			MACIO_OUT32(OHARE_FCR, fcr);
-			fcr |= reset_mask;
-			MACIO_OUT32(OHARE_FCR, fcr);
+			fcr |= OH_SCC_ENABLE;
+			if (htw) {
+				/* Side effect: this will also power up the
+				 * modem, but it's too messy to figure out on which
+				 * ports this controls the tranceiver and on which
+				 * it controls the modem
+				 */
+				if (trans)
+					fcr &= ~HRW_SCC_TRANS_EN_N;
+				MACIO_OUT32(OHARE_FCR, fcr);
+				fcr |= (rmask = HRW_RESET_SCC);
+				MACIO_OUT32(OHARE_FCR, fcr);
+			} else {
+				fcr |= (rmask = OH_SCC_RESET);
+				MACIO_OUT32(OHARE_FCR, fcr);
+			}
 			UNLOCK(flags);
 			(void)MACIO_IN32(OHARE_FCR);
 			mdelay(15);
 			LOCK(flags);
-			fcr &= ~reset_mask;
+			fcr &= ~rmask;
 			MACIO_OUT32(OHARE_FCR, fcr);
 		}
 		if (chan_mask & MACIO_FLAG_SCCA_ON)
@@ -247,31 +269,20 @@
 			fcr &= ~OH_SCCB_IO;
 		MACIO_OUT32(OHARE_FCR, fcr);
 		if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
-			fcr &= ~enable_mask;
+			fcr &= ~OH_SCC_ENABLE;
+			if (htw && trans)
+				fcr |= HRW_SCC_TRANS_EN_N;
 			MACIO_OUT32(OHARE_FCR, fcr);
 		}
 		macio->flags &= ~(chan_mask);
 		UNLOCK(flags);
 		mdelay(10);
-	}
-	return 0;
-}
-
-static int __pmac
-ohare_scc_enable(struct device_node* node, int param, int value)
-{
-	int rc;
-
 #ifdef CONFIG_ADB_PMU
-	if (value && (param & 0xfff) == PMAC_SCC_IRDA)
-		pmu_enable_irled(1);
+		if ((param & 0xfff) == PMAC_SCC_IRDA)
+			pmu_enable_irled(0);
 #endif /* CONFIG_ADB_PMU */		
-	rc = generic_scc_enable(node, OH_SCC_ENABLE, OH_SCC_RESET, param, value);
-#ifdef CONFIG_ADB_PMU
-	if ((param & 0xfff) == PMAC_SCC_IRDA && (rc || !value))
-		pmu_enable_irled(0);
-#endif /* CONFIG_ADB_PMU */		
-	return rc;
+	}
+	return 0;
 }
 
 static int __pmac
@@ -331,9 +342,9 @@
 
 	if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
 		return -EPERM;
-	if (value) {
+	if (value == 1) {
 		MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
-	} else {
+	} else if (value == 0) {
 		MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
 	}
 	
@@ -341,27 +352,6 @@
 }
 
 static int __pmac
-heathrow_scc_enable(struct device_node* node, int param, int value)
-{
-	int rc;
-	
-#ifdef CONFIG_ADB_PMU
-	if (value && param == PMAC_SCC_IRDA)
-		pmu_enable_irled(1);
-#endif /* CONFIG_ADB_PMU */		
-	/* Fixme: It's possible that wallstreet (heathrow) is different
-	 * than other paddington machines. I still have to figure that
-	 * out exactly, for now, the paddington values are used
-	 */
-	rc = generic_scc_enable(node, HRW_SCC_ENABLE, PADD_RESET_SCC, param, value);
-#ifdef CONFIG_ADB_PMU
-	if (param == PMAC_SCC_IRDA && (rc || !value))
-		pmu_enable_irled(0);
-#endif /* CONFIG_ADB_PMU */		
-	return rc;
-}
-
-static int __pmac
 heathrow_modem_enable(struct device_node* node, int param, int value)
 {
 	struct macio_chip*	macio;
@@ -382,16 +372,10 @@
 	if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
 	    pmac_mb.model_id != PMAC_TYPE_YIKES) {
 	    	LOCK(flags);
-	    	/* We use the paddington values as they seem to work properly
-	    	 * on the wallstreet (heathrow) as well. I can't tell why we
-	    	 * had to flip them on older feature.c, the fact is that new
-	    	 * code uses the paddington values which are also the ones used
-	    	 * in Darwin, and that works on wallstreet !
-	    	 */
 	    	if (value)
-	    		MACIO_BIC(HEATHROW_FCR, PADD_MODEM_POWER_N);
+	    		MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
 	    	else
-	    		MACIO_BIS(HEATHROW_FCR, PADD_MODEM_POWER_N);
+	    		MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
 	    	UNLOCK(flags);
 	    	(void)MACIO_IN32(HEATHROW_FCR);
 		mdelay(250);
@@ -406,7 +390,7 @@
 	    	UNLOCK(flags); mdelay(250); LOCK(flags);
 		MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
 		(void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
-	    	UNLOCK(flags); mdelay(250); LOCK(flags);
+	    	UNLOCK(flags); mdelay(250);
 	}
 	return 0;
 }
@@ -614,11 +598,14 @@
 		/* This seems to be necessary as well or the fan
 		 * keeps coming up and battery drains fast */
 		MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
+		/* Make sure eth is down even if module or sleep
+		 * won't work properly */
+		MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
 	}
 	/* Make sure modem is shut down */
 	MACIO_OUT8(HRW_GPIO_MODEM_RESET,
 		MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
-	MACIO_BIS(HEATHROW_FCR, PADD_MODEM_POWER_N);
+	MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
 	MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
 
 	/* Let things settle */
@@ -810,7 +797,7 @@
 	    	UNLOCK(flags); mdelay(250); LOCK(flags);
 		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
 		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
-	    	UNLOCK(flags); mdelay(250); LOCK(flags);
+	    	UNLOCK(flags); mdelay(250);
 	}
 	return 0;
 }
@@ -1467,7 +1454,7 @@
 	    	UNLOCK(flags); mdelay(250); LOCK(flags);
 		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
 		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
-	    	UNLOCK(flags); mdelay(250); LOCK(flags);
+	    	UNLOCK(flags); mdelay(250);
 	}
 	return 0;
 }
@@ -1483,7 +1470,8 @@
 			return pmac_mb.board_flags;
 		case PMAC_MB_INFO_NAME:	
 			/* hack hack hack... but should work */
-			return (int)pmac_mb.model_name;
+			*((const char **)value) = pmac_mb.model_name;
+			break;
 	}
 	return 0;
 }
@@ -1505,7 +1493,7 @@
  * to have issues with turning on/off those asic cells
  */
 static struct feature_table_entry ohare_features[]  __pmacdata = {
-	{ PMAC_FTR_SCC_ENABLE,		ohare_scc_enable },
+	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
 	{ PMAC_FTR_SWIM3_ENABLE,	ohare_floppy_enable },
 	{ PMAC_FTR_MESH_ENABLE,		ohare_mesh_enable },
 	{ PMAC_FTR_IDE_ENABLE,		ohare_ide_enable},
@@ -1531,7 +1519,7 @@
  * powerbooks.
  */
 static struct feature_table_entry heathrow_laptop_features[]  __pmacdata = {
-	{ PMAC_FTR_SCC_ENABLE,		heathrow_scc_enable },
+	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
 	{ PMAC_FTR_MODEM_ENABLE,	heathrow_modem_enable },
 	{ PMAC_FTR_SWIM3_ENABLE,	heathrow_floppy_enable },
 	{ PMAC_FTR_MESH_ENABLE,		heathrow_mesh_enable },
@@ -1547,7 +1535,7 @@
  * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
  */
 static struct feature_table_entry paddington_features[]  __pmacdata = {
-	{ PMAC_FTR_SCC_ENABLE,		heathrow_scc_enable },
+	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
 	{ PMAC_FTR_MODEM_ENABLE,	heathrow_modem_enable },
 	{ PMAC_FTR_SWIM3_ENABLE,	heathrow_floppy_enable },
 	{ PMAC_FTR_MESH_ENABLE,		heathrow_mesh_enable },
@@ -1621,6 +1609,10 @@
 		PMAC_TYPE_PSURGE,		NULL,
 		0
 	},
+	{	"AAPL,ShinerESB",		"Apple Network Server",
+		PMAC_TYPE_ANS,			NULL,
+		0
+	},
 	{	"AAPL,e407",			"Alchemy",
 		PMAC_TYPE_ALCHEMY,		NULL,
 		0
@@ -1661,10 +1653,22 @@
 		PMAC_TYPE_PANGEA_IMAC,		pangea_features,
 		PMAC_MB_CAN_SLEEP
 	},
+	{	"PowerBook4,3",			"iBook 2 with 14\" LCD",
+		PMAC_TYPE_IBOOK2,		pangea_features,
+		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+	},
+	{	"PowerBook4,2",			"iBook 2 with 14\" LCD",
+		PMAC_TYPE_IBOOK2,		pangea_features,
+		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+	},
 	{	"PowerBook4,1",			"iBook 2",
 		PMAC_TYPE_IBOOK2,		pangea_features,
 		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
 	},
+	{	"PowerMac4,2",			"Flat panel iMac",
+		PMAC_TYPE_FLAT_PANEL_IMAC,	pangea_features,
+		PMAC_MB_CAN_SLEEP
+	},
 	{	"PowerMac1,1",			"Blue&White G3",
 		PMAC_TYPE_YOSEMITE,		paddington_features,
 		0
@@ -1724,6 +1728,10 @@
 		PMAC_TYPE_TITANIUM2,		core99_features,
 		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
 	},
+	{	"PowerBook3,4",			"PowerBook Titanium III",
+		PMAC_TYPE_TITANIUM3,		core99_features,
+		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+	},
 };
 
 /*
@@ -1737,13 +1745,12 @@
 	feature_call func = NULL;
 	va_list args;
 	
-	if (!pmac_mb.features)
-		return -ENODEV;
-	for (i=0; pmac_mb.features[i].function; i++)
-		if (pmac_mb.features[i].selector == selector) {
-			func = pmac_mb.features[i].function;
-			break;
-		}
+	if (pmac_mb.features)
+		for (i=0; pmac_mb.features[i].function; i++)
+			if (pmac_mb.features[i].selector == selector) {
+				func = pmac_mb.features[i].function;
+				break;
+			}
 	if (!func)
 		for (i=0; any_features[i].function; i++)
 			if (any_features[i].selector == selector) {
@@ -2062,11 +2069,21 @@
 		}
 	}
 
-	/* On all machines, switch sound off */
+	/* On all machines that support sound PM, switch sound off */
 	if (macio_chips[0].of_node)
 		pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
 			macio_chips[0].of_node, 0, 0);
 
+	/* While on some desktop G3s, we turn it back on */
+	if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
+		&& (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
+		    pmac_mb.model_id == PMAC_TYPE_SILK)) {
+		struct macio_chip* macio = &macio_chips[0];
+		MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+		MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
+	}
+
+
 	/* On all machines, switch modem & serial ports off */
 	np = find_devices("ch-a");
 	while(np) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c
--- linux.orig/arch/ppc/kernel/pmac_pci.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/pmac_pci.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_pci.c 1.31 01/20/02 23:53:11 benh
+ * BK Id: SCCS/s.pmac_pci.c 1.35 05/06/02 01:37:30 benh
  */
 /*
  * Support for PCI bridges found on Power Macintoshes.
@@ -258,21 +258,12 @@
 		rev = in_8(bp->cfg_data);
 		if (rev != BANDIT_REVID)
 			printk(KERN_WARNING
-			       "Unknown revision %d for bandit at %08lx\n",
-			       rev, bp->io_base_phys);
+			       "Unknown revision %d for bandit\n", rev);
 	} else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
 		printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
 		return;
 	}
 
-	/* read the revision id */
-	out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
-	udelay(2);
-	rev = in_8(bp->cfg_data);
-	if (rev != BANDIT_REVID)
-		printk(KERN_WARNING "Unknown revision %d for bandit at %08lx\n",
-		       rev, bp->io_base_phys);
-
 	/* read the word at offset 0x50 */
 	out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
 	udelay(2);
@@ -282,8 +273,7 @@
 	magic |= BANDIT_COHERENT;
 	udelay(2);
 	out_le32((volatile unsigned int *)bp->cfg_data, magic);
-	printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %08lx\n",
-	       bp->io_base_phys);
+	printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
 }
 
 
@@ -492,26 +482,16 @@
 {	
 	struct pci_dev* dev;
 	
-	pci_for_each_dev(dev)
-	{
-		/*
-		 * Open Firmware often doesn't initialize the,
-		 * PCI_INTERRUPT_LINE config register properly, so we
-		 * should find the device node and se if it has an
-		 * AAPL,interrupts property.
-		 */
-		unsigned char pin;
-		struct device_node* node;
-			
-		if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || !pin)
-			continue; /* No interrupt generated -> no fixup */
-		node = pci_device_to_OF_node(dev);
-		if (!node) {
-			printk("No OF node for device %x:%x\n", dev->bus->number, dev->devfn >> 3);
-			continue;
-		}
+	/*
+	 * Open Firmware often doesn't initialize the
+	 * PCI_INTERRUPT_LINE config register properly, so we
+	 * should find the device node and apply the interrupt
+	 * obtained from the OF device-tree
+	 */
+	pci_for_each_dev(dev) {
+		struct device_node* node = pci_device_to_OF_node(dev);
 		/* this is the node, see if it has interrupts */
-		if (node->n_intrs > 0) 
+		if (node && node->n_intrs > 0)
 			dev->irq = node->intrs[0].line;
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c
--- linux.orig/arch/ppc/kernel/pmac_setup.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/pmac_setup.c	2002-07-20 01:08:25.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_setup.c 1.45 12/01/01 20:09:06 benh
+ * BK Id: SCCS/s.pmac_setup.c 1.54 04/16/02 20:08:22 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -50,6 +50,8 @@
 #include <linux/cuda.h>
 #include <linux/pmu.h>
 #include <linux/seq_file.h>
+#include <linux/blkdev.h>
+#include <linux/genhd.h>
 
 #include <asm/processor.h>
 #include <asm/sections.h>
@@ -67,14 +69,14 @@
 #include <asm/bootx.h>
 #include <asm/cputable.h>
 #include <asm/btext.h>
-
 #include <asm/pmac_feature.h>
 #include <asm/time.h>
+
 #include "local_irq.h"
 #include "pmac_pic.h"
-#include "../mm/mem_pieces.h"
-
-#undef SHOW_GATWICK_IRQS
+#include "mem_pieces.h"
+#include "scsi.h" /* sd_find_target */
+#include "sd.h"
 
 extern long pmac_time_init(void);
 extern unsigned long pmac_get_rtc_time(void);
@@ -140,26 +142,6 @@
 #ifdef CONFIG_SMP
 extern struct smp_ops_t psurge_smp_ops;
 extern struct smp_ops_t core99_smp_ops;
-
-volatile static long int core99_l2_cache;
-void __init
-core99_init_l2(void)
-{
-	int cpu = smp_processor_id();
-
-	if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
-		return;
-
-	if (cpu == 0){
-		core99_l2_cache = _get_L2CR();
-		printk("CPU0: L2CR is %lx\n", core99_l2_cache);
-	} else {
-		printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
-		_set_L2CR(0);
-		_set_L2CR(core99_l2_cache);
-		printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
-	}
-}
 #endif /* CONFIG_SMP */
 
 /*
@@ -189,7 +171,15 @@
 	struct device_node *np;
 	char *pp;
 	int plen;
+	int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+		NULL, PMAC_MB_INFO_MODEL, 0);
+	unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+		NULL, PMAC_MB_INFO_FLAGS, 0);
+	char* mbname;
 
+	if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0)
+		mbname = "Unknown";
+		
 	/* find motherboard type */
 	seq_printf(m, "machine\t\t: ");
 	np = find_devices("device-tree");
@@ -213,6 +203,10 @@
 	} else
 		seq_printf(m, "PowerMac\n");
 
+	/* print parsed model */
+	seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
+	seq_printf(m, "pmac flags\t: %08x\n", mbflags);
+	
 	/* find l2 cache info */
 	np = find_devices("l2-cache");
 	if (np == 0)
@@ -275,16 +269,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_SCSI
-/* Find the device number for the disk (if any) at target tgt
-   on host adaptor host.  We just need to get the prototype from
-   sd.h */
-#include <linux/blkdev.h>
-#include "../../../drivers/scsi/scsi.h"
-#include "../../../drivers/scsi/sd.h"
-
-#endif
-
 #ifdef CONFIG_VT
 /*
  * Dummy mksound function that does nothing.
@@ -352,11 +336,6 @@
 		printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
 			ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
 				? "enabled" : "disabled");
-
-#ifdef CONFIG_SMP
-	/* somewhat of a hack */
-	core99_init_l2();
-#endif
 	
 #ifdef CONFIG_KGDB
 	zs_kgdb_hook(0);
@@ -444,6 +423,34 @@
 	pmac_feature_late_init();
 }
 
+/* That include would have to be in include/linux/ ideally */
+#include "../../../fs/partitions/mac.h"
+
+/* Borrowed from fs/partition/check.c */
+static unsigned char* __init
+read_one_block(struct block_device *bdev, unsigned long n, struct page **v)
+{
+	struct address_space *mapping = bdev->bd_inode->i_mapping;
+	int sect = PAGE_CACHE_SIZE / 512;
+	struct page *page;
+
+	page = read_cache_page(mapping, n/sect,
+			(filler_t *)mapping->a_ops->readpage, NULL);
+	if (!IS_ERR(page)) {
+		wait_on_page(page);
+		if (!Page_Uptodate(page))
+			goto fail;
+		if (PageError(page))
+			goto fail;
+		*v = page;
+		return (unsigned char *)page_address(page) + 512 * (n % sect);
+fail:
+		page_cache_release(page);
+	}
+	*v = NULL;
+	return NULL;
+}
+
 #ifdef CONFIG_SCSI
 void __init
 note_scsi_host(struct device_node *node, void *host)
@@ -473,7 +480,7 @@
 		}
 	}
 }
-#endif
+#endif /* CONFIG_SCSI */
 
 #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
 kdev_t __init
@@ -509,32 +516,132 @@
 #endif
 }
 
-/* can't be __init - can be called whenever a disk is first accessed */
-void __pmac
-note_bootable_part(kdev_t dev, int part, int goodness)
+static void __init
+check_bootable_part(kdev_t dev, int blk, struct mac_partition *part)
 {
-	static int found_boot = 0;
-	char *p;
+	int goodness = 0;
+
+	macpart_fix_string(part->processor, 16);
+	macpart_fix_string(part->name, 32);
+	macpart_fix_string(part->type, 32);					
+    
+	if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
+	    && strcasecmp(part->processor, "powerpc") == 0)
+		goodness++;
+
+	if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
+	    || (strnicmp(part->type, "Linux", 5) == 0
+	    && strcasecmp(part->type, "Linux_swap") != 0)) {
+		int i, l;
+
+		goodness++;
+		l = strlen(part->name);
+		if (strcmp(part->name, "/") == 0)
+			goodness++;
+		for (i = 0; i <= l - 4; ++i) {
+			if (strnicmp(part->name + i, "root",
+				     4) == 0) {
+				goodness += 2;
+				break;
+			}
+		}
+		if (strnicmp(part->name, "swap", 4) == 0)
+			goodness--;
+	}
+
+	if (goodness > current_root_goodness) {
+		ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + blk);
+		current_root_goodness = goodness;
+	}
+}
 
-	/* Do nothing if the root has been mounted already. */
-	if (init_task.fs->rootmnt != NULL)
+static void __init
+check_bootable_disk(kdev_t dev, struct block_device *bdev)
+{
+	struct mac_partition *part;
+	struct mac_driver_desc *md;
+	struct page* pg;
+	unsigned secsize, blocks_in_map, blk;
+	unsigned char* data;
+	
+	/* Check driver descriptor */
+	md = (struct mac_driver_desc *) read_one_block(bdev, 0, &pg);
+	if (!md)
 		return;
-	if ((goodness <= current_root_goodness) &&
-	    (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE)))
+	if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC)
+		goto fail;
+	secsize = be16_to_cpu(md->block_size);
+	page_cache_release(pg);
+	
+	/* Check if it looks like a mac partition map */
+	data = read_one_block(bdev, secsize/512, &pg);
+	if (!data)
+		goto fail;
+	part = (struct mac_partition *) (data + secsize%512);
+	if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
+		goto fail;
+
+	/* Iterate the partition map */
+	blocks_in_map = be32_to_cpu(part->map_count);
+	for (blk = 1; blk <= blocks_in_map; ++blk) {
+		int pos = blk * secsize;
+		page_cache_release(pg);
+		data = read_one_block(bdev, pos/512, &pg);
+		if (!data)
+			break;
+		part = (struct mac_partition *) (data + pos%512);
+		if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
+			break;
+		check_bootable_part(dev, blk, part);
+	}
+fail:
+	if (pg)	
+		page_cache_release(pg);
+}
+
+static int __init
+walk_bootable(struct gendisk *hd, void *data)
+{
+	int drive;
+	
+	for (drive=0; drive<hd->nr_real; drive++) {
+		kdev_t dev;
+		struct block_device *bdev;
+		int rc;
+
+		dev = MKDEV(hd->major, drive << hd->minor_shift);
+		if (boot_dev && boot_dev != dev)
+			continue;
+		bdev = bdget(kdev_t_to_nr(dev));
+		if (bdev == NULL)
+			continue;
+		rc = blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW);
+		if (rc == 0) {
+			check_bootable_disk(dev, bdev);
+			blkdev_put(bdev, BDEV_RAW);
+		}
+	}
+
+	return 0;
+}
+
+void __init
+pmac_discover_root(void)
+{
+	char* p;
+
+	/* Check if root devices already got selected by other ways */
+	if (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE))
 		return;
 	p = strstr(saved_command_line, "root=");
 	if (p != NULL && (p == saved_command_line || p[-1] == ' '))
 		return;
 
-	if (!found_boot) {
-		find_boot_device();
-		found_boot = 1;
-	}
-	if (boot_dev == 0 || dev == boot_dev) {
-		ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + part);
-		boot_dev = NODEV;
-		current_root_goodness = goodness;
-	}
+	/* Find the device used for booting if we can */
+	find_boot_device();
+
+	/* Try to locate a partition */
+	walk_gendisk(walk_bootable, NULL);
 }
 
 void __pmac
@@ -664,7 +771,7 @@
  * Read in a property describing some pieces of memory.
  */
 
-static void __init
+static int __init
 get_mem_prop(char *name, struct mem_pieces *mp)
 {
 	struct reg_property *rp;
@@ -677,7 +784,7 @@
 	if (ip == NULL) {
 		printk(KERN_ERR "error: couldn't get %s property on /memory\n",
 		       name);
-		abort();
+		return 0;
 	}
 	s /= (nsc + nac) * 4;
 	rp = mp->regions;
@@ -696,6 +803,7 @@
 	/* Make sure the pieces are sorted. */
 	mem_pieces_sort(mp);
 	mem_pieces_coalesce(mp);
+	return 1;
 }
 
 /*
@@ -711,12 +819,6 @@
 	unsigned long a, total;
 	struct mem_pieces phys_mem;
 
-	memory_node = find_devices("memory");
-	if (memory_node == NULL) {
-		printk(KERN_ERR "can't find memory node\n");
-		abort();
-	}
-
 	/*
 	 * Find out where physical memory is, and check that it
 	 * starts at 0 and is contiguous.  It seems that RAM is
@@ -727,8 +829,9 @@
 	 * more complicated (or else you end up wasting space
 	 * in mem_map).
 	 */
-	get_mem_prop("reg", &phys_mem);
-	if (phys_mem.n_regions == 0)
+	memory_node = find_devices("memory");
+	if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
+	    || phys_mem.n_regions == 0)
 		panic("No RAM??");
 	a = phys_mem.regions[0].address;
 	if (a != 0)
@@ -805,6 +908,8 @@
 	ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
 	ppc_md.pcibios_after_init = pmac_pcibios_after_init;
 
+	ppc_md.discover_root  = pmac_discover_root;
+
 	ppc_md.restart        = pmac_restart;
 	ppc_md.power_off      = pmac_power_off;
 	ppc_md.halt           = pmac_halt;
@@ -841,15 +946,12 @@
 }
 
 #ifdef CONFIG_BOOTX_TEXT
-extern void drawchar(char c);
-extern void drawstring(const char *c);
-extern boot_infos_t *disp_bi;
 void __init
 pmac_progress(char *s, unsigned short hex)
 {
-	if (disp_bi == 0)
-		return;
-	btext_drawstring(s);
-	btext_drawchar('\n');
+	if (boot_text_mapped) {
+		btext_drawstring(s);
+		btext_drawchar('\n');
+	}
 }
 #endif /* CONFIG_BOOTX_TEXT */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/pmac_smp.c linux/arch/ppc/kernel/pmac_smp.c
--- linux.orig/arch/ppc/kernel/pmac_smp.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/pmac_smp.c	2002-07-20 01:08:37.000000000 +0000
@@ -47,6 +47,7 @@
 #include <asm/pmac_feature.h>
 #include <asm/time.h>
 #include <asm/gemini.h>
+#include <asm/processor.h>
 
 #include "open_pic.h"
 
@@ -105,8 +106,140 @@
 #define PSURGE_QUAD_COTTON	2
 #define PSURGE_QUAD_ICEGRASS	3
 
-/* l2 cache stuff for dual G4 macs */
-extern void core99_init_l2(void);
+volatile static long int core99_l2_cache;
+volatile static long int core99_l3_cache;
+
+static void __init
+core99_init_caches(void)
+{
+	int cpu = smp_processor_id();
+
+	if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
+		return;
+
+	if (cpu == 0){
+		core99_l2_cache = _get_L2CR();
+		printk("CPU0: L2CR is %lx\n", core99_l2_cache);
+	} else {
+		printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
+		_set_L2CR(0);
+		_set_L2CR(core99_l2_cache);
+		printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
+	}
+
+	if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR))
+		return;
+
+	if (cpu == 0){
+		core99_l3_cache = _get_L3CR();
+		printk("CPU0: L3CR is %lx\n", core99_l3_cache);
+	} else {
+		printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
+		_set_L3CR(0);
+		_set_L3CR(core99_l3_cache);
+		printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
+	}
+}
+
+/* Some CPU registers have to be saved from the first CPU and
+ * applied to others. Note that we override what is setup by
+ * the cputable intentionally.
+ */
+
+#define	reg_hid0	0
+#define	reg_hid1	1
+#define	reg_msscr0	2
+#define	reg_msssr0	3
+#define	reg_ictrl	4
+#define	reg_ldstcr	5
+#define	reg_ldstdb	6
+#define	reg_count	7
+
+static unsigned long cpu_regs[reg_count];
+
+static void __pmac
+cpu_setup_grab(void)
+{
+	unsigned int pvers = mfspr(SPRN_PVR)>>16;
+
+	/* Read cache setting of CPU 0 */
+	core99_init_caches();
+
+	/* 7400/7410/7450 */
+	if (pvers == 0x8000 || pvers == 0x000c || pvers == 0x800c) {
+		cpu_regs[reg_hid0] = mfspr(SPRN_HID0);
+		cpu_regs[reg_msscr0] = mfspr(SPRN_MSSCR0);
+		cpu_regs[reg_msssr0] = mfspr(SPRN_MSSSR0);
+	}
+	/* 7450 only */
+	if (pvers == 0x8000) {
+		cpu_regs[reg_hid1] = mfspr(SPRN_HID1);
+		cpu_regs[reg_ictrl] = mfspr(SPRN_ICTRL);
+		cpu_regs[reg_ldstcr] = mfspr(SPRN_LDSTCR);
+		cpu_regs[reg_ldstdb] = mfspr(SPRN_LDSTDB);
+	}
+	flush_dcache_range((unsigned long)cpu_regs, (unsigned long)&cpu_regs[reg_count]);
+}
+
+static void __pmac
+cpu_setup_apply(int cpu_nr)
+{
+	unsigned int pvers = mfspr(SPRN_PVR)>>16;
+
+	/* Apply cache setting from CPU 0 */
+	core99_init_caches();
+
+	/* 7400/7410/7450 */
+	if (pvers == 0x8000 || pvers == 0x000c || pvers == 0x800c) {
+		unsigned long tmp;
+		__asm__ __volatile__ (
+			"lwz	%0,4*"stringify(reg_hid0)"(%1)\n"
+			"sync\n"
+			"mtspr	"stringify(SPRN_HID0)", %0\n"
+			"isync;sync\n"
+			"lwz	%0, 4*"stringify(reg_msscr0)"(%1)\n"
+			"sync\n"
+			"mtspr	"stringify(SPRN_MSSCR0)", %0\n"
+			"isync;sync\n"
+//			"lwz	%0, "stringify(reg_msssr0)"(%1)\n"
+//			"sync\n"
+//			"mtspr	"stringify(SPRN_MSSSR0)", %0\n"
+//			"isync;sync\n"
+		: "=&r" (tmp) : "r" (cpu_regs));			
+	}
+	/* 7410 only */
+	if (pvers == 0x800c) {
+		unsigned long tmp;
+		__asm__ __volatile__ (
+			"li	%0, 0\n"
+			"sync\n"
+			"mtspr	"stringify(SPRN_L2CR2)", %0\n"
+			"isync;sync\n"
+		: "=&r" (tmp));		
+	}
+	/* 7450 only */
+	if (pvers == 0x8000) {
+		unsigned long tmp;
+		__asm__ __volatile__ (
+			"lwz	%0, 4*"stringify(reg_hid1)"(%1)\n"
+			"sync\n"
+			"mtspr	"stringify(SPRN_HID1)", %0\n"
+			"isync;sync\n"
+			"lwz	%0, 4*"stringify(reg_ictrl)"(%1)\n"
+			"sync\n"
+			"mtspr	"stringify(SPRN_ICTRL)", %0\n"
+			"isync;sync\n"
+			"lwz	%0, 4*"stringify(reg_ldstcr)"(%1)\n"
+			"sync\n"
+			"mtspr	"stringify(SPRN_LDSTCR)", %0\n"
+			"isync;sync\n"
+			"lwz	%0, 4*"stringify(reg_ldstdb)"(%1)\n"
+			"sync\n"
+			"mtspr	"stringify(SPRN_LDSTDB)", %0\n"
+			"isync;sync\n"
+		: "=&r" (tmp) : "r" (cpu_regs));		
+	}
+}
 
 /*
  * Set and clear IPIs for powersurge.
@@ -383,6 +516,7 @@
 {
 	struct device_node *cpus;
 	int i, ncpus = 1;
+	extern int powersave_nap;
 
 	if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
 	cpus = find_type_devices("cpu");
@@ -394,6 +528,8 @@
 		openpic_request_IPIs();
 		for (i = 1; i < ncpus; ++i)
 			smp_hw_index[i] = i;
+		powersave_nap = 0;
+		cpu_setup_grab();
 	}
 
 	return ncpus;
@@ -404,17 +540,11 @@
 {
 	unsigned long save_vector, new_vector;
 	unsigned long flags;
-#if 1 /* New way... */
+
 	volatile unsigned long *vector
 		 = ((volatile unsigned long *)(KERNELBASE+0x100));
 	if (nr < 1 || nr > 3)
 		return;
-#else
-	volatile unsigned long *vector
-		 = ((volatile unsigned long *)(KERNELBASE+0x500));
-	if (nr != 1)
-		return;
-#endif
 	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
 
 	local_irq_save(flags);
@@ -463,13 +593,15 @@
 static void __init
 smp_core99_setup_cpu(int cpu_nr)
 {
+	/* Setup some registers */
+	if (cpu_nr != 0)
+		cpu_setup_apply(cpu_nr);
+	
 	/* Setup openpic */
 	do_openpic_setup_cpu();
 
-	/* Setup L2 */
-	if (cpu_nr != 0)
-		core99_init_l2();
-	else
+	/* Setup L2/L3 */
+	if (cpu_nr == 0)
 		if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/ppc_asm.h linux/arch/ppc/kernel/ppc_asm.h
--- linux.orig/arch/ppc/kernel/ppc_asm.h	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/kernel/ppc_asm.h	2002-07-20 01:08:24.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ppc_asm.h 1.18 10/18/01 15:02:09 trini
+ * BK Id: SCCS/s.ppc_asm.h 1.20 03/19/02 15:04:39 benh
  */
 /*
  * arch/ppc/kernel/ppc_asm.h
@@ -55,6 +55,7 @@
 #define STVX(r,a,b)	.long	(31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(231<<1)
 #define MFVSCR(r)	.long	(4<<26)+((r)<<21)+(770<<1)
 #define MTVSCR(r)	.long	(4<<26)+((r)<<11)+(802<<1)
+#define DSSALL		.long	(0x1f<<26)+(0x10<<21)+(0x336<<1)
 
 #define SAVE_VR(n,b,base)	li b,THREAD_VR0+(16*(n)); STVX(n,b,base)
 #define SAVE_2VR(n,b,base)	SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- linux.orig/arch/ppc/kernel/ppc_ksyms.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/ppc_ksyms.c	2002-07-20 01:08:39.000000000 +0000
@@ -189,6 +189,9 @@
 EXPORT_SYMBOL(enable_kernel_fp);
 EXPORT_SYMBOL(flush_icache_range);
 EXPORT_SYMBOL(flush_dcache_range);
+EXPORT_SYMBOL(flush_icache_user_range);
+EXPORT_SYMBOL(flush_icache_page);
+EXPORT_SYMBOL(flush_dcache_page);
 EXPORT_SYMBOL(xchg_u32);
 #ifdef CONFIG_ALTIVEC
 EXPORT_SYMBOL(last_task_used_altivec);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- linux.orig/arch/ppc/kernel/prep_setup.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/prep_setup.c	2002-07-20 01:08:39.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_setup.c 1.47 12/19/01 09:45:54 trini
+ * BK Id: SCCS/s.prep_setup.c 1.52 04/05/02 10:17:22 trini
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -111,12 +111,6 @@
 extern int probingmem;
 extern unsigned long loops_per_jiffy;
 
-#ifdef CONFIG_BLK_DEV_RAM
-extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
-extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
-extern int rd_image_start;	/* starting block # of image */
-#endif
-
 #ifdef CONFIG_SOUND_MODULE
 EXPORT_SYMBOL(ppc_cs4232_dma);
 EXPORT_SYMBOL(ppc_cs4232_dma2);
@@ -209,15 +203,13 @@
 static int __prep
 prep_show_percpuinfo(struct seq_file *m, int i)
 {
-	int len = 0;
-
 	/* PREP's without residual data will give incorrect values here */
 	seq_printf(m, "clock\t\t: ");
 #ifdef CONFIG_PREP_RESIDUAL	
 	if (res->ResidualLength)
 		seq_printf(m, "%ldMHz\n",
 			   (res->VitalProductData.ProcessorHz > 1024) ?
-			   res->VitalProductData.ProcessorHz>>20 :
+			   res->VitalProductData.ProcessorHz / 1000000 :
 			   res->VitalProductData.ProcessorHz);
 	else
 #endif /* CONFIG_PREP_RESIDUAL */
@@ -248,13 +240,6 @@
 	outb(reg, SIO_CONFIG_RD);
 	outb(reg, SIO_CONFIG_RD);	/* Have to write twice to change! */
 
-	/*
-	 * We need to set up the NvRAM access routines early as prep_init
-	 * has yet to be called
-	 */
-	ppc_md.nvram_read_val = prep_nvram_read_val;
-	ppc_md.nvram_write_val = prep_nvram_write_val;
-
 	/* we should determine this according to what we find! -- Cort */
 	switch ( _prep_type )
 	{
@@ -840,21 +825,6 @@
 	}
 #endif
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	if ( r4 )
-	{
-		initrd_start = r4 + KERNELBASE;
-		initrd_end = r5 + KERNELBASE;
-	}
-#endif /* CONFIG_BLK_DEV_INITRD */
-
-	/* Copy cmd_line parameters */
-	if ( r6 )
-	{
-		*(char *)(r7 + KERNELBASE) = 0;
-		strcpy(cmd_line, (char *)(r6 + KERNELBASE));
-	}
-	
 	isa_io_base = PREP_ISA_IO_BASE;
 	isa_mem_base = PREP_ISA_MEM_BASE;
 	pci_dram_offset = PREP_PCI_DRAM_OFFSET;
@@ -890,6 +860,9 @@
 	ppc_md.power_off      = prep_power_off;
 	ppc_md.halt           = prep_halt;
 
+	ppc_md.nvram_read_val = prep_nvram_read_val;
+	ppc_md.nvram_write_val = prep_nvram_write_val;
+
 	ppc_md.time_init      = NULL;
 	if (_prep_type == _PREP_IBM) {
 		ppc_md.set_rtc_time   = mc146818_set_rtc_time;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- linux.orig/arch/ppc/kernel/prom.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/prom.c	2002-07-20 01:08:24.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prom.c 1.48 12/19/01 10:50:58 paulus
+ * BK Id: SCCS/s.prom.c 1.52 04/09/02 21:01:58 paulus
  */
 /*
  * Procedures for interfacing to the Open Firmware PROM on
@@ -11,7 +11,6 @@
  * Paul Mackerras	August 1996.
  * Copyright (C) 1996 Paul Mackerras.
  */
-#include <stdarg.h>
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -19,7 +18,6 @@
 #include <linux/version.h>
 #include <linux/threads.h>
 #include <linux/spinlock.h>
-#include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 
@@ -28,37 +26,9 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/bootx.h>
 #include <asm/system.h>
-#include <asm/mmu.h>
-#include <asm/pgtable.h>
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
 #include <asm/btext.h>
 #include <asm/pci-bridge.h>
-#include "open_pic.h"
-
-#ifdef CONFIG_FB
-#include <asm/linux_logo.h>
-#endif
-
-/*
- * Properties whose value is longer than this get excluded from our
- * copy of the device tree.  This way we don't waste space storing
- * things like "driver,AAPL,MacOS,PowerPC" properties.  But this value
- * does need to be big enough to ensure that we don't lose things
- * like the interrupt-map property on a PCI-PCI bridge.
- */
-#define MAX_PROPERTY_LENGTH	4096
-
-struct prom_args {
-	const char *service;
-	int nargs;
-	int nret;
-	void *args[10];
-};
 
 struct pci_address {
 	unsigned a_hi;
@@ -72,26 +42,12 @@
 	unsigned size_lo;
 };
 
-struct pci_range {
-	struct pci_address addr;
-	unsigned phys;
-	unsigned size_hi;
-	unsigned size_lo;
-};
-
 struct isa_reg_property {
 	unsigned space;
 	unsigned address;
 	unsigned size;
 };
 
-struct pci_intr_map {
-	struct pci_address addr;
-	unsigned dunno;
-	phandle int_ctrler;
-	unsigned intr;
-};
-
 typedef unsigned long interpret_func(struct device_node *, unsigned long,
 				     int, int);
 static interpret_func interpret_pci_props;
@@ -100,27 +56,7 @@
 static interpret_func interpret_macio_props;
 static interpret_func interpret_root_props;
 
-#ifndef FB_MAX			/* avoid pulling in all of the fb stuff */
-#define FB_MAX	8
-#endif
-char *prom_display_paths[FB_MAX] __initdata = { 0, };
-phandle prom_display_nodes[FB_MAX] __initdata;
-unsigned int prom_num_displays __initdata = 0;
-char *of_stdout_device __initdata = 0;
-ihandle prom_disp_node __initdata = 0;
-
-prom_entry prom __initdata = 0;
-ihandle prom_chosen __initdata = 0;
-ihandle prom_stdout __initdata = 0;
-
 extern char *klimit;
-char *bootpath;
-char *bootdevice;
-
-unsigned int rtas_data;   /* physical pointer */
-unsigned int rtas_entry;  /* physical pointer */
-unsigned int rtas_size;
-unsigned int old_rtas;
 
 /* Set for a newworld or CHRP machine */
 int use_of_interrupt_tree;
@@ -129,554 +65,30 @@
 
 int pmac_newworld;
 
-static struct device_node *allnodes;
+extern unsigned int rtas_entry;  /* physical pointer */
+
+extern struct device_node *allnodes;
 
-static void *call_prom(const char *service, int nargs, int nret, ...);
-static void prom_exit(void);
-static unsigned long copy_device_tree(unsigned long, unsigned long);
-static unsigned long inspect_node(phandle, struct device_node *, unsigned long,
-				  unsigned long, struct device_node ***);
 static unsigned long finish_node(struct device_node *, unsigned long,
 				 interpret_func *, int, int);
 static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
-static unsigned long check_display(unsigned long);
-static int prom_next_node(phandle *);
-static void *early_get_property(unsigned long, unsigned long, char *);
 static struct device_node *find_phandle(phandle);
 
-#ifdef CONFIG_BOOTX_TEXT
-static void setup_disp_fake_bi(ihandle dp);
-#endif
-
 extern void enter_rtas(void *);
 void phys_call_rtas(int, int, int, ...);
 
 extern char cmd_line[512];	/* XXX */
-boot_infos_t *boot_infos;
+extern boot_infos_t *boot_infos;
 unsigned long dev_tree_size;
 
-#define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
-
-/* Is boot-info compatible ? */
-#define BOOT_INFO_IS_COMPATIBLE(bi)		((bi)->compatible_version <= BOOT_INFO_VERSION)
-#define BOOT_INFO_IS_V2_COMPATIBLE(bi)	((bi)->version >= 2)
-#define BOOT_INFO_IS_V4_COMPATIBLE(bi)	((bi)->version >= 4)
-
-/*
- * Note that prom_init() and anything called from prom_init() must
- * use the RELOC/PTRRELOC macros to access any static data in
- * memory, since the kernel may be running at an address that is
- * different from the address that it was linked at.
- * (Note that strings count as static variables.)
- */
-
-static void __init
-prom_exit()
-{
-	struct prom_args args;
-	unsigned long offset = reloc_offset();
-
-	args.service = "exit";
-	args.nargs = 0;
-	args.nret = 0;
-	RELOC(prom)(&args);
-	for (;;)			/* should never get here */
-		;
-}
-
-void __init
-prom_enter(void)
-{
-	struct prom_args args;
-	unsigned long offset = reloc_offset();
-
-	args.service = RELOC("enter");
-	args.nargs = 0;
-	args.nret = 0;
-	RELOC(prom)(&args);
-}
-
-static void * __init
-call_prom(const char *service, int nargs, int nret, ...)
-{
-	va_list list;
-	int i;
-	unsigned long offset = reloc_offset();
-	struct prom_args prom_args;
-
-	prom_args.service = service;
-	prom_args.nargs = nargs;
-	prom_args.nret = nret;
-	va_start(list, nret);
-	for (i = 0; i < nargs; ++i)
-		prom_args.args[i] = va_arg(list, void *);
-	va_end(list);
-	for (i = 0; i < nret; ++i)
-		prom_args.args[i + nargs] = 0;
-	RELOC(prom)(&prom_args);
-	return prom_args.args[nargs];
-}
-
-void __init
-prom_print(const char *msg)
-{
-	const char *p, *q;
-	unsigned long offset = reloc_offset();
-
-	if (RELOC(prom_stdout) == 0)
-		return;
-
-	for (p = msg; *p != 0; p = q) {
-		for (q = p; *q != 0 && *q != '\n'; ++q)
-			;
-		if (q > p)
-			call_prom(RELOC("write"), 3, 1, RELOC(prom_stdout),
-				  p, q - p);
-		if (*q != 0) {
-			++q;
-			call_prom(RELOC("write"), 3, 1, RELOC(prom_stdout),
-				  RELOC("\r\n"), 2);
-		}
-	}
-}
-
-static void __init
-prom_print_hex(unsigned int v)
-{
-	char buf[16];
-	int i, c;
-
-	for (i = 0; i < 8; ++i) {
-		c = (v >> ((7-i)*4)) & 0xf;
-		c += (c >= 10)? ('a' - 10): '0';
-		buf[i] = c;
-	}
-	buf[i] = ' ';
-	buf[i+1] = 0;
-	prom_print(buf);
-}
-
-unsigned long smp_chrp_cpu_nr __initdata = 0;
-
-#ifdef CONFIG_SMP
-/*
- * With CHRP SMP we need to use the OF to start the other
- * processors so we can't wait until smp_boot_cpus (the OF is
- * trashed by then) so we have to put the processors into
- * a holding pattern controlled by the kernel (not OF) before
- * we destroy the OF.
- *
- * This uses a chunk of high memory, puts some holding pattern
- * code there and sends the other processors off to there until
- * smp_boot_cpus tells them to do something.  We do that by using
- * physical address 0x0.  The holding pattern checks that address
- * until its cpu # is there, when it is that cpu jumps to
- * __secondary_start().  smp_boot_cpus() takes care of setting those
- * values.
- *
- * We also use physical address 0x4 here to tell when a cpu
- * is in its holding pattern code.
- *
- * -- Cort
- */
-static void __init
-prom_hold_cpus(unsigned long mem)
-{
-	extern void __secondary_hold(void);
-	unsigned long i;
-	int cpu;
-	phandle node;
-	unsigned long offset = reloc_offset();
-	char type[16], *path;
-	unsigned int reg;
-
-	/*
-	 * XXX: hack to make sure we're chrp, assume that if we're
-	 *      chrp we have a device_type property -- Cort
-	 */
-	node = call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
-	if ( (int)call_prom(RELOC("getprop"), 4, 1, node,
-			    RELOC("device_type"),type, sizeof(type)) <= 0)
-		return;
-
-	/* copy the holding pattern code to someplace safe (0) */
-	/* the holding pattern is now within the first 0x100
-	   bytes of the kernel image -- paulus */
-	memcpy((void *)0, (void *)(KERNELBASE + offset), 0x100);
-	flush_icache_range(0, 0x100);
-
-	/* look for cpus */
-	*(unsigned long *)(0x0) = 0;
-	asm volatile("dcbf 0,%0": : "r" (0) : "memory");
-	for (node = 0; prom_next_node(&node); ) {
-		type[0] = 0;
-		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
-			  type, sizeof(type));
-		if (strcmp(type, RELOC("cpu")) != 0)
-			continue;
-		path = (char *) mem;
-		memset(path, 0, 256);
-		if ((int) call_prom(RELOC("package-to-path"), 3, 1,
-				    node, path, 255) < 0)
-			continue;
-		reg = -1;
-		call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
-			  &reg, sizeof(reg));
-		cpu = RELOC(smp_chrp_cpu_nr)++;
-		RELOC(smp_hw_index)[cpu] = reg;
-		/* XXX: hack - don't start cpu 0, this cpu -- Cort */
-		if (cpu == 0)
-			continue;
-		prom_print(RELOC("starting cpu "));
-		prom_print(path);
-		*(ulong *)(0x4) = 0;
-		call_prom(RELOC("start-cpu"), 3, 0, node,
-			  __pa(__secondary_hold), cpu);
-		prom_print(RELOC("..."));
-		for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
-			;
-		if (*(ulong *)(0x4) == cpu)
-			prom_print(RELOC("ok\n"));
-		else {
-			prom_print(RELOC("failed: "));
-			prom_print_hex(*(ulong *)0x4);
-			prom_print(RELOC("\n"));
-		}
-	}
-}
-#endif /* CONFIG_SMP */
-
-void __init
-bootx_init(unsigned long r4, unsigned long phys)
-{
-	boot_infos_t *bi = (boot_infos_t *) r4;
-	unsigned long space;
-	unsigned long ptr, x;
-	char *model;
-	unsigned long offset = reloc_offset();
-
-	RELOC(boot_infos) = PTRUNRELOC(bi);
-	if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
-		bi->logicalDisplayBase = 0;
-
-#ifdef CONFIG_BOOTX_TEXT
-	btext_init(bi);
-
-	/*
-	 * Test if boot-info is compatible.  Done only in config
-	 * CONFIG_BOOTX_TEXT since there is nothing much we can do
-	 * with an incompatible version, except display a message
-	 * and eventually hang the processor...
-	 *
-	 * I'll try to keep enough of boot-info compatible in the
-	 * future to always allow display of this message;
-	 */
-	if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
-		btext_drawstring(RELOC(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"));
-		btext_flushscreen();
-	}
-#endif	/* CONFIG_BOOTX_TEXT */
-
-	/* New BootX enters kernel with MMU off, i/os are not allowed
-	   here. This hack will have been done by the boostrap anyway.
-	*/
-	if (bi->version < 4) {
-		/*
-		 * XXX If this is an iMac, turn off the USB controller.
-		 */
-		model = (char *) early_get_property
-			(r4 + bi->deviceTreeOffset, 4, RELOC("model"));
-		if (model
-		    && (strcmp(model, RELOC("iMac,1")) == 0
-			|| strcmp(model, RELOC("PowerMac1,1")) == 0)) {
-			out_le32((unsigned *)0x80880008, 1);	/* XXX */
-		}
-	}
-
-	/* Move klimit to enclose device tree, args, ramdisk, etc... */
-	if (bi->version < 5) {
-		space = bi->deviceTreeOffset + bi->deviceTreeSize;
-		if (bi->ramDisk)
-			space = bi->ramDisk + bi->ramDiskSize;
-	} else
-		space = bi->totalParamsSize;
-	RELOC(klimit) = PTRUNRELOC((char *) bi + space);
-
-	/* New BootX will have flushed all TLBs and enters kernel with
-	   MMU switched OFF, so this should not be useful anymore.
-	*/
-	if (bi->version < 4) {
-		/*
-		 * Touch each page to make sure the PTEs for them
-		 * are in the hash table - the aim is to try to avoid
-		 * getting DSI exceptions while copying the kernel image.
-		 */
-		for (ptr = (KERNELBASE + offset) & PAGE_MASK;
-		     ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
-			x = *(volatile unsigned long *)ptr;
-	}
-
-#ifdef CONFIG_BOOTX_TEXT
-	/*
-	 * Note that after we call prepare_disp_BAT, we can't do
-	 * prom_draw*, flushscreen or clearscreen until we turn the MMU
-	 * on, since prepare_disp_BAT sets disp_bi->logicalDisplayBase
-	 * to a virtual address.
-	 */
-	btext_prepare_BAT();
-#endif
-}
-
-#ifdef CONFIG_PPC64BRIDGE
-/*
- * Set up a hash table with a set of entries in it to map the
- * first 64MB of RAM.  This is used on 64-bit machines since
- * some of them don't have BATs.
- * We assume the PTE will fit in the primary PTEG.
- */
-
-static inline void make_pte(unsigned long htab, unsigned int hsize,
-			    unsigned int va, unsigned int pa, int mode)
-{
-	unsigned int *pteg;
-	unsigned int hash, i, vsid;
-
-	vsid = ((va >> 28) * 0x111) << 12;
-	hash = ((va ^ vsid) >> 5) & 0x7fff80;
-	pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
-	for (i = 0; i < 8; ++i, pteg += 4) {
-		if ((pteg[1] & 1) == 0) {
-			pteg[1] = vsid | ((va >> 16) & 0xf80) | 1;
-			pteg[3] = pa | mode;
-			break;
-		}
-	}
-}
-
-extern unsigned long _SDR1;
-extern PTE *Hash;
-extern unsigned long Hash_size;
-
-static void __init
-prom_alloc_htab(void)
-{
-	unsigned int hsize;
-	unsigned long htab;
-	unsigned int addr;
-	unsigned long offset = reloc_offset();
-
-	/*
-	 * Because of OF bugs we can't use the "claim" client
-	 * interface to allocate memory for the hash table.
-	 * This code is only used on 64-bit PPCs, and the only
-	 * 64-bit PPCs at the moment are RS/6000s, and their
-	 * OF is based at 0xc00000 (the 12M point), so we just
-	 * arbitrarily use the 0x800000 - 0xc00000 region for the
-	 * hash table.
-	 *  -- paulus.
-	 */
-#ifdef CONFIG_POWER4
-	hsize = 4 << 20;	/* POWER4 has no BATs */
-#else
-	hsize = 2 << 20;
-#endif /* CONFIG_POWER4 */
-	htab = (8 << 20);
-	RELOC(Hash) = (void *)(htab + KERNELBASE);
-	RELOC(Hash_size) = hsize;
-	RELOC(_SDR1) = htab + __ilog2(hsize) - 18;
-
-	/*
-	 * Put in PTEs for the first 64MB of RAM
-	 */
-	cacheable_memzero((void *)htab, hsize);
-	for (addr = 0; addr < 0x4000000; addr += 0x1000)
-		make_pte(htab, hsize, addr + KERNELBASE, addr,
-			 _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
-}
-#endif /* CONFIG_PPC64BRIDGE */
-
-static void __init
-prom_instantiate_rtas(void)
-{
-	ihandle prom_rtas;
-	unsigned int i;
-	struct prom_args prom_args;
-	unsigned long offset = reloc_offset();
-
-	prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
-	if (prom_rtas == (void *) -1)
-		return;
-
-	RELOC(rtas_size) = 0;
-	call_prom(RELOC("getprop"), 4, 1, prom_rtas,
-		  RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size));
-	prom_print(RELOC("instantiating rtas"));
-	if (RELOC(rtas_size) == 0) {
-		RELOC(rtas_data) = 0;
-	} else {
-		/*
-		 * Ask OF for some space for RTAS.
-		 * Actually OF has bugs so we just arbitrarily
-		 * use memory at the 6MB point.
-		 */
-		RELOC(rtas_data) = 6 << 20;
-		prom_print(RELOC(" at "));
-		prom_print_hex(RELOC(rtas_data));
-	}
-
-	prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
-	prom_print(RELOC("..."));
-	prom_args.service = RELOC("call-method");
-	prom_args.nargs = 3;
-	prom_args.nret = 2;
-	prom_args.args[0] = RELOC("instantiate-rtas");
-	prom_args.args[1] = prom_rtas;
-	prom_args.args[2] = (void *) RELOC(rtas_data);
-	RELOC(prom)(&prom_args);
-	i = 0;
-	if (prom_args.args[3] == 0)
-		i = (unsigned int)prom_args.args[4];
-	RELOC(rtas_entry) = i;
-	if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0))
-		prom_print(RELOC(" failed\n"));
-	else
-		prom_print(RELOC(" done\n"));
-}
-
-/*
- * We enter here early on, when the Open Firmware prom is still
- * handling exceptions and the MMU hash table for us.
- */
-unsigned long __init
-prom_init(int r3, int r4, prom_entry pp)
-{
-	unsigned long mem;
-	ihandle prom_mmu;
-	unsigned long offset = reloc_offset();
-	int l;
-	char *p, *d;
- 	unsigned long phys;
-
- 	/* Default */
- 	phys = offset + KERNELBASE;
-
-	/* First get a handle for the stdout device */
-	RELOC(prom) = pp;
-	RELOC(prom_chosen) = call_prom(RELOC("finddevice"), 1, 1,
-				       RELOC("/chosen"));
-	if (RELOC(prom_chosen) == (void *)-1)
-		prom_exit();
-	if ((int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen),
-			    RELOC("stdout"), &RELOC(prom_stdout),
-			    sizeof(prom_stdout)) <= 0)
-		prom_exit();
-
-	/* Get the full OF pathname of the stdout device */
-	mem = (unsigned long) RELOC(klimit) + offset;
-	p = (char *) mem;
-	memset(p, 0, 256);
-	call_prom(RELOC("instance-to-path"), 3, 1, RELOC(prom_stdout), p, 255);
-	RELOC(of_stdout_device) = PTRUNRELOC(p);
-	mem += strlen(p) + 1;
-
-	/* Get the boot device and translate it to a full OF pathname. */
-	p = (char *) mem;
-	l = (int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen),
-			    RELOC("bootpath"), p, 1<<20);
-	if (l > 0) {
-		p[l] = 0;	/* should already be null-terminated */
-		RELOC(bootpath) = PTRUNRELOC(p);
-		mem += l + 1;
-		d = (char *) mem;
-		*d = 0;
-		call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);
-		RELOC(bootdevice) = PTRUNRELOC(d);
-		mem = ALIGN(mem + strlen(d) + 1);
-	}
-
-	prom_instantiate_rtas();
-
-#ifdef CONFIG_PPC64BRIDGE
-	/*
-	 * Find out how much memory we have and allocate a
-	 * suitably-sized hash table.
-	 */
-	prom_alloc_htab();
-#endif
-
-	mem = check_display(mem);
-
-	prom_print(RELOC("copying OF device tree..."));
-	mem = copy_device_tree(mem, mem + (1<<20));
-	prom_print(RELOC("done\n"));
-
-#ifdef CONFIG_SMP
-	prom_hold_cpus(mem);
-#endif
-
-	RELOC(klimit) = (char *) (mem - offset);
-
-	/* If we are already running at 0xc0000000, we assume we were loaded by
-	 * an OF bootloader which did set a BAT for us. This breaks OF translate
-	 * so we force phys to be 0
-	 */
-	if (offset == 0)
-		phys = 0;
-	else {
- 	    if ((int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen),
-			    RELOC("mmu"), &prom_mmu, sizeof(prom_mmu)) <= 0) {
-		prom_print(RELOC(" no MMU found\n"));
-	    } else {
-		int nargs;
-		struct prom_args prom_args;
-		nargs = 4;
-		prom_args.service = RELOC("call-method");
-		prom_args.nargs = nargs;
-		prom_args.nret = 4;
-		prom_args.args[0] = RELOC("translate");
-		prom_args.args[1] = prom_mmu;
-		prom_args.args[2] = (void *)(offset + KERNELBASE);
-		prom_args.args[3] = (void *)1;
-		RELOC(prom)(&prom_args);
-
-		/* We assume the phys. address size is 3 cells */
-		if (prom_args.args[nargs] != 0)
-			prom_print(RELOC(" (translate failed)\n"));
-		else
-			phys = (unsigned long)prom_args.args[nargs+3];
-	    }
-	}
-
-#ifdef CONFIG_BOOTX_TEXT
-	if (RELOC(prom_disp_node) != 0)
-		setup_disp_fake_bi(RELOC(prom_disp_node));
-#endif
-
-	/* Use quiesce call to get OF to shut down any devices it's using */
-	prom_print(RELOC("Calling quiesce ...\n"));
-	call_prom(RELOC("quiesce"), 0, 0);
-
-#ifdef CONFIG_BOOTX_TEXT
-	if (RELOC(prom_disp_node) != 0)
-		btext_prepare_BAT();
-#endif
-
-	prom_print(RELOC("returning "));
-	prom_print_hex(phys);
-	prom_print(RELOC(" from prom_init\n"));
-	RELOC(prom_stdout) = 0;
-
-	return phys;
-}
-
-void phys_call_rtas(int service, int nargs, int nret, ...)
+void __openfirmware
+phys_call_rtas(int service, int nargs, int nret, ...)
 {
 	va_list list;
 	union {
 		unsigned long words[16];
 		double align;
 	} u;
-	unsigned long offset = reloc_offset();
 	void (*rtas)(void *, unsigned long);
 	int i;
 
@@ -688,340 +100,8 @@
 		u.words[i+3] = va_arg(list, unsigned long);
 	va_end(list);
 
-	rtas = (void (*)(void *, unsigned long)) RELOC(rtas_entry);
-	rtas(&u, RELOC(rtas_data));
-}
-
-static int __init
-prom_set_color(ihandle ih, int i, int r, int g, int b)
-{
-	struct prom_args prom_args;
-	unsigned long offset = reloc_offset();
-
-	prom_args.service = RELOC("call-method");
-	prom_args.nargs = 6;
-	prom_args.nret = 1;
-	prom_args.args[0] = RELOC("color!");
-	prom_args.args[1] = ih;
-	prom_args.args[2] = (void *) i;
-	prom_args.args[3] = (void *) b;
-	prom_args.args[4] = (void *) g;
-	prom_args.args[5] = (void *) r;
-	RELOC(prom)(&prom_args);
-	return (int) prom_args.args[6];
-}
-
-/*
- * If we have a display that we don't know how to drive,
- * we will want to try to execute OF's open method for it
- * later.  However, OF will probably fall over if we do that
- * we've taken over the MMU.
- * So we check whether we will need to open the display,
- * and if so, open it now.
- */
-static unsigned long __init
-check_display(unsigned long mem)
-{
-	phandle node;
-	ihandle ih;
-	int i;
-	unsigned long offset = reloc_offset();
-	char type[16], *path;
-	static unsigned char default_colors[] = {
-		0x00, 0x00, 0x00,
-		0x00, 0x00, 0xaa,
-		0x00, 0xaa, 0x00,
-		0x00, 0xaa, 0xaa,
-		0xaa, 0x00, 0x00,
-		0xaa, 0x00, 0xaa,
-		0xaa, 0xaa, 0x00,
-		0xaa, 0xaa, 0xaa,
-		0x55, 0x55, 0x55,
-		0x55, 0x55, 0xff,
-		0x55, 0xff, 0x55,
-		0x55, 0xff, 0xff,
-		0xff, 0x55, 0x55,
-		0xff, 0x55, 0xff,
-		0xff, 0xff, 0x55,
-		0xff, 0xff, 0xff
-	};
-
-	RELOC(prom_disp_node) = 0;
-
-	for (node = 0; prom_next_node(&node); ) {
-		type[0] = 0;
-		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
-			  type, sizeof(type));
-		if (strcmp(type, RELOC("display")) != 0)
-			continue;
-		/* It seems OF doesn't null-terminate the path :-( */
-		path = (char *) mem;
-		memset(path, 0, 256);
-		if ((int) call_prom(RELOC("package-to-path"), 3, 1,
-				    node, path, 255) < 0)
-			continue;
-
-		/*
-		 * If this display is the device that OF is using for stdout,
-		 * move it to the front of the list.
-		 */
-		mem += strlen(path) + 1;
-		i = RELOC(prom_num_displays)++;
-		if (RELOC(of_stdout_device) != 0 && i > 0
-		    && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
-			for (; i > 0; --i) {
-				RELOC(prom_display_paths[i])
-					= RELOC(prom_display_paths[i-1]);
-				RELOC(prom_display_nodes[i])
-					= RELOC(prom_display_nodes[i-1]);
-			}
-		}
-		RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
-		RELOC(prom_display_nodes[i]) = node;
-		if (i == 0)
-			RELOC(prom_disp_node) = node;
-		if (RELOC(prom_num_displays) >= FB_MAX)
-			break;
-	}
-
-try_again:
-	/*
-	 * Open the first display and set its colormap.
-	 */
-	if (RELOC(prom_num_displays) > 0) {
-		path = PTRRELOC(RELOC(prom_display_paths[0]));
-		prom_print(RELOC("opening display "));
-		prom_print(path);
-		ih = call_prom(RELOC("open"), 1, 1, path);
-		if (ih == 0 || ih == (ihandle) -1) {
-			prom_print(RELOC("... failed\n"));
-			for (i=1; i<RELOC(prom_num_displays); i++) {
-				RELOC(prom_display_paths[i-1]) = RELOC(prom_display_paths[i]);
-				RELOC(prom_display_nodes[i-1]) = RELOC(prom_display_nodes[i]);
-			}
-			if (--RELOC(prom_num_displays) > 0)
-				RELOC(prom_disp_node) = RELOC(prom_display_nodes[0]);
-			else
-				RELOC(prom_disp_node) = NULL;
-			goto try_again;
-		} else {
-			prom_print(RELOC("... ok\n"));
-			/*
-			 * Setup a usable color table when the appropriate
-			 * method is available.
-			 * Should update this to use set-colors.
-			 */
-			for (i = 0; i < 32; i++)
-				if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
-						   RELOC(default_colors)[i*3+1],
-						   RELOC(default_colors)[i*3+2]) != 0)
-					break;
-
-#ifdef CONFIG_FB
-			for (i = 0; i < LINUX_LOGO_COLORS; i++)
-				if (prom_set_color(ih, i + 32,
-						   RELOC(linux_logo_red)[i],
-						   RELOC(linux_logo_green)[i],
-						   RELOC(linux_logo_blue)[i]) != 0)
-					break;
-#endif /* CONFIG_FB */
-		}
-	}
-
-	return ALIGN(mem);
-}
-
-/* This function will enable the early boot text when doing OF booting. This
- * way, xmon output should work too
- */
-#ifdef CONFIG_BOOTX_TEXT
-static void __init
-setup_disp_fake_bi(ihandle dp)
-{
-	int width = 640, height = 480, depth = 8, pitch;
-	unsigned address;
-	unsigned long offset = reloc_offset();
-	struct pci_reg_property addrs[8];
-	int i, naddrs;
-	char name[32];
-	char *getprop = RELOC("getprop");
-
-	prom_print(RELOC("Initializing fake screen: "));
-
-	memset(name, 0, sizeof(name));
-	call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name));
-	name[sizeof(name)-1] = 0;
-	prom_print(name);
-	prom_print(RELOC("\n"));
-	call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width));
-	call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height));
-	call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth));
-	pitch = width * ((depth + 7) / 8);
-	call_prom(getprop, 4, 1, dp, RELOC("linebytes"),
-		  &pitch, sizeof(pitch));
-	if (pitch == 1)
-		pitch = 0x1000;		/* for strange IBM display */
-	address = 0;
-	call_prom(getprop, 4, 1, dp, RELOC("address"),
-		  &address, sizeof(address));
-	if (address == 0) {
-		/* look for an assigned address with a size of >= 1MB */
-		naddrs = (int) call_prom(getprop, 4, 1, dp,
-				RELOC("assigned-addresses"),
-				addrs, sizeof(addrs));
-		naddrs /= sizeof(struct pci_reg_property);
-		for (i = 0; i < naddrs; ++i) {
-			if (addrs[i].size_lo >= (1 << 20)) {
-				address = addrs[i].addr.a_lo;
-				/* use the BE aperture if possible */
-				if (addrs[i].size_lo >= (16 << 20))
-					address += (8 << 20);
-				break;
-			}
-		}
-		if (address == 0) {
-			prom_print(RELOC("Failed to get address\n"));
-			return;
-		}
-	}
-	/* kludge for valkyrie */
-	if (strcmp(name, RELOC("valkyrie")) == 0)
-		address += 0x1000;
-
-	btext_setup_display(width, height, depth, pitch, address);
-}
-#endif
-
-static int __init
-prom_next_node(phandle *nodep)
-{
-	phandle node;
-	unsigned long offset = reloc_offset();
-
-	if ((node = *nodep) != 0
-	    && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)
-		return 1;
-	if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
-		return 1;
-	for (;;) {
-		if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)
-			return 0;
-		if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
-			return 1;
-	}
-}
-
-/*
- * Make a copy of the device tree from the PROM.
- */
-static unsigned long __init
-copy_device_tree(unsigned long mem_start, unsigned long mem_end)
-{
-	phandle root;
-	unsigned long new_start;
-	struct device_node **allnextp;
-	unsigned long offset = reloc_offset();
-
-	root = call_prom(RELOC("peer"), 1, 1, (phandle)0);
-	if (root == (phandle)0) {
-		prom_print(RELOC("couldn't get device tree root\n"));
-		prom_exit();
-	}
-	allnextp = &RELOC(allnodes);
-	mem_start = ALIGN(mem_start);
-	new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
-	*allnextp = 0;
-	return new_start;
-}
-
-static unsigned long __init
-inspect_node(phandle node, struct device_node *dad,
-	     unsigned long mem_start, unsigned long mem_end,
-	     struct device_node ***allnextpp)
-{
-	int l;
-	phandle child;
-	struct device_node *np;
-	struct property *pp, **prev_propp;
-	char *prev_name, *namep;
-	unsigned char *valp;
-	unsigned long offset = reloc_offset();
-
-	np = (struct device_node *) mem_start;
-	mem_start += sizeof(struct device_node);
-	memset(np, 0, sizeof(*np));
-	np->node = node;
-	**allnextpp = PTRUNRELOC(np);
-	*allnextpp = &np->allnext;
-	if (dad != 0) {
-		np->parent = PTRUNRELOC(dad);
-		/* we temporarily use the `next' field as `last_child'. */
-		if (dad->next == 0)
-			dad->child = PTRUNRELOC(np);
-		else
-			dad->next->sibling = PTRUNRELOC(np);
-		dad->next = np;
-	}
-
-	/* get and store all properties */
-	prev_propp = &np->properties;
-	prev_name = RELOC("");
-	for (;;) {
-		pp = (struct property *) mem_start;
-		namep = (char *) (pp + 1);
-		pp->name = PTRUNRELOC(namep);
-		if ((int) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,
-				    namep) <= 0)
-			break;
-		mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
-		prev_name = namep;
-		valp = (unsigned char *) mem_start;
-		pp->value = PTRUNRELOC(valp);
-		pp->length = (int)
-			call_prom(RELOC("getprop"), 4, 1, node, namep,
-				  valp, mem_end - mem_start);
-		if (pp->length < 0)
-			continue;
-#ifdef MAX_PROPERTY_LENGTH
-		if (pp->length > MAX_PROPERTY_LENGTH)
-			continue; /* ignore this property */
-#endif
-		mem_start = ALIGN(mem_start + pp->length);
-		*prev_propp = PTRUNRELOC(pp);
-		prev_propp = &pp->next;
-	}
-	if (np->node != NULL) {
-		/* Add a "linux,phandle" property" */
-		pp = (struct property *) mem_start;
-		*prev_propp = PTRUNRELOC(pp);
-		prev_propp = &pp->next;
-		namep = (char *) (pp + 1);
-		pp->name = PTRUNRELOC(namep);
-		strcpy(namep, RELOC("linux,phandle"));
-		mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
-		pp->value = (unsigned char *) PTRUNRELOC(&np->node);
-		pp->length = sizeof(np->node);
-	}
-	*prev_propp = NULL;
-
-	/* get the node's full name */
-	l = (int) call_prom(RELOC("package-to-path"), 3, 1, node,
-			    (char *) mem_start, mem_end - mem_start);
-	if (l >= 0) {
-		np->full_name = PTRUNRELOC((char *) mem_start);
-		*(char *)(mem_start + l) = 0;
-		mem_start = ALIGN(mem_start + l + 1);
-	}
-
-	/* do all our children */
-	child = call_prom(RELOC("child"), 1, 1, node);
-	while (child != (void *)0) {
-		mem_start = inspect_node(child, np, mem_start, mem_end,
-					 allnextpp);
-		child = call_prom(RELOC("peer"), 1, 1, child);
-	}
-
-	return mem_start;
+	rtas = (void (*)(void *, unsigned long)) rtas_entry;
+	rtas(&u, rtas_data);
 }
 
 /*
@@ -1086,26 +166,6 @@
 	klimit = (char *) mem;
 }
 
-/*
- * early_get_property is used to access the device tree image prepared
- * by BootX very early on, before the pointers in it have been relocated.
- */
-static void * __init
-early_get_property(unsigned long base, unsigned long node, char *prop)
-{
-	struct device_node *np = (struct device_node *)(base + node);
-	struct property *pp;
-
-	for (pp = np->properties; pp != 0; pp = pp->next) {
-		pp = (struct property *) (base + (unsigned long)pp);
-		if (strcmp((char *)((unsigned long)pp->name + base),
-			   prop) == 0) {
-			return (void *)((unsigned long)pp->value + base);
-		}
-	}
-	return 0;
-}
-
 static unsigned long __init
 finish_node(struct device_node *np, unsigned long mem_start,
 	    interpret_func *ifunc, int naddrc, int nsizec)
@@ -1136,19 +196,6 @@
 	if (ip != NULL)
 		nsizec = *ip;
 
-	/* 
-	 * The F50 sets the name to 'display' and 'compatible' to what we
-	 * expect for the name. -- Cort
-	 *
-	 * But sometimes you get a 'display' name for non-OF cards, and thus
-	 * no compatible property.  And very rarely we won't have a name
-	 * property either. -- Tom
-	 */
-	if (!strcmp(np->name, "display"))
-		np->name = get_property(np, "compatible", 0);
-	if (!np->name)
-		np->name = get_property(np, "name", 0);
-
 	if (np->parent == NULL)
 		ifunc = interpret_root_props;
 	else if (np->type == 0)
@@ -2145,11 +1192,11 @@
 		u.words[i+3] = va_arg(list, unsigned long);
 	va_end(list);
 
-	/* Shouldn't we enable kernel FP here ? enter_rtas will play
-	 * with MSR_FE0|MSR_FE1|MSR_FP so I assume rtas might use
-	 * floating points. If that's the case, then we need to make
-	 * sure any lazy FP context is backed up
-	 * --BenH
+	/*
+	 * RTAS doesn't use floating point.
+	 * Or at least, according to the CHRP spec we enter RTAS
+	 * with FP disabled, and it doesn't change the FP registers.
+	 *  -- paulus.
 	 */
 	spin_lock_irqsave(&rtas_lock, s);
 	enter_rtas((void *)__pa(&u));
@@ -2160,13 +1207,3 @@
 			outputs[i] = u.words[i+nargs+4];
 	return u.words[nargs+3];
 }
-
-void __init
-abort()
-{
-#ifdef CONFIG_XMON
-	xmon(NULL);
-#endif
-	for (;;)
-		prom_exit();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/prom_init.c linux/arch/ppc/kernel/prom_init.c
--- linux.orig/arch/ppc/kernel/prom_init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc/kernel/prom_init.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,892 @@
+/*
+ * Procedures for interfacing to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * In particular, we are interested in the device tree
+ * and in using some of its services (exit, write to stdout).
+ *
+ * Paul Mackerras	August 1996.
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+/*
+ * Note that prom_init() and anything called from prom_init()
+ * may be running at an address that is different from the address
+ * that it was linked at.  References to static data items are
+ * handled by compiling this file with -mrelocatable-lib.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/bootx.h>
+#include <asm/btext.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_FB
+#include <asm/linux_logo.h>
+#endif
+
+/*
+ * Properties whose value is longer than this get excluded from our
+ * copy of the device tree.  This way we don't waste space storing
+ * things like "driver,AAPL,MacOS,PowerPC" properties.  But this value
+ * does need to be big enough to ensure that we don't lose things
+ * like the interrupt-map property on a PCI-PCI bridge.
+ */
+#define MAX_PROPERTY_LENGTH	4096
+
+#ifndef FB_MAX			/* avoid pulling in all of the fb stuff */
+#define FB_MAX	8
+#endif
+
+#define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
+
+struct prom_args {
+	const char *service;
+	int nargs;
+	int nret;
+	void *args[10];
+};
+
+struct pci_address {
+	unsigned a_hi;
+	unsigned a_mid;
+	unsigned a_lo;
+};
+
+struct pci_reg_property {
+	struct pci_address addr;
+	unsigned size_hi;
+	unsigned size_lo;
+};
+
+struct pci_range {
+	struct pci_address addr;
+	unsigned phys;
+	unsigned size_hi;
+	unsigned size_lo;
+};
+
+struct isa_reg_property {
+	unsigned space;
+	unsigned address;
+	unsigned size;
+};
+
+struct pci_intr_map {
+	struct pci_address addr;
+	unsigned dunno;
+	phandle int_ctrler;
+	unsigned intr;
+};
+
+static void prom_exit(void);
+static void *call_prom(const char *service, int nargs, int nret, ...);
+static void *call_prom_ret(const char *service, int nargs, int nret,
+			   void **rets, ...);
+static void prom_print_hex(unsigned int v);
+static int  prom_set_color(ihandle ih, int i, int r, int g, int b);
+static int  prom_next_node(phandle *nodep);
+static unsigned long check_display(unsigned long mem);
+static void setup_disp_fake_bi(ihandle dp);
+static unsigned long copy_device_tree(unsigned long mem_start,
+				unsigned long mem_end);
+static unsigned long inspect_node(phandle node, struct device_node *dad,
+				unsigned long mem_start, unsigned long mem_end,
+				struct device_node ***allnextpp);
+static void prom_hold_cpus(unsigned long mem);
+static void prom_instantiate_rtas(void);
+static void * early_get_property(unsigned long base, unsigned long node,
+				char *prop);
+
+prom_entry prom __initdata = 0;
+ihandle prom_chosen __initdata = 0;
+ihandle prom_stdout __initdata = 0;
+
+char *prom_display_paths[FB_MAX] __initdata = { 0, };
+phandle prom_display_nodes[FB_MAX] __initdata;
+unsigned int prom_num_displays __initdata = 0;
+static char *of_stdout_device __initdata = 0;
+static ihandle prom_disp_node __initdata = 0;
+
+unsigned int rtas_data;   /* physical pointer */
+unsigned int rtas_entry;  /* physical pointer */
+unsigned int rtas_size;
+unsigned int old_rtas;
+
+boot_infos_t *boot_infos;
+char *bootpath;
+char *bootdevice;
+struct device_node *allnodes;
+
+extern char *klimit;
+extern char _stext;
+
+static void __init
+prom_exit(void)
+{
+	struct prom_args args;
+
+	args.service = "exit";
+	args.nargs = 0;
+	args.nret = 0;
+	prom(&args);
+	for (;;)			/* should never get here */
+		;
+}
+
+static void * __init
+call_prom(const char *service, int nargs, int nret, ...)
+{
+	va_list list;
+	int i;
+	struct prom_args prom_args;
+
+	prom_args.service = service;
+	prom_args.nargs = nargs;
+	prom_args.nret = nret;
+	va_start(list, nret);
+	for (i = 0; i < nargs; ++i)
+		prom_args.args[i] = va_arg(list, void *);
+	va_end(list);
+	for (i = 0; i < nret; ++i)
+		prom_args.args[i + nargs] = 0;
+	prom(&prom_args);
+	return prom_args.args[nargs];
+}
+
+static void * __init
+call_prom_ret(const char *service, int nargs, int nret, void **rets, ...)
+{
+	va_list list;
+	int i;
+	struct prom_args prom_args;
+
+	prom_args.service = service;
+	prom_args.nargs = nargs;
+	prom_args.nret = nret;
+	va_start(list, rets);
+	for (i = 0; i < nargs; ++i)
+		prom_args.args[i] = va_arg(list, void *);
+	va_end(list);
+	for (i = 0; i < nret; ++i)
+		prom_args.args[i + nargs] = 0;
+	prom(&prom_args);
+	for (i = 1; i < nret; ++i)
+		rets[i-1] = prom_args.args[nargs + i];
+	return prom_args.args[nargs];
+}
+
+void __init
+prom_print(const char *msg)
+{
+	const char *p, *q;
+
+	if (prom_stdout == 0)
+		return;
+
+	for (p = msg; *p != 0; p = q) {
+		for (q = p; *q != 0 && *q != '\n'; ++q)
+			;
+		if (q > p)
+			call_prom("write", 3, 1, prom_stdout, p, q - p);
+		if (*q != 0) {
+			++q;
+			call_prom("write", 3, 1, prom_stdout, "\r\n", 2);
+		}
+	}
+}
+
+static void __init
+prom_print_hex(unsigned int v)
+{
+	char buf[16];
+	int i, c;
+
+	for (i = 0; i < 8; ++i) {
+		c = (v >> ((7-i)*4)) & 0xf;
+		c += (c >= 10)? ('a' - 10): '0';
+		buf[i] = c;
+	}
+	buf[i] = ' ';
+	buf[i+1] = 0;
+	prom_print(buf);
+}
+
+static int __init
+prom_set_color(ihandle ih, int i, int r, int g, int b)
+{
+	struct prom_args prom_args;
+
+	prom_args.service = "call-method";
+	prom_args.nargs = 6;
+	prom_args.nret = 1;
+	prom_args.args[0] = "color!";
+	prom_args.args[1] = ih;
+	prom_args.args[2] = (void *) i;
+	prom_args.args[3] = (void *) b;
+	prom_args.args[4] = (void *) g;
+	prom_args.args[5] = (void *) r;
+	prom(&prom_args);
+	return (int) prom_args.args[6];
+}
+
+static int __init
+prom_next_node(phandle *nodep)
+{
+	phandle node;
+
+	if ((node = *nodep) != 0
+	    && (*nodep = call_prom("child", 1, 1, node)) != 0)
+		return 1;
+	if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
+		return 1;
+	for (;;) {
+		if ((node = call_prom("parent", 1, 1, node)) == 0)
+			return 0;
+		if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
+			return 1;
+	}
+}
+
+/*
+ * If we have a display that we don't know how to drive,
+ * we will want to try to execute OF's open method for it
+ * later.  However, OF will probably fall over if we do that
+ * we've taken over the MMU.
+ * So we check whether we will need to open the display,
+ * and if so, open it now.
+ */
+static unsigned long __init
+check_display(unsigned long mem)
+{
+	phandle node;
+	ihandle ih;
+	int i;
+	char type[16], *path;
+	static unsigned char default_colors[] = {
+		0x00, 0x00, 0x00,
+		0x00, 0x00, 0xaa,
+		0x00, 0xaa, 0x00,
+		0x00, 0xaa, 0xaa,
+		0xaa, 0x00, 0x00,
+		0xaa, 0x00, 0xaa,
+		0xaa, 0xaa, 0x00,
+		0xaa, 0xaa, 0xaa,
+		0x55, 0x55, 0x55,
+		0x55, 0x55, 0xff,
+		0x55, 0xff, 0x55,
+		0x55, 0xff, 0xff,
+		0xff, 0x55, 0x55,
+		0xff, 0x55, 0xff,
+		0xff, 0xff, 0x55,
+		0xff, 0xff, 0xff
+	};
+
+	prom_disp_node = 0;
+
+	for (node = 0; prom_next_node(&node); ) {
+		type[0] = 0;
+		call_prom("getprop", 4, 1, node, "device_type",
+			  type, sizeof(type));
+		if (strcmp(type, "display") != 0)
+			continue;
+		/* It seems OF doesn't null-terminate the path :-( */
+		path = (char *) mem;
+		memset(path, 0, 256);
+		if ((int) call_prom("package-to-path", 3, 1,
+				    node, path, 255) < 0)
+			continue;
+
+		/*
+		 * If this display is the device that OF is using for stdout,
+		 * move it to the front of the list.
+		 */
+		mem += strlen(path) + 1;
+		i = prom_num_displays++;
+		if (of_stdout_device != 0 && i > 0
+		    && strcmp(of_stdout_device, path) == 0) {
+			for (; i > 0; --i) {
+				prom_display_paths[i]
+					= prom_display_paths[i-1];
+				prom_display_nodes[i]
+					= prom_display_nodes[i-1];
+			}
+		}
+		prom_display_paths[i] = path;
+		prom_display_nodes[i] = node;
+		if (i == 0)
+			prom_disp_node = node;
+		if (prom_num_displays >= FB_MAX)
+			break;
+	}
+
+try_again:
+	/*
+	 * Open the first display and set its colormap.
+	 */
+	if (prom_num_displays > 0) {
+		path = prom_display_paths[0];
+		prom_print("opening display ");
+		prom_print(path);
+		ih = call_prom("open", 1, 1, path);
+		if (ih == 0 || ih == (ihandle) -1) {
+			prom_print("... failed\n");
+			for (i=1; i<prom_num_displays; i++) {
+				prom_display_paths[i-1] = prom_display_paths[i];
+				prom_display_nodes[i-1] = prom_display_nodes[i];
+			}
+			if (--prom_num_displays > 0)
+				prom_disp_node = prom_display_nodes[0];
+			else
+				prom_disp_node = NULL;
+			goto try_again;
+		} else {
+			prom_print("... ok\n");
+			/*
+			 * Setup a usable color table when the appropriate
+			 * method is available.
+			 * Should update this to use set-colors.
+			 */
+			for (i = 0; i < 32; i++)
+				if (prom_set_color(ih, i, default_colors[i*3],
+						   default_colors[i*3+1],
+						   default_colors[i*3+2]) != 0)
+					break;
+
+#ifdef CONFIG_FB
+			for (i = 0; i < LINUX_LOGO_COLORS; i++)
+				if (prom_set_color(ih, i + 32,
+						   linux_logo_red[i],
+						   linux_logo_green[i],
+						   linux_logo_blue[i]) != 0)
+					break;
+#endif /* CONFIG_FB */
+		}
+	}
+
+	return ALIGN(mem);
+}
+
+/* This function will enable the early boot text when doing OF booting. This
+ * way, xmon output should work too
+ */
+static void __init
+setup_disp_fake_bi(ihandle dp)
+{
+#ifdef CONFIG_BOOTX_TEXT
+	int width = 640, height = 480, depth = 8, pitch;
+	unsigned address;
+	struct pci_reg_property addrs[8];
+	int i, naddrs;
+	char name[32];
+	char *getprop = "getprop";
+
+	prom_print("Initializing fake screen: ");
+
+	memset(name, 0, sizeof(name));
+	call_prom(getprop, 4, 1, dp, "name", name, sizeof(name));
+	name[sizeof(name)-1] = 0;
+	prom_print(name);
+	prom_print("\n");
+	call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width));
+	call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height));
+	call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth));
+	pitch = width * ((depth + 7) / 8);
+	call_prom(getprop, 4, 1, dp, "linebytes",
+		  &pitch, sizeof(pitch));
+	if (pitch == 1)
+		pitch = 0x1000;		/* for strange IBM display */
+	address = 0;
+	call_prom(getprop, 4, 1, dp, "address",
+		  &address, sizeof(address));
+	if (address == 0) {
+		/* look for an assigned address with a size of >= 1MB */
+		naddrs = (int) call_prom(getprop, 4, 1, dp,
+				"assigned-addresses",
+				addrs, sizeof(addrs));
+		naddrs /= sizeof(struct pci_reg_property);
+		for (i = 0; i < naddrs; ++i) {
+			if (addrs[i].size_lo >= (1 << 20)) {
+				address = addrs[i].addr.a_lo;
+				/* use the BE aperture if possible */
+				if (addrs[i].size_lo >= (16 << 20))
+					address += (8 << 20);
+				break;
+			}
+		}
+		if (address == 0) {
+			prom_print("Failed to get address\n");
+			return;
+		}
+	}
+	/* kludge for valkyrie */
+	if (strcmp(name, "valkyrie") == 0)
+		address += 0x1000;
+
+	btext_setup_display(width, height, depth, pitch, address);
+
+	btext_prepare_BAT();
+#endif /* CONFIG_BOOTX_TEXT */
+}
+
+/*
+ * Make a copy of the device tree from the PROM.
+ */
+static unsigned long __init
+copy_device_tree(unsigned long mem_start, unsigned long mem_end)
+{
+	phandle root;
+	unsigned long new_start;
+	struct device_node **allnextp;
+
+	root = call_prom("peer", 1, 1, (phandle)0);
+	if (root == (phandle)0) {
+		prom_print("couldn't get device tree root\n");
+		prom_exit();
+	}
+	allnextp = &allnodes;
+	mem_start = ALIGN(mem_start);
+	new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
+	*allnextp = 0;
+	return new_start;
+}
+
+static unsigned long __init
+inspect_node(phandle node, struct device_node *dad,
+	     unsigned long mem_start, unsigned long mem_end,
+	     struct device_node ***allnextpp)
+{
+	int l;
+	phandle child;
+	struct device_node *np;
+	struct property *pp, **prev_propp;
+	char *prev_name, *namep;
+	unsigned char *valp;
+
+	np = (struct device_node *) mem_start;
+	mem_start += sizeof(struct device_node);
+	memset(np, 0, sizeof(*np));
+	np->node = node;
+	**allnextpp = PTRUNRELOC(np);
+	*allnextpp = &np->allnext;
+	if (dad != 0) {
+		np->parent = PTRUNRELOC(dad);
+		/* we temporarily use the `next' field as `last_child'. */
+		if (dad->next == 0)
+			dad->child = PTRUNRELOC(np);
+		else
+			dad->next->sibling = PTRUNRELOC(np);
+		dad->next = np;
+	}
+
+	/* get and store all properties */
+	prev_propp = &np->properties;
+	prev_name = "";
+	for (;;) {
+		pp = (struct property *) mem_start;
+		namep = (char *) (pp + 1);
+		pp->name = PTRUNRELOC(namep);
+		if ((int) call_prom("nextprop", 3, 1, node, prev_name,
+				    namep) <= 0)
+			break;
+		mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
+		prev_name = namep;
+		valp = (unsigned char *) mem_start;
+		pp->value = PTRUNRELOC(valp);
+		pp->length = (int)
+			call_prom("getprop", 4, 1, node, namep,
+				  valp, mem_end - mem_start);
+		if (pp->length < 0)
+			continue;
+#ifdef MAX_PROPERTY_LENGTH
+		if (pp->length > MAX_PROPERTY_LENGTH)
+			continue; /* ignore this property */
+#endif
+		mem_start = ALIGN(mem_start + pp->length);
+		*prev_propp = PTRUNRELOC(pp);
+		prev_propp = &pp->next;
+	}
+	if (np->node != NULL) {
+		/* Add a "linux,phandle" property" */
+		pp = (struct property *) mem_start;
+		*prev_propp = PTRUNRELOC(pp);
+		prev_propp = &pp->next;
+		namep = (char *) (pp + 1);
+		pp->name = PTRUNRELOC(namep);
+		strcpy(namep, "linux,phandle");
+		mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
+		pp->value = (unsigned char *) PTRUNRELOC(&np->node);
+		pp->length = sizeof(np->node);
+	}
+	*prev_propp = NULL;
+
+	/* get the node's full name */
+	l = (int) call_prom("package-to-path", 3, 1, node,
+			    (char *) mem_start, mem_end - mem_start);
+	if (l >= 0) {
+		np->full_name = PTRUNRELOC((char *) mem_start);
+		*(char *)(mem_start + l) = 0;
+		mem_start = ALIGN(mem_start + l + 1);
+	}
+
+	/* do all our children */
+	child = call_prom("child", 1, 1, node);
+	while (child != (void *)0) {
+		mem_start = inspect_node(child, np, mem_start, mem_end,
+					 allnextpp);
+		child = call_prom("peer", 1, 1, child);
+	}
+
+	return mem_start;
+}
+
+unsigned long smp_chrp_cpu_nr __initdata = 0;
+
+/*
+ * With CHRP SMP we need to use the OF to start the other
+ * processors so we can't wait until smp_boot_cpus (the OF is
+ * trashed by then) so we have to put the processors into
+ * a holding pattern controlled by the kernel (not OF) before
+ * we destroy the OF.
+ *
+ * This uses a chunk of high memory, puts some holding pattern
+ * code there and sends the other processors off to there until
+ * smp_boot_cpus tells them to do something.  We do that by using
+ * physical address 0x0.  The holding pattern checks that address
+ * until its cpu # is there, when it is that cpu jumps to
+ * __secondary_start().  smp_boot_cpus() takes care of setting those
+ * values.
+ *
+ * We also use physical address 0x4 here to tell when a cpu
+ * is in its holding pattern code.
+ *
+ * -- Cort
+ *
+ * Note that we have to do this if we have more than one CPU,
+ * even if this is a UP kernel.  Otherwise when we trash OF
+ * the other CPUs will start executing some random instructions
+ * and crash the system.  -- paulus
+ */
+static void __init
+prom_hold_cpus(unsigned long mem)
+{
+	extern void __secondary_hold(void);
+	unsigned long i;
+	int cpu;
+	phandle node;
+	char type[16], *path;
+	unsigned int reg;
+
+	/*
+	 * XXX: hack to make sure we're chrp, assume that if we're
+	 *      chrp we have a device_type property -- Cort
+	 */
+	node = call_prom("finddevice", 1, 1, "/");
+	if ((int)call_prom("getprop", 4, 1, node,
+			   "device_type",type, sizeof(type)) <= 0)
+		return;
+
+	/* copy the holding pattern code to someplace safe (0) */
+	/* the holding pattern is now within the first 0x100
+	   bytes of the kernel image -- paulus */
+	memcpy((void *)0, &_stext, 0x100);
+	flush_icache_range(0, 0x100);
+
+	/* look for cpus */
+	*(unsigned long *)(0x0) = 0;
+	asm volatile("dcbf 0,%0": : "r" (0) : "memory");
+	for (node = 0; prom_next_node(&node); ) {
+		type[0] = 0;
+		call_prom("getprop", 4, 1, node, "device_type",
+			  type, sizeof(type));
+		if (strcmp(type, "cpu") != 0)
+			continue;
+		path = (char *) mem;
+		memset(path, 0, 256);
+		if ((int) call_prom("package-to-path", 3, 1,
+				    node, path, 255) < 0)
+			continue;
+		reg = -1;
+		call_prom("getprop", 4, 1, node, "reg", &reg, sizeof(reg));
+		cpu = smp_chrp_cpu_nr++;
+#ifdef CONFIG_SMP
+		smp_hw_index[cpu] = reg;
+#endif /* CONFIG_SMP */
+		/* XXX: hack - don't start cpu 0, this cpu -- Cort */
+		if (cpu == 0)
+			continue;
+		prom_print("starting cpu ");
+		prom_print(path);
+		*(ulong *)(0x4) = 0;
+		call_prom("start-cpu", 3, 0, node,
+			  (char *)__secondary_hold - &_stext, cpu);
+		prom_print("...");
+		for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
+			;
+		if (*(ulong *)(0x4) == cpu)
+			prom_print("ok\n");
+		else {
+			prom_print("failed: ");
+			prom_print_hex(*(ulong *)0x4);
+			prom_print("\n");
+		}
+	}
+}
+
+static void __init
+prom_instantiate_rtas(void)
+{
+	ihandle prom_rtas;
+	unsigned int i;
+	struct prom_args prom_args;
+
+	prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
+	if (prom_rtas == (void *) -1)
+		return;
+
+	rtas_size = 0;
+	call_prom("getprop", 4, 1, prom_rtas,
+		  "rtas-size", &rtas_size, sizeof(rtas_size));
+	prom_print("instantiating rtas");
+	if (rtas_size == 0) {
+		rtas_data = 0;
+	} else {
+		/*
+		 * Ask OF for some space for RTAS.
+		 * Actually OF has bugs so we just arbitrarily
+		 * use memory at the 6MB point.
+		 */
+		rtas_data = 6 << 20;
+		prom_print(" at ");
+		prom_print_hex(rtas_data);
+	}
+
+	prom_rtas = call_prom("open", 1, 1, "/rtas");
+	prom_print("...");
+	prom_args.service = "call-method";
+	prom_args.nargs = 3;
+	prom_args.nret = 2;
+	prom_args.args[0] = "instantiate-rtas";
+	prom_args.args[1] = prom_rtas;
+	prom_args.args[2] = (void *) rtas_data;
+	prom(&prom_args);
+	i = 0;
+	if (prom_args.args[3] == 0)
+		i = (unsigned int)prom_args.args[4];
+	rtas_entry = i;
+	if ((rtas_entry == -1) || (rtas_entry == 0))
+		prom_print(" failed\n");
+	else
+		prom_print(" done\n");
+}
+
+/*
+ * We enter here early on, when the Open Firmware prom is still
+ * handling exceptions and the MMU hash table for us.
+ */
+unsigned long __init
+prom_init(int r3, int r4, prom_entry pp)
+{
+	unsigned long mem;
+	ihandle prom_mmu;
+	unsigned long offset = reloc_offset();
+	int i, l;
+	char *p, *d;
+ 	unsigned long phys;
+	void *result[3];
+
+ 	/* Default */
+ 	phys = (unsigned long) &_stext;
+
+	/* First get a handle for the stdout device */
+	prom = pp;
+	prom_chosen = call_prom("finddevice", 1, 1,
+				       "/chosen");
+	if (prom_chosen == (void *)-1)
+		prom_exit();
+	if ((int) call_prom("getprop", 4, 1, prom_chosen,
+			    "stdout", &prom_stdout,
+			    sizeof(prom_stdout)) <= 0)
+		prom_exit();
+
+	/* Get the full OF pathname of the stdout device */
+	mem = (unsigned long) klimit + offset;
+	p = (char *) mem;
+	memset(p, 0, 256);
+	call_prom("instance-to-path", 3, 1, prom_stdout, p, 255);
+	of_stdout_device = p;
+	mem += strlen(p) + 1;
+
+	/* Get the boot device and translate it to a full OF pathname. */
+	p = (char *) mem;
+	l = (int) call_prom("getprop", 4, 1, prom_chosen,
+			    "bootpath", p, 1<<20);
+	if (l > 0) {
+		p[l] = 0;	/* should already be null-terminated */
+		bootpath = PTRUNRELOC(p);
+		mem += l + 1;
+		d = (char *) mem;
+		*d = 0;
+		call_prom("canon", 3, 1, p, d, 1<<20);
+		bootdevice = PTRUNRELOC(d);
+		mem = ALIGN(mem + strlen(d) + 1);
+	}
+
+	prom_instantiate_rtas();
+
+	mem = check_display(mem);
+
+	prom_print("copying OF device tree...");
+	mem = copy_device_tree(mem, mem + (1<<20));
+	prom_print("done\n");
+
+	prom_hold_cpus(mem);
+
+	klimit = (char *) (mem - offset);
+
+	/* If we are already running at 0xc0000000, we assume we were
+	 * loaded by an OF bootloader which did set a BAT for us.
+	 * This breaks OF translate so we force phys to be 0.
+	 */
+	if (offset == 0)
+		phys = 0;
+	else if ((int) call_prom("getprop", 4, 1, prom_chosen, "mmu",
+				 &prom_mmu, sizeof(prom_mmu)) <= 0) {
+		prom_print(" no MMU found\n");
+	} else if ((int)call_prom_ret("call-method", 4, 4, result, "translate",
+				      prom_mmu, &_stext, 1) != 0) {
+		prom_print(" (translate failed)\n");
+	} else {
+		/* We assume the phys. address size is 3 cells */
+		phys = (unsigned long)result[2];
+	}
+
+	if (prom_disp_node != 0)
+		setup_disp_fake_bi(prom_disp_node);
+
+	/* Use quiesce call to get OF to shut down any devices it's using */
+	prom_print("Calling quiesce ...\n");
+	call_prom("quiesce", 0, 0);
+
+	/* Relocate various pointers which will be used once the
+	   kernel is running at the address it was linked at. */
+	for (i = 0; i < prom_num_displays; ++i)
+		prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]);
+
+	prom_print("returning 0x");
+	prom_print_hex(phys);
+	prom_print("from prom_init\n");
+	prom_stdout = 0;
+
+	return phys;
+}
+
+/*
+ * early_get_property is used to access the device tree image prepared
+ * by BootX very early on, before the pointers in it have been relocated.
+ */
+static void * __init
+early_get_property(unsigned long base, unsigned long node, char *prop)
+{
+	struct device_node *np = (struct device_node *)(base + node);
+	struct property *pp;
+
+	for (pp = np->properties; pp != 0; pp = pp->next) {
+		pp = (struct property *) (base + (unsigned long)pp);
+		if (strcmp((char *)((unsigned long)pp->name + base),
+			   prop) == 0) {
+			return (void *)((unsigned long)pp->value + base);
+		}
+	}
+	return 0;
+}
+
+/* Is boot-info compatible ? */
+#define BOOT_INFO_IS_COMPATIBLE(bi)		((bi)->compatible_version <= BOOT_INFO_VERSION)
+#define BOOT_INFO_IS_V2_COMPATIBLE(bi)	((bi)->version >= 2)
+#define BOOT_INFO_IS_V4_COMPATIBLE(bi)	((bi)->version >= 4)
+
+void __init
+bootx_init(unsigned long r4, unsigned long phys)
+{
+	boot_infos_t *bi = (boot_infos_t *) r4;
+	unsigned long space;
+	unsigned long ptr, x;
+	char *model;
+
+	boot_infos = PTRUNRELOC(bi);
+	if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
+		bi->logicalDisplayBase = 0;
+
+#ifdef CONFIG_BOOTX_TEXT
+	btext_init(bi);
+
+	/*
+	 * Test if boot-info is compatible.  Done only in config
+	 * CONFIG_BOOTX_TEXT since there is nothing much we can do
+	 * with an incompatible version, except display a message
+	 * and eventually hang the processor...
+	 *
+	 * I'll try to keep enough of boot-info compatible in the
+	 * future to always allow display of this message;
+	 */
+	if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
+		btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
+		btext_flushscreen();
+	}
+#endif	/* CONFIG_BOOTX_TEXT */
+
+	/* New BootX enters kernel with MMU off, i/os are not allowed
+	   here. This hack will have been done by the boostrap anyway.
+	*/
+	if (bi->version < 4) {
+		/*
+		 * XXX If this is an iMac, turn off the USB controller.
+		 */
+		model = (char *) early_get_property
+			(r4 + bi->deviceTreeOffset, 4, "model");
+		if (model
+		    && (strcmp(model, "iMac,1") == 0
+			|| strcmp(model, "PowerMac1,1") == 0)) {
+			out_le32((unsigned *)0x80880008, 1);	/* XXX */
+		}
+	}
+
+	/* Move klimit to enclose device tree, args, ramdisk, etc... */
+	if (bi->version < 5) {
+		space = bi->deviceTreeOffset + bi->deviceTreeSize;
+		if (bi->ramDisk)
+			space = bi->ramDisk + bi->ramDiskSize;
+	} else
+		space = bi->totalParamsSize;
+	klimit = PTRUNRELOC((char *) bi + space);
+
+	/* New BootX will have flushed all TLBs and enters kernel with
+	   MMU switched OFF, so this should not be useful anymore.
+	*/
+	if (bi->version < 4) {
+		/*
+		 * Touch each page to make sure the PTEs for them
+		 * are in the hash table - the aim is to try to avoid
+		 * getting DSI exceptions while copying the kernel image.
+		 */
+		for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
+		     ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
+			x = *(volatile unsigned long *)ptr;
+	}
+
+#ifdef CONFIG_BOOTX_TEXT
+	/*
+	 * Note that after we call btext_prepare_BAT, we can't do
+	 * prom_draw*, flushscreen or clearscreen until we turn the MMU
+	 * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase
+	 * to a virtual address.
+	 */
+	btext_prepare_BAT();
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c
--- linux.orig/arch/ppc/kernel/ptrace.c	2001-11-26 13:29:17.000000000 +0000
+++ linux/arch/ppc/kernel/ptrace.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ptrace.c 1.12 11/23/01 16:38:30 paulus
+ * BK Id: SCCS/s.ptrace.c 1.14 01/17/02 23:05:50 paulus
  */
 /*
  *  linux/arch/ppc/kernel/ptrace.c
@@ -71,6 +71,64 @@
 	return -EIO;
 }
 
+#ifdef CONFIG_ALTIVEC
+/*
+ * Get contents of AltiVec register state in task TASK
+ */
+static inline int get_vrregs(unsigned long *data, struct task_struct *task)
+{
+	int i, j;
+
+	if (!access_ok(VERIFY_WRITE, data, 133 * sizeof(unsigned long)))
+		return -EFAULT;
+
+	/* copy AltiVec registers VR[0] .. VR[31] */
+	for (i = 0; i < 32; i++)
+		for (j = 0; j < 4; j++, data++)
+			if (__put_user(task->thread.vr[i].u[j], data))
+				return -EFAULT;
+
+	/* copy VSCR */
+	for (i = 0; i < 4; i++, data++)
+		if (__put_user(task->thread.vscr.u[i], data))
+			return -EFAULT;
+
+        /* copy VRSAVE */
+	if (__put_user(task->thread.vrsave, data))
+		return -EFAULT;
+
+	return 0;
+}
+
+/*
+ * Write contents of AltiVec register state into task TASK.
+ */
+static inline int set_vrregs(struct task_struct *task, unsigned long *data)
+{
+	int i, j;
+
+	if (!access_ok(VERIFY_READ, data, 133 * sizeof(unsigned long)))
+		return -EFAULT;
+
+	/* copy AltiVec registers VR[0] .. VR[31] */
+	for (i = 0; i < 32; i++)
+		for (j = 0; j < 4; j++, data++) 
+			if (__get_user(task->thread.vr[i].u[j], data))
+				return -EFAULT;
+
+	/* copy VSCR */
+	for (i = 0; i < 4; i++, data++) 
+		if (__get_user(task->thread.vscr.u[i], data))
+			return -EFAULT;
+
+	/* copy VRSAVE */
+	if (__get_user(task->thread.vrsave, data))
+		return -EFAULT;
+
+	return 0;
+}
+#endif
+
 static inline void
 set_single_step(struct task_struct *task)
 {
@@ -259,6 +317,24 @@
 		ret = ptrace_detach(child, data);
 		break;
 
+#ifdef CONFIG_ALTIVEC
+	case PTRACE_GETVRREGS:
+		/* Get the child altivec register state. */
+		if (child->thread.regs->msr & MSR_VEC)
+			giveup_altivec(child);
+		ret = get_vrregs((unsigned long *)data, child);
+		break;
+
+	case PTRACE_SETVRREGS:
+		/* Set the child altivec register state. */
+		/* this is to clear the MSR_VEC bit to force a reload
+		 * of register state from memory */
+		if (child->thread.regs->msr & MSR_VEC)
+			giveup_altivec(child);
+		ret = set_vrregs(child, (unsigned long *)data);
+		break;
+#endif
+
 	default:
 		ret = -EIO;
 		break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/qspan_pci.c linux/arch/ppc/kernel/qspan_pci.c
--- linux.orig/arch/ppc/kernel/qspan_pci.c	2001-05-22 00:04:47.000000000 +0000
+++ linux/arch/ppc/kernel/qspan_pci.c	2002-07-20 01:08:28.000000000 +0000
@@ -14,7 +14,7 @@
  * PCI access and QSpan control register addresses.  The selection is
  * further selected by a bit setting in a board control register.
  * Although it should happen, we disable interrupts during this operation
- * to make sure some driver doesn't accidently access the PCI while
+ * to make sure some driver doesn't accidentally access the PCI while
  * we have switched the chip select.
  */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/residual.c linux/arch/ppc/kernel/residual.c
--- linux.orig/arch/ppc/kernel/residual.c	2001-10-08 18:43:01.000000000 +0000
+++ linux/arch/ppc/kernel/residual.c	2002-07-20 01:08:28.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.residual.c 1.13 09/11/01 16:54:34 trini
+ * BK Id: SCCS/s.residual.c 1.15 02/05/02 18:08:35 trini
  */
 /*
  * Code to deal with the PReP residual data.
@@ -876,3 +876,38 @@
 	};
 	return 0; /* not found */
 }
+
+#ifdef CONFIG_PROC_PREPRESIDUAL
+static int proc_prep_residual_read(char * buf, char ** start, off_t off,
+		int count, int *eof, void *data)
+{
+	int n;
+
+	n = res->ResidualLength - off;
+	if (n < 0) {
+		*eof = 1;
+		n = 0;
+	}
+	else {
+		if (n > count)
+			n = count;
+		else
+			*eof = 1;
+
+		memcpy(buf, (char *)res + off, n);
+		*start = buf;
+	}
+
+	return n;
+}
+
+void __init
+proc_prep_residual_init(void)
+{
+	if (res->ResidualLength)
+		create_proc_read_entry("residual", S_IRUGO, NULL,
+					proc_prep_residual_read, NULL);
+}
+
+__initcall(proc_prep_residual_init);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- linux.orig/arch/ppc/kernel/setup.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/setup.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.setup.c 1.67 12/01/01 20:09:07 benh
+ * BK Id: SCCS/s.setup.c 1.75 04/16/02 20:08:22 paulus
  */
 /*
  * Common prep/pmac/chrp boot and setup code.
@@ -50,16 +50,17 @@
 extern void platform_init(unsigned long r3, unsigned long r4,
 		unsigned long r5, unsigned long r6, unsigned long r7);
 extern void bootx_init(unsigned long r4, unsigned long phys);
-extern unsigned long reloc_offset(void);
 extern void identify_cpu(unsigned long offset, unsigned long cpu);
 extern void do_cpu_ftr_fixups(unsigned long offset);
+extern void reloc_got2(unsigned long offset);
 
 #ifdef CONFIG_XMON
 extern void xmon_map_scc(void);
 #endif
 
 extern boot_infos_t *boot_infos;
-char saved_command_line[256];
+char saved_command_line[512];
+extern char cmd_line[512];
 unsigned char aux_device_present;
 struct ide_machdep_calls ppc_ide_md;
 char *sysmap;
@@ -291,22 +292,22 @@
 	do_cpu_ftr_fixups(offset);
 
 #if defined(CONFIG_ALL_PPC)
+	reloc_got2(offset);
+
 	/* If we came here from BootX, clear the screen,
 	 * set up some pointers and return. */
-	if ((r3 == 0x426f6f58) && (r5 == 0)) {
+	if ((r3 == 0x426f6f58) && (r5 == 0))
 		bootx_init(r4, phys);
-		return phys;
-	}
-
-	/* check if we're prep, return if we are */
-	if ( *(unsigned long *)(0) == 0xdeadc0de )
-		return phys;
 
-	/* 
+	/*
+	 * don't do anything on prep
 	 * for now, don't use bootinfo because it breaks yaboot 0.5
 	 * and assume that if we didn't find a magic number, we have OF
 	 */
-	phys = prom_init(r3, r4, (prom_entry)r5);
+	else if (*(unsigned long *)(0) != 0xdeadc0de)
+		phys = prom_init(r3, r4, (prom_entry)r5);
+
+	reloc_got2(-offset);
 #endif
 
 	return phys;
@@ -343,11 +344,9 @@
 	      unsigned long r6, unsigned long r7)
 {
 #ifdef CONFIG_BOOTX_TEXT
-	extern boot_infos_t *disp_bi;
-
-	if (disp_bi) {
+	if (boot_text_mapped) {
 		btext_clearscreen();
-		btext_welcome(disp_bi);
+		btext_welcome();
 	}
 #endif	
 
@@ -409,15 +408,14 @@
 		char *p;
 			
 #ifdef CONFIG_BLK_DEV_INITRD
-		if (r3 && r4 && r4 != 0xdeadbeef)
-			{
-				if (r3 < KERNELBASE)
-					r3 += KERNELBASE;
-				initrd_start = r3;
-				initrd_end = r3 + r4;
-				ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-				initrd_below_start_ok = 1;
-			}
+		if (r3 && r4 && r4 != 0xdeadbeef) {
+			if (r3 < KERNELBASE)
+				r3 += KERNELBASE;
+			initrd_start = r3;
+			initrd_end = r3 + r4;
+			ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+			initrd_below_start_ok = 1;
+		}
 #endif
 		chosen = find_devices("chosen");
 		if (chosen != NULL) {
@@ -525,6 +523,12 @@
 }
 __setup("l2cr=", ppc_setup_l2cr);
 
+void __init arch_discover_root(void)
+{
+	if (ppc_md.discover_root != NULL)
+		ppc_md.discover_root();
+}
+
 void __init ppc_init(void)
 {
 	/* clear the progress line */
@@ -694,8 +698,12 @@
 	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
 	id->word92         = __le16_to_cpu(id->word92);
 	id->hw_config      = __le16_to_cpu(id->hw_config);
-	for (i = 0; i < 32; i++)
-		id->words94_125[i]  = __le16_to_cpu(id->words94_125[i]);
+	id->acoustic       = __le16_to_cpu(id->acoustic);
+	for (i = 0; i < 5; i++)
+		id->words95_99[i]  = __le16_to_cpu(id->words95_99[i]);
+	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
+	for (i = 0; i < 22; i++)
+		id->words104_125[i]   = __le16_to_cpu(id->words104_125[i]);
 	id->last_lun       = __le16_to_cpu(id->last_lun);
 	id->word127        = __le16_to_cpu(id->word127);
 	id->dlf            = __le16_to_cpu(id->dlf);
@@ -705,6 +713,12 @@
 	id->word156        = __le16_to_cpu(id->word156);
 	for (i = 0; i < 3; i++)
 		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
-	for (i = 0; i < 96; i++)
-		id->words160_255[i] = __le16_to_cpu(id->words160_255[i]);
+	id->cfa_power      = __le16_to_cpu(id->cfa_power);
+	for (i = 0; i < 14; i++)
+		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
+	for (i = 0; i < 31; i++)
+		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
+	for (i = 0; i < 48; i++)
+		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
+	id->integrity_word  = __le16_to_cpu(id->integrity_word);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c
--- linux.orig/arch/ppc/kernel/signal.c	2001-11-26 13:29:17.000000000 +0000
+++ linux/arch/ppc/kernel/signal.c	2002-07-20 01:08:35.000000000 +0000
@@ -645,10 +645,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/ppc/kernel/sleep.S linux/arch/ppc/kernel/sleep.S
--- linux.orig/arch/ppc/kernel/sleep.S	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/sleep.S	2002-07-20 01:08:25.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.sleep.S 1.18 12/02/01 12:38:54 benh
+ * BK Id: SCCS/s.sleep.S 1.20 03/19/02 15:04:39 benh
  */
 /*
  * This file contains sleep low-level functions for PowerBook G3.
@@ -13,10 +13,10 @@
  *
  */
 
-#include "ppc_asm.tmpl"
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/cputable.h>
+#include "ppc_asm.h"
 
 #define MAGIC	0x4c617273	/* 'Lars' */
 
@@ -49,9 +49,6 @@
 #define SL_R12		0x8c	/* r12 to r31 */
 #define SL_SIZE		(SL_R12 + 80)
 
-#define tophys(rd,rs)   addis   rd,rs,-KERNELBASE@h     
-#define tovirt(rd,rs)	addis	rd,rs,KERNELBASE@h
-
 	.text
 	.align	5
 
@@ -190,6 +187,10 @@
 	addi r3,r3,sleep_storage@l
 	stw r5,0(r3)
 
+	BEGIN_FTR_SECTION
+	DSSALL
+	sync
+	END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 
 /*
  * Flush the L1 data cache by reading the first 128kB of RAM
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- linux.orig/arch/ppc/kernel/smp.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/ppc/kernel/smp.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.smp.c 1.37 11/23/01 16:38:30 paulus
+ * BK Id: SCCS/s.smp.c 1.40 03/28/02 16:54:23 hozer
  */
 /*
  * Smp support for ppc.
@@ -65,7 +65,6 @@
 int start_secondary(void *);
 extern int cpu_idle(void *unused);
 void smp_call_function_interrupt(void);
-void smp_message_pass(int target, int msg, unsigned long data, int wait);
 
 /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
  * 
@@ -76,11 +75,14 @@
 #define PPC_MSG_INVALIDATE_TLB	2
 #define PPC_MSG_XMON_BREAK	3
 
-#define smp_message_pass(t,m,d,w) \
-    do { if (smp_ops) \
-	     atomic_inc(&ipi_sent); \
-	     smp_ops->message_pass((t),(m),(d),(w)); \
-       } while(0)
+static inline void 
+smp_message_pass(int target, int msg, unsigned long data, int wait)
+{
+	if (smp_ops){
+		atomic_inc(&ipi_sent);
+		smp_ops->message_pass(target,msg,data,wait);
+	}
+}
 
 /* 
  * Common functions
@@ -121,16 +123,18 @@
 	}
 }
 
+#ifdef CONFIG_750_SMP
 /*
  * 750's don't broadcast tlb invalidates so
  * we have to emulate that behavior.
  *   -- Cort
  */
-void smp_send_tlb_invalidate(int cpu)
+void smp_ppc750_send_tlb_invalidate(int cpu)
 {
 	if ( PVR_VER(mfspr(PVR)) == 8 )
 		smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0);
 }
+#endif
 
 void smp_send_reschedule(int cpu)
 {
@@ -309,6 +313,20 @@
 		return;
 	}
 
+#ifndef CONFIG_750_SMP
+	/* check for 750's, they just don't work with linux SMP.
+	 * If you actually have 750 SMP hardware and want to try to get
+	 * it to work, send me a patch to make it work and
+	 * I'll make CONFIG_750_SMP a config option.  -- Troy (hozer@drgw.net)
+	 */
+	if ( PVR_VER(mfspr(PVR)) == 8 ){
+		printk("SMP not supported on 750 cpus. %s line %d\n",
+				__FILE__, __LINE__);
+		return;
+	}
+#endif
+
+
 	/* Probe arch for CPUs */
 	cpu_nr = smp_ops->probe();
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
--- linux.orig/arch/ppc/kernel/syscalls.c	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/kernel/syscalls.c	2002-07-20 01:08:34.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.syscalls.c 1.11 10/16/01 15:58:42 trini
+ * BK Id: SCCS/s.syscalls.c 1.13 03/13/02 09:12:22 trini
  */
 /*
  * linux/arch/ppc/kernel/sys_ppc.c
@@ -223,11 +223,12 @@
 		       unsigned long fd, off_t offset)
 {
 	int err = -EINVAL;
+	unsigned long off = offset;
 
 	if (offset & ~PAGE_MASK)
 		goto out;
 
-	err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	err = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 out:
 	return err;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- linux.orig/arch/ppc/kernel/time.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/kernel/time.c	2002-07-20 01:08:28.000000000 +0000
@@ -358,7 +358,7 @@
 #define	STARTOFTIME		1970
 #define SECDAY			86400L
 #define SECYR			(SECDAY * 365)
-#define	leapyear(year)		((year) % 4 == 0)
+#define	leapyear(y)		((!(y % 4) && (y % 100)) || !(y % 400))
 #define	days_in_year(a) 	(leapyear(a) ? 366 : 365)
 #define	days_in_month(a) 	(month_days[(a) - 1])
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/lib/string.S linux/arch/ppc/lib/string.S
--- linux.orig/arch/ppc/lib/string.S	2001-11-03 01:43:54.000000000 +0000
+++ linux/arch/ppc/lib/string.S	2002-07-20 01:08:23.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.string.S 1.9 10/25/01 10:08:51 trini
+ * BK Id: SCCS/s.string.S 1.11 05/21/02 21:44:32 paulus
  */
 /*
  * String handling functions for PowerPC.
@@ -468,7 +468,7 @@
 53:
 #if !defined(CONFIG_8xx)
 	dcbt	r3,r4
-	dcbz	r11,r6
+54:	dcbz	r11,r6
 #endif
 /* had to move these to keep extable in order */
 	.section __ex_table,"a"
@@ -477,7 +477,9 @@
 	.long	71b,101f
 	.long	72b,102f
 	.long	73b,103f
-	.long	53b,105f
+#if !defined(CONFIG_8xx)
+	.long	54b,105f
+#endif
 	.text
 /* the main body of the cacheline loop */
 	COPY_16_BYTES_WITHEX(0)
@@ -621,11 +623,11 @@
 	add	r4,r0,r4
 	subf	r6,r0,r6
 	srwi	r0,r4,2
+	andi.	r4,r4,3
 	mtctr	r0
-	bdz	6f
+	bdz	7f
 1:	stwu	r5,4(r6)
 	bdnz	1b
-6:	andi.	r4,r4,3
 	/* clear byte sized chunks */
 7:	cmpwi	0,r4,0
 	beqlr
@@ -634,14 +636,20 @@
 8:	stbu	r5,1(r6)
 	bdnz	8b
 	blr
-99:	li	r3,-EFAULT
+90:	mr	r3,r4
+	blr
+91:	mfctr	r3
+	slwi	r3,r3,2
+	add	r3,r3,r4
+	blr
+92:	mfctr	r3
 	blr
 
 	.section __ex_table,"a"
 	.align	2
-	.long	11b,99b
-	.long	1b,99b
-	.long	8b,99b
+	.long	11b,90b
+	.long	1b,91b
+	.long	8b,92b
 	.text
 
 	.globl	__strncpy_from_user
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- linux.orig/arch/ppc/mm/init.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/mm/init.c	2002-07-20 01:08:28.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.init.c 1.40 01/25/02 15:15:24 benh
+ * BK Id: SCCS/s.init.c 1.43 03/12/02 12:13:51 paulus
  */
 /*
  *  PowerPC version 
@@ -230,7 +230,7 @@
 		 (unsigned long)(&__ ## TYPE ## _end), \
 		 #TYPE);
 
-	printk ("Freeing unused kernel memory:");
+	printk (KERN_INFO "Freeing unused kernel memory:");
 	FREESEC(init);
 	if (_machine != _MACH_Pmac)
 		FREESEC(pmac);
@@ -247,7 +247,7 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long 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));
@@ -515,7 +515,7 @@
 	}
 #endif /* CONFIG_HIGHMEM */
 
-        printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
+        printk(KERN_INFO "Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
 	       (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
 	       codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
 	       initpages<< (PAGE_SHIFT-10),
@@ -570,9 +570,6 @@
 	/* remove the RTAS pages from the available memory */
 	if (rtas_data)
 		mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
-	/* remove the sysmap pages from the available memory */
-	if (sysmap)
-		mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1);
 	/* Because of some uninorth weirdness, we need a page of
 	 * memory as high as possible (it must be outside of the
 	 * bus address seen as the AGP aperture). It will be used
@@ -588,6 +585,9 @@
 		agp_special_page = (unsigned long)__va(agp_special_page);
 	}
 #endif /* CONFIG_ALL_PPC */
+	/* remove the sysmap pages from the available memory */
+	if (sysmap)
+		mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1);
 }
 
 /* Mark some memory as reserved by removing it from phys_avail. */
@@ -596,23 +596,44 @@
 	mem_pieces_remove(&phys_avail, start, size, 1);
 }
 
-void flush_page_to_ram(struct page *page)
+/*
+ * This is called when a page has been modified by the kernel.
+ * It just marks the page as not i-cache clean.  We do the i-cache
+ * flush later when the page is given to a user process, if necessary.
+ */
+void flush_dcache_page(struct page *page)
 {
-	unsigned long vaddr = (unsigned long) kmap(page);
-	__flush_page_to_ram(vaddr);
-	kunmap(page);
+	clear_bit(PG_arch_1, &page->flags);
 }
 
-/*
- * set_pte stores a linux PTE into the linux page table.
- * On machines which use an MMU hash table we avoid changing the
- * _PAGE_HASHPTE bit.
- */
-void set_pte(pte_t *ptep, pte_t pte)
+void flush_icache_page(struct vm_area_struct *vma, struct page *page)
 {
-#if _PAGE_HASHPTE != 0
-	pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
-#else
-	*ptep = pte;
-#endif
+	if (page->mapping && !PageReserved(page)
+	    && !test_bit(PG_arch_1, &page->flags)) {
+		__flush_dcache_icache(kmap(page));
+		kunmap(page);
+		set_bit(PG_arch_1, &page->flags);
+	}
+}
+
+void clear_user_page(void *page, unsigned long vaddr)
+{
+	clear_page(page);
+	__flush_dcache_icache(page);
+}
+
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr)
+{
+	copy_page(vto, vfrom);
+	__flush_dcache_icache(vto);
+}
+
+void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+			     unsigned long addr, int len)
+{
+	unsigned long maddr;
+
+	maddr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
+	flush_icache_range(maddr, maddr + len);
+	kunmap(page);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/mm/pgtable.c linux/arch/ppc/mm/pgtable.c
--- linux.orig/arch/ppc/mm/pgtable.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/mm/pgtable.c	2002-07-20 01:08:27.000000000 +0000
@@ -275,17 +275,17 @@
 		f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
 #if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
 		/* Allows stub to set breakpoints everywhere */
-		f |= _PAGE_RW | _PAGE_DIRTY;
-#else
+		f |= _PAGE_WRENABLE;
+#else	/* !CONFIG_KGDB && !CONFIG_XMON */
 		if ((char *) v < _stext || (char *) v >= etext)
-			f |= _PAGE_RW | _PAGE_DIRTY;
+			f |= _PAGE_WRENABLE;
 #ifdef CONFIG_PPC_STD_MMU
 		else
 			/* On the powerpc (not all), no user access
 			   forces R/W kernel access */
 			f |= _PAGE_USER;
 #endif /* CONFIG_PPC_STD_MMU */
-#endif /* CONFIG_KGDB */
+#endif /* CONFIG_KGDB || CONFIG_XMON */
 		map_page(v, p, f);
 		v += PAGE_SIZE;
 		p += PAGE_SIZE;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/mm/ppc_mmu.c linux/arch/ppc/mm/ppc_mmu.c
--- linux.orig/arch/ppc/mm/ppc_mmu.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/mm/ppc_mmu.c	2002-07-20 01:08:26.000000000 +0000
@@ -163,7 +163,6 @@
 
 	extern unsigned int hash_page_patch_A[];
 	extern unsigned int hash_page_patch_B[], hash_page_patch_C[];
-	extern unsigned int hash_page[];
 	extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[];
 
 #ifdef CONFIG_PPC64BRIDGE
@@ -184,9 +183,15 @@
 #else /* CONFIG_PPC64BRIDGE */
 	unsigned int h;
 
-	if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0)
+	if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0) {
+		Hash_size = 0;
+		Hash_end = 0;
+		Hash = 0;
 		return;
+	}
+
 	if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
+
 	/*
 	 * Allow 64k of hash table for every 16MB of memory,
 	 * up to a maximum of 2MB.
@@ -252,18 +257,7 @@
 		flush_icache_range((unsigned long) &flush_hash_patch_A[0],
 				   (unsigned long) &flush_hash_patch_B[1]);
 	}
-	else {
-		Hash_end = 0;
-		/*
-		 * Put a blr (procedure return) instruction at the
-		 * start of hash_page, since we can still get DSI
-		 * exceptions on a 603.
-		 */
-		hash_page[0] = 0x4e800020;
-		flush_icache_range((unsigned long) &hash_page[0],
-				   (unsigned long) &hash_page[1]);
-	}
-
+	
 	if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/vmlinux.lds linux/arch/ppc/vmlinux.lds
--- linux.orig/arch/ppc/vmlinux.lds	2001-08-28 13:58:33.000000000 +0000
+++ linux/arch/ppc/vmlinux.lds	2002-07-20 01:08:37.000000000 +0000
@@ -33,6 +33,9 @@
     *(.text)
     *(.fixup)
     *(.got1)
+    __got2_start = .;
+    *(.got2)
+    __got2_end = .;
   }
   _etext = .;
   PROVIDE (etext = .);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc/xmon/start.c linux/arch/ppc/xmon/start.c
--- linux.orig/arch/ppc/xmon/start.c	2002-02-25 19:37:55.000000000 +0000
+++ linux/arch/ppc/xmon/start.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.start.c 1.18 12/01/01 20:09:07 benh
+ * BK Id: SCCS/s.start.c 1.20 04/09/02 21:01:58 paulus
  */
 /*
  * Copyright (C) 1996 Paul Mackerras.
@@ -67,8 +67,6 @@
 		unsigned long addr;
 #ifdef CONFIG_BOOTX_TEXT
 		if (!machine_is_compatible("iMac")) {
-			extern boot_infos_t *disp_bi;
-
 			/* see if there is a keyboard in the device tree
 			   with a parent of type "adb" */
 			for (np = find_devices("keyboard"); np; np = np->next)
@@ -79,11 +77,11 @@
 			/* needs to be hacked if xmon_printk is to be used
 			   from within find_via_pmu() */
 #ifdef CONFIG_ADB_PMU
-			if (np != NULL && disp_bi && find_via_pmu())
+			if (np != NULL && boot_text_mapped && find_via_pmu())
 				use_screen = 1;
 #endif
 #ifdef CONFIG_ADB_CUDA
-			if (np != NULL && disp_bi && find_via_cuda())
+			if (np != NULL && boot_text_mapped && find_via_cuda())
 				use_screen = 1;
 #endif
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/Makefile linux/arch/ppc64/Makefile
--- linux.orig/arch/ppc64/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,80 @@
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Linus Torvalds
+# Changes for PPC by Gary Thomas
+# Rewritten by Cort Dougan and Paul Mackerras
+# Adjusted for PPC64 by Tom Gall
+#
+
+KERNELLOAD	=0xc000000000000000
+
+ifeq ($(shell uname -m),ppc64)
+CHECKS		= checks
+endif
+
+LINKFLAGS	= -T arch/ppc64/vmlinux.lds -Bstatic \
+		-e $(KERNELLOAD) -Ttext $(KERNELLOAD)
+CFLAGS		:= $(CFLAGS) -fsigned-char -msoft-float -pipe \
+		-Wno-uninitialized -mminimal-toc -fno-builtin
+CPP		= $(CC) -E $(CFLAGS)
+
+
+HEAD := arch/ppc64/kernel/head.o
+
+ARCH_SUBDIRS = arch/ppc64/kernel arch/ppc64/mm arch/ppc64/lib
+SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS)
+ARCHIVES := arch/ppc64/kernel/kernel.o arch/ppc64/mm/mm.o arch/ppc64/lib/lib.o $(ARCHIVES)
+CORE_FILES := arch/ppc64/kernel/kernel.o arch/ppc64/mm/mm.o arch/ppc64/lib/lib.o $(CORE_FILES)
+
+ifdef CONFIG_XMON
+SUBDIRS += arch/ppc64/xmon
+CORE_FILES += arch/ppc64/xmon/x.o
+endif
+ifdef CONFIG_KDB
+SUBDIRS += arch/ppc64/kdb
+CORE_FILES += arch/ppc64/kdb/kdba.o
+endif
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+checks:
+	@$(MAKE) -C arch/$(ARCH)/kernel checks
+
+ifdef CONFIG_PPC_PSERIES
+BOOT_TARGETS = zImage znetboot.initrd zImage.initrd
+endif
+
+ifdef CONFIG_PPC_ISERIES
+BOOT_TARGETS = vmlinux.sminitrd vmlinux.initrd vmlinux.sm
+endif
+
+$(BOOT_TARGETS): vmlinux
+	@$(MAKEBOOT) $@
+
+znetboot: vmlinux
+ifdef CONFIG_SMP
+	cp -f vmlinux /tftpboot/vmlinux.smp
+else
+	cp -f vmlinux /tftpboot/vmlinux
+endif
+	@$(MAKEBOOT) $@
+
+%_config: arch/ppc64/configs/%_defconfig
+	rm -f .config arch/ppc64/defconfig
+	cp -f arch/ppc64/configs/$(@:config=defconfig) arch/ppc64/defconfig
+
+archclean:
+	rm -f arch/ppc64/kernel/{ppc_defs.h,checks,mk_defs.s,mk_defs_out.c,mk_defs_tpl}
+	@$(MAKEBOOT) clean
+
+archmrproper:
+
+archdep:
+	$(MAKEBOOT) fastdep
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/Makefile linux/arch/ppc64/boot/Makefile
--- linux.orig/arch/ppc64/boot/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/Makefile	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,125 @@
+# Makefile for making ELF bootable images for booting on CHRP
+# using Open Firmware.
+#
+# Geert Uytterhoeven	September 1997
+#
+# Based on coffboot by Paul Mackerras
+# Simplified for ppc64 by Todd Inglett
+#
+# NOTE:	this code is built for 32 bit in ELF32 format even though
+#	it packages a 64 bit kernel.  We do this to simplify the
+#	bootloader and increase compatibility with OpenFirmware.
+#
+#	To this end we need to define BOOTCC, etc, as the tools
+#	needed to build the 32 bit image.  These are normally HOSTCC,
+#	but may be a third compiler if, for example, you are cross
+#	compiling from an intel box.  Once the 64bit ppc gcc is
+#	stable it will probably simply be a compiler switch to
+#	compile for 32bit mode.
+#	To make it easier to setup a cross compiler,
+#	CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE
+#	in the toplevel makefile.
+
+CROSS32_COMPILE =
+#CROSS32_COMPILE = /usr/local/ppc/bin/powerpc-linux-
+
+BOOTCC = $(CROSS32_COMPILE)gcc
+BOOTCFLAGS = $(HOSTCFLAGS) -I$(HPATH)
+BOOTLD = $(CROSS32_COMPILE)ld
+BOOTAS = $(CROSS32_COMPILE)as
+BOOTAFLAGS = -D__ASSEMBLY__ $(HOSTCFLAGS) -I$(HPATH)
+
+OBJCOPYFLAGS = contents,alloc,load,readonly,data
+
+.c.o:
+	$(BOOTCC) $(BOOTCFLAGS) -c -o $*.o $<
+.S.o:
+	$(BOOTCC) $(BOOTAFLAGS) -traditional -c -o $*.o $<
+
+CFLAGS	= $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS
+LD_ARGS = -Ttext 0x00400000 -e _start
+
+OBJS = crt0.o string.o prom.o zImage.o zlib.o imagesize.o
+#LIBS = $(TOPDIR)/lib/lib.a
+LIBS =
+
+ifeq ($(CONFIG_SMP),y)
+TFTPIMAGE=/tftpboot/zImage.chrp.smp
+else
+TFTPIMAGE=/tftpboot/zImage.chrp
+endif
+
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+all:	vmlinux.sm
+else
+all:	$(TOPDIR)/zImage
+endif
+
+
+znetboot: zImage
+	cp zImage $(TFTPIMAGE)
+
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+
+addSystemMap: addSystemMap.c
+	$(HOSTCC) $(HOSTCFLAGS) -o addSystemMap addSystemMap.c
+
+vmlinux.sm: $(TOPDIR)/vmlinux addSystemMap
+	./addSystemMap $(TOPDIR)/System.map $(TOPDIR)/vmlinux vmlinux.sm
+
+
+addRamDisk: addRamDisk.c
+	$(HOSTCC) $(HOSTCFLAGS) -o addRamDisk addRamDisk.c
+
+vmlinux.initrd: $(TOPDIR)/vmlinux addRamDisk ramdisk.image.gz $(TOPDIR)/System.map
+	./addRamDisk ramdisk.image.gz $(TOPDIR)/System.map $(TOPDIR)/vmlinux vmlinux.initrd
+
+vmlinux.sminitrd: vmlinux.sm addRamDisk ramdisk.image.gz $(TOPDIR)/System.map
+	./addRamDisk ramdisk.image.gz $(TOPDIR)/System.map vmlinux.sm vmlinux.sminitrd
+
+endif
+
+
+znetboot.initrd: zImage.initrd
+	cp zImage.initrd $(TFTPIMAGE)
+
+addnote: addnote.c
+	$(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c
+
+
+imagesize.c: $(TOPDIR)/vmlinux
+	ls -l $(TOPDIR)/vmlinux | awk '{printf "/* generated -- do not edit! */\nunsigned long vmlinux_filesize = %d;\n", $$5}' > imagesize.c
+	$(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | tail -1 | awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> imagesize.c
+
+vmlinux .config System.map: % : $(TOPDIR)/%
+	gzip -cvf9 $(TOPDIR)/$@ > kernel-$@.gz
+	$(OBJCOPY) zImage.o \
+		--add-section=.kernel:$@=kernel-$@.gz \
+		--set-section-flags=.kernel:$@=$(OBJCOPYFLAGS)
+
+initrd: ramdisk.image.gz
+	$(OBJCOPY) zImage.o \
+		--add-section=.kernel:$@=ramdisk.image.gz \
+		--set-section-flags=.kernel:$@=$(OBJCOPYFLAGS)
+
+zImage: $(OBJS) addnote vmlinux .config System.map
+	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS)
+	./addnote $@
+
+zImage.initrd: $(OBJS) addnote vmlinux .config System.map initrd
+	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS)
+	./addnote $@
+
+clean:
+	rm -f add{note,RamDisk,SystemMap} $(OBJS) initrd.o \
+		vmlinux.{sm,initrd} zImage{,.initrd} imagesize.c \
+		kernel-{vmlinux,.config,System.map}.gz
+
+fastdep:
+	$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
+
+dep:
+	$(CPP) $(CPPFLAGS) -M *.S *.c > .depend
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/addRamDisk.c linux/arch/ppc64/boot/addRamDisk.c
--- linux.orig/arch/ppc64/boot/addRamDisk.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/addRamDisk.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,301 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#define ElfHeaderSize  (64 * 1024)
+#define ElfPages  (ElfHeaderSize / 4096)
+#define KERNELBASE (0xc000000000000000)
+
+void get4k(FILE *file, char *buf )
+{
+	unsigned j;
+	unsigned num = fread(buf, 1, 4096, file);
+	for ( j=num; j<4096; ++j )
+		buf[j] = 0;
+}
+
+void put4k(FILE *file, char *buf )
+{
+	fwrite(buf, 1, 4096, file);
+}
+
+void death(const char *msg, FILE *fdesc, const char *fname) 
+{
+	printf(msg);
+	fclose(fdesc);
+	unlink(fname);
+	exit(1);
+}
+
+int main(int argc, char **argv)
+{
+	char inbuf[4096];
+	FILE *ramDisk = NULL;
+	FILE *sysmap = NULL;
+	FILE *inputVmlinux = NULL;
+	FILE *outputVmlinux = NULL;
+  
+	unsigned i = 0;
+	unsigned long ramFileLen = 0;
+	unsigned long ramLen = 0;
+	unsigned long roundR = 0;
+  
+	unsigned long sysmapFileLen = 0;
+	unsigned long sysmapLen = 0;
+	unsigned long sysmapPages = 0;
+	char* ptr_end = NULL; 
+	unsigned long offset_end = 0;
+
+	unsigned long kernelLen = 0;
+	unsigned long actualKernelLen = 0;
+	unsigned long round = 0;
+	unsigned long roundedKernelLen = 0;
+	unsigned long ramStartOffs = 0;
+	unsigned long ramPages = 0;
+	unsigned long roundedKernelPages = 0;
+	unsigned long hvReleaseData = 0;
+	u_int32_t eyeCatcher = 0xc8a5d9c4;
+	unsigned long naca = 0;
+	unsigned long xRamDisk = 0;
+	unsigned long xRamDiskSize = 0;
+	long padPages = 0;
+  
+  
+	if (argc < 2) {
+		printf("Name of RAM disk file missing.\n");
+		exit(1);
+	}
+
+	if (argc < 3) {
+		printf("Name of System Map input file is missing.\n");
+		exit(1);
+	}
+  
+	if (argc < 4) {
+		printf("Name of vmlinux file missing.\n");
+		exit(1);
+	}
+
+	if (argc < 5) {
+		printf("Name of vmlinux output file missing.\n");
+		exit(1);
+	}
+
+
+	ramDisk = fopen(argv[1], "r");
+	if ( ! ramDisk ) {
+		printf("RAM disk file \"%s\" failed to open.\n", argv[1]);
+		exit(1);
+	}
+
+	sysmap = fopen(argv[2], "r");
+	if ( ! sysmap ) {
+		printf("System Map file \"%s\" failed to open.\n", argv[2]);
+		exit(1);
+	}
+  
+	inputVmlinux = fopen(argv[3], "r");
+	if ( ! inputVmlinux ) {
+		printf("vmlinux file \"%s\" failed to open.\n", argv[3]);
+		exit(1);
+	}
+  
+	outputVmlinux = fopen(argv[4], "w+");
+	if ( ! outputVmlinux ) {
+		printf("output vmlinux file \"%s\" failed to open.\n", argv[4]);
+		exit(1);
+	}
+  
+  
+  
+	/* Input Vmlinux file */
+	fseek(inputVmlinux, 0, SEEK_END);
+	kernelLen = ftell(inputVmlinux);
+	fseek(inputVmlinux, 0, SEEK_SET);
+	printf("kernel file size = %d\n", kernelLen);
+	if ( kernelLen == 0 ) {
+		printf("You must have a linux kernel specified as argv[3]\n");
+		exit(1);
+	}
+
+	actualKernelLen = kernelLen - ElfHeaderSize;
+
+	printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen);
+
+	round = actualKernelLen % 4096;
+	roundedKernelLen = actualKernelLen;
+	if ( round )
+		roundedKernelLen += (4096 - round);
+	printf("Vmlinux length rounded up to a 4k multiple = %ld/0x%lx \n", roundedKernelLen, roundedKernelLen);
+	roundedKernelPages = roundedKernelLen / 4096;
+	printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages);
+
+
+
+	/* Input System Map file */
+	/* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */
+	fseek(sysmap, 0, SEEK_END);
+	sysmapFileLen = ftell(sysmap);
+	fseek(sysmap, 0, SEEK_SET);
+	printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen);
+
+	sysmapLen = sysmapFileLen;
+
+	roundR = 4096 - (sysmapLen % 4096);
+	if (roundR) {
+		printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
+		sysmapLen += roundR;
+	}
+	printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen);
+  
+	/* Process the Sysmap file to determine where _end is */
+	sysmapPages = sysmapLen / 4096;
+	for (i=0; i<sysmapPages; ++i) {
+		get4k(sysmap, inbuf);
+	}
+	/* search for _end in the last page of the system map */
+	ptr_end = strstr(inbuf, " _end");
+	if (!ptr_end) {
+		printf("Unable to find _end in the sysmap file \n");
+		printf("inbuf: \n");
+		printf("%s \n", inbuf);
+		exit(1);
+	}
+	printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
+	/* convert address of _end in system map to hex offset. */
+	offset_end = (unsigned int)strtol(ptr_end-10, NULL, 16);
+	/* calc how many pages we need to insert between the vmlinux and the start of the ram disk */
+	padPages = offset_end/4096 - roundedKernelPages;
+
+	/* Check and see if the vmlinux is already larger than _end in System.map */
+	if (padPages < 0) {
+		/* vmlinux is larger than _end - adjust the offset to the start of the embedded ram disk */ 
+		offset_end = roundedKernelLen;
+		printf("vmlinux is larger than _end indicates it needs to be - offset_end = %lx \n", offset_end);
+		padPages = 0;
+		printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages);
+	}
+	else {
+		/* _end is larger than vmlinux - use the offset to _end that we calculated from the system map */
+		printf("vmlinux is smaller than _end indicates is needed - offset_end = %lx \n", offset_end);
+		printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages);
+	}
+
+
+
+	/* Input Ram Disk file */
+	// Set the offset that the ram disk will be started at.
+	ramStartOffs = offset_end;  /* determined from the input vmlinux file and the system map */
+	printf("Ram Disk will start at offset = 0x%lx \n", ramStartOffs);
+  
+	fseek(ramDisk, 0, SEEK_END);
+	ramFileLen = ftell(ramDisk);
+	fseek(ramDisk, 0, SEEK_SET);
+	printf("%s file size = %ld/0x%lx \n", argv[1], ramFileLen, ramFileLen);
+
+	ramLen = ramFileLen;
+
+	roundR = 4096 - (ramLen % 4096);
+	if ( roundR ) {
+		printf("Rounding RAM disk file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
+		ramLen += roundR;
+	}
+
+	printf("Rounded RAM disk size is %ld/0x%lx \n", ramLen, ramLen);
+	ramPages = ramLen / 4096;
+	printf("RAM disk pages to copy = %ld/0x%lx\n", ramPages, ramPages);
+
+
+
+  // Copy 64K ELF header
+	for (i=0; i<(ElfPages); ++i) {
+		get4k( inputVmlinux, inbuf );
+		put4k( outputVmlinux, inbuf );
+	}
+
+	/* Copy the vmlinux (as full pages). */
+	fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
+	for ( i=0; i<roundedKernelPages; ++i ) {
+		get4k( inputVmlinux, inbuf );
+		put4k( outputVmlinux, inbuf );
+	}
+  
+	/* Insert pad pages (if appropriate) that are needed between */
+	/* | the end of the vmlinux and the ram disk. */
+	for (i=0; i<padPages; ++i) {
+		memset(inbuf, 0, 4096);
+		put4k(outputVmlinux, inbuf);
+	}
+
+	/* Copy the ram disk (as full pages). */
+	for ( i=0; i<ramPages; ++i ) {
+		get4k( ramDisk, inbuf );
+		put4k( outputVmlinux, inbuf );
+	}
+
+	/* Close the input files */
+	fclose(ramDisk);
+	fclose(inputVmlinux);
+	/* And flush the written output file */
+	fflush(outputVmlinux);
+
+
+
+	/* Fixup the new vmlinux to contain the ram disk starting offset (xRamDisk) and the ram disk size (xRamDiskSize) */
+	/* fseek to the hvReleaseData pointer */
+	fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET);
+	if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) {
+		death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[4]);
+	}
+	hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */
+	printf("hvReleaseData is at %08x\n", hvReleaseData);
+
+	/* fseek to the hvReleaseData */
+	fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET);
+	if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) {
+		death("Could not read hvReleaseData\n", outputVmlinux, argv[4]);
+	}
+	/* Check hvReleaseData sanity */
+	if (memcmp(inbuf, &eyeCatcher, 4) != 0) {
+		death("hvReleaseData is invalid\n", outputVmlinux, argv[4]);
+	}
+	/* Get the naca pointer */
+	naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE;
+	printf("Naca is at offset 0x%lx \n", naca);
+
+	/* fseek to the naca */
+	fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
+	if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) {
+		death("Could not read naca\n", outputVmlinux, argv[4]);
+	}
+	xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c]));
+	xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14]));
+	/* Make sure a RAM disk isn't already present */
+	if ((xRamDisk != 0) || (xRamDiskSize != 0)) {
+		death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[4]);
+	}
+	/* Fill in the values */
+	*((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs);
+	*((u_int32_t *) &inbuf[0x14]) = htonl(ramPages);
+
+	/* Write out the new naca */
+	fflush(outputVmlinux);
+	fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
+	if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) {
+		death("Could not write naca\n", outputVmlinux, argv[4]);
+	}
+	printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08x\n",
+	       ramPages, ramStartOffs);
+
+	/* Done */
+	fclose(outputVmlinux);
+	/* Set permission to executable */
+	chmod(argv[4], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+
+	return 0;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/addSystemMap.c linux/arch/ppc64/boot/addSystemMap.c
--- linux.orig/arch/ppc64/boot/addSystemMap.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/addSystemMap.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,250 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <byteswap.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+void xlate( char * inb, char * trb, unsigned len )
+{
+	unsigned i;
+	for (  i=0; i<len; ++i )
+	{
+		char c = *inb++;
+		char c1 = c >> 4;
+		char c2 = c & 0xf;
+		if ( c1 > 9 )
+			c1 = c1 + 'A' - 10;
+		else
+			c1 = c1 + '0';
+		if ( c2 > 9 )
+			c2 = c2 + 'A' - 10;
+		else
+			c2 = c2 + '0';
+		*trb++ = c1;
+		*trb++ = c2;
+	}
+	*trb = 0;
+}
+
+#define ElfHeaderSize  (64 * 1024)
+#define ElfPages  (ElfHeaderSize / 4096)
+
+void get4k( /*istream *inf*/FILE *file, char *buf )
+{
+	unsigned j;
+	unsigned num = fread(buf, 1, 4096, file);
+	for ( j=num; j<4096; ++j )
+		buf[j] = 0;
+}
+
+void put4k( /*ostream *outf*/FILE *file, char *buf )
+{
+	fwrite(buf, 1, 4096, file);
+}
+
+int main(int argc, char **argv)
+{
+	char inbuf[4096];
+	FILE *sysmap = NULL;
+	char* ptr_end = NULL; 
+	FILE *inputVmlinux = NULL;
+	FILE *outputVmlinux = NULL;
+	long i = 0;
+	unsigned long sysmapFileLen = 0;
+	unsigned long sysmapLen = 0;
+	unsigned long roundR = 0;
+	unsigned long kernelLen = 0;
+	unsigned long actualKernelLen = 0;
+	unsigned long round = 0;
+	unsigned long roundedKernelLen = 0;
+	unsigned long sysmapStartOffs = 0;
+	unsigned long sysmapPages = 0;
+	unsigned long roundedKernelPages = 0;
+	long padPages = 0;
+	if ( argc < 2 )
+	{
+		printf("Name of System Map file missing.\n");
+		exit(1);
+	}
+
+	if ( argc < 3 )
+	{
+		printf("Name of vmlinux file missing.\n");
+		exit(1);
+	}
+
+	if ( argc < 4 )
+	{
+		printf("Name of vmlinux output file missing.\n");
+		exit(1);
+	}
+
+	sysmap = fopen(argv[1], "r");
+	if ( ! sysmap )
+	{
+		printf("System Map file \"%s\" failed to open.\n", argv[1]);
+		exit(1);
+	}
+	inputVmlinux = fopen(argv[2], "r");
+	if ( ! inputVmlinux )
+	{
+		printf("vmlinux file \"%s\" failed to open.\n", argv[2]);
+		exit(1);
+	}
+	outputVmlinux = fopen(argv[3], "w");
+	if ( ! outputVmlinux )
+	{
+		printf("output vmlinux file \"%s\" failed to open.\n", argv[3]);
+		exit(1);
+	}
+
+
+  
+	fseek(inputVmlinux, 0, SEEK_END);
+	kernelLen = ftell(inputVmlinux);
+	fseek(inputVmlinux, 0, SEEK_SET);
+	printf("kernel file size = %ld\n", kernelLen);
+	if ( kernelLen == 0 )
+	{
+		printf("You must have a linux kernel specified as argv[2]\n");
+		exit(1);
+	}
+
+
+	actualKernelLen = kernelLen - ElfHeaderSize;
+
+	printf("actual kernel length (minus ELF header) = %ld/%lxx \n", actualKernelLen, actualKernelLen);
+
+	round = actualKernelLen % 4096;
+	roundedKernelLen = actualKernelLen;
+	if ( round )
+		roundedKernelLen += (4096 - round);
+
+	printf("Kernel length rounded up to a 4k multiple = %ld/%lxx \n", roundedKernelLen, roundedKernelLen);
+	roundedKernelPages = roundedKernelLen / 4096;
+	printf("Kernel pages to copy = %ld/%lxx\n", roundedKernelPages, roundedKernelPages);
+
+
+
+	/* Sysmap file */
+	fseek(sysmap, 0, SEEK_END);
+	sysmapFileLen = ftell(sysmap);
+	fseek(sysmap, 0, SEEK_SET);
+	printf("%s file size = %ld\n", argv[1], sysmapFileLen);
+
+	sysmapLen = sysmapFileLen;
+
+	roundR = 4096 - (sysmapLen % 4096);
+	if (roundR)
+	{
+		printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR);
+		sysmapLen += roundR;
+	}
+	printf("Rounded System Map size is %ld\n", sysmapLen);
+  
+  /* Process the Sysmap file to determine the true end of the kernel */
+	sysmapPages = sysmapLen / 4096;
+	printf("System map pages to copy = %ld\n", sysmapPages);
+	for (i=0; i<sysmapPages; ++i)
+	{
+		get4k(sysmap, inbuf);
+	}
+	/* search for _end in the last page of the system map */
+	ptr_end = strstr(inbuf, " _end");
+	if (!ptr_end)
+	{
+		printf("Unable to find _end in the sysmap file \n");
+		printf("inbuf: \n");
+		printf("%s \n", inbuf);
+		exit(1);
+	}
+	printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
+	sysmapStartOffs = (unsigned int)strtol(ptr_end-10, NULL, 16);
+	/* calc how many pages we need to insert between the vmlinux and the start of the sysmap */
+	padPages = sysmapStartOffs/4096 - roundedKernelPages;
+
+	/* Check and see if the vmlinux is larger than _end in System.map */
+	if (padPages < 0)
+	{ /* vmlinux is larger than _end - adjust the offset to start the embedded system map */ 
+		sysmapStartOffs = roundedKernelLen;
+		printf("vmlinux is larger than _end indicates it needs to be - sysmapStartOffs = %lx \n", sysmapStartOffs);
+		padPages = 0;
+		printf("will insert %lx pages between the vmlinux and the start of the sysmap \n", padPages);
+	}
+	else
+	{ /* _end is larger than vmlinux - use the sysmapStartOffs we calculated from the system map */
+		printf("vmlinux is smaller than _end indicates is needed - sysmapStartOffs = %lx \n", sysmapStartOffs);
+		printf("will insert %lx pages between the vmlinux and the start of the sysmap \n", padPages);
+	}
+
+
+
+
+	/* Copy 64K ELF header */
+	for (i=0; i<(ElfPages); ++i)
+	{
+		get4k( inputVmlinux, inbuf );
+		put4k( outputVmlinux, inbuf );
+	}
+
+  
+	/* Copy the vmlinux (as full pages). */
+	fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
+	for ( i=0; i<roundedKernelPages; ++i )
+	{
+		get4k( inputVmlinux, inbuf );
+    
+		/* Set the offsets (of the start and end) of the embedded sysmap so it is set in the vmlinux.sm */
+		if ( i == 0 )
+		{
+			unsigned long * p;
+			printf("Storing embedded_sysmap_start at 0x3c\n");
+			p = (unsigned long *)(inbuf + 0x3c);
+
+#if (BYTE_ORDER == __BIG_ENDIAN)
+			*p = sysmapStartOffs;
+#else
+			*p = bswap_32(sysmapStartOffs);
+#endif
+
+			printf("Storing embedded_sysmap_end at 0x44\n");
+			p = (unsigned long *)(inbuf + 0x44);
+
+#if (BYTE_ORDER == __BIG_ENDIAN)
+			*p = sysmapStartOffs + sysmapFileLen;
+#else
+			*p = bswap_32(sysmapStartOffs + sysmapFileLen);
+#endif
+		}
+    
+		put4k( outputVmlinux, inbuf );
+	}
+  
+  
+	/* Insert any pad pages between the end of the vmlinux and where the system map needs to be. */
+	for (i=0; i<padPages; ++i)
+	{
+		memset(inbuf, 0, 4096);
+		put4k(outputVmlinux, inbuf);
+	}
+
+
+	/* Copy the system map (as full pages). */
+	fseek(sysmap, 0, SEEK_SET);  /* start reading from begining of the system map */
+	for ( i=0; i<sysmapPages; ++i )
+	{
+		get4k( sysmap, inbuf );
+		put4k( outputVmlinux, inbuf );
+	}
+
+
+	fclose(sysmap);
+	fclose(inputVmlinux);
+	fclose(outputVmlinux);
+	/* Set permission to executable */
+	chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+
+	return 0;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/addnote.c linux/arch/ppc64/boot/addnote.c
--- linux.orig/arch/ppc64/boot/addnote.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/addnote.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,164 @@
+/*
+ * Program to hack in a PT_NOTE program header entry in an ELF file.
+ * This is needed for OF on RS/6000s to load an image correctly.
+ * Note that OF needs a program header entry for the note, not an
+ * ELF section.
+ *
+ * Copyright 2000 Paul Mackerras.
+ *
+ * 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.
+ *
+ * Usage: addnote zImage
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+char arch[] = "PowerPC";
+
+#define N_DESCR	6
+unsigned int descr[N_DESCR] = {
+	0xffffffff,		/* real-mode = true */
+	0x00c00000,		/* real-base, i.e. where we expect OF to be */
+	0xffffffff,		/* real-size */
+	0xffffffff,		/* virt-base */
+	0xffffffff,		/* virt-size */
+	0x4000,			/* load-base */
+};
+
+unsigned char buf[512];
+
+#define GET_16BE(off)	((buf[off] << 8) + (buf[(off)+1]))
+#define GET_32BE(off)	((GET_16BE(off) << 16) + GET_16BE((off)+2))
+
+#define PUT_16BE(off, v)	(buf[off] = ((v) >> 8) & 0xff, \
+				 buf[(off) + 1] = (v) & 0xff)
+#define PUT_32BE(off, v)	(PUT_16BE((off), (v) >> 16), \
+				 PUT_16BE((off) + 2, (v)))
+
+/* Structure of an ELF file */
+#define E_IDENT		0	/* ELF header */
+#define	E_PHOFF		28
+#define E_PHENTSIZE	42
+#define E_PHNUM		44
+#define E_HSIZE		52	/* size of ELF header */
+
+#define EI_MAGIC	0	/* offsets in E_IDENT area */
+#define EI_CLASS	4
+#define EI_DATA		5
+
+#define PH_TYPE		0	/* ELF program header */
+#define PH_OFFSET	4
+#define PH_FILESZ	16
+#define PH_HSIZE	32	/* size of program header */
+
+#define PT_NOTE		4	/* Program header type = note */
+
+#define ELFCLASS32	1
+#define ELFDATA2MSB	2
+
+unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
+
+int
+main(int ac, char **av)
+{
+	int fd, n, i;
+	int ph, ps, np;
+	int nnote, ns;
+
+	if (ac != 2) {
+		fprintf(stderr, "Usage: %s elf-file\n", av[0]);
+		exit(1);
+	}
+	fd = open(av[1], O_RDWR);
+	if (fd < 0) {
+		perror(av[1]);
+		exit(1);
+	}
+
+	nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
+
+	n = read(fd, buf, sizeof(buf));
+	if (n < 0) {
+		perror("read");
+		exit(1);
+	}
+
+	if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
+		goto notelf;
+
+	if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
+	    || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
+		fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
+			av[1]);
+		exit(1);
+	}
+
+	ph = GET_32BE(E_PHOFF);
+	ps = GET_16BE(E_PHENTSIZE);
+	np = GET_16BE(E_PHNUM);
+	if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
+		goto notelf;
+	if (ph + (np + 1) * ps + nnote > n)
+		goto nospace;
+
+	for (i = 0; i < np; ++i) {
+		if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
+			fprintf(stderr, "%s already has a note entry\n",
+				av[1]);
+			exit(0);
+		}
+		ph += ps;
+	}
+
+	/* XXX check that the area we want to use is all zeroes */
+	for (i = 0; i < ps + nnote; ++i)
+		if (buf[ph + i] != 0)
+			goto nospace;
+
+	/* fill in the program header entry */
+	ns = ph + ps;
+	PUT_32BE(ph + PH_TYPE, PT_NOTE);
+	PUT_32BE(ph + PH_OFFSET, ns);
+	PUT_32BE(ph + PH_FILESZ, nnote);
+
+	/* fill in the note area we point to */
+	/* XXX we should probably make this a proper section */
+	PUT_32BE(ns, strlen(arch) + 1);
+	PUT_32BE(ns + 4, N_DESCR * 4);
+	PUT_32BE(ns + 8, 0x1275);
+	strcpy(&buf[ns + 12], arch);
+	ns += 12 + strlen(arch) + 1;
+	for (i = 0; i < N_DESCR; ++i)
+		PUT_32BE(ns + i * 4, descr[i]);
+
+	/* Update the number of program headers */
+	PUT_16BE(E_PHNUM, np + 1);
+
+	/* write back */
+	lseek(fd, (long) 0, SEEK_SET);
+	i = write(fd, buf, n);
+	if (i < 0) {
+		perror("write");
+		exit(1);
+	}
+	if (i < n) {
+		fprintf(stderr, "%s: write truncated\n", av[1]);
+		exit(1);
+	}
+
+	exit(0);
+
+ notelf:
+	fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
+	exit(1);
+
+ nospace:
+	fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
+		av[0]);
+	exit(1);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/crt0.S linux/arch/ppc64/boot/crt0.S
--- linux.orig/arch/ppc64/boot/crt0.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/crt0.S	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ *
+ * NOTE: this code runs in 32 bit mode and is packaged as ELF32.
+ */
+
+#include <asm/ppc_asm.tmpl>
+
+	.text
+	.globl	_start
+_start:
+	lis	r9,_start@h
+	lis	r8,_etext@ha
+	addi	r8,r8,_etext@l
+1:	dcbf	r0,r9
+	icbi	r0,r9
+	addi	r9,r9,0x20
+	cmplwi	0,r9,8
+	blt	1b
+	sync
+	isync
+
+	## Clear out the BSS as per ANSI C requirements
+
+	lis	r7,_end@ha
+	addi    r7,r7,_end@l		# r7 = &_end 
+	lis	r8,__bss_start@ha	# 
+	addi    r8,r8,__bss_start@l	# r8 = &_bss_start
+
+	## Determine how large an area, in number of words, to clear
+
+	subf	r7,r8,r7		# r7 = &_end - &_bss_start + 1 
+	addi	r7,r7,3			# r7 += 3 
+	srwi.	r7,r7,2			# r7 = size in words.
+	beq	3f			# If the size is zero, don't bother
+	addi	r8,r8,-4		# r8 -= 4 
+	mtctr	r7			# SPRN_CTR = number of words to clear
+	li	r0,0			# r0 = 0
+2:	stwu	r0,4(r8)		# Clear out a word
+	bdnz	2b			# Keep clearing until done
+3:
+	b	start
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/mknote.c linux/arch/ppc64/boot/mknote.c
--- linux.orig/arch/ppc64/boot/mknote.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/mknote.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) Cort Dougan 1999.
+ *
+ * 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.
+ *
+ * Generate a note section as per the CHRP specification.
+ *
+ */
+
+#include <stdio.h>
+
+#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
+
+int main(void)
+{
+/* header */
+	/* namesz */
+	PL(strlen("PowerPC")+1);
+	/* descrsz */
+	PL(6*4);
+	/* type */
+	PL(0x1275);
+	/* name */
+	printf("PowerPC"); printf("%c", 0);
+	
+/* descriptor */
+	/* real-mode */
+	PL(0xffffffff);
+	/* real-base */
+	PL(0x00c00000);
+	/* real-size */
+	PL(0xffffffff);
+	/* virt-base */
+	PL(0xffffffff);
+	/* virt-size */
+	PL(0xffffffff);
+	/* load-base */
+	PL(0x4000);
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/ppc32-types.h linux/arch/ppc64/boot/ppc32-types.h
--- linux.orig/arch/ppc64/boot/ppc32-types.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/ppc32-types.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,30 @@
+#ifndef _PPC64_TYPES_H
+#define _PPC64_TYPES_H
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+#endif /* _PPC64_TYPES_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/prom.c linux/arch/ppc64/boot/prom.c
--- linux.orig/arch/ppc64/boot/prom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/prom.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+
+#include <asm/div64.h>
+
+int (*prom)(void *);
+
+void *chosen_handle;
+void *stdin;
+void *stdout;
+void *stderr;
+
+void exit(void);
+void *finddevice(const char *name);
+int getprop(void *phandle, const char *name, void *buf, int buflen);
+void chrpboot(int a1, int a2, void *prom);	/* in main.c */
+
+void printk(char *fmt, ...);
+
+int
+write(void *handle, void *ptr, int nb)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		void *ihandle;
+		void *addr;
+		int len;
+		int actual;
+	} args;
+
+	args.service = "write";
+	args.nargs = 3;
+	args.nret = 1;
+	args.ihandle = handle;
+	args.addr = ptr;
+	args.len = nb;
+	args.actual = -1;
+	(*prom)(&args);
+	return args.actual;
+}
+
+int
+read(void *handle, void *ptr, int nb)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		void *ihandle;
+		void *addr;
+		int len;
+		int actual;
+	} args;
+
+	args.service = "read";
+	args.nargs = 3;
+	args.nret = 1;
+	args.ihandle = handle;
+	args.addr = ptr;
+	args.len = nb;
+	args.actual = -1;
+	(*prom)(&args);
+	return args.actual;
+}
+
+void
+exit()
+{
+	struct prom_args {
+		char *service;
+	} args;
+
+	for (;;) {
+		args.service = "exit";
+		(*prom)(&args);
+	}
+}
+
+void
+pause(void)
+{
+	struct prom_args {
+		char *service;
+	} args;
+
+	args.service = "enter";
+	(*prom)(&args);
+}
+
+void *
+finddevice(const char *name)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		const char *devspec;
+		void *phandle;
+	} args;
+
+	args.service = "finddevice";
+	args.nargs = 1;
+	args.nret = 1;
+	args.devspec = name;
+	args.phandle = (void *) -1;
+	(*prom)(&args);
+	return args.phandle;
+}
+
+void *
+claim(unsigned long virt, unsigned long size, unsigned long align)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		unsigned int virt;
+		unsigned int size;
+		unsigned int align;
+		void *ret;
+	} args;
+
+	args.service = "claim";
+	args.nargs = 3;
+	args.nret = 1;
+	args.virt = virt;
+	args.size = size;
+	args.align = align;
+	(*prom)(&args);
+	return args.ret;
+}
+
+int
+getprop(void *phandle, const char *name, void *buf, int buflen)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		void *phandle;
+		const char *name;
+		void *buf;
+		int buflen;
+		int size;
+	} args;
+
+	args.service = "getprop";
+	args.nargs = 4;
+	args.nret = 1;
+	args.phandle = phandle;
+	args.name = name;
+	args.buf = buf;
+	args.buflen = buflen;
+	args.size = -1;
+	(*prom)(&args);
+	return args.size;
+}
+
+int
+putc(int c, void *f)
+{
+	char ch = c;
+
+	if (c == '\n')
+		putc('\r', f);
+	return write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+putchar(int c)
+{
+	return putc(c, stdout);
+}
+
+int
+fputs(char *str, void *f)
+{
+	int n = strlen(str);
+
+	return write(f, str, n) == n? 0: -1;
+}
+
+int
+readchar(void)
+{
+	char ch;
+
+	for (;;) {
+		switch (read(stdin, &ch, 1)) {
+		case 1:
+			return ch;
+		case -1:
+			printk("read(stdin) returned -1\r\n");
+			return -1;
+		}
+	}
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int
+getchar(void)
+{
+	int c;
+
+	if (lineleft == 0) {
+		lineptr = line;
+		for (;;) {
+			c = readchar();
+			if (c == -1 || c == 4)
+				break;
+			if (c == '\r' || c == '\n') {
+				*lineptr++ = '\n';
+				putchar('\n');
+				break;
+			}
+			switch (c) {
+			case 0177:
+			case '\b':
+				if (lineptr > line) {
+					putchar('\b');
+					putchar(' ');
+					putchar('\b');
+					--lineptr;
+				}
+				break;
+			case 'U' & 0x1F:
+				while (lineptr > line) {
+					putchar('\b');
+					putchar(' ');
+					putchar('\b');
+					--lineptr;
+				}
+				break;
+			default:
+				if (lineptr >= &line[sizeof(line) - 1])
+					putchar('\a');
+				else {
+					putchar(c);
+					*lineptr++ = c;
+				}
+			}
+		}
+		lineleft = lineptr - line;
+		lineptr = line;
+	}
+	if (lineleft == 0)
+		return -1;
+	--lineleft;
+	return *lineptr++;
+}
+
+
+
+/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
+unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,			/* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P,			/* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D,			/* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P,			/* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,	/* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U,			/* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U,			/* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P,			/* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,	/* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L,			/* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L,			/* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C,			/* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
+
+size_t strnlen(const char * s, size_t count)
+{
+	const char *sc;
+
+	for (sc = s; count-- && *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+{
+	unsigned long result = 0,value;
+
+	if (!base) {
+		base = 10;
+		if (*cp == '0') {
+			base = 8;
+			cp++;
+			if ((*cp == 'x') && isxdigit(cp[1])) {
+				cp++;
+				base = 16;
+			}
+		}
+	}
+	while (isxdigit(*cp) &&
+	       (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
+long simple_strtol(const char *cp,char **endp,unsigned int base)
+{
+	if(*cp=='-')
+		return -simple_strtoul(cp+1,endp,base);
+	return simple_strtoul(cp,endp,base);
+}
+
+static int skip_atoi(const char **s)
+{
+	int i=0;
+
+	while (isdigit(**s))
+		i = i*10 + *((*s)++) - '0';
+	return i;
+}
+
+#define ZEROPAD	1		/* pad with zero */
+#define SIGN	2		/* unsigned/signed long */
+#define PLUS	4		/* show plus */
+#define SPACE	8		/* space if plus */
+#define LEFT	16		/* left justified */
+#define SPECIAL	32		/* 0x */
+#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
+
+static char * number(char * str, long long num, int base, int size, int precision, int type)
+{
+	char c,sign,tmp[66];
+	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+	int i;
+
+	if (type & LARGE)
+		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 36)
+		return 0;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if (num < 0) {
+			sign = '-';
+			num = -num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+		else if (base == 8)
+			size--;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++]='0';
+	else while (num != 0)
+		tmp[i++] = digits[do_div(num,base)];
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type&(ZEROPAD+LEFT)))
+		while(size-->0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base==8)
+			*str++ = '0';
+		else if (base==16) {
+			*str++ = '0';
+			*str++ = digits[33];
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	return str;
+}
+
+/* Forward decl. needed for IP address printing stuff... */
+int sprintf(char * buf, const char *fmt, ...);
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+	int len;
+	unsigned long long num;
+	int i, base;
+	char * str;
+	const char *s;
+
+	int flags;		/* flags to number() */
+
+	int field_width;	/* width of output field */
+	int precision;		/* min. # of digits for integers; max
+				   number of chars for from string */
+	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
+	                        /* 'z' support added 23/7/1999 S.H.    */
+				/* 'z' changed to 'Z' --davidm 1/25/99 */
+
+	
+	for (str=buf ; *fmt ; ++fmt) {
+		if (*fmt != '%') {
+			*str++ = *fmt;
+			continue;
+		}
+			
+		/* process flags */
+		flags = 0;
+		repeat:
+			++fmt;		/* this also skips first '%' */
+			switch (*fmt) {
+				case '-': flags |= LEFT; goto repeat;
+				case '+': flags |= PLUS; goto repeat;
+				case ' ': flags |= SPACE; goto repeat;
+				case '#': flags |= SPECIAL; goto repeat;
+				case '0': flags |= ZEROPAD; goto repeat;
+				}
+		
+		/* get field width */
+		field_width = -1;
+		if (isdigit(*fmt))
+			field_width = skip_atoi(&fmt);
+		else if (*fmt == '*') {
+			++fmt;
+			/* it's the next argument */
+			field_width = va_arg(args, int);
+			if (field_width < 0) {
+				field_width = -field_width;
+				flags |= LEFT;
+			}
+		}
+
+		/* get the precision */
+		precision = -1;
+		if (*fmt == '.') {
+			++fmt;	
+			if (isdigit(*fmt))
+				precision = skip_atoi(&fmt);
+			else if (*fmt == '*') {
+				++fmt;
+				/* it's the next argument */
+				precision = va_arg(args, int);
+			}
+			if (precision < 0)
+				precision = 0;
+		}
+
+		/* get the conversion qualifier */
+		qualifier = -1;
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+			qualifier = *fmt;
+			++fmt;
+		}
+
+		/* default base */
+		base = 10;
+
+		switch (*fmt) {
+		case 'c':
+			if (!(flags & LEFT))
+				while (--field_width > 0)
+					*str++ = ' ';
+			*str++ = (unsigned char) va_arg(args, int);
+			while (--field_width > 0)
+				*str++ = ' ';
+			continue;
+
+		case 's':
+			s = va_arg(args, char *);
+			if (!s)
+				s = "<NULL>";
+
+			len = strnlen(s, precision);
+
+			if (!(flags & LEFT))
+				while (len < field_width--)
+					*str++ = ' ';
+			for (i = 0; i < len; ++i)
+				*str++ = *s++;
+			while (len < field_width--)
+				*str++ = ' ';
+			continue;
+
+		case 'p':
+			if (field_width == -1) {
+				field_width = 2*sizeof(void *);
+				flags |= ZEROPAD;
+			}
+			str = number(str,
+				(unsigned long) va_arg(args, void *), 16,
+				field_width, precision, flags);
+			continue;
+
+
+		case 'n':
+			if (qualifier == 'l') {
+				long * ip = va_arg(args, long *);
+				*ip = (str - buf);
+			} else if (qualifier == 'Z') {
+				size_t * ip = va_arg(args, size_t *);
+				*ip = (str - buf);
+			} else {
+				int * ip = va_arg(args, int *);
+				*ip = (str - buf);
+			}
+			continue;
+
+		case '%':
+			*str++ = '%';
+			continue;
+
+		/* integer number formats - set up the flags and "break" */
+		case 'o':
+			base = 8;
+			break;
+
+		case 'X':
+			flags |= LARGE;
+		case 'x':
+			base = 16;
+			break;
+
+		case 'd':
+		case 'i':
+			flags |= SIGN;
+		case 'u':
+			break;
+
+		default:
+			*str++ = '%';
+			if (*fmt)
+				*str++ = *fmt;
+			else
+				--fmt;
+			continue;
+		}
+		if (qualifier == 'L')
+			num = va_arg(args, long long);
+		else if (qualifier == 'l') {
+			num = va_arg(args, unsigned long);
+			if (flags & SIGN)
+				num = (signed long) num;
+		} else if (qualifier == 'Z') {
+			num = va_arg(args, size_t);
+		} else if (qualifier == 'h') {
+			num = (unsigned short) va_arg(args, int);
+			if (flags & SIGN)
+				num = (signed short) num;
+		} else {
+			num = va_arg(args, unsigned int);
+			if (flags & SIGN)
+				num = (signed int) num;
+		}
+		str = number(str, num, base, field_width, precision, flags);
+	}
+	*str = '\0';
+	return str-buf;
+}
+
+int sprintf(char * buf, const char *fmt, ...)
+{
+	va_list args;
+	int i;
+
+	va_start(args, fmt);
+	i=vsprintf(buf,fmt,args);
+	va_end(args);
+	return i;
+}
+
+static char sprint_buf[1024];
+
+void
+printk(char *fmt, ...)
+{
+	va_list args;
+	int n;
+
+	va_start(args, fmt);
+	n = vsprintf(sprint_buf, fmt, args);
+	va_end(args);
+	write(stdout, sprint_buf, n);
+}
+
+int
+printf(char *fmt, ...)
+{
+	va_list args;
+	int n;
+
+	va_start(args, fmt);
+	n = vsprintf(sprint_buf, fmt, args);
+	va_end(args);
+	write(stdout, sprint_buf, n);
+	return n;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/string.S linux/arch/ppc64/boot/string.S
--- linux.orig/arch/ppc64/boot/string.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/string.S	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ *
+ * NOTE: this code runs in 32 bit mode and is packaged as ELF32.
+ */
+
+#include <asm/ppc_asm.tmpl>
+
+	.text
+	.globl	strcpy
+strcpy:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r5)
+	bne	1b
+	blr
+
+	.globl	strncpy
+strncpy:
+	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r6)
+	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
+	blr
+
+	.globl	strcat
+strcat:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r5)
+	cmpwi	0,r0,0
+	bne	1b
+	addi	r5,r5,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r5)
+	bne	1b
+	blr
+
+	.globl	strcmp
+strcmp:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r5)
+	cmpwi	1,r3,0
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	beqlr	1
+	beq	1b
+	blr
+
+	.globl	strlen
+strlen:
+	addi	r4,r3,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	bne	1b
+	subf	r3,r3,r4
+	blr
+
+	.globl	memset
+memset:
+	rlwimi	r4,r4,8,16,23
+	rlwimi	r4,r4,16,0,15
+	addi	r6,r3,-4
+	cmplwi	0,r5,4
+	blt	7f
+	stwu	r4,4(r6)
+	beqlr
+	andi.	r0,r6,3
+	add	r5,r0,r5
+	subf	r6,r0,r6
+	rlwinm	r0,r5,32-2,2,31
+	mtctr	r0
+	bdz	6f
+1:	stwu	r4,4(r6)
+	bdnz	1b
+6:	andi.	r5,r5,3
+7:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r6,3
+8:	stbu	r4,1(r6)
+	bdnz	8b
+	blr
+
+	.globl	bcopy
+bcopy:
+	mr	r6,r3
+	mr	r3,r4
+	mr	r4,r6
+	b	memcpy
+
+	.globl	memmove
+memmove:
+	cmplw	0,r3,r4
+	bgt	backwards_memcpy
+	/* fall through */
+
+	.globl	memcpy
+memcpy:
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	addi	r6,r3,-4
+	addi	r4,r4,-4
+	beq	2f			/* if less than 8 bytes to do */
+	andi.	r0,r6,3			/* get dest word aligned */
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,4(r4)
+	lwzu	r8,8(r4)
+	stw	r7,4(r6)
+	stwu	r8,8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,4(r4)
+	addi	r5,r5,-4
+	stwu	r0,4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r4,r4,3
+	addi	r6,r6,3
+4:	lbzu	r0,1(r4)
+	stbu	r0,1(r6)
+	bdnz	4b
+	blr
+5:	subfic	r0,r0,4
+	mtctr	r0
+6:	lbz	r7,4(r4)
+	addi	r4,r4,1
+	stb	r7,4(r6)
+	addi	r6,r6,1
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+	.globl	backwards_memcpy
+backwards_memcpy:
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	add	r6,r3,r5
+	add	r4,r4,r5
+	beq	2f
+	andi.	r0,r6,3
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,-4(r4)
+	lwzu	r8,-8(r4)
+	stw	r7,-4(r6)
+	stwu	r8,-8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,-4(r4)
+	subi	r5,r5,4
+	stwu	r0,-4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+4:	lbzu	r0,-1(r4)
+	stbu	r0,-1(r6)
+	bdnz	4b
+	blr
+5:	mtctr	r0
+6:	lbzu	r7,-1(r4)
+	stbu	r7,-1(r6)
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+	.globl	memcmp
+memcmp:
+	cmpwi	0,r5,0
+	blelr
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r6)
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	bdnzt	2,1b
+	blr
+
+
+/*
+ * Flush the dcache and invalidate the icache for a range of addresses.
+ *
+ * flush_cache(addr, len)
+ */
+	.global	flush_cache
+flush_cache:
+	addi	4,4,0x1f	/* len = (len + 0x1f) / 0x20 */
+	rlwinm.	4,4,27,5,31
+	mtctr	4
+	beqlr
+1:	dcbf	0,3
+	icbi	0,3
+	addi	3,3,0x20
+	bdnz	1b
+	sync
+	isync
+	blr
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/zImage.c linux/arch/ppc64/boot/zImage.c
--- linux.orig/arch/ppc64/boot/zImage.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/zImage.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner.
+ *
+ * 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.
+ */
+#define __KERNEL__
+#include "ppc32-types.h"
+#include "zlib.h"
+#include <linux/elf.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+
+void memmove(void *dst, void *im, int len);
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+extern void printk(char *fmt, ...);
+extern void printf(const char *fmt, ...);
+extern int sprintf(char *buf, const char *fmt, ...);
+void gunzip(void *, int, unsigned char *, int *);
+void *claim(unsigned int, unsigned int, unsigned int);
+void flush_cache(void *, unsigned long);
+void pause(void);
+extern void exit(void);
+
+static struct bi_record *make_bi_recs(unsigned long);
+
+#define RAM_START	0x00000000
+#define RAM_END		(64<<20)
+
+/* Value picked to match that used by yaboot */
+#define PROG_START	0x01400000
+
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
+unsigned int heap_use;
+unsigned int heap_max;
+
+extern char _end[];
+extern char _vmlinux_start[];
+extern char _vmlinux_end[];
+extern char _sysmap_start[];
+extern char _sysmap_end[];
+extern char _initrd_start[];
+extern char _initrd_end[];
+extern unsigned long vmlinux_filesize;
+extern unsigned long vmlinux_memsize;
+
+struct addr_range {
+	unsigned long addr;
+	unsigned long size;
+	unsigned long memsize;
+};
+struct addr_range vmlinux = {0, 0, 0};
+struct addr_range vmlinuz = {0, 0, 0};
+struct addr_range sysmap  = {0, 0, 0};
+struct addr_range initrd  = {0, 0, 0};
+
+static char scratch[128<<10];	/* 128kB of scratch space for gunzip */
+
+typedef void (*kernel_entry_t)( unsigned long,
+                                unsigned long,
+                                void *,
+				struct bi_record *);
+
+
+int (*prom)(void *);
+
+void *chosen_handle;
+void *stdin;
+void *stdout;
+void *stderr;
+
+
+void
+start(unsigned long a1, unsigned long a2, void *promptr)
+{
+	unsigned long i, claim_addr, claim_size;
+	extern char _start;
+	struct bi_record *bi_recs;
+	kernel_entry_t kernel_entry;
+	Elf64_Ehdr *elf64;
+	Elf64_Phdr *elf64ph;
+
+	prom = (int (*)(void *)) promptr;
+	chosen_handle = finddevice("/chosen");
+	if (chosen_handle == (void *) -1)
+		exit();
+	if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
+		exit();
+	stderr = stdout;
+	if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
+		exit();
+
+	printf("zImage starting: loaded at 0x%x\n\r", (unsigned)&_start);
+
+#if 0
+	sysmap.size = (unsigned long)(_sysmap_end - _sysmap_start);
+	sysmap.memsize = sysmap.size;
+	if ( sysmap.size > 0 ) {
+		sysmap.addr = (RAM_END - sysmap.size) & ~0xFFF;
+		claim(sysmap.addr, RAM_END - sysmap.addr, 0);
+		printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
+		       sysmap.addr, (unsigned long)_sysmap_start, sysmap.size);
+		memcpy((void *)sysmap.addr, (void *)_sysmap_start, sysmap.size);
+	}
+#endif
+
+	initrd.size = (unsigned long)(_initrd_end - _initrd_start);
+	initrd.memsize = initrd.size;
+	if ( initrd.size > 0 ) {
+		initrd.addr = (RAM_END - initrd.size) & ~0xFFF;
+		a1 = a2 = 0;
+		claim(initrd.addr, RAM_END - initrd.addr, 0);
+		printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
+		       initrd.addr, (unsigned long)_initrd_start, initrd.size);
+		memcpy((void *)initrd.addr, (void *)_initrd_start, initrd.size);
+	}
+
+	vmlinuz.addr = (unsigned long)_vmlinux_start;
+	vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
+	vmlinux.addr = (unsigned long)(void *)-1;
+	vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
+	vmlinux.memsize = vmlinux_memsize;
+
+	claim_size = vmlinux.memsize /* PPPBBB: + fudge for bi_recs */;
+	for(claim_addr = PROG_START; 
+	    claim_addr <= PROG_START * 8; 
+	    claim_addr += 0x100000) {
+		printf("    trying: 0x%08lx\n\r", claim_addr);
+		vmlinux.addr = (unsigned long)claim(claim_addr, claim_size, 0);
+		if ((void *)vmlinux.addr != (void *)-1) break;
+	}
+	if ((void *)vmlinux.addr == (void *)-1) {
+		printf("claim error, can't allocate kernel memory\n\r");
+		exit();
+	}
+
+	/* PPPBBB: should kernel always be gziped? */
+	if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
+		avail_ram = scratch;
+		begin_avail = avail_high = avail_ram;
+		end_avail = scratch + sizeof(scratch);
+		printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...",
+		       vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
+		gunzip((void *)vmlinux.addr, vmlinux.size,
+			(unsigned char *)vmlinuz.addr, (int *)&vmlinuz.size);
+		printf("done %lu bytes\n\r", vmlinuz.size);
+		printf("%u bytes of heap consumed, max in use %u\n\r",
+		       (unsigned)(avail_high - begin_avail), heap_max);
+	} else {
+		memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
+	}
+
+	/* Skip over the ELF header */
+	elf64 = (Elf64_Ehdr *)vmlinux.addr;
+	if ( elf64->e_ident[EI_MAG0]  != ELFMAG0	||
+	     elf64->e_ident[EI_MAG1]  != ELFMAG1	||
+	     elf64->e_ident[EI_MAG2]  != ELFMAG2	||
+	     elf64->e_ident[EI_MAG3]  != ELFMAG3	||
+	     elf64->e_ident[EI_CLASS] != ELFCLASS64	||
+	     elf64->e_ident[EI_DATA]  != ELFDATA2MSB	||
+	     elf64->e_type            != ET_EXEC	||
+	     elf64->e_machine         != EM_PPC64 )
+	{
+		printf("Error: not a valid PPC64 ELF file!\n\r");
+		exit();
+	}
+
+	elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
+				(unsigned long)elf64->e_phoff);
+	for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
+		if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
+			break;
+	}
+	printf("... skipping 0x%lx bytes of ELF header\n\r",
+			(unsigned long)elf64ph->p_offset);
+	vmlinux.addr += (unsigned long)elf64ph->p_offset;
+	vmlinux.size -= (unsigned long)elf64ph->p_offset;
+
+	flush_cache((void *)vmlinux.addr, vmlinux.memsize);
+
+	bi_recs = make_bi_recs(vmlinux.addr + vmlinux.memsize);
+
+	kernel_entry = (kernel_entry_t)vmlinux.addr;
+	printf( "kernel:\n\r"
+		"        entry addr = 0x%lx\n\r"
+		"        a1         = 0x%lx,\n\r"
+		"        a2         = 0x%lx,\n\r"
+		"        prom       = 0x%lx,\n\r"
+		"        bi_recs    = 0x%lx,\n\r",
+		(unsigned long)kernel_entry, a1, a2,
+		(unsigned long)prom, (unsigned long)bi_recs);
+
+	kernel_entry( a1, a2, prom, bi_recs );
+
+	printf("Error: Linux kernel returned to zImage bootloader!\n\r");
+
+	exit();
+}
+
+static struct bi_record *
+make_bi_recs(unsigned long addr)
+{
+	struct bi_record *bi_recs;
+	struct bi_record *rec;
+
+	bi_recs = rec = bi_rec_init(addr);
+
+	rec = bi_rec_alloc(rec, 2);
+	rec->tag = BI_FIRST;
+	/* rec->data[0] = ...;	# Written below before return */
+	/* rec->data[1] = ...;	# Written below before return */
+
+	rec = bi_rec_alloc_bytes(rec, strlen("chrpboot")+1);
+	rec->tag = BI_BOOTLOADER_ID;
+	sprintf( (char *)rec->data, "chrpboot");
+
+	rec = bi_rec_alloc(rec, 2);
+	rec->tag = BI_MACHTYPE;
+	rec->data[0] = _MACH_pSeries;
+	rec->data[1] = 1;
+
+	if ( initrd.size > 0 ) {
+		rec = bi_rec_alloc(rec, 2);
+		rec->tag = BI_INITRD;
+		rec->data[0] = initrd.addr;
+		rec->data[1] = initrd.size;
+	}
+
+	if ( sysmap.size > 0 ) {
+		rec = bi_rec_alloc(rec, 2);
+		rec->tag = BI_SYSMAP;
+		rec->data[0] = (unsigned long)sysmap.addr;
+		rec->data[1] = (unsigned long)sysmap.size;
+	}
+
+	rec = bi_rec_alloc(rec, 1);
+	rec->tag = BI_LAST;
+	rec->data[0] = (bi_rec_field)bi_recs;
+
+	/* Save the _end_ address of the bi_rec's in the first bi_rec
+	 * data field for easy access by the kernel.
+	 */
+	bi_recs->data[0] = (bi_rec_field)rec;
+	bi_recs->data[1] = (bi_rec_field)rec + rec->size - (bi_rec_field)bi_recs;
+
+	return bi_recs;
+}
+
+struct memchunk {
+	unsigned int size;
+	unsigned int pad;
+	struct memchunk *next;
+};
+
+static struct memchunk *freechunks;
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+	void *p;
+	struct memchunk **mpp, *mp;
+
+	size *= items;
+	size = _ALIGN(size, sizeof(struct memchunk));
+	heap_use += size;
+	if (heap_use > heap_max)
+		heap_max = heap_use;
+	for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+		if (mp->size == size) {
+			*mpp = mp->next;
+			return mp;
+		}
+	}
+	p = avail_ram;
+	avail_ram += size;
+	if (avail_ram > avail_high)
+		avail_high = avail_ram;
+	if (avail_ram > end_avail) {
+		printf("oops... out of memory\n\r");
+		pause();
+	}
+	return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+	struct memchunk *mp = addr;
+
+	nb = _ALIGN(nb, sizeof(struct memchunk));
+	heap_use -= nb;
+	if (avail_ram == addr + nb) {
+		avail_ram = addr;
+		return;
+	}
+	mp->size = nb;
+	mp->next = freechunks;
+	freechunks = mp;
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+	z_stream s;
+	int r, i, flags;
+
+	/* skip header */
+	i = 10;
+	flags = src[3];
+	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+		printf("bad gzipped data\n\r");
+		exit();
+	}
+	if ((flags & EXTRA_FIELD) != 0)
+		i = 12 + src[10] + (src[11] << 8);
+	if ((flags & ORIG_NAME) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & COMMENT) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & HEAD_CRC) != 0)
+		i += 2;
+	if (i >= *lenp) {
+		printf("gunzip: ran out of data in header\n\r");
+		exit();
+	}
+
+	s.zalloc = zalloc;
+	s.zfree = zfree;
+	r = inflateInit2(&s, -MAX_WBITS);
+	if (r != Z_OK) {
+		printf("inflateInit2 returned %d\n\r", r);
+		exit();
+	}
+	s.next_in = src + i;
+	s.avail_in = *lenp - i;
+	s.next_out = dst;
+	s.avail_out = dstlen;
+	r = inflate(&s, Z_FINISH);
+	if (r != Z_OK && r != Z_STREAM_END) {
+		printf("inflate returned %d msg: %s\n\r", r, s.msg);
+		exit();
+	}
+	*lenp = s.next_out - (unsigned char *) dst;
+	inflateEnd(&s);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/zImage.lds linux/arch/ppc64/boot/zImage.lds
--- linux.orig/arch/ppc64/boot/zImage.lds	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/zImage.lds	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,99 @@
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)      }
+  .dynsym        : { *(.dynsym)        }
+  .dynstr        : { *(.dynstr)        }
+  .rel.text      : { *(.rel.text)      }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)      }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)       }
+  .rela.got      : { *(.rela.got)      }
+  .rel.ctors     : { *(.rel.ctors) }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors) }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)       }
+  .rela.bss      : { *(.rela.bss)      }
+  .rel.plt       : { *(.rel.plt)       }
+  .rela.plt      : { *(.rela.plt)      }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  . = ALIGN(4096);
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .kstrtab   : { *(.kstrtab) }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+  /* Read-write section, merged into data segment: */
+  . = ALIGN(4096);
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.got.plt) *(.got)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+
+  . = ALIGN(4096);
+  _vmlinux_start =  .;
+  .kernel:vmlinux : { *(.kernel:vmlinux) }
+  _vmlinux_end =  .;
+
+  . = ALIGN(4096);
+  _dotconfig_start =  .;
+  .kernel:.config : { *(.kernel:.config) }
+  _dotconfig_end =  .;
+
+  . = ALIGN(4096);
+  _sysmap_start =  .;
+  .kernel:System.map : { *(.kernel:System.map) }
+  _sysmap_end =  .;
+
+  . = ALIGN(4096);
+  _initrd_start =  .;
+  .kernel:initrd : { *(.kernel:initrd) }
+  _initrd_end =  .;
+
+  . = ALIGN(4096);
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  .fixup   : { *(.fixup) }
+
+  . = ALIGN(4096);
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  . = ALIGN(4096);
+  _end = . ;
+  PROVIDE (end = .);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/zlib.c linux/arch/ppc64/boot/zlib.c
--- linux.orig/arch/ppc64/boot/zlib.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/zlib.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,2165 @@
+/*
+ * This file is derived from various .h and .c files from the zlib-0.95
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets.  See zlib.h for conditions of
+ * distribution and use.
+ *
+ * Changes that have been made include:
+ * - changed functions not used outside this file to "local"
+ * - added minCompression parameter to deflateInit2
+ * - added Z_PACKET_FLUSH (see zlib.h for details)
+ * - added inflateIncomp
+ *
+  Copyright (C) 1995 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  gzip@prep.ai.mit.edu    madler@alumni.caltech.edu
+
+ *
+ * 
+ */
+
+/*+++++*/
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
+
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#define FAR
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern char *z_errmsg[]; /* indexed by 1-zlib_error */
+
+#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
+/* To be used only when the state is known to be valid */
+
+#ifndef NULL
+#define NULL	((void *) 0)
+#endif
+
+        /* common constants */
+
+#define DEFLATED   8
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+         /* functions */
+
+#include <linux/string.h>
+#define zmemcpy memcpy
+#define zmemzero(dest, len)	memset(dest, 0, len)
+
+/* Diagnostic functions */
+#ifdef DEBUG_ZLIB
+#  include <stdio.h>
+#  ifndef verbose
+#    define verbose 0
+#  endif
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
+
+/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
+/* void   zcfree  OF((voidpf opaque, voidpf ptr)); */
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr, size)	\
+	   (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
+#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
+
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/*+++++*/
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+local inflate_blocks_statef * inflate_blocks_new OF((
+    z_stream *z,
+    check_func c,               /* check function */
+    uInt w));                   /* window size */
+
+local int inflate_blocks OF((
+    inflate_blocks_statef *,
+    z_stream *,
+    int));                      /* initial return code */
+
+local void inflate_blocks_reset OF((
+    inflate_blocks_statef *,
+    z_stream *,
+    uLongf *));                  /* check value on output */
+
+local int inflate_blocks_free OF((
+    inflate_blocks_statef *,
+    z_stream *,
+    uLongf *));                  /* check value on output */
+
+local int inflate_addhistory OF((
+    inflate_blocks_statef *,
+    z_stream *));
+
+local int inflate_packet_flush OF((
+    inflate_blocks_statef *));
+
+/*+++++*/
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+  union {
+    struct {
+      Byte Exop;        /* number of extra bits or operation */
+      Byte Bits;        /* number of bits in this code or subcode */
+    } what;
+    uInt Nalloc;	/* number of these allocated here */
+    Bytef *pad;         /* pad structure to a power of 2 (4 bytes for */
+  } word;               /*  16-bit, 8 bytes for 32-bit machines) */
+  union {
+    uInt Base;          /* literal, length base, or distance base */
+    inflate_huft *Next; /* pointer to next level of table */
+  } more;
+};
+
+#ifdef DEBUG_ZLIB
+  local uInt inflate_hufts;
+#endif
+
+local int inflate_trees_bits OF((
+    uIntf *,                    /* 19 code lengths */
+    uIntf *,                    /* bits tree desired/actual depth */
+    inflate_huft * FAR *,       /* bits tree result */
+    z_stream *));               /* for zalloc, zfree functions */
+
+local int inflate_trees_dynamic OF((
+    uInt,                       /* number of literal/length codes */
+    uInt,                       /* number of distance codes */
+    uIntf *,                    /* that many (total) code lengths */
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    z_stream *));               /* for zalloc, zfree functions */
+
+local int inflate_trees_fixed OF((
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *));     /* distance tree result */
+
+local int inflate_trees_free OF((
+    inflate_huft *,             /* tables to free */
+    z_stream *));               /* for zfree function */
+
+
+/*+++++*/
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+local inflate_codes_statef *inflate_codes_new OF((
+    uInt, uInt,
+    inflate_huft *, inflate_huft *,
+    z_stream *));
+
+local int inflate_codes OF((
+    inflate_blocks_statef *,
+    z_stream *,
+    int));
+
+local void inflate_codes_free OF((
+    inflate_codes_statef *,
+    z_stream *));
+
+
+/*+++++*/
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* inflate private state */
+struct internal_state {
+
+  /* mode */
+  enum {
+      METHOD,   /* waiting for method byte */
+      FLAG,     /* waiting for flag byte */
+      BLOCKS,   /* decompressing blocks */
+      CHECK4,   /* four check bytes to go */
+      CHECK3,   /* three check bytes to go */
+      CHECK2,   /* two check bytes to go */
+      CHECK1,   /* one check byte to go */
+      DONE,     /* finished check, done */
+      BAD}      /* got an error--stay here */
+    mode;               /* current inflate mode */
+
+  /* mode dependent information */
+  union {
+    uInt method;        /* if FLAGS, method byte */
+    struct {
+      uLong was;                /* computed check value */
+      uLong need;               /* stream check value */
+    } check;            /* if CHECK, check values to compare */
+    uInt marker;        /* if BAD, inflateSync's marker bytes count */
+  } sub;        /* submode */
+
+  /* mode independent information */
+  int  nowrap;          /* flag for no wrapper */
+  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
+  inflate_blocks_statef 
+    *blocks;            /* current inflate_blocks state */
+
+};
+
+
+int inflateReset(z)
+z_stream *z;
+{
+  uLong c;
+
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->total_in = z->total_out = 0;
+  z->msg = Z_NULL;
+  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+  inflate_blocks_reset(z->state->blocks, z, &c);
+  Trace((stderr, "inflate: reset\n"));
+  return Z_OK;
+}
+
+
+int inflateEnd(z)
+z_stream *z;
+{
+  uLong c;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->blocks != Z_NULL)
+    inflate_blocks_free(z->state->blocks, z, &c);
+  ZFREE(z, z->state, sizeof(struct internal_state));
+  z->state = Z_NULL;
+  Trace((stderr, "inflate: end\n"));
+  return Z_OK;
+}
+
+
+int inflateInit2(z, w)
+z_stream *z;
+int w;
+{
+  /* initialize state */
+  if (z == Z_NULL)
+    return Z_STREAM_ERROR;
+/*  if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
+/*  if (z->zfree == Z_NULL) z->zfree = zcfree; */
+  if ((z->state = (struct internal_state FAR *)
+       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+    return Z_MEM_ERROR;
+  z->state->blocks = Z_NULL;
+
+  /* handle undocumented nowrap option (no zlib header or check) */
+  z->state->nowrap = 0;
+  if (w < 0)
+  {
+    w = - w;
+    z->state->nowrap = 1;
+  }
+
+  /* set window size */
+  if (w < 8 || w > 15)
+  {
+    inflateEnd(z);
+    return Z_STREAM_ERROR;
+  }
+  z->state->wbits = (uInt)w;
+
+  /* create inflate_blocks state */
+  if ((z->state->blocks =
+       inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
+      == Z_NULL)
+  {
+    inflateEnd(z);
+    return Z_MEM_ERROR;
+  }
+  Trace((stderr, "inflate: allocated\n"));
+
+  /* reset state */
+  inflateReset(z);
+  return Z_OK;
+}
+
+
+int inflateInit(z)
+z_stream *z;
+{
+  return inflateInit2(z, DEF_WBITS);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int inflate(z, f)
+z_stream *z;
+int f;
+{
+  int r;
+  uInt b;
+
+  if (z == Z_NULL || z->next_in == Z_NULL)
+    return Z_STREAM_ERROR;
+  r = Z_BUF_ERROR;
+  while (1) switch (z->state->mode)
+  {
+    case METHOD:
+      NEEDBYTE
+      if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
+      {
+        z->state->mode = BAD;
+        z->msg = "unknown compression method";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+      {
+        z->state->mode = BAD;
+        z->msg = "invalid window size";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      z->state->mode = FLAG;
+    case FLAG:
+      NEEDBYTE
+      if ((b = NEXTBYTE) & 0x20)
+      {
+        z->state->mode = BAD;
+        z->msg = "invalid reserved bit";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if (((z->state->sub.method << 8) + b) % 31)
+      {
+        z->state->mode = BAD;
+        z->msg = "incorrect header check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Trace((stderr, "inflate: zlib header ok\n"));
+      z->state->mode = BLOCKS;
+    case BLOCKS:
+      r = inflate_blocks(z->state->blocks, z, r);
+      if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
+	  r = inflate_packet_flush(z->state->blocks);
+      if (r == Z_DATA_ERROR)
+      {
+        z->state->mode = BAD;
+        z->state->sub.marker = 0;       /* can try inflateSync */
+        break;
+      }
+      if (r != Z_STREAM_END)
+        return r;
+      r = Z_OK;
+      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+      if (z->state->nowrap)
+      {
+        z->state->mode = DONE;
+        break;
+      }
+      z->state->mode = CHECK4;
+    case CHECK4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = CHECK3;
+    case CHECK3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = CHECK2;
+    case CHECK2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = CHECK1;
+    case CHECK1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+
+      if (z->state->sub.check.was != z->state->sub.check.need)
+      {
+        z->state->mode = BAD;
+        z->msg = "incorrect data check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Trace((stderr, "inflate: zlib check ok\n"));
+      z->state->mode = DONE;
+    case DONE:
+      return Z_STREAM_END;
+    case BAD:
+      return Z_DATA_ERROR;
+    default:
+      return Z_STREAM_ERROR;
+  }
+
+ empty:
+  if (f != Z_PACKET_FLUSH)
+    return r;
+  z->state->mode = BAD;
+  z->state->sub.marker = 0;       /* can try inflateSync */
+  return Z_DATA_ERROR;
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output.  The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS).  On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+
+int inflateIncomp(z)
+z_stream *z;
+{
+    if (z->state->mode != BLOCKS)
+	return Z_DATA_ERROR;
+    return inflate_addhistory(z->state->blocks, z);
+}
+
+
+int inflateSync(z)
+z_stream *z;
+{
+  uInt n;       /* number of bytes to look at */
+  Bytef *p;     /* pointer to bytes */
+  uInt m;       /* number of marker bytes found in a row */
+  uLong r, w;   /* temporaries to save total_in and total_out */
+
+  /* set up */
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->mode != BAD)
+  {
+    z->state->mode = BAD;
+    z->state->sub.marker = 0;
+  }
+  if ((n = z->avail_in) == 0)
+    return Z_BUF_ERROR;
+  p = z->next_in;
+  m = z->state->sub.marker;
+
+  /* search */
+  while (n && m < 4)
+  {
+    if (*p == (Byte)(m < 2 ? 0 : 0xff))
+      m++;
+    else if (*p)
+      m = 0;
+    else
+      m = 4 - m;
+    p++, n--;
+  }
+
+  /* restore */
+  z->total_in += p - z->next_in;
+  z->next_in = p;
+  z->avail_in = n;
+  z->state->sub.marker = m;
+
+  /* return no joy or set up to restart on a new block */
+  if (m != 4)
+    return Z_DATA_ERROR;
+  r = z->total_in;  w = z->total_out;
+  inflateReset(z);
+  z->total_in = r;  z->total_out = w;
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+#undef NEEDBYTE
+#undef NEXTBYTE
+
+/*+++++*/
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+  /* mode */
+  enum {
+      TYPE,     /* get type bits (3, including end bit) */
+      LENS,     /* get lengths for stored */
+      STORED,   /* processing stored block */
+      TABLE,    /* get table lengths */
+      BTREE,    /* get bit lengths tree for a dynamic block */
+      DTREE,    /* get length, distance trees for a dynamic block */
+      CODES,    /* processing fixed or dynamic block */
+      DRY,      /* output remaining window bytes */
+      DONEB,     /* finished last block, done */
+      BADB}      /* got a data error--stuck here */
+    mode;               /* current inflate_block mode */
+
+  /* mode dependent information */
+  union {
+    uInt left;          /* if STORED, bytes left to copy */
+    struct {
+      uInt table;               /* table lengths (14 bits) */
+      uInt index;               /* index into blens (or border) */
+      uIntf *blens;             /* bit lengths of codes */
+      uInt bb;                  /* bit length tree depth */
+      inflate_huft *tb;         /* bit length decoding tree */
+      int nblens;		/* # elements allocated at blens */
+    } trees;            /* if DTREE, decoding info for trees */
+    struct {
+      inflate_huft *tl, *td;    /* trees to free */
+      inflate_codes_statef 
+         *codes;
+    } decode;           /* if CODES, current state */
+  } sub;                /* submode */
+  uInt last;            /* true if this block is the last block */
+
+  /* mode independent information */
+  uInt bitk;            /* bits in bit buffer */
+  uLong bitb;           /* bit buffer */
+  Bytef *window;        /* sliding window */
+  Bytef *end;           /* one byte after sliding window */
+  Bytef *read;          /* window read pointer */
+  Bytef *write;         /* window write pointer */
+  check_func checkfn;   /* check function */
+  uLong check;          /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/*   update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/*   get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/*   output bytes */
+#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/*   load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* And'ing with mask[n] masks the lower n bits */
+local uInt inflate_mask[] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+/* copy as much as possible from the sliding window to the output area */
+local int inflate_flush OF((
+    inflate_blocks_statef *,
+    z_stream *,
+    int));
+
+/*+++++*/
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+local int inflate_fast OF((
+    uInt,
+    uInt,
+    inflate_huft *,
+    inflate_huft *,
+    inflate_blocks_statef *,
+    z_stream *));
+
+
+/*+++++*/
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local uInt border[] = { /* Order of the bit length code lengths */
+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+   Notes beyond the 1.93a appnote.txt:
+
+   1. Distance pointers never point before the beginning of the output
+      stream.
+   2. Distance pointers can point back across blocks, up to 32k away.
+   3. There is an implied maximum of 7 bits for the bit length table and
+      15 bits for the actual data.
+   4. If only one code exists, then it is encoded using one bit.  (Zero
+      would be more efficient, but perhaps a little confusing.)  If two
+      codes exist, they are coded using one bit each (0 and 1).
+   5. There is no way of sending zero distance codes--a dummy must be
+      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+      store blocks with no distance codes, but this was discovered to be
+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+      zero distance codes, which is sent as one code of zero bits in
+      length.
+   6. There are up to 286 literal/length codes.  Code 256 represents the
+      end-of-block.  Note however that the static length tree defines
+      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+      cannot be used though, since there is no length base or extra bits
+      defined for them.  Similarily, there are up to 30 distance codes.
+      However, static trees define 32 codes (all 5 bits) to fill out the
+      Huffman codes, but the last two had better not show up in the data.
+   7. Unzip can check dynamic Huffman blocks for complete code sets.
+      The exception is that a single code would not be complete (see #4).
+   8. The five bits following the block type is really the number of
+      literal codes sent minus 257.
+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+      (1+6+6).  Therefore, to output three times the length, you output
+      three codes (1+1+1), whereas to output four times the same length,
+      you only need two codes (1+3).  Hmm.
+  10. In the tree reconstruction algorithm, Code = Code + Increment
+      only if BitLength(i) is not zero.  (Pretty obvious.)
+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+  12. Note: length code 284 can represent 227-258, but length code 285
+      really is 258.  The last length deserves its own, short code
+      since it gets used a lot in very redundant files.  The length
+      258 is special since 258 - 3 (the min match length) is 255.
+  13. The literal/length and distance code bit lengths are read as a
+      single stream of lengths.  It is possible (and advantageous) for
+      a repeat code (16, 17, or 18) to go across the boundary between
+      the two sets of lengths.
+ */
+
+
+local void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_stream *z;
+uLongf *c;
+{
+  if (s->checkfn != Z_NULL)
+    *c = s->check;
+  if (s->mode == BTREE || s->mode == DTREE)
+    ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
+  if (s->mode == CODES)
+  {
+    inflate_codes_free(s->sub.decode.codes, z);
+    inflate_trees_free(s->sub.decode.td, z);
+    inflate_trees_free(s->sub.decode.tl, z);
+  }
+  s->mode = TYPE;
+  s->bitk = 0;
+  s->bitb = 0;
+  s->read = s->write = s->window;
+  if (s->checkfn != Z_NULL)
+    s->check = (*s->checkfn)(0L, Z_NULL, 0);
+  Trace((stderr, "inflate:   blocks reset\n"));
+}
+
+
+local inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_stream *z;
+check_func c;
+uInt w;
+{
+  inflate_blocks_statef *s;
+
+  if ((s = (inflate_blocks_statef *)ZALLOC
+       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+    return s;
+  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+  {
+    ZFREE(z, s, sizeof(struct inflate_blocks_state));
+    return Z_NULL;
+  }
+  s->end = s->window + w;
+  s->checkfn = c;
+  s->mode = TYPE;
+  Trace((stderr, "inflate:   blocks allocated\n"));
+  inflate_blocks_reset(s, z, &s->check);
+  return s;
+}
+
+
+local int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+  uInt t;               /* temporary storage */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input based on current state */
+  while (1) switch (s->mode)
+  {
+    case TYPE:
+      NEEDBITS(3)
+      t = (uInt)b & 7;
+      s->last = t & 1;
+      switch (t >> 1)
+      {
+        case 0:                         /* stored */
+          Trace((stderr, "inflate:     stored block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          t = k & 7;                    /* go to byte boundary */
+          DUMPBITS(t)
+          s->mode = LENS;               /* get length of stored block */
+          break;
+        case 1:                         /* fixed */
+          Trace((stderr, "inflate:     fixed codes block%s\n",
+                 s->last ? " (last)" : ""));
+          {
+            uInt bl, bd;
+            inflate_huft *tl, *td;
+
+            inflate_trees_fixed(&bl, &bd, &tl, &td);
+            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+            if (s->sub.decode.codes == Z_NULL)
+            {
+              r = Z_MEM_ERROR;
+              LEAVE
+            }
+            s->sub.decode.tl = Z_NULL;  /* don't try to free these */
+            s->sub.decode.td = Z_NULL;
+          }
+          DUMPBITS(3)
+          s->mode = CODES;
+          break;
+        case 2:                         /* dynamic */
+          Trace((stderr, "inflate:     dynamic codes block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          s->mode = TABLE;
+          break;
+        case 3:                         /* illegal */
+          DUMPBITS(3)
+          s->mode = BADB;
+          z->msg = "invalid block type";
+          r = Z_DATA_ERROR;
+          LEAVE
+      }
+      break;
+    case LENS:
+      NEEDBITS(32)
+      if (((~b) >> 16) != (b & 0xffff))
+      {
+        s->mode = BADB;
+        z->msg = "invalid stored block lengths";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+      s->sub.left = (uInt)b & 0xffff;
+      b = k = 0;                      /* dump bits */
+      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
+      s->mode = s->sub.left ? STORED : TYPE;
+      break;
+    case STORED:
+      if (n == 0)
+        LEAVE
+      NEEDOUT
+      t = s->sub.left;
+      if (t > n) t = n;
+      if (t > m) t = m;
+      zmemcpy(q, p, t);
+      p += t;  n -= t;
+      q += t;  m -= t;
+      if ((s->sub.left -= t) != 0)
+        break;
+      Tracev((stderr, "inflate:       stored end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      s->mode = s->last ? DRY : TYPE;
+      break;
+    case TABLE:
+      NEEDBITS(14)
+      s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+      {
+        s->mode = BADB;
+        z->msg = "too many length or distance symbols";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+#endif
+      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+      if (t < 19)
+        t = 19;
+      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+      {
+        r = Z_MEM_ERROR;
+        LEAVE
+      }
+      s->sub.trees.nblens = t;
+      DUMPBITS(14)
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       table sizes ok\n"));
+      s->mode = BTREE;
+    case BTREE:
+      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+      {
+        NEEDBITS(3)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+        DUMPBITS(3)
+      }
+      while (s->sub.trees.index < 19)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+      s->sub.trees.bb = 7;
+      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+                             &s->sub.trees.tb, z);
+      if (t != Z_OK)
+      {
+        r = t;
+        if (r == Z_DATA_ERROR)
+          s->mode = BADB;
+        LEAVE
+      }
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       bits tree ok\n"));
+      s->mode = DTREE;
+    case DTREE:
+      while (t = s->sub.trees.table,
+             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+      {
+        inflate_huft *h;
+        uInt i, j, c;
+
+        t = s->sub.trees.bb;
+        NEEDBITS(t)
+        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+        t = h->word.what.Bits;
+        c = h->more.Base;
+        if (c < 16)
+        {
+          DUMPBITS(t)
+          s->sub.trees.blens[s->sub.trees.index++] = c;
+        }
+        else /* c == 16..18 */
+        {
+          i = c == 18 ? 7 : c - 14;
+          j = c == 18 ? 11 : 3;
+          NEEDBITS(t + i)
+          DUMPBITS(t)
+          j += (uInt)b & inflate_mask[i];
+          DUMPBITS(i)
+          i = s->sub.trees.index;
+          t = s->sub.trees.table;
+          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+              (c == 16 && i < 1))
+          {
+            s->mode = BADB;
+            z->msg = "invalid bit length repeat";
+            r = Z_DATA_ERROR;
+            LEAVE
+          }
+          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+          do {
+            s->sub.trees.blens[i++] = c;
+          } while (--j);
+          s->sub.trees.index = i;
+        }
+      }
+      inflate_trees_free(s->sub.trees.tb, z);
+      s->sub.trees.tb = Z_NULL;
+      {
+        uInt bl, bd;
+        inflate_huft *tl, *td;
+        inflate_codes_statef *c;
+
+        bl = 9;         /* must be <= 9 for lookahead assumptions */
+        bd = 6;         /* must be <= 9 for lookahead assumptions */
+        t = s->sub.trees.table;
+        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+                                  s->sub.trees.blens, &bl, &bd, &tl, &td, z);
+        if (t != Z_OK)
+        {
+          if (t == (uInt)Z_DATA_ERROR)
+            s->mode = BADB;
+          r = t;
+          LEAVE
+        }
+        Tracev((stderr, "inflate:       trees ok\n"));
+        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+        {
+          inflate_trees_free(td, z);
+          inflate_trees_free(tl, z);
+          r = Z_MEM_ERROR;
+          LEAVE
+        }
+        ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
+        s->sub.decode.codes = c;
+        s->sub.decode.tl = tl;
+        s->sub.decode.td = td;
+      }
+      s->mode = CODES;
+    case CODES:
+      UPDATE
+      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+        return inflate_flush(s, z, r);
+      r = Z_OK;
+      inflate_codes_free(s->sub.decode.codes, z);
+      inflate_trees_free(s->sub.decode.td, z);
+      inflate_trees_free(s->sub.decode.tl, z);
+      LOAD
+      Tracev((stderr, "inflate:       codes end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      if (!s->last)
+      {
+        s->mode = TYPE;
+        break;
+      }
+      if (k > 7)              /* return unused byte, if any */
+      {
+        Assert(k < 16, "inflate_codes grabbed too many bytes")
+        k -= 8;
+        n++;
+        p--;                    /* can always return one */
+      }
+      s->mode = DRY;
+    case DRY:
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      s->mode = DONEB;
+    case DONEB:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADB:
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+local int inflate_blocks_free(s, z, c)
+inflate_blocks_statef *s;
+z_stream *z;
+uLongf *c;
+{
+  inflate_blocks_reset(s, z, c);
+  ZFREE(z, s->window, s->end - s->window);
+  ZFREE(z, s, sizeof(struct inflate_blocks_state));
+  Trace((stderr, "inflate:   blocks freed\n"));
+  return Z_OK;
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output.  The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS).  On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+local int inflate_addhistory(s, z)
+inflate_blocks_statef *s;
+z_stream *z;
+{
+    uLong b;              /* bit buffer */  /* NOT USED HERE */
+    uInt k;               /* bits in bit buffer */ /* NOT USED HERE */
+    uInt t;               /* temporary storage */
+    Bytef *p;             /* input data pointer */
+    uInt n;               /* bytes available there */
+    Bytef *q;             /* output window write pointer */
+    uInt m;               /* bytes to end of window or read pointer */
+
+    if (s->read != s->write)
+	return Z_STREAM_ERROR;
+    if (s->mode != TYPE)
+	return Z_DATA_ERROR;
+
+    /* we're ready to rock */
+    LOAD
+    /* while there is input ready, copy to output buffer, moving
+     * pointers as needed.
+     */
+    while (n) {
+	t = n;  /* how many to do */
+	/* is there room until end of buffer? */
+	if (t > m) t = m;
+	/* update check information */
+	if (s->checkfn != Z_NULL)
+	    s->check = (*s->checkfn)(s->check, q, t);
+	zmemcpy(q, p, t);
+	q += t;
+	p += t;
+	n -= t;
+	z->total_out += t;
+	s->read = q;    /* drag read pointer forward */
+/*      WRAP  */ 	/* expand WRAP macro by hand to handle s->read */
+	if (q == s->end) {
+	    s->read = q = s->window;
+	    m = WAVAIL;
+	}
+    }
+    UPDATE
+    return Z_OK;
+}
+
+
+/*
+ * At the end of a Deflate-compressed PPP packet, we expect to have seen
+ * a `stored' block type value but not the (zero) length bytes.
+ */
+local int inflate_packet_flush(s)
+    inflate_blocks_statef *s;
+{
+    if (s->mode != LENS)
+	return Z_DATA_ERROR;
+    s->mode = TYPE;
+    return Z_OK;
+}
+
+
+/*+++++*/
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+    uIntf *,            /* code lengths in bits */
+    uInt,               /* number of codes */
+    uInt,               /* number of "simple" codes */
+    uIntf *,            /* list of base values for non-simple codes */
+    uIntf *,            /* list of extra bits for non-simple codes */
+    inflate_huft * FAR*,/* result: starting table */
+    uIntf *,            /* maximum lookup bits (returns actual) */
+    z_stream *));       /* for zalloc function */
+
+local voidpf falloc OF((
+    voidpf,             /* opaque pointer (not used) */
+    uInt,               /* number of items */
+    uInt));             /* size of item */
+
+local void ffree OF((
+    voidpf q,           /* opaque pointer (not used) */
+    voidpf p,           /* what to free (not used) */
+    uInt n));		/* number of bytes (not used) */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+        /* actually lengths - 2; also see note #13 above about 258 */
+local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
+local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+local uInt cpdext[] = { /* Extra bits for distance codes */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15         /* maximum bit length of any code */
+#define N_MAX 288       /* maximum number of codes in any set */
+
+#ifdef DEBUG_ZLIB
+  uInt inflate_hufts;
+#endif
+
+local int huft_build(b, n, s, d, e, t, m, zs)
+uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
+uInt n;                 /* number of codes (assumed <= N_MAX) */
+uInt s;                 /* number of simple-valued codes (0..s-1) */
+uIntf *d;               /* list of base values for non-simple codes */
+uIntf *e;               /* list of extra bits for non-simple codes */  
+inflate_huft * FAR *t;  /* result: starting table */
+uIntf *m;               /* maximum lookup bits, returns actual */
+z_stream *zs;           /* for zalloc function */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
+   if the given code set is incomplete (the tables are still built in this
+   case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
+   over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
+{
+
+  uInt a;                       /* counter for codes of length k */
+  uInt c[BMAX+1];               /* bit length count table */
+  uInt f;                       /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register uInt i;              /* counter, current code */
+  register uInt j;              /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  register uIntf *p;            /* pointer into c[], b[], or v[] */
+  inflate_huft *q;              /* points to current table */
+  struct inflate_huft_s r;      /* table entry for structure assignment */
+  inflate_huft *u[BMAX];        /* table stack */
+  uInt v[N_MAX];                /* values in order of bit length */
+  register int w;               /* bits before this table == (l * h) */
+  uInt x[BMAX+1];               /* bit offsets, then code stack */
+  uIntf *xp;                    /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  uInt z;                       /* number of entries in current table */
+
+
+  /* Generate counts for each bit length */
+  p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+  C4                            /* clear c[]--assume BMAX+1 is 16 */
+  p = b;  i = n;
+  do {
+    c[*p++]++;                  /* assume all entries <= BMAX */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (inflate_huft *)Z_NULL;
+    *m = 0;
+    return Z_OK;
+  }
+
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                        /* minimum code length */
+  if ((uInt)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((uInt)l > i)
+    l = i;
+  *m = l;
+
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return Z_DATA_ERROR;
+  if ((y -= c[i]) < 0)
+    return Z_DATA_ERROR;
+  c[i] += y;
+
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;  xp = x + 2;
+  while (--i) {                 /* note that i == g from above */
+    *xp++ = (j += *p++);
+  }
+
+
+  /* Make a table of values in order of bit lengths */
+  p = b;  i = 0;
+  do {
+    if ((j = *p++) != 0)
+      v[x[j]++] = i;
+  } while (++i < n);
+
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                 /* first Huffman code is zero */
+  p = v;                        /* grab values in bit order */
+  h = -1;                       /* no tables yet--level -1 */
+  w = -l;                       /* bits decoded == (l * h) */
+  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
+  q = (inflate_huft *)Z_NULL;   /* ditto */
+  z = 0;                        /* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+    a = c[k];
+    while (a--)
+    {
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = (z = g - w) > (uInt)l ? l : z;      /* table size upper limit */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          if (j < z)
+            while (++j < z)     /* try smaller tables up to z bits */
+            {
+              if ((f <<= 1) <= *++xp)
+                break;          /* enough codes to use up j bits */
+              f -= *xp;         /* else deduct codes from patterns */
+            }
+        }
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate and link in new table */
+        if ((q = (inflate_huft *)ZALLOC
+             (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
+        {
+          if (h)
+            inflate_trees_free(u[0], zs);
+          return Z_MEM_ERROR;   /* not enough memory */
+        }
+	q->word.Nalloc = z + 1;
+#ifdef DEBUG_ZLIB
+        inflate_hufts += z + 1;
+#endif
+        *t = q + 1;             /* link to list for huft_free() */
+        *(t = &(q->next)) = Z_NULL;
+        u[h] = ++q;             /* table starts after link */
+
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.bits = (Byte)l;     /* bits to dump before this table */
+          r.exop = (Byte)j;     /* bits in this table */
+          r.next = q;           /* pointer to this table */
+          j = i >> (w - l);     /* (get around Turbo C bug) */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+      }
+
+      /* set up table entry in r */
+      r.bits = (Byte)(k - w);
+      if (p >= v + n)
+        r.exop = 128 + 64;      /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
+        r.base = *p++;          /* simple code is just the value */
+      }
+      else
+      {
+        r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
+        r.base = d[*p++ - s];
+      }
+
+      /* fill code-like entries with r */
+      f = 1 << (k - w);
+      for (j = i >> w; j < z; j += f)
+        q[j] = r;
+
+      /* backwards increment the k-bit code i */
+      for (j = 1 << (k - 1); i & j; j >>= 1)
+        i ^= j;
+      i ^= j;
+
+      /* backup over finished tables */
+      while ((i & ((1 << w) - 1)) != x[h])
+      {
+        h--;                    /* don't need to update q */
+        w -= l;
+      }
+    }
+  }
+
+
+  /* Return Z_BUF_ERROR if we were given an incomplete table */
+  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+local int inflate_trees_bits(c, bb, tb, z)
+uIntf *c;               /* 19 code lengths */
+uIntf *bb;              /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+z_stream *z;            /* for zfree function */
+{
+  int r;
+
+  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
+  if (r == Z_DATA_ERROR)
+    z->msg = "oversubscribed dynamic bit lengths tree";
+  else if (r == Z_BUF_ERROR)
+  {
+    inflate_trees_free(*tb, z);
+    z->msg = "incomplete dynamic bit lengths tree";
+    r = Z_DATA_ERROR;
+  }
+  return r;
+}
+
+
+local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
+uInt nl;                /* number of literal/length codes */
+uInt nd;                /* number of distance codes */
+uIntf *c;               /* that many (total) code lengths */
+uIntf *bl;              /* literal desired/actual bit depth */
+uIntf *bd;              /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+z_stream *z;            /* for zfree function */
+{
+  int r;
+
+  /* build literal/length tree */
+  if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = "oversubscribed literal/length tree";
+    else if (r == Z_BUF_ERROR)
+    {
+      inflate_trees_free(*tl, z);
+      z->msg = "incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    return r;
+  }
+
+  /* build distance tree */
+  if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = "oversubscribed literal/length tree";
+    else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+      r = Z_OK;
+    }
+#else
+      inflate_trees_free(*td, z);
+      z->msg = "incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    inflate_trees_free(*tl, z);
+    return r;
+#endif
+  }
+
+  /* done */
+  return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+local int fixed_lock = 0;
+local int fixed_built = 0;
+#define FIXEDH 530      /* number of hufts used by fixed tables */
+local uInt fixed_left = FIXEDH;
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+
+
+local voidpf falloc(q, n, s)
+voidpf q;        /* opaque pointer (not used) */
+uInt n;         /* number of items */
+uInt s;         /* size of item */
+{
+  Assert(s == sizeof(inflate_huft) && n <= fixed_left,
+         "inflate_trees falloc overflow");
+  if (q) s++; /* to make some compilers happy */
+  fixed_left -= n;
+  return (voidpf)(fixed_mem + fixed_left);
+}
+
+
+local void ffree(q, p, n)
+voidpf q;
+voidpf p;
+uInt n;
+{
+  Assert(0, "inflate_trees ffree called!");
+  if (q) q = p; /* to make some compilers happy */
+}
+
+
+local int inflate_trees_fixed(bl, bd, tl, td)
+uIntf *bl;               /* literal desired/actual bit depth */
+uIntf *bd;               /* distance desired/actual bit depth */
+inflate_huft * FAR *tl;  /* literal/length tree result */
+inflate_huft * FAR *td;  /* distance tree result */
+{
+  /* build fixed tables if not built already--lock out other instances */
+  while (++fixed_lock > 1)
+    fixed_lock--;
+  if (!fixed_built)
+  {
+    int k;              /* temporary variable */
+    unsigned c[288];    /* length list for huft_build */
+    z_stream z;         /* for falloc function */
+
+    /* set up fake z_stream for memory routines */
+    z.zalloc = falloc;
+    z.zfree = ffree;
+    z.opaque = Z_NULL;
+
+    /* literal table */
+    for (k = 0; k < 144; k++)
+      c[k] = 8;
+    for (; k < 256; k++)
+      c[k] = 9;
+    for (; k < 280; k++)
+      c[k] = 7;
+    for (; k < 288; k++)
+      c[k] = 8;
+    fixed_bl = 7;
+    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
+
+    /* distance table */
+    for (k = 0; k < 30; k++)
+      c[k] = 5;
+    fixed_bd = 5;
+    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
+
+    /* done */
+    fixed_built = 1;
+  }
+  fixed_lock--;
+  *bl = fixed_bl;
+  *bd = fixed_bd;
+  *tl = fixed_tl;
+  *td = fixed_td;
+  return Z_OK;
+}
+
+
+local int inflate_trees_free(t, z)
+inflate_huft *t;        /* table to free */
+z_stream *z;            /* for zfree function */
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+   list of the tables it made, with the links in a dummy first entry of
+   each table. */
+{
+  register inflate_huft *p, *q;
+
+  /* Go through linked list, freeing from the malloced (t[-1]) address. */
+  p = t;
+  while (p != Z_NULL)
+  {
+    q = (--p)->next;
+    ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
+    p = q;
+  } 
+  return Z_OK;
+}
+
+/*+++++*/
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+  /* mode */
+  enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+      START,    /* x: set up for LEN */
+      LEN,      /* i: get length/literal/eob next */
+      LENEXT,   /* i: getting length extra (have base) */
+      DIST,     /* i: get distance next */
+      DISTEXT,  /* i: getting distance extra */
+      COPY,     /* o: copying bytes in window, waiting for space */
+      LIT,      /* o: got literal, waiting for output space */
+      WASH,     /* o: got eob, possibly still output waiting */
+      END,      /* x: got eob and all data flushed */
+      BADCODE}  /* x: got error */
+    mode;               /* current inflate_codes mode */
+
+  /* mode dependent information */
+  uInt len;
+  union {
+    struct {
+      inflate_huft *tree;       /* pointer into tree */
+      uInt need;                /* bits needed */
+    } code;             /* if LEN or DIST, where in tree */
+    uInt lit;           /* if LIT, literal */
+    struct {
+      uInt get;                 /* bits to get for extra */
+      uInt dist;                /* distance back to copy from */
+    } copy;             /* if EXT or COPY, where and how much */
+  } sub;                /* submode */
+
+  /* mode independent information */
+  Byte lbits;           /* ltree bits decoded per branch */
+  Byte dbits;           /* dtree bits decoder per branch */
+  inflate_huft *ltree;          /* literal/length/eob tree */
+  inflate_huft *dtree;          /* distance tree */
+
+};
+
+
+local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl, *td;
+z_stream *z;
+{
+  inflate_codes_statef *c;
+
+  if ((c = (inflate_codes_statef *)
+       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+  {
+    c->mode = START;
+    c->lbits = (Byte)bl;
+    c->dbits = (Byte)bd;
+    c->ltree = tl;
+    c->dtree = td;
+    Tracev((stderr, "inflate:       codes new\n"));
+  }
+  return c;
+}
+
+
+local int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+  uInt j;               /* temporary storage */
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  Bytef *f;             /* pointer to copy strings from */
+  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input and output based on current state */
+  while (1) switch (c->mode)
+  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+    case START:         /* x: set up for LEN */
+#ifndef SLOW
+      if (m >= 258 && n >= 10)
+      {
+        UPDATE
+        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+        LOAD
+        if (r != Z_OK)
+        {
+          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+          break;
+        }
+      }
+#endif /* !SLOW */
+      c->sub.code.need = c->lbits;
+      c->sub.code.tree = c->ltree;
+      c->mode = LEN;
+    case LEN:           /* i: get length/literal/eob next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e == 0)               /* literal */
+      {
+        c->sub.lit = t->base;
+        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                 "inflate:         literal '%c'\n" :
+                 "inflate:         literal 0x%02x\n", t->base));
+        c->mode = LIT;
+        break;
+      }
+      if (e & 16)               /* length */
+      {
+        c->sub.copy.get = e & 15;
+        c->len = t->base;
+        c->mode = LENEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t->next;
+        break;
+      }
+      if (e & 32)               /* end of block */
+      {
+        Tracevv((stderr, "inflate:         end of block\n"));
+        c->mode = WASH;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = "invalid literal/length code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case LENEXT:        /* i: getting length extra (have base) */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->len += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      c->sub.code.need = c->dbits;
+      c->sub.code.tree = c->dtree;
+      Tracevv((stderr, "inflate:         length %u\n", c->len));
+      c->mode = DIST;
+    case DIST:          /* i: get distance next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e & 16)               /* distance */
+      {
+        c->sub.copy.get = e & 15;
+        c->sub.copy.dist = t->base;
+        c->mode = DISTEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t->next;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = "invalid distance code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case DISTEXT:       /* i: getting distance extra */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->sub.copy.dist += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
+      c->mode = COPY;
+    case COPY:          /* o: copying bytes in window, waiting for space */
+#ifndef __TURBOC__ /* Turbo C bug for following expression */
+      f = (uInt)(q - s->window) < c->sub.copy.dist ?
+          s->end - (c->sub.copy.dist - (q - s->window)) :
+          q - c->sub.copy.dist;
+#else
+      f = q - c->sub.copy.dist;
+      if ((uInt)(q - s->window) < c->sub.copy.dist)
+        f = s->end - (c->sub.copy.dist - (q - s->window));
+#endif
+      while (c->len)
+      {
+        NEEDOUT
+        OUTBYTE(*f++)
+        if (f == s->end)
+          f = s->window;
+        c->len--;
+      }
+      c->mode = START;
+      break;
+    case LIT:           /* o: got literal, waiting for output space */
+      NEEDOUT
+      OUTBYTE(c->sub.lit)
+      c->mode = START;
+      break;
+    case WASH:          /* o: got eob, possibly more output */
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      c->mode = END;
+    case END:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADCODE:       /* x: got error */
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+local void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_stream *z;
+{
+  ZFREE(z, c, sizeof(struct inflate_codes_state));
+  Tracev((stderr, "inflate:       codes free\n"));
+}
+
+/*+++++*/
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* copy as much as possible from the sliding window to the output area */
+local int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+  uInt n;
+  Bytef *p, *q;
+
+  /* local copies of source and destination pointers */
+  p = z->next_out;
+  q = s->read;
+
+  /* compute number of bytes to copy as far as end of window */
+  n = (uInt)((q <= s->write ? s->write : s->end) - q);
+  if (n > z->avail_out) n = z->avail_out;
+  if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+  /* update counters */
+  z->avail_out -= n;
+  z->total_out += n;
+
+  /* update check information */
+  if (s->checkfn != Z_NULL)
+    s->check = (*s->checkfn)(s->check, q, n);
+
+  /* copy as far as end of window */
+  zmemcpy(p, q, n);
+  p += n;
+  q += n;
+
+  /* see if more to copy at beginning of window */
+  if (q == s->end)
+  {
+    /* wrap pointers */
+    q = s->window;
+    if (s->write == s->end)
+      s->write = s->window;
+
+    /* compute bytes to copy */
+    n = (uInt)(s->write - q);
+    if (n > z->avail_out) n = z->avail_out;
+    if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+    /* update counters */
+    z->avail_out -= n;
+    z->total_out += n;
+
+    /* update check information */
+    if (s->checkfn != Z_NULL)
+      s->check = (*s->checkfn)(s->check, q, n);
+
+    /* copy */
+    zmemcpy(p, q, n);
+    p += n;
+    q += n;
+  }
+
+  /* update pointers */
+  z->next_out = p;
+  s->read = q;
+
+  /* done */
+  return r;
+}
+
+
+/*+++++*/
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
+
+/* Called with number of bytes left to write in window at least 258
+   (the maximum string length) and number of input bytes available
+   at least ten.  The ten bytes are six bytes for the longest length/
+   distance pair plus four bytes for overloading the bit buffer. */
+
+local int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl, *td;
+inflate_blocks_statef *s;
+z_stream *z;
+{
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  uInt ml;              /* mask for literal/length tree */
+  uInt md;              /* mask for distance tree */
+  uInt c;               /* bytes to copy */
+  uInt d;               /* distance back to copy from */
+  Bytef *r;             /* copy source pointer */
+
+  /* load input, output, bit values */
+  LOAD
+
+  /* initialize masks */
+  ml = inflate_mask[bl];
+  md = inflate_mask[bd];
+
+  /* do until not enough input or output space for fast loop */
+  do {                          /* assume called with m >= 258 && n >= 10 */
+    /* get literal/length code */
+    GRABBITS(20)                /* max bits for literal/length code */
+    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+    {
+      DUMPBITS(t->bits)
+      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                "inflate:         * literal '%c'\n" :
+                "inflate:         * literal 0x%02x\n", t->base));
+      *q++ = (Byte)t->base;
+      m--;
+      continue;
+    }
+    do {
+      DUMPBITS(t->bits)
+      if (e & 16)
+      {
+        /* get extra bits for length */
+        e &= 15;
+        c = t->base + ((uInt)b & inflate_mask[e]);
+        DUMPBITS(e)
+        Tracevv((stderr, "inflate:         * length %u\n", c));
+
+        /* decode distance base of block to copy */
+        GRABBITS(15);           /* max bits for distance code */
+        e = (t = td + ((uInt)b & md))->exop;
+        do {
+          DUMPBITS(t->bits)
+          if (e & 16)
+          {
+            /* get extra bits to add to distance base */
+            e &= 15;
+            GRABBITS(e)         /* get extra bits (up to 13) */
+            d = t->base + ((uInt)b & inflate_mask[e]);
+            DUMPBITS(e)
+            Tracevv((stderr, "inflate:         * distance %u\n", d));
+
+            /* do the copy */
+            m -= c;
+            if ((uInt)(q - s->window) >= d)     /* offset before dest */
+            {                                   /*  just copy */
+              r = q - d;
+              *q++ = *r++;  c--;        /* minimum count is three, */
+              *q++ = *r++;  c--;        /*  so unroll loop a little */
+            }
+            else                        /* else offset after destination */
+            {
+              e = d - (q - s->window);  /* bytes from offset to end */
+              r = s->end - e;           /* pointer to offset */
+              if (c > e)                /* if source crosses, */
+              {
+                c -= e;                 /* copy to end of window */
+                do {
+                  *q++ = *r++;
+                } while (--e);
+                r = s->window;          /* copy rest from start of window */
+              }
+            }
+            do {                        /* copy all or what's left */
+              *q++ = *r++;
+            } while (--c);
+            break;
+          }
+          else if ((e & 64) == 0)
+            e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
+          else
+          {
+            z->msg = "invalid distance code";
+            UNGRAB
+            UPDATE
+            return Z_DATA_ERROR;
+          }
+        } while (1);
+        break;
+      }
+      if ((e & 64) == 0)
+      {
+        if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
+        {
+          DUMPBITS(t->bits)
+          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                    "inflate:         * literal '%c'\n" :
+                    "inflate:         * literal 0x%02x\n", t->base));
+          *q++ = (Byte)t->base;
+          m--;
+          break;
+        }
+      }
+      else if (e & 32)
+      {
+        Tracevv((stderr, "inflate:         * end of block\n"));
+        UNGRAB
+        UPDATE
+        return Z_STREAM_END;
+      }
+      else
+      {
+        z->msg = "invalid literal/length code";
+        UNGRAB
+        UPDATE
+        return Z_DATA_ERROR;
+      }
+    } while (1);
+  } while (m >= 258 && n >= 10);
+
+  /* not enough input or output--restore pointers and return */
+  UNGRAB
+  UPDATE
+  return Z_OK;
+}
+
+
+/*+++++*/
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
+
+char *zlib_version = ZLIB_VERSION;
+
+char *z_errmsg[] = {
+"stream end",          /* Z_STREAM_END    1 */
+"",                    /* Z_OK            0 */
+"file error",          /* Z_ERRNO        (-1) */
+"stream error",        /* Z_STREAM_ERROR (-2) */
+"data error",          /* Z_DATA_ERROR   (-3) */
+"insufficient memory", /* Z_MEM_ERROR    (-4) */
+"buffer error",        /* Z_BUF_ERROR    (-5) */
+""};
+
+
+/*+++++*/
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf)  {s1 += *buf++; s2 += s1;}
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+#define DO16(buf) DO8(buf); DO8(buf);
+
+/* ========================================================================= */
+uLong adler32(adler, buf, len)
+    uLong adler;
+    Bytef *buf;
+    uInt len;
+{
+    unsigned long s1 = adler & 0xffff;
+    unsigned long s2 = (adler >> 16) & 0xffff;
+    int k;
+
+    if (buf == Z_NULL) return 1L;
+
+    while (len > 0) {
+        k = len < NMAX ? len : NMAX;
+        len -= k;
+        while (k >= 16) {
+            DO16(buf);
+            k -= 16;
+        }
+        if (k != 0) do {
+            DO1(buf);
+        } while (--k);
+        s1 %= BASE;
+        s2 %= BASE;
+    }
+    return (s2 << 16) | s1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/boot/zlib.h linux/arch/ppc64/boot/zlib.h
--- linux.orig/arch/ppc64/boot/zlib.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/boot/zlib.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,432 @@
+/*		*/
+
+/*
+ * This file is derived from zlib.h and zconf.h from the zlib-0.95
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets.
+ */
+
+/*
+ *  ==FILEVERSION 960122==
+ *
+ * This marker is used by the Linux installation script to determine
+ * whether an up-to-date version of this file is already installed.
+ */
+
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 0.95, Aug 16th, 1995.
+
+  Copyright (C) 1995 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  gzip@prep.ai.mit.edu    madler@alumni.caltech.edu
+ */
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+/* #include "zconf.h" */	/* included directly here */
+
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
+
+/*
+     The library does not install any signal handler. It is recommended to
+  add at least a handler for SIGSEGV when decompressing; the library checks
+  the consistency of the input data whenever possible but may go nuts
+  for some forms of corrupted input.
+ */
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
+ * at addresses which are not a multiple of their size.
+ * Under DOS, -DFAR=far or -DFAR=__far may be needed.
+ */
+
+#ifndef STDC
+#  if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
+#    define STDC
+#  endif
+#endif
+
+#ifdef	__MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
+#  include <unix.h>
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            1 << (windowBits+2)   +  1 << (memLevel+9)
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+typedef unsigned char  Byte;  /* 8 bits */
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+typedef Byte FAR Bytef;
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void FAR *voidpf;
+   typedef void     *voidp;
+#else
+   typedef Byte FAR *voidpf;
+   typedef Byte     *voidp;
+#endif
+
+/* end of original zconf.h */
+
+#define ZLIB_VERSION "0.95P"
+
+/* 
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms may be added later and will have the same
+  stream interface.
+
+     For compression the application must provide the output buffer and
+  may optionally provide the input buffer for optimization. For decompression,
+  the application must provide the input buffer and may optionally provide
+  the output buffer for optimization.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address, uInt nbytes));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidp      opaque;  /* private data object passed to zalloc and zfree */
+
+    Byte     data_type; /* best guess about the data type: ascii or binary */
+
+} z_stream;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_FULL_FLUSH    2
+#define Z_SYNC_FLUSH    3 /* experimental: partial_flush + byte align */
+#define Z_FINISH        4
+#define Z_PACKET_FLUSH	5
+/* See deflate() below for the usage of these constants */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+/* error codes for the compression/decompression functions */
+
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Used to set the data_type field */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+extern char *zlib_version;
+/* The application can compare zlib_version and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+ */
+
+                        /* basic functions */
+
+extern int inflateInit OF((z_stream *strm));
+/* 
+     Initializes the internal stream state for decompression. The fields
+   zalloc and zfree must be initialized before by the caller.  If zalloc and
+   zfree are set to Z_NULL, inflateInit updates them to use default allocation
+   functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory.  msg is set to null if there is no error message.
+   inflateInit does not perform any decompression: this will be done by
+   inflate().
+*/
+
+
+extern int inflate OF((z_stream *strm, int flush));
+/*
+  Performs one or both of the following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() always provides as much output as possible
+    (until there is no more input data or no more space in the output buffer).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate().
+
+    If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
+  inflate flushes as much output as possible to the output buffer. The
+  flushing behavior of inflate is not specified for values of the flush
+  parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
+  current implementation actually flushes as much output as possible
+  anyway.  For Z_PACKET_FLUSH, inflate checks that once all the input data
+  has been consumed, it is expecting to see the length field of a stored
+  block; if not, it returns Z_DATA_ERROR.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster routine
+  may be used for the single inflate() call.
+
+    inflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if the end of the
+  compressed data has been reached and all uncompressed output has been
+  produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
+  the stream structure was inconsistent (for example if next_in or next_out
+  was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
+  progress is possible or if there was not enough room in the output buffer
+  when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
+  call inflateSync to look for a good compression block.  */
+
+
+extern int inflateEnd OF((z_stream *strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* advanced functions */
+
+extern int inflateInit2 OF((z_stream *strm,
+                            int  windowBits));
+/*   
+     This is another version of inflateInit with more compression options. The
+   fields next_out, zalloc and zfree must be initialized before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library (the value 16 will be allowed soon). The
+   default value is 15 if inflateInit is used instead. If a compressed stream
+   with a larger window size is given as input, inflate() will return with
+   the error code Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     If next_out is not null, the library will use this buffer for the history
+   buffer; the buffer must either be large enough to hold the entire output
+   data, or have at least 1<<windowBits bytes.  If next_out is null, the
+   library will allocate its own buffer (and leave next_out null). next_in
+   need not be provided here but must be provided by the application for the
+   next call of inflate().
+
+     If the history buffer is provided by the application, next_out must
+   never be changed by the application since the decompressor maintains
+   history information inside this buffer from call to call; the application
+   can only reset next_out to the beginning of the history buffer when
+   avail_out is zero and all output has been consumed.
+
+      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
+   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
+   windowBits < 8). msg is set to null if there is no error message.
+   inflateInit2 does not perform any decompression: this will be done by
+   inflate().
+*/
+
+extern int inflateSync OF((z_stream *strm));
+/* 
+    Skips invalid compressed data until the special marker (see deflate()
+  above) can be found, or until all available input is skipped. No output
+  is provided.
+
+    inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no marker has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+extern int inflateReset OF((z_stream *strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+extern int inflateIncomp OF((z_stream *strm));
+/*
+     This function adds the data at next_in (avail_in bytes) to the output
+   history without performing any output.  There must be no pending output,
+   and the decompressor must be expecting to see the start of a block.
+   Calling this function is equivalent to decompressing a stored block
+   containing the data at next_in (except that the data is not output).
+*/
+
+                        /* checksum functions */
+
+/*
+     This function is not related to compression but is exported
+   anyway because it might be useful in applications using the
+   compression library.
+*/
+
+extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
+
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+#ifndef _Z_UTIL_H
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+#endif /* _ZLIB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/config.in linux/arch/ppc64/config.in
--- linux.orig/arch/ppc64/config.in	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/config.in	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,241 @@
+# 
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+define_bool CONFIG_UID16 n
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
+define_bool CONFIG_GENERIC_BUST_SPINLOCK n
+define_bool CONFIG_GENERIC_ISA_DMA y
+define_bool CONFIG_HAVE_DEC_LOCK y
+
+mainmenu_name "64 bit PowerPC Linux Kernel Configuration"
+
+mainmenu_option next_comment
+   comment 'Code maturity level options'
+   bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'Platform support'
+define_bool CONFIG_PPC y
+define_bool CONFIG_PPC64 y
+define_bool CONFIG_SERIAL_CONSOLE y
+
+choice 'Machine Type'	\
+	"pSeries       		CONFIG_PPC_PSERIES \
+	 iSeries                CONFIG_PPC_ISERIES" CONFIG_PPC_PSERIES
+
+bool 'Symmetric multi-processing support' CONFIG_SMP
+if [ "$CONFIG_SMP" = "y" ]; then
+  bool '  Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
+  if [ "$CONFIG_PPC_PSERIES" = "y" ]; then
+    bool '  Hardware multithreading' CONFIG_HMT
+  fi
+fi
+if [ "$CONFIG_PPC_ISERIES" = "y" ]; then
+   define_bool CONFIG_MSCHUNKS y
+else
+bool 'MsChunks Physical to Absolute address translation support' CONFIG_MSCHUNKS
+fi
+
+
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+define_bool CONFIG_ISA n
+define_bool CONFIG_SBUS n
+define_bool CONFIG_MCA n
+define_bool CONFIG_EISA n
+define_bool CONFIG_PCI y
+
+bool 'Networking support' CONFIG_NET
+bool 'Sysctl support' CONFIG_SYSCTL
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+
+# only elf supported, a.out is not -- Cort
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   define_bool CONFIG_KCORE_ELF y
+fi
+
+bool 'Kernel Support for 64 bit ELF binaries' CONFIG_BINFMT_ELF
+
+tristate 'Kernel support for 32 bit binaries' CONFIG_BINFMT_ELF32
+
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+source drivers/pci/Config.in
+
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ]; then
+   source drivers/pcmcia/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+fi
+
+source drivers/parport/Config.in
+
+if [ "$CONFIG_PPC_ISERIES" != "y" ]; then
+   bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
+   bool 'Support for frame buffer devices' CONFIG_FB
+
+   bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
+fi
+
+endmenu
+
+source drivers/mtd/Config.in
+source drivers/pnp/Config.in
+source drivers/block/Config.in
+source drivers/md/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+  define_bool CONFIG_BLK_DEV_IDE_MODES n
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'SCSI support'
+tristate 'SCSI support' CONFIG_SCSI
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+source drivers/ieee1394/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+source net/ax25/Config.in
+
+source net/irda/Config.in
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+
+tristate 'ISDN support' CONFIG_ISDN
+if [ "$CONFIG_ISDN" != "n" ]; then
+   source drivers/isdn/Config.in
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+   source drivers/cdrom/Config.in
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Console drivers'
+source drivers/video/Config.in
+endmenu
+
+source drivers/input/Config.in
+
+if [ "$CONFIG_PPC_ISERIES" = "y" ]; then
+mainmenu_option next_comment
+comment 'iSeries device drivers'
+   dep_tristate 'iSeries Virtual Console Support' CONFIG_VIOCONS $CONFIG_PPC_ISERIES
+   dep_tristate 'iSeries Virtual I/O disk support' CONFIG_VIODASD $CONFIG_PPC_ISERIES
+   if [ "$CONFIG_VIODASD" = "y" -o "$CONFIG_VIODASD" = "m" ]; then
+      bool 'iSeries Virtual disk IDE emulation' CONFIG_VIODASD_IDE
+   fi
+   dep_tristate 'iSeries Virtual I/O CD support' CONFIG_VIOCD $CONFIG_PPC_ISERIES
+   if [ "$CONFIG_VIOCD" = "y" -o "$CONFIG_VIOCD" = "m" ]; then
+      bool 'iSeries Virtual CD Aztech emulation' CONFIG_VIOCD_AZTECH
+   fi
+   dep_tristate 'iSeries Virtual Tape Support' CONFIG_VIOTAPE  $CONFIG_PPC_ISERIES
+   dep_tristate 'iSeries Virtual Ethernet driver support' CONFIG_VETH $CONFIG_PPC_ISERIES
+endmenu
+fi
+
+if [ "$CONFIG_VIOCONS" = "n" ]; then
+   if [ "$CONFIG_VIODASD" = "n" ]; then
+      if [ "$CONFIG_VIOTAPE" = "n" ]; then
+         if [ "$CONFIG_VIOCD" = "n" ]; then
+		    define_bool CONFIG_VIOPATH n
+		 else
+		    define_bool CONFIG_VIOPATH y
+         fi
+	  else
+	     define_bool CONFIG_VIOPATH y
+      fi
+   else
+      define_bool CONFIG_VIOPATH y
+   fi
+else
+   define_bool CONFIG_VIOPATH y
+fi
+
+if [ "$CONFIG_VIOCD" = "y" ]; then
+   define_bool CONFIG_CD_NO_IDESCSI y
+fi
+
+source drivers/char/Config.in
+source fs/Config.in
+
+mainmenu_option next_comment
+comment 'Sound'
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/dmasound/Config.in
+   source drivers/sound/Config.in
+fi
+
+endmenu
+
+source drivers/usb/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Include kgdb kernel debugger' CONFIG_KGDB
+bool 'Include xmon kernel debugger' CONFIG_XMON
+#bool 'Include kdb kernel debugger' CONFIG_KDB
+#if [ "$CONFIG_KDB" = "y" ]; then
+#  bool '  KDB off by default' CONFIG_KDB_OFF
+#  define_bool CONFIG_KALLSYMS y
+#fi
+bool 'Include PPCDBG realtime debugging' CONFIG_PPCDBG
+endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/configs/iSeries_devfs_defconfig linux/arch/ppc64/configs/iSeries_devfs_defconfig
--- linux.orig/arch/ppc64/configs/iSeries_devfs_defconfig	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/configs/iSeries_devfs_defconfig	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,699 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_PPC_PSERIES is not set
+CONFIG_PPC_ISERIES=y
+CONFIG_SMP=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_MSCHUNKS=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_EISA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_ELF32=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# CONFIG_PNPBIOS 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
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_BLK_DEV_LVM=m
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK 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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+# 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
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD 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=y
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=m
+
+#
+# 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=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 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=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_OAKNET is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I 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=y
+CONFIG_IBMOL=m
+# CONFIG_IBMLS is not set
+# CONFIG_TMS380TR 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# iSeries device drivers
+#
+CONFIG_VIOCONS=y
+CONFIG_VIODASD=y
+# CONFIG_VIODASD_IDE is not set
+CONFIG_VIOCD=m
+# CONFIG_VIOCD_AZTECH is not set
+CONFIG_VIOTAPE=m
+CONFIG_VETH=y
+CONFIG_VIOPATH=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=1024
+# CONFIG_HVC_CONSOLE is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C 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_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
+# CONFIG_MWAVE 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=y
+# CONFIG_REISERFS_CHECK 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 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=y
+CONFIG_JOLIET=y
+# CONFIG_MINIX_FS is not set
+# CONFIG_JFS_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=y
+CONFIG_DEVFS_MOUNT=y
+# 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_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# 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=y
+# 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 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+# 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
+
+#
+# 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
+#
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+# CONFIG_PPCDBG is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig linux/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig
--- linux.orig/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,724 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_PPC_PSERIES is not set
+CONFIG_PPC_ISERIES=y
+CONFIG_SMP=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_MSCHUNKS=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_EISA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_ELF32=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# CONFIG_PNPBIOS 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
+CONFIG_BLK_DEV_RAM_SIZE=64000
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+# CONFIG_MD_MULTIPATH is not set
+CONFIG_BLK_DEV_LVM=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_ROUTE_LARGE_TABLES=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+# 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
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD 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=y
+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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_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_CPQFCTS 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 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=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_OAKNET is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL 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 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I 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=y
+CONFIG_IBMOL=m
+# CONFIG_IBMLS is not set
+# CONFIG_TMS380TR 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+CONFIG_CD_NO_IDESCSI=y
+# CONFIG_AZTCD is not set
+# CONFIG_GSCD is not set
+# CONFIG_SBPCD is not set
+# CONFIG_MCD is not set
+# CONFIG_MCDX is not set
+# CONFIG_OPTCD is not set
+# CONFIG_CM206 is not set
+# CONFIG_SJCD is not set
+# CONFIG_ISP16_CDI is not set
+# CONFIG_CDU31A is not set
+# CONFIG_CDU535 is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# iSeries device drivers
+#
+CONFIG_VIOCONS=y
+CONFIG_VIODASD=y
+CONFIG_VIODASD_IDE=y
+CONFIG_VIOCD=m
+# CONFIG_VIOCD_AZTECH is not set
+CONFIG_VIOTAPE=m
+CONFIG_VETH=y
+CONFIG_VIOPATH=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_ICOM=m
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=1024
+# CONFIG_HVC_CONSOLE is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C 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_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
+# CONFIG_MWAVE is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK 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 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=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_MINIX_FS is not set
+# CONFIG_JFS_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_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=y
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_NCP_FS=y
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+
+#
+# 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_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=y
+# 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=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+# 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
+
+#
+# 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
+#
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# 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 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 Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+# CONFIG_PPCDBG is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/configs/pSeries_defconfig linux/arch/ppc64/configs/pSeries_defconfig
--- linux.orig/arch/ppc64/configs/pSeries_defconfig	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/configs/pSeries_defconfig	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,802 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_PPC_PSERIES=y
+# CONFIG_PPC_ISERIES is not set
+CONFIG_SMP=y
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_HMT is not set
+# CONFIG_MSCHUNKS is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_EISA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+CONFIG_PROC_DEVICETREE=y
+
+#
+# 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=y
+# 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=y
+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=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+# 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
+
+#
+# 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 is not set
+# 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
+
+#
+# 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_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# 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=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_CPQFCTS 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_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=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 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=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=y
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# 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=y
+CONFIG_IBMOL=y
+# CONFIG_IBMLS is not set
+# CONFIG_TMS380TR 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_G450 is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 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
+CONFIG_VIOPATH=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_HVC_CONSOLE=y
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC 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
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_REISERFS_FS=y
+# 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=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG 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 is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG 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=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=y
+# 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 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 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 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# 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 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_IPAQ 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_KLSI 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
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+CONFIG_XMON=y
+CONFIG_PPCDBG=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/defconfig linux/arch/ppc64/defconfig
--- linux.orig/arch/ppc64/defconfig	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/defconfig	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,802 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_PPC_PSERIES=y
+# CONFIG_PPC_ISERIES is not set
+CONFIG_SMP=y
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_HMT is not set
+# CONFIG_MSCHUNKS is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_EISA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+CONFIG_PROC_DEVICETREE=y
+
+#
+# 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=y
+# 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=y
+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=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+# 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
+
+#
+# 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 is not set
+# 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
+
+#
+# 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_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# 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=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_CPQFCTS 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_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=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 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=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# 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
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=y
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# 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=y
+CONFIG_IBMOL=y
+# CONFIG_IBMLS is not set
+# CONFIG_TMS380TR 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_G450 is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 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
+CONFIG_VIOPATH=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_HVC_CONSOLE=y
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD 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 is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC 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
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_REISERFS_FS=y
+# 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=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG 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 is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG 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=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=y
+# 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 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 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 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI 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
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# 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
+#
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# 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 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_IPAQ 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_KLSI 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
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+CONFIG_XMON=y
+CONFIG_PPCDBG=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/HvCall.c linux/arch/ppc64/kernel/HvCall.c
--- linux.orig/arch/ppc64/kernel/HvCall.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/HvCall.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,115 @@
+/*
+ * HvCall.c
+ * Copyright (C) 2001  Mike Corrigan IBM 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.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/iSeries/HvCall.h>
+#ifndef  _HVCALLSC_H
+#include <asm/iSeries/HvCallSc.h>
+#endif
+#include <asm/iSeries/LparData.h>
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+
+/*=====================================================================
+ * Note that this call takes at MOST one page worth of data
+ */
+int HvCall_readLogBuffer(HvLpIndex lpIndex, void *buffer, u64 bufLen)
+{
+	struct HvLpBufferList *bufList;
+	u64 bytesLeft = bufLen;
+	u64 leftThisPage;
+	u64 curPtr = virt_to_absolute( (unsigned long) buffer );
+	u64 retVal;
+	int npages;
+	int i;
+
+	npages = 0;
+	while (bytesLeft) {
+		npages++;
+		leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
+
+		if (leftThisPage > bytesLeft)
+			bytesLeft = 0;
+		else
+			bytesLeft -= leftThisPage;
+
+		curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
+	}
+
+	if (npages == 0)
+		return 0;
+
+	bufList = (struct HvLpBufferList *)
+		kmalloc(npages * sizeof(struct HvLpBufferList), GFP_ATOMIC);
+	bytesLeft = bufLen;
+	curPtr = virt_to_absolute( (unsigned long) buffer );
+	for(i=0; i<npages; i++) {
+		bufList[i].addr = curPtr;
+      
+		leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
+
+		if (leftThisPage > bytesLeft) {
+			bufList[i].len = bytesLeft;
+			bytesLeft = 0;
+		} else {
+			bufList[i].len = leftThisPage;
+			bytesLeft -= leftThisPage;
+		}
+
+		curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
+	}
+
+
+	retVal = HvCall3(HvCallBaseReadLogBuffer, lpIndex,
+			 virt_to_absolute((unsigned long)bufList), bufLen);
+
+	kfree(bufList);
+
+	return (int)retVal;
+}
+
+/*=====================================================================
+ */
+void HvCall_writeLogBuffer(const void *buffer, u64 bufLen)
+{
+	struct HvLpBufferList bufList;
+	u64 bytesLeft = bufLen;
+	u64 leftThisPage;
+	u64 curPtr = virt_to_absolute( (unsigned long) buffer );
+
+	while (bytesLeft) {
+		bufList.addr = curPtr;
+      
+		leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
+
+		if (leftThisPage > bytesLeft) {
+			bufList.len = bytesLeft;
+			bytesLeft = 0;
+		} else {
+			bufList.len = leftThisPage;
+			bytesLeft -= leftThisPage;
+		}
+
+		curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
+	}
+
+
+	HvCall2(HvCallBaseWriteLogBuffer,
+		virt_to_absolute((unsigned long)&bufList), bufLen);
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/HvLpConfig.c linux/arch/ppc64/kernel/HvLpConfig.c
--- linux.orig/arch/ppc64/kernel/HvLpConfig.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/HvLpConfig.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,28 @@
+/*
+ * HvLpConfig.c
+ * Copyright (C) 2001  Kyle A. Lucke, IBM 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
+ */
+
+#ifndef _HVLPCONFIG_H
+#include <asm/iSeries/HvLpConfig.h>
+#endif
+
+HvLpIndex HvLpConfig_getLpIndex_outline(void)
+{
+	return HvLpConfig_getLpIndex();
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/HvLpEvent.c linux/arch/ppc64/kernel/HvLpEvent.c
--- linux.orig/arch/ppc64/kernel/HvLpEvent.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/HvLpEvent.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2001 Mike Corrigan IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <asm/system.h>
+#include <asm/iSeries/HvLpEvent.h>
+#include <asm/iSeries/HvCallEvent.h>
+#include <asm/iSeries/LparData.h>
+
+/* Array of LpEvent handler functions */
+LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
+
+/* Register a handler for an LpEvent type */
+
+int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler )
+{
+	int rc = 1;
+	if ( eventType < HvLpEvent_Type_NumTypes ) {
+		lpEventHandler[eventType] = handler;
+		rc = 0;
+	}
+	return rc;
+	
+}
+
+int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
+{
+	int rc = 1;
+	if ( eventType < HvLpEvent_Type_NumTypes ) {
+		if ( !lpEventHandlerPaths[eventType] ) {
+			lpEventHandler[eventType] = NULL;
+			rc = 0;
+		}
+	}
+	return rc;
+}
+
+/* (lpIndex is the partition index of the target partition.  
+ * needed only for VirtualIo, VirtualLan and SessionMgr.  Zero
+ * indicates to use our partition index - for the other types)
+ */
+int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
+{
+	int rc = 1;
+	if ( eventType < HvLpEvent_Type_NumTypes &&
+	     lpEventHandler[eventType] ) {
+		if ( lpIndex == 0 )
+			lpIndex = itLpNaca.xLpIndex;
+		HvCallEvent_openLpEventPath( lpIndex, eventType );
+		++lpEventHandlerPaths[eventType];
+		rc = 0;
+	}
+	return rc;
+}
+
+int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
+{
+	int rc = 1;
+	if ( eventType < HvLpEvent_Type_NumTypes &&
+	     lpEventHandler[eventType] &&
+	     lpEventHandlerPaths[eventType] ) {
+		if ( lpIndex == 0 )
+			lpIndex = itLpNaca.xLpIndex;
+		HvCallEvent_closeLpEventPath( lpIndex, eventType );
+		--lpEventHandlerPaths[eventType];
+		rc = 0;
+	}
+	return rc;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ItLpQueue.c linux/arch/ppc64/kernel/ItLpQueue.c
--- linux.orig/arch/ppc64/kernel/ItLpQueue.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ItLpQueue.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,170 @@
+/*
+ * ItLpQueue.c
+ * Copyright (C) 2001 Mike Corrigan  IBM 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.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/system.h>
+#include <asm/paca.h>
+#include <asm/iSeries/ItLpQueue.h>
+#include <asm/iSeries/HvLpEvent.h>
+#include <asm/iSeries/HvCallEvent.h>
+#include <asm/iSeries/LparData.h>
+
+static __inline__ int set_inUse( struct ItLpQueue * lpQueue )
+{
+	int t;
+	u32 * inUseP = &(lpQueue->xInUseWord);
+
+	__asm__ __volatile__("\n\
+1:	lwarx	%0,0,%2		\n\
+	cmpi	0,%0,0		\n\
+	li	%0,0		\n\
+	bne-	2f		\n\
+	addi	%0,%0,1		\n\
+	stwcx.	%0,0,%2		\n\
+	bne-	1b		\n\
+2:	eieio"
+	: "=&r" (t), "=m" (lpQueue->xInUseWord)
+	: "r" (inUseP), "m" (lpQueue->xInUseWord)
+	: "cc");
+
+	return t;
+}
+
+static __inline__ void clear_inUse( struct ItLpQueue * lpQueue )
+{
+	lpQueue->xInUseWord = 0;
+}
+
+/* Array of LpEvent handler functions */
+extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+unsigned long ItLpQueueInProcess = 0;
+
+struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue )
+{
+	struct HvLpEvent * nextLpEvent = 
+		(struct HvLpEvent *)lpQueue->xSlicCurEventPtr;
+	if ( nextLpEvent->xFlags.xValid ) {
+		/* rmb() needed only for weakly consistent machines (regatta) */
+		rmb();
+		/* Set pointer to next potential event */
+		lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 +
+				      LpEventAlign ) /
+				      LpEventAlign ) *
+				      LpEventAlign;
+		/* Wrap to beginning if no room at end */
+		if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr)
+			lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr;
+	}
+	else 
+		nextLpEvent = NULL;
+
+	return nextLpEvent;
+}
+
+int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue )
+{
+	int retval = 0;
+	struct HvLpEvent * nextLpEvent;
+	if ( lpQueue ) {
+		nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr;
+		retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending;
+	}
+	return retval;
+}
+
+void ItLpQueue_clearValid( struct HvLpEvent * event )
+{
+	/* Clear the valid bit of the event
+	 * Also clear bits within this event that might
+	 * look like valid bits (on 64-byte boundaries)
+   	 */
+	unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) /
+						 LpEventAlign ) - 1;
+	switch ( extra ) {
+	  case 3:
+	   ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0;
+	  case 2:
+	   ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0;
+	  case 1:
+	   ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0;
+	  case 0:
+	   ;	
+	}
+	mb();
+	event->xFlags.xValid = 0;
+}
+
+unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs )
+{
+	unsigned numIntsProcessed = 0;
+	struct HvLpEvent * nextLpEvent;
+
+	/* If we have recursed, just return */
+	if ( !set_inUse( lpQueue ) )
+		return 0;
+	
+	if (ItLpQueueInProcess == 0)
+		ItLpQueueInProcess = 1;
+	else
+		BUG();
+
+	for (;;) {
+		nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue );
+		if ( nextLpEvent ) {
+			/* Count events to return to caller
+			 * and count processed events in lpQueue
+ 			 */
+			++numIntsProcessed;
+			lpQueue->xLpIntCount++;		
+			/* Call appropriate handler here, passing 
+			 * a pointer to the LpEvent.  The handler
+			 * must make a copy of the LpEvent if it
+			 * needs it in a bottom half. (perhaps for
+			 * an ACK)
+			 *	
+			 *  Handlers are responsible for ACK processing 
+			 *
+			 * The Hypervisor guarantees that LpEvents will
+			 * only be delivered with types that we have
+			 * registered for, so no type check is necessary
+			 * here!
+  			 */
+			if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes )
+				lpQueue->xLpIntCountByType[nextLpEvent->xType]++;
+			if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes &&
+			     lpEventHandler[nextLpEvent->xType] ) 
+				lpEventHandler[nextLpEvent->xType](nextLpEvent, regs);
+			else
+				printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType );
+			
+			ItLpQueue_clearValid( nextLpEvent );
+		}
+		else 	/* No more valid events
+			 * If overflow events are pending
+			 * process them
+			 */
+			if ( lpQueue->xPlicOverflowIntPending ) {
+				HvCallEvent_getOverflowLpEvents( 
+						lpQueue->xIndex);
+			}
+			else	/* If nothing left then we are done */
+				break;
+	}
+
+	ItLpQueueInProcess = 0;
+	mb();
+	clear_inUse( lpQueue );
+
+	get_paca()->lpEvent_count += numIntsProcessed;
+
+	return numIntsProcessed;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/LparData.c linux/arch/ppc64/kernel/LparData.c
--- linux.orig/arch/ppc64/kernel/LparData.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/LparData.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,250 @@
+/* 
+ * Copyright 2001 Mike Corrigan, IBM Corp
+ *
+ * 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.
+ */
+#define __KERNEL__ 1
+#include <asm/types.h>
+#include <asm/page.h>
+#include <stddef.h>
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/init.h>
+#include <asm/naca.h>
+#include <asm/abs_addr.h>
+#include <asm/bitops.h>
+#include <asm/iSeries/ItLpNaca.h>
+#include <asm/iSeries/ItLpPaca.h>
+#include <asm/iSeries/ItLpRegSave.h>
+#include <asm/paca.h>
+#include <asm/iSeries/HvReleaseData.h>
+#include <asm/iSeries/LparMap.h>
+#include <asm/iSeries/ItVpdAreas.h>
+#include <asm/iSeries/ItIplParmsReal.h>
+#include <asm/iSeries/ItLpQueue.h>
+#include <asm/iSeries/IoHriProcessorVpd.h>
+#include <asm/iSeries/ItSpCommArea.h>
+
+extern char _start_boltedStacks[];
+
+/* The LparMap data is now located at offset 0x6000 in head.S
+ * It was put there so that the HvReleaseData could address it
+ * with a 32-bit offset as required by the iSeries hypervisor
+ *
+ * The Naca has a pointer to the ItVpdAreas.  The hypervisor finds
+ * the Naca via the HvReleaseData area.  The HvReleaseData has the
+ * offset into the Naca of the pointer to the ItVpdAreas.
+ */
+
+extern struct ItVpdAreas itVpdAreas;
+
+/* The LpQueue is used to pass event data from the hypervisor to
+ * the partition.  This is where I/O interrupt events are communicated.
+ * The ItLpQueue must be initialized (even though only to all zeros)
+ * If it were uninitialized (in .bss) it would get zeroed after the
+ * kernel gets control.  The hypervisor will have filled in some fields
+ * before the kernel gets control.  By initializing it we keep it out
+ * of the .bss
+ */
+
+struct ItLpQueue xItLpQueue = {};
+
+
+/* The HvReleaseData is the root of the information shared between 
+ * the hypervisor and Linux.  
+ */
+
+struct HvReleaseData hvReleaseData = {
+	0xc8a5d9c4,	/* desc = "HvRD" ebcdic */
+	sizeof(struct HvReleaseData),
+	offsetof(struct naca_struct, xItVpdAreas),
+	(struct naca_struct *)(KERNELBASE+0x4000), /* 64-bit Naca address */
+	0x6000,		/* offset of LparMap within loadarea (see head.S) */
+	0,
+	1,		/* tags inactive       */
+	0,		/* 64 bit              */
+	0,		/* shared processors   */
+	0,		/* HMT allowed         */
+	6,		/* TEMP: This allows non-GA driver */
+	4,		/* We are v5r2m0               */
+	3,		/* Min supported PLIC = v5r1m0 */
+	3,		/* Min usuable PLIC   = v5r1m0 */
+	{ 0xd3, 0x89, 0x95, 0xa4, /* "Linux 2.4   "*/
+	  0xa7, 0x40, 0xf2, 0x4b,
+	  0xf4, 0x4b, 0xf6, 0xf4 },
+	{0}  
+};
+
+extern void SystemReset_Iseries(void);
+extern void MachineCheck_Iseries(void);
+extern void DataAccess_Iseries(void);
+extern void InstructionAccess_Iseries(void);
+extern void HardwareInterrupt_Iseries(void);
+extern void Alignment_Iseries(void);
+extern void ProgramCheck_Iseries(void);
+extern void FPUnavailable_Iseries(void);
+extern void Decrementer_Iseries(void);
+extern void Trap_0a_Iseries(void);
+extern void Trap_0b_Iseries(void);
+extern void SystemCall_Iseries(void);
+extern void SingleStep_Iseries(void);
+extern void Trap_0e_Iseries(void);
+extern void PerformanceMonitor_Iseries(void);
+extern void DataAccessSLB_Iseries(void);
+extern void InstructionAccessSLB_Iseries(void);
+	
+struct ItLpNaca itLpNaca = {
+	0xd397d581,	/* desc = "LpNa" ebcdic */
+	0x0400,		/* size of ItLpNaca     */
+	0x0300, 19,	/* offset to int array, # ents */
+	0, 0, 0,	/* Part # of primary, serv, me */
+	0, 0x100,	/* # of LP queues, offset */
+	0, 0, 0,	/* Piranha stuff */
+	{ 0,0,0,0,0 },	/* reserved */
+	0,0,0,0,0,0,0,	/* stuff    */
+	{ 0,0,0,0,0 },	/* reserved */
+	0,		/* reserved */
+	0,		/* VRM index of PLIC */
+	0, 0,		/* min supported, compat SLIC */
+	0,		/* 64-bit addr of load area   */
+	0,		/* chunks for load area  */
+	0, 0,		/* PASE mask, seg table  */
+	{ 0 },		/* 64 reserved bytes  */
+	{ 0 }, 		/* 128 reserved bytes */
+	{ 0 }, 		/* Old LP Queue       */
+	{ 0 }, 		/* 384 reserved bytes */
+	{
+		(u64)SystemReset_Iseries,	/* 0x100 System Reset */
+		(u64)MachineCheck_Iseries,	/* 0x200 Machine Check */
+		(u64)DataAccess_Iseries,	/* 0x300 Data Access */
+		(u64)InstructionAccess_Iseries,	/* 0x400 Instruction Access */
+		(u64)HardwareInterrupt_Iseries,	/* 0x500 External */
+		(u64)Alignment_Iseries,		/* 0x600 Alignment */
+		(u64)ProgramCheck_Iseries,	/* 0x700 Program Check */
+		(u64)FPUnavailable_Iseries,	/* 0x800 FP Unavailable */
+		(u64)Decrementer_Iseries,	/* 0x900 Decrementer */
+		(u64)Trap_0a_Iseries,		/* 0xa00 Trap 0A */
+		(u64)Trap_0b_Iseries,		/* 0xb00 Trap 0B */
+		(u64)SystemCall_Iseries,	/* 0xc00 System Call */
+		(u64)SingleStep_Iseries,	/* 0xd00 Single Step */
+		(u64)Trap_0e_Iseries,		/* 0xe00 Trap 0E */
+		(u64)PerformanceMonitor_Iseries,/* 0xf00 Performance Monitor */
+		0,				/* int 0x1000 */
+		0,				/* int 0x1010 */
+		0,				/* int 0x1020 CPU ctls */
+		(u64)HardwareInterrupt_Iseries, /* SC Ret Hdlr */
+		(u64)DataAccessSLB_Iseries,	/* 0x380 D-SLB */
+		(u64)InstructionAccessSLB_Iseries /* 0x480 I-SLB */
+	}
+};
+
+struct ItIplParmsReal xItIplParmsReal = {};
+
+#define maxPhysicalProcessors 32
+
+struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
+	{
+		xInstCacheOperandSize: 32,
+		xDataCacheOperandSize: 32,
+		xProcFreq:     50000000,
+		xTimeBaseFreq: 50000000,
+		xPVR: 0x3600
+	}
+};
+	
+
+u64    xMsVpd[3400] = {};		/* Space for Main Store Vpd 27,200 bytes */
+
+u64    xRecoveryLogBuffer[32] = {};	/* Space for Recovery Log Buffer */
+
+struct SpCommArea xSpCommArea = {
+	0xE2D7C3C2,
+	1,
+	{0},
+	0, 0, 0, 0, {0}
+};
+
+struct ItVpdAreas itVpdAreas = {
+	0xc9a3e5c1,	/* "ItVA" */
+	sizeof( struct ItVpdAreas ),
+	0, 0,
+	26,		/* # VPD array entries */
+	10,		/* # DMA array entries */
+	MAX_PROCESSORS*2, maxPhysicalProcessors,	/* Max logical, physical procs */
+	offsetof(struct ItVpdAreas,xPlicDmaToks),/* offset to DMA toks */
+	offsetof(struct ItVpdAreas,xSlicVpdAdrs),/* offset to VPD addrs */
+	offsetof(struct ItVpdAreas,xPlicDmaLens),/* offset to DMA lens */
+	offsetof(struct ItVpdAreas,xSlicVpdLens),/* offset to VPD lens */
+	0,		/* max slot labels */
+	1,		/* max LP queues */
+	{0}, {0},	/* reserved */
+	{0},		/* DMA lengths */
+	{0},		/* DMA tokens */
+	{		/* VPD lengths */
+		0,0,0,0,		/*  0 -  3 */
+		sizeof(struct paca_struct),	/*       4 length of Paca  */
+		0,			/*       5 */
+		sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */
+		26992,			/*	 7 length of MS VPD */
+		0,			/*       8 */
+		sizeof(struct ItLpNaca),/*       9 length of LP Naca */
+		0, 			/*	10 */
+		256,			/*	11 length of Recovery Log Buf */
+		sizeof(struct SpCommArea), /*   12 length of SP Comm Area */
+		0,0,0,			/* 13 - 15 */
+		sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */
+		0,0,0,0,0,0,		/* 17 - 22  */
+		sizeof(struct ItLpQueue),/*     23 length of Lp Queue */
+		0,0			/* 24 - 25 */
+		},
+	{			/* VPD addresses */
+		0,0,0,0,		/*	 0 -  3 */
+		&paca[0],		/*       4 first Paca */
+		0,			/*       5 */
+		&xItIplParmsReal,	/*	 6 IPL parms */
+		&xMsVpd,		/*	 7 MS Vpd */
+		0,			/*       8 */
+		&itLpNaca,		/*       9 LpNaca */
+		0,			/*	10 */
+		&xRecoveryLogBuffer,	/*	11 Recovery Log Buffer */
+		&xSpCommArea,		/*	12 SP Comm Area */
+		0,0,0,			/* 13 - 15 */
+		&xIoHriProcessorVpd,	/*      16 Proc Vpd */
+		0,0,0,0,0,0,		/* 17 - 22 */
+		&xItLpQueue,		/*      23 Lp Queue */
+		0,0
+	}
+};
+
+struct msChunks msChunks = {0, 0, 0, 0, NULL};
+
+/* Depending on whether this is called from iSeries or pSeries setup
+ * code, the location of the msChunks struct may or may not have
+ * to be reloc'd, so we force the caller to do that for us by passing
+ * in a pointer to the structure.
+ */
+unsigned long
+msChunks_alloc(unsigned long mem, unsigned long num_chunks, unsigned long chunk_size)
+{
+	unsigned long offset = reloc_offset();
+	struct msChunks *_msChunks = PTRRELOC(&msChunks);
+
+	_msChunks->num_chunks  = num_chunks;
+	_msChunks->chunk_size  = chunk_size;
+	_msChunks->chunk_shift = __ilog2(chunk_size);
+	_msChunks->chunk_mask  = (1UL<<_msChunks->chunk_shift)-1;
+
+	mem = _ALIGN(mem, sizeof(msChunks_entry));
+	_msChunks->abs = (msChunks_entry *)(mem + offset);
+	mem += num_chunks * sizeof(msChunks_entry);
+
+	return mem;
+}
+
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/Makefile linux/arch/ppc64/kernel/Makefile
--- linux.orig/arch/ppc64/kernel/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,71 @@
+#
+# 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).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+USE_STANDARD_AS_RULE    := true
+
+EXTRA_CFLAGS = -mno-minimal-toc
+
+KHEAD := head.o
+
+all: $(KHEAD) kernel.o
+
+O_TARGET := kernel.o
+
+export-objs         := ppc_ksyms.o setup.o
+
+obj-y               :=	ppc_ksyms.o setup.o entry.o traps.o irq.o idle.o \
+			time.o process.o signal.o syscalls.o misc.o ptrace.o \
+			align.o semaphore.o bitops.o stab.o htab.o pacaData.o \
+			LparData.o udbg.o binfmt_elf32.o sys_ppc32.o sys32.o \
+			ioctl32.o ptrace32.o signal32.o open_pic.o xics.o \
+			pmc.o mf_proc.o proc_pmc.o proc_pcifr.o iSeries_setup.o \
+			ItLpQueue.o hvCall.o mf.o HvLpEvent.o ras.o \
+			iSeries_proc.o HvCall.o flight_recorder.o HvLpConfig.o \
+			rtc.o
+
+obj-$(CONFIG_PCI) +=  pci.o pci_dn.o pci_dma.o
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+obj-$(CONFIG_PCI) += iSeries_pci.o iSeries_pci_reset.o iSeries_IoMmTable.o iSeries_irq.o iSeries_VpdInfo.o XmPciLpEvent.o 
+endif
+ifeq ($(CONFIG_PPC_PSERIES),y)
+obj-$(CONFIG_PCI) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o eeh.o
+
+obj-y += rtasd.o nvram.o
+endif
+
+obj-$(CONFIG_KGDB) += ppc-stub.o
+
+obj-$(CONFIG_SMP) += smp.o
+
+obj-y += prom.o lmb.o rtas.o rtas-proc.o chrp_setup.o i8259.o
+
+include $(TOPDIR)/Rules.make
+
+#
+# This is just to get the dependencies...
+#
+
+head.o: head.S ppc_defs.h
+
+ppc_defs.h: mk_defs.c ppc_defs.head \
+		$(TOPDIR)/include/asm/mmu.h \
+		$(TOPDIR)/include/asm/processor.h \
+		$(TOPDIR)/include/asm/pgtable.h \
+		$(TOPDIR)/include/asm/ptrace.h
+	$(CC) $(CFLAGS) -S mk_defs.c
+	cp ppc_defs.head ppc_defs.h
+# for bk, this way we can write to the file even if it's not checked out
+	chmod u+w ppc_defs.h
+	grep '^#define' mk_defs.s >> ppc_defs.h
+	rm mk_defs.s
+
+checks: checks.c
+	$(HOSTCC) -I$(HPATH) $(HOSTCFLAGS) -D__KERNEL__ -fno-builtin -o checks checks.c
+	./checks
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/XmPciLpEvent.c linux/arch/ppc64/kernel/XmPciLpEvent.c
--- linux.orig/arch/ppc64/kernel/XmPciLpEvent.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/XmPciLpEvent.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,157 @@
+/*
+   * File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001.
+   *
+   * This module handles PCI interrupt events sent by the iSeries Hypervisor.
+*/
+
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+#include <linux/ide.h>
+
+#include <asm/iSeries/HvTypes.h>
+#include <asm/iSeries/HvLpEvent.h>
+#include <asm/iSeries/HvCallPci.h>
+#include <asm/iSeries/XmPciLpEvent.h>
+#include <asm/ppcdebug.h>
+
+long Pci_Interrupt_Count = 0;
+long Pci_Event_Count     = 0;
+
+enum XmPciLpEvent_Subtype {
+	XmPciLpEvent_BusCreated	   = 0,		// PHB has been created
+	XmPciLpEvent_BusFailed	   = 1,		// PHB has failed
+	XmPciLpEvent_BusRecovered  = 12,	// PHB has been recovered
+	XmPciLpEvent_NodeFailed	   = 4,		// Multi-adapter bridge has failed
+	XmPciLpEvent_NodeRecovered = 5,		// Multi-adapter bridge has recovered
+	XmPciLpEvent_SlotInterrupt = 22		// Slot interrupt
+};
+
+struct XmPciLpEvent_BusInterrupt {
+	HvBusNumber		busNumber;
+	HvSubBusNumber	subBusNumber;
+};
+
+struct XmPciLpEvent_NodeInterrupt {
+	HvBusNumber		busNumber;
+	HvSubBusNumber	subBusNumber;
+	HvAgentId		deviceId;
+};
+
+struct XmPciLpEvent {
+	struct HvLpEvent hvLpEvent;
+
+	union {
+		u64 alignData;			// Align on an 8-byte boundary
+
+		struct {
+			u32			fisr;
+			HvBusNumber	busNumber;
+			HvSubBusNumber	subBusNumber;
+			HvAgentId		deviceId;
+		} slotInterrupt;
+
+		struct XmPciLpEvent_BusInterrupt busFailed;
+		struct XmPciLpEvent_BusInterrupt busRecovered;
+		struct XmPciLpEvent_BusInterrupt busCreated;
+
+		struct XmPciLpEvent_NodeInterrupt nodeFailed;
+		struct XmPciLpEvent_NodeInterrupt nodeRecovered;
+
+	} eventData;
+
+};
+
+static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm);
+
+static void XmPciLpEvent_handler( struct HvLpEvent* eventParm, struct pt_regs* regsParm)
+{
+	//PPCDBG(PPCDBG_BUSWALK,"XmPciLpEvent_handler, type 0x%x\n",eventParm->xType );
+	++Pci_Event_Count;
+
+	if (eventParm && eventParm->xType == HvLpEvent_Type_PciIo) {
+		switch( eventParm->xFlags.xFunction ) {
+		case HvLpEvent_Function_Int:
+			intReceived( (struct XmPciLpEvent*)eventParm, regsParm );
+			break;
+		case HvLpEvent_Function_Ack:
+			printk(KERN_ERR "XmPciLpEvent.c: unexpected ack received\n");
+			break;
+		default:
+			printk(KERN_ERR "XmPciLpEvent.c: unexpected event function %d\n",(int)eventParm->xFlags.xFunction);
+			break;
+		}
+	}
+	else if (event) {
+		printk(KERN_ERR "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n",(int)eventParm->xType);
+	}
+	else {
+		printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n");
+	}
+}
+
+static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm)
+{
+	int irq;
+
+	++Pci_Interrupt_Count;
+	//PPCDBG(PPCDBG_BUSWALK,"PCI: XmPciLpEvent.c: intReceived\n");
+
+	switch (eventParm->hvLpEvent.xSubtype) {
+	case XmPciLpEvent_SlotInterrupt:
+		irq = eventParm->hvLpEvent.xCorrelationToken;
+		/* Dispatch the interrupt handlers for this irq */
+		ppc_irq_dispatch_handler(regsParm, irq);
+		HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
+			      eventParm->eventData.slotInterrupt.subBusNumber,
+			      eventParm->eventData.slotInterrupt.deviceId);
+		break;
+		/* Ignore error recovery events for now */
+	case XmPciLpEvent_BusCreated:
+		printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", eventParm->eventData.busCreated.busNumber);
+		break;
+	case XmPciLpEvent_BusFailed:
+		printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", eventParm->eventData.busFailed.busNumber);
+		break;
+	case XmPciLpEvent_BusRecovered:
+		printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", eventParm->eventData.busRecovered.busNumber);
+		break;
+	case XmPciLpEvent_NodeFailed:
+		printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", eventParm->eventData.nodeFailed.busNumber, eventParm->eventData.nodeFailed.subBusNumber, eventParm->eventData.nodeFailed.deviceId);
+		break;
+	case XmPciLpEvent_NodeRecovered:
+		printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", eventParm->eventData.nodeRecovered.busNumber, eventParm->eventData.nodeRecovered.subBusNumber, eventParm->eventData.nodeRecovered.deviceId);
+		break;
+	default:
+		printk(KERN_ERR "XmPciLpEvent.c: unrecognized event subtype 0x%x\n",
+		       eventParm->hvLpEvent.xSubtype);
+		break;
+	};
+}
+
+
+/* This should be called sometime prior to buswalk (init_IRQ would be good) */
+int XmPciLpEvent_init()
+{
+	int xRc;
+	PPCDBG(PPCDBG_BUSWALK,"XmPciLpEvent_init, Register Event type 0x%04X\n",HvLpEvent_Type_PciIo);
+
+	xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, &XmPciLpEvent_handler);
+	if (xRc == 0) {
+		xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
+		if (xRc != 0) {
+			printk(KERN_ERR "XmPciLpEvent.c: open event path failed with rc 0x%x\n", xRc);
+		}
+	}
+	else {
+		printk(KERN_ERR "XmPciLpEvent.c: register handler failed with rc 0x%x\n", xRc);
+    	}
+    return xRc;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/align.c linux/arch/ppc64/kernel/align.c
--- linux.orig/arch/ppc64/kernel/align.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/align.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,383 @@
+/* align.c - handle alignment exceptions for the Power PC.
+ *
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ *   PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *   PowerPC 403GCX/405GP modifications.
+ * Copyright (c) 2001-2002 PPC64 team, IBM Corp
+ *   64-bit and Power4 support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/cache.h>
+
+struct aligninfo {
+	unsigned char len;
+	unsigned char flags;
+};
+
+#define IS_XFORM(inst)	(((inst) >> 26) == 31)
+#define IS_DSFORM(inst)	(((inst) >> 26) >= 56)
+
+#define INVALID	{ 0, 0 }
+
+#define LD	1	/* load */
+#define ST	2	/* store */
+#define	SE	4	/* sign-extend value */
+#define F	8	/* to/from fp regs */
+#define U	0x10	/* update index register */
+#define M	0x20	/* multiple load/store */
+#define SW	0x40	/* byte swap */
+
+#define DCBZ	0x5f	/* 8xx/82xx dcbz faults when cache not enabled */
+
+/*
+ * The PowerPC stores certain bits of the instruction that caused the
+ * alignment exception in the DSISR register.  This array maps those
+ * bits to information about the operand length and what the
+ * instruction would do.
+ */
+static struct aligninfo aligninfo[128] = {
+	{ 4, LD },		/* 00 0 0000: lwz / lwarx */
+	INVALID,		/* 00 0 0001 */
+	{ 4, ST },		/* 00 0 0010: stw */
+	INVALID,		/* 00 0 0011 */
+	{ 2, LD },		/* 00 0 0100: lhz */
+	{ 2, LD+SE },		/* 00 0 0101: lha */
+	{ 2, ST },		/* 00 0 0110: sth */
+	{ 4, LD+M },		/* 00 0 0111: lmw */
+	{ 4, LD+F },		/* 00 0 1000: lfs */
+	{ 8, LD+F },		/* 00 0 1001: lfd */
+	{ 4, ST+F },		/* 00 0 1010: stfs */
+	{ 8, ST+F },		/* 00 0 1011: stfd */
+	INVALID,		/* 00 0 1100 */
+	{ 8, LD },		/* 00 0 1101: ld */
+	INVALID,		/* 00 0 1110 */
+	{ 8, ST },		/* 00 0 1111: std */
+	{ 4, LD+U },		/* 00 1 0000: lwzu */
+	INVALID,		/* 00 1 0001 */
+	{ 4, ST+U },		/* 00 1 0010: stwu */
+	INVALID,		/* 00 1 0011 */
+	{ 2, LD+U },		/* 00 1 0100: lhzu */
+	{ 2, LD+SE+U },		/* 00 1 0101: lhau */
+	{ 2, ST+U },		/* 00 1 0110: sthu */
+	{ 4, ST+M },		/* 00 1 0111: stmw */
+	{ 4, LD+F+U },		/* 00 1 1000: lfsu */
+	{ 8, LD+F+U },		/* 00 1 1001: lfdu */
+	{ 4, ST+F+U },		/* 00 1 1010: stfsu */
+	{ 8, ST+F+U },		/* 00 1 1011: stfdu */
+	INVALID,		/* 00 1 1100 */
+	INVALID,		/* 00 1 1101 */
+	INVALID,		/* 00 1 1110 */
+	INVALID,		/* 00 1 1111 */
+	{ 8, LD },		/* 01 0 0000: ldx */
+	INVALID,		/* 01 0 0001 */
+	{ 8, ST },		/* 01 0 0010: stdx */
+	INVALID,		/* 01 0 0011 */
+	INVALID,		/* 01 0 0100 */
+	{ 4, LD+SE },		/* 01 0 0101: lwax */
+	INVALID,		/* 01 0 0110 */
+	INVALID,		/* 01 0 0111 */
+	{ 0, LD },		/* 01 0 1000: lswx */
+	{ 0, LD },		/* 01 0 1001: lswi */
+	{ 0, ST },		/* 01 0 1010: stswx */
+	{ 0, ST },		/* 01 0 1011: stswi */
+	INVALID,		/* 01 0 1100 */
+	{ 8, LD+U },		/* 01 0 1101: ldu */
+	INVALID,		/* 01 0 1110 */
+	{ 8, ST+U },		/* 01 0 1111: stdu */
+	{ 8, LD+U },		/* 01 1 0000: ldux */
+	INVALID,		/* 01 1 0001 */
+	{ 8, ST+U },		/* 01 1 0010: stdux */
+	INVALID,		/* 01 1 0011 */
+	INVALID,		/* 01 1 0100 */
+	{ 4, LD+SE+U },		/* 01 1 0101: lwaux */
+	INVALID,		/* 01 1 0110 */
+	INVALID,		/* 01 1 0111 */
+	INVALID,		/* 01 1 1000 */
+	INVALID,		/* 01 1 1001 */
+	INVALID,		/* 01 1 1010 */
+	INVALID,		/* 01 1 1011 */
+	INVALID,		/* 01 1 1100 */
+	INVALID,		/* 01 1 1101 */
+	INVALID,		/* 01 1 1110 */
+	INVALID,		/* 01 1 1111 */
+	INVALID,		/* 10 0 0000 */
+	INVALID,		/* 10 0 0001 */
+	{ 0, ST },		/* 10 0 0010: stwcx. */
+	INVALID,		/* 10 0 0011 */
+	INVALID,		/* 10 0 0100 */
+	INVALID,		/* 10 0 0101 */
+	INVALID,		/* 10 0 0110 */
+	INVALID,		/* 10 0 0111 */
+	{ 4, LD+SW },		/* 10 0 1000: lwbrx */
+	INVALID,		/* 10 0 1001 */
+	{ 4, ST+SW },		/* 10 0 1010: stwbrx */
+	INVALID,		/* 10 0 1011 */
+	{ 2, LD+SW },		/* 10 0 1100: lhbrx */
+	{ 4, LD+SE },		/* 10 0 1101  lwa */
+	{ 2, ST+SW },		/* 10 0 1110: sthbrx */
+	INVALID,		/* 10 0 1111 */
+	INVALID,		/* 10 1 0000 */
+	INVALID,		/* 10 1 0001 */
+	INVALID,		/* 10 1 0010 */
+	INVALID,		/* 10 1 0011 */
+	INVALID,		/* 10 1 0100 */
+	INVALID,		/* 10 1 0101 */
+	INVALID,		/* 10 1 0110 */
+	INVALID,		/* 10 1 0111 */
+	INVALID,		/* 10 1 1000 */
+	INVALID,		/* 10 1 1001 */
+	INVALID,		/* 10 1 1010 */
+	INVALID,		/* 10 1 1011 */
+	INVALID,		/* 10 1 1100 */
+	INVALID,		/* 10 1 1101 */
+	INVALID,		/* 10 1 1110 */
+	{ L1_CACHE_BYTES, ST },	/* 10 1 1111: dcbz */
+	{ 4, LD },		/* 11 0 0000: lwzx */
+	INVALID,		/* 11 0 0001 */
+	{ 4, ST },		/* 11 0 0010: stwx */
+	INVALID,		/* 11 0 0011 */
+	{ 2, LD },		/* 11 0 0100: lhzx */
+	{ 2, LD+SE },		/* 11 0 0101: lhax */
+	{ 2, ST },		/* 11 0 0110: sthx */
+	INVALID,		/* 11 0 0111 */
+	{ 4, LD+F },		/* 11 0 1000: lfsx */
+	{ 8, LD+F },		/* 11 0 1001: lfdx */
+	{ 4, ST+F },		/* 11 0 1010: stfsx */
+	{ 8, ST+F },		/* 11 0 1011: stfdx */
+	INVALID,		/* 11 0 1100 */
+	{ 8, LD+M },		/* 11 0 1101: lmd */
+	INVALID,		/* 11 0 1110 */
+	{ 8, ST+M },		/* 11 0 1111: stmd */
+	{ 4, LD+U },		/* 11 1 0000: lwzux */
+	INVALID,		/* 11 1 0001 */
+	{ 4, ST+U },		/* 11 1 0010: stwux */
+	INVALID,		/* 11 1 0011 */
+	{ 2, LD+U },		/* 11 1 0100: lhzux */
+	{ 2, LD+SE+U },		/* 11 1 0101: lhaux */
+	{ 2, ST+U },		/* 11 1 0110: sthux */
+	INVALID,		/* 11 1 0111 */
+	{ 4, LD+F+U },		/* 11 1 1000: lfsux */
+	{ 8, LD+F+U },		/* 11 1 1001: lfdux */
+	{ 4, ST+F+U },		/* 11 1 1010: stfsux */
+	{ 8, ST+F+U },		/* 11 1 1011: stfdux */
+	INVALID,		/* 11 1 1100 */
+	INVALID,		/* 11 1 1101 */
+	INVALID,		/* 11 1 1110 */
+	INVALID,		/* 11 1 1111 */
+};
+
+#define SWAP(a, b)	(t = (a), (a) = (b), (b) = t)
+
+unsigned static inline make_dsisr( unsigned instr )
+{
+	unsigned dsisr;
+	
+	/* create a DSISR value from the instruction */
+	dsisr = (instr & 0x03ff0000) >> 16;			/* bits  6:15 --> 22:31 */
+	
+	if ( IS_XFORM(instr) ) {
+		dsisr |= (instr & 0x00000006) << 14;		/* bits 29:30 --> 15:16 */
+		dsisr |= (instr & 0x00000040) << 8;		/* bit     25 -->    17 */
+		dsisr |= (instr & 0x00000780) << 3;		/* bits 21:24 --> 18:21 */
+	}
+	else {
+		dsisr |= (instr & 0x04000000) >> 12;		/* bit      5 -->    17 */
+		dsisr |= (instr & 0x78000000) >> 17;		/* bits  1: 4 --> 18:21 */
+		if ( IS_DSFORM(instr) ) {
+			dsisr |= (instr & 0x00000003) << 18;	/* bits 30:31 --> 12:13 */
+		}
+	}
+	
+	return dsisr;
+}
+
+int
+fix_alignment(struct pt_regs *regs)
+{
+	unsigned int instr, nb, flags;
+	int t;
+	unsigned long reg, areg;
+	unsigned long i;
+	int ret;
+	unsigned dsisr;
+	unsigned char *addr, *p;
+	unsigned long *lp;
+	union {
+		long ll;
+		double dd;
+		unsigned char v[8];
+		struct {
+			unsigned hi32;
+			int	 low32;
+		} x32;
+		struct {
+			unsigned char hi48[6];
+			short	      low16;
+		} x16;
+	} data;
+
+	/*
+	 * Return 1 on success
+	 * Return 0 if unable to handle the interrupt
+	 * Return -EFAULT if data address is bad
+	 */
+
+	dsisr = regs->dsisr;
+
+	/* Power4 doesn't set DSISR for an alignment interrupt */
+	if (__is_processor(PV_POWER4))
+		dsisr = make_dsisr( *((unsigned *)regs->nip) );
+
+	/* extract the operation and registers from the dsisr */
+	reg = (dsisr >> 5) & 0x1f;	/* source/dest register */
+	areg = dsisr & 0x1f;		/* register to update */
+	instr = (dsisr >> 10) & 0x7f;
+	instr |= (dsisr >> 13) & 0x60;
+
+	/* Lookup the operation in our table */
+	nb = aligninfo[instr].len;
+	flags = aligninfo[instr].flags;
+
+	/* DAR has the operand effective address */
+	addr = (unsigned char *)regs->dar;
+
+	/* A size of 0 indicates an instruction we don't support */
+	/* we also don't support the multiples (lmw, stmw, lmd, stmd) */
+	if ((nb == 0) || (flags & M))
+		return 0;		/* too hard or invalid instruction */
+
+	/*
+	 * Special handling for dcbz
+	 * dcbz may give an alignment exception for accesses to caching inhibited
+	 * storage
+	 */
+	if (instr == DCBZ)
+		addr = (unsigned char *) ((unsigned long)addr & -L1_CACHE_BYTES);
+
+	/* Verify the address of the operand */
+	if (user_mode(regs)) {
+		if (verify_area((flags & ST? VERIFY_WRITE: VERIFY_READ), addr, nb))
+			return -EFAULT;	/* bad address */
+	}
+
+	/* Force the fprs into the save area so we can reference them */
+	if ((flags & F) && (regs->msr & MSR_FP))
+		giveup_fpu(current);
+	
+	/* If we are loading, get the data from user space */
+	if (flags & LD) {
+		data.ll = 0;
+		ret = 0;
+		p = addr;
+		switch (nb) {
+		case 8:
+			ret |= __get_user(data.v[0], p++);
+			ret |= __get_user(data.v[1], p++);
+			ret |= __get_user(data.v[2], p++);
+			ret |= __get_user(data.v[3], p++);
+		case 4:
+			ret |= __get_user(data.v[4], p++);
+			ret |= __get_user(data.v[5], p++);
+		case 2:
+			ret |= __get_user(data.v[6], p++);
+			ret |= __get_user(data.v[7], p++);
+			if (ret)
+				return -EFAULT;
+		}
+	}
+	
+	/* If we are storing, get the data from the saved gpr or fpr */
+	if (flags & ST) {
+		if (flags & F) {
+			if (nb == 4) {
+				/* Doing stfs, have to convert to single */
+				enable_kernel_fp();
+				cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
+			}
+			else
+				data.dd = current->thread.fpr[reg];
+		}
+		else 
+			data.ll = regs->gpr[reg];
+	}
+	
+	/* Swap bytes as needed */
+	if (flags & SW) {
+		if (nb == 2)
+			SWAP(data.v[6], data.v[7]);
+		else {	/* nb must be 4 */
+			SWAP(data.v[4], data.v[7]);
+			SWAP(data.v[5], data.v[6]);
+		}
+	}
+	
+	/* Sign extend as needed */
+	if (flags & SE) {
+		if ( nb == 2 )
+			data.ll = data.x16.low16;
+		else	/* nb must be 4 */
+			data.ll = data.x32.low32;
+	}
+	
+	/* If we are loading, move the data to the gpr or fpr */
+	if (flags & LD) {
+		if (flags & F) {
+			if (nb == 4) {
+				/* Doing lfs, have to convert to double */
+				enable_kernel_fp();
+				cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
+			}
+			else
+				current->thread.fpr[reg] = data.dd;
+		}
+		else
+			regs->gpr[reg] = data.ll;
+	}
+	
+	/* If we are storing, copy the data to the user */
+	if (flags & ST) {
+		ret = 0;
+		p = addr;
+		switch (nb) {
+		case 128:	/* Special case - must be dcbz */
+			lp = (unsigned long *)p;
+			for (i = 0; i < L1_CACHE_BYTES / sizeof(long); ++i)
+				ret |= __put_user(0, lp++);
+			break;
+		case 8:
+			ret |= __put_user(data.v[0], p++);
+			ret |= __put_user(data.v[1], p++);
+			ret |= __put_user(data.v[2], p++);
+			ret |= __put_user(data.v[3], p++);
+		case 4:
+			ret |= __put_user(data.v[4], p++);
+			ret |= __put_user(data.v[5], p++);
+		case 2:
+			ret |= __put_user(data.v[6], p++);
+			ret |= __put_user(data.v[7], p++);
+		}
+		if (ret)
+			return -EFAULT;
+	}
+	
+	/* Update RA as needed */
+	if (flags & U) {
+		regs->gpr[areg] = regs->dar;
+	}
+
+	return 1;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/binfmt_elf32.c linux/arch/ppc64/kernel/binfmt_elf32.c
--- linux.orig/arch/ppc64/kernel/binfmt_elf32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/binfmt_elf32.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,79 @@
+/*
+ * binfmt_elf32.c: Support 32-bit PPC ELF binaries on Power3 and followons.
+ * based on the SPARC64 version.
+ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller	(davem@redhat.com)
+ * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek	(jj@ultra.linux.cz)
+ *
+ * Copyright (C) 2000,2001 Ken Aaker (kdaaker@rchland.vnet.ibm.com), IBM Corp
+ * Copyright (C) 2001 Anton Blanchard (anton@au.ibm.com), IBM
+ *
+ * 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.
+ */
+
+#define ELF_ARCH		EM_PPC
+#define ELF_CLASS		ELFCLASS32
+#define ELF_DATA		ELFDATA2MSB;
+
+#include <asm/processor.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/elfcore.h>
+
+struct timeval32
+{
+	int tv_sec, tv_usec;
+};
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+	struct elf_siginfo pr_info;	/* Info associated with signal */
+	short	pr_cursig;		/* Current signal */
+	unsigned int pr_sigpend;	/* Set of pending signals */
+	unsigned int pr_sighold;	/* Set of held signals */
+	pid_t	pr_pid;
+	pid_t	pr_ppid;
+	pid_t	pr_pgrp;
+	pid_t	pr_sid;
+	struct timeval32 pr_utime;	/* User time */
+	struct timeval32 pr_stime;	/* System time */
+	struct timeval32 pr_cutime;	/* Cumulative user time */
+	struct timeval32 pr_cstime;	/* Cumulative system time */
+	elf_gregset_t pr_reg;		/* General purpose registers. */
+	int pr_fpvalid;		/* True if math co-processor being used. */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+	char	pr_state;	/* numeric process state */
+	char	pr_sname;	/* char for pr_state */
+	char	pr_zomb;	/* zombie */
+	char	pr_nice;	/* nice val */
+	unsigned int pr_flag;	/* flags */
+	u32	pr_uid;
+	u32	pr_gid;
+	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	/* Lots missing */
+	char	pr_fname[16];	/* filename of executable */
+	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
+};
+
+extern void start_thread32(struct pt_regs *, unsigned long, unsigned long);
+#undef start_thread
+#define start_thread start_thread32
+#define init_elf_binfmt init_elf32_binfmt
+
+#undef CONFIG_BINFMT_ELF
+#ifdef CONFIG_BINFMT_ELF32
+#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32
+#endif
+#undef CONFIG_BINFMT_ELF_MODULE
+#ifdef CONFIG_BINFMT_ELF32_MODULE
+#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE
+#endif
+
+#include "../../../fs/binfmt_elf.c"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/bitops.c linux/arch/ppc64/kernel/bitops.c
--- linux.orig/arch/ppc64/kernel/bitops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/bitops.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ * Adapted for ppc64 - Todd Inglett, Anton Blanchard
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <asm/bitops.h>
+#include <linux/fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/locks.h>
+#include <linux/quotaops.h>
+#include <asm/ppcdebug.h>
+
+#undef DEBUG_BITOPS
+
+/*
+ * Bitops are weird when viewed on big-endian systems.  They were designed
+ * on little endian so the size of the bitset doesn't matter (low order bytes
+ * come first) as long as the bit in question is valid.
+ *
+ * Bits are "tested" often using the C expression (val & (1<<nr)) so we do
+ * our best to stay compatible with that.  The assumption is that val will
+ * be unsigned long for such tests.  As such, we assume the bits are stored
+ * as an array of unsigned long (the usual case is a single unsigned long,
+ * of course).  Here's an example bitset with bit numbering:
+ *
+ *   |63..........0|127........64|195.......128|255.......196|
+ *
+ * This leads to two problems.  First, if an int, short or char is passed as
+ * a bitset it will be a bad memory reference since we want to store in chunks
+ * of unsigned long (64 bits here) size.  Second, since these could be char
+ * arrays we might have an alignment problem.  We ease the alignment problem
+ * by actually doing the operation with 32 bit values yet preserving the
+ * 64 bit long layout as shown above.  Got that?  Good.
+ */
+
+unsigned long find_next_zero_bit(void * addr, unsigned long size,
+				 unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
+	unsigned long result = offset & ~63UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 63UL;
+
+	if (offset) {
+		tmp = *p++;
+		tmp |= ~0UL >> (64-offset);
+		if (size < 64)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 64;
+		result += 64;
+	}
+	while (size & ~63UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 64;
+		size -= 64;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL << size;
+	if (tmp == ~0UL)
+		return result+size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+void BUG_OUTLINE(char* file, unsigned line) 
+{
+	udbg_printf("BUG - kernel BUG at %s:%d! \n", __FILE__, __LINE__);
+	PPCDBG_ENTER_DEBUGGER();
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__);
+	__asm__ __volatile__(".long " BUG_ILLEGAL_INSTR);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/checks.c linux/arch/ppc64/kernel/checks.c
--- linux.orig/arch/ppc64/kernel/checks.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/checks.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+/*
+ * Do various before compile checks of data structures
+ *
+ * This is invoked when you do a make checks 
+ * Is this enough or are there more things that we would like to do here?
+ * -- tgall
+ */
+int main(void)
+{
+	int ret = 0;
+#if 0
+	if ( sizeof(struct thread_struct) % 16 )
+	{
+		printf("Thread struct is not modulo 16 bytes: "
+			"%d bytes total, %d bytes off\n",
+			sizeof(struct thread_struct),
+			sizeof(struct thread_struct)%16);
+		ret = -1;
+	}
+#endif	
+
+	if ( sizeof(struct pt_regs) % 16 )
+	{
+		printf("pt_regs struct is not modulo 16 bytes: "
+			"%d bytes total, %d bytes off\n",
+			sizeof(struct pt_regs),
+			sizeof(struct pt_regs)%16);
+		ret = -1;
+		
+	}
+
+	printf("Task size        : %d bytes\n"
+	       "Tss size         : %d bytes\n"
+	       "pt_regs size     : %d bytes\n"
+	       "Kernel stack size: %d bytes\n",
+	       sizeof(struct task_struct), sizeof(struct thread_struct),
+	       sizeof(struct pt_regs),
+	       sizeof(union task_union) - sizeof(struct task_struct));
+	return ret;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/chrp_setup.c linux/arch/ppc64/kernel/chrp_setup.c
--- linux.orig/arch/ppc64/kernel/chrp_setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/chrp_setup.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,410 @@
+/*
+ *  linux/arch/ppc/kernel/setup.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Adapted from 'alpha' version by Gary Thomas
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *  Modified by PPC64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+/*
+ * bootup setup stuff..
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/blk.h>
+#include <linux/ioport.h>
+#include <linux/console.h>
+#include <linux/pci.h>
+#include <linux/version.h>
+#include <linux/adb.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/pci-bridge.h>
+#include <asm/pci_dma.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/keyboard.h>
+#include <asm/init.h>
+#include <asm/naca.h>
+#include <asm/time.h>
+
+#include "local_irq.h"
+#include "i8259.h"
+#include "open_pic.h"
+#include "xics.h"
+#include <asm/ppcdebug.h>
+
+extern volatile unsigned char *chrp_int_ack_special;
+
+void chrp_setup_pci_ptrs(void);
+void chrp_progress(char *, unsigned short);
+void chrp_request_regions(void);
+
+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+			   char raw_mode);
+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
+extern void openpic_init_IRQ(void);
+extern void init_ras_IRQ(void);
+
+extern void find_and_init_phbs(void);
+extern void pSeries_pcibios_fixup(void);
+extern void iSeries_pcibios_fixup(void);
+
+extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
+extern int  pSeries_set_rtc_time(struct rtc_time *rtc_time);
+void pSeries_calibrate_decr(void);
+static void fwnmi_init(void);
+extern void SystemReset_FWNMI(void), MachineCheck_FWNMI(void);	/* from head.S */
+int fwnmi_active;  /* TRUE if an FWNMI handler is present */
+
+kdev_t boot_dev;
+unsigned long  virtPython0Facilities = 0;  // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
+
+extern HPTE *Hash, *Hash_end;
+extern unsigned long Hash_size, Hash_mask;
+extern int probingmem;
+extern unsigned long loops_per_jiffy;
+
+#ifdef CONFIG_BLK_DEV_RAM
+extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
+extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
+extern int rd_image_start;	/* starting block # of image */
+#endif
+
+void 
+chrp_get_cpuinfo(struct seq_file *m)
+{
+	struct device_node *root;
+	const char *model = "";
+
+	root = find_path_device("/");
+	if (root)
+		model = get_property(root, "model", NULL);
+	seq_printf(m, "machine\t\t: CHRP %s\n", model);
+}
+
+void __init chrp_request_regions(void) {
+	request_region(0x20,0x20,"pic1");
+	request_region(0xa0,0x20,"pic2");
+	request_region(0x00,0x20,"dma1");
+	request_region(0x40,0x20,"timer");
+	request_region(0x80,0x10,"dma page reg");
+	request_region(0xc0,0x20,"dma2");
+}
+
+void __init
+chrp_setup_arch(void)
+{
+	extern char cmd_line[];
+	struct device_node *root;
+	unsigned int *opprop;
+	
+	/* openpic global configuration register (64-bit format). */
+	/* openpic Interrupt Source Unit pointer (64-bit format). */
+	/* python0 facility area (mmio) (64-bit format) REAL address. */
+
+	/* init to some ~sane value until calibrate_delay() runs */
+	loops_per_jiffy = 50000000;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	/* this is fine for chrp */
+	initrd_below_start_ok = 1;
+	
+	if (initrd_start)
+		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	else
+#endif
+	ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
+
+	printk("Boot arguments: %s\n", cmd_line);
+
+	fwnmi_init();
+
+	/* Find and initialize PCI host bridges */
+	/* iSeries needs to be done much later. */
+ 	#ifndef CONFIG_PPC_ISERIES
+		find_and_init_phbs();
+ 	#endif
+
+	/* Find the Open PIC if present */
+	root = find_path_device("/");
+	opprop = (unsigned int *) get_property(root,
+				"platform-open-pic", NULL);
+	if (opprop != 0) {
+		int n = prom_n_addr_cells(root);
+		unsigned long openpic;
+
+		for (openpic = 0; n > 0; --n)
+			openpic = (openpic << 32) + *opprop++;
+		printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic);
+		udbg_printf("OpenPIC addr: %lx\n", openpic);
+		OpenPIC_Addr = __ioremap(openpic, 0x40000, _PAGE_NO_CACHE);
+	}
+
+#ifdef CONFIG_DUMMY_CONSOLE
+	conswitchp = &dummy_con;
+#endif
+}
+
+void __init
+chrp_init2(void)
+{
+	/*
+	 * It is sensitive, when this is called (not too earlu)
+	 * -- tibit
+	 */
+	chrp_request_regions();
+	ppc_md.progress(UTS_RELEASE, 0x7777);
+}
+
+/* Initialize firmware assisted non-maskable interrupts if
+ * the firmware supports this feature.
+ *
+ */
+static void __init fwnmi_init(void)
+{
+	long ret;
+	int ibm_nmi_register = rtas_token("ibm,nmi-register");
+	if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
+		return;
+	ret = rtas_call(ibm_nmi_register, 2, 1, NULL,
+			__pa((unsigned long)SystemReset_FWNMI),
+			__pa((unsigned long)MachineCheck_FWNMI));
+	if (ret == 0)
+		fwnmi_active = 1;
+}
+
+
+/* Early initialization.  Relocation is on but do not reference unbolted pages */
+void __init pSeries_init_early(void)
+{
+#ifdef CONFIG_PPC_PSERIES	/* This ifdef should go away */
+	void *comport;
+
+	hpte_init_pSeries();
+	tce_init_pSeries();
+	pSeries_pcibios_init_early();
+
+#ifdef CONFIG_SMP
+	smp_init_pSeries();
+#endif
+
+	/* Map the uart for udbg. */
+	comport = (void *)__ioremap(naca->serialPortAddr, 16, _PAGE_NO_CACHE);
+	udbg_init_uart(comport);
+
+	ppc_md.udbg_putc = udbg_putc;
+	ppc_md.udbg_getc = udbg_getc;
+	ppc_md.udbg_getc_poll = udbg_getc_poll;
+#endif
+}
+
+void __init
+chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	  unsigned long r6, unsigned long r7)
+{
+#if 0 /* PPPBBB remove this later... -Peter */
+#ifdef CONFIG_BLK_DEV_INITRD
+	/* take care of initrd if we have one */
+	if ( r6 )
+	{
+		initrd_start = __va(r6);
+		initrd_end = __va(r6 + r7);
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+#endif
+
+	ppc_md.ppc_machine = naca->platform;
+
+	ppc_md.setup_arch     = chrp_setup_arch;
+	ppc_md.setup_residual = NULL;
+	ppc_md.get_cpuinfo    = chrp_get_cpuinfo;
+	if(naca->interrupt_controller == IC_OPEN_PIC) {
+		ppc_md.init_IRQ       = openpic_init_IRQ; 
+		ppc_md.get_irq        = openpic_get_irq;
+		ppc_md.post_irq	      = NULL;
+	} else {
+		ppc_md.init_IRQ       = xics_init_IRQ;
+		ppc_md.get_irq        = xics_get_irq;
+		ppc_md.post_irq	      = NULL;
+	}
+	ppc_md.init_ras_IRQ = init_ras_IRQ;
+
+ 	#ifndef CONFIG_PPC_ISERIES
+ 		ppc_md.pcibios_fixup = pSeries_pcibios_fixup;
+ 	#else 
+ 		ppc_md.pcibios_fixup = NULL;
+ 		// ppc_md.pcibios_fixup = iSeries_pcibios_fixup;
+ 	#endif
+
+
+	ppc_md.init           = chrp_init2;
+
+	ppc_md.restart        = rtas_restart;
+	ppc_md.power_off      = rtas_power_off;
+	ppc_md.halt           = rtas_halt;
+
+	ppc_md.time_init      = NULL;
+	ppc_md.get_boot_time  = pSeries_get_rtc_time;
+	ppc_md.get_rtc_time   = pSeries_get_rtc_time;
+	ppc_md.set_rtc_time   = pSeries_set_rtc_time;
+	ppc_md.calibrate_decr = pSeries_calibrate_decr;
+
+	ppc_md.progress = chrp_progress;
+
+#ifdef CONFIG_VT
+	ppc_md.kbd_setkeycode    = pckbd_setkeycode;
+	ppc_md.kbd_getkeycode    = pckbd_getkeycode;
+	ppc_md.kbd_translate     = pckbd_translate;
+	ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+	ppc_md.kbd_leds          = pckbd_leds;
+	ppc_md.kbd_init_hw       = pckbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+	ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
+	SYSRQ_KEY = 0x63;	/* Print Screen */
+#endif
+#endif
+	
+	ppc_md.progress("Linux ppc64\n", 0x0);
+}
+
+void __chrp
+chrp_progress(char *s, unsigned short hex)
+{
+	struct device_node *root;
+	int width, *p;
+	char *os;
+	static int display_character, set_indicator;
+	static int max_width;
+
+	if (hex)
+		udbg_printf("<chrp_progress> %s\n", s);
+
+	if (!rtas.base || (naca->platform != PLATFORM_PSERIES))
+		return;
+
+	if (max_width == 0) {
+		if ( (root = find_path_device("/rtas")) &&
+		     (p = (unsigned int *)get_property(root,
+						       "ibm,display-line-length",
+						       NULL)) )
+			max_width = *p;
+		else
+			max_width = 0x10;
+		display_character = rtas_token("display-character");
+		set_indicator = rtas_token("set-indicator");
+	}
+	if (display_character == RTAS_UNKNOWN_SERVICE) {
+		/* use hex display */
+		if (set_indicator == RTAS_UNKNOWN_SERVICE)
+			return;
+		rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
+		return;
+	}
+
+	rtas_call(display_character, 1, 1, NULL, '\r');
+
+	width = max_width;
+	os = s;
+	while ( *os )
+	{
+		if ( (*os == '\n') || (*os == '\r') )
+			width = max_width;
+		else
+			width--;
+		rtas_call(display_character, 1, 1, NULL, *os++ );
+		/* if we overwrite the screen length */
+		if ( width == 0 )
+			while ( (*os != 0) && (*os != '\n') && (*os != '\r') )
+				os++;
+	}
+
+	/* Blank to end of line. */
+	while ( width-- > 0 )
+		rtas_call(display_character, 1, 1, NULL, ' ' );
+}
+
+extern void setup_default_decr(void);
+
+extern unsigned long ppc_proc_freq;
+extern unsigned long ppc_tb_freq;
+
+void __init pSeries_calibrate_decr(void)
+{
+	struct device_node *cpu;
+	struct div_result divres;
+	int *fp;
+	unsigned long freq, processor_freq;
+
+	/*
+	 * The cpu node should have a timebase-frequency property
+	 * to tell us the rate at which the decrementer counts. 
+	 */
+	freq = 16666000;        /* hardcoded default */
+	cpu = find_type_devices("cpu");
+	if (cpu != 0) { 
+		fp = (int *) get_property(cpu, "timebase-frequency", NULL);
+		if (fp != 0)
+			freq = *fp;
+	}
+	ppc_tb_freq = freq;
+	processor_freq = freq;
+	if (cpu != 0) {
+		fp = (int *) get_property(cpu, "clock-frequency", NULL);
+		if (fp != 0)
+			processor_freq = *fp;
+	}
+	ppc_proc_freq = processor_freq;
+	
+        printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", 
+	       freq/1000000, freq%1000000 );
+	printk("time_init: processor frequency   = %lu.%.6lu MHz\n",
+		processor_freq/1000000, processor_freq%1000000 );
+
+	tb_ticks_per_jiffy = freq / HZ;
+	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
+	tb_ticks_per_usec = freq / 1000000;
+	tb_to_us = mulhwu_scale_factor(freq, 1000000);
+	div128_by_32( 1024*1024, 0, tb_ticks_per_sec, &divres );
+	tb_to_xs = divres.result_low;
+
+	setup_default_decr();
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/eeh.c linux/arch/ppc64/kernel/eeh.c
--- linux.orig/arch/ppc64/kernel/eeh.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/eeh.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,344 @@
+/*
+ * eeh.c
+ * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM 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
+ */
+
+/* Change Activity:
+ * 2001/10/27 : engebret : Created.
+ * End Change Activity 
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/bootmem.h>
+#include <asm/paca.h>
+#include <asm/processor.h>
+#include <asm/naca.h>
+#include <asm/io.h>
+#include "pci.h"
+
+#define BUID_HI(buid) ((buid) >> 32)
+#define BUID_LO(buid) ((buid) & 0xffffffff)
+#define CONFIG_ADDR(busno, devfn) (((((busno) & 0xff) << 8) | ((devfn) & 0xf8)) << 8)
+
+unsigned long eeh_total_mmio_ffs;
+unsigned long eeh_false_positives;
+/* RTAS tokens */
+static int ibm_set_eeh_option;
+static int ibm_set_slot_reset;
+static int ibm_read_slot_reset_state;
+
+int eeh_implemented;
+#define EEH_MAX_OPTS 4096
+static char *eeh_opts;
+static int eeh_opts_last;
+static int eeh_check_opts_config(struct pci_dev *dev, int default_state);
+
+
+unsigned long eeh_token(unsigned long phb, unsigned long bus, unsigned long devfn, unsigned long offset)
+{
+	if (phb > 0xff)
+		panic("eeh_token: phb 0x%lx is too large\n", phb);
+	if (offset & 0x0fffffff00000000)
+		panic("eeh_token: offset 0x%lx is out of range\n", offset);
+	return ((IO_UNMAPPED_REGION_ID << 60) | (phb << 48UL) | ((bus & 0xff) << 40UL) | (devfn << 32UL) | (offset & 0xffffffff));
+}
+
+
+
+int eeh_get_state(unsigned long ea) {
+	return 0;
+}
+
+
+/* Check for an eeh failure at the given token address.
+ * The given value has been read and it should be 1's (0xff, 0xffff or 0xffffffff).
+ *
+ * Probe to determine if an error actually occurred.  If not return val.
+ * Otherwise panic.
+ */
+unsigned long eeh_check_failure(void *token, unsigned long val)
+{
+	unsigned long config_addr = (unsigned long)token >> 24;	/* PPBBDDRR */
+	unsigned long phbidx = (config_addr >> 24) & 0xff;
+	struct pci_controller *phb;
+	unsigned long ret, rets[2];
+
+	config_addr &= 0xffff00;  /* 00BBDD00 */
+
+	if (phbidx >= global_phb_number) {
+		panic("EEH: checking token %p phb index of %ld is greater than max of %d\n", token, phbidx, global_phb_number-1);
+	}
+	phb = phbtab[phbidx];
+
+	ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
+			config_addr, BUID_HI(phb->buid), BUID_LO(phb->buid));
+	if (ret == 0 && rets[1] == 1 && rets[0] >= 2) {
+		struct pci_dev *dev;
+		int bus = ((unsigned long)token >> 40) & 0xffff; /* include PHB# in bus */
+		int devfn = (config_addr >> 8) & 0xff;
+
+		dev = pci_find_slot(bus, devfn);
+		if (dev) {
+			udbg_printf("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
+			      rets[0], dev->slot_name, dev->name);
+			printk("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
+			      rets[0], dev->slot_name, dev->name);
+			PPCDBG_ENTER_DEBUGGER();
+			panic("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
+			      rets[0], dev->slot_name, dev->name);
+		} else {
+			udbg_printf("EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[0], phb->buid, config_addr);
+			printk("EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[0], phb->buid, config_addr);
+			PPCDBG_ENTER_DEBUGGER();
+			panic("EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[0], phb->buid, config_addr);
+		}
+	}
+	eeh_false_positives++;
+	return val;	/* good case */
+}
+
+void eeh_init(void) {
+	extern char cmd_line[];	/* Very early cmd line parse.  Cheap, but works. */
+	char *eeh_force_off = strstr(cmd_line, "eeh-force-off");
+	char *eeh_force_on = strstr(cmd_line, "eeh-force-on");
+
+	ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
+	ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
+	ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
+	if (ibm_set_eeh_option != RTAS_UNKNOWN_SERVICE && naca->platform == PLATFORM_PSERIES_LPAR)
+		eeh_implemented = 1;
+
+	if (eeh_force_off > eeh_force_on) {
+		/* User is forcing EEH off.  Be noisy if it is implemented. */
+		if (eeh_implemented)
+			printk("EEH: WARNING: PCI Enhanced I/O Error Handling is user disabled\n");
+		eeh_implemented = 0;
+		return;
+	}
+
+	if (eeh_force_on > eeh_force_off)
+		eeh_implemented = 1;	/* User is forcing it on. */
+
+	if (eeh_implemented)
+		printk("EEH: PCI Enhanced I/O Error Handling Enabled\n");
+}
+
+
+/* Given a PCI device check if eeh should be configured or not.
+ * This may look at firmware properties and/or kernel cmdline options.
+ */
+int is_eeh_configured(struct pci_dev *dev)
+{
+	struct device_node *dn = pci_device_to_OF_node(dev);
+	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
+	unsigned long ret, rets[2];
+	int eeh_capable;
+	int default_state = 1;	/* default enable EEH if we can. */
+
+	if (dn == NULL || phb == NULL || !eeh_implemented)
+		return 0;
+
+	/* Hack: turn off eeh for display class devices by default.
+	 * This fixes matrox accel framebuffer.
+	 */
+	if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
+		default_state = 0;
+
+	/* Ignore known PHBs and EADs bridges */
+	if (dev->vendor == PCI_VENDOR_ID_IBM &&
+	    (dev->device == 0x0102 || dev->device == 0x008b))
+		default_state = 0;
+
+	if (!eeh_check_opts_config(dev, default_state)) {
+		if (default_state)
+			printk("EEH: %s %s user requested to run without EEH.\n", dev->slot_name, dev->name);
+		return 0;
+	}
+
+	ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
+			CONFIG_ADDR(dn->busno, dn->devfn),
+			BUID_HI(phb->buid), BUID_LO(phb->buid));
+	eeh_capable = (ret == 0 && rets[1] == 1);
+	printk("EEH: %s %s is%s EEH capable.\n", dev->slot_name, dev->name, eeh_capable ? "" : " not");
+	return eeh_capable;
+}
+
+int eeh_set_option(struct pci_dev *dev, int option)
+{
+	struct device_node *dn = pci_device_to_OF_node(dev);
+	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
+
+	if (dn == NULL || phb == NULL || phb->buid == 0 || !eeh_implemented)
+		return -2;
+
+	return rtas_call(ibm_set_eeh_option, 4, 1, NULL,
+			 CONFIG_ADDR(dn->busno, dn->devfn),
+			 BUID_HI(phb->buid), BUID_LO(phb->buid), option);
+}
+
+
+static int eeh_proc_falsepositive_read(char *page, char **start, off_t off,
+			 int count, int *eof, void *data)
+{
+	int len;
+	len = sprintf(page, "eeh_false_positives=%ld\n"
+		      "eeh_total_mmio_ffs=%ld\n",
+		      eeh_false_positives, eeh_total_mmio_ffs);
+	return len;
+}
+
+/* Implementation of /proc/ppc64/eeh
+ * For now it is one file showing false positives.
+ */
+static int __init eeh_init_proc(void)
+{
+	struct proc_dir_entry *ent = create_proc_entry("ppc64/eeh", S_IRUGO, 0);
+	if (ent) {
+		ent->nlink = 1;
+		ent->data = NULL;
+		ent->read_proc = (void *)eeh_proc_falsepositive_read;
+	}
+	return 0;
+}
+
+/*
+ * Test if "dev" should be configured on or off.
+ * This processes the options literally from left to right.
+ * This lets the user specify stupid combinations of options,
+ * but at least the result should be very predictable.
+ */
+static int eeh_check_opts_config(struct pci_dev *dev, int default_state)
+{
+	struct device_node *dn = pci_device_to_OF_node(dev);
+	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
+	char devname[32], classname[32], phbname[32];
+	char *strs[8], *s;
+	int nstrs, i;
+	int ret = default_state;
+
+	if (dn == NULL || phb == NULL)
+		return 0;
+	/* Build list of strings to match */
+	nstrs = 0;
+	s = (char *)get_property(dn, "ibm,loc-code", 0);
+	if (s)
+		strs[nstrs++] = s;
+	sprintf(devname, "dev%04x:%04x", dev->vendor, dev->device);
+	strs[nstrs++] = devname;
+	sprintf(classname, "class%04x", dev->class);
+	strs[nstrs++] = classname;
+	sprintf(phbname, "pci@%lx", phb->buid);
+	strs[nstrs++] = phbname;
+	strs[nstrs++] = "";	/* yes, this matches the empty string */
+
+	/* Now see if any string matches the eeh_opts list.
+	 * The eeh_opts list entries start with + or -.
+	 */
+	for (s = eeh_opts; s && (s < (eeh_opts + eeh_opts_last)); s += strlen(s)+1) {
+		for (i = 0; i < nstrs; i++) {
+			if (strcasecmp(strs[i], s+1) == 0) {
+				ret = (strs[i][0] == '+') ? 1 : 0;
+			}
+		}
+	}
+	return ret;
+}
+
+/* Handle kernel eeh-on & eeh-off cmd line options for eeh.
+ *
+ * We support:
+ *	eeh-off=loc1,loc2,loc3...
+ *
+ * and this option can be repeated so
+ *      eeh-off=loc1,loc2 eeh-off=loc3
+ * is the same as eeh-off=loc1,loc2,loc3
+ *
+ * loc is an IBM location code that can be found in a manual or
+ * via openfirmware (or the Hardware Management Console).
+ *
+ * We also support these additional "loc" values:
+ *
+ *	dev#:#    vendor:device id in hex (e.g. dev1022:2000)
+ *	class#    class id in hex (e.g. class0200)
+ *	pci@buid  all devices under phb (e.g. pci@fef00000)
+ *
+ * If no location code is specified all devices are assumed
+ * so eeh-off means eeh by default is off.
+ */
+
+/* This is implemented as a null separated list of strings.
+ * Each string looks like this:  "+X" or "-X"
+ * where X is a loc code, dev, class or pci string (as shown above)
+ * or empty which is used to indicate all.
+ *
+ * We interpret this option string list during the buswalk
+ * so that it will literally behave left-to-right even if
+ * some combinations don't make sense.  Give the user exactly
+ * what they want! :)
+ */
+
+static int __init eeh_parm(char *str, int state)
+{
+	char *s, *cur, *curend;
+	if (!eeh_opts) {
+		eeh_opts = alloc_bootmem(EEH_MAX_OPTS);
+		eeh_opts[eeh_opts_last++] = '+'; /* default */
+		eeh_opts[eeh_opts_last++] = '\0';
+	}
+	if (*str == '\0') {
+		eeh_opts[eeh_opts_last++] = state ? '+' : '-';
+		eeh_opts[eeh_opts_last++] = '\0';
+		return 1;
+	}
+	if (*str == '=')
+		str++;
+	for (s = str; s && *s != '\0'; s = curend) {
+		cur = s;
+		while (*cur == ',')
+			cur++;	/* ignore empties.  Don't treat as "all-on" or "all-off" */
+		curend = strchr(cur, ',');
+		if (!curend)
+			curend = cur + strlen(cur);
+		if (*cur) {
+			int curlen = curend-cur;
+			if (eeh_opts_last + curlen > EEH_MAX_OPTS-2) {
+				printk("EEH: sorry...too many eeh cmd line options\n");
+				return 1;
+			}
+			eeh_opts[eeh_opts_last++] = state ? '+' : '-';
+			strncpy(eeh_opts+eeh_opts_last, cur, curlen);
+			eeh_opts_last += curlen;
+			eeh_opts[eeh_opts_last++] = '\0';
+		}
+	}
+	return 1;
+}
+
+static int __init eehoff_parm(char *str)
+{
+	return eeh_parm(str, 0);
+}
+static int __init eehon_parm(char *str)
+{
+	return eeh_parm(str, 1);
+}
+
+__initcall(eeh_init_proc);
+__setup("eeh-off", eehoff_parm);
+__setup("eeh-on", eehon_parm);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/entry.S linux/arch/ppc64/kernel/entry.S
--- linux.orig/arch/ppc64/kernel/entry.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/entry.S	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,610 @@
+/*
+ *  arch/ppc64/kernel/entry.S
+ *
+ *  PowerPC version 
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ *  Adapted for Power Macintosh by Paul Mackerras.
+ *  Low-level exception handlers and MMU support
+ *  rewritten by Paul Mackerras.
+ *    Copyright (C) 1996 Paul Mackerras.
+ *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
+ *
+ *  This file contains the system call entry code, context switch
+ *  code, and exception/interrupt return code for PowerPC.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include "ppc_asm.h"
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <linux/errno.h>
+#include <linux/sys.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_PPC_ISERIES
+#define DO_SOFT_DISABLE
+#endif
+
+#undef SHOW_SYSCALLS
+#undef SHOW_SYSCALLS_TASK
+
+#ifdef SHOW_SYSCALLS_TASK
+	.data
+show_syscalls_task:
+	.long	-1
+#endif
+
+/*
+ * Handle a system call.
+ */
+	.text
+_GLOBAL(DoSyscall)
+	std	r0,THREAD+LAST_SYSCALL(r13)
+	ld	r11,_CCR(r1)	/* Clear SO bit in CR */
+	lis	r10,0x1000
+	andc	r11,r11,r10
+	std	r11,_CCR(r1)
+#ifdef SHOW_SYSCALLS
+#ifdef SHOW_SYSCALLS_TASK
+	LOADBASE(r31,show_syscalls_task)
+	ld	r31,show_syscalls_task@l(r31)
+	cmp	0,r13,r31
+	bne	1f
+#endif
+	LOADADDR(r3,7f)
+	ld	r4,GPR0(r1)
+	ld	r5,GPR3(r1)
+	ld	r6,GPR4(r1)
+	ld	r7,GPR5(r1)
+	ld	r8,GPR6(r1)
+	ld	r9,GPR7(r1)
+	bl	.printk
+	LOADADDR(r3,77f)
+	ld	r4,GPR8(r1)
+	ld	r5,GPR9(r1)
+	mr	r6,r13
+	bl	.printk
+	ld	r0,GPR0(r1)
+	ld	r3,GPR3(r1)
+	ld	r4,GPR4(r1)
+	ld	r5,GPR5(r1)
+	ld	r6,GPR6(r1)
+	ld	r7,GPR7(r1)
+	ld	r8,GPR8(r1)
+1:
+#endif /* SHOW_SYSCALLS */
+	ld	r10,TASK_PTRACE(r13)
+	andi.	r10,r10,PT_TRACESYS
+	bne-	50f
+	cmpli	0,r0,NR_syscalls
+	bge-	66f
+/* Ken Aaker: Need to vector to 32 Bit or default sys_call_table here,
+ *            based on caller's run-mode / personality.
+ *
+ */
+#ifdef CONFIG_BINFMT_ELF32
+	ld	r10,THREAD+THREAD_FLAGS(r13)
+	andi.	r10,r10,PPC_FLAG_32BIT
+	beq-	15f
+	LOADADDR(r10,.sys_call_table32)
+/* Now mung the first 4 parameters into shape, by making certain that
+ * the high bits (most significant 32 bits in 64 bit reg) are 0
+ * for the first 4 parameter regs(3-6).
+ */
+	clrldi	r3,r3,32
+	clrldi	r4,r4,32
+	clrldi	r5,r5,32
+	clrldi	r6,r6,32
+	b	17f
+15:
+#endif
+	LOADADDR(r10,.sys_call_table)
+17:
+	slwi	r0,r0,3
+	ldx	r10,r10,r0	/* Fetch system call handler [ptr] */
+	mtlr	r10
+	addi	r9,r1,STACK_FRAME_OVERHEAD
+	blrl			/* Call handler */
+_GLOBAL(ret_from_syscall_1)
+20:	std	r3,RESULT(r1)	/* Save result */
+#ifdef SHOW_SYSCALLS
+#ifdef SHOW_SYSCALLS_TASK
+	cmp	0,r13,r31
+	bne	91f
+#endif
+	mr	r4,r3
+	LOADADDR(r3,79f)
+	bl	.printk
+	ld	r3,RESULT(r1)
+91:
+#endif
+	li	r10,-_LAST_ERRNO
+	cmpl	0,r3,r10
+	blt	30f
+	neg	r3,r3
+	cmpi	0,r3,ERESTARTNOHAND
+	bne	22f
+	li	r3,EINTR
+22:	ld	r10,_CCR(r1)	/* Set SO bit in CR */
+	oris	r10,r10,0x1000
+	std	r10,_CCR(r1)
+30:	std	r3,GPR3(r1)	/* Update return value */
+	b	.ret_from_except
+66:	li	r3,ENOSYS
+	b	22b
+        
+/* Traced system call support */
+50:	bl	.syscall_trace
+	ld	r0,GPR0(r1)	/* Restore original registers */
+	ld	r3,GPR3(r1)
+	ld	r4,GPR4(r1)
+	ld	r5,GPR5(r1)
+	ld	r6,GPR6(r1)
+	ld	r7,GPR7(r1)
+	ld	r8,GPR8(r1)
+	ld	r9,GPR9(r1)
+	cmpli	0,r0,NR_syscalls
+	bge-	66f
+#ifdef CONFIG_BINFMT_ELF32
+	ld	r10,THREAD+THREAD_FLAGS(r13)
+	andi.	r10,r10,PPC_FLAG_32BIT
+	beq-	55f
+	LOADADDR(r10,.sys_call_table32)
+/* Now mung the first 4 parameters into shape, by making certain that
+ * the high bits (most significant 32 bits in 64 bit reg) are 0
+ * for the first 4 parameter regs(3-6).
+ */
+	clrldi	r3,r3,32
+	clrldi	r4,r4,32
+	clrldi	r5,r5,32
+	clrldi	r6,r6,32
+	b	57f
+55:
+#endif
+	LOADADDR(r10,.sys_call_table)
+57:
+	slwi	r0,r0,3
+	ldx	r10,r10,r0	/* Fetch system call handler [ptr] */
+	mtlr	r10
+	addi	r9,r1,STACK_FRAME_OVERHEAD
+	blrl			/* Call handler */
+_GLOBAL(ret_from_syscall_2)
+58:	std	r3,RESULT(r1)	/* Save result */	
+	std	r3,GPR0(r1)	/* temporary gross hack to make strace work */
+	li	r10,-_LAST_ERRNO
+	cmpl	0,r3,r10
+	blt	60f
+	neg	r3,r3
+	cmpi	0,r3,ERESTARTNOHAND
+	bne	57f
+	li	r3,EINTR
+57:	ld	r10,_CCR(r1)	/* Set SO bit in CR */
+	oris	r10,r10,0x1000
+	std	r10,_CCR(r1)
+60:	std	r3,GPR3(r1)	/* Update return value */
+	bl	.syscall_trace
+	b	.ret_from_except
+66:	li	r3,ENOSYS
+	b	57b
+#ifdef SHOW_SYSCALLS
+7:	.string	"syscall %d(%x, %x, %x, %x, %x, "
+77:	.string	"%x, %x), current=%p\n"
+79:	.string	" -> %x\n"
+	.align	2,0
+#endif
+
+_GLOBAL(ppc32_sigreturn)
+	bl	.sys32_sigreturn
+	b	80f
+
+_GLOBAL(ppc32_rt_sigreturn)
+	bl	.sys32_rt_sigreturn
+	b	80f
+
+_GLOBAL(ppc64_sigreturn)
+	bl	.sys_sigreturn
+	b	80f
+
+_GLOBAL(ppc64_rt_sigreturn)
+	bl	.sys_rt_sigreturn
+
+80:	ld	r10,TASK_PTRACE(r13)
+	andi.	r10,r10,PT_TRACESYS
+	bne-	81f
+	cmpi	0,r3,0
+	bge	.ret_from_except
+	b	20b
+81:	cmpi	0,r3,0
+	blt	58b
+	bl	.syscall_trace
+	b	.ret_from_except
+
+/*
+ * This routine switches between two different tasks.  The process
+ * state of one is saved on its kernel stack.  Then the state
+ * of the other is restored from its kernel stack.  The memory
+ * management hardware is updated to the second process's state.
+ * Finally, we can return to the second process, via ret_from_except.
+ * On entry, r3 points to the THREAD for the current task, r4
+ * points to the THREAD for the new task.
+ *
+ * Note: there are two ways to get to the "going out" portion
+ * of this code; either by coming in via the entry (_switch)
+ * or via "fork" which must set up an environment equivalent
+ * to the "_switch" path.  If you change this (or in particular, the
+ * SAVE_REGS macro), you'll have to change the fork code also.
+ *
+ * The code which creates the new task context is in 'copy_thread'
+ * in arch/ppc64/kernel/process.c
+ */
+_GLOBAL(_switch)
+	stdu	r1,-INT_FRAME_SIZE(r1)
+	ld	r6,0(r1)
+	std	r6,GPR1(r1)
+	/* r3-r13 are caller saved -- Cort */
+	SAVE_GPR(2, r1)
+	SAVE_8GPRS(14, r1)
+	SAVE_10GPRS(22, r1)
+	mflr	r20		/* Return to switch caller */
+	mfmsr	r22
+	li	r6,MSR_FP	/* Disable floating-point */
+	andc	r22,r22,r6
+	mtmsrd	r22
+	isync
+	std	r20,_NIP(r1)
+	std	r22,_MSR(r1)
+	std	r20,_LINK(r1)
+	mfcr	r20
+	std	r20,_CCR(r1)
+	li	r6,0x0ff0
+	std	r6,TRAP(r1)
+	std	r1,KSP(r3)	/* Set old stack pointer */
+
+	mfspr	r5,SPRG3	/* Get Paca */
+	addi	r3,r3,-THREAD	/* old 'current' for return value */
+	addi	r13,r4,-THREAD	/* Convert THREAD to 'current' */
+	std	r13,PACACURRENT(r5)	/* Set new 'current' */
+
+#ifdef CONFIG_PPC_ISERIES
+	ld	r7,THREAD_FLAGS(r4)	/* Get run light flag */
+	mfspr	r9,CTRLF
+	srdi	r7,r7,1		/* Align to run light bit in CTRL reg */
+	insrdi	r9,r7,1,63	/* Insert run light into CTRL */
+	mtspr	CTRLT,r9
+#endif
+	ld	r1,KSP(r4)	/* Load new stack pointer */
+	ld	r6,_CCR(r1)
+	mtcrf	0xFF,r6
+	/* r3-r13 are destroyed -- Cort */
+	REST_8GPRS(14, r1)
+	REST_10GPRS(22, r1)
+
+	ld	r7,_NIP(r1)	/* Return to _switch caller in new task */
+	ld	r1,GPR1(r1)
+	mtlr	r7
+	blr
+
+_GLOBAL(ret_from_fork)
+	bl	.schedule_tail
+	ld	r0,TASK_PTRACE(r13)
+	andi.	r0,r0,PT_TRACESYS
+	beq+	.ret_from_except
+	bl	.syscall_trace
+	b	.ret_from_except
+
+_GLOBAL(ret_from_except)
+#ifdef CONFIG_PPC_ISERIES
+	ld	r5,SOFTE(r1)
+	cmpdi	0,r5,0
+	beq	4f
+irq_recheck:
+	/*
+	 * Check for pending interrupts (iSeries)
+	 */
+	CHECKANYINT(r3,r4)
+	beq+	4f	/* skip do_IRQ if no interrupts */
+
+	mfspr	r5,SPRG3
+	li	r3,0
+	stb	r3,PACAPROCENABLED(r5)	/* ensure we are disabled */
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	.do_IRQ
+	b	irq_recheck	/* loop back and handle more */
+4:
+#endif
+_GLOBAL(do_bottom_half_ret)
+	ld	r3,_MSR(r1)	/* Returning to user mode? */
+	andi.	r3,r3,MSR_PR
+	beq+	restore		/* if so, check need_resched and signals */
+_GLOBAL(ret_to_user_hook)
+	nop
+	/* NEED_RESCHED is a volatile long (64-bits) */ 
+	ld	r3,NEED_RESCHED(r13)
+	cmpi	0,r3,0		/* check need_resched flag */
+	beq+	7f
+	bl	.schedule
+	/* SIGPENDING is an int (32-bits) */
+7:	
+	lwz	r5,SIGPENDING(r13) /* Check for pending unblocked signals */
+	cmpwi	0,r5,0
+	beq+	restore
+	li	r3,0
+	addi	r4,r1,STACK_FRAME_OVERHEAD
+	bl	.do_signal
+_GLOBAL(do_signal_ret)
+restore:	
+	ld	r3,_CTR(r1)
+	ld	r0,_LINK(r1)
+	mtctr	r3
+	mtlr	r0
+	ld	r3,_XER(r1)
+	mtspr	XER,r3
+	REST_8GPRS(5, r1)
+	REST_10GPRS(14, r1)
+	REST_8GPRS(24, r1)
+	
+	/* make sure we hard disable here, even if rtl is active, to protect
+	 * SRR[01] and SPRG2 -- Cort 
+	 */
+	mfmsr	r0		/* Get current interrupt state */
+	li	r4,0
+	ori	r4,r4,MSR_EE|MSR_RI
+	andc	r0,r0,r4	/* clear MSR_EE and MSR_RI */
+	mtmsrd	r0		/* Update machine state */
+#ifdef CONFIG_PPC_ISERIES
+	ld	r0,SOFTE(r1)
+	cmpi	0,r0,0
+	beq+	1f
+
+	CHECKANYINT(r4,r3)
+	beq+	1f
+	mfmsr	r0
+	ori	r0,r0,MSR_EE|MSR_RI
+	mtmsrd	r0
+	b	irq_recheck
+	
+1:	
+#endif
+	stdcx.	r0,0,r1		/* to clear the reservation */
+
+	mfspr	r4,SPRG3	/* current task's PACA */
+#ifdef DO_SOFT_DISABLE
+	ld	r0,SOFTE(r1)
+	stb	r0,PACAPROCENABLED(r4)
+#endif
+	/* if returning to user mode, save kernel SP */
+	ld	r0,_MSR(r1)
+	andi.	r0,r0,MSR_PR
+	beq+	1f
+	addi	r0,r1,INT_FRAME_SIZE	/* size of frame */
+	std	r0,THREAD+KSP(r13)	/* save kernel stack pointer */
+	std	r1,PACAKSAVE(r4)	/* save exception stack pointer */
+1:
+	ld	r0,_MSR(r1)
+	mtspr	SRR1,r0
+	ld	r2,_CCR(r1)
+	mtcrf	0xFF,r2
+	ld	r2,_NIP(r1)
+	mtspr	SRR0,r2
+	REST_GPR(13,r1)
+	ld	r0,GPR0(r1)
+	ld	r2,GPR2(r1)
+	ld	r3,GPR3(r1)
+	ld	r4,GPR4(r1)
+	ld	r1,GPR1(r1)
+
+	rfid
+
+/*
+ * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
+ * called with the MMU off.
+ *
+ * In addition, we need to be in 32b mode, at least for now.
+ * 
+ * Note: r3 is an input parameter to rtas, so don't trash it...
+ */
+_GLOBAL(enter_rtas)
+	mflr	r0
+	std	r0,16(r1)
+        stdu	r1,-RTAS_FRAME_SIZE(r1)	/* Save SP and create stack space. */
+
+	/* Because RTAS is running in 32b mode, it clobbers the high order half
+	 * of all registers that it saves.  We therefore save those registers
+	 * RTAS might touch to the stack.  (r0, r3-r13 are caller saved)
+   	 */
+	SAVE_GPR(2, r1)			/* Save the TOC */
+	SAVE_GPR(13, r1)		/* Save current */
+	SAVE_8GPRS(14, r1)		/* Save the non-volatiles */
+	SAVE_10GPRS(22, r1)		/* ditto */
+
+	mfcr	r4
+	std	r4,_CCR(r1)
+	mfctr	r5
+	std	r5,_CTR(r1)
+	mfspr	r6,XER
+	std	r6,_XER(r1)
+	mfdar	r7
+	std	r7,_DAR(r1)
+	mfdsisr	r8
+	std	r8,_DSISR(r1)
+	mfsrr0	r9
+	std	r9,_SRR0(r1)
+	mfsrr1	r10
+	std	r10,_SRR1(r1)
+
+	/* Unfortunatly, the stack pointer and the MSR are also clobbered,
+	 * so they are saved in the PACA (SPRG3) which allows us to restore
+	 * our original state after RTAS returns.
+         */
+	mfspr	r4,SPRG3		/* Get PACA */
+	std	r1,PACAR1(r4)
+	mfmsr	r6
+        std	r6,PACASAVEDMSR(r4)
+
+	/* Setup our real return addr */	
+	SET_REG_TO_LABEL(r4,.rtas_return_loc)
+	SET_REG_TO_CONST(r9,KERNELBASE)
+	sub	r4,r4,r9
+       	mtlr	r4
+
+	li	r0,0
+	ori	r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI
+	andc	r0,r6,r0
+	
+        li      r9,1
+        rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
+	ori	r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI
+	andc	r6,r0,r9
+	sync				/* disable interrupts so SRR0/1 */
+	mtmsrd	r0			/* don't get trashed */
+
+	SET_REG_TO_LABEL(r4,rtas)
+	ld	r5,RTASENTRY(r4)	/* get the rtas->entry value */
+	ld	r4,RTASBASE(r4)		/* get the rtas->base value */
+	
+	mtspr	SRR0,r5
+	mtspr	SRR1,r6
+	rfid
+
+_STATIC(rtas_return_loc)
+	/* relocation is off at this point */
+	mfspr	r4,SPRG3	        /* Get PACA */
+	SET_REG_TO_CONST(r5, KERNELBASE)
+        sub     r4,r4,r5                /* RELOC the PACA base pointer */
+        
+        ld	r1,PACAR1(r4)           /* Restore our SP */
+	LOADADDR(r3,.rtas_restore_regs)
+        ld	r4,PACASAVEDMSR(r4)     /* Restore our MSR */
+
+	mtspr	SRR0,r3
+	mtspr	SRR1,r4
+	rfid
+
+_STATIC(rtas_restore_regs)
+	/* relocation is on at this point */
+	REST_GPR(2, r1)			/* Restore the TOC */
+	REST_GPR(13, r1)		/* Restore current */
+	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
+	REST_10GPRS(22, r1)		/* ditto */
+
+	/* put back current in r13 */
+        mfspr	r4,SPRG3
+	ld	r13,PACACURRENT(r4)
+
+	ld	r4,_CCR(r1)
+	mtcr	r4
+	ld	r5,_CTR(r1)
+	mtctr	r5
+	ld	r6,_XER(r1)
+	mtspr	XER,r6
+	ld	r7,_DAR(r1)
+	mtdar	r7
+	ld	r8,_DSISR(r1)
+	mtdsisr	r8
+	ld	r9,_SRR0(r1)
+	mtsrr0	r9
+	ld	r10,_SRR1(r1)
+	mtsrr1	r10
+
+        addi	r1,r1,RTAS_FRAME_SIZE	/* Unstack our frame */
+	ld	r0,16(r1)		/* get return address */
+
+	mtlr    r0
+        blr				/* return to caller */
+
+_GLOBAL(enter_prom)
+	mflr	r0
+	std	r0,16(r1)
+        stdu	r1,-PROM_FRAME_SIZE(r1)	/* Save SP and create stack space */
+
+	/* Because PROM is running in 32b mode, it clobbers the high order half
+	 * of all registers that it saves.  We therefore save those registers
+	 * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
+   	 */
+	SAVE_8GPRS(2, r1)		/* Save the TOC & incoming param(s) */
+	SAVE_GPR(13, r1)		/* Save current */
+	SAVE_8GPRS(14, r1)		/* Save the non-volatiles */
+	SAVE_10GPRS(22, r1)		/* ditto */
+
+	mfcr	r4
+	std	r4,_CCR(r1)
+	mfctr	r5
+	std	r5,_CTR(r1)
+	mfspr	r6,XER
+	std	r6,_XER(r1)
+	mfdar	r7
+	std	r7,_DAR(r1)
+	mfdsisr	r8
+	std	r8,_DSISR(r1)
+	mfsrr0	r9
+	std	r9,_SRR0(r1)
+	mfsrr1	r10
+	std	r10,_SRR1(r1)
+	mfmsr	r11
+	std	r11,_MSR(r1)
+
+	/* Unfortunatly, the stack pointer is also clobbered, so it is saved
+	 * in the SPRG2 which allows us to restore our original state after
+	 * PROM returns.
+         */
+	mtspr	SPRG2,r1
+
+        /* put a relocation offset into r3 */
+        bl      .reloc_offset
+	LOADADDR(r12,prom)
+	sub	r12,r12,r3
+	ld	r12,PROMENTRY(r12)	/* get the prom->entry value */
+	mtlr	r12
+
+        mfmsr   r11			/* grab the current MSR */
+        li      r12,1
+        rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
+        andc    r11,r11,r12
+        li      r12,1
+        rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
+        andc    r11,r11,r12
+        mtmsrd  r11
+        isync
+
+	REST_8GPRS(2, r1)		/* Restore the TOC & param(s) */
+	REST_GPR(13, r1)		/* Restore current */
+	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
+	REST_10GPRS(22, r1)		/* ditto */
+	blrl				/* Entering PROM here... */
+
+	mfspr	r1,SPRG2		/* Restore the stack pointer */
+	ld	r6,_MSR(r1)		/* Restore the MSR */
+	mtmsrd	r6
+        isync
+
+	REST_GPR(2, r1)			/* Restore the TOC */
+	REST_GPR(13, r1)		/* Restore current */
+	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
+	REST_10GPRS(22, r1)		/* ditto */
+
+	ld	r4,_CCR(r1)
+	mtcr	r4
+	ld	r5,_CTR(r1)
+	mtctr	r5
+	ld	r6,_XER(r1)
+	mtspr	XER,r6
+	ld	r7,_DAR(r1)
+	mtdar	r7
+	ld	r8,_DSISR(r1)
+	mtdsisr	r8
+	ld	r9,_SRR0(r1)
+	mtsrr0	r9
+	ld	r10,_SRR1(r1)
+	mtsrr1	r10
+        addi	r1,r1,PROM_FRAME_SIZE
+	ld	r0,16(r1)		/* get return address */
+
+	mtlr    r0
+        blr				/* return to caller */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/flight_recorder.c linux/arch/ppc64/kernel/flight_recorder.c
--- linux.orig/arch/ppc64/kernel/flight_recorder.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/flight_recorder.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,182 @@
+/************************************************************************
+ * flight_recorder.c
+ ************************************************************************
+ * This code supports the a generic flight recorder.                    *
+ * Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    * 
+ *                                                                      *
+ * 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                                          *
+ ************************************************************************
+ * This is a simple text based flight recorder.  Useful for logging 
+ * information the you may want to retreive at a latter time.  Errors or 
+ * debug inforamtion are good examples.   A good method to dump the 
+ * information is via the proc file system. 
+ *
+ * To use. 
+ * 1. Create the flight recorder object.  Passing a NULL pointer will 
+ *    kmalloc the space for you.  If it is too early for kmalloc, create 
+ *    space for the object.   Beware, don't lie about the size, you will
+ *    pay for that later. 
+ * 		FlightRecorder* TestFr = alloc_Flight_Recorder(NULL,"TestFr",4096);
+ *   
+ * 2. Log any notable events, initialzation, error conditions, etc. 
+ *		LOGFR(TestFr,"5. Stack Variable(10) %d",StackVariable);
+ * 
+ * 3. Dump the information to a buffer. 
+ *		fr_Dump(TestFr, proc_file_buffer, proc_file_buffer_size);
+ *
+ ************************************************************************/
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <asm/string.h>
+#include <asm/time.h>
+#include <asm/flight_recorder.h>
+
+static  char       LogText[512];
+static  int        LogTextIndex;
+static  int        LogCount = 0;
+static  spinlock_t Fr_Lock;
+
+/************************************************************************
+ * Build the log time prefix based on Flags.
+ *  00 = No time prefix
+ *  01 = Date(mmddyy) Time(hhmmss) prefix
+ *  02 = Day(dd) Time(hhmmss) prefix
+ *  03 = Time(hhmmss) prefix
+ ************************************************************************/
+static void fr_Log_Time(FlightRecorder* Fr)
+{
+	struct  timeval  TimeClock;
+	struct  rtc_time LogTime;
+
+	do_gettimeofday(&TimeClock);
+	to_tm(TimeClock.tv_sec, &LogTime);
+
+	if (Fr->Flags == 1) {    
+		LogTextIndex = sprintf(LogText,"%02d%02d%02d %02d%02d%02d ",
+		                       LogTime.tm_mon, LogTime.tm_mday, LogTime.tm_year-2000,
+	     	                  LogTime.tm_hour,LogTime.tm_min, LogTime.tm_sec);
+	}
+	else if (Fr->Flags == 2) {    
+		LogTextIndex = sprintf(LogText,"%02d %02d%02d%02d ",
+		                       LogTime.tm_mday,
+	     	                  LogTime.tm_hour,LogTime.tm_min, LogTime.tm_sec);
+	}
+
+	else if (Fr->Flags == 3) {    
+		LogTextIndex = sprintf(LogText,"%02d%02d%02d ",
+	     	                  LogTime.tm_hour,LogTime.tm_min, LogTime.tm_sec);
+	}
+	else {
+		++LogCount;
+		LogTextIndex = sprintf(LogText,"%04d. ",LogCount);
+	}
+}
+
+/************************************************************************/
+/* Log entry into buffer,                                               */
+/* ->If entry is going to wrap, log "WRAP" and start at the top.        */
+/************************************************************************/
+static void fr_Log_Data(FlightRecorder* Fr)
+{
+	int 	TextLen  = strlen(LogText);
+	int 	Residual = ( Fr->EndPointer - Fr->NextPointer)-15;
+	if (TextLen > Residual) {
+		strcpy(Fr->NextPointer,"WRAP");
+		Fr->WrapPointer = Fr->NextPointer + 5;
+		Fr->NextPointer = Fr->StartPointer;
+	}
+	strcpy(Fr->NextPointer,LogText);
+	Fr->NextPointer += TextLen+1;
+	strcpy(Fr->NextPointer,"<=");
+}
+/************************************************************************
+ * Build the log text, support variable args.
+ ************************************************************************/
+void fr_Log_Entry(struct flightRecorder* LogFr, const char *fmt, ...)
+{
+	va_list arg_ptr;
+	spin_lock(&Fr_Lock);
+
+	fr_Log_Time(LogFr); 
+	va_start(arg_ptr, fmt);
+	vsprintf(LogText+LogTextIndex, fmt, arg_ptr);
+	va_end(arg_ptr);
+	fr_Log_Data(LogFr);
+
+	spin_unlock(&Fr_Lock);
+
+}
+/************************************************************************
+ * Dump Flight Recorder into buffer.
+ * -> Handles the buffer wrapping.
+ ************************************************************************/
+int fr_Dump(FlightRecorder* Fr, char *Buffer, int BufferLen)
+{
+	int   LineLen = 0;
+	char* StartEntry;
+	char* EndEntry;
+	spin_lock(&Fr_Lock);
+	/****************************************************************
+	 * If Buffer has wrapped, find last usable entry to start with.
+	 ****************************************************************/
+	if (Fr->WrapPointer != NULL) {
+		StartEntry  = Fr->NextPointer+3;
+		StartEntry += strlen(StartEntry)+1;
+		EndEntry    = Fr->WrapPointer;
+
+		while (EndEntry > StartEntry && LineLen < BufferLen) {
+			LineLen    += sprintf(Buffer+LineLen,"%s\n",StartEntry);
+			StartEntry += strlen(StartEntry) + 1;
+		}
+	}
+
+	/****************************************************************
+	 * Dump from the beginning to the last logged entry
+	 ****************************************************************/
+	StartEntry = Fr->StartPointer;
+	EndEntry   = Fr->NextPointer;
+	while (EndEntry > StartEntry && LineLen < BufferLen) {
+		LineLen    += sprintf(Buffer+LineLen,"%s\n",StartEntry);
+		StartEntry += strlen(StartEntry) + 1;
+	}
+	spin_unlock(&Fr_Lock);
+	return LineLen;
+}
+
+/************************************************************************
+ * Allocate and Initialized the Flight Recorder
+ * -> If no FlightRecorder pointer is passed, the space is kmalloc.
+ ************************************************************************/
+FlightRecorder* alloc_Flight_Recorder(FlightRecorder* FrPtr, char* Signature, int SizeOfFr)
+{
+	FlightRecorder* Fr     = FrPtr;				/* Pointer to Object */
+	int             FrSize = (SizeOfFr/16)*16;	/* Could be static   */
+	if (Fr == NULL)
+		Fr = (FlightRecorder*)kmalloc(SizeOfFr, GFP_KERNEL);
+	memset(Fr,0,SizeOfFr);
+	strcpy(Fr->Signature,Signature);
+	Fr->Size         = FrSize;
+	Fr->Flags        = 0;
+	Fr->StartPointer = (char*)&Fr->Buffer;
+	Fr->EndPointer   = (char*)Fr + Fr->Size;
+	Fr->NextPointer  = Fr->StartPointer;
+
+	fr_Log_Entry(Fr,"Initialized.");
+	return Fr;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/head.S linux/arch/ppc64/kernel/head.S
--- linux.orig/arch/ppc64/kernel/head.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/head.S	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,1897 @@
+/*
+ *  arch/ppc64/kernel/head.S
+ *
+ *  PowerPC version
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ *  Adapted for Power Macintosh by Paul Mackerras.
+ *  Low-level exception handlers and MMU support
+ *  rewritten by Paul Mackerras.
+ *    Copyright (C) 1996 Paul Mackerras.
+ *
+ *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
+ *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
+ *
+ *  This file contains the low-level support and setup for the
+ *  PowerPC-64 platform, including trap and interrupt dispatch.
+ *
+ *  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.
+ */
+
+#define SECONDARY_PROCESSORS
+
+#include "ppc_asm.h"
+#include "ppc_defs.h"
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <linux/config.h>
+#include <asm/mmu.h>
+// #include <asm/paca.h>
+
+#ifdef CONFIG_PPC_ISERIES
+#define DO_SOFT_DISABLE
+#endif
+
+/*
+ * hcall interface to pSeries LPAR
+ */
+#define HSC .long 0x44000022
+#define H_SET_ASR		0x30
+
+/*
+ * We layout physical memory as follows:
+ * 0x0000 - 0x00ff : Secondary processor spin code
+ * 0x0100 - 0x2fff : pSeries Interrupt prologs
+ * 0x3000 - 0x3fff : Interrupt support
+ * 0x4000 - 0x4fff : NACA
+ * 0x5000 - 0x5fff : Initial segment table
+ * 0x6000          : iSeries and common interrupt prologs
+ */
+
+/*
+ *   SPRG Usage
+ *
+ *   Register          Definition
+ *
+ *   SPRG0             reserved for hypervisor
+ *   SPRG1             temp - used to save gpr
+ *   SPRG2             temp - used to save gpr
+ *   SPRG3             virt addr of paca
+ */
+
+/*
+ * Entering into this code we make the following assumptions:
+ *  For pSeries:
+ *   1. The MMU is off & open firmware is running in real mode.
+ *   2. The kernel is entered at __start
+ *
+ *  For iSeries:
+ *   1. The MMU is on (as it always is for iSeries)
+ *   2. The kernel is entered at SystemReset_Iseries
+ */
+
+	.text
+	.globl  _stext
+_stext:
+_STATIC(__start)
+	b .__start_initialization_pSeries
+
+	/* At offset 0x20, there is a pointer to iSeries LPAR data.
+	 * This is required by the hypervisor */
+	. = 0x20
+	.llong hvReleaseData-KERNELBASE
+
+	/* At offset 0x28 and 0x30 are offsets to the msChunks
+	 * array (used by the iSeries LPAR debugger to do translation
+	 * between physical addresses and absolute addresses) and
+	 * to the pidhash table (also used by the debugger) */
+	.llong msChunks-KERNELBASE
+	.llong pidhash-KERNELBASE
+
+	/* Offset 0x38 - Pointer to start of embedded System.map */
+	.globl	embedded_sysmap_start
+embedded_sysmap_start:
+	.llong	0
+	/* Offset 0x40 - Pointer to end of embedded System.map */
+	.globl	embedded_sysmap_end
+embedded_sysmap_end:
+	.llong	0
+
+	/* Secondary processors spin on this value until it goes to 1. */
+	.globl  __secondary_hold_spinloop
+__secondary_hold_spinloop:
+	.llong  0x0
+
+	/* Secondary processors write this value with their cpu # */
+	/* after they enter the spin loop immediatly below.       */
+	.globl  __secondary_hold_acknowledge
+__secondary_hold_acknowledge:
+	.llong  0x0
+
+	. = 0x60
+/*
+ * The following code is used on pSeries to hold secondary processors
+ * in a spin loop after they have been freed from OpenFirmware, but
+ * before the bulk of the kernel has been relocated.  This code
+ * is relocated to physical address 0x60 before prom_init is run.
+ * All of it must fit below the first exception vector at 0x100.
+ */
+_GLOBAL(__secondary_hold)
+	/* Grab our linux cpu number */
+	mr      r24,r3
+
+	/* Tell the master cpu we're here */
+	/* Relocation is off & we are located at an address less */
+	/* than 0x100, so only need to grab low order offset.    */
+	std     r24,__secondary_hold_acknowledge@l(0)
+
+	/* All secondary cpu's wait here until told to start. */
+100:    ld      r4,__secondary_hold_spinloop@l(0)
+	cmpdi   0,r4,1
+	bne     100b
+
+#ifdef CONFIG_HMT
+	b	.hmt_init
+#else
+#ifdef CONFIG_SMP
+	mr      r3,r24
+	b       .pseries_secondary_smp_init
+#else
+	BUG_OPCODE
+#endif
+#endif
+
+/*
+ * The following macros define the code that appears as
+ * the prologue to each of the exception handlers.  They
+ * are split into two parts to allow a single kernel binary
+ * to be used for pSeries, and iSeries.
+ */
+
+/*
+ * We make as much of the exception code common between native Pseries
+ * and Iseries LPAR implementations as possible.
+ */
+
+/*
+ * This is the start of the interrupt handlers for Pseries
+ * This code runs with relocation off.
+ */
+#define EX_SRR0		0
+#define EX_SRR1		8
+#define EX_R20		16
+#define EX_R21		24
+#define EX_R22		32
+#define EX_R23		40
+#define EX_DAR		48
+#define EX_DSISR	56
+#define EX_CCR   	60
+#define EX_TRAP   	60
+
+#define EXCEPTION_PROLOG_PSERIES(n,label)                                \
+	mtspr   SPRG2,r20;              /* use SPRG2 as scratch reg   */ \
+	mtspr   SPRG1,r21;              /* save r21                   */ \
+	mfspr   r20,SPRG3;              /* get paca virt addr         */ \
+	ld      r21,PACAEXCSP(r20);     /* get exception stack ptr    */ \
+	addi    r21,r21,EXC_FRAME_SIZE; /* make exception frame       */ \
+	std	r22,EX_R22(r21);	/* Save r22 in exc. frame     */ \
+	li	r22,n;                  /* Save the ex # in exc. frame*/ \
+	stw	r22,EX_TRAP(r21);	/*                            */ \
+	std	r23,EX_R23(r21);	/* Save r23 in exc. frame     */ \
+	mfspr   r22,SRR0;               /* EA of interrupted instr    */ \
+	std	r22,EX_SRR0(r21);	/* Save SRR0 in exc. frame    */ \
+	mfspr   r23,SRR1;               /* machine state at interrupt */ \
+	std	r23,EX_SRR1(r21);	/* Save SRR1 in exc. frame    */ \
+	clrrdi  r22,r20,60;             /* Get 0xc part of the vaddr  */ \
+	ori	r22,r22,(label)@l;      /* add in the vaddr offset    */ \
+		                        /*   assumes *_common < 16b   */ \
+	mfmsr   r23;                                                     \
+	rotldi  r23,r23,4;                                               \
+	ori     r23,r23,0x30B;          /* Set IR, DR, SF, ISF, HV    */ \
+	rotldi  r23,r23,60;             /* for generic handlers       */ \
+	mtspr   SRR0,r22;                                                \
+	mtspr   SRR1,r23;                                                \
+	mfcr    r23;                    /* save CR in r23             */ \
+	rfid
+
+/*
+ * This is the start of the interrupt handlers for i_series
+ * This code runs with relocation on.
+ */
+#define EXCEPTION_PROLOG_ISERIES(n)	                                      \
+	mtspr	SPRG2,r20;		    /* use SPRG2 as scratch reg    */ \
+	mtspr   SPRG1,r21;                  /* save r21                    */ \
+	mfspr	r20,SPRG3;		    /* get Paca                    */ \
+	ld      r21,PACAEXCSP(r20);         /* get exception stack ptr     */ \
+	addi    r21,r21,EXC_FRAME_SIZE;     /* make exception frame        */ \
+	std	r22,EX_R22(r21);	    /* save r22 on exception frame */ \
+	li	r22,n;                      /* Save the ex # in exc. frame */ \
+	stw	r22,EX_TRAP(r21);	    /*                             */ \
+	std	r23,EX_R23(r21);	    /* Save r23 in exc. frame      */ \
+	ld      r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca      */ \
+	std	r22,EX_SRR0(r21);	    /* save SRR0 in exc. frame     */ \
+	ld      r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca      */ \
+	std	r23,EX_SRR1(r21);	    /* save SRR1 in exc. frame     */ \
+	mfcr    r23;                        /* save CR in r23              */
+
+/*
+ * The common exception prolog is used for all except a few exceptions
+ * such as a segment miss on a kernel address.  We have to be prepared
+ * to take another exception from the point where we first touch the
+ * kernel stack onwards.
+ *
+ * On entry r20 points to the paca and r21 points to the exception
+ * frame on entry, r23 contains the saved CR, and relocation is on.
+ */
+#define EXCEPTION_PROLOG_COMMON                                           \
+	mfspr	r22,SPRG2;		/* Save r20 in exc. frame      */ \
+	std	r22,EX_R20(r21);	                                  \
+	mfspr	r22,SPRG1;		/* Save r21 in exc. frame      */ \
+	std	r22,EX_R21(r21);	                                  \
+	mfspr   r22,DAR;                /* Save DAR in exc. frame      */ \
+	std	r22,EX_DAR(r21);	                                  \
+	std     r21,PACAEXCSP(r20);     /* update exception stack ptr  */ \
+		                        /*   iff no protection flt     */ \
+	mfspr	r22,DSISR;		/* Save DSISR in exc. frame    */ \
+	stw	r22,EX_DSISR(r21);	                                  \
+	ld	r22,EX_SRR1(r21);	/* Get SRR1 from exc. frame    */ \
+	andi.   r22,r22,MSR_PR;         /* Set CR for later branch     */ \
+	mr      r22,r1;                 /* Save r1                     */ \
+	subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack */ \
+	beq-    1f;                                                       \
+	ld      r1,PACAKSAVE(r20);      /* kernel stack to use         */ \
+1:      std     r22,GPR1(r1);           /* save r1 in stackframe       */ \
+	std     r22,0(r1);              /* make stack chain pointer    */ \
+	std     r23,_CCR(r1);           /* save CR in stackframe       */ \
+	ld	r22,EX_R20(r21);	/* move r20 to stackframe      */ \
+	std	r22,GPR20(r1);		                                  \
+	ld	r23,EX_R21(r21);	/* move r21 to stackframe      */ \
+	std	r23,GPR21(r1);		                                  \
+	ld	r22,EX_R22(r21);	/* move r22 to stackframe      */ \
+	std	r22,GPR22(r1);		                                  \
+	ld	r23,EX_R23(r21);	/* move r23 to stackframe      */ \
+	std	r23,GPR23(r1);		                                  \
+	mflr    r22;                    /* save LR in stackframe       */ \
+	std     r22,_LINK(r1);                                            \
+	mfctr   r23;                    /* save CTR in stackframe      */ \
+	std     r23,_CTR(r1);                                             \
+	mfspr   r22,XER;                /* save XER in stackframe      */ \
+	std     r22,_XER(r1);                                             \
+	ld	r23,EX_DAR(r21);	/* move DAR to stackframe      */ \
+	std	r23,_DAR(r1);		                                  \
+	lwz     r22,EX_DSISR(r21);	/* move DSISR to stackframe    */ \
+	std	r22,_DSISR(r1);		                                  \
+	lbz	r22,PACAPROCENABLED(r20);                                 \
+	std	r22,SOFTE(r1);		                                  \
+	ld	r22,EX_SRR0(r21);	/* get SRR0 from exc. frame    */ \
+	ld	r23,EX_SRR1(r21);	/* get SRR1 from exc. frame    */ \
+	addi    r21,r21,-EXC_FRAME_SIZE;/* pop off exception frame     */ \
+	std     r21,PACAEXCSP(r20);                                       \
+	SAVE_GPR(0, r1);                /* save r0 in stackframe       */ \
+	SAVE_8GPRS(2, r1);              /* save r2 - r13 in stackframe */ \
+	SAVE_4GPRS(10, r1);                                               \
+	ld      r2,PACATOC(r20);	                                  \
+	ld      r13,PACACURRENT(r20)
+
+/*
+ * Note: code which follows this uses cr0.eq (set if from kernel),
+ * r1, r22 (SRR0), and r23 (SRR1).
+ */
+
+/*
+ * Exception vectors.
+ */
+#define STD_EXCEPTION_PSERIES(n, label )	\
+	. = n;					\
+	.globl label##_Pseries;			\
+label##_Pseries:				\
+	EXCEPTION_PROLOG_PSERIES( n, label##_common )
+
+#define STD_EXCEPTION_ISERIES( n, label )	\
+	.globl label##_Iseries;			\
+label##_Iseries:				\
+	EXCEPTION_PROLOG_ISERIES( n );          \
+	b	label##_common
+
+#define MASKABLE_EXCEPTION_ISERIES( n, label )	\
+	.globl label##_Iseries;			\
+label##_Iseries:				\
+	EXCEPTION_PROLOG_ISERIES( n );		\
+	lbz	r22,PACAPROFENABLED(r20);	\
+	cmpi	0,r22,0;			\
+	bne-	label##_Iseries_profile;	\
+label##_Iseries_prof_ret:			\
+	lbz	r22,PACAPROCENABLED(r20);	\
+	cmpi	0,r22,0;			\
+	beq-	label##_Iseries_masked;		\
+	b	label##_common;			\
+label##_Iseries_profile:			\
+	std	r24,48(r21);			\
+	std	r25,56(r21);			\
+	mflr	r24;				\
+	bl	do_profile;			\
+	mtlr	r24;				\
+	ld	r24,48(r21);			\
+	ld	r25,56(r21);			\
+	b	label##_Iseries_prof_ret
+
+#define STD_EXCEPTION_COMMON( trap, label, hdlr )	\
+	.globl label##_common;			\
+label##_common:					\
+	EXCEPTION_PROLOG_COMMON;		\
+	addi	r3,r1,STACK_FRAME_OVERHEAD;	\
+	li	r20,0;				\
+	li	r6,trap;			\
+	bl      .save_remaining_regs;           \
+	bl      hdlr;                           \
+	b       .ret_from_except
+
+/*
+ * Start of pSeries system interrupt routines
+ */
+	. = 0x100
+	.globl __start_interupts
+__start_interupts:
+
+	STD_EXCEPTION_PSERIES( 0x100, SystemReset )
+	STD_EXCEPTION_PSERIES( 0x200, MachineCheck )
+	STD_EXCEPTION_PSERIES( 0x300, DataAccess )
+	STD_EXCEPTION_PSERIES( 0x380, DataAccessSLB )
+	STD_EXCEPTION_PSERIES( 0x400, InstructionAccess )
+	STD_EXCEPTION_PSERIES( 0x480, InstructionAccessSLB )
+	STD_EXCEPTION_PSERIES( 0x500, HardwareInterrupt )
+	STD_EXCEPTION_PSERIES( 0x600, Alignment )
+	STD_EXCEPTION_PSERIES( 0x700, ProgramCheck )
+	STD_EXCEPTION_PSERIES( 0x800, FPUnavailable )
+	STD_EXCEPTION_PSERIES( 0x900, Decrementer )
+	STD_EXCEPTION_PSERIES( 0xa00, Trap_0a )
+	STD_EXCEPTION_PSERIES( 0xb00, Trap_0b )
+	STD_EXCEPTION_PSERIES( 0xc00, SystemCall )
+	STD_EXCEPTION_PSERIES( 0xd00, SingleStep )
+	STD_EXCEPTION_PSERIES( 0xe00, Trap_0e )
+	STD_EXCEPTION_PSERIES( 0xf00, PerformanceMonitor )
+	STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint )
+
+	/* Space for the naca.  Architected to be located at real address
+	 * 0x4000.  Various tools rely on this location being fixed.
+	 * The first dword of the Naca is required by iSeries LPAR to
+	 * point to itVpdAreas.  On pSeries native, this value is not used.
+	 */
+	. = 0x4000
+	.globl __end_interupts
+	.globl __start_naca
+__end_interupts:
+__start_naca:
+	.llong itVpdAreas
+	.llong 0x0
+	.llong 0x0
+	.llong paca
+
+	/*
+	 * Space for the initial segment table
+	 * For LPAR, the hypervisor must fill in at least one entry
+	 * before we get control (with relocate on)
+	 */
+	. = 0x5000
+	.globl __end_naca
+	.globl __start_stab
+__end_naca:
+__start_stab:
+
+
+	. = 0x6000
+	.globl __end_stab
+__end_stab:
+
+	/*
+	 * The iSeries LPAR map is at this fixed address
+	 * so that the HvReleaseData structure can address
+	 * it with a 32-bit offset.
+	 *
+	 * The VSID values below are dependent on the
+	 * VSID generation algorithm.  See include/asm/mmu_context.h.
+	 */
+
+	.llong	1		/* # ESIDs to be mapped by hypervisor         */
+	.llong	1		/* # memory ranges to be mapped by hypervisor */
+	.llong	5		/* Page # of segment table within load area   */
+	.llong	0		/* Reserved */
+	.llong  0		/* Reserved */
+	.llong  0		/* Reserved */
+	.llong	0		/* Reserved */
+	.llong	0		/* Reserved */
+	.llong	0x0c00000000	/* ESID to map (Kernel at EA = 0xC000000000000000) */
+	.llong	0x06a99b4b14    /* VSID to map (Kernel at VA = 0x6a99b4b140000000) */
+	.llong	8192		/* # pages to map (32 MB) */
+	.llong	0		/* Offset from start of loadarea to start of map */
+	.llong	0x0006a99b4b140000	/* VPN of first page to map */
+
+	. = 0x6100
+
+/***  ISeries-LPAR interrupt handlers ***/
+
+	STD_EXCEPTION_ISERIES( 0x200, MachineCheck )
+	STD_EXCEPTION_ISERIES( 0x300, DataAccess )
+	STD_EXCEPTION_ISERIES( 0x380, DataAccessSLB )
+	STD_EXCEPTION_ISERIES( 0x400, InstructionAccess )
+	STD_EXCEPTION_ISERIES( 0x480, InstructionAccessSLB )
+	MASKABLE_EXCEPTION_ISERIES( 0x500, HardwareInterrupt )
+	STD_EXCEPTION_ISERIES( 0x600, Alignment )
+	STD_EXCEPTION_ISERIES( 0x700, ProgramCheck )
+	STD_EXCEPTION_ISERIES( 0x800, FPUnavailable )
+	MASKABLE_EXCEPTION_ISERIES( 0x900, Decrementer )
+	STD_EXCEPTION_ISERIES( 0xa00, Trap_0a )
+	STD_EXCEPTION_ISERIES( 0xb00, Trap_0b )
+	STD_EXCEPTION_ISERIES( 0xc00, SystemCall )
+	STD_EXCEPTION_ISERIES( 0xd00, SingleStep )
+	STD_EXCEPTION_ISERIES( 0xe00, Trap_0e )
+	STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor )
+
+	.globl SystemReset_Iseries
+SystemReset_Iseries:
+	mfspr	25,SPRG3		/* Get paca address */
+	lhz	r24,PACAPACAINDEX(r25)	/* Get processor # */
+	cmpi	0,r24,0			/* Are we processor 0? */
+	beq	.__start_initialization_iSeries	/* Start up the first processor */
+	mfspr	r4,CTRLF
+	li	r5,RUNLATCH		/* Turn off the run light */
+	andc	r4,r4,r5
+	mtspr	CTRLT,r4
+
+1:
+	HMT_LOW
+#ifdef CONFIG_SMP
+	lbz	r23,PACAPROCSTART(r25)	/* Test if this processor
+					 * should start */
+	sync
+	LOADADDR(r3,current_set)
+	sldi	r28,r24,4		/* get current_set[cpu#] */
+	ldx	r3,r3,r28
+	addi	r1,r3,TASK_UNION_SIZE
+	subi	r1,r1,STACK_FRAME_OVERHEAD
+
+	cmpi	0,r23,0
+	beq	iseries_secondary_smp_loop	/* Loop until told to go */
+#ifdef SECONDARY_PROCESSORS
+	bne	.__secondary_start		/* Loop until told to go */
+#endif
+iseries_secondary_smp_loop:
+	/* Let the Hypervisor know we are alive */
+	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
+	lis	r3,0x8002
+	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
+#else /* CONFIG_SMP */
+	/* Yield the processor.  This is required for non-SMP kernels
+	   which are running on multi-threaded machines. */
+	lis	r3,0x8000
+	rldicr	r3,r3,32,15		/* r3 = (r3 << 32) & 0xffff000000000000 */
+	addi	r3,r3,18		/* r3 = 0x8000000000000012 which is "yield" */
+	li	r4,0			/* "yield timed" */
+	li	r5,-1			/* "yield forever" */
+#endif /* CONFIG_SMP */
+	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
+	sc				/* Invoke the hypervisor via a system call */
+	mfspr	r25,SPRG3		/* Put r25 back ???? */
+	b	1b			/* If SMP not configured, secondaries
+					 * loop forever */
+
+	.globl HardwareInterrupt_Iseries_masked
+HardwareInterrupt_Iseries_masked:
+	b	maskable_exception_exit
+
+	.globl Decrementer_Iseries_masked
+Decrementer_Iseries_masked:
+	li	r22,1
+	stb	r22,PACALPPACA+LPPACADECRINT(r20)
+	lwz	r22,PACADEFAULTDECR(r20)
+	mtspr	DEC,r22
+maskable_exception_exit:
+	mtcrf	0xff,r23		/* Restore regs and free exception frame */
+	ld	r22,EX_SRR0(r21)
+	ld	r23,EX_SRR1(r21)
+	mtspr	SRR0,r22
+	mtspr	SRR1,r23
+	ld	r22,EX_R22(r21)
+	ld	r23,EX_R23(r21)
+	mfspr	r21,SPRG1
+	mfspr	r20,SPRG2
+	rfid
+
+/*
+ * Data area reserved for FWNMI option.
+ */
+        .= 0x7000
+	.globl fwnmi_data_area
+fwnmi_data_area:
+
+/*
+ * Vectors for the FWNMI option.  Share common code.
+ */
+	. = 0x8000
+	.globl SystemReset_FWNMI
+SystemReset_FWNMI:
+	EXCEPTION_PROLOG_PSERIES(0x100, SystemReset_common)
+	.globl MachineCheck_FWNMI
+MachineCheck_FWNMI:
+	EXCEPTION_PROLOG_PSERIES(0x200, MachineCheck_common)
+
+/*** Common interrupt handlers ***/
+
+	STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException )
+	STD_EXCEPTION_COMMON( 0x200, MachineCheck, .MachineCheckException )
+	STD_EXCEPTION_COMMON( 0x900, Decrementer, .timer_interrupt )
+	STD_EXCEPTION_COMMON( 0xa00, Trap_0a, .UnknownException )
+	STD_EXCEPTION_COMMON( 0xb00, Trap_0b, .UnknownException )
+	STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException )
+	STD_EXCEPTION_COMMON( 0xe00, Trap_0e, .UnknownException )
+	STD_EXCEPTION_COMMON( 0xf00, PerformanceMonitor, .PerformanceMonitorException )
+	STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException )
+
+/*
+ * Return from an exception which is handled without calling
+ * save_remaining_regs.  The caller is assumed to have done
+ * EXCEPTION_PROLOG_COMMON.
+ */
+fast_exception_return:
+	ld      r3,_CCR(r1)
+	ld      r4,_LINK(r1)
+	ld      r5,_CTR(r1)
+	ld      r6,_XER(r1)
+	mtcr    r3
+	mtlr    r4
+	mtctr   r5
+	mtspr   XER,r6
+	REST_GPR(0, r1)
+	REST_8GPRS(2, r1)
+	REST_4GPRS(10, r1)
+	mtspr   SRR1,r23
+	mtspr   SRR0,r22
+	REST_4GPRS(20, r1)
+	ld      r1,GPR1(r1)
+	rfid
+
+/*
+ * Here r20 points to the PACA, r21 to the exception frame,
+ * r23 contains the saved CR.
+ * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ */
+	.globl DataAccess_common
+DataAccess_common:
+	mfspr   r22,DAR
+	srdi    r22,r22,60
+	cmpi    0,r22,0xc
+	beq     .do_stab_bolted
+	cmpi    0,r22,0xb
+	beq     .do_stab_bolted
+
+stab_bolted_user_return:
+	EXCEPTION_PROLOG_COMMON
+	ld      r3,_DSISR(r1)
+	andis.	r0,r3,0xa450		/* weird error? */
+	bne	1f			/* if not, try to put a PTE */
+	andis.	r0,r3,0x0020		/* Is it a page table fault? */
+	rlwinm	r4,r3,32-23,29,29	/* DSISR_STORE -> _PAGE_RW */
+	ld      r3,_DAR(r1)             /* into the hash table */
+
+	beq	2f			/* If so handle it */
+	li	r4,0x300                /* Trap number */
+	bl	.do_stab_SI
+	b	1f
+
+2:	bl	.do_hash_page_DSI 	/* Try to handle as hpte fault */
+1:
+	ld      r4,_DAR(r1)
+	ld      r5,_DSISR(r1)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)		/* Copy saved SOFTE bit */
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
+	li	r6,0x300
+	bl      .save_remaining_regs
+	bl      .do_page_fault
+	b       .ret_from_except
+
+	.globl DataAccessSLB_common
+DataAccessSLB_common:
+	mfspr   r22,DAR
+	srdi    r22,r22,60
+	cmpi    0,r22,0xc
+	beq     .do_slb_bolted
+	cmpi    0,r22,0xb
+	beq     .do_slb_bolted
+
+	EXCEPTION_PROLOG_COMMON
+	ld      r3,_DAR(r1)
+	li      r4,0x380                /* Exception vector  */
+	bl	.ste_allocate
+	or.	r3,r3,r3		/* Check return code */
+	beq     fast_exception_return   /* Return if we succeeded */
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
+	li	r6,0x380
+	bl      .save_remaining_regs
+	bl      .do_page_fault
+	b       .ret_from_except
+
+	.globl InstructionAccess_common
+InstructionAccess_common:
+	EXCEPTION_PROLOG_COMMON
+
+	andis.	r0,r23,0x0020		/* no ste found? */
+	beq	2f
+	mr	r3,r22			/* SRR0 at interrupt */
+	li	r4,0x400		/* Trap number       */
+	bl	.do_stab_SI
+	b	1f
+
+2:	andis.	r0,r23,0x4000		/* no pte found? */
+	beq	1f			/* if so, try to put a PTE */
+	mr	r3,r22			/* into the hash table */
+	bl	.do_hash_page_ISI	/* Try to handle as hpte fault */
+1:
+	mr	r4,r22
+	mr	r5,r23
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
+	li	r6,0x400
+	bl      .save_remaining_regs
+	bl      .do_page_fault
+	b       .ret_from_except
+
+	.globl InstructionAccessSLB_common
+InstructionAccessSLB_common:
+	EXCEPTION_PROLOG_COMMON
+	mr      r3,r22                  /* SRR0 = NIA        */
+	li	r4,0x480                /* Exception vector  */
+	bl	.ste_allocate
+	or.	r3,r3,r3		/* Check return code */
+	beq     fast_exception_return   /* Return if we succeeded */
+
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
+	li	r6,0x380
+	bl      .save_remaining_regs
+	bl      .do_page_fault
+	b       .ret_from_except
+
+	.globl HardwareInterrupt_common
+HardwareInterrupt_common:
+	EXCEPTION_PROLOG_COMMON
+HardwareInterrupt_entry:
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,0
+	li	r6,0x500
+	bl      .save_remaining_regs
+	/* Determine if need to run do_irq on a hardware interrupt stack  */
+	/*   The first invocation of do_irq will occur on the kernel      */
+	/*   stack in the current stack                                   */
+	/*   All other invocations of do_irq will run on the hardware     */
+	/*   interrupt stack associated with the PACA of the current      */
+	/*   processor.                                                   */
+	/*                                                                */
+	/*  The call to do_irq will preserve the value of r14 - r31       */
+	/*                                                                */
+	mfspr	r20,SPRG3 		    /* get paca                   */
+	lbz     r21,PACAHRDWINTCOUNT(r20)    /* get hardware interrupt cnt */
+	cmpi    0,r21,0                     /*                            */
+	addi    r21,r21,1                   /* incr hardware interrupt cnt*/
+	stb     r21,PACAHRDWINTCOUNT(r20)   /*                            */
+	bne     2f                          /*                            */
+
+	mr      r14,r1                      /* preserve current r1        */
+	ld      r1,PACAHRDWINTSTACK(r20)    /*                            */
+	std     r14,0(r1)                   /* set the back chain         */
+	bl      .do_IRQ
+	lbz     r22,PACAHRDWINTCOUNT(r20)   /* get hardware interrupt cnt */
+	cmp     0,r22,r21                   /* debug test                 */
+	bne     3f
+	subi    r21,r21,1
+	stb     r21,PACAHRDWINTCOUNT(r20)   /*                            */
+	mr      r1,r14                      /*                            */
+	b       .ret_from_except
+
+2:
+	bl      .do_IRQ
+
+	lbz     r22,PACAHRDWINTCOUNT(r20)   /* get hardware interrupt cnt */
+	cmp     0,r22,r21                   /* debug test                 */
+	bne     3f                          /*                            */
+	subi    r21,r21,1                   /* decr hardware interrupt cnt*/
+	stb     r21,PACAHRDWINTCOUNT(r20)   /*                            */
+
+	b       .ret_from_except
+
+3:
+	/* error - counts out of sync                                      */
+#ifdef CONFIG_XMON
+	bl	.xmon
+#endif
+4:	b	4b
+
+
+	.globl Alignment_common
+Alignment_common:
+	EXCEPTION_PROLOG_COMMON
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
+	li	r6,0x600
+	bl      .save_remaining_regs
+	bl      .AlignmentException
+	b       .ret_from_except
+
+	.globl ProgramCheck_common
+ProgramCheck_common:
+	EXCEPTION_PROLOG_COMMON
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
+	li	r6,0x700
+	bl      .save_remaining_regs
+	bl      .ProgramCheckException
+	b       .ret_from_except
+
+	.globl FPUnavailable_common
+FPUnavailable_common:
+	EXCEPTION_PROLOG_COMMON
+	bne	.load_up_fpu		/* if from user, just load it up */
+	li	r20,0
+	li	r6,0x800
+	bl      .save_remaining_regs    /* if from kernel, take a trap */
+	bl      .KernelFP
+	b       .ret_from_except
+
+	.globl SystemCall_common
+SystemCall_common:
+	EXCEPTION_PROLOG_COMMON
+#ifdef CONFIG_PPC_ISERIES
+	cmpi	0,r0,0x5555		/* Special syscall to handle pending */
+	bne+	1f			/* interrupts */
+	andi.	r6,r23,MSR_PR		/* Only allowed from kernel */
+	beq+	HardwareInterrupt_entry
+1:
+#endif
+	std	r3,ORIG_GPR3(r1)
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
+	li	r6,0xC00
+	bl      .save_remaining_regs
+	bl      .DoSyscall
+	b       .ret_from_except
+
+_GLOBAL(do_hash_page_ISI)
+	li	r4,0
+_GLOBAL(do_hash_page_DSI)
+	rlwimi	r4,r23,32-13,30,30	/* Insert MSR_PR as _PAGE_USER */
+	ori	r4,r4,1			/* add _PAGE_PRESENT */
+
+	mflr	r21			/* Save LR in r21 */
+
+#ifdef DO_SOFT_DISABLE
+	/*
+	 * We hard enable here (but first soft disable) so that the hash_page
+	 * code can spin on the hash_table_lock with problem on a shared
+	 * processor.
+	 */
+	li	r0,0
+	stb	r0,PACAPROCENABLED(r20)	/* Soft Disabled */
+
+	mfmsr	r0
+	ori	r0,r0,MSR_EE+MSR_RI
+	mtmsrd	r0			/* Hard Enable, RI on */
+#endif
+
+	/*
+	 * r3 contains the faulting address
+	 * r4 contains the required access permissions
+	 *
+	 * at return r3 = 0 for success
+	 */
+
+	bl	.hash_page		/* build HPTE if possible */
+
+#ifdef DO_SOFT_DISABLE
+	/*
+	 * Now go back to hard disabled.
+	 */
+	mfmsr	r0
+	li	r4,0
+	ori	r4,r4,MSR_EE+MSR_RI
+	andc	r0,r0,r4
+	mtmsrd	r0			/* Hard Disable, RI off */
+
+	ld	r0,SOFTE(r1)
+	cmpdi	0,r0,0			/* See if we will soft enable in */
+					/* save_remaining_regs */
+	beq	5f
+	CHECKANYINT(r4,r5)
+	bne-	HardwareInterrupt_entry	/* Convert this DSI into an External */
+					/* to process interrupts which occurred */
+					/* during hash_page */
+5:
+	stb	r0,PACAPROCENABLED(r20)	/* Restore soft enable/disable status */
+#endif
+	or.	r3,r3,r3		/* Check return code */
+	beq     fast_exception_return   /* Return from exception on success */
+
+	mtlr    r21                     /* restore LR */
+	blr                             /* Return to DSI or ISI on failure */
+
+/*
+ * r20 points to the PACA, r21 to the exception frame,
+ * r23 contains the saved CR.
+ * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(do_stab_bolted)
+	stw	r23,EX_CCR(r21)	/* save CR in exc. frame */
+
+	mfspr   r22,DSISR
+	andis.  r22,r22,0x0020
+	bne+    2f
+	ld	r22,8(r21)	/* get SRR1 */
+	andi.	r22,r22,MSR_PR	/* check if from user */
+	bne+	stab_bolted_user_return  /* from user, send the error on up */
+	li	r3,0
+#ifdef CONFIG_XMON
+	bl	.xmon
+#endif
+1:	b	1b
+2:
+	/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
+	mfspr	r21,DAR
+	rldicl  r20,r21,36,32   /* Permits a full 32b of ESID */
+	rldicr  r20,r20,15,48
+	rldicl  r21,r21,4,60
+	or      r20,r20,r21
+
+	li      r21,9           /* VSID_RANDOMIZER */
+	sldi    r21,r21,32
+	oris    r21,r21,58231
+	ori     r21,r21,39831
+
+	mulld   r20,r20,r21
+	clrldi  r20,r20,28      /* r20 = vsid */
+
+	mfsprg  r21,3
+	ld      r21,PACASTABVIRT(r21)
+
+	/* Hash to the primary group */
+	mfspr	r22,DAR
+	rldicl  r22,r22,36,59
+	rldicr  r22,r22,7,56
+	or      r21,r21,r22     /* r21 = first ste of the group */
+
+	/* Search the primary group for a free entry */
+	li      r22,0
+1:
+	ld      r23,0(r21)      /* Test valid bit of the current ste   */
+	rldicl  r23,r23,57,63
+	cmpwi   r23,0
+	bne     2f
+	ld      r23,8(r21)      /* Get the current vsid part of the ste */
+	rldimi  r23,r20,12,0    /* Insert the new vsid value            */
+	std     r23,8(r21)      /* Put new entry back into the stab     */
+	eieio                  /* Order vsid update                    */
+	ld      r23,0(r21)      /* Get the esid part of the ste         */
+	mfspr	r20,DAR        /* Get the new esid                     */
+	rldicl  r20,r20,36,28  /* Permits a full 36b of ESID           */
+	rldimi  r23,r20,28,0    /* Insert the new esid value            */
+	ori     r23,r23,144      /* Turn on valid and kp                 */
+	std     r23,0(r21)      /* Put new entry back into the stab     */
+	sync                   /* Order the update                     */
+	b       3f
+2:
+	addi    r22,r22,1
+	addi    r21,r21,16
+	cmpldi  r22,7
+	ble     1b
+
+	/* Stick for only searching the primary group for now.          */
+	/* At least for now, we use a very simple random castout scheme */
+	/* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
+	mftb    r22
+	andi.   r22,r22,7
+	ori	r22,r22,1
+	sldi	r22,r22,4
+
+	/* r21 currently points to and ste one past the group of interest */
+	/* make it point to the randomly selected entry                   */
+	subi	r21,r21,128
+	or 	r21,r21,r22      /* r21 is the entry to invalidate        */
+
+	isync                    /* mark the entry invalid                */
+	ld      r23,0(r21)
+	li      r22,-129
+	and     r23,r23,r22
+	std     r23,0(r21)
+	sync
+
+	ld      r23,8(r21)
+	rldimi  r23,r20,12,0
+	std     r23,8(r21)
+	eieio
+
+	ld      r23,0(r21)      /* Get the esid part of the ste         */
+	mr      r22,r23
+	mfspr	r20,DAR         /* Get the new esid                     */
+	rldicl  r20,r20,36,28   /* Permits a full 32b of ESID           */
+	rldimi  r23,r20,28,0    /* Insert the new esid value            */
+	ori     r23,r23,144     /* Turn on valid and kp                 */
+	std     r23,0(r21)      /* Put new entry back into the stab     */
+
+	rldicl  r22,r22,36,28
+	rldicr  r22,r22,28,35
+	slbie   r22
+	sync
+
+3:
+	/* All done -- return from exception. */
+	mfsprg  r20,3                   /* Load the PACA pointer  */
+	ld      r21,PACAEXCSP(r20)      /* Get the exception frame pointer */
+	addi    r21,r21,EXC_FRAME_SIZE
+	lwz	r23,EX_CCR(r21)		/* get saved CR */
+	/* note that this is almost identical to maskable_exception_exit */
+	mtcr    r23                     /* restore CR */
+	ld	r22,EX_SRR0(r21)	/* Get SRR0 from exc. frame */
+	ld	r23,EX_SRR1(r21)	/* Get SRR1 from exc. frame */
+	mtspr	SRR0,r22
+	mtspr   SRR1,r23
+	ld	r22,EX_R22(r21)		/* restore r22 and r23 */
+	ld	r23,EX_R23(r21)
+	mfspr	r20,SPRG2
+	mfspr	r21,SPRG1
+	rfid
+_TRACEBACK(do_stab_bolted)
+
+/*
+ * r20 points to the PACA, r21 to the exception frame,
+ * r23 contains the saved CR.
+ * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(do_slb_bolted)
+	stw     r23,EX_CCR(r21) /* save CR in exc. frame */
+
+	/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
+	mfspr	r21,DAR
+	rldicl  r20,r21,36,32   /* Permits a full 32b of ESID */
+	rldicr  r20,r20,15,48
+	rldicl  r21,r21,4,60
+	or      r20,r20,r21
+
+	li      r21,9           /* VSID_RANDOMIZER */
+	sldi    r21,r21,32
+	oris    r21,r21,58231
+	ori     r21,r21,39831
+
+	mulld   r20,r20,r21
+	clrldi  r20,r20,28      /* r20 = vsid */
+
+	/* Search the SLB for a free entry */
+	li      r22,1
+1:
+	slbmfee	r23,r22
+	rldicl  r23,r23,37,63
+	cmpwi   r23,0
+	beq     3f              /* Found an invalid entry              */
+
+	addi	r22,r22,1
+	cmpldi	r22,64
+	blt	1b
+
+	/* No free entry - just take the next entry, round-robin */
+	/* XXX we should get the number of SLB entries from the naca */
+SLB_NUM_ENTRIES = 64
+	mfspr	r21,SPRG3
+	ld	r22,PACASTABRR(r21)
+	addi	r23,r22,1
+	cmpdi	r23,SLB_NUM_ENTRIES
+	blt	2f
+	li	r23,1
+2:	std	r23,PACASTABRR(r21)
+
+	/* r20 = vsid, r22 = entry */
+3:
+	/* Put together the vsid portion of the entry. */
+	li      r21,0
+	rldimi  r21,r20,12,0
+	ori     r20,r21,1024
+#ifndef CONFIG_PPC_ISERIES
+	ori	r20,r20,256    /* map kernel region with large ptes */
+#endif
+	
+	/* Put together the esid portion of the entry. */
+	mfspr	r21,DAR        /* Get the new esid                     */
+	rldicl  r21,r21,36,28  /* Permits a full 36b of ESID           */
+	li      r23,0
+	rldimi  r23,r21,28,0   /* Insert esid  */
+	oris    r21,r23,2048   /* valid bit    */
+	rldimi  r21,r22,0,52   /* Insert entry */
+
+	isync
+	slbmte  r20,r21
+	isync
+
+	/* All done -- return from exception. */
+	mfsprg  r20,3                   /* Load the PACA pointer  */
+	ld      r21,PACAEXCSP(r20)      /* Get the exception frame pointer */
+	addi    r21,r21,EXC_FRAME_SIZE
+	lwz	r23,EX_CCR(r21)		/* get saved CR */
+	/* note that this is almost identical to maskable_exception_exit */
+	mtcr    r23                     /* restore CR */
+	ld	r22,EX_SRR0(r21)	/* Get SRR0 from exc. frame */
+	ld	r23,EX_SRR1(r21)	/* Get SRR1 from exc. frame */
+	mtspr	SRR0,r22
+	mtspr   SRR1,r23
+	ld	r22,EX_R22(r21)		/* restore r22 and r23 */
+	ld	r23,EX_R23(r21)
+	mfspr	r20,SPRG2
+	mfspr	r21,SPRG1
+	rfid
+_TRACEBACK(do_slb_bolted)
+
+_GLOBAL(do_stab_SI)
+	mflr	r21			/* Save LR in r21 */
+
+	/*
+	 * r3 contains the faulting address
+	 * r4 contains the required access permissions
+	 *
+	 * at return r3 = 0 for success
+	 */
+
+	bl	.ste_allocate		/* build STE if possible */
+	or.	r3,r3,r3		/* Check return code */
+	beq     fast_exception_return   /* Return from exception on success */
+	mtlr    r21                     /* restore LR */
+	blr                             /* Return to DSI or ISI on failure */
+
+/*
+ * This code finishes saving the registers to the exception frame.
+ * Address translation is already on.
+ */
+_GLOBAL(save_remaining_regs)
+	/*
+	 * Save the rest of the registers into the pt_regs structure
+	 */
+	std     r22,_NIP(r1)
+	std     r23,_MSR(r1)
+	std     r6,TRAP(r1)
+	ld      r6,GPR6(r1)
+	SAVE_2GPRS(14, r1)
+	SAVE_4GPRS(16, r1)
+	SAVE_8GPRS(24, r1)
+
+	/*
+	 * Clear the RESULT field
+	 */
+	li	r22,0
+	std	r22,RESULT(r1)
+
+	/*
+	 * Test if from user state; result will be tested later
+	 */
+	andi.	r23,r23,MSR_PR		/* Set CR for later branch */
+
+	/*
+	 * Indicate that r1 contains the kernel stack and
+	 * get the Kernel TOC and CURRENT pointers from the Paca
+	 */
+	mfspr	r23,SPRG3		/* Get PACA */
+	std	r22,PACAKSAVE(r23)	/* r1 is now kernel sp */
+	ld	r2,PACATOC(r23)		/* Get Kernel TOC pointer */
+
+	/*
+	 * If from user state, update THREAD.regs
+	 */
+	beq	2f			/* Modify THREAD.regs if from user */
+	addi	r24,r1,STACK_FRAME_OVERHEAD
+	std	r24,THREAD+PT_REGS(r13)
+2:
+	SET_REG_TO_CONST(r22, MSR_KERNEL)
+
+#ifdef DO_SOFT_DISABLE
+	stb	r20,PACAPROCENABLED(r23) /* possibly soft enable */
+	ori	r22,r22,MSR_EE		/* always hard enable */
+#else
+	rldimi	r22,r20,15,48		/* Insert desired EE value */
+#endif
+
+	mtmsrd  r22
+	blr
+
+
+do_profile:
+	ld	r22,8(r21)		/* Get SRR1 */
+	andi.	r22,r22,MSR_PR		/* Test if in kernel */
+	bnelr				/* return if not in kernel */
+	ld	r22,0(r21)		/* Get SRR0 */
+	ld	r25,PACAPROFSTEXT(r20)	/* _stext */
+	subf	r22,r25,r22		/* offset into kernel */
+	lwz	r25,PACAPROFSHIFT(r20)
+	srd	r22,r22,r25
+	lwz	r25,PACAPROFLEN(r20)	/* length of profile table (-1) */
+	cmp	0,r22,r25		/* off end? */
+	ble	1f
+	mr	r22,r25			/* force into last entry */
+1:	sldi	r22,r22,2		/* convert to offset into buffer */
+	ld	r25,PACAPROFBUFFER(r20)	/* profile buffer */
+	add	r25,r25,r22
+2:	lwarx	r22,0,r25		/* atomically increment */
+	addi	r22,r22,1
+	stwcx.	r22,0,r25
+	bne-	2b
+	blr
+
+
+/*
+ * On pSeries, secondary processors spin in the following code.
+ * At entry, r3 = this processor's number (in Linux terms, not hardware).
+ */
+_GLOBAL(pseries_secondary_smp_init)
+
+	/* turn on 64-bit mode */
+	bl	.enable_64b_mode
+	isync
+
+	/* Set up a Paca value for this processor. */
+	LOADADDR(r24, paca) 		 /* Get base vaddr of Paca array  */
+	mulli	r25,r3,PACA_SIZE	 /* Calculate vaddr of right Paca */
+	add	r25,r25,r24              /* for this processor.           */
+
+	mtspr	SPRG3,r25		 /* Save vaddr of Paca in SPRG3   */
+	mr	r24,r3			 /* __secondary_start needs cpu#  */
+
+1:
+	HMT_LOW
+	lbz	r23,PACAPROCSTART(r25)	 /* Test if this processor should */
+					 /* start.                        */
+	sync
+
+        /* Create a temp kernel stack for use before relocation is on.    */
+        mr      r1,r25
+        addi    r1,r1,PACAGUARD
+        addi    r1,r1,0x1000
+        subi    r1,r1,STACK_FRAME_OVERHEAD
+
+	cmpi	0,r23,0
+#ifdef CONFIG_SMP
+#ifdef SECONDARY_PROCESSORS
+	bne	.__secondary_start
+#endif
+#endif
+	b 	1b			 /* Loop until told to go         */
+
+_GLOBAL(__start_initialization_iSeries)
+
+	LOADADDR(r1,init_task_union)
+	addi	r1,r1,TASK_UNION_SIZE
+	li	r0,0
+	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
+
+	LOADADDR(r2,__toc_start)
+	addi	r2,r2,0x4000
+	addi	r2,r2,0x4000
+
+	LOADADDR(r9,naca)
+	SET_REG_TO_CONST(r4, KERNELBASE)
+	addi	r4,r4,0x4000
+	std	r4,0(r9)		/* set the naca pointer */
+
+	/* Get the pointer to the segment table */
+	ld	r6,PACA(r4)             /* Get the base Paca pointer       */
+	ld	r4,PACASTABVIRT(r6)
+
+	bl      .iSeries_fixup_klimit
+
+	b	.start_here_common
+
+_GLOBAL(__start_initialization_pSeries)
+	mr	r31,r3			/* save parameters */
+	mr	r30,r4
+	mr	r29,r5
+	mr	r28,r6
+	mr	r27,r7
+	mr	r26,r8                  /* YABOOT: debug_print() routine */
+	mr	r25,r9                  /* YABOOT: debug_delay() routine */
+	mr	r24,r10                 /* YABOOT: debug_prom() routine */
+
+	bl	.enable_64b_mode
+
+	/* put a relocation offset into r3 */
+	bl	.reloc_offset
+
+	LOADADDR(r2,__toc_start)
+	addi    r2,r2,0x4000
+	addi    r2,r2,0x4000
+
+	/* Relocate the TOC from a virt addr to a real addr */
+	sub	r2,r2,r3
+
+	/* setup the naca pointer which is needed by prom_init            */
+	LOADADDR(r9,naca)
+	sub	r9,r9,r3                /* addr of the variable naca      */
+
+	SET_REG_TO_CONST(r4, KERNELBASE)
+	sub	r4,r4,r3
+	addi	r4,r4,0x4000
+	std	r4,0(r9)		/* set the value of naca          */
+
+	/* DRENG / PPPBBB Fix the following comment!!! -Peter */
+	/* The following copies the first 0x100 bytes of code from the    */
+	/* load addr to physical addr 0x0.  This code causes secondary    */
+	/* processors to spin until a flag in the PACA is set.  This      */
+	/* is done at this time rather than with the entire kernel        */
+	/* relocation which is done below because we need to cause the    */
+	/* processors to spin on code that is not going to move while OF  */
+	/* is still alive. Although the spin code is not actually run on  */
+	/* a uniprocessor, we always do this copy.                        */
+	SET_REG_TO_CONST(r4, KERNELBASE)/* Src addr                       */
+	sub	r4,r4,r3  		/* current address of __start     */
+			                /*        the source addr         */
+	li	r3,0                    /* Dest addr                      */
+	li	r5,0x100 		/* # bytes of memory to copy      */
+	li	r6,0			/* Destination offset             */
+	bl	.copy_and_flush		/* copy the first 0x100 bytes     */
+
+	mr	r3,r31
+	mr	r4,r30
+	mr	r5,r29
+	mr	r6,r28
+	mr	r7,r27
+	mr	r8,r26
+	mr	r9,r25
+	mr	r10,r24
+
+	bl	.prom_init
+
+	li	r24,0			/* cpu # */
+
+/*
+ * At this point, r3 contains the physical address we are running at,
+ * returned by prom_init()
+ */
+_STATIC(__after_prom_start)
+
+/*
+ * We need to run with __start at physical address 0.
+ * This will leave some code in the first 256B of
+ * real memory, which are reserved for software use.
+ * The remainder of the first page is loaded with the fixed
+ * interrupt vectors.  The next two pages are filled with
+ * unknown exception placeholders.
+ *
+ * Note: This process overwrites the OF exception vectors.
+ *       r26 == relocation offset
+ *       r27 == KERNELBASE
+ */
+	bl	.reloc_offset
+	mr	r26,r3
+	SET_REG_TO_CONST(r27,KERNELBASE)
+
+	li	r3,0                    /* target addr */
+
+	sub	r4,r27,r26 		/* source addr */
+					/* current address of _start   */
+			                /*   i.e. where we are running */
+			                /*        the source addr      */
+
+	LOADADDR(r5,copy_to_here)	/* # bytes of memory to copy      */
+	sub	r5,r5,r27
+
+	li	r6,0x100		/* Start offset, the first 0x100  */
+					/* bytes were copied earlier.	  */
+
+	bl	.copy_and_flush		/* copy the first n bytes         */
+					/* this includes the code being   */
+					/* executed here.                 */
+
+        LOADADDR(r0, 4f)                /* Jump to the copy of this code  */
+	mtctr	r0			/* that we just made              */
+	bctr
+
+4:	LOADADDR(r9,rtas)
+	sub	r9,r9,r26
+	ld	r5,RTASBASE(r9)		/* get the value of rtas->base */
+	ld	r9,RTASSIZE(r9)		/* get the value of rtas->size */
+	bl	.copy_and_flush		/* copy upto rtas->base */
+	add     r6,r6,r9		/* then skip over rtas->size bytes */
+
+	LOADADDR(r5,klimit)
+	sub	r5,r5,r26
+	ld	r5,0(r5)		/* get the value of klimit */
+	sub	r5,r5,r27
+	bl	.copy_and_flush		/* copy the rest */
+	b	.start_here_pSeries
+
+/*
+ * Copy routine used to copy the kernel to start at physical address 0
+ * and flush and invalidate the caches as needed.
+ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
+ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
+ *
+ * Note: this routine *only* clobbers r0, r6 and lr
+ */
+_STATIC(copy_and_flush)
+	addi	r5,r5,-8
+	addi	r6,r6,-8
+4:	li	r0,16                   /* Use the least common      */
+					/* denominator cache line    */
+			                /* size.  This results in    */
+					/* extra cache line flushes  */
+					/* but operation is correct. */
+					/* Can't get cache line size */
+					/* from NACA as it is being  */
+					/* moved too.                */
+
+	mtctr	r0			/* put # words/line in ctr */
+3:	addi	r6,r6,8			/* copy a cache line */
+	ldx	r0,r6,r4
+	stdx	r0,r6,r3
+	bdnz	3b
+	dcbst	r6,r3			/* write it to memory */
+	sync
+	icbi	r6,r3			/* flush the icache line */
+	cmpld	0,r6,r5
+	blt	4b
+	sync
+	addi	r5,r5,8
+	addi	r6,r6,8
+	blr
+
+.align 8
+copy_to_here:
+
+/*
+ * Disable FP for the task which had the FPU previously,
+ * and save its floating-point registers in its thread_struct.
+ * Enables the FPU for use in the kernel on return.
+ * On SMP we know the fpu is free, since we give it up every
+ * switch.  -- Cort
+ */
+_STATIC(load_up_fpu)
+	mfmsr	r5                      /* grab the current MSR */
+	ori	r5,r5,MSR_FP
+	mtmsrd  r5			/* enable use of fpu now */
+	isync
+/*
+ * For SMP, we don't do lazy FPU switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another.  Instead we call giveup_fpu in switch_to.
+ *
+ */
+#ifndef CONFIG_SMP
+	LOADBASE(r3,last_task_used_math)
+	ld	r4,last_task_used_math@l(r3)
+	cmpi	0,r4,0
+	beq	1f
+	addi	r4,r4,THREAD	       /* want THREAD of last_task_used_math */
+	SAVE_32FPRS(0, r4)
+	mffs	fr0
+	stfd	fr0,THREAD_FPSCR-4(r4)
+	ld	r5,PT_REGS(r4)
+	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+	li	r20,MSR_FP|MSR_FE0|MSR_FE1
+	andc	r4,r4,r20		/* disable FP for previous task */
+	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+	/* enable use of FP after return */
+	ori	r23,r23,MSR_FP|MSR_FE0|MSR_FE1
+	addi	r5,r13,THREAD		/* Get THREAD */
+	lfd	fr0,THREAD_FPSCR-4(r5)
+	mtfsf	0xff,fr0
+	REST_32FPRS(0, r5)
+#ifndef CONFIG_SMP
+	subi	r4,r5,THREAD		/* Back to 'current' */
+	std	r4,last_task_used_math@l(r3)
+#endif /* CONFIG_SMP */
+	/* restore registers and return */
+	b	fast_exception_return
+
+/*
+ * FP unavailable trap from kernel - print a message, but let
+ * the task use FP in the kernel until it returns to user mode.
+ */
+_GLOBAL(KernelFP)
+	ld	r3,_MSR(r1)
+	ori	r3,r3,MSR_FP
+	std	r3,_MSR(r1)		/* enable use of FP after return */
+	LOADADDR(r3,86f)
+	mfspr	r4,SPRG3		/* Get PACA */
+	ld	r4,PACACURRENT(r4)	/* current */
+	ld	r5,_NIP(r1)
+	b	.ret_from_except
+86:	.string	"floating point used in kernel (task=%p, pc=%x)\n"
+	.align	4
+
+/*
+ * giveup_fpu(tsk)
+ * Disable FP for the task given as the argument,
+ * and save the floating-point registers in its thread_struct.
+ * Enables the FPU for use in the kernel on return.
+ */
+_GLOBAL(giveup_fpu)
+	mfmsr	r5
+	ori	r5,r5,MSR_FP
+	mtmsrd	r5			/* enable use of fpu now */
+	isync
+	cmpi	0,r3,0
+	beqlr-				/* if no previous owner, done */
+	addi	r3,r3,THREAD		/* want THREAD of task */
+	ld	r5,PT_REGS(r3)
+	cmpi	0,r5,0
+	SAVE_32FPRS(0, r3)
+	mffs	fr0
+	stfd	fr0,THREAD_FPSCR-4(r3)
+	beq	1f
+	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+	li	r3,MSR_FP|MSR_FE0|MSR_FE1
+	andc	r4,r4,r3		/* disable FP for previous task */
+	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+	li	r5,0
+	LOADBASE(r4,last_task_used_math)
+	std	r5,last_task_used_math@l(r4)
+#endif /* CONFIG_SMP */
+	blr
+
+#ifdef CONFIG_SMP
+/*
+ * This function is called after the master CPU has released the
+ * secondary processors.  The execution environment is relocation off.
+ * The Paca for this processor has the following fields initialized at
+ * this point:
+ *   1. Processor number
+ *   2. Segment table pointer (virtual address)
+ * On entry the following are set:
+ *   r1    = stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
+ *   r24   = cpu# (in Linux terms)
+ *   r25   = Paca virtual address
+ *   SPRG3 = Paca virtual address
+ */
+_GLOBAL(__secondary_start)
+
+	HMT_MEDIUM			/* Set thread priority to MEDIUM */
+
+	/* set up the TOC (virtual address) */
+	LOADADDR(r2,__toc_start)
+	addi    r2,r2,0x4000
+	addi    r2,r2,0x4000
+
+	std	r2,PACATOC(r25)
+	li	r6,0
+	std	r6,PACAKSAVE(r25)
+	stb	r6,PACAPROCENABLED(r25)
+
+#ifndef CONFIG_PPC_ISERIES
+	/* Initialize the page table pointer register. */
+	LOADADDR(r6,_SDR1)
+	ld	r6,0(r6)		/* get the value of _SDR1 */
+	mtspr	SDR1,r6			/* set the htab location  */
+#endif
+	/* Initialize the first segment table (or SLB) entry                */
+	ld	r3,PACASTABVIRT(r25)    /* get addr of segment table        */
+	bl	.stab_initialize
+
+	/* Initialize the kernel stack.  Just a repeat for iSeries.         */
+	LOADADDR(r3,current_set)
+	sldi	r28,r24,4		/* get current_set[cpu#] */
+	ldx	r13,r3,r28
+	std	r13,PACACURRENT(r25)
+	addi	r1,r13,TASK_UNION_SIZE
+	subi	r1,r1,STACK_FRAME_OVERHEAD
+
+	ld	r3,PACASTABREAL(r25)    /* get raddr of segment table       */
+	ori	r4,r3,1			/* turn on valid bit                */
+
+#ifdef CONFIG_PPC_ISERIES
+	li	r0,-1			/* hypervisor call */
+	li	r3,1
+	sldi	r3,r3,63		/* 0x8000000000000000 */
+	ori	r3,r3,4			/* 0x8000000000000004 */
+	sc				/* HvCall_setASR */
+#else
+	/* set the ASR */
+	addi  r3,0,0x4000     /* r3 = ptr to naca */
+	lhz   r3,PLATFORM(r3) /* r3 = platform flags */
+	cmpldi r3,PLATFORM_PSERIES_LPAR
+	bne   98f
+	li	r3,H_SET_ASR  /* hcall = H_SET_ASR */
+	HSC     			    /* Invoking hcall */
+	b     99f
+98:             /* This is not a hypervisor machine */
+	mtasr	r4			/* set the stab location            */
+99:
+#endif
+	li	r7,0
+	mtlr	r7
+
+	/* enable MMU and jump to start_secondary */
+	LOADADDR(r3,.start_secondary_prolog)
+	SET_REG_TO_CONST(r4, MSR_KERNEL)
+#ifdef DO_SOFT_DISABLE
+	ori	r4,r4,MSR_EE
+#endif
+	mtspr	SRR0,r3
+	mtspr	SRR1,r4
+	rfid
+#endif /* CONFIG_SMP */
+
+/* 
+ * Running with relocation on at this point.  All we want to do is
+ * zero the stack back-chain pointer before going into C code.
+ */
+_GLOBAL(start_secondary_prolog)
+	li	r3,0
+	std	r3,0(r1)                /* Zero the stack frame pointer     */
+	bl	.start_secondary
+
+/*
+ * This subroutine clobbers r11, r12 and the LR
+ */
+_GLOBAL(enable_64b_mode)
+	mfmsr   r11                      /* grab the current MSR */
+	li      r12,1
+	rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
+	or      r11,r11,r12
+	li      r12,1
+	rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
+	or      r11,r11,r12
+	mtmsrd  r11
+	isync
+	blr
+
+/*
+ * This subroutine clobbers r11, r12 and the LR
+ */
+_GLOBAL(enable_32b_mode)
+	mfmsr   r11                      /* grab the current MSR */
+	li      r12,1
+	rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
+	andc	r11,r11,r12
+	li      r12,1
+	rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
+	andc	r11,r11,r12
+	mtmsrd  r11
+	isync
+	blr
+
+/*
+ * This is where the main kernel code starts.
+ */
+_STATIC(start_here_pSeries)
+	/* get a new offset, now that the kernel has moved. */
+	bl	.reloc_offset
+	mr	r26,r3
+
+	/* setup the naca pointer which is needed by *tab_initialize       */
+	LOADADDR(r6,naca)
+	sub	r6,r6,r26                /* addr of the variable naca      */
+	li	r27,0x4000
+	std	r27,0(r6)	 	 /* set the value of naca          */
+
+#ifdef CONFIG_HMT
+	/* Start up the second thread on cpu 0 */
+	mfspr	r3,PVR
+	srwi	r3,r3,16
+	cmpwi	r3,0x34                 /* Pulsar  */
+	beq	90f
+	cmpwi	r3,0x36                 /* Icestar */
+	beq	90f
+	cmpwi	r3,0x37                 /* SStar   */
+	beq	90f
+	b	91f                     /* HMT not supported */
+90:	li      r3,0
+	bl	.hmt_start_secondary
+91:
+#endif
+
+#ifdef CONFIG_SMP
+	/* All secondary cpus are now spinning on a common
+	 * spinloop, release them all now so they can start
+	 * to spin on their individual paca spinloops.
+	 * For non SMP kernels, the secondary cpus never
+	 * get out of the common spinloop.
+	 */
+	li	r3,1
+	LOADADDR(r5,__secondary_hold_spinloop)
+	tophys(r4,r5)
+	std     r3,0(r4)
+#endif
+
+	/* The following gets the stack and TOC set up with the regs */
+	/* pointing to the real addr of the kernel stack.  This is   */
+	/* all done to support the C function call below which sets  */
+	/* up the htab.  This is done because we have relocated the  */
+	/* kernel but are still running in real mode. */
+
+	/* real ptr to current */
+	LOADADDR(r3,init_task_union)
+	sub	r3,r3,r26
+
+	/* set up a stack pointer (physical address) */
+	addi	r1,r3,TASK_UNION_SIZE
+	li	r0,0
+	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
+
+	/* set up the TOC (physical address) */
+	LOADADDR(r2,__toc_start)
+	addi    r2,r2,0x4000
+	addi    r2,r2,0x4000
+	sub	r2,r2,r26
+
+	/* Init naca->debug_switch so it can be used in stab & htab init.  */
+	bl	.ppcdbg_initialize
+
+	/* Get the pointer to the segment table which is used by           */
+	/* stab_initialize                                                 */
+	li	r27,0x4000
+	ld	r6,PACA(r27)            /* Get the base paca pointer       */
+	sub	r6,r6,r26		/* convert to physical addr         */
+	mtspr	SPRG3,r6		/* PPPBBB: Temp... -Peter */
+	ld	r3,PACASTABREAL(r6)
+	ori	r4,r3,1			/* turn on valid bit                */
+	
+	/* set the ASR */
+	addi  r3,0,0x4000     /* r3 = ptr to naca */
+	lhz   r3,PLATFORM(r3) /* r3 = platform flags */
+	cmpldi r3,PLATFORM_PSERIES_LPAR
+	bne   98f
+	li	r3,H_SET_ASR  /* hcall = H_SET_ASR */
+	HSC     			    /* Invoking hcall */
+	b     99f
+98:                 /* This is not a hypervisor machine */
+	mtasr	r4			/* set the stab location            */
+99:
+	mfspr	r6,SPRG3
+	ld	r3,PACASTABREAL(r6)     /* restore r3 for stab_initialize */
+
+	/* Initialize an initial memory mapping and turn on relocation.   */
+	bl	.stab_initialize
+	bl	.htab_initialize
+
+	LOADADDR(r6,_SDR1)
+	sub	r6,r6,r26
+	ld	r6,0(r6)		/* get the value of _SDR1 */
+	mtspr	SDR1,r6			/* set the htab location  */
+
+	LOADADDR(r3,.start_here_common)
+	SET_REG_TO_CONST(r4, MSR_KERNEL)
+	mtspr	SRR0,r3
+	mtspr	SRR1,r4
+	rfid
+
+	/* This is where all platforms converge execution */
+_STATIC(start_here_common)
+	/* relocation is on at this point */
+
+	/* Clear out the BSS */
+	LOADADDR(r11,_end)
+
+	LOADADDR(r8,__bss_start)
+
+	sub	r11,r11,r8        /* bss size                        */
+	addi	r11,r11,7         /* round up to an even double word */
+	rldicl. r11,r11,61,3      /* shift right by 3                */
+	beq	4f
+	addi	r8,r8,-8
+	li	r0,0
+	mtctr	r11		  /* zero this many doublewords      */
+3:	stdu	r0,8(r8)
+	bdnz	3b
+4:
+
+	/* The following code sets up the SP and TOC now that we are */
+	/* running with translation enabled. */
+
+	/* ptr to current */
+	LOADADDR(r3,init_task_union)
+
+	/* set up the stack */
+	addi	r1,r3,TASK_UNION_SIZE
+	li	r0,0
+	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
+
+	/* set up the TOC */
+	LOADADDR(r2,__toc_start)
+	addi    r2,r2,0x4000
+	addi    r2,r2,0x4000
+
+	/* setup the naca pointer                                         */
+	LOADADDR(r9,naca)
+
+	SET_REG_TO_CONST(r8, KERNELBASE)
+	addi	r8,r8,0x4000
+	std	r8,0(r9)		/* set the value of the naca ptr  */
+
+	LOADADDR(r4,naca)               /* Get Naca ptr address           */
+	ld	r4,0(r4)                /* Get the location of the naca   */
+	ld	r4,PACA(r4)             /* Get the base Paca pointer      */
+	mtspr	SPRG3,r4
+
+	/* ptr to current */
+	LOADADDR(r13,init_task_union)
+	std	r13,PACACURRENT(r4)
+
+	std	r2,PACATOC(r4)
+	li	r5,0
+	std	r0,PACAKSAVE(r4)
+
+	/* ptr to hardware interrupt stack for processor 0                */
+	LOADADDR(r3, hardware_int_paca0)
+	li      r5,0x1000
+	sldi    r5,r5,3
+	subi    r5,r5,STACK_FRAME_OVERHEAD
+
+	add     r3,r3,r5
+	std     r3,PACAHRDWINTSTACK(r4)
+
+	li      r3,0
+	stb     r3,PACAHRDWINTCOUNT(r4)
+
+	/* Restore the parms passed in from the bootloader. */
+	mr	r3,r31
+	mr	r4,r30
+	mr	r5,r29
+	mr	r6,r28
+	mr	r7,r27
+
+	bl	.setup_system
+
+	/* Load up the kernel context */
+5:
+#ifdef DO_SOFT_DISABLE
+	mfspr	r4,SPRG3
+	li	r5,0
+	stb	r5,PACAPROCENABLED(r4)	/* Soft Disabled */
+	mfmsr	r5
+	ori	r5,r5,MSR_EE		/* Hard Enabled */
+	mtmsrd	r5
+#endif
+
+	bl .start_kernel
+
+_GLOBAL(hmt_init)
+#ifdef CONFIG_HMT
+	LOADADDR(r5, hmt_thread_data)
+	mfspr	r7,PVR
+	srwi	r7,r7,16
+	cmpwi	r7,0x34                 /* Pulsar  */
+	beq	90f
+	cmpwi	r7,0x36                 /* Icestar */
+	beq	91f
+	cmpwi	r7,0x37                 /* SStar   */
+	beq	91f
+	b	101f
+90:	mfspr	r6,PIR
+	andi.	r6,r6,0x1f
+	b	92f
+91:	mfspr	r6,PIR
+	andi.	r6,r6,0x3ff
+92:	sldi	r4,r24,3
+	stwx	r6,r5,r4
+	bl	.hmt_start_secondary
+	b	101f
+
+__hmt_secondary_hold:
+	LOADADDR(r5, hmt_thread_data)
+	clrldi	r5,r5,4
+	li	r7,0
+	mfspr	r6,PIR
+	mfspr	r8,PVR
+	srwi	r8,r8,16
+	cmpwi	r8,0x34
+	bne	93f
+	andi.	r6,r6,0x1f
+	b	103f
+93:	andi.	r6,r6,0x3f
+
+103:	lwzx	r8,r5,r7
+	cmpw	r8,r6
+	beq	104f
+	addi	r7,r7,8
+	b	103b
+
+104:	addi	r7,r7,4
+	lwzx	r9,r5,r7
+	mr      r24,r9
+101:
+#endif
+	mr      r3,r24
+	b       .pseries_secondary_smp_init
+
+#ifdef CONFIG_HMT
+_GLOBAL(hmt_start_secondary)
+	LOADADDR(r4,__hmt_secondary_hold)
+	clrldi	r4,r4,4
+	mtspr   NIADORM, r4
+	mfspr   r4, MSRDORM
+	li      r5, -65
+	and     r4, r4, r5
+	mtspr   MSRDORM, r4
+	lis	r4,0xffef
+	ori	r4,r4,0x7403
+	mtspr	TSC, r4
+	li	r4,0x1f4
+	mtspr	TST, r4
+	mfspr   r4, HID0
+	ori     r4, r4, 0x1
+	mtspr   HID0, r4
+	mfspr   r4, CTRLF
+	oris    r4, r4, 0x40
+	mtspr   CTRLT, r4
+	blr
+#endif
+
+/*
+ * We put a few things here that have to be page-aligned.
+ * This stuff goes at the beginning of the data segment,
+ * which is page-aligned.
+ */
+	.data
+	.align  12
+	.globl	sdata
+sdata:
+	.globl	empty_zero_page
+empty_zero_page:
+	.space	4096
+
+	.globl	swapper_pg_dir
+swapper_pg_dir:
+	.space	4096
+
+	.globl	ioremap_dir
+ioremap_dir:
+	.space	4096
+
+	.globl	bolted_dir
+bolted_dir:
+	.space	4096
+
+	.globl  hardware_int_paca0
+hardware_int_paca0:
+	.space	8*4096
+
+/* 1 page segment table per cpu (max 48, cpu0 allocated at 0x5000) */
+	.globl	stab_array
+stab_array:
+        .space	4096 * (48 - 1)
+	
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+	.globl	cmd_line
+cmd_line:
+	.space	512
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/htab.c linux/arch/ppc64/kernel/htab.c
--- linux.orig/arch/ppc64/kernel/htab.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/htab.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,1232 @@
+/*
+ * 
+ *
+ * PowerPC64 port by Mike Corrigan and Dave Engebretsen
+ *   {mikejc|engebret}@us.ibm.com
+ *
+ *    Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
+ * 
+ *    Module name: htab.c
+ *
+ *    Description:
+ *      PowerPC Hashed Page Table functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+#include <asm/page.h>
+#include <asm/types.h>
+#include <asm/init.h>
+#include <asm/system.h>
+#include <asm/iSeries/LparData.h>
+#include <linux/spinlock.h>
+#include <asm/ppcdebug.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/sysctl.h>
+#include <linux/ctype.h>
+#include <linux/cache.h>
+#include <asm/uaccess.h>
+#include <asm/naca.h>
+#include <asm/system.h>
+#include <asm/pmc.h>
+#include <asm/machdep.h>
+#include <asm/lmb.h>
+#include <asm/eeh.h>
+
+/* For iSeries */
+#include <asm/iSeries/HvCallHpt.h>
+
+/* Note:  pte   --> Linux PTE
+ *        HPTE  --> PowerPC Hashed Page Table Entry
+ */
+
+HTAB htab_data = {NULL, 0, 0, 0, 0};
+
+int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
+		   void *buffer, size_t *lenp);
+
+void htab_initialize(void);
+void make_pte_LPAR(HPTE *htab,
+	      unsigned long va, unsigned long pa, int mode,
+	      unsigned long hash_mask, int large);
+
+extern unsigned long reloc_offset(void);
+extern unsigned long get_kernel_vsid( unsigned long ea );
+extern void cacheable_memzero( void *, unsigned int );
+
+extern unsigned long _SDR1;
+extern unsigned long klimit;
+
+extern unsigned long _ASR;
+extern inline void make_ste(unsigned long stab,
+			    unsigned long esid, unsigned long vsid);
+
+extern char _stext[], _etext[], __start_naca[], __end_stab[];
+
+static spinlock_t hash_table_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+
+#define PTRRELOC(x)	((typeof(x))((unsigned long)(x) - offset))
+#define PTRUNRELOC(x)	((typeof(x))((unsigned long)(x) + offset))
+#define RELOC(x)	(*PTRRELOC(&(x)))
+
+extern unsigned long htab_size( unsigned long );
+unsigned long hpte_getword0_iSeries( unsigned long slot );
+
+#define KB (1024)
+#define MB (1024*KB)
+static inline void
+create_pte_mapping(unsigned long start, unsigned long end,
+		   unsigned long mode, unsigned long mask, int large)
+{
+	unsigned long addr, offset = reloc_offset();
+	HTAB *_htab_data = PTRRELOC(&htab_data);
+	HPTE  *htab  = (HPTE *)__v2a(_htab_data->htab);
+	unsigned int step;
+
+	if (large)
+		step = 16*MB;
+	else
+		step = 4*KB;
+
+	for (addr = start; addr < end; addr += step) {
+		unsigned long vsid = get_kernel_vsid(addr);
+		unsigned long va = (vsid << 28) | (addr & 0xfffffff);
+		make_pte(htab, va, (unsigned long)__v2a(addr), mode, mask,
+				large);
+	}
+}
+
+void
+htab_initialize(void)
+{
+	unsigned long table, htab_size_bytes;
+	unsigned long pteg_count;
+	unsigned long mode_ro, mode_rw, mask;
+	unsigned long offset = reloc_offset();
+	struct naca_struct *_naca = RELOC(naca);
+	HTAB *_htab_data = PTRRELOC(&htab_data);
+
+	/*
+	 * Calculate the required size of the htab.  We want the number of
+	 * PTEGs to equal one half the number of real pages.
+	 */ 
+	htab_size_bytes = 1UL << _naca->pftSize;
+	pteg_count = htab_size_bytes >> 7;
+
+	/* For debug, make the HTAB 1/8 as big as it normally would be. */
+	ifppcdebug(PPCDBG_HTABSIZE) {
+		pteg_count >>= 3;
+		htab_size_bytes = pteg_count << 7;
+	}
+
+	_htab_data->htab_num_ptegs = pteg_count;
+	_htab_data->htab_hash_mask = pteg_count - 1;
+
+	if(_naca->platform == PLATFORM_PSERIES) {
+		/* Find storage for the HPT.  Must be contiguous in
+		 * the absolute address space.
+		 */
+		table = lmb_alloc(htab_size_bytes, htab_size_bytes);
+		if ( !table )
+			panic("ERROR, cannot find space for HPTE\n");
+		_htab_data->htab = (HPTE *)__a2v(table);
+
+		/* htab absolute addr + encoded htabsize */
+		RELOC(_SDR1) = table + __ilog2(pteg_count) - 11;
+
+		/* Initialize the HPT with no entries */
+		cacheable_memzero((void *)table, htab_size_bytes);
+	} else {
+		_htab_data->htab = NULL;
+		RELOC(_SDR1) = 0; 
+	}
+
+	mode_ro = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RXRX;
+	mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
+	mask = pteg_count-1;
+
+	/* Create PTE's for the kernel text and data sections plus
+	 * the HPT and HPTX arrays.  Make the assumption that
+	 * (addr & KERNELBASE) == 0 (ie they are disjoint).
+	 * We also assume that the va is <= 64 bits.
+	 */
+#if 0
+	create_pte_mapping((unsigned long)_stext,       (unsigned long)__start_naca,                 mode_ro, mask);
+	create_pte_mapping((unsigned long)__start_naca, (unsigned long)__end_stab,                   mode_rw, mask);
+	create_pte_mapping((unsigned long)__end_stab,   (unsigned long)_etext,                       mode_ro, mask);
+	create_pte_mapping((unsigned long)_etext,       RELOC(klimit),                               mode_rw, mask);
+	create_pte_mapping((unsigned long)__a2v(table), (unsigned long)__a2v(table+htab_size_bytes), mode_rw, mask);
+#else
+#ifndef CONFIG_PPC_ISERIES
+	if (__is_processor(PV_POWER4) && _naca->physicalMemorySize > 256*MB) {
+		create_pte_mapping((unsigned long)KERNELBASE, 
+				   KERNELBASE + 256*MB, mode_rw, mask, 0);
+		create_pte_mapping((unsigned long)KERNELBASE + 256*MB, 
+				   KERNELBASE + (_naca->physicalMemorySize), 
+				   mode_rw, mask, 1);
+		return;
+	}
+#endif
+	create_pte_mapping((unsigned long)KERNELBASE, 
+			   KERNELBASE+(_naca->physicalMemorySize), 
+			   mode_rw, mask, 0);
+#endif
+}
+#undef KB
+#undef MB
+
+/*
+ * Create a pte.  Used during initialization only.
+ * We assume the PTE will fit in the primary PTEG.
+ */
+void make_pte(HPTE *htab,
+	      unsigned long va, unsigned long pa, int mode,
+	      unsigned long hash_mask, int large)
+{
+	HPTE  *hptep;
+	unsigned long hash, i;
+	volatile unsigned long x = 1;
+	unsigned long vpn;
+
+#ifdef CONFIG_PPC_PSERIES
+	if(naca->platform == PLATFORM_PSERIES_LPAR) {
+		make_pte_LPAR(htab, va, pa, mode, hash_mask, large); 
+		return;
+	}
+#endif
+
+	if (large)
+		vpn = va >> 24;
+	else
+		vpn = va >> 12;
+
+	hash = hpt_hash(vpn, large);
+
+	hptep  = htab +  ((hash & hash_mask)*HPTES_PER_GROUP);
+
+	for (i = 0; i < 8; ++i, ++hptep) {
+		if ( hptep->dw0.dw0.v == 0 ) {		/* !valid */
+			hptep->dw1.dword1 = pa | mode;
+			hptep->dw0.dword0 = 0;
+			hptep->dw0.dw0.avpn = va >> 23;
+			hptep->dw0.dw0.bolted = 1;	/* bolted */
+			hptep->dw0.dw0.v = 1;		/* make valid */
+			return;
+		}
+	}
+
+	/* We should _never_ get here and too early to call xmon. */
+	for(;x;x|=1);
+}
+
+/* Functions to invalidate a HPTE */
+static void hpte_invalidate_iSeries( unsigned long slot )
+{
+	HvCallHpt_invalidateSetSwBitsGet( slot, 0, 0 );
+}
+
+static void hpte_invalidate_pSeries( unsigned long slot )
+{
+	/* Local copy of the first doubleword of the HPTE */
+	union {
+		unsigned long d;
+		Hpte_dword0   h;
+	} hpte_dw0;
+
+	/* Locate the HPTE */
+	HPTE  * hptep  = htab_data.htab  + slot;
+
+	/* Get the first doubleword of the HPTE */
+	hpte_dw0.d = hptep->dw0.dword0;
+
+	/* Invalidate the hpte */
+	hptep->dw0.dword0 = 0;
+
+	/* Invalidate the tlb   */
+	{
+		unsigned long vsid, group, pi, pi_high;
+
+		vsid = hpte_dw0.h.avpn >> 5;
+		group = slot >> 3;
+		if(hpte_dw0.h.h) {
+			group = ~group;
+		} 
+		pi = (vsid ^ group) & 0x7ff;
+		pi_high = (hpte_dw0.h.avpn & 0x1f) << 11;
+		pi |= pi_high;
+		_tlbie(pi << 12);
+	}
+}
+
+
+/* Select an available HPT slot for a new HPTE
+ *   return slot index (if in primary group)
+ *   return -slot index (if in secondary group) 
+ */
+static long hpte_selectslot_iSeries( unsigned long vpn )
+{
+	HPTE hpte;
+	long ret_slot, orig_slot;
+	unsigned long primary_hash;
+	unsigned long hpteg_slot;
+	unsigned long slot;
+	unsigned i, k;
+	union {
+		unsigned long	d;
+		Hpte_dword0	h;
+	} hpte_dw0;
+
+	ret_slot = orig_slot = HvCallHpt_findValid( &hpte, vpn );
+	if ( hpte.dw0.dw0.v ) {		/* If valid ...what do we do now? */
+		udbg_printf( "hpte_selectslot_iSeries: vpn 0x%016lx already valid at slot 0x%016lx\n", vpn, ret_slot );
+		udbg_printf( "hpte_selectslot_iSeries: returned hpte 0x%016lx 0x%016lx\n", hpte.dw0.dword0, hpte.dw1.dword1 );
+
+		return (0x8000000000000000); 
+		/*			panic("select_hpte_slot found entry already valid\n"); */
+	}
+	if ( ret_slot == -1 ) {		/* -1 indicates no available slots */
+
+		/* No available entry found in secondary group */
+
+		PMC_SW_SYSTEM(htab_capacity_castouts);
+
+		primary_hash = hpt_hash(vpn, 0);
+		hpteg_slot = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+		k = htab_data.next_round_robin++ & 0x7;
+
+		for ( i=0; i<HPTES_PER_GROUP; ++i ) {
+			if ( k == HPTES_PER_GROUP )
+				k = 0;
+			slot = hpteg_slot + k;
+			hpte_dw0.d = hpte_getword0_iSeries( slot );
+			if ( !hpte_dw0.h.bolted ) {
+				hpte_invalidate_iSeries( slot );
+				ret_slot = slot;
+			}
+			++k;
+		}
+	} else {
+		if ( ret_slot < 0 ) {
+			PMC_SW_SYSTEM(htab_primary_overflows);
+			ret_slot &= 0x7fffffffffffffff;
+			ret_slot = -ret_slot;
+		}
+	}
+	if ( ret_slot == -1 ) {
+		/* No non-bolted entry found in primary group - time to panic */
+        	udbg_printf("hpte_selectslot_pSeries - No non-bolted HPTE in group 0x%lx! \n", hpteg_slot/HPTES_PER_GROUP);
+        	panic("No non-bolted HPTE in group %lx", (unsigned long)hpteg_slot/HPTES_PER_GROUP);
+	}
+	PPCDBG(PPCDBG_MM, "hpte_selectslot_iSeries: vpn=0x%016lx, orig_slot=0x%016lx, ret_slot=0x%016lx \n",
+	       vpn, orig_slot, ret_slot );	
+	return ret_slot;
+}
+
+static long hpte_selectslot_pSeries(unsigned long vpn)
+{
+	HPTE * hptep;
+	unsigned long primary_hash;
+	unsigned long hpteg_slot;
+	unsigned i, k;
+
+	/* Search the primary group for an available slot */
+
+	primary_hash = hpt_hash(vpn, 0);
+	hpteg_slot = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+	hptep = htab_data.htab + hpteg_slot;
+	
+	for (i=0; i<HPTES_PER_GROUP; ++i) {
+		if ( hptep->dw0.dw0.v == 0 ) {
+			/* If an available slot found, return it */
+			return hpteg_slot + i;
+		}
+		hptep++;
+	}
+
+	/* No available entry found in primary group */
+
+	PMC_SW_SYSTEM(htab_primary_overflows);
+
+	/* Search the secondary group */
+
+	hpteg_slot = ( ~primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+	hptep = htab_data.htab + hpteg_slot;
+
+	for (i=0; i<HPTES_PER_GROUP; ++i) {
+		if ( hptep->dw0.dw0.v == 0 ) {
+			/* If an available slot found, return it */
+			return -(hpteg_slot + i);
+		}
+		hptep++;
+	}
+
+	/* No available entry found in secondary group */
+
+	PMC_SW_SYSTEM(htab_capacity_castouts);
+
+	/* Select an entry in the primary group to replace */
+
+	hpteg_slot = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+	hptep = htab_data.htab + hpteg_slot;
+	k = htab_data.next_round_robin++ & 0x7;
+
+	for (i=0; i<HPTES_PER_GROUP; ++i) {
+		if (k == HPTES_PER_GROUP)
+			k = 0;
+
+		if (!hptep[k].dw0.dw0.bolted) {
+			hpteg_slot += k;
+			/* Invalidate the current entry */
+			ppc_md.hpte_invalidate(hpteg_slot); 
+			return hpteg_slot;
+		}
+		++k;
+	}
+
+	/* No non-bolted entry found in primary group - time to panic */
+        udbg_printf("hpte_selectslot_pSeries - No non-bolted HPTE in group 0x%lx! \n", hpteg_slot/HPTES_PER_GROUP);
+	/*      xmon(0); */
+        panic("No non-bolted HPTE in group %lx", (unsigned long)hpteg_slot/HPTES_PER_GROUP);
+
+	/* keep the compiler happy */
+	return 0;
+}
+
+unsigned long hpte_getword0_iSeries( unsigned long slot )
+{
+	unsigned long dword0;
+
+	HPTE hpte;
+	HvCallHpt_get( &hpte, slot );
+	dword0 = hpte.dw0.dword0;
+
+	return dword0;
+}
+
+unsigned long hpte_getword0_pSeries( unsigned long slot )
+{
+	unsigned long dword0;
+	HPTE * hptep = htab_data.htab + slot;
+
+	dword0 = hptep->dw0.dword0;
+	return dword0;
+}
+
+static long hpte_find_iSeries(unsigned long vpn)
+{
+	HPTE hpte;
+	long slot;
+
+	slot = HvCallHpt_findValid( &hpte, vpn );
+	if ( hpte.dw0.dw0.v ) {
+		if ( slot < 0 ) {
+			slot &= 0x7fffffffffffffff;
+			slot = -slot;
+		}
+	} else
+		slot = -1;
+	return slot;
+}
+
+static long hpte_find_pSeries(unsigned long vpn)
+{
+	union {
+		unsigned long d;
+		Hpte_dword0   h;
+	} hpte_dw0;
+	long slot;
+	unsigned long hash;
+	unsigned long i,j;
+
+	hash = hpt_hash(vpn, 0);
+	for ( j=0; j<2; ++j ) {
+		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+		for ( i=0; i<HPTES_PER_GROUP; ++i ) {
+			hpte_dw0.d = hpte_getword0_pSeries( slot );
+			if ( ( hpte_dw0.h.avpn == ( vpn >> 11 ) ) &&
+			     ( hpte_dw0.h.v ) &&
+			     ( hpte_dw0.h.h == j ) ) {
+				/* HPTE matches */
+				if ( j )
+					slot = -slot;
+				return slot;
+			}
+			++slot;
+		}
+		hash = ~hash;
+	}
+	return -1;
+} 
+
+/* This function is called by iSeries setup when initializing the hpt */
+void build_valid_hpte( unsigned long vsid, unsigned long ea, unsigned long pa,
+		       pte_t * ptep, unsigned hpteflags, unsigned bolted )
+{
+	unsigned long vpn, flags;
+	long hpte_slot;
+	unsigned hash;
+	pte_t pte;
+
+	vpn = ((vsid << 28) | ( ea & 0xffff000 )) >> 12;
+
+	spin_lock_irqsave( &hash_table_lock, flags );
+
+	hpte_slot = ppc_md.hpte_selectslot( vpn );
+	hash = 0;
+	if ( hpte_slot < 0 ) {
+		if ( hpte_slot == 0x8000000000000000 ) {
+			udbg_printf("hash_page: ptep    = 0x%016lx\n", 
+				    (unsigned long)ptep );
+			udbg_printf("hash_page: ea      = 0x%016lx\n", ea );
+			udbg_printf("hash_page: vpn     = 0x%016lx\n", vpn );
+               
+			panic("hash_page: hpte already exists\n");
+		}
+		hash = 1;
+		hpte_slot = -hpte_slot;
+	}
+	ppc_md.hpte_create_valid( hpte_slot, vpn, pa >> 12, hash, ptep,
+				  hpteflags, bolted );
+
+	if ( ptep ) {
+		/* Get existing pte flags */
+		pte = *ptep;
+		pte_val(pte) &= ~_PAGE_HPTEFLAGS;
+
+		/* Add in the has hpte flag */
+		pte_val(pte) |= _PAGE_HASHPTE;
+
+		/* Add in the _PAGE_SECONDARY flag */
+		pte_val(pte) |= hash << 15;
+
+		/* Add in the hpte slot */
+		pte_val(pte) |= (hpte_slot << 12) & _PAGE_GROUP_IX;
+               
+		/* Save the new pte.  */
+		*ptep = pte;
+               
+	}
+	spin_unlock_irqrestore( &hash_table_lock, flags );
+}
+
+
+/* Create an HPTE and validate it
+ *   It is assumed that the HPT slot currently is invalid.
+ *   The HPTE is set with the vpn, rpn (converted to absolute)
+ *   and flags
+ */
+static void hpte_create_valid_iSeries(unsigned long slot, unsigned long vpn,
+				      unsigned long prpn, unsigned hash, 
+				      void * ptep, unsigned hpteflags, 
+				      unsigned bolted )
+{
+	/* Local copy of HPTE */
+	struct {
+		/* Local copy of first doubleword of HPTE */
+		union {
+			unsigned long d;
+			Hpte_dword0   h;
+		} dw0;
+		/* Local copy of second doubleword of HPTE */
+		union {
+			unsigned long     d;
+			Hpte_dword1       h;
+			Hpte_dword1_flags f;
+		} dw1;
+	} lhpte;
+	
+	unsigned long avpn = vpn >> 11;
+	unsigned long arpn = physRpn_to_absRpn( prpn );
+
+	/* Fill in the local HPTE with absolute rpn, avpn and flags */
+	lhpte.dw1.d        = 0;
+	lhpte.dw1.h.rpn    = arpn;
+	lhpte.dw1.f.flags  = hpteflags;
+
+	lhpte.dw0.d        = 0;
+	lhpte.dw0.h.avpn   = avpn;
+	lhpte.dw0.h.h      = hash;
+	lhpte.dw0.h.bolted = bolted;
+	lhpte.dw0.h.v      = 1;
+
+	/* Now fill in the actual HPTE */
+	HvCallHpt_addValidate( slot, hash, (HPTE *)&lhpte );
+}
+
+static void hpte_create_valid_pSeries(unsigned long slot, unsigned long vpn,
+				      unsigned long prpn, unsigned hash, 
+				      void * ptep, unsigned hpteflags, 
+				      unsigned bolted)
+{
+	/* Local copy of HPTE */
+	struct {
+		/* Local copy of first doubleword of HPTE */
+		union {
+			unsigned long d;
+			Hpte_dword0   h;
+		} dw0;
+		/* Local copy of second doubleword of HPTE */
+		union {
+			unsigned long     d;
+			Hpte_dword1       h;
+			Hpte_dword1_flags f;
+		} dw1;
+	} lhpte;
+	
+	unsigned long avpn = vpn >> 11;
+	unsigned long arpn = physRpn_to_absRpn( prpn );
+
+	HPTE *hptep;
+
+	/* Fill in the local HPTE with absolute rpn, avpn and flags */
+	lhpte.dw1.d        = 0;
+	lhpte.dw1.h.rpn    = arpn;
+	lhpte.dw1.f.flags  = hpteflags;
+
+	lhpte.dw0.d        = 0;
+	lhpte.dw0.h.avpn   = avpn;
+	lhpte.dw0.h.h      = hash;
+	lhpte.dw0.h.bolted = bolted;
+	lhpte.dw0.h.v      = 1;
+
+	/* Now fill in the actual HPTE */
+	hptep  = htab_data.htab  + slot;
+
+	/* Set the second dword first so that the valid bit
+	 * is the last thing set
+	 */
+	
+	hptep->dw1.dword1 = lhpte.dw1.d;
+
+	/* Guarantee the second dword is visible before
+	 * the valid bit
+	 */
+	
+	__asm__ __volatile__ ("eieio" : : : "memory");
+
+	/* Now set the first dword including the valid bit */
+	hptep->dw0.dword0 = lhpte.dw0.d;
+
+	__asm__ __volatile__ ("ptesync" : : : "memory");
+}
+
+/* find_linux_pte returns the address of a linux pte for a given 
+ * effective address and directory.  If not found, it returns zero.
+ */
+
+pte_t  * find_linux_pte( pgd_t * pgdir, unsigned long ea )
+{
+	pgd_t *pg;
+	pmd_t *pm;
+	pte_t *pt = NULL;
+	pte_t pte;
+	pg = pgdir + pgd_index( ea );
+	if ( ! pgd_none( *pg ) ) {
+
+		pm = pmd_offset( pg, ea );
+		if ( ! pmd_none( *pm ) ) { 
+			pt = pte_offset( pm, ea );
+			pte = *pt;
+			if ( ! pte_present( pte ) )
+				pt = NULL;
+		}
+	}
+
+	return pt;
+
+}
+
+static inline unsigned long computeHptePP( unsigned long pte )
+{
+	return (     pte & _PAGE_USER )           |
+		( ( ( pte & _PAGE_USER )    >> 1 ) &
+		  ( ( ~( ( pte >> 2 ) &		/* _PAGE_RW */
+		         ( pte >> 7 ) ) ) &     /* _PAGE_DIRTY */
+			 1 ) );
+}
+
+static void hpte_updatepp_iSeries(long slot, unsigned long newpp, unsigned long va)
+{
+	HvCallHpt_setPp( slot, newpp );
+}
+
+static void hpte_updatepp_pSeries(long slot, unsigned long newpp, unsigned long va)
+{
+	/* Local copy of first doubleword of HPTE */
+	union {
+		unsigned long d;
+		Hpte_dword0   h;
+	} hpte_dw0;
+	
+	/* Local copy of second doubleword of HPTE */
+	union {
+		unsigned long     d;
+		Hpte_dword1       h;
+		Hpte_dword1_flags f;
+	} hpte_dw1;	
+
+	HPTE *  hptep  = htab_data.htab  + slot;
+
+	/* Turn off valid bit in HPTE */
+	hpte_dw0.d = hptep->dw0.dword0;
+	hpte_dw0.h.v = 0;
+	hptep->dw0.dword0 = hpte_dw0.d;
+
+	/* Ensure it is out of the tlb too */
+	_tlbie( va );
+
+	/* Insert the new pp bits into the HPTE */
+	hpte_dw1.d = hptep->dw1.dword1;
+	hpte_dw1.h.pp = newpp;
+	hptep->dw1.dword1 = hpte_dw1.d;
+
+	/* Ensure it is visible before validating */
+	__asm__ __volatile__ ("eieio" : : : "memory");
+
+	/* Turn the valid bit back on in HPTE */
+	hpte_dw0.h.v = 1;
+	hptep->dw0.dword0 = hpte_dw0.d;
+
+	__asm__ __volatile__ ("ptesync" : : : "memory");
+}
+
+/*
+ * Update the page protection bits.  Intended to be used to create
+ * guard pages for kernel data structures on pages which are bolted
+ * in the HPT.  Assumes pages being operated on will not be stolen. 
+ */
+void hpte_updateboltedpp_iSeries(unsigned long newpp, unsigned long ea )
+{
+	unsigned long vsid,va,vpn;
+	long slot;
+
+	vsid = get_kernel_vsid( ea );
+	va = ( vsid << 28 ) | ( ea & 0x0fffffff );
+	vpn = va >> PAGE_SHIFT;
+
+	slot = ppc_md.hpte_find( vpn );
+	HvCallHpt_setPp( slot, newpp );
+}
+
+
+static __inline__ void set_pp_bit(unsigned long  pp, HPTE *addr)
+{
+	unsigned long old;
+	unsigned long *p = (unsigned long *)(&(addr->dw1));
+
+	__asm__ __volatile__(
+        "1:	ldarx	%0,0,%3\n\
+                rldimi  %0,%2,0,62\n\
+                stdcx.	%0,0,%3\n\
+            	bne	1b"
+        : "=&r" (old), "=m" (*p)
+        : "r" (pp), "r" (p), "m" (*p)
+        : "cc");
+}
+
+/*
+ * Update the page protection bits.  Intended to be used to create
+ * guard pages for kernel data structures on pages which are bolted
+ * in the HPT.  Assumes pages being operated on will not be stolen. 
+ */
+void hpte_updateboltedpp_pSeries(unsigned long newpp, unsigned long ea)
+{
+	unsigned long vsid,va,vpn,flags;
+	long slot;
+	HPTE *hptep;
+
+	vsid = get_kernel_vsid( ea );
+	va = ( vsid << 28 ) | ( ea & 0x0fffffff );
+	vpn = va >> PAGE_SHIFT;
+
+	slot = ppc_md.hpte_find( vpn );
+	hptep = htab_data.htab  + slot;
+
+	set_pp_bit(newpp , hptep);
+
+	/* Ensure it is out of the tlb too */
+	spin_lock_irqsave( &hash_table_lock, flags );
+	_tlbie( va );
+	spin_unlock_irqrestore( &hash_table_lock, flags );
+}
+
+
+
+/* This is called very early. */
+void hpte_init_iSeries(void)
+{
+	ppc_md.hpte_invalidate   = hpte_invalidate_iSeries;
+	ppc_md.hpte_updatepp     = hpte_updatepp_iSeries;
+	ppc_md.hpte_updateboltedpp = hpte_updateboltedpp_iSeries;
+	ppc_md.hpte_getword0     = hpte_getword0_iSeries;
+	ppc_md.hpte_selectslot   = hpte_selectslot_iSeries;
+	ppc_md.hpte_create_valid = hpte_create_valid_iSeries;
+	ppc_md.hpte_find	 = hpte_find_iSeries;
+}
+void hpte_init_pSeries(void)
+{
+	ppc_md.hpte_invalidate   = hpte_invalidate_pSeries;
+	ppc_md.hpte_updatepp     = hpte_updatepp_pSeries;
+	ppc_md.hpte_updateboltedpp = hpte_updateboltedpp_pSeries;
+	ppc_md.hpte_getword0     = hpte_getword0_pSeries;
+	ppc_md.hpte_selectslot   = hpte_selectslot_pSeries;
+	ppc_md.hpte_create_valid = hpte_create_valid_pSeries;
+	ppc_md.hpte_find	 = hpte_find_pSeries;
+}
+
+/* Handle a fault by adding an HPTE 
+ * If the address can't be determined to be valid
+ * via Linux page tables, return 1.  If handled
+ * return 0
+ */
+int hash_page( unsigned long ea, unsigned long access )
+{
+	int rc = 1;
+	void * pgdir = NULL;
+	unsigned long va, vsid, vpn;
+	unsigned long newpp, hash_ind, prpn;
+	unsigned long hpteflags, regionid;
+	long slot;
+	struct mm_struct * mm;
+	pte_t old_pte, new_pte, *ptep;
+
+	/* Check for invalid addresses. */
+	if (!IS_VALID_EA(ea)) {
+		return 1;
+	}
+
+	regionid =  REGION_ID(ea);
+	switch ( regionid ) {
+	case USER_REGION_ID:
+		mm = current->mm;
+		if ( mm == NULL ) {
+			PPCDBG(PPCDBG_MM, "hash_page returning; mm = 0\n"); 
+			return 1;
+		}
+		vsid = get_vsid(mm->context, ea );
+		break;
+	case IO_REGION_ID:
+		mm = &ioremap_mm;
+		vsid = get_kernel_vsid( ea );
+		break;
+	case VMALLOC_REGION_ID:
+		mm = &init_mm;
+		vsid = get_kernel_vsid( ea );
+		break;
+	case IO_UNMAPPED_REGION_ID:
+		udbg_printf("EEH Error ea = 0x%lx\n", ea);
+ 		PPCDBG_ENTER_DEBUGGER();
+		panic("EEH Error ea = 0x%lx\n", ea);
+		break;
+	case KERNEL_REGION_ID:
+		/* As htab_initialize is now, we shouldn't ever get here since
+		 * we're bolting the entire 0xC0... region.
+		 */
+		udbg_printf("Little faulted on kernel address 0x%lx\n", ea);
+ 		PPCDBG_ENTER_DEBUGGER();
+		panic("Little faulted on kernel address 0x%lx\n", ea);
+		break;
+	default:
+		/* Not a valid range, send the problem up to do_page_fault */
+		return 1;
+		break;
+	}
+
+	/* Search the Linux page table for a match with va */
+        va = ( vsid << 28 ) | ( ea & 0x0fffffff );
+	vpn = va >> PAGE_SHIFT;
+	pgdir = mm->pgd;
+	PPCDBG(PPCDBG_MM, "hash_page ea = 0x%16.16lx, va = 0x%16.16lx\n          current = 0x%16.16lx, access = %lx\n", ea, va, current, access); 
+                if ( pgdir == NULL ) {
+                return 1;
+	}
+	
+	/* Lock the Linux page table to prevent mmap and kswapd
+	 * from modifying entries while we search and update
+	 */
+	
+	spin_lock( &mm->page_table_lock );
+	
+	ptep = find_linux_pte( pgdir, ea );
+	/* If no pte found, send the problem up to do_page_fault */
+	if ( ! ptep ) {
+	  spin_unlock( &mm->page_table_lock );
+	  return 1;
+	}
+	
+	/* Acquire the hash table lock to guarantee that the linux
+	 * pte we fetch will not change
+	 */
+	spin_lock( &hash_table_lock );
+	
+	old_pte = *ptep;
+	
+	/* If the pte is not "present" (valid), send the problem
+	 * up to do_page_fault.
+	 */
+	if ( ! pte_present( old_pte ) ) {
+	  spin_unlock( &hash_table_lock );
+	  spin_unlock( &mm->page_table_lock );
+	  return 1;
+	}
+	
+	/* At this point we have found a pte (which was present).
+	 * The spinlocks prevent this status from changing
+	 * The hash_table_lock prevents the _PAGE_HASHPTE status
+	 * from changing (RPN, DIRTY and ACCESSED too)
+	 * The page_table_lock prevents the pte from being 
+	 * invalidated or modified
+	 */
+
+/* At this point, we have a pte (old_pte) which can be used to build or update
+ * an HPTE.   There are 5 cases:
+ *
+ * 1. There is a valid (present) pte with no associated HPTE (this is 
+ *	the most common case)
+ * 2. There is a valid (present) pte with an associated HPTE.  The
+ *	current values of the pp bits in the HPTE prevent access because the
+ *	user doesn't have appropriate access rights.
+ * 3. There is a valid (present) pte with an associated HPTE.  The
+ *	current values of the pp bits in the HPTE prevent access because we are
+ *	doing software DIRTY bit management and the page is currently not DIRTY. 
+ * 4. This is a Kernel address (0xC---) for which there is no page directory.
+ *	There is an HPTE for this page, but the pp bits prevent access.
+ *      Since we always set up kernel pages with R/W access for the kernel
+ *	this case only comes about for users trying to access the kernel.
+ *	This case is always an error and is not dealt with further here.
+ * 5. This is a Kernel address (0xC---) for which there is no page directory.
+ *	There is no HPTE for this page.
+
+ * Check the user's access rights to the page.  If access should be prevented
+ * then send the problem up to do_page_fault.
+ */
+
+	access |= _PAGE_PRESENT;
+	if ( 0 == ( access & ~(pte_val(old_pte)) ) ) {
+		/*
+		 * Check if pte might have an hpte, but we have
+		 * no slot information
+		 */
+		if ( pte_val(old_pte) & _PAGE_HPTENOIX ) {
+			unsigned long slot;	
+			pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
+			slot = ppc_md.hpte_find( vpn );
+			if ( slot != -1 ) {
+				if ( slot < 0 ) {
+					pte_val(old_pte) |= _PAGE_SECONDARY;
+					slot = -slot;
+				}
+				pte_val(old_pte) |= ((slot << 12) & _PAGE_GROUP_IX) | _PAGE_HASHPTE;
+				
+			}
+		}
+
+		/* User has appropriate access rights. */
+		new_pte = old_pte;
+		/* If the attempted access was a store */
+		if ( access & _PAGE_RW )
+			pte_val(new_pte) |= _PAGE_ACCESSED |
+				_PAGE_DIRTY;
+		else
+			pte_val(new_pte) |= _PAGE_ACCESSED;
+
+		/* Only cases 1, 3 and 5 still in play */
+
+		newpp = computeHptePP( pte_val(new_pte) );
+
+		/* Check if pte already has an hpte (case 3) */
+		if ( pte_val(old_pte) & _PAGE_HASHPTE ) {
+			/* There MIGHT be an HPTE for this pte */
+			unsigned long hash, slot, secondary;
+			/* Local copy of first doubleword of HPTE */
+			union {
+				unsigned long d;
+				Hpte_dword0   h;
+			} hpte_dw0;
+			hash = hpt_hash(vpn, 0);
+			secondary = (pte_val(old_pte) & _PAGE_SECONDARY) >> 15;
+			if ( secondary )
+				hash = ~hash;
+			slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+			slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;
+			/* If there is an HPTE for this page it is indexed by slot */
+			hpte_dw0.d = ppc_md.hpte_getword0( slot );
+			if ( (hpte_dw0.h.avpn == (vpn >> 11) ) &&
+			     (hpte_dw0.h.v) && 
+			     (hpte_dw0.h.h == secondary ) ){
+				/* HPTE matches */
+				ppc_md.hpte_updatepp( slot, newpp, va );
+				if ( !pte_same( old_pte, new_pte ) )
+					*ptep = new_pte;
+			}
+			else {
+				/* HPTE is not for this pte */
+				pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
+			}
+		}
+		if ( !( pte_val(old_pte) & _PAGE_HASHPTE ) ) {
+			/* Cases 1 and 5 */
+			/* For these cases we need to create a new
+			 * HPTE and update the linux pte (for
+			 * case 1).  For case 5 there is no linux pte.
+			 *
+			 * Find an available HPTE slot
+ 			 */
+			slot = ppc_md.hpte_selectslot( vpn );
+
+			/* If hpte_selectslot returns 0x8000000000000000 that means
+			 * that there was already an entry in the HPT even though
+			 * the linux PTE said there couldn't be. 
+			 */
+			/* Debug code */
+			if ( slot == 0x8000000000000000 ) {
+				unsigned long xold_pte = pte_val(old_pte);
+				unsigned long xnew_pte = pte_val(new_pte);
+				
+				udbg_printf("hash_page: ptep    = 0x%016lx\n", (unsigned long)ptep );
+				udbg_printf("hash_page: old_pte = 0x%016lx\n", xold_pte );
+				udbg_printf("hash_page: new_pte = 0x%016lx\n", xnew_pte );
+				udbg_printf("hash_page: ea      = 0x%016lx\n", ea );
+				udbg_printf("hash_page: va      = 0x%016lx\n", va );
+				udbg_printf("hash_page: access  = 0x%016lx\n", access );
+			
+				panic("hash_page: hpte already exists\n");
+			}
+			hash_ind = 0;
+			if ( slot < 0 ) {
+				slot = -slot;
+				hash_ind = 1;
+			}
+
+			/* Set the physical address */
+			prpn = pte_val(old_pte) >> PTE_SHIFT;
+			
+			if ( ptep ) {
+				/* Update the linux pte with the HPTE slot */
+				pte_val(new_pte) &= ~_PAGE_HPTEFLAGS;
+				pte_val(new_pte) |= hash_ind << 15;
+				pte_val(new_pte) |= (slot<<12) & _PAGE_GROUP_IX;
+				pte_val(new_pte) |= _PAGE_HASHPTE;
+				/* No need to use ldarx/stdcx here because all
+				 * who might be updating the pte will hold the page_table_lock
+				 * or the hash_table_lock (we hold both)
+				 */
+				*ptep = new_pte;
+			}
+
+			/* copy appropriate flags from linux pte */
+			hpteflags = (pte_val(new_pte) & 0x1f8) | newpp;
+
+			/* Create the HPTE */
+			ppc_md.hpte_create_valid( slot, vpn, prpn, hash_ind, ptep, hpteflags, 0 ); 
+
+		}
+
+		/* Indicate success */
+		rc = 0;
+	}		
+	
+	spin_unlock( &hash_table_lock );
+	if (ptep)
+		spin_unlock( &mm->page_table_lock );
+
+	return rc;
+}
+
+void flush_hash_page( unsigned long context, unsigned long ea, pte_t *ptep )
+{
+	unsigned long vsid, vpn, va, hash, secondary, slot, flags;
+	/* Local copy of first doubleword of HPTE */
+	union {
+		unsigned long d;
+		Hpte_dword0   h;
+	} hpte_dw0;
+	pte_t pte;
+
+	if ( (ea >= USER_START ) && ( ea <= USER_END ) )
+		vsid = get_vsid( context, ea );
+	else
+		vsid = get_kernel_vsid( ea );
+	va = (vsid << 28) | (ea & 0x0fffffff);
+	vpn = va >> PAGE_SHIFT;
+	hash = hpt_hash(vpn, 0);
+
+	spin_lock_irqsave( &hash_table_lock, flags);
+	pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
+	if ( pte_val(pte) & _PAGE_HASHPTE ) {
+		secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
+		if ( secondary )
+			hash = ~hash;
+		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+		slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
+		/* If there is an HPTE for this page it is indexed by slot */
+
+		hpte_dw0.d = ppc_md.hpte_getword0( slot );
+		if ( (hpte_dw0.h.avpn == (vpn >> 11) ) &&
+		     (hpte_dw0.h.v) && 
+		     (hpte_dw0.h.h == secondary ) ){
+			/* HPTE matches */
+			ppc_md.hpte_invalidate( slot );	
+		}
+		else {
+			unsigned k;
+			/* Temporarily lets check for the hpte in all possible slots */
+			for ( secondary = 0; secondary < 2; ++secondary ) {
+				hash = hpt_hash(vpn, 0);
+				if ( secondary )
+					hash = ~hash;
+				slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+				for ( k=0; k<8; ++k ) {
+					hpte_dw0.d = ppc_md.hpte_getword0( slot+k );
+					if ( ( hpte_dw0.h.avpn == (vpn >> 11) ) &&
+					     ( hpte_dw0.h.v ) &&
+					     ( hpte_dw0.h.h == secondary ) ) {
+						while (1) ;
+					}
+				}
+			}
+		}
+	}
+	spin_unlock_irqrestore( &hash_table_lock, flags );
+}
+
+int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
+		   void *buffer, size_t *lenp)
+{
+	int vleft, first=1, len, left, val;
+#define TMPBUFLEN 256
+	char buf[TMPBUFLEN], *p;
+	static const char *sizestrings[4] = {
+		"2MB", "256KB", "512KB", "1MB"
+	};
+	static const char *clockstrings[8] = {
+		"clock disabled", "+1 clock", "+1.5 clock", "reserved(3)",
+		"+2 clock", "+2.5 clock", "+3 clock", "reserved(7)"
+	};
+	static const char *typestrings[4] = {
+		"flow-through burst SRAM", "reserved SRAM",
+		"pipelined burst SRAM", "pipelined late-write SRAM"
+	};
+	static const char *holdstrings[4] = {
+		"0.5", "1.0", "(reserved2)", "(reserved3)"
+	};
+
+	if ( ((_get_PVR() >> 16) != 8) && ((_get_PVR() >> 16) != 12))
+		return -EFAULT;
+	
+	if ( /*!table->maxlen ||*/ (filp->f_pos && !write)) {
+		*lenp = 0;
+		return 0;
+	}
+	
+	vleft = table->maxlen / sizeof(int);
+	left = *lenp;
+	
+	for (; left /*&& vleft--*/; first=0) {
+		if (write) {
+			while (left) {
+				char c;
+				if(get_user(c,(char *) buffer))
+					return -EFAULT;
+				if (!isspace(c))
+					break;
+				left--;
+				((char *) buffer)++;
+			}
+			if (!left)
+				break;
+			len = left;
+			if (len > TMPBUFLEN-1)
+				len = TMPBUFLEN-1;
+			if(copy_from_user(buf, buffer, len))
+				return -EFAULT;
+			buf[len] = 0;
+			p = buf;
+			if (*p < '0' || *p > '9')
+				break;
+			val = simple_strtoul(p, &p, 0);
+			len = p-buf;
+			if ((len < left) && *p && !isspace(*p))
+				break;
+			buffer += len;
+			left -= len;
+#if 0
+			/* DRENG need a def */
+			_set_L2CR(0);
+			_set_L2CR(val);
+			while ( _get_L2CR() & 0x1 )
+				/* wait for invalidate to finish */;
+#endif
+			  
+		} else {
+			p = buf;
+			if (!first)
+				*p++ = '\t';
+#if 0
+			/* DRENG need a def */
+			val = _get_L2CR();
+#endif
+			p += sprintf(p, "0x%08x: ", val);
+			p += sprintf(p, " %s", (val >> 31) & 1 ? "enabled" :
+				     "disabled");
+			p += sprintf(p, ", %sparity", (val>>30)&1 ? "" : "no ");
+			p += sprintf(p, ", %s", sizestrings[(val >> 28) & 3]);
+			p += sprintf(p, ", %s", clockstrings[(val >> 25) & 7]);
+			p += sprintf(p, ", %s", typestrings[(val >> 23) & 2]);
+			p += sprintf(p, "%s", (val>>22)&1 ? ", data only" : "");
+			p += sprintf(p, "%s", (val>>20)&1 ? ", ZZ enabled": "");
+			p += sprintf(p, ", %s", (val>>19)&1 ? "write-through" :
+				     "copy-back");
+			p += sprintf(p, "%s", (val>>18)&1 ? ", testing" : "");
+			p += sprintf(p, ", %sns hold",holdstrings[(val>>16)&3]);
+			p += sprintf(p, "%s", (val>>15)&1 ? ", DLL slow" : "");
+			p += sprintf(p, "%s", (val>>14)&1 ? ", diff clock" :"");
+			p += sprintf(p, "%s", (val>>13)&1 ? ", DLL bypass" :"");
+			
+			p += sprintf(p,"\n");
+			
+			len = strlen(buf);
+			if (len > left)
+				len = left;
+			if(copy_to_user(buffer, buf, len))
+				return -EFAULT;
+			left -= len;
+			buffer += len;
+			break;
+		}
+	}
+
+	if (!write && !first && left) {
+		if(put_user('\n', (char *) buffer))
+			return -EFAULT;
+		left--, buffer++;
+	}
+	if (write) {
+		p = (char *) buffer;
+		while (left) {
+			char c;
+			if(get_user(c, p++))
+				return -EFAULT;
+			if (!isspace(c))
+				break;
+			left--;
+		}
+	}
+	if (write && first)
+		return -EINVAL;
+	*lenp -= left;
+	filp->f_pos += *lenp;
+	return 0;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/hvCall.S linux/arch/ppc64/kernel/hvCall.S
--- linux.orig/arch/ppc64/kernel/hvCall.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/hvCall.S	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,99 @@
+/*
+ * arch/ppc64/kernel/hvCall.S
+ *
+ *
+ * This file contains the code to perform calls to the
+ * iSeries LPAR hypervisor
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "ppc_asm.h"
+#include <asm/processor.h>
+#include <linux/config.h>
+
+	.text
+
+/* 
+ * Hypervisor call
+ * 
+ * Invoke the iSeries hypervisor via the System Call instruction
+ * Parameters are passed to this routine in registers r3 - r10
+ * 
+ * r3 contains the HV function to be called
+ * r4-r10 contain the operands to the hypervisor function
+ *
+ */
+
+_GLOBAL(HvCall)
+_GLOBAL(HvCall0)
+_GLOBAL(HvCall1)
+_GLOBAL(HvCall2)
+_GLOBAL(HvCall3)
+_GLOBAL(HvCall4)
+_GLOBAL(HvCall5)
+_GLOBAL(HvCall6)
+_GLOBAL(HvCall7)
+
+
+	mfcr	r0
+	std	r0,-8(r1)
+	stdu	r1,-(STACK_FRAME_OVERHEAD+16)(r1)
+	
+	/* r0 = 0xffffffffffffffff indicates a hypervisor call */
+	
+	li	r0,-1
+	
+	/* Invoke the hypervisor */
+
+	sc
+
+	ld	r1,0(r1)
+	ld	r0,-8(r1)
+	mtcrf	0xff,r0
+
+	/*  return to caller, return value in r3 */
+	
+	blr
+
+_GLOBAL(HvCall0Ret16)
+_GLOBAL(HvCall1Ret16)
+_GLOBAL(HvCall2Ret16)
+_GLOBAL(HvCall3Ret16)
+_GLOBAL(HvCall4Ret16)
+_GLOBAL(HvCall5Ret16)
+_GLOBAL(HvCall6Ret16)
+_GLOBAL(HvCall7Ret16)
+
+	mfcr	r0
+	std	r0,-8(r1)
+	std	r31,-16(r1)
+	stdu	r1,-(STACK_FRAME_OVERHEAD+32)(r1)
+
+	mr	r31,r4
+	li	r0,-1
+	mr	r4,r5
+	mr	r5,r6
+	mr	r6,r7
+	mr	r7,r8
+	mr	r8,r9
+	mr	r9,r10
+
+	sc
+
+	std	r3,0(r31)
+	std	r4,8(r31)
+
+	mr	r3,r5
+
+	ld	r1,0(r1)
+	ld	r0,-8(r1)
+	mtcrf	0xff,r0
+	ld	r31,-16(r1)
+	
+	blr
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/i8259.c linux/arch/ppc64/kernel/i8259.c
--- linux.orig/arch/ppc64/kernel/i8259.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/i8259.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,164 @@
+/*
+ * c 2001 PPC64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/cache.h>
+#include <asm/io.h>
+#include "i8259.h"
+#include <linux/irq.h>
+#include <asm/ppcdebug.h>
+
+unsigned char cached_8259[2] = { 0xff, 0xff };
+#define cached_A1 (cached_8259[0])
+#define cached_21 (cached_8259[1])
+
+static spinlock_t i8259_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+
+int i8259_pic_irq_offset;
+
+int i8259_irq(int cpu)
+{
+	int irq;
+	
+	spin_lock/*_irqsave*/(&i8259_lock/*, flags*/);
+        /*
+         * Perform an interrupt acknowledge cycle on controller 1
+         */                                                             
+        outb(0x0C, 0x20);
+        irq = inb(0x20) & 7;                                   
+        if (irq == 2)                                                     
+        {                                                                   
+                /*                                     
+                 * Interrupt is cascaded so perform interrupt
+                 * acknowledge on controller 2
+                 */
+                outb(0x0C, 0xA0);                      
+                irq = (inb(0xA0) & 7) + 8;
+        }
+        else if (irq==7)                                
+        {
+                /*                               
+                 * This may be a spurious interrupt
+                 *                         
+                 * Read the interrupt status register. If the most
+                 * significant bit is not set then there is no valid
+		 * interrupt
+		 */
+		outb(0x0b, 0x20);
+		if(~inb(0x20)&0x80) {
+			spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
+			return -1;
+		}
+	}
+	spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
+	return irq;
+}
+
+static void i8259_mask_and_ack_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+	
+	spin_lock_irqsave(&i8259_lock, flags);
+        if ( irq_nr >= i8259_pic_irq_offset )
+                irq_nr -= i8259_pic_irq_offset;
+
+        if (irq_nr > 7) {                                                   
+                cached_A1 |= 1 << (irq_nr-8);                                   
+                inb(0xA1);      /* DUMMY */                                     
+                outb(cached_A1,0xA1);                                           
+                outb(0x20,0xA0);        /* Non-specific EOI */             
+                outb(0x20,0x20);        /* Non-specific EOI to cascade */
+        } else {                                                            
+                cached_21 |= 1 << irq_nr;                                   
+                inb(0x21);      /* DUMMY */                                 
+                outb(cached_21,0x21);
+                outb(0x20,0x20);        /* Non-specific EOI */                 
+        }                                                                
+	spin_unlock_irqrestore(&i8259_lock, flags);
+}
+
+static void i8259_set_irq_mask(int irq_nr)
+{
+        outb(cached_A1,0xA1);
+        outb(cached_21,0x21);
+}
+
+static void i8259_mask_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259_lock, flags);
+        if ( irq_nr >= i8259_pic_irq_offset )
+                irq_nr -= i8259_pic_irq_offset;
+        if ( irq_nr < 8 )
+                cached_21 |= 1 << irq_nr;
+        else
+                cached_A1 |= 1 << (irq_nr-8);
+        i8259_set_irq_mask(irq_nr);
+	spin_unlock_irqrestore(&i8259_lock, flags);
+}
+
+static void i8259_unmask_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259_lock, flags);
+        if ( irq_nr >= i8259_pic_irq_offset )
+                irq_nr -= i8259_pic_irq_offset;
+        if ( irq_nr < 8 )
+                cached_21 &= ~(1 << irq_nr);
+        else
+                cached_A1 &= ~(1 << (irq_nr-8));
+        i8259_set_irq_mask(irq_nr);
+	spin_unlock_irqrestore(&i8259_lock, flags);
+}
+
+static void i8259_end_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		i8259_unmask_irq(irq);
+}
+
+struct hw_interrupt_type i8259_pic = {
+        " i8259    ",
+        NULL,
+        NULL,
+        i8259_unmask_irq,
+        i8259_mask_irq,
+        i8259_mask_and_ack_irq,
+        i8259_end_irq,
+        NULL
+};
+
+void __init i8259_init(void)
+{
+	unsigned long flags;
+	
+	spin_lock_irqsave(&i8259_lock, flags);
+        /* init master interrupt controller */
+        outb(0x11, 0x20); /* Start init sequence */
+        outb(0x00, 0x21); /* Vector base */
+        outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
+        outb(0x01, 0x21); /* Select 8086 mode */
+        outb(0xFF, 0x21); /* Mask all */
+        /* init slave interrupt controller */
+        outb(0x11, 0xA0); /* Start init sequence */
+        outb(0x08, 0xA1); /* Vector base */
+        outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
+        outb(0x01, 0xA1); /* Select 8086 mode */
+        outb(0xFF, 0xA1); /* Mask all */
+        outb(cached_A1, 0xA1);
+        outb(cached_21, 0x21);
+	spin_unlock_irqrestore(&i8259_lock, flags);
+        request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT,
+                     "82c59 secondary cascade", NULL );
+        
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/i8259.h linux/arch/ppc64/kernel/i8259.h
--- linux.orig/arch/ppc64/kernel/i8259.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/i8259.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,19 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ */
+#ifndef _PPC_KERNEL_i8259_H
+#define _PPC_KERNEL_i8259_H
+
+#include "local_irq.h"
+
+extern struct hw_interrupt_type i8259_pic;
+
+void i8259_init(void);
+int i8259_irq(int);
+
+#endif /* _PPC_KERNEL_i8259_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_IoMmTable.c linux/arch/ppc64/kernel/iSeries_IoMmTable.c
--- linux.orig/arch/ppc64/kernel/iSeries_IoMmTable.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_IoMmTable.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,163 @@
+/************************************************************************/
+/* This module supports the iSeries I/O Address translation mapping     */
+/* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
+/*                                                                      */
+/* 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created, December 14, 2000                                         */
+/*   Added Bar table for IoMm performance.                              */
+/*   Ported to ppc64                                                    */
+/*   Added dynamic table allocation                                     */
+/* End Change Activity                                                  */
+/************************************************************************/
+#include <asm/types.h>
+#include <asm/resource.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <asm/ppcdebug.h>
+#include <asm/flight_recorder.h>
+#include <asm/iSeries/HvCallPci.h>
+#include <asm/iSeries/iSeries_pci.h>
+
+#include "iSeries_IoMmTable.h"
+#include "pci.h"
+
+/*******************************************************************/
+/* Table defines                                                   */
+/* Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space. */
+/*******************************************************************/
+#define Max_Entries 1024
+unsigned long iSeries_IoMmTable_Entry_Size = 0x0000000000400000; 
+unsigned long iSeries_Base_Io_Memory       = 0xE000000000000000;
+unsigned long iSeries_Max_Io_Memory        = 0xE000000000000000;
+static   long iSeries_CurrentIndex         = 0;
+
+/*******************************************************************/
+/* Lookup Tables.                                                  */
+/*******************************************************************/
+struct iSeries_Device_Node** iSeries_IoMmTable;
+u8*                          iSeries_IoBarTable;
+
+/*******************************************************************/
+/* Static and Global variables                                     */
+/*******************************************************************/
+static char*      iSeriesPciIoText     = "iSeries PCI I/O";
+static spinlock_t iSeriesIoMmTableLock = SPIN_LOCK_UNLOCKED;
+
+/*******************************************************************/
+/* iSeries_IoMmTable_Initialize                                    */
+/*******************************************************************/
+/* Allocates and initalizes the Address Translation Table and Bar  */
+/* Tables to get them ready for use.  Must be called before any    */
+/* I/O space is handed out to the device BARs.                     */
+/* A follow up method,iSeries_IoMmTable_Status can be called to    */
+/* adjust the table after the device BARs have been assiged to     */
+/* resize the table.                                               */
+/*******************************************************************/
+void iSeries_IoMmTable_Initialize(void)
+{
+	spin_lock(&iSeriesIoMmTableLock);
+	iSeries_IoMmTable  = kmalloc(sizeof(void*)*Max_Entries,GFP_KERNEL);
+	iSeries_IoBarTable = kmalloc(sizeof(u8)*Max_Entries,   GFP_KERNEL);
+	spin_unlock(&iSeriesIoMmTableLock);
+	PCIFR("IoMmTable Initialized 0x%p",  iSeries_IoMmTable);
+	if(iSeries_IoMmTable == NULL || iSeries_IoBarTable == NULL) {
+		panic("PCI: I/O tables allocation failed.\n");
+	}
+}
+
+/*******************************************************************/
+/* iSeries_IoMmTable_AllocateEntry                                 */
+/*******************************************************************/
+/* Adds pci_dev entry in address translation table                 */
+/*******************************************************************/
+/* - Allocates the number of entries required in table base on BAR */
+/*   size.                                                         */
+/* - Allocates starting at iSeries_Base_Io_Memory and increases.   */
+/* - The size is round up to be a multiple of entry size.          */
+/* - CurrentIndex is incremented to keep track of the last entry.  */
+/* - Builds the resource entry for allocated BARs.                 */
+/*******************************************************************/
+static void iSeries_IoMmTable_AllocateEntry(struct pci_dev* PciDev, int BarNumber)
+{
+	struct resource* BarResource = &PciDev->resource[BarNumber];
+	long             BarSize     = pci_resource_len(PciDev,BarNumber);
+	/***********************************************************/
+	/* No space to allocate, quick exit, skip Allocation.      */
+	/***********************************************************/
+	if(BarSize == 0) return;
+	/***********************************************************/
+	/* Set Resource values.                                    */
+	/***********************************************************/
+	spin_lock(&iSeriesIoMmTableLock);
+	BarResource->name  = iSeriesPciIoText;
+	BarResource->start = iSeries_IoMmTable_Entry_Size*iSeries_CurrentIndex;
+	BarResource->start+= iSeries_Base_Io_Memory;
+	BarResource->end   = BarResource->start+BarSize-1;
+	/***********************************************************/
+	/* Allocate the number of table entries needed for BAR.    */
+	/***********************************************************/
+	while (BarSize > 0 ) {
+		*(iSeries_IoMmTable +iSeries_CurrentIndex) = (struct iSeries_Device_Node*)PciDev->sysdata;
+		*(iSeries_IoBarTable+iSeries_CurrentIndex) = BarNumber;
+		BarSize -= iSeries_IoMmTable_Entry_Size;
+		++iSeries_CurrentIndex;
+	}
+	iSeries_Max_Io_Memory = (iSeries_IoMmTable_Entry_Size*iSeries_CurrentIndex)+iSeries_Base_Io_Memory;
+	spin_unlock(&iSeriesIoMmTableLock);
+}
+
+/*******************************************************************/
+/* iSeries_allocateDeviceBars                                      */
+/*******************************************************************/
+/* - Allocates ALL pci_dev BAR's and updates the resources with the*/
+/*   BAR value.  BARS with zero length will have the resources     */
+/*   The HvCallPci_getBarParms is used to get the size of the BAR  */
+/*   space.  It calls iSeries_IoMmTable_AllocateEntry to allocate  */
+/*   each entry.                                                   */
+/* - Loops through The Bar resourses(0 - 5) including the the ROM  */
+/*   is resource(6).                                               */
+/*******************************************************************/
+void iSeries_allocateDeviceBars(struct pci_dev* PciDev)
+{
+	struct resource* BarResource;
+	int              BarNumber;
+	for(BarNumber = 0; BarNumber <= PCI_ROM_RESOURCE; ++BarNumber) {
+		BarResource = &PciDev->resource[BarNumber];
+		iSeries_IoMmTable_AllocateEntry(PciDev, BarNumber);
+    	}
+}
+
+/************************************************************************/
+/* Translates the IoAddress to the device that is mapped to IoSpace.    */
+/* This code is inlined, see the iSeries_pci.c file for the replacement.*/
+/************************************************************************/
+struct iSeries_Device_Node* iSeries_xlateIoMmAddress(void* IoAddress)
+{
+	return NULL;	   
+}
+
+/************************************************************************
+ * Status hook for IoMmTable
+ ************************************************************************/
+void     iSeries_IoMmTable_Status(void)
+{
+	PCIFR("IoMmTable......: 0x%p",iSeries_IoMmTable);
+	PCIFR("IoMmTable Range: 0x%p to 0x%p",iSeries_Base_Io_Memory,iSeries_Max_Io_Memory);
+	return;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_IoMmTable.h linux/arch/ppc64/kernel/iSeries_IoMmTable.h
--- linux.orig/arch/ppc64/kernel/iSeries_IoMmTable.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_IoMmTable.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,85 @@
+#ifndef _ISERIES_IOMMTABLE_H
+#define _ISERIES_IOMMTABLE_H
+/************************************************************************/
+/* File iSeries_IoMmTable.h created by Allan Trautman on Dec 12 2001.   */
+/************************************************************************/
+/* Interfaces for the write/read Io address translation table.          */
+/* Copyright (C) 20yy  Allan H Trautman, IBM 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created December 12, 2000                                          */
+/*   Ported to ppc64, August 30, 2001                                   */
+/* End Change Activity                                                  */
+/************************************************************************/
+
+struct pci_dev;
+struct iSeries_Device_Node;
+
+extern struct iSeries_Device_Node** iSeries_IoMmTable;
+extern u8*                          iSeries_IoBarTable;
+extern unsigned long iSeries_Base_Io_Memory;
+extern unsigned long iSeries_Max_Io_Memory;
+extern unsigned long iSeries_Base_Io_Memory;
+extern unsigned long iSeries_IoMmTable_Entry_Size;
+/************************************************************************/
+/* iSeries_IoMmTable_Initialize                                         */
+/************************************************************************/
+/* - Initalizes the Address Translation Table and get it ready for use. */
+/*   Must be called before any client calls any of the other methods.   */
+/*                                                                      */
+/* Parameters: None.                                                    */
+/*                                                                      */
+/* Return: None.                                                        */  
+/************************************************************************/
+extern  void iSeries_IoMmTable_Initialize(void);
+extern  void iSeries_IoMmTable_Status(void);
+
+/************************************************************************/
+/* iSeries_allocateDeviceBars                                           */
+/************************************************************************/
+/* - Allocates ALL pci_dev BAR's and updates the resources with the BAR */
+/*   value.  BARS with zero length will not have the resources.  The    */
+/*   HvCallPci_getBarParms is used to get the size of the BAR space.    */
+/*   It calls iSeries_IoMmTable_AllocateEntry to allocate each entry.   */
+/*                                                                      */
+/* Parameters:                                                          */
+/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */
+/*           I/O Address.                                               */
+/*                                                                      */
+/* Return:                                                              */
+/*   The pci_dev I/O resources updated with pseudo I/O Addresses.       */
+/************************************************************************/
+extern  void iSeries_allocateDeviceBars(struct pci_dev* );
+
+/************************************************************************/
+/* iSeries_xlateIoMmAddress                                             */
+/************************************************************************/
+/* - Translates an I/O Memory address to Device Node that has been the  */
+/*   allocated the psuedo I/O Address.                                  */
+/*                                                                      */
+/* Parameters:                                                          */
+/* IoAddress = I/O Memory Address.                                      */
+/*                                                                      */
+/* Return:                                                              */
+/*   An iSeries_Device_Node to the device mapped to the I/O address. The*/
+/*   BarNumber and BarOffset are valid if the Device Node is returned.  */
+/************************************************************************/
+extern struct iSeries_Device_Node* iSeries_xlateIoMmAddress(void* IoAddress);
+
+#endif /* _ISERIES_IOMMTABLE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_VpdInfo.c linux/arch/ppc64/kernel/iSeries_VpdInfo.c
--- linux.orig/arch/ppc64/kernel/iSeries_VpdInfo.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_VpdInfo.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,317 @@
+/************************************************************************/
+/* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb  2 2001. */
+/************************************************************************/
+/* This code gets the card location of the hardware                     */
+/* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
+/*                                                                      */
+/* 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created, Feb 2, 2001                                               */
+/*   Ported to ppc64, August 20, 2001                                   */
+/* End Change Activity                                                  */
+/************************************************************************/
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/types.h>
+#include <asm/resource.h>
+
+#include <asm/iSeries/HvCallPci.h>
+#include <asm/iSeries/HvTypes.h>
+#include <asm/iSeries/mf.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/HvCallPci.h>
+//#include <asm/iSeries/iSeries_VpdInfo.h>
+#include <asm/iSeries/iSeries_pci.h>
+#include "pci.h"
+
+/************************************************/
+/* Size of Bus VPD data                         */
+/************************************************/
+#define BUS_VPDSIZE      1024
+/************************************************/
+/* Bus Vpd Tags                                 */
+/************************************************/
+#define  VpdEndOfDataTag   0x78
+#define  VpdEndOfAreaTag   0x79
+#define  VpdIdStringTag    0x82
+#define  VpdVendorAreaTag  0x84
+/************************************************/
+/* Mfg Area Tags                                */
+/************************************************/
+#define  VpdFruFlag       0x4647     // "FG"
+#define  VpdFruFrameId    0x4649     // "FI"
+#define  VpdSlotMapFormat 0x4D46     // "MF"
+#define  VpdAsmPartNumber 0x504E     // "PN"
+#define  VpdFruSerial     0x534E     // "SN"
+#define  VpdSlotMap       0x534D     // "SM"
+
+/************************************************/
+/* Structures of the areas                      */
+/************************************************/
+struct MfgVpdAreaStruct {
+	u16 Tag;
+	u8  TagLength;
+	u8  AreaData1;
+	u8  AreaData2;
+};
+typedef struct MfgVpdAreaStruct MfgArea;
+#define MFG_ENTRY_SIZE   3
+
+struct SlotMapStruct {
+	u8   AgentId;
+	u8   SecondaryAgentId;
+	u8   PhbId;
+	char CardLocation[3];
+	char Parms[8];
+	char Reserved[2];
+}; 
+typedef struct SlotMapStruct SlotMap;
+#define SLOT_ENTRY_SIZE   16
+
+/****************************************************************
+ *                                                              *
+ * Bus, Card, Board, FrameId, CardLocation.                     *
+ ****************************************************************/
+LocationData* iSeries_GetLocationData(struct pci_dev* PciDev)
+{
+	struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)PciDev->sysdata;
+	LocationData* LocationPtr = (LocationData*)kmalloc(LOCATION_DATA_SIZE, GFP_KERNEL);
+	if (LocationPtr == NULL) {
+		printk("PCI: LocationData area allocation failed!\n");
+		return NULL;
+	}
+	memset(LocationPtr,0,LOCATION_DATA_SIZE);
+	LocationPtr->Bus              = ISERIES_BUS(DevNode);
+	LocationPtr->Board            = DevNode->Board;
+	LocationPtr->FrameId          = DevNode->FrameId;
+	LocationPtr->Card             = PCI_SLOT(DevNode->DevFn);
+	strcpy(&LocationPtr->CardLocation[0],&DevNode->CardLocation[0]);
+	return LocationPtr;
+}
+
+/************************************************************************/
+/* Formats the device information.                                      */
+/* - Pass in pci_dev* pointer to the device.                            */
+/* - Pass in buffer to place the data.  Danger here is the buffer must  */
+/*   be as big as the client says it is.   Should be at least 128 bytes.*/
+/* Return will the length of the string data put in the buffer.         */
+/* Format:                                                              */
+/* PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet */
+/* controller                                                           */
+/************************************************************************/
+int  iSeries_Device_Information(struct pci_dev* PciDev,char* Buffer, int BufferSize)
+{
+	struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)PciDev->sysdata;
+	char*          BufPtr  = Buffer;
+	int            LineLen = 0;
+
+	if (DevNode == NULL) {
+		LineLen = sprintf(BufPtr+LineLen, "PCI: iSeries_Device_Information DevNode is NULL");
+		return LineLen;
+	}
+
+	if (BufferSize >= 128) {
+		LineLen =  sprintf(BufPtr+LineLen,"PCI: Bus%3d, Device%3d, Vendor %04X ",
+				   ISERIES_BUS(DevNode), PCI_SLOT(PciDev->devfn),PciDev->vendor);
+
+		LineLen += sprintf(BufPtr+LineLen,"Frame%3d, Card %4s  ", DevNode->FrameId,DevNode->CardLocation);
+
+		if (pci_class_name(PciDev->class >> 8) == 0) {
+			LineLen += sprintf(BufPtr+LineLen,"0x%04X  ",(int)(PciDev->class >> 8));
+		}
+		else {
+			LineLen += sprintf(BufPtr+LineLen,"%s",pci_class_name(PciDev->class >> 8) );
+		}
+	}
+	return LineLen;
+}
+/************************************************************************/
+/* Build a character string of the device location, Frame  1, Card  C10 */
+/************************************************************************/
+int   device_Location(struct pci_dev* PciDev,char* BufPtr)
+{
+	struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)PciDev->sysdata;
+	return sprintf(BufPtr,"PCI: Bus%3d, AgentId%3d, Vendor %04X, Location %s",
+		       DevNode->DsaAddr.busNumber,
+		       DevNode->AgentId,
+		       DevNode->Vendor,
+		       DevNode->Location);
+}
+
+/*****************************************************************/
+/* Parse the Slot Area                                           */
+/*****************************************************************/
+void  iSeries_Parse_SlotArea(SlotMap* MapPtr,int MapLen, struct iSeries_Device_Node* DevNode)
+{
+	int      SlotMapLen = MapLen;
+	SlotMap* SlotMapPtr = MapPtr;
+	/*************************************************************/
+	/* Parse Slot label until we find the one requrested         */
+	/*************************************************************/
+	while (SlotMapLen > 0) {
+		if (SlotMapPtr->AgentId == DevNode->AgentId ) {
+			/*******************************************************/
+			/* If Phb wasn't found, grab the entry first one found.*/ 
+			/*******************************************************/
+			if (DevNode->PhbId == 0xff) {
+				DevNode->PhbId = SlotMapPtr->PhbId; 
+			}
+			/**************************************************/
+			/* Found it, extract the data.                    */
+			/**************************************************/
+			if (SlotMapPtr->PhbId == DevNode->PhbId ) {
+	        		memcpy(&DevNode->CardLocation,&SlotMapPtr->CardLocation,3);
+				DevNode->CardLocation[3]  = 0;
+				break;
+			}
+		}
+		/*********************************************************/
+		/* Point to the next Slot                                */
+		/*********************************************************/
+		SlotMapPtr = (SlotMap*)((char*)SlotMapPtr+SLOT_ENTRY_SIZE);
+		SlotMapLen -= SLOT_ENTRY_SIZE;
+	}
+}
+
+/*****************************************************************/
+/* Parse the Mfg Area                                            */
+/*****************************************************************/
+static void  iSeries_Parse_MfgArea(u8* AreaData,int AreaLen, struct iSeries_Device_Node* DevNode)
+{
+	MfgArea* MfgAreaPtr = (MfgArea*)AreaData;
+	int      MfgAreaLen = AreaLen;
+	u16      SlotMapFmt = 0;
+
+	/*************************************************************/
+	/* Parse Mfg Data                                            */
+	/*************************************************************/
+	while (MfgAreaLen > 0) {
+		int MfgTagLen  = MfgAreaPtr->TagLength;
+		/*******************************************************/
+		/* Frame ID         (FI 4649020310 )                   */
+		/*******************************************************/
+		if (MfgAreaPtr->Tag == VpdFruFrameId) {     /* FI  */
+			DevNode->FrameId = MfgAreaPtr->AreaData1;
+		}
+		/*******************************************************/
+		/* Slot Map Format  (MF 4D46020004 )                   */
+		/*******************************************************/
+		else if (MfgAreaPtr->Tag == VpdSlotMapFormat){   /* MF  */
+			SlotMapFmt = (MfgAreaPtr->AreaData1*256)+(MfgAreaPtr->AreaData2);
+		}
+		/*******************************************************/
+		/* Slot Map         (SM 534D90                         */
+		/*******************************************************/
+		else if (MfgAreaPtr->Tag == VpdSlotMap){         /* SM  */
+			SlotMap*  SlotMapPtr;
+			if (SlotMapFmt == 0x1004) SlotMapPtr = (SlotMap*)((char*)MfgAreaPtr+MFG_ENTRY_SIZE+1);
+ 	    		else                     SlotMapPtr = (SlotMap*)((char*)MfgAreaPtr+MFG_ENTRY_SIZE);
+	    		iSeries_Parse_SlotArea(SlotMapPtr,MfgTagLen, DevNode);
+		}
+		/*********************************************************/
+		/* Point to the next Mfg Area                            */
+		/* Use defined size, sizeof give wrong answer            */
+		/*********************************************************/
+		MfgAreaPtr = (MfgArea*)((char*)MfgAreaPtr + MfgTagLen + MFG_ENTRY_SIZE);
+		MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE); 
+	}	
+}
+
+/*****************************************************************/
+/* Look for "BUS".. Data is not Null terminated.                 */
+/* PHBID of 0xFF indicates PHB was not found in VPD Data.        */	
+/*****************************************************************/
+static int iSeries_Parse_PhbId(u8* AreaPtr,int AreaLength)
+{
+	u8*  PhbPtr  = AreaPtr;
+	int  DataLen = AreaLength;
+	char PhbId   = 0xFF;                   
+	while (DataLen > 0) {
+		if (*PhbPtr == 'B' && *(PhbPtr+1) == 'U' && *(PhbPtr+2) == 'S') {
+			PhbPtr += 3;
+			while(*PhbPtr == ' ') ++PhbPtr;
+			PhbId = (*PhbPtr & 0x0F);
+			break;
+        	}
+		++PhbPtr;
+		--DataLen;
+	}
+	return PhbId;
+}
+
+/****************************************************************/
+/* Parse out the VPD Areas                                      */
+/****************************************************************/
+static void  iSeries_Parse_Vpd(u8* VpdData, int VpdDataLen, struct iSeries_Device_Node* DevNode)
+{
+	u8*  TagPtr  = VpdData;
+	int  DataLen = VpdDataLen-3;
+	/*************************************************************/
+	/* Parse the Areas                                           */
+	/*************************************************************/
+	while (*TagPtr != VpdEndOfAreaTag && DataLen > 0) {
+		int  AreaLen   = *(TagPtr+1) + (*(TagPtr+2)*256);	
+		u8*  AreaData  = TagPtr+3;
+
+		if (*TagPtr == VpdIdStringTag) {
+			DevNode->PhbId = iSeries_Parse_PhbId(AreaData,AreaLen);
+		}
+		else if (*TagPtr == VpdVendorAreaTag) {
+	    		iSeries_Parse_MfgArea(AreaData,AreaLen,DevNode);
+		}
+		/*********************************************************
+		 * Point to next Area.
+		 *********************************************************/
+		TagPtr  = AreaData + AreaLen;
+		DataLen -= AreaLen;
+	}
+}    
+
+/****************************************************************
+ *  iSeries_Get_Location_Code(struct iSeries_Device_Node*)      *
+ *
+ ****************************************************************/
+void  iSeries_Get_Location_Code(struct iSeries_Device_Node* DevNode)
+{
+	int  BusVpdLen = 0;
+	u8*  BusVpdPtr = (u8*)kmalloc(BUS_VPDSIZE, GFP_KERNEL);
+	if (BusVpdPtr == NULL) {
+		printk("PCI: Bus VPD Buffer allocation failure.\n");
+		return;
+	}
+	BusVpdLen  = HvCallPci_getBusVpd(ISERIES_BUS(DevNode),REALADDR(BusVpdPtr),BUS_VPDSIZE);
+	if (BusVpdLen == 0) {
+		kfree(BusVpdPtr);
+		printk("PCI: Bus VPD Buffer zero length.\n");
+		return;
+	}
+	//printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen);
+	/*************************************************************/
+	/* Make sure this is what I think it is                      */
+	/*************************************************************/
+	if (*BusVpdPtr != VpdIdStringTag) {               /*0x82     */
+		printk("PCI: Bus VPD Buffer missing starting tag.\n");
+		kfree(BusVpdPtr);
+		return;
+	}
+	/***************************************************************/
+	/***************************************************************/
+	iSeries_Parse_Vpd(BusVpdPtr,BusVpdLen, DevNode);
+	sprintf(DevNode->Location,"Frame%3d, Card %-4s",DevNode->FrameId,DevNode->CardLocation);
+	kfree(BusVpdPtr);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_irq.c linux/arch/ppc64/kernel/iSeries_irq.c
--- linux.orig/arch/ppc64/kernel/iSeries_irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_irq.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,259 @@
+/************************************************************************/
+/* This module supports the iSeries PCI bus interrupt handling          */
+/* Copyright (C) 20yy  <Robert L Holtorf> <IBM Corp>                    */
+/*                                                                      */
+/* 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created, December 13, 2000 by Wayne Holm                           */ 
+/* End Change Activity                                                  */
+/************************************************************************/
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+#include <linux/ide.h>
+
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <asm/ppcdebug.h>
+
+#include <asm/iSeries/HvCallPci.h>
+#include <asm/iSeries/HvCallXm.h>
+#include <asm/iSeries/iSeries_irq.h>
+#include <asm/iSeries/XmPciLpEvent.h>
+
+
+hw_irq_controller iSeries_IRQ_handler = {
+	"iSeries irq controller",
+	iSeries_startup_IRQ,	/* startup */
+	iSeries_shutdown_IRQ,	/* shutdown */
+	iSeries_enable_IRQ,	/* enable */
+	iSeries_disable_IRQ,	/* disable */
+	NULL,			/* ack  */
+	iSeries_end_IRQ,	/* end  */
+	NULL			/* set_affinity */
+};
+
+
+struct iSeries_irqEntry {
+	u32 dsa;
+	struct iSeries_irqEntry* next;
+};
+
+struct iSeries_irqAnchor {
+	u8  valid : 1;
+	u8  reserved : 7;
+	u16  entryCount;
+	struct iSeries_irqEntry* head;
+};
+
+struct iSeries_irqAnchor iSeries_irqMap[NR_IRQS];
+
+void iSeries_init_irqMap(int irq);
+
+/*  This is called by init_IRQ.  set in ppc_md.init_IRQ by iSeries_setup.c */
+void __init iSeries_init_IRQ(void)
+{
+	int i;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].handler = &iSeries_IRQ_handler;
+		irq_desc[i].status = 0;
+		irq_desc[i].status |= IRQ_DISABLED;
+		irq_desc[i].depth = 1;
+		iSeries_init_irqMap(i);
+	}
+	/* Register PCI event handler and open an event path */
+	PPCDBG(PPCDBG_BUSWALK,"Register PCI event handler and open an event path\n");
+	XmPciLpEvent_init();
+	return;
+}
+
+/**********************************************************************
+ *  Called by iSeries_init_IRQ 
+ * Prevent IRQs 0 and 255 from being used.  IRQ 0 appears in
+ * uninitialized devices.  IRQ 255 appears in the PCI interrupt
+ * line register if a PCI error occurs,
+ *********************************************************************/
+void __init iSeries_init_irqMap(int irq)
+{
+	iSeries_irqMap[irq].valid = (irq == 0 || irq == 255)? 0 : 1;
+	iSeries_irqMap[irq].entryCount = 0;
+	iSeries_irqMap[irq].head = NULL;
+}
+
+/* This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot */
+/* It calculates the irq value for the slot.                                   */
+int __init iSeries_allocate_IRQ(HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId)
+{
+	u8 idsel = (deviceId >> 4);
+	u8 function = deviceId & 0x0F;
+	int irq = ((((busNumber-1)*16 + (idsel-1)*8 + function)*9/8) % 253) + 2;
+	return irq;
+}
+
+/* This is called out of iSeries_scan_slot to assign the EADS slot to its IRQ number */
+int __init iSeries_assign_IRQ(int irq, HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId)
+{
+	int rc;
+	u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId;
+	struct iSeries_irqEntry* newEntry;
+	unsigned long flags;
+
+	if (irq < 0 || irq >= NR_IRQS) {
+		return -1;
+	}
+	newEntry = kmalloc(sizeof(*newEntry), GFP_KERNEL);
+	if (newEntry == NULL) {
+		return -ENOMEM;
+	}
+	newEntry->dsa  = dsa;
+	newEntry->next = NULL;
+	/********************************************************************
+	* Probably not necessary to lock the irq since allocation is only 
+	* done during buswalk, but it should not hurt anything except a 
+	* little performance to be smp safe.
+	*******************************************************************/
+	spin_lock_irqsave(&irq_desc[irq].lock, flags);
+
+	if (iSeries_irqMap[irq].valid) {
+		/* Push the new element onto the irq stack */
+		newEntry->next = iSeries_irqMap[irq].head;
+		iSeries_irqMap[irq].head = newEntry;
+		++iSeries_irqMap[irq].entryCount;
+		rc = 0;
+		PPCDBG(PPCDBG_BUSWALK,"iSeries_assign_IRQ   0x%04X.%02X.%02X = 0x%04X\n",busNumber, subBusNumber, deviceId, irq);
+	}
+	else {
+		printk("PCI: Something is wrong with the iSeries_irqMap. \n");
+		kfree(newEntry);
+		rc = -1;
+    }
+	spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+	return rc;
+}
+
+
+/* This is called by iSeries_activate_IRQs */
+unsigned int iSeries_startup_IRQ(unsigned int irq)
+{
+	struct iSeries_irqEntry* entry;
+	u32 bus, subBus, deviceId, function, mask;
+	for(entry=iSeries_irqMap[irq].head; entry!=NULL; entry=entry->next) {
+		bus      = (entry->dsa >> 16) & 0xFFFF;
+		subBus   = (entry->dsa >> 8) & 0xFF;
+		deviceId = entry->dsa & 0xFF;
+		function = deviceId & 0x0F;
+		/* Link the IRQ number to the bridge */
+		HvCallXm_connectBusUnit(bus, subBus, deviceId, irq);
+        	/* Unmask bridge interrupts in the FISR */
+		mask = 0x01010000 << function;
+		HvCallPci_unmaskFisr(bus, subBus, deviceId, mask);
+		PPCDBG(PPCDBG_BUSWALK,"iSeries_activate_IRQ 0x%02X.%02X.%02X  Irq:0x%02X\n",bus,subBus,deviceId,irq);
+	}
+	return 0;
+}
+
+/* This is called out of iSeries_fixup to activate interrupt
+ * generation for usable slots                              */
+void __init iSeries_activate_IRQs()
+{
+	int irq;
+	unsigned long flags;
+	for (irq=0; irq < NR_IRQS; irq++) {
+		spin_lock_irqsave(&irq_desc[irq].lock, flags);
+		irq_desc[irq].handler->startup(irq);
+		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+    	}
+}
+
+/*  this is not called anywhere currently */
+void iSeries_shutdown_IRQ(unsigned int irq) {
+	struct iSeries_irqEntry* entry;
+	u32 bus, subBus, deviceId, function, mask;
+
+	/* irq should be locked by the caller */
+
+	for (entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
+		bus = (entry->dsa >> 16) & 0xFFFF;
+		subBus = (entry->dsa >> 8) & 0xFF;
+		deviceId = entry->dsa & 0xFF;
+		function = deviceId & 0x0F;
+		/* Invalidate the IRQ number in the bridge */
+		HvCallXm_connectBusUnit(bus, subBus, deviceId, 0);
+		/* Mask bridge interrupts in the FISR */
+		mask = 0x01010000 << function;
+		HvCallPci_maskFisr(bus, subBus, deviceId, mask);
+	}
+
+}
+
+/***********************************************************
+ * This will be called by device drivers (via disable_IRQ)
+ * to disable INTA in the bridge interrupt status register.
+ ***********************************************************/
+void iSeries_disable_IRQ(unsigned int irq)
+{
+	struct iSeries_irqEntry* entry;
+	u32 bus, subBus, deviceId, mask;
+
+	/* The IRQ has already been locked by the caller */
+
+	for (entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
+		bus      = (entry->dsa >> 16) & 0xFFFF;
+		subBus   = (entry->dsa >> 8) & 0xFF;
+		deviceId = entry->dsa & 0xFF;
+		/* Mask secondary INTA   */
+		mask = 0x80000000;
+		HvCallPci_maskInterrupts(bus, subBus, deviceId, mask);
+		PPCDBG(PPCDBG_BUSWALK,"iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n",bus,subBus,deviceId,irq);
+    	}
+}
+
+/***********************************************************
+ * This will be called by device drivers (via enable_IRQ)
+ * to enable INTA in the bridge interrupt status register.
+ ***********************************************************/
+void iSeries_enable_IRQ(unsigned int irq)
+{
+	struct iSeries_irqEntry* entry;
+	u32 bus, subBus, deviceId, mask;
+
+	/* The IRQ has already been locked by the caller */
+	for (entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
+		bus      = (entry->dsa >> 16) & 0xFFFF;
+		subBus   = (entry->dsa >> 8) & 0xFF;
+		deviceId = entry->dsa & 0xFF;
+		/* Unmask secondary INTA */
+		mask = 0x80000000;
+		HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask);
+		PPCDBG(PPCDBG_BUSWALK,"iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n",bus,subBus,deviceId,irq);
+	}
+}
+
+/* Need to define this so ppc_irq_dispatch_handler will NOT call
+   enable_IRQ at the end of interrupt handling.  However, this
+   does nothing because there is not enough information provided
+   to do the EOI HvCall.  This is done by XmPciLpEvent.c */
+void iSeries_end_IRQ(unsigned int irq)
+{
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_pci.c linux/arch/ppc64/kernel/iSeries_pci.c
--- linux.orig/arch/ppc64/kernel/iSeries_pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_pci.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,930 @@
+/*
+ * iSeries_pci.c
+ *
+ * Copyright (C) 2001 Allan Trautman, IBM Corporation
+ *
+ * iSeries specific routines for PCI.
+ * 
+ * Based on code from pci.c and iSeries_pci.c 32bit
+ *
+ * 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/kernel.h>
+#include <linux/list.h> 
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppcdebug.h>
+#include <asm/naca.h>
+#include <asm/flight_recorder.h>
+#include <asm/pci_dma.h>
+
+#include <asm/iSeries/HvCallPci.h>
+#include <asm/iSeries/HvCallSm.h>
+#include <asm/iSeries/HvCallXm.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/iSeries_irq.h>
+#include <asm/iSeries/iSeries_pci.h>
+#include <asm/iSeries/mf.h>
+
+#include "iSeries_IoMmTable.h"
+#include "pci.h"
+
+extern struct pci_controller* hose_head;
+extern struct pci_controller** hose_tail;
+extern int    global_phb_number;
+extern int    panic_timeout;
+
+extern struct device_node *allnodes;
+extern unsigned long phb_tce_table_init(struct pci_controller *phb);
+extern unsigned long iSeries_Base_Io_Memory;    
+
+extern struct pci_ops iSeries_pci_ops;
+extern struct flightRecorder* PciFr;
+extern struct TceTable* tceTables[256];
+
+/*******************************************************************
+ * Counters and control flags. 
+ *******************************************************************/
+extern long   Pci_Io_Read_Count;
+extern long   Pci_Io_Write_Count;
+extern long   Pci_Cfg_Read_Count;
+extern long   Pci_Cfg_Write_Count;
+extern long   Pci_Error_Count;
+
+extern int    Pci_Retry_Max;	
+extern int    Pci_Error_Flag;
+extern int    Pci_Trace_Flag;
+
+extern void iSeries_MmIoTest(void);
+
+
+/*******************************************************************
+ * Forward declares of prototypes. 
+ *******************************************************************/
+struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev);
+struct iSeries_Device_Node* get_Device_Node(struct pci_dev* PciDev);
+
+unsigned long find_and_init_phbs(void);
+void          fixup_resources(struct pci_dev *dev);
+void          iSeries_pcibios_fixup(void);
+struct        pci_controller* alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words) ;
+
+void  iSeries_Scan_PHBs_Slots(struct pci_controller* Phb);
+void  iSeries_Scan_EADs_Bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
+int   iSeries_Scan_Bridge_Slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo* Info);
+void  list_device_nodes(void);
+
+struct pci_dev;
+
+extern struct list_head iSeries_Global_Device_List;
+
+int DeviceCount = 0;
+
+/**********************************************************************************
+ * Log Error infor in Flight Recorder to system Console.
+ * Filter out the device not there errors.
+ * PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx
+ * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
+ * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
+ **********************************************************************************/
+void  pci_Log_Error(char* Error_Text, int Bus, int SubBus, int AgentId, int HvRc)
+{
+	if( HvRc != 0x0302) { 
+		char ErrorString[128];
+		sprintf(ErrorString,"%s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",Error_Text,Bus,SubBus,AgentId,HvRc);
+		PCIFR(ErrorString);
+		printk("PCI: %s\n",ErrorString);
+	}
+}
+
+/**********************************************************************************
+ * Dump the iSeries Temp Device Node 
+ *<4>buswalk [swapper : - DeviceNode: 0xC000000000634300
+ *<4>00. Device Node   = 0xC000000000634300
+ *<4>    - PciDev      = 0x0000000000000000
+ *<4>    - tDevice     = 0x  17:01.00  0x1022 00
+ *<4>  4. Device Node = 0xC000000000634480
+ *<4>     - PciDev    = 0x0000000000000000
+ *<4>     - Device    = 0x  18:38.16 Irq:0xA7 Vendor:0x1014  Flags:0x00
+ *<4>     - Devfn     = 0xB0: 22.18
+ **********************************************************************************/
+void dumpDevice_Node(struct iSeries_Device_Node* DevNode)
+{
+	udbg_printf("Device Node      = 0x%p\n",DevNode);
+	udbg_printf("     - PciDev    = 0x%p\n",DevNode->PciDev);
+	udbg_printf("     - Device    = 0x%4X:%02X.%02X (0x%02X)\n",
+		    ISERIES_BUS(DevNode),
+		    ISERIES_SUBBUS(DevNode),
+		    DevNode->AgentId,
+		    DevNode->DevFn);
+	udbg_printf("     - LSlot     = 0x%02X\n",DevNode->LogicalSlot);
+	udbg_printf("     - TceTable  = 0x%p\n  ",DevNode->DevTceTable);
+
+	udbg_printf("     - DSA       = 0x%04X\n",ISERIES_DSA(DevNode)>>32 );
+
+	udbg_printf("                 = Irq:0x%02X Vendor:0x%04X  Flags:0x%02X\n",
+		    DevNode->Irq,
+		    DevNode->Vendor,
+		    DevNode->Flags );
+	udbg_printf("     - Location  = %s\n",DevNode->CardLocation);
+
+
+}
+/**********************************************************************************
+ * Walk down the device node chain 
+ **********************************************************************************/
+void  list_device_nodes(void)
+{
+	struct list_head* Device_Node_Ptr = iSeries_Global_Device_List.next;
+	while(Device_Node_Ptr != &iSeries_Global_Device_List) {
+		dumpDevice_Node( (struct iSeries_Device_Node*)Device_Node_Ptr );
+		Device_Node_Ptr = Device_Node_Ptr->next;
+	}
+}
+	
+
+/***********************************************************************
+ * build_device_node(u16 Bus, int SubBus, u8 DevFn)
+ *
+ ***********************************************************************/
+struct iSeries_Device_Node* build_device_node(HvBusNumber Bus, HvSubBusNumber  SubBus, int AgentId, int Function)
+{
+	struct iSeries_Device_Node*  DeviceNode;
+
+	PPCDBG(PPCDBG_BUSWALK,"-build_device_node 0x%02X.%02X.%02X Function: %02X\n",Bus,SubBus,AgentId, Function);
+
+	DeviceNode = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
+	if(DeviceNode == NULL) return NULL;
+
+	memset(DeviceNode,0,sizeof(struct iSeries_Device_Node) );
+	list_add_tail(&DeviceNode->Device_List,&iSeries_Global_Device_List);
+	/*DeviceNode->DsaAddr      = ((u64)Bus<<48)+((u64)SubBus<<40)+((u64)0x10<<32); */
+	ISERIES_BUS(DeviceNode)       = Bus;
+	ISERIES_SUBBUS(DeviceNode)    = SubBus;
+	DeviceNode->DsaAddr.deviceId  = 0x10;
+        DeviceNode->DsaAddr.barNumber = 0;
+	DeviceNode->AgentId           = AgentId;
+	DeviceNode->DevFn             = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId),Function );
+	DeviceNode->IoRetry           = 0;
+	iSeries_Get_Location_Code(DeviceNode);
+	PCIFR("Device 0x%02X.%2X, Node:0x%p ",ISERIES_BUS(DeviceNode),ISERIES_DEVFUN(DeviceNode),DeviceNode);
+	return DeviceNode;
+}
+/****************************************************************************
+* 
+* Allocate pci_controller(phb) initialized common variables. 
+* 
+*****************************************************************************/
+struct pci_controller* pci_alloc_pci_controllerX(char *model, enum phb_types controller_type)
+{
+	struct pci_controller *hose;
+	hose = (struct pci_controller*)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
+	if(hose == NULL) return NULL;
+
+	memset(hose, 0, sizeof(struct pci_controller));
+	if(strlen(model) < 8) strcpy(hose->what,model);
+	else                  memcpy(hose->what,model,7);
+	hose->type = controller_type;
+	hose->global_number = global_phb_number;
+	global_phb_number++;
+
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+	return hose;
+}
+
+/****************************************************************************
+ *
+ * unsigned int __init find_and_init_phbs(void)
+ *
+ * Description:
+ *   This function checks for all possible system PCI host bridges that connect
+ *   PCI buses.  The system hypervisor is queried as to the guest partition
+ *   ownership status.  A pci_controller is build for any bus which is partially
+ *   owned or fully owned by this guest partition.
+ ****************************************************************************/
+unsigned long __init find_and_init_phbs(void)
+{
+	struct      pci_controller* phb;
+	HvBusNumber BusNumber;
+
+	PPCDBG(PPCDBG_BUSWALK,"find_and_init_phbs Entry\n");
+
+	/* Check all possible buses. */
+	for (BusNumber = 0; BusNumber < 256; BusNumber++) {
+		int RtnCode = HvCallXm_testBus(BusNumber);
+		if (RtnCode == 0) {
+			phb = pci_alloc_pci_controllerX("PHB HV", phb_type_hypervisor);
+			if(phb == NULL) {
+				printk("PCI: Allocate pci_controller failed.\n");
+				PCIFR(      "Allocate pci_controller failed.");
+				return -1;
+			}
+			phb->pci_mem_offset = phb->local_number = BusNumber;
+			phb->first_busno  = BusNumber;
+			phb->last_busno   = BusNumber;
+			phb->ops          = &iSeries_pci_ops;
+
+			PPCDBG(PPCDBG_BUSWALK, "PCI:Create iSeries pci_controller(%p), Bus: %04X\n",phb,BusNumber);
+			PCIFR("Create iSeries PHB controller: %04X",BusNumber);
+
+			/***************************************************/
+			/* Find and connect the devices.                   */
+			/***************************************************/
+			iSeries_Scan_PHBs_Slots(phb);
+		}
+		/* Check for Unexpected Return code, a clue that something */
+		/* has gone wrong.                                         */
+		else if(RtnCode != 0x0301) {
+			PCIFR("Unexpected Return on Probe(0x%04X): 0x%04X",BusNumber,RtnCode);
+		}
+
+	}
+	return 0;
+}
+/*********************************************************************** 
+ * ppc64_pcibios_init
+ *  
+ * Chance to initialize and structures or variable before PCI Bus walk.
+ *  
+ *<4>buswalk [swapper : iSeries_pcibios_init Entry.
+ *<4>buswalk [swapper : IoMmTable Initialized 0xC00000000034BD30
+ *<4>buswalk [swapper : find_and_init_phbs Entry
+ *<4>buswalk [swapper : Create iSeries pci_controller:(0xC00000001F5C7000), Bus 0x0017
+ *<4>buswalk [swapper : Connect EADs: 0x17.00.12 = 0x00
+ *<4>buswalk [swapper : iSeries_assign_IRQ   0x0017.00.12 = 0x0091
+ *<4>buswalk [swapper : - allocate and assign IRQ 0x17.00.12 = 0x91
+ *<4>buswalk [swapper : - FoundDevice: 0x17.28.10 = 0x12AE
+ *<4>buswalk [swapper : - build_device_node 0x17.28.12
+ *<4>buswalk [swapper : iSeries_pcibios_init Exit.
+ ***********************************************************************/
+void iSeries_pcibios_init(void)
+{
+	PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_init Entry.\n"); 
+
+	iSeries_IoMmTable_Initialize();
+
+	find_and_init_phbs();
+
+	pci_assign_all_busses = 0;
+	PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_init Exit.\n"); 
+}
+/***********************************************************************
+ * iSeries_pcibios_fixup(void)  
+ ***********************************************************************/
+void __init iSeries_pcibios_fixup(void)
+{
+	struct pci_dev* PciDev;
+	struct iSeries_Device_Node* DeviceNode;
+	char   Buffer[256];
+    	int    DeviceCount = 0;
+
+	PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_fixup Entry.\n"); 
+	/******************************************************/
+	/* Fix up at the device node and pci_dev relationship */
+	/******************************************************/
+	mf_displaySrc(0xC9000100);
+
+	pci_for_each_dev(PciDev) {
+		DeviceNode = find_Device_Node(PciDev);
+		if(DeviceNode != NULL) {
+			++DeviceCount;
+			PciDev->sysdata    = (void*)DeviceNode;
+			DeviceNode->PciDev = PciDev;
+
+			PPCDBG(PPCDBG_BUSWALK,"PciDev 0x%p <==> DevNode 0x%p\n",PciDev,DeviceNode );
+
+			iSeries_allocateDeviceBars(PciDev);
+
+			PPCDBGCALL(PPCDBG_BUSWALK,dumpPci_Dev(PciDev) );
+
+			iSeries_Device_Information(PciDev,Buffer, sizeof(Buffer) );
+			printk("%d. %s\n",DeviceCount,Buffer);
+
+			create_pci_bus_tce_table((unsigned long)DeviceNode);
+		} else {
+			printk("PCI: Device Tree not found for 0x%016lX\n",(unsigned long)PciDev);
+		}
+	}
+	iSeries_IoMmTable_Status();
+
+	iSeries_activate_IRQs();
+
+	mf_displaySrc(0xC9000200);
+}
+
+/***********************************************************************
+ * iSeries_pcibios_fixup_bus(int Bus)
+ *
+ ***********************************************************************/
+void iSeries_pcibios_fixup_bus(struct pci_bus* PciBus)
+{
+	PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",PciBus->number); 
+
+}
+
+
+/***********************************************************************
+ * fixup_resources(struct pci_dev *dev) 
+ *	
+ ***********************************************************************/
+void fixup_resources(struct pci_dev *PciDev)
+{
+	PPCDBG(PPCDBG_BUSWALK,"fixup_resources PciDev %p\n",PciDev);
+}   
+
+
+/********************************************************************************
+* Loop through each node function to find usable EADs bridges.  
+*********************************************************************************/
+void  iSeries_Scan_PHBs_Slots(struct pci_controller* Phb)
+{
+	struct HvCallPci_DeviceInfo* DevInfo;
+	HvBusNumber    Bus       = Phb->local_number;       /* System Bus        */	
+	HvSubBusNumber SubBus    = 0;                       /* EADs is always 0. */
+	int            HvRc      = 0;
+	int            IdSel     = 1;	
+	int            MaxAgents = 8;
+
+	DevInfo    = (struct HvCallPci_DeviceInfo*)kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
+	if(DevInfo == NULL) return;
+
+	/********************************************************************************
+	 * Probe for EADs Bridges      
+	 ********************************************************************************/
+	for (IdSel=1; IdSel < MaxAgents; ++IdSel) {
+    		HvRc = HvCallPci_getDeviceInfo(Bus, SubBus, IdSel,REALADDR(DevInfo), sizeof(struct HvCallPci_DeviceInfo));
+		if (HvRc == 0) {
+			if(DevInfo->deviceType == HvCallPci_NodeDevice) {
+				iSeries_Scan_EADs_Bridge(Bus, SubBus, IdSel);
+			}
+			else printk("PCI: Invalid System Configuration(0x%02X.\n",DevInfo->deviceType);
+		}
+		else pci_Log_Error("getDeviceInfo",Bus, SubBus, IdSel,HvRc);
+	}
+	kfree(DevInfo);
+}
+
+/********************************************************************************
+* 
+*********************************************************************************/
+void  iSeries_Scan_EADs_Bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel)
+{
+	struct HvCallPci_BridgeInfo* BridgeInfo;
+	HvAgentId      AgentId;
+	int            Function;
+	int            HvRc;
+
+	BridgeInfo = (struct HvCallPci_BridgeInfo*)kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
+	if(BridgeInfo == NULL) return;
+
+	/*********************************************************************
+	 * Note: hvSubBus and irq is always be 0 at this level!
+	 *********************************************************************/
+	for (Function=0; Function < 8; ++Function) {
+	  	AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
+		HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, 0);
+ 		if (HvRc == 0) {
+  			/*  Connect EADs: 0x18.00.12 = 0x00 */
+			PPCDBG(PPCDBG_BUSWALK,"PCI:Connect EADs: 0x%02X.%02X.%02X\n",Bus, SubBus, AgentId);
+			PCIFR(                    "Connect EADs: 0x%02X.%02X.%02X",  Bus, SubBus, AgentId);
+	    		HvRc = HvCallPci_getBusUnitInfo(Bus, SubBus, AgentId, 
+			                                REALADDR(BridgeInfo), sizeof(struct HvCallPci_BridgeInfo));
+	 		if (HvRc == 0) {
+				PPCDBG(PPCDBG_BUSWALK,"PCI: BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X\n",
+				       BridgeInfo->busUnitInfo.deviceType,
+				       BridgeInfo->subBusNumber,
+				       BridgeInfo->maxAgents,
+				       BridgeInfo->maxSubBusNumber,
+				       BridgeInfo->logicalSlotNumber);
+				PCIFR(                     "BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X",
+				       BridgeInfo->busUnitInfo.deviceType,
+				       BridgeInfo->subBusNumber,
+				       BridgeInfo->maxAgents,
+				       BridgeInfo->maxSubBusNumber,
+				       BridgeInfo->logicalSlotNumber);
+
+				if (BridgeInfo->busUnitInfo.deviceType == HvCallPci_BridgeDevice)  {
+					/* Scan_Bridge_Slot...: 0x18.00.12 */
+					iSeries_Scan_Bridge_Slot(Bus,BridgeInfo);
+				}
+				else printk("PCI: Invalid Bridge Configuration(0x%02X)",BridgeInfo->busUnitInfo.deviceType);
+			}
+    		}
+		else if(HvRc != 0x000B) pci_Log_Error("EADs Connect",Bus,SubBus,AgentId,HvRc);
+	}
+	kfree(BridgeInfo);
+}
+
+/********************************************************************************
+* 
+* This assumes that the node slot is always on the primary bus!
+*
+*********************************************************************************/
+int iSeries_Scan_Bridge_Slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo* BridgeInfo)
+{
+	struct iSeries_Device_Node* DeviceNode;
+	HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
+	u16       VendorId    = 0;
+	int       HvRc        = 0;
+	u8        Irq         = 0;
+	int       IdSel       = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
+	int       Function    = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
+	HvAgentId AgentId     = ISERIES_PCI_AGENTID(IdSel, Function);
+	HvAgentId EADsIdSel   = ISERIES_PCI_AGENTID(IdSel, Function);
+	int       FirstSlotId = 0; 	
+
+	/**********************************************************/
+	/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3)                */
+	/**********************************************************/
+  	Irq   = iSeries_allocate_IRQ(Bus, 0, AgentId);
+	iSeries_assign_IRQ(Irq, Bus, 0, AgentId);
+	PPCDBG(PPCDBG_BUSWALK,"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",Bus, 0, AgentId, Irq );
+
+	/****************************************************************************
+	 * Connect all functions of any device found.  
+	 ****************************************************************************/
+  	for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
+    		for (Function = 0; Function < 8; ++Function) {
+			AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
+			HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, Irq);
+			if( HvRc == 0) {
+				HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId, PCI_VENDOR_ID, &VendorId);
+				if( HvRc == 0) {
+					/**********************************************************/
+					/* FoundDevice: 0x18.28.10 = 0x12AE                       */
+					/**********************************************************/
+					PPCDBG(PPCDBG_BUSWALK,"PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X\n",
+					                                       Bus, SubBus, AgentId, VendorId);
+
+					HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId, PCI_INTERRUPT_LINE, Irq);  
+					if( HvRc != 0) {
+						pci_Log_Error("PciCfgStore Irq Failed!",Bus,SubBus,AgentId,HvRc);
+					}
+
+					++DeviceCount;
+					DeviceNode = build_device_node(Bus, SubBus, EADsIdSel, Function);
+					DeviceNode->Vendor      = VendorId;
+					DeviceNode->Irq         = Irq;
+					DeviceNode->LogicalSlot = BridgeInfo->logicalSlotNumber;
+					PCIFR("Device(%4d): 0x%02X.%02X.%02X 0x%02X 0x%04X",
+					      DeviceCount,Bus, SubBus, AgentId,
+					      DeviceNode->LogicalSlot,DeviceNode->Vendor);
+
+					/***********************************************************
+					 * On the first device/function, assign irq to slot
+					 ***********************************************************/
+					if(Function == 0) { 
+						FirstSlotId = AgentId;
+						// AHT iSeries_assign_IRQ(Irq, Bus, SubBus, AgentId);
+    					}
+				}
+				else pci_Log_Error("Read Vendor",Bus,SubBus,AgentId,HvRc);
+			}
+			else pci_Log_Error("Connect Bus Unit",Bus,SubBus, AgentId,HvRc);
+		} /* for (Function = 0; Function < 8; ++Function) */
+	} /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
+	return HvRc;
+}
+/************************************************************************/
+/* I/0 Memory copy MUST use mmio commands on iSeries                    */
+/* To do; For performance, include the hv call directly                 */
+/************************************************************************/
+void* iSeries_memset(void* dest, char c, size_t Count)
+{
+	u8    ByteValue     = c;
+	long  NumberOfBytes = Count;
+	char* IoBuffer      = dest;
+	while(NumberOfBytes > 0) {
+		iSeries_Write_Byte( ByteValue, (void*)IoBuffer );
+		++IoBuffer;
+		-- NumberOfBytes;
+	}
+	return dest;
+}	
+void* iSeries_memcpy_toio(void *dest, void *source, size_t count)
+{
+	char *dst           = dest;
+	char *src           = source;
+	long  NumberOfBytes = count;
+	while(NumberOfBytes > 0) {
+		iSeries_Write_Byte(*src++, (void*)dst++);
+		-- NumberOfBytes;
+	}
+	return dest;
+}
+void* iSeries_memcpy_fromio(void *dest, void *source, size_t count)
+{
+	char *dst = dest;
+	char *src = source;
+	long  NumberOfBytes = count;
+	while(NumberOfBytes > 0) {
+		*dst++ = iSeries_Read_Byte( (void*)src++);
+		-- NumberOfBytes;
+	}
+	return dest;
+}
+/**********************************************************************************
+ * Look down the chain to find the matching Device Device
+ **********************************************************************************/
+struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev)
+{
+	struct list_head* Device_Node_Ptr = iSeries_Global_Device_List.next;
+	int Bus   = PciDev->bus->number;
+	int DevFn = PciDev->devfn;
+	
+	while(Device_Node_Ptr != &iSeries_Global_Device_List) { 
+		struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)Device_Node_Ptr;
+		if(Bus == ISERIES_BUS(DevNode) && DevFn == DevNode->DevFn) {
+			return DevNode;
+		}
+		Device_Node_Ptr = Device_Node_Ptr->next;
+	}
+	return NULL;
+}
+/******************************************************************/
+/* Returns the device node for the passed pci_dev                 */
+/* Sanity Check Node PciDev to passed pci_dev                     */
+/* If none is found, returns a NULL which the client must handle. */
+/******************************************************************/
+struct iSeries_Device_Node* get_Device_Node(struct pci_dev* PciDev)
+{
+	struct iSeries_Device_Node* Node;
+	Node = (struct iSeries_Device_Node*)PciDev->sysdata;
+	if(Node == NULL ) {
+		Node = find_Device_Node(PciDev);
+	}
+	else if(Node->PciDev != PciDev) { 
+		Node = find_Device_Node(PciDev);
+	}
+	return Node;
+}
+/**********************************************************************************
+ *
+ * Read PCI Config Space Code 
+ *
+ **********************************************************************************/
+/** BYTE  *************************************************************************/
+int iSeries_Node_read_config_byte(struct iSeries_Device_Node* DevNode, int Offset, u8* ReadValue)
+{
+	u8  ReadData; 
+	if(DevNode == NULL) { return 0x301; } 
+	++Pci_Cfg_Read_Count;
+	DevNode->ReturnCode = HvCallPci_configLoad8(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
+	                                                Offset,&ReadData);
+	if(Pci_Trace_Flag == 1) {
+		PCIFR("RCB: 0x%04X.%02X 0x%04X = 0x%02X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);
+	}
+	if(DevNode->ReturnCode != 0 ) { 
+		printk("PCI: RCB: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+		PCIFR(      "RCB: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+	}
+	*ReadValue = ReadData; 
+ 	return DevNode->ReturnCode;
+}
+/** WORD  *************************************************************************/
+int iSeries_Node_read_config_word(struct iSeries_Device_Node* DevNode, int Offset, u16* ReadValue)
+{
+	u16  ReadData; 
+	if(DevNode == NULL) { return 0x301; } 
+	++Pci_Cfg_Read_Count;
+	DevNode->ReturnCode = HvCallPci_configLoad16(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
+	                                                Offset,&ReadData);
+	if(Pci_Trace_Flag == 1) {
+		PCIFR("RCW: 0x%04X.%02X 0x%04X = 0x%04X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);
+	}
+	if(DevNode->ReturnCode != 0 ) { 
+		printk("PCI: RCW: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+		PCIFR(      "RCW: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+
+	}
+	*ReadValue = ReadData; 
+ 	return DevNode->ReturnCode;
+}
+/** DWORD *************************************************************************/
+int iSeries_Node_read_config_dword(struct iSeries_Device_Node* DevNode, int Offset, u32* ReadValue)
+{
+ 	u32  ReadData; 
+	if(DevNode == NULL) { return 0x301; } 
+	++Pci_Cfg_Read_Count;
+	DevNode->ReturnCode = HvCallPci_configLoad32(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
+	                                                Offset,&ReadData);
+	if(Pci_Trace_Flag == 1) {
+		PCIFR("RCL: 0x%04X.%02X 0x%04X = 0x%08X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);
+	}
+	if(DevNode->ReturnCode != 0 ) { 
+		printk("PCI: RCL: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+		PCIFR(      "RCL: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+	}
+	*ReadValue = ReadData; 
+ 	return DevNode->ReturnCode;
+}
+int iSeries_pci_read_config_byte(struct pci_dev* PciDev, int Offset, u8* ReadValue) { 
+	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+	if(DevNode == NULL) return 0x0301;
+	return iSeries_Node_read_config_byte( DevNode ,Offset,ReadValue);
+}
+int iSeries_pci_read_config_word(struct pci_dev* PciDev, int Offset, u16* ReadValue) { 
+	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+	if(DevNode == NULL) return 0x0301;
+	return iSeries_Node_read_config_word( DevNode ,Offset,ReadValue );
+}
+int iSeries_pci_read_config_dword(struct pci_dev* PciDev, int Offset, u32* ReadValue) { 
+	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+	if(DevNode == NULL) return 0x0301;
+	return iSeries_Node_read_config_dword(DevNode ,Offset,ReadValue  );
+}
+/**********************************************************************************/
+/*                                                                                */
+/* Write PCI Config Space                                                         */
+/*                                                                                */
+/** BYTE  *************************************************************************/
+int iSeries_Node_write_config_byte(struct iSeries_Device_Node* DevNode, int Offset, u8 WriteData)
+{
+	++Pci_Cfg_Write_Count;
+	DevNode->ReturnCode = HvCallPci_configStore8(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
+	                                                  Offset,WriteData);
+	if(Pci_Trace_Flag == 1) {
+		PCIFR("WCB: 0x%04X.%02X 0x%04X = 0x%02X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);
+	}
+	if(DevNode->ReturnCode != 0 ) { 
+		printk("PCI: WCB: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+		PCIFR(      "WCB: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+	}
+ 	return DevNode->ReturnCode;
+}
+/** WORD  *************************************************************************/
+int iSeries_Node_write_config_word(struct iSeries_Device_Node* DevNode, int Offset, u16 WriteData)
+{
+	++Pci_Cfg_Write_Count;
+	DevNode->ReturnCode = HvCallPci_configStore16(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
+	                                                  Offset,WriteData);
+	if(Pci_Trace_Flag == 1) {
+		PCIFR("WCW: 0x%04X.%02X 0x%04X = 0x%04X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);
+	}
+	if(DevNode->ReturnCode != 0 ) { 
+		printk("PCI: WCW: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+		PCIFR(      "WCW: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+	}
+ 	return DevNode->ReturnCode;
+}
+/** DWORD *************************************************************************/
+int iSeries_Node_write_config_dword(struct iSeries_Device_Node* DevNode, int Offset, u32 WriteData)
+{
+	++Pci_Cfg_Write_Count;
+	DevNode->ReturnCode = HvCallPci_configStore32(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
+	                                                  Offset,WriteData);
+	if(Pci_Trace_Flag == 1) {
+		PCIFR("WCL: 0x%04X.%02X 0x%04X = 0x%08X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);
+	}
+	if(DevNode->ReturnCode != 0 ) { 
+		printk("PCI: WCL: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+		PCIFR(      "WCL: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
+	}
+	return DevNode->ReturnCode;
+}
+int iSeries_pci_write_config_byte( struct pci_dev* PciDev,int Offset, u8 WriteValue)
+{
+	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+	if(DevNode == NULL) return 0x0301;
+	return iSeries_Node_write_config_byte( DevNode,Offset,WriteValue);
+}
+int iSeries_pci_write_config_word( struct pci_dev* PciDev,int Offset,u16 WriteValue)
+{
+	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+	if(DevNode == NULL) return 0x0301;
+	return iSeries_Node_write_config_word( DevNode,Offset,WriteValue);
+}
+int iSeries_pci_write_config_dword(struct pci_dev* PciDev,int Offset,u32 WriteValue)
+{
+	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+	if(DevNode == NULL) return 0x0301;
+	return iSeries_Node_write_config_dword(DevNode,Offset,WriteValue);
+}
+
+/************************************************************************/
+/* Branch Table                                                         */
+/************************************************************************/
+struct pci_ops iSeries_pci_ops = {
+	iSeries_pci_read_config_byte,
+	iSeries_pci_read_config_word,
+	iSeries_pci_read_config_dword,
+	iSeries_pci_write_config_byte,
+	iSeries_pci_write_config_word,
+	iSeries_pci_write_config_dword 
+};
+
+/************************************************************************
+ * Check Return Code
+ * -> On Failure, print and log information.
+ *    Increment Retry Count, if exceeds max, panic partition.
+ * -> If in retry, print and log success 
+ ************************************************************************
+ * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
+ * PCI: Device 23.90 ReadL Retry( 1)
+ * PCI: Device 23.90 ReadL Retry Successful(1)
+ ************************************************************************/
+int  CheckReturnCode(char* TextHdr, struct iSeries_Device_Node* DevNode, u64 RtnCode)
+{
+	if(RtnCode != 0)  {
+		++Pci_Error_Count;
+		++DevNode->IoRetry;
+		PCIFR(      "%s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X",
+			    TextHdr,ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->IoRetry,(int)RtnCode);
+		printk("PCI: %s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X\n",
+		            TextHdr,ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->IoRetry,(int)RtnCode);
+		/*******************************************************/
+		/* Bump the retry and check for retry count exceeded.  */
+		/* If, Exceeded, panic the system.                     */           
+		/*******************************************************/
+		if(DevNode->IoRetry > Pci_Retry_Max && Pci_Error_Flag > 0 ) {
+			mf_displaySrc(0xB6000103);
+			panic_timeout = 0; 
+			panic("PCI: Hardware I/O Error, SRC B6000103, Automatic Reboot Disabled.\n");
+		}
+		return -1;	/* Retry Try */
+	}
+	/********************************************************************
+	* If retry was in progress, log success and rest retry count        *
+	*********************************************************************/
+	else if(DevNode->IoRetry > 0) {
+		PCIFR("%s: Device 0x%04X:%02X Retry Successful(%2d).",
+		      TextHdr,ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->IoRetry);
+		DevNode->IoRetry = 0;
+		return 0; 
+	}
+	return 0; 
+}
+/************************************************************************/
+/* Translate the I/O Address into a device node, bar, and bar offset.   */
+/* Note: Make sure the passed variable end up on the stack to avoid     */
+/* the exposure of being device global.                                 */
+/************************************************************************/
+static inline struct iSeries_Device_Node* xlateIoMmAddress(void* IoAddress,
+							    union HvDsaMap* DsaPtr,
+							   u64* BarOffsetPtr) {
+
+	unsigned long BaseIoAddr = (unsigned long)IoAddress-iSeries_Base_Io_Memory;
+	long          TableIndex = BaseIoAddr/iSeries_IoMmTable_Entry_Size;
+	struct iSeries_Device_Node* DevNode = *(iSeries_IoMmTable +TableIndex);
+	if(DevNode != NULL) {
+		DsaPtr->DsaAddr       = ISERIES_DSA(DevNode);
+		DsaPtr->Dsa.barNumber = *(iSeries_IoBarTable+TableIndex);
+		*BarOffsetPtr         = BaseIoAddr % iSeries_IoMmTable_Entry_Size;
+	}
+	else {
+		panic("PCI: Invalid PCI IoAddress detected!\n");
+	}
+	return DevNode;
+}
+
+/************************************************************************/
+/* Read MM I/O Instructions for the iSeries                             */
+/* On MM I/O error, all ones are returned and iSeries_pci_IoError is cal*/
+/* else, data is returned in big Endian format.                         */
+/************************************************************************/
+/* iSeries_Read_Byte = Read Byte  ( 8 bit)                              */
+/* iSeries_Read_Word = Read Word  (16 bit)                              */
+/* iSeries_Read_Long = Read Long  (32 bit)                              */
+/************************************************************************/
+u8  iSeries_Read_Byte(void* IoAddress)
+{
+	u64    BarOffset;
+	union  HvDsaMap DsaData;
+	struct HvCallPci_LoadReturn Return;
+	struct iSeries_Device_Node* DevNode = xlateIoMmAddress(IoAddress,&DsaData,&BarOffset);
+
+	do {
+		++Pci_Io_Read_Count;
+		HvCall3Ret16(HvCallPciBarLoad8, &Return, DsaData.DsaAddr,BarOffset, 0);
+	} while (CheckReturnCode("RDB",DevNode, Return.rc) != 0);
+
+	if(Pci_Trace_Flag == 1)	PCIFR("RDB: IoAddress 0x%p = 0x%02X",IoAddress, (u8)Return.value); 
+	return (u8)Return.value;
+}
+u16  iSeries_Read_Word(void* IoAddress)
+{
+	u64    BarOffset;
+	union  HvDsaMap DsaData;
+	struct HvCallPci_LoadReturn Return;
+	struct iSeries_Device_Node* DevNode = xlateIoMmAddress(IoAddress,&DsaData,&BarOffset);
+
+	do {
+		++Pci_Io_Read_Count;
+		HvCall3Ret16(HvCallPciBarLoad16,&Return, DsaData.DsaAddr,BarOffset, 0);
+	} while (CheckReturnCode("RDW",DevNode, Return.rc) != 0);
+
+	if(Pci_Trace_Flag == 1) PCIFR("RDW: IoAddress 0x%p = 0x%04X",IoAddress, swab16((u16)Return.value));
+	return swab16((u16)Return.value);
+}
+u32  iSeries_Read_Long(void* IoAddress)
+{
+	u64    BarOffset;
+	union  HvDsaMap DsaData;
+	struct HvCallPci_LoadReturn Return;
+	struct iSeries_Device_Node* DevNode = xlateIoMmAddress(IoAddress,&DsaData,&BarOffset);
+
+	do {
+		++Pci_Io_Read_Count;
+		HvCall3Ret16(HvCallPciBarLoad32,&Return, DsaData.DsaAddr,BarOffset, 0);
+	} while (CheckReturnCode("RDL",DevNode, Return.rc) != 0);
+
+	if(Pci_Trace_Flag == 1) PCIFR("RDL: IoAddress 0x%p = 0x%04X",IoAddress, swab32((u32)Return.value));
+	return swab32((u32)Return.value);
+}
+/************************************************************************/
+/* Write MM I/O Instructions for the iSeries                            */
+/************************************************************************/
+/* iSeries_Write_Byte = Write Byte (8 bit)                              */
+/* iSeries_Write_Word = Write Word(16 bit)                              */
+/* iSeries_Write_Long = Write Long(32 bit)                              */
+/************************************************************************/
+void iSeries_Write_Byte(u8 Data, void* IoAddress)
+{
+	u64    BarOffset;
+	union  HvDsaMap DsaData;
+	struct HvCallPci_LoadReturn Return;
+	struct iSeries_Device_Node* DevNode = xlateIoMmAddress(IoAddress,&DsaData,&BarOffset);
+
+	do {
+		++Pci_Io_Write_Count;
+		Return.rc = HvCall4(HvCallPciBarStore8, DsaData.DsaAddr,BarOffset, Data, 0);
+	} while (CheckReturnCode("WWB",DevNode, Return.rc) != 0);
+	if(Pci_Trace_Flag == 1) PCIFR("WWB: IoAddress 0x%p = 0x%02X",IoAddress,Data);
+}
+void iSeries_Write_Word(u16 Data, void* IoAddress)
+{
+	u64    BarOffset;
+	union  HvDsaMap DsaData;
+	struct HvCallPci_LoadReturn Return;
+	struct iSeries_Device_Node* DevNode = xlateIoMmAddress(IoAddress,&DsaData,&BarOffset);
+
+	do {
+		++Pci_Io_Write_Count;
+		Return.rc = HvCall4(HvCallPciBarStore16,DsaData.DsaAddr,BarOffset, swab16(Data), 0);
+	} while (CheckReturnCode("WWW",DevNode, Return.rc) != 0);
+	if(Pci_Trace_Flag == 1) PCIFR("WWW: IoAddress 0x%p = 0x%04X",IoAddress,Data);
+}
+void iSeries_Write_Long(u32 Data, void* IoAddress)
+{
+	u64    BarOffset;
+	union  HvDsaMap DsaData;
+	struct HvCallPci_LoadReturn Return;
+	struct iSeries_Device_Node* DevNode = xlateIoMmAddress(IoAddress,&DsaData,&BarOffset);
+
+	do {
+		++Pci_Io_Write_Count;
+		Return.rc = HvCall4(HvCallPciBarStore32,DsaData.DsaAddr,BarOffset, swab32(Data), 0);
+	} while (CheckReturnCode("WWL",DevNode, Return.rc) != 0);
+	if(Pci_Trace_Flag == 1) PCIFR("WWL: IoAddress 0x%p = 0x%08X",IoAddress, Data);
+}
+/*
+ * This is called very early before the page table is setup.
+ * There are warnings here because of type mismatches.. Okay for now. AHT
+ */
+void 
+iSeries_pcibios_init_early(void)
+{
+	//ppc_md.pcibios_read_config_byte   = iSeries_Node_read_config_byte;
+	//ppc_md.pcibios_read_config_word   = iSeries_Node_read_config_word;
+	//ppc_md.pcibios_read_config_dword  = iSeries_Node_read_config_dword;
+	//ppc_md.pcibios_write_config_byte  = iSeries_Node_write_config_byte;
+	//ppc_md.pcibios_write_config_word  = iSeries_Node_write_config_word;
+	//ppc_md.pcibios_write_config_dword = iSeries_Node_write_config_dword;
+}
+
+/************************************************************************/
+/* Set the slot reset line to the state passed in.                      */
+/* This is the platform specific for code for the pci_reset_device      */
+/* function.                                                            */
+/************************************************************************/
+int pci_set_reset(struct pci_dev* PciDev, int State) {
+	struct iSeries_Device_Node* DeviceNode = (struct iSeries_Device_Node*)PciDev->sysdata;
+ 	if (DeviceNode == NULL) { 
+		printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n",PciDev);
+		return -1;
+	}
+	DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),0x00,DeviceNode->AgentId,State);
+	return DeviceNode->ReturnCode;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_pci_reset.c linux/arch/ppc64/kernel/iSeries_pci_reset.c
--- linux.orig/arch/ppc64/kernel/iSeries_pci_reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_pci_reset.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,88 @@
+/************************************************************************/
+/* File iSeries_pci_reset.c created by Allan Trautman on Mar 21 2001.   */
+/************************************************************************/
+/* This code supports the pci interface on the IBM iSeries systems.     */
+/* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
+/*                                                                      */
+/* 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created, March 20, 2001                                            */
+/*   April 30, 2001, Added return codes on functions.                   */
+/*   September 10, 2001, Ported to ppc64.                               */
+/* End Change Activity                                                  */
+/************************************************************************/
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/init.h>
+#include <asm/iSeries/HvCallPci.h>
+#include <asm/iSeries/HvTypes.h>
+#include <asm/iSeries/mf.h>
+#include <asm/flight_recorder.h>
+#include <asm/pci.h>
+
+#include <asm/iSeries/iSeries_pci.h>
+#include "pci.h"
+
+/************************************************************************/
+/* Interface to toggle the reset line                                   */
+/* Time is in .1 seconds, need for seconds.                             */
+/************************************************************************/
+int  iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime)
+{
+	unsigned long AssertDelay, WaitDelay;
+	struct iSeries_Device_Node* DeviceNode = (struct iSeries_Device_Node*)PciDev->sysdata;
+ 	if (DeviceNode == NULL) { 
+		printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n",PciDev);
+		return -1;
+	}
+	/********************************************************************
+	 * Set defaults, Assert is .5 second, Wait is 3 seconds.
+	 ********************************************************************/
+	if (AssertTime == 0) AssertDelay = ( 5 * HZ)/10;
+	else                 AssertDelay = (AssertTime*HZ)/10;
+	if (WaitDelay == 0)  WaitDelay   = (30 * HZ)/10;
+	else                 WaitDelay   = (DelayTime* HZ)/10;
+
+	/********************************************************************
+	 * Assert reset
+	 ********************************************************************/
+	DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),0x00,DeviceNode->AgentId,1);
+	if (DeviceNode->ReturnCode == 0) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(AssertDelay);       /* Sleep for the time     */
+		DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),0x00,DeviceNode->AgentId, 0);
+
+		/***************************************************************
+   		 * Wait for device to reset
+		 ***************************************************************/
+		set_current_state(TASK_UNINTERRUPTIBLE);  
+		schedule_timeout(WaitDelay);
+	}
+	if (DeviceNode->ReturnCode == 0) {
+		PCIFR("Slot 0x%04X.%02 Reset\n",ISERIES_BUS(DeviceNode),DeviceNode->AgentId );
+	} 
+	else {
+		printk("PCI: Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",ISERIES_BUS(DeviceNode),DeviceNode->AgentId,DeviceNode->ReturnCode);
+		PCIFR(      "Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",ISERIES_BUS(DeviceNode),DeviceNode->AgentId,DeviceNode->ReturnCode);
+	}
+	return DeviceNode->ReturnCode;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_proc.c linux/arch/ppc64/kernel/iSeries_proc.c
--- linux.orig/arch/ppc64/kernel/iSeries_proc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_proc.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,142 @@
+/*
+  * iSeries_proc.c
+  * Copyright (C) 2001  Kyle A. Lucke IBM 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
+  */
+
+
+/* Change Activity: */
+/* End Change Activity */
+
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#ifndef _ISERIES_PROC_H
+#include <asm/iSeries/iSeries_proc.h>
+#endif
+
+
+static struct proc_dir_entry * iSeries_proc_root = NULL;
+static int iSeries_proc_initializationDone = 0;
+static spinlock_t iSeries_proc_lock;
+
+struct iSeries_proc_registration
+{
+	struct iSeries_proc_registration *next;
+	iSeriesProcFunction functionMember;
+};
+
+
+struct iSeries_proc_registration preallocated[16];
+#define MYQUEUETYPE(T) struct MYQueue##T
+#define MYQUEUE(T) \
+MYQUEUETYPE(T) \
+{ \
+	struct T *head; \
+	struct T *tail; \
+}
+#define MYQUEUECTOR(q) do { (q)->head = NULL; (q)->tail = NULL; } while(0)
+#define MYQUEUEENQ(q, p) \
+do { \
+	(p)->next = NULL; \
+	if ((q)->head != NULL) { \
+		(q)->head->next = (p); \
+		(q)->head = (p); \
+	} else { \
+		(q)->tail = (q)->head = (p); \
+	} \
+} while(0)
+
+#define MYQUEUEDEQ(q,p) \
+do { \
+	(p) = (q)->tail; \
+	if ((p) != NULL) { \
+		(q)->tail = (p)->next; \
+		(p)->next = NULL; \
+	} \
+	if ((q)->tail == NULL) \
+		(q)->head = NULL; \
+} while(0)
+MYQUEUE(iSeries_proc_registration);
+typedef MYQUEUETYPE(iSeries_proc_registration) aQueue;
+
+
+aQueue iSeries_free;
+aQueue iSeries_queued;
+
+void iSeries_proc_early_init(void)
+{
+	int i = 0;
+	unsigned long flags;
+	iSeries_proc_initializationDone = 0;
+	spin_lock_init(&iSeries_proc_lock);
+	MYQUEUECTOR(&iSeries_free);
+	MYQUEUECTOR(&iSeries_queued);
+
+	spin_lock_irqsave(&iSeries_proc_lock, flags);
+	for (i = 0; i < 16; ++i) {
+		MYQUEUEENQ(&iSeries_free, preallocated+i);
+	}
+	spin_unlock_irqrestore(&iSeries_proc_lock, flags);
+}
+
+void iSeries_proc_create(void)
+{
+	unsigned long flags;
+	struct iSeries_proc_registration *reg = NULL;
+	spin_lock_irqsave(&iSeries_proc_lock, flags);
+	printk("iSeries_proc: Creating /proc/iSeries\n");
+
+	iSeries_proc_root = proc_mkdir("iSeries", 0);
+	if (!iSeries_proc_root) return;
+
+	MYQUEUEDEQ(&iSeries_queued, reg);
+
+	while (reg != NULL) {
+		(*(reg->functionMember))(iSeries_proc_root);
+
+		MYQUEUEDEQ(&iSeries_queued, reg);
+	}
+
+	iSeries_proc_initializationDone = 1;
+	spin_unlock_irqrestore(&iSeries_proc_lock, flags);
+}
+
+void iSeries_proc_callback(iSeriesProcFunction initFunction)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&iSeries_proc_lock, flags);
+
+	if (iSeries_proc_initializationDone) {
+		(*initFunction)(iSeries_proc_root);
+	} else {
+		struct iSeries_proc_registration *reg = NULL;
+
+		MYQUEUEDEQ(&iSeries_free, reg);
+
+		if (reg != NULL) {
+			/* printk("Registering %p in reg %p\n", initFunction, reg); */
+			reg->functionMember = initFunction;
+
+			MYQUEUEENQ(&iSeries_queued, reg);
+		} else {
+			printk("Couldn't get a queue entry\n");
+		}
+	}
+
+	spin_unlock_irqrestore(&iSeries_proc_lock, flags);
+}
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_setup.c linux/arch/ppc64/kernel/iSeries_setup.c
--- linux.orig/arch/ppc64/kernel/iSeries_setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_setup.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,900 @@
+/*
+ * 
+ *
+ *    Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
+ *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: iSeries_setup.c
+ *
+ *    Description:
+ *      Architecture- / platform-specific boot-time initialization code for
+ *      the IBM iSeries LPAR.  Adapted from original code by Grant Erickson and
+ *      code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
+ *      <dan@net4x.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.
+ */
+ 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+#include <linux/seq_file.h>
+
+#include <asm/processor.h>
+#include <asm/machdep.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+
+#include <asm/time.h>
+#include "iSeries_setup.h"
+#include <asm/naca.h>
+#include <asm/paca.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/HvCallHpt.h>
+#include <asm/iSeries/HvLpConfig.h>
+#include <asm/iSeries/HvCallEvent.h>
+#include <asm/iSeries/HvCallSm.h>
+#include <asm/iSeries/HvCallXm.h>
+#include <asm/iSeries/ItLpQueue.h>
+#include <asm/iSeries/IoHriMainStore.h>
+#include <asm/iSeries/iSeries_proc.h>
+#include <asm/proc_pmc.h>
+#include <asm/iSeries/mf.h>
+
+/* Function Prototypes */
+
+extern void abort(void);
+#ifdef CONFIG_PPC_ISERIES
+static void build_iSeries_Memory_Map( void );
+static void setup_iSeries_cache_sizes( void );
+static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr);
+#endif
+void build_valid_hpte( unsigned long vsid, unsigned long ea, unsigned long pa,
+		       pte_t * ptep, unsigned hpteflags, unsigned bolted );
+extern void ppcdbg_initialize(void);
+extern void iSeries_pcibios_init(void);
+extern void iSeries_pcibios_fixup(void);
+extern void iSeries_pcibios_fixup_bus(int);
+static void iSeries_setup_dprofile(void);
+
+/* Global Variables */
+
+static unsigned long procFreqHz = 0;
+static unsigned long procFreqMhz = 0;
+static unsigned long procFreqMhzHundreths = 0;
+
+static unsigned long tbFreqHz = 0;
+static unsigned long tbFreqMhz = 0;
+static unsigned long tbFreqMhzHundreths = 0;
+
+unsigned long dprof_shift = 0;
+unsigned long dprof_len = 0;
+unsigned int * dprof_buffer = NULL;
+
+int piranha_simulator = 0;
+
+extern char _end[];
+
+extern int rd_size;		/* Defined in drivers/block/rd.c */
+extern unsigned long klimit;
+extern unsigned long embedded_sysmap_start;
+extern unsigned long embedded_sysmap_end;
+
+extern unsigned long iSeries_recal_tb;
+extern unsigned long iSeries_recal_titan;
+
+extern char _stext;
+extern char _etext;
+
+static int mf_initialized = 0;
+
+struct MemoryBlock {
+	unsigned long absStart;
+	unsigned long absEnd;
+	unsigned long logicalStart;
+	unsigned long logicalEnd;
+};
+
+/*
+ * Process the main store vpd to determine where the holes in memory are
+ * and return the number of physical blocks and fill in the array of
+ * block data.
+ */
+
+unsigned long iSeries_process_Condor_mainstore_vpd( struct MemoryBlock *mb_array, unsigned long max_entries )
+{
+	/* Determine if absolute memory has any
+	 * holes so that we can interpret the
+	 * access map we get back from the hypervisor
+	 * correctly.
+	 */
+	
+	unsigned long holeFirstChunk, holeSizeChunks;
+	unsigned long numMemoryBlocks = 1;
+	struct IoHriMainStoreSegment4 * msVpd = (struct IoHriMainStoreSegment4 *)xMsVpd;
+	unsigned long holeStart = msVpd->nonInterleavedBlocksStartAdr;
+	unsigned long holeEnd   = msVpd->nonInterleavedBlocksEndAdr;
+	unsigned long holeSize = holeEnd - holeStart;
+
+	printk("Mainstore_VPD: Condor\n");
+
+	mb_array[0].logicalStart = 0;
+	mb_array[0].logicalEnd   = 0x100000000;
+	mb_array[0].absStart     = 0;
+	mb_array[0].absEnd       = 0x100000000;
+
+	if ( holeSize ) {
+		numMemoryBlocks = 2;
+		holeStart = holeStart & 0x000fffffffffffff;
+		holeStart = addr_to_chunk(holeStart);
+		holeFirstChunk = holeStart;
+		holeSize = addr_to_chunk(holeSize);
+		holeSizeChunks = holeSize;
+		printk( "Main store hole: start chunk = %0lx, size = %0lx chunks\n",
+				holeFirstChunk, holeSizeChunks );
+		mb_array[0].logicalEnd   = holeFirstChunk;
+		mb_array[0].absEnd       = holeFirstChunk;
+		mb_array[1].logicalStart = holeFirstChunk;
+		mb_array[1].logicalEnd   = 0x100000000 - holeSizeChunks;
+		mb_array[1].absStart     = holeFirstChunk + holeSizeChunks;
+		mb_array[1].absEnd       = 0x100000000;
+	}
+
+	
+	return numMemoryBlocks;
+}
+
+#define MaxSegmentAreas 32
+#define MaxSegmentAdrRangeBlocks 128
+#define MaxAreaRangeBlocks 4
+unsigned long iSeries_process_Regatta_mainstore_vpd( struct MemoryBlock *mb_array, unsigned long max_entries )
+{
+	struct IoHriMainStoreSegment5 * msVpdP = (struct IoHriMainStoreSegment5 *)xMsVpd;
+	unsigned long numSegmentBlocks = 0;
+	u32 existsBits = msVpdP->msAreaExists;
+	unsigned long area_num;
+
+	printk("Mainstore_VPD: Regatta\n");
+
+	for ( area_num = 0; area_num < MaxSegmentAreas; ++area_num ) {
+		unsigned long numAreaBlocks;
+		struct IoHriMainStoreArea4 * currentArea;
+
+		if ( existsBits & 0x80000000 ) {
+			unsigned long block_num;
+
+			currentArea = &msVpdP->msAreaArray[area_num];
+			numAreaBlocks = currentArea->numAdrRangeBlocks;
+
+			printk("ms_vpd: processing area %2ld  blocks=%ld", area_num, numAreaBlocks);
+
+			for ( block_num = 0; block_num < numAreaBlocks; ++block_num ) {
+				/* Process an address range block */
+				struct MemoryBlock tempBlock;
+				unsigned long i;
+
+				tempBlock.absStart = (unsigned long)currentArea->xAdrRangeBlock[block_num].blockStart;
+				tempBlock.absEnd   = (unsigned long)currentArea->xAdrRangeBlock[block_num].blockEnd;
+				tempBlock.logicalStart = 0;
+				tempBlock.logicalEnd   = 0;
+
+				printk("\n          block %ld absStart=%016lx absEnd=%016lx", block_num,
+							tempBlock.absStart, tempBlock.absEnd);
+
+				for ( i=0; i<numSegmentBlocks; ++i ) {
+					if ( mb_array[i].absStart == tempBlock.absStart )
+						break;
+				}
+				if ( i == numSegmentBlocks ) {
+					if ( numSegmentBlocks == max_entries ) {
+						panic("iSeries_process_mainstore_vpd: too many memory blocks");
+					}
+					mb_array[numSegmentBlocks] = tempBlock;
+					++numSegmentBlocks;
+				}
+				else {
+					printk(" (duplicate)");
+				}
+			}
+			printk("\n");
+		}
+		existsBits <<= 1;
+	}
+	/* Now sort the blocks found into ascending sequence */
+	if ( numSegmentBlocks > 1 ) {
+		unsigned long m, n;
+		for ( m=0; m<numSegmentBlocks-1; ++m ) {
+			for ( n=numSegmentBlocks-1; m<n; --n ) {
+				if ( mb_array[n].absStart < mb_array[n-1].absStart ) {
+					struct MemoryBlock tempBlock;
+					tempBlock = mb_array[n];
+					mb_array[n] = mb_array[n-1];
+					mb_array[n-1] = tempBlock;
+				}
+				
+			}
+		}
+	}
+	/* Assign "logical" addresses to each block.  These
+	 * addresses correspond to the hypervisor "bitmap" space.
+	 * Convert all addresses into units of 256K chunks.
+	 */
+	{
+	unsigned long i, nextBitmapAddress;
+	printk("ms_vpd: %ld sorted memory blocks\n", numSegmentBlocks);
+	nextBitmapAddress = 0;
+	for ( i=0; i<numSegmentBlocks; ++i ) {
+		unsigned long length = mb_array[i].absEnd - mb_array[i].absStart;
+		mb_array[i].logicalStart = nextBitmapAddress;
+		mb_array[i].logicalEnd = nextBitmapAddress + length;
+		nextBitmapAddress += length;
+		printk("          Bitmap range: %016lx - %016lx\n"
+		       "        Absolute range: %016lx - %016lx\n",
+				mb_array[i].logicalStart, mb_array[i].logicalEnd, 
+				mb_array[i].absStart, mb_array[i].absEnd);
+		mb_array[i].absStart     = addr_to_chunk( mb_array[i].absStart & 0x000fffffffffffff );
+		mb_array[i].absEnd       = addr_to_chunk( mb_array[i].absEnd & 0x000fffffffffffff );
+		mb_array[i].logicalStart = addr_to_chunk( mb_array[i].logicalStart );
+		mb_array[i].logicalEnd   = addr_to_chunk( mb_array[i].logicalEnd );
+	}
+	}
+
+	return numSegmentBlocks;
+
+}
+
+unsigned long iSeries_process_mainstore_vpd( struct MemoryBlock *mb_array, unsigned long max_entries )
+{
+	unsigned long i;
+	unsigned long mem_blocks = 0;
+	if ( __is_processor( PV_POWER4 ) )
+		mem_blocks = iSeries_process_Regatta_mainstore_vpd( mb_array, max_entries );
+	else
+		mem_blocks = iSeries_process_Condor_mainstore_vpd( mb_array, max_entries );
+
+	printk("Mainstore_VPD: numMemoryBlocks = %ld \n", mem_blocks);
+	for ( i=0; i<mem_blocks; ++i ) {
+		printk("Mainstore_VPD: block %3ld logical chunks %016lx - %016lx\n"
+		       "                             abs chunks %016lx - %016lx\n",
+			i, mb_array[i].logicalStart, mb_array[i].logicalEnd,
+			mb_array[i].absStart, mb_array[i].absEnd);
+	}
+
+	return mem_blocks;
+}
+
+/*
+ * void __init iSeries_init_early()
+ */
+
+
+
+void __init
+iSeries_init_early(void)
+{
+#ifdef CONFIG_PPC_ISERIES
+	ppcdbg_initialize();
+	
+#if defined(CONFIG_BLK_DEV_INITRD)
+	/*
+	 * If the init RAM disk has been configured and there is
+	 * a non-zero starting address for it, set it up
+	 */
+
+	if ( naca->xRamDisk ) {
+		initrd_start = (unsigned long)__va(naca->xRamDisk);
+		initrd_end   = initrd_start + naca->xRamDiskSize * PAGE_SIZE;
+		initrd_below_start_ok = 1;	// ramdisk in kernel space
+		ROOT_DEV = MKDEV( RAMDISK_MAJOR, 0 );
+
+		if ( ((rd_size*1024)/PAGE_SIZE) < naca->xRamDiskSize )
+			rd_size = (naca->xRamDiskSize*PAGE_SIZE)/1024;
+	} else
+	
+#endif /* CONFIG_BLK_DEV_INITRD */
+	  {
+                
+	    /*		ROOT_DEV = MKDEV( VIODASD_MAJOR, 1 ); */
+	  }
+
+	iSeries_recal_tb = get_tb();
+	iSeries_recal_titan = HvCallXm_loadTod();
+
+	ppc_md.setup_arch	 	= iSeries_setup_arch;
+	ppc_md.setup_residual	 	= iSeries_setup_residual;
+	ppc_md.get_cpuinfo	 	= iSeries_get_cpuinfo;
+	ppc_md.irq_cannonicalize 	= NULL;
+	ppc_md.init_IRQ		 	= iSeries_init_IRQ;
+	ppc_md.init_ras_IRQ		= NULL;
+	ppc_md.get_irq		 	= iSeries_get_irq;
+	ppc_md.init		 	= NULL;
+
+ 	ppc_md.pcibios_fixup        = iSeries_pcibios_fixup;
+	ppc_md.pcibios_fixup_bus    = iSeries_pcibios_fixup_bus;
+
+	ppc_md.restart		 	= iSeries_restart;
+	ppc_md.power_off	 	= iSeries_power_off;
+	ppc_md.halt		 	= iSeries_halt;
+
+	ppc_md.time_init	 	= NULL;
+	ppc_md.get_boot_time    = iSeries_get_boot_time;
+	ppc_md.set_rtc_time	 	= iSeries_set_rtc_time;
+	ppc_md.get_rtc_time	 	= iSeries_get_rtc_time;
+	ppc_md.calibrate_decr	 	= iSeries_calibrate_decr;
+	ppc_md.progress			= iSeries_progress;
+
+	ppc_md.kbd_setkeycode    	= NULL;
+	ppc_md.kbd_getkeycode    	= NULL;
+	ppc_md.kbd_translate     	= NULL;
+	ppc_md.kbd_unexpected_up 	= NULL;
+	ppc_md.kbd_leds          	= NULL;
+	ppc_md.kbd_init_hw       	= NULL;
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+	ppc_md.ppc_kbd_sysrq_xlate	= NULL;
+#endif
+	
+	hpte_init_iSeries();
+	tce_init_iSeries();
+
+	/* Initialize the table which translate Linux physical addresses to
+	 * AS/400 absolute addresses
+	 */
+
+	build_iSeries_Memory_Map();
+
+	setup_iSeries_cache_sizes();
+
+	/* Initialize machine-dependency vectors */
+
+
+#ifdef CONFIG_SMP
+	smp_init_iSeries();
+#endif
+
+	if ( itLpNaca.xPirEnvironMode == 0 ) 
+		piranha_simulator = 1;
+#endif
+}
+
+/*
+ * void __init iSeries_init()
+ */
+
+void __init
+iSeries_init(unsigned long r3, unsigned long r4, unsigned long r5, 
+	   unsigned long r6, unsigned long r7)
+{
+	/* Associate Lp Event Queue 0 with processor 0 */
+	HvCallEvent_setLpEventQueueInterruptProc( 0, 0 );
+
+	{
+		/* copy the command line parameter from the primary VSP  */
+		char *p, *q;
+		HvCallEvent_dmaToSp( cmd_line,
+				     2*64*1024,
+				     256,
+				     HvLpDma_Direction_RemoteToLocal );
+
+		p = q = cmd_line + 255;
+		while( p > cmd_line ) {
+			if ((*p == 0) || (*p == ' ') || (*p == '\n'))
+				--p;
+			else
+				break;
+		}
+		if ( p < q )
+			*(p+1) = 0;
+	}
+
+        if (strstr(cmd_line, "dprofile=")) {
+                char *p, *q;
+
+                for (q = cmd_line; (p = strstr(q, "dprofile=")) != 0; ) {
+			unsigned long size, new_klimit;
+                        q = p + 9;
+                        if (p > cmd_line && p[-1] != ' ')
+                                continue;
+                        dprof_shift = simple_strtoul(q, &q, 0);
+			dprof_len = (unsigned long)&_etext - (unsigned long)&_stext;
+			dprof_len >>= dprof_shift;
+			size = ((dprof_len * sizeof(unsigned int)) + (PAGE_SIZE-1)) & PAGE_MASK;
+			dprof_buffer = (unsigned int *)((klimit + (PAGE_SIZE-1)) & PAGE_MASK);
+			new_klimit = ((unsigned long)dprof_buffer) + size;
+			lmb_reserve( __pa(klimit), (new_klimit-klimit));
+			klimit = new_klimit;
+			memset( dprof_buffer, 0, size );
+                }
+        }
+
+	iSeries_setup_dprofile();
+
+	iSeries_proc_early_init();	
+	mf_init();
+	mf_initialized = 1;
+	mb();
+
+	iSeries_proc_callback( &pmc_proc_init );
+}
+
+#ifdef CONFIG_PPC_ISERIES
+/*
+ * The iSeries may have very large memories ( > 128 GB ) and a partition
+ * may get memory in "chunks" that may be anywhere in the 2**52 real
+ * address space.  The chunks are 256K in size.  To map this to the 
+ * memory model Linux expects, the AS/400 specific code builds a 
+ * translation table to translate what Linux thinks are "physical"
+ * addresses to the actual real addresses.  This allows us to make 
+ * it appear to Linux that we have contiguous memory starting at
+ * physical address zero while in fact this could be far from the truth.
+ * To avoid confusion, I'll let the words physical and/or real address 
+ * apply to the Linux addresses while I'll use "absolute address" to 
+ * refer to the actual hardware real address.
+ *
+ * build_iSeries_Memory_Map gets information from the Hypervisor and 
+ * looks at the Main Store VPD to determine the absolute addresses
+ * of the memory that has been assigned to our partition and builds
+ * a table used to translate Linux's physical addresses to these
+ * absolute addresses.  Absolute addresses are needed when 
+ * communicating with the hypervisor (e.g. to build HPT entries)
+ */
+
+static void __init build_iSeries_Memory_Map(void)
+{
+	u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;
+	u32 nextPhysChunk;
+	u32 hptFirstChunk, hptLastChunk, hptSizeChunks, hptSizePages;
+	u32 num_ptegs;
+	u32 totalChunks,moreChunks;
+	u32 currChunk, thisChunk, absChunk;
+	u32 currDword;
+	u32 chunkBit;
+	u64 map;
+	struct MemoryBlock mb[32];
+	unsigned long numMemoryBlocks, curBlock;
+
+	/* Chunk size on iSeries is 256K bytes */
+	totalChunks = (u32)HvLpConfig_getMsChunks();
+	klimit = msChunks_alloc(klimit, totalChunks, 1UL<<18);
+
+	/* Get absolute address of our load area
+	 * and map it to physical address 0
+	 * This guarantees that the loadarea ends up at physical 0
+	 * otherwise, it might not be returned by PLIC as the first
+	 * chunks
+	 */
+	
+	loadAreaFirstChunk = (u32)addr_to_chunk(itLpNaca.xLoadAreaAddr);
+	loadAreaSize =  itLpNaca.xLoadAreaChunks;
+
+	/* Only add the pages already mapped here.  
+	 * Otherwise we might add the hpt pages 
+	 * The rest of the pages of the load area
+	 * aren't in the HPT yet and can still
+	 * be assigned an arbitrary physical address
+	 */
+	if ( (loadAreaSize * 64) > HvPagesToMap )
+		loadAreaSize = HvPagesToMap / 64;
+
+	loadAreaLastChunk = loadAreaFirstChunk + loadAreaSize - 1;
+
+	/* TODO Do we need to do something if the HPT is in the 64MB load area?
+	 * This would be required if the itLpNaca.xLoadAreaChunks includes 
+	 * the HPT size
+	 */
+
+	printk( "Mapping load area - physical addr = 0000000000000000\n"
+                "                    absolute addr = %016lx\n", 
+			chunk_to_addr(loadAreaFirstChunk) );
+	printk( "Load area size %dK\n", loadAreaSize*256 );
+	
+	for (	nextPhysChunk = 0; 
+		nextPhysChunk < loadAreaSize; 
+		++nextPhysChunk ) {
+		msChunks.abs[nextPhysChunk] = loadAreaFirstChunk+nextPhysChunk;
+	}
+	
+	/* Get absolute address of our HPT and remember it so
+	 * we won't map it to any physical address
+	 */
+
+	hptFirstChunk = (u32)addr_to_chunk(HvCallHpt_getHptAddress());
+	hptSizePages =  (u32)(HvCallHpt_getHptPages());
+	hptSizeChunks = hptSizePages >> (msChunks.chunk_shift-PAGE_SHIFT);
+	hptLastChunk = hptFirstChunk + hptSizeChunks - 1;
+	
+	printk( "HPT absolute addr = %016lx, size = %dK\n",
+			chunk_to_addr(hptFirstChunk), hptSizeChunks*256 );
+
+	/* Fill in the htab_data structure */
+	
+	/* Fill in size of hashed page table */
+	num_ptegs = hptSizePages * (PAGE_SIZE/(sizeof(HPTE)*HPTES_PER_GROUP));
+	htab_data.htab_num_ptegs = num_ptegs;
+	htab_data.htab_hash_mask = num_ptegs - 1;
+	
+	/* The actual hashed page table is in the hypervisor, we have no direct access */
+	htab_data.htab = NULL;
+
+	/* Determine if absolute memory has any
+	 * holes so that we can interpret the
+	 * access map we get back from the hypervisor
+	 * correctly.
+	 */
+	numMemoryBlocks = iSeries_process_mainstore_vpd( mb, 32 );
+
+	/* Process the main store access map from the hypervisor
+	 * to build up our physical -> absolute translation table
+	 */
+	curBlock = 0;
+	currChunk = 0;
+	currDword = 0;
+	moreChunks = totalChunks;
+
+	while ( moreChunks ) {
+		map = HvCallSm_get64BitsOfAccessMap( itLpNaca.xLpIndex,
+						     currDword );
+		thisChunk = currChunk;
+		while ( map ) {
+			chunkBit = map >> 63;
+			map <<= 1;
+			if ( chunkBit ) {
+				--moreChunks;
+
+				while ( thisChunk >= mb[curBlock].logicalEnd ) {
+					++curBlock;
+					if ( curBlock >= numMemoryBlocks )
+						panic("out of memory blocks");
+				}
+				if ( thisChunk < mb[curBlock].logicalStart )
+					panic("memory block error");
+
+				absChunk = mb[curBlock].absStart + ( thisChunk - mb[curBlock].logicalStart );
+
+				if ( ( ( absChunk < hptFirstChunk ) ||
+				       ( absChunk > hptLastChunk ) ) &&
+				     ( ( absChunk < loadAreaFirstChunk ) ||
+				       ( absChunk > loadAreaLastChunk ) ) ) {
+					msChunks.abs[nextPhysChunk] = absChunk;
+					++nextPhysChunk;
+				}
+			}
+			++thisChunk;
+		}
+		++currDword;
+		currChunk += 64;
+	}
+					
+	/* main store size (in chunks) is 
+	 *   totalChunks - hptSizeChunks
+	 * which should be equal to 
+	 *   nextPhysChunk
+	 */
+	naca->physicalMemorySize = chunk_to_addr(nextPhysChunk);
+
+	/* Bolt kernel mappings for all of memory */
+	iSeries_bolt_kernel( 0, naca->physicalMemorySize );
+
+	lmb_init();
+	lmb_add( 0, naca->physicalMemorySize );
+	lmb_analyze();	/* ?? */
+	lmb_reserve( 0, __pa(klimit));
+
+	/* 
+	 * Hardcode to GP size.  I am not sure where to get this info. DRENG
+	 */
+	naca->slb_size = 64;
+}
+
+/*
+ * Set up the variables that describe the cache line sizes
+ * for this machine.
+ */
+
+static void __init setup_iSeries_cache_sizes(void)
+{
+	unsigned i,n;
+	unsigned procIx = get_paca()->xLpPaca.xDynHvPhysicalProcIndex;
+
+	naca->iCacheL1LineSize = xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
+	naca->dCacheL1LineSize = xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
+	naca->iCacheL1LinesPerPage = PAGE_SIZE / naca->iCacheL1LineSize;
+	naca->dCacheL1LinesPerPage = PAGE_SIZE / naca->dCacheL1LineSize;
+	i = naca->iCacheL1LineSize;
+	n = 0;
+	while ((i=(i/2))) ++n;
+	naca->iCacheL1LogLineSize = n;
+	i = naca->dCacheL1LineSize;
+	n = 0;
+	while ((i=(i/2))) ++n;
+	naca->dCacheL1LogLineSize = n;
+
+	printk( "D-cache line size = %d  (log = %d)\n",
+			(unsigned)naca->dCacheL1LineSize,
+			(unsigned)naca->dCacheL1LogLineSize );
+	printk( "I-cache line size = %d  (log = %d)\n",
+			(unsigned)naca->iCacheL1LineSize,
+			(unsigned)naca->iCacheL1LogLineSize );
+	
+}
+
+/*
+ * Bolt the kernel addr space into the HPT
+ */
+
+static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
+{
+	unsigned long pa;
+	unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
+	HPTE hpte;
+
+	for (pa=saddr; pa < eaddr ;pa+=PAGE_SIZE) {
+		unsigned long ea = (unsigned long)__va(pa);
+		unsigned long vsid = get_kernel_vsid( ea );
+		unsigned long va = ( vsid << 28 ) | ( pa & 0xfffffff );
+		unsigned long vpn = va >> PAGE_SHIFT;
+		unsigned long slot = HvCallHpt_findValid( &hpte, vpn );
+		if ( hpte.dw0.dw0.v ) {
+			/* HPTE exists, so just bolt it */
+			HvCallHpt_setSwBits( slot, 0x10, 0 );
+		} else {
+			/* No HPTE exists, so create a new bolted one */
+			build_valid_hpte(vsid, ea, pa, NULL, mode_rw, 1);
+		}
+	}
+}
+#endif /* CONFIG_PPC_ISERIES */
+
+extern unsigned long ppc_proc_freq;
+extern unsigned long ppc_tb_freq;
+
+/*
+ * Document me.
+ */
+void __init
+iSeries_setup_arch(void)
+{
+	void *	eventStack;
+	unsigned procIx = get_paca()->xLpPaca.xDynHvPhysicalProcIndex;
+
+	/* Setup the Lp Event Queue */
+
+	/* Allocate a page for the Event Stack
+	 * The hypervisor wants the absolute real address, so
+	 * we subtract out the KERNELBASE and add in the
+	 * absolute real address of the kernel load area
+	 */
+	
+	eventStack = alloc_bootmem_pages( LpEventStackSize );
+	
+	memset( eventStack, 0, LpEventStackSize );
+	
+	/* Invoke the hypervisor to initialize the event stack */
+	
+	HvCallEvent_setLpEventStack( 0, eventStack, LpEventStackSize );
+	
+	/* Initialize fields in our Lp Event Queue */
+	
+	xItLpQueue.xSlicEventStackPtr = (char *)eventStack;
+	xItLpQueue.xSlicCurEventPtr = (char *)eventStack;
+	xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + 
+					(LpEventStackSize - LpEventMaxSize);
+	xItLpQueue.xIndex = 0;
+	
+	/* Compute processor frequency */
+	procFreqHz = (((1UL<<34) * 1000000) / xIoHriProcessorVpd[procIx].xProcFreq );
+	procFreqMhz = procFreqHz / 1000000;
+	procFreqMhzHundreths = (procFreqHz/10000) - (procFreqMhz*100);
+
+	ppc_proc_freq = procFreqHz;
+
+	/* Compute time base frequency */
+	tbFreqHz = (((1UL<<32) * 1000000) / xIoHriProcessorVpd[procIx].xTimeBaseFreq );
+	tbFreqMhz = tbFreqHz / 1000000;
+	tbFreqMhzHundreths = (tbFreqHz/10000) - (tbFreqMhz*100);
+
+	ppc_tb_freq = tbFreqHz;
+
+	printk("Max  logical processors = %d\n", 
+			itVpdAreas.xSlicMaxLogicalProcs );
+	printk("Max physical processors = %d\n",
+			itVpdAreas.xSlicMaxPhysicalProcs );
+	printk("Processor frequency = %lu.%02lu\n",
+			procFreqMhz, 
+			procFreqMhzHundreths );
+	printk("Time base frequency = %lu.%02lu\n",
+			tbFreqMhz,
+			tbFreqMhzHundreths );
+	printk("Processor version = %x\n",
+			xIoHriProcessorVpd[procIx].xPVR );
+
+}
+
+/*
+ * int as400_setup_residual()
+ *
+ * Description:
+ *   This routine pretty-prints CPU information gathered from the VPD    
+ *   for use in /proc/cpuinfo                               
+ *
+ * Input(s):
+ *  *buffer - Buffer into which CPU data is to be printed.             
+ *
+ * Output(s):
+ *  *buffer - Buffer with CPU data.
+ *
+ * Returns:
+ *   The number of bytes copied into 'buffer' if OK, otherwise zero or less
+ *   on error.
+ */
+void iSeries_setup_residual(struct seq_file *m)
+{
+	
+	seq_printf(m,"clock\t\t: %lu.%02luMhz\n",
+		procFreqMhz, procFreqMhzHundreths );
+	seq_printf(m,"time base\t: %lu.%02luMHz\n",
+		tbFreqMhz, tbFreqMhzHundreths );
+	seq_printf(m,"i-cache\t\t: %d\n",
+		naca->iCacheL1LineSize);
+	seq_printf(m,"d-cache\t\t: %d\n",
+		naca->dCacheL1LineSize);
+
+}
+
+void iSeries_get_cpuinfo(struct seq_file *m)
+{
+
+	seq_printf(m,"machine\t\t: 64-bit iSeries Logical Partition\n");
+
+}
+
+/*
+ * Document me.
+ * and Implement me.
+ */
+int
+iSeries_get_irq(struct pt_regs *regs)
+{
+	/* -2 means ignore this interrupt */
+	return -2;
+}
+
+/*
+ * Document me.
+ */
+void
+iSeries_restart(char *cmd)
+{
+	mf_reboot();
+}
+
+/*
+ * Document me.
+ */
+void
+iSeries_power_off(void)
+{
+	mf_powerOff();
+}
+
+/*
+ * Document me.
+ */
+void
+iSeries_halt(void)
+{
+	mf_powerOff();
+}
+
+/*
+ * Nothing to do here.
+ */
+void __init
+iSeries_time_init(void)
+{
+	/* Nothing to do */
+}
+
+/* JDH Hack */
+unsigned long jdh_time = 0;
+
+extern void setup_default_decr(void);
+
+/*
+ * void __init iSeries_calibrate_decr()
+ *
+ * Description:
+ *   This routine retrieves the internal processor frequency from the VPD,
+ *   and sets up the kernel timer decrementer based on that value.
+ *
+ */
+void __init
+iSeries_calibrate_decr(void)
+{
+	unsigned long	cyclesPerUsec;
+
+	struct div_result divres;
+	
+	/* Compute decrementer (and TB) frequency 
+	 * in cycles/sec 
+	 */
+
+	cyclesPerUsec = ppc_tb_freq / 1000000;	/* cycles / usec */
+
+	/* Set the amount to refresh the decrementer by.  This
+	 * is the number of decrementer ticks it takes for 
+	 * 1/HZ seconds.
+	 */
+
+	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
+
+#if 0
+	/* TEST CODE FOR ADJTIME */
+	tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000;
+	/* END OF TEST CODE */
+#endif
+
+	/*
+	 * tb_ticks_per_sec = freq; would give better accuracy
+	 * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures
+	 * that jiffies (and xtime) will match the time returned
+	 * by do_gettimeofday.
+	 */
+	tb_ticks_per_sec   = tb_ticks_per_jiffy * HZ;
+	tb_ticks_per_usec = cyclesPerUsec;
+	tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
+	div128_by_32( 1024*1024, 0, tb_ticks_per_sec, &divres );
+	tb_to_xs = divres.result_low;
+	setup_default_decr();
+}
+
+void __init
+iSeries_progress( char * st, unsigned short code )
+{
+	printk( "Progress: [%04x] - %s\n", (unsigned)code, st );
+	if ( !piranha_simulator && mf_initialized ) {
+	    if (code != 0xffff)
+		mf_displayProgress( code );
+	    else
+		mf_clearSrc();
+	}
+}
+
+
+void iSeries_fixup_klimit(void)
+{
+	/* Change klimit to take into account any ram disk that may be included */
+	if (naca->xRamDisk)
+		klimit = KERNELBASE + (u64)naca->xRamDisk + (naca->xRamDiskSize * PAGE_SIZE);
+	else {
+		/* No ram disk was included - check and see if there was an embedded system map */
+		/* Change klimit to take into account any embedded system map */
+		if (embedded_sysmap_end)
+			klimit = KERNELBASE + ((embedded_sysmap_end+4095) & 0xfffffffffffff000);
+	}
+}
+
+static void iSeries_setup_dprofile(void)
+{
+	if ( dprof_buffer ) {
+		unsigned i;
+		for (i=0; i<MAX_PACAS; ++i) {
+			paca[i].prof_shift = dprof_shift;
+			paca[i].prof_len = dprof_len-1;
+			paca[i].prof_buffer = dprof_buffer;
+			paca[i].prof_stext = (unsigned *)&_stext;
+			mb();
+			paca[i].prof_enabled = 1;
+		}
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/iSeries_setup.h linux/arch/ppc64/kernel/iSeries_setup.h
--- linux.orig/arch/ppc64/kernel/iSeries_setup.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/iSeries_setup.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,43 @@
+/*
+ *    Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
+ *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: as400_setup.h
+ *
+ *    Description:
+ *      Architecture- / platform-specific boot-time initialization code for
+ *      the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and
+ *      code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek
+ *      <dan@netx4.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.
+ */
+
+#ifndef	__ISERIES_SETUP_H__
+#define	__ISERIES_SETUP_H__
+
+extern void		 iSeries_init_early(void);
+extern void		 iSeries_init(unsigned long r3,
+			            unsigned long ird_start,
+				    unsigned long ird_end,
+				    unsigned long cline_start,
+				    unsigned long cline_end);
+extern void		 iSeries_setup_arch(void);
+extern void		 iSeries_setup_residual(struct seq_file *m);
+extern void		 iSeries_get_cpuinfo(struct seq_file *m);
+extern void		 iSeries_init_IRQ(void);
+extern int		 iSeries_get_irq(struct pt_regs *regs);
+extern void		 iSeries_restart(char *cmd);
+extern void		 iSeries_power_off(void);
+extern void		 iSeries_halt(void);
+extern void		 iSeries_time_init(void);
+extern void      iSeries_get_boot_time(struct rtc_time *tm);
+extern int		 iSeries_set_rtc_time(unsigned long now);
+extern unsigned long	 iSeries_get_rtc_time(void);
+extern void		 iSeries_calibrate_decr(void);
+extern void 	 iSeries_progress( char *, unsigned short );
+
+#endif /* __ISERIES_SETUP_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/idle.c linux/arch/ppc64/kernel/idle.c
--- linux.orig/arch/ppc64/kernel/idle.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/idle.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,134 @@
+/*
+ * Idle daemon for PowerPC.  Idle daemon will handle any action
+ * that needs to be taken when the system becomes idle.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/cache.h>
+
+#include <asm/time.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/HvCall.h>
+#include <asm/iSeries/ItLpQueue.h>
+
+unsigned long maxYieldTime = 0;
+unsigned long minYieldTime = 0xffffffffffffffffUL;
+
+#ifdef CONFIG_PPC_ISERIES
+static void yield_shared_processor(void)
+{
+	struct paca_struct *lpaca = get_paca();
+	unsigned long tb;
+	unsigned long yieldTime;
+
+	HvCall_setEnabledInterrupts( HvCall_MaskIPI |
+				     HvCall_MaskLpEvent |
+				     HvCall_MaskLpProd |
+				     HvCall_MaskTimeout );
+
+	tb = get_tb();
+	/* Compute future tb value when yield should expire */
+	HvCall_yieldProcessor( HvCall_YieldTimed, tb+tb_ticks_per_jiffy );
+
+	yieldTime = get_tb() - tb;
+	if ( yieldTime > maxYieldTime )
+		maxYieldTime = yieldTime;
+
+	if ( yieldTime < minYieldTime )
+		minYieldTime = yieldTime;
+	
+	/* The decrementer stops during the yield.  Force a fake decrementer
+	 * here and let the timer_interrupt code sort out the actual time.
+	 */
+	lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 1;
+	process_iSeries_events();
+}
+#endif /* CONFIG_PPC_ISERIES */
+
+int idled(void)
+{
+	struct paca_struct *lpaca;
+	long oldval;
+#ifdef CONFIG_PPC_ISERIES
+	unsigned long CTRL;
+#endif
+
+	/* endless loop with no priority at all */
+	current->nice = 20;
+	current->counter = -100;
+#ifdef CONFIG_PPC_ISERIES
+	/* ensure iSeries run light will be out when idle */
+	current->thread.flags &= ~PPC_FLAG_RUN_LIGHT;
+	CTRL = mfspr(CTRLF);
+	CTRL &= ~RUNLATCH;
+	mtspr(CTRLT, CTRL);
+#endif
+	init_idle();	
+
+	lpaca = get_paca();
+
+	for (;;) {
+#ifdef CONFIG_PPC_ISERIES
+		if ( lpaca->xLpPaca.xSharedProc ) {
+			if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) )
+				process_iSeries_events();
+			if ( !current->need_resched )
+				yield_shared_processor();
+		}
+		else 
+#endif
+		{
+			/* Avoid an IPI by setting need_resched */
+			oldval = xchg(&current->need_resched, -1);
+			if (!oldval) {
+				while(current->need_resched == -1) {
+#ifdef CONFIG_PPC_ISERIES
+					HMT_medium();
+					if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) )
+						process_iSeries_events();
+#endif
+					HMT_low();
+				}
+			}
+		}
+		HMT_medium();
+		if (current->need_resched) {
+			schedule();
+			check_pgt_cache();
+		}
+	}
+	return 0;
+}
+
+/*
+ * SMP entry into the idle task - calls the same thing as the
+ * non-smp versions. -- Cort
+ */
+int cpu_idle(void)
+{
+	idled();
+	return 0; 
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ioctl32.c linux/arch/ppc64/kernel/ioctl32.c
--- linux.orig/arch/ppc64/kernel/ioctl32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ioctl32.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,4486 @@
+/* 
+ * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
+ * 
+ * Based on sparc64 ioctl32.c by:
+ *
+ * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * ppc64 changes:
+ *
+ * Copyright (C) 2000  Ken Aaker (kdaaker@rchland.vnet.ibm.com)
+ * Copyright (C) 2001  Anton Blanchard (antonb@au.ibm.com)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+ * ioctls.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/ioctl.h>
+#include <linux/if.h>
+#include <linux/slab.h>
+#include <linux/hdreg.h>
+#include <linux/raid/md.h>
+#include <linux/kd.h>
+#include <linux/route.h>
+#include <linux/in6.h>
+#include <linux/ipv6_route.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/vt.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/fd.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/if_pppox.h>
+#include <linux/mtio.h>
+#include <linux/cdrom.h>
+#include <linux/loop.h>
+#include <linux/auto_fs.h>
+#include <linux/devfs_fs.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h>
+#include <linux/fb.h>
+#include <linux/ext2_fs.h>
+#include <linux/videodev.h>
+#include <linux/netdevice.h>
+#include <linux/raw.h>
+#include <linux/smb_fs.h>
+#include <linux/blkpg.h>
+#include <linux/blk.h>
+#include <linux/elevator.h>
+#include <linux/rtc.h>
+#include <linux/pci.h>
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+#include <linux/lvm.h>
+#endif /* LVM */
+
+#include <scsi/scsi.h>
+/* Ugly hack. */
+#undef __KERNEL__
+#include <scsi/scsi_ioctl.h>
+#define __KERNEL__
+#include <scsi/sg.h>
+
+#include <asm/types.h>
+#include <asm/uaccess.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/if_bonding.h>
+#include <asm/module.h>
+#include <linux/soundcard.h>
+#include <linux/watchdog.h>
+#include <linux/lp.h>
+
+#include <linux/atm.h>
+#include <linux/atmarp.h>
+#include <linux/atmclip.h>
+#include <linux/atmdev.h>
+#include <linux/atmioc.h>
+#include <linux/atmlec.h>
+#include <linux/atmmpc.h>
+#include <linux/atmsvc.h>
+#include <linux/atm_tcp.h>
+#include <linux/sonet.h>
+#include <linux/atm_suni.h>
+#include <linux/mtd/mtd.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci.h>
+
+#include <linux/usb.h>
+#include <linux/usbdevice_fs.h>
+#include <linux/nbd.h>
+#include <asm/ppc32.h>
+#include <asm/ppcdebug.h>
+
+/* Aiee. Someone does not find a difference between int and long */
+#define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
+#define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
+#define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
+#define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)
+
+extern asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+
+static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	int err;
+	unsigned long val;
+	
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	set_fs (old_fs);
+	if (!err && put_user(val, (u32 *)arg))
+		return -EFAULT;
+	return err;
+}
+ 
+static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	int err;
+	unsigned long val;
+	
+	if (get_user(val, (u32 *)arg))
+		return -EFAULT;
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	set_fs (old_fs);
+	if (!err && put_user(val, (u32 *)arg))
+		return -EFAULT;
+	return err;
+}
+
+static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	/* These are just misnamed, they actually get/put from/to user an int */
+	switch (cmd) {
+	case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
+	case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
+	case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
+	case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
+	}
+	return sys_ioctl(fd, cmd, arg);
+}
+ 
+struct video_tuner32 {
+	s32 tuner;
+	u8 name[32];
+	u32 rangelow, rangehigh;
+	u32 flags;
+	u16 mode, signal;
+};
+
+static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
+{
+	int i;
+
+	if (get_user(kp->tuner, &up->tuner))
+		return -EFAULT;
+	for(i = 0; i < 32; i++)
+		__get_user(kp->name[i], &up->name[i]);
+	__get_user(kp->rangelow, &up->rangelow);
+	__get_user(kp->rangehigh, &up->rangehigh);
+	__get_user(kp->flags, &up->flags);
+	__get_user(kp->mode, &up->mode);
+	__get_user(kp->signal, &up->signal);
+	return 0;
+}
+
+static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
+{
+	int i;
+
+	if (put_user(kp->tuner, &up->tuner))
+		return -EFAULT;
+	for(i = 0; i < 32; i++)
+		__put_user(kp->name[i], &up->name[i]);
+	__put_user(kp->rangelow, &up->rangelow);
+	__put_user(kp->rangehigh, &up->rangehigh);
+	__put_user(kp->flags, &up->flags);
+	__put_user(kp->mode, &up->mode);
+	__put_user(kp->signal, &up->signal);
+	return 0;
+}
+
+struct video_buffer32 {
+	/* void * */ u32 base;
+	s32 height, width, depth, bytesperline;
+};
+
+static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
+{
+	u32 tmp;
+
+	if (get_user(tmp, &up->base))
+		return -EFAULT;
+	kp->base = (void *) ((unsigned long)tmp);
+	__get_user(kp->height, &up->height);
+	__get_user(kp->width, &up->width);
+	__get_user(kp->depth, &up->depth);
+	__get_user(kp->bytesperline, &up->bytesperline);
+	return 0;
+}
+
+static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
+{
+	u32 tmp = (u32)((unsigned long)kp->base);
+
+	if (put_user(tmp, &up->base))
+		return -EFAULT;
+	__put_user(kp->height, &up->height);
+	__put_user(kp->width, &up->width);
+	__put_user(kp->depth, &up->depth);
+	__put_user(kp->bytesperline, &up->bytesperline);
+	return 0;
+}
+
+struct video_clip32 {
+	s32 x, y, width, height;
+	/* struct video_clip32 * */ u32 next;
+};
+
+struct video_window32 {
+	u32 x, y, width, height, chromakey, flags;
+	/* struct video_clip32 * */ u32 clips;
+	s32 clipcount;
+};
+
+static void free_kvideo_clips(struct video_window *kp)
+{
+	struct video_clip *cp;
+
+	cp = kp->clips;
+	if (cp != NULL)
+		kfree(cp);
+}
+
+static int get_video_window32(struct video_window *kp, struct video_window32 *up)
+{
+	struct video_clip32 *ucp;
+	struct video_clip *kcp;
+	int nclips, err, i;
+	u32 tmp;
+
+	if (get_user(kp->x, &up->x))
+		return -EFAULT;
+	__get_user(kp->y, &up->y);
+	__get_user(kp->width, &up->width);
+	__get_user(kp->height, &up->height);
+	__get_user(kp->chromakey, &up->chromakey);
+	__get_user(kp->flags, &up->flags);
+	__get_user(kp->clipcount, &up->clipcount);
+	__get_user(tmp, &up->clips);
+	ucp = (struct video_clip32 *)A(tmp);
+	kp->clips = NULL;
+
+	nclips = kp->clipcount;
+	if (nclips == 0)
+		return 0;
+
+	if (ucp == 0)
+		return -EINVAL;
+
+	/* Peculiar interface... */
+	if (nclips < 0)
+		nclips = VIDEO_CLIPMAP_SIZE;
+
+	kcp = kmalloc(nclips * sizeof(struct video_clip), GFP_KERNEL);
+	err = -ENOMEM;
+	if (kcp == NULL)
+		goto cleanup_and_err;
+
+	kp->clips = kcp;
+	for(i = 0; i < nclips; i++) {
+		__get_user(kcp[i].x, &ucp[i].x);
+		__get_user(kcp[i].y, &ucp[i].y);
+		__get_user(kcp[i].width, &ucp[i].width);
+		__get_user(kcp[i].height, &ucp[i].height);
+		kcp[nclips].next = NULL;
+	}
+
+	return 0;
+
+cleanup_and_err:
+	free_kvideo_clips(kp);
+	return err;
+}
+
+/* You get back everything except the clips... */
+static int put_video_window32(struct video_window *kp, struct video_window32 *up)
+{
+	if (put_user(kp->x, &up->x))
+		return -EFAULT;
+	__put_user(kp->y, &up->y);
+	__put_user(kp->width, &up->width);
+	__put_user(kp->height, &up->height);
+	__put_user(kp->chromakey, &up->chromakey);
+	__put_user(kp->flags, &up->flags);
+	__put_user(kp->clipcount, &up->clipcount);
+	return 0;
+}
+
+#define VIDIOCGTUNER32		_IOWR('v',4, struct video_tuner32)
+#define VIDIOCSTUNER32		_IOW('v',5, struct video_tuner32)
+#define VIDIOCGWIN32		_IOR('v',9, struct video_window32)
+#define VIDIOCSWIN32		_IOW('v',10, struct video_window32)
+#define VIDIOCGFBUF32		_IOR('v',11, struct video_buffer32)
+#define VIDIOCSFBUF32		_IOW('v',12, struct video_buffer32)
+#define VIDIOCGFREQ32		_IOR('v',14, u32)
+#define VIDIOCSFREQ32		_IOW('v',15, u32)
+
+static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	union {
+		struct video_tuner vt;
+		struct video_buffer vb;
+		struct video_window vw;
+		unsigned long vx;
+	} karg;
+	mm_segment_t old_fs = get_fs();
+	void *up = (void *)arg;
+	int err = 0;
+
+	/* First, convert the command. */
+	switch(cmd) {
+	case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
+	case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
+	case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
+	case VIDIOCSWIN32: cmd = VIDIOCSWIN; break;
+	case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
+	case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
+	case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
+	case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
+	};
+
+	switch(cmd) {
+	case VIDIOCSTUNER:
+	case VIDIOCGTUNER:
+		err = get_video_tuner32(&karg.vt, up);
+		break;
+
+	case VIDIOCSWIN:
+		err = get_video_window32(&karg.vw, up);
+		break;
+
+	case VIDIOCSFBUF:
+		err = get_video_buffer32(&karg.vb, up);
+		break;
+
+	case VIDIOCSFREQ:
+		err = get_user(karg.vx, (u32 *)up);
+		break;
+	};
+	if (err)
+		goto out;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&karg);
+	set_fs(old_fs);
+
+	if (cmd == VIDIOCSWIN)
+		free_kvideo_clips(&karg.vw);
+
+	if (err == 0) {
+		switch(cmd) {
+		case VIDIOCGTUNER:
+			err = put_video_tuner32(&karg.vt, up);
+			break;
+
+		case VIDIOCGWIN:
+			err = put_video_window32(&karg.vw, up);
+			break;
+
+		case VIDIOCGFBUF:
+			err = put_video_buffer32(&karg.vb, up);
+			break;
+
+		case VIDIOCGFREQ:
+			err = put_user(((u32)karg.vx), (u32 *)up);
+			break;
+		};
+	}
+out:
+	return err;
+}
+
+struct timeval32 {
+	int tv_sec;
+	int tv_usec;
+};
+
+static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct timeval32 *up = (struct timeval32 *)arg;
+	struct timeval ktv;
+	mm_segment_t old_fs = get_fs();
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
+	set_fs(old_fs);
+	if (!err) {
+		err = put_user(ktv.tv_sec, &up->tv_sec);
+		err |= __put_user(ktv.tv_usec, &up->tv_usec);
+	}
+	return err;
+}
+
+struct ifmap32 {
+	u32 mem_start;
+	u32 mem_end;
+	unsigned short base_addr;
+	unsigned char irq;
+	unsigned char dma;
+	unsigned char port;
+};
+
+struct ifreq32 {
+#define IFHWADDRLEN     6
+#define IFNAMSIZ        16
+        union {
+                char    ifrn_name[IFNAMSIZ];            /* if name, e.g. "en0" */
+        } ifr_ifrn;
+        union {
+                struct  sockaddr ifru_addr;
+                struct  sockaddr ifru_dstaddr;
+                struct  sockaddr ifru_broadaddr;
+                struct  sockaddr ifru_netmask;
+                struct  sockaddr ifru_hwaddr;
+                short   ifru_flags;
+                int     ifru_ivalue;
+                int     ifru_mtu;
+                struct  ifmap32 ifru_map;
+                char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
+		char	ifru_newname[IFNAMSIZ];
+                __kernel_caddr_t32 ifru_data;
+        } ifr_ifru;
+};
+
+struct ifconf32 {
+        int     ifc_len;                        /* size of buffer       */
+        __kernel_caddr_t32  ifcbuf;
+};
+
+#ifdef CONFIG_NET
+static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct net_device *dev;
+	struct ifreq32 ifr32;
+	int err;
+
+	if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+		return -EFAULT;
+
+	dev = dev_get_by_index(ifr32.ifr_ifindex);
+	if (!dev)
+		return -ENODEV;
+
+	strcpy(ifr32.ifr_name, dev->name);
+
+	err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
+	return (err ? -EFAULT : 0);
+}
+#endif
+
+static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifconf32 ifc32;
+	struct ifconf ifc;
+	struct ifreq32 *ifr32;
+	struct ifreq *ifr;
+	mm_segment_t old_fs;
+	unsigned int i, j;
+	int err;
+
+	if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32)))
+		return -EFAULT;
+
+	if (ifc32.ifcbuf == 0) {
+		ifc32.ifc_len = 0;
+		ifc.ifc_len = 0;
+		ifc.ifc_buf = NULL;
+	} else {
+		ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
+			sizeof (struct ifreq);
+		ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
+		if (!ifc.ifc_buf)
+			return -ENOMEM;
+	}
+	ifr = ifc.ifc_req;
+	ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
+	for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
+		if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
+			kfree (ifc.ifc_buf);
+			return -EFAULT;
+		}
+	}
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);	
+	set_fs (old_fs);
+	if (!err) {
+		ifr = ifc.ifc_req;
+		ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
+		for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
+		     i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
+			if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
+				err = -EFAULT;
+				break;
+			}
+		}
+		if (!err) {
+			if (ifc32.ifcbuf == 0) {
+				/* Translate from 64-bit structure multiple to
+				 * a 32-bit one.
+				 */
+				i = ifc.ifc_len;
+				i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
+				ifc32.ifc_len = i;
+			} else {
+				if (i <= ifc32.ifc_len)
+					ifc32.ifc_len = i;
+				else
+					ifc32.ifc_len = i - sizeof (struct ifreq32);
+			}
+			if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))
+				err = -EFAULT;
+		}
+	}
+	if (ifc.ifc_buf != NULL)
+		kfree (ifc.ifc_buf);
+	return err;
+}
+
+static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifreq ifr;
+	mm_segment_t old_fs;
+	int err, len;
+	u32 data, ethcmd;
+	
+	if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+		return -EFAULT;
+	ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
+	if (!ifr.ifr_data)
+		return -EAGAIN;
+
+	__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+
+	if (get_user(ethcmd, (u32 *)A(data))) {
+		err = -EFAULT;
+		goto out;
+	}
+	switch (ethcmd) {
+	case ETHTOOL_GDRVINFO:	len = sizeof(struct ethtool_drvinfo); break;
+	case ETHTOOL_GMSGLVL:
+	case ETHTOOL_SMSGLVL:
+	case ETHTOOL_GLINK:
+	case ETHTOOL_NWAY_RST:	len = sizeof(struct ethtool_value); break;
+	case ETHTOOL_GREGS: {
+		struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);
+		/* darned variable size arguments */
+		if (get_user(len, (u32 *)&regaddr->len)) {
+			err = -EFAULT;
+			goto out;
+		}
+		len += sizeof(struct ethtool_regs);
+		break;
+	}
+	case ETHTOOL_GSET:
+	case ETHTOOL_SSET:	len = sizeof(struct ethtool_cmd); break;
+	default:
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
+		err = -EFAULT;
+		goto out;
+	}
+
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
+	set_fs (old_fs);
+	if (!err) {
+		u32 data;
+
+		__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+		len = copy_to_user((char *)A(data), ifr.ifr_data, len);
+		if (len)
+			err = -EFAULT;
+	}
+
+out:
+	free_page((unsigned long)ifr.ifr_data);
+	return err;
+}
+
+static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifreq ifr;
+	mm_segment_t old_fs;
+	int err, len;
+	u32 data;
+	
+	if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+		return -EFAULT;
+	ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
+	if (!ifr.ifr_data)
+		return -EAGAIN;
+
+	switch (cmd) {
+	case SIOCBONDENSLAVE:
+	case SIOCBONDRELEASE:
+	case SIOCBONDSETHWADDR:
+	case SIOCBONDCHANGEACTIVE:
+		len = IFNAMSIZ * sizeof(char);
+		break;
+	case SIOCBONDSLAVEINFOQUERY:
+		len = sizeof(struct ifslave);
+		break;
+	case SIOCBONDINFOQUERY:
+		len = sizeof(struct ifbond);
+		break;
+	default:
+		err = -EINVAL;
+		goto out;
+	};
+
+	__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+	if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
+		err = -EFAULT;
+		goto out;
+	}
+
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
+	set_fs (old_fs);
+	if (!err) {
+		len = copy_to_user((char *)A(data), ifr.ifr_data, len);
+		if (len)
+			err = -EFAULT;
+	}
+
+out:
+	free_page((unsigned long)ifr.ifr_data);
+	return err;
+}
+
+static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifreq ifr;
+	mm_segment_t old_fs;
+	int err;
+	
+	switch (cmd) {
+	case SIOCSIFMAP:
+		err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
+		err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
+		err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
+		err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
+		err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
+		err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
+		err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
+		if (err)
+			return -EFAULT;
+		break;
+	default:
+		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+			return -EFAULT;
+		break;
+	}
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
+	set_fs (old_fs);
+	if (!err) {
+		switch (cmd) {
+		case SIOCGIFFLAGS:
+		case SIOCGIFMETRIC:
+		case SIOCGIFMTU:
+		case SIOCGIFMEM:
+		case SIOCGIFHWADDR:
+		case SIOCGIFINDEX:
+		case SIOCGIFADDR:
+		case SIOCGIFBRDADDR:
+		case SIOCGIFDSTADDR:
+		case SIOCGIFNETMASK:
+		case SIOCGIFTXQLEN:
+			if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
+				return -EFAULT;
+			break;
+		case SIOCGIFMAP:
+			err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
+			err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
+			err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
+			err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
+			err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
+			err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
+			err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
+			if (err)
+				err = -EFAULT;
+			break;
+		}
+	}
+	return err;
+}
+
+struct rtentry32 {
+        u32   		rt_pad1;
+        struct sockaddr rt_dst;         /* target address               */
+        struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
+        struct sockaddr rt_genmask;     /* target network mask (IP)     */
+        unsigned short  rt_flags;
+        short           rt_pad2;
+        u32   		rt_pad3;
+        unsigned char   rt_tos;
+        unsigned char   rt_class;
+        short           rt_pad4;
+        short           rt_metric;      /* +1 for binary compatibility! */
+        /* char * */ u32 rt_dev;        /* forcing the device at add    */
+        u32   		rt_mtu;         /* per route MTU/Window         */
+        u32   		rt_window;      /* Window clamping              */
+        unsigned short  rt_irtt;        /* Initial RTT                  */
+
+};
+
+struct in6_rtmsg32 {
+	struct in6_addr		rtmsg_dst;
+	struct in6_addr		rtmsg_src;
+	struct in6_addr		rtmsg_gateway;
+	u32			rtmsg_type;
+	u16			rtmsg_dst_len;
+	u16			rtmsg_src_len;
+	u32			rtmsg_metric;
+	u32			rtmsg_info;
+	u32			rtmsg_flags;
+	s32			rtmsg_ifindex;
+};
+
+extern struct socket *sockfd_lookup(int fd, int *err);
+
+static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	int ret;
+	void *r = NULL;
+	struct in6_rtmsg r6;
+	struct rtentry r4;
+	char devname[16];
+	u32 rtdev;
+	mm_segment_t old_fs = get_fs();
+	
+	struct socket *mysock = sockfd_lookup(fd, &ret);
+
+	if (mysock && mysock->sk && mysock->sk->family == AF_INET6) { /* ipv6 */
+		ret = copy_from_user (&r6.rtmsg_dst, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst),
+			3 * sizeof(struct in6_addr));
+		ret |= __get_user (r6.rtmsg_type, &(((struct in6_rtmsg32 *)arg)->rtmsg_type));
+		ret |= __get_user (r6.rtmsg_dst_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst_len));
+		ret |= __get_user (r6.rtmsg_src_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_src_len));
+		ret |= __get_user (r6.rtmsg_metric, &(((struct in6_rtmsg32 *)arg)->rtmsg_metric));
+		ret |= __get_user (r6.rtmsg_info, &(((struct in6_rtmsg32 *)arg)->rtmsg_info));
+		ret |= __get_user (r6.rtmsg_flags, &(((struct in6_rtmsg32 *)arg)->rtmsg_flags));
+		ret |= __get_user (r6.rtmsg_ifindex, &(((struct in6_rtmsg32 *)arg)->rtmsg_ifindex));
+		
+		r = (void *) &r6;
+	} else { /* ipv4 */
+		ret = copy_from_user (&r4.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr));
+		ret |= __get_user (r4.rt_flags, &(((struct rtentry32 *)arg)->rt_flags));
+		ret |= __get_user (r4.rt_metric, &(((struct rtentry32 *)arg)->rt_metric));
+		ret |= __get_user (r4.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu));
+		ret |= __get_user (r4.rt_window, &(((struct rtentry32 *)arg)->rt_window));
+		ret |= __get_user (r4.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));
+		ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev));
+		if (rtdev) {
+			ret |= copy_from_user (devname, (char *)A(rtdev), 15);
+			r4.rt_dev = devname; devname[15] = 0;
+		} else
+			r4.rt_dev = 0;
+
+		r = (void *) &r4;
+	}
+
+	if (ret)
+		return -EFAULT;
+
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl (fd, cmd, (long) r);
+	set_fs (old_fs);
+
+	return ret;
+}
+
+struct hd_geometry32 {
+	unsigned char heads;
+	unsigned char sectors;
+	unsigned short cylinders;
+	u32 start;
+};
+                        
+static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct hd_geometry geo;
+	int err;
+	
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
+	set_fs (old_fs);
+	if (!err) {
+		err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);
+		err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));
+	}
+	return err ? -EFAULT : 0;
+}
+
+
+static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	unsigned long kval;
+	unsigned int *uvp;
+	int error;
+
+	set_fs(KERNEL_DS);
+	error = sys_ioctl(fd, cmd, (long)&kval);
+	set_fs(old_fs);
+
+	if (error == 0) {
+		uvp = (unsigned int *)arg;
+		if (put_user(kval, uvp))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+struct floppy_struct32 {
+	unsigned int	size;
+	unsigned int	sect;
+	unsigned int	head;
+	unsigned int	track;
+	unsigned int	stretch;
+	unsigned char	gap;
+	unsigned char	rate;
+	unsigned char	spec1;
+	unsigned char	fmt_gap;
+	const __kernel_caddr_t32 name;
+};
+
+struct floppy_drive_params32 {
+	char		cmos;
+	u32		max_dtr;
+	u32		hlt;
+	u32		hut;
+	u32		srt;
+	u32		spinup;
+	u32		spindown;
+	unsigned char	spindown_offset;
+	unsigned char	select_delay;
+	unsigned char	rps;
+	unsigned char	tracks;
+	u32		timeout;
+	unsigned char	interleave_sect;
+	struct floppy_max_errors max_errors;
+	char		flags;
+	char		read_track;
+	short		autodetect[8];
+	int		checkfreq;
+	int		native_format;
+};
+
+struct floppy_drive_struct32 {
+	signed char	flags;
+	u32		spinup_date;
+	u32		select_date;
+	u32		first_read_date;
+	short		probed_format;
+	short		track;
+	short		maxblock;
+	short		maxtrack;
+	int		generation;
+	int		keep_data;
+	int		fd_ref;
+	int		fd_device;
+	int		last_checked;
+	__kernel_caddr_t32 dmabuf;
+	int		bufblocks;
+};
+
+struct floppy_fdc_state32 {
+	int		spec1;
+	int		spec2;
+	int		dtr;
+	unsigned char	version;
+	unsigned char	dor;
+	u32		address;
+	unsigned int	rawcmd:2;
+	unsigned int	reset:1;
+	unsigned int	need_configure:1;
+	unsigned int	perp_mode:2;
+	unsigned int	has_fifo:1;
+	unsigned int	driver_version;
+	unsigned char	track[4];
+};
+
+struct floppy_write_errors32 {
+	unsigned int	write_errors;
+	u32		first_error_sector;
+	int		first_error_generation;
+	u32		last_error_sector;
+	int		last_error_generation;
+	unsigned int	badness;
+};
+
+#define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
+#define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)
+#define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)
+#define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)
+#define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)
+#define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)
+#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)
+#define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)
+#define FDWERRORGET32  _IOR(2, 0x17, struct floppy_write_errors32)
+
+static struct {
+	unsigned int	cmd32;
+	unsigned int	cmd;
+} fd_ioctl_trans_table[] = {
+	{ FDSETPRM32, FDSETPRM },
+	{ FDDEFPRM32, FDDEFPRM },
+	{ FDGETPRM32, FDGETPRM },
+	{ FDSETDRVPRM32, FDSETDRVPRM },
+	{ FDGETDRVPRM32, FDGETDRVPRM },
+	{ FDGETDRVSTAT32, FDGETDRVSTAT },
+	{ FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
+	{ FDGETFDCSTAT32, FDGETFDCSTAT },
+	{ FDWERRORGET32, FDWERRORGET }
+};
+
+#define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))
+
+static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	void *karg = NULL;
+	unsigned int kcmd = 0;
+	int i, err;
+
+	for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
+		if (cmd == fd_ioctl_trans_table[i].cmd32) {
+			kcmd = fd_ioctl_trans_table[i].cmd;
+			break;
+		}
+	if (!kcmd)
+		return -EINVAL;
+
+	switch (cmd) {
+		case FDSETPRM32:
+		case FDDEFPRM32:
+		case FDGETPRM32:
+		{
+			struct floppy_struct *f;
+
+			f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			if (cmd == FDGETPRM32)
+				break;
+			err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size);
+			err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
+			err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head);
+			err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track);
+			err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
+			err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
+			err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
+			err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
+			err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
+			err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
+			if (err) {
+				err = -EFAULT;
+				goto out;
+			}
+			break;
+		}
+		case FDSETDRVPRM32:
+		case FDGETDRVPRM32:
+		{
+			struct floppy_drive_params *f;
+
+			f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			if (cmd == FDGETDRVPRM32)
+				break;
+			err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
+			err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
+			err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
+			err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
+			err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
+			err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
+			err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
+			err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
+			err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
+			err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
+			err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
+			err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
+			err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
+			err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors));
+			err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
+			err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
+			err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect));
+			err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
+			err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
+			if (err) {
+				err = -EFAULT;
+				goto out;
+			}
+			break;
+		}
+		case FDGETDRVSTAT32:
+		case FDPOLLDRVSTAT32:
+			karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		case FDGETFDCSTAT32:
+			karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		case FDWERRORGET32:
+			karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		default:
+			return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		goto out;
+	switch (cmd) {
+		case FDGETPRM32:
+		{
+			struct floppy_struct *f = karg;
+
+			err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size);
+			err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
+			err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head);
+			err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track);
+			err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
+			err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
+			err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
+			err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
+			err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
+			err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
+			break;
+		}
+		case FDGETDRVPRM32:
+		{
+			struct floppy_drive_params *f = karg;
+
+			err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
+			err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
+			err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
+			err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
+			err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
+			err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
+			err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
+			err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
+			err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
+			err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
+			err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
+			err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
+			err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
+			err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors));
+			err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
+			err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
+			err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect));
+			err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
+			err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
+			break;
+		}
+		case FDGETDRVSTAT32:
+		case FDPOLLDRVSTAT32:
+		{
+			struct floppy_drive_struct *f = karg;
+
+			err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags);
+			err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date);
+			err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date);
+			err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date);
+			err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format);
+			err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track);
+			err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock);
+			err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack);
+			err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation);
+			err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data);
+			err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref);
+			err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device);
+			err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked);
+			err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf);
+			err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks);
+			break;
+		}
+		case FDGETFDCSTAT32:
+		{
+			struct floppy_fdc_state *f = karg;
+
+			err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1);
+			err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2);
+			err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr);
+			err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version);
+			err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor);
+			err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address);
+			err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address
+			    		   + sizeof(((struct floppy_fdc_state32 *)arg)->address),
+					   (char *)&f->address + sizeof(f->address), sizeof(int));
+			err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version);
+			err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track));
+			break;
+		}
+		case FDWERRORGET32:
+		{
+			struct floppy_write_errors *f = karg;
+
+			err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors);
+			err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector);
+			err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation);
+			err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector);
+			err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation);
+			err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness);
+			break;
+		}
+		default:
+			break;
+	}
+	if (err)
+		err = -EFAULT;
+
+out:	if (karg) kfree(karg);
+	return err;
+}
+
+struct ppp_option_data32 {
+	__kernel_caddr_t32	ptr;
+	__u32			length;
+	int			transmit;
+};
+#define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)
+
+struct ppp_idle32 {
+	__kernel_time_t32 xmit_idle;
+	__kernel_time_t32 recv_idle;
+};
+#define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)
+
+static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct ppp_option_data32 data32;
+	struct ppp_option_data data;
+	struct ppp_idle32 idle32;
+	struct ppp_idle idle;
+	unsigned int kcmd;
+	void *karg;
+	int err = 0;
+
+	switch (cmd) {
+	case PPPIOCGIDLE32:
+		kcmd = PPPIOCGIDLE;
+		karg = &idle;
+		break;
+	case PPPIOCSCOMPRESS32:
+		if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
+			return -EFAULT;
+		data.ptr = kmalloc (data32.length, GFP_KERNEL);
+		if (!data.ptr)
+			return -ENOMEM;
+		if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {
+			kfree(data.ptr);
+			return -EFAULT;
+		}
+		data.length = data32.length;
+		data.transmit = data32.transmit;
+		kcmd = PPPIOCSCOMPRESS;
+		karg = &data;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk("ppp_ioctl: Unknown cmd fd(%d) "
+				       "cmd(%08x) arg(%08x)\n",
+				       (int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while (0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	switch (cmd) {
+	case PPPIOCGIDLE32:
+		if (err)
+			return err;
+		idle32.xmit_idle = idle.xmit_idle;
+		idle32.recv_idle = idle.recv_idle;
+		if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))
+			return -EFAULT;
+		break;
+	case PPPIOCSCOMPRESS32:
+		kfree(data.ptr);
+		break;
+	default:
+		break;
+	}
+	return err;
+}
+
+
+struct mtget32 {
+	__u32	mt_type;
+	__u32	mt_resid;
+	__u32	mt_dsreg;
+	__u32	mt_gstat;
+	__u32	mt_erreg;
+	__kernel_daddr_t32	mt_fileno;
+	__kernel_daddr_t32	mt_blkno;
+};
+#define MTIOCGET32	_IOR('m', 2, struct mtget32)
+
+struct mtpos32 {
+	__u32	mt_blkno;
+};
+#define MTIOCPOS32	_IOR('m', 3, struct mtpos32)
+
+struct mtconfiginfo32 {
+	__u32	mt_type;
+	__u32	ifc_type;
+	__u16	irqnr;
+	__u16	dmanr;
+	__u16	port;
+	__u32	debug;
+	__u32	have_dens:1;
+	__u32	have_bsf:1;
+	__u32	have_fsr:1;
+	__u32	have_bsr:1;
+	__u32	have_eod:1;
+	__u32	have_seek:1;
+	__u32	have_tell:1;
+	__u32	have_ras1:1;
+	__u32	have_ras2:1;
+	__u32	have_ras3:1;
+	__u32	have_qfa:1;
+	__u32	pad1:5;
+	char	reserved[10];
+};
+#define	MTIOCGETCONFIG32	_IOR('m', 4, struct mtconfiginfo32)
+#define	MTIOCSETCONFIG32	_IOW('m', 5, struct mtconfiginfo32)
+
+static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct mtconfiginfo info;
+	struct mtget get;
+	struct mtpos pos;
+	unsigned long kcmd;
+	void *karg;
+	int err = 0;
+
+	switch(cmd) {
+	case MTIOCPOS32:
+		kcmd = MTIOCPOS;
+		karg = &pos;
+		break;
+	case MTIOCGET32:
+		kcmd = MTIOCGET;
+		karg = &get;
+		break;
+	case MTIOCGETCONFIG32:
+		kcmd = MTIOCGETCONFIG;
+		karg = &info;
+		break;
+	case MTIOCSETCONFIG32:
+		kcmd = MTIOCSETCONFIG;
+		karg = &info;
+		err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
+		err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
+		err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
+		err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
+		err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
+		err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
+		err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
+				     (char *)&((struct mtconfiginfo32 *)arg)->debug
+				     + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
+		if (err)
+			return -EFAULT;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk("mt_ioctl: Unknown cmd fd(%d) "
+				       "cmd(%08x) arg(%08x)\n",
+				       (int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while (0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		return err;
+	switch (cmd) {
+	case MTIOCPOS32:
+		err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
+		break;
+	case MTIOCGET32:
+		err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
+		err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
+		err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
+		err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
+		err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
+		err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
+		err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
+		break;
+	case MTIOCGETCONFIG32:
+		err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
+		err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
+		err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
+		err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
+		err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
+		err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
+		err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
+			    		   + sizeof(((struct mtconfiginfo32 *)arg)->debug),
+					   (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
+		break;
+	case MTIOCSETCONFIG32:
+		break;
+	}
+	return err ? -EFAULT: 0;
+}
+
+struct cdrom_read_audio32 {
+	union cdrom_addr	addr;
+	u_char			addr_format;
+	int			nframes;
+	__kernel_caddr_t32	buf;
+};
+
+struct cdrom_generic_command32 {
+	unsigned char		cmd[CDROM_PACKET_SIZE];
+	__kernel_caddr_t32	buffer;
+	unsigned int		buflen;
+	int			stat;
+	__kernel_caddr_t32	sense;
+	__kernel_caddr_t32	reserved[3];
+};
+
+static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct cdrom_read_audio cdreadaudio;
+	struct cdrom_generic_command cgc;
+	__kernel_caddr_t32 addr;
+	char *data = 0;
+	void *karg;
+	int err = 0;
+
+	switch(cmd) {
+	case CDROMREADAUDIO:
+		karg = &cdreadaudio;
+		err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr));
+		err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format);
+		err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes); 
+		err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
+		if (err)
+			return -EFAULT;
+		data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+		cdreadaudio.buf = data;
+		break;
+	case CDROM_SEND_PACKET:
+		karg = &cgc;
+		err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));
+		err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);
+		err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
+		if (err)
+			return -EFAULT;
+		if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
+			return -ENOMEM;
+		cgc.buffer = data;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk("cdrom_ioctl: Unknown cmd fd(%d) "
+				       "cmd(%08x) arg(%08x)\n",
+				       (int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while (0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		goto out;
+	switch (cmd) {
+	case CDROMREADAUDIO:
+		err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
+		break;
+	case CDROM_SEND_PACKET:
+		err = copy_to_user((char *)A(addr), data, cgc.buflen);
+		break;
+	default:
+		break;
+	}
+out:	if (data)
+		kfree(data);
+	return err ? -EFAULT : 0;
+}
+
+struct loop_info32 {
+	int			lo_number;      /* ioctl r/o */
+	__kernel_dev_t32	lo_device;      /* ioctl r/o */
+	unsigned int		lo_inode;       /* ioctl r/o */
+	__kernel_dev_t32	lo_rdevice;     /* ioctl r/o */
+	int			lo_offset;
+	int			lo_encrypt_type;
+	int			lo_encrypt_key_size;    /* ioctl w/o */
+	int			lo_flags;       /* ioctl r/o */
+	char			lo_name[LO_NAME_SIZE];
+	unsigned char		lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+	unsigned int		lo_init[2];
+	char			reserved[4];
+};
+
+static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct loop_info l;
+	int err = -EINVAL;
+
+	switch(cmd) {
+	case LOOP_SET_STATUS:
+		err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+		err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+		err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+		err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+		err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
+					   8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+		if (err) {
+			err = -EFAULT;
+		} else {
+			set_fs (KERNEL_DS);
+			err = sys_ioctl (fd, cmd, (unsigned long)&l);
+			set_fs (old_fs);
+		}
+		break;
+	case LOOP_GET_STATUS:
+		set_fs (KERNEL_DS);
+		err = sys_ioctl (fd, cmd, (unsigned long)&l);
+		set_fs (old_fs);
+		if (!err) {
+			err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+			err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+			err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+			err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+			err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
+					   (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+			if (err)
+				err = -EFAULT;
+		}
+		break;
+	default: {
+		static int count = 0;
+		if (++count <= 20)
+			printk("%s: Unknown loop ioctl cmd, fd(%d) "
+			       "cmd(%08x) arg(%08lx)\n",
+			       __FUNCTION__, fd, cmd, arg);
+	}
+	}
+	return err;
+}
+
+extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
+
+#ifdef CONFIG_VT
+static int vt_check(struct file *file)
+{
+	struct tty_struct *tty;
+	struct inode *inode = file->f_dentry->d_inode;
+	
+	if (file->f_op->ioctl != tty_ioctl)
+		return -EINVAL;
+	                
+	tty = (struct tty_struct *)file->private_data;
+	if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
+		return -EINVAL;
+	                                                
+	if (tty->driver.ioctl != vt_ioctl)
+		return -EINVAL;
+	
+	/*
+	 * To have permissions to do most of the vt ioctls, we either have
+	 * to be the owner of the tty, or super-user.
+	 */
+	if (current->tty == tty || suser())
+		return 1;
+	return 0;                                                    
+}
+
+struct consolefontdesc32 {
+	unsigned short charcount;       /* characters in font (256 or 512) */
+	unsigned short charheight;      /* scan lines per character (1-32) */
+	u32 chardata;			/* font data in expanded form */
+};
+
+static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file)
+{
+	struct consolefontdesc cfdarg;
+	struct console_font_op op;
+	int i, perm;
+
+	perm = vt_check(file);
+	if (perm < 0) return perm;
+	
+	if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
+		return -EFAULT;
+	
+	cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata);
+ 	
+	switch (cmd) {
+	case PIO_FONTX:
+		if (!perm)
+			return -EPERM;
+		op.op = KD_FONT_OP_SET;
+		op.flags = 0;
+		op.width = 8;
+		op.height = cfdarg.charheight;
+		op.charcount = cfdarg.charcount;
+		op.data = cfdarg.chardata;
+		return con_font_op(fg_console, &op);
+	case GIO_FONTX:
+		if (!cfdarg.chardata)
+			return 0;
+		op.op = KD_FONT_OP_GET;
+		op.flags = 0;
+		op.width = 8;
+		op.height = cfdarg.charheight;
+		op.charcount = cfdarg.charcount;
+		op.data = cfdarg.chardata;
+		i = con_font_op(fg_console, &op);
+		if (i)
+			return i;
+		cfdarg.charheight = op.height;
+		cfdarg.charcount = op.charcount;
+		((struct consolefontdesc32 *)&cfdarg)->chardata	= (unsigned long)cfdarg.chardata;
+		if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32)))
+			return -EFAULT;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+struct console_font_op32 {
+	unsigned int op;        /* operation code KD_FONT_OP_* */
+	unsigned int flags;     /* KD_FONT_FLAG_* */
+	unsigned int width, height;     /* font size */
+	unsigned int charcount;
+	u32 data;    /* font data with height fixed to 32 */
+};
+                                        
+static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file)
+{
+	struct console_font_op op;
+	int perm = vt_check(file), i;
+	struct vt_struct *vt;
+	
+	if (perm < 0) return perm;
+	
+	if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32)))
+		return -EFAULT;
+	if (!perm && op.op != KD_FONT_OP_GET)
+		return -EPERM;
+	op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data);
+	op.flags |= KD_FONT_FLAG_OLD;
+	vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
+	i = con_font_op(vt->vc_num, &op);
+	if (i) return i;
+	((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
+	if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32)))
+		return -EFAULT;
+	return 0;
+}
+
+struct fb_fix_screeninfo32 {
+	char id[16];			/* identification string eg "TT Builtin" */
+	unsigned int smem_start;	/* Start of frame buffer mem */
+					/* (physical address) */
+	__u32 smem_len;			/* Length of frame buffer mem */
+	__u32 type;			/* see FB_TYPE_*		*/
+	__u32 type_aux;			/* Interleave for interleaved Planes */
+	__u32 visual;			/* see FB_VISUAL_*		*/ 
+	__u16 xpanstep;			/* zero if no hardware panning  */
+	__u16 ypanstep;			/* zero if no hardware panning  */
+	__u16 ywrapstep;		/* zero if no hardware ywrap    */
+	__u32 line_length;		/* length of a line in bytes    */
+	unsigned int mmio_start;	/* Start of Memory Mapped I/O   */
+					/* (physical address) */
+	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
+	__u32 accel;			/* Type of acceleration available */
+	__u16 reserved[3];		/* Reserved for future compatibility */
+};
+
+static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct fb_fix_screeninfo fix;
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (long)&fix);
+	set_fs(old_fs);
+
+	if (err == 0) {
+		unsigned int smem_start = fix.smem_start;  /* lose top 32 bits */
+		unsigned int mmio_start = fix.mmio_start;  /* lose top 32 bits */
+		int i;
+
+		err = put_user(fix.id[0], &((struct fb_fix_screeninfo32 *)arg)->id[0]);
+		for (i=1; i<16; i++) {
+			err |= __put_user(fix.id[i], &((struct fb_fix_screeninfo32 *)arg)->id[i]);
+		}
+		err |= __put_user(smem_start, &((struct fb_fix_screeninfo32 *)arg)->smem_start);
+		err |= __put_user(fix.smem_len, &((struct fb_fix_screeninfo32 *)arg)->smem_len);
+		err |= __put_user(fix.type, &((struct fb_fix_screeninfo32 *)arg)->type);
+		err |= __put_user(fix.type_aux, &((struct fb_fix_screeninfo32 *)arg)->type_aux);
+		err |= __put_user(fix.visual, &((struct fb_fix_screeninfo32 *)arg)->visual);
+		err |= __put_user(fix.xpanstep, &((struct fb_fix_screeninfo32 *)arg)->xpanstep);
+		err |= __put_user(fix.ypanstep, &((struct fb_fix_screeninfo32 *)arg)->ypanstep);
+		err |= __put_user(fix.ywrapstep, &((struct fb_fix_screeninfo32 *)arg)->ywrapstep);
+		err |= __put_user(fix.line_length, &((struct fb_fix_screeninfo32 *)arg)->line_length);
+		err |= __put_user(mmio_start, &((struct fb_fix_screeninfo32 *)arg)->mmio_start);
+		err |= __put_user(fix.mmio_len, &((struct fb_fix_screeninfo32 *)arg)->mmio_len);
+		err |= __put_user(fix.accel, &((struct fb_fix_screeninfo32 *)arg)->accel);
+		err |= __put_user(fix.reserved[0], &((struct fb_fix_screeninfo32 *)arg)->reserved[0]);
+		err |= __put_user(fix.reserved[1], &((struct fb_fix_screeninfo32 *)arg)->reserved[1]);
+		err |= __put_user(fix.reserved[2], &((struct fb_fix_screeninfo32 *)arg)->reserved[2]);
+		if (err)
+			err = -EFAULT;
+	}
+	return err;
+}
+
+struct fb_cmap32 {
+	__u32 start;			/* First entry	*/
+	__u32 len;			/* Number of entries */
+	__u32 redptr;			/* Red values	*/
+	__u32 greenptr;
+	__u32 blueptr;
+	__u32 transpptr;		/* transparency, can be NULL */
+};
+
+static int do_fbiogetcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct fb_cmap cmap;
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (long)&cmap);
+	set_fs(old_fs);
+
+	if (err == 0) {
+		__u32 redptr = (__u32)(__u64)cmap.red;
+		__u32 greenptr = (__u32)(__u64)cmap.green;
+		__u32 blueptr = (__u32)(__u64)cmap.blue;
+		__u32 transpptr = (__u32)(__u64)cmap.transp;
+
+		err = put_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
+		err |= __put_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
+		err |= __put_user(redptr, &((struct fb_cmap32 *)arg)->redptr);
+		err |= __put_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr);
+		err |= __put_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr);
+		err |= __put_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr);
+		if (err)
+			err = -EFAULT;
+	}
+	return err;
+}
+
+static int do_fbioputcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct fb_cmap cmap;
+	__u32 redptr, greenptr, blueptr, transpptr;
+	int err;
+
+	err = get_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
+	err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
+	err |= __get_user(redptr, &((struct fb_cmap32 *)arg)->redptr);
+	err |= __get_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr);
+	err |= __get_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr);
+	err |= __get_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr);
+
+	if (err) {
+		err = -EFAULT;
+	} else {
+		cmap.red = (__u16 *)(__u64)redptr;
+		cmap.green = (__u16 *)(__u64)greenptr;
+		cmap.blue = (__u16 *)(__u64)blueptr;
+		cmap.transp = (__u16 *)(__u64)transpptr;
+		set_fs (KERNEL_DS);
+		err = sys_ioctl (fd, cmd, (unsigned long)&cmap);
+		set_fs (old_fs);
+	}
+	return err;
+}
+
+struct unimapdesc32 {
+	unsigned short entry_ct;
+	u32 entries;
+};
+
+static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file)
+{
+	struct unimapdesc32 tmp;
+	int perm = vt_check(file);
+	
+	if (perm < 0) return perm;
+	if (copy_from_user(&tmp, user_ud, sizeof tmp))
+		return -EFAULT;
+	switch (cmd) {
+	case PIO_UNIMAP:
+		if (!perm) return -EPERM;
+		return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));
+	case GIO_UNIMAP:
+		return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));
+	}
+	return 0;
+}
+#endif /* CONFIG_VT */
+static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	__kernel_uid_t kuid;
+	int err;
+
+	cmd = SMB_IOC_GETMOUNTUID;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
+	set_fs(old_fs);
+
+	if (err >= 0)
+		err = put_user(kuid, (__kernel_uid_t32 *)arg);
+
+	return err;
+}
+
+struct atmif_sioc32 {
+        int                number;
+        int                length;
+        __kernel_caddr_t32 arg;
+};
+
+struct atm_iobuf32 {
+	int                length;
+	__kernel_caddr_t32 buffer;
+};
+
+#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
+#define ATM_GETNAMES32    _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
+#define ATM_GETTYPE32     _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
+#define ATM_GETESI32	  _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
+#define ATM_GETADDR32	  _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
+#define ATM_RSTADDR32	  _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
+#define ATM_ADDADDR32	  _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
+#define ATM_DELADDR32	  _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
+#define ATM_GETCIRANGE32  _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
+#define ATM_SETCIRANGE32  _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
+#define ATM_SETESI32      _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
+#define ATM_SETESIF32     _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
+#define ATM_GETSTAT32     _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
+#define ATM_GETSTATZ32    _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
+#define ATM_GETLOOP32	  _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
+#define ATM_SETLOOP32	  _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
+#define ATM_QUERYLOOP32	  _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
+
+static struct {
+        unsigned int cmd32;
+        unsigned int cmd;
+} atm_ioctl_map[] = {
+        { ATM_GETLINKRATE32, ATM_GETLINKRATE },
+	{ ATM_GETNAMES32,    ATM_GETNAMES },
+        { ATM_GETTYPE32,     ATM_GETTYPE },
+        { ATM_GETESI32,      ATM_GETESI },
+        { ATM_GETADDR32,     ATM_GETADDR },
+        { ATM_RSTADDR32,     ATM_RSTADDR },
+        { ATM_ADDADDR32,     ATM_ADDADDR },
+        { ATM_DELADDR32,     ATM_DELADDR },
+        { ATM_GETCIRANGE32,  ATM_GETCIRANGE },
+	{ ATM_SETCIRANGE32,  ATM_SETCIRANGE },
+	{ ATM_SETESI32,      ATM_SETESI },
+	{ ATM_SETESIF32,     ATM_SETESIF },
+	{ ATM_GETSTAT32,     ATM_GETSTAT },
+	{ ATM_GETSTATZ32,    ATM_GETSTATZ },
+	{ ATM_GETLOOP32,     ATM_GETLOOP },
+	{ ATM_SETLOOP32,     ATM_SETLOOP },
+	{ ATM_QUERYLOOP32,   ATM_QUERYLOOP }
+};
+
+#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
+
+
+static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct atm_iobuf32 iobuf32;
+	struct atm_iobuf   iobuf = { 0, NULL };
+	mm_segment_t old_fs;
+	int err;
+
+	err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg,
+	    sizeof(struct atm_iobuf32));
+	if (err)
+		return -EFAULT;
+
+	iobuf.length = iobuf32.length;
+
+	if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) {
+		iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
+	} else {
+		iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
+		if (iobuf.buffer == NULL) {
+			err = -ENOMEM;
+			goto out;
+		}
+
+		err = copy_from_user(iobuf.buffer, (void *)A(iobuf32.buffer), iobuf.length);
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+	}
+
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);      
+	set_fs (old_fs);
+        if (err)
+		goto out;
+
+        if (iobuf.buffer && iobuf.length > 0) {
+		err = copy_to_user((void *)A(iobuf32.buffer), iobuf.buffer, iobuf.length);
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+	}
+	err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
+
+ out:
+        if (iobuf32.buffer && iobuf32.length > 0)
+		kfree(iobuf.buffer);
+
+	return err;
+}
+
+
+static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+        struct atmif_sioc32 sioc32;
+        struct atmif_sioc   sioc = { 0, 0, NULL };
+        mm_segment_t old_fs;
+        int err;
+        
+        err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg,
+			     sizeof(struct atmif_sioc32));
+        if (err)
+                return -EFAULT;
+
+        sioc.number = sioc32.number;
+        sioc.length = sioc32.length;
+        
+	if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) {
+		sioc.arg = (void*)(unsigned long)sioc32.arg;
+        } else {
+                sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
+                if (sioc.arg == NULL) {
+                        err = -ENOMEM;
+			goto out;
+		}
+                
+                err = copy_from_user(sioc.arg, (void *)A(sioc32.arg), sioc32.length);
+                if (err) {
+                        err = -EFAULT;
+                        goto out;
+                }
+        }
+        
+        old_fs = get_fs(); set_fs (KERNEL_DS);
+        err = sys_ioctl (fd, cmd, (unsigned long)&sioc);	
+        set_fs (old_fs);
+        if (err) {
+                goto out;
+	}
+        
+        if (sioc.arg && sioc.length > 0) {
+                err = copy_to_user((void *)A(sioc32.arg), sioc.arg, sioc.length);
+                if (err) {
+                        err = -EFAULT;
+                        goto out;
+                }
+        }
+        err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
+        
+ out:
+        if (sioc32.arg && sioc32.length > 0)
+		kfree(sioc.arg);
+        
+	return err;
+}
+
+
+static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
+{
+        int i;
+        unsigned int cmd = 0;
+        
+	switch (cmd32) {
+	case SONET_GETSTAT:
+	case SONET_GETSTATZ:
+	case SONET_GETDIAG:
+	case SONET_SETDIAG:
+	case SONET_CLRDIAG:
+	case SONET_SETFRAMING:
+	case SONET_GETFRAMING:
+	case SONET_GETFRSENSE:
+		return do_atmif_sioc(fd, cmd32, arg);
+	}
+
+		for (i = 0; i < NR_ATM_IOCTL; i++) {
+			if (cmd32 == atm_ioctl_map[i].cmd32) {
+				cmd = atm_ioctl_map[i].cmd;
+				break;
+			}
+		}
+	        if (i == NR_ATM_IOCTL) {
+	        return -EINVAL;
+	        }
+        
+        switch (cmd) {
+	case ATM_GETNAMES:
+		return do_atm_iobuf(fd, cmd, arg);
+	    
+	case ATM_GETLINKRATE:
+        case ATM_GETTYPE:
+        case ATM_GETESI:
+        case ATM_GETADDR:
+        case ATM_RSTADDR:
+        case ATM_ADDADDR:
+        case ATM_DELADDR:
+        case ATM_GETCIRANGE:
+	case ATM_SETCIRANGE:
+	case ATM_SETESI:
+	case ATM_SETESIF:
+	case ATM_GETSTAT:
+	case ATM_GETSTATZ:
+	case ATM_GETLOOP:
+	case ATM_SETLOOP:
+	case ATM_QUERYLOOP:
+                return do_atmif_sioc(fd, cmd, arg);
+        }
+
+        return -EINVAL;
+}
+
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */
+typedef struct {
+	uint8_t vg_name[NAME_LEN];
+	uint32_t vg_number;
+	uint32_t vg_access;
+	uint32_t vg_status;
+	uint32_t lv_max;
+	uint32_t lv_cur;
+	uint32_t lv_open;
+	uint32_t pv_max;
+	uint32_t pv_cur;
+	uint32_t pv_act;
+	uint32_t dummy;
+	uint32_t vgda;
+	uint32_t pe_size;
+	uint32_t pe_total;
+	uint32_t pe_allocated;
+	uint32_t pvg_total;
+	u32 proc;
+	u32 pv[ABS_MAX_PV + 1];
+	u32 lv[ABS_MAX_LV + 1];
+    	uint8_t vg_uuid[UUID_LEN+1];	/* volume group UUID */
+	uint8_t dummy1[200];
+} vg32_t;
+
+typedef struct {
+	uint8_t id[2];
+	uint16_t version;
+	lvm_disk_data_t pv_on_disk;
+	lvm_disk_data_t vg_on_disk;
+	lvm_disk_data_t pv_namelist_on_disk;
+	lvm_disk_data_t lv_on_disk;
+	lvm_disk_data_t pe_on_disk;
+	uint8_t pv_name[NAME_LEN];
+	uint8_t vg_name[NAME_LEN];
+	uint8_t system_id[NAME_LEN];
+	kdev_t pv_dev;
+	uint32_t pv_number;
+	uint32_t pv_status;
+	uint32_t pv_allocatable;
+	uint32_t pv_size;
+	uint32_t lv_cur;
+	uint32_t pe_size;
+	uint32_t pe_total;
+	uint32_t pe_allocated;
+	uint32_t pe_stale;
+	u32 pe;
+	u32 inode;
+	uint8_t pv_uuid[UUID_LEN+1];
+} pv32_t;
+
+typedef struct {
+	char lv_name[NAME_LEN];
+	u32 lv;
+} lv_req32_t;
+
+typedef struct {
+	u32 lv_index;
+	u32 lv;
+	/* Transfer size because user space and kernel space differ */
+	uint16_t size;
+} lv_status_byindex_req32_t;
+
+typedef struct {
+	__kernel_dev_t32 dev;
+	u32   lv;
+} lv_status_bydev_req32_t;
+
+typedef struct {
+	uint8_t lv_name[NAME_LEN];
+	kdev_t old_dev;
+	kdev_t new_dev;
+	u32 old_pe;
+	u32 new_pe;
+} le_remap_req32_t;
+
+typedef struct {
+	char pv_name[NAME_LEN];
+	u32 pv;
+} pv_status_req32_t;
+
+typedef struct {
+	uint8_t lv_name[NAME_LEN];
+	uint8_t vg_name[NAME_LEN];
+	uint32_t lv_access;
+	uint32_t lv_status;
+	uint32_t lv_open;
+	kdev_t lv_dev;
+	uint32_t lv_number;
+	uint32_t lv_mirror_copies;
+	uint32_t lv_recovery;
+	uint32_t lv_schedule;
+	uint32_t lv_size;
+	u32 lv_current_pe;
+	uint32_t lv_current_le;
+	uint32_t lv_allocated_le;
+	uint32_t lv_stripes;
+	uint32_t lv_stripesize;
+	uint32_t lv_badblock;
+	uint32_t lv_allocation;
+	uint32_t lv_io_timeout;
+	uint32_t lv_read_ahead;
+	/* delta to version 1 starts here */
+	u32 lv_snapshot_org;
+	u32 lv_snapshot_prev;
+	u32 lv_snapshot_next;
+	u32 lv_block_exception;
+	uint32_t lv_remap_ptr;
+	uint32_t lv_remap_end;
+	uint32_t lv_chunk_size;
+	uint32_t lv_snapshot_minor;
+	char dummy[200];
+} lv32_t;
+
+typedef struct {
+	u32 hash[2];
+	u32 rsector_org;
+	kdev_t rdev_org;
+	u32 rsector_new;
+	kdev_t rdev_new;
+} lv_block_exception32_t;
+
+static void put_lv_t(lv_t *l)
+{
+	if (l->lv_current_pe) vfree(l->lv_current_pe);
+	if (l->lv_block_exception) vfree(l->lv_block_exception);
+	kfree(l);
+}
+
+static lv_t *get_lv_t(u32 p, int *errp)
+{
+	int err, i;
+	u32 ptr1, ptr2;
+	size_t size;
+	lv_block_exception32_t *lbe32;
+	lv_block_exception_t *lbe;
+	lv32_t *ul = (lv32_t *)A(p);
+	lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);
+
+	if (!l) {
+		*errp = -ENOMEM;
+		return NULL;
+	}
+	memset(l, 0, sizeof(lv_t));
+	err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe);
+	err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le,
+				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
+	err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr,
+				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
+	err |= __get_user(ptr1, &ul->lv_current_pe);
+	err |= __get_user(ptr2, &ul->lv_block_exception);
+	if (err) {
+		kfree(l);
+		*errp = -EFAULT;
+		return NULL;
+	}
+	if (ptr1) {
+		size = l->lv_allocated_le * sizeof(pe_t);
+		l->lv_current_pe = vmalloc(size);
+		if (l->lv_current_pe)
+			err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size);
+	}
+	if (!err && ptr2) {
+		size = l->lv_remap_end * sizeof(lv_block_exception_t);
+		l->lv_block_exception = lbe = vmalloc(size);
+		if (l->lv_block_exception) {
+			lbe32 = (lv_block_exception32_t *)A(ptr2);
+			memset(lbe, 0, size);
+                       for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {
+                               err |= get_user(lbe->rsector_org, &lbe32->rsector_org);
+                               err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
+                               err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
+                               err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
+
+			}
+		}
+	}
+	if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) {
+		if (!err)
+			*errp = -ENOMEM;
+		else
+			*errp = -EFAULT;
+		put_lv_t(l);
+		return NULL;
+	}
+	return l;
+}
+
+static int copy_lv_t(u32 ptr, lv_t *l)
+{
+	int err;
+	lv32_t *ul = (lv32_t *)A(ptr);
+	u32 ptr1;
+	size_t size;
+
+	err = get_user(ptr1, &ul->lv_current_pe);
+	if (err)
+		return -EFAULT;
+	err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe);
+	err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le,
+				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
+	err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,
+				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
+	size = l->lv_allocated_le * sizeof(pe_t);
+	if (ptr1)
+		err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
+	return err ? -EFAULT : 0;
+}
+
+static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	vg_t *v = NULL;
+	union {
+		lv_req_t lv_req;
+		le_remap_req_t le_remap;
+		lv_status_byindex_req_t lv_byindex;
+	        lv_status_bydev_req_t lv_bydev;
+		pv_status_req_t pv_status;
+	} u;
+	pv_t p;
+	int err;
+	u32 ptr = 0;
+	int i;
+	mm_segment_t old_fs;
+	void *karg = &u;
+
+	switch (cmd) {
+	case VG_STATUS:
+		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
+		if (!v) return -ENOMEM;
+		karg = v;
+		break;
+
+	case VG_CREATE_OLD:
+	case VG_CREATE:
+		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
+		if (!v) return -ENOMEM;
+		if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc) ||
+		    __get_user(v->proc, &((vg32_t *)arg)->proc)) {
+			kfree(v);
+			return -EFAULT;
+		}
+		/* 'proc' field is unused, just NULL it out. */
+		v->proc = NULL;
+		if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
+			kfree(v);
+			return -EFAULT;
+		}
+		    
+		karg = v;
+		memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));
+		if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)
+			return -EPERM;
+		for (i = 0; i < v->pv_max; i++) {
+			err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
+			if (err) break;
+			if (ptr) {
+				v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
+				if (!v->pv[i]) {
+					err = -ENOMEM;
+					break;
+				}
+				err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
+				if (err) {
+					err = -EFAULT;
+					break;
+				}
+				err = copy_from_user(v->pv[i]->pv_uuid, ((pv32_t *)A(ptr))->pv_uuid, UUID_LEN+1);
+				if (err) {
+				        err = -EFAULT;
+					break;
+				}
+
+				
+				v->pv[i]->pe = NULL; v->pv[i]->inode = NULL;
+			}
+		}
+		if (!err) {
+			for (i = 0; i < v->lv_max; i++) {
+				err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
+				if (err) break;
+				if (ptr) {
+					v->lv[i] = get_lv_t(ptr, &err);
+					if (err) break;
+				}
+			}
+		}
+		break;
+	case LV_CREATE:
+	case LV_EXTEND:
+	case LV_REDUCE:
+	case LV_REMOVE:
+	case LV_RENAME:
+	case LV_STATUS_BYNAME:
+	        err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
+		if (err) return -EFAULT;
+		if (cmd != LV_REMOVE) {
+			err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
+			if (err) return err;
+			u.lv_req.lv = get_lv_t(ptr, &err);
+		} else
+			u.lv_req.lv = NULL;
+		break;
+
+
+	case LV_STATUS_BYINDEX:
+		err = get_user(u.lv_byindex.lv_index, &((lv_status_byindex_req32_t *)arg)->lv_index);
+		err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
+		if (err) return err;
+		u.lv_byindex.lv = get_lv_t(ptr, &err);
+		break;
+	case LV_STATUS_BYDEV:
+	        err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
+		u.lv_bydev.lv = get_lv_t(ptr, &err);
+		if (err) return err;
+		u.lv_bydev.lv = &p;
+		p.pe = NULL; p.inode = NULL;		
+		break;		
+	case VG_EXTEND:
+		err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
+		if (err) return -EFAULT;
+		err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
+		if (err) return -EFAULT;
+		p.pe = NULL; p.inode = NULL;
+		karg = &p;
+		break;
+	case PV_CHANGE:
+	case PV_STATUS:
+		err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
+		if (err) return -EFAULT;
+		err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
+		if (err) return err;
+		u.pv_status.pv = &p;
+		if (cmd == PV_CHANGE) {
+			err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
+			if (err) return -EFAULT;
+			p.pe = NULL; p.inode = NULL;
+		}
+		break;
+	}
+        old_fs = get_fs(); set_fs (KERNEL_DS);
+        err = sys_ioctl (fd, cmd, (unsigned long)karg);
+        set_fs (old_fs);
+	switch (cmd) {
+	case VG_STATUS:
+		if (!err) {
+			if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) ||
+			    clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))
+				err = -EFAULT;
+		}
+		if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {
+		        err = -EFAULT;
+		}
+		kfree(v);
+		break;
+
+	case VG_CREATE_OLD:
+	case VG_CREATE:
+		for (i = 0; i < v->pv_max; i++) {
+			if (v->pv[i])
+				kfree(v->pv[i]);
+		}
+		for (i = 0; i < v->lv_max; i++) {
+			if (v->lv[i])
+				put_lv_t(v->lv[i]);
+		}
+		kfree(v);
+		break;
+	case LV_STATUS_BYNAME:
+		if (!err && u.lv_req.lv) err = copy_lv_t(ptr, u.lv_req.lv);
+		/* Fall through */
+        case LV_CREATE:
+	case LV_EXTEND:
+	case LV_REDUCE:
+		if (u.lv_req.lv) put_lv_t(u.lv_req.lv);
+		break;
+	case LV_STATUS_BYINDEX:
+		if (u.lv_byindex.lv) {
+			if (!err) err = copy_lv_t(ptr, u.lv_byindex.lv);
+			put_lv_t(u.lv_byindex.lv);
+		}
+		break;
+
+	case LV_STATUS_BYDEV:
+	        if (u.lv_bydev.lv) {
+			if (!err)
+				err = copy_lv_t(ptr, u.lv_bydev.lv);
+			put_lv_t(u.lv_byindex.lv);
+	        }
+	        break;
+
+	case PV_STATUS:
+		if (!err) {
+			err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
+			if (err) return -EFAULT;
+			err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
+			if (err) return -EFAULT;
+		}
+		break;
+	};
+
+	return err;
+}
+#endif
+
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+/* This really belongs in include/linux/drm.h -DaveM */
+#include "../../../drivers/char/drm/drm.h"
+
+typedef struct drm32_version {
+	int    version_major;	  /* Major version			    */
+	int    version_minor;	  /* Minor version			    */
+	int    version_patchlevel;/* Patch level			    */
+	int    name_len;	  /* Length of name buffer		    */
+	u32    name;		  /* Name of driver			    */
+	int    date_len;	  /* Length of date buffer		    */
+	u32    date;		  /* User-space buffer to hold date	    */
+	int    desc_len;	  /* Length of desc buffer		    */
+	u32    desc;		  /* User-space buffer to hold desc	    */
+} drm32_version_t;
+#define DRM32_IOCTL_VERSION    DRM_IOWR(0x00, drm32_version_t)
+
+static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_version_t *uversion = (drm32_version_t *)arg;
+	char *name_ptr, *date_ptr, *desc_ptr;
+	u32 tmp1, tmp2, tmp3;
+	drm_version_t kversion;
+	mm_segment_t old_fs;
+	int ret;
+
+	memset(&kversion, 0, sizeof(kversion));
+	if (get_user(kversion.name_len, &uversion->name_len) ||
+	    get_user(kversion.date_len, &uversion->date_len) ||
+	    get_user(kversion.desc_len, &uversion->desc_len) ||
+	    get_user(tmp1, &uversion->name) ||
+	    get_user(tmp2, &uversion->date) ||
+	    get_user(tmp3, &uversion->desc))
+		return -EFAULT;
+
+	name_ptr = (char *) A(tmp1);
+	date_ptr = (char *) A(tmp2);
+	desc_ptr = (char *) A(tmp3);
+
+	ret = -ENOMEM;
+	if (kversion.name_len && name_ptr) {
+		kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
+		if (!kversion.name)
+			goto out;
+	}
+	if (kversion.date_len && date_ptr) {
+		kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
+		if (!kversion.date)
+			goto out;
+	}
+	if (kversion.desc_len && desc_ptr) {
+		kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
+		if (!kversion.desc)
+			goto out;
+	}
+
+        old_fs = get_fs();
+	set_fs(KERNEL_DS);
+        ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
+        set_fs(old_fs);
+
+	if (!ret) {
+		if ((kversion.name &&
+		     copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
+		    (kversion.date &&
+		     copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
+		    (kversion.desc &&
+		     copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
+			ret = -EFAULT;
+		if (put_user(kversion.version_major, &uversion->version_major) ||
+		    put_user(kversion.version_minor, &uversion->version_minor) ||
+		    put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
+		    put_user(kversion.name_len, &uversion->name_len) ||
+		    put_user(kversion.date_len, &uversion->date_len) ||
+		    put_user(kversion.desc_len, &uversion->desc_len))
+			ret = -EFAULT;
+	}
+
+out:
+	if (kversion.name)
+		kfree(kversion.name);
+	if (kversion.date)
+		kfree(kversion.date);
+	if (kversion.desc)
+		kfree(kversion.desc);
+	return ret;
+}
+
+typedef struct drm32_unique {
+	int	unique_len;	  /* Length of unique			    */
+	u32	unique;		  /* Unique name for driver instantiation   */
+} drm32_unique_t;
+#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
+#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
+
+static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_unique_t *uarg = (drm32_unique_t *)arg;
+	drm_unique_t karg;
+	mm_segment_t old_fs;
+	char *uptr;
+	u32 tmp;
+	int ret;
+
+	if (get_user(karg.unique_len, &uarg->unique_len))
+		return -EFAULT;
+	karg.unique = NULL;
+
+	if (get_user(tmp, &uarg->unique))
+		return -EFAULT;
+
+	uptr = (char *) A(tmp);
+
+	if (uptr) {
+		karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
+		if (!karg.unique)
+			return -ENOMEM;
+		if (cmd == DRM32_IOCTL_SET_UNIQUE &&
+		    copy_from_user(karg.unique, uptr, karg.unique_len)) {
+			kfree(karg.unique);
+			return -EFAULT;
+		}
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	if (cmd == DRM32_IOCTL_GET_UNIQUE)
+		ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
+	else
+		ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
+        set_fs(old_fs);
+
+	if (!ret) {
+		if (cmd == DRM32_IOCTL_GET_UNIQUE &&
+		    uptr != NULL &&
+		    copy_to_user(uptr, karg.unique, karg.unique_len))
+			ret = -EFAULT;
+		if (put_user(karg.unique_len, &uarg->unique_len))
+			ret = -EFAULT;
+	}
+
+	if (karg.unique != NULL)
+		kfree(karg.unique);
+
+	return ret;
+}
+
+typedef struct drm32_map {
+	u32		offset;	 /* Requested physical address (0 for SAREA)*/
+	u32		size;	 /* Requested physical size (bytes)	    */
+	drm_map_type_t	type;	 /* Type of memory to map		    */
+	drm_map_flags_t flags;	 /* Flags				    */
+	u32		handle;  /* User-space: "Handle" to pass to mmap    */
+				 /* Kernel-space: kernel-virtual address    */
+	int		mtrr;	 /* MTRR slot used			    */
+				 /* Private data			    */
+} drm32_map_t;
+#define DRM32_IOCTL_ADD_MAP    DRM_IOWR(0x15, drm32_map_t)
+
+static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_map_t *uarg = (drm32_map_t *) arg;
+	drm_map_t karg;
+	mm_segment_t old_fs;
+	u32 tmp;
+	int ret;
+
+	ret  = get_user(karg.offset, &uarg->offset);
+	ret |= get_user(karg.size, &uarg->size);
+	ret |= get_user(karg.type, &uarg->type);
+	ret |= get_user(karg.flags, &uarg->flags);
+	ret |= get_user(tmp, &uarg->handle);
+	ret |= get_user(karg.mtrr, &uarg->mtrr);
+	if (ret)
+		return -EFAULT;
+
+	karg.handle = (void *) A(tmp);
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		ret  = put_user(karg.offset, &uarg->offset);
+		ret |= put_user(karg.size, &uarg->size);
+		ret |= put_user(karg.type, &uarg->type);
+		ret |= put_user(karg.flags, &uarg->flags);
+		tmp = (u32) (long)karg.handle;
+		ret |= put_user(tmp, &uarg->handle);
+		ret |= put_user(karg.mtrr, &uarg->mtrr);
+		if (ret)
+			ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+typedef struct drm32_buf_info {
+	int	       count;	/* Entries in list			     */
+	u32	       list;    /* (drm_buf_desc_t *) */ 
+} drm32_buf_info_t;
+#define DRM32_IOCTL_INFO_BUFS  DRM_IOWR(0x18, drm32_buf_info_t)
+
+static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
+	drm_buf_desc_t *ulist;
+	drm_buf_info_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret;
+	u32 tmp;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->list))
+		return -EFAULT;
+
+	ulist = (drm_buf_desc_t *) A(tmp);
+
+	orig_count = karg.count;
+
+	karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
+	if (!karg.list)
+		return -EFAULT;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (karg.count <= orig_count &&
+		    (copy_to_user(ulist, karg.list,
+				  karg.count * sizeof(drm_buf_desc_t))))
+			ret = -EFAULT;
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+	kfree(karg.list);
+
+	return ret;
+}
+
+typedef struct drm32_buf_free {
+	int	       count;
+	u32	       list;	/* (int *) */
+} drm32_buf_free_t;
+#define DRM32_IOCTL_FREE_BUFS  DRM_IOW( 0x1a, drm32_buf_free_t)
+
+static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
+	drm_buf_free_t karg;
+	mm_segment_t old_fs;
+	int *ulist;
+	int ret;
+	u32 tmp;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->list))
+		return -EFAULT;
+
+	ulist = (int *) A(tmp);
+
+	karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
+	if (!karg.list)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
+		goto out;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+out:
+	kfree(karg.list);
+
+	return ret;
+}
+
+typedef struct drm32_buf_pub {
+	int		  idx;	       /* Index into master buflist	     */
+	int		  total;       /* Buffer size			     */
+	int		  used;	       /* Amount of buffer in use (for DMA)  */
+	u32		  address;     /* Address of buffer (void *)	     */
+} drm32_buf_pub_t;
+
+typedef struct drm32_buf_map {
+	int	      count;	/* Length of buflist			    */
+	u32	      virtual;	/* Mmaped area in user-virtual (void *)	    */
+	u32 	      list;	/* Buffer information (drm_buf_pub_t *)	    */
+} drm32_buf_map_t;
+#define DRM32_IOCTL_MAP_BUFS   DRM_IOWR(0x19, drm32_buf_map_t)
+
+static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
+	drm32_buf_pub_t *ulist;
+	drm_buf_map_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret, i;
+	u32 tmp1, tmp2;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp1, &uarg->virtual) ||
+	    get_user(tmp2, &uarg->list))
+		return -EFAULT;
+
+	karg.virtual = (void *) A(tmp1);
+	ulist = (drm32_buf_pub_t *) A(tmp2);
+
+	orig_count = karg.count;
+
+	karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
+	if (!karg.list)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	for (i = 0; i < karg.count; i++) {
+		if (get_user(karg.list[i].idx, &ulist[i].idx) ||
+		    get_user(karg.list[i].total, &ulist[i].total) ||
+		    get_user(karg.list[i].used, &ulist[i].used) ||
+		    get_user(tmp1, &ulist[i].address))
+			goto out;
+
+		karg.list[i].address = (void *) A(tmp1);
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		for (i = 0; i < orig_count; i++) {
+			tmp1 = (u32) (long) karg.list[i].address;
+			if (put_user(karg.list[i].idx, &ulist[i].idx) ||
+			    put_user(karg.list[i].total, &ulist[i].total) ||
+			    put_user(karg.list[i].used, &ulist[i].used) ||
+			    put_user(tmp1, &ulist[i].address)) {
+				ret = -EFAULT;
+				goto out;
+			}
+		}
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+out:
+	kfree(karg.list);
+	return ret;
+}
+
+typedef struct drm32_dma {
+				/* Indices here refer to the offset into
+				   buflist in drm_buf_get_t.  */
+	int		context;	  /* Context handle		    */
+	int		send_count;	  /* Number of buffers to send	    */
+	u32		send_indices;	  /* List of handles to buffers (int *) */
+	u32		send_sizes;	  /* Lengths of data to send (int *) */
+	drm_dma_flags_t flags;		  /* Flags			    */
+	int		request_count;	  /* Number of buffers requested    */
+	int		request_size;	  /* Desired size for buffers	    */
+	u32		request_indices;  /* Buffer information (int *)	    */
+	u32		request_sizes;    /* (int *) */
+	int		granted_count;	  /* Number of buffers granted	    */
+} drm32_dma_t;
+#define DRM32_IOCTL_DMA	     DRM_IOWR(0x29, drm32_dma_t)
+
+/* RED PEN	The DRM layer blindly dereferences the send/request
+ * 		indice/size arrays even though they are userland
+ * 		pointers.  -DaveM
+ */
+static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_dma_t *uarg = (drm32_dma_t *) arg;
+	int *u_si, *u_ss, *u_ri, *u_rs;
+	drm_dma_t karg;
+	mm_segment_t old_fs;
+	int ret;
+	u32 tmp1, tmp2, tmp3, tmp4;
+
+	karg.send_indices = karg.send_sizes = NULL;
+	karg.request_indices = karg.request_sizes = NULL;
+
+	if (get_user(karg.context, &uarg->context) ||
+	    get_user(karg.send_count, &uarg->send_count) ||
+	    get_user(tmp1, &uarg->send_indices) ||
+	    get_user(tmp2, &uarg->send_sizes) ||
+	    get_user(karg.flags, &uarg->flags) ||
+	    get_user(karg.request_count, &uarg->request_count) ||
+	    get_user(karg.request_size, &uarg->request_size) ||
+	    get_user(tmp3, &uarg->request_indices) ||
+	    get_user(tmp4, &uarg->request_sizes) ||
+	    get_user(karg.granted_count, &uarg->granted_count))
+		return -EFAULT;
+
+	u_si = (int *) A(tmp1);
+	u_ss = (int *) A(tmp2);
+	u_ri = (int *) A(tmp3);
+	u_rs = (int *) A(tmp4);
+
+	if (karg.send_count) {
+		karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
+		karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
+
+		ret = -ENOMEM;
+		if (!karg.send_indices || !karg.send_sizes)
+			goto out;
+
+		ret = -EFAULT;
+		if (copy_from_user(karg.send_indices, u_si,
+				   (karg.send_count * sizeof(int))) ||
+		    copy_from_user(karg.send_sizes, u_ss,
+				   (karg.send_count * sizeof(int))))
+			goto out;
+	}
+
+	if (karg.request_count) {
+		karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
+		karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
+
+		ret = -ENOMEM;
+		if (!karg.request_indices || !karg.request_sizes)
+			goto out;
+
+		ret = -EFAULT;
+		if (copy_from_user(karg.request_indices, u_ri,
+				   (karg.request_count * sizeof(int))) ||
+		    copy_from_user(karg.request_sizes, u_rs,
+				   (karg.request_count * sizeof(int))))
+			goto out;
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (put_user(karg.context, &uarg->context) ||
+		    put_user(karg.send_count, &uarg->send_count) ||
+		    put_user(karg.flags, &uarg->flags) ||
+		    put_user(karg.request_count, &uarg->request_count) ||
+		    put_user(karg.request_size, &uarg->request_size) ||
+		    put_user(karg.granted_count, &uarg->granted_count))
+			ret = -EFAULT;
+
+		if (karg.send_count) {
+			if (copy_to_user(u_si, karg.send_indices,
+					 (karg.send_count * sizeof(int))) ||
+			    copy_to_user(u_ss, karg.send_sizes,
+					 (karg.send_count * sizeof(int))))
+				ret = -EFAULT;
+		}
+		if (karg.request_count) {
+			if (copy_to_user(u_ri, karg.request_indices,
+					 (karg.request_count * sizeof(int))) ||
+			    copy_to_user(u_rs, karg.request_sizes,
+					 (karg.request_count * sizeof(int))))
+				ret = -EFAULT;
+		}
+	}
+
+out:
+	if (karg.send_indices)
+		kfree(karg.send_indices);
+	if (karg.send_sizes)
+		kfree(karg.send_sizes);
+	if (karg.request_indices)
+		kfree(karg.request_indices);
+	if (karg.request_sizes)
+		kfree(karg.request_sizes);
+
+	return ret;
+}
+
+typedef struct drm32_ctx_res {
+	int		count;
+	u32		contexts; /* (drm_ctx_t *) */
+} drm32_ctx_res_t;
+#define DRM32_IOCTL_RES_CTX    DRM_IOWR(0x26, drm32_ctx_res_t)
+
+static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
+	drm_ctx_t *ulist;
+	drm_ctx_res_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret;
+	u32 tmp;
+
+	karg.contexts = NULL;
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->contexts))
+		return -EFAULT;
+
+	ulist = (drm_ctx_t *) A(tmp);
+
+	orig_count = karg.count;
+	if (karg.count && ulist) {
+		karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
+		if (!karg.contexts)
+			return -ENOMEM;
+		if (copy_from_user(karg.contexts, ulist,
+				   (karg.count * sizeof(drm_ctx_t)))) {
+			kfree(karg.contexts);
+			return -EFAULT;
+		}
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (orig_count) {
+			if (copy_to_user(ulist, karg.contexts,
+					 (orig_count * sizeof(drm_ctx_t))))
+				ret = -EFAULT;
+		}
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+	if (karg.contexts)
+		kfree(karg.contexts);
+
+	return ret;
+}
+
+#endif
+
+static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return -EINVAL;
+}
+
+static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	/* The mkswap binary hard codes it to Intel value :-((( */
+	return w_long(fd, BLKGETSIZE, arg);
+}
+
+struct blkpg_ioctl_arg32 {
+	int op;
+	int flags;
+	int datalen;
+	u32 data;
+};
+                                
+static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
+{
+	struct blkpg_ioctl_arg a;
+	struct blkpg_partition p;
+	int err;
+	mm_segment_t old_fs = get_fs();
+	
+	err = get_user(a.op, &arg->op);
+	err |= __get_user(a.flags, &arg->flags);
+	err |= __get_user(a.datalen, &arg->datalen);
+	err |= __get_user((long)a.data, &arg->data);
+	if (err) return err;
+	switch (a.op) {
+	case BLKPG_ADD_PARTITION:
+	case BLKPG_DEL_PARTITION:
+		if (a.datalen < sizeof(struct blkpg_partition))
+			return -EINVAL;
+                if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
+			return -EFAULT;
+		a.data = &p;
+		set_fs (KERNEL_DS);
+		err = sys_ioctl(fd, cmd, (unsigned long)&a);
+		set_fs (old_fs);
+	default:
+		return -EINVAL;
+	}                                        
+	return err;
+}
+
+static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
+}
+
+struct usbdevfs_ctrltransfer32 {
+	__u8 requesttype;
+	__u8 request;
+	__u16 value;
+	__u16 index;
+	__u16 length;
+	__u32 timeout;  /* in milliseconds */
+	__u32 data;
+};
+
+#define USBDEVFS_CONTROL32           _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
+
+static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct usbdevfs_ctrltransfer kctrl;
+	struct usbdevfs_ctrltransfer32 *uctrl;
+	mm_segment_t old_fs;
+	__u32 udata;
+	void *uptr, *kptr;
+	int err;
+
+	uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
+
+	if (copy_from_user(&kctrl, uctrl,
+			   (sizeof(struct usbdevfs_ctrltransfer) -
+			    sizeof(void *))))
+		return -EFAULT;
+
+	if (get_user(udata, &uctrl->data))
+		return -EFAULT;
+	uptr = (void *) A(udata);
+
+	/* In usbdevice_fs, it limits the control buffer to a page,
+	 * for simplicity so do we.
+	 */
+	if (!uptr || kctrl.length > PAGE_SIZE)
+		return -EINVAL;
+
+	kptr = (void *)__get_free_page(GFP_KERNEL);
+
+	if ((kctrl.requesttype & 0x80) == 0) {
+		err = -EFAULT;
+		if (copy_from_user(kptr, uptr, kctrl.length))
+			goto out;
+	}
+
+	kctrl.data = kptr;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
+	set_fs(old_fs);
+
+	if (err >= 0 &&
+	    ((kctrl.requesttype & 0x80) != 0)) {
+		if (copy_to_user(uptr, kptr, kctrl.length))
+			err = -EFAULT;
+	}
+
+out:
+	free_page((unsigned long) kptr);
+	return err;
+}
+
+struct usbdevfs_bulktransfer32 {
+	unsigned int ep;
+	unsigned int len;
+	unsigned int timeout; /* in milliseconds */
+	__u32 data;
+};
+
+#define USBDEVFS_BULK32              _IOWR('U', 2, struct usbdevfs_bulktransfer32)
+
+static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct usbdevfs_bulktransfer kbulk;
+	struct usbdevfs_bulktransfer32 *ubulk;
+	mm_segment_t old_fs;
+	__u32 udata;
+	void *uptr, *kptr;
+	int err;
+
+	ubulk = (struct usbdevfs_bulktransfer32 *) arg;
+
+	if (get_user(kbulk.ep, &ubulk->ep) ||
+	    get_user(kbulk.len, &ubulk->len) ||
+	    get_user(kbulk.timeout, &ubulk->timeout) ||
+	    get_user(udata, &ubulk->data))
+		return -EFAULT;
+
+	uptr = (void *) A(udata);
+
+	/* In usbdevice_fs, it limits the control buffer to a page,
+	 * for simplicity so do we.
+	 */
+	if (!uptr || kbulk.len > PAGE_SIZE)
+		return -EINVAL;
+
+	kptr = (void *) __get_free_page(GFP_KERNEL);
+
+	if ((kbulk.ep & 0x80) == 0) {
+		err = -EFAULT;
+		if (copy_from_user(kptr, uptr, kbulk.len))
+			goto out;
+	}
+
+	kbulk.data = kptr;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
+	set_fs(old_fs);
+
+	if (err >= 0 &&
+	    ((kbulk.ep & 0x80) != 0)) {
+		if (copy_to_user(uptr, kptr, kbulk.len))
+			err = -EFAULT;
+	}
+
+out:
+	free_page((unsigned long) kptr);
+	return err;
+}
+
+/* This needs more work before we can enable it.  Unfortunately
+ * because of the fancy asynchronous way URB status/error is written
+ * back to userspace, we'll need to fiddle with USB devio internals
+ * and/or reimplement entirely the frontend of it ourselves. -DaveM
+ *
+ * The issue is:
+ *
+ *	When an URB is submitted via usbdevicefs it is put onto an
+ *	asynchronous queue.  When the URB completes, it may be reaped
+ *	via another ioctl.  During this reaping the status is written
+ *	back to userspace along with the length of the transfer.
+ *
+ *	We must translate into 64-bit kernel types so we pass in a kernel
+ *	space copy of the usbdevfs_urb structure.  This would mean that we
+ *	must do something to deal with the async entry reaping.  First we
+ *	have to deal somehow with this transitory memory we've allocated.
+ *	This is problematic since there are many call sites from which the
+ *	async entries can be destroyed (and thus when we'd need to free up
+ *	this kernel memory).  One of which is the close() op of usbdevicefs.
+ *	To handle that we'd need to make our own file_operations struct which
+ *	overrides usbdevicefs's release op with our own which runs usbdevicefs's
+ *	real release op then frees up the kernel memory.
+ *
+ *	But how to keep track of these kernel buffers?  We'd need to either
+ *	keep track of them in some table _or_ know about usbdevicefs internals
+ *	(ie. the exact layout of it's file private, which is actually defined
+ *	in linux/usbdevice_fs.h, the layout of the async queues are private to
+ *	devio.c)
+ *
+ * There is one possible other solution I considered, also involving knowledge
+ * of usbdevicefs internals:
+ *
+ *	After an URB is submitted, we "fix up" the address back to the user
+ *	space one.  This would work if the status/length fields written back
+ *	by the async URB completion lines up perfectly in the 32-bit type with
+ *	the 64-bit kernel type.  Unfortunately, it does not because the iso
+ *	frame descriptors, at the end of the struct, can be written back.
+ *
+ * I think we'll just need to simply duplicate the devio URB engine here.
+ */
+#if 0
+struct usbdevfs_urb32 {
+	__u8 type;
+	__u8 endpoint;
+	__s32 status;
+	__u32 flags;
+	__u32 buffer;
+	__s32 buffer_length;
+	__s32 actual_length;
+	__s32 start_frame;
+	__s32 number_of_packets;
+	__s32 error_count;
+	__u32 signr;
+	__u32 usercontext; /* unused */
+	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+};
+
+#define USBDEVFS_SUBMITURB32       _IOR('U', 10, struct usbdevfs_urb32)
+
+static int get_urb32(struct usbdevfs_urb *kurb,
+		     struct usbdevfs_urb32 *uurb)
+{
+	if (get_user(kurb->type, &uurb->type) ||
+	    __get_user(kurb->endpoint, &uurb->endpoint) ||
+	    __get_user(kurb->status, &uurb->status) ||
+	    __get_user(kurb->flags, &uurb->flags) ||
+	    __get_user(kurb->buffer_length, &uurb->buffer_length) ||
+	    __get_user(kurb->actual_length, &uurb->actual_length) ||
+	    __get_user(kurb->start_frame, &uurb->start_frame) ||
+	    __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
+	    __get_user(kurb->error_count, &uurb->error_count) ||
+	    __get_user(kurb->signr, &uurb->signr))
+		return -EFAULT;
+
+	kurb->usercontext = 0; /* unused currently */
+
+	return 0;
+}
+
+/* Just put back the values which usbdevfs actually changes. */
+static int put_urb32(struct usbdevfs_urb *kurb,
+		     struct usbdevfs_urb32 *uurb)
+{
+	if (put_user(kurb->status, &uurb->status) ||
+	    __put_user(kurb->actual_length, &uurb->actual_length) ||
+	    __put_user(kurb->error_count, &uurb->error_count))
+		return -EFAULT;
+
+	if (kurb->number_of_packets != 0) {
+		int i;
+
+		for (i = 0; i < kurb->number_of_packets; i++) {
+			if (__put_user(kurb->iso_frame_desc[i].actual_length,
+				       &uurb->iso_frame_desc[i].actual_length) ||
+			    __put_user(kurb->iso_frame_desc[i].status,
+				       &uurb->iso_frame_desc[i].status))
+				return -EFAULT;
+		}
+	}
+
+	return 0;
+}
+
+static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
+			       struct usbdevfs_urb32 *uurb)
+{
+	unsigned int totlen;
+	int i;
+
+	if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
+		kurb->number_of_packets = 0;
+		return 0;
+	}
+
+	if (kurb->number_of_packets < 1 ||
+	    kurb->number_of_packets > 128)
+		return -EINVAL;
+
+	if (copy_from_user(&kurb->iso_frame_desc[0],
+			   &uurb->iso_frame_desc[0],
+			   sizeof(struct usbdevfs_iso_packet_desc) *
+			   kurb->number_of_packets))
+		return -EFAULT;
+
+	totlen = 0;
+	for (i = 0; i < kurb->number_of_packets; i++) {
+		unsigned int this_len;
+
+		this_len = kurb->iso_frame_desc[i].length;
+		if (this_len > 1023)
+			return -EINVAL;
+
+		totlen += this_len;
+	}
+
+	if (totlen > 32768)
+		return -EINVAL;
+
+	kurb->buffer_length = totlen;
+
+	return 0;
+}
+
+static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct usbdevfs_urb *kurb;
+	struct usbdevfs_urb32 *uurb;
+	mm_segment_t old_fs;
+	__u32 udata;
+	void *uptr, *kptr;
+	unsigned int buflen;
+	int err;
+
+	uurb = (struct usbdevfs_urb32 *) arg;
+
+	err = -ENOMEM;
+	kurb = kmalloc(sizeof(struct usbdevfs_urb) +
+		       (sizeof(struct usbdevfs_iso_packet_desc) * 128),
+		       GFP_KERNEL);
+	if (!kurb)
+		goto out;
+
+	err = -EFAULT;
+	if (get_urb32(kurb, uurb))
+		goto out;
+
+	err = get_urb32_isoframes(kurb, uurb);
+	if (err)
+		goto out;
+
+	err = -EFAULT;
+	if (__get_user(udata, &uurb->buffer))
+		goto out;
+	uptr = (void *) A(udata);
+
+	err = -ENOMEM;
+	buflen = kurb->buffer_length;
+	kptr = kmalloc(buflen, GFP_KERNEL);
+	if (!kptr)
+		goto out;
+
+	kurb->buffer = kptr;
+
+	err = -EFAULT;
+	if (copy_from_user(kptr, uptr, buflen))
+		goto out_kptr;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
+	set_fs(old_fs);
+
+	if (err >= 0) {
+		/* XXX Shit, this doesn't work for async URBs :-( XXX */
+		if (put_urb32(kurb, uurb)) {
+			err = -EFAULT;
+		} else if ((kurb->endpoint & USB_DIR_IN) != 0) {
+			if (copy_to_user(uptr, kptr, buflen))
+				err = -EFAULT;
+		}
+	}
+
+out_kptr:
+	kfree(kptr);
+
+out:
+	kfree(kurb);
+	return err;
+}
+#endif
+
+#define USBDEVFS_REAPURB32         _IOW('U', 12, u32)
+#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, u32)
+
+static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs;
+	void *kptr;
+	int err;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd,
+			(cmd == USBDEVFS_REAPURB32 ?
+			 USBDEVFS_REAPURB :
+			 USBDEVFS_REAPURBNDELAY),
+			(unsigned long) &kptr);
+	set_fs(old_fs);
+
+	if (err >= 0 &&
+	    put_user(((u32)(long)kptr), (u32 *) A(arg)))
+		err = -EFAULT;
+
+	return err;
+}
+
+struct usbdevfs_disconnectsignal32 {
+	unsigned int signr;
+	u32 context;
+};
+
+#define USBDEVFS_DISCSIGNAL32      _IOR('U', 14, struct usbdevfs_disconnectsignal32)
+
+static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct usbdevfs_disconnectsignal kdis;
+	struct usbdevfs_disconnectsignal32 *udis;
+	mm_segment_t old_fs;
+	u32 uctx;
+	int err;
+
+	udis = (struct usbdevfs_disconnectsignal32 *) arg;
+
+	if (get_user(kdis.signr, &udis->signr) ||
+	    __get_user(uctx, &udis->context))
+		return -EFAULT;
+
+	kdis.context = (void *) (long)uctx;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
+	set_fs(old_fs);
+
+	return err;
+}
+
+struct mtd_oob_buf32 {
+	u32 start;
+	u32 length;
+	u32 ptr;	/* unsigned char* */
+};
+
+#define MEMWRITEOOB32 	_IOWR('M',3,struct mtd_oob_buf32)
+#define MEMREADOOB32 	_IOWR('M',4,struct mtd_oob_buf32)
+
+static inline int 
+mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t 			old_fs 	= get_fs();
+	struct mtd_oob_buf32	*uarg 	= (struct mtd_oob_buf32 *)arg;
+	struct mtd_oob_buf		karg;
+	u32 tmp;
+	char *ptr;
+	int ret;
+
+	if (get_user(karg.start, &uarg->start) 		||
+	    get_user(karg.length, &uarg->length)	||
+	    get_user(tmp, &uarg->ptr))
+		return -EFAULT;
+
+	ptr = (char *)A(tmp);
+	if (0 >= karg.length) 
+		return -EINVAL;
+
+	karg.ptr = kmalloc(karg.length, GFP_KERNEL);
+	if (NULL == karg.ptr)
+		return -ENOMEM;
+
+	if (copy_from_user(karg.ptr, ptr, karg.length)) {
+		kfree(karg.ptr);
+		return -EFAULT;
+	}
+
+	set_fs(KERNEL_DS);
+	if (MEMREADOOB32 == cmd) 
+		ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg);
+	else if (MEMWRITEOOB32 == cmd)
+		ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg);
+	else
+		ret = -EINVAL;
+	set_fs(old_fs);
+
+	if (0 == ret && cmd == MEMREADOOB32) {
+		ret = copy_to_user(ptr, karg.ptr, karg.length);
+		ret |= put_user(karg.start, &uarg->start);
+		ret |= put_user(karg.length, &uarg->length);
+	}
+
+	kfree(karg.ptr);
+	return ((0 == ret) ? 0 : -EFAULT);
+}	
+
+struct sg_io_hdr_32
+{
+	int interface_id;
+	int dxfer_direction;
+	unsigned char cmd_len;
+	unsigned char mx_sb_len;
+	unsigned short iovec_count;
+	unsigned int dxfer_len;
+	u32 dxferp;
+	u32 cmdp;
+	u32 sbp;
+	unsigned int timeout;
+	unsigned int flags;
+	int pack_id;
+	u32 usr_ptr;
+	unsigned char status;
+	unsigned char masked_status;
+	unsigned char msg_status;
+	unsigned char sb_len_wr;
+	unsigned short host_status;
+	unsigned short driver_status;
+	int resid;
+	unsigned int duration;
+	unsigned int info;
+};
+
+static int do_sg_io(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct sg_io_hdr *sg = kmalloc(sizeof(struct sg_io_hdr), GFP_KERNEL);
+	struct sg_io_hdr_32 *sg_32 = (struct sg_io_hdr_32 *)arg;
+	u32 dxferp_32;
+	u32 cmdp_32;
+	u32 sbp_32;
+	u32 usr_ptr_32;
+	int ret = -EFAULT;
+	int err;
+	mm_segment_t old_fs = get_fs();
+
+	if (!sg)
+		return -ENOMEM;
+
+	memset(sg, 0, sizeof(*sg));
+
+	err = copy_from_user(sg, sg_32, offsetof(struct sg_io_hdr, dxferp));
+	err |= __get_user(dxferp_32, &sg_32->dxferp);
+	err |= __get_user(cmdp_32, &sg_32->cmdp);
+	err |= __get_user(sbp_32, &sg_32->sbp);
+
+	if (err)
+		goto error;
+
+	sg->dxferp = (void *)A(dxferp_32);
+	sg->cmdp = (void *)A(cmdp_32);
+	sg->sbp = (void *)A(sbp_32);
+
+	err = __copy_from_user(&sg->timeout, &sg_32->timeout,
+			       (long)&sg->usr_ptr - (long)&sg->timeout);
+
+	err |= __get_user(usr_ptr_32, &sg_32->usr_ptr);
+
+	if (err)
+		goto error;
+
+	sg->usr_ptr = (void *)A(usr_ptr_32);
+
+	err = __copy_from_user(&sg->status, &sg_32->status,
+			       sizeof(struct sg_io_hdr) -
+			       offsetof(struct sg_io_hdr, status));
+
+	if (err)
+		goto error;
+
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, cmd, (unsigned long)sg);
+	set_fs(old_fs);
+
+	err = copy_to_user(sg_32, sg, offsetof(struct sg_io_hdr, dxferp));
+
+	dxferp_32 = (unsigned long)sg->dxferp;
+	cmdp_32 = (unsigned long)sg->cmdp;
+	sbp_32 = (unsigned long)sg->sbp;
+	err |= __put_user(dxferp_32, &sg_32->dxferp);
+	err |= __put_user(cmdp_32, &sg_32->cmdp);
+	err |= __put_user(sbp_32, &sg_32->sbp);
+
+	if (err) {
+		ret = -EFAULT;
+		goto error;
+	}
+
+	err = __copy_to_user(&sg_32->timeout, &sg->timeout,
+			     (long)&sg->usr_ptr - (long)&sg->timeout);
+
+	usr_ptr_32 = (unsigned long)sg->usr_ptr;
+	err |= __put_user(usr_ptr_32, &sg_32->usr_ptr);
+
+	if (err) {
+		ret = -EFAULT;
+		goto error;
+	}
+
+	err = __copy_to_user(&sg_32->status, &sg->status,
+			      sizeof(struct sg_io_hdr) -
+			      offsetof(struct sg_io_hdr, status));
+
+	if (err)
+		ret = -EFAULT;
+
+error:
+	kfree(sg);
+	return ret;
+}
+
+struct ioctl_trans {
+	unsigned long cmd;
+	unsigned long handler;
+	unsigned long next;
+};
+
+#define COMPATIBLE_IOCTL(cmd) { cmd, (unsigned long)sys_ioctl, 0 }
+
+#define HANDLE_IOCTL(cmd,handler) { cmd, (unsigned long)handler, 0 }
+
+#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
+#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, __kernel_uid_t32)
+
+static struct ioctl_trans ioctl_translations[] = {
+    /* List here explicitly which ioctl's need translation,
+     * all others default to calling sys_ioctl().
+     */
+/* Big T */
+COMPATIBLE_IOCTL(TCGETA),
+COMPATIBLE_IOCTL(TCSETA),
+COMPATIBLE_IOCTL(TCSETAW),
+COMPATIBLE_IOCTL(TCSETAF),
+COMPATIBLE_IOCTL(TCSBRK),
+COMPATIBLE_IOCTL(TCXONC),
+COMPATIBLE_IOCTL(TCFLSH),
+COMPATIBLE_IOCTL(TCGETS),
+COMPATIBLE_IOCTL(TCSETS),
+COMPATIBLE_IOCTL(TCSETSW),
+COMPATIBLE_IOCTL(TCSETSF),
+COMPATIBLE_IOCTL(TIOCLINUX),
+COMPATIBLE_IOCTL(TIOCSTART),
+/* Little t */
+COMPATIBLE_IOCTL(TIOCGETD),
+COMPATIBLE_IOCTL(TIOCSETD),
+COMPATIBLE_IOCTL(TIOCEXCL),
+COMPATIBLE_IOCTL(TIOCNXCL),
+COMPATIBLE_IOCTL(TIOCCONS),
+COMPATIBLE_IOCTL(TIOCGSOFTCAR),
+COMPATIBLE_IOCTL(TIOCSSOFTCAR),
+COMPATIBLE_IOCTL(TIOCSWINSZ),
+COMPATIBLE_IOCTL(TIOCGWINSZ),
+COMPATIBLE_IOCTL(TIOCMGET),
+COMPATIBLE_IOCTL(TIOCMBIC),
+COMPATIBLE_IOCTL(TIOCMBIS),
+COMPATIBLE_IOCTL(TIOCMSET),
+COMPATIBLE_IOCTL(TIOCPKT),
+COMPATIBLE_IOCTL(TIOCNOTTY),
+COMPATIBLE_IOCTL(TIOCSTI),
+COMPATIBLE_IOCTL(TIOCOUTQ),
+COMPATIBLE_IOCTL(TIOCSPGRP),
+COMPATIBLE_IOCTL(TIOCGPGRP),
+COMPATIBLE_IOCTL(TIOCSCTTY),
+COMPATIBLE_IOCTL(TIOCGPTN),
+COMPATIBLE_IOCTL(TIOCSPTLCK),
+COMPATIBLE_IOCTL(TIOCGSERIAL),
+COMPATIBLE_IOCTL(TIOCSSERIAL),
+COMPATIBLE_IOCTL(TIOCSERGETLSR),
+COMPATIBLE_IOCTL(TIOCSLTC),
+/* Big F */
+COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO),
+COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO),
+COMPATIBLE_IOCTL(FBIOPAN_DISPLAY),
+COMPATIBLE_IOCTL(FBIOGET_FCURSORINFO),
+COMPATIBLE_IOCTL(FBIOGET_VCURSORINFO),
+COMPATIBLE_IOCTL(FBIOPUT_VCURSORINFO),
+COMPATIBLE_IOCTL(FBIOGET_CURSORSTATE),
+COMPATIBLE_IOCTL(FBIOPUT_CURSORSTATE),
+COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP),
+COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP),
+#if 0
+COMPATIBLE_IOCTL(FBIOBLANK),
+#endif
+/* Little f */
+COMPATIBLE_IOCTL(FIOCLEX),
+COMPATIBLE_IOCTL(FIONCLEX),
+COMPATIBLE_IOCTL(FIOASYNC),
+COMPATIBLE_IOCTL(FIONBIO),
+COMPATIBLE_IOCTL(FIONREAD),  /* This is also TIOCINQ */
+/* 0x00 */
+COMPATIBLE_IOCTL(FIBMAP),
+COMPATIBLE_IOCTL(FIGETBSZ),
+/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
+ *         Some need translations, these do not.
+ */
+COMPATIBLE_IOCTL(HDIO_GET_IDENTITY),
+COMPATIBLE_IOCTL(HDIO_SET_DMA),
+COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS),
+COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR),
+COMPATIBLE_IOCTL(HDIO_SET_NOWERR),
+COMPATIBLE_IOCTL(HDIO_SET_32BIT),
+COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT),
+COMPATIBLE_IOCTL(HDIO_DRIVE_CMD),
+COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE),
+COMPATIBLE_IOCTL(HDIO_SCAN_HWIF),
+COMPATIBLE_IOCTL(HDIO_SET_NICE),
+/* 0x02 -- Floppy ioctls */
+COMPATIBLE_IOCTL(FDMSGON),
+COMPATIBLE_IOCTL(FDMSGOFF),
+COMPATIBLE_IOCTL(FDSETEMSGTRESH),
+COMPATIBLE_IOCTL(FDFLUSH),
+COMPATIBLE_IOCTL(FDWERRORCLR),
+COMPATIBLE_IOCTL(FDSETMAXERRS),
+COMPATIBLE_IOCTL(FDGETMAXERRS),
+COMPATIBLE_IOCTL(FDGETDRVTYP),
+COMPATIBLE_IOCTL(FDEJECT),
+COMPATIBLE_IOCTL(FDCLRPRM),
+COMPATIBLE_IOCTL(FDFMTBEG),
+COMPATIBLE_IOCTL(FDFMTEND),
+COMPATIBLE_IOCTL(FDRESET),
+COMPATIBLE_IOCTL(FDTWADDLE),
+COMPATIBLE_IOCTL(FDFMTTRK),
+COMPATIBLE_IOCTL(FDRAWCMD),
+/* 0x12 */
+COMPATIBLE_IOCTL(BLKROSET),
+COMPATIBLE_IOCTL(BLKROGET),
+COMPATIBLE_IOCTL(BLKRRPART),
+COMPATIBLE_IOCTL(BLKFLSBUF),
+COMPATIBLE_IOCTL(BLKRASET),
+COMPATIBLE_IOCTL(BLKFRASET),
+COMPATIBLE_IOCTL(BLKSECTSET),
+COMPATIBLE_IOCTL(BLKSSZGET),
+COMPATIBLE_IOCTL(BLKBSZGET),
+COMPATIBLE_IOCTL(BLKBSZSET),
+COMPATIBLE_IOCTL(BLKGETSIZE64),
+
+/* RAID */
+COMPATIBLE_IOCTL(RAID_VERSION),
+COMPATIBLE_IOCTL(GET_ARRAY_INFO),
+COMPATIBLE_IOCTL(GET_DISK_INFO),
+COMPATIBLE_IOCTL(PRINT_RAID_DEBUG),
+COMPATIBLE_IOCTL(CLEAR_ARRAY),
+COMPATIBLE_IOCTL(ADD_NEW_DISK),
+COMPATIBLE_IOCTL(HOT_REMOVE_DISK),
+COMPATIBLE_IOCTL(SET_ARRAY_INFO),
+COMPATIBLE_IOCTL(SET_DISK_INFO),
+COMPATIBLE_IOCTL(WRITE_RAID_INFO),
+COMPATIBLE_IOCTL(UNPROTECT_ARRAY),
+COMPATIBLE_IOCTL(PROTECT_ARRAY),
+COMPATIBLE_IOCTL(HOT_ADD_DISK),
+COMPATIBLE_IOCTL(SET_DISK_FAULTY),
+COMPATIBLE_IOCTL(RUN_ARRAY),
+COMPATIBLE_IOCTL(START_ARRAY),
+COMPATIBLE_IOCTL(STOP_ARRAY),
+COMPATIBLE_IOCTL(STOP_ARRAY_RO),
+COMPATIBLE_IOCTL(RESTART_ARRAY_RW),
+/* Big K */
+COMPATIBLE_IOCTL(PIO_FONT),
+COMPATIBLE_IOCTL(GIO_FONT),
+COMPATIBLE_IOCTL(KDSIGACCEPT),
+COMPATIBLE_IOCTL(KDGETKEYCODE),
+COMPATIBLE_IOCTL(KDSETKEYCODE),
+COMPATIBLE_IOCTL(KIOCSOUND),
+COMPATIBLE_IOCTL(KDMKTONE),
+COMPATIBLE_IOCTL(KDGKBTYPE),
+COMPATIBLE_IOCTL(KDSETMODE),
+COMPATIBLE_IOCTL(KDGETMODE),
+COMPATIBLE_IOCTL(KDSKBMODE),
+COMPATIBLE_IOCTL(KDGKBMODE),
+COMPATIBLE_IOCTL(KDSKBMETA),
+COMPATIBLE_IOCTL(KDGKBMETA),
+COMPATIBLE_IOCTL(KDGKBENT),
+COMPATIBLE_IOCTL(KDSKBENT),
+COMPATIBLE_IOCTL(KDGKBSENT),
+COMPATIBLE_IOCTL(KDSKBSENT),
+COMPATIBLE_IOCTL(KDGKBDIACR),
+COMPATIBLE_IOCTL(KDKBDREP),
+COMPATIBLE_IOCTL(KDSKBDIACR),
+COMPATIBLE_IOCTL(KDGKBLED),
+COMPATIBLE_IOCTL(KDSKBLED),
+COMPATIBLE_IOCTL(KDGETLED),
+COMPATIBLE_IOCTL(KDSETLED),
+COMPATIBLE_IOCTL(GIO_SCRNMAP),
+COMPATIBLE_IOCTL(PIO_SCRNMAP),
+COMPATIBLE_IOCTL(GIO_UNISCRNMAP),
+COMPATIBLE_IOCTL(PIO_UNISCRNMAP),
+COMPATIBLE_IOCTL(PIO_FONTRESET),
+COMPATIBLE_IOCTL(PIO_UNIMAPCLR),
+/* Big S */
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN),
+COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST),
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI),
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK),
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK),
+COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY),
+COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE),
+COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE),
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER),
+COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND),
+/* Big V */
+COMPATIBLE_IOCTL(VT_SETMODE),
+COMPATIBLE_IOCTL(VT_GETMODE),
+COMPATIBLE_IOCTL(VT_GETSTATE),
+COMPATIBLE_IOCTL(VT_OPENQRY),
+COMPATIBLE_IOCTL(VT_ACTIVATE),
+COMPATIBLE_IOCTL(VT_WAITACTIVE),
+COMPATIBLE_IOCTL(VT_RELDISP),
+COMPATIBLE_IOCTL(VT_DISALLOCATE),
+COMPATIBLE_IOCTL(VT_RESIZE),
+COMPATIBLE_IOCTL(VT_RESIZEX),
+COMPATIBLE_IOCTL(VT_LOCKSWITCH),
+COMPATIBLE_IOCTL(VT_UNLOCKSWITCH),
+/* Little v, the video4linux ioctls */
+COMPATIBLE_IOCTL(VIDIOCGCAP),
+COMPATIBLE_IOCTL(VIDIOCGCHAN),
+COMPATIBLE_IOCTL(VIDIOCSCHAN),
+COMPATIBLE_IOCTL(VIDIOCGPICT),
+COMPATIBLE_IOCTL(VIDIOCSPICT),
+COMPATIBLE_IOCTL(VIDIOCCAPTURE),
+COMPATIBLE_IOCTL(VIDIOCKEY),
+COMPATIBLE_IOCTL(VIDIOCGAUDIO),
+COMPATIBLE_IOCTL(VIDIOCSAUDIO),
+COMPATIBLE_IOCTL(VIDIOCSYNC),
+COMPATIBLE_IOCTL(VIDIOCMCAPTURE),
+COMPATIBLE_IOCTL(VIDIOCGMBUF),
+COMPATIBLE_IOCTL(VIDIOCGUNIT),
+COMPATIBLE_IOCTL(VIDIOCGCAPTURE),
+COMPATIBLE_IOCTL(VIDIOCSCAPTURE),
+/* BTTV specific... */
+COMPATIBLE_IOCTL(_IOW('v',  BASE_VIDIOCPRIVATE+0, char [256])),
+COMPATIBLE_IOCTL(_IOR('v',  BASE_VIDIOCPRIVATE+1, char [256])),
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)),
+COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])), /* struct bttv_pll_info */
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int)),
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int)),
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)),
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)),
+/* Little p (/dev/rtc, /dev/envctrl, etc.) */
+COMPATIBLE_IOCTL(_IOR('p', 20, int[7])), /* RTCGET */
+COMPATIBLE_IOCTL(_IOW('p', 21, int[7])), /* RTCSET */
+COMPATIBLE_IOCTL(RTC_AIE_ON),
+COMPATIBLE_IOCTL(RTC_AIE_OFF),
+COMPATIBLE_IOCTL(RTC_UIE_ON),
+COMPATIBLE_IOCTL(RTC_UIE_OFF),
+COMPATIBLE_IOCTL(RTC_PIE_ON),
+COMPATIBLE_IOCTL(RTC_PIE_OFF),
+COMPATIBLE_IOCTL(RTC_WIE_ON),
+COMPATIBLE_IOCTL(RTC_WIE_OFF),
+COMPATIBLE_IOCTL(RTC_ALM_SET),
+COMPATIBLE_IOCTL(RTC_ALM_READ),
+COMPATIBLE_IOCTL(RTC_RD_TIME),
+COMPATIBLE_IOCTL(RTC_SET_TIME),
+COMPATIBLE_IOCTL(RTC_WKALM_SET),
+COMPATIBLE_IOCTL(RTC_WKALM_RD),
+/* Little m */
+COMPATIBLE_IOCTL(MTIOCTOP),
+/* Socket level stuff */
+COMPATIBLE_IOCTL(FIOSETOWN),
+COMPATIBLE_IOCTL(SIOCSPGRP),
+COMPATIBLE_IOCTL(FIOGETOWN),
+COMPATIBLE_IOCTL(SIOCGPGRP),
+COMPATIBLE_IOCTL(SIOCATMARK),
+COMPATIBLE_IOCTL(SIOCSIFLINK),
+COMPATIBLE_IOCTL(SIOCSIFENCAP),
+COMPATIBLE_IOCTL(SIOCGIFENCAP),
+COMPATIBLE_IOCTL(SIOCSIFBR),
+COMPATIBLE_IOCTL(SIOCGIFBR),
+COMPATIBLE_IOCTL(SIOCSARP),
+COMPATIBLE_IOCTL(SIOCGARP),
+COMPATIBLE_IOCTL(SIOCDARP),
+COMPATIBLE_IOCTL(SIOCSRARP),
+COMPATIBLE_IOCTL(SIOCGRARP),
+COMPATIBLE_IOCTL(SIOCDRARP),
+COMPATIBLE_IOCTL(SIOCADDDLCI),
+COMPATIBLE_IOCTL(SIOCDELDLCI),
+/* SG stuff */
+COMPATIBLE_IOCTL(SG_SET_TIMEOUT),
+COMPATIBLE_IOCTL(SG_GET_TIMEOUT),
+COMPATIBLE_IOCTL(SG_EMULATED_HOST),
+COMPATIBLE_IOCTL(SG_SET_TRANSFORM),
+COMPATIBLE_IOCTL(SG_GET_TRANSFORM),
+COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE),
+COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE),
+COMPATIBLE_IOCTL(SG_GET_SCSI_ID),
+COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA),
+COMPATIBLE_IOCTL(SG_GET_LOW_DMA),
+COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID),
+COMPATIBLE_IOCTL(SG_GET_PACK_ID),
+COMPATIBLE_IOCTL(SG_GET_NUM_WAITING),
+COMPATIBLE_IOCTL(SG_SET_DEBUG),
+COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE),
+COMPATIBLE_IOCTL(SG_GET_COMMAND_Q),
+COMPATIBLE_IOCTL(SG_SET_COMMAND_Q),
+COMPATIBLE_IOCTL(SG_GET_VERSION_NUM),
+COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN),
+COMPATIBLE_IOCTL(SG_SCSI_RESET),
+COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE),
+COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN),
+COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN),
+/* PPP stuff */
+COMPATIBLE_IOCTL(PPPIOCGFLAGS),
+COMPATIBLE_IOCTL(PPPIOCSFLAGS),
+COMPATIBLE_IOCTL(PPPIOCGASYNCMAP),
+COMPATIBLE_IOCTL(PPPIOCSASYNCMAP),
+COMPATIBLE_IOCTL(PPPIOCGUNIT),
+COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP),
+COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP),
+COMPATIBLE_IOCTL(PPPIOCGMRU),
+COMPATIBLE_IOCTL(PPPIOCSMRU),
+COMPATIBLE_IOCTL(PPPIOCSMAXCID),
+COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP),
+COMPATIBLE_IOCTL(LPGETSTATUS),
+COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP),
+COMPATIBLE_IOCTL(PPPIOCXFERUNIT),
+COMPATIBLE_IOCTL(PPPIOCGNPMODE),
+COMPATIBLE_IOCTL(PPPIOCSNPMODE),
+COMPATIBLE_IOCTL(PPPIOCGDEBUG),
+COMPATIBLE_IOCTL(PPPIOCSDEBUG),
+COMPATIBLE_IOCTL(PPPIOCNEWUNIT),
+COMPATIBLE_IOCTL(PPPIOCATTACH),
+COMPATIBLE_IOCTL(PPPIOCDETACH),
+COMPATIBLE_IOCTL(PPPIOCSMRRU),
+COMPATIBLE_IOCTL(PPPIOCCONNECT),
+COMPATIBLE_IOCTL(PPPIOCDISCONN),
+COMPATIBLE_IOCTL(PPPIOCATTCHAN),
+COMPATIBLE_IOCTL(PPPIOCGCHAN),
+/* PPPOX */
+COMPATIBLE_IOCTL(PPPOEIOCSFWD),
+COMPATIBLE_IOCTL(PPPOEIOCDFWD),
+/* CDROM stuff */
+COMPATIBLE_IOCTL(CDROMPAUSE),
+COMPATIBLE_IOCTL(CDROMRESUME),
+COMPATIBLE_IOCTL(CDROMPLAYMSF),
+COMPATIBLE_IOCTL(CDROMPLAYTRKIND),
+COMPATIBLE_IOCTL(CDROMREADCOOKED),
+COMPATIBLE_IOCTL(CDROMREADMODE1),
+COMPATIBLE_IOCTL(CDROMREADMODE2),
+COMPATIBLE_IOCTL(CDROMREADRAW),
+COMPATIBLE_IOCTL(CDROMREADTOCHDR),
+COMPATIBLE_IOCTL(CDROMREADTOCENTRY),
+COMPATIBLE_IOCTL(CDROMSTOP),
+COMPATIBLE_IOCTL(CDROMSTART),
+COMPATIBLE_IOCTL(CDROMEJECT),
+COMPATIBLE_IOCTL(CDROMVOLCTRL),
+COMPATIBLE_IOCTL(CDROMSUBCHNL),
+COMPATIBLE_IOCTL(CDROMEJECT_SW),
+COMPATIBLE_IOCTL(CDROMMULTISESSION),
+COMPATIBLE_IOCTL(CDROM_GET_MCN),
+COMPATIBLE_IOCTL(CDROMRESET),
+COMPATIBLE_IOCTL(CDROMVOLREAD),
+COMPATIBLE_IOCTL(CDROMSEEK),
+COMPATIBLE_IOCTL(CDROMPLAYBLK),
+COMPATIBLE_IOCTL(CDROMCLOSETRAY),
+COMPATIBLE_IOCTL(CDROM_SET_OPTIONS),
+COMPATIBLE_IOCTL(CDROM_CLEAR_OPTIONS),
+COMPATIBLE_IOCTL(CDROM_SELECT_SPEED),
+COMPATIBLE_IOCTL(CDROM_SELECT_DISC),
+COMPATIBLE_IOCTL(CDROM_MEDIA_CHANGED),
+COMPATIBLE_IOCTL(CDROM_DRIVE_STATUS),
+COMPATIBLE_IOCTL(CDROM_DISC_STATUS),
+COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS),
+COMPATIBLE_IOCTL(CDROM_LOCKDOOR),
+COMPATIBLE_IOCTL(CDROM_DEBUG),
+COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY),
+/* DVD ioctls */
+COMPATIBLE_IOCTL(DVD_READ_STRUCT),
+COMPATIBLE_IOCTL(DVD_WRITE_STRUCT),
+COMPATIBLE_IOCTL(DVD_AUTH),
+/* Big L */
+COMPATIBLE_IOCTL(LOOP_SET_FD),
+COMPATIBLE_IOCTL(LOOP_CLR_FD),
+/* Big Q for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC),
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE),
+COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS),
+COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD),
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL),
+COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND),
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME),
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID),
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL),
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE),
+/* Big T for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE),
+COMPATIBLE_IOCTL(SNDCTL_TMR_START),
+COMPATIBLE_IOCTL(SNDCTL_TMR_STOP),
+COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE),
+COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO),
+COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE),
+COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME),
+COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT),
+/* Little m for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME),
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE),
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD),
+/* Big P for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_DSP_RESET),
+COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC),
+COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED),
+COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE),
+COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS),
+COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER),
+COMPATIBLE_IOCTL(SNDCTL_DSP_POST),
+COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE),
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS),
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE),
+COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER),
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR),
+/* SNDCTL_DSP_MAPINBUF,  XXX needs translation */
+/* SNDCTL_DSP_MAPOUTBUF,  XXX needs translation */
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO),
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX),
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY),
+COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE),
+COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE),
+COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS),
+COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS),
+COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER),
+/* Big C for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_COPR_RESET),
+COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD),
+COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA),
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE),
+COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA),
+COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE),
+COMPATIBLE_IOCTL(SNDCTL_COPR_RUN),
+COMPATIBLE_IOCTL(SNDCTL_COPR_HALT),
+COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG),
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG),
+/* Big M for sound/OSS */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3),
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1)),
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2)),
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3)),
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN)),
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT)),
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO)),
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO)),
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR)),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE),
+/* SOUND_MIXER_READ_ENHANCE,  same value as READ_MUTE */
+/* SOUND_MIXER_READ_LOUD,  same value as READ_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS),
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3),
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1)),
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2)),
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3)),
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN)),
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT)),
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO)),
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO)),
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR)),
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE),
+/* SOUND_MIXER_WRITE_ENHANCE,  same value as WRITE_MUTE */
+/* SOUND_MIXER_WRITE_LOUD,  same value as WRITE_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC),
+COMPATIBLE_IOCTL(SOUND_MIXER_INFO),
+COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO),
+COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS),
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1),
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2),
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3),
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4),
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5),
+COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS),
+COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS),
+COMPATIBLE_IOCTL(OSS_GETVERSION),
+/* AUTOFS */
+COMPATIBLE_IOCTL(AUTOFS_IOC_READY),
+COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL),
+COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC),
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER),
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE),
+/* DEVFS */
+COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV),
+COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK),
+COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE),
+COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK),
+/* Raw devices */
+COMPATIBLE_IOCTL(RAW_SETBIND),
+COMPATIBLE_IOCTL(RAW_GETBIND),
+/* SMB ioctls which do not need any translations */
+COMPATIBLE_IOCTL(SMB_IOC_NEWCONN),
+/* Little a */
+COMPATIBLE_IOCTL(ATMSIGD_CTRL),
+COMPATIBLE_IOCTL(ATMARPD_CTRL),
+COMPATIBLE_IOCTL(ATMLEC_CTRL),
+COMPATIBLE_IOCTL(ATMLEC_MCAST),
+COMPATIBLE_IOCTL(ATMLEC_DATA),
+COMPATIBLE_IOCTL(ATM_SETSC),
+COMPATIBLE_IOCTL(SIOCSIFATMTCP),
+COMPATIBLE_IOCTL(SIOCMKCLIP),
+COMPATIBLE_IOCTL(ATMARP_MKIP),
+COMPATIBLE_IOCTL(ATMARP_SETENTRY),
+COMPATIBLE_IOCTL(ATMARP_ENCAP),
+COMPATIBLE_IOCTL(ATMTCP_CREATE),
+COMPATIBLE_IOCTL(ATMTCP_REMOVE),
+COMPATIBLE_IOCTL(ATMMPC_CTRL),
+COMPATIBLE_IOCTL(ATMMPC_DATA),
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* 0xfe - lvm */
+COMPATIBLE_IOCTL(VG_SET_EXTENDABLE),
+COMPATIBLE_IOCTL(VG_STATUS_GET_COUNT),
+COMPATIBLE_IOCTL(VG_STATUS_GET_NAMELIST),
+COMPATIBLE_IOCTL(VG_REMOVE),
+COMPATIBLE_IOCTL(VG_RENAME),
+COMPATIBLE_IOCTL(VG_REDUCE),
+COMPATIBLE_IOCTL(PE_LOCK_UNLOCK),
+COMPATIBLE_IOCTL(PV_FLUSH),
+COMPATIBLE_IOCTL(LVM_LOCK_LVM),
+COMPATIBLE_IOCTL(LVM_GET_IOP_VERSION),
+#ifdef LVM_TOTAL_RESET
+COMPATIBLE_IOCTL(LVM_RESET),
+#endif
+COMPATIBLE_IOCTL(LV_SET_ACCESS),
+COMPATIBLE_IOCTL(LV_SET_STATUS),
+COMPATIBLE_IOCTL(LV_SET_ALLOCATION),
+COMPATIBLE_IOCTL(LE_REMAP),
+COMPATIBLE_IOCTL(LV_BMAP),
+COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE),
+#endif /* LVM */
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC),
+COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID),
+COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC),
+COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK),
+COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK),
+COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL),
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS),
+COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS),
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX),
+COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX),
+COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX),
+COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX),
+COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX),
+COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX),
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW),
+COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW),
+COMPATIBLE_IOCTL(DRM_IOCTL_LOCK),
+COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK),
+COMPATIBLE_IOCTL(DRM_IOCTL_FINISH),
+#endif /* DRM */
+/* elevator */
+COMPATIBLE_IOCTL(BLKELVGET),
+COMPATIBLE_IOCTL(BLKELVSET),
+/* Big W */
+/* WIOC_GETSUPPORT not yet implemented -E */
+COMPATIBLE_IOCTL(WDIOC_GETSTATUS),
+COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS),
+COMPATIBLE_IOCTL(WDIOC_GETTEMP),
+COMPATIBLE_IOCTL(WDIOC_SETOPTIONS),
+COMPATIBLE_IOCTL(WDIOC_KEEPALIVE),
+/* Bluetooth ioctls */
+COMPATIBLE_IOCTL(HCIDEVUP),
+COMPATIBLE_IOCTL(HCIDEVDOWN),
+COMPATIBLE_IOCTL(HCIDEVRESET),
+COMPATIBLE_IOCTL(HCIGETDEVLIST),
+COMPATIBLE_IOCTL(HCISETRAW),
+COMPATIBLE_IOCTL(HCISETSCAN),
+COMPATIBLE_IOCTL(HCISETAUTH),
+COMPATIBLE_IOCTL(HCIINQUIRY),
+COMPATIBLE_IOCTL(PCIIOC_CONTROLLER),
+COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO),
+COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM),
+COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE),
+/* USB */
+COMPATIBLE_IOCTL(USBDEVFS_RESETEP),
+COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE),
+COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION),
+COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER),
+COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB),
+COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE),
+COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE),
+COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO),
+COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO),
+COMPATIBLE_IOCTL(USBDEVFS_RESET),
+COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT),
+/* MTD */
+COMPATIBLE_IOCTL(MEMGETINFO),
+COMPATIBLE_IOCTL(MEMERASE),
+COMPATIBLE_IOCTL(MEMLOCK),
+COMPATIBLE_IOCTL(MEMUNLOCK),
+COMPATIBLE_IOCTL(MEMGETREGIONCOUNT),
+COMPATIBLE_IOCTL(MEMGETREGIONINFO),
+/* NBD */
+COMPATIBLE_IOCTL(NBD_SET_SOCK),
+COMPATIBLE_IOCTL(NBD_SET_BLKSIZE),
+COMPATIBLE_IOCTL(NBD_SET_SIZE),
+COMPATIBLE_IOCTL(NBD_DO_IT),
+COMPATIBLE_IOCTL(NBD_CLEAR_SOCK),
+COMPATIBLE_IOCTL(NBD_CLEAR_QUE),
+COMPATIBLE_IOCTL(NBD_PRINT_DEBUG),
+COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS),
+COMPATIBLE_IOCTL(NBD_DISCONNECT),
+/* Remove *PRIVATE in 2.5 */
+COMPATIBLE_IOCTL(SIOCDEVPRIVATE),
+COMPATIBLE_IOCTL(SIOCDEVPRIVATE+1),
+COMPATIBLE_IOCTL(SIOCDEVPRIVATE+2),
+COMPATIBLE_IOCTL(SIOCGMIIPHY),
+COMPATIBLE_IOCTL(SIOCGMIIREG),
+COMPATIBLE_IOCTL(SIOCSMIIREG),
+/* And these ioctls need translation */
+HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob),
+HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob),
+#ifdef CONFIG_NET
+HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32),
+#endif
+HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf),
+HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc),
+HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc),
+HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl),
+HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl),
+HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl),
+HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl),
+HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl),
+HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl),
+HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl),
+HANDLE_IOCTL(SIOCADDRT, routing_ioctl),
+HANDLE_IOCTL(SIOCDELRT, routing_ioctl),
+/* Note SIOCRTMSG is no longer, so this is safe and
+ * the user would have seen just an -EINVAL anyways. */
+HANDLE_IOCTL(SIOCRTMSG, ret_einval),
+HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp),
+HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo),
+HANDLE_IOCTL(BLKRAGET, w_long),
+HANDLE_IOCTL(BLKGETSIZE, w_long),
+HANDLE_IOCTL(0x1260, broken_blkgetsize),
+HANDLE_IOCTL(BLKFRAGET, w_long),
+HANDLE_IOCTL(BLKSECTGET, w_long),
+HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans),
+HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDSETDRVPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDGETDRVPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans),
+HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans),
+HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans),
+HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans),
+HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans),
+HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans),
+HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans),
+HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans),
+HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans),
+HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans),
+HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans),
+HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans),
+HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans),
+HANDLE_IOCTL(LOOP_SET_STATUS, loop_status),
+HANDLE_IOCTL(LOOP_GET_STATUS, loop_status),
+HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
+#ifdef CONFIG_VT
+HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl),
+HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl),
+HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl),
+HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl),
+HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl),
+HANDLE_IOCTL(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl),
+HANDLE_IOCTL(FBIOGETCMAP, do_fbiogetcmap_ioctl),
+HANDLE_IOCTL(FBIOPUTCMAP, do_fbioputcmap_ioctl),
+#endif
+HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
+HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
+HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
+HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
+HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCSWIN32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl),
+/* One SMB ioctl needs translations. */
+HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid),
+HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl),
+HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl),
+HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl),
+HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl),
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+HANDLE_IOCTL(VG_STATUS, do_lvm_ioctl),
+HANDLE_IOCTL(VG_CREATE_OLD, do_lvm_ioctl),
+HANDLE_IOCTL(VG_CREATE, do_lvm_ioctl),
+HANDLE_IOCTL(VG_EXTEND, do_lvm_ioctl),
+HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl),
+HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl),
+HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl),
+HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl),
+HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl),
+HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl),
+HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl),
+HANDLE_IOCTL(LV_STATUS_BYDEV, do_lvm_ioctl),
+HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl),
+HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl),
+#endif /* LVM */
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version),
+HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique),
+HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique),
+HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap),
+HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs),
+HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs),
+HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs),
+HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma),
+HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx),
+#endif /* DRM */
+HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control),
+HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk),
+/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
+HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb),
+HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb),
+HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal),
+HANDLE_IOCTL(SG_IO, do_sg_io),
+};
+
+unsigned long ioctl32_hash_table[1024];
+
+static inline unsigned long ioctl32_hash(unsigned long cmd)
+{
+	return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
+}
+
+static void ioctl32_insert_translation(struct ioctl_trans *trans)
+{
+	unsigned long hash;
+	struct ioctl_trans *t;
+
+	hash = ioctl32_hash (trans->cmd);
+	if (!ioctl32_hash_table[hash])
+		ioctl32_hash_table[hash] = (long)trans;
+	else {
+		t = (struct ioctl_trans *)ioctl32_hash_table[hash];
+		while (t->next)
+			t = (struct ioctl_trans *)(long)t->next;
+		trans->next = 0;
+		t->next = (long)trans;
+	}
+}
+
+static int __init init_sys32_ioctl(void)
+{
+        int i, size = sizeof(ioctl_translations) / sizeof(struct ioctl_trans);
+        for (i=0; i < size ;i++)
+                ioctl32_insert_translation(&ioctl_translations[i]);
+	return 0;
+}
+
+__initcall(init_sys32_ioctl);
+
+static struct ioctl_trans *additional_ioctls;
+
+/* Always call these with kernel lock held! */
+
+int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *))
+{
+	int i;
+	if (!additional_ioctls) {
+		additional_ioctls = module_map(PAGE_SIZE);
+		if (!additional_ioctls)
+			return -ENOMEM;
+		memset(additional_ioctls, 0, PAGE_SIZE);
+	}
+	for (i = 0; i < PAGE_SIZE/sizeof(struct ioctl_trans); i++)
+		if (!additional_ioctls[i].cmd)
+			break;
+	if (i == PAGE_SIZE/sizeof(struct ioctl_trans))
+		return -ENOMEM;
+	additional_ioctls[i].cmd = cmd;
+	if (!handler)
+		additional_ioctls[i].handler = (long)sys_ioctl;
+	else
+		additional_ioctls[i].handler = (long)handler;
+	ioctl32_insert_translation(&additional_ioctls[i]);
+	return 0;
+}
+
+int unregister_ioctl32_conversion(unsigned int cmd)
+{
+	unsigned long hash = ioctl32_hash(cmd);
+	struct ioctl_trans *t, *t1;
+
+	t = (struct ioctl_trans *)ioctl32_hash_table[hash];
+	if (!t) return -EINVAL;
+	if (t->cmd == cmd && t >= additional_ioctls &&
+	    (unsigned long)t < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
+		ioctl32_hash_table[hash] = t->next;
+		t->cmd = 0;
+		return 0;
+	} else while (t->next) {
+		t1 = (struct ioctl_trans *)t->next;
+		if (t1->cmd == cmd && t1 >= additional_ioctls &&
+		    (unsigned long)t1 < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
+			t1->cmd = 0;
+			t->next = t1->next;
+			return 0;
+		}
+		t = t1;
+	}
+	return -EINVAL;
+}
+
+asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct file * filp;
+	int error = -EBADF;
+	int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
+	struct ioctl_trans *t;
+
+	filp = fget(fd);
+	if (!filp)
+		goto out2;
+
+	if (!filp->f_op || !filp->f_op->ioctl) {
+		error = sys_ioctl (fd, cmd, arg);
+		goto out;
+	}
+
+	t = (struct ioctl_trans *)ioctl32_hash_table [ioctl32_hash (cmd)];
+
+	while (t && t->cmd != cmd)
+		t = (struct ioctl_trans *)t->next;
+	if (t) {
+		handler = (void *)t->handler;
+		error = handler(fd, cmd, arg, filp);
+	} else {
+		static int count = 0;
+		if (++count <= 20)
+			printk("sys32_ioctl(%s:%d): Unknown cmd fd(%d) "
+			       "cmd(%08x) arg(%08x)\n",
+			       current->comm, current->pid,
+			       (int)fd, (unsigned int)cmd, (unsigned int)arg);
+		error = -EINVAL;
+	}
+out:
+	fput(filp);
+out2:
+	return error;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/irq.c linux/arch/ppc64/kernel/irq.c
--- linux.orig/arch/ppc64/kernel/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/irq.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,973 @@
+/*
+ * 
+ *
+ *  arch/ppc/kernel/irq.c
+ *
+ *  Derived from arch/i386/kernel/irq.c
+ *    Copyright (C) 1992 Linus Torvalds
+ *  Adapted from arch/i386 by Gary Thomas
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *  Updated and modified by Cort Dougan (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Cort Dougan
+ *  Adapted for Power Macintosh by Paul Mackerras
+ *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * This file contains the code used by various IRQ handling routines:
+ * asking for different IRQ's should be done through these routines
+ * instead of just grabbing them. Thus setups with different IRQ numbers
+ * shouldn't result in any weird surprises, and installing new handlers
+ * should be easier.
+ */
+
+
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/threads.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/proc_fs.h>
+#include <linux/random.h>
+
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/cache.h>
+#include <asm/prom.h>
+#include <asm/ptrace.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/machdep.h>
+#include <asm/paca.h>
+
+#include "local_irq.h"
+
+atomic_t ipi_recv;
+atomic_t ipi_sent;
+void enable_irq(unsigned int irq_nr);
+void disable_irq(unsigned int irq_nr);
+
+#ifdef CONFIG_SMP
+extern void iSeries_smp_message_recv( struct pt_regs * );
+#endif
+
+volatile unsigned char *chrp_int_ack_special;
+static void register_irq_proc (unsigned int irq);
+
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+	{ [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}};
+	
+int ppc_spurious_interrupts = 0;
+struct irqaction *ppc_irq_action[NR_IRQS];
+unsigned long lpEvent_count = 0;
+#ifdef CONFIG_XMON
+extern void xmon(struct pt_regs *regs);
+extern int xmon_bpt(struct pt_regs *regs);
+extern int xmon_sstep(struct pt_regs *regs);
+extern int xmon_iabr_match(struct pt_regs *regs);
+extern int xmon_dabr_match(struct pt_regs *regs);
+extern void (*xmon_fault_handler)(struct pt_regs *regs);
+#endif
+#ifdef CONFIG_XMON
+extern void (*debugger)(struct pt_regs *regs);
+extern int (*debugger_bpt)(struct pt_regs *regs);
+extern int (*debugger_sstep)(struct pt_regs *regs);
+extern int (*debugger_iabr_match)(struct pt_regs *regs);
+extern int (*debugger_dabr_match)(struct pt_regs *regs);
+extern void (*debugger_fault_handler)(struct pt_regs *regs);
+#endif
+
+/* nasty hack for shared irq's since we need to do kmalloc calls but
+ * can't very early in the boot when we need to do a request irq.
+ * this needs to be removed.
+ * -- Cort
+ */
+#define IRQ_KMALLOC_ENTRIES 8
+static int cache_bitmask = 0;
+static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
+extern int mem_init_done;
+
+void *irq_kmalloc(size_t size, int pri)
+{
+	unsigned int i;
+	if ( mem_init_done )
+		return kmalloc(size,pri);
+	for ( i = 0; i < IRQ_KMALLOC_ENTRIES ; i++ )
+		if ( ! ( cache_bitmask & (1<<i) ) ) {
+			cache_bitmask |= (1<<i);
+			return (void *)(&malloc_cache[i]);
+		}
+	return 0;
+}
+
+void irq_kfree(void *ptr)
+{
+	unsigned int i;
+	for ( i = 0 ; i < IRQ_KMALLOC_ENTRIES ; i++ )
+		if ( ptr == &malloc_cache[i] ) {
+			cache_bitmask &= ~(1<<i);
+			return;
+		}
+	kfree(ptr);
+}
+
+int
+setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	unsigned long flags;
+	struct irqaction *old, **p;
+	irq_desc_t *desc = irq_desc + irq;
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&desc->lock,flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->depth = 0;
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+		unmask_irq(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+
+	register_irq_proc(irq);
+	return 0;
+}
+
+/* This could be promoted to a real free_irq() ... */
+static int
+do_free_irq(int irq, void* dev_id)
+{
+	irq_desc_t *desc;
+	struct irqaction **p;
+	unsigned long flags;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	for (;;) {
+		struct irqaction * action = *p;
+		if (action) {
+			struct irqaction **pp = p;
+			p = &action->next;
+			if (action->dev_id != dev_id)
+				continue;
+
+			/* Found it - now remove it from the list of entries */
+			*pp = action->next;
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				mask_irq(irq);
+			}
+			spin_unlock_irqrestore(&desc->lock,flags);
+
+#ifdef CONFIG_SMP
+			/* Wait to make sure it's not being used on another CPU */
+			while (desc->status & IRQ_INPROGRESS)
+				barrier();
+#endif
+			irq_kfree(action);
+			return 0;
+		}
+		printk("Trying to free free IRQ%d\n",irq);
+		spin_unlock_irqrestore(&desc->lock,flags);
+		break;
+	}
+	return -ENOENT;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+	unsigned long irqflags, const char * devname, void *dev_id)
+{
+	struct irqaction *action;
+	int retval;
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+	if (!handler)
+		/* We could implement really free_irq() instead of that... */
+		return do_free_irq(irq, dev_id);
+	
+	action = (struct irqaction *)
+		irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action) {
+		printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq);
+		return -ENOMEM;
+	}
+	
+	action->handler = handler;
+	action->flags = irqflags;					
+	action->mask = 0;
+	action->name = devname;
+	action->dev_id = dev_id;
+	action->next = NULL;
+	
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+		
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	request_irq(irq, NULL, 0, NULL, dev_id);
+}
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock. 
+ */
+ 
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+ void disable_irq_nosync(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		if (!(desc->status & IRQ_PER_CPU))
+			desc->status |= IRQ_DISABLED;
+		mask_irq(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. That is for two disables you need two enables. This
+ *	function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+ 
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *	providing no disable_irq calls are now in effect.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void enable_irq(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
+	case 1: {
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
+		}
+		unmask_irq(irq);
+		/* fall-through */
+	}
+	default:
+		desc->depth--;
+		break;
+	case 0:
+		printk("enable_irq(%u) unbalanced\n", irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/* one would think this function has one foot in the grave */
+int get_irq_list(char *buf)
+{
+   int i, len = 0, j;
+   struct irqaction * action;
+
+   len += sprintf(buf+len, "           ");
+   for (j=0; j<smp_num_cpus; j++)
+       len += sprintf(buf+len, "CPU%d       ",j);
+   *(char *)(buf+len++) = '\n';
+
+   for (i = 0 ; i < NR_IRQS ; i++) {
+       action = irq_desc[i].action;
+       if ( !action || !action->handler )
+           continue;
+       len += sprintf(buf+len, "%3d: ", i);
+#ifdef CONFIG_SMP
+       for (j = 0; j < smp_num_cpus; j++)
+           len += sprintf(buf+len, "%10u ",
+               kstat.irqs[cpu_logical_map(j)][i]);
+#else
+       len += sprintf(buf+len, "%10u ", kstat_irqs(i));
+#endif /* CONFIG_SMP */
+if ( irq_desc[i].handler )
+len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
+else
+len += sprintf(buf+len, "  None      ");
+len += sprintf(buf+len, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
+len += sprintf(buf+len, "    %s",action->name);
+for (action=action->next; action; action = action->next) {
+len += sprintf(buf+len, ", %s", action->name);
+}
+len += sprintf(buf+len, "\n");
+}
+#ifdef CONFIG_SMP
+/* should this be per processor send/receive? */
+len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n",
+atomic_read(&ipi_recv), atomic_read(&ipi_sent));
+#endif
+len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts);
+return len;
+}
+
+
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i, j;
+	struct irqaction * action;
+
+	seq_printf(p, "           ");
+	for (j=0; j<smp_num_cpus; j++)
+		seq_printf(p, "CPU%d       ",j);
+	seq_putc(p, '\n');
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+		action = irq_desc[i].action;
+		if (!action || !action->handler)
+			continue;
+		seq_printf(p, "%3d: ", i);		
+#ifdef CONFIG_SMP
+		for (j = 0; j < smp_num_cpus; j++)
+			seq_printf(p, "%10u ",
+				kstat.irqs[cpu_logical_map(j)][i]);
+#else		
+		seq_printf(p, "%10u ", kstat_irqs(i));
+#endif /* CONFIG_SMP */
+		if (irq_desc[i].handler)		
+			seq_printf(p, " %s ", irq_desc[i].handler->typename );
+		else
+			seq_printf(p, "  None      ");
+		seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
+		seq_printf(p, "    %s",action->name);
+		for (action=action->next; action; action = action->next)
+			seq_printf(p, ", %s", action->name);
+		seq_putc(p, '\n');
+	}
+#ifdef CONFIG_SMP
+	/* should this be per processor send/receive? */
+	seq_printf(p, "IPI (recv/sent): %10u/%u\n",
+		       atomic_read(&ipi_recv), atomic_read(&ipi_sent));
+#endif		
+	seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
+	return 0;
+}
+
+static inline void
+handle_irq_event(int irq, struct pt_regs *regs, struct irqaction *action)
+{
+	int status = 0;
+
+	if (!(action->flags & SA_INTERRUPT))
+		__sti();
+
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+	__cli();
+}
+
+/*
+ * Eventually, this should take an array of interrupts and an array size
+ * so it can dispatch multiple interrupts.
+ */
+void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
+{
+	int status;
+	struct irqaction *action;
+	int cpu = smp_processor_id();
+	irq_desc_t *desc = irq_desc + irq;
+
+	kstat.irqs[cpu][irq]++;
+	spin_lock(&desc->lock);
+	ack_irq(irq);	
+	/*
+	   REPLAY is when Linux resends an IRQ that was dropped earlier
+	   WAITING is used by probe to mark irqs that are being tested
+	   */
+	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+	if (!(status & IRQ_PER_CPU))
+		status |= IRQ_PENDING; /* we _want_ to handle it */
+
+	/*
+	 * If the IRQ is disabled for whatever reason, we cannot
+	 * use the action we have.
+	 */
+	action = NULL;
+	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		if (!action || !action->handler) {
+			ppc_spurious_interrupts++;
+			printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
+			/* We can't call disable_irq here, it would deadlock */
+			if (!desc->depth)
+				desc->depth = 1;
+			desc->status |= IRQ_DISABLED;
+			/* This is not a real spurrious interrupt, we
+			 * have to eoi it, so we jump to out
+			 */
+			mask_irq(irq);
+			goto out;
+		}
+		status &= ~IRQ_PENDING; /* we commit to handling */
+		if (!(status & IRQ_PER_CPU))
+			status |= IRQ_INPROGRESS; /* we are handling it */
+	}
+	desc->status = status;
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	   Since we set PENDING, if another processor is handling
+	   a different instance of this same irq, the other processor
+	   will take care of it.
+	 */
+	if (!action)
+		goto out;
+
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events.
+	 * This applies to any hw interrupts that allow a second
+	 * instance of the same irq to arrive while we are in do_IRQ
+	 * or in the handler. But the code here only handles the _second_
+	 * instance of the irq, not the third or fourth. So it is mostly
+	 * useful for irq hardware that does not mask cleanly in an
+	 * SMP environment.
+	 */
+	for (;;) {
+		spin_unlock(&desc->lock);
+		handle_irq_event(irq, regs, action);
+		spin_lock(&desc->lock);
+		
+		if (!(desc->status & IRQ_PENDING))
+			break;
+		desc->status &= ~IRQ_PENDING;
+	}
+	desc->status &= ~IRQ_INPROGRESS;
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	if (irq_desc[irq].handler) {
+		if (irq_desc[irq].handler->end)
+			irq_desc[irq].handler->end(irq);
+		else if (irq_desc[irq].handler->enable)
+			irq_desc[irq].handler->enable(irq);
+	}
+	spin_unlock(&desc->lock);
+}
+
+int do_IRQ(struct pt_regs *regs, int isfake)
+{
+	int cpu = smp_processor_id();
+	int irq;
+	struct paca_struct *lpaca;
+	struct ItLpQueue * lpq;
+
+	/* if(cpu) udbg_printf("Entering do_IRQ\n");  */
+
+        irq_enter(cpu);
+
+	if (naca->platform != PLATFORM_ISERIES_LPAR) {
+	
+		/* every arch is required to have a get_irq -- Cort */
+		irq = ppc_md.get_irq( regs );
+
+		if ( irq >= 0 ) {
+			ppc_irq_dispatch_handler( regs, irq );
+			if (ppc_md.post_irq)
+				ppc_md.post_irq( regs, irq );
+		} else {
+			/* -2 means ignore, already handled */
+			if (irq != -2) {
+				printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
+					irq, regs->nip);
+				ppc_spurious_interrupts++;
+			}
+		}
+	}
+	/* if on iSeries partition */
+	else {
+		lpaca = get_paca();
+#ifdef CONFIG_SMP
+		if ( lpaca->xLpPaca.xIntDword.xFields.xIpiCnt ) {
+			lpaca->xLpPaca.xIntDword.xFields.xIpiCnt = 0;
+			iSeries_smp_message_recv( regs );
+		}
+#endif /* CONFIG_SMP */
+		lpq = lpaca->lpQueuePtr;
+		if ( lpq && ItLpQueue_isLpIntPending( lpq ) )
+			lpEvent_count += ItLpQueue_process( lpq, regs );
+	}
+		
+        irq_exit(cpu);
+
+	if (naca->platform == PLATFORM_ISERIES_LPAR) {
+		if ( lpaca->xLpPaca.xIntDword.xFields.xDecrInt ) {
+			lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
+			/* Signal a fake decrementer interrupt */
+			timer_interrupt( regs );
+		}
+	}
+
+	if (softirq_pending(cpu))
+		do_softirq();
+
+	return 1; /* lets ret_from_int know we can do checks */
+}
+
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+unsigned int probe_irq_mask(unsigned long irqs)
+{
+	return 0;
+}
+
+void __init init_IRQ(void)
+{
+	static int once = 0;
+
+	if ( once )
+		return;
+	else
+		once++;
+	
+	ppc_md.init_IRQ();
+	if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ(); 
+}
+
+#ifdef CONFIG_SMP
+unsigned char global_irq_holder = NO_PROC_ID;
+
+static void show(char * str)
+{
+	int cpu = smp_processor_id();
+	int i;
+
+	printk("\n%s, CPU %d:\n", str, cpu);
+	printk("irq:  %d [ ", irqs_running());
+	for (i = 0; i < smp_num_cpus; i++)
+		printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]);
+	printk("]\nbh:   %d [ ",
+		(spin_is_locked(&global_bh_lock) ? 1 : 0));
+	for (i = 0; i < smp_num_cpus; i++)
+		printk("%u ", local_bh_count(i));
+	printk("]\n");
+}
+
+#define MAXCOUNT 10000000
+
+void synchronize_irq(void)
+{
+	if (irqs_running()) {
+		cli();
+		sti();
+	}
+}
+
+static inline void get_irqlock(int cpu)
+{
+        int count;
+
+        if ((unsigned char)cpu == global_irq_holder)
+                return;
+
+        count = MAXCOUNT;
+again:
+        br_write_lock(BR_GLOBALIRQ_LOCK);
+        for (;;) {
+                spinlock_t *lock;
+
+                if (!irqs_running() &&
+                    (local_bh_count(smp_processor_id()) || !spin_is_locked(&global_bh_lock)))
+                        break;
+
+                br_write_unlock(BR_GLOBALIRQ_LOCK);
+                lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
+                while (irqs_running() ||
+                       spin_is_locked(lock) ||
+                       (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) {
+                        if (!--count) {
+                                show("get_irqlock");
+                                count = (~0 >> 1);
+                        }
+                        __sti();
+                        barrier();
+                        __cli();
+                }
+                goto again;
+        }
+
+        global_irq_holder = cpu;
+}
+
+/*
+ * A global "cli()" while in an interrupt context
+ * turns into just a local cli(). Interrupts
+ * should use spinlocks for the (very unlikely)
+ * case that they ever want to protect against
+ * each other.
+ *
+ * If we already have local interrupts disabled,
+ * this will not turn a local disable into a
+ * global one (problems with spinlocks: this makes
+ * save_flags+cli+sti usable inside a spinlock).
+ */
+void __global_cli(void)
+{
+	unsigned long flags;
+	
+	__save_flags(flags);
+	if (flags & (1UL << 15)) {
+		int cpu = smp_processor_id();
+		__cli();
+		if (!local_irq_count(cpu))
+			get_irqlock(cpu);
+	}
+}
+
+void __global_sti(void)
+{
+	int cpu = smp_processor_id();
+
+	if (!local_irq_count(cpu))
+		release_irqlock(cpu);
+	__sti();
+}
+
+/*
+ * SMP flags value to restore to:
+ * 0 - global cli
+ * 1 - global sti
+ * 2 - local cli
+ * 3 - local sti
+ */
+unsigned long __global_save_flags(void)
+{
+	int retval;
+	int local_enabled;
+	unsigned long flags;
+
+	__save_flags(flags);
+	local_enabled = (flags >> 15) & 1;
+	/* default to local */
+	retval = 2 + local_enabled;
+
+	/* check for global flags if we're not in an interrupt */
+	if (!local_irq_count(smp_processor_id())) {
+		if (local_enabled)
+			retval = 1;
+		if (global_irq_holder == (unsigned char) smp_processor_id())
+			retval = 0;
+	}
+	return retval;
+}
+
+void __global_restore_flags(unsigned long flags)
+{
+	switch (flags) {
+	case 0:
+		__global_cli();
+		break;
+	case 1:
+		__global_sti();
+		break;
+	case 2:
+		__cli();
+		break;
+	case 3:
+		__sti();
+		break;
+	default:
+		printk("global_restore_flags: %016lx caller %p\n",
+			flags, __builtin_return_address(0));
+	}
+}
+
+#endif /* CONFIG_SMP */
+
+static struct proc_dir_entry * root_irq_dir;
+static struct proc_dir_entry * irq_dir [NR_IRQS];
+static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+
+#ifdef CONFIG_IRQ_ALL_CPUS
+unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff};
+#else  /* CONFIG_IRQ_ALL_CPUS */
+unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000};
+#endif /* CONFIG_IRQ_ALL_CPUS */
+
+#define HEX_DIGITS 8
+
+static int irq_affinity_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08x\n", irq_affinity[(int)(long)data]);
+}
+
+static unsigned int parse_hex_value (const char *buffer,
+		unsigned long count, unsigned long *ret)
+{
+	unsigned char hexnum [HEX_DIGITS];
+	unsigned long value;
+	int i;
+
+	if (!count)
+		return -EINVAL;
+	if (count > HEX_DIGITS)
+		count = HEX_DIGITS;
+	if (copy_from_user(hexnum, buffer, count))
+		return -EFAULT;
+
+	/*
+	 * Parse the first 8 characters as a hex string, any non-hex char
+	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+	 */
+	value = 0;
+
+	for (i = 0; i < count; i++) {
+		unsigned int c = hexnum[i];
+
+		switch (c) {
+			case '0' ... '9': c -= '0'; break;
+			case 'a' ... 'f': c -= 'a'-10; break;
+			case 'A' ... 'F': c -= 'A'-10; break;
+		default:
+			goto out;
+		}
+		value = (value << 4) | c;
+	}
+out:
+	*ret = value;
+	return 0;
+}
+
+static int irq_affinity_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	int irq = (int)(long) data, full_count = count, err;
+	unsigned long new_value;
+
+	if (!irq_desc[irq].handler->set_affinity)
+		return -EIO;
+
+	err = parse_hex_value(buffer, count, &new_value);
+
+/* Why is this disabled ? --BenH */
+#if 0/*CONFIG_SMP*/
+	/*
+	 * Do not allow disabling IRQs completely - it's a too easy
+	 * way to make the system unusable accidentally :-) At least
+	 * one online CPU still has to be targeted.
+	 */
+	if (!(new_value & cpu_online_map))
+		return -EINVAL;
+#endif
+
+	irq_affinity[irq] = new_value;
+	irq_desc[irq].handler->set_affinity(irq, new_value);
+
+	return full_count;
+}
+
+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	unsigned long *mask = (unsigned long *) data;
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", *mask);
+}
+
+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	unsigned long *mask = (unsigned long *) data, full_count = count, err;
+	unsigned long new_value;
+
+	err = parse_hex_value(buffer, count, &new_value);
+	if (err)
+		return err;
+
+	*mask = new_value;
+
+#ifdef CONFIG_PPC_ISERIES
+	{
+		unsigned i;
+		for (i=0; i<MAX_PACAS; ++i) {
+			if ( paca[i].prof_buffer && (new_value & 1) )
+				paca[i].prof_enabled = 1;
+			else
+				paca[i].prof_enabled = 0;
+			new_value >>= 1;
+		}
+	}
+#endif
+
+	return full_count;
+}
+
+#define MAX_NAMELEN 10
+
+static void register_irq_proc (unsigned int irq)
+{
+	struct proc_dir_entry *entry;
+	char name [MAX_NAMELEN];
+
+	if (!root_irq_dir || (irq_desc[irq].handler == NULL))
+		return;
+
+	memset(name, 0, MAX_NAMELEN);
+	sprintf(name, "%d", irq);
+
+	/* create /proc/irq/1234 */
+	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+
+	/* create /proc/irq/1234/smp_affinity */
+	entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
+
+	entry->nlink = 1;
+	entry->data = (void *)(long)irq;
+	entry->read_proc = irq_affinity_read_proc;
+	entry->write_proc = irq_affinity_write_proc;
+
+	smp_affinity_entry[irq] = entry;
+}
+
+unsigned long prof_cpu_mask = -1;
+
+void init_irq_proc (void)
+{
+	struct proc_dir_entry *entry;
+	int i;
+
+	/* create /proc/irq */
+	root_irq_dir = proc_mkdir("irq", 0);
+
+	/* create /proc/irq/prof_cpu_mask */
+	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
+
+	entry->nlink = 1;
+	entry->data = (void *)&prof_cpu_mask;
+	entry->read_proc = prof_cpu_mask_read_proc;
+	entry->write_proc = prof_cpu_mask_write_proc;
+
+	/*
+	 * Create entries for all existing IRQs.
+	 */
+	for (i = 0; i < NR_IRQS; i++) {
+		if (irq_desc[i].handler == NULL)
+			continue;
+		register_irq_proc(i);
+	}
+}
+
+void no_action(int irq, void *dev, struct pt_regs *regs)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/lmb.c linux/arch/ppc64/kernel/lmb.c
--- linux.orig/arch/ppc64/kernel/lmb.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/lmb.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,384 @@
+/*
+ *
+ * Procedures for interfacing to Open Firmware.
+ *
+ * Peter Bergner, IBM Corp.	June 2001.
+ * Copyright (C) 2001 Peter Bergner.
+ * 
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <asm/types.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/abs_addr.h>
+#include <asm/bitops.h>
+#include <asm/udbg.h>
+
+extern unsigned long klimit;
+extern unsigned long reloc_offset(void);
+
+
+static long lmb_add_region(struct lmb_region *, unsigned long, unsigned long, unsigned long);
+
+struct lmb lmb = {
+	0,
+	{0,0,0,0,{{0,0,0}}},
+	{0,0,0,0,{{0,0,0}}}
+};
+
+
+/* Assumption: base addr of region 1 < base addr of region 2 */
+static void
+lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+{
+	unsigned long i;
+
+	rgn->region[r1].size += rgn->region[r2].size;
+	for (i=r2; i < rgn->cnt-1 ;i++) {
+		rgn->region[i].base = rgn->region[i+1].base;
+		rgn->region[i].physbase = rgn->region[i+1].physbase;
+		rgn->region[i].size = rgn->region[i+1].size;
+		rgn->region[i].type = rgn->region[i+1].type;
+	}
+	rgn->cnt--;
+}
+
+
+/* This routine called with relocation disabled. */
+void
+lmb_init(void)
+{
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+
+	/* Create a dummy zero size LMB which will get coalesced away later.
+	 * This simplifies the lmb_add() code below...
+	 */
+	_lmb->memory.region[0].base = 0;
+	_lmb->memory.region[0].size = 0;
+	_lmb->memory.region[0].type = LMB_MEMORY_AREA;
+	_lmb->memory.cnt = 1;
+
+	/* Ditto. */
+	_lmb->reserved.region[0].base = 0;
+	_lmb->reserved.region[0].size = 0;
+	_lmb->reserved.region[0].type = LMB_MEMORY_AREA;
+	_lmb->reserved.cnt = 1;
+}
+
+/* This routine called with relocation disabled. */
+void
+lmb_analyze(void)
+{
+	unsigned long i;
+	unsigned long mem_size = 0;
+	unsigned long io_size = 0;
+	unsigned long size_mask = 0;
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+#ifdef CONFIG_MSCHUNKS
+	unsigned long physbase = 0;
+#endif
+
+	for (i=0; i < _lmb->memory.cnt ;i++) {
+		unsigned long lmb_type = _lmb->memory.region[i].type;
+		unsigned long lmb_size;
+
+		if ( lmb_type != LMB_MEMORY_AREA )
+			continue;
+
+		lmb_size = _lmb->memory.region[i].size;
+
+#ifdef CONFIG_MSCHUNKS
+		_lmb->memory.region[i].physbase = physbase;
+		physbase += lmb_size;
+#else
+		_lmb->memory.region[i].physbase = _lmb->memory.region[i].base;
+#endif
+		mem_size += lmb_size;
+		size_mask |= lmb_size;
+	}
+
+#ifdef CONFIG_MSCHUNKS
+	for (i=0; i < _lmb->memory.cnt ;i++) {
+		unsigned long lmb_type = _lmb->memory.region[i].type;
+		unsigned long lmb_size;
+
+		if ( lmb_type != LMB_IO_AREA )
+			continue;
+
+		lmb_size = _lmb->memory.region[i].size;
+
+		_lmb->memory.region[i].physbase = physbase;
+		physbase += lmb_size;
+		io_size += lmb_size;
+		size_mask |= lmb_size;
+	}
+#endif /* CONFIG_MSCHUNKS */
+
+	_lmb->memory.size = mem_size;
+	_lmb->memory.iosize = io_size;
+	_lmb->memory.lcd_size = (1UL << cnt_trailing_zeros(size_mask));
+}
+
+/* This routine called with relocation disabled. */
+long
+lmb_add(unsigned long base, unsigned long size)
+{
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+	struct lmb_region *_rgn = &(_lmb->memory);
+
+	return lmb_add_region(_rgn, base, size, LMB_MEMORY_AREA);
+
+}
+
+#ifdef CONFIG_MSCHUNKS
+/* This routine called with relocation disabled. */
+long
+lmb_add_io(unsigned long base, unsigned long size)
+{
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+	struct lmb_region *_rgn = &(_lmb->memory);
+
+	return lmb_add_region(_rgn, base, size, LMB_IO_AREA);
+
+}
+#endif /* CONFIG_MSCHUNKS */
+
+long
+lmb_reserve(unsigned long base, unsigned long size)
+{
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+	struct lmb_region *_rgn = &(_lmb->reserved);
+
+	return lmb_add_region(_rgn, base, size, LMB_MEMORY_AREA);
+}
+
+/* This routine called with relocation disabled. */
+static long
+lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size,
+		unsigned long type)
+{
+	unsigned long i, coalesced = 0;
+	long adjacent;
+
+	/* First try and coalesce this LMB with another. */
+	for (i=0; i < rgn->cnt ;i++) {
+		unsigned long rgnbase = rgn->region[i].base;
+		unsigned long rgnsize = rgn->region[i].size;
+		unsigned long rgntype = rgn->region[i].type;
+
+		if ( rgntype != type )
+			continue;
+
+		adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
+		if ( adjacent > 0 ) {
+			rgn->region[i].base -= size;
+			rgn->region[i].physbase -= size;
+			rgn->region[i].size += size;
+			coalesced++;
+			break;
+		}
+		else if ( adjacent < 0 ) {
+			rgn->region[i].size += size;
+			coalesced++;
+			break;
+		}
+	}
+
+	if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
+		lmb_coalesce_regions(rgn, i, i+1);
+		coalesced++;
+	}
+
+	if ( coalesced ) {
+		return coalesced;
+	} else if ( rgn->cnt >= MAX_LMB_REGIONS ) {
+		return -1;
+	}
+
+	/* Couldn't coalesce the LMB, so add it to the sorted table. */
+	for (i=rgn->cnt-1; i >= 0 ;i--) {
+		if (base < rgn->region[i].base) {
+			rgn->region[i+1].base = rgn->region[i].base;
+			rgn->region[i+1].physbase = rgn->region[i].physbase;
+			rgn->region[i+1].size = rgn->region[i].size;
+			rgn->region[i+1].type = rgn->region[i].type;
+		}  else {
+			rgn->region[i+1].base = base;
+			rgn->region[i+1].physbase = lmb_abs_to_phys(base);
+			rgn->region[i+1].size = size;
+			rgn->region[i+1].type = type;
+			break;
+		}
+	}
+	rgn->cnt++;
+
+	return 0;
+}
+
+long
+lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
+{
+	unsigned long i;
+
+	for (i=0; i < rgn->cnt ;i++) {
+		unsigned long rgnbase = rgn->region[i].base;
+		unsigned long rgnsize = rgn->region[i].size;
+		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
+			break;
+		}
+	}
+
+	return (i < rgn->cnt) ? i : -1;
+}
+
+
+unsigned long
+lmb_alloc(unsigned long size, unsigned long align)
+{
+	long i, j;
+	unsigned long base;
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+	struct lmb_region *_mem = &(_lmb->memory);
+	struct lmb_region *_rsv = &(_lmb->reserved);
+
+	for (i=_mem->cnt-1; i >= 0 ;i--) {
+		unsigned long lmbbase = _mem->region[i].base;
+		unsigned long lmbsize = _mem->region[i].size;
+		unsigned long lmbtype = _mem->region[i].type;
+
+		if ( lmbtype != LMB_MEMORY_AREA )
+			continue;
+
+		base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
+
+		while ( (lmbbase <= base) &&
+			((j = lmb_overlaps_region(_rsv,base,size)) >= 0) ) {
+			base = _ALIGN_DOWN(_rsv->region[j].base-size, align);
+		}
+
+		if ( (base != 0) && (lmbbase <= base) )
+			break;
+	}
+
+	if ( i < 0 )
+		return 0;
+
+	lmb_add_region(_rsv, base, size, LMB_MEMORY_AREA);
+
+	return base;
+}
+
+unsigned long
+lmb_phys_mem_size(void)
+{
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+#ifdef CONFIG_MSCHUNKS
+	return _lmb->memory.size;
+#else
+	struct lmb_region *_mem = &(_lmb->memory);
+	unsigned long idx = _mem->cnt-1;
+	unsigned long lastbase = _mem->region[idx].physbase;
+	unsigned long lastsize = _mem->region[idx].size;
+	
+	return (lastbase + lastsize);
+#endif /* CONFIG_MSCHUNKS */
+}
+
+unsigned long
+lmb_end_of_DRAM(void)
+{
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+	struct lmb_region *_mem = &(_lmb->memory);
+	unsigned long idx;
+
+	for(idx=_mem->cnt-1; idx >= 0 ;idx--) {
+		if ( _mem->region[idx].type != LMB_MEMORY_AREA )
+			continue;
+#ifdef CONFIG_MSCHUNKS
+		return (_mem->region[idx].physbase + _mem->region[idx].size);
+#else
+		return (_mem->region[idx].base + _mem->region[idx].size);
+#endif /* CONFIG_MSCHUNKS */
+	}
+
+	return 0;
+}
+
+
+unsigned long
+lmb_abs_to_phys(unsigned long aa)
+{
+	unsigned long i, pa = aa;
+	unsigned long offset = reloc_offset();
+	struct lmb *_lmb = PTRRELOC(&lmb);
+	struct lmb_region *_mem = &(_lmb->memory);
+
+	for (i=0; i < _mem->cnt ;i++) {
+		unsigned long lmbbase = _mem->region[i].base;
+		unsigned long lmbsize = _mem->region[i].size;
+		if ( lmb_addrs_overlap(aa,1,lmbbase,lmbsize) ) {
+			pa = _mem->region[i].physbase + (aa - lmbbase);
+			break;
+		}
+	}
+
+	return pa;
+}
+
+void
+lmb_dump(char *str)
+{
+	unsigned long i;
+
+	udbg_printf("\nlmb_dump: %s\n", str);
+	udbg_printf("    debug                       = %s\n",
+		(lmb.debug) ? "TRUE" : "FALSE");
+	udbg_printf("    memory.cnt                  = %d\n",
+		lmb.memory.cnt);
+	udbg_printf("    memory.size                 = 0x%lx\n",
+		lmb.memory.size);
+	udbg_printf("    memory.lcd_size             = 0x%lx\n",
+		lmb.memory.lcd_size);
+	for (i=0; i < lmb.memory.cnt ;i++) {
+		udbg_printf("    memory.region[%d].base       = 0x%lx\n",
+			i, lmb.memory.region[i].base);
+		udbg_printf("                      .physbase = 0x%lx\n",
+			lmb.memory.region[i].physbase);
+		udbg_printf("                      .size     = 0x%lx\n",
+			lmb.memory.region[i].size);
+		udbg_printf("                      .type     = 0x%lx\n",
+			lmb.memory.region[i].type);
+	}
+
+	udbg_printf("\n");
+	udbg_printf("    reserved.cnt                = %d\n",
+		lmb.reserved.cnt);
+	udbg_printf("    reserved.size               = 0x%lx\n",
+		lmb.reserved.size);
+	udbg_printf("    reserved.lcd_size           = 0x%lx\n",
+		lmb.reserved.lcd_size);
+	for (i=0; i < lmb.reserved.cnt ;i++) {
+		udbg_printf("    reserved.region[%d].base     = 0x%lx\n",
+			i, lmb.reserved.region[i].base);
+		udbg_printf("                      .physbase = 0x%lx\n",
+			lmb.reserved.region[i].physbase);
+		udbg_printf("                      .size     = 0x%lx\n",
+			lmb.reserved.region[i].size);
+		udbg_printf("                      .type     = 0x%lx\n",
+			lmb.reserved.region[i].type);
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/local_irq.h linux/arch/ppc64/kernel/local_irq.h
--- linux.orig/arch/ppc64/kernel/local_irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/local_irq.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,26 @@
+/*
+ *      c 2001 PowerPC 64 Team, IBM Corp
+ *
+ *      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.
+ */
+#ifndef _PPC_KERNEL_LOCAL_IRQ_H
+#define _PPC_KERNEL_LOCAL_IRQ_H
+
+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
+#include <linux/cache.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+
+void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
+
+#define NR_MASK_WORDS	((NR_IRQS + 63) / 64)
+
+extern int ppc_spurious_interrupts;
+extern int ppc_second_irq;
+extern struct irqaction *ppc_irq_action[NR_IRQS];
+
+#endif /* _PPC_KERNEL_LOCAL_IRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/mf.c linux/arch/ppc64/kernel/mf.c
--- linux.orig/arch/ppc64/kernel/mf.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/mf.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,1202 @@
+/*
+  * mf.c
+  * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
+  *
+  * This modules exists as an interface between a Linux secondary partition
+  * running on an iSeries and the primary partition's Virtual Service
+  * Processor (VSP) object.  The VSP has final authority over powering on/off
+  * all partitions in the iSeries.  It also provides miscellaneous low-level
+  * machine facility type operations.
+  *
+  * 
+  * 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 <asm/iSeries/mf.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <asm/iSeries/HvLpConfig.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <asm/nvram.h>
+#include <asm/time.h>
+#include <asm/iSeries/ItSpCommArea.h>
+#include <asm/iSeries/mf_proc.h>
+#include <asm/iSeries/iSeries_proc.h>
+#include <asm/uaccess.h>
+#include <linux/pci.h>
+
+extern struct pci_dev * iSeries_vio_dev;
+
+/*
+ * This is the structure layout for the Machine Facilites LPAR event
+ * flows.
+ */
+struct VspCmdData;
+struct CeMsgData;
+union SafeCast
+{
+	u64 ptrAsU64;
+	void *ptr;
+};
+
+
+typedef void (*CeMsgCompleteHandler)( void *token, struct CeMsgData *vspCmdRsp );
+
+struct CeMsgCompleteData
+{
+	CeMsgCompleteHandler xHdlr;
+	void *xToken;
+};
+
+struct VspRspData
+{
+	struct semaphore *xSemaphore;
+	struct VspCmdData *xResponse;
+};
+
+struct IoMFLpEvent
+{
+	struct HvLpEvent xHvLpEvent;
+
+	u16 xSubtypeRc;
+	u16 xRsvd1;
+	u32 xRsvd2;
+
+	union
+	{
+
+		struct AllocData
+		{
+			u16 xSize;
+			u16 xType;
+			u32 xCount;
+			u16 xRsvd3;
+			u8 xRsvd4;
+			HvLpIndex xTargetLp;
+		} xAllocData;
+
+		struct CeMsgData
+		{
+			u8 xCEMsg[12];
+			char xReserved[4];
+			struct CeMsgCompleteData *xToken;
+		} xCEMsgData;
+
+		struct VspCmdData
+		{
+			union SafeCast xTokenUnion;
+			u16 xCmd;
+			HvLpIndex xLpIndex;
+			u8 xRc;
+			u32 xReserved1;
+
+			union VspCmdSubData
+			{
+				struct
+				{
+					u64 xState;
+				} xGetStateOut;
+
+				struct
+				{
+					u64 xIplType;
+				} xGetIplTypeOut, xFunction02SelectIplTypeIn;
+
+				struct
+				{
+					u64 xIplMode;
+				} xGetIplModeOut, xFunction02SelectIplModeIn;
+
+				struct
+				{
+					u64 xPage[4];
+				} xGetSrcHistoryIn;
+
+				struct
+				{
+					u64 xFlag;
+				} xGetAutoIplWhenPrimaryIplsOut,
+					xSetAutoIplWhenPrimaryIplsIn,
+					xWhiteButtonPowerOffIn,
+					xFunction08FastPowerOffIn,
+					xIsSpcnRackPowerIncompleteOut;
+
+				struct
+				{
+					u64 xToken;
+					u64 xAddressType;
+					u64 xSide;
+					u32 xTransferLength;
+					u32 xOffset;
+				} xSetKernelImageIn,
+					xGetKernelImageIn,
+					xSetKernelCmdLineIn,
+					xGetKernelCmdLineIn;
+
+				struct
+				{
+					u32 xTransferLength;
+				} xGetKernelImageOut,xGetKernelCmdLineOut;
+
+
+				u8 xReserved2[80];
+
+			} xSubData;
+		} xVspCmd;
+	} xUnion;
+};
+
+
+/*
+ * All outgoing event traffic is kept on a FIFO queue.  The first
+ * pointer points to the one that is outstanding, and all new
+ * requests get stuck on the end.  Also, we keep a certain number of
+ * preallocated stack elements so that we can operate very early in
+ * the boot up sequence (before kmalloc is ready).
+ */
+struct StackElement
+{
+	struct StackElement * next;
+	struct IoMFLpEvent event;
+	MFCompleteHandler hdlr;
+	char dmaData[72];
+	unsigned dmaDataLength;
+	unsigned remoteAddress;
+};
+static spinlock_t spinlock;
+static struct StackElement * head = NULL;
+static struct StackElement * tail = NULL;
+static struct StackElement * avail = NULL;
+static struct StackElement prealloc[16];
+
+/*
+ * Put a stack element onto the available queue, so it can get reused.
+ * Attention! You must have the spinlock before calling!
+ */
+void free( struct StackElement * element )
+{
+	if ( element != NULL )
+	{
+		element->next = avail;
+		avail = element;
+	}
+}
+
+/*
+ * Enqueue the outbound event onto the stack.  If the queue was
+ * empty to begin with, we must also issue it via the Hypervisor
+ * interface.  There is a section of code below that will touch
+ * the first stack pointer without the protection of the spinlock.
+ * This is OK, because we know that nobody else will be modifying
+ * the first pointer when we do this.
+ */
+static int signalEvent( struct StackElement * newElement )
+{
+	int rc = 0;
+	unsigned long flags;
+	int go = 1;
+	struct StackElement * element;
+	HvLpEvent_Rc hvRc;
+
+	/* enqueue the event */
+	if ( newElement != NULL )
+	{
+		spin_lock_irqsave( &spinlock, flags );
+		if ( head == NULL )
+			head = newElement;
+		else {
+			go = 0;
+			tail->next = newElement;
+		}
+		newElement->next = NULL;
+		tail = newElement;
+		spin_unlock_irqrestore( &spinlock, flags );
+	}
+
+	/* send the event */
+	while ( go )
+	{
+		go = 0;
+
+		/* any DMA data to send beforehand? */
+		if ( head->dmaDataLength > 0 )
+			HvCallEvent_dmaToSp( head->dmaData, head->remoteAddress, head->dmaDataLength, HvLpDma_Direction_LocalToRemote );
+
+		hvRc = HvCallEvent_signalLpEvent(&head->event.xHvLpEvent);
+		if ( hvRc != HvLpEvent_Rc_Good )
+		{
+			printk( KERN_ERR "mf.c: HvCallEvent_signalLpEvent() failed with %d\n", (int)hvRc );
+
+			spin_lock_irqsave( &spinlock, flags );
+			element = head;
+			head = head->next;
+			if ( head != NULL )
+				go = 1;
+			spin_unlock_irqrestore( &spinlock, flags );
+
+			if ( element == newElement )
+				rc = -EIO;
+			else {
+				if ( element->hdlr != NULL )
+				{
+					union SafeCast mySafeCast;
+					mySafeCast.ptrAsU64 = element->event.xHvLpEvent.xCorrelationToken;
+					(*element->hdlr)( mySafeCast.ptr, -EIO );
+				}
+			}
+
+			spin_lock_irqsave( &spinlock, flags );
+			free( element );
+			spin_unlock_irqrestore( &spinlock, flags );
+		}
+	}
+
+	return rc;
+}
+
+/*
+ * Allocate a new StackElement structure, and initialize it.
+ */
+static struct StackElement * newStackElement( void )
+{
+	struct StackElement * newElement = NULL;
+	HvLpIndex primaryLp = HvLpConfig_getPrimaryLpIndex();
+	unsigned long flags;
+
+	if ( newElement == NULL )
+	{
+		spin_lock_irqsave( &spinlock, flags );
+		if ( avail != NULL )
+		{
+			newElement = avail;
+			avail = avail->next;
+		}
+		spin_unlock_irqrestore( &spinlock, flags );
+	}
+
+	if ( newElement == NULL )
+		newElement = kmalloc(sizeof(struct StackElement),GFP_ATOMIC);
+
+	if ( newElement == NULL )
+	{
+		printk( KERN_ERR "mf.c: unable to kmalloc %ld bytes\n", sizeof(struct StackElement) );
+		return NULL;
+	}
+
+	memset( newElement, 0, sizeof(struct StackElement) );
+	newElement->event.xHvLpEvent.xFlags.xValid = 1;
+	newElement->event.xHvLpEvent.xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
+	newElement->event.xHvLpEvent.xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
+	newElement->event.xHvLpEvent.xFlags.xFunction = HvLpEvent_Function_Int;
+	newElement->event.xHvLpEvent.xType = HvLpEvent_Type_MachineFac;
+	newElement->event.xHvLpEvent.xSourceLp = HvLpConfig_getLpIndex();
+	newElement->event.xHvLpEvent.xTargetLp = primaryLp;
+	newElement->event.xHvLpEvent.xSizeMinus1 = sizeof(newElement->event)-1;
+	newElement->event.xHvLpEvent.xRc = HvLpEvent_Rc_Good;
+	newElement->event.xHvLpEvent.xSourceInstanceId = HvCallEvent_getSourceLpInstanceId(primaryLp,HvLpEvent_Type_MachineFac);
+	newElement->event.xHvLpEvent.xTargetInstanceId = HvCallEvent_getTargetLpInstanceId(primaryLp,HvLpEvent_Type_MachineFac);
+
+	return newElement;
+}
+
+static int signalVspInstruction( struct VspCmdData *vspCmd )
+{
+	struct StackElement * newElement = newStackElement();
+	int rc = 0;
+	struct VspRspData response;
+	DECLARE_MUTEX_LOCKED(Semaphore);
+	response.xSemaphore = &Semaphore;
+	response.xResponse = vspCmd;
+
+	if ( newElement == NULL )
+		rc = -ENOMEM;
+	else {
+		newElement->event.xHvLpEvent.xSubtype = 6;
+		newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('V'<<8)+('I'<<0);
+		newElement->event.xUnion.xVspCmd.xTokenUnion.ptr = &response;
+		newElement->event.xUnion.xVspCmd.xCmd = vspCmd->xCmd;
+		newElement->event.xUnion.xVspCmd.xLpIndex = HvLpConfig_getLpIndex();
+		newElement->event.xUnion.xVspCmd.xRc = 0xFF;
+		newElement->event.xUnion.xVspCmd.xReserved1 = 0;
+		memcpy(&(newElement->event.xUnion.xVspCmd.xSubData),&(vspCmd->xSubData), sizeof(vspCmd->xSubData));
+		mb();
+
+		rc = signalEvent(newElement);
+	}
+
+	if (rc == 0)
+	{
+		down(&Semaphore);
+	}
+
+	return rc;
+}
+
+
+/*
+ * Send a 12-byte CE message to the primary partition VSP object
+ */
+static int signalCEMsg( char * ceMsg, void * token )
+{
+	struct StackElement * newElement = newStackElement();
+	int rc = 0;
+
+	if ( newElement == NULL )
+		rc = -ENOMEM;
+	else {
+		newElement->event.xHvLpEvent.xSubtype = 0;
+		newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('C'<<8)+('E'<<0);
+		memcpy( newElement->event.xUnion.xCEMsgData.xCEMsg, ceMsg, 12 );
+		newElement->event.xUnion.xCEMsgData.xToken = token;
+		rc = signalEvent(newElement);
+	}
+
+	return rc;
+}
+
+/*
+ * Send a 12-byte CE message and DMA data to the primary partition VSP object
+ */
+static int dmaAndSignalCEMsg( char * ceMsg, void * token, void * dmaData, unsigned dmaDataLength, unsigned remoteAddress )
+{
+	struct StackElement * newElement = newStackElement();
+	int rc = 0;
+
+	if ( newElement == NULL )
+		rc = -ENOMEM;
+	else {
+		newElement->event.xHvLpEvent.xSubtype = 0;
+		newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('C'<<8)+('E'<<0);
+		memcpy( newElement->event.xUnion.xCEMsgData.xCEMsg, ceMsg, 12 );
+		newElement->event.xUnion.xCEMsgData.xToken = token;
+		memcpy( newElement->dmaData, dmaData, dmaDataLength );
+		newElement->dmaDataLength = dmaDataLength;
+		newElement->remoteAddress = remoteAddress;
+		rc = signalEvent(newElement);
+	}
+
+	return rc;
+}
+
+/*
+ * Initiate a nice (hopefully) shutdown of Linux.  We simply are
+ * going to try and send the init process a SIGINT signal.  If
+ * this fails (why?), we'll simply force it off in a not-so-nice
+ * manner.
+ */
+static int shutdown( void )
+{
+	int rc = kill_proc(1,SIGINT,1);
+
+	if ( rc )
+	{
+		printk( KERN_ALERT "mf.c: SIGINT to init failed (%d), hard shutdown commencing\n", rc );
+		mf_powerOff();
+	}
+	else
+		printk( KERN_ALERT "mf.c: init has been successfully notified to proceed with shutdown\n" );
+
+	return rc;
+}
+
+/*
+ * The primary partition VSP object is sending us a new
+ * event flow.  Handle it...
+ */
+static void intReceived( struct IoMFLpEvent * event )
+{
+	int freeIt = 0;
+	struct StackElement * two = NULL;
+	/* ack the interrupt */
+	event->xHvLpEvent.xRc = HvLpEvent_Rc_Good;
+	HvCallEvent_ackLpEvent( &event->xHvLpEvent );
+
+    /* process interrupt */
+	switch( event->xHvLpEvent.xSubtype )
+	{
+	case 0:	/* CE message */
+		switch( event->xUnion.xCEMsgData.xCEMsg[3] )
+		{
+		case 0x5B:	/* power control notification */
+			if ( (event->xUnion.xCEMsgData.xCEMsg[5]&0x20) != 0 )
+			{
+				printk( KERN_ALERT "mf.c: Commencing partition shutdown\n" );
+				if ( shutdown() == 0 )
+					signalCEMsg( "\x00\x00\x00\xDB\x00\x00\x00\x00\x00\x00\x00\x00", NULL );
+			}
+			break;
+		case 0xC0:	/* get time */
+			{
+				if ( (head != NULL) && ( head->event.xUnion.xCEMsgData.xCEMsg[3] == 0x40 ) )
+				{
+					freeIt = 1;
+					if ( head->event.xUnion.xCEMsgData.xToken != 0 )
+					{
+						CeMsgCompleteHandler xHdlr = head->event.xUnion.xCEMsgData.xToken->xHdlr;
+						void * token = head->event.xUnion.xCEMsgData.xToken->xToken;
+
+						if (xHdlr != NULL)
+							(*xHdlr)( token, &(event->xUnion.xCEMsgData) );
+					}
+				}
+			}
+			break;
+		}
+
+		/* remove from queue */
+		if ( freeIt == 1 )
+		{
+			unsigned long flags;
+			spin_lock_irqsave( &spinlock, flags );
+			if ( head != NULL )
+			{
+				struct StackElement *oldHead = head;
+				head = head->next;
+				two = head;
+				free( oldHead );
+			}
+			spin_unlock_irqrestore( &spinlock, flags );
+		}
+
+		/* send next waiting event */
+		if ( two != NULL )
+			signalEvent( NULL );
+		break;
+	case 1:	/* IT sys shutdown */
+		printk( KERN_ALERT "mf.c: Commencing system shutdown\n" );
+		shutdown();
+		break;
+	}
+}
+
+/*
+ * The primary partition VSP object is acknowledging the receipt
+ * of a flow we sent to them.  If there are other flows queued
+ * up, we must send another one now...
+ */
+static void ackReceived( struct IoMFLpEvent * event )
+{
+	unsigned long flags;
+	struct StackElement * two = NULL;
+	unsigned long freeIt = 0;
+
+    /* handle current event */
+	if ( head != NULL )
+	{
+		switch( event->xHvLpEvent.xSubtype )
+		{
+		case 0:     /* CE msg */
+			if ( event->xUnion.xCEMsgData.xCEMsg[3] == 0x40 )
+			{
+				if ( event->xUnion.xCEMsgData.xCEMsg[2] != 0 )
+				{
+					freeIt = 1;
+					if ( head->event.xUnion.xCEMsgData.xToken != 0 )
+					{
+						CeMsgCompleteHandler xHdlr = head->event.xUnion.xCEMsgData.xToken->xHdlr;
+						void * token = head->event.xUnion.xCEMsgData.xToken->xToken;
+
+						if (xHdlr != NULL)
+							(*xHdlr)( token, &(event->xUnion.xCEMsgData) );
+					}
+				}
+			} else {
+				freeIt = 1;
+			}
+			break;
+		case 4:	/* allocate */
+		case 5:	/* deallocate */
+			if ( head->hdlr != NULL )
+			{
+				union SafeCast mySafeCast;
+				mySafeCast.ptrAsU64 = event->xHvLpEvent.xCorrelationToken;
+				(*head->hdlr)( mySafeCast.ptr, event->xUnion.xAllocData.xCount );
+			}
+			freeIt = 1;
+			break;
+		case 6:
+			{
+				struct VspRspData *rsp = (struct VspRspData *)event->xUnion.xVspCmd.xTokenUnion.ptr;
+
+				if (rsp != NULL)
+				{
+					if (rsp->xResponse != NULL)
+						memcpy(rsp->xResponse, &(event->xUnion.xVspCmd), sizeof(event->xUnion.xVspCmd));
+					if (rsp->xSemaphore != NULL)
+						up(rsp->xSemaphore);
+				} else {
+					printk( KERN_ERR "mf.c: no rsp\n");
+				}
+				freeIt = 1;
+			}
+			break;
+		}
+	}
+	else
+		printk( KERN_ERR "mf.c: stack empty for receiving ack\n" );
+
+    /* remove from queue */
+	spin_lock_irqsave( &spinlock, flags );
+	if (( head != NULL ) && ( freeIt == 1 ))
+	{
+		struct StackElement *oldHead = head;
+		head = head->next;
+		two = head;
+		free( oldHead );
+	} 
+	spin_unlock_irqrestore( &spinlock, flags );
+
+    /* send next waiting event */
+	if ( two != NULL )
+		signalEvent( NULL );
+}
+
+/*
+ * This is the generic event handler we are registering with
+ * the Hypervisor.  Ensure the flows are for us, and then
+ * parse it enough to know if it is an interrupt or an
+ * acknowledge.
+ */
+static void hvHandler( struct HvLpEvent * event, struct pt_regs * regs )
+{
+	if ( (event != NULL) && (event->xType == HvLpEvent_Type_MachineFac) )
+	{
+		switch( event->xFlags.xFunction )
+		{
+		case HvLpEvent_Function_Ack:
+			ackReceived( (struct IoMFLpEvent *)event );
+			break;
+		case HvLpEvent_Function_Int:
+			intReceived( (struct IoMFLpEvent *)event );
+			break;
+		default:
+			printk( KERN_ERR "mf.c: non ack/int event received\n" );
+			break;
+		}
+	}
+	else
+		printk( KERN_ERR "mf.c: alien event received\n" );
+}
+
+/*
+ * Global kernel interface to allocate and seed events into the
+ * Hypervisor.
+ */
+void mf_allocateLpEvents( HvLpIndex targetLp,
+			  HvLpEvent_Type type,
+			  unsigned size,
+			  unsigned count,
+			  MFCompleteHandler hdlr,
+			  void * userToken )
+{
+	struct StackElement * newElement = newStackElement();
+	int rc = 0;
+
+	if ( newElement == NULL )
+		rc = -ENOMEM;
+	else {
+		union SafeCast mine;
+		mine.ptr = userToken;
+		newElement->event.xHvLpEvent.xSubtype = 4;
+		newElement->event.xHvLpEvent.xCorrelationToken = mine.ptrAsU64;
+		newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('M'<<8)+('A'<<0);
+		newElement->event.xUnion.xAllocData.xTargetLp = targetLp;
+		newElement->event.xUnion.xAllocData.xType = type;
+		newElement->event.xUnion.xAllocData.xSize = size;
+		newElement->event.xUnion.xAllocData.xCount = count;
+		newElement->hdlr = hdlr;
+		rc = signalEvent(newElement);
+	}
+
+	if ( (rc != 0) && (hdlr != NULL) )
+		(*hdlr)( userToken, rc );
+}
+
+/*
+ * Global kernel interface to unseed and deallocate events already in
+ * Hypervisor.
+ */
+void mf_deallocateLpEvents( HvLpIndex targetLp,
+			    HvLpEvent_Type type,
+			    unsigned count,
+			    MFCompleteHandler hdlr,
+			    void * userToken )
+{
+	struct StackElement * newElement = newStackElement();
+	int rc = 0;
+
+	if ( newElement == NULL )
+		rc = -ENOMEM;
+	else {
+		union SafeCast mine;
+		mine.ptr = userToken;
+		newElement->event.xHvLpEvent.xSubtype = 5;
+		newElement->event.xHvLpEvent.xCorrelationToken = mine.ptrAsU64;
+		newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('M'<<8)+('D'<<0);
+		newElement->event.xUnion.xAllocData.xTargetLp = targetLp;
+		newElement->event.xUnion.xAllocData.xType = type;
+		newElement->event.xUnion.xAllocData.xCount = count;
+		newElement->hdlr = hdlr;
+		rc = signalEvent(newElement);
+	}
+
+	if ( (rc != 0) && (hdlr != NULL) )
+		(*hdlr)( userToken, rc );
+}
+
+/*
+ * Global kernel interface to tell the VSP object in the primary
+ * partition to power this partition off.
+ */
+void mf_powerOff( void )
+{
+	printk( KERN_ALERT "mf.c: Down it goes...\n" );
+	signalCEMsg( "\x00\x00\x00\x4D\x00\x00\x00\x00\x00\x00\x00\x00", NULL );
+	for (;;);
+}
+
+/*
+ * Global kernel interface to tell the VSP object in the primary
+ * partition to reboot this partition.
+ */
+void mf_reboot( void )
+{
+	printk( KERN_ALERT "mf.c: Preparing to bounce...\n" );
+	signalCEMsg( "\x00\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x00", NULL );
+	for (;;);
+}
+
+/*
+ * Display a single word SRC onto the VSP control panel.
+ */
+void mf_displaySrc( u32 word )
+{
+	u8 ce[12];
+
+	memcpy( ce, "\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x00", 12 );
+	ce[8] = word>>24;
+	ce[9] = word>>16;
+	ce[10] = word>>8;
+	ce[11] = word;
+	signalCEMsg( ce, NULL );
+}
+
+/*
+ * Display a single word SRC of the form "PROGXXXX" on the VSP control panel.
+ */
+void mf_displayProgress( u16 value )
+{
+	u8 ce[12];
+	u8 src[72];
+
+	memcpy( ce, "\x00\x00\x04\x4A\x00\x00\x00\x48\x00\x00\x00\x00", 12 );
+	memcpy( src,
+		"\x01\x00\x00\x01"
+		"\x00\x00\x00\x00"
+		"\x00\x00\x00\x00"
+		"\x00\x00\x00\x00"
+		"\x00\x00\x00\x00"
+		"\x00\x00\x00\x00"
+		"\x00\x00\x00\x00"
+		"\x00\x00\x00\x00"
+		"\x00\x00\x00\x00"
+		"\x00\x00\x00\x00"
+		"PROGxxxx"
+		"                        ",
+		72 );
+	src[6] = value>>8;
+	src[7] = value&255;
+	src[44] = "0123456789ABCDEF"[(value>>12)&15];
+	src[45] = "0123456789ABCDEF"[(value>>8)&15];
+	src[46] = "0123456789ABCDEF"[(value>>4)&15];
+	src[47] = "0123456789ABCDEF"[value&15];
+	dmaAndSignalCEMsg( ce, NULL, src, sizeof(src), 9*64*1024 );
+}
+
+/*
+ * Clear the VSP control panel.  Used to "erase" an SRC that was
+ * previously displayed.
+ */
+void mf_clearSrc( void )
+{
+	signalCEMsg( "\x00\x00\x00\x4B\x00\x00\x00\x00\x00\x00\x00\x00", NULL );
+}
+
+/*
+ * Initialization code here.
+ */
+void mf_init( void )
+{
+	int i;
+
+    /* initialize */
+	spin_lock_init( &spinlock );
+	for ( i = 0; i < sizeof(prealloc)/sizeof(*prealloc); ++i )
+		free( &prealloc[i] );
+	HvLpEvent_registerHandler( HvLpEvent_Type_MachineFac, &hvHandler );
+
+	/* virtual continue ack */
+	signalCEMsg( "\x00\x00\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00", NULL );
+
+	/* initialization complete */
+	printk( KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities initialized\n" );
+
+	iSeries_proc_callback(&mf_proc_init);
+}
+
+void mf_setSide(char side)
+{
+	int rc = 0;
+	u64 newSide = 0;
+	struct VspCmdData myVspCmd;
+
+	memset(&myVspCmd, 0, sizeof(myVspCmd));
+	if (side == 'A')
+		newSide = 0;
+	else if (side == 'B')
+		newSide = 1;
+	else if (side == 'C')
+		newSide = 2; 
+	else
+		newSide = 3;
+
+	myVspCmd.xSubData.xFunction02SelectIplTypeIn.xIplType = newSide;
+	myVspCmd.xCmd = 10;
+
+	rc = signalVspInstruction(&myVspCmd);
+}
+
+char mf_getSide(void)
+{
+	char returnValue = ' ';
+	int rc = 0;
+	struct VspCmdData myVspCmd;
+
+	memset(&myVspCmd, 0, sizeof(myVspCmd));
+	myVspCmd.xCmd = 2;
+	myVspCmd.xSubData.xFunction02SelectIplTypeIn.xIplType = 0;
+	mb();
+	rc = signalVspInstruction(&myVspCmd);
+
+	if (rc != 0)
+	{
+		return returnValue;
+	} else {
+		if (myVspCmd.xRc == 0)
+		{
+			if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 0)
+				returnValue = 'A';
+			else if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 1)
+				returnValue = 'B';
+			else if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 2)
+				returnValue = 'C';
+			else
+				returnValue = 'D';
+		}
+	}
+
+	return returnValue;
+}
+
+void mf_getSrcHistory(char *buffer, int size)
+{
+    /*    struct IplTypeReturnStuff returnStuff;
+     struct StackElement * newElement = newStackElement();
+     int rc = 0;
+     char *pages[4];
+
+     pages[0] = kmalloc(4096, GFP_ATOMIC);
+     pages[1] = kmalloc(4096, GFP_ATOMIC);
+     pages[2] = kmalloc(4096, GFP_ATOMIC);
+     pages[3] = kmalloc(4096, GFP_ATOMIC);
+     if (( newElement == NULL ) || (pages[0] == NULL) || (pages[1] == NULL) || (pages[2] == NULL) || (pages[3] == NULL))
+     rc = -ENOMEM;
+     else
+     {
+     returnStuff.xType = 0;
+     returnStuff.xRc = 0;
+     returnStuff.xDone = 0;
+     newElement->event.xHvLpEvent.xSubtype = 6;
+     newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('V'<<8)+('I'<<0);
+     newElement->event.xUnion.xVspCmd.xEvent = &returnStuff;
+     newElement->event.xUnion.xVspCmd.xCmd = 4;
+     newElement->event.xUnion.xVspCmd.xLpIndex = HvLpConfig_getLpIndex();
+     newElement->event.xUnion.xVspCmd.xRc = 0xFF;
+     newElement->event.xUnion.xVspCmd.xReserved1 = 0;
+     newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[0] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[0]));
+     newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[1] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[1]));
+     newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[2] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[2]));
+     newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[3] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[3]));
+     mb();
+     rc = signalEvent(newElement);
+     }
+
+     if (rc != 0)
+     {
+     return;
+     }
+     else
+     {
+     while (returnStuff.xDone != 1)
+     {
+     udelay(10);
+     }
+
+     if (returnStuff.xRc == 0)
+     {
+     memcpy(buffer, pages[0], size);
+     }
+     }
+
+     kfree(pages[0]);
+     kfree(pages[1]);
+     kfree(pages[2]);
+     kfree(pages[3]);*/
+}
+
+void mf_setCmdLine(const char *cmdline, int size, u64 side)
+{
+	struct VspCmdData myVspCmd;
+	int rc = 0;
+	dma_addr_t dma_addr = 0;
+	char *page = pci_alloc_consistent(iSeries_vio_dev, size, &dma_addr);
+
+	if (page == NULL) {
+		printk(KERN_ERR "mf.c: couldn't allocate memory to set command line\n");
+		return;
+	}
+
+	copy_from_user(page, cmdline, size);
+
+	memset(&myVspCmd, 0, sizeof(myVspCmd));
+	myVspCmd.xCmd = 31;
+	myVspCmd.xSubData.xSetKernelCmdLineIn.xToken = dma_addr;
+	myVspCmd.xSubData.xSetKernelCmdLineIn.xAddressType = HvLpDma_AddressType_TceIndex;
+	myVspCmd.xSubData.xSetKernelCmdLineIn.xSide = side;
+	myVspCmd.xSubData.xSetKernelCmdLineIn.xTransferLength = size;
+	mb();
+	rc = signalVspInstruction(&myVspCmd);
+
+	pci_free_consistent(iSeries_vio_dev, size, page, dma_addr);
+}
+
+int mf_getCmdLine(char *cmdline, int *size, u64 side)
+{
+	struct VspCmdData myVspCmd;
+	int rc = 0;
+	int len = *size;
+	dma_addr_t dma_addr = pci_map_single(iSeries_vio_dev, cmdline, *size, PCI_DMA_FROMDEVICE);
+
+	memset(cmdline, 0, *size);
+	memset(&myVspCmd, 0, sizeof(myVspCmd));
+	myVspCmd.xCmd = 33;
+	myVspCmd.xSubData.xGetKernelCmdLineIn.xToken = dma_addr;
+	myVspCmd.xSubData.xGetKernelCmdLineIn.xAddressType = HvLpDma_AddressType_TceIndex;
+	myVspCmd.xSubData.xGetKernelCmdLineIn.xSide = side;
+	myVspCmd.xSubData.xGetKernelCmdLineIn.xTransferLength = *size;
+	mb();
+	rc = signalVspInstruction(&myVspCmd);
+
+	if ( ! rc ) {
+
+		if (myVspCmd.xRc == 0)
+		{
+			len = myVspCmd.xSubData.xGetKernelCmdLineOut.xTransferLength;
+		}
+		/* else
+			{
+			memcpy(cmdline, "Bad cmdline", 11);
+			}
+		*/
+	}
+
+	pci_unmap_single(iSeries_vio_dev, dma_addr, *size, PCI_DMA_FROMDEVICE);
+
+	return len;
+}
+
+
+int mf_setVmlinuxChunk(const char *buffer, int size, int offset, u64 side)
+{
+	struct VspCmdData myVspCmd;
+	int rc = 0;
+
+	dma_addr_t dma_addr = 0;
+
+	char *page = pci_alloc_consistent(iSeries_vio_dev, size, &dma_addr);
+
+	if (page == NULL) {
+		printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n");
+		return -ENOMEM;
+	}
+
+	copy_from_user(page, buffer, size);
+	memset(&myVspCmd, 0, sizeof(myVspCmd));
+
+	myVspCmd.xCmd = 30;
+	myVspCmd.xSubData.xGetKernelImageIn.xToken = dma_addr;
+	myVspCmd.xSubData.xGetKernelImageIn.xAddressType = HvLpDma_AddressType_TceIndex;
+	myVspCmd.xSubData.xGetKernelImageIn.xSide = side;
+	myVspCmd.xSubData.xGetKernelImageIn.xOffset = offset;
+	myVspCmd.xSubData.xGetKernelImageIn.xTransferLength = size;
+	mb();
+	rc = signalVspInstruction(&myVspCmd);
+
+	if (rc == 0)
+	{
+		if (myVspCmd.xRc == 0)
+		{
+			rc = 0;
+		} else {
+			rc = -ENOMEM;
+		}
+	}
+
+	pci_free_consistent(iSeries_vio_dev, size, page, dma_addr);
+
+	return rc;
+}
+
+int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side)
+{
+	struct VspCmdData myVspCmd;
+	int rc = 0;
+	int len = *size;
+
+	dma_addr_t dma_addr = pci_map_single(iSeries_vio_dev, buffer, *size, PCI_DMA_FROMDEVICE);
+
+	memset(buffer, 0, len);
+
+	memset(&myVspCmd, 0, sizeof(myVspCmd));
+	myVspCmd.xCmd = 32;
+	myVspCmd.xSubData.xGetKernelImageIn.xToken = dma_addr;
+	myVspCmd.xSubData.xGetKernelImageIn.xAddressType = HvLpDma_AddressType_TceIndex;
+	myVspCmd.xSubData.xGetKernelImageIn.xSide = side;
+	myVspCmd.xSubData.xGetKernelImageIn.xOffset = offset;
+	myVspCmd.xSubData.xGetKernelImageIn.xTransferLength = len;
+	mb();
+	rc = signalVspInstruction(&myVspCmd);
+
+	if (rc == 0)
+	{
+		if (myVspCmd.xRc == 0)
+		{
+			*size = myVspCmd.xSubData.xGetKernelImageOut.xTransferLength;
+		} else {
+			rc = -ENOMEM;
+		}
+	}
+
+	pci_unmap_single(iSeries_vio_dev, dma_addr, len, PCI_DMA_FROMDEVICE);
+
+	return rc;
+}
+
+int mf_setRtcTime(unsigned long time)
+{
+	struct rtc_time tm;
+
+	to_tm(time, &tm);
+
+	return mf_setRtc( &tm );
+}
+
+struct RtcTimeData
+{
+	struct semaphore *xSemaphore;
+	struct CeMsgData xCeMsg;
+	int xRc;
+};
+
+void getRtcTimeComplete(void * token, struct CeMsgData *ceMsg)
+{
+	struct RtcTimeData *rtc = (struct RtcTimeData *)token;
+
+	memcpy(&(rtc->xCeMsg), ceMsg, sizeof(rtc->xCeMsg));
+
+	rtc->xRc = 0;
+	up(rtc->xSemaphore);
+}
+
+static unsigned long lastsec = 1;
+
+int mf_getRtcTime(unsigned long *time)
+{
+/*    unsigned long usec, tsec; */
+	
+	u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
+	u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
+	int year = 1970;
+	int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
+	int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
+	int sec = ( dataWord1 >> 8 ) & 0x000000FF;
+	int min = dataWord1 & 0x000000FF;
+	int hour = ( dataWord2 >> 24 ) & 0x000000FF;
+	int day = ( dataWord2 >> 8 ) & 0x000000FF;
+	int mon = dataWord2 & 0x000000FF;
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hour);
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(year1);
+	BCD_TO_BIN(year2);
+	year = year1 * 100 + year2;
+
+	*time = mktime(year, mon, day, hour, min, sec);
+
+	*time += ( jiffies / HZ );
+    
+	/* Now THIS is a nasty hack!
+	 * It ensures that the first two calls to mf_getRtcTime get different
+	 * answers.  That way the loop in init_time (time.c) will not think
+	 * the clock is stuck.
+	 */
+	if ( lastsec ) {
+		*time -= lastsec;
+		--lastsec;
+	}
+    
+	return 0;
+
+}
+
+int mf_getRtc( struct rtc_time * tm )
+{
+
+	struct CeMsgCompleteData ceComplete;
+	struct RtcTimeData rtcData;
+	int rc = 0;
+	DECLARE_MUTEX_LOCKED(Semaphore);
+
+	memset(&ceComplete, 0, sizeof(ceComplete));
+	memset(&rtcData, 0, sizeof(rtcData));
+
+	rtcData.xSemaphore = &Semaphore;
+
+	ceComplete.xHdlr = &getRtcTimeComplete;
+	ceComplete.xToken = (void *)&rtcData;
+
+	rc = signalCEMsg( "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", &ceComplete );
+
+	if ( rc == 0 )
+	{
+		down(&Semaphore);
+
+		if ( rtcData.xRc == 0)
+		{
+			if ( ( rtcData.xCeMsg.xCEMsg[2] == 0xa9 ) ||
+			     ( rtcData.xCeMsg.xCEMsg[2] == 0xaf ) ) {
+				/* TOD clock is not set */
+				tm->tm_sec = 1;
+				tm->tm_min = 1;
+				tm->tm_hour = 1;
+				tm->tm_mday = 10;
+				tm->tm_mon = 8;
+				tm->tm_year = 71;
+				mf_setRtc( tm );
+			}
+			{
+				u32 dataWord1 = *((u32 *)(rtcData.xCeMsg.xCEMsg+4));
+				u32 dataWord2 = *((u32 *)(rtcData.xCeMsg.xCEMsg+8));
+				u8 year = (dataWord1 >> 16 ) & 0x000000FF;
+				u8 sec = ( dataWord1 >> 8 ) & 0x000000FF;
+				u8 min = dataWord1 & 0x000000FF;
+				u8 hour = ( dataWord2 >> 24 ) & 0x000000FF;
+				u8 day = ( dataWord2 >> 8 ) & 0x000000FF;
+				u8 mon = dataWord2 & 0x000000FF;
+
+				BCD_TO_BIN(sec);
+				BCD_TO_BIN(min);
+				BCD_TO_BIN(hour);
+				BCD_TO_BIN(day);
+				BCD_TO_BIN(mon);
+				BCD_TO_BIN(year);
+
+				if ( year <= 69 )
+					year += 100;
+	    
+				tm->tm_sec = sec;
+				tm->tm_min = min;
+				tm->tm_hour = hour;
+				tm->tm_mday = day;
+				tm->tm_mon = mon;
+				tm->tm_year = year;
+			}
+		} else {
+			rc = rtcData.xRc;
+			tm->tm_sec = 0;
+			tm->tm_min = 0;
+			tm->tm_hour = 0;
+			tm->tm_mday = 15;
+			tm->tm_mon = 5;
+			tm->tm_year = 52;
+
+		}
+		tm->tm_wday = 0;
+		tm->tm_yday = 0;
+		tm->tm_isdst = 0;
+
+	}
+
+	return rc;
+
+}
+
+int mf_setRtc(struct rtc_time * tm)
+{
+	char ceTime[12] = "\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00";
+	int rc = 0;
+	u8 day, mon, hour, min, sec, y1, y2;
+	unsigned year;
+    
+	year = 1900 + tm->tm_year;
+	y1 = year / 100;
+	y2 = year % 100;
+    
+	sec = tm->tm_sec;
+	min = tm->tm_min;
+	hour = tm->tm_hour;
+	day = tm->tm_mday;
+	mon = tm->tm_mon + 1;
+	    
+	BIN_TO_BCD(sec);
+	BIN_TO_BCD(min);
+	BIN_TO_BCD(hour);
+	BIN_TO_BCD(mon);
+	BIN_TO_BCD(day);
+	BIN_TO_BCD(y1);
+	BIN_TO_BCD(y2);
+
+	ceTime[4] = y1;
+	ceTime[5] = y2;
+	ceTime[6] = sec;
+	ceTime[7] = min;
+	ceTime[8] = hour;
+	ceTime[10] = day;
+	ceTime[11] = mon;
+   
+	rc = signalCEMsg( ceTime, NULL );
+
+	return rc;
+}
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/mf_proc.c linux/arch/ppc64/kernel/mf_proc.c
--- linux.orig/arch/ppc64/kernel/mf_proc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/mf_proc.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,297 @@
+/*
+ * mf_proc.c
+ * Copyright (C) 2001 Kyle A. Lucke  IBM 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
+ */
+
+
+/* Change Activity: */
+/* End Change Activity */
+
+#ifndef _MF_PROC_H
+#include <asm/iSeries/mf_proc.h>
+#endif
+#ifndef MF_H_INCLUDED
+#include <asm/iSeries/mf.h>
+#endif
+#include <asm/uaccess.h>
+
+static struct proc_dir_entry *mf_proc_root = NULL;
+
+int proc_mf_dump_cmdline
+(char *page, char **start, off_t off, int count, int *eof, void *data);
+
+int proc_mf_dump_vmlinux
+(char *page, char **start, off_t off, int count, int *eof, void *data);
+
+int proc_mf_dump_side
+(char *page, char **start, off_t off, int count, int *eof, void *data);
+
+int proc_mf_change_side
+(struct file *file, const char *buffer, unsigned long count, void *data);
+
+int proc_mf_dump_src
+(char *page, char **start, off_t off, int count, int *eof, void *data);
+int proc_mf_change_src (struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_mf_change_cmdline(struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_mf_change_vmlinux(struct file *file, const char *buffer, unsigned long count, void *data);
+
+
+void mf_proc_init(struct proc_dir_entry *iSeries_proc)
+{
+	struct proc_dir_entry *ent = NULL;
+	struct proc_dir_entry *mf_a = NULL;
+	struct proc_dir_entry *mf_b = NULL;
+	struct proc_dir_entry *mf_c = NULL;
+	struct proc_dir_entry *mf_d = NULL;
+
+	mf_proc_root = proc_mkdir("mf", iSeries_proc);
+	if (!mf_proc_root) return;
+
+	mf_a = proc_mkdir("A", mf_proc_root);
+	if (!mf_a) return;
+
+	ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_a);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)0;
+	ent->read_proc = proc_mf_dump_cmdline;
+	ent->write_proc = proc_mf_change_cmdline;
+
+	ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf_a);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)0;
+	ent->write_proc = proc_mf_change_vmlinux;
+	ent->read_proc = NULL;
+
+	mf_b = proc_mkdir("B", mf_proc_root);
+	if (!mf_b) return;
+
+	ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_b);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)1;
+	ent->read_proc = proc_mf_dump_cmdline;
+	ent->write_proc = proc_mf_change_cmdline;
+
+	ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf_b);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)1;
+	ent->write_proc = proc_mf_change_vmlinux;
+	ent->read_proc = NULL;
+
+	mf_c = proc_mkdir("C", mf_proc_root);
+	if (!mf_c) return;
+
+	ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_c);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)2;
+	ent->read_proc = proc_mf_dump_cmdline;
+	ent->write_proc = proc_mf_change_cmdline;
+
+	ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf_c);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)2;
+	ent->write_proc = proc_mf_change_vmlinux;
+	ent->read_proc = NULL;
+
+	mf_d = proc_mkdir("D", mf_proc_root);
+	if (!mf_d) return;
+
+
+	ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_d);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)3;
+	ent->read_proc = proc_mf_dump_cmdline;
+	ent->write_proc = proc_mf_change_cmdline;
+#if 0
+	ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR, mf_d);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)3;
+	ent->read_proc = proc_mf_dump_vmlinux;
+	ent->write_proc = NULL;
+#endif
+	ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)0;
+	ent->read_proc = proc_mf_dump_side;
+	ent->write_proc = proc_mf_change_side;
+
+	ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
+	if (!ent) return;
+	ent->nlink = 1;
+	ent->data = (void *)0;
+	ent->read_proc = proc_mf_dump_src;
+	ent->write_proc = proc_mf_change_src;
+}
+
+int proc_mf_dump_cmdline
+(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int		len = count;
+	char *p;
+    
+	len = mf_getCmdLine(page, &len, (u64)data);
+   
+	p = page + len - 1;
+	while ( p > page ) {
+		if ( (*p == 0) || (*p == ' ') )
+			--p;
+		else
+			break;
+	}
+	if ( *p != '\n' ) {
+		++p;
+		*p = '\n';
+	}
+	++p;
+	*p = 0;
+	len = p - page;
+    
+	len -= off;			
+	if (len < count) {		
+		*eof = 1;		
+		if (len <= 0)		
+			return 0;	
+	} else				
+		len = count;		
+	*start = page + off;		
+	return len;			
+}
+
+int proc_mf_dump_vmlinux
+(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int sizeToGet = count;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	if (mf_getVmlinuxChunk(page, &sizeToGet, off, (u64)data) == 0)
+	{
+		if (sizeToGet != 0)
+		{
+			*start = page + off;
+			return sizeToGet;
+		} else {
+			*eof = 1;
+			return 0;
+		}
+	} else {
+		*eof = 1;
+		return 0;
+	}
+}
+
+int proc_mf_dump_side
+(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int		len = 0;
+
+	char mf_current_side = mf_getSide();
+	len = sprintf(page, "%c\n", mf_current_side);
+
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;			
+}
+
+int proc_mf_change_side(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	if ((*buffer != 'A') &&
+	    (*buffer != 'B') &&
+	    (*buffer != 'C') &&
+	    (*buffer != 'D'))
+	{
+		printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n");
+		return -EINVAL;
+	}
+
+	mf_setSide(*buffer);
+
+	return count;			
+}
+
+int proc_mf_dump_src
+(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int		len = 0;
+	mf_getSrcHistory(page, count);
+	len = count;
+	len -= off;			
+	if (len < count) {		
+		*eof = 1;		
+		if (len <= 0)		
+			return 0;	
+	} else				
+		len = count;		
+	*start = page + off;		
+	return len;			
+}
+
+int proc_mf_change_src(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	if ((count < 4) && (count != 1))
+	{
+		printk(KERN_ERR "mf_proc: invalid src\n");
+		return -EINVAL;
+	}
+
+	if ((count == 1) && ((*buffer) == '\0'))
+	{
+		mf_clearSrc();
+	} else {
+		mf_displaySrc(*(u32 *)buffer);
+	}
+
+	return count;			
+}
+
+int proc_mf_change_cmdline(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	mf_setCmdLine(buffer, count, (u64)data);
+
+	return count;			
+}
+
+int proc_mf_change_vmlinux(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	mf_setVmlinuxChunk(buffer, count, file->f_pos, (u64)data);
+	file->f_pos += count;
+
+	return count;			
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/misc.S linux/arch/ppc64/kernel/misc.S
--- linux.orig/arch/ppc64/kernel/misc.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/misc.S	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,980 @@
+/*
+ *  arch/ppc/kernel/misc.S
+ *
+ *  
+ *
+ * This file contains miscellaneous low-level functions.
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.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.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include "ppc_asm.h"
+
+	.text
+
+/*
+ * Returns (address we're running at) - (address we were linked at)
+ * for use before the text and data are mapped to KERNELBASE.
+ */
+
+_GLOBAL(reloc_offset)
+	mflr	r0
+	bl	1f
+1:	mflr	r3
+	LOADADDR(r4,1b)
+	sub	r3,r4,r3
+	mtlr	r0
+	blr
+
+_GLOBAL(get_msr)
+	mfmsr	r3
+	blr
+
+_GLOBAL(get_dar)
+	mfdar	r3
+	blr
+
+_GLOBAL(get_srr0)
+	mfsrr0  r3
+	blr
+
+_GLOBAL(get_srr1)
+	mfsrr1  r3
+	blr
+	
+_GLOBAL(get_sp)
+	mr	r3,r1
+	blr
+		
+#ifdef CONFIG_PPC_ISERIES
+/* unsigned long __no_use_save_flags(void) */
+_GLOBAL(__no_use_save_flags)
+	mfspr	r4,SPRG3
+	lbz	r3,PACAPROCENABLED(r4)
+	blr
+
+/* void __no_use_restore_flags(unsigned long flags) */	
+_GLOBAL(__no_use_restore_flags)
+/*
+ * Just set/clear the MSR_EE bit through restore/flags but do not
+ * change anything else.  This is needed by the RT system and makes
+ * sense anyway.
+ *    -- Cort
+ */
+	mfspr	r6,SPRG3
+	lbz	r5,PACAPROCENABLED(r6)
+	 /* Check if things are setup the way we want _already_. */
+	cmpw	0,r3,r5
+	beqlr
+	/* are we enabling interrupts? */
+	cmpi	0,r3,0
+	stb	r3,PACAPROCENABLED(r6)
+	beqlr
+	/* Check pending interrupts */
+	CHECKANYINT(r4,r5)
+	beqlr
+
+	/* 
+	 * Handle pending interrupts in interrupt context
+	 */
+	li	r0,0x5555
+	sc
+	blr
+
+_GLOBAL(__no_use_cli)
+	mfspr	r5,SPRG3
+	lbz	r3,PACAPROCENABLED(r5)
+	li	r4,0
+	stb	r4,PACAPROCENABLED(r5)
+	blr			/* Done */
+
+_GLOBAL(__no_use_sti)
+	mfspr	r6,SPRG3
+	li	r3,1
+	stb	r3,PACAPROCENABLED(r6)
+
+	/* Check for pending interrupts
+	 *   A decrementer, IPI or PMC interrupt may have occurred
+	 *   while we were in the hypervisor (which enables)
+	 */
+	CHECKANYINT(r4,r5)
+	beqlr
+
+	/* 
+	 * Handle pending interrupts in interrupt context
+	 */
+	li	r0,0x5555
+	sc	
+	blr
+#endif
+/*
+ * Flush instruction cache.
+ */
+_GLOBAL(flush_instruction_cache)
+
+/*
+ * This is called by kgdb code
+ * and should probably go away
+ * to be replaced by invalidating
+ * the cache lines that are actually
+ * modified
+ */
+	/* use invalidate-all bit in HID0
+	 *  - is this consistent across all 64-bit cpus?  -- paulus */
+	mfspr	r3,HID0
+	ori	r3,r3,HID0_ICFI
+	mtspr	HID0,r3
+	sync
+	isync
+	blr
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ *
+ *   flush all bytes from start through stop-1 inclusive
+ */
+
+_GLOBAL(flush_icache_range)
+
+/*
+ * Flush the data cache to memory 
+ * 
+ * Different systems have different cache line sizes
+ * and in some cases i-cache and d-cache line sizes differ from
+ * each other.
+ */
+	LOADADDR(r10,naca)		/* Get Naca address */
+	ld	r10,0(r10)
+	lhz	r7,DCACHEL1LINESIZE(r10)	/* Get cache line size */
+	addi	r5,r7,-1
+	andc	r6,r3,r5		/* round low to line bdy */
+	subf	r8,r6,r4		/* compute length */
+	add	r8,r8,r5		/* ensure we get enough */
+	lhz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of cache line size */
+	srw.	r8,r8,r9		/* compute line count */
+	beqlr				/* nothing to do? */
+	mtctr	r8
+1:	dcbst	0,r6
+	add	r6,r6,r7
+	bdnz	1b
+	sync
+
+/* Now invalidate the instruction cache */
+	
+	lhz	r7,ICACHEL1LINESIZE(r10)	/* Get Icache line size */
+	addi	r5,r7,-1
+	andc	r6,r3,r5		/* round low to line bdy */
+	subf	r8,r6,r4		/* compute length */
+	add	r8,r8,r5
+	lhz	r9,ICACHEL1LOGLINESIZE(r10)	/* Get log-2 of Icache line size */
+	srw.	r8,r8,r9		/* compute line count */
+	beqlr				/* nothing to do? */
+	mtctr	r8
+2:	icbi	0,r6
+	add	r6,r6,r7
+	bdnz	2b
+	isync
+	blr
+	
+/*
+ * Like above, but only do the D-cache.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ *
+ *    flush all bytes from start to stop-1 inclusive
+ */
+_GLOBAL(flush_dcache_range)
+
+/*
+ * Flush the data cache to memory 
+ * 
+ * Different systems have different cache line sizes
+ */
+	LOADADDR(r10,naca)		/* Get Naca address */
+	ld	r10,0(r10)
+	lhz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
+	addi	r5,r7,-1
+	andc	r6,r3,r5		/* round low to line bdy */
+	subf	r8,r6,r4		/* compute length */
+	add	r8,r8,r5		/* ensure we get enough */
+	lhz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
+	srw.	r8,r8,r9		/* compute line count */
+	beqlr				/* nothing to do? */
+	mtctr	r8
+0:	dcbst	0,r6
+	add	r6,r6,r7
+	bdnz	0b
+	sync
+	blr
+
+/*
+ * Flush a particular page from the data cache to RAM.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ *	void __flush_dcache_icache(void *page)
+ */
+_GLOBAL(__flush_dcache_icache)
+/*
+ * Flush the data cache to memory 
+ * 
+ * Different systems have different cache line sizes
+ */
+
+/* Flush the dcache */
+	LOADADDR(r7,naca)
+	ld	r7,0(r7)
+	clrrdi	r3,r3,12           	    /* Page align */
+	lhz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */
+	lhz	r5,DCACHEL1LINESIZE(r7)		/* Get dcache line size */
+	mr	r6,r3
+	mtctr	r4
+0:	dcbst	0,r6
+	add	r6,r6,r5
+	bdnz	0b
+	sync
+
+/* Now invalidate the icache */	
+
+	lhz	r4,ICACHEL1LINESPERPAGE(r7)	/* Get # icache lines per page */
+	lhz	r5,ICACHEL1LINESIZE(r7)		/* Get icache line size */
+	mtctr	r4
+1:	icbi	0,r3
+	add	r3,r3,r5
+	bdnz	1b
+	isync
+	blr
+	
+/*
+ * Copy a whole page.  Assumes a 4096B page size.
+ */
+_GLOBAL(copy_page)
+	clrrdi	r3,r3,12           	    /* Page align */
+	clrrdi	r4,r4,12           	    /* Page align */
+	li	r5,256
+	mtctr	r5
+	addi	r3,r3,-8
+	addi	r4,r4,-8
+
+1:      ld 	r6,8(r4)
+        ldu	r7,16(r4)
+	std     r6,8(r3) 
+	stdu    r7,16(r3) 
+	bdnz+	1b
+	blr  
+
+/*
+ * I/O string operations
+ *
+ * insb(port, buf, len)
+ * outsb(port, buf, len)
+ * insw(port, buf, len)
+ * outsw(port, buf, len)
+ * insl(port, buf, len)
+ * outsl(port, buf, len)
+ * insw_ns(port, buf, len)
+ * outsw_ns(port, buf, len)
+ * insl_ns(port, buf, len)
+ * outsl_ns(port, buf, len)
+ *
+ * The *_ns versions don't do byte-swapping.
+ */
+_GLOBAL(_insb)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,1
+	blelr-
+00:	lbz	r5,0(r3)
+	eieio
+	stbu	r5,1(r4)
+	bdnz	00b
+	blr
+
+_GLOBAL(_outsb)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,1
+	blelr-
+00:	lbzu	r5,1(r4)
+	stb	r5,0(r3)
+	eieio
+	bdnz	00b
+	blr	
+
+_GLOBAL(_insw)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,2
+	blelr-
+00:	lhbrx	r5,0,r3
+	eieio
+	sthu	r5,2(r4)
+	bdnz	00b
+	blr
+
+_GLOBAL(_outsw)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,2
+	blelr-
+00:	lhzu	r5,2(r4)
+	eieio
+	sthbrx	r5,0,r3	
+	bdnz	00b
+	blr	
+
+_GLOBAL(_insl)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,4
+	blelr-
+00:	lwbrx	r5,0,r3
+	eieio
+	stwu	r5,4(r4)
+	bdnz	00b
+	blr
+
+_GLOBAL(_outsl)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,4
+	blelr-
+00:	lwzu	r5,4(r4)
+	stwbrx	r5,0,r3
+	eieio
+	bdnz	00b
+	blr	
+
+_GLOBAL(ide_insw)
+_GLOBAL(_insw_ns)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,2
+	blelr-
+00:	lhz	r5,0(r3)
+	eieio
+	sthu	r5,2(r4)
+	bdnz	00b
+	blr
+
+_GLOBAL(ide_outsw)
+_GLOBAL(_outsw_ns)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,2
+	blelr-
+00:	lhzu	r5,2(r4)
+	sth	r5,0(r3)
+	eieio
+	bdnz	00b
+	blr	
+
+_GLOBAL(_insl_ns)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,4
+	blelr-
+00:	lwz	r5,0(r3)
+	eieio
+	stwu	r5,4(r4)
+	bdnz	00b
+	blr
+
+_GLOBAL(_outsl_ns)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,4
+	blelr-
+00:	lwzu	r5,4(r4)
+	stw	r5,0(r3)
+	eieio
+	bdnz	00b
+	blr	
+
+/*
+ * Extended precision shifts
+ *
+ * R3/R4 has 64 bit value
+ * R5    has shift count
+ * result in R3/R4
+ *
+ *  ashrdi3:     XXXYYY/ZZZAAA -> SSSXXX/YYYZZZ
+ *  ashldi3:     XXXYYY/ZZZAAA -> YYYZZZ/AAA000
+ *  lshrdi3:     XXXYYY/ZZZAAA -> 000XXX/YYYZZZ
+ */
+/* MIKEC: These may no longer be needed...what does gcc expect ? */
+	
+_GLOBAL(__ashrdi3)
+	li	r6,32
+	sub	r6,r6,r5
+	slw	r7,r3,r6	/* isolate YYY */
+	srw	r4,r4,r5	/* isolate ZZZ */
+	or	r4,r4,r7	/* YYYZZZ */
+	sraw	r3,r3,r5	/* SSSXXX */
+	blr
+
+_GLOBAL(__ashldi3)
+	li	r6,32
+	sub	r6,r6,r5
+	srw	r7,r4,r6	/* isolate ZZZ */
+	slw	r4,r4,r5	/* AAA000 */
+	slw	r3,r3,r5	/* YYY--- */
+	or	r3,r3,r7	/* YYYZZZ */
+	blr
+
+_GLOBAL(__lshrdi3)
+	li	r6,32
+	sub	r6,r6,r5
+	slw	r7,r3,r6        /* isolate YYY */
+	srw	r4,r4,r5        /* isolate ZZZ */
+	or	r4,r4,r7        /* YYYZZZ */
+	srw	r3,r3,r5        /* 000XXX */
+	blr
+
+_GLOBAL(abs)
+	cmpi	0,r3,0
+	bge	10f
+	neg	r3,r3
+10:	blr
+
+_GLOBAL(_get_SP)
+	mr	r3,r1		/* Close enough */
+	blr
+	
+_GLOBAL(_get_PVR)
+	mfspr	r3,PVR
+	blr
+
+_GLOBAL(_get_PIR)
+	mfspr	r3,PIR
+	blr
+
+_GLOBAL(_get_HID0)
+	mfspr	r3,HID0
+	blr
+
+_GLOBAL(cvt_fd)
+	lfd	0,-4(r5)	/* load up fpscr value */
+	mtfsf	0xff,0
+	lfs	0,0(r3)
+	stfd	0,0(r4)
+	mffs	0		/* save new fpscr value */
+	stfd	0,-4(r5)
+	blr
+
+_GLOBAL(cvt_df)
+	lfd	0,-4(r5)	/* load up fpscr value */
+	mtfsf	0xff,0
+	lfd	0,0(r3)
+	stfs	0,0(r4)
+	mffs	0		/* save new fpscr value */
+	stfd	0,-4(r5)
+	blr
+
+/*
+ * Create a kernel thread
+ *   kernel_thread(fn, arg, flags)
+ */
+_GLOBAL(kernel_thread)
+	mr	r6,r3		/* function */
+	ori	r3,r5,CLONE_VM	/* flags */
+	li	r0,__NR_clone
+	sc
+	cmpi	0,r3,0		/* parent or child? */
+	bnelr			/* return if parent */
+
+	li	r0,0		/* clear out p->thread.regs */
+	std	r0,THREAD+PT_REGS(r13)	/* since we don't have user ctx */
+	li	r0,RUN_FLAG		/* Run light on */
+	std	r0,THREAD+THREAD_FLAGS(r13)
+
+	ld	r2,8(r6)
+	ld	r6,0(r6)
+	mtlr	r6              /* fn addr in lr */
+	mr	r3,r4	        /* load arg and call fn */
+	blrl
+	li	r0,__NR_exit	/* exit after child exits */
+        li	r3,0
+	sc
+
+#ifdef CONFIG_BINFMT_ELF32
+/* Why isn't this a) automatic, b) written in 'C'? */	
+	.balign 8
+_GLOBAL(sys_call_table32)
+	.llong .sys_ni_syscall	/* 0  -  old "setup()" system call */
+	.llong .sys32_exit
+	.llong .sys32_fork
+	.llong .sys_read
+	.llong .sys_write
+	.llong .sys32_open		/* 5 */
+	.llong .sys_close
+	.llong .sys32_waitpid
+	.llong .sys32_creat
+	.llong .sys_link
+	.llong .sys_unlink      	/* 10 */
+	.llong .sys32_execve
+	.llong .sys_chdir
+	.llong .sys32_time
+	.llong .sys32_mknod
+	.llong .sys32_chmod		/* 15 */
+	.llong .sys_lchown
+	.llong .sys_ni_syscall			/* old break syscall holder */
+	.llong .sys32_stat
+	.llong .sys32_lseek
+	.llong .sys_getpid              /* 20 */
+	.llong .sys32_mount
+	.llong .sys_oldumount
+	.llong .sys_setuid
+	.llong .sys_getuid
+	.llong .ppc64_sys32_stime       /* 25 */
+	.llong .sys32_ptrace
+	.llong .sys_alarm
+	.llong .sys32_fstat
+	.llong .sys32_pause
+	.llong .sys32_utime		/* 30 */
+	.llong .sys_ni_syscall			/* old stty syscall holder */
+	.llong .sys_ni_syscall			/* old gtty syscall holder */
+	.llong .sys32_access
+	.llong .sys32_nice
+	.llong .sys_ni_syscall	/* 35 */	/* old ftime syscall holder */
+	.llong .sys_sync
+	.llong .sys32_kill
+	.llong .sys_rename
+	.llong .sys32_mkdir
+	.llong .sys_rmdir		/* 40 */
+	.llong .sys_dup
+	.llong .sys_pipe
+	.llong .sys32_times
+	.llong .sys_ni_syscall			/* old prof syscall holder */
+	.llong .sys_brk		/* 45 */
+	.llong .sys_setgid
+	.llong .sys_getgid
+	.llong .sys_signal
+	.llong .sys_geteuid
+	.llong .sys_getegid  	/* 50 */
+	.llong .sys_acct
+	.llong .sys32_umount			/* recycled never used phys() */
+	.llong .sys_ni_syscall			/* old lock syscall holder */
+	.llong .sys32_ioctl
+	.llong .sys32_fcntl		/* 55 */
+	.llong .sys_ni_syscall			/* old mpx syscall holder */
+	.llong .sys32_setpgid
+	.llong .sys_ni_syscall			/* old ulimit syscall holder */
+	.llong .sys_olduname
+	.llong .sys32_umask		/* 60 */
+	.llong .sys_chroot
+	.llong .sys_ustat
+	.llong .sys_dup2
+	.llong .sys_getppid
+	.llong .sys_getpgrp	        /* 65 */
+	.llong .sys_setsid
+	.llong .sys32_sigaction
+	.llong .sys_sgetmask
+	.llong .sys32_ssetmask
+	.llong .sys_setreuid	        /* 70 */
+	.llong .sys_setregid
+	.llong .sys_sigsuspend
+	.llong .sys32_sigpending
+	.llong .sys32_sethostname
+	.llong .sys32_setrlimit	        /* 75 */
+	.llong .sys32_old_getrlimit
+	.llong .sys32_getrusage
+	.llong .sys32_gettimeofday
+	.llong .sys32_settimeofday
+	.llong .sys32_getgroups	        /* 80 */
+	.llong .sys32_setgroups
+	.llong .ppc32_select
+	.llong .sys_symlink
+	.llong .sys32_lstat
+	.llong .sys32_readlink	        /* 85 */
+	.llong .sys_uselib
+	.llong .sys32_swapon
+	.llong .sys32_reboot
+	.llong .old32_readdir
+	.llong .sys32_mmap		/* 90 */
+	.llong .sys_munmap
+	.llong .sys_truncate
+	.llong .sys_ftruncate
+	.llong .sys_fchmod
+	.llong .sys_fchown              /* 95 */
+	.llong .sys32_getpriority
+	.llong .sys32_setpriority
+	.llong .sys_ni_syscall			/* old profil syscall holder */
+	.llong .sys32_statfs
+	.llong .sys32_fstatfs	/* 100 */
+	.llong .sys32_ioperm
+	.llong .sys32_socketcall
+	.llong .sys32_syslog
+	.llong .sys32_setitimer
+	.llong .sys32_getitimer	/* 105 */
+	.llong .sys32_newstat
+	.llong .sys32_newlstat
+	.llong .sys32_newfstat
+	.llong .sys_uname
+	.llong .sys32_iopl		/* 110 */
+	.llong .sys_vhangup
+	.llong .sys_ni_syscall	/* old 'idle' syscall */
+	.llong .sys32_vm86
+	.llong .sys32_wait4
+	.llong .sys_swapoff	/* 115 */
+	.llong .sys32_sysinfo
+	.llong .sys32_ipc
+	.llong .sys_fsync
+	.llong .ppc32_sigreturn
+	.llong .sys32_clone		/* 120 */
+	.llong .sys32_setdomainname
+	.llong .ppc64_newuname
+	.llong .sys32_modify_ldt
+	.llong .sys32_adjtimex
+	.llong .sys_mprotect	/* 125 */
+	.llong .sys32_sigprocmask
+	.llong .sys32_create_module
+	.llong .sys32_init_module
+	.llong .sys32_delete_module
+	.llong .sys32_get_kernel_syms	/* 130 */
+	.llong .sys32_quotactl
+	.llong .sys32_getpgid
+	.llong .sys_fchdir
+	.llong .sys32_bdflush
+	.llong .sys32_sysfs		/* 135 */
+	.llong .sys32_personality
+	.llong .sys_ni_syscall	        /* for afs_syscall */
+	.llong .sys_setfsuid
+	.llong .sys_setfsgid
+	.llong .sys_llseek	        /* 140 */
+        .llong .sys32_getdents
+	.llong .ppc32_select
+	.llong .sys_flock
+	.llong .sys32_msync
+	.llong .sys32_readv		/* 145 */
+	.llong .sys32_writev
+	.llong .sys32_getsid
+	.llong .sys_fdatasync
+	.llong .sys32_sysctl
+	.llong .sys_mlock		/* 150 */
+	.llong .sys_munlock
+	.llong .sys32_mlockall
+	.llong .sys_munlockall
+	.llong .sys32_sched_setparam
+	.llong .sys32_sched_getparam	/* 155 */
+	.llong .sys32_sched_setscheduler
+	.llong .sys32_sched_getscheduler
+	.llong .sys_sched_yield
+	.llong .sys32_sched_get_priority_max
+	.llong .sys32_sched_get_priority_min  /* 160 */
+	.llong .sys32_sched_rr_get_interval
+	.llong .sys32_nanosleep
+	.llong .sys32_mremap
+	.llong .sys_setresuid
+	.llong .sys_getresuid	        /* 165 */
+	.llong .sys32_query_module
+	.llong .sys_poll
+	.llong .sys32_nfsservctl
+	.llong .sys_setresgid
+	.llong .sys_getresgid	        /* 170 */
+	.llong .sys32_prctl
+	.llong .ppc32_rt_sigreturn
+	.llong .sys32_rt_sigaction
+	.llong .sys32_rt_sigprocmask
+	.llong .sys32_rt_sigpending     /* 175 */
+	.llong .sys32_rt_sigtimedwait
+	.llong .sys32_rt_sigqueueinfo
+	.llong .sys32_rt_sigsuspend
+	.llong .sys32_pread
+	.llong .sys32_pwrite	        /* 180 */
+	.llong .sys_chown
+	.llong .sys_getcwd
+	.llong .sys_capget
+	.llong .sys_capset
+	.llong .sys32_sigaltstack	        /* 185 */
+	.llong .sys32_sendfile
+	.llong .sys_ni_syscall		/* streams1 */
+	.llong .sys_ni_syscall		/* streams2 */
+	.llong .sys32_vfork
+	.llong .sys32_getrlimit	        /* 190 */
+	.llong .sys_ni_syscall		/* 191 */	/* Unused */
+	.llong .sys_ni_syscall		/* 192 - reserved - mmap2 */
+	.llong .sys32_truncate64	/* 193 - truncate64 */
+	.llong .sys32_ftruncate64	/* 194 - ftruncate64 */
+	.llong .sys_stat64      	/* 195 - stat64 */
+	.llong .sys_lstat64     	/* 196 - lstat64 */
+	.llong .sys_fstat64		/* 197 - fstat64 */
+	.llong .sys32_pciconfig_read  	/* 198 */
+	.llong .sys32_pciconfig_write  	/* 199 */
+	.llong .sys_pciconfig_iobase 	/* 200 */
+	.llong .sys_ni_syscall		/* 201 - reserved - MacOnLinux - new */
+	.llong .sys_getdents64		/* 202 */
+	.llong .sys_pivot_root		/* 203 */
+	.llong .sys32_fcntl64		/* 204 */
+	.llong .sys_madvise		/* 205 */
+	.llong .sys_mincore		/* 206 */
+	.llong .sys_gettid		/* 207 */
+#if 0 /* Reserved syscalls */
+	.llong .sys_tkill		/* 208 */
+	.llong .sys_setxattr
+	.llong .sys_lsetxattr	/* 210 */
+	.llong .sys_fsetxattr
+	.llong .sys_getxattr
+	.llong .sys_lgetxattr
+	.llong .sys_fgetxattr
+	.llong .sys_listxattr	/* 215 */
+	.llong .sys_llistxattr
+	.llong .sys_flistxattr
+	.llong .sys_removexattr
+	.llong .sys_lremovexattr
+	.llong .sys_fremovexattr	/* 220 */
+	.llong .sys_futex
+#endif
+	.rept NR_syscalls-221
+		.llong .sys_ni_syscall
+	.endr
+#endif
+	.balign 8
+_GLOBAL(sys_call_table)
+	.llong .sys_ni_syscall	/* 0  -  old "setup()" system call */
+	.llong .sys_exit
+	.llong .sys_fork
+	.llong .sys_read
+	.llong .sys_write
+	.llong .sys_open		/* 5 */
+	.llong .sys_close
+	.llong .sys_waitpid
+	.llong .sys_creat
+	.llong .sys_link
+	.llong .sys_unlink	/* 10 */
+	.llong .sys_execve
+	.llong .sys_chdir
+	.llong .sys64_time
+	.llong .sys_mknod
+	.llong .sys_chmod		/* 15 */
+	.llong .sys_lchown
+	.llong .sys_ni_syscall			/* old break syscall holder */
+	.llong .sys_stat
+	.llong .sys_lseek
+	.llong .sys_getpid	/* 20 */
+	.llong .sys_mount
+	.llong .sys_oldumount
+	.llong .sys_setuid
+	.llong .sys_getuid
+	.llong .ppc64_sys_stime		/* 25 */
+	.llong .sys_ptrace
+	.llong .sys_alarm
+	.llong .sys_fstat
+	.llong .sys_pause
+	.llong .sys_utime		/* 30 */
+	.llong .sys_ni_syscall			/* old stty syscall holder */
+	.llong .sys_ni_syscall			/* old gtty syscall holder */
+	.llong .sys_access
+	.llong .sys_nice
+	.llong .sys_ni_syscall	/* 35 */	/* old ftime syscall holder */
+	.llong .sys_sync
+	.llong .sys_kill
+	.llong .sys_rename
+	.llong .sys_mkdir
+	.llong .sys_rmdir		/* 40 */
+	.llong .sys_dup
+	.llong .sys_pipe
+	.llong .sys_times
+	.llong .sys_ni_syscall			/* old prof syscall holder */
+	.llong .sys_brk		/* 45 */
+	.llong .sys_setgid
+	.llong .sys_getgid
+	.llong .sys_signal
+	.llong .sys_geteuid
+	.llong .sys_getegid	/* 50 */
+	.llong .sys_acct
+	.llong .sys_umount			/* recycled never used phys() */
+	.llong .sys_ni_syscall			/* old lock syscall holder */
+	.llong .sys_ioctl
+	.llong .sys_fcntl		/* 55 */
+	.llong .sys_ni_syscall			/* old mpx syscall holder */
+	.llong .sys_setpgid
+	.llong .sys_ni_syscall			/* old ulimit syscall holder */
+	.llong .sys_olduname
+	.llong .sys_umask		/* 60 */
+	.llong .sys_chroot
+	.llong .sys_ustat
+	.llong .sys_dup2
+	.llong .sys_getppid
+	.llong .sys_getpgrp	/* 65 */
+	.llong .sys_setsid
+	.llong .sys_sigaction
+	.llong .sys_sgetmask
+	.llong .sys_ssetmask
+	.llong .sys_setreuid	/* 70 */
+	.llong .sys_setregid
+	.llong .sys_sigsuspend
+	.llong .sys_sigpending
+	.llong .sys_sethostname
+	.llong .sys_setrlimit	/* 75 */
+	.llong .sys_old_getrlimit
+	.llong .sys_getrusage
+	.llong .sys_gettimeofday
+	.llong .sys_settimeofday
+	.llong .sys_getgroups	/* 80 */
+	.llong .sys_setgroups
+	.llong .sys_select
+	.llong .sys_symlink
+	.llong .sys_lstat
+	.llong .sys_readlink	/* 85 */
+	.llong .sys_uselib
+	.llong .sys_swapon
+	.llong .sys_reboot
+	.llong .old_readdir
+	.llong .sys_mmap	/* 90 */
+	.llong .sys_munmap
+	.llong .sys_truncate
+	.llong .sys_ftruncate
+	.llong .sys_fchmod
+	.llong .sys_fchown	/* 95 */
+	.llong .sys_getpriority
+	.llong .sys_setpriority
+	.llong .sys_ni_syscall			/* old profil syscall holder */
+	.llong .sys_statfs
+	.llong .sys_fstatfs	/* 100 */
+	.llong .sys_ioperm
+	.llong .sys_socketcall
+	.llong .sys_syslog
+	.llong .sys_setitimer
+	.llong .sys_getitimer	/* 105 */
+	.llong .sys_newstat
+	.llong .sys_newlstat
+	.llong .sys_newfstat
+	.llong .sys_uname
+	.llong .sys_iopl		/* 110 */
+	.llong .sys_vhangup
+	.llong .sys_ni_syscall	/* old 'idle' syscall */
+	.llong .sys_vm86
+	.llong .sys_wait4
+	.llong .sys_swapoff	/* 115 */
+	.llong .sys_sysinfo
+	.llong .sys_ipc
+	.llong .sys_fsync
+	.llong .ppc64_sigreturn
+	.llong .sys_clone		/* 120 */
+	.llong .sys_setdomainname
+	.llong .ppc64_newuname
+	.llong .sys_modify_ldt
+	.llong .sys_adjtimex
+	.llong .sys_mprotect	/* 125 */
+	.llong .sys_sigprocmask
+	.llong .sys_create_module
+	.llong .sys_init_module
+	.llong .sys_delete_module
+	.llong .sys_get_kernel_syms	/* 130 */
+	.llong .sys_quotactl
+	.llong .sys_getpgid
+	.llong .sys_fchdir
+	.llong .sys_bdflush
+	.llong .sys_sysfs		/* 135 */
+	.llong .sys_personality
+	.llong .sys_ni_syscall	        /* for afs_syscall */
+	.llong .sys_setfsuid
+	.llong .sys_setfsgid
+	.llong .sys_llseek	        /* 140 */
+        .llong .sys_getdents
+	.llong .sys_select
+	.llong .sys_flock
+	.llong .sys_msync
+	.llong .sys_readv		/* 145 */
+	.llong .sys_writev
+	.llong .sys_getsid
+	.llong .sys_fdatasync
+	.llong .sys_sysctl
+	.llong .sys_mlock		/* 150 */
+	.llong .sys_munlock
+	.llong .sys_mlockall
+	.llong .sys_munlockall
+	.llong .sys_sched_setparam
+	.llong .sys_sched_getparam	/* 155 */
+	.llong .sys_sched_setscheduler
+	.llong .sys_sched_getscheduler
+	.llong .sys_sched_yield
+	.llong .sys_sched_get_priority_max
+	.llong .sys_sched_get_priority_min  /* 160 */
+	.llong .sys_sched_rr_get_interval
+	.llong .sys_nanosleep
+	.llong .sys_mremap
+	.llong .sys_setresuid
+	.llong .sys_getresuid	        /* 165 */
+	.llong .sys_query_module
+	.llong .sys_poll
+	.llong .sys_nfsservctl
+	.llong .sys_setresgid
+	.llong .sys_getresgid	        /* 170 */
+	.llong .sys_prctl
+	.llong .ppc64_rt_sigreturn
+	.llong .sys_rt_sigaction
+	.llong .sys_rt_sigprocmask	
+	.llong .sys_rt_sigpending	/* 175 */
+	.llong .sys_rt_sigtimedwait
+	.llong .sys_rt_sigqueueinfo
+	.llong .sys_rt_sigsuspend
+	.llong .sys_pread
+	.llong .sys_pwrite	        /* 180 */
+	.llong .sys_chown
+	.llong .sys_getcwd
+	.llong .sys_capget
+	.llong .sys_capset
+	.llong .sys_sigaltstack	        /* 185 */
+	.llong .sys_sendfile
+	.llong .sys_ni_syscall		/* streams1 */
+	.llong .sys_ni_syscall		/* streams2 */
+	.llong .sys_vfork
+	.llong .sys_getrlimit	        /* 190 */
+	.llong .sys_ni_syscall		/* 191 */	/* Unused */
+	.llong .sys_ni_syscall		/* 192 - reserved - mmap2 */
+	.llong .sys_ni_syscall		/* 193 - reserved - truncate64 */
+	.llong .sys_ni_syscall		/* 194 - reserved - ftruncate64 */
+	.llong .sys_ni_syscall		/* 195 - reserved - stat64 */
+	.llong .sys_ni_syscall		/* 196 - reserved - lstat64 */
+	.llong .sys_ni_syscall		/* 197 - reserved - fstat64 */
+	.llong .sys_pciconfig_read	/* 198 */
+	.llong .sys_pciconfig_write 	/* 199 */
+	.llong .sys_pciconfig_iobase 	/* 200 */
+	.llong .sys_ni_syscall		/* 201 - reserved - MacOnLinux - new */
+	.llong .sys_getdents64		/* 202 */
+	.llong .sys_pivot_root		/* 203 */
+	.llong .sys_ni_syscall		/* 204 */
+	.llong .sys_madvise		/* 205 */
+	.llong .sys_mincore		/* 206 */
+	.llong .sys_gettid		/* 207 */
+#if 0 /* Reserved syscalls */
+	.llong .sys_tkill		/* 208 */
+	.llong .sys_setxattr
+	.llong .sys_lsetxattr	/* 210 */
+	.llong .sys_fsetxattr
+	.llong .sys_getxattr
+	.llong .sys_lgetxattr
+	.llong .sys_fgetxattr
+	.llong .sys_listxattr	/* 215 */
+	.llong .sys_llistxattr
+	.llong .sys_flistxattr
+	.llong .sys_removexattr
+	.llong .sys_lremovexattr
+	.llong .sys_fremovexattr	/* 220 */
+	.llong .sys_futex
+#endif
+	.rept NR_syscalls-221
+	.llong .sys_ni_syscall
+	.endr
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/mk_defs.c linux/arch/ppc64/kernel/mk_defs.c
--- linux.orig/arch/ppc64/kernel/mk_defs.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/mk_defs.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,160 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <stddef.h>
+#include <linux/config.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 <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/hardirq.h>
+
+#include <asm/naca.h>
+#include <asm/paca.h>
+#include <asm/iSeries/ItLpPaca.h>
+#include <asm/iSeries/ItLpQueue.h>
+#include <asm/iSeries/HvLpEvent.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+
+#define DEFINE(sym, val) \
+	        asm volatile("\n#define\t" #sym "\t%0" : : "i" (val))
+
+int
+main(void)
+{
+	DEFINE(SIGPENDING, offsetof(struct task_struct, sigpending));
+	DEFINE(THREAD, offsetof(struct task_struct, thread));
+	DEFINE(MM, offsetof(struct task_struct, mm));
+	DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
+	DEFINE(KSP, offsetof(struct thread_struct, ksp));
+
+        DEFINE(PACA, offsetof(struct naca_struct, paca));
+        DEFINE(PACA_SIZE, sizeof(struct paca_struct));
+
+        DEFINE(DCACHEL1LINESIZE, offsetof(struct naca_struct, dCacheL1LineSize));
+        DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct naca_struct, dCacheL1LogLineSize));
+        DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct naca_struct, dCacheL1LinesPerPage));
+
+        DEFINE(ICACHEL1LINESIZE, offsetof(struct naca_struct, iCacheL1LineSize));
+        DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct naca_struct, iCacheL1LogLineSize));
+        DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct naca_struct, iCacheL1LinesPerPage));
+	DEFINE(SLBSIZE, offsetof(struct naca_struct, slb_size));
+	DEFINE(PLATFORM, offsetof(struct naca_struct, platform));
+
+        DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, xPacaIndex));
+        DEFINE(PACAPROCSTART, offsetof(struct paca_struct, xProcStart));
+        DEFINE(PACAKSAVE, offsetof(struct paca_struct, xKsave));
+	DEFINE(PACACURRENT, offsetof(struct paca_struct, xCurrent));
+        DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, xSavedMsr));
+        DEFINE(PACASTABREAL, offsetof(struct paca_struct, xStab_data.real));
+        DEFINE(PACASTABVIRT, offsetof(struct paca_struct, xStab_data.virt));
+	DEFINE(PACASTABRR, offsetof(struct paca_struct, xStab_data.next_round_robin));
+        DEFINE(PACAR1, offsetof(struct paca_struct, xR1));
+        DEFINE(PACALPQUEUE, offsetof(struct paca_struct, lpQueuePtr));
+	DEFINE(PACATOC, offsetof(struct paca_struct, xTOC));
+	DEFINE(PACAEXCSP, offsetof(struct paca_struct, exception_sp));
+	DEFINE(PACAHRDWINTSTACK, offsetof(struct paca_struct, xHrdIntStack));
+	DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, xProcEnabled));
+	DEFINE(PACAHRDWINTCOUNT, offsetof(struct paca_struct, xHrdIntCount));
+	DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
+	DEFINE(PACAPROFENABLED, offsetof(struct paca_struct, prof_enabled));
+	DEFINE(PACAPROFLEN, offsetof(struct paca_struct, prof_len));
+	DEFINE(PACAPROFSHIFT, offsetof(struct paca_struct, prof_shift));
+	DEFINE(PACAPROFBUFFER, offsetof(struct paca_struct, prof_buffer));
+	DEFINE(PACAPROFSTEXT, offsetof(struct paca_struct, prof_stext));
+	DEFINE(PACALPPACA, offsetof(struct paca_struct, xLpPaca));
+        DEFINE(LPPACA, offsetof(struct paca_struct, xLpPaca));
+        DEFINE(PACAREGSAV, offsetof(struct paca_struct, xRegSav));
+        DEFINE(PACAEXC, offsetof(struct paca_struct, exception_stack));
+        DEFINE(PACAGUARD, offsetof(struct paca_struct, guard));
+        DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0));
+        DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
+	DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xIntDword.xAnyInt));
+	DEFINE(LPPACADECRINT, offsetof(struct ItLpPaca, xIntDword.xFields.xDecrInt));
+        DEFINE(LPQCUREVENTPTR, offsetof(struct ItLpQueue, xSlicCurEventPtr));
+        DEFINE(LPQOVERFLOW, offsetof(struct ItLpQueue, xPlicOverflowIntPending));
+        DEFINE(LPEVENTFLAGS, offsetof(struct HvLpEvent, xFlags));
+	DEFINE(PROMENTRY, offsetof(struct prom_t, entry));
+
+	DEFINE(RTASBASE, offsetof(struct rtas_t, base));
+	DEFINE(RTASENTRY, offsetof(struct rtas_t, entry));
+	DEFINE(RTASSIZE, offsetof(struct rtas_t, size));
+
+	DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall));
+	DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
+	DEFINE(PT_TRACESYS, PT_TRACESYS);
+	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+	DEFINE(NEED_RESCHED, offsetof(struct task_struct, need_resched));
+	DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
+	DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
+	DEFINE(THREAD_FLAGS, offsetof(struct thread_struct, flags));
+	DEFINE(PPC_FLAG_32BIT, PPC_FLAG_32BIT);
+	/* Interrupt register frame */
+	DEFINE(TASK_UNION_SIZE, sizeof(union task_union));
+	DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
+        /* 288 = # of volatile regs, int & fp, for leaf routines */
+        /* which do not stack a frame.  See the PPC64 ABI.       */
+        DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288);
+	/* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
+        DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16 + 288);
+        DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16 + 288);
+	DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
+	DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
+	DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2]));
+	DEFINE(GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[3]));
+	DEFINE(GPR4, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[4]));
+	DEFINE(GPR5, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[5]));
+	DEFINE(GPR6, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[6]));
+	DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
+	DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
+	DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
+	DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20]));
+	DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21]));
+	DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22]));
+	DEFINE(GPR23, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[23]));
+	/* Note: these symbols include _ because they overlap with special
+	 * register names
+	 */
+	DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
+	DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
+	DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
+	DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link));
+	DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr));
+	DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
+	DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+	DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+	DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
+	DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
+	DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
+	DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
+
+	/* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
+	DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs));
+	DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
+
+	DEFINE(CLONE_VM, CLONE_VM);
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/nvram.c linux/arch/ppc64/kernel/nvram.c
--- linux.orig/arch/ppc64/kernel/nvram.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/nvram.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,140 @@
+/*
+ *  c 2001 PPC 64 Team, IBM Corp
+ *
+ *      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.
+ *
+ * /dev/nvram driver for PPC64
+ *
+ * This perhaps should live in drivers/char
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/fcntl.h>
+#include <linux/nvram.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/nvram.h>
+#include <asm/rtas.h>
+#include <asm/prom.h>
+
+static unsigned int rtas_nvram_size;
+static unsigned int nvram_fetch, nvram_store;
+static char nvram_buf[4];	/* assume this is in the first 4GB */
+
+static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
+{
+	switch (origin) {
+	case 1:
+		offset += file->f_pos;
+		break;
+	case 2:
+		offset += rtas_nvram_size;
+		break;
+	}
+	if (offset < 0)
+		return -EINVAL;
+	file->f_pos = offset;
+	return file->f_pos;
+}
+
+
+static ssize_t read_nvram(struct file *file, char *buf,
+			  size_t count, loff_t *ppos)
+{
+	unsigned int i;
+	unsigned long len;
+	char *p = buf;
+
+	if (verify_area(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+	if (*ppos >= rtas_nvram_size)
+		return 0;
+	for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) {
+		if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) ||
+		    len != 1)
+			return -EIO;
+		if (__put_user(nvram_buf[0], p))
+			return -EFAULT;
+	}
+	*ppos = i;
+	return p - buf;
+}
+
+static ssize_t write_nvram(struct file *file, const char *buf,
+			   size_t count, loff_t *ppos)
+{
+	unsigned int i;
+	unsigned long len;
+	const char *p = buf;
+	char c;
+
+	if (verify_area(VERIFY_READ, buf, count))
+		return -EFAULT;
+	if (*ppos >= rtas_nvram_size)
+		return 0;
+	for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) {
+		if (__get_user(c, p))
+			return -EFAULT;
+		nvram_buf[0] = c;
+		if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) ||
+		    len != 1)
+			return -EIO;
+	}
+	*ppos = i;
+	return p - buf;
+}
+
+static int nvram_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	return -EINVAL;
+}
+
+struct file_operations nvram_fops = {
+	owner:		THIS_MODULE,
+	llseek:		nvram_llseek,
+	read:		read_nvram,
+	write:		write_nvram,
+	ioctl:		nvram_ioctl,
+};
+
+static struct miscdevice nvram_dev = {
+	NVRAM_MINOR,
+	"nvram",
+	&nvram_fops
+};
+
+int __init nvram_init(void)
+{
+	struct device_node *nvram;
+	unsigned int *nbytes_p, proplen;
+	if ((nvram = find_type_devices("nvram")) != NULL) {
+		nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
+		if (nbytes_p && proplen == sizeof(unsigned int)) {
+			rtas_nvram_size = *nbytes_p;
+		}
+	}
+	nvram_fetch = rtas_token("nvram-fetch");
+	nvram_store = rtas_token("nvram-store");
+	printk(KERN_INFO "PPC64 nvram contains %d bytes\n", rtas_nvram_size);
+
+	misc_register(&nvram_dev);
+	return 0;
+}
+
+void __exit nvram_cleanup(void)
+{
+        misc_deregister( &nvram_dev );
+}
+
+module_init(nvram_init);
+module_exit(nvram_cleanup);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/open_pic.c linux/arch/ppc64/kernel/open_pic.c
--- linux.orig/arch/ppc64/kernel/open_pic.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/open_pic.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,828 @@
+/*
+ *  arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
+ *
+ *  Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive
+ *  for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+
+#include <asm/machdep.h>
+
+#include "local_irq.h"
+#include "open_pic.h"
+#include "open_pic_defs.h"
+#include "i8259.h"
+#include <asm/ppcdebug.h>
+
+void* OpenPIC_Addr;
+static volatile struct OpenPIC *OpenPIC = NULL;
+u_int OpenPIC_NumInitSenses __initdata = 0;
+u_char *OpenPIC_InitSenses __initdata = NULL;
+extern int use_of_interrupt_tree;
+
+void find_ISUs(void);
+
+static u_int NumProcessors;
+static u_int NumSources;
+static int NumISUs;
+static int open_pic_irq_offset;
+static volatile unsigned char* chrp_int_ack_special;
+static int broken_ipi_registers;
+
+OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU];
+
+static void openpic_end_irq(unsigned int irq_nr);
+static void openpic_ack_irq(unsigned int irq_nr);
+static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask);
+
+struct hw_interrupt_type open_pic = {
+	" OpenPIC  ",
+	NULL,
+	NULL,
+	openpic_enable_irq,
+	openpic_disable_irq,
+	openpic_ack_irq,
+	openpic_end_irq,
+	openpic_set_affinity
+};
+
+#ifdef CONFIG_SMP
+static void openpic_end_ipi(unsigned int irq_nr);
+static void openpic_ack_ipi(unsigned int irq_nr);
+static void openpic_enable_ipi(unsigned int irq_nr);
+static void openpic_disable_ipi(unsigned int irq_nr);
+
+struct hw_interrupt_type open_pic_ipi = {
+	" OpenPIC  ",
+	NULL,
+	NULL,
+	openpic_enable_ipi,
+	openpic_disable_ipi,
+	openpic_ack_ipi,
+	openpic_end_ipi,
+	0
+};
+#endif /* CONFIG_SMP */
+
+unsigned int openpic_vec_ipi;
+unsigned int openpic_vec_timer;
+unsigned int openpic_vec_spurious;
+
+/*
+ *  Accesses to the current processor's openpic registers
+ */
+#ifdef CONFIG_SMP
+#define THIS_CPU		Processor[cpu]
+#define DECL_THIS_CPU		int cpu = hard_smp_processor_id()
+#define CHECK_THIS_CPU		check_arg_cpu(cpu)
+#else
+#define THIS_CPU		Processor[hard_smp_processor_id()]
+#define DECL_THIS_CPU
+#define CHECK_THIS_CPU
+#endif /* CONFIG_SMP */
+
+#if 1
+#define check_arg_ipi(ipi) \
+    if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \
+	printk(KERN_ERR "open_pic.c:%d: illegal ipi %d\n", __LINE__, ipi);
+#define check_arg_timer(timer) \
+    if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \
+	printk(KERN_ERR "open_pic.c:%d: illegal timer %d\n", __LINE__, timer);
+#define check_arg_vec(vec) \
+    if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \
+	printk(KERN_ERR "open_pic.c:%d: illegal vector %d\n", __LINE__, vec);
+#define check_arg_pri(pri) \
+    if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
+	printk(KERN_ERR "open_pic.c:%d: illegal priority %d\n", __LINE__, pri);
+/*
+ * Print out a backtrace if it's out of range, since if it's larger than NR_IRQ's
+ * data has probably been corrupted and we're going to panic or deadlock later
+ * anyway --Troy
+ */
+extern unsigned long* _get_SP(void);
+#define check_arg_irq(irq) \
+    if (irq < open_pic_irq_offset || irq >= (NumSources+open_pic_irq_offset)){ \
+      printk(KERN_ERR "open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \
+      print_backtrace(_get_SP()); }
+#define check_arg_cpu(cpu) \
+    if (cpu < 0 || cpu >= OPENPIC_MAX_PROCESSORS){ \
+	printk(KERN_ERR "open_pic.c:%d: illegal cpu %d\n", __LINE__, cpu); \
+	print_backtrace(_get_SP()); }
+#else
+#define check_arg_ipi(ipi)	do {} while (0)
+#define check_arg_timer(timer)	do {} while (0)
+#define check_arg_vec(vec)	do {} while (0)
+#define check_arg_pri(pri)	do {} while (0)
+#define check_arg_irq(irq)	do {} while (0)
+#define check_arg_cpu(cpu)	do {} while (0)
+#endif
+
+#define GET_ISU(source)	ISU[(source) >> 4][(source) & 0xf]
+
+void __init openpic_init_IRQ(void)
+{
+        struct device_node *np;
+        int i;
+        unsigned int *addrp;
+        unsigned char* chrp_int_ack_special = 0;
+        unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
+        int nmi_irq = -1;
+#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
+        struct device_node *kbd;
+#endif
+
+        if (!(np = find_devices("pci"))
+            || !(addrp = (unsigned int *)
+                 get_property(np, "8259-interrupt-acknowledge", NULL)))
+                printk(KERN_ERR "Cannot find pci to get ack address\n");
+        else
+		chrp_int_ack_special = (unsigned char *)
+			__ioremap(addrp[prom_n_addr_cells(np)-1], 1, _PAGE_NO_CACHE);
+        /* hydra still sets OpenPIC_InitSenses to a static set of values */
+        if (OpenPIC_InitSenses == NULL) {
+                prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
+                OpenPIC_InitSenses = init_senses;
+                OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
+        }
+        openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq);
+        for ( i = 0 ; i < NUM_8259_INTERRUPTS  ; i++ )
+                irq_desc[i].handler = &i8259_pic;
+        i8259_init();
+}
+
+static inline u_int openpic_read(volatile u_int *addr)
+{
+	u_int val;
+
+	val = in_le32(addr);
+	return val;
+}
+
+static inline void openpic_write(volatile u_int *addr, u_int val)
+{
+	out_le32(addr, val);
+}
+
+static inline u_int openpic_readfield(volatile u_int *addr, u_int mask)
+{
+	u_int val = openpic_read(addr);
+	return val & mask;
+}
+
+static inline void openpic_writefield(volatile u_int *addr, u_int mask,
+			       u_int field)
+{
+	u_int val = openpic_read(addr);
+	openpic_write(addr, (val & ~mask) | (field & mask));
+}
+
+static inline void openpic_clearfield(volatile u_int *addr, u_int mask)
+{
+	openpic_writefield(addr, mask, 0);
+}
+
+static inline void openpic_setfield(volatile u_int *addr, u_int mask)
+{
+	openpic_writefield(addr, mask, mask);
+}
+
+static void openpic_safe_writefield(volatile u_int *addr, u_int mask,
+				    u_int field)
+{
+	unsigned int loops = 100000;
+
+	openpic_setfield(addr, OPENPIC_MASK);
+	while (openpic_read(addr) & OPENPIC_ACTIVITY) {
+		if (!loops--) {
+			printk(KERN_ERR "openpic_safe_writefield timeout\n");
+			break;
+		}
+	}
+	openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK);
+}
+
+#ifdef CONFIG_SMP
+static u_int openpic_read_IPI(volatile u_int* addr)
+{
+        u_int val = 0;
+
+	if (broken_ipi_registers)
+		/* yes this is right ... bug, feature, you decide! -- tgall */
+		val = in_be32(addr);
+	else
+		val = in_le32(addr);
+
+        return val;
+}
+
+static void openpic_test_broken_IPI(void)
+{
+	u_int t;
+
+	openpic_write(&OpenPIC->Global.IPI_Vector_Priority(0), OPENPIC_MASK);
+	t = openpic_read(&OpenPIC->Global.IPI_Vector_Priority(0));
+	if (t == le32_to_cpu(OPENPIC_MASK)) {
+		printk(KERN_INFO "OpenPIC reversed IPI registers detected\n");
+		broken_ipi_registers = 1;
+	}
+}
+
+/* because of the power3 be / le above, this is needed */
+static inline void openpic_writefield_IPI(volatile u_int* addr, u_int mask, u_int field)
+{
+        u_int  val = openpic_read_IPI(addr);
+        openpic_write(addr, (val & ~mask) | (field & mask));
+}
+
+static inline void openpic_clearfield_IPI(volatile u_int *addr, u_int mask)
+{
+        openpic_writefield_IPI(addr, mask, 0);
+}
+
+static inline void openpic_setfield_IPI(volatile u_int *addr, u_int mask)
+{
+        openpic_writefield_IPI(addr, mask, mask);
+}
+
+static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int field)
+{
+	unsigned int loops = 100000;
+
+        openpic_setfield_IPI(addr, OPENPIC_MASK);
+
+        /* wait until it's not in use */
+        /* BenH: Is this code really enough ? I would rather check the result
+         *       and eventually retry ...
+         */
+        while(openpic_read_IPI(addr) & OPENPIC_ACTIVITY) {
+		if (!loops--) {
+			printk(KERN_ERR "openpic_safe_writefield timeout\n");
+			break;
+		}
+	}
+
+        openpic_writefield_IPI(addr, mask, field | OPENPIC_MASK);
+}
+#endif /* CONFIG_SMP */
+
+void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
+			 int programmer_switch_irq)
+{
+	u_int t, i;
+	u_int timerfreq;
+	const char *version;
+
+	if (!OpenPIC_Addr) {
+		printk(KERN_INFO "No OpenPIC found !\n");
+		return;
+	}
+	OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr;
+
+	ppc_md.progress("openpic enter",0x122);
+
+	t = openpic_read(&OpenPIC->Global.Feature_Reporting0);
+	switch (t & OPENPIC_FEATURE_VERSION_MASK) {
+	case 1:
+		version = "1.0";
+		break;
+	case 2:
+		version = "1.2";
+		break;
+	case 3:
+		version = "1.3";
+		break;
+	default:
+		version = "?";
+		break;
+	}
+	NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >>
+			 OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1;
+	NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
+		      OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1;
+	printk(KERN_INFO "OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n",
+	       version, NumProcessors, NumSources, OpenPIC);
+	timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
+	if (timerfreq)
+		printk(KERN_INFO "OpenPIC timer frequency is %d.%06d MHz\n",
+		       timerfreq / 1000000, timerfreq % 1000000);
+
+	if (!main_pic)
+		return;
+
+	open_pic_irq_offset = offset;
+	chrp_int_ack_special = (volatile unsigned char*)chrp_ack;
+
+	find_ISUs();
+
+	/* Initialize timer interrupts */
+	ppc_md.progress("openpic timer",0x3ba);
+	for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
+		/* Disabled, Priority 0 */
+		openpic_inittimer(i, 0, openpic_vec_timer+i);
+		/* No processor */
+		openpic_maptimer(i, 0);
+	}
+
+#ifdef CONFIG_SMP
+	/* Initialize IPI interrupts */
+	ppc_md.progress("openpic ipi",0x3bb);
+	openpic_test_broken_IPI();
+	for (i = 0; i < OPENPIC_NUM_IPI; i++) {
+		/* Disabled, Priority 10..13 */
+		openpic_initipi(i, 10+i, openpic_vec_ipi+i);
+		/* IPIs are per-CPU */
+		irq_desc[openpic_vec_ipi+i].status |= IRQ_PER_CPU;
+		irq_desc[openpic_vec_ipi+i].handler = &open_pic_ipi;
+	}
+#endif
+
+	/* Initialize external interrupts */
+	ppc_md.progress("openpic ext",0x3bc);
+
+	openpic_set_priority(0xf);
+
+	/* SIOint (8259 cascade) is special */
+	if (offset) {
+		openpic_initirq(0, 8, offset, 1, 1);
+		openpic_mapirq(0, 1<<get_hard_smp_processor_id(0));
+	}
+
+	/* Init all external sources */
+	for (i = 1; i < NumSources; i++) {
+		int pri, sense;
+
+		/* the bootloader may have left it enabled (bad !) */
+		openpic_disable_irq(i+offset);
+
+		pri = (i == programmer_switch_irq)? 9: 8;
+		sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1;
+		if (sense)
+			irq_desc[i+offset].status = IRQ_LEVEL;
+
+		/* Enabled, Priority 8 or 9 */
+		openpic_initirq(i, pri, i+offset, !sense, sense);
+		/* Processor 0 */
+		openpic_mapirq(i, 1<<get_hard_smp_processor_id(0));
+	}
+
+	/* Init descriptors */
+	for (i = offset; i < NumSources + offset; i++)
+		irq_desc[i].handler = &open_pic;
+
+	/* Initialize the spurious interrupt */
+	ppc_md.progress("openpic spurious",0x3bd);
+	openpic_set_spurious(openpic_vec_spurious);
+
+	/* Initialize the cascade */
+	if (offset) {
+		if (request_irq(offset, no_action, SA_INTERRUPT,
+				"82c59 cascade", NULL))
+			printk(KERN_ERR "Unable to get OpenPIC IRQ 0 for cascade\n");
+	}
+	openpic_set_priority(0);
+	openpic_disable_8259_pass_through();
+
+	ppc_md.progress("openpic exit",0x222);
+}
+
+void openpic_setup_ISU(int isu_num, unsigned long addr)
+{
+	if (isu_num >= OPENPIC_MAX_ISU)
+		return;
+	ISU[isu_num] = (OpenPIC_SourcePtr) __ioremap(addr, 0x400, _PAGE_NO_CACHE);
+	if (isu_num >= NumISUs)
+		NumISUs = isu_num + 1;
+}
+
+void find_ISUs(void)
+{
+        /* Use /interrupt-controller/reg and
+         * /interrupt-controller/interrupt-ranges from OF device tree
+	 * the ISU array is setup in chrp_pci.c in ibm_add_bridges
+	 * as a result
+	 * -- tgall
+         */
+
+	/* basically each ISU is a bus, and this assumes that
+	 * open_pic_isu_count interrupts per bus are possible 
+	 * ISU == Interrupt Source
+	 */
+	NumSources = NumISUs * 0x10;
+	openpic_vec_ipi = NumSources + open_pic_irq_offset;
+	openpic_vec_timer = openpic_vec_ipi + OPENPIC_NUM_IPI; 
+	openpic_vec_spurious = openpic_vec_timer + OPENPIC_NUM_TIMERS;
+}
+
+static inline void openpic_reset(void)
+{
+	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
+			 OPENPIC_CONFIG_RESET);
+}
+
+static inline void openpic_enable_8259_pass_through(void)
+{
+	openpic_clearfield(&OpenPIC->Global.Global_Configuration0,
+			   OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
+}
+
+static void openpic_disable_8259_pass_through(void)
+{
+	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
+			 OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
+}
+
+/*
+ *  Find out the current interrupt
+ */
+static u_int openpic_irq(void)
+{
+	u_int vec;
+	DECL_THIS_CPU;
+
+	CHECK_THIS_CPU;
+	vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge,
+				OPENPIC_VECTOR_MASK);
+	return vec;
+}
+
+static void openpic_eoi(void)
+{
+	DECL_THIS_CPU;
+
+	CHECK_THIS_CPU;
+	openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
+	/* Handle PCI write posting */
+	(void)openpic_read(&OpenPIC->THIS_CPU.EOI);
+}
+
+
+static inline u_int openpic_get_priority(void)
+{
+	DECL_THIS_CPU;
+
+	CHECK_THIS_CPU;
+	return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority,
+				 OPENPIC_CURRENT_TASK_PRIORITY_MASK);
+}
+
+static void openpic_set_priority(u_int pri)
+{
+	DECL_THIS_CPU;
+
+	CHECK_THIS_CPU;
+	check_arg_pri(pri);
+	openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority,
+			   OPENPIC_CURRENT_TASK_PRIORITY_MASK, pri);
+}
+
+/*
+ *  Get/set the spurious vector
+ */
+static inline u_int openpic_get_spurious(void)
+{
+	return openpic_readfield(&OpenPIC->Global.Spurious_Vector,
+				 OPENPIC_VECTOR_MASK);
+}
+
+static void openpic_set_spurious(u_int vec)
+{
+	check_arg_vec(vec);
+	openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK,
+			   vec);
+}
+
+/*
+ * Convert a cpu mask from logical to physical cpu numbers.
+ */
+static inline u32 physmask(u32 cpumask)
+{
+	int i;
+	u32 mask = 0;
+
+	for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1)
+		mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
+	return mask;
+}
+
+void openpic_init_processor(u_int cpumask)
+{
+	openpic_write(&OpenPIC->Global.Processor_Initialization,
+		      physmask(cpumask));
+}
+
+#ifdef CONFIG_SMP
+/*
+ *  Initialize an interprocessor interrupt (and disable it)
+ *
+ *  ipi: OpenPIC interprocessor interrupt number
+ *  pri: interrupt source priority
+ *  vec: the vector it will produce
+ */
+static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
+{
+	check_arg_ipi(ipi);
+	check_arg_pri(pri);
+	check_arg_vec(vec);
+	openpic_safe_writefield_IPI(&OpenPIC->Global.IPI_Vector_Priority(ipi),
+				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,
+				(pri << OPENPIC_PRIORITY_SHIFT) | vec);
+}
+
+/*
+ *  Send an IPI to one or more CPUs
+ *  
+ *  Externally called, however, it takes an IPI number (0...OPENPIC_NUM_IPI)
+ *  and not a system-wide interrupt number
+ */
+void openpic_cause_IPI(u_int ipi, u_int cpumask)
+{
+	DECL_THIS_CPU;
+
+	CHECK_THIS_CPU;
+	check_arg_ipi(ipi);
+	openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
+		      physmask(cpumask));
+}
+
+void openpic_request_IPIs(void)
+{
+	int i;
+	
+	/*
+	 * Make sure this matches what is defined in smp.c for 
+	 * smp_message_{pass|recv}() or what shows up in 
+	 * /proc/interrupts will be wrong!!! --Troy */
+	
+	if (OpenPIC == NULL)
+		return;
+
+	request_irq(openpic_vec_ipi,
+		    openpic_ipi_action, 0, "IPI0 (call function)", 0);
+	request_irq(openpic_vec_ipi+1,
+		    openpic_ipi_action, 0, "IPI1 (reschedule)", 0);
+	request_irq(openpic_vec_ipi+2,
+		    openpic_ipi_action, 0, "IPI2 (invalidate tlb)", 0);
+	request_irq(openpic_vec_ipi+3,
+		    openpic_ipi_action, 0, "IPI3 (xmon break)", 0);
+
+	for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
+		openpic_enable_ipi(openpic_vec_ipi+i);
+}
+
+/*
+ * Do per-cpu setup for SMP systems.
+ *
+ * Get IPI's working and start taking interrupts.
+ *   -- Cort
+ */
+static spinlock_t openpic_setup_lock __initdata = SPIN_LOCK_UNLOCKED;
+
+void __init do_openpic_setup_cpu(void)
+{
+#ifdef CONFIG_IRQ_ALL_CPUS
+ 	int i;
+	u32 msk = 1 << hard_smp_processor_id();
+#endif
+
+	spin_lock(&openpic_setup_lock);
+
+#ifdef CONFIG_IRQ_ALL_CPUS
+ 	/* let the openpic know we want intrs. default affinity
+ 	 * is 0xffffffff until changed via /proc
+ 	 * That's how it's done on x86. If we want it differently, then
+ 	 * we should make sure we also change the default values of irq_affinity
+ 	 * in irq.c.
+ 	 */
+ 	for (i = 0; i < NumSources ; i++)
+		openpic_mapirq(i, openpic_read(&GET_ISU(i).Destination) | msk);
+#endif /* CONFIG_IRQ_ALL_CPUS */
+ 	openpic_set_priority(0);
+
+	spin_unlock(&openpic_setup_lock);
+}
+#endif /* CONFIG_SMP */
+
+/*
+ *  Initialize a timer interrupt (and disable it)
+ *
+ *  timer: OpenPIC timer number
+ *  pri: interrupt source priority
+ *  vec: the vector it will produce
+ */
+static void __init openpic_inittimer(u_int timer, u_int pri, u_int vec)
+{
+	check_arg_timer(timer);
+	check_arg_pri(pri);
+	check_arg_vec(vec);
+	openpic_safe_writefield(&OpenPIC->Global.Timer[timer].Vector_Priority,
+				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,
+				(pri << OPENPIC_PRIORITY_SHIFT) | vec);
+}
+
+/*
+ *  Map a timer interrupt to one or more CPUs
+ */
+static void __init openpic_maptimer(u_int timer, u_int cpumask)
+{
+	check_arg_timer(timer);
+	openpic_write(&OpenPIC->Global.Timer[timer].Destination,
+		      physmask(cpumask));
+}
+
+
+/*
+ *
+ * All functions below take an offset'ed irq argument
+ *
+ */
+
+
+/*
+ *  Enable/disable an external interrupt source
+ *
+ *  Externally called, irq is an offseted system-wide interrupt number
+ */
+static void openpic_enable_irq(u_int irq)
+{
+	unsigned int loops = 100000;
+	check_arg_irq(irq);
+
+	openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK);
+	/* make sure mask gets to controller before we return to user */
+	do {
+		if (!loops--) {
+			printk(KERN_ERR "openpic_enable_irq timeout\n");
+			break;
+		}
+
+		mb(); /* sync is probably useless here */
+	} while(openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority,
+			OPENPIC_MASK));
+}
+
+static void openpic_disable_irq(u_int irq)
+{
+	u32 vp;
+	unsigned int loops = 100000;
+	
+	check_arg_irq(irq);
+
+	openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK);
+	/* make sure mask gets to controller before we return to user */
+	do {
+		if (!loops--) {
+			printk(KERN_ERR "openpic_disable_irq timeout\n");
+			break;
+		}
+
+		mb();  /* sync is probably useless here */
+		vp = openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority,
+    			OPENPIC_MASK | OPENPIC_ACTIVITY);
+	} while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK));
+}
+
+#ifdef CONFIG_SMP
+/*
+ *  Enable/disable an IPI interrupt source
+ *  
+ *  Externally called, irq is an offseted system-wide interrupt number
+ */
+void openpic_enable_ipi(u_int irq)
+{
+	irq -= openpic_vec_ipi;
+	check_arg_ipi(irq);
+	openpic_clearfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK);
+
+}
+void openpic_disable_ipi(u_int irq)
+{
+   /* NEVER disable an IPI... that's just plain wrong! */
+}
+
+#endif
+
+/*
+ *  Initialize an interrupt source (and disable it!)
+ *
+ *  irq: OpenPIC interrupt number
+ *  pri: interrupt source priority
+ *  vec: the vector it will produce
+ *  pol: polarity (1 for positive, 0 for negative)
+ *  sense: 1 for level, 0 for edge
+ */
+static void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
+{
+	openpic_safe_writefield(&GET_ISU(irq).Vector_Priority,
+				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
+				OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK,
+				(pri << OPENPIC_PRIORITY_SHIFT) | vec |
+				(pol ? OPENPIC_POLARITY_POSITIVE :
+			    		OPENPIC_POLARITY_NEGATIVE) |
+				(sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE));
+}
+
+/*
+ *  Map an interrupt source to one or more CPUs
+ */
+static void openpic_mapirq(u_int irq, u_int physmask)
+{
+	openpic_write(&GET_ISU(irq).Destination, physmask);
+}
+
+/*
+ *  Set the sense for an interrupt source (and disable it!)
+ *
+ *  sense: 1 for level, 0 for edge
+ */
+static inline void openpic_set_sense(u_int irq, int sense)
+{
+	openpic_safe_writefield(&GET_ISU(irq).Vector_Priority,
+				OPENPIC_SENSE_LEVEL,
+				(sense ? OPENPIC_SENSE_LEVEL : 0));
+}
+
+/* No spinlocks, should not be necessary with the OpenPIC
+ * (1 register = 1 interrupt and we have the desc lock).
+ */
+static void openpic_ack_irq(unsigned int irq_nr)
+{
+}
+
+static void openpic_end_irq(unsigned int irq_nr)
+{
+	if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
+		openpic_eoi();
+}
+
+static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
+{
+	openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask));
+}
+
+#ifdef CONFIG_SMP
+static void openpic_ack_ipi(unsigned int irq_nr)
+{
+}
+
+static void openpic_end_ipi(unsigned int irq_nr)
+{
+	/* IPIs are marked IRQ_PER_CPU. This has the side effect of
+	 * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
+	 * applying to them. We EOI them late to avoid re-entering.
+	 * however, I'm wondering if we could simply let them have the
+	 * SA_INTERRUPT flag and let them execute with all interrupts OFF.
+	 * This would have the side effect of either running cross-CPU
+	 * functions with interrupts off, or we can re-enable them explicitely
+	 * with a __sti() in smp_call_function_interrupt(), since
+	 * smp_call_function() is protected by a spinlock.
+	 * Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU
+	 * function calls IPI at all but that would make a special case.
+	 */
+	openpic_eoi();
+}
+
+static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+	smp_message_recv(cpl-openpic_vec_ipi, regs);
+}
+
+#endif /* CONFIG_SMP */
+
+int openpic_get_irq(struct pt_regs *regs)
+{
+	extern int i8259_irq(int cpu);
+
+	int irq = openpic_irq();
+
+	/* Management of the cascade should be moved out of here */
+        if (open_pic_irq_offset && irq == open_pic_irq_offset)
+        {
+                /*
+                 * This magic address generates a PCI IACK cycle.
+                 */
+		if ( chrp_int_ack_special )
+			irq = *chrp_int_ack_special;
+		else
+			irq = i8259_irq( smp_processor_id() );
+		openpic_eoi();
+        }
+	if (irq == openpic_vec_spurious)
+		irq = -1;
+	return irq;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/open_pic.h linux/arch/ppc64/kernel/open_pic.h
--- linux.orig/arch/ppc64/kernel/open_pic.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/open_pic.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,45 @@
+/*
+ *  arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling
+ *
+ *  Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive
+ *  for more details.
+ *  
+ */
+
+#ifndef _PPC64_KERNEL_OPEN_PIC_H
+#define _PPC64_KERNEL_OPEN_PIC_H
+
+#include <linux/config.h>
+
+#define OPENPIC_SIZE	0x40000
+
+/* OpenPIC IRQ controller structure */
+extern struct hw_interrupt_type open_pic;
+
+/* OpenPIC IPI controller structure */
+#ifdef CONFIG_SMP
+extern struct hw_interrupt_type open_pic_ipi;
+#endif /* CONFIG_SMP */
+
+extern u_int OpenPIC_NumInitSenses;
+extern u_char *OpenPIC_InitSenses;
+extern void* OpenPIC_Addr;
+
+/* Exported functions */
+extern void openpic_init(int, int, unsigned char *, int);
+extern void openpic_request_IPIs(void);
+extern void do_openpic_setup_cpu(void);
+extern int openpic_get_irq(struct pt_regs *regs);
+extern void openpic_init_processor(u_int cpumask);
+extern void openpic_setup_ISU(int isu_num, unsigned long addr);
+extern void openpic_cause_IPI(u_int ipi, u_int cpumask);
+
+extern inline int openpic_to_irq(int irq)
+{
+	return irq += NUM_8259_INTERRUPTS;
+}
+/*extern int open_pic_irq_offset;*/
+#endif /* _PPC64_KERNEL_OPEN_PIC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/open_pic_defs.h linux/arch/ppc64/kernel/open_pic_defs.h
--- linux.orig/arch/ppc64/kernel/open_pic_defs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/open_pic_defs.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,318 @@
+/*
+ *  linux/openpic.h -- OpenPIC definitions
+ *
+ *  Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This file is based on the following documentation:
+ *
+ *	The Open Programmable Interrupt Controller (PIC)
+ *	Register Interface Specification Revision 1.2
+ *
+ *	Issue Date: October 1995
+ *
+ *	Issued jointly by Advanced Micro Devices and Cyrix Corporation
+ *
+ *	AMD is a registered trademark of Advanced Micro Devices, Inc.
+ *	Copyright (C) 1995, Advanced Micro Devices, Inc. and Cyrix, Inc.
+ *	All Rights Reserved.
+ *
+ *  To receive a copy of this documentation, send an email to openpic@amd.com.
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive
+ *  for more details.
+ */
+
+#ifndef _LINUX_OPENPIC_H
+#define _LINUX_OPENPIC_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+/*
+ *  OpenPIC supports up to 2048 interrupt sources and up to 32 processors
+ */
+
+#define OPENPIC_MAX_SOURCES	2048
+#define OPENPIC_MAX_PROCESSORS	32
+#define OPENPIC_MAX_ISU		32
+
+#define OPENPIC_NUM_TIMERS	4
+#define OPENPIC_NUM_IPI		4
+#define OPENPIC_NUM_PRI		16
+#define OPENPIC_NUM_VECTORS	OPENPIC_MAX_SOURCES
+
+/*
+ *  OpenPIC Registers are 32 bits and aligned on 128 bit boundaries
+ */
+
+typedef struct _OpenPIC_Reg {
+	u_int Reg;					/* Little endian! */
+	char Pad[0xc];
+} OpenPIC_Reg;
+
+
+/*
+ *  Per Processor Registers
+ */
+
+typedef struct _OpenPIC_Processor {
+	/*
+	 *  Private Shadow Registers (for SLiC backwards compatibility)
+	 */
+	u_int IPI0_Dispatch_Shadow;			/* Write Only */
+	char Pad1[0x4];
+	u_int IPI0_Vector_Priority_Shadow;		/* Read/Write */
+	char Pad2[0x34];
+	/*
+	 *  Interprocessor Interrupt Command Ports
+	 */
+	OpenPIC_Reg _IPI_Dispatch[OPENPIC_NUM_IPI];	/* Write Only */
+	/*
+	 *  Current Task Priority Register
+	 */
+	OpenPIC_Reg _Current_Task_Priority;		/* Read/Write */
+	char Pad3[0x10];
+	/*
+	 *  Interrupt Acknowledge Register
+	 */
+	OpenPIC_Reg _Interrupt_Acknowledge;		/* Read Only */
+	/*
+	 *  End of Interrupt (EOI) Register
+	 */
+	OpenPIC_Reg _EOI;				/* Read/Write */
+	char Pad5[0xf40];
+} OpenPIC_Processor;
+
+
+    /*
+     *  Timer Registers
+     */
+
+typedef struct _OpenPIC_Timer {
+	OpenPIC_Reg _Current_Count;			/* Read Only */
+	OpenPIC_Reg _Base_Count;			/* Read/Write */
+	OpenPIC_Reg _Vector_Priority;			/* Read/Write */
+	OpenPIC_Reg _Destination;			/* Read/Write */
+} OpenPIC_Timer;
+
+
+    /*
+     *  Global Registers
+     */
+
+typedef struct _OpenPIC_Global {
+	/*
+	 *  Feature Reporting Registers
+	 */
+	OpenPIC_Reg _Feature_Reporting0;		/* Read Only */
+	OpenPIC_Reg _Feature_Reporting1;		/* Future Expansion */
+	/*
+	 *  Global Configuration Registers
+	 */
+	OpenPIC_Reg _Global_Configuration0;		/* Read/Write */
+	OpenPIC_Reg _Global_Configuration1;		/* Future Expansion */
+	/*
+	 *  Vendor Specific Registers
+	 */
+	OpenPIC_Reg _Vendor_Specific[4];
+	/*
+	 *  Vendor Identification Register
+	 */
+	OpenPIC_Reg _Vendor_Identification;		/* Read Only */
+	/*
+	 *  Processor Initialization Register
+	 */
+	OpenPIC_Reg _Processor_Initialization;		/* Read/Write */
+	/*
+	 *  IPI Vector/Priority Registers
+	 */
+	OpenPIC_Reg _IPI_Vector_Priority[OPENPIC_NUM_IPI]; /* Read/Write */
+	/*
+	 *  Spurious Vector Register
+	 */
+	OpenPIC_Reg _Spurious_Vector;			/* Read/Write */
+	/*
+	 *  Global Timer Registers
+	 */
+	OpenPIC_Reg _Timer_Frequency;			/* Read/Write */
+	OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS];
+	char Pad1[0xee00];
+} OpenPIC_Global;
+
+
+    /*
+     *  Interrupt Source Registers
+     */
+
+typedef struct _OpenPIC_Source {
+	OpenPIC_Reg _Vector_Priority;			/* Read/Write */
+	OpenPIC_Reg _Destination;			/* Read/Write */
+} OpenPIC_Source, *OpenPIC_SourcePtr;
+
+
+    /*
+     *  OpenPIC Register Map
+     */
+
+struct OpenPIC {
+	char Pad1[0x1000];
+	/*
+	 *  Global Registers
+	 */
+	OpenPIC_Global Global;
+	/*
+	 *  Interrupt Source Configuration Registers
+	 */
+	OpenPIC_Source Source[OPENPIC_MAX_SOURCES];
+	/*
+	 *  Per Processor Registers
+	 */
+	OpenPIC_Processor Processor[OPENPIC_MAX_PROCESSORS];
+};
+
+extern volatile struct OpenPIC *OpenPIC;
+
+
+/*
+ *  Current Task Priority Register
+ */
+
+#define OPENPIC_CURRENT_TASK_PRIORITY_MASK	0x0000000f
+
+/*
+ *  Who Am I Register
+ */
+
+#define OPENPIC_WHO_AM_I_ID_MASK		0x0000001f
+
+/*
+ *  Feature Reporting Register 0
+ */
+
+#define OPENPIC_FEATURE_LAST_SOURCE_MASK	0x07ff0000
+#define OPENPIC_FEATURE_LAST_SOURCE_SHIFT	16
+#define OPENPIC_FEATURE_LAST_PROCESSOR_MASK	0x00001f00
+#define OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT	8
+#define OPENPIC_FEATURE_VERSION_MASK		0x000000ff
+
+/*
+ *  Global Configuration Register 0
+ */
+
+#define OPENPIC_CONFIG_RESET			0x80000000
+#define OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE	0x20000000
+#define OPENPIC_CONFIG_BASE_MASK		0x000fffff
+
+/*
+ *  Vendor Identification Register
+ */
+
+#define OPENPIC_VENDOR_ID_STEPPING_MASK		0x00ff0000
+#define OPENPIC_VENDOR_ID_STEPPING_SHIFT	16
+#define OPENPIC_VENDOR_ID_DEVICE_ID_MASK	0x0000ff00
+#define OPENPIC_VENDOR_ID_DEVICE_ID_SHIFT	8
+#define OPENPIC_VENDOR_ID_VENDOR_ID_MASK	0x000000ff
+
+/*
+ *  Vector/Priority Registers
+ */
+
+#define OPENPIC_MASK				0x80000000
+#define OPENPIC_ACTIVITY			0x40000000	/* Read Only */
+#define OPENPIC_PRIORITY_MASK			0x000f0000
+#define OPENPIC_PRIORITY_SHIFT			16
+#define OPENPIC_VECTOR_MASK			0x000007ff
+
+
+/*
+ *  Interrupt Source Registers
+ */
+
+#define OPENPIC_POLARITY_POSITIVE		0x00800000
+#define OPENPIC_POLARITY_NEGATIVE		0x00000000
+#define OPENPIC_POLARITY_MASK			0x00800000
+#define OPENPIC_SENSE_LEVEL			0x00400000
+#define OPENPIC_SENSE_EDGE			0x00000000
+#define OPENPIC_SENSE_MASK			0x00400000
+
+
+/*
+ *  Timer Registers
+ */
+
+#define OPENPIC_COUNT_MASK			0x7fffffff
+#define OPENPIC_TIMER_TOGGLE			0x80000000
+#define OPENPIC_TIMER_COUNT_INHIBIT		0x80000000
+
+
+/*
+ *  Aliases to make life simpler
+ */
+
+/* Per Processor Registers */
+#define IPI_Dispatch(i)			_IPI_Dispatch[i].Reg
+#define Current_Task_Priority		_Current_Task_Priority.Reg
+#define Interrupt_Acknowledge		_Interrupt_Acknowledge.Reg
+#define EOI				_EOI.Reg
+
+/* Global Registers */
+#define Feature_Reporting0		_Feature_Reporting0.Reg
+#define Feature_Reporting1		_Feature_Reporting1.Reg
+#define Global_Configuration0		_Global_Configuration0.Reg
+#define Global_Configuration1		_Global_Configuration1.Reg
+#define Vendor_Specific(i)		_Vendor_Specific[i].Reg
+#define Vendor_Identification		_Vendor_Identification.Reg
+#define Processor_Initialization	_Processor_Initialization.Reg
+#define IPI_Vector_Priority(i)		_IPI_Vector_Priority[i].Reg
+#define Spurious_Vector			_Spurious_Vector.Reg
+#define Timer_Frequency			_Timer_Frequency.Reg
+
+/* Timer Registers */
+#define Current_Count			_Current_Count.Reg
+#define Base_Count			_Base_Count.Reg
+#define Vector_Priority			_Vector_Priority.Reg
+#define Destination			_Destination.Reg
+
+/* Interrupt Source Registers */
+#define Vector_Priority			_Vector_Priority.Reg
+#define Destination			_Destination.Reg
+
+/*
+ *  Local (static) OpenPIC Operations
+ */
+
+
+/* Global Operations */
+static void openpic_reset(void);
+static void openpic_enable_8259_pass_through(void);
+static void openpic_disable_8259_pass_through(void);
+static u_int openpic_irq(void);
+static void openpic_eoi(void);
+static u_int openpic_get_priority(void);
+static void openpic_set_priority(u_int pri);
+static u_int openpic_get_spurious(void);
+static void openpic_set_spurious(u_int vector);
+
+#ifdef CONFIG_SMP
+/* Interprocessor Interrupts */
+static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
+static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
+#endif
+
+/* Timer Interrupts */
+static void openpic_inittimer(u_int timer, u_int pri, u_int vector);
+static void openpic_maptimer(u_int timer, u_int cpumask);
+
+/* Interrupt Sources */
+static void openpic_enable_irq(u_int irq);
+static void openpic_disable_irq(u_int irq);
+static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
+			    int is_level);
+static void openpic_mapirq(u_int irq, u_int cpumask);
+static void openpic_set_sense(u_int irq, int sense);
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_OPENPIC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pSeries_hvCall.S linux/arch/ppc64/kernel/pSeries_hvCall.S
--- linux.orig/arch/ppc64/kernel/pSeries_hvCall.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pSeries_hvCall.S	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,70 @@
+/*
+ * arch/ppc64/kernel/pSeries_hvCall.S
+ *
+ *
+ * This file contains the generic code to perform a call to the
+ * pSeries LPAR hypervisor.
+ * NOTE: this file will go away when we move to inline this work.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include "ppc_asm.h"
+	
+/*
+ * hcall interface to pSeries LPAR
+ */
+#define HSC .long 0x44000022
+
+/* long plpar_hcall(unsigned long opcode,	 R3 
+		 unsigned long arg1,		 R4 
+		 unsigned long arg2,		 R5 
+		 unsigned long arg3,		 R6 
+		 unsigned long arg4,		 R7 
+		 unsigned long *out1,		 R8 
+		 unsigned long *out2,		 R9
+		 unsigned long *out3);		 R10
+ */
+
+	.text
+_GLOBAL(plpar_hcall)
+	mfcr	r0
+	std	r0,-8(r1)
+	stdu	r1,-32(r1)
+
+        std     r8,-8(r1)       /* Save out ptrs. */
+        std     r9,-16(r1)
+        std     r10,-24(r1)
+	
+	HSC                     /* invoke the hypervisor */
+
+        ld      r10,-8(r1)      /* Fetch r4-r7 ret args. */
+        std     r4,0(r10)
+        ld      r10,-16(r1)
+        std     r5,0(r10)
+        ld      r10,-24(r1)
+        std     r6,0(r10)
+
+	ld	r1,0(r1)
+	ld	r0,-8(r1)
+	mtcrf	0xff,r0
+	blr                     /* return r3 = status */
+
+
+/* Simple interface with no output values (other than status) */
+_GLOBAL(plpar_hcall_norets)
+	mfcr	r0
+	std	r0,-8(r1)
+	HSC                     /* invoke the hypervisor */
+	ld	r0,-8(r1)
+	mtcrf	0xff,r0
+	blr                     /* return r3 = status */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pSeries_lpar.c linux/arch/ppc64/kernel/pSeries_lpar.c
--- linux.orig/arch/ppc64/kernel/pSeries_lpar.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pSeries_lpar.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,855 @@
+/*
+ * pSeries_lpar.c
+ * Copyright (C) 2001 Todd Inglett, IBM Corporation
+ *
+ * pSeries LPAR support.
+ * 
+ * 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/kernel.h>
+#include <asm/processor.h>
+#include <asm/semaphore.h>
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/abs_addr.h>
+#include <asm/mmu_context.h>
+#include <asm/ppcdebug.h>
+#include <asm/pci_dma.h>
+#include <linux/pci.h>
+#include <asm/naca.h>
+
+/* Status return values */
+#define H_Success	0
+#define H_Busy		1	/* Hardware busy -- retry later */
+#define H_Hardware	-1	/* Hardware error */
+#define H_Function	-2	/* Function not supported */
+#define H_Privilege	-3	/* Caller not privileged */
+#define H_Parameter	-4	/* Parameter invalid, out-of-range or conflicting */
+#define H_Bad_Mode	-5	/* Illegal msr value */
+#define H_PTEG_Full	-6	/* PTEG is full */
+#define H_Not_Found	-7	/* PTE was not found" */
+#define H_Reserved_DABR	-8	/* DABR address is reserved by the hypervisor on this processor" */
+
+/* Flags */
+#define H_LARGE_PAGE		(1UL<<(63-16))
+#define H_EXACT		    (1UL<<(63-24))	/* Use exact PTE or return H_PTEG_FULL */
+#define H_R_XLATE		(1UL<<(63-25))	/* include a valid logical page num in the pte if the valid bit is set */
+#define H_READ_4		(1UL<<(63-26))	/* Return 4 PTEs */
+#define H_AVPN			(1UL<<(63-32))	/* An avpn is provided as a sanity test */
+#define H_ICACHE_INVALIDATE	(1UL<<(63-40))	/* icbi, etc.  (ignored for IO pages) */
+#define H_ICACHE_SYNCHRONIZE	(1UL<<(63-41))	/* dcbst, icbi, etc (ignored for IO pages */
+#define H_ZERO_PAGE		(1UL<<(63-48))	/* zero the page before mapping (ignored for IO pages) */
+#define H_COPY_PAGE		(1UL<<(63-49))
+#define H_N			(1UL<<(63-61))
+#define H_PP1			(1UL<<(63-62))
+#define H_PP2			(1UL<<(63-63))
+
+
+
+/* pSeries hypervisor opcodes */
+#define H_REMOVE		0x04
+#define H_ENTER			0x08
+#define H_READ			0x0c
+#define H_CLEAR_MOD		0x10
+#define H_CLEAR_REF		0x14
+#define H_PROTECT		0x18
+#define H_GET_TCE		0x1c
+#define H_PUT_TCE		0x20
+#define H_SET_SPRG0		0x24
+#define H_SET_DABR		0x28
+#define H_PAGE_INIT		0x2c
+#define H_SET_ASR		0x30
+#define H_ASR_ON		0x34
+#define H_ASR_OFF		0x38
+#define H_LOGICAL_CI_LOAD	0x3c
+#define H_LOGICAL_CI_STORE	0x40
+#define H_LOGICAL_CACHE_LOAD	0x44
+#define H_LOGICAL_CACHE_STORE	0x48
+#define H_LOGICAL_ICBI		0x4c
+#define H_LOGICAL_DCBF		0x50
+#define H_GET_TERM_CHAR		0x54
+#define H_PUT_TERM_CHAR		0x58
+#define H_REAL_TO_LOGICAL	0x5c
+#define H_HYPERVISOR_DATA	0x60
+#define H_EOI			0x64
+#define H_CPPR			0x68
+#define H_IPI			0x6c
+#define H_IPOLL			0x70
+#define H_XIRR			0x74
+
+#define HSC			".long 0x44000022\n"
+#define H_ENTER_r3		"li	3, 0x08\n"
+
+/* plpar_hcall() -- Generic call interface using above opcodes
+ *
+ * The actual call interface is a hypervisor call instruction with
+ * the opcode in R3 and input args in R4-R7.
+ * Status is returned in R3 with variable output values in R4-R11.
+ * Only H_PTE_READ with H_READ_4 uses R6-R11 so we ignore it for now
+ * and return only two out args which MUST ALWAYS BE PROVIDED.
+ */
+long plpar_hcall(unsigned long opcode,
+		 unsigned long arg1,
+		 unsigned long arg2,
+		 unsigned long arg3,
+		 unsigned long arg4,
+		 unsigned long *out1,
+		 unsigned long *out2,
+		 unsigned long *out3);
+
+/* Same as plpar_hcall but for those opcodes that return no values
+ * other than status.  Slightly more efficient.
+ */
+long plpar_hcall_norets(unsigned long opcode, ...);
+
+
+long plpar_pte_enter(unsigned long flags,
+		     unsigned long ptex,
+		     unsigned long new_pteh, unsigned long new_ptel,
+		     unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
+{
+	unsigned long dummy, ret;
+	ret = plpar_hcall(H_ENTER, flags, ptex, new_pteh, new_ptel,
+			   old_pteh_ret, old_ptel_ret, &dummy);
+	return(ret);
+}
+
+long plpar_pte_remove(unsigned long flags,
+		      unsigned long ptex,
+		      unsigned long avpn,
+		      unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
+{
+	unsigned long dummy;
+	return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0,
+			   old_pteh_ret, old_ptel_ret, &dummy);
+}
+
+long plpar_pte_read(unsigned long flags,
+		    unsigned long ptex,
+		    unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
+{
+	unsigned long dummy;
+	return plpar_hcall(H_READ, flags, ptex, 0, 0,
+			   old_pteh_ret, old_ptel_ret, &dummy);
+}
+
+long plpar_pte_protect(unsigned long flags,
+		       unsigned long ptex,
+		       unsigned long avpn)
+{
+	return plpar_hcall_norets(H_PROTECT, flags, ptex);
+}
+
+long plpar_tce_get(unsigned long liobn,
+		   unsigned long ioba,
+		   unsigned long *tce_ret)
+{
+	unsigned long dummy;
+	return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0,
+			   tce_ret, &dummy, &dummy);
+}
+
+
+long plpar_tce_put(unsigned long liobn,
+		   unsigned long ioba,
+		   unsigned long tceval)
+{
+	return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
+}
+
+long plpar_get_term_char(unsigned long termno,
+			 unsigned long *len_ret,
+			 char *buf_ret)
+{
+	unsigned long *lbuf = (unsigned long *)buf_ret;  /* ToDo: alignment? */
+	return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0,
+			   len_ret, lbuf+0, lbuf+1);
+}
+
+long plpar_put_term_char(unsigned long termno,
+			 unsigned long len,
+			 const char *buffer)
+{
+	unsigned long dummy;
+	unsigned long *lbuf = (unsigned long *)buffer;  /* ToDo: alignment? */
+	return plpar_hcall(H_PUT_TERM_CHAR, termno, len,
+			   lbuf[0], lbuf[1], &dummy, &dummy, &dummy);
+}
+
+long plpar_eoi(unsigned long xirr)
+{
+	return plpar_hcall_norets(H_EOI, xirr);
+}
+
+long plpar_cppr(unsigned long cppr)
+{
+	return plpar_hcall_norets(H_CPPR, cppr);
+}
+
+long plpar_ipi(unsigned long servernum,
+	       unsigned long mfrr)
+{
+	return plpar_hcall_norets(H_IPI, servernum, mfrr);
+}
+
+long plpar_xirr(unsigned long *xirr_ret)
+{
+	unsigned long dummy;
+	return plpar_hcall(H_XIRR, 0, 0, 0, 0,
+			   xirr_ret, &dummy, &dummy);
+}
+
+long plpar_ipoll(unsigned long servernum, unsigned long* xirr_ret, unsigned long* mfrr_ret)
+{
+	unsigned long dummy;
+	return plpar_hcall(H_IPOLL, servernum, 0, 0, 0,
+			   xirr_ret, mfrr_ret, &dummy);
+}
+
+/*
+ * The following section contains code that ultimately should
+ * be put in the relavent file (htab.c, xics.c, etc).  It has
+ * been put here for the time being in order to ease maintainence
+ * of the pSeries LPAR code until it can all be put into CVS.
+ */
+static void hpte_invalidate_pSeriesLP(unsigned long slot)
+{
+	HPTE old_pte;
+	unsigned long lpar_rc;
+	unsigned long flags = 0;
+			
+	lpar_rc = plpar_pte_remove(flags,
+				   slot,
+				   0,
+				   &old_pte.dw0.dword0, 
+				   &old_pte.dw1.dword1);
+	if (lpar_rc != H_Success) BUG();
+}
+
+/* NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
+ * the low 3 bits of flags happen to line up.  So no transform is needed.
+ * We can probably optimize here and assume the high bits of newpp are
+ * already zero.  For now I am paranoid.
+ */
+static void hpte_updatepp_pSeriesLP(long slot, unsigned long newpp, unsigned long va)
+{
+	unsigned long lpar_rc;
+	unsigned long flags;
+	flags =   newpp & 3;
+	lpar_rc = plpar_pte_protect( flags,
+				     slot,
+				     0);
+	if (lpar_rc != H_Success) {
+		udbg_printf( " bad return code from pte protect rc = %lx \n", lpar_rc); 
+		for (;;);
+	}
+}
+
+static void hpte_updateboltedpp_pSeriesLP(unsigned long newpp, unsigned long ea)
+{
+	unsigned long lpar_rc;
+	unsigned long vsid,va,vpn,flags;
+	long slot;
+
+	vsid = get_kernel_vsid( ea );
+	va = ( vsid << 28 ) | ( ea & 0x0fffffff );
+	vpn = va >> PAGE_SHIFT;
+
+	slot = ppc_md.hpte_find( vpn );
+	flags =   newpp & 3;
+	lpar_rc = plpar_pte_protect( flags,
+				     slot,
+				     0);
+	if (lpar_rc != H_Success) {
+		udbg_printf( " bad return code from pte bolted protect rc = %lx \n", lpar_rc); 
+		for (;;);
+	}
+}
+
+
+static unsigned long hpte_getword0_pSeriesLP(unsigned long slot)
+{
+	unsigned long dword0;
+	unsigned long lpar_rc;
+	unsigned long dummy_word1;
+	unsigned long flags;
+	/* Read 1 pte at a time                        */
+	/* Do not need RPN to logical page translation */
+	/* No cross CEC PFT access                     */
+	flags = 0;
+	
+	lpar_rc = plpar_pte_read(flags,
+				 slot,
+				 &dword0, &dummy_word1);
+	if (lpar_rc != H_Success) {
+		udbg_printf(" error on pte read in get_hpte0 rc = %lx \n", lpar_rc);
+		for (;;);
+	}
+
+	return(dword0);
+}
+
+static long hpte_selectslot_pSeriesLP(unsigned long vpn)
+{
+	unsigned long primary_hash;
+	unsigned long hpteg_slot;
+	unsigned i, k;
+	unsigned long flags;
+	HPTE  pte_read;
+	unsigned long lpar_rc;
+
+	/* Search the primary group for an available slot */
+	primary_hash = hpt_hash(vpn, 0);
+
+	hpteg_slot = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+
+	/* Read 1 pte at a time                        */
+	/* Do not need RPN to logical page translation */
+	/* No cross CEC PFT access                     */
+	flags = 0;
+	for (i=0; i<HPTES_PER_GROUP; ++i) {
+		/* read the hpte entry from the slot */
+		lpar_rc = plpar_pte_read(flags,
+					 hpteg_slot + i,
+					 &pte_read.dw0.dword0, &pte_read.dw1.dword1);
+		if (lpar_rc != H_Success) {
+			udbg_printf(" read of hardware page table failed rc = %lx \n", lpar_rc); 
+			for (;;);
+		}
+		if ( pte_read.dw0.dw0.v == 0 ) {
+			/* If an available slot found, return it */
+			return hpteg_slot + i;
+		}
+
+	}
+
+
+	/* Search the secondary group for an available slot */
+	hpteg_slot = ( ~primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+
+
+	for (i=0; i<HPTES_PER_GROUP; ++i) {
+		/* read the hpte entry from the slot */
+		lpar_rc = plpar_pte_read(flags,
+					 hpteg_slot + i,
+					 &pte_read.dw0.dword0, &pte_read.dw1.dword1);
+		if (lpar_rc != H_Success) {
+			udbg_printf(" read of hardware page table failed2 rc = %lx  \n", lpar_rc); 
+			for (;;);
+		}
+		if ( pte_read.dw0.dw0.v == 0 ) {
+			/* If an available slot found, return it */
+			return hpteg_slot + i;
+		}
+
+	}
+
+	/* No available entry found in secondary group */
+
+
+	/* Select an entry in the primary group to replace */
+
+	hpteg_slot = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+
+	k = htab_data.next_round_robin++ & 0x7;
+
+	for (i=0; i<HPTES_PER_GROUP; ++i) {
+		if (k == HPTES_PER_GROUP)
+			k = 0;
+
+		lpar_rc = plpar_pte_read(flags,
+					 hpteg_slot + k,
+					 &pte_read.dw0.dword0, &pte_read.dw1.dword1);
+		if (lpar_rc != H_Success) {
+			udbg_printf( " pte read failed - rc = %lx", lpar_rc); 
+			for (;;);
+		}
+		if (  ! pte_read.dw0.dw0.bolted)
+		{
+			hpteg_slot += k;
+			/* Invalidate the current entry */
+			ppc_md.hpte_invalidate(hpteg_slot); 
+			return hpteg_slot;
+		}
+		++k;
+	}
+
+	/* No non-bolted entry found in primary group - time to panic */
+	udbg_printf("select_hpte_slot - No non-bolted HPTE in group 0x%lx! \n", hpteg_slot/HPTES_PER_GROUP);
+	udbg_printf("No non-bolted HPTE in group %lx", (unsigned long)hpteg_slot/HPTES_PER_GROUP);
+	for (;;);
+
+	/* never executes - avoid compiler errors */
+	return 0;
+}
+
+
+static void hpte_create_valid_pSeriesLP(unsigned long slot, unsigned long vpn,
+					unsigned long prpn, unsigned hash, 
+					void *ptep, unsigned hpteflags, 
+					unsigned bolted)
+{
+	/* Local copy of HPTE */
+	struct {
+		/* Local copy of first doubleword of HPTE */
+		union {
+			unsigned long d;
+			Hpte_dword0   h;
+		} dw0;
+		/* Local copy of second doubleword of HPTE */
+		union {
+			unsigned long     d;
+			Hpte_dword1       h;
+			Hpte_dword1_flags f;
+		} dw1;
+	} lhpte;
+	
+	unsigned long avpn = vpn >> 11;
+	unsigned long arpn = physRpn_to_absRpn( prpn );
+
+	unsigned long lpar_rc;
+	unsigned long flags;
+	HPTE ret_hpte;
+
+	/* Fill in the local HPTE with absolute rpn, avpn and flags */
+	lhpte.dw1.d        = 0;
+	lhpte.dw1.h.rpn    = arpn;
+	lhpte.dw1.f.flags  = hpteflags;
+
+	lhpte.dw0.d        = 0;
+	lhpte.dw0.h.avpn   = avpn;
+	lhpte.dw0.h.h      = hash;
+	lhpte.dw0.h.bolted = bolted;
+	lhpte.dw0.h.v      = 1;
+
+	/* Now fill in the actual HPTE */
+	/* Set CEC cookie to 0                  */
+	/* Large page = 0                       */
+	/* Zero page = 0                        */
+	/* I-cache Invalidate = 0               */
+	/* I-cache synchronize = 0              */
+	/* Exact = 1 - only modify exact entry  */
+	flags = H_EXACT;
+
+	if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
+		lhpte.dw1.f.flags &= ~_PAGE_COHERENT;
+#if 1
+	__asm__ __volatile__ (
+		 H_ENTER_r3
+		 "mr	4, %1\n"
+		 "mr	5, %2\n"
+		 "mr	6, %3\n"
+		 "mr	7, %4\n"
+		 HSC
+		 "mr	%0, 3\n"
+		 : "=r" (lpar_rc)
+		 : "r" (flags), "r" (slot), "r" (lhpte.dw0.d), "r" (lhpte.dw1.d)
+		 : "r3", "r4", "r5", "r6", "r7", "cc");
+#else
+	lpar_rc =  plpar_pte_enter(flags,
+				   slot,
+				   lhpte.dw0.d,
+				   lhpte.dw1.d,
+				   &ret_hpte.dw0.dword0,
+				   &ret_hpte.dw1.dword1);
+#endif
+	if (lpar_rc != H_Success) {
+		udbg_printf("error on pte enter lapar rc = %ld\n",lpar_rc);
+		udbg_printf("ent: s=%lx, dw0=%lx, dw1=%lx\n", slot, lhpte.dw0.d, lhpte.dw1.d);
+		/* xmon_backtrace("backtrace"); */
+		for (;;);
+	}
+}
+
+static long hpte_find_pSeriesLP(unsigned long vpn)
+{
+	union {
+		unsigned long d;
+		Hpte_dword0   h;
+	} hpte_dw0;
+	long slot;
+	unsigned long hash;
+	unsigned long i,j;
+
+	hash = hpt_hash(vpn, 0);
+	for ( j=0; j<2; ++j ) {
+		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+		for ( i=0; i<HPTES_PER_GROUP; ++i ) {
+			hpte_dw0.d = hpte_getword0_pSeriesLP( slot );
+			if ( ( hpte_dw0.h.avpn == ( vpn >> 11 ) ) &&
+			     ( hpte_dw0.h.v ) &&
+			     ( hpte_dw0.h.h == j ) ) {
+				/* HPTE matches */
+				if ( j )
+					slot = -slot;
+				return slot;
+			}
+			++slot;
+		}
+		hash = ~hash;
+	}
+	return -1;
+} 
+
+/*
+ * Create a pte - LPAR .  Used during initialization only.
+ * We assume the PTE will fit in the primary PTEG.
+ */
+void make_pte_LPAR(HPTE *htab,
+		   unsigned long va, unsigned long pa, int mode,
+		   unsigned long hash_mask, int large)
+{
+	HPTE  local_hpte, ret_hpte;
+	unsigned long hash, slot, flags,lpar_rc, vpn;
+
+	if (large)
+		vpn = va >> 24;
+	else
+		vpn = va >> 12;
+
+	hash = hpt_hash(vpn, large);
+
+	slot = ((hash & hash_mask)*HPTES_PER_GROUP);
+
+	local_hpte.dw1.dword1 = pa | mode;
+	local_hpte.dw0.dword0 = 0;
+	local_hpte.dw0.dw0.avpn = va >> 23;
+	local_hpte.dw0.dw0.bolted = 1;				/* bolted */
+	if (large)
+		local_hpte.dw0.dw0.l = 1;  /* large page */
+	local_hpte.dw0.dw0.v = 1;
+
+	/* Set CEC cookie to 0                   */
+	/* Zero page = 0                         */
+	/* I-cache Invalidate = 0                */
+	/* I-cache synchronize = 0               */
+	/* Exact = 0 - modify any entry in group */
+	flags = 0;
+#if 1
+	__asm__ __volatile__ (
+		 H_ENTER_r3
+		 "mr	4, %1\n"
+		 "mr	5, %2\n"
+		 "mr	6, %3\n"
+		 "mr	7, %4\n"
+		 HSC
+		 "mr	%0, 3\n"
+		 : "=r" (lpar_rc)
+		 : "r" (flags), "r" (slot), "r" (local_hpte.dw0.dword0), "r" (local_hpte.dw1.dword1)
+		 : "r3", "r4", "r5", "r6", "r7", "cc");
+#else
+	lpar_rc =  plpar_pte_enter(flags,
+				   slot,
+				   local_hpte.dw0.dword0,
+				   local_hpte.dw1.dword1,
+				   &ret_hpte.dw0.dword0,
+				   &ret_hpte.dw1.dword1);
+#endif
+#if 0 /* NOTE: we explicitly do not check return status here because it is
+       * "normal" for early boot code to map io regions for which a partition
+       * has no access.  However, we will die if we actually fault on these
+       * "permission denied" pages.
+       */
+	if (lpar_rc != H_Success) {
+		/* pSeriesLP_init_early(); */
+		udbg_printf("flags=%lx, slot=%lx, dword0=%lx, dword1=%lx, rc=%d\n", flags, slot, local_hpte.dw0.dword0,local_hpte.dw1.dword1, lpar_rc);
+		BUG();
+	}
+#endif
+}
+
+static void tce_build_pSeriesLP(struct TceTable *tbl, long tcenum, 
+				unsigned long uaddr, int direction )
+{
+	u64 set_tce_rc;
+	union Tce tce;
+	
+	PPCDBG(PPCDBG_TCE, "build_tce: uaddr = 0x%lx\n", uaddr);
+	PPCDBG(PPCDBG_TCE, "\ttcenum = 0x%lx, tbl = 0x%lx, index=%lx\n", 
+	       tcenum, tbl, tbl->index);
+
+	tce.wholeTce = 0;
+	tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT;
+
+	tce.tceBits.readWrite = 1;
+	if ( direction != PCI_DMA_TODEVICE ) tce.tceBits.pciWrite = 1;
+
+	set_tce_rc = plpar_tce_put((u64)tbl->index, 
+				 (u64)tcenum << 12, 
+				 tce.wholeTce );
+
+	if(set_tce_rc) {
+		printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", set_tce_rc);
+		printk("\tindex   = 0x%lx\n", (u64)tbl->index);
+		printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
+		printk("\ttce val = 0x%lx\n", tce.wholeTce );
+	}
+}
+
+static void tce_free_one_pSeriesLP(struct TceTable *tbl, long tcenum)
+{
+	u64 set_tce_rc;
+	union Tce tce;
+
+	tce.wholeTce = 0;
+	set_tce_rc = plpar_tce_put((u64)tbl->index, 
+				 (u64)tcenum << 12,
+				 tce.wholeTce );
+	if ( set_tce_rc ) {
+		printk("tce_free_one_pSeriesLP: plpar_tce_put failed\n");
+		printk("\trc      = %ld\n", set_tce_rc);
+		printk("\tindex   = 0x%lx\n", (u64)tbl->index);
+		printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
+		printk("\ttce val = 0x%lx\n", tce.wholeTce );
+	}
+
+}
+
+/* PowerPC Interrupts for lpar. */
+/* NOTE: this typedef is duplicated (for now) from xics.c! */
+typedef struct {
+	int (*xirr_info_get)(int cpu);
+	void (*xirr_info_set)(int cpu, int val);
+	void (*cppr_info)(int cpu, u8 val);
+	void (*qirr_info)(int cpu, u8 val);
+} xics_ops;
+static int pSeriesLP_xirr_info_get(int n_cpu)
+{
+	unsigned long lpar_rc;
+	unsigned long return_value; 
+
+	lpar_rc = plpar_xirr(&return_value);
+	if (lpar_rc != H_Success) {
+		panic(" bad return code xirr - rc = %lx \n", lpar_rc); 
+	}
+	return ((int)(return_value));
+}
+
+static void pSeriesLP_xirr_info_set(int n_cpu, int value)
+{
+	unsigned long lpar_rc;
+	unsigned long val64 = value & 0xffffffff;
+
+	lpar_rc = plpar_eoi(val64);
+	if (lpar_rc != H_Success) {
+		panic(" bad return code EOI - rc = %ld, value=%lx \n", lpar_rc, val64); 
+	}
+}
+
+static void pSeriesLP_cppr_info(int n_cpu, u8 value)
+{
+	unsigned long lpar_rc;
+
+	lpar_rc = plpar_cppr(value);
+	if (lpar_rc != H_Success) {
+		panic(" bad return code cppr - rc = %lx \n", lpar_rc); 
+	}
+}
+
+static void pSeriesLP_qirr_info(int n_cpu , u8 value)
+{
+	unsigned long lpar_rc;
+
+	lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu),value);
+	if (lpar_rc != H_Success) {
+    udbg_printf("pSeriesLP_qirr_info - plpar_ipi failed!!!!!!!! \n");
+		panic(" bad return code qirr -ipi  - rc = %lx \n", lpar_rc); 
+	}
+}
+
+xics_ops pSeriesLP_ops = {
+	pSeriesLP_xirr_info_get,
+	pSeriesLP_xirr_info_set,
+	pSeriesLP_cppr_info,
+	pSeriesLP_qirr_info
+};
+/* end TAI-LPAR */
+
+
+int vtermno;	/* virtual terminal# for udbg  */
+
+static void udbg_putcLP(unsigned char c)
+{
+	char buf[16];
+	unsigned long rc;
+
+	if (c == '\n')
+		udbg_putcLP('\r');
+
+	buf[0] = c;
+	do {
+		rc = plpar_put_term_char(vtermno, 1, buf);
+	} while(rc == H_Busy);
+}
+
+/* Buffered chars getc */
+static long inbuflen;
+static long inbuf[2];	/* must be 2 longs */
+
+static int udbg_getc_pollLP(void)
+{
+	/* The interface is tricky because it may return up to 16 chars.
+	 * We save them statically for future calls to udbg_getc().
+	 */
+	char ch, *buf = (char *)inbuf;
+	int i;
+	long rc;
+	if (inbuflen == 0) {
+		/* get some more chars. */
+		inbuflen = 0;
+		rc = plpar_get_term_char(vtermno, &inbuflen, buf);
+		if (rc != H_Success)
+			inbuflen = 0;	/* otherwise inbuflen is garbage */
+	}
+	if (inbuflen <= 0 || inbuflen > 16) {
+		/* Catch error case as well as other oddities (corruption) */
+		inbuflen = 0;
+		return -1;
+	}
+	ch = buf[0];
+	for (i = 1; i < inbuflen; i++)	/* shuffle them down. */
+		buf[i-1] = buf[i];
+	inbuflen--;
+	return ch;
+}
+
+static unsigned char udbg_getcLP(void)
+{
+	int ch;
+	for (;;) {
+		ch = udbg_getc_pollLP();
+		if (ch == -1) {
+			/* This shouldn't be needed...but... */
+			volatile unsigned long delay;
+			for (delay=0; delay < 2000000; delay++)
+				;
+		} else {
+			return ch;
+		}
+	}
+}
+
+
+/* This is called early in setup.c.
+ * Use it to setup page table ppc_md stuff as well as udbg.
+ */
+void pSeriesLP_init_early(void)
+{
+	ppc_md.hpte_invalidate   = hpte_invalidate_pSeriesLP;
+	ppc_md.hpte_updatepp     = hpte_updatepp_pSeriesLP;
+	ppc_md.hpte_updateboltedpp  = hpte_updateboltedpp_pSeriesLP;
+	ppc_md.hpte_getword0     = hpte_getword0_pSeriesLP;
+	ppc_md.hpte_selectslot   = hpte_selectslot_pSeriesLP;
+	ppc_md.hpte_create_valid = hpte_create_valid_pSeriesLP;
+	ppc_md.hpte_find	 = hpte_find_pSeriesLP;
+
+	ppc_md.tce_build	 = tce_build_pSeriesLP;
+	ppc_md.tce_free_one	 = tce_free_one_pSeriesLP;
+
+#ifdef CONFIG_SMP
+	smp_init_pSeries();
+#endif
+	pSeries_pcibios_init_early();
+
+	/* The keyboard is not useful in the LPAR environment.
+	 * Leave all the interfaces NULL.
+	 */
+
+	if (naca->serialPortAddr) {
+		void *comport = (void *)__ioremap(naca->serialPortAddr, 16, _PAGE_NO_CACHE);
+		udbg_init_uart(comport);
+		ppc_md.udbg_putc = udbg_putc;
+		ppc_md.udbg_getc = udbg_getc;
+		ppc_md.udbg_getc_poll = udbg_getc_poll;
+	} else {
+		/* lookup the first virtual terminal number in case we don't have a com port.
+		 * Zero is probably correct in case someone calls udbg before the init.
+		 * The property is a pair of numbers.  The first is the starting termno (the
+		 * one we use) and the second is the number of terminals.
+		 */
+		u32 *termno;
+		struct device_node *np = find_path_device("/rtas");
+		if (np) {
+			termno = (u32 *)get_property(np, "ibm,termno", 0);
+			if (termno)
+				vtermno = termno[0];
+		}
+		ppc_md.udbg_putc = udbg_putcLP;
+		ppc_md.udbg_getc = udbg_getcLP;
+		ppc_md.udbg_getc_poll = udbg_getc_pollLP;
+	}
+}
+
+/* Code for hvc_console.  Should move it back eventually. */
+
+int hvc_get_chars(int index, char *buf, int count)
+{
+	unsigned long got;
+
+	if (plpar_hcall(H_GET_TERM_CHAR, index, 0, 0, 0, &got,
+		(unsigned long *)buf, (unsigned long *)buf+1) == H_Success) {
+		/*
+		 * Work around a HV bug where it gives us a null
+		 * after every \r.  -- paulus
+		 */
+		if (got > 0) {
+			int i;
+			for (i = 1; i < got; ++i) {
+				if (buf[i] == 0 && buf[i-1] == '\r') {
+					--got;
+					if (i < got)
+						memmove(&buf[i], &buf[i+1],
+							got - i);
+				}
+			}
+		}
+		return got;
+	}
+	return 0;
+}
+
+int hvc_put_chars(int index, const char *buf, int count)
+{
+	unsigned long dummy;
+	unsigned long *lbuf = (unsigned long *) buf;
+	long ret;
+
+	ret = plpar_hcall(H_PUT_TERM_CHAR, index, count, lbuf[0], lbuf[1],
+			  &dummy, &dummy, &dummy);
+	if (ret == H_Success)
+		return count;
+	if (ret == H_Busy)
+		return 0;
+	return -1;
+}
+
+int hvc_count(int *start_termno)
+{
+	u32 *termno;
+	struct device_node *dn;
+
+	if ((dn = find_path_device("/rtas")) != NULL) {
+		if ((termno = (u32 *)get_property(dn, "ibm,termno", 0)) != NULL) {
+			if (start_termno)
+				*start_termno = termno[0];
+			return termno[1];
+		}
+	}
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pSeries_pci.c linux/arch/ppc64/kernel/pSeries_pci.c
--- linux.orig/arch/ppc64/kernel/pSeries_pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pSeries_pci.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,814 @@
+/*
+ * pSeries_pci.c
+ *
+ * pSeries_pcibios_init(void)opyright (C) 2001 Dave Engebretsen, IBM Corporation
+ *
+ * pSeries specific routines for PCI.
+ * 
+ * Based on code from pci.c and chrp_pci.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/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <linux/bootmem.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/init.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppcdebug.h>
+#include <asm/naca.h>
+#include <asm/pci_dma.h>
+#include <asm/eeh.h>
+
+#include "xics.h"
+#include "open_pic.h"
+#include "pci.h"
+
+extern struct device_node *allnodes;
+
+/*******************************************************************
+ * Forward declares of prototypes. 
+ *******************************************************************/
+unsigned long find_and_init_phbs(void);
+struct pci_controller* alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words) ;
+void pSeries_pcibios_fixup(void);
+static int rtas_fake_read(struct device_node *dn, int offset, int nbytes, unsigned long *returnval);
+
+/* RTAS tokens */
+static int read_pci_config;
+static int write_pci_config;
+static int ibm_read_pci_config;
+static int ibm_write_pci_config;
+
+static int s7a_workaround;
+
+/******************************************************************************
+ *
+ * pSeries I/O Operations to access the PCI configuration space.
+ *
+ *****************************************************************************/
+#define RTAS_PCI_READ_OP(size, type, nbytes) \
+int __chrp \
+rtas_read_config_##size(struct device_node *dn, int offset, type val) {  \
+	unsigned long returnval = ~0L; \
+	unsigned long buid; \
+	unsigned int addr; \
+	int ret; \
+	 \
+	if (dn == NULL) { \
+		ret = -2; \
+	} else if (dn->status) { \
+		ret = -1; \
+	} else { \
+		addr = (dn->busno << 16) | (dn->devfn << 8) | offset; \
+		buid = dn->phb->buid; \
+		if (buid) { \
+			ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, addr, buid >> 32, buid & 0xffffffff, nbytes); \
+                        if (ret < 0) \
+                               ret = rtas_fake_read(dn, offset, nbytes, &returnval); \
+		} else { \
+			ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, nbytes); \
+		} \
+	} \
+	*val = returnval; \
+	return ret; \
+} \
+int __chrp \
+rtas_pci_read_config_##size(struct pci_dev *dev, int offset, type val) {  \
+        struct device_node *dn = pci_device_to_OF_node(dev); \
+	int ret = rtas_read_config_##size(dn, offset, val); \
+        /* udbg_printf("read bus=%x, devfn=%x, ret=%d phb=%lx, dn=%lx\n", dev->bus->number, dev->devfn, ret, dn ? dn->phb : 0, dn); */ \
+        return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; \
+}
+
+#define RTAS_PCI_WRITE_OP(size, type, nbytes) \
+int __chrp \
+rtas_write_config_##size(struct device_node *dn, int offset, type val) { \
+	unsigned long buid; \
+	unsigned int addr; \
+	int ret; \
+	 \
+	if (dn == NULL) { \
+		ret = -2; \
+	} else if (dn->status) { \
+		ret = -1; \
+	} else { \
+		buid = dn->phb->buid; \
+		addr = (dn->busno << 16) | (dn->devfn << 8) | offset; \
+		if (buid) { \
+			ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, nbytes, (ulong) val); \
+		} else { \
+			ret = rtas_call(write_pci_config, 3, 1, NULL, addr, nbytes, (ulong)val); \
+		} \
+	} \
+	return ret; \
+} \
+int __chrp \
+rtas_pci_write_config_##size(struct pci_dev *dev, int offset, type val) { \
+	struct device_node*  dn = pci_device_to_OF_node(dev); \
+	int  ret = rtas_write_config_##size(dn, offset, val); \
+	/* udbg_printf("write bus=%x, devfn=%x, ret=%d phb=%lx, dn=%lx\n", dev->bus->number, dev->devfn, ret, dn ? dn->phb : 0, dn); */ \
+	return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; \
+}
+
+RTAS_PCI_READ_OP(byte, u8 *, 1)
+RTAS_PCI_READ_OP(word, u16 *, 2)
+RTAS_PCI_READ_OP(dword, u32 *, 4)
+RTAS_PCI_WRITE_OP(byte, u8, 1)
+RTAS_PCI_WRITE_OP(word, u16, 2)
+RTAS_PCI_WRITE_OP(dword, u32, 4)
+
+struct pci_ops rtas_pci_ops = {
+	rtas_pci_read_config_byte,
+	rtas_pci_read_config_word,
+	rtas_pci_read_config_dword,
+	rtas_pci_write_config_byte,
+ 	rtas_pci_write_config_word,
+	rtas_pci_write_config_dword,
+};
+
+/*
+ * Handle the case where rtas refuses to do a pci config read.
+ * This currently only happens with some PHBs in which case we totally fake
+ * out the values (and call it a speedwagaon -- something we could look up
+ * in the device tree).
+ */
+static int
+rtas_fake_read(struct device_node *dn, int offset, int nbytes, unsigned long *returnval)
+{
+	char *device_type = (char *)get_property(dn, "device_type", 0);
+	u32 *class_code = (u32 *)get_property(dn, "class-code", 0);
+
+	*returnval = ~0;	/* float by default */
+
+	/* udbg_printf("rtas_fake_read dn=%p, offset=0x%02x, nbytes=%d, device_type=%s\n", dn, offset, nbytes, device_type ? device_type : "<none>"); */
+	if (device_type && strcmp(device_type, "pci") != 0)
+		return -3;	/* Not a phb or bridge */
+
+	/* NOTE: class_code != NULL => EADS pci bridge.  Else a PHB */
+	if (nbytes == 1) {
+		if (offset == PCI_HEADER_TYPE)
+			*returnval = 0x80;	/* multifunction */
+		else if (offset == PCI_INTERRUPT_PIN || offset == PCI_INTERRUPT_LINE)
+			*returnval = 0;
+	} else if (nbytes == 2) {
+		if (offset == PCI_SUBSYSTEM_VENDOR_ID || offset == PCI_SUBSYSTEM_ID)
+			*returnval = 0;
+		else if (offset == PCI_COMMAND)
+			*returnval = PCI_COMMAND_PARITY|PCI_COMMAND_MASTER|PCI_COMMAND_MEMORY;
+	} else if (nbytes == 4) {
+		if (offset == PCI_VENDOR_ID)
+			*returnval = 0x1014 | ((class_code ? 0x8b : 0x102) << 16); /* a phb */
+		else if (offset == PCI_REVISION_ID)
+			*returnval = (class_code ? PCI_CLASS_BRIDGE_PCI : PCI_CLASS_BRIDGE_HOST) << 16; /* revs are zero */
+		else if ((offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_5) || offset == PCI_ROM_ADDRESS)
+			*returnval = 0;
+	}
+
+	/* printk("fake: %s nbytes=%d, offset=%lx ret=%lx\n", class_code ? "EADS" : "PHB", nbytes, offset, *returnval); */
+	return 0;
+}
+
+/******************************************************************
+ * pci_read_irq_line
+ *
+ * Reads the Interrupt Pin to determine if interrupt is use by card.
+ * If the interrupt is used, then gets the interrupt line from the 
+ * openfirmware and sets it in the pci_dev and pci_config line.
+ *
+ ******************************************************************/
+int 
+pci_read_irq_line(struct pci_dev *Pci_Dev)
+{
+	u8 InterruptPin;
+	struct device_node *Node;
+
+    	pci_read_config_byte(Pci_Dev, PCI_INTERRUPT_PIN, &InterruptPin);
+	if (InterruptPin == 0) {
+		PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Interrupt used by device.\n",Pci_Dev->slot_name);
+		return 0;	
+	}
+	Node = pci_device_to_OF_node(Pci_Dev);
+	if ( Node == NULL) { 
+		PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s Device Node not found.\n",Pci_Dev->slot_name);
+		return -1;	
+	}
+	if (Node->n_intrs == 0) 	{
+		PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Device OF interrupts defined.\n",Pci_Dev->slot_name);
+		return -1;	
+	}
+	Pci_Dev->irq = Node->intrs[0].line;
+
+	if (s7a_workaround) {
+		if (Pci_Dev->irq > 16)
+			Pci_Dev->irq -= 3;
+	}
+
+	pci_write_config_byte(Pci_Dev, PCI_INTERRUPT_LINE, Pci_Dev->irq);
+	
+	PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s pci_dev->irq = 0x%02X\n",Pci_Dev->slot_name,Pci_Dev->irq);
+	return 0;
+}
+
+/******************************************************************
+ * Find all PHBs in the system and initialize a set of data 
+ * structures to represent them.
+ ******************************************************************/
+unsigned long __init
+find_and_init_phbs(void)
+{
+        struct device_node *Pci_Node;
+        struct pci_controller *phb;
+        unsigned int root_addr_size_words = 0, this_addr_size_words = 0;
+	unsigned int this_addr_count = 0, range_stride;
+        unsigned int *ui_ptr = NULL, *ranges;
+        char *model;
+	struct pci_range64 range;
+	struct resource *res;
+	unsigned int memno, rlen, i, index;
+	unsigned int *opprop;
+	int has_isa = 0;
+        PPCDBG(PPCDBG_PHBINIT, "find_and_init_phbs\n"); 
+
+	read_pci_config = rtas_token("read-pci-config");
+	write_pci_config = rtas_token("write-pci-config");
+	ibm_read_pci_config = rtas_token("ibm,read-pci-config");
+	ibm_write_pci_config = rtas_token("ibm,write-pci-config");
+
+	eeh_init();
+
+	if (naca->interrupt_controller == IC_OPEN_PIC) {
+		opprop = (unsigned int *)get_property(find_path_device("/"),
+				"platform-open-pic", NULL);
+	}
+
+	/* Get the root address word size. */
+	ui_ptr = (unsigned int *) get_property(find_path_device("/"), 
+					       "#size-cells", NULL);
+	if (ui_ptr) {
+		root_addr_size_words = *ui_ptr;
+	} else {
+		PPCDBG(PPCDBG_PHBINIT, "\tget #size-cells failed.\n"); 
+		return(-1);
+	}
+
+	if (find_type_devices("isa")) {
+		has_isa = 1;
+		PPCDBG(PPCDBG_PHBINIT, "\tFound an ISA bus.\n"); 
+	}
+
+	index = 0;
+
+	/******************************************************************
+	* Find all PHB devices and create an object for them.
+	******************************************************************/
+	for (Pci_Node = find_devices("pci"); Pci_Node != NULL; Pci_Node = Pci_Node->next) {
+		model = (char *) get_property(Pci_Node, "model", NULL);
+		if (model != NULL)  {
+			phb = alloc_phb(Pci_Node, model, root_addr_size_words);
+			if (phb == NULL) return(-1);
+		}
+		else {
+         		continue;
+		}
+		
+		/* Get this node's address word size. */
+		ui_ptr = (unsigned int *) get_property(Pci_Node, "#size-cells", NULL);
+		if (ui_ptr)
+			this_addr_size_words = *ui_ptr;
+		else
+			this_addr_size_words = 1;
+		/* Get this node's address word count. */
+		ui_ptr = (unsigned int *) get_property(Pci_Node, "#address-cells", NULL);
+		if (ui_ptr)
+			this_addr_count = *ui_ptr;
+		else
+			this_addr_count = 3;
+		
+		range_stride = this_addr_count + root_addr_size_words + this_addr_size_words;
+	      
+		memno = 0;
+		phb->io_base_phys = 0;
+         
+		ranges = (unsigned int *) get_property(Pci_Node, "ranges", &rlen);
+		PPCDBG(PPCDBG_PHBINIT, "\trange_stride = 0x%lx, rlen = 0x%x\n", range_stride, rlen);
+                
+		for (i = 0; i < (rlen/sizeof(*ranges)); i+=range_stride) {
+		  	/* Put the PCI addr part of the current element into a 
+			 * '64' struct. 
+			 */
+		  	range = *((struct pci_range64 *)(ranges + i));
+
+			/* If this is a '32' element, map into a 64 struct. */
+			if ((range_stride * sizeof(int)) == 
+			   sizeof(struct pci_range32)) {
+				range.parent_addr = 
+					(unsigned long)(*(ranges + i + 3));
+				range.size = 
+					(((unsigned long)(*(ranges + i + 4)))<<32) | 
+					(*(ranges + i + 5));
+			} else {
+				range.parent_addr = 
+					(((unsigned long)(*(ranges + i + 3)))<<32) | 
+					(*(ranges + i + 4));
+				range.size = 
+					(((unsigned long)(*(ranges + i + 5)))<<32) | 
+					(*(ranges + i + 6));
+			}
+			
+			PPCDBG(PPCDBG_PHBINIT, "\trange.parent_addr    = 0x%lx\n", 
+			       range.parent_addr);
+			PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.hi  = 0x%lx\n", 
+			       range.child_addr.a_hi);
+			PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.mid = 0x%lx\n", 
+			       range.child_addr.a_mid);
+			PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.lo  = 0x%lx\n", 
+			       range.child_addr.a_lo);
+			PPCDBG(PPCDBG_PHBINIT, "\trange.size           = 0x%lx\n", 
+			       range.size);
+
+			res = NULL;
+		        switch ((range.child_addr.a_hi >> 24) & 0x3) {
+			case 1:		/* I/O space */
+				PPCDBG(PPCDBG_PHBINIT, "\tIO Space\n");
+				phb->io_base_phys = range.parent_addr;
+				res = &phb->io_resource;
+				res->name = Pci_Node->full_name;
+				res->flags = IORESOURCE_IO;
+				if (is_eeh_implemented()) {
+					if (!isa_io_base && has_isa) {
+						/* map a page for ISA ports.  Not EEH protected. */
+						isa_io_base = (unsigned long)__ioremap(phb->io_base_phys, PAGE_SIZE, _PAGE_NO_CACHE);
+					}
+					res->start = phb->io_base_virt = eeh_token(index, 0, 0, 0);
+					res->end = eeh_token(index, 0xff, 0xff, 0xffffffff);
+				} else {
+					phb->io_base_virt = ioremap(phb->io_base_phys, range.size);
+					if (!pci_io_base) {
+						pci_io_base = (unsigned long)phb->io_base_virt;
+						if (has_isa)
+							isa_io_base = pci_io_base;
+					}
+					res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo));
+					res->start += (unsigned long)phb->io_base_virt;
+					res->end =   res->start + range.size - 1;
+				}
+				res->parent = NULL;
+				res->sibling = NULL;
+				res->child = NULL;
+				phb->pci_io_offset = range.parent_addr - 
+					((((unsigned long)
+					   range.child_addr.a_mid) << 32) | 
+					 (range.child_addr.a_lo));
+				PPCDBG(PPCDBG_PHBINIT, "\tpci_io_offset  = 0x%lx\n", 
+				       phb->pci_io_offset);
+			  	break;
+			case 2:		/* mem space */
+				PPCDBG(PPCDBG_PHBINIT, "\tMem Space\n");
+				phb->pci_mem_offset = range.parent_addr - 
+					((((unsigned long)
+					   range.child_addr.a_mid) << 32) | 
+					 (range.child_addr.a_lo));
+				PPCDBG(PPCDBG_PHBINIT, "\tpci_mem_offset = 0x%lx\n", 
+				       phb->pci_mem_offset);
+				if (memno < sizeof(phb->mem_resources)/sizeof(phb->mem_resources[0])) {
+					res = &(phb->mem_resources[memno]);
+					++memno;
+					res->name = Pci_Node->full_name;
+					res->flags = IORESOURCE_MEM;
+					if (is_eeh_implemented()) {
+						res->start = eeh_token(index, 0, 0, 0);
+						res->end =   eeh_token(index, 0xff, 0xff, 0xffffffff);
+					} else {
+						res->start = range.parent_addr;
+						res->end =   range.parent_addr + range.size - 1;
+					}
+					res->parent = NULL;
+					res->sibling = NULL;
+					res->child = NULL;
+				}
+			  	break;
+			}
+		}
+		PPCDBG(PPCDBG_PHBINIT, "\tphb->io_base_phys   = 0x%lx\n", 
+		       phb->io_base_phys); 
+		PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%lx\n", 
+		       phb->pci_mem_offset); 
+
+		if (naca->interrupt_controller == IC_OPEN_PIC) {
+			int addr = root_addr_size_words * (index + 2) - 1;
+			openpic_setup_ISU(index, opprop[addr]); 
+		}
+		index++;
+	}
+	pci_devs_phb_init();
+	return 0;	 /*Success */
+}
+
+/******************************************************************
+ *
+ * Allocate and partially initialize a structure to represent a PHB.
+ *
+ ******************************************************************/
+struct pci_controller *
+alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
+{
+	struct pci_controller *phb;
+	unsigned int *ui_ptr = NULL, len;
+	struct reg_property64 reg_struct;
+	int *bus_range;
+	int *buid_vals;
+
+	PPCDBG(PPCDBG_PHBINIT, "alloc_phb: %s\n", dev->full_name); 
+	PPCDBG(PPCDBG_PHBINIT, "\tdev             = 0x%lx\n", dev); 
+	PPCDBG(PPCDBG_PHBINIT, "\tmodel           = 0x%lx\n", model); 
+	PPCDBG(PPCDBG_PHBINIT, "\taddr_size_words = 0x%lx\n", addr_size_words); 
+  
+	/* Found a PHB, now figure out where his registers are mapped. */
+	ui_ptr = (unsigned int *) get_property(dev, "reg", &len);
+	if (ui_ptr == NULL) {
+		PPCDBG(PPCDBG_PHBINIT, "\tget reg failed.\n"); 
+		return(NULL);
+	}
+
+	if (addr_size_words == 1) {
+		reg_struct.address = ((struct reg_property32 *)ui_ptr)->address;
+		reg_struct.size    = ((struct reg_property32 *)ui_ptr)->size;
+	} else {
+		reg_struct = *((struct reg_property64 *)ui_ptr);
+	}
+
+	PPCDBG(PPCDBG_PHBINIT, "\treg_struct.address = 0x%lx\n", reg_struct.address);
+	PPCDBG(PPCDBG_PHBINIT, "\treg_struct.size    = 0x%lx\n", reg_struct.size); 
+
+	/***************************************************************
+	* Set chip specific data in the phb, including types & 
+	* register pointers.
+	***************************************************************/
+
+	/****************************************************************
+	* Python
+	***************************************************************/
+	if (strstr(model, "Python")) {
+		PPCDBG(PPCDBG_PHBINIT, "\tCreate python\n");
+	        phb = pci_alloc_pci_controller("PHB PY",phb_type_python);
+		if (phb == NULL) return NULL;
+	
+       		phb->cfg_addr = (volatile unsigned long *) 
+			ioremap(reg_struct.address + 0xf8000, PAGE_SIZE);
+		PPCDBG(PPCDBG_PHBINIT, "\tcfg_addr_r = 0x%lx\n", 
+		       reg_struct.address + 0xf8000);
+		PPCDBG(PPCDBG_PHBINIT, "\tcfg_addr_v = 0x%lx\n", 
+		       phb->cfg_addr);
+		phb->cfg_data = (char*)(phb->cfg_addr + 0x02);
+       		phb->phb_regs = (volatile unsigned long *) 
+			ioremap(reg_struct.address + 0xf7000, PAGE_SIZE);
+		/* Python's register file is 1 MB in size. */
+		phb->chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 
+					 0x100000); 
+
+		/* 
+		 * Firmware doesnt always clear this bit which is critical
+		 * for good performance - Anton
+		 */
+		{
+			volatile u32 *tmp, i;
+
+#define PRG_CL_RESET_VALID 0x00010000
+
+			tmp = (u32 *)((unsigned long)phb->chip_regs + 0xf6030);
+
+			if (*tmp & PRG_CL_RESET_VALID) {
+				printk("Python workaround: ");
+				*tmp &= ~PRG_CL_RESET_VALID;
+				/*
+				 * We must read it back for changes to
+				 * take effect
+				 */
+				i = *tmp;
+				printk("reg0: %x\n", i);
+			}
+		}
+
+	/***************************************************************
+	* Speedwagon
+	*   include Winnipeg as well for the time being.
+	***************************************************************/
+	} else if ((strstr(model, "Speedwagon")) || 
+		   (strstr(model, "Winnipeg"))) {
+		PPCDBG(PPCDBG_PHBINIT, "\tCreate speedwagon\n");
+	        phb = pci_alloc_pci_controller("PHB SW",phb_type_speedwagon);
+		if (phb == NULL) return NULL;
+
+		if (naca->platform == PLATFORM_PSERIES) {
+			phb->cfg_addr = (volatile unsigned long *) 
+			  ioremap(reg_struct.address + 0x140, PAGE_SIZE);
+			phb->cfg_data = (char*)(phb->cfg_addr - 0x02); /* minus is correct */
+			phb->phb_regs = (volatile unsigned long *) 
+			  ioremap(reg_struct.address, PAGE_SIZE);
+			/* Speedwagon's register file is 1 MB in size. */
+			phb->chip_regs = ioremap(reg_struct.address & ~(0xfffffUL),
+						 0x100000); 
+			PPCDBG(PPCDBG_PHBINIT, "\tmapping chip_regs from 0x%lx -> 0x%lx\n", 
+			       reg_struct.address & 0xfffff, phb->chip_regs);
+		} else {
+			phb->cfg_addr = NULL;
+			phb->cfg_data = NULL; 
+			phb->phb_regs = NULL;
+			phb->chip_regs = NULL;
+		}
+
+		phb->local_number = ((reg_struct.address >> 12) & 0xf) - 0x8;
+	/***************************************************************
+	* Trying to build a known just gets the code in trouble.
+	***************************************************************/
+	} else { 
+		PPCDBG(PPCDBG_PHBINIT, "\tUnknown PHB Type!\n");
+		printk("PCI: Unknown Phb Type!\n");
+		return NULL;
+	}
+
+	bus_range = (int *) get_property(dev, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int)) {
+		PPCDBG(PPCDBG_PHBINIT, "Can't get bus-range for %s\n", dev->full_name);
+		kfree(phb);
+		return(NULL);
+	}
+
+	/***************************************************************
+	* Finished with the initialization
+	***************************************************************/
+	phb->first_busno =  bus_range[0];
+	phb->last_busno  =  bus_range[1];
+
+	phb->arch_data   = dev;
+	phb->ops = &rtas_pci_ops;
+
+	buid_vals = (int *) get_property(dev, "ibm,fw-phb-id", &len);
+	
+  if (buid_vals == NULL) {
+		phb->buid = 0;
+	} 
+  else {
+		struct pci_bus check;
+		if (sizeof(check.number) == 1 || sizeof(check.primary) == 1 ||
+		    sizeof(check.secondary) == 1 || sizeof(check.subordinate) == 1) {
+			udbg_printf("pSeries_pci:  this system has large bus numbers and the kernel was not\n"
+			      "built with the patch that fixes include/linux/pci.h struct pci_bus so\n"
+			      "number, primary, secondary and subordinate are ints.\n");
+			panic("pSeries_pci:  this system has large bus numbers and the kernel was not\n"
+			      "built with the patch that fixes include/linux/pci.h struct pci_bus so\n"
+			      "number, primary, secondary and subordinate are ints.\n");
+    }
+    
+    if (len < 2 * sizeof(int))
+      phb->buid = (unsigned long)buid_vals[0];  // Support for new OF that only has 1 integer for buid.
+    else
+      phb->buid = (((unsigned long)buid_vals[0]) << 32UL) |
+                  (((unsigned long)buid_vals[1]) & 0xffffffff);
+  	
+		phb->first_busno += (phb->global_number << 8);
+		phb->last_busno += (phb->global_number << 8);
+	}
+
+	/* Dump PHB information for Debug */
+	PPCDBGCALL(PPCDBG_PHBINIT,dumpPci_Controller(phb) );
+
+	return phb;
+}
+
+void 
+fixup_resources(struct pci_dev *dev)
+{
+ 	int i;
+ 	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
+	struct device_node *dn;
+	unsigned long eeh_disable_bit;
+
+	/* Add IBM loc code (slot) as a prefix to the device names for service */
+	dn = pci_device_to_OF_node(dev);
+	if (dn) {
+		char *loc_code = get_property(dn, "ibm,loc-code", 0);
+		if (loc_code) {
+			int loc_len = strlen(loc_code);
+			if (loc_len < sizeof(dev->name)) {
+				memmove(dev->name+loc_len+1, dev->name, sizeof(dev->name)-loc_len-1);
+				memcpy(dev->name, loc_code, loc_len);
+				dev->name[loc_len] = ' ';
+				dev->name[sizeof(dev->name)-1] = '\0';
+			}
+		}
+	}
+
+	if (is_eeh_implemented()) {
+		if (is_eeh_configured(dev)) {
+			eeh_disable_bit = 0;
+			if (eeh_set_option(dev, EEH_ENABLE) != 0) {
+				printk("PCI: failed to enable EEH for %s %s\n", dev->slot_name, dev->name);
+				eeh_disable_bit = EEH_TOKEN_DISABLED;
+			}
+		} else {
+			/* Assume device is by default EEH_DISABLE'd */
+			printk("PCI: eeh NOT configured for %s %s\n", dev->slot_name, dev->name);
+			eeh_disable_bit = EEH_TOKEN_DISABLED;
+		}
+	}
+
+	PPCDBG(PPCDBG_PHBINIT, "fixup_resources:\n"); 
+	PPCDBG(PPCDBG_PHBINIT, "\tphb                 = 0x%016LX\n", phb); 
+	PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_io_offset  = 0x%016LX\n", phb->pci_io_offset); 
+	PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%016LX\n", phb->pci_mem_offset); 
+
+	PPCDBG(PPCDBG_PHBINIT, "\tdev->name   = %s\n", dev->name);
+	PPCDBG(PPCDBG_PHBINIT, "\tdev->vendor:device = 0x%04X : 0x%04X\n", dev->vendor, dev->device);
+
+	if (phb == NULL)
+		return;
+
+ 	for (i = 0; i <  DEVICE_COUNT_RESOURCE; ++i) {
+		PPCDBG(PPCDBG_PHBINIT, "\tdevice %x.%x[%d] (flags %x) [%lx..%lx]\n",
+			    dev->bus->number, dev->devfn, i,
+			    dev->resource[i].flags,
+			    dev->resource[i].start,
+			    dev->resource[i].end);
+
+		if ((dev->resource[i].start == 0) && (dev->resource[i].end == 0)) {
+			continue;
+		}
+
+		if (dev->resource[i].flags & IORESOURCE_IO) {
+			if (is_eeh_implemented()) {
+				unsigned int busno = dev->bus ? dev->bus->number : 0;
+				unsigned long size = dev->resource[i].end - dev->resource[i].start;
+				unsigned long addr = (unsigned long)__ioremap(dev->resource[i].start + phb->io_base_phys, size, _PAGE_NO_CACHE);
+				if (!addr)
+					panic("fixup_resources: ioremap failed!\n");
+				dev->resource[i].start = eeh_token(phb->global_number, busno, dev->devfn, addr) | eeh_disable_bit;
+				dev->resource[i].end = dev->resource[i].start + size;
+			} else {
+				unsigned long offset = (unsigned long)phb->io_base_virt;
+				dev->resource[i].start += offset;
+				dev->resource[i].end += offset;
+			}
+			PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx .. %lx]\n",
+			       dev->resource[i].start, dev->resource[i].end);
+		} else if (dev->resource[i].flags & IORESOURCE_MEM) {
+			if (dev->resource[i].start == 0) {
+				/* Bogus.  Probably an unused bridge. */
+				dev->resource[i].end = 0;
+			} else {
+				if (is_eeh_implemented()) {
+					unsigned int busno = dev->bus ? dev->bus->number : 0;
+					unsigned long size = dev->resource[i].end - dev->resource[i].start;
+					unsigned long addr = (unsigned long)__ioremap(dev->resource[i].start + phb->pci_mem_offset, size, _PAGE_NO_CACHE);
+					if (!addr)
+						panic("fixup_resources: ioremap failed!\n");
+					dev->resource[i].start = eeh_token(phb->global_number, busno, dev->devfn, addr) | eeh_disable_bit;
+					dev->resource[i].end = dev->resource[i].start + size;
+				} else {
+					dev->resource[i].start += phb->pci_mem_offset;
+					dev->resource[i].end += phb->pci_mem_offset;
+				}
+			}
+			PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx..%lx]\n",
+			       dev->resource[i].start, dev->resource[i].end);
+
+		} else {
+			continue;
+		}
+
+ 		/* zap the 2nd function of the winbond chip */
+ 		if (dev->resource[i].flags & IORESOURCE_IO
+ 		    && dev->bus->number == 0 && dev->devfn == 0x81)
+ 			dev->resource[i].flags &= ~IORESOURCE_IO;
+ 	}
+}   
+
+static void check_s7a(void)
+{
+	struct device_node *root;
+	char *model;
+
+	root = find_path_device("/");
+	if (root) {
+		model = get_property(root, "model", NULL);
+		if (model && !strcmp(model, "IBM,7013-S7A"))
+			s7a_workaround = 1;
+	}
+}
+
+void __init
+pSeries_pcibios_fixup(void)
+{
+	struct pci_dev *dev;
+
+	PPCDBG(PPCDBG_PHBINIT, "pSeries_pcibios_fixup: start\n");
+	pci_assign_all_busses = 0;
+
+	check_s7a();
+	
+	pci_for_each_dev(dev) {
+		pci_read_irq_line(dev);
+		PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Dev(dev) );
+	}
+
+	if (naca->interrupt_controller == IC_PPC_XIC) {
+		xics_isa_init(); 
+	}
+}
+
+/*********************************************************************** 
+ * pci_find_hose_for_OF_device
+ *
+ * This function finds the PHB that matching device_node in the 
+ * OpenFirmware by scanning all the pci_controllers.
+ * 
+ ***********************************************************************/
+struct pci_controller*
+pci_find_hose_for_OF_device(struct device_node *node)
+{
+	while (node) {
+		struct pci_controller *hose;
+		for (hose=hose_head;hose;hose=hose->next)
+			if (hose->arch_data == node)
+				return hose;
+		node=node->parent;
+	}
+	return NULL;
+}
+
+/*********************************************************************** 
+ * ppc64_pcibios_init
+ *  
+ * Chance to initialize and structures or variable before PCI Bus walk.
+ *  
+ ***********************************************************************/
+void 
+pSeries_pcibios_init(void)
+{
+	PPCDBG(PPCDBG_PHBINIT, "\tppc64_pcibios_init Entry.\n"); 
+
+	if (get_property(find_path_device("/rtas"),"ibm,fw-phb-id",NULL) != NULL) {
+		PPCDBG(PPCDBG_PHBINIT, "\tFound: ibm,fw-phb-id\n"); 
+		Pci_Large_Bus_System = 1;
+	}
+}
+
+/*
+ * This is called very early before the page table is setup.
+ */
+void 
+pSeries_pcibios_init_early(void)
+{
+	ppc_md.pcibios_read_config_byte = rtas_read_config_byte;
+	ppc_md.pcibios_read_config_word = rtas_read_config_word;
+	ppc_md.pcibios_read_config_dword = rtas_read_config_dword;
+	ppc_md.pcibios_write_config_byte = rtas_write_config_byte;
+	ppc_md.pcibios_write_config_word = rtas_write_config_word;
+	ppc_md.pcibios_write_config_dword = rtas_write_config_dword;
+}
+/************************************************************************/
+/* Get a char* of the device physical location(U0.3-P1-I8)              */
+/* See the Product Topology in the RS/6000 Architecture.                */
+/************************************************************************/
+int device_Location(struct pci_dev *PciDev, char *BufPtr)
+{
+	struct device_node *DevNode = (struct device_node *)PciDev->sysdata;
+	return sprintf(BufPtr,"PCI: Bus%3d, Device%3d, Vendor %04X, Location %-12s",
+		       PciDev->bus->number,
+		       PCI_SLOT(PciDev->devfn),
+		       PciDev->vendor,
+		       (char*)get_property(DevNode,"ibm,loc-code",0));
+}
+/************************************************************************/
+/* Set the slot reset line to the state passed in.                      */
+/* This is the platform specific for code for the pci_reset_device      */
+/* function.                                                            */
+/************************************************************************/
+int pci_set_reset(struct pci_dev *PciDev, int state)
+{
+	return -1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pacaData.c linux/arch/ppc64/kernel/pacaData.c
--- linux.orig/arch/ppc64/kernel/pacaData.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pacaData.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,120 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ *      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.
+ */
+
+#define __KERNEL__
+#include <asm/types.h>
+#include <asm/page.h>
+#include <stddef.h>
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+
+#include <asm/iSeries/ItLpPaca.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
+
+struct naca_struct *naca;
+
+/* The Paca is an array with one entry per processor.  Each contains an 
+ * ItLpPaca, which contains the information shared between the 
+ * hypervisor and Linux.  Each also contains an ItLpRegSave area which
+ * is used by the hypervisor to save registers.
+ * On systems with hardware multi-threading, there are two threads
+ * per processor.  The Paca array must contain an entry for each thread.
+ * The VPD Areas will give a max logical processors = 2 * max physical
+ * processors.  The processor VPD array needs one entry per physical
+ * processor (not thread).
+ */
+#define PACAINITDATA(number,start,lpq,asrr,asrv) \
+{                                                                          \
+        xLpPacaPtr: &paca[number].xLpPaca,                                 \
+        xLpRegSavePtr: &paca[number].xRegSav,                              \
+        xPacaIndex: (number),           /* Paca Index        */             \
+        default_decr: 0x00ff0000,       /* Initial Decr      */             \
+        xStab_data: {                                                       \
+                real: (asrr),           /* Real pointer to segment table */ \
+                virt: (asrv),           /* Virt pointer to segment table */ \
+                next_round_robin: 1     /* Round robin index */             \
+        },                                                                  \
+        lpQueuePtr: (lpq),              /* &xItLpQueue,                  */ \
+        /* xRtas: {                                                            \
+                lock: SPIN_LOCK_UNLOCKED                                    \
+        }, */                                                                  \
+        xProcStart: (start),            /* Processor start */               \
+        xLpPaca: {                                                          \
+                xDesc: 0xd397d781,      /* "LpPa"          */               \
+                xSize: sizeof(struct ItLpPaca),                             \
+                xFPRegsInUse: 1,                                            \
+                xDynProcStatus: 2,                                          \
+		xDecrVal: 0x00ff0000,					    \
+                xEndOfQuantum: 0xffffffffffffffff                           \
+        },                                                                  \
+        xRegSav: {                                                          \
+                xDesc: 0xd397d9e2,      /* "LpRS"          */               \
+                xSize: sizeof(struct ItLpRegSave)                           \
+        },                                                                  \
+        exception_sp:                                                       \
+                (&paca[number].exception_stack[0]) - EXC_FRAME_SIZE,       \
+}
+
+struct paca_struct paca[MAX_PACAS] __page_aligned = {
+#ifdef CONFIG_PPC_ISERIES
+	PACAINITDATA( 0, 1, &xItLpQueue, 0, 0xc000000000005000),
+#else
+	PACAINITDATA( 0, 1, 0, 0x5000, 0xc000000000005000),
+#endif
+	PACAINITDATA( 1, 0, 0, 0, 0),
+	PACAINITDATA( 2, 0, 0, 0, 0),
+	PACAINITDATA( 3, 0, 0, 0, 0),
+	PACAINITDATA( 4, 0, 0, 0, 0),
+	PACAINITDATA( 5, 0, 0, 0, 0),
+	PACAINITDATA( 6, 0, 0, 0, 0),
+	PACAINITDATA( 7, 0, 0, 0, 0),
+	PACAINITDATA( 8, 0, 0, 0, 0),
+	PACAINITDATA( 9, 0, 0, 0, 0),
+	PACAINITDATA(10, 0, 0, 0, 0),
+	PACAINITDATA(11, 0, 0, 0, 0),
+	PACAINITDATA(12, 0, 0, 0, 0),
+	PACAINITDATA(13, 0, 0, 0, 0),
+	PACAINITDATA(14, 0, 0, 0, 0),
+	PACAINITDATA(15, 0, 0, 0, 0),
+	PACAINITDATA(16, 0, 0, 0, 0),
+	PACAINITDATA(17, 0, 0, 0, 0),
+	PACAINITDATA(18, 0, 0, 0, 0),
+	PACAINITDATA(19, 0, 0, 0, 0),
+	PACAINITDATA(20, 0, 0, 0, 0),
+	PACAINITDATA(21, 0, 0, 0, 0),
+	PACAINITDATA(22, 0, 0, 0, 0),
+	PACAINITDATA(23, 0, 0, 0, 0),
+	PACAINITDATA(24, 0, 0, 0, 0),
+	PACAINITDATA(25, 0, 0, 0, 0),
+	PACAINITDATA(26, 0, 0, 0, 0),
+	PACAINITDATA(27, 0, 0, 0, 0),
+	PACAINITDATA(28, 0, 0, 0, 0),
+	PACAINITDATA(29, 0, 0, 0, 0),
+	PACAINITDATA(30, 0, 0, 0, 0),
+	PACAINITDATA(31, 0, 0, 0, 0),
+	PACAINITDATA(32, 0, 0, 0, 0),
+	PACAINITDATA(33, 0, 0, 0, 0),
+	PACAINITDATA(34, 0, 0, 0, 0),
+	PACAINITDATA(35, 0, 0, 0, 0),
+	PACAINITDATA(36, 0, 0, 0, 0),
+	PACAINITDATA(37, 0, 0, 0, 0),
+	PACAINITDATA(38, 0, 0, 0, 0),
+	PACAINITDATA(39, 0, 0, 0, 0),
+	PACAINITDATA(40, 0, 0, 0, 0),
+	PACAINITDATA(41, 0, 0, 0, 0),
+	PACAINITDATA(42, 0, 0, 0, 0),
+	PACAINITDATA(43, 0, 0, 0, 0),
+	PACAINITDATA(44, 0, 0, 0, 0),
+	PACAINITDATA(45, 0, 0, 0, 0),
+	PACAINITDATA(46, 0, 0, 0, 0),
+	PACAINITDATA(47, 0, 0, 0, 0)
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pci.c linux/arch/ppc64/kernel/pci.c
--- linux.orig/arch/ppc64/kernel/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pci.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,1055 @@
+/*
+ * 
+ *
+ * Port for PPC64 David Engebretsen, IBM Corp.
+ *   Contains common pci routines for ppc64 platform, pSeries and iSeries brands. 
+ * 
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/flight_recorder.h>
+#include <asm/ppcdebug.h>
+#include <asm/naca.h>
+#include <asm/pci_dma.h>
+#include <asm/machdep.h>
+#include <asm/eeh.h>
+
+#include "pci.h"
+
+/* pci_io_base -- the base address from which io bars are offsets.
+ * This is the lowest I/O base address (so bar values are always positive),
+ * and it *must* be the start of ISA space if an ISA bus exists because
+ * ISA drivers use hard coded offsets.  If no ISA bus exists a dummy
+ * page is mapped and isa_io_limit prevents access to it.
+ */
+unsigned long isa_io_base     = 0;	/* NULL if no ISA bus */
+unsigned long pci_io_base     = 0;
+unsigned long isa_mem_base    = 0;
+unsigned long pci_dram_offset = 0;
+
+/******************************************************************
+ * Forward declare of prototypes
+ ******************************************************************/
+static void pcibios_fixup_resources(struct pci_dev* dev);
+static void fixup_broken_pcnet32(struct pci_dev* dev);
+static void fixup_windbond_82c105(struct pci_dev* dev);
+void        fixup_resources(struct pci_dev* dev);
+
+void   iSeries_pcibios_init(void);
+void   pSeries_pcibios_init(void);
+
+int    pci_assign_all_busses = 0;
+struct pci_controller* hose_head;
+struct pci_controller** hose_tail = &hose_head;
+
+LIST_HEAD(iSeries_Global_Device_List);
+
+/*******************************************************************
+ * Counters and control flags. 
+ *******************************************************************/
+long   Pci_Io_Read_Count  = 0;
+long   Pci_Io_Write_Count = 0;
+long   Pci_Cfg_Read_Count = 0;
+long   Pci_Cfg_Write_Count= 0;
+long   Pci_Error_Count    = 0;
+
+int    Pci_Retry_Max      = 3;	/* Only retry 3 times  */	
+int    Pci_Error_Flag     = 1;	/* Set Retry Error on. */
+int    Pci_Trace_Flag     = 0;
+
+/******************************************************************
+ * 
+ ******************************************************************/
+int  global_phb_number    = 0;           /* Global phb counter    */
+int  Pci_Large_Bus_System = 0;
+int  Pci_Set_IOA_Address  = 0;
+int  Pci_Manage_Phb_Space = 0;
+struct pci_controller *phbtab[PCI_MAX_PHB];
+
+static int pci_bus_count;
+
+/* Cached ISA bridge dev. */
+struct pci_dev *ppc64_isabridge_dev = NULL;
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_TRIDENT,	PCI_ANY_ID, fixup_broken_pcnet32 },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_WINBOND,	PCI_DEVICE_ID_WINBOND_82C105, fixup_windbond_82c105 },
+	{ PCI_FIXUP_HEADER, PCI_ANY_ID,	PCI_ANY_ID, pcibios_fixup_resources },
+ 	{ 0 }
+};
+
+static void fixup_broken_pcnet32(struct pci_dev* dev)
+{
+	if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
+		dev->vendor = PCI_VENDOR_ID_AMD;
+		pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+		pci_name_device(dev);
+	}
+}
+
+static void fixup_windbond_82c105(struct pci_dev* dev)
+{
+	/* Assume the windbond 82c105 is the IDE controller on a
+	 * p610.  We should probably be more careful in case
+	 * someone tries to plug in a similar adapter.
+	 */
+	unsigned int reg;
+
+	printk("Using INTC for W82c105 IDE controller.\n");
+	pci_read_config_dword(dev, 0x40, &reg);
+	/* Enable LEGIRQ to use INTC instead of ISA interrupts */
+	pci_write_config_dword(dev, 0x40, reg | (1<<11));
+}
+
+
+void pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
+				struct pbus_set_ranges_data *pranges)
+{
+}
+
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			     struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+	struct pci_controller* hose = PCI_GET_PHB_PTR(dev);
+	
+	new = res->start;
+	if (hose && res->flags & IORESOURCE_MEM)
+		new -= hose->pci_mem_offset;
+	new |= (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+static void
+pcibios_fixup_resources(struct pci_dev* dev)
+{
+	fixup_resources(dev);
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+	struct pci_dev *dev = data;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (size > 0x100) {
+			printk(KERN_ERR "PCI: Can not align I/O Region %s %s because size %ld is too large.\n",
+                                        dev->slot_name, res->name, size);
+		}
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+
+/*
+ *  Handle resources of PCI devices.  If the world were perfect, we could
+ *  just allocate all the resource regions and do nothing more.  It isn't.
+ *  On the other hand, we cannot just re-allocate all devices, as it would
+ *  require us to know lots of host bridge internals.  So we attempt to
+ *  keep as much of the original configuration as possible, but tweak it
+ *  when it's found to be wrong.
+ *
+ *  Known BIOS problems we have to work around:
+ *	- I/O or memory regions not configured
+ *	- regions configured, but not enabled in the command register
+ *	- bogus I/O addresses above 64K used
+ *	- expansion ROMs left enabled (this may sound harmless, but given
+ *	  the fact the PCI specs explicitly allow address decoders to be
+ *	  shared between expansion ROMs and other resource regions, it's
+ *	  at least dangerous)
+ *
+ *  Our solution:
+ *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ *	    This gives us fixed barriers on where we can allocate.
+ *	(2) Allocate resources for all enabled devices.  If there is
+ *	    a collision, just mark the resource as unallocated. Also
+ *	    disable expansion ROMs during this step.
+ *	(3) Try to allocate resources for disabled devices.  If the
+ *	    resources were assigned correctly, everything goes well,
+ *	    if they weren't, they won't disturb allocation of other
+ *	    resources.
+ *	(4) Assign new addresses to resources which were either
+ *	    not configured at all or misconfigured.  If explicitly
+ *	    requested by the user, configure expansion ROM address
+ *	    as well.
+ */
+
+static void __init
+pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	int i;
+	struct resource *res, *pr;
+
+	/* Depth-First Search on bus tree */
+	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		for (i = 0; i < 4; ++i) {
+			if ((res = bus->resource[i]) == NULL || !res->flags)
+				continue;
+			if (bus->parent == NULL)
+				pr = (res->flags & IORESOURCE_IO)?
+					&ioport_resource: &iomem_resource;
+			else
+				pr = pci_find_parent_resource(bus->self, res);
+
+			if (pr == res)
+				continue;	/* transparent bus or undefined */
+			if (pr && request_resource(pr, res) == 0)
+				continue;
+			printk(KERN_ERR "PCI: Cannot allocate resource region "
+			       "%d of PCI bridge %x\n", i, bus->number);
+			printk(KERN_ERR "PCI: resource is %lx..%lx (%lx), parent %p\n",
+			    res->start, res->end, res->flags, pr);
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+static void __init
+pcibios_allocate_resources(int pass)
+{
+	struct pci_dev *dev;
+	int idx, disabled;
+	u16 command;
+	struct resource *r, *pr;
+
+	pci_for_each_dev(dev) {
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++) {
+			r = &dev->resource[idx];
+			if (r->parent)		/* Already allocated */
+				continue;
+			if (!r->start)		/* Address not assigned at all */
+				continue;
+
+			if (r->flags & IORESOURCE_IO)
+				disabled = !(command & PCI_COMMAND_IO);
+			else
+				disabled = !(command & PCI_COMMAND_MEMORY);
+			if (pass == disabled) {
+				PPCDBG(PPCDBG_PHBINIT,
+				       "PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
+				       r->start, r->end, r->flags, disabled, pass);
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0) {
+					PPCDBG(PPCDBG_PHBINIT,
+					       "PCI: Cannot allocate resource region %d of device %s, pr = 0x%lx\n", idx, dev->slot_name, pr);
+					if(pr) {
+					PPCDBG(PPCDBG_PHBINIT,
+					       "PCI: Cannot allocate resource 0x%lx\n", request_resource(pr,r));
+					}
+					/* We'll assign a new address later */
+					r->end -= r->start;
+					r->start = 0;
+				}
+			}
+		}
+		if (!pass) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
+				/* Turn the ROM off, leave the resource region, but keep it unregistered. */
+				u32 reg;
+				r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
+				pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+				pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
+			}
+		}
+	}
+}
+
+static void __init
+pcibios_assign_resources(void)
+{
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r;
+
+	pci_for_each_dev(dev) {
+		int class = dev->class >> 8;
+
+		/* Don't touch classless devices and host bridges */
+		if (!class || class == PCI_CLASS_BRIDGE_HOST)
+			continue;
+
+		for(idx=0; idx<6; idx++) {
+			r = &dev->resource[idx];
+
+			/*
+			 *  Don't touch IDE controllers and I/O ports of video cards!
+			 */
+			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
+			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
+				continue;
+
+			/*
+			 *  We shall assign a new address to this resource, either because
+			 *  the BIOS forgot to do so or because we have decided the old
+			 *  address was unusable for some reason.
+			 */
+			if (!r->start && r->end && ppc_md.pcibios_enable_device_hook &&
+			    !ppc_md.pcibios_enable_device_hook(dev, 1))
+				pci_assign_resource(dev, idx);
+		}
+
+		if (0) { /* don't assign ROMs */
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			r->end -= r->start;
+			r->start = 0;
+			if (r->end)
+				pci_assign_resource(dev, PCI_ROM_RESOURCE);
+		}
+	}
+}
+
+
+int
+pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/* 
+ * Allocate pci_controller(phb) initialized common variables. 
+ */
+struct pci_controller * __init
+pci_alloc_pci_controller(char *model, enum phb_types controller_type)
+{
+        struct pci_controller *hose;
+        PPCDBG(PPCDBG_PHBINIT, "PCI: Allocate pci_controller for %s\n",model);
+        hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
+        if(hose == NULL) {
+                printk(KERN_ERR "PCI: Allocate pci_controller failed.\n");
+                return NULL;
+        }
+        memset(hose, 0, sizeof(struct pci_controller));
+        if(strlen(model) < 8) strcpy(hose->what,model);
+        else                  memcpy(hose->what,model,7);
+        hose->type = controller_type;
+        hose->global_number = global_phb_number;
+	phbtab[global_phb_number++] = hose;
+        
+        *hose_tail = hose;
+        hose_tail = &hose->next;
+        return hose;
+}
+
+/*
+ * This fixup is arch independent and probably should go somewhere else.
+ */
+void __init
+pcibios_generic_fixup(void)
+{
+	struct pci_dev *dev;
+
+	/* Fix miss-identified vendor AMD pcnet32 adapters. */
+	dev = NULL;
+	while ((dev = pci_find_device(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_AMD_LANCE, dev)) != NULL &&
+	       dev->class == (PCI_CLASS_NETWORK_ETHERNET << 8))
+		dev->vendor = PCI_VENDOR_ID_AMD;
+}
+
+
+
+/*********************************************************************** 
+ *
+ *
+ * 
+ ***********************************************************************/
+void __init
+pcibios_init(void)
+{
+	struct pci_controller *hose;
+	struct pci_bus *bus;
+	int    next_busno;
+
+#ifndef CONFIG_PPC_ISERIES
+	pSeries_pcibios_init();
+#else
+	iSeries_pcibios_init(); 
+#endif
+
+	printk("PCI: Probing PCI hardware\n");
+	PPCDBG(PPCDBG_BUSWALK,"PCI: Probing PCI hardware\n");
+				
+
+	/* Scan all of the recorded PCI controllers.  */
+	for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
+		hose->last_busno = 0xff;
+		bus = pci_scan_bus(hose->first_busno, hose->ops, hose->arch_data);
+		hose->bus = bus;
+		hose->last_busno = bus->subordinate;
+		if (pci_assign_all_busses || next_busno <= hose->last_busno)
+			next_busno = hose->last_busno+1;
+	}
+	pci_bus_count = next_busno;
+		
+	/* Call machine dependant fixup */
+	if (ppc_md.pcibios_fixup) {
+		ppc_md.pcibios_fixup();
+	}
+
+	/* Generic fixups */
+	pcibios_generic_fixup();
+
+	/* Allocate and assign resources */
+	pcibios_allocate_bus_resources(&pci_root_buses);
+	pcibios_allocate_resources(0);
+	pcibios_allocate_resources(1);
+	pcibios_assign_resources();
+
+#ifndef CONFIG_PPC_ISERIES
+	pci_fix_bus_sysdata();
+
+	create_tce_tables();
+	PPCDBG(PPCDBG_BUSWALK,"pSeries create_tce_tables()\n");
+#endif
+
+	/* Cache the location of the ISA bridge (if we have one) */
+	if (ppc64_isabridge_dev = pci_find_class(PCI_CLASS_BRIDGE_ISA << 8, NULL))
+		printk("ISA bridge at %s\n", ppc64_isabridge_dev->slot_name);
+
+	printk("PCI: Probing PCI hardware done\n");
+	PPCDBG(PPCDBG_BUSWALK,"PCI: Probing PCI hardware done.\n");
+
+}
+
+int __init
+pcibios_assign_all_busses(void)
+{
+	return pci_assign_all_busses;
+}
+
+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
+			     unsigned long start, unsigned long size)
+{
+	return start;
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_controller *phb = PCI_GET_PHB_PTR(bus);
+	struct resource *res;
+	int i;
+
+#ifndef CONFIG_PPC_ISERIES
+	if (bus->parent == NULL) {
+		/* This is a host bridge - fill in its resources */
+		phb->bus = bus;
+		bus->resource[0] = res = &phb->io_resource;
+		if (!res->flags)
+			BUG();	/* No I/O resource for this PHB? */
+
+		for (i = 0; i < 3; ++i) {
+			res = &phb->mem_resources[i];
+			if (!res->flags) {
+				if (i == 0)
+					BUG();	/* No memory resource for this PHB? */
+			}
+			bus->resource[i+1] = res;
+		}
+	} else {
+		/* This is a subordinate bridge */
+		pci_read_bridge_bases(bus);
+
+		for (i = 0; i < 4; ++i) {
+			if ((res = bus->resource[i]) == NULL)
+				continue;
+			if (!res->flags)
+				continue;
+			if (res == pci_find_parent_resource(bus->self, res)) {
+				/* Transparent resource -- don't try to "fix" it. */
+				continue;
+			}
+			if (is_eeh_implemented()) {
+				if (res->flags & (IORESOURCE_IO|IORESOURCE_MEM)) {
+					res->start = eeh_token(phb->global_number, bus->number, 0, 0);
+					res->end = eeh_token(phb->global_number, bus->number, 0xff, 0xffffffff);
+				}
+			} else {
+				if (res->flags & IORESOURCE_IO) {
+					res->start += (unsigned long)phb->io_base_virt;
+					res->end += (unsigned long)phb->io_base_virt;
+				} else if (phb->pci_mem_offset
+					   && (res->flags & IORESOURCE_MEM)) {
+					if (res->start < phb->pci_mem_offset) {
+						res->start += phb->pci_mem_offset;
+						res->end += phb->pci_mem_offset;
+					}
+				}
+			}
+		}
+	}
+#endif	
+	if ( ppc_md.pcibios_fixup_bus )
+		ppc_md.pcibios_fixup_bus(bus);
+}
+
+char __init *pcibios_setup(char *str)
+{
+	return str;
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	PPCDBG(PPCDBG_BUSWALK,"PCI: %s for device %s \n",__FUNCTION__,dev->slot_name);
+	if (ppc_md.pcibios_enable_device_hook)
+		if (ppc_md.pcibios_enable_device_hook(dev, 0))
+			return -EINVAL;
+			
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n",
+		       dev->slot_name, old_cmd, cmd);
+		PPCDBG(PPCDBG_BUSWALK,"PCI: Enabling device %s \n",dev->slot_name);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+struct pci_controller*
+pci_bus_to_hose(int bus)
+{
+	struct pci_controller* hose = hose_head;
+
+	for (; hose; hose = hose->next)
+		if (bus >= hose->first_busno && bus <= hose->last_busno)
+			return hose;
+	return NULL;
+}
+
+void*
+pci_bus_io_base(unsigned int bus)
+{
+	struct pci_controller *hose;
+
+	hose = pci_bus_to_hose(bus);
+	if (!hose)
+		return NULL;
+	return hose->io_base_virt;
+}
+
+unsigned long
+pci_bus_io_base_phys(unsigned int bus)
+{
+	struct pci_controller *hose;
+
+	hose = pci_bus_to_hose(bus);
+	if (!hose)
+		return 0;
+	return hose->io_base_phys;
+}
+
+unsigned long
+pci_bus_mem_base_phys(unsigned int bus)
+{
+	struct pci_controller *hose;
+
+	hose = pci_bus_to_hose(bus);
+	if (!hose)
+		return 0;
+	return hose->pci_mem_offset;
+}
+
+/*
+ * Return the index of the PCI controller for device pdev.
+ */
+int pci_controller_num(struct pci_dev *dev)
+{
+	struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+
+	return hose->global_number;
+}
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ *  -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static __inline__ int
+__pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
+		       enum pci_mmap_state mmap_state)
+{
+	struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long io_offset = 0;
+	int i, res_bit;
+
+	if (hose == 0)
+		return -EINVAL;		/* should never happen */
+
+	/* If memory, add on the PCI bridge address offset */
+	if (mmap_state == pci_mmap_mem) {
+		offset += hose->pci_mem_offset;
+		res_bit = IORESOURCE_MEM;
+	} else {
+		io_offset = (unsigned long)hose->io_base_virt;
+		offset += io_offset;
+		res_bit = IORESOURCE_IO;
+	}
+
+	/*
+	 * Check that the offset requested corresponds to one of the
+	 * resources of the device.
+	 */
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		struct resource *rp = &dev->resource[i];
+		int flags = rp->flags;
+
+		/* treat ROM as memory (should be already) */
+		if (i == PCI_ROM_RESOURCE)
+			flags |= IORESOURCE_MEM;
+
+		/* Active and same type? */
+		if ((flags & res_bit) == 0)
+			continue;
+
+		/* In the range of this resource? */
+		if (offset < (rp->start & PAGE_MASK) || offset > rp->end)
+			continue;
+
+		/* found it! construct the final physical address */
+		if (mmap_state == pci_mmap_io)
+			offset += hose->io_base_phys - io_offset;
+
+		vma->vm_pgoff = offset >> PAGE_SHIFT;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * Set vm_flags of VMA, as appropriate for this architecture, for a pci device
+ * mapping.
+ */
+static __inline__ void
+__pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
+		     enum pci_mmap_state mmap_state)
+{
+	vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static __inline__ void
+__pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
+		      enum pci_mmap_state mmap_state, int write_combine)
+{
+	long prot = pgprot_val(vma->vm_page_prot);
+
+	/* XXX would be nice to have a way to ask for write-through */
+	prot |= _PAGE_NO_CACHE;
+	prot |= _PAGE_GUARDED;
+	vma->vm_page_prot = __pgprot(prot);
+}
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture.  The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state,
+			int write_combine)
+{
+	int ret;
+
+	ret = __pci_mmap_make_offset(dev, vma, mmap_state);
+	if (ret < 0)
+		return ret;
+
+	__pci_mmap_set_flags(dev, vma, mmap_state);
+	__pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
+
+	ret = remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+	return ret;
+}
+
+/* Provide information on locations of various I/O regions in physical
+ * memory.  Do this on a per-card basis so that we choose the right
+ * root bridge.
+ * Note that the returned IO or memory base is a physical address
+ */
+
+long
+sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
+{
+	struct pci_controller* hose = pci_bus_to_hose(bus);
+	long result = -EOPNOTSUPP;
+
+	if (!hose)
+		return -ENODEV;
+	
+	switch (which) {
+	case IOBASE_BRIDGE_NUMBER:
+		return (long)hose->first_busno;
+	case IOBASE_MEMORY:
+		return (long)hose->pci_mem_offset;
+	case IOBASE_IO:
+		return (long)hose->io_base_phys;
+	case IOBASE_ISA_IO:
+		return (long)isa_io_base;
+	case IOBASE_ISA_MEM:
+		return (long)isa_mem_base;
+	}
+
+	return result;
+}
+/************************************************************************/
+/* Formats the device information and location for service.             */
+/* - Pass in pci_dev* pointer to the device.                            */
+/* - Pass in buffer to place the data.  Danger here is the buffer must  */
+/*   be as big as the client says it is.   Should be at least 128 bytes.*/
+/* Return will the length of the string data put in the buffer.         */
+/* The brand specific method device_Location is called.                 */
+/* Format:                                                              */
+/* PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet */
+/* PCI: Bus  0, Device 26, Vendor 0x12AE  Location U0.3-P1-I8  Ethernet */
+/* For pSeries, see the Product Topology in the RS/6000 Architecture.   */
+/* For iSeries, see the Service Manuals.                                */
+/************************************************************************/
+int  format_device_location(struct pci_dev* PciDev,char* BufPtr, int BufferSize)
+{
+	struct device_node* DevNode = (struct device_node*)PciDev->sysdata;
+	int  LineLen = 0;
+	if (DevNode != NULL && BufferSize >= 128) {
+		LineLen += device_Location(PciDev,BufPtr+LineLen);
+		LineLen += sprintf(BufPtr+LineLen," %12s",pci_class_name(PciDev->class >> 8) );
+	}
+	return LineLen;
+}
+/************************************************************************
+ * Saves the config registers for a device.                             *
+ ************************************************************************
+ * Note: This does byte reads so the data may appear byte swapped,      *
+ * The data returned in the pci_config_reg_save_area structure can be   *
+ * used to the restore of the data.  If the save failed, the data       *
+ * will not be restore.  Yes I know, you are most likey toast.          *
+ ************************************************************************/
+int pci_save_config_regs(struct pci_dev* PciDev,struct pci_config_reg_save_area* SaveArea)
+{
+	memset(SaveArea,0x00,sizeof(struct pci_config_reg_save_area) );
+	SaveArea->PciDev    = PciDev;
+	SaveArea->RCode     = 0;
+	SaveArea->Register  = 0;
+	/******************************************************************
+	 * Save All the Regs,  NOTE: restore skips the first 16 bytes.    *
+	 ******************************************************************/
+	while (SaveArea->Register < REG_SAVE_SIZE && SaveArea->RCode == 0) {
+		SaveArea->RCode = pci_read_config_byte(PciDev, SaveArea->Register, &SaveArea->Regs[SaveArea->Register]);
+		++SaveArea->Register;
+	}
+	if (SaveArea->RCode != 0) { 	/* Ouch */
+		SaveArea->Flags = 0x80;	
+		printk("PCI: pci_restore_save_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
+		PCIFR(      "pci_restore_save_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
+	}
+	else {
+		SaveArea->Flags = 0x01;
+	}
+	return  SaveArea->RCode;
+}
+
+/************************************************************************
+ * Restores the registers saved via the save function.  See the save    *
+ * function for details.                                                *
+ ************************************************************************/
+int pci_restore_config_regs(struct pci_dev* PciDev,struct pci_config_reg_save_area* SaveArea)
+{
+ 	if (SaveArea->PciDev != PciDev || SaveArea->Flags == 0x80 || SaveArea->RCode != 0) {
+		printk("PCI: pci_restore_config_regs failed! %p\n",PciDev);
+		return -1;
+	}
+	/******************************************************************
+	 * Don't touch the Cmd or BIST regs, user must restore those.     *
+	 * Restore PCI_VENDOR_ID & PCI_DEVICE_ID                          *
+	 * Restore PCI_CACHE_LINE_SIZE & PCI_LATENCY_TIMER                *
+	 * Restore Saved Regs from 0x10 to 0x3F                           * 
+	 ******************************************************************/
+	SaveArea->Register = 0;
+	while(SaveArea->Register < REG_SAVE_SIZE && SaveArea->RCode == 0) {
+		SaveArea->RCode = pci_write_config_byte(PciDev,SaveArea->Register,SaveArea->Regs[SaveArea->Register]);
+		++SaveArea->Register;
+		if (     SaveArea->Register == PCI_COMMAND)     SaveArea->Register = PCI_CACHE_LINE_SIZE;
+		else if (SaveArea->Register == PCI_HEADER_TYPE) SaveArea->Register = PCI_BASE_ADDRESS_0;
+	}
+	if (SaveArea->RCode != 0) {
+		printk("PCI: pci_restore_config_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
+		PCIFR(      "pci_restore_config_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
+	}
+	return  SaveArea->RCode;
+}
+
+/************************************************************************/
+/* Interface to toggle the reset line                                   */
+/* Time is in .1 seconds, need for seconds.                             */
+/************************************************************************/
+int  pci_reset_device(struct pci_dev* PciDev, int AssertTime, int DelayTime)
+{
+	unsigned long AssertDelay, WaitDelay;
+	int RtnCode;
+	/********************************************************************
+	 * Set defaults, Assert is .5 second, Wait is 3 seconds.
+	 ********************************************************************/
+	if (AssertTime == 0) AssertDelay = ( 5 * HZ)/10;
+	else                 AssertDelay = (AssertTime*HZ)/10;
+	if (WaitDelay == 0)  WaitDelay   = (30 * HZ)/10;
+	else                 WaitDelay   = (DelayTime* HZ)/10;
+
+	/********************************************************************
+	 * Assert reset, wait, de-assert reset, wait for IOA to reset.
+	 * - Don't waste the CPU time on jiffies.
+	 ********************************************************************/
+	RtnCode = pci_set_reset(PciDev,1);
+	if (RtnCode == 0) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(AssertDelay);   /* Sleep for the time     */
+		RtnCode = pci_set_reset(PciDev,0);
+		set_current_state(TASK_UNINTERRUPTIBLE);  
+		schedule_timeout(WaitDelay);
+	}
+	if (RtnCode == 0) {
+		PCIFR(      "Bus%3d, Device%3d, Reset\n",PciDev->bus->number,PCI_SLOT(PciDev->devfn) );
+	} 
+	else {
+		printk("PCI: Bus%3d, Device%3d, Reset Failed:0x%04X\n",PciDev->bus->number,PCI_SLOT(PciDev->devfn),RtnCode );
+		PCIFR(      "Bus%3d, Device%3d, Reset Failed:0x%04X\n",PciDev->bus->number,PCI_SLOT(PciDev->devfn),RtnCode );
+	}
+	return RtnCode;
+}
+
+/*****************************************************
+ * Dump Resource information
+ *****************************************************/
+void dumpResources(struct resource* Resource)
+{
+	if(Resource != NULL) {
+		int Flags = 0x00000F00 & Resource->flags;
+		if(Resource->start == 0 && Resource->end == 0) return;
+		else if(Resource->start == Resource->end )     return;
+		else {
+			if     (Flags == IORESOURCE_IO)  udbg_printf("IO.:");
+			else if(Flags == IORESOURCE_MEM) udbg_printf("MEM:");
+			else if(Flags == IORESOURCE_IRQ) udbg_printf("IRQ:");
+			else                             udbg_printf("0x%02X:",Resource->flags);
+
+		}
+		udbg_printf("0x%016LX / 0x%016LX (0x%08X)\n",
+			    Resource->start, Resource->end, Resource->end - Resource->start);
+	}
+}
+
+int  resourceSize(struct resource* Resource)
+{
+	if(Resource->start == 0 && Resource->end == 0) return 0;
+	else if(Resource->start == Resource->end )     return 0;
+	else return (Resource->end-1)-Resource->start;
+}
+
+
+/*****************************************************
+ * Dump PHB information for Debug
+ *****************************************************/
+void dumpPci_Controller(struct pci_controller* phb)
+{
+	udbg_printf("\tpci_controller= 0x%016LX\n", phb);
+	if (phb != NULL) {
+		udbg_printf("\twhat & type   = %s 0x%02X\n ",phb->what,phb->type);
+		udbg_printf("\tbus           = ");
+		if (phb->bus != NULL) udbg_printf("0x%02X\n",   phb->bus->number);
+		else                  udbg_printf("<NULL>\n");
+		udbg_printf("\tarch_data     = 0x%016LX\n", phb->arch_data);
+		udbg_printf("\tfirst_busno   = 0x%02X\n",   phb->first_busno);
+		udbg_printf("\tlast_busno    = 0x%02X\n",   phb->last_busno);
+		udbg_printf("\tio_base_virt* = 0x%016LX\n", phb->io_base_virt);
+		udbg_printf("\tio_base_phys  = 0x%016LX\n", phb->io_base_phys);
+		udbg_printf("\tpci_mem_offset= 0x%016LX\n", phb->pci_mem_offset);
+		udbg_printf("\tpci_io_offset = 0x%016LX\n", phb->pci_io_offset);
+
+		udbg_printf("\tcfg_addr      = 0x%016LX\n", phb->cfg_addr);
+		udbg_printf("\tcfg_data      = 0x%016LX\n", phb->cfg_data);
+		udbg_printf("\tphb_regs      = 0x%016LX\n", phb->phb_regs);
+		udbg_printf("\tchip_regs     = 0x%016LX\n", phb->chip_regs);
+
+
+		udbg_printf("\tResources\n");
+		dumpResources(&phb->io_resource);
+		if (phb->mem_resource_count >  0) dumpResources(&phb->mem_resources[0]);
+		if (phb->mem_resource_count >  1) dumpResources(&phb->mem_resources[1]);
+		if (phb->mem_resource_count >  2) dumpResources(&phb->mem_resources[2]);
+
+		udbg_printf("\tglobal_num    = 0x%02X\n",   phb->global_number);
+		udbg_printf("\tlocal_num     = 0x%02X\n",   phb->local_number);
+	}
+}
+
+/*****************************************************
+ * Dump PHB information for Debug
+ *****************************************************/
+void dumpPci_Bus(struct pci_bus* Pci_Bus)
+{
+	int i;
+	udbg_printf("\tpci_bus         = 0x%016LX   \n",Pci_Bus);
+	if (Pci_Bus != NULL) {
+
+		udbg_printf("\tnumber          = 0x%02X     \n",Pci_Bus->number);
+		udbg_printf("\tprimary         = 0x%02X     \n",Pci_Bus->primary);
+		udbg_printf("\tsecondary       = 0x%02X     \n",Pci_Bus->secondary);
+		udbg_printf("\tsubordinate     = 0x%02X     \n",Pci_Bus->subordinate);
+
+		for (i=0;i<4;++i) {
+			if(Pci_Bus->resource[i] == NULL) continue;
+			if(Pci_Bus->resource[i]->start == 0 && Pci_Bus->resource[i]->end == 0) break;
+			udbg_printf("\tResources[%d]",i);
+			dumpResources(Pci_Bus->resource[i]);
+		}
+	}
+}
+
+/*****************************************************
+ * Dump Device information for Debug
+ *****************************************************/
+void dumpPci_Dev(struct pci_dev* Pci_Dev)
+{
+	int i;
+	udbg_printf("\tpci_dev*        = 0x%p\n",Pci_Dev);
+	if ( Pci_Dev == NULL )  return;
+	udbg_printf("\tname            = %s  \n",Pci_Dev->name);
+	udbg_printf("\tbus*            = 0x%p\n",Pci_Dev->bus);
+	udbg_printf("\tsysdata*        = 0x%p\n",Pci_Dev->sysdata);
+	udbg_printf("\tDevice          = 0x%4X%02X:%02X.%02X 0x%04X:%04X\n",
+		    PCI_GET_PHB_NUMBER(Pci_Dev),
+		    PCI_GET_BUS_NUMBER(Pci_Dev),
+		    PCI_SLOT(Pci_Dev->devfn),
+		    PCI_FUNC(Pci_Dev->devfn),
+		    Pci_Dev->vendor,
+		    Pci_Dev->device);
+	udbg_printf("\tHdr/Irq         = 0x%02X/0x%02X \n",Pci_Dev->hdr_type,Pci_Dev->irq);
+	for (i=0;i<DEVICE_COUNT_RESOURCE;++i) {
+		if (Pci_Dev->resource[i].start == 0 && Pci_Dev->resource[i].end == 0) continue;
+		udbg_printf("\tResources[%d] ",i);
+		dumpResources(&Pci_Dev->resource[i]);
+	}
+	dumpResources(&Pci_Dev->resource[i]);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pci.h linux/arch/ppc64/kernel/pci.h
--- linux.orig/arch/ppc64/kernel/pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pci.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,119 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ *      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.
+ */
+#ifndef __PPC_KERNEL_PCI_H__
+#define __PPC_KERNEL_PCI_H__
+
+#include <linux/pci.h>
+#include <asm/pci-bridge.h>
+
+extern unsigned long isa_io_base;
+extern unsigned long isa_mem_base;
+extern unsigned long pci_dram_offset;
+
+/*******************************************************************
+ * Platform independant variables referenced.
+ *******************************************************************
+ * Set pci_assign_all_busses to 1 if you want the kernel to re-assign
+ * all PCI bus numbers.  
+ *******************************************************************/
+extern int pci_assign_all_busses;
+
+extern struct pci_controller* pci_alloc_pci_controller(char *model, enum phb_types controller_type);
+extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node);
+
+extern struct pci_controller* hose_head;
+extern struct pci_controller** hose_tail;
+/* PHB's are also in a table. */
+#define PCI_MAX_PHB 64
+extern int  global_phb_number;
+extern struct pci_controller *phbtab[];
+
+/*******************************************************************
+ * Platform functions that are brand specific implementation. 
+ *******************************************************************/
+extern unsigned long find_and_init_phbs(void);
+
+extern void   fixup_resources(struct pci_dev *dev);
+extern void   ppc64_pcibios_init(void);
+
+extern int    pci_set_reset(struct pci_dev*,int);
+extern int    device_Location(struct pci_dev*,char*);
+extern int    format_device_location(struct pci_dev*,char*, int );
+
+extern struct pci_dev *ppc64_isabridge_dev;	/* may be NULL if no ISA bus */
+
+/*******************************************************************
+ * PCI device_node operations
+ *******************************************************************/
+struct device_node;
+typedef void *(*traverse_func)(struct device_node *me, void *data);
+void *traverse_pci_devices(struct device_node *start, traverse_func pre, traverse_func post, void *data);
+void *traverse_all_pci_devices(traverse_func pre);
+
+void pci_devs_phb_init(void);
+void pci_fix_bus_sysdata(void);
+struct device_node *fetch_dev_dn(struct pci_dev *dev);
+
+void iSeries_pcibios_init_early(void);
+void pSeries_pcibios_init_early(void);
+void pSeries_pcibios_init(void);
+
+/* Get a device_node from a pci_dev.  This code must be fast except in the case
+ * where the sysdata is incorrect and needs to be fixed up (hopefully just once)
+ */
+static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
+{
+	struct device_node *dn = (struct device_node *)(dev->sysdata);
+	if (dn->devfn == dev->devfn && dn->busno == dev->bus->number)
+		return dn;	/* fast path.  sysdata is good */
+	else
+		return fetch_dev_dn(dev);
+}
+/* Use this macro after the PCI bus walk for max performance when it
+ * is known that sysdata is correct.
+ */
+#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
+
+
+/*******************************************************************
+ * Platform configuration flags.. (Live in pci.c)
+ *******************************************************************/
+extern int  Pci_Large_Bus_System;      /* System has > 256 buses   */
+extern int  Pci_Manage_Phb_Space;      /* Manage Phb Space for IOAs*/
+
+/*******************************************************************
+ * Helper macros for extracting data from pci structures.  
+ *   PCI_GET_PHB_PTR(struct pci_dev*)    returns the Phb pointer.
+ *   PCI_GET_PHB_NUMBER(struct pci_dev*) returns the Phb number.
+ *   PCI_GET_BUS_NUMBER(struct pci_dev*) returns the bus number.
+ *******************************************************************/
+#define PCI_GET_PHB_PTR(dev)    (((struct device_node *)(dev)->sysdata)->phb)
+#define PCI_GET_PHB_NUMBER(dev) (((dev)->bus->number&0x00FFFF00)>>8)
+#define PCI_GET_BUS_NUMBER(dev) ((dev)->bus->number&0x0000FF)
+
+/*******************************************************************
+ * Pci Flight Recorder support.
+ *******************************************************************/
+#define PCIFR(...) fr_Log_Entry(PciFr,__VA_ARGS__);
+extern struct flightRecorder* PciFr;
+extern int    Pci_Trace_Flag;
+
+/*******************************************************************
+ * Debugging  Routines.
+ *******************************************************************/
+extern void dumpResources(struct resource* Resource);
+extern void dumpPci_Controller(struct pci_controller* phb);
+extern void dumpPci_Bus(struct pci_bus* Pci_Bus);
+extern void dumpPci_Dev(struct pci_dev* Pci_Dev);
+
+extern void dump_Phb_tree(void);
+extern void dump_Bus_tree(void);
+extern void dump_Dev_tree(void);
+
+#endif /* __PPC_KERNEL_PCI_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pci_dma.c linux/arch/ppc64/kernel/pci_dma.c
--- linux.orig/arch/ppc64/kernel/pci_dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pci_dma.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,1496 @@
+/*
+ * pci_dma.c
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+ *
+ * Dynamic DMA mapping support.
+ * 
+ * Manages the TCE space assigned to this partition.
+ * 
+ * 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/slab.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/ppcdebug.h>
+
+#include <asm/iSeries/HvCallXm.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/pci_dma.h>
+#include <asm/pci-bridge.h>
+#include <asm/iSeries/iSeries_pci.h>
+
+#include <asm/machdep.h>
+
+#include "pci.h"
+
+/* #define DEBUG_TCE 1   */
+/* #define MONITOR_TCE 1 */ /* Turn on to sanity check TCE generation. */
+
+
+/* Initialize so this guy does not end up in the BSS section.
+ * Only used to pass OF initialization data set in prom.c into the main 
+ * kernel code -- data ultimately copied into tceTables[].
+ */
+extern struct _of_tce_table of_tce_table[];
+
+extern struct pci_controller* hose_head;
+extern struct pci_controller** hose_tail;
+extern struct list_head iSeries_Global_Device_List;
+
+struct TceTable   virtBusVethTceTable;	/* Tce table for virtual ethernet */
+struct TceTable   virtBusVioTceTable;	/* Tce table for virtual I/O */
+
+struct iSeries_Device_Node iSeries_veth_dev_node = { LogicalSlot: 0xFF, DevTceTable: &virtBusVethTceTable };
+struct iSeries_Device_Node iSeries_vio_dev_node  = { LogicalSlot: 0xFF, DevTceTable: &virtBusVioTceTable };
+
+struct pci_dev    iSeries_veth_dev_st = { sysdata: &iSeries_veth_dev_node };
+struct pci_dev    iSeries_vio_dev_st  = { sysdata: &iSeries_vio_dev_node  };
+
+struct pci_dev  * iSeries_veth_dev = &iSeries_veth_dev_st;
+struct pci_dev  * iSeries_vio_dev  = &iSeries_vio_dev_st;
+
+/* Device TceTable is stored in Device Node */
+/* struct TceTable * tceTables[256]; */	/* Tce tables for 256 busses
+					 * Bus 255 is the virtual bus
+					 * zero indicates no bus defined
+					 */
+/* allocates a contiguous range of tces (power-of-2 size) */
+static inline long alloc_tce_range(struct TceTable *, 
+				   unsigned order );
+
+/* allocates a contiguous range of tces (power-of-2 size)
+ * assumes lock already held
+ */
+static long alloc_tce_range_nolock(struct TceTable *, 
+				   unsigned order );
+
+/* frees a contiguous range of tces (power-of-2 size) */
+static inline void free_tce_range(struct TceTable *, 
+				  long tcenum, 
+				  unsigned order );
+
+/* frees a contiguous rnage of tces (power-of-2 size)
+ * assumes lock already held
+ */
+void free_tce_range_nolock(struct TceTable *, 
+			   long tcenum, 
+			   unsigned order );
+
+/* allocates a range of tces and sets them to the pages  */
+static inline dma_addr_t get_tces( struct TceTable *, 
+				   unsigned order, 
+				   void *page, 
+				   unsigned numPages,
+				   int direction );
+
+static long test_tce_range( struct TceTable *, 
+			    long tcenum, 
+			    unsigned order );
+
+static unsigned fill_scatterlist_sg(struct scatterlist *sg, int nents, 
+				    dma_addr_t dma_addr, 
+				    unsigned long numTces );
+
+static unsigned long num_tces_sg( struct scatterlist *sg, 
+				  int nents );
+	
+static dma_addr_t create_tces_sg( struct TceTable *tbl, 
+				  struct scatterlist *sg, 
+			 	  int nents, 
+				  unsigned numTces,
+				  int direction );
+
+static void getTceTableParmsiSeries(struct iSeries_Device_Node* DevNode,
+				      struct TceTable *tce_table_parms );
+
+static void getTceTableParmsPSeries( struct pci_controller *phb, 
+				     struct device_node *dn,
+				     struct TceTable *tce_table_parms );
+
+static void getTceTableParmsPSeriesLP(struct pci_controller *phb,
+				    struct device_node *dn,
+				    struct TceTable *newTceTable );
+
+static struct TceTable* findHwTceTable(struct TceTable * newTceTable );
+
+void create_pci_bus_tce_table( unsigned long token );
+
+u8 iSeries_Get_Bus( struct pci_dev * dv )
+{
+	return 0;
+}
+
+static inline struct TceTable *get_tce_table(struct pci_dev *dev)
+{
+	if (!dev)
+		dev = ppc64_isabridge_dev;
+	if (!dev)
+		return NULL;
+	if (naca->platform == PLATFORM_ISERIES_LPAR) {
+ 		return ISERIES_DEVNODE(dev)->DevTceTable;
+	} else {
+		return PCI_GET_DN(dev)->tce_table;
+	}
+}
+
+static unsigned long __inline__ count_leading_zeros64( unsigned long x )
+{
+	unsigned long lz;
+	asm("cntlzd %0,%1" : "=r"(lz) : "r"(x));
+	return lz;
+}
+
+static void tce_build_iSeries(struct TceTable *tbl, long tcenum, 
+			       unsigned long uaddr, int direction )
+{
+	u64 setTceRc;
+	union Tce tce;
+	
+	PPCDBG(PPCDBG_TCE, "build_tce: uaddr = 0x%lx\n", uaddr);
+	PPCDBG(PPCDBG_TCE, "\ttcenum = 0x%lx, tbl = 0x%lx, index=%lx\n", 
+	       tcenum, tbl, tbl->index);
+
+	tce.wholeTce = 0;
+	tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT;
+
+	/* If for virtual bus */
+	if ( tbl->tceType == TCE_VB ) {
+		tce.tceBits.valid = 1;
+		tce.tceBits.allIo = 1;
+		if ( direction != PCI_DMA_TODEVICE )
+			tce.tceBits.readWrite = 1;
+	} else {
+		/* If for PCI bus */
+		tce.tceBits.readWrite = 1; // Read allowed 
+		if ( direction != PCI_DMA_TODEVICE )
+			tce.tceBits.pciWrite = 1;
+	}
+
+	setTceRc = HvCallXm_setTce((u64)tbl->index, 
+				   (u64)tcenum, 
+				   tce.wholeTce );
+	if(setTceRc) {
+		panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", setTceRc);
+	}
+}
+
+static void tce_build_pSeries(struct TceTable *tbl, long tcenum, 
+			       unsigned long uaddr, int direction )
+{
+	union Tce tce;
+	union Tce *tce_addr;
+	
+	PPCDBG(PPCDBG_TCE, "build_tce: uaddr = 0x%lx\n", uaddr);
+	PPCDBG(PPCDBG_TCE, "\ttcenum = 0x%lx, tbl = 0x%lx, index=%lx\n", 
+	       tcenum, tbl, tbl->index);
+
+	tce.wholeTce = 0;
+	tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT;
+
+	tce.tceBits.readWrite = 1; // Read allowed 
+	if ( direction != PCI_DMA_TODEVICE ) tce.tceBits.pciWrite = 1;
+
+	tce_addr = ((union Tce *)tbl->base) + tcenum;
+	*tce_addr = (union Tce)tce.wholeTce;
+
+}
+
+/* 
+ * Build a TceTable structure.  This contains a multi-level bit map which
+ * is used to manage allocation of the tce space.
+ */
+static struct TceTable *build_tce_table( struct TceTable * tbl )
+{
+	unsigned long bits, bytes, totalBytes;
+	unsigned long numBits[NUM_TCE_LEVELS], numBytes[NUM_TCE_LEVELS];
+	unsigned i, k, m;
+	unsigned char * pos, * p, b;
+
+	PPCDBG(PPCDBG_TCEINIT, "build_tce_table: tbl = 0x%lx\n", tbl);
+	spin_lock_init( &(tbl->lock) );
+	
+	tbl->mlbm.maxLevel = 0;
+
+	/* Compute number of bits and bytes for each level of the
+	 * multi-level bit map
+	 */ 
+	totalBytes = 0;
+	bits = tbl->size * (PAGE_SIZE / sizeof( union Tce ));
+	
+	for ( i=0; i<NUM_TCE_LEVELS; ++i ) {
+		bytes = ((bits+63)/64) * 8;
+		PPCDBG(PPCDBG_TCEINIT, "build_tce_table: level %d bits=%ld, bytes=%ld\n", i, bits, bytes );
+		numBits[i] = bits;
+		numBytes[i] = bytes;
+		bits /= 2;
+		totalBytes += bytes;
+	}
+	PPCDBG(PPCDBG_TCEINIT, "build_tce_table: totalBytes=%ld\n", totalBytes );
+	
+	pos = (char *)__get_free_pages( GFP_ATOMIC, get_order( totalBytes ));
+ 
+	if ( pos == NULL ) {
+		panic("PCI_DMA: Allocation failed in build_tce_table!\n");
+	}
+
+	/* For each level, fill in the pointer to the bit map,
+	 * and turn on the last bit in the bit map (if the
+	 * number of bits in the map is odd).  The highest
+	 * level will get all of its bits turned on.
+	 */
+	memset( pos, 0, totalBytes );
+	for (i=0; i<NUM_TCE_LEVELS; ++i) {
+		if ( numBytes[i] ) {
+			tbl->mlbm.level[i].map = pos;
+			tbl->mlbm.maxLevel = i;
+
+			if ( numBits[i] & 1 ) {
+				p = pos + numBytes[i] - 1;
+				m = (( numBits[i] % 8) - 1) & 7;
+				*p = 0x80 >> m;
+				PPCDBG(PPCDBG_TCEINIT, "build_tce_table: level %d last bit %x\n", i, 0x80>>m );
+			}
+		}
+		else
+			tbl->mlbm.level[i].map = 0;
+		pos += numBytes[i];
+		tbl->mlbm.level[i].numBits = numBits[i];
+		tbl->mlbm.level[i].numBytes = numBytes[i];
+	}
+
+	/* For the highest level, turn on all the bits */
+	
+	i = tbl->mlbm.maxLevel;
+	p = tbl->mlbm.level[i].map;
+	m = numBits[i];
+	PPCDBG(PPCDBG_TCEINIT, "build_tce_table: highest level (%d) has all bits set\n", i);
+	for (k=0; k<numBytes[i]; ++k) {
+		if ( m >= 8 ) {
+			/* handle full bytes */
+			*p++ = 0xff;
+			m -= 8;
+		}
+		else if(m>0) {
+			/* handle the last partial byte */
+			b = 0x80;
+			*p = 0;
+			while (m) {
+				*p |= b;
+				b >>= 1;
+				--m;
+			}
+		} else {
+			break;
+		}
+	}
+
+	return tbl;
+}
+
+static inline long alloc_tce_range( struct TceTable *tbl, unsigned order )
+{
+	long retval;
+	unsigned long flags;
+	
+	/* Lock the tce allocation bitmap */
+	spin_lock_irqsave( &(tbl->lock), flags );
+
+	/* Do the actual work */
+	retval = alloc_tce_range_nolock( tbl, order );
+	
+	/* Unlock the tce allocation bitmap */
+	spin_unlock_irqrestore( &(tbl->lock), flags );
+
+	return retval;
+}
+
+static long alloc_tce_range_nolock( struct TceTable *tbl, unsigned order )
+{
+	unsigned long numBits, numBytes;
+	unsigned long i, bit, block, mask;
+	long tcenum;
+	u64 * map;
+
+	/* If the order (power of 2 size) requested is larger than our
+	 * biggest, indicate failure
+	 */
+	if(order >= NUM_TCE_LEVELS) {
+		/* This can happen if block of TCE's are not found. This code      */
+		/*  maybe in a recursive loop looking up the bit map for the range.*/
+		panic("PCI_DMA: alloc_tce_range_nolock: invalid order: %d\n",order);
+	}
+	
+	numBits =  tbl->mlbm.level[order].numBits;
+	numBytes = tbl->mlbm.level[order].numBytes;
+	map =      (u64 *)tbl->mlbm.level[order].map;
+
+	/* Initialize return value to -1 (failure) */
+	tcenum = -1;
+
+	/* Loop through the bytes of the bitmap */
+	for (i=0; i<numBytes/8; ++i) {
+		if ( *map ) {
+			/* A free block is found, compute the block
+			 * number (of this size)
+			 */
+			bit = count_leading_zeros64( *map );
+			block = (i * 64) + bit;    /* Bit count to free entry */
+
+			/* turn off the bit in the map to indicate
+			 * that the block is now in use
+			 */
+			mask = 0x1UL << (63 - bit);
+			*map &= ~mask;
+
+			/* compute the index into our tce table for
+			 * the first tce in the block
+			 */
+			PPCDBG(PPCDBG_TCE, "alloc_tce_range_nolock: allocating block %ld, (byte=%ld, bit=%ld) order %d\n", block, i, bit, order );
+			tcenum = block << order;
+			return tcenum;
+		}
+		++map;
+	}
+
+#ifdef DEBUG_TCE
+	if ( tcenum == -1 ) {
+		PPCDBG(PPCDBG_TCE, "alloc_tce_range_nolock: no available blocks of order = %d\n", order );
+		if ( order < tbl->mlbm.maxLevel ) {
+			PPCDBG(PPCDBG_TCE, "alloc_tce_range_nolock: trying next bigger size\n" );
+		}
+		else {
+			panic("PCI_DMA: alloc_tce_range_nolock: maximum size reached...failing\n");
+		}
+	}
+#endif	
+	
+	/* If no block of the requested size was found, try the next
+	 * size bigger.  If one of those is found, return the second
+	 * half of the block to freespace and keep the first half
+	 */
+	if((tcenum == -1) && (order < (NUM_TCE_LEVELS - 1))) {
+		tcenum = alloc_tce_range_nolock( tbl, order+1 );
+		if ( tcenum != -1 ) {
+			free_tce_range_nolock( tbl, tcenum+(1<<order), order );
+		}
+	}
+	
+	/* Return the index of the first tce in the block
+	 * (or -1 if we failed)
+	 */
+	return tcenum;
+}
+
+static inline void free_tce_range(struct TceTable *tbl, 
+				  long tcenum, unsigned order )
+{
+	unsigned long flags;
+
+	/* Lock the tce allocation bitmap */
+	spin_lock_irqsave( &(tbl->lock), flags );
+
+	/* Do the actual work */
+	free_tce_range_nolock( tbl, tcenum, order );
+	
+	/* Unlock the tce allocation bitmap */
+	spin_unlock_irqrestore( &(tbl->lock), flags );
+
+}
+
+void free_tce_range_nolock(struct TceTable *tbl, 
+			   long tcenum, unsigned order )
+{
+	unsigned long block;
+	unsigned byte, bit, mask, b;
+	unsigned char  * map, * bytep;
+
+	if (order >= NUM_TCE_LEVELS) {
+		panic("PCI_DMA: free_tce_range: invalid order: 0x%x\n",order);
+		return;
+	}
+
+	block = tcenum >> order;
+
+#ifdef MONITOR_TCE
+	if ( tcenum != (block << order ) ) {
+		printk("PCI_DMA: Free_tce_range: tcenum %lx misaligned for order %x\n",tcenum, order);
+		return;
+	}
+	if ( block >= tbl->mlbm.level[order].numBits ) {
+		printk("PCI_DMA: Free_tce_range: tcenum %lx is outside the range of this map (order %x, numBits %lx\n", 
+		       tcenum, order, tbl->mlbm.level[order].numBits );
+		return;
+	}
+	if ( test_tce_range( tbl, tcenum, order ) ) {
+		printk("PCI_DMA: Freeing range not allocated: tTceTable %p, tcenum %lx, order %x\n",tbl, tcenum, order );
+		return;
+	}
+#endif
+
+	map = tbl->mlbm.level[order].map;
+	byte  = block / 8;
+	bit   = block % 8;
+	mask  = 0x80 >> bit;
+	bytep = map + byte;
+
+#ifdef DEBUG_TCE
+	PPCDBG(PPCDBG_TCE,"free_tce_range_nolock: freeing block %ld (byte=%d, bit=%d) of order %d\n",
+	       block, byte, bit, order);
+#endif	
+
+#ifdef MONITOR_TCE
+	if ( *bytep & mask ) {
+		panic("PCI_DMA: Tce already free: TceTable %p, tcenum %lx, order %x\n",tbl,tcenum,order);
+	}
+#endif	
+
+	*bytep |= mask;
+
+	/* If there is a higher level in the bit map than this we may be
+	 * able to buddy up this block with its partner.
+	 *   If this is the highest level we can't buddy up
+	 *   If this level has an odd number of bits and
+	 *      we are freeing the last block we can't buddy up
+	 * Don't buddy up if it's in the first 1/4 of the level
+	 */
+	if (( order < tbl->mlbm.maxLevel ) &&
+	    ( block > (tbl->mlbm.level[order].numBits/4) ) &&
+	    (( block < tbl->mlbm.level[order].numBits-1 ) ||
+	      ( 0 == ( tbl->mlbm.level[order].numBits & 1)))) {
+		/* See if we can buddy up the block we just freed */
+		bit  &= 6;		/* get to the first of the buddy bits */
+		mask  = 0xc0 >> bit;	/* build two bit mask */
+		b     = *bytep & mask;	/* Get the two bits */
+		if ( 0 == (b ^ mask) ) { /* If both bits are on */
+			/* both of the buddy blocks are free we can combine them */
+			*bytep ^= mask;	/* turn off the two bits */
+			block = ( byte * 8 ) + bit; /* block of first of buddies */
+			tcenum = block << order;
+			/* free the buddied block */
+			PPCDBG(PPCDBG_TCE, 
+			       "free_tce_range: buddying blocks %ld & %ld\n",
+			       block, block+1);
+			free_tce_range_nolock( tbl, tcenum, order+1 ); 
+		}	
+	}
+}
+
+static long test_tce_range( struct TceTable *tbl, long tcenum, unsigned order )
+{
+	unsigned long block;
+	unsigned byte, bit, mask, b;
+	long	retval, retLeft, retRight;
+	unsigned char  * map;
+	
+	map = tbl->mlbm.level[order].map;
+	block = tcenum >> order;
+	byte = block / 8;		/* Byte within bitmap */
+	bit  = block % 8;		/* Bit within byte */
+	mask = 0x80 >> bit;		
+	b    = (*(map+byte) & mask );	/* 0 if block is allocated, else free */
+	if ( b ) 
+		retval = 1;		/* 1 == block is free */
+	else
+		retval = 0;		/* 0 == block is allocated */
+	/* Test bits at all levels below this to ensure that all agree */
+
+	if (order) {
+		retLeft  = test_tce_range( tbl, tcenum, order-1 );
+		retRight = test_tce_range( tbl, tcenum+(1<<(order-1)), order-1 );
+		if ( retLeft || retRight ) {
+			retval = 2;		
+		}
+	}
+
+	/* Test bits at all levels above this to ensure that all agree */
+	
+	return retval;
+}
+
+static inline dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int direction )
+{
+	long tcenum;
+	unsigned long uaddr;
+	unsigned i;
+	dma_addr_t retTce = NO_TCE;
+
+	uaddr = (unsigned long)page & PAGE_MASK;
+	
+	/* Allocate a range of tces */
+	tcenum = alloc_tce_range( tbl, order );
+	if ( tcenum != -1 ) {
+		/* We got the tces we wanted */
+		tcenum += tbl->startOffset;	/* Offset into real TCE table */
+		retTce = tcenum << PAGE_SHIFT;	/* Set the return dma address */
+		/* Setup a tce for each page */
+		for (i=0; i<numPages; ++i) {
+			ppc_md.tce_build(tbl, tcenum, uaddr, direction); 
+			++tcenum;
+			uaddr += PAGE_SIZE;
+		}
+		/* Make sure the update is visible to hardware. 
+		   sync required to synchronize the update to 
+		   the TCE table with the MMIO that will send
+		   the bus address to the IOA */
+		__asm__ __volatile__ ("sync" : : : "memory");
+	}
+	else {
+		panic("PCI_DMA: Tce Allocation failure in get_tces. 0x%p\n",tbl);
+	}
+
+	return retTce; 
+}
+
+static void tce_free_one_iSeries( struct TceTable *tbl, long tcenum )
+{
+	u64 set_tce_rc;
+	union Tce tce;
+	tce.wholeTce = 0;
+	set_tce_rc = HvCallXm_setTce((u64)tbl->index,
+				   (u64)tcenum,
+				   tce.wholeTce);
+	if ( set_tce_rc ) 
+		panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", set_tce_rc);
+
+}
+
+static void tce_free_one_pSeries( struct TceTable *tbl, long tcenum )
+{
+	union Tce tce;
+	union Tce *tce_addr;
+
+	tce.wholeTce = 0;
+
+	tce_addr  = ((union Tce *)tbl->base) + tcenum;
+	*tce_addr = (union Tce)tce.wholeTce;
+
+}
+
+static void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, 
+			     unsigned order, unsigned num_pages)
+{
+	long tcenum, total_tces, free_tce;
+	unsigned i;
+
+	total_tces = (tbl->size * (PAGE_SIZE / sizeof(union Tce)));
+	
+	tcenum = dma_addr >> PAGE_SHIFT;
+	free_tce = tcenum - tbl->startOffset;
+
+	if ( ( (free_tce + num_pages) > total_tces ) ||
+	     ( tcenum < tbl->startOffset ) ) {
+		printk("tce_free: invalid tcenum\n");
+		printk("\ttcenum    = 0x%lx\n", tcenum); 
+		printk("\tTCE Table = 0x%lx\n", (u64)tbl);
+		printk("\tbus#      = 0x%lx\n", (u64)tbl->busNumber );
+		printk("\tsize      = 0x%lx\n", (u64)tbl->size);
+		printk("\tstartOff  = 0x%lx\n", (u64)tbl->startOffset );
+		printk("\tindex     = 0x%lx\n", (u64)tbl->index);
+		return;
+	}
+	
+	for (i=0; i<num_pages; ++i) {
+		ppc_md.tce_free_one(tbl, tcenum);
+		++tcenum;
+	}
+
+	/* No sync (to make TCE change visible) is required here.
+	   The lwsync when acquiring the lock in free_tce_range
+	   is sufficient to synchronize with the bitmap.
+	*/
+
+	free_tce_range( tbl, free_tce, order );
+}
+
+void __init create_virtual_bus_tce_table(void)
+{
+	struct TceTable *t;
+	struct TceTableManagerCB virtBusTceTableParms;
+	u64 absParmsPtr;
+
+	virtBusTceTableParms.busNumber = 255;	/* Bus 255 is the virtual bus */
+	virtBusTceTableParms.virtualBusFlag = 0xff; /* Ask for virtual bus */
+	
+	absParmsPtr = virt_to_absolute( (u64)&virtBusTceTableParms );
+	HvCallXm_getTceTableParms( absParmsPtr );
+	
+	virtBusVethTceTable.size = virtBusTceTableParms.size / 2;
+	virtBusVethTceTable.busNumber = virtBusTceTableParms.busNumber;
+	virtBusVethTceTable.startOffset = virtBusTceTableParms.startOffset;
+	virtBusVethTceTable.index = virtBusTceTableParms.index;
+	virtBusVethTceTable.tceType = TCE_VB;
+
+	virtBusVioTceTable.size = virtBusTceTableParms.size - virtBusVethTceTable.size;
+	virtBusVioTceTable.busNumber = virtBusTceTableParms.busNumber;
+	virtBusVioTceTable.startOffset = virtBusTceTableParms.startOffset +
+			virtBusVethTceTable.size * (PAGE_SIZE/sizeof(union Tce));
+	virtBusVioTceTable.index = virtBusTceTableParms.index;
+	virtBusVioTceTable.tceType = TCE_VB; 
+
+	t = build_tce_table( &virtBusVethTceTable );
+	if ( t ) {
+		/* tceTables[255] = t; */
+		//VirtBusVethTceTable = t;
+		printk( "Virtual Bus VETH TCE table built successfully.\n");
+		printk( "  TCE table size = %ld entries\n", 
+				(unsigned long)t->size*(PAGE_SIZE/sizeof(union Tce)) );
+		printk( "  TCE table token = %d\n",
+				(unsigned)t->index );
+		printk( "  TCE table start entry = 0x%lx\n",
+				(unsigned long)t->startOffset );
+	}
+	else printk( "Virtual Bus VETH TCE table failed.\n");
+
+	t = build_tce_table( &virtBusVioTceTable );
+	if ( t ) {
+		//VirtBusVioTceTable = t;
+		printk( "Virtual Bus VIO TCE table built successfully.\n");
+		printk( "  TCE table size = %ld entries\n", 
+				(unsigned long)t->size*(PAGE_SIZE/sizeof(union Tce)) );
+		printk( "  TCE table token = %d\n",
+				(unsigned)t->index );
+		printk( "  TCE table start entry = 0x%lx\n",
+				(unsigned long)t->startOffset );
+	}
+	else printk( "Virtual Bus VIO TCE table failed.\n");
+}
+
+void create_tce_tables_for_buses(struct list_head *bus_list)
+{
+	struct pci_controller* phb;
+	struct device_node *dn, *first_dn;
+	int num_slots, num_slots_ilog2;
+	int first_phb = 1;
+
+	for (phb=hose_head;phb;phb=phb->next) {
+		first_dn = ((struct device_node *)phb->arch_data)->child;
+		/* Carve 2GB into the largest dma_window_size possible */
+		for (dn = first_dn, num_slots = 0; dn != NULL; dn = dn->sibling)
+			num_slots++;
+		num_slots_ilog2 = __ilog2(num_slots);
+		if ((1<<num_slots_ilog2) != num_slots)
+			num_slots_ilog2++;
+		phb->dma_window_size = 1 << (22 - num_slots_ilog2);
+		/* Reserve 16MB of DMA space on the first PHB.
+		 * We should probably be more careful and use firmware props.
+		 * In reality this space is remapped, not lost.  But we don't
+		 * want to get that smart to handle it -- too much work.
+		 */
+		phb->dma_window_base_cur = first_phb ? (1 << 12) : 0;
+		first_phb = 0;
+		for (dn = first_dn, num_slots = 0; dn != NULL; dn = dn->sibling) {
+			create_pci_bus_tce_table((unsigned long)dn);
+		}
+	}
+}
+
+void create_tce_tables_for_busesLP(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	struct device_node *busdn;
+	u32 *dma_window;
+	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		busdn = PCI_GET_DN(bus);
+		/* NOTE: there should never be a window declared on a bus when
+		 * child devices also have a window.  If this should ever be
+		 * architected, we probably want children to have priority.
+		 * In reality, the PHB containing ISA has the property, but otherwise
+		 * it is the pci-bridges that have the property.
+		 */
+		dma_window = (u32 *)get_property(busdn, "ibm,dma-window", 0);
+		if (dma_window) {
+			/* Busno hasn't been copied yet.
+			 * Do it now because getTceTableParmsPSeriesLP needs it.
+			 */
+			busdn->busno = bus->number;
+			create_pci_bus_tce_table((unsigned long)busdn);
+		} else
+			create_tce_tables_for_busesLP(&bus->children);
+	}
+}
+
+void create_tce_tables(void) {
+	struct pci_dev *dev;
+	struct device_node *dn, *mydn;
+
+	if (naca->platform == PLATFORM_PSERIES_LPAR) {
+		create_tce_tables_for_busesLP(&pci_root_buses);
+	}
+	else {
+		create_tce_tables_for_buses(&pci_root_buses);
+	}
+	/* Now copy the tce_table ptr from the bus devices down to every
+	 * pci device_node.  This means get_tce_table() won't need to search
+	 * up the device tree to find it.
+	 */
+	pci_for_each_dev(dev) {
+		mydn = dn = PCI_GET_DN(dev);
+		while (dn && dn->tce_table == NULL)
+			dn = dn->parent;
+		if (dn) {
+			mydn->tce_table = dn->tce_table;
+		}
+	}
+}
+
+
+/*
+ * iSeries token = iSeries_device_Node*
+ * pSeries token = pci_controller*
+ *
+ */
+void create_pci_bus_tce_table( unsigned long token ) {
+	struct TceTable * newTceTable;
+
+	PPCDBG(PPCDBG_TCE, "Entering create_pci_bus_tce_table.\n");
+	PPCDBG(PPCDBG_TCE, "\ttoken = 0x%lx\n", token);
+
+	newTceTable = (struct TceTable *)kmalloc( sizeof(struct TceTable), GFP_KERNEL );
+
+	/*****************************************************************/
+ 	/* For the iSeries machines, the HvTce Table can be one of three */
+ 	/* flavors,                                                      */
+ 	/* - Single bus TCE table,                                       */
+ 	/* - Tce Table Share between buses,                              */
+ 	/* - Tce Table per logical slot.                                 */
+	/*****************************************************************/
+	if(naca->platform == PLATFORM_ISERIES_LPAR) {
+
+		struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)token;
+		getTceTableParmsiSeries(DevNode,newTceTable);
+
+		/* Look for existing TCE table for this device.          */
+		DevNode->DevTceTable = findHwTceTable(newTceTable );
+		if( DevNode->DevTceTable == NULL) {
+			DevNode->DevTceTable = build_tce_table( newTceTable );
+		}
+		else {
+		    /* We're using a shared table, free this new one.    */
+		    kfree(newTceTable);
+		}
+		printk("Pci Device 0x%p TceTable: %p\n",DevNode,DevNode->DevTceTable);
+ 		return;
+	}
+	/* pSeries Leg */
+	else {
+		struct device_node *dn;
+		struct pci_controller *phb;
+
+		dn = (struct device_node *)token;
+		phb = dn->phb;
+		if (naca->platform == PLATFORM_PSERIES)
+			getTceTableParmsPSeries(phb, dn, newTceTable);
+		else
+			getTceTableParmsPSeriesLP(phb, dn, newTceTable);
+
+		dn->tce_table  = build_tce_table( newTceTable );
+	}
+}
+
+/***********************************************************************/
+/* This function compares the known Tce tables to find a TceTable that */
+/* has already been built for hardware TCEs.                           */
+/* Search the complete(all devices) for a TCE table assigned.  If the  */
+/* startOffset, index, and size match, then the TCE for this device has*/
+/* already been built and it should be shared with this device         */
+/***********************************************************************/
+static struct TceTable* findHwTceTable(struct TceTable * newTceTable )
+{
+	struct list_head* Device_Node_Ptr    = iSeries_Global_Device_List.next;
+	/* Cache the compare values. */
+	u64  startOffset = newTceTable->startOffset;
+	u64  index       = newTceTable->index;
+	u64  size        = newTceTable->size;
+
+	while(Device_Node_Ptr != &iSeries_Global_Device_List) {
+		struct iSeries_Device_Node* CmprNode = (struct iSeries_Device_Node*)Device_Node_Ptr;
+		if( CmprNode->DevTceTable != NULL &&
+		    CmprNode->DevTceTable->tceType == TCE_PCI) {
+			if( CmprNode->DevTceTable->startOffset == startOffset &&
+			    CmprNode->DevTceTable->index       == index       &&
+			    CmprNode->DevTceTable->size        == size        ) {
+				printk("PCI TCE table matches 0x%p \n",CmprNode->DevTceTable);
+				return CmprNode->DevTceTable;
+			}
+		}
+		/* Get next Device Node in List             */
+		Device_Node_Ptr = Device_Node_Ptr->next;
+	}
+	return NULL;
+}
+
+/***********************************************************************/
+/* Call Hv with the architected data structure to get TCE table info.  */
+/* info. Put the returned data into the Linux representation of the    */
+/* TCE table data.                                                     */
+/* The Hardware Tce table comes in three flavors.                      */ 
+/* 1. TCE table shared between Buses.                                  */
+/* 2. TCE table per Bus.                                               */
+/* 3. TCE Table per IOA.                                               */
+/***********************************************************************/
+static void getTceTableParmsiSeries(struct iSeries_Device_Node* DevNode,
+				    struct TceTable* newTceTable )
+{
+	struct TceTableManagerCB* pciBusTceTableParms = (struct TceTableManagerCB*)kmalloc( sizeof(struct TceTableManagerCB), GFP_KERNEL );
+	if(pciBusTceTableParms == NULL) panic("PCI_DMA: TCE Table Allocation failed.");
+
+	memset( (void*)pciBusTceTableParms,0,sizeof(struct TceTableManagerCB) );
+	pciBusTceTableParms->busNumber      = ISERIES_BUS(DevNode);
+	pciBusTceTableParms->logicalSlot    = DevNode->LogicalSlot;
+	pciBusTceTableParms->virtualBusFlag = 0;
+
+	HvCallXm_getTceTableParms( REALADDR(pciBusTceTableParms) );
+
+        /* PciTceTableParms Bus:0x18 Slot:0x04 Start:0x000000 Offset:0x04c000 Size:0x0020 */
+	printk("PciTceTableParms Bus:0x%02lx Slot:0x%02x Start:0x%06lx Offset:0x%06lx Size:0x%04lx\n",
+	       pciBusTceTableParms->busNumber,
+	       pciBusTceTableParms->logicalSlot,
+	       pciBusTceTableParms->start,
+	       pciBusTceTableParms->startOffset,
+	       pciBusTceTableParms->size);
+
+	if(pciBusTceTableParms->size == 0) {
+		printk("PCI_DMA: Possible Structure mismatch, 0x%p\n",pciBusTceTableParms);
+		panic( "PCI_DMA: pciBusTceTableParms->size is zero, halt here!");
+	}
+
+	newTceTable->size        = pciBusTceTableParms->size;
+	newTceTable->busNumber   = pciBusTceTableParms->busNumber;
+	newTceTable->startOffset = pciBusTceTableParms->startOffset;
+	newTceTable->index       = pciBusTceTableParms->index;
+	newTceTable->tceType     = TCE_PCI;
+
+	kfree(pciBusTceTableParms);
+}
+
+static void getTceTableParmsPSeries(struct pci_controller *phb,
+				    struct device_node *dn,
+				    struct TceTable *newTceTable ) {
+	phandle node;
+	unsigned long i;
+
+	node = ((struct device_node *)(phb->arch_data))->node;
+
+	PPCDBG(PPCDBG_TCEINIT, "getTceTableParms: start\n"); 
+	PPCDBG(PPCDBG_TCEINIT, "\tof_tce_table = 0x%lx\n", of_tce_table); 
+	PPCDBG(PPCDBG_TCEINIT, "\tphb          = 0x%lx\n", phb); 
+	PPCDBG(PPCDBG_TCEINIT, "\tdn           = 0x%lx\n", dn); 
+	PPCDBG(PPCDBG_TCEINIT, "\tdn->name     = %s\n", dn->name); 
+	PPCDBG(PPCDBG_TCEINIT, "\tdn->full_name= %s\n", dn->full_name); 
+	PPCDBG(PPCDBG_TCEINIT, "\tnewTceTable  = 0x%lx\n", newTceTable); 
+	PPCDBG(PPCDBG_TCEINIT, "\tdma_window_size = 0x%lx\n", phb->dma_window_size); 
+
+	i = 0;
+	while(of_tce_table[i].node) {
+		PPCDBG(PPCDBG_TCEINIT, "\tof_tce_table[%d].node = 0x%lx\n", 
+		       i, of_tce_table[i].node);
+		PPCDBG(PPCDBG_TCEINIT, "\tof_tce_table[%d].base = 0x%lx\n", 
+		       i, of_tce_table[i].base);
+		PPCDBG(PPCDBG_TCEINIT, "\tof_tce_table[%d].size = 0x%lx\n", 
+		       i, of_tce_table[i].size >> PAGE_SHIFT);
+		PPCDBG(PPCDBG_TCEINIT, "\tphb->arch_data->node = 0x%lx\n", 
+		       node);
+
+		if(of_tce_table[i].node == node) {
+			memset((void *)of_tce_table[i].base, 
+			       0, of_tce_table[i].size);
+			newTceTable->busNumber = phb->bus->number;
+
+			/* Units of tce entries.                        */
+			newTceTable->startOffset = phb->dma_window_base_cur;
+
+			/* Adjust the current table offset to the next  */
+			/* region.  Measured in TCE entries. Force an   */
+			/* alignment to the size alloted per IOA. This  */
+			/* makes it easier to remove the 1st 16MB.      */
+			phb->dma_window_base_cur += (phb->dma_window_size>>3);
+			phb->dma_window_base_cur &= 
+				~((phb->dma_window_size>>3)-1);
+
+			/* Set the tce table size - measured in units   */
+			/* of pages of tce table.                       */
+			newTceTable->size = ((phb->dma_window_base_cur -
+					      newTceTable->startOffset) << 3)
+					      >> PAGE_SHIFT;
+
+			/* Test if we are going over 2GB of DMA space.  */
+			if(phb->dma_window_base_cur > (1 << 19)) { 
+				panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 
+			}
+
+			newTceTable->base = of_tce_table[i].base;
+			newTceTable->index = 0;
+			
+			PPCDBG(PPCDBG_TCEINIT, 
+			       "\tnewTceTable->base        = 0x%lx\n",
+			       newTceTable->base);
+			PPCDBG(PPCDBG_TCEINIT, 
+			       "\tnewTceTable->startOffset = 0x%lx"
+			       "(# tce entries)\n", 
+			       newTceTable->startOffset);
+			PPCDBG(PPCDBG_TCEINIT, 
+			       "\tnewTceTable->size        = 0x%lx"
+			       "(# pages of tce table)\n", 
+			       newTceTable->size);
+		}
+		i++;
+	}
+}
+
+/*
+ * getTceTableParmsPSeriesLP
+ *
+ * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
+ *
+ * ToDo: properly interpret the ibm,dma-window property.  The definition is:
+ *	logical-bus-number	(1 word)
+ *	phys-address		(#address-cells words)
+ *	size			(#cell-size words)
+ *
+ * Currently we hard code these sizes (more or less).
+ */
+static void getTceTableParmsPSeriesLP(struct pci_controller *phb,
+				    struct device_node *dn,
+				    struct TceTable *newTceTable ) {
+	u32 *dma_window = (u32 *)get_property(dn, "ibm,dma-window", 0);
+	if (!dma_window) {
+		panic("PCI_DMA: getTceTableParmsPSeriesLP: device %s has no ibm,dma-window property!\n", dn->full_name);
+	}
+
+	newTceTable->busNumber = dn->busno;
+	newTceTable->size = (((((unsigned long)dma_window[4] << 32) | (unsigned long)dma_window[5]) >> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
+	newTceTable->startOffset = ((((unsigned long)dma_window[2] << 32) | (unsigned long)dma_window[3]) >> 12);
+	newTceTable->base = 0;
+	newTceTable->index = dma_window[0];
+	PPCDBG(PPCDBG_TCEINIT, "getTceTableParmsPSeriesLP for bus 0x%lx:\n", dn->busno);
+	PPCDBG(PPCDBG_TCEINIT, "\tDevice = %s\n", dn->full_name);
+	PPCDBG(PPCDBG_TCEINIT, "\tnewTceTable->index       = 0x%lx\n", newTceTable->index);
+	PPCDBG(PPCDBG_TCEINIT, "\tnewTceTable->startOffset = 0x%lx\n", newTceTable->startOffset);
+	PPCDBG(PPCDBG_TCEINIT, "\tnewTceTable->size        = 0x%lx\n", newTceTable->size);
+}
+
+/* Allocates a contiguous real buffer and creates TCEs over it.
+ * Returns the virtual address of the buffer and sets dma_handle
+ * to the dma address (tce) of the first page.
+ */
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t *dma_handle)
+{
+	struct TceTable * tbl;
+	void *ret = NULL;
+	unsigned order, nPages;
+	dma_addr_t tce;
+
+	PPCDBG(PPCDBG_TCE, "pci_alloc_consistent:\n");
+	PPCDBG(PPCDBG_TCE, "\thwdev      = 0x%16.16lx\n", hwdev);
+	PPCDBG(PPCDBG_TCE, "\tsize       = 0x%16.16lx\n", size);
+	PPCDBG(PPCDBG_TCE, "\tdma_handle = 0x%16.16lx\n", dma_handle);	
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+	nPages = 1 << order;
+
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_alloc_consistent size to large: 0x%lx \n",size);
+ 		return (void *)NO_TCE;
+ 	}
+
+	tbl = get_tce_table(hwdev); 
+
+	if ( tbl ) {
+		/* Alloc enough pages (and possibly more) */
+		ret = (void *)__get_free_pages( GFP_ATOMIC, order );
+		if ( ret ) {
+			/* Page allocation succeeded */
+			memset(ret, 0, nPages << PAGE_SHIFT);
+			/* Set up tces to cover the allocated range */
+			tce = get_tces( tbl, order, ret, nPages, PCI_DMA_BIDIRECTIONAL );
+			if ( tce == NO_TCE ) {
+				PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: get_tces failed\n" );
+				free_pages( (unsigned long)ret, order );
+				ret = NULL;
+			}
+			else
+			{
+				*dma_handle = tce;
+			}
+		}
+		else PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: __get_free_pages failed for order = %d\n", order);
+	}
+	else PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: get_tce_table failed for 0x%016lx\n", hwdev);
+
+	PPCDBG(PPCDBG_TCE, "\tpci_alloc_consistent: dma_handle = 0x%16.16lx\n", *dma_handle);	
+	PPCDBG(PPCDBG_TCE, "\tpci_alloc_consistent: return     = 0x%16.16lx\n", ret);	
+	return ret;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	struct TceTable * tbl;
+	unsigned order, nPages;
+	
+	PPCDBG(PPCDBG_TCE, "pci_free_consistent:\n");
+	PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, size = 0x%16.16lx, dma_handle = 0x%16.16lx, vaddr = 0x%16.16lx\n", hwdev, size, dma_handle, vaddr);	
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+	nPages = 1 << order;
+
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_free_consistent size to large: 0x%lx \n",size);
+ 		return;
+ 	}
+	
+	tbl = get_tce_table(hwdev); 
+
+	if ( tbl ) {
+		tce_free(tbl, dma_handle, order, nPages);
+		free_pages( (unsigned long)vaddr, order );
+	}
+}
+
+/* Creates TCEs for a user provided buffer.  The user buffer must be 
+ * contiguous real kernel storage (not vmalloc).  The address of the buffer
+ * passed here is the kernel (virtual) address of the buffer.  The buffer
+ * need not be page aligned, the dma_addr_t returned will point to the same
+ * byte within the page as vaddr.
+ */
+dma_addr_t pci_map_single(struct pci_dev *hwdev, void *vaddr, 
+			  size_t size, int direction )
+{
+	struct TceTable * tbl;
+	dma_addr_t dma_handle = NO_TCE;
+	unsigned long uaddr;
+	unsigned order, nPages;
+
+	PPCDBG(PPCDBG_TCE, "pci_map_single:\n");
+	PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, size = 0x%16.16lx, direction = 0x%16.16lx, vaddr = 0x%16.16lx\n", hwdev, size, direction, vaddr);	
+	if ( direction == PCI_DMA_NONE )
+		BUG();
+	
+	uaddr = (unsigned long)vaddr;
+	nPages = PAGE_ALIGN( uaddr + size ) - ( uaddr & PAGE_MASK );
+	order = get_order( nPages & PAGE_MASK );
+	nPages >>= PAGE_SHIFT;
+	
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_map_single size to large: 0x%lx \n",size);
+ 		return NO_TCE;
+ 	}
+
+	tbl = get_tce_table(hwdev); 
+
+	if ( tbl ) {
+		dma_handle = get_tces( tbl, order, vaddr, nPages, direction );
+		dma_handle |= ( uaddr & ~PAGE_MASK );
+	}
+
+	return dma_handle;
+}
+
+void pci_unmap_single( struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction )
+{
+	struct TceTable * tbl;
+	unsigned order, nPages;
+	
+	PPCDBG(PPCDBG_TCE, "pci_unmap_single:\n");
+	PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, size = 0x%16.16lx, direction = 0x%16.16lx, dma_handle = 0x%16.16lx\n", hwdev, size, direction, dma_handle);	
+	if ( direction == PCI_DMA_NONE )
+		BUG();
+
+	nPages = PAGE_ALIGN( dma_handle + size ) - ( dma_handle & PAGE_MASK );
+	order = get_order( nPages & PAGE_MASK );
+	nPages >>= PAGE_SHIFT;
+
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_unmap_single size to large: 0x%lx \n",size);
+ 		return;
+ 	}
+	
+	tbl = get_tce_table(hwdev); 
+
+	if ( tbl ) 
+		tce_free(tbl, dma_handle, order, nPages);
+
+}
+
+/* Figure out how many TCEs are actually going to be required
+ * to map this scatterlist.  This code is not optimal.  It 
+ * takes into account the case where entry n ends in the same
+ * page in which entry n+1 starts.  It does not handle the 
+ * general case of entry n ending in the same page in which 
+ * entry m starts.   
+ */
+static unsigned long num_tces_sg( struct scatterlist *sg, int nents )
+{
+	unsigned long nTces, numPages, startPage, endPage, prevEndPage;
+	unsigned i;
+
+	prevEndPage = 0;
+	nTces = 0;
+
+	for (i=0; i<nents; ++i) {
+		/* Compute the starting page number and
+		 * the ending page number for this entry
+		 */
+		startPage = (unsigned long)sg->address >> PAGE_SHIFT;
+		endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT;
+		numPages = endPage - startPage + 1;
+		/* Simple optimization: if the previous entry ended
+		 * in the same page in which this entry starts
+		 * then we can reduce the required pages by one.
+		 * This matches assumptions in fill_scatterlist_sg and
+		 * create_tces_sg
+		 */
+		if ( startPage == prevEndPage )
+			--numPages;
+		nTces += numPages;
+		prevEndPage = endPage;
+		sg++;
+	}
+	return nTces;
+}
+
+/* Fill in the dma data in the scatterlist
+ * return the number of dma sg entries created
+ */
+static unsigned fill_scatterlist_sg( struct scatterlist *sg, int nents, 
+				 dma_addr_t dma_addr , unsigned long numTces)
+{
+	struct scatterlist *dma_sg;
+	u32 cur_start_dma;
+	unsigned long cur_len_dma, cur_end_virt, uaddr;
+	unsigned num_dma_ents;
+
+	dma_sg = sg;
+	num_dma_ents = 1;
+
+	/* Process the first sg entry */
+	cur_start_dma = dma_addr + ((unsigned long)sg->address & (~PAGE_MASK));
+	cur_len_dma = sg->length;
+	/* cur_end_virt holds the address of the byte immediately after the
+	 * end of the current buffer.
+	 */
+	cur_end_virt = (unsigned long)sg->address + cur_len_dma;
+	/* Later code assumes that unused sg->dma_address and sg->dma_length
+	 * fields will be zero.  Other archs seem to assume that the user
+	 * (device driver) guarantees that...I don't want to depend on that
+	 */
+	sg->dma_address = sg->dma_length = 0;
+	
+	/* Process the rest of the sg entries */
+	while (--nents) {
+		++sg;
+		/* Clear possibly unused fields. Note: sg >= dma_sg so
+		 * this can't be clearing a field we've already set
+		 */
+		sg->dma_address = sg->dma_length = 0;
+
+		/* Check if it is possible to make this next entry
+		 * contiguous (in dma space) with the previous entry.
+		 */
+		
+		/* The entries can be contiguous in dma space if
+		 * the previous entry ends immediately before the
+		 * start of the current entry (in virtual space)
+		 * or if the previous entry ends at a page boundary
+		 * and the current entry starts at a page boundary.
+		 */
+		uaddr = (unsigned long)sg->address;
+		if ( ( uaddr != cur_end_virt ) &&
+		     ( ( ( uaddr | cur_end_virt ) & (~PAGE_MASK) ) ||
+		       ( ( uaddr & PAGE_MASK ) == ( ( cur_end_virt-1 ) & PAGE_MASK ) ) ) ) {
+			/* This entry can not be contiguous in dma space.
+			 * save the previous dma entry and start a new one
+			 */
+			dma_sg->dma_address = cur_start_dma;
+			dma_sg->dma_length  = cur_len_dma;
+
+			++dma_sg;
+			++num_dma_ents;
+			
+			cur_start_dma += cur_len_dma-1;
+			/* If the previous entry ends and this entry starts
+			 * in the same page then they share a tce.  In that
+			 * case don't bump cur_start_dma to the next page 
+			 * in dma space.  This matches assumptions made in
+			 * num_tces_sg and create_tces_sg.
+			 */
+			if ((uaddr & PAGE_MASK) == ((cur_end_virt-1) & PAGE_MASK))
+				cur_start_dma &= PAGE_MASK;
+			else
+				cur_start_dma = PAGE_ALIGN(cur_start_dma+1);
+			cur_start_dma += ( uaddr & (~PAGE_MASK) );
+			cur_len_dma = 0;
+		}
+		/* Accumulate the length of this entry for the next 
+		 * dma entry
+		 */
+		cur_len_dma += sg->length;
+		cur_end_virt = uaddr + sg->length;
+	}
+	/* Fill in the last dma entry */
+	dma_sg->dma_address = cur_start_dma;
+	dma_sg->dma_length  = cur_len_dma;
+
+	if ((((cur_start_dma +cur_len_dma - 1)>> PAGE_SHIFT) - (dma_addr >> PAGE_SHIFT) + 1) != numTces)
+	  {
+	    PPCDBG(PPCDBG_TCE, "fill_scatterlist_sg: numTces %ld, used tces %d\n",
+		   numTces,
+		   (unsigned)(((cur_start_dma + cur_len_dma - 1) >> PAGE_SHIFT) - (dma_addr >> PAGE_SHIFT) + 1));
+	  }
+	
+
+	return num_dma_ents;
+}
+
+/* Call the hypervisor to create the TCE entries.
+ * return the number of TCEs created
+ */
+static dma_addr_t create_tces_sg( struct TceTable *tbl, struct scatterlist *sg, 
+		   int nents, unsigned numTces, int direction )
+{
+	unsigned order, i, j;
+	unsigned long startPage, endPage, prevEndPage, numPages, uaddr;
+	long tcenum, starttcenum;
+	dma_addr_t dmaAddr;
+
+	dmaAddr = NO_TCE;
+
+	order = get_order( numTces << PAGE_SHIFT );
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+		printk("PCI_DMA: create_tces_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT));
+ 		return NO_TCE;
+ 	}
+
+	/* allocate a block of tces */
+	tcenum = alloc_tce_range( tbl, order );
+	if ( tcenum != -1 ) {
+		tcenum += tbl->startOffset;
+		starttcenum = tcenum;
+		dmaAddr = tcenum << PAGE_SHIFT;
+		prevEndPage = 0;
+		for (j=0; j<nents; ++j) {
+			startPage = (unsigned long)sg->address >> PAGE_SHIFT;
+			endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT;
+			numPages = endPage - startPage + 1;
+			
+			uaddr = (unsigned long)sg->address;
+
+			/* If the previous entry ended in the same page that
+			 * the current page starts then they share that
+			 * tce and we reduce the number of tces we need
+			 * by one.  This matches assumptions made in
+			 * num_tces_sg and fill_scatterlist_sg
+			 */
+			if ( startPage == prevEndPage ) {
+				--numPages;
+				uaddr += PAGE_SIZE;
+			}
+			
+			for (i=0; i<numPages; ++i) {
+			  ppc_md.tce_build(tbl, tcenum, uaddr, direction); 
+			  ++tcenum;
+			  uaddr += PAGE_SIZE;
+			}
+		
+			prevEndPage = endPage;
+			sg++;
+		}
+		/* Make sure the update is visible to hardware. 
+		   sync required to synchronize the update to 
+		   the TCE table with the MMIO that will send
+		   the bus address to the IOA */
+		__asm__ __volatile__ ("sync" : : : "memory");
+
+		if ((tcenum - starttcenum) != numTces)
+	    		PPCDBG(PPCDBG_TCE, "create_tces_sg: numTces %d, tces used %d\n",
+		   		numTces, (unsigned)(tcenum - starttcenum));
+
+	}
+
+	return dmaAddr;
+}
+
+int pci_map_sg( struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction )
+{
+	struct TceTable * tbl;
+	unsigned numTces;
+	int num_dma;
+	dma_addr_t dma_handle;
+
+	PPCDBG(PPCDBG_TCE, "pci_map_sg:\n");
+	PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, sg = 0x%16.16lx, direction = 0x%16.16lx, nents = 0x%16.16lx\n", hwdev, sg, direction, nents);	
+	/* Fast path for a single entry scatterlist */
+	if ( nents == 1 ) {
+		sg->dma_address = pci_map_single( hwdev, sg->address, 
+					sg->length, direction );
+		sg->dma_length = sg->length;
+		return 1;
+	}
+	
+	if ( direction == PCI_DMA_NONE )
+		BUG();
+	
+	tbl = get_tce_table(hwdev); 
+
+	if ( tbl ) {
+		/* Compute the number of tces required */
+		numTces = num_tces_sg( sg, nents );
+		/* Create the tces and get the dma address */ 
+		dma_handle = create_tces_sg( tbl, sg, nents, numTces, direction );
+
+		/* Fill in the dma scatterlist */
+		num_dma = fill_scatterlist_sg( sg, nents, dma_handle, numTces );
+	}
+
+	return num_dma;
+}
+
+void pci_unmap_sg( struct pci_dev *hwdev, struct scatterlist *sg, int nelms, int direction )
+{
+	struct TceTable * tbl;
+	unsigned order, numTces, i;
+	dma_addr_t dma_end_page, dma_start_page;
+	
+	PPCDBG(PPCDBG_TCE, "pci_unmap_sg:\n");
+	PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, sg = 0x%16.16lx, direction = 0x%16.16lx, nelms = 0x%16.16lx\n", hwdev, sg, direction, nelms);	
+
+	if ( direction == PCI_DMA_NONE )
+		BUG();
+
+	dma_start_page = sg->dma_address & PAGE_MASK;
+	for ( i=nelms; i>0; --i ) {
+		unsigned k = i - 1;
+		if ( sg[k].dma_length ) {
+			dma_end_page = ( sg[k].dma_address +
+					 sg[k].dma_length - 1 ) & PAGE_MASK;
+			break;
+		}
+	}
+
+	numTces = ((dma_end_page - dma_start_page ) >> PAGE_SHIFT) + 1;
+	order = get_order( numTces << PAGE_SHIFT );
+
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+		printk("PCI_DMA: pci_unmap_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT));
+ 		return;
+ 	}
+	
+	tbl = get_tce_table(hwdev); 
+
+	if ( tbl ) 
+		tce_free( tbl, dma_start_page, order, numTces );
+
+}
+
+/*
+ * phb_tce_table_init
+ * 
+ * Function: Display TCE config registers.  Could be easily changed
+ *           to initialize the hardware to use TCEs.
+ */
+unsigned long phb_tce_table_init(struct pci_controller *phb) {
+	unsigned int r, cfg_rw, i;	
+	unsigned long r64;	
+	phandle node;
+
+	PPCDBG(PPCDBG_TCE, "phb_tce_table_init: start.\n"); 
+
+	node = ((struct device_node *)(phb->arch_data))->node;
+
+	PPCDBG(PPCDBG_TCEINIT, "\tphb            = 0x%lx\n", phb); 
+	PPCDBG(PPCDBG_TCEINIT, "\tphb->type      = 0x%lx\n", phb->type); 
+	PPCDBG(PPCDBG_TCEINIT, "\tphb->phb_regs  = 0x%lx\n", phb->phb_regs); 
+	PPCDBG(PPCDBG_TCEINIT, "\tphb->chip_regs = 0x%lx\n", phb->chip_regs); 
+	PPCDBG(PPCDBG_TCEINIT, "\tphb: node      = 0x%lx\n", node);
+	PPCDBG(PPCDBG_TCEINIT, "\tphb->arch_data = 0x%lx\n", phb->arch_data); 
+
+	i = 0;
+	while(of_tce_table[i].node) {
+		if(of_tce_table[i].node == node) {
+			if(phb->type == phb_type_python) {
+				r = *(((unsigned int *)phb->phb_regs) + (0xf10>>2)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tTAR(low)    = 0x%x\n", r);
+				r = *(((unsigned int *)phb->phb_regs) + (0xf00>>2)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tTAR(high)   = 0x%x\n", r);
+				r = *(((unsigned int *)phb->phb_regs) + (0xfd0>>2)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tPHB cfg(rw) = 0x%x\n", r);
+				break;
+			} else if(phb->type == phb_type_speedwagon) {
+				r64 = *(((unsigned long *)phb->chip_regs) + 
+					(0x800>>3)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tNCFG    = 0x%lx\n", r64);
+				r64 = *(((unsigned long *)phb->chip_regs) + 
+					(0x580>>3)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tTAR0    = 0x%lx\n", r64);
+				r64 = *(((unsigned long *)phb->chip_regs) + 
+					(0x588>>3)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tTAR1    = 0x%lx\n", r64);
+				r64 = *(((unsigned long *)phb->chip_regs) + 
+					(0x590>>3)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tTAR2    = 0x%lx\n", r64);
+				r64 = *(((unsigned long *)phb->chip_regs) + 
+					(0x598>>3)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tTAR3    = 0x%lx\n", r64);
+				cfg_rw = *(((unsigned int *)phb->chip_regs) + 
+					   ((0x160 +
+					     (((phb->local_number)+8)<<12))>>2)); 
+				PPCDBG(PPCDBG_TCEINIT, "\tcfg_rw = 0x%x\n", cfg_rw);
+			}
+		}
+		i++;
+	}
+
+	PPCDBG(PPCDBG_TCEINIT, "phb_tce_table_init: done\n"); 
+
+	return(0); 
+}
+
+/* These are called very early. */
+void tce_init_pSeries(void)
+{
+	ppc_md.tce_build = tce_build_pSeries;
+	ppc_md.tce_free_one = tce_free_one_pSeries;
+}
+
+void tce_init_iSeries(void)
+{
+	ppc_md.tce_build = tce_build_iSeries;
+	ppc_md.tce_free_one = tce_free_one_iSeries;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pci_dn.c linux/arch/ppc64/kernel/pci_dn.c
--- linux.orig/arch/ppc64/kernel/pci_dn.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pci_dn.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,385 @@
+/*
+ * pci_dn.c
+ *
+ * Copyright (C) 2001 Todd Inglett, IBM Corporation
+ *
+ * PCI manipulation via device_nodes.
+ *
+ * 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/init.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppcdebug.h>
+#include <asm/naca.h>
+#include <asm/pci_dma.h>
+
+#include "pci.h"
+
+/* Traverse_func that inits the PCI fields of the device node.
+ * NOTE: this *must* be done before read/write config to the device.
+ */
+static void * __init
+update_dn_pci_info(struct device_node *dn, void *data)
+{
+	struct pci_controller *phb = (struct pci_controller *)data;
+	u32 *regs;
+	char *device_type = get_property(dn, "device_type", 0);
+
+	dn->phb = phb;
+	if (device_type && strcmp(device_type, "pci") == 0 && get_property(dn, "class-code", 0) == 0) {
+		/* special case for PHB's.  Sigh. */
+		regs = (u32 *)get_property(dn, "bus-range", 0);
+		dn->busno = regs[0];
+		dn->devfn = 0;	/* assumption */
+	} else {
+		regs = (u32 *)get_property(dn, "reg", 0);
+		if (regs) {
+			/* First register entry is addr (00BBSS00)  */
+			dn->busno = (regs[0] >> 16) & 0xff;
+			dn->devfn = (regs[0] >> 8) & 0xff;
+		}
+	}
+	return NULL;
+}
+
+/*
+ * Hit all the BARs of all the devices with values from OF.
+ * This is unnecessary on most systems, but also harmless.
+ */
+static void * __init
+write_OF_bars(struct device_node *dn, void *data)
+{
+	int i;
+	u32 oldbar, newbar, newbartest;
+	u8  config_offset;
+	char *name = get_property(dn, "name", 0);
+	char *device_type = get_property(dn, "device_type", 0);
+	char devname[128];
+	sprintf(devname, "%04x:%02x.%x %s (%s)", dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn), name ? name : "<no name>", device_type ? device_type : "<unknown type>");
+
+	if (device_type && strcmp(device_type, "pci") == 0 &&
+	    get_property(dn, "class-code", 0) == 0)
+		return NULL;	/* This is probably a phb.  Skip it. */
+
+	if (dn->n_addrs == 0)
+		return NULL;	/* This is normal for some adapters or bridges */
+
+	if (dn->addrs == NULL) {
+		/* This shouldn't happen. */
+		printk(KERN_WARNING "write_OF_bars %s: device has %d BARs, but no addrs recorded\n", devname, dn->n_addrs);
+		return NULL;
+	}
+
+#ifndef CONFIG_PPC_ISERIES 
+	for (i = 0; i < dn->n_addrs; i++) {
+		newbar = dn->addrs[i].address;
+		config_offset = dn->addrs[i].space & 0xff;
+		if (ppc_md.pcibios_read_config_dword(dn, config_offset, &oldbar) != PCIBIOS_SUCCESSFUL) {
+			printk(KERN_WARNING "write_OF_bars %s: read BAR%d failed\n", devname, i);
+			continue;
+		}
+		/* Need to update this BAR. */
+		if (ppc_md.pcibios_write_config_dword(dn, config_offset, newbar) != PCIBIOS_SUCCESSFUL) {
+			printk(KERN_WARNING "write_OF_bars %s: write BAR%d with 0x%08x failed (old was 0x%08x)\n", devname, i, newbar, oldbar);
+			continue;
+		}
+		/* sanity check */
+		if (ppc_md.pcibios_read_config_dword(dn, config_offset, &newbartest) != PCIBIOS_SUCCESSFUL) {
+			printk(KERN_WARNING "write_OF_bars %s: sanity test read BAR%d failed?\n", devname, i);
+			continue;
+		}
+		if ((newbar & PCI_BASE_ADDRESS_MEM_MASK) != (newbartest & PCI_BASE_ADDRESS_MEM_MASK)) {
+			printk(KERN_WARNING "write_OF_bars %s: oops...BAR%d read back as 0x%08x%s!\n", devname, i, newbartest, (oldbar & PCI_BASE_ADDRESS_MEM_MASK) == (newbartest & PCI_BASE_ADDRESS_MEM_MASK) ? " (original value)" : "");
+			continue;
+		}
+	}
+#endif
+	return NULL; 
+}
+
+#if 0
+/* Traverse_func that starts the BIST (self test) */
+static void * __init
+startBIST(struct device_node *dn, void *data)
+{
+	struct pci_controller *phb = (struct pci_controller *)data;
+	u8 bist;
+
+	char *name = get_property(dn, "name", 0);
+	udbg_printf("startBIST: %s phb=%p, device=%p\n", name ? name : "<unknown>", phb, dn);
+
+	if (ppc_md.pcibios_read_config_byte(dn, PCI_BIST, &bist) == PCIBIOS_SUCCESSFUL) {
+		if (bist & PCI_BIST_CAPABLE) {
+			udbg_printf("  -> is BIST capable!\n", phb, dn);
+			/* Start bist here */
+		}
+	}
+	return NULL;
+}
+#endif
+
+
+/******************************************************************
+ * Traverse a device tree stopping each PCI device in the tree.
+ * This is done depth first.  As each node is processed, a "pre"
+ * function is called, the children are processed recursively, and
+ * then a "post" function is called.
+ *
+ * The "pre" and "post" funcs return a value.  If non-zero
+ * is returned from the "pre" func, the traversal stops and this
+ * value is returned.  The return value from "post" is not used.
+ * This return value is useful when using traverse as
+ * a method of finding a device.
+ *
+ * NOTE: we do not run the funcs for devices that do not appear to
+ * be PCI except for the start node which we assume (this is good
+ * because the start node is often a phb which may be missing PCI
+ * properties).
+ * We use the class-code as an indicator. If we run into
+ * one of these nodes we also assume its siblings are non-pci for
+ * performance.
+ *
+ ******************************************************************/
+void *traverse_pci_devices(struct device_node *start, traverse_func pre, traverse_func post, void *data)
+{
+	struct device_node *dn, *nextdn;
+	void *ret;
+
+	if (pre && (ret = pre(start, data)) != NULL)
+		return ret;
+	for (dn = start->child; dn; dn = nextdn) {
+		nextdn = NULL;
+		if (get_property(dn, "class-code", 0)) {
+			if (pre && (ret = pre(dn, data)) != NULL)
+				return ret;
+			if (dn->child) {
+				/* Depth first...do children */
+				nextdn = dn->child;
+			} else if (dn->sibling) {
+				/* ok, try next sibling instead. */
+				nextdn = dn->sibling;
+			} else {
+				/* no more children or siblings...call "post" */
+				if (post)
+					post(dn, data);
+			}
+		}
+		if (!nextdn) {
+			/* Walk up to next valid sibling. */
+			do {
+				dn = dn->parent;
+				if (dn == start)
+					return NULL;
+			} while (dn->sibling == NULL);
+			nextdn = dn->sibling;
+		}
+	}
+	return NULL;
+}
+
+/* Same as traverse_pci_devices except this does it for all phbs.
+ */
+void *traverse_all_pci_devices(traverse_func pre)
+{
+	struct pci_controller* phb;
+	void *ret;
+	for (phb=hose_head;phb;phb=phb->next)
+		if ((ret = traverse_pci_devices((struct device_node *)phb->arch_data, pre, NULL, phb)) != NULL)
+			return ret;
+	return NULL;
+}
+
+
+/* Traversal func that looks for a <busno,devfcn> value.
+ * If found, the device_node is returned (thus terminating the traversal).
+ */
+static void *
+is_devfn_node(struct device_node *dn, void *data)
+{
+	int busno = ((unsigned long)data >> 8) & 0xff;
+	int devfn = ((unsigned long)data) & 0xff;
+	return (devfn == dn->devfn && busno == dn->busno) ? dn : NULL;
+}
+
+/* Same as is_devfn_node except ignore the "fn" part of the "devfn".
+ */
+static void *
+is_devfn_sub_node(struct device_node *dn, void *data)
+{
+	int busno = ((unsigned long)data >> 8) & 0xff;
+	int devfn = ((unsigned long)data) & 0xf8;
+	return (devfn == (dn->devfn & 0xf8) && busno == dn->busno) ? dn : NULL;
+}
+
+/* Given an existing EADs (pci bridge) device node create a fake one
+ * that will simulate function zero.  Make it a sibling of other_eads.
+ */
+static struct device_node *
+create_eads_node(struct device_node *other_eads)
+{
+	struct device_node *eads = (struct device_node *)kmalloc(sizeof(struct device_node), GFP_KERNEL);
+
+	if (!eads) return NULL;	/* huh? */
+	*eads = *other_eads;
+	eads->devfn &= ~7;	/* make it function zero */
+	eads->tce_table = NULL;
+	/* NOTE: share properties.  We could copy but for now this should suffice.
+	 * The full_name is also incorrect...but seems harmless.
+	 */
+	eads->child = NULL;
+	eads->next = NULL;
+	other_eads->allnext = eads;
+	other_eads->sibling = eads;
+	return eads;
+}
+
+/* This is the "slow" path for looking up a device_node from a
+ * pci_dev.  It will hunt for the device under it's parent's
+ * phb and then update sysdata for a future fastpath.
+ *
+ * It may also do fixups on the actual device since this happens
+ * on the first read/write.
+ *
+ * Note that it also must deal with devices that don't exist.
+ * In this case it may probe for real hardware ("just in case")
+ * and add a device_node to the device tree if necessary.
+ *
+ */
+struct device_node *fetch_dev_dn(struct pci_dev *dev)
+{
+	struct device_node *orig_dn = (struct device_node *)dev->sysdata;
+	struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */
+	struct device_node *phb_dn;
+	struct device_node *dn;
+	unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
+
+	phb_dn = (struct device_node *)(phb->arch_data);
+	dn = (struct device_node *)traverse_pci_devices(phb_dn, is_devfn_node, NULL, (void *)searchval);
+	if (dn) {
+		dev->sysdata = dn;
+		/* ToDo: call some device init hook here */
+	} else {
+		/* Now it is very possible that we can't find the device because it is
+		 * not the zero'th device of a mutifunction device and we don't have
+		 * permission to read the zero'th device.  If this is the case, Linux
+		 * would ordinarily skip all the other functions.
+		 */
+		if ((searchval & 0x7) == 0) {
+			struct device_node *thisdevdn;
+			/* Ok, we are looking for fn == 0.  Let's check for other functions. */
+			thisdevdn = (struct device_node *)traverse_pci_devices(phb_dn, is_devfn_sub_node, NULL, (void *)searchval);
+			if (thisdevdn) {
+				/* Ah ha!  There does exist a sub function.  Now this isn't an exact
+				 * match for searchval, but in order to get Linux to believe the sub
+				 * functions exist we will need to manufacture a fake device_node
+				 * for this zero'th function.  To keept this simple for now we only
+				 * handle pci bridges and we just hand back the found node which
+				 * isn't correct, but Linux won't care.
+				 */
+				char *device_type = (char *)get_property(thisdevdn, "device_type", 0);
+				if (device_type && strcmp(device_type, "pci") == 0) {
+					return create_eads_node(thisdevdn);
+				}
+			}
+		}
+		/* ToDo: device not found...probe for it anyway with a fake dn?
+		struct device_node fake_dn;
+		memset(&fake_dn, 0, sizeof(fake_dn));
+		fake_dn.phb = phb;
+		fake_dn.busno = dev->bus->number;
+		fake_dn.devfn = dev->devfn;
+		... now do ppc_md.pcibios_read_config_dword(&fake_dn.....)
+		 ... if ok, alloc a real device_node and dn = real_dn;
+		 */
+	}
+	return dn;
+}
+
+
+/******************************************************************
+ * Actually initialize the phbs.
+ * The buswalk on this phb has not happened yet.
+ ******************************************************************/
+void __init
+pci_devs_phb_init(void)
+{
+	/* This must be done first so the device nodes have valid pci info! */
+	traverse_all_pci_devices(update_dn_pci_info);
+
+	/* Hack for regatta which does not init the bars correctly */
+	traverse_all_pci_devices(write_OF_bars);
+#if 0
+	traverse_all_pci_devices(startBIST);
+	mdelay(5000);
+	traverse_all_pci_devices(checkBIST);
+#endif
+}
+
+
+static void __init
+pci_fixup_bus_sysdata_list(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	struct pci_controller *phb;
+	int newnum;
+
+	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		if (bus->self) {
+			bus->sysdata = bus->self->sysdata;
+			/* Also fixup the bus number on large bus systems to
+			 * include the PHB# in the next byte
+			 */
+			phb = PCI_GET_DN(bus)->phb;
+			if (phb && phb->buid) {
+				newnum = (phb->global_number << 8) | bus->number;
+				bus->number = newnum;
+				sprintf(bus->name, "PCI Bus #%x", bus->number);
+			}
+		}
+		pci_fixup_bus_sysdata_list(&bus->children);
+	}
+}
+
+
+/******************************************************************
+ * Fixup the bus->sysdata ptrs to point to the bus' device_node.
+ * This is done late in pcibios_init().  We do this mostly for
+ * sanity, but pci_dma.c uses these at DMA time so they must be
+ * correct.
+ * To do this we recurse down the bus hierarchy.  Note that PHB's
+ * have bus->self == NULL, but fortunately bus->sysdata is already
+ * correct in this case.
+ ******************************************************************/
+void __init
+pci_fix_bus_sysdata(void)
+{
+	pci_fixup_bus_sysdata_list(&pci_root_buses);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/pmc.c linux/arch/ppc64/kernel/pmc.c
--- linux.orig/arch/ppc64/kernel/pmc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/pmc.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,347 @@
+/*
+ * pmc.c
+ * Copyright (C) 2001 Dave Engebretsen & Mike Corrigan IBM 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
+ */
+
+/* Change Activity:
+ * 2001/06/05 : engebret : Created.
+ * 2002/04/11 : engebret : Add btmalloc code.
+ * End Change Activity 
+ */
+
+#include <asm/proc_fs.h>
+#include <asm/paca.h>
+#include <asm/iSeries/ItLpPaca.h>
+#include <asm/iSeries/ItLpQueue.h>
+#include <asm/processor.h>
+
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <asm/pmc.h>
+#include <asm/uaccess.h>
+#include <asm/naca.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/ppcdebug.h>
+
+struct _pmc_sw pmc_sw_system = {
+	0  
+};
+
+struct _pmc_sw pmc_sw_cpu[NR_CPUS] = {
+	{0 }, 
+};
+
+/*
+ * Provide enough storage for either system level counters or
+ * one cpu's counters.
+ */
+struct _pmc_sw_text pmc_sw_text;
+struct _pmc_hw_text pmc_hw_text;
+
+extern pte_t *find_linux_pte( pgd_t * pgdir, unsigned long ea );
+extern pgd_t *bolted_pgd;
+
+static struct vm_struct *get_btm_area(unsigned long size, unsigned long flags);
+static int local_free_bolted_pages(unsigned long ea, unsigned long num);
+
+extern pgd_t bolted_dir[];
+pgd_t *bolted_pgd  = (pgd_t *)&bolted_dir;
+
+struct vm_struct *btmlist = NULL;
+struct mm_struct btmalloc_mm = {pgd             : bolted_dir,
+                                page_table_lock : SPIN_LOCK_UNLOCKED};
+
+char *
+ppc64_pmc_stab(int file)
+{
+	int  n;
+	unsigned long stab_faults, stab_capacity_castouts, stab_invalidations; 
+	unsigned long i;
+
+	stab_faults = stab_capacity_castouts = stab_invalidations = n = 0;
+
+	if (file == -1) {
+		for (i = 0;  i < smp_num_cpus; i++) {
+			stab_faults += pmc_sw_cpu[i].stab_faults;
+			stab_capacity_castouts += pmc_sw_cpu[i].stab_capacity_castouts;
+			stab_invalidations += pmc_sw_cpu[i].stab_invalidations;
+		}
+		n += sprintf(pmc_sw_text.buffer + n,    
+			     "Faults         0x%lx\n", stab_faults); 
+		n += sprintf(pmc_sw_text.buffer + n, 
+			     "Castouts       0x%lx\n", stab_capacity_castouts); 
+		n += sprintf(pmc_sw_text.buffer + n, 
+			     "Invalidations  0x%lx\n", stab_invalidations); 
+	} else {
+		n += sprintf(pmc_sw_text.buffer + n,
+			     "Faults         0x%lx\n", 
+			     pmc_sw_cpu[file].stab_faults);
+		
+		n += sprintf(pmc_sw_text.buffer + n,   
+			     "Castouts       0x%lx\n", 
+			     pmc_sw_cpu[file].stab_capacity_castouts);
+		
+		n += sprintf(pmc_sw_text.buffer + n,   
+			     "Invalidations  0x%lx\n", 
+			     pmc_sw_cpu[file].stab_invalidations);
+
+		for (i = 0; i < STAB_ENTRY_MAX; i++) {
+			if (pmc_sw_cpu[file].stab_entry_use[i]) {
+				n += sprintf(pmc_sw_text.buffer + n,   
+					     "Entry %02ld       0x%lx\n", i, 
+					     pmc_sw_cpu[file].stab_entry_use[i]);
+			}
+		}
+
+	}
+
+	return(pmc_sw_text.buffer); 
+}
+
+char *
+ppc64_pmc_htab(int file)
+{
+	int  n;
+	unsigned long htab_primary_overflows, htab_capacity_castouts;
+	unsigned long htab_read_to_write_faults; 
+
+	htab_primary_overflows = htab_capacity_castouts = 0;
+	htab_read_to_write_faults = n = 0;
+
+	if (file == -1) {
+		n += sprintf(pmc_sw_text.buffer + n,    
+			     "Primary Overflows  0x%lx\n", 
+			     pmc_sw_system.htab_primary_overflows); 
+		n += sprintf(pmc_sw_text.buffer + n, 
+			     "Castouts           0x%lx\n", 
+			     pmc_sw_system.htab_capacity_castouts); 
+	} else {
+		n += sprintf(pmc_sw_text.buffer + n,
+			     "Primary Overflows  N/A\n");
+
+		n += sprintf(pmc_sw_text.buffer + n,   
+			     "Castouts           N/A\n\n");
+
+	}
+	
+	return(pmc_sw_text.buffer); 
+}
+
+char *
+ppc64_pmc_hw(int file)
+{
+	int  n;
+
+	n = 0;
+	if (file == -1) {
+		n += sprintf(pmc_hw_text.buffer + n, "Not Implemented\n");
+	} else {
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "MMCR0  0x%lx\n", mfspr(MMCR0)); 
+		n += sprintf(pmc_hw_text.buffer + n, 
+			     "MMCR1  0x%lx\n", mfspr(MMCR1)); 
+#if 0
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "MMCRA  0x%lx\n", mfspr(MMCRA)); 
+#endif
+
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "PMC1   0x%lx\n", mfspr(PMC1)); 
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "PMC2   0x%lx\n", mfspr(PMC2)); 
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "PMC3   0x%lx\n", mfspr(PMC3)); 
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "PMC4   0x%lx\n", mfspr(PMC4)); 
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "PMC5   0x%lx\n", mfspr(PMC5)); 
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "PMC6   0x%lx\n", mfspr(PMC6)); 
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "PMC7   0x%lx\n", mfspr(PMC7)); 
+		n += sprintf(pmc_hw_text.buffer + n,    
+			     "PMC8   0x%lx\n", mfspr(PMC8)); 
+	}
+
+	return(pmc_hw_text.buffer); 
+}
+
+/*
+ * Manage allocations of storage which is bolted in the HPT and low fault
+ * overhead in the segment tables. Intended to be used for buffers used 
+ * to collect performance data.  
+ *
+ * Remaining Issues:
+ *   - Power4 is not tested at all, 0xB regions will always be castout of slb
+ *   - On Power3, 0xB00000000 esid is left in the stab for all time,
+ *     other 0xB segments are castout, but not explicitly removed.
+ *   - Error path checking is weak at best, wrong at worst.
+ *
+ * btmalloc - Allocate a buffer which is bolted in the HPT and (eventually)
+ *            the segment table.
+ *
+ * Input : unsigned long size: bytes of storage to allocate.
+ * Return: void * : pointer to the kernal address of the buffer.
+ */
+void* btmalloc (unsigned long size) {
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	unsigned long ea_base, ea;
+	struct vm_struct *area;
+	unsigned long pa, pg_count, page, vsid;
+  
+	size = PAGE_ALIGN(size);
+	if (!size || (size >> PAGE_SHIFT) > num_physpages) return NULL;
+
+	spin_lock(&btmalloc_mm.page_table_lock);
+
+	/* Get a virtual address region in the bolted space */
+	area = get_btm_area(size, 0);
+	if (!area) {
+		spin_unlock(&btmalloc_mm.page_table_lock);
+		return NULL;
+	}
+
+	ea_base = (unsigned long) area->addr;
+	pg_count = (size >> PAGE_SHIFT);
+
+	/* Create a Linux page table entry and an HPTE for each page */
+	for(page = 0; page < pg_count; page++) {
+		pa = get_free_page(GFP_KERNEL) - PAGE_OFFSET; 
+		ea = ea_base + (page * PAGE_SIZE);
+
+		/* Get a pointer to the linux page table entry for this page
+		 * allocating pmd or pte pages along the way as needed.  Note
+		 * that the pmd & pte pages are not themselfs bolted.
+		 */
+		pgdp = pgd_offset_b(ea);
+		pmdp = pmd_alloc(&btmalloc_mm, pgdp, ea);
+		ptep = pte_alloc(&btmalloc_mm, pmdp, ea);
+
+		/* Clear any old hpte and set the new linux pte */
+		set_pte(ptep, mk_pte_phys(pa & PAGE_MASK, PAGE_KERNEL));
+
+		vsid = get_kernel_vsid(ea);
+		build_valid_hpte(vsid, ea, pa, ptep, 
+				  _PAGE_ACCESSED|_PAGE_COHERENT|PP_RWXX, 1);
+	}
+
+	spin_unlock(&btmalloc_mm.page_table_lock);
+	return (void*)ea_base;
+}
+
+/*
+ * Free a range of bolted pages that were allocated with btmalloc
+ */
+void btfree(void *ea) {
+	struct vm_struct **p, *tmp;
+	unsigned long size = 0;
+
+	if ((!ea) || ((PAGE_SIZE-1) & (unsigned long)ea)) {
+		printk(KERN_ERR "Trying to btfree() bad address (%p)\n", ea);
+		return;
+	}
+
+	spin_lock(&btmalloc_mm.page_table_lock);
+
+	/* Scan the bolted memory list for an entry matching
+	 * the address to be freed, get the size (in bytes)
+	 * and free the entry.  The list lock is not dropped
+	 * until the page table entries are removed.
+	 */
+	for(p = &btmlist; (tmp = *p); p = &tmp->next ) {
+		if ( tmp->addr == ea ) {
+			size = tmp->size;
+			break;
+		}
+	}
+
+	/* If no entry found, it is an error */
+	if ( !size ) {
+		printk(KERN_ERR "Trying to btfree() bad address (%p)\n", ea);
+		spin_unlock(&btmalloc_mm.page_table_lock);
+		return;
+	}
+
+	/* Free up the bolted pages and remove the page table entries */
+	if(local_free_bolted_pages((unsigned long)ea, size >> PAGE_SHIFT)) {
+		*p = tmp->next;
+		kfree(tmp);
+	}
+
+	spin_unlock(&btmalloc_mm.page_table_lock);
+}
+
+static int local_free_bolted_pages(unsigned long ea, unsigned long num) {
+	int i;
+	pte_t pte;
+
+	for(i=0; i<num; i++) {
+		pte_t *ptep = find_linux_pte(bolted_pgd, ea);
+		if(!ptep) {
+			panic("free_bolted_pages - page being freed "
+			      "(0x%lx) is not bolted", ea );
+		}
+		pte = *ptep;
+		pte_clear(ptep);
+		__free_pages(pte_page(pte), 0);
+		flush_hash_page(0, ea, ptep); 
+		ea += PAGE_SIZE;
+	}
+	return 1;
+}
+
+/*
+ * get_btm_area
+ *
+ * Get a virtual region in the bolted space
+ */
+static struct vm_struct *get_btm_area(unsigned long size, 
+				      unsigned long flags) {
+	unsigned long addr;
+	struct vm_struct **p, *tmp, *area;
+  
+	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
+	if (!area) return NULL;
+
+	addr = BTMALLOC_START;
+	for (p = &btmlist; (tmp = *p) ; p = &tmp->next) {
+		if (size + addr < (unsigned long) tmp->addr)
+			break;
+		addr = tmp->size + (unsigned long) tmp->addr;
+		if (addr + size > BTMALLOC_END) {
+			kfree(area);
+			return NULL;
+		}
+	}
+
+	if (addr + size > BTMALLOC_END) {
+		kfree(area);
+		return NULL;
+	}
+	area->flags = flags;
+	area->addr = (void *)addr;
+	area->size = size;
+	area->next = *p;
+	*p = area;
+	return area;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ppc-stub.c linux/arch/ppc64/kernel/ppc-stub.c
--- linux.orig/arch/ppc64/kernel/ppc-stub.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ppc-stub.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,739 @@
+/* 
+ * ppc-stub.c:  KGDB support for the Linux kernel.
+ *
+ * adapted from arch/sparc/kernel/sparc-stub.c for the PowerPC
+ * some stuff borrowed from Paul Mackerras' xmon
+ * Copyright (C) 1998 Michael AK Tesch (tesch@cs.wisc.edu)
+ *
+ * Modifications to run under Linux
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * This file originally came from the gdb sources, and the
+ * copyright notices have been retained below.
+ */
+
+/****************************************************************************
+
+		THIS SOFTWARE IS NOT COPYRIGHTED
+
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or its performance and the
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ *  Module name: remcom.c $
+ *  Revision: 1.34 $
+ *  Date: 91/03/09 12:29:49 $
+ *  Contributor:     Lake Stevens Instrument Division$
+ *
+ *  Description:     low level support for gdb debugger. $
+ *
+ *  Considerations:  only works on target hardware $
+ *
+ *  Written by:      Glenn Engel $
+ *  ModuleState:     Experimental $
+ *
+ *  NOTES:           See Below $
+ *
+ *  Modified for SPARC by Stu Grossman, Cygnus Support.
+ *
+ *  This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *    qOffsets      Get section offsets.  Reply is Text=xxx;Data=yyy;Bss=zzz
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ *    bBB..BB	    Set baud rate to BB..BB		   OK or BNN, then sets
+ *							   baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: <two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/system.h>
+#include <asm/signal.h>
+#include <asm/kgdb.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+void breakinst(void);
+
+/*
+ * BUFMAX defines the maximum number of characters in inbound/outbound buffers
+ * at least NUMREGBYTES*2 are needed for register packets
+ */
+#define BUFMAX 2048
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+static int initialized = 0;
+static int kgdb_active = 0;
+static int kgdb_started = 0;
+static u_int fault_jmp_buf[100];
+static int kdebug;
+
+static const char hexchars[]="0123456789abcdef";
+
+/* Place where we save old trap entries for restoration - sparc*/
+/* struct tt_entry kgdb_savettable[256]; */
+/* typedef void (*trapfunc_t)(void); */
+
+#if 0
+/* Install an exception handler for kgdb */
+static void exceptionHandler(int tnum, unsigned int *tfunc)
+{
+	/* We are dorking with a live trap table, all irqs off */
+}
+#endif
+
+int
+kgdb_setjmp(long *buf)
+{
+	asm ("mflr 0; stw 0,0(%0);"
+	     "stw 1,4(%0); stw 2,8(%0);"
+	     "mfcr 0; stw 0,12(%0);"
+	     "stmw 13,16(%0)"
+	     : : "r" (buf));
+	/* XXX should save fp regs as well */
+	return 0;
+}
+void
+kgdb_longjmp(long *buf, int val)
+{
+	if (val == 0)
+		val = 1;
+	asm ("lmw 13,16(%0);"
+	     "lwz 0,12(%0); mtcrf 0x38,0;"
+	     "lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);"
+	     "mtlr 0; mr 3,%1"
+	     : : "r" (buf), "r" (val));
+}
+/* Convert ch from a hex digit to an int */
+static int
+hex(unsigned char ch)
+{
+	if (ch >= 'a' && ch <= 'f')
+		return ch-'a'+10;
+	if (ch >= '0' && ch <= '9')
+		return ch-'0';
+	if (ch >= 'A' && ch <= 'F')
+		return ch-'A'+10;
+	return -1;
+}
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ */
+static unsigned char *
+mem2hex(char *mem, char *buf, int count)
+{
+	unsigned char ch;
+
+	if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
+		debugger_fault_handler = kgdb_fault_handler;
+		while (count-- > 0) {
+			ch = *mem++;
+			*buf++ = hexchars[ch >> 4];
+			*buf++ = hexchars[ch & 0xf];
+		}
+	} else {
+		/* error condition */
+	}
+	debugger_fault_handler = 0;
+	*buf = 0;
+	return buf;
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written.
+*/
+static char *
+hex2mem(char *buf, char *mem, int count)
+{
+	int i;
+	unsigned char ch;
+
+	if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
+		debugger_fault_handler = kgdb_fault_handler;
+		for (i=0; i<count; i++) {
+			ch = hex(*buf++) << 4;
+			ch |= hex(*buf++);
+			*mem++ = ch;
+		}
+		flush_icache_range((int)mem, (int)mem+count);
+	} else {
+		/* error condition */
+	}
+	debugger_fault_handler = 0;
+	return mem;
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+static int
+hexToInt(char **ptr, int *intValue)
+{
+	int numChars = 0;
+	int hexValue;
+
+	*intValue = 0;
+
+	if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
+		debugger_fault_handler = kgdb_fault_handler;
+		while (**ptr) {
+			hexValue = hex(**ptr);
+			if (hexValue < 0)
+				break;
+
+			*intValue = (*intValue << 4) | hexValue;
+			numChars ++;
+
+			(*ptr)++;
+		}
+	} else {
+	     /* error condition */
+	}
+	debugger_fault_handler = 0;
+
+	return (numChars);
+}
+
+/* scan for the sequence $<data>#<checksum>     */
+static void
+getpacket(char *buffer)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	int i;
+	int count;
+	unsigned char ch;
+
+	do {
+		/* wait around for the start character, ignore all other
+		 * characters */
+		while ((ch = (getDebugChar() & 0x7f)) != '$') ;
+
+		checksum = 0;
+		xmitcsum = -1;
+
+		count = 0;
+
+		/* now, read until a # or end of buffer is found */
+		while (count < BUFMAX) {
+			ch = getDebugChar() & 0x7f;
+			if (ch == '#')
+				break;
+			checksum = checksum + ch;
+			buffer[count] = ch;
+			count = count + 1;
+		}
+
+		if (count >= BUFMAX)
+			continue;
+
+		buffer[count] = 0;
+
+		if (ch == '#') {
+			xmitcsum = hex(getDebugChar() & 0x7f) << 4;
+			xmitcsum |= hex(getDebugChar() & 0x7f);
+			if (checksum != xmitcsum)
+				putDebugChar('-');	/* failed checksum */
+			else {
+				putDebugChar('+'); /* successful transfer */
+				/* if a sequence char is present, reply the ID */
+				if (buffer[2] == ':') {
+					putDebugChar(buffer[0]);
+					putDebugChar(buffer[1]);
+					/* remove sequence chars from buffer */
+					count = strlen(buffer);
+					for (i=3; i <= count; i++)
+						buffer[i-3] = buffer[i];
+				}
+			}
+		}
+	} while (checksum != xmitcsum);
+}
+
+/* send the packet in buffer.  */
+static void putpacket(unsigned char *buffer)
+{
+	unsigned char checksum;
+	int count;
+	unsigned char ch, recv;
+
+	/*  $<packet info>#<checksum>. */
+	do {
+		putDebugChar('$');
+		checksum = 0;
+		count = 0;
+
+		while ((ch = buffer[count])) {
+			putDebugChar(ch);
+			checksum += ch;
+			count += 1;
+		}
+
+		putDebugChar('#');
+		putDebugChar(hexchars[checksum >> 4]);
+		putDebugChar(hexchars[checksum & 0xf]);
+		recv = getDebugChar();
+	} while ((recv & 0x7f) != '+');
+}
+
+static void kgdb_flush_cache_all(void)
+{
+	flush_instruction_cache();
+}
+
+
+/* Set up exception handlers for tracing and breakpoints
+ * [could be called kgdb_init()]
+ */
+void set_debug_traps(void)
+{
+#if 0
+	unsigned char c;
+
+	save_and_cli(flags);
+
+	/* In case GDB is started before us, ack any packets (presumably
+	 * "$?#xx") sitting there.
+	 *
+	 * I've found this code causes more problems than it solves,
+	 * so that's why it's commented out.  GDB seems to work fine
+	 * now starting either before or after the kernel   -bwb
+	 */
+
+	while((c = getDebugChar()) != '$');
+	while((c = getDebugChar()) != '#');
+	c = getDebugChar(); /* eat first csum byte */
+	c = getDebugChar(); /* eat second csum byte */
+	putDebugChar('+'); /* ack it */
+#endif
+	debugger = kgdb;
+	debugger_bpt = kgdb_bpt;
+	debugger_sstep = kgdb_sstep;
+	debugger_iabr_match = kgdb_iabr_match;
+	debugger_dabr_match = kgdb_dabr_match;
+
+	initialized = 1;
+}
+
+static void kgdb_fault_handler(struct pt_regs *regs)
+{
+	kgdb_longjmp((long*)fault_jmp_buf, 1);
+}
+
+int kgdb_bpt(struct pt_regs *regs)
+{
+	handle_exception(regs);
+	return 1;
+}
+
+int kgdb_sstep(struct pt_regs *regs)
+{
+	handle_exception(regs);
+	return 1;
+}
+
+void kgdb(struct pt_regs *regs)
+{
+	handle_exception(regs);
+}
+
+int kgdb_iabr_match(struct pt_regs *regs)
+{
+	printk("kgdb doesn't support iabr, what?!?\n");
+	handle_exception(regs);
+	return 1;
+}
+
+int kgdb_dabr_match(struct pt_regs *regs)
+{
+	printk("kgdb doesn't support dabr, what?!?\n");
+	handle_exception(regs);
+	return 1;
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+/*
+ * This table contains the mapping between PowerPC hardware trap types, and
+ * signals, which are primarily what GDB understands.
+ */
+static struct hard_trap_info
+{
+	unsigned int tt;		/* Trap type code for powerpc */
+	unsigned char signo;		/* Signal that we map this trap into */
+} hard_trap_info[] = {
+	{ 0x200, SIGSEGV },			/* machine check */
+	{ 0x300, SIGSEGV },			/* address error (store) */
+	{ 0x400, SIGBUS },			/* instruction bus error */
+	{ 0x500, SIGINT },			/* interrupt */
+	{ 0x600, SIGBUS },			/* alingment */
+	{ 0x700, SIGTRAP },			/* breakpoint trap */
+	{ 0x800, SIGFPE },			/* fpu unavail */
+	{ 0x900, SIGALRM },			/* decrementer */
+	{ 0xa00, SIGILL },			/* reserved */
+	{ 0xb00, SIGILL },			/* reserved */
+	{ 0xc00, SIGCHLD },			/* syscall */
+	{ 0xd00, SIGTRAP },			/* single-step/watch */
+	{ 0xe00, SIGFPE },			/* fp assist */
+	{ 0, 0}				/* Must be last */
+};
+
+static int computeSignal(unsigned int tt)
+{
+	struct hard_trap_info *ht;
+
+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+		if (ht->tt == tt)
+			return ht->signo;
+
+	return SIGHUP;         /* default for things we don't know about */
+}
+
+#define PC_REGNUM 64
+#define SP_REGNUM 1
+
+/*
+ * This function does all command processing for interfacing to gdb.
+ */
+static void
+handle_exception (struct pt_regs *regs)
+{
+	int sigval;
+	int addr;
+	int length;
+	char *ptr;
+	unsigned long msr;
+
+	if (debugger_fault_handler) {
+		debugger_fault_handler(regs);
+		panic("kgdb longjump failed!\n");
+	}
+	if (kgdb_active) {
+		printk("interrupt while in kgdb, returning\n");
+		return;
+	}
+	kgdb_active = 1;
+	kgdb_started = 1;
+
+#ifdef KGDB_DEBUG
+	printk("kgdb: entering handle_exception; trap [0x%x]\n",
+	       (unsigned int)regs->trap);
+#endif
+
+	kgdb_interruptible(0);
+	lock_kernel();
+	msr = get_msr();
+	set_msr(msr & ~MSR_EE);	/* disable interrupts */
+
+	if (regs->nip == (unsigned long)breakinst) {
+		/* Skip over breakpoint trap insn */
+		regs->nip += 4;
+	}
+
+	/* reply to host that an exception has occurred */
+	sigval = computeSignal(regs->trap);
+	ptr = remcomOutBuffer;
+
+#if 0
+	*ptr++ = 'S';
+	*ptr++ = hexchars[sigval >> 4];
+	*ptr++ = hexchars[sigval & 0xf];
+#else
+	*ptr++ = 'T';
+	*ptr++ = hexchars[sigval >> 4];
+	*ptr++ = hexchars[sigval & 0xf];
+	*ptr++ = hexchars[PC_REGNUM >> 4];
+	*ptr++ = hexchars[PC_REGNUM & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex((char *)&regs->nip, ptr, 4);
+	*ptr++ = ';';
+	*ptr++ = hexchars[SP_REGNUM >> 4];
+	*ptr++ = hexchars[SP_REGNUM & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex(((char *)&regs) + SP_REGNUM*4, ptr, 4);
+	*ptr++ = ';';
+#endif
+
+	*ptr++ = 0;
+
+	putpacket(remcomOutBuffer);
+
+	/* XXX We may want to add some features dealing with poking the
+	 * XXX page tables, ... (look at sparc-stub.c for more info)
+	 * XXX also required hacking to the gdb sources directly...
+	 */
+
+	while (1) {
+		remcomOutBuffer[0] = 0;
+
+		getpacket(remcomInBuffer);
+		switch (remcomInBuffer[0]) {
+		case '?':               /* report most recent signal */
+			remcomOutBuffer[0] = 'S';
+			remcomOutBuffer[1] = hexchars[sigval >> 4];
+			remcomOutBuffer[2] = hexchars[sigval & 0xf];
+			remcomOutBuffer[3] = 0;
+			break;
+#if 0
+		case 'q': /* this screws up gdb for some reason...*/
+		{
+			extern long _start, sdata, __bss_start;
+
+			ptr = &remcomInBuffer[1];
+			if (strncmp(ptr, "Offsets", 7) != 0)
+				break;
+
+			ptr = remcomOutBuffer;
+			sprintf(ptr, "Text=%8.8x;Data=%8.8x;Bss=%8.8x",
+				&_start, &sdata, &__bss_start);
+			break;
+		}
+#endif
+		case 'd':
+			/* toggle debug flag */
+			kdebug ^= 1;
+			break;
+
+		case 'g':	/* return the value of the CPU registers.
+				 * some of them are non-PowerPC names :(
+				 * they are stored in gdb like:
+				 * struct {
+				 *     u32 gpr[32];
+				 *     f64 fpr[32];
+				 *     u32 pc, ps, cnd, lr; (ps=msr)
+				 *     u32 cnt, xer, mq;
+				 * }
+				 */
+		{
+			int i;
+			ptr = remcomOutBuffer;
+			/* General Purpose Regs */
+			ptr = mem2hex((char *)regs, ptr, 32 * 4);
+			/* Floating Point Regs - FIXME */
+			/*ptr = mem2hex((char *), ptr, 32 * 8);*/
+			for(i=0; i<(32*8*2); i++) { /* 2chars/byte */
+				ptr[i] = '0';
+			}
+			ptr += 32*8*2;
+			/* pc, msr, cr, lr, ctr, xer, (mq is unused) */
+			ptr = mem2hex((char *)&regs->nip, ptr, 4);
+			ptr = mem2hex((char *)&regs->msr, ptr, 4);
+			ptr = mem2hex((char *)&regs->ccr, ptr, 4);
+			ptr = mem2hex((char *)&regs->link, ptr, 4);
+			ptr = mem2hex((char *)&regs->ctr, ptr, 4);
+			ptr = mem2hex((char *)&regs->xer, ptr, 4);
+		}
+			break;
+
+		case 'G':   /* set the value of the CPU registers */
+		{
+			ptr = &remcomInBuffer[1];
+
+			/*
+			 * If the stack pointer has moved, you should pray.
+			 * (cause only god can help you).
+			 */
+
+			/* General Purpose Regs */
+			hex2mem(ptr, (char *)regs, 32 * 4);
+
+			/* Floating Point Regs - FIXME?? */
+			/*ptr = hex2mem(ptr, ??, 32 * 8);*/
+			ptr += 32*8*2;
+
+			/* pc, msr, cr, lr, ctr, xer, (mq is unused) */
+			ptr = hex2mem(ptr, (char *)&regs->nip, 4);
+			ptr = hex2mem(ptr, (char *)&regs->msr, 4);
+			ptr = hex2mem(ptr, (char *)&regs->ccr, 4);
+			ptr = hex2mem(ptr, (char *)&regs->link, 4);
+			ptr = hex2mem(ptr, (char *)&regs->ctr, 4);
+			ptr = hex2mem(ptr, (char *)&regs->xer, 4);
+
+			strcpy(remcomOutBuffer,"OK");
+		}
+			break;
+		case 'H':
+			/* don't do anything, yet, just acknowledge */
+			hexToInt(&ptr, &addr);
+			strcpy(remcomOutBuffer,"OK");
+			break;
+
+		case 'm':	/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+				/* Try to read %x,%x.  */
+
+			ptr = &remcomInBuffer[1];
+
+			if (hexToInt(&ptr, &addr)
+			    && *ptr++ == ','
+			    && hexToInt(&ptr, &length))	{
+				if (mem2hex((char *)addr, remcomOutBuffer,length))
+					break;
+				strcpy (remcomOutBuffer, "E03");
+			} else {
+				strcpy(remcomOutBuffer,"E01");
+			}
+			break;
+
+		case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+			/* Try to read '%x,%x:'.  */
+
+			ptr = &remcomInBuffer[1];
+
+			if (hexToInt(&ptr, &addr)
+			    && *ptr++ == ','
+			    && hexToInt(&ptr, &length)
+			    && *ptr++ == ':') {
+				if (hex2mem(ptr, (char *)addr, length)) {
+					strcpy(remcomOutBuffer, "OK");
+				} else {
+					strcpy(remcomOutBuffer, "E03");
+				}
+				flush_icache_range(addr, addr+length);
+			} else {
+				strcpy(remcomOutBuffer, "E02");
+			}
+			break;
+
+
+		case 'k':    /* kill the program, actually just continue */
+		case 'c':    /* cAA..AA  Continue; address AA..AA optional */
+			/* try to read optional parameter, pc unchanged if no parm */
+
+			ptr = &remcomInBuffer[1];
+			if (hexToInt(&ptr, &addr)) {
+				regs->nip = addr;
+			}
+
+/* Need to flush the instruction cache here, as we may have deposited a
+ * breakpoint, and the icache probably has no way of knowing that a data ref to
+ * some location may have changed something that is in the instruction cache.
+ */
+			kgdb_flush_cache_all();
+			set_msr(msr);
+			kgdb_interruptible(1);
+			unlock_kernel();
+			kgdb_active = 0;
+			return;
+
+		case 's':
+			kgdb_flush_cache_all();
+			regs->msr |= MSR_SE;
+#if 0
+			set_msr(msr | MSR_SE);
+#endif
+			unlock_kernel();
+			kgdb_active = 0;
+			return;
+
+		case 'r':		/* Reset (if user process..exit ???)*/
+			panic("kgdb reset.");
+			break;
+		}			/* switch */
+		if (remcomOutBuffer[0] && kdebug) {
+			printk("remcomInBuffer: %s\n", remcomInBuffer);
+			printk("remcomOutBuffer: %s\n", remcomOutBuffer);
+		}
+		/* reply to the request */
+		putpacket(remcomOutBuffer);
+	} /* while(1) */
+}
+
+/* This function will generate a breakpoint exception.  It is used at the
+   beginning of a program to sync up with a debugger and can be used
+   otherwise as a quick means to stop program execution and "break" into
+   the debugger. */
+
+void
+breakpoint(void)
+{
+	if (!initialized) {
+		printk("breakpoint() called b4 kgdb init\n");
+		return;
+	}
+
+	asm("	.globl breakinst
+	     breakinst: .long 0x7d821008
+            ");
+}
+
+/* Output string in GDB O-packet format if GDB has connected. If nothing
+   output, returns 0 (caller must then handle output). */
+int
+kgdb_output_string (const char* s, unsigned int count)
+{
+	char buffer[512];
+
+        if (!kgdb_started)
+            return 0;
+
+	count = (count <= (sizeof(buffer) / 2 - 2)) 
+		? count : (sizeof(buffer) / 2 - 2);
+
+	buffer[0] = 'O';
+	mem2hex (s, &buffer[1], count);
+	putpacket(buffer);
+
+        return 1;
+ }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ppc_asm.h linux/arch/ppc64/kernel/ppc_asm.h
--- linux.orig/arch/ppc64/kernel/ppc_asm.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ppc_asm.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,117 @@
+/*
+ * arch/ppc64/kernel/ppc_asm.h
+ *
+ * Definitions used by various bits of low-level assembly code on PowerPC.
+ *
+ * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+
+#include <asm/ppc_asm.tmpl>
+#include "ppc_defs.h"
+
+/*
+ * Macros for storing registers into and loading registers from
+ * exception frames.
+ */
+#define SAVE_GPR(n, base)	std	n,GPR0+8*(n)(base)
+#define SAVE_2GPRS(n, base)	SAVE_GPR(n, base); SAVE_GPR(n+1, base)
+#define SAVE_4GPRS(n, base)	SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
+#define SAVE_8GPRS(n, base)	SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
+#define SAVE_10GPRS(n, base)	SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
+#define REST_GPR(n, base)	ld	n,GPR0+8*(n)(base)
+#define REST_2GPRS(n, base)	REST_GPR(n, base); REST_GPR(n+1, base)
+#define REST_4GPRS(n, base)	REST_2GPRS(n, base); REST_2GPRS(n+2, base)
+#define REST_8GPRS(n, base)	REST_4GPRS(n, base); REST_4GPRS(n+4, base)
+#define REST_10GPRS(n, base)	REST_8GPRS(n, base); REST_2GPRS(n+8, base)
+
+#define SAVE_FPR(n, base)	stfd	n,THREAD_FPR0+8*(n)(base)
+#define SAVE_2FPRS(n, base)	SAVE_FPR(n, base); SAVE_FPR(n+1, base)
+#define SAVE_4FPRS(n, base)	SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
+#define SAVE_8FPRS(n, base)	SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
+#define SAVE_16FPRS(n, base)	SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
+#define SAVE_32FPRS(n, base)	SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
+#define REST_FPR(n, base)	lfd	n,THREAD_FPR0+8*(n)(base)
+#define REST_2FPRS(n, base)	REST_FPR(n, base); REST_FPR(n+1, base)
+#define REST_4FPRS(n, base)	REST_2FPRS(n, base); REST_2FPRS(n+2, base)
+#define REST_8FPRS(n, base)	REST_4FPRS(n, base); REST_4FPRS(n+4, base)
+#define REST_16FPRS(n, base)	REST_8FPRS(n, base); REST_8FPRS(n+8, base)
+#define REST_32FPRS(n, base)	REST_16FPRS(n, base); REST_16FPRS(n+16, base)
+
+#define CHECKANYINT(ra,rb)			\
+	mfspr	rb,SPRG3;		/* Get Paca address */\
+	ld	ra,PACALPPACA+LPPACAANYINT(rb); /* Get pending interrupt flags */\
+	cmpldi	0,ra,0;
+
+/* Macros to adjust thread priority for Iseries hardware multithreading */
+#define HMT_LOW		or 1,1,1
+#define HMT_MEDIUM	or 2,2,2
+#define HMT_HIGH	or 3,3,3
+
+/* Insert the high 32 bits of the MSR into what will be the new
+   MSR (via SRR1 and rfid)  This preserves the MSR.SF and MSR.ISF
+   bits. */
+
+#define FIX_SRR1(ra, rb)	\
+	mr	rb,ra;		\
+	mfmsr	ra;		\
+	rldimi	ra,rb,0,32
+
+#define CLR_TOP32(r)	rlwinm	(r),(r),0,0,31	/* clear top 32 bits */
+
+/* 
+ * LOADADDR( rn, name )
+ *   loads the address of 'name' into 'rn'
+ *
+ * LOADBASE( rn, name )
+ *   loads the address (less the low 16 bits) of 'name' into 'rn'
+ *   suitable for base+disp addressing
+ */
+#define LOADADDR(rn,name) \
+	lis	rn,name##@highest;	\
+	ori	rn,rn,name##@higher;	\
+	rldicr	rn,rn,32,31;		\
+	oris	rn,rn,name##@h;		\
+	ori	rn,rn,name##@l
+
+#define LOADBASE(rn,name) \
+	lis	rn,name@highest;	\
+	ori	rn,rn,name@higher;	\
+	rldicr	rn,rn,32,31;		\
+	oris	rn,rn,name@ha
+
+
+#define SET_REG_TO_CONST(reg, value)	         	\
+	lis     reg,(((value)>>48)&0xFFFF);             \
+	ori     reg,reg,(((value)>>32)&0xFFFF);         \
+	rldicr  reg,reg,32,31;                          \
+	oris    reg,reg,(((value)>>16)&0xFFFF);         \
+	ori     reg,reg,((value)&0xFFFF);
+
+#define SET_REG_TO_LABEL(reg, label)	         	\
+	lis     reg,(label)@highest;                    \
+	ori     reg,reg,(label)@higher;                 \
+	rldicr  reg,reg,32,31;                          \
+	oris    reg,reg,(label)@h;                      \
+	ori     reg,reg,(label)@l;
+
+
+/* PPPBBB - DRENG  If KERNELBASE is always 0xC0...,
+ * Then we can easily do this with one asm insn. -Peter
+ */
+#define tophys(rd,rs)                           \
+        lis     rd,((KERNELBASE>>48)&0xFFFF);   \
+        rldicr  rd,rd,32,31;                    \
+        sub     rd,rs,rd
+
+#define tovirt(rd,rs)                           \
+        lis     rd,((KERNELBASE>>48)&0xFFFF);   \
+        rldicr  rd,rd,32,31;                    \
+        add     rd,rs,rd
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ppc_defs.head linux/arch/ppc64/kernel/ppc_defs.head
--- linux.orig/arch/ppc64/kernel/ppc_defs.head	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ppc_defs.head	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,3 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ppc_ksyms.c linux/arch/ppc64/kernel/ppc_ksyms.c
--- linux.orig/arch/ppc64/kernel/ppc_ksyms.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ppc_ksyms.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,290 @@
+/* 
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <linux/elfcore.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/vt_kern.h>
+#include <linux/spinlock.h>
+#include <linux/console.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include <asm/page.h>
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/ide.h>
+#include <asm/ide.h>
+#include <asm/atomic.h>
+#include <asm/bitops.h>
+#include <asm/checksum.h>
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/pci-bridge.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/hw_irq.h>
+#include <asm/abs_addr.h>
+#ifdef CONFIG_SMP
+#include <asm/smplock.h>
+#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC_ISERIES
+#include <asm/iSeries/iSeries_pci.h>
+#include <asm/iSeries/iSeries_proc.h>
+#include <asm/iSeries/mf.h>
+#include <asm/iSeries/HvLpEvent.h>
+#include <asm/iSeries/HvLpConfig.h>
+#endif
+
+/* Tell string.h we don't want memcpy etc. as cpp defines */
+#define EXPORT_SYMTAB_STROPS
+
+extern void syscall_trace(void);
+extern void do_IRQ(struct pt_regs *regs, int isfake);
+extern void SystemResetException(struct pt_regs *regs);
+extern void MachineCheckException(struct pt_regs *regs);
+extern void AlignmentException(struct pt_regs *regs);
+extern void ProgramCheckException(struct pt_regs *regs);
+extern void SingleStepException(struct pt_regs *regs);
+extern int sys_sigreturn(struct pt_regs *regs);
+extern int do_signal(sigset_t *, struct pt_regs *);
+extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
+extern int unregister_ioctl32_conversion(unsigned int cmd);
+
+long long __ashrdi3(long long, int);
+long long __ashldi3(long long, int);
+long long __lshrdi3(long long, int);
+int abs(int);
+
+extern struct pci_dev * iSeries_veth_dev;
+extern struct pci_dev * iSeries_vio_dev;
+
+EXPORT_SYMBOL(do_signal);
+EXPORT_SYMBOL(syscall_trace);
+EXPORT_SYMBOL(do_IRQ);
+EXPORT_SYMBOL(SystemResetException);
+EXPORT_SYMBOL(MachineCheckException);
+EXPORT_SYMBOL(AlignmentException);
+EXPORT_SYMBOL(ProgramCheckException);
+EXPORT_SYMBOL(SingleStepException);
+EXPORT_SYMBOL(sys_sigreturn);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(disable_irq_nosync);
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(kernel_flag);
+EXPORT_SYMBOL(synchronize_irq);
+EXPORT_SYMBOL(smp_num_cpus);
+#endif /* CONFIG_SMP */
+
+EXPORT_SYMBOL(register_ioctl32_conversion);
+EXPORT_SYMBOL(unregister_ioctl32_conversion);
+
+EXPORT_SYMBOL(isa_io_base);
+EXPORT_SYMBOL(isa_mem_base);
+EXPORT_SYMBOL(pci_io_base);
+EXPORT_SYMBOL(pci_dram_offset);
+
+EXPORT_SYMBOL(find_next_zero_bit);
+
+EXPORT_SYMBOL(strcpy);
+EXPORT_SYMBOL(strncpy);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strncat);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strtok);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+
+EXPORT_SYMBOL(__down_interruptible);
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(naca);
+EXPORT_SYMBOL(__down);
+
+/* EXPORT_SYMBOL(csum_partial); already in net/netsyms.c */
+EXPORT_SYMBOL(csum_partial_copy_generic);
+EXPORT_SYMBOL(ip_fast_csum);
+EXPORT_SYMBOL(csum_tcpudp_magic);
+
+EXPORT_SYMBOL(__copy_tofrom_user);
+EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(__strncpy_from_user);
+EXPORT_SYMBOL(__strnlen_user);
+
+/*
+EXPORT_SYMBOL(inb);
+EXPORT_SYMBOL(inw);
+EXPORT_SYMBOL(inl);
+EXPORT_SYMBOL(outb);
+EXPORT_SYMBOL(outw);
+EXPORT_SYMBOL(outl);
+EXPORT_SYMBOL(outsl);*/
+
+#ifdef CONFIG_MSCHUNKS
+EXPORT_SYMBOL(msChunks);
+#endif
+EXPORT_SYMBOL(reloc_offset);
+
+#ifdef CONFIG_PPC_ISERIES
+EXPORT_SYMBOL(iSeries_proc_callback);
+EXPORT_SYMBOL(HvCall0);
+EXPORT_SYMBOL(HvCall1);
+EXPORT_SYMBOL(HvCall2);
+EXPORT_SYMBOL(HvCall3);
+EXPORT_SYMBOL(HvCall4);
+EXPORT_SYMBOL(HvCall5);
+EXPORT_SYMBOL(HvCall6);
+EXPORT_SYMBOL(HvCall7);
+EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
+EXPORT_SYMBOL(HvLpEvent_registerHandler);
+EXPORT_SYMBOL(mf_allocateLpEvents);
+EXPORT_SYMBOL(mf_deallocateLpEvents);
+EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline);
+#endif
+
+EXPORT_SYMBOL(_insb);
+EXPORT_SYMBOL(_outsb);
+EXPORT_SYMBOL(_insw);
+EXPORT_SYMBOL(_outsw);
+EXPORT_SYMBOL(_insl);
+EXPORT_SYMBOL(_outsl);
+EXPORT_SYMBOL(_insw_ns);
+EXPORT_SYMBOL(_outsw_ns);
+EXPORT_SYMBOL(_insl_ns);
+EXPORT_SYMBOL(_outsl_ns);
+EXPORT_SYMBOL(ioremap);
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+
+#ifdef CONFIG_PCI
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_map_single);
+EXPORT_SYMBOL(pci_unmap_single);
+EXPORT_SYMBOL(pci_map_sg);
+EXPORT_SYMBOL(pci_unmap_sg);
+#ifdef CONFIG_PPC_ISERIES
+EXPORT_SYMBOL(iSeries_Write_Long);
+EXPORT_SYMBOL(iSeries_GetLocationData);
+EXPORT_SYMBOL(iSeries_Read_Long);
+EXPORT_SYMBOL(iSeries_Device_ToggleReset);
+EXPORT_SYMBOL(iSeries_Write_Word);
+EXPORT_SYMBOL(iSeries_memcpy_fromio);
+EXPORT_SYMBOL(iSeries_Read_Word);
+EXPORT_SYMBOL(iSeries_Read_Byte);
+EXPORT_SYMBOL(iSeries_Write_Byte);
+#endif /* CONFIG_PPC_ISERIES */
+#ifndef CONFIG_PPC_ISERIES
+EXPORT_SYMBOL(eeh_check_failure);
+EXPORT_SYMBOL(eeh_total_mmio_ffs);
+#endif /* CONFIG_PPC_ISERIES */
+#endif /* CONFIG_PCI */
+
+EXPORT_SYMBOL(iSeries_veth_dev);
+EXPORT_SYMBOL(iSeries_vio_dev);
+
+EXPORT_SYMBOL(start_thread);
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(flush_instruction_cache);
+EXPORT_SYMBOL(_get_PVR);
+EXPORT_SYMBOL(giveup_fpu);
+EXPORT_SYMBOL(enable_kernel_fp);
+EXPORT_SYMBOL(flush_icache_range);
+EXPORT_SYMBOL(flush_icache_user_range);
+EXPORT_SYMBOL(flush_icache_page);
+EXPORT_SYMBOL(flush_dcache_page);
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(__global_cli);
+EXPORT_SYMBOL(__global_sti);
+EXPORT_SYMBOL(__global_save_flags);
+EXPORT_SYMBOL(__global_restore_flags);
+#ifdef CONFIG_PPC_ISERIES
+EXPORT_SYMBOL(__no_use_restore_flags);
+EXPORT_SYMBOL(__no_use_save_flags);
+EXPORT_SYMBOL(__no_use_sti);
+EXPORT_SYMBOL(__no_use_cli);
+#endif
+#endif
+
+EXPORT_SYMBOL(ppc_md);
+
+EXPORT_SYMBOL(find_devices);
+EXPORT_SYMBOL(find_type_devices);
+EXPORT_SYMBOL(find_compatible_devices);
+EXPORT_SYMBOL(find_path_device);
+EXPORT_SYMBOL(device_is_compatible);
+EXPORT_SYMBOL(machine_is_compatible);
+EXPORT_SYMBOL(find_all_nodes);
+EXPORT_SYMBOL(get_property);
+
+#ifndef CONFIG_PPC_ISERIES
+EXPORT_SYMBOL(kd_mksound);
+#endif
+
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(memcmp);
+
+EXPORT_SYMBOL(abs);
+
+#ifdef CONFIG_VT
+EXPORT_SYMBOL(screen_info);
+#endif
+
+EXPORT_SYMBOL(timer_interrupt);
+EXPORT_SYMBOL(irq_desc);
+void ppc_irq_dispatch_handler(struct pt_regs *, int);
+EXPORT_SYMBOL(ppc_irq_dispatch_handler);
+EXPORT_SYMBOL(get_wchan);
+EXPORT_SYMBOL(console_drivers);
+#ifdef CONFIG_XMON
+EXPORT_SYMBOL(xmon);
+#endif
+
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
+extern void (*debugger)(struct pt_regs *regs);
+extern int (*debugger_bpt)(struct pt_regs *regs);
+extern int (*debugger_sstep)(struct pt_regs *regs);
+extern int (*debugger_iabr_match)(struct pt_regs *regs);
+extern int (*debugger_dabr_match)(struct pt_regs *regs);
+extern void (*debugger_fault_handler)(struct pt_regs *regs);
+
+EXPORT_SYMBOL(debugger);
+EXPORT_SYMBOL(debugger_bpt);
+EXPORT_SYMBOL(debugger_sstep);
+EXPORT_SYMBOL(debugger_iabr_match);
+EXPORT_SYMBOL(debugger_dabr_match);
+EXPORT_SYMBOL(debugger_fault_handler);
+#endif
+
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(atomic_dec_and_lock);
+#endif
+
+EXPORT_SYMBOL(tb_ticks_per_usec);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/proc_pcifr.c linux/arch/ppc64/kernel/proc_pcifr.c
--- linux.orig/arch/ppc64/kernel/proc_pcifr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/proc_pcifr.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,251 @@
+/************************************************************************/
+/* File pcifr_proc.c created by Allan Trautman on Thu Aug  2 2001.      */
+/************************************************************************/
+/* Supports the ../proc/ppc64/pcifr for the pci flight recorder.        */
+/* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
+/*                                                                      */
+/* 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 <stdarg.h>
+#include <linux/kernel.h>
+
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <asm/time.h>
+
+#include <linux/pci.h>
+#include <asm/pci-bridge.h>
+#include <linux/netdevice.h>
+
+#include <asm/flight_recorder.h>
+#include <asm/iSeries/iSeries_pci.h>
+#include "pci.h"
+
+void pci_Fr_TestCode(void);
+
+static spinlock_t proc_pcifr_lock;
+struct flightRecorder* PciFr = NULL;
+
+extern long Pci_Interrupt_Count;
+extern long Pci_Event_Count;
+extern long Pci_Io_Read_Count;
+extern long Pci_Io_Write_Count;
+extern long Pci_Cfg_Read_Count;
+extern long Pci_Cfg_Write_Count;
+extern long Pci_Error_Count;
+
+/************************************************************************/
+/* Forward declares.                                                    */
+/************************************************************************/
+static struct proc_dir_entry *pciFr_proc_root = NULL;
+int proc_pciFr_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data);
+int proc_pciFr_write_proc(struct file *file, const char *buffer, unsigned long count, void *data);
+
+static struct proc_dir_entry *pciDev_proc_root = NULL;
+int proc_pciDev_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data);
+int proc_pciDev_write_proc(struct file *file, const char *buffer, unsigned long count, void *data);
+
+/************************************************************************/
+/* Create entry ../proc/ppc64/pcifr                                     */
+/************************************************************************/
+void proc_pciFr_init(struct proc_dir_entry *proc_ppc64_root)
+{
+	if (proc_ppc64_root == NULL) return;
+
+	/* Read = User,Group,Other, Write User */
+	printk("PCI: Creating ../proc/ppc64/pcifr \n");
+	spin_lock(&proc_pcifr_lock);
+	pciFr_proc_root = create_proc_entry("pcifr", S_IFREG | S_IRUGO | S_IWUSR, proc_ppc64_root);
+	spin_unlock(&proc_pcifr_lock);
+
+	if (pciFr_proc_root == NULL) return;
+
+	pciFr_proc_root->nlink = 1;
+	pciFr_proc_root->data = (void *)0;
+	pciFr_proc_root->read_proc  = proc_pciFr_read_proc;
+	pciFr_proc_root->write_proc = proc_pciFr_write_proc;
+
+	PciFr = alloc_Flight_Recorder(NULL,"PciFr", 4096);
+
+	printk("PCI: Creating ../proc/ppc64/pci \n");
+	spin_lock(&proc_pcifr_lock);
+	pciDev_proc_root = create_proc_entry("pci", S_IFREG | S_IRUGO | S_IWUSR, proc_ppc64_root);
+	spin_unlock(&proc_pcifr_lock);
+
+	if (pciDev_proc_root == NULL) return;
+
+	pciDev_proc_root->nlink = 1;
+	pciDev_proc_root->data = (void *)0;
+	pciDev_proc_root->read_proc  = proc_pciDev_read_proc;
+	pciDev_proc_root->write_proc = proc_pciDev_write_proc;
+}
+
+static	char* PciFrBuffer = NULL;
+static  int   PciFrBufLen = 0;
+static  char* PciFrBufPtr = NULL;
+static  int   PciFileSize = 0;
+
+/*******************************************************************************/
+/* Read function for ../proc/ppc64/pcifr.                                      */
+/*  -> Function grabs a copy of the pcifr(could change) and writes the data to */
+/*     the caller.  Note, it may not all fit in the buffer.  The function      */
+/*     handles the repeated calls until all the data has been read.            */
+/* Tip:                                                                        */
+/* ./fs/proc/generic.c::proc_file_read is the caller of this routine.          */
+/*******************************************************************************/
+int proc_pciFr_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	/* First call will have offset 0, get snapshot the pcifr          */
+	if( off == 0) {
+		spin_lock(&proc_pcifr_lock);
+		PciFrBuffer = (char*)kmalloc(PciFr->Size, GFP_KERNEL);
+		PciFrBufLen = fr_Dump(PciFr,PciFrBuffer, PciFr->Size);
+		PciFrBufPtr = PciFrBuffer;
+		PciFileSize = 0;
+	}
+	/* For the persistant folks, set eof and return zero length.      */
+	else if( PciFrBuffer == NULL) {
+		*eof = 1;
+		return 0;
+	}
+	/* - If there is more data than will fit, move what will fit.     */
+	/* - The rest will get moved on the next call.                    */
+	int MoveSize = PciFrBufLen;
+	if( MoveSize > count) MoveSize = count;
+
+	/* Move the data info the FileSystem buffer.                      */
+	memcpy(page+off,PciFrBufPtr,MoveSize);
+	PciFrBufPtr += MoveSize;
+	PciFileSize += MoveSize;
+	PciFrBufLen -= MoveSize;
+
+	/* If all the data has been moved, free the buffer and set EOF.   */
+	if( PciFrBufLen == 0) {
+		kfree(PciFrBuffer);
+		PciFrBuffer = NULL;
+		spin_unlock(&proc_pcifr_lock);
+		*eof = 1;
+	}
+	return PciFileSize;
+}
+/*******************************************************************************/
+/* Gets called when client writes to ../proc/ppc64/pcifr                       */
+/*******************************************************************************/
+int proc_pciFr_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	return count;
+}
+static  spinlock_t ProcBufferLock;
+static	char* ProcBuffer   = NULL;
+static  int   ProcBufSize  = 0;
+static  char* ProcBufPtr   = NULL;
+static  int   ProcFileSize = 0;
+
+/*******************************************************************************/
+/* Build Device Buffer for /proc/ppc64/pci                                     */
+/*******************************************************************************/
+static int build_PciDev_Buffer(int BufferSize) 
+{
+	ProcBuffer  = (char*)kmalloc(BufferSize, GFP_KERNEL);
+	ProcBufPtr  = ProcBuffer;
+
+	int BufLen  = 0;
+
+	BufLen += sprintf(ProcBuffer+BufLen,"Pci I/O Reads. %8ld  ",Pci_Io_Read_Count);
+	BufLen += sprintf(ProcBuffer+BufLen,"Pci I/O Writes %8ld\n",Pci_Io_Write_Count);
+
+	BufLen += sprintf(ProcBuffer+BufLen,"Pci Cfg Reads. %8ld  ",Pci_Cfg_Read_Count);
+	BufLen += sprintf(ProcBuffer+BufLen,"Pci Cfg Writes %8ld\n",Pci_Cfg_Write_Count);
+
+	BufLen += sprintf(ProcBuffer+BufLen,"Pci I/O Errors %8ld\n",Pci_Error_Count);
+	BufLen += sprintf(ProcBuffer+BufLen,"\n");
+
+	/***************************************************************************/
+	/* List the devices                                                        */
+	/***************************************************************************/
+	struct pci_dev*    PciDev;		    /* Device pointer              */
+	struct net_device* dev;		            /* net_device pointer          */
+	int    DeviceCount  = 0;
+	pci_for_each_dev(PciDev) {
+		if ( BufLen > BufferSize-128) {    /* Room for another line?       */
+			BufLen +=sprintf(ProcBuffer+BufLen,"Buffer Full\n");
+			break;
+		}
+		if( PCI_SLOT(PciDev->devfn) != 0) {
+			++DeviceCount;
+			BufLen += sprintf(ProcBuffer+BufLen,"%3d. ",DeviceCount);
+			if ( PciDev->sysdata != NULL ) {
+				BufLen += format_device_location(PciDev,ProcBuffer+BufLen,128);
+			}
+			else {
+				BufLen += sprintf(ProcBuffer+BufLen,"No Device Node!\n");
+			}
+			BufLen += sprintf(ProcBuffer+BufLen,"\n");
+
+			/* look for the net devices out */
+			for (dev = dev_base; dev != NULL; dev = dev->next) 	{
+				if (dev->base_addr == PciDev->resource[0].start ) {
+					BufLen += sprintf(ProcBuffer+BufLen, "     - Net device: %s\n", dev->name);
+					break;
+				} /* if */
+			} /* for */
+		} /* if(PCI_SLOT(PciDev->devfn) != 0)  */
+	}
+	return BufLen;
+}
+/*******************************************************************************/
+/* Get called when client reads the ../proc/ppc64/pcifr.                       */
+/*******************************************************************************/
+int proc_pciDev_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	/* First call will have offset 0                                  */
+	if( off == 0) {
+		spin_lock(&ProcBufferLock);
+		ProcBufSize  = build_PciDev_Buffer(4096);
+		ProcFileSize = 0;
+	}
+	/* For the persistant folks, set eof and return zero length.      */
+	else if( ProcBuffer == NULL) {
+		*eof = 1;
+		return 0;
+	}
+	/* How much data can be moved                                     */
+	int MoveSize = ProcBufSize;
+	if( MoveSize > count) MoveSize = count;
+
+	/* Move the data info the FileSystem buffer.                      */
+	memcpy(page+off,ProcBufPtr,MoveSize);
+	ProcBufPtr   += MoveSize;
+	ProcBufSize  -= MoveSize;
+	ProcFileSize += MoveSize;
+
+	/* If all the data has been moved, free the buffer and set EOF.   */
+	if( ProcBufSize == 0) {
+		kfree(ProcBuffer );
+		ProcBuffer  = NULL;
+		spin_unlock(&ProcBufferLock);
+		*eof = 1;
+	}
+	return ProcFileSize;
+}
+/*******************************************************************************/
+/* Gets called when client writes to ../proc/ppc64/pcifr                       */
+/*******************************************************************************/
+int proc_pciDev_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	return count;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/proc_pmc.c linux/arch/ppc64/kernel/proc_pmc.c
--- linux.orig/arch/ppc64/kernel/proc_pmc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/proc_pmc.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,840 @@
+/*
+ * proc_pmc.c
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM 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
+ */
+
+
+/* Change Activity:
+ * 2001       : mikec    : Created
+ * 2001/06/05 : engebret : Software event count support.
+ * 2001/08/03 : trautman : Added PCI Flight Recorder
+ * End Change Activity 
+ */
+
+#include <asm/proc_fs.h>
+#include <asm/paca.h>
+#include <asm/iSeries/ItLpPaca.h>
+#include <asm/iSeries/ItLpQueue.h>
+#include <asm/iSeries/HvCallXm.h>
+#include <asm/iSeries/IoHriMainStore.h>
+#include <asm/processor.h>
+#include <asm/time.h>
+#include <asm/iSeries/LparData.h>
+
+#include <linux/config.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <asm/pmc.h>
+#include <asm/uaccess.h>
+#include <asm/naca.h>
+
+/* pci Flight Recorder AHT */
+extern void proc_pciFr_init(struct proc_dir_entry *proc_ppc64_root);
+
+static int proc_pmc_control_mode = 0;
+
+static struct proc_dir_entry *proc_ppc64_root = NULL;
+static struct proc_dir_entry *proc_ppc64_pmc_root = NULL;
+static struct proc_dir_entry *proc_ppc64_pmc_system_root = NULL;
+static struct proc_dir_entry *proc_ppc64_pmc_cpu_root[NR_CPUS] = {NULL, };
+
+static spinlock_t proc_ppc64_lock;
+static int proc_ppc64_page_read(char *page, char **start, off_t off,
+				int count, int *eof, void *data);
+static void proc_ppc64_create_paca(int num, struct proc_dir_entry *paca_dir);
+int proc_ppc64_pmc_find_file(void *data);
+int proc_ppc64_pmc_read(char *page, char **start, off_t off,
+			int count, int *eof, char *buffer);
+int proc_ppc64_pmc_stab_read(char *page, char **start, off_t off,
+			     int count, int *eof, void *data);
+int proc_ppc64_pmc_htab_read(char *page, char **start, off_t off,
+			     int count, int *eof, void *data);
+int proc_ppc64_pmc_hw_read(char *page, char **start, off_t off, 
+			   int count, int *eof, void *data);
+
+static struct proc_dir_entry *pmc_proc_root = NULL;
+
+int proc_get_lpevents( char *page, char **start, off_t off, int count, int *eof, void *data);
+int proc_reset_lpevents( struct file *file, const char *buffer, unsigned long count, void *data);
+
+int proc_get_titanTod( char *page, char **start, off_t off, int count, int *eof, void *data);
+
+int proc_pmc_get_control( char *page, char **start, off_t off, int count, int *eof, void *data);
+
+int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_pmc1(  struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_pmc2(  struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_pmc3(  struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_pmc4(  struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_pmc5(  struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_pmc6(  struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_pmc7(  struct file *file, const char *buffer, unsigned long count, void *data);
+int proc_pmc_set_pmc8(  struct file *file, const char *buffer, unsigned long count, void *data);
+
+
+void proc_ppc64_init(void)
+{
+	unsigned long i;
+	struct proc_dir_entry *ent = NULL;
+	char buf[256];
+
+	printk("proc_ppc64: Creating /proc/ppc64/pmc\n");
+
+	/*
+	 * Create the root, system, and cpu directories as follows:
+	 *   /proc/ppc64/pmc/system 
+	 *   /proc/ppc64/pmc/cpu0 
+	 */
+	spin_lock(&proc_ppc64_lock);
+	proc_ppc64_root = proc_mkdir("ppc64", 0);
+	if (!proc_ppc64_root) return;
+	spin_unlock(&proc_ppc64_lock);
+
+	/* /proc/ppc64/naca -- raw naca contents.  Only readable to root */
+	create_proc_read_entry("naca", S_IRUSR, proc_ppc64_root, proc_ppc64_page_read, naca);
+	/* /proc/ppc64/paca/XX -- raw paca contents.  Only readable to root */
+	ent = proc_mkdir("paca", proc_ppc64_root);
+	if (ent) {
+		for (i = 0; i < naca->processorCount; i++)
+			proc_ppc64_create_paca(i, ent);
+	}
+
+	/* Create the /proc/ppc64/pcifr for the Pci Flight Recorder.	 */
+	proc_pciFr_init(proc_ppc64_root);
+
+	proc_ppc64_pmc_root = proc_mkdir("pmc", proc_ppc64_root);
+
+	proc_ppc64_pmc_system_root = proc_mkdir("system", proc_ppc64_pmc_root);
+	for (i = 0; i < naca->processorCount; i++) {
+		sprintf(buf, "cpu%ld", i); 
+		proc_ppc64_pmc_cpu_root[i] = proc_mkdir(buf, proc_ppc64_pmc_root);
+	}
+
+
+	/* Create directories for the software counters. */
+	for (i = 0; i < naca->processorCount; i++) {
+		ent = create_proc_entry("stab", S_IRUGO | S_IWUSR, 
+					proc_ppc64_pmc_cpu_root[i]);
+		if (ent) {
+			ent->nlink = 1;
+			ent->data = (void *)proc_ppc64_pmc_cpu_root[i];
+			ent->read_proc = (void *)proc_ppc64_pmc_stab_read;
+			ent->write_proc = (void *)proc_ppc64_pmc_stab_read;
+		}
+
+		ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, 
+					proc_ppc64_pmc_cpu_root[i]);
+		if (ent) {
+			ent->nlink = 1;
+			ent->data = (void *)proc_ppc64_pmc_cpu_root[i];
+			ent->read_proc = (void *)proc_ppc64_pmc_htab_read;
+			ent->write_proc = (void *)proc_ppc64_pmc_htab_read;
+		}
+	}
+
+	ent = create_proc_entry("stab", S_IRUGO | S_IWUSR, 
+				proc_ppc64_pmc_system_root);
+	if (ent) {
+		ent->nlink = 1;
+		ent->data = (void *)proc_ppc64_pmc_system_root;
+		ent->read_proc = (void *)proc_ppc64_pmc_stab_read;
+		ent->write_proc = (void *)proc_ppc64_pmc_stab_read;
+	}
+
+	ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, 
+				proc_ppc64_pmc_system_root);
+	if (ent) {
+		ent->nlink = 1;
+		ent->data = (void *)proc_ppc64_pmc_system_root;
+		ent->read_proc = (void *)proc_ppc64_pmc_htab_read;
+		ent->write_proc = (void *)proc_ppc64_pmc_htab_read;
+	}
+
+	/* Create directories for the hardware counters. */
+	for (i = 0; i < naca->processorCount; i++) {
+		ent = create_proc_entry("hardware", S_IRUGO | S_IWUSR, 
+					proc_ppc64_pmc_cpu_root[i]);
+		if (ent) {
+			ent->nlink = 1;
+			ent->data = (void *)proc_ppc64_pmc_cpu_root[i];
+			ent->read_proc = (void *)proc_ppc64_pmc_hw_read;
+			ent->write_proc = (void *)proc_ppc64_pmc_hw_read;
+		}
+	}
+
+	ent = create_proc_entry("hardware", S_IRUGO | S_IWUSR, 
+				proc_ppc64_pmc_system_root);
+	if (ent) {
+		ent->nlink = 1;
+		ent->data = (void *)proc_ppc64_pmc_system_root;
+		ent->read_proc = (void *)proc_ppc64_pmc_hw_read;
+		ent->write_proc = (void *)proc_ppc64_pmc_hw_read;
+	}
+}
+
+/* Read a page of raw data.  "data" points to the start addr.
+ * Intended as a proc read function.
+ */
+static int proc_ppc64_page_read(char *page, char **start, off_t off,
+				int count, int *eof, void *data)
+{
+	int len = PAGE_SIZE - off;
+	char *p = (char *)data;
+
+	if (len > count)
+		len = count;
+	if (len <= 0)
+		return 0;
+	/* Rely on a "hack" in fs/proc/generic.c.
+	 * If we could return a ptr to our own data this would be
+	 * trivial (currently *start must be either an offset, or
+	 * point into the given page).
+	 */
+	memcpy(page, p+off, len);
+	*start = (char *)len;
+	return len;
+}
+
+/* NOTE: since paca data is always in flux the values will never be a consistant set.
+ * In theory it could be made consistent if we made the corresponding cpu
+ * copy the page for us (via an IPI).  Probably not worth it.
+ *
+ */
+static void proc_ppc64_create_paca(int num, struct proc_dir_entry *paca_dir)
+{
+	struct proc_dir_entry *ent;
+	struct paca_struct *lpaca = paca + num;
+	char buf[16];
+
+	sprintf(buf, "%02x", num);
+	ent = create_proc_read_entry(buf, S_IRUSR, paca_dir, proc_ppc64_page_read, lpaca);
+}
+
+/*
+ * Find the requested 'file' given a proc token.
+ *
+ * Inputs: void * data: proc token
+ * Output: int        : (0, ..., +N) = CPU number.
+ *                      -1           = System.
+ */
+int proc_ppc64_pmc_find_file(void *data)
+{
+	int i;
+
+	if ((unsigned long)data == 
+	   (unsigned long) proc_ppc64_pmc_system_root) {
+		return(-1); 
+	} else {
+		for (i = 0; i < naca->processorCount; i++) {
+			if ((unsigned long)data ==
+			   (unsigned long)proc_ppc64_pmc_cpu_root[i]) {
+				return(i); 
+			}
+		}
+	}
+
+	/* On error, just default to a type of system. */
+	printk("proc_ppc64_pmc_find_file: failed to find file token.\n"); 
+	return(-1); 
+}
+
+int 
+proc_ppc64_pmc_read(char *page, char **start, off_t off, 
+		    int count, int *eof, char *buffer)
+{
+	int buffer_size, n;
+
+	if (count < 0) return 0;
+
+	if (buffer == NULL) {
+		*eof = 1;
+		return 0;
+	}
+
+	/* Check for read beyond EOF */
+	buffer_size = n = strlen(buffer);
+	if (off >= buffer_size) {
+		*eof = 1;
+		return 0;
+	}
+	if (n > (buffer_size - off)) n = buffer_size - off;
+
+	/* Never return more than was requested */
+	if (n > count) {
+		n = count;
+	} else {
+		*eof = 1;
+	}
+
+	memcpy(page, buffer + off, n);
+
+	*start = page;
+
+	return n;
+}
+
+int 
+proc_ppc64_pmc_stab_read(char *page, char **start, off_t off, 
+			 int count, int *eof, void *data)
+{
+	int n, file;
+	char *buffer = NULL;
+
+	if (count < 0) return 0;
+	spin_lock(&proc_ppc64_lock);
+
+	/* Figure out which file is being request. */
+	file = proc_ppc64_pmc_find_file(data);
+
+	/* Update the counters and the text buffer representation. */
+	buffer = ppc64_pmc_stab(file);
+
+	/* Put the data into the requestor's buffer. */
+	n = proc_ppc64_pmc_read(page, start, off, count, eof, buffer); 
+
+	spin_unlock(&proc_ppc64_lock);
+	return n;
+}
+
+int 
+proc_ppc64_pmc_htab_read(char *page, char **start, off_t off, 
+			 int count, int *eof, void *data)
+{
+	int n, file;
+	char *buffer = NULL;
+
+	if (count < 0) return 0;
+	spin_lock(&proc_ppc64_lock);
+
+	/* Figure out which file is being request. */
+	file = proc_ppc64_pmc_find_file(data);
+
+	/* Update the counters and the text buffer representation. */
+	buffer = ppc64_pmc_htab(file);
+
+	/* Put the data into the requestor's buffer. */
+	n = proc_ppc64_pmc_read(page, start, off, count, eof, buffer);
+
+	spin_unlock(&proc_ppc64_lock);
+	return n;
+}
+
+int 
+proc_ppc64_pmc_hw_read(char *page, char **start, off_t off, 
+			     int count, int *eof, void *data)
+{
+	int n, file;
+	char *buffer = NULL;
+
+	if (count < 0) return 0;
+	spin_lock(&proc_ppc64_lock);
+
+	/* Figure out which file is being request. */
+	file = proc_ppc64_pmc_find_file(data);
+
+	/* Update the counters and the text buffer representation. */
+	buffer = ppc64_pmc_hw(file);
+
+	/* Put the data into the requestor's buffer. */
+	n = proc_ppc64_pmc_read(page, start, off, count, eof, buffer);
+
+	spin_unlock(&proc_ppc64_lock);
+	return n;
+}
+
+/* 
+ * DRENG the remainder of these functions still need work ...
+ */
+void pmc_proc_init(struct proc_dir_entry *iSeries_proc)
+{
+    struct proc_dir_entry *ent = NULL;
+
+    ent = create_proc_entry("lpevents", S_IFREG|S_IRUGO, iSeries_proc);
+    if (!ent) return;
+    ent->nlink = 1;
+    ent->data = (void *)0;
+    ent->read_proc = proc_get_lpevents;
+    ent->write_proc = proc_reset_lpevents;
+
+    ent = create_proc_entry("titanTod", S_IFREG|S_IRUGO, iSeries_proc);
+    if (!ent) return;
+    ent->nlink = 1;
+    ent->data = (void *)0;
+    ent->read_proc = proc_get_titanTod;
+    ent->write_proc = NULL;
+
+    pmc_proc_root = proc_mkdir("pmc", iSeries_proc);
+    if (!pmc_proc_root) return;
+
+    ent = create_proc_entry("control", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root);
+    if (!ent) return;
+    ent->nlink = 1;
+    ent->data = (void *)0;
+    ent->read_proc = proc_pmc_get_control;
+    ent->write_proc = proc_pmc_set_control;
+
+}
+
+static int pmc_calc_metrics( char *page, char **start, off_t off, int count, int *eof, int len)
+{
+	if ( len <= off+count)
+		*eof = 1;
+	*start = page+off;
+	len -= off;
+	if ( len > count )
+		len = count;
+	if ( len < 0 )
+		len = 0;
+	return len;
+}
+
+static char * lpEventTypes[9] = {
+	"Hypervisor\t\t",
+	"Machine Facilities\t",
+	"Session Manager\t",
+	"SPD I/O\t\t",
+	"Virtual Bus\t\t",
+	"PCI I/O\t\t",
+	"RIO I/O\t\t",
+	"Virtual Lan\t\t",
+	"Virtual I/O\t\t"
+	};
+	
+
+int proc_get_lpevents
+(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	unsigned i;
+	int len = 0;
+
+	len += sprintf( page+len, "LpEventQueue 0\n" );
+	len += sprintf( page+len, "  events processed:\t%lu\n",
+			(unsigned long)xItLpQueue.xLpIntCount );
+	for (i=0; i<9; ++i) {
+		len += sprintf( page+len, "    %s %10lu\n",
+			lpEventTypes[i],
+			(unsigned long)xItLpQueue.xLpIntCountByType[i] );
+	}
+	len += sprintf( page+len, "\n  events processed by processor:\n" );
+	for (i=0; i<naca->processorCount; ++i) {
+		len += sprintf( page+len, "    CPU%02d  %10u\n",
+			i, paca[i].lpEvent_count );
+	}
+
+	return pmc_calc_metrics( page, start, off, count, eof, len );
+
+}
+
+int proc_reset_lpevents( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	return count;
+}
+
+static unsigned long startTitan = 0;
+static unsigned long startTb = 0;
+
+
+int proc_get_titanTod
+(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int len = 0;
+	unsigned long tb0, titan_tod;
+
+	tb0 = get_tb();
+	titan_tod = HvCallXm_loadTod();
+
+	len += sprintf( page+len, "Titan\n" );
+	len += sprintf( page+len, "  time base =          %016lx\n", tb0 );
+	len += sprintf( page+len, "  titan tod =          %016lx\n", titan_tod );
+	len += sprintf( page+len, "  xProcFreq =          %016x\n", xIoHriProcessorVpd[0].xProcFreq );
+	len += sprintf( page+len, "  xTimeBaseFreq =      %016x\n", xIoHriProcessorVpd[0].xTimeBaseFreq );
+	len += sprintf( page+len, "  tb_ticks_per_jiffy = %lu\n", tb_ticks_per_jiffy );
+	len += sprintf( page+len, "  tb_ticks_per_usec  = %lu\n", tb_ticks_per_usec );
+
+	if ( !startTitan ) {
+		startTitan = titan_tod;
+		startTb = tb0;
+	}
+	else {
+		unsigned long titan_usec = (titan_tod - startTitan) >> 12;
+		unsigned long tb_ticks = (tb0 - startTb);
+		unsigned long titan_jiffies = titan_usec / (1000000/HZ);
+		unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ);
+		unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec;
+		unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy;
+		unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
+		unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks;
+		unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec;
+		unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec;
+		
+		len += sprintf( page+len, "  titan elapsed = %lu uSec\n", titan_usec);
+		len += sprintf( page+len, "  tb elapsed    = %lu ticks\n", tb_ticks);
+		len += sprintf( page+len, "  titan jiffies = %lu.%04lu \n", titan_jiffies, titan_jiff_rem_usec );				
+		len += sprintf( page+len, "  tb jiffies    = %lu.%04lu\n", tb_jiffies, tb_jiff_rem_usec );
+		len += sprintf( page+len, "  new tb_ticks_per_jiffy = %lu\n", new_tb_ticks_per_jiffy );	
+
+	}
+	
+	return pmc_calc_metrics( page, start, off, count, eof, len );
+}
+	
+int proc_pmc_get_control
+(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int len = 0;
+
+	if ( proc_pmc_control_mode == PMC_CONTROL_CPI ) {
+		unsigned long mach_cycles   = mfspr( PMC5 );
+		unsigned long inst_complete = mfspr( PMC4 );
+		unsigned long inst_dispatch = mfspr( PMC3 );
+		unsigned long thread_active_run = mfspr( PMC1 );
+		unsigned long thread_active  = mfspr( PMC2 );
+		unsigned long cpi = 0;
+		unsigned long cpithou = 0;
+		unsigned long remain;
+	
+		if ( inst_complete ) {
+			cpi = thread_active_run / inst_complete;
+			remain = thread_active_run % inst_complete;
+			if ( inst_complete > 1000000 ) 
+				cpithou = remain / ( inst_complete / 1000 );
+			else 
+				cpithou = ( remain * 1000 ) / inst_complete;
+		}
+		len += sprintf( page+len, "PMC CPI Mode\nRaw Counts\n" );
+		len += sprintf( page+len, "machine cycles           : %12lu\n", mach_cycles );
+		len += sprintf( page+len, "thread active cycles     : %12lu\n\n", thread_active );
+
+		len += sprintf( page+len, "instructions completed   : %12lu\n", inst_complete );
+		len += sprintf( page+len, "instructions dispatched  : %12lu\n", inst_dispatch );
+		len += sprintf( page+len, "thread active run cycles : %12lu\n", thread_active_run );
+
+		len += sprintf( page+len, "thread active run cycles/instructions completed\n" );
+		len += sprintf( page+len, "CPI = %lu.%03lu\n", cpi, cpithou );
+		
+	}
+	else if ( proc_pmc_control_mode == PMC_CONTROL_TLB ) {
+		len += sprintf( page+len, "PMC TLB Mode\n" );
+		len += sprintf( page+len, "I-miss count             : %12lu\n", mfspr( PMC1 ) );
+		len += sprintf( page+len, "I-miss latency           : %12lu\n", mfspr( PMC2 ) );
+		len += sprintf( page+len, "D-miss count             : %12lu\n", mfspr( PMC3 ) );
+		len += sprintf( page+len, "D-miss latency           : %12lu\n", mfspr( PMC4 ) );
+		len += sprintf( page+len, "IERAT miss count         : %12lu\n", mfspr( PMC5 ) );
+		len += sprintf( page+len, "D-reference count        : %12lu\n", mfspr( PMC6 ) );
+		len += sprintf( page+len, "miss PTEs searched       : %12lu\n", mfspr( PMC7 ) );
+		len += sprintf( page+len, "miss >8 PTEs searched    : %12lu\n", mfspr( PMC8 ) );
+	}
+	/* IMPLEMENT ME */
+	return pmc_calc_metrics( page, start, off, count, eof, len );
+}
+
+unsigned long proc_pmc_conv_int( const char *buf, unsigned count )
+{
+	const char * p;
+	char b0, b1;
+	unsigned v, multiplier, mult, i;
+	unsigned long val;
+	multiplier = 10;
+	p = buf;
+	if ( count >= 3 ) {
+		b0 = buf[0];
+		b1 = buf[1];
+		if ( ( b0 == '0' ) &&
+		     ( ( b1 == 'x' ) || ( b1 == 'X' ) ) ) {
+			p = buf + 2;
+			count -= 2;
+			multiplier = 16;
+		}
+			
+	}
+	val = 0;
+	for ( i=0; i<count; ++i ) {
+		b0 = *p++;
+		v = 0;
+		mult = multiplier;
+		if ( ( b0 >= '0' ) && ( b0 <= '9' ) ) 
+			v = b0 - '0';
+		else if ( multiplier == 16 ) {
+			if ( ( b0 >= 'a' ) && ( b0 <= 'f' ) )
+				v = b0 - 'a' + 10;
+			else if ( ( b0 >= 'A' ) && ( b0 <= 'F' ) )
+				v = b0 - 'A' + 10;
+			else 
+				mult = 1;
+		}
+		else
+			mult = 1;
+		val *= mult;
+		val += v;
+	}
+
+	return val;
+
+}
+
+static inline void proc_pmc_stop(void)
+{
+	/* Freeze all counters, leave everything else alone */
+	mtspr( MMCR0, mfspr( MMCR0 ) | 0x80000000 );
+}
+
+static inline void proc_pmc_start(void)
+{
+	/* Unfreeze all counters, leave everything else alone */
+	mtspr( MMCR0, mfspr( MMCR0 ) & ~0x80000000 );
+
+}
+
+static inline void proc_pmc_reset(void)
+{
+	/* Clear all the PMCs to zeros 
+	 * Assume a "stop" has already frozen the counters
+	 * Clear all the PMCs
+	 */
+	mtspr( PMC1, 0 );
+	mtspr( PMC2, 0 );
+	mtspr( PMC3, 0 );
+	mtspr( PMC4, 0 );
+	mtspr( PMC5, 0 );
+	mtspr( PMC6, 0 );
+	mtspr( PMC7, 0 );
+	mtspr( PMC8, 0 );
+
+}
+
+static inline void proc_pmc_cpi(void)
+{
+	/* Configure the PMC registers to count cycles and instructions */
+	/* so we can compute cpi */
+	/*
+	 * MMCRA[30]    = 1     Don't count in wait state (CTRL[31]=0)
+	 * MMCR0[6]     = 1     Freeze counters when any overflow
+	 * MMCR0[19:25] = 0x01  PMC1 counts Thread Active Run Cycles
+	 * MMCR0[26:31] = 0x05	PMC2 counts Thread Active Cycles
+	 * MMCR1[0:4]   = 0x07	PMC3 counts Instructions Dispatched
+	 * MMCR1[5:9]   = 0x03	PMC4 counts Instructions Completed
+	 * MMCR1[10:14] = 0x06	PMC5 counts Machine Cycles
+	 *
+	 */
+
+	proc_pmc_control_mode = PMC_CONTROL_CPI;
+	
+	/* Indicate to hypervisor that we are using the PMCs */
+	get_paca()->xLpPacaPtr->xPMCRegsInUse = 1;
+
+	/* Freeze all counters */
+	mtspr( MMCR0, 0x80000000 );
+	mtspr( MMCR1, 0x00000000 );
+	
+	/* Clear all the PMCs */
+	mtspr( PMC1, 0 );
+	mtspr( PMC2, 0 );
+	mtspr( PMC3, 0 );
+	mtspr( PMC4, 0 );
+	mtspr( PMC5, 0 );
+	mtspr( PMC6, 0 );
+	mtspr( PMC7, 0 );
+	mtspr( PMC8, 0 );
+
+	/* Freeze counters in Wait State (CTRL[31]=0) */
+	mtspr( MMCRA, 0x00000002 );
+
+	/* PMC3<-0x07, PMC4<-0x03, PMC5<-0x06 */
+	mtspr( MMCR1, 0x38cc0000 );
+
+	mb();
+	
+	/* PMC1<-0x01, PMC2<-0x05
+	 * Start all counters
+	 */
+	mtspr( MMCR0, 0x02000045 );
+	
+}
+
+static inline void proc_pmc_tlb(void)
+{
+	/* Configure the PMC registers to count tlb misses  */
+	/*
+	 * MMCR0[6]     = 1     Freeze counters when any overflow
+	 * MMCR0[19:25] = 0x55  Group count
+	 *   PMC1 counts  I misses
+	 *   PMC2 counts  I miss duration (latency)
+	 *   PMC3 counts  D misses
+	 *   PMC4 counts  D miss duration (latency)
+	 *   PMC5 counts  IERAT misses
+	 *   PMC6 counts  D references (including PMC7)
+	 *   PMC7 counts  miss PTEs searched
+	 *   PMC8 counts  miss >8 PTEs searched
+	 *   
+	 */
+
+	proc_pmc_control_mode = PMC_CONTROL_TLB;
+	
+	/* Indicate to hypervisor that we are using the PMCs */
+	get_paca()->xLpPacaPtr->xPMCRegsInUse = 1;
+
+	/* Freeze all counters */
+	mtspr( MMCR0, 0x80000000 );
+	mtspr( MMCR1, 0x00000000 );
+	
+	/* Clear all the PMCs */
+	mtspr( PMC1, 0 );
+	mtspr( PMC2, 0 );
+	mtspr( PMC3, 0 );
+	mtspr( PMC4, 0 );
+	mtspr( PMC5, 0 );
+	mtspr( PMC6, 0 );
+	mtspr( PMC7, 0 );
+	mtspr( PMC8, 0 );
+
+	mtspr( MMCRA, 0x00000000 );
+
+	mb();
+	
+	/* PMC1<-0x55
+	 * Start all counters
+	 */
+	mtspr( MMCR0, 0x02001540 );
+	
+}
+
+int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	if      ( ! strncmp( buffer, "stop", 4 ) )
+		proc_pmc_stop();
+	else if ( ! strncmp( buffer, "start", 5 ) )
+		proc_pmc_start();
+	else if ( ! strncmp( buffer, "reset", 5 ) )
+		proc_pmc_reset();
+	else if ( ! strncmp( buffer, "cpi", 3 ) )
+		proc_pmc_cpi();
+	else if ( ! strncmp( buffer, "tlb", 3 ) )
+		proc_pmc_tlb();
+	
+	/* IMPLEMENT ME */
+	return count;
+}
+
+int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	v = v & ~0x04000000;	/* Don't allow interrupts for now */
+	if ( v & ~0x80000000 ) 	/* Inform hypervisor we are using PMCs */
+		get_paca()->xLpPacaPtr->xPMCRegsInUse = 1;
+	else
+		get_paca()->xLpPacaPtr->xPMCRegsInUse = 0;
+	mtspr( MMCR0, v );
+	
+	return count;	
+}
+
+int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( MMCR1, v );
+
+	return count;
+}
+
+int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	v = v & ~0x00008000;	/* Don't allow interrupts for now */
+	mtspr( MMCRA, v );
+
+	return count;
+}
+
+
+int proc_pmc_set_pmc1( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( PMC1, v );
+
+	return count;
+}
+
+int proc_pmc_set_pmc2( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( PMC2, v );
+
+	return count;
+}
+
+int proc_pmc_set_pmc3( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( PMC3, v );
+
+	return count;
+}
+
+int proc_pmc_set_pmc4( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( PMC4, v );
+
+	return count;
+}
+
+int proc_pmc_set_pmc5( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( PMC5, v );
+
+	return count;
+}
+
+int proc_pmc_set_pmc6( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( PMC6, v );
+
+	return count;
+}
+
+int proc_pmc_set_pmc7( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( PMC7, v );
+
+	return count;
+}
+
+int proc_pmc_set_pmc8( struct file *file, const char *buffer, unsigned long count, void *data )
+{
+	unsigned long v;
+	v = proc_pmc_conv_int( buffer, count );
+	mtspr( PMC8, v );
+
+	return count;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/process.c linux/arch/ppc64/kernel/process.c
--- linux.orig/arch/ppc64/kernel/process.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/process.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,535 @@
+/*
+ *  linux/arch/ppc64/kernel/process.c
+ *
+ *  Derived from "arch/i386/kernel/process.c"
+ *    Copyright (C) 1995  Linus Torvalds
+ *
+ *  Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
+ *  Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ *  PowerPC version 
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/elf.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+#include <asm/prom.h>
+#include <asm/ppcdebug.h>
+#include <asm/machdep.h>
+#include <asm/iSeries/HvCallHpt.h>
+
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs);
+
+struct task_struct *last_task_used_math = NULL;
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+struct mm_struct ioremap_mm = { pgd             : ioremap_dir  
+                               ,page_table_lock : SPIN_LOCK_UNLOCKED };
+
+/* this is 16-byte aligned because it has a stack in it */
+union task_union __attribute((aligned(16))) init_task_union = {
+	INIT_TASK(init_task_union.task)
+};
+
+#ifdef CONFIG_SMP
+struct current_set_struct current_set[NR_CPUS] = {{&init_task, 0}, };
+#endif
+
+char *sysmap = NULL; 
+unsigned long sysmap_size = 0;
+
+extern char __toc_start;
+
+#undef SHOW_TASK_SWITCHES
+
+void
+enable_kernel_fp(void)
+{
+#ifdef CONFIG_SMP
+	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
+		giveup_fpu(current);
+	else
+		giveup_fpu(NULL);	/* just enables FP for kernel */
+#else
+	giveup_fpu(last_task_used_math);
+#endif /* CONFIG_SMP */
+}
+
+int
+dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
+{
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+	memcpy(fpregs, &current->thread.fpr[0], sizeof(*fpregs));
+	return 1;
+}
+
+void
+_switch_to(struct task_struct *prev, struct task_struct *new,
+	  struct task_struct **last)
+{
+	struct thread_struct *new_thread, *old_thread;
+	unsigned long s;
+	
+	__save_flags(s);
+	__cli();
+
+#ifdef SHOW_TASK_SWITCHES
+	printk("%s/%d -> %s/%d NIP %08lx cpu %d root %x/%x\n",
+	       prev->comm,prev->pid,
+	       new->comm,new->pid,new->thread.regs->nip,new->processor,
+	       new->fs->root,prev->fs->root);
+#endif
+#ifdef CONFIG_SMP
+	/* avoid complexity of lazy save/restore of fpu
+	 * by just saving it every time we switch out if
+	 * this task used the fpu during the last quantum.
+	 * 
+	 * If it tries to use the fpu again, it'll trap and
+	 * reload its fp regs.  So we don't have to do a restore
+	 * every switch, just a save.
+	 *  -- Cort
+	 */
+	if ( prev->thread.regs && (prev->thread.regs->msr & MSR_FP) )
+		giveup_fpu(prev);
+
+	/* prev->last_processor = prev->processor; */
+	current_set[smp_processor_id()].task = new;
+#endif /* CONFIG_SMP */
+	new_thread = &new->thread;
+	old_thread = &current->thread;
+	*last = _switch(old_thread, new_thread);
+	__restore_flags(s);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	int i;
+
+	printk("NIP: %016lX XER: %016lX LR: %016lX REGS: %p TRAP: %04lx    %s\n",
+	       regs->nip, regs->xer, regs->link, regs,regs->trap, print_tainted());
+	printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
+	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
+	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
+	       regs->msr&MSR_IR ? 1 : 0,
+	       regs->msr&MSR_DR ? 1 : 0);
+	printk("TASK = %p[%d] '%s' ",
+	       current, current->pid, current->comm);
+	printk("Last syscall: %ld ", current->thread.last_syscall);
+	printk("\nlast math %p ", last_task_used_math);
+	
+#ifdef CONFIG_SMP
+	/* printk(" CPU: %d last CPU: %d", current->processor,current->last_processor); */
+#endif /* CONFIG_SMP */
+	
+	printk("\n");
+	for (i = 0;  i < 32;  i++)
+	{
+		long r;
+		if ((i % 4) == 0)
+		{
+			printk("GPR%02d: ", i);
+		}
+
+		if ( __get_user(r, &(regs->gpr[i])) )
+		    return;
+
+		printk("%016lX ", r);
+		if ((i % 4) == 3)
+		{
+			printk("\n");
+		}
+	}
+}
+
+void exit_thread(void)
+{
+	if (last_task_used_math == current)
+		last_task_used_math = NULL;
+}
+
+void flush_thread(void)
+{
+	if (last_task_used_math == current)
+		last_task_used_math = NULL;
+}
+
+void
+release_thread(struct task_struct *t)
+{
+}
+
+/*
+ * Copy a thread..
+ */
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+	    unsigned long unused,
+	    struct task_struct * p, struct pt_regs * regs)
+{
+	unsigned long msr;
+	struct pt_regs * childregs, *kregs;
+	extern void ret_from_fork(void);
+
+	/* Copy registers */
+	childregs = ((struct pt_regs *)
+		     ((unsigned long)p + sizeof(union task_union)
+		      - STACK_FRAME_OVERHEAD)) - 2;
+	*childregs = *regs;
+	childregs->gpr[3] = 0;  /* Result from fork() */
+	p->thread.regs = childregs;
+	p->thread.ksp = (unsigned long) childregs - STACK_FRAME_OVERHEAD;
+	p->thread.ksp -= sizeof(struct pt_regs ) + STACK_FRAME_OVERHEAD;
+	kregs = (struct pt_regs *)(p->thread.ksp + STACK_FRAME_OVERHEAD);
+	/* The PPC64 compiler makes use of a TOC to contain function 
+	 * pointers.  The function (ret_from_except) is actually a pointer
+	 * to the TOC entry.  The first entry is a pointer to the actual
+	 * function.
+ 	 */
+	kregs->nip = *((unsigned long *)ret_from_fork);
+	asm volatile("mfmsr %0" : "=r" (msr):);
+	kregs->msr = msr;
+	kregs->gpr[1] = (unsigned long)childregs - STACK_FRAME_OVERHEAD;
+	kregs->gpr[2] = (((unsigned long)&__toc_start) + 0x8000);
+	
+	if (usp >= (unsigned long) regs) {
+		/* Stack is in kernel space - must adjust */
+		childregs->gpr[1] = (unsigned long)(childregs + 1);
+		*((unsigned long *) childregs->gpr[1]) = 0;
+		childregs->gpr[13] = (unsigned long) p;
+	} else {
+		/* Provided stack is in user space */
+		childregs->gpr[1] = usp;
+	}
+	p->thread.last_syscall = -1;
+	  
+	/*
+	 * copy fpu info - assume lazy fpu switch now always
+	 *  -- Cort
+	 */
+	if (regs->msr & MSR_FP) {
+		giveup_fpu(current);
+		childregs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+	}
+	memcpy(&p->thread.fpr, &current->thread.fpr, sizeof(p->thread.fpr));
+	p->thread.fpscr = current->thread.fpscr;
+
+	return 0;
+}
+
+/*
+ * Set up a thread for executing a new program
+ */
+void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp)
+{
+	unsigned long entry, toc, load_addr = regs->gpr[2];
+
+	/* fdptr is a relocated pointer to the function descriptor for
+         * the elf _start routine.  The first entry in the function
+         * descriptor is the entry address of _start and the second
+         * entry is the TOC value we need to use.
+         */
+	set_fs(USER_DS);
+	__get_user(entry, (unsigned long *)fdptr);
+	__get_user(toc, (unsigned long *)fdptr+1);
+
+	/* Check whether the e_entry function descriptor entries
+	 * need to be relocated before we can use them.
+	 */
+	if ( load_addr != 0 ) {
+		entry += load_addr;
+		toc   += load_addr;
+	}
+
+	regs->nip = entry;
+	regs->gpr[1] = sp;
+	regs->gpr[2] = toc;
+	regs->msr = MSR_USER64;
+	if (last_task_used_math == current)
+		last_task_used_math = 0;
+	current->thread.fpscr = 0;
+}
+
+asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
+			 struct pt_regs *regs)
+{
+	unsigned long clone_flags = p1;
+	int res;
+
+	PPCDBG(PPCDBG_SYS64, "sys_clone - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	res = do_fork(clone_flags, regs->gpr[1], regs, 0);
+#ifdef CONFIG_SMP
+	/* When we clone the idle task we keep the same pid but
+	 * the return value of 0 for both causes problems.
+	 * -- Cort
+	 */
+	if ((current->pid == 0) && (current == &init_task))
+		res = 1;
+#endif /* CONFIG_SMP */
+
+	PPCDBG(PPCDBG_SYS64, "sys_clone - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return res;
+}
+
+asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
+			struct pt_regs *regs)
+{
+	int res;
+	
+	PPCDBG(PPCDBG_SYS64, "sys_fork - entered - pid=%ld comm=%s \n", current->pid, current->comm);
+
+	res = do_fork(SIGCHLD, regs->gpr[1], regs, 0);
+
+#ifdef CONFIG_SMP
+	/* When we clone the idle task we keep the same pid but
+	 * the return value of 0 for both causes problems.
+	 * -- Cort
+	 */
+	if ((current->pid == 0) && (current == &init_task))
+		res = 1;
+#endif /* CONFIG_SMP */
+	
+	PPCDBG(PPCDBG_SYS64, "sys_fork - exited - pid=%ld comm=%s \n", current->pid, current->comm);
+
+	return res;
+}
+
+asmlinkage int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
+			 struct pt_regs *regs)
+{
+  	PPCDBG(PPCDBG_SYS64, "sys_vfork - running - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0);
+}
+
+asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+			  unsigned long a3, unsigned long a4, unsigned long a5,
+			  struct pt_regs *regs)
+{
+	int error;
+	char * filename;
+
+	PPCDBG(PPCDBG_SYS64, "sys_execve - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	filename = getname((char *) a0);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+
+	PPCDBG(PPCDBG_SYS64, "sys_execve - before do_execve : filename = %s\n", filename);
+
+	error = do_execve(filename, (char **) a1, (char **) a2, regs);
+
+	if (error == 0)
+		current->ptrace &= ~PT_DTRACE;
+	putname(filename);
+
+  out:
+	PPCDBG(PPCDBG_SYS64, "sys_execve - exited - pid=%ld current=%lx comm=%s error = %lx\n", current->pid, current, current->comm, error);
+
+	return error;
+}
+
+struct task_struct * alloc_task_struct(void)
+{
+	struct task_struct * new_task_ptr;
+    
+	new_task_ptr = ((struct task_struct *) 
+			__get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE)));
+    
+	return new_task_ptr;
+}
+
+void free_task_struct(struct task_struct * task_ptr)
+{
+	free_pages((unsigned long)(task_ptr), get_order(THREAD_SIZE));
+}
+
+void initialize_paca_hardware_interrupt_stack(void)
+{
+	extern struct naca_struct *naca;
+
+	int i;
+	unsigned long stack;
+	unsigned long end_of_stack =0;
+
+	for (i=1; i < naca->processorCount; i++) {
+		/* Carve out storage for the hardware interrupt stack */
+		stack = __get_free_pages(GFP_KERNEL, get_order(8*PAGE_SIZE));
+
+		if ( !stack ) {     
+			printk("ERROR, cannot find space for hardware stack.\n");
+			panic(" no hardware stack ");
+		}
+
+
+		/* Store the stack value in the PACA for the processor */
+		paca[i].xHrdIntStack = stack + (8*PAGE_SIZE) - STACK_FRAME_OVERHEAD;
+		paca[i].xHrdIntCount = 0;
+
+	}
+
+	/*
+	 * __get_free_pages() might give us a page > KERNBASE+256M which
+	 * is mapped with large ptes so we can't set up the guard page.
+	 */
+	if (__is_processor(PV_POWER4))
+		return;
+
+	for (i=0; i < naca->processorCount; i++) {
+		/* set page at the top of stack to be protected - prevent overflow */
+		end_of_stack = paca[i].xHrdIntStack - (8*PAGE_SIZE - STACK_FRAME_OVERHEAD);
+		ppc_md.hpte_updateboltedpp(PP_RXRX,end_of_stack);
+	}
+}
+
+extern char _stext[], _etext[];
+
+char * ppc_find_proc_name( unsigned * p, char * buf, unsigned buflen )
+{
+	unsigned long tb_flags;
+	unsigned short name_len;
+	unsigned long tb_start, code_start, code_ptr, code_offset;
+	unsigned code_len;
+	strcpy( buf, "Unknown" );
+	code_ptr = (unsigned long)p;
+	code_offset = 0;
+	if ( ( (unsigned long)p >= (unsigned long)_stext ) && ( (unsigned long)p <= (unsigned long)_etext ) ) {
+		while ( (unsigned long)p <= (unsigned long)_etext ) {
+			if ( *p == 0 ) {
+				tb_start = (unsigned long)p;
+				++p;	/* Point to traceback flags */
+				tb_flags = *((unsigned long *)p);
+				p += 2;	/* Skip over traceback flags */
+				if ( tb_flags & TB_NAME_PRESENT ) {
+					if ( tb_flags & TB_PARMINFO )
+						++p;	/* skip over parminfo data */
+					if ( tb_flags & TB_HAS_TBOFF ) {
+						code_len = *p;	/* get code length */
+						code_start = tb_start - code_len;
+						code_offset = code_ptr - code_start + 1;
+						if ( code_offset > 0x100000 )
+							break;
+						++p;		/* skip over code size */
+					}
+					name_len = *((unsigned short *)p);
+					if ( name_len > (buflen-20) )
+						name_len = buflen-20;
+					memcpy( buf, ((char *)p)+2, name_len );
+					buf[name_len] = 0;
+					if ( code_offset )
+						sprintf( buf+name_len, "+0x%lx", code_offset-1 ); 
+				}
+				break;
+			}
+			++p;
+		}
+	}
+	return buf;
+}
+
+void
+print_backtrace(unsigned long *sp)
+{
+	int cnt = 0;
+	unsigned long i;
+	char name_buf[256];
+
+	printk("Call backtrace: \n");
+	while (sp) {
+		if (__get_user( i, &sp[2] ))
+			break;
+		printk("%016lX ", i);
+		printk("%s\n", ppc_find_proc_name( (unsigned *)i, name_buf, 256 ));
+		if (cnt > 32) break;
+		if (__get_user(sp, (unsigned long **)sp))
+			break;
+	}
+	printk("\n");
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched    (*(unsigned long *)scheduling_functions_start_here)
+#define last_sched     (*(unsigned long *)scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long ip, sp;
+	unsigned long stack_page = (unsigned long)p;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+	sp = p->thread.ksp;
+	do {
+		sp = *(unsigned long *)sp;
+		if (sp < (stack_page + (2 * PAGE_SIZE)) ||
+		    sp >= (stack_page + (THREAD_SIZE * PAGE_SIZE)))
+			return 0;
+		if (count > 0) {
+			ip = *(unsigned long *)(sp + 16);
+			if (ip < first_sched || ip >= last_sched)
+				return (ip & 0xFFFFFFFF);
+		}
+	} while (count++ < 16);
+	return 0;
+}
+
+void show_trace_task(struct task_struct *p)
+{
+	unsigned long ip, sp;
+	unsigned long stack_page = (unsigned long)p;
+	int count = 0;
+
+	if (!p)
+		return;
+
+	printk("Call Trace: ");
+	sp = p->thread.ksp;
+	do {
+		sp = *(unsigned long *)sp;
+		if (sp < (stack_page + (2 * PAGE_SIZE)) ||
+		    sp >= (stack_page + (THREAD_SIZE * PAGE_SIZE)))
+			break;
+		if (count > 0) {
+			ip = *(unsigned long *)(sp + 16);
+			printk("[%016lx] ", ip);
+		}
+	} while (count++ < 16);
+	printk("\n");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/prom.c linux/arch/ppc64/kernel/prom.c
--- linux.orig/arch/ppc64/kernel/prom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/prom.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,2366 @@
+/*
+ * 
+ *
+ * Procedures for interfacing to Open Firmware.
+ *
+ * Paul Mackerras	August 1996.
+ * Copyright (C) 1996 Paul Mackerras.
+ * 
+ *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ *    {engebret|bergner}@us.ibm.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.
+ */
+
+#if 0
+#define DEBUG_YABOOT
+#endif
+
+#if 0
+#define DEBUG_PROM
+#endif
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/blk.h>
+
+#ifdef DEBUG_YABOOT
+#define call_yaboot(FUNC,...) \
+	do { \
+		if (FUNC) {					\
+			struct prom_t *_prom = PTRRELOC(&prom);	\
+			unsigned long prom_entry = _prom->entry;\
+			_prom->entry = (unsigned long)(FUNC);	\
+			enter_prom(__VA_ARGS__); 		\
+			_prom->entry = prom_entry;		\
+		}						\
+	} while (0)
+#else
+#define call_yaboot(FUNC,...) do { ; } while (0)
+#endif
+
+#include <asm/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/lmb.h>
+#include <asm/abs_addr.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/bitops.h>
+#include <asm/naca.h>
+#include <asm/pci.h>
+#include "open_pic.h"
+#include <asm/bootinfo.h>
+#include <asm/ppcdebug.h>
+
+#ifdef CONFIG_FB
+#include <asm/linux_logo.h>
+#endif
+
+extern char _end[];
+
+/*
+ * prom_init() is called very early on, before the kernel text
+ * and data have been mapped to KERNELBASE.  At this point the code
+ * is running at whatever address it has been loaded at, so
+ * references to extern and static variables must be relocated
+ * explicitly.  The procedure reloc_offset() returns the address
+ * we're currently running at minus the address we were linked at.
+ * (Note that strings count as static variables.)
+ *
+ * Because OF may have mapped I/O devices into the area starting at
+ * KERNELBASE, particularly on CHRP machines, we can't safely call
+ * OF once the kernel has been mapped to KERNELBASE.  Therefore all
+ * OF calls should be done within prom_init(), and prom_init()
+ * and all routines called within it must be careful to relocate
+ * references as necessary.
+ *
+ * Note that the bss is cleared *after* prom_init runs, so we have
+ * to make sure that any static or extern variables it accesses
+ * are put in the data segment.
+ */
+
+
+#define PROM_BUG() do { \
+        prom_print(RELOC("kernel BUG at ")); \
+        prom_print(RELOC(__FILE__)); \
+        prom_print(RELOC(":")); \
+        prom_print_hex(__LINE__); \
+        prom_print(RELOC("!\n")); \
+        __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
+} while (0)
+
+
+
+struct pci_reg_property {
+	struct pci_address addr;
+	u32 size_hi;
+	u32 size_lo;
+};
+
+
+struct isa_reg_property {
+	u32 space;
+	u32 address;
+	u32 size;
+};
+
+struct pci_intr_map {
+	struct pci_address addr;
+	u32 dunno;
+	phandle int_ctrler;
+	u32 intr;
+};
+
+
+typedef unsigned long interpret_func(struct device_node *, unsigned long,
+				     int, int);
+#if 0
+static interpret_func interpret_pci_props;
+#endif
+static unsigned long interpret_pci_props(struct device_node *, unsigned long,
+					 int, int);
+
+static interpret_func interpret_isa_props;
+static interpret_func interpret_root_props;
+
+#ifndef FB_MAX			/* avoid pulling in all of the fb stuff */
+#define FB_MAX	8
+#endif
+
+
+struct prom_t prom = {
+	0,			/* entry */
+	0,			/* chosen */
+	0,			/* cpu */
+	0,			/* stdout */
+	0,			/* disp_node */
+	{0,0,0,{0},NULL},	/* args */
+	0,			/* version */
+	32,			/* encode_phys_size */
+	0			/* bi_rec pointer */
+#ifdef DEBUG_YABOOT
+	,NULL			/* yaboot */
+#endif
+};
+
+
+char *prom_display_paths[FB_MAX] __initdata = { 0, };
+unsigned int prom_num_displays = 0;
+char *of_stdout_device = 0;
+
+extern struct rtas_t rtas;
+extern unsigned long klimit;
+extern unsigned long embedded_sysmap_end;
+extern struct lmb lmb;
+#ifdef CONFIG_MSCHUNKS
+extern struct msChunks msChunks;
+#endif /* CONFIG_MSCHUNKS */
+
+#define MAX_PHB 16 * 3  // 16 Towers * 3 PHBs/tower
+struct _of_tce_table of_tce_table[MAX_PHB + 1] = {{0, 0, 0}};
+
+char *bootpath = 0;
+char *bootdevice = 0;
+
+struct device_node *allnodes = 0;
+
+#define UNDEFINED_IRQ 0xffff
+unsigned short real_irq_to_virt_map[NR_HW_IRQS];
+unsigned short virt_irq_to_real_map[NR_IRQS];
+int last_virt_irq = 2;	/* index of last virt_irq.  Skip through IPI */
+
+static unsigned long call_prom(const char *service, int nargs, int nret, ...);
+static void prom_exit(void);
+static unsigned long copy_device_tree(unsigned long);
+static unsigned long inspect_node(phandle, struct device_node *, unsigned long,
+				  unsigned long, struct device_node ***);
+static unsigned long finish_node(struct device_node *, unsigned long,
+				 interpret_func *, int, int);
+static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
+static unsigned long check_display(unsigned long);
+static int prom_next_node(phandle *);
+static struct bi_record * prom_bi_rec_verify(struct bi_record *);
+static unsigned long prom_bi_rec_reserve(unsigned long);
+static struct device_node *find_phandle(phandle);
+
+#ifdef CONFIG_MSCHUNKS
+static unsigned long prom_initialize_mschunks(unsigned long);
+#ifdef DEBUG_PROM
+void prom_dump_mschunks_mapping(void);
+#endif /* DEBUG_PROM */
+#endif /* CONFIG_MSCHUNKS */
+#ifdef DEBUG_PROM
+void prom_dump_lmb(void);
+#endif
+
+extern unsigned long reloc_offset(void);
+
+extern void enter_prom(void *dummy,...);
+
+void cacheable_memzero(void *, unsigned int);
+
+extern char cmd_line[512];	/* XXX */
+unsigned long dev_tree_size;
+
+#ifdef CONFIG_HMT
+struct {
+	unsigned int pir;
+	unsigned int threadid;
+} hmt_thread_data[NR_CPUS] = {0};
+#endif /* CONFIG_HMT */
+
+char testString[] = "LINUX\n"; 
+
+
+/* This is the one and *ONLY* place where we actually call open
+ * firmware from, since we need to make sure we're running in 32b
+ * mode when we do.  We switch back to 64b mode upon return.
+ */
+
+static unsigned long __init
+call_prom(const char *service, int nargs, int nret, ...)
+{
+	int i;
+	unsigned long offset = reloc_offset();
+	struct prom_t *_prom = PTRRELOC(&prom);
+	va_list list;
+        
+	_prom->args.service = (u32)LONG_LSW(service);
+	_prom->args.nargs = nargs;
+	_prom->args.nret = nret;
+        _prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]);
+
+        va_start(list, nret);
+	for (i=0; i < nargs ;i++)
+		_prom->args.args[i] = (prom_arg_t)LONG_LSW(va_arg(list, unsigned long));
+        va_end(list);
+
+	for (i=0; i < nret ;i++)
+		_prom->args.rets[i] = 0;
+
+	enter_prom(&_prom->args);
+
+	return (unsigned long)((nret > 0) ? _prom->args.rets[0] : 0);
+}
+
+
+static void __init
+prom_exit()
+{
+	unsigned long offset = reloc_offset();
+
+	call_prom(RELOC("exit"), 0, 0);
+
+	for (;;)			/* should never get here */
+		;
+}
+
+void __init
+prom_enter(void)
+{
+	unsigned long offset = reloc_offset();
+
+	call_prom(RELOC("enter"), 0, 0);
+}
+
+
+void __init
+prom_print(const char *msg)
+{
+	const char *p, *q;
+	unsigned long offset = reloc_offset();
+	struct prom_t *_prom = PTRRELOC(&prom);
+
+	if (_prom->stdout == 0)
+		return;
+
+	for (p = msg; *p != 0; p = q) {
+		for (q = p; *q != 0 && *q != '\n'; ++q)
+			;
+		if (q > p)
+			call_prom(RELOC("write"), 3, 1, _prom->stdout,
+				  p, q - p);
+		if (*q != 0) {
+			++q;
+			call_prom(RELOC("write"), 3, 1, _prom->stdout,
+				  RELOC("\r\n"), 2);
+		}
+	}
+}
+
+void
+prom_print_hex(unsigned long val)
+{
+        int i, nibbles = sizeof(val)*2;
+        char buf[sizeof(val)*2+1];
+
+        for (i = nibbles-1;  i >= 0;  i--) {
+                buf[i] = (val & 0xf) + '0';
+                if (buf[i] > '9')
+                    buf[i] += ('a'-'0'-10);
+                val >>= 4;
+        }
+        buf[nibbles] = '\0';
+	prom_print(buf);
+}
+
+void
+prom_print_nl(void)
+{
+	unsigned long offset = reloc_offset();
+	prom_print(RELOC("\n"));
+}
+
+
+static unsigned long
+prom_initialize_naca(unsigned long mem)
+{
+	phandle node;
+	char type[64];
+        unsigned long num_cpus = 0;
+        unsigned long offset = reloc_offset();
+	struct prom_t *_prom = PTRRELOC(&prom);
+        struct naca_struct *_naca = RELOC(naca);
+
+#ifdef DEBUG_PROM
+	prom_print(RELOC("prom_initialize_naca: start...\n"));
+#endif
+
+	_naca->pftSize = 0;	/* ilog2 of htab size.  computed below. */
+
+        for (node = 0; prom_next_node(&node); ) {
+                type[0] = 0;
+                call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
+                          type, sizeof(type));
+
+                if (!strcmp(type, RELOC("cpu"))) {
+			num_cpus += 1;
+
+			/* We're assuming *all* of the CPUs have the same
+			 * d-cache and i-cache sizes... -Peter
+			 */
+			if ( num_cpus == 1 ) {
+				u32 size;
+
+				call_prom(RELOC("getprop"), 4, 1, node,
+					  RELOC("d-cache-line-size"),
+					  &size, sizeof(size));
+
+				_naca->dCacheL1LineSize     = size;
+				_naca->dCacheL1LogLineSize  = __ilog2(size);
+				_naca->dCacheL1LinesPerPage = PAGE_SIZE / size;
+
+				call_prom(RELOC("getprop"), 4, 1, node,
+					  RELOC("i-cache-line-size"),
+					  &size, sizeof(size));
+
+				_naca->iCacheL1LineSize     = size;
+				_naca->iCacheL1LogLineSize  = __ilog2(size);
+				_naca->iCacheL1LinesPerPage = PAGE_SIZE / size;
+
+				if (_naca->platform == PLATFORM_PSERIES_LPAR) {
+					u32 pft_size[2];
+					call_prom(RELOC("getprop"), 4, 1, node, 
+						  RELOC("ibm,pft-size"),
+						  &pft_size, sizeof(pft_size));
+				/* pft_size[0] is the NUMA CEC cookie */
+					_naca->pftSize = pft_size[1];
+				}
+			}
+                } else if (!strcmp(type, RELOC("serial"))) {
+			phandle isa, pci;
+			struct isa_reg_property reg;
+			union pci_range ranges;
+
+			type[0] = 0;
+			call_prom(RELOC("getprop"), 4, 1, node,
+				  RELOC("ibm,aix-loc"), type, sizeof(type));
+
+			if (strcmp(type, RELOC("S1")))
+				continue;
+
+			call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
+				  &reg, sizeof(reg));
+
+			isa = call_prom(RELOC("parent"), 1, 1, node);
+			if (!isa)
+				PROM_BUG();
+			pci = call_prom(RELOC("parent"), 1, 1, isa);
+			if (!pci)
+				PROM_BUG();
+
+			call_prom(RELOC("getprop"), 4, 1, pci, RELOC("ranges"),
+				  &ranges, sizeof(ranges));
+
+			if ( _prom->encode_phys_size == 32 )
+				_naca->serialPortAddr = ranges.pci32.phys+reg.address;
+			else {
+				_naca->serialPortAddr = 
+					((((unsigned long)ranges.pci64.phys_hi) << 32) |
+					 (ranges.pci64.phys_lo)) + reg.address;
+			}
+                }
+	}
+
+	_naca->interrupt_controller = IC_INVALID;
+        for (node = 0; prom_next_node(&node); ) {
+                type[0] = 0;
+                call_prom(RELOC("getprop"), 4, 1, node, RELOC("name"),
+                          type, sizeof(type));
+                if (strcmp(type, RELOC("interrupt-controller"))) {
+			continue;
+		}
+                call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
+                          type, sizeof(type));
+                if (strstr(type, RELOC("open-pic"))) {
+			_naca->interrupt_controller = IC_OPEN_PIC;
+		} else if (strstr(type, RELOC("ppc-xicp"))) {
+			_naca->interrupt_controller = IC_PPC_XIC;
+		} else {
+			prom_print(RELOC("prom: failed to recognize interrupt-controller\n"));
+		}
+		break;
+	}
+
+	if (_naca->interrupt_controller == IC_INVALID) {
+		prom_print(RELOC("prom: failed to find interrupt-controller\n"));
+		PROM_BUG();
+	}
+
+	/* We gotta have at least 1 cpu... */
+        if ( (_naca->processorCount = num_cpus) < 1 )
+                PROM_BUG();
+
+	_naca->physicalMemorySize = lmb_phys_mem_size();
+
+	if (_naca->platform == PLATFORM_PSERIES) {
+		unsigned long rnd_mem_size, pteg_count;
+
+		/* round mem_size up to next power of 2 */
+		rnd_mem_size = 1UL << __ilog2(_naca->physicalMemorySize);
+		if (rnd_mem_size < _naca->physicalMemorySize)
+			rnd_mem_size <<= 1;
+
+		/* # pages / 2 */
+		pteg_count = (rnd_mem_size >> (12 + 1));
+
+		_naca->pftSize = __ilog2(pteg_count << 7);
+	}
+
+	if (_naca->pftSize == 0) {
+		prom_print(RELOC("prom: failed to compute pftSize!\n"));
+		PROM_BUG();
+	}
+
+	/* 
+	 * Hardcode to GP size.  I am not sure where to get this info
+	 * in general, as there does not appear to be a slb-size OF
+	 * entry.  At least in Condor and earlier.  DRENG 
+	 */
+	_naca->slb_size = 64;
+
+#ifdef DEBUG_PROM
+        prom_print(RELOC("naca->processorCount       = 0x"));
+        prom_print_hex(_naca->processorCount);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->physicalMemorySize   = 0x"));
+        prom_print_hex(_naca->physicalMemorySize);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->pftSize              = 0x"));
+        prom_print_hex(_naca->pftSize);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->dCacheL1LineSize     = 0x"));
+        prom_print_hex(_naca->dCacheL1LineSize);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->dCacheL1LogLineSize  = 0x"));
+        prom_print_hex(_naca->dCacheL1LogLineSize);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->dCacheL1LinesPerPage = 0x"));
+        prom_print_hex(_naca->dCacheL1LinesPerPage);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->iCacheL1LineSize     = 0x"));
+        prom_print_hex(_naca->iCacheL1LineSize);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->iCacheL1LogLineSize  = 0x"));
+        prom_print_hex(_naca->iCacheL1LogLineSize);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->iCacheL1LinesPerPage = 0x"));
+        prom_print_hex(_naca->iCacheL1LinesPerPage);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->serialPortAddr       = 0x"));
+        prom_print_hex(_naca->serialPortAddr);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->interrupt_controller = 0x"));
+        prom_print_hex(_naca->interrupt_controller);
+        prom_print_nl();
+
+        prom_print(RELOC("naca->platform             = 0x"));
+        prom_print_hex(_naca->platform);
+        prom_print_nl();
+
+	prom_print(RELOC("prom_initialize_naca: end...\n"));
+#endif
+
+	return mem;
+}
+
+
+static unsigned long __init
+prom_initialize_lmb(unsigned long mem)
+{
+	phandle node;
+	char type[64];
+        unsigned long i, offset = reloc_offset();
+	struct prom_t *_prom = PTRRELOC(&prom);
+	union lmb_reg_property reg;
+	unsigned long lmb_base, lmb_size;
+	unsigned long num_regs, bytes_per_reg = (_prom->encode_phys_size*2)/8;
+
+#ifdef CONFIG_MSCHUNKS
+	unsigned long max_addr = 0;
+#if 1
+	/* Fix me: 630 3G-4G IO hack here... -Peter (PPPBBB) */
+	unsigned long io_base = 3UL<<30;
+	unsigned long io_size = 1UL<<30;
+	unsigned long have_630 = 1;	/* assume we have a 630 */
+
+#else
+	unsigned long io_base = <real io base here>;
+	unsigned long io_size = <real io size here>;
+#endif
+#endif /* CONFIG_MSCHUNKS */
+
+	lmb_init();
+
+        for (node = 0; prom_next_node(&node); ) {
+                type[0] = 0;
+                call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
+                          type, sizeof(type));
+
+                if (strcmp(type, RELOC("memory")))
+			continue;
+
+		num_regs = call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
+			&reg, sizeof(reg)) / bytes_per_reg;
+
+		for (i=0; i < num_regs ;i++) {
+			if (_prom->encode_phys_size == 32) {
+				lmb_base = reg.addr32[i].address;
+				lmb_size = reg.addr32[i].size;
+			} else {
+				lmb_base = reg.addr64[i].address;
+				lmb_size = reg.addr64[i].size;
+			}
+
+#ifdef CONFIG_MSCHUNKS
+			if ( lmb_addrs_overlap(lmb_base,lmb_size,
+						io_base,io_size) ) {
+				/* If we really have dram here, then we don't
+			 	 * have a 630! -Peter
+			 	 */
+				have_630 = 0;
+			}
+#endif /* CONFIG_MSCHUNKS */
+			if ( lmb_add(lmb_base, lmb_size) < 0 )
+				prom_print(RELOC("Too many LMB's, discarding this one...\n"));
+#ifdef CONFIG_MSCHUNKS
+			else if ( max_addr < (lmb_base+lmb_size-1) )
+				max_addr = lmb_base+lmb_size-1;
+#endif /* CONFIG_MSCHUNKS */
+		}
+
+	}
+
+#ifdef CONFIG_MSCHUNKS
+	if ( have_630 && lmb_addrs_overlap(0,max_addr,io_base,io_size) )
+		lmb_add_io(io_base, io_size);
+#endif /* CONFIG_MSCHUNKS */
+
+	lmb_analyze();
+#ifdef DEBUG_PROM
+	prom_dump_lmb();
+#endif /* DEBUG_PROM */
+
+#ifdef CONFIG_MSCHUNKS
+	mem = prom_initialize_mschunks(mem);
+#ifdef DEBUG_PROM
+	prom_dump_mschunks_mapping();
+#endif /* DEBUG_PROM */
+#endif /* CONFIG_MSCHUNKS */
+
+	return mem;
+}
+
+
+static unsigned long __init
+prom_instantiate_rtas(unsigned long mem)
+{
+	unsigned long offset = reloc_offset();
+	struct prom_t *_prom = PTRRELOC(&prom);
+	struct rtas_t *_rtas = PTRRELOC(&rtas);
+	struct naca_struct *_naca = RELOC(naca);
+	ihandle prom_rtas;
+        u32 getprop_rval;
+
+#ifdef DEBUG_PROM
+	prom_print(RELOC("prom_instantiate_rtas: start...\n"));
+#endif
+	prom_rtas = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
+	if (prom_rtas != (ihandle) -1) {
+		char hypertas_funcs[1024];
+		int  rc; 
+		
+		if ((rc = call_prom(RELOC("getprop"), 
+				  4, 1, prom_rtas,
+				  RELOC("ibm,hypertas-functions"), 
+				  hypertas_funcs, 
+				  sizeof(hypertas_funcs))) > 0) {
+			_naca->platform = PLATFORM_PSERIES_LPAR;
+		}
+
+		call_prom(RELOC("getprop"), 
+			  4, 1, prom_rtas,
+			  RELOC("rtas-size"), 
+			  &getprop_rval, 
+			  sizeof(getprop_rval));
+	        _rtas->size = getprop_rval;
+		prom_print(RELOC("instantiating rtas"));
+		if (_rtas->size != 0) {
+			/*
+			 * Ask OF for some space for RTAS.
+			 * Actually OF has bugs so we just arbitrarily
+			 * use memory at the 6MB point.
+			 */
+			// The new code...
+			mem = PAGE_ALIGN(mem);
+			_rtas->base = mem + offset - KERNELBASE;
+
+			mem += _rtas->size;
+			prom_print(RELOC(" at 0x"));
+			prom_print_hex(_rtas->base);
+
+			prom_rtas = (ihandle)call_prom(RELOC("open"), 
+					      	1, 1, RELOC("/rtas"));
+			prom_print(RELOC("..."));
+
+			if ((long)call_prom(RELOC("call-method"), 3, 2,
+						      RELOC("instantiate-rtas"),
+						      prom_rtas,
+						      _rtas->base) >= 0) {
+				_rtas->entry = (long)_prom->args.rets[1];
+			}
+		}
+
+		if (_rtas->entry <= 0) {
+			prom_print(RELOC(" failed\n"));
+		} else {
+			prom_print(RELOC(" done\n"));
+		}
+
+#ifdef DEBUG_PROM
+        	prom_print(RELOC("rtas->base                 = 0x"));
+        	prom_print_hex(_rtas->base);
+        	prom_print_nl();
+        	prom_print(RELOC("rtas->entry                = 0x"));
+        	prom_print_hex(_rtas->entry);
+        	prom_print_nl();
+        	prom_print(RELOC("rtas->size                 = 0x"));
+        	prom_print_hex(_rtas->size);
+        	prom_print_nl();
+#endif
+	}
+#ifdef DEBUG_PROM
+	prom_print(RELOC("prom_instantiate_rtas: end...\n"));
+#endif
+
+	return mem;
+}
+
+unsigned long prom_strtoul(const char *cp)
+{
+	unsigned long result = 0,value;
+
+	while (*cp) {
+		value = *cp-'0';
+		result = result*10 + value;
+		cp++;
+	} 
+
+	return result;
+}
+
+
+#ifdef CONFIG_MSCHUNKS
+static unsigned long
+prom_initialize_mschunks(unsigned long mem)
+{
+        unsigned long offset = reloc_offset();
+	struct lmb *_lmb  = PTRRELOC(&lmb);
+	struct msChunks *_msChunks = PTRRELOC(&msChunks);
+	unsigned long i, pchunk = 0;
+	unsigned long addr_range = _lmb->memory.size + _lmb->memory.iosize;
+	unsigned long chunk_size = _lmb->memory.lcd_size;
+
+
+	mem = msChunks_alloc(mem, addr_range / chunk_size, chunk_size);
+
+	/* First create phys -> abs mapping for memory/dram */
+	for (i=0; i < _lmb->memory.cnt ;i++) {
+		unsigned long base = _lmb->memory.region[i].base;
+		unsigned long size = _lmb->memory.region[i].size;
+		unsigned long achunk = addr_to_chunk(base);
+		unsigned long end_achunk = addr_to_chunk(base+size);
+
+		if(_lmb->memory.region[i].type != LMB_MEMORY_AREA)
+			continue;
+
+		_lmb->memory.region[i].physbase = chunk_to_addr(pchunk);
+		for (; achunk < end_achunk ;) {
+			PTRRELOC(_msChunks->abs)[pchunk++] = achunk++;
+		}
+	}
+
+#ifdef CONFIG_MSCHUNKS
+	/* Now create phys -> abs mapping for IO */
+	for (i=0; i < _lmb->memory.cnt ;i++) {
+		unsigned long base = _lmb->memory.region[i].base;
+		unsigned long size = _lmb->memory.region[i].size;
+		unsigned long achunk = addr_to_chunk(base);
+		unsigned long end_achunk = addr_to_chunk(base+size);
+
+		if(_lmb->memory.region[i].type != LMB_IO_AREA)
+			continue;
+
+		_lmb->memory.region[i].physbase = chunk_to_addr(pchunk);
+		for (; achunk < end_achunk ;) {
+			PTRRELOC(_msChunks->abs)[pchunk++] = achunk++;
+		}
+	}
+#endif /* CONFIG_MSCHUNKS */
+
+	return mem;
+}
+
+#ifdef DEBUG_PROM
+void
+prom_dump_mschunks_mapping(void)
+{
+        unsigned long offset = reloc_offset();
+	struct msChunks *_msChunks = PTRRELOC(&msChunks);
+	unsigned long chunk;
+
+        prom_print(RELOC("\nprom_dump_mschunks_mapping:\n"));
+        prom_print(RELOC("    msChunks.num_chunks         = 0x"));
+        prom_print_hex(_msChunks->num_chunks);
+	prom_print_nl();
+        prom_print(RELOC("    msChunks.chunk_size         = 0x"));
+        prom_print_hex(_msChunks->chunk_size);
+	prom_print_nl();
+        prom_print(RELOC("    msChunks.chunk_shift        = 0x"));
+        prom_print_hex(_msChunks->chunk_shift);
+	prom_print_nl();
+        prom_print(RELOC("    msChunks.chunk_mask         = 0x"));
+        prom_print_hex(_msChunks->chunk_mask);
+	prom_print_nl();
+        prom_print(RELOC("    msChunks.abs                = 0x"));
+        prom_print_hex(_msChunks->abs);
+	prom_print_nl();
+
+        prom_print(RELOC("    msChunks mapping:\n"));
+	for(chunk=0; chunk < _msChunks->num_chunks ;chunk++) {
+        	prom_print(RELOC("        phys 0x"));
+        	prom_print_hex(chunk);
+        	prom_print(RELOC(" -> abs 0x"));
+        	prom_print_hex(PTRRELOC(_msChunks->abs)[chunk]);
+		prom_print_nl();
+	}
+
+}
+#endif /* DEBUG_PROM */
+#endif /* CONFIG_MSCHUNKS */
+
+#ifdef DEBUG_PROM
+void
+prom_dump_lmb(void)
+{
+        unsigned long i;
+        unsigned long offset = reloc_offset();
+	struct lmb *_lmb  = PTRRELOC(&lmb);
+
+        prom_print(RELOC("\nprom_dump_lmb:\n"));
+        prom_print(RELOC("    memory.cnt                  = 0x"));
+        prom_print_hex(_lmb->memory.cnt);
+	prom_print_nl();
+        prom_print(RELOC("    memory.size                 = 0x"));
+        prom_print_hex(_lmb->memory.size);
+	prom_print_nl();
+        prom_print(RELOC("    memory.lcd_size             = 0x"));
+        prom_print_hex(_lmb->memory.lcd_size);
+	prom_print_nl();
+        for (i=0; i < _lmb->memory.cnt ;i++) {
+                prom_print(RELOC("    memory.region[0x"));
+		prom_print_hex(i);
+		prom_print(RELOC("].base       = 0x"));
+                prom_print_hex(_lmb->memory.region[i].base);
+		prom_print_nl();
+                prom_print(RELOC("                      .physbase = 0x"));
+                prom_print_hex(_lmb->memory.region[i].physbase);
+		prom_print_nl();
+                prom_print(RELOC("                      .size     = 0x"));
+                prom_print_hex(_lmb->memory.region[i].size);
+		prom_print_nl();
+                prom_print(RELOC("                      .type     = 0x"));
+                prom_print_hex(_lmb->memory.region[i].type);
+		prom_print_nl();
+        }
+
+	prom_print_nl();
+        prom_print(RELOC("    reserved.cnt                  = 0x"));
+        prom_print_hex(_lmb->reserved.cnt);
+	prom_print_nl();
+        prom_print(RELOC("    reserved.size                 = 0x"));
+        prom_print_hex(_lmb->reserved.size);
+	prom_print_nl();
+        prom_print(RELOC("    reserved.lcd_size             = 0x"));
+        prom_print_hex(_lmb->reserved.lcd_size);
+	prom_print_nl();
+        for (i=0; i < _lmb->reserved.cnt ;i++) {
+                prom_print(RELOC("    reserved.region[0x"));
+		prom_print_hex(i);
+		prom_print(RELOC("].base       = 0x"));
+                prom_print_hex(_lmb->reserved.region[i].base);
+		prom_print_nl();
+                prom_print(RELOC("                      .physbase = 0x"));
+                prom_print_hex(_lmb->reserved.region[i].physbase);
+		prom_print_nl();
+                prom_print(RELOC("                      .size     = 0x"));
+                prom_print_hex(_lmb->reserved.region[i].size);
+		prom_print_nl();
+                prom_print(RELOC("                      .type     = 0x"));
+                prom_print_hex(_lmb->reserved.region[i].type);
+		prom_print_nl();
+        }
+}
+#endif /* DEBUG_PROM */
+
+
+void
+prom_initialize_tce_table(void)
+{
+	phandle node;
+	ihandle phb_node;
+        unsigned long offset = reloc_offset();
+	char compatible[64], path[64], type[64], model[64];
+	unsigned long i, table = 0;
+	unsigned long base, vbase, align;
+	unsigned int minalign, minsize;
+	struct _of_tce_table *prom_tce_table = RELOC(of_tce_table);
+	unsigned long tce_entry, *tce_entryp;
+
+#ifdef DEBUG_PROM
+	prom_print(RELOC("starting prom_initialize_tce_table\n"));
+#endif
+
+	/* Search all nodes looking for PHBs. */
+	for (node = 0; prom_next_node(&node); ) {
+		compatible[0] = 0;
+		type[0] = 0;
+		model[0] = 0;
+		call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
+			  compatible, sizeof(compatible));
+		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
+			  type, sizeof(type));
+		call_prom(RELOC("getprop"), 4, 1, node, RELOC("model"),
+			  model, sizeof(model));
+
+		/* Keep the old logic in tack to avoid regression. */
+		if (compatible[0] != 0) {
+			if((strstr(compatible, RELOC("python")) == NULL) &&
+			   (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
+			   (strstr(compatible, RELOC("Winnipeg")) == NULL))
+				continue;
+		} else if (model[0] != 0) {
+			if ((strstr(model, RELOC("ython")) == NULL) &&
+			    (strstr(model, RELOC("peedwagon")) == NULL) &&
+			    (strstr(model, RELOC("innipeg")) == NULL))
+				continue;
+		} else {
+			prom_print(RELOC("No known I/O bridge chip found.\n"));
+		}
+
+		if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL)) {
+			continue;
+		}
+
+		if (call_prom(RELOC("getprop"), 4, 1, node, 
+			     RELOC("tce-table-minalign"), &minalign, 
+			     sizeof(minalign)) < 0) {
+			minalign = 0;
+		}
+
+		if (call_prom(RELOC("getprop"), 4, 1, node, 
+			     RELOC("tce-table-minsize"), &minsize, 
+			     sizeof(minsize)) < 0) {
+			minsize = 4UL << 20;
+		}
+
+		/* Even though we read what OF wants, we just set the table
+		 * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
+		 * By doing this, we avoid the pitfalls of trying to DMA to
+		 * MMIO space and the DMA alias hole.
+		 */
+		minsize = 4UL << 20;
+
+		/* Align to the greater of the align or size */
+		align = (minalign < minsize) ? minsize : minalign;
+
+		/* Carve out storage for the TCE table. */
+		base = lmb_alloc(minsize, align);
+
+		if ( !base ) {
+			prom_print(RELOC("ERROR, cannot find space for TCE table.\n"));
+			prom_exit();
+		}
+
+		vbase = absolute_to_virt(base);
+
+		/* Save away the TCE table attributes for later use. */
+		prom_tce_table[table].node = node;
+		prom_tce_table[table].base = vbase;
+		prom_tce_table[table].size = minsize;
+
+#ifdef DEBUG_PROM
+		prom_print(RELOC("TCE table: 0x"));
+		prom_print_hex(table);
+		prom_print_nl();
+
+		prom_print(RELOC("\tnode = 0x"));
+		prom_print_hex(node);
+		prom_print_nl();
+
+		prom_print(RELOC("\tbase = 0x"));
+		prom_print_hex(vbase);
+		prom_print_nl();
+
+		prom_print(RELOC("\tsize = 0x"));
+		prom_print_hex(minsize);
+		prom_print_nl();
+#endif
+
+		/* Initialize the table to have a one-to-one mapping
+		 * over the allocated size.
+		 */
+		tce_entryp = (unsigned long *)base;
+		for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
+			tce_entry = (i << PAGE_SHIFT);
+			tce_entry |= 0x3;
+			*tce_entryp = tce_entry;
+		}
+
+		/* Call OF to setup the TCE hardware */
+		if (call_prom(RELOC("package-to-path"), 3, 1, node,
+                             path, 255) <= 0) {
+                        prom_print(RELOC("package-to-path failed\n"));
+                } else {
+                        prom_print(RELOC("opened "));
+                        prom_print(path);
+                        prom_print_nl();
+                }
+
+                phb_node = (ihandle)call_prom(RELOC("open"), 1, 1, path);
+                if ( (long)phb_node <= 0) {
+                        prom_print(RELOC("open failed\n"));
+                } else {
+                        prom_print(RELOC("open success\n"));
+                }
+                call_prom(RELOC("call-method"), 6, 0,
+                             RELOC("set-64-bit-addressing"),
+			     phb_node,
+			     -1,
+                             minsize, 
+                             base & 0xffffffff,
+                             (base >> 32) & 0xffffffff);
+                call_prom(RELOC("close"), 1, 0, phb_node);
+
+		table++;
+	}
+
+	/* Flag the first invalid entry */
+	prom_tce_table[table].node = 0;
+#ifdef DEBUG_PROM
+	prom_print(RELOC("ending prom_initialize_tce_table\n"));
+#endif
+}
+
+/*
+ * With CHRP SMP we need to use the OF to start the other
+ * processors so we can't wait until smp_boot_cpus (the OF is
+ * trashed by then) so we have to put the processors into
+ * a holding pattern controlled by the kernel (not OF) before
+ * we destroy the OF.
+ *
+ * This uses a chunk of low memory, puts some holding pattern
+ * code there and sends the other processors off to there until
+ * smp_boot_cpus tells them to do something.  The holding pattern
+ * checks that address until its cpu # is there, when it is that
+ * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
+ * of setting those values.
+ *
+ * We also use physical address 0x4 here to tell when a cpu
+ * is in its holding pattern code.
+ *
+ * Fixup comment... DRENG / PPPBBB - Peter
+ *
+ * -- Cort
+ */
+static void
+prom_hold_cpus(unsigned long mem)
+{
+	unsigned long i;
+	unsigned int reg;
+	phandle node;
+	unsigned long offset = reloc_offset();
+	char type[64], *path;
+	int cpuid = 0;
+	extern void __secondary_hold(void);
+        extern unsigned long __secondary_hold_spinloop;
+        extern unsigned long __secondary_hold_acknowledge;
+        unsigned long *spinloop     = __v2a(&__secondary_hold_spinloop);
+        unsigned long *acknowledge  = __v2a(&__secondary_hold_acknowledge);
+        unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));
+        struct naca_struct *_naca = RELOC(naca);
+	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
+	struct prom_t *_prom = PTRRELOC(&prom);
+
+	/* Initially, we must have one active CPU. */
+	_naca->processorCount = 1;
+
+#ifdef DEBUG_PROM
+	prom_print(RELOC("prom_hold_cpus: start...\n"));
+	prom_print(RELOC("    1) spinloop       = 0x"));
+	prom_print_hex(spinloop);
+	prom_print_nl();
+	prom_print(RELOC("    1) *spinloop      = 0x"));
+	prom_print_hex(*spinloop);
+	prom_print_nl();
+	prom_print(RELOC("    1) acknowledge    = 0x"));
+	prom_print_hex(acknowledge);
+	prom_print_nl();
+	prom_print(RELOC("    1) *acknowledge   = 0x"));
+	prom_print_hex(*acknowledge);
+	prom_print_nl();
+	prom_print(RELOC("    1) secondary_hold = 0x"));
+	prom_print_hex(secondary_hold);
+	prom_print_nl();
+#endif
+
+        /* Set the common spinloop variable, so all of the secondary cpus
+	 * will block when they are awakened from their OF spinloop.
+	 * This must occur for both SMP and non SMP kernels, since OF will
+	 * be trashed when we move the kernel.
+         */
+        *spinloop = 0;
+
+#ifdef CONFIG_HMT
+	for (i=0; i < NR_CPUS; i++) {
+		RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
+	}
+#endif
+	/* look for cpus */
+	for (node = 0; prom_next_node(&node); ) {
+		type[0] = 0;
+		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
+			  type, sizeof(type));
+		if (strcmp(type, RELOC("cpu")) != 0)
+			continue;
+
+		/* Skip non-configured cpus. */
+		call_prom(RELOC("getprop"), 4, 1, node, RELOC("status"),
+			  type, sizeof(type));
+		if (strcmp(type, RELOC("okay")) != 0)
+			continue;
+
+                reg = -1;
+		call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
+			  &reg, sizeof(reg));
+
+		/* Only need to start secondary procs, not ourself. */
+		if ( reg == _prom->cpu )
+			continue;
+
+		path = (char *) mem;
+		memset(path, 0, 256);
+		if ((long) call_prom(RELOC("package-to-path"), 3, 1,
+				     node, path, 255) < 0)
+			continue;
+
+		cpuid++;
+
+#ifdef DEBUG_PROM
+		prom_print_nl();
+		prom_print(RELOC("cpuid        = 0x"));
+		prom_print_hex(cpuid);
+		prom_print_nl();
+		prom_print(RELOC("cpu hw idx   = 0x"));
+		prom_print_hex(reg);
+		prom_print_nl();
+#endif
+		_xPaca[cpuid].xHwProcNum = reg;
+
+		prom_print(RELOC("starting cpu "));
+		prom_print(path);
+
+		/* Init the acknowledge var which will be reset by
+		 * the secondary cpu when it awakens from its OF
+		 * spinloop.
+		 */
+		*acknowledge = (unsigned long)-1;
+
+#ifdef DEBUG_PROM
+		prom_print(RELOC("    3) spinloop       = 0x"));
+		prom_print_hex(spinloop);
+		prom_print_nl();
+		prom_print(RELOC("    3) *spinloop      = 0x"));
+		prom_print_hex(*spinloop);
+		prom_print_nl();
+		prom_print(RELOC("    3) acknowledge    = 0x"));
+		prom_print_hex(acknowledge);
+		prom_print_nl();
+		prom_print(RELOC("    3) *acknowledge   = 0x"));
+		prom_print_hex(*acknowledge);
+		prom_print_nl();
+		prom_print(RELOC("    3) secondary_hold = 0x"));
+		prom_print_hex(secondary_hold);
+		prom_print_nl();
+		prom_print(RELOC("    3) cpuid = 0x"));
+		prom_print_hex(cpuid);
+		prom_print_nl();
+#endif
+		call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid);
+		prom_print(RELOC("..."));
+		for ( i = 0 ; (i < 100000000) && 
+			      (*acknowledge == ((unsigned long)-1)); i++ ) ;
+#ifdef DEBUG_PROM
+		{
+			unsigned long *p = 0x0;
+			prom_print(RELOC("    4) 0x0 = 0x"));
+			prom_print_hex(*p);
+			prom_print_nl();
+		}
+#endif
+		if (*acknowledge == cpuid) {
+			prom_print(RELOC("ok\n"));
+			/* Set the number of active processors. */
+			_naca->processorCount++;
+		} else {
+			prom_print(RELOC("failed: "));
+			prom_print_hex(*acknowledge);
+			prom_print_nl();
+		}
+	}
+#ifdef CONFIG_HMT
+	/* Only enable HMT on processors that provide support. */
+	if (__is_processor(PV_PULSAR) || 
+	    __is_processor(PV_ICESTAR) ||
+	    __is_processor(PV_SSTAR)) {
+		prom_print(RELOC("    starting secondary threads\n"));
+
+		for (i=0; i < _naca->processorCount ;i++) {
+			unsigned long threadid = _naca->processorCount*2-1-i;
+			
+			if (i == 0) {
+				unsigned long pir = _get_PIR();
+				if (__is_processor(PV_PULSAR)) {
+					RELOC(hmt_thread_data)[i].pir = 
+						pir & 0x1f;
+				} else {
+					RELOC(hmt_thread_data)[i].pir = 
+						pir & 0x3ff;
+				}
+			}
+			
+			RELOC(hmt_thread_data)[i].threadid = threadid;
+#ifdef DEBUG_PROM
+			prom_print(RELOC("        cpuid 0x"));
+			prom_print_hex(i);
+			prom_print(RELOC(" maps to threadid 0x"));
+			prom_print_hex(threadid);
+			prom_print_nl();
+			prom_print(RELOC(" pir 0x"));
+			prom_print_hex(RELOC(hmt_thread_data)[i].pir);
+			prom_print_nl();
+#endif
+			_xPaca[threadid].xHwProcNum = _xPaca[i].xHwProcNum+1;
+		}
+		_naca->processorCount *= 2;
+	} else {
+		prom_print(RELOC("Processor is not HMT capable\n"));
+	}
+#endif
+	
+#ifdef DEBUG_PROM
+	prom_print(RELOC("prom_hold_cpus: end...\n"));
+#endif
+}
+
+
+/*
+ * We enter here early on, when the Open Firmware prom is still
+ * handling exceptions and the MMU hash table for us.
+ */
+
+unsigned long __init
+prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
+	  unsigned long r6, unsigned long r7, yaboot_debug_t *yaboot)
+{
+	int chrp = 0;
+	unsigned long mem;
+	ihandle prom_mmu, prom_op, prom_root, prom_cpu;
+	phandle cpu_pkg;
+	unsigned long offset = reloc_offset();
+	long l;
+	char *p, *d;
+ 	unsigned long phys;
+        u32 getprop_rval;
+        struct naca_struct   *_naca = RELOC(naca);
+	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
+	struct prom_t *_prom = PTRRELOC(&prom);
+
+	/* Default machine type. */
+	_naca->platform = PLATFORM_PSERIES;
+	/* Reset klimit to take into account the embedded system map */
+	if (RELOC(embedded_sysmap_end))
+		RELOC(klimit) = __va(PAGE_ALIGN(RELOC(embedded_sysmap_end)));
+
+	/* Get a handle to the prom entry point before anything else */
+	_prom->entry = pp;
+	_prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6);
+	if ( _prom->bi_recs != NULL ) {
+		RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs + _prom->bi_recs->data[1]);
+	}
+
+#ifdef DEBUG_YABOOT
+	call_yaboot(yaboot->dummy,offset>>32,offset&0xffffffff);
+	call_yaboot(yaboot->printf, RELOC("offset = 0x%08x%08x\n"), LONG_MSW(offset), LONG_LSW(offset));
+#endif
+
+ 	/* Default */
+ 	phys = KERNELBASE - offset;
+
+#ifdef DEBUG_YABOOT
+	call_yaboot(yaboot->printf, RELOC("phys = 0x%08x%08x\n"), LONG_MSW(phys), LONG_LSW(phys));
+#endif
+
+
+#ifdef DEBUG_YABOOT
+	_prom->yaboot = yaboot;
+	call_yaboot(yaboot->printf, RELOC("pp = 0x%08x%08x\n"), LONG_MSW(pp), LONG_LSW(pp));
+	call_yaboot(yaboot->printf, RELOC("prom = 0x%08x%08x\n"), LONG_MSW(_prom->entry), LONG_LSW(_prom->entry));
+#endif
+
+	/* First get a handle for the stdout device */
+	_prom->chosen = (ihandle)call_prom(RELOC("finddevice"), 1, 1,
+				       RELOC("/chosen"));
+
+#ifdef DEBUG_YABOOT
+	call_yaboot(yaboot->printf, RELOC("prom->chosen = 0x%08x%08x\n"), LONG_MSW(_prom->chosen), LONG_LSW(_prom->chosen));
+#endif
+
+	if ((long)_prom->chosen <= 0)
+		prom_exit();
+
+        if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
+			    RELOC("stdout"), &getprop_rval,
+			    sizeof(getprop_rval)) <= 0)
+                prom_exit();
+
+        _prom->stdout = (ihandle)(unsigned long)getprop_rval;
+
+#ifdef DEBUG_YABOOT
+        if (_prom->stdout == 0) {
+	    call_yaboot(yaboot->printf, RELOC("prom->stdout = 0x%08x%08x\n"), LONG_MSW(_prom->stdout), LONG_LSW(_prom->stdout));
+        }
+
+	call_yaboot(yaboot->printf, RELOC("prom->stdout = 0x%08x%08x\n"), LONG_MSW(_prom->stdout), LONG_LSW(_prom->stdout));
+#endif
+
+#ifdef DEBUG_YABOOT
+	call_yaboot(yaboot->printf, RELOC("Location: 0x11\n"));
+#endif
+
+	mem = RELOC(klimit) - offset; 
+#ifdef DEBUG_YABOOT
+	call_yaboot(yaboot->printf, RELOC("Location: 0x11b\n"));
+#endif
+
+	/* Get the full OF pathname of the stdout device */
+	p = (char *) mem;
+	memset(p, 0, 256);
+	call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255);
+	RELOC(of_stdout_device) = PTRUNRELOC(p);
+	mem += strlen(p) + 1;
+
+	getprop_rval = 1;
+	prom_root = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));
+	if (prom_root != (ihandle)-1) {
+                call_prom(RELOC("getprop"), 4, 1,
+                    prom_root, RELOC("#size-cells"),
+		    &getprop_rval, sizeof(getprop_rval));
+	}
+	_prom->encode_phys_size = (getprop_rval==1) ? 32 : 64;
+
+#ifdef DEBUG_PROM
+	prom_print(RELOC("DRENG:    Detect OF version...\n"));
+#endif
+	/* Find the OF version */
+	prom_op = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/openprom"));
+	if (prom_op != (ihandle)-1) {
+		char model[64];
+		long sz;
+		sz = (long)call_prom(RELOC("getprop"), 4, 1, prom_op,
+				    RELOC("model"), model, 64);
+		if (sz > 0) {
+			char *c;
+			/* hack to skip the ibm chrp firmware # */
+			if ( strncmp(model,RELOC("IBM"),3) ) {
+				for (c = model; *c; c++)
+					if (*c >= '0' && *c <= '9') {
+						_prom->version = *c - '0';
+						break;
+					}
+			}
+			else
+				chrp = 1;
+		}
+	}
+	if (_prom->version >= 3)
+		prom_print(RELOC("OF Version 3 detected.\n"));
+
+
+	/* Determine which cpu is actually running right _now_ */
+        if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
+			    RELOC("cpu"), &getprop_rval,
+			    sizeof(getprop_rval)) <= 0)
+                prom_exit();
+
+	prom_cpu = (ihandle)(unsigned long)getprop_rval;
+	cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu);
+	call_prom(RELOC("getprop"), 4, 1,
+		cpu_pkg, RELOC("reg"),
+		&getprop_rval, sizeof(getprop_rval));
+	_prom->cpu = (int)(unsigned long)getprop_rval;
+	_xPaca[0].xHwProcNum = _prom->cpu;
+
+#ifdef DEBUG_PROM
+  	prom_print(RELOC("Booting CPU hw index = 0x"));
+  	prom_print_hex(_prom->cpu);
+  	prom_print_nl();
+#endif
+
+	/* Get the boot device and translate it to a full OF pathname. */
+	p = (char *) mem;
+	l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
+			    RELOC("bootpath"), p, 1<<20);
+	if (l > 0) {
+		p[l] = 0;	/* should already be null-terminated */
+		RELOC(bootpath) = PTRUNRELOC(p);
+		mem += l + 1;
+		d = (char *) mem;
+		*d = 0;
+		call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);
+		RELOC(bootdevice) = PTRUNRELOC(d);
+		mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1);
+	}
+
+	mem = prom_initialize_lmb(mem);
+
+	mem = prom_bi_rec_reserve(mem);
+
+	mem = prom_instantiate_rtas(mem);
+        
+        /* Initialize some system info into the Naca early... */
+        mem = prom_initialize_naca(mem);
+
+        /* If we are on an SMP machine, then we *MUST* do the
+         * following, regardless of whether we have an SMP
+         * kernel or not.
+         */
+        if ( _naca->processorCount > 1 )
+	        prom_hold_cpus(mem);
+
+	mem = check_display(mem);
+
+#ifdef DEBUG_PROM
+	prom_print(RELOC("copying OF device tree...\n"));
+#endif
+	mem = copy_device_tree(mem);
+
+	RELOC(klimit) = mem + offset;
+
+	lmb_reserve(0, __pa(RELOC(klimit)));
+
+	if (_naca->platform == PLATFORM_PSERIES)
+		prom_initialize_tce_table();
+
+ 	if ((long) call_prom(RELOC("getprop"), 4, 1,
+				_prom->chosen,
+				RELOC("mmu"),
+				&getprop_rval,
+				sizeof(getprop_rval)) <= 0) {	
+		prom_print(RELOC(" no MMU found\n"));
+                prom_exit();
+	}
+
+	/* We assume the phys. address size is 3 cells */
+	RELOC(prom_mmu) = (ihandle)(unsigned long)getprop_rval;
+
+	if ((long)call_prom(RELOC("call-method"), 4, 4,
+				RELOC("translate"),
+				prom_mmu,
+				(void *)(KERNELBASE - offset),
+				(void *)1) != 0) {
+		prom_print(RELOC(" (translate failed) "));
+	} else {
+		prom_print(RELOC(" (translate ok) "));
+		phys = (unsigned long)_prom->args.rets[3];
+	}
+
+	/* If OpenFirmware version >= 3, then use quiesce call */
+	if (_prom->version >= 3) {
+		prom_print(RELOC("Calling quiesce ...\n"));
+		call_prom(RELOC("quiesce"), 0, 0);
+		phys = KERNELBASE - offset;
+	}
+
+	prom_print(RELOC("returning from prom_init\n"));
+	return phys;
+}
+
+
+static int
+prom_set_color(ihandle ih, int i, int r, int g, int b)
+{
+	unsigned long offset = reloc_offset();
+
+	return (int)(long)call_prom(RELOC("call-method"), 6, 1,
+		                    RELOC("color!"),
+                                    ih,
+                                    (void *)(long) i,
+                                    (void *)(long) b,
+                                    (void *)(long) g,
+                                    (void *)(long) r );
+}
+
+/*
+ * If we have a display that we don't know how to drive,
+ * we will want to try to execute OF's open method for it
+ * later.  However, OF will probably fall over if we do that
+ * we've taken over the MMU.
+ * So we check whether we will need to open the display,
+ * and if so, open it now.
+ */
+static unsigned long __init
+check_display(unsigned long mem)
+{
+	phandle node;
+	ihandle ih;
+	int i;
+	unsigned long offset = reloc_offset();
+        struct prom_t *_prom = PTRRELOC(&prom);
+	char type[64], *path;
+	static unsigned char default_colors[] = {
+		0x00, 0x00, 0x00,
+		0x00, 0x00, 0xaa,
+		0x00, 0xaa, 0x00,
+		0x00, 0xaa, 0xaa,
+		0xaa, 0x00, 0x00,
+		0xaa, 0x00, 0xaa,
+		0xaa, 0xaa, 0x00,
+		0xaa, 0xaa, 0xaa,
+		0x55, 0x55, 0x55,
+		0x55, 0x55, 0xff,
+		0x55, 0xff, 0x55,
+		0x55, 0xff, 0xff,
+		0xff, 0x55, 0x55,
+		0xff, 0x55, 0xff,
+		0xff, 0xff, 0x55,
+		0xff, 0xff, 0xff
+	};
+
+	_prom->disp_node = 0;
+
+	for (node = 0; prom_next_node(&node); ) {
+		type[0] = 0;
+		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
+			  type, sizeof(type));
+		if (strcmp(type, RELOC("display")) != 0)
+			continue;
+		/* It seems OF doesn't null-terminate the path :-( */
+		path = (char *) mem;
+		memset(path, 0, 256);
+		if ((long) call_prom(RELOC("package-to-path"), 3, 1,
+				    node, path, 255) < 0)
+			continue;
+		prom_print(RELOC("opening display "));
+		prom_print(path);
+		ih = (ihandle)call_prom(RELOC("open"), 1, 1, path);
+		if (ih == (ihandle)0 || ih == (ihandle)-1) {
+			prom_print(RELOC("... failed\n"));
+			continue;
+		}
+		prom_print(RELOC("... ok\n"));
+
+		if (_prom->disp_node == 0)
+			_prom->disp_node = (ihandle)(unsigned long)node;
+
+		/* Setup a useable color table when the appropriate
+		 * method is available. Should update this to set-colors */
+		for (i = 0; i < 32; i++)
+			if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
+					   RELOC(default_colors)[i*3+1],
+					   RELOC(default_colors)[i*3+2]) != 0)
+				break;
+
+#ifdef CONFIG_FB
+		for (i = 0; i < LINUX_LOGO_COLORS; i++)
+			if (prom_set_color(ih, i + 32,
+					   RELOC(linux_logo_red)[i],
+					   RELOC(linux_logo_green)[i],
+					   RELOC(linux_logo_blue)[i]) != 0)
+				break;
+#endif /* CONFIG_FB */
+
+		/*
+		 * If this display is the device that OF is using for stdout,
+		 * move it to the front of the list.
+		 */
+		mem += strlen(path) + 1;
+		i = RELOC(prom_num_displays)++;
+		if (RELOC(of_stdout_device) != 0 && i > 0
+		    && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
+			for (; i > 0; --i)
+				RELOC(prom_display_paths[i]) = RELOC(prom_display_paths[i-1]);
+		}
+		RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
+		if (RELOC(prom_num_displays) >= FB_MAX)
+			break;
+	}
+	return DOUBLEWORD_ALIGN(mem);
+}
+
+void
+virt_irq_init(void)
+{
+	int i;
+	for (i = 0; i < NR_IRQS; i++)
+		virt_irq_to_real_map[i] = UNDEFINED_IRQ;
+	for (i = 0; i < NR_HW_IRQS; i++)
+		real_irq_to_virt_map[i] = UNDEFINED_IRQ;
+}
+
+/* Create a mapping for a real_irq if it doesn't already exist.
+ * Return the virtual irq as a convenience.
+ */
+unsigned long
+virt_irq_create_mapping(unsigned long real_irq)
+{
+	unsigned long virq;
+	if (naca->interrupt_controller == IC_OPEN_PIC)
+		return real_irq;	/* no mapping for openpic (for now) */
+	virq = real_irq_to_virt(real_irq);
+	if (virq == UNDEFINED_IRQ) {
+		/* Assign a virtual IRQ number */
+		if (real_irq < NR_IRQS && virt_irq_to_real(real_irq) == UNDEFINED_IRQ) {
+			/* A 1-1 mapping will work. */
+			virq = real_irq;
+		} else {
+			while (last_virt_irq < NR_IRQS &&
+			       virt_irq_to_real(++last_virt_irq) != UNDEFINED_IRQ)
+				/* skip irq's in use */;
+			if (last_virt_irq >= NR_IRQS)
+				panic("Too many IRQs are required on this system.  NR_IRQS=%d\n", NR_IRQS);
+			virq = last_virt_irq;
+		}
+		virt_irq_to_real_map[virq] = real_irq;
+		real_irq_to_virt_map[real_irq] = virq;
+	}
+	return virq;
+}
+
+
+static int __init
+prom_next_node(phandle *nodep)
+{
+	phandle node;
+	unsigned long offset = reloc_offset();
+
+	if ((node = *nodep) != 0
+	    && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)
+		return 1;
+	if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
+		return 1;
+	for (;;) {
+		if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)
+			return 0;
+		if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
+			return 1;
+	}
+}
+
+/*
+ * Make a copy of the device tree from the PROM.
+ */
+static unsigned long __init
+copy_device_tree(unsigned long mem_start)
+{
+	phandle root;
+	unsigned long new_start;
+	struct device_node **allnextp;
+	unsigned long offset = reloc_offset();
+	unsigned long mem_end = mem_start + (8<<20);
+
+	root = call_prom(RELOC("peer"), 1, 1, (phandle)0);
+	if (root == (phandle)0) {
+		prom_print(RELOC("couldn't get device tree root\n"));
+		prom_exit();
+	}
+	allnextp = &RELOC(allnodes);
+	mem_start = DOUBLEWORD_ALIGN(mem_start);
+	new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
+	*allnextp = 0;
+	return new_start;
+}
+
+__init
+static unsigned long
+inspect_node(phandle node, struct device_node *dad,
+	     unsigned long mem_start, unsigned long mem_end,
+	     struct device_node ***allnextpp)
+{
+	int l;
+	phandle child;
+	struct device_node *np;
+	struct property *pp, **prev_propp;
+	char *prev_name, *namep;
+	unsigned char *valp;
+	unsigned long offset = reloc_offset();
+
+	np = (struct device_node *) mem_start;
+	mem_start += sizeof(struct device_node);
+	memset(np, 0, sizeof(*np));
+	np->node = node;
+	**allnextpp = PTRUNRELOC(np);
+	*allnextpp = &np->allnext;
+	if (dad != 0) {
+		np->parent = PTRUNRELOC(dad);
+		/* we temporarily use the `next' field as `last_child'. */
+		if (dad->next == 0)
+			dad->child = PTRUNRELOC(np);
+		else
+			dad->next->sibling = PTRUNRELOC(np);
+		dad->next = np;
+	}
+
+	/* get and store all properties */
+	prev_propp = &np->properties;
+	prev_name = RELOC("");
+	for (;;) {
+		pp = (struct property *) mem_start;
+		namep = (char *) (pp + 1);
+		pp->name = PTRUNRELOC(namep);
+		if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,
+				    namep) <= 0)
+			break;
+		mem_start = DOUBLEWORD_ALIGN((unsigned long)namep + strlen(namep) + 1);
+		prev_name = namep;
+		valp = (unsigned char *) mem_start;
+		pp->value = PTRUNRELOC(valp);
+		pp->length = (int)(long)
+			call_prom(RELOC("getprop"), 4, 1, node, namep,
+				  valp, mem_end - mem_start);
+		if (pp->length < 0)
+			continue;
+		mem_start = DOUBLEWORD_ALIGN(mem_start + pp->length);
+		*prev_propp = PTRUNRELOC(pp);
+		prev_propp = &pp->next;
+	}
+	*prev_propp = 0;
+
+	/* get the node's full name */
+	l = (long) call_prom(RELOC("package-to-path"), 3, 1, node,
+			    (char *) mem_start, mem_end - mem_start);
+	if (l >= 0) {
+		np->full_name = PTRUNRELOC((char *) mem_start);
+		*(char *)(mem_start + l) = 0;
+		mem_start = DOUBLEWORD_ALIGN(mem_start + l + 1);
+	}
+
+	/* do all our children */
+	child = call_prom(RELOC("child"), 1, 1, node);
+	while (child != (phandle)0) {
+		mem_start = inspect_node(child, np, mem_start, mem_end,
+					 allnextpp);
+		child = call_prom(RELOC("peer"), 1, 1, child);
+	}
+
+	return mem_start;
+}
+
+/*
+ * finish_device_tree is called once things are running normally
+ * (i.e. with text and data mapped to the address they were linked at).
+ * It traverses the device tree and fills in the name, type,
+ * {n_}addrs and {n_}intrs fields of each node.
+ */
+void __init
+finish_device_tree(void)
+{
+	unsigned long mem = klimit;
+
+	virt_irq_init();
+
+	mem = finish_node(allnodes, mem, NULL, 0, 0);
+	dev_tree_size = mem - (unsigned long) allnodes;
+
+	mem = _ALIGN(mem, PAGE_SIZE);
+	lmb_reserve(__pa(klimit), mem-klimit);
+
+	klimit = mem;
+
+	rtas.dev = find_devices("rtas");
+}
+
+static unsigned long __init
+finish_node(struct device_node *np, unsigned long mem_start,
+	    interpret_func *ifunc, int naddrc, int nsizec)
+{
+	struct device_node *child;
+	int *ip;
+
+	np->name = get_property(np, "name", 0);
+	np->type = get_property(np, "device_type", 0);
+
+	/* get the device addresses and interrupts */
+	if (ifunc != NULL) {
+	  mem_start = ifunc(np, mem_start, naddrc, nsizec);
+	}
+	mem_start = finish_node_interrupts(np, mem_start);
+
+	/* Look for #address-cells and #size-cells properties. */
+	ip = (int *) get_property(np, "#address-cells", 0);
+	if (ip != NULL)
+		naddrc = *ip;
+	ip = (int *) get_property(np, "#size-cells", 0);
+	if (ip != NULL)
+		nsizec = *ip;
+
+	/* the f50 sets the name to 'display' and 'compatible' to what we
+	 * expect for the name -- Cort
+	 */
+	ifunc = NULL;
+	if (!strcmp(np->name, "display"))
+		np->name = get_property(np, "compatible", 0);
+
+	if (!strcmp(np->name, "device-tree") || np->parent == NULL)
+		ifunc = interpret_root_props;
+	else if (np->type == 0)
+		ifunc = NULL;
+	else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
+		ifunc = interpret_pci_props;
+	else if (!strcmp(np->type, "isa"))
+		ifunc = interpret_isa_props;
+
+	for (child = np->child; child != NULL; child = child->sibling)
+		mem_start = finish_node(child, mem_start, ifunc,
+					naddrc, nsizec);
+
+	return mem_start;
+}
+
+/* This routine walks the interrupt tree for a given device node and gather 
+ * all necessary informations according to the draft interrupt mapping
+ * for CHRP. The current version was only tested on Apple "Core99" machines
+ * and may not handle cascaded controllers correctly.
+ */
+__init
+static unsigned long
+finish_node_interrupts(struct device_node *np, unsigned long mem_start)
+{
+	/* Finish this node */
+	unsigned int *isizep, *asizep, *interrupts, *map, *map_mask, *reg;
+	phandle *parent, map_parent;
+	struct device_node *node, *parent_node;
+	int l, isize, ipsize, asize, map_size, regpsize;
+
+	/* Currently, we don't look at all nodes with no "interrupts" property */
+
+	interrupts = (unsigned int *)get_property(np, "interrupts", &l);
+	if (interrupts == NULL)
+		return mem_start;
+	ipsize = l>>2;
+
+	reg = (unsigned int *)get_property(np, "reg", &l);
+	regpsize = l>>2;
+
+	/* We assume default interrupt cell size is 1 (bugus ?) */
+	isize = 1;
+	node = np;
+	
+	do {
+	    /* We adjust the cell size if the current parent contains an #interrupt-cells
+	     * property */
+	    isizep = (unsigned int *)get_property(node, "#interrupt-cells", &l);
+	    if (isizep)
+	    	isize = *isizep;
+
+	    /* We don't do interrupt cascade (ISA) for now, we stop on the first 
+	     * controller found
+	     */
+	    if (get_property(node, "interrupt-controller", &l)) {
+	    	int i,j;
+
+	    	np->intrs = (struct interrupt_info *) mem_start;
+		np->n_intrs = ipsize / isize;
+		mem_start += np->n_intrs * sizeof(struct interrupt_info);
+		for (i = 0; i < np->n_intrs; ++i) {
+		    np->intrs[i].line = openpic_to_irq(virt_irq_create_mapping(*interrupts++));
+		    np->intrs[i].sense = 1;
+		    if (isize > 1)
+		        np->intrs[i].sense = *interrupts++;
+		    for (j=2; j<isize; j++)
+		    	interrupts++;
+		}
+		return mem_start;
+	    }
+	    /* We lookup for an interrupt-map. This code can only handle one interrupt
+	     * per device in the map. We also don't handle #address-cells in the parent
+	     * I skip the pci node itself here, may not be necessary but I don't like it's
+	     * reg property.
+	     */
+	    if (np != node)
+	        map = (unsigned int *)get_property(node, "interrupt-map", &l);
+	     else
+	     	map = NULL;
+	    if (map && l) {
+	    	int i, found, temp_isize, temp_asize;
+	        map_size = l>>2;
+	        map_mask = (unsigned int *)get_property(node, "interrupt-map-mask", &l);
+	        asizep = (unsigned int *)get_property(node, "#address-cells", &l);
+	        if (asizep && l == sizeof(unsigned int))
+	            asize = *asizep;
+	        else
+	            asize = 0;
+	        found = 0;
+	        while (map_size>0 && !found) {
+	            found = 1;
+	            for (i=0; i<asize; i++) {
+	            	unsigned int mask = map_mask ? map_mask[i] : 0xffffffff;
+	            	if (!reg || (i>=regpsize) || ((mask & *map) != (mask & reg[i])))
+	           	    found = 0;
+	           	map++;
+	           	map_size--;
+	            }
+	            for (i=0; i<isize; i++) {
+	            	unsigned int mask = map_mask ? map_mask[i+asize] : 0xffffffff;
+	            	if ((mask & *map) != (mask & interrupts[i]))
+	            	    found = 0;
+	            	map++;
+	            	map_size--;
+	            }
+	            map_parent = *((phandle *)map);
+	            map+=1; map_size-=1;
+	            parent_node = find_phandle(map_parent);
+	            temp_isize = isize;
+		    temp_asize = 0;
+	            if (parent_node) {
+			isizep = (unsigned int *)get_property(parent_node, "#interrupt-cells", &l);
+	    		if (isizep)
+	    		    temp_isize = *isizep;
+			asizep = (unsigned int *)get_property(parent_node, "#address-cells", &l);
+			if (asizep && l == sizeof(unsigned int))
+				temp_asize = *asizep;
+	            }
+	            if (!found) {
+			map += temp_isize + temp_asize;
+			map_size -= temp_isize + temp_asize;
+	            }
+	        }
+	        if (found) {
+		    /* Mapped to a new parent.  Use the reg and interrupts specified in
+		     * the map as the new search parameters.  Then search from the parent.
+		     */
+	            node = parent_node;
+		    reg = map;
+		    regpsize = temp_asize;
+		    interrupts = map + temp_asize;
+		    ipsize = temp_isize;
+		    continue;
+	        }
+	    }
+	    /* We look for an explicit interrupt-parent.
+	     */
+	    parent = (phandle *)get_property(node, "interrupt-parent", &l);
+	    if (parent && (l == sizeof(phandle)) &&
+	    	(parent_node = find_phandle(*parent))) {
+	    	node = parent_node;
+	    	continue;
+	    }
+	    /* Default, get real parent */
+	    node = node->parent;
+	} while (node);
+
+	return mem_start;
+}
+
+int
+prom_n_addr_cells(struct device_node* np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = (int *) get_property(np, "#address-cells", 0);
+		if (ip != NULL)
+			return *ip;
+	} while (np->parent);
+	/* No #address-cells property for the root node, default to 1 */
+	return 1;
+}
+
+int
+prom_n_size_cells(struct device_node* np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = (int *) get_property(np, "#size-cells", 0);
+		if (ip != NULL)
+			return *ip;
+	} while (np->parent);
+	/* No #size-cells property for the root node, default to 1 */
+	return 1;
+}
+
+static unsigned long __init
+interpret_pci_props(struct device_node *np, unsigned long mem_start,
+		    int naddrc, int nsizec)
+{
+	struct address_range *adr;
+	struct pci_reg_property *pci_addrs;
+	int i, l;
+
+	pci_addrs = (struct pci_reg_property *)
+		get_property(np, "assigned-addresses", &l);
+	if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
+		i = 0;
+		adr = (struct address_range *) mem_start;
+		while ((l -= sizeof(struct pci_reg_property)) >= 0) {
+			adr[i].space = pci_addrs[i].addr.a_hi;
+			adr[i].address = pci_addrs[i].addr.a_lo;
+			adr[i].size = pci_addrs[i].size_lo;
+			++i;
+		}
+		np->addrs = adr;
+		np->n_addrs = i;
+		mem_start += i * sizeof(struct address_range);
+	}
+	return mem_start;
+}
+
+static unsigned long __init
+interpret_isa_props(struct device_node *np, unsigned long mem_start,
+		    int naddrc, int nsizec)
+{
+	struct isa_reg_property *rp;
+	struct address_range *adr;
+	int i, l;
+
+	rp = (struct isa_reg_property *) get_property(np, "reg", &l);
+	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
+		i = 0;
+		adr = (struct address_range *) mem_start;
+		while ((l -= sizeof(struct reg_property)) >= 0) {
+			adr[i].space = rp[i].space;
+			adr[i].address = rp[i].address
+				+ (adr[i].space? 0: _ISA_MEM_BASE);
+			adr[i].size = rp[i].size;
+			++i;
+		}
+		np->addrs = adr;
+		np->n_addrs = i;
+		mem_start += i * sizeof(struct address_range);
+	}
+
+	return mem_start;
+}
+
+static unsigned long __init
+interpret_root_props(struct device_node *np, unsigned long mem_start,
+		     int naddrc, int nsizec)
+{
+	struct address_range *adr;
+	int i, l;
+	unsigned int *rp;
+	int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
+
+	rp = (unsigned int *) get_property(np, "reg", &l);
+	if (rp != 0 && l >= rpsize) {
+		i = 0;
+		adr = (struct address_range *) mem_start;
+		while ((l -= rpsize) >= 0) {
+			adr[i].space = 0;
+			adr[i].address = rp[naddrc - 1];
+			adr[i].size = rp[naddrc + nsizec - 1];
+			++i;
+			rp += naddrc + nsizec;
+		}
+		np->addrs = adr;
+		np->n_addrs = i;
+		mem_start += i * sizeof(struct address_range);
+	}
+
+	return mem_start;
+}
+
+/*
+ * Work out the sense (active-low level / active-high edge)
+ * of each interrupt from the device tree.
+ */
+void __init
+prom_get_irq_senses(unsigned char *senses, int off, int max)
+{
+	struct device_node *np;
+	int i, j;
+
+	/* default to level-triggered */
+	memset(senses, 1, max - off);
+
+	for (np = allnodes; np != 0; np = np->allnext) {
+		for (j = 0; j < np->n_intrs; j++) {
+			i = np->intrs[j].line;
+			if (i >= off && i < max)
+				senses[i-off] = np->intrs[j].sense;
+		}
+	}
+}
+
+/*
+ * Construct and return a list of the device_nodes with a given name.
+ */
+struct device_node *
+find_devices(const char *name)
+{
+	struct device_node *head, **prevp, *np;
+
+	prevp = &head;
+	for (np = allnodes; np != 0; np = np->allnext) {
+		if (np->name != 0 && strcasecmp(np->name, name) == 0) {
+			*prevp = np;
+			prevp = &np->next;
+		}
+	}
+	*prevp = 0;
+	return head;
+}
+
+/*
+ * Construct and return a list of the device_nodes with a given type.
+ */
+struct device_node *
+find_type_devices(const char *type)
+{
+	struct device_node *head, **prevp, *np;
+
+	prevp = &head;
+	for (np = allnodes; np != 0; np = np->allnext) {
+		if (np->type != 0 && strcasecmp(np->type, type) == 0) {
+			*prevp = np;
+			prevp = &np->next;
+		}
+	}
+	*prevp = 0;
+	return head;
+}
+
+/*
+ * Returns all nodes linked together
+ */
+struct device_node * __openfirmware
+find_all_nodes(void)
+{
+	struct device_node *head, **prevp, *np;
+
+	prevp = &head;
+	for (np = allnodes; np != 0; np = np->allnext) {
+		*prevp = np;
+		prevp = &np->next;
+	}
+	*prevp = 0;
+	return head;
+}
+
+/* Checks if the given "compat" string matches one of the strings in
+ * the device's "compatible" property
+ */
+int
+device_is_compatible(struct device_node *device, const char *compat)
+{
+	const char* cp;
+	int cplen, l;
+
+	cp = (char *) get_property(device, "compatible", &cplen);
+	if (cp == NULL)
+		return 0;
+	while (cplen > 0) {
+		if (strncasecmp(cp, compat, strlen(compat)) == 0)
+			return 1;
+		l = strlen(cp) + 1;
+		cp += l;
+		cplen -= l;
+	}
+
+	return 0;
+}
+
+
+/*
+ * Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+int
+machine_is_compatible(const char *compat)
+{
+	struct device_node *root;
+	
+	root = find_path_device("/");
+	if (root == 0)
+		return 0;
+	return device_is_compatible(root, compat);
+}
+
+/*
+ * Construct and return a list of the device_nodes with a given type
+ * and compatible property.
+ */
+struct device_node *
+find_compatible_devices(const char *type, const char *compat)
+{
+	struct device_node *head, **prevp, *np;
+
+	prevp = &head;
+	for (np = allnodes; np != 0; np = np->allnext) {
+		if (type != NULL
+		    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
+			continue;
+		if (device_is_compatible(np, compat)) {
+			*prevp = np;
+			prevp = &np->next;
+		}
+	}
+	*prevp = 0;
+	return head;
+}
+
+/*
+ * Find the device_node with a given full_name.
+ */
+struct device_node *
+find_path_device(const char *path)
+{
+	struct device_node *np;
+
+	for (np = allnodes; np != 0; np = np->allnext)
+		if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
+			return np;
+	return NULL;
+}
+
+/*
+ * Find the device_node with a given phandle.
+ */
+static struct device_node * __init
+find_phandle(phandle ph)
+{
+	struct device_node *np;
+
+	for (np = allnodes; np != 0; np = np->allnext)
+		if (np->node == ph)
+			return np;
+	return NULL;
+}
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+unsigned char *
+get_property(struct device_node *np, const char *name, int *lenp)
+{
+	struct property *pp;
+
+	for (pp = np->properties; pp != 0; pp = pp->next)
+		if (strcmp(pp->name, name) == 0) {
+			if (lenp != 0)
+				*lenp = pp->length;
+			return pp->value;
+		}
+	return 0;
+}
+
+/*
+ * Add a property to a node
+ */
+void __openfirmware
+prom_add_property(struct device_node* np, struct property* prop)
+{
+	struct property **next = &np->properties;
+
+	prop->next = NULL;	
+	while (*next)
+		next = &(*next)->next;
+	*next = prop;
+}
+
+#if 0
+void __openfirmware
+print_properties(struct device_node *np)
+{
+	struct property *pp;
+	char *cp;
+	int i, n;
+
+	for (pp = np->properties; pp != 0; pp = pp->next) {
+		printk(KERN_INFO "%s", pp->name);
+		for (i = strlen(pp->name); i < 16; ++i)
+			printk(" ");
+		cp = (char *) pp->value;
+		for (i = pp->length; i > 0; --i, ++cp)
+			if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
+			    || (i == 1 && *cp != 0))
+				break;
+		if (i == 0 && pp->length > 1) {
+			/* looks like a string */
+			printk(" %s\n", (char *) pp->value);
+		} else {
+			/* dump it in hex */
+			n = pp->length;
+			if (n > 64)
+				n = 64;
+			if (pp->length % 4 == 0) {
+				unsigned int *p = (unsigned int *) pp->value;
+
+				n /= 4;
+				for (i = 0; i < n; ++i) {
+					if (i != 0 && (i % 4) == 0)
+						printk("\n                ");
+					printk(" %08x", *p++);
+				}
+			} else {
+				unsigned char *bp = pp->value;
+
+				for (i = 0; i < n; ++i) {
+					if (i != 0 && (i % 16) == 0)
+						printk("\n                ");
+					printk(" %02x", *bp++);
+				}
+			}
+			printk("\n");
+			if (pp->length > 64)
+				printk("                 ... (length = %d)\n",
+				       pp->length);
+		}
+	}
+}
+#endif
+
+
+void __init
+abort()
+{
+#ifdef CONFIG_XMON
+	xmon(NULL);
+#endif
+	for (;;)
+		prom_exit();
+}
+
+
+/* Verify bi_recs are good */
+static struct bi_record *
+prom_bi_rec_verify(struct bi_record *bi_recs)
+{
+	struct bi_record *first, *last;
+
+	if ( bi_recs == NULL || bi_recs->tag != BI_FIRST )
+		return NULL;
+
+	last = (struct bi_record *)bi_recs->data[0];
+	if ( last == NULL || last->tag != BI_LAST )
+		return NULL;
+
+	first = (struct bi_record *)last->data[0];
+	if ( first == NULL || first != bi_recs )
+		return NULL;
+
+	return bi_recs;
+}
+
+static unsigned long
+prom_bi_rec_reserve(unsigned long mem)
+{
+	unsigned long offset = reloc_offset();
+	struct prom_t *_prom = PTRRELOC(&prom);
+	struct bi_record *rec;
+
+	if ( _prom->bi_recs != NULL) {
+
+		for ( rec=_prom->bi_recs;
+		      rec->tag != BI_LAST;
+		      rec=bi_rec_next(rec) ) {
+			switch (rec->tag) {
+#ifdef CONFIG_BLK_DEV_INITRD
+			case BI_INITRD:
+				lmb_reserve(rec->data[0], rec->data[1]);
+				break;
+#endif /* CONFIG_BLK_DEV_INITRD */
+			}
+		}
+		/* The next use of this field will be after relocation
+	 	 * is enabled, so convert this physical address into a
+	 	 * virtual address.
+	 	 */
+		_prom->bi_recs = PTRUNRELOC(_prom->bi_recs);
+	}
+
+	return mem;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ptrace.c linux/arch/ppc64/kernel/ptrace.c
--- linux.orig/arch/ppc64/kernel/ptrace.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ptrace.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,341 @@
+/*
+ *  linux/arch/ppc/kernel/ptrace.c
+ *
+ *  PowerPC version
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Derived from "arch/m68k/kernel/ptrace.c"
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * Modified by Cort Dougan (cort@hq.fsmlabs.com)
+ * and Paul Mackerras (paulus@linuxcare.com.au).
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file README.legal in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+/*
+ * Set of msr bits that gdb can change on behalf of a process.
+ */
+#define MSR_DEBUGCHANGE	(MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline unsigned long get_reg(struct task_struct *task, int regno)
+{
+	if (regno < sizeof(struct pt_regs) / sizeof(unsigned long))
+		return ((unsigned long *)task->thread.regs)[regno];
+	return (0);
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	if (regno < PT_SOFTE) {
+		if (regno == PT_MSR)
+			data = (data & MSR_DEBUGCHANGE)
+				| (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
+		((unsigned long *)task->thread.regs)[regno] = data;
+		return 0;
+	}
+	return -EIO;
+}
+
+static inline void
+set_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL)
+		regs->msr |= MSR_SE;
+}
+
+static inline void
+clear_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL)
+		regs->msr &= ~MSR_SE;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	/* make sure the single step bit is not set. */
+	clear_single_step(child);
+}
+
+int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret = -EPERM;
+
+	lock_kernel();
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->p_pptr != current)
+		goto out_tsk;
+
+	switch (request) {
+	/* when I and D space are separate, these will need to be fixed. */
+	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKDATA: {
+		unsigned long tmp;
+		int copied;
+
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		ret = -EIO;
+		if (copied != sizeof(tmp))
+			break;
+		ret = put_user(tmp,(unsigned long *) data);
+		break;
+	}
+
+	/* read the word at location addr in the USER area. */
+	case PTRACE_PEEKUSR: {
+		unsigned long index, tmp;
+
+		ret = -EIO;
+		/* convert to index and check */
+		index = (unsigned long) addr >> 3;
+		if ((addr & 7) || index > PT_FPSCR)
+			break;
+
+		if (index < PT_FPR0) {
+			tmp = get_reg(child, (int) index);
+		} else {
+			if (child->thread.regs->msr & MSR_FP)
+				giveup_fpu(child);
+			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
+		}
+		ret = put_user(tmp,(unsigned long *) data);
+		break;
+	}
+
+	/* If I and D space are separate, this will have to be fixed. */
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		ret = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+			break;
+		ret = -EIO;
+		break;
+
+	/* write the word at location addr in the USER area */
+	case PTRACE_POKEUSR: {
+		unsigned long index;
+
+		ret = -EIO;
+		/* convert to index and check */
+		index = (unsigned long) addr >> 3;
+		if ((addr & 7) || index > PT_FPSCR)
+			break;
+
+		if (index == PT_ORIG_R3)
+			break;
+		if (index < PT_FPR0) {
+			ret = put_reg(child, index, data);
+		} else {
+			if (child->thread.regs->msr & MSR_FP)
+				giveup_fpu(child);
+			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
+			ret = 0;
+		}
+		break;
+	}
+
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: { /* restart after signal. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		if (request == PTRACE_SYSCALL)
+			child->ptrace |= PT_TRACESYS;
+		else
+			child->ptrace &= ~PT_TRACESYS;
+		child->exit_code = data;
+		/* make sure the single step bit is not set. */
+		clear_single_step(child);
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+/*
+ * make the child exit.  Best I can do is send it a sigkill. 
+ * perhaps it should be put in the status that it wants to 
+ * exit.
+ */
+	case PTRACE_KILL: {
+		ret = 0;
+		if (child->state == TASK_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		/* make sure the single step bit is not set. */
+		clear_single_step(child);
+		wake_up_process(child);
+		break;
+	}
+
+	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		child->ptrace &= ~PT_TRACESYS;
+		set_single_step(child);
+		child->exit_code = data;
+		/* give it a chance to run. */
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_DETACH:
+		ret = ptrace_detach(child, data);
+		break;
+
+	case PPC_PTRACE_GETREGS:
+	{ /* Get GPRs 0 - 31. */
+		u64 tmp;
+		u64 cntr;
+		ret = 0; 
+		for (cntr=0; cntr<32 && ret==0; ++cntr)
+		{
+			tmp = ((u64*)child->thread.regs)[cntr];
+			ret = put_user(tmp, (u64*)(data+cntr));
+		}
+		break;
+	}
+
+	case PPC_PTRACE_SETREGS:
+	{ /* Set GPRs 0 - 31. */
+		u64 cntr;
+		ret = 0; 
+		for (cntr=0; cntr<32 && ret==0; ++cntr)
+		{
+			ret = put_reg(child, cntr, *(u64*)(data+cntr));
+		}
+		break;
+	}
+
+	case PPC_PTRACE_GETFPREGS:
+	{ /* Get FPRs 0 - 31. */
+		u64 tmp;
+		u64 cntr;
+		ret = -EIO;
+		if (child->thread.regs->msr & MSR_FP)
+			giveup_fpu(child);
+		ret = 0; 
+		for (cntr=0; cntr<32 && ret==0; ++cntr)
+		{
+			tmp = ((u64*)child->thread.fpr)[cntr];
+			ret = put_user(tmp, (u64*)(data+cntr));
+		}
+		break;
+	}
+
+	case PPC_PTRACE_SETFPREGS:
+	{ /* Get FPRs 0 - 31. */
+		u64 cntr;
+		ret = -EIO;
+		if (child->thread.regs->msr & MSR_FP)
+			giveup_fpu(child);
+		for (cntr=0; cntr<32; ++cntr)
+		{
+			((u64*)child->thread.fpr)[cntr] = *(u64*)(data+cntr);
+		}
+		ret = 0; 
+		break;
+	}
+
+	default:
+		ret = -EIO;
+		break;
+	}
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+void syscall_trace(void)
+{
+  if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ptrace32.c linux/arch/ppc64/kernel/ptrace32.c
--- linux.orig/arch/ppc64/kernel/ptrace32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ptrace32.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,406 @@
+/*
+ *  linux/arch/ppc/kernel/ptrace32.c
+ *
+ *  PowerPC version
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Derived from "arch/m68k/kernel/ptrace.c"
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * Modified by Cort Dougan (cort@hq.fsmlabs.com)
+ * and Paul Mackerras (paulus@linuxcare.com.au).
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file README.legal in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+/*
+ * Set of msr bits that gdb can change on behalf of a process.
+ */
+#define MSR_DEBUGCHANGE	(MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline unsigned long get_reg(struct task_struct *task, int regno)
+{
+	if (regno < sizeof(struct pt_regs) / sizeof(unsigned long))
+		return ((unsigned long *)task->thread.regs)[regno];
+	return (0);
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ * (Put DATA into task TASK's register REGNO.)
+ */
+static inline int put_reg(struct task_struct *task, int regno, unsigned long data)
+{
+	if (regno < PT_SOFTE) 
+  {
+		if (regno == PT_MSR)
+			data = (data & MSR_DEBUGCHANGE) | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
+		((unsigned long *)task->thread.regs)[regno] = data;
+		return 0;
+	}
+	return -EIO;
+}
+
+static inline void
+set_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL)
+		regs->msr |= MSR_SE;
+}
+
+static inline void
+clear_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL)
+		regs->msr &= ~MSR_SE;
+}
+
+int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
+{
+	struct task_struct *child;
+	int ret  = -EPERM;
+  
+	lock_kernel();
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->p_pptr != current)
+		goto out_tsk;
+
+	switch (request)
+	{
+	/* Read word at location ADDR */
+	/* when I and D space are separate, these will need to be fixed. */
+	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKDATA: 
+	{
+		unsigned int  tmp_mem_value;
+		int copied;
+
+		copied = access_process_vm(child, addr, &tmp_mem_value, sizeof(tmp_mem_value), 0);
+		ret = -EIO;
+		if (copied != sizeof(tmp_mem_value))
+			break;
+		ret = put_user(tmp_mem_value, (u32*)data);  // copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
+		break;
+	}
+
+	/* Read 4 bytes of the other process' storage */
+	/*  data is a pointer specifying where the user wants the 4 bytes copied into */
+	/*  addr is a pointer in the user's storage that contains an 8 byte address in the other process of the 4 bytes that is to be read */
+	/* (this is run in a 32-bit process looking at a 64-bit process) */
+	/* when I and D space are separate, these will need to be fixed. */
+	case PPC_PTRACE_PEEKTEXT_3264:
+	case PPC_PTRACE_PEEKDATA_3264: 
+	{
+		u32  tmp_mem_value;
+		int  copied;
+		u32* addrOthers;
+
+		ret = -EIO;
+
+		/* Get the addr in the other process that we want to read */
+		if (get_user(addrOthers,(u32**)addr) != 0)
+			break;
+
+		copied = access_process_vm(child, (u64)addrOthers, &tmp_mem_value, sizeof(tmp_mem_value), 0);
+		if (copied != sizeof(tmp_mem_value))
+			break;
+		ret = put_user(tmp_mem_value, (u32*)data);  // copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
+		break;
+	}
+
+	/* Read a register (specified by ADDR) out of the "user area" */
+	case PTRACE_PEEKUSR: {
+		int index;
+		unsigned int reg32bits;
+		unsigned long tmp_reg_value;
+
+		ret = -EIO;
+		/* convert to index and check */
+		index = (unsigned long) addr >> 2;
+		if ((addr & 3) || index > PT_FPSCR32)
+			break;
+
+		if (index < PT_FPR0) {
+			tmp_reg_value = get_reg(child,  index);
+		} else {
+			if (child->thread.regs->msr & MSR_FP)
+				giveup_fpu(child);
+			/* the user space code considers the floating point to be 
+			 *   an array of unsigned int (32 bits) - the index passed 
+			 *   in is based on this assumption.
+			 */
+			tmp_reg_value = ((unsigned int *)child->thread.fpr)[index - PT_FPR0];
+		}
+		reg32bits = tmp_reg_value;
+		ret = put_user(reg32bits, (u32*)data);  // copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
+		break;
+	}
+  
+	/* Read 4 bytes out of the other process' pt_regs area */
+	/*  data is a pointer specifying where the user wants the 4 bytes copied into */
+	/*  addr is the offset into the other process' pt_regs structure that is to be read */
+	/* (this is run in a 32-bit process looking at a 64-bit process) */
+	case PPC_PTRACE_PEEKUSR_3264:
+	{
+		u32 index;
+		u32 reg32bits;
+		u64 tmp_reg_value;
+		u32 numReg;
+		u32 part;
+
+		ret = -EIO;
+		/* Determine which register the user wants */
+		index = (u64)addr >> 2;  /* Divide addr by 4 */
+		numReg = index / 2;
+		/* Determine which part of the register the user wants */
+		if (index % 2)
+			part = 1;  /* want the 2nd half of the register (right-most). */
+		else
+			part = 0;  /* want the 1st half of the register (left-most). */
+
+		/* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */
+		if ((addr & 3) || numReg > PT_FPSCR)
+			break;
+
+		if (numReg >= PT_FPR0)
+		{
+			if (child->thread.regs->msr & MSR_FP)
+				giveup_fpu(child);
+		        if (numReg == PT_FPSCR) 
+			        tmp_reg_value = ((unsigned int *)child->thread.fpscr);
+		        else 
+			        tmp_reg_value = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
+		} else { /* register within PT_REGS struct */
+		    tmp_reg_value = get_reg(child, numReg);
+		} 
+                reg32bits = ((u32*)&tmp_reg_value)[part];
+		ret = put_user(reg32bits, (u32*)data);  /* copy 4 bytes of data into the user location specified by the 8 byte pointer in "data". */
+		break;
+	}
+
+	/* Write the word at location ADDR */
+	/* If I and D space are separate, this will have to be fixed. */
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA: {
+		unsigned int tmp_value_to_write;
+		tmp_value_to_write =  data;
+		ret = 0;
+		if (access_process_vm(child, addr, &tmp_value_to_write, sizeof(tmp_value_to_write), 1) == sizeof(tmp_value_to_write))
+			break;
+		ret = -EIO;
+		break;
+	}
+
+	/* Write 4 bytes into the other process' storage */
+	/*  data is the 4 bytes that the user wants written */
+	/*  addr is a pointer in the user's storage that contains an 8 byte address in the other process where the 4 bytes that is to be written */
+	/* (this is run in a 32-bit process looking at a 64-bit process) */
+	/* when I and D space are separate, these will need to be fixed. */
+	case PPC_PTRACE_POKETEXT_3264:
+	case PPC_PTRACE_POKEDATA_3264:
+	{
+		u32  tmp_value_to_write = data;
+		u32* addrOthers;
+		int  bytesWritten;
+
+		/* Get the addr in the other process that we want to write into */
+		ret = -EIO;
+		if (get_user(addrOthers,(u32**)addr) != 0)
+			break;
+
+		ret = 0;
+		bytesWritten = access_process_vm(child, (u64)addrOthers, &tmp_value_to_write, sizeof(tmp_value_to_write), 1);
+		if (bytesWritten == sizeof(tmp_value_to_write))
+			break;
+		ret = -EIO;
+		break;
+	}
+
+	/* Write DATA into location ADDR within the USER area  */
+	case PTRACE_POKEUSR: {
+		unsigned long index;
+
+		ret = -EIO;
+
+		/* convert to index and check */
+		index = (unsigned long) addr >> 2;
+		if ((addr & 3) || index > PT_FPSCR32)
+			break;
+
+		if (index == PT_ORIG_R3)
+			break;
+
+
+		if (index < PT_FPR0) {
+			ret = put_reg(child, index, data);
+		} else {
+			if (child->thread.regs->msr & MSR_FP)
+				giveup_fpu(child);
+      /* the user space code considers the floating point to be 
+       *   an array of unsigned int (32 bits) - the index passed 
+       *   in is based on this assumption.
+       */
+
+			((unsigned int *)child->thread.fpr)[index - PT_FPR0] = data;
+			ret = 0;
+		}
+		break;
+	}
+
+	/* Write 4 bytes into the other process' pt_regs area */
+	/*  data is the 4 bytes that the user wants written */
+	/*  addr is the offset into the other process' pt_regs structure that is to be written into */
+	/* (this is run in a 32-bit process looking at a 64-bit process) */
+	case PPC_PTRACE_POKEUSR_3264:
+	{
+		u32 index;
+		u32 numReg;
+
+		ret = -EIO;
+
+		/* Determine which register the user wants */
+		index = (u64)addr >> 2;  /* Divide addr by 4 */
+		numReg = index / 2;
+
+		/* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */
+		if ((addr & 3) || numReg > PT_FPSCR)
+			break;
+		/* Insure it is a register we let them change */
+		if ((numReg == PT_ORIG_R3) || ((numReg > PT_CCR) && (numReg < PT_FPR0)))
+			break;
+
+		if (numReg >= PT_FPR0)
+		{
+			if (child->thread.regs->msr & MSR_FP)
+				giveup_fpu(child);
+		}
+
+		if (numReg == PT_MSR)
+			data = (data & MSR_DEBUGCHANGE) | (child->thread.regs->msr & ~MSR_DEBUGCHANGE);
+
+		((u32*)child->thread.regs)[index] = data;
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: { /* restart after signal. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		if (request == PTRACE_SYSCALL)
+			child->ptrace |= PT_TRACESYS;
+		else
+			child->ptrace &= ~PT_TRACESYS;
+		child->exit_code = data;
+		/* make sure the single step bit is not set. */
+		clear_single_step(child);
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill. 
+	 * perhaps it should be put in the status that it wants to 
+	 * exit.
+	 */
+	case PTRACE_KILL: {
+		ret = 0;
+		if (child->state == TASK_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		/* make sure the single step bit is not set. */
+		clear_single_step(child);
+		wake_up_process(child);
+		break;
+	}
+
+	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		child->ptrace &= ~PT_TRACESYS;
+		set_single_step(child);
+		child->exit_code = data;
+		/* give it a chance to run. */
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_DETACH:
+		ret = ptrace_detach(child, data);
+		break;
+
+	default:
+		ret = -EIO;
+		break;
+	}
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/ras.c linux/arch/ppc64/kernel/ras.c
--- linux.orig/arch/ppc64/kernel/ras.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/ras.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,165 @@
+
+/*
+ * ras.c
+ * Copyright (C) 2001 Dave Engebretsen IBM 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
+ */
+
+/* Change Activity:
+ * 2001/09/21 : engebret : Created with minimal EPOW and HW exception support.
+ * End Change Activity 
+ */
+
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/threads.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/proc_fs.h>
+#include <linux/random.h>
+#include <linux/sysrq.h>
+
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/cache.h>
+#include <asm/prom.h>
+#include <asm/ptrace.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/machdep.h>
+#include <asm/rtas.h>
+#include <asm/ppcdebug.h>
+
+static void ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static void ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+void init_ras_IRQ(void);
+
+/* #define DEBUG */
+
+/*
+ * Initialize handlers for the set of interrupts caused by hardware errors
+ * and power system events.
+ */
+void init_ras_IRQ(void) {
+	struct device_node *np;
+	unsigned int *ireg, len, i;
+
+	if((np = find_path_device("/event-sources/internal-errors")) &&
+	   (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", 
+						&len))) {
+		for(i=0; i<(len / sizeof(*ireg)); i++) {
+			request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, 
+				    &ras_error_interrupt, 0, 
+				    "RAS_ERROR", NULL);
+			ireg++;
+		}
+	}
+
+	if((np = find_path_device("/event-sources/epow-events")) &&
+	   (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", 
+						&len))) {
+		for(i=0; i<(len / sizeof(*ireg)); i++) {
+			request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, 
+				    &ras_epow_interrupt, 0, 
+				    "RAS_EPOW", NULL);
+			ireg++;
+		}
+	}
+}
+
+/*
+ * Handle power subsystem events (EPOW).
+ *
+ * Presently we just log the event has occured.  This should be fixed
+ * to examine the type of power failure and take appropriate action where
+ * the time horizon permits something useful to be done.
+ */
+static void
+ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct rtas_error_log log_entry;
+	unsigned int size = sizeof(log_entry);
+	long status = 0xdeadbeef;
+
+	status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 
+			   0x500, irq, 
+			   EPOW_WARNING | POWERMGM_EVENTS, 
+			   1,  /* Time Critical */
+			   __pa(&log_entry), size);
+
+	udbg_printf("EPOW <0x%lx 0x%lx>\n", 
+		    *((unsigned long *)&log_entry), status); 
+	printk(KERN_WARNING 
+	       "EPOW <0x%lx 0x%lx>\n",*((unsigned long *)&log_entry), status);
+}
+
+/*
+ * Handle hardware error interrupts.
+ *
+ * RTAS check-exception is called to collect data on the exception.  If
+ * the error is deemed recoverable, we log a warning and return.
+ * For nonrecoverable errors, an error is logged and we stop all processing
+ * as quickly as possible in order to prevent propagation of the failure.
+ */
+static void
+ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct rtas_error_log log_entry;
+	unsigned int size = sizeof(log_entry);
+	long status = 0xdeadbeef;
+
+	status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 
+			   0x500, irq, 
+			   INTERNAL_ERROR, 
+			   1, /* Time Critical */
+			   __pa(&log_entry), size);
+
+	if((status != 1) && 
+	   (log_entry.severity >= SEVERITY_ERROR_SYNC)) {
+		udbg_printf("HW Error <0x%lx 0x%lx>\n",
+			    *((unsigned long *)&log_entry), status);
+		printk(KERN_EMERG 
+		       "Error: Fatal hardware error <0x%lx 0x%lx>\n",
+		       *((unsigned long *)&log_entry), status);
+
+#ifndef DEBUG
+		/* Don't actually power off when debugging so we can test
+		 * without actually failing while injecting errors.
+		 */
+		ppc_md.power_off();
+#endif
+	} else {
+		udbg_printf("Recoverable HW Error <0x%lx 0x%lx>\n",
+			    *((unsigned long *)&log_entry), status); 
+		printk(KERN_WARNING 
+		       "Warning: Recoverable hardware error <0x%lx 0x%lx>\n",
+		       *((unsigned long *)&log_entry), status);
+
+		return;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/rtas-proc.c linux/arch/ppc64/kernel/rtas-proc.c
--- linux.orig/arch/ppc64/kernel/rtas-proc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/rtas-proc.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,796 @@
+/*
+ *   arch/ppc64/kernel/rtas-proc.c
+ *   Copyright (C) 2000 Tilmann Bitterberg
+ *   (tilmann@bitterberg.de)
+ *
+ *   RTAS (Runtime Abstraction Services) stuff
+ *   Intention is to provide a clean user interface
+ *   to use the RTAS.
+ *
+ *   TODO:
+ *   Split off a header file and maybe move it to a different
+ *   location. Write Documentation on what the /proc/rtas/ entries
+ *   actually do.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/ctype.h>
+#include <linux/time.h>
+#include <linux/string.h>
+
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/machdep.h> /* for ppc_md */
+#include <asm/time.h>
+
+/* Token for Sensors */
+#define KEY_SWITCH		0x0001
+#define ENCLOSURE_SWITCH	0x0002
+#define THERMAL_SENSOR		0x0003
+#define LID_STATUS		0x0004
+#define POWER_SOURCE		0x0005
+#define BATTERY_VOLTAGE		0x0006
+#define BATTERY_REMAINING	0x0007
+#define BATTERY_PERCENTAGE	0x0008
+#define EPOW_SENSOR		0x0009
+#define BATTERY_CYCLESTATE	0x000a
+#define BATTERY_CHARGING	0x000b
+
+/* IBM specific sensors */
+#define IBM_SURVEILLANCE	0x2328 /* 9000 */
+#define IBM_FANRPM		0x2329 /* 9001 */
+#define IBM_VOLTAGE		0x232a /* 9002 */
+#define IBM_DRCONNECTOR		0x232b /* 9003 */
+#define IBM_POWERSUPPLY		0x232c /* 9004 */
+#define IBM_INTQUEUE		0x232d /* 9005 */
+
+/* Status return values */
+#define SENSOR_CRITICAL_HIGH	13
+#define SENSOR_WARNING_HIGH	12
+#define SENSOR_NORMAL		11
+#define SENSOR_WARNING_LOW	10
+#define SENSOR_CRITICAL_LOW	 9
+#define SENSOR_SUCCESS		 0
+#define SENSOR_HW_ERROR		-1
+#define SENSOR_BUSY		-2
+#define SENSOR_NOT_EXIST	-3
+#define SENSOR_DR_ENTITY	-9000
+
+/* Location Codes */
+#define LOC_SCSI_DEV_ADDR	'A'
+#define LOC_SCSI_DEV_LOC	'B'
+#define LOC_CPU			'C'
+#define LOC_DISKETTE		'D'
+#define LOC_ETHERNET		'E'
+#define LOC_FAN			'F'
+#define LOC_GRAPHICS		'G'
+/* reserved / not used		'H' */
+#define LOC_IO_ADAPTER		'I'
+/* reserved / not used		'J' */
+#define LOC_KEYBOARD		'K'
+#define LOC_LCD			'L'
+#define LOC_MEMORY		'M'
+#define LOC_NV_MEMORY		'N'
+#define LOC_MOUSE		'O'
+#define LOC_PLANAR		'P'
+#define LOC_OTHER_IO		'Q'
+#define LOC_PARALLEL		'R'
+#define LOC_SERIAL		'S'
+#define LOC_DEAD_RING		'T'
+#define LOC_RACKMOUNTED		'U' /* for _u_nit is rack mounted */
+#define LOC_VOLTAGE		'V'
+#define LOC_SWITCH_ADAPTER	'W'
+#define LOC_OTHER		'X'
+#define LOC_FIRMWARE		'Y'
+#define LOC_SCSI		'Z'
+
+/* Tokens for indicators */
+#define TONE_FREQUENCY		0x0001 /* 0 - 1000 (HZ)*/
+#define TONE_VOLUME		0x0002 /* 0 - 100 (%) */
+#define SYSTEM_POWER_STATE	0x0003 
+#define WARNING_LIGHT		0x0004
+#define DISK_ACTIVITY_LIGHT	0x0005
+#define HEX_DISPLAY_UNIT	0x0006
+#define BATTERY_WARNING_TIME	0x0007
+#define CONDITION_CYCLE_REQUEST	0x0008
+#define SURVEILLANCE_INDICATOR	0x2328 /* 9000 */
+#define DR_ACTION		0x2329 /* 9001 */
+#define DR_INDICATOR		0x232a /* 9002 */
+/* 9003 - 9004: Vendor specific */
+#define GLOBAL_INTERRUPT_QUEUE	0x232d /* 9005 */
+/* 9006 - 9999: Vendor specific */
+
+/* other */
+#define MAX_SENSORS		 17  /* I only know of 17 sensors */    
+#define MAX_LINELENGTH          256
+#define SENSOR_PREFIX		"ibm,sensor-"
+#define cel_to_fahr(x)		((x*9/5)+32)
+
+
+/* Globals */
+static struct proc_dir_entry *proc_rtas;
+static struct rtas_sensors sensors;
+static struct device_node *rtas_node;
+static unsigned long power_on_time = 0; /* Save the time the user set */
+static char progress_led[MAX_LINELENGTH];
+
+static unsigned long rtas_tone_frequency = 1000;
+static unsigned long rtas_tone_volume = 0;
+
+/* ****************STRUCTS******************************************* */
+struct individual_sensor {
+	unsigned int token;
+	unsigned int quant;
+};
+
+struct rtas_sensors {
+        struct individual_sensor sensor[MAX_SENSORS];
+	unsigned int quant;
+};
+
+/* ****************************************************************** */
+/* Declarations */
+static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
+		int count, int *eof, void *data);
+static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, 
+		size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, 
+		size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
+		size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
+		size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
+		size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
+		size_t count, loff_t *ppos);
+
+static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
+		size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
+		size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
+		size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
+		size_t count, loff_t *ppos);
+
+struct file_operations ppc_rtas_poweron_operations = {
+	read:		ppc_rtas_poweron_read,
+	write:		ppc_rtas_poweron_write
+};
+struct file_operations ppc_rtas_progress_operations = {
+	read:		ppc_rtas_progress_read,
+	write:		ppc_rtas_progress_write
+};
+
+struct file_operations ppc_rtas_clock_operations = {
+	read:		ppc_rtas_clock_read,
+	write:		ppc_rtas_clock_write
+};
+
+struct file_operations ppc_rtas_tone_freq_operations = {
+	read:		ppc_rtas_tone_freq_read,
+	write:		ppc_rtas_tone_freq_write
+};
+struct file_operations ppc_rtas_tone_volume_operations = {
+	read:		ppc_rtas_tone_volume_read,
+	write:		ppc_rtas_tone_volume_write
+};
+
+int ppc_rtas_find_all_sensors (void);
+int ppc_rtas_process_sensor(struct individual_sensor s, int state, 
+		int error, char * buf);
+char * ppc_rtas_process_error(int error);
+int get_location_code(struct individual_sensor s, char * buf);
+int check_location_string (char *c, char * buf);
+int check_location (char *c, int idx, char * buf);
+
+/* ****************************************************************** */
+/* MAIN                                                               */
+/* ****************************************************************** */
+void proc_rtas_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	rtas_node = find_devices("rtas");
+	if ((rtas_node == 0) || (naca->platform == PLATFORM_ISERIES_LPAR)) {
+		return;
+	}
+	
+	proc_rtas = proc_mkdir("rtas", 0);
+	if (proc_rtas == 0)
+		return;
+
+	/* /proc/rtas entries */
+
+	entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas);
+	if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
+
+	entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); 
+	if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
+
+	entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); 
+	if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
+
+	create_proc_read_entry("sensors", S_IRUGO, proc_rtas, 
+			ppc_rtas_sensor_read, NULL);
+	
+	entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); 
+	if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
+
+	entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); 
+	if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
+}
+
+/* ****************************************************************** */
+/* POWER-ON-TIME                                                      */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
+		size_t count, loff_t *ppos)
+{
+	struct rtc_time tm;
+	unsigned long nowtime;
+	char *dest;
+	int error;
+
+	nowtime = simple_strtoul(buf, &dest, 10);
+	if (*dest != '\0' && *dest != '\n') {
+		printk("ppc_rtas_poweron_write: Invalid time\n");
+		return count;
+	}
+	power_on_time = nowtime; /* save the time */
+
+	to_tm(nowtime, &tm);
+
+	error = rtas_call(rtas_token("set-time-for-power-on"), 7, 1, NULL, 
+			tm.tm_year, tm.tm_mon, tm.tm_mday, 
+			tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
+	if (error != 0)
+		printk(KERN_WARNING "error: setting poweron time returned: %s\n", 
+				ppc_rtas_process_error(error));
+	return count;
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
+		size_t count, loff_t *ppos)
+{
+	int n;
+	if (power_on_time == 0)
+		n = sprintf(buf, "Power on time not set\n");
+	else
+		n = sprintf(buf, "%lu\n", power_on_time);
+
+	if (*ppos >= strlen(buf))
+		return 0;
+	if (n > strlen(buf) - *ppos)
+		n = strlen(buf) - *ppos;
+	if (n > count)
+		n = count;
+	*ppos += n;
+	return n;
+}
+
+/* ****************************************************************** */
+/* PROGRESS                                                           */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
+		size_t count, loff_t *ppos)
+{
+	unsigned long hex;
+
+	strcpy(progress_led, buf); /* save the string */
+	/* Lets see if the user passed hexdigits */
+	hex = simple_strtoul(buf, NULL, 10);
+	
+	ppc_md.progress ((char *)buf, hex);
+	return count;
+
+	/* clear the line */ /* ppc_md.progress("                   ", 0xffff);*/
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
+		size_t count, loff_t *ppos)
+{
+	int n = 0;
+	if (progress_led != NULL)
+		n = sprintf (buf, "%s\n", progress_led);
+	if (*ppos >= strlen(buf))
+		return 0;
+	if (n > strlen(buf) - *ppos)
+		n = strlen(buf) - *ppos;
+	if (n > count)
+		n = count;
+	*ppos += n;
+	return n;
+}
+
+/* ****************************************************************** */
+/* CLOCK                                                              */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, 
+		size_t count, loff_t *ppos)
+{
+	struct rtc_time tm;
+	unsigned long nowtime;
+	char *dest;
+	int error;
+
+	nowtime = simple_strtoul(buf, &dest, 10);
+	if (*dest != '\0' && *dest != '\n') {
+		printk("ppc_rtas_clock_write: Invalid time\n");
+		return count;
+	}
+
+	to_tm(nowtime, &tm);
+	error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, 
+			tm.tm_year, tm.tm_mon, tm.tm_mday, 
+			tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
+	if (error != 0)
+		printk(KERN_WARNING "error: setting the clock returned: %s\n", 
+				ppc_rtas_process_error(error));
+	return count;
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, 
+		size_t count, loff_t *ppos)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	unsigned long *ret = kmalloc(4*8, GFP_KERNEL);
+	int n, error;
+
+	error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
+	
+	year = ret[0]; mon  = ret[1]; day  = ret[2];
+	hour = ret[3]; min  = ret[4]; sec  = ret[5];
+
+	if (error != 0){
+		printk(KERN_WARNING "error: reading the clock returned: %s\n", 
+				ppc_rtas_process_error(error));
+		n = sprintf (buf, "0");
+	} else { 
+		n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec));
+	}
+	kfree(ret);
+
+	if (*ppos >= strlen(buf))
+		return 0;
+	if (n > strlen(buf) - *ppos)
+		n = strlen(buf) - *ppos;
+	if (n > count)
+		n = count;
+	*ppos += n;
+	return n;
+}
+
+/* ****************************************************************** */
+/* SENSOR STUFF                                                       */
+/* ****************************************************************** */
+static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
+		int count, int *eof, void *data)
+{
+	int i,j,n;
+	unsigned long ret;
+	int state, error;
+	char *buffer;
+	int get_sensor_state = rtas_token("get-sensor-state");
+
+	if (count < 0)
+		return -EINVAL;
+
+	/* May not be enough */
+	buffer = kmalloc(MAX_LINELENGTH*MAX_SENSORS, GFP_KERNEL);
+
+	if (!buffer)
+		return -ENOMEM;
+
+	memset(buffer, 0, MAX_LINELENGTH*MAX_SENSORS);
+
+	n  = sprintf ( buffer  , "RTAS (RunTime Abstraction Services) Sensor Information\n");
+	n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n");
+	n += sprintf ( buffer+n, "********************************************************\n");
+
+	if (ppc_rtas_find_all_sensors() != 0) {
+		n += sprintf ( buffer+n, "\nNo sensors are available\n");
+		goto return_string;
+	}
+
+	for (i=0; i<sensors.quant; i++) {
+		j = sensors.sensor[i].quant;
+		/* A sensor may have multiple instances */
+		while (j >= 0) {
+			error =	rtas_call(get_sensor_state, 2, 2, &ret, 
+				  sensors.sensor[i].token, sensors.sensor[i].quant-j);
+			state = (int) ret;
+			n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n );
+			n += sprintf (buffer+n, "\n");
+			j--;
+		} /* while */
+	} /* for */
+
+return_string:
+	if (off >= strlen(buffer)) {
+		*eof = 1;
+		kfree(buffer);
+		return 0;
+	}
+	if (n > strlen(buffer) - off)
+		n = strlen(buffer) - off;
+	if (n > count)
+		n = count;
+	else
+		*eof = 1;
+	memcpy(buf, buffer + off, n);
+	*start = buf;
+	kfree(buffer);
+	return n;
+}
+
+/* ****************************************************************** */
+
+int ppc_rtas_find_all_sensors (void)
+{
+	unsigned long *utmp;
+	int len, i, j;
+
+	utmp = (unsigned long *) get_property(rtas_node, "rtas-sensors", &len);
+	if (utmp == NULL) {
+		printk (KERN_ERR "error: could not get rtas-sensors\n");
+		return 1;
+	}
+
+	sensors.quant = len / 8;      /* int + int */
+
+	for (i=0, j=0; j<sensors.quant; i+=2, j++) {
+		sensors.sensor[j].token = utmp[i];
+		sensors.sensor[j].quant = utmp[i+1];
+	}
+	return 0;
+}
+
+/* ****************************************************************** */
+/*
+ * Builds a string of what rtas returned
+ */
+char * ppc_rtas_process_error(int error)
+{
+	switch (error) {
+		case SENSOR_CRITICAL_HIGH:
+			return "(critical high)";
+		case SENSOR_WARNING_HIGH:
+			return "(warning high)";
+		case SENSOR_NORMAL:
+			return "(normal)";
+		case SENSOR_WARNING_LOW:
+			return "(warning low)";
+		case SENSOR_CRITICAL_LOW:
+			return "(critical low)";
+		case SENSOR_SUCCESS:
+			return "(read ok)";
+		case SENSOR_HW_ERROR:
+			return "(hardware error)";
+		case SENSOR_BUSY:
+			return "(busy)";
+		case SENSOR_NOT_EXIST:
+			return "(non existant)";
+		case SENSOR_DR_ENTITY:
+			return "(dr entity removed)";
+		default:
+			return "(UNKNOWN)";
+	}
+}
+
+/* ****************************************************************** */
+/*
+ * Builds a string out of what the sensor said
+ */
+
+int ppc_rtas_process_sensor(struct individual_sensor s, int state, 
+		int error, char * buf) 
+{
+	/* Defined return vales */
+	const char * key_switch[]        = { "Off\t", "Normal\t", "Secure\t", "Mainenance" };
+	const char * enclosure_switch[]  = { "Closed", "Open" };
+	const char * lid_status[]        = { " ", "Open", "Closed" };
+	const char * power_source[]      = { "AC\t", "Battery", "AC & Battery" };
+	const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
+	const char * epow_sensor[]       = { 
+		"EPOW Reset", "Cooling warning", "Power warning",
+		"System shutdown", "System halt", "EPOW main enclosure",
+		"EPOW power off" };
+	const char * battery_cyclestate[]  = { "None", "In progress", "Requested" };
+	const char * battery_charging[]    = { "Charging", "Discharching", "No current flow" };
+	const char * ibm_drconnector[]     = { "Empty", "Present" };
+	const char * ibm_intqueue[]        = { "Disabled", "Enabled" };
+
+	int have_strings = 0;
+	int temperature = 0;
+	int unknown = 0;
+	int n = 0;
+
+	/* What kind of sensor do we have here? */
+	switch (s.token) {
+		case KEY_SWITCH:
+			n += sprintf(buf+n, "Key switch:\t");
+			n += sprintf(buf+n, "%s\t", key_switch[state]);
+			have_strings = 1;
+			break;
+		case ENCLOSURE_SWITCH:
+			n += sprintf(buf+n, "Enclosure switch:\t");
+			n += sprintf(buf+n, "%s\t", enclosure_switch[state]);
+			have_strings = 1;
+			break;
+		case THERMAL_SENSOR:
+			n += sprintf(buf+n, "Temp. (°C/°F):\t");
+			temperature = 1;
+			break;
+		case LID_STATUS:
+			n += sprintf(buf+n, "Lid status:\t");
+			n += sprintf(buf+n, "%s\t", lid_status[state]);
+			have_strings = 1;
+			break;
+		case POWER_SOURCE:
+			n += sprintf(buf+n, "Power source:\t");
+			n += sprintf(buf+n, "%s\t", power_source[state]);
+			have_strings = 1;
+			break;
+		case BATTERY_VOLTAGE:
+			n += sprintf(buf+n, "Battery voltage:\t");
+			break;
+		case BATTERY_REMAINING:
+			n += sprintf(buf+n, "Battery remaining:\t");
+			n += sprintf(buf+n, "%s\t", battery_remaining[state]);
+			have_strings = 1;
+			break;
+		case BATTERY_PERCENTAGE:
+			n += sprintf(buf+n, "Battery percentage:\t");
+			break;
+		case EPOW_SENSOR:
+			n += sprintf(buf+n, "EPOW Sensor:\t");
+			n += sprintf(buf+n, "%s\t", epow_sensor[state]);
+			have_strings = 1;
+			break;
+		case BATTERY_CYCLESTATE:
+			n += sprintf(buf+n, "Battery cyclestate:\t");
+			n += sprintf(buf+n, "%s\t", battery_cyclestate[state]);
+			have_strings = 1;
+			break;
+		case BATTERY_CHARGING:
+			n += sprintf(buf+n, "Battery Charging:\t");
+			n += sprintf(buf+n, "%s\t", battery_charging[state]);
+			have_strings = 1;
+			break;
+		case IBM_SURVEILLANCE:
+			n += sprintf(buf+n, "Surveillance:\t");
+			break;
+		case IBM_FANRPM:
+			n += sprintf(buf+n, "Fan (rpm):\t");
+			break;
+		case IBM_VOLTAGE:
+			n += sprintf(buf+n, "Voltage (mv):\t");
+			break;
+		case IBM_DRCONNECTOR:
+			n += sprintf(buf+n, "DR connector:\t");
+			n += sprintf(buf+n, "%s\t", ibm_drconnector[state]);
+			have_strings = 1;
+			break;
+		case IBM_POWERSUPPLY:
+			n += sprintf(buf+n, "Powersupply:\t");
+			break;
+		case IBM_INTQUEUE:
+			n += sprintf(buf+n, "Interrupt queue:\t");
+			n += sprintf(buf+n, "%s\t", ibm_intqueue[state]);
+			have_strings = 1;
+			break;
+		default:
+			n += sprintf(buf+n,  "Unkown sensor (type %d), ignoring it\n",
+					s.token);
+			unknown = 1;
+			have_strings = 1;
+			break;
+	}
+	if (have_strings == 0) {
+		if (temperature) {
+			n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state));
+		} else
+			n += sprintf(buf+n, "%10d\t", state);
+	}
+	if (unknown == 0) {
+		n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error));
+		n += get_location_code(s, buf+n);
+	}
+	return n;
+}
+
+/* ****************************************************************** */
+
+int check_location (char *c, int idx, char * buf)
+{
+	int n = 0;
+
+	switch (*(c+idx)) {
+		case LOC_PLANAR:
+			n += sprintf ( buf, "Planar #%c", *(c+idx+1));
+			break;
+		case LOC_CPU:
+			n += sprintf ( buf, "CPU #%c", *(c+idx+1));
+			break;
+		case LOC_FAN:
+			n += sprintf ( buf, "Fan #%c", *(c+idx+1));
+			break;
+		case LOC_RACKMOUNTED:
+			n += sprintf ( buf, "Rack #%c", *(c+idx+1));
+			break;
+		case LOC_VOLTAGE:
+			n += sprintf ( buf, "Voltage #%c", *(c+idx+1));
+			break;
+		case LOC_LCD:
+			n += sprintf ( buf, "LCD #%c", *(c+idx+1));
+			break;
+		case '.':
+			n += sprintf ( buf, "- %c", *(c+idx+1));
+		default:
+			n += sprintf ( buf, "Unknown location");
+			break;
+	}
+	return n;
+}
+
+
+/* ****************************************************************** */
+/* 
+ * Format: 
+ * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
+ * the '.' may be an abbrevation
+ */
+int check_location_string (char *c, char *buf)
+{
+	int n=0,i=0;
+
+	while (c[i]) {
+		if (isalpha(c[i]) || c[i] == '.') {
+			 n += check_location(c, i, buf+n);
+		}
+		else if (c[i] == '/' || c[i] == '-')
+			n += sprintf(buf+n, " at ");
+		i++;
+	}
+	return n;
+}
+
+
+/* ****************************************************************** */
+
+int get_location_code(struct individual_sensor s, char * buffer)
+{
+	char rstr[512], tmp[10], tmp2[10];
+	int n=0, i=0, llen, len;
+	/* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */
+	char *ret;
+
+	static int pos = 0; /* remember position where buffer was */
+
+	/* construct the sensor number like 0003 */
+	/* fill with zeros */
+	n = sprintf(tmp, "%d", s.token);
+	len = strlen(tmp);
+	while (strlen(tmp) < 4)
+		n += sprintf (tmp+n, "0");
+	
+	/* invert the string */
+	while (tmp[i]) {
+		if (i<len)
+			tmp2[4-len+i] = tmp[i];
+		else
+			tmp2[3-i] = tmp[i];
+		i++;
+	}
+	tmp2[4] = '\0';
+
+	sprintf (rstr, SENSOR_PREFIX"%s", tmp2);
+
+	ret = (char *) get_property(rtas_node, rstr, &llen);
+
+	n=0;
+	if (ret[0] == '\0')
+		n += sprintf ( buffer+n, "--- ");/* does not have a location */
+	else {
+		char t[50];
+		ret += pos;
+
+		n += check_location_string(ret, buffer + n);
+		n += sprintf ( buffer+n, " ");
+		/* see how many characters we have printed */
+		sprintf ( t, "%s ", ret);
+
+		pos += strlen(t);
+		if (pos >= llen) pos=0;
+	}
+	return n;
+}
+/* ****************************************************************** */
+/* INDICATORS - Tone Frequency                                        */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
+		size_t count, loff_t *ppos)
+{
+	unsigned long freq;
+	char *dest;
+	int error;
+	freq = simple_strtoul(buf, &dest, 10);
+	if (*dest != '\0' && *dest != '\n') {
+		printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");
+		return count;
+	}
+	if (freq < 0) freq = 0;
+	rtas_tone_frequency = freq; /* save it for later */
+	error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL,
+			TONE_FREQUENCY, 0, freq);
+	if (error != 0)
+		printk(KERN_WARNING "error: setting tone frequency returned: %s\n", 
+				ppc_rtas_process_error(error));
+	return count;
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
+		size_t count, loff_t *ppos)
+{
+	int n;
+	n = sprintf(buf, "%lu\n", rtas_tone_frequency);
+
+	if (*ppos >= strlen(buf))
+		return 0;
+	if (n > strlen(buf) - *ppos)
+		n = strlen(buf) - *ppos;
+	if (n > count)
+		n = count;
+	*ppos += n;
+	return n;
+}
+/* ****************************************************************** */
+/* INDICATORS - Tone Volume                                           */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
+		size_t count, loff_t *ppos)
+{
+	unsigned long volume;
+	char *dest;
+	int error;
+	volume = simple_strtoul(buf, &dest, 10);
+	if (*dest != '\0' && *dest != '\n') {
+		printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");
+		return count;
+	}
+	if (volume < 0) volume = 0;
+	if (volume > 100) volume = 100;
+	
+        rtas_tone_volume = volume; /* save it for later */
+	error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL,
+			TONE_VOLUME, 0, volume);
+	if (error != 0)
+		printk(KERN_WARNING "error: setting tone volume returned: %s\n", 
+				ppc_rtas_process_error(error));
+	return count;
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
+		size_t count, loff_t *ppos)
+{
+	int n;
+	n = sprintf(buf, "%lu\n", rtas_tone_volume);
+
+	if (*ppos >= strlen(buf))
+		return 0;
+	if (n > strlen(buf) - *ppos)
+		n = strlen(buf) - *ppos;
+	if (n > count)
+		n = count;
+	*ppos += n;
+	return n;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/rtas.c linux/arch/ppc64/kernel/rtas.c
--- linux.orig/arch/ppc64/kernel/rtas.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/rtas.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,209 @@
+/*
+ *
+ * Procedures for interfacing to the RTAS on CHRP machines.
+ *
+ * Peter Bergner, IBM	March 2001.
+ * Copyright (C) 2001 IBM.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+
+#include <asm/init.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/semaphore.h>
+#include <asm/machdep.h>
+#include <asm/paca.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/udbg.h>
+
+/*
+ * prom_init() is called very early on, before the kernel text
+ * and data have been mapped to KERNELBASE.  At this point the code
+ * is running at whatever address it has been loaded at, so
+ * references to extern and static variables must be relocated
+ * explicitly.  The procedure reloc_offset() returns the address
+ * we're currently running at minus the address we were linked at.
+ * (Note that strings count as static variables.)
+ *
+ * Because OF may have mapped I/O devices into the area starting at
+ * KERNELBASE, particularly on CHRP machines, we can't safely call
+ * OF once the kernel has been mapped to KERNELBASE.  Therefore all
+ * OF calls should be done within prom_init(), and prom_init()
+ * and all routines called within it must be careful to relocate
+ * references as necessary.
+ *
+ * Note that the bss is cleared *after* prom_init runs, so we have
+ * to make sure that any static or extern variables it accesses
+ * are put in the data segment.
+ */
+
+struct rtas_t rtas = { 
+	lock: SPIN_LOCK_UNLOCKED
+};
+
+extern unsigned long reloc_offset(void);
+
+void
+phys_call_rtas(int token, int nargs, int nret, ...)
+{
+	va_list list;
+	unsigned long offset = reloc_offset();
+	struct rtas_args *rtas = PTRRELOC(&(get_paca()->xRtas));
+	int i;
+
+	rtas->token = token;
+	rtas->nargs = nargs;
+	rtas->nret  = nret;
+	rtas->rets  = (rtas_arg_t *)PTRRELOC(&(rtas->args[nargs]));
+
+	va_start(list, nret);
+	for (i = 0; i < nargs; i++)
+	  rtas->args[i] = (rtas_arg_t)LONG_LSW(va_arg(list, ulong));
+	va_end(list);
+
+        enter_rtas(rtas);	
+}
+
+void
+phys_call_rtas_display_status(char c)
+{
+	unsigned long offset = reloc_offset();
+	struct rtas_args *rtas = PTRRELOC(&(get_paca()->xRtas));
+
+	rtas->token = 10;
+	rtas->nargs = 1;
+	rtas->nret  = 1;
+	rtas->rets  = (rtas_arg_t *)PTRRELOC(&(rtas->args[1]));
+	rtas->args[0] = (int)c;
+
+	enter_rtas(rtas);	
+}
+
+void
+call_rtas_display_status(char c)
+{
+	struct rtas_args *rtas = &(get_paca()->xRtas);
+
+	rtas->token = 10;
+	rtas->nargs = 1;
+	rtas->nret  = 1;
+	rtas->rets  = (rtas_arg_t *)&(rtas->args[1]);
+	rtas->args[0] = (int)c;
+
+	enter_rtas((void *)__pa((unsigned long)rtas));	
+}
+
+#if 0
+#define DEBUG_RTAS
+#endif
+__openfirmware
+int
+rtas_token(const char *service)
+{
+	int *tokp;
+	if (rtas.dev == NULL) {
+#ifdef DEBUG_RTAS
+		udbg_printf("\tNo rtas device in device-tree...\n");
+#endif /* DEBUG_RTAS */
+		return RTAS_UNKNOWN_SERVICE;
+	}
+	tokp = (int *) get_property(rtas.dev, service, NULL);
+	return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
+}
+
+__openfirmware
+long
+rtas_call(int token, int nargs, int nret,
+	  unsigned long *outputs, ...)
+{
+	va_list list;
+	int i;
+	unsigned long s;
+	struct rtas_args *rtas_args = &(get_paca()->xRtas);
+
+#ifdef DEBUG_RTAS
+	udbg_printf("Entering rtas_call\n");
+	udbg_printf("\ttoken    = 0x%x\n", token);
+	udbg_printf("\tnargs    = %d\n", nargs);
+	udbg_printf("\tnret     = %d\n", nret);
+	udbg_printf("\t&outputs = 0x%lx\n", outputs);
+#endif /* DEBUG_RTAS */
+	if (token == RTAS_UNKNOWN_SERVICE)
+		return -1;
+
+	rtas_args->token = token;
+	rtas_args->nargs = nargs;
+	rtas_args->nret  = nret;
+	rtas_args->rets  = (rtas_arg_t *)&(rtas_args->args[nargs]);
+	va_start(list, outputs);
+	for (i = 0; i < nargs; ++i) {
+	  rtas_args->args[i] = (rtas_arg_t)LONG_LSW(va_arg(list, ulong));
+#ifdef DEBUG_RTAS
+	  udbg_printf("\tnarg[%d] = 0x%lx\n", i, rtas_args->args[i]);
+#endif /* DEBUG_RTAS */
+	}
+	va_end(list);
+
+	for (i = 0; i < nret; ++i)
+	  rtas_args->rets[i] = 0;
+
+#if 0   /* Gotta do something different here, use global lock for now... */
+	spin_lock_irqsave(&rtas_args->lock, s);
+#else
+	spin_lock_irqsave(&rtas.lock, s);
+#endif
+#ifdef DEBUG_RTAS
+	udbg_printf("\tentering rtas with 0x%lx\n", (void *)__pa((unsigned long)rtas_args));
+#endif /* DEBUG_RTAS */
+	enter_rtas((void *)__pa((unsigned long)rtas_args));
+#ifdef DEBUG_RTAS
+	udbg_printf("\treturned from rtas ...\n");
+#endif /* DEBUG_RTAS */
+#if 0   /* Gotta do something different here, use global lock for now... */
+	spin_unlock_irqrestore(&rtas_args->lock, s);
+#else
+	spin_unlock_irqrestore(&rtas.lock, s);
+#endif
+#ifdef DEBUG_RTAS
+	for(i=0; i < nret ;i++)
+	  udbg_printf("\tnret[%d] = 0x%lx\n", i, (ulong)rtas_args->rets[i]);
+#endif /* DEBUG_RTAS */
+
+	if (nret > 1 && outputs != NULL)
+		for (i = 0; i < nret-1; ++i)
+			outputs[i] = rtas_args->rets[i+1];
+	return (ulong)((nret > 0) ? rtas_args->rets[0] : 0);
+}
+
+void __chrp
+rtas_restart(char *cmd)
+{
+        printk("RTAS system-reboot returned %ld\n",
+	       rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
+        for (;;);
+}
+
+void __chrp
+rtas_power_off(void)
+{
+        /* allow power on only with power button press */
+        printk("RTAS power-off returned %ld\n",
+               rtas_call(rtas_token("power-off"), 2, 1, NULL,0xffffffff,0xffffffff));
+        for (;;);
+}
+
+void __chrp
+rtas_halt(void)
+{
+        rtas_power_off();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/rtasd.c linux/arch/ppc64/kernel/rtasd.c
--- linux.orig/arch/ppc64/kernel/rtasd.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/rtasd.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,845 @@
+/*
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * 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.
+ *
+ * Communication to userspace based on kernel/printk.c
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/rtas.h>
+#include <asm/prom.h>
+
+#if 0
+#define DEBUG(A...)	printk(KERN_ERR A)
+#else
+#define DEBUG(A...)
+#endif
+
+static spinlock_t rtas_log_lock = SPIN_LOCK_UNLOCKED;
+
+DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
+
+#define LOG_NUMBER		64		/* must be a power of two */
+#define LOG_NUMBER_MASK		(LOG_NUMBER-1)
+
+static char *rtas_log_buf;
+static unsigned long rtas_log_start;
+static unsigned long rtas_log_size;
+
+static int surveillance_requested;
+static unsigned int rtas_event_scan_rate;
+static unsigned int rtas_error_log_max;
+
+#define EVENT_SCAN_ALL_EVENTS	0xf0000000
+#define SURVEILLANCE_TOKEN	9000
+#define SURVEILLANCE_TIMEOUT	1
+#define SURVEILLANCE_SCANRATE	1
+
+/*
+ * Since we use 32 bit RTAS, the physical address of this must be below
+ * 4G or else bad things happen. Allocate this in the kernel data and
+ * make it big enough.
+ */
+#define RTAS_ERROR_LOG_MAX 1024
+static unsigned char logdata[RTAS_ERROR_LOG_MAX];
+
+static int rtas_log_open(struct inode * inode, struct file * file)
+{
+	return 0;
+}
+
+static int rtas_log_release(struct inode * inode, struct file * file)
+{
+	return 0;
+}
+
+static ssize_t rtas_log_read(struct file * file, char * buf,
+			 size_t count, loff_t *ppos)
+{
+	int error;
+	char *tmp;
+	unsigned long offset;
+
+	if (!buf || count < rtas_error_log_max)
+		return -EINVAL;
+
+	count = rtas_error_log_max;
+
+	error = verify_area(VERIFY_WRITE, buf, count);
+	if (error)
+		return -EINVAL;
+
+	tmp = kmalloc(rtas_error_log_max, GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
+	if (error)
+		goto out;
+
+	spin_lock(&rtas_log_lock);
+	offset = rtas_error_log_max * (rtas_log_start & LOG_NUMBER_MASK);
+	memcpy(tmp, &rtas_log_buf[offset], count);
+	rtas_log_start += 1;
+	rtas_log_size -= 1;
+	spin_unlock(&rtas_log_lock);
+
+	copy_to_user(buf, tmp, count);
+	error = count;
+
+out:
+	kfree(tmp);
+	return error;
+}
+
+static unsigned int rtas_log_poll(struct file *file, poll_table * wait)
+{
+	poll_wait(file, &rtas_log_wait, wait);
+	if (rtas_log_size)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+struct file_operations proc_rtas_log_operations = {
+	read:		rtas_log_read,
+	poll:		rtas_log_poll,
+	open:		rtas_log_open,
+	release:	rtas_log_release,
+};
+
+
+#define RTAS_ERR KERN_ERR "RTAS: "
+
+/* Extended error log header (12 bytes) */
+struct exthdr {
+	unsigned int valid:1;
+	unsigned int unrecoverable:1;
+	unsigned int recoverable:1;
+	unsigned int unrecoverable_bypassed:1;	/* i.e. degraded performance */
+	unsigned int predictive:1;
+	unsigned int newlog:1;
+	unsigned int bigendian:1;		/* always 1 */
+	unsigned int /* reserved */:1;
+
+	unsigned int platform_specific:1;	/* only in version 3+ */
+	unsigned int /* reserved */:3;
+	unsigned int platform_value:4;		/* valid iff platform_specific */
+
+	unsigned int power_pc:1;		/* always 1 */
+	unsigned int /* reserved */:2;
+	unsigned int addr_invalid:1;		/* failing_address is invalid */
+	unsigned int format_type:4;
+#define EXTLOG_FMT_CPU 1
+#define EXTLOG_FMT_MEMORY 2
+#define EXTLOG_FMT_IO 3
+#define EXTLOG_FMT_POST 4
+#define EXTLOG_FMT_ENV 5
+#define EXTLOG_FMT_POW 6
+#define EXTLOG_FMT_IBMDIAG 12
+#define EXTLOG_FMT_IBMSP 13
+
+	/* This group is in version 3+ only */
+	unsigned int non_hardware:1;		/* Firmware or software is suspect */
+	unsigned int hot_plug:1;		/* Failing component may be hot plugged */
+	unsigned int group_failure:1;		/* Group of components should be replaced */
+	unsigned int /* reserved */:1;
+
+	unsigned int residual:1;		/* Residual error from previous boot (maybe a crash) */
+	unsigned int boot:1;			/* Error during boot */
+	unsigned int config_change:1;		/* Configuration changed since last boot */
+	unsigned int post:1;			/* Error during POST */
+
+	unsigned int bcdtime:32;		/* Time of error in BCD HHMMSS00 */
+	unsigned int bcddate:32;		/* Time of error in BCD YYYYMMDD */
+};
+
+struct cpuhdr {
+	unsigned int internal:1;
+	unsigned int intcache:1;
+	unsigned int extcache_parity:1;	/* or multi-bit ECC */
+	unsigned int extcache_ecc:1;
+	unsigned int sysbus_timeout:1;
+	unsigned int io_timeout:1;
+	unsigned int sysbus_parity:1;
+	unsigned int sysbus_protocol:1;
+	unsigned int cpuid:8;
+	unsigned int element:16;
+	unsigned int failing_address_hi:32;
+	unsigned int failing_address_lo:32;
+
+	/* These are version 4+ */
+	unsigned int try_reboot:1;	/* 1 => fault may be fixed by reboot */
+	unsigned int /* reserved */:7;
+	/* 15 bytes reserved here */
+};
+
+struct memhdr {
+	unsigned int uncorrectable:1;
+	unsigned int ECC:1;
+	unsigned int threshold_exceeded:1;
+	unsigned int control_internal:1;
+	unsigned int bad_address:1;
+	unsigned int bad_data:1;
+	unsigned int bus:1;
+	unsigned int timeout:1;
+	unsigned int sysbus_parity:1;
+	unsigned int sysbus_timeout:1;
+	unsigned int sysbus_protocol:1;
+	unsigned int hostbridge_timeout:1;
+	unsigned int hostbridge_parity:1;
+	unsigned int reserved1:1;
+	unsigned int support:1;
+	unsigned int sysbus_internal:1;
+	unsigned int mem_controller_detected:8;	/* who detected fault? */
+	unsigned int mem_controller_faulted:8;	/* who caused fault? */
+	unsigned int failing_address_hi:32;
+	unsigned int failing_address_lo:32;
+	unsigned int ecc_syndrome:16;
+	unsigned int memory_card:8;
+	unsigned int reserved2:8;
+	unsigned int sub_elements:32;		/* one bit per element */
+	unsigned int element:16;
+};
+
+struct iohdr {
+	unsigned int bus_addr_parity:1;
+	unsigned int bus_data_parity:1;
+	unsigned int bus_timeout:1;
+	unsigned int bridge_internal:1;
+	unsigned int non_pci:1;		/* i.e. secondary bus such as ISA */
+	unsigned int mezzanine_addr_parity:1;
+	unsigned int mezzanine_data_parity:1;
+	unsigned int mezzanine_timeout:1;
+
+	unsigned int bridge_via_sysbus:1;
+	unsigned int bridge_via_mezzanine:1;
+	unsigned int bridge_via_expbus:1;
+	unsigned int detected_by_expbus:1;
+	unsigned int expbus_data_parity:1;
+	unsigned int expbus_timeout:1;
+	unsigned int expbus_connection_failure:1;
+	unsigned int expbus_not_operating:1;
+
+	/* IOA signalling the error */
+	unsigned int pci_sig_busno:8;
+	unsigned int pci_sig_devfn:8;
+	unsigned int pci_sig_deviceid:16;
+	unsigned int pci_sig_vendorid:16;
+	unsigned int pci_sig_revisionid:8;
+	unsigned int pci_sig_slot:8;	/* 00 => system board, ff => multiple */
+
+	/* IOA sending at time of error */
+	unsigned int pci_send_busno:8;
+	unsigned int pci_send_devfn:8;
+	unsigned int pci_send_deviceid:16;
+	unsigned int pci_send_vendorid:16;
+	unsigned int pci_send_revisionid:8;
+	unsigned int pci_send_slot:8;	/* 00 => system board, ff => multiple */
+};
+
+struct posthdr {
+	unsigned int firmware:1;
+	unsigned int config:1;
+	unsigned int cpu:1;
+	unsigned int memory:1;
+	unsigned int io:1;
+	unsigned int keyboard:1;
+	unsigned int mouse:1;
+	unsigned int display:1;
+
+	unsigned int ipl_floppy:1;
+	unsigned int ipl_controller:1;
+	unsigned int ipl_cdrom:1;
+	unsigned int ipl_disk:1;
+	unsigned int ipl_net:1;
+	unsigned int ipl_other:1;
+	unsigned int /* reserved */:1;
+	unsigned int firmware_selftest:1;
+
+	char         devname[12];
+	unsigned int post_code:4;
+	unsigned int firmware_rev:2;
+	unsigned int loc_code:8;	/* currently unused */
+};
+
+struct epowhdr {
+	unsigned int epow_sensor_value:32;
+	unsigned int sensor:1;
+	unsigned int power_fault:1;
+	unsigned int fan:1;
+	unsigned int temp:1;
+	unsigned int redundancy:1;
+	unsigned int CUoD:1;
+	unsigned int /* reserved */:2;
+
+	unsigned int general:1;
+	unsigned int power_loss:1;
+	unsigned int power_supply:1;
+	unsigned int power_switch:1;
+	unsigned int /* reserved */:4;
+
+	unsigned int /* reserved */:16;
+	unsigned int sensor_token:32;
+	unsigned int sensor_index:32;
+	unsigned int sensor_value:32;
+	unsigned int sensor_status:32;
+};
+
+struct pm_eventhdr {
+	unsigned int event_id:32;
+};
+
+struct sphdr {
+	unsigned int ibm:32;	/* "IBM\0" */
+
+	unsigned int timeout:1;
+	unsigned int i2c_bus:1;
+	unsigned int i2c_secondary_bus:1;
+	unsigned int sp_memory:1;
+	unsigned int sp_registers:1;
+	unsigned int sp_communication:1;
+	unsigned int sp_firmware:1;
+	unsigned int sp_hardware:1;
+
+	unsigned int vpd_eeprom:1;
+	unsigned int op_panel:1;
+	unsigned int power_controller:1;
+	unsigned int fan_sensor:1;
+	unsigned int thermal_sensor:1;
+	unsigned int voltage_sensor:1;
+	unsigned int reserved1:2;
+
+	unsigned int serial_port:1;
+	unsigned int nvram:1;
+	unsigned int rtc:1;
+	unsigned int jtag:1;
+	unsigned int tod_battery:1;
+	unsigned int reserved2:1;
+	unsigned int heartbeat:1;
+	unsigned int surveillance:1;
+
+	unsigned int pcn_connection:1;	/* power control network */
+	unsigned int pcn_node:1;
+	unsigned int reserved3:2;
+	unsigned int pcn_access:1;
+	unsigned int reserved:3;
+
+	unsigned int sensor_token:32;	/* zero if undef */
+	unsigned int sensor_index:32;	/* zero if undef */
+};
+
+
+static char *severity_names[] = {
+	"NO ERROR", "EVENT", "WARNING", "ERROR_SYNC", "ERROR", "FATAL", "(6)", "(7)"
+};
+static char *rtas_disposition_names[] = {
+	"FULLY RECOVERED", "LIMITED RECOVERY", "NOT RECOVERED", "(4)"
+};
+static char *entity_names[] = { /* for initiator & targets */
+	"UNKNOWN", "CPU", "PCI", "ISA", "MEMORY", "POWER MANAGEMENT", "HOT PLUG", "(7)", "(8)",
+	"(9)", "(10)", "(11)", "(12)", "(13)", "(14)", "(15)"
+};
+static char *error_type[] = {	/* Not all types covered here so need to bounds check */
+	"UNKNOWN", "RETRY", "TCE_ERR", "INTERN_DEV_FAIL",
+	"TIMEOUT", "DATA_PARITY", "ADDR_PARITY", "CACHE_PARITY",
+	"ADDR_INVALID", "ECC_UNCORR", "ECC_CORR",
+};
+
+static char *rtas_error_type(int type)
+{
+	if (type < 11)
+		return error_type[type];
+	if (type == 64)
+		return "SENSOR";
+	if (type >=96 && type <= 159)
+		return "POWER";
+	return error_type[0];
+}
+
+static void printk_cpu_failure(int version, struct exthdr *exthdr, char *data)
+{
+	struct cpuhdr cpuhdr;
+
+	memcpy(&cpuhdr, data, sizeof(cpuhdr));
+
+	if (cpuhdr.internal) printk(RTAS_ERR "Internal error (not cache)\n");
+	if (cpuhdr.intcache) printk(RTAS_ERR "Internal cache\n");
+	if (cpuhdr.extcache_parity) printk(RTAS_ERR "External cache parity (or multi-bit)\n");
+	if (cpuhdr.extcache_ecc) printk(RTAS_ERR "External cache ECC\n");
+	if (cpuhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n");
+	if (cpuhdr.io_timeout) printk(RTAS_ERR "I/O timeout\n");
+	if (cpuhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n");
+	if (cpuhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n");
+	printk(RTAS_ERR "CPU id: %d\n", cpuhdr.cpuid);
+	printk(RTAS_ERR "Failing element: 0x%04x\n", cpuhdr.element);
+	if (!exthdr->addr_invalid)
+		printk(RTAS_ERR "Failing address: %08x%08x\n", cpuhdr.failing_address_hi, cpuhdr.failing_address_lo);
+	if (version >= 4 && cpuhdr.try_reboot)
+		printk(RTAS_ERR "A reboot of the system may correct the problem\n");
+}
+
+static void printk_mem_failure(int version, struct exthdr *exthdr, char *data)
+{
+	struct memhdr memhdr;
+
+	memcpy(&memhdr, data, sizeof(memhdr));
+	if (memhdr.uncorrectable) printk(RTAS_ERR "Uncorrectable Memory error\n");
+	if (memhdr.ECC) printk(RTAS_ERR "ECC Correctable error\n");
+	if (memhdr.threshold_exceeded) printk(RTAS_ERR "Correctable threshold exceeded\n");
+	if (memhdr.control_internal) printk(RTAS_ERR "Memory Controller internal error\n");
+	if (memhdr.bad_address) printk(RTAS_ERR "Memory Address error\n");
+	if (memhdr.bad_data) printk(RTAS_ERR "Memory Data error\n");
+	if (memhdr.bus) printk(RTAS_ERR "Memory bus/switch internal error\n");
+	if (memhdr.timeout) printk(RTAS_ERR "Memory timeout\n");
+	if (memhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n");
+	if (memhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n");
+	if (memhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n");
+	if (memhdr.hostbridge_timeout) printk(RTAS_ERR "I/O Host Bridge timeout\n");
+	if (memhdr.hostbridge_parity) printk(RTAS_ERR "I/O Host Bridge parity\n");
+	if (memhdr.support) printk(RTAS_ERR "System support function error\n");
+	if (memhdr.sysbus_internal) printk(RTAS_ERR "System bus internal hardware/switch error\n");
+	printk(RTAS_ERR "Memory Controller that detected failure: %d\n", memhdr.mem_controller_detected);
+	printk(RTAS_ERR "Memory Controller that faulted: %d\n", memhdr.mem_controller_faulted);
+	if (!exthdr->addr_invalid)
+		printk(RTAS_ERR "Failing address: 0x%016x%016x\n", memhdr.failing_address_hi, memhdr.failing_address_lo);
+	printk(RTAS_ERR "ECC syndrome bits: 0x%04x\n", memhdr.ecc_syndrome);
+	printk(RTAS_ERR "Memory Card: %d\n", memhdr.memory_card);
+	printk(RTAS_ERR "Failing element: 0x%04x\n", memhdr.element);
+	printk(RTAS_ERR "Sub element bits: 0x%08x\n", memhdr.sub_elements);
+}
+
+static void printk_io_failure(int version, struct exthdr *exthdr, char *data)
+{
+	struct iohdr iohdr;
+
+	memcpy(&iohdr, data, sizeof(iohdr));
+	if (iohdr.bus_addr_parity) printk(RTAS_ERR "I/O bus address parity\n");
+	if (iohdr.bus_data_parity) printk(RTAS_ERR "I/O bus data parity\n");
+	if (iohdr.bus_timeout) printk(RTAS_ERR "I/O bus timeout, access or other\n");
+	if (iohdr.bridge_internal) printk(RTAS_ERR "I/O bus bridge/device internal\n");
+	if (iohdr.non_pci) printk(RTAS_ERR "Signaling IOA is a PCI to non-PCI bridge (e.g. ISA)\n");
+	if (iohdr.mezzanine_addr_parity) printk(RTAS_ERR "Mezzanine/System bus address parity\n");
+	if (iohdr.mezzanine_data_parity) printk(RTAS_ERR "Mezzanine/System bus data parity\n");
+	if (iohdr.mezzanine_timeout) printk(RTAS_ERR "Mezzanine/System bus timeout, transfer or protocol\n");
+	if (iohdr.bridge_via_sysbus) printk(RTAS_ERR "Bridge is connected to system bus\n");
+	if (iohdr.bridge_via_mezzanine) printk(RTAS_ERR "Bridge is connected to memory controller via mezzanine bus\n");
+	if (iohdr.bridge_via_expbus) printk(RTAS_ERR "Bridge is connected to I/O expansion bus\n");
+	if (iohdr.detected_by_expbus) printk(RTAS_ERR "Error on system bus detected by I/O expansion bus controller\n");
+	if (iohdr.expbus_data_parity) printk(RTAS_ERR "I/O expansion bus data error\n");
+	if (iohdr.expbus_timeout) printk(RTAS_ERR "I/O expansion bus timeout, access or other\n");
+	if (iohdr.expbus_connection_failure) printk(RTAS_ERR "I/O expansion bus connection failure\n");
+	if (iohdr.expbus_not_operating) printk(RTAS_ERR "I/O expansion unit not in an operating state (powered off, off-line)\n");
+
+	printk(RTAS_ERR "IOA Signaling the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n",
+	       iohdr.pci_sig_busno, iohdr.pci_sig_devfn >> 3, iohdr.pci_sig_devfn & 0x7,
+	       iohdr.pci_sig_vendorid, iohdr.pci_sig_deviceid, iohdr.pci_sig_revisionid, iohdr.pci_sig_slot);
+	printk(RTAS_ERR "IOA Sending during the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n",
+	       iohdr.pci_send_busno, iohdr.pci_send_devfn >> 3, iohdr.pci_send_devfn & 0x7,
+	       iohdr.pci_send_vendorid, iohdr.pci_send_deviceid, iohdr.pci_send_revisionid, iohdr.pci_send_slot);
+
+}
+
+static void printk_post_failure(int version, struct exthdr *exthdr, char *data)
+{
+	struct posthdr posthdr;
+
+	memcpy(&posthdr, data, sizeof(posthdr));
+
+	if (posthdr.devname[0]) printk(RTAS_ERR "Failing Device: %s\n", posthdr.devname);
+	if (posthdr.firmware) printk(RTAS_ERR "Firmware Error\n");
+	if (posthdr.config) printk(RTAS_ERR "Configuration Error\n");
+	if (posthdr.cpu) printk(RTAS_ERR "CPU POST Error\n");
+	if (posthdr.memory) printk(RTAS_ERR "Memory POST Error\n");
+	if (posthdr.io) printk(RTAS_ERR "I/O Subsystem POST Error\n");
+	if (posthdr.keyboard) printk(RTAS_ERR "Keyboard POST Error\n");
+	if (posthdr.mouse) printk(RTAS_ERR "Mouse POST Error\n");
+	if (posthdr.display) printk(RTAS_ERR "Display POST Error\n");
+
+	if (posthdr.ipl_floppy) printk(RTAS_ERR "Floppy IPL Error\n");
+	if (posthdr.ipl_controller) printk(RTAS_ERR "Drive Controller Error during IPL\n");
+	if (posthdr.ipl_cdrom) printk(RTAS_ERR "CDROM IPL Error\n");
+	if (posthdr.ipl_disk) printk(RTAS_ERR "Disk IPL Error\n");
+	if (posthdr.ipl_net) printk(RTAS_ERR "Network IPL Error\n");
+	if (posthdr.ipl_other) printk(RTAS_ERR "Other (tape,flash) IPL Error\n");
+	if (posthdr.firmware_selftest) printk(RTAS_ERR "Self-test error in firmware extended diagnostics\n");
+	printk(RTAS_ERR "POST Code: %d\n", posthdr.post_code);
+	printk(RTAS_ERR "Firmware Revision Code: %d\n", posthdr.firmware_rev);
+}
+
+static void printk_epow_warning(int version, struct exthdr *exthdr, char *data)
+{
+	struct epowhdr epowhdr;
+
+	memcpy(&epowhdr, data, sizeof(epowhdr));
+	printk(RTAS_ERR "EPOW Sensor Value:  0x%08x\n", epowhdr.epow_sensor_value); 
+	if (epowhdr.sensor) {
+		printk(RTAS_ERR "EPOW detected by a sensor\n");
+		printk(RTAS_ERR "Sensor Token:  0x%08x\n", epowhdr.sensor_token); 
+		printk(RTAS_ERR "Sensor Index:  0x%08x\n", epowhdr.sensor_index); 
+		printk(RTAS_ERR "Sensor Value:  0x%08x\n", epowhdr.sensor_value); 
+		printk(RTAS_ERR "Sensor Status: 0x%08x\n", epowhdr.sensor_status);
+	}
+	if (epowhdr.power_fault) printk(RTAS_ERR "EPOW caused by a power fault\n");
+	if (epowhdr.fan) printk(RTAS_ERR "EPOW caused by fan failure\n");
+	if (epowhdr.temp) printk(RTAS_ERR "EPOW caused by over-temperature condition\n");
+	if (epowhdr.redundancy) printk(RTAS_ERR "EPOW warning due to loss of redundancy\n");
+	if (epowhdr.CUoD) printk(RTAS_ERR "EPOW warning due to CUoD Entitlement Exceeded\n");
+
+	if (epowhdr.general) printk(RTAS_ERR "EPOW general power fault\n");
+	if (epowhdr.power_loss) printk(RTAS_ERR "EPOW power fault due to loss of power source\n");
+	if (epowhdr.power_supply) printk(RTAS_ERR "EPOW power fault due to internal power supply failure\n");
+	if (epowhdr.power_switch) printk(RTAS_ERR "EPOW power fault due to activation of power switch\n");
+}
+
+static void printk_pm_event(int version, struct exthdr *exthdr, char *data)
+{
+	struct pm_eventhdr pm_eventhdr;
+
+	memcpy(&pm_eventhdr, data, sizeof(pm_eventhdr));
+	printk(RTAS_ERR "Event id: 0x%08x\n", pm_eventhdr.event_id);
+}
+
+static void printk_sp_log_msg(int version, struct exthdr *exthdr, char *data)
+{
+	struct sphdr sphdr;
+	u32 eyecatcher;
+
+	memcpy(&sphdr, data, sizeof(sphdr));
+
+	eyecatcher = sphdr.ibm;
+	if (strcmp((char *)&eyecatcher, "IBM") != 0)
+		printk(RTAS_ERR "This log entry may be corrupt (IBM signature malformed)\n");
+	if (sphdr.timeout) printk(RTAS_ERR "Timeout on communication response from service processor\n");
+	if (sphdr.i2c_bus) printk(RTAS_ERR "I2C general bus error\n");
+	if (sphdr.i2c_secondary_bus) printk(RTAS_ERR "I2C secondary bus error\n");
+	if (sphdr.sp_memory) printk(RTAS_ERR "Internal service processor memory error\n");
+	if (sphdr.sp_registers) printk(RTAS_ERR "Service processor error accessing special registers\n");
+	if (sphdr.sp_communication) printk(RTAS_ERR "Service processor reports unknown communcation error\n");
+	if (sphdr.sp_firmware) printk(RTAS_ERR "Internal service processor firmware error\n");
+	if (sphdr.sp_hardware) printk(RTAS_ERR "Other internal service processor hardware error\n");
+	if (sphdr.vpd_eeprom) printk(RTAS_ERR "Service processor error accessing VPD EEPROM\n");
+	if (sphdr.op_panel) printk(RTAS_ERR "Service processor error accessing Operator Panel\n");
+	if (sphdr.power_controller) printk(RTAS_ERR "Service processor error accessing Power Controller\n");
+	if (sphdr.fan_sensor) printk(RTAS_ERR "Service processor error accessing Fan Sensor\n");
+	if (sphdr.thermal_sensor) printk(RTAS_ERR "Service processor error accessing Thermal Sensor\n");
+	if (sphdr.voltage_sensor) printk(RTAS_ERR "Service processor error accessing Voltage Sensor\n");
+	if (sphdr.serial_port) printk(RTAS_ERR "Service processor error accessing serial port\n");
+	if (sphdr.nvram) printk(RTAS_ERR "Service processor detected NVRAM error\n");
+	if (sphdr.rtc) printk(RTAS_ERR "Service processor error accessing real time clock\n");
+	if (sphdr.jtag) printk(RTAS_ERR "Service processor error accessing JTAG/COP\n");
+	if (sphdr.tod_battery) printk(RTAS_ERR "Service processor or RTAS detects loss of voltage from TOD battery\n");
+	if (sphdr.heartbeat) printk(RTAS_ERR "Loss of heartbeat from Service processor\n");
+	if (sphdr.surveillance) printk(RTAS_ERR "Service processor detected a surveillance timeout\n");
+	if (sphdr.pcn_connection) printk(RTAS_ERR "Power Control Network general connection failure\n");
+	if (sphdr.pcn_node) printk(RTAS_ERR "Power Control Network node failure\n");
+	if (sphdr.pcn_access) printk(RTAS_ERR "Service processor error accessing Power Control Network\n");
+
+	if (sphdr.sensor_token) printk(RTAS_ERR "Sensor Token 0x%08x (%d)\n", sphdr.sensor_token, sphdr.sensor_token);
+	if (sphdr.sensor_index) printk(RTAS_ERR "Sensor Index 0x%08x (%d)\n", sphdr.sensor_index, sphdr.sensor_index);
+}
+
+
+static void printk_ext_raw_data(char *data)
+{
+	int i;
+	printk(RTAS_ERR "raw ext data: ");
+	for (i = 0; i < 40; i++) {
+		printk("%02x", data[i]);
+	}
+	printk("\n");
+}
+
+static void printk_ext_log_data(int version, char *buf)
+{
+	char *data = buf+12;
+	struct exthdr exthdr;
+	memcpy(&exthdr, buf, sizeof(exthdr));	/* copy for alignment */
+	if (!exthdr.valid) {
+		if (exthdr.bigendian && exthdr.power_pc)
+			printk(RTAS_ERR "extended log data is not valid\n");
+		else
+			printk(RTAS_ERR "extended log data can not be decoded\n");
+		return;
+	}
+
+	/* Dump useful stuff in the exthdr */
+	printk(RTAS_ERR "Status:%s%s%s%s%s\n",
+	       exthdr.unrecoverable ? " unrecoverable" : "",
+	       exthdr.recoverable ? " recoverable" : "",
+	       exthdr.unrecoverable_bypassed ? " bypassed" : "",
+	       exthdr.predictive ? " predictive" : "",
+	       exthdr.newlog ? " new" : "");
+	printk(RTAS_ERR "Date/Time: %08x %08x\n", exthdr.bcddate, exthdr.bcdtime);
+	switch (exthdr.format_type) {
+	    case EXTLOG_FMT_CPU:
+		printk(RTAS_ERR "CPU Failure\n");
+		printk_cpu_failure(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_MEMORY:
+		printk(RTAS_ERR "Memory Failure\n");
+		printk_mem_failure(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_IO:
+		printk(RTAS_ERR "I/O Failure\n");
+		printk_io_failure(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_POST:
+		printk(RTAS_ERR "POST Failure\n");
+		printk_post_failure(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_ENV:
+		printk(RTAS_ERR "Environment and Power Warning\n");
+		printk_epow_warning(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_POW:
+		printk(RTAS_ERR "Power Management Event\n");
+		printk_pm_event(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_IBMDIAG:
+		printk(RTAS_ERR "IBM Diagnostic Log\n");
+		printk_ext_raw_data(data);
+		break;
+	    case EXTLOG_FMT_IBMSP:
+		printk(RTAS_ERR "IBM Service Processor Log\n");
+		printk_sp_log_msg(version, &exthdr, data);
+		break;
+	    default:
+		printk(RTAS_ERR "Unknown ext format type %d\n", exthdr.format_type);
+		printk_ext_raw_data(data);
+		break;
+	}
+}
+
+
+/* Yeah, the output here is ugly, but we want a CE to be
+ * able to grep RTAS /var/log/messages and see all the info
+ * collected together with obvious begin/end.
+ */
+static void printk_log_rtas(char *buf)
+{
+	struct rtas_error_log *err = (struct rtas_error_log *)buf;
+
+	printk(RTAS_ERR "-------- event-scan begin --------\n");
+	if (strcmp(buf+8+40, "IBM") == 0) {
+		/* Location code follows */
+		char *loc = buf+8+40+4;
+		if (*loc >= 'A' && *loc <= 'Z')	/* Sanity check */
+			printk(RTAS_ERR "Location Code: %s\n", loc);
+	}
+
+	printk(RTAS_ERR "%s: (%s) type: %s\n",
+	       severity_names[err->severity],
+	       rtas_disposition_names[err->disposition],
+	       rtas_error_type(err->type));
+	printk(RTAS_ERR "initiator: %s  target: %s\n",
+	       entity_names[err->initiator], entity_names[err->target]);
+	if (err->extended_log_length)
+		printk_ext_log_data(err->version, buf+8);
+	printk(RTAS_ERR "-------- event-scan end ----------\n");
+}
+
+
+static void log_rtas(char *buf)
+{
+	unsigned long offset;
+
+	DEBUG("logging rtas event\n");
+
+	/* Temporary -- perhaps we can do this when nobody has the log open? */
+	printk_log_rtas(buf);
+
+	spin_lock(&rtas_log_lock);
+
+	offset = rtas_error_log_max *
+			((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK);
+
+	memcpy(&rtas_log_buf[offset], buf, rtas_error_log_max);
+
+	if (rtas_log_size < LOG_NUMBER)
+		rtas_log_size += 1;
+	else
+		rtas_log_start += 1;
+
+	spin_unlock(&rtas_log_lock);
+	wake_up_interruptible(&rtas_log_wait);
+}
+
+static int enable_surveillance(void)
+{
+	int error;
+
+	error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, SURVEILLANCE_TOKEN,
+			0, SURVEILLANCE_TIMEOUT);
+
+	if (error) {
+		printk(KERN_ERR "rtasd: could not enable surveillance\n");
+		return -1;
+	}
+
+	rtas_event_scan_rate = SURVEILLANCE_SCANRATE;
+
+	return 0;
+}
+
+static int get_eventscan_parms(void)
+{
+	struct device_node *node;
+	int *ip;
+
+	node = find_path_device("/rtas");
+
+	ip = (int *)get_property(node, "rtas-event-scan-rate", NULL);
+	if (ip == NULL) {
+		printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n");
+		return -1;
+	}
+	rtas_event_scan_rate = *ip;
+	DEBUG("rtas-event-scan-rate %d\n", rtas_event_scan_rate);
+
+	ip = (int *)get_property(node, "rtas-error-log-max", NULL);
+	if (ip == NULL) {
+		printk(KERN_ERR "rtasd: no rtas-error-log-max\n");
+		return -1;
+	}
+	rtas_error_log_max = *ip;
+	DEBUG("rtas-error-log-max %d\n", rtas_error_log_max);
+
+	if (rtas_error_log_max > RTAS_ERROR_LOG_MAX) {
+		printk(KERN_ERR "rtasd: truncated error log from %d to %d bytes\n", rtas_error_log_max, RTAS_ERROR_LOG_MAX);
+		rtas_error_log_max = RTAS_ERROR_LOG_MAX;
+	}
+
+	return 0;
+}
+
+extern long sys_sched_get_priority_max(int policy);
+
+static int rtasd(void *unused)
+{
+	int cpu = 0;
+	int error;
+	int first_pass = 1;
+	int event_scan = rtas_token("event-scan");
+
+	if (event_scan == RTAS_UNKNOWN_SERVICE || get_eventscan_parms() == -1)
+		goto error;
+
+	rtas_log_buf = vmalloc(rtas_error_log_max*LOG_NUMBER);
+	if (!rtas_log_buf) {
+		printk(KERN_ERR "rtasd: no memory\n");
+		goto error;
+	}
+
+	DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2);
+
+	daemonize();
+	sigfillset(&current->blocked);
+	sprintf(current->comm, "rtasd");
+
+	/* Rusty unreal time task */
+	current->policy = SCHED_FIFO;
+	current->nice = sys_sched_get_priority_max(SCHED_FIFO) + 1;
+
+	cpu = 0;
+	current->cpus_allowed = 1UL << cpu_logical_map(cpu);
+	schedule();
+
+	while(1) {
+		do {
+			memset(logdata, 0, rtas_error_log_max);
+			error = rtas_call(event_scan, 4, 1, NULL,
+					EVENT_SCAN_ALL_EVENTS, 0,
+					__pa(logdata), rtas_error_log_max);
+			if (error == -1) {
+				printk(KERN_ERR "event-scan failed\n");
+				break;
+			}
+
+			if (error == 0)
+				log_rtas(logdata);
+
+		} while(error == 0);
+
+		DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id());
+
+		cpu++;
+		if (cpu >= smp_num_cpus) {
+
+			if (first_pass && surveillance_requested) {
+				DEBUG("enabling surveillance\n");
+				if (enable_surveillance())
+					goto error_vfree;
+				DEBUG("surveillance enabled\n");
+			}
+
+			first_pass = 0;
+			cpu = 0;
+		}
+
+		current->cpus_allowed = 1UL << cpu_logical_map(cpu);
+
+		/* Check all cpus for pending events before sleeping*/
+		if (first_pass) {
+			schedule();
+		} else {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout((HZ*60/rtas_event_scan_rate) / 2);
+		}
+	}
+
+error_vfree:
+	vfree(rtas_log_buf);
+error:
+	/* Should delete proc entries */
+	return -EINVAL;
+}
+
+static void __init rtas_init(void)
+{
+	struct proc_dir_entry *rtas_dir, *entry;
+
+	rtas_dir = proc_mkdir("rtas", 0);
+	if (!rtas_dir) {
+		printk(KERN_ERR "Failed to create rtas proc directory\n");
+	} else {
+		entry = create_proc_entry("error_log", S_IRUSR, rtas_dir);
+		if (entry)
+			entry->proc_fops = &proc_rtas_log_operations;
+		else
+			printk(KERN_ERR "Failed to create rtas/error_log proc entry\n");
+	}
+
+	if (kernel_thread(rtasd, 0, CLONE_FS) < 0)
+		printk(KERN_ERR "Failed to start RTAS daemon\n");
+
+	printk(KERN_ERR "RTAS daemon started\n");
+}
+
+static int __init surveillance_setup(char *str)
+{
+	int i;
+
+	if (get_option(&str,&i)) {
+		if (i == 1)
+			surveillance_requested = 1;
+	}
+
+	return 1;
+}
+
+__initcall(rtas_init);
+__setup("surveillance=", surveillance_setup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/rtc.c linux/arch/ppc64/kernel/rtc.c
--- linux.orig/arch/ppc64/kernel/rtc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/rtc.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,382 @@
+/*
+ *	Real Time Clock interface for PPC64.
+ *
+ *	Based on rtc.c by Paul Gortmaker
+ *
+ *	This driver allows use of the real time clock
+ *	from user space. It exports the /dev/rtc
+ *	interface supporting various ioctl() and also the
+ *	/proc/driver/rtc pseudo-file for status information.
+ *
+ * 	Interface does not support RTC interrupts nor an alarm.
+ *
+ *	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.
+ *
+ *      1.0	Mike Corrigan:    IBM iSeries rtc support
+ *      1.1	Dave Engebretsen: IBM pSeries rtc support
+ */
+
+#define RTC_VERSION		"1.1"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/mc146818rtc.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/time.h>
+
+#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/mf.h>
+#include <asm/machdep.h>
+#include <asm/iSeries/ItSpCommArea.h>
+
+extern int piranha_simulator;
+
+/*
+ *	We sponge a minor off of the misc major. No need slurping
+ *	up another valuable major dev number for this. If you add
+ *	an ioctl, make sure you don't conflict with SPARC's RTC
+ *	ioctls.
+ */
+
+static loff_t rtc_llseek(struct file *file, loff_t offset, int origin);
+
+static ssize_t rtc_read(struct file *file, char *buf,
+			size_t count, loff_t *ppos);
+
+static int rtc_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg);
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+                         int count, int *eof, void *data);
+
+/*
+ *	If this driver ever becomes modularised, it will be really nice
+ *	to make the epoch retain its value across module reload...
+ */
+
+static unsigned long epoch = 1900;	/* year corresponding to 0x00	*/
+
+static const unsigned char days_in_mo[] = 
+{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+/*
+ *	Now all the various file operations that we export.
+ */
+
+static loff_t rtc_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+static ssize_t rtc_read(struct file *file, char *buf,
+			size_t count, loff_t *ppos)
+{
+	return -EIO;
+}
+
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg)
+{
+	struct rtc_time wtime; 
+
+	switch (cmd) {
+	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+	{
+		ppc_md.get_rtc_time(&wtime);
+		break;
+	}
+	case RTC_SET_TIME:	/* Set the RTC */
+	{
+		struct rtc_time rtc_tm;
+		unsigned char mon, day, hrs, min, sec, leap_yr;
+		unsigned int yrs;
+
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+
+		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
+				   sizeof(struct rtc_time)))
+			return -EFAULT;
+
+		yrs = rtc_tm.tm_year;
+		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
+		day = rtc_tm.tm_mday;
+		hrs = rtc_tm.tm_hour;
+		min = rtc_tm.tm_min;
+		sec = rtc_tm.tm_sec;
+
+		if (yrs < 70)
+			return -EINVAL;
+
+		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
+
+		if ((mon > 12) || (day == 0))
+			return -EINVAL;
+
+		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
+			return -EINVAL;
+			
+		if ((hrs >= 24) || (min >= 60) || (sec >= 60))
+			return -EINVAL;
+
+		if ( yrs > 169 )
+			return -EINVAL;
+
+		ppc_md.set_rtc_time(&rtc_tm);
+		
+		return 0;
+	}
+	case RTC_EPOCH_READ:	/* Read the epoch.	*/
+	{
+		return put_user (epoch, (unsigned long *)arg);
+	}
+	case RTC_EPOCH_SET:	/* Set the epoch.	*/
+	{
+		/* 
+		 * There were no RTC clocks before 1900.
+		 */
+		if (arg < 1900)
+			return -EINVAL;
+
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+
+		epoch = arg;
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
+}
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+static struct file_operations rtc_fops = {
+	owner:		THIS_MODULE,
+	llseek:		rtc_llseek,
+	read:		rtc_read,
+	ioctl:		rtc_ioctl,
+	open:		rtc_open,
+	release:	rtc_release,
+};
+
+static struct miscdevice rtc_dev=
+{
+	RTC_MINOR,
+	"rtc",
+	&rtc_fops
+};
+
+static int __init rtc_init(void)
+{
+	misc_register(&rtc_dev);
+	create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
+
+	printk(KERN_INFO "i/pSeries Real Time Clock Driver v" RTC_VERSION "\n");
+
+	return 0;
+}
+
+static void __exit rtc_exit (void)
+{
+	remove_proc_entry ("driver/rtc", NULL);
+	misc_deregister(&rtc_dev);
+}
+
+module_init(rtc_init);
+module_exit(rtc_exit);
+EXPORT_NO_SYMBOLS;
+
+/*
+ *	Info exported via "/proc/driver/rtc".
+ */
+
+static int rtc_proc_output (char *buf)
+{
+	
+	char *p;
+	struct rtc_time tm;
+	
+	p = buf;
+
+	ppc_md.get_rtc_time(&tm);
+
+	/*
+	 * There is no way to tell if the luser has the RTC set for local
+	 * time or for Universal Standard Time (GMT). Probably local though.
+	 */
+	p += sprintf(p,
+		     "rtc_time\t: %02d:%02d:%02d\n"
+		     "rtc_date\t: %04d-%02d-%02d\n"
+	 	     "rtc_epoch\t: %04lu\n",
+		     tm.tm_hour, tm.tm_min, tm.tm_sec,
+		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
+
+	p += sprintf(p,
+		     "DST_enable\t: no\n"
+		     "BCD\t\t: yes\n"
+		     "24hr\t\t: yes\n" );
+
+	return  p - buf;
+}
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+                         int count, int *eof, void *data)
+{
+        int len = rtc_proc_output (page);
+        if (len <= off+count) *eof = 1;
+        *start = page + off;
+        len -= off;
+        if (len>count) len = count;
+        if (len<0) len = 0;
+        return len;
+}
+
+/*
+ * Get the RTC from the virtual service processor
+ * This requires flowing LpEvents to the primary partition
+ */
+void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
+{
+	if (piranha_simulator)
+		return;
+
+	mf_getRtc(rtc_tm);
+	rtc_tm->tm_mon--;
+}
+
+
+void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
+{
+        unsigned long ret[8];
+        int error;
+	int count;
+
+	/*
+	 * error -2 is clock busy, we keep retrying a few times to see
+	 * if it will come good  -- paulus
+	 */
+	count = 0;
+	do {
+		error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret);
+	} while (error == -2 && ++count < 1000);
+
+        if (error != 0) {
+                printk(KERN_WARNING "error: reading the clock failed (%d)\n",
+		       error);
+		return;
+        }
+
+	rtc_tm->tm_sec = ret[5];
+	rtc_tm->tm_min = ret[4];
+	rtc_tm->tm_hour = ret[3];
+	rtc_tm->tm_mday = ret[2];
+	rtc_tm->tm_mon = ret[1] - 1;
+	rtc_tm->tm_year = ret[0] - 1900;
+}
+
+int pSeries_set_rtc_time(struct rtc_time *tm)
+{
+        int error;
+	int count;
+
+	/*
+	 * error -2 is clock busy, we keep retrying a few times to see
+	 * if it will come good  -- paulus
+	 */
+	count = 0;
+	do {
+	        error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
+				  tm->tm_year + 1900, tm->tm_mon + 1, 
+				  tm->tm_mday, tm->tm_hour, tm->tm_min, 
+				  tm->tm_sec, 0);
+	} while (error == -2 && ++count < 1000);
+
+        if (error != 0)
+                printk(KERN_WARNING "error: setting the clock failed (%d)\n",
+		       error); 
+
+        return 0;
+}
+
+/*
+ * Set the RTC in the virtual service processor
+ * This requires flowing LpEvents to the primary partition
+ */
+int iSeries_set_rtc_time(struct rtc_time *tm)
+{
+	mf_setRtc(tm);
+	return 0;
+}
+
+void iSeries_get_boot_time(struct rtc_time *tm)
+{
+	unsigned long time;
+	static unsigned long lastsec = 1;
+
+	u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
+	u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
+	int year = 1970;
+	int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
+	int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
+	int sec = ( dataWord1 >> 8 ) & 0x000000FF;
+	int min = dataWord1 & 0x000000FF;
+	int hour = ( dataWord2 >> 24 ) & 0x000000FF;
+	int day = ( dataWord2 >> 8 ) & 0x000000FF;
+	int mon = dataWord2 & 0x000000FF;
+
+	if ( piranha_simulator )
+		return;
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hour);
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(year1);
+	BCD_TO_BIN(year2);
+	year = year1 * 100 + year2;
+
+	time = mktime(year, mon, day, hour, min, sec);
+	time += ( jiffies / HZ );
+
+	/* Now THIS is a nasty hack!
+	* It ensures that the first two calls get different answers.  
+	* That way the loop in init_time (time.c) will not think
+	* the clock is stuck.
+	*/
+	if ( lastsec ) {
+		time -= lastsec;
+		--lastsec;
+	}
+
+	to_tm(time, tm); 
+	tm->tm_year -= 1900;
+	tm->tm_mon  -= 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/semaphore.c linux/arch/ppc64/kernel/semaphore.c
--- linux.orig/arch/ppc64/kernel/semaphore.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/semaphore.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,131 @@
+/*
+ * 
+ *
+ * PowerPC-specific semaphore code.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ *
+ * 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.
+ *
+ * April 2001 - Reworked by Paul Mackerras <paulus@samba.org>
+ * to eliminate the SMP races in the old version between the updates
+ * of `count' and `waking'.  Now we use negative `count' values to
+ * indicate that some process(es) are waiting for the semaphore.
+ */
+
+#include <linux/sched.h>
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+#include <asm/errno.h>
+
+/*
+ * Atomically update sem->count.
+ * This does the equivalent of the following:
+ *
+ *	old_count = sem->count;
+ *	tmp = MAX(old_count, 0) + incr;
+ *	sem->count = tmp;
+ *	return old_count;
+ */
+static inline int __sem_update_count(struct semaphore *sem, int incr)
+{
+	int old_count, tmp;
+
+	__asm__ __volatile__("\n"
+"1:	lwarx	%0,0,%3\n"
+"	srawi	%1,%0,31\n"
+"	andc	%1,%0,%1\n"
+"	add	%1,%1,%4\n"
+"	stwcx.	%1,0,%3\n"
+"	bne	1b"
+	: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+	: "r" (&sem->count), "r" (incr), "m" (sem->count)
+	: "cc");
+
+	return old_count;
+}
+
+void __up(struct semaphore *sem)
+{
+	/*
+	 * Note that we incremented count in up() before we came here,
+	 * but that was ineffective since the result was <= 0, and
+	 * any negative value of count is equivalent to 0.
+	 * This ends up setting count to 1, unless count is now > 0
+	 * (i.e. because some other cpu has called up() in the meantime),
+	 * in which case we just increment count.
+	 */
+	__sem_update_count(sem, 1);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Note that when we come in to __down or __down_interruptible,
+ * we have already decremented count, but that decrement was
+ * ineffective since the result was < 0, and any negative value
+ * of count is equivalent to 0.
+ * Thus it is only when we decrement count from some value > 0
+ * that we have actually got the semaphore.
+ */
+void __down(struct semaphore *sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+	smp_wmb();
+
+	/*
+	 * Try to get the semaphore.  If the count is > 0, then we've
+	 * got the semaphore; we decrement count and exit the loop.
+	 * If the count is 0 or negative, we set it to -1, indicating
+	 * that we are asleep, and then sleep.
+	 */
+	while (__sem_update_count(sem, -1) <= 0) {
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+	}
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+
+	/*
+	 * If there are any more sleepers, wake one of them up so
+	 * that it can either get the semaphore, or set count to -1
+	 * indicating that there are still processes sleeping.
+	 */
+	wake_up(&sem->wait);
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+	smp_wmb();
+
+	while (__sem_update_count(sem, -1) <= 0) {
+		if (signal_pending(current)) {
+			/*
+			 * A signal is pending - give up trying.
+			 * Set sem->count to 0 if it is negative,
+			 * since we are no longer sleeping.
+			 */
+			__sem_update_count(sem, 0);
+			retval = -EINTR;
+			break;
+		}
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
+	}
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/setup.c linux/arch/ppc64/kernel/setup.c
--- linux.orig/arch/ppc64/kernel/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/setup.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,718 @@
+/*
+ * 
+ * Common boot and setup code.
+ *
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+#include <linux/delay.h>
+#include <linux/blk.h>
+#include <linux/ide.h>
+#include <linux/seq_file.h>
+#include <linux/ioport.h>
+#include <asm/init.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/bootinfo.h>
+#include <asm/smp.h>
+#include <asm/elf.h>
+#include <asm/machdep.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
+#include <asm/ppcdebug.h>
+#include <asm/time.h>
+
+extern unsigned long klimit;
+/* extern void *stab; */
+extern HTAB htab_data;
+extern unsigned long loops_per_jiffy;
+
+extern unsigned long embedded_sysmap_start;
+extern unsigned long embedded_sysmap_end;
+
+int have_of = 1;
+
+extern void  chrp_init(unsigned long r3,
+		       unsigned long r4,
+		       unsigned long r5,
+		       unsigned long r6,
+		       unsigned long r7);
+
+extern void chrp_init_map_io_space( void );
+extern void iSeries_init( void );
+extern void iSeries_init_early( void );
+extern void pSeries_init_early( void );
+extern void pSeriesLP_init_early(void);
+extern void mm_init_ppc64( void ); 
+
+unsigned long decr_overclock = 1;
+unsigned long decr_overclock_proc0 = 1;
+unsigned long decr_overclock_set = 0;
+unsigned long decr_overclock_proc0_set = 0;
+
+#ifdef CONFIG_XMON
+extern void xmon_map_scc(void);
+#endif
+
+char saved_command_line[256];
+unsigned char aux_device_present;
+
+void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5,
+		    unsigned long r6, unsigned long r7);
+int parse_bootinfo(void);
+
+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned long SYSRQ_KEY;
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+struct machdep_calls ppc_md;
+
+/*
+ * Perhaps we can put the pmac screen_info[] here
+ * on pmac as well so we don't need the ifdef's.
+ * Until we get multiple-console support in here
+ * that is.  -- Cort
+ * Maybe tie it to serial consoles, since this is really what
+ * these processors use on existing boards.  -- Dan
+ */ 
+struct screen_info screen_info = {
+	0, 25,			/* orig-x, orig-y */
+	0,			/* unused */
+	0,			/* orig-video-page */
+	0,			/* orig-video-mode */
+	80,			/* orig-video-cols */
+	0,0,0,			/* ega_ax, ega_bx, ega_cx */
+	25,			/* orig-video-lines */
+	1,			/* orig-video-isVGA */
+	16			/* orig-video-points */
+};
+
+/*
+ * These are used in binfmt_elf.c to put aux entries on the stack
+ * for each elf executable being started.
+ */
+int dcache_bsize;
+int icache_bsize;
+int ucache_bsize;
+
+/*
+ * Initialize the PPCDBG state.  Called before relocation has been enabled.
+ */
+void ppcdbg_initialize(void) {
+	unsigned long offset = reloc_offset();
+	struct naca_struct *_naca = RELOC(naca);
+
+	_naca->debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */;
+}
+
+/*
+ * Do some initial setup of the system.  The paramters are those which 
+ * were passed in from the bootloader.
+ */
+void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
+		  unsigned long r6, unsigned long r7)
+{
+	/* This should be fixed properly in kernel/resource.c */
+	iomem_resource.end = MEM_SPACE_LIMIT;
+
+	/* pSeries systems are identified in prom.c via OF. */
+	if ( itLpNaca.xLparInstalled == 1 )
+		naca->platform = PLATFORM_ISERIES_LPAR;
+	
+	switch (naca->platform) {
+	case PLATFORM_ISERIES_LPAR:
+		iSeries_init_early();
+		break;
+
+#ifdef CONFIG_PPC_PSERIES
+	case PLATFORM_PSERIES:
+		pSeries_init_early();
+#ifdef CONFIG_BLK_DEV_INITRD
+		initrd_start = initrd_end = 0;
+#endif
+		parse_bootinfo();
+		break;
+
+	case PLATFORM_PSERIES_LPAR:
+		pSeriesLP_init_early();
+#ifdef CONFIG_BLK_DEV_INITRD
+		initrd_start = initrd_end = 0;
+#endif
+		parse_bootinfo();
+		break;
+#endif
+	}
+
+	udbg_puts("\n-----------------------------------------------------\n");
+	udbg_puts("Naca Info...\n\n");
+	udbg_puts("naca                       = 0x");
+	udbg_puthex((unsigned long)naca);
+	udbg_putc('\n');
+
+	udbg_puts("naca->processorCount       = 0x");
+	udbg_puthex(naca->processorCount);
+	udbg_putc('\n');
+
+	udbg_puts("naca->physicalMemorySize   = 0x");
+	udbg_puthex(naca->physicalMemorySize);
+	udbg_putc('\n');
+
+	udbg_puts("naca->dCacheL1LineSize     = 0x");
+	udbg_puthex(naca->dCacheL1LineSize);
+	udbg_putc('\n');
+
+	udbg_puts("naca->dCacheL1LogLineSize  = 0x");
+	udbg_puthex(naca->dCacheL1LogLineSize);
+	udbg_putc('\n');
+
+	udbg_puts("naca->dCacheL1LinesPerPage = 0x");
+	udbg_puthex(naca->dCacheL1LinesPerPage);
+	udbg_putc('\n');
+
+	udbg_puts("naca->iCacheL1LineSize     = 0x");
+	udbg_puthex(naca->iCacheL1LineSize);
+	udbg_putc('\n');
+
+	udbg_puts("naca->iCacheL1LogLineSize  = 0x");
+	udbg_puthex(naca->iCacheL1LogLineSize);
+	udbg_putc('\n');
+
+	udbg_puts("naca->iCacheL1LinesPerPage = 0x");
+	udbg_puthex(naca->iCacheL1LinesPerPage);
+	udbg_putc('\n');
+
+	udbg_puts("naca->pftSize              = 0x");
+	udbg_puthex(naca->pftSize);
+	udbg_putc('\n');
+
+	udbg_puts("naca->serialPortAddr       = 0x");
+	udbg_puthex(naca->serialPortAddr);
+	udbg_putc('\n');
+
+	udbg_puts("naca->interrupt_controller = 0x");
+	udbg_puthex(naca->interrupt_controller);
+	udbg_putc('\n');
+
+	udbg_printf("\nHTAB Info ...\n\n"); 
+	udbg_puts("htab_data.htab             = 0x");
+	udbg_puthex((unsigned long)htab_data.htab);
+	udbg_putc('\n');
+	udbg_puts("htab_data.num_ptegs        = 0x");
+	udbg_puthex(htab_data.htab_num_ptegs);
+	udbg_putc('\n');
+
+	udbg_puts("\n-----------------------------------------------------\n");
+
+
+	if (naca->platform & PLATFORM_PSERIES) {
+		finish_device_tree();
+		chrp_init(r3, r4, r5, r6, r7);
+	}
+
+	mm_init_ppc64();
+
+	switch (naca->platform) {
+	case PLATFORM_ISERIES_LPAR:
+		iSeries_init();
+		break;
+	default:
+		/* The following relies on the device tree being */
+		/* fully configured.                             */
+		parse_cmd_line(r3, r4, r5, r6, r7);
+	}
+}
+
+void machine_restart(char *cmd)
+{
+	ppc_md.restart(cmd);
+}
+  
+void machine_power_off(void)
+{
+	ppc_md.power_off();
+}
+  
+void machine_halt(void)
+{
+	ppc_md.halt();
+}
+
+unsigned long ppc_proc_freq;
+unsigned long ppc_tb_freq;
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+	unsigned long cpu_id = (unsigned long)v - 1;
+	unsigned int pvr;
+	unsigned short maj;
+	unsigned short min;
+
+#ifdef CONFIG_SMP
+	if (cpu_id == NR_CPUS) {
+
+		if (ppc_md.get_cpuinfo != NULL)
+			ppc_md.get_cpuinfo(m);
+
+		return 0;
+	}
+
+	if (!(cpu_online_map & (1<<cpu_id)))
+		return 0;
+#endif
+
+	pvr = paca[cpu_id].pvr;
+	maj = (pvr >> 8) & 0xFF;
+	min = pvr & 0xFF;
+
+	seq_printf(m, "processor\t: %lu\n", cpu_id);
+	seq_printf(m, "cpu\t\t: ");
+
+	pvr = paca[cpu_id].pvr;
+
+	switch (PVR_VER(pvr)) {
+	case PV_PULSAR:
+		seq_printf(m, "RS64-III (pulsar)\n");
+		break;
+	case PV_POWER4:
+		seq_printf(m, "POWER4 (gp)\n");
+		break;
+	case PV_ICESTAR:
+		seq_printf(m, "RS64-III (icestar)\n");
+		break;
+	case PV_SSTAR:
+		seq_printf(m, "RS64-IV (sstar)\n");
+		break;
+	case PV_630:
+		seq_printf(m, "POWER3 (630)\n");
+		break;
+	case PV_630p:
+		seq_printf(m, "POWER3 (630+)\n");
+		break;
+	default:
+		seq_printf(m, "Unknown (%08x)\n", pvr);
+		break;
+	}
+
+	/*
+	 * Assume here that all clock rates are the same in a
+	 * smp system.  -- Cort
+	 */
+	if (naca->platform != PLATFORM_ISERIES_LPAR) {
+		struct device_node *cpu_node;
+		int *fp;
+
+		cpu_node = find_type_devices("cpu");
+		if (cpu_node) {
+			fp = (int *) get_property(cpu_node, "clock-frequency",
+						  NULL);
+			if (fp)
+				seq_printf(m, "clock\t\t: %dMHz\n",
+					   *fp / 1000000);
+		}
+	}
+
+	if (ppc_md.setup_residual != NULL)
+		ppc_md.setup_residual(m, cpu_id);
+
+	seq_printf(m, "revision\t: %hd.%hd\n", maj, min);
+	
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL;
+}
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
+
+/*
+ * Fetch the cmd_line from open firmware. */
+void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5,
+		  unsigned long r6, unsigned long r7)
+{
+	struct device_node *chosen;
+	char *p;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if ((initrd_start == 0) && r3 && r4 && r4 != 0xdeadbeef) {
+		initrd_start = (r3 >= KERNELBASE) ? r3 : (unsigned long)__va(r3);
+		initrd_end = initrd_start + r4;
+		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+		initrd_below_start_ok = 1;
+	}
+#endif
+
+	cmd_line[0] = 0;
+	chosen = find_devices("chosen");
+	if (chosen != NULL) {
+		p = get_property(chosen, "bootargs", NULL);
+		if (p != NULL)
+			strncpy(cmd_line, p, sizeof(cmd_line));
+	}
+	cmd_line[sizeof(cmd_line) - 1] = 0;
+
+	/* Look for mem= option on command line */
+	if (strstr(cmd_line, "mem=")) {
+		char *p, *q;
+		unsigned long maxmem = 0;
+		extern unsigned long __max_memory;
+
+		for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
+			q = p + 4;
+			if (p > cmd_line && p[-1] != ' ')
+				continue;
+			maxmem = simple_strtoul(q, &q, 0);
+			if (*q == 'k' || *q == 'K') {
+				maxmem <<= 10;
+				++q;
+			} else if (*q == 'm' || *q == 'M') {
+				maxmem <<= 20;
+				++q;
+			}
+		}
+		__max_memory = maxmem;
+	}
+	ppc_md.progress("id mach: done", 0x200);
+}
+
+
+char *bi_tag2str(unsigned long tag)
+{
+	switch (tag) {
+	case BI_FIRST:
+		return "BI_FIRST";
+	case BI_LAST:
+		return "BI_LAST";
+	case BI_CMD_LINE:
+		return "BI_CMD_LINE";
+	case BI_BOOTLOADER_ID:
+		return "BI_BOOTLOADER_ID";
+	case BI_INITRD:
+		return "BI_INITRD";
+	case BI_SYSMAP:
+		return "BI_SYSMAP";
+	case BI_MACHTYPE:
+		return "BI_MACHTYPE";
+	default:
+		return "BI_UNKNOWN";
+	}
+}
+
+int parse_bootinfo(void)
+{
+	struct bi_record *rec;
+	extern char *sysmap;
+	extern unsigned long sysmap_size;
+
+	rec = prom.bi_recs;
+
+	if ( rec == NULL || rec->tag != BI_FIRST )
+		return -1;
+
+	for ( ; rec->tag != BI_LAST ; rec = bi_rec_next(rec) ) {
+		switch (rec->tag) {
+		case BI_CMD_LINE:
+			memcpy(cmd_line, (void *)rec->data, rec->size);
+			break;
+		case BI_SYSMAP:
+			sysmap = (char *)((rec->data[0] >= (KERNELBASE))
+					? rec->data[0] : (unsigned long)__va(rec->data[0]));
+			sysmap_size = rec->data[1];
+			break;
+#ifdef CONFIG_BLK_DEV_INITRD
+		case BI_INITRD:
+			initrd_start = (unsigned long)__va(rec->data[0]);
+			initrd_end = initrd_start + rec->data[1];
+			ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+			initrd_below_start_ok = 1;
+			break;
+#endif /* CONFIG_BLK_DEV_INITRD */
+		}
+	}
+
+	return 0;
+}
+
+void __init ppc_init(void)
+{
+	/* clear the progress line */
+	ppc_md.progress(" ", 0xffff);
+
+	if (ppc_md.init != NULL) {
+		ppc_md.init();
+	}
+}
+
+void __init ppc64_calibrate_delay(void)
+{
+	loops_per_jiffy = tb_ticks_per_jiffy;
+
+	printk("Calibrating delay loop... %lu.%02lu BogoMips\n",
+			       loops_per_jiffy/(500000/HZ),
+			       loops_per_jiffy/(5000/HZ) % 100);
+
+}	
+
+extern void (*calibrate_delay)(void);
+
+/*
+ * Called into from start_kernel, after lock_kernel has been called.
+ * Initializes bootmem, which is unsed to manage page allocation until
+ * mem_init is called.
+ */
+void __init setup_arch(char **cmdline_p)
+{
+	extern int panic_timeout;
+	extern char _etext[], _edata[];
+	extern void do_init_bootmem(void);
+
+	calibrate_delay = ppc64_calibrate_delay;
+
+#ifdef CONFIG_XMON
+	xmon_map_scc();
+	if (strstr(cmd_line, "xmon"))
+		xmon(0);
+#endif /* CONFIG_XMON */
+#ifdef CONFIG_KDB
+	xmon_map_scc();	/* in kdb/start.c --need to rename TAI */
+#endif
+	ppc_md.progress("setup_arch:enter", 0x3eab);
+
+#if defined(CONFIG_KGDB)
+	kgdb_map_scc();
+	set_debug_traps();
+	breakpoint();
+#endif
+	/*
+	 * Set cache line size based on type of cpu as a default.
+	 * Systems with OF can look in the properties on the cpu node(s)
+	 * for a possibly more accurate value.
+	 */
+	dcache_bsize = naca->dCacheL1LineSize; 
+	icache_bsize = naca->iCacheL1LineSize; 
+
+	/* reboot on panic */
+	panic_timeout = 180;
+
+	init_mm.start_code = PAGE_OFFSET;
+	init_mm.end_code = (unsigned long) _etext;
+	init_mm.end_data = (unsigned long) _edata;
+	init_mm.brk = (unsigned long) klimit;
+	
+	/* Save unparsed command line copy for /proc/cmdline */
+	strcpy(saved_command_line, cmd_line);
+	*cmdline_p = cmd_line;
+
+	/* set up the bootmem stuff with available memory */
+	do_init_bootmem();
+	ppc_md.progress("setup_arch:bootmem", 0x3eab);
+
+	ppc_md.setup_arch();
+
+	paging_init();
+	ppc_md.progress("setup_arch: exit", 0x3eab);
+}
+
+#ifdef CONFIG_IDE
+
+/* Convert the shorts/longs in hd_driveid from little to big endian;
+ * chars are endian independant, of course, but strings need to be flipped.
+ * (Despite what it says in drivers/block/ide.h, they come up as little
+ * endian...)
+ *
+ * Changes to linux/hdreg.h may require changes here. */
+void ppc64_ide_fix_driveid(struct hd_driveid *id)
+{
+        int i;
+	unsigned short *stringcast;
+
+	id->config         = __le16_to_cpu(id->config);
+	id->cyls           = __le16_to_cpu(id->cyls);
+	id->reserved2      = __le16_to_cpu(id->reserved2);
+	id->heads          = __le16_to_cpu(id->heads);
+	id->track_bytes    = __le16_to_cpu(id->track_bytes);
+	id->sector_bytes   = __le16_to_cpu(id->sector_bytes);
+	id->sectors        = __le16_to_cpu(id->sectors);
+	id->vendor0        = __le16_to_cpu(id->vendor0);
+	id->vendor1        = __le16_to_cpu(id->vendor1);
+	id->vendor2        = __le16_to_cpu(id->vendor2);
+	stringcast = (unsigned short *)&id->serial_no[0];
+	for (i = 0; i < (20/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	id->buf_type       = __le16_to_cpu(id->buf_type);
+	id->buf_size       = __le16_to_cpu(id->buf_size);
+	id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
+	stringcast = (unsigned short *)&id->fw_rev[0];
+	for (i = 0; i < (8/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	stringcast = (unsigned short *)&id->model[0];
+	for (i = 0; i < (40/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	id->dword_io       = __le16_to_cpu(id->dword_io);
+	id->reserved50     = __le16_to_cpu(id->reserved50);
+	id->field_valid    = __le16_to_cpu(id->field_valid);
+	id->cur_cyls       = __le16_to_cpu(id->cur_cyls);
+	id->cur_heads      = __le16_to_cpu(id->cur_heads);
+	id->cur_sectors    = __le16_to_cpu(id->cur_sectors);
+	id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);
+	id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);
+	id->lba_capacity   = __le32_to_cpu(id->lba_capacity);
+	id->dma_1word      = __le16_to_cpu(id->dma_1word);
+	id->dma_mword      = __le16_to_cpu(id->dma_mword);
+	id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
+	id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);
+	id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
+	id->eide_pio       = __le16_to_cpu(id->eide_pio);
+	id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
+	for (i = 0; i < 2; i++)
+		id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
+        for (i = 0; i < 4; i++)
+                id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
+	id->queue_depth	   = __le16_to_cpu(id->queue_depth);
+	for (i = 0; i < 4; i++)
+		id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
+	id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
+	id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
+	id->command_set_1  = __le16_to_cpu(id->command_set_1);
+	id->command_set_2  = __le16_to_cpu(id->command_set_2);
+	id->cfsse          = __le16_to_cpu(id->cfsse);
+	id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);
+	id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);
+	id->csf_default    = __le16_to_cpu(id->csf_default);
+	id->dma_ultra      = __le16_to_cpu(id->dma_ultra);
+	id->word89         = __le16_to_cpu(id->word89);
+	id->word90         = __le16_to_cpu(id->word90);
+	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
+	id->word92         = __le16_to_cpu(id->word92);
+	id->hw_config      = __le16_to_cpu(id->hw_config);
+	id->acoustic       = __le16_to_cpu(id->acoustic);
+	for (i = 0; i < 5; i++)
+		id->words95_99[i]  = __le16_to_cpu(id->words95_99[i]);
+	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
+	for (i = 0; i < 21; i++)
+		id->words104_125[i]  = __le16_to_cpu(id->words104_125[i]);
+	id->last_lun       = __le16_to_cpu(id->last_lun);
+	id->word127        = __le16_to_cpu(id->word127);
+	id->dlf            = __le16_to_cpu(id->dlf);
+	id->csfo           = __le16_to_cpu(id->csfo);
+	for (i = 0; i < 26; i++)
+		id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
+	id->word156        = __le16_to_cpu(id->word156);
+	for (i = 0; i < 3; i++)
+		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
+	id->cfa_power=__le16_to_cpu(id->cfa_power);
+	for (i = 0; i < 15; i++)
+		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
+	for (i = 0; i < 29; i++)
+		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
+	for (i = 0; i < 48; i++)
+		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
+	id->integrity_word=__le16_to_cpu(id->integrity_word);
+}
+#endif
+
+
+void exception_trace(unsigned long trap)
+{
+	unsigned long x, srr0, srr1, reg20, reg1, reg21;
+
+	asm("mflr %0" : "=r" (x) :);
+	asm("mfspr %0,0x1a" : "=r" (srr0) :);
+	asm("mfspr %0,0x1b" : "=r" (srr1) :);
+	asm("mr %0,1" : "=r" (reg1) :);
+	asm("mr %0,20" : "=r" (reg20) :);
+	asm("mr %0,21" : "=r" (reg21) :);
+
+	udbg_puts("\n");
+	udbg_puts("Took an exception : "); udbg_puthex(x); udbg_puts("\n");
+	udbg_puts("   "); udbg_puthex(reg1); udbg_puts("\n");
+	udbg_puts("   "); udbg_puthex(reg20); udbg_puts("\n");
+	udbg_puts("   "); udbg_puthex(reg21); udbg_puts("\n");
+	udbg_puts("   "); udbg_puthex(srr0); udbg_puts("\n");
+	udbg_puts("   "); udbg_puthex(srr1); udbg_puts("\n");
+}
+
+int set_spread_lpevents( char * str )
+{
+	/* The parameter is the number of processors to share in processing lp events */
+	unsigned long i;
+	unsigned long val = simple_strtoul( str, NULL, 0 );
+	if ( ( val > 0 ) && ( val <= MAX_PACAS ) ) {
+		for ( i=1; i<val; ++i )
+			paca[i].lpQueuePtr = paca[0].lpQueuePtr;
+		printk("lpevent processing spread over %ld processors\n", val);
+	}
+	else
+		printk("invalid spreaqd_lpevents %ld\n", val);
+	return 1;
+}	
+
+/* This should only be called on processor 0 during calibrate decr */
+void setup_default_decr(void)
+{
+	struct paca_struct *lpaca = get_paca();
+
+	if ( decr_overclock_set && !decr_overclock_proc0_set )
+		decr_overclock_proc0 = decr_overclock;
+
+	lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;	
+	lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
+}
+
+int set_decr_overclock_proc0( char * str )
+{
+	unsigned long val = simple_strtoul( str, NULL, 0 );
+	if ( ( val >= 1 ) && ( val <= 48 ) ) {
+		decr_overclock_proc0_set = 1;
+		decr_overclock_proc0 = val;
+		printk("proc 0 decrementer overclock factor of %ld\n", val);
+	}
+	else
+		printk("invalid proc 0 decrementer overclock factor of %ld\n", val);
+	return 1;
+}
+
+int set_decr_overclock( char * str )
+{
+	unsigned long val = simple_strtoul( str, NULL, 0 );
+	if ( ( val >= 1 ) && ( val <= 48 ) ) {
+		decr_overclock_set = 1;
+		decr_overclock = val;
+		printk("decrementer overclock factor of %ld\n", val);
+	}
+	else
+		printk("invalid decrementer overclock factor of %ld\n", val);
+	return 1;
+
+}
+
+__setup("spread_lpevents=", set_spread_lpevents );
+__setup("decr_overclock_proc0=", set_decr_overclock_proc0 );
+__setup("decr_overclock=", set_decr_overclock );
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/signal.c linux/arch/ppc64/kernel/signal.c
--- linux.orig/arch/ppc64/kernel/signal.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/signal.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,790 @@
+/*
+ *  linux/arch/ppc64/kernel/signal.c
+ *
+ *  
+ *
+ *  PowerPC version 
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Derived from "arch/i386/kernel/signal.c"
+ *    Copyright (C) 1991, 1992 Linus Torvalds
+ *    1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/elf.h>
+#include <asm/ppc32.h>
+#include <asm/sigcontext.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/ppcdebug.h>
+#include <asm/unistd.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define GP_REGS_SIZE	MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+
+/* 
+ * These are the flags in the MSR that the user is allowed to change
+ * by modifying the saved value of the MSR on the stack.  SE and BE
+ * should not be in this list since gdb may want to change these.  I.e,
+ * you should be able to step out of a signal handler to see what
+ * instruction executes next after the signal handler completes.
+ * Alternately, if you stepped into a signal handler, you should be
+ * able to continue 'til the next breakpoint from within the signal
+ * handler, even if the handler returns.
+ */
+#define MSR_USERCHANGE	(MSR_FE0 | MSR_FE1)
+
+int do_signal(sigset_t *oldset, struct pt_regs *regs);
+extern long sys_wait4(pid_t pid, unsigned int *stat_addr,
+		     int options, /*unsigned long*/ struct rusage *ru);
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
+	       struct pt_regs *regs)
+{
+	sigset_t saveset;
+  
+        PPCDBG(PPCDBG_SYS64X, "sys_sigsuspend - running - pid=%ld current=%lx comm=%s \n",
+                current->pid, current, current->comm);
+
+
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->gpr[3] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			/*
+			 * If a signal handler needs to be called,
+			 * do_signal() has set R3 to the signal number (the
+			 * first argument of the signal handler), so don't
+			 * overwrite that with EINTR !
+			 * In the other cases, do_signal() doesn't touch 
+			 * R3, so it's still set to -EINTR (see above).
+			 */
+			return regs->gpr[3];
+	}
+}
+
+long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
+		  int p7, struct pt_regs *regs)
+{
+	sigset_t saveset, newset;
+
+  
+        PPCDBG(PPCDBG_SYS64X, "sys_rt_sigsuspend - running - pid=%ld current=%lx comm=%s \n",
+                current->pid, current, current->comm);
+	
+  /* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->gpr[3] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return regs->gpr[3];
+	}
+}
+
+
+
+asmlinkage long sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+  struct pt_regs *regs = (struct pt_regs *) &uss;
+  
+  PPCDBG(PPCDBG_SYS64X, "sys_sigaltstack - running - pid=%ld current=%lx comm=%s \n",
+          current->pid, current, current->comm);
+
+  return do_sigaltstack(uss, uoss, regs->gpr[1]);
+}
+
+long sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+        PPCDBG(PPCDBG_SYS64X, "sys_sigaction - running - pid=%ld current=%lx comm=%s \n",
+                current->pid, current, current->comm);
+
+ 
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+
+ 
+
+	return ret;
+}
+
+/*
+ * When we have signals to deliver, we set up on the
+ * user stack, going down from the original stack pointer:
+ *	a sigregs struct
+ *	one or more sigcontext structs
+ *	a gap of __SIGNAL_FRAMESIZE bytes
+ *
+ * Each of these things must be a multiple of 16 bytes in size.
+ *
+ * XXX ultimately we will have to stack up a siginfo and ucontext
+ * for each rt signal.
+ */
+struct sigregs {
+	elf_gregset_t	gp_regs;
+	double		fp_regs[ELF_NFPREG];
+	unsigned int	tramp[2];
+	/* 64 bit API allows for 288 bytes below sp before 
+	   decrementing it. */
+	int		abigap[72];
+};
+
+
+
+struct rt_sigframe
+{
+	unsigned long	_unused[2];
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+
+/*
+ *  When we have rt signals to deliver, we set up on the
+ *  user stack, going down from the original stack pointer:
+ *	   a sigregs struct
+ *	   one rt_sigframe struct (siginfo + ucontext)
+ *	   a gap of __SIGNAL_FRAMESIZE bytes
+ *
+ *  Each of these things must be a multiple of 16 bytes in size.
+ *
+ */
+
+int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
+		     unsigned long r6, unsigned long r7, unsigned long r8,
+		     struct pt_regs *regs)
+{
+	struct rt_sigframe *rt_sf;
+	struct sigcontext_struct sigctx;
+	struct sigregs *sr;
+	int ret;
+	elf_gregset_t saved_regs;  /* an array of ELF_NGREG unsigned longs */
+	sigset_t set;
+	stack_t st;
+	unsigned long prevsp;
+
+	rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+	if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))
+	    || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set))
+	    || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
+		goto badframe;
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	rt_sf++;			/* Look at next rt_sigframe */
+	if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) {
+		/* Last stacked signal - restore registers -
+		 * sigctx is initialized to point to the 
+		 * preamble frame (where registers are stored) 
+		 * see handle_signal()
+		 */
+		sr = (struct sigregs *) sigctx.regs;
+		if (regs->msr & MSR_FP )
+			giveup_fpu(current);
+		if (copy_from_user(saved_regs, &sr->gp_regs,
+				   sizeof(sr->gp_regs)))
+			goto badframe;
+		saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+			| (saved_regs[PT_MSR] & MSR_USERCHANGE);
+		saved_regs[PT_SOFTE] = regs->softe;
+		memcpy(regs, saved_regs, GP_REGS_SIZE);
+		if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+				   sizeof(sr->fp_regs)))
+			goto badframe;
+		/* This function sets back the stack flags into
+		   the current task structure.  */
+		sys_sigaltstack(&st, NULL);
+
+		ret = regs->result;
+	} else {
+		/* More signals to go */
+		/* Set up registers for next signal handler */
+		regs->gpr[1] = (unsigned long)rt_sf - __SIGNAL_FRAMESIZE;
+		if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx)))
+			goto badframe;
+		sr = (struct sigregs *) sigctx.regs;
+		regs->gpr[3] = ret = sigctx.signal;
+		/* Get the siginfo   */
+		get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo);
+		/* Get the ucontext */
+		get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc);
+		regs->gpr[6] = (unsigned long) rt_sf;
+
+		regs->link = (unsigned long) &sr->tramp;
+		regs->nip = sigctx.handler;
+		if (get_user(prevsp, &sr->gp_regs[PT_R1])
+		    || put_user(prevsp, (unsigned long *) regs->gpr[1]))
+			goto badframe;
+	}
+	return ret;
+
+badframe:
+	do_exit(SIGSEGV);
+}
+
+static void
+setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
+	       signed long newsp)
+{
+	struct rt_sigframe *rt_sf = (struct rt_sigframe *) newsp;
+	/* Handler is *really* a pointer to the function descriptor for
+	 * the signal routine.  The first entry in the function
+	 * descriptor is the entry address of signal and the second
+	 * entry is the TOC value we need to use.
+	 */
+        struct funct_descr_entry {
+                     unsigned long entry;
+                     unsigned long toc;
+	};
+  
+	struct funct_descr_entry * funct_desc_ptr;
+	unsigned long temp_ptr;
+
+	/* Set up preamble frame */
+	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto badframe;
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+	if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
+	    || __copy_to_user(&frame->fp_regs, current->thread.fpr,
+			      ELF_NFPREG * sizeof(double))
+	    || __put_user(0x38000000UL + __NR_rt_sigreturn, &frame->tramp[0])	/* li r0, __NR_rt_sigreturn */
+	    || __put_user(0x44000002UL, &frame->tramp[1]))	/* sc */
+		goto badframe;
+	flush_icache_range((unsigned long) &frame->tramp[0],
+			   (unsigned long) &frame->tramp[2]);
+
+	/* Retrieve rt_sigframe from stack and
+	   set up registers for signal handler
+	*/
+	newsp -= __SIGNAL_FRAMESIZE;
+
+        if ( get_user(temp_ptr, &rt_sf->uc.uc_mcontext.handler)) {
+		goto badframe;
+	}
+
+        funct_desc_ptr = ( struct funct_descr_entry *) temp_ptr;
+        
+	if (put_user(regs->gpr[1], (unsigned long *)newsp)
+	    || get_user(regs->nip, &funct_desc_ptr->entry)
+            || get_user(regs->gpr[2], &funct_desc_ptr->toc)
+	    || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
+	    || get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo)
+	    || get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc))
+		goto badframe;
+
+	regs->gpr[1] = newsp;
+	regs->gpr[6] = (unsigned long) rt_sf;
+	regs->link = (unsigned long) frame->tramp;
+
+	
+	return;
+
+badframe:
+#if DEBUG_SIG
+	printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
+	       regs, frame, newsp);
+#endif
+	do_exit(SIGSEGV);
+}
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
+		   unsigned long r6, unsigned long r7, unsigned long r8,
+		   struct pt_regs *regs)
+{
+	struct sigcontext_struct *sc, sigctx;
+	struct sigregs *sr;
+	long ret;
+	elf_gregset_t saved_regs;  /* an array of ELF_NGREG unsigned longs */
+	sigset_t set;
+	unsigned long prevsp;
+
+        sc = (struct sigcontext_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+		goto badframe;
+
+	set.sig[0] = sigctx.oldmask;
+#if _NSIG_WORDS > 1
+	set.sig[1] = sigctx._unused[3];
+#endif
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	sc++;			/* Look at next sigcontext */
+	if (sc == (struct sigcontext_struct *)(sigctx.regs)) {
+		/* Last stacked signal - restore registers */
+		sr = (struct sigregs *) sigctx.regs;
+		if (regs->msr & MSR_FP )
+			giveup_fpu(current);
+		if (copy_from_user(saved_regs, &sr->gp_regs,
+				   sizeof(sr->gp_regs)))
+			goto badframe;
+		saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+			| (saved_regs[PT_MSR] & MSR_USERCHANGE);
+		saved_regs[PT_SOFTE] = regs->softe;
+		memcpy(regs, saved_regs, GP_REGS_SIZE);
+
+		if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+				   sizeof(sr->fp_regs)))
+			goto badframe;
+
+		ret = regs->result;
+
+	} else {
+		/* More signals to go */
+		regs->gpr[1] = (unsigned long)sc - __SIGNAL_FRAMESIZE;
+		if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+			goto badframe;
+		sr = (struct sigregs *) sigctx.regs;
+		regs->gpr[3] = ret = sigctx.signal;
+		regs->gpr[4] = (unsigned long) sc;
+		regs->link = (unsigned long) &sr->tramp;
+		regs->nip = sigctx.handler;
+
+		if (get_user(prevsp, &sr->gp_regs[PT_R1])
+		    || put_user(prevsp, (unsigned long *) regs->gpr[1]))
+			goto badframe;
+	}
+	return ret;
+
+badframe:
+	do_exit(SIGSEGV);
+}	
+
+/*
+ * Set up a signal frame.
+ */
+static void
+setup_frame(struct pt_regs *regs, struct sigregs *frame,
+            unsigned long newsp)
+{
+
+	/* Handler is *really* a pointer to the function descriptor for
+	 * the signal routine.  The first entry in the function
+	 * descriptor is the entry address of signal and the second
+	 * entry is the TOC value we need to use.
+	 */
+	struct funct_descr_entry {
+		unsigned long entry;
+		unsigned long toc;
+	};
+  
+	struct funct_descr_entry * funct_desc_ptr;
+	unsigned long temp_ptr;
+
+	struct sigcontext_struct *sc = (struct sigcontext_struct *) newsp;
+  
+	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto badframe;
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+	if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
+	    || __copy_to_user(&frame->fp_regs, current->thread.fpr,
+			      ELF_NFPREG * sizeof(double))
+	    || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])    /* li r0, __NR_sigreturn */
+	    || __put_user(0x44000002UL, &frame->tramp[1]))   /* sc */
+		goto badframe;
+	flush_icache_range((unsigned long) &frame->tramp[0],
+			   (unsigned long) &frame->tramp[2]);
+
+	newsp -= __SIGNAL_FRAMESIZE;
+	if ( get_user(temp_ptr, &sc->handler))
+		goto badframe;
+  
+	funct_desc_ptr = ( struct funct_descr_entry *) temp_ptr;
+
+	if (put_user(regs->gpr[1], (unsigned long *)newsp)
+	    || get_user(regs->nip, & funct_desc_ptr ->entry)
+	    || get_user(regs->gpr[2],& funct_desc_ptr->toc)
+	    || get_user(regs->gpr[3], &sc->signal))
+		goto badframe;
+	regs->gpr[1] = newsp;
+	regs->gpr[4] = (unsigned long) sc;
+	regs->link = (unsigned long) frame->tramp;
+
+
+	PPCDBG(PPCDBG_SIGNAL, "setup_frame - returning - regs->gpr[1]=%lx, regs->gpr[4]=%lx, regs->link=%lx \n",
+	       regs->gpr[1], regs->gpr[4], regs->link);
+
+	return;
+
+ badframe:
+	PPCDBG(PPCDBG_SIGNAL, "setup_frame - badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp);  PPCDBG_ENTER_DEBUGGER();
+#if DEBUG_SIG
+	printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
+	       regs, frame, newsp);
+#endif
+	do_exit(SIGSEGV);
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
+	      unsigned long *newspp, unsigned long frame)
+{
+	struct sigcontext_struct *sc;
+        struct rt_sigframe *rt_sf;
+
+	if (regs->trap == 0x0C00 /* System Call! */
+	    && ((int)regs->result == -ERESTARTNOHAND ||
+		((int)regs->result == -ERESTARTSYS &&
+		 !(ka->sa.sa_flags & SA_RESTART))))
+		regs->result = -EINTR;
+        /* Set up Signal Frame */
+     
+	if (ka->sa.sa_flags & SA_SIGINFO) {
+		/* Put a Real Time Context onto stack */
+		*newspp -= sizeof(*rt_sf);
+		rt_sf = (struct rt_sigframe *) *newspp;
+		if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
+			goto badframe;
+                
+
+		if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler)
+		    || __put_user(&rt_sf->info, &rt_sf->pinfo)
+		    || __put_user(&rt_sf->uc, &rt_sf->puc)
+		    /* Put the siginfo */
+		    || __copy_to_user(&rt_sf->info, info, sizeof(*info))
+		    /* Create the ucontext */
+		    || __put_user(0, &rt_sf->uc.uc_flags)
+		    || __put_user(0, &rt_sf->uc.uc_link)
+		    || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
+		    || __put_user(sas_ss_flags(regs->gpr[1]), 
+				  &rt_sf->uc.uc_stack.ss_flags)
+		    || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
+		    || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))
+		    /* mcontext.regs points to preamble register frame */
+		    || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
+		    || __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
+			goto badframe;
+               
+	} else {
+	        /* Put another sigcontext on the stack */
+                *newspp -= sizeof(*sc);
+        	sc = (struct sigcontext_struct *) *newspp;
+        	if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
+	        	goto badframe;
+
+        	if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
+	           || __put_user(oldset->sig[0], &sc->oldmask)
+#if _NSIG_WORDS > 1
+	           || __put_user(oldset->sig[1], &sc->_unused[3])
+#endif
+	           || __put_user((struct pt_regs *)frame, &sc->regs)
+	           || __put_user(sig, &sc->signal))
+	        	goto badframe;
+	}
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+	return;
+
+badframe:
+#if DEBUG_SIG
+	printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
+	       regs, frame, *newspp);
+	printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
+#endif
+	do_exit(SIGSEGV);
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+	unsigned long frame, newsp;
+
+	/*
+	 * If the current thread is 32 bit - invoke the
+	 * 32 bit signal handling code
+	 */
+	if (current->thread.flags & PPC_FLAG_32BIT)
+		return do_signal32(oldset, regs);
+  
+        PPCDBG(PPCDBG_SIGNAL, "do_signal - running - pid=%ld current=%lx comm=%s \n", 
+               current->pid, current, current->comm);
+
+  
+
+        if (!oldset)
+		oldset = &current->blocked;
+
+	newsp = frame = 0;
+
+	for (;;) {
+		unsigned long signr;
+
+                PPCDBG(PPCDBG_SIGNAL, "do_signal - (pre) dequeueing signal - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+                PPCDBG(PPCDBG_SIGNAL, "do_signal - (aft) dequeueing signal - signal=%lx - pid=%ld current=%lx comm=%s \n", signr, current->pid, current, current->comm);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+
+  
+                PPCDBG(PPCDBG_SIGNAL, "do_signal - ka=%p, action handler=%lx \n", ka, ka->sa.sa_handler);
+
+		if (ka->sa.sa_handler == SIG_IGN) {
+                        PPCDBG(PPCDBG_SIGNAL, "do_signal - into SIG_IGN logic \n");
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+                        PPCDBG(PPCDBG_SIGNAL, "do_signal - into SIG_DFL logic \n");
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		if ( (ka->sa.sa_flags & SA_ONSTACK)
+		     && (! on_sig_stack(regs->gpr[1])))
+			newsp = (current->sas_ss_sp + current->sas_ss_size);
+		else
+			newsp = regs->gpr[1];
+		newsp = frame = newsp - sizeof(struct sigregs);
+
+		/* Whee!  Actually deliver the signal.  */
+  
+                PPCDBG(PPCDBG_SIGNAL, "do_signal - GOING TO RUN SIGNAL HANDLER - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+		handle_signal(signr, ka, &info, oldset, regs, &newsp, frame);
+                PPCDBG(PPCDBG_SIGNAL, "do_signal - after running signal handler - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+                break;
+	}
+
+	if (regs->trap == 0x0C00 /* System Call! */ &&
+	    ((int)regs->result == -ERESTARTNOHAND ||
+	     (int)regs->result == -ERESTARTSYS ||
+	     (int)regs->result == -ERESTARTNOINTR)) {
+                PPCDBG(PPCDBG_SIGNAL, "do_signal - going to back up & retry system call \n");
+		regs->gpr[3] = regs->orig_gpr3;
+		regs->nip -= 4;		/* Back up & retry system call */
+		regs->result = 0;
+	}
+
+	if (newsp == frame)
+          {
+             PPCDBG(PPCDBG_SIGNAL, "do_signal - returning w/ no signal delivered \n");
+             return 0;		/* no signals delivered */
+           }
+  
+     
+
+        if (ka->sa.sa_flags & SA_SIGINFO)
+             setup_rt_frame(regs, (struct sigregs *) frame, newsp);
+        else        
+	    setup_frame(regs, (struct sigregs *) frame, newsp);
+        PPCDBG(PPCDBG_SIGNAL, "do_signal - returning a signal was delivered \n");
+	return 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/signal32.c linux/arch/ppc64/kernel/signal32.c
--- linux.orig/arch/ppc64/kernel/signal32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/signal32.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,1483 @@
+/*
+ * signal32.c: Support 32bit signal syscalls.
+ *
+ * Copyright (C) 2001 IBM
+ * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+ * environment.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/ptrace.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h> 
+#include <linux/mm.h> 
+#include <linux/file.h> 
+#include <linux/signal.h>
+#include <linux/utime.h>
+#include <linux/resource.h>
+#include <linux/times.h>
+#include <linux/utsname.h>
+#include <linux/timex.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/slab.h>
+#include <linux/uio.h>
+#include <linux/nfs_fs.h>
+#include <linux/smb_fs.h>
+#include <linux/smb_mount.h>
+#include <linux/ncp_fs.h>
+#include <linux/quota.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/personality.h>
+#include <linux/stat.h>
+#include <linux/filter.h>
+#include <asm/types.h>
+#include <asm/ipc.h>
+#include <asm/uaccess.h>
+#include <linux/elf.h>
+#include <asm/ppc32.h>
+#include <asm/ppcdebug.h>
+#include <asm/unistd.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+/* 
+ * These are the flags in the MSR that the user is allowed to change
+ * by modifying the saved value of the MSR on the stack.  SE and BE
+ * should not be in this list since gdb may want to change these.  I.e,
+ * you should be able to step out of a signal handler to see what
+ * instruction executes next after the signal handler completes.
+ * Alternately, if you stepped into a signal handler, you should be
+ * able to continue 'til the next breakpoint from within the signal
+ * handler, even if the handler returns.
+ */
+#define MSR_USERCHANGE	(MSR_FE0 | MSR_FE1)
+
+struct timespec32 {
+	s32    tv_sec;
+	s32    tv_nsec;
+};
+
+struct sigregs32 {
+    /***********************************************************************/
+    /* the gp_regs array is 32 bit representation of the pt_regs structure */
+    /*  that was stored on the kernle stack during the system call that    */
+    /*  was interrupted for the signal.                                    */
+    /*                                                                     */
+    /* Note that the entire pt_regs regs structure will fit in the gp_regs */
+    /*   structure because the ELF_NREG value is 48 for PPC and the pt_regs*/
+    /*   structure contains 44 registers                                   */
+    /*                                                                     */ 
+    /***********************************************************************/ 
+	elf_gregset_t32	gp_regs;
+	double		fp_regs[ELF_NFPREG];
+	unsigned int	tramp[2];
+	/* Programs using the rs6000/xcoff abi can save up to 19 gp regs
+	   and 18 fp regs below sp before decrementing it. */
+	int		abigap[56];
+};
+
+
+struct rt_sigframe_32 {
+	/* Unused space at start of frame to allow for storing of stack pointers */
+	unsigned long _unused;
+	/* This is a 32 bit pointer in user address space 
+	 *     it is a pointer to the siginfo stucture in the rt stack frame 
+	 */
+	u32 pinfo;
+	/* This is a 32 bit pointer in user address space */
+	/*     it is a pointer to the user context in the rt stack frame  */
+	u32 puc;
+	struct siginfo32  info;
+	struct ucontext32 uc;
+};
+
+
+
+
+
+extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru);
+
+
+/****************************************************************************/
+/*  Start of nonRT signal support                                           */
+/*                                                                          */
+/*     sigset_t is 32 bits for non-rt signals                               */
+/*                                                                          */
+/*  System Calls                                                            */
+/*       sigaction                sys32_sigaction                           */
+/*       sigpending               sys32_sigpending                          */
+/*       sigprocmask              sys32_sigprocmask                         */
+/*       sigreturn                sys32_sigreturn                           */
+/*                                                                          */
+/*  Note sigsuspend has no special 32 bit routine - uses the 64 bit routine */ 
+/*                                                                          */
+/*  Other routines                                                          */
+/*        setup_frame32                                                     */
+/*                                                                          */
+/****************************************************************************/
+
+
+asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sigaction - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	if (sig < 0)
+	{
+		sig = -sig;
+	}
+
+	if (act)
+	{
+		old_sigset_t32 mask;
+
+		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
+		ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
+		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		ret |= __get_user(mask, &act->sa_mask);
+		if (ret)
+			return ret;
+		PPCDBG(PPCDBG_SIGNAL, "sys32_sigaction flags =%lx  \n", new_ka.sa.sa_flags);
+
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact)
+	{
+		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
+		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
+		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sigaction - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return ret;
+}
+
+
+
+
+extern asmlinkage long sys_sigpending(old_sigset_t *set);
+
+asmlinkage long sys32_sigpending(old_sigset_t32 *set)
+{
+	old_sigset_t s;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sigpending - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+		
+	set_fs (KERNEL_DS);
+	ret = sys_sigpending(&s);
+	set_fs (old_fs);
+	if (put_user (s, set)) return -EFAULT;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sigpending - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return ret;
+}
+
+
+
+
+extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
+
+/* Note: it is necessary to treat how as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sigprocmask(u32 how, old_sigset_t32 *set, old_sigset_t32 *oset)
+{
+	old_sigset_t s;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sigprocmask - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+	
+	if (set && get_user (s, set)) return -EFAULT;
+	set_fs (KERNEL_DS);
+	ret = sys_sigprocmask((int)how, set ? &s : NULL, oset ? &s : NULL);
+	set_fs (old_fs);
+	if (ret) return ret;
+	if (oset && put_user (s, oset)) return -EFAULT;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sigprocmask - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return 0;
+}
+
+
+
+/*
+ * When we have signals to deliver, we set up on the
+ * user stack, going down from the original stack pointer:
+ *	a sigregs struct
+ *	one or more sigcontext structs
+ *	a gap of __SIGNAL_FRAMESIZE32 bytes
+ *
+ * Each of these things must be a multiple of 16 bytes in size.
+ *
+*/
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
+		     unsigned long r6, unsigned long r7, unsigned long r8,
+		     struct pt_regs *regs)
+{
+	struct sigcontext32_struct *sc, sigctx;
+	struct sigregs32 *sr;
+	int ret;
+	elf_gregset_t32 saved_regs;  /* an array of ELF_NGREG unsigned ints (32 bits) */
+	sigset_t set;
+	unsigned int prevsp;
+
+	PPCDBG(PPCDBG_SIGNAL, "sys32_sigreturn - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	sc = (struct sigcontext32_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
+	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+		goto badframe;
+
+	/* Note that PPC32 puts the upper 32 bits of the sigmask in the  */
+	/*   unused part of the signal stackframe                        */
+	set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3])<< 32);
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	sc++;			/* Look at next sigcontext */
+	/* If the next sigcontext is actually the sigregs (frame)  */
+	/*   - then no more sigcontexts on the user stack          */  
+	if (sc == (struct sigcontext32_struct*)(u64)sigctx.regs)
+	{
+		/* Last stacked signal - restore registers */
+		sr = (struct sigregs32*)(u64)sigctx.regs;
+		if (regs->msr & MSR_FP )
+			giveup_fpu(current);
+		/* copy the 32 bit register values off the user stack */
+		/*   into the 32 bit register area                    */
+		if (copy_from_user(saved_regs, &sr->gp_regs,sizeof(sr->gp_regs)))
+			goto badframe;
+		/**********************************************************************/
+		/* The saved reg structure in the frame is an elf_grepset_t32, it is  */
+		/*   a 32 bit register save of the registers in the pt_regs structure */
+		/*   that was stored on the kernel stack during the system call       */
+		/*   when the system call was interrupted for the signal. Only 32 bits*/
+		/*   are saved because the sigcontext contains a pointer to the regs  */
+		/*   and the sig context address is passed as a pointer to the signal */
+		/*   handler.                                                         */
+		/*                                                                    */
+		/* The entries in the elf_grepset have the same index as the elements */
+		/*   in the pt_regs structure.                                        */
+		/*                                                                    */
+		/**********************************************************************/
+
+		saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+			| (saved_regs[PT_MSR] & MSR_USERCHANGE);
+		regs->gpr[0] = (u64)(saved_regs[0]) & 0xFFFFFFFF;
+		regs->gpr[1] = (u64)(saved_regs[1]) & 0xFFFFFFFF;
+		/**********************************************************************/
+		/* Register 2 is the kernel toc - should be reset on any calls into   */
+		/*  the kernel                                                        */
+		/**********************************************************************/
+		regs->gpr[2] = (u64)(saved_regs[2]) & 0xFFFFFFFF;
+
+		regs->gpr[3] = (u64)(saved_regs[3]) & 0xFFFFFFFF;
+		regs->gpr[4] = (u64)(saved_regs[4]) & 0xFFFFFFFF;
+		regs->gpr[5] = (u64)(saved_regs[5]) & 0xFFFFFFFF;
+		regs->gpr[6] = (u64)(saved_regs[6]) & 0xFFFFFFFF;
+		regs->gpr[7] = (u64)(saved_regs[7]) & 0xFFFFFFFF;
+		regs->gpr[8] = (u64)(saved_regs[8]) & 0xFFFFFFFF;
+		regs->gpr[9] = (u64)(saved_regs[9]) & 0xFFFFFFFF;
+		regs->gpr[10] = (u64)(saved_regs[10]) & 0xFFFFFFFF;
+		regs->gpr[11] = (u64)(saved_regs[11]) & 0xFFFFFFFF;
+		regs->gpr[12] = (u64)(saved_regs[12]) & 0xFFFFFFFF;
+		regs->gpr[13] = (u64)(saved_regs[13]) & 0xFFFFFFFF;
+		regs->gpr[14] = (u64)(saved_regs[14]) & 0xFFFFFFFF;
+		regs->gpr[15] = (u64)(saved_regs[15]) & 0xFFFFFFFF;
+		regs->gpr[16] = (u64)(saved_regs[16]) & 0xFFFFFFFF;
+		regs->gpr[17] = (u64)(saved_regs[17]) & 0xFFFFFFFF;
+		regs->gpr[18] = (u64)(saved_regs[18]) & 0xFFFFFFFF;
+		regs->gpr[19] = (u64)(saved_regs[19]) & 0xFFFFFFFF;
+		regs->gpr[20] = (u64)(saved_regs[20]) & 0xFFFFFFFF;
+		regs->gpr[21] = (u64)(saved_regs[21]) & 0xFFFFFFFF;
+		regs->gpr[22] = (u64)(saved_regs[22]) & 0xFFFFFFFF;
+		regs->gpr[23] = (u64)(saved_regs[23]) & 0xFFFFFFFF;
+		regs->gpr[24] = (u64)(saved_regs[24]) & 0xFFFFFFFF;
+		regs->gpr[25] = (u64)(saved_regs[25]) & 0xFFFFFFFF;
+		regs->gpr[26] = (u64)(saved_regs[26]) & 0xFFFFFFFF;
+		regs->gpr[27] = (u64)(saved_regs[27]) & 0xFFFFFFFF;
+		regs->gpr[28] = (u64)(saved_regs[28]) & 0xFFFFFFFF;
+		regs->gpr[29] = (u64)(saved_regs[29]) & 0xFFFFFFFF;
+		regs->gpr[30] = (u64)(saved_regs[30]) & 0xFFFFFFFF;
+		regs->gpr[31] = (u64)(saved_regs[31]) & 0xFFFFFFFF;
+		/****************************************************/
+		/*  restore the non gpr registers                   */
+		/****************************************************/
+		regs->msr = (u64)(saved_regs[PT_MSR]) & 0xFFFFFFFF;
+		/* Insure that the interrupt mode is 64 bit, during 32 bit execution.
+		 * (This is necessary because we only saved lower 32 bits of msr.)
+		 */
+		regs->msr = regs->msr | MSR_ISF;  /* When this thread is interrupted it should run in 64 bit mode. */
+
+		regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
+		regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF; 
+		regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF; 
+		regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF; 
+		regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF; 
+		regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
+		/* regs->softe is left unchanged (like the MSR.EE bit) */
+		/******************************************************/
+		/* the DAR and the DSISR are only relevant during a   */
+		/*   data or instruction storage interrupt. The value */
+		/*   will be set to zero.                             */
+		/******************************************************/
+		regs->dar = 0; 
+		regs->dsisr = 0;
+		regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
+
+		if (copy_from_user(current->thread.fpr, &sr->fp_regs, sizeof(sr->fp_regs)))
+			goto badframe;
+
+		ret = regs->result;
+	} else {
+		/* More signals to go */
+		regs->gpr[1] = (unsigned long)sc - __SIGNAL_FRAMESIZE32;
+		if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+			goto badframe;
+		sr = (struct sigregs32*)(u64)sigctx.regs;
+		regs->gpr[3] = ret = sigctx.signal;
+		regs->gpr[4] = (unsigned long) sc;
+		regs->link = (unsigned long) &sr->tramp;
+		regs->nip = sigctx.handler;
+
+		if (get_user(prevsp, &sr->gp_regs[PT_R1])
+		    || put_user(prevsp, (unsigned int*) regs->gpr[1]))
+			goto badframe;
+	}
+  
+	PPCDBG(PPCDBG_SIGNAL, "sys32_sigreturn - normal exit returning %ld - pid=%ld current=%lx comm=%s \n", ret, current->pid, current, current->comm);
+	return ret;
+
+badframe:
+	PPCDBG(PPCDBG_SYS32NI, "sys32_sigreturn - badframe - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	do_exit(SIGSEGV);
+}	
+
+/*
+ * Set up a signal frame.
+ */
+static void
+setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
+            unsigned int newsp)
+{
+	struct sigcontext32_struct *sc = (struct sigcontext32_struct *)(u64)newsp;
+
+	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto badframe;
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+
+	/***************************************************************/
+	/*                                                             */ 
+	/* Copy the register contents for the pt_regs structure on the */
+	/*   kernel stack to the elf_gregset_t32 structure on the user */
+	/*   stack. This is a copy of 64 bit register values to 32 bit */
+	/*   register values. The high order 32 bits of the 64 bit     */
+	/*   registers are not needed since a 32 bit application is    */
+	/*   running and the saved registers are the contents of the   */
+	/*   user registers at the time of a system call.              */
+	/*                                                             */
+	/* The values saved on the user stack will be restored into    */
+	/*  the registers during the signal return processing          */
+	/*                                                             */
+	/* Note the +1 is needed in order to get the lower 32 bits     */
+	/*  of 64 bit register                                         */
+	/***************************************************************/
+	if (__copy_to_user(&frame->gp_regs[0], (u32*)(&regs->gpr[0])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[1], (u32*)(&regs->gpr[1])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[2], (u32*)(&regs->gpr[2])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[3], (u32*)(&regs->gpr[3])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[4], (u32*)(&regs->gpr[4])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[5], (u32*)(&regs->gpr[5])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[6], (u32*)(&regs->gpr[6])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[7], (u32*)(&regs->gpr[7])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[8], (u32*)(&regs->gpr[8])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[9], (u32*)(&regs->gpr[9])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[10], (u32*)(&regs->gpr[10])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[11], (u32*)(&regs->gpr[11])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[12], (u32*)(&regs->gpr[12])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[13], (u32*)(&regs->gpr[13])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[14], (u32*)(&regs->gpr[14])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[15], (u32*)(&regs->gpr[15])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[16], (u32*)(&regs->gpr[16])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[17], (u32*)(&regs->gpr[17])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[18], (u32*)(&regs->gpr[18])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[19], (u32*)(&regs->gpr[19])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[20], (u32*)(&regs->gpr[20])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[21], (u32*)(&regs->gpr[21])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[22], (u32*)(&regs->gpr[22])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[23], (u32*)(&regs->gpr[23])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[24], (u32*)(&regs->gpr[24])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[25], (u32*)(&regs->gpr[25])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[26], (u32*)(&regs->gpr[26])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[27], (u32*)(&regs->gpr[27])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[28], (u32*)(&regs->gpr[28])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[29], (u32*)(&regs->gpr[29])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[30], (u32*)(&regs->gpr[30])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[31], (u32*)(&regs->gpr[31])+1, sizeof(u32))) 
+		goto badframe;
+
+  /*****************************************************************************/
+  /* Copy the non gpr registers to the user stack                              */
+  /*****************************************************************************/
+
+	if (__copy_to_user(&frame->gp_regs[PT_NIP], (u32*)(&regs->gpr[PT_NIP])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_MSR], (u32*)(&regs->gpr[PT_MSR])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_ORIG_R3], (u32*)(&regs->gpr[PT_ORIG_R3])+1,
+			      sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_CTR], (u32*)(&regs->gpr[PT_CTR])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_LNK], (u32*)(&regs->gpr[PT_LNK])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_XER], (u32*)(&regs->gpr[PT_XER])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_CCR], (u32*)(&regs->gpr[PT_CCR])+1, sizeof(u32))
+# if 0
+	    || __copy_to_user(&frame->gp_regs[PT_MQ], (u32*)(&regs->gpr[PT_MQ])+1, sizeof(u32))
+#endif
+	    || __copy_to_user(&frame->gp_regs[PT_RESULT], (u32*)(&regs->gpr[PT_RESULT])+1,
+			      sizeof(u32)))
+		goto badframe;
+
+
+	/*****************************************************************************/
+	/* Now copy the floating point registers onto the user stack                 */
+	/*                                                                           */
+	/* Also set up so on the completion of the signal handler, the sys_sigreturn */
+	/*   will get control to reset the stack                                     */
+	/*****************************************************************************/
+	if (__copy_to_user(&frame->fp_regs, current->thread.fpr,
+			   ELF_NFPREG * sizeof(double))
+	    || __put_user(0x38000000U + __NR_sigreturn, &frame->tramp[0])    /* li r0, __NR_sigreturn */
+	    || __put_user(0x44000002U, &frame->tramp[1]))   /* sc */
+		goto badframe;
+
+	flush_icache_range((unsigned long) &frame->tramp[0],
+			   (unsigned long) &frame->tramp[2]);
+
+	newsp -= __SIGNAL_FRAMESIZE32;
+	if (put_user(regs->gpr[1], (u32*)(u64)newsp)
+	    || get_user(regs->nip, &sc->handler)
+	    || get_user(regs->gpr[3], &sc->signal))
+		goto badframe;
+
+	regs->gpr[1] = newsp & 0xFFFFFFFF;
+	/**************************************************************/
+	/* first parameter to the signal handler is the signal number */
+	/*  - the value is in gpr3                                    */  
+	/* second parameter to the signal handler is the sigcontext   */
+	/*   - set the value into gpr4                                */ 
+	/**************************************************************/
+	regs->gpr[4] = (unsigned long) sc;
+	regs->link = (unsigned long) frame->tramp;
+	return;
+
+ badframe:
+	udbg_printf("setup_frame32 - badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp);  PPCDBG_ENTER_DEBUGGER();
+#if DEBUG_SIG
+	printk("badframe in setup_frame32, regs=%p frame=%p newsp=%lx\n",
+	       regs, frame, newsp);
+#endif
+	do_exit(SIGSEGV);
+}
+
+
+/****************************************************************************/
+/*  Start of RT signal support                                              */
+/*                                                                          */
+/*     sigset_t is 64 bits for rt signals                                   */
+/*                                                                          */
+/*  System Calls                                                            */
+/*       sigaction                sys32_rt_sigaction                        */
+/*       sigpending               sys32_rt_sigpending                       */
+/*       sigprocmask              sys32_rt_sigprocmask                      */
+/*       sigreturn                sys32_rt_sigreturn                        */
+/*       sigtimedwait             sys32_rt_sigtimedwait                     */
+/*       sigqueueinfo             sys32_rt_sigqueueinfo                     */
+/*       sigsuspend               sys32_rt_sigsuspend                       */ 
+/*                                                                          */
+/*  Other routines                                                          */
+/*        setup_rt_frame32                                                  */
+/*        siginfo64to32                                                     */
+/*        siginfo32to64                                                     */
+/*                                                                          */
+/*                                                                          */
+/****************************************************************************/
+
+
+// This code executes after the rt signal handler in 32 bit mode has completed and 
+//  returned  
+long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
+			unsigned long r6, unsigned long r7, unsigned long r8,
+			struct pt_regs * regs)
+{
+	struct rt_sigframe_32 *rt_stack_frame;
+	struct sigcontext32_struct sigctx;
+	struct sigregs32 *signalregs;
+ 
+	int ret;
+	elf_gregset_t32 saved_regs;   /* an array of 32 bit register values */
+	sigset_t signal_set; 
+	stack_t stack;
+	unsigned int previous_stack;
+
+	ret = 0;
+	/* Adjust the inputted reg1 to point to the first rt signal frame */
+	rt_stack_frame = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
+	/* Copy the information from the user stack  */
+	if (copy_from_user(&sigctx, &rt_stack_frame->uc.uc_mcontext,sizeof(sigctx))
+	    || copy_from_user(&signal_set, &rt_stack_frame->uc.uc_sigmask,sizeof(signal_set))
+	    || copy_from_user(&stack,&rt_stack_frame->uc.uc_stack,sizeof(stack)))
+	{
+		/* unable to copy from user storage */
+		goto badframe;
+	}
+
+	/* Unblock the signal that was processed 
+	 *   After a signal handler runs - 
+	 *     if the signal is blockable - the signal will be unblocked  
+	 *       ( sigkill and sigstop are not blockable)
+	 */
+	sigdelsetmask(&signal_set, ~_BLOCKABLE); 
+	/* update the current based on the sigmask found in the rt_stackframe */
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = signal_set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	/* Set to point to the next rt_sigframe - this is used to determine whether this 
+	 *   is the last signal to process
+	 */
+	rt_stack_frame ++;
+
+	if (rt_stack_frame == (struct rt_sigframe_32 *)(u64)(sigctx.regs))
+	{
+		signalregs = (struct sigregs32 *) (u64)sigctx.regs;
+		/* If currently owning the floating point - give them up */
+		if (regs->msr & MSR_FP)
+		{
+			giveup_fpu(current);
+		}
+		if (copy_from_user(saved_regs,&signalregs->gp_regs,sizeof(signalregs->gp_regs))) 
+		{
+			goto badframe;
+		}
+		/**********************************************************************/
+		/* The saved reg structure in the frame is an elf_grepset_t32, it is  */
+		/*   a 32 bit register save of the registers in the pt_regs structure */
+		/*   that was stored on the kernel stack during the system call       */
+		/*   when the system call was interrupted for the signal. Only 32 bits*/
+		/*   are saved because the sigcontext contains a pointer to the regs  */
+		/*   and the sig context address is passed as a pointer to the signal */
+		/*   handler.                                                         */
+		/*                                                                    */
+		/* The entries in the elf_grepset have the same index as the elements */
+		/*   in the pt_regs structure.                                        */
+		/*                                                                    */
+		/**********************************************************************/
+
+		saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+			| (saved_regs[PT_MSR] & MSR_USERCHANGE);
+		regs->gpr[0] = (u64)(saved_regs[0]) & 0xFFFFFFFF;
+		regs->gpr[1] = (u64)(saved_regs[1]) & 0xFFFFFFFF;
+		/**********************************************************************/
+		/* Register 2 is the kernel toc - should be reset on any calls into   */
+		/*  the kernel                                                        */
+		/**********************************************************************/
+		regs->gpr[2] = (u64)(saved_regs[2]) & 0xFFFFFFFF;
+ 
+		regs->gpr[3] = (u64)(saved_regs[3]) & 0xFFFFFFFF;
+		regs->gpr[4] = (u64)(saved_regs[4]) & 0xFFFFFFFF;
+		regs->gpr[5] = (u64)(saved_regs[5]) & 0xFFFFFFFF;
+		regs->gpr[6] = (u64)(saved_regs[6]) & 0xFFFFFFFF;
+		regs->gpr[7] = (u64)(saved_regs[7]) & 0xFFFFFFFF;
+		regs->gpr[8] = (u64)(saved_regs[8]) & 0xFFFFFFFF;
+		regs->gpr[9] = (u64)(saved_regs[9]) & 0xFFFFFFFF;
+		regs->gpr[10] = (u64)(saved_regs[10]) & 0xFFFFFFFF;
+		regs->gpr[11] = (u64)(saved_regs[11]) & 0xFFFFFFFF;
+		regs->gpr[12] = (u64)(saved_regs[12]) & 0xFFFFFFFF;
+		regs->gpr[13] = (u64)(saved_regs[13]) & 0xFFFFFFFF;
+		regs->gpr[14] = (u64)(saved_regs[14]) & 0xFFFFFFFF;
+		regs->gpr[15] = (u64)(saved_regs[15]) & 0xFFFFFFFF;
+		regs->gpr[16] = (u64)(saved_regs[16]) & 0xFFFFFFFF;
+		regs->gpr[17] = (u64)(saved_regs[17]) & 0xFFFFFFFF;
+		regs->gpr[18] = (u64)(saved_regs[18]) & 0xFFFFFFFF;
+		regs->gpr[19] = (u64)(saved_regs[19]) & 0xFFFFFFFF;
+		regs->gpr[20] = (u64)(saved_regs[20]) & 0xFFFFFFFF;
+		regs->gpr[21] = (u64)(saved_regs[21]) & 0xFFFFFFFF;
+		regs->gpr[22] = (u64)(saved_regs[22]) & 0xFFFFFFFF;
+		regs->gpr[23] = (u64)(saved_regs[23]) & 0xFFFFFFFF;
+		regs->gpr[24] = (u64)(saved_regs[24]) & 0xFFFFFFFF;
+		regs->gpr[25] = (u64)(saved_regs[25]) & 0xFFFFFFFF;
+		regs->gpr[26] = (u64)(saved_regs[26]) & 0xFFFFFFFF;
+		regs->gpr[27] = (u64)(saved_regs[27]) & 0xFFFFFFFF;
+		regs->gpr[28] = (u64)(saved_regs[28]) & 0xFFFFFFFF;
+		regs->gpr[29] = (u64)(saved_regs[29]) & 0xFFFFFFFF;
+		regs->gpr[30] = (u64)(saved_regs[30]) & 0xFFFFFFFF;
+		regs->gpr[31] = (u64)(saved_regs[31]) & 0xFFFFFFFF;
+		/****************************************************/
+		/*  restore the non gpr registers                   */
+		/****************************************************/
+		regs->msr = (u64)(saved_regs[PT_MSR]) & 0xFFFFFFFF;
+
+		regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
+		regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF; 
+		regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF; 
+		regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF; 
+		regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF; 
+		regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
+		/* regs->softe is left unchanged (like MSR.EE) */
+		/******************************************************/
+		/* the DAR and the DSISR are only relevant during a   */
+		/*   data or instruction storage interrupt. The value */
+		/*   will be set to zero.                             */
+		/******************************************************/
+		regs->dar = 0; 
+		regs->dsisr = 0;
+		regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
+		ret = regs->result;
+	}
+	else  /* more signals to go  */
+	{
+		regs->gpr[1] = (u64)rt_stack_frame - __SIGNAL_FRAMESIZE32;
+		if (copy_from_user(&sigctx, &rt_stack_frame->uc.uc_mcontext,sizeof(sigctx)))
+		{
+			goto badframe;
+		}
+		signalregs = (struct sigregs32 *) (u64)sigctx.regs;
+		/* first parm to signal handler is the signal number */
+		regs->gpr[3] = ret = sigctx.signal;
+		/* second parm is a pointer to sig info */
+		get_user(regs->gpr[4], &rt_stack_frame->pinfo);
+		/* third parm is a pointer to the ucontext */
+		get_user(regs->gpr[5], &rt_stack_frame->puc);
+		/* fourth parm is the stack frame */
+		regs->gpr[6] = (u64)rt_stack_frame;
+		/* Set up link register to return to sigreturn when the */
+		/*  signal handler completes */
+		regs->link = (u64)&signalregs->tramp;
+		/* Set next instruction to the start fo the signal handler */
+		regs->nip = sigctx.handler;
+		/* Set the reg1 to look like a call to the signal handler */
+		if (get_user(previous_stack,&signalregs->gp_regs[PT_R1])
+		    || put_user(previous_stack, (unsigned long *)regs->gpr[1]))
+		{
+			goto badframe;
+		}
+
+	}
+
+	return ret;
+
+ badframe:
+	do_exit(SIGSEGV);     
+}
+
+
+
+asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act, struct sigaction32 *oact, size_t sigsetsize)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+	sigset32_t set32;
+
+	PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigaction - entered - sig=%x \n", sig);
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset32_t))
+		return -EINVAL;
+
+	if (act) {
+		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
+		ret |= __copy_from_user(&set32, &act->sa_mask,
+					sizeof(sigset32_t));
+		switch (_NSIG_WORDS) {
+		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
+				| (((long)set32.sig[7]) << 32);
+		case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
+				| (((long)set32.sig[5]) << 32);
+		case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
+				| (((long)set32.sig[3]) << 32);
+		case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
+				| (((long)set32.sig[1]) << 32);
+		}
+
+		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		
+		if (ret)
+			return -EFAULT;
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		switch (_NSIG_WORDS) {
+		case 4:
+			set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
+			set32.sig[6] = old_ka.sa.sa_mask.sig[3];
+		case 3:
+			set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
+			set32.sig[4] = old_ka.sa.sa_mask.sig[2];
+		case 2:
+			set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
+			set32.sig[2] = old_ka.sa.sa_mask.sig[1];
+		case 1:
+			set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
+			set32.sig[0] = old_ka.sa.sa_mask.sig[0];
+		}
+		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
+		ret |= __copy_to_user(&oact->sa_mask, &set32,
+				      sizeof(sigset32_t));
+		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+	}
+
+  
+	PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigaction - exiting - sig=%x \n", sig);
+	return ret;
+}
+
+
+extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
+					  size_t sigsetsize);
+
+/* Note: it is necessary to treat how as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set, sigset32_t *oset, size_t sigsetsize)
+{
+	sigset_t s;
+	sigset32_t s32;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+
+	PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigprocmask - entered how=%x \n", (int)how);
+	
+	if (set) {
+		if (copy_from_user (&s32, set, sizeof(sigset32_t)))
+			return -EFAULT;
+    
+		switch (_NSIG_WORDS) {
+		case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
+		case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
+		case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
+		case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
+		}
+	}
+	
+	set_fs (KERNEL_DS);
+	ret = sys_rt_sigprocmask((int)how, set ? &s : NULL, oset ? &s : NULL,
+				 sigsetsize); 
+	set_fs (old_fs);
+	if (ret) return ret;
+	if (oset) {
+		switch (_NSIG_WORDS) {
+		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
+		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
+		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
+		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
+		}
+		if (copy_to_user (oset, &s32, sizeof(sigset32_t)))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+
+extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
+
+
+
+asmlinkage long sys32_rt_sigpending(sigset32_t *set,   __kernel_size_t32 sigsetsize)
+{
+
+	sigset_t s;
+	sigset32_t s32;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+		
+	set_fs (KERNEL_DS);
+	ret = sys_rt_sigpending(&s, sigsetsize);
+	set_fs (old_fs);
+	if (!ret) {
+		switch (_NSIG_WORDS) {
+		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
+		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
+		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
+		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
+		}
+		if (copy_to_user (set, &s32, sizeof(sigset32_t)))
+			return -EFAULT;
+	}
+	return ret;
+}
+
+
+
+siginfo_t32 *
+siginfo64to32(siginfo_t32 *d, siginfo_t *s)
+{
+	memset (d, 0, sizeof(siginfo_t32));
+	d->si_signo = s->si_signo;
+	d->si_errno = s->si_errno;
+	d->si_code = s->si_code;
+	if (s->si_signo >= SIGRTMIN) {
+		d->si_pid = s->si_pid;
+		d->si_uid = s->si_uid;
+		
+		d->si_int = s->si_int;
+	} else switch (s->si_signo) {
+	/* XXX: What about POSIX1.b timers */
+	case SIGCHLD:
+		d->si_pid = s->si_pid;
+		d->si_status = s->si_status;
+		d->si_utime = s->si_utime;
+		d->si_stime = s->si_stime;
+		break;
+	case SIGSEGV:
+	case SIGBUS:
+	case SIGFPE:
+	case SIGILL:
+		d->si_addr = (long)(s->si_addr);
+        break;
+	case SIGPOLL:
+		d->si_band = s->si_band;
+		d->si_fd = s->si_fd;
+		break;
+	default:
+		d->si_pid = s->si_pid;
+		d->si_uid = s->si_uid;
+		break;
+	}
+	return d;
+}
+
+extern asmlinkage long
+sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
+		    const struct timespec *uts, size_t sigsetsize);
+
+asmlinkage long
+sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
+		      struct timespec32 *uts, __kernel_size_t32 sigsetsize)
+{
+	sigset_t s;
+	sigset32_t s32;
+	struct timespec t;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+	siginfo_t info;
+	siginfo_t32 info32;
+		
+	if (copy_from_user (&s32, uthese, sizeof(sigset32_t)))
+		return -EFAULT;
+	switch (_NSIG_WORDS) {
+	case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
+	case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
+	case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
+	case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
+	}
+	if (uts) {
+		ret = get_user (t.tv_sec, &uts->tv_sec);
+		ret |= __get_user (t.tv_nsec, &uts->tv_nsec);
+		if (ret)
+			return -EFAULT;
+	}
+	set_fs (KERNEL_DS);
+	if (uts) 
+	{
+		ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
+	} else {
+		ret = sys_rt_sigtimedwait(&s, &info, (struct timespec *)uts, sigsetsize);
+	}
+	
+	set_fs (old_fs);
+	if (ret >= 0 && uinfo) {
+		if (copy_to_user (uinfo, siginfo64to32(&info32, &info),
+				  sizeof(siginfo_t32)))
+			return -EFAULT;
+	}
+	return ret;
+}
+
+
+
+siginfo_t *
+siginfo32to64(siginfo_t *d, siginfo_t32 *s)
+{
+	d->si_signo = s->si_signo;
+	d->si_errno = s->si_errno;
+	d->si_code = s->si_code;
+	if (s->si_signo >= SIGRTMIN) {
+		d->si_pid = s->si_pid;
+		d->si_uid = s->si_uid;
+		d->si_int = s->si_int;
+        
+	} else switch (s->si_signo) {
+	/* XXX: What about POSIX1.b timers */
+	case SIGCHLD:
+		d->si_pid = s->si_pid;
+		d->si_status = s->si_status;
+		d->si_utime = s->si_utime;
+		d->si_stime = s->si_stime;
+		break;
+	case SIGSEGV:
+	case SIGBUS:
+	case SIGFPE:
+	case SIGILL:
+		d->si_addr = (void *)A(s->si_addr);
+  		break;
+	case SIGPOLL:
+		d->si_band = s->si_band;
+		d->si_fd = s->si_fd;
+		break;
+	default:
+		d->si_pid = s->si_pid;
+		d->si_uid = s->si_uid;
+		break;
+	}
+	return d;
+}
+
+
+extern asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
+
+/* Note: it is necessary to treat pid and sig as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_rt_sigqueueinfo(u32 pid, u32 sig, siginfo_t32 *uinfo)
+{
+	siginfo_t info;
+	siginfo_t32 info32;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+	
+	if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32)))
+		return -EFAULT;
+    	/* XXX: Is this correct? */
+	siginfo32to64(&info, &info32);
+
+	set_fs (KERNEL_DS);
+	ret = sys_rt_sigqueueinfo((int)pid, (int)sig, &info);
+	set_fs (old_fs);
+	return ret;
+}
+
+
+int do_signal(sigset_t *oldset, struct pt_regs *regs);
+int sys32_rt_sigsuspend(sigset32_t* unewset, size_t sigsetsize, int p3, int p4, int p6, int p7, struct pt_regs *regs)
+{
+	sigset_t saveset, newset;
+	
+	sigset32_t s32;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&s32, unewset, sizeof(s32)))
+		return -EFAULT;
+
+	/* Swap the 2 words of the 64-bit sigset_t (they are stored in the "wrong" endian in 32-bit user storage). */
+	switch (_NSIG_WORDS) 
+	{
+		case 4: newset.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
+		case 3: newset.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
+		case 2: newset.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
+		case 1: newset.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
+	}
+
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->gpr[3] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return regs->gpr[3];
+	}
+}
+
+
+
+
+
+
+
+
+/*
+ * Set up a rt signal frame.
+ */
+static void
+setup_rt_frame32(struct pt_regs *regs, struct sigregs32 *frame,
+            unsigned int newsp)
+{
+	unsigned int copyreg4,copyreg5;
+	struct rt_sigframe_32 * rt_sf = (struct rt_sigframe_32 *) (u64)newsp;
+
+  
+	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto badframe;
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+	/***************************************************************/
+	/*                                                             */ 
+	/* Copy the register contents for the pt_regs structure on the */
+	/*   kernel stack to the elf_gregset_t32 structure on the user */
+	/*   stack. This is a copy of 64 bit register values to 32 bit */
+	/*   register values. The high order 32 bits of the 64 bit     */
+	/*   registers are not needed since a 32 bit application is    */
+	/*   running and the saved registers are the contents of the   */
+	/*   user registers at the time of a system call.              */
+	/*                                                             */
+	/* The values saved on the user stack will be restored into    */
+	/*  the registers during the signal return processing          */
+	/*                                                             */
+	/* Note the +1 is needed in order to get the lower 32 bits     */
+	/*  of 64 bit register                                         */
+	/***************************************************************/
+	if (__copy_to_user(&frame->gp_regs[0], (u32*)(&regs->gpr[0])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[1], (u32*)(&regs->gpr[1])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[2], (u32*)(&regs->gpr[2])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[3], (u32*)(&regs->gpr[3])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[4], (u32*)(&regs->gpr[4])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[5], (u32*)(&regs->gpr[5])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[6], (u32*)(&regs->gpr[6])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[7], (u32*)(&regs->gpr[7])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[8], (u32*)(&regs->gpr[8])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[9], (u32*)(&regs->gpr[9])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[10], (u32*)(&regs->gpr[10])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[11], (u32*)(&regs->gpr[11])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[12], (u32*)(&regs->gpr[12])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[13], (u32*)(&regs->gpr[13])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[14], (u32*)(&regs->gpr[14])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[15], (u32*)(&regs->gpr[15])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[16], (u32*)(&regs->gpr[16])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[17], (u32*)(&regs->gpr[17])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[18], (u32*)(&regs->gpr[18])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[19], (u32*)(&regs->gpr[19])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[20], (u32*)(&regs->gpr[20])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[21], (u32*)(&regs->gpr[21])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[22], (u32*)(&regs->gpr[22])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[23], (u32*)(&regs->gpr[23])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[24], (u32*)(&regs->gpr[24])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[25], (u32*)(&regs->gpr[25])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[26], (u32*)(&regs->gpr[26])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[27], (u32*)(&regs->gpr[27])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[28], (u32*)(&regs->gpr[28])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[29], (u32*)(&regs->gpr[29])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[30], (u32*)(&regs->gpr[30])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[31], (u32*)(&regs->gpr[31])+1, sizeof(u32))) 
+		goto badframe;
+
+	/*****************************************************************************/
+	/* Copy the non gpr registers to the user stack                              */
+	/*****************************************************************************/
+
+	if (__copy_to_user(&frame->gp_regs[PT_NIP], (u32*)(&regs->gpr[PT_NIP])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_MSR], (u32*)(&regs->gpr[PT_MSR])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_ORIG_R3], (u32*)(&regs->gpr[PT_ORIG_R3])+1,
+			      sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_CTR], (u32*)(&regs->gpr[PT_CTR])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_LNK], (u32*)(&regs->gpr[PT_LNK])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_XER], (u32*)(&regs->gpr[PT_XER])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_CCR], (u32*)(&regs->gpr[PT_CCR])+1, sizeof(u32))
+	    || __copy_to_user(&frame->gp_regs[PT_RESULT], (u32*)(&regs->gpr[PT_RESULT])+1,
+			      sizeof(u32)))
+		goto badframe;
+
+
+	/*****************************************************************************/
+	/* Now copy the floating point registers onto the user stack                 */
+	/*                                                                           */
+	/* Also set up so on the completion of the signal handler, the sys_sigreturn */
+	/*   will get control to reset the stack                                     */
+	/*****************************************************************************/
+
+
+	if (__copy_to_user(&frame->fp_regs, current->thread.fpr,
+			   ELF_NFPREG * sizeof(double))
+	    || __put_user(0x38000000U + __NR_rt_sigreturn, &frame->tramp[0])    /* li r0, __NR_rt_sigreturn */
+	    || __put_user(0x44000002U, &frame->tramp[1]))   /* sc */
+		goto badframe;
+
+	flush_icache_range((unsigned long) &frame->tramp[0],
+			   (unsigned long) &frame->tramp[2]);
+
+  
+	/* Retrieve rt_sigframe from stack and
+	   set up registers for signal handler
+	*/
+	newsp -= __SIGNAL_FRAMESIZE32;
+      
+
+	if (put_user((u32)(regs->gpr[1]), (unsigned int *)(u64)newsp)
+	    || get_user(regs->nip, &rt_sf->uc.uc_mcontext.handler)
+	    || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
+	    || get_user(copyreg4, &rt_sf->pinfo)
+	    || get_user(copyreg5, &rt_sf->puc))
+		goto badframe;
+
+	regs->gpr[4] = copyreg4;
+	regs->gpr[5] = copyreg5;
+
+   
+	regs->gpr[1] = newsp;
+	regs->gpr[6] = (unsigned long) rt_sf;
+
+
+	regs->link = (unsigned long) frame->tramp;
+
+	return;
+
+
+ badframe:
+	udbg_printf("setup_frame32 - badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp);  PPCDBG_ENTER_DEBUGGER();
+#if DEBUG_SIG
+	printk("badframe in setup_frame32, regs=%p frame=%p newsp=%lx\n",
+	       regs, frame, newsp);
+#endif
+	do_exit(SIGSEGV);
+}
+
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal32(unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
+	      unsigned int *newspp, unsigned int frame)
+{
+	struct sigcontext32_struct *sc;
+	struct rt_sigframe_32 *rt_stack_frame;
+	siginfo_t32 siginfo32bit;
+
+	if (regs->trap == 0x0C00 /* System Call! */
+	    && ((int)regs->result == -ERESTARTNOHAND ||
+		((int)regs->result == -ERESTARTSYS &&
+		 !(ka->sa.sa_flags & SA_RESTART))))
+		regs->result = -EINTR;
+
+	/* Set up the signal frame             */
+	/*   Determine if an real time frame - siginfo required   */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+	{
+		siginfo64to32(&siginfo32bit,info);
+		*newspp -= sizeof(*rt_stack_frame);
+		rt_stack_frame = (struct rt_sigframe_32 *) (u64)(*newspp) ;
+    
+		if (verify_area(VERIFY_WRITE, rt_stack_frame, sizeof(*rt_stack_frame)))
+		{
+			goto badframe;
+		}
+		if (__put_user((u32)(u64)ka->sa.sa_handler, &rt_stack_frame->uc.uc_mcontext.handler)
+		    || __put_user((u32)(u64)&rt_stack_frame->info, &rt_stack_frame->pinfo)
+		    || __put_user((u32)(u64)&rt_stack_frame->uc, &rt_stack_frame->puc)
+		    /*  put the siginfo on the user stack                    */
+		    || __copy_to_user(&rt_stack_frame->info,&siginfo32bit,sizeof(siginfo32bit))
+		    /*  set the ucontext on the user stack                   */ 
+		    || __put_user(0,&rt_stack_frame->uc.uc_flags)
+		    || __put_user(0,&rt_stack_frame->uc.uc_link)
+		    || __put_user(current->sas_ss_sp, &rt_stack_frame->uc.uc_stack.ss_sp)
+		    || __put_user(sas_ss_flags(regs->gpr[1]),
+				  &rt_stack_frame->uc.uc_stack.ss_flags)
+		    || __put_user(current->sas_ss_size, &rt_stack_frame->uc.uc_stack.ss_size)
+		    || __copy_to_user(&rt_stack_frame->uc.uc_sigmask, oldset,sizeof(*oldset))
+		    /* point the mcontext.regs to the pramble register frame  */
+		    || __put_user(frame, &rt_stack_frame->uc.uc_mcontext.regs)
+		    || __put_user(sig,&rt_stack_frame->uc.uc_mcontext.signal))
+		{
+			goto badframe; 
+		}
+	} else {
+		/* Put another sigcontext on the stack */
+		*newspp -= sizeof(*sc);
+		sc = (struct sigcontext32_struct *)(u64)*newspp;
+		if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
+			goto badframe;
+
+		/* Note the upper 32 bits of the signal mask are stored in the */
+		/*   unused part of the signal stack frame                     */  
+		if (__put_user((u32)(u64)ka->sa.sa_handler, &sc->handler)
+		    || __put_user(oldset->sig[0], &sc->oldmask)
+		    || __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
+		    || __put_user((unsigned int)frame, &sc->regs)
+		    || __put_user(sig, &sc->signal))
+			goto badframe;
+	}
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+	
+	return;
+
+badframe:
+#if DEBUG_SIG
+	printk("badframe in handle_signal32, regs=%p frame=%lx newsp=%lx\n",
+	       regs, frame, *newspp);
+	printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
+#endif
+	do_exit(SIGSEGV);
+}
+
+
+/****************************************************************************/
+/*  Start Alternate signal stack support                                    */
+/*                                                                          */
+/*                                                                          */
+/*                                                                          */
+/*  System Calls                                                            */
+/*       sigaltatck               sys32_sigaltstack                         */
+/*                                                                          */
+/****************************************************************************/
+
+
+asmlinkage int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3, int p4, int p6,
+				 int p7, struct pt_regs *regs)
+{
+	stack_t uss, uoss;
+	int ret;
+	mm_segment_t old_fs;
+	unsigned long sp;
+
+	/* set sp to the user stack on entry to the system call                  */
+	/*   the system call router sets R9 to the saved registers               */
+	sp = regs->gpr[1];
+
+	/*  Put new stack info in local 64 bit stack struct                      */ 
+	if (newstack && (get_user((long)uss.ss_sp, &((stack_32_t *)(long)newstack)->ss_sp) ||
+			 __get_user(uss.ss_flags, &((stack_32_t *)(long)newstack)->ss_flags) ||
+			 __get_user(uss.ss_size, &((stack_32_t *)(long)newstack)->ss_size)))
+		return -EFAULT; 
+
+   
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = do_sigaltstack(newstack ? &uss : NULL, oldstack ? &uoss : NULL, sp);
+	set_fs(old_fs);
+	/* Copy the stack information to the user output buffer                  */
+	if (!ret && oldstack  && (put_user((long)uoss.ss_sp, &((stack_32_t *)(long)oldstack)->ss_sp) ||
+				  __put_user(uoss.ss_flags, &((stack_32_t *)(long)oldstack)->ss_flags) ||
+				  __put_user(uoss.ss_size, &((stack_32_t *)(long)oldstack)->ss_size)))
+		return -EFAULT;
+	return ret;
+}
+
+
+
+/****************************************************************************/
+/*  Start of do_signal32 routine                                            */
+/*                                                                          */
+/*   This routine gets control when a pemding signal needs to be processed  */
+/*     in the 32 bit target thread -                                        */
+/*                                                                          */
+/*   It handles both rt and non-rt signals                                  */
+/*                                                                          */
+/****************************************************************************/
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+
+int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+	unsigned int frame, newsp;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	newsp = frame = 0;
+
+	for (;;) {
+		unsigned long signr;
+		
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+		ifppcdebug(PPCDBG_SYS32) {
+			if (signr)
+				udbg_printf("do_signal32 - processing signal=%2lx - pid=%ld, comm=%s \n", signr, current->pid, current->comm);
+		}
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		PPCDBG(PPCDBG_SIGNAL, " do signal :sigaction flags = %lx \n" ,ka->sa.sa_flags);
+		PPCDBG(PPCDBG_SIGNAL, " do signal :on sig stack  = %lx \n" ,on_sig_stack(regs->gpr[1]));
+		PPCDBG(PPCDBG_SIGNAL, " do signal :reg1  = %lx \n" ,regs->gpr[1]);
+		PPCDBG(PPCDBG_SIGNAL, " do signal :alt stack  = %lx \n" ,current->sas_ss_sp);
+		PPCDBG(PPCDBG_SIGNAL, " do signal :alt stack size  = %lx \n" ,current->sas_ss_size);
+
+
+
+		if ( (ka->sa.sa_flags & SA_ONSTACK)
+		     && (! on_sig_stack(regs->gpr[1])))
+		{
+			newsp = (current->sas_ss_sp + current->sas_ss_size);
+		} else
+			newsp = regs->gpr[1];
+		newsp = frame = newsp - sizeof(struct sigregs32);
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal32(signr, ka, &info, oldset, regs, &newsp, frame);
+		break;
+	}
+
+	if (regs->trap == 0x0C00 /* System Call! */ &&
+	    ((int)regs->result == -ERESTARTNOHAND ||
+	     (int)regs->result == -ERESTARTSYS ||
+	     (int)regs->result == -ERESTARTNOINTR)) {
+		regs->gpr[3] = regs->orig_gpr3;
+		regs->nip -= 4;		/* Back up & retry system call */
+		regs->result = 0;
+	}
+
+	if (newsp == frame)
+	{
+		return 0;		/* no signals delivered */
+	}
+	// Invoke correct stack setup routine 
+	if (ka->sa.sa_flags & SA_SIGINFO) 
+		setup_rt_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
+	else
+		setup_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
+
+	return 1;
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/smp.c linux/arch/ppc64/kernel/smp.c
--- linux.orig/arch/ppc64/kernel/smp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/smp.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,763 @@
+/*
+ * 
+ *
+ * SMP support for ppc.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
+ * deal of code from the sparc and intel versions.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ *
+ * PowerPC-64 Support added by Dave Engebretsen, Peter Bergner, and
+ * Mike Corrigan {engebret|bergner|mikec}@us.ibm.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.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <linux/init.h>
+/* #include <linux/openpic.h> */
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/init.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
+#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/HvCall.h>
+#include <asm/iSeries/HvCallCfg.h>
+#include <asm/time.h>
+#include <asm/ppcdebug.h>
+#include "open_pic.h"
+#include <asm/machdep.h>
+
+int smp_threads_ready = 0;
+volatile int smp_commenced = 0;
+int smp_num_cpus = 1;
+int smp_tb_synchronized = 0;
+extern atomic_t ipi_recv;
+extern atomic_t ipi_sent;
+spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+cycles_t cacheflush_time;
+static int max_cpus __initdata = NR_CPUS;
+
+unsigned long cpu_online_map;
+
+volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
+
+#define TB_SYNC_PASSES 4
+volatile unsigned long __initdata tb_sync_flag = 0;
+volatile unsigned long __initdata tb_offset = 0;
+
+extern unsigned char stab_array[];
+
+int start_secondary(void *);
+extern int cpu_idle(void *unused);
+void smp_call_function_interrupt(void);
+void smp_message_pass(int target, int msg, unsigned long data, int wait);
+static unsigned long iSeries_smp_message[NR_CPUS];
+
+void xics_setup_cpu(void);
+void xics_cause_IPI(int cpu);
+
+/*
+ * XICS only has a single IPI, so encode the messages per CPU
+ */
+volatile unsigned long xics_ipi_message[NR_CPUS] = {0};
+
+#define smp_message_pass(t,m,d,w) \
+    do {     atomic_inc(&ipi_sent); \
+	     ppc_md.smp_message_pass((t),(m),(d),(w)); \
+       } while(0)
+
+#ifdef CONFIG_KDB
+void smp_kdb_stop(void)
+{
+}
+#endif
+
+static inline void set_tb(unsigned int upper, unsigned int lower)
+{
+	mtspr(SPRN_TBWL, 0);
+	mtspr(SPRN_TBWU, upper);
+	mtspr(SPRN_TBWL, lower);
+}
+
+void iSeries_smp_message_recv( struct pt_regs * regs )
+{
+	int cpu = smp_processor_id();
+	int msg;
+
+	if ( smp_num_cpus < 2 )
+		return;
+
+	for ( msg = 0; msg < 4; ++msg )
+		if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) )
+			smp_message_recv( msg, regs );
+
+}
+
+static void smp_iSeries_message_pass(int target, int msg, unsigned long data, int wait)
+{
+	int i;
+	for (i = 0; i < smp_num_cpus; ++i) {
+		if ( (target == MSG_ALL) || 
+                    (target == i) || 
+                    ((target == MSG_ALL_BUT_SELF) && (i != smp_processor_id())) ) {
+			set_bit( msg, &iSeries_smp_message[i] );
+			HvCall_sendIPI(&(paca[i]));
+		}
+	}
+}
+
+static int smp_iSeries_numProcs(void)
+{
+	unsigned np, i;
+	struct ItLpPaca * lpPaca;
+
+	np = 0;
+        for (i=0; i < MAX_PACAS; ++i) {
+                lpPaca = paca[i].xLpPacaPtr;
+                if ( lpPaca->xDynProcStatus < 2 ) {
+                        ++np;
+                }
+        }
+	return np;
+}
+
+static int smp_iSeries_probe(void)
+{
+	unsigned i;
+	unsigned np;
+	struct ItLpPaca * lpPaca;
+
+	np = 0;
+	for (i=0; i < MAX_PACAS; ++i) {
+		lpPaca = paca[i].xLpPacaPtr;
+		if ( lpPaca->xDynProcStatus < 2 ) {
+			++np;
+			paca[i].next_jiffy_update_tb = paca[0].next_jiffy_update_tb;
+		}
+	}
+	
+	smp_tb_synchronized = 1;
+	return np;
+}
+
+static void smp_iSeries_kick_cpu(int nr)
+{
+	struct ItLpPaca * lpPaca;
+	/* Verify we have a Paca for processor nr */
+	if ( ( nr <= 0 ) ||
+	     ( nr >= MAX_PACAS ) )
+		return;
+	/* Verify that our partition has a processor nr */
+	lpPaca = paca[nr].xLpPacaPtr;
+	if ( lpPaca->xDynProcStatus >= 2 )
+		return;
+
+	/* The information for processor bringup must
+	 * be written out to main store before we release
+	 * the processor.
+	 */
+	mb();
+
+	/* The processor is currently spinning, waiting
+	 * for the xProcStart field to become non-zero
+	 * After we set xProcStart, the processor will
+	 * continue on to secondary_start in iSeries_head.S
+	 */
+	paca[nr].xProcStart = 1;
+}
+
+static void smp_iSeries_setup_cpu(int nr)
+{
+}
+
+/* This is called very early. */
+void smp_init_iSeries(void)
+{
+	ppc_md.smp_message_pass = smp_iSeries_message_pass;
+	ppc_md.smp_probe        = smp_iSeries_probe;
+	ppc_md.smp_kick_cpu     = smp_iSeries_kick_cpu;
+	ppc_md.smp_setup_cpu    = smp_iSeries_setup_cpu;
+
+	naca->processorCount	= smp_iSeries_numProcs();
+}
+
+
+static void
+smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
+{
+	/* make sure we're sending something that translates to an IPI */
+	if ( msg > 0x3 ){
+		printk("SMP %d: smp_message_pass: unknown msg %d\n",
+		       smp_processor_id(), msg);
+		return;
+	}
+	switch ( target )
+	{
+	case MSG_ALL:
+		openpic_cause_IPI(msg, 0xffffffff);
+		break;
+	case MSG_ALL_BUT_SELF:
+		openpic_cause_IPI(msg,
+				  0xffffffff & ~(1 << smp_processor_id()));
+		break;
+	default:
+		openpic_cause_IPI(msg, 1<<target);
+		break;
+	}
+}
+
+static int
+smp_chrp_probe(void)
+{
+	if (naca->processorCount > 1)
+		openpic_request_IPIs();
+
+	return naca->processorCount;
+}
+
+static void
+smp_kick_cpu(int nr)
+{
+	/* Verify we have a Paca for processor nr */
+	if ( ( nr <= 0 ) ||
+	     ( nr >= MAX_PACAS ) )
+		return;
+
+	/* The information for processor bringup must
+	 * be written out to main store before we release
+	 * the processor.
+	 */
+	mb();
+
+	/* The processor is currently spinning, waiting
+	 * for the xProcStart field to become non-zero
+	 * After we set xProcStart, the processor will
+	 * continue on to secondary_start in iSeries_head.S
+	 */
+	paca[nr].xProcStart = 1;
+}
+
+extern struct gettimeofday_struct do_gtod;
+
+static void smp_space_timers( unsigned nr )
+{
+	unsigned long offset, i;
+	
+	offset = tb_ticks_per_jiffy / nr;
+	for ( i=1; i<nr; ++i ) {
+		paca[i].next_jiffy_update_tb = paca[i-1].next_jiffy_update_tb + offset;
+	}
+}
+
+static void
+smp_chrp_setup_cpu(int cpu_nr)
+{
+	static atomic_t ready = ATOMIC_INIT(1);
+	static volatile int frozen = 0;
+
+	if (naca->platform == PLATFORM_PSERIES_LPAR) {
+		/* timebases already synced under the hypervisor. */
+		paca[cpu_nr].next_jiffy_update_tb = tb_last_stamp = get_tb();
+		if (cpu_nr == 0) {
+			do_gtod.tb_orig_stamp = tb_last_stamp;
+			/* Should update do_gtod.stamp_xsec.
+			 * For now we leave it which means the time can be some
+			 * number of msecs off until someone does a settimeofday()
+			 */
+		}
+		smp_tb_synchronized = 1;
+	} else {
+		if (cpu_nr == 0) {
+			/* wait for all the others */
+			while (atomic_read(&ready) < smp_num_cpus)
+				barrier();
+			atomic_set(&ready, 1);
+			/* freeze the timebase */
+			rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
+			mb();
+			frozen = 1;
+			set_tb(0, 0);
+			paca[0].next_jiffy_update_tb = 0;
+			smp_space_timers(smp_num_cpus);
+			while (atomic_read(&ready) < smp_num_cpus)
+				barrier();
+			/* thaw the timebase again */
+			rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
+			mb();
+			frozen = 0;
+			tb_last_stamp = get_tb();
+			do_gtod.tb_orig_stamp = tb_last_stamp;
+			smp_tb_synchronized = 1;
+		} else {
+			atomic_inc(&ready);
+			while (!frozen)
+				barrier();
+			set_tb(0, 0);
+			mb();
+			atomic_inc(&ready);
+			while (frozen)
+				barrier();
+		}
+	}
+
+	if (OpenPIC_Addr) {
+		do_openpic_setup_cpu();
+	} else {
+	  if (cpu_nr > 0)
+	    xics_setup_cpu();
+	}
+}
+
+static void
+smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
+{
+	int i;
+
+	for (i = 0; i < smp_num_cpus; ++i) {
+		if (target == MSG_ALL || target == i
+		    || (target == MSG_ALL_BUT_SELF
+			&& i != smp_processor_id())) {
+			set_bit(msg, &xics_ipi_message[i]);
+			mb();
+			xics_cause_IPI(i);
+			}
+	}
+}
+
+static int
+smp_xics_probe(void)
+{
+	return naca->processorCount;
+}
+
+/* This is called very early */
+void smp_init_pSeries(void)
+{
+	if(naca->interrupt_controller == IC_OPEN_PIC) {
+		ppc_md.smp_message_pass = smp_openpic_message_pass;
+		ppc_md.smp_probe        = smp_chrp_probe;
+		ppc_md.smp_kick_cpu     = smp_kick_cpu;
+		ppc_md.smp_setup_cpu    = smp_chrp_setup_cpu;
+	} else {
+		ppc_md.smp_message_pass = smp_xics_message_pass;
+		ppc_md.smp_probe        = smp_xics_probe;
+		ppc_md.smp_kick_cpu     = smp_kick_cpu;
+		ppc_md.smp_setup_cpu    = smp_chrp_setup_cpu;
+	}
+}
+
+
+void smp_local_timer_interrupt(struct pt_regs * regs)
+{
+	if (!--(get_paca()->prof_counter)) {
+		update_process_times(user_mode(regs));
+		(get_paca()->prof_counter)=get_paca()->prof_multiplier;
+	}
+}
+
+void smp_message_recv(int msg, struct pt_regs *regs)
+{
+	atomic_inc(&ipi_recv);
+	
+	switch( msg ) {
+	case PPC_MSG_CALL_FUNCTION:
+		smp_call_function_interrupt();
+		break;
+	case PPC_MSG_RESCHEDULE: 
+		current->need_resched = 1;
+		break;
+#ifdef CONFIG_XMON
+	case PPC_MSG_XMON_BREAK:
+		xmon(regs);
+		break;
+#endif /* CONFIG_XMON */
+#ifdef CONFIG_KDB
+	case PPC_MSG_XMON_BREAK:
+	        /* This isn't finished yet, obviously -TAI */
+		kdb(KDB_REASON_KEYBOARD,0, (kdb_eframe_t) regs);
+		break;
+#endif
+	default:
+		printk("SMP %d: smp_message_recv(): unknown msg %d\n",
+		       smp_processor_id(), msg);
+		break;
+	}
+}
+
+void smp_send_reschedule(int cpu)
+{
+	smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
+}
+
+#ifdef CONFIG_XMON
+void smp_send_xmon_break(int cpu)
+{
+	smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0);
+}
+#endif /* CONFIG_XMON */
+
+static void stop_this_cpu(void *dummy)
+{
+	__cli();
+	while (1)
+		;
+}
+
+void smp_send_stop(void)
+{
+	smp_call_function(stop_this_cpu, NULL, 1, 0);
+	smp_num_cpus = 1;
+}
+
+/*
+ * Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
+ * Stolen from the i386 version.
+ */
+static spinlock_t call_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+
+static struct call_data_struct {
+	void (*func) (void *info);
+	void *info;
+	atomic_t started;
+	atomic_t finished;
+	int wait;
+} *call_data;
+
+/*
+ * This function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ *
+ * [SUMMARY] Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <nonatomic> currently unused.
+ * <wait> If true, wait (atomically) until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code. Does not return until
+ * 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.
+ */
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+			int wait)
+
+{ 
+	struct call_data_struct data;
+	int ret = -1, cpus = smp_num_cpus-1;
+	int timeout;
+
+	if (!cpus)
+		return 0;
+
+	data.func = func;
+	data.info = info;
+	atomic_set(&data.started, 0);
+	data.wait = wait;
+	if (wait)
+		atomic_set(&data.finished, 0);
+
+	spin_lock_bh(&call_lock);
+	call_data = &data;
+	/* Send a message to all other CPUs and wait for them to respond */
+	smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION, 0, 0);
+
+	/* Wait for response */
+	timeout = 8000000;
+	while (atomic_read(&data.started) != cpus) {
+		HMT_low();
+		if (--timeout == 0) {
+			printk("smp_call_function on cpu %d: other cpus not responding (%d)\n",
+			       smp_processor_id(), atomic_read(&data.started));
+#ifdef CONFIG_XMON
+                        xmon(0);
+#endif
+#ifdef CONFIG_PPC_ISERIES
+			HvCall_terminateMachineSrc();
+#endif
+			goto out;
+		}
+		barrier();
+		udelay(1);
+	}
+
+	if (wait) {
+		timeout = 1000000;
+		while (atomic_read(&data.finished) != cpus) {
+			HMT_low();
+			if (--timeout == 0) {
+				printk("smp_call_function on cpu %d: other cpus not finishing (%d/%d)\n",
+				       smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started));
+#ifdef CONFIG_PPC_ISERIES
+				HvCall_terminateMachineSrc();
+#endif
+				goto out;
+			}
+			barrier();
+			udelay(1);
+		}
+	}
+	ret = 0;
+
+ out:
+	HMT_medium();
+	spin_unlock_bh(&call_lock);
+	return ret;
+}
+
+void smp_call_function_interrupt(void)
+{
+	void (*func) (void *info) = call_data->func;
+	void *info = call_data->info;
+	int wait = call_data->wait;
+
+	/*
+	 * Notify initiating CPU that I've grabbed the data and am
+	 * about to execute the function
+	 */
+	atomic_inc(&call_data->started);
+	/*
+	 * At this point the info structure may be out of scope unless wait==1
+	 */
+	(*func)(info);
+	if (wait)
+		atomic_inc(&call_data->finished);
+}
+
+extern unsigned long decr_overclock;
+
+void __init smp_boot_cpus(void)
+{
+	extern struct current_set_struct current_set[];
+	extern void __secondary_start_chrp(void);
+	int i, cpu_nr;
+	struct task_struct *p;
+	unsigned long sp;
+
+	printk("Entering SMP Mode...\n");
+	PPCDBG(PPCDBG_SMP, "smp_boot_cpus: start.  NR_CPUS = 0x%lx\n", NR_CPUS);
+
+	smp_num_cpus = 1;
+        smp_store_cpu_info(0);
+	cpu_online_map = 1UL;
+
+	/*
+	 * assume for now that the first cpu booted is
+	 * cpu 0, the master -- Cort
+	 */
+	cpu_callin_map[0] = 1;
+	current->processor = 0;
+
+	init_idle();
+
+	for (i = 0; i < NR_CPUS; i++) {
+		paca[i].prof_counter=1;
+		paca[i].prof_multiplier = 1;
+		if(i != 0) {
+		        /*
+			 * Processor 0's segment table is statically 
+			 * initialized to real address 0x5000.  The
+			 * Other processor's tables are created and
+			 * initialized here.
+			 */
+			paca[i].xStab_data.virt = (unsigned long)&stab_array[PAGE_SIZE * (i-1)];
+			memset((void *)paca[i].xStab_data.virt, 0, PAGE_SIZE); 
+			paca[i].xStab_data.real = __v2a(paca[i].xStab_data.virt);
+			paca[i].default_decr = tb_ticks_per_jiffy / decr_overclock;
+		}
+	}
+
+	/*
+	 * XXX very rough, assumes 20 bus cycles to read a cache line,
+	 * timebase increments every 4 bus cycles, 32kB L1 data cache.
+	 */
+	cacheflush_time = 5 * 1024;
+
+	/* Probe arch for CPUs */
+	cpu_nr = ppc_md.smp_probe();
+
+	printk("Probe found %d CPUs\n", cpu_nr);
+
+	/*
+	 * only check for cpus we know exist.  We keep the callin map
+	 * with cpus at the bottom -- Cort
+	 */
+	if (cpu_nr > max_cpus)
+		cpu_nr = max_cpus;
+
+#ifdef CONFIG_ISERIES
+	smp_space_timers( cpu_nr );
+#endif
+
+	printk("Waiting for %d CPUs\n", cpu_nr-1);
+
+	for ( i = 1 ; i < cpu_nr; i++ ) {
+		int c;
+		struct pt_regs regs;
+		
+		/* create a process for the processor */
+		/* we don't care about the values in regs since we'll
+		   never reschedule the forked task. */
+		/* We DO care about one bit in the pt_regs we
+		   pass to do_fork.  That is the MSR_FP bit in
+		   regs.msr.  If that bit is on, then do_fork
+		   (via copy_thread) will call giveup_fpu.
+		   giveup_fpu will get a pointer to our (current's)
+		   last register savearea via current->thread.regs
+		   and using that pointer will turn off the MSR_FP,
+		   MSR_FE0 and MSR_FE1 bits.  At this point, this
+		   pointer is pointing to some arbitrary point within
+		   our stack */
+
+		memset(&regs, 0, sizeof(struct pt_regs));
+
+		if (do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0) < 0)
+			panic("failed fork for CPU %d", i);
+		p = init_task.prev_task;
+		if (!p)
+			panic("No idle task for CPU %d", i);
+
+		PPCDBG(PPCDBG_SMP,"\tProcessor %d, task = 0x%lx\n", i, p);
+
+		del_from_runqueue(p);
+		unhash_process(p);
+		init_tasks[i] = p;
+
+		p->processor = i;
+		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
+		current_set[i].task = p;
+		sp = ((unsigned long)p) + sizeof(union task_union)
+			- STACK_FRAME_OVERHEAD;
+		current_set[i].sp_real = (void *)__v2a(sp);
+
+		/* wake up cpus */
+		ppc_md.smp_kick_cpu(i);
+
+		/*
+		 * wait to see if the cpu made a callin (is actually up).
+		 * use this value that I found through experimentation.
+		 * -- Cort
+		 */
+		for ( c = 5000; c && !cpu_callin_map[i] ; c-- ) {
+			udelay(100);
+		}
+		
+		if ( cpu_callin_map[i] )
+		{
+			printk("Processor %d found.\n", i);
+			PPCDBG(PPCDBG_SMP, "\tProcessor %d found.\n", i);
+			/* this sync's the decr's -- Cort */
+			smp_num_cpus++;
+		} else {
+			printk("Processor %d is stuck.\n", i);
+			PPCDBG(PPCDBG_SMP, "\tProcessor %d is stuck.\n", i);
+		}
+	}
+
+	/* Setup CPU 0 last (important) */
+	ppc_md.smp_setup_cpu(0);
+	
+	if (smp_num_cpus < 2) {
+	        tb_last_stamp = get_tb();
+		smp_tb_synchronized = 1;
+	}
+}
+
+void __init smp_commence(void)
+{
+	/*
+	 *	Lets the callin's below out of their loop.
+	 */
+	PPCDBG(PPCDBG_SMP, "smp_commence: start\n"); 
+	wmb();
+	smp_commenced = 1;
+}
+
+void __init smp_callin(void)
+{
+	int cpu = current->processor;
+	
+        smp_store_cpu_info(cpu);
+	set_dec(paca[cpu].default_decr);
+	cpu_callin_map[cpu] = 1;
+
+	ppc_md.smp_setup_cpu(cpu);
+
+	init_idle();
+
+	set_bit(smp_processor_id(), &cpu_online_map);
+	
+	while(!smp_commenced) {
+		barrier();
+	}
+	__sti();
+}
+
+/* intel needs this */
+void __init initialize_secondary(void)
+{
+}
+
+/* Activate a secondary processor. */
+int start_secondary(void *unused)
+{
+	int cpu; 
+
+	cpu = current->processor;
+	atomic_inc(&init_mm.mm_count);
+	current->active_mm = &init_mm;
+	smp_callin();
+
+	/* Go into the idle loop. */
+	return cpu_idle(NULL);
+}
+
+void __init smp_setup(char *str, int *ints)
+{
+}
+
+int __init setup_profiling_timer(unsigned int multiplier)
+{
+	return 0;
+}
+
+/* this function is called for each processor
+ */
+void __init smp_store_cpu_info(int id)
+{
+        paca[id].pvr = _get_PVR();
+}
+
+static int __init maxcpus(char *str)
+{
+	get_option(&str, &max_cpus);
+	return 1;
+}
+
+__setup("maxcpus=", maxcpus);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/stab.c linux/arch/ppc64/kernel/stab.c
--- linux.orig/arch/ppc64/kernel/stab.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/stab.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,359 @@
+/*
+ * PowerPC64 Segment Translation Support.
+ *
+ * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
+ *    Copyright (c) 2001 Dave Engebretsen
+ * 
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+#include <asm/paca.h>
+#include <asm/naca.h>
+#include <asm/pmc.h>
+
+inline int make_ste(unsigned long stab, 
+		    unsigned long esid, unsigned long vsid);
+inline void make_slbe(unsigned long esid, unsigned long vsid,
+		      int large);
+
+/*
+ * Build an entry for the base kernel segment and put it into
+ * the segment table or SLB.  All other segment table or SLB
+ * entries are faulted in.
+ */
+void stab_initialize(unsigned long stab)
+{
+	unsigned long esid, vsid; 
+
+	esid = GET_ESID(KERNELBASE);
+	vsid = get_kernel_vsid(esid << SID_SHIFT); 
+
+	if (!__is_processor(PV_POWER4)) {
+                __asm__ __volatile__("isync; slbia; isync":::"memory");
+		make_ste(stab, esid, vsid);
+	} else {
+                /* Invalidate the entire SLB & all the ERATS */
+                __asm__ __volatile__("isync" : : : "memory");
+#ifndef CONFIG_PPC_ISERIES
+                __asm__ __volatile__("slbmte  %0,%0"
+                                      : : "r" (0) : "memory");
+                __asm__ __volatile__("isync; slbia; isync":::"memory");
+		make_slbe(esid, vsid, 0);
+#else
+                __asm__ __volatile__("isync; slbia; isync":::"memory");
+#endif
+        }
+}
+
+/*
+ * Create a segment table entry for the given esid/vsid pair.
+ */ 
+inline int
+make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
+{
+	unsigned long entry, group, old_esid, castout_entry, i;
+	unsigned int global_entry;
+	STE *ste, *castout_ste;
+
+	/* Search the primary group first. */
+	global_entry = (esid & 0x1f) << 3;
+	ste = (STE *)(stab | ((esid & 0x1f) << 7)); 
+
+	/*
+	 * Find an empty entry, if one exists.
+	 */
+	for(group = 0; group < 2; group++) {
+		for(entry = 0; entry < 8; entry++, ste++) {
+			if(!(ste->dw0.dw0.v)) {
+				ste->dw1.dw1.vsid = vsid;
+				/* Order VSID updte */
+				__asm__ __volatile__ ("eieio" : : : "memory");
+				ste->dw0.dw0.esid = esid;
+				ste->dw0.dw0.v  = 1;
+				ste->dw0.dw0.kp = 1;
+				/* Order update     */
+				__asm__ __volatile__ ("sync" : : : "memory"); 
+
+				return(global_entry | entry);
+			}
+		}
+		/* Now search the secondary group. */
+		global_entry = ((~esid) & 0x1f) << 3;
+		ste = (STE *)(stab | (((~esid) & 0x1f) << 7)); 
+	}
+
+	/*
+	 * Could not find empty entry, pick one with a round robin selection.
+	 * Search all entries in the two groups.  Note that the first time
+	 * we get here, we start with entry 1 so the initializer
+	 * can be common with the SLB castout code.
+	 */
+
+	/* This assumes we never castout when initializing the stab. */
+	PMC_SW_PROCESSOR(stab_capacity_castouts); 
+
+	castout_entry = get_paca()->xStab_data.next_round_robin;
+	for(i = 0; i < 16; i++) {
+		if(castout_entry < 8) {
+			global_entry = (esid & 0x1f) << 3;
+			ste = (STE *)(stab | ((esid & 0x1f) << 7)); 
+			castout_ste = ste + castout_entry;
+		} else {
+			global_entry = ((~esid) & 0x1f) << 3;
+			ste = (STE *)(stab | (((~esid) & 0x1f) << 7)); 
+			castout_ste = ste + (castout_entry - 8);
+		}
+
+		if((((castout_ste->dw0.dw0.esid) >> 32) == 0) ||
+		   (((castout_ste->dw0.dw0.esid) & 0xffffffff) > 0)) {
+			/* Found an entry to castout.  It is either a user */
+			/* region, or a secondary kernel segment.          */
+			break;
+		}
+
+		castout_entry = (castout_entry + 1) & 0xf;
+	}
+
+	get_paca()->xStab_data.next_round_robin = (castout_entry + 1) & 0xf;
+
+	/* Modify the old entry to the new value. */
+
+	/* Force previous translations to complete. DRENG */
+	__asm__ __volatile__ ("isync" : : : "memory" );
+
+	castout_ste->dw0.dw0.v = 0;
+	__asm__ __volatile__ ("sync" : : : "memory" );    /* Order update */
+	castout_ste->dw1.dw1.vsid = vsid;
+	__asm__ __volatile__ ("eieio" : : : "memory" );   /* Order update */
+	old_esid = castout_ste->dw0.dw0.esid;
+	castout_ste->dw0.dw0.esid = esid;
+	castout_ste->dw0.dw0.v  = 1;
+	castout_ste->dw0.dw0.kp = 1;
+	__asm__ __volatile__ ("slbie  %0" : : "r" (old_esid << SID_SHIFT)); 
+	/* Ensure completion of slbie */
+	__asm__ __volatile__ ("sync" : : : "memory" );  
+
+	return(global_entry | (castout_entry & 0x7));
+}
+
+/*
+ * Create a segment buffer entry for the given esid/vsid pair.
+ */ 
+inline void make_slbe(unsigned long esid, unsigned long vsid, int large)
+{
+	unsigned long entry, castout_entry;
+	slb_dword0 castout_esid_data;
+	union {
+		unsigned long word0;
+		slb_dword0    data;
+	} esid_data;
+	union {
+		unsigned long word0;
+		slb_dword1    data;
+	} vsid_data;
+	
+	/*
+	 * Find an empty entry, if one exists.
+	 */
+	for(entry = 0; entry < naca->slb_size; entry++) {
+		__asm__ __volatile__("slbmfee  %0,%1" 
+				     : "=r" (esid_data) : "r" (entry)); 
+		if(!esid_data.data.v) {
+			/* 
+			 * Write the new SLB entry.
+			 */
+			vsid_data.word0 = 0;
+			vsid_data.data.vsid = vsid;
+			vsid_data.data.kp = 1;
+			if (large)
+				vsid_data.data.l = 1;
+
+			esid_data.word0 = 0;
+			esid_data.data.esid = esid;
+			esid_data.data.v = 1;
+			esid_data.data.index = entry;
+
+			/* slbie not needed as no previous mapping existed. */
+			/* Order update  */
+			__asm__ __volatile__ ("isync" : : : "memory");
+			__asm__ __volatile__ ("slbmte  %0,%1" 
+					      : : "r" (vsid_data), 
+					      "r" (esid_data)); 
+			/* Order update  */
+			__asm__ __volatile__ ("isync" : : : "memory");
+			return;
+		}
+	}
+	
+	/*
+	 * Could not find empty entry, pick one with a round robin selection.
+	 */
+
+	PMC_SW_PROCESSOR(stab_capacity_castouts); 
+
+	castout_entry = get_paca()->xStab_data.next_round_robin;
+	__asm__ __volatile__("slbmfee  %0,%1" 
+			     : "=r" (castout_esid_data) 
+			     : "r" (castout_entry)); 
+
+	entry = castout_entry; 
+	castout_entry++; 
+	if(castout_entry >= naca->slb_size) {
+		castout_entry = 1; 
+	}
+	get_paca()->xStab_data.next_round_robin = castout_entry;
+
+	/* Invalidate the old entry. */
+	castout_esid_data.v = 0; /* Set the class to 0 */
+	/* slbie not needed as the previous mapping is still valid. */
+	__asm__ __volatile__("slbie  %0" : : "r" (castout_esid_data)); 
+	
+	/* 
+	 * Write the new SLB entry.
+	 */
+	vsid_data.word0 = 0;
+	vsid_data.data.vsid = vsid;
+	vsid_data.data.kp = 1;
+	if (large)
+		vsid_data.data.l = 1;
+	
+	esid_data.word0 = 0;
+	esid_data.data.esid = esid;
+	esid_data.data.v = 1;
+	esid_data.data.index = entry;
+	
+	__asm__ __volatile__ ("isync" : : : "memory");   /* Order update */
+	__asm__ __volatile__ ("slbmte  %0,%1" 
+			      : : "r" (vsid_data), "r" (esid_data)); 
+	__asm__ __volatile__ ("isync" : : : "memory" );   /* Order update */
+}
+
+/*
+ * Allocate a segment table entry for the given ea.
+ */
+int ste_allocate ( unsigned long ea, 
+		   unsigned long trap) 
+{
+	unsigned long vsid, esid;
+	int kernel_segment = 0;
+
+	PMC_SW_PROCESSOR(stab_faults); 
+
+	/* Check for invalid effective addresses. */
+	if (!IS_VALID_EA(ea)) {
+		return 1;
+	}
+	
+	/* Kernel or user address? */
+	if (REGION_ID(ea)) {
+		kernel_segment = 1;
+		vsid = get_kernel_vsid( ea );
+	} else {
+		struct mm_struct *mm = current->mm;
+		if ( mm ) {
+			vsid = get_vsid(mm->context, ea );
+		} else {
+			return 1;
+		}
+	}
+
+	esid = GET_ESID(ea);
+	if (trap == 0x380 || trap == 0x480) {
+#ifndef CONFIG_PPC_ISERIES
+		if (REGION_ID(ea) == KERNEL_REGION_ID)
+			make_slbe(esid, vsid, 1); 
+		else
+#endif
+			make_slbe(esid, vsid, 0); 
+	} else {
+		unsigned char top_entry, stab_entry, *segments; 
+
+		stab_entry = make_ste(get_paca()->xStab_data.virt, esid, vsid);
+		PMC_SW_PROCESSOR_A(stab_entry_use, stab_entry & 0xf); 
+
+		segments = get_paca()->xSegments;		
+		top_entry = segments[0];
+		if(!kernel_segment && top_entry < (STAB_CACHE_SIZE - 1)) {
+			top_entry++;
+			segments[top_entry] = stab_entry;
+			if(top_entry == STAB_CACHE_SIZE - 1) top_entry = 0xff;
+			segments[0] = top_entry;
+		}
+	}
+	
+	return(0); 
+}
+ 
+/* 
+ * Flush all entries from the segment table of the current processor.
+ * Kernel and Bolted entries are not removed as we cannot tolerate 
+ * faults on those addresses.
+ */
+
+#define STAB_PRESSURE 0
+
+void flush_stab(void)
+{
+	STE *stab = (STE *) get_paca()->xStab_data.virt;
+	unsigned char *segments = get_paca()->xSegments;
+	unsigned long flags, i;
+
+	if(!__is_processor(PV_POWER4)) {
+		unsigned long entry;
+		STE *ste;
+
+		/* Force previous translations to complete. DRENG */
+		__asm__ __volatile__ ("isync" : : : "memory");
+
+		__save_and_cli(flags);
+		if(segments[0] != 0xff && !STAB_PRESSURE) {
+			for(i = 1; i <= segments[0]; i++) {
+				ste = stab + segments[i]; 
+				ste->dw0.dw0.v = 0;
+				PMC_SW_PROCESSOR(stab_invalidations); 
+			}
+		} else {
+			/* Invalidate all entries. */
+                        ste = stab;
+
+		        /* Never flush the first entry. */ 
+		        ste += 1;
+			for(entry = 1;
+			    entry < (PAGE_SIZE / sizeof(STE)); 
+			    entry++, ste++) {
+				unsigned long ea;
+				ea = ste->dw0.dw0.esid << SID_SHIFT;
+				if (STAB_PRESSURE || (!REGION_ID(ea))) {
+					ste->dw0.dw0.v = 0;
+					PMC_SW_PROCESSOR(stab_invalidations); 
+				}
+			}
+		}
+
+		*((unsigned long *)segments) = 0;
+		__restore_flags(flags);
+
+		/* Invalidate the SLB. */
+		/* Force invals to complete. */
+		__asm__ __volatile__ ("sync" : : : "memory");  
+		/* Flush the SLB.            */
+		__asm__ __volatile__ ("slbia" : : : "memory"); 
+		/* Force flush to complete.  */
+		__asm__ __volatile__ ("sync" : : : "memory");  
+	} else {
+		unsigned long flags;
+
+		PMC_SW_PROCESSOR(stab_invalidations); 
+
+		__save_and_cli(flags);
+		__asm__ __volatile__("isync; slbia; isync":::"memory");
+		__restore_flags(flags);
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/sys32.S linux/arch/ppc64/kernel/sys32.S
--- linux.orig/arch/ppc64/kernel/sys32.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/sys32.S	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,243 @@
+/* 
+ * sys32.S: I-cache tricks for 32-bit compatability layer simple
+ *          conversions.
+ *
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1998 Jakub Jelinek   (jj@ultra.linux.cz)
+ * Copyright (C) 2000 Ken Aaker (kdaaker@rchland.vnet.ibm.com)
+ * For PPC ABI convention is parms in Regs 3-10.
+ * The router in entry.S clears the high 32 bits in the first
+ * 4 arguments (R3-R6).
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include "ppc_asm.h"
+#include <asm/errno.h>
+#include <asm/processor.h>
+
+/* NOTE: call as jump breaks return stack, we have to avoid that */
+
+	.text
+
+_GLOBAL(sys32_mmap)
+	clrldi		r7, r7, 32	/* int fd parm */
+	clrldi		r8, r8, 32	/* off_t offset parm */
+	b		.sys_mmap
+
+_GLOBAL(sys32_lseek)
+	extsw		r4,r4		/* sign extend off_t offset parm */
+	b		.sys_lseek
+
+_GLOBAL(sys32_chmod)
+/* Ken Aaker.. hmmm maybe I don't need to do anything here */
+	b		.sys_chmod
+
+_GLOBAL(sys32_mknod)
+/* Ken Aaker.. hmmm maybe I don't need to do anything here */
+	b		.sys_mknod
+
+_GLOBAL(sys32_sendto)
+	clrldi		r7, r7, 32	/* struct sockaddr *addr parm */
+	clrldi		r8, r8, 32	/* int addr_len parm */
+	b		.sys_sendto
+
+_GLOBAL(sys32_recvfrom)
+	clrldi		r7, r7, 32	/* struct sockaddr *addr parm */
+	clrldi		r8, r8, 32	/* int *addr_len parm */
+	b		.sys_recvfrom
+
+_GLOBAL(sys32_getsockopt)
+	clrldi		r7, r7, 32	/* int *optlen parm */
+	b		.sys_getsockopt
+
+_GLOBAL(sys32_bdflush)
+	extsw		r4,r4		/* sign extend long data parm */
+	b		.sys_bdflush
+
+_GLOBAL(sys32_mmap2)
+	clrldi		r7, r7, 32	/* unsigned long fd parm */
+	extsw		r8, r8		/* off_t offset */
+	b		.sys_mmap
+
+_GLOBAL(sys32_socketcall)	/* r3=call, r4=args */
+	cmpwi		r3, 1
+	blt-		.do_einval
+	cmpwi		r3, 17
+	bgt-		.do_einval
+	subi		r3, r3, 1	/* index into socketcall_table vectors and jmp */
+	sldi		r3, r3, 3	/* each entry is 8 bytes */
+	LOADADDR(r10,.socketcall_table_begin)
+	ldx		r10, r10, r3
+	mtctr		r10
+	bctr
+
+/* Socket function vectored fix ups for 32 bit */
+_STATIC(do_sys_socket) /* sys_socket(int, int, int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwa		r4,4(r10)
+	lwa		r5,8(r10)
+	b		.sys_socket
+
+_STATIC(do_sys_bind) /* sys_bind(int fd, struct sockaddr *, int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwa		r5,8(r10)
+	b		.sys_bind
+
+_STATIC(do_sys_connect) /* sys_connect(int, struct sockaddr *, int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwa		r5,8(r10)
+	b		.sys_connect
+
+_STATIC(do_sys_listen) /* sys_listen(int, int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwa		r4,4(r10)
+	b		.sys_listen
+
+_STATIC(do_sys_accept) /* sys_accept(int, struct sockaddr *, int *) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwz		r5,8(r10)
+	b		.sys_accept
+
+_STATIC(do_sys_getsockname) /* sys_getsockname(int, struct sockaddr *, int *) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwz		r5,8(r10)
+	b		.sys_getsockname
+
+_STATIC(do_sys_getpeername) /* sys_getpeername(int, struct sockaddr *, int *) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwz		r5,8(r10)
+	b		.sys_getpeername
+
+_STATIC(do_sys_socketpair) /* sys_socketpair(int, int, int, int *) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwa		r4,4(r10)
+	lwa		r5,8(r10)
+	lwz		r6,12(r10)
+	b		.sys_socketpair
+
+_STATIC(do_sys_send) /* sys_send(int, void *, size_t, unsigned int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwz		r5,8(r10)
+	lwz		r6,12(r10)
+	b		.sys_send
+
+_STATIC(do_sys_recv) /* sys_recv(int, void *, size_t, unsigned int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwz		r5,8(r10)
+	lwz		r6,12(r10)
+	b		.sys_recv
+
+_STATIC(do_sys_sendto) /* sys32_sendto(int, u32, __kernel_size_t32, unsigned int, u32, int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwz		r5,8(r10)
+	lwz		r6,12(r10)
+	lwz		r7,16(r10)
+	lwa		r8,20(r10)
+	b		.sys32_sendto
+
+_STATIC(do_sys_recvfrom) /* sys32_recvfrom(int, u32, __kernel_size_t32, unsigned int, u32, u32) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwz		r5,8(r10)
+	lwz		r6,12(r10)
+	lwz		r7,16(r10)
+	lwz		r8,20(r10)
+	b		.sys32_recvfrom
+
+_STATIC(do_sys_shutdown) /* sys_shutdown(int, int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwa		r4,4(r10)
+	b		.sys_shutdown
+
+_STATIC(do_sys_setsockopt) /* sys32_setsockopt(int, int, int, char *, int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwa		r4,4(r10)
+	lwa		r5,8(r10)
+	lwz		r6,12(r10)
+	lwa		r7,16(r10)
+	b		.sys32_setsockopt
+
+_STATIC(do_sys_getsockopt) /* sys32_getsockopt(int, int, int, u32, u32) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwa		r4,4(r10)
+	lwa		r5,8(r10)
+	lwz		r6,12(r10)
+	lwz		r7,16(r10)
+	b		.sys32_getsockopt
+
+_STATIC(do_sys_sendmsg) /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwa		r5,8(r10)
+	b		.sys32_sendmsg
+
+_STATIC(do_sys_recvmsg) /* sys32_recvmsg(int, struct msghdr32 *, unsigned int) */
+	mr		r10,r4
+	lwa		r3,0(r10)
+	lwz		r4,4(r10)
+	lwa		r5,8(r10)
+	b		.sys32_recvmsg
+
+_STATIC(do_einval)
+	li	r3,-EINVAL
+	b	.ret_from_syscall_1
+_STATIC(do_efault)
+	li	r3,-EFAULT
+	b	.ret_from_syscall_1
+
+	.data
+	.align	8
+_GLOBAL(socketcall_table_begin)
+	.llong		.do_sys_socket
+	.llong		.do_sys_bind
+	.llong		.do_sys_connect
+	.llong		.do_sys_listen
+	.llong		.do_sys_accept
+	.llong		.do_sys_getsockname
+	.llong		.do_sys_getpeername
+	.llong		.do_sys_socketpair
+	.llong		.do_sys_send
+	.llong		.do_sys_recv
+	.llong		.do_sys_sendto
+	.llong		.do_sys_recvfrom
+	.llong		.do_sys_shutdown
+	.llong		.do_sys_setsockopt
+	.llong		.do_sys_getsockopt
+	.llong		.do_sys_sendmsg
+	.llong		.do_sys_recvmsg
+_GLOBAL(socketcall_table_end)
+	.section	__ex_table,"a"
+	.align		3
+	.llong		.socketcall_table_begin
+	.llong		0
+	.llong		.socketcall_table_end
+	.llong		.do_efault
+	.previous
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/sys_ppc32.c linux/arch/ppc64/kernel/sys_ppc32.c
--- linux.orig/arch/ppc64/kernel/sys_ppc32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/sys_ppc32.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,4806 @@
+/*
+ * sys_ppc32.c: Conversion between 32bit and 64bit native syscalls.
+ *
+ * Copyright (C) 2001 IBM
+ * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+ * environment.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/ptrace.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h> 
+#include <linux/mm.h> 
+#include <linux/file.h> 
+#include <linux/signal.h>
+#include <linux/utime.h>
+#include <linux/resource.h>
+#include <linux/times.h>
+#include <linux/utsname.h>
+#include <linux/timex.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/slab.h>
+#include <linux/uio.h>
+#include <linux/nfs_fs.h>
+#include <linux/smb_fs.h>
+#include <linux/smb_mount.h>
+#include <linux/ncp_fs.h>
+#include <linux/quota.h>
+#include <linux/module.h>
+#include <linux/sunrpc/svc.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfsd/cache.h>
+#include <linux/nfsd/xdr.h>
+#include <linux/nfsd/syscall.h>
+#include <linux/poll.h>
+#include <linux/personality.h>
+#include <linux/stat.h>
+#include <linux/filter.h>
+#include <linux/highmem.h>
+#include <linux/highuid.h>
+#include <linux/mman.h>
+#include <linux/sysctl.h>
+
+#include <asm/types.h>
+#include <asm/ipc.h>
+#include <asm/uaccess.h>
+
+#include <asm/semaphore.h>
+
+#include <net/scm.h>
+#include <linux/elf.h>
+#include <asm/ppcdebug.h>
+#include <asm/time.h>
+#include <asm/ppc32.h>
+
+extern unsigned long wall_jiffies;
+#define USEC_PER_SEC (1000000)
+
+/* 
+ * These are the flags in the MSR that the user is allowed to change
+ * by modifying the saved value of the MSR on the stack.  SE and BE
+ * should not be in this list since gdb may want to change these.  I.e,
+ * you should be able to step out of a signal handler to see what
+ * instruction executes next after the signal handler completes.
+ * Alternately, if you stepped into a signal handler, you should be
+ * able to continue 'til the next breakpoint from within the signal
+ * handler, even if the handler returns.
+ */
+#define MSR_USERCHANGE	(MSR_FE0 | MSR_FE1)
+
+/* In order to reduce some races, while at the same time doing additional
+ * checking and hopefully speeding things up, we copy filenames to the
+ * kernel data space before using them..
+ *
+ * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
+ */
+static inline int do_getname32(const char *filename, char *page)
+{
+	int retval;
+
+	/* 32bit pointer will be always far below TASK_SIZE :)) */
+	retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
+	if (retval > 0) {
+		if (retval < PAGE_SIZE)
+			return 0;
+		return -ENAMETOOLONG;
+	} else if (!retval)
+		retval = -ENOENT;
+	return retval;
+}
+
+char * getname32(const char *filename)
+{
+	char *tmp, *result;
+
+	result = ERR_PTR(-ENOMEM);
+  tmp =  __getname();
+	if (tmp)  {
+		int retval = do_getname32(filename, tmp);
+
+		result = tmp;
+		if (retval < 0) {
+			putname(tmp);
+			result = ERR_PTR(retval);
+		}
+	}
+	return result;
+}
+
+
+
+extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
+
+struct utimbuf32 {
+	__kernel_time_t32 actime, modtime;
+};
+
+asmlinkage long sys32_utime(char * filename, struct utimbuf32 *times)
+{
+	struct utimbuf t;
+	mm_segment_t old_fs;
+	int ret;
+	char *filenam;
+	
+	PPCDBG(PPCDBG_SYS32NI, "sys32_utime - running - filename=%s, times=%p - pid=%ld, comm=%s \n", filename, times, current->pid, current->comm);
+
+	if (!times)
+		return sys_utime(filename, NULL);
+	if (get_user(t.actime, &times->actime) || __get_user(t.modtime, &times->modtime))
+		return -EFAULT;
+	filenam = getname32(filename);
+
+	ret = PTR_ERR(filenam);
+	if (!IS_ERR(filenam)) {
+		old_fs = get_fs();
+		set_fs (KERNEL_DS); 
+		ret = sys_utime(filenam, &t);
+		set_fs (old_fs);
+		putname (filenam);
+	}
+
+	return ret;
+}
+
+
+
+struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
+
+typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
+
+static long do_readv_writev32(int type, struct file *file,
+			      const struct iovec32 *vector, u32 count)
+{
+	unsigned long tot_len;
+	struct iovec iovstack[UIO_FASTIOV];
+	struct iovec *iov=iovstack, *ivp;
+	struct inode *inode;
+	long retval, i;
+	IO_fn_t fn;
+
+	/* First get the "struct iovec" from user memory and
+	 * verify all the pointers
+	 */
+	if (!count)
+		return 0;
+	if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
+		return -EFAULT;
+	if (count > UIO_MAXIOV)
+		return -EINVAL;
+	if (count > UIO_FASTIOV) {
+		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
+		if (!iov)
+			return -ENOMEM;
+	}
+
+	tot_len = 0;
+	i = count;
+	ivp = iov;
+	while(i > 0) {
+		u32 len;
+		u32 buf;
+
+		__get_user(len, &vector->iov_len);
+		__get_user(buf, &vector->iov_base);
+		tot_len += len;
+		ivp->iov_base = (void *)A(buf);
+		ivp->iov_len = (__kernel_size_t) len;
+		vector++;
+		ivp++;
+		i--;
+	}
+
+	inode = file->f_dentry->d_inode;
+	/* VERIFY_WRITE actually means a read, as we write to user space */
+	retval = locks_verify_area((type == VERIFY_WRITE
+				    ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
+				   inode, file, file->f_pos, tot_len);
+	if (retval) {
+		if (iov != iovstack)
+			kfree(iov);
+		return retval;
+	}
+
+	/* Then do the actual IO.  Note that sockets need to be handled
+	 * specially as they have atomicity guarantees and can handle
+	 * iovec's natively
+	 */
+	if (inode->i_sock) {
+		int err;
+		err = sock_readv_writev(type, inode, file, iov, count, tot_len);
+		if (iov != iovstack)
+			kfree(iov);
+		return err;
+	}
+
+	if (!file->f_op) {
+		if (iov != iovstack)
+			kfree(iov);
+		return -EINVAL;
+	}
+	/* VERIFY_WRITE actually means a read, as we write to user space */
+	fn = file->f_op->read;
+	if (type == VERIFY_READ)
+		fn = (IO_fn_t) file->f_op->write;		
+	ivp = iov;
+	while (count > 0) {
+		void * base;
+		int len, nr;
+
+		base = ivp->iov_base;
+		len = ivp->iov_len;
+		ivp++;
+		count--;
+		nr = fn(file, base, len, &file->f_pos);
+		if (nr < 0) {
+			if (retval)
+				break;
+			retval = nr;
+			break;
+		}
+		retval += nr;
+		if (nr != len)
+			break;
+	}
+	if (iov != iovstack)
+		kfree(iov);
+	return retval;
+}
+
+asmlinkage long sys32_readv(u32 fd, struct iovec32 *vector, u32 count)
+{
+	struct file *file;
+	long ret = -EBADF;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_readv - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	file = fget(fd);
+	if(!file)
+		goto bad_file;
+
+	if (file->f_op && (file->f_mode & FMODE_READ) &&
+     (file->f_op->readv || file->f_op->read))
+		ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
+	fput(file);
+
+bad_file:
+	PPCDBG(PPCDBG_SYS32, "sys32_readv - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	return ret;
+}
+
+asmlinkage long sys32_writev(u32 fd, struct iovec32 *vector, u32 count)
+{
+	struct file *file;
+	int ret = -EBADF;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_writev - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	file = fget(fd);
+	if(!file)
+		goto bad_file;
+	if (file->f_op && (file->f_mode & FMODE_WRITE) &&
+	   (file->f_op->writev || file->f_op->write))
+		ret = do_readv_writev32(VERIFY_READ, file, vector, count);
+	fput(file);
+
+bad_file:
+	PPCDBG(PPCDBG_SYS32, "sys32_writev - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	return ret;
+}
+
+
+
+static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
+{
+	int err;
+	
+	err = get_user(kfl->l_type, &ufl->l_type);
+	err |= __get_user(kfl->l_whence, &ufl->l_whence);
+	err |= __get_user(kfl->l_start, &ufl->l_start);
+	err |= __get_user(kfl->l_len, &ufl->l_len);
+	err |= __get_user(kfl->l_pid, &ufl->l_pid);
+	return err;
+}
+
+static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
+{
+	int err;
+	
+	err = __put_user(kfl->l_type, &ufl->l_type);
+	err |= __put_user(kfl->l_whence, &ufl->l_whence);
+	err |= __put_user(kfl->l_start, &ufl->l_start);
+	err |= __put_user(kfl->l_len, &ufl->l_len);
+	err |= __put_user(kfl->l_pid, &ufl->l_pid);
+	return err;
+}
+
+extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
+asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case F_GETLK:
+	case F_SETLK:
+	case F_SETLKW:
+	{
+		struct flock f;
+		mm_segment_t old_fs;
+		long ret;
+
+		if(get_flock(&f, (struct flock32 *)arg))
+			return -EFAULT;
+		old_fs = get_fs(); set_fs (KERNEL_DS);
+		ret = sys_fcntl(fd, cmd, (unsigned long)&f);
+		set_fs (old_fs);
+		if(put_flock(&f, (struct flock32 *)arg))
+			return -EFAULT;
+		return ret;
+	}
+	default:
+		return sys_fcntl(fd, cmd, (unsigned long)arg);
+	}
+}
+
+struct ncp_mount_data32 {
+        int version;
+        unsigned int ncp_fd;
+        __kernel_uid_t32 mounted_uid;
+        __kernel_pid_t32 wdog_pid;
+        unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
+        unsigned int time_out;
+        unsigned int retry_count;
+        unsigned int flags;
+        __kernel_uid_t32 uid;
+        __kernel_gid_t32 gid;
+        __kernel_mode_t32 file_mode;
+        __kernel_mode_t32 dir_mode;
+};
+
+static void *do_ncp_super_data_conv(void *raw_data)
+{
+	struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
+	struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
+
+	n->dir_mode = n32->dir_mode;
+	n->file_mode = n32->file_mode;
+	n->gid = n32->gid;
+	n->uid = n32->uid;
+	memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
+	n->wdog_pid = n32->wdog_pid;
+	n->mounted_uid = n32->mounted_uid;
+	return raw_data;
+}
+
+struct smb_mount_data32 {
+        int version;
+        __kernel_uid_t32 mounted_uid;
+        __kernel_uid_t32 uid;
+        __kernel_gid_t32 gid;
+        __kernel_mode_t32 file_mode;
+        __kernel_mode_t32 dir_mode;
+};
+
+static void *do_smb_super_data_conv(void *raw_data)
+{
+	struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
+	struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
+
+	s->version = s32->version;
+	s->mounted_uid = s32->mounted_uid;
+	s->uid = s32->uid;
+	s->gid = s32->gid;
+	s->file_mode = s32->file_mode;
+	s->dir_mode = s32->dir_mode;
+	return raw_data;
+}
+
+static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
+{
+	int i;
+	unsigned long page;
+	struct vm_area_struct *vma;
+
+	*kernel = 0;
+	if(!user)
+		return 0;
+	vma = find_vma(current->mm, (unsigned long)user);
+	if(!vma || (unsigned long)user < vma->vm_start)
+		return -EFAULT;
+	if(!(vma->vm_flags & VM_READ))
+		return -EFAULT;
+	i = vma->vm_end - (unsigned long) user;
+	if(PAGE_SIZE <= (unsigned long) i)
+		i = PAGE_SIZE - 1;
+	if(!(page = __get_free_page(GFP_KERNEL)))
+		return -ENOMEM;
+	if(copy_from_user((void *) page, user, i)) {
+		free_page(page);
+		return -EFAULT;
+	}
+	*kernel = page;
+	return 0;
+}
+
+#define SMBFS_NAME	"smbfs"
+#define NCPFS_NAME	"ncpfs"
+
+asmlinkage long sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
+{
+	unsigned long type_page = 0;
+	unsigned long data_page = 0;
+	unsigned long dev_page = 0;
+	unsigned long dir_page = 0;
+	int err, is_smb, is_ncp;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_mount - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	is_smb = is_ncp = 0;
+
+	err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
+	if (err)
+		goto out;
+
+	if (!type_page) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	is_smb = !strcmp((char *)type_page, SMBFS_NAME);
+	is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
+
+	err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
+	if (err)
+		goto type_out;
+
+	err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
+	if (err)
+		goto data_out;
+
+	err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
+	if (err)
+		goto dev_out;
+
+	if (!is_smb && !is_ncp) {
+		lock_kernel();
+		err = do_mount((char*)dev_page, (char*)dir_page,
+				(char*)type_page, new_flags, (char*)data_page);
+		unlock_kernel();
+	} else {
+		if (is_ncp)
+			do_ncp_super_data_conv((void *)data_page);
+		else
+			do_smb_super_data_conv((void *)data_page);
+
+		lock_kernel();
+		err = do_mount((char*)dev_page, (char*)dir_page,
+				(char*)type_page, new_flags, (char*)data_page);
+		unlock_kernel();
+	}
+	free_page(dir_page);
+
+dev_out:
+	free_page(dev_page);
+
+data_out:
+	free_page(data_page);
+
+type_out:
+	free_page(type_page);
+
+out:
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_mount - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return err;
+}
+
+struct dqblk32 {
+    __u32 dqb_bhardlimit;
+    __u32 dqb_bsoftlimit;
+    __u32 dqb_curblocks;
+    __u32 dqb_ihardlimit;
+    __u32 dqb_isoftlimit;
+    __u32 dqb_curinodes;
+    __kernel_time_t32 dqb_btime;
+    __kernel_time_t32 dqb_itime;
+};
+                                
+
+extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
+
+/* Note: it is necessary to treat cmd and id as unsigned ints, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, unsigned long addr)
+{
+  int cmd = (int)cmd_parm;
+  int id  = (int)id_parm;
+	int cmds = cmd >> SUBCMDSHIFT;
+	int err;
+	struct dqblk d;
+	mm_segment_t old_fs;
+	char *spec;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_quotactl - entered - pid=%ld current=%lx comm=%s \n",
+		    current->pid, current, current->comm);
+
+	switch (cmds) {
+	case Q_GETQUOTA:
+		break;
+	case Q_SETQUOTA:
+	case Q_SETUSE:
+	case Q_SETQLIM:
+		if (copy_from_user (&d, (struct dqblk32 *)addr,
+				    sizeof (struct dqblk32)))
+			return -EFAULT;
+		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
+		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
+		break;
+	default:
+		return sys_quotactl(cmd, special,
+				    id, (caddr_t)addr);
+	}
+	spec = getname32 (special);
+	err = PTR_ERR(spec);
+	if (IS_ERR(spec)) return err;
+	old_fs = get_fs ();
+	set_fs (KERNEL_DS);
+	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
+	set_fs (old_fs);
+	putname (spec);
+	if (cmds == Q_GETQUOTA) {
+		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
+		((struct dqblk32 *)&d)->dqb_itime = i;
+		((struct dqblk32 *)&d)->dqb_btime = b;
+		if (copy_to_user ((struct dqblk32 *)addr, &d,
+				  sizeof (struct dqblk32)))
+			return -EFAULT;
+	}
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_quotactl - exited - pid=%ld current=%lx comm=%s \n",
+		    current->pid, current, current->comm);
+
+	return err;
+}
+
+
+
+/* readdir & getdents */
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
+#define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
+
+struct old_linux_dirent32 {
+	u32		d_ino;
+	u32		d_offset;
+	unsigned short	d_namlen;
+  /* unsigned char	d_type; */
+	char		d_name[1];
+};
+
+struct readdir_callback32 {
+	struct old_linux_dirent32 * dirent;
+	int count;
+};
+
+static int fillonedir(void * __buf, const char * name, int namlen,
+		                  off_t offset, ino_t ino, unsigned int d_type)
+{
+	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
+	struct old_linux_dirent32 * dirent;
+
+	if (buf->count)
+		return -EINVAL;
+	buf->count++;
+	dirent = buf->dirent;
+	put_user(ino, &dirent->d_ino);
+	put_user(offset, &dirent->d_offset);
+	put_user(namlen, &dirent->d_namlen);
+	copy_to_user(dirent->d_name, name, namlen);
+	put_user(0, dirent->d_name + namlen);
+	return 0;
+}
+
+asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
+{
+	int error = -EBADF;
+	struct file * file;
+	struct readdir_callback32 buf;
+
+	file = fget(fd);
+	if (!file)
+		goto out;
+
+	buf.count = 0;
+	buf.dirent = dirent;
+
+	error = vfs_readdir(file, (filldir_t)fillonedir, &buf);
+	if (error < 0)
+		goto out_putf;
+	error = buf.count;
+
+out_putf:
+	fput(file);
+out:
+	return error;
+}
+
+#if 0
+struct linux_dirent32 {
+	u32		d_ino;
+	u32		d_off;
+	unsigned short	d_reclen;
+	char		d_name[1];
+};
+#else
+struct linux_dirent32 {
+	u32		d_ino;
+	u32		d_off;
+	unsigned short	d_reclen;
+  /* unsigned char	d_type; */
+	char		d_name[256];
+};
+#endif
+
+struct getdents_callback32 {
+	struct linux_dirent32 * current_dir;
+	struct linux_dirent32 * previous;
+	int count;
+	int error;
+};
+
+static int
+filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino,
+		               unsigned int d_type)
+{
+	struct linux_dirent32 * dirent;
+	struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
+	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+
+	buf->error = -EINVAL;	/* only used if we fail.. */
+	if (reclen > buf->count)
+		return -EINVAL;
+	dirent = buf->previous;
+	if (dirent)
+		put_user(offset, &dirent->d_off);
+	dirent = buf->current_dir;
+	buf->previous = dirent;
+	put_user(ino, &dirent->d_ino);
+	put_user(reclen, &dirent->d_reclen);
+	/* put_user(d_type, &dirent->d_type); */
+	copy_to_user(dirent->d_name, name, namlen);
+	put_user(0, dirent->d_name + namlen);
+	((char *) dirent) += reclen;
+	buf->current_dir = dirent;
+	buf->count -= reclen;
+	return 0;
+}
+
+asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
+{
+	struct file * file;
+	struct linux_dirent32 * lastdirent;
+	struct getdents_callback32 buf;
+	int error = -EBADF;
+
+	PPCDBG(PPCDBG_SYS32NI, "sys32_getdents - running - fd=%x, pid=%ld, comm=%s \n", fd, current->pid, current->comm);
+
+	file = fget(fd);
+	if (!file)
+		goto out;
+
+	buf.current_dir = dirent;
+	buf.previous = NULL;
+	buf.count = count;
+	buf.error = 0;
+
+	error = vfs_readdir(file, (filldir_t)filldir, &buf);
+	if (error < 0)
+		goto out_putf;
+	lastdirent = buf.previous;
+	error = buf.error;
+	if(lastdirent) {
+		put_user(file->f_pos, &lastdirent->d_off);
+		error = count - buf.count;
+	}
+ out_putf:
+	fput(file);
+
+ out:
+	return error;
+}
+/* end of readdir & getdents */
+
+
+
+/* 32-bit timeval and related flotsam.  */
+
+struct timeval32
+{
+	int tv_sec, tv_usec;
+};
+
+struct itimerval32
+{
+	struct timeval32 it_interval;
+	struct timeval32 it_value;
+};
+
+
+
+
+/*
+ * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
+ * 64-bit unsigned longs.
+ */
+static inline int
+get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
+{
+	if (ufdset) {
+		unsigned long odd;
+
+		if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
+			return -EFAULT;
+
+		odd = n & 1UL;
+		n &= ~1UL;
+		while (n) {
+			unsigned long h, l;
+			__get_user(l, ufdset);
+			__get_user(h, ufdset+1);
+			ufdset += 2;
+			*fdset++ = h << 32 | l;
+			n -= 2;
+		}
+		if (odd)
+			__get_user(*fdset, ufdset);
+	} else {
+		/* Tricky, must clear full unsigned long in the
+		 * kernel fdset at the end, this makes sure that
+		 * actually happens.
+		 */
+		memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
+	}
+	return 0;
+}
+
+static inline void
+set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
+{
+	unsigned long odd;
+
+	if (!ufdset)
+		return;
+
+	odd = n & 1UL;
+	n &= ~1UL;
+	while (n) {
+		unsigned long h, l;
+		l = *fdset++;
+		h = l >> 32;
+		__put_user(l, ufdset);
+		__put_user(h, ufdset+1);
+		ufdset += 2;
+		n -= 2;
+	}
+	if (odd)
+		__put_user(*fdset, ufdset);
+}
+
+
+
+#define MAX_SELECT_SECONDS ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
+
+asmlinkage long sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
+{
+	fd_set_bits fds;
+	struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
+	char *bits;
+	unsigned long nn;
+	long timeout;
+	int ret, size;
+	
+  PPCDBG(PPCDBG_SYS32X, "sys32_select - entered - n=%x, inp=%p, outp=%p - pid=%ld comm=%s \n", n, inp, outp, current->pid, current->comm);
+
+	timeout = MAX_SCHEDULE_TIMEOUT;
+	if (tvp) {
+		time_t sec, usec;
+		if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
+		    || (ret = __get_user(sec, &tvp->tv_sec))
+		    || (ret = __get_user(usec, &tvp->tv_usec)))
+			goto out_nofds;
+
+		ret = -EINVAL;
+		if(sec < 0 || usec < 0)
+			goto out_nofds;
+
+		if ((unsigned long) sec < MAX_SELECT_SECONDS) {
+			timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
+			timeout += sec * (unsigned long) HZ;
+		}
+	}
+
+	ret = -EINVAL;
+	if (n < 0)
+		goto out_nofds;
+	if (n > current->files->max_fdset)
+		n = current->files->max_fdset;
+
+	/*
+	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
+	 * since we used fdset we need to allocate memory in units of
+	 * long-words. 
+	 */
+	ret = -ENOMEM;
+	size = FDS_BYTES(n);
+	bits = kmalloc(6 * size, GFP_KERNEL);
+	if (!bits)
+		goto out_nofds;
+	fds.in      = (unsigned long *)  bits;
+	fds.out     = (unsigned long *) (bits +   size);
+	fds.ex      = (unsigned long *) (bits + 2*size);
+	fds.res_in  = (unsigned long *) (bits + 3*size);
+	fds.res_out = (unsigned long *) (bits + 4*size);
+	fds.res_ex  = (unsigned long *) (bits + 5*size);
+
+	nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
+	if ((ret = get_fd_set32(nn, fds.in, inp)) ||
+	    (ret = get_fd_set32(nn, fds.out, outp)) ||
+	    (ret = get_fd_set32(nn, fds.ex, exp)))
+		goto out;
+	zero_fd_set(n, fds.res_in);
+	zero_fd_set(n, fds.res_out);
+	zero_fd_set(n, fds.res_ex);
+
+	ret = do_select(n, &fds, &timeout);
+
+	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
+		time_t sec = 0, usec = 0;
+		if (timeout) {
+			sec = timeout / HZ;
+			usec = timeout % HZ;
+			usec *= (1000000/HZ);
+		}
+		put_user(sec, &tvp->tv_sec);
+		put_user(usec, &tvp->tv_usec);
+	}
+
+  if (ret < 0)
+		goto out;
+	if (!ret) {
+		ret = -ERESTARTNOHAND;
+		if (signal_pending(current))
+			goto out;
+		ret = 0;
+	}
+
+	set_fd_set32(nn, inp, fds.res_in);
+	set_fd_set32(nn, outp, fds.res_out);
+	set_fd_set32(nn, exp, fds.res_ex);
+  
+out:
+	kfree(bits);
+
+out_nofds:
+	PPCDBG(PPCDBG_SYS32X, "sys32_select - exited - pid=%ld, comm=%s \n", current->pid, current->comm);
+	return ret;
+}
+
+
+
+
+/*
+ * Due to some executables calling the wrong select we sometimes
+ * get wrong args.  This determines how the args are being passed
+ * (a single ptr to them all args passed) then calls
+ * sys_select() with the appropriate args. -- Cort
+ */
+/* Note: it is necessary to treat n as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage int ppc32_select(u32 n, u32* inp, u32* outp, u32* exp, u32 tvp_x)
+{
+	if ((unsigned int)n >= 4096)
+		panic("ppc32_select - wrong arguments were passed in \n");
+
+	return sys32_select((int)n, inp, outp, exp, tvp_x);
+}
+
+
+
+static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
+{
+	unsigned long ino, blksize, blocks;
+	kdev_t dev, rdev;
+	umode_t mode;
+	nlink_t nlink;
+	uid_t uid;
+	gid_t gid;
+	off_t size;
+	time_t atime, mtime, ctime;
+	int err;
+
+	/* Stream the loads of inode data into the load buffer,
+	 * then we push it all into the store buffer below.  This
+	 * should give optimal cache performance.
+	 */
+	ino = inode->i_ino;
+	dev = inode->i_dev;
+	mode = inode->i_mode;
+	nlink = inode->i_nlink;
+	uid = inode->i_uid;
+	gid = inode->i_gid;
+	rdev = inode->i_rdev;
+	size = inode->i_size;
+	atime = inode->i_atime;
+	mtime = inode->i_mtime;
+	ctime = inode->i_ctime;
+	blksize = inode->i_blksize;
+	blocks = inode->i_blocks;
+
+	err  = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
+	err |= put_user(ino, &statbuf->st_ino);
+	err |= put_user(mode, &statbuf->st_mode);
+	err |= put_user(nlink, &statbuf->st_nlink);
+	err |= put_user(uid, &statbuf->st_uid);
+	err |= put_user(gid, &statbuf->st_gid);
+	err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
+	err |= put_user(size, &statbuf->st_size);
+	err |= put_user(atime, &statbuf->st_atime);
+	err |= put_user(0, &statbuf->__unused1);
+	err |= put_user(mtime, &statbuf->st_mtime);
+	err |= put_user(0, &statbuf->__unused2);
+	err |= put_user(ctime, &statbuf->st_ctime);
+	err |= put_user(0, &statbuf->__unused3);
+	if (blksize) {
+		err |= put_user(blksize, &statbuf->st_blksize);
+		err |= put_user(blocks, &statbuf->st_blocks);
+	} else {
+		unsigned int tmp_blocks;
+
+#define D_B   7
+#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
+		tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
+		if (tmp_blocks > D_B) {
+			unsigned int indirect;
+
+			indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
+			tmp_blocks += indirect;
+			if (indirect > 1) {
+				indirect = (indirect - 1 + I_B - 1) / I_B;
+				tmp_blocks += indirect;
+				if (indirect > 1)
+					tmp_blocks++;
+			}
+		}
+		err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
+		err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
+#undef D_B
+#undef I_B
+	}
+	err |= put_user(0, &statbuf->__unused4[0]);
+	err |= put_user(0, &statbuf->__unused4[1]);
+
+	return err;
+}
+
+static __inline__ int
+do_revalidate(struct dentry *dentry)
+{
+	struct inode * inode = dentry->d_inode;
+	if (inode->i_op && inode->i_op->revalidate)
+		return inode->i_op->revalidate(dentry);
+	return 0;
+}
+
+asmlinkage long sys32_newstat(char* filename, struct stat32* statbuf)
+{
+	struct nameidata nd;
+	int error;
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_newstat - running - filename=%s, statbuf=%p, pid=%ld, comm=%s\n", filename, statbuf, current->pid, current->comm);
+
+	error = user_path_walk(filename, &nd);
+	if (!error) {
+		error = do_revalidate(nd.dentry);
+		if (!error)
+			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
+		path_release(&nd);
+	}
+	return error;
+}
+
+asmlinkage long sys32_newlstat(char * filename, struct stat32 *statbuf)
+{
+	struct nameidata nd;
+	int error;
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_newlstat - running - fn=%s, pid=%ld, comm=%s\n", filename, current->pid, current->comm);
+
+	error = user_path_walk_link(filename, &nd);
+	if (!error) {
+		error = do_revalidate(nd.dentry);
+		if (!error)
+			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
+
+		path_release(&nd);
+	}
+	return error;
+}
+
+asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
+{
+	struct file *f;
+	int err = -EBADF;
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_newfstat - running - fd=%x, pid=%ld, comm=%s\n", fd, current->pid, current->comm);
+
+	f = fget(fd);
+	if (f) {
+		struct dentry * dentry = f->f_dentry;
+
+		err = do_revalidate(dentry);
+		if (!err)
+			err = cp_new_stat32(dentry->d_inode, statbuf);
+		fput(f);
+	}
+	return err;
+}
+
+static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
+{
+	int err;
+	
+	err = put_user (kbuf->f_type, &ubuf->f_type);
+	err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
+	err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
+	err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
+	err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
+	err |= __put_user (kbuf->f_files, &ubuf->f_files);
+	err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
+	err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
+	err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
+	err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
+	return err;
+}
+
+extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
+
+asmlinkage long sys32_statfs(const char * path, struct statfs32 *buf)
+{
+	int ret;
+	struct statfs s;
+	mm_segment_t old_fs = get_fs();
+	char *pth;
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_statfs - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+	
+	pth = getname32 (path);
+	ret = PTR_ERR(pth);
+	if (!IS_ERR(pth)) {
+		set_fs (KERNEL_DS);
+		ret = sys_statfs((const char *)pth, &s);
+		set_fs (old_fs);
+		putname (pth);
+		if (put_statfs(buf, &s))
+			return -EFAULT;
+	}
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_statfs - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return ret;
+}
+
+extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
+
+asmlinkage long sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
+{
+	int ret;
+	struct statfs s;
+	mm_segment_t old_fs = get_fs();
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_fstatfs - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+	
+	set_fs (KERNEL_DS);
+	ret = sys_fstatfs(fd, &s);
+	set_fs (old_fs);
+	if (put_statfs(buf, &s))
+		return -EFAULT;
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_fstatfs - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return ret;
+}
+
+
+
+extern asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
+
+/* Note: it is necessary to treat option as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sysfs(u32 option, u32 arg1, u32 arg2)
+{
+	PPCDBG(PPCDBG_SYS32, "sys32_sysfs - running - pid=%ld, comm=%s\n", current->pid, current->comm);
+	return sys_sysfs((int)option, arg1, arg2);
+}
+
+
+
+
+extern unsigned long do_mremap(unsigned long addr,
+	unsigned long old_len, unsigned long new_len,
+	unsigned long flags, unsigned long new_addr);
+                
+asmlinkage unsigned long sys32_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len,
+                                    	unsigned long flags, u32 __new_addr)
+{
+	unsigned long ret = -EINVAL;
+	unsigned long new_addr = AA(__new_addr);
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_mremap - entered - pid=%ld current=%lx comm=%s\n",
+		    current->pid, current, current->comm);
+
+
+	if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
+		goto out;
+	if (addr > 0xf0000000UL - old_len)
+		goto out;
+	down_write(&current->mm->mmap_sem);
+	if (flags & MREMAP_FIXED) {
+		if (new_addr > 0xf0000000UL - new_len)
+			goto out_sem;
+	} else if (addr > 0xf0000000UL - new_len) {
+		ret = -ENOMEM;
+		if (!(flags & MREMAP_MAYMOVE))
+			goto out_sem;
+		new_addr = get_unmapped_area (NULL, addr, new_len, 0, 0);
+		if (!new_addr)
+			goto out_sem;
+		flags |= MREMAP_FIXED;
+	}
+	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+out_sem:
+	up_write(&current->mm->mmap_sem);
+out:
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_mremap - exited - pid=%ld current=%lx comm=%s\n",
+		    current->pid, current, current->comm);
+
+	return ret;       
+}
+
+
+
+/* Handle adjtimex compatability. */
+struct timex32 {
+	u32 modes;
+	s32 offset, freq, maxerror, esterror;
+	s32 status, constant, precision, tolerance;
+	struct timeval32 time;
+	s32 tick;
+	s32 ppsfreq, jitter, shift, stabil;
+	s32 jitcnt, calcnt, errcnt, stbcnt;
+	s32  :32; s32  :32; s32  :32; s32  :32;
+	s32  :32; s32  :32; s32  :32; s32  :32;
+	s32  :32; s32  :32; s32  :32; s32  :32;
+};
+
+extern int do_adjtimex(struct timex *);
+extern void ppc_adjtimex(void);
+
+asmlinkage long sys32_adjtimex(struct timex32 *utp)
+{
+	struct timex txc;
+	int ret;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_adjtimex - running - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	memset(&txc, 0, sizeof(struct timex));
+
+	if(get_user(txc.modes, &utp->modes) ||
+	   __get_user(txc.offset, &utp->offset) ||
+	   __get_user(txc.freq, &utp->freq) ||
+	   __get_user(txc.maxerror, &utp->maxerror) ||
+	   __get_user(txc.esterror, &utp->esterror) ||
+	   __get_user(txc.status, &utp->status) ||
+	   __get_user(txc.constant, &utp->constant) ||
+	   __get_user(txc.precision, &utp->precision) ||
+	   __get_user(txc.tolerance, &utp->tolerance) ||
+	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
+	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
+	   __get_user(txc.tick, &utp->tick) ||
+	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||
+	   __get_user(txc.jitter, &utp->jitter) ||
+	   __get_user(txc.shift, &utp->shift) ||
+	   __get_user(txc.stabil, &utp->stabil) ||
+	   __get_user(txc.jitcnt, &utp->jitcnt) ||
+	   __get_user(txc.calcnt, &utp->calcnt) ||
+	   __get_user(txc.errcnt, &utp->errcnt) ||
+	   __get_user(txc.stbcnt, &utp->stbcnt))
+		return -EFAULT;
+
+	ret = do_adjtimex(&txc);
+
+	/* adjust the conversion of TB to time of day to track adjtimex */
+	ppc_adjtimex();
+
+	if(put_user(txc.modes, &utp->modes) ||
+	   __put_user(txc.offset, &utp->offset) ||
+	   __put_user(txc.freq, &utp->freq) ||
+	   __put_user(txc.maxerror, &utp->maxerror) ||
+	   __put_user(txc.esterror, &utp->esterror) ||
+	   __put_user(txc.status, &utp->status) ||
+	   __put_user(txc.constant, &utp->constant) ||
+	   __put_user(txc.precision, &utp->precision) ||
+	   __put_user(txc.tolerance, &utp->tolerance) ||
+	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
+	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
+	   __put_user(txc.tick, &utp->tick) ||
+	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||
+	   __put_user(txc.jitter, &utp->jitter) ||
+	   __put_user(txc.shift, &utp->shift) ||
+	   __put_user(txc.stabil, &utp->stabil) ||
+	   __put_user(txc.jitcnt, &utp->jitcnt) ||
+	   __put_user(txc.calcnt, &utp->calcnt) ||
+	   __put_user(txc.errcnt, &utp->errcnt) ||
+	   __put_user(txc.stbcnt, &utp->stbcnt))
+		ret = -EFAULT;
+
+	return ret;
+}
+
+
+
+#ifdef CONFIG_MODULES
+
+extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
+
+asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
+{
+	
+	PPCDBG(PPCDBG_SYS32M, "sys32_create_module - running - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return sys_create_module(name_user, (size_t)size);
+}
+
+
+
+extern asmlinkage long sys_init_module(const char *name_user, struct module *mod_user);
+
+asmlinkage long sys32_init_module(const char *name_user, struct module *mod_user)
+{
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_init_module - running - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return sys_init_module(name_user, mod_user);
+}
+
+
+
+extern asmlinkage long sys_delete_module(const char *name_user);
+
+asmlinkage long sys32_delete_module(const char *name_user)
+{
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_delete_module - running - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return sys_delete_module(name_user);
+}
+
+
+
+struct module_info32 {
+	u32 addr;
+	u32 size;
+	u32 flags;
+	s32 usecount;
+};
+
+/* Query various bits about modules.  */
+
+static inline long
+get_mod_name(const char *user_name, char **buf)
+{
+	unsigned long page;
+	long retval;
+
+	if ((unsigned long)user_name >= TASK_SIZE
+	    && !segment_eq(get_fs (), KERNEL_DS))
+		return -EFAULT;
+
+	page = __get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
+	if (retval > 0) {
+		if (retval < PAGE_SIZE) {
+			*buf = (char *)page;
+			return retval;
+		}
+		retval = -ENAMETOOLONG;
+	} else if (!retval)
+		retval = -EINVAL;
+
+	free_page(page);
+	return retval;
+}
+
+static inline void
+put_mod_name(char *buf)
+{
+	free_page((unsigned long)buf);
+}
+
+static __inline__ struct module *find_module(const char *name)
+{
+	struct module *mod;
+
+	for (mod = module_list; mod ; mod = mod->next) {
+		if (mod->flags & MOD_DELETED)
+			continue;
+		if (!strcmp(mod->name, name))
+			break;
+	}
+
+	return mod;
+}
+
+static int
+qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	struct module *mod;
+	size_t nmod, space, len;
+
+	nmod = space = 0;
+
+	for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
+		len = strlen(mod->name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, mod->name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(nmod, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	space += len;
+	while ((mod = mod->next)->next != NULL)
+		space += strlen(mod->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static int
+qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t i, space, len;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+	if (!MOD_CAN_QUERY(mod))
+		return put_user(0, ret);
+
+	space = 0;
+	for (i = 0; i < mod->ndeps; ++i) {
+		const char *dep_name = mod->deps[i].dep->name;
+
+		len = strlen(dep_name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, dep_name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	return put_user(i, ret);
+
+calc_space_needed:
+	space += len;
+	while (++i < mod->ndeps)
+		space += strlen(mod->deps[i].dep->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static int
+qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t nrefs, space, len;
+	struct module_ref *ref;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+	if (!MOD_CAN_QUERY(mod))
+		if (put_user(0, ret))
+			return -EFAULT;
+		else
+			return 0;
+
+	space = 0;
+	for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
+		const char *ref_name = ref->ref->name;
+
+		len = strlen(ref_name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, ref_name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(nrefs, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	space += len;
+	while ((ref = ref->next_ref) != NULL)
+		space += strlen(ref->ref->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static inline int
+qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t i, space, len;
+	struct module_symbol *s;
+	char *strings;
+	unsigned *vals;
+
+	if (!MOD_CAN_QUERY(mod))
+		if (put_user(0, ret))
+			return -EFAULT;
+		else
+			return 0;
+
+	space = mod->nsyms * 2*sizeof(u32);
+
+	i = len = 0;
+	s = mod->syms;
+
+	if (space > bufsize)
+		goto calc_space_needed;
+
+	if (!access_ok(VERIFY_WRITE, buf, space))
+		return -EFAULT;
+
+	bufsize -= space;
+	vals = (unsigned *)buf;
+	strings = buf+space;
+
+	for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
+		len = strlen(s->name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+
+		if (copy_to_user(strings, s->name, len)
+		    || __put_user(s->value, vals+0)
+		    || __put_user(space, vals+1))
+			return -EFAULT;
+
+		strings += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(i, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	for (; i < mod->nsyms; ++i, ++s)
+		space += strlen(s->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static inline int
+qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	int error = 0;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+
+	if (sizeof(struct module_info32) <= bufsize) {
+		struct module_info32 info;
+		info.addr = (unsigned long)mod;
+		info.size = mod->size;
+		info.flags = mod->flags;
+		info.usecount =
+			((mod_member_present(mod, can_unload)
+			  && mod->can_unload)
+			 ? -1 : atomic_read(&mod->uc.usecount));
+
+		if (copy_to_user(buf, &info, sizeof(struct module_info32)))
+			return -EFAULT;
+	} else
+		error = -ENOSPC;
+
+	if (put_user(sizeof(struct module_info32), ret))
+		return -EFAULT;
+
+	return error;
+}
+
+/* Note: it is necessary to treat which as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_query_module(char *name_user, u32 which, char *buf, __kernel_size_t32 bufsize, u32 ret)
+{
+	struct module *mod;
+	int err;
+	
+	PPCDBG(PPCDBG_SYS32M, "sys32_query_module - entered - pid=%ld current=%lx comm=%s\n",
+		    current->pid, current, current->comm);
+
+	lock_kernel();
+	if (name_user == 0) {
+		/* This finds "kernel_module" which is not exported. */
+		for(mod = module_list; mod->next != NULL; mod = mod->next)
+			;
+	} else {
+		long namelen;
+		char *name;
+
+		if ((namelen = get_mod_name(name_user, &name)) < 0) {
+			err = namelen;
+			goto out;
+		}
+		err = -ENOENT;
+		if (namelen == 0) {
+			/* This finds "kernel_module" which is not exported. */
+			for(mod = module_list; mod->next != NULL; mod = mod->next)
+				;
+		} else if ((mod = find_module(name)) == NULL) {
+			put_mod_name(name);
+			goto out;
+		}
+		put_mod_name(name);
+	}
+
+	switch ((int)which)
+	{
+	case 0:
+		err = 0;
+		break;
+	case QM_MODULES:
+		err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_DEPS:
+		err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_REFS:
+		err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_SYMBOLS:
+		err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_INFO:
+		err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+out:
+	unlock_kernel();
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_query_module - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return err;
+}
+
+
+
+struct kernel_sym32 {
+	u32 value;
+	char name[60];
+};
+		 
+extern asmlinkage long sys_get_kernel_syms(struct kernel_sym *table);
+
+asmlinkage long sys32_get_kernel_syms(struct kernel_sym32 *table)
+{
+	int len, i;
+	struct kernel_sym *tbl;
+	mm_segment_t old_fs;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_get_kernel_syms - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	
+	len = sys_get_kernel_syms(NULL);
+	if (!table) return len;
+	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
+	if (!tbl) return -ENOMEM;
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	sys_get_kernel_syms(tbl);
+	set_fs (old_fs);
+	for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
+		if (put_user (tbl[i].value, &table->value) ||
+		    copy_to_user (table->name, tbl[i].name, 60))
+			break;
+	}
+	kfree (tbl);
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_get_kernel_syms - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return i;
+}
+
+#else /* CONFIG_MODULES */
+
+asmlinkage unsigned long sys32_create_module(const char *name_user, size_t size)
+{
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_create_module - running - pid=%ld, comm=%s\n", current->pid, current->comm);
+
+	return -ENOSYS;
+}
+
+asmlinkage long sys32_init_module(const char *name_user, struct module *mod_user)
+{
+	PPCDBG(PPCDBG_SYS32, "sys32_init_module - running - pid=%ld, comm=%s\n", current->pid, current->comm);
+
+	return -ENOSYS;
+}
+
+asmlinkage long sys32_delete_module(const char *name_user)
+{
+	PPCDBG(PPCDBG_SYS32, "sys32_delete_module - running - pid=%ld, comm=%s\n", current->pid, current->comm);
+
+	return -ENOSYS;
+}
+
+/* Note: it is necessary to treat which as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_query_module(const char *name_user, u32 which, char *buf, size_t bufsize, size_t *ret)
+{
+	PPCDBG(PPCDBG_SYS32, "sys32_query_module - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	/* Let the program know about the new interface.  Not that it'll do them much good. */
+	if ((int)which == 0)
+		return 0;
+
+	PPCDBG(PPCDBG_SYS32, "sys32_query_module - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+	return -ENOSYS;
+}
+
+asmlinkage long sys32_get_kernel_syms(struct kernel_sym *table)
+{
+	PPCDBG(PPCDBG_SYS32, "sys32_get_kernel_syms - running - pid=%ld, comm=%s\n", current->pid, current->comm);
+
+	return -ENOSYS;
+}
+
+#endif  /* CONFIG_MODULES */
+
+
+
+/* Stuff for NFS server syscalls... */
+struct nfsctl_svc32 {
+	u16			svc32_port;
+	s32			svc32_nthreads;
+};
+
+struct nfsctl_client32 {
+	s8			cl32_ident[NFSCLNT_IDMAX+1];
+	s32			cl32_naddr;
+	struct in_addr		cl32_addrlist[NFSCLNT_ADDRMAX];
+	s32			cl32_fhkeytype;
+	s32			cl32_fhkeylen;
+	u8			cl32_fhkey[NFSCLNT_KEYMAX];
+};
+
+struct nfsctl_export32 {
+	s8			ex32_client[NFSCLNT_IDMAX+1];
+	s8			ex32_path[NFS_MAXPATHLEN+1];
+	__kernel_dev_t32	ex32_dev;
+	__kernel_ino_t32	ex32_ino;
+	s32			ex32_flags;
+	__kernel_uid_t32	ex32_anon_uid;
+	__kernel_gid_t32	ex32_anon_gid;
+};
+
+struct nfsctl_uidmap32 {
+	u32			ug32_ident;   /* char * */
+	__kernel_uid_t32	ug32_uidbase;
+	s32			ug32_uidlen;
+	u32			ug32_udimap;  /* uid_t * */
+	__kernel_uid_t32	ug32_gidbase;
+	s32			ug32_gidlen;
+	u32			ug32_gdimap;  /* gid_t * */
+};
+
+struct nfsctl_fhparm32 {
+	struct sockaddr		gf32_addr;
+	__kernel_dev_t32	gf32_dev;
+	__kernel_ino_t32	gf32_ino;
+	s32			gf32_version;
+};
+
+struct nfsctl_fdparm32 {
+	struct sockaddr		gd32_addr;
+	s8			gd32_path[NFS_MAXPATHLEN+1];
+	s32			gd32_version;
+};
+
+struct nfsctl_fsparm32 {
+	struct sockaddr		gd32_addr;
+	s8			gd32_path[NFS_MAXPATHLEN+1];
+	s32			gd32_maxlen;
+};
+
+struct nfsctl_arg32 {
+	s32			ca32_version;	/* safeguard */
+	union {
+		struct nfsctl_svc32	u32_svc;
+		struct nfsctl_client32	u32_client;
+		struct nfsctl_export32	u32_export;
+		struct nfsctl_uidmap32	u32_umap;
+		struct nfsctl_fhparm32	u32_getfh;
+		struct nfsctl_fdparm32	u32_getfd;
+		struct nfsctl_fsparm32	u32_getfs;
+	} u;
+#define ca32_svc	u.u32_svc
+#define ca32_client	u.u32_client
+#define ca32_export	u.u32_export
+#define ca32_umap	u.u32_umap
+#define ca32_getfh	u.u32_getfh
+#define ca32_getfd	u.u32_getfd
+#define ca32_getfs	u.u32_getfs
+#define ca32_authd	u.u32_authd
+};
+
+union nfsctl_res32 {
+	__u8			cr32_getfh[NFS_FHSIZE];
+	struct knfsd_fh		cr32_getfs;
+};
+
+static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+	int err;
+	
+	err = __get_user(karg->ca_version, &arg32->ca32_version);
+	err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
+	err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
+	return err;
+}
+
+static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+	int err;
+	
+	err = __get_user(karg->ca_version, &arg32->ca32_version);
+	err |= copy_from_user(&karg->ca_client.cl_ident[0],
+			  &arg32->ca32_client.cl32_ident[0],
+			  NFSCLNT_IDMAX);
+	err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
+	err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
+			  &arg32->ca32_client.cl32_addrlist[0],
+			  (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
+	err |= __get_user(karg->ca_client.cl_fhkeytype,
+		      &arg32->ca32_client.cl32_fhkeytype);
+	err |= __get_user(karg->ca_client.cl_fhkeylen,
+		      &arg32->ca32_client.cl32_fhkeylen);
+	err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
+			  &arg32->ca32_client.cl32_fhkey[0],
+			  NFSCLNT_KEYMAX);
+
+	if(err) return -EFAULT;
+	return 0;
+}
+
+static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+	int err;
+	
+	err = __get_user(karg->ca_version, &arg32->ca32_version);
+	err |= copy_from_user(&karg->ca_export.ex_client[0],
+			  &arg32->ca32_export.ex32_client[0],
+			  NFSCLNT_IDMAX);
+	err |= copy_from_user(&karg->ca_export.ex_path[0],
+			  &arg32->ca32_export.ex32_path[0],
+			  NFS_MAXPATHLEN);
+	err |= __get_user(karg->ca_export.ex_dev,
+		      &arg32->ca32_export.ex32_dev);
+	err |= __get_user(karg->ca_export.ex_ino,
+		      &arg32->ca32_export.ex32_ino);
+	err |= __get_user(karg->ca_export.ex_flags,
+		      &arg32->ca32_export.ex32_flags);
+	err |= __get_user(karg->ca_export.ex_anon_uid,
+		      &arg32->ca32_export.ex32_anon_uid);
+	err |= __get_user(karg->ca_export.ex_anon_gid,
+		      &arg32->ca32_export.ex32_anon_gid);
+	karg->ca_export.ex_anon_uid = karg->ca_export.ex_anon_uid;
+	karg->ca_export.ex_anon_gid = karg->ca_export.ex_anon_gid;
+
+	if(err) return -EFAULT;
+	return 0;
+}
+
+static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+	u32 uaddr;
+	int i;
+	int err;
+
+	memset(karg, 0, sizeof(*karg));
+	if(__get_user(karg->ca_version, &arg32->ca32_version))
+		return -EFAULT;
+	karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
+	if(!karg->ca_umap.ug_ident)
+		return -ENOMEM;
+	err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
+	if(strncpy_from_user(karg->ca_umap.ug_ident,
+			     (char *)A(uaddr), PAGE_SIZE) <= 0)
+		return -EFAULT;
+	err |= __get_user(karg->ca_umap.ug_uidbase,
+		      &arg32->ca32_umap.ug32_uidbase);
+	err |= __get_user(karg->ca_umap.ug_uidlen,
+		      &arg32->ca32_umap.ug32_uidlen);
+	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
+	if (err)
+		return -EFAULT;
+	karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
+					  GFP_USER);
+	if(!karg->ca_umap.ug_udimap)
+		return -ENOMEM;
+	for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
+		err |= __get_user(karg->ca_umap.ug_udimap[i],
+			      &(((__kernel_uid_t32 *)A(uaddr))[i]));
+	err |= __get_user(karg->ca_umap.ug_gidbase,
+		      &arg32->ca32_umap.ug32_gidbase);
+	err |= __get_user(karg->ca_umap.ug_uidlen,
+		      &arg32->ca32_umap.ug32_gidlen);
+	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
+	if (err)
+		return -EFAULT;
+	karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
+					  GFP_USER);
+	if(!karg->ca_umap.ug_gdimap)
+		return -ENOMEM;
+	for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
+		err |= __get_user(karg->ca_umap.ug_gdimap[i],
+			      &(((__kernel_gid_t32 *)A(uaddr))[i]));
+
+	return err;
+}
+
+static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+	int err;
+	
+	err = __get_user(karg->ca_version, &arg32->ca32_version);
+	err |= copy_from_user(&karg->ca_getfh.gf_addr,
+			  &arg32->ca32_getfh.gf32_addr,
+			  (sizeof(struct sockaddr)));
+	err |= __get_user(karg->ca_getfh.gf_dev,
+		      &arg32->ca32_getfh.gf32_dev);
+	err |= __get_user(karg->ca_getfh.gf_ino,
+		      &arg32->ca32_getfh.gf32_ino);
+	err |= __get_user(karg->ca_getfh.gf_version,
+		      &arg32->ca32_getfh.gf32_version);
+
+	if(err) return -EFAULT;
+	return 0;
+}
+
+static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+	int err;
+	
+	err = __get_user(karg->ca_version, &arg32->ca32_version);
+	err |= copy_from_user(&karg->ca_getfd.gd_addr,
+			  &arg32->ca32_getfd.gd32_addr,
+			  (sizeof(struct sockaddr)));
+	err |= copy_from_user(&karg->ca_getfd.gd_path,
+			  &arg32->ca32_getfd.gd32_path,
+			  (NFS_MAXPATHLEN+1));
+	err |= __get_user(karg->ca_getfd.gd_version,
+		      &arg32->ca32_getfd.gd32_version);
+
+	if(err) return -EFAULT;
+	return 0;
+}
+
+static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+	int err;
+	
+	err = __get_user(karg->ca_version, &arg32->ca32_version);
+	err |= copy_from_user(&karg->ca_getfs.gd_addr,
+			  &arg32->ca32_getfs.gd32_addr,
+			  (sizeof(struct sockaddr)));
+	err |= copy_from_user(&karg->ca_getfs.gd_path,
+			  &arg32->ca32_getfs.gd32_path,
+			  (NFS_MAXPATHLEN+1));
+	err |= __get_user(karg->ca_getfs.gd_maxlen,
+		      &arg32->ca32_getfs.gd32_maxlen);
+
+	if(err) return -EFAULT;
+	return 0;
+}
+
+/* This really doesn't need translations, we are only passing
+ * back a union which contains opaque nfs file handle data.
+ */
+static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
+{
+	int err;
+
+	err = copy_to_user(res32, kres, sizeof(*res32));
+
+	if(err) return -EFAULT;
+	return 0;
+}
+
+/* Note: it is necessary to treat cmd_parm as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+int asmlinkage sys32_nfsservctl(u32 cmd_parm, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
+{
+  int cmd = (int)cmd_parm;
+	struct nfsctl_arg *karg = NULL;
+	union nfsctl_res *kres = NULL;
+	mm_segment_t oldfs;
+	int err;
+
+	karg = kmalloc(sizeof(*karg), GFP_USER);
+	if(!karg)
+		return -ENOMEM;
+	if(res32) {
+		kres = kmalloc(sizeof(*kres), GFP_USER);
+		if(!kres) {
+			kfree(karg);
+			return -ENOMEM;
+		}
+	}
+	switch(cmd) {
+	case NFSCTL_SVC:
+		err = nfs_svc32_trans(karg, arg32);
+		break;
+	case NFSCTL_ADDCLIENT:
+		err = nfs_clnt32_trans(karg, arg32);
+		break;
+	case NFSCTL_DELCLIENT:
+		err = nfs_clnt32_trans(karg, arg32);
+		break;
+	case NFSCTL_EXPORT:
+	case NFSCTL_UNEXPORT:
+		err = nfs_exp32_trans(karg, arg32);
+		break;
+	/* This one is unimplemented, be we're ready for it. */
+	case NFSCTL_UGIDUPDATE:
+		err = nfs_uud32_trans(karg, arg32);
+		break;
+	case NFSCTL_GETFH:
+		err = nfs_getfh32_trans(karg, arg32);
+		break;
+	case NFSCTL_GETFD:
+		err = nfs_getfd32_trans(karg, arg32);
+		break;
+	case NFSCTL_GETFS:
+		err = nfs_getfs32_trans(karg, arg32);
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+	if(err)
+		goto done;
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_nfsservctl(cmd, karg, kres);
+	set_fs(oldfs);
+
+	if (err)
+		goto done;
+
+	if((cmd == NFSCTL_GETFH) ||
+	   (cmd == NFSCTL_GETFD) ||
+	   (cmd == NFSCTL_GETFS))
+		err = nfs_getfh32_res_trans(kres, res32);
+
+done:
+	if(karg) {
+		if(cmd == NFSCTL_UGIDUPDATE) {
+			if(karg->ca_umap.ug_ident)
+				kfree(karg->ca_umap.ug_ident);
+			if(karg->ca_umap.ug_udimap)
+				kfree(karg->ca_umap.ug_udimap);
+			if(karg->ca_umap.ug_gdimap)
+				kfree(karg->ca_umap.ug_gdimap);
+		}
+		kfree(karg);
+	}
+	if(kres)
+		kfree(kres);
+	return err;
+}
+
+
+
+struct timespec32 {
+	s32    tv_sec;
+	s32    tv_nsec;
+};
+
+extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
+
+asmlinkage long sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
+{
+	struct timespec t;
+	int ret;
+	mm_segment_t old_fs = get_fs ();
+	
+	PPCDBG(PPCDBG_SYS32NI, "sys32_nanosleep - running - pid=%ld, comm=%s \n", current->pid, current->comm);
+	
+	if (get_user (t.tv_sec, &rqtp->tv_sec) ||
+	    __get_user (t.tv_nsec, &rqtp->tv_nsec))
+		return -EFAULT;
+	set_fs (KERNEL_DS);
+	ret = sys_nanosleep(&t, rmtp ? &t : NULL);
+	set_fs (old_fs);
+	if (rmtp && ret == -EINTR) {
+		if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
+	    	    __put_user (t.tv_nsec, &rmtp->tv_nsec))
+			return -EFAULT;
+	}
+	
+	return ret;
+}
+
+
+
+
+/* These are here just in case some old sparc32 binary calls it. */
+asmlinkage long sys32_pause(void)
+{
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_pause - running - pid=%ld, comm=%s \n", current->pid, current->comm);
+
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	
+	return -ERESTARTNOHAND;
+}
+
+
+
+static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
+{
+	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
+		(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
+		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
+		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
+		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
+}
+
+static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
+{
+	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
+		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
+		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
+		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
+		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
+}
+
+static inline long get_tv32(struct timeval *o, struct timeval32 *i)
+{
+	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
+		(__get_user(o->tv_sec, &i->tv_sec) |
+		 __get_user(o->tv_usec, &i->tv_usec)));
+}
+
+static inline long put_tv32(struct timeval32 *o, struct timeval *i)
+{
+	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
+		(__put_user(i->tv_sec, &o->tv_sec) |
+		 __put_user(i->tv_usec, &o->tv_usec)));
+}
+
+
+
+
+extern int do_getitimer(int which, struct itimerval *value);
+
+/* Note: it is necessary to treat which as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_getitimer(u32 which, struct itimerval32 *it)
+{
+	struct itimerval kit;
+	int error;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_getitimer - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	error = do_getitimer((int)which, &kit);
+	if (!error && put_it32(it, &kit))
+		error = -EFAULT;
+
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_getitimer - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+	return error;
+}
+
+
+
+extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
+
+/* Note: it is necessary to treat which as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_setitimer(u32 which, struct itimerval32 *in, struct itimerval32 *out)
+{
+	struct itimerval kin, kout;
+	int error;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_setitimer - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	if (in) {
+		if (get_it32(&kin, in))
+			return -EFAULT;
+	} else
+		memset(&kin, 0, sizeof(kin));
+
+	error = do_setitimer((int)which, &kin, out ? &kout : NULL);
+	if (error || !out)
+		return error;
+	if (put_it32(out, &kout))
+		return -EFAULT;
+
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_setitimer - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+	return 0;
+}
+
+#define RLIM_INFINITY32	0xffffffff
+#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
+
+struct rlimit32 {
+	u32	rlim_cur;
+	u32	rlim_max;
+};
+
+extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
+asmlinkage long sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
+{
+	struct rlimit r;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+	
+	set_fs (KERNEL_DS);
+	ret = sys_getrlimit(resource, &r);
+	set_fs(old_fs);
+	if (!ret) {
+		ret = put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
+		ret |= __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max);
+	}
+	
+	return ret;
+}
+
+/* Back compatibility for getrlimit. Needed for some apps. */
+asmlinkage long sys32_old_getrlimit(unsigned int resource, struct rlimit32* rlim)
+{
+	struct rlimit   x;    // 64-bit version of the resource limits.
+	struct rlimit32 x32;  // 32-bit version of the resource limits.
+	long rc = 0;
+	
+	if (resource >= RLIM_NLIMITS) {
+		PPCDBG(PPCDBG_SYS32, "sys32_old_getrlimit - specified resource is too large (%x) - pid=%ld, comm=%s\n", resource, current->pid, current->comm);
+		return -EINVAL;
+	}
+
+	memcpy(&x, current->rlim+resource, sizeof(struct rlimit));
+
+	if(x.rlim_cur > RLIM_INFINITY32)
+		x32.rlim_cur = RLIM_INFINITY32;
+	else
+		x32.rlim_cur = x.rlim_cur;
+
+	if(x.rlim_max > RLIM_INFINITY32)
+		x32.rlim_max = RLIM_INFINITY32;
+	else
+		x32.rlim_max = x.rlim_max;
+
+	rc = (copy_to_user(rlim, &x32, sizeof(x32))) ? (-EFAULT) : 0;
+	if (rc == 0) {
+		PPCDBG(PPCDBG_SYS32, "sys32_old_getrlimit - current=%x, maximum=%x - pid=%ld, comm=%s\n", x32.rlim_cur, x32.rlim_max, current->pid, current->comm);
+	} else {
+		PPCDBG(PPCDBG_SYS32, "sys32_old_getrlimit - unable to copy into user's storage - pid=%ld, comm=%s\n", current->pid, current->comm);
+	}
+	return rc;
+}
+
+extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
+asmlinkage long sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
+{
+	struct rlimit r;
+	long ret;
+	mm_segment_t old_fs = get_fs ();
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_setrlimit - entered - resource=%x, rlim=%p - pid=%ld, comm=%s\n", resource, rlim, current->pid, current->comm);
+
+	if (resource >= RLIM_NLIMITS) return -EINVAL;	
+	if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
+	    __get_user (r.rlim_max, &rlim->rlim_max))
+		return -EFAULT;
+	if (r.rlim_cur >= RLIM_INFINITY32)
+		r.rlim_cur = RLIM_INFINITY;
+	if (r.rlim_max >= RLIM_INFINITY32)
+		r.rlim_max = RLIM_INFINITY;
+	set_fs (KERNEL_DS);
+	ret = sys_setrlimit(resource, &r);
+	set_fs (old_fs);
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_setrlimit - exited w/ ret=%x - pid=%ld, comm=%s\n", ret, current->pid, current->comm);
+	return ret;
+}
+
+
+struct rusage32 {
+        struct timeval32 ru_utime;
+        struct timeval32 ru_stime;
+        s32    ru_maxrss;
+        s32    ru_ixrss;
+        s32    ru_idrss;
+        s32    ru_isrss;
+        s32    ru_minflt;
+        s32    ru_majflt;
+        s32    ru_nswap;
+        s32    ru_inblock;
+        s32    ru_oublock;
+        s32    ru_msgsnd; 
+        s32    ru_msgrcv; 
+        s32    ru_nsignals;
+        s32    ru_nvcsw;
+        s32    ru_nivcsw;
+};
+
+static int put_rusage (struct rusage32 *ru, struct rusage *r)
+{
+	int err;
+	
+	err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
+	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
+	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
+	err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
+	err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
+	err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
+	err |= __put_user (r->ru_idrss, &ru->ru_idrss);
+	err |= __put_user (r->ru_isrss, &ru->ru_isrss);
+	err |= __put_user (r->ru_minflt, &ru->ru_minflt);
+	err |= __put_user (r->ru_majflt, &ru->ru_majflt);
+	err |= __put_user (r->ru_nswap, &ru->ru_nswap);
+	err |= __put_user (r->ru_inblock, &ru->ru_inblock);
+	err |= __put_user (r->ru_oublock, &ru->ru_oublock);
+	err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
+	err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
+	err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
+	err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
+	err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
+	return err;
+}
+
+
+extern asmlinkage long sys_getrusage(int who, struct rusage *ru);
+
+/* Note: it is necessary to treat who as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_getrusage(u32 who, struct rusage32 *ru)
+{
+	struct rusage r;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_getrusage - running - pid=%ld, comm=%s\n", current->pid, current->comm);
+		
+	set_fs (KERNEL_DS);
+	ret = sys_getrusage((int)who, &r);
+	set_fs (old_fs);
+	if (put_rusage (ru, &r)) 
+		return -EFAULT;
+
+	return ret;
+}
+
+
+
+
+struct sysinfo32 {
+        s32 uptime;
+        u32 loads[3];
+        u32 totalram;
+        u32 freeram;
+        u32 sharedram;
+        u32 bufferram;
+        u32 totalswap;
+        u32 freeswap;
+        unsigned short procs;
+        char _f[22];
+};
+
+extern asmlinkage long sys_sysinfo(struct sysinfo *info);
+
+asmlinkage long sys32_sysinfo(struct sysinfo32 *info)
+{
+	struct sysinfo s;
+	int ret, err;
+	mm_segment_t old_fs = get_fs ();
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sysinfo - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	
+	set_fs (KERNEL_DS);
+	ret = sys_sysinfo(&s);
+	set_fs (old_fs);
+	err = put_user (s.uptime, &info->uptime);
+	err |= __put_user (s.loads[0], &info->loads[0]);
+	err |= __put_user (s.loads[1], &info->loads[1]);
+	err |= __put_user (s.loads[2], &info->loads[2]);
+	err |= __put_user (s.totalram, &info->totalram);
+	err |= __put_user (s.freeram, &info->freeram);
+	err |= __put_user (s.sharedram, &info->sharedram);
+	err |= __put_user (s.bufferram, &info->bufferram);
+	err |= __put_user (s.totalswap, &info->totalswap);
+	err |= __put_user (s.freeswap, &info->freeswap);
+	err |= __put_user (s.procs, &info->procs);
+	if (err)
+		return -EFAULT;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sysinfo - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return ret;
+}
+
+
+
+
+/* Translations due to time_t size differences.  Which affects all
+   sorts of things, like timeval and itimerval.  */
+extern struct timezone sys_tz;
+extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
+
+asmlinkage long sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
+{
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_gettimeofday - running - pid=%ld, comm=%s\n", current->pid, current->comm);
+
+	if (tv) {
+		struct timeval ktv;
+		do_gettimeofday(&ktv);
+		if (put_tv32(tv, &ktv))
+			return -EFAULT;
+	}
+	if (tz) {
+		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
+			return -EFAULT;
+	}
+	
+	return 0;
+}
+
+
+
+asmlinkage long sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
+{
+	struct timeval ktv;
+	struct timezone ktz;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_settimeofday - running - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+ 	if (tv) {
+		if (get_tv32(&ktv, tv))
+			return -EFAULT;
+	}
+	if (tz) {
+		if (copy_from_user(&ktz, tz, sizeof(ktz)))
+			return -EFAULT;
+	}
+
+	return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
+}
+
+
+
+
+struct tms32 {
+	__kernel_clock_t32 tms_utime;
+	__kernel_clock_t32 tms_stime;
+	__kernel_clock_t32 tms_cutime;
+	__kernel_clock_t32 tms_cstime;
+};
+                                
+extern asmlinkage long sys_times(struct tms * tbuf);
+
+asmlinkage long sys32_times(struct tms32 *tbuf)
+{
+	struct tms t;
+	long ret;
+	mm_segment_t old_fs = get_fs ();
+	int err;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_times - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	
+	set_fs (KERNEL_DS);
+	ret = sys_times(tbuf ? &t : NULL);
+	set_fs (old_fs);
+	if (tbuf) {
+		err = put_user (t.tms_utime, &tbuf->tms_utime);
+		err |= __put_user (t.tms_stime, &tbuf->tms_stime);
+		err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
+		err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
+		if (err)
+			ret = -EFAULT;
+	}
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_times - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return ret;
+}
+
+struct msgbuf32 { s32 mtype; char mtext[1]; };
+
+struct semid_ds32 {
+	struct ipc_perm sem_perm;
+	__kernel_time_t32 sem_otime;
+	__kernel_time_t32 sem_ctime;
+	u32 sem_base;
+	u32 sem_pending;
+	u32 sem_pending_last;
+	u32 undo;
+	unsigned short sem_nsems;
+};
+
+struct semid64_ds32 {
+	struct ipc64_perm sem_perm;
+	unsigned int __unused1;
+	__kernel_time_t32 sem_otime;
+	unsigned int __unused2;
+	__kernel_time_t32 sem_ctime;
+	u32 sem_nsems;
+	u32 __unused3;
+	u32 __unused4;
+};
+
+struct msqid_ds32
+{
+	struct ipc_perm msg_perm;
+	u32 msg_first;
+	u32 msg_last;
+	__kernel_time_t32 msg_stime;
+	__kernel_time_t32 msg_rtime;
+	__kernel_time_t32 msg_ctime;
+	u32 msg_lcbytes;
+	u32 msg_lqbytes;
+	unsigned short msg_cbytes;
+	unsigned short msg_qnum;
+	unsigned short msg_qbytes;
+	__kernel_ipc_pid_t32 msg_lspid;
+	__kernel_ipc_pid_t32 msg_lrpid;
+};
+
+struct msqid64_ds32 {
+	struct ipc64_perm msg_perm;
+	unsigned int __unused1;
+	__kernel_time_t32 msg_stime;
+	unsigned int __unused2;
+	__kernel_time_t32 msg_rtime;
+	unsigned int __unused3;
+	__kernel_time_t32 msg_ctime;
+	unsigned int msg_cbytes;
+	unsigned int msg_qnum;
+	unsigned int msg_qbytes;
+	__kernel_pid_t32 msg_lspid;
+	__kernel_pid_t32 msg_lrpid;
+	unsigned int __unused4;
+	unsigned int __unused5;
+};
+
+struct shmid_ds32 {
+	struct ipc_perm shm_perm;
+	int shm_segsz;
+	__kernel_time_t32 shm_atime;
+	__kernel_time_t32 shm_dtime;
+	__kernel_time_t32 shm_ctime;
+	__kernel_ipc_pid_t32 shm_cpid;
+	__kernel_ipc_pid_t32 shm_lpid;
+	unsigned short shm_nattch;
+	unsigned short __unused;
+	unsigned int __unused2;
+	unsigned int __unused3;
+};
+
+struct shmid64_ds32 {
+	struct ipc64_perm shm_perm;
+	unsigned int __unused1;
+	__kernel_time_t32 shm_atime;
+	unsigned int __unused2;
+	__kernel_time_t32 shm_dtime;
+	unsigned int __unused3;
+	__kernel_time_t32 shm_ctime;
+	unsigned int __unused4;
+	__kernel_size_t32 shm_segsz;
+	__kernel_pid_t32 shm_cpid;
+	__kernel_pid_t32 shm_lpid;
+	unsigned int shm_nattch;
+	unsigned int __unused5;
+	unsigned int __unused6;
+};
+
+/*
+ * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit
+ * emulation..
+ *
+ * This is really horribly ugly.
+ */
+static long do_sys32_semctl(int first, int second, int third, void *uptr)
+{
+	union semun fourth;
+	u32 pad;
+	int err, err2;
+	mm_segment_t old_fs;
+
+	if (!uptr)
+		return -EINVAL;
+	err = -EFAULT;
+	if (get_user(pad, (u32 *)uptr))
+		return err;
+	if (third == SETVAL)
+		fourth.val = (int)pad;
+	else
+		fourth.__pad = (void *)A(pad);
+	switch (third & (~IPC_64)) {
+
+	case IPC_INFO:
+	case IPC_RMID:
+	case SEM_INFO:
+	case GETVAL:
+	case GETPID:
+	case GETNCNT:
+	case GETZCNT:
+	case GETALL:
+	case SETALL:
+	case SETVAL:
+		err = sys_semctl(first, second, third, fourth);
+		break;
+
+	case IPC_STAT:
+	case SEM_STAT:
+		if (third & IPC_64) {
+			struct semid64_ds s64;
+			struct semid64_ds32 *usp;
+
+			usp = (struct semid64_ds32 *)A(pad);
+			fourth.__pad = &s64;
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_semctl(first, second, third, fourth);
+			set_fs(old_fs);
+			err2 = copy_to_user(&usp->sem_perm, &s64.sem_perm,
+					    sizeof(struct ipc64_perm));
+			err2 |= __put_user(s64.sem_otime, &usp->sem_otime);
+			err2 |= __put_user(s64.sem_ctime, &usp->sem_ctime);
+			err2 |= __put_user(s64.sem_nsems, &usp->sem_nsems);
+			if (err2)
+				err = -EFAULT;
+		} else {
+			struct semid_ds s;
+			struct semid_ds32 *usp;
+
+			usp = (struct semid_ds32 *)A(pad);
+			fourth.__pad = &s;
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_semctl(first, second, third, fourth);
+			set_fs(old_fs);
+			err2 = copy_to_user(&usp->sem_perm, &s.sem_perm,
+					    sizeof(struct ipc_perm));
+			err2 |= __put_user(s.sem_otime, &usp->sem_otime);
+			err2 |= __put_user(s.sem_ctime, &usp->sem_ctime);
+			err2 |= __put_user(s.sem_nsems, &usp->sem_nsems);
+			if (err2)
+				err = -EFAULT;
+		}
+		break;
+ 
+	case IPC_SET:
+		if (third & IPC_64) {
+			struct semid64_ds s64;
+			struct semid64_ds32 *usp;
+
+			usp = (struct semid64_ds32 *)A(pad);
+
+			err = get_user(s64.sem_perm.uid, &usp->sem_perm.uid);
+			err |= __get_user(s64.sem_perm.gid,
+					  &usp->sem_perm.gid);
+			err |= __get_user(s64.sem_perm.mode,
+					  &usp->sem_perm.mode);
+			if (err)
+				goto out;
+			fourth.__pad = &s64;
+
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_semctl(first, second, third, fourth);
+			set_fs(old_fs);
+
+		} else {
+			struct semid_ds s;
+			struct semid_ds32 *usp;
+
+			usp = (struct semid_ds32 *)A(pad);
+
+			err = get_user(s.sem_perm.uid, &usp->sem_perm.uid);
+			err |= __get_user(s.sem_perm.gid,
+					  &usp->sem_perm.gid);
+			err |= __get_user(s.sem_perm.mode,
+					  &usp->sem_perm.mode);
+			if (err)
+				goto out;
+			fourth.__pad = &s;
+
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_semctl(first, second, third, fourth);
+			set_fs(old_fs);
+		}
+		break;
+	}
+out:
+	return err;
+}
+
+static int 
+do_sys32_msgsnd(int first, int second, int third, void *uptr)
+{
+	struct msgbuf *p;
+	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
+	mm_segment_t old_fs;
+	int err;
+
+	if (second < 0)
+		return -EINVAL;
+
+	p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+	if (!p)
+		return -ENOMEM;
+	err = get_user(p->mtype, &up->mtype);
+	err |= __copy_from_user(p->mtext, &up->mtext, second);
+	if (err) {
+		err = -EFAULT;
+		goto out;
+	}
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_msgsnd(first, p, second, third);
+	set_fs(old_fs);
+out:
+	kfree(p);
+	return err;
+}
+
+static int
+do_sys32_msgrcv(int first, int second, int msgtyp, int third,
+		int version, void *uptr)
+{
+	struct msgbuf32 *up;
+	struct msgbuf *p;
+	mm_segment_t old_fs;
+	int err;
+
+	if (second < 0)
+		return -EINVAL;
+
+	if (!version) {
+		struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
+		struct ipc_kludge ipck;
+
+		err = -EINVAL;
+		if (!uptr)
+			goto out;
+		err = -EFAULT;
+		if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge)))
+			goto out;
+		uptr = (void *)A(ipck.msgp);
+		msgtyp = ipck.msgtyp;
+	}
+	err = -ENOMEM;
+	p = kmalloc(second + sizeof (struct msgbuf) + 4, GFP_USER);
+	if (!p)
+		goto out;
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_msgrcv(first, p, second + 4, msgtyp, third);
+	set_fs(old_fs);
+	if (err < 0)
+		goto free_then_out;
+	up = (struct msgbuf32 *)uptr;
+	if (put_user(p->mtype, &up->mtype) ||
+	    __copy_to_user(&up->mtext, p->mtext, err))
+		err = -EFAULT;
+free_then_out:
+	kfree(p);
+out:
+	return err;
+}
+
+static int
+do_sys32_msgctl(int first, int second, void *uptr)
+{
+	int err = -EINVAL, err2;
+	mm_segment_t old_fs;
+
+	switch (second & (~IPC_64)) {
+
+	case IPC_INFO:
+	case IPC_RMID:
+	case MSG_INFO:
+		err = sys_msgctl(first, second, (struct msqid_ds *)uptr);
+		break;
+
+	case IPC_SET:
+		if (second & IPC_64) {
+			struct msqid64_ds m64;
+			struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
+
+			err2 = copy_from_user(&m64.msg_perm, &up->msg_perm,
+					      sizeof(struct ipc64_perm));
+			err2 |= __get_user(m64.msg_qbytes, &up->msg_qbytes);
+			if (err2) {
+				err = -EFAULT;
+				break;
+			}
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_msgctl(first, second,
+					 (struct msqid_ds *)&m64);
+			set_fs(old_fs);
+		} else {
+			struct msqid_ds m;
+			struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
+
+			err2 = copy_from_user(&m.msg_perm, &up->msg_perm,
+					      sizeof(struct ipc_perm));
+			err2 |= __get_user(m.msg_qbytes, &up->msg_qbytes);
+			if (err2) {
+				err = -EFAULT;
+				break;
+			}
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_msgctl(first, second, &m);
+			set_fs(old_fs);
+		}
+		break;
+
+	case IPC_STAT:
+	case MSG_STAT:
+		if (second & IPC_64) {
+			struct msqid64_ds m64;
+			struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
+
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_msgctl(first, second,
+					 (struct msqid_ds *)&m64);
+			set_fs(old_fs);
+
+			err2 = copy_to_user(&up->msg_perm, &m64.msg_perm,
+					    sizeof(struct ipc64_perm));
+ 			err2 |= __put_user(m64.msg_stime, &up->msg_stime);
+			err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);
+			err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);
+			err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);
+			err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);
+			err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);
+			err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);
+			err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);
+			if (err2)
+				err = -EFAULT;
+		} else {
+			struct msqid64_ds m;
+			struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
+
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_msgctl(first, second, (struct msqid_ds *)&m);
+			set_fs(old_fs);
+
+			err2 = copy_to_user(&up->msg_perm, &m.msg_perm,
+					    sizeof(struct ipc_perm));
+ 			err2 |= __put_user(m.msg_stime, &up->msg_stime);
+			err2 |= __put_user(m.msg_rtime, &up->msg_rtime);
+			err2 |= __put_user(m.msg_ctime, &up->msg_ctime);
+			err2 |= __put_user(m.msg_cbytes, &up->msg_cbytes);
+			err2 |= __put_user(m.msg_qnum, &up->msg_qnum);
+			err2 |= __put_user(m.msg_qbytes, &up->msg_qbytes);
+			err2 |= __put_user(m.msg_lspid, &up->msg_lspid);
+			err2 |= __put_user(m.msg_lrpid, &up->msg_lrpid);
+			if (err2)
+				err = -EFAULT;
+		}
+		break;
+	}
+#if 0
+	udbg_printf("  err3 = 0x%lx\n", err); 
+#endif
+	return err;
+}
+
+static int
+do_sys32_shmat(int first, int second, int third, int version, void *uptr)
+{
+	unsigned long raddr;
+	u32 *uaddr = (u32 *)A((u32)third);
+	int err = -EINVAL;
+
+	if (version == 1)
+		return err;
+	err = sys_shmat(first, uptr, second, &raddr);
+	if (err)
+		return err;
+	err = put_user(raddr, uaddr);
+	return err;
+}
+
+static int
+do_sys32_shmctl(int first, int second, void *uptr)
+{
+	int err = -EFAULT, err2;
+	mm_segment_t old_fs;
+
+	switch (second & (~IPC_64)) {
+
+	case IPC_INFO:
+	case IPC_RMID:
+	case SHM_LOCK:
+	case SHM_UNLOCK:
+		err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
+		break;
+	case IPC_SET:
+		if (second & IPC_64) {
+			struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
+			struct shmid64_ds s64;
+
+			err = get_user(s64.shm_perm.uid, &up->shm_perm.uid);
+			err |= __get_user(s64.shm_perm.gid, &up->shm_perm.gid);
+			err |= __get_user(s64.shm_perm.mode,
+					  &up->shm_perm.mode);
+			if (err)
+				break;
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_shmctl(first, second,
+					 (struct shmid_ds *)&s64);
+			set_fs(old_fs);
+		} else {
+			struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
+			struct shmid_ds s;
+
+			err = get_user(s.shm_perm.uid, &up->shm_perm.uid);
+			err |= __get_user(s.shm_perm.gid, &up->shm_perm.gid);
+			err |= __get_user(s.shm_perm.mode, &up->shm_perm.mode);
+			if (err)
+				break;
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_shmctl(first, second, &s);
+			set_fs(old_fs);
+		}
+		break;
+
+	case IPC_STAT:
+	case SHM_STAT:
+		if (second & IPC_64) {
+			struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
+			struct shmid64_ds s64;
+
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_shmctl(first, second,
+					 (struct shmid_ds *)&s64);
+			set_fs(old_fs);
+			if (err < 0)
+				break;
+
+			err2 = copy_to_user(&up->shm_perm, &s64.shm_perm,
+					    sizeof(struct ipc64_perm));
+			err2 |= __put_user(s64.shm_atime, &up->shm_atime);
+			err2 |= __put_user(s64.shm_dtime, &up->shm_dtime);
+			err2 |= __put_user(s64.shm_ctime, &up->shm_ctime);
+			err2 |= __put_user(s64.shm_segsz, &up->shm_segsz);
+			err2 |= __put_user(s64.shm_nattch, &up->shm_nattch);
+			err2 |= __put_user(s64.shm_cpid, &up->shm_cpid);
+			err2 |= __put_user(s64.shm_lpid, &up->shm_lpid);
+			if (err2)
+				err = -EFAULT;
+		} else {
+			struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
+			struct shmid_ds s;
+
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			err = sys_shmctl(first, second, &s);
+			set_fs(old_fs);
+			if (err < 0)
+				break;
+
+			err2 = copy_to_user(&up->shm_perm, &s.shm_perm,
+					    sizeof(struct ipc_perm));
+			err2 |= __put_user (s.shm_atime, &up->shm_atime);
+			err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
+			err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
+			err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
+			err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
+			err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
+			err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
+			if (err2)
+				err = -EFAULT;
+		}
+		break;
+
+	case SHM_INFO: {
+		struct shm_info si;
+		struct shm_info32 {
+			int used_ids;
+			u32 shm_tot, shm_rss, shm_swp;
+			u32 swap_attempts, swap_successes;
+		} *uip = (struct shm_info32 *)uptr;
+
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		err = sys_shmctl(first, second, (struct shmid_ds *)&si);
+		set_fs(old_fs);
+		if (err < 0)
+			break;
+		err2 = put_user(si.used_ids, &uip->used_ids);
+		err2 |= __put_user(si.shm_tot, &uip->shm_tot);
+		err2 |= __put_user(si.shm_rss, &uip->shm_rss);
+		err2 |= __put_user(si.shm_swp, &uip->shm_swp);
+		err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
+		err2 |= __put_user(si.swap_successes, &uip->swap_successes);
+		if (err2)
+			err = -EFAULT;
+		break;
+	}
+	}
+	return err;
+}
+
+/*
+ * Note: it is necessary to treat first_parm, second_parm, and
+ * third_parm as unsigned ints, with the corresponding cast to a
+ * signed int to insure that the proper conversion (sign extension)
+ * between the register representation of a signed int (msr in 32-bit
+ * mode) and the register representation of a signed int (msr in
+ * 64-bit mode) is performed.
+ */
+asmlinkage long sys32_ipc(u32 call, u32 first_parm, u32 second_parm, u32 third_parm, u32 ptr, u32 fifth)
+{
+	int first  = (int)first_parm;
+	int second = (int)second_parm;
+	int third  = (int)third_parm;
+	int version, err;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_ipc - entered - call=%x, parm1=%x, parm2=%x, parm3=%x, parm4=%x, parm5=%x \n", 
+         call, first_parm, second_parm, third_parm, ptr, fifth);
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+
+	case SEMOP:
+		/* struct sembuf is the same on 32 and 64bit :)) */
+		err = sys_semop(first, (struct sembuf *)AA(ptr),
+				second);
+		break;
+	case SEMGET:
+		err = sys_semget(first, second, third);
+		break;
+	case SEMCTL:
+		err = do_sys32_semctl(first, second, third,
+				      (void *)AA(ptr));
+		break;
+
+	case MSGSND:
+		err = do_sys32_msgsnd(first, second, third,
+				      (void *)AA(ptr));
+		break;
+	case MSGRCV:
+		err = do_sys32_msgrcv(first, second, fifth, third,
+				      version, (void *)AA(ptr));
+		break;
+	case MSGGET:
+		err = sys_msgget((key_t)first, second);
+		break;
+	case MSGCTL:
+		err = do_sys32_msgctl(first, second, (void *)AA(ptr));
+		break;
+
+	case SHMAT:
+		err = do_sys32_shmat(first, second, third,
+				     version, (void *)AA(ptr));
+		break;
+	case SHMDT: 
+		err = sys_shmdt((char *)AA(ptr));
+		break;
+	case SHMGET:
+		err = sys_shmget(first, second, third);
+		break;
+	case SHMCTL:
+		err = do_sys32_shmctl(first, second, (void *)AA(ptr));
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_ipc - exited w/ %d/0x%x \n", err, err);
+	return err;
+}
+
+/* stat syscall methods. */
+extern asmlinkage int sys_stat(char* filename, struct __old_kernel_stat* statbuf);
+
+static int cp_old_stat32(struct inode* inode, struct __old_kernel_stat32* statbuf)
+{
+	static int warncount = 5;
+	struct __old_kernel_stat32 tmp;
+
+	if (warncount) {
+		warncount--;
+		printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
+			current->comm);
+	}
+
+	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
+	tmp.st_ino = inode->i_ino;
+	tmp.st_mode = inode->i_mode;
+	tmp.st_nlink = inode->i_nlink;
+	SET_OLDSTAT_UID(tmp, inode->i_uid);
+	SET_OLDSTAT_GID(tmp, inode->i_gid);
+	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
+	tmp.st_size = inode->i_size;
+	tmp.st_atime = inode->i_atime;
+	tmp.st_mtime = inode->i_mtime;
+	tmp.st_ctime = inode->i_ctime;
+	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long sys32_stat(char* filename, struct __old_kernel_stat32* statbuf)
+{
+	struct nameidata nd;
+	int error;
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_stat - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	error = user_path_walk(filename, &nd);
+	if (!error) {
+		error = do_revalidate(nd.dentry);
+		if (!error)
+			error = cp_old_stat32(nd.dentry->d_inode, statbuf);
+		path_release(&nd);
+	}
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_stat - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return error;
+}
+
+asmlinkage long sys32_fstat(unsigned int fd, struct __old_kernel_stat32* statbuf)
+{
+	struct file *f;
+	int err = -EBADF;
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_fstat - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	f = fget(fd);
+	if (f) {
+		struct dentry * dentry = f->f_dentry;
+
+		err = do_revalidate(dentry);
+		if (!err)
+			err = cp_old_stat32(dentry->d_inode, statbuf);
+		fput(f);
+	}
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_fstat - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return err;
+}
+
+asmlinkage long sys32_lstat(char* filename, struct __old_kernel_stat32* statbuf)
+{
+	struct nameidata nd;
+	int error;
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_lstat - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	error = user_path_walk_link(filename, &nd);
+	if (!error) {
+		error = do_revalidate(nd.dentry);
+		if (!error)
+			error = cp_old_stat32(nd.dentry->d_inode, statbuf);
+
+		path_release(&nd);
+	}
+	
+	PPCDBG(PPCDBG_SYS32X, "sys32_lstat - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return error;
+}
+
+extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
+
+/* Note: it is necessary to treat out_fd and in_fd as unsigned ints, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, __kernel_off_t32* offset, u32 count)
+{
+	mm_segment_t old_fs = get_fs();
+	int ret;
+	off_t of;
+	
+	if (offset && get_user(of, offset))
+		return -EFAULT;
+		
+	set_fs(KERNEL_DS);
+	ret = sys_sendfile((int)out_fd, (int)in_fd, offset ? &of : NULL, count);
+	set_fs(old_fs);
+	
+	if (offset && put_user(of, offset))
+		return -EFAULT;
+		
+	return ret;
+}
+
+extern asmlinkage int sys_setsockopt(int fd, int level, int optname, char *optval, int optlen);
+
+asmlinkage long sys32_setsockopt(int fd, int level, int optname, char* optval, int optlen)
+{
+	
+	PPCDBG(PPCDBG_SYS32,"sys32_setsockopt - running - pid=%ld, comm=%s\n", current->pid, current->comm);
+
+	if (optname == SO_ATTACH_FILTER) {
+		struct sock_fprog32 {
+			__u16 len;
+			__u32 filter;
+		} *fprog32 = (struct sock_fprog32 *)optval;
+		struct sock_fprog kfprog;
+		struct sock_filter *kfilter;
+		unsigned int fsize;
+		mm_segment_t old_fs;
+		__u32 uptr;
+		int ret;
+
+		if (get_user(kfprog.len, &fprog32->len) ||
+		    __get_user(uptr, &fprog32->filter))
+			return -EFAULT;
+		kfprog.filter = (struct sock_filter *)A(uptr);
+		fsize = kfprog.len * sizeof(struct sock_filter);
+		kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
+		if (kfilter == NULL)
+			return -ENOMEM;
+		if (copy_from_user(kfilter, kfprog.filter, fsize)) {
+			kfree(kfilter);
+			return -EFAULT;
+		}
+		kfprog.filter = kfilter;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		ret = sys_setsockopt(fd, level, optname,
+				     (char *)&kfprog, sizeof(kfprog));
+		set_fs(old_fs);
+		kfree(kfilter);
+		return ret;
+	}
+	return sys_setsockopt(fd, level, optname, optval, optlen);
+}
+
+
+
+
+#define MAX_SOCK_ADDR	128		/* 108 for Unix domain -  16 for IP, 16 for IPX, 24 for IPv6, about 80 for AX.25 */
+#define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
+#define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
+
+#define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
+
+#define CMSG32_DATA(cmsg)	((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
+#define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
+#define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
+#define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
+				    (struct cmsghdr32 *)(ctl) : \
+				    (struct cmsghdr32 *)NULL)
+#define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+
+struct msghdr32
+{
+	u32               msg_name;
+	int               msg_namelen;
+	u32               msg_iov;
+	__kernel_size_t32 msg_iovlen;
+	u32               msg_control;
+	__kernel_size_t32 msg_controllen;
+	unsigned          msg_flags;
+};
+
+struct cmsghdr32
+{
+	__kernel_size_t32 cmsg_len;
+	int               cmsg_level;
+	int               cmsg_type;
+};
+
+__inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
+					     struct cmsghdr32 *__cmsg, int __cmsg_len)
+{
+	struct cmsghdr32 * __ptr;
+
+	__ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
+				     CMSG32_ALIGN(__cmsg_len));
+	if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
+		return NULL;
+
+	return __ptr;
+}
+
+__inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
+					    struct cmsghdr32 *__cmsg,
+					    int __cmsg_len)
+{
+	return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
+			       __cmsg, __cmsg_len);
+}
+
+extern __inline__ struct socket *socki_lookup(struct inode *inode)
+{
+	return &inode->u.socket_i;
+}
+
+extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
+{
+	struct file *file;
+	struct inode *inode;
+
+	if (!(file = fget(fd)))
+	{
+		*err = -EBADF;
+		return NULL;
+	}
+
+	inode = file->f_dentry->d_inode;
+	if (!inode || !inode->i_sock || !socki_lookup(inode))
+	{
+		*err = -ENOTSOCK;
+		fput(file);
+		return NULL;
+	}
+
+	return socki_lookup(inode);
+}
+
+extern __inline__ void sockfd_put(struct socket *sock)
+{
+	fput(sock->file);
+}
+
+static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg, struct msghdr32 *umsg)
+{
+	u32 tmp1, tmp2, tmp3;
+	int err;
+
+	err = get_user(tmp1, &umsg->msg_name);
+	err |= __get_user(tmp2, &umsg->msg_iov);
+	err |= __get_user(tmp3, &umsg->msg_control);
+	if (err)
+		return -EFAULT;
+
+	kmsg->msg_name = (void *)A(tmp1);
+	kmsg->msg_iov = (struct iovec *)A(tmp2);
+	kmsg->msg_control = (void *)A(tmp3);
+
+	err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
+	err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
+	err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
+	err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
+	
+	return err;
+}
+
+static inline int iov_from_user32_to_kern(struct iovec *kiov,
+					  struct iovec32 *uiov32,
+					  int niov)
+{
+	int tot_len = 0;
+
+	while(niov > 0) {
+		u32 len, buf;
+
+		if(get_user(len, &uiov32->iov_len) ||
+		   get_user(buf, &uiov32->iov_base)) {
+			tot_len = -EFAULT;
+			break;
+		}
+		tot_len += len;
+		kiov->iov_base = (void *)A(buf);
+		kiov->iov_len = (__kernel_size_t) len;
+		uiov32++;
+		kiov++;
+		niov--;
+	}
+	return tot_len;
+}
+
+/* I've named the args so it is easy to tell whose space the pointers are in. */
+static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
+			  char *kern_address, int mode)
+{
+	int tot_len;
+
+	if(kern_msg->msg_namelen) {
+		if(mode==VERIFY_READ) {
+			int err = move_addr_to_kernel(kern_msg->msg_name,
+						      kern_msg->msg_namelen,
+						      kern_address);
+			if(err < 0)
+				return err;
+		}
+		kern_msg->msg_name = kern_address;
+	} else
+		kern_msg->msg_name = NULL;
+
+	if(kern_msg->msg_iovlen > UIO_FASTIOV) {
+		kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
+				   GFP_KERNEL);
+		if(!kern_iov)
+			return -ENOMEM;
+	}
+
+	tot_len = iov_from_user32_to_kern(kern_iov,
+					  (struct iovec32 *)kern_msg->msg_iov,
+					  kern_msg->msg_iovlen);
+	if(tot_len >= 0)
+		kern_msg->msg_iov = kern_iov;
+	else if(kern_msg->msg_iovlen > UIO_FASTIOV)
+		kfree(kern_iov);
+
+	return tot_len;
+}
+
+/* There is a lot of hair here because the alignment rules (and
+ * thus placement) of cmsg headers and length are different for
+ * 32-bit apps.  -DaveM
+ */
+static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
+				       unsigned char *stackbuf, int stackbuf_size)
+{
+	struct cmsghdr32 *ucmsg;
+	struct cmsghdr *kcmsg, *kcmsg_base;
+	__kernel_size_t32 ucmlen;
+	__kernel_size_t kcmlen, tmp;
+
+	kcmlen = 0;
+	kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
+	ucmsg = CMSG32_FIRSTHDR(kmsg);
+	while(ucmsg != NULL) {
+		if(get_user(ucmlen, &ucmsg->cmsg_len))
+			return -EFAULT;
+
+		/* Catch bogons. */
+		if(CMSG32_ALIGN(ucmlen) <
+		   CMSG32_ALIGN(sizeof(struct cmsghdr32)))
+			return -EINVAL;
+		if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
+				   + ucmlen) > kmsg->msg_controllen)
+			return -EINVAL;
+
+		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
+		       CMSG_ALIGN(sizeof(struct cmsghdr)));
+		kcmlen += tmp;
+		ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
+	}
+	if (kcmlen == 0)
+		return -EINVAL;
+
+	/* The kcmlen holds the 64-bit version of the control length.
+	 * It may not be modified as we do not stick it into the kmsg
+	 * until we have successfully copied over all of the data
+	 * from the user.
+	 */
+	if (kcmlen > stackbuf_size)
+		kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
+	if (kcmsg == NULL)
+		return -ENOBUFS;
+
+	/* Now copy them over neatly. */
+	memset(kcmsg, 0, kcmlen);
+	ucmsg = CMSG32_FIRSTHDR(kmsg);
+	while (ucmsg != NULL) {
+		__get_user(ucmlen, &ucmsg->cmsg_len);
+		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
+		       CMSG_ALIGN(sizeof(struct cmsghdr)));
+		kcmsg->cmsg_len = tmp;
+		__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
+		__get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
+
+		/* Copy over the data. */
+		if(copy_from_user(CMSG_DATA(kcmsg),
+				  CMSG32_DATA(ucmsg),
+				  (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
+			goto out_free_efault;
+
+		/* Advance. */
+		kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
+		ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
+	}
+
+	/* Ok, looks like we made it.  Hook it up and return success. */
+	kmsg->msg_control = kcmsg_base;
+	kmsg->msg_controllen = kcmlen;
+	return 0;
+
+out_free_efault:
+	if(kcmsg_base != (struct cmsghdr *)stackbuf)
+		kfree(kcmsg_base);
+	return -EFAULT;
+}
+
+asmlinkage long sys32_sendmsg(int fd, struct msghdr32* user_msg, unsigned int user_flags)
+{
+	struct socket *sock;
+	char address[MAX_SOCK_ADDR];
+	struct iovec iov[UIO_FASTIOV];
+	unsigned char ctl[sizeof(struct cmsghdr) + 20];
+	unsigned char *ctl_buf = ctl;
+	struct msghdr kern_msg;
+	int err, total_len;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sendmsg - entered - fd=%x, user_msg@=%p, user_flags=%x \n", fd, user_msg, user_flags);
+
+	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
+		return -EFAULT;
+	if(kern_msg.msg_iovlen > UIO_MAXIOV)
+		return -EINVAL;
+	err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
+	if (err < 0)
+		goto out;
+	total_len = err;
+
+	if(kern_msg.msg_controllen) {
+		err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
+		if(err)
+			goto out_freeiov;
+		ctl_buf = kern_msg.msg_control;
+	}
+	kern_msg.msg_flags = user_flags;
+
+	sock = sockfd_lookup(fd, &err);
+	if (sock != NULL) {
+		if (sock->file->f_flags & O_NONBLOCK)
+			kern_msg.msg_flags |= MSG_DONTWAIT;
+		err = sock_sendmsg(sock, &kern_msg, total_len);
+		sockfd_put(sock);
+	}
+
+	/* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
+	if(ctl_buf != ctl)
+		kfree(ctl_buf);
+out_freeiov:
+	if(kern_msg.msg_iov != iov)
+		kfree(kern_msg.msg_iov);
+out:
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sendmsg - exited w/ %lx \n", err);
+	return err;
+}
+
+static void put_cmsg32(struct msghdr *kmsg, int level, int type,
+		       int len, void *data)
+{
+	struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
+	struct cmsghdr32 cmhdr;
+	int cmlen = CMSG32_LEN(len);
+
+	if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
+		kmsg->msg_flags |= MSG_CTRUNC;
+		return;
+	}
+
+	if (kmsg->msg_controllen < cmlen) {
+		kmsg->msg_flags |= MSG_CTRUNC;
+		cmlen = kmsg->msg_controllen;
+	}
+	cmhdr.cmsg_level = level;
+	cmhdr.cmsg_type = type;
+	cmhdr.cmsg_len = cmlen;
+
+	if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
+		return;
+	if (copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
+		return;
+	cmlen = CMSG32_SPACE(len);
+	kmsg->msg_control += cmlen;
+	kmsg->msg_controllen -= cmlen;
+}
+
+
+static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
+{
+	struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
+	int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
+	int fdnum = scm->fp->count;
+	struct file **fp = scm->fp->fp;
+	int *cmfptr;
+	int err = 0, i;
+
+	if (fdnum < fdmax)
+		fdmax = fdnum;
+
+	for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
+		int new_fd;
+		err = get_unused_fd();
+		if (err < 0)
+			break;
+		new_fd = err;
+		err = put_user(new_fd, cmfptr);
+		if (err) {
+			put_unused_fd(new_fd);
+			break;
+		}
+		/* Bump the usage count and install the file. */
+		get_file(fp[i]);
+		fd_install(new_fd, fp[i]);
+	}
+
+	if (i > 0) {
+		int cmlen = CMSG32_LEN(i * sizeof(int));
+		if (!err)
+			err = put_user(SOL_SOCKET, &cm->cmsg_level);
+		if (!err)
+			err = put_user(SCM_RIGHTS, &cm->cmsg_type);
+		if (!err)
+			err = put_user(cmlen, &cm->cmsg_len);
+		if (!err) {
+			cmlen = CMSG32_SPACE(i * sizeof(int));
+			kmsg->msg_control += cmlen;
+			kmsg->msg_controllen -= cmlen;
+		}
+	}
+	if (i < fdnum)
+		kmsg->msg_flags |= MSG_CTRUNC;
+
+	/*
+	 * All of the files that fit in the message have had their
+	 * usage counts incremented, so we just free the list.
+	 */
+	__scm_destroy(scm);
+}
+
+/* In these cases we (currently) can just copy to data over verbatim
+ * because all CMSGs created by the kernel have well defined types which
+ * have the same layout in both the 32-bit and 64-bit API.  One must add
+ * some special cased conversions here if we start sending control messages
+ * with incompatible types.
+ *
+ * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
+ * we do our work.  The remaining cases are:
+ *
+ * SOL_IP	IP_PKTINFO	struct in_pktinfo	32-bit clean
+ *		IP_TTL		int			32-bit clean
+ *		IP_TOS		__u8			32-bit clean
+ *		IP_RECVOPTS	variable length		32-bit clean
+ *		IP_RETOPTS	variable length		32-bit clean
+ *		(these last two are clean because the types are defined
+ *		 by the IPv4 protocol)
+ *		IP_RECVERR	struct sock_extended_err +
+ *				struct sockaddr_in	32-bit clean
+ * SOL_IPV6	IPV6_RECVERR	struct sock_extended_err +
+ *				struct sockaddr_in6	32-bit clean
+ *		IPV6_PKTINFO	struct in6_pktinfo	32-bit clean
+ *		IPV6_HOPLIMIT	int			32-bit clean
+ *		IPV6_FLOWINFO	u32			32-bit clean
+ *		IPV6_HOPOPTS	ipv6 hop exthdr		32-bit clean
+ *		IPV6_DSTOPTS	ipv6 dst exthdr(s)	32-bit clean
+ *		IPV6_RTHDR	ipv6 routing exthdr	32-bit clean
+ *		IPV6_AUTHHDR	ipv6 auth exthdr	32-bit clean
+ */
+static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
+{
+	unsigned char *workbuf, *wp;
+	unsigned long bufsz, space_avail;
+	struct cmsghdr *ucmsg;
+
+	bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
+	space_avail = kmsg->msg_controllen + bufsz;
+	wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
+	if(workbuf == NULL)
+		goto fail;
+
+	/* To make this more sane we assume the kernel sends back properly
+	 * formatted control messages.  Because of how the kernel will truncate
+	 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
+	 */
+	ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
+	while(((unsigned long)ucmsg) <=
+	      (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
+		struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
+		int clen64, clen32;
+
+		/* UCMSG is the 64-bit format CMSG entry in user-space.
+		 * KCMSG32 is within the kernel space temporary buffer
+		 * we use to convert into a 32-bit style CMSG.
+		 */
+		__get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
+		__get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
+		__get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
+
+		clen64 = kcmsg32->cmsg_len;
+		copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
+			       clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
+		clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
+			  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
+		kcmsg32->cmsg_len = clen32;
+
+		switch (kcmsg32->cmsg_type) {
+			/*
+			 * The timestamp type's data needs to be converted
+			 * from 64-bit time values to 32-bit time values
+			 */
+		case SO_TIMESTAMP: {
+			__kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32);
+			__kernel_time_t*   ptr_time   = CMSG_DATA(ucmsg);
+			*ptr_time32     = *ptr_time;
+			*(ptr_time32+1) = *(ptr_time+1);
+			kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) -
+						sizeof(__kernel_time_t32));
+		}
+		default:;
+		}
+
+		ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
+		wp = (((char *)kcmsg32) + CMSG32_ALIGN(kcmsg32->cmsg_len));
+	}
+
+	/* Copy back fixed up data, and adjust pointers. */
+	bufsz = (wp - workbuf);
+	copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
+
+	kmsg->msg_control = (struct cmsghdr *)
+		(((char *)orig_cmsg_uptr) + bufsz);
+	kmsg->msg_controllen = space_avail - bufsz;
+
+	kfree(workbuf);
+	return;
+
+fail:
+	/* If we leave the 64-bit format CMSG chunks in there,
+	 * the application could get confused and crash.  So to
+	 * ensure greater recovery, we report no CMSGs.
+	 */
+	kmsg->msg_controllen += bufsz;
+	kmsg->msg_control = (void *) orig_cmsg_uptr;
+}
+
+asmlinkage long sys32_recvmsg(int fd, struct msghdr32* user_msg, unsigned int user_flags)
+{
+	struct iovec iovstack[UIO_FASTIOV];
+	struct msghdr kern_msg;
+	char addr[MAX_SOCK_ADDR];
+	struct socket *sock;
+	struct iovec *iov = iovstack;
+	struct sockaddr *uaddr;
+	int *uaddr_len;
+	unsigned long cmsg_ptr;
+	int err, total_len, len = 0;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_recvmsg - entered - fd=%x, user_msg@=%p, user_flags=%x \n", fd, user_msg, user_flags);
+
+	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
+		return -EFAULT;
+	if(kern_msg.msg_iovlen > UIO_MAXIOV)
+		return -EINVAL;
+
+	uaddr = kern_msg.msg_name;
+	uaddr_len = &user_msg->msg_namelen;
+	err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
+	if (err < 0)
+		goto out;
+	total_len = err;
+
+	cmsg_ptr = (unsigned long) kern_msg.msg_control;
+	kern_msg.msg_flags = 0;
+
+	sock = sockfd_lookup(fd, &err);
+	if (sock != NULL) {
+		struct scm_cookie scm;
+
+		if (sock->file->f_flags & O_NONBLOCK)
+			user_flags |= MSG_DONTWAIT;
+		memset(&scm, 0, sizeof(scm));
+		err = sock->ops->recvmsg(sock, &kern_msg, total_len,
+					 user_flags, &scm);
+		if(err >= 0) {
+			len = err;
+			if(!kern_msg.msg_control) {
+				if(sock->passcred || scm.fp)
+					kern_msg.msg_flags |= MSG_CTRUNC;
+				if(scm.fp)
+					__scm_destroy(&scm);
+			} else {
+				/* If recvmsg processing itself placed some
+				 * control messages into user space, it's is
+				 * using 64-bit CMSG processing, so we need
+				 * to fix it up before we tack on more stuff.
+				 */
+				if((unsigned long) kern_msg.msg_control != cmsg_ptr)
+					cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
+
+				/* Wheee... */
+				if(sock->passcred)
+					put_cmsg32(&kern_msg,
+						   SOL_SOCKET, SCM_CREDENTIALS,
+						   sizeof(scm.creds), &scm.creds);
+				if(scm.fp != NULL)
+					scm_detach_fds32(&kern_msg, &scm);
+			}
+		}
+		sockfd_put(sock);
+	}
+
+  if (uaddr != NULL && err >= 0 && kern_msg.msg_namelen)
+		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
+	if(cmsg_ptr != 0 && err >= 0) {
+		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
+		__kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
+		err |= __put_user(uclen, &user_msg->msg_controllen);
+	}
+	if(err >= 0)
+		err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
+	if(kern_msg.msg_iov != iov)
+		kfree(kern_msg.msg_iov);
+out:
+	if(err < 0)
+		return err;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_recvmsg - exited w/ %lx \n", len);
+	return len;
+}
+
+/*
+ * count32() counts the number of arguments/envelopes
+ */
+static int count32(u32 * argv, int max)
+{
+	int i = 0;
+
+	if (argv != NULL) {
+		for (;;) {
+			u32 p; int error;
+
+			error = get_user(p,argv);
+			if (error)
+				return error;
+			if (!p)
+				break;
+			argv++;
+			if (++i > max)
+				return -E2BIG;
+		}
+	}
+	return i;
+}
+
+/*
+ * 'copy_string32()' copies argument/envelope strings from user
+ * memory to free pages in kernel mem. These are in a format ready
+ * to be put directly into the top of new user memory.
+ */
+static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
+{
+	while (argc-- > 0) {
+		u32 str;
+		int len;
+		unsigned long pos;
+
+		if (get_user(str, argv + argc) ||
+		    !str ||
+		    !(len = strnlen_user((char *)A(str), bprm->p)))
+			return -EFAULT;
+
+		if (bprm->p < len)
+			return -E2BIG;
+
+		bprm->p -= len;
+
+		pos = bprm->p;
+		while (len) {
+			char *kaddr;
+			struct page *page;
+			int offset, bytes_to_copy, new, err;
+
+			offset = pos % PAGE_SIZE;
+			page = bprm->page[pos / PAGE_SIZE];
+			new = 0;
+			if (!page) {
+				page = alloc_page(GFP_USER);
+				bprm->page[pos / PAGE_SIZE] = page;
+				if (!page)
+					return -ENOMEM;
+				new = 1;
+			}
+			kaddr = (char *)kmap(page);
+
+			if (new && offset)
+				memset(kaddr, 0, offset);
+			bytes_to_copy = PAGE_SIZE - offset;
+			if (bytes_to_copy > len) {
+				bytes_to_copy = len;
+				if (new)
+					memset(kaddr+offset+len, 0,
+					       PAGE_SIZE-offset-len);
+			}
+
+			err = copy_from_user(kaddr + offset, (char *)A(str),
+					     bytes_to_copy);
+			flush_page_to_ram(page);
+			kunmap((unsigned long)kaddr);
+
+			if (err)
+				return -EFAULT;
+
+			pos += bytes_to_copy;
+			str += bytes_to_copy;
+			len -= bytes_to_copy;
+		}
+	}
+	return 0;
+}
+
+/*
+ * sys32_execve() executes a new program.
+ */
+static int do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
+{
+	struct linux_binprm bprm;
+	struct file * file;
+	int retval;
+	int i;
+
+	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
+	memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
+
+	file = open_exec(filename);
+
+	retval = PTR_ERR(file);
+	if (IS_ERR(file))
+		return retval;
+
+	bprm.file = file;
+	bprm.filename = filename;
+	bprm.sh_bang = 0;
+	bprm.loader = 0;
+	bprm.exec = 0;
+	if ((bprm.argc = count32(argv, bprm.p / sizeof(u32))) < 0) {
+		allow_write_access(file);
+		fput(file);
+		return bprm.argc;
+	}
+	if ((bprm.envc = count32(envp, bprm.p / sizeof(u32))) < 0) {
+		allow_write_access(file);
+		fput(file);
+		return bprm.argc;
+	}
+  
+	retval = prepare_binprm(&bprm);
+	if (retval < 0)
+		goto out;
+	
+	retval = copy_strings_kernel(1, &bprm.filename, &bprm);
+	if (retval < 0)
+		goto out;
+
+	bprm.exec = bprm.p;
+	retval = copy_strings32(bprm.envc, envp, &bprm);
+	if (retval < 0)
+		goto out;
+
+	retval = copy_strings32(bprm.argc, argv, &bprm);
+	if (retval < 0)
+		goto out;
+
+	retval = search_binary_handler(&bprm, regs);
+	if (retval >= 0)
+		/* execve success */
+		return retval;
+
+out:
+	/* Something went wrong, return the inode and free the argument pages*/
+	allow_write_access(bprm.file);
+	if (bprm.file)
+		fput(bprm.file);
+
+	for (i=0 ; i<MAX_ARG_PAGES ; i++)
+		if (bprm.page[i])
+			__free_page(bprm.page[i]);
+
+	return retval;
+}
+
+asmlinkage long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+			                       unsigned long a3, unsigned long a4, unsigned long a5,
+			                       struct pt_regs *regs)
+{
+	int error;
+	char * filename;
+	
+	ifppcdebug(PPCDBG_SYS32) {
+		udbg_printf("sys32_execve - entered - pid=%ld, comm=%s \n", current->pid, current->comm);
+		//PPCDBG(PPCDBG_SYS32NI, "               a0=%lx, a1=%lx, a2=%lx, a3=%lx, a4=%lx, a5=%lx, regs=%p \n", a0, a1, a2, a3, a4, a5, regs);
+	}
+
+	filename = getname((char *) a0);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+
+	error = do_execve32(filename, (u32*) a1, (u32*) a2, regs);
+
+	if (error == 0)
+		current->ptrace &= ~PT_DTRACE;
+	putname(filename);
+
+out:
+	ifppcdebug(PPCDBG_SYS32) {
+		udbg_printf("sys32_execve - exited - returning %x - pid=%ld \n", error, current->pid);
+		//udbg_printf("sys32_execve - at exit - regs->gpr[1]=%lx, gpr[3]=%lx, gpr[4]=%lx, gpr[5]=%lx, gpr[6]=%lx \n", regs->gpr[1], regs->gpr[3], regs->gpr[4], regs->gpr[5], regs->gpr[6]);
+	}
+	return error;
+}
+
+/* Set up a thread for executing a new program. */
+void start_thread32(struct pt_regs* regs, unsigned long nip, unsigned long sp)
+{
+	set_fs(USER_DS);
+	memset(regs->gpr, 0, sizeof(regs->gpr));
+	memset(&regs->ctr, 0, 4 * sizeof(regs->ctr));
+	regs->nip = nip;
+	regs->gpr[1] = sp;
+	regs->msr = MSR_USER32;
+	if (last_task_used_math == current)
+		last_task_used_math = 0;
+	current->thread.fpscr = 0;
+}
+
+extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
+				unsigned long arg4, unsigned long arg5);
+
+/* Note: it is necessary to treat option as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
+{
+	PPCDBG(PPCDBG_SYS32, "sys32_prctl - running - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return sys_prctl((int)option,
+			 (unsigned long) arg2,
+			 (unsigned long) arg3,
+			 (unsigned long) arg4,
+			 (unsigned long) arg5);
+}
+
+extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
+
+/* Note: it is necessary to treat pid as an unsigned int, 
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage int sys32_sched_rr_get_interval(u32 pid, struct timespec32 *interval)
+{
+	struct timespec t;
+	int ret;
+	mm_segment_t old_fs = get_fs ();
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sched_rr_get_interval - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	
+	set_fs (KERNEL_DS);
+	ret = sys_sched_rr_get_interval((int)pid, &t);
+	set_fs (old_fs);
+	if (put_user (t.tv_sec, &interval->tv_sec) ||
+	    __put_user (t.tv_nsec, &interval->tv_nsec))
+		return -EFAULT;
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_sched_rr_get_interval - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	return ret;
+}
+
+extern asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, unsigned long off,
+					 unsigned long len, unsigned char *buf);
+
+asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
+{
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_pciconfig_read - running - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
+
+	return sys_pciconfig_read((unsigned long) bus,
+				  (unsigned long) dfn,
+				  (unsigned long) off,
+				  (unsigned long) len,
+				  (unsigned char *)AA(ubuf));
+}
+
+
+
+
+extern asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn, unsigned long off,
+					                                unsigned long len, unsigned char *buf);
+
+asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
+{
+	
+	PPCDBG(PPCDBG_SYS32, "sys32_pciconfig_write - running - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	return sys_pciconfig_write((unsigned long) bus,
+				   (unsigned long) dfn,
+				   (unsigned long) off,
+				   (unsigned long) len,
+				   (unsigned char *)AA(ubuf));
+}
+
+extern asmlinkage int sys_newuname(struct new_utsname * name);
+
+asmlinkage int ppc64_newuname(struct new_utsname * name)
+{
+	int errno = sys_newuname(name);
+
+	if (current->personality == PER_LINUX32 && !errno) {
+		if(copy_to_user(name->machine, "ppc\0\0", 8)) {
+			errno = -EFAULT;
+		}
+	}
+	return errno;
+}
+
+extern asmlinkage long sys_personality(unsigned long);
+
+asmlinkage int sys32_personality(unsigned long personality)
+{
+	int ret;
+	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
+		personality = PER_LINUX32;
+	ret = sys_personality(personality);
+	if (ret == PER_LINUX32)
+		ret = PER_LINUX;
+	return ret;
+}
+
+
+
+extern asmlinkage long sys_access(const char * filename, int mode);
+
+/* Note: it is necessary to treat mode as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_access(const char * filename, u32 mode)
+{
+	return sys_access(filename, (int)mode);
+}
+
+
+extern asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs);
+
+/* Note: it is necessary to treat p1, p2, p3, p4, p5, p7, and regs as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage int sys32_clone(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, struct pt_regs *regs)
+{
+	return sys_clone((int)p1, (int)p2, (int)p3, (int)p4, (int)p5, (int)p6, regs);
+}
+
+
+extern asmlinkage long sys_creat(const char * pathname, int mode);
+
+/* Note: it is necessary to treat mode as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_creat(const char * pathname, u32 mode)
+{
+	return sys_creat(pathname, (int)mode);
+}
+
+
+extern asmlinkage long sys_exit(int error_code);
+
+/* Note: it is necessary to treat error_code as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_exit(u32 error_code)
+{
+	return sys_exit((int)error_code);
+}
+
+
+extern asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options, struct rusage * ru);
+
+/* Note: it is necessary to treat pid and options as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_wait4(u32 pid, unsigned int * stat_addr, u32 options, struct rusage * ru)
+{
+        PPCDBG(PPCDBG_SYS32, "sys32_wait4 - running - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	if (!ru)
+		return sys_wait4((int)pid, stat_addr, options, NULL);
+	else {
+		struct rusage r;
+		int ret;
+		unsigned int status;
+		mm_segment_t old_fs = get_fs();
+		
+		set_fs (KERNEL_DS);
+		ret = sys_wait4((int)pid, stat_addr ? &status : NULL, options, &r);
+		set_fs (old_fs);
+		if (put_rusage ((struct rusage32 *)ru, &r)) return -EFAULT;
+		if (stat_addr && put_user (status, stat_addr))
+			return -EFAULT;
+		return ret;
+	}
+	
+}
+
+
+extern asmlinkage long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
+
+/* Note: it is necessary to treat pid and options as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_waitpid(u32 pid, unsigned int * stat_addr, u32 options)
+{
+	return sys_waitpid((int)pid, stat_addr, (int)options);
+}
+
+
+extern asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs);
+
+/* Note: it is necessary to treat p1, p2, p3, p4, p5, and p6 as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage int sys32_fork(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, struct pt_regs *regs)
+{
+	return sys_fork((int)p1, (int)p2, (int)p3, (int)p4, (int)p5, (int)p6, regs);
+}
+
+
+extern asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist);
+
+/* Note: it is necessary to treat gidsetsize as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t *grouplist)
+{
+	return sys_getgroups((int)gidsetsize, grouplist);
+}
+
+
+extern asmlinkage long sys_getpgid(pid_t pid);
+
+/* Note: it is necessary to treat pid as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_getpgid(u32 pid)
+{
+	return sys_getpgid((int)pid);
+}
+
+
+extern asmlinkage long sys_getpriority(int which, int who);
+
+/* Note: it is necessary to treat which and who as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_getpriority(u32 which, u32 who)
+{
+	return sys_getpriority((int)which, (int)who);
+}
+
+
+extern asmlinkage long sys_getsid(pid_t pid);
+
+/* Note: it is necessary to treat pid as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_getsid(u32 pid)
+{
+	return sys_getsid((int)pid);
+}
+
+
+extern asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
+
+/* Note: it is necessary to treat on as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_ioperm(unsigned long from, unsigned long num, u32 on)
+{
+	return sys_ioperm(from, num, (int)on);
+}
+
+
+extern asmlinkage int sys_iopl(int a1, int a2, int a3, int a4);
+
+/* Note: it is necessary to treat a1, a2, a3, and a4 as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage int sys32_iopl(u32 a1, u32 a2, u32 a3, u32 a4)
+{
+	return sys_iopl((int)a1, (int)a2, (int)a3, (int)a4);
+}
+
+
+extern asmlinkage long sys_kill(int pid, int sig);
+
+/* Note: it is necessary to treat pid and sig as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_kill(u32 pid, u32 sig)
+{
+	return sys_kill((int)pid, (int)sig);
+}
+
+
+extern asmlinkage long sys_mkdir(const char * pathname, int mode);
+
+/* Note: it is necessary to treat mode as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_mkdir(const char * pathname, u32 mode)
+{
+	return sys_mkdir(pathname, (int)mode);
+}
+
+
+extern asmlinkage long sys_mlockall(int flags);
+
+/* Note: it is necessary to treat flags as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_mlockall(u32 flags)
+{
+	return sys_mlockall((int)flags);
+}
+
+
+extern asmlinkage int sys_modify_ldt(int a1, int a2, int a3, int a4);
+
+/* Note: it is necessary to treat a1, a2, a3, and a4 as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage int sys32_modify_ldt(u32 a1, u32 a2, u32 a3, u32 a4)
+{
+	return sys_modify_ldt((int)a1, (int)a2, (int)a3, (int)a4);
+}
+
+
+extern asmlinkage long sys_msync(unsigned long start, size_t len, int flags);
+
+/* Note: it is necessary to treat flags as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_msync(unsigned long start, size_t len, u32 flags)
+{
+	return sys_msync(start, len, (int)flags);
+}
+
+
+extern asmlinkage long sys_nice(int increment);
+
+/* Note: it is necessary to treat increment as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_nice(u32 increment)
+{
+	return sys_nice((int)increment);
+}
+
+
+extern asmlinkage long sys_open(const char * filename, int flags, int mode);
+
+/* Note: it is necessary to treat flags and mode as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_open(const char * filename, int flags, int mode)
+{
+	return sys_open(filename, (int)flags, (int)mode);
+}
+
+
+extern asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz);
+
+/* Note: it is necessary to treat bufsiz as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_readlink(const char * path, char * buf, u32 bufsiz)
+{
+	return sys_readlink(path, buf, (int)bufsiz);
+}
+
+
+extern asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void * arg);
+
+/* Note: it is necessary to treat magic1 and magic2 as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_reboot(u32 magic1, u32 magic2, unsigned int cmd, void * arg)
+{
+	return sys_reboot((int)magic1, (int)magic2, cmd, arg);
+}
+
+
+extern asmlinkage long sys_sched_get_priority_max(int policy);
+
+/* Note: it is necessary to treat option as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sched_get_priority_max(u32 policy)
+{
+	return sys_sched_get_priority_max((int)policy);
+}
+
+
+extern asmlinkage long sys_sched_get_priority_min(int policy);
+
+/* Note: it is necessary to treat policy as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sched_get_priority_min(u32 policy)
+{
+	return sys_sched_get_priority_min((int)policy);
+}
+
+
+extern asmlinkage long sys_sched_getparam(pid_t pid, struct sched_param *param);
+
+/* Note: it is necessary to treat pid as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param *param)
+{
+	return sys_sched_getparam((int)pid, param);
+}
+
+
+extern asmlinkage long sys_sched_getscheduler(pid_t pid);
+
+/* Note: it is necessary to treat pid as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sched_getscheduler(u32 pid)
+{
+	return sys_sched_getscheduler((int)pid);
+}
+
+
+extern asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param *param);
+
+/* Note: it is necessary to treat pid as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param *param)
+{
+	return sys_sched_setparam((int)pid, param);
+}
+
+
+extern asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, struct sched_param *param);
+
+/* Note: it is necessary to treat pid and policy as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param *param)
+{
+	return sys_sched_setscheduler((int)pid, (int)policy, param);
+}
+
+
+extern asmlinkage long sys_setdomainname(char *name, int len);
+
+/* Note: it is necessary to treat len as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_setdomainname(char *name, u32 len)
+{
+	return sys_setdomainname(name, (int)len);
+}
+
+
+extern asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist);
+
+/* Note: it is necessary to treat gidsetsize as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_setgroups(u32 gidsetsize, gid_t *grouplist)
+{
+	return sys_setgroups((int)gidsetsize, grouplist);
+}
+
+
+extern asmlinkage long sys_sethostname(char *name, int len);
+
+/* Note: it is necessary to treat len as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_sethostname(char *name, u32 len)
+{
+	return sys_sethostname(name, (int)len);
+}
+
+
+extern asmlinkage long sys_setpgid(pid_t pid, pid_t pgid);
+
+/* Note: it is necessary to treat pid and pgid as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_setpgid(u32 pid, u32 pgid)
+{
+	return sys_setpgid((int)pid, (int)pgid);
+}
+
+
+extern asmlinkage long sys_setpriority(int which, int who, int niceval);
+
+/* Note: it is necessary to treat which, who, and niceval as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_setpriority(u32 which, u32 who, u32 niceval)
+{
+	return sys_setpriority((int)which, (int)who, (int)niceval);
+}
+
+
+extern asmlinkage long sys_ssetmask(int newmask);
+
+/* Note: it is necessary to treat newmask as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_ssetmask(u32 newmask)
+{
+	return sys_ssetmask((int) newmask);
+}
+
+
+extern asmlinkage long sys_swapon(const char * specialfile, int swap_flags);
+
+/* Note: it is necessary to treat swap_flags as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_swapon(const char * specialfile, u32 swap_flags)
+{
+	return sys_swapon(specialfile, (int)swap_flags);
+}
+
+
+extern asmlinkage long sys_syslog(int type, char * buf, int len);
+
+/* Note: it is necessary to treat type and len as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_syslog(u32 type, char * buf, u32 len)
+{
+	return sys_syslog((int)type, buf, (int)len);
+}
+
+
+extern asmlinkage long sys_umask(int mask);
+
+/* Note: it is necessary to treat mask as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_umask(u32 mask)
+{
+	return sys_umask((int)mask);
+}
+
+
+extern asmlinkage long sys_umount(char * name, int flags);
+
+/* Note: it is necessary to treat flags as an unsigned int,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage long sys32_umount(char * name, u32 flags)
+{
+	return sys_umount(name, (int)flags);
+}
+
+
+extern asmlinkage int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs);
+
+/* Note: it is necessary to treat p1, p2, p3, p4, p5, and p6 as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage int sys32_vfork(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, struct pt_regs *regs)
+{
+	return sys_vfork((int)p1, (int)p2, (int)p3, (int)p4, (int)p5, (int)p6, regs);
+}
+
+
+extern asmlinkage int sys_vm86(int a1, int a2, int a3, int a4);
+
+/* Note: it is necessary to treat a1, a2, a3, and a4 as unsigned ints,
+ * with the corresponding cast to a signed int to insure that the 
+ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+ * and the register representation of a signed int (msr in 64-bit mode) is performed.
+ */
+asmlinkage int sys32_vm86(u32 a1, u32 a2, u32 a3, u32 a4)
+{
+	return sys_vm86((int)a1, (int)a2, (int)a3, (int)a4);
+}
+
+
+
+
+
+extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
+				    size_t count, loff_t pos);
+
+extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
+				     size_t count, loff_t pos);
+
+typedef __kernel_ssize_t32 ssize_t32;
+
+asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
+				 __kernel_size_t32 count, u32 reg6, u32 poshi, u32 poslo)
+{
+	return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
+}
+
+asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
+				  __kernel_size_t32 count, u32 reg6 ,u32 poshi, u32 poslo)
+{
+	return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
+}
+
+
+extern asmlinkage long sys_truncate(const char * path, unsigned long length);
+extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
+
+asmlinkage int sys32_truncate64(const char * path, u32 reg4, unsigned long high, unsigned long low)
+{
+     	if ((int)high < 0)
+		return -EINVAL;
+	else
+		return sys_truncate(path, (high << 32) | low);
+}
+
+asmlinkage int sys32_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, unsigned long low)
+{
+     	if ((int)high < 0)
+		return -EINVAL;
+	else
+		return sys_ftruncate(fd, (high << 32) | low);
+}
+
+
+
+asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+     	if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
+		return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg);
+	return sys32_fcntl(fd, cmd, arg);
+}
+
+
+
+
+struct __sysctl_args32 {
+	u32 name;
+	int nlen;
+	u32 oldval;
+	u32 oldlenp;
+	u32 newval;
+	u32 newlen;
+	u32 __unused[4];
+};
+
+extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
+{
+	struct __sysctl_args32 tmp;
+	int error;
+	size_t oldlen, *oldlenp = NULL;
+	unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
+
+	if (copy_from_user(&tmp, args, sizeof(tmp)))
+		return -EFAULT;
+
+	if (tmp.oldval && tmp.oldlenp) {
+		/* Duh, this is ugly and might not work if sysctl_args
+		   is in read-only memory, but do_sysctl does indirectly
+		   a lot of uaccess in both directions and we'd have to
+		   basically copy the whole sysctl.c here, and
+		   glibc's __sysctl uses rw memory for the structure
+		   anyway.  */
+		if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
+		    put_user(oldlen, (size_t *)addr))
+			return -EFAULT;
+		oldlenp = (size_t *)addr;
+	}
+
+	lock_kernel();
+	error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
+			  oldlenp, (void *)A(tmp.newval), tmp.newlen);
+	unlock_kernel();
+	if (oldlenp) {
+		if (!error) {
+			if (get_user(oldlen, (size_t *)addr) ||
+			    put_user(oldlen, (u32 *)A(tmp.oldlenp)))
+				error = -EFAULT;
+		}
+		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
+	}
+	return error;
+}
+
+asmlinkage long sys32_time(__kernel_time_t32* tloc)
+{
+	__kernel_time_t32 secs;
+
+	struct timeval tv;
+
+	do_gettimeofday( &tv );
+	secs = tv.tv_sec;
+
+	if (tloc) {
+		if (put_user(secs,tloc))
+			secs = -EFAULT;
+	}
+
+	return secs;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/syscalls.c linux/arch/ppc64/kernel/syscalls.c
--- linux.orig/arch/ppc64/kernel/syscalls.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/syscalls.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,316 @@
+/*
+ * linux/arch/ppc/kernel/sys_ppc.c
+ *
+ *  PowerPC version 
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Derived from "arch/i386/kernel/sys_i386.c"
+ * Adapted from the i386 version by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@cs.anu.edu.au).
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/PPC
+ * platform.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/ipc.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+#include <linux/init.h>
+#include <linux/personality.h>
+
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/semaphore.h>
+#include <asm/ppcdebug.h>
+
+#include <asm/time.h>
+
+extern unsigned long wall_jiffies;
+#define USEC_PER_SEC (1000000)
+
+void
+check_bugs(void)
+{
+}
+
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+{
+	printk(KERN_ERR "sys_ioperm()\n");
+	return -EIO;
+}
+
+int sys_iopl(int a1, int a2, int a3, int a4)
+{
+	printk(KERN_ERR "sys_iopl(%x, %x, %x, %x)!\n", a1, a2, a3, a4);
+	return (-ENOSYS);
+}
+
+int sys_vm86(int a1, int a2, int a3, int a4)
+{
+	printk(KERN_ERR "sys_vm86(%x, %x, %x, %x)!\n", a1, a2, a3, a4);
+	return (-ENOSYS);
+}
+
+int sys_modify_ldt(int a1, int a2, int a3, int a4)
+{
+	printk(KERN_ERR "sys_modify_ldt(%x, %x, %x, %x)!\n", a1, a2, a3, a4);
+	return (-ENOSYS);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int 
+sys_ipc (uint call, int first, int second, long third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	PPCDBG(PPCDBG_SYS64X, "sys_ipc - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	ret = -EINVAL;
+	switch (call) {
+	case SEMOP:
+		ret = sys_semop (first, (struct sembuf *)ptr, second);
+		break;
+	case SEMGET:
+		ret = sys_semget (first, second, third);
+		break;
+	case SEMCTL: {
+		union semun fourth;
+
+		if (!ptr)
+			break;
+		if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long)))
+		    || (ret = get_user(fourth.__pad, (void **)ptr)))
+			break;
+		ret = sys_semctl (first, second, third, fourth);
+		break;
+	}
+	case MSGSND:
+		ret = sys_msgsnd (first, (struct msgbuf *) ptr, second, third);
+		break;
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+
+			if (!ptr)
+				break;
+			if ((ret = verify_area (VERIFY_READ, ptr, sizeof(tmp)))
+			    || (ret = copy_from_user(&tmp,
+						(struct ipc_kludge *) ptr,
+						sizeof (tmp))))
+				break;
+			ret = sys_msgrcv (first, (struct msgbuf *)(unsigned long)tmp.msgp,
+						second, tmp.msgtyp, third);
+			break;
+		}
+		default:
+			ret = sys_msgrcv (first, (struct msgbuf *) ptr,
+					  second, fifth, third);
+			break;
+		}
+		break;
+	case MSGGET:
+		ret = sys_msgget ((key_t) first, second);
+		break;
+	case MSGCTL:
+		ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
+		break;
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+
+			if ((ret = verify_area(VERIFY_WRITE, (ulong*) third,
+					       sizeof(ulong))))
+				break;
+			ret = sys_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				break;
+			ret = put_user (raddr, (ulong *) third);
+			break;
+		}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				break;
+			ret = sys_shmat (first, (char *) ptr, second,
+					 (ulong *) third);
+			break;
+		}
+		break;
+	case SHMDT: 
+		ret = sys_shmdt ((char *)ptr);
+		break;
+	case SHMGET:
+		ret = sys_shmget (first, second, third);
+		break;
+	case SHMCTL:
+		ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
+		break;
+	}
+
+	PPCDBG(PPCDBG_SYS64X, "sys_ipc - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	return ret;
+}
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(int *fildes)
+{
+	int fd[2];
+	int error;
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_pipe - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_pipe - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	return error;
+}
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
+				  unsigned long prot, unsigned long flags,
+				  unsigned long fd, off_t offset)
+{
+	struct file * file = NULL;
+	unsigned long ret = -EBADF;
+
+	PPCDBG(PPCDBG_SYS64X, "sys_mmap - entered - addr=%lx, len=%lx - pid=%ld, comm=%s \n", addr, len, current->pid, current->comm);
+	
+	if (!(flags & MAP_ANONYMOUS)) {
+		if (!(file = fget(fd)))
+			goto out;
+	}
+	
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	down_write(&current->mm->mmap_sem);
+	ret = do_mmap(file, addr, len, prot, flags, offset);
+	up_write(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+
+out:
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_mmap - exited - ret=%x \n", ret);
+	
+	return ret;
+}
+
+asmlinkage int sys_pause(void)
+{
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_pause - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_pause - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	return -ERESTARTNOHAND;
+}
+
+static int __init set_fakeppc(char *str)
+{
+	if (*str)
+		return 0;
+	init_task.personality = PER_LINUX32;
+	return 1;
+}
+__setup("fakeppc", set_fakeppc);
+
+asmlinkage int sys_uname(struct old_utsname * name)
+{
+	int err = -EFAULT;
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_uname - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	down_read(&uts_sem);
+	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+		err = 0;
+	up_read(&uts_sem);
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_uname - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	return err;
+}
+
+asmlinkage int sys_olduname(struct oldold_utsname * name)
+{
+	int error;
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_olduname - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+
+	if (!name)
+		return -EFAULT;
+	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+		return -EFAULT;
+  
+	down_read(&uts_sem);
+	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
+	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+	error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+	error -= __put_user(0,name->release+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+	error -= __put_user(0,name->version+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+	error = __put_user(0,name->machine+__OLD_UTS_LEN);
+	up_read(&uts_sem);
+
+	error = error ? -EFAULT : 0;
+	
+	PPCDBG(PPCDBG_SYS64X, "sys_olduname - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
+	return error;
+}
+
+asmlinkage time_t sys64_time(time_t* tloc)
+{
+	time_t secs;
+	time_t usecs;
+
+	long tb_delta = tb_ticks_since(tb_last_stamp);
+	tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
+
+	secs  = xtime.tv_sec;  
+	usecs = xtime.tv_usec + tb_delta / tb_ticks_per_usec;
+	while (usecs >= USEC_PER_SEC) {
+		++secs;
+		usecs -= USEC_PER_SEC;
+	}
+
+	if (tloc) {
+		if (put_user(secs,tloc))
+			secs = -EFAULT;
+	}
+
+	return secs;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/time.c linux/arch/ppc64/kernel/time.c
--- linux.orig/arch/ppc64/kernel/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/time.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,754 @@
+/*
+ * 
+ * Common time routines among all ppc machines.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) to merge
+ * Paul Mackerras' version and mine for PReP and Pmac.
+ * MPC8xx/MBX changes by Dan Malek (dmalek@jlc.net).
+ * Converted for 64-bit by Mike Corrigan (mikejc@us.ibm.com)
+ *
+ * First round of bugfixes by Gabriel Paubert (paubert@iram.es)
+ * to make clock more stable (2.4.0-test5). The only thing
+ * that this code assumes is that the timebases have been synchronized
+ * by firmware on SMP and are never stopped (never do sleep
+ * on SMP then, nap and doze are OK).
+ * 
+ * Speeded up do_gettimeofday by getting rid of references to
+ * xtime (which required locks for consistency). (mikejc@us.ibm.com)
+ *
+ * TODO (not necessarily in this file):
+ * - improve precision and reproducibility of timebase frequency
+ * measurement at boot time. (for iSeries, we calibrate the timebase
+ * against the Titan chip's clock.)
+ * - for astronomical applications: add a new function to get
+ * non ambiguous timestamps even around leap seconds. This needs
+ * a new timestamp format and a good name.
+ *
+ * 1997-09-10  Updated NTP code according to technical memorandum Jan '96
+ *             "A Kernel Model for Precision Timekeeping" by Dave Mills
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/kernel_stat.h>
+#include <linux/mc146818rtc.h>
+#include <linux/time.h>
+#include <linux/init.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/nvram.h>
+#include <asm/cache.h>
+#include <asm/machdep.h>
+#include <asm/init.h>
+#ifdef CONFIG_PPC_ISERIES
+#include <asm/iSeries/HvCallXm.h>
+#endif
+#include <asm/uaccess.h>
+
+#include <asm/time.h>
+#include <asm/ppcdebug.h>
+
+void smp_local_timer_interrupt(struct pt_regs *);
+
+/* keep track of when we need to update the rtc */
+time_t last_rtc_update;
+extern rwlock_t xtime_lock;
+extern int piranha_simulator;
+#ifdef CONFIG_PPC_ISERIES
+unsigned long iSeries_recal_titan = 0;
+unsigned long iSeries_recal_tb = 0; 
+static unsigned long first_settimeofday = 1;
+#endif
+
+#define XSEC_PER_SEC (1024*1024)
+#define USEC_PER_SEC (1000000)
+
+unsigned long tb_ticks_per_jiffy;
+unsigned long tb_ticks_per_usec;
+unsigned long tb_ticks_per_sec;
+unsigned long next_xtime_sync_tb;
+unsigned long xtime_sync_interval;
+unsigned long tb_to_xs;
+unsigned      tb_to_us;
+unsigned long processor_freq;
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+
+struct gettimeofday_struct do_gtod;
+
+extern unsigned long wall_jiffies;
+extern unsigned long lpEvent_count;
+extern int smp_tb_synchronized;
+
+extern unsigned long prof_cpu_mask;
+extern unsigned int * prof_buffer;
+extern unsigned long prof_len;
+extern unsigned long prof_shift;
+extern char _stext;
+
+void ppc_adjtimex(void);
+
+static unsigned adjusting_time = 0;
+
+static inline void ppc_do_profile (unsigned long nip)
+{
+	if (!prof_buffer)
+		return;
+
+	/*
+	 * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
+	 * (default is all CPUs.)
+	 */
+	if (!((1<<smp_processor_id()) & prof_cpu_mask))
+		return;
+
+	nip -= (unsigned long) &_stext;
+	nip >>= prof_shift;
+	/*
+	 * Don't ignore out-of-bounds EIP values silently,
+	 * put them into the last histogram slot, so if
+	 * present, they will show up as a sharp peak.
+	 */
+	if (nip > prof_len-1)
+		nip = prof_len-1;
+	atomic_inc((atomic_t *)&prof_buffer[nip]);
+}
+
+
+static __inline__ void timer_check_rtc(void)
+{
+        /*
+         * update the rtc when needed, this should be performed on the
+         * right fraction of a second. Half or full second ?
+         * Full second works on mk48t59 clocks, others need testing.
+         * Note that this update is basically only used through 
+         * the adjtimex system calls. Setting the HW clock in
+         * any other way is a /dev/rtc and userland business.
+         * This is still wrong by -0.5/+1.5 jiffies because of the
+         * timer interrupt resolution and possible delay, but here we 
+         * hit a quantization limit which can only be solved by higher
+         * resolution timers and decoupling time management from timer
+         * interrupts. This is also wrong on the clocks
+         * which require being written at the half second boundary.
+         * We should have an rtc call that only sets the minutes and
+         * seconds like on Intel to avoid problems with non UTC clocks.
+         */
+        if ( (time_status & STA_UNSYNC) == 0 &&
+             xtime.tv_sec - last_rtc_update >= 659 &&
+             abs(xtime.tv_usec - (1000000-1000000/HZ)) < 500000/HZ &&
+             jiffies - wall_jiffies == 1) {
+	    struct rtc_time tm;
+	    to_tm(xtime.tv_sec+1, &tm);
+	    tm.tm_year -= 1900;
+	    tm.tm_mon -= 1;
+            if (ppc_md.set_rtc_time(&tm) == 0)
+                last_rtc_update = xtime.tv_sec+1;
+            else
+                /* Try again one minute later */
+                last_rtc_update += 60;
+        }
+}
+
+/* Synchronize xtime with do_gettimeofday */ 
+
+static __inline__ void timer_sync_xtime( unsigned long cur_tb )
+{
+	struct timeval my_tv;
+
+	if ( cur_tb > next_xtime_sync_tb ) {
+		next_xtime_sync_tb = cur_tb + xtime_sync_interval;
+		do_gettimeofday( &my_tv );
+		if ( xtime.tv_sec <= my_tv.tv_sec ) {
+			xtime.tv_sec = my_tv.tv_sec;
+			xtime.tv_usec = my_tv.tv_usec;
+		}
+	}
+}
+
+#ifdef CONFIG_PPC_ISERIES
+
+/* 
+ * This function recalibrates the timebase based on the 49-bit time-of-day value in the Titan chip.
+ * The Titan is much more accurate than the value returned by the service processor for the
+ * timebase frequency.  
+ */
+
+static void iSeries_tb_recal(void)
+{
+	struct div_result divres;
+	unsigned long titan, tb;
+	tb = get_tb();
+	titan = HvCallXm_loadTod();
+	if ( iSeries_recal_titan ) {
+		unsigned long tb_ticks = tb - iSeries_recal_tb;
+		unsigned long titan_usec = (titan - iSeries_recal_titan) >> 12;
+		unsigned long new_tb_ticks_per_sec   = (tb_ticks * USEC_PER_SEC)/titan_usec;
+		unsigned long new_tb_ticks_per_jiffy = (new_tb_ticks_per_sec+(HZ/2))/HZ;
+		long tick_diff = new_tb_ticks_per_jiffy - tb_ticks_per_jiffy;
+		char sign = '+';		
+		/* make sure tb_ticks_per_sec and tb_ticks_per_jiffy are consistent */
+		new_tb_ticks_per_sec = new_tb_ticks_per_jiffy * HZ;
+
+		if ( tick_diff < 0 ) {
+			tick_diff = -tick_diff;
+			sign = '-';
+		}
+		if ( tick_diff ) {
+			if ( tick_diff < tb_ticks_per_jiffy/25 ) {
+				printk( "Titan recalibrate: new tb_ticks_per_jiffy = %lu (%c%ld)\n",
+						new_tb_ticks_per_jiffy, sign, tick_diff );
+				tb_ticks_per_jiffy = new_tb_ticks_per_jiffy;
+				tb_ticks_per_sec   = new_tb_ticks_per_sec;
+				div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres );
+				do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
+				tb_to_xs = divres.result_low;
+				do_gtod.varp->tb_to_xs = tb_to_xs;
+			}
+			else {
+				printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
+					"                   new tb_ticks_per_jiffy = %lu\n"
+					"                   old tb_ticks_per_jiffy = %lu\n",
+					new_tb_ticks_per_jiffy, tb_ticks_per_jiffy );
+			}
+		}
+	}
+	iSeries_recal_titan = titan;
+	iSeries_recal_tb = tb;
+}
+#endif
+
+/*
+ * For iSeries shared processors, we have to let the hypervisor
+ * set the hardware decrementer.  We set a virtual decrementer
+ * in the ItLpPaca and call the hypervisor if the virtual
+ * decrementer is less than the current value in the hardware
+ * decrementer. (almost always the new decrementer value will
+ * be greater than the current hardware decementer so the hypervisor
+ * call will not be needed)
+ */
+
+unsigned long tb_last_stamp=0;
+
+/*
+ * timer_interrupt - gets called when the decrementer overflows,
+ * with interrupts disabled.
+ */
+int timer_interrupt(struct pt_regs * regs)
+{
+	int next_dec;
+	unsigned long cur_tb;
+	struct paca_struct *lpaca = get_paca();
+	unsigned long cpu = lpaca->xPacaIndex;
+	struct ItLpQueue * lpq;
+
+	irq_enter(cpu);
+
+#ifndef CONFIG_PPC_ISERIES
+	if (!user_mode(regs))
+		ppc_do_profile(instruction_pointer(regs));
+#endif
+
+	lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
+
+	while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) {
+
+#ifdef CONFIG_SMP
+		smp_local_timer_interrupt(regs);
+#endif
+		if (cpu == 0) {
+			write_lock(&xtime_lock);
+			tb_last_stamp = lpaca->next_jiffy_update_tb;
+			do_timer(regs);
+			timer_sync_xtime( cur_tb );
+			timer_check_rtc();
+			write_unlock(&xtime_lock);
+			if ( adjusting_time && (time_adjust == 0) )
+				ppc_adjtimex();
+		}
+		lpaca->next_jiffy_update_tb += tb_ticks_per_jiffy;
+	}
+	
+	next_dec = lpaca->next_jiffy_update_tb - cur_tb;
+	if (next_dec > lpaca->default_decr)
+        	next_dec = lpaca->default_decr;
+	set_dec(next_dec);
+
+	lpq = lpaca->lpQueuePtr;
+	if (lpq && ItLpQueue_isLpIntPending(lpq))
+		lpEvent_count += ItLpQueue_process(lpq, regs); 
+
+	irq_exit(cpu);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+	
+	return 1;
+}
+
+
+/*
+ * This version of gettimeofday has microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+        unsigned long sec, usec, tb_ticks;
+	unsigned long xsec, tb_xsec;
+	struct gettimeofday_vars * temp_varp;
+	unsigned long temp_tb_to_xs, temp_stamp_xsec;
+
+	/* These calculations are faster (gets rid of divides)
+	 * if done in units of 1/2^20 rather than microseconds.
+	 * The conversion to microseconds at the end is done
+	 * without a divide (and in fact, without a multiply) */
+	tb_ticks = get_tb() - do_gtod.tb_orig_stamp;
+	temp_varp = do_gtod.varp;
+	temp_tb_to_xs = temp_varp->tb_to_xs;
+	temp_stamp_xsec = temp_varp->stamp_xsec;
+	tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs );
+	xsec = temp_stamp_xsec + tb_xsec;
+	sec = xsec / XSEC_PER_SEC;
+	xsec -= sec * XSEC_PER_SEC;
+	usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC;
+
+        tv->tv_sec = sec;
+        tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+	unsigned long delta_xsec;
+	long int tb_delta, new_usec, new_sec;
+	unsigned long new_xsec;
+
+	write_lock_irqsave(&xtime_lock, flags);
+	/* Updating the RTC is not the job of this code. If the time is
+	 * stepped under NTP, the RTC will be update after STA_UNSYNC
+	 * is cleared. Tool like clock/hwclock either copy the RTC
+	 * to the system time, in which case there is no point in writing
+	 * to the RTC again, or write to the RTC but then they don't call
+	 * settimeofday to perform this operation.
+	 */
+#ifdef CONFIG_PPC_ISERIES
+	if ( first_settimeofday ) {
+		iSeries_tb_recal();
+		first_settimeofday = 0;
+	}
+#endif
+	tb_delta = tb_ticks_since(tb_last_stamp);
+	tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
+
+	new_sec = tv->tv_sec;
+	new_usec = tv->tv_usec - tb_delta / tb_ticks_per_usec;
+	while (new_usec <0) {
+		new_sec--; 
+		new_usec += USEC_PER_SEC;
+	}
+	xtime.tv_usec = new_usec;
+	xtime.tv_sec = new_sec;
+
+	/* In case of a large backwards jump in time with NTP, we want the 
+	 * clock to be updated as soon as the PLL is again in lock.
+	 */
+	last_rtc_update = new_sec - 658;
+
+	time_adjust = 0;                /* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
+	delta_xsec = mulhdu( (tb_last_stamp-do_gtod.tb_orig_stamp), do_gtod.varp->tb_to_xs );
+	new_xsec = (new_usec * XSEC_PER_SEC) / USEC_PER_SEC;
+	new_xsec += new_sec * XSEC_PER_SEC;
+	if ( new_xsec > delta_xsec ) {
+		do_gtod.varp->stamp_xsec = new_xsec - delta_xsec;
+	}
+	else {
+		/* This is only for the case where the user is setting the time
+		 * way back to a time such that the boot time would have been
+		 * before 1970 ... eg. we booted ten days ago, and we are setting
+		 * the time to Jan 5, 1970 */
+		do_gtod.varp->stamp_xsec = new_xsec;
+		do_gtod.tb_orig_stamp = tb_last_stamp;
+	}
+
+	write_unlock_irqrestore(&xtime_lock, flags);
+}
+
+/*
+ * This function is a copy of the architecture independent function
+ * but which calls do_settimeofday rather than setting the xtime
+ * fields itself.  This way, the fields which are used for 
+ * do_settimeofday get updated too.
+ */
+long ppc64_sys32_stime(int* tptr)
+{
+	int value;
+	struct timeval myTimeval;
+
+	if (!capable(CAP_SYS_TIME))
+		return -EPERM;
+
+	if (get_user(value, tptr))
+		return -EFAULT;
+
+	myTimeval.tv_sec = value;
+	myTimeval.tv_usec = 0;
+
+	do_settimeofday(&myTimeval);
+
+	return 0;
+}
+
+/*
+ * This function is a copy of the architecture independent function
+ * but which calls do_settimeofday rather than setting the xtime
+ * fields itself.  This way, the fields which are used for 
+ * do_settimeofday get updated too.
+ */
+long ppc64_sys_stime(long* tptr)
+{
+	long value;
+	struct timeval myTimeval;
+
+	if (!capable(CAP_SYS_TIME))
+		return -EPERM;
+
+	if (get_user(value, tptr))
+		return -EFAULT;
+
+	myTimeval.tv_sec = value;
+	myTimeval.tv_usec = 0;
+
+	do_settimeofday(&myTimeval);
+
+	return 0;
+}
+
+void __init time_init(void)
+{
+	/* This function is only called on the boot processor */
+	unsigned long flags;
+	struct rtc_time tm;
+
+	ppc_md.calibrate_decr();
+
+	if ( ! piranha_simulator ) {
+		ppc_md.get_boot_time(&tm);
+	}
+	write_lock_irqsave(&xtime_lock, flags);
+	xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+			      tm.tm_hour, tm.tm_min, tm.tm_sec);
+	tb_last_stamp = get_tb();
+	do_gtod.tb_orig_stamp = tb_last_stamp;
+	do_gtod.varp = &do_gtod.vars[0];
+	do_gtod.var_idx = 0;
+	do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
+	do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
+	do_gtod.varp->tb_to_xs = tb_to_xs;
+	do_gtod.tb_to_us = tb_to_us;
+
+	xtime_sync_interval = tb_ticks_per_sec - (tb_ticks_per_sec/8);
+	next_xtime_sync_tb = tb_last_stamp + xtime_sync_interval;
+
+	time_freq = 0;
+
+	xtime.tv_usec = 0;
+	last_rtc_update = xtime.tv_sec;
+	write_unlock_irqrestore(&xtime_lock, flags);
+
+#ifdef CONFIG_PPC_ISERIES
+	/* HACK HACK This allows the iSeries profiling to use /proc/profile */
+	prof_shift = 0;
+#endif
+
+	/* Not exact, but the timer interrupt takes care of this */
+	set_dec(tb_ticks_per_jiffy);
+}
+
+/* 
+ * After adjtimex is called, adjust the conversion of tb ticks
+ * to microseconds to keep do_gettimeofday synchronized 
+ * with ntpd.
+
+ * Use the time_adjust, time_freq and time_offset computed by adjtimex to 
+ * adjust the frequency.
+*/
+
+/* #define DEBUG_PPC_ADJTIMEX 1 */
+
+void ppc_adjtimex(void)
+{
+	unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec, new_tb_to_xs, new_xsec, new_stamp_xsec;
+	unsigned long tb_ticks_per_sec_delta;
+	long delta_freq, ltemp;
+	struct div_result divres; 
+	unsigned long flags;
+	struct gettimeofday_vars * temp_varp;
+	unsigned temp_idx;
+	long singleshot_ppm = 0;
+
+	/* Compute parts per million frequency adjustment to accomplish the time adjustment
+	   implied by time_offset to be applied over the elapsed time indicated by time_constant.
+	   Use SHIFT_USEC to get it into the same units as time_freq. */
+	if ( time_offset < 0 ) {
+		ltemp = -time_offset;
+		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
+		ltemp >>= SHIFT_KG + time_constant;
+		ltemp = -ltemp;
+	}
+	else {
+		ltemp = time_offset;
+		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
+		ltemp >>= SHIFT_KG + time_constant;
+	}
+	
+	/* If there is a single shot time adjustment in progress */
+	if ( time_adjust ) {
+#ifdef DEBUG_PPC_ADJTIMEX
+		printk("ppc_adjtimex: ");
+		if ( adjusting_time == 0 )
+			printk("starting ");
+		printk("single shot time_adjust = %ld\n", time_adjust);
+#endif	
+	
+		adjusting_time = 1;
+		
+		/* Compute parts per million frequency adjustment to match time_adjust */
+		singleshot_ppm = tickadj * HZ;	
+		/* The adjustment should be tickadj*HZ to match the code in linux/kernel/timer.c, but
+		   experiments show that this is too large. 3/4 of tickadj*HZ seems about right */
+		singleshot_ppm -= singleshot_ppm / 4;
+		/* Use SHIFT_USEC to get it into the same units as time_freq */	
+		singleshot_ppm <<= SHIFT_USEC;
+		if ( time_adjust < 0 )
+			singleshot_ppm = -singleshot_ppm;
+	}
+	else {
+#ifdef DEBUG_PPC_ADJTIMEX
+		if ( adjusting_time )
+			printk("ppc_adjtimex: ending single shot time_adjust\n");
+#endif
+		adjusting_time = 0;
+	}
+	
+	/* Add up all of the frequency adjustments */
+	delta_freq = time_freq + ltemp + singleshot_ppm;
+	
+	/* Compute a new value for tb_ticks_per_sec based on the frequency adjustment */
+	den = 1000000 * (1 << (SHIFT_USEC - 8));
+	if ( delta_freq < 0 ) {
+		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( (-delta_freq) >> (SHIFT_USEC - 8))) / den;
+		new_tb_ticks_per_sec = tb_ticks_per_sec + tb_ticks_per_sec_delta;
+	}
+	else {
+		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( delta_freq >> (SHIFT_USEC - 8))) / den;
+		new_tb_ticks_per_sec = tb_ticks_per_sec - tb_ticks_per_sec_delta;
+	}
+	
+#ifdef DEBUG_PPC_ADJTIMEX
+	printk("ppc_adjtimex: ltemp = %ld, time_freq = %ld, singleshot_ppm = %ld\n", ltemp, time_freq, singleshot_ppm);
+	printk("ppc_adjtimex: tb_ticks_per_sec - base = %ld  new = %ld\n", tb_ticks_per_sec, new_tb_ticks_per_sec);
+#endif
+				
+	/* Compute a new value of tb_to_xs (used to convert tb to microseconds and a new value of 
+	   stamp_xsec which is the time (in 1/2^20 second units) corresponding to tb_orig_stamp.  This 
+	   new value of stamp_xsec compensates for the change in frequency (implied by the new tb_to_xs)
+	   which guarantees that the current time remains the same */ 
+	tb_ticks = get_tb() - do_gtod.tb_orig_stamp;
+	div128_by_32( 1024*1024, 0, new_tb_ticks_per_sec, &divres );
+	new_tb_to_xs = divres.result_low;
+	new_xsec = mulhdu( tb_ticks, new_tb_to_xs );
+
+	write_lock_irqsave( &xtime_lock, flags );
+	old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs );
+	new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec;
+
+	/* There are two copies of tb_to_xs and stamp_xsec so that no lock is needed to access and use these
+	   values in do_gettimeofday.  We alternate the copies and as long as a reasonable time elapses between
+	   changes, there will never be inconsistent values.  ntpd has a minimum of one minute between updates */
+
+	if (do_gtod.var_idx == 0) {
+		temp_varp = &do_gtod.vars[1];
+		temp_idx  = 1;
+	}
+	else {
+		temp_varp = &do_gtod.vars[0];
+		temp_idx  = 0;
+	}
+	temp_varp->tb_to_xs = new_tb_to_xs;
+	temp_varp->stamp_xsec = new_stamp_xsec;
+	mb();
+	do_gtod.varp = temp_varp;
+	do_gtod.var_idx = temp_idx;
+
+	write_unlock_irqrestore( &xtime_lock, flags );
+
+}
+
+
+#define TICK_SIZE tick
+#define FEBRUARY	2
+#define	STARTOFTIME	1970
+#define SECDAY		86400L
+#define SECYR		(SECDAY * 365)
+#define	leapyear(year)		((year) % 4 == 0)
+#define	days_in_year(a) 	(leapyear(a) ? 366 : 365)
+#define	days_in_month(a) 	(month_days[(a) - 1])
+
+static int month_days[12] = {
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
+ */
+void GregorianDay(struct rtc_time * tm)
+{
+	int leapsToDate;
+	int lastYear;
+	int day;
+	int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+	lastYear=tm->tm_year-1;
+
+	/*
+	 * Number of leap corrections to apply up to end of last year
+	 */
+	leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+
+	/*
+	 * This year is a leap year if it is divisible by 4 except when it is
+	 * divisible by 100 unless it is divisible by 400
+	 *
+	 * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+	 */
+	if((tm->tm_year%4==0) &&
+	   ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
+	   (tm->tm_mon>2))
+	{
+		/*
+		 * We are past Feb. 29 in a leap year
+		 */
+		day=1;
+	}
+	else
+	{
+		day=0;
+	}
+
+	day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
+		   tm->tm_mday;
+
+	tm->tm_wday=day%7;
+}
+
+void to_tm(int tim, struct rtc_time * tm)
+{
+	register int    i;
+	register long   hms, day;
+
+	day = tim / SECDAY;
+	hms = tim % SECDAY;
+
+	/* Hours, minutes, seconds are easy */
+	tm->tm_hour = hms / 3600;
+	tm->tm_min = (hms % 3600) / 60;
+	tm->tm_sec = (hms % 3600) % 60;
+
+	/* Number of years in days */
+	for (i = STARTOFTIME; day >= days_in_year(i); i++)
+		day -= days_in_year(i);
+	tm->tm_year = i;
+
+	/* Number of months in days left */
+	if (leapyear(tm->tm_year))
+		days_in_month(FEBRUARY) = 29;
+	for (i = 1; day >= days_in_month(i); i++)
+		day -= days_in_month(i);
+	days_in_month(FEBRUARY) = 28;
+	tm->tm_mon = i;
+
+	/* Days are what is left over (+1) from all that. */
+	tm->tm_mday = day + 1;
+
+	/*
+	 * Determine the day of week
+	 */
+	GregorianDay(tm);
+}
+
+/* Auxiliary function to compute scaling factors */
+/* Actually the choice of a timebase running at 1/4 the of the bus
+ * frequency giving resolution of a few tens of nanoseconds is quite nice.
+ * It makes this computation very precise (27-28 bits typically) which
+ * is optimistic considering the stability of most processor clock
+ * oscillators and the precision with which the timebase frequency
+ * is measured but does not harm.
+ */
+unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
+        unsigned mlt=0, tmp, err;
+        /* No concern for performance, it's done once: use a stupid
+         * but safe and compact method to find the multiplier.
+         */
+  
+        for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
+                if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp;
+        }
+  
+        /* We might still be off by 1 for the best approximation.
+         * A side effect of this is that if outscale is too large
+         * the returned value will be zero.
+         * Many corner cases have been checked and seem to work,
+         * some might have been forgotten in the test however.
+         */
+  
+        err = inscale*(mlt+1);
+        if (err <= inscale/2) mlt++;
+        return mlt;
+  }
+
+/*
+ * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit
+ * result.
+ */
+
+void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
+		   unsigned divisor, struct div_result *dr )
+{
+	unsigned long a,b,c,d, w,x,y,z, ra,rb,rc;
+
+	a = dividend_high >> 32;
+	b = dividend_high & 0xffffffff;
+	c = dividend_low >> 32;
+	d = dividend_low & 0xffffffff;
+
+	w = a/divisor;
+	ra = (a - (w * divisor)) << 32;
+
+	x = (ra + b)/divisor;
+	rb = ((ra + b) - (x * divisor)) << 32;
+
+	y = (rb + c)/divisor;
+	rc = ((rb + b) - (y * divisor)) << 32;
+
+	z = (rc + d)/divisor;
+
+	dr->result_high = (w << 32) + x;
+	dr->result_low  = (y << 32) + z;
+
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/traps.c linux/arch/ppc64/kernel/traps.c
--- linux.orig/arch/ppc64/kernel/traps.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/traps.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,309 @@
+/*
+ *  linux/arch/ppc/kernel/traps.c
+ *
+ *  Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
+ *
+ *  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.
+ *
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *  and Paul Mackerras (paulus@cs.anu.edu.au)
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+#include <linux/init.h>
+
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/ppcdebug.h>
+
+extern int fix_alignment(struct pt_regs *);
+extern void bad_page_fault(struct pt_regs *, unsigned long);
+
+/* This is true if we are using the firmware NMI handler (typically LPAR) */
+extern int fwnmi_active;
+
+#ifdef CONFIG_XMON
+extern void xmon(struct pt_regs *regs);
+extern int xmon_bpt(struct pt_regs *regs);
+extern int xmon_sstep(struct pt_regs *regs);
+extern int xmon_iabr_match(struct pt_regs *regs);
+extern int xmon_dabr_match(struct pt_regs *regs);
+extern void (*xmon_fault_handler)(struct pt_regs *regs);
+#endif
+
+#ifdef CONFIG_XMON
+void (*debugger)(struct pt_regs *regs) = xmon;
+int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
+int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep;
+int (*debugger_iabr_match)(struct pt_regs *regs) = xmon_iabr_match;
+int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match;
+void (*debugger_fault_handler)(struct pt_regs *regs);
+#else
+#ifdef CONFIG_KGDB
+void (*debugger)(struct pt_regs *regs);
+int (*debugger_bpt)(struct pt_regs *regs);
+int (*debugger_sstep)(struct pt_regs *regs);
+int (*debugger_iabr_match)(struct pt_regs *regs);
+int (*debugger_dabr_match)(struct pt_regs *regs);
+void (*debugger_fault_handler)(struct pt_regs *regs);
+#endif
+#endif
+/*
+ * Trap & Exception support
+ */
+
+void
+_exception(int signr, struct pt_regs *regs)
+{
+	if (!user_mode(regs))
+	{
+		show_regs(regs);
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+		debugger(regs);
+#endif
+#if defined(CONFIG_KDB)
+		kdb(KDB_REASON_OOPS, 0, (kdb_eframe_t) regs);
+#endif
+		print_backtrace((unsigned long *)regs->gpr[1]);
+		panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
+#if defined(CONFIG_PPCDBG) && (defined(CONFIG_XMON) || defined(CONFIG_KGDB))
+	/* Allow us to catch SIGILLs for 64-bit app/glibc debugging. -Peter */
+	} else if (signr == SIGILL) {
+		ifppcdebug(PPCDBG_SIGNALXMON)
+			debugger(regs);
+#endif
+	}
+	force_sig(signr, current);
+}
+
+/* Get the error information for errors coming through the
+ * FWNMI vectors.  The pt_regs' r3 will be updated to reflect
+ * the actual r3 if possible, and a ptr to the error log entry
+ * will be returned if found.
+ */
+static struct rtas_error_log *FWNMI_get_errinfo(struct pt_regs *regs)
+{
+	unsigned long errdata = regs->gpr[3];
+	struct rtas_error_log *errhdr = NULL;
+	unsigned long *savep;
+
+	if ((errdata >= 0x7000 && errdata < 0x7fff0) ||
+	    (errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) {
+		savep = __va(errdata);
+		regs->gpr[3] = savep[0];	/* restore original r3 */
+		errhdr = (struct rtas_error_log *)(savep + 1);
+	} else {
+		printk("FWNMI: corrupt r3\n");
+	}
+	return errhdr;
+}
+
+/* Call this when done with the data returned by FWNMI_get_errinfo.
+ * It will release the saved data area for other CPUs in the
+ * partition to receive FWNMI errors.
+ */
+static void FWNMI_release_errinfo(void)
+{
+	unsigned long ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL);
+	if (ret != 0)
+		printk("FWNMI: nmi-interlock failed: %ld\n", ret);
+}
+
+void
+SystemResetException(struct pt_regs *regs)
+{
+	char *msg = "System Reset in kernel mode.\n";
+	udbg_printf(msg); printk(msg);
+	if (fwnmi_active) {
+		unsigned long *r3 = __va(regs->gpr[3]); /* for FWNMI debug */
+		struct rtas_error_log *errlog;
+
+		msg = "FWNMI is active with save area at %016lx\n";
+		udbg_printf(msg, r3); printk(msg, r3);
+		errlog = FWNMI_get_errinfo(regs);
+	}
+#if defined(CONFIG_XMON)
+	xmon(regs);
+	udbg_printf("leaving xmon...\n");
+#endif
+	for(;;);
+}
+
+
+void
+MachineCheckException(struct pt_regs *regs)
+{
+	if (fwnmi_active) {
+		struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs);
+		if (errhdr) {
+			/* ToDo: attempt to recover from some errors here */
+		}
+		FWNMI_release_errinfo();
+	}
+	if ( !user_mode(regs) )
+	{
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+		if (debugger_fault_handler) {
+			debugger_fault_handler(regs);
+			return;
+		}
+#endif
+#ifdef CONFIG_KDB
+		if (kdb(KDB_REASON_FAULT, 0, regs))
+			return;
+#endif
+		printk("Machine check in kernel mode.\n");
+		printk("Caused by (from SRR1=%lx): ", regs->msr);
+		show_regs(regs);
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+		debugger(regs);
+#endif
+#ifdef CONFIG_KDB
+		if (kdb(KDB_REASON_FAULT, 0, regs))
+			return ;
+#endif
+		print_backtrace((unsigned long *)regs->gpr[1]);
+		panic("machine check");
+	}
+	_exception(SIGSEGV, regs);	
+}
+
+void
+SMIException(struct pt_regs *regs)
+{
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+	{
+		debugger(regs);
+		return;
+	}
+#endif
+#ifdef CONFIG_KDB
+	{
+		kdb(KDB_REASON_OOPS, 0, regs);
+		return;
+	}
+#endif
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("System Management Interrupt");
+}
+
+void
+UnknownException(struct pt_regs *regs)
+{
+	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+	_exception(SIGTRAP, regs);	
+}
+
+void
+InstructionBreakpointException(struct pt_regs *regs)
+{
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+	if (debugger_iabr_match(regs))
+		return;
+#endif
+#ifdef CONFIG_KDB
+	if (kdb(KDB_REASON_BREAK, 0, regs))
+		return ;
+#endif
+	_exception(SIGTRAP, regs);
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+	if (regs->msr & 0x100000) {
+		/* IEEE FP exception */
+		_exception(SIGFPE, regs);
+	} else if (regs->msr & 0x20000) {
+		/* trap exception */
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+		if (debugger_bpt(regs))
+			return;
+#endif
+#ifdef CONFIG_KDB
+		if (kdb(KDB_REASON_BREAK, 0, regs))
+			return;
+#endif
+		_exception(SIGTRAP, regs);
+	} else {
+		_exception(SIGILL, regs);
+	}
+}
+
+void
+SingleStepException(struct pt_regs *regs)
+{
+	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+	if (debugger_sstep(regs))
+		return;
+#endif
+#ifdef CONFIG_KDB
+	if (kdb(KDB_REASON_DEBUG, 0, regs))
+		return;
+#endif
+	_exception(SIGTRAP, regs);	
+}
+
+/* Dummy handler for Performance Monitor */
+
+void
+PerformanceMonitorException(struct pt_regs *regs)
+{
+	_exception(SIGTRAP, regs);
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+	int fixed;
+
+	fixed = fix_alignment(regs);
+	if (fixed == 1) {
+		ifppcdebug(PPCDBG_ALIGNFIXUP)
+			if (!user_mode(regs))
+				PPCDBG(PPCDBG_ALIGNFIXUP, "fix alignment at %lx\n", regs->nip);
+		regs->nip += 4;	/* skip over emulated instruction */
+		return;
+	}
+	if (fixed == -EFAULT) {
+		/* fixed == -EFAULT means the operand address was bad */
+		if (user_mode(regs))
+			force_sig(SIGSEGV, current);
+		else
+			bad_page_fault(regs, regs->dar);
+		return;
+	}
+	_exception(SIGBUS, regs);	
+}
+
+void __init trap_init(void)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/udbg.c linux/arch/ppc64/kernel/udbg.c
--- linux.orig/arch/ppc64/kernel/udbg.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/udbg.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,250 @@
+/*
+ * NS16550 Serial Port (uart) debugging stuff.
+ *
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * NOTE: I am trying to make this code avoid any static data references to
+ *  simplify debugging early boot.  We'll see how that goes...
+ *
+ * To use this call udbg_init() first.  It will init the uart to 9600 8N1.
+ * You may need to update the COM1 define if your uart is at a different addr.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <stdarg.h>
+#define WANT_PPCDBG_TAB /* Only defined here */
+#include <asm/ppcdebug.h>
+#include <asm/processor.h>
+#include <asm/naca.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+
+struct NS16550 {
+	/* this struct must be packed */
+	unsigned char rbr;  /* 0 */
+	unsigned char ier;  /* 1 */
+	unsigned char fcr;  /* 2 */
+	unsigned char lcr;  /* 3 */
+	unsigned char mcr;  /* 4 */
+	unsigned char lsr;  /* 5 */
+	unsigned char msr;  /* 6 */
+	unsigned char scr;  /* 7 */
+};
+
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+#define dlab lcr
+
+#define LSR_DR   0x01  /* Data ready */
+#define LSR_OE   0x02  /* Overrun */
+#define LSR_PE   0x04  /* Parity error */
+#define LSR_FE   0x08  /* Framing error */
+#define LSR_BI   0x10  /* Break */
+#define LSR_THRE 0x20  /* Xmit holding register empty */
+#define LSR_TEMT 0x40  /* Xmitter empty */
+#define LSR_ERR  0x80  /* Error */
+
+volatile struct NS16550 *udbg_comport;
+
+spinlock_t udbg_lock = SPIN_LOCK_UNLOCKED;
+
+void
+udbg_init_uart(void *comport)
+{
+	if (comport) {
+		udbg_comport = (struct NS16550 *)comport;
+		udbg_comport->lcr = 0x00; eieio();
+		udbg_comport->ier = 0xFF; eieio();
+		udbg_comport->ier = 0x00; eieio();
+		udbg_comport->lcr = 0x80; eieio();	/* Access baud rate */
+		udbg_comport->dll = 12;   eieio();	/* 1 = 115200,  2 = 57600, 3 = 38400, 12 = 9600 baud */
+		udbg_comport->dlm = 0;    eieio();	/* dll >> 8 which should be zero for fast rates; */
+		udbg_comport->lcr = 0x03; eieio();	/* 8 data, 1 stop, no parity */
+		udbg_comport->mcr = 0x03; eieio();	/* RTS/DTR */
+		udbg_comport->fcr = 0x07; eieio();	/* Clear & enable FIFOs */
+	}
+}
+
+void
+udbg_putc(unsigned char c)
+{
+	if ( udbg_comport ) {
+		while ((udbg_comport->lsr & LSR_THRE) == 0)
+			/* wait for idle */;
+		udbg_comport->thr = c; eieio();
+		if (c == '\n') {
+			/* Also put a CR.  This is for convenience. */
+			while ((udbg_comport->lsr & LSR_THRE) == 0)
+				/* wait for idle */;
+			udbg_comport->thr = '\r'; eieio();
+		}
+	} else if (naca->platform == PLATFORM_ISERIES_LPAR) {
+		/* ToDo: switch this via ppc_md */
+		printk("%c", c);
+	}
+}
+
+int udbg_getc_poll(void)
+{
+	if (udbg_comport) {
+		if ((udbg_comport->lsr & LSR_DR) != 0)
+			return udbg_comport->rbr;
+		else
+			return -1;
+	}
+	return -1;
+}
+
+unsigned char
+udbg_getc(void)
+{
+	if ( udbg_comport ) {
+		while ((udbg_comport->lsr & LSR_DR) == 0)
+			/* wait for char */;
+		return udbg_comport->rbr;
+	}
+	return 0;
+}
+
+void
+udbg_puts(const char *s)
+{
+	if (ppc_md.udbg_putc) {
+		char c;
+
+		if (s && *s != '\0') {
+			while ((c = *s++) != '\0')
+				ppc_md.udbg_putc(c);
+		} else {
+			udbg_puts("NULL");
+		}
+	} else {
+		printk("%s", s);
+	}
+}
+
+int
+udbg_write(const char *s, int n)
+{
+	int remain = n;
+	char c;
+	if (!ppc_md.udbg_putc)
+		for (;;);	/* stop here for cpuctl */
+	if ( s && *s != '\0' ) {
+		while ( (( c = *s++ ) != '\0') && (remain-- > 0)) {
+			ppc_md.udbg_putc(c);
+		}
+	} else
+		udbg_puts("NULL");
+	return n - remain;
+}
+
+int
+udbg_read(char *buf, int buflen) {
+	char c, *p = buf;
+	int i;
+	if (!ppc_md.udbg_putc)
+		for (;;);	/* stop here for cpuctl */
+	for (i = 0; i < buflen; ++i) {
+		do {
+			c = ppc_md.udbg_getc();
+		} while (c == 0x11 || c == 0x13);
+		*p++ = c;
+	}
+	return i;
+}
+
+void
+udbg_puthex(unsigned long val)
+{
+	int i, nibbles = sizeof(val)*2;
+	unsigned char buf[sizeof(val)*2+1];
+	for (i = nibbles-1;  i >= 0;  i--) {
+		buf[i] = (val & 0xf) + '0';
+		if (buf[i] > '9')
+		    buf[i] += ('a'-'0'-10);
+		val >>= 4;
+	}
+	buf[nibbles] = '\0';
+	udbg_puts(buf);
+}
+
+void
+udbg_printSP(const char *s)
+{
+	if (naca->platform == PLATFORM_PSERIES) {
+		unsigned long sp;
+		asm("mr %0,1" : "=r" (sp) :);
+		if (s)
+			udbg_puts(s);
+		udbg_puthex(sp);
+	}
+}
+
+void
+udbg_printf(const char *fmt, ...)
+{
+	unsigned long flags;
+	unsigned char buf[256];
+
+	va_list args;
+	va_start(args, fmt);
+
+	spin_lock_irqsave(&udbg_lock, flags);
+	vsprintf(buf, fmt, args);
+	udbg_puts(buf);
+	spin_unlock_irqrestore(&udbg_lock, flags);
+
+	va_end(args);
+}
+
+/* Special print used by PPCDBG() macro */
+void
+udbg_ppcdbg(unsigned long debug_flags, const char *fmt, ...)
+{
+	unsigned long flags;
+	unsigned long active_debugs = debug_flags & naca->debug_switch;
+
+	if ( active_debugs ) {
+		va_list ap;
+		unsigned char buf[256];
+		unsigned long i, len = 0;
+
+		spin_lock_irqsave(&udbg_lock, flags);
+		for(i=0; i < PPCDBG_NUM_FLAGS ;i++) {
+			if (((1U << i) & active_debugs) && 
+			    trace_names[i]) {
+				len += strlen(trace_names[i]); 
+				udbg_puts(trace_names[i]);
+				break;
+			}
+		}
+		sprintf(buf, " [%s]: ", current->comm);
+		len += strlen(buf); 
+		udbg_puts(buf);
+
+		while(len < 18) {
+			udbg_puts(" ");
+			len++;
+		}
+
+		va_start(ap, fmt);
+		vsprintf(buf, fmt, ap);
+		udbg_puts(buf);
+		spin_unlock_irqrestore(&udbg_lock, flags);
+		
+		va_end(ap);
+	}
+}
+
+unsigned long
+udbg_ifdebug(unsigned long flags)
+{
+	return (flags & naca->debug_switch);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/xics.c linux/arch/ppc64/kernel/xics.c
--- linux.orig/arch/ppc64/kernel/xics.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/xics.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,471 @@
+/* 
+ * arch/ppc/kernel/xics.c
+ *
+ * Copyright 2000 IBM 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.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/threads.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/smp.h>
+#include <asm/naca.h>
+#include <asm/rtas.h>
+#include "i8259.h"
+#include "xics.h"
+#include <asm/ppcdebug.h>
+
+void xics_enable_irq(u_int irq);
+void xics_disable_irq(u_int irq);
+void xics_mask_and_ack_irq(u_int irq);
+void xics_end_irq(u_int irq);
+void xics_set_affinity(unsigned int irq_nr, unsigned long cpumask);
+
+struct hw_interrupt_type xics_pic = {
+	" XICS     ",
+	NULL,
+	NULL,
+	xics_enable_irq,
+	xics_disable_irq,
+	xics_mask_and_ack_irq,
+	xics_end_irq,
+	xics_set_affinity
+};
+
+struct hw_interrupt_type xics_8259_pic = {
+	" XICS/8259",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	xics_mask_and_ack_irq,
+	NULL
+};
+
+#define XICS_IPI		2
+#define XICS_IRQ_OFFSET		0x10
+#define XICS_IRQ_SPURIOUS	0
+
+/* Want a priority other than 0.  Various HW issues require this. */
+#define	DEFAULT_PRIORITY	5
+
+struct xics_ipl {
+	union {
+		u32	word;
+		u8	bytes[4];
+	} xirr_poll;
+	union {
+		u32 word;
+		u8	bytes[4];
+	} xirr;
+	u32	dummy;
+	union {
+		u32	word;
+		u8	bytes[4];
+	} qirr;
+};
+
+struct xics_info {
+	volatile struct xics_ipl *	per_cpu[NR_CPUS];
+};
+
+struct xics_info	xics_info;
+
+unsigned long long intr_base = 0;
+int xics_irq_8259_cascade = 0;
+int xics_irq_8259_cascade_real = 0;
+unsigned int default_server = 0xFF;
+unsigned int default_distrib_server = 0;
+
+/* RTAS service tokens */
+int ibm_get_xive;
+int ibm_set_xive;
+int ibm_int_off;
+
+struct xics_interrupt_node {
+	unsigned long long addr;
+	unsigned long long size;
+} inodes[NR_CPUS*2];	 
+
+typedef struct {
+	int (*xirr_info_get)(int cpu);
+	void (*xirr_info_set)(int cpu, int val);
+	void (*cppr_info)(int cpu, u8 val);
+	void (*qirr_info)(int cpu, u8 val);
+} xics_ops;
+
+
+static int pSeries_xirr_info_get(int n_cpu)
+{
+	return (xics_info.per_cpu[n_cpu]->xirr.word);
+}
+
+static void pSeries_xirr_info_set(int n_cpu, int value)
+{
+	xics_info.per_cpu[n_cpu]->xirr.word = value;
+}
+
+static void pSeries_cppr_info(int n_cpu, u8 value)
+{
+	xics_info.per_cpu[n_cpu]->xirr.bytes[0] = value;
+}
+
+static void pSeries_qirr_info(int n_cpu , u8 value)
+{
+	xics_info.per_cpu[n_cpu]->qirr.bytes[0] = value;
+}
+
+static xics_ops pSeries_ops = {
+	pSeries_xirr_info_get,
+	pSeries_xirr_info_set,
+	pSeries_cppr_info,
+	pSeries_qirr_info
+};
+
+static xics_ops *ops = &pSeries_ops;
+extern xics_ops pSeriesLP_ops;
+
+
+void
+xics_enable_irq(
+	u_int	virq
+	)
+{
+	u_int		irq;
+	unsigned long	status;
+	long	        call_status;
+
+	virq -= XICS_IRQ_OFFSET;
+	irq = virt_irq_to_real(virq);
+	if (irq == XICS_IPI)
+		return;
+#ifdef CONFIG_IRQ_ALL_CPUS
+	call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
+				irq, smp_threads_ready ? default_distrib_server : default_server, DEFAULT_PRIORITY);
+#else
+	call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
+				irq, default_server, DEFAULT_PRIORITY);
+#endif
+	if( call_status != 0 ) {
+		printk("xics_enable_irq: irq=%x: rtas_call failed; retn=%lx, status=%lx\n",
+		       irq, call_status, status);
+		return;
+	}
+}
+
+void
+xics_disable_irq(
+	u_int	virq
+	)
+{
+	u_int		irq;
+	unsigned long 	status;
+	long 	        call_status;
+
+	virq -= XICS_IRQ_OFFSET;
+	irq = virt_irq_to_real(virq);
+	call_status = rtas_call(ibm_int_off, 1, 1, (unsigned long*)&status, 
+				irq);
+	if( call_status != 0 ) {
+		printk("xics_disable_irq: irq=%x: rtas_call failed, retn=%lx\n",
+		       irq, call_status);
+		return;
+	}
+}
+
+void
+xics_end_irq(
+	u_int	irq
+	)
+{
+	int cpu = smp_processor_id();
+
+	ops->cppr_info(cpu, 0); /* actually the value overwritten by ack */
+	iosync();
+	ops->xirr_info_set(cpu, ((0xff<<24) | (virt_irq_to_real(irq-XICS_IRQ_OFFSET))));
+	iosync();
+}
+
+void
+xics_mask_and_ack_irq(u_int	irq)
+{
+	int cpu = smp_processor_id();
+
+	if( irq < XICS_IRQ_OFFSET ) {
+		i8259_pic.ack(irq);
+		iosync();
+		ops->xirr_info_set(cpu, ((0xff<<24) | xics_irq_8259_cascade_real));
+		iosync();
+	}
+	else {
+		ops->cppr_info(cpu, 0xff);
+		iosync();
+	}
+}
+
+int
+xics_get_irq(struct pt_regs *regs)
+{
+	u_int	cpu = smp_processor_id();
+	u_int	vec;
+	int irq;
+
+	vec = ops->xirr_info_get(cpu);
+	/*  (vec >> 24) == old priority */
+	vec &= 0x00ffffff;
+	/* for sanity, this had better be < NR_IRQS - 16 */
+	if( vec == xics_irq_8259_cascade_real ) {
+		irq = i8259_irq(cpu);
+		if(irq == -1) {
+			/* Spurious cascaded interrupt.  Still must ack xics */
+                        xics_end_irq(XICS_IRQ_OFFSET + xics_irq_8259_cascade);
+			irq = -1;
+		}
+	} else if( vec == XICS_IRQ_SPURIOUS ) {
+		irq = -1;
+		printk("spurious PPC interrupt!\n");
+	} else
+		irq = real_irq_to_virt(vec) + XICS_IRQ_OFFSET;
+	return irq;
+}
+
+
+#ifdef CONFIG_SMP
+void xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+{
+	extern volatile unsigned long xics_ipi_message[];
+	int cpu = smp_processor_id();
+
+	ops->qirr_info(cpu, 0xff);
+	while (xics_ipi_message[cpu]) {
+		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, &xics_ipi_message[cpu])) {
+			mb();
+			smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
+		}
+		if (test_and_clear_bit(PPC_MSG_RESCHEDULE, &xics_ipi_message[cpu])) {
+			mb();
+			smp_message_recv(PPC_MSG_RESCHEDULE, regs);
+		}
+#ifdef CONFIG_XMON
+		if (test_and_clear_bit(PPC_MSG_XMON_BREAK, &xics_ipi_message[cpu])) {
+			mb();
+			smp_message_recv(PPC_MSG_XMON_BREAK, regs);
+		}
+#endif
+	}
+}
+
+void xics_cause_IPI(int cpu)
+{
+	ops->qirr_info(cpu,0) ;
+}
+
+void xics_setup_cpu(void)
+{
+	int cpu = smp_processor_id();
+
+	ops->cppr_info(cpu, 0xff);
+	iosync();
+}
+#endif /* CONFIG_SMP */
+
+void
+xics_init_IRQ( void )
+{
+	int i;
+	unsigned long intr_size = 0;
+	struct device_node *np;
+	uint *ireg, ilen, indx=0;
+
+	ibm_get_xive = rtas_token("ibm,get-xive");
+	ibm_set_xive = rtas_token("ibm,set-xive");
+	ibm_int_off = rtas_token("ibm,int-off");
+
+	np = find_type_devices("PowerPC-External-Interrupt-Presentation");
+	if (!np) {
+		printk(KERN_WARNING "Can't find Interrupt Presentation\n");
+		udbg_printf("Can't find Interrupt Presentation\n");
+		while (1);
+	}
+nextnode:
+	ireg = (uint *)get_property(np, "ibm,interrupt-server-ranges", 0);
+	if (ireg) {
+		/*
+		 * set node starting index for this node
+		 */
+		indx = *ireg;
+	}
+
+	ireg = (uint *)get_property(np, "reg", &ilen);
+	if (!ireg) {
+		printk(KERN_WARNING "Can't find Interrupt Reg Property\n");
+		udbg_printf("Can't find Interrupt Reg Property\n");
+		while (1);
+	}
+	
+	while (ilen) {
+		inodes[indx].addr = (unsigned long long)*ireg++ << 32;
+		ilen -= sizeof(uint);
+		inodes[indx].addr |= *ireg++;
+		ilen -= sizeof(uint);
+		inodes[indx].size = (unsigned long long)*ireg++ << 32;
+		ilen -= sizeof(uint);
+		inodes[indx].size |= *ireg++;
+		ilen -= sizeof(uint);
+		indx++;
+		if (indx >= NR_CPUS) break;
+	}
+
+	np = np->next;
+	if ((indx < NR_CPUS) && np) goto nextnode;
+
+	/* Find the server numbers for the boot cpu. */
+	for (np = find_type_devices("cpu"); np; np = np->next) {
+		ireg = (uint *)get_property(np, "reg", &ilen);
+		if (ireg && ireg[0] == hard_smp_processor_id()) {
+			ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
+			i = ilen / sizeof(int);
+			if (ireg && i > 0) {
+				default_server = ireg[0];
+				default_distrib_server = ireg[i-1]; /* take last element */
+			}
+			break;
+		}
+	}
+
+	intr_base = inodes[0].addr;
+	intr_size = (ulong)inodes[0].size;
+
+	np = find_type_devices("interrupt-controller");
+	if (!np) {
+		printk(KERN_WARNING "xics:  no ISA Interrupt Controller\n");
+		xics_irq_8259_cascade = -1;
+	} else {
+		ireg = (uint *) get_property(np, "interrupts", 0);
+		if (!ireg) {
+			printk(KERN_WARNING "Can't find ISA Interrupts Property\n");
+			udbg_printf("Can't find ISA Interrupts Property\n");
+			while (1);
+		}
+		xics_irq_8259_cascade_real = *ireg;
+		xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real);
+	}
+
+	if (naca->platform == PLATFORM_PSERIES) {
+#ifdef CONFIG_SMP
+		for (i = 0; i < naca->processorCount; ++i) {
+			xics_info.per_cpu[i] =
+			  __ioremap((ulong)inodes[get_hard_smp_processor_id(i)].addr, 
+				  (ulong)inodes[get_hard_smp_processor_id(i)].size, _PAGE_NO_CACHE);
+		}
+#else
+		xics_info.per_cpu[0] = __ioremap((ulong)intr_base, intr_size, _PAGE_NO_CACHE);
+#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC_PSERIES
+	/* actually iSeries does not use any of xics...but it has link dependencies
+	 * for now, except this new one...
+	 */
+	} else if (naca->platform == PLATFORM_PSERIES_LPAR) {
+		ops = &pSeriesLP_ops;
+#endif
+	}
+
+	xics_8259_pic.enable = i8259_pic.enable;
+	xics_8259_pic.disable = i8259_pic.disable;
+	for (i = 0; i < 16; ++i)
+		irq_desc[i].handler = &xics_8259_pic;
+	for (; i < NR_IRQS; ++i)
+		irq_desc[i].handler = &xics_pic;
+
+	ops->cppr_info(0, 0xff);
+	iosync();
+	if (xics_irq_8259_cascade != -1) {
+		if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action,
+				0, "8259 cascade", 0))
+			printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
+		i8259_init();
+	}
+
+#ifdef CONFIG_SMP
+	real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] = XICS_IPI;
+	request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0);
+	irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU;
+#endif
+}
+
+void xics_isa_init(void)
+{
+	return;
+	if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action,
+			0, "8259 cascade", 0))
+		printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
+	i8259_init();
+}
+
+/*
+ * Find first logical cpu and return its physical cpu number
+ */
+static inline u32 physmask(u32 cpumask)
+{
+	int i;
+
+	for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1) {
+		if (cpumask & 1)
+			return get_hard_smp_processor_id(i);
+	}
+
+	printk(KERN_ERR "xics_set_affinity: invalid irq mask\n");
+
+	return default_distrib_server;
+}
+
+void xics_set_affinity(unsigned int virq, unsigned long cpumask)
+{
+        irq_desc_t *desc = irq_desc + virq;
+	unsigned int irq;
+	unsigned long flags;
+	long status;
+	unsigned long xics_status[2];
+	u32 newmask;
+
+	virq -= XICS_IRQ_OFFSET;
+	irq = virt_irq_to_real(virq);
+	if (irq == XICS_IPI)
+		return;
+
+        spin_lock_irqsave(&desc->lock, flags);
+
+	status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, irq);
+
+	if (status) {
+		printk("xics_set_affinity: irq=%d ibm,get-xive returns %ld\n",
+			irq, status);
+		goto out;
+	}
+
+	/* For the moment only implement delivery to all cpus or one cpu */
+	if (cpumask == 0xffffffff)
+		newmask = default_distrib_server;
+	else
+		newmask = physmask(cpumask);
+
+	status = rtas_call(ibm_set_xive, 3, 1, NULL,
+				irq, newmask, xics_status[1]);
+
+	if (status) {
+		printk("xics_set_affinity irq=%d ibm,set-xive returns %ld\n",
+			irq, status);
+		goto out;
+	}
+
+out:
+        spin_unlock_irqrestore(&desc->lock, flags);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/kernel/xics.h linux/arch/ppc64/kernel/xics.h
--- linux.orig/arch/ppc64/kernel/xics.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/kernel/xics.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,24 @@
+/* 
+ * arch/ppc/kernel/xics.h
+ *
+ * Copyright 2000 IBM 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.
+ */
+
+#ifndef _PPC_KERNEL_XICS_H
+#define _PPC_KERNEL_XICS_H
+
+#include "local_irq.h"
+
+extern struct hw_interrupt_type xics_pic;
+extern struct hw_interrupt_type xics_8259_pic;
+
+void xics_init_IRQ(void);
+int xics_get_irq(struct pt_regs *);
+void xics_isa_init(void);
+
+#endif /* _PPC_KERNEL_XICS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/lib/Makefile linux/arch/ppc64/lib/Makefile
--- linux.orig/arch/ppc64/lib/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/lib/Makefile	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,11 @@
+#
+# Makefile for ppc64-specific library files..
+#
+
+USE_STANDARD_AS_RULE    := true
+
+O_TARGET = lib.o
+
+obj-y           := checksum.o dec_and_lock.o string.o strcase.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/lib/checksum.S linux/arch/ppc64/lib/checksum.S
--- linux.orig/arch/ppc64/lib/checksum.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/lib/checksum.S	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,231 @@
+/*
+ * This file contains assembly-language implementations
+ * of IP-style 1's complement checksum routines.
+ *	
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  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.
+ *
+ * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
+ */
+
+#include <linux/sys.h>
+#include <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/ppc_asm.tmpl>
+
+	.text
+
+/*
+ * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header
+ * len is in words and is always >= 5.
+ *
+ * In practice len == 5, but this is not guaranteed.  So this code does not
+ * attempt to use doubleword instructions.
+ */
+_GLOBAL(ip_fast_csum)
+	lwz	r0,0(r3)
+	lwzu	r5,4(r3)
+	addic.	r4,r4,-2
+	addc	r0,r0,r5
+	mtctr	r4
+	blelr-
+1:	lwzu	r4,4(r3)
+	adde	r0,r0,r4
+	bdnz	1b
+	addze	r0,r0		/* add in final carry */
+        rldicl  r4,r0,32,0      /* fold two 32-bit halves together */
+        add     r0,r0,r4
+        srdi    r0,r0,32
+	rlwinm	r3,r0,16,0,31	/* fold two halves together */
+	add	r3,r0,r3
+	not	r3,r3
+	srwi	r3,r3,16
+	blr
+
+/*
+ * Compute checksum of TCP or UDP pseudo-header:
+ *   csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum)
+ * No real gain trying to do this specially for 64 bit, but
+ * the 32 bit addition may spill into the upper bits of
+ * the doubleword so we still must fold it down from 64.
+ */	
+_GLOBAL(csum_tcpudp_magic)
+	rlwimi	r5,r6,16,0,15	/* put proto in upper half of len */
+	addc	r0,r3,r4	/* add 4 32-bit words together */
+	adde	r0,r0,r5
+	adde	r0,r0,r7
+        rldicl  r4,r0,32,0      /* fold 64 bit value */
+        add     r0,r4,r0
+        srdi    r0,r0,32
+	rlwinm	r3,r0,16,0,31	/* fold two halves together */
+	add	r3,r0,r3
+	not	r3,r3
+	srwi	r3,r3,16
+	blr
+
+/*
+ * Computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit).
+ *
+ * This code assumes at least halfword alignment, though the length
+ * can be any number of bytes.  The sum is accumulated in r5.
+ *
+ * csum_partial(r3=buff, r4=len, r5=sum)
+ */
+_GLOBAL(csum_partial)
+        subi	r3,r3,8		/* we'll offset by 8 for the loads */
+        srdi.	r6,r4,3         /* divide by 8 for doubleword count */
+        addic   r5,r5,0         /* clear carry */
+        beq	3f              /* if we're doing < 8 bytes */
+        andi.	r0,r3,2         /* aligned on a word boundary already? */
+        beq+	1f
+        lhz     r6,8(r3)        /* do 2 bytes to get aligned */
+        addi    r3,r3,2
+        subi    r4,r4,2
+        addc    r5,r5,r6
+        srdi.   r6,r4,3         /* recompute number of doublewords */
+        beq     3f              /* any left? */
+1:      mtctr   r6
+2:      ldu     r6,8(r3)        /* main sum loop */
+        adde    r5,r5,r6
+        bdnz    2b
+        andi.	r4,r4,7         /* compute bytes left to sum after doublewords */
+3:	cmpi	0,r4,4		/* is at least a full word left? */
+	blt	4f
+	lwz	r6,8(r3)	/* sum this word */
+	addi	r3,r3,4
+	subi	r4,r4,4
+	adde	r5,r5,r6
+4:      cmpi    0,r4,2		/* is at least a halfword left? */
+        blt+	5f
+        lhz     r6,8(r3)        /* sum this halfword */
+        addi    r3,r3,2
+        subi    r4,r4,2
+        adde    r5,r5,r6
+5:      cmpi    0,r4,1		/* is at least a byte left? */
+        bne+    6f
+        lbz     r6,8(r3)        /* sum this byte */
+        slwi    r6,r6,8         /* this byte is assumed to be the upper byte of a halfword */
+        adde    r5,r5,r6
+6:      addze	r5,r5		/* add in final carry */
+	rldicl  r4,r5,32,0      /* fold two 32-bit halves together */
+        add     r3,r4,r5
+        srdi    r3,r3,32
+        blr
+
+/*
+ * Computes the checksum of a memory block at src, length len,
+ * and adds in "sum" (32-bit), while copying the block to dst.
+ * If an access exception occurs on src or dst, it stores -EFAULT
+ * to *src_err or *dst_err respectively, and (for an error on
+ * src) zeroes the rest of dst.
+ *
+ * This code needs to be reworked to take advantage of 64 bit sum+copy.
+ * However, due to tokenring halfword alignment problems this will be very
+ * tricky.  For now we'll leave it until we instrument it somehow.
+ *
+ * csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err)
+ */
+_GLOBAL(csum_partial_copy_generic)
+	addic	r0,r6,0
+	subi	r3,r3,4
+	subi	r4,r4,4
+	srwi.	r6,r5,2
+	beq	3f		/* if we're doing < 4 bytes */
+	andi.	r9,r4,2		/* Align dst to longword boundary */
+	beq+	1f
+81:	lhz	r6,4(r3)	/* do 2 bytes to get aligned */
+	addi	r3,r3,2
+	subi	r5,r5,2
+91:	sth	r6,4(r4)
+	addi	r4,r4,2
+	addc	r0,r0,r6
+	srwi.	r6,r5,2		/* # words to do */
+	beq	3f
+1:	mtctr	r6
+82:	lwzu	r6,4(r3)	/* the bdnz has zero overhead, so it should */
+92:	stwu	r6,4(r4)	/* be unnecessary to unroll this loop */
+	adde	r0,r0,r6
+	bdnz	82b
+	andi.	r5,r5,3
+3:	cmpi	0,r5,2
+	blt+	4f
+83:	lhz	r6,4(r3)
+	addi	r3,r3,2
+	subi	r5,r5,2
+93:	sth	r6,4(r4)
+	addi	r4,r4,2
+	adde	r0,r0,r6
+4:	cmpi	0,r5,1
+	bne+	5f
+84:	lbz	r6,4(r3)
+94:	stb	r6,4(r4)
+	slwi	r6,r6,8		/* Upper byte of word */
+	adde	r0,r0,r6
+5:	addze	r3,r0		/* add in final carry (unlikely with 64-bit regs) */
+        rldicl  r4,r3,32,0      /* fold 64 bit value */
+        add     r3,r4,r3
+        srdi    r3,r3,32
+	blr
+
+/* These shouldn't go in the fixup section, since that would
+   cause the ex_table addresses to get out of order. */
+
+	.globl src_error_1
+src_error_1:
+	li	r6,0
+	subi	r5,r5,2
+95:	sth	r6,4(r4)
+	addi	r4,r4,2
+	srwi.	r6,r5,2
+	beq	3f
+	mtctr	r6
+	.globl src_error_2
+src_error_2:
+	li	r6,0
+96:	stwu	r6,4(r4)
+	bdnz	96b
+3:	andi.	r5,r5,3
+	beq	src_error
+	.globl src_error_3
+src_error_3:
+	li	r6,0
+	mtctr	r5
+	addi	r4,r4,3
+97:	stbu	r6,1(r4)
+	bdnz	97b
+	.globl src_error
+src_error:
+	cmpi	0,r7,0
+	beq	1f
+	li	r6,-EFAULT
+	stw	r6,0(r7)
+1:	addze	r3,r0
+	blr
+
+	.globl dst_error
+dst_error:
+	cmpi	0,r8,0
+	beq	1f
+	li	r6,-EFAULT
+	stw	r6,0(r8)
+1:	addze	r3,r0
+	blr
+
+.section __ex_table,"a"
+	.align  3
+	.llong	81b,src_error_1
+	.llong	91b,dst_error
+	.llong	82b,src_error_2
+	.llong	92b,dst_error
+	.llong	83b,src_error_3
+	.llong	93b,dst_error
+	.llong	84b,src_error_3
+	.llong	94b,dst_error
+	.llong	95b,dst_error
+	.llong	96b,dst_error
+	.llong	97b,dst_error
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/lib/dec_and_lock.c linux/arch/ppc64/lib/dec_and_lock.c
--- linux.orig/arch/ppc64/lib/dec_and_lock.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/lib/dec_and_lock.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,38 @@
+/*
+ * ppc64 version of atomic_dec_and_lock() using cmpxchg
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/spinlock.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
+{
+	int counter;
+	int newcount;
+
+repeat:
+	counter = atomic_read(atomic);
+	newcount = counter-1;
+
+	if (!newcount)
+		goto slow_path;
+
+	newcount = cmpxchg(&atomic->counter, counter, newcount);
+
+	if (newcount != counter)
+		goto repeat;
+	return 0;
+
+slow_path:
+	spin_lock(lock);
+	if (atomic_dec_and_test(atomic))
+		return 1;
+	spin_unlock(lock);
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/lib/strcase.c linux/arch/ppc64/lib/strcase.c
--- linux.orig/arch/ppc64/lib/strcase.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/lib/strcase.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,31 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/ctype.h>
+
+int strcasecmp(const char *s1, const char *s2)
+{
+	int c1, c2;
+
+	do {
+		c1 = tolower(*s1++);
+		c2 = tolower(*s2++);
+	} while (c1 == c2 && c1 != 0);
+	return c1 - c2;
+}
+
+int strncasecmp(const char *s1, const char *s2, int n)
+{
+	int c1, c2;
+
+	do {
+		c1 = tolower(*s1++);
+		c2 = tolower(*s2++);
+	} while ((--n > 0) && c1 == c2 && c1 != 0);
+	return c1 - c2;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/lib/string.S linux/arch/ppc64/lib/string.S
--- linux.orig/arch/ppc64/lib/string.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/lib/string.S	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,575 @@
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <asm/ppc_asm.tmpl>
+#include <asm/processor.h>
+#include <asm/errno.h>
+
+#define CACHE_LINE_SIZE		128
+#define LG_CACHE_LINE_SIZE	7
+#define MAX_COPY_PREFETCH	1
+
+#define COPY_16_BYTES		\
+	lwz	r7,4(r4);	\
+	lwz	r8,8(r4);	\
+	lwz	r9,12(r4);	\
+	lwzu	r10,16(r4);	\
+	stw	r7,4(r6);	\
+	stw	r8,8(r6);	\
+	stw	r9,12(r6);	\
+	stwu	r10,16(r6)
+
+#define COPY_16_BYTES_WITHEX(n)	\
+8 ## n ## 0:			\
+	lwz	r7,4(r4);	\
+8 ## n ## 1:			\
+	lwz	r8,8(r4);	\
+8 ## n ## 2:			\
+	lwz	r9,12(r4);	\
+8 ## n ## 3:			\
+	lwzu	r10,16(r4);	\
+8 ## n ## 4:			\
+	stw	r7,4(r6);	\
+8 ## n ## 5:			\
+	stw	r8,8(r6);	\
+8 ## n ## 6:			\
+	stw	r9,12(r6);	\
+8 ## n ## 7:			\
+	stwu	r10,16(r6)
+
+#define COPY_16_BYTES_EXCODE(n)			\
+9 ## n ## 0:					\
+	addi	r5,r5,-(16 * n);		\
+	b	104f;				\
+9 ## n ## 1:					\
+	addi	r5,r5,-(16 * n);		\
+	b	105f;				\
+.section __ex_table,"a";			\
+	.align	3;				\
+	.llong	8 ## n ## 0b,9 ## n ## 0b;	\
+	.llong	8 ## n ## 1b,9 ## n ## 0b;	\
+	.llong	8 ## n ## 2b,9 ## n ## 0b;	\
+	.llong	8 ## n ## 3b,9 ## n ## 0b;	\
+	.llong	8 ## n ## 4b,9 ## n ## 1b;	\
+	.llong	8 ## n ## 5b,9 ## n ## 1b;	\
+	.llong	8 ## n ## 6b,9 ## n ## 1b;	\
+	.llong	8 ## n ## 7b,9 ## n ## 1b;	\
+.text
+
+CACHELINE_BYTES = CACHE_LINE_SIZE
+LG_CACHELINE_BYTES = LG_CACHE_LINE_SIZE
+CACHELINE_MASK = (CACHE_LINE_SIZE-1)
+
+_GLOBAL(strcpy)
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r5)
+	bne	1b
+	blr
+
+_GLOBAL(strncpy)
+	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r6)
+	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
+	blr
+
+_GLOBAL(strcat)
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r5)
+	cmpwi	0,r0,0
+	bne	1b
+	addi	r5,r5,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r5)
+	bne	1b
+	blr
+
+_GLOBAL(strcmp)
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r5)
+	cmpwi	1,r3,0
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	beqlr	1
+	beq	1b
+	blr
+
+_GLOBAL(strlen)
+	addi	r4,r3,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	bne	1b
+	subf	r3,r3,r4
+	blr
+
+/*
+ * Use dcbz on the complete cache lines in the destination
+ * to set them to zero.  This requires that the destination
+ * area is cacheable.  -- paulus
+ */
+_GLOBAL(cacheable_memzero)
+	mr	r5,r4
+	li	r4,0
+	addi	r6,r3,-4
+	cmplwi	0,r5,4
+	blt	7f
+	stwu	r4,4(r6)
+	beqlr
+	andi.	r0,r6,3
+	add	r5,r0,r5
+	subf	r6,r0,r6
+	clrlwi	r7,r6,32-LG_CACHELINE_BYTES
+	add	r8,r7,r5
+	srwi	r9,r8,LG_CACHELINE_BYTES
+	addic.	r9,r9,-1	/* total number of complete cachelines */
+	ble	2f
+	xori	r0,r7,CACHELINE_MASK & ~3
+	srwi.	r0,r0,2
+	beq	3f
+	mtctr	r0
+4:	stwu	r4,4(r6)
+	bdnz	4b
+3:	mtctr	r9
+	li	r7,4
+10:	dcbz	r7,r6
+	addi	r6,r6,CACHELINE_BYTES
+	bdnz	10b
+	clrlwi	r5,r8,32-LG_CACHELINE_BYTES
+	addi	r5,r5,4
+2:	srwi	r0,r5,2
+	mtctr	r0
+	bdz	6f
+1:	stwu	r4,4(r6)
+	bdnz	1b
+6:	andi.	r5,r5,3
+7:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r6,3
+8:	stbu	r4,1(r6)
+	bdnz	8b
+	blr
+
+_GLOBAL(memset)
+	rlwimi	r4,r4,8,16,23
+	rlwimi	r4,r4,16,0,15
+	addi	r6,r3,-4
+	cmplwi	0,r5,4
+	blt	7f
+	stwu	r4,4(r6)
+	beqlr
+	andi.	r0,r6,3
+	add	r5,r0,r5
+	subf	r6,r0,r6
+	srwi	r0,r5,2
+	mtctr	r0
+	bdz	6f
+1:	stwu	r4,4(r6)
+	bdnz	1b
+6:	andi.	r5,r5,3
+7:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r6,3
+8:	stbu	r4,1(r6)
+	bdnz	8b
+	blr
+
+_GLOBAL(memmove)
+	cmplw	0,r3,r4
+	bgt	.backwards_memcpy
+	/* fall through */
+
+_GLOBAL(memcpy)
+	srwi.	r7,r5,3
+	addi	r6,r3,-4
+	addi	r4,r4,-4
+	beq	2f			/* if less than 8 bytes to do */
+	andi.	r0,r6,3			/* get dest word aligned */
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,4(r4)
+	lwzu	r8,8(r4)
+	stw	r7,4(r6)
+	stwu	r8,8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,4(r4)
+	addi	r5,r5,-4
+	stwu	r0,4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r4,r4,3
+	addi	r6,r6,3
+4:	lbzu	r0,1(r4)
+	stbu	r0,1(r6)
+	bdnz	4b
+	blr
+5:	subfic	r0,r0,4
+	mtctr	r0
+6:	lbz	r7,4(r4)
+	addi	r4,r4,1
+	stb	r7,4(r6)
+	addi	r6,r6,1
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+_GLOBAL(backwards_memcpy)
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	add	r6,r3,r5
+	add	r4,r4,r5
+	beq	2f
+	andi.	r0,r6,3
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,-4(r4)
+	lwzu	r8,-8(r4)
+	stw	r7,-4(r6)
+	stwu	r8,-8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,-4(r4)
+	subi	r5,r5,4
+	stwu	r0,-4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+4:	lbzu	r0,-1(r4)
+	stbu	r0,-1(r6)
+	bdnz	4b
+	blr
+5:	mtctr	r0
+6:	lbzu	r7,-1(r4)
+	stbu	r7,-1(r6)
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+	
+_GLOBAL(memcmp)
+	cmpwi	0,r5,0
+	ble-	2f
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r6)
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	bdnzt	2,1b
+	blr
+2:	li	r3,0
+	blr
+
+_GLOBAL(memchr)
+	cmpwi	0,r5,0
+	ble-	2f
+	mtctr	r5
+	addi	r3,r3,-1
+1:	lbzu	r0,1(r3)
+	cmpw	0,r0,r4
+	bdnzf	2,1b
+	beqlr
+2:	li	r3,0
+	blr
+
+_GLOBAL(__copy_tofrom_user)
+	addi	r4,r4,-4
+	addi	r6,r3,-4
+	neg	r0,r3
+	andi.	r0,r0,CACHELINE_MASK	/* # bytes to start of cache line */
+	beq	58f
+
+	cmplw	0,r5,r0			/* is this more than total to do? */
+	blt	63f			/* if not much to do */
+	andi.	r8,r0,3			/* get it word-aligned first */
+	mtctr	r8
+	beq+	61f
+70:	lbz	r9,4(r4)		/* do some bytes */
+71:	stb	r9,4(r6)
+	addi	r4,r4,1
+	addi	r6,r6,1
+	bdnz	70b
+61:	subf	r5,r0,r5
+	srwi.	r0,r0,2
+	mtctr	r0
+	beq	58f
+72:	lwzu	r9,4(r4)		/* do some words */
+73:	stwu	r9,4(r6)
+	bdnz	72b
+
+58:	srwi.	r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+	clrlwi	r5,r5,32-LG_CACHELINE_BYTES
+	li	r11,4
+	beq	63f
+
+	/* Here we decide how far ahead to prefetch the source */
+#if MAX_COPY_PREFETCH > 1
+	/* Heuristically, for large transfers we prefetch
+	   MAX_COPY_PREFETCH cachelines ahead.  For small transfers
+	   we prefetch 1 cacheline ahead. */
+	cmpwi	r0,MAX_COPY_PREFETCH
+	li	r7,1
+	li	r3,4
+	ble	111f
+	li	r7,MAX_COPY_PREFETCH
+111:	mtctr	r7
+112:	dcbt	r3,r4
+	addi	r3,r3,CACHELINE_BYTES
+	bdnz	112b
+#else /* MAX_COPY_PREFETCH == 1 */
+	li	r3,CACHELINE_BYTES + 4
+	dcbt	r11,r4
+#endif /* MAX_COPY_PREFETCH */
+
+	mtctr	r0
+53:
+	dcbt	r3,r4
+	dcbz	r11,r6
+/* had to move these to keep extable in order */
+	.section __ex_table,"a"
+	.align	3
+	.llong	70b,100f
+	.llong	71b,101f
+	.llong	72b,102f
+	.llong	73b,103f
+	.llong	53b,105f
+	.text
+/* the main body of the cacheline loop */
+	COPY_16_BYTES_WITHEX(0)
+#if CACHE_LINE_SIZE >= 32
+	COPY_16_BYTES_WITHEX(1)
+#if CACHE_LINE_SIZE >= 64
+	COPY_16_BYTES_WITHEX(2)
+	COPY_16_BYTES_WITHEX(3)
+#if CACHE_LINE_SIZE >= 128
+	COPY_16_BYTES_WITHEX(4)
+	COPY_16_BYTES_WITHEX(5)
+	COPY_16_BYTES_WITHEX(6)
+	COPY_16_BYTES_WITHEX(7)
+#endif
+#endif
+#endif
+	bdnz	53b
+
+63:	srwi.	r0,r5,2
+	mtctr	r0
+	beq	64f
+30:	lwzu	r0,4(r4)
+31:	stwu	r0,4(r6)
+	bdnz	30b
+
+64:	andi.	r0,r5,3
+	mtctr	r0
+	beq+	65f
+40:	lbz	r0,4(r4)
+41:	stb	r0,4(r6)
+	addi	r4,r4,1
+	addi	r6,r6,1
+	bdnz	40b
+65:	li	r3,0
+	blr
+
+/* read fault, initial single-byte copy */
+100:	li	r4,0
+	b	90f
+/* write fault, initial single-byte copy */
+101:	li	r4,1
+90:	subf	r5,r8,r5
+	li	r3,0
+	b	99f
+/* read fault, initial word copy */
+102:	li	r4,0
+	b	91f
+/* write fault, initial word copy */
+103:	li	r4,1
+91:	li	r3,2
+	b	99f
+
+/*
+ * this stuff handles faults in the cacheline loop and branches to either
+ * 104f (if in read part) or 105f (if in write part), after updating r5
+ */
+	COPY_16_BYTES_EXCODE(0)
+#if CACHE_LINE_SIZE >= 32
+	COPY_16_BYTES_EXCODE(1)
+#if CACHE_LINE_SIZE >= 64
+	COPY_16_BYTES_EXCODE(2)
+	COPY_16_BYTES_EXCODE(3)
+#if CACHE_LINE_SIZE >= 128
+	COPY_16_BYTES_EXCODE(4)
+	COPY_16_BYTES_EXCODE(5)
+	COPY_16_BYTES_EXCODE(6)
+	COPY_16_BYTES_EXCODE(7)
+#endif
+#endif
+#endif
+
+/* read fault in cacheline loop */
+104:	li	r4,0
+	b	92f
+/* fault on dcbz (effectively a write fault) */
+/* or write fault in cacheline loop */
+105:	li	r4,1
+92:	li	r3,LG_CACHELINE_BYTES
+	b	99f
+/* read fault in final word loop */
+108:	li	r4,0
+	b	93f
+/* write fault in final word loop */
+109:	li	r4,1
+93:	andi.	r5,r5,3
+	li	r3,2
+	b	99f
+/* read fault in final byte loop */
+110:	li	r4,0
+	b	94f
+/* write fault in final byte loop */
+111:	li	r4,1
+94:	li	r5,0
+	li	r3,0
+/*
+ * At this stage the number of bytes not copied is
+ * r5 + (ctr << r3), and r4 is 0 for read or 1 for write.
+ */
+99:	mfctr	r0
+	slw	r3,r0,r3
+	add	r3,r3,r5
+	cmpwi	0,r4,0
+	bne	120f
+/* for read fault, clear out the destination: r3 bytes starting at 4(r6) */
+	srwi.	r0,r3,2
+	li	r9,0
+	mtctr	r0
+	beq	113f
+112:	stwu	r9,4(r6)
+	bdnz	112b
+113:	andi.	r0,r3,3
+	mtctr	r0
+	beq	120f
+114:	stb	r9,4(r6)
+	addi	r6,r6,1
+	bdnz	114b
+120:	blr
+
+	.section __ex_table,"a"
+	.align	3
+	.llong	30b,108b
+	.llong	31b,109b
+	.llong	40b,110b
+	.llong	41b,111b
+	.llong	112b,120b
+	.llong	114b,120b
+	.text
+
+_GLOBAL(__clear_user)
+	addi	r6,r3,-4
+	li	r3,0
+	li	r5,0
+	cmplwi	0,r4,4
+	blt	7f
+	/* clear a single word */
+11:	stwu	r5,4(r6)
+	beqlr
+	/* clear word sized chunks */
+	andi.	r0,r6,3
+	add	r4,r0,r4
+	subf	r6,r0,r6
+	srwi	r0,r4,2
+	mtctr	r0
+	bdz	6f
+1:	stwu	r5,4(r6)
+	bdnz	1b
+6:	andi.	r4,r4,3
+	/* clear byte sized chunks */
+7:	cmpwi	0,r4,0
+	beqlr
+	mtctr	r4
+	addi	r6,r6,3
+8:	stbu	r5,1(r6)
+	bdnz	8b
+	blr
+99:	li	r3,-EFAULT
+	blr
+
+	.section __ex_table,"a"
+	.align	3
+	.llong	11b,99b
+	.llong	1b,99b
+	.llong	8b,99b
+	.text
+
+_GLOBAL(__strncpy_from_user)
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+	cmpwi	0,r5,0
+	beq	2f
+	mtctr	r5
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r6)
+	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
+	beq	3f
+2:	addi	r6,r6,1
+3:	subf	r3,r3,r6
+	blr
+99:	li	r3,-EFAULT
+	blr
+
+	.section __ex_table,"a"
+	.align	3
+	.llong	1b,99b
+	.text
+
+/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
+_GLOBAL(__strnlen_user)
+	addi	r7,r3,-1
+	subf	r6,r7,r5	/* top+1 - str */
+	cmplw	0,r4,r6
+	bge	0f
+	mr	r6,r4
+0:	mtctr	r6		/* ctr = min(len, top - str) */
+1:	lbzu	r0,1(r7)	/* get next byte */
+	cmpwi	0,r0,0
+	bdnzf	2,1b		/* loop if --ctr != 0 && byte != 0 */
+	addi	r7,r7,1
+	subf	r3,r3,r7	/* number of bytes we have looked at */
+	beqlr			/* return if we found a 0 byte */
+	cmpw	0,r3,r4		/* did we look at all len bytes? */
+	blt	99f		/* if not, must have hit top */
+	addi	r3,r4,1		/* return len + 1 to indicate no null found */
+	blr
+99:	li	r3,0		/* bad address, return 0 */
+	blr
+
+	.section __ex_table,"a"
+	.align	3
+	.llong	1b,99b
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/mm/Makefile linux/arch/ppc64/mm/Makefile
--- linux.orig/arch/ppc64/mm/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/mm/Makefile	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,16 @@
+#
+# Makefile for the linux ppc-specific parts of the memory manager.
+#
+# 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).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+EXTRA_CFLAGS = -mno-minimal-toc
+
+O_TARGET := mm.o
+
+obj-y           := fault.o init.o extable.o imalloc.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/mm/extable.c linux/arch/ppc64/mm/extable.c
--- linux.orig/arch/ppc64/mm/extable.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/mm/extable.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/ppc/mm/extable.c
+ *
+ * from linux/arch/i386/mm/extable.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.
+ */
+
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+		 const struct exception_table_entry *last,
+		 unsigned long value)
+{
+        while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0)
+                        return mid->fixup;
+                else if (diff < 0)
+                        first = mid+1;
+                else
+                        last = mid-1;
+        }
+        return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+	unsigned long ret;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+	if (ret) return ret;
+#else
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->ex_table_start == NULL)
+			continue;
+		ret = search_one_table(mp->ex_table_start,
+				       mp->ex_table_end - 1, addr);
+		if (ret)
+			return ret;
+	}
+#endif
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/mm/fault.c linux/arch/ppc64/mm/fault.c
--- linux.orig/arch/ppc64/mm/fault.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/mm/fault.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,231 @@
+/*
+ *  arch/ppc/mm/fault.c
+ *
+ *  PowerPC version 
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Derived from "arch/i386/mm/fault.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  Modified by Cort Dougan and Paul Mackerras.
+ *
+ *  Modified for PPC64 by Dave Engebretsen (engebret@ibm.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.
+ */
+
+#include <linux/config.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 <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <asm/ppcdebug.h>
+
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+extern void (*debugger)(struct pt_regs *);
+extern void (*debugger_fault_handler)(struct pt_regs *);
+extern int (*debugger_dabr_match)(struct pt_regs *);
+int debugger_kernel_faults = 1;
+#endif
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+void bad_page_fault(struct pt_regs *, unsigned long);
+void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
+
+#ifdef CONFIG_PPCDBG
+extern unsigned long get_srr0(void);
+extern unsigned long get_srr1(void);
+#endif
+
+/*
+ * For 600- and 800-family processors, the error_code parameter is DSISR
+ * for a data fault, SRR1 for an instruction fault.
+ */
+void do_page_fault(struct pt_regs *regs, unsigned long address,
+		   unsigned long error_code)
+{
+	struct vm_area_struct * vma;
+	struct mm_struct *mm = current->mm;
+	siginfo_t info;
+	unsigned long code = SEGV_MAPERR;
+	unsigned long is_write = error_code & 0x02000000;
+	unsigned long mm_fault_return;
+
+	PPCDBG(PPCDBG_MM, "Entering do_page_fault: addr = 0x%16.16lx, error_code = %lx\n\tregs_trap = %lx, srr0 = %lx, srr1 = %lx\n", address, error_code, regs->trap, get_srr0(), get_srr1());
+	/*
+	 * Fortunately the bit assignments in SRR1 for an instruction
+	 * fault and DSISR for a data fault are mostly the same for the
+	 * bits we are interested in.  But there are some bits which
+	 * indicate errors in DSISR but can validly be set in SRR1.
+	 */
+	if (regs->trap == 0x400)
+		error_code &= 0x48200000;
+
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+	if (debugger_fault_handler && (regs->trap == 0x300 ||
+				regs->trap == 0x380)) {
+		debugger_fault_handler(regs);
+		return;
+	}
+
+	if (error_code & 0x00400000) {
+		/* DABR match */
+		if (debugger_dabr_match(regs))
+			return;
+	}
+#endif /* CONFIG_XMON || CONFIG_KGDB */
+
+	if (in_interrupt() || mm == NULL) {
+		bad_page_fault(regs, address);
+		return;
+	}
+	down_read(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+	PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma = 0x%16.16lx\n", vma);
+	if (!vma) {
+	        PPCDBG(PPCDBG_MM, "\tdo_page_fault: !vma\n");
+		goto bad_area;
+	}
+	PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_start = 0x%16.16lx, vma->vm_flags = 0x%16.16lx\n", vma->vm_start, vma->vm_flags);
+	if (vma->vm_start <= address) {
+		goto good_area;
+	}
+	if (!(vma->vm_flags & VM_GROWSDOWN)) {
+		PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_flags = %lx, %lx\n", vma->vm_flags, VM_GROWSDOWN);
+		goto bad_area;
+	}
+	if (expand_stack(vma, address)) {
+		PPCDBG(PPCDBG_MM, "\tdo_page_fault: expand_stack\n");
+		goto bad_area;
+	}
+
+good_area:
+	code = SEGV_ACCERR;
+	
+	/* a write */
+	if (is_write) {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	/* a read */
+	} else {
+		/* protection fault */
+		if (error_code & 0x08000000)
+			goto bad_area;
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			goto bad_area;
+	}
+
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+	PPCDBG(PPCDBG_MM, "\tdo_page_fault: calling handle_mm_fault\n");
+        mm_fault_return = handle_mm_fault(mm, vma, address, is_write);
+	PPCDBG(PPCDBG_MM, "\tdo_page_fault: handle_mm_fault = 0x%lx\n", 
+	       mm_fault_return);
+        switch(mm_fault_return) {
+        case 1:
+                current->min_flt++;
+                break;
+        case 2:
+                current->maj_flt++;
+                break;
+        case 0:
+                goto do_sigbus;
+        default:
+                goto out_of_memory;
+	}
+
+	up_read(&mm->mmap_sem);
+	return;
+
+bad_area:
+	up_read(&mm->mmap_sem);
+	
+	/* User mode accesses cause a SIGSEGV */
+	if (user_mode(regs)) {
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		info.si_code = code;
+		info.si_addr = (void *) address;
+		PPCDBG(PPCDBG_SIGNAL, "Bad addr in user: 0x%lx\n", address);
+#ifdef CONFIG_XMON
+	        ifppcdebug(PPCDBG_SIGNALXMON)
+        	    PPCDBG_ENTER_DEBUGGER_REGS(regs);
+#endif
+
+		force_sig_info(SIGSEGV, &info, current);
+		return;
+	}
+
+	bad_page_fault(regs, address);
+	return;
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+	up_read(&mm->mmap_sem);
+	printk("VM: killing process %s\n", current->comm);
+	if (user_mode(regs))
+		do_exit(SIGKILL);
+	bad_page_fault(regs, address);
+	return;
+
+do_sigbus:
+	up_read(&mm->mmap_sem);
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void *)address;
+	force_sig_info (SIGBUS, &info, current);
+	if (!user_mode(regs))
+		bad_page_fault(regs, address);
+}
+
+/*
+ * bad_page_fault is called when we have a bad access from the kernel.
+ * It is called from do_page_fault above and from some of the procedures
+ * in traps.c.
+ */
+void
+bad_page_fault(struct pt_regs *regs, unsigned long address)
+{
+	unsigned long fixup;
+
+	/* Are we prepared to handle this fault?  */
+	if ((fixup = search_exception_table(regs->nip)) != 0) {
+		regs->nip = fixup;
+		return;
+	}
+
+	/* kernel has accessed a bad area */
+	show_regs(regs);
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+	if (debugger_kernel_faults)
+		debugger(regs);
+#endif
+	print_backtrace( (unsigned long *)regs->gpr[1] );
+	panic("kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d",
+	      regs->nip,regs->link,address,current->comm,current->pid);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/mm/imalloc.c linux/arch/ppc64/mm/imalloc.c
--- linux.orig/arch/ppc64/mm/imalloc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/mm/imalloc.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,71 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ * 
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/spinlock.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+
+rwlock_t imlist_lock = RW_LOCK_UNLOCKED;
+struct vm_struct * imlist = NULL;
+
+struct vm_struct *get_im_area(unsigned long size)
+{
+	unsigned long addr;
+	struct vm_struct **p, *tmp, *area;
+  
+	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
+	if (!area)
+		return NULL;
+	addr = IMALLOC_START;
+	write_lock(&imlist_lock);
+	for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
+		if (size + addr < (unsigned long) tmp->addr)
+			break;
+		addr = tmp->size + (unsigned long) tmp->addr;
+		if (addr > IMALLOC_END-size) {
+			write_unlock(&imlist_lock);
+			kfree(area);
+			return NULL;
+		}
+	}
+	area->flags = 0;
+	area->addr = (void *)addr;
+	area->size = size;
+	area->next = *p;
+	*p = area;
+	write_unlock(&imlist_lock);
+	return area;
+}
+
+void ifree(void * addr)
+{
+	struct vm_struct **p, *tmp;
+  
+	if (!addr)
+		return;
+	if ((PAGE_SIZE-1) & (unsigned long) addr) {
+		printk(KERN_ERR "Trying to ifree() bad address (%p)\n", addr);
+		return;
+	}
+	write_lock(&imlist_lock);
+	for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
+		if (tmp->addr == addr) {
+			*p = tmp->next;
+			kfree(tmp);
+			write_unlock(&imlist_lock);
+			return;
+		}
+	}
+	write_unlock(&imlist_lock);
+	printk(KERN_ERR "Trying to ifree() nonexistent area (%p)\n", addr);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/mm/init.c linux/arch/ppc64/mm/init.c
--- linux.orig/arch/ppc64/mm/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/mm/init.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,656 @@
+/*
+ *  
+ *
+ *  PowerPC version 
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Paul Mackerras
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ *  Derived from "arch/i386/mm/init.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  Dave Engebretsen <engebret@us.ibm.com>
+ *      Rework for PPC64 port.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/config.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/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>		/* for initrd_* */
+#endif
+
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/abs_addr.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/rtas.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/tlb.h>
+#include <asm/naca.h>
+#include <asm/eeh.h>
+
+#include <asm/ppcdebug.h>
+
+#define	PGTOKB(pages)	(((pages) * PAGE_SIZE) >> 10)
+
+#ifdef CONFIG_PPC_ISERIES
+#include <asm/iSeries/iSeries_dma.h>
+#endif
+
+struct mmu_context_queue_t mmu_context_queue;
+int mem_init_done;
+unsigned long ioremap_bot = IMALLOC_BASE;
+
+static int boot_mapsize;
+static unsigned long totalram_pages;
+
+extern pgd_t swapper_pg_dir[];
+extern char __init_begin, __init_end;
+extern char __chrp_begin, __chrp_end;
+extern char __openfirmware_begin, __openfirmware_end;
+extern struct _of_tce_table of_tce_table[];
+extern char _start[], _end[];
+extern char _stext[], etext[];
+extern struct task_struct *current_set[NR_CPUS];
+
+void mm_init_ppc64(void);
+
+unsigned long *pmac_find_end_of_memory(void);
+extern unsigned long *find_end_of_memory(void);
+
+extern pgd_t ioremap_dir[];
+pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir;
+
+static void map_io_page(unsigned long va, unsigned long pa, int flags);
+extern void die_if_kernel(char *,struct pt_regs *,long);
+
+unsigned long klimit = (unsigned long)_end;
+
+HPTE *Hash=0;
+unsigned long Hash_size=0;
+unsigned long _SDR1=0;
+unsigned long _ASR=0;
+
+/* max amount of RAM to use */
+unsigned long __max_memory;
+
+/* This is declared as we are using the more or less generic 
+ * include/asm-ppc64/tlb.h file -- tgall
+ */
+mmu_gather_t     mmu_gathers[NR_CPUS];
+
+int do_check_pgt_cache(int low, int high)
+{
+	int freed = 0;
+
+	if (pgtable_cache_size > high) {
+		do {
+			if (pgd_quicklist)
+				free_page((unsigned long)pgd_alloc_one_fast(0)), ++freed;
+			if (pmd_quicklist)
+				free_page((unsigned long)pmd_alloc_one_fast(0, 0)), ++freed;
+			if (pte_quicklist)
+				free_page((unsigned long)pte_alloc_one_fast(0, 0)), ++freed;
+		} while (pgtable_cache_size > low);
+	}
+	return freed;	
+}
+
+void show_mem(void)
+{
+	int i,free = 0,total = 0,reserved = 0;
+	int shared = 0, cached = 0;
+
+	printk("Mem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+	i = max_mapnr;
+	while (i-- > 0) {
+		total++;
+		if (PageReserved(mem_map+i))
+			reserved++;
+		else if (PageSwapCache(mem_map+i))
+			cached++;
+		else if (!atomic_read(&mem_map[i].count))
+			free++;
+		else
+			shared += atomic_read(&mem_map[i].count) - 1;
+	}
+	printk("%d pages of RAM\n",total);
+	printk("%d free pages\n",free);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages shared\n",shared);
+	printk("%d pages swap cached\n",cached);
+	printk("%d pages in page table cache\n",(int)pgtable_cache_size);
+	show_buffers();
+}
+
+void si_meminfo(struct sysinfo *val)
+{
+ 	val->totalram = totalram_pages;
+	val->sharedram = 0;
+	val->freeram = nr_free_pages();
+	val->bufferram = atomic_read(&buffermem_pages);
+	val->totalhigh = 0;
+	val->freehigh = 0;
+	val->mem_unit = PAGE_SIZE;
+}
+
+void *
+ioremap(unsigned long addr, unsigned long size)
+{
+#ifdef CONFIG_PPC_ISERIES
+	return (void*)addr;
+#else
+	if(mem_init_done && (addr >> 60UL)) {
+		if (IS_EEH_TOKEN_DISABLED(addr))
+			return IO_TOKEN_TO_ADDR(addr);
+		return (void*)addr; /* already mapped address or EEH token. */
+	}
+	return __ioremap(addr, size, _PAGE_NO_CACHE);
+#endif
+}
+
+extern struct vm_struct * get_im_area( unsigned long size );
+
+void *
+__ioremap(unsigned long addr, unsigned long size, unsigned long flags)
+{
+	unsigned long pa, ea, i;
+
+	/*
+	 * Choose an address to map it to.
+	 * Once the imalloc system is running, we use it.
+	 * Before that, we map using addresses going
+	 * up from ioremap_bot.  imalloc will use
+	 * the addresses from ioremap_bot through
+	 * IMALLOC_END (0xE000001fffffffff)
+	 * 
+	 */
+	pa = addr & PAGE_MASK;
+	size = PAGE_ALIGN(addr + size) - pa;
+
+	if (size == 0)
+		return NULL;
+
+	if (mem_init_done) {
+		struct vm_struct *area;
+		area = get_im_area(size);
+		if (area == 0)
+			return NULL;
+		ea = (unsigned long)(area->addr);
+	} 
+	else {
+		ea = ioremap_bot;
+		ioremap_bot += size;
+        }
+
+	if ((flags & _PAGE_PRESENT) == 0)
+		flags |= pgprot_val(PAGE_KERNEL);
+	if (flags & (_PAGE_NO_CACHE | _PAGE_WRITETHRU))
+		flags |= _PAGE_GUARDED;
+
+	for (i = 0; i < size; i += PAGE_SIZE) {
+		map_io_page(ea+i, pa+i, flags);
+	}
+
+	return (void *) (ea + (addr & ~PAGE_MASK));
+}
+
+void iounmap(void *addr) 
+{
+#ifdef CONFIG_PPC_ISERIES
+     /* iSeries I/O Remap is a noop              */
+	return;
+#else 
+	/* DRENG / PPPBBB todo */
+	return;
+#endif
+}
+
+/*
+ * map_io_page currently only called by __ioremap
+ * map_io_page adds an entry to the ioremap page table
+ * and adds an entry to the HPT, possibly bolting it
+ */
+static void map_io_page(unsigned long ea, unsigned long pa, int flags)
+{
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	unsigned long vsid;
+	
+	if (mem_init_done) {
+		spin_lock(&ioremap_mm.page_table_lock);
+		pgdp = pgd_offset_i(ea);
+		pmdp = pmd_alloc(&ioremap_mm, pgdp, ea);
+		ptep = pte_alloc(&ioremap_mm, pmdp, ea);
+
+		pa = absolute_to_phys(pa);
+		set_pte(ptep, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
+		spin_unlock(&ioremap_mm.page_table_lock);
+	} else {
+		/* If the mm subsystem is not fully up, we cannot create a
+		 * linux page table entry for this mapping.  Simply bolt an
+		 * entry in the hardware page table. 
+ 		 */
+		vsid = get_kernel_vsid(ea);
+		make_pte(htab_data.htab,
+			(vsid << 28) | (ea & 0xFFFFFFF), // va (NOT the ea)
+			pa, 
+			_PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX,
+			htab_data.htab_hash_mask, 0);
+	}
+}
+
+void
+local_flush_tlb_all(void)
+{
+	/* Implemented to just flush the vmalloc area.
+	 * vmalloc is the only user of flush_tlb_all.
+	 */
+	local_flush_tlb_range( NULL, VMALLOC_START, VMALLOC_END );
+}
+
+void
+local_flush_tlb_mm(struct mm_struct *mm)
+{
+	if ( mm->map_count ) {
+		struct vm_area_struct *mp;
+		for ( mp = mm->mmap; mp != NULL; mp = mp->vm_next )
+			local_flush_tlb_range( mm, mp->vm_start, mp->vm_end );
+	}
+	else	/* MIKEC: It is not clear why this is needed */
+		/* paulus: it is needed to clear out stale HPTEs
+		 * when an address space (represented by an mm_struct)
+		 * is being destroyed. */
+		local_flush_tlb_range( mm, USER_START, USER_END );
+}
+
+/*
+ * Callers should hold the mm->page_table_lock
+ */
+void
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+{
+	unsigned long context = 0;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *ptep;
+	
+	switch( REGION_ID(vmaddr) ) {
+	case VMALLOC_REGION_ID:
+		pgd = pgd_offset_k( vmaddr );
+		break;
+	case IO_REGION_ID:
+		pgd = pgd_offset_i( vmaddr );
+		break;
+	case USER_REGION_ID:
+		pgd = pgd_offset( vma->vm_mm, vmaddr );
+		context = vma->vm_mm->context;
+		break;
+	default:
+		panic("local_flush_tlb_page: invalid region 0x%016lx", vmaddr);
+	
+	}
+
+	if (!pgd_none(*pgd)) {
+		pmd = pmd_offset(pgd, vmaddr);
+		if (!pmd_none(*pmd)) {
+			ptep = pte_offset(pmd, vmaddr);
+			/* Check if HPTE might exist and flush it if so */
+			if (pte_val(*ptep) & _PAGE_HASHPTE)
+				flush_hash_page(context, vmaddr, ptep);
+		}
+	}
+}
+
+void
+local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *ptep;
+	unsigned long pgd_end, pmd_end;
+	unsigned long context;
+
+	if ( start >= end )
+		panic("flush_tlb_range: start (%016lx) greater than end (%016lx)\n", start, end );
+
+	if ( REGION_ID(start) != REGION_ID(end) )
+		panic("flush_tlb_range: start (%016lx) and end (%016lx) not in same region\n", start, end );
+	
+	context = 0;
+
+	switch( REGION_ID(start) ) {
+	case VMALLOC_REGION_ID:
+		pgd = pgd_offset_k( start );
+		break;
+	case IO_REGION_ID:
+		pgd = pgd_offset_i( start );
+		break;
+	case USER_REGION_ID:
+		pgd = pgd_offset( mm, start );
+		context = mm->context;
+		break;
+	default:
+		panic("flush_tlb_range: invalid region for start (%016lx) and end (%016lx)\n", start, end);
+	
+	}
+
+	do {
+		pgd_end = (start + PGDIR_SIZE) & PGDIR_MASK;
+		if ( pgd_end > end ) 
+			pgd_end = end;
+		if ( !pgd_none( *pgd ) ) {
+			pmd = pmd_offset( pgd, start );
+			do {
+				pmd_end = ( start + PMD_SIZE ) & PMD_MASK;
+				if ( pmd_end > end )
+					pmd_end = end;
+				if ( !pmd_none( *pmd ) ) {
+					ptep = pte_offset( pmd, start );
+					do {
+						if ( pte_val(*ptep) & _PAGE_HASHPTE )
+							flush_hash_page( context, start, ptep );
+						start += PAGE_SIZE;
+						++ptep;
+					} while ( start < pmd_end );
+				}
+				else
+					start = pmd_end;
+				++pmd;
+			} while ( start < pgd_end );
+		}
+		else
+			start = pgd_end;
+		++pgd;
+	} while ( start < end );
+}
+
+
+void __init free_initmem(void)
+{
+	unsigned long a;
+	unsigned long num_freed_pages = 0;
+#define FREESEC(START,END,CNT) do { \
+	a = (unsigned long)(&START); \
+	for (; a < (unsigned long)(&END); a += PAGE_SIZE) { \
+	  	clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags); \
+		set_page_count(mem_map+MAP_NR(a), 1); \
+		free_page(a); \
+		CNT++; \
+	} \
+} while (0)
+
+	FREESEC(__init_begin,__init_end,num_freed_pages);
+
+	printk ("Freeing unused kernel memory: %ldk init\n",
+		PGTOKB(num_freed_pages));
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	unsigned long xstart = start;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(mem_map + MAP_NR(start));
+		set_page_count(mem_map+MAP_NR(start), 1);
+		free_page(start);
+		totalram_pages++;
+	}
+	printk ("Freeing initrd memory: %ldk freed\n", (end - xstart) >> 10);
+}
+#endif
+
+
+
+/*
+ * Do very early mm setup.
+ */
+void __init mm_init_ppc64(void) {
+	struct paca_struct *lpaca;
+	unsigned long guard_page, index;
+
+	ppc_md.progress("MM:init", 0);
+
+	/* Reserve all contexts < FIRST_USER_CONTEXT for kernel use.
+	 * The range of contexts [FIRST_USER_CONTEXT, NUM_USER_CONTEXT)
+	 * are stored on a stack/queue for easy allocation and deallocation.
+	 */
+        mmu_context_queue.lock = SPIN_LOCK_UNLOCKED;
+        mmu_context_queue.head = 0;
+        mmu_context_queue.tail = NUM_USER_CONTEXT-1;
+        mmu_context_queue.size = NUM_USER_CONTEXT;
+	for(index=0; index < NUM_USER_CONTEXT ;index++) {
+                mmu_context_queue.elements[index] = index+FIRST_USER_CONTEXT;
+	}
+
+	/* Setup guard pages for the Paca's */
+	for (index = 0; index < NR_CPUS; index++) {
+		lpaca = &paca[index];
+		guard_page = ((unsigned long)lpaca) + 0x1000;
+		ppc_md.hpte_updateboltedpp(PP_RXRX, guard_page);
+	}
+
+	ppc_md.progress("MM:exit", 0x211);
+}
+
+
+
+/*
+ * Initialize the bootmem system and give it all the memory we
+ * have available.
+ */
+void __init do_init_bootmem(void)
+{
+	unsigned long i;
+	unsigned long start, bootmap_pages;
+	unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
+
+	PPCDBG(PPCDBG_MMINIT, "do_init_bootmem: start\n");
+	/*
+	 * Find an area to use for the bootmem bitmap.  Calculate the size of
+	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
+	 * Add 1 additional page in case the address isn't page-aligned.
+	 */
+	bootmap_pages = bootmem_bootmap_pages(total_pages);
+
+	start = (unsigned long)__a2p(lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE));
+	if( start == 0 ) {
+		udbg_printf("do_init_bootmem: failed to allocate a bitmap.\n");
+		udbg_printf("\tbootmap_pages = 0x%lx.\n", bootmap_pages);
+		PPCDBG_ENTER_DEBUGGER(); 
+	}
+
+	PPCDBG(PPCDBG_MMINIT, "\tstart               = 0x%lx\n", start);
+	PPCDBG(PPCDBG_MMINIT, "\tbootmap_pages       = 0x%lx\n", bootmap_pages);
+	PPCDBG(PPCDBG_MMINIT, "\tphysicalMemorySize  = 0x%lx\n", naca->physicalMemorySize);
+
+	boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
+	PPCDBG(PPCDBG_MMINIT, "\tboot_mapsize        = 0x%lx\n", boot_mapsize);
+
+	/* add all physical memory to the bootmem map */
+	for (i=0; i < lmb.memory.cnt ;i++) {
+		unsigned long physbase, size;
+		unsigned long type = lmb.memory.region[i].type;
+
+		if ( type != LMB_MEMORY_AREA )
+			continue;
+
+		physbase = lmb.memory.region[i].physbase;
+		size = lmb.memory.region[i].size;
+		free_bootmem(physbase, size);
+	}
+	/* reserve the sections we're already using */
+	for (i=0; i < lmb.reserved.cnt ;i++) {
+		unsigned long physbase = lmb.reserved.region[i].physbase;
+		unsigned long size = lmb.reserved.region[i].size;
+#if 0 /* PPPBBB */
+		if ( (physbase == 0) && (size < (16<<20)) ) {
+			size = 16 << 20;
+		}
+#endif
+		reserve_bootmem(physbase, size);
+	}
+
+	PPCDBG(PPCDBG_MMINIT, "do_init_bootmem: end\n");
+}
+
+/*
+ * paging_init() sets up the page tables - in fact we've already done this.
+ */
+void __init paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES], i;
+
+	/*
+	 * All pages are DMA-able so we put them all in the DMA zone.
+	 */
+	zones_size[0] = lmb_end_of_DRAM() >> PAGE_SHIFT;
+	for (i = 1; i < MAX_NR_ZONES; i++)
+		zones_size[i] = 0;
+	free_area_init(zones_size);
+}
+
+extern unsigned long prof_shift;
+extern unsigned long prof_len;
+extern unsigned int * prof_buffer;
+extern unsigned long dprof_shift;
+extern unsigned long dprof_len;
+extern unsigned int * dprof_buffer;
+
+void initialize_paca_hardware_interrupt_stack(void);
+
+void __init mem_init(void)
+{
+	extern char *sysmap; 
+	extern unsigned long sysmap_size;
+	unsigned long addr;
+	int codepages = 0;
+	int datapages = 0;
+	int initpages = 0;
+	unsigned long va_rtas_base = (unsigned long)__va(rtas.base);
+
+	max_mapnr = max_low_pfn;
+	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+	num_physpages = max_mapnr;	/* RAM is assumed contiguous */
+
+	totalram_pages += free_all_bootmem();
+
+	ifppcdebug(PPCDBG_MMINIT) {
+		udbg_printf("mem_init: totalram_pages = 0x%lx\n", totalram_pages);
+		udbg_printf("mem_init: va_rtas_base   = 0x%lx\n", va_rtas_base); 
+		udbg_printf("mem_init: va_rtas_end    = 0x%lx\n", PAGE_ALIGN(va_rtas_base+rtas.size)); 
+		udbg_printf("mem_init: pinned start   = 0x%lx\n", __va(0)); 
+		udbg_printf("mem_init: pinned end     = 0x%lx\n", PAGE_ALIGN(klimit)); 
+	}
+
+	if ( sysmap_size )
+		for (addr = (unsigned long)sysmap;
+		     addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
+		     addr += PAGE_SIZE)
+			SetPageReserved(mem_map + MAP_NR(addr));
+	
+	for (addr = KERNELBASE; addr <= (unsigned long)__va(lmb_end_of_DRAM());
+	     addr += PAGE_SIZE) {
+		if (!PageReserved(mem_map + MAP_NR(addr)))
+			continue;
+		if (addr < (ulong) etext)
+			codepages++;
+
+		else if (addr >= (unsigned long)&__init_begin
+			 && addr < (unsigned long)&__init_end)
+			initpages++;
+		else if (addr < klimit)
+			datapages++;
+	}
+
+        printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]\n",
+	       (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
+	       codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
+	       initpages<< (PAGE_SHIFT-10),
+	       PAGE_OFFSET, (unsigned long)__va(lmb_end_of_DRAM()));
+	mem_init_done = 1;
+
+	/* set the last page of each hardware interrupt stack to be protected */
+	initialize_paca_hardware_interrupt_stack();
+
+#ifdef CONFIG_PPC_ISERIES
+	create_virtual_bus_tce_table();
+	/* HACK HACK This allows the iSeries profiling to use /proc/profile */
+	prof_shift = dprof_shift;
+	prof_len = dprof_len;
+	prof_buffer = dprof_buffer;
+#endif
+}
+
+/*
+ * This is called when a page has been modified by the kernel.
+ * It just marks the page as not i-cache clean.  We do the i-cache
+ * flush later when the page is given to a user process, if necessary.
+ */
+void flush_dcache_page(struct page *page)
+{
+	clear_bit(PG_arch_1, &page->flags);
+}
+
+void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	if (page->mapping && !PageReserved(page)
+	    && !test_bit(PG_arch_1, &page->flags)) {
+		__flush_dcache_icache(page_address(page));
+		set_bit(PG_arch_1, &page->flags);
+	}
+}
+
+void clear_user_page(void *page, unsigned long vaddr)
+{
+	clear_page(page);
+}
+
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr)
+{
+	copy_page(vto, vfrom);
+	__flush_dcache_icache(vto);
+}
+
+void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+			     unsigned long addr, int len)
+{
+	unsigned long maddr;
+
+	maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK);
+	flush_icache_range(maddr, maddr + len);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/vmlinux.lds linux/arch/ppc64/vmlinux.lds
--- linux.orig/arch/ppc64/vmlinux.lds	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/vmlinux.lds	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,140 @@
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+/*  .init          : { *(.init)	} =0*/
+  .plt : { *(.plt) }
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  . = ALIGN(4096);
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFFFFFFFFFF000;
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.got.plt) *(.got)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  . = ALIGN(4096);
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  .fixup   : { *(.fixup) }
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  __start___ksymtab = .;        /* Kernel symbol table */
+  __ksymtab : { *(__ksymtab) }
+  __stop___ksymtab = .;
+  __start___kallsyms = .;	/* All kernel symbols */
+  __kallsyms : { *(__kallsyms) }
+  __stop___kallsyms = .;
+
+
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.page_aligned) }
+
+  . = ALIGN(128);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { 
+    *(.data.init);
+    __vtop_table_begin = .;
+    *(.vtop_fixup);
+    __vtop_table_end = .;
+    __ptov_table_begin = .;
+    *(.ptov_fixup);
+    __ptov_table_end = .;
+  }
+  . = ALIGN(16);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) }
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) }
+  __initcall_end = .;
+
+
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __chrp_begin = .;
+  .text.chrp : { *(.text.chrp) }
+  .data.chrp : { *(.data.chrp) }
+  . = ALIGN(4096);
+  __chrp_end = .;
+
+  . = ALIGN(4096);
+  __openfirmware_begin = .;
+  .text.openfirmware : { *(.text.openfirmware) }
+  .data.openfirmware : { *(.data.openfirmware) }
+  . = ALIGN(4096);
+  __openfirmware_end = .;
+
+  __toc_start = .;
+  .toc       :
+  {
+   *(.toc)
+  }
+  . = ALIGN(4096);
+  __toc_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+
+  . = ALIGN(4096);
+  _end = . ;
+  PROVIDE (end = .);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/Makefile linux/arch/ppc64/xmon/Makefile
--- linux.orig/arch/ppc64/xmon/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/Makefile	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,9 @@
+# Makefile for xmon
+
+EXTRA_CFLAGS = -mno-minimal-toc
+
+O_TARGET = x.o
+
+obj-y       := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/ansidecl.h linux/arch/ppc64/xmon/ansidecl.h
--- linux.orig/arch/ppc64/xmon/ansidecl.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/ansidecl.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,141 @@
+/* ANSI and traditional C compatability macros
+   Copyright 1991, 1992 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+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.  */
+
+/* ANSI and traditional C compatibility macros
+
+   ANSI C is assumed if __STDC__ is #defined.
+
+   Macro	ANSI C definition	Traditional C definition
+   -----	---- - ----------	----------- - ----------
+   PTR		`void *'		`char *'
+   LONG_DOUBLE	`long double'		`double'
+   VOLATILE	`volatile'		`'
+   SIGNED	`signed'		`'
+   PTRCONST	`void *const'		`char *'
+   ANSI_PROTOTYPES  1			not defined
+
+   CONST is also defined, but is obsolete.  Just use const.
+
+   DEFUN (name, arglist, args)
+
+	Defines function NAME.
+
+	ARGLIST lists the arguments, separated by commas and enclosed in
+	parentheses.  ARGLIST becomes the argument list in traditional C.
+
+	ARGS list the arguments with their types.  It becomes a prototype in
+	ANSI C, and the type declarations in traditional C.  Arguments should
+	be separated with `AND'.  For functions with a variable number of
+	arguments, the last thing listed should be `DOTS'.
+
+   DEFUN_VOID (name)
+
+	Defines a function NAME, which takes no arguments.
+
+   obsolete --     EXFUN (name, (prototype))	-- obsolete.
+
+	Replaced by PARAMS.  Do not use; will disappear someday soon.
+	Was used in external function declarations.
+	In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
+	parentheses).  In traditional C it is `NAME()'.
+	For a function that takes no arguments, PROTOTYPE should be `(void)'.
+
+    PARAMS ((args))
+
+	We could use the EXFUN macro to handle prototype declarations, but
+	the name is misleading and the result is ugly.  So we just define a
+	simple macro to handle the parameter lists, as in:
+
+	      static int foo PARAMS ((int, char));
+
+	This produces:  `static int foo();' or `static int foo (int, char);'
+
+	EXFUN would have done it like this:
+
+	      static int EXFUN (foo, (int, char));
+
+	but the function is not external...and it's hard to visually parse
+	the function name out of the mess.   EXFUN should be considered
+	obsolete; new code should be written to use PARAMS.
+
+    For example:
+	extern int printf PARAMS ((CONST char *format DOTS));
+	int DEFUN(fprintf, (stream, format),
+		  FILE *stream AND CONST char *format DOTS) { ... }
+	void DEFUN_VOID(abort) { ... }
+*/
+
+#ifndef	_ANSIDECL_H
+
+#define	_ANSIDECL_H	1
+
+
+/* Every source file includes this file,
+   so they will all get the switch for lint.  */
+/* LINTLIBRARY */
+
+
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32)
+/* All known AIX compilers implement these things (but don't always
+   define __STDC__).  The RISC/OS MIPS compiler defines these things
+   in SVR4 mode, but does not define __STDC__.  */
+
+#define	PTR		void *
+#define	PTRCONST	void *CONST
+#define	LONG_DOUBLE	long double
+
+#define	AND		,
+#define	NOARGS		void
+#define	CONST		const
+#define	VOLATILE	volatile
+#define	SIGNED		signed
+#define	DOTS		, ...
+
+#define	EXFUN(name, proto)		name proto
+#define	DEFUN(name, arglist, args)	name(args)
+#define	DEFUN_VOID(name)		name(void)
+
+#define PROTO(type, name, arglist)	type name arglist
+#define PARAMS(paramlist)		paramlist
+#define ANSI_PROTOTYPES			1
+
+#else	/* Not ANSI C.  */
+
+#define	PTR		char *
+#define	PTRCONST	PTR
+#define	LONG_DOUBLE	double
+
+#define	AND		;
+#define	NOARGS
+#define	CONST
+#ifndef const /* some systems define it in header files for non-ansi mode */
+#define	const
+#endif
+#define	VOLATILE
+#define	SIGNED
+#define	DOTS
+
+#define	EXFUN(name, proto)		name()
+#define	DEFUN(name, arglist, args)	name arglist args;
+#define	DEFUN_VOID(name)		name()
+#define PROTO(type, name, arglist) type name ()
+#define PARAMS(paramlist)		()
+
+#endif	/* ANSI C.  */
+
+#endif	/* ansidecl.h	*/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/nonstdio.h linux/arch/ppc64/xmon/nonstdio.h
--- linux.orig/arch/ppc64/xmon/nonstdio.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/nonstdio.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,22 @@
+typedef int	FILE;
+extern FILE *xmon_stdin, *xmon_stdout;
+#define EOF	(-1)
+#define stdin	xmon_stdin
+#define stdout	xmon_stdout
+#define printf	xmon_printf
+#define fprintf	xmon_fprintf
+#define fputs	xmon_fputs
+#define fgets	xmon_fgets
+#define putchar	xmon_putchar
+#define getchar	xmon_getchar
+#define putc	xmon_putc
+#define getc	xmon_getc
+#define fopen(n, m)	NULL
+#define fflush(f)	do {} while (0)
+#define fclose(f)	do {} while (0)
+extern char *fgets(char *, int, void *);
+extern void xmon_printf(const char *, ...);
+extern void xmon_fprintf(void *, const char *, ...);
+extern void xmon_sprintf(char *, const char *, ...);
+
+#define perror(s)	printf("%s: no files!\n", (s))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/ppc-dis.c linux/arch/ppc64/xmon/ppc-dis.c
--- linux.orig/arch/ppc64/xmon/ppc-dis.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/ppc-dis.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,190 @@
+/* ppc-dis.c -- Disassemble PowerPC instructions
+   Copyright 1994 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "nonstdio.h"
+#include "ansidecl.h"
+#include "ppc.h"
+
+static int print_insn_powerpc PARAMS ((FILE *, unsigned long insn,
+				       unsigned long memaddr, int dialect));
+
+extern void print_address PARAMS((unsigned long memaddr));
+
+/* Print a big endian PowerPC instruction.  For convenience, also
+   disassemble instructions supported by the Motorola PowerPC 601.  */
+
+int
+print_insn_big_powerpc (FILE *out, unsigned long insn, unsigned long memaddr)
+{
+  return print_insn_powerpc (out, insn, memaddr,
+			     PPC_OPCODE_PPC | PPC_OPCODE_601);
+}
+
+/* Print a PowerPC or POWER instruction.  */
+
+static int
+print_insn_powerpc (FILE *out, unsigned long insn, unsigned long memaddr,
+		    int dialect)
+{
+  const struct powerpc_opcode *opcode;
+  const struct powerpc_opcode *opcode_end;
+  unsigned long op;
+
+  /* Get the major opcode of the instruction.  */
+  op = PPC_OP (insn);
+
+  /* Find the first match in the opcode table.  We could speed this up
+     a bit by doing a binary search on the major opcode.  */
+  opcode_end = powerpc_opcodes + powerpc_num_opcodes;
+  for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
+    {
+      unsigned long table_op;
+      const unsigned char *opindex;
+      const struct powerpc_operand *operand;
+      int invalid;
+      int need_comma;
+      int need_paren;
+
+      table_op = PPC_OP (opcode->opcode);
+      if (op < table_op)
+		break;
+      if (op > table_op)
+		continue;
+
+      if ((insn & opcode->mask) != opcode->opcode
+	  || (opcode->flags & dialect) == 0)
+		continue;
+
+      /* Make two passes over the operands.  First see if any of them
+		 have extraction functions, and, if they do, make sure the
+		 instruction is valid.  */
+      invalid = 0;
+      for (opindex = opcode->operands; *opindex != 0; opindex++)
+		{
+		  operand = powerpc_operands + *opindex;
+		  if (operand->extract)
+		    (*operand->extract) (insn, &invalid);
+		}
+      if (invalid)
+		continue;
+
+      /* The instruction is valid.  */
+      fprintf(out, "%s", opcode->name);
+      if (opcode->operands[0] != 0)
+		fprintf(out, "\t");
+
+      /* Now extract and print the operands.  */
+      need_comma = 0;
+      need_paren = 0;
+      for (opindex = opcode->operands; *opindex != 0; opindex++)
+		{
+		  long value;
+
+		  operand = powerpc_operands + *opindex;
+
+		  /* Operands that are marked FAKE are simply ignored.  We
+		     already made sure that the extract function considered
+		     the instruction to be valid.  */
+		  if ((operand->flags & PPC_OPERAND_FAKE) != 0)
+		    continue;
+
+		  /* Extract the value from the instruction.  */
+		  if (operand->extract)
+		    value = (*operand->extract) (insn, (int *) 0);
+		  else
+		    {
+		      value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+		      if ((operand->flags & PPC_OPERAND_SIGNED) != 0
+			  && (value & (1 << (operand->bits - 1))) != 0)
+			value -= 1 << operand->bits;
+		    }
+
+		  /* If the operand is optional, and the value is zero, don't
+		     print anything.  */
+		  if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+		      && (operand->flags & PPC_OPERAND_NEXT) == 0
+		      && value == 0)
+		    continue;
+
+		  if (need_comma)
+		    {
+		      fprintf(out, ",");
+		      need_comma = 0;
+		    }
+
+		  /* Print the operand as directed by the flags.  */
+		  if ((operand->flags & PPC_OPERAND_GPR) != 0)
+		    fprintf(out, "r%ld", value);
+		  else if ((operand->flags & PPC_OPERAND_FPR) != 0)
+		    fprintf(out, "f%ld", value);
+		  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
+		    print_address (memaddr + value);
+		  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+		    print_address (value & 0xffffffff);
+		  else if ((operand->flags & PPC_OPERAND_CR) == 0
+			   || (dialect & PPC_OPCODE_PPC) == 0)
+		    fprintf(out, "%ld", value);
+		  else
+		    {
+		      if (operand->bits == 3)
+				fprintf(out, "cr%d", value);
+		      else
+			{
+			  static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
+			  int cr;
+			  int cc;
+
+			  cr = value >> 2;
+			  if (cr != 0)
+			    fprintf(out, "4*cr%d", cr);
+			  cc = value & 3;
+			  if (cc != 0)
+			    {
+			      if (cr != 0)
+					fprintf(out, "+");
+			      fprintf(out, "%s", cbnames[cc]);
+			    }
+			}
+	    }
+
+	  if (need_paren)
+	    {
+	      fprintf(out, ")");
+	      need_paren = 0;
+	    }
+
+	  if ((operand->flags & PPC_OPERAND_PARENS) == 0)
+	    need_comma = 1;
+	  else
+	    {
+	      fprintf(out, "(");
+	      need_paren = 1;
+	    }
+	}
+
+      /* We have found and printed an instruction; return.  */
+      return 4;
+    }
+
+  /* We could not find a match.  */
+  fprintf(out, ".long 0x%lx", insn);
+
+  return 4;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/ppc-opc.c linux/arch/ppc64/xmon/ppc-opc.c
--- linux.orig/arch/ppc64/xmon/ppc-opc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/ppc-opc.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,2816 @@
+/* ppc-opc.c -- PowerPC opcode list
+   Copyright 1994 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <linux/posix_types.h>
+#include "ansidecl.h"
+#include "ppc.h"
+
+/* This file holds the PowerPC opcode table.  The opcode table
+   includes almost all of the extended instruction mnemonics.  This
+   permits the disassembler to use them, and simplifies the assembler
+   logic, at the cost of increasing the table size.  The table is
+   strictly constant data, so the compiler should be able to put it in
+   the .text section.
+
+   This file also holds the operand table.  All knowledge about
+   inserting operands into instructions and vice-versa is kept in this
+   file.  */
+
+/* Local insertion and extraction functions.  */
+
+static unsigned long insert_bat PARAMS ((unsigned long, long, const char **));
+static long extract_bat PARAMS ((unsigned long, int *));
+static unsigned long insert_bba PARAMS ((unsigned long, long, const char **));
+static long extract_bba PARAMS ((unsigned long, int *));
+static unsigned long insert_bd PARAMS ((unsigned long, long, const char **));
+static long extract_bd PARAMS ((unsigned long, int *));
+static unsigned long insert_bdm PARAMS ((unsigned long, long, const char **));
+static long extract_bdm PARAMS ((unsigned long, int *));
+static unsigned long insert_bdp PARAMS ((unsigned long, long, const char **));
+static long extract_bdp PARAMS ((unsigned long, int *));
+static unsigned long insert_bo PARAMS ((unsigned long, long, const char **));
+static long extract_bo PARAMS ((unsigned long, int *));
+static unsigned long insert_boe PARAMS ((unsigned long, long, const char **));
+static long extract_boe PARAMS ((unsigned long, int *));
+static unsigned long insert_ds PARAMS ((unsigned long, long, const char **));
+static long extract_ds PARAMS ((unsigned long, int *));
+static unsigned long insert_li PARAMS ((unsigned long, long, const char **));
+static long extract_li PARAMS ((unsigned long, int *));
+static unsigned long insert_mbe PARAMS ((unsigned long, long, const char **));
+static long extract_mbe PARAMS ((unsigned long, int *));
+static unsigned long insert_mb6 PARAMS ((unsigned long, long, const char **));
+static long extract_mb6 PARAMS ((unsigned long, int *));
+static unsigned long insert_nb PARAMS ((unsigned long, long, const char **));
+static long extract_nb PARAMS ((unsigned long, int *));
+static unsigned long insert_nsi PARAMS ((unsigned long, long, const char **));
+static long extract_nsi PARAMS ((unsigned long, int *));
+static unsigned long insert_ral PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_ram PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_ras PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_rbs PARAMS ((unsigned long, long, const char **));
+static long extract_rbs PARAMS ((unsigned long, int *));
+static unsigned long insert_sh6 PARAMS ((unsigned long, long, const char **));
+static long extract_sh6 PARAMS ((unsigned long, int *));
+static unsigned long insert_spr PARAMS ((unsigned long, long, const char **));
+static long extract_spr PARAMS ((unsigned long, int *));
+static unsigned long insert_tbr PARAMS ((unsigned long, long, const char **));
+static long extract_tbr PARAMS ((unsigned long, int *));
+
+/* The operands table.
+
+   The fields are bits, shift, signed, insert, extract, flags.  */
+
+const struct powerpc_operand powerpc_operands[] =
+{
+  /* The zero index is used to indicate the end of the list of
+     operands.  */
+#define UNUSED (0)
+  { 0, 0, 0, 0, 0 },
+
+  /* The BA field in an XL form instruction.  */
+#define BA (1)
+#define BA_MASK (0x1f << 16)
+  { 5, 16, 0, 0, PPC_OPERAND_CR },
+
+  /* The BA field in an XL form instruction when it must be the same
+     as the BT field in the same instruction.  */
+#define BAT (2)
+  { 5, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE },
+
+  /* The BB field in an XL form instruction.  */
+#define BB (3)
+#define BB_MASK (0x1f << 11)
+  { 5, 11, 0, 0, PPC_OPERAND_CR },
+
+  /* The BB field in an XL form instruction when it must be the same
+     as the BA field in the same instruction.  */
+#define BBA (4)
+  { 5, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE },
+
+  /* The BD field in a B form instruction.  The lower two bits are
+     forced to zero.  */
+#define BD (5)
+  { 16, 0, insert_bd, extract_bd, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when absolute addressing is
+     used.  */
+#define BDA (6)
+  { 16, 0, insert_bd, extract_bd, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when the - modifier is used.
+     This sets the y bit of the BO field appropriately.  */
+#define BDM (7)
+  { 16, 0, insert_bdm, extract_bdm,
+      PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when the - modifier is used
+     and absolute address is used.  */
+#define BDMA (8)
+  { 16, 0, insert_bdm, extract_bdm,
+      PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when the + modifier is used.
+     This sets the y bit of the BO field appropriately.  */
+#define BDP (9)
+  { 16, 0, insert_bdp, extract_bdp,
+      PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+  /* The BD field in a B form instruction when the + modifier is used
+     and absolute addressing is used.  */
+#define BDPA (10)
+  { 16, 0, insert_bdp, extract_bdp,
+      PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+  /* The BF field in an X or XL form instruction.  */
+#define BF (11)
+  { 3, 23, 0, 0, PPC_OPERAND_CR },
+
+  /* An optional BF field.  This is used for comparison instructions,
+     in which an omitted BF field is taken as zero.  */
+#define OBF (12)
+  { 3, 23, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+
+  /* The BFA field in an X or XL form instruction.  */
+#define BFA (13)
+  { 3, 18, 0, 0, PPC_OPERAND_CR },
+
+  /* The BI field in a B form or XL form instruction.  */
+#define BI (14)
+#define BI_MASK (0x1f << 16)
+  { 5, 16, 0, 0, PPC_OPERAND_CR },
+
+  /* The BO field in a B form instruction.  Certain values are
+     illegal.  */
+#define BO (15)
+#define BO_MASK (0x1f << 21)
+  { 5, 21, insert_bo, extract_bo, 0 },
+
+  /* The BO field in a B form instruction when the + or - modifier is
+     used.  This is like the BO field, but it must be even.  */
+#define BOE (16)
+  { 5, 21, insert_boe, extract_boe, 0 },
+
+  /* The BT field in an X or XL form instruction.  */
+#define BT (17)
+  { 5, 21, 0, 0, PPC_OPERAND_CR },
+
+  /* The condition register number portion of the BI field in a B form
+     or XL form instruction.  This is used for the extended
+     conditional branch mnemonics, which set the lower two bits of the
+     BI field.  This field is optional.  */
+#define CR (18)
+  { 3, 18, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+
+  /* The D field in a D form instruction.  This is a displacement off
+     a register, and implies that the next operand is a register in
+     parentheses.  */
+#define D (19)
+  { 16, 0, 0, 0, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+
+  /* The DS field in a DS form instruction.  This is like D, but the
+     lower two bits are forced to zero.  */
+#define DS (20)
+  { 16, 0, insert_ds, extract_ds, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+
+  /* The FL1 field in a POWER SC form instruction.  */
+#define FL1 (21)
+  { 4, 12, 0, 0, 0 },
+
+  /* The FL2 field in a POWER SC form instruction.  */
+#define FL2 (22)
+  { 3, 2, 0, 0, 0 },
+
+  /* The FLM field in an XFL form instruction.  */
+#define FLM (23)
+  { 8, 17, 0, 0, 0 },
+
+  /* The FRA field in an X or A form instruction.  */
+#define FRA (24)
+#define FRA_MASK (0x1f << 16)
+  { 5, 16, 0, 0, PPC_OPERAND_FPR },
+
+  /* The FRB field in an X or A form instruction.  */
+#define FRB (25)
+#define FRB_MASK (0x1f << 11)
+  { 5, 11, 0, 0, PPC_OPERAND_FPR },
+
+  /* The FRC field in an A form instruction.  */
+#define FRC (26)
+#define FRC_MASK (0x1f << 6)
+  { 5, 6, 0, 0, PPC_OPERAND_FPR },
+
+  /* The FRS field in an X form instruction or the FRT field in a D, X
+     or A form instruction.  */
+#define FRS (27)
+#define FRT (FRS)
+  { 5, 21, 0, 0, PPC_OPERAND_FPR },
+
+  /* The FXM field in an XFX instruction.  */
+#define FXM (28)
+#define FXM_MASK (0xff << 12)
+  { 8, 12, 0, 0, 0 },
+
+  /* The L field in a D or X form instruction.  */
+#define L (29)
+  { 1, 21, 0, 0, PPC_OPERAND_OPTIONAL },
+
+  /* The LEV field in a POWER SC form instruction.  */
+#define LEV (30)
+  { 7, 5, 0, 0, 0 },
+
+  /* The LI field in an I form instruction.  The lower two bits are
+     forced to zero.  */
+#define LI (31)
+  { 26, 0, insert_li, extract_li, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+  /* The LI field in an I form instruction when used as an absolute
+     address.  */
+#define LIA (32)
+  { 26, 0, insert_li, extract_li, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+  /* The MB field in an M form instruction.  */
+#define MB (33)
+#define MB_MASK (0x1f << 6)
+  { 5, 6, 0, 0, 0 },
+
+  /* The ME field in an M form instruction.  */
+#define ME (34)
+#define ME_MASK (0x1f << 1)
+  { 5, 1, 0, 0, 0 },
+
+  /* The MB and ME fields in an M form instruction expressed a single
+     operand which is a bitmask indicating which bits to select.  This
+     is a two operand form using PPC_OPERAND_NEXT.  See the
+     description in opcode/ppc.h for what this means.  */
+#define MBE (35)
+  { 5, 6, 0, 0, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
+  { 32, 0, insert_mbe, extract_mbe, 0 },
+
+  /* The MB or ME field in an MD or MDS form instruction.  The high
+     bit is wrapped to the low end.  */
+#define MB6 (37)
+#define ME6 (MB6)
+#define MB6_MASK (0x3f << 5)
+  { 6, 5, insert_mb6, extract_mb6, 0 },
+
+  /* The NB field in an X form instruction.  The value 32 is stored as
+     0.  */
+#define NB (38)
+  { 6, 11, insert_nb, extract_nb, 0 },
+
+  /* The NSI field in a D form instruction.  This is the same as the
+     SI field, only negated.  */
+#define NSI (39)
+  { 16, 0, insert_nsi, extract_nsi,
+      PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
+
+  /* The RA field in an D, DS, X, XO, M, or MDS form instruction.  */
+#define RA (40)
+#define RA_MASK (0x1f << 16)
+  { 5, 16, 0, 0, PPC_OPERAND_GPR },
+
+  /* The RA field in a D or X form instruction which is an updating
+     load, which means that the RA field may not be zero and may not
+     equal the RT field.  */
+#define RAL (41)
+  { 5, 16, insert_ral, 0, PPC_OPERAND_GPR },
+
+  /* The RA field in an lmw instruction, which has special value
+     restrictions.  */
+#define RAM (42)
+  { 5, 16, insert_ram, 0, PPC_OPERAND_GPR },
+
+  /* The RA field in a D or X form instruction which is an updating
+     store or an updating floating point load, which means that the RA
+     field may not be zero.  */
+#define RAS (43)
+  { 5, 16, insert_ras, 0, PPC_OPERAND_GPR },
+
+  /* The RB field in an X, XO, M, or MDS form instruction.  */
+#define RB (44)
+#define RB_MASK (0x1f << 11)
+  { 5, 11, 0, 0, PPC_OPERAND_GPR },
+
+  /* The RB field in an X form instruction when it must be the same as
+     the RS field in the instruction.  This is used for extended
+     mnemonics like mr.  */
+#define RBS (45)
+  { 5, 1, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
+
+  /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
+     instruction or the RT field in a D, DS, X, XFX or XO form
+     instruction.  */
+#define RS (46)
+#define RT (RS)
+#define RT_MASK (0x1f << 21)
+  { 5, 21, 0, 0, PPC_OPERAND_GPR },
+
+  /* The SH field in an X or M form instruction.  */
+#define SH (47)
+#define SH_MASK (0x1f << 11)
+  { 5, 11, 0, 0, 0 },
+
+  /* The SH field in an MD form instruction.  This is split.  */
+#define SH6 (48)
+#define SH6_MASK ((0x1f << 11) | (1 << 1))
+  { 6, 1, insert_sh6, extract_sh6, 0 },
+
+  /* The SI field in a D form instruction.  */
+#define SI (49)
+  { 16, 0, 0, 0, PPC_OPERAND_SIGNED },
+
+  /* The SI field in a D form instruction when we accept a wide range
+     of positive values.  */
+#define SISIGNOPT (50)
+  { 16, 0, 0, 0, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT },
+
+  /* The SPR field in an XFX form instruction.  This is flipped--the
+     lower 5 bits are stored in the upper 5 and vice- versa.  */
+#define SPR (51)
+#define SPR_MASK (0x3ff << 11)
+  { 10, 11, insert_spr, extract_spr, 0 },
+
+  /* The BAT index number in an XFX form m[ft]ibat[lu] instruction.  */
+#define SPRBAT (52)
+#define SPRBAT_MASK (0x3 << 17)
+  { 2, 17, 0, 0, 0 },
+
+  /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
+#define SPRG (53)
+#define SPRG_MASK (0x3 << 16)
+  { 2, 16, 0, 0, 0 },
+
+  /* The SR field in an X form instruction.  */
+#define SR (54)
+  { 4, 16, 0, 0, 0 },
+
+  /* The SV field in a POWER SC form instruction.  */
+#define SV (55)
+  { 14, 2, 0, 0, 0 },
+
+  /* The TBR field in an XFX form instruction.  This is like the SPR
+     field, but it is optional.  */
+#define TBR (56)
+  { 10, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
+
+  /* The TO field in a D or X form instruction.  */
+#define TO (57)
+#define TO_MASK (0x1f << 21)
+  { 5, 21, 0, 0, 0 },
+
+  /* The U field in an X form instruction.  */
+#define U (58)
+  { 4, 12, 0, 0, 0 },
+
+  /* The UI field in a D form instruction.  */
+#define UI (59)
+  { 16, 0, 0, 0, 0 },
+};
+
+/* The functions used to insert and extract complicated operands.  */
+
+/* The BA field in an XL form instruction when it must be the same as
+   the BT field in the same instruction.  This operand is marked FAKE.
+   The insertion function just copies the BT field into the BA field,
+   and the extraction function just checks that the fields are the
+   same.  */
+
+/*ARGSUSED*/
+static unsigned long 
+insert_bat (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | (((insn >> 21) & 0x1f) << 16);
+}
+
+static long
+extract_bat (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if (invalid != (int *) NULL
+      && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
+    *invalid = 1;
+  return 0;
+}
+
+/* The BB field in an XL form instruction when it must be the same as
+   the BA field in the same instruction.  This operand is marked FAKE.
+   The insertion function just copies the BA field into the BB field,
+   and the extraction function just checks that the fields are the
+   same.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bba (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | (((insn >> 16) & 0x1f) << 11);
+}
+
+static long
+extract_bba (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if (invalid != (int *) NULL
+      && ((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f))
+    *invalid = 1;
+  return 0;
+}
+
+/* The BD field in a B form instruction.  The lower two bits are
+   forced to zero.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bd (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | (value & 0xfffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_bd (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if ((insn & 0x8000) != 0)
+    return (insn & 0xfffc) - 0x10000;
+  else
+    return insn & 0xfffc;
+}
+
+/* The BD field in a B form instruction when the - modifier is used.
+   This modifier means that the branch is not expected to be taken.
+   We must set the y bit of the BO field to 1 if the offset is
+   negative.  When extracting, we require that the y bit be 1 and that
+   the offset be positive, since if the y bit is 0 we just want to
+   print the normal form of the instruction.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bdm (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if ((value & 0x8000) != 0)
+    insn |= 1 << 21;
+  return insn | (value & 0xfffc);
+}
+
+static long
+extract_bdm (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if (invalid != (int *) NULL
+      && ((insn & (1 << 21)) == 0
+	  || (insn & (1 << 15)) == 0))
+    *invalid = 1;
+  if ((insn & 0x8000) != 0)
+    return (insn & 0xfffc) - 0x10000;
+  else
+    return insn & 0xfffc;
+}
+
+/* The BD field in a B form instruction when the + modifier is used.
+   This is like BDM, above, except that the branch is expected to be
+   taken.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bdp (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if ((value & 0x8000) == 0)
+    insn |= 1 << 21;
+  return insn | (value & 0xfffc);
+}
+
+static long
+extract_bdp (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if (invalid != (int *) NULL
+      && ((insn & (1 << 21)) == 0
+	  || (insn & (1 << 15)) != 0))
+    *invalid = 1;
+  if ((insn & 0x8000) != 0)
+    return (insn & 0xfffc) - 0x10000;
+  else
+    return insn & 0xfffc;
+}
+
+/* Check for legal values of a BO field.  */
+
+static int
+valid_bo (long value)
+{
+  /* Certain encodings have bits that are required to be zero.  These
+     are (z must be zero, y may be anything):
+         001zy
+	 011zy
+	 1z00y
+	 1z01y
+	 1z1zz
+     */
+  switch (value & 0x14)
+    {
+    default:
+    case 0:
+      return 1;
+    case 0x4:
+      return (value & 0x2) == 0;
+    case 0x10:
+      return (value & 0x8) == 0;
+    case 0x14:
+      return value == 0x14;
+    }
+}
+
+/* The BO field in a B form instruction.  Warn about attempts to set
+   the field to an illegal value.  */
+
+static unsigned long
+insert_bo (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if (errmsg != (const char **) NULL
+      && ! valid_bo (value))
+    *errmsg = "invalid conditional option";
+  return insn | ((value & 0x1f) << 21);
+}
+
+static long
+extract_bo (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  long value;
+
+  value = (insn >> 21) & 0x1f;
+  if (invalid != (int *) NULL
+      && ! valid_bo (value))
+    *invalid = 1;
+  return value;
+}
+
+/* The BO field in a B form instruction when the + or - modifier is
+   used.  This is like the BO field, but it must be even.  When
+   extracting it, we force it to be even.  */
+
+static unsigned long
+insert_boe (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if (errmsg != (const char **) NULL)
+    {
+      if (! valid_bo (value))
+	*errmsg = "invalid conditional option";
+      else if ((value & 1) != 0)
+	*errmsg = "attempt to set y bit when using + or - modifier";
+    }
+  return insn | ((value & 0x1f) << 21);
+}
+
+static long
+extract_boe (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  long value;
+
+  value = (insn >> 21) & 0x1f;
+  if (invalid != (int *) NULL
+      && ! valid_bo (value))
+    *invalid = 1;
+  return value & 0x1e;
+}
+
+/* The DS field in a DS form instruction.  This is like D, but the
+   lower two bits are forced to zero.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_ds (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | (value & 0xfffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_ds (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if ((insn & 0x8000) != 0)
+    return (insn & 0xfffc) - 0x10000;
+  else
+    return insn & 0xfffc;
+}
+
+/* The LI field in an I form instruction.  The lower two bits are
+   forced to zero.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_li (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | (value & 0x3fffffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_li (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if ((insn & 0x2000000) != 0)
+    return (insn & 0x3fffffc) - 0x4000000;
+  else
+    return insn & 0x3fffffc;
+}
+
+/* The MB and ME fields in an M form instruction expressed as a single
+   operand which is itself a bitmask.  The extraction function always
+   marks it as invalid, since we never want to recognize an
+   instruction which uses a field of this type.  */
+
+static unsigned long
+insert_mbe (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  unsigned long uval;
+  int mb, me;
+
+  uval = value;
+
+  if (uval == 0)
+    {
+      if (errmsg != (const char **) NULL)
+	*errmsg = "illegal bitmask";
+      return insn;
+    }
+
+  me = 31;
+  while ((uval & 1) == 0)
+    {
+      uval >>= 1;
+      --me;
+    }
+
+  mb = me;
+  uval >>= 1;
+  while ((uval & 1) != 0)
+    {
+      uval >>= 1;
+      --mb;
+    }
+
+  if (uval != 0)
+    {
+      if (errmsg != (const char **) NULL)
+	*errmsg = "illegal bitmask";
+    }
+
+  return insn | (mb << 6) | (me << 1);
+}
+
+static long
+extract_mbe (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  long ret;
+  int mb, me;
+  int i;
+
+  if (invalid != (int *) NULL)
+    *invalid = 1;
+
+  ret = 0;
+  mb = (insn >> 6) & 0x1f;
+  me = (insn >> 1) & 0x1f;
+  for (i = mb; i < me; i++)
+    ret |= 1 << (31 - i);
+  return ret;
+}
+
+/* The MB or ME field in an MD or MDS form instruction.  The high bit
+   is wrapped to the low end.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_mb6 (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | ((value & 0x1f) << 6) | (value & 0x20);
+}
+
+/*ARGSUSED*/
+static long
+extract_mb6 (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  return ((insn >> 6) & 0x1f) | (insn & 0x20);
+}
+
+/* The NB field in an X form instruction.  The value 32 is stored as
+   0.  */
+
+static unsigned long
+insert_nb (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if (value < 0 || value > 32)
+    *errmsg = "value out of range";
+  if (value == 32)
+    value = 0;
+  return insn | ((value & 0x1f) << 11);
+}
+
+/*ARGSUSED*/
+static long
+extract_nb (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  long ret;
+
+  ret = (insn >> 11) & 0x1f;
+  if (ret == 0)
+    ret = 32;
+  return ret;
+}
+
+/* The NSI field in a D form instruction.  This is the same as the SI
+   field, only negated.  The extraction function always marks it as
+   invalid, since we never want to recognize an instruction which uses
+   a field of this type.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_nsi (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | ((- value) & 0xffff);
+}
+
+static long
+extract_nsi (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if (invalid != (int *) NULL)
+    *invalid = 1;
+  if ((insn & 0x8000) != 0)
+    return - ((insn & 0xffff) - 0x10000);
+  else
+    return - (insn & 0xffff);
+}
+
+/* The RA field in a D or X form instruction which is an updating
+   load, which means that the RA field may not be zero and may not
+   equal the RT field.  */
+
+static unsigned long
+insert_ral (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if (value == 0
+      || value == ((insn >> 21) & 0x1f))
+    *errmsg = "invalid register operand when updating";
+  return insn | ((value & 0x1f) << 16);
+}
+
+/* The RA field in an lmw instruction, which has special value
+   restrictions.  */
+
+static unsigned long
+insert_ram (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if (value >= ((insn >> 21) & 0x1f))
+    *errmsg = "index register in load range";
+  return insn | ((value & 0x1f) << 16);
+}
+
+/* The RA field in a D or X form instruction which is an updating
+   store or an updating floating point load, which means that the RA
+   field may not be zero.  */
+
+static unsigned long
+insert_ras (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if (value == 0)
+    *errmsg = "invalid register operand when updating";
+  return insn | ((value & 0x1f) << 16);
+}
+
+/* The RB field in an X form instruction when it must be the same as
+   the RS field in the instruction.  This is used for extended
+   mnemonics like mr.  This operand is marked FAKE.  The insertion
+   function just copies the BT field into the BA field, and the
+   extraction function just checks that the fields are the same.  */
+
+/*ARGSUSED*/
+static unsigned long 
+insert_rbs (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | (((insn >> 21) & 0x1f) << 11);
+}
+
+static long
+extract_rbs (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  if (invalid != (int *) NULL
+      && ((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f))
+    *invalid = 1;
+  return 0;
+}
+
+/* The SH field in an MD form instruction.  This is split.  */
+
+/*ARGSUSED*/
+static unsigned long
+insert_sh6 (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
+}
+
+/*ARGSUSED*/
+static long
+extract_sh6 (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
+}
+
+/* The SPR field in an XFX form instruction.  This is flipped--the
+   lower 5 bits are stored in the upper 5 and vice- versa.  */
+
+static unsigned long
+insert_spr (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+}
+
+static long
+extract_spr (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+}
+
+/* The TBR field in an XFX instruction.  This is just like SPR, but it
+   is optional.  When TBR is omitted, it must be inserted as 268 (the
+   magic number of the TB register).  These functions treat 0
+   (indicating an omitted optional operand) as 268.  This means that
+   ``mftb 4,0'' is not handled correctly.  This does not matter very
+   much, since the architecture manual does not define mftb as
+   accepting any values other than 268 or 269.  */
+
+#define TB (268)
+
+static unsigned long
+insert_tbr (insn, value, errmsg)
+     unsigned long insn;
+     long value;
+     const char **errmsg;
+{
+  if (value == 0)
+    value = TB;
+  return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+}
+
+static long
+extract_tbr (insn, invalid)
+     unsigned long insn;
+     int *invalid;
+{
+  long ret;
+
+  ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+  if (ret == TB)
+    ret = 0;
+  return ret;
+}
+
+/* Macros used to form opcodes.  */
+
+/* The main opcode.  */
+#define OP(x) (((x) & 0x3f) << 26)
+#define OP_MASK OP (0x3f)
+
+/* The main opcode combined with a trap code in the TO field of a D
+   form instruction.  Used for extended mnemonics for the trap
+   instructions.  */
+#define OPTO(x,to) (OP (x) | (((to) & 0x1f) << 21))
+#define OPTO_MASK (OP_MASK | TO_MASK)
+
+/* The main opcode combined with a comparison size bit in the L field
+   of a D form or X form instruction.  Used for extended mnemonics for
+   the comparison instructions.  */
+#define OPL(x,l) (OP (x) | (((l) & 1) << 21))
+#define OPL_MASK OPL (0x3f,1)
+
+/* An A form instruction.  */
+#define A(op, xop, rc) (OP (op) | (((xop) & 0x1f) << 1) | ((rc) & 1))
+#define A_MASK A (0x3f, 0x1f, 1)
+
+/* An A_MASK with the FRB field fixed.  */
+#define AFRB_MASK (A_MASK | FRB_MASK)
+
+/* An A_MASK with the FRC field fixed.  */
+#define AFRC_MASK (A_MASK | FRC_MASK)
+
+/* An A_MASK with the FRA and FRC fields fixed.  */
+#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
+
+/* A B form instruction.  */
+#define B(op, aa, lk) (OP (op) | (((aa) & 1) << 1) | ((lk) & 1))
+#define B_MASK B (0x3f, 1, 1)
+
+/* A B form instruction setting the BO field.  */
+#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | (((bo) & 0x1f) << 21))
+#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)
+
+/* A BBO_MASK with the y bit of the BO field removed.  This permits
+   matching a conditional branch regardless of the setting of the y
+   bit.  */
+#define Y_MASK (1 << 21)
+#define BBOY_MASK (BBO_MASK &~ Y_MASK)
+
+/* A B form instruction setting the BO field and the condition bits of
+   the BI field.  */
+#define BBOCB(op, bo, cb, aa, lk) \
+  (BBO ((op), (bo), (aa), (lk)) | (((cb) & 0x3) << 16))
+#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)
+
+/* A BBOCB_MASK with the y bit of the BO field removed.  */
+#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)
+
+/* A BBOYCB_MASK in which the BI field is fixed.  */
+#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)
+
+/* The main opcode mask with the RA field clear.  */
+#define DRA_MASK (OP_MASK | RA_MASK)
+
+/* A DS form instruction.  */
+#define DSO(op, xop) (OP (op) | ((xop) & 0x3))
+#define DS_MASK DSO (0x3f, 3)
+
+/* An M form instruction.  */
+#define M(op, rc) (OP (op) | ((rc) & 1))
+#define M_MASK M (0x3f, 1)
+
+/* An M form instruction with the ME field specified.  */
+#define MME(op, me, rc) (M ((op), (rc)) | (((me) & 0x1f) << 1))
+
+/* An M_MASK with the MB and ME fields fixed.  */
+#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK)
+
+/* An M_MASK with the SH and ME fields fixed.  */
+#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK)
+
+/* An MD form instruction.  */
+#define MD(op, xop, rc) (OP (op) | (((xop) & 0x7) << 2) | ((rc) & 1))
+#define MD_MASK MD (0x3f, 0x7, 1)
+
+/* An MD_MASK with the MB field fixed.  */
+#define MDMB_MASK (MD_MASK | MB6_MASK)
+
+/* An MD_MASK with the SH field fixed.  */
+#define MDSH_MASK (MD_MASK | SH6_MASK)
+
+/* An MDS form instruction.  */
+#define MDS(op, xop, rc) (OP (op) | (((xop) & 0xf) << 1) | ((rc) & 1))
+#define MDS_MASK MDS (0x3f, 0xf, 1)
+
+/* An MDS_MASK with the MB field fixed.  */
+#define MDSMB_MASK (MDS_MASK | MB6_MASK)
+
+/* An SC form instruction.  */
+#define SC(op, sa, lk) (OP (op) | (((sa) & 1) << 1) | ((lk) & 1))
+#define SC_MASK (OP_MASK | (0x3ff << 16) | (1 << 1) | 1)
+
+/* An X form instruction.  */
+#define X(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
+
+/* An X form instruction with the RC bit specified.  */
+#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
+
+/* The mask for an X form instruction.  */
+#define X_MASK XRC (0x3f, 0x3ff, 1)
+
+/* An X_MASK with the RA field fixed.  */
+#define XRA_MASK (X_MASK | RA_MASK)
+
+/* An X_MASK with the RB field fixed.  */
+#define XRB_MASK (X_MASK | RB_MASK)
+
+/* An X_MASK with the RT field fixed.  */
+#define XRT_MASK (X_MASK | RT_MASK)
+
+/* An X_MASK with the RA and RB fields fixed.  */
+#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
+
+/* An X_MASK with the RT and RA fields fixed.  */
+#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK)
+
+/* An X form comparison instruction.  */
+#define XCMPL(op, xop, l) (X ((op), (xop)) | (((l) & 1) << 21))
+
+/* The mask for an X form comparison instruction.  */
+#define XCMP_MASK (X_MASK | (1 << 22))
+
+/* The mask for an X form comparison instruction with the L field
+   fixed.  */
+#define XCMPL_MASK (XCMP_MASK | (1 << 21))
+
+/* An X form trap instruction with the TO field specified.  */
+#define XTO(op, xop, to) (X ((op), (xop)) | (((to) & 0x1f) << 21))
+#define XTO_MASK (X_MASK | TO_MASK)
+
+/* An XFL form instruction.  */
+#define XFL(op, xop, rc) (OP (op) | (((xop) & 0x3ff) << 1) | ((rc) & 1))
+#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (1 << 25) | (1 << 16))
+
+/* An XL form instruction with the LK field set to 0.  */
+#define XL(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
+
+/* An XL form instruction which uses the LK field.  */
+#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1))
+
+/* The mask for an XL form instruction.  */
+#define XL_MASK XLLK (0x3f, 0x3ff, 1)
+
+/* An XL form instruction which explicitly sets the BO field.  */
+#define XLO(op, bo, xop, lk) \
+  (XLLK ((op), (xop), (lk)) | (((bo) & 0x1f) << 21))
+#define XLO_MASK (XL_MASK | BO_MASK)
+
+/* An XL form instruction which explicitly sets the y bit of the BO
+   field.  */
+#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | (((y) & 1) << 21))
+#define XLYLK_MASK (XL_MASK | Y_MASK)
+
+/* An XL form instruction which sets the BO field and the condition
+   bits of the BI field.  */
+#define XLOCB(op, bo, cb, xop, lk) \
+  (XLO ((op), (bo), (xop), (lk)) | (((cb) & 3) << 16))
+#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1)
+
+/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed.  */
+#define XLBB_MASK (XL_MASK | BB_MASK)
+#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
+#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
+
+/* An XL_MASK with the BO and BB fields fixed.  */
+#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
+
+/* An XL_MASK with the BO, BI and BB fields fixed.  */
+#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK)
+
+/* An XO form instruction.  */
+#define XO(op, xop, oe, rc) \
+  (OP (op) | (((xop) & 0x1ff) << 1) | (((oe) & 1) << 10) | ((rc) & 1))
+#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
+
+/* An XO_MASK with the RB field fixed.  */
+#define XORB_MASK (XO_MASK | RB_MASK)
+
+/* An XS form instruction.  */
+#define XS(op, xop, rc) (OP (op) | (((xop) & 0x1ff) << 2) | ((rc) & 1))
+#define XS_MASK XS (0x3f, 0x1ff, 1)
+
+/* A mask for the FXM version of an XFX form instruction.  */
+#define XFXFXM_MASK (X_MASK | (1 << 20) | (1 << 11))
+
+/* An XFX form instruction with the FXM field filled in.  */
+#define XFXM(op, xop, fxm) \
+  (X ((op), (xop)) | (((fxm) & 0xff) << 12))
+
+/* An XFX form instruction with the SPR field filled in.  */
+#define XSPR(op, xop, spr) \
+  (X ((op), (xop)) | (((spr) & 0x1f) << 16) | (((spr) & 0x3e0) << 6))
+#define XSPR_MASK (X_MASK | SPR_MASK)
+
+/* An XFX form instruction with the SPR field filled in except for the
+   SPRBAT field.  */
+#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK)
+
+/* An XFX form instruction with the SPR field filled in except for the
+   SPRG field.  */
+#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
+
+/* The BO encodings used in extended conditional branch mnemonics.  */
+#define BODNZF	(0x0)
+#define BODNZFP	(0x1)
+#define BODZF	(0x2)
+#define BODZFP	(0x3)
+#define BOF	(0x4)
+#define BOFP	(0x5)
+#define BODNZT	(0x8)
+#define BODNZTP	(0x9)
+#define BODZT	(0xa)
+#define BODZTP	(0xb)
+#define BOT	(0xc)
+#define BOTP	(0xd)
+#define BODNZ	(0x10)
+#define BODNZP	(0x11)
+#define BODZ	(0x12)
+#define BODZP	(0x13)
+#define BOU	(0x14)
+
+/* The BI condition bit encodings used in extended conditional branch
+   mnemonics.  */
+#define CBLT	(0)
+#define CBGT	(1)
+#define CBEQ	(2)
+#define CBSO	(3)
+
+/* The TO encodings used in extended trap mnemonics.  */
+#define TOLGT	(0x1)
+#define TOLLT	(0x2)
+#define TOEQ	(0x4)
+#define TOLGE	(0x5)
+#define TOLNL	(0x5)
+#define TOLLE	(0x6)
+#define TOLNG	(0x6)
+#define TOGT	(0x8)
+#define TOGE	(0xc)
+#define TONL	(0xc)
+#define TOLT	(0x10)
+#define TOLE	(0x14)
+#define TONG	(0x14)
+#define TONE	(0x18)
+#define TOU	(0x1f)
+
+/* Smaller names for the flags so each entry in the opcodes table will
+   fit on a single line.  */
+#undef PPC
+#define PPC PPC_OPCODE_PPC
+#define POWER PPC_OPCODE_POWER
+#define POWER2 PPC_OPCODE_POWER2
+#define B32 PPC_OPCODE_32
+#define B64 PPC_OPCODE_64
+#define M601 PPC_OPCODE_601
+
+/* The opcode table.
+
+   The format of the opcode table is:
+
+   NAME	     OPCODE	MASK		FLAGS		{ OPERANDS }
+
+   NAME is the name of the instruction.
+   OPCODE is the instruction opcode.
+   MASK is the opcode mask; this is used to tell the disassembler
+     which bits in the actual opcode must match OPCODE.
+   FLAGS are flags indicated what processors support the instruction.
+   OPERANDS is the list of operands.
+
+   The disassembler reads the table in order and prints the first
+   instruction which matches, so this table is sorted to put more
+   specific instructions before more general instructions.  It is also
+   sorted by major opcode.  */
+
+const struct powerpc_opcode powerpc_opcodes[] = {
+{ "tdlgti",  OPTO(2,TOLGT), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdllti",  OPTO(2,TOLLT), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdeqi",   OPTO(2,TOEQ), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlgei",  OPTO(2,TOLGE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlnli",  OPTO(2,TOLNL), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdllei",  OPTO(2,TOLLE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlngi",  OPTO(2,TOLNG), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdgti",   OPTO(2,TOGT), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdgei",   OPTO(2,TOGE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdnli",   OPTO(2,TONL), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlti",   OPTO(2,TOLT), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdlei",   OPTO(2,TOLE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdngi",   OPTO(2,TONG), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdnei",   OPTO(2,TONE), OPTO_MASK,	PPC|B64,	{ RA, SI } },
+{ "tdi",     OP(2),	OP_MASK,	PPC|B64,	{ TO, RA, SI } },
+
+{ "twlgti",  OPTO(3,TOLGT), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlgti",   OPTO(3,TOLGT), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twllti",  OPTO(3,TOLLT), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tllti",   OPTO(3,TOLLT), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "tweqi",   OPTO(3,TOEQ), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "teqi",    OPTO(3,TOEQ), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlgei",  OPTO(3,TOLGE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlgei",   OPTO(3,TOLGE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlnli",  OPTO(3,TOLNL), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlnli",   OPTO(3,TOLNL), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twllei",  OPTO(3,TOLLE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tllei",   OPTO(3,TOLLE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlngi",  OPTO(3,TOLNG), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlngi",   OPTO(3,TOLNG), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twgti",   OPTO(3,TOGT), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tgti",    OPTO(3,TOGT), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twgei",   OPTO(3,TOGE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tgei",    OPTO(3,TOGE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twnli",   OPTO(3,TONL), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tnli",    OPTO(3,TONL), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlti",   OPTO(3,TOLT), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlti",    OPTO(3,TOLT), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twlei",   OPTO(3,TOLE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tlei",    OPTO(3,TOLE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twngi",   OPTO(3,TONG), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tngi",    OPTO(3,TONG), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twnei",   OPTO(3,TONE), OPTO_MASK,	PPC,		{ RA, SI } },
+{ "tnei",    OPTO(3,TONE), OPTO_MASK,	POWER,		{ RA, SI } },
+{ "twi",     OP(3),	OP_MASK,	PPC,		{ TO, RA, SI } },
+{ "ti",      OP(3),	OP_MASK,	POWER,		{ TO, RA, SI } },
+
+{ "mulli",   OP(7),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "muli",    OP(7),	OP_MASK,	POWER,		{ RT, RA, SI } },
+
+{ "subfic",  OP(8),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "sfi",     OP(8),	OP_MASK,	POWER,		{ RT, RA, SI } },
+
+{ "dozi",    OP(9),	OP_MASK,	POWER|M601,	{ RT, RA, SI } },
+
+{ "cmplwi",  OPL(10,0),	OPL_MASK,	PPC,		{ OBF, RA, UI } },
+{ "cmpldi",  OPL(10,1), OPL_MASK,	PPC|B64,	{ OBF, RA, UI } },
+{ "cmpli",   OP(10),	OP_MASK,	PPC,		{ BF, L, RA, UI } },
+{ "cmpli",   OP(10),	OP_MASK,	POWER,		{ BF, RA, UI } },
+
+{ "cmpwi",   OPL(11,0),	OPL_MASK,	PPC,		{ OBF, RA, SI } },
+{ "cmpdi",   OPL(11,1),	OPL_MASK,	PPC|B64,	{ OBF, RA, SI } },
+{ "cmpi",    OP(11),	OP_MASK,	PPC,		{ BF, L, RA, SI } },
+{ "cmpi",    OP(11),	OP_MASK,	POWER,		{ BF, RA, SI } },
+
+{ "addic",   OP(12),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "ai",	     OP(12),	OP_MASK,	POWER,		{ RT, RA, SI } },
+{ "subic",   OP(12),	OP_MASK,	PPC,		{ RT, RA, NSI } },
+
+{ "addic.",  OP(13),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "ai.",     OP(13),	OP_MASK,	POWER,		{ RT, RA, SI } },
+{ "subic.",  OP(13),	OP_MASK,	PPC,		{ RT, RA, NSI } },
+
+{ "li",	     OP(14),	DRA_MASK,	PPC,		{ RT, SI } },
+{ "lil",     OP(14),	DRA_MASK,	POWER,		{ RT, SI } },
+{ "addi",    OP(14),	OP_MASK,	PPC,		{ RT, RA, SI } },
+{ "cal",     OP(14),	OP_MASK,	POWER,		{ RT, D, RA } },
+{ "subi",    OP(14),	OP_MASK,	PPC,		{ RT, RA, NSI } },
+{ "la",	     OP(14),	OP_MASK,	PPC,		{ RT, D, RA } },
+
+{ "lis",     OP(15),	DRA_MASK,	PPC,		{ RT, SISIGNOPT } },
+{ "liu",     OP(15),	DRA_MASK,	POWER,		{ RT, SISIGNOPT } },
+{ "addis",   OP(15),	OP_MASK,	PPC,		{ RT,RA,SISIGNOPT } },
+{ "cau",     OP(15),	OP_MASK,	POWER,		{ RT,RA,SISIGNOPT } },
+{ "subis",   OP(15),	OP_MASK,	PPC,		{ RT, RA, NSI } },
+
+{ "bdnz-",   BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC,	{ BDM } },
+{ "bdnz+",   BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC,	{ BDP } },
+{ "bdnz",    BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC,	{ BD } },
+{ "bdn",     BBO(16,BODNZ,0,0), BBOYBI_MASK, POWER,	{ BD } },
+{ "bdnzl-",  BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC,	{ BDM } },
+{ "bdnzl+",  BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC,	{ BDP } },
+{ "bdnzl",   BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC,	{ BD } },
+{ "bdnl",    BBO(16,BODNZ,0,1), BBOYBI_MASK, POWER,	{ BD } },
+{ "bdnza-",  BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC,	{ BDMA } },
+{ "bdnza+",  BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC,	{ BDPA } },
+{ "bdnza",   BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC,	{ BDA } },
+{ "bdna",    BBO(16,BODNZ,1,0), BBOYBI_MASK, POWER,	{ BDA } },
+{ "bdnzla-", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC,	{ BDMA } },
+{ "bdnzla+", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC,	{ BDPA } },
+{ "bdnzla",  BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC,	{ BDA } },
+{ "bdnla",   BBO(16,BODNZ,1,1), BBOYBI_MASK, POWER,	{ BDA } },
+{ "bdz-",    BBO(16,BODZ,0,0), BBOYBI_MASK, PPC,	{ BDM } },
+{ "bdz+",    BBO(16,BODZ,0,0), BBOYBI_MASK, PPC,	{ BDP } },
+{ "bdz",     BBO(16,BODZ,0,0), BBOYBI_MASK, PPC|POWER,	{ BD } },
+{ "bdzl-",   BBO(16,BODZ,0,1), BBOYBI_MASK, PPC,	{ BDM } },
+{ "bdzl+",   BBO(16,BODZ,0,1), BBOYBI_MASK, PPC,	{ BDP } },
+{ "bdzl",    BBO(16,BODZ,0,1), BBOYBI_MASK, PPC|POWER,	{ BD } },
+{ "bdza-",   BBO(16,BODZ,1,0), BBOYBI_MASK, PPC,	{ BDMA } },
+{ "bdza+",   BBO(16,BODZ,1,0), BBOYBI_MASK, PPC,	{ BDPA } },
+{ "bdza",    BBO(16,BODZ,1,0), BBOYBI_MASK, PPC|POWER,	{ BDA } },
+{ "bdzla-",  BBO(16,BODZ,1,1), BBOYBI_MASK, PPC,	{ BDMA } },
+{ "bdzla+",  BBO(16,BODZ,1,1), BBOYBI_MASK, PPC,	{ BDPA } },
+{ "bdzla",   BBO(16,BODZ,1,1), BBOYBI_MASK, PPC|POWER,	{ BDA } },
+{ "blt-",    BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "blt+",    BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "blt",     BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bltl-",   BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bltl+",   BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bltl",    BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "blta-",   BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "blta+",   BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "blta",    BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bltla-",  BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bltla+",  BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bltla",   BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bgt-",    BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bgt+",    BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bgt",     BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bgtl-",   BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bgtl+",   BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bgtl",    BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bgta-",   BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bgta+",   BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bgta",    BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bgtla-",  BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bgtla+",  BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bgtla",   BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "beq-",    BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "beq+",    BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "beq",     BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "beql-",   BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "beql+",   BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "beql",    BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "beqa-",   BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "beqa+",   BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "beqa",    BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "beqla-",  BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "beqla+",  BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "beqla",   BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bso-",    BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bso+",    BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bso",     BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bsol-",   BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bsol+",   BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bsol",    BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bsoa-",   BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bsoa+",   BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bsoa",    BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bsola-",  BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bsola+",  BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bsola",   BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bun-",    BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bun+",    BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bun",     BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BD } },
+{ "bunl-",   BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bunl+",   BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bunl",    BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BD } },
+{ "buna-",   BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "buna+",   BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "buna",    BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDA } },
+{ "bunla-",  BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bunla+",  BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bunla",   BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDA } },
+{ "bge-",    BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bge+",    BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bge",     BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bgel-",   BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bgel+",   BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bgel",    BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bgea-",   BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bgea+",   BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bgea",    BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bgela-",  BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bgela+",  BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bgela",   BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnl-",    BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnl+",    BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnl",     BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnll-",   BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnll+",   BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnll",    BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnla-",   BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnla+",   BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnla",    BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnlla-",  BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnlla+",  BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnlla",   BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "ble-",    BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "ble+",    BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "ble",     BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "blel-",   BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "blel+",   BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "blel",    BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "blea-",   BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "blea+",   BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "blea",    BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "blela-",  BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "blela+",  BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "blela",   BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bng-",    BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bng+",    BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bng",     BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bngl-",   BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bngl+",   BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bngl",    BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnga-",   BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnga+",   BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnga",    BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bngla-",  BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bngla+",  BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bngla",   BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bne-",    BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bne+",    BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bne",     BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnel-",   BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnel+",   BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnel",    BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnea-",   BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnea+",   BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnea",    BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnela-",  BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnela+",  BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnela",   BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bns-",    BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bns+",    BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bns",     BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnsl-",   BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnsl+",   BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnsl",    BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
+{ "bnsa-",   BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnsa+",   BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnsa",    BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnsla-",  BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnsla+",  BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnsla",   BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
+{ "bnu-",    BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnu+",    BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnu",     BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC,	{ CR, BD } },
+{ "bnul-",   BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDM } },
+{ "bnul+",   BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BDP } },
+{ "bnul",    BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC,	{ CR, BD } },
+{ "bnua-",   BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnua+",   BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnua",    BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC,	{ CR, BDA } },
+{ "bnula-",  BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDMA } },
+{ "bnula+",  BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDPA } },
+{ "bnula",   BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC,	{ CR, BDA } },
+{ "bdnzt-",  BBO(16,BODNZT,0,0), BBOY_MASK, PPC,	{ BI, BDM } },
+{ "bdnzt+",  BBO(16,BODNZT,0,0), BBOY_MASK, PPC,	{ BI, BDP } },
+{ "bdnzt",   BBO(16,BODNZT,0,0), BBOY_MASK, PPC,	{ BI, BD } },
+{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, PPC,	{ BI, BDM } },
+{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, PPC,	{ BI, BDP } },
+{ "bdnztl",  BBO(16,BODNZT,0,1), BBOY_MASK, PPC,	{ BI, BD } },
+{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, PPC,	{ BI, BDMA } },
+{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, PPC,	{ BI, BDPA } },
+{ "bdnzta",  BBO(16,BODNZT,1,0), BBOY_MASK, PPC,	{ BI, BDA } },
+{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, PPC,	{ BI, BDMA } },
+{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, PPC,	{ BI, BDPA } },
+{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPC,	{ BI, BDA } },
+{ "bdnzf-",  BBO(16,BODNZF,0,0), BBOY_MASK, PPC,	{ BI, BDM } },
+{ "bdnzf+",  BBO(16,BODNZF,0,0), BBOY_MASK, PPC,	{ BI, BDP } },
+{ "bdnzf",   BBO(16,BODNZF,0,0), BBOY_MASK, PPC,	{ BI, BD } },
+{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, PPC,	{ BI, BDM } },
+{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, PPC,	{ BI, BDP } },
+{ "bdnzfl",  BBO(16,BODNZF,0,1), BBOY_MASK, PPC,	{ BI, BD } },
+{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, PPC,	{ BI, BDMA } },
+{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, PPC,	{ BI, BDPA } },
+{ "bdnzfa",  BBO(16,BODNZF,1,0), BBOY_MASK, PPC,	{ BI, BDA } },
+{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, PPC,	{ BI, BDMA } },
+{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, PPC,	{ BI, BDPA } },
+{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPC,	{ BI, BDA } },
+{ "bt-",     BBO(16,BOT,0,0), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bt+",     BBO(16,BOT,0,0), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bt",	     BBO(16,BOT,0,0), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bbt",     BBO(16,BOT,0,0), BBOY_MASK, POWER,		{ BI, BD } },
+{ "btl-",    BBO(16,BOT,0,1), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "btl+",    BBO(16,BOT,0,1), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "btl",     BBO(16,BOT,0,1), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bbtl",    BBO(16,BOT,0,1), BBOY_MASK, POWER,		{ BI, BD } },
+{ "bta-",    BBO(16,BOT,1,0), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bta+",    BBO(16,BOT,1,0), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bta",     BBO(16,BOT,1,0), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bbta",    BBO(16,BOT,1,0), BBOY_MASK, POWER,		{ BI, BDA } },
+{ "btla-",   BBO(16,BOT,1,1), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "btla+",   BBO(16,BOT,1,1), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "btla",    BBO(16,BOT,1,1), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bbtla",   BBO(16,BOT,1,1), BBOY_MASK, POWER,		{ BI, BDA } },
+{ "bf-",     BBO(16,BOF,0,0), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bf+",     BBO(16,BOF,0,0), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bf",	     BBO(16,BOF,0,0), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bbf",     BBO(16,BOF,0,0), BBOY_MASK, POWER,		{ BI, BD } },
+{ "bfl-",    BBO(16,BOF,0,1), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bfl+",    BBO(16,BOF,0,1), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bfl",     BBO(16,BOF,0,1), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bbfl",    BBO(16,BOF,0,1), BBOY_MASK, POWER,		{ BI, BD } },
+{ "bfa-",    BBO(16,BOF,1,0), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bfa+",    BBO(16,BOF,1,0), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bfa",     BBO(16,BOF,1,0), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bbfa",    BBO(16,BOF,1,0), BBOY_MASK, POWER,		{ BI, BDA } },
+{ "bfla-",   BBO(16,BOF,1,1), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bfla+",   BBO(16,BOF,1,1), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bfla",    BBO(16,BOF,1,1), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bbfla",   BBO(16,BOF,1,1), BBOY_MASK, POWER,		{ BI, BDA } },
+{ "bdzt-",   BBO(16,BODZT,0,0), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bdzt+",   BBO(16,BODZT,0,0), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bdzt",    BBO(16,BODZT,0,0), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bdztl-",  BBO(16,BODZT,0,1), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bdztl+",  BBO(16,BODZT,0,1), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bdztl",   BBO(16,BODZT,0,1), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bdzta-",  BBO(16,BODZT,1,0), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bdzta+",  BBO(16,BODZT,1,0), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bdzta",   BBO(16,BODZT,1,0), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bdztla",  BBO(16,BODZT,1,1), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bdzf-",   BBO(16,BODZF,0,0), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bdzf+",   BBO(16,BODZF,0,0), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bdzf",    BBO(16,BODZF,0,0), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bdzfl-",  BBO(16,BODZF,0,1), BBOY_MASK, PPC,		{ BI, BDM } },
+{ "bdzfl+",  BBO(16,BODZF,0,1), BBOY_MASK, PPC,		{ BI, BDP } },
+{ "bdzfl",   BBO(16,BODZF,0,1), BBOY_MASK, PPC,		{ BI, BD } },
+{ "bdzfa-",  BBO(16,BODZF,1,0), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bdzfa+",  BBO(16,BODZF,1,0), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bdzfa",   BBO(16,BODZF,1,0), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, PPC,		{ BI, BDMA } },
+{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, PPC,		{ BI, BDPA } },
+{ "bdzfla",  BBO(16,BODZF,1,1), BBOY_MASK, PPC,		{ BI, BDA } },
+{ "bc-",     B(16,0,0),	B_MASK,		PPC,		{ BOE, BI, BDM } },
+{ "bc+",     B(16,0,0),	B_MASK,		PPC,		{ BOE, BI, BDP } },
+{ "bc",	     B(16,0,0),	B_MASK,		PPC|POWER,	{ BO, BI, BD } },
+{ "bcl-",    B(16,0,1),	B_MASK,		PPC,		{ BOE, BI, BDM } },
+{ "bcl+",    B(16,0,1),	B_MASK,		PPC,		{ BOE, BI, BDP } },
+{ "bcl",     B(16,0,1),	B_MASK,		PPC|POWER,	{ BO, BI, BD } },
+{ "bca-",    B(16,1,0),	B_MASK,		PPC,		{ BOE, BI, BDMA } },
+{ "bca+",    B(16,1,0),	B_MASK,		PPC,		{ BOE, BI, BDPA } },
+{ "bca",     B(16,1,0),	B_MASK,		PPC|POWER,	{ BO, BI, BDA } },
+{ "bcla-",   B(16,1,1),	B_MASK,		PPC,		{ BOE, BI, BDMA } },
+{ "bcla+",   B(16,1,1),	B_MASK,		PPC,		{ BOE, BI, BDPA } },
+{ "bcla",    B(16,1,1),	B_MASK,		PPC|POWER,	{ BO, BI, BDA } },
+
+{ "sc",      SC(17,1,0), 0xffffffff,	PPC,		{ 0 } },
+{ "svc",     SC(17,0,0), SC_MASK,	POWER,		{ LEV, FL1, FL2 } },
+{ "svcl",    SC(17,0,1), SC_MASK,	POWER,		{ LEV, FL1, FL2 } },
+{ "svca",    SC(17,1,0), SC_MASK,	POWER,		{ SV } },
+{ "svcla",   SC(17,1,1), SC_MASK,	POWER,		{ SV } },
+
+{ "b",	     B(18,0,0),	B_MASK,		PPC|POWER,	{ LI } },
+{ "bl",      B(18,0,1),	B_MASK,		PPC|POWER,	{ LI } },
+{ "ba",      B(18,1,0),	B_MASK,		PPC|POWER,	{ LIA } },
+{ "bla",     B(18,1,1),	B_MASK,		PPC|POWER,	{ LIA } },
+
+{ "mcrf",    XL(19,0),	XLBB_MASK|(3<<21)|(3<<16), PPC|POWER, { BF, BFA } },
+
+{ "blr",     XLO(19,BOU,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "br",      XLO(19,BOU,16,0), XLBOBIBB_MASK, POWER,	{ 0 } },
+{ "blrl",    XLO(19,BOU,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "brl",     XLO(19,BOU,16,1), XLBOBIBB_MASK, POWER,	{ 0 } },
+{ "bdnzlr",  XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlr",   XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlr-",  XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlr+",  XLO(19,BODZP,16,0), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlrl",  XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, PPC,	{ 0 } },
+{ "bltlr",   XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlr-",  XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlr+",  XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltr",    XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bltlrl",  XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltrl",   XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bgtlr",   XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlr-",  XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlr+",  XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtr",    XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bgtlrl",  XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtrl",   XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "beqlr",   XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlr-",  XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlr+",  XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqr",    XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "beqlrl",  XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqrl",   XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bsolr",   XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolr-",  XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolr+",  XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsor",    XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bsolrl",  XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsorl",   XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bunlr",   XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlr-",  XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlr+",  XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl",  XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr",   XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr-",  XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr+",  XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bger",    XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bgelrl",  XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgerl",   XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnllr",   XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllr-",  XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllr+",  XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlr",    XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnllrl",  XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlrl",   XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "blelr",   XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelr-",  XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelr+",  XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bler",    XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "blelrl",  XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blerl",   XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnglr",   XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglr-",  XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglr+",  XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngr",    XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnglrl",  XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngrl",   XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnelr",   XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelr-",  XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelr+",  XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bner",    XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnelrl",  XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnerl",   XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnslr",   XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslr-",  XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslr+",  XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsr",    XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnslrl",  XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsrl",   XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, POWER, { CR } },
+{ "bnulr",   XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulr-",  XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulr+",  XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl",  XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "btlr",    XLO(19,BOT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btlr-",   XLO(19,BOT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btlr+",   XLO(19,BOTP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bbtr",    XLO(19,BOT,16,0), XLBOBB_MASK, POWER,	{ BI } },
+{ "btlrl",   XLO(19,BOT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "btlrl-",  XLO(19,BOT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "btlrl+",  XLO(19,BOTP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bbtrl",   XLO(19,BOT,16,1), XLBOBB_MASK, POWER,	{ BI } },
+{ "bflr",    XLO(19,BOF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bflr-",   XLO(19,BOF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bflr+",   XLO(19,BOFP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bbfr",    XLO(19,BOF,16,0), XLBOBB_MASK, POWER,	{ BI } },
+{ "bflrl",   XLO(19,BOF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bflrl-",  XLO(19,BOF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bflrl+",  XLO(19,BOFP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bbfrl",   XLO(19,BOF,16,1), XLBOBB_MASK, POWER,	{ BI } },
+{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlr",  XLO(19,BODZT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflr",  XLO(19,BODZF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bclr",    XLLK(19,16,0), XLYBB_MASK,	PPC,		{ BO, BI } },
+{ "bclrl",   XLLK(19,16,1), XLYBB_MASK,	PPC,		{ BO, BI } },
+{ "bclr+",   XLYLK(19,16,1,0), XLYBB_MASK, PPC,		{ BOE, BI } },
+{ "bclrl+",  XLYLK(19,16,1,1), XLYBB_MASK, PPC,		{ BOE, BI } },
+{ "bclr-",   XLYLK(19,16,0,0), XLYBB_MASK, PPC,		{ BOE, BI } },
+{ "bclrl-",  XLYLK(19,16,0,1), XLYBB_MASK, PPC,		{ BOE, BI } },
+{ "bcr",     XLLK(19,16,0), XLBB_MASK,	POWER,		{ BO, BI } },
+{ "bcrl",    XLLK(19,16,1), XLBB_MASK,	POWER,		{ BO, BI } },
+
+{ "crnot",   XL(19,33), XL_MASK,	PPC,		{ BT, BA, BBA } },
+{ "crnor",   XL(19,33),	XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "rfi",     XL(19,50),	0xffffffff,	PPC|POWER,	{ 0 } },
+{ "rfci",    XL(19,51),	0xffffffff,	PPC,		{ 0 } },
+
+{ "rfsvc",   XL(19,82),	0xffffffff,	POWER,		{ 0 } },
+
+{ "crandc",  XL(19,129), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "isync",   XL(19,150), 0xffffffff,	PPC,		{ 0 } },
+{ "ics",     XL(19,150), 0xffffffff,	POWER,		{ 0 } },
+
+{ "crclr",   XL(19,193), XL_MASK,	PPC,		{ BT, BAT, BBA } },
+{ "crxor",   XL(19,193), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crnand",  XL(19,225), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crand",   XL(19,257), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crset",   XL(19,289), XL_MASK,	PPC,		{ BT, BAT, BBA } },
+{ "creqv",   XL(19,289), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crorc",   XL(19,417), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "crmove",  XL(19,449), XL_MASK,	PPC,		{ BT, BA, BBA } },
+{ "cror",    XL(19,449), XL_MASK,	PPC|POWER,	{ BT, BA, BB } },
+
+{ "bctr",    XLO(19,BOU,528,0), XLBOBIBB_MASK, PPC|POWER, { 0 } },
+{ "bctrl",   XLO(19,BOU,528,1), XLBOBIBB_MASK, PPC|POWER, { 0 } },
+{ "bltctr",  XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctr-", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl", XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr",  XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr",  XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr",  XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr",  XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr",  XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr",  XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr",  XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr",  XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr",  XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr",  XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr",  XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "btctr",   XLO(19,BOT,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctr-",  XLO(19,BOT,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctr+",  XLO(19,BOTP,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctrl",  XLO(19,BOT,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctrl-", XLO(19,BOT,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctr",   XLO(19,BOF,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctr-",  XLO(19,BOF,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctr+",  XLO(19,BOFP,528,0), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctrl",  XLO(19,BOF,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctrl-", XLO(19,BOF,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, PPC,	{ BI } },
+{ "bcctr",   XLLK(19,528,0), XLYBB_MASK, PPC,		{ BO, BI } },
+{ "bcctr-",  XLYLK(19,528,0,0), XLYBB_MASK, PPC,	{ BOE, BI } },
+{ "bcctr+",  XLYLK(19,528,1,0), XLYBB_MASK, PPC,	{ BOE, BI } },
+{ "bcctrl",  XLLK(19,528,1), XLYBB_MASK, PPC,		{ BO, BI } },
+{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPC,	{ BOE, BI } },
+{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPC,	{ BOE, BI } },
+{ "bcc",     XLLK(19,528,0), XLBB_MASK,	POWER,		{ BO, BI } },
+{ "bccl",    XLLK(19,528,1), XLBB_MASK,	POWER,		{ BO, BI } },
+
+{ "rlwimi",  M(20,0),	M_MASK,		PPC,		{ RA,RS,SH,MBE,ME } },
+{ "rlimi",   M(20,0),	M_MASK,		POWER,		{ RA,RS,SH,MBE,ME } },
+
+{ "rlwimi.", M(20,1),	M_MASK,		PPC,		{ RA,RS,SH,MBE,ME } },
+{ "rlimi.",  M(20,1),	M_MASK,		POWER,		{ RA,RS,SH,MBE,ME } },
+
+{ "rotlwi",  MME(21,31,0), MMBME_MASK,	PPC,		{ RA, RS, SH } },
+{ "clrlwi",  MME(21,31,0), MSHME_MASK,	PPC,		{ RA, RS, MB } },
+{ "rlwinm",  M(21,0),	M_MASK,		PPC,		{ RA,RS,SH,MBE,ME } },
+{ "rlinm",   M(21,0),	M_MASK,		POWER,		{ RA,RS,SH,MBE,ME } },
+{ "rotlwi.", MME(21,31,1), MMBME_MASK,	PPC,		{ RA,RS,SH } },
+{ "clrlwi.", MME(21,31,1), MSHME_MASK,	PPC,		{ RA, RS, MB } },
+{ "rlwinm.", M(21,1),	M_MASK,		PPC,		{ RA,RS,SH,MBE,ME } },
+{ "rlinm.",  M(21,1),	M_MASK,		POWER,		{ RA,RS,SH,MBE,ME } },
+
+{ "rlmi",    M(22,0),	M_MASK,		POWER|M601,	{ RA,RS,RB,MBE,ME } },
+{ "rlmi.",   M(22,1),	M_MASK,		POWER|M601,	{ RA,RS,RB,MBE,ME } },
+
+{ "rotlw",   MME(23,31,0), MMBME_MASK,	PPC,		{ RA, RS, RB } },
+{ "rlwnm",   M(23,0),	M_MASK,		PPC,		{ RA,RS,RB,MBE,ME } },
+{ "rlnm",    M(23,0),	M_MASK,		POWER,		{ RA,RS,RB,MBE,ME } },
+{ "rotlw.",  MME(23,31,1), MMBME_MASK,	PPC,		{ RA, RS, RB } },
+{ "rlwnm.",  M(23,1),	M_MASK,		PPC,		{ RA,RS,RB,MBE,ME } },
+{ "rlnm.",   M(23,1),	M_MASK,		POWER,		{ RA,RS,RB,MBE,ME } },
+
+{ "nop",     OP(24),	0xffffffff,	PPC,		{ 0 } },
+{ "ori",     OP(24),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "oril",    OP(24),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "oris",    OP(25),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "oriu",    OP(25),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "xori",    OP(26),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "xoril",   OP(26),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "xoris",   OP(27),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "xoriu",   OP(27),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "andi.",   OP(28),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "andil.",  OP(28),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "andis.",  OP(29),	OP_MASK,	PPC,		{ RA, RS, UI } },
+{ "andiu.",  OP(29),	OP_MASK,	POWER,		{ RA, RS, UI } },
+
+{ "rotldi",  MD(30,0,0), MDMB_MASK,	PPC|B64,	{ RA, RS, SH6 } },
+{ "clrldi",  MD(30,0,0), MDSH_MASK,	PPC|B64,	{ RA, RS, MB6 } },
+{ "rldicl",  MD(30,0,0), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+{ "rotldi.", MD(30,0,1), MDMB_MASK,	PPC|B64,	{ RA, RS, SH6 } },
+{ "clrldi.", MD(30,0,1), MDSH_MASK,	PPC|B64,	{ RA, RS, MB6 } },
+{ "rldicl.", MD(30,0,1), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+
+{ "rldicr",  MD(30,1,0), MD_MASK,	PPC|B64,	{ RA, RS, SH6, ME6 } },
+{ "rldicr.", MD(30,1,1), MD_MASK,	PPC|B64,	{ RA, RS, SH6, ME6 } },
+
+{ "rldic",   MD(30,2,0), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+{ "rldic.",  MD(30,2,1), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+
+{ "rldimi",  MD(30,3,0), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+{ "rldimi.", MD(30,3,1), MD_MASK,	PPC|B64,	{ RA, RS, SH6, MB6 } },
+
+{ "rotld",   MDS(30,8,0), MDSMB_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "rldcl",   MDS(30,8,0), MDS_MASK,	PPC|B64,	{ RA, RS, RB, MB6 } },
+{ "rotld.",  MDS(30,8,1), MDSMB_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "rldcl.",  MDS(30,8,1), MDS_MASK,	PPC|B64,	{ RA, RS, RB, MB6 } },
+
+{ "rldcr",   MDS(30,9,0), MDS_MASK,	PPC|B64,	{ RA, RS, RB, ME6 } },
+{ "rldcr.",  MDS(30,9,1), MDS_MASK,	PPC|B64,	{ RA, RS, RB, ME6 } },
+
+{ "cmpw",    XCMPL(31,0,0), XCMPL_MASK, PPC,		{ OBF, RA, RB } },
+{ "cmpd",    XCMPL(31,0,1), XCMPL_MASK, PPC|B64,	{ OBF, RA, RB } },
+{ "cmp",     X(31,0),	XCMP_MASK,	PPC,		{ BF, L, RA, RB } },
+{ "cmp",     X(31,0),	XCMPL_MASK,	POWER,		{ BF, RA, RB } },
+
+{ "twlgt",   XTO(31,4,TOLGT), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlgt",    XTO(31,4,TOLGT), XTO_MASK, POWER,		{ RA, RB } },
+{ "twllt",   XTO(31,4,TOLLT), XTO_MASK, PPC,		{ RA, RB } },
+{ "tllt",    XTO(31,4,TOLLT), XTO_MASK, POWER,		{ RA, RB } },
+{ "tweq",    XTO(31,4,TOEQ), XTO_MASK,	PPC,		{ RA, RB } },
+{ "teq",     XTO(31,4,TOEQ), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twlge",   XTO(31,4,TOLGE), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlge",    XTO(31,4,TOLGE), XTO_MASK, POWER,		{ RA, RB } },
+{ "twlnl",   XTO(31,4,TOLNL), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlnl",    XTO(31,4,TOLNL), XTO_MASK, POWER,		{ RA, RB } },
+{ "twlle",   XTO(31,4,TOLLE), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlle",    XTO(31,4,TOLLE), XTO_MASK, POWER,		{ RA, RB } },
+{ "twlng",   XTO(31,4,TOLNG), XTO_MASK, PPC,		{ RA, RB } },
+{ "tlng",    XTO(31,4,TOLNG), XTO_MASK, POWER,		{ RA, RB } },
+{ "twgt",    XTO(31,4,TOGT), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tgt",     XTO(31,4,TOGT), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twge",    XTO(31,4,TOGE), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tge",     XTO(31,4,TOGE), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twnl",    XTO(31,4,TONL), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tnl",     XTO(31,4,TONL), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twlt",    XTO(31,4,TOLT), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tlt",     XTO(31,4,TOLT), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twle",    XTO(31,4,TOLE), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tle",     XTO(31,4,TOLE), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twng",    XTO(31,4,TONG), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tng",     XTO(31,4,TONG), XTO_MASK,	POWER,		{ RA, RB } },
+{ "twne",    XTO(31,4,TONE), XTO_MASK,	PPC,		{ RA, RB } },
+{ "tne",     XTO(31,4,TONE), XTO_MASK,	POWER,		{ RA, RB } },
+{ "trap",    XTO(31,4,TOU), 0xffffffff,	PPC,		{ 0 } },
+{ "tw",      X(31,4),	X_MASK,		PPC,		{ TO, RA, RB } },
+{ "t",       X(31,4),	X_MASK,		POWER,		{ TO, RA, RB } },
+
+{ "subfc",   XO(31,8,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sf",      XO(31,8,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subc",    XO(31,8,0,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfc.",  XO(31,8,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sf.",     XO(31,8,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subc.",   XO(31,8,0,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfco",  XO(31,8,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfo",     XO(31,8,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subco",   XO(31,8,1,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfco.", XO(31,8,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfo.",    XO(31,8,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subco.",  XO(31,8,1,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+
+{ "mulhdu",  XO(31,9,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulhdu.", XO(31,9,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "addc",    XO(31,10,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "a",       XO(31,10,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addc.",   XO(31,10,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "a.",      XO(31,10,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addco",   XO(31,10,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "ao",      XO(31,10,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addco.",  XO(31,10,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "ao.",     XO(31,10,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "mulhwu",  XO(31,11,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "mulhwu.", XO(31,11,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+
+{ "mfcr",    X(31,19),	XRARB_MASK,	POWER|PPC,	{ RT } },
+
+{ "lwarx",   X(31,20),	X_MASK,		PPC,		{ RT, RA, RB } },
+
+{ "ldx",     X(31,21),	X_MASK,		PPC|B64,	{ RT, RA, RB } },
+
+{ "lwzx",    X(31,23),	X_MASK,		PPC,		{ RT, RA, RB } },
+{ "lx",      X(31,23),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "slw",     XRC(31,24,0), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sl",      XRC(31,24,0), X_MASK,	POWER,		{ RA, RS, RB } },
+{ "slw.",    XRC(31,24,1), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sl.",     XRC(31,24,1), X_MASK,	POWER,		{ RA, RS, RB } },
+
+{ "cntlzw",  XRC(31,26,0), XRB_MASK,	PPC,		{ RA, RS } },
+{ "cntlz",   XRC(31,26,0), XRB_MASK,	POWER,		{ RA, RS } },
+{ "cntlzw.", XRC(31,26,1), XRB_MASK,	PPC,		{ RA, RS } },
+{ "cntlz.",  XRC(31,26,1), XRB_MASK, 	POWER,		{ RA, RS } },
+
+{ "sld",     XRC(31,27,0), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "sld.",    XRC(31,27,1), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+
+{ "and",     XRC(31,28,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "and.",    XRC(31,28,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "maskg",   XRC(31,29,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "maskg.",  XRC(31,29,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "cmplw",   XCMPL(31,32,0), XCMPL_MASK, PPC,		{ OBF, RA, RB } },
+{ "cmpld",   XCMPL(31,32,1), XCMPL_MASK, PPC|B64,	{ OBF, RA, RB } },
+{ "cmpl",    X(31,32),	XCMP_MASK,	PPC,		{ BF, L, RA, RB } },
+{ "cmpl",    X(31,32),	XCMPL_MASK,	POWER,		{ BF, RA, RB } },
+
+{ "subf",    XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sub",     XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subf.",   XO(31,40,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sub.",    XO(31,40,0,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfo",   XO(31,40,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "subo",    XO(31,40,1,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+{ "subfo.",  XO(31,40,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "subo.",   XO(31,40,1,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+
+{ "ldux",    X(31,53),	X_MASK,		PPC|B64,	{ RT, RAL, RB } },
+
+{ "dcbst",   X(31,54),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "lwzux",   X(31,55),	X_MASK,		PPC,		{ RT, RAL, RB } },
+{ "lux",     X(31,55),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "cntlzd",  XRC(31,58,0), XRB_MASK,	PPC|B64,	{ RA, RS } },
+{ "cntlzd.", XRC(31,58,1), XRB_MASK,	PPC|B64,	{ RA, RS } },
+
+{ "andc",    XRC(31,60,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "andc.",   XRC(31,60,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "tdlgt",   XTO(31,68,TOLGT), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdllt",   XTO(31,68,TOLLT), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdeq",    XTO(31,68,TOEQ), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlge",   XTO(31,68,TOLGE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlnl",   XTO(31,68,TOLNL), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlle",   XTO(31,68,TOLLE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlng",   XTO(31,68,TOLNG), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdgt",    XTO(31,68,TOGT), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdge",    XTO(31,68,TOGE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdnl",    XTO(31,68,TONL), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdlt",    XTO(31,68,TOLT), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdle",    XTO(31,68,TOLE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdng",    XTO(31,68,TONG), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "tdne",    XTO(31,68,TONE), XTO_MASK, PPC|B64,	{ RA, RB } },
+{ "td",	     X(31,68),	X_MASK,		PPC|B64,	{ TO, RA, RB } },
+
+{ "mulhd",   XO(31,73,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulhd.",  XO(31,73,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "mulhw",   XO(31,75,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "mulhw.",  XO(31,75,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+
+{ "mfmsr",   X(31,83),	XRARB_MASK,	PPC|POWER,	{ RT } },
+
+{ "ldarx",   X(31,84),	X_MASK,		PPC|B64,	{ RT, RA, RB } },
+
+{ "dcbf",    X(31,86),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "lbzx",    X(31,87),	X_MASK,		PPC|POWER,	{ RT, RA, RB } },
+
+{ "neg",     XO(31,104,0,0), XORB_MASK,	PPC|POWER,	{ RT, RA } },
+{ "neg.",    XO(31,104,0,1), XORB_MASK,	PPC|POWER,	{ RT, RA } },
+{ "nego",    XO(31,104,1,0), XORB_MASK,	PPC|POWER,	{ RT, RA } },
+{ "nego.",   XO(31,104,1,1), XORB_MASK,	PPC|POWER,	{ RT, RA } },
+
+{ "mul",     XO(31,107,0,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "mul.",    XO(31,107,0,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "mulo",    XO(31,107,1,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "mulo.",   XO(31,107,1,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "clf",     X(31,118), XRB_MASK,	POWER,		{ RT, RA } },
+
+{ "lbzux",   X(31,119),	X_MASK,		PPC|POWER,	{ RT, RAL, RB } },
+
+{ "not",     XRC(31,124,0), X_MASK,	PPC|POWER,	{ RA, RS, RBS } },
+{ "nor",     XRC(31,124,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "not.",    XRC(31,124,1), X_MASK,	PPC|POWER,	{ RA, RS, RBS } },
+{ "nor.",    XRC(31,124,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "subfe",   XO(31,136,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfe",     XO(31,136,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subfe.",  XO(31,136,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfe.",    XO(31,136,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subfeo",  XO(31,136,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfeo",    XO(31,136,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "subfeo.", XO(31,136,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "sfeo.",   XO(31,136,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "adde",    XO(31,138,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "ae",      XO(31,138,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "adde.",   XO(31,138,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "ae.",     XO(31,138,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addeo",   XO(31,138,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "aeo",     XO(31,138,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addeo.",  XO(31,138,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "aeo.",    XO(31,138,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "mtcr",    XFXM(31,144,0xff), XFXFXM_MASK|FXM_MASK, PPC|POWER, { RS }},
+{ "mtcrf",   X(31,144),	XFXFXM_MASK,	PPC|POWER,	{ FXM, RS } },
+
+{ "mtmsr",   X(31,146),	XRARB_MASK,	PPC|POWER,	{ RS } },
+{ "mtmsrd",  X(31,178),	XRARB_MASK,	PPC|POWER,	{ RS } },
+
+{ "stdx",    X(31,149), X_MASK,		PPC|B64,	{ RS, RA, RB } },
+
+{ "stwcx.",  XRC(31,150,1), X_MASK,	PPC,		{ RS, RA, RB } },
+
+{ "stwx",    X(31,151), X_MASK,		PPC,		{ RS, RA, RB } },
+{ "stx",     X(31,151), X_MASK,		POWER,		{ RS, RA, RB } },
+
+{ "slq",     XRC(31,152,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "slq.",    XRC(31,152,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "sle",     XRC(31,153,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sle.",    XRC(31,153,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "stdux",   X(31,181),	X_MASK,		PPC|B64,	{ RS, RAS, RB } },
+
+{ "stwux",   X(31,183),	X_MASK,		PPC,		{ RS, RAS, RB } },
+{ "stux",    X(31,183),	X_MASK,		POWER,		{ RS, RA, RB } },
+
+{ "sliq",    XRC(31,184,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "sliq.",   XRC(31,184,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "subfze",  XO(31,200,0,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfze",    XO(31,200,0,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfze.", XO(31,200,0,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfze.",   XO(31,200,0,1), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfzeo",   XO(31,200,1,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfzeo.",  XO(31,200,1,1), XORB_MASK, POWER,		{ RT, RA } },
+
+{ "addze",   XO(31,202,0,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "aze",     XO(31,202,0,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "addze.",  XO(31,202,0,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "aze.",    XO(31,202,0,1), XORB_MASK, POWER,		{ RT, RA } },
+{ "addzeo",  XO(31,202,1,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "azeo",    XO(31,202,1,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "azeo.",   XO(31,202,1,1), XORB_MASK, POWER,		{ RT, RA } },
+
+{ "mtsr",    X(31,210),	XRB_MASK|(1<<20), PPC|POWER|B32, { SR, RS } },
+
+{ "stdcx.",  XRC(31,214,1), X_MASK,	PPC|B64,	{ RS, RA, RB } },
+
+{ "stbx",    X(31,215),	X_MASK,		PPC|POWER,	{ RS, RA, RB } },
+
+{ "sllq",    XRC(31,216,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sllq.",   XRC(31,216,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "sleq",    XRC(31,217,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sleq.",   XRC(31,217,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "subfme",  XO(31,232,0,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfme",    XO(31,232,0,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfme.", XO(31,232,0,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfme.",   XO(31,232,0,1), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfmeo",   XO(31,232,1,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "sfmeo.",  XO(31,232,1,1), XORB_MASK, POWER,		{ RT, RA } },
+
+{ "mulld",   XO(31,233,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulld.",  XO(31,233,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulldo",  XO(31,233,1,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "mulldo.", XO(31,233,1,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "addme",   XO(31,234,0,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "ame",     XO(31,234,0,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "addme.",  XO(31,234,0,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "ame.",    XO(31,234,0,1), XORB_MASK, POWER,		{ RT, RA } },
+{ "addmeo",  XO(31,234,1,0), XORB_MASK, PPC,		{ RT, RA } },
+{ "ameo",    XO(31,234,1,0), XORB_MASK, POWER,		{ RT, RA } },
+{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPC,		{ RT, RA } },
+{ "ameo.",   XO(31,234,1,1), XORB_MASK, POWER,		{ RT, RA } },
+
+{ "mullw",   XO(31,235,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "muls",    XO(31,235,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "mullw.",  XO(31,235,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "muls.",   XO(31,235,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "mullwo",  XO(31,235,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "mulso",   XO(31,235,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "mullwo.", XO(31,235,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "mulso.",  XO(31,235,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "mtsrin",  X(31,242),	XRA_MASK,	PPC|B32,	{ RS, RB } },
+{ "mtsri",   X(31,242),	XRA_MASK,	POWER|B32,	{ RS, RB } },
+
+{ "dcbtst",  X(31,246),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "stbux",   X(31,247),	X_MASK,		PPC|POWER,	{ RS, RAS, RB } },
+
+{ "slliq",   XRC(31,248,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "slliq.",  XRC(31,248,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "doz",     XO(31,264,0,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "doz.",    XO(31,264,0,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "dozo",    XO(31,264,1,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "dozo.",   XO(31,264,1,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "add",     XO(31,266,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "cax",     XO(31,266,0,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "add.",    XO(31,266,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "cax.",    XO(31,266,0,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addo",    XO(31,266,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "caxo",    XO(31,266,1,0), XO_MASK,	POWER,		{ RT, RA, RB } },
+{ "addo.",   XO(31,266,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "caxo.",   XO(31,266,1,1), XO_MASK,	POWER,		{ RT, RA, RB } },
+
+{ "lscbx",   XRC(31,277,0), X_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "lscbx.",  XRC(31,277,1), X_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "dcbt",    X(31,278),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "lhzx",    X(31,279),	X_MASK,		PPC|POWER,	{ RT, RA, RB } },
+
+{ "icbt",    X(31,262),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "eqv",     XRC(31,284,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "eqv.",    XRC(31,284,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "tlbie",   X(31,306),	XRTRA_MASK,	PPC,		{ RB } },
+{ "tlbi",    X(31,306),	XRTRA_MASK,	POWER,		{ RB } },
+
+{ "eciwx",   X(31,310), X_MASK,		PPC,		{ RT, RA, RB } },
+
+{ "lhzux",   X(31,311),	X_MASK,		PPC|POWER,	{ RT, RAL, RB } },
+
+{ "xor",     XRC(31,316,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "xor.",    XRC(31,316,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "mfdcr",   X(31,323),	X_MASK,		PPC,		{ RT, SPR } },
+
+{ "div",     XO(31,331,0,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "div.",    XO(31,331,0,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divo",    XO(31,331,1,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divo.",   XO(31,331,1,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "mfmq",    XSPR(31,339,0), XSPR_MASK,	POWER|M601,	{ RT } },
+{ "mfxer",   XSPR(31,339,1), XSPR_MASK,	PPC|POWER,	{ RT } },
+{ "mfrtcu",  XSPR(31,339,4), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfrtcl",  XSPR(31,339,5), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfdec",   XSPR(31,339,6), XSPR_MASK, POWER|M601,	{ RT } },
+{ "mflr",    XSPR(31,339,8), XSPR_MASK,	PPC|POWER,	{ RT } },
+{ "mfctr",   XSPR(31,339,9), XSPR_MASK,	PPC|POWER,	{ RT } },
+{ "mftid",   XSPR(31,339,17), XSPR_MASK, POWER,		{ RT } },
+{ "mfdsisr", XSPR(31,339,18), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfdar",   XSPR(31,339,19), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfdec",   XSPR(31,339,22), XSPR_MASK, PPC,		{ RT } },
+{ "mfsdr0",  XSPR(31,339,24), XSPR_MASK, POWER,		{ RT } },
+{ "mfsdr1",  XSPR(31,339,25), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfsrr0",  XSPR(31,339,26), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfsrr1",  XSPR(31,339,27), XSPR_MASK, PPC|POWER,	{ RT } },
+{ "mfsprg",  XSPR(31,339,272), XSPRG_MASK, PPC,		{ RT, SPRG } },
+{ "mfasr",   XSPR(31,339,280), XSPR_MASK, PPC|B64,	{ RT } },
+{ "mfear",   XSPR(31,339,282), XSPR_MASK, PPC,		{ RT } },
+{ "mfpvr",   XSPR(31,339,287), XSPR_MASK, PPC,		{ RT } },
+{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+{ "mfdbatl", XSPR(31,339,537), XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+{ "mfspr",   X(31,339),	X_MASK,		PPC|POWER,	{ RT, SPR } },
+
+{ "lwax",    X(31,341),	X_MASK,		PPC|B64,	{ RT, RA, RB } },
+
+{ "lhax",    X(31,343),	X_MASK,		PPC|POWER,	{ RT, RA, RB } },
+
+{ "dccci",   X(31,454),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "abs",     XO(31,360,0,0), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "abs.",    XO(31,360,0,1), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "abso",    XO(31,360,1,0), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "abso.",   XO(31,360,1,1), XORB_MASK, POWER|M601,	{ RT, RA } },
+
+{ "divs",    XO(31,363,0,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divs.",   XO(31,363,0,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divso",   XO(31,363,1,0), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+{ "divso.",  XO(31,363,1,1), XO_MASK,	POWER|M601,	{ RT, RA, RB } },
+
+{ "tlbia",   X(31,370),	0xffffffff,	PPC,		{ 0 } },
+
+{ "mftbu",   XSPR(31,371,269), XSPR_MASK, PPC,		{ RT } },
+{ "mftb",    X(31,371),	X_MASK,		PPC,		{ RT, TBR } },
+
+{ "lwaux",   X(31,373),	X_MASK,		PPC|B64,	{ RT, RAL, RB } },
+
+{ "lhaux",   X(31,375),	X_MASK,		PPC|POWER,	{ RT, RAL, RB } },
+
+{ "sthx",    X(31,407),	X_MASK,		PPC|POWER,	{ RS, RA, RB } },
+
+{ "lfqx",    X(31,791),	X_MASK,		POWER2,		{ FRT, RA, RB } },
+
+{ "lfqux",   X(31,823),	X_MASK,		POWER2,		{ FRT, RA, RB } },
+
+{ "stfqx",   X(31,919),	X_MASK,		POWER2,		{ FRS, RA, RB } },
+
+{ "stfqux",  X(31,951),	X_MASK,		POWER2,		{ FRS, RA, RB } },
+
+{ "orc",     XRC(31,412,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "orc.",    XRC(31,412,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "sradi",   XS(31,413,0), XS_MASK,	PPC|B64,	{ RA, RS, SH6 } },
+{ "sradi.",  XS(31,413,1), XS_MASK,	PPC|B64,	{ RA, RS, SH6 } },
+
+{ "slbie",   X(31,434),	XRTRA_MASK,	PPC|B64,	{ RB } },
+
+{ "ecowx",   X(31,438),	X_MASK,		PPC,		{ RT, RA, RB } },
+
+{ "sthux",   X(31,439),	X_MASK,		PPC|POWER,	{ RS, RAS, RB } },
+
+{ "mr",	     XRC(31,444,0), X_MASK,	PPC|POWER,	{ RA, RS, RBS } },
+{ "or",      XRC(31,444,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "mr.",     XRC(31,444,1), X_MASK,	PPC|POWER,	{ RA, RS, RBS } },
+{ "or.",     XRC(31,444,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "mtdcr",   X(31,451),	X_MASK,		PPC,		{ SPR, RS } },
+
+{ "divdu",   XO(31,457,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divdu.",  XO(31,457,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divduo",  XO(31,457,1,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divduo.", XO(31,457,1,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "divwu",   XO(31,459,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwu.",  XO(31,459,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwuo",  XO(31,459,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwuo.", XO(31,459,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+
+{ "mtmq",    XSPR(31,467,0), XSPR_MASK,	POWER|M601,	{ RS } },
+{ "mtxer",   XSPR(31,467,1), XSPR_MASK,	PPC|POWER,	{ RS } },
+{ "mtlr",    XSPR(31,467,8), XSPR_MASK,	PPC|POWER,	{ RS } },
+{ "mtctr",   XSPR(31,467,9), XSPR_MASK,	PPC|POWER,	{ RS } },
+{ "mttid",   XSPR(31,467,17), XSPR_MASK, POWER,		{ RS } },
+{ "mtdsisr", XSPR(31,467,18), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtdar",   XSPR(31,467,19), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtrtcu",  XSPR(31,467,20), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtrtcl",  XSPR(31,467,21), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtdec",   XSPR(31,467,22), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtsdr0",  XSPR(31,467,24), XSPR_MASK, POWER,		{ RS } },
+{ "mtsdr1",  XSPR(31,467,25), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtsrr0",  XSPR(31,467,26), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtsrr1",  XSPR(31,467,27), XSPR_MASK, PPC|POWER,	{ RS } },
+{ "mtsprg",  XSPR(31,467,272), XSPRG_MASK, PPC,		{ SPRG, RS } },
+{ "mtasr",   XSPR(31,467,280), XSPR_MASK, PPC|B64,	{ RS } },
+{ "mtear",   XSPR(31,467,282), XSPR_MASK, PPC,		{ RS } },
+{ "mttbl",   XSPR(31,467,284), XSPR_MASK, PPC,		{ RS } },
+{ "mttbu",   XSPR(31,467,285), XSPR_MASK, PPC,		{ RS } },
+{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+{ "mtdbatl", XSPR(31,467,537), XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+{ "mtspr",   X(31,467),	X_MASK,		PPC|POWER,	{ SPR, RS } },
+
+{ "dcbi",    X(31,470),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "nand",    XRC(31,476,0), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+{ "nand.",   XRC(31,476,1), X_MASK,	PPC|POWER,	{ RA, RS, RB } },
+
+{ "nabs",    XO(31,488,0,0), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "nabs.",   XO(31,488,0,1), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "nabso",   XO(31,488,1,0), XORB_MASK, POWER|M601,	{ RT, RA } },
+{ "nabso.",  XO(31,488,1,1), XORB_MASK, POWER|M601,	{ RT, RA } },
+
+{ "divd",    XO(31,489,0,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divd.",   XO(31,489,0,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divdo",   XO(31,489,1,0), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+{ "divdo.",  XO(31,489,1,1), XO_MASK,	PPC|B64,	{ RT, RA, RB } },
+
+{ "divw",    XO(31,491,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divw.",   XO(31,491,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwo",   XO(31,491,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+{ "divwo.",  XO(31,491,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+
+{ "slbia",   X(31,498),	0xffffffff,	PPC|B64,	{ 0 } },
+
+{ "cli",     X(31,502), XRB_MASK,	POWER,		{ RT, RA } },
+
+{ "mcrxr",   X(31,512),	XRARB_MASK|(3<<21), PPC|POWER,	{ BF } },
+
+{ "clcs",    X(31,531), XRB_MASK,	POWER|M601,	{ RT, RA } },
+
+{ "lswx",    X(31,533),	X_MASK,		PPC,		{ RT, RA, RB } },
+{ "lsx",     X(31,533),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "lwbrx",   X(31,534),	X_MASK,		PPC,		{ RT, RA, RB } },
+{ "lbrx",    X(31,534),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "lfsx",    X(31,535),	X_MASK,		PPC|POWER,	{ FRT, RA, RB } },
+
+{ "srw",     XRC(31,536,0), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sr",      XRC(31,536,0), X_MASK,	POWER,		{ RA, RS, RB } },
+{ "srw.",    XRC(31,536,1), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sr.",     XRC(31,536,1), X_MASK,	POWER,		{ RA, RS, RB } },
+
+{ "rrib",    XRC(31,537,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "rrib.",   XRC(31,537,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "srd",     XRC(31,539,0), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "srd.",    XRC(31,539,1), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+
+{ "maskir",  XRC(31,541,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "maskir.", XRC(31,541,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "tlbsync", X(31,566),	0xffffffff,	PPC,		{ 0 } },
+
+{ "lfsux",   X(31,567),	X_MASK,		PPC|POWER,	{ FRT, RAS, RB } },
+
+{ "mfsr",    X(31,595),	XRB_MASK|(1<<20), PPC|POWER|B32, { RT, SR } },
+
+{ "lswi",    X(31,597),	X_MASK,		PPC,		{ RT, RA, NB } },
+{ "lsi",     X(31,597),	X_MASK,		POWER,		{ RT, RA, NB } },
+
+{ "sync",    X(31,598), 0xffffffff,	PPC,		{ 0 } },
+{ "dcs",     X(31,598), 0xffffffff,	POWER,		{ 0 } },
+
+{ "lfdx",    X(31,599), X_MASK,		PPC|POWER,	{ FRT, RA, RB } },
+
+{ "mfsri",   X(31,627), X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "dclst",   X(31,630), XRB_MASK,	POWER,		{ RS, RA } },
+
+{ "lfdux",   X(31,631), X_MASK,		PPC|POWER,	{ FRT, RAS, RB } },
+
+{ "mfsrin",  X(31,659), XRA_MASK,	PPC|B32,	{ RT, RB } },
+
+{ "stswx",   X(31,661), X_MASK,		PPC,		{ RS, RA, RB } },
+{ "stsx",    X(31,661), X_MASK,		POWER,		{ RS, RA, RB } },
+
+{ "stwbrx",  X(31,662), X_MASK,		PPC,		{ RS, RA, RB } },
+{ "stbrx",   X(31,662), X_MASK,		POWER,		{ RS, RA, RB } },
+
+{ "stfsx",   X(31,663), X_MASK,		PPC|POWER,	{ FRS, RA, RB } },
+
+{ "srq",     XRC(31,664,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "srq.",    XRC(31,664,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "sre",     XRC(31,665,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sre.",    XRC(31,665,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "stfsux",  X(31,695),	X_MASK,		PPC|POWER,	{ FRS, RAS, RB } },
+
+{ "sriq",    XRC(31,696,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "sriq.",   XRC(31,696,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "stswi",   X(31,725),	X_MASK,		PPC,		{ RS, RA, NB } },
+{ "stsi",    X(31,725),	X_MASK,		POWER,		{ RS, RA, NB } },
+
+{ "stfdx",   X(31,727),	X_MASK,		PPC|POWER,	{ FRS, RA, RB } },
+
+{ "srlq",    XRC(31,728,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "srlq.",   XRC(31,728,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "sreq",    XRC(31,729,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sreq.",   XRC(31,729,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "stfdux",  X(31,759),	X_MASK,		PPC|POWER,	{ FRS, RAS, RB } },
+
+{ "srliq",   XRC(31,760,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "srliq.",  XRC(31,760,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "lhbrx",   X(31,790),	X_MASK,		PPC|POWER,	{ RT, RA, RB } },
+
+{ "sraw",    XRC(31,792,0), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sra",     XRC(31,792,0), X_MASK,	POWER,		{ RA, RS, RB } },
+{ "sraw.",   XRC(31,792,1), X_MASK,	PPC,		{ RA, RS, RB } },
+{ "sra.",    XRC(31,792,1), X_MASK,	POWER,		{ RA, RS, RB } },
+
+{ "srad",    XRC(31,794,0), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+{ "srad.",   XRC(31,794,1), X_MASK,	PPC|B64,	{ RA, RS, RB } },
+
+{ "rac",     X(31,818),	X_MASK,		POWER,		{ RT, RA, RB } },
+
+{ "srawi",   XRC(31,824,0), X_MASK,	PPC,		{ RA, RS, SH } },
+{ "srai",    XRC(31,824,0), X_MASK,	POWER,		{ RA, RS, SH } },
+{ "srawi.",  XRC(31,824,1), X_MASK,	PPC,		{ RA, RS, SH } },
+{ "srai.",   XRC(31,824,1), X_MASK,	POWER,		{ RA, RS, SH } },
+
+{ "eieio",   X(31,854),	0xffffffff,	PPC,		{ 0 } },
+
+{ "sthbrx",  X(31,918),	X_MASK,		PPC|POWER,	{ RS, RA, RB } },
+
+{ "sraq",    XRC(31,920,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "sraq.",   XRC(31,920,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "srea",    XRC(31,921,0), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+{ "srea.",   XRC(31,921,1), X_MASK,	POWER|M601,	{ RA, RS, RB } },
+
+{ "extsh",   XRC(31,922,0), XRB_MASK,	PPC,		{ RA, RS } },
+{ "exts",    XRC(31,922,0), XRB_MASK,	POWER,		{ RA, RS } },
+{ "extsh.",  XRC(31,922,1), XRB_MASK,	PPC,		{ RA, RS } },
+{ "exts.",   XRC(31,922,1), XRB_MASK,	POWER,		{ RA, RS } },
+
+{ "sraiq",   XRC(31,952,0), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+{ "sraiq.",  XRC(31,952,1), X_MASK,	POWER|M601,	{ RA, RS, SH } },
+
+{ "extsb",   XRC(31,954,0), XRB_MASK,	PPC,		{ RA, RS} },
+{ "extsb.",  XRC(31,954,1), XRB_MASK,	PPC,		{ RA, RS} },
+
+{ "iccci",   X(31,966),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "icbi",    X(31,982),	XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "stfiwx",  X(31,983),	X_MASK,		PPC,		{ FRS, RA, RB } },
+
+{ "extsw",   XRC(31,986,0), XRB_MASK,	PPC,		{ RA, RS } },
+{ "extsw.",  XRC(31,986,1), XRB_MASK,	PPC,		{ RA, RS } },
+
+{ "dcbz",    X(31,1014), XRT_MASK,	PPC,		{ RA, RB } },
+{ "dclz",    X(31,1014), XRT_MASK,	PPC,		{ RA, RB } },
+
+{ "lwz",     OP(32),	OP_MASK,	PPC,		{ RT, D, RA } },
+{ "l",	     OP(32),	OP_MASK,	POWER,		{ RT, D, RA } },
+
+{ "lwzu",    OP(33),	OP_MASK,	PPC,		{ RT, D, RAL } },
+{ "lu",      OP(33),	OP_MASK,	POWER,		{ RT, D, RA } },
+
+{ "lbz",     OP(34),	OP_MASK,	PPC|POWER,	{ RT, D, RA } },
+
+{ "lbzu",    OP(35),	OP_MASK,	PPC|POWER,	{ RT, D, RAL } },
+
+{ "stw",     OP(36),	OP_MASK,	PPC,		{ RS, D, RA } },
+{ "st",      OP(36),	OP_MASK,	POWER,		{ RS, D, RA } },
+
+{ "stwu",    OP(37),	OP_MASK,	PPC,		{ RS, D, RAS } },
+{ "stu",     OP(37),	OP_MASK,	POWER,		{ RS, D, RA } },
+
+{ "stb",     OP(38),	OP_MASK,	PPC|POWER,	{ RS, D, RA } },
+
+{ "stbu",    OP(39),	OP_MASK,	PPC|POWER,	{ RS, D, RAS } },
+
+{ "lhz",     OP(40),	OP_MASK,	PPC|POWER,	{ RT, D, RA } },
+
+{ "lhzu",    OP(41),	OP_MASK,	PPC|POWER,	{ RT, D, RAL } },
+
+{ "lha",     OP(42),	OP_MASK,	PPC|POWER,	{ RT, D, RA } },
+
+{ "lhau",    OP(43),	OP_MASK,	PPC|POWER,	{ RT, D, RAL } },
+
+{ "sth",     OP(44),	OP_MASK,	PPC|POWER,	{ RS, D, RA } },
+
+{ "sthu",    OP(45),	OP_MASK,	PPC|POWER,	{ RS, D, RAS } },
+
+{ "lmw",     OP(46),	OP_MASK,	PPC,		{ RT, D, RAM } },
+{ "lm",      OP(46),	OP_MASK,	POWER,		{ RT, D, RA } },
+
+{ "stmw",    OP(47),	OP_MASK,	PPC,		{ RS, D, RA } },
+{ "stm",     OP(47),	OP_MASK,	POWER,		{ RS, D, RA } },
+
+{ "lfs",     OP(48),	OP_MASK,	PPC|POWER,	{ FRT, D, RA } },
+
+{ "lfsu",    OP(49),	OP_MASK,	PPC|POWER,	{ FRT, D, RAS } },
+
+{ "lfd",     OP(50),	OP_MASK,	PPC|POWER,	{ FRT, D, RA } },
+
+{ "lfdu",    OP(51),	OP_MASK,	PPC|POWER,	{ FRT, D, RAS } },
+
+{ "stfs",    OP(52),	OP_MASK,	PPC|POWER,	{ FRS, D, RA } },
+
+{ "stfsu",   OP(53),	OP_MASK,	PPC|POWER,	{ FRS, D, RAS } },
+
+{ "stfd",    OP(54),	OP_MASK,	PPC|POWER,	{ FRS, D, RA } },
+
+{ "stfdu",   OP(55),	OP_MASK,	PPC|POWER,	{ FRS, D, RAS } },
+
+{ "lfq",     OP(56),	OP_MASK,	POWER2,		{ FRT, D, RA } },
+
+{ "lfqu",    OP(57),	OP_MASK,	POWER2,		{ FRT, D, RA } },
+
+{ "ld",      DSO(58,0),	DS_MASK,	PPC|B64,	{ RT, DS, RA } },
+
+{ "ldu",     DSO(58,1), DS_MASK,	PPC|B64,	{ RT, DS, RAL } },
+
+{ "lwa",     DSO(58,2), DS_MASK,	PPC|B64,	{ RT, DS, RA } },
+
+{ "fdivs",   A(59,18,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fdivs.",  A(59,18,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+
+{ "fsubs",   A(59,20,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fsubs.",  A(59,20,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+
+{ "fadds",   A(59,21,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fadds.",  A(59,21,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+
+{ "fsqrts",  A(59,22,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+{ "fsqrts.", A(59,22,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+
+{ "fres",    A(59,24,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+{ "fres.",   A(59,24,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+
+{ "fmuls",   A(59,25,0), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+{ "fmuls.",  A(59,25,1), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+
+{ "fmsubs",  A(59,28,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fmsubs.", A(59,28,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "fmadds",  A(59,29,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fmadds.", A(59,29,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "fnmsubs", A(59,30,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnmsubs.",A(59,30,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "fnmadds", A(59,31,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnmadds.",A(59,31,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "stfq",    OP(60),	OP_MASK,	POWER2,		{ FRS, D, RA } },
+
+{ "stfqu",   OP(61),	OP_MASK,	POWER2,		{ FRS, D, RA } },
+
+{ "std",     DSO(62,0),	DS_MASK,	PPC|B64,	{ RS, DS, RA } },
+
+{ "stdu",    DSO(62,1),	DS_MASK,	PPC|B64,	{ RS, DS, RAS } },
+
+{ "fcmpu",   X(63,0),	X_MASK|(3<<21),	PPC|POWER,	{ BF, FRA, FRB } },
+
+{ "frsp",    XRC(63,12,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "frsp.",   XRC(63,12,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "fctiw",   XRC(63,14,0), XRA_MASK,	PPC,		{ FRT, FRB } },
+{ "fcir",    XRC(63,14,0), XRA_MASK,	POWER2,		{ FRT, FRB } },
+{ "fctiw.",  XRC(63,14,1), XRA_MASK,	PPC,		{ FRT, FRB } },
+{ "fcir.",   XRC(63,14,1), XRA_MASK,	POWER2,		{ FRT, FRB } },
+
+{ "fctiwz",  XRC(63,15,0), XRA_MASK,	PPC,		{ FRT, FRB } },
+{ "fcirz",   XRC(63,15,0), XRA_MASK,	POWER2,		{ FRT, FRB } },
+{ "fctiwz.", XRC(63,15,1), XRA_MASK,	PPC,		{ FRT, FRB } },
+{ "fcirz.",  XRC(63,15,1), XRA_MASK,	POWER2,		{ FRT, FRB } },
+
+{ "fdiv",    A(63,18,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fd",      A(63,18,0), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+{ "fdiv.",   A(63,18,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fd.",     A(63,18,1), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+
+{ "fsub",    A(63,20,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fs",      A(63,20,0), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+{ "fsub.",   A(63,20,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fs.",     A(63,20,1), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+
+{ "fadd",    A(63,21,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fa",      A(63,21,0), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+{ "fadd.",   A(63,21,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+{ "fa.",     A(63,21,1), AFRC_MASK,	POWER,		{ FRT, FRA, FRB } },
+
+{ "fsqrt",   A(63,22,0), AFRAFRC_MASK,	PPC|POWER2,	{ FRT, FRB } },
+{ "fsqrt.",  A(63,22,1), AFRAFRC_MASK,	PPC|POWER2,	{ FRT, FRB } },
+
+{ "fsel",    A(63,23,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fsel.",   A(63,23,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+
+{ "fmul",    A(63,25,0), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+{ "fm",      A(63,25,0), AFRB_MASK,	POWER,		{ FRT, FRA, FRC } },
+{ "fmul.",   A(63,25,1), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+{ "fm.",     A(63,25,1), AFRB_MASK,	POWER,		{ FRT, FRA, FRC } },
+
+{ "frsqrte", A(63,26,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+{ "frsqrte.",A(63,26,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+
+{ "fmsub",   A(63,28,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fms",     A(63,28,0), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+{ "fmsub.",  A(63,28,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fms.",    A(63,28,1), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+
+{ "fmadd",   A(63,29,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fma",     A(63,29,0), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+{ "fmadd.",  A(63,29,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fma.",    A(63,29,1), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+
+{ "fnmsub",  A(63,30,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnms",    A(63,30,0), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+{ "fnmsub.", A(63,30,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnms.",   A(63,30,1), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+
+{ "fnmadd",  A(63,31,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnma",    A(63,31,0), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+{ "fnmadd.", A(63,31,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+{ "fnma.",   A(63,31,1), A_MASK,	POWER,		{ FRT,FRA,FRC,FRB } },
+
+{ "fcmpo",   X(63,30),	X_MASK|(3<<21),	PPC|POWER,	{ BF, FRA, FRB } },
+
+{ "mtfsb1",  XRC(63,38,0), XRARB_MASK,	PPC|POWER,	{ BT } },
+{ "mtfsb1.", XRC(63,38,1), XRARB_MASK,	PPC|POWER,	{ BT } },
+
+{ "fneg",    XRC(63,40,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "fneg.",   XRC(63,40,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "mcrfs",   X(63,64),	XRB_MASK|(3<<21)|(3<<16), PPC|POWER, { BF, BFA } },
+
+{ "mtfsb0",  XRC(63,70,0), XRARB_MASK,	PPC|POWER,	{ BT } },
+{ "mtfsb0.", XRC(63,70,1), XRARB_MASK,	PPC|POWER,	{ BT } },
+
+{ "fmr",     XRC(63,72,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "fmr.",    XRC(63,72,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "mtfsfi",  XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), PPC|POWER, { BF, U } },
+{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), PPC|POWER, { BF, U } },
+
+{ "fnabs",   XRC(63,136,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "fnabs.",  XRC(63,136,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "fabs",    XRC(63,264,0), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+{ "fabs.",   XRC(63,264,1), XRA_MASK,	PPC|POWER,	{ FRT, FRB } },
+
+{ "mffs",    XRC(63,583,0), XRARB_MASK,	PPC|POWER,	{ FRT } },
+{ "mffs.",   XRC(63,583,1), XRARB_MASK,	PPC|POWER,	{ FRT } },
+
+{ "mtfsf",   XFL(63,711,0), XFL_MASK,	PPC|POWER,	{ FLM, FRB } },
+{ "mtfsf.",  XFL(63,711,1), XFL_MASK,	PPC|POWER,	{ FLM, FRB } },
+
+{ "fctid",   XRC(63,814,0), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+{ "fctid.",  XRC(63,814,1), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+
+{ "fctidz",  XRC(63,815,0), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+{ "fctidz.", XRC(63,815,1), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+
+{ "fcfid",   XRC(63,846,0), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+{ "fcfid.",  XRC(63,846,1), XRA_MASK,	PPC|B64,	{ FRT, FRB } },
+
+};
+
+const int powerpc_num_opcodes =
+  sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
+
+/* The macro table.  This is only used by the assembler.  */
+
+const struct powerpc_macro powerpc_macros[] = {
+{ "extldi",  4,   PPC|B64,	"rldicr %0,%1,%3,(%2)-1" },
+{ "extldi.", 4,   PPC|B64,	"rldicr. %0,%1,%3,(%2)-1" },
+{ "extrdi",  4,   PPC|B64,	"rldicl %0,%1,(%2)+(%3),64-(%2)" },
+{ "extrdi.", 4,   PPC|B64,	"rldicl. %0,%1,(%2)+(%3),64-(%2)" },
+{ "insrdi",  4,   PPC|B64,	"rldimi %0,%1,64-((%2)+(%3)),%3" },
+{ "insrdi.", 4,   PPC|B64,	"rldimi. %0,%1,64-((%2)+(%3)),%3" },
+{ "rotrdi",  3,   PPC|B64,	"rldicl %0,%1,64-(%2),0" },
+{ "rotrdi.", 3,   PPC|B64,	"rldicl. %0,%1,64-(%2),0" },
+{ "sldi",    3,   PPC|B64,	"rldicr %0,%1,%2,63-(%2)" },
+{ "sldi.",   3,   PPC|B64,	"rldicr. %0,%1,%2,63-(%2)" },
+{ "srdi",    3,   PPC|B64,	"rldicl %0,%1,64-(%2),%2" },
+{ "srdi.",   3,   PPC|B64,	"rldicl. %0,%1,64-(%2),%2" },
+{ "clrrdi",  3,   PPC|B64,	"rldicr %0,%1,0,63-(%2)" },
+{ "clrrdi.", 3,   PPC|B64,	"rldicr. %0,%1,0,63-(%2)" },
+{ "clrlsldi",4,   PPC|B64,	"rldic %0,%1,%3,(%2)-(%3)" },
+{ "clrlsldi.",4,  PPC|B64,	"rldic. %0,%1,%3,(%2)-(%3)" },
+
+{ "extlwi",  4,   PPC,		"rlwinm %0,%1,%3,0,(%2)-1" },
+{ "extlwi.", 4,   PPC,		"rlwinm. %0,%1,%3,0,(%2)-1" },
+{ "extrwi",  4,   PPC,		"rlwinm %0,%1,(%2)+(%3),32-(%2),31" },
+{ "extrwi.", 4,   PPC,		"rlwinm. %0,%1,(%2)+(%3),32-(%2),31" },
+{ "inslwi",  4,   PPC,		"rlwimi %0,%1,32-(%3),%3,(%2)+(%3)-1" },
+{ "inslwi.", 4,   PPC,		"rlwimi. %0,%1,32-(%3),%3,(%2)+(%3)-1" },
+{ "insrwi",  4,   PPC,		"rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },
+{ "insrwi.", 4,   PPC,		"rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"},
+{ "rotrwi",  3,   PPC,		"rlwinm %0,%1,32-(%2),0,31" },
+{ "rotrwi.", 3,   PPC,		"rlwinm. %0,%1,32-(%2),0,31" },
+{ "slwi",    3,   PPC,		"rlwinm %0,%1,%2,0,31-(%2)" },
+{ "sli",     3,   POWER,	"rlinm %0,%1,%2,0,31-(%2)" },
+{ "slwi.",   3,   PPC,		"rlwinm. %0,%1,%2,0,31-(%2)" },
+{ "sli.",    3,   POWER,	"rlinm. %0,%1,%2,0,31-(%2)" },
+{ "srwi",    3,   PPC,		"rlwinm %0,%1,32-(%2),%2,31" },
+{ "sri",     3,   POWER,	"rlinm %0,%1,32-(%2),%2,31" },
+{ "srwi.",   3,   PPC,		"rlwinm. %0,%1,32-(%2),%2,31" },
+{ "sri.",    3,   POWER,	"rlinm. %0,%1,32-(%2),%2,31" },
+{ "clrrwi",  3,   PPC,		"rlwinm %0,%1,0,0,31-(%2)" },
+{ "clrrwi.", 3,   PPC,		"rlwinm. %0,%1,0,0,31-(%2)" },
+{ "clrlslwi",4,   PPC,		"rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" },
+{ "clrlslwi.",4,  PPC,		"rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
+
+};
+
+const int powerpc_num_macros =
+  sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/ppc.h linux/arch/ppc64/xmon/ppc.h
--- linux.orig/arch/ppc64/xmon/ppc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/ppc.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,240 @@
+/* ppc.h -- Header file for PowerPC opcode table
+   Copyright 1994 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef PPC_H
+#define PPC_H
+
+/* The opcode table is an array of struct powerpc_opcode.  */
+
+struct powerpc_opcode
+{
+  /* The opcode name.  */
+  const char *name;
+
+  /* The opcode itself.  Those bits which will be filled in with
+     operands are zeroes.  */
+  unsigned long opcode;
+
+  /* The opcode mask.  This is used by the disassembler.  This is a
+     mask containing ones indicating those bits which must match the
+     opcode field, and zeroes indicating those bits which need not
+     match (and are presumably filled in by operands).  */
+  unsigned long mask;
+
+  /* One bit flags for the opcode.  These are used to indicate which
+     specific processors support the instructions.  The defined values
+     are listed below.  */
+  unsigned long flags;
+
+  /* An array of operand codes.  Each code is an index into the
+     operand table.  They appear in the order which the operands must
+     appear in assembly code, and are terminated by a zero.  */
+  unsigned char operands[8];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise
+   in the order in which the disassembler should consider
+   instructions.  */
+extern const struct powerpc_opcode powerpc_opcodes[];
+extern const int powerpc_num_opcodes;
+
+/* Values defined for the flags field of a struct powerpc_opcode.  */
+
+/* Opcode is defined for the PowerPC architecture.  */
+#define PPC_OPCODE_PPC (01)
+
+/* Opcode is defined for the POWER (RS/6000) architecture.  */
+#define PPC_OPCODE_POWER (02)
+
+/* Opcode is defined for the POWER2 (Rios 2) architecture.  */
+#define PPC_OPCODE_POWER2 (04)
+
+/* Opcode is only defined on 32 bit architectures.  */
+#define PPC_OPCODE_32 (010)
+
+/* Opcode is only defined on 64 bit architectures.  */
+#define PPC_OPCODE_64 (020)
+
+/* Opcode is supported by the Motorola PowerPC 601 processor.  The 601
+   is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
+   but it also supports many additional POWER instructions.  */
+#define PPC_OPCODE_601 (040)
+
+/* A macro to extract the major opcode from an instruction.  */
+#define PPC_OP(i) (((i) >> 26) & 0x3f)
+
+/* The operands table is an array of struct powerpc_operand.  */
+
+struct powerpc_operand
+{
+  /* The number of bits in the operand.  */
+  int bits;
+
+  /* How far the operand is left shifted in the instruction.  */
+  int shift;
+
+  /* Insertion function.  This is used by the assembler.  To insert an
+     operand value into an instruction, check this field.
+
+     If it is NULL, execute
+         i |= (op & ((1 << o->bits) - 1)) << o->shift;
+     (i is the instruction which we are filling in, o is a pointer to
+     this structure, and op is the opcode value; this assumes twos
+     complement arithmetic).
+
+     If this field is not NULL, then simply call it with the
+     instruction and the operand value.  It will return the new value
+     of the instruction.  If the ERRMSG argument is not NULL, then if
+     the operand value is illegal, *ERRMSG will be set to a warning
+     string (the operand will be inserted in any case).  If the
+     operand value is legal, *ERRMSG will be unchanged (most operands
+     can accept any value).  */
+  unsigned long (*insert) PARAMS ((unsigned long instruction, long op,
+				   const char **errmsg));
+
+  /* Extraction function.  This is used by the disassembler.  To
+     extract this operand type from an instruction, check this field.
+
+     If it is NULL, compute
+         op = ((i) >> o->shift) & ((1 << o->bits) - 1);
+	 if ((o->flags & PPC_OPERAND_SIGNED) != 0
+	     && (op & (1 << (o->bits - 1))) != 0)
+	   op -= 1 << o->bits;
+     (i is the instruction, o is a pointer to this structure, and op
+     is the result; this assumes twos complement arithmetic).
+
+     If this field is not NULL, then simply call it with the
+     instruction value.  It will return the value of the operand.  If
+     the INVALID argument is not NULL, *INVALID will be set to
+     non-zero if this operand type can not actually be extracted from
+     this operand (i.e., the instruction does not match).  If the
+     operand is valid, *INVALID will not be changed.  */
+  long (*extract) PARAMS ((unsigned long instruction, int *invalid));
+
+  /* One bit syntax flags.  */
+  unsigned long flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+   the operands field of the powerpc_opcodes table.  */
+
+extern const struct powerpc_operand powerpc_operands[];
+
+/* Values defined for the flags field of a struct powerpc_operand.  */
+
+/* This operand takes signed values.  */
+#define PPC_OPERAND_SIGNED (01)
+
+/* This operand takes signed values, but also accepts a full positive
+   range of values when running in 32 bit mode.  That is, if bits is
+   16, it takes any value from -0x8000 to 0xffff.  In 64 bit mode,
+   this flag is ignored.  */
+#define PPC_OPERAND_SIGNOPT (02)
+
+/* This operand does not actually exist in the assembler input.  This
+   is used to support extended mnemonics such as mr, for which two
+   operands fields are identical.  The assembler should call the
+   insert function with any op value.  The disassembler should call
+   the extract function, ignore the return value, and check the value
+   placed in the valid argument.  */
+#define PPC_OPERAND_FAKE (04)
+
+/* The next operand should be wrapped in parentheses rather than
+   separated from this one by a comma.  This is used for the load and
+   store instructions which want their operands to look like
+       reg,displacement(reg)
+   */
+#define PPC_OPERAND_PARENS (010)
+
+/* This operand may use the symbolic names for the CR fields, which
+   are
+       lt  0	gt  1	eq  2	so  3	un  3
+       cr0 0	cr1 1	cr2 2	cr3 3
+       cr4 4	cr5 5	cr6 6	cr7 7
+   These may be combined arithmetically, as in cr2*4+gt.  These are
+   only supported on the PowerPC, not the POWER.  */
+#define PPC_OPERAND_CR (020)
+
+/* This operand names a register.  The disassembler uses this to print
+   register names with a leading 'r'.  */
+#define PPC_OPERAND_GPR (040)
+
+/* This operand names a floating point register.  The disassembler
+   prints these with a leading 'f'.  */
+#define PPC_OPERAND_FPR (0100)
+
+/* This operand is a relative branch displacement.  The disassembler
+   prints these symbolically if possible.  */
+#define PPC_OPERAND_RELATIVE (0200)
+
+/* This operand is an absolute branch address.  The disassembler
+   prints these symbolically if possible.  */
+#define PPC_OPERAND_ABSOLUTE (0400)
+
+/* This operand is optional, and is zero if omitted.  This is used for
+   the optional BF and L fields in the comparison instructions.  The
+   assembler must count the number of operands remaining on the line,
+   and the number of operands remaining for the opcode, and decide
+   whether this operand is present or not.  The disassembler should
+   print this operand out only if it is not zero.  */
+#define PPC_OPERAND_OPTIONAL (01000)
+
+/* This flag is only used with PPC_OPERAND_OPTIONAL.  If this operand
+   is omitted, then for the next operand use this operand value plus
+   1, ignoring the next operand field for the opcode.  This wretched
+   hack is needed because the Power rotate instructions can take
+   either 4 or 5 operands.  The disassembler should print this operand
+   out regardless of the PPC_OPERAND_OPTIONAL field.  */
+#define PPC_OPERAND_NEXT (02000)
+
+/* This operand should be regarded as a negative number for the
+   purposes of overflow checking (i.e., the normal most negative
+   number is disallowed and one more than the normal most positive
+   number is allowed).  This flag will only be set for a signed
+   operand.  */
+#define PPC_OPERAND_NEGATIVE (04000)
+
+/* The POWER and PowerPC assemblers use a few macros.  We keep them
+   with the operands table for simplicity.  The macro table is an
+   array of struct powerpc_macro.  */
+
+struct powerpc_macro
+{
+  /* The macro name.  */
+  const char *name;
+
+  /* The number of operands the macro takes.  */
+  unsigned int operands;
+
+  /* One bit flags for the opcode.  These are used to indicate which
+     specific processors support the instructions.  The values are the
+     same as those for the struct powerpc_opcode flags field.  */
+  unsigned long flags;
+
+  /* A format string to turn the macro into a normal instruction.
+     Each %N in the string is replaced with operand number N (zero
+     based).  */
+  const char *format;
+};
+
+extern const struct powerpc_macro powerpc_macros[];
+extern const int powerpc_num_macros;
+
+#endif /* PPC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/privinst.h linux/arch/ppc64/xmon/privinst.h
--- linux.orig/arch/ppc64/xmon/privinst.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/privinst.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+
+#define GETREG(reg)		\
+    static inline unsigned long get_ ## reg (void)	\
+	{ unsigned long ret; asm volatile ("mf" #reg " %0" : "=r" (ret) :); return ret; }
+
+#define SETREG(reg)		\
+    static inline void set_ ## reg (unsigned long val)	\
+	{ asm volatile ("mt" #reg " %0" : : "r" (val)); }
+
+GETREG(msr)
+SETREG(msrd)
+GETREG(cr)
+
+#define GSETSPR(n, name)	\
+    static inline long get_ ## name (void) \
+	{ long ret; asm volatile ("mfspr %0," #n : "=r" (ret) : ); return ret; } \
+    static inline void set_ ## name (long val) \
+	{ asm volatile ("mtspr " #n ",%0" : : "r" (val)); }
+
+GSETSPR(0, mq)
+GSETSPR(1, xer)
+GSETSPR(4, rtcu)
+GSETSPR(5, rtcl)
+GSETSPR(8, lr)
+GSETSPR(9, ctr)
+GSETSPR(18, dsisr)
+GSETSPR(19, dar)
+GSETSPR(22, dec)
+GSETSPR(25, sdr1)
+GSETSPR(26, srr0)
+GSETSPR(27, srr1)
+GSETSPR(272, sprg0)
+GSETSPR(273, sprg1)
+GSETSPR(274, sprg2)
+GSETSPR(275, sprg3)
+GSETSPR(282, ear)
+GSETSPR(287, pvr)
+GSETSPR(528, bat0u)
+GSETSPR(529, bat0l)
+GSETSPR(530, bat1u)
+GSETSPR(531, bat1l)
+GSETSPR(532, bat2u)
+GSETSPR(533, bat2l)
+GSETSPR(534, bat3u)
+GSETSPR(535, bat3l)
+GSETSPR(1008, hid0)
+GSETSPR(1009, hid1)
+GSETSPR(1010, iabr)
+GSETSPR(1013, dabr)
+GSETSPR(1023, pir)
+
+static inline int get_sr(int n)
+{
+	int ret;
+
+#if 0
+	// DRENG does not assemble 
+	asm (" mfsrin %0,%1" : "=r" (ret) : "r" (n << 28));
+#endif
+	return ret;
+}
+
+static inline void set_sr(int n, int val)
+{
+#if 0
+	// DRENG does not assemble 
+	asm ("mtsrin %0,%1" : : "r" (val), "r" (n << 28));
+#endif
+}
+
+static inline void store_inst(void *p)
+{
+	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
+}
+
+static inline void cflush(void *p)
+{
+	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/setjmp.c linux/arch/ppc64/xmon/setjmp.c
--- linux.orig/arch/ppc64/xmon/setjmp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/setjmp.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *      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.
+ *
+ * NB this file must be compiled with -O2.
+ */
+
+int
+xmon_setjmp(long *buf)  /* NOTE: assert(sizeof(buf) > 184) */
+{
+	/* XXX should save fp regs as well */
+	asm volatile (
+	"mflr 0; std 0,0(%0)\n\
+	 std	1,8(%0)\n\
+	 std	2,16(%0)\n\
+	 mfcr 0; std 0,24(%0)\n\
+	 std	13,32(%0)\n\
+	 std	14,40(%0)\n\
+	 std	15,48(%0)\n\
+	 std	16,56(%0)\n\
+	 std	17,64(%0)\n\
+	 std	18,72(%0)\n\
+	 std	19,80(%0)\n\
+	 std	20,88(%0)\n\
+	 std	21,96(%0)\n\
+	 std	22,104(%0)\n\
+	 std	23,112(%0)\n\
+	 std	24,120(%0)\n\
+	 std	25,128(%0)\n\
+	 std	26,136(%0)\n\
+	 std	27,144(%0)\n\
+	 std	28,152(%0)\n\
+	 std	29,160(%0)\n\
+	 std	30,168(%0)\n\
+	 std	31,176(%0)\n\
+	 " : : "r" (buf));
+    return 0;
+}
+
+void
+xmon_longjmp(long *buf, int val)
+{
+	if (val == 0)
+		val = 1;
+	asm volatile (
+	"ld	13,32(%0)\n\
+	 ld	14,40(%0)\n\
+	 ld	15,48(%0)\n\
+	 ld	16,56(%0)\n\
+	 ld	17,64(%0)\n\
+	 ld	18,72(%0)\n\
+	 ld	19,80(%0)\n\
+	 ld	20,88(%0)\n\
+	 ld	21,96(%0)\n\
+	 ld	22,104(%0)\n\
+	 ld	23,112(%0)\n\
+	 ld	24,120(%0)\n\
+	 ld	25,128(%0)\n\
+	 ld	26,136(%0)\n\
+	 ld	27,144(%0)\n\
+	 ld	28,152(%0)\n\
+	 ld	29,160(%0)\n\
+	 ld	30,168(%0)\n\
+	 ld	31,176(%0)\n\
+	 ld	0,24(%0)\n\
+	 mtcrf	0x38,0\n\
+	 ld	0,0(%0)\n\
+	 ld	1,8(%0)\n\
+	 ld	2,16(%0)\n\
+	 mtlr	0\n\
+	 mr	3,%1\n\
+	 " : : "r" (buf), "r" (val));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/start.c linux/arch/ppc64/xmon/start.c
--- linux.orig/arch/ppc64/xmon/start.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/start.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sysrq.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/processor.h>
+
+/* Transition to udbg isn't quite done yet...but very close. */
+#define USE_UDBG
+#ifdef USE_UDBG
+#include <asm/udbg.h>
+#endif
+
+#ifndef USE_UDBG
+static volatile unsigned char *sccc, *sccd;
+#endif
+unsigned long TXRDY, RXRDY;
+extern void xmon_printf(const char *fmt, ...);
+static int xmon_expect(const char *str, unsigned int timeout);
+
+#ifndef USE_UDBG
+static int console = 0;
+#endif
+static int via_modem = 0;
+/* static int xmon_use_sccb = 0;  --Unused */
+
+#define TB_SPEED	25000000
+
+extern void *comport1;
+static inline unsigned int readtb(void)
+{
+	unsigned int ret;
+
+	asm volatile("mftb %0" : "=r" (ret) :);
+	return ret;
+}
+
+#ifndef USE_UDBG
+void buf_access(void)
+{
+	sccd[3] &= ~0x80;	/* reset DLAB */
+}
+#endif
+
+static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, struct kbd_struct *kbd, struct tty_struct *tty) 
+{
+  xmon(pt_regs);
+}
+static struct sysrq_key_op sysrq_xmon_op = 
+{
+	handler:	sysrq_handle_xmon,
+	help_msg:	"xmon",
+	action_msg:	"Entering xmon\n",
+};
+
+void
+xmon_map_scc(void)
+{
+	/* This maybe isn't the best place to register sysrq 'x' */
+	__sysrq_put_key_op('x', &sysrq_xmon_op);
+#ifndef USE_UDBG
+	/* should already be mapped by the kernel boot */
+	sccd = (volatile unsigned char *) (((unsigned long)comport1));
+	sccc = (volatile unsigned char *) (((unsigned long)comport1)+5);
+	TXRDY = 0x20;
+	RXRDY = 1;
+#endif
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+extern void pmu_poll(void);
+
+int
+xmon_write(void *handle, void *ptr, int nb)
+{
+#ifdef USE_UDBG
+	return udbg_write(ptr, nb);
+#else
+	char *p = ptr;
+	int i, c, ct;
+
+	if (!scc_initialized)
+		xmon_init_scc();
+	ct = 0;
+	for (i = 0; i < nb; ++i) {
+		while ((*sccc & TXRDY) == 0) {
+		}
+		c = p[i];
+		if (c == '\n' && !ct) {
+			c = '\r';
+			ct = 1;
+			--i;
+		} else {
+			if (console)
+				printk("%c", c);
+			ct = 0;
+		}
+		buf_access();
+		*sccd = c;
+	}
+	return i;
+#endif
+}
+
+int xmon_wants_key;
+
+int
+xmon_read(void *handle, void *ptr, int nb)
+{
+#ifdef USE_UDBG
+	return udbg_read(ptr, nb);
+#else
+	char *p = ptr;
+	int i, c;
+
+	if (!scc_initialized)
+		xmon_init_scc();
+	for (i = 0; i < nb; ++i) {
+		do {
+			while ((*sccc & RXRDY) == 0)
+				;
+			buf_access();
+			c = *sccd;
+		} while (c == 0x11 || c == 0x13);
+		*p++ = c;
+	}
+	return i;
+#endif
+}
+
+int
+xmon_read_poll(void)
+{
+#ifdef USE_UDBG
+	return udbg_getc_poll();
+#else
+	if ((*sccc & RXRDY) == 0) {
+		return -1;
+	}
+	buf_access();
+	return *sccd;
+#endif
+}
+ 
+void
+xmon_init_scc()
+{
+#ifndef USE_UDBG
+	sccd[3] = 0x83; eieio();	/* LCR = 8N1 + DLAB */
+	sccd[0] = 12; eieio();		/* DLL = 9600 baud */
+	sccd[1] = 0; eieio();
+	sccd[2] = 0; eieio();		/* FCR = 0 */
+	sccd[3] = 3; eieio();		/* LCR = 8N1 */
+	sccd[1] = 0; eieio();		/* IER = 0 */
+#endif
+
+	scc_initialized = 1;
+	if (via_modem) {
+		for (;;) {
+			xmon_write(0, "ATE1V1\r", 7);
+			if (xmon_expect("OK", 5)) {
+				xmon_write(0, "ATA\r", 4);
+				if (xmon_expect("CONNECT", 40))
+					break;
+			}
+			xmon_write(0, "+++", 3);
+			xmon_expect("OK", 3);
+		}
+	}
+}
+
+void *xmon_stdin;
+void *xmon_stdout;
+void *xmon_stderr;
+
+void
+xmon_init(void)
+{
+}
+
+int
+xmon_putc(int c, void *f)
+{
+	char ch = c;
+
+	if (c == '\n')
+		xmon_putc('\r', f);
+	return xmon_write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+xmon_putchar(int c)
+{
+	return xmon_putc(c, xmon_stdout);
+}
+
+int
+xmon_fputs(char *str, void *f)
+{
+	int n = strlen(str);
+
+	return xmon_write(f, str, n) == n? 0: -1;
+}
+
+int
+xmon_readchar(void)
+{
+	char ch;
+
+	for (;;) {
+		switch (xmon_read(xmon_stdin, &ch, 1)) {
+		case 1:
+			return ch;
+		case -1:
+			xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+			return -1;
+		}
+	}
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int xmon_expect(const char *str, unsigned int timeout)
+{
+	int c;
+	unsigned int t0;
+
+	timeout *= TB_SPEED;
+	t0 = readtb();
+	do {
+		lineptr = line;
+		for (;;) {
+			c = xmon_read_poll();
+			if (c == -1) {
+				if (readtb() - t0 > timeout)
+					return 0;
+				continue;
+			}
+			if (c == '\n')
+				break;
+			if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+				*lineptr++ = c;
+		}
+		*lineptr = 0;
+	} while (strstr(line, str) == NULL);
+	return 1;
+}
+
+int
+xmon_getchar(void)
+{
+	int c;
+
+	if (lineleft == 0) {
+		lineptr = line;
+		for (;;) {
+			c = xmon_readchar();
+			if (c == -1 || c == 4)
+				break;
+			if (c == '\r' || c == '\n') {
+				*lineptr++ = '\n';
+				xmon_putchar('\n');
+				break;
+			}
+			switch (c) {
+			case 0177:
+			case '\b':
+				if (lineptr > line) {
+					xmon_putchar('\b');
+					xmon_putchar(' ');
+					xmon_putchar('\b');
+					--lineptr;
+				}
+				break;
+			case 'U' & 0x1F:
+				while (lineptr > line) {
+					xmon_putchar('\b');
+					xmon_putchar(' ');
+					xmon_putchar('\b');
+					--lineptr;
+				}
+				break;
+			default:
+				if (lineptr >= &line[sizeof(line) - 1])
+					xmon_putchar('\a');
+				else {
+					xmon_putchar(c);
+					*lineptr++ = c;
+				}
+			}
+		}
+		lineleft = lineptr - line;
+		lineptr = line;
+	}
+	if (lineleft == 0)
+		return -1;
+	--lineleft;
+	return *lineptr++;
+}
+
+char *
+xmon_fgets(char *str, int nb, void *f)
+{
+	char *p;
+	int c;
+
+	for (p = str; p < str + nb - 1; ) {
+		c = xmon_getchar();
+		if (c == -1) {
+			if (p == str)
+				return 0;
+			break;
+		}
+		*p++ = c;
+		if (c == '\n')
+			break;
+	}
+	*p = 0;
+	return str;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/subr_prf.c linux/arch/ppc64/xmon/subr_prf.c
--- linux.orig/arch/ppc64/xmon/subr_prf.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/subr_prf.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,55 @@
+/*
+ * Written by Cort Dougan to replace the version originally used
+ * by Paul Mackerras, which came from NetBSD and thus had copyright
+ * conflicts with Linux.
+ *
+ * This file makes liberal use of the standard linux utility
+ * routines to reduce the size of the binary.  We assume we can
+ * trust some parts of Linux inside the debugger.
+ *   -- Cort (cort@cs.nmt.edu)
+ *
+ * Copyright (C) 1999 Cort Dougan.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <stdarg.h>
+#include "nonstdio.h"
+
+extern int xmon_write(void *, void *, int);
+
+void
+xmon_vfprintf(void *f, const char *fmt, va_list ap)
+{
+	static char xmon_buf[2048];
+	int n;
+
+	n = vsprintf(xmon_buf, fmt, ap);
+	xmon_write(f, xmon_buf, n);
+}
+
+void
+xmon_printf(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	xmon_vfprintf(stdout, fmt, ap);
+	va_end(ap);
+}
+
+void
+xmon_fprintf(void *f, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	xmon_vfprintf(f, fmt, ap);
+	va_end(ap);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ppc64/xmon/xmon.c linux/arch/ppc64/xmon/xmon.c
--- linux.orig/arch/ppc64/xmon/xmon.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/ppc64/xmon/xmon.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,2840 @@
+/*
+ * Routines providing a simple monitor for use on the PowerMac.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/reboot.h>
+#include <asm/ptrace.h>
+#include <asm/string.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
+#include <asm/ppcdebug.h>
+#include "nonstdio.h"
+#include "privinst.h"
+
+#define scanhex	xmon_scanhex
+#define skipbl	xmon_skipbl
+
+#ifdef CONFIG_SMP
+static unsigned long cpus_in_xmon = 0;
+static unsigned long got_xmon = 0;
+static volatile int take_xmon = -1;
+#endif /* CONFIG_SMP */
+
+static unsigned long adrs;
+static int size = 1;
+static unsigned long ndump = 64;
+static unsigned long nidump = 16;
+static unsigned long ncsum = 4096;
+static int termch;
+
+static u_int bus_error_jmp[100];
+#define setjmp xmon_setjmp
+#define longjmp xmon_longjmp
+
+#define memlist_entry list_entry
+#define memlist_next(x) ((x)->next)
+#define memlist_prev(x) ((x)->prev)
+
+
+/* Max number of stack frames we are willing to produce on a backtrace. */
+#define MAXFRAMECOUNT 50
+
+/* Breakpoint stuff */
+struct bpt {
+	unsigned long address;
+	unsigned instr;
+	unsigned long count;
+	unsigned char enabled;
+	char funcname[64];	/* function name for humans */
+};
+
+#define NBPTS	16
+static struct bpt bpts[NBPTS];
+static struct bpt dabr;
+static struct bpt iabr;
+static unsigned bpinstr = 0x7fe00008;	/* trap */
+
+/* Prototypes */
+extern void (*debugger_fault_handler)(struct pt_regs *);
+static int cmds(struct pt_regs *);
+static int mread(unsigned long, void *, int);
+static int mwrite(unsigned long, void *, int);
+static void handle_fault(struct pt_regs *);
+static void byterev(unsigned char *, int);
+static void memex(void);
+static int bsesc(void);
+static void dump(void);
+static void prdump(unsigned long, long);
+#ifdef __MWERKS__
+static void prndump(unsigned, int);
+static int nvreadb(unsigned);
+#endif
+static int ppc_inst_dump(unsigned long, long);
+void print_address(unsigned long);
+static int getsp(void);
+static void dump_hash_table(void);
+static void backtrace(struct pt_regs *);
+static void excprint(struct pt_regs *);
+static void prregs(struct pt_regs *);
+static void memops(int);
+static void memlocate(void);
+static void memzcan(void);
+static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
+int skipbl(void);
+int scanhex(unsigned long *valp);
+static void scannl(void);
+static int hexdigit(int);
+void getstring(char *, int);
+static void flush_input(void);
+static int inchar(void);
+static void take_input(char *);
+/* static void openforth(void); */
+static unsigned long read_spr(int);
+static void write_spr(int, unsigned long);
+static void super_regs(void);
+static void print_sysmap(void);
+static void remove_bpts(void);
+static void insert_bpts(void);
+static struct bpt *at_breakpoint(unsigned long pc);
+static void bpt_cmds(void);
+static void cacheflush(void);
+#ifdef CONFIG_SMP
+static void cpu_cmd(void);
+#endif /* CONFIG_SMP */
+static void csum(void);
+static void mem_translate(void);
+static void mem_check(void);
+static void mem_find_real(void);
+static void mem_find_vsid(void);
+static void mem_check_full_group(void);
+static void mem_check_pagetable_vsids (void);
+
+static void mem_map_check_slab(void);
+static void mem_map_lock_pages(void);
+static void mem_map_check_hash(void);
+static void mem_check_dup_rpn (void);
+static void debug_trace(void);
+
+extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned long);
+extern void printf(const char *fmt, ...);
+extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
+extern int xmon_putc(int c, void *f);
+extern int putchar(int ch);
+extern int xmon_read_poll(void);
+extern int setjmp(u_int *);
+extern void longjmp(u_int *, int);
+extern unsigned long _ASR;
+
+pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va);	/* from htab.c */
+
+#define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
+
+static char *help_string = "\
+Commands:\n\
+  b	show breakpoints\n\
+  bd	set data breakpoint\n\
+  bi	set instruction breakpoint\n\
+  bc	clear breakpoint\n\
+  d	dump bytes\n\
+  di	dump instructions\n\
+  df	dump float values\n\
+  dd	dump double values\n\
+  e	print exception information\n\
+  f	flush cache\n\
+  h	dump hash table\n\
+  m	examine/change memory\n\
+  mm	move a block of memory\n\
+  ms	set a block of memory\n\
+  md	compare two blocks of memory\n\
+  ml	locate a block of memory\n\
+  mz	zero a block of memory\n\
+  mx	translation information for an effective address\n\
+  mi	show information about memory allocation\n\
+  M	print System.map\n\
+  p 	show the task list\n\
+  r	print registers\n\
+  s	single step\n\
+  S	print special registers\n\
+  t	print backtrace\n\
+  T	Enable/Disable PPCDBG flags\n\
+  x	exit monitor\n\
+  z	reboot\n\
+  Z	halt\n\
+";
+
+static int xmon_trace[NR_CPUS];
+#define SSTEP	1		/* stepping because of 's' command */
+#define BRSTEP	2		/* stepping over breakpoint */
+
+/*
+ * Stuff for reading and writing memory safely
+ */
+extern inline void sync(void)
+{
+	asm volatile("sync; isync");
+}
+
+extern inline void __delay(unsigned int loops)
+{
+	if (loops != 0)
+		__asm__ __volatile__("mtctr %0; 1: bdnz 1b" : :
+				     "r" (loops) : "ctr");
+}
+
+/* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
+ A PPC stack frame looks like this:
+
+ High Address
+    Back Chain
+    FP reg save area
+    GP reg save area
+    Local var space
+    Parameter save area		(SP+48)
+    TOC save area		(SP+40)
+    link editor doubleword	(SP+32)
+    compiler doubleword		(SP+24)
+    LR save			(SP+16)
+    CR save			(SP+8)
+    Back Chain			(SP+0)
+
+ Note that the LR (ret addr) may not be saved in the current frame if
+ no functions have been called from the current function.
+ */
+
+/*
+ A traceback table typically follows each function.
+ The find_tb_table() func will fill in this struct.  Note that the struct
+ is not an exact match with the encoded table defined by the ABI.  It is
+ defined here more for programming convenience.
+ */
+struct tbtable {
+	unsigned long	flags;		/* flags: */
+#define TBTAB_FLAGSGLOBALLINK	(1L<<47)
+#define TBTAB_FLAGSISEPROL	(1L<<46)
+#define TBTAB_FLAGSHASTBOFF	(1L<<45)
+#define TBTAB_FLAGSINTPROC	(1L<<44)
+#define TBTAB_FLAGSHASCTL	(1L<<43)
+#define TBTAB_FLAGSTOCLESS	(1L<<42)
+#define TBTAB_FLAGSFPPRESENT	(1L<<41)
+#define TBTAB_FLAGSNAMEPRESENT	(1L<<38)
+#define TBTAB_FLAGSUSESALLOCA	(1L<<37)
+#define TBTAB_FLAGSSAVESCR	(1L<<33)
+#define TBTAB_FLAGSSAVESLR	(1L<<32)
+#define TBTAB_FLAGSSTORESBC	(1L<<31)
+#define TBTAB_FLAGSFIXUP	(1L<<30)
+#define TBTAB_FLAGSPARMSONSTK	(1L<<0)
+	unsigned char	fp_saved;	/* num fp regs saved f(32-n)..f31 */
+	unsigned char	gpr_saved;	/* num gpr's saved */
+	unsigned char	fixedparms;	/* num fixed point parms */
+	unsigned char	floatparms;	/* num float parms */
+	unsigned char	parminfo[32];	/* types of args.  null terminated */
+#define TBTAB_PARMFIXED 1
+#define TBTAB_PARMSFLOAT 2
+#define TBTAB_PARMDFLOAT 3
+	unsigned int	tb_offset;	/* offset from start of func */
+	unsigned long	funcstart;	/* addr of start of function */
+	char		name[64];	/* name of function (null terminated)*/
+};
+static int find_tb_table(unsigned long codeaddr, struct tbtable *tab);
+
+void
+xmon(struct pt_regs *excp)
+{
+	struct pt_regs regs;
+	int cmd;
+	unsigned long msr;
+
+	if (excp == NULL) {
+		/* Ok, grab regs as they are now.
+		 This won't do a particularily good job because the
+		 prologue has already been executed.
+		 ToDo: We could reach back into the callers save
+		 area to do a better job of representing the
+		 caller's state.
+		 */
+		asm volatile ("std	0,0(%0)\n\
+			std	1,8(%0)\n\
+			std	2,16(%0)\n\
+			std	3,24(%0)\n\
+			std	4,32(%0)\n\
+			std	5,40(%0)\n\
+			std	6,48(%0)\n\
+			std	7,56(%0)\n\
+			std	8,64(%0)\n\
+			std	9,72(%0)\n\
+			std	10,80(%0)\n\
+			std	11,88(%0)\n\
+			std	12,96(%0)\n\
+			std	13,104(%0)\n\
+			std	14,112(%0)\n\
+			std	15,120(%0)\n\
+			std	16,128(%0)\n\
+			std	17,136(%0)\n\
+			std	18,144(%0)\n\
+			std	19,152(%0)\n\
+			std	20,160(%0)\n\
+			std	21,168(%0)\n\
+			std	22,176(%0)\n\
+			std	23,184(%0)\n\
+			std	24,192(%0)\n\
+			std	25,200(%0)\n\
+			std	26,208(%0)\n\
+			std	27,216(%0)\n\
+			std	28,224(%0)\n\
+			std	29,232(%0)\n\
+			std	30,240(%0)\n\
+			std	31,248(%0)" : : "b" (&regs));
+		printf("xmon called\n");
+		/* Fetch the link reg for this stack frame.
+		 NOTE: the prev printf fills in the lr. */
+		regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
+		regs.msr = get_msr();
+		regs.ctr = get_ctr();
+		regs.xer = get_xer();
+		regs.ccr = get_cr();
+		regs.trap = 0;
+		excp = &regs;
+	}
+
+	msr = get_msr();
+	set_msrd(msr & ~MSR_EE);	/* disable interrupts */
+	excprint(excp);
+#ifdef CONFIG_SMP
+	if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon))
+		for (;;)
+			;
+	while (test_and_set_bit(0, &got_xmon)) {
+		if (take_xmon == smp_processor_id()) {
+			take_xmon = -1;
+			break;
+		}
+	}
+	/*
+	 * XXX: breakpoints are removed while any cpu is in xmon
+	 */
+#endif /* CONFIG_SMP */
+	remove_bpts();
+	cmd = cmds(excp);
+	if (cmd == 's') {
+		xmon_trace[smp_processor_id()] = SSTEP;
+		excp->msr |= 0x400;
+	} else if (at_breakpoint(excp->nip)) {
+		xmon_trace[smp_processor_id()] = BRSTEP;
+		excp->msr |= 0x400;
+	} else {
+		xmon_trace[smp_processor_id()] = 0;
+		insert_bpts();
+	}
+#ifdef CONFIG_SMP
+	clear_bit(0, &got_xmon);
+	clear_bit(smp_processor_id(), &cpus_in_xmon);
+#endif /* CONFIG_SMP */
+	set_msrd(msr);		/* restore interrupt enable */
+}
+
+/* Code can call this to get a backtrace and continue. */
+void
+xmon_backtrace(const char *fmt, ...)
+{
+	va_list ap;
+	struct pt_regs regs;
+
+
+	/* Ok, grab regs as they are now.
+	 This won't do a particularily good job because the
+	 prologue has already been executed.
+	 ToDo: We could reach back into the callers save
+	 area to do a better job of representing the
+	 caller's state.
+	 */
+	asm volatile ("std	0,0(%0)\n\
+	    std	1,8(%0)\n\
+	    std	2,16(%0)\n\
+	    std	3,24(%0)\n\
+	    std	4,32(%0)\n\
+	    std	5,40(%0)\n\
+	    std	6,48(%0)\n\
+	    std	7,56(%0)\n\
+	    std	8,64(%0)\n\
+	    std	9,72(%0)\n\
+	    std	10,80(%0)\n\
+	    std	11,88(%0)\n\
+	    std	12,96(%0)\n\
+	    std	13,104(%0)\n\
+	    std	14,112(%0)\n\
+	    std	15,120(%0)\n\
+	    std	16,128(%0)\n\
+	    std	17,136(%0)\n\
+	    std	18,144(%0)\n\
+	    std	19,152(%0)\n\
+	    std	20,160(%0)\n\
+	    std	21,168(%0)\n\
+	    std	22,176(%0)\n\
+	    std	23,184(%0)\n\
+	    std	24,192(%0)\n\
+	    std	25,200(%0)\n\
+	    std	26,208(%0)\n\
+	    std	27,216(%0)\n\
+	    std	28,224(%0)\n\
+	    std	29,232(%0)\n\
+	    std	30,240(%0)\n\
+	    std	31,248(%0)" : : "b" (&regs));
+	/* Fetch the link reg for this stack frame.
+	 NOTE: the prev printf fills in the lr. */
+	regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
+	regs.msr = get_msr();
+	regs.ctr = get_ctr();
+	regs.xer = get_xer();
+	regs.ccr = get_cr();
+	regs.trap = 0;
+
+	va_start(ap, fmt);
+	xmon_vfprintf(stdout, fmt, ap);
+	xmon_putc('\n', stdout);
+	va_end(ap);
+	take_input("\n");
+	backtrace(&regs);
+}
+
+/* Call this to poll for ^C during busy operations.
+ * Returns true if the user has hit ^C.
+ */
+int
+xmon_interrupted(void)
+{
+	int ret = xmon_read_poll();
+	if (ret == 3) {
+		printf("\n^C interrupted.\n");
+		return 1;
+	}
+	return 0;
+}
+
+
+void
+xmon_irq(int irq, void *d, struct pt_regs *regs)
+{
+	unsigned long flags;
+	__save_flags(flags);
+	__cli();
+	printf("Keyboard interrupt\n");
+	xmon(regs);
+	__restore_flags(flags);
+}
+
+int
+xmon_bpt(struct pt_regs *regs)
+{
+	struct bpt *bp;
+
+	bp = at_breakpoint(regs->nip);
+	if (!bp)
+		return 0;
+	if (bp->count) {
+		--bp->count;
+		remove_bpts();
+		excprint(regs);
+		xmon_trace[smp_processor_id()] = BRSTEP;
+		regs->msr |= 0x400;
+	} else {
+		printf("Stopped at breakpoint %x (%lx %s)\n", (bp - bpts)+1, bp->address, bp->funcname);
+		xmon(regs);
+	}
+	return 1;
+}
+
+int
+xmon_sstep(struct pt_regs *regs)
+{
+	if (!xmon_trace[smp_processor_id()])
+		return 0;
+	if (xmon_trace[smp_processor_id()] == BRSTEP) {
+		xmon_trace[smp_processor_id()] = 0;
+		insert_bpts();
+	} else {
+		xmon(regs);
+	}
+	return 1;
+}
+
+int
+xmon_dabr_match(struct pt_regs *regs)
+{
+	if (dabr.enabled && dabr.count) {
+		--dabr.count;
+		remove_bpts();
+		excprint(regs);
+		xmon_trace[smp_processor_id()] = BRSTEP;
+		regs->msr |= 0x400;
+	} else {
+		dabr.instr = regs->nip;
+		xmon(regs);
+	}
+	return 1;
+}
+
+int
+xmon_iabr_match(struct pt_regs *regs)
+{
+	if (iabr.enabled && iabr.count) {
+		--iabr.count;
+		remove_bpts();
+		excprint(regs);
+		xmon_trace[smp_processor_id()] = BRSTEP;
+		regs->msr |= 0x400;
+	} else {
+		xmon(regs);
+	}
+	return 1;
+}
+
+static struct bpt *
+at_breakpoint(unsigned long pc)
+{
+	int i;
+	struct bpt *bp;
+
+	if (dabr.enabled && pc == dabr.instr)
+		return &dabr;
+	if (iabr.enabled && pc == iabr.address)
+		return &iabr;
+	bp = bpts;
+	for (i = 0; i < NBPTS; ++i, ++bp)
+		if (bp->enabled && pc == bp->address)
+			return bp;
+	return 0;
+}
+
+static void
+insert_bpts()
+{
+	int i;
+	struct bpt *bp;
+
+	if (naca->platform != PLATFORM_PSERIES)
+		return;
+	bp = bpts;
+	for (i = 0; i < NBPTS; ++i, ++bp) {
+		if (!bp->enabled)
+			continue;
+		if (mread(bp->address, &bp->instr, 4) != 4
+		    || mwrite(bp->address, &bpinstr, 4) != 4) {
+			printf("Couldn't insert breakpoint at %x, disabling\n",
+			       bp->address);
+			bp->enabled = 0;
+		} else {
+			store_inst((void *)bp->address);
+		}
+	}
+
+	if (!__is_processor(PV_POWER4)) {
+		if (dabr.enabled)
+			set_dabr(dabr.address);
+		if (iabr.enabled)
+			set_iabr(iabr.address);
+	}
+}
+
+static void
+remove_bpts()
+{
+	int i;
+	struct bpt *bp;
+	unsigned instr;
+
+	if (naca->platform != PLATFORM_PSERIES)
+		return;
+	if (!__is_processor(PV_POWER4)) {
+		set_dabr(0);
+		set_iabr(0);
+	}
+
+	bp = bpts;
+	for (i = 0; i < NBPTS; ++i, ++bp) {
+		if (!bp->enabled)
+			continue;
+		if (mread(bp->address, &instr, 4) == 4
+		    && instr == bpinstr
+		    && mwrite(bp->address, &bp->instr, 4) != 4)
+			printf("Couldn't remove breakpoint at %x\n",
+			       bp->address);
+		else
+			store_inst((void *)bp->address);
+	}
+}
+
+static char *last_cmd;
+
+/* Command interpreting routine */
+static int
+cmds(struct pt_regs *excp)
+{
+	int cmd;
+
+	last_cmd = NULL;
+	for(;;) {
+#ifdef CONFIG_SMP
+		printf("%d:", smp_processor_id());
+#endif /* CONFIG_SMP */
+		printf("mon> ");
+		fflush(stdout);
+		flush_input();
+		termch = 0;
+		cmd = skipbl();
+		if( cmd == '\n' ) {
+			if (last_cmd == NULL)
+				continue;
+			take_input(last_cmd);
+			last_cmd = NULL;
+			cmd = inchar();
+		}
+		switch (cmd) {
+		case 'z':
+			printf("Rebooting machine now...");
+			machine_restart(NULL);
+			break;
+		case 'Z':
+			printf("Halting machine now...");
+			machine_halt();
+			break;
+		case 'm':
+			cmd = inchar();
+			switch (cmd) {
+			case 'm':
+			case 's':
+			case 'd':
+				memops(cmd);
+				break;
+			case 'l':
+				memlocate();
+				break;
+			case 'z':
+				memzcan();
+				break;
+			case 'x':
+				mem_translate();
+				break;
+			case 'c':
+				mem_check();
+				break;
+			case 'g':
+				mem_check_full_group();
+				break;
+			case 'j':
+				mem_map_check_slab();
+				break;
+			case 'h':
+				mem_map_check_hash();
+				break;
+			case 'f':
+				mem_find_real();
+				break;
+			case 'e':
+				mem_find_vsid();
+				break;
+			case 'r':
+				mem_check_dup_rpn();
+				break;           
+			case 'i':
+				show_mem();
+				break;
+			case 'o':
+				mem_check_pagetable_vsids ();
+				break;
+			case 'q':
+				mem_map_lock_pages() ;
+				break;
+			default:
+				termch = cmd;
+				memex();
+			}
+			break;
+		case 'd':
+			dump();
+			break;
+		case 'r':
+			if (excp != NULL)
+				prregs(excp);	/* print regs */
+			break;
+		case 'e':
+			if (excp == NULL)
+				printf("No exception information\n");
+			else
+				excprint(excp);
+			break;
+		case 'M':
+			print_sysmap();
+			break;
+		case 'S':
+			super_regs();
+			break;
+		case 't':
+			backtrace(excp);
+			break;
+		case 'f':
+			cacheflush();
+			break;
+		case 'h':
+			dump_hash_table();
+			break;
+		case 's':
+		case 'x':
+		case EOF:
+			return cmd;
+		case '?':
+			printf(help_string);
+			break;
+		case 'p':
+			show_state();
+			break;
+		case 'b':
+			bpt_cmds();
+			break;
+		case 'C':
+			csum();
+			break;
+#ifdef CONFIG_SMP
+		case 'c':
+			cpu_cmd();
+			break;
+#endif /* CONFIG_SMP */
+		case 'T':
+			debug_trace();
+			break;
+		default:
+			printf("Unrecognized command: ");
+		        do {
+				if( ' ' < cmd && cmd <= '~' )
+					putchar(cmd);
+				else
+					printf("\\x%x", cmd);
+				cmd = inchar();
+		        } while (cmd != '\n'); 
+			printf(" (type ? for help)\n");
+			break;
+		}
+	}
+}
+
+#ifdef CONFIG_SMP
+static void cpu_cmd(void)
+{
+	unsigned long cpu;
+	int timeout;
+	int cmd;
+
+	cmd = inchar();
+	if (cmd == 'i') {
+		printf("stopping all cpus\n");
+		/* interrupt other cpu(s) */
+		cpu = MSG_ALL_BUT_SELF;
+		smp_send_xmon_break(cpu);
+		return;
+	}
+	termch = cmd;
+	if (!scanhex(&cpu)) {
+		/* print cpus waiting or in xmon */
+		printf("cpus stopped:");
+		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+			if (test_bit(cpu, &cpus_in_xmon)) {
+				printf(" %d", cpu);
+				if (cpu == smp_processor_id())
+					printf("*", cpu);
+			}
+		}
+		printf("\n");
+		return;
+	}
+	/* try to switch to cpu specified */
+	take_xmon = cpu;
+	timeout = 10000000;
+	while (take_xmon >= 0) {
+		if (--timeout == 0) {
+			/* yes there's a race here */
+			take_xmon = -1;
+			printf("cpu %u didn't take control\n", cpu);
+			return;
+		}
+	}
+	/* now have to wait to be given control back */
+	while (test_and_set_bit(0, &got_xmon)) {
+		if (take_xmon == smp_processor_id()) {
+			take_xmon = -1;
+			break;
+		}
+	}
+}
+#endif /* CONFIG_SMP */
+
+static unsigned short fcstab[256] = {
+	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+#define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
+
+static void
+csum(void)
+{
+	unsigned int i;
+	unsigned short fcs;
+	unsigned char v;
+
+	if (!scanhex(&adrs))
+		return;
+	if (!scanhex(&ncsum))
+		return;
+	fcs = 0xffff;
+	for (i = 0; i < ncsum; ++i) {
+		if (mread(adrs+i, &v, 1) == 0) {
+			printf("csum stopped at %x\n", adrs+i);
+			break;
+		}
+		fcs = FCS(fcs, v);
+	}
+	printf("%x\n", fcs);
+}
+
+static char *breakpoint_help_string = 
+    "Breakpoint command usage:\n"
+    "b                show breakpoints\n"
+    "b <addr> [cnt]   set breakpoint at given instr addr\n"
+    "bc               clear all breakpoints\n"
+    "bc <n/addr>      clear breakpoint number n or at addr\n"
+    "bi <addr> [cnt]  set hardware instr breakpoint (broken?)\n"
+    "bd <addr> [cnt]  set hardware data breakpoint (broken?)\n"
+    "";
+
+static void
+bpt_cmds(void)
+{
+	int cmd;
+	unsigned long a;
+	int mode, i;
+	struct bpt *bp;
+	struct tbtable tab;
+
+	cmd = inchar();
+	switch (cmd) {
+	case 'd':	/* bd - hardware data breakpoint */
+		if (__is_processor(PV_POWER4)) {
+			printf("Not implemented on POWER4\n");
+			break;
+		}
+		mode = 7;
+		cmd = inchar();
+		if (cmd == 'r')
+			mode = 5;
+		else if (cmd == 'w')
+			mode = 6;
+		else
+			termch = cmd;
+		dabr.address = 0;
+		dabr.count = 0;
+		dabr.enabled = scanhex(&dabr.address);
+		scanhex(&dabr.count);
+		if (dabr.enabled)
+			dabr.address = (dabr.address & ~7) | mode;
+		break;
+	case 'i':	/* bi - hardware instr breakpoint */
+		if (__is_processor(PV_POWER4)) {
+			printf("Not implemented on POWER4\n");
+			break;
+		}
+		iabr.address = 0;
+		iabr.count = 0;
+		iabr.enabled = scanhex(&iabr.address);
+		if (iabr.enabled)
+			iabr.address |= 3;
+		scanhex(&iabr.count);
+		break;
+	case 'c':
+		if (!scanhex(&a)) {
+			/* clear all breakpoints */
+			for (i = 0; i < NBPTS; ++i)
+				bpts[i].enabled = 0;
+			iabr.enabled = 0;
+			dabr.enabled = 0;
+			printf("All breakpoints cleared\n");
+		} else {
+			if (a <= NBPTS && a >= 1) {
+				/* assume a breakpoint number */
+				--a;	/* bp nums are 1 based */
+				bp = &bpts[a];
+			} else {
+				/* assume a breakpoint address */
+				bp = at_breakpoint(a);
+			}
+			if (bp == 0) {
+				printf("No breakpoint at %x\n", a);
+			} else {
+				printf("Cleared breakpoint %x (%lx %s)\n", (bp - bpts)+1, bp->address, bp->funcname);
+				bp->enabled = 0;
+			}
+		}
+		break;
+	case '?':
+	        printf(breakpoint_help_string);
+	        break;
+	default:
+		termch = cmd;
+	        cmd = skipbl();
+		if (cmd == '?') {
+			printf(breakpoint_help_string);
+			break;
+		}
+		termch = cmd;
+		if (!scanhex(&a)) {
+			/* print all breakpoints */
+			int bpnum;
+
+			printf("   type            address    count\n");
+			if (dabr.enabled) {
+				printf("   data   %.16lx %8x [", dabr.address & ~7,
+				       dabr.count);
+				if (dabr.address & 1)
+					printf("r");
+				if (dabr.address & 2)
+					printf("w");
+				printf("]\n");
+			}
+			if (iabr.enabled)
+				printf("   inst   %.16lx %8x\n", iabr.address & ~3,
+				       iabr.count);
+			for (bp = bpts, bpnum = 1; bp < &bpts[NBPTS]; ++bp, ++bpnum)
+				if (bp->enabled)
+					printf("%2x trap   %.16lx %8x  %s\n", bpnum, bp->address, bp->count, bp->funcname);
+			break;
+		}
+		bp = at_breakpoint(a);
+		if (bp == 0) {
+			for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
+				if (!bp->enabled)
+					break;
+			if (bp >= &bpts[NBPTS]) {
+				printf("Sorry, no free breakpoints.  Please clear one first.\n");
+				break;
+			}
+		}
+		bp->enabled = 1;
+		bp->address = a;
+		bp->count = 0;
+		scanhex(&bp->count);
+		/* Find the function name just once. */
+		bp->funcname[0] = '\0';
+		if (find_tb_table(bp->address, &tab) && tab.name[0]) {
+			/* Got a nice name for it. */
+			int delta = bp->address - tab.funcstart;
+			sprintf(bp->funcname, "%s+0x%x", tab.name, delta);
+		}
+		printf("Set breakpoint %2x trap   %.16lx %8x  %s\n", (bp-bpts)+1, bp->address, bp->count, bp->funcname);
+		break;
+	}
+}
+
+/* Very cheap human name for vector lookup. */
+static
+const char *getvecname(unsigned long vec)
+{
+	char *ret;
+	switch (vec) {
+	case 0x100:	ret = "(System Reset)"; break; 
+	case 0x200:	ret = "(Machine Check)"; break; 
+	case 0x300:	ret = "(Data Access)"; break; 
+	case 0x400:	ret = "(Instruction Access)"; break; 
+	case 0x500:	ret = "(Hardware Interrupt)"; break; 
+	case 0x600:	ret = "(Alignment)"; break; 
+	case 0x700:	ret = "(Program Check)"; break; 
+	case 0x800:	ret = "(FPU Unavailable)"; break; 
+	case 0x900:	ret = "(Decrementer)"; break; 
+	case 0xc00:	ret = "(System Call)"; break; 
+	case 0xd00:	ret = "(Single Step)"; break; 
+	case 0xf00:	ret = "(Performance Monitor)"; break; 
+	default: ret = "";
+	}
+	return ret;
+}
+
+static void
+backtrace(struct pt_regs *excp)
+{
+	unsigned long sp;
+	unsigned long lr;
+	unsigned long stack[3];
+	struct pt_regs regs;
+	struct tbtable tab;
+	int framecount;
+	char *funcname;
+	/* declare these as raw ptrs so we don't get func descriptors */
+	extern void *ret_from_except, *ret_from_syscall_1;
+
+	if (excp != NULL) {
+	        lr = excp->link;
+		sp = excp->gpr[1];
+	} else {
+	        /* Use care not to call any function before this point
+		 so the saved lr has a chance of being good. */
+	        asm volatile ("mflr %0" : "=r" (lr) :);
+		sp = getsp();
+	}
+	scanhex(&sp);
+	scannl();
+	for (framecount = 0;
+	     sp != 0 && framecount < MAXFRAMECOUNT;
+	     sp = stack[0], framecount++) {
+		if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
+			break;
+#if 0
+		if (lr != 0) {
+		    stack[2] = lr;	/* fake out the first saved lr.  It may not be saved yet. */
+		    lr = 0;
+		}
+#endif
+		printf("%.16lx  %.16lx", sp, stack[2]);
+		/* TAI -- for now only the ones cast to unsigned long will match.
+		 * Need to test the rest...
+		 */
+		if ((stack[2] == (unsigned long)ret_from_except &&
+		            (funcname = "ret_from_except"))
+		    || (stack[2] == (unsigned long)ret_from_syscall_1 &&
+		            (funcname = "ret_from_syscall_1"))
+#if 0
+		    || stack[2] == (unsigned) &ret_from_syscall_2
+		    || stack[2] == (unsigned) &do_signal_ret
+#endif
+		    ) {
+			printf("  %s\n", funcname);
+			if (mread(sp+112, &regs, sizeof(regs)) != sizeof(regs))
+				break;
+			printf("exception: %lx %s regs %lx\n", regs.trap, getvecname(regs.trap), sp+112);
+			printf("                  %.16lx", regs.nip);
+			if ((regs.nip & 0xffffffff00000000UL) &&
+			    find_tb_table(regs.nip, &tab)) {
+				int delta = regs.nip-tab.funcstart;
+				if (delta < 0)
+					printf("  <unknown code>");
+				else
+					printf("  %s+0x%x", tab.name, delta);
+			}
+			printf("\n");
+                        if (regs.gpr[1] < sp) {
+                            printf("<Stack drops into 32-bit userspace %.16lx>\n", regs.gpr[1]);
+                            break;
+			}
+
+			sp = regs.gpr[1];
+			if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
+				break;
+		} else {
+			if (stack[2] && find_tb_table(stack[2], &tab)) {
+				int delta = stack[2]-tab.funcstart;
+				if (delta < 0)
+					printf("  <unknown code>");
+				else
+					printf("  %s+0x%x", tab.name, delta);
+			}
+			printf("\n");
+		}
+		if (stack[0] && stack[0] <= sp) {
+			if ((stack[0] & 0xffffffff00000000UL) == 0)
+				printf("<Stack drops into 32-bit userspace %.16lx>\n", stack[0]);
+			else
+				printf("<Corrupt stack.  Next backchain is %.16lx>\n", stack[0]);
+			break;
+		}
+	}
+	if (framecount >= MAXFRAMECOUNT)
+		printf("<Punt. Too many stack frames>\n");
+}
+
+int
+getsp()
+{
+	int x;
+
+	asm("mr %0,1" : "=r" (x) :);
+	return x;
+}
+
+spinlock_t exception_print_lock = SPIN_LOCK_UNLOCKED;
+
+void
+excprint(struct pt_regs *fp)
+{
+	struct task_struct *c;
+	struct tbtable tab;
+	unsigned long flags;
+
+	spin_lock_irqsave(&exception_print_lock, flags);
+
+#ifdef CONFIG_SMP
+	printf("cpu %d: ", smp_processor_id());
+#endif /* CONFIG_SMP */
+
+	printf("Vector: %lx %s at  [%lx]\n", fp->trap, getvecname(fp->trap), fp);
+	printf("    pc: %lx", fp->nip);
+	if (find_tb_table(fp->nip, &tab) && tab.name[0]) {
+		/* Got a nice name for it */
+		int delta = fp->nip - tab.funcstart;
+		printf(" (%s+0x%x)", tab.name, delta);
+	}
+	printf("\n");
+	printf("    lr: %lx", fp->link);
+	if (find_tb_table(fp->link, &tab) && tab.name[0]) {
+		/* Got a nice name for it */
+		int delta = fp->link - tab.funcstart;
+		printf(" (%s+0x%x)", tab.name, delta);
+	}
+	printf("\n");
+	printf("    sp: %lx\n", fp->gpr[1]);
+	printf("   msr: %lx\n", fp->msr);
+
+	if (fp->trap == 0x300 || fp->trap == 0x600) {
+		printf("   dar: %lx\n", fp->dar);
+		printf(" dsisr: %lx\n", fp->dsisr);
+	}
+
+	/* XXX: need to copy current or we die.  Why? */
+	c = current;
+	printf("  current = 0x%lx\n", c);
+	printf("  paca    = 0x%lx\n", get_paca());
+	if (c) {
+		printf("  current = %lx, pid = %ld, comm = %s\n",
+		       c, c->pid, c->comm);
+	}
+
+	spin_unlock_irqrestore(&exception_print_lock, flags);
+}
+
+void
+prregs(struct pt_regs *fp)
+{
+	int n;
+	unsigned long base;
+
+	if (scanhex((void *)&base))
+		fp = (struct pt_regs *) base;
+	for (n = 0; n < 16; ++n)
+		printf("R%.2ld = %.16lx   R%.2ld = %.16lx\n", n, fp->gpr[n],
+		       n+16, fp->gpr[n+16]);
+	printf("pc  = %.16lx   msr = %.16lx\nlr  = %.16lx   cr  = %.16lx\n",
+	       fp->nip, fp->msr, fp->link, fp->ccr);
+	printf("ctr = %.16lx   xer = %.16lx   trap = %8lx\n",
+	       fp->ctr, fp->xer, fp->trap);
+}
+
+void
+cacheflush(void)
+{
+	int cmd;
+	unsigned long nflush;
+
+	cmd = inchar();
+	if (cmd != 'i')
+		termch = cmd;
+	scanhex((void *)&adrs);
+	if (termch != '\n')
+		termch = 0;
+	nflush = 1;
+	scanhex(&nflush);
+	nflush = (nflush + 31) / 32;
+	if (cmd != 'i') {
+		for (; nflush > 0; --nflush, adrs += 0x20)
+			cflush((void *) adrs);
+	} else {
+		for (; nflush > 0; --nflush, adrs += 0x20)
+			cinval((void *) adrs);
+	}
+}
+
+unsigned long
+read_spr(int n)
+{
+	unsigned int instrs[2];
+	unsigned long (*code)(void);
+	unsigned long opd[3];
+
+	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
+	instrs[1] = 0x4e800020;
+	opd[0] = (unsigned long)instrs;
+	opd[1] = 0;
+	opd[2] = 0;
+	store_inst(instrs);
+	store_inst(instrs+1);
+	code = (unsigned long (*)(void)) opd;
+
+	return code();
+}
+
+void
+write_spr(int n, unsigned long val)
+{
+	unsigned int instrs[2];
+	unsigned long (*code)(unsigned long);
+	unsigned long opd[3];
+
+	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
+	instrs[1] = 0x4e800020;
+	opd[0] = (unsigned long)instrs;
+	opd[1] = 0;
+	opd[2] = 0;
+	store_inst(instrs);
+	store_inst(instrs+1);
+	code = (unsigned long (*)(unsigned long)) opd;
+
+	code(val);
+}
+
+static unsigned long regno;
+extern char exc_prolog;
+extern char dec_exc;
+
+void
+print_sysmap(void)
+{
+	extern char *sysmap;
+	if ( sysmap )
+		printf("System.map: \n%s", sysmap);
+}
+
+void
+super_regs()
+{
+	int i, cmd;
+	unsigned long val;
+	struct paca_struct*  ptrPaca = NULL;
+	struct ItLpPaca*  ptrLpPaca = NULL;
+	struct ItLpRegSave*  ptrLpRegSave = NULL;
+
+	cmd = skipbl();
+	if (cmd == '\n') {
+	        unsigned long sp, toc;
+		asm("mr %0,1" : "=r" (sp) :);
+		asm("mr %0,2" : "=r" (toc) :);
+
+		printf("msr  = %.16lx  sprg0= %.16lx\n", get_msr(), get_sprg0());
+		printf("pvr  = %.16lx  sprg1= %.16lx\n", get_pvr(), get_sprg1()); 
+		printf("dec  = %.16lx  sprg2= %.16lx\n", get_dec(), get_sprg2());
+		printf("sp   = %.16lx  sprg3= %.16lx\n", sp, get_sprg3());
+		printf("toc  = %.16lx  dar  = %.16lx\n", toc, get_dar());
+		printf("srr0 = %.16lx  srr1 = %.16lx\n", get_srr0(), get_srr1());
+		printf("asr  = %.16lx\n", mfasr());
+		for (i = 0; i < 8; ++i)
+			printf("sr%.2ld = %.16lx  sr%.2ld = %.16lx\n", i, get_sr(i), i+8, get_sr(i+8));
+
+		// Dump out relevant Paca data areas.
+		printf("Paca: \n");
+		ptrPaca = get_paca();
+    
+		printf("  Local Processor Control Area (LpPaca): \n");
+		ptrLpPaca = ptrPaca->xLpPacaPtr;
+		printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n", ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);
+		printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n", ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);
+		printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5);
+    
+		printf("  Local Processor Register Save Area (LpRegSave): \n");
+		ptrLpRegSave = ptrPaca->xLpRegSavePtr;
+		printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx \n", ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
+		printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx \n", ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
+		printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx \n", ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
+    
+		return;
+	}
+
+	scanhex(&regno);
+	switch (cmd) {
+	case 'w':
+		val = read_spr(regno);
+		scanhex(&val);
+		write_spr(regno, val);
+		/* fall through */
+	case 'r':
+		printf("spr %lx = %lx\n", regno, read_spr(regno));
+		break;
+	case 's':
+		val = get_sr(regno);
+		scanhex(&val);
+		set_sr(regno, val);
+		break;
+	case 'm':
+		val = get_msr();
+		scanhex(&val);
+		set_msrd(val);
+		break;
+	}
+	scannl();
+}
+
+#if 0
+static void
+openforth()
+{
+	int c;
+	char *p;
+	char cmd[1024];
+	int args[5];
+	extern int (*prom_entry)(int *);
+
+	p = cmd;
+	c = skipbl();
+	while (c != '\n') {
+		*p++ = c;
+		c = inchar();
+	}
+	*p = 0;
+	args[0] = (int) "interpret";
+	args[1] = 1;
+	args[2] = 1;
+	args[3] = (int) cmd;
+	(*prom_entry)(args);
+	printf("\n");
+	if (args[4] != 0)
+		printf("error %x\n", args[4]);
+}
+#endif
+
+#ifndef CONFIG_PPC64BRIDGE
+static void
+dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+{
+	extern void *Hash;
+	extern unsigned long Hash_size;
+	unsigned *htab = Hash;
+	unsigned hsize = Hash_size;
+	unsigned v, hmask, va, last_va;
+	int found, last_found, i;
+	unsigned *hg, w1, last_w2, last_va0;
+
+	last_found = 0;
+	hmask = hsize / 64 - 1;
+	va = start;
+	start = (start >> 12) & 0xffff;
+	end = (end >> 12) & 0xffff;
+	for (v = start; v < end; ++v) {
+		found = 0;
+		hg = htab + (((v ^ seg) & hmask) * 16);
+		w1 = 0x80000000 | (seg << 7) | (v >> 10);
+		for (i = 0; i < 8; ++i, hg += 2) {
+			if (*hg == w1) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found) {
+			w1 ^= 0x40;
+			hg = htab + ((~(v ^ seg) & hmask) * 16);
+			for (i = 0; i < 8; ++i, hg += 2) {
+				if (*hg == w1) {
+					found = 1;
+					break;
+				}
+			}
+		}
+		if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) {
+			if (last_found) {
+				if (last_va != last_va0)
+					printf(" ... %x", last_va);
+				printf("\n");
+			}
+			if (found) {
+				printf("%x to %x", va, hg[1]);
+				last_va0 = va;
+			}
+			last_found = found;
+		}
+		if (found) {
+			last_w2 = hg[1] & ~0x180;
+			last_va = va;
+		}
+		va += 4096;
+	}
+	if (last_found)
+		printf(" ... %x\n", last_va);
+}
+
+#else /* CONFIG_PPC64BRIDGE */
+static void
+dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+{
+	extern void *Hash;
+	extern unsigned long Hash_size;
+	unsigned *htab = Hash;
+	unsigned hsize = Hash_size;
+	unsigned v, hmask, va, last_va;
+	int found, last_found, i;
+	unsigned *hg, w1, last_w2, last_va0;
+
+	last_found = 0;
+	hmask = hsize / 128 - 1;
+	va = start;
+	start = (start >> 12) & 0xffff;
+	end = (end >> 12) & 0xffff;
+	for (v = start; v < end; ++v) {
+		found = 0;
+		hg = htab + (((v ^ seg) & hmask) * 32);
+		w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4);
+		for (i = 0; i < 8; ++i, hg += 4) {
+			if (hg[1] == w1) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found) {
+			w1 ^= 2;
+			hg = htab + ((~(v ^ seg) & hmask) * 32);
+			for (i = 0; i < 8; ++i, hg += 4) {
+				if (hg[1] == w1) {
+					found = 1;
+					break;
+				}
+			}
+		}
+		if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) {
+			if (last_found) {
+				if (last_va != last_va0)
+					printf(" ... %x", last_va);
+				printf("\n");
+			}
+			if (found) {
+				printf("%x to %x", va, hg[3]);
+				last_va0 = va;
+			}
+			last_found = found;
+		}
+		if (found) {
+			last_w2 = hg[3] & ~0x180;
+			last_va = va;
+		}
+		va += 4096;
+	}
+	if (last_found)
+		printf(" ... %x\n", last_va);
+}
+#endif /* CONFIG_PPC64BRIDGE */
+
+static unsigned long hash_ctx;
+static unsigned long hash_start;
+static unsigned long hash_end;
+
+static void
+dump_hash_table()
+{
+	int seg;
+	unsigned seg_start, seg_end;
+
+	hash_ctx = 0;
+	hash_start = 0;
+	hash_end = 0xfffff000;
+	scanhex(&hash_ctx);
+	scanhex(&hash_start);
+	scanhex(&hash_end);
+	printf("Mappings for context %x\n", hash_ctx);
+	seg_start = hash_start;
+	for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) {
+		seg_end = (seg << 28) | 0x0ffff000;
+		if (seg_end > hash_end)
+			seg_end = hash_end;
+		dump_hash_table_seg((hash_ctx << 4) + seg, seg_start, seg_end);
+		seg_start = seg_end + 0x1000;
+	}
+}
+
+int
+mread(unsigned long adrs, void *buf, int size)
+{
+	volatile int n;
+	char *p, *q;
+
+	n = 0;
+	if( setjmp(bus_error_jmp) == 0 ){
+		debugger_fault_handler = handle_fault;
+		sync();
+		p = (char *) adrs;
+		q = (char *) buf;
+		switch (size) {
+		case 2: *(short *)q = *(short *)p;	break;
+		case 4: *(int *)q = *(int *)p;		break;
+		default:
+			for( ; n < size; ++n ) {
+				*q++ = *p++;
+				sync();
+			}
+		}
+		sync();
+		/* wait a little while to see if we get a machine check */
+		__delay(200);
+		n = size;
+	}
+	debugger_fault_handler = 0;
+	return n;
+}
+
+int
+mwrite(unsigned long adrs, void *buf, int size)
+{
+	volatile int n;
+	char *p, *q;
+
+	n = 0;
+	if( setjmp(bus_error_jmp) == 0 ){
+		debugger_fault_handler = handle_fault;
+		sync();
+		p = (char *) adrs;
+		q = (char *) buf;
+		switch (size) {
+		case 2: *(short *)p = *(short *)q;	break;
+		case 4: *(int *)p = *(int *)q;		break;
+		default:
+			for( ; n < size; ++n ) {
+				*p++ = *q++;
+				sync();
+			}
+		}
+		sync();
+		/* wait a little while to see if we get a machine check */
+		__delay(200);
+		n = size;
+	} else {
+		printf("*** Error writing address %x\n", adrs + n);
+	}
+	debugger_fault_handler = 0;
+	return n;
+}
+
+static int fault_type;
+static char *fault_chars[] = { "--", "**", "##" };
+
+static void
+handle_fault(struct pt_regs *regs)
+{
+	fault_type = regs->trap == 0x200? 0: regs->trap == 0x300? 1: 2;
+	longjmp(bus_error_jmp, 1);
+}
+
+#define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
+
+void
+byterev(unsigned char *val, int size)
+{
+	int t;
+	
+	switch (size) {
+	case 2:
+		SWAP(val[0], val[1], t);
+		break;
+	case 4:
+		SWAP(val[0], val[3], t);
+		SWAP(val[1], val[2], t);
+		break;
+	case 8: /* is there really any use for this? */
+		SWAP(val[0], val[7], t);
+		SWAP(val[1], val[6], t);
+		SWAP(val[2], val[5], t);
+		SWAP(val[3], val[4], t);
+		break;
+	}
+}
+
+static int brev;
+static int mnoread;
+
+static char *memex_help_string = 
+    "Memory examine command usage:\n"
+    "m [addr] [flags] examine/change memory\n"
+    "  addr is optional.  will start where left off.\n"
+    "  flags may include chars from this set:\n"
+    "    b   modify by bytes (default)\n"
+    "    w   modify by words (2 byte)\n"
+    "    l   modify by longs (4 byte)\n"
+    "    d   modify by doubleword (8 byte)\n"
+    "    r   toggle reverse byte order mode\n"
+    "    n   do not read memory (for i/o spaces)\n"
+    "    .   ok to read (default)\n"
+    "NOTE: flags are saved as defaults\n"
+    "";
+
+static char *memex_subcmd_help_string = 
+    "Memory examine subcommands:\n"
+    "  hexval   write this val to current location\n"
+    "  'string' write chars from string to this location\n"
+    "  '        increment address\n"
+    "  ^        decrement address\n"
+    "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
+    "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
+    "  `        clear no-read flag\n"
+    "  ;        stay at this addr\n"
+    "  v        change to byte mode\n"
+    "  w        change to word (2 byte) mode\n"
+    "  l        change to long (4 byte) mode\n"
+    "  u        change to doubleword (8 byte) mode\n"
+    "  m addr   change current addr\n"
+    "  n        toggle no-read flag\n"
+    "  r        toggle byte reverse flag\n"
+    "  < count  back up count bytes\n"
+    "  > count  skip forward count bytes\n"
+    "  x        exit this mode\n"
+    "";
+
+void
+memex()
+{
+	int cmd, inc, i, nslash;
+	unsigned long n;
+	unsigned char val[16];
+
+	scanhex((void *)&adrs);
+	cmd = skipbl();
+	if (cmd == '?') {
+		printf(memex_help_string);
+		return;
+	} else {
+		termch = cmd;
+	}
+	last_cmd = "m\n";
+	while ((cmd = skipbl()) != '\n') {
+		switch( cmd ){
+		case 'b':	size = 1;	break;
+		case 'w':	size = 2;	break;
+		case 'l':	size = 4;	break;
+		case 'd':	size = 8;	break;
+		case 'r': 	brev = !brev;	break;
+		case 'n':	mnoread = 1;	break;
+		case '.':	mnoread = 0;	break;
+		}
+	}
+	if( size <= 0 )
+		size = 1;
+	else if( size > 8 )
+		size = 8;
+	for(;;){
+		if (!mnoread)
+			n = mread(adrs, val, size);
+		printf("%.16x%c", adrs, brev? 'r': ' ');
+		if (!mnoread) {
+			if (brev)
+				byterev(val, size);
+			putchar(' ');
+			for (i = 0; i < n; ++i)
+				printf("%.2x", val[i]);
+			for (; i < size; ++i)
+				printf("%s", fault_chars[fault_type]);
+		}
+		putchar(' ');
+		inc = size;
+		nslash = 0;
+		for(;;){
+			if( scanhex(&n) ){
+				for (i = 0; i < size; ++i)
+					val[i] = n >> (i * 8);
+				if (!brev)
+					byterev(val, size);
+				mwrite(adrs, val, size);
+				inc = size;
+			}
+			cmd = skipbl();
+			if (cmd == '\n')
+				break;
+			inc = 0;
+			switch (cmd) {
+			case '\'':
+				for(;;){
+					n = inchar();
+					if( n == '\\' )
+						n = bsesc();
+					else if( n == '\'' )
+						break;
+					for (i = 0; i < size; ++i)
+						val[i] = n >> (i * 8);
+					if (!brev)
+						byterev(val, size);
+					mwrite(adrs, val, size);
+					adrs += size;
+				}
+				adrs -= size;
+				inc = size;
+				break;
+			case ',':
+				adrs += size;
+				break;
+			case '.':
+				mnoread = 0;
+				break;
+			case ';':
+				break;
+			case 'x':
+			case EOF:
+				scannl();
+				return;
+			case 'b':
+			case 'v':
+				size = 1;
+				break;
+			case 'w':
+				size = 2;
+				break;
+			case 'l':
+				size = 4;
+				break;
+			case 'u':
+				size = 8;
+				break;
+			case '^':
+				adrs -= size;
+				break;
+				break;
+			case '/':
+				if (nslash > 0)
+					adrs -= 1 << nslash;
+				else
+					nslash = 0;
+				nslash += 4;
+				adrs += 1 << nslash;
+				break;
+			case '\\':
+				if (nslash < 0)
+					adrs += 1 << -nslash;
+				else
+					nslash = 0;
+				nslash -= 4;
+				adrs -= 1 << -nslash;
+				break;
+			case 'm':
+				scanhex((void *)&adrs);
+				break;
+			case 'n':
+				mnoread = 1;
+				break;
+			case 'r':
+				brev = !brev;
+				break;
+			case '<':
+				n = size;
+				scanhex(&n);
+				adrs -= n;
+				break;
+			case '>':
+				n = size;
+				scanhex(&n);
+				adrs += n;
+				break;
+			case '?':
+				printf(memex_subcmd_help_string);
+				break;
+			}
+		}
+		adrs += inc;
+	}
+}
+
+int
+bsesc()
+{
+	int c;
+
+	c = inchar();
+	switch( c ){
+	case 'n':	c = '\n';	break;
+	case 'r':	c = '\r';	break;
+	case 'b':	c = '\b';	break;
+	case 't':	c = '\t';	break;
+	}
+	return c;
+}
+
+#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
+			 || ('a' <= (c) && (c) <= 'f') \
+			 || ('A' <= (c) && (c) <= 'F'))
+void
+dump()
+{
+	int c;
+
+	c = inchar();
+	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
+		termch = c;
+	scanhex((void *)&adrs);
+	if( termch != '\n')
+		termch = 0;
+	if( c == 'i' ){
+		scanhex(&nidump);
+		if( nidump == 0 )
+			nidump = 16;
+		adrs += ppc_inst_dump(adrs, nidump);
+		last_cmd = "di\n";
+	} else {
+		scanhex(&ndump);
+		if( ndump == 0 )
+			ndump = 64;
+		prdump(adrs, ndump);
+		adrs += ndump;
+		last_cmd = "d\n";
+	}
+}
+
+void
+prdump(unsigned long adrs, long ndump)
+{
+	long n, m, c, r, nr;
+	unsigned char temp[16];
+
+	for( n = ndump; n > 0; ){
+		printf("%.16lx", adrs);
+		putchar(' ');
+		r = n < 16? n: 16;
+		nr = mread(adrs, temp, r);
+		adrs += nr;
+		for( m = 0; m < r; ++m ){
+		        if ((m & 7) == 0 && m > 0)
+			    putchar(' ');
+			if( m < nr )
+				printf("%.2x", temp[m]);
+			else
+				printf("%s", fault_chars[fault_type]);
+		}
+		for(; m < 16; ++m )
+			printf("   ");
+		printf("  |");
+		for( m = 0; m < r; ++m ){
+			if( m < nr ){
+				c = temp[m];
+				putchar(' ' <= c && c <= '~'? c: '.');
+			} else
+				putchar(' ');
+		}
+		n -= r;
+		for(; m < 16; ++m )
+			putchar(' ');
+		printf("|\n");
+		if( nr < r )
+			break;
+	}
+}
+
+int
+ppc_inst_dump(unsigned long adr, long count)
+{
+	int nr, dotted;
+	unsigned long first_adr;
+	unsigned long inst, last_inst;
+	unsigned char val[4];
+
+	dotted = 0;
+	for (first_adr = adr; count > 0; --count, adr += 4){
+		nr = mread(adr, val, 4);
+		if( nr == 0 ){
+			const char *x = fault_chars[fault_type];
+			printf("%.16lx  %s%s%s%s\n", adr, x, x, x, x);
+			break;
+		}
+		inst = GETWORD(val);
+		if (adr > first_adr && inst == last_inst) {
+			if (!dotted) {
+				printf(" ...\n");
+				dotted = 1;
+			}
+			continue;
+		}
+		dotted = 0;
+		last_inst = inst;
+		printf("%.16lx  ", adr);
+		printf("%.8x\t", inst);
+		print_insn_big_powerpc(stdout, inst, adr);	/* always returns 4 */
+		printf("\n");
+	}
+	return adr - first_adr;
+}
+
+void
+print_address(unsigned long addr)
+{
+	printf("0x%lx", addr);
+}
+
+/*
+ * Memory operations - move, set, print differences
+ */
+static unsigned long mdest;		/* destination address */
+static unsigned long msrc;		/* source address */
+static unsigned long mval;		/* byte value to set memory to */
+static unsigned long mcount;		/* # bytes to affect */
+static unsigned long mdiffs;		/* max # differences to print */
+
+void
+memops(int cmd)
+{
+	scanhex((void *)&mdest);
+	if( termch != '\n' )
+		termch = 0;
+	scanhex((void *)(cmd == 's'? &mval: &msrc));
+	if( termch != '\n' )
+		termch = 0;
+	scanhex((void *)&mcount);
+	switch( cmd ){
+	case 'm':
+		memmove((void *)mdest, (void *)msrc, mcount);
+		break;
+	case 's':
+		memset((void *)mdest, mval, mcount);
+		break;
+	case 'd':
+		if( termch != '\n' )
+			termch = 0;
+		scanhex((void *)&mdiffs);
+		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
+		break;
+	}
+}
+
+void
+memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
+{
+	unsigned n, prt;
+
+	prt = 0;
+	for( n = nb; n > 0; --n )
+		if( *p1++ != *p2++ )
+			if( ++prt <= maxpr )
+				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
+					p1[-1], p2 - 1, p2[-1]);
+	if( prt > maxpr )
+		printf("Total of %d differences\n", prt);
+}
+
+static unsigned mend;
+static unsigned mask;
+
+void
+memlocate()
+{
+	unsigned a, n;
+	unsigned char val[4];
+
+	last_cmd = "ml";
+	scanhex((void *)&mdest);
+	if (termch != '\n') {
+		termch = 0;
+		scanhex((void *)&mend);
+		if (termch != '\n') {
+			termch = 0;
+			scanhex((void *)&mval);
+			mask = ~0;
+			if (termch != '\n') termch = 0;
+			scanhex((void *)&mask);
+		}
+	}
+	n = 0;
+	for (a = mdest; a < mend; a += 4) {
+		if (mread(a, val, 4) == 4
+			&& ((GETWORD(val) ^ mval) & mask) == 0) {
+			printf("%.16x:  %.16x\n", a, GETWORD(val));
+			if (++n >= 10)
+				break;
+		}
+	}
+}
+
+static unsigned long mskip = 0x1000;
+static unsigned long mlim = 0xffffffff;
+
+void
+memzcan()
+{
+	unsigned char v;
+	unsigned a;
+	int ok, ook;
+
+	scanhex(&mdest);
+	if (termch != '\n') termch = 0;
+	scanhex(&mskip);
+	if (termch != '\n') termch = 0;
+	scanhex(&mlim);
+	ook = 0;
+	for (a = mdest; a < mlim; a += mskip) {
+		ok = mread(a, &v, 1);
+		if (ok && !ook) {
+			printf("%.8x .. ", a);
+			fflush(stdout);
+		} else if (!ok && ook)
+			printf("%.8x\n", a - mskip);
+		ook = ok;
+		if (a + mskip < a)
+			break;
+	}
+	if (ook)
+		printf("%.8x\n", a - mskip);
+}
+
+/* Input scanning routines */
+int
+skipbl()
+{
+	int c;
+
+	if( termch != 0 ){
+		c = termch;
+		termch = 0;
+	} else
+		c = inchar();
+	while( c == ' ' || c == '\t' )
+		c = inchar();
+	return c;
+}
+
+int
+scanhex(vp)
+unsigned long *vp;
+{
+	int c, d;
+	unsigned long v;
+
+	c = skipbl();
+	d = hexdigit(c);
+	if( d == EOF ){
+		termch = c;
+		return 0;
+	}
+	v = 0;
+	do {
+		v = (v << 4) + d;
+		c = inchar();
+		d = hexdigit(c);
+	} while( d != EOF );
+	termch = c;
+	*vp = v;
+	return 1;
+}
+
+void
+scannl()
+{
+	int c;
+
+	c = termch;
+	termch = 0;
+	while( c != '\n' )
+		c = inchar();
+}
+
+int
+hexdigit(int c)
+{
+	if( '0' <= c && c <= '9' )
+		return c - '0';
+	if( 'A' <= c && c <= 'F' )
+		return c - ('A' - 10);
+	if( 'a' <= c && c <= 'f' )
+		return c - ('a' - 10);
+	return EOF;
+}
+
+void
+getstring(char *s, int size)
+{
+	int c;
+
+	c = skipbl();
+	do {
+		if( size > 1 ){
+			*s++ = c;
+			--size;
+		}
+		c = inchar();
+	} while( c != ' ' && c != '\t' && c != '\n' );
+	termch = c;
+	*s = 0;
+}
+
+static char line[256];
+static char *lineptr;
+
+void
+flush_input()
+{
+	lineptr = NULL;
+}
+
+int
+inchar()
+{
+	if (lineptr == NULL || *lineptr == 0) {
+		if (fgets(line, sizeof(line), stdin) == NULL) {
+			lineptr = NULL;
+			return EOF;
+		}
+		lineptr = line;
+	}
+	return *lineptr++;
+}
+
+void
+take_input(str)
+char *str;
+{
+	lineptr = str;
+}
+
+
+/* Starting at codeaddr scan forward for a tbtable and fill in the
+ given table.  Return non-zero if successful at doing something.
+ */
+static int
+find_tb_table(unsigned long codeaddr, struct tbtable *tab)
+{
+	unsigned long codeaddr_max;
+	unsigned long tbtab_start;
+	int nr;
+	int instr;
+	int num_parms;
+
+	if (tab == NULL)
+		return 0;
+	memset(tab, 0, sizeof(tab));
+
+	/* Scan instructions starting at codeaddr for 128k max */
+	for (codeaddr_max = codeaddr + 128*1024*4;
+	     codeaddr < codeaddr_max;
+	     codeaddr += 4) {
+		nr = mread(codeaddr, &instr, 4);
+		if (nr != 4)
+			return 0;	/* Bad read.  Give up promptly. */
+		if (instr == 0) {
+			/* table should follow. */
+			int version;
+			unsigned long flags;
+			tbtab_start = codeaddr;	/* save it to compute func start addr */
+			codeaddr += 4;
+			nr = mread(codeaddr, &flags, 8);
+			if (nr != 8)
+				return 0;	/* Bad read or no tb table. */
+			tab->flags = flags;
+			version = (flags >> 56) & 0xff;
+			if (version != 0)
+				continue;	/* No tb table here. */
+			/* Now, like the version, some of the flags are values
+			 that are more conveniently extracted... */
+			tab->fp_saved = (flags >> 24) & 0x3f;
+			tab->gpr_saved = (flags >> 16) & 0x3f;
+			tab->fixedparms = (flags >> 8) & 0xff;
+			tab->floatparms = (flags >> 1) & 0x7f;
+			codeaddr += 8;
+			num_parms = tab->fixedparms + tab->floatparms;
+			if (num_parms) {
+				unsigned int parminfo;
+				int parm;
+				if (num_parms > 32)
+					return 1;	/* incomplete */
+				nr = mread(codeaddr, &parminfo, 4);
+				if (nr != 4)
+					return 1;	/* incomplete */
+				/* decode parminfo...32 bits.
+				 A zero means fixed.  A one means float and the
+				 following bit determines single (0) or double (1).
+				 */
+				for (parm = 0; parm < num_parms; parm++) {
+					if (parminfo & 0x80000000) {
+						parminfo <<= 1;
+						if (parminfo & 0x80000000)
+							tab->parminfo[parm] = TBTAB_PARMDFLOAT;
+						else
+							tab->parminfo[parm] = TBTAB_PARMSFLOAT;
+					} else {
+						tab->parminfo[parm] = TBTAB_PARMFIXED;
+					}
+					parminfo <<= 1;
+				}
+				codeaddr += 4;
+			}
+			if (flags & TBTAB_FLAGSHASTBOFF) {
+				nr = mread(codeaddr, &tab->tb_offset, 4);
+				if (nr != 4)
+					return 1;	/* incomplete */
+				if (tab->tb_offset > 0) {
+					tab->funcstart = tbtab_start - tab->tb_offset;
+				}
+				codeaddr += 4;
+			}
+			/* hand_mask appears to be always be omitted. */
+			if (flags & TBTAB_FLAGSHASCTL) {
+				/* Assume this will never happen for C or asm */
+				return 1;	/* incomplete */
+			}
+			if (flags & TBTAB_FLAGSNAMEPRESENT) {
+				short namlen;
+				nr = mread(codeaddr, &namlen, 2);
+				if (nr != 2)
+					return 1;	/* incomplete */
+				if (namlen >= sizeof(tab->name))
+					namlen = sizeof(tab->name)-1;
+				codeaddr += 2;
+				nr = mread(codeaddr, tab->name, namlen);
+				tab->name[namlen] = '\0';
+				codeaddr += namlen;
+			}
+			return 1;
+		}
+	}
+	return 0;	/* hit max...sorry. */
+}
+
+void
+mem_translate()
+{
+	int c;
+	unsigned long ea, va, vsid, vpn, page, hpteg_slot_primary, hpteg_slot_secondary, primary_hash, i, *steg, esid, stabl;
+	HPTE *  hpte;
+	struct mm_struct * mm;
+	pte_t  *ptep = NULL;
+	void * pgdir;
+ 
+	c = inchar();
+	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
+		termch = c;
+	scanhex((void *)&ea);
+  
+	if ((ea >= KRANGE_START) && (ea <= (KRANGE_START + (1UL<<60)))) {
+		ptep = 0;
+		vsid = get_kernel_vsid(ea);
+		va = ( vsid << 28 ) | ( ea & 0x0fffffff );
+	} else {
+		// if in vmalloc range, use the vmalloc page directory
+		if ( ( ea >= VMALLOC_START ) && ( ea <= VMALLOC_END ) ) {
+			mm = &init_mm;
+			vsid = get_kernel_vsid( ea );
+		}
+		// if in ioremap range, use the ioremap page directory
+		else if ( ( ea >= IMALLOC_START ) && ( ea <= IMALLOC_END ) ) {
+			mm = &ioremap_mm;
+			vsid = get_kernel_vsid( ea );
+		}
+		// if in user range, use the current task's page directory
+		else if ( ( ea >= USER_START ) && ( ea <= USER_END ) ) {
+			mm = current->mm;
+			vsid = get_vsid(mm->context, ea );
+		}
+		pgdir = mm->pgd;
+		va = ( vsid << 28 ) | ( ea & 0x0fffffff );
+		ptep = find_linux_pte( pgdir, ea );
+	}
+
+	vpn = ((vsid << 28) | (((ea) & 0xFFFF000))) >> 12;
+	page = vpn & 0xffff;
+	esid = (ea >> 28)  & 0xFFFFFFFFF;
+
+  // Search the primary group for an available slot
+	primary_hash = ( vsid & 0x7fffffffff ) ^ page;
+	hpteg_slot_primary = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+	hpteg_slot_secondary = ( ~primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+
+	printf("ea             : %.16lx\n", ea);
+	printf("esid           : %.16lx\n", esid);
+	printf("vsid           : %.16lx\n", vsid);
+
+	printf("\nSoftware Page Table\n-------------------\n");
+	printf("ptep           : %.16lx\n", ((unsigned long *)ptep));
+	if(ptep) {
+		printf("*ptep          : %.16lx\n", *((unsigned long *)ptep));
+	}
+
+	hpte  = htab_data.htab  + hpteg_slot_primary;
+	printf("\nHardware Page Table\n-------------------\n");
+	printf("htab base      : %.16lx\n", htab_data.htab);
+	printf("slot primary   : %.16lx\n", hpteg_slot_primary);
+	printf("slot secondary : %.16lx\n", hpteg_slot_secondary);
+	printf("\nPrimary Group\n");
+	for (i=0; i<8; ++i) {
+		if ( hpte->dw0.dw0.v != 0 ) {
+			printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1);
+			printf("          vsid: %.13lx   api: %.2lx  hash: %.1lx\n", 
+			       (hpte->dw0.dw0.avpn)>>5, 
+			       (hpte->dw0.dw0.avpn) & 0x1f,
+			       (hpte->dw0.dw0.h));
+			printf("          rpn: %.13lx \n", (hpte->dw1.dw1.rpn));
+			printf("           pp: %.1lx \n", 
+			       ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
+			printf("        wimgn: %.2lx  reference: %.1lx  change: %.1lx\n", 
+			       ((hpte->dw1.dw1.w)<<4)|
+			       ((hpte->dw1.dw1.i)<<3)|
+			       ((hpte->dw1.dw1.m)<<2)|
+			       ((hpte->dw1.dw1.g)<<1)|
+			       ((hpte->dw1.dw1.n)<<0),
+			       hpte->dw1.dw1.r, hpte->dw1.dw1.c);
+		}
+		hpte++;
+	}
+
+	printf("\nSecondary Group\n");
+	// Search the secondary group
+	hpte  = htab_data.htab  + hpteg_slot_secondary;
+	for (i=0; i<8; ++i) {
+		if(hpte->dw0.dw0.v) {
+			printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1);
+			printf("          vsid: %.13lx   api: %.2lx  hash: %.1lx\n", 
+			       (hpte->dw0.dw0.avpn)>>5, 
+			       (hpte->dw0.dw0.avpn) & 0x1f,
+			       (hpte->dw0.dw0.h));
+			printf("          rpn: %.13lx \n", (hpte->dw1.dw1.rpn));
+			printf("           pp: %.1lx \n", 
+			       ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
+			printf("        wimgn: %.2lx  reference: %.1lx  change: %.1lx\n", 
+			       ((hpte->dw1.dw1.w)<<4)|
+			       ((hpte->dw1.dw1.i)<<3)|
+			       ((hpte->dw1.dw1.m)<<2)|
+			       ((hpte->dw1.dw1.g)<<1)|
+			       ((hpte->dw1.dw1.n)<<0),
+			       hpte->dw1.dw1.r, hpte->dw1.dw1.c);
+		}
+		hpte++;
+	}
+
+	printf("\nHardware Segment Table\n-----------------------\n");
+	stabl = (unsigned long)(KERNELBASE+(_ASR&0xFFFFFFFFFFFFFFFE));
+	steg = (unsigned long *)((stabl) | ((esid & 0x1f) << 7));
+
+	printf("stab base      : %.16lx\n", stabl);
+	printf("slot           : %.16lx\n", steg);
+
+	for (i=0; i<8; ++i) {
+		printf("%d: (ste) %.16lx %.16lx\n", i,
+		       *((unsigned long *)(steg+i*2)),*((unsigned long *)(steg+i*2+1)) );
+	}
+}
+
+void mem_check()
+{
+	unsigned long htab_size_bytes;
+	unsigned long htab_end;
+	unsigned long last_rpn;
+	HPTE *hpte1, *hpte2;
+
+	htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
+	htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
+	// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
+	last_rpn = 0xfffff;
+
+	printf("\nHardware Page Table Check\n-------------------\n");
+	printf("htab base      : %.16lx\n", htab_data.htab);
+	printf("htab size      : %.16lx\n", htab_size_bytes);
+
+#if 1
+	for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
+		if ( hpte1->dw0.dw0.v != 0 ) {
+			if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
+				for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
+					if ( hpte2->dw0.dw0.v != 0 ) {
+						if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
+							printf(" Duplicate rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
+							printf("   hpte1: %16.16lx  *hpte1: %16.16lx %16.16lx\n",
+							       hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
+							printf("   hpte2: %16.16lx  *hpte2: %16.16lx %16.16lx\n",
+							       hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1);
+						}
+					}
+				}
+			} else {
+				printf(" Bogus rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
+				printf("   hpte: %16.16lx  *hpte: %16.16lx %16.16lx\n",
+				       hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
+			}
+		}
+	}
+#endif
+	printf("\nDone -------------------\n");
+}
+
+void mem_find_real()
+{
+	unsigned long htab_size_bytes;
+	unsigned long htab_end;
+	unsigned long last_rpn;
+	HPTE *hpte1;
+	unsigned long pa, rpn;
+	int c;
+
+	c = inchar();
+	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
+		termch = c;
+	scanhex((void *)&pa);
+	rpn = pa >> 12;
+  
+	htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
+	htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
+	// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
+	last_rpn = 0xfffff;
+
+	printf("\nMem Find RPN\n-------------------\n");
+	printf("htab base      : %.16lx\n", htab_data.htab);
+	printf("htab size      : %.16lx\n", htab_size_bytes);
+
+	for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
+		if ( hpte1->dw0.dw0.v != 0 ) {
+			if ( hpte1->dw1.dw1.rpn == rpn ) {
+				printf(" Found rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
+				printf("      hpte: %16.16lx  *hpte1: %16.16lx %16.16lx\n",
+				       hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
+			}
+		}
+	}
+	printf("\nDone -------------------\n");
+}
+
+void mem_find_vsid()
+{
+	unsigned long htab_size_bytes;
+	unsigned long htab_end;
+	HPTE *hpte1;
+	unsigned long vsid;
+	int c;
+
+	c = inchar();
+	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
+		termch = c;
+	scanhex((void *)&vsid);
+  
+	htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
+	htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
+
+	printf("\nMem Find VSID\n-------------------\n");
+	printf("htab base      : %.16lx\n", htab_data.htab);
+	printf("htab size      : %.16lx\n", htab_size_bytes);
+
+	for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
+		if ( hpte1->dw0.dw0.v != 0 ) {
+			if ( ((hpte1->dw0.dw0.avpn)>>5) == vsid ) {
+				printf(" Found vsid: %.16lx \n", ((hpte1->dw0.dw0.avpn) >> 5));
+				printf("       hpte: %16.16lx  *hpte1: %16.16lx %16.16lx\n",
+				       hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
+			}
+		}
+	}
+	printf("\nDone -------------------\n");
+}
+
+void mem_map_check_slab()
+{
+	int i, slab_count;
+
+	i = max_mapnr;
+	slab_count = 0;
+	
+	while (i-- > 0)  {
+		if (PageSlab(mem_map+i)){
+			printf(" slab entry - mem_map entry =%p  \n", mem_map+i);
+			slab_count ++;
+		}
+	}
+
+	printf(" count of pages for slab = %d \n", slab_count);
+}
+
+void mem_map_lock_pages()
+{
+	int i, lock_count;
+
+	i = max_mapnr;
+	lock_count = 0;
+	
+	while (i-- > 0)  {
+		if (PageLocked(mem_map+i)){
+			printf(" locked entry - mem_map entry =%p  \n", mem_map+i);
+			lock_count ++;
+		}
+	}
+
+	printf(" count of locked pages = %d \n", lock_count); 
+}
+
+
+
+void mem_map_check_hash()
+{
+	int i = max_mapnr;
+	
+	while (i-- > 0)  {
+		/* skip the reserved */
+		if (!PageReserved(mem_map+i)) {
+			if (((mem_map+i)->next_hash) != NULL) {
+				if ( REGION_ID((mem_map+i)->next_hash) != KERNEL_REGION_ID ) {
+					printf(" mem_map check hash - non c0 entry - "
+					       "address/value = %p %lx\n", mem_map+i,(mem_map+i)->next_hash);
+				} 
+				if ((unsigned long)((mem_map+i)->next_hash) ==  KERNELBASE){
+					printf(" mem_map check hash - 0x%lx  entry = %p \n",
+					       KERNELBASE, mem_map+i);
+				} 
+			}
+		} else {
+			if (page_count(mem_map+i) < 0) {
+				printf(" reserved page with negative count- entry = %lx \n", mem_map+i);
+			}
+		}
+	}
+	printf(" mem_map check hash completed \n");
+}
+
+void mem_check_dup_rpn ()
+{
+	unsigned long htab_size_bytes;
+	unsigned long htab_end;
+	unsigned long last_rpn;
+	HPTE *hpte1, *hpte2;
+	int dup_count;
+	struct task_struct *p;
+	unsigned long kernel_vsid_c0,kernel_vsid_c1,kernel_vsid_c2,kernel_vsid_c3;
+	unsigned long kernel_vsid_c4,kernel_vsid_c5,kernel_vsid_d,kernel_vsid_e;
+	unsigned long kernel_vsid_f;
+	unsigned long vsid0,vsid1,vsidB,vsid2;
+
+	htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
+	htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
+	// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
+	last_rpn = 0xfffff;
+
+	printf("\nHardware Page Table Check\n-------------------\n");
+	printf("htab base      : %.16lx\n", htab_data.htab);
+	printf("htab size      : %.16lx\n", htab_size_bytes);
+
+
+	for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
+		if ( hpte1->dw0.dw0.v != 0 ) {
+			if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
+				dup_count = 0;
+				for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
+					if ( hpte2->dw0.dw0.v != 0 ) {
+						if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
+							dup_count++;
+						}
+					}
+				}
+				if(dup_count > 5) {
+					printf(" Duplicate rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
+					printf("    mem map array entry %p count = %d \n",
+					       (mem_map+(hpte1->dw1.dw1.rpn)), (mem_map+(hpte1->dw1.dw1.rpn))->count);
+					for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
+						if ( hpte2->dw0.dw0.v != 0 ) {
+							if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
+								printf("   hpte2: %16.16lx  *hpte2: %16.16lx %16.16lx\n",
+								       hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1);
+							}
+						}
+					}
+				}
+			} else {
+				printf(" Bogus rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
+				printf("   hpte: %16.16lx  *hpte: %16.16lx %16.16lx\n",
+				       hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
+			}
+		}
+		if (xmon_interrupted())
+			return;
+	}                                                                     
+
+
+
+	// print the kernel vsids
+	kernel_vsid_c0 =  get_kernel_vsid(0xC000000000000000);
+	kernel_vsid_c1 =  get_kernel_vsid(0xC000000010000000);
+	kernel_vsid_c2 =  get_kernel_vsid(0xC000000020000000);
+	kernel_vsid_c3 =  get_kernel_vsid(0xC000000030000000);
+	kernel_vsid_c4 =  get_kernel_vsid(0xC000000040000000);
+	kernel_vsid_c5 =  get_kernel_vsid(0xC000000050000000);
+	kernel_vsid_d  =  get_kernel_vsid(0xD000000000000000);
+	kernel_vsid_e  =  get_kernel_vsid(0xE000000000000000);
+	kernel_vsid_f  =  get_kernel_vsid(0xF000000000000000);
+
+	printf(" kernel vsid -  seg c0  = %lx\n",  kernel_vsid_c0 );
+	printf(" kernel vsid -  seg c1  = %lx\n",  kernel_vsid_c1 );
+	printf(" kernel vsid -  seg c2  = %lx\n",  kernel_vsid_c2 );
+	printf(" kernel vsid -  seg c3  = %lx\n",  kernel_vsid_c3 );
+	printf(" kernel vsid -  seg c4  = %lx\n",  kernel_vsid_c4 );
+	printf(" kernel vsid -  seg c5  = %lx\n",  kernel_vsid_c5 );
+	printf(" kernel vsid -  seg d   = %lx\n",  kernel_vsid_d );
+	printf(" kernel vsid -  seg e   = %lx\n",  kernel_vsid_e );
+	printf(" kernel vsid -  seg f   = %lx\n",  kernel_vsid_f );
+
+
+  // print a list of valid vsids for the tasks
+	read_lock(&tasklist_lock);
+	for_each_task(p)
+		if(p->mm) {
+			struct mm_struct *mm = p->mm; 
+			printf(" task = %p  mm =  %lx  pgd   %lx\n", 
+			       p, mm, mm->pgd);
+			vsid0 = get_vsid( mm->context, 0 );
+			vsid1 = get_vsid( mm->context, 0x10000000 );
+			vsid2 = get_vsid( mm->context, 0x20000000 );
+			vsidB = get_vsid( mm->context, 0xB0000000 );
+			printf("            context = %lx  vsid seg 0  = %lx\n",  mm->context, vsid0 );
+			printf("                           vsid seg 1  = %lx\n",  vsid1 );
+			printf("                           vsid seg 2  = %lx\n",  vsid2 );
+			printf("                           vsid seg 2  = %lx\n",  vsidB );
+	  
+			printf("\n");
+		};
+	read_unlock(&tasklist_lock);
+
+	printf("\nDone -------------------\n");
+}
+
+
+
+void mem_check_pagetable_vsids ()
+{
+	unsigned long htab_size_bytes;
+	unsigned long htab_end;
+	unsigned long last_rpn;
+	struct task_struct *p;
+	unsigned long valid_table_count,invalid_table_count,bogus_rpn_count;
+	int found;
+	unsigned long user_address_table_count,kernel_page_table_count;
+	unsigned long pt_vsid;
+	HPTE *hpte1;
+
+
+	htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
+	htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
+	// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
+	last_rpn = 0xfffff;
+
+	printf("\nHardware Page Table Check\n-------------------\n");
+	printf("htab base      : %.16lx\n", htab_data.htab);
+	printf("htab size      : %.16lx\n", htab_size_bytes);
+
+	valid_table_count = 0;
+	invalid_table_count = 0;
+	bogus_rpn_count = 0;
+	user_address_table_count = 0;
+	kernel_page_table_count = 0;
+	for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
+		if ( hpte1->dw0.dw0.v != 0 ) {
+			valid_table_count++;
+			if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
+				pt_vsid =  (hpte1->dw0.dw0.avpn) >> 5;
+				if ((pt_vsid == get_kernel_vsid(0xC000000000000000)) |
+				    (pt_vsid == get_kernel_vsid(0xC000000010000000)) |
+				    (pt_vsid == get_kernel_vsid(0xC000000020000000)) |
+				    (pt_vsid == get_kernel_vsid(0xC000000030000000)) |
+				    (pt_vsid == get_kernel_vsid(0xC000000040000000)) |
+				    (pt_vsid == get_kernel_vsid(0xC000000050000000)) |
+				    (pt_vsid == get_kernel_vsid(0xD000000000000000)) |
+				    (pt_vsid == get_kernel_vsid(0xE000000000000000)) |
+				    (pt_vsid == get_kernel_vsid(0xF000000000000000)) ) {
+					kernel_page_table_count ++;
+				} else {
+					read_lock(&tasklist_lock);
+					found = 0;
+					for_each_task(p) {
+						if(p->mm && (found == 0)) {
+							struct mm_struct *mm = p->mm; 
+	     
+							if ((pt_vsid == get_vsid( mm->context, 0 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x10000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x20000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x30000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x40000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x50000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x60000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x70000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x80000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0x90000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0xA0000000 )) |
+							    (pt_vsid == get_vsid( mm->context, 0xB0000000 ))) {
+								user_address_table_count ++;
+								found = 1;
+							}
+						}
+					}
+					read_unlock(&tasklist_lock);
+					if (found == 0)
+					{
+						printf(" vsid not found vsid = %lx, hpte = %p  \n", 
+						       pt_vsid,hpte1);
+						printf("    rpn in entry = %lx \n", hpte1->dw1.dw1.rpn);
+						printf("    mem map address = %lx  \n", mem_map + (hpte1->dw1.dw1.rpn));
+           
+					} else //  found
+					{
+					}
+
+				}  // good rpn
+       
+			} else {
+				bogus_rpn_count ++;
+			}
+		} else {
+			invalid_table_count++;
+		}
+	}                                                                     
+
+
+	printf(" page table valid counts - valid entries = %lx  invalid entries =  %lx \n",
+	       valid_table_count, invalid_table_count);
+
+	printf("  bogus rpn entries ( probably io) = %lx \n", bogus_rpn_count);
+
+ 
+  
+	printf(" page table counts - kernel entries = %lx  user entries =  %lx \n",
+	       kernel_page_table_count, user_address_table_count); 
+
+	printf("\nDone -------------------\n");
+
+}
+
+
+void mem_check_full_group()
+{
+	unsigned long htab_size_bytes;
+	unsigned count;
+	unsigned count_array[] = {0,0,0,0,0,0,0,0,0}; 
+	unsigned i;
+	unsigned long htab_end;
+	HPTE *hpte1, *hpte2, *hpte3;
+	u64  rpn = 0;
+
+	htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
+	htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
+
+	printf("\nHardware Page Find full groups \n-------------------\n");
+	printf("htab base      : %.16lx\n", htab_data.htab);
+	printf("htab size      : %.16lx\n", htab_size_bytes);
+
+	for (hpte1 = htab_data.htab; (unsigned long)hpte1 < htab_end; hpte1= hpte1 + 8)
+	{
+		count = 0;
+		hpte2 = hpte1;
+		for (i=0; i<8; ++i)
+		{
+			if ( hpte2->dw0.dw0.v != 0 )
+			{
+				count++;
+			}
+			hpte2++;
+		}
+		if (count == 8 )
+		{
+			printf("  full group starting with entry %lx \n", hpte1);
+			hpte3 = hpte1;
+			for (i=0; i<8; ++i)
+			{
+				if ( hpte3->dw0.dw0.v != 0 )
+				{
+					printf(" entry number %d   \n",i);
+					printf("          vsid: %.13lx   api: %.2lx  hash: %.1lx\n", 
+					       (hpte3->dw0.dw0.avpn)>>5, 
+					       (hpte3->dw0.dw0.avpn) & 0x1f,
+					       (hpte3->dw0.dw0.h));
+					printf("          rpn: %.13lx \n", (hpte3->dw1.dw1.rpn)); 
+					// Dump out the memmap array entry address, corresponding virtual address, and reference count.
+					rpn = hpte3->dw1.dw1.rpn;
+					printf("          mem_map+rpn=%p, virtual@=%p, count=%lx \n", mem_map+rpn, (mem_map+rpn)->virtual, (mem_map+rpn)->count);
+				}
+				hpte3++;
+			}
+			if (xmon_interrupted())
+				return;
+		}
+
+		count_array[count]++;
+	}
+	for (i=1; i<9; ++i)
+	{
+		printf("  group count for size  %i = %lx \n", i, count_array[i]);
+	}
+
+	printf("\nDone -------------------\n");
+}
+
+static void debug_trace(void) {
+        unsigned long val, cmd, on;
+
+	cmd = skipbl();
+	if (cmd == '\n') {
+		/* show current state */
+		unsigned long i;
+		printf("naca->debug_switch = 0x%lx\n", naca->debug_switch);
+		for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
+			on = PPCDBG_BITVAL(i) & naca->debug_switch;
+			printf("%02x %s %12s   ", i, on ? "on " : "off",  trace_names[i] ? trace_names[i] : "");
+			if (((i+1) % 3) == 0)
+				printf("\n");
+		}
+		printf("\n");
+		return;
+	}
+	while (cmd != '\n') {
+		on = 1;	/* default if no sign given */
+		while (cmd == '+' || cmd == '-') {
+			on = (cmd == '+');
+			cmd = inchar();
+			if (cmd == ' ' || cmd == '\n') {  /* Turn on or off based on + or - */
+				naca->debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
+				printf("Setting all values to %s...\n", on ? "on" : "off");
+				if (cmd == '\n') return;
+				else cmd = skipbl(); 
+			}
+			else
+				termch = cmd;
+		}
+		termch = cmd;	/* not +/- ... let scanhex see it */
+		scanhex((void *)&val);
+		if (val >= 64) {
+			printf("Value %x out of range:\n", val);
+			return;
+		}
+		if (on) {
+			naca->debug_switch |= PPCDBG_BITVAL(val);
+			printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
+		} else {
+			naca->debug_switch &= ~PPCDBG_BITVAL(val);
+			printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
+		}
+		cmd = skipbl();
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/Makefile linux/arch/s390/Makefile
--- linux.orig/arch/s390/Makefile	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -60,6 +60,7 @@
 
 archclean:
 	@$(MAKEBOOT) clean
+	$(MAKE) -C arch/$(ARCH)/kernel clean
 
 archmrproper:
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/boot/install.sh linux/arch/s390/boot/install.sh
--- linux.orig/arch/s390/boot/install.sh	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/s390/boot/install.sh	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# arch/s390x/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+#
+# "make install" script for s390 architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
+if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
+
+# Default install - same as make zlilo
+
+if [ -f $4/vmlinuz ]; then
+	mv $4/vmlinuz $4/vmlinuz.old
+fi
+
+if [ -f $4/System.map ]; then
+	mv $4/System.map $4/System.old
+fi
+
+cat $2 > $4/vmlinuz
+cp $3 $4/System.map
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/config.in linux/arch/s390/config.in
--- linux.orig/arch/s390/config.in	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/config.in	2002-07-20 01:08:29.000000000 +0000
@@ -7,8 +7,8 @@
 define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
 define_bool CONFIG_UID16 y
-define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
-define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
 define_bool CONFIG_GENERIC_BUST_SPINLOCK n
 
 mainmenu_name "Linux Kernel Configuration"
@@ -37,6 +37,8 @@
 mainmenu_option next_comment
 comment 'General setup'
 bool 'Fast IRQ handling' CONFIG_FAST_IRQ
+bool 'Process warning machine checks' CONFIG_MACHCHK_WARNING
+bool 'Use chscs for Common I/O' CONFIG_CHSC
 bool 'Builtin IPL record support' CONFIG_IPL
 if [ "$CONFIG_IPL" = "y" ]; then
   choice 'IPL method generated into head.S' \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/defconfig linux/arch/s390/defconfig
--- linux.orig/arch/s390/defconfig	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/defconfig	2002-07-20 01:08:31.000000000 +0000
@@ -5,8 +5,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 # CONFIG_GENERIC_BUST_SPINLOCK is not set
 CONFIG_ARCH_S390=y
 
@@ -131,8 +131,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -144,10 +142,10 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 CONFIG_IPV6=m
-# CONFIG_IPV6_NETLINK is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -165,7 +163,7 @@
 # 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_FASTROUTE=y
 # CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/Makefile linux/arch/s390/kernel/Makefile
--- linux.orig/arch/s390/kernel/Makefile	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/s390/kernel/Makefile	2002-07-20 01:08:40.000000000 +0000
@@ -8,9 +8,9 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 .S.o:
-	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
 
-all: kernel.o head.o init_task.o
+all: asm-offsets.h kernel.o head.o init_task.o
 
 O_TARGET := kernel.o
 
@@ -27,5 +27,29 @@
 #
 obj-$(CONFIG_REMOTE_DEBUG)	+= gdb-stub.o #gdb-low.o 
 
+.PHONY: asm-offsets.h
+
+entry.S: asm-offsets.h
+
+#
+# Automatic offset generation for assembler files.
+#
+asm-offsets.h: asm-offsets.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -S $< -o - | grep -- "->" | \
+	(echo "#ifndef __ASM_OFFSETS_H__"; \
+	 echo "#define __ASM_OFFSETS_H__"; \
+	 echo "/*"; \
+	 echo " * DO NOT MODIFY"; \
+	 echo " *"; \
+	 echo " * This file was generated by arch/s390/kernel/Makefile"; \
+	 echo " */"; \
+	 sed -e "s:^->\([^ ]*\) \([^ ]*\) \(.*\):#define \\1 \\2 /* \\3*/:" \
+	     -e "s:->::"; \
+	 echo "#endif" \
+	) > asm-offsets.h
+
+clean:
+	rm -f asm-offsets.h
+
 include $(TOPDIR)/Rules.make
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/asm-offsets.c linux/arch/s390/kernel/asm-offsets.c
--- linux.orig/arch/s390/kernel/asm-offsets.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/s390/kernel/asm-offsets.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+
+/* Use marker if you need to separate the values later */
+
+#define DEFINE(sym, val, marker) \
+	asm volatile("\n->" #sym " %0 " #val " " #marker : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+	DEFINE(__THREAD_ar2, offsetof(struct task_struct, thread.ar2),);
+	DEFINE(__THREAD_ar4, offsetof(struct task_struct, thread.ar4),);
+	DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp),);
+	DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info),);
+	BLANK();
+	DEFINE(__TASK_state, offsetof(struct task_struct, state),);
+	DEFINE(__TASK_sigpending, offsetof(struct task_struct, sigpending),);
+	DEFINE(__TASK_need_resched,
+	       offsetof(struct task_struct, need_resched),);
+	DEFINE(__TASK_ptrace, offsetof(struct task_struct, ptrace),);
+	DEFINE(__TASK_processor, offsetof(struct task_struct, processor),);
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/debug.c linux/arch/s390/kernel/debug.c
--- linux.orig/arch/s390/kernel/debug.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/debug.c	2002-07-20 01:08:25.000000000 +0000
@@ -443,7 +443,6 @@
 {
 	size_t count = 0;
 	size_t entry_offset, size = 0;
-	int rc;
 	file_private_info_t *p_info;
 
 	p_info = ((file_private_info_t *) file->private_data);
@@ -459,9 +458,9 @@
 		size = MIN((len - count), (size - entry_offset));
 
 		if(size){
-			if ((rc = copy_to_user(user_buf + count, 
-					p_info->temp_buf + entry_offset, size)))
-			return rc;
+			if (copy_to_user(user_buf + count, 
+					p_info->temp_buf + entry_offset, size))
+				return count ? count: -EFAULT;
 		}
 		count += size;
 		entry_offset = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S
--- linux.orig/arch/s390/kernel/entry.S	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/entry.S	2002-07-20 01:08:27.000000000 +0000
@@ -18,6 +18,8 @@
 #include <asm/smp.h>
 #include <asm/ptrace.h>
 
+#include "asm-offsets.h"
+
 /*
  * Stack layout for the system_call stack entry.
  * The first few entries are identical to the user_regs_struct.
@@ -44,42 +46,7 @@
 SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + PT_ORIGGPR2
 /* Now the additional entries */
 SP_TRAP      =  (SP_ORIG_R2+GPR_SIZE)
-#if CONFIG_REMOTE_DEBUG
-SP_CRREGS    =  (SP_TRAP+4)
-/* fpu registers are saved & restored by the gdb stub itself */
-SP_FPC       =  (SP_CRREGS+(NUM_CRS*CR_SIZE))
-SP_FPRS      =  (SP_FPC+FPC_SIZE+FPC_PAD_SIZE)
-SP_PGM_OLD_ILC= (SP_FPRS+(NUM_FPRS*FPR_SIZE))
-#else
-SP_PGM_OLD_ILC= (SP_TRAP+4)
-#endif
-SP_SIZE      =  (SP_PGM_OLD_ILC+4)
-/*
- * these defines are offsets into the thread_struct
- */
-_TSS_PTREGS  = 0
-_TSS_FPRS    = (_TSS_PTREGS+8)
-_TSS_AR2     = (_TSS_FPRS+136)
-_TSS_AR4     = (_TSS_AR2+4)
-_TSS_KSP     = (_TSS_AR4+4)
-_TSS_USERSEG = (_TSS_KSP+4)
-_TSS_ERROR   = (_TSS_USERSEG+4)
-_TSS_PROT    = (_TSS_ERROR+4)
-_TSS_TRAP    = (_TSS_PROT+4)
-_TSS_MM      = (_TSS_TRAP+4)
-_TSS_PER     = (_TSS_MM+8)
-_TSS_IEEE    = (_TSS_PER+36)
-_TSS_FLAGS   = (_TSS_IEEE+4)
-
-/*
- * these are offsets into the task-struct.
- */
-state        =  0
-flags        =  4
-sigpending   =  8
-need_resched = 24
-tsk_ptrace   = 28
-processor    = 52
+SP_SIZE      =  (SP_TRAP+4)
 
 /*
  * Base Address of this Module --- saved in __LC_ENTRY_BASE
@@ -97,12 +64,15 @@
  *    R15 - kernel stack pointer
  */
 
-        .macro  SAVE_ALL psworg,sync      # system entry macro
+        .macro  SAVE_ALL_BASE
         stm     %r13,%r15,__LC_SAVE_AREA
         basr    %r13,0                    #  temp base pointer
-        l       %r13,.Lentry_base-.(%r13) # load &entry_base to %r13 
+0:	stam    %a2,%a4,__LC_SAVE_AREA+12
+        l       %r13,.Lentry_base-0b(%r13)# load &entry_base to %r13
+	.endm
+
+        .macro  SAVE_ALL psworg,sync      # system entry macro
         tm      \psworg+1,0x01            # test problem state bit
-        stam    %a2,%a4,__LC_SAVE_AREA+12
 	.if	\sync
         bz      BASED(1f)                 # skip stack setup save
 	.else
@@ -146,8 +116,8 @@
 
 /*
  * Scheduler resume function, called by switch_to
- *  grp2 = (thread_struct *) prev->tss
- *  grp3 = (thread_struct *) next->tss
+ *  gpr2 = (task_struct *) prev
+ *  gpr3 = (task_struct *) next
  * Returns:
  *  gpr2 = prev
  */
@@ -155,30 +125,24 @@
 resume:
         basr    %r1,0
 resume_base:
-        l       %r4,_TSS_PTREGS(%r3)
-        tm      SP_PSW-SP_PTREGS(%r4),0x40 # is the new process using per ?
-        bz      resume_noper-resume_base(%r1) # if not we're fine
-        stctl   %c9,%c11,24(%r15)             # We are using per stuff
-        clc     _TSS_PER(12,%r3),24(%r15)
-        be      resume_noper-resume_base(%r1) # we got away w/o bashing TLB's
-        lctl    %c9,%c11,_TSS_PER(%r3)        # Nope we didn't
+	tm	__THREAD_per(%r3),0xe8		# new process is using per ?
+	bz	resume_noper-resume_base(%r1)	# if not we're fine
+        stctl   %c9,%c11,24(%r15)		# We are using per stuff
+        clc     __THREAD_per(12,%r3),24(%r15)
+        be      resume_noper-resume_base(%r1)	# we got away w/o bashing TLB's
+        lctl    %c9,%c11,__THREAD_per(%r3)	# Nope we didn't
 resume_noper:
         stm     %r6,%r15,24(%r15)       # store resume registers of prev task
-        st      %r15,_TSS_KSP(%r2) # store kernel stack ptr to prev->tss.ksp
-        lr      %r0,%r15
-        n       %r0,.Lc0xffffe000-resume_base(%r1)
-        l       %r15,_TSS_KSP(%r3) # load kernel stack ptr from next->tss.ksp
-        l       %r1,.Lc8191-resume_base(%r1)
-        or      %r1,%r15
-        la      %r1,1(%r1)
-        st      %r1,__LC_KERNEL_STACK   # __LC_KERNEL_STACK = new kernel stack
-        stam    %a2,%a2,_TSS_AR2(%r2)   # store kernel access reg. 2
-        stam    %a4,%a4,_TSS_AR4(%r2)   # store kernel access reg. 4
-        lam     %a2,%a2,_TSS_AR2(%r3)   # load kernel access reg. 2
-        lam     %a4,%a4,_TSS_AR4(%r3)   # load kernel access reg. 4
-        lr      %r2,%r0                 # return task_struct of last task
-        lm      %r6,%r15,24(%r15)       # load resume registers of next task
-        br      %r14
+	st	%r15,__THREAD_ksp(%r2)	# store kernel stack to prev->tss.ksp
+	l	%r15,__THREAD_ksp(%r3)	# load kernel stack from next->tss.ksp
+	stam    %a2,%a2,__THREAD_ar2(%r2)	# store kernel access reg. 2
+	stam    %a4,%a4,__THREAD_ar4(%r2)	# store kernel access reg. 4
+	lam     %a2,%a2,__THREAD_ar2(%r3)	# load kernel access reg. 2
+	lam     %a4,%a4,__THREAD_ar4(%r3)	# load kernel access reg. 4
+	lm	%r6,%r15,24(%r15)	# load resume registers of next task
+	ahi	%r3,8192
+	st	%r3,__LC_KERNEL_STACK	# __LC_KERNEL_STACK = new kernel stack
+	br	%r14
 
 /*
  * do_softirq calling function. We want to run the softirq functions on the
@@ -209,16 +173,14 @@
 
 	.globl  system_call
 system_call:
+	SAVE_ALL_BASE
         SAVE_ALL __LC_SVC_OLD_PSW,1
-	mvi     SP_PGM_OLD_ILC(%r15),1  # mark PGM_OLD_ILC as invalid
-pgm_system_call:	
+	lh	%r8,0x8a	  # get svc number from lowcore
+        sll     %r8,2
         GET_CURRENT               # load pointer to task_struct to R9
-        slr     %r8,%r8           # gpr 8 is call save (-> tracesys)
-        ic      %r8,0x8B          # get svc number from lowcore
         stosm   24(%r15),0x03     # reenable interrupts
-        sll     %r8,2
-        l       %r8,sys_call_table-entry_base(8,%r13) # get address of system call
-        tm      tsk_ptrace+3(%r9),0x02 # PT_TRACESYS
+        l       %r8,sys_call_table-entry_base(%r8,%r13) # get system call addr.
+        tm      __TASK_ptrace+3(%r9),0x02 # PT_TRACESYS
         bnz     BASED(sysc_tracesys)
         basr    %r14,%r8          # call sys_xxxx
         st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
@@ -231,14 +193,12 @@
 #
 # check, if reschedule is needed
 #
-        icm     %r0,15,need_resched(%r9) # get need_resched from task_struct
+        icm     %r0,15,__TASK_need_resched(%r9)
         bnz     BASED(sysc_reschedule)
-        icm     %r0,15,sigpending(%r9)   # get sigpending from task_struct
+        icm     %r0,15,__TASK_sigpending(%r9)
         bnz     BASED(sysc_signal_return)
 sysc_leave:
-	tm      SP_PGM_OLD_ILC(%r15),0xff
-        bz      BASED(pgm_svcret)
-	stnsm   24(%r15),0xfc            # disable I/O and ext. interrupts
+	stnsm   24(%r15),0xfc     # disable I/O and ext. interrupts
         RESTORE_ALL 1
 
 #
@@ -250,39 +210,42 @@
         l       %r1,BASED(.Ldo_signal)
 	la      %r14,BASED(sysc_leave)
         br      %r1               # return point is sysc_leave
-
+#
+# call schedule with sysc_return as return-address
+#
+sysc_reschedule:        
+        l       %r1,BASED(.Lschedule)
+	la      %r14,BASED(sysc_return)
+        br      %r1               # call scheduler, return to sysc_return
 #
 # call trace before and after sys_call
 #
 sysc_tracesys:
+	la	%r12,BASED(sysc_return)
+
+#
+# call syscall_trace before and after system call
+# special linkage: %r12 contains the return address for trace_svc
+#
+trace_svc:
         l       %r1,BASED(.Ltrace)
 	l       %r7,BASED(.Lc_ENOSYS)
 	st      %r7,SP_R2(%r15)   # give sysc_trace an -ENOSYS retval
         basr    %r14,%r1
 	l       %r2,SP_R2(%r15)
-	cr      %r2,%r7 # compare with saved -ENOSYS
-	be      BASED(sysc_tracesys_dn1)
-	# strace wants to change the syscall
+	cr      %r2,%r7		  # compare with saved -ENOSYS
+	be      BASED(trace_svc_go) # strace changed the syscall ?
 	sll     %r2,24
 	srl     %r2,22
-        l       %r8,sys_call_table-entry_base(2,%r13) # get address of system call    
-sysc_tracesys_dn1:		
+        l       %r8,sys_call_table-entry_base(%r2,%r13) # get system call addr.
+trace_svc_go:
 	lm      %r3,%r6,SP_R3(%r15)
 	l       %r2,SP_ORIG_R2(%r15)
         basr    %r14,%r8          # call sys_xxx
         st      %r2,SP_R2(%r15)   # store return value
         l       %r1,BASED(.Ltrace)
-	la      %r14,BASED(sysc_return)
-        br      %r1               # return point is sysc_return
-
-
-#
-# call schedule with sysc_return as return-address
-#
-sysc_reschedule:        
-        l       %r1,BASED(.Lschedule)
-	la      %r14,BASED(sysc_return)
-        br      %r1               # call scheduler, return to sysc_return
+	lr	%r14,%r12	  # return point is in %r12
+        br      %r1
 
 #
 # a new process exits the kernel with ret_from_fork
@@ -295,13 +258,9 @@
         stosm   24(%r15),0x03     # reenable interrupts
         sr      %r0,%r0           # child returns 0
         st      %r0,SP_R2(%r15)   # store return value (change R2 on stack)
-#ifdef CONFIG_SMP
         l       %r1,BASED(.Lschedtail)
 	la      %r14,BASED(sysc_return)
         br      %r1               # call schedule_tail, return to sysc_return
-#else
-        b       BASED(sysc_return)
-#endif
 
 #
 # clone, fork, vfork, exec and sigreturn need glue,
@@ -597,10 +556,23 @@
         .long  sys_madvise
 	.long  sys_getdents64		 /* 220 */
         .long  sys_fcntl64 
-	.long  sys_ni_syscall		 /* 222 - reserved for posix_acl */
-	.long  sys_ni_syscall		 /* 223 - reserved for posix_acl */
-	.long  sys_ni_syscall		 /* 224 - reserved for posix_acl */
-	.rept  255-224
+	.long  sys_ni_syscall
+	.long  sys_ni_syscall
+	.long  sys_ni_syscall		 /* 224 - reserved for setxattr  */
+	.long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
+	.long  sys_ni_syscall		 /* 226 - reserved for fsetxattr */
+	.long  sys_ni_syscall		 /* 227 - reserved for getxattr  */
+	.long  sys_ni_syscall		 /* 228 - reserved for lgetxattr */
+	.long  sys_ni_syscall		 /* 229 - reserved for fgetxattr */
+	.long  sys_ni_syscall		 /* 230 - reserved for listxattr */
+	.long  sys_ni_syscall		 /* 231 - reserved for llistxattr */
+	.long  sys_ni_syscall		 /* 232 - reserved for flistxattr */
+	.long  sys_ni_syscall		 /* 233 - reserved for removexattr */
+	.long  sys_ni_syscall		 /* 234 - reserved for lremovexattr */
+	.long  sys_ni_syscall		 /* 235 - reserved for fremovexattr */
+	.long  sys_gettid
+	.long  sys_tkill
+	.rept  255-237
 	.long  sys_ni_syscall
 	.endr
 
@@ -623,93 +595,91 @@
  * we just ignore the PER event (FIXME: is there anything we have to do
  * for LPSW?).
  */
-	stm     %r13,%r15,__LC_SAVE_AREA
-	basr    %r13,0                   # temp base pointer
-	l       %r13,.Lentry_base-.(%r13)# load &entry_base to %r13
+	SAVE_ALL_BASE
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
-	stam    %a2,%a4,__LC_SAVE_AREA+12
-        bz      BASED(pgm_sv)            # skip if not
+        bnz     BASED(pgm_per)           # got per exception -> special case
+	SAVE_ALL __LC_PGM_OLD_PSW,1
+        l       %r7,BASED(.Ljump_table)
+        lh      %r8,__LC_PGM_INT_CODE
+        sll     %r8,2
+	GET_CURRENT
+        l       %r7,0(%r8,%r7)		 # load address of handler routine
+        la      %r2,SP_PTREGS(%r15)	 # address of register-save area
+        l       %r3,__LC_PGM_ILC         # load program interruption code
+	la      %r14,BASED(sysc_return)
+	br      %r7			 # branch to interrupt-handler
+
+#
+# handle per exception
+#
+pgm_per:
         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
-        bnz     BASED(pgm_sv)            # skip if it is
+        bnz     BASED(pgm_per_std)       # ok, normal per event from user space
 # ok its one of the special cases, now we need to find out which one
         clc     __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
         be      BASED(pgm_svcper)
 # no interesting special case, ignore PER event
         lm      %r13,%r15,__LC_SAVE_AREA
 	lpsw    0x28
-# it was a single stepped SVC that is causing all the trouble
-pgm_svcper:
-        tm      0x21,0x01                # test problem state bit
-	bz	BASED(.+12)              # skip stack & access regs setup
-	l	%r15,__LC_KERNEL_STACK   # problem state -> load ksp
-	lam     %a2,%a4,BASED(.Lc_ac)    # set ac.reg. 2 to primary space
-                                         # and access reg. 4 to home space
-	s       %r15,BASED(.Lc_spsize)   # make room for registers & psw
-        n       %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
-        stm     %r0,%r12,SP_R0(%r15)     # store gprs 0-12 to kernel stack
-        st      %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
-        mvc     SP_R13(12,%r15),__LC_SAVE_AREA # move R13-R15 to stack
-        stam    %a0,%a15,SP_AREGS(%r15)  # store access registers to kst.
-	mvc     SP_AREGS+8(12,%r15),__LC_SAVE_AREA+12 # store ac. regs
-        mvc     SP_PSW(8,%r15),0x20      # move user PSW to stack
-        la      %r0,0x20                 # store trap indication
-        st      %r0,SP_TRAP(%r15)
-        xc      0(4,%r15),0(%r15)        # clear back chain
-        mvc     SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
-        b       BASED(pgm_system_call)   # now do the svc
-pgm_svcret:
-        mvi     SP_TRAP+3(%r15),0x28     # set trap indication back to pgm_chk
-        lh      %r7,SP_PGM_OLD_ILC(%r15) # get ilc from stack
-	mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
-	b       BASED(pgm_no_sv)
-pgm_sv:
-        tm      0x29,0x01                # test problem state bit
-	bz	BASED(.+12)              # skip stack & access regs setup
-	l	%r15,__LC_KERNEL_STACK   # problem state -> load ksp
-	lam     %a2,%a4,BASED(.Lc_ac)    # set ac.reg. 2 to primary space
-                                         # and access reg. 4 to home space
-	s       %r15,BASED(.Lc_spsize)   # make room for registers & psw
-        n       %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
-        stm     %r0,%r12,SP_R0(%r15)     # store gprs 0-12 to kernel stack
-        st      %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
-        mvc     SP_R13(12,%r15),__LC_SAVE_AREA # move R13-R15 to stack
-        stam    %a0,%a15,SP_AREGS(%r15)  # store access registers to kst.
-	mvc     SP_AREGS+8(12,%r15),__LC_SAVE_AREA+12 # store ac. regs
-        mvc     SP_PSW(8,%r15),0x28      # move user PSW to stack
-        la      %r0,0x28                 # store trap indication
-        st      %r0,SP_TRAP(%r15)
-        xc      0(4,%r15),0(%r15)        # clear back chain
-	mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
-        lh      %r7,__LC_PGM_ILC         # load instruction length
+
+#
+# Normal per exception
+#
+pgm_per_std:
+	SAVE_ALL __LC_PGM_OLD_PSW,1
 	GET_CURRENT
-pgm_no_sv:
-	la	%r3,0x7f
-        lh      %r8,__LC_PGM_INT_CODE  # N.B. saved int code used later KEEP it
-	nr      %r3,%r8           # reload & clear per-event-bit
-        be      BASED(pgm_dn)     # none of Martins exceptions occurred bypass
+	la	%r4,0x7f
+	l	%r3,__LC_PGM_ILC	 # load program interruption code
+        nr      %r4,%r3                  # clear per-event-bit and ilc
+        be      BASED(pgm_per_only)      # only per or per+check ?
         l       %r1,BASED(.Ljump_table)
-        sll     %r3,2
-        l       %r1,0(%r3,%r1)    # load address of handler routine
-        la      %r2,SP_PTREGS(%r15) # address of register-save area
-        srl     %r3,2
-        cl      %r3,BASED(.Lc4)   # protection-exception ?
-        bne     BASED(pgm_per)    # if not,
-        l       %r5,SP_PSW+4(15)  # load psw addr
-        sr      %r5,%r7           # substract ilc from psw
-        st      %r5,SP_PSW+4(15)  # store corrected psw addr
-pgm_per:basr    %r14,%r1          # branch to interrupt-handler
-pgm_dn: n	%r8,BASED(.Lc128) # check for per excepton
-        be      BASED(pgm_return)
-        la      %r2,SP_PTREGS(15) # address of register-save area
-        l       %r1,BASED(.Lhandle_per) # load adr. of per handler
-        la      %r14,BASED(sysc_return) # load adr. of system return
-        br      %r1               # branch to handle_per_exception
+        sll     %r4,2
+        l       %r1,0(%r4,%r1)		 # load address of handler routine
+        la      %r2,SP_PTREGS(%r15)	 # address of register-save area
+	basr    %r14,%r1		 # branch to interrupt-handler
+pgm_per_only:
+	la      %r2,SP_PTREGS(15)	 # address of register-save area
+        l       %r1,BASED(.Lhandle_per)  # load adr. of per handler
+        la      %r14,BASED(sysc_return)  # load adr. of system return
+        br      %r1			 # branch to handle_per_exception
+
+#
+# it was a single stepped SVC that is causing all the trouble
+#
+pgm_svcper:
+	SAVE_ALL __LC_SVC_OLD_PSW,1
+        GET_CURRENT               # load pointer to task_struct to R9
+	lh	%r8,0x8a	  # get svc number from lowcore
+        sll     %r8,2
+        stosm   24(%r15),0x03     # reenable interrupts
+        l       %r8,sys_call_table-entry_base(%r8,%r13) # get system call addr.
+        tm      __TASK_ptrace+3(%r9),0x02 # PT_TRACESYS
+        bnz     BASED(pgm_tracesys)
+        basr    %r14,%r8          # call sys_xxxx
+        st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
+                                  # ATTENTION: check sys_execve_glue before
+                                  # changing anything here !!
 
+pgm_svcret:
+        icm     %r0,15,__TASK_sigpending(%r9)
+        bz      BASED(pgm_svcper_nosig)
+	la	%r2,SP_PTREGS(%r15) # load pt_regs
+	sr	%r3,%r3		  # clear *oldset
+	l	%r1,BASED(.Ldo_signal)
+	basr	%r4,%r1		  # call do_signal
+	
+pgm_svcper_nosig:
+        mvi     SP_TRAP+3(%r15),0x28     # set trap indication to pgm check
+	la      %r2,SP_PTREGS(15)        # address of register-save area
+        l       %r1,BASED(.Lhandle_per)  # load adr. of per handler
+        la      %r14,BASED(sysc_return)  # load adr. of system return
+        br      %r1                      # branch to handle_per_exception
 #
-# the backend code is the same as for sys-call
+# call trace before and after sys_call
 #
-pgm_return:
-        b       BASED(sysc_return)
+pgm_tracesys:
+	la	%r12,BASED(pgm_svcret)
+	b	BASED(trace_svc)
 
 /*
  * IO interrupt handler routine
@@ -717,21 +687,22 @@
 
         .globl io_int_handler
 io_int_handler:
+	SAVE_ALL_BASE
         SAVE_ALL __LC_IO_OLD_PSW,0
         GET_CURRENT               # load pointer to task_struct to R9
+        l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ
         la      %r2,SP_PTREGS(%r15) # address of register-save area
         sr      %r3,%r3
-        icm     %r3,%r3,__LC_SUBCHANNEL_NR # load subchannel nr & extend to int
+        icm     %r3,3,__LC_SUBCHANNEL_NR   # load subchannel nr & extend to int
         l       %r4,__LC_IO_INT_PARM       # load interuption parm
 	l       %r5,__LC_IO_INT_WORD       # load interuption word
-        l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ
         basr    %r14,%r1          # branch to standard irq handler
 
 io_return:
 #
 # check, if bottom-half has to be done
 #
-        l       %r1,processor(%r9)    # get cpu number from task struture
+        l       %r1,__TASK_processor(%r9)
         sll     %r1,L1_CACHE_SHIFT
         al      %r1,BASED(.Lirq_stat) # get address of irq_stat
         icm     %r0,15,0(%r1)         # test irq_stat[#cpu].__softirq_pending
@@ -744,9 +715,9 @@
 #
 # check, if reschedule is needed
 #
-        icm     %r0,15,need_resched(%r9) # get need_resched from task_struct
+        icm     %r0,15,__TASK_need_resched(%r9)
         bnz     BASED(io_reschedule)
-        icm     %r0,15,sigpending(%r9)   # get sigpending from task_struct
+        icm     %r0,15,__TASK_sigpending(%r9)
         bnz     BASED(io_signal_return)
 io_leave:
         stnsm   24(%r15),0xfc            # disable I/O and ext. interrupts
@@ -784,6 +755,7 @@
 
         .globl  ext_int_handler
 ext_int_handler:
+	SAVE_ALL_BASE
         SAVE_ALL __LC_EXT_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
@@ -812,6 +784,7 @@
 
         .globl mcck_int_handler
 mcck_int_handler:
+	SAVE_ALL_BASE
         SAVE_ALL __LC_MCK_OLD_PSW,0
 	l       %r1,BASED(.Ls390_mcck)
 	basr    %r14,%r1	  # call machine check handler
@@ -894,7 +867,5 @@
 .Ltrace:       .long  syscall_trace
 .Lvfork:       .long  sys_vfork
 
-#ifdef CONFIG_SMP
 .Lschedtail:   .long  schedule_tail
-#endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/irq.c linux/arch/s390/kernel/irq.c
--- linux.orig/arch/s390/kernel/irq.c	2001-07-25 21:12:01.000000000 +0000
+++ linux/arch/s390/kernel/irq.c	2002-07-20 01:08:37.000000000 +0000
@@ -59,60 +59,6 @@
 BUILD_SMP_INTERRUPT(spurious_interrupt)
 #endif
 
-#if 0
-int get_irq_list(char *buf)
-{
-	int i, j;
-	struct irqaction * action;
-	char *p = buf;
-
-	p += sprintf(p, "           ");
-
-	for (j=0; j<smp_num_cpus; j++)
-		p += sprintf(p, "CPU%d       ",j);
-
-	*p++ = '\n';
-
-	for (i = 0 ; i < NR_IRQS ; i++)
-	{
-		if (ioinfo[i] == INVALID_STORAGE_AREA)
-			continue;
-
-		action = ioinfo[i]->irq_desc.action;
-		
-  		if (!action)
-			continue;
-
-		p += sprintf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
-		p += sprintf(p, "%10u ", kstat_irqs(i));
-#else
-		for (j=0; j<smp_num_cpus; j++)
-			p += sprintf( p, "%10u ",
-			              kstat.irqs[cpu_logical_map(j)][i]);
-#endif
-		p += sprintf(p, " %14s", ioinfo[i]->irq_desc.handler->typename);
-		p += sprintf(p, "  %s", action->name);
-
-		for (action=action->next; action; action = action->next)
-		{
-			p += sprintf(p, ", %s", action->name);
-
-		} /* endfor */
-
-		*p++ = '\n';
-	
-	} /* endfor */
-
-	p += sprintf(p, "NMI: %10u\n", nmi_counter);
-#ifdef CONFIG_SMP
-	p += sprintf(p, "IPI: %10u\n", atomic_read(&ipi_count));
-#endif
-
-	return p - buf;
-}
-#endif
-
 /*
  * Global interrupt locks for SMP. Allow interrupts to come in on any
  * CPU, yet make cli/sti act globally to protect critical regions..
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c
--- linux.orig/arch/s390/kernel/process.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/process.c	2002-07-20 01:08:29.000000000 +0000
@@ -50,28 +50,40 @@
  * The idle loop on a S390...
  */
 
-static psw_t wait_psw;
-
 int cpu_idle(void *unused)
 {
+	psw_t wait_psw;
+	unsigned long reg;
+
 	/* endless idle loop with no priority at all */
         init_idle();
 	current->nice = 20;
 	current->counter = -100;
-	wait_psw.mask = _WAIT_PSW_MASK;
-	wait_psw.addr = (unsigned long) &&idle_wakeup | 0x80000000L;
-	while(1) {
-                if (current->need_resched) {
-                        schedule();
-                        check_pgt_cache();
-                        continue;
-                }
+	while (1) {
+		if (current->need_resched) {
+			schedule();
+			check_pgt_cache();
+			continue;
+		}
 
-		/* load wait psw */
+		/* 
+		 * Wait for external, I/O or machine check interrupt and
+		 * switch of machine check bit after the wait has ended.
+		 */
+		wait_psw.mask = _WAIT_PSW_MASK;
 		asm volatile (
-                        "lpsw %0"
-                        : : "m" (wait_psw) );
-idle_wakeup:
+			"    basr %0,0\n"
+			"0:  la   %0,1f-0b(%0)\n"
+			"    st   %0,4(%1)\n"
+			"    oi   4(%1),0x80\n"
+			"    lpsw 0(%1)\n"
+			"1:  la   %0,2f-1b(%0)\n"
+			"    st   %0,4(%1)\n"
+			"    oi   4(%1),0x80\n"
+			"    ni   1(%1),0xf9\n"
+			"    lpsw 0(%1)\n"
+			"2:"
+			: "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
 	}
 }
 
@@ -166,11 +178,9 @@
 
         /* fake return stack for resume(), don't go back to schedule */
         frame->gprs[9]  = (unsigned long) frame;
-	frame->childregs.old_ilc = -1; /* We are not single stepping an svc */
         /* save fprs, if used in last task */
 	save_fp_regs(&p->thread.fp_regs);
         p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _SEGMENT_TABLE;
-        p->thread.fs = USER_DS;
         /* Don't copy debug registers */
         memset(&p->thread.per_info,0,sizeof(p->thread.per_info));
         return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/ptrace.c linux/arch/s390/kernel/ptrace.c
--- linux.orig/arch/s390/kernel/ptrace.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/ptrace.c	2002-07-20 01:08:32.000000000 +0000
@@ -341,9 +341,11 @@
 		break;
 	case PTRACE_PEEKUSR_AREA:
 	case PTRACE_POKEUSR_AREA:
-		if((ret=copy_from_user(&parea,(void *)addr,sizeof(parea)))==0)  
-		   ret=copy_user(child,parea.kernel_addr,parea.process_addr,
+		if(copy_from_user(&parea,(void *)addr,sizeof(parea))==0)  
+			ret=copy_user(child,parea.kernel_addr,parea.process_addr,
 				 parea.len,1,(request==PTRACE_POKEUSR_AREA));
+		else
+			ret = -EFAULT;
 		break;
 	default:
 		ret = -EIO;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/reipl.S linux/arch/s390/kernel/reipl.S
--- linux.orig/arch/s390/kernel/reipl.S	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/s390/kernel/reipl.S	2002-07-20 01:08:22.000000000 +0000
@@ -21,8 +21,10 @@
 	        oi      .Lschib+5-.Lpg0(%r13),0x84 
 .Lecs:  	xi      .Lschib+27-.Lpg0(%r13),0x01 
         	msch    .Lschib-.Lpg0(%r13) 
-		ssch	.Liplorb-.Lpg0(%r13)           
-		jz	.L001   
+                lhi     %r0,5
+.Lssch:		ssch	.Liplorb-.Lpg0(%r13)           
+		jz	.L001
+                brct    %r0,.Lssch  
 		bas	%r14,.Ldisab-.Lpg0(%r13)
 .L001:		mvc	__LC_IO_NEW_PSW(8),.Lionew-.Lpg0(%r13)	
 .Ltpi:		lpsw	.Lwaitpsw-.Lpg0(%r13)          
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/s390_ksyms.c linux/arch/s390/kernel/s390_ksyms.c
--- linux.orig/arch/s390/kernel/s390_ksyms.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/s390_ksyms.c	2002-07-20 01:08:24.000000000 +0000
@@ -5,6 +5,7 @@
  */
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/smp.h>
 #include <asm/checksum.h>
 #include <asm/delay.h>
 #include <asm/setup.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/setup.c linux/arch/s390/kernel/setup.c
--- linux.orig/arch/s390/kernel/setup.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/setup.c	2002-07-20 01:08:25.000000000 +0000
@@ -48,7 +48,7 @@
 unsigned int console_device = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
-struct { unsigned long addr, size, type; } memory_chunk[16];
+struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } };
 #define CHUNK_READ_WRITE 0
 #define CHUNK_READ_ONLY 1
 __u16 boot_cpu_addr;
@@ -284,8 +284,8 @@
          * print what head.S has found out about the machine 
          */
 	printk((MACHINE_IS_VM) ?
-	       "We are running under VM\n" :
-	       "We are running native\n");
+	       "We are running under VM (31 bit mode)\n" :
+	       "We are running native (31 bit mode)\n");
 	printk((MACHINE_HAS_IEEE) ?
 	       "This machine has an IEEE fpu\n" :
 	       "This machine has no IEEE fpu\n");
@@ -494,9 +494,9 @@
 			       "bogomips per cpu: %lu.%02lu\n",
 			       smp_num_cpus, loops_per_jiffy/(500000/HZ),
 			       (loops_per_jiffy/(5000/HZ))%100);
-	} 
+	}
 	if (cpu_online_map & (1 << n)) {
-		cpuinfo = &safe_get_cpu_lowcore(n).cpu_data;
+		cpuinfo = &safe_get_cpu_lowcore(n)->cpu_data;
 		seq_printf(m, "processor %i: "
 			       "version = %02X,  "
 			       "identification = %06X,  "
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/signal.c linux/arch/s390/kernel/signal.c
--- linux.orig/arch/s390/kernel/signal.c	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/s390/kernel/signal.c	2002-07-20 01:08:29.000000000 +0000
@@ -563,10 +563,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/s390/kernel/smp.c linux/arch/s390/kernel/smp.c
--- linux.orig/arch/s390/kernel/smp.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/smp.c	2002-07-20 01:08:22.000000000 +0000
@@ -191,7 +191,8 @@
 {
         if (smp_processor_id() != 0) {
                 smp_ext_bitcall(0, ec_restart);
-                for (;;);
+		for (;;)
+			enabled_wait();
         } else
                 do_machine_restart();
 }
@@ -208,7 +209,8 @@
 {
         if (smp_processor_id() != 0) {
                 smp_ext_bitcall(0, ec_halt);
-                for (;;);
+		for (;;)
+			enabled_wait();
         } else
                 do_machine_halt();
 }
@@ -225,7 +227,8 @@
 {
         if (smp_processor_id() != 0) {
                 smp_ext_bitcall(0, ec_power_off);
-                for (;;);
+		for (;;)
+			enabled_wait();
         } else
                 do_machine_power_off();
 }
@@ -267,7 +270,7 @@
  */
 static sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
 {
-        struct _lowcore *lowcore = &get_cpu_lowcore(cpu);
+        struct _lowcore *lowcore = get_cpu_lowcore(cpu);
         sigp_ccode ccode;
 
         /*
@@ -291,12 +294,13 @@
         for (i = 0; i < smp_num_cpus; i++) {
                 if (smp_processor_id() == i)
                         continue;
-                lowcore = &get_cpu_lowcore(i);
+                lowcore = get_cpu_lowcore(i);
                 /*
                  * Set signaling bit in lowcore of target cpu and kick it
                  */
                 atomic_set_mask(1<<sig, &lowcore->ext_call_fast);
-                ccode = signal_processor(i, sigp_external_call);
+                while (signal_processor(i, sigp_external_call) == sigp_busy)
+			udelay(10);
         }
 }
 
@@ -313,7 +317,7 @@
 
         /* write magic number to zero page (absolute 0) */
 
-        get_cpu_lowcore(smp_processor_id()).panic_magic = __PANIC_MAGIC;
+        get_cpu_lowcore(smp_processor_id())->panic_magic = __PANIC_MAGIC;
 
         /* stop all processors */
 
@@ -335,7 +339,7 @@
         for (i =  0; i < smp_num_cpus; i++) {
                 if (smp_processor_id() != i) {
                         int ccode;
-                        low_core_addr = (unsigned long)&get_cpu_lowcore(i);
+                        low_core_addr = (unsigned long)get_cpu_lowcore(i);
                         do {
                                 ccode = signal_processor_ps(
                                    &dummy,
@@ -479,7 +483,7 @@
         /* Setup the cpu */
         cpu_init();
         /* Print info about this processor */
-        print_cpu_info(&safe_get_cpu_lowcore(smp_processor_id()).cpu_data);
+        print_cpu_info(&safe_get_cpu_lowcore(smp_processor_id())->cpu_data);
         /* Wait for completion of smp startup */
         while (!atomic_read(&smp_commenced))
                 /* nothing */ ;
@@ -535,7 +539,7 @@
         unhash_process(idle);
         init_tasks[cpu] = idle;
 
-        cpu_lowcore=&get_cpu_lowcore(cpu);
+        cpu_lowcore = get_cpu_lowcore(cpu);
 	cpu_lowcore->save_area[15] = idle->thread.ksp;
 	cpu_lowcore->kernel_stack = (__u32) idle + 8192;
         __asm__ __volatile__("la    1,%0\n\t"
@@ -589,7 +593,7 @@
         /*
          *      Initialize the logical to physical CPU number mapping
          */
-        print_cpu_info(&safe_get_cpu_lowcore(0).cpu_data);
+        print_cpu_info(&safe_get_cpu_lowcore(0)->cpu_data);
 
         for(i = 0; i < smp_num_cpus; i++)
         {
@@ -642,3 +646,4 @@
 EXPORT_SYMBOL(smp_ctl_set_bit);
 EXPORT_SYMBOL(smp_ctl_clear_bit);
 EXPORT_SYMBOL(smp_num_cpus);
+EXPORT_SYMBOL(smp_call_function);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/time.c linux/arch/s390/kernel/time.c
--- linux.orig/arch/s390/kernel/time.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/time.c	2002-07-20 01:08:22.000000000 +0000
@@ -82,7 +82,7 @@
 {
 	__u64 now;
 
-	asm ("STCK %0" : "=m" (now));
+	asm ("STCK 0(%0)" : : "a" (&now) : "memory", "cc");
         now = (now - init_timer_cc) >> 12;
 	/* We require the offset from the latest update of xtime */
 	now -= (__u64) wall_jiffies*USECS_PER_JIFFY;
@@ -200,9 +200,10 @@
 	int cc;
 
         /* kick the TOD clock */
-        asm volatile ("STCK %1\n\t"
+        asm volatile ("STCK 0(%1)\n\t"
                       "IPM  %0\n\t"
-                      "SRL  %0,28" : "=r" (cc), "=m" (init_timer_cc));
+                      "SRL  %0,28" : "=r" (cc) : "a" (&init_timer_cc) 
+				   : "memory", "cc");
         switch (cc) {
         case 0: /* clock in set state: all is fine */
                 break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/kernel/traps.c linux/arch/s390/kernel/traps.c
--- linux.orig/arch/s390/kernel/traps.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390/kernel/traps.c	2002-07-20 01:08:32.000000000 +0000
@@ -50,7 +50,9 @@
 #endif
 #endif
 
-extern pgm_check_handler_t do_page_fault;
+extern pgm_check_handler_t do_protection_exception;
+extern pgm_check_handler_t do_segment_exception;
+extern pgm_check_handler_t do_page_exception;
 extern pgm_check_handler_t do_pseudo_page_fault;
 #ifdef CONFIG_PFAULT
 extern int pfault_init(void);
@@ -269,23 +271,6 @@
         do_exit(SIGSEGV);
 }
 
-#define DO_ERROR(signr, str, name) \
-asmlinkage void name(struct pt_regs * regs, long interruption_code) \
-{ \
-	do_trap(interruption_code, signr, str, regs, NULL); \
-}
-
-#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \
-asmlinkage void name(struct pt_regs * regs, long interruption_code) \
-{ \
-        siginfo_t info; \
-        info.si_signo = signr; \
-        info.si_errno = 0; \
-        info.si_code = sicode; \
-        info.si_addr = (void *)siaddr; \
-        do_trap(interruption_code, signr, str, regs, &info); \
-}
-
 static void inline do_trap(long interruption_code, int signr, char *str,
                            struct pt_regs *regs, siginfo_t *info)
 {
@@ -299,7 +284,7 @@
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
                 struct task_struct *tsk = current;
 
-                tsk->thread.trap_no = interruption_code;
+                tsk->thread.trap_no = interruption_code & 0xffff;
 		if (info)
 			force_sig_info(signr, info, tsk);
 		else
@@ -326,6 +311,11 @@
         }
 }
 
+static inline void *get_check_address(struct pt_regs *regs)
+{
+	return (void *) ADDR_BITS_REMOVE(regs->psw.addr-S390_lowcore.pgm_ilc);
+}
+
 int do_debugger_trap(struct pt_regs *regs,int signal)
 {
 	if(regs->psw.mask&PSW_PROBLEM_STATE)
@@ -349,14 +339,68 @@
 	return 0;
 }
 
+#define DO_ERROR(signr, str, name) \
+asmlinkage void name(struct pt_regs * regs, long interruption_code) \
+{ \
+	do_trap(interruption_code, signr, str, regs, NULL); \
+}
+
+#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \
+asmlinkage void name(struct pt_regs * regs, long interruption_code) \
+{ \
+        siginfo_t info; \
+        info.si_signo = signr; \
+        info.si_errno = 0; \
+        info.si_code = sicode; \
+        info.si_addr = (void *)siaddr; \
+        do_trap(interruption_code, signr, str, regs, &info); \
+}
+
 DO_ERROR(SIGSEGV, "Unknown program exception", default_trap_handler)
-DO_ERROR(SIGILL,  "privileged operation", privileged_op)
-DO_ERROR(SIGILL,  "execute exception", execute_exception)
-DO_ERROR(SIGSEGV, "addressing exception", addressing_exception)
-DO_ERROR(SIGFPE,  "fixpoint divide exception", divide_exception)
-DO_ERROR(SIGILL,  "translation exception", translation_exception)
-DO_ERROR(SIGILL,  "special operand exception", special_op_exception)
-DO_ERROR(SIGILL,  "operand exception", operand_exception)
+
+DO_ERROR_INFO(SIGBUS, "addressing exception", addressing_exception,
+	      BUS_ADRERR, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "execute exception", execute_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+DO_ERROR_INFO(SIGFPE,  "fixpoint divide exception", divide_exception,
+	      FPE_INTDIV, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "operand exception", operand_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "privileged operation", privileged_op,
+	      ILL_PRVOPC, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "special operation exception", special_op_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "translation exception", translation_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+
+static inline void
+do_fp_trap(struct pt_regs *regs, void *location,
+           int fpc, long interruption_code)
+{
+	siginfo_t si;
+
+	si.si_signo = SIGFPE;
+	si.si_errno = 0;
+	si.si_addr = location;
+	si.si_code = 0;
+	/* FPC[2] is Data Exception Code */
+	if ((fpc & 0x00000300) == 0) {
+		/* bits 6 and 7 of DXC are 0 iff IEEE exception */
+		if (fpc & 0x8000) /* invalid fp operation */
+			si.si_code = FPE_FLTINV;
+		else if (fpc & 0x4000) /* div by 0 */
+			si.si_code = FPE_FLTDIV;
+		else if (fpc & 0x2000) /* overflow */
+			si.si_code = FPE_FLTOVF;
+		else if (fpc & 0x1000) /* underflow */
+			si.si_code = FPE_FLTUND;
+		else if (fpc & 0x0800) /* inexact */
+			si.si_code = FPE_FLTRES;
+	}
+	current->thread.ieee_instruction_pointer = (addr_t) location;
+	do_trap(interruption_code, SIGFPE,
+		"floating point exception", regs, &si);
+}
 
 asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
 {
@@ -407,11 +451,10 @@
 #endif 
 	else
 		signal = SIGILL;
-        if (signal == SIGFPE) {
-		current->thread.ieee_instruction_pointer = (addr_t) location;
-		do_trap(interruption_code, signal,
-			"floating point exception", regs, NULL);
-        } else if (signal)
+        if (signal == SIGFPE)
+		do_fp_trap(regs, location,
+                           current->thread.fp_regs.fpc, interruption_code);
+        else if (signal)
 		do_trap(interruption_code, signal,
 			"illegal operation", regs, NULL);
 }
@@ -426,7 +469,7 @@
 	__u16 *location = NULL;
 	int signal = 0;
 
-	location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
+	location = (__u16 *) get_check_address(regs);
 
 	/*
 	 * We got all needed information from the lowcore and can
@@ -466,16 +509,22 @@
                 }
         } else
 		signal = SIGILL;
-        if (signal == SIGFPE) {
-		current->thread.ieee_instruction_pointer = (addr_t) location;
-		do_trap(interruption_code, signal,
-			"floating point exception", regs, NULL);
-        } else if (signal)
-                do_trap(interruption_code, signal,
-			"specification exception", regs, NULL);
+        if (signal == SIGFPE)
+		do_fp_trap(regs, location,
+                           current->thread.fp_regs.fpc, interruption_code);
+        else if (signal) {
+		siginfo_t info;
+		info.si_signo = signal;
+		info.si_errno = 0;
+		info.si_code = ILL_ILLOPN;
+		info.si_addr = location;
+		do_trap(interruption_code, signal, 
+			"specification exception", regs, &info);
+	}
 }
 #else
-DO_ERROR(SIGILL, "specification exception", specification_exception)
+DO_ERROR_INFO(SIGILL, "specification exception", specification_exception,
+	      ILL_ILLOPN, get_check_address(regs));
 #endif
 
 asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
@@ -484,7 +533,7 @@
 	__u16 *location;
 	int signal = 0;
 
-	location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
+	location = (__u16 *) get_check_address(regs);
 
 	/*
 	 * We got all needed information from the lowcore and can
@@ -555,13 +604,18 @@
 		signal = SIGFPE;
 	else
 		signal = SIGILL;
-        if (signal == SIGFPE) {
-		current->thread.ieee_instruction_pointer = (addr_t) location;
-		do_trap(interruption_code, signal,
-			"floating point exception", regs, NULL);
-	} else if (signal) 
-                do_trap(interruption_code, signal,
-			"data exception", regs, NULL);
+        if (signal == SIGFPE)
+		do_fp_trap(regs, location,
+                           current->thread.fp_regs.fpc, interruption_code);
+        else if (signal) {
+		siginfo_t info;
+		info.si_signo = signal;
+		info.si_errno = 0;
+		info.si_code = ILL_ILLOPN;
+		info.si_addr = location;
+		do_trap(interruption_code, signal, 
+			"data exception", regs, &info);
+	}
 }
 
 
@@ -577,13 +631,13 @@
         pgm_check_table[1] = &illegal_op;
         pgm_check_table[2] = &privileged_op;
         pgm_check_table[3] = &execute_exception;
-        pgm_check_table[4] = &do_page_fault;
+        pgm_check_table[4] = &do_protection_exception;
         pgm_check_table[5] = &addressing_exception;
         pgm_check_table[6] = &specification_exception;
         pgm_check_table[7] = &data_exception;
         pgm_check_table[9] = &divide_exception;
-        pgm_check_table[0x10] = &do_page_fault;
-        pgm_check_table[0x11] = &do_page_fault;
+        pgm_check_table[0x10] = &do_segment_exception;
+        pgm_check_table[0x11] = &do_page_exception;
         pgm_check_table[0x12] = &translation_exception;
         pgm_check_table[0x13] = &special_op_exception;
  	pgm_check_table[0x14] = &do_pseudo_page_fault;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/lib/Makefile linux/arch/s390/lib/Makefile
--- linux.orig/arch/s390/lib/Makefile	2001-04-12 02:02:28.000000000 +0000
+++ linux/arch/s390/lib/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -2,13 +2,8 @@
 # Makefile for s390-specific library files..
 #
 
-ifdef SMP
 .S.o:
-	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
-else
-.S.o:
-	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
-endif
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
 
 L_TARGET = lib.a
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/mm/fault.c linux/arch/s390/mm/fault.c
--- linux.orig/arch/s390/mm/fault.c	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/s390/mm/fault.c	2002-07-20 01:08:29.000000000 +0000
@@ -36,7 +36,6 @@
 #endif
 
 extern void die(const char *,struct pt_regs *,long);
-static void force_sigsegv(struct task_struct *tsk, int code, void *address);
 
 extern spinlock_t timerlist_lock;
 
@@ -66,25 +65,95 @@
 }
 
 /*
+ * Check which address space is addressed by the access
+ * register in S390_lowcore.exc_access_id.
+ * Returns 1 for user space and 0 for kernel space.
+ */
+static int __check_access_register(struct pt_regs *regs, int error_code)
+{
+	int areg = S390_lowcore.exc_access_id;
+
+	if (areg == 0)
+		/* Access via access register 0 -> kernel address */
+		return 0;
+	if (regs && areg < NUM_ACRS && regs->acrs[areg] <= 1)
+		/*
+		 * access register contains 0 -> kernel address,
+		 * access register contains 1 -> user space address
+		 */
+		return regs->acrs[areg];
+
+	/* Something unhealthy was done with the access registers... */
+	die("page fault via unknown access register", regs, error_code);
+	do_exit(SIGKILL);
+	return 0;
+}
+
+/*
+ * Check which address space the address belongs to.
+ * Returns 1 for user space and 0 for kernel space.
+ */
+static inline int check_user_space(struct pt_regs *regs, int error_code)
+{
+	/*
+	 * The lowest two bits of S390_lowcore.trans_exc_code indicate
+	 * which paging table was used:
+	 *   0: Primary Segment Table Descriptor
+	 *   1: STD determined via access register
+	 *   2: Secondary Segment Table Descriptor
+	 *   3: Home Segment Table Descriptor
+	 */
+	int descriptor = S390_lowcore.trans_exc_code & 3;
+	if (descriptor == 1)
+		return __check_access_register(regs, error_code);
+	return descriptor >> 1;
+}
+
+/*
+ * Send SIGSEGV to task.  This is an external routine
+ * to keep the stack usage of do_page_fault small.
+ */
+static void force_sigsegv(struct pt_regs *regs, unsigned long error_code,
+			  int si_code, unsigned long address)
+{
+	struct siginfo si;
+
+#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
+#if defined(CONFIG_SYSCTL)
+	if (sysctl_userprocess_debug)
+#endif
+	{
+		printk("User process fault: interruption code 0x%lX\n",
+		       error_code);
+		printk("failing address: %lX\n", address);
+		show_regs(regs);
+	}
+#endif
+	si.si_signo = SIGSEGV;
+	si.si_code = si_code;
+	si.si_addr = (void *) address;
+	force_sig_info(SIGSEGV, &si, current);
+}
+
+/*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  *
  * error_code:
- *             ****0004       Protection           ->  Write-Protection  (suprression)
- *             ****0010       Segment translation  ->  Not present       (nullification)
- *             ****0011       Page translation     ->  Not present       (nullification)
+ *   04       Protection           ->  Write-Protection  (suprression)
+ *   10       Segment translation  ->  Not present       (nullification)
+ *   11       Page translation     ->  Not present       (nullification)
  */
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
 {
         struct task_struct *tsk;
         struct mm_struct *mm;
         struct vm_area_struct * vma;
         unsigned long address;
+	int user_address;
         unsigned long fixup;
-        int write;
 	int si_code = SEGV_MAPERR;
-	int kernel_address = 0;
 
         tsk = current;
         mm = tsk->mm;
@@ -94,13 +163,13 @@
 	 * as a special case because the translation exception code 
 	 * field is not guaranteed to contain valid data in this case.
 	 */
-	if ((error_code & 0xff) == 4 && !(S390_lowcore.trans_exc_code & 4)) {
+	if (error_code == 4 && !(S390_lowcore.trans_exc_code & 4)) {
 
 		/* Low-address protection hit in kernel mode means 
 		   NULL pointer write access in kernel mode.  */
  		if (!(regs->psw.mask & PSW_PROBLEM_STATE)) {
 			address = 0;
-			kernel_address = 1;
+			user_address = 0;
 			goto no_context;
 		}
 
@@ -114,52 +183,15 @@
          * more specific the segment and page table portion of 
          * the address 
          */
-
         address = S390_lowcore.trans_exc_code&0x7ffff000;
-
-
-	/*
-	 * Check which address space the address belongs to
-	 */
-	switch (S390_lowcore.trans_exc_code & 3)
-	{
-	case 0: /* Primary Segment Table Descriptor */
-		kernel_address = 1;
-		goto no_context;
-
-	case 1: /* STD determined via access register */
-		if (S390_lowcore.exc_access_id == 0)
-		{
-			kernel_address = 1;
-			goto no_context;
-		}
-		if (regs && S390_lowcore.exc_access_id < NUM_ACRS)
-		{
-			if (regs->acrs[S390_lowcore.exc_access_id] == 0)
-			{
-				kernel_address = 1;
-				goto no_context;
-			}
-			if (regs->acrs[S390_lowcore.exc_access_id] == 1)
-			{
-				/* user space address */
-				break;
-			}
-		}
-		die("page fault via unknown access register", regs, error_code);
-        	do_exit(SIGKILL);
-		break;
-
-	case 2: /* Secondary Segment Table Descriptor */
-	case 3: /* Home Segment Table Descriptor */
-		/* user space address */
-		break;
-	}
+	user_address = check_user_space(regs, error_code);
 
 	/*
-	 * Check whether we have a user MM in the first place.
+	 * Verify that the fault happened in user space, that
+	 * we are not in an interrupt and that there is a 
+	 * user context.
 	 */
-        if (in_interrupt() || !mm || !(regs->psw.mask & _PSW_IO_MASK_BIT))
+        if (user_address == 0 || in_interrupt() || !mm)
                 goto no_context;
 
 	/*
@@ -167,7 +199,6 @@
 	 * task's user address space, so we can switch on the
 	 * interrupts again and then search the VMAs
 	 */
-
 	__sti();
 
         down_read(&mm->mmap_sem);
@@ -186,30 +217,23 @@
  * we can handle it..
  */
 good_area:
-        write = 0;
 	si_code = SEGV_ACCERR;
+	if (error_code != 4) {
+		/* page not present, check vm flags */
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
+			goto bad_area;
+	} else {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	}
 
-        switch (error_code & 0xFF) {
-                case 0x04:                                /* write, present*/
-                        write = 1;
-                        break;
-                case 0x10:                                   /* not present*/
-                case 0x11:                                   /* not present*/
-                        if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
-                                goto bad_area;
-                        break;
-                default:
-                       printk("code should be 4, 10 or 11 (%lX) \n",error_code&0xFF);  
-                       goto bad_area;
-        }
-
- survive:
+survive:
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
-	switch (handle_mm_fault(mm, vma, address, write)) {
+	switch (handle_mm_fault(mm, vma, address, error_code == 4)) {
 	case 1:
 		tsk->min_flt++;
 		break;
@@ -236,22 +260,7 @@
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
                 tsk->thread.prot_addr = address;
                 tsk->thread.trap_no = error_code;
-#ifndef CONFIG_SYSCTL
-#ifdef CONFIG_PROCESS_DEBUG
-                printk("User process fault: interruption code 0x%lX\n",error_code);
-                printk("failing address: %lX\n",address);
-		show_regs(regs);
-#endif
-#else
-		if (sysctl_userprocess_debug) {
-			printk("User process fault: interruption code 0x%lX\n",
-			       error_code);
-			printk("failing address: %lX\n", address);
-			show_regs(regs);
-		}
-#endif
-
-		force_sigsegv(tsk, si_code, (void *)address);
+		force_sigsegv(regs, error_code, si_code, address);
                 return;
 	}
 
@@ -266,8 +275,7 @@
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
  */
-
-        if (kernel_address)
+        if (user_address == 0)
                 printk(KERN_ALERT "Unable to handle kernel pointer dereference"
         	       " at virtual kernel address %08lx\n", address);
         else
@@ -311,17 +319,20 @@
 		goto no_context;
 }
 
-/*
- * Send SIGSEGV to task.  This is an external routine
- * to keep the stack usage of do_page_fault small.
- */
-static void force_sigsegv(struct task_struct *tsk, int code, void *address)
+void do_protection_exception(struct pt_regs *regs, unsigned long error_code)
 {
-	struct siginfo si;
-	si.si_signo = SIGSEGV;
-	si.si_code = code;
-	si.si_addr = address;
-	force_sig_info(SIGSEGV, &si, tsk);
+	regs->psw.addr -= (error_code >> 16);
+	do_exception(regs, 4);
+}
+
+void do_segment_exception(struct pt_regs *regs, unsigned long error_code)
+{
+	do_exception(regs, 0x10);
+}
+
+void do_page_exception(struct pt_regs *regs, unsigned long error_code)
+{
+	do_exception(regs, 0x11);
 }
 
 typedef struct _pseudo_wait_t {
@@ -343,7 +354,6 @@
         pseudo_wait_t wait_struct;
         pseudo_wait_t *ptr, *last, *next;
         unsigned long address;
-        int kernel_address;
 
         /*
          * get the failing address
@@ -393,21 +403,7 @@
 			 * while we are running disabled. VM will then swap
 			 * in the page synchronously.
                          */
-			kernel_address = 0;
-                         switch (S390_lowcore.trans_exc_code & 3) {
-                         case 0: /* Primary Segment Table Descriptor */
-                                 kernel_address = 1;
-                                 break;
-                         case 1: /* STD determined via access register */
-                                 if (S390_lowcore.exc_access_id == 0 ||
-                                     regs->acrs[S390_lowcore.exc_access_id]==0)
-                                         kernel_address = 1;
-                                 break;
-                         case 2: /* Secondary Segment Table Descriptor */
-                         case 3: /* Home Segment Table Descriptor */
-                                 break;
-                         }
-                         if (kernel_address)
+                         if (check_user_space(regs, error_code) == 0)
                                  /* dereference a virtual kernel address */
                                  __asm__ __volatile__ (
                                          "  ic 0,0(%0)"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390/mm/init.c linux/arch/s390/mm/init.c
--- linux.orig/arch/s390/mm/init.c	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/s390/mm/init.c	2002-07-20 01:08:27.000000000 +0000
@@ -214,7 +214,7 @@
 		free_page(addr);
 		totalram_pages++;
         }
-        printk ("Freeing unused kernel memory: %dk freed\n",
+        printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n",
 		(&__init_end - &__init_begin) >> 10);
 }
 
@@ -222,7 +222,7 @@
 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/s390x/Makefile linux/arch/s390x/Makefile
--- linux.orig/arch/s390x/Makefile	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/Makefile	2002-07-20 01:08:37.000000000 +0000
@@ -60,6 +60,7 @@
 
 archclean:
 	@$(MAKEBOOT) clean
+	$(MAKE) -C arch/$(ARCH)/kernel clean
 
 archmrproper:
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/boot/install.sh linux/arch/s390x/boot/install.sh
--- linux.orig/arch/s390x/boot/install.sh	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/s390x/boot/install.sh	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# arch/s390x/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+#
+# "make install" script for s390 architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
+if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
+
+# Default install - same as make zlilo
+
+if [ -f $4/vmlinuz ]; then
+	mv $4/vmlinuz $4/vmlinuz.old
+fi
+
+if [ -f $4/System.map ]; then
+	mv $4/System.map $4/System.old
+fi
+
+cat $2 > $4/vmlinuz
+cp $3 $4/System.map
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/config.in linux/arch/s390x/config.in
--- linux.orig/arch/s390x/config.in	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/config.in	2002-07-20 01:08:25.000000000 +0000
@@ -6,8 +6,8 @@
 define_bool CONFIG_ISA n
 define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
-define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
-define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
 define_bool CONFIG_GENERIC_BUST_SPINLOCK n
 
 mainmenu_name "Linux Kernel Configuration"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/defconfig linux/arch/s390x/defconfig
--- linux.orig/arch/s390x/defconfig	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/defconfig	2002-07-20 01:08:21.000000000 +0000
@@ -4,8 +4,8 @@
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 # CONFIG_GENERIC_BUST_SPINLOCK is not set
 CONFIG_ARCH_S390=y
 CONFIG_ARCH_S390X=y
@@ -131,8 +131,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -144,10 +142,10 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 CONFIG_IPV6=m
-# CONFIG_IPV6_NETLINK is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -165,7 +163,7 @@
 # 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_FASTROUTE=y
 # CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/Makefile linux/arch/s390x/kernel/Makefile
--- linux.orig/arch/s390x/kernel/Makefile	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/s390x/kernel/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -8,9 +8,9 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 .S.o:
-	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
 
-all: kernel.o head.o init_task.o
+all: asm-offsets.h kernel.o head.o init_task.o
 
 O_TARGET	:= kernel.o
 
@@ -32,9 +32,31 @@
 obj-$(CONFIG_S390_SUPPORT)	+= linux32.o signal32.o ioctl32.o wrapper32.o exec32.o
 obj-$(CONFIG_BINFMT_ELF32)	+= binfmt_elf32.o
 
+.PHONY: asm-offsets.h
+
 #
 # This is just to get the dependencies...
 #
 binfmt_elf32.o:	$(TOPDIR)/fs/binfmt_elf.c
 
+#
+# Automatic offset generation for assembler files.
+#
+asm-offsets.h: asm-offsets.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -S $< -o - | grep -- "->" | \
+	(echo "#ifndef __ASM_OFFSETS_H__"; \
+	 echo "#define __ASM_OFFSETS_H__"; \
+	 echo "/*"; \
+	 echo " * DO NOT MODIFY"; \
+	 echo " *"; \
+	 echo " * This file was generated by arch/s390/kernel/Makefile"; \
+	 echo " */"; \
+	 sed -e "s:^->\([^ ]*\) \([^ ]*\) \(.*\):#define \\1 \\2 /* \\3*/:" \
+	     -e "s:->::"; \
+	 echo "#endif" \
+	) > asm-offsets.h
+
+clean:
+	rm -f asm-offsets.h
+
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/asm-offsets.c linux/arch/s390x/kernel/asm-offsets.c
--- linux.orig/arch/s390x/kernel/asm-offsets.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/s390x/kernel/asm-offsets.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+
+/* Use marker if you need to separate the values later */
+
+#define DEFINE(sym, val, marker) \
+	asm volatile("\n->" #sym " %0 " #val " " #marker : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+	DEFINE(__THREAD_ar2, offsetof(struct task_struct, thread.ar2),);
+	DEFINE(__THREAD_ar4, offsetof(struct task_struct, thread.ar4),);
+	DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp),);
+	DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info),);
+	BLANK();
+	DEFINE(__TASK_state, offsetof(struct task_struct, state),);
+	DEFINE(__TASK_sigpending, offsetof(struct task_struct, sigpending),);
+	DEFINE(__TASK_need_resched,
+	       offsetof(struct task_struct, need_resched),);
+	DEFINE(__TASK_ptrace, offsetof(struct task_struct, ptrace),);
+	DEFINE(__TASK_processor, offsetof(struct task_struct, processor),);
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/debug.c linux/arch/s390x/kernel/debug.c
--- linux.orig/arch/s390x/kernel/debug.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/debug.c	2002-07-20 01:08:25.000000000 +0000
@@ -443,7 +443,6 @@
 {
 	size_t count = 0;
 	size_t entry_offset, size = 0;
-	int rc;
 	file_private_info_t *p_info;
 
 	p_info = ((file_private_info_t *) file->private_data);
@@ -459,9 +458,9 @@
 		size = MIN((len - count), (size - entry_offset));
 
 		if(size){
-			if ((rc = copy_to_user(user_buf + count, 
-					p_info->temp_buf + entry_offset, size)))
-			return rc;
+			if (copy_to_user(user_buf + count, 
+					p_info->temp_buf + entry_offset, size))
+				return count ? count : -EFAULT;
 		}
 		count += size;
 		entry_offset = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/entry.S linux/arch/s390x/kernel/entry.S
--- linux.orig/arch/s390x/kernel/entry.S	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/entry.S	2002-07-20 01:08:29.000000000 +0000
@@ -18,6 +18,7 @@
 #include <asm/smp.h>
 #include <asm/ptrace.h>
 
+#include "asm-offsets.h"
 
 /*
  * Stack layout for the system_call stack entry.
@@ -45,41 +46,7 @@
 SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + PT_ORIGGPR2
 /* Now the additional entries */
 SP_TRAP      =  (SP_ORIG_R2+GPR_SIZE)
-#if CONFIG_REMOTE_DEBUG
-SP_CRREGS    =  (SP_TRAP+4)
-/* fpu registers are saved & restored by the gdb stub itself */
-SP_FPC       =  (SP_CRREGS+(NUM_CRS*CR_SIZE))
-SP_FPRS      =  (SP_FPC+FPC_SIZE+FPC_PAD_SIZE)
-SP_PGM_OLD_ILC= (SP_FPRS+(NUM_FPRS*FPR_SIZE))
-#else
-SP_PGM_OLD_ILC= (SP_TRAP+4)
-#endif
-SP_SIZE      =  (SP_PGM_OLD_ILC+4)
-/*
- * these defines are offsets into the thread_struct
- */
-_TSS_PTREGS  = 0
-_TSS_FPRS    = (_TSS_PTREGS+8)
-_TSS_AR2     = (_TSS_FPRS+136)
-_TSS_AR4     = (_TSS_AR2+4)
-_TSS_KSP     = (_TSS_AR4+4)
-_TSS_USERSEG = (_TSS_KSP+8)
-_TSS_PROT    = (_TSS_USERSEG+8)
-_TSS_ERROR   = (_TSS_PROT+8)
-_TSS_TRAP    = (_TSS_ERROR+4)
-_TSS_PER     = (_TSS_TRAP+4)
-_TSS_IEEE    = (_TSS_PER+72)
-_TSS_FLAGS   = (_TSS_IEEE+8)
-
-/*
- * these are offsets into the task-struct.
- */
-state        =  0
-flags        =  8
-sigpending   = 16
-need_resched = 32
-tsk_ptrace   = 40
-processor    = 88
+SP_SIZE      =  (SP_TRAP+4)
 
 /*
  * Register usage in interrupt handlers:
@@ -136,37 +103,31 @@
 
 /*
  * Scheduler resume function, called by switch_to
- *  grp2 = (thread_struct *) prev->tss
- *  grp3 = (thread_struct *) next->tss
+ *  gpr2 = (task_struct *) prev
+ *  gpr3 = (task_struct *) next
  * Returns:
  *  gpr2 = prev
  */
         .globl  resume
 resume:
-        lg      %r4,_TSS_PTREGS(%r3)
-        tm      SP_PSW-SP_PTREGS(%r4),0x40 # is the new process using per ?
-        jz      resume_noper            # if not we're fine
+	tm	__THREAD_per+4(%r3),0xe8	# is the new process using per ?
+	jz	resume_noper		# if not we're fine
         stctg   %c9,%c11,48(%r15)       # We are using per stuff
-        clc     _TSS_PER(24,%r3),48(%r15)
+        clc     __THREAD_per(24,%r3),48(%r15)
         je      resume_noper            # we got away without bashing TLB's
-        lctlg   %c9,%c11,_TSS_PER(%r3)  # Nope we didn't
+        lctlg   %c9,%c11,__THREAD_per(%r3)	# Nope we didn't
 resume_noper:
         stmg    %r6,%r15,48(%r15)       # store resume registers of prev task
-        stg     %r15,_TSS_KSP(%r2) # store kernel stack ptr to prev->tss.ksp
-        lghi    %r0,-16384
-        ngr     %r0,%r15
-        lg      %r15,_TSS_KSP(%r3) # load kernel stack ptr from next->tss.ksp
-        lghi    %r1,16383
-        ogr     %r1,%r15
-        aghi    %r1,1
-        stg     %r1,__LC_KERNEL_STACK   # __LC_KERNEL_STACK = new kernel stack
-        stam    %a2,%a2,_TSS_AR2(%r2)   # store kernel access reg. 2
-        stam    %a4,%a4,_TSS_AR4(%r2)   # store kernel access reg. 4
-        lam     %a2,%a2,_TSS_AR2(%r3)   # load kernel access reg. 2
-        lam     %a4,%a4,_TSS_AR4(%r3)   # load kernel access reg. 4
-        lgr     %r2,%r0                 # return task_struct of last task
+	stg	%r15,__THREAD_ksp(%r2)	# store kernel stack to prev->tss.ksp
+	lg	%r15,__THREAD_ksp(%r3)	# load kernel stack from next->tss.ksp
+        stam    %a2,%a2,__THREAD_ar2(%r2)	# store kernel access reg. 2
+        stam    %a4,%a4,__THREAD_ar4(%r2)	# store kernel access reg. 4
+        lam     %a2,%a2,__THREAD_ar2(%r3)	# load kernel access reg. 2
+        lam     %a4,%a4,__THREAD_ar4(%r3)	# load kernel access reg. 4
         lmg     %r6,%r15,48(%r15)       # load resume registers of next task
-        br      %r14
+	aghi	%r3,16384
+	stg	%r3,__LC_KERNEL_STACK	# __LC_KERNEL_STACK = new kernel stack
+	br	%r14
 
 /*
  * do_softirq calling function. We want to run the softirq functions on the
@@ -195,19 +156,17 @@
 	.globl  system_call
 system_call:
         SAVE_ALL __LC_SVC_OLD_PSW,1
-	mvi     SP_PGM_OLD_ILC(%r15),1  # mark PGM_OLD_ILC as invalid
-pgm_system_call:
-        GET_CURRENT               # load pointer to task_struct to R9
 	larl    %r7,sys_call_table
-	llgc    %r8,__LC_SVC_INT_CODE+1 # get svc number from lowcore
-	stosm   48(%r15),0x03     # reenable interrupts
+	llgh    %r8,__LC_SVC_INT_CODE # get svc number from lowcore
         sll     %r8,3
+        GET_CURRENT               # load pointer to task_struct to R9
+	stosm   48(%r15),0x03     # reenable interrupts
         tm      SP_PSW+3(%r15),0x01  # are we running in 31 bit mode ?
         jo      sysc_noemu
 	la      %r8,4(%r8)        # use 31 bit emulation system calls
 sysc_noemu:
         lgf     %r8,0(%r8,%r7)    # load address of system call routine
-        tm      tsk_ptrace+7(%r9),0x02 # PT_TRACESYS
+        tm      __TASK_ptrace+7(%r9),0x02 # PT_TRACESYS
         jnz     sysc_tracesys
         basr    %r14,%r8          # call sys_xxxx
         stg     %r2,SP_R2(%r15)   # store return value (change R2 on stack)
@@ -220,14 +179,12 @@
 #
 # check, if reschedule is needed
 #
-	lg      %r0,need_resched(%r9) # get need_resched from task_struct
+	lg      %r0,__TASK_need_resched(%r9)
 	ltgr    %r0,%r0
         jnz     sysc_reschedule
-        icm     %r0,15,sigpending(%r9)     # get sigpending from task_struct
+        icm     %r0,15,__TASK_sigpending(%r9)
         jnz     sysc_signal_return
 sysc_leave:
-        tm      SP_PGM_OLD_ILC(%r15),0xff
-        jz      pgm_svcret
 	stnsm   48(%r15),0xfc         # disable I/O and ext. interrupts
         RESTORE_ALL 1
 
@@ -241,38 +198,44 @@
 	jg      do_signal           # return point is sysc_leave
 
 #
+# call schedule with sysc_return as return-address
+#
+sysc_reschedule:        
+	larl    %r14,sysc_return
+        jg      schedule            # return point is sysc_return
+#
 # call trace before and after sys_call
 #
 sysc_tracesys:
-	lghi    %r2,-ENOSYS
-	stg     %r2,SP_R2(%r15)     # give sysc_trace an -ENOSYS retval
+	larl	%r12,sysc_return
+
+#
+# call syscall_trace before and after system call
+# special linkage: %r12 contains the return address for trace_svc
+#
+trace_svc:
+	lghi    %r7,-ENOSYS
+	stg     %r7,SP_R2(%r15)     # give sysc_trace an -ENOSYS retval
         brasl   %r14,syscall_trace
 	lg      %r2,SP_R2(%r15)
 	cghi    %r2,-ENOSYS
-	je      sysc_tracesys_dn1   
+	je      trace_svc_go
 	sllg    %r2,%r2,56          # strace wants to change the syscall
 	srlg    %r2,%r2,53          # zap unused bits & multiply by 8
 	tm      SP_PSW+3(%r15),0x01 # are we running in 31 bit mode ?
-        jo      sysc_tracesys_noemu
+        jo      trace_svc_noemu
 	la      %r2,4(%r2)          # use 31 bit emulation system calls
-sysc_tracesys_noemu:
+trace_svc_noemu:
 	lgf	%r8,0(%r2,%r7)      # load address of system call routine
-sysc_tracesys_dn1:	
+trace_svc_go:	
 	lmg     %r3,%r6,SP_R3(%r15)
 	lg      %r2,SP_ORIG_R2(%r15)
         basr    %r14,%r8            # call sys_xxx
         stg     %r2,SP_R2(%r15)     # store return value
-	larl    %r14,sysc_return
+	lgr	%r14,%r12	    # return point is in %r12
         jg      syscall_trace       # return point is sysc_return
 
 #
-# call schedule with sysc_return as return-address
-#
-sysc_reschedule:        
-	larl    %r14,sysc_return
-        jg      schedule            # return point is sysc_return
-
-#
 # a new process exits the kernel with ret_from_fork
 #
         .globl  ret_from_fork
@@ -280,12 +243,8 @@
         GET_CURRENT               # load pointer to task_struct to R9
         stosm   48(%r15),0x03     # reenable interrupts
 	xc      SP_R2(8,%r15),SP_R2(%r15) # child returns 0
-#ifdef CONFIG_SMP
 	larl    %r14,sysc_return
         jg      schedule_tail     # return to sysc_return
-#else
-        j       sysc_return
-#endif
 
 #
 # clone, fork, vfork, exec and sigreturn need glue,
@@ -630,10 +589,23 @@
         .long  SYSCALL(sys_madvise,sys32_madvise_wrapper)
 	.long  SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 222 - reserved for posix_acl */
-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 223 - reserved for posix_acl */
-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for posix_acl */
-        .rept  255-224
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
+	.long  SYSCALL(sys_gettid,sys_gettid)
+	.long  SYSCALL(sys_tkill,sys_tkill)
+	.rept  255-237
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
 	.endr
 
@@ -657,51 +629,91 @@
  * for LPSW?).
  */
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
-        jz      pgm_sv                   # skip if not
+        jnz     pgm_per                  # got per exception -> special case
+	SAVE_ALL __LC_PGM_OLD_PSW,1
+	llgh    %r8,__LC_PGM_INT_CODE
+        sll     %r8,3
+	GET_CURRENT
+        larl    %r1,pgm_check_table
+        lg      %r1,0(%r8,%r1)		 # load address of handler routine
+        la      %r2,SP_PTREGS(%r15)	 # address of register-save area
+	lgf     %r3,__LC_PGM_ILC	 # load program interruption code
+	larl	%r14,sysc_return
+        br      %r1			 # branch to interrupt-handler
+
+#
+# handle per exception
+#
+pgm_per:
         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
-        jnz     pgm_sv                   # skip if it is
+        jnz     pgm_per_std              # ok, normal per event from user space
 # ok its one of the special cases, now we need to find out which one
         clc     __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
         je      pgm_svcper
 # no interesting special case, ignore PER event
 	lpswe   __LC_PGM_OLD_PSW
+
+#
+# Normal per exception
+#
+pgm_per_std:
+	SAVE_ALL __LC_PGM_OLD_PSW,1
+	GET_CURRENT
+	lghi    %r4,0x7f
+	lgf     %r3,__LC_PGM_ILC	 # load program interruption code
+        nr      %r4,%r3			 # clear per-event-bit and ilc
+        je      pgm_per_only		 # only per of per+check ?
+        sll     %r4,3
+        larl    %r1,pgm_check_table
+        lg      %r1,0(%r4,%r1)		 # load address of handler routine
+        la      %r2,SP_PTREGS(%r15)	 # address of register-save area
+        basr    %r14,%r1		 # branch to interrupt-handler
+pgm_per_only:
+        la      %r2,SP_PTREGS(15)	 # address of register-save area
+        larl    %r14,sysc_return	 # load adr. of system return
+        jg      handle_per_exception
+
+#
 # it was a single stepped SVC that is causing all the trouble
+#
 pgm_svcper:
 	SAVE_ALL __LC_SVC_OLD_PSW,1
-        mvc     SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
-        j       pgm_system_call          # now do the svc
+	larl    %r7,sys_call_table
+	llgh    %r8,__LC_SVC_INT_CODE # get svc number from lowcore
+        sll     %r8,3
+        GET_CURRENT               # load pointer to task_struct to R9
+	stosm   48(%r15),0x03     # reenable interrupts
+        tm      SP_PSW+3(%r15),0x01  # are we running in 31 bit mode ?
+        jo      pgm_svcper_noemu
+	la      %r8,4(%r8)        # use 31 bit emulation system calls
+pgm_svcper_noemu:
+        lgf     %r8,0(%r8,%r7)    # load address of system call routine
+        tm      __TASK_ptrace+7(%r9),0x02 # PT_TRACESYS
+        jnz     pgm_tracesys
+        basr    %r14,%r8          # call sys_xxxx
+        stg     %r2,SP_R2(%r15)   # store return value (change R2 on stack)
+                                  # ATTENTION: check sys_execve_glue before
+                                  # changing anything here !!
+
 pgm_svcret:
+        icm     %r0,15,__TASK_sigpending(%r9)
+        jz      pgm_svcper_nosig
+        la      %r2,SP_PTREGS(%r15) # load pt_regs
+        sgr     %r3,%r3             # clear *oldset
+	brasl	%r14,do_signal
+	
+pgm_svcper_nosig:
 	lhi     %r0,__LC_PGM_OLD_PSW     # set trap indication back to pgm_chk
 	st      %r0,SP_TRAP(%r15)
-        llgh    %r7,SP_PGM_OLD_ILC(%r15) # get ilc from stack
-        mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
-	j       pgm_no_sv
-pgm_sv:
-	SAVE_ALL __LC_PGM_OLD_PSW,1
-        mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
-        llgh    %r7,__LC_PGM_ILC         # load instruction length
-	GET_CURRENT
-pgm_no_sv:
-        llgh    %r8,__LC_PGM_INT_CODE  # N.B. saved int code used later KEEP it
-	lghi    %r3,0x7f
-        nr      %r3,%r8           # clear per-event-bit & move to r3
-        je      pgm_dn            # none of Martins exceptions occurred bypass
-        sll     %r3,3
-        larl    %r1,pgm_check_table
-        lg      %r1,0(%r3,%r1)    # load address of handler routine
-        srl     %r3,3
-        la      %r2,SP_PTREGS(%r15) # address of register-save area
-        chi     %r3,0x4           # protection-exception ?
-        jne     pgm_go            # if not,
-        lg      %r5,SP_PSW+8(15)  # load psw addr
-        slgr    %r5,%r7           # substract ilc from psw
-        stg     %r5,SP_PSW+8(15)  # store corrected psw addr
-pgm_go: basr    %r14,%r1          # branch to interrupt-handler
-pgm_dn: nill    %r8,0x80          # check for per exception
-        je      sysc_return
         la      %r2,SP_PTREGS(15) # address of register-save area
         larl    %r14,sysc_return  # load adr. of system return
         jg      handle_per_exception
+#
+# call trace before and after sys_call
+#
+pgm_tracesys:
+	larl	%r12,pgm_svcret
+	j	trace_svc
 
 /*
  * IO interrupt handler routine
@@ -720,7 +732,7 @@
 #
 # check, if bottom-half has to be done
 #
-	lgf     %r1,processor(%r9)    # get cpu number from task struture
+	lgf     %r1,__TASK_processor(%r9)
 	larl    %r2,irq_stat
 	sll     %r1,L1_CACHE_SHIFT
 	la      %r1,0(%r1,%r2)
@@ -734,10 +746,10 @@
 #
 # check, if reschedule is needed
 #
-	lg      %r0,need_resched(%r9)  # get need_resched from task_struct
+	lg      %r0,__TASK_need_resched(%r9)
 	ltgr    %r0,%r0
         jnz     io_reschedule
-        icm     %r0,15,sigpending(%r9) # get sigpending from task_struct
+        icm     %r0,15,__TASK_sigpending(%r9)
         jnz     io_signal_return
 io_leave:
         stnsm   48(%r15),0xfc          # disable I/O and ext. interrupts
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/irq.c linux/arch/s390x/kernel/irq.c
--- linux.orig/arch/s390x/kernel/irq.c	2001-07-25 21:12:01.000000000 +0000
+++ linux/arch/s390x/kernel/irq.c	2002-07-20 01:08:40.000000000 +0000
@@ -59,60 +59,6 @@
 BUILD_SMP_INTERRUPT(spurious_interrupt)
 #endif
 
-#if 0
-int get_irq_list(char *buf)
-{
-	int i, j;
-	struct irqaction * action;
-	char *p = buf;
-
-	p += sprintf(p, "           ");
-
-	for (j=0; j<smp_num_cpus; j++)
-		p += sprintf(p, "CPU%d       ",j);
-
-	*p++ = '\n';
-
-	for (i = 0 ; i < NR_IRQS ; i++)
-	{
-		if (ioinfo[i] == INVALID_STORAGE_AREA)
-			continue;
-
-		action = ioinfo[i]->irq_desc.action;
-		
-  		if (!action)
-			continue;
-
-		p += sprintf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
-		p += sprintf(p, "%10u ", kstat_irqs(i));
-#else
-		for (j=0; j<smp_num_cpus; j++)
-			p += sprintf( p, "%10u ",
-			              kstat.irqs[cpu_logical_map(j)][i]);
-#endif
-		p += sprintf(p, " %14s", ioinfo[i]->irq_desc.handler->typename);
-		p += sprintf(p, "  %s", action->name);
-
-		for (action=action->next; action; action = action->next)
-		{
-			p += sprintf(p, ", %s", action->name);
-
-		} /* endfor */
-
-		*p++ = '\n';
-	
-	} /* endfor */
-
-	p += sprintf(p, "NMI: %10u\n", nmi_counter);
-#ifdef CONFIG_SMP
-	p += sprintf(p, "IPI: %10u\n", atomic_read(&ipi_count));
-#endif
-
-	return p - buf;
-}
-#endif
-
 /*
  * Global interrupt locks for SMP. Allow interrupts to come in on any
  * CPU, yet make cli/sti act globally to protect critical regions..
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/linux32.c linux/arch/s390x/kernel/linux32.c
--- linux.orig/arch/s390x/kernel/linux32.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/linux32.c	2002-07-20 01:08:27.000000000 +0000
@@ -288,6 +288,21 @@
 
 struct msgbuf32 { s32 mtype; char mtext[1]; };
 
+struct ipc64_perm_ds32
+{
+        __kernel_key_t          key;
+        __kernel_uid32_t        uid;
+        __kernel_gid32_t        gid;
+        __kernel_uid32_t        cuid;
+        __kernel_gid32_t        cgid;
+        __kernel_mode_t32       mode;
+        unsigned short          __pad1;
+        unsigned short          seq;
+        unsigned short          __pad2;
+        unsigned int            __unused1;
+        unsigned int            __unused2;
+};
+
 struct ipc_perm32
 {
 	key_t    	  key;
@@ -311,7 +326,7 @@
 };
 
 struct semid64_ds32 {
-	struct ipc64_perm sem_perm;		  /* this structure is the same on sparc32 and sparc64 */
+	struct ipc64_perm_ds32 sem_perm;
 	unsigned int	  __pad1;
 	__kernel_time_t32 sem_otime;
 	unsigned int	  __pad2;
@@ -339,7 +354,7 @@
 };
 
 struct msqid64_ds32 {
-	struct ipc64_perm msg_perm;
+	struct ipc64_perm_ds32 msg_perm;
 	unsigned int   __pad1;
 	__kernel_time_t32 msg_stime;
 	unsigned int   __pad2;
@@ -368,7 +383,7 @@
 };
 
 struct shmid64_ds32 {
-	struct ipc64_perm	shm_perm;
+	struct ipc64_perm_ds32	shm_perm;
 	unsigned int		__pad1;
 	__kernel_time_t32	shm_atime;
 	unsigned int		__pad2;
@@ -1390,7 +1405,7 @@
 
 	timeout = MAX_SCHEDULE_TIMEOUT;
 	if (tvp) {
-		time_t sec, usec;
+		int sec, usec;
 
 		if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
 		    || (ret = __get_user(sec, &tvp->tv_sec))
@@ -1442,7 +1457,7 @@
 	ret = do_select(n, &fds, &timeout);
 
 	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
-		time_t sec = 0, usec = 0;
+		int sec = 0, usec = 0;
 		if (timeout) {
 			sec = timeout / HZ;
 			usec = timeout % HZ;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/process.c linux/arch/s390x/kernel/process.c
--- linux.orig/arch/s390x/kernel/process.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/process.c	2002-07-20 01:08:27.000000000 +0000
@@ -50,28 +50,37 @@
  * The idle loop on a S390...
  */
 
-static psw_t wait_psw;
-
 int cpu_idle(void *unused)
 {
+	psw_t wait_psw;
+	unsigned long reg;
+
 	/* endless idle loop with no priority at all */
         init_idle();
 	current->nice = 20;
 	current->counter = -100;
-	wait_psw.mask = _WAIT_PSW_MASK;
-	wait_psw.addr = (unsigned long) &&idle_wakeup;
-	while(1) {
-                if (current->need_resched) {
-                        schedule();
-                        check_pgt_cache();
-                        continue;
-                }
-
-		/* load wait psw */
+	while (1) {
+		if (current->need_resched) {
+			schedule();
+			check_pgt_cache();
+			continue;
+		}
+
+		/* 
+		 * Wait for external, I/O or machine check interrupt and
+		 * switch of machine check bit after the wait has ended.
+		 */
+		wait_psw.mask = _WAIT_PSW_MASK;
 		asm volatile (
-                        "lpswe %0"
-                        : : "m" (wait_psw) );
-idle_wakeup:
+			"    larl  %0,0f\n"
+			"    stg   %0,8(%1)\n"
+			"    lpswe 0(%1)\n"
+			"0:  larl  %0,1f\n"
+			"    stg   %0,8(%1)\n"
+			"    ni    1(%1),0xf9\n"
+			"    lpswe 0(%1)\n"
+			"1:"
+			: "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
 	}
 }
 
@@ -165,8 +174,7 @@
         frame->gprs[8] = (unsigned long) &ret_from_fork;
 
         /* fake return stack for resume(), don't go back to schedule */
-        frame->gprs[9]  = (unsigned long) frame;
-	frame->childregs.old_ilc = -1; /* We are not single stepping an svc */
+        frame->gprs[9] = (unsigned long) frame;
         /* save fprs, if used in last task */
 	save_fp_regs(&p->thread.fp_regs);
         p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _REGION_TABLE;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/ptrace.c linux/arch/s390x/kernel/ptrace.c
--- linux.orig/arch/s390x/kernel/ptrace.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/ptrace.c	2002-07-20 01:08:25.000000000 +0000
@@ -357,9 +357,10 @@
 
 	case PTRACE_PEEKUSR_AREA:
 	case PTRACE_POKEUSR_AREA:
-		if((ret=copy_from_user(&parea,(void *)addr,sizeof(parea)))==0)  
-		   ret=copy_user(child,parea.kernel_addr,parea.process_addr,
+		if(copy_from_user(&parea,(void *)addr,sizeof(parea)) == 0)  
+			ret=copy_user(child,parea.kernel_addr,parea.process_addr,
 				 parea.len,1,(request==PTRACE_POKEUSR_AREA));
+		else ret = -EFAULT;
 		break;
 	default:
 		ret = -EIO;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/reipl.S linux/arch/s390x/kernel/reipl.S
--- linux.orig/arch/s390x/kernel/reipl.S	2001-07-04 18:50:39.000000000 +0000
+++ linux/arch/s390x/kernel/reipl.S	2002-07-20 01:08:40.000000000 +0000
@@ -21,8 +21,10 @@
 	        oi      .Lschib+5-.Lpg0(%r13),0x84 
 .Lecs:  	xi      .Lschib+27-.Lpg0(%r13),0x01 
         	msch    .Lschib-.Lpg0(%r13) 
-		ssch	.Liplorb-.Lpg0(%r13)           
-		jz	.L001   
+	        lghi    %r0,5
+.Lssch:		ssch	.Liplorb-.Lpg0(%r13)           
+		jz	.L001
+		brct    %r0,.Lssch   
 		bas	%r14,.Ldisab-.Lpg0(%r13)
 .L001:		mvc	__LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13)	
 .Ltpi:		lpswe	.Lwaitpsw-.Lpg0(%r13)          
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/s390_ksyms.c linux/arch/s390x/kernel/s390_ksyms.c
--- linux.orig/arch/s390x/kernel/s390_ksyms.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/s390_ksyms.c	2002-07-20 01:08:30.000000000 +0000
@@ -7,6 +7,7 @@
 #include <linux/highuid.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/smp.h>
 #include <asm/checksum.h>
 #include <asm/delay.h>
 #include <asm/pgalloc.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/setup.c linux/arch/s390x/kernel/setup.c
--- linux.orig/arch/s390x/kernel/setup.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/setup.c	2002-07-20 01:08:33.000000000 +0000
@@ -48,7 +48,7 @@
 unsigned int console_device = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
-struct { unsigned long addr, size, type; } memory_chunk[16];
+struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } };
 #define CHUNK_READ_WRITE 0
 #define CHUNK_READ_ONLY 1
 __u16 boot_cpu_addr;
@@ -283,8 +283,8 @@
          * print what head.S has found out about the machine 
          */
 	printk((MACHINE_IS_VM) ?
-	       "We are running under VM\n" :
-	       "We are running native\n");
+	       "We are running under VM (64 bit mode)\n" :
+	       "We are running native (64 bit mode)\n");
 
         ROOT_DEV = to_kdev_t(0x0100);
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
@@ -485,7 +485,7 @@
 				(loops_per_jiffy/(5000/HZ))%100);
 	}
 	if (cpu_online_map & (1 << n)) {
-		cpuinfo = &safe_get_cpu_lowcore(n).cpu_data;
+		cpuinfo = &safe_get_cpu_lowcore(n)->cpu_data;
 		seq_printf(m, "processor %i: "
 				"version = %02X,  "
 				"identification = %06X,  "
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/signal.c linux/arch/s390x/kernel/signal.c
--- linux.orig/arch/s390x/kernel/signal.c	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/s390x/kernel/signal.c	2002-07-20 01:08:24.000000000 +0000
@@ -66,17 +66,15 @@
 		err = __put_user(from->si_signo, &to->si_signo);
 		err |= __put_user(from->si_errno, &to->si_errno);
 		err |= __put_user((short)from->si_code, &to->si_code);
-		/* First 32bits of unions are always present.  */
+		/* First 64bits of unions are always present.  */
 		err |= __put_user(from->si_pid, &to->si_pid);
+		err |= __put_user(from->si_uid, &to->si_uid);
 		switch (from->si_code >> 16) {
-		case __SI_FAULT >> 16:
-			break;
 		case __SI_CHLD >> 16:
 			err |= __put_user(from->si_utime, &to->si_utime);
 			err |= __put_user(from->si_stime, &to->si_stime);
 			err |= __put_user(from->si_status, &to->si_status);
 		default:
-			err |= __put_user(from->si_uid, &to->si_uid);
 			break;
 		/* case __SI_RT: This is not generated by the kernel as of now.  */
 		}
@@ -569,10 +567,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/s390x/kernel/signal32.c linux/arch/s390x/kernel/signal32.c
--- linux.orig/arch/s390x/kernel/signal32.c	2001-10-11 16:04:57.000000000 +0000
+++ linux/arch/s390x/kernel/signal32.c	2002-07-20 01:08:35.000000000 +0000
@@ -30,7 +30,7 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-#define _USER_PSW_MASK32 0x0701C00080000000
+#define _USER_PSW_MASK32 0x0705C00080000000
 
 typedef struct 
 {
@@ -699,10 +699,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/s390x/kernel/smp.c linux/arch/s390x/kernel/smp.c
--- linux.orig/arch/s390x/kernel/smp.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/smp.c	2002-07-20 01:08:37.000000000 +0000
@@ -191,7 +191,8 @@
 {
         if (smp_processor_id() != 0) {
                 smp_ext_bitcall(0, ec_restart);
-                for (;;);
+		for (;;)
+			enabled_wait();
         } else
                 do_machine_restart();
 }
@@ -208,7 +209,8 @@
 {
         if (smp_processor_id() != 0) {
                 smp_ext_bitcall(0, ec_halt);
-                for (;;);
+		for (;;)
+			enabled_wait();
         } else
                 do_machine_halt();
 }
@@ -225,7 +227,8 @@
 {
         if (smp_processor_id() != 0) {
                 smp_ext_bitcall(0, ec_power_off);
-                for (;;);
+		for (;;)
+			enabled_wait();
         } else
                 do_machine_power_off();
 }
@@ -270,7 +273,7 @@
         /*
          * Set signaling bit in lowcore of target cpu and kick it
          */
-	set_bit(sig, &(get_cpu_lowcore(cpu).ext_call_fast));
+	set_bit(sig, &(get_cpu_lowcore(cpu)->ext_call_fast));
         ccode = signal_processor(cpu, sigp_external_call);
         return ccode;
 }
@@ -290,8 +293,9 @@
                 /*
                  * Set signaling bit in lowcore of target cpu and kick it
                  */
-		set_bit(sig, &(get_cpu_lowcore(i).ext_call_fast));
-                ccode = signal_processor(i, sigp_external_call);
+		set_bit(sig, &(get_cpu_lowcore(i)->ext_call_fast));
+                while (signal_processor(i, sigp_external_call) == sigp_busy)
+			udelay(10);
         }
 }
 
@@ -308,7 +312,7 @@
 
         /* write magic number to zero page (absolute 0) */
 
-        get_cpu_lowcore(smp_processor_id()).panic_magic = __PANIC_MAGIC;
+        get_cpu_lowcore(smp_processor_id())->panic_magic = __PANIC_MAGIC;
 
         /* stop all processors */
 
@@ -330,7 +334,7 @@
         for (i =  0; i < smp_num_cpus; i++) {
                 if (smp_processor_id() != i) {
                         int ccode;
-                        low_core_addr = (unsigned long)&get_cpu_lowcore(i);
+                        low_core_addr = (unsigned long)get_cpu_lowcore(i);
                         do {
                                 ccode = signal_processor_ps(
                                    &dummy,
@@ -432,6 +436,7 @@
 
         current->processor = 0;
         smp_num_cpus = 1;
+        cpu_online_map = 1;
         for (curr_cpu = 0;
              curr_cpu <= 65535 && smp_num_cpus < max_cpus; curr_cpu++) {
                 if ((__u16) curr_cpu == boot_cpu_addr)
@@ -458,7 +463,7 @@
         /* Setup the cpu */
         cpu_init();
         /* Print info about this processor */
-        print_cpu_info(&safe_get_cpu_lowcore(smp_processor_id()).cpu_data);
+        print_cpu_info(&safe_get_cpu_lowcore(smp_processor_id())->cpu_data);
         /* Wait for completion of smp startup */
         while (!atomic_read(&smp_commenced))
                 /* nothing */ ;
@@ -514,7 +519,7 @@
         unhash_process(idle);
         init_tasks[cpu] = idle;
 
-        cpu_lowcore=&get_cpu_lowcore(cpu);
+        cpu_lowcore = get_cpu_lowcore(cpu);
 	cpu_lowcore->save_area[15] = idle->thread.ksp;
 	cpu_lowcore->kernel_stack = (__u64) idle + 16384;
         __asm__ __volatile__("la    1,%0\n\t"
@@ -569,7 +574,7 @@
         /*
          *      Initialize the logical to physical CPU number mapping
          */
-        print_cpu_info(&safe_get_cpu_lowcore(0).cpu_data);
+        print_cpu_info(&safe_get_cpu_lowcore(0)->cpu_data);
 
         for(i = 0; i < smp_num_cpus; i++)
         {
@@ -627,3 +632,4 @@
 EXPORT_SYMBOL(smp_ctl_set_bit);
 EXPORT_SYMBOL(smp_ctl_clear_bit);
 EXPORT_SYMBOL(smp_num_cpus);
+EXPORT_SYMBOL(smp_call_function);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/time.c linux/arch/s390x/kernel/time.c
--- linux.orig/arch/s390x/kernel/time.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/time.c	2002-07-20 01:08:30.000000000 +0000
@@ -55,7 +55,7 @@
 {
 	__u64 now;
 
-	asm ("STCK %0" : "=m" (now));
+	asm ("STCK 0(%0)" : : "a" (&now) : "memory", "cc");
         now = (now - init_timer_cc) >> 12;
 	/* We require the offset from the latest update of xtime */
 	now -= (__u64) wall_jiffies*USECS_PER_JIFFY;
@@ -173,9 +173,10 @@
 	int cc;
 
         /* kick the TOD clock */
-        asm volatile ("STCK %1\n\t"
+        asm volatile ("STCK 0(%1)\n\t"
                       "IPM  %0\n\t"
-                      "SRL  %0,28" : "=r" (cc), "=m" (init_timer_cc));
+                      "SRL  %0,28" : "=r" (cc) : "a" (&init_timer_cc) 
+				   : "memory", "cc");
         switch (cc) {
         case 0: /* clock in set state: all is fine */
                 break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/kernel/traps.c linux/arch/s390x/kernel/traps.c
--- linux.orig/arch/s390x/kernel/traps.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/s390x/kernel/traps.c	2002-07-20 01:08:39.000000000 +0000
@@ -52,7 +52,10 @@
 #endif
 #endif
 
-extern pgm_check_handler_t do_page_fault;
+extern pgm_check_handler_t do_protection_exception;
+extern pgm_check_handler_t do_segment_exception;
+extern pgm_check_handler_t do_region_exception;
+extern pgm_check_handler_t do_page_exception;
 #ifdef CONFIG_PFAULT
 extern int pfault_init(void);
 extern void pfault_fini(void);
@@ -270,23 +273,6 @@
         do_exit(SIGSEGV);
 }
 
-#define DO_ERROR(signr, str, name) \
-asmlinkage void name(struct pt_regs * regs, long interruption_code) \
-{ \
-	do_trap(interruption_code, signr, str, regs, NULL); \
-}
-
-#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \
-asmlinkage void name(struct pt_regs * regs, long interruption_code) \
-{ \
-        siginfo_t info; \
-        info.si_signo = signr; \
-        info.si_errno = 0; \
-        info.si_code = sicode; \
-        info.si_addr = (void *)siaddr; \
-        do_trap(interruption_code, signr, str, regs, &info); \
-}
-
 static void inline do_trap(long interruption_code, int signr, char *str,
                            struct pt_regs *regs, siginfo_t *info)
 {
@@ -299,7 +285,7 @@
 
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
                 struct task_struct *tsk = current;
-                tsk->thread.trap_no = interruption_code;
+                tsk->thread.trap_no = interruption_code & 0xffff;
 		if (info)
 			force_sig_info(signr, info, tsk);
 		else
@@ -326,6 +312,11 @@
         }
 }
 
+static inline void *get_check_address(struct pt_regs *regs)
+{
+	return (void *) ADDR_BITS_REMOVE(regs->psw.addr-S390_lowcore.pgm_ilc);
+}
+
 int do_debugger_trap(struct pt_regs *regs,int signal)
 {
 	if(regs->psw.mask&PSW_PROBLEM_STATE)
@@ -349,15 +340,70 @@
 	return 0;
 }
 
+#define DO_ERROR(signr, str, name) \
+asmlinkage void name(struct pt_regs * regs, long interruption_code) \
+{ \
+	do_trap(interruption_code, signr, str, regs, NULL); \
+}
+
+#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \
+asmlinkage void name(struct pt_regs * regs, long interruption_code) \
+{ \
+        siginfo_t info; \
+        info.si_signo = signr; \
+        info.si_errno = 0; \
+        info.si_code = sicode; \
+        info.si_addr = (void *)siaddr; \
+        do_trap(interruption_code, signr, str, regs, &info); \
+}
+
 DO_ERROR(SIGSEGV, "Unknown program exception", default_trap_handler)
-DO_ERROR(SIGILL,  "privileged operation", privileged_op)
-DO_ERROR(SIGILL,  "execute exception", execute_exception)
-DO_ERROR(SIGSEGV, "addressing exception", addressing_exception)
-DO_ERROR(SIGFPE,  "fixpoint divide exception", divide_exception)
-DO_ERROR(SIGILL,  "translation exception", translation_exception)
-DO_ERROR(SIGILL,  "special operand exception", special_op_exception)
-DO_ERROR(SIGILL,  "operand exception", operand_exception)
-DO_ERROR(SIGILL,  "specification exception", specification_exception);
+
+DO_ERROR_INFO(SIGBUS, "addressing exception", addressing_exception,
+	      BUS_ADRERR, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "execute exception", execute_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+DO_ERROR_INFO(SIGFPE,  "fixpoint divide exception", divide_exception,
+	      FPE_INTDIV, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "operand exception", operand_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "privileged operation", privileged_op,
+	      ILL_PRVOPC, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "special operation exception", special_op_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "specification exception", specification_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+DO_ERROR_INFO(SIGILL,  "translation exception", translation_exception,
+	      ILL_ILLOPN, get_check_address(regs))
+
+static inline void
+do_fp_trap(struct pt_regs *regs, void *location,
+           int fpc, long interruption_code)
+{
+	siginfo_t si;
+
+	si.si_signo = SIGFPE;
+	si.si_errno = 0;
+	si.si_addr = location;
+	si.si_code = 0;
+	/* FPC[2] is Data Exception Code */
+	if ((fpc & 0x00000300) == 0) {
+		/* bits 6 and 7 of DXC are 0 iff IEEE exception */
+		if (fpc & 0x8000) /* invalid fp operation */
+			si.si_code = FPE_FLTINV;
+		else if (fpc & 0x4000) /* div by 0 */
+			si.si_code = FPE_FLTDIV;
+		else if (fpc & 0x2000) /* overflow */
+			si.si_code = FPE_FLTOVF;
+		else if (fpc & 0x1000) /* underflow */
+			si.si_code = FPE_FLTUND;
+		else if (fpc & 0x0800) /* inexact */
+			si.si_code = FPE_FLTRES;
+	}
+	current->thread.ieee_instruction_pointer = (addr_t) location;
+	do_trap(interruption_code, SIGFPE,
+		"floating point exception", regs, &si);
+}
 
 asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
 {
@@ -365,7 +411,7 @@
 	__u16 *location;
 	int do_sig = 0;
 
-	location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
+	location = (__u16 *) get_check_address(regs);
 
 	/*
 	 * We got all needed information from the lowcore and can
@@ -390,15 +436,15 @@
 	else
 		do_sig = 1;
 	if (do_sig)
-		do_trap(interruption_code, SIGILL, "illegal operation", regs, NULL);
+		do_trap(interruption_code, SIGILL,
+			"illegal operation", regs, NULL);
 }
 
 asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
 {
 	__u16 *location;
-	int do_sig = 0;
 
-	location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
+	location = (__u16 *) get_check_address(regs);
 
 	/*
 	 * We got all needed information from the lowcore and can
@@ -409,17 +455,19 @@
 
 	__asm__ volatile ("stfpc %0\n\t" 
 			  : "=m" (current->thread.fp_regs.fpc));
-	/* Same code should work when we implement fpu emulation */
-	/* provided we call data exception from the fpu emulator */
-	if(current->thread.fp_regs.fpc&FPC_DXC_MASK)
-	{
-		current->thread.ieee_instruction_pointer=(addr_t)location;
-		force_sig(SIGFPE, current);
+
+	if (current->thread.fp_regs.fpc & FPC_DXC_MASK)
+		do_fp_trap(regs, location,
+                           current->thread.fp_regs.fpc, interruption_code);
+        else {
+		siginfo_t info;
+		info.si_signo = SIGILL;
+		info.si_errno = 0;
+		info.si_code = ILL_ILLOPN;
+		info.si_addr = location;
+		do_trap(interruption_code, SIGILL, 
+			"data exception", regs, &info);
 	}
-	else
-		do_sig = 1;
-        if (do_sig)
-                do_trap(interruption_code, SIGILL, "data exception", regs, NULL);
 }
 
 
@@ -435,6 +483,7 @@
         pgm_check_table[1] = &illegal_op;
         pgm_check_table[2] = &privileged_op;
         pgm_check_table[3] = &execute_exception;
+        pgm_check_table[4] = &do_protection_exception;
         pgm_check_table[5] = &addressing_exception;
         pgm_check_table[6] = &specification_exception;
         pgm_check_table[7] = &data_exception;
@@ -442,12 +491,11 @@
         pgm_check_table[0x12] = &translation_exception;
         pgm_check_table[0x13] = &special_op_exception;
         pgm_check_table[0x15] = &operand_exception;
-        pgm_check_table[4] = &do_page_fault;
-        pgm_check_table[0x10] = &do_page_fault;
-        pgm_check_table[0x11] = &do_page_fault;
+        pgm_check_table[0x10] = &do_segment_exception;
+        pgm_check_table[0x11] = &do_page_exception;
         pgm_check_table[0x1C] = &privileged_op;
         pgm_check_table[0x38] = &addressing_exception;
-        pgm_check_table[0x3B] = &do_page_fault;
+        pgm_check_table[0x3B] = &do_region_exception;
 #ifdef CONFIG_PFAULT
 	if (MACHINE_IS_VM) {
 		/* request the 0x2603 external interrupt */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/lib/Makefile linux/arch/s390x/lib/Makefile
--- linux.orig/arch/s390x/lib/Makefile	2001-04-12 02:02:29.000000000 +0000
+++ linux/arch/s390x/lib/Makefile	2002-07-20 01:08:26.000000000 +0000
@@ -2,13 +2,8 @@
 # Makefile for s390-specific library files..
 #
 
-ifdef SMP
 .S.o:
-	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
-else
-.S.o:
-	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
-endif
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
 
 L_TARGET = lib.a
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/mm/fault.c linux/arch/s390x/mm/fault.c
--- linux.orig/arch/s390x/mm/fault.c	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/s390x/mm/fault.c	2002-07-20 01:08:32.000000000 +0000
@@ -35,7 +35,6 @@
 #endif
 
 extern void die(const char *,struct pt_regs *,long);
-static void force_sigsegv(struct task_struct *tsk, int code, void *address);
 
 extern spinlock_t timerlist_lock;
 
@@ -65,26 +64,96 @@
 }
 
 /*
+ * Check which address space is addressed by the access
+ * register in S390_lowcore.exc_access_id.
+ * Returns 1 for user space and 0 for kernel space.
+ */
+static int __check_access_register(struct pt_regs *regs, int error_code)
+{
+	int areg = S390_lowcore.exc_access_id;
+
+	if (areg == 0)
+		/* Access via access register 0 -> kernel address */
+		return 0;
+	if (regs && areg < NUM_ACRS && regs->acrs[areg] <= 1)
+		/*
+		 * access register contains 0 -> kernel address,
+		 * access register contains 1 -> user space address
+		 */
+		return regs->acrs[areg];
+
+	/* Something unhealthy was done with the access registers... */
+	die("page fault via unknown access register", regs, error_code);
+	do_exit(SIGKILL);
+	return 0;
+}
+
+/*
+ * Check which address space the address belongs to.
+ * Returns 1 for user space and 0 for kernel space.
+ */
+static inline int check_user_space(struct pt_regs *regs, int error_code)
+{
+	/*
+	 * The lowest two bits of S390_lowcore.trans_exc_code indicate
+	 * which paging table was used:
+	 *   0: Primary Segment Table Descriptor
+	 *   1: STD determined via access register
+	 *   2: Secondary Segment Table Descriptor
+	 *   3: Home Segment Table Descriptor
+	 */
+	int descriptor = S390_lowcore.trans_exc_code & 3;
+	if (descriptor == 1)
+		return __check_access_register(regs, error_code);
+	return descriptor >> 1;
+}
+		
+/*
+ * Send SIGSEGV to task.  This is an external routine
+ * to keep the stack usage of do_page_fault small.
+ */
+static void force_sigsegv(struct pt_regs *regs, unsigned long error_code,
+			  int si_code, unsigned long address)
+{
+	struct siginfo si;
+
+#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
+#if defined(CONFIG_SYSCTL)
+	if (sysctl_userprocess_debug)
+#endif
+	{
+		printk("User process fault: interruption code 0x%lX\n",
+		       error_code);
+		printk("failing address: %lX\n", address);
+		show_regs(regs);
+	}
+#endif
+	si.si_signo = SIGSEGV;
+	si.si_code = si_code;
+	si.si_addr = (void *) address;
+	force_sig_info(SIGSEGV, &si, current);
+}
+
+/*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  *
  * error_code:
- *             ****0004       Protection           ->  Write-Protection  (suprression)
- *             ****0010       Segment translation  ->  Not present       (nullification)
- *             ****0011       Page translation     ->  Not present       (nullification)
- *             ****003B       Region third exception ->  Not present       (nullification)
+ *   04       Protection           ->  Write-Protection  (suprression)
+ *   10       Segment translation  ->  Not present       (nullification)
+ *   11       Page translation     ->  Not present       (nullification)
+ *   3b       Region third trans.  ->  Not present       (nullification)
  */
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
 {
         struct task_struct *tsk;
         struct mm_struct *mm;
         struct vm_area_struct * vma;
         unsigned long address;
+	int user_address;
         unsigned long fixup;
-        int write;
 	int si_code = SEGV_MAPERR;
-	int kernel_address = 0;
 
         tsk = current;
         mm = tsk->mm;
@@ -94,13 +163,13 @@
 	 * as a special case because the translation exception code 
 	 * field is not guaranteed to contain valid data in this case.
 	 */
-	if ((error_code & 0xff) == 4 && !(S390_lowcore.trans_exc_code & 4)) {
+	if (error_code == 4 && !(S390_lowcore.trans_exc_code & 4)) {
 
 		/* Low-address protection hit in kernel mode means 
 		   NULL pointer write access in kernel mode.  */
  		if (!(regs->psw.mask & PSW_PROBLEM_STATE)) {
 			address = 0;
-			kernel_address = 1;
+			user_address = 0;
 			goto no_context;
 		}
 
@@ -114,52 +183,15 @@
          * more specific the segment and page table portion of 
          * the address 
          */
-
-        address = S390_lowcore.trans_exc_code&-4096L;
-
+        address = S390_lowcore.trans_exc_code & -4096L;
+	user_address = check_user_space(regs, error_code);
 
 	/*
-	 * Check which address space the address belongs to
+	 * Verify that the fault happened in user space, that
+	 * we are not in an interrupt and that there is a 
+	 * user context.
 	 */
-	switch (S390_lowcore.trans_exc_code & 3)
-	{
-	case 0: /* Primary Segment Table Descriptor */
-		kernel_address = 1;
-		goto no_context;
-
-	case 1: /* STD determined via access register */
-		if (S390_lowcore.exc_access_id == 0)
-		{
-			kernel_address = 1;
-			goto no_context;
-		}
-		if (regs && S390_lowcore.exc_access_id < NUM_ACRS)
-		{
-			if (regs->acrs[S390_lowcore.exc_access_id] == 0)
-			{
-				kernel_address = 1;
-				goto no_context;
-			}
-			if (regs->acrs[S390_lowcore.exc_access_id] == 1)
-			{
-				/* user space address */
-				break;
-			}
-		}
-		die("page fault via unknown access register", regs, error_code);
-        	do_exit(SIGKILL);
-		break;
-
-	case 2: /* Secondary Segment Table Descriptor */
-	case 3: /* Home Segment Table Descriptor */
-		/* user space address */
-		break;
-	}
-
-	/*
-	 * Check whether we have a user MM in the first place.
-	 */
-        if (in_interrupt() || !mm || !(regs->psw.mask & _PSW_IO_MASK_BIT))
+        if (user_address == 0 || in_interrupt() || !mm)
                 goto no_context;
 
 	/*
@@ -167,7 +199,6 @@
 	 * task's user address space, so we can switch on the
 	 * interrupts again and then search the VMAs
 	 */
-
 	__sti();
 
         down_read(&mm->mmap_sem);
@@ -186,31 +217,23 @@
  * we can handle it..
  */
 good_area:
-        write = 0;
 	si_code = SEGV_ACCERR;
+	if (error_code != 4) {
+		/* page not present, check vm flags */
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
+			goto bad_area;
+	} else {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	}
 
-        switch (error_code & 0xFF) {
-                case 0x04:                                /* write, present*/
-                        write = 1;
-                        break;
-                case 0x10:                                   /* not present*/
-                case 0x11:                                   /* not present*/
-                case 0x3B:                                   /* not present*/
-                        if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
-                                goto bad_area;
-                        break;
-                default:
-                       printk("code should be 4, 10 or 11 (%lX) \n",error_code&0xFF);  
-                       goto bad_area;
-        }
-
- survive:
+survive:
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
-	switch (handle_mm_fault(mm, vma, address, write)) {
+	switch (handle_mm_fault(mm, vma, address, error_code == 4)) {
 	case 1:
 		tsk->min_flt++;
 		break;
@@ -237,22 +260,7 @@
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
                 tsk->thread.prot_addr = address;
                 tsk->thread.trap_no = error_code;
-#ifndef CONFIG_SYSCTL
-#ifdef CONFIG_PROCESS_DEBUG
-                printk("User process fault: interruption code 0x%lX\n",error_code);
-                printk("failing address: %lX\n",address);
-		show_regs(regs);
-#endif
-#else
-		if (sysctl_userprocess_debug) {
-			printk("User process fault: interruption code 0x%lX\n",
-			       error_code);
-			printk("failing address: %lX\n", address);
-			show_regs(regs);
-		}
-#endif
-
-		force_sigsegv(tsk, si_code, (void *)address);
+		force_sigsegv(regs, error_code, si_code, address);
                 return;
 	}
 
@@ -267,8 +275,7 @@
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
  */
-
-        if (kernel_address)
+        if (user_address == 0)
                 printk(KERN_ALERT "Unable to handle kernel pointer dereference"
         	       " at virtual kernel address %016lx\n", address);
         else
@@ -312,19 +319,26 @@
 		goto no_context;
 }
 
-/*
- * Send SIGSEGV to task.  This is an external routine
- * to keep the stack usage of do_page_fault small.
- */
-static void force_sigsegv(struct task_struct *tsk, int code, void *address)
+void do_protection_exception(struct pt_regs *regs, unsigned long error_code)
 {
-	struct siginfo si;
-	si.si_signo = SIGSEGV;
-	si.si_code = code;
-	si.si_addr = address;
-	force_sig_info(SIGSEGV, &si, tsk);
+	regs->psw.addr -= (error_code >> 16);
+	do_exception(regs, 4);
 }
 
+void do_segment_exception(struct pt_regs *regs, unsigned long error_code)
+{
+	do_exception(regs, 0x10);
+}
+
+void do_page_exception(struct pt_regs *regs, unsigned long error_code)
+{
+	do_exception(regs, 0x11);
+}
+
+void do_region_exception(struct pt_regs *regs, unsigned long error_code)
+{
+	do_exception(regs, 0x3b);
+}
 
 #ifdef CONFIG_PFAULT
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/s390x/mm/init.c linux/arch/s390x/mm/init.c
--- linux.orig/arch/s390x/mm/init.c	2001-11-09 21:58:02.000000000 +0000
+++ linux/arch/s390x/mm/init.c	2002-07-20 01:08:31.000000000 +0000
@@ -226,7 +226,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);
 }
 
@@ -234,7 +234,7 @@
 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/sh/kernel/entry.S linux/arch/sh/kernel/entry.S
--- linux.orig/arch/sh/kernel/entry.S	2001-10-08 17:39:18.000000000 +0000
+++ linux/arch/sh/kernel/entry.S	2002-07-20 01:08:33.000000000 +0000
@@ -1298,6 +1298,8 @@
 	.long SYMBOL_NAME(sys_madvise)
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
 	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_tkill)
 
 	/*
 	 * NOTE!! This doesn't have to be exact - we just have
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sh/kernel/setup.c linux/arch/sh/kernel/setup.c
--- linux.orig/arch/sh/kernel/setup.c	2001-11-17 02:38:39.000000000 +0000
+++ linux/arch/sh/kernel/setup.c	2002-07-20 01:08:24.000000000 +0000
@@ -140,15 +140,6 @@
     	sh_bios_console_write(s, count);
 }
 
-/*
- *	Receive character from the serial port
- */
-static int sh_console_wait_key(struct console *co)
-{
-	/* Not implemented yet */
-	return 0;
-}
-
 static kdev_t sh_console_device(struct console *c)
 {
     	/* TODO: this is totally bogus */
@@ -183,7 +174,6 @@
 	name:		"bios",
 	write:		sh_console_write,
 	device:		sh_console_device,
-	wait_key:	sh_console_wait_key,
 	setup:		sh_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sh/kernel/signal.c linux/arch/sh/kernel/signal.c
--- linux.orig/arch/sh/kernel/signal.c	2001-10-15 20:36:48.000000000 +0000
+++ linux/arch/sh/kernel/signal.c	2002-07-20 01:08:37.000000000 +0000
@@ -671,10 +671,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/sh/mm/init.c linux/arch/sh/mm/init.c
--- linux.orig/arch/sh/mm/init.c	2001-10-15 20:36:48.000000000 +0000
+++ linux/arch/sh/mm/init.c	2002-07-20 01:08:39.000000000 +0000
@@ -187,7 +187,7 @@
 		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
@@ -200,7 +200,7 @@
 		free_page(p);
 		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/sparc/boot/Makefile linux/arch/sparc/boot/Makefile
--- linux.orig/arch/sparc/boot/Makefile	2000-02-27 04:46:44.000000000 +0000
+++ linux/arch/sparc/boot/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -22,7 +22,7 @@
 clean:
 	rm -f btfixupprep piggyback tftpboot.img btfix.o btfix.s
 
-BTOBJS := $(HEAD) init/main.o init/version.o
+BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o
 BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
 	$(DRIVERS) $(NETWORKS)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/config.in linux/arch/sparc/config.in
--- linux.orig/arch/sparc/config.in	2001-06-12 02:15:27.000000000 +0000
+++ linux/arch/sparc/config.in	2002-07-20 01:08:24.000000000 +0000
@@ -50,6 +50,7 @@
 define_bool CONFIG_SUN_IO y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_SUN_PM y
 
 bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4
 if [ "$CONFIG_SUN4" != "y" ]; then
@@ -211,6 +212,12 @@
         dep_tristate '  PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
         dep_tristate '  PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
         dep_tristate '  PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m
+	if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	  dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
+	  if [ "$CONFIG_ATM" = "y" ]; then
+	    dep_tristate '  PPP over ATM (EXPERIMENTAL)' CONFIG_PPPOATM $CONFIG_PPP
+	  fi
+	fi
       fi
       tristate '  SLIP (serial line) support' CONFIG_SLIP
       if [ "$CONFIG_SLIP" != "n" ]; then
@@ -251,9 +258,7 @@
 
 source fs/Config.in
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   source net/bluetooth/Config.in
-fi
+source net/bluetooth/Config.in
 
 mainmenu_option next_comment
 comment 'Watchdog'
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/defconfig linux/arch/sparc/defconfig
--- linux.orig/arch/sparc/defconfig	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc/defconfig	2002-07-20 01:08:39.000000000 +0000
@@ -40,6 +40,7 @@
 CONFIG_SUN_IO=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_SUN_PM=y
 # CONFIG_SUN4 is not set
 # CONFIG_PCI is not set
 CONFIG_SUN_OPENPROMFS=m
@@ -162,6 +163,11 @@
 CONFIG_IPX=m
 # CONFIG_IPX_INTERN is not set
 CONFIG_ATALK=m
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 CONFIG_DECNET=m
 CONFIG_DECNET_SIOCGIFCONF=y
 # CONFIG_DECNET_ROUTER is not set
@@ -179,6 +185,11 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
 # CONFIG_IDE is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -247,6 +258,7 @@
 CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
@@ -289,7 +301,7 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=m
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/Makefile linux/arch/sparc/kernel/Makefile
--- linux.orig/arch/sparc/kernel/Makefile	2000-12-29 22:07:20.000000000 +0000
+++ linux/arch/sparc/kernel/Makefile	2002-07-20 01:08:31.000000000 +0000
@@ -32,6 +32,7 @@
 obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o
 obj-$(CONFIG_SUN_AUXIO) += auxio.o
 obj-$(CONFIG_PCI) += ebus.o
+obj-$(CONFIG_SUN_PM) += apc.o pmc.o
 
 ifdef CONFIG_SUNOS_EMUL
 obj-y += sys_sunos.o sunos_ioctl.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/apc.c linux/arch/sparc/kernel/apc.c
--- linux.orig/arch/sparc/kernel/apc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/sparc/kernel/apc.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,171 @@
+/* apc - Driver implementation for power management functions
+ * of Aurora Personality Chip (APC) on SPARCstation-4/5 and
+ * derivatives.
+ *
+ * Copyright (c) 2002 Eric Brower (ebrower@usa.net)
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+#include <asm/auxio.h>
+#include <asm/apc.h>
+
+/* Debugging
+ * 
+ * #define APC_DEBUG_LED
+ * #define APC_NO_IDLE
+ */
+
+#define APC_MINOR	MISC_DYNAMIC_MINOR
+#define APC_OBPNAME	"power-management"
+#define APC_DEVNAME "apc"
+
+volatile static u8 *regs; 
+static int apc_regsize;
+
+#define apc_readb(offs)			(sbus_readb(regs+offs))
+#define apc_writeb(val, offs) 	(sbus_writeb(val, regs+offs))
+
+/* 
+ * CPU idle callback function
+ * See .../arch/sparc/kernel/process.c
+ */
+void apc_swift_idle(void)
+{
+#ifdef APC_DEBUG_LED
+	set_auxio(0x00, AUXIO_LED); 
+#endif
+
+	apc_writeb(apc_readb(APC_IDLE_REG) | APC_IDLE_ON, APC_IDLE_REG);
+
+#ifdef APC_DEBUG_LED
+	set_auxio(AUXIO_LED, 0x00); 
+#endif
+} 
+
+static inline void apc_free(void)
+{
+	sbus_iounmap((unsigned long)regs, apc_regsize);
+}
+
+static int apc_open(struct inode *inode, struct file *f)
+{
+	return 0;
+}
+
+static int apc_release(struct inode *inode, struct file *f)
+{
+	return 0;
+}
+
+static int apc_ioctl(struct inode *inode, struct file *f, 
+		     unsigned int cmd, unsigned long arg)
+{
+	__u8 inarg;
+
+	switch (cmd) {
+		case APCIOCGFANCTL:
+			if(put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			break;
+		case APCIOCGCPWR:
+			if(put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			break;
+		case APCIOCGBPORT:
+			if(put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			break;
+
+		case APCIOCSFANCTL:
+			if(get_user(inarg, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG);
+			break;
+		case APCIOCSCPWR:
+			if(get_user(inarg, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG);
+			break;
+		case APCIOCSBPORT:
+			if(get_user(inarg, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG);
+			break;
+		default:
+			return -EINVAL;
+	};
+
+	return 0;
+}
+
+static struct file_operations apc_fops = {
+	ioctl:		apc_ioctl,
+	open:		apc_open,
+	release:	apc_release,
+};
+
+static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
+
+static int __init apc_probe(void)
+{
+	struct sbus_bus *sbus = NULL;
+	struct sbus_dev *sdev = NULL;
+	int iTmp = 0;
+	for_each_sbus(sbus) {
+		for_each_sbusdev(sdev, sbus) {
+			if (!strcmp(sdev->prom_name, APC_OBPNAME)) {
+				goto sbus_done;
+			}
+		}
+	}
+
+sbus_done:
+	if (!sdev) {
+		return -ENODEV;
+	}
+
+	apc_regsize = sdev->reg_addrs[0].reg_size;
+	regs = (u8*) sbus_ioremap(&sdev->resource[0], 0, 
+				   apc_regsize, APC_OBPNAME);
+	if(NULL == regs) {
+		printk(KERN_ERR "%s: unable to map registers\n", APC_DEVNAME);
+		return -ENODEV;
+	}
+
+	iTmp = misc_register(&apc_miscdev);
+	if (iTmp != 0) {
+		printk(KERN_ERR "%s: unable to register device\n", APC_DEVNAME);
+		apc_free();
+		return -ENODEV;
+	}
+
+#ifndef APC_NO_IDLE	
+	/* Assign power management IDLE handler */
+	pm_idle = apc_swift_idle;	
+#endif
+
+	printk(KERN_INFO "%s: power management initialized\n", APC_DEVNAME);
+	return 0;
+}
+
+/* This driver is not critical to the boot process
+ * and is easiest to ioremap when SBus is already
+ * initialized, so we install ourselves thusly:
+ */
+__initcall(apc_probe);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/check_asm.sh linux/arch/sparc/kernel/check_asm.sh
--- linux.orig/arch/sparc/kernel/check_asm.sh	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc/kernel/check_asm.sh	2002-07-20 01:08:29.000000000 +0000
@@ -11,7 +11,7 @@
     echo "	sizeof(struct $2_struct)," >> $4
   ;;
   -ints)
-    sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.ident.*//' -e 's/\.long[ 	]\([0-9]*\)/\1,/' >>$3
+    sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.ident.*//' -e 's/\.global.*//' -e 's/\.long[ 	]\([0-9]*\)/\1,/' >>$3
   ;;
   *)
     exit 1
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/ioport.c linux/arch/sparc/kernel/ioport.c
--- linux.orig/arch/sparc/kernel/ioport.c	2001-10-30 23:08:11.000000000 +0000
+++ linux/arch/sparc/kernel/ioport.c	2002-07-20 01:08:40.000000000 +0000
@@ -161,7 +161,7 @@
 static void *_sparc_alloc_io(unsigned int busno, unsigned long phys,
     unsigned long size, char *name)
 {
-	static int printed_full = 0;
+	static int printed_full;
 	struct xresource *xres;
 	struct resource *res;
 	char *tack;
@@ -351,7 +351,7 @@
  * CPU view of this memory may be inconsistent with
  * a device view and explicit flushing is necessary.
  */
-u32 sbus_map_single(struct sbus_dev *sdev, void *va, long len, int direction)
+dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *va, size_t len, int direction)
 {
 #if 0 /* This is the version that abuses consistent space */
 	unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
@@ -398,7 +398,7 @@
 #endif
 }
 
-void sbus_unmap_single(struct sbus_dev *sdev, u32 ba, long n, int direction)
+void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t ba, size_t n, int direction)
 {
 #if 0 /* This is the version that abuses consistent space */
 	struct resource *res;
@@ -445,7 +445,7 @@
 
 /*
  */
-void sbus_dma_sync_single(struct sbus_dev *sdev, u32 ba, long size, int direction)
+void sbus_dma_sync_single(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction)
 {
 #if 0
 	unsigned long va;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
--- linux.orig/arch/sparc/kernel/irq.c	2001-07-20 01:11:13.000000000 +0000
+++ linux/arch/sparc/kernel/irq.c	2002-07-20 01:08:23.000000000 +0000
@@ -90,7 +90,7 @@
  */
 #define MAX_STATIC_ALLOC	4
 struct irqaction static_irqaction[MAX_STATIC_ALLOC];
-int static_irq_count = 0;
+int static_irq_count;
 
 struct irqaction *irq_action[NR_IRQS+1] = {
 	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/pcic.c linux/arch/sparc/kernel/pcic.c
--- linux.orig/arch/sparc/kernel/pcic.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc/kernel/pcic.c	2002-07-20 01:08:21.000000000 +0000
@@ -185,7 +185,7 @@
  * Only one PCIC per IIep,
  * and since we have no SMP IIep, only one per system.
  */
-static int pcic0_up = 0;
+static int pcic0_up;
 static struct linux_pcic pcic0;
 
 unsigned int pcic_regs;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/pmc.c linux/arch/sparc/kernel/pmc.c
--- linux.orig/arch/sparc/kernel/pmc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/sparc/kernel/pmc.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,99 @@
+/* pmc - Driver implementation for power management functions
+ * of Power Management Controller (PMC) on SPARCstation-Voyager.
+ *
+ * Copyright (c) 2002 Eric Brower (ebrower@usa.net)
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+#include <asm/auxio.h>
+
+/* Debug
+ *
+ * #define PMC_DEBUG_LED
+ * #define PMC_NO_IDLE
+ */
+
+#define PMC_MINOR	MISC_DYNAMIC_MINOR
+#define PMC_OBPNAME	"SUNW,pmc"
+#define PMC_DEVNAME "pmc"
+
+#define PMC_IDLE_REG	0x00
+#define PMC_IDLE_ON		0x01
+
+volatile static u8 *regs; 
+static int pmc_regsize;
+
+#define pmc_readb(offs)			(sbus_readb(regs+offs))
+#define pmc_writeb(val, offs) 	(sbus_writeb(val, regs+offs))
+
+/* 
+ * CPU idle callback function
+ * See .../arch/sparc/kernel/process.c
+ */
+void pmc_swift_idle(void)
+{
+#ifdef PMC_DEBUG_LED
+	set_auxio(0x00, AUXIO_LED); 
+#endif
+
+	pmc_writeb(pmc_readb(PMC_IDLE_REG) | PMC_IDLE_ON, PMC_IDLE_REG);
+
+#ifdef PMC_DEBUG_LED
+	set_auxio(AUXIO_LED, 0x00); 
+#endif
+} 
+
+static inline void pmc_free(void)
+{
+	sbus_iounmap((unsigned long)regs, pmc_regsize);
+}
+
+static int __init pmc_probe(void)
+{
+	struct sbus_bus *sbus = NULL;
+	struct sbus_dev *sdev = NULL;
+	for_each_sbus(sbus) {
+		for_each_sbusdev(sdev, sbus) {
+			if (!strcmp(sdev->prom_name, PMC_OBPNAME)) {
+				goto sbus_done;
+			}
+		}
+	}
+
+sbus_done:
+	if (!sdev) {
+		return -ENODEV;
+	}
+
+	pmc_regsize = sdev->reg_addrs[0].reg_size;
+	regs = (u8*) sbus_ioremap(&sdev->resource[0], 0, 
+				   pmc_regsize, PMC_OBPNAME);
+	if(NULL == regs) {
+		printk(KERN_ERR "%s: unable to map registers\n", PMC_DEVNAME);
+		return -ENODEV;
+	}
+
+#ifndef PMC_NO_IDLE
+	/* Assign power management IDLE handler */
+	pm_idle = pmc_swift_idle;	
+#endif
+
+	printk(KERN_INFO "%s: power management initialized\n", PMC_DEVNAME);
+	return 0;
+}
+
+/* This driver is not critical to the boot process
+ * and is easiest to ioremap when SBus is already
+ * initialized, so we install ourselves thusly:
+ */
+__initcall(pmc_probe);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- linux.orig/arch/sparc/kernel/process.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc/kernel/process.c	2002-07-20 01:08:26.000000000 +0000
@@ -27,6 +27,7 @@
 #include <linux/smp_lock.h>
 #include <linux/reboot.h>
 #include <linux/delay.h>
+#include <linux/pm.h>
 
 #include <asm/auxio.h>
 #include <asm/oplib.h>
@@ -40,6 +41,19 @@
 #include <asm/psr.h>
 #include <asm/elf.h>
 
+/* 
+ * Power management idle function 
+ * Set in pm platform drivers
+ */
+void (*pm_idle)(void);
+
+/* 
+ * Power-off handler instantiation for pm.h compliance
+ * This is done via auxio, but could be used as a fallback
+ * handler when auxio is not present-- unused for now...
+ */
+void (*pm_power_off)(void);
+
 extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 
 struct task_struct *last_task_used_math = NULL;
@@ -67,9 +81,9 @@
 	for (;;) {
 		if (ARCH_SUN4C_SUN4) {
 			static int count = HZ;
-			static unsigned long last_jiffies = 0;
-			static unsigned long last_faults = 0;
-			static unsigned long fps = 0;
+			static unsigned long last_jiffies;
+			static unsigned long last_faults;
+			static unsigned long fps;
 			unsigned long now;
 			unsigned long faults;
 			unsigned long flags;
@@ -87,7 +101,7 @@
 				fps = (fps + (faults - last_faults)) >> 1;
 				last_faults = faults;
 #if 0
-				printk("kernel faults / second = %d\n", fps);
+				printk("kernel faults / second = %ld\n", fps);
 #endif
 				if (fps >= SUN4C_FAULT_HIGH) {
 					sun4c_grow_kernel_ring();
@@ -95,8 +109,13 @@
 			}
 			restore_flags(flags);
 		}
-		check_pgt_cache();
+
+		while((!current->need_resched) && pm_idle) {
+				(*pm_idle)();
+		}
+
 		schedule();
+		check_pgt_cache();
 	}
 	ret = 0;
 out:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c
--- linux.orig/arch/sparc/kernel/ptrace.c	2001-09-19 00:03:51.000000000 +0000
+++ linux/arch/sparc/kernel/ptrace.c	2002-07-20 01:08:36.000000000 +0000
@@ -234,29 +234,13 @@
 
 #ifdef DEBUG_PTRACE
 char *pt_rq [] = {
-"TRACEME",
-"PEEKTEXT",
-"PEEKDATA",
-"PEEKUSR",
-"POKETEXT",
-"POKEDATA",
-"POKEUSR",
-"CONT",
-"KILL",
-"SINGLESTEP",
-"SUNATTACH",
-"SUNDETACH",
-"GETREGS",
-"SETREGS",
-"GETFPREGS",
-"SETFPREGS",
-"READDATA",
-"WRITEDATA",
-"READTEXT",
-"WRITETEXT",
-"GETFPAREGS",
-"SETFPAREGS",
-""
+	/* 0  */ "TRACEME", "PEEKTEXT", "PEEKDATA", "PEEKUSR",
+	/* 4  */ "POKETEXT", "POKEDATA", "POKEUSR", "CONT",
+	/* 8  */ "KILL", "SINGLESTEP", "SUNATTACH", "SUNDETACH",
+	/* 12 */ "GETREGS", "SETREGS", "GETFPREGS", "SETFPREGS",
+	/* 16 */ "READDATA", "WRITEDATA", "READTEXT", "WRITETEXT",
+	/* 20 */ "GETFPAREGS", "SETFPAREGS", "unknown", "unknown",
+	/* 24 */ "SYSCALL", ""
 };
 #endif
 
@@ -284,7 +268,7 @@
 	{
 		char *s;
 
-		if ((request > 0) && (request < 21))
+		if ((request >= 0) && (request <= 24))
 			s = pt_rq [request];
 		else
 			s = "unknown";
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/setup.c linux/arch/sparc/kernel/setup.c
--- linux.orig/arch/sparc/kernel/setup.c	2001-11-13 17:16:05.000000000 +0000
+++ linux/arch/sparc/kernel/setup.c	2002-07-20 01:08:22.000000000 +0000
@@ -47,8 +47,6 @@
 #include <asm/hardirq.h>
 #include <asm/machines.h>
 
-#undef PROM_DEBUG_CONSOLE
-
 struct screen_info screen_info = {
 	0, 0,			/* orig-x, orig-y */
 	0,			/* unused */
@@ -134,6 +132,19 @@
 	}
 }
 
+static void
+prom_console_write(struct console *con, const char *s, unsigned n)
+{
+	prom_printf("%s", s);
+}
+
+static struct console prom_debug_console = {
+	name:		"debug",
+	write:		prom_console_write,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
 int obp_system_intr(void)
 {
 	if (boot_flags & BOOTME_KGDB) {
@@ -166,6 +177,10 @@
 		prom_printf("boot_flags_init: Halt!\n");
 		prom_halt();
 		break;
+	case 'p':
+		/* Use PROM debug console. */
+		register_console(&prom_debug_console);
+		break;
 	default:
 		printk("Unknown boot switch (-%c)\n", c);
 		break;
@@ -280,21 +295,6 @@
 
 struct pt_regs fake_swapper_regs;
 
-#ifdef PROM_DEBUG_CONSOLE
-static void
-prom_console_write(struct console *con, const char *s, unsigned n)
-{
-	prom_printf("%s", s);
-}
-
-static struct console prom_console = {
-	name:		"debug",
-	write:		prom_console_write,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
-};
-#endif
-
 extern void paging_init(void);
 
 void __init setup_arch(char **cmdline_p)
@@ -348,9 +348,6 @@
 		printk("UNKNOWN!\n");
 		break;
 	};
-#ifdef PROM_DEBUG_CONSOLE
-	register_console(&prom_console);
-#endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
@@ -381,7 +378,7 @@
 	if (!root_flags)
 		root_mountflags &= ~MS_RDONLY;
 	ROOT_DEV = to_kdev_t(root_dev);
-#ifdef CONFIG_BLK_DEV_RAM
+#ifdef CONFIG_BLK_DEV_INITRD
 	rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
 	rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
 	rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c
--- linux.orig/arch/sparc/kernel/signal.c	2001-01-24 23:18:06.000000000 +0000
+++ linux/arch/sparc/kernel/signal.c	2002-07-20 01:08:27.000000000 +0000
@@ -664,6 +664,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
 	regs->u_regs[UREG_I0] = signo;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
 
 	/* 4. signal handler */
 	regs->pc = (unsigned long) ka->sa.sa_handler;
@@ -747,6 +748,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
 	regs->u_regs[UREG_I0] = signo;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
 
 	regs->pc = (unsigned long) ka->sa.sa_handler;
 	regs->npc = (regs->pc + 4);
@@ -1172,9 +1174,22 @@
 		signr = dequeue_signal(&current->blocked, &info);
 		spin_unlock_irq(&current->sigmask_lock);
 
-		if (!signr) break;
+		if (!signr)
+			break;
 
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Do the syscall restart before we let the debugger
+			 * look at the child registers.
+			 */
+			if (restart_syscall &&
+			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+				regs->u_regs[UREG_I0] = orig_i0;
+				regs->pc -= 4;
+				regs->npc -= 4;
+				restart_syscall = 0;
+			}
 			current->exit_code = signr;
 			current->state = TASK_STOPPED;
 
@@ -1207,8 +1222,8 @@
 
 		ka = &current->sig->action[signr-1];
 
-		if(ka->sa.sa_handler == SIG_IGN) {
-			if(signr != SIGCHLD)
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
 				continue;
 
 			/* sys_wait4() grabs the master kernel lock, so
@@ -1216,16 +1231,16 @@
 			 * threaded and would not be that difficult to
 			 * do anyways.
 			 */
-			while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
 				;
 			continue;
 		}
-		if(ka->sa.sa_handler == SIG_DFL) {
+		if (ka->sa.sa_handler == SIG_DFL) {
 			unsigned long exit_code = signr;
 
-			if(current->pid == 1)
+			if (current->pid == 1)
 				continue;
-			switch(signr) {
+			switch (signr) {
 			case SIGCONT: case SIGCHLD: case SIGWINCH:
 				continue;
 
@@ -1244,8 +1259,8 @@
 				current->exit_code = signr;
 
 				/* notify_parent() is SMP safe */
-				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
-				     SA_NOCLDSTOP))
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+				      SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
@@ -1264,8 +1279,8 @@
 					struct reg_window *rw = (struct reg_window *)regs->u_regs[UREG_FP];
 					unsigned int ins[8];
 
-					while(rw &&
-					      !(((unsigned long) rw) & 0x3)) {
+					while (rw &&
+					       !(((unsigned long) rw) & 0x3)) {
 						copy_from_user(ins, &rw->ins[0], sizeof(ins));
 						printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
 						rw = (struct reg_window *)(unsigned long)ins[6];
@@ -1286,15 +1301,15 @@
 				/* NOT REACHED */
 			}
 		}
-		if(restart_syscall)
+		if (restart_syscall)
 			syscall_restart(orig_i0, regs, &ka->sa);
 		handle_signal(signr, ka, &info, oldset, regs, svr4_signal);
 		return 1;
 	}
-	if(restart_syscall &&
-	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+	if (restart_syscall &&
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->pc -= 4;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c
--- linux.orig/arch/sparc/kernel/sparc_ksyms.c	2001-07-20 01:11:13.000000000 +0000
+++ linux/arch/sparc/kernel/sparc_ksyms.c	2002-07-20 01:08:25.000000000 +0000
@@ -22,6 +22,7 @@
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
 #endif
+#include <linux/pm.h>
 
 #include <asm/oplib.h>
 #include <asm/delay.h>
@@ -296,3 +297,6 @@
 EXPORT_SYMBOL_DOT(umul);
 EXPORT_SYMBOL_DOT(div);
 EXPORT_SYMBOL_DOT(udiv);
+
+/* Sun Power Management Idle Handler */
+EXPORT_SYMBOL(pm_idle);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/sun4d_smp.c linux/arch/sparc/kernel/sun4d_smp.c
--- linux.orig/arch/sparc/kernel/sun4d_smp.c	2001-11-21 18:31:09.000000000 +0000
+++ linux/arch/sparc/kernel/sun4d_smp.c	2002-07-20 01:08:25.000000000 +0000
@@ -47,7 +47,7 @@
 extern volatile int smp_processors_ready;
 extern unsigned long cpu_present_map;
 extern int smp_num_cpus;
-static int smp_highest_cpu = 0;
+static int smp_highest_cpu;
 extern int smp_threads_ready;
 extern unsigned char mid_xlate[NR_CPUS];
 extern volatile unsigned long cpu_callin_map[NR_CPUS];
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c
--- linux.orig/arch/sparc/kernel/sys_sunos.c	2001-08-15 02:57:28.000000000 +0000
+++ linux/arch/sparc/kernel/sys_sunos.c	2002-07-20 01:08:34.000000000 +0000
@@ -1049,8 +1049,8 @@
 	return ret;
 }
 
-extern asmlinkage int sys_read(unsigned int fd,char *buf,int count);
-extern asmlinkage int sys_write(unsigned int fd,char *buf,int count);
+extern asmlinkage ssize_t sys_read(unsigned int fd,char *buf,int count);
+extern asmlinkage ssize_t sys_write(unsigned int fd,char *buf,int count);
 extern asmlinkage int sys_recv(int fd, void * ubuf, int size, unsigned flags);
 extern asmlinkage int sys_send(int fd, void * buff, int len, unsigned flags);
 extern asmlinkage int sys_accept(int fd, struct sockaddr *sa, int *addrlen);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/systbls.S linux/arch/sparc/kernel/systbls.S
--- linux.orig/arch/sparc/kernel/systbls.S	2001-10-21 17:36:54.000000000 +0000
+++ linux/arch/sparc/kernel/systbls.S	2002-07-20 01:08:37.000000000 +0000
@@ -55,7 +55,7 @@
 /*170*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
 /*175*/	.long sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*180*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_sigpending, sys_query_module
-/*185*/	.long sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_newuname
+/*185*/	.long sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sys_newuname
 /*190*/	.long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*195*/	.long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
 /*200*/	.long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/time.c linux/arch/sparc/kernel/time.c
--- linux.orig/arch/sparc/kernel/time.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc/kernel/time.c	2002-07-20 01:08:22.000000000 +0000
@@ -115,7 +115,7 @@
 void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	/* last time the cmos clock got updated */
-	static long last_rtc_update=0;
+	static long last_rtc_update;
 
 #ifndef CONFIG_SMP
 	if(!user_mode(regs))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/kernel/traps.c linux/arch/sparc/kernel/traps.c
--- linux.orig/arch/sparc/kernel/traps.c	2000-09-07 15:32:00.000000000 +0000
+++ linux/arch/sparc/kernel/traps.c	2002-07-20 01:08:37.000000000 +0000
@@ -272,7 +272,7 @@
 void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 		 unsigned long psr)
 {
-	static int calls = 0;
+	static int calls;
 	siginfo_t info;
 	unsigned long fsr;
 	int ret = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c
--- linux.orig/arch/sparc/mm/init.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc/mm/init.c	2002-07-20 01:08:35.000000000 +0000
@@ -459,7 +459,7 @@
 	initpages = (((unsigned long) &__init_end) - ((unsigned long) &__init_begin));
 	initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT;
 
-	printk("Memory: %dk available (%dk kernel code, %dk data, %dk init, %ldk highmem) [%08lx,%08lx]\n",
+	printk(KERN_INFO "Memory: %dk available (%dk kernel code, %dk data, %dk init, %ldk highmem) [%08lx,%08lx]\n",
 	       nr_free_pages() << (PAGE_SHIFT-10),
 	       codepages << (PAGE_SHIFT-10),
 	       datapages << (PAGE_SHIFT-10), 
@@ -486,14 +486,14 @@
 		totalram_pages++;
 		num_physpages++;
 	}
-	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) {
 		struct page *p = virt_to_page(start);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/mm/iommu.c linux/arch/sparc/mm/iommu.c
--- linux.orig/arch/sparc/mm/iommu.c	2001-02-19 03:49:54.000000000 +0000
+++ linux/arch/sparc/mm/iommu.c	2002-07-20 01:08:35.000000000 +0000
@@ -25,7 +25,7 @@
 BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long)
 #define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page)
 extern int flush_page_for_dma_global;
-static int viking_flush = 0;
+static int viking_flush;
 /* viking.S */
 extern void viking_flush_page(unsigned long page);
 extern void viking_mxcc_flush_page(unsigned long page);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
--- linux.orig/arch/sparc/mm/srmmu.c	2001-11-13 17:16:05.000000000 +0000
+++ linux/arch/sparc/mm/srmmu.c	2002-07-20 01:08:23.000000000 +0000
@@ -394,7 +394,6 @@
 
 static pte_t *srmmu_pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	BUG();
 	return NULL;
 }
 
@@ -1733,7 +1732,7 @@
 static void __init poke_viking(void)
 {
 	unsigned long mreg = srmmu_get_mmureg();
-	static int smp_catch = 0;
+	static int smp_catch;
 
 	if(viking_mxcc_present) {
 		unsigned long mxcc_control = mxcc_get_creg();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/mm/sun4c.c linux/arch/sparc/mm/sun4c.c
--- linux.orig/arch/sparc/mm/sun4c.c	2001-11-13 17:16:05.000000000 +0000
+++ linux/arch/sparc/mm/sun4c.c	2002-07-20 01:08:28.000000000 +0000
@@ -1902,19 +1902,6 @@
 	}
 }
 
-static void sun4c_set_pte(pte_t *ptep, pte_t pte)
-{
-	*ptep = pte;
-}
-
-static void sun4c_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{
-}
-
-static void sun4c_pmd_set(pmd_t * pmdp, pte_t * ptep)
-{
-}
-
 void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr,
 		     int bus_type, int rdonly)
 {
@@ -2093,6 +2080,20 @@
 #define PGD_DIRTY    0x040
 #define PGD_TABLE    (PGD_PRESENT | PGD_RW | PGD_USER | PGD_ACCESSED | PGD_DIRTY)
 
+static void sun4c_set_pte(pte_t *ptep, pte_t pte)
+{
+	*ptep = pte;
+}
+
+static void sun4c_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+{
+}
+
+static void sun4c_pmd_set(pmd_t * pmdp, pte_t * ptep)
+{
+	*pmdp = (PGD_TABLE | (unsigned long) ptep);
+}
+
 static int sun4c_pte_present(pte_t pte)
 {
 	return ((pte_val(pte) & (_SUN4C_PAGE_PRESENT | _SUN4C_PAGE_PRIV)) != 0);
@@ -2508,6 +2509,7 @@
 #else
 	BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_NORM);
 #endif
+	BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NORM);
 
 	BTFIXUPSET_CALL(pte_present, sun4c_pte_present, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pte_clear, sun4c_pte_clear, BTFIXUPCALL_STG0O0);
@@ -2568,5 +2570,4 @@
 	/* These should _never_ get called with two level tables. */
 	BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP);
 	BTFIXUPSET_CALL(pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0);
-	BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NOP);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/mm/swift.S linux/arch/sparc/mm/swift.S
--- linux.orig/arch/sparc/mm/swift.S	2000-07-18 19:29:47.000000000 +0000
+++ linux/arch/sparc/mm/swift.S	2002-07-20 01:08:36.000000000 +0000
@@ -53,11 +53,9 @@
 
 	.globl	swift_flush_cache_mm
 swift_flush_cache_mm:
-#ifndef CONFIG_SMP
 	ld	[%o0 + AOFF_mm_context], %g2
 	cmp	%g2, -1
 	be	swift_flush_cache_mm_out
-#endif
 	WINDOW_FLUSH(%g4, %g5)
 	rd	%psr, %g1
 	andn	%g1, PSR_ET, %g3
@@ -120,11 +118,9 @@
 swift_flush_cache_page:
 	ld	[%o0 + 0x0], %o0		/* XXX vma->vm_mm, GROSS XXX */
 70:
-#ifndef CONFIG_SMP
 	ld	[%o0 + AOFF_mm_context], %g2
 	cmp	%g2, -1
 	be	swift_flush_cache_page_out
-#endif
 	WINDOW_FLUSH(%g4, %g5)
 	rd	%psr, %g1
 	andn	%g1, PSR_ET, %g3
@@ -224,11 +220,9 @@
 	.globl	swift_flush_tlb_all
 swift_flush_tlb_mm:
 swift_flush_tlb_range:
-#ifndef CONFIG_SMP
 	ld	[%o0 + AOFF_mm_context], %g2
 	cmp	%g2, -1
 	be	swift_flush_tlb_all_out
-#endif
 swift_flush_tlb_all:
 	mov	0x400, %o1
 	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
@@ -242,11 +236,9 @@
 	mov	SRMMU_CTX_REG, %g1
 	ld	[%o0 + AOFF_mm_context], %o3
 	andn	%o1, (PAGE_SIZE - 1), %o1
-#ifndef CONFIG_SMP
 	cmp	%o3, -1
 	be	swift_flush_tlb_page_out
 	 nop
-#endif
 #if 1
 	mov	0x400, %o1
 	sta	%g0, [%o1] ASI_M_FLUSH_PROBE	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc/mm/tsunami.S linux/arch/sparc/mm/tsunami.S
--- linux.orig/arch/sparc/mm/tsunami.S	2000-07-18 19:29:47.000000000 +0000
+++ linux/arch/sparc/mm/tsunami.S	2002-07-20 01:08:30.000000000 +0000
@@ -27,10 +27,8 @@
 tsunami_flush_cache_mm:
 tsunami_flush_cache_range:
 	ld	[%o0 + AOFF_mm_context], %g2
-#ifndef CONFIG_SMP
 	cmp	%g2, -1
 	be	tsunami_flush_cache_out
-#endif
 tsunami_flush_cache_all:
 	WINDOW_FLUSH(%g4, %g5)
 tsunami_flush_page_for_dma:
@@ -49,11 +47,9 @@
 	/* More slick stuff... */
 tsunami_flush_tlb_mm:
 tsunami_flush_tlb_range:
-#ifndef CONFIG_SMP
 	ld	[%o0 + AOFF_mm_context], %g2
 	cmp	%g2, -1
 	be	tsunami_flush_tlb_out
-#endif
 tsunami_flush_tlb_all:
 	 mov	0x400, %o1
 	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
@@ -72,10 +68,8 @@
 	mov	SRMMU_CTX_REG, %g1
 	ld	[%o0 + AOFF_mm_context], %o3
 	andn	%o1, (PAGE_SIZE - 1), %o1
-#ifndef CONFIG_SMP
 	cmp	%o3, -1
 	be	tsunami_flush_tlb_page_out
-#endif
 	 lda	[%g1] ASI_M_MMUREGS, %g5
 	sta	%o3, [%g1] ASI_M_MMUREGS
 	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/Makefile linux/arch/sparc64/Makefile
--- linux.orig/arch/sparc64/Makefile	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/Makefile	2002-07-20 01:08:40.000000000 +0000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.51 2001/11/17 00:15:27 davem Exp $
+# $Id: Makefile,v 1.51.2.1 2002/03/14 01:26:21 kanoj Exp $
 # sparc64/Makefile
 #
 # Makefile for the architecture dependent flags and dependencies on the
@@ -48,6 +48,11 @@
   AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL)
 endif
 
+ifeq ($(CONFIG_MCOUNT),y)
+  CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
+  CFLAGS := $(CFLAGS) -pg
+endif
+
 LINKFLAGS = -T arch/sparc64/vmlinux.lds
 
 HEAD := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/config.in linux/arch/sparc64/config.in
--- linux.orig/arch/sparc64/config.in	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/config.in	2002-07-20 01:08:31.000000000 +0000
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.156 2001/11/30 00:17:32 davem Exp $
+# $Id: config.in,v 1.156.2.2 2002/03/14 01:26:21 kanoj Exp $
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
@@ -283,9 +283,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 'Watchdog'
@@ -304,5 +302,9 @@
    bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
    bool '  D-cache flush debugging' CONFIG_DEBUG_DCFLUSH
 fi
+bool 'Stack Overflow Detection Support' CONFIG_STACK_DEBUG
+if [ "$CONFIG_STACK_DEBUG" = "y" ] ; then
+   define_bool CONFIG_MCOUNT y
+fi
 
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- linux.orig/arch/sparc64/defconfig	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/defconfig	2002-07-20 01:08:32.000000000 +0000
@@ -96,6 +96,7 @@
 CONFIG_FB_PM2=y
 # CONFIG_FB_PM2_FIFO_DISCONNECT is not set
 CONFIG_FB_PM2_PCI=y
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_MATROX is not set
 CONFIG_FB_ATY=y
@@ -104,8 +105,10 @@
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
 CONFIG_FB_SBUS=y
 CONFIG_FB_CREATOR=y
 CONFIG_FB_CGSIX=y
@@ -199,6 +202,11 @@
 CONFIG_IPX=m
 # CONFIG_IPX_INTERN is not set
 CONFIG_ATALK=m
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 CONFIG_DECNET=m
 CONFIG_DECNET_SIOCGIFCONF=y
 # CONFIG_DECNET_ROUTER is not set
@@ -238,6 +246,11 @@
 CONFIG_NET_CLS_POLICE=y
 
 #
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+
+#
 # ATA/IDE/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -254,6 +267,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE 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
@@ -268,6 +282,7 @@
 CONFIG_BLK_DEV_IDETAPE=m
 CONFIG_BLK_DEV_IDEFLOPPY=m
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -279,12 +294,15 @@
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_AEC62XX_TUNING is not set
 CONFIG_BLK_DEV_ALI15X3=y
@@ -292,6 +310,7 @@
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
 CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_CMD680 is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
@@ -348,6 +367,7 @@
 CONFIG_SCSI_AIC7XXX=m
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
 CONFIG_AIC7XXX_RESET_DELAY_MS=5000
+# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
 CONFIG_SCSI_AIC7XXX_OLD=m
 CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y
@@ -384,10 +404,6 @@
 #
 CONFIG_FUSION=m
 # CONFIG_FUSION_BOOT is not set
-
-#
-# (ability to boot linux kernel from Fusion device is DISABLED!)
-#
 CONFIG_FUSION_ISENSE=m
 CONFIG_FUSION_CTL=m
 CONFIG_FUSION_LAN=m
@@ -411,7 +427,11 @@
 #
 # CONFIG_IEEE1394_VIDEO1394 is not set
 CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
 CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
 # CONFIG_IEEE1394_VERBOSEDEBUG is not set
 
 #
@@ -423,14 +443,6 @@
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_APPLETALK is not set
-# CONFIG_LTPC is not set
-# CONFIG_COPS is not set
-# CONFIG_IPDDP is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
 CONFIG_EQUALIZER=m
@@ -445,7 +457,6 @@
 CONFIG_HAPPYMEAL=y
 CONFIG_SUNBMAC=m
 CONFIG_SUNQE=m
-CONFIG_SUNLANCE=y
 CONFIG_SUNGEM=y
 CONFIG_NET_VENDOR_3COM=y
 # CONFIG_EL1 is not set
@@ -466,6 +477,7 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=m
+# CONFIG_TC35815 is not set
 # CONFIG_TULIP_MWI is not set
 # CONFIG_TULIP_MMIO is not set
 CONFIG_DE4X5=m
@@ -475,6 +487,7 @@
 # CONFIG_LNE390 is not set
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
+# CONFIG_NATSEMI_CABLE_MAGIC is not set
 CONFIG_NE2K_PCI=m
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
@@ -504,7 +517,7 @@
 CONFIG_HAMACHI=m
 CONFIG_YELLOWFIN=m
 CONFIG_SK98LIN=m
-# CONFIG_TIGON3 is not set
+CONFIG_TIGON3=m
 CONFIG_FDDI=y
 # CONFIG_DEFXX is not set
 CONFIG_SKFP=m
@@ -600,7 +613,7 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-CONFIG_RAMFS=m
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
@@ -741,8 +754,9 @@
 # CONFIG_USB_LONG_TIMEOUT is not set
 
 #
-# USB Controllers
+# USB Host Controller Drivers
 #
+# CONFIG_USB_EHCI_HCD is not set
 CONFIG_USB_UHCI=y
 # CONFIG_USB_UHCI_ALT is not set
 CONFIG_USB_OHCI=y
@@ -751,6 +765,7 @@
 # USB Device Class drivers
 #
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 CONFIG_USB_BLUETOOTH=m
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -768,6 +783,7 @@
 # USB Human Interface Devices (HID)
 #
 CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDDEV is not set
 CONFIG_USB_WACOM=m
 
@@ -796,6 +812,7 @@
 # USB Network adaptors
 #
 CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
 CONFIG_USB_KAWETH=m
 CONFIG_USB_CATC=m
 CONFIG_USB_CDCETHER=m
@@ -841,18 +858,24 @@
 # USB Miscellaneous drivers
 #
 CONFIG_USB_RIO500=m
+# CONFIG_USB_AUERSWALD is not set
 
 #
 # Bluetooth support
 #
 CONFIG_BLUEZ=m
 CONFIG_BLUEZ_L2CAP=m
+CONFIG_BLUEZ_SCO=m
 
 #
 # Bluetooth device drivers
 #
 CONFIG_BLUEZ_HCIUSB=m
+CONFIG_BLUEZ_USB_FW_LOAD=y
+CONFIG_BLUEZ_USB_ZERO_PACKET=y
 CONFIG_BLUEZ_HCIUART=m
+CONFIG_BLUEZ_HCIUART_H4=y
+# CONFIG_BLUEZ_HCIDTL1 is not set
 CONFIG_BLUEZ_HCIVHCI=m
 
 #
@@ -869,3 +892,4 @@
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
+# CONFIG_STACK_DEBUG is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/Makefile linux/arch/sparc64/kernel/Makefile
--- linux.orig/arch/sparc64/kernel/Makefile	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/kernel/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -1,19 +1,11 @@
 # $Id: Makefile,v 1.69 2001/11/19 04:09:53 davem Exp $
 # 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).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
 
 SH = $(CONFIG_SHELL)
 
-.S.s:
-	$(CPP) $(AFLAGS) -ansi $< -o $*.s
-
-.S.o:
-	$(CC) $(AFLAGS) -ansi -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
+EXTRA_AFLAGS := -ansi
 
 all: kernel.o head.o init_task.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/binfmt_aout32.c linux/arch/sparc64/kernel/binfmt_aout32.c
--- linux.orig/arch/sparc64/kernel/binfmt_aout32.c	2001-07-20 03:38:52.000000000 +0000
+++ linux/arch/sparc64/kernel/binfmt_aout32.c	2002-07-20 01:08:37.000000000 +0000
@@ -201,6 +201,7 @@
 	unsigned long error;
 	unsigned long fd_offset;
 	unsigned long rlim;
+	unsigned char orig_thr_flags;
 	int retval;
 
 	ex = *((struct exec *) bprm->buf);		/* exec-header */
@@ -305,8 +306,14 @@
 
 	set_brk(current->mm->start_brk, current->mm->brk);
 
+	/* Make sure STACK_TOP returns the right thing.  */
+	orig_thr_flags = current->thread.flags;
+	current->thread.flags |= SPARC_FLAG_32BIT;
+
 	retval = setup_arg_pages(bprm);
 	if (retval < 0) { 
+		current->thread.flags = orig_thr_flags;
+
 		/* Someone check-me: is this error path enough? */ 
 		send_sig(SIGKILL, current, 0); 
 		return retval;
@@ -314,7 +321,7 @@
 
 	current->mm->start_stack =
 		(unsigned long) create_aout32_tables((char *)bprm->p, bprm);
-	if (!(current->thread.flags & SPARC_FLAG_32BIT)) {
+	if (!(orig_thr_flags & SPARC_FLAG_32BIT)) {
 		unsigned long pgd_cache;
 
 		pgd_cache = ((unsigned long)current->mm->pgd[0])<<11UL;
@@ -323,7 +330,6 @@
 				     : /* no outputs */
 				     : "r" (pgd_cache),
 				       "r" (TSB_REG), "i" (ASI_DMMU));
-		current->thread.flags |= SPARC_FLAG_32BIT;
 	}
 	start_thread32(regs, ex.a_entry, current->mm->start_stack);
 	if (current->ptrace & PT_PTRACED)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/binfmt_elf32.c linux/arch/sparc64/kernel/binfmt_elf32.c
--- linux.orig/arch/sparc64/kernel/binfmt_elf32.c	2000-07-12 02:02:37.000000000 +0000
+++ linux/arch/sparc64/kernel/binfmt_elf32.c	2002-07-20 01:08:31.000000000 +0000
@@ -43,7 +43,7 @@
 	dest[34] = (unsigned int) src->tnpc;		\
 	dest[35] = src->y;				\
 	dest[36] = dest[37] = 0; /* XXX */		\
-} while(0);
+} while (0);
 
 typedef struct {
 	union {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/central.c linux/arch/sparc64/kernel/central.c
--- linux.orig/arch/sparc64/kernel/central.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/central.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: central.c,v 1.14.2.1 2001/12/19 00:16:21 davem Exp $
+/* $Id: central.c,v 1.14.2.2 2002/03/01 01:26:50 davem Exp $
  * central.c: Central FHC driver for Sunfire/Starfire/Wildfire.
  *
  * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
@@ -247,6 +247,55 @@
 	       (central->clkver ? upa_readb(central->clkver) : 0x00));
 }
 
+static void init_all_fhc_hw(void)
+{
+	struct linux_fhc *fhc;
+
+	for(fhc = fhc_list; fhc != NULL; fhc = fhc->next) {
+		u32 tmp;
+
+		/* Clear all of the interrupt mapping registers
+		 * just in case OBP left them in a foul state.
+		 */
+#define ZAP(ICLR, IMAP) \
+do {	u32 imap_tmp; \
+	upa_writel(0, (ICLR)); \
+	upa_readl(ICLR); \
+	imap_tmp = upa_readl(IMAP); \
+	imap_tmp &= ~(0x80000000); \
+	upa_writel(imap_tmp, (IMAP)); \
+	upa_readl(IMAP); \
+} while (0)
+
+		ZAP(fhc->fhc_regs.ffregs + FHC_FFREGS_ICLR,
+		    fhc->fhc_regs.ffregs + FHC_FFREGS_IMAP);
+		ZAP(fhc->fhc_regs.sregs + FHC_SREGS_ICLR,
+		    fhc->fhc_regs.sregs + FHC_SREGS_IMAP);
+		ZAP(fhc->fhc_regs.uregs + FHC_UREGS_ICLR,
+		    fhc->fhc_regs.uregs + FHC_UREGS_IMAP);
+		ZAP(fhc->fhc_regs.tregs + FHC_TREGS_ICLR,
+		    fhc->fhc_regs.tregs + FHC_TREGS_IMAP);
+
+#undef ZAP
+
+		/* Setup FHC control register. */
+		tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
+
+		/* All non-central boards have this bit set. */
+		if(! IS_CENTRAL_FHC(fhc))
+			tmp |= FHC_CONTROL_IXIST;
+
+		/* For all FHCs, clear the firmware synchronization
+		 * line and both low power mode enables.
+		 */
+		tmp &= ~(FHC_CONTROL_AOFF | FHC_CONTROL_BOFF | FHC_CONTROL_SLINE);
+
+		upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
+		upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
+	}
+
+}
+
 void central_probe(void)
 {
 	struct linux_prom_registers fpregs[6];
@@ -341,6 +390,8 @@
 	       ((err & FHC_ID_MANUF) >> 1));
 
 	probe_other_fhcs();
+
+	init_all_fhc_hw();
 }
 
 static __inline__ void fhc_ledblink(struct linux_fhc *fhc, int on)
@@ -398,56 +449,12 @@
 void firetruck_init(void)
 {
 	struct linux_central *central = central_bus;
-	struct linux_fhc *fhc;
 	u8 ctrl;
 
 	/* No central bus, nothing to do. */
 	if (central == NULL)
 		return;
 
-	for(fhc = fhc_list; fhc != NULL; fhc = fhc->next) {
-		u32 tmp;
-
-		/* Clear all of the interrupt mapping registers
-		 * just in case OBP left them in a foul state.
-		 */
-#define ZAP(ICLR, IMAP) \
-do {	u32 imap_tmp; \
-	upa_writel(0, (ICLR)); \
-	upa_readl(ICLR); \
-	imap_tmp = upa_readl(IMAP); \
-	imap_tmp &= ~(0x80000000); \
-	upa_writel(imap_tmp, (IMAP)); \
-	upa_readl(IMAP); \
-} while (0)
-
-		ZAP(fhc->fhc_regs.ffregs + FHC_FFREGS_ICLR,
-		    fhc->fhc_regs.ffregs + FHC_FFREGS_IMAP);
-		ZAP(fhc->fhc_regs.sregs + FHC_SREGS_ICLR,
-		    fhc->fhc_regs.sregs + FHC_SREGS_IMAP);
-		ZAP(fhc->fhc_regs.uregs + FHC_UREGS_ICLR,
-		    fhc->fhc_regs.uregs + FHC_UREGS_IMAP);
-		ZAP(fhc->fhc_regs.tregs + FHC_TREGS_ICLR,
-		    fhc->fhc_regs.tregs + FHC_TREGS_IMAP);
-
-#undef ZAP
-
-		/* Setup FHC control register. */
-		tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
-
-		/* All non-central boards have this bit set. */
-		if(! IS_CENTRAL_FHC(fhc))
-			tmp |= FHC_CONTROL_IXIST;
-
-		/* For all FHCs, clear the firmware synchronization
-		 * line and both low power mode enables.
-		 */
-		tmp &= ~(FHC_CONTROL_AOFF | FHC_CONTROL_BOFF | FHC_CONTROL_SLINE);
-
-		upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
-		upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
-	}
-
 	/* OBP leaves it on, turn it off so clock board timer LED
 	 * is in sync with FHC ones.
 	 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/ebus.c linux/arch/sparc64/kernel/ebus.c
--- linux.orig/arch/sparc64/kernel/ebus.c	2001-11-13 17:16:05.000000000 +0000
+++ linux/arch/sparc64/kernel/ebus.c	2002-07-20 01:08:31.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: ebus.c,v 1.64 2001/11/08 04:41:33 davem Exp $
+/* $Id: ebus.c,v 1.64.2.1 2002/03/12 18:46:14 davem Exp $
  * ebus.c: PCI to EBus bridge device.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -32,7 +32,7 @@
 
 	mem = kmalloc(size, GFP_ATOMIC);
 	if (!mem)
-		panic(__FUNCTION__ ": out of memory");
+		panic("ebus_alloc: out of memory");
 	memset((char *)mem, 0, size);
 	return mem;
 }
@@ -66,7 +66,7 @@
 				   (char *)&ebus->ebus_intmask,
 				   sizeof(ebus->ebus_intmask));
 	if (success == -1) {
-		prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
+		prom_printf("ebus: can't get interrupt-map-mask\n");
 		prom_halt();
 	}
 }
@@ -125,7 +125,7 @@
 			if (rnum >= dev->parent->num_addrs) {
 				prom_printf("UGH: property for %s was %d, need < %d\n",
 					    dev->prom_name, len, dev->parent->num_addrs);
-				panic(__FUNCTION__);
+				panic("fill_ebus_child");
 			}
 			dev->resource[i].start = dev->parent->resource[i].start;
 			dev->resource[i].end = dev->parent->resource[i].end;
@@ -208,7 +208,8 @@
 	dev->num_addrs = len / sizeof(struct linux_prom_registers);
 
 	for (i = 0; i < dev->num_addrs; i++) {
-		if (dev->bus->is_rio == 0)
+		/* XXX Learn how to interpret ebus ranges... -DaveM */
+		if (regs[i].which_io >= 0x10)
 			n = (regs[i].which_io - 0x10) >> 2;
 		else
 			n = regs[i].which_io;
@@ -274,6 +275,25 @@
 	printk("]");
 }
 
+static struct pci_dev *find_next_ebus(struct pci_dev *start, int *is_rio_p)
+{
+	struct pci_dev *pdev = start;
+
+	do {
+		pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_ANY_ID, pdev);
+		if (pdev &&
+		    (pdev->device == PCI_DEVICE_ID_SUN_EBUS ||
+		     pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS))
+			break;
+	} while (pdev != NULL);
+
+	if (pdev && (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS))
+		*is_rio_p = 1;
+	else
+		*is_rio_p = 0;
+
+	return pdev;
+}
 
 void __init ebus_init(void)
 {
@@ -288,12 +308,7 @@
 	if (!pci_present())
 		return;
 
-	is_rio = 0;
-	pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
-	if (!pdev) {
-		pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_RIO_EBUS, 0);
-		is_rio = 1;
-	}
+	pdev = find_next_ebus(NULL, &is_rio);
 	if (!pdev) {
 		printk("ebus: No EBus's found.\n");
 		return;
@@ -314,16 +329,7 @@
 		   we'd have to tweak with the ebus_chain
 		   in the runtime after initialization. -jj */
 		if (!prom_getchild (ebusnd)) {
-			struct pci_dev *orig_pdev = pdev;
-
-			is_rio = 0;
-			pdev = pci_find_device(PCI_VENDOR_ID_SUN, 
-					       PCI_DEVICE_ID_SUN_EBUS, orig_pdev);
-			if (!pdev) {
-				pdev = pci_find_device(PCI_VENDOR_ID_SUN, 
-						       PCI_DEVICE_ID_SUN_RIO_EBUS, orig_pdev);
-				is_rio = 1;
-			}
+			pdev = find_next_ebus(pdev, &is_rio);
 			if (!pdev) {
 				if (ebus == ebus_chain) {
 					ebus_chain = NULL;
@@ -373,20 +379,9 @@
 	next_ebus:
 		printk("\n");
 
-		{
-			struct pci_dev *orig_pdev = pdev;
-
-			is_rio = 0;
-			pdev = pci_find_device(PCI_VENDOR_ID_SUN,
-					       PCI_DEVICE_ID_SUN_EBUS, orig_pdev);
-			if (!pdev) {
-				pdev = pci_find_device(PCI_VENDOR_ID_SUN,
-						       PCI_DEVICE_ID_SUN_RIO_EBUS, orig_pdev);
-				is_rio = 1;
-			}
-			if (!pdev)
-				break;
-		}
+		pdev = find_next_ebus(pdev, &is_rio);
+		if (!pdev)
+			break;
 
 		cookie = pdev->sysdata;
 		ebusnd = cookie->prom_node;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/head.S linux/arch/sparc64/kernel/head.S
--- linux.orig/arch/sparc64/kernel/head.S	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/kernel/head.S	2002-07-20 01:08:33.000000000 +0000
@@ -567,13 +567,6 @@
 #define KERN_HIGHBITS		((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
 #define KERN_LOWBITS		(_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
 
-#define VPTE_BASE_SPITFIRE	0xfffffffe00000000
-#if 1
-#define VPTE_BASE_CHEETAH	VPTE_BASE_SPITFIRE
-#else
-#define VPTE_BASE_CHEETAH	0xffe0000000000000
-#endif
-
 	mov	TSB_REG, %g1
 	stxa	%g0, [%g1] ASI_DMMU
 	membar	#Sync
@@ -604,8 +597,6 @@
 	clr	%g7
 #undef KERN_HIGHBITS
 #undef KERN_LOWBITS
-#undef VPTE_BASE_SPITFIRE
-#undef VPTE_BASE_CHEETAH
 
 	/* Setup Interrupt globals */
 	wrpr	%o1, (PSTATE_IG|PSTATE_IE), %pstate
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c
--- linux.orig/arch/sparc64/kernel/ioctl32.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/ioctl32.c	2002-07-20 01:08:32.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.133.2.2 2002/01/14 09:49:29 davem Exp $
+/* $Id: ioctl32.c,v 1.133.2.5 2002/03/01 08:52:38 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -32,6 +32,7 @@
 #include <linux/ppp_defs.h>
 #include <linux/if_ppp.h>
 #include <linux/if_pppox.h>
+#include <linux/if_tun.h>
 #include <linux/mtio.h>
 #include <linux/cdrom.h>
 #include <linux/loop.h>
@@ -76,6 +77,7 @@
 #include <asm/watchdog.h>
 #include <asm/module.h>
 #include <linux/soundcard.h>
+#include <linux/lp.h>
 
 #include <linux/atm.h>
 #include <linux/atmarp.h>
@@ -96,6 +98,7 @@
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/nbd.h>
+#include <linux/random.h>
 
 /* Use this to get at 32-bit user passed pointers. 
    See sys_sparc32.c for description about these. */
@@ -1059,7 +1062,7 @@
 		break;
 	default:
 		do {
-			static int count = 0;
+			static int count;
 			if (++count <= 20)
 				printk("%s: Unknown fb ioctl cmd fd(%d) "
 				       "cmd(%08x) arg(%08lx)\n",
@@ -1712,7 +1715,7 @@
 		break;
 	default:
 		do {
-			static int count = 0;
+			static int count;
 			if (++count <= 20)
 				printk("ppp_ioctl: Unknown cmd fd(%d) "
 				       "cmd(%08x) arg(%08x)\n",
@@ -1822,7 +1825,7 @@
 		break;
 	default:
 		do {
-			static int count = 0;
+			static int count;
 			if (++count <= 20)
 				printk("mt_ioctl: Unknown cmd fd(%d) "
 				       "cmd(%08x) arg(%08x)\n",
@@ -1940,7 +1943,7 @@
 		break;
 	default:
 		do {
-			static int count = 0;
+			static int count;
 			if (++count <= 20)
 				printk("cdrom_ioctl: Unknown cmd fd(%d) "
 				       "cmd(%08x) arg(%08x)\n",
@@ -2027,7 +2030,7 @@
 		}
 		break;
 	default: {
-		static int count = 0;
+		static int count;
 		if (++count <= 20)
 			printk("%s: Unknown loop ioctl cmd, fd(%d) "
 			       "cmd(%08x) arg(%08lx)\n",
@@ -3906,6 +3909,8 @@
 COMPATIBLE_IOCTL(TCSETSW)
 COMPATIBLE_IOCTL(TCSETSF)
 COMPATIBLE_IOCTL(TIOCLINUX)
+COMPATIBLE_IOCTL(TIOCSTART)
+COMPATIBLE_IOCTL(TIOCSTOP)
 /* Little t */
 COMPATIBLE_IOCTL(TIOCGETD)
 COMPATIBLE_IOCTL(TIOCSETD)
@@ -3932,6 +3937,7 @@
 COMPATIBLE_IOCTL(TIOCGSERIAL)
 COMPATIBLE_IOCTL(TIOCSSERIAL)
 COMPATIBLE_IOCTL(TIOCSERGETLSR)
+COMPATIBLE_IOCTL(TIOCSLTC)
 /* Big F */
 COMPATIBLE_IOCTL(FBIOGTYPE)
 COMPATIBLE_IOCTL(FBIOSATTR)
@@ -4071,6 +4077,8 @@
 COMPATIBLE_IOCTL(KIOCGRATE)
 /* Big S */
 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
+COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
 COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
 COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
 COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
@@ -4078,6 +4086,12 @@
 COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE)
 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
 COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
+/* Big T */
+COMPATIBLE_IOCTL(TUNSETNOCSUM)
+COMPATIBLE_IOCTL(TUNSETDEBUG)
+COMPATIBLE_IOCTL(TUNSETIFF)
+COMPATIBLE_IOCTL(TUNSETPERSIST)
+COMPATIBLE_IOCTL(TUNSETOWNER)
 /* Big V */
 COMPATIBLE_IOCTL(VT_SETMODE)
 COMPATIBLE_IOCTL(VT_GETMODE)
@@ -4191,6 +4205,8 @@
 COMPATIBLE_IOCTL(SIOCGMIIPHY)
 COMPATIBLE_IOCTL(SIOCGMIIREG)
 COMPATIBLE_IOCTL(SIOCSMIIREG)
+COMPATIBLE_IOCTL(SIOCGIFVLAN)
+COMPATIBLE_IOCTL(SIOCSIFVLAN)
 /* SG stuff */
 COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
 COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
@@ -4227,6 +4243,7 @@
 COMPATIBLE_IOCTL(PPPIOCSMRU)
 COMPATIBLE_IOCTL(PPPIOCSMAXCID)
 COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
+COMPATIBLE_IOCTL(LPGETSTATUS)
 COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
 COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
 COMPATIBLE_IOCTL(PPPIOCGNPMODE)
@@ -4242,8 +4259,8 @@
 COMPATIBLE_IOCTL(PPPIOCATTCHAN)
 COMPATIBLE_IOCTL(PPPIOCGCHAN)
 /* PPPOX */
-COMPATIBLE_IOCTL(PPPOEIOCSFWD);
-COMPATIBLE_IOCTL(PPPOEIOCDFWD);
+COMPATIBLE_IOCTL(PPPOEIOCSFWD)
+COMPATIBLE_IOCTL(PPPOEIOCDFWD)
 /* CDROM stuff */
 COMPATIBLE_IOCTL(CDROMPAUSE)
 COMPATIBLE_IOCTL(CDROMRESUME)
@@ -4529,16 +4546,31 @@
 COMPATIBLE_IOCTL(WIOCSTART)
 COMPATIBLE_IOCTL(WIOCSTOP)
 COMPATIBLE_IOCTL(WIOCGSTAT)
+/* Big R */
+COMPATIBLE_IOCTL(RNDGETENTCNT)
+COMPATIBLE_IOCTL(RNDADDTOENTCNT)
+COMPATIBLE_IOCTL(RNDGETPOOL)
+COMPATIBLE_IOCTL(RNDADDENTROPY)
+COMPATIBLE_IOCTL(RNDZAPENTCNT)
+COMPATIBLE_IOCTL(RNDCLEARPOOL)
 /* Bluetooth ioctls */
 COMPATIBLE_IOCTL(HCIDEVUP)
 COMPATIBLE_IOCTL(HCIDEVDOWN)
 COMPATIBLE_IOCTL(HCIDEVRESET)
-COMPATIBLE_IOCTL(HCIRESETSTAT)
-COMPATIBLE_IOCTL(HCIGETINFO)
+COMPATIBLE_IOCTL(HCIDEVRESTAT)
 COMPATIBLE_IOCTL(HCIGETDEVLIST)
+COMPATIBLE_IOCTL(HCIGETDEVINFO)
+COMPATIBLE_IOCTL(HCIGETCONNLIST)
+COMPATIBLE_IOCTL(HCIGETCONNINFO)
 COMPATIBLE_IOCTL(HCISETRAW)
 COMPATIBLE_IOCTL(HCISETSCAN)
 COMPATIBLE_IOCTL(HCISETAUTH)
+COMPATIBLE_IOCTL(HCISETENCRYPT)
+COMPATIBLE_IOCTL(HCISETPTYPE)
+COMPATIBLE_IOCTL(HCISETLINKPOL)
+COMPATIBLE_IOCTL(HCISETLINKMODE)
+COMPATIBLE_IOCTL(HCISETACLMTU)
+COMPATIBLE_IOCTL(HCISETSCOMTU)
 COMPATIBLE_IOCTL(HCIINQUIRY)
 /* Misc. */
 COMPATIBLE_IOCTL(0x41545900)		/* ATYIO_CLKR */
@@ -4734,15 +4766,15 @@
 HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
 #endif /* LVM */
 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
+HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
+HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
+HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
+HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
+HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
+HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
 #endif /* DRM */
 #if 0
 HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
@@ -4870,7 +4902,7 @@
 		handler = (void *)(long)t->handler;
 		error = handler(fd, cmd, arg, filp);
 	} else {
-		static int count = 0;
+		static int count;
 		if (++count <= 20)
 			printk("sys32_ioctl(%s:%d): Unknown cmd fd(%d) "
 			       "cmd(%08x) arg(%08x)\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c
--- linux.orig/arch/sparc64/kernel/irq.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/kernel/irq.c	2002-07-20 01:08:33.000000000 +0000
@@ -81,7 +81,7 @@
  */
 #define MAX_STATIC_ALLOC	4
 static struct irqaction static_irqaction[MAX_STATIC_ALLOC];
-static int static_irq_count = 0;
+static int static_irq_count;
 
 /* This is exported so that fast IRQ handlers can get at it... -DaveM */
 struct irqaction *irq_action[NR_IRQS+1] = {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/pci.c linux/arch/sparc64/kernel/pci.c
--- linux.orig/arch/sparc64/kernel/pci.c	2001-10-11 06:42:46.000000000 +0000
+++ linux/arch/sparc64/kernel/pci.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.36 2001/10/06 00:38:25 davem Exp $
+/* $Id: pci.c,v 1.36.2.4 2002/02/10 15:06:48 ecd Exp $
  * pci.c: UltraSparc PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -234,33 +234,63 @@
 	return request_resource(root, res);
 }
 
+/*
+ * Given the PCI bus a device resides on, try to
+ * find an acceptable resource allocation for a
+ * specific device resource..
+ */
+static int pci_assign_bus_resource(const struct pci_bus *bus,
+	struct pci_dev *dev,
+	struct resource *res,
+	unsigned long size,
+	unsigned long min,
+	int resno)
+{
+	unsigned int type_mask;
+	int i;
+
+	type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+	for (i = 0 ; i < 4; i++) {
+		struct resource *r = bus->resource[i];
+		if (!r)
+			continue;
+
+		/* type_mask must match */
+		if ((res->flags ^ r->flags) & type_mask)
+			continue;
+
+		/* Ok, try it out.. */
+		if (allocate_resource(r, res, size, min, -1, size, NULL, NULL) < 0)
+			continue;
+
+		/* PCI config space updated by caller.  */
+		return 0;
+	}
+	return -EBUSY;
+}
+
 int pci_assign_resource(struct pci_dev *pdev, int resource)
 {
 	struct pcidev_cookie *pcp = pdev->sysdata;
 	struct pci_pbm_info *pbm = pcp->pbm;
 	struct resource *res = &pdev->resource[resource];
-	struct resource *root;
-	unsigned long min, max, size, align;
+	unsigned long min, size;
 	int err;
 
-	if (res->flags & IORESOURCE_IO) {
-		root = &pbm->io_space;
-		min = root->start + 0x400UL;
-		max = root->end;
-	} else {
-		root = &pbm->mem_space;
-		min = root->start;
-		max = min + 0x80000000UL;
-	}
+	if (res->flags & IORESOURCE_IO)
+		min = pbm->io_space.start + 0x400UL;
+	else
+		min = pbm->mem_space.start;
+
+	size = res->end - res->start + 1;
 
-	size = res->end - res->start;
-	align = size + 1;
+	err = pci_assign_bus_resource(pdev->bus, pdev, res, size, min, resource);
 
-	err = allocate_resource(root, res, size + 1, min, max, align, NULL, NULL);
 	if (err < 0) {
 		printk("PCI: Failed to allocate resource %d for %s\n",
 		       resource, pdev->name);
 	} else {
+		/* Update PCI config space. */
 		pbm->parent->base_address_update(pdev, resource);
 	}
 
@@ -418,7 +448,7 @@
 				  enum pci_mmap_state mmap_state)
 {
 	unsigned long user_offset = vma->vm_pgoff << PAGE_SHIFT;
-	unsigned long user32 = user_offset & 0xffffffffUL;
+	unsigned long user32 = user_offset & pci_memspace_mask;
 	unsigned long largest_base, this_base, addr32;
 	int i;
 
@@ -448,7 +478,7 @@
 
 		this_base = rp->start;
 
-		addr32 = (this_base & PAGE_MASK) & 0xffffffffUL;
+		addr32 = (this_base & PAGE_MASK) & pci_memspace_mask;
 
 		if (mmap_state == pci_mmap_io)
 			addr32 &= 0xffffff;
@@ -464,7 +494,7 @@
 	if (mmap_state == pci_mmap_io)
 		vma->vm_pgoff = (((largest_base & ~0xffffffUL) | user32) >> PAGE_SHIFT);
 	else
-		vma->vm_pgoff = (((largest_base & ~0xffffffffUL) | user32) >> PAGE_SHIFT);
+		vma->vm_pgoff = (((largest_base & ~(pci_memspace_mask)) | user32) >> PAGE_SHIFT);
 
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/pci_common.c linux/arch/sparc64/kernel/pci_common.c
--- linux.orig/arch/sparc64/kernel/pci_common.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/pci_common.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: pci_common.c,v 1.27.2.2 2002/02/01 00:56:44 davem Exp $
+/* $Id: pci_common.c,v 1.27.2.5 2002/03/10 05:21:26 davem Exp $
  * pci_common.c: PCI controller common support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -571,33 +571,55 @@
 	struct pci_pbm_info *pbm = dev_pcp->pbm;
 	struct linux_prom_pci_registers *pregs = dev_pcp->prom_regs;
 	unsigned int hi, mid, lo, irq;
-	int i, num_intmap;
-
-	if (pbm->num_pbm_intmap == 0)
-		return 0;
+	int i, num_intmap, map_slot;
 
 	intmap = &pbm->pbm_intmap[0];
 	intmask = &pbm->pbm_intmask;
 	num_intmap = pbm->num_pbm_intmap;
+	map_slot = 0;
 
 	/* If we are underneath a PCI bridge, use PROM register
 	 * property of the parent bridge which is closest to
 	 * the PBM.
+	 *
+	 * However if that parent bridge has interrupt map/mask
+	 * properties of it's own we use the PROM register property
+	 * of the next child device on the path to PDEV.
+	 *
+	 * In detail the two cases are (note that the 'X' below is the
+	 * 'next child on the path to PDEV' mentioned above):
+	 *
+	 * 1) PBM --> PCI bus lacking int{map,mask} --> X ... PDEV
+	 *
+	 *    Here we use regs of 'PCI bus' device.
+	 *
+	 * 2) PBM --> PCI bus with int{map,mask} --> X ... PDEV
+	 *
+	 *    Here we use regs of 'X'.  Note that X can be PDEV.
 	 */
 	if (pdev->bus->number != pbm->pci_first_busno) {
-		struct pcidev_cookie *bus_pcp;
-		struct pci_dev *pwalk;
-		int offset, plen;
-
-		pwalk = pdev->bus->self;
-		while (pwalk->bus &&
-		       pwalk->bus->number != pbm->pci_first_busno)
-			pwalk = pwalk->bus->self;
+		struct pcidev_cookie *bus_pcp, *regs_pcp;
+		struct pci_dev *bus_dev, *regs_dev;
+		int plen;
+
+		bus_dev = pdev->bus->self;
+		regs_dev = pdev;
+
+		while (bus_dev->bus &&
+		       bus_dev->bus->number != pbm->pci_first_busno) {
+			regs_dev = bus_dev;
+			bus_dev = bus_dev->bus->self;
+		}
 
-		bus_pcp = pwalk->sysdata;
+		regs_pcp = regs_dev->sysdata;
+		pregs = regs_pcp->prom_regs;
+
+		bus_pcp = bus_dev->sysdata;
 
 		/* But if the PCI bridge has it's own interrupt map
-		 * and mask properties, use that and the device regs.
+		 * and mask properties, use that and the regs of the
+		 * PCI entity at the next level down on the path to the
+		 * device.
 		 */
 		plen = prom_getproperty(bus_pcp->prom_node, "interrupt-map",
 					(char *) &bridge_local_intmap[0],
@@ -605,38 +627,31 @@
 		if (plen != -1) {
 			intmap = &bridge_local_intmap[0];
 			num_intmap = plen / sizeof(struct linux_prom_pci_intmap);
-			plen = prom_getproperty(bus_pcp->prom_node, "interrupt-map-mask",
+			plen = prom_getproperty(bus_pcp->prom_node,
+						"interrupt-map-mask",
 						(char *) &bridge_local_intmask,
 						sizeof(bridge_local_intmask));
 			if (plen == -1) {
-				prom_printf("pbm_intmap_match: Bridge has intmap but "
-					    "no intmask.\n");
-				prom_halt();
+				printk("pci_intmap_match: Warning! Bridge has intmap "
+				       "but no intmask.\n");
+				printk("pci_intmap_match: Trying to recover.\n");
+				return 0;
 			}
-			goto check_intmap;
-		}
 
-		pregs = bus_pcp->prom_regs;
-
-		offset = prom_getint(dev_pcp->prom_node,
-				     "fcode-rom-offset");
-
-		/* Did PROM know better and assign an interrupt other
-		 * than #INTA to the device? - We test here for presence of
-		 * FCODE on the card, in this case we assume PROM has set
-		 * correct 'interrupts' property, unless it is quadhme.
-		 */
-		if (offset == -1 ||
-		    !strcmp(dev_pcp->prom_name, "SUNW,qfe") ||
-		    !strcmp(dev_pcp->prom_name, "qfe")) {
-			/*
-			 * No, use low slot number bits of child as IRQ line.
-			 */
-			*interrupt = ((*interrupt - 1 + PCI_SLOT(pdev->devfn)) & 3) + 1;
+			if (pdev->bus->self != bus_dev)
+				map_slot = 1;
+		} else {
+			pregs = bus_pcp->prom_regs;
+			map_slot = 1;
 		}
 	}
 
-check_intmap:
+	if (map_slot) {
+		*interrupt = ((*interrupt
+			       - 1
+			       + PCI_SLOT(pdev->devfn)) & 0x3) + 1;
+	}
+
 	hi   = pregs->phys_hi & intmask->phys_hi;
 	mid  = pregs->phys_mid & intmask->phys_mid;
 	lo   = pregs->phys_lo & intmask->phys_lo;
@@ -648,16 +663,35 @@
 		    intmap[i].phys_lo  == lo	&&
 		    intmap[i].interrupt == irq) {
 			*interrupt = intmap[i].cinterrupt;
+			printk("PCI-IRQ: Routing bus[%2x] slot[%2x] map[%d] to INO[%02x]\n",
+			       pdev->bus->number, PCI_SLOT(pdev->devfn),
+			       map_slot, *interrupt);
 			return 1;
 		}
 	}
 
-	prom_printf("pbm_intmap_match: bus %02x, devfn %02x: ",
-		    pdev->bus->number, pdev->devfn);
-	prom_printf("IRQ [%08x.%08x.%08x.%08x] not found in interrupt-map\n",
-		    pregs->phys_hi, pregs->phys_mid, pregs->phys_lo, *interrupt);
-	prom_printf("Please email this information to davem@redhat.com\n");
-	prom_halt();
+	/* We will run this code even if pbm->num_pbm_intmap is zero, just so
+	 * we can apply the slot mapping to the PROM interrupt property value.
+	 * So do not spit out these warnings in that case.
+	 */
+	if (num_intmap != 0) {
+		/* Print it both to OBP console and kernel one so that if bootup
+		 * hangs here the user has the information to report.
+		 */
+		prom_printf("pci_intmap_match: bus %02x, devfn %02x: ",
+			    pdev->bus->number, pdev->devfn);
+		prom_printf("IRQ [%08x.%08x.%08x.%08x] not found in interrupt-map\n",
+			    pregs->phys_hi, pregs->phys_mid, pregs->phys_lo, *interrupt);
+		prom_printf("Please email this information to davem@redhat.com\n");
+
+		printk("pci_intmap_match: bus %02x, devfn %02x: ",
+		       pdev->bus->number, pdev->devfn);
+		printk("IRQ [%08x.%08x.%08x.%08x] not found in interrupt-map\n",
+		       pregs->phys_hi, pregs->phys_mid, pregs->phys_lo, *interrupt);
+		printk("Please email this information to davem@redhat.com\n");
+	}
+
+	return 0;
 }
 
 static void __init pdev_fixup_irq(struct pci_dev *pdev)
@@ -738,12 +772,19 @@
 		 * ranges. -DaveM
  		 */
 		if (pdev->bus->number == pbm->pci_first_busno) {
-			slot = (pdev->devfn >> 3) - pbm->pci_first_slot;
+			slot = PCI_SLOT(pdev->devfn) - pbm->pci_first_slot;
 		} else {
+			struct pci_dev *bus_dev;
+
 			/* Underneath a bridge, use slot number of parent
-			 * bridge.
+			 * bridge which is closest to the PBM.
 			 */
-			slot = (pdev->bus->self->devfn >> 3) - pbm->pci_first_slot;
+			bus_dev = pdev->bus->self;
+			while (bus_dev->bus &&
+			       bus_dev->bus->number != pbm->pci_first_busno)
+				bus_dev = bus_dev->bus->self;
+
+			slot = PCI_SLOT(bus_dev->devfn) - pbm->pci_first_slot;
 		}
 		slot = slot << 2;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/pci_psycho.c linux/arch/sparc64/kernel/pci_psycho.c
--- linux.orig/arch/sparc64/kernel/pci_psycho.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/pci_psycho.c	2002-07-20 01:08:38.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.30.2.2 2002/02/01 00:57:47 davem Exp $
+/* $Id: pci_psycho.c,v 1.30.2.3 2002/03/03 10:31:56 davem Exp $
  * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -326,15 +326,15 @@
 /*0x14*/0, 0, 0, 0,	/* PCI B slot 1  Int A, B, C, D */
 /*0x18*/0, 0, 0, 0,	/* PCI B slot 2  Int A, B, C, D */
 /*0x1c*/0, 0, 0, 0,	/* PCI B slot 3  Int A, B, C, D */
-/*0x20*/3,		/* SCSI				*/
+/*0x20*/4,		/* SCSI				*/
 /*0x21*/5,		/* Ethernet			*/
 /*0x22*/8,		/* Parallel Port		*/
 /*0x23*/13,		/* Audio Record			*/
 /*0x24*/14,		/* Audio Playback		*/
 /*0x25*/15,		/* PowerFail			*/
-/*0x26*/3,		/* second SCSI			*/
+/*0x26*/4,		/* second SCSI			*/
 /*0x27*/11,		/* Floppy			*/
-/*0x28*/2,		/* Spare Hardware		*/
+/*0x28*/4,		/* Spare Hardware		*/
 /*0x29*/9,		/* Keyboard			*/
 /*0x2a*/4,		/* Mouse			*/
 /*0x2b*/12,		/* Serial			*/
@@ -344,7 +344,7 @@
 /*0x2f*/15,		/* Correctable ECC		*/
 /*0x30*/15,		/* PCI Bus A Error		*/
 /*0x31*/15,		/* PCI Bus B Error		*/
-/*0x32*/1,		/* Power Management		*/
+/*0x32*/15,		/* Power Management		*/
 };
 
 static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
@@ -353,7 +353,7 @@
 
 	ret = psycho_pil_table[ino];
 	if (ret == 0 && pdev == NULL) {
-		ret = 1;
+		ret = 4;
 	} else if (ret == 0) {
 		switch ((pdev->class >> 16) & 0xff) {
 		case PCI_BASE_CLASS_STORAGE:
@@ -376,7 +376,7 @@
 			break;
 
 		default:
-			ret = 1;
+			ret = 4;
 			break;
 		};
 	}
@@ -409,6 +409,10 @@
 
 	/* Now build the IRQ bucket. */
 	pil = psycho_ino_to_pil(pdev, ino);
+
+	if (PIL_RESERVED(pil))
+		BUG();
+
 	imap = p->controller_regs + imap_off;
 	imap += 4;
 
@@ -1097,7 +1101,14 @@
 	int where, size, is_64bit;
 
 	res = &pdev->resource[resource];
-	where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	if (resource < 6) {
+		where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	} else if (resource == PCI_ROM_RESOURCE) {
+		where = pdev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
 
 	is_64bit = 0;
 	if (res->flags & IORESOURCE_IO)
@@ -1113,6 +1124,10 @@
 	pci_read_config_dword(pdev, where, &reg);
 	reg = ((reg & size) |
 	       (((u32)(res->start - root->start)) & ~size));
+	if (resource == PCI_ROM_RESOURCE) {
+		reg |= PCI_ROM_ADDRESS_ENABLE;
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+	}
 	pci_write_config_dword(pdev, where, reg);
 
 	/* This knows that the upper 32-bits of the address
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/pci_sabre.c linux/arch/sparc64/kernel/pci_sabre.c
--- linux.orig/arch/sparc64/kernel/pci_sabre.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/kernel/pci_sabre.c	2002-07-20 01:08:35.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.41 2001/11/14 13:17:56 davem Exp $
+/* $Id: pci_sabre.c,v 1.41.2.1 2002/03/03 10:31:56 davem Exp $
  * pci_sabre.c: Sabre specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -564,15 +564,15 @@
 /*0x14*/0, 0, 0, 0,	/* PCI B slot 1  Int A, B, C, D */
 /*0x18*/0, 0, 0, 0,	/* PCI B slot 2  Int A, B, C, D */
 /*0x1c*/0, 0, 0, 0,	/* PCI B slot 3  Int A, B, C, D */
-/*0x20*/3,		/* SCSI				*/
+/*0x20*/4,		/* SCSI				*/
 /*0x21*/5,		/* Ethernet			*/
 /*0x22*/8,		/* Parallel Port		*/
 /*0x23*/13,		/* Audio Record			*/
 /*0x24*/14,		/* Audio Playback		*/
 /*0x25*/15,		/* PowerFail			*/
-/*0x26*/3,		/* second SCSI			*/
+/*0x26*/4,		/* second SCSI			*/
 /*0x27*/11,		/* Floppy			*/
-/*0x28*/2,		/* Spare Hardware		*/
+/*0x28*/4,		/* Spare Hardware		*/
 /*0x29*/9,		/* Keyboard			*/
 /*0x2a*/4,		/* Mouse			*/
 /*0x2b*/12,		/* Serial			*/
@@ -582,7 +582,7 @@
 /*0x2f*/15,		/* Correctable ECC		*/
 /*0x30*/15,		/* PCI Bus A Error		*/
 /*0x31*/15,		/* PCI Bus B Error		*/
-/*0x32*/1,		/* Power Management		*/
+/*0x32*/15,		/* Power Management		*/
 };
 
 static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
@@ -596,7 +596,7 @@
 
 	ret = sabre_pil_table[ino];
 	if (ret == 0 && pdev == NULL) {
-		ret = 1;
+		ret = 4;
 	} else if (ret == 0) {
 		switch ((pdev->class >> 16) & 0xff) {
 		case PCI_BASE_CLASS_STORAGE:
@@ -619,7 +619,7 @@
 			break;
 
 		default:
-			ret = 1;
+			ret = 4;
 			break;
 		};
 	}
@@ -651,6 +651,10 @@
 
 	/* Now build the IRQ bucket. */
 	pil = sabre_ino_to_pil(pdev, ino);
+
+	if (PIL_RESERVED(pil))
+		BUG();
+
 	imap = p->controller_regs + imap_off;
 	imap += 4;
 
@@ -1063,7 +1067,14 @@
 	int where, size, is_64bit;
 
 	res = &pdev->resource[resource];
-	where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	if (resource < 6) {
+		where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	} else if (resource == PCI_ROM_RESOURCE) {
+		where = pdev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
 
 	is_64bit = 0;
 	if (res->flags & IORESOURCE_IO)
@@ -1079,6 +1090,10 @@
 	pci_read_config_dword(pdev, where, &reg);
 	reg = ((reg & size) |
 	       (((u32)(res->start - base)) & ~size));
+	if (resource == PCI_ROM_RESOURCE) {
+		reg |= PCI_ROM_ADDRESS_ENABLE;
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+	}
 	pci_write_config_dword(pdev, where, reg);
 
 	/* This knows that the upper 32-bits of the address
@@ -1144,7 +1159,7 @@
 
 static void __init sabre_scan_bus(struct pci_controller_info *p)
 {
-	static int once = 0;
+	static int once;
 	struct pci_bus *sabre_bus;
 	struct pci_pbm_info *pbm;
 	struct pcidev_cookie *cookie;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/pci_schizo.c linux/arch/sparc64/kernel/pci_schizo.c
--- linux.orig/arch/sparc64/kernel/pci_schizo.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/kernel/pci_schizo.c	2002-07-20 01:08:26.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: pci_schizo.c,v 1.23 2001/11/14 13:17:56 davem Exp $
+/* $Id: pci_schizo.c,v 1.23.2.2 2002/03/11 07:55:24 davem Exp $
  * pci_schizo.c: SCHIZO specific PCI controller support.
  *
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
@@ -291,8 +291,8 @@
 /*0x0c*/0, 0, 0, 0,	/* PCI slot 3  Int A, B, C, D	*/
 /*0x10*/0, 0, 0, 0,	/* PCI slot 4  Int A, B, C, D	*/
 /*0x14*/0, 0, 0, 0,	/* PCI slot 5  Int A, B, C, D	*/
-/*0x18*/3,		/* SCSI				*/
-/*0x19*/3,		/* second SCSI			*/
+/*0x18*/4,		/* SCSI				*/
+/*0x19*/4,		/* second SCSI			*/
 /*0x1a*/0,		/* UNKNOWN			*/
 /*0x1b*/0,		/* UNKNOWN			*/
 /*0x1c*/8,		/* Parallel			*/
@@ -302,7 +302,7 @@
 /*0x20*/13,		/* Audio Record			*/
 /*0x21*/14,		/* Audio Playback		*/
 /*0x22*/12,		/* Serial			*/
-/*0x23*/2,		/* EBUS I2C 			*/
+/*0x23*/4,		/* EBUS I2C 			*/
 /*0x24*/10,		/* RTC Clock			*/
 /*0x25*/11,		/* Floppy			*/
 /*0x26*/0,		/* UNKNOWN			*/
@@ -344,7 +344,7 @@
 
 	ret = schizo_pil_table[ino];
 	if (ret == 0 && pdev == NULL) {
-		ret = 1;
+		ret = 4;
 	} else if (ret == 0) {
 		switch ((pdev->class >> 16) & 0xff) {
 		case PCI_BASE_CLASS_STORAGE:
@@ -367,7 +367,7 @@
 			break;
 
 		default:
-			ret = 1;
+			ret = 4;
 			break;
 		};
 	}
@@ -383,7 +383,7 @@
 	struct ino_bucket *bucket;
 	unsigned long imap, iclr, pbm_off;
 	unsigned long imap_off, iclr_off;
-	int pil, inofixup = 0;
+	int pil;
 
 	if (pbm == &p->pbm_A)
 		pbm_off = SCHIZO_PBM_A_REGS_OFF;
@@ -395,6 +395,10 @@
 
 	/* Now build the IRQ bucket. */
 	pil = schizo_ino_to_pil(pdev, ino);
+
+	if (PIL_RESERVED(pil))
+		BUG();
+
 	imap = p->controller_regs + pbm_off + imap_off;
 	imap += 4;
 
@@ -402,10 +406,13 @@
 	iclr = p->controller_regs + pbm_off + iclr_off;
 	iclr += 4;
 
-	if (ino < 0x18)
-		inofixup = ino & 0x03;
-
-	bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
+	/* On Schizo, no inofixup occurs.  This is because each
+	 * INO has it's own IMAP register.  On Psycho and Sabre
+	 * there is only one IMAP register for each PCI slot even
+	 * though four different INOs can be generated by each
+	 * PCI slot.
+	 */
+	bucket = __bucket(build_irq(pil, 0, iclr, imap));
 	bucket->flags |= IBF_PCI;
 
 	return __irq(bucket);
@@ -1078,15 +1085,22 @@
 
 #define SCHIZO_PCIA_CTRL	(SCHIZO_PBM_A_REGS_OFF + 0x2000UL)
 #define SCHIZO_PCIB_CTRL	(SCHIZO_PBM_B_REGS_OFF + 0x2000UL)
-#define SCHIZO_PCICTRL_BUNUS	(1UL << 63UL)
+#define SCHIZO_PCICTRL_BUS_UNUS	(1UL << 63UL)
 #define SCHIZO_PCICTRL_ESLCK	(1UL << 51UL)
+#define SCHIZO_PCICTRL_ERRSLOT	(7UL << 48UL)
 #define SCHIZO_PCICTRL_TTO_ERR	(1UL << 38UL)
 #define SCHIZO_PCICTRL_RTRY_ERR	(1UL << 37UL)
 #define SCHIZO_PCICTRL_DTO_ERR	(1UL << 36UL)
 #define SCHIZO_PCICTRL_SBH_ERR	(1UL << 35UL)
 #define SCHIZO_PCICTRL_SERR	(1UL << 34UL)
+#define SCHIZO_PCICTRL_PCISPD	(1UL << 33UL)
+#define SCHIZO_PCICTRL_PTO	(3UL << 24UL)
+#define SCHIZO_PCICTRL_DTO_INT	(1UL << 19UL)
 #define SCHIZO_PCICTRL_SBH_INT	(1UL << 18UL)
 #define SCHIZO_PCICTRL_EEN	(1UL << 17UL)
+#define SCHIZO_PCICTRL_PARK	(1UL << 16UL)
+#define SCHIZO_PCICTRL_PCIRST	(1UL <<  8UL)
+#define SCHIZO_PCICTRL_ARB	(0x3fUL << 0UL)
 
 static void __init schizo_register_error_handlers(struct pci_controller_info *p)
 {
@@ -1163,7 +1177,7 @@
 	 * bits for each PBM.
 	 */
 	tmp = schizo_read(base + SCHIZO_PCIA_CTRL);
-	tmp |= (SCHIZO_PCICTRL_BUNUS |
+	tmp |= (SCHIZO_PCICTRL_BUS_UNUS |
 		SCHIZO_PCICTRL_ESLCK |
 		SCHIZO_PCICTRL_TTO_ERR |
 		SCHIZO_PCICTRL_RTRY_ERR |
@@ -1175,7 +1189,7 @@
 	schizo_write(base + SCHIZO_PCIA_CTRL, tmp);
 
 	tmp = schizo_read(base + SCHIZO_PCIB_CTRL);
-	tmp |= (SCHIZO_PCICTRL_BUNUS |
+	tmp |= (SCHIZO_PCICTRL_BUS_UNUS |
 		SCHIZO_PCICTRL_ESLCK |
 		SCHIZO_PCICTRL_TTO_ERR |
 		SCHIZO_PCICTRL_RTRY_ERR |
@@ -1412,7 +1426,14 @@
 	int where, size, is_64bit;
 
 	res = &pdev->resource[resource];
-	where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	if (resource < 6) {
+		where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	} else if (resource == PCI_ROM_RESOURCE) {
+		where = pdev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
 
 	is_64bit = 0;
 	if (res->flags & IORESOURCE_IO)
@@ -1428,6 +1449,10 @@
 	pci_read_config_dword(pdev, where, &reg);
 	reg = ((reg & size) |
 	       (((u32)(res->start - root->start)) & ~size));
+	if (resource == PCI_ROM_RESOURCE) {
+		reg |= PCI_ROM_ADDRESS_ENABLE;
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+	}
 	pci_write_config_dword(pdev, where, reg);
 
 	/* This knows that the upper 32-bits of the address
@@ -1458,24 +1483,12 @@
 #define SCHIZO_PCI_B_IO_MATCH		0x00070UL
 #define SCHIZO_PCI_B_IO_MASK		0x00078UL
 
-/* VAL must be non-zero. */
-static unsigned long strip_to_lowest_bit_set(unsigned long val)
-{
-	unsigned long tmp;
-
-	tmp = 1UL;
-	while (!(tmp & val))
-		tmp <<= 1UL;
-
-	return tmp;
-}
-
 static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm,
 					  int is_pbm_a, unsigned long reg_base)
 {
 	u64 mem_match, mem_mask;
 	u64 io_match;
-	u64 long a, b;
+	u64 a;
 
 	if (is_pbm_a) {
 		mem_match = reg_base + SCHIZO_PCI_A_MEM_MATCH;
@@ -1487,11 +1500,12 @@
 	mem_mask = mem_match + 0x8UL;
 
 	a = schizo_read(mem_match) & ~0x8000000000000000UL;
-	b = strip_to_lowest_bit_set(schizo_read(mem_mask));
 
-	/* It should be 2GB in size. */
+	/* It should be 2GB in size but the decode is set for the full
+	 * 4GB so we have to add the 2G by hand.
+	 */
 	pbm->mem_space.start = a;
-	pbm->mem_space.end = a + (b - 1UL);
+	pbm->mem_space.end = a + 0x80000000;
 	pbm->mem_space.flags = IORESOURCE_MEM;
 
 	/* This 32MB area is divided into two pieces.  The first
@@ -1738,6 +1752,22 @@
 	schizo_pbm_strbuf_init(p, pbm, is_pbm_a);
 }
 
+#define SCHIZO_PCIA_IRQ_RETRY	(SCHIZO_PBM_A_REGS_OFF + 0x1a00UL)
+#define SCHIZO_PCIB_IRQ_RETRY	(SCHIZO_PBM_B_REGS_OFF + 0x1a00UL)
+#define  SCHIZO_IRQ_RETRY_INF	 0xffUL
+
+#define SCHIZO_PCIA_DIAG	(SCHIZO_PBM_A_REGS_OFF + 0x2020UL)
+#define SCHIZO_PCIB_DIAG	(SCHIZO_PBM_B_REGS_OFF + 0x2020UL)
+#define  SCHIZO_PCIDIAG_D_BADECC	(1UL << 10UL) /* Disable BAD ECC errors */
+#define  SCHIZO_PCIDIAG_D_BYPASS	(1UL <<  9UL) /* Disable MMU bypass mode */
+#define  SCHIZO_PCIDIAG_D_TTO		(1UL <<  8UL) /* Disable TTO errors */
+#define  SCHIZO_PCIDIAG_D_RTRYARB	(1UL <<  7UL) /* Disable retry arbitration */
+#define  SCHIZO_PCIDIAG_D_RETRY		(1UL <<  6UL) /* Disable retry limit */
+#define  SCHIZO_PCIDIAG_D_INTSYNC	(1UL <<  5UL) /* Disable interrupt/DMA synch */
+#define  SCHIZO_PCIDIAG_I_DMA_PARITY	(1UL <<  3UL) /* Invert DMA parity */
+#define  SCHIZO_PCIDIAG_I_PIOD_PARITY	(1UL <<  2UL) /* Invert PIO data parity */
+#define  SCHIZO_PCIDIAG_I_PIOA_PARITY	(1UL <<  1U)L /* Invert PIO address parity */
+
 static void schizo_controller_hwinit(struct pci_controller_info *p)
 {
 	unsigned long pbm_a_base, pbm_b_base;
@@ -1747,17 +1777,37 @@
 	pbm_b_base = p->controller_regs + SCHIZO_PBM_B_REGS_OFF;
 
 	/* Set IRQ retry to infinity. */
-	schizo_write(pbm_a_base + 0x1a00UL, 0xff);
-	schizo_write(pbm_b_base + 0x1a00UL, 0xff);
-
-	/* Enable arbiter for all PCI slots. */
-	tmp = schizo_read(pbm_a_base + 0x2000UL);
-	tmp |= 0x3fUL;
-	schizo_write(pbm_a_base + 0x2000UL, tmp);
-
-	tmp = schizo_read(pbm_b_base + 0x2000UL);
-	tmp |= 0x3fUL;
-	schizo_write(pbm_b_base + 0x2000UL, tmp);
+	schizo_write(p->controller_regs + SCHIZO_PCIA_IRQ_RETRY,
+		     SCHIZO_IRQ_RETRY_INF);
+	schizo_write(p->controller_regs + SCHIZO_PCIB_IRQ_RETRY,
+		     SCHIZO_IRQ_RETRY_INF);
+
+	/* Enable arbiter for all PCI slots.  Also, disable PCI interval
+	 * timer so that DTO (Discard TimeOuts) are not reported because
+	 * some Schizo revisions report them erroneously.
+	 */
+
+	tmp = schizo_read(p->controller_regs + SCHIZO_PCIA_CTRL);
+	tmp |= SCHIZO_PCICTRL_ARB;
+	tmp &= ~SCHIZO_PCICTRL_PTO;
+	schizo_write(p->controller_regs + SCHIZO_PCIA_CTRL, tmp);
+
+	tmp = schizo_read(p->controller_regs + SCHIZO_PCIB_CTRL);
+	tmp |= SCHIZO_PCICTRL_ARB;
+	tmp &= ~SCHIZO_PCICTRL_PTO;
+	schizo_write(p->controller_regs + SCHIZO_PCIB_CTRL, tmp);
+
+	/* Disable TTO error reporting (won't happen anyway since we
+	 * disabled the PCI interval timer above) and retry arbitration
+	 * (can cause hangs in some Schizo revisions).
+	 */
+	tmp = schizo_read(p->controller_regs + SCHIZO_PCIA_DIAG);
+	tmp |= (SCHIZO_PCIDIAG_D_TTO | SCHIZO_PCIDIAG_D_RTRYARB);
+	schizo_write(p->controller_regs + SCHIZO_PCIA_DIAG, tmp);
+
+	tmp = schizo_read(p->controller_regs + SCHIZO_PCIB_DIAG);
+	tmp |= (SCHIZO_PCIDIAG_D_TTO | SCHIZO_PCIDIAG_D_RTRYARB);
+	schizo_write(p->controller_regs + SCHIZO_PCIB_DIAG, tmp);
 }
 
 void __init schizo_init(int node, char *model_name)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/power.c linux/arch/sparc64/kernel/power.c
--- linux.orig/arch/sparc64/kernel/power.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/power.c	2002-07-20 01:08:32.000000000 +0000
@@ -22,7 +22,7 @@
 #define POWER_COURTESY_OFF (1 << 1)
 
 static DECLARE_WAIT_QUEUE_HEAD(powerd_wait);
-static int button_pressed = 0;
+static int button_pressed;
 
 static void power_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -81,7 +81,7 @@
 {
 	struct linux_ebus *ebus;
 	struct linux_ebus_device *edev;
-	static int invoked = 0;
+	static int invoked;
 
 	if (invoked)
 		return;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
--- linux.orig/arch/sparc64/kernel/process.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/process.c	2002-07-20 01:08:34.000000000 +0000
@@ -421,11 +421,15 @@
 {
 	struct thread_struct *t = &current->thread;
 
+	if (t->flags & SPARC_FLAG_ABI_PENDING)
+		t->flags ^= (SPARC_FLAG_ABI_PENDING |
+			     SPARC_FLAG_32BIT);
 	if (current->mm) {
+		unsigned long pgd_cache = 0UL;
+
 		if (t->flags & SPARC_FLAG_32BIT) {
 			struct mm_struct *mm = current->mm;
 			pgd_t *pgd0 = &mm->pgd[0];
-			unsigned long pgd_cache;
 
 			if (pgd_none(*pgd0)) {
 				pmd_t *page = pmd_alloc_one_fast(NULL, 0);
@@ -434,13 +438,13 @@
 				pgd_set(pgd0, page);
 			}
 			pgd_cache = pgd_val(*pgd0) << 11UL;
-			__asm__ __volatile__("stxa %0, [%1] %2\n\t"
-					     "membar #Sync"
-					     : /* no outputs */
-					     : "r" (pgd_cache),
-					       "r" (TSB_REG),
-					       "i" (ASI_DMMU));
 		}
+		__asm__ __volatile__("stxa %0, [%1] %2\n\t"
+				     "membar #Sync"
+				     : /* no outputs */
+				     : "r" (pgd_cache),
+				     "r" (TSB_REG),
+				     "i" (ASI_DMMU));
 	}
 	t->w_saved = 0;
 
@@ -577,13 +581,6 @@
  * under SunOS are nothing short of bletcherous:
  * Parent -->  %o0 == childs  pid, %o1 == 0
  * Child  -->  %o0 == parents pid, %o1 == 1
- *
- * NOTE: We have a separate fork kpsr/kwim because
- *       the parent could change these values between
- *       sys_fork invocation and when we reach here
- *       if the parent should sleep while trying to
- *       allocate the task_struct and kernel stack in
- *       do_fork().
  */
 int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 		unsigned long unused,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
--- linux.orig/arch/sparc64/kernel/ptrace.c	2001-10-01 16:19:56.000000000 +0000
+++ linux/arch/sparc64/kernel/ptrace.c	2002-07-20 01:08:35.000000000 +0000
@@ -80,29 +80,13 @@
 
 #ifdef DEBUG_PTRACE
 char *pt_rq [] = {
-"TRACEME",
-"PEEKTEXT",
-"PEEKDATA",
-"PEEKUSR",
-"POKETEXT",
-"POKEDATA",
-"POKEUSR",
-"CONT",
-"KILL",
-"SINGLESTEP",
-"SUNATTACH",
-"SUNDETACH",
-"GETREGS",
-"SETREGS",
-"GETFPREGS",
-"SETFPREGS",
-"READDATA",
-"WRITEDATA",
-"READTEXT",
-"WRITETEXT",
-"GETFPAREGS",
-"SETFPAREGS",
-""
+	/* 0  */ "TRACEME", "PEEKTEXT", "PEEKDATA", "PEEKUSR",
+	/* 4  */ "POKETEXT", "POKEDATA", "POKEUSR", "CONT",
+	/* 8  */ "KILL", "SINGLESTEP", "SUNATTACH", "SUNDETACH",
+	/* 12 */ "GETREGS", "SETREGS", "GETFPREGS", "SETFPREGS",
+	/* 16 */ "READDATA", "WRITEDATA", "READTEXT", "WRITETEXT",
+	/* 20 */ "GETFPAREGS", "SETFPAREGS", "unknown", "unknown",
+	/* 24 */ "SYSCALL", ""
 };
 #endif
 
@@ -135,7 +119,7 @@
 	{
 		char *s;
 
-		if ((request > 0) && (request < 21))
+		if ((request >= 0) && (request <= 24))
 			s = pt_rq [request];
 		else
 			s = "unknown";
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/rtrap.S linux/arch/sparc64/kernel/rtrap.S
--- linux.orig/arch/sparc64/kernel/rtrap.S	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/rtrap.S	2002-07-20 01:08:36.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.57.2.1 2001/12/24 04:32:33 davem Exp $
+/* $Id: rtrap.S,v 1.57.2.2 2002/03/03 10:31:56 davem Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -13,7 +13,6 @@
 #include <asm/visasm.h>
 #include <asm/processor.h>
 
-#define		PTREGS_OFF		(STACK_BIAS + REGWIN_SZ)
 #define		RTRAP_PSTATE		(PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
 #define		RTRAP_PSTATE_IRQOFF	(PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV)
 #define		RTRAP_PSTATE_AG_IRQOFF	(PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
@@ -139,7 +138,7 @@
 		 andn			%l1, %l4, %l1
 
 		.align			64
-		.globl			rtrap_clr_l6, rtrap, irqsz_patchme
+		.globl			rtrap_clr_l6, rtrap, irqsz_patchme, rtrap_xcall
 rtrap_clr_l6:	clr			%l6
 rtrap:		lduw			[%g6 + AOFF_task_processor], %l0
 		sethi			%hi(irq_stat), %l2	! &softirq_active
@@ -148,9 +147,12 @@
 		lduw			[%l2 + %l0], %l1	! softirq_pending
 		cmp			%l1, 0
 
+		/* mm/ultra.S:xcall_report_regs KNOWS about this load. */
 		bne,pn			%icc, __handle_softirq
 		 ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
+
 __handle_softirq_continue:
+rtrap_xcall:
 		sethi			%hi(0xf << 20), %l4
 		andcc			%l1, TSTATE_PRIV, %l3
 		and			%l1, %l4, %l4
@@ -296,5 +298,3 @@
 		wr			%g0, FPRS_DU, %fprs
 		ba,pt			%xcc, rt_continue
 		 stb			%l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth]
-
-#undef PTREGS_OFF
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/sbus.c linux/arch/sparc64/kernel/sbus.c
--- linux.orig/arch/sparc64/kernel/sbus.c	2001-10-12 22:35:53.000000000 +0000
+++ linux/arch/sparc64/kernel/sbus.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.17 2001/10/09 02:24:33 davem Exp $
+/* $Id: sbus.c,v 1.17.2.1 2002/03/03 10:31:56 davem Exp $
  * sbus.c: UltraSparc SBUS controller support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -632,11 +632,11 @@
 
 /* SBUS SYSIO INO number to Sparc PIL level. */
 static unsigned char sysio_ino_to_pil[] = {
-	0, 1, 2, 7, 5, 7, 8, 9,		/* SBUS slot 0 */
-	0, 1, 2, 7, 5, 7, 8, 9,		/* SBUS slot 1 */
-	0, 1, 2, 7, 5, 7, 8, 9,		/* SBUS slot 2 */
-	0, 1, 2, 7, 5, 7, 8, 9,		/* SBUS slot 3 */
-	3, /* Onboard SCSI */
+	0, 4, 4, 7, 5, 7, 8, 9,		/* SBUS slot 0 */
+	0, 4, 4, 7, 5, 7, 8, 9,		/* SBUS slot 1 */
+	0, 4, 4, 7, 5, 7, 8, 9,		/* SBUS slot 2 */
+	0, 4, 4, 7, 5, 7, 8, 9,		/* SBUS slot 3 */
+	4, /* Onboard SCSI */
 	5, /* Onboard Ethernet */
 /*XXX*/	8, /* Onboard BPP */
 	0, /* Bogon */
@@ -758,6 +758,10 @@
 		printk("sbus_irq_build: Bad SYSIO INO[%x]\n", ino);
 		panic("Bad SYSIO IRQ translations...");
 	}
+
+	if (PIL_RESERVED(pil))
+		BUG();
+
 	imap = sysio_irq_offsets[ino];
 	if (imap == ((unsigned long)-1)) {
 		prom_printf("get_irq_translations: Bad SYSIO INO[%x] cpu[%d]\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- linux.orig/arch/sparc64/kernel/setup.c	2001-11-13 17:16:05.000000000 +0000
+++ linux/arch/sparc64/kernel/setup.c	2002-07-20 01:08:32.000000000 +0000
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.71 2001/11/13 00:49:28 davem Exp $
+/*  $Id: setup.c,v 1.71.2.1 2002/02/27 21:31:38 davem Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
@@ -530,7 +530,7 @@
 	if (!root_flags)
 		root_mountflags &= ~MS_RDONLY;
 	ROOT_DEV = to_kdev_t(root_dev);
-#ifdef CONFIG_BLK_DEV_RAM
+#ifdef CONFIG_BLK_DEV_INITRD
 	rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
 	rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
 	rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/signal.c linux/arch/sparc64/kernel/signal.c
--- linux.orig/arch/sparc64/kernel/signal.c	2001-03-26 02:14:21.000000000 +0000
+++ linux/arch/sparc64/kernel/signal.c	2002-07-20 01:08:22.000000000 +0000
@@ -411,6 +411,7 @@
 	struct rt_signal_frame *sf;
 	unsigned long tpc, tnpc, tstate;
 	__siginfo_fpu_t *fpu_save;
+	mm_segment_t old_fs;
 	sigset_t set;
 	stack_t st;
 	int err;
@@ -455,7 +456,10 @@
 	
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
 	do_sigaltstack(&st, NULL, (unsigned long)sf);
+	set_fs(old_fs);
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sigmask_lock);
@@ -574,6 +578,12 @@
 	regs->u_regs[UREG_I0] = signo;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 
+	/* The sigcontext is passed in this way because of how it
+	 * is defined in GLIBC's /usr/include/bits/sigcontext.h
+	 * for sparc64.  It includes the 128 bytes of siginfo_t.
+	 */
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
+
 	/* 5. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
 	regs->tnpc = (regs->tpc + 4);
@@ -709,9 +719,23 @@
 		signr = dequeue_signal(&current->blocked, &info);
 		spin_unlock_irq(&current->sigmask_lock);
 		
-		if (!signr) break;
+		if (!signr)
+			break;
 
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Do the syscall restart before we let the debugger
+			 * look at the child registers.
+			 */
+			if (restart_syscall &&
+			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+				regs->u_regs[UREG_I0] = orig_i0;
+				regs->tpc -= 4;
+				regs->tnpc -= 4;
+				restart_syscall = 0;
+			}
+
 			current->exit_code = signr;
 			current->state = TASK_STOPPED;
 			notify_parent(current, SIGCHLD);
@@ -740,8 +764,8 @@
 		
 		ka = &current->sig->action[signr-1];
 		
-		if(ka->sa.sa_handler == SIG_IGN) {
-			if(signr != SIGCHLD)
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
 				continue;
 
                         /* sys_wait4() grabs the master kernel lock, so
@@ -749,16 +773,16 @@
                          * threaded and would not be that difficult to
                          * do anyways.
                          */
-                        while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
                                 ;
 			continue;
 		}
-		if(ka->sa.sa_handler == SIG_DFL) {
+		if (ka->sa.sa_handler == SIG_DFL) {
 			unsigned long exit_code = signr;
 			
-			if(current->pid == 1)
+			if (current->pid == 1)
 				continue;
-			switch(signr) {
+			switch (signr) {
 			case SIGCONT: case SIGCHLD: case SIGWINCH:
 				continue;
 
@@ -771,8 +795,8 @@
 					continue;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
-				     SA_NOCLDSTOP))
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+				      SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
@@ -791,8 +815,8 @@
 					struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
 					unsigned long ins[8];
                                                 
-					while(rw &&
-					      !(((unsigned long) rw) & 0x3)) {
+					while (rw &&
+					       !(((unsigned long) rw) & 0x3)) {
 					        copy_from_user(ins, &rw->ins[0], sizeof(ins));
 						printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
 						rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS);
@@ -806,22 +830,19 @@
 #endif
 				/* fall through */
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOT REACHED */
 			}
 		}
-		if(restart_syscall)
+		if (restart_syscall)
 			syscall_restart(orig_i0, regs, &ka->sa);
 		handle_signal(signr, ka, &info, oldset, regs);
 		return 1;
 	}
-	if(restart_syscall &&
-	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+	if (restart_syscall &&
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c
--- linux.orig/arch/sparc64/kernel/signal32.c	2001-04-27 05:17:25.000000000 +0000
+++ linux/arch/sparc64/kernel/signal32.c	2002-07-20 01:08:21.000000000 +0000
@@ -394,6 +394,7 @@
 	struct rt_signal_frame32 *sf;
 	unsigned int psr;
 	unsigned pc, npc, fpu_save;
+	mm_segment_t old_fs;
 	sigset_t set;
 	sigset_t32 seta;
 	stack_t st;
@@ -451,7 +452,10 @@
 		
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
 	do_sigaltstack(&st, NULL, (unsigned long)sf);
+	set_fs(old_fs);
 	
 	switch (_NSIG_WORDS) {
 		case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
@@ -757,6 +761,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
 	regs->u_regs[UREG_I0] = signo;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
 
 	/* 4. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
@@ -1024,6 +1029,7 @@
 {
 	struct thread_struct *tp = &current->thread;
 	svr4_gregset_t  *gr;
+	mm_segment_t old_fs;
 	u32 pc, npc, psr;
 	sigset_t set;
 	svr4_sigset_t setv;
@@ -1077,7 +1083,10 @@
 		
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
 	do_sigaltstack(&st, NULL, regs->u_regs[UREG_I6]);
+	set_fs(old_fs);
 	
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sigmask_lock);
@@ -1203,6 +1212,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
 	regs->u_regs[UREG_I0] = signr;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
 
 	/* 4. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
@@ -1370,9 +1380,23 @@
 		signr = dequeue_signal(&current->blocked, &info);
 		spin_unlock_irq(&current->sigmask_lock);
 		
-		if (!signr) break;
+		if (!signr)
+			break;
 
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Do the syscall restart before we let the debugger
+			 * look at the child registers.
+			 */
+			if (restart_syscall &&
+			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+				regs->u_regs[UREG_I0] = orig_i0;
+				regs->tpc -= 4;
+				regs->tnpc -= 4;
+				restart_syscall = 0;
+			}
+
 			current->exit_code = signr;
 			current->state = TASK_STOPPED;
 			notify_parent(current, SIGCHLD);
@@ -1401,8 +1425,8 @@
 		
 		ka = &current->sig->action[signr-1];
 		
-		if(ka->sa.sa_handler == SIG_IGN) {
-			if(signr != SIGCHLD)
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
 				continue;
 
 			/* sys_wait4() grabs the master kernel lock, so
@@ -1410,16 +1434,16 @@
 			 * threaded and would not be that difficult to
 			 * do anyways.
 			 */
-			while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
 				;
 			continue;
 		}
-		if(ka->sa.sa_handler == SIG_DFL) {
+		if (ka->sa.sa_handler == SIG_DFL) {
 			unsigned long exit_code = signr;
 			
-			if(current->pid == 1)
+			if (current->pid == 1)
 				continue;
-			switch(signr) {
+			switch (signr) {
 			case SIGCONT: case SIGCHLD: case SIGWINCH:
 				continue;
 
@@ -1432,8 +1456,8 @@
 					continue;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
-				     SA_NOCLDSTOP))
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+				      SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
@@ -1463,8 +1487,8 @@
 					struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff);
 					unsigned int ins[8];
 
-					while(rw &&
-					      !(((unsigned long) rw) & 0x3)) {
+					while (rw &&
+					       !(((unsigned long) rw) & 0x3)) {
 						copy_from_user(ins, &rw->ins[0], sizeof(ins));
 						printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
 						rw = (struct reg_window32 *)(unsigned long)ins[6];
@@ -1478,22 +1502,19 @@
 #endif
 				/* fall through */
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOT REACHED */
 			}
 		}
-		if(restart_syscall)
+		if (restart_syscall)
 			syscall_restart32(orig_i0, regs, &ka->sa);
 		handle_signal32(signr, ka, &info, oldset, regs, svr4_signal);
 		return 1;
 	}
-	if(restart_syscall &&
-	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+	if (restart_syscall &&
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/smp.c linux/arch/sparc64/kernel/smp.c
--- linux.orig/arch/sparc64/kernel/smp.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/smp.c	2002-07-20 01:08:21.000000000 +0000
@@ -46,8 +46,8 @@
 volatile int __cpu_logical_map[NR_CPUS] __attribute__ ((aligned (SMP_CACHE_BYTES)));
 
 /* Please don't make this stuff initdata!!!  --DaveM */
-static unsigned char boot_cpu_id = 0;
-static int smp_activated = 0;
+static unsigned char boot_cpu_id;
+static int smp_activated;
 
 /* Kernel spinlock */
 spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
@@ -167,28 +167,28 @@
 	 * purposes.  Also workaround BB_ERRATA_1 by doing a dummy
 	 * read back of %tick after writing it.
 	 */
-	__asm__ __volatile__("
-	sethi	%%hi(0x80000000), %%g1
-	ba,pt	%%xcc, 1f
-	 sllx	%%g1, 32, %%g1
-	.align	64
-1:	rd	%%tick, %%g2
-	add	%%g2, 6, %%g2
-	andn	%%g2, %%g1, %%g2
-	wrpr	%%g2, 0, %%tick
-	rdpr	%%tick, %%g0"
+	__asm__ __volatile__(
+		"sethi	%%hi(0x80000000), %%g1\n\t"
+		"ba,pt	%%xcc, 1f\n\t"
+		"sllx	%%g1, 32, %%g1\n\t"
+		".align	64\n"
+	"1:	rd	%%tick, %%g2\n\t"
+		"add	%%g2, 6, %%g2\n\t"
+		"andn	%%g2, %%g1, %%g2\n\t"
+		"wrpr	%%g2, 0, %%tick\n\t"
+		"rdpr	%%tick, %%g0"
 	: /* no outputs */
 	: /* no inputs */
 	: "g1", "g2");
 
 	if (SPARC64_USE_STICK) {
 		/* Let the user get at STICK too. */
-		__asm__ __volatile__("
-			sethi	%%hi(0x80000000), %%g1
-			sllx	%%g1, 32, %%g1
-			rd	%%asr24, %%g2
-			andn	%%g2, %%g1, %%g2
-			wr	%%g2, 0, %%asr24"
+		__asm__ __volatile__(
+			"sethi	%%hi(0x80000000), %%g1\n\t"
+			"sllx	%%g1, 32, %%g1\n\t"
+			"rd	%%asr24, %%g2\n\t"
+			"andn	%%g2, %%g1, %%g2\n\t"
+			"wr	%%g2, 0, %%asr24"
 		: /* no outputs */
 		: /* no inputs */
 		: "g1", "g2");
@@ -364,18 +364,18 @@
 	 * ADDR 0x20) for the dummy read. -DaveM
 	 */
 	tmp = 0x40;
-	__asm__ __volatile__("
-	wrpr	%1, %2, %%pstate
-	stxa	%4, [%0] %3
-	stxa	%5, [%0+%8] %3
-	add	%0, %8, %0
-	stxa	%6, [%0+%8] %3
-	membar	#Sync
-	stxa	%%g0, [%7] %3
-	membar	#Sync
-	mov	0x20, %%g1
-	ldxa	[%%g1] 0x7f, %%g0
-	membar	#Sync"
+	__asm__ __volatile__(
+	"wrpr	%1, %2, %%pstate\n\t"
+	"stxa	%4, [%0] %3\n\t"
+	"stxa	%5, [%0+%8] %3\n\t"
+	"add	%0, %8, %0\n\t"
+	"stxa	%6, [%0+%8] %3\n\t"
+	"membar	#Sync\n\t"
+	"stxa	%%g0, [%7] %3\n\t"
+	"membar	#Sync\n\t"
+	"mov	0x20, %%g1\n\t"
+	"ldxa	[%%g1] 0x7f, %%g0\n\t"
+	"membar	#Sync"
 	: "=r" (tmp)
 	: "r" (pstate), "i" (PSTATE_IE), "i" (ASI_INTR_W),
 	  "r" (data0), "r" (data1), "r" (data2), "r" (target), "r" (0x10), "0" (tmp)
@@ -602,11 +602,12 @@
 	return 0;
 }
 
-void smp_call_function_client(void)
+void smp_call_function_client(int irq, struct pt_regs *regs)
 {
 	void (*func) (void *info) = call_data->func;
 	void *info = call_data->info;
 
+	clear_softint(1 << irq);
 	if (call_data->wait) {
 		/* let initiator proceed only after completion */
 		func(info);
@@ -730,6 +731,12 @@
 	}
 }
 
+void smp_receive_signal_client(int irq, struct pt_regs *regs)
+{
+	/* Just return, rtrap takes care of the rest. */
+	clear_softint(1 << irq);
+}
+
 void smp_report_regs(void)
 {
 	smp_cross_call(&xcall_report_regs, 0, 0, 0);
@@ -897,7 +904,7 @@
 
 static atomic_t smp_capture_depth = ATOMIC_INIT(0);
 static atomic_t smp_capture_registry = ATOMIC_INIT(0);
-static unsigned long penguins_are_doing_time = 0;
+static unsigned long penguins_are_doing_time;
 
 void smp_capture(void)
 {
@@ -946,10 +953,12 @@
 extern void prom_world(int);
 extern void save_alternate_globals(unsigned long *);
 extern void restore_alternate_globals(unsigned long *);
-void smp_penguin_jailcell(void)
+void smp_penguin_jailcell(int irq, struct pt_regs *regs)
 {
 	unsigned long global_save[24];
 
+	clear_softint(1 << irq);
+
 	__asm__ __volatile__("flushw");
 	save_alternate_globals(global_save);
 	prom_world(1);
@@ -1097,21 +1106,21 @@
 	 * read back from %tick_cmpr right after writing to it. -DaveM
 	 */
 	if (!SPARC64_USE_STICK) {
-	__asm__ __volatile__("
-		rd	%%tick, %%g1
-		ba,pt	%%xcc, 1f
-		 add	%%g1, %0, %%g1
-		.align	64
-	1:	wr	%%g1, 0x0, %%tick_cmpr
-		rd	%%tick_cmpr, %%g0"
+	__asm__ __volatile__(
+		"rd	%%tick, %%g1\n\t"
+		"ba,pt	%%xcc, 1f\n\t"
+		" add	%%g1, %0, %%g1\n\t"
+		".align	64\n"
+	"1:	wr	%%g1, 0x0, %%tick_cmpr\n\t"
+		"rd	%%tick_cmpr, %%g0"
 	: /* no outputs */
 	: "r" (current_tick_offset)
 	: "g1");
 	} else {
-	__asm__ __volatile__("
-		rd	%%asr24, %%g1
-		add	%%g1, %0, %%g1
-		wr	%%g1, 0x0, %%asr25"
+	__asm__ __volatile__(
+		"rd	%%asr24, %%g1\n\t"
+		"add	%%g1, %0, %%g1\n\t"
+		"wr	%%g1, 0x0, %%asr25"
 	: /* no outputs */
 	: "r" (current_tick_offset)
 	: "g1");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- linux.orig/arch/sparc64/kernel/sparc64_ksyms.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.119 2001/11/30 01:04:10 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.119.2.2 2002/03/14 01:26:21 kanoj Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -134,6 +134,11 @@
 EXPORT_SYMBOL(__global_save_flags);
 EXPORT_SYMBOL(__global_restore_flags);
 
+#if defined(CONFIG_MCOUNT)
+extern void mcount(void);
+EXPORT_SYMBOL(mcount);
+#endif
+
 /* Per-CPU information table */
 EXPORT_SYMBOL(cpu_data);
 
@@ -355,6 +360,10 @@
 /* RAID code needs this */
 EXPORT_SYMBOL_NOVERS(VISenter);
 
+extern void batten_down_hatches(void);
+/* for input/keybdev */
+EXPORT_SYMBOL(batten_down_hatches);
+
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 EXPORT_SYMBOL(do_BUG);
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/sys_sparc.c linux/arch/sparc64/kernel/sys_sparc.c
--- linux.orig/arch/sparc64/kernel/sys_sparc.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/sys_sparc.c	2002-07-20 01:08:22.000000000 +0000
@@ -380,7 +380,7 @@
 asmlinkage unsigned long
 c_sys_nis_syscall (struct pt_regs *regs)
 {
-	static int count=0;
+	static int count;
 	
 	/* Don't make the system unusable, if someone goes stuck */
 	if (count++ > 5)
@@ -450,7 +450,7 @@
 
 asmlinkage int solaris_syscall(struct pt_regs *regs)
 {
-	static int count = 0;
+	static int count;
 
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
@@ -470,7 +470,7 @@
 #ifndef CONFIG_SUNOS_EMUL
 asmlinkage int sunos_syscall(struct pt_regs *regs)
 {
-	static int count = 0;
+	static int count;
 
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- linux.orig/arch/sparc64/kernel/sys_sparc32.c	2001-10-21 17:36:54.000000000 +0000
+++ linux/arch/sparc64/kernel/sys_sparc32.c	2002-07-20 01:08:38.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.182 2001/10/18 09:06:36 davem Exp $
+/* $Id: sys_sparc32.c,v 1.182.2.1 2002/02/20 08:49:24 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -49,6 +49,7 @@
 #include <linux/in.h>
 #include <linux/icmpv6.h>
 #include <linux/sysctl.h>
+#include <linux/dnotify.h>
 
 #include <asm/types.h>
 #include <asm/ipc.h>
@@ -1066,16 +1067,20 @@
 	/* First get the "struct iovec" from user memory and
 	 * verify all the pointers
 	 */
+	retval = 0;
 	if (!count)
-		return 0;
+		goto out_nofree;
+	retval = -EFAULT;
 	if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
-		return -EFAULT;
+		goto out_nofree;
+	retval = -EINVAL;
 	if (count > UIO_MAXIOV)
-		return -EINVAL;
+		goto out_nofree;
 	if (count > UIO_FASTIOV) {
+		retval = -ENOMEM;
 		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
 		if (!iov)
-			return -ENOMEM;
+			goto out_nofree;
 	}
 
 	tot_len = 0;
@@ -1135,6 +1140,11 @@
 out:
 	if (iov != iovstack)
 		kfree(iov);
+out_nofree:
+	/* VERIFY_WRITE actually means a read, as we write to user space */
+	if ((retval + (type == VERIFY_WRITE)) > 0)
+		dnotify_parent(file->f_dentry,
+			(type == VERIFY_WRITE) ? DN_MODIFY : DN_ACCESS);
 
 	return retval;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c
--- linux.orig/arch/sparc64/kernel/sys_sunos32.c	2001-08-15 02:57:28.000000000 +0000
+++ linux/arch/sparc64/kernel/sys_sunos32.c	2002-07-20 01:08:24.000000000 +0000
@@ -210,7 +210,7 @@
 
 asmlinkage void sunos_vadvise(u32 strategy)
 {
-	static int count = 0;
+	static int count;
 
 	/* I wanna see who uses this... */
 	if (count++ < 5)
@@ -1199,8 +1199,8 @@
 	return ret;
 }
 
-extern asmlinkage int sys_read(unsigned int fd, char *buf, unsigned long count);
-extern asmlinkage int sys_write(unsigned int fd, char *buf, unsigned long count);
+extern asmlinkage ssize_t sys_read(unsigned int fd, char *buf, unsigned long count);
+extern asmlinkage ssize_t sys_write(unsigned int fd, char *buf, unsigned long count);
 extern asmlinkage int sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
 extern asmlinkage int sys_send(int fd, void *buff, size_t len, unsigned flags);
 extern asmlinkage int sys_accept(int fd, struct sockaddr *sa, int *addrlen);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S
--- linux.orig/arch/sparc64/kernel/systbls.S	2001-10-21 17:36:54.000000000 +0000
+++ linux/arch/sparc64/kernel/systbls.S	2002-07-20 01:08:34.000000000 +0000
@@ -56,7 +56,7 @@
 /*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
 	.word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*180*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module
-	.word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sparc64_newuname
+	.word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
 /*190*/	.word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 	.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
 /*200*/	.word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
@@ -115,7 +115,7 @@
 /*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
 	.word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*180*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module
-	.word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sparc64_newuname
+	.word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
 /*190*/	.word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 	.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
 /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/time.c linux/arch/sparc64/kernel/time.c
--- linux.orig/arch/sparc64/kernel/time.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/kernel/time.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.41.2.1 2002/01/23 14:35:45 davem Exp $
+/* $Id: time.c,v 1.41.2.2 2002/03/03 04:08:10 davem Exp $
  * time.c: UltraSparc timer and TOD clock support.
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -62,7 +62,7 @@
 static __inline__ void timer_check_rtc(void)
 {
 	/* last time the cmos clock got updated */
-	static long last_rtc_update=0;
+	static long last_rtc_update;
 
 	/* Determine when to update the Mostek clock. */
 	if ((time_status & STA_UNSYNC) == 0 &&
@@ -405,11 +405,12 @@
 	char model[128];
 	int node, busnd = -1, err;
 	unsigned long flags;
+	struct linux_central *cbus;
 #ifdef CONFIG_PCI
 	struct linux_ebus *ebus = NULL;
 	struct isa_bridge *isa_br = NULL;
 #endif
-	static int invoked = 0;
+	static int invoked;
 
 	if (invoked)
 		return;
@@ -431,21 +432,30 @@
 
 	__save_and_cli(flags);
 
-	if(central_bus != NULL) {
+	cbus = central_bus;
+	if (cbus != NULL)
 		busnd = central_bus->child->prom_node;
-	}
+
+	/* Check FHC Central then EBUSs then ISA bridges then SBUSs.
+	 * That way we handle the presence of multiple properly.
+	 *
+	 * As a special case, machines with Central must provide the
+	 * timer chip there.
+	 */
 #ifdef CONFIG_PCI
-	else if (ebus_chain != NULL) {
+	if (ebus_chain != NULL) {
 		ebus = ebus_chain;
-		busnd = ebus->prom_node;
-	} else if (isa_chain != NULL) {
+		if (busnd == -1)
+			busnd = ebus->prom_node;
+	}
+	if (isa_chain != NULL) {
 		isa_br = isa_chain;
-		busnd = isa_br->prom_node;
+		if (busnd == -1)
+			busnd = isa_br->prom_node;
 	}
 #endif
-	else if (sbus_root != NULL) {
+	if (sbus_root != NULL && busnd == -1)
 		busnd = sbus_root->prom_node;
-	}
 
 	if (busnd == -1) {
 		prom_printf("clock_probe: problem, cannot find bus to search.\n");
@@ -464,7 +474,12 @@
 		    strcmp(model, "mk48t59") &&
 		    strcmp(model, "m5819") &&
 		    strcmp(model, "ds1287")) {
-		   	if (node)
+			if (cbus != NULL) {
+				prom_printf("clock_probe: Central bus lacks timer chip.\n");
+				prom_halt();
+			}
+
+		   	if (node != 0)
 				node = prom_getsibling(node);
 #ifdef CONFIG_PCI
 			while ((node == 0) && ebus != NULL) {
@@ -496,12 +511,12 @@
 			prom_halt();
 		}
 
-		if(central_bus) {
+		if (cbus != NULL) {
 			apply_fhc_ranges(central_bus->child, clk_reg, 1);
 			apply_central_ranges(central_bus, clk_reg, 1);
 		}
 #ifdef CONFIG_PCI
-		else if (ebus_chain != NULL) {
+		else if (ebus != NULL) {
 			struct linux_ebus_device *edev;
 
 			for_each_ebusdev(edev, ebus)
@@ -523,7 +538,8 @@
 				mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
 			}
 			break;
-		} else if (isa_chain != NULL) {
+		}
+		else if (isa_br != NULL) {
 			struct isa_device *isadev;
 
 try_isa_clock:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/trampoline.S linux/arch/sparc64/kernel/trampoline.S
--- linux.orig/arch/sparc64/kernel/trampoline.S	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/kernel/trampoline.S	2002-07-20 01:08:33.000000000 +0000
@@ -218,13 +218,6 @@
 #define KERN_HIGHBITS		((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
 #define KERN_LOWBITS		(_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
 
-#define VPTE_BASE_SPITFIRE	0xfffffffe00000000
-#if 1
-#define VPTE_BASE_CHEETAH	VPTE_BASE_SPITFIRE
-#else
-#define VPTE_BASE_CHEETAH	0xffe0000000000000
-#endif
-
 	mov		TSB_REG, %g1
 	stxa		%g0, [%g1] ASI_DMMU
 	membar		#Sync
@@ -255,8 +248,6 @@
 	clr	%g7
 #undef KERN_HIGHBITS
 #undef KERN_LOWBITS
-#undef VPTE_BASE_SPITFIRE
-#undef VPTE_BASE_CHEETAH
 
 	/* Setup interrupt globals, we are always SMP. */
 	wrpr		%o1, PSTATE_IG, %pstate
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/kernel/ttable.S linux/arch/sparc64/kernel/ttable.S
--- linux.orig/arch/sparc64/kernel/ttable.S	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/kernel/ttable.S	2002-07-20 01:08:23.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: ttable.S,v 1.36 2001/11/28 23:32:16 davem Exp $
+/* $Id: ttable.S,v 1.36.2.1 2002/03/03 10:31:56 davem Exp $
  * ttable.S: Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions.
  *
  * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu)
@@ -44,8 +44,16 @@
 tl0_privact:	TRAP_NOSAVE(__do_privact)
 tl0_resv038:	BTRAP(0x38) BTRAP(0x39) BTRAP(0x3a) BTRAP(0x3b) BTRAP(0x3c) BTRAP(0x3d)
 tl0_resv03e:	BTRAP(0x3e) BTRAP(0x3f) BTRAP(0x40)
-tl0_irq1:	TRAP_IRQ(handler_irq, 1)  TRAP_IRQ(handler_irq, 2)
-tl0_irq3:	TRAP_IRQ(handler_irq, 3)  TRAP_IRQ(handler_irq, 4)
+#ifdef CONFIG_SMP
+tl0_irq1:	TRAP_IRQ(smp_call_function_client, 1)
+tl0_irq2:	TRAP_IRQ(smp_receive_signal_client, 2)
+tl0_irq3:	TRAP_IRQ(smp_penguin_jailcell, 3)
+#else
+tl0_irq1:	BTRAP(0x41)
+tl0_irq2:	BTRAP(0x42)
+tl0_irq3:	BTRAP(0x43)
+#endif
+tl0_irq4:	TRAP_IRQ(handler_irq, 4)
 tl0_irq5:	TRAP_IRQ(handler_irq, 5)  TRAP_IRQ(handler_irq, 6)
 tl0_irq7:	TRAP_IRQ(handler_irq, 7)  TRAP_IRQ(handler_irq, 8)
 tl0_irq9:	TRAP_IRQ(handler_irq, 9)  TRAP_IRQ(handler_irq, 10)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/lib/Makefile linux/arch/sparc64/lib/Makefile
--- linux.orig/arch/sparc64/lib/Makefile	2000-12-29 22:07:21.000000000 +0000
+++ linux/arch/sparc64/lib/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -1,14 +1,9 @@
-# $Id: Makefile,v 1.25 2000/12/14 22:57:25 davem Exp $
+# $Id: Makefile,v 1.25.2.1 2002/03/14 01:26:21 kanoj Exp $
 # Makefile for Sparc64 library files..
 #
 
-.S.s:
-	$(CPP) $(AFLAGS) -ansi $< -o $*.s
-
-.S.o:
-	$(CC) $(AFLAGS) -ansi -c $< -o $*.o
-
-CFLAGS := $(CFLAGS)
+USE_STANDARD_AS_RULE := true
+EXTRA_AFLAGS := -ansi
 
 L_TARGET = lib.a
 obj-y := PeeCeeI.o blockops.o debuglocks.o strlen.o strncmp.o \
@@ -16,6 +11,6 @@
 	 VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \
 	 VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o \
 	 dec_and_lock.o U3memcpy.o U3copy_from_user.o U3copy_to_user.o \
-	 U3copy_in_user.o
+	 U3copy_in_user.o mcount.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/lib/mcount.S linux/arch/sparc64/lib/mcount.S
--- linux.orig/arch/sparc64/lib/mcount.S	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/sparc64/lib/mcount.S	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
+ *
+ * This file implements mcount(), which is used to collect profiling data.
+ * This can also be tweaked for kernel stack overflow detection.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+
+#include <asm/asm_offsets.h>
+#include <asm/ptrace.h>
+
+/*
+ * This is the main variant and is called by C code.  GCC's -pg option
+ * automatically instruments every C function with a call to this.
+ */
+
+#ifdef CONFIG_STACK_DEBUG
+
+#define OVSTACKSIZE	4096		/* lets hope this is enough */
+
+	.data
+	.align		8
+panicstring:
+	.asciz		"Stack overflow\n"
+	.align		8
+ovstack:
+	.skip		OVSTACKSIZE
+#endif
+	.text
+	.align 32
+	.globl mcount
+mcount:
+#ifdef CONFIG_STACK_DEBUG
+	/*
+	 * Check whether %sp is dangerously low.
+	 */
+	ldub		[%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %g1
+	srl		%g1, 1, %g5
+	add		%g5, 1, %g5
+	sllx		%g5, 8, %g5			! each fpregs frame is 256b
+	add		%g5, 192, %g5
+	add		%g6, %g5, %g5			! where does task_struct+frame end?
+	sub		%g5, STACK_BIAS, %g5
+	cmp		%sp, %g5
+	bg,pt		%xcc, 1f
+	 sethi		%hi(panicstring), %g5
+	sethi		%hi(ovstack), %g7		! cant move to panic stack fast enough
+	 or		%g7, %lo(ovstack), %g7
+	add		%g7, OVSTACKSIZE, %g7
+	sub		%g7, STACK_BIAS, %g7
+	mov		%g7, %sp
+	call		prom_printf
+	 or		%g5, %lo(panicstring), %o0
+	call		prom_halt
+	 nop
+#endif
+1:	retl
+	 nop
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/math-emu/math.c linux/arch/sparc64/math-emu/math.c
--- linux.orig/arch/sparc64/math-emu/math.c	1999-12-21 06:05:52.000000000 +0000
+++ linux/arch/sparc64/math-emu/math.c	2002-07-20 01:08:38.000000000 +0000
@@ -57,6 +57,12 @@
 #define FSTOD	0x0c9
 #define FSTOI	0x0d1
 #define FDTOI	0x0d2
+#define FXTOS	0x084 /* Only Ultra-III generates this. */
+#define FXTOD	0x088 /* Only Ultra-III generates this. */
+#if 0	/* Optimized inline in sparc64/kernel/entry.S */
+#define FITOS	0x0c4 /* Only Ultra-III generates this. */
+#endif
+#define FITOD	0x0c8 /* Only Ultra-III generates this. */
 /* FPOP2 */
 #define FCMPQ	0x053
 #define FCMPEQ	0x057
@@ -175,7 +181,7 @@
 	long XR, xfsr;
 
 	if(tstate & TSTATE_PRIV)
-		die_if_kernel("FPQuad from kernel", regs);
+		die_if_kernel("unfinished/unimplemented FPop from kernel", regs);
 	if(current->thread.flags & SPARC_FLAG_32BIT)
 		pc = (u32)pc;
 	if (get_user(insn, (u32 *)pc) != -EFAULT) {
@@ -217,6 +223,14 @@
 			case FSTOD: TYPE(2,2,1,1,1,0,0); break;
 			case FSTOI: TYPE(2,1,0,1,1,0,0); break;
 			case FDTOI: TYPE(2,1,0,2,1,0,0); break;
+
+			/* Only Ultra-III generates these */
+			case FXTOS: TYPE(2,1,1,2,0,0,0); break;
+			case FXTOD: TYPE(2,2,1,2,0,0,0); break;
+#if 0			/* Optimized inline in sparc64/kernel/entry.S */
+			case FITOS: TYPE(2,1,1,1,0,0,0); break;
+#endif
+			case FITOD: TYPE(2,2,1,1,0,0,0); break;
 			}
 		}
 		else if ((insn & 0xc1f80000) == 0x81a80000) /* FPOP2 */ {
@@ -420,6 +434,13 @@
 		/* int to float */
 		case FITOQ: IR = rs2->s; FP_FROM_INT_Q (QR, IR, 32, int); break;
 		case FXTOQ: XR = rs2->d; FP_FROM_INT_Q (QR, XR, 64, long); break;
+		/* Only Ultra-III generates these */
+		case FXTOS: XR = rs2->d; FP_FROM_INT_S (SR, XR, 64, long); break;
+		case FXTOD: XR = rs2->d; FP_FROM_INT_D (DR, XR, 64, long); break;
+#if 0		/* Optimized inline in sparc64/kernel/entry.S */
+		case FITOS: IR = rs2->s; FP_FROM_INT_S (SR, IR, 32, int); break;
+#endif
+		case FITOD: IR = rs2->s; FP_FROM_INT_D (DR, IR, 32, int); break;
 		/* float to float */
 		case FSTOD: FP_CONV (D, S, 1, 1, DR, SB); break;
 		case FSTOQ: FP_CONV (Q, S, 2, 1, QR, SB); break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/mm/Makefile linux/arch/sparc64/mm/Makefile
--- linux.orig/arch/sparc64/mm/Makefile	2000-12-29 22:07:21.000000000 +0000
+++ linux/arch/sparc64/mm/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -1,17 +1,9 @@
 # $Id: Makefile,v 1.8 2000/12/14 22:57:25 davem Exp $
 # Makefile for the linux Sparc64-specific parts of the memory manager.
 #
-# 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).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-.S.s:
-	$(CPP) $(AFLAGS) -ansi $< -o $*.s
 
-.S.o:
-	$(CC) $(AFLAGS) -ansi -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
+EXTRA_AFLAGS := -ansi
 
 O_TARGET := mm.o
 obj-y    := ultra.o fault.o init.o generic.o extable.o modutil.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/mm/fault.c linux/arch/sparc64/mm/fault.c
--- linux.orig/arch/sparc64/mm/fault.c	2001-09-07 18:01:20.000000000 +0000
+++ linux/arch/sparc64/mm/fault.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.58 2001/09/01 00:11:16 kanoj Exp $
+/* $Id: fault.c,v 1.58.2.2 2002/03/12 12:25:15 davem Exp $
  * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -55,13 +55,21 @@
  */
 void set_brkpt(unsigned long addr, unsigned char mask, int flags, int mode)
 {
-	unsigned long lsubits = LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM;
+	unsigned long lsubits;
+
+	__asm__ __volatile__("ldxa [%%g0] %1, %0"
+			     : "=r" (lsubits)
+			     : "i" (ASI_LSU_CONTROL));
+	lsubits &= ~(LSU_CONTROL_PM | LSU_CONTROL_VM |
+		     LSU_CONTROL_PR | LSU_CONTROL_VR |
+		     LSU_CONTROL_PW | LSU_CONTROL_VW);
 
 	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
 			     "membar	#Sync"
 			     : /* no outputs */
 			     : "r" (addr), "r" (mode ? VIRT_WATCHPOINT : PHYS_WATCHPOINT),
 			       "i" (ASI_DMMU));
+
 	lsubits |= ((unsigned long)mask << (mode ? 25 : 33));
 	if (flags & VM_READ)
 		lsubits |= (mode ? LSU_CONTROL_VR : LSU_CONTROL_PR);
@@ -340,6 +348,20 @@
 		goto good_area;
 	if (!(vma->vm_flags & VM_GROWSDOWN))
 		goto bad_area;
+	if (!(fault_code & FAULT_CODE_WRITE)) {
+		/* Non-faulting loads shouldn't expand stack. */
+		insn = get_fault_insn(regs, insn);
+		if ((insn & 0xc0800000) == 0xc0800000) {
+			unsigned char asi;
+
+			if (insn & 0x2000)
+				asi = (regs->tstate >> 24);
+			else
+				asi = (insn >> 5);
+			if ((asi & 0xf2) == 0x82)
+				goto bad_area;
+		}
+	}
 	if (expand_stack(vma, address))
 		goto bad_area;
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- linux.orig/arch/sparc64/mm/init.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/mm/init.c	2002-07-20 01:08:33.000000000 +0000
@@ -616,7 +616,7 @@
 	}
 }
 
-static int prom_ditlb_set = 0;
+static int prom_ditlb_set;
 struct prom_tlb_entry {
 	int		tlb_ent;
 	unsigned long	tlb_tag;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/mm/ultra.S linux/arch/sparc64/mm/ultra.S
--- linux.orig/arch/sparc64/mm/ultra.S	2001-12-21 17:41:53.000000000 +0000
+++ linux/arch/sparc64/mm/ultra.S	2002-07-20 01:08:38.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.70 2001/11/29 16:42:10 kanoj Exp $
+/* $Id: ultra.S,v 1.70.2.1 2002/03/03 10:31:56 davem Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
@@ -10,6 +10,8 @@
 #include <asm/page.h>
 #include <asm/spitfire.h>
 #include <asm/mmu_context.h>
+#include <asm/pil.h>
+#include <asm/head.h>
 
 	/* Basically, all this madness has to do with the
 	 * fact that Cheetah does not support IMMU flushes
@@ -489,6 +491,15 @@
 	nop
 	nop
 
+	/* NOTE: This is SPECIAL!!  We do etrap/rtrap however
+	 *       we choose to deal with the "BH's run with
+	 *       %pil==15" problem (described in asm/pil.h)
+	 *       by just invoking rtrap directly past where
+	 *       BH's are checked for.
+	 *
+	 *       We do it like this because we do not want %pil==15
+	 *       lockups to prevent regs being reported.
+	 */
 	.globl		xcall_report_regs
 xcall_report_regs:
 	rdpr		%pstate, %g2
@@ -500,8 +511,10 @@
 109:	 or		%g7, %lo(109b), %g7
 	call		__show_regs
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	clr		%l6
+	/* Has to be a non-v9 branch due to the large distance. */
+	b		rtrap_xcall
+	 ldx		[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
 
 	.align		32
 	.globl		xcall_flush_dcache_page_cheetah
@@ -550,20 +563,6 @@
 	nop
 	nop
 
-	.globl		xcall_capture
-xcall_capture:
-	rdpr		%pstate, %g2
-	wrpr		%g2, PSTATE_IG | PSTATE_AG, %pstate
-	rdpr		%pil, %g2
-	wrpr		%g0, 15, %pil
-	sethi		%hi(109f), %g7
-	b,pt		%xcc, etrap_irq
-109:	 or		%g7, %lo(109b), %g7
-	call		smp_penguin_jailcell
-	 nop
-	b,pt		%xcc, rtrap
-	 clr		%l6
-
 	.globl		xcall_promstop
 xcall_promstop:
 	rdpr		%pstate, %g2
@@ -580,21 +579,6 @@
 1:	b,a,pt		%xcc, 1b
 	nop
 
-	.globl		xcall_receive_signal
-xcall_receive_signal:
-	rdpr		%pstate, %g2
-	wrpr		%g2, PSTATE_IG | PSTATE_AG, %pstate
-	rdpr		%tstate, %g1
-	andcc		%g1, TSTATE_PRIV, %g0
-	/* If we did not trap from user space, just ignore. */
-	bne,pn		%xcc, 99f
-	 sethi		%hi(109f), %g7
-	b,pt		%xcc, etrap
-109:	 or		%g7, %lo(109b), %g7
-	b,pt		%xcc, rtrap
-	 clr		%l6
-99:	retry
-
 	.data
 
 errata32_hwbug:
@@ -677,18 +661,20 @@
 __cheetah_xcall_flush_cache_all:
 	retry
 
+	/* These just get rescheduled to PIL vectors. */
 	.globl		xcall_call_function
 xcall_call_function:
-	rdpr		%pstate, %g2
-	wrpr		%g2, PSTATE_IG | PSTATE_AG, %pstate
-	rdpr		%pil, %g2
-	wrpr		%g0, 15, %pil
-	sethi		%hi(109f), %g7
-	b,pt		%xcc, etrap_irq
-109:	 or		%g7, %lo(109b), %g7
-	call		smp_call_function_client
-	 nop
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	wr		%g0, (1 << PIL_SMP_CALL_FUNC), %set_softint
+	retry
+
+	.globl		xcall_receive_signal
+xcall_receive_signal:
+	wr		%g0, (1 << PIL_SMP_RECEIVE_SIGNAL), %set_softint
+	retry
+
+	.globl		xcall_capture
+xcall_capture:
+	wr		%g0, (1 << PIL_SMP_CAPTURE), %set_softint
+	retry
 
 #endif /* CONFIG_SMP */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/prom/Makefile linux/arch/sparc64/prom/Makefile
--- linux.orig/arch/sparc64/prom/Makefile	2000-12-29 22:07:21.000000000 +0000
+++ linux/arch/sparc64/prom/Makefile	2002-07-20 01:08:30.000000000 +0000
@@ -1,21 +1,16 @@
-# $Id: Makefile,v 1.7 2000/12/14 22:57:25 davem Exp $
+# $Id: Makefile,v 1.7.2.1 2002/03/14 01:26:21 kanoj Exp $
 # Makefile for the Sun Boot PROM interface library under
 # Linux.
 #
-# 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).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
+
+USE_STANDARD_AS_RULE := true
+EXTRA_AFLAGS := -ansi
 
 L_TARGET = promlib.a
 obj-y   := bootstr.o devops.o init.o memory.o misc.o \
 	   tree.o console.o printf.o p1275.o map.o
 
-.S.s:
-	$(CPP) $(AFLAGS) -ansi $< -o $*.s
-
-.S.o:
-	$(CC) $(AFLAGS) -ansi -c $< -o $*.o
-
 include $(TOPDIR)/Rules.make
+
+%.o: %.c
+	$(CC) $(subst -pg,,$(CFLAGS)) -c $<
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/prom/bootstr.c linux/arch/sparc64/prom/bootstr.c
--- linux.orig/arch/sparc64/prom/bootstr.c	1999-08-31 18:23:30.000000000 +0000
+++ linux/arch/sparc64/prom/bootstr.c	2002-07-20 01:08:26.000000000 +0000
@@ -9,6 +9,11 @@
 #include <linux/init.h>
 #include <asm/oplib.h>
 
+/* WARNING: The boot loader knows that these next three variables come one right
+ *          after another in the .data section.  Do not move this stuff into
+ *          the .bss section or it will break things.
+ */
+
 #define BARG_LEN  256
 int bootstr_len = BARG_LEN;
 static int bootstr_valid = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/prom/misc.c linux/arch/sparc64/prom/misc.c
--- linux.orig/arch/sparc64/prom/misc.c	2001-10-01 16:19:56.000000000 +0000
+++ linux/arch/sparc64/prom/misc.c	2002-07-20 01:08:29.000000000 +0000
@@ -171,7 +171,7 @@
 
 static int prom_get_memory_ihandle(void)
 {
-	static int memory_ihandle_cache = 0;
+	static int memory_ihandle_cache;
 	int node, ret;
 
 	if (memory_ihandle_cache != 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/solaris/Makefile linux/arch/sparc64/solaris/Makefile
--- linux.orig/arch/sparc64/solaris/Makefile	2000-12-29 22:07:21.000000000 +0000
+++ linux/arch/sparc64/solaris/Makefile	2002-07-20 01:08:23.000000000 +0000
@@ -7,16 +7,13 @@
 #
 # Note 2! The CFLAGS definition is now in the main makefile...
 
+USE_STANDARD_AS_RULE := true
+EXTRA_AFLAGS := -ansi
+
 ifeq ($(CONFIG_SOLARIS_EMUL),m)
-CPPFLAGS = $(MODFLAGS)
+  EXTRA_AFLAGS += $(MODFLAGS)
 endif
 
-.S.s:
-	$(CPP) $(AFLAGS) $(CPPFLAGS) -ansi $< -o $*.s
-
-.S.o:
-	$(CC) $(AFLAGS) $(CPPFLAGS) -ansi -c $< -o $*.o
-
 list-multi := solaris.o
 
 solaris-objs := entry64.o fs.o misc.o signal.o systbl.o socket.o \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/solaris/ioctl.c linux/arch/sparc64/solaris/ioctl.c
--- linux.orig/arch/sparc64/solaris/ioctl.c	2000-11-29 05:53:44.000000000 +0000
+++ linux/arch/sparc64/solaris/ioctl.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: ioctl.c,v 1.16 2000/11/18 02:10:59 davem Exp $
+/* $Id: ioctl.c,v 1.16.2.1 2002/03/03 23:41:26 davem Exp $
  * ioctl.c: Solaris ioctl emulation.
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -289,11 +289,15 @@
 {
 	struct inode *ino;
 	/* I wonder which of these tests are superfluous... --patrik */
+	read_lock(&current->files->file_lock);
 	if (! current->files->fd[fd] ||
 	    ! current->files->fd[fd]->f_dentry ||
 	    ! (ino = current->files->fd[fd]->f_dentry->d_inode) ||
-	    ! ino->i_sock)
+	    ! ino->i_sock) {
+		read_unlock(&current->files->file_lock);
 		return TBADF;
+	}
+	read_unlock(&current->files->file_lock);
 	
 	switch (cmd & 0xff) {
 	case 109: /* SI_SOCKPARAMS */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/solaris/misc.c linux/arch/sparc64/solaris/misc.c
--- linux.orig/arch/sparc64/solaris/misc.c	2001-09-20 21:11:57.000000000 +0000
+++ linux/arch/sparc64/solaris/misc.c	2002-07-20 01:08:34.000000000 +0000
@@ -56,7 +56,7 @@
 	/* Do we need it here? */
 	set_personality(PER_SVR4);
 	if (flags & MAP_NORESERVE) {
-		static int cnt = 0;
+		static int cnt;
 		
 		if (cnt < 5) {
 			printk("%s:  unimplemented Solaris MAP_NORESERVE mmap() flag\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/sparc64/solaris/timod.c linux/arch/sparc64/solaris/timod.c
--- linux.orig/arch/sparc64/solaris/timod.c	2002-02-25 19:37:56.000000000 +0000
+++ linux/arch/sparc64/solaris/timod.c	2002-07-20 01:08:33.000000000 +0000
@@ -46,7 +46,7 @@
 void * mykmalloc(size_t s, int gfp)
 {
 	static char * page;
-	static size_t free = 0;
+	static size_t free;
 	void * r;
 	s = ((s + 63) & ~63);
 	if( s > PAGE_SIZE ) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/Makefile linux/drivers/Makefile
--- linux.orig/drivers/Makefile	2002-02-25 19:37:56.000000000 +0000
+++ linux/drivers/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -24,7 +24,7 @@
 subdir-$(CONFIG_TC)		+= tc
 subdir-$(CONFIG_VT)		+= video
 subdir-$(CONFIG_MAC)		+= macintosh
-subdir-$(CONFIG_ALL_PPC)	+= macintosh
+subdir-$(CONFIG_PPC)		+= macintosh
 subdir-$(CONFIG_USB)		+= usb
 subdir-$(CONFIG_INPUT)		+= input
 subdir-$(CONFIG_PHONE)		+= telephony
@@ -36,7 +36,7 @@
 subdir-$(CONFIG_MD)		+= md
 subdir-$(CONFIG_IEEE1394)	+= ieee1394
 subdir-$(CONFIG_PNP)		+= pnp
-subdir-$(CONFIG_ISDN)		+= isdn
+subdir-$(CONFIG_ISDN_BOOL)	+= isdn
 subdir-$(CONFIG_ATM)		+= atm
 subdir-$(CONFIG_FC4)		+= fc4
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/acorn/block/fd1772.c linux/drivers/acorn/block/fd1772.c
--- linux.orig/drivers/acorn/block/fd1772.c	2001-08-12 17:38:48.000000000 +0000
+++ linux/drivers/acorn/block/fd1772.c	2002-07-20 01:08:32.000000000 +0000
@@ -1620,7 +1620,3 @@
 
 	return 0;
 }
-
-void floppy_eject(void)
-{
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- linux.orig/drivers/acorn/block/mfmhd.c	2001-10-25 20:58:35.000000000 +0000
+++ linux/drivers/acorn/block/mfmhd.c	2002-07-20 01:08:28.000000000 +0000
@@ -1369,9 +1369,6 @@
  */
 static int mfm_probecontroller (unsigned int mfm_addr)
 {
-	if (check_region (mfm_addr, 10))
-		return 0;
-
 	if (inw (MFM_STATUS) & STAT_BSY) {
 		outw (CMD_ABT, MFM_COMMAND);
 		udelay (50);
@@ -1429,15 +1426,19 @@
 		ecard_claim(ecs);
 	}
 
+	printk("mfm: found at address %08X, interrupt %d\n", mfm_addr, mfm_irq);
+	if (!request_region (mfm_addr, 10, "mfm")) {
+		ecard_release(ecs);
+		return -1;
+	}
+
 	if (register_blkdev(MAJOR_NR, "mfm", &mfm_fops)) {
 		printk("mfm_init: unable to get major number %d\n", MAJOR_NR);
 		ecard_release(ecs);
+		release_region(mfm_addr, 10);
 		return -1;
 	}
 
-	printk("mfm: found at address %08X, interrupt %d\n", mfm_addr, mfm_irq);
-	request_region (mfm_addr, 10, "mfm");
-
 	/* Stuff for the assembler routines to get to */
 	hdc63463_baseaddress	= ioaddr(mfm_addr);
 	hdc63463_irqpolladdress	= mfm_IRQPollLoc;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/acorn/char/mouse_ps2.c linux/drivers/acorn/char/mouse_ps2.c
--- linux.orig/drivers/acorn/char/mouse_ps2.c	2001-08-12 17:38:48.000000000 +0000
+++ linux/drivers/acorn/char/mouse_ps2.c	2002-07-20 01:08:28.000000000 +0000
@@ -273,7 +273,8 @@
 	iomd_writeb(0, IOMD_MSECTL);
 	iomd_writeb(8, IOMD_MSECTL);
   
-	misc_register(&psaux_mouse);
+	if (misc_register(&psaux_mouse))
+		return -ENODEV;
 	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
 	memset(queue, 0, sizeof(*queue));
 	queue->head = queue->tail = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/acorn/net/etherh.c linux/drivers/acorn/net/etherh.c
--- linux.orig/drivers/acorn/net/etherh.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/acorn/net/etherh.c	2002-07-20 01:08:39.000000000 +0000
@@ -475,7 +475,7 @@
 		if (i == 6)
 			return 0;
 	}
-	return ENODEV;
+	return -ENODEV;
 }
 
 /*
@@ -486,7 +486,7 @@
 	unsigned int serial;
 
 	if (system_serial_low == 0 && system_serial_high == 0)
-		return ENODEV;
+		return -ENODEV;
 
 	serial = system_serial_low | system_serial_high;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/acorn/scsi/acornscsi.c linux/drivers/acorn/scsi/acornscsi.c
--- linux.orig/drivers/acorn/scsi/acornscsi.c	2001-10-11 16:04:57.000000000 +0000
+++ linux/drivers/acorn/scsi/acornscsi.c	2002-07-20 01:08:21.000000000 +0000
@@ -2915,13 +2915,18 @@
 	ecs[count]->irqaddr	= (char *)ioaddr(host->card.io_intr);
 	ecs[count]->irqmask	= 0x0a;
 
-	request_region(instance->io_port + 0x800,  2, "acornscsi(sbic)");
-	request_region(host->card.io_intr,  1, "acornscsi(intr)");
-	request_region(host->card.io_page,  1, "acornscsi(page)");
+	if (!request_region(instance->io_port + 0x800,  2, "acornscsi(sbic)"))
+		goto err_1;
+	if (!request_region(host->card.io_intr,  1, "acornscsi(intr)"))
+		goto err_2;
+	if (!request_region(host->card.io_page,  1, "acornscsi(page)"))
+		goto err_3;
 #ifdef USE_DMAC
-	request_region(host->dma.io_port, 256, "acornscsi(dmac)");
+	if (!request_region(host->dma.io_port, 256, "acornscsi(dmac)"))
+		goto err_4;
 #endif
-	request_region(instance->io_port, 2048, "acornscsi(ram)");
+	if (!request_region(instance->io_port, 2048, "acornscsi(ram)"))
+		goto err_5;
 
 	if (request_irq(host->scsi.irq, acornscsi_intr, SA_INTERRUPT, "acornscsi", host)) {
 	    printk(KERN_CRIT "scsi%d: IRQ%d not free, interrupts disabled\n",
@@ -2934,6 +2939,20 @@
 	++count;
     }
     return count;
+    
+err_5:
+#ifdef USE_DMAC
+    release_region(host->dma.io_port, 256);
+#endif
+err_4:
+    release_region(host->card.io_page, 1);
+err_3:
+    release_region(host->card.io_intr, 1);    
+err_2:
+    release_region(instance->io_port + 0x800, 2);
+err_1:
+    scsi_unregister(instance);
+    return 0;
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/acorn/scsi/ecoscsi.c linux/drivers/acorn/scsi/ecoscsi.c
--- linux.orig/drivers/acorn/scsi/ecoscsi.c	2001-10-25 20:53:46.000000000 +0000
+++ linux/drivers/acorn/scsi/ecoscsi.c	2002-07-20 01:08:40.000000000 +0000
@@ -125,7 +125,10 @@
     }
 
     NCR5380_init(instance, 0);
-    request_region (instance->io_port, instance->n_io_port, "ecoscsi");
+    if (request_region (instance->io_port, instance->n_io_port, "ecoscsi") == NULL) {
+	scsi_unregister(instance);
+	return 0;
+    }
 
     if (instance->irq != IRQ_NONE)
 	if (request_irq(instance->irq, do_ecoscsi_intr, SA_INTERRUPT, "ecoscsi", NULL)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/acpi/acpi_ksyms.c linux/drivers/acpi/acpi_ksyms.c
--- linux.orig/drivers/acpi/acpi_ksyms.c	2001-10-24 21:06:21.000000000 +0000
+++ linux/drivers/acpi/acpi_ksyms.c	2002-07-20 01:08:32.000000000 +0000
@@ -106,6 +106,7 @@
 EXPORT_SYMBOL(acpi_enter_sleep_state);
 EXPORT_SYMBOL(acpi_get_system_info);
 EXPORT_SYMBOL(acpi_leave_sleep_state);
+EXPORT_SYMBOL(acpi_walk_namespace);
 /*EXPORT_SYMBOL(acpi_save_state_mem);*/
 /*EXPORT_SYMBOL(acpi_save_state_disk);*/
 EXPORT_SYMBOL(acpi_hw_register_read);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/acpi/executer/exresnte.c linux/drivers/acpi/executer/exresnte.c
--- linux.orig/drivers/acpi/executer/exresnte.c	2001-10-24 21:06:22.000000000 +0000
+++ linux/drivers/acpi/executer/exresnte.c	2002-07-20 01:08:28.000000000 +0000
@@ -44,7 +44,7 @@
  * FUNCTION:    Acpi_ex_resolve_node_to_value
  *
  * PARAMETERS:  Object_ptr      - Pointer to a location that contains
- *                                a pointer to a NS node, and will recieve a
+ *                                a pointer to a NS node, and will receive a
  *                                pointer to the resolved object.
  *              Walk_state      - Current state.  Valid only if executing AML
  *                                code.  NULL if simply resolving an object
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/atm/fore200e.c linux/drivers/atm/fore200e.c
--- linux.orig/drivers/atm/fore200e.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/atm/fore200e.c	2002-07-20 01:08:36.000000000 +0000
@@ -252,7 +252,7 @@
 fore200e_spin(int msecs)
 {
     unsigned long timeout = jiffies + MSECS(msecs);
-    while (jiffies < timeout);
+    while (time_before(jiffies, timeout));
 }
 
 
@@ -267,7 +267,7 @@
 	if ((ok = (*addr == val)) || (*addr & STATUS_ERROR))
 	    break;
 
-    } while (jiffies < timeout);
+    } while (time_before(jiffies, timeout));
 
 #if 1
     if (!ok) {
@@ -290,7 +290,7 @@
 	if ((ok = (fore200e->bus->read(addr) == val)))
 	    break;
 
-    } while (jiffies < timeout);
+    } while (time_before(jiffies, timeout));
 
 #if 1
     if (!ok) {
@@ -2417,7 +2417,7 @@
     unsigned long      timeout = jiffies + MSECS(50);
     int                c;
 
-    while (jiffies < timeout) {
+    while (time_before(jiffies, timeout)) {
 
 	c = (int) fore200e->bus->read(&monitor->soft_uart.recv);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/atm/horizon.c linux/drivers/atm/horizon.c
--- linux.orig/drivers/atm/horizon.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/atm/horizon.c	2002-07-20 01:08:21.000000000 +0000
@@ -2765,15 +2765,13 @@
     u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 1));
     u8 irq = pci_dev->irq;
     
-    // check IO region
-    if (check_region (iobase, HRZ_IO_EXTENT)) {
-      PRINTD (DBG_WARN, "IO range already in use");
-      continue;
-    }
+    /* XXX DEV_LABEL is a guess */
+    if (!request_region (iobase, HRZ_IO_EXTENT, DEV_LABEL))
+  	  continue;
 
     if (pci_enable_device (pci_dev))
       continue;
-
+    
     dev = kmalloc (sizeof(hrz_dev), GFP_KERNEL);
     if (!dev) {
       // perhaps we should be nice: deregister all adapters and abort?
@@ -2807,9 +2805,6 @@
 	dev->atm_dev->dev_data = (void *) dev;
 	dev->pci_dev = pci_dev; 
 	
-	/* XXX DEV_LABEL is a guess */
-	request_region (iobase, HRZ_IO_EXTENT, DEV_LABEL);
-	
 	// enable bus master accesses
 	pci_set_master (pci_dev);
 	
@@ -2901,8 +2896,10 @@
 	atm_dev_deregister (dev->atm_dev);
       } /* atm_dev_register */
       free_irq (irq, dev);
+	
     } /* request_irq */
     kfree (dev);
+    release_region(iobase, HRZ_IO_EXTENT);
   } /* kmalloc and while */
   return devs;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/Config.in linux/drivers/block/Config.in
--- linux.orig/drivers/block/Config.in	2001-09-14 21:04:06.000000000 +0000
+++ linux/drivers/block/Config.in	2002-07-20 01:08:29.000000000 +0000
@@ -35,7 +35,9 @@
 fi
 dep_tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA $CONFIG_PCI
 dep_tristate 'Compaq Smart Array 5xxx support' CONFIG_BLK_CPQ_CISS_DA $CONFIG_PCI 
+dep_mbool '       SCSI tape drive support for Smart Array 5xxx' CONFIG_CISS_SCSI_TAPE $CONFIG_BLK_CPQ_CISS_DA $CONFIG_SCSI
 dep_tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960 $CONFIG_PCI
+dep_tristate 'Micro Memory MM5415 Battery Backed RAM support' CONFIG_BLK_DEV_UMEM $CONFIG_PCI $CONFIG_EXPERIMENTAL
 
 tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
 dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- linux.orig/drivers/block/DAC960.c	2001-10-25 20:58:35.000000000 +0000
+++ linux/drivers/block/DAC960.c	2002-07-20 01:08:39.000000000 +0000
@@ -7013,3 +7013,5 @@
 
 module_init(DAC960_Initialize);
 module_exit(DAC960_Finalize);
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/Makefile linux/drivers/block/Makefile
--- linux.orig/drivers/block/Makefile	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/block/Makefile	2002-07-20 01:08:39.000000000 +0000
@@ -29,7 +29,7 @@
 obj-$(CONFIG_BLK_CPQ_DA)	+= cpqarray.o
 obj-$(CONFIG_BLK_CPQ_CISS_DA)  += cciss.o
 obj-$(CONFIG_BLK_DEV_DAC960)	+= DAC960.o
-
+obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_NBD)	+= nbd.o
 
 subdir-$(CONFIG_PARIDE) += paride
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/amiflop.c linux/drivers/block/amiflop.c
--- linux.orig/drivers/block/amiflop.c	2001-10-25 20:58:34.000000000 +0000
+++ linux/drivers/block/amiflop.c	2002-07-20 01:08:36.000000000 +0000
@@ -1491,7 +1491,6 @@
 {
 	int drive = inode->i_rdev & 3;
 	static struct floppy_struct getprm;
-	struct super_block * sb;
 
 	switch(cmd){
 	case HDIO_GETGEO:
@@ -1678,9 +1677,6 @@
 
 static int floppy_release(struct inode * inode, struct file * filp)
 {
-#ifdef DEBUG
-	struct super_block * sb;
-#endif
 	int drive = MINOR(inode->i_rdev) & 3;
 
 	if (unit[drive].dirty == 1) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/blkpg.c linux/drivers/block/blkpg.c
--- linux.orig/drivers/block/blkpg.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/block/blkpg.c	2002-07-20 01:08:23.000000000 +0000
@@ -110,6 +110,7 @@
 	g->part[minor].nr_sects = plength;
 	if (g->sizes)
 		g->sizes[minor] = (plength >> (BLOCK_SIZE_BITS - 9));
+	devfs_register_partitions (g, first_minor, 0);
 	return 0;
 }
 
@@ -157,6 +158,7 @@
 	g->part[minor].nr_sects = 0;
 	if (g->sizes)
 		g->sizes[minor] = 0;
+	devfs_register_partitions (g, first_minor, 0);
 
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/cciss.c linux/drivers/block/cciss.c
--- linux.orig/drivers/block/cciss.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/drivers/block/cciss.c	2002-07-20 01:08:40.000000000 +0000
@@ -64,6 +64,8 @@
                         0x0E11, 0x4080, 0, 0, 0},
 	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB,
                         0x0E11, 0x4082, 0, 0, 0},
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB,
+                        0x0E11, 0x4083, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -78,6 +80,7 @@
 	{ 0x40700E11, "Smart Array 5300",	&SA5_access },
 	{ 0x40800E11, "Smart Array 5i", &SA5B_access},
 	{ 0x40820E11, "Smart Array 532", &SA5B_access},
+	{ 0x40830E11, "Smart Array 5312", &SA5B_access},
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
@@ -99,7 +102,6 @@
 static int cciss_ioctl(struct inode *inode, struct file *filep, 
 		unsigned int cmd, unsigned long arg);
 
-static int revalidate_allvol(kdev_t dev);
 static int revalidate_logvol(kdev_t dev, int maxusage);
 static int frevalidate_logvol(kdev_t dev);
 
@@ -126,6 +128,8 @@
 	revalidate:		frevalidate_logvol,
 };
 
+#include "cciss_scsi.c"		/* For SCSI tape support */
+
 /*
  * Report information about this controller.
  */
@@ -162,6 +166,7 @@
 		h->maxQsinceinit, h->max_outstanding, h->maxSG);
 
         pos += size; len += size;
+	cciss_proc_tape_report(ctlr, buffer, &pos, &len);
 	for(i=0; i<h->num_luns; i++) {
                 drv = &h->drv[i];
                 size = sprintf(buffer+len, "cciss/c%dd%d: blksz=%d nr_blocks=%d\n",
@@ -181,20 +186,53 @@
         return len;
 }
 
+static int
+cciss_proc_write(struct file *file, const char *buffer,
+			unsigned long count, void *data)
+{
+	unsigned char cmd[80];
+	int len;
+#ifdef CONFIG_CISS_SCSI_TAPE
+	ctlr_info_t *h = (ctlr_info_t *) data;
+	int rc;
+#endif
+
+	if (count > sizeof(cmd)-1) return -EINVAL;
+	if (copy_from_user(cmd, buffer, count)) return -EFAULT;
+	cmd[count] = '\0';
+	len = strlen(cmd);	// safe???
+	if (cmd[len-1] == '\n')
+		cmd[--len] = '\0';
+#	ifdef CONFIG_CISS_SCSI_TAPE
+		if (strcmp("engage scsi", cmd)==0) {
+			rc = cciss_engage_scsi(h->ctlr);
+			if (rc != 0) return -rc;
+			return count;
+		}
+		/* might be nice to have "disengage" too, but it's not
+		   safely possible. (only 1 module use count, lock issues.) */
+#	endif
+	return -EINVAL;
+}
+
 /*
  * Get us a file in /proc/cciss that says something about each controller.
  * Create /proc/cciss if it doesn't exist yet.
  */
 static void __init cciss_procinit(int i)
 {
-        if (proc_cciss == NULL) {
-                proc_cciss = proc_mkdir("cciss", proc_root_driver);
-                if (!proc_cciss) 
+	struct proc_dir_entry *pde;
+
+	if (proc_cciss == NULL) {
+		proc_cciss = proc_mkdir("cciss", proc_root_driver);
+		if (!proc_cciss)
 			return;
-        }
+	}
 
-        create_proc_read_entry(hba[i]->devname, 0, proc_cciss,
-        		cciss_proc_get_info, hba[i]);
+	pde = create_proc_read_entry(hba[i]->devname,
+		S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH,
+		proc_cciss, cciss_proc_get_info, hba[i]);
+	pde->write_proc = cciss_proc_write;
 }
 #endif /* CONFIG_PROC_FS */
 
@@ -331,20 +369,18 @@
 
 	if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
 		return -ENXIO;
-
-	if (!suser() && hba[ctlr]->sizes[ MINOR(inode->i_rdev)] == 0)
-		return -ENXIO;
-
 	/*
 	 * Root is allowed to open raw volume zero even if its not configured
-	 * so array config can still work.  I don't think I really like this,
+	 * so array config can still work. I don't think I really like this,
 	 * but I'm already using way to many device nodes to claim another one
 	 * for "raw controller".
 	 */
-	if (suser()
-		&& (hba[ctlr]->sizes[MINOR(inode->i_rdev)] == 0) 
-		&& (MINOR(inode->i_rdev)!= 0))
-		return -ENXIO;
+	if (hba[ctlr]->sizes[MINOR(inode->i_rdev)] == 0) { /* not online? */
+		if (MINOR(inode->i_rdev) != 0)	 /* not node 0? */
+			return -ENXIO;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+	}
 
 	hba[ctlr]->drv[dsk].usage_count++;
 	hba[ctlr]->usage_count++;
@@ -377,8 +413,6 @@
 {
 	int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
 	int dsk  = MINOR(inode->i_rdev) >> NWD_SHIFT;
-	int diskinfo[4];
-	struct hd_geometry *geo = (struct hd_geometry *)arg;
 
 #ifdef CCISS_DEBUG
 	printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
@@ -386,19 +420,45 @@
 	
 	switch(cmd) {
 	case HDIO_GETGEO:
+	{
+		struct hd_geometry driver_geo;
 		if (hba[ctlr]->drv[dsk].cylinders) {
-			diskinfo[0] = hba[ctlr]->drv[dsk].heads;
-			diskinfo[1] = hba[ctlr]->drv[dsk].sectors;
-			diskinfo[2] = hba[ctlr]->drv[dsk].cylinders;
+			driver_geo.heads = hba[ctlr]->drv[dsk].heads;
+			driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders;
 		} else {
-			diskinfo[0] = 0xff;
-			diskinfo[1] = 0x3f;
-			diskinfo[2] = hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f);		}
-		put_user(diskinfo[0], &geo->heads);
-		put_user(diskinfo[1], &geo->sectors);
-		put_user(diskinfo[2], &geo->cylinders);
-		put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect, &geo->start);
-		return 0;
+			driver_geo.heads = 0xff;
+			driver_geo.sectors = 0x3f;
+			driver_geo.cylinders = 
+				hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f);
+		}
+		driver_geo.start=
+			hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect;
+		if (copy_to_user((void *) arg, &driver_geo,
+				sizeof( struct hd_geometry)))
+			return  -EFAULT;
+		return(0);
+	}
+	case HDIO_GETGEO_BIG:
+	{
+		struct hd_big_geometry driver_geo;
+		if (hba[ctlr]->drv[dsk].cylinders) {
+			driver_geo.heads = hba[ctlr]->drv[dsk].heads;
+			driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders;
+		} else {
+			driver_geo.heads = 0xff;
+			driver_geo.sectors = 0x3f;
+			driver_geo.cylinders = 
+				hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f);
+		}
+		driver_geo.start= 
+		hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect;
+		if (copy_to_user((void *) arg, &driver_geo,  
+				sizeof( struct hd_big_geometry)))
+			return  -EFAULT;
+		return(0);
+	}
 	case BLKGETSIZE:
 		put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
 		return 0;
@@ -406,6 +466,8 @@
 		put_user((u64)hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects << 9, (u64*)arg);
 		return 0;
 	case BLKRRPART:
+		if(!capable(CAP_SYS_ADMIN))
+			return -EPERM;
 		return revalidate_logvol(inode->i_rdev, 1);
 	case BLKFLSBUF:
 	case BLKBSZSET:
@@ -581,9 +643,28 @@
                 return(0);
         }
 
-	case CCISS_REVALIDVOLS:
-                return( revalidate_allvol(inode->i_rdev));
-	
+	case CCISS_GETLUNINFO:
+	{
+		LogvolInfo_struct luninfo;
+		int num_parts = 0;
+		int i, start;
+
+		luninfo.LunID = hba[ctlr]->drv[dsk].LunID;
+		luninfo.num_opens = hba[ctlr]->drv[dsk].usage_count;
+
+		/* count partitions 1 to 15 with sizes > 0 */
+  		start = (dsk << NWD_SHIFT);
+		for(i=1; i <MAX_PART; i++) {
+			int minor = start+i;
+			if(hba[ctlr]->sizes[minor] != 0)
+				num_parts++;
+		}
+		luninfo.num_parts = num_parts;
+		if (copy_to_user((void *) arg, &luninfo,
+				sizeof( LogvolInfo_struct) ))
+			return -EFAULT;
+		return(0);
+	}
 	case CCISS_PASSTHRU:
 	{
 		IOCTL_Command_struct iocommand;
@@ -592,6 +673,7 @@
 		char 	*buff = NULL;
 		u64bit	temp64;
 		unsigned long flags;
+		DECLARE_COMPLETION(wait);
 
 		if (!arg) return -EINVAL;
 	
@@ -657,6 +739,8 @@
 			c->SG[0].Len = iocommand.buf_size;
 			c->SG[0].Ext = 0;  // we are not chaining
 		}
+		c->waiting = &wait;
+
 		/* Put the request on the tail of the request queue */
 		spin_lock_irqsave(&io_request_lock, flags);
 		addQ(&h->reqQ, c);
@@ -664,9 +748,7 @@
 		start_io(h);
 		spin_unlock_irqrestore(&io_request_lock, flags);
 
-		/* Wait for completion */
-		while(c->cmd_type != CMD_IOCTL_DONE)
-			schedule_timeout(1);
+		wait_for_completion(&wait);
 
 		/* unlock the buffers from DMA */
 		temp64.val32.lower = c->SG[0].Addr.lower;
@@ -755,69 +837,6 @@
 #endif /* CCISS_DEBUG */ 
 	return revalidate_logvol(dev, 0);
 }
-
-/*
- * revalidate_allvol is for online array config utilities.  After a
- * utility reconfigures the drives in the array, it can use this function
- * (through an ioctl) to make the driver zap any previous disk structs for
- * that controller and get new ones.
- *
- * Right now I'm using the getgeometry() function to do this, but this
- * function should probably be finer grained and allow you to revalidate one
- * particualar logical volume (instead of all of them on a particular
- * controller).
- */
-static int revalidate_allvol(kdev_t dev)
-{
-	int ctlr, i;
-	unsigned long flags;
-
-	ctlr = MAJOR(dev) - MAJOR_NR;
-        if (MINOR(dev) != 0)
-                return -ENXIO;
-
-        spin_lock_irqsave(&io_request_lock, flags);
-        if (hba[ctlr]->usage_count > 1) {
-                spin_unlock_irqrestore(&io_request_lock, flags);
-                printk(KERN_WARNING "cciss: Device busy for volume"
-                        " revalidation (usage=%d)\n", hba[ctlr]->usage_count);
-                return -EBUSY;
-        }
-        spin_unlock_irqrestore(&io_request_lock, flags);
-        hba[ctlr]->usage_count++;
-
-        /*
-         * Set the partition and block size structures for all volumes
-         * on this controller to zero.  We will reread all of this data
-         */
-	memset(hba[ctlr]->hd,         0, sizeof(struct hd_struct) * 256);
-        memset(hba[ctlr]->sizes,      0, sizeof(int) * 256);
-        memset(hba[ctlr]->blocksizes, 0, sizeof(int) * 256);
-        memset(hba[ctlr]->hardsizes,  0, sizeof(int) * 256);
-        memset(hba[ctlr]->drv,        0, sizeof(drive_info_struct)
-						* CISS_MAX_LUN);
-        hba[ctlr]->gendisk.nr_real = 0;
-
-        /*
-         * Tell the array controller not to give us any interrupts while
-         * we check the new geometry.  Then turn interrupts back on when
-         * we're done.
-         */
-        hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_OFF);
-        cciss_getgeometry(ctlr);
-        hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_ON);
-
-        cciss_geninit(ctlr);
-        for(i=0; i<NWD; i++)
-                if (hba[ctlr]->sizes[ i<<NWD_SHIFT ])
-                        revalidate_logvol(dev+(i<<NWD_SHIFT), 2);
-
-        hba[ctlr]->usage_count--;
-        return 0;
-}
-
-
-
 /*
  *   Wait polling for a command to complete.
  *   The memory mapped FIFO is polled for the completion.
@@ -849,9 +868,12 @@
 	int	ctlr,
 	void	*buff,
 	size_t	size,
-	unsigned int use_unit_num,
+	unsigned int use_unit_num, /* 0: address the controller,
+				      1: address logical volume log_unit,
+				      2: periph device address is scsi3addr */
 	unsigned int log_unit,
-	__u8	page_code )
+	__u8	page_code,
+	unsigned char *scsi3addr)
 {
 	CommandList_struct *c;
 	int i;
@@ -885,15 +907,23 @@
 				to controller so It's a physical command
 				mode = 0 target = 0.
 				So we have nothing to write. 
-				Otherwise 
-				mode = 1  target = LUNID
+				otherwise, if use_unit_num == 1,
+				mode = 1(volume set addressing) target = LUNID
+				otherwise, if use_unit_num == 2,
+				mode = 0(periph dev addr) target = scsi3addr
 			*/
-			if(use_unit_num != 0)
+			if(use_unit_num == 1)
 			{
 				c->Header.LUN.LogDev.VolId=
                                 	hba[ctlr]->drv[log_unit].LunID;
                         	c->Header.LUN.LogDev.Mode = 1;
 			}
+			else if (use_unit_num == 2)
+			{
+				memcpy(c->Header.LUN.LunAddrBytes,scsi3addr,8);
+				c->Header.LUN.LogDev.Mode = 0; // phys dev addr
+			}
+
 			/* are we trying to read a vital product page */
 			if(page_code != 0)
 			{
@@ -909,6 +939,7 @@
 			c->Request.CDB[4] = size  & 0xFF;  
 		break;
 		case CISS_REPORT_LOG:
+		case CISS_REPORT_PHYS:
                         /* Talking to controller so It's a physical command
                                 mode = 00 target = 0.
                                 So we have nothing to write.
@@ -918,7 +949,7 @@
                         c->Request.Type.Attribute = ATTR_SIMPLE; 
                         c->Request.Type.Direction = XFER_READ; // Read
                         c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = CISS_REPORT_LOG;
+			c->Request.CDB[0] = cmd;
                         c->Request.CDB[6] = (size >> 24) & 0xFF;  //MSB
                         c->Request.CDB[7] = (size >> 16) & 0xFF;
                         c->Request.CDB[8] = (size >> 8) & 0xFF;
@@ -936,6 +967,15 @@
                         c->Request.Timeout = 0; // Don't time out
                         c->Request.CDB[0] = CCISS_READ_CAPACITY;
 		break;
+		case CCISS_CACHE_FLUSH:
+			c->Request.CDBLen = 12;
+			c->Request.Type.Type =  TYPE_CMD; // It is a command.
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_WRITE; // No data
+			c->Request.Timeout = 0; // Don't time out
+			c->Request.CDB[0] = BMIC_WRITE;  // BMIC Passthru
+			c->Request.CDB[6] = BMIC_CACHE_FLUSH;
+		break;
 		default:
 			printk(KERN_WARNING
 				"cciss:  Unknown Command 0x%c sent attempted\n",
@@ -996,6 +1036,7 @@
 				ignore it 
 			*/
 			if (((c->Request.CDB[0] == CISS_REPORT_LOG) ||
+			     (c->Request.CDB[0] == CISS_REPORT_PHYS) ||
 			     (c->Request.CDB[0] == CISS_INQUIRY)) &&
 				((c->err_info->CommandStatus == 
 					CMD_DATA_OVERRUN) || 
@@ -1145,17 +1186,27 @@
 	{ /* an error has occurred */ 
 		switch(cmd->err_info->CommandStatus)
 		{
+			unsigned char sense_key;
 			case CMD_TARGET_STATUS:
-				printk(KERN_WARNING "cciss: cmd %p has "
-					" completed with errors\n", cmd);
-				if( cmd->err_info->ScsiStatus)
-                		{
-                    			printk(KERN_WARNING "cciss: cmd %p "
-					"has SCSI Status = %x\n",
-                        			cmd,  
-						cmd->err_info->ScsiStatus);
-                		}
-
+				status = 0;
+			
+				if( cmd->err_info->ScsiStatus == 0x02) {
+					printk(KERN_WARNING "cciss: cmd %p "
+						"has CHECK CONDITION,"
+						" sense key = 0x%x\n", cmd,
+						cmd->err_info->SenseInfo[2]);
+					/* check the sense key */
+					sense_key = 0xf & 
+						cmd->err_info->SenseInfo[2];
+					/* no status or recovered error */
+					if ((sense_key == 0x0) ||
+						(sense_key == 0x1))
+							status = 1;
+				} else {
+					printk(KERN_WARNING "cciss: cmd %p "
+						"has SCSI Status 0x%x\n",
+						cmd, cmd->err_info->ScsiStatus);
+				}
 			break;
 			case CMD_DATA_UNDERRUN:
 				printk(KERN_WARNING "cciss: cmd %p has"
@@ -1441,8 +1492,13 @@
 					complete_command(c, 0);
 					cmd_free(h, c, 1);
 				} else if (c->cmd_type == CMD_IOCTL_PEND) {
-					c->cmd_type = CMD_IOCTL_DONE;
+					complete(c->waiting);
+				}
+#				ifdef CONFIG_CISS_SCSI_TAPE
+				else if (c->cmd_type == CMD_SCSI) {
+					complete_scsi_command(c, 0, a1);
 				}
+#				endif
 				continue;
 			}
 		}
@@ -1493,6 +1549,15 @@
 }
 #endif /* CCISS_DEBUG */ 
 
+static void release_io_mem(ctlr_info_t *c)
+{
+	/* if IO mem was not protected do nothing */
+	if( c->io_mem_addr == 0)
+		return;
+	release_region(c->io_mem_addr, c->io_mem_length);
+	c->io_mem_addr = 0;
+	c->io_mem_length = 0;
+}
 static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 {
 	ushort vendor_id, device_id, command;
@@ -1533,6 +1598,36 @@
 	(void) pci_read_config_dword(pdev, PCI_SUBSYSTEM_VENDOR_ID, 
 						&board_id);
 
+	/* check to see if controller has been disabled */
+	if (!(command & 0x02)) {
+		printk(KERN_WARNING "cciss: controller appears to be disabled\n");
+		return(-1);
+	}
+	/* search for our IO range so we can protect it */
+	for (i=0; i<6; i++) {
+		/* is this an IO range */
+		if (pdev->resource[i].flags & 0x01) {
+			c->io_mem_addr = pdev->resource[i].start;
+			c->io_mem_length = pdev->resource[i].end -
+				pdev->resource[i].start +1; 
+#ifdef CCISS_DEBUG
+			printk("IO value found base_addr[%d] %lx %lx\n", i,
+				c->io_mem_addr, c->io_mem_length);
+#endif /* CCISS_DEBUG */
+			/* register the IO range */
+			if (!request_region( c->io_mem_addr,
+                                        c->io_mem_length, "cciss")) {
+				printk(KERN_WARNING 
+					"cciss I/O memory range already in "
+					"use addr=%lx length=%ld\n",
+				c->io_mem_addr, c->io_mem_length);
+				c->io_mem_addr= 0;
+				c->io_mem_length = 0;
+			}
+			break;
+		}
+	}
+
 #ifdef CCISS_DEBUG
 	printk("vendor_id = %x\n", vendor_id);
 	printk("device_id = %x\n", device_id);
@@ -1553,7 +1648,7 @@
          *   table
 	 */
 
-	c->paddr = addr[0] & 0xfffffff0; /* remove the addressing mode bits */
+	c->paddr = addr[0] ; /* addressing mode bits already removed */
 #ifdef CCISS_DEBUG
 	printk("address 0 = %x\n", c->paddr);
 #endif /* CCISS_DEBUG */ 
@@ -1650,7 +1745,7 @@
 	int return_code;
 	int i;
 	int listlength = 0;
-	int lunid = 0;
+	__u32 lunid = 0;
 	int block_size;
 	int total_size; 
 
@@ -1678,7 +1773,7 @@
         }
 	/* Get the firmware version */ 
 	return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, 
-		sizeof(InquiryData_struct), 0, 0 ,0 );
+		sizeof(InquiryData_struct), 0, 0 ,0, NULL);
 	if (return_code == IO_OK)
 	{
 		hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];
@@ -1692,7 +1787,7 @@
 	}
 	/* Get the number of logical volumes */ 
 	return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, 
-			sizeof(ReportLunData_struct), 0, 0, 0 );
+			sizeof(ReportLunData_struct), 0, 0, 0, NULL);
 
 	if( return_code == IO_OK)
 	{
@@ -1738,7 +1833,7 @@
 
 	  	memset(size_buff, 0, sizeof(ReadCapdata_struct));
 	  	return_code = sendcmd(CCISS_READ_CAPACITY, cntl_num, size_buff, 
-				sizeof( ReadCapdata_struct), 1, i, 0 );
+				sizeof( ReadCapdata_struct), 1, i, 0, NULL);
 	  	if (return_code == IO_OK)
 		{
 			total_size = (0xff & 
@@ -1770,7 +1865,7 @@
 		/* Execute the command to read the disk geometry */
 		memset(inq_buff, 0, sizeof(InquiryData_struct));
 		return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
-                	sizeof(InquiryData_struct), 1, i ,0xC1 );
+			sizeof(InquiryData_struct), 1, i, 0xC1, NULL );
 	  	if (return_code == IO_OK)
 		{
 			if(inq_buff->data_byte[8] == 0xFF)
@@ -1814,6 +1909,7 @@
 	}
 	kfree(ld_buff);
 	kfree(size_buff);
+	kfree(inq_buff);
 }	
 
 /* Function to find the first free pointer into our hba[] array */
@@ -1878,17 +1974,20 @@
 	{
 		printk(KERN_ERR "cciss:  Unable to get major number "
 			"%d for %s\n", MAJOR_NR+i, hba[i]->devname);
+		release_io_mem(hba[i]);
 		free_hba(i);
 		return(-1);
 	}
 	/* make sure the board interrupts are off */
 	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
 	if( request_irq(hba[i]->intr, do_cciss_intr, 
-		SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i]))
+		SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
+			hba[i]->devname, hba[i]))
 	{
 		printk(KERN_ERR "ciss: Unable to get irq %d for %s\n",
 			hba[i]->intr, hba[i]->devname);
 		unregister_blkdev( MAJOR_NR+i, hba[i]->devname);
+		release_io_mem(hba[i]);
 		free_hba(i);
 		return(-1);
 	}
@@ -1917,6 +2016,7 @@
 				hba[i]->errinfo_pool_dhandle);
                 free_irq(hba[i]->intr, hba[i]);
                 unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+		release_io_mem(hba[i]);
 		free_hba(i);
                 printk( KERN_ERR "cciss: out of memory");
 		return(-1);
@@ -1935,6 +2035,8 @@
 
 	cciss_getgeometry(i);
 
+	cciss_find_non_disk_devices(i);	/* find our tape drives, if any */
+
 	/* Turn the interrupts on so we can service requests */
 	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
 
@@ -1975,6 +2077,8 @@
 			MAX_PART, &cciss_fops, 
 			hba[i]->drv[j].nr_blocks);
 
+	cciss_register_scsi(i, 1);  /* hook ourself into SCSI subsystem */
+
 	return(1);
 }
 
@@ -1982,6 +2086,8 @@
 {
 	ctlr_info_t *tmp_ptr;
 	int i;
+	char flush_buf[4];
+	int return_code; 
 
 	if (pci_get_drvdata(pdev) == NULL)
 	{
@@ -1996,11 +2102,19 @@
 			"already be removed \n");
 		return;
 	}
-	/* Turn board interrupts off */
-	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
+ 	/* Turn board interrupts off  and send the flush cache command */
+ 	/* sendcmd will turn off interrupt, and send the flush...
+ 	 * To write all data in the battery backed cache to disks */
+ 	memset(flush_buf, 0, 4);
+ 	return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4,0,0,0, NULL);
+ 	if (return_code != IO_OK) {
+ 		printk(KERN_WARNING 
+			"Error Flushing cache on controller %d\n", i);
+ 	}
 	free_irq(hba[i]->intr, hba[i]);
 	pci_set_drvdata(pdev, NULL);
 	iounmap((void*)hba[i]->vaddr);
+	cciss_unregister_scsi(i);  /* unhook from SCSI subsystem */
 	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
 	remove_proc_entry(hba[i]->devname, proc_cciss);	
 	
@@ -2013,6 +2127,7 @@
 	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
 		hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
 	kfree(hba[i]->cmd_pool_bits);
+	release_io_mem(hba[i]);
 	free_hba(i);
 }	
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/cciss.h linux/drivers/block/cciss.h
--- linux.orig/drivers/block/cciss.h	2001-05-22 17:23:16.000000000 +0000
+++ linux/drivers/block/cciss.h	2002-07-20 01:08:21.000000000 +0000
@@ -51,6 +51,8 @@
 	__u32	board_id;
 	ulong   vaddr;
 	__u32	paddr;	
+	unsigned long io_mem_addr;
+	unsigned long io_mem_length;
 	CfgTable_struct *cfgtable;
 	int	intr;
 
@@ -88,6 +90,9 @@
 	int              sizes[256];
 	int              blocksizes[256];
 	int              hardsizes[256];
+#ifdef CONFIG_CISS_SCSI_TAPE
+	void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
+#endif
 };
 
 /*  Defining the diffent access_menthods */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/cciss_cmd.h linux/drivers/block/cciss_cmd.h
--- linux.orig/drivers/block/cciss_cmd.h	2001-11-03 01:45:42.000000000 +0000
+++ linux/drivers/block/cciss_cmd.h	2002-07-20 01:08:27.000000000 +0000
@@ -89,6 +89,7 @@
 //STRUCTURES
 //###########################################################################
 #define CISS_MAX_LUN	16	
+#define CISS_MAX_PHYS_LUN	1024
 // SCSI-3 Cmmands 
 
 #pragma pack(1)	
@@ -101,6 +102,7 @@
 } InquiryData_struct;
 
 #define CISS_REPORT_LOG 0xc2    /* Report Logical LUNs */
+#define CISS_REPORT_PHYS 0xc3   /* Report Physical LUNs */
 // Data returned
 typedef struct _ReportLUNdata_struct
 {
@@ -122,6 +124,12 @@
  #define CCISS_READ   0x28    // Read(10)
  #define CCISS_WRITE  0x2a    // Write(10)
 
+// BMIC commands 
+#define BMIC_READ 0x26
+#define BMIC_WRITE 0x27
+#define BMIC_CACHE_FLUSH 0xc2
+#define CCISS_CACHE_FLUSH 0x01	//C2 was already being used by CCISS
+
 //Command List Structure
 typedef union _SCSI3Addr_struct {
    struct {
@@ -214,7 +222,9 @@
 /* Command types */
 #define CMD_RWREQ       0x00
 #define CMD_IOCTL_PEND  0x01
-#define CMD_IOCTL_DONE  0x02
+#define CMD_SCSI	0x03
+#define CMD_MSG_DONE	0x04
+#define CMD_MSG_TIMEOUT 0x05
 
 typedef struct _CommandList_struct {
   CommandListHeader_struct Header;
@@ -229,6 +239,10 @@
   struct _CommandList_struct *prev;
   struct _CommandList_struct *next;
   struct request *	   rq;
+  struct completion *waiting;
+#ifdef CONFIG_CISS_SCSI_TAPE
+  void * scsi_cmd;
+#endif
 } CommandList_struct;
 
 //Configuration Table Structure
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/cciss_scsi.c linux/drivers/block/cciss_scsi.c
--- linux.orig/drivers/block/cciss_scsi.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/block/cciss_scsi.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,1602 @@
+/*
+ *    Disk Array driver for Compaq SA53xx Controllers, SCSI Tape module
+ *    Copyright 2001 Compaq Computer 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, GOOD TITLE or
+ *    NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *    Questions/Comments/Bugfixes to arrays@compaq.com
+ *
+ *    Author: Stephen M. Cameron
+ */
+#ifdef CONFIG_CISS_SCSI_TAPE
+
+/* Here we have code to present the driver as a scsi driver
+   as it is simultaneously presented as a block driver.  The
+   reason for doing this is to allow access to SCSI tape drives
+   through the array controller.  Note in particular, neither
+   physical nor logical disks are presented through the scsi layer. */
+
+#include "../scsi/scsi.h"
+#include "../scsi/hosts.h"
+#include <asm/atomic.h>
+#include <linux/timer.h>
+
+#include "cciss_scsi.h"
+
+/* some prototypes... */
+static int sendcmd(
+	__u8	cmd,
+	int	ctlr,
+	void	*buff,
+	size_t	size,
+	unsigned int use_unit_num, /* 0: address the controller,
+				      1: address logical volume log_unit,
+				      2: address is in scsi3addr */
+	unsigned int log_unit,
+	__u8	page_code,
+	unsigned char *scsi3addr );
+
+
+int __init cciss_scsi_detect(Scsi_Host_Template *tpnt);
+int cciss_scsi_release(struct Scsi_Host *sh);
+const char *cciss_scsi_info(struct Scsi_Host *sa);
+
+int cciss_scsi_proc_info(
+		char *buffer, /* data buffer */
+		char **start, 	   /* where data in buffer starts */
+		off_t offset,	   /* offset from start of imaginary file */
+		int length, 	   /* length of data in buffer */
+		int hostnum, 	   /* which host adapter (always zero for me) */
+		int func);	   /* 0 == read, 1 == write */
+
+int cciss_scsi_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *));
+#if 0
+int cciss_scsi_abort(Scsi_Cmnd *cmd);
+#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
+int cciss_scsi_reset(Scsi_Cmnd *cmd, unsigned int reset_flags);
+#else
+int cciss_scsi_reset(Scsi_Cmnd *cmd);
+#endif
+#endif
+
+static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
+	{ name: "cciss0", ndevices: 0 },
+	{ name: "cciss1", ndevices: 0 },
+	{ name: "cciss2", ndevices: 0 },
+	{ name: "cciss3", ndevices: 0 },
+	{ name: "cciss4", ndevices: 0 },
+	{ name: "cciss5", ndevices: 0 },
+	{ name: "cciss6", ndevices: 0 },
+	{ name: "cciss7", ndevices: 0 },
+};
+
+/* We need one Scsi_Host_Template *per controller* instead of
+   the usual one Scsi_Host_Template per controller *type*. This
+   is so PCI hot plug could have a remote possibility of still
+   working even with the SCSI system.  It's so
+   scsi_unregister_module will differentiate the controllers.
+   When register_scsi_module is called, each host template is
+   customized (name change) in cciss_register_scsi()
+   (that's called from cciss.c:cciss_init_one()) */
+
+static
+Scsi_Host_Template driver_template[MAX_CTLR] =
+{
+	CCISS_SCSI, CCISS_SCSI, CCISS_SCSI, CCISS_SCSI,
+	CCISS_SCSI, CCISS_SCSI, CCISS_SCSI, CCISS_SCSI,
+};
+
+#pragma pack(1)
+struct cciss_scsi_cmd_stack_elem_t {
+	CommandList_struct cmd;
+	ErrorInfo_struct Err;
+	__u32 busaddr; // 32 bits always, must fit through cmd register.
+};
+
+#pragma pack()
+
+#define CMD_STACK_SIZE (SCSI_CCISS_CAN_QUEUE * \
+		CCISS_MAX_SCSI_DEVS_PER_HBA + 2)
+			// plus two for init time usage
+
+#pragma pack(1)
+struct cciss_scsi_cmd_stack_t {
+	struct cciss_scsi_cmd_stack_elem_t *pool;
+	struct cciss_scsi_cmd_stack_elem_t *elem[CMD_STACK_SIZE];
+	dma_addr_t cmd_pool_handle;
+	int top;
+};
+#pragma pack()
+
+struct cciss_scsi_adapter_data_t {
+	struct Scsi_Host *scsi_host;
+	struct cciss_scsi_cmd_stack_t cmd_stack;
+	int registered;
+	spinlock_t lock; // to protect ccissscsi[ctlr];
+};
+#if 1
+#define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \
+	&(((struct cciss_scsi_adapter_data_t *) \
+	hba[ctlr]->scsi_ctlr)->lock), flags);
+#define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \
+	&(((struct cciss_scsi_adapter_data_t *) \
+	hba[ctlr]->scsi_ctlr)->lock), flags);
+#else
+#define CPQ_TAPE_LOCK(x,y)
+#define CPQ_TAPE_UNLOCK(x,y)
+#endif
+
+static CommandList_struct *
+scsi_cmd_alloc(ctlr_info_t *h)
+{
+	/* assume only one process in here at a time, locking done by caller. */
+
+	/* take the top memory chunk off the stack and return it, if any. */
+	struct cciss_scsi_cmd_stack_elem_t *c;
+	struct cciss_scsi_adapter_data_t *sa;
+	struct cciss_scsi_cmd_stack_t *stk;
+	u64bit temp64;
+
+	sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
+	stk = &sa->cmd_stack;
+
+	if (stk->top < 0)
+		return NULL;
+	c = stk->elem[stk->top];
+	memset(&c->cmd, 0, sizeof(c->cmd));
+	memset(&c->Err, 0, sizeof(c->Err));
+	/* set physical addr of cmd and addr of scsi parameters */
+	c->cmd.busaddr = c->busaddr;
+
+	temp64.val = (__u64) (c->busaddr + sizeof(CommandList_struct));
+	stk->top--;
+	c->cmd.ErrDesc.Addr.lower = temp64.val32.lower;
+	c->cmd.ErrDesc.Addr.upper = temp64.val32.upper;
+	c->cmd.ErrDesc.Len = sizeof(ErrorInfo_struct);
+
+	c->cmd.ctlr = h->ctlr;
+	c->cmd.err_info = &c->Err;
+
+	return (CommandList_struct *) c;
+}
+
+static void
+scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd)
+{
+	/* assume only one process in here at a time, locking done by caller. */
+	/* drop the free memory chunk on top of the stack. */
+
+	struct cciss_scsi_adapter_data_t *sa;
+	struct cciss_scsi_cmd_stack_t *stk;
+
+	sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
+	stk = &sa->cmd_stack;
+	if (stk->top >= CMD_STACK_SIZE) {
+		printk("cciss: scsi_cmd_free called too many times.\n");
+		BUG();
+	}
+	stk->top++;
+	stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd;
+}
+
+static int
+scsi_cmd_stack_setup(int ctlr)
+{
+	int i;
+	struct cciss_scsi_adapter_data_t *sa;
+	struct cciss_scsi_cmd_stack_t *stk;
+	size_t size;
+
+	sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
+	stk = &sa->cmd_stack;
+	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
+
+	stk->pool = (struct cciss_scsi_cmd_stack_elem_t *)
+		pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);
+
+	if (stk->pool == NULL) {
+		printk("stk->pool is null\n");
+		return -1;
+	}
+
+	for (i=0; i<CMD_STACK_SIZE; i++) {
+		stk->elem[i] = &stk->pool[i];
+		stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle +
+			(sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
+	}
+	stk->top = CMD_STACK_SIZE-1;
+	return 0;
+}
+
+static void
+scsi_cmd_stack_free(int ctlr)
+{
+	struct cciss_scsi_adapter_data_t *sa;
+	struct cciss_scsi_cmd_stack_t *stk;
+	size_t size;
+
+	sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
+	stk = &sa->cmd_stack;
+	if (stk->top != CMD_STACK_SIZE-1) {
+		printk( "cciss: %d scsi commands are still outstanding.\n",
+			CMD_STACK_SIZE - stk->top);
+		// BUG();
+		printk("WE HAVE A BUG HERE!!! stk=0x%08x\n",
+			(unsigned int) stk);
+	}
+	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
+
+	pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
+	stk->pool = NULL;
+}
+
+/* scsi_device_types comes from scsi.h */
+#define DEVICETYPE(n) (n<0 || n>MAX_SCSI_DEVICE_CODE) ? \
+	"Unknown" : scsi_device_types[n]
+
+#if 0
+static int xmargin=8;
+static int amargin=60;
+
+static void
+print_bytes (unsigned char *c, int len, int hex, int ascii)
+{
+
+	int i;
+	unsigned char *x;
+
+	if (hex)
+	{
+		x = c;
+		for (i=0;i<len;i++)
+		{
+			if ((i % xmargin) == 0 && i>0) printk("\n");
+			if ((i % xmargin) == 0) printk("0x%04x:", i);
+			printk(" %02x", *x);
+			x++;
+		}
+		printk("\n");
+	}
+	if (ascii)
+	{
+		x = c;
+		for (i=0;i<len;i++)
+		{
+			if ((i % amargin) == 0 && i>0) printk("\n");
+			if ((i % amargin) == 0) printk("0x%04x:", i);
+			if (*x > 26 && *x < 128) printk("%c", *x);
+			else printk(".");
+			x++;
+		}
+		printk("\n");
+	}
+}
+
+static void
+print_cmd(CommandList_struct *cp)
+{
+	printk("queue:%d\n", cp->Header.ReplyQueue);
+	printk("sglist:%d\n", cp->Header.SGList);
+	printk("sgtot:%d\n", cp->Header.SGTotal);
+	printk("Tag:0x%08x/0x%08x\n", cp->Header.Tag.upper,
+			cp->Header.Tag.lower);
+	printk("LUN:0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+		cp->Header.LUN.LunAddrBytes[0],
+		cp->Header.LUN.LunAddrBytes[1],
+		cp->Header.LUN.LunAddrBytes[2],
+		cp->Header.LUN.LunAddrBytes[3],
+		cp->Header.LUN.LunAddrBytes[4],
+		cp->Header.LUN.LunAddrBytes[5],
+		cp->Header.LUN.LunAddrBytes[6],
+		cp->Header.LUN.LunAddrBytes[7]);
+	printk("CDBLen:%d\n", cp->Request.CDBLen);
+	printk("Type:%d\n",cp->Request.Type.Type);
+	printk("Attr:%d\n",cp->Request.Type.Attribute);
+	printk(" Dir:%d\n",cp->Request.Type.Direction);
+	printk("Timeout:%d\n",cp->Request.Timeout);
+	printk( "CDB: %02x %02x %02x %02x %02x %02x %02x %02x"
+		" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+		cp->Request.CDB[0], cp->Request.CDB[1],
+		cp->Request.CDB[2], cp->Request.CDB[3],
+		cp->Request.CDB[4], cp->Request.CDB[5],
+		cp->Request.CDB[6], cp->Request.CDB[7],
+		cp->Request.CDB[8], cp->Request.CDB[9],
+		cp->Request.CDB[10], cp->Request.CDB[11],
+		cp->Request.CDB[12], cp->Request.CDB[13],
+		cp->Request.CDB[14], cp->Request.CDB[15]),
+	printk("edesc.Addr: 0x%08x/0%08x, Len  = %d\n",
+		cp->ErrDesc.Addr.upper, cp->ErrDesc.Addr.lower,
+			cp->ErrDesc.Len);
+	printk("sgs..........Errorinfo:\n");
+	printk("scsistatus:%d\n", cp->err_info->ScsiStatus);
+	printk("senselen:%d\n", cp->err_info->SenseLen);
+	printk("cmd status:%d\n", cp->err_info->CommandStatus);
+	printk("resid cnt:%d\n", cp->err_info->ResidualCnt);
+	printk("offense size:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_size);
+	printk("offense byte:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_num);
+	printk("offense value:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
+
+}
+
+#endif
+
+static int
+find_bus_target_lun(int ctlr, int *bus, int *target, int *lun)
+{
+	/* finds an unused bus, target, lun for a new device */
+	/* assumes hba[ctlr]->scsi_ctlr->lock is held */
+	int i, found=0;
+	unsigned char target_taken[CCISS_MAX_SCSI_DEVS_PER_HBA];
+
+	memset(&target_taken[0], 0, CCISS_MAX_SCSI_DEVS_PER_HBA);
+
+#	if SELF_SCSI_ID >= 0
+		target_taken[SELF_SCSI_ID] = 1;
+#	endif
+	for (i=0;i<ccissscsi[ctlr].ndevices;i++)
+		target_taken[ccissscsi[ctlr].dev[i].target] = 1;
+
+	for (i=0;i<CCISS_MAX_SCSI_DEVS_PER_HBA;i++) {
+		if (!target_taken[i]) {
+			*bus = 0; *target=i; *lun = 0; found=1;
+			break;
+		}
+	}
+	return (!found);
+}
+
+static int
+cciss_scsi_add_entry(int ctlr, int hostno,
+		unsigned char *scsi3addr, int devtype)
+{
+	/* assumes hba[ctlr]->scsi_ctlr->lock is held */
+	int n = ccissscsi[ctlr].ndevices;
+	struct cciss_scsi_dev_t *sd;
+
+	if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
+		printk("cciss%d: Too many devices, "
+			"some will be inaccessible.\n", ctlr);
+		return -1;
+	}
+	sd = &ccissscsi[ctlr].dev[n];
+	if (find_bus_target_lun(ctlr, &sd->bus, &sd->target, &sd->lun) != 0)
+		return -1;
+	memcpy(&sd->scsi3addr[0], scsi3addr, 8);
+	sd->devtype = devtype;
+	ccissscsi[ctlr].ndevices++;
+
+	/* initially, (before registering with scsi layer) we don't
+	   know our hostno and we don't want to print anything first
+	   time anyway (the scsi layer's inquiries will show that info) */
+	if (hostno != -1)
+		printk("cciss%d: %s device c%db%dt%dl%d added.\n",
+			ctlr, DEVICETYPE(sd->devtype), hostno,
+			sd->bus, sd->target, sd->lun);
+	return 0;
+}
+
+static void
+cciss_scsi_remove_entry(int ctlr, int hostno, int entry)
+{
+	/* assumes hba[ctlr]->scsi_ctlr->lock is held */
+	int i;
+	struct cciss_scsi_dev_t sd;
+
+	if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return;
+	sd = ccissscsi[ctlr].dev[entry];
+	for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++)
+		ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1];
+	ccissscsi[ctlr].ndevices--;
+	printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
+		ctlr, DEVICETYPE(sd.devtype), hostno,
+			sd.bus, sd.target, sd.lun);
+}
+
+
+#define SCSI3ADDR_EQ(a,b) ( \
+	(a)[7] == (b)[7] && \
+	(a)[6] == (b)[6] && \
+	(a)[5] == (b)[5] && \
+	(a)[4] == (b)[4] && \
+	(a)[3] == (b)[3] && \
+	(a)[2] == (b)[2] && \
+	(a)[1] == (b)[1] && \
+	(a)[0] == (b)[0])
+
+static int
+adjust_cciss_scsi_table(int ctlr, int hostno,
+	struct cciss_scsi_dev_t sd[], int nsds)
+{
+	/* sd contains scsi3 addresses and devtypes, but
+	   bus target and lun are not filled in.  This funciton
+	   takes what's in sd to be the current and adjusts
+	   ccissscsi[] to be in line with what's in sd. */
+
+	int i,j, found, changes=0;
+	struct cciss_scsi_dev_t *csd;
+	unsigned long flags;
+
+	CPQ_TAPE_LOCK(ctlr, flags);
+
+	/* find any devices in ccissscsi[] that are not in
+	   sd[] and remove them from ccissscsi[] */
+
+	i = 0;
+	while(i<ccissscsi[ctlr].ndevices) {
+		csd = &ccissscsi[ctlr].dev[i];
+		found=0;
+		for (j=0;j<nsds;j++) {
+			if (SCSI3ADDR_EQ(sd[j].scsi3addr,
+				csd->scsi3addr)) {
+				if (sd[j].devtype == csd->devtype)
+					found=2;
+				else
+					found=1;
+				break;
+			}
+		}
+
+		if (found == 0) { /* device no longer present. */
+			changes++;
+			/* printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
+				ctlr, DEVICETYPE(csd->devtype), hostno,
+					csd->bus, csd->target, csd->lun); */
+			cciss_scsi_remove_entry(ctlr, hostno, i);
+			/* note, i not incremented */
+		}
+		else if (found == 1) { /* device is different kind */
+			changes++;
+			printk("cciss%d: device c%db%dt%dl%d type changed "
+				"(device type now %s).\n",
+				ctlr, hostno, csd->bus, csd->target, csd->lun,
+					DEVICETYPE(csd->devtype));
+			csd->devtype = sd[j].devtype;
+			i++;	/* so just move along. */
+		} else 		/* device is same as it ever was, */
+			i++;	/* so just move along. */
+	}
+
+	/* Now, make sure every device listed in sd[] is also
+ 	   listed in ccissscsi[], adding them if they aren't found */
+
+	for (i=0;i<nsds;i++) {
+		found=0;
+		for (j=0;j<ccissscsi[ctlr].ndevices;j++) {
+			csd = &ccissscsi[ctlr].dev[j];
+			if (SCSI3ADDR_EQ(sd[i].scsi3addr,
+				csd->scsi3addr)) {
+				if (sd[i].devtype == csd->devtype)
+					found=2;	/* found device */
+				else
+					found=1; 	/* found a bug. */
+				break;
+			}
+		}
+		if (!found) {
+			changes++;
+			if (cciss_scsi_add_entry(ctlr, hostno,
+				&sd[i].scsi3addr[0], sd[i].devtype) != 0)
+				break;
+		} else if (found == 1) {
+			/* should never happen... */
+			changes++;
+			printk("cciss%d: device unexpectedly changed type\n",
+				ctlr);
+			/* but if it does happen, we just ignore that device */
+		}
+	}
+	CPQ_TAPE_UNLOCK(ctlr, flags);
+
+	if (!changes)
+		printk("cciss%d: No device changes detected.\n", ctlr);
+
+	return 0;
+}
+
+static int
+lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr)
+{
+	int i;
+	struct cciss_scsi_dev_t *sd;
+	unsigned long flags;
+
+	CPQ_TAPE_LOCK(ctlr, flags);
+	for (i=0;i<ccissscsi[ctlr].ndevices;i++) {
+		sd = &ccissscsi[ctlr].dev[i];
+		if (sd->bus == bus &&
+		    sd->target == target &&
+		    sd->lun == lun) {
+			memcpy(scsi3addr, &sd->scsi3addr[0], 8);
+			CPQ_TAPE_UNLOCK(ctlr, flags);
+			return 0;
+		}
+	}
+	CPQ_TAPE_UNLOCK(ctlr, flags);
+	return -1;
+}
+
+
+static void
+cciss_find_non_disk_devices(int cntl_num)
+{
+	ReportLunData_struct *ld_buff;
+	InquiryData_struct *inq_buff;
+	int return_code;
+	int i;
+	int listlength = 0;
+	int num_luns;
+	unsigned char scsi3addr[8];
+	unsigned long flags;
+	int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
+
+	hba[cntl_num]->scsi_ctlr = (void *)
+		kmalloc(sizeof(struct cciss_scsi_adapter_data_t),
+			GFP_KERNEL);
+	if (hba[cntl_num]->scsi_ctlr == NULL)
+		return;
+
+	((struct cciss_scsi_adapter_data_t *)
+		hba[cntl_num]->scsi_ctlr)->scsi_host = NULL;
+	((struct cciss_scsi_adapter_data_t *)
+		hba[cntl_num]->scsi_ctlr)->lock = SPIN_LOCK_UNLOCKED;
+	((struct cciss_scsi_adapter_data_t *)
+		hba[cntl_num]->scsi_ctlr)->registered = 0;
+
+	if (scsi_cmd_stack_setup(cntl_num) != 0) {
+		printk("Trouble, returned non-zero!\n");
+		return;
+	}
+
+	ld_buff = kmalloc(reportlunsize, GFP_KERNEL);
+	if (ld_buff == NULL) {
+		printk(KERN_ERR "cciss: out of memory\n");
+		return;
+	}
+	memset(ld_buff, 0, sizeof(ReportLunData_struct));
+	inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
+	if (inq_buff == NULL) {
+		printk(KERN_ERR "cciss: out of memory\n");
+		kfree(ld_buff);
+		return;
+	}
+
+	/* Get the physical luns */
+	return_code = sendcmd(CISS_REPORT_PHYS, cntl_num, ld_buff,
+			reportlunsize, 0, 0, 0, NULL );
+
+	if( return_code == IO_OK) {
+		unsigned char *c = &ld_buff->LUNListLength[0];
+		listlength = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
+	}
+	else {  /* getting report of physical luns failed */
+		printk(KERN_WARNING "cciss: report physical luns"
+			" command failed\n");
+		listlength = 0;
+	}
+
+	CPQ_TAPE_LOCK(cntl_num, flags);
+	ccissscsi[cntl_num].ndevices = 0;
+	num_luns = listlength / 8; // 8 bytes pre entry
+	/* printk("Found %d LUNs\n", num_luns); */
+
+	if (num_luns > CISS_MAX_PHYS_LUN)
+	{
+		printk(KERN_WARNING
+			"cciss: Maximum physical LUNs (%d) exceeded.  "
+			"%d LUNs ignored.\n", CISS_MAX_PHYS_LUN,
+			num_luns - CISS_MAX_PHYS_LUN);
+		num_luns = CISS_MAX_PHYS_LUN;
+	}
+
+	for(i=0; i<num_luns; i++) {
+		/* Execute an inquiry to figure the device type */
+		memset(inq_buff, 0, sizeof(InquiryData_struct));
+		memcpy(scsi3addr, ld_buff->LUN[i], 8); /* ugly... */
+		return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
+			sizeof(InquiryData_struct), 2, 0 ,0, scsi3addr );
+	  	if (return_code == IO_OK) {
+			if(inq_buff->data_byte[8] == 0xFF)
+			{
+			   printk(KERN_WARNING "cciss: inquiry failed\n");
+			} else {
+			   int devtype;
+
+			   /* printk("Inquiry...\n");
+			   print_bytes((unsigned char *) inq_buff, 36, 1, 1); */
+			   devtype = (inq_buff->data_byte[0] & 0x1f);
+
+			   switch (devtype)
+			   {
+			    case 0x01: /* sequential access, (tape) */
+			    case 0x08: /* medium changer */
+					  /* this is the only kind of dev */
+					  /* we want to expose here. */
+				if (cciss_scsi_add_entry(cntl_num, -1,
+					(unsigned char *) ld_buff->LUN[i],
+					devtype) != 0)
+						i=num_luns; // leave loop
+				break;
+			    default:
+				break;
+			   }
+
+			}
+		}
+		else printk("cciss: inquiry failed.\n");
+	}
+#if 0
+	for (i=0;i<ccissscsi[cntl_num].ndevices;i++)
+		printk("Tape device presented at c%db%dt%dl%d\n",
+			cntl_num, // <-- this is wrong
+			ccissscsi[cntl_num].dev[i].bus,
+			ccissscsi[cntl_num].dev[i].target,
+			ccissscsi[cntl_num].dev[i].lun);
+#endif
+	CPQ_TAPE_UNLOCK(cntl_num, flags);
+	kfree(ld_buff);
+	kfree(inq_buff);
+	return;
+}
+
+static void
+complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
+{
+	Scsi_Cmnd *cmd;
+	ctlr_info_t *ctlr;
+	u64bit addr64;
+	ErrorInfo_struct *ei;
+
+	ei = cp->err_info;
+
+	/* First, see if it was a message rather than a command */
+	if (cp->Request.Type.Type == TYPE_MSG)  {
+		cp->cmd_type = CMD_MSG_DONE;
+		return;
+	}
+
+	/* we stored ptr to scsi cmd in the buffer head pointer */
+	cmd = (Scsi_Cmnd *) cp->scsi_cmd;
+	ctlr = hba[cp->ctlr];
+
+	/* undo the DMA mappings */
+
+	if (cmd->use_sg) {
+		pci_unmap_sg(ctlr->pdev,
+			cmd->buffer, cmd->use_sg,
+				scsi_to_pci_dma_dir(cmd->sc_data_direction));
+	}
+	else if (cmd->request_bufflen) {
+		addr64.val32.lower = cp->SG[0].Addr.lower;
+		addr64.val32.upper = cp->SG[0].Addr.upper;
+		pci_unmap_single(ctlr->pdev, (dma_addr_t) addr64.val,
+			cmd->request_bufflen,
+				scsi_to_pci_dma_dir(cmd->sc_data_direction));
+	}
+
+	cmd->result = (DID_OK << 16); 		/* host byte */
+	cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
+	/* cmd->result |= (GOOD < 1); */		/* status byte */
+
+	cmd->result |= (ei->ScsiStatus);
+	/* printk("Scsistatus is 0x%02x\n", ei->ScsiStatus);  */
+
+	/* copy the sense data whether we need to or not. */
+
+	memcpy(cmd->sense_buffer, ei->SenseInfo,
+		ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
+			SCSI_SENSE_BUFFERSIZE :
+			ei->SenseLen);
+	cmd->resid = ei->ResidualCnt;
+
+	if(ei->CommandStatus != 0)
+	{ /* an error has occurred */
+		switch(ei->CommandStatus)
+		{
+			case CMD_TARGET_STATUS:
+				/* Pass it up to the upper layers... */
+				if( ei->ScsiStatus)
+					cmd->result |= (ei->ScsiStatus < 1);
+				else {  /* scsi status is zero??? How??? */
+
+	/* Ordinarily, this case should never happen, but there is a bug
+	   in some released firmware revisions that allows it to happen
+	   if, for example, a 4100 backplane loses power and the tape
+	   drive is in it.  We assume that it's a fatal error of some
+	   kind because we can't show that it wasn't. We will make it
+	   look like selection timeout since that is the most common
+	   reason for this to occur, and it's severe enough. */
+
+					cmd->result = DID_NO_CONNECT << 16;
+				}
+			break;
+			case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
+			break;
+			case CMD_DATA_OVERRUN:
+				printk(KERN_WARNING "cciss: cp %p has"
+					" completed with data overrun "
+					"reported\n", cp);
+			break;
+			case CMD_INVALID: {
+				/* print_bytes(cp, sizeof(*cp), 1, 0);
+				print_cmd(cp); */
+     /* We get CMD_INVALID if you address a non-existent tape drive instead
+	of a selection timeout (no response).  You will see this if you yank
+	out a tape drive, then try to access it. This is kind of a shame
+	because it means that any other CMD_INVALID (e.g. driver bug) will
+	get interpreted as a missing target. */
+				cmd->result = DID_NO_CONNECT << 16;
+				}
+			break;
+			case CMD_PROTOCOL_ERR:
+				printk(KERN_WARNING "cciss: cp %p has "
+					"protocol error \n", cp);
+			break;
+			case CMD_HARDWARE_ERR:
+				cmd->result = DID_ERROR << 16;
+				printk(KERN_WARNING "cciss: cp %p had "
+					" hardware error\n", cp);
+			break;
+			case CMD_CONNECTION_LOST:
+				cmd->result = DID_ERROR << 16;
+				printk(KERN_WARNING "cciss: cp %p had "
+					"connection lost\n", cp);
+			break;
+			case CMD_ABORTED:
+				cmd->result = DID_ABORT << 16;
+				printk(KERN_WARNING "cciss: cp %p was "
+					"aborted\n", cp);
+			break;
+			case CMD_ABORT_FAILED:
+				cmd->result = DID_ERROR << 16;
+				printk(KERN_WARNING "cciss: cp %p reports "
+					"abort failed\n", cp);
+			break;
+			case CMD_UNSOLICITED_ABORT:
+				cmd->result = DID_ABORT << 16;
+				printk(KERN_WARNING "cciss: cp %p aborted "
+					"do to an unsolicited abort\n", cp);
+			break;
+			case CMD_TIMEOUT:
+				cmd->result = DID_TIME_OUT << 16;
+				printk(KERN_WARNING "cciss: cp %p timedout\n",
+					cp);
+			break;
+			default:
+				cmd->result = DID_ERROR << 16;
+				printk(KERN_WARNING "cciss: cp %p returned "
+					"unknown status %x\n", cp,
+						ei->CommandStatus);
+		}
+	}
+	cmd->scsi_done(cmd);
+	scsi_cmd_free(ctlr, cp);
+}
+
+/* cciss_scsi_detect is called from the scsi mid layer.
+   The scsi mid layer (scsi_register_module) is
+   called from cciss.c:cciss_init_one().  */
+
+int __init
+cciss_scsi_detect(Scsi_Host_Template *tpnt)
+{
+	int i;
+	struct Scsi_Host *sh;
+
+	/* Tell the kernel we want to be a SCSI driver... */
+	sh = scsi_register(tpnt, sizeof(struct ctlr_info *));
+	if (sh == NULL) return 0;
+
+	sh->io_port = 0;	// good enough?  FIXME,
+	sh->n_io_port = 0;	// I don't think we use these two...
+
+	sh->this_id = SELF_SCSI_ID;
+
+	/* This is a bit kludgey, using the adapter name to figure out */
+	/* which scsi host template we've got, won't scale beyond 9 ctlrs. */
+	i = tpnt->name[5] - '0';
+
+#	if MAX_CTLR > 9
+#		error "cciss_scsi.c: MAX_CTLR > 9, code maintenance needed."
+#	endif
+
+	if (i<0 || i>=MAX_CTLR || hba[i] == NULL) {
+		/* we didn't find ourself... we shouldn't get here. */
+		printk("cciss_scsi_detect: could not find ourself in hba[]\n");
+		return 0;
+	}
+
+	((struct cciss_scsi_adapter_data_t *)
+		hba[i]->scsi_ctlr)->scsi_host = (void *) sh;
+	sh->hostdata[0] = (unsigned long) hba[i];
+	sh->irq = hba[i]->intr;
+	sh->unique_id = sh->irq;
+	scsi_set_pci_device(sh, hba[i]->pdev);
+
+	return 1;	/* Say we have 1 scsi adapter, this will be */
+			/* called multiple times, once for each adapter */
+			/* from cciss.c:cciss_init_one().  We do it this */
+			/* way for PCI-hot plug reasons. (we don't know how */
+			/* many adapters we have total, so we say we have */
+			/* 1, each of a unique type.) */
+}
+
+static void __exit cleanup_cciss_module(void);
+int
+cciss_scsi_release(struct Scsi_Host *sh)
+{
+	return 0;
+}
+
+static void
+cciss_unmap_one(struct pci_dev *pdev,
+		CommandList_struct *cp,
+		size_t buflen,
+		int data_direction)
+{
+	u64bit addr64;
+
+	addr64.val32.lower = cp->SG[0].Addr.lower;
+	addr64.val32.upper = cp->SG[0].Addr.upper;
+	pci_unmap_single(pdev, (dma_addr_t) addr64.val, buflen, data_direction);
+}
+
+static void
+cciss_map_one(struct pci_dev *pdev,
+		CommandList_struct *cp,
+		unsigned char *buf,
+		size_t buflen,
+		int data_direction)
+{
+	__u64 addr64;
+
+	addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction);
+	cp->SG[0].Addr.lower =
+	  (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
+	cp->SG[0].Addr.upper =
+	  (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
+	cp->SG[0].Len = buflen;
+	cp->Header.SGList = (__u8) 1;   /* no. SGs contig in this cmd */
+	cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */
+}
+
+static int
+cciss_scsi_do_simple_cmd(ctlr_info_t *c,
+			CommandList_struct *cp,
+			unsigned char *scsi3addr,
+			unsigned char *cdb,
+			unsigned char cdblen,
+			unsigned char *buf, int bufsize,
+			int direction)
+{
+	unsigned long flags;
+	DECLARE_COMPLETION(wait);
+
+	cp->cmd_type = CMD_IOCTL_PEND;		// treat this like an ioctl
+	cp->scsi_cmd = NULL;
+	cp->Header.ReplyQueue = 0;  // unused in simple mode
+	memcpy(&cp->Header.LUN, scsi3addr, sizeof(cp->Header.LUN));
+	cp->Header.Tag.lower = cp->busaddr;  // Use k. address of cmd as tag
+	// Fill in the request block...
+
+	/* printk("Using scsi3addr 0x%02x%0x2%0x2%0x2%0x2%0x2%0x2%0x2\n",
+		scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3],
+		scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]); */
+
+	memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
+	memcpy(cp->Request.CDB, cdb, cdblen);
+	cp->Request.Timeout = 1000;		// guarantee completion.
+	cp->Request.CDBLen = cdblen;
+	cp->Request.Type.Type = TYPE_CMD;
+	cp->Request.Type.Attribute = ATTR_SIMPLE;
+	cp->Request.Type.Direction = direction;
+
+	/* Fill in the SG list and do dma mapping */
+	cciss_map_one(c->pdev, cp,
+			(unsigned char *) buf, bufsize,
+			scsi_to_pci_dma_dir(SCSI_DATA_READ));
+
+	cp->waiting = &wait;
+
+	/* Put the request on the tail of the request queue */
+	spin_lock_irqsave(&io_request_lock, flags);
+	addQ(&c->reqQ, cp);
+	c->Qdepth++;
+	start_io(c);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+
+	wait_for_completion(&wait);
+
+	/* undo the dma mapping */
+	cciss_unmap_one(c->pdev, cp, bufsize,
+				scsi_to_pci_dma_dir(SCSI_DATA_READ));
+
+	return(0);
+}
+
+static void
+cciss_scsi_interpret_error(CommandList_struct *cp)
+{
+	ErrorInfo_struct *ei;
+
+	ei = cp->err_info;
+	switch(ei->CommandStatus)
+	{
+		case CMD_TARGET_STATUS:
+			printk(KERN_WARNING "cciss: cmd %p has "
+				"completed with errors\n", cp);
+			printk(KERN_WARNING "cciss: cmd %p "
+				"has SCSI Status = %x\n",
+					cp,
+					ei->ScsiStatus);
+			if (ei->ScsiStatus == 0)
+				printk(KERN_WARNING
+				"cciss:SCSI status is abnormally zero.  "
+				"(probably indicates selection timeout "
+				"reported incorrectly due to a known "
+				"firmware bug, circa July, 2001.)\n");
+		break;
+		case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
+			printk("UNDERRUN\n");
+		break;
+		case CMD_DATA_OVERRUN:
+			printk(KERN_WARNING "cciss: cp %p has"
+				" completed with data overrun "
+				"reported\n", cp);
+		break;
+		case CMD_INVALID: {
+			/* controller unfortunately reports SCSI passthru's */
+			/* to non-existent targets as invalid commands. */
+			printk(KERN_WARNING "cciss: cp %p is "
+				"reported invalid (probably means "						"target device no longer present)\n",
+				cp);
+			/* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0);
+			print_cmd(cp);  */
+			}
+		break;
+		case CMD_PROTOCOL_ERR:
+			printk(KERN_WARNING "cciss: cp %p has "
+				"protocol error \n", cp);
+		break;
+		case CMD_HARDWARE_ERR:
+			/* cmd->result = DID_ERROR << 16; */
+			printk(KERN_WARNING "cciss: cp %p had "
+				" hardware error\n", cp);
+		break;
+		case CMD_CONNECTION_LOST:
+			printk(KERN_WARNING "cciss: cp %p had "
+				"connection lost\n", cp);
+		break;
+		case CMD_ABORTED:
+			printk(KERN_WARNING "cciss: cp %p was "
+				"aborted\n", cp);
+		break;
+		case CMD_ABORT_FAILED:
+			printk(KERN_WARNING "cciss: cp %p reports "
+				"abort failed\n", cp);
+		break;
+		case CMD_UNSOLICITED_ABORT:
+			printk(KERN_WARNING "cciss: cp %p aborted "
+				"do to an unsolicited abort\n", cp);
+		break;
+		case CMD_TIMEOUT:
+			printk(KERN_WARNING "cciss: cp %p timedout\n",
+				cp);
+		break;
+		default:
+			printk(KERN_WARNING "cciss: cp %p returned "
+				"unknown status %x\n", cp,
+					ei->CommandStatus);
+	}
+}
+
+static int
+cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
+		 InquiryData_struct *buf)
+{
+	int rc;
+	CommandList_struct *cp;
+	char cdb[6];
+	ErrorInfo_struct *ei;
+
+	cp = scsi_cmd_alloc(c);
+	ei = cp->err_info;
+
+	if (cp == NULL) {			/* trouble... */
+		printk("cmd_alloc returned NULL!\n");
+		return -1;
+	}
+
+	cdb[0] = CISS_INQUIRY;
+	cdb[1] = 0;
+	cdb[2] = 0;
+	cdb[3] = 0;
+	cdb[4] = sizeof(*buf) & 0xff;
+	cdb[5] = 0;
+	rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb,
+				6, (unsigned char *) buf,
+				sizeof(*buf), XFER_READ);
+
+	if (rc != 0) return rc; /* something went wrong */
+
+	if (ei->CommandStatus != 0 &&
+	    ei->CommandStatus != CMD_DATA_UNDERRUN) {
+		cciss_scsi_interpret_error(cp);
+		scsi_cmd_free(c, cp);
+		return -1;
+	}
+	scsi_cmd_free(c, cp);
+	return 0;
+}
+
+static int
+cciss_scsi_do_report_phys_luns(ctlr_info_t *c,
+		ReportLunData_struct *buf, int bufsize)
+{
+	int rc;
+	CommandList_struct *cp;
+	unsigned char cdb[12];
+	unsigned char scsi3addr[8];
+	ErrorInfo_struct *ei;
+
+	cp = scsi_cmd_alloc(c);
+	if (cp == NULL) {			/* trouble... */
+		printk("cmd_alloc returned NULL!\n");
+		return -1;
+	}
+
+	memset(&scsi3addr[0], 0, 8); /* address the controller */
+	cdb[0] = CISS_REPORT_PHYS;
+	cdb[1] = 0;
+	cdb[2] = 0;
+	cdb[3] = 0;
+	cdb[4] = 0;
+	cdb[5] = 0;
+	cdb[6] = (bufsize >> 24) & 0xFF;  //MSB
+	cdb[7] = (bufsize >> 16) & 0xFF;
+	cdb[8] = (bufsize >> 8) & 0xFF;
+	cdb[9] = bufsize & 0xFF;
+	cdb[10] = 0;
+	cdb[11] = 0;
+
+	rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr,
+				cdb, 12,
+				(unsigned char *) buf,
+				bufsize, XFER_READ);
+
+	if (rc != 0) return rc; /* something went wrong */
+
+	ei = cp->err_info;
+	if (ei->CommandStatus != 0 &&
+	    ei->CommandStatus != CMD_DATA_UNDERRUN) {
+		cciss_scsi_interpret_error(cp);
+		scsi_cmd_free(c, cp);
+		return -1;
+	}
+	scsi_cmd_free(c, cp);
+	return 0;
+}
+
+static void
+cciss_update_non_disk_devices(int cntl_num, int hostno)
+{
+	/* the idea here is we could get notified from /proc
+	   that some devices have changed, so we do a report
+	   physical luns cmd, and adjust our list of devices
+	   accordingly.  (We can't rely on the scsi-mid layer just
+	   doing inquiries, because the "busses" that the scsi
+	   mid-layer probes are totally fabricated by this driver,
+	   so new devices wouldn't show up.
+
+	   the scsi3addr's of devices won't change so long as the
+	   adapter is not reset.  That means we can rescan and
+	   tell which devices we already know about, vs. new
+	   devices, vs.  disappearing devices.
+
+	   Also, if you yank out a tape drive, then put in a disk
+	   in it's place, (say, a configured volume from another
+	   array controller for instance)  _don't_ poke this driver
+	   (so it thinks it's still a tape, but _do_ poke the scsi
+	   mid layer, so it does an inquiry... the scsi mid layer
+	   could see the physical disk.  This would be bad.  Need to
+	   think about how to prevent that.  One idea would be to
+	   snoop all scsi responses and if an inquiry repsonse comes
+	   back that reports a disk, chuck it an return selection
+	   timeout instead and adjust our table...  Not sure i like
+	   that though.
+
+	 */
+
+	ReportLunData_struct *ld_buff;
+	InquiryData_struct *inq_buff;
+	unsigned char scsi3addr[8];
+	ctlr_info_t *c;
+	__u32 num_luns=0;
+	unsigned char *ch;
+	/* unsigned char found[CCISS_MAX_SCSI_DEVS_PER_HBA]; */
+	struct cciss_scsi_dev_t currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
+	int ncurrent=0;
+	int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
+	int i;
+
+	c = (ctlr_info_t *) hba[cntl_num];
+	ld_buff = kmalloc(reportlunsize, GFP_KERNEL);
+	if (ld_buff == NULL) {
+		printk(KERN_ERR "cciss: out of memory\n");
+		return;
+	}
+	memset(ld_buff, 0, reportlunsize);
+	inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
+	if (inq_buff == NULL) {
+		printk(KERN_ERR "cciss: out of memory\n");
+		kfree(ld_buff);
+		return;
+	}
+
+	if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) {
+		ch = &ld_buff->LUNListLength[0];
+		num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8;
+		if (num_luns > CISS_MAX_PHYS_LUN) {
+			printk(KERN_WARNING
+				"cciss: Maximum physical LUNs (%d) exceeded.  "
+				"%d LUNs ignored.\n", CISS_MAX_PHYS_LUN,
+				num_luns - CISS_MAX_PHYS_LUN);
+			num_luns = CISS_MAX_PHYS_LUN;
+		}
+	}
+	else {
+		printk(KERN_ERR  "cciss: Report physical LUNs failed.\n");
+		return;
+	}
+
+
+	/* adjust our table of devices */
+	for(i=0; i<num_luns; i++)
+	{
+		int devtype;
+
+		/* for each physical lun, do an inquiry */
+		memset(inq_buff, 0, sizeof(InquiryData_struct));
+		memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
+
+		if (cciss_scsi_do_inquiry(hba[cntl_num],
+			scsi3addr, inq_buff) != 0)
+		{
+			/* Inquiry failed (msg printed already) */
+			devtype = 0; /* so we will skip this device. */
+		} else /* what kind of device is this? */
+			devtype = (inq_buff->data_byte[0] & 0x1f);
+
+		switch (devtype)
+		{
+		  case 0x01: /* sequential access, (tape) */
+		  case 0x08: /* medium changer */
+			memcpy(&currentsd[ncurrent].scsi3addr[0],
+				&scsi3addr[0], 8);
+			currentsd[ncurrent].devtype = devtype;
+			currentsd[ncurrent].bus = -1;
+			currentsd[ncurrent].target = -1;
+			currentsd[ncurrent].lun = -1;
+			ncurrent++;
+			break;
+		  default:
+			break;
+		}
+	}
+
+	adjust_cciss_scsi_table(cntl_num, hostno, currentsd, ncurrent);
+
+	kfree(inq_buff);
+	kfree(ld_buff);
+	return;
+}
+
+static int
+is_keyword(char *ptr, int len, char *verb)  // Thanks to ncr53c8xx.c
+{
+	int verb_len = strlen(verb);
+	if (len >= verb_len && !memcmp(verb,ptr,verb_len))
+		return verb_len;
+	else
+		return 0;
+}
+
+static int
+cciss_scsi_user_command(int ctlr, int hostno, char *buffer, int length)
+{
+	int arg_len;
+
+	if ((arg_len = is_keyword(buffer, length, "rescan")) != 0)
+		cciss_update_non_disk_devices(ctlr, hostno);
+	else
+		return -EINVAL;
+	return length;
+}
+
+/* It's a pity that we need this, but, we do... */
+extern struct Scsi_Host *scsi_hostlist;  /* from ../scsi/hosts.c */
+
+int
+cciss_scsi_proc_info(char *buffer, /* data buffer */
+		char **start, 	   /* where data in buffer starts */
+		off_t offset,	   /* offset from start of imaginary file */
+		int length, 	   /* length of data in buffer */
+		int hostnum, 	   /* which host adapter (always zero for me) */
+		int func)	   /* 0 == read, 1 == write */
+{
+
+	int buflen, datalen;
+	struct Scsi_Host *sh;
+	int found;
+	ctlr_info_t *ci;
+	int cntl_num;
+
+	/* Lets see if we can find our Scsi_Host...
+	   this might be kind of "bad", searching scis_hostlist this way
+	   but how else can we find the scsi host?  I think I've seen
+	   this coded both ways, (circular list and null terminated list)
+	   I coded it to work either way, since I wasn't sure.  */
+
+	sh = scsi_hostlist;
+	found=0;
+	do {
+		if (sh == NULL) break;
+		if (sh->host_no == hostnum) {
+			found++;
+			break;
+		}
+		sh = sh->next;
+	} while (sh != scsi_hostlist && sh != NULL);
+
+	if (sh == NULL || found == 0) /* This really shouldn't ever happen. */
+		return -EINVAL;
+
+	ci = (ctlr_info_t *) sh->hostdata[0];
+	if (ci == NULL)  /* This really shouldn't ever happen. */
+		return -EINVAL;
+
+	cntl_num = ci->ctlr;	/* Get our index into the hba[] array */
+
+	if (func == 0) {	/* User is reading from /proc/scsi/ciss*?/?*  */
+		buflen = sprintf(buffer, "hostnum=%d\n", hostnum);
+
+		datalen = buflen - offset;
+		if (datalen < 0) { 	/* they're reading past EOF. */
+			datalen = 0;
+			*start = buffer+buflen;
+		} else
+			*start = buffer + offset;
+		return(datalen);
+	} else 	/* User is writing to /proc/scsi/cciss*?/?*  ... */
+		return cciss_scsi_user_command(cntl_num, hostnum,
+			buffer, length);
+}
+
+/* this is via the generic proc support */
+const char *
+cciss_scsi_info(struct Scsi_Host *sa)
+{
+	static char buf[300];
+	ctlr_info_t *ci;
+
+	/* probably need to work on putting a bit more info in here... */
+	/* this is output via the /proc filesystem. */
+
+	ci = (ctlr_info_t *) sa->hostdata[0];
+
+	sprintf(buf, "%s %c%c%c%c\n",
+		ci->product_name,
+		ci->firm_ver[0],
+		ci->firm_ver[1],
+		ci->firm_ver[2],
+		ci->firm_ver[3]);
+
+	return buf;
+}
+
+
+/* cciss_scatter_gather takes a Scsi_Cmnd, (cmd), and does the pci
+   dma mapping  and fills in the scatter gather entries of the
+   cciss command, cp. */
+
+static void
+cciss_scatter_gather(struct pci_dev *pdev,
+		CommandList_struct *cp,
+		Scsi_Cmnd *cmd)
+{
+	unsigned int use_sg, nsegs=0, len;
+	struct scatterlist *scatter = (struct scatterlist *) cmd->buffer;
+	__u64 addr64;
+
+	/* is it just one virtual address? */
+	if (!cmd->use_sg) {
+		if (cmd->request_bufflen) {	/* anything to xfer? */
+
+			addr64 = (__u64) pci_map_single(pdev,
+				cmd->request_buffer,
+				cmd->request_bufflen,
+				scsi_to_pci_dma_dir(cmd->sc_data_direction));
+
+			cp->SG[0].Addr.lower =
+			  (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
+			cp->SG[0].Addr.upper =
+			  (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
+			cp->SG[0].Len = cmd->request_bufflen;
+			nsegs=1;
+		}
+	} /* else, must be a list of virtual addresses.... */
+	else if (cmd->use_sg <= MAXSGENTRIES) {	/* not too many addrs? */
+
+		use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg,
+			scsi_to_pci_dma_dir(cmd->sc_data_direction));
+
+		for (nsegs=0; nsegs < use_sg; nsegs++) {
+			addr64 = (__u64) sg_dma_address(&scatter[nsegs]);
+			len  = sg_dma_len(&scatter[nsegs]);
+			cp->SG[nsegs].Addr.lower =
+			  (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
+			cp->SG[nsegs].Addr.upper =
+			  (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
+			cp->SG[nsegs].Len = len;
+			cp->SG[nsegs].Ext = 0;  // we are not chaining
+		}
+	} else BUG();
+
+	cp->Header.SGList = (__u8) nsegs;   /* no. SGs contig in this cmd */
+	cp->Header.SGTotal = (__u16) nsegs; /* total sgs in this cmd list */
+	return;
+}
+
+
+int
+cciss_scsi_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
+{
+	ctlr_info_t **c;
+	int ctlr, rc;
+	unsigned char scsi3addr[8];
+	CommandList_struct *cp;
+
+	// Get the ptr to our adapter structure (hba[i]) out of cmd->host.
+	// We violate cmd->host privacy here.  (Is there another way?)
+	c = (ctlr_info_t **) &cmd->host->hostdata[0];
+	ctlr = (*c)->ctlr;
+
+	rc = lookup_scsi3addr(ctlr, cmd->channel, cmd->target, cmd->lun,
+			scsi3addr);
+	if (rc != 0) {
+		/* the scsi nexus does not match any that we presented... */
+		/* pretend to mid layer that we got selection timeout */
+		cmd->result = DID_NO_CONNECT << 16;
+		done(cmd);
+		/* we might want to think about registering controller itself
+		   as a processor device on the bus so sg binds to it. */
+		return 0;
+	}
+
+	// printk("cciss_queue_command, p=%p, cmd=0x%02x, c%db%dt%dl%d\n",
+	//	cmd, cmd->cmnd[0], ctlr, cmd->channel, cmd->target, cmd->lun);
+
+	/* Ok, we have a reasonable scsi nexus, so send the cmd down, and
+		see what the device thinks of it. */
+
+	cp = scsi_cmd_alloc(*c);
+	if (cp == NULL) {			/* trouble... */
+		printk("scsi_cmd_alloc returned NULL!\n");
+		/* FIXME: next 3 lines are -> BAD! <- */
+		cmd->result = DID_NO_CONNECT << 16;
+		done(cmd);
+		return 0;
+	}
+
+	// Fill in the command list header
+
+	cmd->scsi_done = done;    // save this for use by completion code
+
+	// save cp in case we have to abort it
+	cmd->host_scribble = (unsigned char *) cp;
+
+	cp->cmd_type = CMD_SCSI;
+	cp->scsi_cmd = cmd;
+	cp->Header.ReplyQueue = 0;  // unused in simple mode
+	memcpy(&cp->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
+	cp->Header.Tag.lower = cp->busaddr;  // Use k. address of cmd as tag
+
+	// Fill in the request block...
+
+	cp->Request.Timeout = 1000; // guarantee completion
+	memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
+	if (cmd->cmd_len > sizeof(cp->Request.CDB)) BUG();
+	cp->Request.CDBLen = cmd->cmd_len;
+	memcpy(cp->Request.CDB, cmd->cmnd, cmd->cmd_len);
+	cp->Request.Type.Type = TYPE_CMD;
+	cp->Request.Type.Attribute = ATTR_SIMPLE;
+	switch(cmd->sc_data_direction)
+	{
+	  case SCSI_DATA_WRITE: cp->Request.Type.Direction = XFER_WRITE; break;
+	  case SCSI_DATA_READ: cp->Request.Type.Direction = XFER_READ; break;
+	  case SCSI_DATA_NONE: cp->Request.Type.Direction = XFER_NONE; break;
+
+	  case SCSI_DATA_UNKNOWN:
+		// This can happen if a buggy application does a scsi passthru
+		// and sets both inlen and outlen to non-zero. ( see
+		// ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() )
+
+		cp->Request.Type.Direction = XFER_RSVD;
+		// This is technically wrong, and cciss controllers should
+		// reject it with CMD_INVALID, which is the most correct
+		// response, but non-fibre backends appear to let it
+		// slide by, and give the same results as if this field
+		// were set correctly.  Either way is acceptable for
+		// our purposes here.
+
+		break;
+
+	  default:
+		printk("cciss: unknown data direction: %d\n",
+			cmd->sc_data_direction);
+		BUG();
+		break;
+	}
+
+	cciss_scatter_gather((*c)->pdev, cp, cmd); // Fill the SG list
+
+	/* Put the request on the tail of the request queue */
+
+	addQ(&(*c)->reqQ, cp);
+	(*c)->Qdepth++;
+	start_io(*c);
+
+	/* the cmd'll come back via intr handler in complete_scsi_command()  */
+	return 0;
+}
+
+static void
+init_driver_template(int ctlr)
+{
+	memset(&driver_template[ctlr], 0, sizeof(driver_template[ctlr]));
+	driver_template[ctlr].name = ccissscsi[ctlr].name;
+	driver_template[ctlr].proc_name = ccissscsi[ctlr].name;
+	driver_template[ctlr].detect = cciss_scsi_detect;
+	driver_template[ctlr].release = cciss_scsi_release;
+	driver_template[ctlr].proc_info = cciss_scsi_proc_info;
+	driver_template[ctlr].queuecommand = cciss_scsi_queue_command;
+	driver_template[ctlr].eh_abort_handler = NULL;
+	driver_template[ctlr].eh_device_reset_handler = NULL;
+	driver_template[ctlr].bios_param = scsicam_bios_param;
+	driver_template[ctlr].can_queue = SCSI_CCISS_CAN_QUEUE;
+	driver_template[ctlr].this_id = SELF_SCSI_ID;
+	driver_template[ctlr].sg_tablesize = MAXSGENTRIES;
+	driver_template[ctlr].cmd_per_lun = 1;
+	driver_template[ctlr].use_new_eh_code = 1;
+	driver_template[ctlr].use_clustering = DISABLE_CLUSTERING;
+	driver_template[ctlr].module = THIS_MODULE;
+
+	/* set scsi_host to NULL so our detect routine will
+	   find us on register */
+
+	((struct cciss_scsi_adapter_data_t *)
+		hba[ctlr]->scsi_ctlr)->scsi_host = NULL;
+
+}
+
+static void
+cciss_unregister_scsi(int ctlr)
+{
+	struct cciss_scsi_adapter_data_t *sa;
+	struct cciss_scsi_cmd_stack_t *stk;
+	unsigned long flags;
+
+	/* we are being forcibly unloaded, and may not refuse. */
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
+	stk = &sa->cmd_stack;
+
+	/* if we weren't ever actually registered, don't unregister */
+	if (((struct cciss_scsi_adapter_data_t *)
+		hba[ctlr]->scsi_ctlr)->registered) {
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		scsi_unregister_module(MODULE_SCSI_HA, &driver_template[ctlr]);
+		spin_lock_irqsave(&io_request_lock, flags);
+	}
+	init_driver_template(ctlr);
+	scsi_cmd_stack_free(ctlr);
+	kfree(hba[ctlr]->scsi_ctlr);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+static int
+cciss_register_scsi(int ctlr, int this_is_init_time)
+{
+	unsigned long flags;
+
+	CPQ_TAPE_LOCK(ctlr, flags);
+	driver_template[ctlr].name = ccissscsi[ctlr].name;
+	driver_template[ctlr].proc_name = ccissscsi[ctlr].name;
+	driver_template[ctlr].module = THIS_MODULE;;
+
+	/* Since this is really a block driver, the SCSI core may not be
+	   initialized yet, in which case, calling scsi_register_module
+	   would hang.  instead, we will do it later, via /proc filesystem
+	   and rc scripts, when we know SCSI core is good to go. */
+
+	if (this_is_init_time) {
+		CPQ_TAPE_UNLOCK(ctlr, flags);
+		return 0;
+	}
+
+	/* Only register if SCSI devices are detected. */
+	if (ccissscsi[ctlr].ndevices != 0) {
+		((struct cciss_scsi_adapter_data_t *)
+			hba[ctlr]->scsi_ctlr)->registered = 1;
+		CPQ_TAPE_UNLOCK(ctlr, flags);
+		return scsi_register_module(MODULE_SCSI_HA,
+			&driver_template[ctlr]);
+	}
+	CPQ_TAPE_UNLOCK(ctlr, flags);
+	printk(KERN_INFO
+		"cciss%d: No appropriate SCSI device detected, "
+		"SCSI subsystem not engaged.\n", ctlr);
+	return 0;
+}
+
+static int
+cciss_engage_scsi(int ctlr)
+{
+	struct cciss_scsi_adapter_data_t *sa;
+	struct cciss_scsi_cmd_stack_t *stk;
+	unsigned long flags;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
+	stk = &sa->cmd_stack;
+
+	if (((struct cciss_scsi_adapter_data_t *)
+		hba[ctlr]->scsi_ctlr)->registered) {
+		printk("cciss%d: SCSI subsystem already engaged.\n", ctlr);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return ENXIO;
+	}
+	spin_unlock_irqrestore(&io_request_lock, flags);
+	cciss_update_non_disk_devices(ctlr, -1);
+	cciss_register_scsi(ctlr, 0);
+	return 0;
+}
+
+static void
+cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len)
+{
+	int size;
+	unsigned int flags;
+
+	*pos = *pos -1; *len = *len - 1; // cut off the last trailing newline
+
+	CPQ_TAPE_LOCK(ctlr, flags);
+	size = sprintf(buffer + *len,
+		"       Sequential access devices: %d\n\n",
+			ccissscsi[ctlr].ndevices);
+	CPQ_TAPE_UNLOCK(ctlr, flags);
+	*pos += size; *len += size;
+}
+
+#else /* no CONFIG_CISS_SCSI_TAPE */
+
+/* If no tape support, then these become defined out of existence */
+
+#define cciss_find_non_disk_devices(cntl_num)
+#define cciss_unregister_scsi(ctlr)
+#define cciss_register_scsi(ctlr, this_is_init_time)
+#define cciss_proc_tape_report(ctlr, buffer, pos, len)
+
+#endif /* CONFIG_CISS_SCSI_TAPE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/cciss_scsi.h linux/drivers/block/cciss_scsi.h
--- linux.orig/drivers/block/cciss_scsi.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/block/cciss_scsi.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,99 @@
+/*
+ *    Disk Array driver for Compaq SA53xx Controllers, SCSI Tape module
+ *    Copyright 2001 Compaq Computer 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, GOOD TITLE or
+ *    NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *    Questions/Comments/Bugfixes to arrays@compaq.com
+ *
+ */
+#ifdef CONFIG_CISS_SCSI_TAPE
+#ifndef _CCISS_SCSI_H_
+#define _CCISS_SCSI_H_
+
+#include <scsi/scsicam.h> /* possibly irrelevant, since we don't show disks */
+
+		// the scsi id of the adapter...
+#define SELF_SCSI_ID -1 
+		// In case we ever want to present controller so sg will 
+		// bind to it.  The scsi bus that's presented by the
+		// driver to the OS is fabricated.  The "real" scsi-3
+		// bus the hardware presents is fabricated too.
+		// The actual, honest-to-goodness physical
+		// bus that the devices are attached to is not
+		// addressible natively, and may in fact turn
+		// out to be not scsi at all.
+
+#define SCSI_CCISS_CAN_QUEUE 2
+
+/* this notation works fine for static initializations (as is the usual
+   case for linux scsi drivers), but not so well for dynamic settings,
+   so, if you change this, you also have to change cciss_unregister_scsi()
+   in cciss_scsi.c  */
+#define CCISS_SCSI {    \
+	name:			"",				\
+	detect:			cciss_scsi_detect,		\
+	release:		cciss_scsi_release,		\
+	proc_info:		cciss_scsi_proc_info,		\
+	queuecommand:   	cciss_scsi_queue_command,	\
+	bios_param:     	scsicam_bios_param,		\
+	can_queue:      	SCSI_CCISS_CAN_QUEUE,		\
+	this_id:		SELF_SCSI_ID,			\
+	sg_tablesize:   	MAXSGENTRIES, 			\
+	cmd_per_lun:		1,				\
+	use_new_eh_code:	1,				\
+	use_clustering:		DISABLE_CLUSTERING,\
+}
+
+/*
+	info:			cciss_scsi_info,		\
+
+Note, cmd_per_lun could give us some trouble, so I'm setting it very low.
+Likewise, SCSI_CCISS_CAN_QUEUE is set very conservatively.
+
+If the upper scsi layer tries to track how many commands we have
+outstanding, it will be operating under the misapprehension that it is
+the only one sending us requests.  We also have the block interface,
+which is where most requests must surely come from, so the upper layer's
+notion of how many requests we have outstanding will be wrong most or
+all of the time.
+
+Note, the normal SCSI mid-layer error handling doesn't work well
+for this driver because 1) it takes the io_request_lock before
+calling error handlers and uses a local variable to store flags,
+so the io_request_lock cannot be released and interrupts enabled
+inside the error handlers, and, the error handlers cannot poll
+for command completion because they might get commands from the
+block half of the driver completing, and not know what to do
+with them.  That's what we get for making a hybrid scsi/block
+driver, I suppose.
+
+*/
+
+struct cciss_scsi_dev_t {
+	int devtype;
+	int bus, target, lun;		/* as presented to the OS */
+	unsigned char scsi3addr[8];	/* as presented to the HW */
+};
+
+struct cciss_scsi_hba_t {
+	char *name;
+	int ndevices;
+#define CCISS_MAX_SCSI_DEVS_PER_HBA 16
+	struct cciss_scsi_dev_t dev[CCISS_MAX_SCSI_DEVS_PER_HBA];
+};
+
+#endif /* _CCISS_SCSI_H_ */
+#endif /* CONFIG_CISS_SCSI_TAPE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- linux.orig/drivers/block/cpqarray.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/block/cpqarray.c	2002-07-20 01:08:26.000000000 +0000
@@ -32,7 +32,6 @@
 #include <linux/blkpg.h>
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/init.h>
 #include <linux/hdreg.h>
 #include <linux/spinlock.h>
@@ -42,13 +41,13 @@
 
 #define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 
-#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.5)"
-#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,5)
+#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.21)"
+#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,21)
 
 /* Embedded module documentation macros - see modules.h */
 /* Original author Chris Frantz - Compaq Computer Corporation */
 MODULE_AUTHOR("Compaq Computer Corporation");
-MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers");
+MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.4.21");
 MODULE_LICENSE("GPL");
 
 #define MAJOR_NR COMPAQ_SMART2_MAJOR
@@ -65,13 +64,11 @@
 #define NR_CMDS		128 /* This could probably go as high as ~400 */
 
 #define MAX_CTLR	8
-#define CTLR_SHIFT	8
 
 #define CPQARRAY_DMA_MASK	0xFFFFFFFF	/* 32 bit DMA */
 
-static int nr_ctlr;
-static ctlr_info_t *hba[MAX_CTLR];
-static devfs_handle_t de_arr[MAX_CTLR][NWD];
+static ctlr_info_t *hba[MAX_CTLR] = 
+	{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 
 static int eisa[8];
 
@@ -99,11 +96,33 @@
 	{ 0x40580E11, "Smart Array 431",	&smart4_access },
 };
 
-static struct hd_struct * ida;
-static int * ida_sizes;
-static int * ida_blocksizes;
-static int * ida_hardsizes;
-static struct gendisk ida_gendisk[MAX_CTLR];
+/* define the PCI info for the PCI cards this driver can control */
+const struct pci_device_id cpqarray_pci_device_id[] = 
+{
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, 
+		0x0E11, 0x4058, 0, 0, 0},	/* SA431 */
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, 
+                0x0E11, 0x4051, 0, 0, 0},	/* SA4250ES */
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, 
+                0x0E11, 0x4050, 0, 0, 0},	/* SA4200 */
+	{ PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C1510,
+		0x0E11, 0x4048, 0, 0, 0},	/* LC2 */
+	{ PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C1510,
+                0x0E11, 0x4040, 0, 0, 0}, 	/* Integrated Array */
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+		0x0E11, 0x4034, 0, 0, 0},	/* SA 221 */ 
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+                0x0E11, 0x4033, 0, 0, 0},       /* SA 3100ES*/
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+                0x0E11, 0x4032, 0, 0, 0},       /* SA 3200*/
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+                0x0E11, 0x4031, 0, 0, 0},       /* SA 2SL*/
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+                0x0E11, 0x4030, 0, 0, 0},       /* SA 2P */
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, cpqarray_pci_device_id);
 
 static struct proc_dir_entry *proc_array;
 
@@ -117,7 +136,6 @@
 #define DBGPX(s) do { } while(0)
 
 int cpqarray_init(void);
-static int cpqarray_pci_detect(void);
 static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev);
 static void *remap_pci_mem(ulong base, ulong size);
 static int cpqarray_eisa_detect(void);
@@ -128,6 +146,9 @@
 static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool);
 static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool);
 
+static void free_hba(int i);
+static int alloc_cpqarray_hba(void);
+
 static int sendcmd(
 	__u8	cmd,
 	int	ctlr,
@@ -156,6 +177,9 @@
 static int revalidate_logvol(kdev_t dev, int maxusage);
 static int revalidate_allvol(kdev_t dev);
 
+static int deregister_disk(int ctlr, int logvol);
+static int register_new_disk(int cltr,int logvol);
+
 #ifdef CONFIG_PROC_FS
 static void ida_procinit(int i);
 static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
@@ -174,18 +198,15 @@
 		drv = &hba[ctlr]->drv[i];
 		if (!drv->nr_blks)
 			continue;
-		ida[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)].nr_sects =
-		ida_sizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)] =
-				drv->nr_blks;
-
-		for(j=0; j<16; j++) {
-			ida_blocksizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)+j] =
-				1024;
-			ida_hardsizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)+j] =
-				drv->blk_size;
+		hba[ctlr]->hd[i<<NWD_SHIFT].nr_sects =
+			hba[ctlr]->sizes[i<<NWD_SHIFT] = drv->nr_blks;
+
+		for(j=0; j<IDA_MAX_PART; j++) {
+			hba[ctlr]->blocksizes[(i<<NWD_SHIFT)+j] = 1024;
+			hba[ctlr]->hardsizes[(i<<NWD_SHIFT)+j] = drv->blk_size;
 		}
-		ida_gendisk[ctlr].nr_real++;
 	}
+	hba[ctlr]->gendisk.nr_real = hba[ctlr]->highest_lun +1;
 
 }
 
@@ -238,6 +259,7 @@
 		"       I/O Port: 0x%04x\n"
 		"       IRQ: %d\n"
 		"       Logical drives: %d\n"
+		"       Highest Logical ID: %d\n"
 		"       Physical drives: %d\n\n"
 		"       Current Q depth: %d\n"
 		"       Max Q depth since init: %d\n\n",
@@ -246,8 +268,8 @@
 		(unsigned long)h->board_id,
 		h->firm_rev[0], h->firm_rev[1], h->firm_rev[2], h->firm_rev[3],
 		(unsigned long)h->ctlr_sig, (unsigned long)h->vaddr,
-		(unsigned int) h->ioaddr, (unsigned int)h->intr,
-		h->log_drives, h->phys_drives,
+		(unsigned int) h->io_mem_addr, (unsigned int)h->intr,
+		h->log_drives, h->highest_lun, h->phys_drives,
 		h->Qdepth, h->maxQsinceinit);
 
 	pos += size; len += size;
@@ -255,11 +277,14 @@
 	size = sprintf(buffer+len, "Logical Drive Info:\n");
 	pos += size; len += size;
 
-	for(i=0; i<h->log_drives; i++) {
+	for(i=0; i<=h->highest_lun; i++) {
 		drv = &h->drv[i];
-		size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
+		if(drv->nr_blks != 0)
+		{
+		    	size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
 				ctlr, i, drv->blk_size, drv->nr_blks);
-		pos += size; len += size;
+			pos += size; len += size;
+		}
 	}
 
 #ifdef CPQ_PROC_PRINT_QUEUES
@@ -299,56 +324,112 @@
 }
 #endif /* CONFIG_PROC_FS */
 
-#ifdef MODULE
 
 MODULE_PARM(eisa, "1-8i");
 EXPORT_NO_SYMBOLS;
 
 /* This is a bit of a hack... */
-int __init init_module(void)
+int __init init_cpqarray_module(void)
 {
 	if (cpqarray_init() == 0) /* all the block dev numbers already used */
-		return -EIO;	  /* or no controllers were found */
+		return -ENODEV;	  /* or no controllers were found */
 	return 0;
 }
 
-void cleanup_module(void)
+static void release_io_mem(ctlr_info_t *c)
+{
+	/* if IO mem was not protected do nothing */
+	if( c->io_mem_addr == 0)
+		return;
+	release_region(c->io_mem_addr, c->io_mem_length);
+	c->io_mem_addr = 0;
+	c->io_mem_length = 0;
+}
+
+static void __devexit cpqarray_remove_one (struct pci_dev *pdev)
 {
 	int i;
+	ctlr_info_t *tmp_ptr;
 	char buff[4]; 
 
-	for(i=0; i<nr_ctlr; i++) {
+		if (pdev->driver_data == NULL)
+	{
+		printk( KERN_ERR "cpqarray: Unable to remove device \n");
+		return;
+	}
+	tmp_ptr = (ctlr_info_t *) pdev->driver_data;
+	i = tmp_ptr->ctlr;
+	if (hba[i] == NULL) 
+	{
+		printk(KERN_ERR "cpqarray: device appears to "
+			"already be removed \n");
+		return;
+	}
 
-		/* sendcmd will turn off interrupt, and send the flush... 
-		 * To write all data in the battery backed cache to disks    
-		 * no data returned, but don't want to send NULL to sendcmd */	
-		if( sendcmd(FLUSH_CACHE, i, buff, 4, 0, 0, 0))
-		{
-			printk(KERN_WARNING "Unable to flush cache on "
-				"controller %d\n", i);	
-		}
-		free_irq(hba[i]->intr, hba[i]);
-		iounmap(hba[i]->vaddr);
-		unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-		del_timer(&hba[i]->timer);
-		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i));
-		remove_proc_entry(hba[i]->devname, proc_array);
-		pci_free_consistent(hba[i]->pci_dev, 
+	/* sendcmd will turn off interrupt, and send the flush... 
+	 * To write all data in the battery backed cache to disks    */
+	memset(buff, 0 , 4);
+	if( sendcmd(FLUSH_CACHE, i, buff, 4, 0, 0, 0))
+	{
+		printk(KERN_WARNING "Unable to flush cache on controller %d\n",
+			 i);	
+	}
+	free_irq(hba[i]->intr, hba[i]);
+	pdev->driver_data = NULL;
+	/* remove it from the disk list */
+	del_gendisk(&(hba[i]->gendisk));
+
+	iounmap(hba[i]->vaddr);
+	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+	del_timer(&hba[i]->timer);
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i));
+	remove_proc_entry(hba[i]->devname, proc_array);
+	pci_free_consistent(hba[i]->pci_dev, 
 			NR_CMDS * sizeof(cmdlist_t), (hba[i]->cmd_pool), 
 			hba[i]->cmd_pool_dhandle);
-		kfree(hba[i]->cmd_pool_bits);
+	kfree(hba[i]->cmd_pool_bits);
+	release_io_mem(hba[i]);
+	free_hba(i);
+}
+
+/* removing an instance that was not removed automatically.. 
+ * must be an eisa card. 
+ */
+static void __devexit cpqarray_remove_one_eisa (int i)
+{
+	char buff[4]; 
 
-		del_gendisk(&ida_gendisk[i]);
+	if (hba[i] == NULL) 
+	{
+		printk(KERN_ERR "cpqarray: device appears to "
+			"already be removed \n");
+		return;
 	}
-	devfs_unregister(devfs_find_handle(NULL, "ida", 0, 0, 0, 0));
-	remove_proc_entry("cpqarray", proc_root_driver);
-	kfree(ida);
-	kfree(ida_sizes);
-	kfree(ida_hardsizes);
-	kfree(ida_blocksizes);
-}
-#endif /* MODULE */
 
+	/* sendcmd will turn off interrupt, and send the flush... 
+	 * To write all data in the battery backed cache to disks    
+	 * no data returned, but don't want to send NULL to sendcmd */	
+	if( sendcmd(FLUSH_CACHE, i, buff, 4, 0, 0, 0))
+	{
+		printk(KERN_WARNING "Unable to flush cache on controller %d\n",
+			 i);	
+	}
+	free_irq(hba[i]->intr, hba[i]);
+	/* remove it from the disk list */
+	del_gendisk(&(hba[i]->gendisk));
+
+	iounmap(hba[i]->vaddr);
+	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+	del_timer(&hba[i]->timer);
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i));
+	remove_proc_entry(hba[i]->devname, proc_array);
+	pci_free_consistent(hba[i]->pci_dev, 
+			NR_CMDS * sizeof(cmdlist_t), (hba[i]->cmd_pool), 
+			hba[i]->cmd_pool_dhandle);
+	kfree(hba[i]->cmd_pool_bits);
+	release_io_mem(hba[i]);
+	free_hba(i);
+}
 static inline int cpq_new_segment(request_queue_t *q, struct request *rq,
 				  int max_segments)
 {
@@ -390,248 +471,190 @@
 	return 1;
 }
 
-/*
- *  This is it.  Find all the controllers and register them.  I really hate
- *  stealing all these major device numbers.
- *  returns the number of block devices registered.
- */
-int __init cpqarray_init(void)
+static int __init cpqarray_init_one( struct pci_dev *pdev,
+	const struct pci_device_id *ent)
 {
 	request_queue_t *q;
-	int i,j;
-	int num_cntlrs_reg = 0;
-
-	/* detect controllers */
-	cpqarray_pci_detect();
-	cpqarray_eisa_detect();
-	
-	if (nr_ctlr == 0)
-		return(num_cntlrs_reg);
+        int i,j;
 
-	printk(DRIVER_NAME "\n");
-	printk("Found %d controller(s)\n", nr_ctlr);
-
-	/* allocate space for disk structs */
-	ida = kmalloc(sizeof(struct hd_struct)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida==NULL)
-	{
-		printk( KERN_ERR "cpqarray: out of memory");
-		return(num_cntlrs_reg);
-	}
-	
-	ida_sizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida_sizes==NULL)
-	{
-		kfree(ida); 
-		printk( KERN_ERR "cpqarray: out of memory");
-		return(num_cntlrs_reg);
-	}
 
-	ida_blocksizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida_blocksizes==NULL)
-	{
-		kfree(ida);
-		kfree(ida_sizes); 
-		printk( KERN_ERR "cpqarray: out of memory");
-		return(num_cntlrs_reg);
-	}
+	printk(KERN_DEBUG "cpqarray: Device 0x%x has been found at"
+		" bus %d dev %d func %d\n",
+		pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn),
+			PCI_FUNC(pdev->devfn));
+	i = alloc_cpqarray_hba();
+	if( i < 0 ) 
+		return (-1);
+	memset(hba[i], 0, sizeof(ctlr_info_t));
+	/* fill in default block size */
+	for(j=0;j<256;j++)
+                hba[i]->hardsizes[j] = BLOCK_SIZE;
+
+	sprintf(hba[i]->devname, "ida%d", i);
+        hba[i]->ctlr = i;
+	/* Initialize the pdev driver private data */
+	pdev->driver_data = hba[i];
 
-	ida_hardsizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida_hardsizes==NULL)
+	if (cpqarray_pci_init(hba[i], pdev) != 0)
 	{
-		kfree(ida);
-		kfree(ida_sizes); 
-		kfree(ida_blocksizes);
-		printk( KERN_ERR "cpqarray: out of memory");
-		return(num_cntlrs_reg);
+		release_io_mem(hba[i]);
+		free_hba(i);
+		return (-1);
 	}
-
-	memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
-	memset(ida_sizes, 0, sizeof(int)*nr_ctlr*NWD*16);
-	memset(ida_blocksizes, 0, sizeof(int)*nr_ctlr*NWD*16);
-	memset(ida_hardsizes, 0, sizeof(int)*nr_ctlr*NWD*16);
-	memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR);
-
-		/* 
+			
+	/* 
 	 * register block devices
 	 * Find disks and fill in structs
 	 * Get an interrupt, set the Q depth and get into /proc
 	 */
-	for(i=0; i< nr_ctlr; i++) {
-	  	/* If this successful it should insure that we are the only */
-		/* instance of the driver */	
-		if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) {
-                        printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n",
+	
+	/* If this successful it should insure that we are the only */
+	/* instance of the driver */	
+	if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) 
+	{
+        	printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n",
                                 MAJOR_NR+i);
-                        continue;
-                }
+                release_io_mem(hba[i]);
+                free_hba(i);
+                return (-1);
+        }
 
 	
-		hba[i]->access.set_intr_mask(hba[i], 0);
-		if (request_irq(hba[i]->intr, do_ida_intr,
-			SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) {
+	hba[i]->access.set_intr_mask(hba[i], 0);
+	if (request_irq(hba[i]->intr, do_ida_intr,
+		SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) 
+	{
 
-			printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", 
+		printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", 
 				hba[i]->intr, hba[i]->devname);
-			unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-			continue;
-		}
-		num_cntlrs_reg++;
-		hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent(
-				hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), 
+		unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+		release_io_mem(hba[i]);
+                free_hba(i);
+                return (-1);
+	}
+	hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent(
+	hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), 
 				&(hba[i]->cmd_pool_dhandle));
-		hba[i]->cmd_pool_bits = (__u32*)kmalloc(
+	hba[i]->cmd_pool_bits = (__u32*)kmalloc(
 				((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
 		
 	if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL)
-		{
-			nr_ctlr = i; 
-			if(hba[i]->cmd_pool_bits)
-				kfree(hba[i]->cmd_pool_bits);
-			if(hba[i]->cmd_pool)
-				pci_free_consistent(hba[i]->pci_dev, 
-					NR_CMDS * sizeof(cmdlist_t), 
-					hba[i]->cmd_pool, 
-					hba[i]->cmd_pool_dhandle);
-			free_irq(hba[i]->intr, hba[i]);
-			unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-			num_cntlrs_reg--;
-                	printk( KERN_ERR "cpqarray: out of memory");
-
-			/* If num_cntlrs_reg == 0, no controllers worked. 
-			 *	init_module will fail, so clean up global 
-			 *	memory that clean_module would do.
-			*/	
-	
-			if (num_cntlrs_reg == 0) 
-			{
-				kfree(ida);
-				kfree(ida_sizes);
-				kfree(ida_hardsizes);
-				kfree(ida_blocksizes);
-			}
-                	return(num_cntlrs_reg);
-	
-		}
-		memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
-		memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));
-		printk(KERN_INFO "cpqarray: Finding drives on %s", 
-			hba[i]->devname);
-		getgeometry(i);
-		start_fwbk(i); 
-
-		hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);
-
-		ida_procinit(i);
-
-		q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
-		q->queuedata = hba[i];
-		blk_init_queue(q, do_ida_request);
-		blk_queue_headactive(q, 0);
-		blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
-		hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256);
-		read_ahead[MAJOR_NR+i] = READ_AHEAD;
-
-		q->back_merge_fn = cpq_back_merge_fn;
-		q->front_merge_fn = cpq_front_merge_fn;
-		q->merge_requests_fn = cpq_merge_requests_fn;
-
-		ida_gendisk[i].major = MAJOR_NR + i;
-		ida_gendisk[i].major_name = "ida";
-		ida_gendisk[i].minor_shift = NWD_SHIFT;
-		ida_gendisk[i].max_p = 16;
-		ida_gendisk[i].part = ida + (i*256);
-		ida_gendisk[i].sizes = ida_sizes + (i*256);
-		ida_gendisk[i].nr_real = 0; 
-		ida_gendisk[i].de_arr = de_arr[i]; 
-		ida_gendisk[i].fops = &ida_fops; 
+	{
+		if(hba[i]->cmd_pool_bits)
+			kfree(hba[i]->cmd_pool_bits);
+		if(hba[i]->cmd_pool)
+			pci_free_consistent(hba[i]->pci_dev, 
+				NR_CMDS * sizeof(cmdlist_t), 
+				hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
+		free_irq(hba[i]->intr, hba[i]);
+		unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+                printk( KERN_ERR "cpqarray: out of memory");
+		release_io_mem(hba[i]);
+                free_hba(i);
+                return (-1);
+	}
+	memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
+	memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));
+	printk(KERN_INFO "cpqarray: Finding drives on %s", hba[i]->devname);
+	getgeometry(i);
+	start_fwbk(i); 
+
+	hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);
+
+	ida_procinit(i);
+
+	q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
+	q->queuedata = hba[i];
+	blk_init_queue(q, do_ida_request);
+	blk_queue_headactive(q, 0);
+	blksize_size[MAJOR_NR+i] = hba[i]->blocksizes;
+	hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes;
+	read_ahead[MAJOR_NR+i] = READ_AHEAD;
+
+	q->back_merge_fn = cpq_back_merge_fn;
+	q->front_merge_fn = cpq_front_merge_fn;
+	q->merge_requests_fn = cpq_merge_requests_fn;
+
+	hba[i]->gendisk.major = MAJOR_NR + i;
+	hba[i]->gendisk.major_name = "ida";
+	hba[i]->gendisk.minor_shift = NWD_SHIFT;
+	hba[i]->gendisk.max_p = IDA_MAX_PART;
+	hba[i]->gendisk.part = hba[i]->hd;
+	hba[i]->gendisk.sizes = hba[i]->sizes;
+	hba[i]->gendisk.nr_real = hba[i]->highest_lun+1; 
 	
 		/* Get on the disk list */
-		add_gendisk(&ida_gendisk[i]);
+	add_gendisk(&(hba[i]->gendisk));
 
-		init_timer(&hba[i]->timer);
-		hba[i]->timer.expires = jiffies + IDA_TIMER;
-		hba[i]->timer.data = (unsigned long)hba[i];
-		hba[i]->timer.function = ida_timer;
-		add_timer(&hba[i]->timer);
-
-		ida_geninit(i);
-		for(j=0; j<NWD; j++)	
-			register_disk(&ida_gendisk[i], 
-				MKDEV(MAJOR_NR+i,j<<4),
-				16, &ida_fops, hba[i]->drv[j].nr_blks);
+	init_timer(&hba[i]->timer);
+	hba[i]->timer.expires = jiffies + IDA_TIMER;
+	hba[i]->timer.data = (unsigned long)hba[i];
+	hba[i]->timer.function = ida_timer;
+	add_timer(&hba[i]->timer);
+
+	ida_geninit(i);
+	for(j=0; j<NWD; j++)	
+		register_disk(&(hba[i]->gendisk), MKDEV(MAJOR_NR+i,j<<4),
+			IDA_MAX_PART, &ida_fops, hba[i]->drv[j].nr_blks);
+
+	return(i);
+}
+static struct pci_driver cpqarray_pci_driver = {
+        name:   "cpqarray",
+        probe:  cpqarray_init_one,
+        remove:  __devexit_p(cpqarray_remove_one),
+        id_table:  cpqarray_pci_device_id,
+};
+
+/*
+ *  This is it.  Find all the controllers and register them.  I really hate
+ *  stealing all these major device numbers.
+ *  returns the number of block devices registered.
+ */
+int __init cpqarray_init(void)
+{
+	int num_cntlrs_reg = 0;
+	int i;
+
+	/* detect controllers */
+	printk(DRIVER_NAME "\n");
+	pci_register_driver(&cpqarray_pci_driver);
+	cpqarray_eisa_detect();
 
+	for(i=0; i< MAX_CTLR; i++)
+        {
+		if (hba[i] != NULL)
+			num_cntlrs_reg++;
 	}
-	/* done ! */
 	return(num_cntlrs_reg);
 }
-
-/*
- * Find the controller and initialize it
- *  Cannot use the class code to search, because older array controllers use
- *    0x018000 and new ones use 0x010400.  So I might as well search for each
- *    each device IDs, being there are only going to be three of them. 
- */
-static int cpqarray_pci_detect(void)
-{
-	struct pci_dev *pdev;
-
-#define IDA_BOARD_TYPES 3
-	static int ida_vendor_id[IDA_BOARD_TYPES] = { PCI_VENDOR_ID_DEC, 
-		PCI_VENDOR_ID_NCR, PCI_VENDOR_ID_COMPAQ };
-	static int ida_device_id[IDA_BOARD_TYPES] = { PCI_DEVICE_ID_COMPAQ_42XX,		PCI_DEVICE_ID_NCR_53C1510, PCI_DEVICE_ID_COMPAQ_SMART2P };
-	int brdtype;
-	
-	/* search for all PCI board types that could be for this driver */
-	for(brdtype=0; brdtype<IDA_BOARD_TYPES; brdtype++)
+/* Function to find the first free pointer into our hba[] array */
+/* Returns -1 if no free entries are left.  */
+static int alloc_cpqarray_hba(void)
+{
+	int i;
+	for(i=0; i< MAX_CTLR; i++)
 	{
-		pdev = pci_find_device(ida_vendor_id[brdtype],
-				       ida_device_id[brdtype], NULL);
-		while (pdev) {
-			printk(KERN_DEBUG "cpqarray: Device 0x%x has"
-				" been found at bus %d dev %d func %d\n",
-				ida_vendor_id[brdtype],
-				pdev->bus->number, PCI_SLOT(pdev->devfn),
-				PCI_FUNC(pdev->devfn));
-			if (nr_ctlr == 8) {
-				printk(KERN_WARNING "cpqarray: This driver"
-				" supports a maximum of 8 controllers.\n");
-				break;
-			}
-			
-/* if it is a PCI_DEVICE_ID_NCR_53C1510, make sure it's 				the Compaq version of the chip */ 
-
-			if (ida_device_id[brdtype] == PCI_DEVICE_ID_NCR_53C1510)			{	
-				unsigned short subvendor=pdev->subsystem_vendor;
-				if(subvendor !=  PCI_VENDOR_ID_COMPAQ)
-				{
-					printk(KERN_DEBUG 
-						"cpqarray: not a Compaq integrated array controller\n");
-					continue;
-				}
-			}
-
-			hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);			if(hba[nr_ctlr]==NULL)
+		if (hba[i] == NULL)
+		{
+			hba[i] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+			if(hba[i]==NULL)
 			{
 				printk(KERN_ERR "cpqarray: out of memory.\n");
-				continue;
+				return (-1);
 			}
-			memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
-			if (cpqarray_pci_init(hba[nr_ctlr], pdev) != 0)
-			{
-				kfree(hba[nr_ctlr]);
-				continue;
-			}
-			sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
-			hba[nr_ctlr]->ctlr = nr_ctlr;
-			nr_ctlr++;
-
-			pdev = pci_find_device(ida_vendor_id[brdtype],
-					       ida_device_id[brdtype], pdev);
+			return (i);
 		}
 	}
+	printk(KERN_WARNING "cpqarray: This driver supports a maximum"
+		" of 8 controllers.\n");
+	return(-1);
+}
 
-	return nr_ctlr;
+static void free_hba(int i)
+{
+	kfree(hba[i]);
+	hba[i]=NULL;
 }
 
 /*
@@ -648,6 +671,14 @@
 
 	int i;
 
+	pci_read_config_word(pdev, PCI_COMMAND, &command);
+	/* check to see if controller has been disabled */
+	if(!(command & 0x02))
+	{
+		printk(KERN_WARNING "cpqarray: controller appears to be disabled\n");
+		return(-1);
+	}
+	
 	c->pci_dev = pdev;
 	vendor_id = pdev->vendor;
 	device_id = pdev->device;
@@ -667,7 +698,6 @@
 		return -1;
 	}
 
-	pci_read_config_word(pdev, PCI_COMMAND, &command);
 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
 	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size);
 	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer);
@@ -688,11 +718,28 @@
 );
 
 	c->intr = irq;
-	c->ioaddr = addr[0];
-
+	for(i=0; i<6; i++)
+	{
+		if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO)
+		{ /* IO space */  
+			c->io_mem_addr = addr[i];
+			c->io_mem_length = pci_resource_end(pdev, i) 
+				- pci_resource_start(pdev, i) +1; 
+			// printk("IO Value found addr[%d] %lx %lx\n",
+			//		i, c->io_mem_addr, c->io_mem_length);
+			if(!request_region( c->io_mem_addr, c->io_mem_length,
+				"cpqarray"))
+			{
+				printk( KERN_WARNING "cpqarray I/O memory range already in use addr %lx length = %ld\n", c->io_mem_addr, c->io_mem_length);
+				c->io_mem_addr = 0;
+				c->io_mem_length = 0;
+			}
+			break;
+		}
+	}	
 	c->paddr = 0;
 	for(i=0; i<6; i++)
-		if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
+		if (!(pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO)) {
 			c->paddr = pci_resource_start (pdev, i);
 			break;
 		}
@@ -772,11 +819,11 @@
 	int i=0, j;
 	__u32 board_id;
 	int intr;
-
+	int ctlr;
+	int num_ctlr = 0;
 	while(i<8 && eisa[i]) {
-		if (nr_ctlr == 8) {
-			printk(KERN_WARNING "cpqarray: This driver supports"
-				" a maximum of 8 controllers.\n");
+		ctlr = alloc_cpqarray_hba();
+		if (ctlr == -1 ) {
 			break;
 		}
 		board_id = inl(eisa[i]+0xC80);
@@ -787,17 +834,21 @@
 		if (j == NR_PRODUCTS) {
 			printk(KERN_WARNING "cpqarray: Sorry, I don't know how"
 				" to access the SMART Array controller %08lx\n",				 (unsigned long)board_id);
+			free_hba(ctlr);
 			continue;
 		}
-		hba[nr_ctlr] = (ctlr_info_t *) kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
-		if(hba[nr_ctlr]==NULL)
+		memset(hba[ctlr], 0, sizeof(ctlr_info_t));
+		hba[ctlr]->io_mem_addr = eisa[i];
+		hba[ctlr]->io_mem_length = 0x7FF;		
+		if(!request_region( hba[ctlr]->io_mem_addr, 
+					hba[ctlr]->io_mem_length, 
+				"cpqarray"))
 		{
-			printk(KERN_ERR "cpqarray: out of memory.\n");
-			continue;
+			printk( KERN_WARNING "cpqarray: I/0 range already in use addr = %lx length=%ld\n",
+			 hba[ctlr]->io_mem_addr, hba[ctlr]->io_mem_length);
+			free_hba(ctlr);
+			continue;	
 		}
-		memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
-		hba[nr_ctlr]->ioaddr = eisa[i];
-
 		/*
 		 * Read the config register to find our interrupt
 		 */
@@ -807,13 +858,13 @@
 		else if (intr & 4) intr = 14;
 		else if (intr & 8) intr = 15;
 		
-		hba[nr_ctlr]->intr = intr;
-		sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
-		hba[nr_ctlr]->product_name = products[j].product_name;
-		hba[nr_ctlr]->access = *(products[j].access);
-		hba[nr_ctlr]->ctlr = nr_ctlr;
-		hba[nr_ctlr]->board_id = board_id;
-		hba[nr_ctlr]->pci_dev = NULL; /* not PCI */
+		hba[ctlr]->intr = intr;
+		sprintf(hba[ctlr]->devname, "ida%d", ctlr);
+		hba[ctlr]->product_name = products[j].product_name;
+		hba[ctlr]->access = *(products[j].access);
+		hba[ctlr]->ctlr = ctlr;
+		hba[ctlr]->board_id = board_id;
+		hba[ctlr]->pci_dev = NULL; /* not PCI */
 
 DBGINFO(
 	printk("i = %d, j = %d\n", i, j);
@@ -822,11 +873,11 @@
 	printk("board_id = %x\n", board_id);
 );
 
-		nr_ctlr++;
+		num_ctlr++;
 		i++;
 	}
 
-	return nr_ctlr;
+	return num_ctlr;
 }
 
 
@@ -842,8 +893,7 @@
 	if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
 		return -ENXIO;
 
-	if (!suser() && ida_sizes[(ctlr << CTLR_SHIFT) +
-						MINOR(inode->i_rdev)] == 0)
+	if (!suser() && hba[ctlr]->sizes[ MINOR(inode->i_rdev)] == 0)
 		return -ENXIO;
 
 	/*
@@ -853,7 +903,7 @@
 	 * for "raw controller".
 	 */
 	if (suser()
-		&& ida_sizes[(ctlr << CTLR_SHIFT) + MINOR(inode->i_rdev)] == 0 
+		&& hba[ctlr]->sizes[ MINOR(inode->i_rdev)] == 0 
 		&& MINOR(inode->i_rdev) != 0)
 		return -ENXIO;
 
@@ -934,7 +984,7 @@
 	if (creq->nr_segments > SG_MAX)
 		BUG();
 
-	if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR || h->ctlr > nr_ctlr)
+	if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR )
 	{
 		printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",
 				h->ctlr, creq->rq_dev, creq);
@@ -958,7 +1008,8 @@
 	c->hdr.size = sizeof(rblk_t) >> 2;
 	c->size += sizeof(rblk_t);
 
-	c->req.hdr.blk = ida[(h->ctlr<<CTLR_SHIFT) + MINOR(creq->rq_dev)].start_sect + creq->sector;
+	c->req.hdr.blk = hba[h->ctlr]->hd[MINOR(creq->rq_dev)].start_sect 
+				+ creq->sector;
 	c->rq = creq;
 DBGPX(
 	if (bh == NULL)
@@ -1187,33 +1238,61 @@
 	int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
 	int dsk  = MINOR(inode->i_rdev) >> NWD_SHIFT;
 	int error;
-	int diskinfo[4];
-	struct hd_geometry *geo = (struct hd_geometry *)arg;
 	ida_ioctl_t *io = (ida_ioctl_t*)arg;
 	ida_ioctl_t my_io;
 
 	switch(cmd) {
 	case HDIO_GETGEO:
+	{
+		struct hd_geometry driver_geo;
+
 		if (hba[ctlr]->drv[dsk].cylinders) {
-			diskinfo[0] = hba[ctlr]->drv[dsk].heads;
-			diskinfo[1] = hba[ctlr]->drv[dsk].sectors;
-			diskinfo[2] = hba[ctlr]->drv[dsk].cylinders;
+			driver_geo.heads = hba[ctlr]->drv[dsk].heads;
+			driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders;
 		} else {
-			diskinfo[0] = 0xff;
-			diskinfo[1] = 0x3f;
-			diskinfo[2] = hba[ctlr]->drv[dsk].nr_blks / (0xff*0x3f);
+			driver_geo.heads = 0xff;
+			driver_geo.sectors = 0x3f;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].nr_blks 
+							/ (0xff*0x3f);
 		}
-		put_user(diskinfo[0], &geo->heads);
-		put_user(diskinfo[1], &geo->sectors);
-		put_user(diskinfo[2], &geo->cylinders);
-		put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].start_sect, &geo->start);
-		return 0;
+		driver_geo.start=
+		hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect;
+		if (copy_to_user((void *) arg, &driver_geo,
+				sizeof( struct hd_geometry)))
+			return  -EFAULT;
+		return(0);
+	}
+	case HDIO_GETGEO_BIG:
+	{
+		struct hd_big_geometry driver_geo;
+
+		if (hba[ctlr]->drv[dsk].cylinders) {
+			driver_geo.heads = hba[ctlr]->drv[dsk].heads;
+			driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders;
+		} else {
+			driver_geo.heads = 0xff;
+			driver_geo.sectors = 0x3f;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].nr_blks 
+				/ (0xff*0x3f);
+		}
+		driver_geo.start=
+			hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect;
+		if (copy_to_user((void *) arg, &driver_geo,
+				sizeof( struct hd_big_geometry)))
+			return  -EFAULT;
+		return(0);
+	}
+
 	case IDAGETDRVINFO:
 		return copy_to_user(&io->c.drv,&hba[ctlr]->drv[dsk],sizeof(drv_info_t));
 	case BLKGETSIZE:
-		return put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
+		if (!arg) return -EINVAL;
+		return put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects, 
+			(unsigned long *)arg);
 	case BLKGETSIZE64:
-		return put_user((u64)(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects) << 9, (u64*)arg);
+		return put_user((u64)(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects) << 9, (u64*)arg);
 	case BLKRRPART:
 		return revalidate_logvol(inode->i_rdev, 1);
 	case IDAPASSTHRU:
@@ -1248,6 +1327,37 @@
 				return -EFAULT;
 		return(0);
 	}	
+	case IDADEREGDISK:
+			return( deregister_disk(ctlr,dsk));
+	case IDAREGNEWDISK:
+	{
+		int logvol = arg; 
+		return(register_new_disk(ctlr, logvol));
+	}	
+
+	case IDAGETLOGINFO:
+	{
+		idaLogvolInfo_struct luninfo;
+		int num_parts = 0;
+		int i, start;
+
+		luninfo.LogVolID = dsk; 
+		luninfo.num_opens = hba[ctlr]->drv[dsk].usage_count;
+
+		/* count partitions 1 to 15 with sizes > 0 */
+		start = (dsk << NWD_SHIFT); 	
+		for(i=1; i <IDA_MAX_PART; i++)
+		{
+			int minor = start+i;
+			if(hba[ctlr]->sizes[minor] != 0)
+				num_parts++;
+		}
+		luninfo.num_parts = num_parts;
+		if (copy_to_user((void *) arg, &luninfo, 
+			sizeof( idaLogvolInfo_struct) ))
+				return -EFAULT;
+		return(0);
+	}
 
 	case BLKFLSBUF:
 	case BLKBSZSET:
@@ -1587,15 +1697,18 @@
 
 	/*
 	 * Set the partition and block size structures for all volumes
-	 * on this controller to zero.  We will reread all of this data
+	 * on this controller to zero.  And set the hardsizes to non zero to 
+	 * avoid a possible divide by zero error.  
+	 * We will reread all of this data
 	 */
-	memset(ida+(ctlr*256),            0, sizeof(struct hd_struct)*NWD*16);
-	memset(ida_sizes+(ctlr*256),      0, sizeof(int)*NWD*16);
-	memset(ida_blocksizes+(ctlr*256), 0, sizeof(int)*NWD*16);
-	memset(ida_hardsizes+(ctlr*256),  0, sizeof(int)*NWD*16);
-	memset(hba[ctlr]->drv,            0, sizeof(drv_info_t)*NWD);
-	ida_gendisk[ctlr].nr_real = 0;
+	memset(hba[ctlr]->hd,         0, sizeof(struct hd_struct)*NWD*16);
+	memset(hba[ctlr]->sizes,      0, sizeof(int)*NWD*16);
+	memset(hba[ctlr]->blocksizes, 0, sizeof(int)*NWD*16);
+	memset(hba[ctlr]->drv,        0, sizeof(drv_info_t)*NWD);
+	hba[ctlr]->gendisk.nr_real = 0;
 
+	for(i=0;i<256;i++)
+                hba[ctlr]->hardsizes[i] = BLOCK_SIZE;
 	/*
 	 * Tell the array controller not to give us any interrupts while
 	 * we check the new geometry.  Then turn interrupts back on when
@@ -1607,13 +1720,257 @@
 
 	ida_geninit(ctlr);
 	for(i=0; i<NWD; i++)
-		if (ida_sizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)])
+		if (hba[ctlr]->sizes[i<<NWD_SHIFT])
 			revalidate_logvol(dev+(i<<NWD_SHIFT), 2);
 
 	hba[ctlr]->usage_count--;
 	return 0;
 }
 
+static int deregister_disk(int ctlr, int logvol)
+{
+	unsigned long flags;
+	struct gendisk *gdev = &(hba[ctlr]->gendisk); 
+	ctlr_info_t  *h = hba[ctlr];
+	int start, max_p, i;	
+
+
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	/* make sure logical volume is NOT is use */
+	if( h->drv[logvol].usage_count > 1)
+	{
+		spin_unlock_irqrestore(&io_request_lock, flags);
+                return -EBUSY;
+	}
+	h->drv[logvol].usage_count++;
+	spin_unlock_irqrestore(&io_request_lock, flags);
+
+	/* invalidate the devices and deregister the disk */ 
+	max_p = gdev->max_p;
+	start = logvol << gdev->minor_shift;
+	for (i=max_p-1; i>=0; i--)
+	{
+		int minor = start+i;
+		// printk("invalidating( %d %d)\n", ctlr, minor);
+		invalidate_device(MKDEV(MAJOR_NR+ctlr, minor), 1);
+		/* so open will now fail */
+		hba[ctlr]->sizes[minor] = 0;
+	}
+	/* check to see if it was the last disk */
+	if (logvol == h->highest_lun)
+	{
+		/* if so, find the new hightest lun */
+		int i, newhighest =-1;
+		for(i=0; i<h->highest_lun; i++)
+		{
+			/* if the disk has size > 0, it is available */
+			if (hba[ctlr]->sizes[i << gdev->minor_shift] != 0)
+				newhighest = i;
+		}
+		h->highest_lun = newhighest;
+				
+	}
+	--h->log_drives;
+	gdev->nr_real = h->highest_lun+1; 
+	/* zero out the disk size info */ 
+	h->drv[logvol].nr_blks = 0;
+	h->drv[logvol].blk_size = BLOCK_SIZE;
+	return(0);
+
+}
+
+static int sendcmd_withirq(
+	__u8	cmd,
+	int	ctlr,
+	void	*buff,
+	size_t	size,
+	unsigned int blk,
+	unsigned int blkcnt,
+	unsigned int log_unit )
+{
+	cmdlist_t *c;
+	unsigned long flags;
+	ctlr_info_t *info_p = hba[ctlr];
+
+	c = cmd_alloc(info_p, 0);
+	if(!c)
+		return IO_ERROR;
+	c->type = CMD_IOCTL_PEND;
+	c->ctlr = ctlr;
+	c->hdr.unit = log_unit;
+	c->hdr.prio = 0;
+	c->hdr.size = sizeof(rblk_t) >> 2;
+	c->size += sizeof(rblk_t);
+
+	/* The request information. */
+	c->req.hdr.next = 0;
+	c->req.hdr.rcode = 0;
+	c->req.bp = 0;
+	c->req.hdr.sg_cnt = 1;
+	c->req.hdr.reserved = 0;
+
+	if (size == 0)
+		c->req.sg[0].size = 512;
+	else
+		c->req.sg[0].size = size;
+
+	c->req.hdr.blk = blk;
+	c->req.hdr.blk_cnt = blkcnt;
+	c->req.hdr.cmd = (unsigned char) cmd;
+	c->req.sg[0].addr = (__u32) pci_map_single(info_p->pci_dev, 
+		buff, c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
+
+	/* Put the request on the tail of the request queue */
+	spin_lock_irqsave(&io_request_lock, flags);
+	addQ(&info_p->reqQ, c);
+	info_p->Qdepth++;
+	start_io(info_p);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+
+	/* Wait for completion */
+	while(c->type != CMD_IOCTL_DONE)
+		schedule();
+
+	if (c->req.hdr.rcode & RCODE_FATAL) {
+		printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
+				c->ctlr, c->hdr.unit);
+		cmd_free(info_p, c, 0);
+		return(IO_ERROR);
+	}
+	if (c->req.hdr.rcode & RCODE_INVREQ) {
+		printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
+				c->ctlr, c->hdr.unit, c->req.hdr.cmd,
+				c->req.hdr.blk, c->req.hdr.blk_cnt,
+				c->req.hdr.sg_cnt, c->req.hdr.rcode);
+		cmd_free(info_p, c, 0);
+		return(IO_ERROR);	
+	}
+	cmd_free(info_p, c, 0);
+	return(IO_OK);
+}
+
+static int register_new_disk(int ctlr, int logvol)
+{
+	struct gendisk *gdev = &(hba[ctlr]->gendisk);
+	ctlr_info_t *info_p = hba[ctlr];
+	int ret_code, size;
+	sense_log_drv_stat_t *id_lstatus_buf;
+	id_log_drv_t *id_ldrive;
+	drv_info_t *drv;
+	int max_p;
+	int start;
+	int i;	
+
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+	if( (logvol < 0) || (logvol >= IDA_MAX_PART))
+		return -EINVAL;
+	/* disk is already registered */
+	if(hba[ctlr]->sizes[logvol <<  gdev->minor_shift] != 0 )
+		return -EINVAL;
+
+	id_ldrive = (id_log_drv_t *)kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
+	if(id_ldrive == NULL)
+	{
+		printk( KERN_ERR "cpqarray:  out of memory.\n");
+		return -1;
+	}
+	id_lstatus_buf = (sense_log_drv_stat_t *)kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
+	if(id_lstatus_buf == NULL)
+	{
+		kfree(id_ldrive);
+		printk( KERN_ERR "cpqarray:  out of memory.\n");
+		return -1;
+	}
+
+	size = sizeof(sense_log_drv_stat_t);
+
+	/*
+		Send "Identify logical drive status" cmd
+	 */
+	ret_code = sendcmd_withirq(SENSE_LOG_DRV_STAT,
+		ctlr, id_lstatus_buf, size, 0, 0, logvol);
+	if (ret_code == IO_ERROR) 
+	{
+			/*
+			   If can't get logical drive status, set
+			   the logical drive map to 0, so the
+			   idastubopen will fail for all logical drives
+			   on the controller. 
+			 */
+			/* Free all the buffers and return */
+
+                kfree(id_lstatus_buf);
+                kfree(id_ldrive);
+                return -1;
+	}
+	/*
+		   Make sure the logical drive is configured
+	 */
+	if (id_lstatus_buf->status == LOG_NOT_CONF) 
+	{
+		printk(KERN_WARNING "cpqarray: c%dd%d array not configured\n",
+			ctlr, logvol); 
+		kfree(id_lstatus_buf);
+                kfree(id_ldrive);
+		return -1;
+	}
+	ret_code = sendcmd_withirq(ID_LOG_DRV, ctlr, id_ldrive,
+			       sizeof(id_log_drv_t), 0, 0, logvol);
+			/*
+			   If error, the bit for this
+			   logical drive won't be set and
+			   idastubopen will return error. 
+			 */
+	if (ret_code == IO_ERROR) 
+	{
+		printk(KERN_WARNING "cpqarray: c%dd%d unable to ID logical volume\n",
+			ctlr,logvol);
+		kfree(id_lstatus_buf);
+                kfree(id_ldrive);
+		return -1;
+	}
+	drv = &info_p->drv[logvol];
+	drv->blk_size = id_ldrive->blk_size;
+	drv->nr_blks = id_ldrive->nr_blks;
+	drv->cylinders = id_ldrive->drv.cyl;
+	drv->heads = id_ldrive->drv.heads;
+	drv->sectors = id_ldrive->drv.sect_per_track;
+	info_p->log_drv_map |=	(1 << logvol);
+	if (info_p->highest_lun < logvol)
+		info_p->highest_lun = logvol;
+
+	printk(KERN_INFO "cpqarray ida/c%dd%d: blksz=%d nr_blks=%d\n",
+		ctlr, logvol, drv->blk_size, drv->nr_blks);
+
+	hba[ctlr]->drv[logvol].usage_count = 0;	
+	
+	max_p = gdev->max_p;
+	start = logvol<< gdev->minor_shift;
+	
+	for(i=max_p-1; i>=0; i--) 
+	{
+		int minor = start+i;
+		invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
+		gdev->part[minor].start_sect = 0;
+		gdev->part[minor].nr_sects = 0;
+	
+		/* reset the blocksize so we can read the partition table */
+		blksize_size[MAJOR_NR+ctlr][minor] = 1024;
+	}
+	++hba[ctlr]->log_drives;
+	gdev->nr_real = info_p->highest_lun + 1;
+	/* setup partitions per disk */
+	grok_partitions(gdev, logvol, IDA_MAX_PART, drv->nr_blks); 
+	
+	kfree(id_lstatus_buf);
+        kfree(id_ldrive);
+	return (0);
+}
+
 /* Borrowed and adapted from sd.c */
 static int revalidate_logvol(kdev_t dev, int maxusage)
 {
@@ -1626,7 +1983,7 @@
 
 	target = DEVICE_NR(dev);
 	ctlr = MAJOR(dev) - MAJOR_NR;
-	gdev = &ida_gendisk[ctlr];
+	gdev = &(hba[ctlr]->gendisk);
 	
 	spin_lock_irqsave(&io_request_lock, flags);
 	if (hba[ctlr]->drv[target].usage_count > maxusage) {
@@ -1654,7 +2011,8 @@
 	}
 
 	/* 16 minors per disk... */
-	grok_partitions(gdev, target, 16, hba[ctlr]->drv[target].nr_blks);
+	grok_partitions(gdev, target, IDA_MAX_PART, 
+		hba[ctlr]->drv[target].nr_blks);
 	hba[ctlr]->drv[target].usage_count--;
 	return 0;
 }
@@ -1813,7 +2171,7 @@
 	/*
 	 * Get drive geometry for all logical drives
 	 */
-	if (id_ctlr_buf->nr_drvs > 16)
+	if (id_ctlr_buf->nr_drvs > IDA_MAX_PART)
 		printk(KERN_WARNING "cpqarray ida%d:  This driver supports "
 			"16 logical drives per controller.\n.  "
 			" Additional drives will not be "
@@ -1887,14 +2245,8 @@
                 			return;
 
 				}
-				if (!de_arr[ctlr][log_unit]) {
-					char txt[16];
-
-					sprintf(txt, "ida/c%dd%d", ctlr,
-						log_unit);
-					de_arr[ctlr][log_unit] =
-						devfs_mk_dir(NULL, txt, NULL);
-				}
+				if(log_unit > info_p->highest_lun)
+					info_p->highest_lun = log_unit;
 				info_p->phys_drives =
 				    sense_config_buf->ctlr_phys_drv;
 				info_p->drv_assign_map
@@ -1914,3 +2266,26 @@
 	return;
 
 }
+
+static void __exit cleanup_cpqarray_module(void)
+{
+        int i;
+
+        pci_unregister_driver(&cpqarray_pci_driver);
+        /* double check that all controller entrys have been removed */
+        for (i=0; i< MAX_CTLR; i++)
+        {
+                if (hba[i] != NULL)
+                {
+                        printk(KERN_WARNING "cpqarray: had to remove"
+                                        " controller %d\n", i);
+                        cpqarray_remove_one_eisa(i);
+                }
+        }
+        remove_proc_entry("cpqarray", proc_root_driver);
+}
+
+
+module_init(init_cpqarray_module);
+module_exit(cleanup_cpqarray_module);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/cpqarray.h linux/drivers/block/cpqarray.h
--- linux.orig/drivers/block/cpqarray.h	2001-05-22 17:23:16.000000000 +0000
+++ linux/drivers/block/cpqarray.h	2002-07-20 01:08:38.000000000 +0000
@@ -39,6 +39,7 @@
 #define IO_ERROR	1
 #define NWD		16
 #define NWD_SHIFT	4
+#define IDA_MAX_PART	16
 
 #define IDA_TIMER	(5*HZ)
 #define IDA_TIMEOUT	(10*HZ)
@@ -87,9 +88,11 @@
 	__u32	mp_failed_drv_map;
 
 	char	firm_rev[4];
+	struct pci_dev *pdev;
 	int	ctlr_sig;
 
 	int	log_drives;
+	int	highest_lun;
 	int	phys_drives;
 
 	struct pci_dev *pci_dev;    /* NULL if EISA */
@@ -98,7 +101,8 @@
 
 	void *vaddr;
 	unsigned long paddr;
-	unsigned long ioaddr;
+	unsigned long io_mem_addr;
+	unsigned long io_mem_length;	
 	int	intr;
 	int	usage_count;
 	drv_info_t	drv[NWD];
@@ -120,6 +124,13 @@
 	unsigned int nr_frees;
 	struct timer_list timer;
 	unsigned int misc_tflags;
+	// Disk structures we need to pass back
+	struct gendisk gendisk;
+	// Index by Minor Numbers
+	struct hd_struct	hd[256];
+	int			sizes[256];
+	int			blocksizes[256];
+	int			hardsizes[256];
 };
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/floppy.c linux/drivers/block/floppy.c
--- linux.orig/drivers/block/floppy.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/block/floppy.c	2002-07-20 01:08:26.000000000 +0000
@@ -129,6 +129,12 @@
  * floppy controller (lingering task on list after module is gone... boom.)
  */
 
+/*
+ * 2002/02/07 -- Anton Altaparmakov - Fix io ports reservation to correct range
+ * (0x3f2-0x3f5, 0x3f7). This fix is a bit of a hack but the proper fix
+ * requires many non-obvious changes in arch dependent code.
+ */
+
 #define FLOPPY_SANITY_CHECK
 #undef  FLOPPY_SILENT_DCL_CLEAR
 
@@ -4181,9 +4187,12 @@
 		CLEARSTRUCT(FDCS);
 		FDCS->dtr = -1;
 		FDCS->dor = 0x4;
-#ifdef __sparc__
-		/*sparcs don't have a DOR reset which we can fall back on to*/
-		FDCS->version = FDC_82072A;
+#if defined(__sparc__) || defined(__mc68000__)
+		/*sparcs/sun3x don't have a DOR reset which we can fall back on to*/
+#ifdef __mc68000__
+		if(MACH_IS_SUN3X)
+#endif
+			FDCS->version = FDC_82072A;		
 #endif
 	}
 
@@ -4229,7 +4238,7 @@
 		FDCS->rawcmd = 2;
 		if (user_reset_fdc(-1,FD_RESET_ALWAYS,0)){
  			/* free ioports reserved by floppy_grab_irq_and_dma() */
- 			release_region(FDCS->address, 6);
+ 			release_region(FDCS->address+2, 4);
  			release_region(FDCS->address+7, 1);
 			FDCS->address = -1;
 			FDCS->version = FDC_NONE;
@@ -4239,7 +4248,7 @@
 		FDCS->version = get_fdc_version();
 		if (FDCS->version == FDC_NONE){
  			/* free ioports reserved by floppy_grab_irq_and_dma() */
- 			release_region(FDCS->address, 6);
+ 			release_region(FDCS->address+2, 4);
  			release_region(FDCS->address+7, 1);
 			FDCS->address = -1;
 			continue;
@@ -4318,11 +4327,11 @@
 
 	for (fdc=0; fdc< N_FDC; fdc++){
 		if (FDCS->address != -1){
-			if (!request_region(FDCS->address, 6, "floppy")) {
-				DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address);
+			if (!request_region(FDCS->address+2, 4, "floppy")) {
+				DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + 2);
 				goto cleanup1;
 			}
-			if (!request_region(FDCS->address + 7, 1, "floppy DIR")) {
+			if (!request_region(FDCS->address+7, 1, "floppy DIR")) {
 				DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + 7);
 				goto cleanup2;
 			}
@@ -4350,12 +4359,12 @@
 	irqdma_allocated = 1;
 	return 0;
 cleanup2:
-	release_region(FDCS->address, 6);
+	release_region(FDCS->address + 2, 4);
 cleanup1:
 	fd_free_irq();
 	fd_free_dma();
 	while(--fdc >= 0) {
-		release_region(FDCS->address, 6);
+		release_region(FDCS->address + 2, 4);
 		release_region(FDCS->address + 7, 1);
 	}
 	MOD_DEC_USE_COUNT;
@@ -4422,7 +4431,7 @@
 	old_fdc = fdc;
 	for (fdc = 0; fdc < N_FDC; fdc++)
 		if (FDCS->address != -1) {
-			release_region(FDCS->address, 6);
+			release_region(FDCS->address+2, 4);
 			release_region(FDCS->address+7, 1);
 		}
 	fdc = old_fdc;
@@ -4481,22 +4490,6 @@
 
 __setup ("floppy=", floppy_setup);
 
-/* eject the boot floppy (if we need the drive for a different root floppy) */
-/* This should only be called at boot time when we're sure that there's no
- * resource contention. */
-void floppy_eject(void)
-{
-	int dummy;
-	if (have_no_fdc)
-		return;
-	if(floppy_grab_irq_and_dma()==0)
-	{
-		lock_fdc(MAXTIMEOUT,0);
-		dummy=fd_eject(0);
-		process_fd_request();
-		floppy_release_irq_and_dma();
-	}
-}
 #endif
 
 EXPORT_NO_SYMBOLS;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/genhd.c linux/drivers/block/genhd.c
--- linux.orig/drivers/block/genhd.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/block/genhd.c	2002-07-20 01:08:36.000000000 +0000
@@ -130,25 +130,52 @@
 EXPORT_SYMBOL(get_gendisk);
 
 
+/**
+ * walk_gendisk - issue a command for every registered gendisk
+ * @walk: user-specified callback
+ * @data: opaque data for the callback
+ *
+ * This function walks through the gendisk chain and calls back
+ * into @walk for every element.
+ */
+int
+walk_gendisk(int (*walk)(struct gendisk *, void *), void *data)
+{
+	struct gendisk *gp;
+	int error = 0;
+
+	read_lock(&gendisk_lock);
+	for (gp = gendisk_head; gp; gp = gp->next)
+		if ((error = walk(gp, data)))
+			break;
+	read_unlock(&gendisk_lock);
+
+	return error;
+}
+
+
 #ifdef CONFIG_PROC_FS
 int
 get_partition_list(char *page, char **start, off_t offset, int count)
 {
 	struct gendisk *gp;
+	struct hd_struct *hd;
 	char buf[64];
 	int len, n;
 
 	len = sprintf(page, "major minor  #blocks  name\n\n");
+		
 	read_lock(&gendisk_lock);
 	for (gp = gendisk_head; gp; gp = gp->next) {
 		for (n = 0; n < (gp->nr_real << gp->minor_shift); n++) {
 			if (gp->part[n].nr_sects == 0)
 				continue;
 
-			len += snprintf(page + len, 63,
-					"%4d  %4d %10d %s\n",
-					gp->major, n, gp->sizes[n],
-					disk_name(gp, n, buf));
+			hd = &gp->part[n]; disk_round_stats(hd);
+			len += sprintf(page + len,
+				"%4d  %4d %10d %s\n", gp->major,
+				n, gp->sizes[n], disk_name(gp, n, buf));
+
 			if (len < offset)
 				offset -= len, len = 0;
 			else if (len >= offset + count)
@@ -168,34 +195,15 @@
 
 
 extern int blk_dev_init(void);
-#ifdef CONFIG_FUSION_BOOT
-extern int fusion_init(void);
-#endif
 extern int net_dev_init(void);
 extern void console_map_init(void);
-extern int soc_probe(void);
 extern int atmdev_init(void);
-extern int i2o_init(void);
-extern int cpqarray_init(void);
 
 int __init device_init(void)
 {
 	rwlock_init(&gendisk_lock);
 	blk_dev_init();
 	sti();
-#ifdef CONFIG_I2O
-	i2o_init();
-#endif
-#ifdef CONFIG_FUSION_BOOT
-	fusion_init();
-#endif
-#ifdef CONFIG_FC4_SOC
-	/* This has to be done before scsi_dev_init */
-	soc_probe();
-#endif
-#ifdef CONFIG_BLK_CPQ_DA
-	cpqarray_init();
-#endif
 #ifdef CONFIG_NET
 	net_dev_init();
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/ida_ioctl.h linux/drivers/block/ida_ioctl.h
--- linux.orig/drivers/block/ida_ioctl.h	2001-07-25 21:12:01.000000000 +0000
+++ linux/drivers/block/ida_ioctl.h	2002-07-20 01:08:36.000000000 +0000
@@ -31,6 +31,9 @@
 #define IDAREVALIDATEVOLS	0x30303131
 #define IDADRIVERVERSION	0x31313232
 #define IDAGETPCIINFO		0x32323333
+#define IDADEREGDISK		0x33333434
+#define IDAREGNEWDISK		0x34343535
+#define IDAGETLOGINFO		0x35353636
 
 typedef struct _ida_pci_info_struct
 {
@@ -38,6 +41,13 @@
 	unsigned char 	dev_fn;
 	__u32 		board_id;
 } ida_pci_info_struct;
+
+typedef struct _idaLogvolInfo_struct{
+int		LogVolID;
+int		num_opens;  /* number of opens on the logical volume */
+int		num_parts;  /* number of partitions configured on logvol */
+} idaLogvolInfo_struct;
+
 /*
  * Normally, the ioctl determines the logical unit for this command by
  * the major,minor number of the fd passed to ioctl.  If you need to send
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux.orig/drivers/block/ll_rw_blk.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/block/ll_rw_blk.c	2002-07-20 01:08:25.000000000 +0000
@@ -117,12 +117,6 @@
  */
 int * max_sectors[MAX_BLKDEV];
 
-/*
- * How many reqeusts do we allocate per queue,
- * and how many do we "batch" on freeing them?
- */
-static int queue_nr_requests, batch_requests;
-
 static inline int get_max_sectors(kdev_t dev)
 {
 	if (!max_sectors[MAJOR(dev)])
@@ -176,7 +170,7 @@
  **/
 void blk_cleanup_queue(request_queue_t * q)
 {
-	int count = queue_nr_requests;
+	int count = q->nr_requests;
 
 	count -= __blk_cleanup_queue(&q->rq[READ]);
 	count -= __blk_cleanup_queue(&q->rq[WRITE]);
@@ -326,33 +320,70 @@
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
+/** blk_grow_request_list
+ *  @q: The &request_queue_t
+ *  @nr_requests: how many requests are desired
+ *
+ * More free requests are added to the queue's free lists, bringing
+ * the total number of requests to @nr_requests.
+ *
+ * The requests are added equally to the request queue's read
+ * and write freelists.
+ *
+ * This function can sleep.
+ *
+ * Returns the (new) number of requests which the queue has available.
+ */
+int blk_grow_request_list(request_queue_t *q, int nr_requests)
+{
+	unsigned long flags;
+	/* Several broken drivers assume that this function doesn't sleep,
+	 * this causes system hangs during boot.
+	 * As a temporary fix, make the the function non-blocking.
+	 */
+	spin_lock_irqsave(&io_request_lock, flags);
+	while (q->nr_requests < nr_requests) {
+		struct request *rq;
+		int rw;
+
+		rq = kmem_cache_alloc(request_cachep, SLAB_ATOMIC);
+		if (rq == NULL)
+			break;
+		memset(rq, 0, sizeof(*rq));
+		rq->rq_status = RQ_INACTIVE;
+		rw = q->nr_requests & 1;
+		list_add(&rq->queue, &q->rq[rw].free);
+		q->rq[rw].count++;
+		q->nr_requests++;
+	}
+	q->batch_requests = q->nr_requests / 4;
+	if (q->batch_requests > 32)
+		q->batch_requests = 32;
+	spin_unlock_irqrestore(&io_request_lock, flags);
+	return q->nr_requests;
+}
+
 static void blk_init_free_list(request_queue_t *q)
 {
-	struct request *rq;
-	int i;
+	struct sysinfo si;
+	int megs;		/* Total memory, in megabytes */
+	int nr_requests;
 
 	INIT_LIST_HEAD(&q->rq[READ].free);
 	INIT_LIST_HEAD(&q->rq[WRITE].free);
 	q->rq[READ].count = 0;
 	q->rq[WRITE].count = 0;
+	q->nr_requests = 0;
 
-	/*
-	 * Divide requests in half between read and write
-	 */
-	for (i = 0; i < queue_nr_requests; i++) {
-		rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL);
-		if (rq == NULL) {
-			/* We'll get a `leaked requests' message from blk_cleanup_queue */
-			printk(KERN_EMERG "blk_init_free_list: error allocating requests\n");
-			break;
-		}
-		memset(rq, 0, sizeof(struct request));
-		rq->rq_status = RQ_INACTIVE;
-		list_add(&rq->queue, &q->rq[i&1].free);
-		q->rq[i&1].count++;
-	}
+	si_meminfo(&si);
+	megs = si.totalram >> (20 - PAGE_SHIFT);
+	nr_requests = 128;
+	if (megs < 32)
+		nr_requests /= 2;
+	blk_grow_request_list(q, nr_requests);
 
-	init_waitqueue_head(&q->wait_for_request);
+	init_waitqueue_head(&q->wait_for_requests[0]);
+	init_waitqueue_head(&q->wait_for_requests[1]);
 	spin_lock_init(&q->queue_lock);
 }
 
@@ -418,9 +449,9 @@
 #define blkdev_free_rq(list) list_entry((list)->next, struct request, queue);
 /*
  * Get a free request. io_request_lock must be held and interrupts
- * disabled on the way in.
+ * disabled on the way in.  Returns NULL if there are no free requests.
  */
-static inline struct request *get_request(request_queue_t *q, int rw)
+static struct request *get_request(request_queue_t *q, int rw)
 {
 	struct request *rq = NULL;
 	struct request_list *rl = q->rq + rw;
@@ -430,6 +461,7 @@
 		list_del(&rq->queue);
 		rl->count--;
 		rq->rq_status = RQ_ACTIVE;
+		rq->cmd = rw;
 		rq->special = NULL;
 		rq->q = q;
 	}
@@ -438,40 +470,84 @@
 }
 
 /*
- * No available requests for this queue, unplug the device.
+ * Here's the request allocation design:
+ *
+ * 1: Blocking on request exhaustion is a key part of I/O throttling.
+ * 
+ * 2: We want to be `fair' to all requesters.  We must avoid starvation, and
+ *    attempt to ensure that all requesters sleep for a similar duration.  Hence
+ *    no stealing requests when there are other processes waiting.
+ * 
+ * 3: We also wish to support `batching' of requests.  So when a process is
+ *    woken, we want to allow it to allocate a decent number of requests
+ *    before it blocks again, so they can be nicely merged (this only really
+ *    matters if the process happens to be adding requests near the head of
+ *    the queue).
+ * 
+ * 4: We want to avoid scheduling storms.  This isn't really important, because
+ *    the system will be I/O bound anyway.  But it's easy.
+ * 
+ *    There is tension between requirements 2 and 3.  Once a task has woken,
+ *    we don't want to allow it to sleep as soon as it takes its second request.
+ *    But we don't want currently-running tasks to steal all the requests
+ *    from the sleepers.  We handle this with wakeup hysteresis around
+ *    0 .. batch_requests and with the assumption that request taking is much,
+ *    much faster than request freeing.
+ * 
+ * So here's what we do:
+ * 
+ *    a) A READA requester fails if free_requests < batch_requests
+ * 
+ *       We don't want READA requests to prevent sleepers from ever
+ *       waking.  Note that READA is used extremely rarely - a few
+ *       filesystems use it for directory readahead.
+ * 
+ *  When a process wants a new request:
+ * 
+ *    b) If free_requests == 0, the requester sleeps in FIFO manner.
+ * 
+ *    b) If 0 <  free_requests < batch_requests and there are waiters,
+ *       we still take a request non-blockingly.  This provides batching.
+ *
+ *    c) If free_requests >= batch_requests, the caller is immediately
+ *       granted a new request.
+ * 
+ *  When a request is released:
+ * 
+ *    d) If free_requests < batch_requests, do nothing.
+ * 
+ *    f) If free_requests >= batch_requests, wake up a single waiter.
+ * 
+ *   The net effect is that when a process is woken at the batch_requests level,
+ *   it will be able to take approximately (batch_requests) requests before
+ *   blocking again (at the tail of the queue).
+ * 
+ *   This all assumes that the rate of taking requests is much, much higher
+ *   than the rate of releasing them.  Which is very true.
+ *
+ * -akpm, Feb 2002.
  */
+
 static struct request *__get_request_wait(request_queue_t *q, int rw)
 {
 	register struct request *rq;
 	DECLARE_WAITQUEUE(wait, current);
 
 	generic_unplug_device(q);
-	add_wait_queue(&q->wait_for_request, &wait);
+	add_wait_queue_exclusive(&q->wait_for_requests[rw], &wait);
 	do {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		if (q->rq[rw].count < batch_requests)
+		if (q->rq[rw].count == 0)
 			schedule();
 		spin_lock_irq(&io_request_lock);
 		rq = get_request(q,rw);
 		spin_unlock_irq(&io_request_lock);
 	} while (rq == NULL);
-	remove_wait_queue(&q->wait_for_request, &wait);
+	remove_wait_queue(&q->wait_for_requests[rw], &wait);
 	current->state = TASK_RUNNING;
 	return rq;
 }
 
-static inline struct request *get_request_wait(request_queue_t *q, int rw)
-{
-	register struct request *rq;
-
-	spin_lock_irq(&io_request_lock);
-	rq = get_request(q, rw);
-	spin_unlock_irq(&io_request_lock);
-	if (rq)
-		return rq;
-	return __get_request_wait(q, rw);
-}
-
 /* RO fail safe mechanism */
 
 static long ro_bits[MAX_BLKDEV][8];
@@ -518,6 +594,119 @@
 		printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
 }
 
+/* Return up to two hd_structs on which to do IO accounting for a given
+ * request.  On a partitioned device, we want to account both against
+ * the partition and against the whole disk.  */
+static void locate_hd_struct(struct request *req, 
+			     struct hd_struct **hd1,
+			     struct hd_struct **hd2)
+{
+	struct gendisk *gd;
+
+	*hd1 = NULL;
+	*hd2 = NULL;
+	
+	gd = get_gendisk(req->rq_dev);
+	if (gd && gd->part) {
+		/* Mask out the partition bits: account for the entire disk */
+		int devnr = MINOR(req->rq_dev) >> gd->minor_shift;
+		int whole_minor = devnr << gd->minor_shift;
+		*hd1 = &gd->part[whole_minor];
+		if (whole_minor != MINOR(req->rq_dev))
+			*hd2= &gd->part[MINOR(req->rq_dev)];
+	}
+}
+
+/* Round off the performance stats on an hd_struct.  The average IO
+ * queue length and utilisation statistics are maintained by observing
+ * the current state of the queue length and the amount of time it has
+ * been in this state for.  Normally, that accounting is done on IO
+ * completion, but that can result in more than a second's worth of IO
+ * being accounted for within any one second, leading to >100%
+ * utilisation.  To deal with that, we do a round-off before returning
+ * the results when reading /proc/partitions, accounting immediately for
+ * all queue usage up to the current jiffies and restarting the counters
+ * again. */
+void disk_round_stats(struct hd_struct *hd)
+{
+	unsigned long now = jiffies;
+	
+	hd->aveq += (hd->ios_in_flight * (jiffies - hd->last_queue_change));
+	hd->last_queue_change = now;
+
+	if (hd->ios_in_flight)
+		hd->io_ticks += (now - hd->last_idle_time);
+	hd->last_idle_time = now;	
+}
+
+
+static inline void down_ios(struct hd_struct *hd)
+{
+	disk_round_stats(hd);	
+	--hd->ios_in_flight;
+}
+
+static inline void up_ios(struct hd_struct *hd)
+{
+	disk_round_stats(hd);
+	++hd->ios_in_flight;
+}
+
+static void account_io_start(struct hd_struct *hd, struct request *req,
+			     int merge, int sectors)
+{
+	switch (req->cmd) {
+	case READ:
+		if (merge)
+			hd->rd_merges++;
+		hd->rd_sectors += sectors;
+		break;
+	case WRITE:
+		if (merge)
+			hd->wr_merges++;
+		hd->wr_sectors += sectors;
+		break;
+	}
+	if (!merge)
+		up_ios(hd);
+}
+
+static void account_io_end(struct hd_struct *hd, struct request *req)
+{
+	unsigned long duration = jiffies - req->start_time;
+	switch (req->cmd) {
+	case READ:
+		hd->rd_ticks += duration;
+		hd->rd_ios++;
+		break;
+	case WRITE:
+		hd->wr_ticks += duration;
+		hd->wr_ios++;
+		break;
+	}
+	down_ios(hd);
+}
+
+void req_new_io(struct request *req, int merge, int sectors)
+{
+	struct hd_struct *hd1, *hd2;
+	locate_hd_struct(req, &hd1, &hd2);
+	if (hd1)
+		account_io_start(hd1, req, merge, sectors);
+	if (hd2)
+		account_io_start(hd2, req, merge, sectors);
+}
+
+void req_finished_io(struct request *req)
+{
+	struct hd_struct *hd1, *hd2;
+	locate_hd_struct(req, &hd1, &hd2);
+	if (hd1)
+		account_io_end(hd1, req);
+	if (hd2)	
+		account_io_end(hd2, req);
+}
+
 /*
  * add-request adds a request to the linked list.
  * io_request_lock is held and interrupts disabled, as we muck with the
@@ -546,7 +735,7 @@
 /*
  * Must be called with io_request_lock held and interrupts disabled
  */
-inline void blkdev_release_request(struct request *req)
+void blkdev_release_request(struct request *req)
 {
 	request_queue_t *q = req->q;
 	int rw = req->cmd;
@@ -560,8 +749,9 @@
 	 */
 	if (q) {
 		list_add(&req->queue, &q->rq[rw].free);
-		if (++q->rq[rw].count >= batch_requests && waitqueue_active(&q->wait_for_request))
-			wake_up(&q->wait_for_request);
+		if (++q->rq[rw].count >= q->batch_requests &&
+				waitqueue_active(&q->wait_for_requests[rw]))
+			wake_up(&q->wait_for_requests[rw]);
 	}
 }
 
@@ -574,6 +764,7 @@
 			  int max_segments)
 {
 	struct request *next;
+	struct hd_struct *hd1, *hd2;
   
 	next = blkdev_next_request(req);
 	if (req->sector + req->nr_sectors != next->sector)
@@ -597,6 +788,15 @@
 	req->bhtail = next->bhtail;
 	req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors;
 	list_del(&next->queue);
+
+	/* One last thing: we have removed a request, so we now have one
+	   less expected IO to complete for accounting purposes. */
+
+	locate_hd_struct(req, &hd1, &hd2);
+	if (hd1)
+		down_ios(hd1);
+	if (hd2)	
+		down_ios(hd2);
 	blkdev_release_request(next);
 }
 
@@ -704,6 +904,7 @@
 			req->nr_sectors = req->hard_nr_sectors += count;
 			blk_started_io(count);
 			drive_stat_acct(req->rq_dev, req->cmd, count, 0);
+			req_new_io(req, 1, count);
 			attempt_back_merge(q, req, max_sectors, max_segments);
 			goto out;
 
@@ -721,6 +922,7 @@
 			req->nr_sectors = req->hard_nr_sectors += count;
 			blk_started_io(count);
 			drive_stat_acct(req->rq_dev, req->cmd, count, 0);
+			req_new_io(req, 1, count);
 			attempt_front_merge(q, head, req, max_sectors, max_segments);
 			goto out;
 
@@ -742,22 +944,30 @@
 			BUG();
 	}
 		
-	/*
-	 * Grab a free request from the freelist - if that is empty, check
-	 * if we are doing read ahead and abort instead of blocking for
-	 * a free slot.
-	 */
 get_rq:
 	if (freereq) {
 		req = freereq;
 		freereq = NULL;
-	} else if ((req = get_request(q, rw)) == NULL) {
-		spin_unlock_irq(&io_request_lock);
-		if (rw_ahead)
-			goto end_io;
-
-		freereq = __get_request_wait(q, rw);
-		goto again;
+	} else {
+		/*
+		 * See description above __get_request_wait()
+		 */
+		if (rw_ahead) {
+			if (q->rq[rw].count < q->batch_requests) {
+				spin_unlock_irq(&io_request_lock);
+				goto end_io;
+			}
+			req = get_request(q, rw);
+			if (req == NULL)
+				BUG();
+		} else {
+			req = get_request(q, rw);
+			if (req == NULL) {
+				spin_unlock_irq(&io_request_lock);
+				freereq = __get_request_wait(q, rw);
+				goto again;
+			}
+		}
 	}
 
 /* fill up the request-info, and add it to the queue */
@@ -774,6 +984,8 @@
 	req->bh = bh;
 	req->bhtail = bh;
 	req->rq_dev = bh->b_rdev;
+	req->start_time = jiffies;
+	req_new_io(req, 0, count);
 	blk_started_io(count);
 	add_request(q, req, insert_here);
 out:
@@ -899,6 +1111,7 @@
 		BUG();
 
 	set_bit(BH_Req, &bh->b_state);
+	set_bit(BH_Launder, &bh->b_state);
 
 	/*
 	 * First step, 'identity mapping' - RAID or LVM might
@@ -1086,16 +1299,14 @@
 {
 	if (req->waiting != NULL)
 		complete(req->waiting);
+	req_finished_io(req);
 
 	blkdev_release_request(req);
 }
 
-#define MB(kb)	((kb) << 10)
-
 int __init blk_dev_init(void)
 {
 	struct blk_dev_struct *dev;
-	int total_ram;
 
 	request_cachep = kmem_cache_create("blkdev_requests",
 					   sizeof(struct request),
@@ -1111,31 +1322,12 @@
 	memset(max_readahead, 0, sizeof(max_readahead));
 	memset(max_sectors, 0, sizeof(max_sectors));
 
-	total_ram = nr_free_pages() << (PAGE_SHIFT - 10);
-
-	/*
-	 * Free request slots per queue.
-	 * (Half for reads, half for writes)
-	 */
-	queue_nr_requests = 64;
-	if (total_ram > MB(32))
-		queue_nr_requests = 128;
-
-	/*
-	 * Batch frees according to queue length
-	 */
-	batch_requests = queue_nr_requests/4;
-	printk("block: %d slots per queue, batch=%d\n", queue_nr_requests, batch_requests);
-
 #ifdef CONFIG_AMIGA_Z2RAM
 	z2_init();
 #endif
 #ifdef CONFIG_STRAM_SWAP
 	stram_device_init();
 #endif
-#ifdef CONFIG_BLK_DEV_RAM
-	rd_init();
-#endif
 #ifdef CONFIG_ISP16_CDI
 	isp16_init();
 #endif
@@ -1237,6 +1429,7 @@
 EXPORT_SYMBOL(io_request_lock);
 EXPORT_SYMBOL(end_that_request_first);
 EXPORT_SYMBOL(end_that_request_last);
+EXPORT_SYMBOL(blk_grow_request_list);
 EXPORT_SYMBOL(blk_init_queue);
 EXPORT_SYMBOL(blk_get_queue);
 EXPORT_SYMBOL(blk_cleanup_queue);
@@ -1244,4 +1437,5 @@
 EXPORT_SYMBOL(blk_queue_make_request);
 EXPORT_SYMBOL(generic_make_request);
 EXPORT_SYMBOL(blkdev_release_request);
+EXPORT_SYMBOL(req_finished_io);
 EXPORT_SYMBOL(generic_unplug_device);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/loop.c linux/drivers/block/loop.c
--- linux.orig/drivers/block/loop.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/drivers/block/loop.c	2002-07-20 01:08:23.000000000 +0000
@@ -36,6 +36,9 @@
  * Al Viro too.
  * Jens Axboe <axboe@suse.de>, Nov 2000
  *
+ * Support up to 256 loop devices
+ * Heinz Mauelshagen <mge@sistina.com>, Feb 2002
+ *
  * Still To Fix:
  * - Advisory locking is ignored here. 
  * - Should use an own CAP_* category instead of CAP_SYS_ADMIN 
@@ -965,7 +968,7 @@
  * And now the modules code and kernel interface.
  */
 MODULE_PARM(max_loop, "i");
-MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-255)");
+MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)");
 MODULE_LICENSE("GPL");
 
 int loop_register_transfer(struct loop_func_table *funcs)
@@ -1001,9 +1004,9 @@
 {
 	int	i;
 
-	if ((max_loop < 1) || (max_loop > 255)) {
+	if ((max_loop < 1) || (max_loop > 256)) {
 		printk(KERN_WARNING "loop: invalid max_loop (must be between"
-				    " 1 and 255), using default (8)\n");
+				    " 1 and 256), using default (8)\n");
 		max_loop = 8;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/nbd.c linux/drivers/block/nbd.c
--- linux.orig/drivers/block/nbd.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/drivers/block/nbd.c	2002-07-20 01:08:28.000000000 +0000
@@ -24,6 +24,8 @@
  * 01-3-11 Make nbd work with new Linux block layer code. It now supports
  *   plugging like all the other block devices. Also added in MSG_MORE to
  *   reduce number of partial TCP segments sent. <steve@chygwyn.com>
+ * 01-12-6 Fix deadlock condition by making queue locks independant of
+ *   the transmit lock. <steve@chygwyn.com>
  *
  * possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall
  * why not: would need verify_area and friends, would share yet another 
@@ -146,11 +148,12 @@
 
 #define FAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); goto error_out; }
 
-void nbd_send_req(struct socket *sock, struct request *req)
+void nbd_send_req(struct nbd_device *lo, struct request *req)
 {
 	int result;
 	struct nbd_request request;
 	unsigned long size = req->nr_sectors << 9;
+	struct socket *sock = lo->sock;
 
 	DEBUG("NBD: sending control, ");
 	request.magic = htonl(NBD_REQUEST_MAGIC);
@@ -159,6 +162,8 @@
 	request.len = htonl(size);
 	memcpy(request.handle, &req, sizeof(req));
 
+	down(&lo->tx_lock);
+
 	result = nbd_xmit(1, sock, (char *) &request, sizeof(request), req->cmd == WRITE ? MSG_MORE : 0);
 	if (result <= 0)
 		FAIL("Sendmsg failed for control.");
@@ -173,30 +178,51 @@
 			bh = bh->b_reqnext;
 		} while(bh);
 	}
+	up(&lo->tx_lock);
 	return;
 
-      error_out:
+error_out:
+	up(&lo->tx_lock);
 	req->errors++;
 }
 
+static struct request *nbd_find_request(struct nbd_device *lo, char *handle)
+{
+	struct request *req;
+	struct list_head *tmp;
+	struct request *xreq;
+
+	memcpy(&xreq, handle, sizeof(xreq));
+
+	spin_lock(&lo->queue_lock);
+	list_for_each(tmp, &lo->queue_head) {
+		req = list_entry(tmp, struct request, queue);
+		if (req != xreq)
+			continue;
+		list_del(&req->queue);
+		spin_unlock(&lo->queue_lock);
+		return req;
+	}
+	spin_unlock(&lo->queue_lock);
+	return NULL;
+}
+
 #define HARDFAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); lo->harderror = result; return NULL; }
 struct request *nbd_read_stat(struct nbd_device *lo)
 		/* NULL returned = something went wrong, inform userspace       */ 
 {
 	int result;
 	struct nbd_reply reply;
-	struct request *xreq, *req;
+	struct request *req;
 
 	DEBUG("reading control, ");
 	reply.magic = 0;
 	result = nbd_xmit(0, lo->sock, (char *) &reply, sizeof(reply), MSG_WAITALL);
 	if (result <= 0)
 		HARDFAIL("Recv control failed.");
-	memcpy(&xreq, reply.handle, sizeof(xreq));
-	req = blkdev_entry_prev_request(&lo->queue_head);
-
-	if (xreq != req)
-		FAIL("Unexpected handle received.\n");
+	req = nbd_find_request(lo, reply.handle);
+	if (req == NULL)
+		HARDFAIL("Unexpected reply");
 
 	DEBUG("ok, ");
 	if (ntohl(reply.magic) != NBD_REPLY_MAGIC)
@@ -226,20 +252,14 @@
 {
 	struct request *req;
 
-	down (&lo->queue_lock);
 	while (1) {
-		up (&lo->queue_lock);
 		req = nbd_read_stat(lo);
-		down (&lo->queue_lock);
 
 		if (!req) {
 			printk(KERN_ALERT "req should never be null\n" );
 			goto out;
 		}
 #ifdef PARANOIA
-		if (req != blkdev_entry_prev_request(&lo->queue_head)) {
-			printk(KERN_ALERT "NBD: I have problem...\n");
-		}
 		if (lo != &nbd_dev[MINOR(req->rq_dev)]) {
 			printk(KERN_ALERT "NBD: request corrupted!\n");
 			continue;
@@ -249,15 +269,12 @@
 			goto out;
 		}
 #endif
-		list_del(&req->queue);
-		up (&lo->queue_lock);
 		
 		nbd_end_request(req);
 
-		down (&lo->queue_lock);
 	}
  out:
-	up (&lo->queue_lock);
+	return;
 }
 
 void nbd_clear_que(struct nbd_device *lo)
@@ -270,27 +287,20 @@
 		return;
 	}
 #endif
-
-	while (!list_empty(&lo->queue_head)) {
-		req = blkdev_entry_prev_request(&lo->queue_head);
-#ifdef PARANOIA
-		if (!req) {
-			printk( KERN_ALERT "NBD: panic, panic, panic\n" );
-			break;
+	do {
+		req = NULL;
+		spin_lock(&lo->queue_lock);
+		if (!list_empty(&lo->queue_head)) {
+			req = list_entry(lo->queue_head.next, struct request, queue);
+			list_del(&req->queue);
 		}
-		if (lo != &nbd_dev[MINOR(req->rq_dev)]) {
-			printk(KERN_ALERT "NBD: request corrupted when clearing!\n");
-			continue;
+		spin_unlock(&lo->queue_lock);
+		if (req) {
+			req->errors++;
+			nbd_end_request(req);
 		}
-#endif
-		req->errors++;
-		list_del(&req->queue);
-		up(&lo->queue_lock);
+	} while(req);
 
-		nbd_end_request(req);
-
-		down(&lo->queue_lock);
-	}
 }
 
 /*
@@ -334,10 +344,11 @@
 		blkdev_dequeue_request(req);
 		spin_unlock_irq(&io_request_lock);
 
-		down (&lo->queue_lock);
-		list_add(&req->queue, &lo->queue_head);
-		nbd_send_req(lo->sock, req);	/* Why does this block?         */
-		up (&lo->queue_lock);
+		spin_lock(&lo->queue_lock);
+		list_add_tail(&req->queue, &lo->queue_head);
+		spin_unlock(&lo->queue_lock);
+
+		nbd_send_req(lo, req);
 
 		spin_lock_irq(&io_request_lock);
 		continue;
@@ -372,21 +383,21 @@
 	lo = &nbd_dev[dev];
 	switch (cmd) {
 	case NBD_DISCONNECT:
-	        printk("NBD_DISCONNECT\n") ;
+	        printk("NBD_DISCONNECT\n");
                 sreq.cmd=2 ; /* shutdown command */
-                if (!lo->sock) return -EINVAL ;
-                nbd_send_req(lo->sock,&sreq) ;
+                if (!lo->sock) return -EINVAL;
+                nbd_send_req(lo, &sreq);
                 return 0 ;
  
 	case NBD_CLEAR_SOCK:
-		down(&lo->queue_lock);
 		nbd_clear_que(lo);
+		spin_lock(&lo->queue_lock);
 		if (!list_empty(&lo->queue_head)) {
-			up(&lo->queue_lock);
+			spin_unlock(&lo->queue_lock);
 			printk(KERN_ERR "nbd: Some requests are in progress -> can not turn off.\n");
 			return -EBUSY;
 		}
-		up(&lo->queue_lock);
+		spin_unlock(&lo->queue_lock);
 		file = lo->file;
 		if (!file)
 			return -EINVAL;
@@ -507,8 +518,9 @@
 		nbd_dev[i].file = NULL;
 		nbd_dev[i].magic = LO_MAGIC;
 		nbd_dev[i].flags = 0;
+		spin_lock_init(&nbd_dev[i].queue_lock);
 		INIT_LIST_HEAD(&nbd_dev[i].queue_head);
-		init_MUTEX(&nbd_dev[i].queue_lock);
+		init_MUTEX(&nbd_dev[i].tx_lock);
 		nbd_blksizes[i] = 1024;
 		nbd_blksize_bits[i] = 10;
 		nbd_bytesizes[i] = 0x7ffffc00; /* 2GB */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/paride/bpck6.c linux/drivers/block/paride/bpck6.c
--- linux.orig/drivers/block/paride/bpck6.c	2001-10-05 19:06:51.000000000 +0000
+++ linux/drivers/block/paride/bpck6.c	2002-07-20 01:08:22.000000000 +0000
@@ -17,13 +17,15 @@
    Version 2.0.0 is the first to have source released 
    Version 2.0.1 is the "Cox-ified" source code 
    Version 2.0.2 - fixed version string usage, and made ppc functions static 
+   Version 2.0.2ac - additional cleanup (privptr now not private to fix 64bit
+   		   platforms), use memset, rename clashing PPC define.
 */
 
 
 /* PARAMETERS */
 int verbose=0; /* set this to 1 to see debugging messages and whatnot */
 
-#define BACKPACK_VERSION "2.0.2"
+#define BACKPACK_VERSION "2.0.2ac"
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -40,7 +42,7 @@
 
  
 
-#define PPCSTRUCT(pi) ((PPC *)(pi->private))
+#define PPCSTRUCT(pi) ((PPC_STORAGE *)(pi->privptr))
 
 /****************************************************************/
 /*
@@ -223,12 +225,10 @@
 
 static void bpck6_init_proto(PIA *pi)
 {
-	int i;
-
 	/* allocate a state structure for this item */
-	pi->private=(int)kmalloc(sizeof(PPC),GFP_KERNEL);
+	pi->privptr=kmalloc(sizeof(PPC_STORAGE),GFP_KERNEL);
 
-	if(pi->private==(int)NULL)
+	if(pi->privptr==NULL)
 	{
 		printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n",pi->device); 
 		return;
@@ -238,10 +238,7 @@
 		MOD_INC_USE_COUNT; 
 	}
 
-	for(i=0;i<sizeof(PPC);i++)
-	{
-		((unsigned char *)(pi->private))[i]=0;
-	}
+	memset(pi->privptr, 0, sizeof(PPC_STORAGE));
 }
 
 static void bpck6_release_proto(PIA *pi)
@@ -249,7 +246,7 @@
 	MOD_DEC_USE_COUNT;
 	/* free after use count decremented so that we aren't using it
 		when it is decremented */
-	kfree((void *)(pi->private)); 
+	kfree(pi->privptr); 
 }
 
 struct pi_protocol bpck6 = { "bpck6", /* name for proto*/
@@ -290,7 +287,7 @@
 #ifdef MODULE
 /*module information*/
 
-static int init_module(void)
+int init_module(void)
 {
 	printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
 	printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
@@ -303,7 +300,7 @@
 	return pi_register(&bpck6) - 1;  
 }
 
-void    cleanup_module(void)
+void cleanup_module(void)
 {
 	pi_unregister(&bpck6);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c
--- linux.orig/drivers/block/paride/paride.c	2001-10-11 16:04:57.000000000 +0000
+++ linux/drivers/block/paride/paride.c	2002-07-20 01:08:26.000000000 +0000
@@ -276,9 +276,6 @@
 		range = 3;
 		if (pi->mode >= pi->proto->epp_first) range = 8;
 		if ((range == 8) && (pi->port % 8)) return 0;
-#ifndef CONFIG_PARPORT
-		if (check_region(pi->port,range)) return 0;
-#endif /* !CONFIG_PARPORT */
 		pi->reserved = range;
 		return (!pi_test_proto(pi,scratch,verbose));
 	}
@@ -287,9 +284,6 @@
 		range = 3;
 		if (pi->mode >= pi->proto->epp_first) range = 8;
 		if ((range == 8) && (pi->port % 8)) break;
-#ifndef CONFIG_PARPORT
-		if (check_region(pi->port,range)) break;
-#endif /* !CONFIG_PARPORT */
 		pi->reserved = range;
 		if (!pi_test_proto(pi,scratch,verbose)) best = pi->mode;
 	}
@@ -311,10 +305,6 @@
 	if (!pi_register_parport(pi,verbose))
 	  return 0;
 
-#ifndef CONFIG_PARPORT
-	if (check_region(pi->port,3)) return 0;
-#endif /* !CONFIG_PARPORT */
-
 	if (pi->proto->test_port) {
 		pi_claim(pi);
 		max = pi->proto->test_port(pi);
@@ -404,7 +394,11 @@
 	}
 
 #ifndef CONFIG_PARPORT
-	request_region(pi->port,pi->reserved,pi->device);
+	if (!request_region(pi->port,pi->reserved,pi->device))
+		{
+		printk(KERN_WARNING"paride: Unable to request region 0x%x\n", pi->port);
+		return 0;
+		}
 #endif /* !CONFIG_PARPORT */
 
 	if (pi->parname)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/paride/paride.h linux/drivers/block/paride/paride.h
--- linux.orig/drivers/block/paride/paride.h	2000-09-22 21:21:16.000000000 +0000
+++ linux/drivers/block/paride/paride.h	2002-07-20 01:08:31.000000000 +0000
@@ -13,9 +13,10 @@
 /* Changes:
 
 	1.01	GRG 1998.05.05	init_proto, release_proto
+	1.01ac	AGC 2002.04.03  added privptr
 */
 
-#define PARIDE_H_VERSION 	"1.01"
+#define PARIDE_H_VERSION 	"1.01ac"
 
 /* Some adapters need to know what kind of device they are in
 
@@ -46,7 +47,9 @@
 	int	saved_r2;	     /* saved port state */
 	int	reserved;	     /* number of ports reserved */
 	int	private;	     /* for protocol module */
-
+	void	*privptr;	     /* private pointer for protocol module */
+				     /* For 2.5 just make private a ulong but
+		     			for 2.4 fixups thats a bit risky.. */				
 	wait_queue_head_t parq;     /* semaphore for parport sharing */
 	void	*pardev;	     /* pointer to pardevice */
 	char	*parname;	     /* parport name */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/paride/pg.c linux/drivers/block/paride/pg.c
--- linux.orig/drivers/block/paride/pg.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/drivers/block/paride/pg.c	2002-07-20 01:08:30.000000000 +0000
@@ -628,7 +628,8 @@
 	if (PG.busy) return -EBUSY;
 	if (count < hs) return -EINVAL;
 	
-	copy_from_user((char *)&hdr,buf,hs);
+	if (copy_from_user((char *)&hdr, buf, hs))
+		return -EFAULT;
 
 	if (hdr.magic != PG_MAGIC) return -EINVAL;
 	if (hdr.dlen > PG_MAX_DATA) return -EINVAL;
@@ -652,8 +653,8 @@
 
 	PG.busy = 1;
 
-	copy_from_user(PG.bufptr,buf+hs,count-hs);
-
+	if (copy_from_user(PG.bufptr, buf + hs, count - hs))
+		return -EFAULT;
 	return count;
 }
 
@@ -687,9 +688,11 @@
 	hdr.duration = (jiffies - PG.start + HZ/2) / HZ;
 	hdr.scsi = PG.status & 0x0f;
 
-	copy_to_user(buf,(char *)&hdr,hs);
-	if (copy > 0) copy_to_user(buf+hs,PG.bufptr,copy);
-	
+	if (copy_to_user(buf, (char *)&hdr, hs))
+		return -EFAULT;
+	if (copy > 0)
+		if (copy_to_user(buf+hs,PG.bufptr,copy))
+			return -EFAULT;
 	return copy+hs;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/paride/ppc6lnx.c linux/drivers/block/paride/ppc6lnx.c
--- linux.orig/drivers/block/paride/ppc6lnx.c	2001-10-11 16:04:57.000000000 +0000
+++ linux/drivers/block/paride/ppc6lnx.c	2002-07-20 01:08:22.000000000 +0000
@@ -79,7 +79,7 @@
 	u8	org_data;				// original LPT data port contents
 	u8	org_ctrl;				// original LPT control port contents
 	u8	cur_ctrl;				// current control port contents
-} PPC;
+} PPC_STORAGE;
 
 //***************************************************************************
 
@@ -101,25 +101,25 @@
 
 //***************************************************************************
 
-static int ppc6_select(PPC *ppc);
-static void ppc6_deselect(PPC *ppc);
-static void ppc6_send_cmd(PPC *ppc, u8 cmd);
-static void ppc6_wr_data_byte(PPC *ppc, u8 data);
-static u8 ppc6_rd_data_byte(PPC *ppc);
-static u8 ppc6_rd_port(PPC *ppc, u8 port);
-static void ppc6_wr_port(PPC *ppc, u8 port, u8 data);
-static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count);
-static void ppc6_wait_for_fifo(PPC *ppc);
-static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count);
-static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static void ppc6_wr_extout(PPC *ppc, u8 regdata);
-static int ppc6_open(PPC *ppc);
-static void ppc6_close(PPC *ppc);
+static int ppc6_select(PPC_STORAGE *ppc);
+static void ppc6_deselect(PPC_STORAGE *ppc);
+static void ppc6_send_cmd(PPC_STORAGE *ppc, u8 cmd);
+static void ppc6_wr_data_byte(PPC_STORAGE *ppc, u8 data);
+static u8 ppc6_rd_data_byte(PPC_STORAGE *ppc);
+static u8 ppc6_rd_port(PPC_STORAGE *ppc, u8 port);
+static void ppc6_wr_port(PPC_STORAGE *ppc, u8 port, u8 data);
+static void ppc6_rd_data_blk(PPC_STORAGE *ppc, u8 *data, long count);
+static void ppc6_wait_for_fifo(PPC_STORAGE *ppc);
+static void ppc6_wr_data_blk(PPC_STORAGE *ppc, u8 *data, long count);
+static void ppc6_rd_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length);
+static void ppc6_wr_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length);
+static void ppc6_wr_extout(PPC_STORAGE *ppc, u8 regdata);
+static int ppc6_open(PPC_STORAGE *ppc);
+static void ppc6_close(PPC_STORAGE *ppc);
 
 //***************************************************************************
 
-static int ppc6_select(PPC *ppc)
+static int ppc6_select(PPC_STORAGE *ppc)
 {
 	u8 i, j, k;
 
@@ -205,7 +205,7 @@
 
 //***************************************************************************
 
-static void ppc6_deselect(PPC *ppc)
+static void ppc6_deselect(PPC_STORAGE *ppc)
 {
 	if (ppc->mode & 4)	// EPP
 		ppc->cur_ctrl |= port_init;
@@ -223,7 +223,7 @@
 
 //***************************************************************************
 
-static void ppc6_send_cmd(PPC *ppc, u8 cmd)
+static void ppc6_send_cmd(PPC_STORAGE *ppc, u8 cmd)
 {
 	switch(ppc->mode)
 	{
@@ -254,7 +254,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_data_byte(PPC *ppc, u8 data)
+static void ppc6_wr_data_byte(PPC_STORAGE *ppc, u8 data)
 {
 	switch(ppc->mode)
 	{
@@ -285,7 +285,7 @@
 
 //***************************************************************************
 
-static u8 ppc6_rd_data_byte(PPC *ppc)
+static u8 ppc6_rd_data_byte(PPC_STORAGE *ppc)
 {
 	u8 data = 0;
 
@@ -358,7 +358,7 @@
 
 //***************************************************************************
 
-static u8 ppc6_rd_port(PPC *ppc, u8 port)
+static u8 ppc6_rd_port(PPC_STORAGE *ppc, u8 port)
 {
 	ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_READ));
 
@@ -367,7 +367,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_port(PPC *ppc, u8 port, u8 data)
+static void ppc6_wr_port(PPC_STORAGE *ppc, u8 port, u8 data)
 {
 	ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_WRITE));
 
@@ -376,7 +376,7 @@
 
 //***************************************************************************
 
-static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count)
+static void ppc6_rd_data_blk(PPC_STORAGE *ppc, u8 *data, long count)
 {
 	switch(ppc->mode)
 	{
@@ -512,7 +512,7 @@
 
 //***************************************************************************
 
-static void ppc6_wait_for_fifo(PPC *ppc)
+static void ppc6_wait_for_fifo(PPC_STORAGE *ppc)
 {
 	int i;
 
@@ -525,7 +525,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count)
+static void ppc6_wr_data_blk(PPC_STORAGE *ppc, u8 *data, long count)
 {
 	switch(ppc->mode)
 	{
@@ -644,7 +644,7 @@
 
 //***************************************************************************
 
-static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
+static void ppc6_rd_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length)
 {
 	length = length << 1;
 
@@ -664,7 +664,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
+static void ppc6_wr_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length)
 {
 	length = length << 1;
 
@@ -684,7 +684,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_extout(PPC *ppc, u8 regdata)
+static void ppc6_wr_extout(PPC_STORAGE *ppc, u8 regdata)
 {
 	ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE));
 
@@ -693,7 +693,7 @@
 
 //***************************************************************************
 
-static int ppc6_open(PPC *ppc)
+static int ppc6_open(PPC_STORAGE *ppc)
 {
 	int ret;
 
@@ -717,7 +717,7 @@
 
 //***************************************************************************
 
-static void ppc6_close(PPC *ppc)
+static void ppc6_close(PPC_STORAGE *ppc)
 {
 	ppc6_deselect(ppc);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c
--- linux.orig/drivers/block/paride/pt.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/drivers/block/paride/pt.c	2002-07-20 01:08:29.000000000 +0000
@@ -864,7 +864,10 @@
 		    n -= k;
 		    b = k;
 		    if (b > count) b = count;
-		    copy_to_user(buf+t,PT.bufptr,b);
+		    if (copy_to_user(buf + t, PT.bufptr, b)) {
+	    		pi_disconnect(PI);
+			return -EFAULT;
+		    }
 		    t += b;
 		    count -= b;
 	        }
@@ -948,7 +951,10 @@
 		    if (k > PT_BUFSIZE) k = PT_BUFSIZE;
 		    b = k;
 		    if (b > count) b = count;
-		    copy_from_user(PT.bufptr,buf+t,b);
+		    if (copy_from_user(PT.bufptr, buf + t, b)) {
+			pi_disconnect(PI);
+			return -EFAULT;
+		    }
                     pi_write_block(PI,PT.bufptr,k);
 		    t += b;
 		    count -= b;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/rd.c linux/drivers/block/rd.c
--- linux.orig/drivers/block/rd.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/block/rd.c	2002-07-20 01:08:24.000000000 +0000
@@ -43,29 +43,13 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/romfs_fs.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/hdreg.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
 #include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <linux/fd.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
-
-#include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/byteorder.h>
-
-extern void wait_for_keypress(void);
 
 /*
  * 35 has been officially registered as the RAMDISK major number, but
@@ -79,17 +63,10 @@
 /* The RAM disk size is now a parameter */
 #define NUM_RAMDISKS 16		/* This cannot be overridden (yet) */ 
 
-#ifndef MODULE
-/* We don't have to load RAM disks or gunzip them in a module. */
-#define RD_LOADER
-#define BUILD_CRAMDISK
-
-void rd_load(void);
-static int crd_load(struct file *fp, struct file *outfp);
-
 #ifdef CONFIG_BLK_DEV_INITRD
 static int initrd_users;
-#endif
+unsigned long initrd_start, initrd_end;
+int initrd_below_start_ok;
 #endif
 
 /* Various static variables go here.  Most are used only in the RAM disk code.
@@ -122,70 +99,6 @@
  */
 int rd_blocksize = BLOCK_SIZE;			/* blocksize of the RAM disks */
 
-#ifndef MODULE
-
-int rd_doload;			/* 1 = load RAM disk, 0 = don't load */
-int rd_prompt = 1;		/* 1 = prompt for RAM disk, 0 = don't prompt */
-int rd_image_start;		/* starting block # of image */
-#ifdef CONFIG_BLK_DEV_INITRD
-unsigned long initrd_start, initrd_end;
-int mount_initrd = 1;		/* zero if initrd should not be mounted */
-int initrd_below_start_ok;
-
-static int __init no_initrd(char *str)
-{
-	mount_initrd = 0;
-	return 1;
-}
-
-__setup("noinitrd", no_initrd);
-
-#endif
-
-static int __init ramdisk_start_setup(char *str)
-{
-	rd_image_start = simple_strtol(str,NULL,0);
-	return 1;
-}
-
-static int __init load_ramdisk(char *str)
-{
-	rd_doload = simple_strtol(str,NULL,0) & 3;
-	return 1;
-}
-
-static int __init prompt_ramdisk(char *str)
-{
-	rd_prompt = simple_strtol(str,NULL,0) & 1;
-	return 1;
-}
-
-static int __init ramdisk_size(char *str)
-{
-	rd_size = simple_strtol(str,NULL,0);
-	return 1;
-}
-
-static int __init ramdisk_size2(char *str)
-{
-	return ramdisk_size(str);
-}
-
-static int __init ramdisk_blocksize(char *str)
-{
-	rd_blocksize = simple_strtol(str,NULL,0);
-	return 1;
-}
-
-__setup("ramdisk_start=", ramdisk_start_setup);
-__setup("load_ramdisk=", load_ramdisk);
-__setup("prompt_ramdisk=", prompt_ramdisk);
-__setup("ramdisk=", ramdisk_size);
-__setup("ramdisk_size=", ramdisk_size2);
-__setup("ramdisk_blocksize=", ramdisk_blocksize);
-
-#endif
-
 /*
  * Copyright (C) 2000 Linus Torvalds.
  *               2000 Transmeta Corp.
@@ -354,7 +267,7 @@
 	sbh->b_end_io(sbh,1);
 	return 0;
  fail:
-	sbh->b_end_io(sbh,0);
+	buffer_IO_error(sbh);
 	return 0;
 } 
 
@@ -382,6 +295,7 @@
 				error = 0;
 			}
 			up(&inode->i_bdev->bd_sem);
+			invalidate_buffers(inode->i_rdev);
 			break;
          	case BLKGETSIZE:   /* Return device size */
 			if (!arg)
@@ -411,7 +325,8 @@
 	left = initrd_end - initrd_start - *ppos;
 	if (count > left) count = left;
 	if (count == 0) return 0;
-	copy_to_user(buf, (char *)initrd_start + *ppos, count);
+	if (copy_to_user(buf, (char *)initrd_start + *ppos, count))
+		return -EFAULT;
 	*ppos += count;
 	return count;
 }
@@ -474,7 +389,6 @@
 	ioctl:		rd_ioctl,
 };
 
-#ifdef MODULE
 /* Before freeing the module, invalidate all of the protected buffers! */
 static void __exit rd_cleanup (void)
 {
@@ -494,10 +408,9 @@
 	blksize_size[MAJOR_NR] = NULL;
 	blk_size[MAJOR_NR] = NULL;
 }
-#endif
 
 /* This is the registration and initialization section of the RAM disk driver */
-int __init rd_init (void)
+static int __init rd_init (void)
 {
 	int		i;
 
@@ -535,6 +448,8 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* We ought to separate initrd operations here */
 	register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &rd_bd_op, rd_size<<1);
+	devfs_register(devfs_handle, "initrd", DEVFS_FL_DEFAULT, MAJOR_NR,
+			INITRD_MINOR, S_IFBLK | S_IRUSR, &rd_bd_op, NULL);
 #endif
 
 	hardsect_size[MAJOR_NR] = rd_hardsec;		/* Size of the RAM disk blocks */
@@ -549,474 +464,34 @@
 	return 0;
 }
 
-#ifdef MODULE
 module_init(rd_init);
 module_exit(rd_cleanup);
-#endif
-
-/* loadable module support */
-MODULE_PARM     (rd_size, "1i");
-MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes.");
-MODULE_PARM     (rd_blocksize, "i");
-MODULE_PARM_DESC(rd_blocksize, "Blocksize of each RAM disk in bytes.");
-
-MODULE_LICENSE("GPL");
-
-/* End of non-loading portions of the RAM disk driver */
-
-#ifdef RD_LOADER 
-/*
- * This routine tries to find a RAM disk image to load, and returns the
- * number of blocks to read for a non-compressed image, 0 if the image
- * is a compressed image, and -1 if an image with the right magic
- * numbers could not be found.
- *
- * We currently check for the following magic numbers:
- * 	minix
- * 	ext2
- *	romfs
- * 	gzip
- */
-static int __init 
-identify_ramdisk_image(kdev_t device, struct file *fp, int start_block)
-{
-	const int size = 512;
-	struct minix_super_block *minixsb;
-	struct ext2_super_block *ext2sb;
-	struct romfs_super_block *romfsb;
-	int nblocks = -1;
-	unsigned char *buf;
-
-	buf = kmalloc(size, GFP_KERNEL);
-	if (buf == 0)
-		return -1;
-
-	minixsb = (struct minix_super_block *) buf;
-	ext2sb = (struct ext2_super_block *) buf;
-	romfsb = (struct romfs_super_block *) buf;
-	memset(buf, 0xe5, size);
-
-	/*
-	 * Read block 0 to test for gzipped kernel
-	 */
-	if (fp->f_op->llseek)
-		fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0);
-	fp->f_pos = start_block * BLOCK_SIZE;
-	
-	fp->f_op->read(fp, buf, size, &fp->f_pos);
-
-	/*
-	 * If it matches the gzip magic numbers, return -1
-	 */
-	if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
-		printk(KERN_NOTICE
-		       "RAMDISK: Compressed image found at block %d\n",
-		       start_block);
-		nblocks = 0;
-		goto done;
-	}
-
-	/* romfs is at block zero too */
-	if (romfsb->word0 == ROMSB_WORD0 &&
-	    romfsb->word1 == ROMSB_WORD1) {
-		printk(KERN_NOTICE
-		       "RAMDISK: romfs filesystem found at block %d\n",
-		       start_block);
-		nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
-		goto done;
-	}
-
-	/*
-	 * Read block 1 to test for minix and ext2 superblock
-	 */
-	if (fp->f_op->llseek)
-		fp->f_op->llseek(fp, (start_block+1) * BLOCK_SIZE, 0);
-	fp->f_pos = (start_block+1) * BLOCK_SIZE;
-
-	fp->f_op->read(fp, buf, size, &fp->f_pos);
-		
-	/* Try minix */
-	if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
-	    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
-		printk(KERN_NOTICE
-		       "RAMDISK: Minix filesystem found at block %d\n",
-		       start_block);
-		nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
-		goto done;
-	}
-
-	/* Try ext2 */
-	if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
-		printk(KERN_NOTICE
-		       "RAMDISK: ext2 filesystem found at block %d\n",
-		       start_block);
-		nblocks = le32_to_cpu(ext2sb->s_blocks_count);
-		goto done;
-	}
-
-	printk(KERN_NOTICE
-	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
-	       start_block);
-	
-done:
-	if (fp->f_op->llseek)
-		fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0);
-	fp->f_pos = start_block * BLOCK_SIZE;	
 
-	kfree(buf);
-	return nblocks;
-}
-
-/*
- * This routine loads in the RAM disk image.
- */
-static void __init rd_load_image(kdev_t device, int offset, int unit)
-{
- 	struct inode *inode, *out_inode;
-	struct file infile, outfile;
-	struct dentry in_dentry, out_dentry;
-	mm_segment_t fs;
-	kdev_t ram_device;
-	int nblocks, i;
-	char *buf;
-	unsigned short rotate = 0;
-	unsigned short devblocks = 0;
-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
-	char rotator[4] = { '|' , '/' , '-' , '\\' };
-#endif
-	ram_device = MKDEV(MAJOR_NR, unit);
-
-	if ((inode = get_empty_inode()) == NULL)
-		return;
-	memset(&infile, 0, sizeof(infile));
-	memset(&in_dentry, 0, sizeof(in_dentry));
-	infile.f_mode = 1; /* read only */
-	infile.f_dentry = &in_dentry;
-	in_dentry.d_inode = inode;
-	infile.f_op = &def_blk_fops;
-	init_special_inode(inode, S_IFBLK | S_IRUSR, kdev_t_to_nr(device));
-
-	if ((out_inode = get_empty_inode()) == NULL)
-		goto free_inode;
-	memset(&outfile, 0, sizeof(outfile));
-	memset(&out_dentry, 0, sizeof(out_dentry));
-	outfile.f_mode = 3; /* read/write */
-	outfile.f_dentry = &out_dentry;
-	out_dentry.d_inode = out_inode;
-	outfile.f_op = &def_blk_fops;
-	init_special_inode(out_inode, S_IFBLK | S_IRUSR | S_IWUSR, kdev_t_to_nr(ram_device));
-
-	if (blkdev_open(inode, &infile) != 0) {
-		iput(out_inode);
-		goto free_inode;
-	}
-	if (blkdev_open(out_inode, &outfile) != 0)
-		goto free_inodes;
-
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	
-	nblocks = identify_ramdisk_image(device, &infile, offset);
-	if (nblocks < 0)
-		goto done;
-
-	if (nblocks == 0) {
-#ifdef BUILD_CRAMDISK
-		if (crd_load(&infile, &outfile) == 0)
-			goto successful_load;
-#else
-		printk(KERN_NOTICE
-		       "RAMDISK: Kernel does not support compressed "
-		       "RAM disk images\n");
-#endif
-		goto done;
-	}
-
-	/*
-	 * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
-	 * rd_load_image will work only with filesystem BLOCK_SIZE wide!
-	 * So make sure to use 1k blocksize while generating ext2fs
-	 * ramdisk-images.
-	 */
-	if (nblocks > (rd_length[unit] >> BLOCK_SIZE_BITS)) {
-		printk("RAMDISK: image too big! (%d/%ld blocks)\n",
-		       nblocks, rd_length[unit] >> BLOCK_SIZE_BITS);
-		goto done;
-	}
-		
-	/*
-	 * OK, time to copy in the data
-	 */
-	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
-	if (buf == 0) {
-		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
-		goto done;
-	}
-
-	if (blk_size[MAJOR(device)])
-		devblocks = blk_size[MAJOR(device)][MINOR(device)];
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (MAJOR(device) == MAJOR_NR && MINOR(device) == INITRD_MINOR)
-		devblocks = nblocks;
-#endif
-
-	if (devblocks == 0) {
-		printk(KERN_ERR "RAMDISK: could not determine device size\n");
-		goto done;
-	}
-
-	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ", 
-		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
-	for (i=0; i < nblocks; i++) {
-		if (i && (i % devblocks == 0)) {
-			printk("done disk #%d.\n", i/devblocks);
-			rotate = 0;
-			if (infile.f_op->release(inode, &infile) != 0) {
-				printk("Error closing the disk.\n");
-				goto noclose_input;
-			}
-			printk("Please insert disk #%d and press ENTER\n", i/devblocks+1);
-			wait_for_keypress();
-			if (blkdev_open(inode, &infile) != 0)  {
-				printk("Error opening disk.\n");
-				goto noclose_input;
-			}
-			infile.f_pos = 0;
-			printk("Loading disk #%d... ", i/devblocks+1);
-		}
-		infile.f_op->read(&infile, buf, BLOCK_SIZE, &infile.f_pos);
-		outfile.f_op->write(&outfile, buf, BLOCK_SIZE, &outfile.f_pos);
-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
-		if (!(i % 16)) {
-			printk("%c\b", rotator[rotate & 0x3]);
-			rotate++;
-		}
-#endif
-	}
-	printk("done.\n");
-	kfree(buf);
-
-successful_load:
-	ROOT_DEV = MKDEV(MAJOR_NR, unit);
-	if (ROOT_DEVICE_NAME != NULL) strcpy (ROOT_DEVICE_NAME, "rd/0");
-
-done:
-	infile.f_op->release(inode, &infile);
-noclose_input:
-	blkdev_close(out_inode, &outfile);
-	iput(inode);
-	iput(out_inode);
-	set_fs(fs);
-	return;
-free_inodes: /* free inodes on error */ 
-	iput(out_inode);
-	infile.f_op->release(inode, &infile);
-free_inode:
-	iput(inode);
-}
-
-#ifdef CONFIG_MAC_FLOPPY
-int swim3_fd_eject(int devnum);
-#endif
-
-static void __init rd_load_disk(int n)
-{
-
-	if (rd_doload == 0)
-		return;
-
-	if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR
-#ifdef CONFIG_BLK_DEV_INITRD
-		&& MAJOR(real_root_dev) != FLOPPY_MAJOR
-#endif
-	)
-		return;
-
-	if (rd_prompt) {
-#ifdef CONFIG_BLK_DEV_FD
-		floppy_eject();
-#endif
-#ifdef CONFIG_MAC_FLOPPY
-		if(MAJOR(ROOT_DEV) == FLOPPY_MAJOR)
-			swim3_fd_eject(MINOR(ROOT_DEV));
-		else if(MAJOR(real_root_dev) == FLOPPY_MAJOR)
-			swim3_fd_eject(MINOR(real_root_dev));
-#endif
-		printk(KERN_NOTICE
-		       "VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER\n");
-		wait_for_keypress();
-	}
-
-	rd_load_image(ROOT_DEV,rd_image_start, n);
-
-}
-
-void __init rd_load(void)
+/* options - nonmodular */
+#ifndef MODULE
+static int __init ramdisk_size(char *str)
 {
-	rd_load_disk(0);
+	rd_size = simple_strtol(str,NULL,0);
+	return 1;
 }
-
-void __init rd_load_secondary(void)
+static int __init ramdisk_size2(char *str)	/* kludge */
 {
-	rd_load_disk(1);
+	return ramdisk_size(str);
 }
-
-#ifdef CONFIG_BLK_DEV_INITRD
-void __init initrd_load(void)
+static int __init ramdisk_blocksize(char *str)
 {
-	rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),rd_image_start,0);
+	rd_blocksize = simple_strtol(str,NULL,0);
+	return 1;
 }
+__setup("ramdisk=", ramdisk_size);
+__setup("ramdisk_size=", ramdisk_size2);
+__setup("ramdisk_blocksize=", ramdisk_blocksize);
 #endif
 
-#endif /* RD_LOADER */
-
-#ifdef BUILD_CRAMDISK
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-
-#ifndef memzero
-#define memzero(s, n)     memset ((s), 0, (n))
-#endif
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define INBUFSIZ 4096
-#define WSIZE 0x8000    /* window size--must be a power of two, and */
-			/*  at least 32K for zip's deflate method */
-
-static uch *inbuf;
-static uch *window;
-
-static unsigned insize;  /* valid bytes in inbuf */
-static unsigned inptr;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt;  /* bytes in output buffer */
-static int exit_code;
-static long bytes_out;
-static struct file *crd_infp, *crd_outfp;
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-		
-/* Diagnostic functions (stubbed out) */
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define STATIC static
-
-static int  fill_inbuf(void);
-static void flush_window(void);
-static void *malloc(int size);
-static void free(void *where);
-static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
-
-#include "../../lib/inflate.c"
-
-static void __init *malloc(int size)
-{
-	return kmalloc(size, GFP_KERNEL);
-}
-
-static void __init free(void *where)
-{
-	kfree(where);
-}
-
-static void __init gzip_mark(void **ptr)
-{
-}
-
-static void __init gzip_release(void **ptr)
-{
-}
-
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int __init fill_inbuf(void)
-{
-	if (exit_code) return -1;
-	
-	insize = crd_infp->f_op->read(crd_infp, inbuf, INBUFSIZ,
-				      &crd_infp->f_pos);
-	if (insize == 0) return -1;
-
-	inptr = 1;
-
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n;
-    uch *in, ch;
-    
-    crd_outfp->f_op->write(crd_outfp, window, outcnt, &crd_outfp->f_pos);
-    in = window;
-    for (n = 0; n < outcnt; n++) {
-	    ch = *in++;
-	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    outcnt = 0;
-}
-
-static void __init error(char *x)
-{
-	printk(KERN_ERR "%s", x);
-	exit_code = 1;
-}
-
-static int __init 
-crd_load(struct file * fp, struct file *outfp)
-{
-	int result;
-
-	insize = 0;		/* valid bytes in inbuf */
-	inptr = 0;		/* index of next byte to be processed in inbuf */
-	outcnt = 0;		/* bytes in output buffer */
-	exit_code = 0;
-	bytes_out = 0;
-	crc = (ulg)0xffffffffL; /* shift register contents */
-
-	crd_infp = fp;
-	crd_outfp = outfp;
-	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
-	if (inbuf == 0) {
-		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
-		return -1;
-	}
-	window = kmalloc(WSIZE, GFP_KERNEL);
-	if (window == 0) {
-		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
-		kfree(inbuf);
-		return -1;
-	}
-	makecrc();
-	result = gunzip();
-	kfree(inbuf);
-	kfree(window);
-	return result;
-}
-
-#endif  /* BUILD_CRAMDISK */
+/* options - modular */
+MODULE_PARM     (rd_size, "1i");
+MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes.");
+MODULE_PARM     (rd_blocksize, "i");
+MODULE_PARM_DESC(rd_blocksize, "Blocksize of each RAM disk in bytes.");
 
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/smart1,2.h linux/drivers/block/smart1,2.h
--- linux.orig/drivers/block/smart1,2.h	2001-05-01 23:05:00.000000000 +0000
+++ linux/drivers/block/smart1,2.h	2002-07-20 01:08:38.000000000 +0000
@@ -156,27 +156,27 @@
  */
 static void smart2e_submit_command(ctlr_info_t *h, cmdlist_t *c)
 {
-	outl(c->busaddr, h->ioaddr + COMMAND_FIFO);
+	outl(c->busaddr, h->io_mem_addr+ COMMAND_FIFO);
 }
 
 static void smart2e_intr_mask(ctlr_info_t *h, unsigned long val)
 {
-	outl(val, h->ioaddr + INTR_MASK);
+	outl(val, h->io_mem_addr+ INTR_MASK);
 }
 
 static unsigned long smart2e_fifo_full(ctlr_info_t *h)
 {
-	return inl(h->ioaddr + COMMAND_FIFO);
+	return inl(h->io_mem_addr+ COMMAND_FIFO);
 }
 
 static unsigned long smart2e_completed(ctlr_info_t *h)
 {
-	return inl(h->ioaddr + COMMAND_COMPLETE_FIFO);
+	return inl(h->io_mem_addr+ COMMAND_COMPLETE_FIFO);
 }
 
 static unsigned long smart2e_intr_pending(ctlr_info_t *h)
 {
-	return inl(h->ioaddr + INTR_PENDING);
+	return inl(h->io_mem_addr+ INTR_PENDING);
 }
 
 static struct access_method smart2e_access = {
@@ -212,30 +212,30 @@
 	 */
 	c->hdr.size = 0;
 
-	outb(CHANNEL_CLEAR, h->ioaddr + SMART1_SYSTEM_DOORBELL);
+	outb(CHANNEL_CLEAR, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
 
-	outl(c->busaddr, h->ioaddr + SMART1_LISTADDR);
-	outw(c->size, h->ioaddr + SMART1_LISTLEN);
+	outl(c->busaddr, h->io_mem_addr + SMART1_LISTADDR);
+	outw(c->size, h->io_mem_addr + SMART1_LISTLEN);
 
-	outb(CHANNEL_BUSY, h->ioaddr + SMART1_LOCAL_DOORBELL);
+	outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
 }
 
 static void smart1_intr_mask(ctlr_info_t *h, unsigned long val)
 {
 	if (val == 1) {
-		outb(0xFD, h->ioaddr + SMART1_SYSTEM_DOORBELL);
-		outb(CHANNEL_BUSY, h->ioaddr + SMART1_LOCAL_DOORBELL);
-		outb(0x01, h->ioaddr + SMART1_INTR_MASK);
-		outb(0x01, h->ioaddr + SMART1_SYSTEM_MASK);
+		outb(0xFD, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
+		outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
+		outb(0x01, h->io_mem_addr + SMART1_INTR_MASK);
+		outb(0x01, h->io_mem_addr + SMART1_SYSTEM_MASK);
 	} else {
-		outb(0, h->ioaddr + 0xC8E);
+		outb(0, h->io_mem_addr + 0xC8E);
 	}
 }
 
 static unsigned long smart1_fifo_full(ctlr_info_t *h)
 {
 	unsigned char chan;
-	chan = inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_CLEAR;
+	chan = inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_CLEAR;
 	return chan;
 }
 
@@ -244,13 +244,13 @@
 	unsigned char status;
 	unsigned long cmd;
 
-	if (inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY) {
-		outb(CHANNEL_BUSY, h->ioaddr + SMART1_SYSTEM_DOORBELL);
+	if (inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY) {
+		outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
 
-		cmd = inl(h->ioaddr + SMART1_COMPLETE_ADDR);
-		status = inb(h->ioaddr + SMART1_LISTSTATUS);
+		cmd = inl(h->io_mem_addr + SMART1_COMPLETE_ADDR);
+		status = inb(h->io_mem_addr + SMART1_LISTSTATUS);
 
-		outb(CHANNEL_CLEAR, h->ioaddr + SMART1_LOCAL_DOORBELL);
+		outb(CHANNEL_CLEAR, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
 
 		if (cmd) ((cmdlist_t*)bus_to_virt(cmd))->req.hdr.rcode = status;
 	} else {
@@ -262,7 +262,7 @@
 static unsigned long smart1_intr_pending(ctlr_info_t *h)
 {
 	unsigned char chan;
-	chan = inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY;
+	chan = inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY;
 	return chan;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/swim3.c linux/drivers/block/swim3.c
--- linux.orig/drivers/block/swim3.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/block/swim3.c	2002-07-20 01:08:32.000000000 +0000
@@ -811,16 +811,6 @@
 	return err;
 }
 
-int swim3_fd_eject(int devnum)
-{
-	if (devnum >= floppy_count)
-		return -ENODEV;
-	/* Do not check this - this function should ONLY be called early
-	 * in the boot process! */
-	/* if (floppy_states[devnum].ref_count != 1) return -EBUSY; */
-	return fd_eject(&floppy_states[devnum]);
-}
-
 static struct floppy_struct floppy_type =
 	{ 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };	/*  7 1.44MB 3.5"   */
 
@@ -849,9 +839,10 @@
 		err = fd_eject(fs);
 		return err;
 	case FDGETPRM:
-	        err = copy_to_user((void *) param, (void *) &floppy_type,
-				   sizeof(struct floppy_struct));
-		return err;
+	        if (copy_to_user((void *) param, (void *)&floppy_type,
+				 sizeof(struct floppy_struct)))
+			return -EFAULT;
+		return 0;
 	}
 	return -ENOTTY;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/swim_iop.c linux/drivers/block/swim_iop.c
--- linux.orig/drivers/block/swim_iop.c	2001-05-20 00:43:05.000000000 +0000
+++ linux/drivers/block/swim_iop.c	2002-07-20 01:08:21.000000000 +0000
@@ -359,9 +359,10 @@
 		err = swimiop_eject(fs);
 		return err;
 	case FDGETPRM:
-	        err = copy_to_user((void *) param, (void *) &floppy_type,
-				   sizeof(struct floppy_struct));
-		return err;
+	        if (copy_to_user((void *) param, (void *) &floppy_type,
+				 sizeof(struct floppy_struct)))
+			return -EFAULT;
+		return 0;
 	}
 	return -ENOTTY;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/umem.c linux/drivers/block/umem.c
--- linux.orig/drivers/block/umem.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/block/umem.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,1440 @@
+/*
+ * mm.c - Micro Memory(tm) PCI memory board block device driver - v2.3
+ *
+ * (C) 2001 San Mehat <nettwerk@valinux.com>
+ * (C) 2001 Johannes Erdfelt <jerdfelt@valinux.com>
+ * (C) 2001 NeilBrown <neilb@cse.unsw.edu.au>
+ *
+ * This driver for the Micro Memory PCI Memory Module with Battery Backup
+ * is Copyright Micro Memory Inc 2001-2002.  All rights reserved.
+ *
+ * This driver is released to the public under the terms of the
+ *  GNU GENERAL PUBLIC LICENSE version 2
+ * See the file COPYING for details.
+ *
+ * This driver provides a standard block device interface for Micro Memory(tm)
+ * PCI based RAM boards.
+ * 10/05/01: Phap Nguyen - Rebuilt the driver
+ * 10/22/01: Phap Nguyen - v2.1 Added disk partitioning
+ * 29oct2001:NeilBrown   - Use make_request_fn instead of request_fn
+ *                       - use stand disk partitioning (so fdisk works).
+ * 08nov2001:NeilBrown	 - change driver name from "mm" to "umem"
+ *			 - incorporate into main kernel
+ * 08apr2002:NeilBrown   - Move some of interrupt handle to tasklet
+ *			 - use spin_lock_bh instead of _irq
+ *			 - Never block on make_request.  queue
+ *			   bh's instead.
+ *			 - unregister umem from devfs at mod unload
+ *			 - Change version to 2.3
+ * 07Nov2001:Phap Nguyen - Select pci read command: 06, 12, 15 (Decimal)
+ * 07Jan2002: P. Nguyen  - Used PCI Memory Write & Invalidate for DMA
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/ioctl.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+#include <linux/fcntl.h>        /* O_ACCMODE */
+#include <linux/hdreg.h>  /* HDIO_GETGEO */
+
+#include <linux/umem.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define PRINTK(x...) do {} while (0)
+#define dprintk(x...) do {} while (0)
+/*#define dprintk(x...) printk(x) */
+
+#define MM_MAXCARDS 4
+#define MM_RAHEAD 2      /* two sectors */
+#define MM_BLKSIZE 1024  /* 1k blocks */
+#define MM_HARDSECT 512  /* 512-byte hardware sectors */
+#define MM_SHIFT 6       /* max 64 partitions on 4 cards  */
+#define DEVICE_NR(device) (MINOR(device)>>MM_SHIFT)
+
+/*
+ * Version Information
+ */
+
+#define DRIVER_VERSION "v2.3"
+#define DRIVER_AUTHOR "San Mehat, Johannes Erdfelt, NeilBrown"
+#define DRIVER_DESC "Micro Memory(tm) PCI memory board block driver"
+
+static int debug;
+/* #define HW_TRACE(x)     writeb(x,cards[0].csr_remap + MEMCTRLSTATUS_MAGIC) */
+#define HW_TRACE(x)
+
+#define DEBUG_LED_ON_TRANSFER	0x01
+#define DEBUG_BATTERY_POLLING	0x02
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug bitmask");
+
+static int init_mem = 0;
+
+MODULE_PARM(init_mem, "i");
+MODULE_PARM_DESC(init_mem, "Initialize memory");
+
+static int pci_read_cmd = 0x0C;		/* Read Multiple */
+MODULE_PARM(pci_read_cmd, "i");
+MODULE_PARM_DESC(pci_read_cmd, "PCI read command");
+
+static int pci_write_cmd = 0x0F;	/* Write and Invalidate */
+MODULE_PARM(pci_write_cmd, "i");
+MODULE_PARM_DESC(pci_write_cmd, "PCI write command");
+
+static int pci_cmds;
+
+#define MAJOR_NR	UMEM_MAJOR
+
+#include <linux/blk.h>
+#include <linux/blkpg.h>
+
+
+static devfs_handle_t devfs_handle;      /*  For the directory */
+
+
+struct cardinfo {
+	int		card_number;
+	struct pci_dev	*dev;
+
+	int		irq;
+
+	unsigned long	csr_base;
+	unsigned char	*csr_remap;
+	unsigned long	csr_len;
+#ifdef CONFIG_MM_MAP_MEMORY
+	unsigned long	mem_base;
+	unsigned char	*mem_remap;
+	unsigned long	mem_len;
+#endif
+
+	unsigned int	win_size; /* PCI window size */
+	unsigned int	mm_size;  /* size in kbytes */
+
+	struct buffer_head	*bh, **bhtail;
+
+	struct mm_page {
+		dma_addr_t		page_dma;
+		struct mm_dma_desc	*desc;
+		int	 		cnt, headcnt;
+		struct buffer_head	*bh, **bhtail;
+	} mm_pages[2];
+#define DESC_PER_PAGE ((PAGE_SIZE*2)/sizeof(struct mm_dma_desc))
+
+	int  Active, Ready;
+
+	struct tasklet_struct	tasklet;
+	unsigned int dma_status;
+
+	struct tq_struct plug_tq;
+
+	struct {
+		int		good;
+		int		warned;
+		unsigned long	last_change;
+	} battery[2];
+
+	atomic_t	 usage;
+	spinlock_t 	lock;
+	int		check_batteries;
+
+};
+
+static struct cardinfo cards[MM_MAXCARDS];
+static struct block_device_operations mm_fops;
+static struct timer_list battery_timer;
+
+
+static int              mm_hardsect  [MM_MAXCARDS << MM_SHIFT];
+static int              mm_blocksizes[MM_MAXCARDS << MM_SHIFT];
+static int              mm_sizes[MM_MAXCARDS << MM_SHIFT];
+static struct hd_struct mm_partitions[MM_MAXCARDS << MM_SHIFT];
+
+static int num_cards = 0;
+
+struct gendisk mm_gendisk = {
+    major:         MAJOR_NR,		/* Major number assigned later */
+    major_name:    "umem",		/* Name of the major device */
+    minor_shift:   MM_SHIFT,		/* Shift to get device number */
+    max_p:         1 << MM_SHIFT,	/* Number of partitions */
+    fops:          &mm_fops,   		/* Block dev operations */
+/* everything else is dynamic */
+};
+
+
+static void check_batteries(struct cardinfo *card);
+
+/*
+-----------------------------------------------------------------------------------
+--                           get_userbit
+-----------------------------------------------------------------------------------
+*/
+static int get_userbit(struct cardinfo *card, int bit)
+{
+	unsigned char led;
+
+	led = readb(card->csr_remap + MEMCTRLCMD_LEDCTRL);
+	return led & bit;
+}
+/*
+-----------------------------------------------------------------------------------
+--                            set_userbit
+-----------------------------------------------------------------------------------
+*/
+static int set_userbit(struct cardinfo *card, int bit, unsigned char state)
+{
+	unsigned char led;
+
+	led = readb(card->csr_remap + MEMCTRLCMD_LEDCTRL);
+	if (state)
+		led |= bit;
+	else
+		led &= ~bit;
+	writeb(led, card->csr_remap + MEMCTRLCMD_LEDCTRL);
+
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                             set_led
+-----------------------------------------------------------------------------------
+*/
+/*
+ * NOTE: For the power LED, use the LED_POWER_* macros since they differ
+ */
+static void set_led(struct cardinfo *card, int shift, unsigned char state)
+{
+	unsigned char led;
+
+	led = readb(card->csr_remap + MEMCTRLCMD_LEDCTRL);
+	if (state == LED_FLIP)
+		led ^= (1<<shift);
+	else {
+		led &= ~(0x03 << shift);
+		led |= (state << shift);
+	}
+	writeb(led, card->csr_remap + MEMCTRLCMD_LEDCTRL);
+
+}
+
+#ifdef MM_DIAG
+/*
+-----------------------------------------------------------------------------------
+--                              dump_regs
+-----------------------------------------------------------------------------------
+*/
+static void dump_regs(struct cardinfo *card)
+{
+	unsigned char *p;
+	int i, i1;
+
+	p = card->csr_remap;
+	for (i = 0; i < 8; i++) {
+		printk(KERN_DEBUG "%p   ", p);
+
+		for (i1 = 0; i1 < 16; i1++)
+			printk("%02x ", *p++);
+
+		printk("\n");
+	}
+}
+#endif
+/*
+-----------------------------------------------------------------------------------
+--                            dump_dmastat
+-----------------------------------------------------------------------------------
+*/
+static void dump_dmastat(struct cardinfo *card, unsigned int dmastat)
+{
+	printk(KERN_DEBUG "MM%d*: DMAstat - ", card->card_number);
+	if (dmastat & DMASCR_ANY_ERR)
+		printk("ANY_ERR ");
+	if (dmastat & DMASCR_MBE_ERR)
+		printk("MBE_ERR ");
+	if (dmastat & DMASCR_PARITY_ERR_REP)
+		printk("PARITY_ERR_REP ");
+	if (dmastat & DMASCR_PARITY_ERR_DET)
+		printk("PARITY_ERR_DET ");
+	if (dmastat & DMASCR_SYSTEM_ERR_SIG)
+		printk("SYSTEM_ERR_SIG ");
+	if (dmastat & DMASCR_TARGET_ABT)
+		printk("TARGET_ABT ");
+	if (dmastat & DMASCR_MASTER_ABT)
+		printk("MASTER_ABT ");
+	if (dmastat & DMASCR_CHAIN_COMPLETE)
+		printk("CHAIN_COMPLETE ");
+	if (dmastat & DMASCR_DMA_COMPLETE)
+		printk("DMA_COMPLETE ");
+	printk("\n");
+}
+
+/*
+ * Theory of request handling
+ *
+ * Each buffer_head is assigned to one mm_dma_desc.
+ * We have two pages of mm_dma_desc, holding about 64 descriptors
+ * each.  These are allocated at init time.
+ * One page is "Ready" and is either full, or can have request added.
+ * The other page might be "Active", which DMA is happening on it.
+ *
+ * Whenever IO on the active page completes, the Ready page is activated
+ * and the ex-Active page is clean out and made Ready.
+ * Otherwise the Ready page is only activated when it becomes full, or
+ * when mm_unplug_device is called via run_task_queue(&tq_disk).
+ *
+ * If a request arrives while both pages a full, it is queued, and b_rdev is
+ * overloaded to record whether it was a read or a write.
+ *
+ * The interrupt handler only polls the device to clear the interrupt.
+ * The processing of the result is done in a tasklet.
+ */
+
+static void mm_start_io(struct cardinfo *card)
+{
+	/* we have the lock, we know there is
+	 * no IO active, and we know that card->Active
+	 * is set
+	 */
+	struct mm_dma_desc *desc;
+	struct mm_page *page;
+	int offset;
+
+	/* make the last descriptor end the chain */
+	page = &card->mm_pages[card->Active];
+	PRINTK("start_io: %d %d->%d\n", card->Active, page->headcnt, page->cnt-1);
+	desc = &page->desc[page->cnt-1];
+
+	desc->control_bits |= cpu_to_le32(DMASCR_CHAIN_COMP_EN);
+	desc->control_bits &= ~cpu_to_le32(DMASCR_CHAIN_EN);
+	desc->sem_control_bits = desc->control_bits;
+
+			       
+	if (debug & DEBUG_LED_ON_TRANSFER)
+		set_led(card, LED_REMOVE, LED_ON);
+
+	desc = &page->desc[page->headcnt];
+	writel(0, card->csr_remap + DMA_PCI_ADDR);
+	writel(0, card->csr_remap + DMA_PCI_ADDR + 4);
+
+	writel(0, card->csr_remap + DMA_LOCAL_ADDR);
+	writel(0, card->csr_remap + DMA_LOCAL_ADDR + 4);
+
+	writel(0, card->csr_remap + DMA_TRANSFER_SIZE);
+	writel(0, card->csr_remap + DMA_TRANSFER_SIZE + 4);
+
+	writel(0, card->csr_remap + DMA_SEMAPHORE_ADDR);
+	writel(0, card->csr_remap + DMA_SEMAPHORE_ADDR + 4);
+
+	offset = ((char*)desc) - ((char*)page->desc);
+	writel(cpu_to_le32((page->page_dma+offset)&0xffffffff),
+	       card->csr_remap + DMA_DESCRIPTOR_ADDR);
+	/* Force the valiue to u64 before shifting otherwise >> 32 is undefined C
+	   and on some ports will do nothing ! */
+	writel(((u64)cpu_to_le32((page->page_dma)>>32)),
+	       card->csr_remap + DMA_DESCRIPTOR_ADDR + 4);
+
+	/* Go, go, go */
+	writel(cpu_to_le32(DMASCR_GO | DMASCR_CHAIN_EN | pci_cmds),
+	       card->csr_remap + DMA_STATUS_CTRL);
+}
+
+static int add_bh(struct cardinfo *card);
+
+static void activate(struct cardinfo *card)
+{
+	/* if No page is Active, and Ready is 
+	 * not empty, then switch Ready page
+	 * to active and start IO.
+	 * Then add any bh's that are available to Ready
+	 */
+
+	do {
+		while (add_bh(card))
+			;
+
+		if (card->Active == -1 &&
+		    card->mm_pages[card->Ready].cnt > 0) {
+			card->Active = card->Ready;
+			card->Ready = 1-card->Ready;
+			mm_start_io(card);
+		}
+
+	} while (card->Active == -1 && add_bh(card));
+}
+
+static inline void reset_page(struct mm_page *page)
+{
+	page->cnt = 0;
+	page->headcnt = 0;
+	page->bh = NULL;
+	page->bhtail = & page->bh;
+}
+
+static void mm_unplug_device(void *data)
+{
+	struct cardinfo *card = data;
+
+	spin_lock_bh(&card->lock);
+	activate(card);
+	spin_unlock_bh(&card->lock);
+}
+
+/* 
+ * If there is room on Ready page, take
+ * one bh off list and add it.
+ * return 1 if there was room, else 0.
+ */
+static int add_bh(struct cardinfo *card)
+{
+	struct mm_page *p;
+	struct mm_dma_desc *desc;
+	dma_addr_t dma_handle;
+	int offset;
+	struct buffer_head *bh;
+	int rw;
+
+	bh = card->bh;
+	if (!bh)
+		return 0;
+
+	if (card->mm_pages[card->Ready].cnt >= DESC_PER_PAGE)
+		return 0;
+
+	card->bh = bh->b_reqnext;
+	if (card->bh == NULL)
+		card->bhtail = &card->bh;
+	rw = bh->b_rdev;
+
+	dma_handle = pci_map_page(card->dev, bh->b_page, bh_offset(bh),
+				  bh->b_size,
+				  (rw==READ) ?
+				  PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+
+	p = &card->mm_pages[card->Ready];
+	desc = &p->desc[p->cnt];
+	p->cnt++;
+	*(p->bhtail) = bh;
+	p->bhtail = &(bh->b_reqnext);
+	bh->b_reqnext = NULL;
+
+	desc->data_dma_handle = dma_handle;
+
+	desc->pci_addr = cpu_to_le64((u64)desc->data_dma_handle);
+	desc->local_addr= cpu_to_le64(bh->b_rsector << 9);
+	desc->transfer_size = cpu_to_le32(bh->b_size);
+	offset = ( ((char*)&desc->sem_control_bits) - ((char*)p->desc));
+	desc->sem_addr = cpu_to_le64((u64)(p->page_dma+offset));
+	desc->zero1 = desc->zero2 = 0;
+	offset = ( ((char*)(desc+1)) - ((char*)p->desc));
+	desc->next_desc_addr = cpu_to_le64(p->page_dma+offset);
+	desc->control_bits = cpu_to_le32(DMASCR_GO|DMASCR_ERR_INT_EN|
+					 DMASCR_PARITY_INT_EN|
+					 DMASCR_CHAIN_EN |
+					 DMASCR_SEM_EN |
+					 pci_cmds);
+	if (rw == WRITE)
+		desc->control_bits |= cpu_to_le32(DMASCR_TRANSFER_READ);
+	desc->sem_control_bits = desc->control_bits;
+	return 1;
+}
+
+static void process_page(unsigned long data)
+{
+	/* check if any of the requests in the page are DMA_COMPLETE,
+	 * and deal with them appropriately.
+	 * If we find a descriptor without DMA_COMPLETE in the semaphore, then
+	 * dma must have hit an error on that descriptor, so use dma_status instead
+	 * and assume that all following descriptors must be re-tried.
+	 */
+	struct mm_page *page;
+	struct buffer_head *ok=NULL, *fail=NULL;
+	struct cardinfo *card = (struct cardinfo *)data;
+	unsigned int dma_status = card->dma_status;
+
+	spin_lock_bh(&card->lock);
+	if (card->Active < 0)
+		goto out_unlock;
+	page = &card->mm_pages[card->Active];
+	
+	while (page->bh != NULL) {
+		struct buffer_head *bh = page->bh;
+		struct mm_dma_desc *desc = &page->desc[page->headcnt];
+		int control = le32_to_cpu(desc->sem_control_bits);
+		int last=0;
+
+		if (!(control & DMASCR_DMA_COMPLETE)) {
+			control = dma_status;
+			last=1; 
+		}
+		page->headcnt++;
+		page->bh = bh->b_reqnext;
+
+		pci_unmap_page(card->dev, desc->data_dma_handle, bh->b_size,
+				 (control& DMASCR_TRANSFER_READ) ?
+				PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+		if (!(control & DMASCR_HARD_ERROR)) {
+			/* it worked just fine */
+			bh->b_reqnext = ok;
+			ok = bh;
+		} else {
+			/* error */
+			bh->b_reqnext = fail;
+			fail = bh;
+			printk(KERN_WARNING "MM%d: I/O error on sector %lx/%x\n",
+			       card->card_number, bh->b_rsector, bh->b_size);
+			dump_dmastat(card, control);
+		}
+		if (last) break;
+	}
+
+	if (debug & DEBUG_LED_ON_TRANSFER)
+		set_led(card, LED_REMOVE, LED_OFF);
+
+	if (card->check_batteries) {
+		card->check_batteries = 0;
+		check_batteries(card);
+	}
+	if (page->headcnt >= page->cnt) {
+		reset_page(page);
+		card->Active = -1;
+		activate(card);
+	} else {
+		/* haven't finished with this one yet */
+		PRINTK("do some more\n");
+		mm_start_io(card);
+	}
+ out_unlock:
+	spin_unlock_bh(&card->lock);
+
+	while(ok) {
+		struct buffer_head *bh = ok;
+		ok = bh->b_reqnext;
+		bh->b_reqnext = NULL;
+		bh->b_end_io(bh, 1);
+	}
+	while(fail) {
+		struct buffer_head *bh = fail;
+		fail = bh->b_reqnext;
+		bh->b_reqnext = NULL;
+		bh->b_end_io(bh, 0);
+	}
+
+}
+
+/*
+-----------------------------------------------------------------------------------
+--                              mm_make_request
+-----------------------------------------------------------------------------------
+*/
+static int mm_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
+{
+	struct cardinfo *card = &cards[DEVICE_NR(bh->b_rdev)];
+	PRINTK("mm_make_request %d %ld %d\n", rw, bh->b_rsector, bh->b_size);
+	bh->b_rsector += mm_partitions[MINOR(bh->b_rdev)].start_sect;
+	bh->b_rdev = rw; /* overloading... */
+
+	spin_lock_bh(&card->lock);
+	*card->bhtail = bh;
+	bh->b_reqnext = NULL;
+	card->bhtail = &bh->b_reqnext;
+	spin_unlock_bh(&card->lock);
+
+	queue_task(&card->plug_tq, &tq_disk);
+	return 0;
+}
+
+/*
+-----------------------------------------------------------------------------------
+--                              mm_interrupt
+-----------------------------------------------------------------------------------
+*/
+static void mm_interrupt(int irq, void *__card, struct pt_regs *regs)
+{
+	struct cardinfo *card = (struct cardinfo *) __card;
+	unsigned int dma_status;
+	unsigned short cfg_status;
+
+HW_TRACE(0x30);
+
+	dma_status = le32_to_cpu(readl(card->csr_remap + DMA_STATUS_CTRL));
+
+	if (!(dma_status & (DMASCR_ERROR_MASK | DMASCR_CHAIN_COMPLETE))) {
+		/* interrupt wasn't for me ... */
+		return;
+        }
+
+	/* clear COMPLETION interrupts */
+	writel(cpu_to_le32(DMASCR_DMA_COMPLETE|DMASCR_CHAIN_COMPLETE),
+	       card->csr_remap+ DMA_STATUS_CTRL);
+
+	
+	/* log errors and clear interrupt status */
+	if (dma_status & DMASCR_ANY_ERR) {
+		unsigned int	data_log1, data_log2;
+		unsigned int	addr_log1, addr_log2;
+		unsigned char	stat, count, syndrome, check;
+
+		stat = readb(card->csr_remap + MEMCTRLCMD_ERRSTATUS);
+
+		data_log1 = le32_to_cpu(readl(card->csr_remap + ERROR_DATA_LOG));
+		data_log2 = le32_to_cpu(readl(card->csr_remap + ERROR_DATA_LOG + 4));
+		addr_log1 = le32_to_cpu(readl(card->csr_remap + ERROR_ADDR_LOG));
+		addr_log2 = readb(card->csr_remap + ERROR_ADDR_LOG + 4);
+
+		count = readb(card->csr_remap + ERROR_COUNT);
+		syndrome = readb(card->csr_remap + ERROR_SYNDROME);
+		check = readb(card->csr_remap + ERROR_CHECK);
+
+		dump_dmastat(card, dma_status);
+
+		if (stat & 0x01)
+			printk(KERN_ERR "MM%d*: Memory access error detected (err count %d)\n",
+				card->card_number, count);
+		if (stat & 0x02)
+			printk(KERN_ERR "MM%d*: Multi-bit EDC error\n",
+				card->card_number);
+
+		printk(KERN_ERR "MM%d*: Fault Address 0x%02x%08x, Fault Data 0x%08x%08x\n",
+			card->card_number, addr_log2, addr_log1, data_log2, data_log1);
+		printk(KERN_ERR "MM%d*: Fault Check 0x%02x, Fault Syndrome 0x%02x\n",
+			card->card_number, check, syndrome);
+
+		writeb(0, card->csr_remap + ERROR_COUNT);
+	}
+
+	if (dma_status & DMASCR_PARITY_ERR_REP) {
+		printk(KERN_ERR "MM%d*: PARITY ERROR REPORTED\n", card->card_number);
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	if (dma_status & DMASCR_PARITY_ERR_DET) {
+		printk(KERN_ERR "MM%d*: PARITY ERROR DETECTED\n", card->card_number); 
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	if (dma_status & DMASCR_SYSTEM_ERR_SIG) {
+		printk(KERN_ERR "MM%d*: SYSTEM ERROR\n", card->card_number); 
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	if (dma_status & DMASCR_TARGET_ABT) {
+		printk(KERN_ERR "MM%d*: TARGET ABORT\n", card->card_number); 
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	if (dma_status & DMASCR_MASTER_ABT) {
+		printk(KERN_ERR "MM%d*: MASTER ABORT\n", card->card_number); 
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	/* and process the DMA descriptors */
+	card->dma_status = dma_status;
+	tasklet_schedule(&card->tasklet);
+
+HW_TRACE(0x36);
+
+}
+/*
+-----------------------------------------------------------------------------------
+--                         set_fault_to_battery_status
+-----------------------------------------------------------------------------------
+*/
+/*
+ * If both batteries are good, no LED
+ * If either battery has been warned, solid LED
+ * If both batteries are bad, flash the LED quickly
+ * If either battery is bad, flash the LED semi quickly
+ */
+static void set_fault_to_battery_status(struct cardinfo *card)
+{
+	if (card->battery[0].good && card->battery[1].good)
+		set_led(card, LED_FAULT, LED_OFF);
+	else if (card->battery[0].warned || card->battery[1].warned)
+		set_led(card, LED_FAULT, LED_ON);
+	else if (!card->battery[0].good && !card->battery[1].good)
+		set_led(card, LED_FAULT, LED_FLASH_7_0);
+	else
+		set_led(card, LED_FAULT, LED_FLASH_3_5);
+}
+
+static void init_battery_timer(void);
+
+
+/*
+-----------------------------------------------------------------------------------
+--                            check_battery
+-----------------------------------------------------------------------------------
+*/
+static int check_battery(struct cardinfo *card, int battery, int status)
+{
+	if (status != card->battery[battery].good) {
+		card->battery[battery].good = !card->battery[battery].good;
+		card->battery[battery].last_change = jiffies;
+
+		if (card->battery[battery].good) {
+			printk(KERN_ERR "MM%d: Battery %d now good\n",
+				card->card_number, battery + 1);
+			card->battery[battery].warned = 0;
+		} else
+			printk(KERN_ERR "MM%d: Battery %d now FAILED\n",
+				card->card_number, battery + 1);
+
+		return 1;
+	} else if (!card->battery[battery].good &&
+		   !card->battery[battery].warned &&
+		   time_after_eq(jiffies, card->battery[battery].last_change +
+				 (HZ * 60 * 60 * 5))) {
+		printk(KERN_ERR "MM%d: Battery %d still FAILED after 5 hours\n",
+			card->card_number, battery + 1);
+		card->battery[battery].warned = 1;
+
+		return 1;
+	}
+
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                              check_batteries
+-----------------------------------------------------------------------------------
+*/
+static void check_batteries(struct cardinfo *card)
+{
+	/* NOTE: this must *never* be called while the card
+	 * is doing (bus-to-card) DMA, or you will need the
+	 * reset switch
+	 */
+	unsigned char status;
+	int ret1, ret2;
+
+	status = readb(card->csr_remap + MEMCTRLSTATUS_BATTERY);
+	if (debug & DEBUG_BATTERY_POLLING)
+		printk(KERN_DEBUG "MM%d: checking battery status, 1 = %s, 2 = %s\n",
+		       card->card_number,
+		       (status & BATTERY_1_FAILURE) ? "FAILURE" : "OK",
+		       (status & BATTERY_2_FAILURE) ? "FAILURE" : "OK");
+
+	ret1 = check_battery(card, 0, !(status & BATTERY_1_FAILURE));
+	ret2 = check_battery(card, 1, !(status & BATTERY_2_FAILURE));
+
+	if (ret1 || ret2)
+		set_fault_to_battery_status(card);
+}
+
+static void check_all_batteries(unsigned long ptr)
+{
+	int i;
+
+	for (i = 0; i < num_cards; i++) {
+		struct cardinfo *card = &cards[i];
+		spin_lock_bh(&card->lock);
+		if (card->Active >= 0)
+			card->check_batteries = 1;
+		else
+			check_batteries(card);
+		spin_unlock_bh(&card->lock);
+	}
+
+	init_battery_timer();
+}
+/*
+-----------------------------------------------------------------------------------
+--                            init_battery_timer
+-----------------------------------------------------------------------------------
+*/
+static void init_battery_timer(void)
+{
+	init_timer(&battery_timer);
+	battery_timer.function = check_all_batteries;
+	battery_timer.expires = jiffies + (HZ * 60);
+	add_timer(&battery_timer);
+}
+/*
+-----------------------------------------------------------------------------------
+--                              del_battery_timer
+-----------------------------------------------------------------------------------
+*/
+static void del_battery_timer(void)
+{
+	del_timer(&battery_timer);
+}
+/*
+-----------------------------------------------------------------------------------
+--                                mm_revalidate
+-----------------------------------------------------------------------------------
+*/
+/*
+ * Note no locks taken out here.  In a worst case scenario, we could drop
+ * a chunk of system memory.  But that should never happen, since validation
+ * happens at open or mount time, when locks are held.
+ */
+static int mm_revalidate(kdev_t i_rdev)
+{
+	int i;
+
+	int card_number = DEVICE_NR(i_rdev);
+	/* first partition, # of partitions */
+	int part1 = (DEVICE_NR(i_rdev) << MM_SHIFT) + 1;
+	int npart = (1 << MM_SHIFT) -1;
+
+	/* first clear old partition information */
+	for (i=0; i<npart ;i++) {
+		mm_gendisk.sizes[part1+i]=0;
+		mm_gendisk.part[part1+i].start_sect = 0;
+		mm_gendisk.part[part1+i].nr_sects = 0;
+	}
+
+	mm_gendisk.part[card_number << MM_SHIFT].nr_sects =
+		cards[card_number].mm_size << 1;
+
+
+	/* then fill new info */
+	printk(KERN_INFO "mm partition check: (%d)\n", DEVICE_NR(i_rdev));
+	grok_partitions(&mm_gendisk, card_number,  1<<MM_SHIFT,
+			mm_gendisk.sizes[card_number<<MM_SHIFT]);
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                            mm_ioctl
+-----------------------------------------------------------------------------------
+*/
+static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
+{
+	int err, size, card_number;
+	struct hd_geometry geo;
+	unsigned int minor;
+
+	if (!i || !i->i_rdev)
+		return -EINVAL;
+
+	minor       = MINOR(i->i_rdev);
+	card_number = (minor >> MM_SHIFT);
+
+
+	switch(cmd) {
+
+	case BLKGETSIZE:
+		/* Return the device size, expressed in sectors */
+		err = ! access_ok (VERIFY_WRITE, arg, sizeof(long));
+		if (err) return -EFAULT;
+		size = mm_gendisk.part[minor].nr_sects;
+		if (copy_to_user((long *) arg, &size, sizeof (long)))
+			return -EFAULT;
+		return 0;
+
+
+	case BLKRAGET: /* return the readahead value */
+		err = ! access_ok(VERIFY_WRITE, arg, sizeof(long));
+		if (err) return -EFAULT;
+		copy_to_user((long *)arg, &read_ahead[MAJOR(i->i_rdev)],sizeof(long));
+		return 0;
+
+	case BLKRASET: /* set the readahead value */
+		if (!capable(CAP_SYS_RAWIO)) return -EACCES;
+		if (arg > 0xff) return -EINVAL; /* limit it */
+		read_ahead[MAJOR(i->i_rdev)] = arg;
+		return 0;
+
+	case BLKRRPART:
+		return (mm_revalidate(i->i_rdev));
+
+	case HDIO_GETGEO:
+		/*
+		 * get geometry: we have to fake one...  trim the size to a
+		 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
+		 * whatever cylinders.
+		 */
+		err = ! access_ok(VERIFY_WRITE, arg, sizeof(geo));
+		if (err) return -EFAULT;
+		size = cards[card_number].mm_size * (1024 / MM_HARDSECT);
+		geo.heads     = 64;
+		geo.sectors   = 32;
+		geo.start     = mm_gendisk.part[minor].start_sect;
+		geo.cylinders = size / (geo.heads * geo.sectors);
+
+		if (copy_to_user((void *) arg, &geo, sizeof(geo)))
+			return -EFAULT;
+		return 0;
+
+
+	default:
+		return blk_ioctl(i->i_rdev, cmd, arg);
+	}
+
+	return -ENOTTY; /* unknown command */
+}
+/*
+-----------------------------------------------------------------------------------
+--                                mm_check_change
+-----------------------------------------------------------------------------------
+  Future support for removable devices
+*/
+static int mm_check_change(kdev_t i_rdev)
+{
+	int card_number = DEVICE_NR(i_rdev);
+/*  struct cardinfo *dev = cards + card_number; */
+	if (card_number >= num_cards) /* paranoid */
+		return 0;
+
+	return 0;
+}
+
+/*
+-----------------------------------------------------------------------------------
+--                            mm_open
+-----------------------------------------------------------------------------------
+*/
+static int mm_open(struct inode *i, struct file *filp)
+{
+	int num;
+	struct cardinfo *card;
+
+	num = DEVICE_NR(i->i_rdev);
+	if (num >= num_cards)
+		return -ENXIO;
+
+	card = cards + num;
+
+	atomic_inc(&card->usage);
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                              mm_do_release
+-----------------------------------------------------------------------------------
+*/
+static int mm_do_release(struct inode *i, struct file *filp)
+{
+	int num;
+	struct cardinfo *card;
+
+	num = DEVICE_NR(i->i_rdev);
+
+	card = cards + num;
+
+	if (atomic_dec_and_test(&card->usage))
+		invalidate_device(i->i_rdev, 1);
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+#define INITIALIZE_BHS	32
+/*
+-----------------------------------------------------------------------------------
+--                               mm_init_mem
+-----------------------------------------------------------------------------------
+*/
+static void mm_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
+{
+	mark_buffer_uptodate(bh, uptodate);
+	unlock_buffer(bh);
+}
+
+ 
+static int __devinit mm_init_mem(struct cardinfo *card)
+{
+	struct buffer_head *bhlist, *bhactive, *bh;
+	unsigned int i;
+	int rc = 0;
+	struct page *zero_page;
+
+	/* Turn this off when we flush the contents of memory and have */
+	/*  the card rebuild ECC */
+	writeb(EDC_NONE_DEFAULT, card->csr_remap + MEMCTRLCMD_ERRCTRL);
+
+	printk("MM%d: initializing memory\n", card->card_number);
+
+	zero_page = alloc_page(GFP_KERNEL);
+	if (!zero_page) {
+		printk(KERN_ERR "unable to allocate page for zeroing memory\n");
+		rc = -ENOMEM;
+		goto out_alloc_zero_page;
+	}
+
+	memset(page_address(zero_page), 0, PAGE_SIZE);
+	
+	i=0; bhlist = NULL;
+	while (i < INITIALIZE_BHS) {
+		bh = kmem_cache_alloc(bh_cachep, SLAB_KERNEL);
+		if (bh == NULL)
+			break;
+		bh->b_next = bhlist;
+		bhlist = bh;
+
+		bh->b_size = PAGE_SIZE;
+		init_buffer(bh, mm_end_buffer_io_sync, NULL);
+		set_bh_page(bh, zero_page, 0);
+		bh->b_dev = bh->b_rdev =
+			MKDEV(MAJOR_NR, card->card_number<<MM_SHIFT);
+		init_waitqueue_head(&bh->b_wait);
+
+		i++;
+	}
+	if (bhlist == NULL) {
+		printk(KERN_ERR "MM: count not allocate buffer heads!!\n");
+		rc = -ENOMEM;
+		goto out_alloc_bh;
+	}
+
+	bhactive = NULL;
+	for (i = 0; i < card->mm_size / (PAGE_SIZE / 1024);i++) {
+		if (bhlist == NULL) {
+			/* time to wait for some buffers */
+			while (bhactive) {
+				bh = bhactive;
+				bhactive = bh->b_next;
+				wait_on_buffer(bh);
+				if (!test_bit(BH_Uptodate, &bh->b_state))
+					rc = -EIO;
+				bh->b_next = bhlist;
+				bhlist = bh;
+			}
+		}
+		bh = bhlist;
+		bhlist = bh->b_next;
+
+		bh->b_blocknr = i;
+		bh->b_rsector = i*(PAGE_SIZE/512);
+		set_bit(BH_Lock, &bh->b_state);
+		clear_bit(BH_Uptodate, &bh->b_state);
+		mm_make_request(NULL, WRITE, bh);
+		bh->b_next = bhactive;
+		bhactive = bh;
+	}
+	while (bhactive) {
+		bh = bhactive;
+		bhactive = bh->b_next;
+		wait_on_buffer(bh);
+		bh->b_next = bhlist;
+		bhlist = bh;
+	}
+
+	if (!rc)
+		set_userbit(card, MEMORY_INITIALIZED, 1);
+
+	while (bhlist) {
+		bh = bhlist;
+		bhlist = bh->b_next;
+		kmem_cache_free(bh_cachep, bh);
+	}
+
+out_alloc_bh:
+
+	free_page((unsigned long) zero_page);
+out_alloc_zero_page:
+
+	return rc;
+}
+/*
+-----------------------------------------------------------------------------------
+--                             mm_fops
+-----------------------------------------------------------------------------------
+*/
+static struct block_device_operations mm_fops = {
+	owner:		THIS_MODULE,
+	open:		mm_open,
+	release:	mm_do_release,
+	ioctl:		mm_ioctl,
+	revalidate:	mm_revalidate,
+	check_media_change: mm_check_change,
+};
+/*
+-----------------------------------------------------------------------------------
+--                                mm_pci_probe
+-----------------------------------------------------------------------------------
+*/
+static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int ret = -ENODEV;
+	struct cardinfo *card = &cards[num_cards];
+	unsigned char	mem_present;
+	unsigned char	batt_status;
+	unsigned int	saved_bar, data;
+
+	if (pci_enable_device(dev) < 0)
+		return -ENODEV;
+
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF8);
+	pci_set_master(dev);
+
+	card->dev         = dev;
+	card->card_number = num_cards;
+
+	card->csr_base = pci_resource_start(dev, 0);
+	card->csr_len  = pci_resource_len(dev, 0);
+#ifdef CONFIG_MM_MAP_MEMORY
+	card->mem_base = pci_resource_start(dev, 1);
+	card->mem_len  = pci_resource_len(dev, 1);
+#endif
+
+	printk(KERN_INFO "Micro Memory(tm) controller #%d found at %02x:%02x (PCI Mem Module (Battery Backup))\n",
+	       card->card_number, dev->bus->number, dev->devfn);
+
+	if (pci_set_dma_mask(dev, 0xffffffffffffffffLL) &&
+	    !pci_set_dma_mask(dev, 0xffffffffLL)) {
+		printk(KERN_WARNING "MM%d: NO suitable DMA found\n",num_cards);
+		return  -ENOMEM;
+	}
+	if (!request_mem_region(card->csr_base, card->csr_len, "Micro Memory")) {
+		printk(KERN_ERR "MM%d: Unable to request memory region\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_req_csr;
+	}
+
+	card->csr_remap = ioremap_nocache(card->csr_base, card->csr_len);
+	if (!card->csr_remap) {
+		printk(KERN_ERR "MM%d: Unable to remap memory region\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_remap_csr;
+	}
+
+	printk(KERN_INFO "MM%d: CSR 0x%08lx -> 0x%p (0x%lx)\n", card->card_number,
+	       card->csr_base, card->csr_remap, card->csr_len);
+
+#ifdef CONFIG_MM_MAP_MEMORY
+	if (!request_mem_region(card->mem_base, card->mem_len, "Micro Memory")) {
+		printk(KERN_ERR "MM%d: Unable to request memory region\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_req_mem;
+	}
+
+	if (!(card->mem_remap = (unsigned char *)ioremap(card->mem_base, cards->mem_len))) {
+		printk(KERN_ERR "MM%d: Unable to remap memory region\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_remap_mem;
+	}
+
+	printk(KERN_INFO "MM%d: MEM 0x%8lx -> 0x%8lx (0x%lx)\n", card->card_number,
+	       card->mem_base, card->mem_remap, card->mem_len);
+#else
+	printk(KERN_INFO "MM%d: MEM area not remapped (CONFIG_MM_MAP_MEMORY not set)\n",
+	       card->card_number);
+#endif
+	if (readb(card->csr_remap + MEMCTRLSTATUS_MAGIC) != MM_MAGIC_VALUE) {
+		printk(KERN_ERR "MM%d: Magic number invalid\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_magic;
+	}
+	card->mm_pages[0].desc = pci_alloc_consistent(card->dev,
+						      PAGE_SIZE*2,
+						      &card->mm_pages[0].page_dma);
+	card->mm_pages[1].desc = pci_alloc_consistent(card->dev,
+						      PAGE_SIZE*2,
+						      &card->mm_pages[1].page_dma);
+	if (card->mm_pages[0].desc == NULL ||
+	    card->mm_pages[1].desc == NULL) {
+		printk(KERN_ERR "MM%d: alloc failed\n", card->card_number);
+		goto failed_alloc;
+	}
+	reset_page(&card->mm_pages[0]);
+	reset_page(&card->mm_pages[1]);
+	card->Ready = 0;	/* page 0 is ready */
+	card->Active = -1;	/* no page is active */
+	card->bh = NULL;
+	card->bhtail = &card->bh;
+
+	tasklet_init(&card->tasklet, process_page, (unsigned long)card);
+
+	card->plug_tq.sync = 0;
+	card->plug_tq.routine = &mm_unplug_device;
+	card->plug_tq.data = card;
+	card->check_batteries = 0;
+	
+	mem_present = readb(card->csr_remap + MEMCTRLSTATUS_MEMORY);
+	switch (mem_present) {
+	case MEM_128_MB:
+		card->mm_size = 1024 * 128;
+		break;
+	case MEM_256_MB:
+		card->mm_size = 1024 * 256;
+		break;
+	case MEM_512_MB:
+		card->mm_size = 1024 * 512;
+		break;
+	case MEM_1_GB:
+		card->mm_size = 1024 * 1024;
+		break;
+	case MEM_2_GB:
+		card->mm_size = 1024 * 2048;
+		break;
+	default:
+		card->mm_size = 0;
+		break;
+	}
+
+	/* Clear the LED's we control */
+	set_led(card, LED_REMOVE, LED_OFF);
+	set_led(card, LED_FAULT, LED_OFF);
+
+	batt_status = readb(card->csr_remap + MEMCTRLSTATUS_BATTERY);
+
+	card->battery[0].good = !(batt_status & BATTERY_1_FAILURE);
+	card->battery[1].good = !(batt_status & BATTERY_2_FAILURE);
+	card->battery[0].last_change = card->battery[1].last_change = jiffies;
+
+	printk(KERN_INFO "MM%d: Size %d KB, Battery 1 %s (%s), Battery 2 %s (%s)\n",
+	       card->card_number, card->mm_size,
+	       (batt_status & BATTERY_1_DISABLED ? "Disabled" : "Enabled"),
+	       card->battery[0].good ? "OK" : "FAILURE",
+	       (batt_status & BATTERY_2_DISABLED ? "Disabled" : "Enabled"),
+	       card->battery[1].good ? "OK" : "FAILURE");
+
+	set_fault_to_battery_status(card);
+
+	pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &saved_bar);
+	data = 0xffffffff;
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, data);
+	pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &data);
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, saved_bar);
+	data &= 0xfffffff0;
+	data = ~data;
+	data += 1;
+
+	card->win_size = data;
+
+
+	if (request_irq(dev->irq, mm_interrupt, SA_SHIRQ, "pci-umem", card)) {
+		printk(KERN_ERR "MM%d: Unable to allocate IRQ\n", card->card_number);
+		ret = -ENODEV;
+
+		goto failed_req_irq;
+	}
+
+	card->irq = dev->irq;
+	printk(KERN_INFO "MM%d: Window size %d bytes, IRQ %d\n", card->card_number,
+	       card->win_size, card->irq);
+
+        spin_lock_init(&card->lock);
+
+	dev->driver_data = card;
+
+	if (pci_write_cmd != 0x0F) 	/* If not Memory Write & Invalidate */
+		pci_write_cmd = 0x07;	/* then Memory Write command */
+
+	if (pci_write_cmd & 0x08) { /* use Memory Write and Invalidate */
+		unsigned short cfg_command;
+		pci_read_config_word(dev, PCI_COMMAND, &cfg_command);
+		cfg_command |= 0x10; /* Memory Write & Invalidate Enable */
+		pci_write_config_word(dev, PCI_COMMAND, cfg_command);
+	}
+	pci_cmds = (pci_read_cmd << 28) | (pci_write_cmd << 24);
+
+	num_cards++;
+
+	if (init_mem)
+		mm_init_mem(card);
+	else {
+		if (!get_userbit(card, MEMORY_INITIALIZED))
+			printk(KERN_INFO "MM%d: memory NOT initialized. perhaps load with init_mem=1?\n", card->card_number);
+		else
+			printk(KERN_INFO "MM%d: memory already initialized\n", card->card_number);
+	}
+
+	/* Enable ECC */
+	writeb(EDC_STORE_CORRECT, card->csr_remap + MEMCTRLCMD_ERRCTRL);
+
+	return 0;
+
+ failed_req_irq:
+ failed_alloc:
+	if (card->mm_pages[0].desc)
+		pci_free_consistent(card->dev, PAGE_SIZE*2,
+				    card->mm_pages[0].desc,
+				    card->mm_pages[0].page_dma);
+	if (card->mm_pages[1].desc)
+		pci_free_consistent(card->dev, PAGE_SIZE*2,
+				    card->mm_pages[1].desc,
+				    card->mm_pages[1].page_dma);
+ failed_magic:
+#ifdef CONFIG_MM_MAP_MEMORY
+	iounmap((void *) card->mem_remap);
+ failed_remap_mem:
+	release_mem_region(card->mem_base, card->mem_len);
+ failed_req_mem:
+#endif
+	iounmap((void *) card->csr_base);
+ failed_remap_csr:
+	release_mem_region(card->csr_base, card->csr_len);
+ failed_req_csr:
+
+	return ret;
+}
+/*
+-----------------------------------------------------------------------------------
+--                              mm_pci_remove
+-----------------------------------------------------------------------------------
+*/
+static void mm_pci_remove(struct pci_dev *dev)
+{
+	struct cardinfo *card = dev->driver_data;
+
+	tasklet_kill(&card->tasklet);
+	iounmap(card->csr_remap);
+	release_mem_region(card->csr_base, card->csr_len);
+#ifdef CONFIG_MM_MAP_MEMORY
+	iounmap(card->mem_remap);
+	release_mem_region(card->mem_base, card->mem_len);
+#endif
+	free_irq(card->irq, card);
+
+	if (card->mm_pages[0].desc)
+		pci_free_consistent(card->dev, PAGE_SIZE*2,
+				    card->mm_pages[0].desc,
+				    card->mm_pages[0].page_dma);
+	if (card->mm_pages[1].desc)
+		pci_free_consistent(card->dev, PAGE_SIZE*2,
+				    card->mm_pages[1].desc,
+				    card->mm_pages[1].page_dma);
+}
+
+static const struct pci_device_id __devinitdata mm_pci_ids[] = { {
+	vendor:		PCI_VENDOR_ID_MICRO_MEMORY,
+	device:		PCI_DEVICE_ID_MICRO_MEMORY_5415CN,
+	}, { /* end: all zeroes */ }
+};
+
+MODULE_DEVICE_TABLE(pci, mm_pci_ids);
+
+static struct pci_driver mm_pci_driver = {
+	name:		"umem",
+	id_table:	mm_pci_ids,
+	probe:		mm_pci_probe,
+	remove:		mm_pci_remove,
+};
+/*
+-----------------------------------------------------------------------------------
+--                               mm_init
+-----------------------------------------------------------------------------------
+*/
+int __init mm_init(void)
+{
+	int retval, i;
+	int err;
+
+	printk(KERN_INFO DRIVER_VERSION " : " DRIVER_DESC "\n");
+
+	memset (cards,    0, MM_MAXCARDS * sizeof(struct cardinfo));
+	memset (mm_sizes, 0, (MM_MAXCARDS << MM_SHIFT) * sizeof (int));
+	memset (mm_partitions, 0,
+		(MM_MAXCARDS << MM_SHIFT) * sizeof(struct hd_struct));
+
+	retval = pci_module_init(&mm_pci_driver);
+	if (retval)
+		return -ENOMEM;
+
+	err = devfs_register_blkdev(MAJOR_NR, "umem", &mm_fops);
+	if (err < 0) {
+		printk(KERN_ERR "MM: Could not register block device\n");
+		return -EIO;
+	}
+	devfs_handle = devfs_mk_dir(NULL, "umem", NULL);
+
+	read_ahead[MAJOR_NR] = MM_RAHEAD;
+
+
+	/* Initialize partition size: partion 0 of each card is the entire card */
+	for (i = 0; i < num_cards; i++) {
+		mm_sizes[i << MM_SHIFT] = cards[i].mm_size;
+	}
+        mm_gendisk.sizes = mm_sizes;
+
+	for (i = 0; i < num_cards; i++) {
+		spin_lock_init(&cards[i].lock);
+		mm_partitions[i << MM_SHIFT].nr_sects =
+			cards[i].mm_size * (1024 / MM_HARDSECT);
+	}
+
+	mm_gendisk.part      = mm_partitions;
+	mm_gendisk.nr_real   = num_cards;
+
+	mm_gendisk.next   = gendisk_head;
+	gendisk_head = &mm_gendisk;
+
+	blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR),
+			       mm_make_request);
+
+	for (i = 0; i < num_cards << MM_SHIFT; i++) {
+		mm_hardsect[i]   = MM_HARDSECT;
+		mm_blocksizes[i] = MM_BLKSIZE;
+	}
+
+	hardsect_size[MAJOR_NR] = mm_hardsect;
+	blksize_size[MAJOR_NR]  = mm_blocksizes;
+        blk_size[MAJOR_NR]      = mm_gendisk.sizes;
+        for (i = 0; i < num_cards; i++) {
+		register_disk(&mm_gendisk, MKDEV(MAJOR_NR, i<<MM_SHIFT), MM_SHIFT,
+			      &mm_fops, cards[i].mm_size << 1);
+	}
+
+	init_battery_timer();
+	printk("MM: desc_per_page = %ld\n", DESC_PER_PAGE);
+/* printk("mm_init: Done. 10-19-01 9:00\n"); */
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                             mm_cleanup
+-----------------------------------------------------------------------------------
+*/
+void __exit mm_cleanup(void)
+{
+	int i;
+
+	del_battery_timer();
+
+	for (i=0; i < num_cards ; i++)
+		devfs_register_partitions(&mm_gendisk, i<<MM_SHIFT, 1);
+	if (devfs_handle)
+		devfs_unregister(devfs_handle);
+	devfs_handle = NULL;
+
+	pci_unregister_driver(&mm_pci_driver);
+
+	devfs_unregister_blkdev(MAJOR_NR, "umem");
+
+        for (i = 0; i < (num_cards << MM_SHIFT); i++)
+		invalidate_device (MKDEV(MAJOR_NR,i), 1);
+
+	hardsect_size[MAJOR_NR] = NULL;
+	blksize_size [MAJOR_NR] = NULL;
+	blk_size     [MAJOR_NR] = NULL;
+        read_ahead   [MAJOR_NR] = 0;
+
+	/*
+	 * Get our gendisk structure off the list.
+	 */
+	del_gendisk(&mm_gendisk);
+}
+
+module_init(mm_init);
+module_exit(mm_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/xd.c linux/drivers/block/xd.c
--- linux.orig/drivers/block/xd.c	2001-11-09 22:01:21.000000000 +0000
+++ linux/drivers/block/xd.c	2002-07-20 01:08:30.000000000 +0000
@@ -107,6 +107,8 @@
 	{ 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
 	{ 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
 	{ 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller,xd_xebec_init_drive," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
+	{ 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller, xd_wd_init_drive," Western Dig. 1002s-wx2" },
+	{ 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller, xd_wd_init_drive," 1986 Western Digital" }, /* jfree@sovereign.org */
 };
 
 static unsigned int xd_bases[] __initdata =
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/block/z2ram.c linux/drivers/block/z2ram.c
--- linux.orig/drivers/block/z2ram.c	2001-10-25 20:58:35.000000000 +0000
+++ linux/drivers/block/z2ram.c	2002-07-20 01:08:25.000000000 +0000
@@ -38,7 +38,7 @@
 #include <asm/bitops.h>
 #include <asm/amigahw.h>
 #include <asm/pgtable.h>
-#include <asm/io.h>
+
 #include <linux/zorro.h>
 
 
@@ -207,7 +207,7 @@
 						   _PAGE_WRITETHRU);
 
 #else
-		vaddr = (unsigned long)ioremap(paddr, size);
+		vaddr = (unsigned long)z_remap_nocache_nonser(paddr, size);
 #endif
 		z2ram_map = 
 			kmalloc((size/Z2RAM_CHUNKSIZE)*sizeof(z2ram_map[0]),
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/Config.in linux/drivers/bluetooth/Config.in
--- linux.orig/drivers/bluetooth/Config.in	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/bluetooth/Config.in	2002-07-20 01:08:22.000000000 +0000
@@ -2,7 +2,18 @@
 comment 'Bluetooth device drivers'
 
 dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
+if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then
+   bool '  Firmware download support'  CONFIG_BLUEZ_USB_FW_LOAD
+   bool '  USB zero packet support'  CONFIG_BLUEZ_USB_ZERO_PACKET
+fi
+
 dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
-dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
+if [ "$CONFIG_BLUEZ_HCIUART" != "n" ]; then
+   bool '  UART (H4) protocol support' CONFIG_BLUEZ_HCIUART_H4
+fi
+
+dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
+
+dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
 
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/Makefile linux/drivers/bluetooth/Makefile
--- linux.orig/drivers/bluetooth/Makefile	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/bluetooth/Makefile	2002-07-20 01:08:35.000000000 +0000
@@ -4,8 +4,18 @@
 
 O_TARGET	:= bluetooth.o
 
+list-multi	:= hci_uart.o
+
 obj-$(CONFIG_BLUEZ_HCIUSB)	+= hci_usb.o
-obj-$(CONFIG_BLUEZ_HCIUART)	+= hci_uart.o
 obj-$(CONFIG_BLUEZ_HCIVHCI)	+= hci_vhci.o
 
+obj-$(CONFIG_BLUEZ_HCIUART)	+= hci_uart.o
+uart-y				:= hci_ldisc.o
+uart-$(CONFIG_BLUEZ_HCIUART_H4)	+= hci_h4.o
+
+obj-$(CONFIG_BLUEZ_HCIDTL1)	+= dtl1_cs.o
+
 include $(TOPDIR)/Rules.make
+
+hci_uart.o: $(uart-y)
+	$(LD) -r -o $@ $(uart-y)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/dtl1_cs.c linux/drivers/bluetooth/dtl1_cs.c
--- linux.orig/drivers/bluetooth/dtl1_cs.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/bluetooth/dtl1_cs.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,939 @@
+/*
+ *
+ *  A driver for Nokia Connectivity Card DTL-1 devices
+ *
+ *  Copyright (C) 2001-2002  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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;
+ *
+ *  Software distributed under the License is distributed on an "AS
+ *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ *  implied. See the License for the specific language governing
+ *  rights and limitations under the License.
+ *
+ *  The initial developer of the original code is David A. Hinds
+ *  <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ *  are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+
+
+/* ======================== Module parameters ======================== */
+
+
+/* Bit map of interrupts to choose from */
+static u_int irq_mask = 0xffff;
+static int irq_list[4] = { -1 };
+
+MODULE_PARM(irq_mask, "i");
+MODULE_PARM(irq_list, "1-4i");
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("BlueZ driver for Nokia Connectivity Card DTL-1");
+MODULE_LICENSE("GPL");
+
+
+
+/* ======================== Local structures ======================== */
+
+
+typedef struct dtl1_info_t {
+  dev_link_t link;
+  dev_node_t node;
+
+  struct hci_dev hdev;
+
+  spinlock_t lock;          /* For serializing operations */
+
+  unsigned long flowmask;   /* HCI flow mask */
+  int ri_latch;
+
+  struct sk_buff_head txq;
+  unsigned long tx_state;
+
+  unsigned long rx_state;
+  unsigned long rx_count;
+  struct sk_buff *rx_skb;
+
+} dtl1_info_t;
+
+
+void dtl1_config(dev_link_t *link);
+void dtl1_release(u_long arg);
+int dtl1_event(event_t event, int priority, event_callback_args_t *args);
+
+static dev_info_t dev_info = "dtl1_cs";
+
+dev_link_t *dtl1_attach(void);
+void dtl1_detach(dev_link_t *);
+
+dev_link_t *dev_list = NULL;
+
+
+/* Transmit states  */
+#define XMIT_SENDING  1
+#define XMIT_WAKEUP   2
+#define XMIT_WAITING  8
+
+/* Receiver States */
+#define RECV_WAIT_NSH   0
+#define RECV_WAIT_DATA  1
+
+
+typedef struct {
+  u8 type;
+  u8 zero;
+  u16 len;
+} __attribute__ ((packed)) nsh_t;   /* Nokia Specific Header */
+
+#define NSHL  4    /* Nokia Specific Header Length */
+
+
+
+/* ======================== Interrupt handling ======================== */
+
+
+static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) {
+
+  int actual = 0;
+
+
+  /* Tx FIFO should be empty */
+  if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
+    return 0;
+
+
+  /* Fill FIFO with current frame */
+  while ((fifo_size-- > 0) && (actual < len)) {
+    /* Transmit next byte */
+    outb(buf[actual], iobase + UART_TX);
+    actual++;
+  }
+
+
+  return actual;
+
+}
+
+
+static void dtl1_write_wakeup(dtl1_info_t *info) {
+
+  if (!info) {
+    printk(KERN_WARNING "dtl1_cs: Call of write_wakeup for unknown device.\n");
+    return;
+  }
+
+
+  if (test_bit(XMIT_WAITING, &(info->tx_state))) {
+    set_bit(XMIT_WAKEUP, &(info->tx_state));
+    return;
+  }
+
+  if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
+    set_bit(XMIT_WAKEUP, &(info->tx_state));
+    return;
+  }
+
+
+  do {
+    register unsigned int iobase = info->link.io.BasePort1;
+    register struct sk_buff *skb;
+    register int len;
+
+    clear_bit(XMIT_WAKEUP, &(info->tx_state));
+
+    if (!(info->link.state & DEV_PRESENT))
+      return;
+
+
+    if (!(skb = skb_dequeue(&(info->txq))))
+      break;
+
+
+    /* Send frame */
+    len = dtl1_write(iobase, 32, skb->data, skb->len);
+
+    if (len == skb->len) {
+      set_bit(XMIT_WAITING, &(info->tx_state));
+      kfree_skb(skb);
+    }
+    else {
+      skb_pull(skb, len);
+      skb_queue_head(&(info->txq), skb);
+    }
+
+    info->hdev.stat.byte_tx += len;
+
+  } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
+
+
+  clear_bit(XMIT_SENDING, &(info->tx_state));
+
+}
+
+
+static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb) {
+
+  u8 flowmask = *(u8 *)skb->data;
+  int i;
+
+
+  printk(KERN_INFO "dtl1_cs: Nokia control data = ");
+  for (i = 0; i < skb->len; i++) {
+    printk("%02x ", skb->data[i]);
+  }
+  printk("\n");
+
+
+  /* transition to active state */
+  if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
+    clear_bit(XMIT_WAITING, &(info->tx_state));
+    dtl1_write_wakeup(info);
+  }
+
+  info->flowmask = flowmask;
+
+
+  kfree_skb(skb);
+
+}
+
+
+static void dtl1_receive(dtl1_info_t *info) {
+
+  unsigned int iobase;
+  nsh_t *nsh;
+  int boguscount = 0;
+
+
+  if (!info) {
+    printk(KERN_WARNING "dtl1_cs: Call of receive for unknown device.\n");
+    return;
+  }
+
+
+  iobase = info->link.io.BasePort1;
+
+  do {
+    info->hdev.stat.byte_rx++;
+
+    /* Allocate packet */
+    if (info->rx_skb == NULL)
+      if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
+        printk(KERN_WARNING "dtl1_cs: Can't allocate mem for new packet.\n");
+        info->rx_state = RECV_WAIT_NSH;
+        info->rx_count = NSHL;
+        return;
+    }
+
+
+    *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
+    nsh = (nsh_t *)info->rx_skb->data;
+
+    info->rx_count--;
+
+
+    if (info->rx_count == 0) {
+
+      switch (info->rx_state) {
+      case RECV_WAIT_NSH:
+        info->rx_state = RECV_WAIT_DATA;
+        info->rx_count = nsh->len + (nsh->len & 0x0001);
+        break;
+      case RECV_WAIT_DATA:
+        info->rx_skb->pkt_type = nsh->type;
+
+        /* remove PAD byte if it exists */
+        if (nsh->len & 0x0001) {
+          info->rx_skb->tail--;
+          info->rx_skb->len--;
+        }
+
+        /* remove NSH */
+        skb_pull(info->rx_skb, NSHL);
+
+
+        switch (info->rx_skb->pkt_type) {
+        case 0x80:
+          /* control data for the Nokia Card */
+          dtl1_control(info, info->rx_skb);
+          break;
+        case 0x82:
+        case 0x83:
+        case 0x84:
+          /* send frame to the HCI layer */
+          info->rx_skb->dev = (void *)&(info->hdev);
+          info->rx_skb->pkt_type &= 0x0f;
+          hci_recv_frame(info->rx_skb);
+          break;
+        default:
+          /* unknown packet */
+          printk(KERN_WARNING "dtl1_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
+          kfree_skb(info->rx_skb);
+          break;
+        }
+
+
+        info->rx_state = RECV_WAIT_NSH;
+        info->rx_count = NSHL;
+        info->rx_skb = NULL;
+        break;
+      }
+
+    }
+
+
+    /* Make sure we don't stay here to long */
+    if (boguscount++ > 32)
+      break;
+
+  } while (inb(iobase + UART_LSR) & UART_LSR_DR);
+
+
+}
+
+
+void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs) {
+
+  dtl1_info_t *info = dev_inst;
+  unsigned int iobase;
+  unsigned char msr;
+  int boguscount = 0;
+  int iir, lsr;
+
+
+  if (!info) {
+    printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
+    return;
+  }
+
+
+  iobase = info->link.io.BasePort1;
+
+
+  spin_lock(&(info->lock));
+
+  iir = inb(iobase + UART_IIR) & UART_IIR_ID;
+  while (iir) {
+
+    /* Clear interrupt */
+    lsr = inb(iobase + UART_LSR);
+
+    switch (iir) {
+    case UART_IIR_RLSI:
+      printk(KERN_NOTICE "dtl1_cs: RLSI\n");
+      break;
+    case UART_IIR_RDI:
+      /* Receive interrupt */
+      dtl1_receive(info);
+      break;
+    case UART_IIR_THRI:
+      if (lsr & UART_LSR_THRE) {
+        /* Transmitter ready for data */
+        dtl1_write_wakeup(info);
+      }
+      break;
+    default:
+      printk(KERN_NOTICE "dtl1_cs: Unhandled IIR=%#x\n", iir);
+      break;
+    }
+
+    /* Make sure we don't stay here to long */
+    if (boguscount++ > 100)
+      break;
+
+    iir = inb(iobase + UART_IIR) & UART_IIR_ID;
+
+  }
+
+
+  msr = inb(iobase + UART_MSR);
+
+  if (info->ri_latch ^ (msr & UART_MSR_RI)) {
+    info->ri_latch = msr & UART_MSR_RI;
+    clear_bit(XMIT_WAITING, &(info->tx_state));
+    dtl1_write_wakeup(info);
+  }
+
+  spin_unlock(&(info->lock));
+
+}
+
+
+
+/* ======================== HCI interface ======================== */
+
+
+static int dtl1_hci_open(struct hci_dev *hdev) {
+
+  set_bit(HCI_RUNNING, &(hdev->flags));
+
+
+  return 0;
+
+}
+
+
+static int dtl1_hci_flush(struct hci_dev *hdev) {
+
+  dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
+
+
+  /* Drop TX queue */
+  skb_queue_purge(&(info->txq));
+
+
+  return 0;
+
+}
+
+
+static int dtl1_hci_close(struct hci_dev *hdev) {
+
+  if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
+    return 0;
+
+
+  dtl1_hci_flush(hdev);
+
+
+  return 0;
+
+}
+
+
+static int dtl1_hci_send_frame(struct sk_buff *skb) {
+
+  dtl1_info_t *info;
+  struct hci_dev* hdev = (struct hci_dev *)(skb->dev);
+  struct sk_buff *s;
+  nsh_t nsh;
+
+
+  if (!hdev) {
+    printk(KERN_WARNING "dtl1_cs: Frame for unknown HCI device (hdev=NULL).");
+    return -ENODEV;
+  }
+
+  info = (dtl1_info_t *)(hdev->driver_data);
+
+
+  switch (skb->pkt_type) {
+  case HCI_COMMAND_PKT:
+    hdev->stat.cmd_tx++;
+    nsh.type = 0x81;
+    break;
+  case HCI_ACLDATA_PKT:
+    hdev->stat.acl_tx++;
+    nsh.type = 0x82;
+    break;
+  case HCI_SCODATA_PKT:
+    hdev->stat.sco_tx++;
+    nsh.type = 0x83;
+    break;
+  };
+
+  nsh.zero = 0;
+  nsh.len = skb->len;
+
+  s = bluez_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
+  skb_reserve(s, NSHL);
+  memcpy(skb_put(s, skb->len), skb->data, skb->len);
+  if (skb->len & 0x0001)
+    *skb_put(s, 1) = 0;  /* PAD */
+
+  /* Prepend skb with Nokia frame header and queue */
+  memcpy(skb_push(s, NSHL), &nsh, NSHL);
+  skb_queue_tail(&(info->txq), s);
+
+
+  dtl1_write_wakeup(info);
+
+  kfree_skb(skb);
+
+
+  return 0;
+
+}
+
+
+static void dtl1_hci_destruct(struct hci_dev *hdev) {
+}
+
+
+static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) {
+
+  return -ENOIOCTLCMD;
+
+}
+
+
+
+/* ======================== Card services HCI interaction ======================== */
+
+
+int dtl1_open(dtl1_info_t *info) {
+
+  unsigned long flags;
+  unsigned int iobase = info->link.io.BasePort1;
+  struct hci_dev *hdev;
+
+
+  spin_lock_init(&(info->lock));
+
+  skb_queue_head_init(&(info->txq));
+
+  info->rx_state = RECV_WAIT_NSH;
+  info->rx_count = NSHL;
+  info->rx_skb = NULL;
+
+  set_bit(XMIT_WAITING, &(info->tx_state));
+
+
+  spin_lock_irqsave(&(info->lock), flags);
+
+  /* Reset UART */
+  outb(0, iobase + UART_MCR);
+
+  /* Turn off interrupts */
+  outb(0, iobase + UART_IER);
+
+  /* Initialize UART */
+  outb(UART_LCR_WLEN8, iobase + UART_LCR);  /* Reset DLAB */
+  outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
+
+  info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
+
+  /* Turn on interrupts */
+  outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
+
+  spin_unlock_irqrestore(&(info->lock), flags);
+
+
+  /* Timeout before it is safe to send the first HCI packet */
+  set_current_state(TASK_INTERRUPTIBLE);
+  schedule_timeout(HZ * 2);
+
+
+  /* Initialize and register HCI device */
+
+  hdev = &(info->hdev);
+
+  hdev->type = HCI_PCCARD;
+  hdev->driver_data = info;
+
+  hdev->open     = dtl1_hci_open;
+  hdev->close    = dtl1_hci_close;
+  hdev->flush    = dtl1_hci_flush;
+  hdev->send     = dtl1_hci_send_frame;
+  hdev->destruct = dtl1_hci_destruct;
+  hdev->ioctl    = dtl1_hci_ioctl;
+
+  if (hci_register_dev(hdev) < 0) {
+    printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
+    return -ENODEV;
+  }
+
+
+  return 0;
+
+}
+
+
+int dtl1_close(dtl1_info_t *info) {
+
+  unsigned long flags;
+  unsigned int iobase = info->link.io.BasePort1;
+  struct hci_dev *hdev = &(info->hdev);
+
+
+  dtl1_hci_close(hdev);
+
+
+  spin_lock_irqsave(&(info->lock), flags);
+
+  /* Reset UART */
+  outb(0, iobase + UART_MCR);
+
+  /* Turn off interrupts */
+  outb(0, iobase + UART_IER);
+
+  spin_unlock_irqrestore(&(info->lock), flags);
+
+
+  if (hci_unregister_dev(hdev) < 0)
+    printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.\n", hdev->name);
+
+
+  return 0;
+
+}
+
+
+
+/* ======================== Card services ======================== */
+
+
+static void cs_error(client_handle_t handle, int func, int ret) {
+
+  error_info_t err = { func, ret };
+
+
+  CardServices(ReportError, handle, &err);
+
+}
+
+
+dev_link_t *dtl1_attach(void) {
+
+  dtl1_info_t *info;
+  client_reg_t client_reg;
+  dev_link_t *link;
+  int i, ret;
+
+
+  /* Create new info device */
+  info = kmalloc(sizeof(*info), GFP_KERNEL);
+  if (!info)
+    return NULL;
+  memset(info, 0, sizeof(*info));
+
+
+  link = &info->link;
+  link->priv = info;
+
+  link->release.function = &dtl1_release;
+  link->release.data = (u_long)link;
+  link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+  link->io.NumPorts1 = 8;
+  link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+  link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
+
+  if (irq_list[0] == -1)
+    link->irq.IRQInfo2 = irq_mask;
+  else
+    for (i = 0; i < 4; i++)
+      link->irq.IRQInfo2 |= 1 << irq_list[i];
+
+  link->irq.Handler = dtl1_interrupt;
+  link->irq.Instance = info;
+
+  link->conf.Attributes = CONF_ENABLE_IRQ;
+  link->conf.Vcc = 50;
+  link->conf.IntType = INT_MEMORY_AND_IO;
+
+
+  /* Register with Card Services */
+  link->next = dev_list;
+  dev_list = link;
+  client_reg.dev_info = &dev_info;
+  client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+  client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+                         CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+                         CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+  client_reg.event_handler = &dtl1_event;
+  client_reg.Version = 0x0210;
+  client_reg.event_callback_args.client_data = link;
+
+  ret = CardServices(RegisterClient, &link->handle, &client_reg);
+  if (ret != CS_SUCCESS) {
+    cs_error(link->handle, RegisterClient, ret);
+    dtl1_detach(link);
+    return NULL;
+  }
+
+
+  return link;
+
+}
+
+
+void dtl1_detach(dev_link_t *link) {
+
+  dtl1_info_t *info = link->priv;
+  dev_link_t **linkp;
+  int ret;
+
+
+  /* Locate device structure */
+  for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+    if (*linkp == link)
+      break;
+
+  if (*linkp == NULL)
+    return;
+
+
+  del_timer(&link->release);
+  if (link->state & DEV_CONFIG)
+    dtl1_release((u_long)link);
+
+
+  if (link->handle) {
+    ret = CardServices(DeregisterClient, link->handle);
+    if (ret != CS_SUCCESS)
+      cs_error(link->handle, DeregisterClient, ret);
+  }
+
+
+  /* Unlink device structure, free bits */
+  *linkp = link->next;
+
+  kfree(info);
+
+}
+
+
+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
+		     cisparse_t *parse) {
+
+  int i;
+
+
+  i = CardServices(fn, handle, tuple);
+  if (i != CS_SUCCESS)
+    return CS_NO_MORE_ITEMS;
+
+  i = CardServices(GetTupleData, handle, tuple);
+  if (i != CS_SUCCESS)
+    return i;
+
+  return CardServices(ParseTuple, handle, tuple, parse);
+
+}
+
+
+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
+
+void dtl1_config(dev_link_t *link) {
+
+  client_handle_t handle = link->handle;
+  dtl1_info_t *info = link->priv;
+  tuple_t tuple;
+  u_short buf[256];
+  cisparse_t parse;
+  cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+  config_info_t config;
+  int i, last_ret, last_fn;
+
+
+  tuple.TupleData = (cisdata_t *)buf;
+  tuple.TupleOffset = 0;
+  tuple.TupleDataMax = 255;
+  tuple.Attributes = 0;
+
+  /* Get configuration register information */
+  tuple.DesiredTuple = CISTPL_CONFIG;
+  last_ret = first_tuple(handle, &tuple, &parse);
+  if (last_ret != CS_SUCCESS) {
+    last_fn = ParseTuple;
+    goto cs_failed;
+  }
+  link->conf.ConfigBase = parse.config.base;
+  link->conf.Present = parse.config.rmask[0];
+
+
+  /* Configure card */
+  link->state |= DEV_CONFIG;
+  i = CardServices(GetConfigurationInfo, handle, &config);
+  link->conf.Vcc = config.Vcc;
+
+  tuple.TupleData = (cisdata_t *)buf;
+  tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
+  tuple.Attributes = 0;
+  tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+
+  /* Look for a generic full-sized window */
+  link->io.NumPorts1 = 8;
+  i = first_tuple(handle, &tuple, &parse);
+  while (i != CS_NO_MORE_ITEMS) {
+    if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
+      link->conf.ConfigIndex = cf->index;
+      link->io.BasePort1 = cf->io.win[0].base;
+      link->io.NumPorts1 = cf->io.win[0].len; /*yo*/
+      link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+      i = CardServices(RequestIO, link->handle, &link->io);
+      if (i == CS_SUCCESS)
+        break;
+    }
+    i = next_tuple(handle, &tuple, &parse);
+  }
+
+  if (i != CS_SUCCESS) {
+    cs_error(link->handle, RequestIO, i);
+    goto failed;
+  }
+
+  i = CardServices(RequestIRQ, link->handle, &link->irq);
+  if (i != CS_SUCCESS) {
+    cs_error(link->handle, RequestIRQ, i);
+    link->irq.AssignedIRQ = 0;
+  }
+
+  i = CardServices(RequestConfiguration, link->handle, &link->conf);
+  if (i != CS_SUCCESS) {
+    cs_error(link->handle, RequestConfiguration, i);
+    goto failed;
+  }
+
+
+  MOD_INC_USE_COUNT;
+
+  if (dtl1_open(info) != 0)
+    goto failed;
+
+
+  link->dev = &info->node;
+  link->state &= ~DEV_CONFIG_PENDING;
+
+
+  return;
+
+
+cs_failed:
+  cs_error(link->handle, last_fn, last_ret);
+failed:
+  dtl1_release((u_long)link);
+
+}
+
+
+void dtl1_release(u_long arg) {
+
+  dev_link_t *link = (dev_link_t *)arg;
+  dtl1_info_t *info = link->priv;
+
+
+  if (link->state & DEV_PRESENT)
+    dtl1_close(info);
+
+  MOD_DEC_USE_COUNT;
+
+
+  link->dev = NULL;
+
+  CardServices(ReleaseConfiguration, link->handle);
+  CardServices(ReleaseIO, link->handle, &link->io);
+  CardServices(ReleaseIRQ, link->handle, &link->irq);
+
+  link->state &= ~DEV_CONFIG;
+
+}
+
+
+int dtl1_event(event_t event, int priority, event_callback_args_t *args) {
+
+  dev_link_t *link = args->client_data;
+  dtl1_info_t *info = link->priv;
+
+
+  switch (event) {
+  case CS_EVENT_CARD_REMOVAL:
+    link->state &= ~DEV_PRESENT;
+    if (link->state & DEV_CONFIG) {
+      dtl1_close(info);
+      mod_timer(&link->release, jiffies + HZ/20);
+    }
+    break;
+  case CS_EVENT_CARD_INSERTION:
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    dtl1_config(link);
+    break;
+  case CS_EVENT_PM_SUSPEND:
+    link->state |= DEV_SUSPEND;
+    /* Fall through... */
+  case CS_EVENT_RESET_PHYSICAL:
+    if (link->state & DEV_CONFIG)
+      CardServices(ReleaseConfiguration, link->handle);
+    break;
+  case CS_EVENT_PM_RESUME:
+    link->state &= ~DEV_SUSPEND;
+    /* Fall through... */
+  case CS_EVENT_CARD_RESET:
+    if (DEV_OK(link))
+      CardServices(RequestConfiguration, link->handle, &link->conf);
+    break;
+  }
+
+
+  return 0;
+
+}
+
+
+
+/* ======================== Module initialization ======================== */
+
+
+int __init init_dtl1_cs(void) {
+
+  servinfo_t serv;
+  int err;
+
+
+  CardServices(GetCardServicesInfo, &serv);
+  if (serv.Revision != CS_RELEASE_CODE) {
+    printk(KERN_NOTICE "dtl1_cs: Card Services release does not match!\n");
+    return -1;
+  }
+
+
+  err = register_pccard_driver(&dev_info, &dtl1_attach, &dtl1_detach);
+
+
+  return err;
+
+}
+
+void __exit exit_dtl1_cs(void) {
+
+  unregister_pccard_driver(&dev_info);
+
+  while (dev_list != NULL)
+    dtl1_detach(dev_list);
+
+}
+
+
+module_init(init_dtl1_cs);
+module_exit(exit_dtl1_cs);
+
+EXPORT_NO_SYMBOLS;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_h4.c linux/drivers/bluetooth/hci_h4.c
--- linux.orig/drivers/bluetooth/hci_h4.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/bluetooth/hci_h4.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,273 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * BlueZ HCI UART(H4) protocol.
+ *
+ * $Id: hci_h4.c,v 1.2 2002/04/17 17:37:20 maxk Exp $    
+ */
+#define VERSION "1.1"
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/poll.h>
+
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include "hci_uart.h"
+#include "hci_h4.h"
+
+#ifndef HCI_UART_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#undef  BT_DMP
+#define BT_DMP( A... )
+#endif
+
+/* Initialize protocol */
+static int h4_open(struct n_hci *n_hci)
+{
+	struct h4_struct *h4;
+	
+	BT_DBG("n_hci %p", n_hci);
+	
+	h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
+	if (!h4)
+		return -ENOMEM;
+	memset(h4, 0, sizeof(*h4));
+
+	n_hci->priv = h4;
+	return 0;
+}
+
+/* Flush protocol data */
+static int h4_flush(struct n_hci *n_hci)
+{
+	BT_DBG("n_hci %p", n_hci);
+	return 0;
+}
+
+/* Close protocol */
+static int h4_close(struct n_hci *n_hci)
+{
+	struct h4_struct *h4 = n_hci->priv;
+	n_hci->priv = NULL;
+
+	BT_DBG("n_hci %p", n_hci);
+
+	if (h4->rx_skb)
+		kfree_skb(h4->rx_skb);
+
+	kfree(h4);
+	return 0;
+}
+
+/* Send data */
+static int h4_send(struct n_hci *n_hci, void *data, int len)
+{
+	struct tty_struct *tty = n_hci->tty;
+	
+	BT_DBG("n_hci %p len %d", n_hci, len);
+
+	/* Send frame to TTY driver */
+	tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
+	return tty->driver.write(tty, 0, data, len);
+}
+
+/* Init frame before queueing (padding, crc, etc) */
+static struct sk_buff* h4_preq(struct n_hci *n_hci, struct sk_buff *skb)
+{
+	BT_DBG("n_hci %p skb %p", n_hci, skb);
+
+	/* Prepend skb with frame type */
+	memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
+	return skb;
+}
+
+static inline int h4_check_data_len(struct h4_struct *h4, int len)
+{
+	register int room = skb_tailroom(h4->rx_skb);
+
+	BT_DBG("len %d room %d", len, room);
+	if (!len) {
+		BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
+		hci_recv_frame(h4->rx_skb);
+	} else if (len > room) {
+		BT_ERR("Data length is to large");
+		kfree_skb(h4->rx_skb);
+	} else {
+		h4->rx_state = H4_W4_DATA;
+		h4->rx_count = len;
+		return len;
+	}
+
+	h4->rx_state = H4_W4_PACKET_TYPE;
+	h4->rx_skb   = NULL;
+	h4->rx_count = 0;
+	return 0;
+}
+
+/* Recv data */
+static int h4_recv(struct n_hci *n_hci, void *data, int count)
+{
+	struct h4_struct *h4 = n_hci->priv;
+	register char *ptr;
+	hci_event_hdr *eh;
+	hci_acl_hdr   *ah;
+	hci_sco_hdr   *sh;
+	register int len, type, dlen;
+
+	BT_DBG("n_hci %p count %d rx_state %ld rx_count %ld", n_hci, count, h4->rx_state, h4->rx_count);
+
+	ptr = data;
+	while (count) {
+		if (h4->rx_count) {
+			len = MIN(h4->rx_count, count);
+			memcpy(skb_put(h4->rx_skb, len), ptr, len);
+			h4->rx_count -= len; count -= len; ptr += len;
+
+			if (h4->rx_count)
+				continue;
+
+			switch (h4->rx_state) {
+			case H4_W4_DATA:
+				BT_DBG("Complete data");
+
+				BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
+
+				hci_recv_frame(h4->rx_skb);
+
+				h4->rx_state = H4_W4_PACKET_TYPE;
+				h4->rx_skb = NULL;
+				continue;
+
+			case H4_W4_EVENT_HDR:
+				eh = (hci_event_hdr *) h4->rx_skb->data;
+
+				BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
+
+				h4_check_data_len(h4, eh->plen);
+				continue;
+
+			case H4_W4_ACL_HDR:
+				ah = (hci_acl_hdr *) h4->rx_skb->data;
+				dlen = __le16_to_cpu(ah->dlen);
+
+				BT_DBG("ACL header: dlen %d", dlen);
+
+				h4_check_data_len(h4, dlen);
+				continue;
+
+			case H4_W4_SCO_HDR:
+				sh = (hci_sco_hdr *) h4->rx_skb->data;
+
+				BT_DBG("SCO header: dlen %d", sh->dlen);
+
+				h4_check_data_len(h4, sh->dlen);
+				continue;
+			};
+		}
+
+		/* H4_W4_PACKET_TYPE */
+		switch (*ptr) {
+		case HCI_EVENT_PKT:
+			BT_DBG("Event packet");
+			h4->rx_state = H4_W4_EVENT_HDR;
+			h4->rx_count = HCI_EVENT_HDR_SIZE;
+			type = HCI_EVENT_PKT;
+			break;
+
+		case HCI_ACLDATA_PKT:
+			BT_DBG("ACL packet");
+			h4->rx_state = H4_W4_ACL_HDR;
+			h4->rx_count = HCI_ACL_HDR_SIZE;
+			type = HCI_ACLDATA_PKT;
+			break;
+
+		case HCI_SCODATA_PKT:
+			BT_DBG("SCO packet");
+			h4->rx_state = H4_W4_SCO_HDR;
+			h4->rx_count = HCI_SCO_HDR_SIZE;
+			type = HCI_SCODATA_PKT;
+			break;
+
+		default:
+			BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
+			n_hci->hdev.stat.err_rx++;
+			ptr++; count--;
+			continue;
+		};
+		ptr++; count--;
+
+		/* Allocate packet */
+		h4->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
+		if (!h4->rx_skb) {
+			BT_ERR("Can't allocate mem for new packet");
+			h4->rx_state = H4_W4_PACKET_TYPE;
+			h4->rx_count = 0;
+			return 0;
+		}
+		h4->rx_skb->dev = (void *) &n_hci->hdev;
+		h4->rx_skb->pkt_type = type;
+	}
+	return count;
+}
+
+static struct hci_uart_proto h4p = {
+	id:    HCI_UART_H4,
+	open:  h4_open,
+	close: h4_close,
+	send:  h4_send,
+	recv:  h4_recv,
+	preq:  h4_preq,
+	flush: h4_flush,
+};
+	      
+int h4_init(void)
+{
+	return hci_uart_register_proto(&h4p);
+}
+
+int h4_deinit(void)
+{
+	return hci_uart_unregister_proto(&h4p);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_h4.h linux/drivers/bluetooth/hci_h4.h
--- linux.orig/drivers/bluetooth/hci_h4.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/bluetooth/hci_h4.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,43 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * $Id: hci_h4.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
+ */
+
+#ifdef __KERNEL__
+struct h4_struct {
+	unsigned long rx_state;
+	unsigned long rx_count;
+	struct sk_buff *rx_skb;
+};
+
+/* H4 receiver States */
+#define H4_W4_PACKET_TYPE 0
+#define H4_W4_EVENT_HDR	  1
+#define H4_W4_ACL_HDR     2
+#define H4_W4_SCO_HDR     3
+#define H4_W4_DATA        4
+
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_ldisc.c linux/drivers/bluetooth/hci_ldisc.c
--- linux.orig/drivers/bluetooth/hci_ldisc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/bluetooth/hci_ldisc.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,554 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * BlueZ HCI UART driver.
+ *
+ * $Id: hci_ldisc.c,v 1.2 2002/04/17 17:37:20 maxk Exp $    
+ */
+#define VERSION "2.0"
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/poll.h>
+
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include "hci_uart.h"
+
+#ifndef HCI_UART_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#undef  BT_DMP
+#define BT_DMP( A... )
+#endif
+
+static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
+
+int hci_uart_register_proto(struct hci_uart_proto *p)
+{
+	if (p->id >= HCI_UART_MAX_PROTO)
+		return -EINVAL;
+
+	if (hup[p->id])
+		return -EEXIST;
+
+	hup[p->id] = p;
+	return 0;
+}
+
+int hci_uart_unregister_proto(struct hci_uart_proto *p)
+{
+	if (p->id >= HCI_UART_MAX_PROTO)
+		return -EINVAL;
+
+	if (!hup[p->id])
+		return -EINVAL;
+
+	hup[p->id] = NULL;
+	return 0;
+}
+
+static struct hci_uart_proto *n_hci_get_proto(unsigned int id)
+{
+	if (id >= HCI_UART_MAX_PROTO)
+		return NULL;
+	return hup[id];
+}
+
+/* ------- Interface to HCI layer ------ */
+/* Initialize device */
+static int n_hci_open(struct hci_dev *hdev)
+{
+	BT_DBG("%s %p", hdev->name, hdev);
+
+	/* Nothing to do for UART driver */
+
+	set_bit(HCI_RUNNING, &hdev->flags);
+	return 0;
+}
+
+/* Reset device */
+static int n_hci_flush(struct hci_dev *hdev)
+{
+	struct n_hci *n_hci  = (struct n_hci *) hdev->driver_data;
+	struct tty_struct *tty = n_hci->tty;
+
+	BT_DBG("hdev %p tty %p", hdev, tty);
+
+	/* Drop TX queue */
+	skb_queue_purge(&n_hci->txq);
+
+	/* Flush any pending characters in the driver and discipline. */
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+
+	if (n_hci->proto->flush)
+		n_hci->proto->flush(n_hci);
+
+	return 0;
+}
+
+/* Close device */
+static int n_hci_close(struct hci_dev *hdev)
+{
+	BT_DBG("hdev %p", hdev);
+
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	n_hci_flush(hdev);
+	return 0;
+}
+
+static int n_hci_tx_wakeup(struct n_hci *n_hci)
+{
+	struct hci_dev *hdev = &n_hci->hdev;
+	
+	if (test_and_set_bit(N_HCI_SENDING, &n_hci->tx_state)) {
+		set_bit(N_HCI_TX_WAKEUP, &n_hci->tx_state);
+		return 0;
+	}
+
+	BT_DBG("");
+	do {
+		register struct sk_buff *skb;
+		register int len;
+
+		clear_bit(N_HCI_TX_WAKEUP, &n_hci->tx_state);
+
+		if (!(skb = skb_dequeue(&n_hci->txq)))
+			break;
+
+		len = n_hci->proto->send(n_hci, skb->data, skb->len);
+		n_hci->hdev.stat.byte_tx += len;
+
+		if (len == skb->len) {
+			/* Complete frame was sent */
+
+			switch (skb->pkt_type) {
+			case HCI_COMMAND_PKT:
+				hdev->stat.cmd_tx++;
+				break;
+
+			case HCI_ACLDATA_PKT:
+				hdev->stat.acl_tx++;
+				break;
+
+			case HCI_SCODATA_PKT:
+				hdev->stat.cmd_tx++;
+				break;
+			};
+
+			kfree_skb(skb);
+		} else {
+			/* Subtract sent part and requeue  */
+			skb_pull(skb, len);
+			skb_queue_head(&n_hci->txq, skb);
+		}
+	} while (test_bit(N_HCI_TX_WAKEUP, &n_hci->tx_state));
+	clear_bit(N_HCI_SENDING, &n_hci->tx_state);
+	return 0;
+}
+
+/* Send frames from HCI layer */
+static int n_hci_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
+	struct tty_struct *tty;
+	struct n_hci *n_hci;
+
+	if (!hdev) {
+		BT_ERR("Frame for uknown device (hdev=NULL)");
+		return -ENODEV;
+	}
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return -EBUSY;
+
+	n_hci = (struct n_hci *) hdev->driver_data;
+	tty = n_hci->tty;
+
+	BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
+
+	if (n_hci->proto->preq) {
+		skb = n_hci->proto->preq(n_hci, skb);
+		if (!skb)
+			return 0;
+	}
+	
+	skb_queue_tail(&n_hci->txq, skb);
+	n_hci_tx_wakeup(n_hci);
+	return 0;
+}
+
+static void n_hci_destruct(struct hci_dev *hdev)
+{
+	struct n_hci *n_hci;
+
+	if (!hdev) return;
+
+	BT_DBG("%s", hdev->name);
+
+	n_hci = (struct n_hci *) hdev->driver_data;
+	kfree(n_hci);
+
+	MOD_DEC_USE_COUNT;
+}
+
+/* ------ LDISC part ------ */
+/* n_hci_tty_open
+ * 
+ *     Called when line discipline changed to N_HCI.
+ *
+ * Arguments:
+ *     tty    pointer to tty info structure
+ * Return Value:    
+ *     0 if success, otherwise error code
+ */
+static int n_hci_tty_open(struct tty_struct *tty)
+{
+	struct n_hci *n_hci = (void *)tty->disc_data;
+
+	BT_DBG("tty %p", tty);
+
+	if (n_hci)
+		return -EEXIST;
+
+	if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
+		BT_ERR("Can't allocate controll structure");
+		return -ENFILE;
+	}
+	memset(n_hci, 0, sizeof(struct n_hci));
+
+	tty->disc_data = n_hci;
+	n_hci->tty = tty;
+
+	spin_lock_init(&n_hci->rx_lock);
+	skb_queue_head_init(&n_hci->txq);
+
+	/* Flush any pending characters in the driver and line discipline */
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+/* n_hci_tty_close()
+ *
+ *    Called when the line discipline is changed to something
+ *    else, the tty is closed, or the tty detects a hangup.
+ */
+static void n_hci_tty_close(struct tty_struct *tty)
+{
+	struct n_hci *n_hci = (void *)tty->disc_data;
+
+	BT_DBG("tty %p", tty);
+
+	/* Detach from the tty */
+	tty->disc_data = NULL;
+
+	if (n_hci) {
+		struct hci_dev *hdev = &n_hci->hdev;
+		n_hci_close(hdev);
+
+		if (test_and_clear_bit(N_HCI_PROTO_SET, &n_hci->flags)) {
+			n_hci->proto->close(n_hci);
+			hci_unregister_dev(hdev);
+		}
+				
+		MOD_DEC_USE_COUNT;
+	}
+}
+
+/* n_hci_tty_wakeup()
+ *
+ *    Callback for transmit wakeup. Called when low level
+ *    device driver can accept more send data.
+ *
+ * Arguments:        tty    pointer to associated tty instance data
+ * Return Value:    None
+ */
+static void n_hci_tty_wakeup( struct tty_struct *tty )
+{
+	struct n_hci *n_hci = (void *)tty->disc_data;
+
+	BT_DBG("");
+
+	if (!n_hci)
+		return;
+
+	tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
+
+	if (tty != n_hci->tty)
+		return;
+
+	n_hci_tx_wakeup(n_hci);
+}
+
+/* n_hci_tty_room()
+ * 
+ *    Callback function from tty driver. Return the amount of 
+ *    space left in the receiver's buffer to decide if remote
+ *    transmitter is to be throttled.
+ *
+ * Arguments:        tty    pointer to associated tty instance data
+ * Return Value:    number of bytes left in receive buffer
+ */
+static int n_hci_tty_room (struct tty_struct *tty)
+{
+	return 65536;
+}
+
+/* n_hci_tty_receive()
+ * 
+ *     Called by tty low level driver when receive data is
+ *     available.
+ *     
+ * Arguments:  tty          pointer to tty isntance data
+ *             data         pointer to received data
+ *             flags        pointer to flags for data
+ *             count        count of received data in bytes
+ *     
+ * Return Value:    None
+ */
+static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
+{
+	struct n_hci *n_hci = (void *)tty->disc_data;
+	
+	if (!n_hci || tty != n_hci->tty)
+		return;
+
+	if (!test_bit(N_HCI_PROTO_SET, &n_hci->flags))
+		return;
+	
+	spin_lock(&n_hci->rx_lock);
+	n_hci->proto->recv(n_hci, (void *) data, count);
+	n_hci->hdev.stat.byte_rx += count;
+	spin_unlock(&n_hci->rx_lock);
+
+	if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
+		tty->driver.unthrottle(tty);
+}
+
+static int n_hci_register_dev(struct n_hci *n_hci)
+{
+	struct hci_dev *hdev;
+
+	BT_DBG("");
+
+	/* Initialize and register HCI device */
+	hdev = &n_hci->hdev;
+
+	hdev->type = HCI_UART;
+	hdev->driver_data = n_hci;
+
+	hdev->open  = n_hci_open;
+	hdev->close = n_hci_close;
+	hdev->flush = n_hci_flush;
+	hdev->send  = n_hci_send_frame;
+	hdev->destruct = n_hci_destruct;
+
+	if (hci_register_dev(hdev) < 0) {
+		BT_ERR("Can't register HCI device %s", hdev->name);
+		return -ENODEV;
+	}
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int n_hci_set_proto(struct n_hci *n_hci, int id)
+{
+	struct hci_uart_proto *p;
+	int err;	
+	
+	p = n_hci_get_proto(id);
+	if (!p)
+		return -EPROTONOSUPPORT;
+
+	err = p->open(n_hci);
+	if (err)
+		return err;
+
+	n_hci->proto = p;
+
+	err = n_hci_register_dev(n_hci);
+	if (err) {
+		p->close(n_hci);
+		return err;
+	}
+	return 0;
+}
+
+/* n_hci_tty_ioctl()
+ *
+ *    Process IOCTL system call for the tty device.
+ *
+ * Arguments:
+ *
+ *    tty        pointer to tty instance data
+ *    file       pointer to open file object for device
+ *    cmd        IOCTL command code
+ *    arg        argument for IOCTL call (cmd dependent)
+ *
+ * Return Value:    Command dependent
+ */
+static int n_hci_tty_ioctl(struct tty_struct *tty, struct file * file,
+                            unsigned int cmd, unsigned long arg)
+{
+	struct n_hci *n_hci = (void *)tty->disc_data;
+	int err = 0;
+
+	BT_DBG("");
+
+	/* Verify the status of the device */
+	if (!n_hci)
+		return -EBADF;
+
+	switch (cmd) {
+	case HCIUARTSETPROTO:
+		if (!test_and_set_bit(N_HCI_PROTO_SET, &n_hci->flags)) {
+			err = n_hci_set_proto(n_hci, arg);
+			if (err) {
+				clear_bit(N_HCI_PROTO_SET, &n_hci->flags);
+				return err;
+			}
+			tty->low_latency = 1;
+		} else	
+			return -EBUSY;
+
+	case HCIUARTGETPROTO:
+		if (test_bit(N_HCI_PROTO_SET, &n_hci->flags))
+			return n_hci->proto->id;
+		return -EUNATCH;
+		
+	default:
+		err = n_tty_ioctl(tty, file, cmd, arg);
+		break;
+	};
+
+	return err;
+}
+
+/*
+ * We don't provide read/write/poll interface for user space.
+ */
+static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
+{
+	return 0;
+}
+static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
+{
+	return 0;
+}
+static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
+{
+	return 0;
+}
+
+#ifdef CONFIG_BLUEZ_HCIUART_H4
+int h4_init(void);
+int h4_deinit(void);
+#endif
+
+int __init n_hci_init(void)
+{
+	static struct tty_ldisc n_hci_ldisc;
+	int err;
+
+	BT_INFO("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc", 
+		VERSION);
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+
+	/* Register the tty discipline */
+
+	memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
+	n_hci_ldisc.magic       = TTY_LDISC_MAGIC;
+	n_hci_ldisc.name        = "n_hci";
+	n_hci_ldisc.open        = n_hci_tty_open;
+	n_hci_ldisc.close       = n_hci_tty_close;
+	n_hci_ldisc.read        = n_hci_tty_read;
+	n_hci_ldisc.write       = n_hci_tty_write;
+	n_hci_ldisc.ioctl       = n_hci_tty_ioctl;
+	n_hci_ldisc.poll        = n_hci_tty_poll;
+	n_hci_ldisc.receive_room= n_hci_tty_room;
+	n_hci_ldisc.receive_buf = n_hci_tty_receive;
+	n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
+
+	if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
+		BT_ERR("Can't register HCI line discipline (%d)", err);
+		return err;
+	}
+
+#ifdef CONFIG_BLUEZ_HCIUART_H4
+	h4_init();
+#endif
+	
+	return 0;
+}
+
+void n_hci_cleanup(void)
+{
+	int err;
+
+#ifdef CONFIG_BLUEZ_HCIUART_H4
+	h4_deinit();
+#endif
+
+	/* Release tty registration of line discipline */
+	if ((err = tty_register_ldisc(N_HCI, NULL)))
+		BT_ERR("Can't unregister HCI line discipline (%d)", err);
+}
+
+module_init(n_hci_init);
+module_exit(n_hci_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_uart.c linux/drivers/bluetooth/hci_uart.c
--- linux.orig/drivers/bluetooth/hci_uart.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/bluetooth/hci_uart.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,580 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * BlueZ HCI UART driver.
- *
- * $Id: hci_uart.c,v 1.5 2001/07/05 18:42:44 maxk Exp $    
- */
-#define VERSION "1.0"
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/version.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/poll.h>
-
-#include <linux/slab.h>
-#include <linux/tty.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/signal.h>
-#include <linux/ioctl.h>
-#include <linux/skbuff.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
-#include <net/bluetooth/hci_core.h>
-#include <net/bluetooth/hci_uart.h>
-
-#ifndef HCI_UART_DEBUG
-#undef  DBG
-#define DBG( A... )
-#undef  DMP
-#define DMP( A... )
-#endif
-
-/* ------- Interface to HCI layer ------ */
-/* Initialize device */
-int n_hci_open(struct hci_dev *hdev)
-{
-	DBG("%s %p", hdev->name, hdev);
-
-	/* Nothing to do for UART driver */
-
-	hdev->flags |= HCI_RUNNING;
-
-	return 0;
-}
-
-/* Reset device */
-int n_hci_flush(struct hci_dev *hdev)
-{
-	struct n_hci *n_hci  = (struct n_hci *) hdev->driver_data;
-	struct tty_struct *tty = n_hci->tty;
-
-	DBG("hdev %p tty %p", hdev, tty);
-
-	/* Drop TX queue */
-	skb_queue_purge(&n_hci->txq);
-
-	/* Flush any pending characters in the driver and discipline. */
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
-
-	if (tty->driver.flush_buffer)
-		tty->driver.flush_buffer(tty);
-
-	return 0;
-}
-
-/* Close device */
-int n_hci_close(struct hci_dev *hdev)
-{
-	DBG("hdev %p", hdev);
-
-	hdev->flags &= ~HCI_RUNNING;
-
-	n_hci_flush(hdev);
-
-	return 0;
-}
-
-int n_hci_tx_wakeup(struct n_hci *n_hci)
-{
-	register struct tty_struct *tty = n_hci->tty;
-
-	if (test_and_set_bit(TRANS_SENDING, &n_hci->tx_state)) {
-		set_bit(TRANS_WAKEUP, &n_hci->tx_state);
-		return 0;
-	}
-
-	DBG("");
-	do {
-		register struct sk_buff *skb;
-		register int len;
-
-		clear_bit(TRANS_WAKEUP, &n_hci->tx_state);
-
-		if (!(skb = skb_dequeue(&n_hci->txq)))
-			break;
-
-		DMP(skb->data, skb->len);
-
-		/* Send frame to TTY driver */
-		tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
-		len = tty->driver.write(tty, 0, skb->data, skb->len);
-
-		n_hci->hdev.stat.byte_tx += len;
-
-		DBG("sent %d", len);
-
-		if (len == skb->len) {
-			/* Full frame was sent */
-			kfree_skb(skb);
-		} else {
-			/* Subtract sent part and requeue  */
-			skb_pull(skb, len);
-			skb_queue_head(&n_hci->txq, skb);
-		}
-	} while (test_bit(TRANS_WAKEUP, &n_hci->tx_state));
-	clear_bit(TRANS_SENDING, &n_hci->tx_state);
-
-	return 0;
-}
-
-/* Send frames from HCI layer */
-int n_hci_send_frame(struct sk_buff *skb)
-{
-	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-	struct tty_struct *tty;
-	struct n_hci *n_hci;
-
-	if (!hdev) {
-		ERR("Frame for uknown device (hdev=NULL)");
-		return -ENODEV;
-	}
-
-	if (!(hdev->flags & HCI_RUNNING))
-		return -EBUSY;
-
-	n_hci = (struct n_hci *) hdev->driver_data;
-	tty = n_hci2tty(n_hci);
-
-	DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-	switch (skb->pkt_type) {
-		case HCI_COMMAND_PKT:
-			hdev->stat.cmd_tx++;
-			break;
-
-                case HCI_ACLDATA_PKT:
-			hdev->stat.acl_tx++;
-                        break;
-
-		case HCI_SCODATA_PKT:
-			hdev->stat.cmd_tx++;
-                        break;
-	};
-
-	/* Prepend skb with frame type and queue */
-	memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-	skb_queue_tail(&n_hci->txq, skb);
-
-	n_hci_tx_wakeup(n_hci);
-
-	return 0;
-}
-
-/* ------ LDISC part ------ */
-
-/* n_hci_tty_open
- * 
- *     Called when line discipline changed to N_HCI.
- *     
- * Arguments:    
- *     tty    pointer to tty info structure
- * Return Value:    
- *     0 if success, otherwise error code
- */
-static int n_hci_tty_open(struct tty_struct *tty)
-{
-	struct n_hci *n_hci = tty2n_hci(tty);
-	struct hci_dev *hdev;
-
-	DBG("tty %p", tty);
-
-	if (n_hci)
-		return -EEXIST;
-
-	if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
-		ERR("Can't allocate controll structure");
-		return -ENFILE;
-	}
-	memset(n_hci, 0, sizeof(struct n_hci));
-
-	/* Initialize and register HCI device */
-	hdev = &n_hci->hdev;
-
-	hdev->type = HCI_UART;
-	hdev->driver_data = n_hci;
-
-	hdev->open  = n_hci_open;
-	hdev->close = n_hci_close;
-	hdev->flush = n_hci_flush;
-	hdev->send  = n_hci_send_frame;
-
-	if (hci_register_dev(hdev) < 0) {
-		ERR("Can't register HCI device %s", hdev->name);
-		kfree(n_hci);
-		return -ENODEV;
-	}
-
-	tty->disc_data = n_hci;
-	n_hci->tty = tty;
-
-	spin_lock_init(&n_hci->rx_lock);
-	n_hci->rx_state = WAIT_PACKET_TYPE;
-
-	skb_queue_head_init(&n_hci->txq);
-
-	MOD_INC_USE_COUNT;
-
-	/* Flush any pending characters in the driver and discipline. */
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
-
-	if (tty->driver.flush_buffer)
-		tty->driver.flush_buffer(tty);
-
-	return 0;
-}
-
-/* n_hci_tty_close()
- *
- *    Called when the line discipline is changed to something
- *    else, the tty is closed, or the tty detects a hangup.
- */
-static void n_hci_tty_close(struct tty_struct *tty)
-{
-	struct n_hci *n_hci = tty2n_hci(tty);
-	struct hci_dev *hdev = &n_hci->hdev;
-
-	DBG("tty %p hdev %p", tty, hdev);
-
-	if (n_hci != NULL) {
-		n_hci_close(hdev);
-
-		if (hci_unregister_dev(hdev) < 0) {
-			ERR("Can't unregister HCI device %s",hdev->name);
-		}
-
-		hdev->driver_data = NULL;
-		tty->disc_data = NULL;
-		kfree(n_hci);
-
-		MOD_DEC_USE_COUNT;
-	}
-}
-
-/* n_hci_tty_wakeup()
- *
- *    Callback for transmit wakeup. Called when low level
- *    device driver can accept more send data.
- *
- * Arguments:        tty    pointer to associated tty instance data
- * Return Value:    None
- */
-static void n_hci_tty_wakeup( struct tty_struct *tty )
-{
-	struct n_hci *n_hci = tty2n_hci(tty);
-
-	DBG("");
-
-	if (!n_hci)
-		return;
-
-	tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
-
-	if (tty != n_hci->tty)
-		return;
-
-	n_hci_tx_wakeup(n_hci);
-}
-
-/* n_hci_tty_room()
- * 
- *    Callback function from tty driver. Return the amount of 
- *    space left in the receiver's buffer to decide if remote
- *    transmitter is to be throttled.
- *
- * Arguments:        tty    pointer to associated tty instance data
- * Return Value:    number of bytes left in receive buffer
- */
-static int n_hci_tty_room (struct tty_struct *tty)
-{
-	return 65536;
-}
-
-static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
-{
-	register int room = skb_tailroom(n_hci->rx_skb);
-
-	DBG("len %d room %d", len, room);
-	if (!len) {
-		DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
-		hci_recv_frame(n_hci->rx_skb);
-	} else if (len > room) {
-		ERR("Data length is to large");
-		kfree_skb(n_hci->rx_skb);
-		n_hci->hdev.stat.err_rx++;
-	} else {
-		n_hci->rx_state = WAIT_DATA;
-		n_hci->rx_count = len;
-		return len;
-	}
-
-	n_hci->rx_state = WAIT_PACKET_TYPE;
-	n_hci->rx_skb   = NULL;
-	n_hci->rx_count = 0;
-	return 0;
-}
-
-static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags, int count)
-{
-	register const char *ptr;
-	hci_event_hdr *eh;
-	hci_acl_hdr   *ah;
-	hci_sco_hdr   *sh;
-	register int len, type, dlen;
-
-	DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
-
-	n_hci->hdev.stat.byte_rx += count;
-
-	ptr = data;
-	while (count) {
-		if (n_hci->rx_count) {
-			len = MIN(n_hci->rx_count, count);
-			memcpy(skb_put(n_hci->rx_skb, len), ptr, len);
-			n_hci->rx_count -= len; count -= len; ptr += len;
-
-			if (n_hci->rx_count)
-				continue;
-
-			switch (n_hci->rx_state) {
-				case WAIT_DATA:
-					DBG("Complete data");
-
-					DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
-
-					hci_recv_frame(n_hci->rx_skb);
-
-					n_hci->rx_state = WAIT_PACKET_TYPE;
-					n_hci->rx_skb = NULL;
-					continue;
-
-				case WAIT_EVENT_HDR:
-					eh = (hci_event_hdr *) n_hci->rx_skb->data;
-
-					DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
-
-					n_hci_check_data_len(n_hci, eh->plen);
-					continue;
-
-				case WAIT_ACL_HDR:
-					ah = (hci_acl_hdr *) n_hci->rx_skb->data;
-					dlen = __le16_to_cpu(ah->dlen);
-
-					DBG("ACL header: dlen %d", dlen);
-
-					n_hci_check_data_len(n_hci, dlen);
-					continue;
-
-				case WAIT_SCO_HDR:
-					sh = (hci_sco_hdr *) n_hci->rx_skb->data;
-
-					DBG("SCO header: dlen %d", sh->dlen);
-
-					n_hci_check_data_len(n_hci, sh->dlen);
-					continue;
-			};
-		}
-
-		/* WAIT_PACKET_TYPE */
-		switch (*ptr) {
-			case HCI_EVENT_PKT:
-				DBG("Event packet");
-				n_hci->rx_state = WAIT_EVENT_HDR;
-				n_hci->rx_count = HCI_EVENT_HDR_SIZE;
-				type = HCI_EVENT_PKT;
-				break;
-
-			case HCI_ACLDATA_PKT:
-				DBG("ACL packet");
-				n_hci->rx_state = WAIT_ACL_HDR;
-				n_hci->rx_count = HCI_ACL_HDR_SIZE;
-				type = HCI_ACLDATA_PKT;
-				break;
-
-			case HCI_SCODATA_PKT:
-				DBG("SCO packet");
-				n_hci->rx_state = WAIT_SCO_HDR;
-				n_hci->rx_count = HCI_SCO_HDR_SIZE;
-				type = HCI_SCODATA_PKT;
-				break;
-
-			default:
-				ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-				n_hci->hdev.stat.err_rx++;
-				ptr++; count--;
-				continue;
-		};
-		ptr++; count--;
-
-		/* Allocate packet */
-		if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-			ERR("Can't allocate mem for new packet");
-
-			n_hci->rx_state = WAIT_PACKET_TYPE;
-			n_hci->rx_count = 0;
-			return;
-		}
-		n_hci->rx_skb->dev = (void *) &n_hci->hdev;
-		n_hci->rx_skb->pkt_type = type;
-	}
-}
-
-/* n_hci_tty_receive()
- * 
- *     Called by tty low level driver when receive data is
- *     available.
- *     
- * Arguments:  tty          pointer to tty isntance data
- *             data         pointer to received data
- *             flags        pointer to flags for data
- *             count        count of received data in bytes
- *     
- * Return Value:    None
- */
-static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
-{
-	struct n_hci *n_hci = tty2n_hci(tty);
-
-	if (!n_hci || tty != n_hci->tty)
-		return;
-
-	spin_lock(&n_hci->rx_lock);
-	n_hci_rx(n_hci, data, flags, count);
-	spin_unlock(&n_hci->rx_lock);
-
-	if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-		tty->driver.unthrottle(tty);
-}
-
-/* n_hci_tty_ioctl()
- *
- *    Process IOCTL system call for the tty device.
- *
- * Arguments:
- *
- *    tty        pointer to tty instance data
- *    file       pointer to open file object for device
- *    cmd        IOCTL command code
- *    arg        argument for IOCTL call (cmd dependent)
- *
- * Return Value:    Command dependent
- */
-static int n_hci_tty_ioctl (struct tty_struct *tty, struct file * file,
-                            unsigned int cmd, unsigned long arg)
-{
-	struct n_hci *n_hci = tty2n_hci(tty);
-	int error = 0;
-
-	DBG("");
-
-	/* Verify the status of the device */
-	if (!n_hci)
-		return -EBADF;
-
-	switch (cmd) {
-		default:
-			error = n_tty_ioctl(tty, file, cmd, arg);
-			break;
-	};
-
-	return error;
-}
-
-/*
- * We don't provide read/write/poll interface for user space.
- */
-static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
-{
-	return 0;
-}
-static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
-{
-	return 0;
-}
-static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
-{
-	return 0;
-}
-
-int __init n_hci_init(void)
-{
-	static struct tty_ldisc n_hci_ldisc;
-	int err;
-
-	INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc", 
-		VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
-	/* Register the tty discipline */
-
-	memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
-	n_hci_ldisc.magic       = TTY_LDISC_MAGIC;
-	n_hci_ldisc.name        = "n_hci";
-	n_hci_ldisc.open        = n_hci_tty_open;
-	n_hci_ldisc.close       = n_hci_tty_close;
-	n_hci_ldisc.read        = n_hci_tty_read;
-	n_hci_ldisc.write       = n_hci_tty_write;
-	n_hci_ldisc.ioctl       = n_hci_tty_ioctl;
-	n_hci_ldisc.poll        = n_hci_tty_poll;
-	n_hci_ldisc.receive_room= n_hci_tty_room;
-	n_hci_ldisc.receive_buf = n_hci_tty_receive;
-	n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
-
-	if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
-		ERR("Can't register HCI line discipline (%d)", err);
-		return err;
-	}
-
-	return 0;
-}
-
-void n_hci_cleanup(void)
-{
-	int err;
-
-	/* Release tty registration of line discipline */
-	if ((err = tty_register_ldisc(N_HCI, NULL)))
-		ERR("Can't unregister HCI line discipline (%d)", err);
-}
-
-module_init(n_hci_init);
-module_exit(n_hci_cleanup);
-
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
-MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_uart.h linux/drivers/bluetooth/hci_uart.h
--- linux.orig/drivers/bluetooth/hci_uart.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/bluetooth/hci_uart.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,80 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * $Id: hci_uart.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
+ */
+
+#ifndef N_HCI
+#define N_HCI	15
+#endif
+
+/* Ioctls */
+#define HCIUARTSETPROTO	_IOW('U', 200, int)
+#define HCIUARTGETPROTO	_IOR('U', 201, int)
+
+/* UART protocols */
+#define HCI_UART_MAX_PROTO	3
+
+#define HCI_UART_H4	0
+#define HCI_UART_BCSP	1
+#define HCI_UART_NCSP	2
+
+#ifdef __KERNEL__
+struct n_hci;
+
+struct hci_uart_proto {
+	unsigned int id;
+	int (*open)(struct n_hci *n_hci);
+	int (*recv)(struct n_hci *n_hci, void *data, int len);
+	int (*send)(struct n_hci *n_hci, void *data, int len);
+	int (*close)(struct n_hci *n_hci);
+	int (*flush)(struct n_hci *n_hci);
+	struct sk_buff* (*preq)(struct n_hci *n_hci, struct sk_buff *skb);
+};
+
+struct n_hci {
+	struct tty_struct  *tty;
+	struct hci_dev     hdev;
+	unsigned long      flags;
+
+	struct hci_uart_proto *proto;
+	void               *priv;
+	
+	struct sk_buff_head txq;
+	unsigned long       tx_state;
+	spinlock_t          rx_lock;
+};
+
+/* N_HCI flag bits */
+#define N_HCI_PROTO_SET		0x00
+
+/* TX states  */
+#define N_HCI_SENDING		1
+#define N_HCI_TX_WAKEUP		2
+
+int hci_uart_register_proto(struct hci_uart_proto *p);
+int hci_uart_unregister_proto(struct hci_uart_proto *p);
+
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_usb.c linux/drivers/bluetooth/hci_usb.c
--- linux.orig/drivers/bluetooth/hci_usb.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/bluetooth/hci_usb.c	2002-07-20 01:08:33.000000000 +0000
@@ -28,570 +28,755 @@
  *    Copyright (c) 2000 Greg Kroah-Hartman        <greg@kroah.com>
  *    Copyright (c) 2000 Mark Douglas Corner       <mcorner@umich.edu>
  *
- * $Id: hci_usb.c,v 1.5 2001/07/05 18:42:44 maxk Exp $    
+ * $Id: hci_usb.c,v 1.6 2002/04/17 17:37:20 maxk Exp $    
  */
-#define VERSION "1.0"
+#define VERSION "2.0"
 
 #include <linux/config.h>
 #include <linux/module.h>
 
+#define __KERNEL_SYSCALLS__
+
 #include <linux/version.h>
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/unistd.h>
 #include <linux/types.h>
-#include <linux/fcntl.h>
 #include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/poll.h>
 
 #include <linux/slab.h>
-#include <linux/tty.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/signal.h>
-#include <linux/ioctl.h>
 #include <linux/skbuff.h>
+#include <linux/kmod.h>
 
 #include <linux/usb.h>
 
 #include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
 #include <net/bluetooth/hci_core.h>
-#include <net/bluetooth/hci_usb.h>
+#include "hci_usb.h"
+
+#define HCI_MAX_PENDING (HCI_MAX_BULK_RX + HCI_MAX_BULK_TX + 1)
 
 #ifndef HCI_USB_DEBUG
-#undef  DBG
-#define DBG( A... )
-#undef  DMP
-#define DMP( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
+#undef  BT_DMP
+#define BT_DMP( A... )
+#endif
+
+#ifndef CONFIG_BLUEZ_USB_ZERO_PACKET
+#undef  USB_ZERO_PACKET
+#define USB_ZERO_PACKET 0
 #endif
 
+static struct usb_driver hci_usb_driver; 
+
 static struct usb_device_id usb_bluetooth_ids [] = {
+	/* Generic Bluetooth USB device */
 	{ USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
+
+	/* Ericsson with non-standard id */
+	{ USB_DEVICE(0x0bdb, 0x1002) },
+
 	{ }	/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
 
-static int hci_usb_ctrl_msg(struct hci_usb *husb,  struct sk_buff *skb);
-static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);
+static void hci_usb_interrupt(struct urb *urb);
+static void hci_usb_rx_complete(struct urb *urb);
+static void hci_usb_tx_complete(struct urb *urb);
 
-static void hci_usb_unlink_urbs(struct hci_usb *husb)
+static purb_t hci_usb_get_completed(struct hci_usb *husb)
 {
-	usb_unlink_urb(husb->read_urb);
-	usb_unlink_urb(husb->intr_urb);
-	usb_unlink_urb(husb->ctrl_urb);
-	usb_unlink_urb(husb->write_urb);
+	struct sk_buff *skb;
+	purb_t urb = NULL;
+
+	skb = skb_dequeue(&husb->completed_q);
+	if (skb) {
+		urb = ((struct hci_usb_scb *) skb->cb)->urb;
+		kfree_skb(skb);
+	}
+
+	BT_DBG("%s urb %p", husb->hdev.name, urb);
+	return urb;
 }
 
-static void hci_usb_free_bufs(struct hci_usb *husb)
+static int hci_usb_enable_intr(struct hci_usb *husb)
 {
-	if (husb->read_urb) {
-		if (husb->read_urb->transfer_buffer)
-			kfree(husb->read_urb->transfer_buffer);
-		usb_free_urb(husb->read_urb);
-	}
+	struct urb *urb;
+	int pipe, size;
+	void *buf;
 
-	if (husb->intr_urb) {
-		if (husb->intr_urb->transfer_buffer)
-			kfree(husb->intr_urb->transfer_buffer);
-		usb_free_urb(husb->intr_urb);
-	}
+	BT_DBG("%s", husb->hdev.name);
 
-	if (husb->ctrl_urb)
-		usb_free_urb(husb->ctrl_urb);
+ 	if (!(urb = usb_alloc_urb(0)))
+		return -ENOMEM;
 
-	if (husb->write_urb)
-		usb_free_urb(husb->write_urb);
+	if (!(buf = kmalloc(HCI_MAX_EVENT_SIZE, GFP_KERNEL))) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
 
-	if (husb->intr_skb)
-		kfree_skb(husb->intr_skb);
+	husb->intr_urb = urb;
+	
+        pipe = usb_rcvintpipe(husb->udev, husb->intr_ep);
+        size = usb_maxpacket(husb->udev, pipe, usb_pipeout(pipe));
+	FILL_INT_URB(urb, husb->udev, pipe, buf, size, 
+			hci_usb_interrupt, husb, husb->intr_interval);
+	
+	return usb_submit_urb(urb);
 }
 
-/* ------- Interface to HCI layer ------ */
-/* Initialize device */
-int hci_usb_open(struct hci_dev *hdev)
+static int hci_usb_disable_intr(struct hci_usb *husb)
 {
-	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-	int status;
-
-	DBG("%s", hdev->name);
+	struct urb *urb = husb->intr_urb;
+	struct sk_buff *skb;
 
-	husb->read_urb->dev = husb->udev;
-	if ((status = usb_submit_urb(husb->read_urb)))
-		DBG("read submit failed. %d", status);
+	BT_DBG("%s", husb->hdev.name);
 
-	husb->intr_urb->dev = husb->udev;
-	if ((status = usb_submit_urb(husb->intr_urb)))
-		DBG("interrupt submit failed. %d", status);
+	usb_unlink_urb(urb); usb_free_urb(urb);
+	husb->intr_urb = NULL;
 
-	hdev->flags |= HCI_RUNNING;
+	skb = husb->intr_skb;
+	if (skb) {
+		husb->intr_skb = NULL;
+		kfree_skb(skb);
+	}
 
 	return 0;
 }
 
-/* Reset device */
-int hci_usb_flush(struct hci_dev *hdev)
+static int hci_usb_rx_submit(struct hci_usb *husb, struct urb *urb)
 {
-	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+	struct hci_usb_scb *scb;
+	struct sk_buff *skb;
+	int    pipe, size, err;
 
-	DBG("%s", hdev->name);
+	if (!urb && !(urb = usb_alloc_urb(0)))
+		return -ENOMEM;
 
-	/* Drop TX queues */
-	skb_queue_purge(&husb->tx_ctrl_q);
-	skb_queue_purge(&husb->tx_write_q);
+        size = HCI_MAX_FRAME_SIZE;
 
-	return 0;
+	if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+	
+	BT_DBG("%s urb %p", husb->hdev.name, urb);
+
+	skb->dev = (void *) &husb->hdev;
+	skb->pkt_type = HCI_ACLDATA_PKT;
+
+	scb = (struct hci_usb_scb *) skb->cb;
+	scb->urb = urb;
+
+        pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep);
+
+        FILL_BULK_URB(urb, husb->udev, pipe, skb->data, size, hci_usb_rx_complete, skb);
+        urb->transfer_flags = USB_QUEUE_BULK;
+
+	skb_queue_tail(&husb->pending_q, skb);
+	err = usb_submit_urb(urb);
+	if (err) {
+		BT_ERR("%s bulk rx submit failed urb %p err %d",
+				husb->hdev.name, urb, err);
+		skb_unlink(skb);
+		usb_free_urb(urb);
+	}
+	return err;
 }
 
-/* Close device */
-int hci_usb_close(struct hci_dev *hdev)
+/* Initialize device */
+static int hci_usb_open(struct hci_dev *hdev)
 {
 	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+	int i, err;
+	long flags;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
-	hdev->flags &= ~HCI_RUNNING;
-	hci_usb_unlink_urbs(husb);
+	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
 
-	hci_usb_flush(hdev);
+	write_lock_irqsave(&husb->completion_lock, flags);
 
-	return 0;
+	err = hci_usb_enable_intr(husb);
+	if (!err) {
+		for (i = 0; i < HCI_MAX_BULK_TX; i++)
+			hci_usb_rx_submit(husb, NULL);
+	} else 
+		clear_bit(HCI_RUNNING, &hdev->flags);
+		
+	write_unlock_irqrestore(&husb->completion_lock, flags);
+	return err;
 }
 
-void hci_usb_ctrl_wakeup(struct hci_usb *husb)
+/* Reset device */
+static int hci_usb_flush(struct hci_dev *hdev)
 {
-	struct sk_buff *skb;
+	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
 
-	if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))
-		return;
+	BT_DBG("%s", hdev->name);
 
-	DBG("%s", husb->hdev.name);
+	skb_queue_purge(&husb->cmd_q);
+	skb_queue_purge(&husb->acl_q);
+	return 0;
+}
 
-	if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))
-		goto done;
+static inline void hci_usb_unlink_urbs(struct hci_usb *husb)
+{
+	struct sk_buff *skb;
+	purb_t urb;
 
-	if (hci_usb_ctrl_msg(husb, skb)){
+	BT_DBG("%s", husb->hdev.name);
+
+	while ((skb = skb_dequeue(&husb->pending_q))) {
+		urb = ((struct hci_usb_scb *) skb->cb)->urb;
+		usb_unlink_urb(urb);
 		kfree_skb(skb);
-		goto done;
 	}
 
-	DMP(skb->data, skb->len);
+	while ((urb = hci_usb_get_completed(husb)))
+		usb_free_urb(urb);
+}
 
-	husb->hdev.stat.byte_tx += skb->len;
-	return;
+/* Close device */
+static int hci_usb_close(struct hci_dev *hdev)
+{
+	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+	long flags;
+	
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
 
-done:
-	clear_bit(HCI_TX_CTRL, &husb->tx_state);
-	return;
+	BT_DBG("%s", hdev->name);
+
+	write_lock_irqsave(&husb->completion_lock, flags);
+	
+	hci_usb_disable_intr(husb);
+	hci_usb_unlink_urbs(husb);
+	hci_usb_flush(hdev);
+
+	write_unlock_irqrestore(&husb->completion_lock, flags);
+	return 0;
 }
 
-void hci_usb_write_wakeup(struct hci_usb *husb)
+static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
 {
-	struct sk_buff *skb;
+	struct hci_usb_scb *scb = (void *) skb->cb;
+	purb_t urb = hci_usb_get_completed(husb);
+	devrequest *dr;
+	int pipe, err;
 
-	if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))
-		return;
+	if (!urb && !(urb = usb_alloc_urb(0)))
+		return -ENOMEM;
 
-	DBG("%s", husb->hdev.name);
+	if (!(dr = kmalloc(sizeof(*dr), GFP_ATOMIC))) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+	
+	pipe = usb_sndctrlpipe(husb->udev, 0);
 
-	if (!(skb = skb_dequeue(&husb->tx_write_q)))
-		goto done;
+	dr->requesttype = HCI_CTRL_REQ;
+	dr->request = 0;
+	dr->index   = 0;
+	dr->value   = 0;
+	dr->length  = __cpu_to_le16(skb->len);
 
-	if (hci_usb_write_msg(husb, skb)) {
-		skb_queue_head(&husb->tx_write_q, skb);
-		goto done;
-	}
+	FILL_CONTROL_URB(urb, husb->udev, pipe, (void *) dr,
+			skb->data, skb->len, hci_usb_tx_complete, skb);
 
-	DMP(skb->data, skb->len);
+	BT_DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len);
 
-	husb->hdev.stat.byte_tx += skb->len;
-	return;
+	scb->urb = urb;
 
-done:
-	clear_bit(HCI_TX_WRITE, &husb->tx_state);
-	return;
+	skb_queue_tail(&husb->pending_q, skb);
+	err = usb_submit_urb(urb);
+	if (err) {
+		BT_ERR("%s ctrl tx submit failed urb %p err %d", 
+				husb->hdev.name, urb, err);
+		skb_unlink(skb);
+		usb_free_urb(urb); kfree(dr);
+	}
+	return err;
 }
 
-/* Send frames from HCI layer */
-int hci_usb_send_frame(struct sk_buff *skb)
+static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-	struct hci_usb *husb;
+	struct hci_usb_scb *scb = (void *) skb->cb;
+	purb_t urb = hci_usb_get_completed(husb);
+	int pipe, err;
 
-	if (!hdev) {
-		ERR("frame for uknown device (hdev=NULL)");
-		return -ENODEV;
-	}
-
-	if (!(hdev->flags & HCI_RUNNING))
-		return 0;
+	if (!urb && !(urb = usb_alloc_urb(0)))
+		return -ENOMEM;
 
-	husb = (struct hci_usb *) hdev->driver_data;
+	pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep);
+        
+	FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
+	              hci_usb_tx_complete, skb);
+	urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET;
 
-	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+	BT_DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len);
 
-	switch (skb->pkt_type) {
-		case HCI_COMMAND_PKT:
-			skb_queue_tail(&husb->tx_ctrl_q, skb);
-			hci_usb_ctrl_wakeup(husb);
-			hdev->stat.cmd_tx++;
-			return 0;
-
-		case HCI_ACLDATA_PKT:
-			skb_queue_tail(&husb->tx_write_q, skb);
-			hci_usb_write_wakeup(husb);
-			hdev->stat.acl_tx++;
-			return 0;
-
-		case HCI_SCODATA_PKT:
-			return -EOPNOTSUPP;
-	};
+	scb->urb = urb;
 
-	return 0;
+	skb_queue_tail(&husb->pending_q, skb);
+	err = usb_submit_urb(urb);
+	if (err) {
+		BT_ERR("%s bulk tx submit failed urb %p err %d", 
+				husb->hdev.name, urb, err);
+		skb_unlink(skb);
+		usb_free_urb(urb);
+	}
+	return err;
 }
 
-/* ---------- USB ------------- */
-
-static void hci_usb_ctrl(struct urb *urb)
+static void hci_usb_tx_process(struct hci_usb *husb)
 {
-	struct sk_buff *skb = (struct sk_buff *) urb->context;
-	struct hci_dev *hdev;
-	struct hci_usb *husb;
-
-	if (!skb)
-		return;
-	hdev = (struct hci_dev *) skb->dev;
-	husb = (struct hci_usb *) hdev->driver_data;
+	struct sk_buff *skb;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", husb->hdev.name);
 
-	if (urb->status)
-		DBG("%s ctrl status: %d", hdev->name, urb->status);
+	do {
+		clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
+		
+		/* Process ACL queue */
+		while (skb_queue_len(&husb->pending_q) < HCI_MAX_PENDING &&
+				(skb = skb_dequeue(&husb->acl_q))) {
+			if (hci_usb_send_bulk(husb, skb) < 0) {
+				skb_queue_head(&husb->acl_q, skb);
+				break;
+			}
+		}
 
-	clear_bit(HCI_TX_CTRL, &husb->tx_state);
-	kfree_skb(skb);
+		/* Process command queue */
+		if (!test_bit(HCI_USB_CTRL_TX, &husb->state) &&
+			(skb = skb_dequeue(&husb->cmd_q)) != NULL) {
+			set_bit(HCI_USB_CTRL_TX, &husb->state);
+			if (hci_usb_send_ctrl(husb, skb) < 0) {
+				skb_queue_head(&husb->cmd_q, skb);
+				clear_bit(HCI_USB_CTRL_TX, &husb->state);
+			}
+		}
+	} while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
+}
 
-	/* Wake up device */
-	hci_usb_ctrl_wakeup(husb);
+static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
+{
+	/* Serialize TX queue processing to avoid data reordering */
+	if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
+		hci_usb_tx_process(husb);
+		clear_bit(HCI_USB_TX_PROCESS, &husb->state);
+	} else
+		set_bit(HCI_USB_TX_WAKEUP, &husb->state);
 }
 
-static void hci_usb_bulk_write(struct urb *urb)
+/* Send frames from HCI layer */
+int hci_usb_send_frame(struct sk_buff *skb)
 {
-	struct sk_buff *skb = (struct sk_buff *) urb->context;
-	struct hci_dev *hdev;
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct hci_usb *husb;
 
-	if (!skb)
-		return;
-	hdev = (struct hci_dev *) skb->dev;
+	if (!hdev) {
+		BT_ERR("frame for uknown device (hdev=NULL)");
+		return -ENODEV;
+	}
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return -EBUSY;
+
 	husb = (struct hci_usb *) hdev->driver_data;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
-	if (urb->status)
-		DBG("%s bulk write status: %d", hdev->name, urb->status);
+	read_lock(&husb->completion_lock);
 
-	clear_bit(HCI_TX_WRITE, &husb->tx_state);
-	kfree_skb(skb);
+	switch (skb->pkt_type) {
+	case HCI_COMMAND_PKT:
+		skb_queue_tail(&husb->cmd_q, skb);
+		hdev->stat.cmd_tx++;
+		break;
+
+	case HCI_ACLDATA_PKT:
+		skb_queue_tail(&husb->acl_q, skb);
+		hdev->stat.acl_tx++;
+		break;
 
-	/* Wake up device */
-	hci_usb_write_wakeup(husb);
+	case HCI_SCODATA_PKT:
+	default:
+		kfree_skb(skb);
+		break;
+	}
+	hci_usb_tx_wakeup(husb);
 
-	return;
+	read_unlock(&husb->completion_lock);
+	return 0;
 }
 
-static void hci_usb_intr(struct urb *urb)
+static void hci_usb_interrupt(struct urb *urb)
 {
-	struct hci_usb *husb = (struct hci_usb *) urb->context;
-	unsigned char *data = urb->transfer_buffer;
-	register int count  = urb->actual_length;
-	register struct sk_buff *skb = husb->intr_skb;
+	struct hci_usb *husb = (void *) urb->context;
+	struct hci_usb_scb *scb;
+	struct sk_buff *skb;
 	hci_event_hdr *eh;
-	register int len;
+	__u8 *data = urb->transfer_buffer;
+	int count = urb->actual_length;
+	int len = HCI_EVENT_HDR_SIZE;
 
-	if (!husb)
-		return;
+	BT_DBG("%s urb %p count %d", husb->hdev.name, urb, count);
 
-	DBG("%s count %d", husb->hdev.name, count);
+	if (!test_bit(HCI_RUNNING, &husb->hdev.flags))
+		return;
 
 	if (urb->status || !count) {
-		DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);
+		BT_DBG("%s intr status %d, count %d", 
+				husb->hdev.name, urb->status, count);
 		return;
 	}
 
-	/* Do we really have to handle continuations here ? */
-	if (!skb) {
-		/* New frame */
-		if (count < HCI_EVENT_HDR_SIZE) {
-			DBG("%s bad frame len %d", husb->hdev.name, count);
-			return;
-		}
+	read_lock(&husb->completion_lock);
+	
+	husb->hdev.stat.byte_rx += count;
+
+	if (!(skb = husb->intr_skb)) {
+		/* Start of the frame */
+		if (count < HCI_EVENT_HDR_SIZE)
+			goto bad_len;
 
-		eh = (hci_event_hdr *) data;
+		eh  = (hci_event_hdr *) data;
 		len = eh->plen + HCI_EVENT_HDR_SIZE;
 
-		if (count > len) {
-			DBG("%s corrupted frame, len %d", husb->hdev.name, count);
-			return;
-		}
+		if (count > len)
+			goto bad_len;
 
-		/* Allocate skb */
-		if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-			ERR("Can't allocate mem for new packet");
-			return;
+		skb = bluez_skb_alloc(len, GFP_ATOMIC);
+		if (!skb) {
+			BT_ERR("%s no memory for event packet", husb->hdev.name);
+			goto done;
 		}
+		scb = (void *) skb->cb;
+
 		skb->dev = (void *) &husb->hdev;
 		skb->pkt_type = HCI_EVENT_PKT;
 
 		husb->intr_skb = skb;
-		husb->intr_count = len;
+		scb->intr_len  = len;
 	} else {
 		/* Continuation */
-		if (count > husb->intr_count) {
-			ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
-
-			kfree_skb(skb);
+		scb = (void *) skb->cb;
+		len = scb->intr_len;
+		if (count > len) {
 			husb->intr_skb = NULL;
-			husb->intr_count = 0;
-			return;
+			kfree_skb(skb);
+			goto bad_len;
 		}
 	}
 
 	memcpy(skb_put(skb, count), data, count);
-	husb->intr_count -= count;
+	scb->intr_len -= count;
 
-	DMP(data, count);
+	if (!scb->intr_len) {
+		/* Complete frame */
+		husb->intr_skb = NULL;
+		hci_recv_frame(skb);
+	}
 
-	if (!husb->intr_count) {
-		/* Got complete frame */
+done:
+	read_unlock(&husb->completion_lock);
+	return;
 
-		husb->hdev.stat.byte_rx += skb->len;
-		hci_recv_frame(skb);
+bad_len:
+	BT_ERR("%s bad frame len %d expected %d", husb->hdev.name, count, len);
+	husb->hdev.stat.err_rx++;
+	read_unlock(&husb->completion_lock);
+}
 
-		husb->intr_skb = NULL;
+static void hci_usb_tx_complete(struct urb *urb)
+{
+	struct sk_buff *skb  = (struct sk_buff *) urb->context;
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+
+	BT_DBG("%s urb %p status %d flags %x", husb->hdev.name, urb,
+			urb->status, urb->transfer_flags);
+
+	if (urb->pipe == usb_sndctrlpipe(husb->udev, 0)) {
+		kfree(urb->setup_packet);
+		clear_bit(HCI_USB_CTRL_TX, &husb->state);
 	}
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return;
+
+	read_lock(&husb->completion_lock);
+	
+	if (!urb->status)
+		husb->hdev.stat.byte_tx += skb->len;
+	else
+		husb->hdev.stat.err_tx++;
+
+	skb_unlink(skb);
+	skb_queue_tail(&husb->completed_q, skb);
+	hci_usb_tx_wakeup(husb);
+	
+	read_unlock(&husb->completion_lock);
+	return;
 }
 
-static void hci_usb_bulk_read(struct urb *urb)
+static void hci_usb_rx_complete(struct urb *urb)
 {
-	struct hci_usb *husb = (struct hci_usb *) urb->context;
-	unsigned char *data = urb->transfer_buffer;
-	int count = urb->actual_length, status;
-	struct sk_buff *skb;
+	struct sk_buff *skb  = (struct sk_buff *) urb->context;
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+	int status, count = urb->actual_length;
 	hci_acl_hdr *ah;
-	register __u16 dlen;
+	int dlen, size;
 
-	if (!husb)
+	BT_DBG("%s urb %p status %d count %d flags %x", husb->hdev.name, urb,
+			urb->status, count, urb->transfer_flags);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return;
 
-	DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);
+	read_lock(&husb->completion_lock);
 
-	if (urb->status) {
-		/* Do not re-submit URB on critical errors */
-		switch (urb->status) {
-			case -ENOENT:
-				return;
-			default:
-				goto resubmit;
-		};
-	}
-	if (!count)
+	if (urb->status || !count)
 		goto resubmit;
 
-	DMP(data, count);
+	husb->hdev.stat.byte_rx += count;
 
-	ah = (hci_acl_hdr *) data;
-	dlen = le16_to_cpu(ah->dlen);
+	ah   = (hci_acl_hdr *) skb->data;
+	dlen = __le16_to_cpu(ah->dlen);
+	size = HCI_ACL_HDR_SIZE + dlen;
 
 	/* Verify frame len and completeness */
-	if ((count - HCI_ACL_HDR_SIZE) != dlen) {
-		ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);
-		goto resubmit;
-	}
-
-	/* Allocate packet */
-	if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {
-		ERR("Can't allocate mem for new packet");
+	if (count != size) {
+		BT_ERR("%s corrupted ACL packet: count %d, dlen %d",
+				husb->hdev.name, count, dlen);
+		bluez_dump("hci_usb", skb->data, count);
+		husb->hdev.stat.err_rx++;
 		goto resubmit;
 	}
 
-	memcpy(skb_put(skb, count), data, count);
-	skb->dev = (void *) &husb->hdev;
-	skb->pkt_type = HCI_ACLDATA_PKT;
-
-	husb->hdev.stat.byte_rx += skb->len;
-
+	skb_unlink(skb);
+	skb_put(skb, count);
 	hci_recv_frame(skb);
 
-resubmit:
-	husb->read_urb->dev = husb->udev;
-	if ((status = usb_submit_urb(husb->read_urb)))
-		DBG("%s read URB submit failed %d", husb->hdev.name, status);
+	hci_usb_rx_submit(husb, urb);
 
-	DBG("%s read URB re-submited", husb->hdev.name);
+	read_unlock(&husb->completion_lock);
+	return;
+		
+resubmit:
+	urb->dev = husb->udev;
+	status   = usb_submit_urb(urb);
+	BT_DBG("%s URB resubmit status %d", husb->hdev.name, status);
+	read_unlock(&husb->completion_lock);
 }
 
-static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb)
+static void hci_usb_destruct(struct hci_dev *hdev)
 {
-	struct urb *urb = husb->ctrl_urb;
-	devrequest *dr  = &husb->dev_req;
-	int pipe, status;
+	struct hci_usb *husb;
 
-	DBG("%s len %d", husb->hdev.name, skb->len);
+	if (!hdev) return;
 
-	pipe = usb_sndctrlpipe(husb->udev, 0);
+	BT_DBG("%s", hdev->name);
 
-	dr->requesttype = HCI_CTRL_REQ;
-	dr->request = 0;
-	dr->index   = 0;
-	dr->value   = 0;
-	dr->length  = cpu_to_le16(skb->len);
+	husb = (struct hci_usb *) hdev->driver_data;
+	kfree(husb);
+
+	MOD_DEC_USE_COUNT;
+}
 
-	FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
-	                 hci_usb_ctrl, skb);
+#ifdef CONFIG_BLUEZ_USB_FW_LOAD
 
-	if ((status = usb_submit_urb(urb))) {
-		DBG("%s control URB submit failed %d", husb->hdev.name, status);
-		return status;
-	}
+/* Support for user mode Bluetooth USB firmware loader */
 
-	return 0;
-}
+#define FW_LOADER "/sbin/bluefw"
+static int errno;
 
-static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
+static int hci_usb_fw_exec(void *dev)
 {
-	struct urb *urb = husb->write_urb;
-	int pipe, status;
+	char *envp[] = { "HOME=/", "TERM=linux", 
+			 "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+	char *argv[] = { FW_LOADER, dev, NULL };
+	int err;
 
-	DBG("%s len %d", husb->hdev.name, skb->len);
+	err = exec_usermodehelper(FW_LOADER, argv, envp);
+	if (err)
+		BT_ERR("failed to exec %s %s", FW_LOADER, (char *)dev);
+	return err;
+}
 
-	pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);
+static int hci_usb_fw_load(struct usb_device *udev)
+{
+	sigset_t tmpsig;
+	char dev[16];
+	pid_t pid;
+	int result;
 
-	FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-	              hci_usb_bulk_write, skb);
-	urb->transfer_flags |= USB_QUEUE_BULK;
+	/* Check if root fs is mounted */
+	if (!current->fs->root) {
+		BT_ERR("root fs not mounted");
+		return -EPERM;
+	}
+
+	sprintf(dev, "%3.3d/%3.3d", udev->bus->busnum, udev->devnum);
 
-	if ((status = usb_submit_urb(urb))) {
-		DBG("%s write URB submit failed %d", husb->hdev.name, status);
-		return status;
+	pid = kernel_thread(hci_usb_fw_exec, (void *)dev, 0);
+	if (pid < 0) {
+		BT_ERR("fork failed, errno %d\n", -pid);
+		return pid;
 	}
 
+	/* Block signals, everything but SIGKILL/SIGSTOP */
+	spin_lock_irq(&current->sigmask_lock);
+	tmpsig = current->blocked;
+	siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	result = waitpid(pid, NULL, __WCLONE);
+
+	/* Allow signals again */
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = tmpsig;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (result != pid) {
+		BT_ERR("waitpid failed pid %d errno %d\n", pid, -result);
+		return -result;
+	}
 	return 0;
 }
 
+#endif /* CONFIG_BLUEZ_USB_FW_LOAD */
+
 static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
 {
-	struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
+	struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM];
+	struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM];
+	struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM];
+	struct usb_endpoint_descriptor *isoc_in_ep[HCI_MAX_IFACE_NUM];
+	struct usb_endpoint_descriptor *intr_in_ep[HCI_MAX_IFACE_NUM];
 	struct usb_interface_descriptor *uif;
 	struct usb_endpoint_descriptor *ep;
+	struct usb_interface *iface, *isoc_iface;
 	struct hci_usb *husb;
 	struct hci_dev *hdev;
-	int i, size, pipe;
-	__u8 * buf;
+	int i, a, e, size, ifn, isoc_ifnum, isoc_alts;
 
-	DBG("udev %p ifnum %d", udev, ifnum);
+	BT_DBG("udev %p ifnum %d", udev, ifnum);
 
-	/* Check device signature */
-	if ((udev->descriptor.bDeviceClass    != HCI_DEV_CLASS)   ||
-	    (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
-	    (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
+	/* Check number of endpoints */
+	if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3)
 		return NULL;
 
 	MOD_INC_USE_COUNT;
 
-	uif = &udev->actconfig->interface[ifnum].altsetting[0];
-
-	if (uif->bNumEndpoints != 3) {
-		DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
-		MOD_DEC_USE_COUNT;
-		return NULL;
-	}
-
-	bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;
+#ifdef CONFIG_BLUEZ_USB_FW_LOAD
+	hci_usb_fw_load(udev);
+#endif
 
+	memset(bulk_out_ep, 0, sizeof(bulk_out_ep));
+	memset(isoc_out_ep, 0, sizeof(isoc_out_ep));
+	memset(bulk_in_ep,  0, sizeof(bulk_in_ep));
+	memset(isoc_in_ep,  0, sizeof(isoc_in_ep));
+	memset(intr_in_ep,  0, sizeof(intr_in_ep));
+
+	size = 0; 
+	isoc_iface = NULL;
+	isoc_alts  = isoc_ifnum = 0;
+	
 	/* Find endpoints that we need */
-	for ( i = 0; i < uif->bNumEndpoints; ++i) {
-		ep = &uif->endpoint[i];
 
-		switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-			case USB_ENDPOINT_XFER_BULK:
-				if (ep->bEndpointAddress & USB_DIR_IN)
-					bulk_in_ep  = ep;
-				else
-					bulk_out_ep = ep;
-				break;
+	ifn = MIN(udev->actconfig->bNumInterfaces, HCI_MAX_IFACE_NUM);
+	for (i = 0; i < ifn; i++) {
+		iface = &udev->actconfig->interface[i];
+		for (a = 0; a < iface->num_altsetting; a++) {
+			uif = &iface->altsetting[a];
+			for (e = 0; e < uif->bNumEndpoints; e++) {
+				ep = &uif->endpoint[e];
+
+				switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+				case USB_ENDPOINT_XFER_INT:
+					if (ep->bEndpointAddress & USB_DIR_IN)
+						intr_in_ep[i] = ep;
+					break;
+
+				case USB_ENDPOINT_XFER_BULK:
+					if (ep->bEndpointAddress & USB_DIR_IN)
+						bulk_in_ep[i]  = ep;
+					else
+						bulk_out_ep[i] = ep;
+					break;
+
+				case USB_ENDPOINT_XFER_ISOC:
+					if (ep->wMaxPacketSize < size)
+						break;
+					size = ep->wMaxPacketSize;
+
+					isoc_iface = iface;
+					isoc_alts  = a;
+					isoc_ifnum = i;
+
+					if (ep->bEndpointAddress & USB_DIR_IN)
+						isoc_in_ep[i]  = ep;
+					else
+						isoc_out_ep[i] = ep;
+					break;
+				}
+			}
+		}
+	}
 
-			case USB_ENDPOINT_XFER_INT:
-				intr_in_ep = ep;
-				break;
-		};
+	if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) {
+		BT_DBG("Bulk endpoints not found");
+		goto done;
 	}
 
-	if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
-		DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
-		MOD_DEC_USE_COUNT;
-		return NULL;
+	if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
+		BT_DBG("Isoc endpoints not found");
+		isoc_iface = NULL;
 	}
 
 	if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
-		ERR("Can't allocate: control structure");
-		MOD_DEC_USE_COUNT;
-		return NULL;
+		BT_ERR("Can't allocate: control structure");
+		goto done;
 	}
 
 	memset(husb, 0, sizeof(struct hci_usb));
 
 	husb->udev = udev;
-	husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;
-
-	if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
-		ERR("Can't allocate: control URB");
-		goto probe_error;
-	}
+	husb->bulk_out_ep = bulk_out_ep[0]->bEndpointAddress;
+	husb->bulk_in_ep  = bulk_in_ep[0]->bEndpointAddress;
 
-	if (!(husb->write_urb = usb_alloc_urb(0))) {
-		ERR("Can't allocate: write URB");
-		goto probe_error;
-	}
-
-	if (!(husb->read_urb = usb_alloc_urb(0))) {
-		ERR("Can't allocate: read URB");
-		goto probe_error;
-	}
-
-	ep = bulk_in_ep;
-	pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
-	size = HCI_MAX_FRAME_SIZE;
-
-	if (!(buf = kmalloc(size, GFP_KERNEL))) {
-		ERR("Can't allocate: read buffer");
-		goto probe_error;
-	}
+	husb->intr_ep = intr_in_ep[0]->bEndpointAddress;
+	husb->intr_interval = intr_in_ep[0]->bInterval;
 
-	FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
-	husb->read_urb->transfer_flags |= USB_QUEUE_BULK;
-
-	ep = intr_in_ep;
-	pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
-	size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
-
-	if (!(husb->intr_urb = usb_alloc_urb(0))) {
-		ERR("Can't allocate: interrupt URB");
-		goto probe_error;
-	}
+	if (isoc_iface) {
+		if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
+			BT_ERR("Can't set isoc interface settings");
+			isoc_iface = NULL;
+		}
+		usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
+		husb->isoc_iface  = isoc_iface;
 
-	if (!(buf = kmalloc(size, GFP_KERNEL))) {
-		ERR("Can't allocate: interrupt buffer");
-		goto probe_error;
+		husb->isoc_in_ep  = isoc_in_ep[1]->bEndpointAddress;
+		husb->isoc_out_ep = isoc_in_ep[1]->bEndpointAddress;
 	}
 
-	FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);
-
-	skb_queue_head_init(&husb->tx_ctrl_q);
-	skb_queue_head_init(&husb->tx_write_q);
+	husb->completion_lock = RW_LOCK_UNLOCKED;
+	
+	skb_queue_head_init(&husb->acl_q);
+	skb_queue_head_init(&husb->cmd_q);
+	skb_queue_head_init(&husb->pending_q);
+	skb_queue_head_init(&husb->completed_q);
 
 	/* Initialize and register HCI device */
 	hdev = &husb->hdev;
@@ -602,18 +787,20 @@
 	hdev->open  = hci_usb_open;
 	hdev->close = hci_usb_close;
 	hdev->flush = hci_usb_flush;
-	hdev->send	= hci_usb_send_frame;
+	hdev->send  = hci_usb_send_frame;
+	hdev->destruct = hci_usb_destruct;
 
 	if (hci_register_dev(hdev) < 0) {
-		ERR("Can't register HCI device %s", hdev->name);
+		BT_ERR("Can't register HCI device");
 		goto probe_error;
 	}
 
 	return husb;
 
 probe_error:
-	hci_usb_free_bufs(husb);
 	kfree(husb);
+
+done:
 	MOD_DEC_USE_COUNT;
 	return NULL;
 }
@@ -626,22 +813,18 @@
 	if (!husb)
 		return;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	hci_usb_close(hdev);
 
-	if (hci_unregister_dev(hdev) < 0) {
-		ERR("Can't unregister HCI device %s", hdev->name);
-	}
+	if (husb->isoc_iface)
+		usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
 
-	hci_usb_free_bufs(husb);
-	kfree(husb);
-
-	MOD_DEC_USE_COUNT;
+	if (hci_unregister_dev(hdev) < 0)
+		BT_ERR("Can't unregister HCI device %s", hdev->name);
 }
 
-static struct usb_driver hci_usb_driver =
-{
+static struct usb_driver hci_usb_driver = {
 	name:           "hci_usb",
 	probe:          hci_usb_probe,
 	disconnect:     hci_usb_disconnect,
@@ -652,12 +835,12 @@
 {
 	int err;
 
-	INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
+	BT_INFO("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
 		VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	if ((err = usb_register(&hci_usb_driver)) < 0)
-		ERR("Failed to register HCI USB driver");
+		BT_ERR("Failed to register HCI USB driver");
 
 	return err;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_usb.h linux/drivers/bluetooth/hci_usb.h
--- linux.orig/drivers/bluetooth/hci_usb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/bluetooth/hci_usb.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,79 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * $Id: hci_usb.h,v 1.2 2002/03/18 19:10:04 maxk Exp $
+ */
+
+#ifdef __KERNEL__
+
+/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
+#define HCI_DEV_CLASS        0xe0	/* Wireless class */
+#define HCI_DEV_SUBCLASS     0x01	/* RF subclass */
+#define HCI_DEV_PROTOCOL     0x01	/* Bluetooth programming protocol */
+
+#define HCI_CTRL_REQ	     0x20
+
+#define HCI_MAX_IFACE_NUM	3 
+
+#define HCI_MAX_BULK_TX     	4
+#define HCI_MAX_BULK_RX     	1
+
+struct hci_usb {
+	struct hci_dev		hdev;
+
+	unsigned long		state;
+	
+	struct usb_device 	*udev;
+	struct usb_interface    *isoc_iface;
+	
+	__u8			bulk_out_ep;
+	__u8			bulk_in_ep;
+	__u8			isoc_out_ep;
+	__u8			isoc_in_ep;
+
+	__u8			intr_ep;
+	__u8			intr_interval;
+	purb_t			intr_urb;
+	struct sk_buff *	intr_skb;
+
+	rwlock_t		completion_lock;
+	
+	struct sk_buff_head	cmd_q;	     // TX Commands
+	struct sk_buff_head	acl_q;	     // TX ACLs
+	struct sk_buff_head	pending_q;   // Pending requests
+	struct sk_buff_head	completed_q; // Completed requests
+};
+
+struct hci_usb_scb {
+	struct urb *urb;
+	int    intr_len;
+};
+
+/* States  */
+#define HCI_USB_TX_PROCESS	1
+#define HCI_USB_TX_WAKEUP	2
+#define HCI_USB_CTRL_TX		3
+
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_vhci.c linux/drivers/bluetooth/hci_vhci.c
--- linux.orig/drivers/bluetooth/hci_vhci.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/bluetooth/hci_vhci.c	2002-07-20 01:08:40.000000000 +0000
@@ -25,9 +25,9 @@
 /*
  * BlueZ HCI virtual device driver.
  *
- * $Id: hci_vhci.c,v 1.3 2001/08/03 04:19:50 maxk Exp $ 
+ * $Id: hci_vhci.c,v 1.3 2002/04/17 17:37:20 maxk Exp $ 
  */
-#define VERSION "1.0"
+#define VERSION "1.1"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -49,43 +49,56 @@
 #include <asm/uaccess.h>
 
 #include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
 #include <net/bluetooth/hci_core.h>
-#include <net/bluetooth/hci_vhci.h>
+#include "hci_vhci.h"
 
 /* HCI device part */
 
-int hci_vhci_open(struct hci_dev *hdev)
+static int hci_vhci_open(struct hci_dev *hdev)
 {
-	hdev->flags |= HCI_RUNNING;
+	set_bit(HCI_RUNNING, &hdev->flags);
 	return 0;
 }
 
-int hci_vhci_flush(struct hci_dev *hdev)
+static int hci_vhci_flush(struct hci_dev *hdev)
 {
 	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
 	skb_queue_purge(&hci_vhci->readq);
 	return 0;
 }
 
-int hci_vhci_close(struct hci_dev *hdev)
+static int hci_vhci_close(struct hci_dev *hdev)
 {
-	hdev->flags &= ~HCI_RUNNING;
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
 	hci_vhci_flush(hdev);
 	return 0;
 }
 
-int hci_vhci_send_frame(struct sk_buff *skb)
+static void hci_vhci_destruct(struct hci_dev *hdev)
+{
+	struct hci_vhci_struct *vhci;
+
+	if (!hdev) return;
+
+	vhci = (struct hci_vhci_struct *) hdev->driver_data;
+	kfree(vhci);
+
+	MOD_DEC_USE_COUNT;
+}
+
+static int hci_vhci_send_frame(struct sk_buff *skb)
 {
 	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
 	struct hci_vhci_struct *hci_vhci;
 
 	if (!hdev) {
-		ERR("Frame for uknown device (hdev=NULL)");
+		BT_ERR("Frame for uknown device (hdev=NULL)");
 		return -ENODEV;
 	}
 
-	if (!(hdev->flags & HCI_RUNNING))
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
 	hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
@@ -188,7 +201,7 @@
 
 	add_wait_queue(&hci_vhci->read_wait, &wait);
 	while (count) {
-		current->state = TASK_INTERRUPTIBLE;
+		set_current_state(TASK_INTERRUPTIBLE);
 
 		/* Read frames from device queue */
 		if (!(skb = skb_dequeue(&hci_vhci->readq))) {
@@ -214,8 +227,7 @@
 		kfree_skb(skb);
 		break;
 	}
-
-	current->state = TASK_RUNNING;
+	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&hci_vhci->read_wait, &wait);
 
 	return ret;
@@ -270,11 +282,13 @@
 	hdev->close = hci_vhci_close;
 	hdev->flush = hci_vhci_flush;
 	hdev->send  = hci_vhci_send_frame;
+	hdev->destruct = hci_vhci_destruct;
 
 	if (hci_register_dev(hdev) < 0) {
 		kfree(hci_vhci);
 		return -EBUSY;
 	}
+	MOD_INC_USE_COUNT;
 
 	file->private_data = hci_vhci;
 	return 0;   
@@ -285,12 +299,10 @@
 	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
 
 	if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
-		ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
+		BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
 	}
 
-	kfree(hci_vhci);
 	file->private_data = NULL;
-
 	return 0;
 }
 
@@ -315,12 +327,12 @@
 
 int __init hci_vhci_init(void)
 {
-	INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
+	BT_INFO("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
 		VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	if (misc_register(&hci_vhci_miscdev)) {
-		ERR("Can't register misc device %d\n", VHCI_MINOR);
+		BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
 		return -EIO;
 	}
 
@@ -337,4 +349,4 @@
 
 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
 MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL"); 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/bluetooth/hci_vhci.h linux/drivers/bluetooth/hci_vhci.h
--- linux.orig/drivers/bluetooth/hci_vhci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/bluetooth/hci_vhci.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,50 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * $Id: hci_vhci.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
+ */
+
+#ifndef __HCI_VHCI_H
+#define __HCI_VHCI_H
+
+#ifdef __KERNEL__
+
+struct hci_vhci_struct {
+	struct hci_dev       hdev;
+	__u32                flags;
+	wait_queue_head_t    read_wait;
+	struct sk_buff_head  readq;
+	struct fasync_struct *fasync;
+};
+
+/* VHCI device flags */
+#define VHCI_FASYNC		0x0010
+
+#endif /* __KERNEL__ */
+
+#define VHCI_DEV	"/dev/vhci"
+#define VHCI_MINOR	250
+
+#endif /* __HCI_VHCI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- linux.orig/drivers/cdrom/cdrom.c	2001-11-16 18:14:08.000000000 +0000
+++ linux/drivers/cdrom/cdrom.c	2002-07-20 01:08:26.000000000 +0000
@@ -761,6 +761,7 @@
 	cgc.cmd[0] = GPCMD_LOAD_UNLOAD;
 	cgc.cmd[4] = 2 + (slot >= 0);
 	cgc.cmd[8] = slot;
+	cgc.timeout = 60 * HZ;
 
 	/* The Sanyo 3 CD changer uses byte 7 of the 
 	GPCMD_TEST_UNIT_READY to command to switch CDs instead of
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/Config.in linux/drivers/char/Config.in
--- linux.orig/drivers/char/Config.in	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/Config.in	2002-07-20 01:08:28.000000000 +0000
@@ -11,14 +11,14 @@
 tristate 'Standard/generic (8250/16550 and compatible UARTs) serial support' CONFIG_SERIAL
 if [ "$CONFIG_SERIAL" = "y" ]; then
    bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
+   if [ "$CONFIG_IA64" = "y" ]; then
+      bool 'Support for serial console port described by EFI HCDP table' CONFIG_SERIAL_HCDP
+   fi
    if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
       tristate '   Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL
       tristate '   Dual serial port support' CONFIG_DUALSP_SERIAL
    fi
 fi
-if [ "$CONFIG_ACPI" = "y" ]; then
-   bool '  Support for serial ports defined by ACPI tables' CONFIG_SERIAL_ACPI
-fi
 dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL
 if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
    bool '  Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS
@@ -63,6 +63,41 @@
      tristate '    Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION
    fi
    if [ "$CONFIG_MIPS" = "y" ]; then
+     bool '  TX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912
+     dep_bool '     Console on TX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912
+     bool '  Enable Au1000 UART Support' CONFIG_AU1000_UART
+     if [ "$CONFIG_AU1000_UART" = "y" ]; then
+        bool '        Enable Au1000 serial console' CONFIG_AU1000_SERIAL_CONSOLE
+     fi
+     bool 'TXx927 SIO support' CONFIG_TXX927_SERIAL 
+     if [ "$CONFIG_TXX927_SERIAL" = "y" ]; then
+        bool 'TXx927 SIO Console support' CONFIG_TXX927_SERIAL_CONSOLE  
+     fi                             
+     if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+        bool '  Support for sb1250 onchip DUART' CONFIG_SIBYTE_SB1250_DUART
+        if [ "$CONFIG_SIBYTE_SB1250_DUART" = "y" ]; then
+           bool '  Console on SB1250 DUART' CONFIG_SIBYTE_SB1250_DUART_CONSOLE
+	   if [ "$CONFIG_SIBYTE_SB1250_DUART_CONSOLE" = "y" ]; then
+	      define_bool CONFIG_SERIAL_CONSOLE y
+	   fi
+	   int  '  Output buffers size (in bytes)' CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE 1024
+	   bool '  Leave port 1 alone (for kgdb or audio)' CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1
+       fi
+     fi
+  fi
+fi
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then
+   tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
+fi
+if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
+   bool 'DC21285 serial port support' CONFIG_SERIAL_21285
+   if [ "$CONFIG_SERIAL_21285" = "y" ]; then
+      if [ "$CONFIG_OBSOLETE" = "y" ]; then
+         bool '  Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD
+      fi
+      bool '  Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE
+   fi
+   if [ "$CONFIG_MIPS" = "y" ]; then
      bool '  TMPTX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912
      dep_bool '     Console on TMPTX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912
      bool '  Enable Au1000 UART Support' CONFIG_AU1000_UART
@@ -71,7 +106,7 @@
      fi
    fi
 fi
-if [ "$CONFIG_IT8712" = "y" ]; then
+if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
    bool 'Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD
    if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then
      define_bool CONFIG_IT8172_CIR y
@@ -81,17 +116,12 @@
    bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0
    bool 'Enable Smart Card Reader 1 Support ' CONFIG_IT8172_SCR1
 fi
-if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then
-   tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
-fi
-if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
-   bool 'DC21285 serial port support' CONFIG_SERIAL_21285
-   if [ "$CONFIG_SERIAL_21285" = "y" ]; then
-      if [ "$CONFIG_OBSOLETE" = "y" ]; then
-         bool '  Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD
-      fi
-      bool '  Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE
+if [ "$CONFIG_MIPS_IVR" = "y" ]; then
+   bool 'Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD
+   if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then
+     define_bool CONFIG_IT8172_CIR y
    fi
+   bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0
 fi
 bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
 if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
@@ -124,6 +154,7 @@
    bool '  PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
    tristate '  C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
    tristate '  PC110 digitizer pad support' CONFIG_PC110_PAD
+   tristate '  MK712 touch screen support' CONFIG_MK712_MOUSE
 fi
 endmenu
 
@@ -146,18 +177,11 @@
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
    bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
-   tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG
-   tristate '  WDT Watchdog timer' CONFIG_WDT
-   tristate '  WDT PCI Watchdog timer' CONFIG_WDTPCI
-   if [ "$CONFIG_WDT" != "n" ]; then
-      bool '    WDT501 features' CONFIG_WDT_501
-      if [ "$CONFIG_WDT_501" = "y" ]; then
-         bool '      Fan Tachometer' CONFIG_WDT_501_FAN
-      fi
-   fi
-   tristate '  Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
    tristate '  Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
    tristate '  Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT
+   tristate '  ALi M7101 PMU Watchdog Timer' CONFIG_ALIM7101_WDT
+   tristate '  AMD "Elan" SC520 Watchdog Timer' CONFIG_SC520_WDT
+   tristate '  Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
    if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
       tristate '  DC21285 watchdog' CONFIG_21285_WATCHDOG
       if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then
@@ -166,10 +190,24 @@
    fi
    tristate '  Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT
    tristate '  IB700 SBC Watchdog Timer' CONFIG_IB700_WDT
+   tristate '  ICP ELectronics Wafer 5823 Watchdog' CONFIG_WAFER_WDT
+   if [ "$CONFIG_SGI_IP22" = "y" ]; then
+      dep_tristate '  Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22
+   fi
    tristate '  Intel i810 TCO timer / Watchdog' CONFIG_I810_TCO
    tristate '  Mixcom Watchdog' CONFIG_MIXCOMWD 
    tristate '  SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
+   dep_tristate '  SC1200 Watchdog Timer (EXPERIMENTAL)' CONFIG_SC1200_WDT $CONFIG_EXPERIMENTAL
+   tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG
    tristate '  W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT
+   tristate '  WDT Watchdog timer' CONFIG_WDT
+   tristate '  WDT PCI Watchdog timer' CONFIG_WDTPCI
+   if [ "$CONFIG_WDT" != "n" ]; then
+      bool '    WDT501 features' CONFIG_WDT_501
+      if [ "$CONFIG_WDT_501" = "y" ]; then
+         bool '      Fan Tachometer' CONFIG_WDT_501_FAN
+      fi
+   fi
    tristate '  ZF MachZ Watchdog' CONFIG_MACHZ_WDT
 fi
 endmenu
@@ -183,7 +221,12 @@
    tristate 'NetWinder flash support' CONFIG_NWFLASH
 fi
 
-dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI
+if [ "$CONFIG_X86" = "y" -o "$CONFIG_X86_64" = "y" ]; then
+   dep_tristate 'AMD 768 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI
+fi
+if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then
+   dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI
+fi
 tristate '/dev/nvram support' CONFIG_NVRAM
 tristate 'Enhanced Real Time Clock Support' CONFIG_RTC
 if [ "$CONFIG_IA64" = "y" ]; then
@@ -210,13 +253,16 @@
 
 dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
 if [ "$CONFIG_AGP" != "n" ]; then
-   bool '  Intel 440LX/BX/GX and I815/I830M/I840/I850 support' CONFIG_AGP_INTEL
+   bool '  Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL
    bool '  Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810
    bool '  VIA chipset support' CONFIG_AGP_VIA
    bool '  AMD Irongate, 761, and 762 support' CONFIG_AGP_AMD
    bool '  Generic SiS support' CONFIG_AGP_SIS
    bool '  ALI chipset support' CONFIG_AGP_ALI
    bool '  Serverworks LE/HE support' CONFIG_AGP_SWORKS
+   if [ "$CONFIG_IA64" = "y" ]; then
+      bool '  HP ZX1 AGP support' CONFIG_AGP_HP_ZX1
+   fi
 fi
 
 bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM
@@ -235,6 +281,13 @@
 if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
    source drivers/char/pcmcia/Config.in
 fi
+if [ "$CONFIG_MIPS_AU1000" = "y" ]; then
+   tristate ' Alchemy Au1000 GPIO device support' CONFIG_AU1000_GPIO
+   tristate ' Au1000/ADS7846 touchscreen support' CONFIG_TS_AU1000_ADS7846
+fi
+if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
+  tristate ' ITE GPIO' CONFIG_ITE_GPIO
+fi
 
 if [ "$CONFIG_X86" = "y" ]; then
    tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/Makefile linux/drivers/char/Makefile
--- linux.orig/drivers/char/Makefile	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -23,7 +23,8 @@
 
 export-objs     :=	busmouse.o console.o keyboard.o sysrq.o \
 			misc.o pty.o random.o selection.o serial.o \
-			sonypi.o tty_io.o tty_ioctl.o generic_serial.o
+			sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
+			au1000_gpio.o
 
 mod-subdirs	:=	joystick ftape drm drm-4.0 pcmcia
 
@@ -58,11 +59,18 @@
    ifdef CONFIG_AMIGA
       KEYBD = amikeyb.o
    else
-      KEYBD =
+      ifndef CONFIG_MAC
+	 KEYBD =
+      endif
    endif
    SERIAL   =
 endif
 
+ifdef CONFIG_Q40
+  KEYBD += q40_keyb.o
+  SERIAL = serial.o
+endif
+
 ifeq ($(ARCH),arm)
   ifneq ($(CONFIG_PC_KEYMAP),y)
     KEYMAP   =
@@ -124,12 +132,17 @@
   KEYMAP   = qtronixmap.o
 endif
 
+ifeq ($(CONFIG_DUMMY_KEYB),y)
+  KEYBD = dummy_keyb.o
+endif
+
 obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
 obj-$(CONFIG_SERIAL) += $(SERIAL)
-obj-$(CONFIG_SERIAL_ACPI) += acpi_serial.o
+obj-$(CONFIG_SERIAL_HCDP) += hcdp_serial.o
 obj-$(CONFIG_SERIAL_21285) += serial_21285.o
 obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o
 obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o
+obj-$(CONFIG_TS_AU1000_ADS7846) += au1000_ts.o
 
 ifndef CONFIG_SUN_KEYBOARD
   obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
@@ -147,6 +160,7 @@
 obj-$(CONFIG_CYCLADES) += cyclades.o
 obj-$(CONFIG_STALLION) += stallion.o
 obj-$(CONFIG_ISTALLION) += istallion.o
+obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o
 obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o
 obj-$(CONFIG_RISCOM8) += riscom8.o
 obj-$(CONFIG_ISI) += isicom.o
@@ -164,6 +178,7 @@
 obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o
 obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o
 obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o
+obj-$(CONFIG_TXX927_SERIAL) += serial_txx927.o
 
 subdir-$(CONFIG_RIO) += rio
 subdir-$(CONFIG_INPUT) += joystick
@@ -187,6 +202,7 @@
 obj-$(CONFIG_ATARIMOUSE) += atarimouse.o
 obj-$(CONFIG_ADBMOUSE) += adbmouse.o
 obj-$(CONFIG_PC110_PAD) += pc110pad.o
+obj-$(CONFIG_MK712_MOUSE) += mk712.o
 obj-$(CONFIG_RTC) += rtc.o
 obj-$(CONFIG_EFI_RTC) += efirtc.o
 ifeq ($(CONFIG_PPC),)
@@ -196,6 +212,11 @@
 obj-$(CONFIG_I8K) += i8k.o
 obj-$(CONFIG_DS1620) += ds1620.o
 obj-$(CONFIG_INTEL_RNG) += i810_rng.o
+obj-$(CONFIG_AMD_RNG) += amd768_rng.o
+
+obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
+obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o
+obj-$(CONFIG_COBALT_LCD) += lcd.o
 
 obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
 
@@ -226,6 +247,8 @@
 obj-$(CONFIG_IB700_WDT) += ib700wdt.o
 obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
 obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
+obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
+obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
 obj-$(CONFIG_WDT) += wdt.o
 obj-$(CONFIG_WDTPCI) += wdt_pci.o
 obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
@@ -234,6 +257,10 @@
 obj-$(CONFIG_MACHZ_WDT) += machzwd.o
 obj-$(CONFIG_SH_WDT) += shwdt.o
 obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
+obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
+obj-$(CONFIG_INDYDOG) += indydog.o
+obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
+obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
 obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
 
 subdir-$(CONFIG_MWAVE) += mwave
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/acpi_serial.c linux/drivers/char/acpi_serial.c
--- linux.orig/drivers/char/acpi_serial.c	2001-11-14 19:45:41.000000000 +0000
+++ linux/drivers/char/acpi_serial.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,203 +0,0 @@
-/*
- *  linux/drivers/char/acpi_serial.c
- *
- *  Copyright (C) 2000  Hewlett-Packard Co.
- *  Copyright (C) 2000  Khalid Aziz <khalid_aziz@hp.com>
- *
- *  Detect and initialize the headless console serial port defined in 
- *  SPCR table and debug serial port defined in DBGP table
- *
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/acpi.h>
-#include <linux/init.h>
-#include <linux/serial.h>
-#include <asm/serial.h>
-#include <asm/io.h>
-#include <linux/acpi_serial.h>
-/*#include <asm/acpi-ext.h>*/
-
-#undef SERIAL_DEBUG_ACPI
-
-/*
- * Query ACPI tables for a debug and a headless console serial
- * port. If found, add them to rs_table[]. A pointer to either SPCR
- * or DBGP table is passed as parameter. This function should be called 
- * before serial_console_init() is called to make sure the SPCR serial 
- * console will be available for use. IA-64 kernel calls this function
- * from within acpi.c when it encounters SPCR or DBGP tables as it parses 
- * the ACPI 2.0 tables during bootup.
- *
- */
-void __init setup_serial_acpi(void *tablep) 
-{
-	acpi_ser_t *acpi_ser_p;
-	struct serial_struct serial_req;
-	unsigned long iobase;
-	int global_sys_irq;
-
-#ifdef SERIAL_DEBUG_ACPI
-	printk("Entering setup_serial_acpi()\n");
-#endif
-
-	/* Now get the table */
-	if (tablep == NULL) {
-		return;
-	}
-
-	acpi_ser_p = (acpi_ser_t *)tablep;
-
-	/*
-	 * Perform a sanity check on the table. Table should have a 
-	 * signature of "SPCR" or "DBGP" and it should be atleast 52 bytes
-	 * long.
-	 */
-	if ((strncmp(acpi_ser_p->signature, ACPI_SPCRT_SIGNATURE, 
-					ACPI_SIG_LEN) != 0) && 
-		(strncmp(acpi_ser_p->signature, ACPI_DBGPT_SIGNATURE, 
-					ACPI_SIG_LEN) != 0)) {
-		return;
-	}
-	if (acpi_ser_p->length < 52) {
-		return;
-	}
-
-	iobase = (((u64) acpi_ser_p->base_addr.addrh) << 32) | acpi_ser_p->base_addr.addrl;
-	global_sys_irq = (acpi_ser_p->global_int[3] << 24) | 
-			(acpi_ser_p->global_int[2] << 16) |
-			(acpi_ser_p->global_int[1] << 8) |
-			acpi_ser_p->global_int[0];
-
-#ifdef SERIAL_DEBUG_ACPI
-	printk("setup_serial_acpi(): table pointer = 0x%p\n", acpi_ser_p);
-	printk("                     sig = '%c%c%c%c'\n",
-			acpi_ser_p->signature[0],
-			acpi_ser_p->signature[1],
-			acpi_ser_p->signature[2],
-			acpi_ser_p->signature[3]);
-	printk("                     length = %d\n", acpi_ser_p->length);
-	printk("                     Rev = %d\n", acpi_ser_p->rev);
-	printk("                     Interface type = %d\n", acpi_ser_p->intfc_type);
-	printk("                     Base address = 0x%lX\n", iobase);
-	printk("                     IRQ = %d\n", acpi_ser_p->irq);
-	printk("                     Global System Int = %d\n", global_sys_irq);
-	printk("                     Baud rate = ");
-	switch (acpi_ser_p->baud) {
-		case ACPI_SERIAL_BAUD_9600:
-			printk("9600\n");
-			break;
-
-		case ACPI_SERIAL_BAUD_19200:
-			printk("19200\n");
-			break;
-
-		case ACPI_SERIAL_BAUD_57600:
-			printk("57600\n");
-			break;
-
-		case ACPI_SERIAL_BAUD_115200:
-			printk("115200\n");
-			break;
-
-		default:
-			printk("Huh (%d)\n", acpi_ser_p->baud);
-			break;
-
-	}
-	if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_PCICONF_SPACE) {
-		printk("                     PCI serial port:\n");
-		printk("                         Bus %d, Device %d, Vendor ID 0x%x, Dev ID 0x%x\n",
-		acpi_ser_p->pci_bus, acpi_ser_p->pci_dev,
-		acpi_ser_p->pci_vendor_id, acpi_ser_p->pci_dev_id);
-	}
-#endif
-
-	/* 
-	 * Now build a serial_req structure to update the entry in
-	 * rs_table for the headless console port.
-	 */
-	switch (acpi_ser_p->intfc_type) {
- 		case ACPI_SERIAL_INTFC_16550:
-			serial_req.type = PORT_16550;
-			serial_req.baud_base = BASE_BAUD;
-			break;
-
- 		case ACPI_SERIAL_INTFC_16450:
-			serial_req.type = PORT_16450;
-			serial_req.baud_base = BASE_BAUD;
-			break;
-
-		default:
-			serial_req.type = PORT_UNKNOWN;
-			break;
-	}
-	if (strncmp(acpi_ser_p->signature, ACPI_SPCRT_SIGNATURE,
-					ACPI_SIG_LEN) == 0) {
-		serial_req.line = ACPI_SERIAL_CONSOLE_PORT;
-	}
-	else if (strncmp(acpi_ser_p->signature, ACPI_DBGPT_SIGNATURE, 
-					ACPI_SIG_LEN) == 0) {
-		serial_req.line = ACPI_SERIAL_DEBUG_PORT;
-	}
-	/*
-	 * Check if this is an I/O mapped address or a memory mapped address
-	 */
-	if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_MEM_SPACE) {
-		serial_req.port = 0;
-		serial_req.port_high = 0;
-		serial_req.iomem_base = (void *)ioremap(iobase, 64);
-		serial_req.io_type = SERIAL_IO_MEM;
-	}
-	else if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_IO_SPACE) {
-		serial_req.port = (unsigned long) iobase & 0xffffffff;
-		serial_req.port_high = (unsigned long)(((u64)iobase) >> 32);
-		serial_req.iomem_base = NULL;
-		serial_req.io_type = SERIAL_IO_PORT;
-	}
-	else if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_PCICONF_SPACE) {
-		printk("WARNING: No support for PCI serial console\n");
-		return;
-	}
-
-	/*
-	 * If the table does not have IRQ information, use 0 for IRQ. 
-	 * This will force rs_init() to probe for IRQ. 
-	 */
-	if (acpi_ser_p->length < 53) {
-		serial_req.irq = 0;
-	}
-	else {
-		serial_req.flags = ASYNC_SKIP_TEST | ASYNC_BOOT_AUTOCONF | 
-					ASYNC_AUTO_IRQ;
-		if (acpi_ser_p->int_type & 
-			(ACPI_SERIAL_INT_APIC | ACPI_SERIAL_INT_SAPIC)) {
-			serial_req.irq = global_sys_irq;
-		}
-		else if (acpi_ser_p->int_type & ACPI_SERIAL_INT_PCAT) {
-			serial_req.irq = acpi_ser_p->irq;
-		}
-		else {
-			/*
-			 * IRQ type not being set would mean UART will
-			 * run in polling mode. Do not probe for IRQ in
-			 * that case.
-			 */
-			serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF;
-		}
-	}
-
-	serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
-	serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
-	serial_req.iomem_reg_shift = 0;
-	if (early_serial_setup(&serial_req) < 0) {
-		printk("early_serial_setup() for ACPI serial console port failed\n");
-		return;
-	}
-
-#ifdef SERIAL_DEBUG_ACPI
-	printk("Leaving setup_serial_acpi()\n");
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/acquirewdt.c linux/drivers/char/acquirewdt.c
--- linux.orig/drivers/char/acquirewdt.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/char/acquirewdt.c	2002-07-20 01:08:24.000000000 +0000
@@ -209,7 +209,8 @@
 	printk("WDT driver for Acquire single board computer initialising.\n");
 
 	spin_lock_init(&acq_lock);
-	misc_register(&acq_miscdev);
+	if (misc_register(&acq_miscdev))
+		return -ENODEV;
 	request_region(WDT_STOP, 1, "Acquire WDT");
 	request_region(WDT_START, 1, "Acquire WDT");
 	register_reboot_notifier(&acq_notifier);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/advantechwdt.c linux/drivers/char/advantechwdt.c
--- linux.orig/drivers/char/advantechwdt.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/advantechwdt.c	2002-07-20 01:08:33.000000000 +0000
@@ -13,10 +13,10 @@
  *	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.
- *	
- *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
- *	warranty for any of this software. This material is provided 
- *	"AS-IS" and at no charge.	
+ *
+ *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
  *
  *	(c) Copyright 1995    Alan Cox <alan@redhat.com>
  *
@@ -24,14 +24,11 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <asm/io.h>
@@ -40,41 +37,67 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
-static int advwdt_is_open;
-static spinlock_t advwdt_lock;
+static unsigned long advwdt_is_open;
+static char adv_expect_close;
 
 /*
  *	You must set these - there is no sane way to probe for this board.
  *
  *	To enable or restart, write the timeout value in seconds (1 to 63)
- *	to I/O port WDT_START.  To disable, read I/O port WDT_STOP.
+ *	to I/O port wdt_start.  To disable, read I/O port wdt_stop.
  *	Both are 0x443 for most boards (tested on a PCA-6276VE-00B1), but
  *	check your manual (at least the PCA-6159 seems to be different -
- *	the manual says WDT_STOP is 0x43, not 0x443).
+ *	the manual says wdt_stop is 0x43, not 0x443).
  *	(0x43 is also a write-only control register for the 8254 timer!)
- *
- *	TODO: module parameters to set the I/O port addresses and NOWAYOUT
- *	option at load time.
  */
  
-#define WDT_STOP 0x443
-#define WDT_START 0x443
+static int wdt_stop = 0x443;
+static int wdt_start = 0x443;
 
-#define WD_TIMO 60		/* 1 minute */
-static int wd_margin = WD_TIMO;
+static int wd_margin = 60; /* 60 sec default timeout */
 
 /*
  *	Kernel methods.
  */
- 
+
+#ifndef MODULE
+
+static int __init adv_setup(char *str)
+{
+	int ints[4];
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+
+	if(ints[0] > 0){
+		wdt_stop = ints[1];
+		if(ints[0] > 1)
+			wdt_start = ints[2];
+	}
+
+	return 1;
+}
+
+__setup("advwdt=", adv_setup);
+
+#endif /* !MODULE */
+
+MODULE_PARM(wdt_stop, "i");
+MODULE_PARM_DESC(wdt_stop, "Advantech WDT 'stop' io port (default 0x443)");
+MODULE_PARM(wdt_start, "i");
+MODULE_PARM_DESC(wdt_start, "Advantech WDT 'start' io port (default 0x443)");
+
 static void
 advwdt_ping(void)
 {
 	/* Write a watchdog value */
-	outb_p(wd_margin, WDT_START);
+	outb_p(wd_margin, wdt_start);
+}
+
+static void
+advwdt_disable(void)
+{
+	inb_p(wdt_stop);
 }
 
 static ssize_t
@@ -85,16 +108,19 @@
 		return -ESPIPE;
 
 	if (count) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+		size_t i;
+
+		adv_expect_close = 0;
+
+		for (i = 0; i != count; i++) {
+			if (buf[i] == 'V')
+				adv_expect_close = 42;
+		}
+#endif
 		advwdt_ping();
-		return 1;
 	}
-	return 0;
-}
-
-static ssize_t
-advwdt_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-{
-	return -EINVAL;
+	return count;
 }
 
 static int
@@ -103,19 +129,20 @@
 {
 	int new_margin;
 	static struct watchdog_info ident = {
-		WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, 1, "Advantech WDT"
+		options:		WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+		firmware_version:	0,
+		identity:		"Advantech WDT"
 	};
-	
+
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
 	  if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
 	    return -EFAULT;
 	  break;
-	  
+
 	case WDIOC_GETSTATUS:
-	  if (copy_to_user((int *)arg, &advwdt_is_open,  sizeof(int)))
-	    return -EFAULT;
-	  break;
+	case WDIOC_GETBOOTSTATUS:
+	  return put_user(0, (int *)arg);
 
 	case WDIOC_KEEPALIVE:
 	  advwdt_ping();
@@ -132,7 +159,26 @@
 
 	case WDIOC_GETTIMEOUT:
 	  return put_user(wd_margin, (int *)arg);
-	  break;
+
+	case WDIOC_SETOPTIONS:
+	{
+	  int options, retval = -EINVAL;
+
+	  if (get_user(options, (int *)arg))
+	    return -EFAULT;
+
+	  if (options & WDIOS_DISABLECARD) {
+	    advwdt_disable();
+	    retval = 0;
+	  }
+
+	  if (options & WDIOS_ENABLECARD) {
+	    advwdt_ping();
+	    retval = 0;
+	  }
+
+	  return retval;
+	}
 
 	default:
 	  return -ENOTTY;
@@ -143,39 +189,27 @@
 static int
 advwdt_open(struct inode *inode, struct file *file)
 {
-	switch (MINOR(inode->i_rdev)) {
-		case WATCHDOG_MINOR:
-			spin_lock(&advwdt_lock);
-			if (advwdt_is_open) {
-				spin_unlock(&advwdt_lock);
-				return -EBUSY;
-			}
-			/*
-			 *	Activate 
-			 */
-	 
-			advwdt_is_open = 1;
-			advwdt_ping();
-			spin_unlock(&advwdt_lock);
-			return 0;
-		default:
-			return -ENODEV;
-	}
+	if (test_and_set_bit(0, &advwdt_is_open))
+		return -EBUSY;
+	/*
+	 *	Activate
+	 */
+
+	advwdt_ping();
+	return 0;
 }
 
 static int
 advwdt_close(struct inode *inode, struct file *file)
 {
-	lock_kernel();
-	if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
-		spin_lock(&advwdt_lock);
-#ifndef CONFIG_WATCHDOG_NOWAYOUT	
-		inb_p(WDT_STOP);
-#endif		
-		advwdt_is_open = 0;
-		spin_unlock(&advwdt_lock);
+	if (adv_expect_close == 42) {
+		advwdt_disable();
+	} else {
+		printk(KERN_CRIT "advancetechwdt: Unexpected close, not stopping watchdog!\n");
+		advwdt_ping();
 	}
-	unlock_kernel();
+	clear_bit(0, &advwdt_is_open);
+	adv_expect_close = 0;
 	return 0;
 }
 
@@ -189,7 +223,7 @@
 {
 	if (code == SYS_DOWN || code == SYS_HALT) {
 		/* Turn the WDT off */
-		inb_p(WDT_STOP);
+		advwdt_disable();
 	}
 	return NOTIFY_DONE;
 }
@@ -200,7 +234,7 @@
  
 static struct file_operations advwdt_fops = {
 	owner:		THIS_MODULE,
-	read:		advwdt_read,
+	llseek:		no_llseek,
 	write:		advwdt_write,
 	ioctl:		advwdt_ioctl,
 	open:		advwdt_open,
@@ -208,14 +242,14 @@
 };
 
 static struct miscdevice advwdt_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&advwdt_fops
+	minor:		WATCHDOG_MINOR,
+	name:		"watchdog",
+	fops:		&advwdt_fops,
 };
 
 /*
  *	The WDT needs to learn about soft shutdowns in order to
- *	turn the timebomb registers off. 
+ *	turn the timebomb registers off.
  */
  
 static struct notifier_block advwdt_notifier = {
@@ -227,14 +261,12 @@
 static int __init
 advwdt_init(void)
 {
-	printk("WDT driver for Advantech single board computer initialising.\n");
+	printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
 
-	spin_lock_init(&advwdt_lock);
 	misc_register(&advwdt_miscdev);
-#if WDT_START != WDT_STOP
-	request_region(WDT_STOP, 1, "Advantech WDT");
-#endif
-	request_region(WDT_START, 1, "Advantech WDT");
+	if(wdt_stop != wdt_start)
+		request_region(wdt_stop, 1, "Advantech WDT");
+	request_region(wdt_start, 1, "Advantech WDT");
 	register_reboot_notifier(&advwdt_notifier);
 	return 0;
 }
@@ -244,16 +276,18 @@
 {
 	misc_deregister(&advwdt_miscdev);
 	unregister_reboot_notifier(&advwdt_notifier);
-#if WDT_START != WDT_STOP
-	release_region(WDT_STOP,1);
-#endif
-	release_region(WDT_START,1);
+	if(wdt_stop != wdt_start)
+		release_region(wdt_stop,1);
+	release_region(wdt_start,1);
 }
 
 module_init(advwdt_init);
 module_exit(advwdt_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marek Michalkiewicz <marekm@linux.org.pl>");
+MODULE_DESCRIPTION("Advantech Single Board Computer WDT driver");
+EXPORT_NO_SYMBOLS;
 
 /* end of advantechwdt.c */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/agp/agp.h linux/drivers/char/agp/agp.h
--- linux.orig/drivers/char/agp/agp.h	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/agp/agp.h	2002-07-20 01:08:34.000000000 +0000
@@ -125,10 +125,12 @@
 	
 };
 
+#define OUTREG64(mmap, addr, val)   __raw_writeq((val), (mmap)+(addr))
 #define OUTREG32(mmap, addr, val)   __raw_writel((val), (mmap)+(addr))
 #define OUTREG16(mmap, addr, val)   __raw_writew((val), (mmap)+(addr))
 #define OUTREG8(mmap, addr, val)   __raw_writeb((val), (mmap)+(addr))
 
+#define INREG64(mmap, addr)         __raw_readq((mmap)+(addr))
 #define INREG32(mmap, addr)         __raw_readl((mmap)+(addr))
 #define INREG16(mmap, addr)         __raw_readw((mmap)+(addr))
 #define INREG8(mmap, addr)         __raw_readb((mmap)+(addr))
@@ -170,6 +172,12 @@
 #ifndef PCI_DEVICE_ID_INTEL_810_0
 #define PCI_DEVICE_ID_INTEL_810_0       0x7120
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_845_G_0
+#define PCI_DEVICE_ID_INTEL_845_G_0	0x2560
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_845_G_1
+#define PCI_DEVICE_ID_INTEL_845_G_1     0x2562
+#endif
 #ifndef PCI_DEVICE_ID_INTEL_830_M_0
 #define PCI_DEVICE_ID_INTEL_830_M_0	0x3575
 #endif
@@ -248,12 +256,18 @@
 #ifndef PCI_DEVICE_ID_AL_M1641_0
 #define PCI_DEVICE_ID_AL_M1641_0	0x1641
 #endif
+#ifndef PCI_DEVICE_ID_AL_M1644_0
+#define PCI_DEVICE_ID_AL_M1644_0	0x1644
+#endif
 #ifndef PCI_DEVICE_ID_AL_M1647_0
 #define PCI_DEVICE_ID_AL_M1647_0	0x1647
 #endif
 #ifndef PCI_DEVICE_ID_AL_M1651_0
 #define PCI_DEVICE_ID_AL_M1651_0	0x1651
 #endif
+#ifndef PCI_DEVICE_ID_AL_M1671_0
+#define PCI_DEVICE_ID_AL_M1671_0	0x1671
+#endif
 
 /* intel register */
 #define INTEL_APBASE    0x10
@@ -282,6 +296,10 @@
 /* This one is for I830MP w. an external graphic card */
 #define INTEL_I830_ERRSTS          0x92
 
+/* intel 815 register */
+#define INTEL_815_APCONT        0x51
+#define INTEL_815_ATTBASE_MASK  ~0x1FFFFFFF
+
 /* intel i820 registers */
 #define INTEL_I820_RDCR     0x51
 #define INTEL_I820_ERRSTS   0xc8
@@ -375,4 +393,13 @@
 #define SVWRKS_POSTFLUSH  0x14
 #define SVWRKS_DIRFLUSH   0x0c
 
+/* HP ZX1 SBA registers */
+#define HP_ZX1_CTRL		0x200
+#define HP_ZX1_IBASE		0x300
+#define HP_ZX1_IMASK		0x308
+#define HP_ZX1_PCOM		0x310
+#define HP_ZX1_TCNFG		0x318
+#define HP_ZX1_PDIR_BASE	0x320
+#define HP_ZX1_CACHE_FLUSH	0x428
+
 #endif				/* _AGP_BACKEND_PRIV_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- linux.orig/drivers/char/agp/agpgart_be.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/agp/agpgart_be.c	2002-07-20 01:08:26.000000000 +0000
@@ -410,34 +410,8 @@
 	 */
 
 
-	pci_for_each_dev(device)
-	{
-		/*
-		 *	Enable AGP devices. Most will be VGA display but
-		 *	some may be coprocessors on non VGA devices too
-		 */
-		 
-		if((((device->class >> 16) & 0xFF) != PCI_BASE_CLASS_DISPLAY) &&
-			(device->class != (PCI_CLASS_PROCESSOR_CO << 8)))
-			continue;
-
-		pci_read_config_dword(device, 0x04, &scratch);
-
-		if (!(scratch & 0x00100000))
-			continue;
-
-		pci_read_config_byte(device, 0x34, &cap_ptr);
-
-		if (cap_ptr != 0x00) {
-			do {
-				pci_read_config_dword(device,
-						      cap_ptr, &cap_id);
-
-				if ((cap_id & 0xff) != 0x02)
-					cap_ptr = (cap_id >> 8) & 0xff;
-			}
-			while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
-		}
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
 		if (cap_ptr != 0x00) {
 			/*
 			 * Ok, here we have a AGP device. Disable impossible 
@@ -506,25 +480,8 @@
 	 *        command registers.
 	 */
 
-	while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8,
-					device)) != NULL) {
-		pci_read_config_dword(device, 0x04, &scratch);
-
-		if (!(scratch & 0x00100000))
-			continue;
-
-		pci_read_config_byte(device, 0x34, &cap_ptr);
-
-		if (cap_ptr != 0x00) {
-			do {
-				pci_read_config_dword(device,
-						      cap_ptr, &cap_id);
-
-				if ((cap_id & 0xff) != 0x02)
-					cap_ptr = (cap_id >> 8) & 0xff;
-			}
-			while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
-		}
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
 		if (cap_ptr != 0x00)
 			pci_write_config_dword(device, cap_ptr + 8, command);
 	}
@@ -622,7 +579,7 @@
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
 	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
-		set_bit(PG_reserved, &page->flags);
+		SetPageReserved(page);
 
 	agp_bridge.gatt_table_real = (unsigned long *) table;
 	CACHE_FLUSH();
@@ -632,7 +589,7 @@
 
 	if (agp_bridge.gatt_table == NULL) {
 		for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
-			clear_bit(PG_reserved, &page->flags);
+			ClearPageReserved(page);
 
 		free_pages((unsigned long) table, page_order);
 
@@ -699,7 +656,7 @@
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
 	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
-		clear_bit(PG_reserved, &page->flags);
+		ClearPageReserved(page);
 
 	free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
 	return 0;
@@ -812,8 +769,8 @@
 	if (page == NULL) {
 		return 0;
 	}
-	atomic_inc(&page->count);
-	set_bit(PG_locked, &page->flags);
+	get_page(page);
+	LockPage(page);
 	atomic_inc(&agp_bridge.current_memory_agp);
 	return (unsigned long)page_address(page);
 }
@@ -828,9 +785,8 @@
 	}
 	
 	page = virt_to_page(pt);
-	atomic_dec(&page->count);
-	clear_bit(PG_locked, &page->flags);
-	wake_up(&page->wait);
+	put_page(page);
+	UnlockPage(page);
 	free_page((unsigned long) pt);
 	atomic_dec(&agp_bridge.current_memory_agp);
 }
@@ -1137,7 +1093,8 @@
 	int gtt_entries;
 } intel_i830_private;
 
-static void intel_i830_init_gtt_entries(void) {
+static void intel_i830_init_gtt_entries(void)
+{
 	u16 gmch_ctrl;
 	int gtt_entries;
 	u8 rdct;
@@ -1147,15 +1104,15 @@
 
 	switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
 	case I830_GMCH_GMS_STOLEN_512:
-		gtt_entries = KB(512);
+		gtt_entries = KB(512) - KB(132);
 		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
 		break;
 	case I830_GMCH_GMS_STOLEN_1024:
-		gtt_entries = MB(1);
+		gtt_entries = MB(1) - KB(132);
 		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
 		break;
 	case I830_GMCH_GMS_STOLEN_8192:
-		gtt_entries = MB(8);
+		gtt_entries = MB(8) - KB(132);
 		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
 		break;
 	case I830_GMCH_GMS_LOCAL:
@@ -1445,6 +1402,12 @@
 	aper_size_info_8 *values;
 
 	pci_read_config_byte(agp_bridge.dev, INTEL_APSIZE, &temp);
+
+        /* Intel 815 chipsets have a _weird_ APSIZE register with only
+         * one non-reserved bit, so mask the others out ... */
+        if (agp_bridge.type == INTEL_I815) 
+          temp &= (1 << 3);
+        
 	values = A_SIZE_8(agp_bridge.aperture_sizes);
 
 	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
@@ -1534,6 +1497,44 @@
 	return 0;
 }
 
+static int intel_815_configure(void)
+{
+	u32 temp, addr;
+	u8 temp2;
+	aper_size_info_8 *current_size;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
+			      current_size->size_value); 
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+        /* the Intel 815 chipset spec. says that bits 29-31 in the
+         * ATTBASE register are reserved -> try not to write them */
+        if (agp_bridge.gatt_bus_addr &  INTEL_815_ATTBASE_MASK)
+		panic("gatt bus addr too high");
+	pci_read_config_dword(agp_bridge.dev, INTEL_ATTBASE, &addr);
+	addr &= INTEL_815_ATTBASE_MASK;
+	addr |= agp_bridge.gatt_bus_addr;
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, addr);
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+
+	/* apcont */
+	pci_read_config_byte(agp_bridge.dev, INTEL_815_APCONT, &temp2);
+	pci_write_config_byte(agp_bridge.dev, INTEL_815_APCONT,
+			      temp2 | (1 << 1));
+	/* clear any possible error conditions */
+        /* Oddness : this chipset seems to have no ERRSTS register ! */
+	return 0;
+}
+
 static void intel_820_tlbflush(agp_memory * mem)
 {
   return;
@@ -1768,6 +1769,12 @@
 	{0x00000017, 0}
 };
 
+static aper_size_info_8 intel_815_sizes[2] =
+{
+	{64, 16384, 4, 0},
+	{32, 8192, 3, 8},
+};
+
 static aper_size_info_8 intel_8xx_sizes[7] =
 {
 	{256, 65536, 6, 0},
@@ -1831,7 +1838,38 @@
 	(void) pdev; /* unused */
 }
 
+static int __init intel_815_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_815_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 2;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_815_configure;
+	agp_bridge.fetch_size = intel_8xx_fetch_size;
+	agp_bridge.cleanup = intel_8xx_cleanup;
+	agp_bridge.tlb_flush = intel_8xx_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
 
+	return 0;
+	
+	(void) pdev; /* unused */
+}
 
 static int __init intel_820_setup (struct pci_dev *pdev)
 {
@@ -2285,13 +2323,12 @@
 	if (page_map->real == NULL) {
 		return -ENOMEM;
 	}
-	set_bit(PG_reserved, &virt_to_page(page_map->real)->flags);
+	SetPageReserved(virt_to_page(page_map->real));
 	CACHE_FLUSH();
 	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), 
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL) {
-		clear_bit(PG_reserved, 
-			  &virt_to_page(page_map->real)->flags);
+		ClearPageReserved(virt_to_page(page_map->real));
 		free_page((unsigned long) page_map->real);
 		page_map->real = NULL;
 		return -ENOMEM;
@@ -2308,8 +2345,7 @@
 static void amd_free_page_map(amd_page_map *page_map)
 {
 	iounmap(page_map->remapped);
-	clear_bit(PG_reserved, 
-		  &virt_to_page(page_map->real)->flags);
+	ClearPageReserved(virt_to_page(page_map->real));
 	free_page((unsigned long) page_map->real);
 }
 
@@ -2797,8 +2833,8 @@
 	if (page == NULL)
 		return 0;
 
-	atomic_inc(&page->count);
-	set_bit(PG_locked, &page->flags);
+	get_page(page);
+	LockPage(page);
 	atomic_inc(&agp_bridge.current_memory_agp);
 
 	global_cache_flush();
@@ -2833,9 +2869,8 @@
 	}
 
 	page = virt_to_page(pt);
-	atomic_dec(&page->count);
-	clear_bit(PG_locked, &page->flags);
-	wake_up(&page->wait);
+	put_page(page);
+	UnlockPage(page);
 	free_page((unsigned long) pt);
 	atomic_dec(&agp_bridge.current_memory_agp);
 }
@@ -2917,13 +2952,12 @@
 	if (page_map->real == NULL) {
 		return -ENOMEM;
 	}
-	set_bit(PG_reserved, &virt_to_page(page_map->real)->flags);
+	SetPageReserved(virt_to_page(page_map->real));
 	CACHE_FLUSH();
 	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), 
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL) {
-		clear_bit(PG_reserved, 
-			  &virt_to_page(page_map->real)->flags);
+		ClearPageReserved(virt_to_page(page_map->real));
 		free_page((unsigned long) page_map->real);
 		page_map->real = NULL;
 		return -ENOMEM;
@@ -2940,8 +2974,7 @@
 static void serverworks_free_page_map(serverworks_page_map *page_map)
 {
 	iounmap(page_map->remapped);
-	clear_bit(PG_reserved, 
-		  &virt_to_page(page_map->real)->flags);
+	ClearPageReserved(virt_to_page(page_map->real));
 	free_page((unsigned long) page_map->real);
 }
 
@@ -3331,24 +3364,8 @@
 	 */
 
 
-	pci_for_each_dev(device)
-	{
-		/*
-		 *	Enable AGP devices. Most will be VGA display but
-		 *	some may be coprocessors on non VGA devices too
-		 */
-		 
-		if((((device->class >> 16) & 0xFF) != PCI_BASE_CLASS_DISPLAY) &&
-			(device->class != (PCI_CLASS_PROCESSOR_CO << 8)))
-			continue;
-
-		pci_read_config_dword(device, 0x04, &scratch);
-
-		if (!(scratch & 0x00100000))
-			continue;
-
-		pci_read_config_byte(device, 0x34, &cap_ptr);
-
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
 		if (cap_ptr != 0x00) {
 			do {
 				pci_read_config_dword(device,
@@ -3426,25 +3443,8 @@
 	 *        command registers.
 	 */
 
-	while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8,
-					device)) != NULL) {
-		pci_read_config_dword(device, 0x04, &scratch);
-
-		if (!(scratch & 0x00100000))
-			continue;
-
-		pci_read_config_byte(device, 0x34, &cap_ptr);
-
-		if (cap_ptr != 0x00) {
-			do {
-				pci_read_config_dword(device,
-						      cap_ptr, &cap_id);
-
-				if ((cap_id & 0xff) != 0x02)
-					cap_ptr = (cap_id >> 8) & 0xff;
-			}
-			while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
-		}
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
 		if (cap_ptr != 0x00)
 			pci_write_config_dword(device, cap_ptr + 8, command);
 	}
@@ -3522,6 +3522,368 @@
 
 #endif /* CONFIG_AGP_SWORKS */
 
+#ifdef CONFIG_AGP_HP_ZX1
+
+#ifndef log2
+#define log2(x)		ffz(~(x))
+#endif
+
+#define HP_ZX1_IOVA_BASE	GB(1UL)
+#define HP_ZX1_IOVA_SIZE	GB(1UL)
+#define HP_ZX1_GART_SIZE	(HP_ZX1_IOVA_SIZE / 2)
+#define HP_ZX1_SBA_IOMMU_COOKIE	0x0000badbadc0ffeeUL
+
+#define HP_ZX1_PDIR_VALID_BIT	0x8000000000000000UL
+#define HP_ZX1_IOVA_TO_PDIR(va)	((va - hp_private.iova_base) >> \
+					hp_private.io_tlb_shift)
+
+static aper_size_info_fixed hp_zx1_sizes[] =
+{
+	{0, 0, 0},		/* filled in by hp_zx1_fetch_size() */
+};
+
+static gatt_mask hp_zx1_masks[] =
+{
+	{HP_ZX1_PDIR_VALID_BIT, 0}
+};
+
+static struct _hp_private {
+	struct pci_dev *ioc;
+	volatile u8 *registers;
+	u64 *io_pdir;		// PDIR for entire IOVA
+	u64 *gatt;		// PDIR just for GART (subset of above)
+	u64 gatt_entries;
+	u64 iova_base;
+	u64 gart_base;
+	u64 gart_size;
+	u64 io_pdir_size;
+	int io_pdir_owner;	// do we own it, or share it with sba_iommu?
+	int io_page_size;
+	int io_tlb_shift;
+	int io_tlb_ps;		// IOC ps config
+	int io_pages_per_kpage;
+} hp_private;
+
+static int __init hp_zx1_ioc_shared(void)
+{
+	struct _hp_private *hp = &hp_private;
+
+	printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR shared with sba_iommu\n");
+
+	/*
+	 * IOC already configured by sba_iommu module; just use
+	 * its setup.  We assume:
+	 * 	- IOVA space is 1Gb in size
+	 * 	- first 512Mb is IOMMU, second 512Mb is GART
+	 */
+	hp->io_tlb_ps = INREG64(hp->registers, HP_ZX1_TCNFG);
+	switch (hp->io_tlb_ps) {
+		case 0: hp->io_tlb_shift = 12; break;
+		case 1: hp->io_tlb_shift = 13; break;
+		case 2: hp->io_tlb_shift = 14; break;
+		case 3: hp->io_tlb_shift = 16; break;
+		default:
+			printk(KERN_ERR PFX "Invalid IOTLB page size "
+			       "configuration 0x%x\n", hp->io_tlb_ps);
+			hp->gatt = 0;
+			hp->gatt_entries = 0;
+			return -ENODEV;
+	}
+	hp->io_page_size = 1 << hp->io_tlb_shift;
+	hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
+
+	hp->iova_base = INREG64(hp->registers, HP_ZX1_IBASE) & ~0x1;
+	hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE;
+
+	hp->gart_size = HP_ZX1_GART_SIZE;
+	hp->gatt_entries = hp->gart_size / hp->io_page_size;
+
+	hp->io_pdir = phys_to_virt(INREG64(hp->registers, HP_ZX1_PDIR_BASE));
+	hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
+
+	if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
+	    	hp->gatt = 0;
+		hp->gatt_entries = 0;
+		printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
+		       "GART disabled\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int __init hp_zx1_ioc_owner(u8 ioc_rev)
+{
+	struct _hp_private *hp = &hp_private;
+
+	printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR dedicated to GART\n");
+
+	/*
+	 * Select an IOV page size no larger than system page size.
+	 */
+	if (PAGE_SIZE >= KB(64)) {
+		hp->io_tlb_shift = 16;
+		hp->io_tlb_ps = 3;
+	} else if (PAGE_SIZE >= KB(16)) {
+		hp->io_tlb_shift = 14;
+		hp->io_tlb_ps = 2;
+	} else if (PAGE_SIZE >= KB(8)) {
+		hp->io_tlb_shift = 13;
+		hp->io_tlb_ps = 1;
+	} else {
+		hp->io_tlb_shift = 12;
+		hp->io_tlb_ps = 0;
+	}
+	hp->io_page_size = 1 << hp->io_tlb_shift;
+	hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
+
+	hp->iova_base = HP_ZX1_IOVA_BASE;
+	hp->gart_size = HP_ZX1_GART_SIZE;
+	hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - hp->gart_size;
+
+	hp->gatt_entries = hp->gart_size / hp->io_page_size;
+	hp->io_pdir_size = (HP_ZX1_IOVA_SIZE / hp->io_page_size) * sizeof(u64);
+
+	return 0;
+}
+
+static int __init hp_zx1_ioc_init(void)
+{
+	struct _hp_private *hp = &hp_private;
+	struct pci_dev *ioc;
+	int i;
+	u8 ioc_rev;
+
+	ioc = pci_find_device(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_ZX1_IOC, NULL);
+	if (!ioc) {
+		printk(KERN_ERR PFX "Detected HP ZX1 AGP bridge but no IOC\n");
+		return -ENODEV;
+	}
+	hp->ioc = ioc;
+
+	pci_read_config_byte(ioc, PCI_REVISION_ID, &ioc_rev);
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		if (pci_resource_flags(ioc, i) == IORESOURCE_MEM) {
+			hp->registers = (u8 *) ioremap(pci_resource_start(ioc,
+									    i),
+						    pci_resource_len(ioc, i));
+			break;
+		}
+	}
+	if (!hp->registers) {
+		printk(KERN_ERR PFX "Detected HP ZX1 AGP bridge but no CSRs\n");
+
+		return -ENODEV;
+	}
+
+	/*
+	 * If the IOTLB is currently disabled, we can take it over.
+	 * Otherwise, we have to share with sba_iommu.
+	 */
+	hp->io_pdir_owner = (INREG64(hp->registers, HP_ZX1_IBASE) & 0x1) == 0;
+
+	if (hp->io_pdir_owner)
+		return hp_zx1_ioc_owner(ioc_rev);
+
+	return hp_zx1_ioc_shared();
+}
+
+static int hp_zx1_fetch_size(void)
+{
+	int size;
+
+	size = hp_private.gart_size / MB(1);
+	hp_zx1_sizes[0].size = size;
+	agp_bridge.current_size = (void *) &hp_zx1_sizes[0];
+	return size;
+}
+
+static int hp_zx1_configure(void)
+{
+	struct _hp_private *hp = &hp_private;
+
+	agp_bridge.gart_bus_addr = hp->gart_base;
+	agp_bridge.capndx = pci_find_capability(agp_bridge.dev, PCI_CAP_ID_AGP);
+	pci_read_config_dword(agp_bridge.dev,
+		agp_bridge.capndx + PCI_AGP_STATUS, &agp_bridge.mode);
+
+	if (hp->io_pdir_owner) {
+		OUTREG64(hp->registers, HP_ZX1_PDIR_BASE,
+			virt_to_phys(hp->io_pdir));
+		OUTREG64(hp->registers, HP_ZX1_TCNFG, hp->io_tlb_ps);
+		OUTREG64(hp->registers, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1));
+		OUTREG64(hp->registers, HP_ZX1_IBASE, hp->iova_base | 0x1);
+		OUTREG64(hp->registers, HP_ZX1_PCOM,
+			hp->iova_base | log2(HP_ZX1_IOVA_SIZE));
+		INREG64(hp->registers, HP_ZX1_PCOM);
+	}
+
+	return 0;
+}
+
+static void hp_zx1_cleanup(void)
+{
+	struct _hp_private *hp = &hp_private;
+
+	if (hp->io_pdir_owner)
+		OUTREG64(hp->registers, HP_ZX1_IBASE, 0);
+	iounmap((void *) hp->registers);
+}
+
+static void hp_zx1_tlbflush(agp_memory * mem)
+{
+	struct _hp_private *hp = &hp_private;
+
+	OUTREG64(hp->registers, HP_ZX1_PCOM, 
+		hp->gart_base | log2(hp->gart_size));
+	INREG64(hp->registers, HP_ZX1_PCOM);
+}
+
+static int hp_zx1_create_gatt_table(void)
+{
+	struct _hp_private *hp = &hp_private;
+	int i;
+
+	if (hp->io_pdir_owner) {
+		hp->io_pdir = (u64 *) __get_free_pages(GFP_KERNEL,
+						get_order(hp->io_pdir_size));
+		if (!hp->io_pdir) {
+			printk(KERN_ERR PFX "Couldn't allocate contiguous "
+				"memory for I/O PDIR\n");
+			hp->gatt = 0;
+			hp->gatt_entries = 0;
+			return -ENOMEM;
+		}
+		memset(hp->io_pdir, 0, hp->io_pdir_size);
+
+		hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
+	}
+
+	for (i = 0; i < hp->gatt_entries; i++) {
+		hp->gatt[i] = (unsigned long) agp_bridge.scratch_page;
+	}
+
+	return 0;
+}
+
+static int hp_zx1_free_gatt_table(void)
+{
+	struct _hp_private *hp = &hp_private;
+	
+	if (hp->io_pdir_owner)
+		free_pages((unsigned long) hp->io_pdir,
+			    get_order(hp->io_pdir_size));
+	else
+		hp->gatt[0] = HP_ZX1_SBA_IOMMU_COOKIE;
+	return 0;
+}
+
+static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	struct _hp_private *hp = &hp_private;
+	int i, k;
+	off_t j, io_pg_start;
+	int io_pg_count;
+
+	if (type != 0 || mem->type != 0) {
+		return -EINVAL;
+	}
+
+	io_pg_start = hp->io_pages_per_kpage * pg_start;
+	io_pg_count = hp->io_pages_per_kpage * mem->page_count;
+	if ((io_pg_start + io_pg_count) > hp->gatt_entries) {
+		return -EINVAL;
+	}
+
+	j = io_pg_start;
+	while (j < (io_pg_start + io_pg_count)) {
+		if (hp->gatt[j]) {
+			return -EBUSY;
+		}
+		j++;
+	}
+
+	if (mem->is_flushed == FALSE) {
+		CACHE_FLUSH();
+		mem->is_flushed = TRUE;
+	}
+
+	for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
+		unsigned long paddr;
+
+		paddr = mem->memory[i];
+		for (k = 0;
+		     k < hp->io_pages_per_kpage;
+		     k++, j++, paddr += hp->io_page_size) {
+			hp->gatt[j] = agp_bridge.mask_memory(paddr, type);
+		}
+	}
+
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+static int hp_zx1_remove_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	struct _hp_private *hp = &hp_private;
+	int i, io_pg_start, io_pg_count;
+
+	if (type != 0 || mem->type != 0) {
+		return -EINVAL;
+	}
+
+	io_pg_start = hp->io_pages_per_kpage * pg_start;
+	io_pg_count = hp->io_pages_per_kpage * mem->page_count;
+	for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
+		hp->gatt[i] = agp_bridge.scratch_page;
+	}
+
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+static unsigned long hp_zx1_mask_memory(unsigned long addr, int type)
+{
+	return HP_ZX1_PDIR_VALID_BIT | addr;
+}
+
+static unsigned long hp_zx1_unmask_memory(unsigned long addr)
+{
+	return addr & ~(HP_ZX1_PDIR_VALID_BIT);
+}
+
+static int __init hp_zx1_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = hp_zx1_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.size_type = FIXED_APER_SIZE;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = hp_zx1_configure;
+	agp_bridge.fetch_size = hp_zx1_fetch_size;
+	agp_bridge.cleanup = hp_zx1_cleanup;
+	agp_bridge.tlb_flush = hp_zx1_tlbflush;
+	agp_bridge.mask_memory = hp_zx1_mask_memory;
+	agp_bridge.unmask_memory = hp_zx1_unmask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = hp_zx1_create_gatt_table;
+	agp_bridge.free_gatt_table = hp_zx1_free_gatt_table;
+	agp_bridge.insert_memory = hp_zx1_insert_memory;
+	agp_bridge.remove_memory = hp_zx1_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 1;
+
+	return hp_zx1_ioc_init();
+
+	(void) pdev; /* unused */
+}
+
+#endif /* CONFIG_AGP_HP_ZX1 */
 
 /* per-chipset initialization data.
  * note -- all chipsets for a single vendor MUST be grouped together
@@ -3566,6 +3928,12 @@
 		"Ali",
 		"M1641",
 		ali_generic_setup },
+	{ PCI_DEVICE_ID_AL_M1644_0,
+		PCI_VENDOR_ID_AL,
+		ALI_M1644,
+		"Ali",
+		"M1644",
+		ali_generic_setup },
 	{ PCI_DEVICE_ID_AL_M1647_0,
 		PCI_VENDOR_ID_AL,
 		ALI_M1647,
@@ -3578,6 +3946,12 @@
 		"Ali",
 		"M1651",
 		ali_generic_setup },  
+	{ PCI_DEVICE_ID_AL_M1671_0,
+		PCI_VENDOR_ID_AL,
+		ALI_M1671,
+		"Ali",
+		"M1671",
+		ali_generic_setup },  
 	{ 0,
 		PCI_VENDOR_ID_AL,
 		ALI_GENERIC,
@@ -3597,7 +3971,7 @@
 		PCI_VENDOR_ID_AMD,
 		AMD_IRONGATE,
 		"AMD",
-		"AMD 760MP",
+		"760MP",
 		amd_irongate_setup },
 	{ PCI_DEVICE_ID_AMD_761_0,
 		PCI_VENDOR_ID_AMD,
@@ -3609,7 +3983,7 @@
 		PCI_VENDOR_ID_AMD,
 		AMD_762,
 		"AMD",
-		"AMD 760MP",
+		"760MP",
 		amd_irongate_setup },
 	{ 0,
 		PCI_VENDOR_ID_AMD,
@@ -3643,7 +4017,7 @@
 		INTEL_I815,
 		"Intel",
 		"i815",
-		intel_generic_setup },
+		intel_815_setup },
 	{ PCI_DEVICE_ID_INTEL_820_0,
 		PCI_VENDOR_ID_INTEL,
 		INTEL_I820,
@@ -3662,6 +4036,12 @@
 		"Intel",
 		"i830M",
 		intel_830mp_setup },
+    { PCI_DEVICE_ID_INTEL_845_G_0,
+		 PCI_VENDOR_ID_INTEL,
+		 INTEL_I845_G,
+		 "Intel",
+		 "i845G",
+		 intel_830mp_setup },
 	{ PCI_DEVICE_ID_INTEL_840_0,
 		PCI_VENDOR_ID_INTEL,
 		INTEL_I840,
@@ -3720,6 +4100,12 @@
 		"SiS",
 		"735",
 		sis_generic_setup },
+	{ PCI_DEVICE_ID_SI_745,
+		PCI_VENDOR_ID_SI,
+		SIS_GENERIC,
+		"SiS",
+		"745",
+		sis_generic_setup },
 	{ PCI_DEVICE_ID_SI_730,
 		PCI_VENDOR_ID_SI,
 		SIS_GENERIC,
@@ -3815,6 +4201,15 @@
 		via_generic_setup },
 #endif /* CONFIG_AGP_VIA */
 
+#ifdef CONFIG_AGP_HP_ZX1
+	{ PCI_DEVICE_ID_HP_ZX1_LBA,
+		PCI_VENDOR_ID_HP,
+		HP_ZX1,
+		"HP",
+		"ZX1",
+		hp_zx1_setup },
+#endif
+
 	{ 0, }, /* dummy final entry, always present */
 };
 
@@ -3979,6 +4374,28 @@
 			agp_bridge.type = INTEL_I810;
 			return intel_i810_setup(i810_dev);
 
+		case PCI_DEVICE_ID_INTEL_845_G_0:
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+					PCI_DEVICE_ID_INTEL_845_G_1, NULL);
+			if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
+				i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+					PCI_DEVICE_ID_INTEL_845_G_1, i810_dev);
+			}
+
+			if (i810_dev == NULL) {
+                                /* 
+                                 * We probably have a I845 G chipset
+                                 * with an external graphics
+                                 * card. It will be initialized later 
+                                 */
+				agp_bridge.type = INTEL_I845_G;
+				break;
+			}
+			printk(KERN_INFO PFX "Detected an Intel "
+				   "845G Chipset.\n");
+			agp_bridge.type = INTEL_I810;
+			return intel_i830_setup(i810_dev);
+		   
 		case PCI_DEVICE_ID_INTEL_830_M_0:
 			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
 					PCI_DEVICE_ID_INTEL_830_M_1, NULL);
@@ -4041,21 +4458,25 @@
 
 #endif	/* CONFIG_AGP_SWORKS */
 
-	/* find capndx */
-	pci_read_config_dword(dev, 0x04, &scratch);
-	if (!(scratch & 0x00100000))
-		return -ENODEV;
-
-	pci_read_config_byte(dev, 0x34, &cap_ptr);
-	if (cap_ptr != 0x00) {
+#ifdef CONFIG_AGP_HP_ZX1
+	if (dev->vendor == PCI_VENDOR_ID_HP) {
 		do {
-			pci_read_config_dword(dev, cap_ptr, &cap_id);
-
-			if ((cap_id & 0xff) != 0x02)
-				cap_ptr = (cap_id >> 8) & 0xff;
-		}
-		while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
+			/* ZX1 LBAs can be either PCI or AGP bridges */
+			if (pci_find_capability(dev, PCI_CAP_ID_AGP)) {
+				printk(KERN_INFO PFX "Detected HP ZX1 AGP "
+				       "chipset at %s\n", dev->slot_name);
+				agp_bridge.type = HP_ZX1;
+				agp_bridge.dev = dev;
+				return hp_zx1_setup(dev);
+			}
+			dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, dev);
+		} while (dev);
+		return -ENODEV;
 	}
+#endif	/* CONFIG_AGP_HP_ZX1 */
+
+	/* find capndx */
+	cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
 	if (cap_ptr == 0x00)
 		return -ENODEV;
 	agp_bridge.capndx = cap_ptr;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/alim7101_wdt.c linux/drivers/char/alim7101_wdt.c
--- linux.orig/drivers/char/alim7101_wdt.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/alim7101_wdt.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,335 @@
+/*
+ *	ALi M7101 PMU Computer Watchdog Timer driver for Linux 2.4.x
+ *
+ *	Based on w83877f_wdt.c by Scott Jennings <management@oro.net>
+ *	and the Cobalt kernel WDT timer driver by Tim Hockin
+ *	                                      <thockin@cobaltnet.com>
+ *
+ *	(c)2002 Steve Hill <steve@navaho.co.uk>
+ * 
+ *  Theory of operation:
+ *  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 WDT driver
+ *  via the /proc/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.
+ *
+ *  This WDT driver is different from most other Linux WDT
+ *  drivers in that the driver will ping the watchdog by itself,
+ *  because this particular WDT has a very short timeout (1.6
+ *  seconds) and it would be insane to count on any userspace
+ *  daemon always getting scheduled within that time frame.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/smp_lock.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#define OUR_NAME "alim7101_wdt"
+
+#define WDT_ENABLE 0x9C
+#define WDT_DISABLE 0x8C
+
+#define ALI_7101_WDT    0x92
+#define ALI_WDT_ARM     0x01
+
+/*
+ * We're going to use a 1 second timeout.
+ * If we reset the watchdog every ~250ms we should be safe.  */
+
+#define WDT_INTERVAL (HZ/4+1)
+
+/*
+ * We must not require too good response from the userspace daemon.
+ * Here we require the userspace daemon to send us a heartbeat
+ * char to /dev/watchdog every 30 seconds.
+ */
+
+#define WDT_HEARTBEAT (HZ * 30)
+
+static void wdt_timer_ping(unsigned long);
+static struct timer_list timer;
+static unsigned long next_heartbeat;
+static unsigned long wdt_is_open;
+static int wdt_expect_close;
+static struct pci_dev *alim7101_pmu;
+
+/*
+ *	Whack the dog
+ */
+
+static void wdt_timer_ping(unsigned long data)
+{
+	/* If we got a heartbeat pulse within the WDT_US_INTERVAL
+	 * we agree to ping the WDT 
+	 */
+	char	tmp;
+
+	if(time_before(jiffies, next_heartbeat)) 
+	{
+		/* Ping the WDT (this is actually a disarm/arm sequence) */
+		pci_read_config_byte(alim7101_pmu, 0x92, &tmp);
+		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
+		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM));
+	} else {
+		printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n");
+	}
+	/* Re-set the timer interval */
+	timer.expires = jiffies + WDT_INTERVAL;
+	add_timer(&timer);
+}
+
+/* 
+ * Utility routines
+ */
+
+static void wdt_change(int writeval)
+{
+	char	tmp;
+
+	pci_read_config_byte(alim7101_pmu, 0x92, &tmp);
+	if (writeval == WDT_ENABLE)
+		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM));
+	else
+		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
+}
+
+static void wdt_startup(void)
+{
+	next_heartbeat = jiffies + WDT_HEARTBEAT;
+
+	/* We must enable before we kick off the timer in case the timer
+	   occurs as we ping it */
+
+	wdt_change(WDT_ENABLE);
+
+	/* Start the timer */
+	timer.expires = jiffies + WDT_INTERVAL;	
+	add_timer(&timer);
+
+
+	printk(OUR_NAME ": Watchdog timer is now enabled.\n");  
+}
+
+static void wdt_turnoff(void)
+{
+	/* Stop the timer */
+	del_timer_sync(&timer);
+	wdt_change(WDT_DISABLE);
+	printk(OUR_NAME ": Watchdog timer is now disabled...\n");
+}
+
+/*
+ * /dev/watchdog handling
+ */
+
+static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+{
+	/* We can't seek */
+	if(ppos != &file->f_pos)
+		return -ESPIPE;
+
+	/* See if we got the magic character */
+	if(count) 
+	{
+		size_t ofs;
+
+		/* note: just in case someone wrote the magic character
+		 * five months ago... */
+		wdt_expect_close = 0;
+
+		/* now scan */
+		for(ofs = 0; ofs != count; ofs++)
+			if(buf[ofs] == 'V')
+				wdt_expect_close = 1;
+
+		/* someone wrote to us, we should restart timer */
+		next_heartbeat = jiffies + WDT_HEARTBEAT;
+		return 1;
+	};
+	return 0;
+}
+
+static ssize_t fop_read(struct file * file, char * buf, size_t count, loff_t * ppos)
+{
+	/* No can do */
+	return -EINVAL;
+}
+
+static int fop_open(struct inode * inode, struct file * file)
+{
+	/* Just in case we're already talking to someone... */
+	if(test_and_set_bit(0, &wdt_is_open))
+		return -EBUSY;
+	/* Good, fire up the show */
+	wdt_startup();
+	return 0;
+}
+
+static int fop_close(struct inode * inode, struct file * file)
+{
+#ifdef CONFIG_WDT_NOWAYOUT
+	if(wdt_expect_close)
+		wdt_turnoff();
+	else {
+		printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
+	}
+#else
+	wdt_turnoff();
+#endif
+	clear_bit(0, &wdt_is_open);
+	return 0;
+}
+
+static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	static struct watchdog_info ident=
+	{
+		0,
+		1,
+		"ALiM7101"
+	};
+	
+	switch(cmd)
+	{
+		case WDIOC_GETSUPPORT:
+			return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+		case WDIOC_KEEPALIVE:
+			next_heartbeat = jiffies + WDT_HEARTBEAT;
+			return 0;
+		default:
+			return -ENOTTY;
+	}
+}
+
+static struct file_operations wdt_fops = {
+	owner:		THIS_MODULE,
+	llseek:		no_llseek,
+	read:		fop_read,
+	write:		fop_write,
+	open:		fop_open,
+	release:	fop_close,
+	ioctl:		fop_ioctl
+};
+
+static struct miscdevice wdt_miscdev = {
+	WATCHDOG_MINOR,
+	"watchdog",
+	&wdt_fops
+};
+
+/*
+ *	Notifier for system down
+ */
+
+static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+	if (code==SYS_DOWN || code==SYS_HALT) wdt_turnoff();
+	if (code==SYS_RESTART) {
+		/*
+		 * Cobalt devices have no way of rebooting themselves other than
+		 * getting the watchdog to pull reset, so we restart the watchdog on
+		 * reboot with no heartbeat
+		 */
+		wdt_change(WDT_ENABLE);
+		printk(OUR_NAME ": Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n");
+	};
+	return NOTIFY_DONE;
+}
+ 
+/*
+ *	The WDT needs to learn about soft shutdowns in order to
+ *	turn the timebomb registers off. 
+ */
+ 
+static struct notifier_block wdt_notifier=
+{
+	wdt_notify_sys,
+	0,
+	0
+};
+
+static void __exit alim7101_wdt_unload(void)
+{
+	wdt_turnoff();
+	/* Deregister */
+	misc_deregister(&wdt_miscdev);
+	unregister_reboot_notifier(&wdt_notifier);
+}
+
+static int __init alim7101_wdt_init(void)
+{
+	int rc = -EBUSY;
+	struct pci_dev *ali1543_south;
+	char tmp;
+
+	printk(KERN_INFO OUR_NAME ": Steve Hill <steve@navaho.co.uk>.\n");
+	alim7101_pmu = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,NULL);
+	if (!alim7101_pmu) {
+		printk(KERN_INFO OUR_NAME ": ALi M7101 PMU not present - WDT not set\n");
+		return -EBUSY;
+	};
+	
+	/* Set the WDT in the PMU to 1 second */
+	pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02);
+
+	ali1543_south = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
+	if (!ali1543_south) {
+		printk(KERN_INFO OUR_NAME ": ALi 1543 South-Bridge not present - WDT not set\n");
+		return -EBUSY;
+	};
+	pci_read_config_byte(ali1543_south, 0x5e, &tmp);
+	if ((tmp & 0x1e) != 0x12) {
+		printk(KERN_INFO OUR_NAME ": ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
+		return -EBUSY;
+	};
+
+	init_timer(&timer);
+	timer.function = wdt_timer_ping;
+	timer.data = 1;
+		
+	rc = misc_register(&wdt_miscdev);
+	if (rc)
+		return rc;
+
+	rc = register_reboot_notifier(&wdt_notifier);
+	if (rc) {
+		misc_deregister(&wdt_miscdev);
+		return rc;
+	};
+	
+	printk(KERN_INFO OUR_NAME ": WDT driver for ALi M7101 initialised.\n");
+	return 0;
+}
+
+module_init(alim7101_wdt_init);
+module_exit(alim7101_wdt_unload);
+
+EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Steve Hill");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/amd768_rng.c linux/drivers/char/amd768_rng.c
--- linux.orig/drivers/char/amd768_rng.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/amd768_rng.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,295 @@
+/*
+ 	Hardware driver for the AMD 768 Random Number Generator (RNG)
+	(c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+ 
+ 	derived from
+ 
+	Hardware driver for Intel i810 Random Number Generator (RNG)
+	Copyright 2000,2001 Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+
+	Please read Documentation/i810_rng.txt for details on use.
+
+	----------------------------------------------------------
+	This software may be used and distributed according to the terms
+        of the GNU General Public License, incorporated herein by reference.
+
+ */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/random.h>
+#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+
+/*
+ * core module and version information
+ */
+#define RNG_VERSION "0.1.0"
+#define RNG_MODULE_NAME "amd768_rng"
+#define RNG_DRIVER_NAME   RNG_MODULE_NAME " hardware driver " RNG_VERSION
+#define PFX RNG_MODULE_NAME ": "
+
+
+/*
+ * debugging macros
+ */
+#undef RNG_DEBUG /* define to enable copious debugging info */
+
+#ifdef RNG_DEBUG
+/* note: prints function name for you */
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#undef RNG_NDEBUG        /* define to disable lightweight runtime checks */
+#ifdef RNG_NDEBUG
+#define assert(expr)
+#else
+#define assert(expr) \
+        if(!(expr)) {                                   \
+        printk( "Assertion failed! %s,%s,%s,line=%d\n", \
+        #expr,__FILE__,__FUNCTION__,__LINE__);          \
+        }
+#endif
+
+#define RNG_MISCDEV_MINOR		183 /* official */
+
+/*
+ * various RNG status variables.  they are globals
+ * as we only support a single RNG device
+ */
+
+static u32 pmbase;			/* PMxx I/O base */
+static struct semaphore rng_open_sem;	/* Semaphore for serializing rng_open/release */
+
+
+/*
+ * inlined helper functions for accessing RNG registers
+ */
+
+static inline int rng_data_present (void)
+{
+      	return inl(pmbase+0xF4) & 1;
+}
+
+
+static inline int rng_data_read (void)
+{
+	return inl(pmbase+0xF0);
+}
+
+static int rng_dev_open (struct inode *inode, struct file *filp)
+{
+	if ((filp->f_mode & FMODE_READ) == 0)
+		return -EINVAL;
+	if (filp->f_mode & FMODE_WRITE)
+		return -EINVAL;
+
+	/* wait for device to become free */
+	if (filp->f_flags & O_NONBLOCK) {
+		if (down_trylock (&rng_open_sem))
+			return -EAGAIN;
+	} else {
+		if (down_interruptible (&rng_open_sem))
+			return -ERESTARTSYS;
+	}
+	return 0;
+}
+
+
+static int rng_dev_release (struct inode *inode, struct file *filp)
+{
+	up(&rng_open_sem);
+	return 0;
+}
+
+
+static ssize_t rng_dev_read (struct file *filp, char *buf, size_t size,
+			     loff_t * offp)
+{
+	static spinlock_t rng_lock = SPIN_LOCK_UNLOCKED;
+	int have_data;
+	u32 data = 0;
+	ssize_t ret = 0;
+
+	while (size) {
+		spin_lock(&rng_lock);
+
+		have_data = 0;
+		if (rng_data_present()) {
+			data = rng_data_read();
+			have_data = 4;
+		}
+
+		spin_unlock (&rng_lock);
+
+		while (have_data > 0) {
+			if (put_user((u8)data, buf++)) {
+				ret = ret ? : -EFAULT;
+				break;
+			}
+			size--;
+			ret++;
+			have_data--;
+			data>>=8;
+		}
+
+		if (filp->f_flags & O_NONBLOCK)
+			return ret ? : -EAGAIN;
+
+		if(current->need_resched)
+		{
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(1);
+		}
+		else
+			udelay(200);	/* FIXME: We could poll for 250uS ?? */
+
+		if (signal_pending (current))
+			return ret ? : -ERESTARTSYS;
+	}
+	return ret;
+}
+
+
+static struct file_operations rng_chrdev_ops = {
+	owner:		THIS_MODULE,
+	open:		rng_dev_open,
+	release:	rng_dev_release,
+	read:		rng_dev_read,
+};
+
+
+static struct miscdevice rng_miscdev = {
+	RNG_MISCDEV_MINOR,
+	RNG_MODULE_NAME,
+	&rng_chrdev_ops,
+};
+
+
+/*
+ * rng_init_one - look for and attempt to init a single RNG
+ */
+static int __init rng_init_one (struct pci_dev *dev)
+{
+	int rc;
+	u8 rnen;
+
+	DPRINTK ("ENTER\n");
+
+	rc = misc_register (&rng_miscdev);
+	if (rc) {
+		printk (KERN_ERR PFX "cannot register misc device\n");
+		DPRINTK ("EXIT, returning %d\n", rc);
+		goto err_out;
+	}
+
+	pci_read_config_dword(dev, 0x58, &pmbase);
+
+	pmbase&=0x0000FF00;
+
+	if(pmbase == 0)
+	{
+		printk (KERN_ERR PFX "power management base not set\n");
+		DPRINTK ("EXIT, returning %d\n", rc);
+		goto err_out_free_miscdev;
+	}
+
+	pci_read_config_byte(dev, 0x40, &rnen);
+	rnen|=(1<<7);	/* RNG on */
+	pci_write_config_byte(dev, 0x40, rnen);
+
+	pci_read_config_byte(dev, 0x41, &rnen);
+	rnen|=(1<<7);	/* PMIO enable */
+	pci_write_config_byte(dev, 0x41, rnen);
+
+	printk(KERN_INFO PFX "AMD768 system management I/O registers at 0x%X.\n", pmbase);
+	DPRINTK ("EXIT, returning 0\n");
+	return 0;
+
+err_out_free_miscdev:
+	misc_deregister (&rng_miscdev);
+err_out:
+	return rc;
+}
+
+
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+static struct pci_device_id rng_pci_tbl[] __initdata = {
+	{ 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
+
+
+MODULE_AUTHOR("Alan Cox, Jeff Garzik, Philipp Rumpf, Matt Sottek");
+MODULE_DESCRIPTION("AMD 768 Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * rng_init - initialize RNG module
+ */
+static int __init rng_init (void)
+{
+	int rc;
+	struct pci_dev *pdev;
+
+	DPRINTK ("ENTER\n");
+
+	init_MUTEX (&rng_open_sem);
+
+	pci_for_each_dev(pdev) {
+		if (pci_match_device (rng_pci_tbl, pdev) != NULL)
+			goto match;
+	}
+
+	DPRINTK ("EXIT, returning -ENODEV\n");
+	return -ENODEV;
+
+match:
+	rc = rng_init_one (pdev);
+	if (rc)
+		return rc;
+
+	printk (KERN_INFO RNG_DRIVER_NAME " loaded\n");
+
+	DPRINTK ("EXIT, returning 0\n");
+	return 0;
+}
+
+
+/*
+ * rng_init - shutdown RNG module
+ */
+static void __exit rng_cleanup (void)
+{
+	DPRINTK ("ENTER\n");
+	misc_deregister (&rng_miscdev);
+	DPRINTK ("EXIT\n");
+}
+
+
+module_init (rng_init);
+module_exit (rng_cleanup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/amiserial.c linux/drivers/char/amiserial.c
--- linux.orig/drivers/char/amiserial.c	2001-09-17 04:22:56.000000000 +0000
+++ linux/drivers/char/amiserial.c	2002-07-20 01:08:40.000000000 +0000
@@ -89,7 +89,7 @@
 #include <asm/setup.h>
 
 #include <asm/system.h>
-#include <asm/io.h>
+
 #include <asm/irq.h>
 #include <asm/bitops.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/applicom.c linux/drivers/char/applicom.c
--- linux.orig/drivers/char/applicom.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/char/applicom.c	2002-07-20 01:08:33.000000000 +0000
@@ -36,7 +36,7 @@
 
 #if LINUX_VERSION_CODE < 0x20300 
 /* These probably want adding to <linux/compatmac.h> */
-#define init_waitqueue_head(x) do { *(x) = NULL; } while (0);
+#define init_waitqueue_head(x) do { *(x) = NULL; } while (0)
 #define PCI_BASE_ADDRESS(dev) (dev->base_address[0])
 #define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x
 #define __setup(x,y) /* */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/au1000_gpio.c linux/drivers/char/au1000_gpio.c
--- linux.orig/drivers/char/au1000_gpio.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/au1000_gpio.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,270 @@
+/*
+ * FILE NAME au1000_gpio.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *  Driver for Alchemy Au1000 GPIO.
+ *
+ *  Author: MontaVista Software, Inc.  <source@mvista.com>
+ *          Steve Longerbeam <stevel@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE	LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/au1000.h>
+#include <asm/au1000_gpio.h>
+
+#define VERSION "0.01"
+
+static const struct {
+	u32 active_hi;
+	u32 avail_mask;
+} pinfunc_to_avail[15] = {
+	{1,  0x7<<16},   // 0  = SSI0     / GPIO[18:16]
+	{-1, 0},         // 1  = AC97     / SSI1
+	{1,  1<<19},     // 2  = IRDA     / GPIO19
+	{1,  1<<20},     // 3  = UART0    / GPIO20
+	{1,  0x1f<<24},  // 4  = NIC2     / GPIO[28:24]
+	{1,  0x7<<29},   // 5  = I2S      / GPIO[31:29]
+	{0,  1<<8},      // 6  = I2SDI    / GPIO8
+	{0,  0x3f<<9},   // 7  = UART3    / GPIO[14:9]
+	{0,  1<<15},     // 8  = IRFIRSEL / GPIO15
+	{0,  1<<2},      // 9  = EXTCLK0 or OSC / GPIO2
+	{0,  1<<3},      // 10 = EXTCLK1  / GPIO3
+	{0,  1<<6},      // 11 = SMROMCKE / GPIO6
+	{1,  1<<21},     // 12 = UART1    / GPIO21
+	{1,  1<<22},     // 13 = UART2    / GPIO22
+	{1,  1<<23}      // 14 = UART3    / GPIO23
+};
+
+	
+u32 get_au1000_avail_gpio_mask(void)
+{
+	int i;
+	u32 pinfunc = inl(SYS_PINFUNC);
+	u32 avail_mask = 0; // start with no gpio available
+
+	// first, check for GPIO's reprogrammed as peripheral pins
+	for (i=0; i<15; i++) {
+		if (pinfunc_to_avail[i].active_hi < 0)
+			continue;
+		if (!(pinfunc_to_avail[i].active_hi ^
+		      ((pinfunc & (1<<i)) ? 1:0)))
+			avail_mask |= pinfunc_to_avail[i].avail_mask;
+	}
+
+	// check for GPIO's used as interrupt sources
+	avail_mask &= ~(inl(IC1_MASKRD) &
+			(inl(IC1_CFG0RD) | inl(IC1_CFG1RD)));
+
+#ifdef CONFIG_USB_OHCI
+	avail_mask &= ~((1<<4) | (1<<11));
+#ifndef CONFIG_AU1000_USB_DEVICE
+	avail_mask &= ~((1<<5) | (1<<13));
+#endif
+#endif
+	
+	return avail_mask;
+}
+
+
+/*
+ * Tristate the requested GPIO pins specified in data.
+ * Only available GPIOs will be tristated.
+ */
+int au1000gpio_tristate(u32 data)
+{
+	data &= get_au1000_avail_gpio_mask();
+
+	if (data)
+		outl(data, SYS_TRIOUTCLR);
+
+	return 0;
+}
+
+
+/*
+ * Return the pin state. Pins configured as outputs will return
+ * the output state, and pins configured as inputs (tri-stated)
+ * will return input pin state.
+ */
+int au1000gpio_in(u32 *data)
+{
+	*data = inl(SYS_PINSTATERD);
+	return 0;
+}
+
+
+/*
+ * Set/clear GPIO pins. Only available GPIOs will be affected.
+ */
+int au1000gpio_set(u32 data)
+{
+	data &= get_au1000_avail_gpio_mask();
+
+	if (data)
+		outl(data, SYS_OUTPUTSET);
+	return 0;
+}
+
+int au1000gpio_clear(u32 data)
+{
+	data &= get_au1000_avail_gpio_mask();
+
+	if (data)
+		outl(data, SYS_OUTPUTCLR);
+	return 0;
+}
+
+/*
+ * Output data to GPIO pins. Only available GPIOs will be affected.
+ */
+int au1000gpio_out(u32 data)
+{
+	au1000gpio_set(data);
+	au1000gpio_clear(~data);
+	return 0;
+}
+
+
+EXPORT_SYMBOL(get_au1000_avail_gpio_mask);
+EXPORT_SYMBOL(au1000gpio_tristate);
+EXPORT_SYMBOL(au1000gpio_in);
+EXPORT_SYMBOL(au1000gpio_set);
+EXPORT_SYMBOL(au1000gpio_clear);
+EXPORT_SYMBOL(au1000gpio_out);
+
+
+static int au1000gpio_open(struct inode *inode, struct file *file)
+{
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+
+static int au1000gpio_release(struct inode *inode, struct file *file)
+{
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+
+static int au1000gpio_ioctl(struct inode *inode, struct file *file,
+			    unsigned int cmd, unsigned long arg)
+{
+	int status;
+	u32 val;
+	
+	switch(cmd) {
+	case AU1000GPIO_IN:
+		
+		status = au1000gpio_in(&val);
+		if (status != 0)
+			return status;
+
+		return put_user(val, (u32 *)arg);
+
+	case AU1000GPIO_OUT:
+
+		if (get_user(val, (u32 *)arg)) 
+			return -EFAULT;
+
+		return au1000gpio_out(val);
+
+	case AU1000GPIO_SET:
+
+		if (get_user(val, (u32 *)arg)) 
+			return -EFAULT;
+
+		return au1000gpio_set(val);
+		
+	case AU1000GPIO_CLEAR:
+
+		if (get_user(val, (u32 *)arg)) 
+			return -EFAULT;
+
+		return au1000gpio_clear(val);
+
+	case AU1000GPIO_TRISTATE:
+
+		if (get_user(val, (u32 *)arg)) 
+			return -EFAULT;
+
+		return au1000gpio_tristate(val);
+
+	case AU1000GPIO_AVAIL_MASK:
+		
+		return put_user(get_au1000_avail_gpio_mask(),
+				(u32 *)arg);
+		
+	default:
+		return -ENOIOCTLCMD;
+
+	}
+
+	return 0;
+}
+
+
+static struct file_operations au1000gpio_fops =
+{
+	owner:		THIS_MODULE,
+	ioctl:		au1000gpio_ioctl,
+	open:		au1000gpio_open,
+	release:	au1000gpio_release,
+};
+
+
+static struct miscdevice au1000gpio_miscdev =
+{
+	GPIO_MINOR,
+	"au1000_gpio",
+	&au1000gpio_fops
+};
+
+
+int __init au1000gpio_init(void)
+{
+	misc_register(&au1000gpio_miscdev);
+	printk("Au1000 gpio driver, version %s\n", VERSION);
+	return 0;
+}	
+
+
+void __exit au1000gpio_exit(void)
+{
+	misc_deregister(&au1000gpio_miscdev);
+}
+
+
+module_init(au1000gpio_init);
+module_exit(au1000gpio_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/au1000_ts.c linux/drivers/char/au1000_ts.c
--- linux.orig/drivers/char/au1000_ts.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/au1000_ts.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,678 @@
+/*
+ *      au1000_ts.c  --  Touch screen driver for the Alchemy Au1000's
+ *                       SSI Port 0 talking to the ADS7846 touch screen
+ *                       controller.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	stevel@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Notes:
+ *
+ *  Revision history
+ *    06.27.2001  Initial version
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/string.h>
+#include <linux/ioport.h>       /* request_region */
+#include <linux/interrupt.h>    /* mark_bh */
+#include <asm/uaccess.h>        /* get_user,copy_to_user */
+#include <asm/io.h>
+#include <asm/au1000.h>
+
+#define TS_NAME "au1000-ts"
+#define TS_MAJOR 11
+
+#define PFX TS_NAME
+#define AU1000_TS_DEBUG 1
+
+#ifdef AU1000_TS_DEBUG
+#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
+
+
+// SSI Status register bit defines
+#define SSISTAT_BF    (1<<4)
+#define SSISTAT_OF    (1<<3)
+#define SSISTAT_UF    (1<<2)
+#define SSISTAT_DONE  (1<<1)
+#define SSISTAT_BUSY  (1<<0)
+
+// SSI Interrupt Pending and Enable register bit defines
+#define SSIINT_OI     (1<<3)
+#define SSIINT_UI     (1<<2)
+#define SSIINT_DI     (1<<1)
+
+// SSI Address/Data register bit defines
+#define SSIADAT_D         (1<<24)
+#define SSIADAT_ADDR_BIT  16
+#define SSIADAT_ADDR_MASK (0xff<<SSIADAT_ADDR_BIT)
+#define SSIADAT_DATA_BIT  0
+#define SSIADAT_DATA_MASK (0xfff<<SSIADAT_DATA_BIT)
+
+// SSI Enable register bit defines
+#define SSIEN_CD (1<<1)
+#define SSIEN_E  (1<<0)
+
+// SSI Config register bit defines
+#define SSICFG_AO (1<<24)
+#define SSICFG_DO (1<<23)
+#define SSICFG_ALEN_BIT 20
+#define SSICFG_ALEN_MASK (0x7<<SSICFG_ALEN_BIT)
+#define SSICFG_DLEN_BIT 16
+#define SSICFG_DLEN_MASK (0xf<<SSICFG_DLEN_BIT)
+#define SSICFG_DD (1<<11)
+#define SSICFG_AD (1<<10)
+#define SSICFG_BM_BIT 8
+#define SSICFG_BM_MASK (0x3<<SSICFG_BM_BIT)
+#define SSICFG_CE (1<<7)
+#define SSICFG_DP (1<<6)
+#define SSICFG_DL (1<<5)
+#define SSICFG_EP (1<<4)
+
+// Bus Turnaround Selection
+#define SCLK_HOLD_HIGH 0
+#define SCLK_HOLD_LOW  1
+#define SCLK_CYCLE     2
+
+/*
+ * Default config for SSI0:
+ *
+ *   - transmit MSBit first
+ *   - expect MSBit first on data receive
+ *   - address length 7 bits
+ *   - expect data length 12 bits
+ *   - do not disable Direction bit
+ *   - do not disable Address bits
+ *   - SCLK held low during bus turnaround
+ *   - Address and Data bits clocked out on falling edge of SCLK
+ *   - Direction bit high is a read, low is a write
+ *   - Direction bit precedes Address bits
+ *   - Active low enable signal
+ */
+
+#define DEFAULT_SSI_CONFIG \
+    (SSICFG_AO | SSICFG_DO | (6<<SSICFG_ALEN_BIT) | (11<<SSICFG_DLEN_BIT) |\
+    (SCLK_HOLD_LOW<<SSICFG_BM_BIT) | SSICFG_DP | SSICFG_EP)
+
+
+// ADS7846 Control Byte bit defines
+#define ADS7846_ADDR_BIT  4
+#define ADS7846_ADDR_MASK (0x7<<ADS7846_ADDR_BIT)
+#define   ADS7846_MEASURE_X  (0x5<<ADS7846_ADDR_BIT)
+#define   ADS7846_MEASURE_Y  (0x1<<ADS7846_ADDR_BIT)
+#define   ADS7846_MEASURE_Z1 (0x3<<ADS7846_ADDR_BIT)
+#define   ADS7846_MEASURE_Z2 (0x4<<ADS7846_ADDR_BIT)
+#define ADS7846_8BITS     (1<<3)
+#define ADS7846_12BITS    0
+#define ADS7846_SER       (1<<2)
+#define ADS7846_DFR       0
+#define ADS7846_PWR_BIT   0
+#define   ADS7846_PD      0
+#define   ADS7846_ADC_ON  (0x1<<ADS7846_PWR_BIT)
+#define   ADS7846_REF_ON  (0x2<<ADS7846_PWR_BIT)
+#define   ADS7846_REF_ADC_ON (0x3<<ADS7846_PWR_BIT)
+
+#define MEASURE_12BIT_X \
+    (ADS7846_MEASURE_X | ADS7846_12BITS | ADS7846_DFR | ADS7846_PD)
+#define MEASURE_12BIT_Y \
+    (ADS7846_MEASURE_Y | ADS7846_12BITS | ADS7846_DFR | ADS7846_PD)
+#define MEASURE_12BIT_Z1 \
+    (ADS7846_MEASURE_Z1 | ADS7846_12BITS | ADS7846_DFR | ADS7846_PD)
+#define MEASURE_12BIT_Z2 \
+    (ADS7846_MEASURE_Z2 | ADS7846_12BITS | ADS7846_DFR | ADS7846_PD)
+
+typedef enum {
+	IDLE = 0,
+	ACQ_X,
+	ACQ_Y,
+	ACQ_Z1,
+	ACQ_Z2
+} acq_state_t;
+
+/* +++++++++++++ Lifted from include/linux/h3600_ts.h ++++++++++++++*/
+typedef struct {
+	unsigned short pressure;  // touch pressure
+	unsigned short x;         // calibrated X
+	unsigned short y;         // calibrated Y
+	unsigned short millisecs; // timestamp of this event
+} TS_EVENT;
+
+typedef struct {
+	int xscale;
+	int xtrans;
+	int yscale;
+	int ytrans;
+	int xyswap;
+} TS_CAL;
+
+/* Use 'f' as magic number */
+#define IOC_MAGIC  'f'
+
+#define TS_GET_RATE             _IO(IOC_MAGIC, 8)
+#define TS_SET_RATE             _IO(IOC_MAGIC, 9)
+#define TS_GET_CAL              _IOR(IOC_MAGIC, 10, TS_CAL)
+#define TS_SET_CAL              _IOW(IOC_MAGIC, 11, TS_CAL)
+
+/* +++++++++++++ Done lifted from include/linux/h3600_ts.h +++++++++*/
+
+
+#define EVENT_BUFSIZE 128
+
+/*
+ * Which pressure equation to use from ADS7846 datasheet.
+ * The first equation requires knowing only the X plate
+ * resistance, but needs 4 measurements (X, Y, Z1, Z2).
+ * The second equation requires knowing both X and Y plate
+ * resistance, but only needs 3 measurements (X, Y, Z1).
+ * The second equation is preferred because of the shorter
+ * acquisition time required.
+ */
+enum {
+	PRESSURE_EQN_1 = 0,
+	PRESSURE_EQN_2
+};
+
+
+/*
+ * The touch screen's X and Y plate resistances, used by
+ * pressure equations.
+ */
+#define DEFAULT_X_PLATE_OHMS 580
+#define DEFAULT_Y_PLATE_OHMS 580
+
+/*
+ * Pen up/down pressure resistance thresholds.
+ *
+ * FIXME: these are bogus and will have to be found empirically.
+ *
+ * These are hysteresis points. If pen state is up and pressure
+ * is greater than pen-down threshold, pen transitions to down.
+ * If pen state is down and pressure is less than pen-up threshold,
+ * pen transitions to up. If pressure is in-between, pen status
+ * doesn't change.
+ *
+ * This wouldn't be needed if PENIRQ* from the ADS7846 were
+ * routed to an interrupt line on the Au1000. This would issue
+ * an interrupt when the panel is touched.
+ */
+#define DEFAULT_PENDOWN_THRESH_OHMS 100
+#define DEFAULT_PENUP_THRESH_OHMS    80
+
+typedef struct {
+	int baudrate;
+	u32 clkdiv;
+	acq_state_t acq_state;            // State of acquisition state machine
+	int x_raw, y_raw, z1_raw, z2_raw; // The current raw acquisition values
+	TS_CAL cal;                       // Calibration values
+	// The X and Y plate resistance, needed to calculate pressure
+	int x_plate_ohms, y_plate_ohms;
+	// pressure resistance at which pen is considered down/up
+	int pendown_thresh_ohms;
+	int penup_thresh_ohms;
+	int pressure_eqn;                 // eqn to use for pressure calc
+	int pendown;                      // 1 = pen is down, 0 = pen is up
+	TS_EVENT event_buf[EVENT_BUFSIZE];// The event queue
+	int nextIn, nextOut;
+	int event_count;
+	struct fasync_struct *fasync;     // asynch notification
+	struct timer_list acq_timer;      // Timer for triggering acquisitions
+	wait_queue_head_t wait;           // read wait queue
+	spinlock_t lock;
+	struct tq_struct chug_tq;
+} au1000_ts_t;
+
+static au1000_ts_t au1000_ts;
+
+
+static inline u32
+calc_clkdiv(int baud)
+{
+	u32 sys_busclk =
+		(get_au1000_speed() / (int)(inl(PM_POWERUP_CONTROL)&0x03) + 2);
+	return (sys_busclk / (2 * baud)) - 1;
+}
+
+static inline int
+calc_baudrate(u32 clkdiv)
+{
+	u32 sys_busclk =
+		(get_au1000_speed() / (int)(inl(PM_POWERUP_CONTROL)&0x03) + 2);
+	return sys_busclk / (2 * (clkdiv + 1));
+}
+
+
+/*
+ * This is a bottom-half handler that is scheduled after
+ * raw X,Y,Z1,Z2 coordinates have been acquired, and does
+ * the following:
+ *
+ *   - computes touch screen pressure resistance
+ *   - if pressure is above a threshold considered to be pen-down:
+ *         - compute calibrated X and Y coordinates
+ *         - queue a new TS_EVENT
+ *         - signal asynchronously and wake up any read
+ */
+static void
+chug_raw_data(void* private)
+{
+	au1000_ts_t* ts = (au1000_ts_t*)private;
+	TS_EVENT event;
+	int Rt, Xcal, Ycal;
+	unsigned long flags;
+
+	// timestamp this new event.
+	event.millisecs = jiffies;
+
+	// Calculate touch pressure resistance
+	if (ts->pressure_eqn == PRESSURE_EQN_2) {
+		Rt = (ts->x_plate_ohms * ts->x_raw *
+		      (4096 - ts->z1_raw)) / ts->z1_raw;
+		Rt -= (ts->y_plate_ohms * ts->y_raw);
+		Rt = (Rt + 2048) >> 12; // round up to nearest ohm
+	} else {
+		Rt = (ts->x_plate_ohms * ts->x_raw *
+		      (ts->z2_raw - ts->z1_raw)) / ts->z1_raw;
+		Rt = (Rt + 2048) >> 12; // round up to nearest ohm
+	}
+
+	// hysteresis
+	if (!ts->pendown && Rt > ts->pendown_thresh_ohms)
+		ts->pendown = 1;
+	else if (ts->pendown && Rt < ts->penup_thresh_ohms)
+		ts->pendown = 0;
+
+	if (ts->pendown) {
+		// Pen is down
+		// Calculate calibrated X,Y
+		Xcal = ((ts->cal.xscale * ts->x_raw) >> 8) + ts->cal.xtrans;
+		Ycal = ((ts->cal.yscale * ts->y_raw) >> 8) + ts->cal.ytrans;
+
+		event.x = (unsigned short)Xcal;
+		event.y = (unsigned short)Ycal;
+		event.pressure = (unsigned short)Rt;
+
+		// add this event to the event queue
+		spin_lock_irqsave(&ts->lock, flags);
+		ts->event_buf[ts->nextIn++] = event;
+		if (ts->nextIn == EVENT_BUFSIZE)
+			ts->nextIn = 0;
+		if (ts->event_count < EVENT_BUFSIZE) {
+			ts->event_count++;
+		} else {
+			// throw out the oldest event
+			if (++ts->nextOut == EVENT_BUFSIZE)
+				ts->nextOut = 0;
+		}
+		spin_unlock_irqrestore(&ts->lock, flags);
+
+		// async notify
+		if (ts->fasync)
+			kill_fasync(&ts->fasync, SIGIO, POLL_IN);
+		// wake up any read call
+		if (waitqueue_active(&ts->wait))
+			wake_up_interruptible(&ts->wait);
+	}
+}
+
+
+/*
+ * Raw X,Y,pressure acquisition timer function. This triggers
+ * the start of a new acquisition. Its duration between calls
+ * is the touch screen polling rate.
+ */
+static void
+au1000_acq_timer(unsigned long data)
+{
+	au1000_ts_t* ts = (au1000_ts_t*)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ts->lock, flags);
+
+	// start acquisition with X coordinate
+	ts->acq_state = ACQ_X;
+	// start me up
+	outl(SSIADAT_D | (MEASURE_12BIT_X << SSIADAT_ADDR_BIT), SSI0_ADATA);
+
+	// schedule next acquire
+	ts->acq_timer.expires = jiffies + HZ / 100;
+	add_timer(&ts->acq_timer);
+
+	spin_unlock_irqrestore(&ts->lock, flags);
+}
+
+static void
+ssi0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	au1000_ts_t *ts = (au1000_ts_t*)dev_id;
+	u32 stat, int_stat, data;
+
+	spin_lock(&ts->lock);
+
+	stat = inl(SSI0_STATUS);
+	// clear sticky status bits
+	outl(stat & (SSISTAT_OF|SSISTAT_UF|SSISTAT_DONE), SSI0_STATUS);
+
+	int_stat = inl(SSI0_INT);
+	// clear sticky intr status bits
+	outl(int_stat & (SSIINT_OI|SSIINT_UI|SSIINT_DI), SSI0_INT);
+
+	if ((int_stat & (SSIINT_OI|SSIINT_UI|SSIINT_DI)) != SSIINT_DI) {
+		if (int_stat & SSIINT_OI)
+			err("overflow");
+		if (int_stat & SSIINT_UI)
+			err("underflow");
+		spin_unlock(&ts->lock);
+		return;
+	}
+
+	data = inl(SSI0_ADATA) & SSIADAT_DATA_MASK;
+
+	switch (ts->acq_state) {
+	case IDLE:
+		break;
+	case ACQ_X:
+		ts->x_raw = data;
+		ts->acq_state = ACQ_Y;
+		// trigger Y acq
+		outl(SSIADAT_D | (MEASURE_12BIT_Y << SSIADAT_ADDR_BIT),
+		     SSI0_ADATA);
+		break;
+	case ACQ_Y:
+		ts->y_raw = data;
+		ts->acq_state = ACQ_Z1;
+		// trigger Z1 acq
+		outl(SSIADAT_D | (MEASURE_12BIT_Z1 << SSIADAT_ADDR_BIT),
+		     SSI0_ADATA);
+		break;
+	case ACQ_Z1:
+		ts->z1_raw = data;
+		if (ts->pressure_eqn == PRESSURE_EQN_2) {
+			// don't acq Z2, using 2nd eqn for touch pressure
+			ts->acq_state = IDLE;
+			// got the raw stuff, now mark BH
+			queue_task(&ts->chug_tq, &tq_immediate);
+			mark_bh(IMMEDIATE_BH);
+		} else {
+			ts->acq_state = ACQ_Z2;
+			// trigger Z2 acq
+			outl(SSIADAT_D | (MEASURE_12BIT_Z2<<SSIADAT_ADDR_BIT),
+			     SSI0_ADATA);
+		}
+		break;
+	case ACQ_Z2:
+		ts->z2_raw = data;
+		ts->acq_state = IDLE;
+		// got the raw stuff, now mark BH
+		queue_task(&ts->chug_tq, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+		break;
+	}
+
+	spin_unlock(&ts->lock);
+}
+
+
+/* +++++++++++++ File operations ++++++++++++++*/
+
+static int
+au1000_fasync(int fd, struct file *filp, int mode)
+{
+	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
+	return fasync_helper(fd, filp, mode, &ts->fasync);
+}
+
+static int
+au1000_ioctl(struct inode * inode, struct file *filp,
+	     unsigned int cmd, unsigned long arg)
+{
+	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
+
+	switch(cmd) {
+	case TS_GET_RATE:       /* TODO: what is this? */
+		break;
+	case TS_SET_RATE:       /* TODO: what is this? */
+		break;
+	case TS_GET_CAL:
+		copy_to_user((char *)arg, (char *)&ts->cal, sizeof(TS_CAL));
+		break;
+	case TS_SET_CAL:
+		copy_from_user((char *)&ts->cal, (char *)arg, sizeof(TS_CAL));
+		break;
+	default:
+		err("unknown cmd %04x", cmd);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned int
+au1000_poll(struct file * filp, poll_table * wait)
+{
+	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
+	poll_wait(filp, &ts->wait, wait);
+	if (ts->event_count)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static ssize_t
+au1000_read(struct file * filp, char * buf, size_t count, loff_t * l)
+{
+	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
+	unsigned long flags;
+	TS_EVENT event;
+	int i;
+
+	if (ts->event_count == 0) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		interruptible_sleep_on(&ts->wait);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+	}
+
+	for (i = count;
+	     i >= sizeof(TS_EVENT);
+	     i -= sizeof(TS_EVENT), buf += sizeof(TS_EVENT)) {
+		if (ts->event_count == 0)
+			break;
+		spin_lock_irqsave(&ts->lock, flags);
+		event = ts->event_buf[ts->nextOut++];
+		if (ts->nextOut == EVENT_BUFSIZE)
+			ts->nextOut = 0;
+		if (ts->event_count)
+			ts->event_count--;
+		spin_unlock_irqrestore(&ts->lock, flags);
+		copy_to_user(buf, &event, sizeof(TS_EVENT));
+	}
+
+	return count - i;
+}
+
+
+static int
+au1000_open(struct inode * inode, struct file * filp)
+{
+	au1000_ts_t* ts;
+	unsigned long flags;
+
+	filp->private_data = ts = &au1000_ts;
+
+	spin_lock_irqsave(&ts->lock, flags);
+
+	// setup SSI0 config
+	outl(DEFAULT_SSI_CONFIG, SSI0_CONFIG);
+
+	// clear out SSI0 status bits
+	outl(SSISTAT_OF|SSISTAT_UF|SSISTAT_DONE, SSI0_STATUS);
+	// clear out SSI0 interrupt pending bits
+	outl(SSIINT_OI|SSIINT_UI|SSIINT_DI, SSI0_INT);
+
+	// enable SSI0 interrupts
+	outl(SSIINT_OI|SSIINT_UI|SSIINT_DI, SSI0_INT_ENABLE);
+
+	/*
+	 * init bh handler that chugs the raw data (calibrates and
+	 * calculates touch pressure).
+	 */
+	ts->chug_tq.routine = chug_raw_data;
+	ts->chug_tq.data = ts;
+	ts->pendown = 0; // pen up
+	
+	// flush event queue
+	ts->nextIn = ts->nextOut = ts->event_count = 0;
+	
+	// Start acquisition timer function
+	init_timer(&ts->acq_timer);
+	ts->acq_timer.function = au1000_acq_timer;
+	ts->acq_timer.data = (unsigned long)ts;
+	ts->acq_timer.expires = jiffies + HZ / 100;
+	add_timer(&ts->acq_timer);
+
+	spin_unlock_irqrestore(&ts->lock, flags);
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int
+au1000_release(struct inode * inode, struct file * filp)
+{
+	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
+	unsigned long flags;
+	
+	au1000_fasync(-1, filp, 0);
+	del_timer_sync(&ts->acq_timer);
+
+	spin_lock_irqsave(&ts->lock, flags);
+	// disable SSI0 interrupts
+	outl(0, SSI0_INT_ENABLE);
+	spin_unlock_irqrestore(&ts->lock, flags);
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+
+static struct file_operations ts_fops = {
+	read:           au1000_read,
+	poll:           au1000_poll,
+	ioctl:		au1000_ioctl,
+	fasync:         au1000_fasync,
+	open:		au1000_open,
+	release:	au1000_release,
+};
+
+/* +++++++++++++ End File operations ++++++++++++++*/
+
+
+int __init
+au1000ts_init_module(void)
+{
+	au1000_ts_t* ts = &au1000_ts;
+	int ret;
+
+	/* register our character device */
+	if ((ret = register_chrdev(TS_MAJOR, TS_NAME, &ts_fops)) < 0) {
+		err("can't get major number");
+		return ret;
+	}
+	info("registered");
+
+	memset(ts, 0, sizeof(au1000_ts_t));
+	init_waitqueue_head(&ts->wait);
+	spin_lock_init(&ts->lock);
+
+	if (!request_region(virt_to_phys((void*)SSI0_STATUS), 0x100, TS_NAME)) {
+		err("SSI0 ports in use");
+		return -ENXIO;
+	}
+
+	if ((ret = request_irq(AU1000_SSI0_INT, ssi0_interrupt,
+			       SA_SHIRQ | SA_INTERRUPT, TS_NAME, ts))) {
+		err("could not get IRQ");
+		return ret;
+	}
+
+	// initial calibration values
+	ts->cal.xscale = -93;
+	ts->cal.xtrans = 346;
+	ts->cal.yscale = -64;
+	ts->cal.ytrans = 251;
+
+	// init pen up/down hysteresis points
+	ts->pendown_thresh_ohms = DEFAULT_PENDOWN_THRESH_OHMS;
+	ts->penup_thresh_ohms = DEFAULT_PENUP_THRESH_OHMS;
+	ts->pressure_eqn = PRESSURE_EQN_2;
+	// init X and Y plate resistances
+	ts->x_plate_ohms = DEFAULT_X_PLATE_OHMS;
+	ts->y_plate_ohms = DEFAULT_Y_PLATE_OHMS;
+
+	// set GPIO to SSI0 function
+	outl(inl(PIN_FUNCTION) & ~1, PIN_FUNCTION);
+	
+	// enable SSI0 clock and bring SSI0 out of reset
+	outl(0, SSI0_CONTROL);
+	udelay(1000);
+	outl(SSIEN_E, SSI0_CONTROL);
+	udelay(100);
+	
+	// FIXME: is this a working baudrate?
+	ts->clkdiv = 0;
+	ts->baudrate = calc_baudrate(ts->clkdiv);
+	outl(ts->clkdiv, SSI0_CLKDIV);
+
+	info("baudrate = %d Hz", ts->baudrate);
+	
+	return 0;
+}
+
+void
+au1000ts_cleanup_module(void)
+{
+	// disable clocks and hold in reset
+	outl(SSIEN_CD, SSI0_CONTROL);
+	free_irq(AU1000_SSI0_INT, &au1000_ts);
+	release_region(virt_to_phys((void*)SSI0_STATUS), 0x100);
+	unregister_chrdev(TS_MAJOR, TS_NAME);
+}
+
+/* Module information */
+MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com, www.mvista.com");
+MODULE_DESCRIPTION("Au1000/ADS7846 Touch Screen Driver");
+
+module_init(au1000ts_init_module);
+module_exit(au1000ts_cleanup_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/console.c linux/drivers/char/console.c
--- linux.orig/drivers/char/console.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/drivers/char/console.c	2002-07-20 01:08:31.000000000 +0000
@@ -2179,7 +2179,6 @@
 	name:		"tty",
 	write:		vt_console_print,
 	device:		vt_console_device,
-	wait_key:	keyboard_wait_for_keypress,
 	unblank:	unblank_screen,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/drm/drm_agpsupport.h linux/drivers/char/drm/drm_agpsupport.h
--- linux.orig/drivers/char/drm/drm_agpsupport.h	2001-11-22 19:46:37.000000000 +0000
+++ linux/drivers/char/drm/drm_agpsupport.h	2002-07-20 01:08:21.000000000 +0000
@@ -303,6 +303,7 @@
 		case ALI_M1631: 	head->chipset = "ALi M1631";	 break;
 		case ALI_M1632: 	head->chipset = "ALi M1632";	 break;
 		case ALI_M1641: 	head->chipset = "ALi M1641";	 break;
+		case ALI_M1644: 	head->chipset = "ALi M1644";	 break;
 		case ALI_M1647: 	head->chipset = "ALi M1647";	 break;
 		case ALI_M1651: 	head->chipset = "ALi M1651";	 break;
 #endif
@@ -316,6 +317,8 @@
 			break;
 #endif
 
+		case HP_ZX1:		head->chipset = "HP ZX1";	 break;
+
 		default:		head->chipset = "Unknown";       break;
 		}
 #if LINUX_VERSION_CODE <= 0x020408
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/drm/i810_dma.c linux/drivers/char/drm/i810_dma.c
--- linux.orig/drivers/char/drm/i810_dma.c	2001-08-08 16:42:15.000000000 +0000
+++ linux/drivers/char/drm/i810_dma.c	2002-07-20 01:08:32.000000000 +0000
@@ -286,22 +286,20 @@
 	if(address == 0UL)
 		return 0;
 
-	atomic_inc(&virt_to_page(address)->count);
-	set_bit(PG_locked, &virt_to_page(address)->flags);
+	get_page(virt_to_page(address));
+	LockPage(virt_to_page(address));
 
 	return address;
 }
 
 static void i810_free_page(drm_device_t *dev, unsigned long page)
 {
-	if(page == 0UL)
-		return;
-
-	atomic_dec(&virt_to_page(page)->count);
-	clear_bit(PG_locked, &virt_to_page(page)->flags);
-	wake_up(&virt_to_page(page)->wait);
-	free_page(page);
-	return;
+	if (page) {
+		struct page *p = virt_to_page(page);
+		put_page(p);
+		UnlockPage(p);
+		free_page(page);
+	}
 }
 
 static int i810_dma_cleanup(drm_device_t *dev)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/drm/radeon_state.c linux/drivers/char/drm/radeon_state.c
--- linux.orig/drivers/char/drm/radeon_state.c	2001-08-08 16:42:15.000000000 +0000
+++ linux/drivers/char/drm/radeon_state.c	2002-07-20 01:08:30.000000000 +0000
@@ -1058,7 +1058,7 @@
 			DRM_ERROR( "EFAULT on tex->image\n" );
 			return -EFAULT;
 		}
-	} else if ( size < 4 ) {
+	} else if ( size < 4 && size > 0 ) {
 		size = 4;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/drm/sis_ds.c linux/drivers/char/drm/sis_ds.c
--- linux.orig/drivers/char/drm/sis_ds.c	2001-12-21 17:41:53.000000000 +0000
+++ linux/drivers/char/drm/sis_ds.c	2002-07-20 01:08:29.000000000 +0000
@@ -33,7 +33,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/poll.h>
 #include <asm/io.h>
 #include <linux/pci.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/drm-4.0/i810_dma.c linux/drivers/char/drm-4.0/i810_dma.c
--- linux.orig/drivers/char/drm-4.0/i810_dma.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/drm-4.0/i810_dma.c	2002-07-20 01:08:38.000000000 +0000
@@ -280,20 +280,20 @@
 	if(address == 0UL) 
 		return 0;
 	
-	atomic_inc(&virt_to_page(address)->count);
-	set_bit(PG_locked, &virt_to_page(address)->flags);
+	get_page(virt_to_page(address));
+	LockPage(virt_to_page(address));
    
 	return address;
 }
 
 static void i810_free_page(drm_device_t *dev, unsigned long page)
 {
+	struct page * p = virt_to_page(page);
 	if(page == 0UL) 
 		return;
 	
-	atomic_dec(&virt_to_page(page)->count);
-	clear_bit(PG_locked, &virt_to_page(page)->flags);
-	wake_up(&virt_to_page(page)->wait);
+	put_page(p);
+	UnlockPage(p);
 	free_page(page);
 	return;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/dummy_keyb.c linux/drivers/char/dummy_keyb.c
--- linux.orig/drivers/char/dummy_keyb.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/dummy_keyb.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,60 @@
+/*
+ * linux/drivers/char/dummy_keyb.c
+ *
+ * Allows CONFIG_VT on hardware without keyboards.
+ *
+ * Copyright (C) 1999, 2001 Bradley D. LaRonde
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * What is this for?
+ *
+ * Not all systems have keyboards.  Some don't even have a keyboard
+ * port.  However, some of those systems have video support and can
+ * use the virtual terminal support for display.  However, the virtual
+ * terminal code expects a keyboard of some kind.  This driver keeps
+ * the virtual terminal code happy by providing it a "keyboard", albeit
+ * a very quiet one.
+ *
+ * If you want to use the virtual terminal support but your system
+ * does not support a keyboard, define CONFIG_DUMMY_KEYB along with
+ * CONFIG_VT.
+ *
+ */
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+void kbd_leds(unsigned char leds)
+{
+}
+
+int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+	return (scancode == keycode) ? 0 : -EINVAL;
+}
+
+int kbd_getkeycode(unsigned int scancode)
+{
+	return scancode;
+}
+
+int kbd_translate(unsigned char scancode, unsigned char *keycode,
+	char raw_mode)
+{
+	*keycode = scancode;
+
+	return 1;
+}
+
+char kbd_unexpected_up(unsigned char keycode)
+{
+	return 0x80;
+}
+
+void __init kbd_init_hw(void)
+{
+	printk("Dummy keyboard driver installed.\n");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/dz.c linux/drivers/char/dz.c
--- linux.orig/drivers/char/dz.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/drivers/char/dz.c	2002-07-20 01:08:25.000000000 +0000
@@ -14,41 +14,31 @@
  *    after patches by harald to irq code.  
  * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
  *            field from "current" - somewhere between 2.1.121 and 2.1.131
-Qua Jun 27 15:02:26 BRT 2001
+ Qua Jun 27 15:02:26 BRT 2001
  * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
  *  
  * Parts (C) 1999 David Airlie, airlied@linux.ie 
  * [07-SEP-99] Bugfixes 
  */
 
-/* #define DEBUG_DZ 1 */
-
-#include <linux/version.h>
-#include <linux/module.h>
+#define DEBUG_DZ 1
 
 #include <linux/config.h>
+#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/init.h> 
+#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/major.h>
+#include <linux/module.h>
 #include <linux/param.h>
 #include <linux/tqueue.h>
 #include <linux/interrupt.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
 #include <asm-mips/wbflush.h>
-#include <asm/dec/interrupts.h>			/* for definition of SERIAL */
+#include <asm/dec/interrupts.h>
 
-/* for definition of struct console */
-#ifdef CONFIG_SERIAL_CONSOLE
-#define CONSOLE_LINE (3)
-#endif /* ifdef CONFIG_SERIAL_CONSOLE */
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(DEBUG_DZ)
 #include <linux/console.h>
-#endif /* if defined(CONFIG_SERIAL_CONSOLE) || defined(DEBUG_DZ) */
-
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
@@ -59,15 +49,13 @@
 #include <asm/dec/kn01.h>
 #include <asm/dec/kn02.h>
 
-#ifdef DEBUG_DZ
 #include <linux/ptrace.h>
 #include <linux/fs.h>
 #include <asm/bootinfo.h>
 
-extern int (*prom_printf) (char *,...);
-#endif
-
+#define CONSOLE_LINE (3)	/* for definition of struct console */
 
+extern int (*prom_printf) (char *,...);
 
 #include "dz.h"
 
@@ -75,17 +63,14 @@
 
 DECLARE_TASK_QUEUE(tq_serial);
 
-extern wait_queue_head_t keypress_wait; 
 static struct dz_serial *lines[4];
 static unsigned char tmp_buffer[256];
 
-
-
 #ifdef DEBUG_DZ
 /*
  * debugging code to send out chars via prom 
  */
-static void debug_console( const char *s,int count)
+static void debug_console(const char *s, int count)
 {
 	unsigned i;
 
@@ -106,17 +91,19 @@
  * ------------------------------------------------------------
  */
 
-static inline unsigned short dz_in (struct dz_serial *info, unsigned offset)
+static inline unsigned short dz_in(struct dz_serial *info, unsigned offset)
 {
-	volatile u16 *addr = (volatile u16 *)(info->port + offset);
-
+	volatile unsigned short *addr =
+		(volatile unsigned short *) (info->port + offset);
 	return *addr;
 }
 
-static inline void dz_out (struct dz_serial *info, unsigned offset,
-                           unsigned short value)
+static inline void dz_out(struct dz_serial *info, unsigned offset,
+                          unsigned short value)
 {
-	volatile u16 *addr = (volatile u16 *)(info->port + offset);
+
+	volatile unsigned short *addr =
+		(volatile unsigned short *) (info->port + offset);
 	*addr = value;
 }
 
@@ -130,33 +117,34 @@
  * ------------------------------------------------------------
  */
 
-static void dz_stop (struct tty_struct *tty)
+static void dz_stop(struct tty_struct *tty)
 {
-	struct dz_serial *info; 
+	struct dz_serial *info;
 	unsigned short mask, tmp;
 
-	if (!tty) 
-		return; 
- 
-	info = (struct dz_serial *)tty->driver_data; 
+	if (tty == 0)
+		return;
+
+	info = (struct dz_serial *) tty->driver_data;
 
 	mask = 1 << info->line;
-	tmp = dz_in (info, DZ_TCR);       /* read the TX flag */
+	tmp = dz_in(info, DZ_TCR);	/* read the TX flag */
 
-	tmp &= ~mask;                   /* clear the TX flag */
-	dz_out (info, DZ_TCR, tmp);
+	tmp &= ~mask;		/* clear the TX flag */
+	dz_out(info, DZ_TCR, tmp);
 }
 
-static void dz_start (struct tty_struct *tty)
+static void dz_start(struct tty_struct *tty)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 	unsigned short mask, tmp;
 
 	mask = 1 << info->line;
-	tmp = dz_in (info, DZ_TCR);      /* read the TX flag */
+	tmp = dz_in(info, DZ_TCR);	/* read the TX flag */
+
+	tmp |= mask;		/* set the TX flag */
+	dz_out(info, DZ_TCR, tmp);
 
-	tmp |= mask;                   /* set the TX flag */
-	dz_out (info, DZ_TCR, tmp);
 }
 
 /*
@@ -187,7 +175,7 @@
  * processing in the software interrupt portion of the driver.
  * ------------------------------------------------------------
  */
-static inline void dz_sched_event (struct dz_serial *info, int event)
+static inline void dz_sched_event(struct dz_serial *info, int event)
 {
 	info->event |= 1 << event;
 	queue_task(&info->tqueue, &tq_serial);
@@ -201,8 +189,9 @@
  * This routine deals with inputs from any lines.
  * ------------------------------------------------------------
  */
-static inline void receive_chars (struct dz_serial *info_in)
+static inline void receive_chars(struct dz_serial *info_in)
 {
+
 	struct dz_serial *info;
 	struct tty_struct *tty = 0;
 	struct async_icount *icount;
@@ -210,26 +199,25 @@
 	unsigned short status, tmp;
 	unsigned char ch;
 
-	/*
-	 * This code is going to be a problem...  the call to tty_flip_buffer
-	 * is going to need to be rethought...
+	/* this code is going to be a problem...
+	   the call to tty_flip_buffer is going to need
+	   to be rethought...
 	 */
 	do {
-		status = dz_in (info_in, DZ_RBUF);
+		status = dz_in(info_in, DZ_RBUF);
 		info = lines[LINE(status)];
 
 		/* punt so we don't get duplicate characters */
 		if (!(status & DZ_DVAL))
 			goto ignore_char;
 
-		ch = UCHAR(status);			/* grab the char */
+
+		ch = UCHAR(status);	/* grab the char */
 
 #if 0
 		if (info->is_console) {
 			if (ch == 0)
-				return;			/* it's a break ... */
-
-			wake_up (&keypress_wait);       /* It is a 'keyboard interrupt' ;-) */
+				return;		/* it's a break ... */
 		}
 #endif
 
@@ -238,7 +226,8 @@
 
 		if (!tty)
 			break;
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			break;
 
 		*tty->flip.char_buf_ptr = ch;
 		*tty->flip.flag_buf_ptr = 0;
@@ -246,16 +235,15 @@
 
 		/* keep track of the statistics */
 		if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
-			if (status & DZ_PERR)		/* parity error */
+			if (status & DZ_PERR)	/* parity error */
 				icount->parity++;
 			else if (status & DZ_FERR)	/* frame error */
 				icount->frame++;
-			if (status & DZ_OERR)		/* overrun error */
+			if (status & DZ_OERR)	/* overrun error */
 				icount->overrun++;
 
-			/*
-			 * Check to see if we should ignore the character and
-			 * mask off conditions that should be ignored
+			/*  check to see if we should ignore the character
+			   and mask off conditions that should be ignored
 			 */
 
 			if (status & info->ignore_status_mask) {
@@ -263,24 +251,18 @@
 					break;
 				goto ignore_char;
 			}
-
 			/* mask off the error conditions we want to ignore */
 			tmp = status & info->read_status_mask;
 
 			if (tmp & DZ_PERR) {
 				*tty->flip.flag_buf_ptr = TTY_PARITY;
-#ifdef DEBUG_DZ
-				debug_console("PERR\n",5);
-#endif /* DEBUG_DZ */
+				debug_console("PERR\n", 5);
 			} else if (tmp & DZ_FERR) {
 				*tty->flip.flag_buf_ptr = TTY_FRAME;
-#ifdef DEBUG_DZ
-				debug_console("FERR\n",5);
-#endif /* DEBUG_DZ */
-			} if (tmp & DZ_OERR) { 
-#ifdef DEBUG_DZ
-				debug_console("OERR\n",5);
-#endif /* DEBUG_DZ */
+				debug_console("FERR\n", 5);
+			}
+			if (tmp & DZ_OERR) {
+				debug_console("OERR\n", 5);
 				if (tty->flip.count < TTY_FLIPBUF_SIZE) {
 					tty->flip.count++;
 					tty->flip.flag_buf_ptr++;
@@ -289,11 +271,10 @@
 				}
 			}
 		}
-	tty->flip.flag_buf_ptr++;
-	tty->flip.char_buf_ptr++;
-	tty->flip.count++;
-ignore_char:
-	;
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		tty->flip.count++;
+	      ignore_char:
 	} while (status & DZ_DVAL);
 
 	if (tty)
@@ -307,26 +288,25 @@
  * This routine deals with outputs to any lines.
  * ------------------------------------------------------------
  */
-static inline void transmit_chars (struct dz_serial *info)
+static inline void transmit_chars(struct dz_serial *info)
 {
 	unsigned char tmp;
 
-	if (info->x_char) {           /* XON/XOFF chars */
+
+
+	if (info->x_char) {	/* XON/XOFF chars */
 		dz_out(info, DZ_TDR, info->x_char);
 		info->icount.tx++;
 		info->x_char = 0;
 		return;
 	}
-
 	/* if nothing to do or stopped or hardware stopped */
-	if ((info->xmit_cnt <= 0) || info->tty->stopped ||
-	    info->tty->hw_stopped) {
+	if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped) {
 		dz_stop(info->tty);
 		return;
 	}
-
 	/*
-	 * If something to do ... (rember the dz has no output fifo so we go
+	 * if something to do ... (rember the dz has no output fifo so we go
 	 * one char at a time :-<
 	 */
 	tmp = (unsigned short) info->xmit_buf[info->xmit_tail++];
@@ -335,7 +315,8 @@
 	info->icount.tx++;
 
 	if (--info->xmit_cnt < WAKEUP_CHARS)
-	dz_sched_event(info, DZ_EVENT_WRITE_WAKEUP);
+		dz_sched_event(info, DZ_EVENT_WRITE_WAKEUP);
+
 
 	/* Are we done */
 	if (info->xmit_cnt <= 0)
@@ -349,7 +330,7 @@
  * Only valid for the MODEM line duh !
  * ------------------------------------------------------------
  */
-static inline void check_modem_status (struct dz_serial *info)
+static inline void check_modem_status(struct dz_serial *info)
 {
 	unsigned short status;
 
@@ -358,7 +339,7 @@
 		return;
 
 	status = dz_in(info, DZ_MSR);
-  
+
 	/* it's easy, since DSR2 is the only bit in the register */
 	if (status)
 		info->icount.dsr++;
@@ -372,20 +353,20 @@
  * It deals with the multiple ports.
  * ------------------------------------------------------------
  */
-static void dz_interrupt (int irq, void *dev, struct pt_regs *regs)
+static void dz_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
 	struct dz_serial *info;
 	unsigned short status;
 
-	 /* get the reason why we just got an irq */
-	status = dz_in((struct dz_serial *)dev, DZ_CSR);
-	info = lines[LINE(status)];     /* re-arrange info the proper port */
+	/* get the reason why we just got an irq */
+	status = dz_in((struct dz_serial *) dev, DZ_CSR);
+	info = lines[LINE(status)];	/* re-arrange info the proper port */
 
-	if (status & DZ_RDONE) 
+	if (status & DZ_RDONE)
 		receive_chars(info);	/* the receive function */
 
-	if (status & DZ_TRDY) 
-		transmit_chars (info);
+	if (status & DZ_TRDY)
+		transmit_chars(info);
 }
 
 /*
@@ -403,12 +384,12 @@
  * interrupt driver proper are done; the interrupt driver schedules
  * them using rs_sched_event(), and they get done here.
  */
-static void do_serial_bh (void)
+static void do_serial_bh(void)
 {
-	run_task_queue (&tq_serial);
+	run_task_queue(&tq_serial);
 }
 
-static void do_softint (void *private_data)
+static void do_softint(void *private_data)
 {
 	struct dz_serial *info = (struct dz_serial *) private_data;
 	struct tty_struct *tty = info->tty;
@@ -417,10 +398,9 @@
 		return;
 
 	if (test_and_clear_bit(DZ_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
 			(tty->ldisc.write_wakeup) (tty);
-		wake_up_interruptible (&tty->write_wait);
+		wake_up_interruptible(&tty->write_wait);
 	}
 }
 
@@ -434,11 +414,11 @@
  *      do_serial_hangup() -> tty->hangup() -> rs_hangup()
  * ------------------------------------------------------------------- 
  */
-static void do_serial_hangup (void *private_data)
+static void do_serial_hangup(void *private_data)
 {
 	struct dz_serial *info = (struct dz_serial *) private_data;
 	struct tty_struct *tty = info->tty;;
-        
+
 	if (!tty)
 		return;
 
@@ -452,31 +432,31 @@
  * various initialization tasks
  * ------------------------------------------------------------------- 
  */
-static int startup (struct dz_serial *info)
+static int startup(struct dz_serial *info)
 {
 	unsigned long page, flags;
 	unsigned short tmp;
 
 	if (info->is_initialized)
 		return 0;
-  
-	save_and_cli(flags);
+
+	save_flags(flags);
+	cli();
 
 	if (!info->port) {
-		if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
 		restore_flags(flags);
 		return -ENODEV;
 	}
-
 	if (!info->xmit_buf) {
 		page = get_free_page(GFP_KERNEL);
 		if (!page) {
-			restore_flags (flags);
-		return -ENOMEM;
+			restore_flags(flags);
+			return -ENOMEM;
 		}
-		info->xmit_buf = (unsigned char *)page;
+		info->xmit_buf = (unsigned char *) page;
 	}
-
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
 
@@ -487,18 +467,24 @@
 
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 
-	change_speed(info);			/* set up the speed */
+	/* set up the speed */
+	change_speed(info);
 
-	/*
-	 * Clear the line transmitter buffer I can't figure out why I need to
-	 * do this - but its necessary - in order for the console portion and
-	 * the interrupt portion to live happily side by side.
+	/* clear the line transmitter buffer 
+	   I can't figure out why I need to do this - but
+	   its necessary - in order for the console portion
+	   and the interrupt portion to live happily side by side.
+	 */
+
+	/* clear the line transmitter buffer 
+	   I can't figure out why I need to do this - but
+	   its necessary - in order for the console portion
+	   and the interrupt portion to live happily side by side.
 	 */
 
 	info->is_initialized = 1;
 
 	restore_flags(flags);
-
 	return 0;
 }
 
@@ -510,7 +496,7 @@
  * DTR is dropped if the hangup on close termio flag is on.
  * ------------------------------------------------------------------- 
  */
-static void shutdown (struct dz_serial *info)
+static void shutdown(struct dz_serial *info)
 {
 	unsigned long flags;
 	unsigned short tmp;
@@ -518,18 +504,20 @@
 	if (!info->is_initialized)
 		return;
 
-	save_and_cli(flags);
+	save_flags(flags);
+	cli();
+
+	dz_stop(info->tty);
+
 
-	dz_stop (info->tty);
 
 	info->cflags &= ~DZ_CREAD;	/* turn off receive enable flag */
 	dz_out(info, DZ_LPR, info->cflags);
 
-	if (info->xmit_buf) {               /* free Tx buffer */
-		free_page((unsigned long)info->xmit_buf);
+	if (info->xmit_buf) {	/* free Tx buffer */
+		free_page((unsigned long) info->xmit_buf);
 		info->xmit_buf = 0;
 	}
-
 	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
 		tmp = dz_in(info, DZ_TCR);
 		if (tmp & DZ_MODEM_DTR) {
@@ -537,13 +525,11 @@
 			dz_out(info, DZ_TCR, tmp);
 		}
 	}
-
 	if (info->tty)
-		set_bit (TTY_IO_ERROR, &info->tty->flags);
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
 	info->is_initialized = 0;
-
-	restore_flags (flags);
+	restore_flags(flags);
 }
 
 /* 
@@ -553,7 +539,7 @@
  * set the baud rate.
  * ------------------------------------------------------------------- 
  */
-static void change_speed (struct dz_serial *info)
+static void change_speed(struct dz_serial *info)
 {
 	unsigned long flags;
 	unsigned cflag;
@@ -561,26 +547,27 @@
 
 	if (!info->tty || !info->tty->termios)
 		return;
-  
-	save_and_cli(flags);
-  
+
+	save_flags(flags);
+	cli();
+
 	info->cflags = info->line;
 
 	cflag = info->tty->termios->c_cflag;
 
 	switch (cflag & CSIZE) {
-		case CS5:
-			info->cflags |= DZ_CS5;
-			break;
-		case CS6:
-			info->cflags |= DZ_CS6;
-			break;
-		case CS7:
-			info->cflags |= DZ_CS7;
-			break;
-		case CS8: 
-		default:
-			info->cflags |= DZ_CS8;
+	case CS5:
+		info->cflags |= DZ_CS5;
+		break;
+	case CS6:
+		info->cflags |= DZ_CS6;
+		break;
+	case CS7:
+		info->cflags |= DZ_CS7;
+		break;
+	case CS8:
+	default:
+		info->cflags |= DZ_CS8;
 	}
 
 	if (cflag & CSTOPB)
@@ -589,7 +576,7 @@
 		info->cflags |= DZ_PARENB;
 	if (cflag & PARODD)
 		info->cflags |= DZ_PARODD;
-  
+
 	baud = tty_get_baud_rate(info->tty);
 	switch (baud) {
 	case 50:
@@ -603,19 +590,19 @@
 		break;
 	case 134:
 		info->cflags |= DZ_B134;
-		break; 
+		break;
 	case 150:
 		info->cflags |= DZ_B150;
 		break;
 	case 300:
 		info->cflags |= DZ_B300;
-		break; 
+		break;
 	case 600:
 		info->cflags |= DZ_B600;
 		break;
 	case 1200:
 		info->cflags |= DZ_B1200;
-		break; 
+		break;
 	case 1800:
 		info->cflags |= DZ_B1800;
 		break;
@@ -627,16 +614,16 @@
 		break;
 	case 3600:
 		info->cflags |= DZ_B3600;
-		break; 
+		break;
 	case 4800:
 		info->cflags |= DZ_B4800;
 		break;
 	case 7200:
 		info->cflags |= DZ_B7200;
-		break; 
-	case 9600: 
+		break;
+	case 9600:
 	default:
-		info->cflags |= DZ_B9600; 
+		info->cflags |= DZ_B9600;
 	}
 
 	info->cflags |= DZ_RXENAB;
@@ -645,8 +632,8 @@
 	/* setup accept flag */
 	info->read_status_mask = DZ_OERR;
 	if (I_INPCK(info->tty))
-		info->read_status_mask |= (DZ_FERR | DZ_PERR); 
-  
+		info->read_status_mask |= (DZ_FERR | DZ_PERR);
+
 	/* characters to ignore */
 	info->ignore_status_mask = 0;
 	if (I_IGNPAR(info->tty))
@@ -662,17 +649,19 @@
  * Flush the buffer.
  * ------------------------------------------------------------------- 
  */
-static void dz_flush_chars (struct tty_struct *tty)
+static void dz_flush_chars(struct tty_struct *tty)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 	unsigned long flags;
 
-	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
-	    !info->xmit_buf)
+	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf)
 		return;
 
-	save_and_cli(flags);
-	dz_start (info->tty);
+	save_flags(flags);
+	cli();
+
+	dz_start(info->tty);
+
 	restore_flags(flags);
 }
 
@@ -684,64 +673,67 @@
  * main output routine.
  * ------------------------------------------------------------------- 
  */
-static int dz_write (struct tty_struct *tty, int from_user,
-                     const unsigned char *buf, int count)
+static int dz_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 	unsigned long flags;
 	int c, ret = 0;
 
-	if (!tty )
+	if (!tty)
 		return ret;
 	if (!info->xmit_buf)
 		return ret;
 	if (!tmp_buf)
 		tmp_buf = tmp_buffer;
 
+
+
 	if (from_user) {
-		down (&tmp_buf_sem);
+
+		down(&tmp_buf_sem);
 		while (1) {
-			c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
-			                   DZ_XMIT_SIZE - info->xmit_head));
+			c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
 			if (c <= 0)
 				break;
 
-			c -= copy_from_user (tmp_buf, buf, c);
+			c -= copy_from_user(tmp_buf, buf, c);
 			if (!c) {
 				if (!ret)
 					ret = -EFAULT;
 				break;
 			}
+			save_flags(flags);
+			cli();
 
-			save_and_cli(flags);
-
-			c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
-			               DZ_XMIT_SIZE - info->xmit_head));
+			c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
 			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
-			info->xmit_head = ((info->xmit_head + c) &
-					   (DZ_XMIT_SIZE - 1));
+			info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE - 1));
 			info->xmit_cnt += c;
+
 			restore_flags(flags);
 
 			buf += c;
 			count -= c;
 			ret += c;
 		}
+
 		up(&tmp_buf_sem);
 	} else {
+
+
 		while (1) {
-			save_and_cli(flags);
+			save_flags(flags);
+			cli();
 
-			c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
-			                   DZ_XMIT_SIZE - info->xmit_head));
+			c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
 			if (c <= 0) {
-				restore_flags (flags);
+				restore_flags(flags);
 				break;
 			}
 			memcpy(info->xmit_buf + info->xmit_head, buf, c);
-			info->xmit_head = ((info->xmit_head + c) &
-			                   (DZ_XMIT_SIZE-1));
+			info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE - 1));
 			info->xmit_cnt += c;
+
 			restore_flags(flags);
 
 			buf += c;
@@ -750,14 +742,14 @@
 		}
 	}
 
+
 	if (info->xmit_cnt) {
 		if (!tty->stopped) {
 			if (!tty->hw_stopped) {
-				dz_start (info->tty);
+				dz_start(info->tty);
 			}
 		}
 	}
-
 	return ret;
 }
 
@@ -768,15 +760,14 @@
  * compute the amount of space available for writing.
  * ------------------------------------------------------------------- 
  */
-static int dz_write_room (struct tty_struct *tty)
+static int dz_write_room(struct tty_struct *tty)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 	int ret;
 
 	ret = DZ_XMIT_SIZE - info->xmit_cnt - 1;
 	if (ret < 0)
 		ret = 0;
-
 	return ret;
 }
 
@@ -787,10 +778,10 @@
  * compute the amount of char left to be transmitted
  * ------------------------------------------------------------------- 
  */
-static int dz_chars_in_buffer (struct tty_struct *tty)
+static int dz_chars_in_buffer(struct tty_struct *tty)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
-  
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
+
 	return info->xmit_cnt;
 }
 
@@ -801,19 +792,18 @@
  * Empty the output buffer
  * ------------------------------------------------------------------- 
  */
-static void dz_flush_buffer (struct tty_struct *tty)
+static void dz_flush_buffer(struct tty_struct *tty)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
-                                
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
+
 	cli();
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	sti();
 
-	wake_up_interruptible (&tty->write_wait);
+	wake_up_interruptible(&tty->write_wait);
 
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	     tty->ldisc.write_wakeup)
-		tty->ldisc.write_wakeup(tty);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup) (tty);
 }
 
 /*
@@ -824,17 +814,17 @@
  * incoming characters should be throttled (or not).
  * ------------------------------------------------------------
  */
-static void dz_throttle (struct tty_struct *tty)
+static void dz_throttle(struct tty_struct *tty)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;  
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 
 	if (I_IXOFF(tty))
 		info->x_char = STOP_CHAR(tty);
 }
 
-static void dz_unthrottle (struct tty_struct *tty)
+static void dz_unthrottle(struct tty_struct *tty)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;  
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 
 	if (I_IXOFF(tty)) {
 		if (info->x_char)
@@ -844,9 +834,9 @@
 	}
 }
 
-static void dz_send_xchar (struct tty_struct *tty, char ch)
+static void dz_send_xchar(struct tty_struct *tty, char ch)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 
 	info->x_char = ch;
 
@@ -863,11 +853,11 @@
                            struct serial_struct *retinfo)
 {
 	struct serial_struct tmp;
-  
+
 	if (!retinfo)
 		return -EFAULT;
 
-	memset (&tmp, 0, sizeof(tmp));
+	memset(&tmp, 0, sizeof(tmp));
 
 	tmp.type = info->type;
 	tmp.line = info->line;
@@ -881,8 +871,8 @@
 	return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
 }
 
-static int set_serial_info (struct dz_serial *info,
-                            struct serial_struct *new_info)
+static int set_serial_info(struct dz_serial *info,
+                           struct serial_struct *new_info)
 {
 	struct serial_struct new_serial;
 	struct dz_serial old_info;
@@ -913,7 +903,6 @@
 	info->closing_wait = new_serial.closing_wait;
 
 	retval = startup(info);
-
 	return retval;
 }
 
@@ -927,17 +916,17 @@
  *          transmit holding register is empty.  This functionality
  *          allows an RS485 driver to be written in user space. 
  */
-static int get_lsr_info (struct dz_serial *info, unsigned int *value)
+static int get_lsr_info(struct dz_serial *info, unsigned int *value)
 {
-	unsigned short status = dz_in (info, DZ_LPR);
+	unsigned short status = dz_in(info, DZ_LPR);
 
-	return put_user (status, value);
+	return put_user(status, value);
 }
 
 /*
  * This routine sends a break character out the serial port.
  */
-static void send_break (struct dz_serial *info, int duration)
+static void send_break(struct dz_serial *info, int duration)
 {
 	unsigned long flags;
 	unsigned short tmp, mask;
@@ -946,33 +935,36 @@
 		return;
 
 	mask = 1 << info->line;
-	tmp = dz_in (info, DZ_TCR);
+	tmp = dz_in(info, DZ_TCR);
 	tmp |= mask;
 
 	current->state = TASK_INTERRUPTIBLE;
 
-	save_and_cli(flags);
+	save_flags(flags);
+	cli();
+
 	dz_out(info, DZ_TCR, tmp);
+
 	schedule_timeout(duration);
+
 	tmp &= ~mask;
 	dz_out(info, DZ_TCR, tmp);
+
 	restore_flags(flags);
 }
 
 static int dz_ioctl(struct tty_struct *tty, struct file *file,
-                    unsigned int cmd, unsigned long arg)
+		    unsigned int cmd, unsigned long arg)
 {
-	int error;
-	struct dz_serial * info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 	int retval;
 
-	if (cmd != TIOCGSERIAL && cmd != TIOCSSERIAL &&
-	    cmd != TIOCSERCONFIG && cmd != TIOCSERGWILD  &&
-	    cmd != TIOCSERSWILD && cmd != TIOCSERGSTRUCT) {
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
 		if (tty->flags & (1 << TTY_IO_ERROR))
 			return -EIO;
 	}
-
 	switch (cmd) {
 	case TCSBRK:		/* SVID version: non-zero arg --> no break */
 		retval = tty_check_change(tty);
@@ -980,7 +972,7 @@
 			return retval;
 		tty_wait_until_sent(tty, 0);
 		if (!arg)
-			send_break(info, HZ/4); /* 1/4 second */
+			send_break(info, HZ / 4);	/* 1/4 second */
 		return 0;
 
 	case TCSBRKP:		/* support for POSIX tcsendbreak() */
@@ -988,41 +980,32 @@
 		if (retval)
 			return retval;
 		tty_wait_until_sent(tty, 0);
-		send_break(info, arg ? arg*(HZ/10) : HZ/4);
+		send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
 		return 0;
 
 	case TIOCGSOFTCAR:
-		error = verify_area (VERIFY_WRITE, (void *)arg, sizeof(long));
-		if (error)
-			return error;
-		put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
-		return 0;
+		return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
 
 	case TIOCSSOFTCAR:
-		if (get_user (arg, (unsigned long *)arg))
+		if (get_user(arg, (unsigned long *) arg))
 			return -EFAULT;
-
-		tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) |
-		                        (arg ? CLOCAL : 0);
+		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
+		                         (arg ? CLOCAL : 0));
 		return 0;
 
 	case TIOCGSERIAL:
-		error = verify_area(VERIFY_WRITE, (void *)arg,
-		                    sizeof(struct serial_struct));
-		if (error)
-			return error;
-		return get_serial_info(info, (struct serial_struct *)arg);
+		return get_serial_info(info, (struct serial_struct *) arg);
 
 	case TIOCSSERIAL:
 		return set_serial_info(info, (struct serial_struct *) arg);
 
-	case TIOCSERGETLSR:		/* Get line status register */
-		return get_lsr_info (info, (unsigned int *)arg);
+	case TIOCSERGETLSR:	/* Get line status register */
+		return get_lsr_info(info, (unsigned int *) arg);
 
 	case TIOCSERGSTRUCT:
-		return copy_to_user((struct dz_serial *)arg, info,
-		                    sizeof(struct dz_serial)) ? -EFAULT : 0;
- 
+		return copy_to_user((struct dz_serial *) arg, info,
+				 sizeof(struct dz_serial)) ? -EFAULT : 0;
+
 	default:
 		return -ENOIOCTLCMD;
 	}
@@ -1030,15 +1013,15 @@
 	return 0;
 }
 
-static void dz_set_termios (struct tty_struct *tty,
-			    struct termios *old_termios)
+static void dz_set_termios(struct tty_struct *tty,
+			   struct termios *old_termios)
 {
-	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 
 	if (tty->termios->c_cflag == old_termios->c_cflag)
 		return;
 
-	change_speed (info);
+	change_speed(info);
 
 	if ((old_termios->c_cflag & CRTSCTS) &&
 	    !(tty->termios->c_cflag & CRTSCTS)) {
@@ -1058,37 +1041,36 @@
  */
 static void dz_close(struct tty_struct *tty, struct file *filp)
 {
-	struct dz_serial * info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
 	unsigned long flags;
 
 	if (!info)
 		return;
- 
-	save_and_cli(flags); 
+
+	save_flags(flags);
+	cli();
 
 	if (tty_hung_up_p(filp)) {
 		restore_flags(flags);
 		return;
 	}
-
 	if ((tty->count == 1) && (info->count != 1)) {
 		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty structure
-		 * will be freed.  Info->count should always be one in these
-		 * conditions.  If it's greater than one, we've got real
-		 * problems, since it means the serial port won't be shutdown.
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
 		 */
 		printk("dz_close: bad serial port count; tty->count is 1, "
 		       "info->count is %d\n", info->count);
 		info->count = 1;
 	}
-
 	if (--info->count < 0) {
 		printk("ds_close: bad serial port count for ttyS%02d: %d\n",
 		       info->line, info->count);
 		info->count = 0;
 	}
-
 	if (info->count) {
 		restore_flags(flags);
 		return;
@@ -1103,8 +1085,8 @@
 	if (info->flags & DZ_CALLOUT_ACTIVE)
 		info->callout_termios = *tty->termios;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify the line
-	 * discipline to only process XON/XOFF characters.
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
 
@@ -1112,26 +1094,27 @@
 		tty_wait_until_sent(tty, info->closing_wait);
 
 	/*
-	 * At this point we stop accepting input.  To do this, we disable the
-	 * receive line status interrupts.
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts.
 	 */
+
 	shutdown(info);
 
 	if (tty->driver.flush_buffer)
-		tty->driver.flush_buffer (tty);
+		tty->driver.flush_buffer(tty);
 	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer (tty);
+		tty->ldisc.flush_buffer(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
 
 	if (tty->ldisc.num != ldiscs[N_TTY].num) {
 		if (tty->ldisc.close)
-			tty->ldisc.close(tty);
+			(tty->ldisc.close) (tty);
 		tty->ldisc = ldiscs[N_TTY];
 		tty->termios->c_line = N_TTY;
 		if (tty->ldisc.open)
-			tty->ldisc.open(tty);
+			(tty->ldisc.open) (tty);
 	}
 	if (info->blocked_open) {
 		if (info->close_delay) {
@@ -1140,7 +1123,6 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-
 	info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 
@@ -1150,10 +1132,10 @@
 /*
  * dz_hangup () --- called by tty_hangup() when a hangup is signaled.
  */
-static void dz_hangup (struct tty_struct *tty)
+static void dz_hangup(struct tty_struct *tty)
 {
 	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
-  
+
 	dz_flush_buffer(tty);
 	shutdown(info);
 	info->event = 0;
@@ -1168,10 +1150,9 @@
  * rs_open() and friends
  * ------------------------------------------------------------
  */
-static int block_til_ready(struct tty_struct *tty, struct file *filp,
-                           struct dz_serial *info)
+static int block_til_ready(struct tty_struct *tty, struct file *filp, struct dz_serial *info)
 {
-	DECLARE_WAITQUEUE(wait, current); 
+	DECLARE_WAITQUEUE(wait, current);
 	int retval;
 	int do_clocal = 0;
 
@@ -1183,7 +1164,6 @@
 		interruptible_sleep_on(&info->close_wait);
 		return -EAGAIN;
 	}
-
 	/*
 	 * If this is a callout device, then just make sure the normal
 	 * device isn't being used.
@@ -1191,47 +1171,44 @@
 	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
 		if (info->flags & DZ_NORMAL_ACTIVE)
 			return -EBUSY;
-    
+
 		if ((info->flags & DZ_CALLOUT_ACTIVE) &&
 		    (info->flags & DZ_SESSION_LOCKOUT) &&
 		    (info->session != current->session))
 			return -EBUSY;
-    
+
 		if ((info->flags & DZ_CALLOUT_ACTIVE) &&
 		    (info->flags & DZ_PGRP_LOCKOUT) &&
 		    (info->pgrp != current->pgrp))
 			return -EBUSY;
-
 		info->flags |= DZ_CALLOUT_ACTIVE;
 		return 0;
 	}
-
 	/*
-	 * If non-blocking mode is set, or the port is not enabled, then make
-	 * the check up front and then exit.
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
 		if (info->flags & DZ_CALLOUT_ACTIVE)
 			return -EBUSY;
 		info->flags |= DZ_NORMAL_ACTIVE;
-
 		return 0;
 	}
-
 	if (info->flags & DZ_CALLOUT_ACTIVE) {
 		if (info->normal_termios.c_cflag & CLOCAL)
 			do_clocal = 1;
 	} else {
 		if (tty->termios->c_cflag & CLOCAL)
-		do_clocal = 1;
+			do_clocal = 1;
 	}
 
 	/*
-	 * Block waiting for the carrier detect and the line to become free
-	 * (i.e., not in use by the callout).  While we are in this loop,
-	 * info->count is dropped by one, so that dz_close() knows when to free
-	 * things.  We restore it upon exit, either normal or abnormal.
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * dz_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
 	 */
 	retval = 0;
 	add_wait_queue(&info->open_wait, &wait);
@@ -1240,7 +1217,7 @@
 	info->blocked_open++;
 	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p (filp) || !(info->is_initialized)) {
+		if (tty_hung_up_p(filp) || !(info->is_initialized)) {
 			retval = -EAGAIN;
 			break;
 		}
@@ -1253,9 +1230,9 @@
 		}
 		schedule();
 	}
-		
+
 	current->state = TASK_RUNNING;
-	remove_wait_queue (&info->open_wait, &wait);
+	remove_wait_queue(&info->open_wait, &wait);
 	if (!tty_hung_up_p(filp))
 		info->count++;
 	info->blocked_open--;
@@ -1271,16 +1248,15 @@
  * enables interrupts for a serial port. It also performs the 
  * serial-specific initialization for the tty structure.
  */
-static int dz_open (struct tty_struct *tty, struct file *filp)
+static int dz_open(struct tty_struct *tty, struct file *filp)
 {
 	struct dz_serial *info;
 	int retval, line;
 
 	line = MINOR(tty->device) - tty->driver.minor_start;
 
-	/*
-	 * The dz lines for the mouse/keyboard must be opened using their
-	 * respective drivers.
+	/* The dz lines for the mouse/keyboard must be
+	 * opened using their respective drivers.
 	 */
 	if ((line < 0) || (line >= DZ_NB_PORT))
 		return -ENODEV;
@@ -1297,37 +1273,36 @@
 	/*
 	 * Start up serial port
 	 */
-	retval = startup (info);
+	retval = startup(info);
 	if (retval)
 		return retval;
 
-	retval = block_til_ready (tty, filp, info);
+	retval = block_til_ready(tty, filp, info);
 	if (retval)
 		return retval;
 
 	if ((info->count == 1) && (info->flags & DZ_SPLIT_TERMIOS)) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
 			*tty->termios = info->normal_termios;
-		else 
+		else
 			*tty->termios = info->callout_termios;
 		change_speed(info);
-	}
 
+	}
 	info->session = current->session;
 	info->pgrp = current->pgrp;
-
 	return 0;
 }
 
-static void show_serial_version (void)
+static void show_serial_version(void)
 {
 	printk("%s%s\n", dz_name, dz_version);
 }
 
-
 int __init dz_init(void)
 {
-	int i, flags;
+	int i, tmp;
+	long flags;
 	struct dz_serial *info;
 
 	/* Setup base handler, and timer table. */
@@ -1374,8 +1349,8 @@
 	serial_driver.hangup = dz_hangup;
 
 	/*
-	 * The callout device is just like normal device except for major
-	 * number and the subtype code.
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
 	 */
 	callout_driver = serial_driver;
 #if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
@@ -1386,21 +1361,22 @@
 	callout_driver.major = TTYAUX_MAJOR;
 	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
-	if (tty_register_driver (&serial_driver))
-		panic("Couldn't register serial driver\n");
-	if (tty_register_driver (&callout_driver))
-		panic("Couldn't register callout driver\n");
-
-	save_flags(flags); cli();
-	for (i=0; i < DZ_NB_PORT;  i++) {
-		info = &multi[i]; 
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver");
+	save_flags(flags);
+	cli();
+
+	for (i = 0; i < DZ_NB_PORT; i++) {
+		info = &multi[i];
 		lines[i] = info;
 		info->magic = SERIAL_MAGIC;
 
-		if ((mips_machtype == MACH_DS23100) ||
-		    (mips_machtype == MACH_DS5100)) 
+		if (mips_machtype == MACH_DS23100 ||
+		    mips_machtype == MACH_DS5100)
 			info->port = (unsigned long) KN01_DZ11_BASE;
-		else 
+		else
 			info->port = (unsigned long) KN02_DZ11_BASE;
 
 		info->line = i;
@@ -1417,76 +1393,71 @@
 		info->tqueue_hangup.data = info;
 		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
-		init_waitqueue_head(&info->open_wait); 
-		init_waitqueue_head(&info->close_wait); 
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
 
 		/*
 		 * If we are pointing to address zero then punt - not correctly
 		 * set up in setup.c to handle this.
 		 */
-		if (! info->port)
+		if (!info->port)
 			return 0;
 
 		printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line,
 		       info->port, SERIAL);
 
 		tty_register_devfs(&serial_driver, 0,
-		                   serial_driver.minor_start + info->line);
+				 serial_driver.minor_start + info->line);
 		tty_register_devfs(&callout_driver, 0,
-		                   callout_driver.minor_start + info->line);
+				callout_driver.minor_start + info->line);
 	}
 
-	/* Reset the chip */
+	/* reset the chip */
 #ifndef CONFIG_SERIAL_CONSOLE
-	{
-		int tmp;
-		dz_out(info, DZ_CSR, DZ_CLR);
-		while ((tmp = dz_in(info,DZ_CSR)) & DZ_CLR);
-		wbflush();
-  
-		/* Enable scanning */
-		dz_out(info, DZ_CSR, DZ_MSE); 
-	}
+	dz_out(info, DZ_CSR, DZ_CLR);
+	while ((tmp = dz_in(info, DZ_CSR)) & DZ_CLR);
+	wbflush();
+
+	/* enable scanning */
+	dz_out(info, DZ_CSR, DZ_MSE);
 #endif
-  
-	/*
-	 * Order matters here... the trick is that flags is updated... in
-	 * request_irq - to immediatedly obliterate it is unwise.
-	 */
+
+	/* order matters here... the trick is that flags
+	   is updated... in request_irq - to immediatedly obliterate
+	   it is unwise. */
 	restore_flags(flags);
 
+
 	if (request_irq(SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0]))
-		panic("Unable to register DZ interrupt\n");
- 
+		panic("Unable to register DZ interrupt");
+
 	return 0;
 }
 
 #ifdef CONFIG_SERIAL_CONSOLE
-static void dz_console_put_char (unsigned char ch)
+static void dz_console_put_char(unsigned char ch)
 {
 	unsigned long flags;
-	int  loops = 2500;
+	int loops = 2500;
 	unsigned short tmp = ch;
-	/*
-	 * this code sends stuff out to serial device - spinning its wheels and
-	 * waiting.
-	 */
+	/* this code sends stuff out to serial device - spinning its
+	   wheels and waiting. */
 
-	/* force the issue - point it at lines[3]*/
+	/* force the issue - point it at lines[3] */
 	dz_console = &multi[CONSOLE_LINE];
 
-	save_and_cli(flags);
+	save_flags(flags);
+	cli();
+
 
 	/* spin our wheels */
-	while (((dz_in(dz_console, DZ_CSR) & DZ_TRDY) != DZ_TRDY) &&  loops--)
-		;
-  
+	while (((dz_in(dz_console, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--);
+
 	/* Actually transmit the character. */
 	dz_out(dz_console, DZ_TDR, tmp);
 
-	restore_flags(flags); 
+	restore_flags(flags);
 }
-
 /* 
  * -------------------------------------------------------------------
  * dz_console_print ()
@@ -1495,12 +1466,12 @@
  * The console must be locked when we get here.
  * ------------------------------------------------------------------- 
  */
-static void dz_console_print (struct console *cons, 
-			      const char *str, 
-			      unsigned int count)
+static void dz_console_print(struct console *cons,
+			     const char *str,
+			     unsigned int count)
 {
 #ifdef DEBUG_DZ
-	prom_printf((char *)str);
+	prom_printf((char *) str);
 #endif
 	while (count--) {
 		if (*str == '\n')
@@ -1509,11 +1480,6 @@
 	}
 }
 
-static int dz_console_wait_key(struct console *co)
-{
-	return 0;
-}
-
 static kdev_t dz_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
@@ -1526,7 +1492,7 @@
 	int parity = 'n';
 	int cflag = CREAD | HUPCL | CLOCAL;
 	char *s;
-	unsigned short mask,tmp;
+	unsigned short mask, tmp;
 
 	if (options) {
 		baud = simple_strtoul(options, NULL, 10);
@@ -1536,11 +1502,10 @@
 		if (*s)
 			parity = *s++;
 		if (*s)
-			bits   = *s - '0';
+			bits = *s - '0';
 	}
-
 	/*
-	 * Now construct a cflag setting.
+	 *    Now construct a cflag setting.
 	 */
 	switch (baud) {
 	case 1200:
@@ -1580,18 +1545,17 @@
 
 	/* TOFIX: force to console line */
 	dz_console = &multi[CONSOLE_LINE];
-	if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) 
+	if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100))
 		dz_console->port = KN01_DZ11_BASE;
-	else 
-		dz_console->port = KN02_DZ11_BASE; 
+	else
+		dz_console->port = KN02_DZ11_BASE;
 	dz_console->line = CONSOLE_LINE;
 
 	dz_out(dz_console, DZ_CSR, DZ_CLR);
-	while ((tmp = dz_in(dz_console,DZ_CSR)) & DZ_CLR)
-		;
+	while ((tmp = dz_in(dz_console, DZ_CSR)) & DZ_CLR);
 
 	/* enable scanning */
-	dz_out(dz_console, DZ_CSR, DZ_MSE); 
+	dz_out(dz_console, DZ_CSR, DZ_MSE);
 
 	/*  Set up flags... */
 	dz_console->cflags = 0;
@@ -1601,20 +1565,19 @@
 	dz_out(dz_console, DZ_LPR, dz_console->cflags);
 
 	mask = 1 << dz_console->line;
-	tmp = dz_in (dz_console, DZ_TCR);		/* read the TX flag */
+	tmp = dz_in(dz_console, DZ_TCR);	/* read the TX flag */
 	if (!(tmp & mask)) {
-		tmp |= mask;				/* set the TX flag */
-		dz_out (dz_console, DZ_TCR, tmp); 
+		tmp |= mask;	/* set the TX flag */
+		dz_out(dz_console, DZ_TCR, tmp);
 	}
-
 	return 0;
 }
 
-static struct console dz_sercons = {
+static struct console dz_sercons =
+{
     name:	"ttyS",
     write:	dz_console_print,
     device:	dz_console_device,
-    wait_key:	dz_console_wait_key,
     setup:	dz_console_setup,
     flags:	CON_CONSDEV | CON_PRINTBUFFER,
     index:	CONSOLE_LINE,
@@ -1625,6 +1588,6 @@
 	register_console(&dz_sercons);
 }
 
-#endif /* ifdef CONFIG_SERIAL_CONSOLE */
+#endif /* CONFIG_SERIAL_CONSOLE */
 
 MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/dz.h linux/drivers/char/dz.h
--- linux.orig/drivers/char/dz.h	2000-02-25 18:26:42.000000000 +0000
+++ linux/drivers/char/dz.h	2002-07-20 01:08:28.000000000 +0000
@@ -10,6 +10,8 @@
 #ifndef DZ_SERIAL_H
 #define DZ_SERIAL_H
 
+#define SERIAL_MAGIC 0x5301
+
 /*
  * Definitions for the Control and Status Received.
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/efirtc.c linux/drivers/char/efirtc.c
--- linux.orig/drivers/char/efirtc.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/char/efirtc.c	2002-07-20 01:08:27.000000000 +0000
@@ -40,7 +40,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-#define EFI_RTC_VERSION		"0.2"
+#define EFI_RTC_VERSION		"0.3"
 
 #define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT)
 /*
@@ -315,56 +315,45 @@
 	spin_unlock_irqrestore(&efi_rtc_lock,flags);
 
 	p += sprintf(p,
-		     "Time      :\n"
-		     "Year      : %u\n"
-		     "Month     : %u\n"
-		     "Day       : %u\n"
-		     "Hour      : %u\n"
-		     "Minute    : %u\n"
-		     "Second    : %u\n"
-		     "Nanosecond: %u\n"
-		     "Daylight  : %u\n",
-		     eft.year, eft.month, eft.day, eft.hour, eft.minute,
-		     eft.second, eft.nanosecond, eft.daylight);
+		     "Time          : %u:%u:%u.%09u\n"
+		     "Date          : %u-%u-%u\n"
+		     "Daylight      : %u\n",
+		     eft.hour, eft.minute, eft.second, eft.nanosecond, 
+		     eft.year, eft.month, eft.day,
+		     eft.daylight);
 
 	if ( eft.timezone == EFI_UNSPECIFIED_TIMEZONE)
-		p += sprintf(p, "Timezone  : unspecified\n");
+		p += sprintf(p, "Timezone       : unspecified\n");
 	else
 		/* XXX fixme: convert to string? */
-		p += sprintf(p, "Timezone  : %u\n", eft.timezone);
+		p += sprintf(p, "Timezone       : %u\n", eft.timezone);
 		
 
 	p += sprintf(p,
-		     "\nWakeup Alm:\n"
-		     "Enabled   : %s\n"
-		     "Pending   : %s\n"
-		     "Year      : %u\n"
-		     "Month     : %u\n"
-		     "Day       : %u\n"
-		     "Hour      : %u\n"
-		     "Minute    : %u\n"
-		     "Second    : %u\n"
-		     "Nanosecond: %u\n"
-		     "Daylight  : %u\n",
-		     enabled == 1 ? "Yes" : "No",
-		     pending == 1 ? "Yes" : "No",
-		     alm.year, alm.month, alm.day, alm.hour, alm.minute,
-		     alm.second, alm.nanosecond, alm.daylight);
+		     "Alarm Time     : %u:%u:%u.%09u\n"
+		     "Alarm Date     : %u-%u-%u\n"
+		     "Alarm Daylight : %u\n"
+		     "Enabled        : %s\n"
+		     "Pending        : %s\n",
+		     alm.hour, alm.minute, alm.second, alm.nanosecond, 
+		     alm.year, alm.month, alm.day, 
+		     alm.daylight,
+		     enabled == 1 ? "yes" : "no",
+		     pending == 1 ? "yes" : "no");
 
 	if ( eft.timezone == EFI_UNSPECIFIED_TIMEZONE)
-		p += sprintf(p, "Timezone  : unspecified\n");
+		p += sprintf(p, "Timezone       : unspecified\n");
 	else
 		/* XXX fixme: convert to string? */
-		p += sprintf(p, "Timezone  : %u\n", eft.timezone);
+		p += sprintf(p, "Timezone       : %u\n", alm.timezone);
 
 	/*
 	 * now prints the capabilities
 	 */
 	p += sprintf(p,
-		     "\nClock Cap :\n"
-		     "Resolution: %u\n"
-		     "Accuracy  : %u\n"
-		     "SetstoZero: %u\n",
+		     "Resolution     : %u\n"
+		     "Accuracy       : %u\n"
+		     "SetstoZero     : %u\n",
 		      cap.resolution, cap.accuracy, cap.sets_to_zero);
 
 	return  p - buf;
@@ -390,7 +379,7 @@
 
 	misc_register(&efi_rtc_dev);
 
-	create_proc_read_entry ("efirtc", 0, NULL, efi_rtc_read_proc, NULL);
+	create_proc_read_entry ("driver/efirtc", 0, NULL, efi_rtc_read_proc, NULL);
 
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/epca.c linux/drivers/char/epca.c
--- linux.orig/drivers/char/epca.c	2001-10-12 20:48:42.000000000 +0000
+++ linux/drivers/char/epca.c	2002-07-20 01:08:23.000000000 +0000
@@ -908,7 +908,9 @@
 				
 				----------------------------------------------------------------- */
 
-				copy_from_user(ch->tmp_buf, buf, bytesAvailable);
+				if (copy_from_user(ch->tmp_buf, buf,
+						   bytesAvailable))
+					return -EFAULT;
 
 			} /* End if area verified */
 
@@ -3000,7 +3002,8 @@
 				di.port = boards[brd].port ;
 				di.membase = boards[brd].membase ;
 
-				copy_to_user((char *)arg, &di, sizeof (di));
+				if (copy_to_user((char *)arg, &di, sizeof (di)))
+					return -EFAULT;
 				break;
 
 			} /* End case DIGI_GETINFO */
@@ -3069,14 +3072,9 @@
 	{ /* Begin switch cmd */
 
 		case TCGETS:
-			retval = verify_area(VERIFY_WRITE, (void *)arg,
-                              sizeof(struct termios));
-			
-			if (retval)
-				return(retval);
-
-			copy_to_user((struct termios *)arg, 
-			             tty->termios, sizeof(struct termios));
+			if (copy_to_user((struct termios *)arg, 
+					 tty->termios, sizeof(struct termios)))
+				return -EFAULT;
 			return(0);
 
 		case TCGETA:
@@ -3236,14 +3234,9 @@
 			break;
 
 		case DIGI_GETA:
-			if ((error=
-				verify_area(VERIFY_WRITE, (char*)arg, sizeof(digi_t))))
-			{
-				printk(KERN_ERR "<Error> - Digi GETA failed\n");
-				return(error);
-			}
-
-			copy_to_user((char*)arg, &ch->digiext, sizeof(digi_t));
+			if (copy_to_user((char*)arg, &ch->digiext,
+					 sizeof(digi_t)))
+				return -EFAULT;
 			break;
 
 		case DIGI_SETAW:
@@ -3264,11 +3257,9 @@
 			/* Fall Thru */
 
 		case DIGI_SETA:
-			if ((error =
-				verify_area(VERIFY_READ, (char*)arg,sizeof(digi_t))))
-				return(error);
-
-			copy_from_user(&ch->digiext, (char*)arg, sizeof(digi_t));
+			if (copy_from_user(&ch->digiext, (char*)arg,
+					   sizeof(digi_t)))
+				return -EFAULT;
 			
 			if (ch->digiext.digi_flags & DIGI_ALTPIN) 
 			{
@@ -3311,10 +3302,8 @@
 			memoff(ch);
 			restore_flags(flags);
 
-			if ((error = verify_area(VERIFY_WRITE, (char*)arg,sizeof(dflow))))
-				return(error);
-
-			copy_to_user((char*)arg, &dflow, sizeof(dflow));
+			if (copy_to_user((char*)arg, &dflow, sizeof(dflow)))
+				return -EFAULT;
 			break;
 
 		case DIGI_SETAFLOW:
@@ -3330,10 +3319,8 @@
 				stopc = ch->stopca;
 			}
 
-			if ((error = verify_area(VERIFY_READ, (char*)arg,sizeof(dflow))))
-				return(error);
-
-			copy_from_user(&dflow, (char*)arg, sizeof(dflow));
+			if (copy_from_user(&dflow, (char*)arg, sizeof(dflow)))
+				return -EFAULT;
 
 			if (dflow.startc != startc || dflow.stopc != stopc) 
 			{ /* Begin  if setflow toggled */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/esp.c linux/drivers/char/esp.c
--- linux.orig/drivers/char/esp.c	2001-11-09 22:01:21.000000000 +0000
+++ linux/drivers/char/esp.c	2002-07-20 01:08:22.000000000 +0000
@@ -2162,7 +2162,7 @@
 		if (signal_pending(current))
 			break;
 
-		if (timeout && ((orig_jiffies + timeout) < jiffies))
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
 			break;
 
 		serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/eurotechwdt.c linux/drivers/char/eurotechwdt.c
--- linux.orig/drivers/char/eurotechwdt.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/eurotechwdt.c	2002-07-20 01:08:26.000000000 +0000
@@ -3,6 +3,7 @@
  *
  *	(c) Copyright 2001 Ascensit <support@ascensit.com>
  *	(c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
+ *	(c) Copyright 2002 Rob Radez <rob@osinvestor.com>
  *
  *	Based on wdt.c.
  *	Original copyright messages:
@@ -22,17 +23,27 @@
  *      (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>*
  */
 
+/* Changelog:
+ *
+ * 2002/04/25 - Rob Radez
+ *	clean up #includes
+ *	clean up locking
+ *	make __setup param unique
+ *	proper options in watchdog_info
+ *	add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
+ *	add expect_close support
+ *
+ * 2001 - Rodolfo Giometti
+ *	Initial release
+ */
+
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <asm/io.h>
@@ -41,12 +52,10 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
-static int eurwdt_is_open;
-static int eurwdt_timeout; 
-static spinlock_t eurwdt_lock;
+static unsigned long eurwdt_is_open;
+static int eurwdt_timeout;
+static char eur_expect_close;
  
 /*
  *      You must set these - there is no sane way to probe for this board.
@@ -100,7 +109,7 @@
    return 1;
 }
  
-__setup("wdt=", eurwdt_setup);
+__setup("eurwdt=", eurwdt_setup);
 
 #endif /* !MODULE */
  
@@ -109,7 +118,7 @@
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(irq, "Eurotech WDT irq (default=10)");
 MODULE_PARM(ev, "s");
-MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `reboot')");
+MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `int')");
 
 
 /*
@@ -211,11 +220,20 @@
       return -ESPIPE;
  
    if (count) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+      size_t i;
+
+      eur_expect_close = 0;
+
+      for (i = 0; i != count; i++) {
+         if (buf[i] == 'V')
+            eur_expect_close = 42;
+      }
+#endif
       eurwdt_ping();   /* the default timeout */
-      return 1;
    }
 
-   return 0;
+   return count;
 }
 
 /**
@@ -233,8 +251,8 @@
         unsigned int cmd, unsigned long arg)
 {
    static struct watchdog_info ident = {
-      options		: WDIOF_CARDRESET | WDIOF_SETTIMEOUT,
-      firmware_version	: 1,
+      options		: WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+      firmware_version	: 0,
       identity		: "WDT Eurotech CPU-1220/1410"
    };
 
@@ -248,6 +266,7 @@
          return copy_to_user((struct watchdog_info *)arg, &ident,
                sizeof(ident)) ? -EFAULT : 0;
  
+      case WDIOC_GETSTATUS:
       case WDIOC_GETBOOTSTATUS:
          return put_user(0, (int *) arg);
 
@@ -269,6 +288,27 @@
 
       case WDIOC_GETTIMEOUT:
 	 return put_user(eurwdt_timeout, (int *)arg);
+
+      case WDIOC_SETOPTIONS:
+      {
+	 int options, retval = -EINVAL;
+
+	 if (get_user(options, (int *)arg))
+	    return -EFAULT;
+
+	 if (options & WDIOS_DISABLECARD) {
+	    eurwdt_disable_timer();
+	    retval = 0;
+	 }
+
+	 if (options & WDIOS_ENABLECARD) {
+	    eurwdt_activate_timer();
+	    eurwdt_ping();
+	    retval = 0;
+	 }
+
+	 return retval;
+      }
    }
 }
 
@@ -283,32 +323,15 @@
  
 static int eurwdt_open(struct inode *inode, struct file *file)
 {
-   switch (MINOR(inode->i_rdev)) {
-      case WATCHDOG_MINOR:
-         spin_lock(&eurwdt_lock);
-         if (eurwdt_is_open) {
-            spin_unlock(&eurwdt_lock);
-            return -EBUSY;
-         }
-
-         eurwdt_is_open = 1;
-         eurwdt_timeout = WDT_TIMEOUT;   /* initial timeout */
-
-         /* Activate the WDT */
-         eurwdt_activate_timer(); 
-            
-         spin_unlock(&eurwdt_lock);
-
-         MOD_INC_USE_COUNT;
+   if (test_and_set_bit(0, &eurwdt_is_open))
+      return -EBUSY;
 
-         return 0;
+   eurwdt_timeout = WDT_TIMEOUT;   /* initial timeout */
 
-         case TEMP_MINOR:
-            return 0;
+   /* Activate the WDT */
+   eurwdt_activate_timer(); 
 
-         default:
-            return -ENODEV;
-   }
+   return 0;
 }
  
 /**
@@ -325,14 +348,14 @@
  
 static int eurwdt_release(struct inode *inode, struct file *file)
 {
-   if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
+   if (eur_expect_close == 42) {
       eurwdt_disable_timer();
-#endif
-      eurwdt_is_open = 0;
-
-      MOD_DEC_USE_COUNT;
+   } else {
+      printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
+      eurwdt_ping();
    }
+   clear_bit(0, &eurwdt_is_open);
+   eur_expect_close = 0;
 
    return 0;
 }
@@ -376,9 +399,9 @@
 
 static struct miscdevice eurwdt_miscdev =
 {
-        WATCHDOG_MINOR,
-        "watchdog",
-        &eurwdt_fops
+        minor:		WATCHDOG_MINOR,
+        name:		"watchdog",
+        fops:		&eurwdt_fops,
 };
  
 /*
@@ -458,8 +481,6 @@
                     " - timeout event: %s\n", 
          io, irq, (!strcmp("int", ev) ? "int" : "reboot"));
 
-   spin_lock_init(&eurwdt_lock);
-
    out:
       return ret;
  
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/ftape/lowlevel/ftape-rw.h linux/drivers/char/ftape/lowlevel/ftape-rw.h
--- linux.orig/drivers/char/ftape/lowlevel/ftape-rw.h	1999-11-23 18:29:15.000000000 +0000
+++ linux/drivers/char/ftape/lowlevel/ftape-rw.h	2002-07-20 01:08:33.000000000 +0000
@@ -71,7 +71,7 @@
 
 /*      Count nr of 1's in pattern.
  */
-extern inline int count_ones(unsigned long mask)
+static inline int count_ones(unsigned long mask)
 {
 	int bits;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/ftape/zftape/zftape-vtbl.h linux/drivers/char/ftape/zftape/zftape-vtbl.h
--- linux.orig/drivers/char/ftape/zftape/zftape-vtbl.h	1997-11-25 22:45:28.000000000 +0000
+++ linux/drivers/char/ftape/zftape/zftape-vtbl.h	2002-07-20 01:08:33.000000000 +0000
@@ -168,11 +168,11 @@
 extern int   zft_weof                  (unsigned int count, zft_position *pos);
 extern void  zft_move_past_eof         (zft_position *pos);
 
-extern inline int   zft_tape_at_eod         (const zft_position *pos);
-extern inline int   zft_tape_at_lbot        (const zft_position *pos);
-extern inline void  zft_position_before_eof (zft_position *pos, 
+static inline int   zft_tape_at_eod         (const zft_position *pos);
+static inline int   zft_tape_at_lbot        (const zft_position *pos);
+static inline void  zft_position_before_eof (zft_position *pos, 
 					     const zft_volinfo *volume);
-extern inline __s64 zft_check_for_eof(const zft_volinfo *vtbl,
+static inline __s64 zft_check_for_eof(const zft_volinfo *vtbl,
 				      const zft_position *pos);
 
 /* this function decrements the zft_seg_pos counter if we are right
@@ -180,7 +180,7 @@
  * need to position before the eof mark.  NOTE: zft_tape_pos is not
  * changed 
  */
-extern inline void zft_position_before_eof(zft_position *pos, 
+static inline void zft_position_before_eof(zft_position *pos, 
 					   const zft_volinfo *volume)
 { 
 	TRACE_FUN(ft_t_flow);
@@ -195,7 +195,7 @@
 /*  Mmmh. Is the position at the end of the last volume, that is right
  *  before the last EOF mark also logical an EOD condition?
  */
-extern inline int zft_tape_at_eod(const zft_position *pos)
+static inline int zft_tape_at_eod(const zft_position *pos)
 { 
 	TRACE_FUN(ft_t_any);
 
@@ -207,7 +207,7 @@
 	}
 }
 
-extern inline int zft_tape_at_lbot(const zft_position *pos)
+static inline int zft_tape_at_lbot(const zft_position *pos)
 {
 	if (zft_qic_mode) {
 		return (pos->seg_pos <= zft_first_vtbl->start_seg &&
@@ -220,7 +220,7 @@
 
 /* This one checks for EOF.  return remaing space (may be negative) 
  */
-extern inline __s64 zft_check_for_eof(const zft_volinfo *vtbl,
+static inline __s64 zft_check_for_eof(const zft_volinfo *vtbl,
 				      const zft_position *pos)
 {     
 	return (__s64)(vtbl->size - pos->volume_pos);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/hcdp_serial.c linux/drivers/char/hcdp_serial.c
--- linux.orig/drivers/char/hcdp_serial.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/hcdp_serial.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,221 @@
+/*
+ *  linux/drivers/char/hcdp_serial.c
+ *
+ *  Copyright (C) 2002  Hewlett-Packard Co.
+ *  Copyright (C) 2002  Khalid Aziz <khalid_aziz@hp.com>
+ *
+ *  Parse the EFI HCDP table to locate serial console and debug ports
+ *  and initialize them
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+#include <asm/efi.h>
+#include <linux/hcdp_serial.h>
+
+#undef SERIAL_DEBUG_HCDP
+
+extern struct serial_state rs_table[];
+extern int serial_nr_ports;
+
+/*
+ * Parse the HCDP table to find descriptions for headless console and 
+ * debug serial ports and add them to rs_table[]. A pointer to HCDP
+ * table is passed as parameter. This function should be called 
+ * before serial_console_init() is called to make sure the HCDP serial 
+ * console will be available for use. IA-64 kernel calls this function
+ * from setup_arch() after the EFI and ACPI tables have been parsed.
+ */
+void __init setup_serial_hcdp(void *tablep) 
+{
+	hcdp_t hcdp;
+	hcdp_dev_t *hcdp_dev;
+	struct serial_struct serial_req;
+	unsigned long iobase;
+	int global_sys_irq;
+	int i, nr;
+	int shift_once = 1;
+
+#ifdef SERIAL_DEBUG_HCDP
+	printk("Entering setup_serial_hcdp()\n");
+#endif
+
+	/* Verify we have a valid table pointer */
+	if (tablep == NULL) {
+		return;
+	}
+
+	/*
+	 * We do not trust firmware to give us a table starting at an
+	 * aligned address. Make a local copy of the HCDP table with 
+	 * aligned structures.
+	 */
+	memcpy(&hcdp, tablep, sizeof(hcdp));
+
+	/*
+	 * Perform a sanity check on the table. Table should have a 
+	 * signature of "HCDP" and it should be atleast 82 bytes
+	 * long to have any useful information.
+	 */
+	if ((strncmp(hcdp.signature, HCDP_SIGNATURE, 
+					HCDP_SIG_LEN) != 0)) {
+		return;
+	}
+	if (hcdp.len < 82) {
+		return;
+	}
+
+#ifdef SERIAL_DEBUG_HCDP
+	printk("setup_serial_hcdp(): table pointer = 0x%p\n", tablep);
+	printk("                     sig = '%c%c%c%c'\n",
+			hcdp.signature[0],
+			hcdp.signature[1],
+			hcdp.signature[2],
+			hcdp.signature[3]);
+	printk("                     length = %d\n", hcdp.len);
+	printk("                     Rev = %d\n", hcdp.rev);
+	printk("                     OEM ID = %c%c%c%c%c%c\n", 
+			hcdp.oemid[0], hcdp.oemid[1], hcdp.oemid[2],
+			hcdp.oemid[3], hcdp.oemid[4], hcdp.oemid[5]);
+	printk("                     Number of entries = %d\n", hcdp.num_entries);
+#endif
+
+	/*
+	 * Parse each device entry
+	 */
+	for (nr=0; nr<hcdp.num_entries; nr++) {
+		hcdp_dev = &(hcdp.hcdp_dev[nr]);
+
+		/*
+		 * We will parse only the primary console device
+		 * which is the first entry for these devices. We will
+		 * ignore rest of the entries for the same type device that
+		 * has already been parsed and initialized
+		 */
+		if (hcdp_dev->type != HCDP_DEV_CONSOLE)
+			continue;
+
+		iobase = (u64)(hcdp_dev->base_addr.addrhi)<<32 | hcdp_dev->base_addr.addrlo;
+		global_sys_irq = hcdp_dev->global_int;
+#ifdef SERIAL_DEBUG_HCDP
+		printk("                 type = %s\n", 
+			((hcdp_dev->type == HCDP_DEV_CONSOLE)?"Headless Console":((hcdp_dev->type == HCDP_DEV_DEBUG)?"Debug port":"Huh????")));
+		printk("                 Base address space = %s\n", ((hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE)?"Memory Space":((hcdp_dev->base_addr.space_id == ACPI_IO_SPACE)?"I/O space":"PCI space")));
+		printk("                 Base address = 0x%p\n", iobase);
+		printk("                 Global System Int = %d\n", global_sys_irq);
+		printk("                 Baud rate = %d\n", hcdp_dev->baud);
+		printk("                 Bits = %d\n", hcdp_dev->bits);
+		printk("                 Clock rate = %d\n", hcdp_dev->clock_rate);
+		if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) {
+			printk("                     PCI serial port:\n");
+			printk("                         Bus %d, Device %d, Vendor ID 0x%x, Dev ID 0x%x\n",
+			hcdp_dev->pci_bus, hcdp_dev->pci_dev,
+			hcdp_dev->pci_vendor_id, hcdp_dev->pci_dev_id);
+		}
+#endif
+
+
+		/* 
+	 	* Now build a serial_req structure to update the entry in
+	 	* rs_table for the headless console port.
+	 	*/
+		if (hcdp_dev->clock_rate)
+			serial_req.baud_base = hcdp_dev->clock_rate;
+		else
+			serial_req.baud_base = DEFAULT_BAUD_BASE;
+		/*
+	 	* Check if this is an I/O mapped address or a memory mapped address
+	 	*/
+		if (hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE) {
+			serial_req.port = 0;
+			serial_req.port_high = 0;
+			serial_req.iomem_base = (void *)ioremap(iobase, 64);
+			serial_req.io_type = SERIAL_IO_MEM;
+		}
+		else if (hcdp_dev->base_addr.space_id == ACPI_IO_SPACE) {
+			serial_req.port = (unsigned long) iobase & 0xffffffff;
+			serial_req.port_high = (unsigned long)(((u64)iobase) >> 32);
+			serial_req.iomem_base = NULL;
+			serial_req.io_type = SERIAL_IO_PORT;
+		}
+		else if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) {
+			printk("WARNING: No support for PCI serial console\n");
+			return;
+		}
+
+		/*
+		 * Check if HCDP defines a port already in rs_table
+		 */
+		for (i = 0; i < serial_nr_ports; i++) {
+			if ((rs_table[i].port == serial_req.port) &&
+				(rs_table[i].iomem_base==serial_req.iomem_base))
+				break;
+		}
+		if (i == serial_nr_ports) {
+			/*
+			 * We have reserved a slot for HCDP defined console
+			 * port at HCDP_SERIAL_CONSOLE_PORT in rs_table
+			 * which is not 0. This means using this slot would
+			 * put the console at a device other than ttyS0. 
+			 * Users expect to see the console at ttyS0. Now 
+			 * that we have determined HCDP does describe a 
+			 * serial console and it is not one of the compiled
+			 * in ports, let us move the entries in rs_table
+			 * up by a slot towards HCDP_SERIAL_CONSOLE_PORT to 
+			 * make room for the HCDP console at ttyS0. We may go
+			 * through this loop more than once if 
+			 * early_serial_setup() fails. Make sure we shift the
+			 * entries in rs_table only once.
+			 */
+			if (shift_once) {
+				int j;
+
+				for (j=HCDP_SERIAL_CONSOLE_PORT; j>0; j--)
+					memcpy(rs_table+j, rs_table+j-1, 
+						sizeof(struct serial_state));
+				shift_once = 0;
+			}
+			serial_req.line = 0;
+		}
+		else
+			serial_req.line = i;
+
+		/*
+	 	* If the table does not have IRQ information, use 0 for IRQ. 
+	 	* This will force rs_init() to probe for IRQ. 
+	 	*/
+		serial_req.irq = global_sys_irq;
+		if (global_sys_irq == 0) {
+			serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF;
+		}
+		else {
+			serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|
+						ASYNC_AUTO_IRQ;
+		}
+
+		serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
+		serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
+		serial_req.iomem_reg_shift = 0;
+		if (early_serial_setup(&serial_req) < 0) {
+			printk("setup_serial_hcdp(): early_serial_setup() for HCDP serial console port failed. Will try any additional consoles in HCDP.\n");
+			continue;
+		}
+		else
+			if (hcdp_dev->type == HCDP_DEV_CONSOLE)
+				break;
+#ifdef SERIAL_DEBUG_HCDP
+		printk("\n");
+#endif
+	}
+
+#ifdef SERIAL_DEBUG_HCDP
+	printk("Leaving setup_serial_hcdp()\n");
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/i810-tco.c linux/drivers/char/i810-tco.c
--- linux.orig/drivers/char/i810-tco.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/i810-tco.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *	i810-tco 0.02:	TCO timer driver for i810 chipsets
+ *	i810-tco 0.05:	TCO timer driver for i8xx chipsets
  *
  *	(c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
  *				http://www.kernelconcepts.de
@@ -9,25 +9,40 @@
  *	as published by the Free Software Foundation; either version
  *	2 of the License, or (at your option) any later version.
  *	
- *	Neither kernel concepts nor Nils Faerber admit liability nor provide 
- *	warranty for any of this software. This material is provided 
- *	"AS-IS" and at no charge.	
+ *	Neither kernel concepts nor Nils Faerber admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
  *
  *	(c) Copyright 2000	kernel concepts <nils@kernelconcepts.de>
  *				developed for
  *                              Jentro AG, Haar/Munich (Germany)
  *
- *	TCO timer driver for i810/i815 chipsets
+ *	TCO timer driver for i8xx chipsets
  *	based on softdog.c by Alan Cox <alan@redhat.com>
  *
- *	The TCO timer is implemented in the 82801AA (82801AB) chip,
- *	see intel documentation from http://developer.intel.com,
- *	order number 290655-003
+ *	The TCO timer is implemented in the following I/O controller hubs:
+ *	(See the intel documentation on http://developer.intel.com.)
+ *	82801AA & 82801AB  chip : document number 290655-003, 290677-004,
+ *	82801BA & 82801BAM chip : document number 290687-002, 298242-005,
+ *	82801CA & 82801CAM chip : document number 290716-001, 290718-001,
+ *	82801DB & 82801E   chip : document number 290744-001, 273599-001
  *
  *  20000710 Nils Faerber
  *	Initial Version 0.01
  *  20000728 Nils Faerber
- *      0.02 Fix for SMI_EN->TCO_EN bit, some cleanups
+ *	0.02 Fix for SMI_EN->TCO_EN bit, some cleanups
+ *  20011214 Matt Domsch <Matt_Domsch@dell.com>
+ *	0.03 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ *	     Didn't add timeout option as i810_margin already exists.
+ *  20020224 Joel Becker, Wim Van Sebroeck
+ *	0.04 Support for 82801CA(M) chipset, timer margin needs to be > 3,
+ *	     add support for WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT.
+ *  20020412 Rob Radez <rob@osinvestor.com>, Wim Van Sebroeck
+ *	0.05 Fix possible timer_alive race, add expect close support,
+ *	     clean up ioctls (WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS and
+ *	     WDIOC_SETOPTIONS), made i810tco_getdevice __init,
+ *	     removed boot_status, removed tco_timer_read,
+ *	     added support for 82801DB and 82801E chipset, general cleanup.
  */
  
 #include <linux/module.h>
@@ -46,30 +61,41 @@
 #include "i810-tco.h"
 
 
-/* Just in case that the PCI vendor and device IDs are not yet defined */
-#ifndef PCI_DEVICE_ID_INTEL_82801AA_0
-#define PCI_DEVICE_ID_INTEL_82801AA_0	0x2410
-#endif
+/* Module and version information */
+#define TCO_VERSION "0.05"
+#define TCO_MODULE_NAME "i810 TCO timer"
+#define TCO_DRIVER_NAME   TCO_MODULE_NAME ", v" TCO_VERSION
 
 /* Default expire timeout */
-#define TIMER_MARGIN	50	/* steps of 0.6sec, 2<n<64. Default is 30 seconds */
+#define TIMER_MARGIN	50	/* steps of 0.6sec, 3<n<64. Default is 30 seconds */
 
 static unsigned int ACPIBASE;
 static spinlock_t tco_lock;	/* Guards the hardware */
 
 static int i810_margin = TIMER_MARGIN;	/* steps of 0.6sec */
 
-MODULE_PARM (i810_margin, "i");
+MODULE_PARM(i810_margin, "i");
+MODULE_PARM_DESC(i810_margin, "i810-tco timeout in steps of 0.6sec, 3<n<64. Default = 50 (30 seconds)");
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
+
+MODULE_PARM(nowayout,"i");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
 
 /*
  *	Timer active flag
  */
 
-static int timer_alive;
-static int boot_status;
+static unsigned long timer_alive;
+static char tco_expect_close;
 
 /*
- * Some i810 specific functions
+ * Some TCO specific functions
  */
 
 
@@ -120,7 +146,7 @@
 
 	/* from the specs: */
 	/* "Values of 0h-3h are ignored and should not be attempted" */
-	if (tmrval > 0x3f || tmrval < 0x03)
+	if (tmrval > 0x3f || tmrval < 0x04)
 		return -1;
 	
 	spin_lock(&tco_lock);
@@ -150,21 +176,12 @@
 }
 
 /*
- * Read the current timer value
- */
-static unsigned char tco_timer_read (void)
-{
-	return (inb (TCO1_RLD));
-}
-
-
-/*
  *	Allow only one person to hold it open
  */
 
 static int i810tco_open (struct inode *inode, struct file *file)
 {
-	if (timer_alive)
+	if (test_and_set_bit(0, &timer_alive))
 		return -EBUSY;
 
 	/*
@@ -172,7 +189,6 @@
 	 */
 	tco_timer_reload ();
 	tco_timer_start ();
-	timer_alive = 1;
 	return 0;
 }
 
@@ -181,10 +197,14 @@
 	/*
 	 *      Shut off the timer.
 	 */
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
-	tco_timer_stop ();
-	timer_alive = 0;
-#endif	
+	if (tco_expect_close == 42 && !nowayout) {
+		tco_timer_stop ();
+	} else {
+		tco_timer_reload ();
+		printk(KERN_CRIT TCO_MODULE_NAME ": Unexpected close, not stopping watchdog!\n");
+	}
+	clear_bit(0, &timer_alive);
+	tco_expect_close = 0;
 	return 0;
 }
 
@@ -195,10 +215,19 @@
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
 
-	/*
-	 *      Refresh the timer.
-	 */
+	/* See if we got the magic character 'V' and reload the timer */
 	if (len) {
+		size_t i;
+
+		tco_expect_close = 0;
+
+		/* scan to see wether or not we got the magic character */
+		for (i = 0; i != len; i++) {
+			if (data[i] == 'V')
+				tco_expect_close = 42;
+		}
+
+		/* someone wrote to us, we should reload the timer */
 		tco_timer_reload ();
 		return 1;
 	}
@@ -209,41 +238,53 @@
 			  unsigned int cmd, unsigned long arg)
 {
 	int new_margin, u_margin;
+	int options, retval = -EINVAL;
 
 	static struct watchdog_info ident = {
-		WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
-		0,
-		"i810 TCO timer"
+		options:		WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+		firmware_version:	0,
+		identity:		"i810 TCO timer",
 	};
 	switch (cmd) {
-	default:
-		return -ENOTTY;
-	case WDIOC_GETSUPPORT:
-		if (copy_to_user
-		    ((struct watchdog_info *) arg, &ident, sizeof (ident)))
-			return -EFAULT;
-		return 0;
-	case WDIOC_GETSTATUS:
-		return put_user (tco_timer_read (),
-				 (unsigned int *) (int) arg);
-	case WDIOC_GETBOOTSTATUS:
-		return put_user (boot_status, (int *) arg);
-	case WDIOC_KEEPALIVE:
-		tco_timer_reload ();
-		return 0;
-	case WDIOC_SETTIMEOUT:
-		if (get_user(u_margin, (int *) arg))
-			return -EFAULT;
-		new_margin = (u_margin * 10 + 5) / 6;
-		if ((new_margin < 3) || (new_margin > 63))
-			return -EINVAL;
-		if (tco_timer_settimer((unsigned char)new_margin))
-		    return -EINVAL;
-		i810_margin = new_margin;
-		tco_timer_reload();
-		/* Fall */
-	case WDIOC_GETTIMEOUT:
-		return put_user((int)(i810_margin * 6 / 10), (int *) arg);
+		default:
+			return -ENOTTY;
+		case WDIOC_GETSUPPORT:
+			if (copy_to_user
+			    ((struct watchdog_info *) arg, &ident, sizeof (ident)))
+				return -EFAULT;
+			return 0;
+		case WDIOC_GETSTATUS:
+		case WDIOC_GETBOOTSTATUS:
+			return put_user (0, (int *) arg);
+		case WDIOC_SETOPTIONS:
+			if (get_user (options, (int *) arg))
+				return -EFAULT;
+			if (options & WDIOS_DISABLECARD) {
+				tco_timer_stop ();
+				retval = 0;
+			}
+			if (options & WDIOS_ENABLECARD) {
+				tco_timer_reload ();
+				tco_timer_start ();
+				retval = 0;
+			}
+			return retval;
+		case WDIOC_KEEPALIVE:
+			tco_timer_reload ();
+			return 0;
+		case WDIOC_SETTIMEOUT:
+			if (get_user (u_margin, (int *) arg))
+				return -EFAULT;
+			new_margin = (u_margin * 10 + 5) / 6;
+			if ((new_margin < 4) || (new_margin > 63))
+				return -EINVAL;
+			if (tco_timer_settimer ((unsigned char) new_margin))
+			    return -EINVAL;
+			i810_margin = new_margin;
+			tco_timer_reload ();
+			/* Fall */
+		case WDIOC_GETTIMEOUT:
+			return put_user ((int)(i810_margin * 6 / 10), (int *) arg);
 	}
 }
 
@@ -260,13 +301,17 @@
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0,	PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,	PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0,	PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0, },
 };
 MODULE_DEVICE_TABLE (pci, i810tco_pci_tbl);
 
 static struct pci_dev *i810tco_pci;
 
-static unsigned char i810tco_getdevice (void)
+static unsigned char __init i810tco_getdevice (void)
 {
 	struct pci_dev *dev;
 	u8 val1, val2;
@@ -294,7 +339,7 @@
 		ACPIBASE = badr;
 		/* Something's wrong here, ACPIBASE has to be set */
 		if (badr == 0x0001 || badr == 0x0000) {
-			printk (KERN_ERR "i810tco init: failed to get TCOBASE address\n");
+			printk (KERN_ERR TCO_MODULE_NAME " init: failed to get TCOBASE address\n");
 			return 0;
 		}
 		/*
@@ -306,7 +351,7 @@
 			pci_write_config_byte (i810tco_pci, 0xd4, val1);
 			pci_read_config_byte (i810tco_pci, 0xd4, &val1);
 			if (val1 & 0x02) {
-				printk (KERN_ERR "i810tco init: failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+				printk (KERN_ERR TCO_MODULE_NAME " init: failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
 				return 0;	/* Cannot reset NO_REBOOT bit */
 			}
 		}
@@ -316,7 +361,6 @@
 		outb (val1, SMI_EN + 1);
 		/* Clear out the (probably old) status */
 		outb (0, TCO1_STS);
-		boot_status = (int) inb (TCO2_STS);
 		outb (3, TCO2_STS);
 		return 1;
 	}
@@ -332,9 +376,9 @@
 };
 
 static struct miscdevice i810tco_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&i810tco_fops
+	minor:		WATCHDOG_MINOR,
+	name:		"watchdog",
+	fops:		&i810tco_fops,
 };
 
 static int __init watchdog_init (void)
@@ -343,22 +387,22 @@
 	if (!i810tco_getdevice () || i810tco_pci == NULL)
 		return -ENODEV;
 	if (!request_region (TCOBASE, 0x10, "i810 TCO")) {
-		printk (KERN_ERR
-			"i810 TCO timer: I/O address 0x%04x already in use\n",
+		printk (KERN_ERR TCO_MODULE_NAME
+			": I/O address 0x%04x already in use\n",
 			TCOBASE);
 		return -EIO;
 	}
 	if (misc_register (&i810tco_miscdev) != 0) {
 		release_region (TCOBASE, 0x10);
-		printk (KERN_ERR "i810 TCO timer: cannot register miscdev\n");
+		printk (KERN_ERR TCO_MODULE_NAME ": cannot register miscdev\n");
 		return -EIO;
 	}
 	tco_timer_settimer ((unsigned char) i810_margin);
 	tco_timer_reload ();
 
-	printk (KERN_INFO
-		"i810 TCO timer: V0.02, timer margin: %d sec (0x%04x)\n",
-		(int) (i810_margin * 6 / 10), TCOBASE);
+	printk (KERN_INFO TCO_DRIVER_NAME
+		": timer margin: %d sec (0x%04x) (nowayout=%d)\n",
+		(int) (i810_margin * 6 / 10), TCOBASE, nowayout);
 	return 0;
 }
 
@@ -379,4 +423,7 @@
 module_init(watchdog_init);
 module_exit(watchdog_cleanup);
 
+MODULE_AUTHOR("Nils Faerber");
+MODULE_DESCRIPTION("TCO timer driver for i8xx chipsets");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/i810-tco.h linux/drivers/char/i810-tco.h
--- linux.orig/drivers/char/i810-tco.h	2000-08-11 22:57:57.000000000 +0000
+++ linux/drivers/char/i810-tco.h	2002-07-20 01:08:26.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *	i810-tco 0.02:	TCO timer driver for i810 chipsets
+ *	i810-tco 0.05:	TCO timer driver for i8xx chipsets
  *
  *	(c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
  *				http://www.kernelconcepts.de
@@ -9,22 +9,19 @@
  *	as published by the Free Software Foundation; either version
  *	2 of the License, or (at your option) any later version.
  *	
- *	Neither kernel concepts nor Nils Faerber admit liability nor provide 
- *	warranty for any of this software. This material is provided 
- *	"AS-IS" and at no charge.	
+ *	Neither kernel concepts nor Nils Faerber admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
  *
  *	(c) Copyright 2000	kernel concepts <nils@kernelconcepts.de>
  *				developed for
  *                              Jentro AG, Haar/Munich (Germany)
  *
- *	TCO timer driver for i810 chipsets
+ *	TCO timer driver for i8xx chipsets
  *	based on softdog.c by Alan Cox <alan@redhat.com>
  *
- *      The TCO timer is implemented in the 82801AA (82801AB) chip,
- *	see intel documentation from http://developer.intel.com,
- *	order number 290655-003
- *
- *	For history see i810-tco.c
+ *	For history and the complete list of supported I/O Controller Hub's
+ *	see i810-tco.c
  */
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/i810_rng.c linux/drivers/char/i810_rng.c
--- linux.orig/drivers/char/i810_rng.c	2001-10-11 16:14:32.000000000 +0000
+++ linux/drivers/char/i810_rng.c	2002-07-20 01:08:34.000000000 +0000
@@ -35,7 +35,7 @@
 /*
  * core module and version information
  */
-#define RNG_VERSION "0.9.6"
+#define RNG_VERSION "0.9.8"
 #define RNG_MODULE_NAME "i810_rng"
 #define RNG_DRIVER_NAME   RNG_MODULE_NAME " hardware driver " RNG_VERSION
 #define PFX RNG_MODULE_NAME ": "
@@ -334,7 +334,9 @@
 static struct pci_device_id rng_pci_tbl[] __initdata = {
 	{ 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, },
-	{ 0x8086, 0x1130, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0, },
 };
 MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/indydog.c linux/drivers/char/indydog.c
--- linux.orig/drivers/char/indydog.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/indydog.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,155 @@
+/*
+ *	IndyDog	0.2	A Hardware Watchdog Device for SGI IP22
+ *
+ *	(c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, 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.
+ *	
+ *	based on softdog.c by Alan Cox <alan@redhat.com>
+ */
+ 
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/sgi/sgimc.h>
+
+static unsigned long indydog_alive;
+static struct sgimc_misc_ctrl *mcmisc_regs; 
+
+static void indydog_ping()
+{
+	mcmisc_regs->watchdogt = 0;
+}
+
+
+/*
+ *	Allow only one person to hold it open
+ */
+
+static int indydog_open(struct inode *inode, struct file *file)
+{
+	u32 mc_ctrl0;
+	
+	if( test_and_set_bit(0,&indydog_alive) )
+		return -EBUSY;
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+	MOD_INC_USE_COUNT;
+#endif
+	/*
+	 *	Activate timer
+	 */
+	mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
+
+	mc_ctrl0 = mcmisc_regs->cpuctrl0 | SGIMC_CCTRL0_WDOG;
+	mcmisc_regs->cpuctrl0 = mc_ctrl0;
+	indydog_ping();
+			
+	printk("Started watchdog timer.\n");
+	return 0;
+}
+
+static int indydog_release(struct inode *inode, struct file *file)
+{
+	/*
+	 *	Shut off the timer.
+	 * 	Lock it in if it's a module and we defined ...NOWAYOUT
+	 */
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+	{
+	u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; 
+	mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG;
+	mcmisc_regs->cpuctrl0 = mc_ctrl0;
+	printk("Stopped watchdog timer.\n");
+	}
+#endif
+	clear_bit(0,&indydog_alive);
+	return 0;
+}
+
+static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	/*
+	 *	Refresh the timer.
+	 */
+	if(len) {
+		indydog_ping();
+		return 1;
+	}
+	return 0;
+}
+
+static int indydog_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	static struct watchdog_info ident = {
+		identity: "Hardware Watchdog for SGI IP22",
+	};
+	switch (cmd) {
+		default:
+			return -ENOIOCTLCMD;
+		case WDIOC_GETSUPPORT:
+			if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+				return -EFAULT;
+			return 0;
+		case WDIOC_GETSTATUS:
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0,(int *)arg);
+		case WDIOC_KEEPALIVE:
+			indydog_ping();
+			return 0;
+	}
+}
+
+static struct file_operations indydog_fops = {
+	owner:		THIS_MODULE,
+	write:		indydog_write,
+	ioctl:		indydog_ioctl,
+	open:		indydog_open,
+	release:	indydog_release,
+};
+
+static struct miscdevice indydog_miscdev = {
+	minor:		WATCHDOG_MINOR,
+	name:		"watchdog",
+	fops:		&indydog_fops,
+};
+
+static const char banner[] __initdata = KERN_INFO "Hardware Watchdog Timer for SGI IP22: 0.2\n";
+
+static int __init watchdog_init(void)
+{
+	int ret;
+
+	ret = misc_register(&indydog_miscdev);
+
+	if (ret)
+		return ret;
+
+	printk(banner);
+
+	return 0;
+}
+
+static void __exit watchdog_exit(void)
+{
+	misc_deregister(&indydog_miscdev);
+}
+
+module_init(watchdog_init);
+module_exit(watchdog_exit);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/ip2/i2lib.c linux/drivers/char/ip2/i2lib.c
--- linux.orig/drivers/char/ip2/i2lib.c	2001-11-03 01:26:17.000000000 +0000
+++ linux/drivers/char/ip2/i2lib.c	2002-07-20 01:08:36.000000000 +0000
@@ -1330,7 +1330,7 @@
 
 	// if expires == 0 then timer poped, then do not need to del_timer
 	if ((timeout > 0) && pCh->BookmarkTimer.expires && 
-				(pCh->BookmarkTimer.expires > jiffies)) {
+	                     time_before(jiffies, pCh->BookmarkTimer.expires)) {
 		del_timer( &(pCh->BookmarkTimer) );
 		pCh->BookmarkTimer.expires = 0;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/isicom.c linux/drivers/char/isicom.c
--- linux.orig/drivers/char/isicom.c	2001-11-09 22:01:21.000000000 +0000
+++ linux/drivers/char/isicom.c	2002-07-20 01:08:23.000000000 +0000
@@ -123,7 +123,7 @@
 };
 
  
-extern inline int WaitTillCardIsFree(unsigned short base)
+static inline int WaitTillCardIsFree(unsigned short base)
 {
 	unsigned long count=0;
 	while( (!(inw(base+0xe) & 0x1)) && (count++ < 6000000));
@@ -359,7 +359,7 @@
 	return 0;
 }
 			
-extern inline void schedule_bh(struct isi_port * port)
+static inline void schedule_bh(struct isi_port * port)
 {
 	queue_task(&port->bh_tqueue, &tq_isicom);
 	mark_bh(ISICOM_BH);
@@ -824,7 +824,7 @@
  
 /* open et all */ 
 
-extern inline void isicom_setup_board(struct isi_board * bp)
+static inline void isicom_setup_board(struct isi_board * bp)
 {
 	int channel;
 	struct isi_port * port;
@@ -1092,7 +1092,7 @@
  
 /* close et all */
 
-extern inline void isicom_shutdown_board(struct isi_board * bp)
+static inline void isicom_shutdown_board(struct isi_board * bp)
 {
 	int channel;
 	struct isi_port * port;
@@ -1350,7 +1350,7 @@
 }
 
 /* ioctl et all */
-extern inline void isicom_send_break(struct isi_port * port, unsigned long length)
+static inline void isicom_send_break(struct isi_port * port, unsigned long length)
 {
 	struct isi_board * card = port->card;
 	short wait = 10;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/istallion.c linux/drivers/char/istallion.c
--- linux.orig/drivers/char/istallion.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/char/istallion.c	2002-07-20 01:08:24.000000000 +0000
@@ -2022,7 +2022,8 @@
 	printk("stli_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
 #endif
 
-	copy_from_user(&sio, sp, sizeof(struct serial_struct));
+	if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
+		return -EFAULT;
 	if (!capable(CAP_SYS_ADMIN)) {
 		if ((sio.baud_base != portp->baud_base) ||
 		    (sio.close_delay != portp->close_delay) ||
@@ -4878,11 +4879,15 @@
 	while (size > 0) {
 		memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
 		n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
-		copy_to_user(buf, memptr, n);
+		if (copy_to_user(buf, memptr, n)) {
+			count = -EFAULT;
+			goto out;
+		}
 		fp->f_pos += n;
 		buf += n;
 		size -= n;
 	}
+out:
 	EBRDDISABLE(brdp);
 	restore_flags(flags);
 
@@ -4930,11 +4935,15 @@
 	while (size > 0) {
 		memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
 		n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
-		copy_from_user(memptr, chbuf, n);
+		if (copy_from_user(memptr, chbuf, n)) {
+			count = -EFAULT;
+			goto out;
+		}
 		fp->f_pos += n;
 		chbuf += n;
 		size -= n;
 	}
+out:
 	EBRDDISABLE(brdp);
 	restore_flags(flags);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/joystick/a3d.c linux/drivers/char/joystick/a3d.c
--- linux.orig/drivers/char/joystick/a3d.c	2001-09-12 22:34:06.000000000 +0000
+++ linux/drivers/char/joystick/a3d.c	2002-07-20 01:08:21.000000000 +0000
@@ -190,7 +190,7 @@
 
 int a3d_adc_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-	struct a3d *a3d = gameport->private;
+	struct a3d *a3d = gameport->driver;
 	int i;
 	for (i = 0; i < 4; i++)
 		axes[i] = (a3d->axes[i] < 254) ? a3d->axes[i] : -1;
@@ -205,7 +205,7 @@
 
 int a3d_adc_open(struct gameport *gameport, int mode)
 {
-	struct a3d *a3d = gameport->private;
+	struct a3d *a3d = gameport->driver;
 	if (mode != GAMEPORT_MODE_COOKED)
 		return -1;
 	if (!a3d->used++)
@@ -219,7 +219,7 @@
 
 static void a3d_adc_close(struct gameport *gameport)
 {
-	struct a3d *a3d = gameport->private;
+	struct a3d *a3d = gameport->driver;
 	if (!--a3d->used)
 		del_timer(&a3d->timer);
 }
@@ -323,7 +323,7 @@
 		a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y);
 		a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE);
 
-		a3d->adc.private = a3d;
+		a3d->adc.driver = a3d;
 		a3d->adc.open = a3d_adc_open;
 		a3d->adc.close = a3d_adc_close;
 		a3d->adc.cooked_read = a3d_adc_cooked_read;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/joystick/lightning.c linux/drivers/char/joystick/lightning.c
--- linux.orig/drivers/char/joystick/lightning.c	2001-09-12 22:34:06.000000000 +0000
+++ linux/drivers/char/joystick/lightning.c	2002-07-20 01:08:32.000000000 +0000
@@ -77,7 +77,7 @@
 
 static int l4_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-	struct l4 *l4 = gameport->private;
+	struct l4 *l4 = gameport->driver;
 	unsigned char status;
 	int i, result = -1;
 
@@ -110,7 +110,7 @@
 
 static int l4_open(struct gameport *gameport, int mode)
 {
-	struct l4 *l4 = gameport->private;
+	struct l4 *l4 = gameport->driver;
         if (l4->port != 0 && mode != GAMEPORT_MODE_COOKED)
 		return -1;
 	outb(L4_SELECT_ANALOG, L4_PORT);
@@ -188,7 +188,7 @@
 {
 	int i, t;
 	int cal[4];
-	struct l4 *l4 = gameport->private;
+	struct l4 *l4 = gameport->driver;
 
 	if (l4_getcal(l4->port, cal))
 		return -1;
@@ -248,7 +248,7 @@
 			l4->port = i * 4 + j;
 
 			gameport = &l4->gameport;
-			gameport->private = l4;
+			gameport->driver = l4;
 			gameport->open = l4_open;
 			gameport->cooked_read = l4_cooked_read;
 			gameport->calibrate = l4_calibrate;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/joystick/pcigame.c linux/drivers/char/joystick/pcigame.c
--- linux.orig/drivers/char/joystick/pcigame.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/char/joystick/pcigame.c	2002-07-20 01:08:27.000000000 +0000
@@ -76,19 +76,19 @@
 
 static unsigned char pcigame_read(struct gameport *gameport)
 {
-	struct pcigame *pcigame = gameport->private;
+	struct pcigame *pcigame = gameport->driver;
 	return readb(pcigame->base + pcigame->data->legacy);
 }
 
 static void pcigame_trigger(struct gameport *gameport)
 {
-	struct pcigame *pcigame = gameport->private;
+	struct pcigame *pcigame = gameport->driver;
 	writeb(0xff, pcigame->base + pcigame->data->legacy);
 }
 
 static int pcigame_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-        struct pcigame *pcigame = gameport->private;
+        struct pcigame *pcigame = gameport->driver;
 	int i;
 
 	*buttons = (~readb(pcigame->base + pcigame->data->legacy) >> 4) & 0xf;
@@ -103,7 +103,7 @@
 
 static int pcigame_open(struct gameport *gameport, int mode)
 {
-	struct pcigame *pcigame = gameport->private;
+	struct pcigame *pcigame = gameport->driver;
 
 	switch (mode) {
 		case GAMEPORT_MODE_COOKED:
@@ -135,7 +135,7 @@
 	pcigame->dev = dev;
 	pci_set_drvdata(dev, pcigame);
 
-	pcigame->gameport.private = pcigame;
+	pcigame->gameport.driver = pcigame;
 	pcigame->gameport.fuzz = 64;
 	
 	pcigame->gameport.read = pcigame_read;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/keyboard.c linux/drivers/char/keyboard.c
--- linux.orig/drivers/char/keyboard.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/keyboard.c	2002-07-20 01:08:34.000000000 +0000
@@ -67,15 +67,8 @@
 
 extern void ctrl_alt_del(void);
 
-DECLARE_WAIT_QUEUE_HEAD(keypress_wait);
 struct console;
 
-int keyboard_wait_for_keypress(struct console *co)
-{
-	sleep_on(&keypress_wait);
-	return 0;
-}
-
 /*
  * global state includes the following, and various static variables
  * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
@@ -331,19 +324,32 @@
 	schedule_console_callback();
 }
 
+#ifdef CONFIG_FORWARD_KEYBOARD
+extern int forward_chars;
 
 void put_queue(int ch)
 {
-	wake_up(&keypress_wait);
+	if (forward_chars == fg_console+1){
+		kbd_forward_char (ch);
+	} else {
+		if (tty) {
+			tty_insert_flip_char(tty, ch, 0);
+			con_schedule_flip(tty);
+		}
+	}
+}
+#else
+void put_queue(int ch)
+{
 	if (tty) {
 		tty_insert_flip_char(tty, ch, 0);
 		con_schedule_flip(tty);
 	}
 }
+#endif
 
 static void puts_queue(char *cp)
 {
-	wake_up(&keypress_wait);
 	if (!tty)
 		return;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/lcd.c linux/drivers/char/lcd.c
--- linux.orig/drivers/char/lcd.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/lcd.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,632 @@
+/*
+ * LCD, LED and Button interface for Cobalt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997 by Andrew Bose
+ *
+ * Linux kernel version history:
+ *       March 2001: Ported from 2.0.34  by Liam Davies
+ *
+ */
+
+#define RTC_IO_EXTENT	0x10    /*Only really two ports, but...	*/
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/mc146818rtc.h>
+#include <linux/netdevice.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+
+#include "lcd.h"
+
+static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 
+                     unsigned long arg);
+
+static int lcd_present = 1;
+
+int led_state = 0;
+
+#if defined(CONFIG_TULIP) && 0
+
+#define MAX_INTERFACES	8
+static linkcheck_func_t linkcheck_callbacks[MAX_INTERFACES];
+static void *linkcheck_cookies[MAX_INTERFACES];
+
+int lcd_register_linkcheck_func(int iface_num, void *func, void *cookie)
+{
+	if (iface_num < 0 ||
+	    iface_num >= MAX_INTERFACES ||
+	    linkcheck_callbacks[iface_num] != NULL)
+		return -1;
+	linkcheck_callbacks[iface_num] = (linkcheck_func_t) func;
+	linkcheck_cookies[iface_num] = cookie;
+	return 0;
+}
+#endif
+
+static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 
+			unsigned long arg)
+{
+	struct lcd_display button_display;
+	unsigned long address, a;
+	int index;
+
+	switch (cmd) {
+	case LCD_On:
+		udelay(150);
+		BusyCheck();
+		LCDWriteInst(0x0F);
+		break;		
+
+	case LCD_Off:
+		udelay(150);
+		BusyCheck();
+		LCDWriteInst(0x08);
+		break;
+
+	case LCD_Reset:
+		udelay(150);
+		LCDWriteInst(0x3F);
+		udelay(150);
+		LCDWriteInst(0x3F);
+		udelay(150);
+		LCDWriteInst(0x3F);
+		udelay(150);
+		LCDWriteInst(0x3F);
+		udelay(150);
+		LCDWriteInst(0x01);
+		udelay(150);
+		LCDWriteInst(0x06);
+		break;
+
+	case LCD_Clear:
+		udelay(150);
+		BusyCheck();
+       		LCDWriteInst(0x01);     
+		break;
+
+	case LCD_Cursor_Left:
+		udelay(150);
+		BusyCheck();
+		LCDWriteInst(0x10);
+		break;
+
+	case LCD_Cursor_Right:
+		udelay(150);
+		BusyCheck();
+		LCDWriteInst(0x14);
+		break;	
+
+	case LCD_Cursor_Off:
+		udelay(150);
+                BusyCheck();
+                LCDWriteInst(0x0C);
+	        break;
+
+        case LCD_Cursor_On:
+                udelay(150);
+                BusyCheck();
+                LCDWriteInst(0x0F);
+                break;
+
+        case LCD_Blink_Off:
+                udelay(150);
+                BusyCheck();
+                LCDWriteInst(0x0E);
+                break;
+
+	case LCD_Get_Cursor_Pos:{
+                struct lcd_display display;
+
+		udelay(150);
+                BusyCheck();
+		display.cursor_address = ( LCDReadInst ); 
+		display.cursor_address = ( display.cursor_address & 0x07F );
+		if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display)))
+		  return -EFAULT;
+
+		break;
+		}
+
+
+	case LCD_Set_Cursor_Pos: {
+                struct lcd_display display;
+
+                if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display)))
+		  return -EFAULT;
+
+		a = (display.cursor_address | kLCD_Addr ); 
+
+                udelay(150);
+                BusyCheck();    
+                LCDWriteInst( a );
+
+                break;
+		}
+	
+	case LCD_Get_Cursor: {
+                struct lcd_display display;
+
+                udelay(150);
+                BusyCheck();    
+		display.character = LCDReadData;	
+
+		if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display)))
+		  return -EFAULT;
+                udelay(150);
+                BusyCheck();
+                LCDWriteInst(0x10);
+
+		break;
+		}
+
+	case LCD_Set_Cursor:{
+                struct lcd_display display;
+   
+                if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display)))
+		  return -EFAULT;
+
+                udelay(150);
+		BusyCheck();    
+                LCDWriteData( display.character );
+                udelay(150);
+                BusyCheck();
+                LCDWriteInst(0x10);
+
+                break;
+                }
+
+
+	case LCD_Disp_Left:
+		udelay(150);
+		BusyCheck();
+		LCDWriteInst(0x18);
+		break;
+
+	case LCD_Disp_Right:
+		udelay(150);
+		BusyCheck();
+		LCDWriteInst(0x1C);
+		break;
+
+	case LCD_Home:
+		udelay(150);
+		BusyCheck();
+		LCDWriteInst(0x02);
+		break;
+
+	case LCD_Write: {
+		struct lcd_display display;
+   
+
+                if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display)))
+		  return -EFAULT;
+ 
+		udelay(150);
+                BusyCheck();    
+                LCDWriteInst(0x80);
+		udelay(150);
+		BusyCheck();
+	
+		for (index = 0; index < (display.size1); index++) {
+			udelay(150);
+			BusyCheck();	
+			LCDWriteData( display.line1[index]);
+			BusyCheck();	
+		}		
+		
+		udelay(150);
+		BusyCheck();	
+		LCDWriteInst(0xC0);	
+		udelay(150);
+		BusyCheck();	
+                for (index = 0; index < (display.size2); index++) {
+                        udelay(150);
+                        BusyCheck();    
+                        LCDWriteData( display.line2[index]);
+		}
+ 
+		break;	
+	}
+	
+	case LCD_Read: {	
+        	struct lcd_display display;
+
+		BusyCheck();
+		for (address = kDD_R00; address <= kDD_R01; address++) {
+			a = (address | kLCD_Addr );	
+
+			udelay(150);
+			BusyCheck();
+			LCDWriteInst( a );
+			udelay(150);
+			BusyCheck();
+			display.line1[address] = LCDReadData;
+		}
+
+		display.line1[ 0x27 ] = '\0';
+	
+		for (address = kDD_R10; address <= kDD_R11; address++) {
+			a = (address | kLCD_Addr );     
+        
+			udelay(150);
+	 		BusyCheck();
+        		LCDWriteInst( a );
+       
+        		udelay(150);
+	 		BusyCheck();
+        		display.line2[address - 0x40 ] = LCDReadData;
+		 }
+
+		display.line2[ 0x27 ] = '\0';
+
+		if(copy_to_user((struct lcd_display*)arg, &display,
+				sizeof(struct lcd_display)))
+		  return -EFAULT;
+		break;
+	}
+
+//  set all GPIO leds to led_display.leds 
+
+	case LED_Set: {	
+		struct lcd_display led_display;
+	
+
+	        if(copy_from_user(&led_display, (struct lcd_display*)arg,
+				  sizeof(struct lcd_display)))
+		  return -EFAULT;
+
+		led_state = led_display.leds;
+		LEDSet(led_state);
+
+        	break;
+	}
+
+
+//  set only bit led_display.leds
+
+        case LED_Bit_Set: {
+                int i;
+		int bit=1;
+                struct lcd_display led_display;
+
+
+                if(copy_from_user(&led_display, (struct lcd_display*)arg,
+				  sizeof(struct lcd_display)))
+		  return -EFAULT;
+
+		for (i=0;i<(int)led_display.leds;i++)
+			{
+				bit = 2*bit;	
+			}
+
+		led_state = led_state | bit;
+                LEDSet(led_state);
+                break;
+        }
+
+//  clear only bit led_display.leds
+
+        case LED_Bit_Clear: {
+                int i;
+		int bit=1;
+                struct lcd_display led_display;
+
+
+                if(copy_from_user(&led_display, (struct lcd_display*)arg,
+				  sizeof(struct lcd_display)))
+		  return -EFAULT;
+
+                for (i=0;i<(int)led_display.leds;i++)
+                        {
+                                bit = 2*bit;
+                        }
+
+		led_state = led_state &  ~bit;
+                LEDSet(led_state);
+                break;
+        }
+
+
+	case BUTTON_Read: {
+		button_display.buttons = GPIRead;
+                if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display)))
+		  return -EFAULT;
+		break;
+	}
+
+        case LINK_Check: {
+                button_display.buttons = *((volatile unsigned long *) (0xB0100060) );
+                if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display)))
+		  return -EFAULT;
+                break;
+        }
+
+	case LINK_Check_2: {
+		int iface_num;
+
+		/* panel-utils should pass in the desired interface status is wanted for
+		 * in "buttons" of the structure.  We will set this to non-zero if the
+		 * link is in fact up for the requested interface.  --DaveM
+		 */
+		if(copy_from_user(&button_display, (struct lcd_display *)arg, sizeof(button_display)))
+		  return -EFAULT;
+		iface_num = button_display.buttons;
+#if defined(CONFIG_TULIP) && 0
+		if (iface_num >= 0 &&
+		    iface_num < MAX_INTERFACES &&
+		    linkcheck_callbacks[iface_num] != NULL) {
+			button_display.buttons =
+				linkcheck_callbacks[iface_num](linkcheck_cookies[iface_num]);
+		} else
+#endif
+			button_display.buttons = 0;
+
+                if(__copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display)))
+		  return -EFAULT;
+                break;
+	}
+
+//  Erase the flash
+
+	case FLASH_Erase: {
+
+		int ctr=0;
+
+		    // Chip Erase Sequence
+		WRITE_FLASH( kFlash_Addr1, kFlash_Data1 );
+		WRITE_FLASH( kFlash_Addr2, kFlash_Data2 );
+		WRITE_FLASH( kFlash_Addr1, kFlash_Erase3 );
+		WRITE_FLASH( kFlash_Addr1, kFlash_Data1 );
+		WRITE_FLASH( kFlash_Addr2, kFlash_Data2 );
+		WRITE_FLASH( kFlash_Addr1, kFlash_Erase6 );
+
+		printk( "Erasing Flash.\n");
+
+		while ( (!dqpoll(0x00000000,0xFF)) && (!timeout(0x00000000)) ) {
+		    ctr++;
+		}
+
+		printk("\n");
+		printk("\n");
+		printk("\n");
+
+		if (READ_FLASH(0x07FFF0)==0xFF) { printk("Erase Successful\r\n"); }
+		else if (timeout) { printk("Erase Timed Out\r\n"); }
+
+	break;
+	}
+
+// burn the flash 
+
+	case FLASH_Burn: {
+
+		volatile unsigned long burn_addr;
+		unsigned long flags;
+		int i;
+		unsigned char *rom;
+		
+
+                struct lcd_display display;
+
+                if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display)))
+		  return -EFAULT;
+		rom = (unsigned char *) kmalloc((128),GFP_ATOMIC);
+                if ( rom == NULL ) {
+                       printk ("broken\n");
+                       return 1;
+                   }
+
+		printk("Churning and Burning -");
+		save_flags(flags);
+		for (i=0; i<FLASH_SIZE; i=i+128) {
+
+		        if(copy_from_user(rom, display.RomImage + i, 128))
+			   return -EFAULT;
+			burn_addr = kFlashBase + i;
+			cli();
+			for ( index = 0; index < ( 128 ) ; index++ ) 
+		  	  {
+
+				WRITE_FLASH( kFlash_Addr1, kFlash_Data1 );
+		 	    	WRITE_FLASH( kFlash_Addr2, kFlash_Data2 );
+		 	    	WRITE_FLASH( kFlash_Addr1, kFlash_Prog );
+		 	    	*((volatile unsigned char *)burn_addr) = (volatile unsigned char) rom[index];
+
+		   	 	 while ( (!dqpoll(burn_addr,(volatile unsigned char) rom[index])) && (!timeout(burn_addr)) ) {
+		  	   		}
+		  	   	burn_addr++;
+		  	  }
+			restore_flags(flags);
+                	if ( *((volatile unsigned char *)(burn_addr-1)) == (volatile unsigned char) rom[index-1]  ) {
+               		 } else if (timeout) {
+                	    printk("Program timed out\r\n");
+               		 }
+
+
+		}
+		kfree(rom);
+
+	break;
+	}
+
+//  read the flash all at once 
+	
+	case FLASH_Read: {
+
+		unsigned char *user_bytes;
+                volatile unsigned long read_addr;
+                int i;
+
+		user_bytes = &(((struct lcd_display *)arg)->RomImage[0]);
+
+		if(!access_ok(VERIFY_WRITE, user_bytes, FLASH_SIZE))
+                         return -EFAULT;
+
+		printk("Reading Flash");
+		for (i=0; i<FLASH_SIZE; i++) {
+			unsigned char tmp_byte;
+			read_addr = kFlashBase + i;
+			tmp_byte = *((volatile unsigned char *)read_addr);
+			if(__put_user (tmp_byte, &user_bytes[i]))
+			  return -EFAULT;
+		}
+
+
+	break;
+	}
+
+
+
+
+
+	default:
+		return 0;
+	break;
+
+	}
+
+	return 0;
+
+}
+
+static int lcd_open(struct inode *inode, struct file *file)
+{
+	if (!lcd_present)
+		return -ENXIO;
+	else
+		return 0;
+}
+
+/* Only RESET or NEXT counts as button pressed */
+
+static inline int button_pressed(void)
+{
+	unsigned long buttons = GPIRead;
+
+	if ( (buttons == BUTTON_Next) || (buttons == BUTTON_Next_B) || (buttons == BUTTON_Reset_B) )
+		return buttons;
+	return 0;
+}
+
+/* LED daemon sits on this and we wake him up once a key is pressed. */
+
+static int lcd_waiters = 0;
+
+static long lcd_read(struct inode *inode, struct file *file, char *buf, unsigned long count)
+{
+	long buttons_now;
+
+	if(lcd_waiters > 0)
+		return -EINVAL;
+
+	lcd_waiters++;
+	while(((buttons_now = (long)button_pressed()) == 0) &&
+	      !(signal_pending(current))) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(2 * HZ);
+	}
+	lcd_waiters--;
+
+	if(signal_pending(current))
+		return -ERESTARTSYS;
+	return buttons_now;
+}
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations lcd_fops = {
+	read:		lcd_read,
+	ioctl:		lcd_ioctl,
+	open:		lcd_open,
+};
+
+static struct miscdevice lcd_dev=
+{
+	LCD_MINOR,
+	"lcd",
+	&lcd_fops
+};
+
+int lcd_init(void)
+{
+unsigned long data;
+
+	printk("%s\n", LCD_DRIVER);
+	misc_register(&lcd_dev);
+
+	/* Check region? Naaah! Just snarf it up. */
+/*	request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/
+
+	udelay(150);
+	data = LCDReadData;
+	if ( (data & 0x000000FF) == (0x00) ) {
+		lcd_present = 0;
+		printk("LCD Not Present\n");
+	        }
+	else {
+		lcd_present = 1;
+		WRITE_GAL( kGal_DevBank2PReg, kGal_DevBank2Cfg );
+		WRITE_GAL( kGal_DevBank3PReg, kGal_DevBank3Cfg );
+		}
+
+	return 0;
+}
+
+
+//
+// Function: dqpoll
+//
+// Description:  Polls the data lines to see if the flash is busy
+//
+// In: address, byte data
+//
+// Out: 0 = busy, 1 = write or erase complete
+//
+//
+
+int dqpoll( volatile unsigned long address, volatile unsigned char data ) {
+
+volatile unsigned char dq7;
+
+dq7 = data & 0x80;
+
+return ( (READ_FLASH(address) & 0x80) == dq7  );
+
+}
+
+
+//
+// Function: timeout
+//
+// Description: Checks to see if erase or write has timed out
+//              By polling dq5
+//
+// In: address
+//
+//
+// Out: 0 = not timed out, 1 = timed out
+
+int timeout( volatile unsigned long address ) {
+
+
+return (  (READ_FLASH(address) & 0x20) ==  0x20 );
+
+}
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/lcd.h linux/drivers/char/lcd.h
--- linux.orig/drivers/char/lcd.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/lcd.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,184 @@
+/*
+ * LED, LCD and Button panel driver for Cobalt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997 by Andrew Bose
+ *
+ * Linux kernel version history:
+ *       March 2001: Ported from 2.0.34  by Liam Davies
+ *
+ */
+
+// function headers
+
+int dqpoll( volatile unsigned long, volatile unsigned char );
+int timeout( volatile unsigned long );
+
+#define LCD_CHARS_PER_LINE 40
+#define FLASH_SIZE 524288
+#define MAX_IDLE_TIME 120
+
+struct lcd_display {
+        unsigned long buttons;
+        int size1;
+        int size2;
+        unsigned char line1[LCD_CHARS_PER_LINE];
+        unsigned char line2[LCD_CHARS_PER_LINE];
+        unsigned char cursor_address;
+        unsigned char character;
+        unsigned char leds;
+        unsigned char *RomImage;
+};
+
+
+
+#define LCD_DRIVER	"Cobalt LCD Driver v2.10"
+
+#define kLCD_IR		0xBF000000
+#define kLCD_DR		0xBF000010
+#define kGPI            0xBD000000
+#define kLED		0xBC000000
+
+#define kDD_R00         0x00
+#define kDD_R01         0x27
+#define kDD_R10         0x40
+#define kDD_R11         0x67
+
+#define kLCD_Addr       0x00000080
+
+#define LCDTimeoutValue	0xfff
+
+
+// Flash definitions AMD 29F040
+#define kFlashBase      0xBFC00000
+
+#define kFlash_Addr1    0x5555
+#define kFlash_Addr2    0x2AAA
+#define kFlash_Data1    0xAA
+#define kFlash_Data2    0x55
+#define kFlash_Prog     0xA0
+#define kFlash_Erase3   0x80
+#define kFlash_Erase6   0x10
+#define kFlash_Read     0xF0
+
+#define kFlash_ID       0x90
+#define kFlash_VenAddr  0x00
+#define kFlash_DevAddr  0x01
+#define kFlash_VenID    0x01
+#define kFlash_DevID    0xA4    // 29F040
+//#define kFlash_DevID  0xAD    // 29F016
+
+
+// Macros
+
+#define LCDWriteData(x)	(*(volatile unsigned long *) kLCD_DR) = (x << 24)
+#define LCDWriteInst(x)	(*(volatile unsigned long *) kLCD_IR) = (x << 24)
+
+#define LCDReadData	(((*(volatile unsigned long *) kLCD_DR) >> 24))
+#define LCDReadInst	(((*(volatile unsigned long *) kLCD_IR) >> 24))
+
+#define GPIRead         (( (*(volatile unsigned long *) kGPI) >> 24))
+
+#define LEDSet(x)	(*(volatile unsigned char *) kLED) = ((char)x)
+
+#define WRITE_GAL(x,y)  (*((volatile unsigned long *) (0xB4000000 | (x)) ) =y)
+#define BusyCheck()     while ((LCDReadInst & 0x80) == 0x80)
+
+#define WRITE_FLASH(x,y)  (*((volatile unsigned char *) (kFlashBase | (x)) ) = y)
+#define READ_FLASH(x)     *((volatile unsigned char *) (kFlashBase | (x)) )
+
+
+
+/* 
+ * Function command codes for io_ctl.
+ */
+#define LCD_On			1
+#define LCD_Off			2
+#define LCD_Clear		3
+#define LCD_Reset		4
+#define LCD_Cursor_Left		5
+#define LCD_Cursor_Right	6
+#define LCD_Disp_Left		7
+#define LCD_Disp_Right		8
+#define LCD_Get_Cursor		9
+#define LCD_Set_Cursor		10
+#define LCD_Home		11
+#define LCD_Read		12		
+#define LCD_Write		13	
+#define LCD_Cursor_Off		14
+#define LCD_Cursor_On		15
+#define LCD_Get_Cursor_Pos	16
+#define LCD_Set_Cursor_Pos	17
+#define LCD_Blink_Off           18
+
+#define LED_Set			40	
+#define LED_Bit_Set		41
+#define LED_Bit_Clear		42
+
+
+//  Button defs
+#define BUTTON_Read             50  
+
+//  Flash command codes
+#define FLASH_Erase		60
+#define FLASH_Burn		61
+#define FLASH_Read		62
+
+
+// Ethernet LINK check hackaroo
+#define LINK_Check              90
+#define LINK_Check_2		91
+
+//  Button patterns  _B - single layer lcd boards
+
+#define BUTTON_NONE               0x3F
+#define BUTTON_NONE_B             0xFE
+
+#define BUTTON_Left               0x3B
+#define BUTTON_Left_B             0xFA
+
+#define BUTTON_Right              0x37
+#define BUTTON_Right_B            0xDE
+
+#define BUTTON_Up                 0x2F
+#define BUTTON_Up_B               0xF6
+
+#define BUTTON_Down               0x1F
+#define BUTTON_Down_B             0xEE
+
+#define BUTTON_Next               0x3D
+#define BUTTON_Next_B             0x7E
+
+#define BUTTON_Enter              0x3E
+#define BUTTON_Enter_B            0xBE
+
+#define BUTTON_Reset_B            0xFC
+
+
+// debounce constants
+
+#define BUTTON_SENSE            160000
+#define BUTTON_DEBOUNCE		5000
+
+
+//  Galileo register stuff
+
+#define kGal_DevBank2Cfg        0x1466DB33
+#define kGal_DevBank2PReg       0x464
+#define kGal_DevBank3Cfg        0x146FDFFB
+#define kGal_DevBank3PReg       0x468
+
+// Network 
+
+#define kIPADDR			1
+#define kNETMASK		2
+#define kGATEWAY		3	
+#define kDNS			4
+
+#define kClassA			5
+#define kClassB			6
+#define kClassC			7
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/logibusmouse.c linux/drivers/char/logibusmouse.c
--- linux.orig/drivers/char/logibusmouse.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/char/logibusmouse.c	2002-07-20 01:08:39.000000000 +0000
@@ -128,25 +128,28 @@
 
 static int __init logi_busmouse_init(void)
 {
-	if (check_region(LOGIBM_BASE, LOGIBM_EXTENT))
+	if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "busmouse"))
 		return -EIO;
 
 	outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
 	outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
 	udelay(100L);	/* wait for reply from mouse */
-	if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE)
+	if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
+		release_region(LOGIBM_BASE, LOGIBM_EXTENT);
 		return -EIO;
+	}
 
 	outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
 	MSE_INT_OFF();
 	
-	request_region(LOGIBM_BASE, LOGIBM_EXTENT, "busmouse");
-
 	msedev = register_busmouse(&busmouse);
-	if (msedev < 0)
+	if (msedev < 0) {
+		release_region(LOGIBM_BASE, LOGIBM_EXTENT);
 		printk(KERN_WARNING "Unable to register busmouse driver.\n");
+	} 
 	else
 		printk(KERN_INFO "Logitech busmouse installed.\n");
+	
 	return msedev < 0 ? msedev : 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/lp.c linux/drivers/char/lp.c
--- linux.orig/drivers/char/lp.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/lp.c	2002-07-20 01:08:22.000000000 +0000
@@ -270,7 +270,7 @@
 	return error;
 }
 
-static int lp_wait_ready(int minor)
+static int lp_wait_ready(int minor, int nonblock)
 {
 	int error = 0;
 
@@ -281,7 +281,7 @@
 
 	do {
 		error = lp_check_status (minor);
-		if (error && (LP_F(minor) & LP_ABORT))
+		if (error && (nonblock || (LP_F(minor) & LP_ABORT)))
 			break;
 		if (signal_pending (current)) {
 			error = -EINTR;
@@ -300,6 +300,8 @@
 	ssize_t retv = 0;
 	ssize_t written;
 	size_t copy_size = count;
+	int nonblock = ((file->f_flags & O_NONBLOCK) ||
+			(LP_F(minor) & LP_ABORT));
 
 #ifdef LP_STATS
 	if (jiffies-lp_table[minor].lastcall > LP_TIME(minor))
@@ -326,9 +328,10 @@
 						     lp_table[minor].best_mode);
 
 	parport_set_timeout (lp_table[minor].dev,
-			     lp_table[minor].timeout);
+			     (nonblock ? PARPORT_INACTIVITY_O_NONBLOCK
+			      : lp_table[minor].timeout));
 
-	if ((retv = lp_wait_ready (minor)) == 0)
+	if ((retv = lp_wait_ready (minor, nonblock)) == 0)
 	do {
 		/* Write the data. */
 		written = parport_write (port, kbuf, copy_size);
@@ -354,12 +357,16 @@
 					   IEEE1284_MODE_COMPAT);
 			lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
 
-			error = lp_wait_ready (minor);
+			error = lp_wait_ready (minor, nonblock);
 
 			if (error) {
 				if (retv == 0)
 					retv = error;
 				break;
+			} else if (nonblock) {
+				if (retv == 0)
+					retv = -EAGAIN;
+				break;
 			}
 
 			parport_yield_blocking (lp_table[minor].dev);
@@ -407,6 +414,8 @@
 	struct parport *port = lp_table[minor].dev->port;
 	ssize_t retval = 0;
 	char *kbuf = lp_table[minor].lp_buffer;
+	int nonblock = ((file->f_flags & O_NONBLOCK) ||
+			(LP_F(minor) & LP_ABORT));
 
 	if (count > LP_BUFFER_SIZE)
 		count = LP_BUFFER_SIZE;
@@ -415,7 +424,54 @@
 		return -EINTR;
 
 	lp_claim_parport_or_block (&lp_table[minor]);
-	retval = parport_read (port, kbuf, count);
+
+	parport_set_timeout (lp_table[minor].dev,
+			     (nonblock ? PARPORT_INACTIVITY_O_NONBLOCK
+			      : lp_table[minor].timeout));
+
+	parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
+	if (parport_negotiate (lp_table[minor].dev->port,
+			       IEEE1284_MODE_NIBBLE)) {
+		retval = -EIO;
+		goto out;
+	}
+
+	while (retval == 0) {
+		retval = parport_read (port, kbuf, count);
+
+		if (retval > 0)
+			break;
+
+		if (nonblock) {
+			retval = -EAGAIN;
+			break;
+		}
+
+		/* Wait for data. */
+
+		if (lp_table[minor].dev->port->irq == PARPORT_IRQ_NONE) {
+			parport_negotiate (lp_table[minor].dev->port,
+					   IEEE1284_MODE_COMPAT);
+			lp_error (minor);
+			if (parport_negotiate (lp_table[minor].dev->port,
+					       IEEE1284_MODE_NIBBLE)) {
+				retval = -EIO;
+				goto out;
+			}
+		} else
+			interruptible_sleep_on_timeout (&lp_table[minor].waitq,
+							LP_TIMEOUT_POLLED);
+
+		if (signal_pending (current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+
+		if (current->need_resched)
+			schedule ();
+	}
+	parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
+ out:
 	lp_release_parport (&lp_table[minor]);
 
 	if (retval > 0 && copy_to_user (buf, kbuf, retval))
@@ -476,7 +532,6 @@
 		printk (KERN_INFO "lp%d: ECP mode\n", minor);
 		lp_table[minor].best_mode = IEEE1284_MODE_ECP;
 	} else {
-		printk (KERN_INFO "lp%d: compatibility mode\n", minor);
 		lp_table[minor].best_mode = IEEE1284_MODE_COMPAT;
 	}
 	/* Leave peripheral in compatibility mode */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/machzwd.c linux/drivers/char/machzwd.c
--- linux.orig/drivers/char/machzwd.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/char/machzwd.c	2002-07-20 01:08:27.000000000 +0000
@@ -348,20 +348,15 @@
 static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	unsigned long arg)
 {
-	int ret;
-		
 	switch(cmd){
 		case WDIOC_GETSUPPORT:
-			ret = copy_to_user((struct watchdog_info *)arg, 
-						&zf_info, sizeof(zf_info));
-			if(ret)
+			if (copy_to_user((struct watchdog_info *)arg, 
+					 &zf_info, sizeof(zf_info)))
 				return -EFAULT;
 			break;
 	  
 		case WDIOC_GETSTATUS:
-			ret = copy_to_user((int *)arg, &zf_is_open,
-								sizeof(int));
-			if(ret)
+			if (copy_to_user((int *)arg, &zf_is_open, sizeof(int)))
 				return -EFAULT;
 			break;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/mem.c linux/drivers/char/mem.c
--- linux.orig/drivers/char/mem.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/char/mem.c	2002-07-20 01:08:37.000000000 +0000
@@ -323,7 +323,7 @@
  	return virtr + wrote;
 }
 
-#if !defined(__mc68000__)
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 static ssize_t read_port(struct file * file, char * buf,
 			 size_t count, loff_t *ppos)
 {
@@ -550,7 +550,7 @@
 	write:		write_null,
 };
 
-#if !defined(__mc68000__)
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 static struct file_operations port_fops = {
 	llseek:		memory_lseek,
 	read:		read_port,
@@ -584,7 +584,7 @@
 		case 3:
 			filp->f_op = &null_fops;
 			break;
-#if !defined(__mc68000__)
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 		case 4:
 			filp->f_op = &port_fops;
 			break;
@@ -621,7 +621,9 @@
 	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
 	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
 	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
 	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
+#endif
 	{5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
 	{7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
 	{8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/misc.c linux/drivers/char/misc.c
--- linux.orig/drivers/char/misc.c	2001-11-03 01:46:47.000000000 +0000
+++ linux/drivers/char/misc.c	2002-07-20 01:08:33.000000000 +0000
@@ -76,6 +76,7 @@
 extern int pmu_device_init(void);
 extern int tosh_init(void);
 extern int i8k_init(void);
+extern int lcd_init(void);
 
 static int misc_read_proc(char *buf, char **start, off_t offset,
 			  int len, int *eof, void *private)
@@ -170,7 +171,7 @@
  
 int misc_register(struct miscdevice * misc)
 {
-	static devfs_handle_t devfs_handle;
+	static devfs_handle_t devfs_handle, dir;
 	struct miscdevice *c;
 	
 	if (misc->next || misc->prev)
@@ -201,11 +202,12 @@
 		misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
 	if (!devfs_handle)
 		devfs_handle = devfs_mk_dir (NULL, "misc", NULL);
+	dir = strchr (misc->name, '/') ? NULL : devfs_handle;
 	misc->devfs_handle =
-	    devfs_register (devfs_handle, misc->name, DEVFS_FL_NONE,
-			    MISC_MAJOR, misc->minor,
-			    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
-			    misc->fops, NULL);
+		devfs_register (dir, misc->name, DEVFS_FL_NONE,
+				MISC_MAJOR, misc->minor,
+				S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
+				misc->fops, NULL);
 
 	/*
 	 * Add it to the front, so that later devices can "override"
@@ -277,6 +279,9 @@
 #ifdef CONFIG_TOSHIBA
 	tosh_init();
 #endif
+#ifdef CONFIG_COBALT_LCD
+	lcd_init();
+#endif
 #ifdef CONFIG_I8K
 	i8k_init();
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/mk712.c linux/drivers/char/mk712.c
--- linux.orig/drivers/char/mk712.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/mk712.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,505 @@
+/* -*- c -*- --------------------------------------------------------- *
+ *
+ * linux/drivers/char/mk712.c
+ *
+ * Copyright 1999-2002 Transmeta 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
+ *
+ * This driver supports the MK712 touch screen.
+ * based on busmouse.c, pc_keyb.c, and other mouse drivers
+ *
+ * 1999-12-18: original version, Daniel Quinlan
+ * 1999-12-19: added anti-jitter code, report pen-up events, fixed mk712_poll
+ *             to use queue_empty, Nathan Laredo
+ * 1999-12-20: improved random point rejection, Nathan Laredo
+ * 2000-01-05: checked in new anti-jitter code, changed mouse protocol, fixed
+ *             queue code, added module options, other fixes, Daniel Quinlan
+ * 2002-03-15: Clean up for kernel merge <alan@redhat.com>
+ *	       Fixed multi open race, fixed memory checks, fixed resource
+ *	       allocation, fixed close/powerdown bug, switched to new init
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#define DEBUG(x)	x
+#define SQUARE(x)	((x)*(x))
+
+#define MK712_DEFAULT_IO 0x260		/* demo board: 0x200, 0x208, 0x300 */
+#define MK712_DEFAULT_IRQ 10		/* demo board: 10, 12, 14 or 15  */
+
+/* eight 8-bit registers */
+#define MK712_STATUS_LOW 0	/* READ */
+#define MK712_STATUS_HIGH 1	/* READ */
+#define MK712_X_LOW 2		/* READ */
+#define MK712_X_HIGH 3		/* READ */
+#define MK712_Y_LOW 4		/* READ */
+#define MK712_Y_HIGH 5		/* READ */
+#define MK712_CONTROL 6		/* R/W */
+#define MK712_RATE 7		/* R/W */
+
+/* status */
+#define	MK712_STATUS_TOUCH 0x10
+#define	MK712_CONVERSION_COMPLETE 0x80
+
+#define MK712_ENABLE_INT			0x01 /* enable interrupts */
+#define MK712_INT_ON_CONVERSION_COMPLETE	0x02 /* if bit 0 = 1 */
+#define MK712_INT_ON_CHANGE_IN_TOUCH_STATUS_A	0x04 /* if bit 0 = 1 */
+#define MK712_INT_ON_CHANGE_IN_TOUCH_STATUS_B	0x08 /* if bit 0 = 1 */
+#define MK712_ENABLE_PERIODIC_CONVERSIONS	0x10
+#define MK712_READ_ONE_POINT			0x20
+#define MK712_POWERDOWN_A			0x40
+#define MK712_POWERDOWN_B			0x80
+
+#define MK712_BUF_SIZE 256      /* a page */
+
+struct mk712_packet {
+        unsigned int header;
+        unsigned int x;
+        unsigned int y;
+        unsigned int reserved;
+};
+
+struct mk712_queue {
+	unsigned long head;
+	unsigned long tail;
+	wait_queue_head_t proc_list;
+	struct fasync_struct *fasync;
+	struct mk712_packet buf[256];
+};
+
+#ifdef MODULE
+static int io = 0;
+static int irq = 0;
+#endif
+static int mk712_io = MK712_DEFAULT_IO;
+static int mk712_irq = MK712_DEFAULT_IRQ;
+static int mk712_users = 0;
+static spinlock_t mk712_lock = SPIN_LOCK_UNLOCKED;
+static struct mk712_queue *queue; /* mouse data buffer */
+
+static struct mk712_packet get_from_queue(void)
+{
+	struct mk712_packet result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mk712_lock, flags);
+	result = queue->buf[queue->tail];
+	queue->tail = (queue->tail + 1) & (MK712_BUF_SIZE-1);
+	spin_unlock_irqrestore(&mk712_lock, flags);
+	return result;
+}
+
+static inline int queue_empty(void)
+{
+	return queue->head == queue->tail;
+}
+
+static int mk712_fasync(int fd, struct file *filp, int on)
+{
+	int retval;
+
+	retval = fasync_helper(fd, filp, on, &queue->fasync);
+	if (retval < 0)
+		return retval;
+	return 0;
+}
+
+static void mk712_output_packet(struct mk712_packet data)
+{
+        int head = queue->head;
+
+        queue->buf[head] = data;
+        head = (head + 1) & (MK712_BUF_SIZE-1);
+        if (head != queue->tail) {
+                queue->head = head;
+                kill_fasync(&queue->fasync, SIGIO, POLL_IN);
+                wake_up_interruptible(&queue->proc_list);
+        }
+}
+
+static int points = 0;          /* number of stored points */
+static int output_point = 0;    /* did I output a point since last release? */
+
+static void mk712_output_point(int x, int y)
+{
+        struct mk712_packet t;
+
+        t.header = 0;
+        t.x = x;
+        t.y = y;
+        t.reserved = 0;
+
+        mk712_output_packet(t);
+        output_point = 1;
+}
+
+static void mk712_store_point(int x_new, int y_new)
+{
+        static int x[3], y[3];
+        int x_out, y_out;
+
+        x[points] = x_new;
+        y[points] = y_new;
+
+        if (points == 1 && abs(x[0] - x[1]) < 88 && abs(y[0] - y[1]) < 88)
+	{
+		x_out = (x[0] + x[1]) >> 1;
+                y_out = (y[0] + y[1]) >> 1;
+                mk712_output_point(x_out, y_out);
+        }
+
+        if (points == 2) {
+                if ((abs(x[1] - x[2]) < 88 && abs(y[1] - y[2]) < 88) &&
+                    (abs(x[0] - x[1]) < 88 && abs(y[0] - y[1]) < 88))
+                {
+                        x_out = (x[0] + x[1] + x[2]) / 3;
+                        y_out = (y[0] + y[1] + y[2]) / 3;
+                        mk712_output_point(x_out, y_out);
+                }
+                else if (abs(x[1] - x[2]) < 88 && abs(y[1] - y[2]) < 88)
+                {
+                        x_out = (x[1] + x[2]) >> 1;
+                        y_out = (y[1] + y[2]) >> 1;
+                        mk712_output_point(x_out, y_out);
+                }
+                else
+                {
+                        int x_avg, y_avg, d0, d1, d2;
+
+                        x_avg = (x[0] + x[1] + x[2]) / 3;
+                        y_avg = (y[0] + y[1] + y[2]) / 3;
+
+                        d0 = SQUARE(x[0] - x_avg) + SQUARE(y[0] - y_avg);
+                        d1 = SQUARE(x[1] - x_avg) + SQUARE(y[1] - y_avg);
+                        d2 = SQUARE(x[2] - x_avg) + SQUARE(y[2] - y_avg);
+
+                        if (d2 > d1 && d2 > d0)
+			{
+                                x_out = (x[0] + x[1]) >> 1;
+                                y_out = (y[0] + y[1]) >> 1;
+                        }
+                        if (d1 > d0 && d1 > d2)
+			{
+                                x_out = (x[0] + x[2]) >> 1;
+                                y_out = (y[0] + y[2]) >> 1;
+                        }
+                        else
+                        {
+                                x_out = (x[1] + x[2]) >> 1;
+                                y_out = (y[1] + y[2]) >> 1;
+                        }
+
+                        mk712_output_point(x_out, y_out);
+
+                        x[0] = x[1];
+                        x[1] = x[2];
+                        y[0] = y[1];
+                        y[1] = y[2];
+                }
+        }
+        else
+	{
+                points++;
+        }
+}
+
+static void mk712_release_event(void)
+{
+        struct mk712_packet t;
+
+        if (!output_point) {
+                points = 0;
+                return;
+        }
+        output_point = 0;
+
+        t.header = 1;
+        t.x = t.y = t.reserved = 0;
+
+        mk712_output_packet(t);
+        points = 0;
+}
+
+#define MK712_FILTER
+static void mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned short x;
+	unsigned short y;
+        unsigned char status;
+	unsigned long flags;
+#ifdef MK712_FILTER
+        static int drop_next = 1;
+#endif
+
+	spin_lock_irqsave(&mk712_lock, flags);
+
+        status = inb(mk712_io + MK712_STATUS_LOW);
+
+	if (!(status & MK712_CONVERSION_COMPLETE)) {
+#ifdef MK712_FILTER
+                drop_next = 1;
+#endif
+		return;
+	}
+	if (!(status & MK712_STATUS_TOUCH))	/* release event */
+	{
+#ifdef MK712_FILTER
+                drop_next = 1;
+#endif
+                mk712_release_event();
+
+                spin_unlock_irqrestore(&mk712_lock, flags);
+                wake_up_interruptible(&queue->proc_list);
+
+		return;
+	}
+
+        x = inw(mk712_io + MK712_X_LOW) & 0x0fff;
+        y = inw(mk712_io + MK712_Y_LOW) & 0x0fff;
+
+#ifdef MK712_FILTER
+        if (drop_next)
+        {
+                drop_next = 0;
+
+                spin_unlock_irqrestore(&mk712_lock, flags);
+                wake_up_interruptible(&queue->proc_list);
+
+                return;
+        }
+#endif
+
+        x = inw(mk712_io + MK712_X_LOW) & 0x0fff;
+	y = inw(mk712_io + MK712_Y_LOW) & 0x0fff;
+
+        mk712_store_point(x, y);
+
+        spin_unlock_irqrestore(&mk712_lock, flags);
+        wake_up_interruptible(&queue->proc_list);
+}
+
+static int mk712_open(struct inode *inode, struct file *file) 
+{
+	unsigned char control;
+	unsigned long flags;
+
+	control = 0;
+
+	spin_lock_irqsave(&mk712_lock, flags);
+	if(!mk712_users++)
+	{
+		outb(0, mk712_io + MK712_CONTROL);
+
+		control |= (MK712_ENABLE_INT |
+	                    MK712_INT_ON_CONVERSION_COMPLETE |
+	                    MK712_INT_ON_CHANGE_IN_TOUCH_STATUS_B |
+	                    MK712_ENABLE_PERIODIC_CONVERSIONS |
+	                    MK712_POWERDOWN_A);
+		outb(control, mk712_io + MK712_CONTROL);
+
+	        outb(10, mk712_io + MK712_RATE); /* default count = 10 */
+
+		queue->head = queue->tail = 0;          /* Flush input queue */
+	}
+	spin_unlock_irqrestore(&mk712_lock, flags);
+	return 0;
+}
+
+static int mk712_close(struct inode * inode, struct file * file) {
+        /* power down controller */
+        unsigned long flags;
+        spin_lock_irqsave(&mk712_lock, flags);
+	if(--mk712_users==0)
+		outb(0, mk712_io + MK712_CONTROL);
+	spin_unlock_irqrestore(&mk712_lock, flags);
+	return 0;
+}
+
+static unsigned int mk712_poll(struct file *file, poll_table *wait)
+{
+	poll_wait(file, &queue->proc_list, wait);
+	if(!queue_empty())
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static int mk712_ioctl(struct inode *inode, struct file * file,
+	unsigned int cmd, unsigned long arg)
+{
+	if (!inode)
+		BUG();
+	return -ENOTTY;
+}
+
+
+static ssize_t mk712_read(struct file *file, char *buffer,
+			  size_t count, loff_t *pos)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t bytes_read = 0;
+	struct mk712_packet p;
+
+	/* wait for an event */
+	if (queue_empty()) {
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		add_wait_queue(&queue->proc_list, &wait);
+repeat:
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (queue_empty() && !signal_pending(current)) {
+			schedule();
+			goto repeat;
+		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&queue->proc_list, &wait);
+	}
+
+	while (bytes_read < count && !queue_empty()) {
+		p = get_from_queue();
+		if (copy_to_user (buffer+bytes_read, (void *) &p, sizeof(p)))
+		{
+			bytes_read = -EFAULT;
+			break;
+		}
+		bytes_read += sizeof(p);
+	}
+
+        if (bytes_read > 0)
+        {
+                file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+                return bytes_read;
+        }
+
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+
+	return bytes_read;
+}
+
+static ssize_t mk712_write(struct file *file, const char *buffer, size_t count,
+			   loff_t *ppos)
+{
+	return -EINVAL;
+}
+
+struct file_operations mk712_fops = {
+	owner: THIS_MODULE,
+	read: mk712_read,
+	write: mk712_write,
+	poll: mk712_poll,
+	ioctl: mk712_ioctl,
+	open: mk712_open,
+	release: mk712_close,
+	fasync: mk712_fasync,
+};
+
+static struct miscdevice mk712_touchscreen = {
+	MK712_MINOR, "mk712_touchscreen", &mk712_fops
+};
+
+int __init mk712_init(void)
+{
+#ifdef MODULE
+        if (io)
+                mk712_io = io;
+        if (irq)
+                mk712_irq = irq;
+#endif
+
+	if(request_region(mk712_io, 8, "mk712_touchscreen"))
+	{
+		printk("mk712: unable to get IO region\n");
+		return -ENODEV;
+	}
+
+	/* set up wait queue */
+	queue = (struct mk712_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+	if(queue == NULL)
+	{
+		release_region(mk712_io, 8);
+		return -ENOMEM;
+	}
+	memset(queue, 0, sizeof(*queue));
+	queue->head = queue->tail = 0;
+	init_waitqueue_head(&queue->proc_list);
+
+        /* The MK712 is ISA and hard-coded to a particular IRQ, so the
+           driver should keep the IRQ as long as it is loaded. */
+	if(request_irq(mk712_irq, mk712_interrupt, 0, "mk712_touchscreen",
+		       queue))
+	{
+		printk("mk712: unable to get IRQ\n");
+		release_region(mk712_io, 8);
+		kfree(queue);
+		return -EBUSY;
+	}
+
+        /* register misc device */
+	if(misc_register(&mk712_touchscreen)<0)
+	{
+		release_region(mk712_io, 8);
+		kfree(queue);
+		free_irq(mk712_irq, queue);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static void __exit mk712_exit(void)
+{
+	misc_deregister(&mk712_touchscreen);
+	release_region(mk712_io, 8);
+	free_irq(mk712_irq, queue);
+	kfree(queue);
+	printk(KERN_INFO "mk712 touchscreen uninstalled\n");
+}
+
+MODULE_AUTHOR("Daniel Quinlan");
+MODULE_DESCRIPTION("MK712 touch screen driver");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O base address of MK712 touch screen controller");
+MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(irq, "IRQ of MK712 touch screen controller");
+MODULE_LICENSE("GPL");
+
+module_init(mk712_init);
+module_exit(mk712_exit);
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c
--- linux.orig/drivers/char/msbusmouse.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/char/msbusmouse.c	2002-07-20 01:08:39.000000000 +0000
@@ -149,11 +149,15 @@
 	}
 	if (present == 0)
 		return -EIO;
+	if (!request_region(MS_MSE_CONTROL_PORT, 0x04, "MS Busmouse"))
+		return -EIO;
+	
 	MS_MSE_INT_OFF();
-	request_region(MS_MSE_CONTROL_PORT, 0x04, "MS Busmouse");
 	msedev = register_busmouse(&msbusmouse);
-	if (msedev < 0)
+	if (msedev < 0) {
 		printk(KERN_WARNING "Unable to register msbusmouse driver.\n");
+		release_region(MS_MSE_CONTROL_PORT, 0x04);
+	}
 	else
 		printk(KERN_INFO "Microsoft BusMouse detected and installed.\n");
 	return msedev < 0 ? msedev : 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/mxser.c linux/drivers/char/mxser.c
--- linux.orig/drivers/char/mxser.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/mxser.c	2002-07-20 01:08:26.000000000 +0000
@@ -32,6 +32,9 @@
  *      version         : 1.2 
  *      
  *    Fixes for C104H/PCI by Tim Hockin <thockin@sun.com>
+ *    Added support for: C102, CI-132, CI-134, CP-132, CP-114, CT-114 cards
+ *                        by Damian Wrobel <dwrobel@ertel.com.pl>
+ *
  */
 
 #include <linux/config.h>
@@ -62,7 +65,7 @@
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
-#define		MXSER_VERSION			"1.2"
+#define		MXSER_VERSION			"1.2.1"
 
 #define		MXSERMAJOR	 	174
 #define		MXSERCUMAJOR		175
@@ -115,10 +118,22 @@
 #ifndef PCI_DEVICE_ID_C104
 #define PCI_DEVICE_ID_C104	0x1040
 #endif
+#ifndef PCI_DEVICE_ID_CP132
+#define PCI_DEVICE_ID_CP132	0x1320
+#endif
+#ifndef PCI_DEVICE_ID_CP114
+#define PCI_DEVICE_ID_CP114	0x1141
+#endif
+#ifndef PCI_DEVICE_ID_CT114
+#define PCI_DEVICE_ID_CT114	0x1140
+#endif
 
 #define C168_ASIC_ID    1
 #define C104_ASIC_ID    2
+#define CI134_ASIC_ID   3
+#define CI132_ASIC_ID   4
 #define CI104J_ASIC_ID  5
+#define C102_ASIC_ID	0xB
 
 enum {
 	MXSER_BOARD_C168_ISA = 0,
@@ -126,6 +141,12 @@
 	MXSER_BOARD_CI104J,
 	MXSER_BOARD_C168_PCI,
 	MXSER_BOARD_C104_PCI,
+	MXSER_BOARD_C102_ISA,
+	MXSER_BOARD_CI132,
+	MXSER_BOARD_CI134,
+	MXSER_BOARD_CP132_PCI,
+	MXSER_BOARD_CP114_PCI,
+	MXSER_BOARD_CT114_PCI
 };
 
 static char *mxser_brdname[] =
@@ -135,6 +156,12 @@
 	"CI-104J series",
 	"C168H/PCI series",
 	"C104H/PCI series",
+	"C102 series",
+	"CI-132 series",
+	"CI-134 series",
+	"CP-132 series",
+	"CP-114 series",
+	"CT-114 series"
 };
 
 static int mxser_numports[] =
@@ -144,6 +171,12 @@
 	4,
 	8,
 	4,
+	2,
+	2,
+	4,
+	2,
+	4,
+	4
 };
 
 /*
@@ -164,6 +197,12 @@
 	  MXSER_BOARD_C168_PCI },
 	{ PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
 	  MXSER_BOARD_C104_PCI },
+	{ PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP132, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  MXSER_BOARD_CP132_PCI },
+	{ PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP114, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  MXSER_BOARD_CP114_PCI },
+	{ PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CT114, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  MXSER_BOARD_CT114_PCI },
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
@@ -2137,8 +2176,7 @@
 	tmp.closing_wait = info->closing_wait;
 	tmp.custom_divisor = info->custom_divisor;
 	tmp.hub6 = 0;
-	copy_to_user(retinfo, &tmp, sizeof(*retinfo));
-	return (0);
+	return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
 }
 
 static int mxser_set_serial_info(struct mxser_struct *info,
@@ -2150,7 +2188,8 @@
 
 	if (!new_info || !info->base)
 		return (-EFAULT);
-	copy_from_user(&new_serial, new_info, sizeof(new_serial));
+	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+		return -EFAULT;
 
 	if ((new_serial.irq != info->irq) ||
 	    (new_serial.port != info->base) ||
@@ -2304,6 +2343,12 @@
 		hwconf->board_type = MXSER_BOARD_C168_ISA;
 	else if (id == C104_ASIC_ID)
 		hwconf->board_type = MXSER_BOARD_C104_ISA;
+	else if (id == C102_ASIC_ID)
+		hwconf->board_type = MXSER_BOARD_C102_ISA;
+	else if (id == CI132_ASIC_ID)
+		hwconf->board_type = MXSER_BOARD_CI132;
+	else if (id == CI134_ASIC_ID)
+		hwconf->board_type = MXSER_BOARD_CI134;
 	else if (id == CI104J_ASIC_ID)
 		hwconf->board_type = MXSER_BOARD_CI104J;
 	else
@@ -2415,7 +2460,8 @@
 	(void) inb(port);
 	restore_flags(flags);
 	id = inb(port + 1) & 0x1F;
-	if ((id != C168_ASIC_ID) && (id != C104_ASIC_ID) && (id != CI104J_ASIC_ID))
+	if ((id != C168_ASIC_ID) && (id != C104_ASIC_ID) && (id != CI104J_ASIC_ID) &&
+		(id != C102_ASIC_ID) &&	(id != CI132_ASIC_ID) && (id != CI134_ASIC_ID))
 		return (-1);
 	for (i = 0, j = 0; i < 4; i++) {
 		n = inb(port + 2);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/n_tty.c linux/drivers/char/n_tty.c
--- linux.orig/drivers/char/n_tty.c	2001-04-06 17:42:55.000000000 +0000
+++ linux/drivers/char/n_tty.c	2002-07-20 01:08:22.000000000 +0000
@@ -23,6 +23,11 @@
  * 2000/01/20   Fixed SMP locking on put_tty_queue using bits of 
  *		the patch by Andrew J. Kroll <ag784@freenet.buffalo.edu>
  *		who actually finally proved there really was a race.
+ *
+ * 2002/03/18   Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
+ *		waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
+ *		Also fixed a bug in BLOCKING mode where write_chan returns
+ *		EAGAIN
  */
 
 #include <linux/types.h>
@@ -711,6 +716,22 @@
 	return 0;
 }
 
+/*
+ * Required for the ptys, serial driver etc. since processes
+ * that attach themselves to the master and rely on ASYNC
+ * IO must be woken up
+ */
+
+static void n_tty_write_wakeup(struct tty_struct *tty)
+{
+	if (tty->fasync)
+	{
+ 		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+		kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
+	}
+	return;
+}
+
 static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 			      char *fp, int count)
 {
@@ -1157,6 +1178,8 @@
 			while (nr > 0) {
 				ssize_t num = opost_block(tty, b, nr);
 				if (num < 0) {
+					if (num == -EAGAIN)
+						break;
 					retval = num;
 					goto break_out;
 				}
@@ -1236,6 +1259,6 @@
 	normal_poll,		/* poll */
 	n_tty_receive_buf,	/* receive_buf */
 	n_tty_receive_room,	/* receive_room */
-	0			/* write_wakeup */
+	n_tty_write_wakeup	/* write_wakeup */
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/nvram.c linux/drivers/char/nvram.c
--- linux.orig/drivers/char/nvram.c	2001-09-14 21:40:00.000000000 +0000
+++ linux/drivers/char/nvram.c	2002-07-20 01:08:33.000000000 +0000
@@ -320,7 +320,7 @@
 		return( 0 );
 
 	  default:
-		return( -EINVAL );
+		return( -ENOTTY );
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- linux.orig/drivers/char/pc_keyb.c	2001-11-09 22:01:21.000000000 +0000
+++ linux/drivers/char/pc_keyb.c	2002-07-20 01:08:34.000000000 +0000
@@ -1215,3 +1215,43 @@
 }
 
 #endif /* CONFIG_PSMOUSE */
+
+
+static int blink_frequency = HZ/2;
+
+/* Tell the user who may be running in X and not see the console that we have 
+   panic'ed. This is to distingush panics from "real" lockups. 
+   Could in theory send the panic message as morse, but that is left as an
+   exercise for the reader.  */ 
+void panic_blink(void)
+{ 
+	static unsigned long last_jiffie;
+	static char led;
+	/* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is 
+	   different. */
+	if (!blink_frequency) 
+		return;
+	if (jiffies - last_jiffie > blink_frequency) {
+		led ^= 0x01 | 0x04;
+		while (kbd_read_status() & KBD_STAT_IBF) mdelay(1); 
+		kbd_write_output(KBD_CMD_SET_LEDS);
+		mdelay(1); 
+		while (kbd_read_status() & KBD_STAT_IBF) mdelay(1); 
+		mdelay(1); 
+		kbd_write_output(led);
+		last_jiffie = jiffies;
+	}
+}  
+
+static int __init panicblink_setup(char *str)
+{
+    int par;
+    if (get_option(&str,&par)) 
+	    blink_frequency = par*(1000/HZ);
+    return 1;
+}
+
+/* panicblink=0 disables the blinking as it caused problems with some console
+   switches. otherwise argument is ms of a blink period. */
+__setup("panicblink=", panicblink_setup);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/pcwd.c linux/drivers/char/pcwd.c
--- linux.orig/drivers/char/pcwd.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/char/pcwd.c	2002-07-20 01:08:24.000000000 +0000
@@ -40,55 +40,67 @@
  *		fairly useless proc entry.
  * 990610	removed said useless proc code for the merge <alan>
  * 000403	Removed last traces of proc code. <davej>
+ * 011214	Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com>
+ * 020210       Backported 2.5 open_allowed changes, and got rid of a useless
+ *              variable <rob@osinvestor.com>
+ *              Added timeout module option to override default
+ * 020306	Support the PCI version [Lindsay Harris <lindsay@bluegum.com>]
  */
 
+/*
+ *  A bells and whistles driver is available from http://www.pcwd.de/
+ */
 #include <linux/module.h>
 
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/timer.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-/*
- * These are the auto-probe addresses available.
- *
- * Revision A only uses ports 0x270 and 0x370.  Revision C introduced 0x350.
- * Revision A has an address range of 2 addresses, while Revision C has 3.
- */
-static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
-
-#define WD_VER                  "1.10 (06/05/99)"
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+
+#define WD_VER                  "1.13 (03/06/2002)"
+
+/*  Stuff for the PCI version  */
+#ifndef	PCI_VENDOR_ID_QUICKLOGIC
+#define	PCI_VENDOR_ID_QUICKLOGIC	0x11e3
+#endif
+#ifndef	PCI_DEVICE_ID_BERKSHIRE
+#define	PCI_DEVICE_ID_BERKSHIRE	0x5030
+#endif
 
 /*
- * It should be noted that PCWD_REVISION_B was removed because A and B
+ * It should be noted that PCWD_REV_B was removed because A and B
  * are essentially the same types of card, with the exception that B
  * has temperature reporting.  Since I didn't receive a Rev.B card,
  * the Rev.B card is not supported.  (It's a good thing too, as they
  * are no longer in production.)
  */
-#define	PCWD_REVISION_A		1
-#define	PCWD_REVISION_C		2
+#define	PCWD_REV_A	0
+#define	PCWD_REV_C	1
+#define	PCWD_REV_PCI	2
+
+static int timeout_val;
+static int timeout = 2;
+
+MODULE_PARM (timeout, "i");
+MODULE_PARM_DESC (timeout, "Watchdog timeout in seconds (default=2)");
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
 
-#define	WD_TIMEOUT		3	/* 1 1/2 seconds for a timeout */
+MODULE_PARM (nowayout, "i");
+MODULE_PARM_DESC (nowayout,
+		  "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
 /*
  * These are the defines for the PC Watchdog card, revision A.
@@ -99,330 +111,316 @@
 #define WD_RLY2                 0x08	/* External relay triggered */
 #define WD_SRLY2                0x80	/* Software external relay triggered */
 
-static int current_readport, revision, temp_panic;
-static int is_open, initial_status, supports_temp, mode_debug;
-static spinlock_t io_lock;
-
 /*
- * PCWD_CHECKCARD
- *
- * This routine checks the "current_readport" to see if the card lies there.
- * If it does, it returns accordingly.
+ *  Differences between cards regarding how they perform some operations
+ *  are handled by an array of structs, with per card functions for the
+ *  incompatible operations.  It's all defined here.
  */
-static int __init pcwd_checkcard(void)
-{
-	int card_dat, prev_card_dat, found = 0, count = 0, done = 0;
-
-	/* As suggested by Alan Cox - this is a safety measure. */
-	if (check_region(current_readport, 4)) {
-		printk("pcwd: Port 0x%x unavailable.\n", current_readport);
-		return 0;
-	}
-
-	card_dat = 0x00;
-	prev_card_dat = 0x00;
-
-	prev_card_dat = inb(current_readport);
-	if (prev_card_dat == 0xFF)
-		return 0;
 
-	while(count < WD_TIMEOUT) {
+/*  ENABLE/DISABLE the card  */
+typedef int (*fn_enable) (int);	/* Enable/disable card */
 
-	/* Read the raw card data from the port, and strip off the
-	   first 4 bits */
+static int pcwd_enable_card (int enable);	/* Actually works */
+static int pcwd_enable_nop (int enable);	/* NOP - REV A cannot */
 
-		card_dat = inb_p(current_readport);
-		card_dat &= 0x000F;
+/* Obtain firmware version, if possible */
+#define	PCWD_FIRMWARE_BSZ	16	/* Version buffer size */
+typedef void (*fn_firmware) (char *bp);
+
+static void pcwd_firmware_ver_none (char *bp);	/* REV A can't do it */
+static void pcwd_firmware_ver_revc (char *bp);	/* REV C boards can */
+static void pcwd_firmware_ver_pci (char *bp);	/* PCI boards can too */
+
+/*  Tickle the watchdog timer */
+typedef void (*fn_tickle) (void);
+
+static void pcwd_tickle_reva (void);	/* Rev A only */
+static void pcwd_tickle (void);	/* Rev C, PCI */
+
+/*  Determine reboot and temperature status */
+typedef int (*fn_status) (int reset_boot);
+
+static int pcwd_get_stat_reva (int reset_boot);
+static int pcwd_get_stat (int reset_boot);
+
+/*  Per card type specifications */
+typedef struct {
+	fn_tickle wd_tickle;	/* Reset the watchdog */
+	fn_enable enable_card;	/* Enable/disable card, if possible */
+	fn_firmware firmware_ver;	/* Get firmware version, if possible */
+	fn_status wd_status;	/* Card reset and/or over temp */
+	int io_size;		/* I/O space used */
+	const char *name;	/* Nice name to display */
+} PCWD_CARD_INFO;
 
-	/* Sleep 1/2 second (or 500000 microseconds :) */
-
-		mdelay(500);
-		done = 0;
+/* Per card information, indexed by card version ID */
+static PCWD_CARD_INFO pcwd_card_info[] = {
+	{
+	 pcwd_tickle_reva,
+	 pcwd_enable_nop,
+	 pcwd_firmware_ver_none,
+	 pcwd_get_stat_reva,
+	 2,
+	 "Berkshire Products PC Watchdog (REV A)",
+	 },
+	{
+	 pcwd_tickle,
+	 pcwd_enable_card,
+	 pcwd_firmware_ver_revc,
+	 pcwd_get_stat,
+	 4,
+	 "Berkshire Products PC Watchdog (REV C)",
+	 },
+	{
+	 pcwd_tickle,
+	 pcwd_enable_card,
+	 pcwd_firmware_ver_pci,
+	 pcwd_get_stat,
+	 8,
+	 "Berkshire Products PC Watchdog (PCI)",
+	 },
+};
 
-	/* If there's a heart beat in both instances, then this means we
-	   found our card.  This also means that either the card was
-	   previously reset, or the computer was power-cycled. */
+/*  Overall driver information, including per card pointer */
+static struct {
+	PCWD_CARD_INFO *card_info;	/* Points to one of the above */
+	atomic_t open_allowed;	/* Watchdog is single open */
+	int flags;		/* Defined below */
+	int boot_status;	/* Card status at boot time */
+	int io_addr;		/* Card's base address */
+} pcwd_info = {
+NULL, ATOMIC_INIT (1), 0, 0, 0};
+
+/*  Bits allocated in flags above. */
+#define	PCWD_HAS_TEMP	0x0001	/* Set when thermometer available */
+#define	PCWD_PCI_REG	0x0002	/* Set if PCI register code worked */
+#define	PCWD_TEMP_PANIC	0x0004	/* Panic when over temperature */
 
-		if ((card_dat & WD_HRTBT) && (prev_card_dat & WD_HRTBT) &&
-			(!done)) {
-			found = 1;
-			done = 1;
-			break;
-		}
+static spinlock_t io_lock;
 
-	/* If the card data is exactly the same as the previous card data,
-	   it's safe to assume that we should check again.  The manual says
-	   that the heart beat will change every second (or the bit will
-	   toggle), and this can be used to see if the card is there.  If
-	   the card was powered up with a cold boot, then the card will
-	   not start blinking until 2.5 minutes after a reboot, so this
-	   bit will stay at 1. */
-
-		if ((card_dat == prev_card_dat) && (!done)) {
-			count++;
-			done = 1;
-		}
+/* D E T E R M I N E   C A R D   S T A T U S   F U N C T I O N S  */
+/*   Rev A cards return status information from the base register,
+ * which is used for the temperature in other cards.  */
+
+static int
+pcwd_get_stat_reva (int reset_boot)
+{
+	int retval;
+	int status;
+
+	spin_lock (&io_lock);
+	status = inb_p (pcwd_info.io_addr);
+	spin_unlock (&io_lock);
+
+	/* Transform the card register to the ioctl bits we use internally */
+	retval = 0;
+	if (status & WD_WDRST)
+		retval |= WDIOF_CARDRESET;
+	if (status & WD_T110)
+		retval |= WDIOF_OVERHEAT;
 
-	/* If the card data is toggling any bits, this means that the heart
-	   beat was detected, or something else about the card is set. */
+	return retval;
+}
 
-		if ((card_dat != prev_card_dat) && (!done)) {
-			done = 1;
-			found = 1;
-			break;
-		}
+/*
+ *  Rev C and PCI cards return card status in the base address + 1 register.
+ *  And use different bits to indicate a card initiated reset, and
+ *  an over-temperature condition.  And the reboot status can be reset.
+ */
 
-	/* Otherwise something else strange happened. */
+static int
+pcwd_get_stat (int reset_boot)
+{
+	int retval;
+	int status;
 
-		if (!done)
-			count++;
+	spin_lock (&io_lock);
+	status = inb_p (pcwd_info.io_addr + 1);
+	if (reset_boot) {
+		/*  NOTE:  the REV C card clears the "card caused reboot"
+		 * flag when writing ANY value to this port.  However,
+		 * the PCI card requires writing a 1 to bit 0.  */
+		outb_p (0x01, pcwd_info.io_addr + 1);
 	}
+	spin_unlock (&io_lock);
 
-	return((found) ? 1 : 0);
-}
-
-void pcwd_showprevstate(void)
-{
-	int card_status = 0x0000;
+	retval = 0;
+	if (status & 0x01)
+		retval |= WDIOF_CARDRESET;
+	if (status & 0x04)
+		retval |= WDIOF_OVERHEAT;
 
-	if (revision == PCWD_REVISION_A)
-		initial_status = card_status = inb(current_readport);
-	else {
-		initial_status = card_status = inb(current_readport + 1);
-		outb_p(0x00, current_readport + 1); /* clear reset status */
-	}
+	return retval;
+}
 
-	if (revision == PCWD_REVISION_A) {
-		if (card_status & WD_WDRST)
-			printk("pcwd: Previous reboot was caused by the card.\n");
+/*  W A T C H D O G   T I M E R   R E S E T   F U N C T I O N S   */
+/*  Rev A cards are reset by setting a specific bit in register 1.  */
 
-		if (card_status & WD_T110) {
-			printk("pcwd: Card senses a CPU Overheat.  Panicking!\n");
-			panic("pcwd: CPU Overheat.\n");
-		}
+static void
+pcwd_tickle_reva (void)
+{
+	int wdrst_stat;
 
-		if ((!(card_status & WD_WDRST)) &&
-		    (!(card_status & WD_T110)))
-			printk("pcwd: Cold boot sense.\n");
-	} else {
-		if (card_status & 0x01)
-			printk("pcwd: Previous reboot was caused by the card.\n");
+	spin_lock (&io_lock);
+	wdrst_stat = inb_p (pcwd_info.io_addr);
+	wdrst_stat = (wdrst_stat & 0x0F) | WD_WDRST;
 
-		if (card_status & 0x04) {
-			printk("pcwd: Card senses a CPU Overheat.  Panicking!\n");
-			panic("pcwd: CPU Overheat.\n");
-		}
+	outb_p (wdrst_stat, pcwd_info.io_addr + 1);
+	spin_unlock (&io_lock);
 
-		if ((!(card_status & 0x01)) &&
-		    (!(card_status & 0x04)))
-			printk("pcwd: Cold boot sense.\n");
-	}
+	return;
 }
 
-static void pcwd_send_heartbeat(void)
-{
-	int wdrst_stat;
-
-	wdrst_stat = inb_p(current_readport);
-	wdrst_stat &= 0x0F;
+/*  Other cards are reset by writing anything to the base register.  */
 
-	wdrst_stat |= WD_WDRST;
+static void
+pcwd_tickle (void)
+{
+	spin_lock (&io_lock);
+	outb_p (0x42, pcwd_info.io_addr);
+	spin_unlock (&io_lock);
 
-	if (revision == PCWD_REVISION_A)
-		outb_p(wdrst_stat, current_readport + 1);
-	else
-		outb_p(wdrst_stat, current_readport);
+	return;
 }
 
-static int pcwd_ioctl(struct inode *inode, struct file *file,
-		      unsigned int cmd, unsigned long arg)
+static int
+pcwd_ioctl (struct inode *inode, struct file *file,
+	    unsigned int cmd, unsigned long arg)
 {
-	int i, cdat, rv;
-	static struct watchdog_info ident=
-	{
-		WDIOF_OVERHEAT|WDIOF_CARDRESET,
+	int rv;
+	int retval;
+
+	static struct watchdog_info ident = {
+		WDIOF_OVERHEAT | WDIOF_CARDRESET,
 		1,
 		"PCWD"
 	};
 
-	switch(cmd) {
-	default:
-		return -ENOTTY;
-
+	switch (cmd) {
 	case WDIOC_GETSUPPORT:
-		i = copy_to_user((void*)arg, &ident, sizeof(ident));
-		return i ? -EFAULT : 0;
+		rv = copy_to_user ((void *) arg, &ident, sizeof (ident));
+		return rv ? -EFAULT : 0;
 
 	case WDIOC_GETSTATUS:
-		spin_lock(&io_lock);
-		if (revision == PCWD_REVISION_A) 
-			cdat = inb(current_readport);
-		else
-			cdat = inb(current_readport + 1 );
-		spin_unlock(&io_lock);
-		rv = 0;
+		rv = pcwd_info.card_info->wd_status (0);
 
-		if (revision == PCWD_REVISION_A) 
-		{
-			if (cdat & WD_WDRST)
-				rv |= WDIOF_CARDRESET;
-
-			if (cdat & WD_T110) 
-			{
-				rv |= WDIOF_OVERHEAT;
-
-				if (temp_panic)
-					panic("pcwd: Temperature overheat trip!\n");
-			}
+		if (rv & WDIOF_OVERHEAT) {
+			if (pcwd_info.flags & PCWD_TEMP_PANIC)
+				panic ("pcwd: Temperature overheat trip!\n");
 		}
-		else 
-		{
-			if (cdat & 0x01)
-				rv |= WDIOF_CARDRESET;
-
-			if (cdat & 0x04) 
-			{
-				rv |= WDIOF_OVERHEAT;
 
-				if (temp_panic)
-					panic("pcwd: Temperature overheat trip!\n");
-			}
-		}
-
-		if(put_user(rv, (int *) arg))
+		if (put_user (rv, (int *) arg))
 			return -EFAULT;
 		return 0;
 
 	case WDIOC_GETBOOTSTATUS:
-		rv = 0;
-
-		if (revision == PCWD_REVISION_A) 
-		{
-			if (initial_status & WD_WDRST)
-				rv |= WDIOF_CARDRESET;
+		rv = pcwd_info.boot_status;
 
-			if (initial_status & WD_T110)
-				rv |= WDIOF_OVERHEAT;
-		}
-		else
-		{
-			if (initial_status & 0x01)
-				rv |= WDIOF_CARDRESET;
-
-			if (initial_status & 0x04)
-				rv |= WDIOF_OVERHEAT;
-		}
-
-		if(put_user(rv, (int *) arg))
+		if (put_user (rv, (int *) arg))
 			return -EFAULT;
 		return 0;
 
 	case WDIOC_GETTEMP:
-
 		rv = 0;
-		if ((supports_temp) && (mode_debug == 0)) 
-		{
-			spin_lock(&io_lock);
-			rv = inb(current_readport);
-			spin_unlock(&io_lock);
-			if(put_user(rv, (int*) arg))
-				return -EFAULT;
-		} else if(put_user(rv, (int*) arg))
-				return -EFAULT;
+		if (pcwd_info.flags & PCWD_HAS_TEMP) {
+			spin_lock (&io_lock);
+			rv = inb_p (pcwd_info.io_addr);
+			spin_unlock (&io_lock);
+		}
+		if (put_user (rv, (int *) arg))
+			return -EFAULT;
 		return 0;
 
 	case WDIOC_SETOPTIONS:
-		if (revision == PCWD_REVISION_C) 
-		{
-			if(copy_from_user(&rv, (int*) arg, sizeof(int)))
-				return -EFAULT;
-
-			if (rv & WDIOS_DISABLECARD) 
-			{
-				spin_lock(&io_lock);
-				outb_p(0xA5, current_readport + 3);
-				outb_p(0xA5, current_readport + 3);
-				cdat = inb_p(current_readport + 2);
-				spin_unlock(&io_lock);
-				if ((cdat & 0x10) == 0) 
-				{
-					printk("pcwd: Could not disable card.\n");
-					return -EIO;
-				}
+		if (copy_from_user (&rv, (int *) arg, sizeof (int)))
+			return -EFAULT;
 
-				return 0;
-			}
+		retval = -EINVAL;
 
-			if (rv & WDIOS_ENABLECARD) 
-			{
-				spin_lock(&io_lock);
-				outb_p(0x00, current_readport + 3);
-				cdat = inb_p(current_readport + 2);
-				spin_unlock(&io_lock);
-				if (cdat & 0x10) 
-				{
-					printk("pcwd: Could not enable card.\n");
-					return -EIO;
-				}
-				return 0;
+		if (rv & WDIOS_DISABLECARD) {
+			if (!pcwd_info.card_info->enable_card (0)) {
+				printk (KERN_EMERG
+					"pcwd: Could not disable card\n");
+				return -EIO;
 			}
 
-			if (rv & WDIOS_TEMPPANIC) 
-			{
-				temp_panic = 1;
+			retval = 0;
+		}
+
+		if (rv & WDIOS_ENABLECARD) {
+			if (!pcwd_info.card_info->enable_card (1)) {
+				printk (KERN_EMERG
+					"pcwd: Could not enable card\n");
+				return -EIO;
 			}
+			retval = 0;
+		}
+
+		if (rv & WDIOS_TEMPPANIC) {
+			pcwd_info.flags |= PCWD_TEMP_PANIC;
+
+			retval = 0;
 		}
-		return -EINVAL;
-		
+
+		return retval;
+
 	case WDIOC_KEEPALIVE:
-		pcwd_send_heartbeat();
+		pcwd_info.card_info->wd_tickle ();
 		return 0;
+
+	default:
+		return -ENOTTY;
 	}
 
 	return 0;
 }
 
-static ssize_t pcwd_write(struct file *file, const char *buf, size_t len,
-			  loff_t *ppos)
+/*   Write:  only for the watchdog device (thermometer is read-only).  */
+
+static ssize_t
+pcwd_write (struct file *file, const char *buf, size_t len, loff_t * ppos)
 {
 	/*  Can't seek (pwrite) on this device  */
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
 
-	if (len)
-	{
-		pcwd_send_heartbeat();
+	if (len) {
+		pcwd_info.card_info->wd_tickle ();
 		return 1;
 	}
 	return 0;
 }
 
-static int pcwd_open(struct inode *ino, struct file *filep)
+static int
+pcwd_open (struct inode *ino, struct file *filep)
 {
-        switch (MINOR(ino->i_rdev))
-        {
-                case WATCHDOG_MINOR:
-                    if (is_open)
-                        return -EBUSY;
-                    MOD_INC_USE_COUNT;
-                    /*  Enable the port  */
-                    if (revision == PCWD_REVISION_C)
-                    {
-                    	spin_lock(&io_lock);
-                    	outb_p(0x00, current_readport + 3);
-                    	spin_unlock(&io_lock);
-                    }
-                    is_open = 1;
-                    return(0);
-                case TEMP_MINOR:
-                    return(0);
-                default:
-                    return (-ENODEV);
-        }
+	switch (MINOR (ino->i_rdev)) {
+	case WATCHDOG_MINOR:
+		if (!atomic_dec_and_test (&pcwd_info.open_allowed)) {
+			atomic_inc (&pcwd_info.open_allowed);
+			return -EBUSY;
+		}
+
+		/*  Enable the card  */
+		pcwd_info.card_info->enable_card (1);
+		pcwd_info.card_info->wd_tickle ();
+
+		return 0;
+
+	case TEMP_MINOR:
+		if (pcwd_info.flags & PCWD_HAS_TEMP) {
+			return 0;
+		}
+		return -ENODEV;
+
+	default:
+		return -ENODEV;
+	}
 }
 
-static ssize_t pcwd_read(struct file *file, char *buf, size_t count,
-			 loff_t *ppos)
+/*	Read:  applies only to the thermometer (watchdog is write only).  */
+static ssize_t
+pcwd_read (struct file *file, char *buf, size_t count, loff_t * ppos)
 {
 	unsigned short c;
 	unsigned char cp;
@@ -430,126 +428,279 @@
 	/*  Can't seek (pread) on this device  */
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
-	switch(MINOR(file->f_dentry->d_inode->i_rdev)) 
-	{
-		case TEMP_MINOR:
-			/*
-			 * Convert metric to Fahrenheit, since this was
-			 * the decided 'standard' for this return value.
-			 */
-			
-			c = inb(current_readport);
-			cp = (c * 9 / 5) + 32;
-			if(copy_to_user(buf, &cp, 1))
-				return -EFAULT;
-			return 1;
-		default:
-			return -EINVAL;
+
+	/*
+	 * Convert celsius to fahrenheit, since this was
+	 * the decided 'standard' for this return value.
+	 */
+
+	spin_lock (&io_lock);
+	c = inb_p (pcwd_info.io_addr);
+	spin_unlock (&io_lock);
+
+	cp = (c * 9 / 5) + 32;
+	if (copy_to_user (buf, &cp, 1))
+		return -EFAULT;
+
+	return 1;
+}
+
+static int
+pcwd_close (struct inode *ino, struct file *filep)
+{
+	switch (MINOR (ino->i_rdev)) {
+	case WATCHDOG_MINOR:
+		if (!nowayout)
+			pcwd_info.card_info->enable_card (0);
+
+		atomic_inc (&pcwd_info.open_allowed);
+		break;
+
+	case TEMP_MINOR:
+		break;
 	}
+	return 0;
 }
 
-static int pcwd_close(struct inode *ino, struct file *filep)
+/*
+ *  System is shutting down, so disable the card.  Otherwise the timeout
+ * may expire during shutdown.  Of course, this means a hang during
+ * shutdown will not be reset, but somebody is probably nearby and will
+ * notice.  The alternative is to have the shutdown aborted when the
+ * watchdog expires and hits reset.
+ */
+
+static int
+pcwd_notify_sys (struct notifier_block *this, unsigned long code, void *unused)
 {
-	if (MINOR(ino->i_rdev)==WATCHDOG_MINOR)
-	{
-		lock_kernel();
-	        is_open = 0;
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
-		/*  Disable the board  */
-		if (revision == PCWD_REVISION_C) {
-			spin_lock(&io_lock);
-			outb_p(0xA5, current_readport + 3);
-			outb_p(0xA5, current_readport + 3);
-			spin_unlock(&io_lock);
-		}
-#endif
-		unlock_kernel();
+	if (code == SYS_DOWN || code == SYS_HALT) {
+		/*
+		 *  If initialisation is still in progress, the device pointer
+		 * may not be valid, so check, just to make sure.
+		 */
+
+		if (pcwd_info.card_info)
+			pcwd_info.card_info->enable_card (0);
 	}
+
+	return NOTIFY_DONE;
+}
+
+/*  C A R D   E N A B L E / D I S A B L E   F U N C T I O N S  */
+/*  Enable/disable the card, not REV A.  The two writes are required by card */
+
+static int
+pcwd_enable_card (int enable)
+{
+	int stat_reg;
+
+	spin_lock (&io_lock);
+	if (enable) {
+		outb_p (0x00, pcwd_info.io_addr + 3);
+	} else {
+		outb_p (0xA5, pcwd_info.io_addr + 3);
+		outb_p (0xA5, pcwd_info.io_addr + 3);
+	}
+	stat_reg = inb_p (pcwd_info.io_addr + 2);
+	spin_unlock (&io_lock);
+
+	stat_reg &= 0x10;	/* "disabled when set" bit */
+	if (enable) {
+		stat_reg ^= 0x10;
+	}
+
+	return stat_reg;
+}
+
+static int
+pcwd_enable_nop (int enable)
+{
 	return 0;
 }
 
-static inline void get_support(void)
+static void __init
+set_card_type (int is_pci)
 {
-	if (inb(current_readport) != 0xF0)
-		supports_temp = 1;
+
+	if (is_pci) {
+		pcwd_info.card_info = &pcwd_card_info[PCWD_REV_PCI];
+		pcwd_info.flags |= PCWD_PCI_REG;
+	} else {
+		pcwd_info.card_info = &pcwd_card_info[PCWD_REV_C];
+
+		/* REV A cards use only 2 io ports; test
+		 * presumes a floating bus reads as 0xff.  */
+		if ((inb (pcwd_info.io_addr + 2) == 0xFF) ||
+		    (inb (pcwd_info.io_addr + 3) == 0xFF)) {
+			pcwd_info.card_info = &pcwd_card_info[PCWD_REV_A];
+		}
+	}
+
+	return;
 }
 
-static inline int get_revision(void)
+/* G E T    F I R M W A R E   V E R S I O N   F U N C T I O N S    */
+/* REV A can't do it */
+static void __init
+pcwd_firmware_ver_none (char *bp)
 {
-	int r = PCWD_REVISION_C;
-	
-	spin_lock(&io_lock);
-	if ((inb(current_readport + 2) == 0xFF) ||
-	    (inb(current_readport + 3) == 0xFF))
-		r=PCWD_REVISION_A;
-	spin_unlock(&io_lock);
+	strncpy (bp, "<unavailable>", PCWD_FIRMWARE_BSZ);
 
-	return r;
+	return;
 }
 
-static int __init send_command(int cmd)
+/* PCI boards can too */
+static void __init
+pcwd_firmware_ver_pci (char *bp)
 {
-	int i;
+	int count;
+
+	/* Write the 'Get Firmware Version' command to port 6 and wait */
+	outb (0x08, pcwd_info.io_addr + 6);
+
+	/* Card sets bit 0x40 (WRSP) bit in port 2.  Can take 10ms! */
+	for (count = 0; count < 15; ++count) {
+		mdelay (1);	/* Board responds slowly */
 
-	outb_p(cmd, current_readport + 2);
-	mdelay(1);
+		if (inb (pcwd_info.io_addr + 2) & 0x40) {
+			/* Board says data now valid */
 
-	i = inb(current_readport);
-	i = inb(current_readport);
+			snprintf (bp, PCWD_FIRMWARE_BSZ, "%u.%u",
+				  inb (pcwd_info.io_addr + 5),
+				  inb (pcwd_info.io_addr + 4));
 
-	return(i);
+			return;
+		}
+	}
+	strncpy (bp, "<card no answer>", PCWD_FIRMWARE_BSZ);
+
+	return;
 }
 
-static inline char *get_firmware(void)
+/*
+ *   REV C boards read diagnostic (including firmware version) data
+ * from the register 0.  To do this, the card is put into diagnostic
+ * mode, then the command is submitted and data read from register 0.
+ * NOTE:  the onboard processor writes 4 bits at a time to the register,
+ * so it's necessary to wait for the data to stabilise before
+ * accepting it.
+ */
+
+static int __init
+send_command (int cmd)
 {
-	int i, found = 0, count = 0, one, ten, hund, minor;
-	char *ret;
+	int ii;
 
-	ret = kmalloc(6, GFP_KERNEL);
-	if(ret == NULL)
-		return NULL;
+	int reg0, last_reg0;	/* Double read for stabilising */
 
-	while((count < 3) && (!found)) {
-		outb_p(0x80, current_readport + 2);
-		i = inb(current_readport);
+	outb (cmd, pcwd_info.io_addr + 2);
+	/*
+	 *    The following delay need only be 200 microseconds according
+	 *  to the spec I have.  But my card seems slower, as waiting
+	 *  250 microseconds returns valid data, but NOT from this
+	 *  command.  The 1000 value may be excessive, but is reliable.
+	 */
+	mdelay (1);
 
-		if (i == 0x00)
-			found = 1;
-		else if (i == 0xF3)
-			outb_p(0x00, current_readport + 2);
+	reg0 = inb (pcwd_info.io_addr);
+	for (ii = 0; ii < 25; ++ii) {
+		last_reg0 = reg0;
+		reg0 = inb (pcwd_info.io_addr);
 
-		udelay(400L);
+		if (reg0 == last_reg0)
+			break;	/* Data is stable */
+
+		udelay (250);
+	}
+
+	return reg0;
+}
+
+/*  REV C board function to retrieve firmware version */
+static void __init
+pcwd_firmware_ver_revc (char *bp)
+{
+	int i, found = 0, count = 0;
+
+	/*  Set the card into debug mode to find firmware version */
+	outb_p (0x00, pcwd_info.io_addr + 2);	/* Spec says to do this */
+	udelay (500);
+
+	while ((count < 3) && (!found)) {
+		i = send_command (0x80);
+
+		if (i == 0x00) {
+			found = 1;
+			break;
+		} else if (i == 0xF3) {
+			/* Card does not like what we've done to it */
+			outb_p (0x00, pcwd_info.io_addr + 2);
+			udelay (1200);	/* Spec says wait 1ms */
+			outb_p (0x00, pcwd_info.io_addr + 2);
+			udelay (500);
+		}
 		count++;
 	}
 
 	if (found) {
-		mode_debug = 1;
 
-		one = send_command(0x81);
-		ten = send_command(0x82);
-		hund = send_command(0x83);
-		minor = send_command(0x84);
-		sprintf(ret, "%c.%c%c%c", one, ten, hund, minor);
-	}
-	else
-		sprintf(ret, "ERROR");
+		*bp++ = send_command (0x81);
+		*bp++ = '.';
+		*bp++ = send_command (0x82);
+		*bp++ = send_command (0x83);
+		*bp++ = send_command (0x84);
+		*bp++ = '\0';
+
+		/* Out of debug mode */
+		outb (0x00, pcwd_info.io_addr + 2);
+	} else
+		strncpy (bp, "<err - no go>", PCWD_FIRMWARE_BSZ);
 
-	return(ret);
+	return;
 }
 
-static void debug_off(void)
+/*   Initialisation function called ONLY from the PCI layer.  */
+
+static int __init
+pcwd_init_one (struct pci_dev *dev, const struct pci_device_id *ent)
 {
-	outb_p(0x00, current_readport + 2);
-	mode_debug = 0;
+	static int devices = 0;
+
+	++devices;
+	if (devices > 1) {
+		printk (KERN_ERR "pcwd: Driver supports only ONE device\n");
+
+		return -ENODEV;
+	}
+
+	pcwd_info.io_addr = pci_resource_start (dev, 0);
+
+	if (pcwd_info.io_addr == 0 || pci_enable_device (dev))
+		return -ENODEV;
+
+	return 0;
 }
 
+static struct pci_device_id pcwd_pci_tbl[] __initdata = {
+	{PCI_VENDOR_ID_QUICKLOGIC, PCI_DEVICE_ID_BERKSHIRE,
+	 PCI_ANY_ID, PCI_ANY_ID,},
+	{0},			/* End of list */
+};
+
+MODULE_DEVICE_TABLE (pci, pcwd_pci_tbl);
+
+static struct pci_driver pcwd_driver = {
+	name:"pcwd",
+	id_table:pcwd_pci_tbl,
+	probe:pcwd_init_one,
+};
+
 static struct file_operations pcwd_fops = {
-	owner:		THIS_MODULE,
-	read:		pcwd_read,
-	write:		pcwd_write,
-	ioctl:		pcwd_ioctl,
-	open:		pcwd_open,
-	release:	pcwd_close,
+	owner:THIS_MODULE,
+	write:pcwd_write,
+	ioctl:pcwd_ioctl,
+	open:pcwd_open,
+	release:pcwd_close,
 };
 
 static struct miscdevice pcwd_miscdev = {
@@ -558,105 +709,224 @@
 	&pcwd_fops
 };
 
+static struct file_operations pcwd_temp_fops = {
+	owner:THIS_MODULE,
+	read:pcwd_read,
+	open:pcwd_open,
+	release:pcwd_close,
+};
+
 static struct miscdevice temp_miscdev = {
 	TEMP_MINOR,
 	"temperature",
-	&pcwd_fops
+	&pcwd_temp_fops
 };
- 
-static int __init pcwatchdog_init(void)
+
+/* Need to know about shutdown to kill the timer - may reset during shutdown! */
+    static struct notifier_block pcwd_notifier =
 {
-	int i, found = 0;
-	spin_lock_init(&io_lock);
-	
-	revision = PCWD_REVISION_A;
-
-	printk("pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
-
-	/* Initial variables */
-	is_open = 0;
-	supports_temp = 0;
-	mode_debug = 0;
-	temp_panic = 0;
-	initial_status = 0x0000;
-
-#ifndef	PCWD_BLIND
-	for (i = 0; pcwd_ioports[i] != 0; i++) {
-		current_readport = pcwd_ioports[i];
+	pcwd_notify_sys,
+	NULL,
+	0,
+};
 
-		if (pcwd_checkcard()) {
-			found = 1;
-			break;
+/*
+ *   The ISA cards have a heartbeat bit in one of the registers, which
+ *  register is card dependent.  The heartbeat bit is monitored, and if
+ *  found, is considered proof that a Berkshire card has been found.
+ *  The initial rate is once per second at board start up, then twice
+ *  per second for normal operation.
+ */
+static int __init
+check_isa_card (int base_addr)
+{
+	int reg0, last_reg0;	/* Reg 0, in case it's REV A */
+	int reg1, last_reg1;	/* Register 1 for REV C cards */
+	int ii;
+	int retval;
+
+	/* As suggested by Alan Cox - this is a safety measure. */
+	if (!request_region (base_addr, 4, "pcwd-isa")) {
+		printk (KERN_INFO "pcwd: Port 0x%x unavailable\n", base_addr);
+		return 0;
+	}
+
+	retval = 0;
+
+	reg0 = inb_p (base_addr);	/* For REV A boards */
+	reg1 = inb (base_addr + 1);	/* For REV C boards */
+	if (reg0 != 0xff || reg1 != 0xff) {
+		/* Not an 'ff' from a floating bus, so must be a card! */
+		for (ii = 0; ii < timeout_val; ++ii) {
+
+			set_current_state (TASK_INTERRUPTIBLE);
+			schedule_timeout (HZ / 2);
+
+			last_reg0 = reg0;
+			last_reg1 = reg1;
+
+			reg0 = inb_p (base_addr);
+			reg1 = inb (base_addr + 1);
+
+			/* Has either hearbeat bit changed?  */
+			if ((reg0 ^ last_reg0) & WD_HRTBT ||
+			    (reg1 ^ last_reg1) & 0x02) {
+
+				retval = 1;
+				break;
+			}
 		}
 	}
+	release_region (base_addr, 4);
 
-	if (!found) {
-		printk("pcwd: No card detected, or port not available.\n");
-		return(-EIO);
+	return retval;
+}
+
+static int __init
+pcwd_card_init (void)
+{
+	int retval;
+	char fvbuf[PCWD_FIRMWARE_BSZ];
+
+	pcwd_info.card_info->firmware_ver (fvbuf);
+
+	printk (KERN_INFO "pcwd: %s at port 0x%03x (Firmware: %s)\n",
+		pcwd_info.card_info->name, pcwd_info.io_addr, fvbuf);
+
+	/* Returns 0xf0 in temperature register if no thermometer */
+	if (inb (pcwd_info.io_addr) != 0xF0) {
+		pcwd_info.flags |= PCWD_HAS_TEMP;
+		printk (KERN_INFO "pcwd: Temperature option detected\n");
 	}
-#endif
 
-#ifdef	PCWD_BLIND
-	current_readport = PCWD_BLIND;
-#endif
+	if (nowayout)
+		printk (KERN_INFO
+			"pcwd: Watchdog cannot be stopped once started\n");
+
+	/* Record the power up status of "card did reset" and/or temp trip */
+	pcwd_info.boot_status = pcwd_info.card_info->wd_status (1);
 
-	get_support();
-	revision = get_revision();
+	if (pcwd_info.boot_status & WDIOF_CARDRESET)
+		printk (KERN_INFO
+			"pcwd: Previous reboot was caused by the card\n");
 
-	if (revision == PCWD_REVISION_A)
-		printk("pcwd: PC Watchdog (REV.A) detected at port 0x%03x\n", current_readport);
-	else if (revision == PCWD_REVISION_C)
-		printk("pcwd: PC Watchdog (REV.C) detected at port 0x%03x (Firmware version: %s)\n",
-			current_readport, get_firmware());
-	else {
-		/* Should NEVER happen, unless get_revision() fails. */
-		printk("pcwd: Unable to get revision.\n");
-		return -1;
+	if (pcwd_info.boot_status & WDIOF_OVERHEAT) {
+		printk (KERN_EMERG
+			"pcwd: Card senses a CPU Overheat.  Panicking!\n");
+		panic ("pcwd: CPU Overheat\n");
 	}
 
-	if (supports_temp)
-		printk("pcwd: Temperature Option Detected.\n");
+	if (pcwd_info.boot_status == 0)
+		printk (KERN_INFO "pcwd: Cold boot sense\n");
 
-	debug_off();
+	pcwd_info.card_info->enable_card (0);
 
-	pcwd_showprevstate();
+	retval = 0;
+	if (!request_region (pcwd_info.io_addr,
+			     pcwd_info.card_info->io_size,
+			     pcwd_info.card_info->name)) {
+		printk (KERN_ERR "pcwd: I/0 %d is not free\n",
+			pcwd_info.io_addr);
 
-	/*  Disable the board  */
-	if (revision == PCWD_REVISION_C) {
-		outb_p(0xA5, current_readport + 3);
-		outb_p(0xA5, current_readport + 3);
+		return retval;
 	}
 
-	if (revision == PCWD_REVISION_A)
-		request_region(current_readport, 2, "PCWD Rev.A (Berkshire)");
-	else
-		request_region(current_readport, 4, "PCWD Rev.C (Berkshire)");
+	retval = misc_register (&pcwd_miscdev);
+	if (retval) {
+		release_region (pcwd_info.io_addr,
+				pcwd_info.card_info->io_size);
+		printk (KERN_ERR "pcwd: can't misc_register on minor %d\n",
+			WATCHDOG_MINOR);
+		return retval;
+	}
 
-	misc_register(&pcwd_miscdev);
+	if (pcwd_info.flags & PCWD_HAS_TEMP) {
+		if (misc_register (&temp_miscdev)) {
+			printk (KERN_ERR
+				"pwcd: can't misc_register thermometer - disabling it\n");
+			pcwd_info.flags &= ~PCWD_HAS_TEMP;
+		}
+	}
 
-	if (supports_temp)
-		misc_register(&temp_miscdev);
+	retval = register_reboot_notifier (&pcwd_notifier);
+	if (retval) {
+		if (pcwd_info.flags & PCWD_HAS_TEMP)
+			misc_deregister (&temp_miscdev);
+		misc_deregister (&pcwd_miscdev);
+		release_region (pcwd_info.io_addr,
+				pcwd_info.card_info->io_size);
+	}
 
-	return 0;
+	return retval;
 }
 
-static void __exit pcwatchdog_exit(void)
+static int __init
+pcwatchdog_init (void)
 {
-	misc_deregister(&pcwd_miscdev);
-	/*  Disable the board  */
-	if (revision == PCWD_REVISION_C) {
-		outb_p(0xA5, current_readport + 3);
-		outb_p(0xA5, current_readport + 3);
+	int i, found = 0;
+	/*
+	 * ISA card auto-probe addresses available.  Last one is only
+	 * available on REV C cards.
+	 */
+	static int pcwd_ioports[] = { 0x270, 0x350, 0x370 };
+#define	PCWD_NUM_ADDR	(sizeof(pcwd_ioports)/sizeof(pcwd_ioports[0]))
+
+	timeout_val = timeout * 2;
+
+	spin_lock_init (&io_lock);
+
+	printk (KERN_INFO "pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
+
+	if (pci_register_driver (&pcwd_driver) > 0) {
+		found = 1;
+		set_card_type (1);	/* Set to PCI card model */
+	} else {
+		/* No PCI entry, try the ISA addresses.  */
+		for (i = 0; i < PCWD_NUM_ADDR; i++) {
+
+			if (check_isa_card (pcwd_ioports[i])) {
+				found = 1;
+
+				pcwd_info.io_addr = pcwd_ioports[i];
+
+				set_card_type (0);
+				break;
+			}
+		}
 	}
-	if (supports_temp)
-		misc_deregister(&temp_miscdev);
 
-	release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4);
+	if (!found) {
+		printk (KERN_INFO
+			"pcwd: No card detected, or port not available\n");
+		return -EIO;
+	}
+
+	return pcwd_card_init ();
+}
+
+static void __exit
+pcwatchdog_exit (void)
+{
+	unregister_reboot_notifier (&pcwd_notifier);
+	misc_deregister (&pcwd_miscdev);
+
+	if (!nowayout)
+		pcwd_info.card_info->enable_card (0);
+
+	if (pcwd_info.flags & PCWD_HAS_TEMP)
+		misc_deregister (&temp_miscdev);
+
+	release_region (pcwd_info.io_addr, pcwd_info.card_info->io_size);
+
+	if (pcwd_info.flags & PCWD_PCI_REG)
+		pci_unregister_driver (&pcwd_driver);
+
+	return;
 }
 
-module_init(pcwatchdog_init);
-module_exit(pcwatchdog_exit);
+module_init (pcwatchdog_init);
+module_exit (pcwatchdog_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE ("GPL");
 
 EXPORT_NO_SYMBOLS;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/ppdev.c linux/drivers/char/ppdev.c
--- linux.orig/drivers/char/ppdev.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/ppdev.c	2002-07-20 01:08:34.000000000 +0000
@@ -4,7 +4,7 @@
  * This is the code behind /dev/parport* -- it allows a user-space
  * application to use the parport subsystem.
  *
- * Copyright (C) 1998-2000 Tim Waugh <tim@cyberelk.demon.co.uk>
+ * Copyright (C) 1998-2000, 2002 Tim Waugh <tim@cyberelk.net>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -80,6 +80,7 @@
 	unsigned char irqctl;
 	struct ieee1284_info state;
 	struct ieee1284_info saved_state;
+	long default_inactivity;
 };
 
 /* pp_struct.flags bitfields */
@@ -107,7 +108,6 @@
 	struct pp_struct *pp = file->private_data;
 	char * kbuffer;
 	ssize_t bytes_read = 0;
-	ssize_t got = 0;
 	struct parport *pport;
 	int mode;
 
@@ -118,6 +118,10 @@
 		return -EINVAL;
 	}
 
+	/* Trivial case. */
+	if (count == 0)
+		return 0;
+
 	kbuffer = kmalloc(min_t(size_t, count, PP_BUFFER_SIZE), GFP_KERNEL);
 	if (!kbuffer) {
 		return -ENOMEM;
@@ -125,8 +129,13 @@
 	pport = pp->pdev->port;
 	mode = pport->ieee1284.mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);
 
-	while (bytes_read < count) {
-		ssize_t need = min_t(unsigned long, count - bytes_read, PP_BUFFER_SIZE);
+	parport_set_timeout (pp->pdev,
+			     (file->f_flags & O_NONBLOCK) ?
+			     PARPORT_INACTIVITY_O_NONBLOCK :
+			     pp->default_inactivity);
+
+	while (bytes_read == 0) {
+		ssize_t need = min_t(unsigned long, count, PP_BUFFER_SIZE);
 
 		if (mode == IEEE1284_MODE_EPP) {
 			/* various specials for EPP mode */
@@ -144,37 +153,33 @@
 			} else {
 				fn = pport->ops->epp_read_data;
 			}
-			got = (*fn)(pport, kbuffer, need, flags);
+			bytes_read = (*fn)(pport, kbuffer, need, flags);
 		} else {
-			got = parport_read (pport, kbuffer, need);
+			bytes_read = parport_read (pport, kbuffer, need);
 		}
 
-		if (got <= 0) {
-			if (!bytes_read) {
-				bytes_read = got;
-			}
+		if (bytes_read != 0)
 			break;
-		}
 
-		if (copy_to_user (buf + bytes_read, kbuffer, got)) {
-			bytes_read = -EFAULT;
+		if (file->f_flags & O_NONBLOCK) {
+			bytes_read = -EAGAIN;
 			break;
 		}
 
-		bytes_read += got;
-
 		if (signal_pending (current)) {
-			if (!bytes_read) {
-				bytes_read = -EINTR;
-			}
+			bytes_read = -ERESTARTSYS;
 			break;
 		}
 
-		if (current->need_resched) {
+		if (current->need_resched)
 			schedule ();
-		}
 	}
 
+	parport_set_timeout (pp->pdev, pp->default_inactivity);
+
+	if (bytes_read > 0 && copy_to_user (buf, kbuffer, bytes_read))
+		bytes_read = -EFAULT;
+
 	kfree (kbuffer);
 	pp_enable_irq (pp);
 	return bytes_read;
@@ -205,6 +210,11 @@
 	pport = pp->pdev->port;
 	mode = pport->ieee1284.mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);
 
+	parport_set_timeout (pp->pdev,
+			     (file->f_flags & O_NONBLOCK) ?
+			     PARPORT_INACTIVITY_O_NONBLOCK :
+			     pp->default_inactivity);
+
 	while (bytes_written < count) {
 		ssize_t n = min_t(unsigned long, count - bytes_written, PP_BUFFER_SIZE);
 
@@ -235,6 +245,12 @@
 
 		bytes_written += wrote;
 
+		if (file->f_flags & O_NONBLOCK) {
+			if (!bytes_written)
+				bytes_written = -EAGAIN;
+			break;
+		}
+
 		if (signal_pending (current)) {
 			if (!bytes_written) {
 				bytes_written = -EINTR;
@@ -247,6 +263,8 @@
 		}
 	}
 
+	parport_set_timeout (pp->pdev, pp->default_inactivity);
+
 	kfree (kbuffer);
 	pp_enable_irq (pp);
 	return bytes_written;
@@ -356,6 +374,8 @@
 		pp->saved_state.phase = info->phase;
 		info->mode = pp->state.mode;
 		info->phase = pp->state.phase;
+		pp->default_inactivity = parport_set_timeout (pp->pdev, 0);
+		parport_set_timeout (pp->pdev, pp->default_inactivity);
 
 		return 0;
 	    }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/pty.c linux/drivers/char/pty.c
--- linux.orig/drivers/char/pty.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/char/pty.c	2002-07-20 01:08:31.000000000 +0000
@@ -5,6 +5,10 @@
  *
  *  Added support for a Unix98-style ptmx device.
  *    -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
+ *  Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to
+ *      waiting writers -- Sapan Bhatia <sapan@corewars.org>
+ *
+ *
  */
 
 #include <linux/config.h>
@@ -331,6 +335,8 @@
 	clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 	wake_up_interruptible(&pty->open_wait);
 	set_bit(TTY_THROTTLED, &tty->flags);
+	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+
 	/*  Register a slave for the master  */
 	if (tty->driver.major == PTY_MASTER_MAJOR)
 		tty_register_devfs(&tty->link->driver,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/q40_keyb.c linux/drivers/char/q40_keyb.c
--- linux.orig/drivers/char/q40_keyb.c	2001-02-09 19:30:22.000000000 +0000
+++ linux/drivers/char/q40_keyb.c	2002-07-20 01:08:37.000000000 +0000
@@ -31,9 +31,6 @@
 #include <asm/irq.h>
 #include <asm/q40ints.h>
 
-/* Some configuration switches are present in the include file... */
-
-#define KBD_REPORT_ERR
 
 /* Simple translation table for the SysRq keys */
 
@@ -215,7 +212,6 @@
   0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
 };
 
-static unsigned int prev_scancode = 0;   /* remember E0, E1 */
 
 int q40kbd_setkeycode(unsigned int scancode, unsigned int keycode)
 {
@@ -246,10 +242,21 @@
 int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
 		    char raw_mode)
 {
-  	if (scancode == 0xe0 || scancode == 0xe1) {
+	static int prev_scancode;
+
+	/* special prefix scancodes.. */
+	if (scancode == 0xe0 || scancode == 0xe1) {
 		prev_scancode = scancode;
 		return 0;
- 	}
+	}
+
+	/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
+	if (scancode == 0x00 || scancode == 0xff) {
+		prev_scancode = 0;
+		return 0;
+	}
+
+	scancode &= 0x7f;
 
 	if (prev_scancode) {
 	  /*
@@ -347,7 +354,7 @@
 	spin_lock(&kbd_controller_lock);
 	kbd_pt_regs = regs;
 
-	status = IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
+	status = Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
 	if (status ) 
 	  {
 	    unsigned char scancode,qcode;
@@ -398,7 +405,7 @@
 	int retval = KBD_NO_DATA;
 	unsigned char status;
 
-	status = IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
+	status = Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
 	if (status) {
 		unsigned char data = master_inb(KEYCODE_REG);
 
@@ -408,8 +415,6 @@
 	return retval;
 }
 
-extern void q40kbd_leds(unsigned char leds)
-{ /* nothing can be done */ }
 
 static void __init kbd_clear_input(void)
 {
@@ -424,10 +429,7 @@
 
 void __init q40kbd_init_hw(void)
 {
-#if 0
-	/* Get the keyboard controller registers (incomplete decode) */
-	request_region(0x60, 16, "keyboard");
-#endif
+
 	/* Flush any pending input. */
 	kbd_clear_input();
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/qtronix.c linux/drivers/char/qtronix.c
--- linux.orig/drivers/char/qtronix.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/drivers/char/qtronix.c	2002-07-20 01:08:33.000000000 +0000
@@ -51,6 +51,7 @@
 
 #ifdef CONFIG_QTRONIX_KEYBOARD
 
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -121,7 +122,7 @@
 
 };
 
-void init_qtronix_990P_kbd(void)
+void __init init_qtronix_990P_kbd(void)
 {
 	int retval;
 
@@ -594,4 +595,5 @@
 
 	return 0;
 }
+module_init(init_qtronix_990P_kbd);
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/qtronixmap.c linux/drivers/char/qtronixmap.c
--- linux.orig/drivers/char/qtronixmap.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/qtronixmap.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,265 @@
+
+/* Do not edit this file! It was automatically generated by   */
+/*    loadkeys --mktable defkeymap.map > defkeymap.c          */
+
+#include <linux/types.h>
+#include <linux/keyboard.h>
+#include <linux/kd.h>
+
+u_short plain_map[NR_KEYS] = {
+	0xf200,	0xf060,	0xf031,	0xf032,	0xf033,	0xf034,	0xf035,	0xf036,
+	0xf037,	0xf038,	0xf039,	0xf030,	0xf02d,	0xf03d,	0xf200,	0xf07f,
+	0xf009,	0xfb71,	0xfb77,	0xfb65,	0xfb72,	0xfb74,	0xfb79,	0xfb75,
+	0xfb69,	0xfb6f,	0xfb70,	0xf05b,	0xf05d,	0xf05c,	0xf207,	0xfb61,
+	0xfb73,	0xfb64,	0xfb66,	0xfb67,	0xfb68,	0xfb6a,	0xfb6b,	0xfb6c,
+	0xf03b,	0xf027,	0xf060,	0xf201,	0xf700,	0xf200,	0xfb7a,	0xfb78,
+	0xfb63,	0xfb76,	0xfb62,	0xfb6e,	0xfb6d,	0xf02c,	0xf02e,	0xf02f,
+	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf020,	0xf703,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
+	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
+	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf01b,	0xf200,
+	0xf100,	0xf101,	0xf102,	0xf103,	0xf104,	0xf105,	0xf106,	0xf107,
+	0xf108,	0xf109,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
+};
+
+u_short shift_map[NR_KEYS] = {
+	0xf200,	0xf07e,	0xf021,	0xf040,	0xf023,	0xf024,	0xf025,	0xf05e,
+	0xf026,	0xf02a,	0xf028,	0xf029,	0xf05f,	0xf02b,	0xf200,	0xf07f,
+	0xf009,	0xfb51,	0xfb57,	0xfb45,	0xfb52,	0xfb54,	0xfb59,	0xfb55,
+	0xfb49,	0xfb4f,	0xfb50,	0xf07b,	0xf07d,	0xf07c,	0xf207,	0xfb41,
+	0xfb53,	0xfb44,	0xfb46,	0xfb47,	0xfb48,	0xfb4a,	0xfb4b,	0xfb4c,
+	0xf03a,	0xf022,	0xf07e,	0xf201,	0xf700,	0xf200,	0xfb5a,	0xfb58,
+	0xfb43,	0xfb56,	0xfb42,	0xfb4e,	0xfb4d,	0xf03c,	0xf03e,	0xf03f,
+	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf020,	0xf703,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
+	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf20b,	0xf20a,	0xf200,
+	0xf200,	0xf602,	0xf213,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf01b,	0xf200,
+	0xf10a,	0xf10b,	0xf10c,	0xf10d,	0xf10e,	0xf10f,	0xf110,	0xf111,
+	0xf112,	0xf113,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
+};
+
+u_short altgr_map[NR_KEYS] = {
+	0xf200,	0xf200,	0xf200,	0xf040,	0xf200,	0xf024,	0xf200,	0xf200,
+	0xf07b,	0xf05b,	0xf05d,	0xf07d,	0xf05c,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xfb71,	0xfb77,	0xfb65,	0xfb72,	0xfb74,	0xfb79,	0xfb75,
+	0xfb69,	0xfb6f,	0xfb70,	0xf200,	0xf200,	0xf200,	0xf207,	0xfb61,
+	0xfb73,	0xfb64,	0xfb66,	0xfb67,	0xfb68,	0xfb6a,	0xfb6b,	0xfb6c,
+	0xf200,	0xf200,	0xf200,	0xf201,	0xf700,	0xf200,	0xfb7a,	0xfb78,
+	0xfb63,	0xfb76,	0xfb62,	0xfb6e,	0xfb6d,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf200,	0xf703,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
+	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
+	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
+	0xf50c,	0xf50d,	0xf50e,	0xf50f,	0xf510,	0xf511,	0xf512,	0xf513,
+	0xf514,	0xf515,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
+};
+
+u_short ctrl_map[NR_KEYS] = {
+	0xf200,	0xf200,	0xf200,	0xf000,	0xf01b,	0xf01c,	0xf01d,	0xf01e,
+	0xf01f,	0xf07f,	0xf200,	0xf200,	0xf01f,	0xf200,	0xf200,	0xf008,
+	0xf200,	0xf011,	0xf017,	0xf005,	0xf012,	0xf014,	0xf019,	0xf015,
+	0xf009,	0xf00f,	0xf010,	0xf01b,	0xf01d,	0xf01c,	0xf207,	0xf001,
+	0xf013,	0xf004,	0xf006,	0xf007,	0xf008,	0xf00a,	0xf00b,	0xf00c,
+	0xf007,	0xf000,	0xf200,	0xf201,	0xf700,	0xf200,	0xf01a,	0xf018,
+	0xf003,	0xf016,	0xf002,	0xf00e,	0xf20e,	0xf07f,	0xf200,	0xf200,
+	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf000,	0xf703,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
+	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
+	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
+	0xf100,	0xf101,	0xf102,	0xf103,	0xf104,	0xf105,	0xf106,	0xf107,
+	0xf108,	0xf109,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
+};
+
+u_short shift_ctrl_map[NR_KEYS] = {
+	0xf200,	0xf200,	0xf200,	0xf000,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf01f,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf011,	0xf017,	0xf005,	0xf012,	0xf014,	0xf019,	0xf015,
+	0xf009,	0xf00f,	0xf010,	0xf200,	0xf200,	0xf200,	0xf207,	0xf001,
+	0xf013,	0xf004,	0xf006,	0xf007,	0xf008,	0xf00a,	0xf00b,	0xf00c,
+	0xf200,	0xf200,	0xf200,	0xf201,	0xf700,	0xf200,	0xf01a,	0xf018,
+	0xf003,	0xf016,	0xf002,	0xf00e,	0xf00d,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf200,	0xf703,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
+	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
+	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
+};
+
+u_short alt_map[NR_KEYS] = {
+	0xf200,	0xf81b,	0xf831,	0xf832,	0xf833,	0xf834,	0xf835,	0xf836,
+	0xf837,	0xf838,	0xf839,	0xf830,	0xf82d,	0xf83d,	0xf200,	0xf87f,
+	0xf809,	0xf871,	0xf877,	0xf865,	0xf872,	0xf874,	0xf879,	0xf875,
+	0xf869,	0xf86f,	0xf870,	0xf85b,	0xf85d,	0xf85c,	0xf207,	0xf861,
+	0xf873,	0xf864,	0xf866,	0xf867,	0xf868,	0xf86a,	0xf86b,	0xf83b,
+	0xf827,	0xf860,	0xf200,	0xf80d,	0xf700,	0xf200,	0xf87a,	0xf878,
+	0xf863,	0xf876,	0xf862,	0xf82c,	0xf82e,	0xf82f,	0xf200,	0xf200,
+	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf820,	0xf703,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf210,
+	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
+	0xf200,	0xf211,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
+	0xf500,	0xf501,	0xf502,	0xf503,	0xf504,	0xf505,	0xf506,	0xf507,
+	0xf508,	0xf509,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
+};
+
+u_short ctrl_alt_map[NR_KEYS] = {
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf811,	0xf817,	0xf805,	0xf812,	0xf814,	0xf819,	0xf815,
+	0xf809,	0xf80f,	0xf810,	0xf200,	0xf200,	0xf200,	0xf207,	0xf801,
+	0xf813,	0xf804,	0xf806,	0xf807,	0xf808,	0xf80a,	0xf80b,	0xf80c,
+	0xf200,	0xf200,	0xf200,	0xf201,	0xf700,	0xf200,	0xf81a,	0xf818,
+	0xf803,	0xf816,	0xf802,	0xf80e,	0xf80d,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf700,	0xf702,	0xf200,	0xf703,	0xf200,	0xf703,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf115,	0xf07f,	0xf200,	0xf200,	0xf601,
+	0xf200,	0xf200,	0xf200,	0xf603,	0xf600,	0xf118,	0xf119,	0xf200,
+	0xf200,	0xf602,	0xf208,	0xf02d,	0xf02b,	0xf30c,	0xf02e,	0xf30d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf200,	0xf200,	0xf200,	0xf117,	0xf600,	0xf200,	0xf200,	0xf200,
+	0xf500,	0xf501,	0xf502,	0xf503,	0xf504,	0xf505,	0xf506,	0xf507,
+	0xf508,	0xf509,	0xf200,	0xf200,	0xf200,	0xf200,	0xf11d,	0xf200,
+};
+
+ushort *key_maps[MAX_NR_KEYMAPS] = {
+	plain_map, shift_map, altgr_map, 0,
+	ctrl_map, shift_ctrl_map, 0, 0,
+	alt_map, 0, 0, 0,
+	ctrl_alt_map,	0
+};
+
+unsigned int keymap_count = 7;
+
+
+/*
+ * Philosophy: most people do not define more strings, but they who do
+ * often want quite a lot of string space. So, we statically allocate
+ * the default and allocate dynamically in chunks of 512 bytes.
+ */
+
+char func_buf[] = {
+	'\033', '[', '[', 'A', 0, 
+	'\033', '[', '[', 'B', 0, 
+	'\033', '[', '[', 'C', 0, 
+	'\033', '[', '[', 'D', 0, 
+	'\033', '[', '[', 'E', 0, 
+	'\033', '[', '1', '7', '~', 0, 
+	'\033', '[', '1', '8', '~', 0, 
+	'\033', '[', '1', '9', '~', 0, 
+	'\033', '[', '2', '0', '~', 0, 
+	'\033', '[', '2', '1', '~', 0, 
+	'\033', '[', '2', '3', '~', 0, 
+	'\033', '[', '2', '4', '~', 0, 
+	'\033', '[', '2', '5', '~', 0, 
+	'\033', '[', '2', '6', '~', 0, 
+	'\033', '[', '2', '8', '~', 0, 
+	'\033', '[', '2', '9', '~', 0, 
+	'\033', '[', '3', '1', '~', 0, 
+	'\033', '[', '3', '2', '~', 0, 
+	'\033', '[', '3', '3', '~', 0, 
+	'\033', '[', '3', '4', '~', 0, 
+	'\033', '[', '1', '~', 0, 
+	'\033', '[', '2', '~', 0, 
+	'\033', '[', '3', '~', 0, 
+	'\033', '[', '4', '~', 0, 
+	'\033', '[', '5', '~', 0, 
+	'\033', '[', '6', '~', 0, 
+	'\033', '[', 'M', 0, 
+	'\033', '[', 'P', 0, 
+};
+
+
+char *funcbufptr = func_buf;
+int funcbufsize = sizeof(func_buf);
+int funcbufleft = 0;          /* space left */
+
+char *func_table[MAX_NR_FUNC] = {
+	func_buf + 0,
+	func_buf + 5,
+	func_buf + 10,
+	func_buf + 15,
+	func_buf + 20,
+	func_buf + 25,
+	func_buf + 31,
+	func_buf + 37,
+	func_buf + 43,
+	func_buf + 49,
+	func_buf + 55,
+	func_buf + 61,
+	func_buf + 67,
+	func_buf + 73,
+	func_buf + 79,
+	func_buf + 85,
+	func_buf + 91,
+	func_buf + 97,
+	func_buf + 103,
+	func_buf + 109,
+	func_buf + 115,
+	func_buf + 120,
+	func_buf + 125,
+	func_buf + 130,
+	func_buf + 135,
+	func_buf + 140,
+	func_buf + 145,
+	0,
+	0,
+	func_buf + 149,
+	0,
+};
+
+struct kbdiacr accent_table[MAX_DIACR] = {
+	{'`', 'A', 'À'},	{'`', 'a', 'à'},
+	{'\'', 'A', 'Á'},	{'\'', 'a', 'á'},
+	{'^', 'A', 'Â'},	{'^', 'a', 'â'},
+	{'~', 'A', 'Ã'},	{'~', 'a', 'ã'},
+	{'"', 'A', 'Ä'},	{'"', 'a', 'ä'},
+	{'O', 'A', 'Å'},	{'o', 'a', 'å'},
+	{'0', 'A', 'Å'},	{'0', 'a', 'å'},
+	{'A', 'A', 'Å'},	{'a', 'a', 'å'},
+	{'A', 'E', 'Æ'},	{'a', 'e', 'æ'},
+	{',', 'C', 'Ç'},	{',', 'c', 'ç'},
+	{'`', 'E', 'È'},	{'`', 'e', 'è'},
+	{'\'', 'E', 'É'},	{'\'', 'e', 'é'},
+	{'^', 'E', 'Ê'},	{'^', 'e', 'ê'},
+	{'"', 'E', 'Ë'},	{'"', 'e', 'ë'},
+	{'`', 'I', 'Ì'},	{'`', 'i', 'ì'},
+	{'\'', 'I', 'Í'},	{'\'', 'i', 'í'},
+	{'^', 'I', 'Î'},	{'^', 'i', 'î'},
+	{'"', 'I', 'Ï'},	{'"', 'i', 'ï'},
+	{'-', 'D', 'Ð'},	{'-', 'd', 'ð'},
+	{'~', 'N', 'Ñ'},	{'~', 'n', 'ñ'},
+	{'`', 'O', 'Ò'},	{'`', 'o', 'ò'},
+	{'\'', 'O', 'Ó'},	{'\'', 'o', 'ó'},
+	{'^', 'O', 'Ô'},	{'^', 'o', 'ô'},
+	{'~', 'O', 'Õ'},	{'~', 'o', 'õ'},
+	{'"', 'O', 'Ö'},	{'"', 'o', 'ö'},
+	{'/', 'O', 'Ø'},	{'/', 'o', 'ø'},
+	{'`', 'U', 'Ù'},	{'`', 'u', 'ù'},
+	{'\'', 'U', 'Ú'},	{'\'', 'u', 'ú'},
+	{'^', 'U', 'Û'},	{'^', 'u', 'û'},
+	{'"', 'U', 'Ü'},	{'"', 'u', 'ü'},
+	{'\'', 'Y', 'Ý'},	{'\'', 'y', 'ý'},
+	{'T', 'H', 'Þ'},	{'t', 'h', 'þ'},
+	{'s', 's', 'ß'},	{'"', 'y', 'ÿ'},
+	{'s', 'z', 'ß'},	{'i', 'j', 'ÿ'},
+};
+
+unsigned int accent_table_size = 68;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/raw.c linux/drivers/char/raw.c
--- linux.orig/drivers/char/raw.c	2001-09-23 03:35:43.000000000 +0000
+++ linux/drivers/char/raw.c	2002-07-20 01:08:24.000000000 +0000
@@ -34,6 +34,7 @@
 int	raw_open(struct inode *, struct file *);
 int	raw_release(struct inode *, struct file *);
 int	raw_ctl_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int	raw_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
 
 
 static struct file_operations raw_fops = {
@@ -41,6 +42,7 @@
 	write:		raw_write,
 	open:		raw_open,
 	release:	raw_release,
+	ioctl:		raw_ioctl,
 };
 
 static struct file_operations raw_ctl_fops = {
@@ -160,6 +162,25 @@
 
 
 
+/* Forward ioctls to the underlying block device. */ 
+int raw_ioctl(struct inode *inode, 
+		  struct file *flip,
+		  unsigned int command, 
+		  unsigned long arg)
+{
+	int minor = minor(inode->i_rdev), err; 
+	struct block_device *b; 
+	if (minor < 1 && minor > 255)
+		return -ENODEV;
+
+	b = raw_devices[minor].binding;
+	err = -EINVAL; 
+	if (b && b->bd_inode && b->bd_op && b->bd_op->ioctl) { 
+		err = b->bd_op->ioctl(b->bd_inode, NULL, command, arg); 
+	} 
+	return err;
+} 
+
 /*
  * Deal with ioctls against the raw-device control interface, to bind
  * and unbind other raw devices.  
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/rocket_int.h linux/drivers/char/rocket_int.h
--- linux.orig/drivers/char/rocket_int.h	2000-12-11 20:51:57.000000000 +0000
+++ linux/drivers/char/rocket_int.h	2002-07-20 01:08:27.000000000 +0000
@@ -185,7 +185,7 @@
 
 /* Old clock prescale definition and baud rates associated with it */
 
-#define CLOCK_PRESC 0x19  */        /* mod 9 (divide by 10) prescale */
+#define CLOCK_PRESC 0x19          /* mod 9 (divide by 10) prescale */
 #define BRD50             4607
 #define BRD75             3071
 #define BRD110            2094
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/rtc.c linux/drivers/char/rtc.c
--- linux.orig/drivers/char/rtc.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/char/rtc.c	2002-07-20 01:08:34.000000000 +0000
@@ -67,6 +67,7 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
+#include <linux/sysctl.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -138,6 +139,7 @@
 static unsigned long rtc_status = 0;	/* bitmapped status byte.	*/
 static unsigned long rtc_freq = 0;	/* Current periodic IRQ rate	*/
 static unsigned long rtc_irq_data = 0;	/* our output to the world	*/
+static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */
 
 /*
  *	If this driver ever becomes modularised, it will be really nice
@@ -187,6 +189,38 @@
 #endif
 
 /*
+ * sysctl-tuning infrastructure.
+ */
+static ctl_table rtc_table[] = {
+    { 1, "max-user-freq", &rtc_max_user_freq, sizeof(int), 0644, NULL,
+      &proc_dointvec, NULL, },
+    { 0, }
+};
+
+static ctl_table rtc_root[] = {
+    { 1, "rtc", NULL, 0, 0555, rtc_table, },
+    { 0, }
+};
+
+static ctl_table dev_root[] = {
+    { CTL_DEV, "dev", NULL, 0, 0555, rtc_root, },
+    { 0, }
+};
+
+static struct ctl_table_header *sysctl_header;
+
+static int __init init_sysctl(void)
+{
+    sysctl_header = register_sysctl_table(dev_root, 0);
+    return 0;
+}
+
+static void __exit cleanup_sysctl(void)
+{
+    unregister_sysctl_table(sysctl_header);
+}
+
+/*
  *	Now all the various file operations that we export.
  */
 
@@ -295,7 +329,8 @@
 		 * We don't really want Joe User enabling more
 		 * than 64Hz of interrupts on a multi-user machine.
 		 */
-		if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE)))
+		if ((rtc_freq > rtc_max_user_freq) && 
+		    (!capable(CAP_SYS_RESOURCE)))
 			return -EACCES;
 
 		if (!(rtc_status & RTC_TIMER_ON)) {
@@ -493,7 +528,7 @@
 		 * We don't really want Joe User generating more
 		 * than 64Hz of interrupts on a multi-user machine.
 		 */
-		if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
+		if ((arg > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE)))
 			return -EACCES;
 
 		while (arg > (1<<tmp))
@@ -534,7 +569,7 @@
 		return 0;
 	}
 	default:
-		return -EINVAL;
+		return -ENOTTY;
 	}
 	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
 }
@@ -720,7 +755,7 @@
 	}
 no_irq:
 #else
-	if (check_region (RTC_PORT (0), RTC_IO_EXTENT))
+	if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"))
 	{
 		printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0));
 		return -EIO;
@@ -731,11 +766,11 @@
 	{
 		/* Yeah right, seeing as irq 8 doesn't even hit the bus. */
 		printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
+		release_region(RTC_PORT(0), RTC_IO_EXTENT);
 		return -EIO;
 	}
 #endif
 
-	request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
 #endif /* __sparc__ vs. others */
 
 	misc_register(&rtc_dev);
@@ -798,6 +833,8 @@
 no_irq2:
 #endif
 
+	(void) init_sysctl();
+
 	printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n");
 
 	return 0;
@@ -805,6 +842,7 @@
 
 static void __exit rtc_exit (void)
 {
+	cleanup_sysctl();
 	remove_proc_entry ("driver/rtc", NULL);
 	misc_deregister(&rtc_dev);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sb1250_duart.c linux/drivers/char/sb1250_duart.c
--- linux.orig/drivers/char/sb1250_duart.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/sb1250_duart.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,799 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+
+/* 
+ * Driver support for the on-chip sb1250 dual-channel serial port,
+ * running in asynchronous mode.  Also, support for doing a serial console
+ * on one of those ports 
+ *
+ * The non-console part of this code is based heavily on the serial_21285.c
+ * driver also in this directory.  See tty_driver.h for a description of some
+ * of the driver functions, though it (like most of the inline code documentation :)
+ * is a bit out of date.  
+ */
+
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/termios.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+#include <linux/tty_flip.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/sibyte/swarm.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/64bit.h>
+
+/* Toggle spewing of debugging output */
+#undef DUART_SPEW
+
+#define DEFAULT_CFLAGS          (CS8 | B115200)
+
+
+/*
+  Still not sure what the termios structures set up here are for, 
+   but we have to supply pointers to them to register the tty driver
+*/
+
+static struct tty_driver sb1250_duart_driver, sb1250_duart_callout_driver;
+static int ref_count;
+static struct tty_struct *duart_table[2];
+static struct termios    *duart_termios[2];
+static struct termios    *duart_termios_locked[2];
+
+/* This lock protects both the open flags for all the uart states as 
+   well as the reference count for the module */
+static spinlock_t          open_lock = SPIN_LOCK_UNLOCKED;
+
+/* Protect the writing stuff from contention */
+//static spinlock_t          console_lock = SPIN_LOCK_UNLOCKED;
+
+/* Bit fields of flags in the flags field below */
+
+#define SD_WRITE_WAKE       0x000000001
+
+
+typedef struct { 
+	struct tty_struct   *tty;
+	unsigned char       outp_buf[CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE];
+	unsigned int        outp_head;
+	unsigned int        outp_tail;
+	unsigned int        outp_count;
+	spinlock_t          outp_lock;
+	unsigned int        outp_stopped;
+	unsigned int        open;
+	unsigned long       flags;
+	unsigned int        last_cflags;
+} uart_state_t;
+
+static uart_state_t uart_states[2] = { [0 ... 1] = {
+	tty:                0,
+	outp_head:          0,
+	outp_tail:          0,
+	outp_lock:          SPIN_LOCK_UNLOCKED,
+	outp_count:         0,
+	open:               0,
+	flags:              0,
+	last_cflags:        0,
+}};
+
+/*
+ * Inline functions local to this module 
+ */
+
+
+/*
+ * Mask out the passed interrupt lines at the duart level.  This should be
+ * called while holding the associated outp_lock.
+ */
+static inline void duart_mask_ints(unsigned int line, unsigned int mask)
+{
+	u64 tmp;
+	tmp = in64(IO_SPACE_BASE | A_DUART_IMRREG(line));
+	tmp &= ~mask;
+	out64(tmp, IO_SPACE_BASE | A_DUART_IMRREG(line));
+}
+
+	
+/* Unmask the passed interrupt lines at the duart level */
+static inline void duart_unmask_ints(unsigned int line, unsigned int mask)
+{
+	u64 tmp;
+	tmp = in64(IO_SPACE_BASE | A_DUART_IMRREG(line));
+	tmp |= mask;
+	out64(tmp, IO_SPACE_BASE | A_DUART_IMRREG(line));
+}
+
+static inline unsigned long get_status_reg(unsigned int line)
+{
+	return in64(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_STATUS));
+}
+
+/* Derive which uart a call is for from the passed tty line.  */
+static inline unsigned int get_line(struct tty_struct *tty) 
+{
+	unsigned int line = MINOR(tty->device) - 64;
+	if (line > 1)
+		printk(KERN_CRIT "Invalid line\n");
+
+	return line;
+}
+
+
+
+#define MIN(a, b) (((a)<(b))?(a):(b))
+
+/* 
+ * Generic interrupt handler for both channels.  dev_id is a pointer
+ * to the proper uart_states structure, so from that we can derive 
+ * which port interrupted 
+ */
+
+static void duart_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int line;
+	uart_state_t *us = (uart_state_t *)dev_id;
+	line = us-uart_states;
+#ifdef DUART_SPEW
+//	setleds("INT!");
+        printk("DUART INT\n");
+#endif
+	/* We could query the ISR to figure out why we are here, but since
+	   we are here, we may as well just take care of both rx and tx */
+	spin_lock(&us->outp_lock);
+	if (get_status_reg(line) & M_DUART_RX_RDY) {
+		do {
+			unsigned int status = get_status_reg(line);
+			unsigned int ch = in64(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_RX_HOLD));
+			unsigned int flag = 0;
+			if (status & 0x10) {
+				tty_insert_flip_char(us->tty, 0, TTY_OVERRUN);			}
+			if (status & 0x20) {
+				printk("Parity error!\n");
+				flag = TTY_PARITY;
+			} else if (status & 0x40) {
+				printk("Frame error!\n");
+				flag = TTY_FRAME;
+			}
+			tty_insert_flip_char(us->tty, ch, flag);
+		} while (get_status_reg(line) & M_DUART_RX_RDY);
+		tty_flip_buffer_push(us->tty);
+	} 
+	if ((get_status_reg(line) & M_DUART_TX_RDY) && us->outp_count) {
+		do {
+			out64(us->outp_buf[us->outp_head], IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_TX_HOLD));
+			us->outp_head = (us->outp_head + 1) & (CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1);
+			us->outp_count--;
+		} while ((get_status_reg(line) & M_DUART_TX_RDY) && us->outp_count);
+
+		if (us->open && (us->flags & SD_WRITE_WAKE) &&
+		    (us->outp_count < (CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE/2))) {
+			/* We told the discipline at one point that we had no space, so it went
+			   to sleep.  Wake it up when we hit half empty */
+			wake_up_interruptible(&us->tty->write_wait);
+		}
+		if (!us->outp_count) {
+			duart_mask_ints(line, M_DUART_IMR_TX);
+		}
+	}
+	spin_unlock(&us->outp_lock);
+}
+
+/*
+ *  Actual driver functions
+ */
+
+/* Return the number of characters we can accomodate in a write at this instant */
+static int duart_write_room(struct tty_struct *tty)
+{
+	unsigned long flags;
+	int retval;
+	uart_state_t *us = &uart_states[get_line(tty)];
+
+	spin_lock_irqsave(&us->outp_lock, flags);
+	retval = CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE - uart_states[get_line(tty)].outp_count;
+	if (!retval) {
+		us->flags |= SD_WRITE_WAKE;
+	}
+	spin_unlock_irqrestore(&us->outp_lock, flags);
+#ifdef DUART_SPEW
+	printk("duart_write_room called, returning %i\n", retval);
+#endif
+	return retval;
+}
+
+/* memcpy the data from src to destination, but take extra care if the
+   data is coming from user space */
+static inline int copy_buf(char *dest, const char *src, int size, int from_user) 
+{
+	if (from_user) {
+		(void) copy_from_user(dest, src, size); 
+	} else {
+		memcpy(dest, src, size);
+	}
+	return size;
+}
+
+/* Buffer up to count characters from buf to be written.  If we don't have other
+   characters buffered, enable the tx interrupt to start sending */
+static int duart_write(struct tty_struct * tty, int from_user,
+		      const unsigned char *buf, int count)
+{
+	uart_state_t *us;
+	unsigned long flags;
+	unsigned int line;
+	int chars_written = 0;
+	if (from_user && verify_area(VERIFY_READ, buf, count)) {
+		return -EINVAL;
+	}
+#ifdef DUART_SPEW
+	printk("duart_write called for %i chars by %i (%s)\n", count, current->pid, current->comm);
+#endif
+	line = get_line(tty);
+	us = &uart_states[line];
+	spin_lock_irqsave(&us->outp_lock, flags);
+	if (!count || (us->outp_count == CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE)) {
+		spin_unlock_irqrestore(&us->outp_lock, flags);
+		return 0;
+	}
+	if (us->outp_tail < us->outp_head) {
+		/* Straightforward case; copy from tail to head */
+		chars_written += copy_buf(us->outp_buf + us->outp_tail, buf, 
+					  MIN(count, us->outp_head - us->outp_tail), from_user);
+	} else {
+		/* Copy from tail to end of buffer, wrap around and then
+		   copy to head */
+		chars_written += copy_buf(us->outp_buf + us->outp_tail, buf, 
+					  MIN(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE - us->outp_tail, count), 
+					  from_user);
+		if (chars_written < count) {
+			chars_written += copy_buf(us->outp_buf, buf + chars_written,
+						  MIN(us->outp_head, count - chars_written), from_user);
+		}
+	}
+	us->outp_tail = (us->outp_tail + chars_written) &(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1);
+	if (!(us->outp_count || us->outp_stopped)) {
+		duart_unmask_ints(line, M_DUART_IMR_TX);
+	}
+	us->outp_count += chars_written;
+	spin_unlock_irqrestore(&us->outp_lock, flags);
+	return chars_written;
+}	
+
+
+/* Buffer one character to be written.  If there's not room for it, just drop
+   it on the floor.  This is used for echo, among other things */
+static void duart_put_char(struct tty_struct *tty, u_char ch)
+{
+	unsigned long flags;
+	unsigned int line = get_line(tty);
+	uart_state_t *us = &uart_states[line];
+#ifdef DUART_SPEW
+	printk("duart_put_char called.  Char is %x (%c)\n", (int)ch, ch);
+#endif
+	spin_lock_irqsave(&us->outp_lock, flags);
+	if (us->outp_count != CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE) {
+		us->outp_buf[us->outp_tail] = ch;
+		us->outp_tail = (us->outp_tail + 1) &(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1);
+		if (!(us->outp_count || us->outp_stopped)) {
+			duart_unmask_ints(line, M_DUART_IMR_TX);
+		}
+		us->outp_count++;
+	}
+	spin_unlock_irqrestore(&us->outp_lock, flags);
+}
+
+/* Return the number of characters in the output buffer that have yet to be 
+   written */
+static int duart_chars_in_buffer(struct tty_struct *tty)
+{
+	int retval;
+	unsigned long flags;
+	uart_state_t *us = &uart_states[get_line(tty)];
+	spin_lock_irqsave(&us->outp_lock, flags);
+	retval = us->outp_count;
+	if (retval) {
+		us->flags |= SD_WRITE_WAKE;
+	}
+	spin_unlock_irqrestore(&us->outp_lock, flags);
+#ifdef DUART_SPEW
+	printk("duart_chars_in_buffer returning %i\n", retval);
+#endif
+	return retval;
+}
+
+/* Kill everything we haven't yet shoved into the FIFO.  Turn off the
+   transmit interrupt since we've nothing more to transmit */
+static void duart_flush_buffer(struct tty_struct *tty)
+{
+	unsigned long flags;
+	unsigned int line = get_line(tty);
+	uart_state_t *us = &uart_states[get_line(tty)];
+#ifdef DUART_SPEW
+	printk("duart_flush_buffer called\n");
+#endif
+	duart_mask_ints(line, M_DUART_IMR_TX);
+	spin_lock_irqsave(&us->outp_lock, flags);
+	us->outp_head = us->outp_tail = us->outp_count = 0;
+	if (us->flags & SD_WRITE_WAKE) {
+		wake_up_interruptible(&us->tty->write_wait);
+	}	
+	spin_unlock_irqrestore(&us->outp_lock, flags);
+}
+
+
+/* See sb1250 user manual for details on these registers */
+static inline void duart_set_cflag(unsigned int line, unsigned int cflag)
+{
+	unsigned int mode_reg1 = 0, mode_reg2 = 0;
+	unsigned int clk_divisor;
+	switch (cflag & CSIZE) {
+	case CS7:
+		mode_reg1 |= V_DUART_BITS_PER_CHAR_7;
+		
+	default:
+		/* We don't handle CS5 or CS6...is there a way we're supposed to flag this? 
+		   right now we just force them to CS8 */
+		mode_reg1 |= 0x0;
+		break;
+	}
+	if (cflag & CSTOPB) {
+	        mode_reg2 |= M_DUART_STOP_BIT_LEN_2;	/* XXX was: 0x4; */
+	}
+	if (!(cflag & PARENB)) {
+	        mode_reg1 |= V_DUART_PARITY_MODE_NONE;	/* XXX was: 0x8; */
+	}
+	if (cflag & PARODD) {
+		mode_reg1 |= M_DUART_PARITY_TYPE_ODD;
+	}
+	
+	/* Formula for this is (5000000/baud)-1, but we saturate
+	   at 12 bits, which means we can't actually do anything less
+	   that 1200 baud */
+	switch (cflag & CBAUD) {
+	case B200:	
+	case B300:	
+	case B1200:	clk_divisor = 4095;		break;
+	case B1800:	clk_divisor = 2776;		break;
+	case B2400:	clk_divisor = 2082;		break;
+	case B4800:	clk_divisor = 1040;		break;
+	default:
+	case B9600:	clk_divisor = 519;		break;
+	case B19200:	clk_divisor = 259;		break;
+	case B38400:	clk_divisor = 129;		break;
+	case B57600:	clk_divisor = 85;		break;
+	case B115200:	clk_divisor = 42;		break;
+	}
+	out64(mode_reg1, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_1));
+	out64(mode_reg2, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_2));
+	out64(clk_divisor, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_CLK_SEL));
+	uart_states[line].last_cflags = cflag;
+}
+
+
+/* Handle notification of a termios change.  */
+static void duart_set_termios(struct tty_struct *tty, struct termios *old)
+{
+#ifdef DUART_SPEW 
+	printk("duart_set_termios called by %i (%s)\n", current->pid, current->comm);
+#endif
+	if (old && tty->termios->c_cflag == old->c_cflag)
+		return;
+	duart_set_cflag(get_line(tty), tty->termios->c_cflag);
+}
+
+/* Stop pushing stuff into the fifo, now.  Do the mask under the 
+   outp_lock to avoid races involving turning the interrupt line on/off */
+static void duart_stop(struct tty_struct *tty)
+{
+	unsigned long flags;
+	unsigned int line = get_line(tty);
+	uart_state_t *us = &uart_states[line];
+#ifdef DUART_SPEW
+	printk("duart_stop called\n");
+#endif
+	spin_lock_irqsave(&us->outp_lock, flags);
+	duart_mask_ints(get_line(tty), M_DUART_IMR_TX);
+	us->outp_stopped = 1;
+	spin_unlock_irqrestore(&us->outp_lock, flags);
+}
+
+static int duart_ioctl(struct tty_struct *tty, struct file * file,
+		       unsigned int cmd, unsigned long arg)
+{
+/*	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+	return -ENODEV;*/
+	switch (cmd) {
+	case TIOCMGET:
+		printk("Ignoring TIOCMGET\n");
+		break;
+	case TIOCMBIS:
+		printk("Ignoring TIOCMBIS\n");
+		break;
+	case TIOCMBIC:
+		printk("Ignoring TIOCMBIC\n");
+		break;
+	case TIOCMSET:
+		printk("Ignoring TIOCMSET\n");
+		break;
+	case TIOCGSERIAL:
+		printk("Ignoring TIOCGSERIAL\n");
+		break;
+	case TIOCSSERIAL:
+		printk("Ignoring TIOCSSERIAL\n");
+		break;
+	case TIOCSERCONFIG:
+		printk("Ignoring TIOCSERCONFIG\n");
+		break;
+	case TIOCSERGETLSR: /* Get line status register */
+		printk("Ignoring TIOCSERGETLSR\n");
+		break;
+	case TIOCSERGSTRUCT:
+		printk("Ignoring TIOCSERGSTRUCT\n");
+		break;
+	case TIOCMIWAIT:
+		printk("Ignoring TIOCMIWAIT\n");
+		break;
+	case TIOCGICOUNT:
+		printk("Ignoring TIOCGICOUNT\n");
+		break;
+	case TIOCSERGWILD:
+		printk("Ignoring TIOCSERGWILD\n");
+		break;
+	case TIOCSERSWILD:
+		printk("Ignoring TIOCSERSWILD\n");
+		break;
+	default:
+		break;
+	}
+//	printk("Ignoring IOCTL %x from pid %i (%s)\n", cmd, current->pid, current->comm);
+	return -ENOIOCTLCMD;
+#if 0
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+	
+	switch (cmd) {
+	case TIOCMGET:
+	case TIOCMBIS:
+	case TIOCMBIC:
+	case TIOCMSET:
+	case TIOCGSERIAL:
+	case TIOCSSERIAL:
+	case TIOCSERCONFIG:
+	case TIOCSERGETLSR: /* Get line status register */
+	case TIOCSERGSTRUCT:
+	case TIOCMIWAIT:
+	case TIOCGICOUNT:
+	case TIOCSERGWILD:
+	case TIOCSERSWILD:
+		/* XXX Implement me! */
+		printk("IOCTL needs implementing: %x\n", cmd);
+		
+	default:
+		printk("Unknown ioctl: %x\n", cmd);
+	}
+#endif
+	return 0;
+}
+
+/* Stop pushing stuff into the fifo, now.  Do the mask under the 
+   outp_lock to avoid races involving turning the interrupt line on/off */
+static void duart_start(struct tty_struct *tty)
+{
+	unsigned long flags;
+	unsigned int line = get_line(tty);
+	uart_state_t *us = &uart_states[line];
+#ifdef DUART_SPEW
+	printk("duart_start called\n");
+#endif
+	spin_lock_irqsave(&us->outp_lock, flags);
+	if (us->outp_count) {
+		duart_unmask_ints(get_line(tty), M_DUART_IMR_TX);
+	}
+	us->outp_stopped = 0;
+	spin_unlock_irqrestore(&us->outp_lock, flags);
+}
+
+/* Not sure on the semantics of this; are we supposed to wait until the stuff
+   already in the hardware FIFO drains, or are we supposed to wait until 
+   we've drained the output buffer, too?  I'm assuming the former, 'cause thats
+   what the other drivers seem to assume 
+*/
+
+static void duart_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	unsigned long target_time;
+	unsigned int line;
+	uart_state_t *us;
+#ifdef DUART_SPEW
+	printk("duart_wait_until_sent(%d)+\n", timeout);
+#endif
+	target_time = jiffies + timeout;
+	line = get_line(tty);
+	us = &uart_states[line];
+	while (!(get_status_reg(line) & M_DUART_TX_EMT) && (jiffies < target_time)) {
+	 	schedule_timeout(1);
+	}
+#ifdef DUART_SPEW
+	printk("duart_wait_until_sent()-\n");
+#endif
+}
+
+/*
+ * Open a tty line.  Note that this can be called multiple times, so ->open can
+ * be >1.  Only set up the tty struct if this is a "new" open, e.g. ->open was
+ * zero
+ */
+static int duart_open(struct tty_struct *tty, struct file *filp)
+{
+	unsigned long flags;
+	unsigned int line;
+	uart_state_t *us;
+
+	MOD_INC_USE_COUNT;
+#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1
+	if (get_line(tty) > 1)
+#else
+	if (get_line(tty) > 0)
+#endif
+	                      {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+#ifdef DUART_SPEW
+	printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n", current->pid, current->comm, tty,
+	       tty->read_wait, tty->write_wait);
+#endif
+	line = get_line(tty);
+	tty->driver_data = NULL;
+	us = &uart_states[line];
+	
+	spin_lock_irqsave(&open_lock, flags);
+	if (!us->open) {
+		us->tty = tty;
+		us->tty->termios->c_cflag = us->last_cflags;
+	}
+	us->open++;
+#ifdef FORCED_INPUT
+	if (!line && (us->open == 1)) {
+		next_inp = inp_cmds;
+		init_timer(&inp_timer);
+		inp_timer.expires = jiffies + 20;
+		inp_timer.data = 0;
+		inp_timer.function = stuff_char;
+		stuff_char_tty = tty;
+		add_timer(&inp_timer);
+	}
+#endif
+	duart_unmask_ints(line, M_DUART_IMR_RX);
+	spin_unlock_irqrestore(&open_lock, flags);
+	return 0;
+}
+
+
+/*
+ * Close a reference count out.  If reference count hits zero, null the
+ * tty, kill the interrupts.  The tty_io driver is responsible for making
+ * sure we've cleared out our internal buffers before calling close()
+ */
+static void duart_close(struct tty_struct *tty, struct file *filp)
+{
+	unsigned long flags;
+	unsigned int line = get_line(tty);
+	uart_state_t *us = &uart_states[line];
+#ifdef DUART_SPEW
+	printk("duart_close called by %i (%s)\n", current->pid, current->comm);
+#endif
+	spin_lock_irqsave(&open_lock, flags);
+	us->open--;
+#if 0
+	if (!us->open) {
+		/* Flushing TX stuff here is conservative */
+		duart_mask_ints(line, M_DUART_IMR_IN | M_DUART_IMR_BRK | M_DUART_IMR_RX | M_DUART_IMR_TX);
+		spin_lock(&us->outp_lock);
+		us->outp_head = us->outp_tail = us->outp_count = us->outp_stopped = 0;
+		us->tty = NULL;
+		spin_unlock(&us->outp_lock);
+	}
+#endif
+	ref_count--;
+	spin_unlock_irqrestore(&open_lock, flags);
+	MOD_DEC_USE_COUNT;
+}
+
+
+/* Set up the driver and register it, register the 2 1250 UART interrupts.  This
+   is called from tty_init, or as a part of the module init */
+static int __init sb1250_duart_init(void) 
+{
+	sb1250_duart_driver.magic            = TTY_DRIVER_MAGIC;
+	sb1250_duart_driver.driver_name      = "serial";
+#ifdef CONFIG_DEVFS_FS
+	sb1250_duart_driver.name             = "tts/%d";
+#else
+	sb1250_duart_driver.name             = "ttyS";
+#endif
+	sb1250_duart_driver.major            = TTY_MAJOR;
+	sb1250_duart_driver.minor_start      = 64;
+	sb1250_duart_driver.num              = 2;
+	sb1250_duart_driver.type             = TTY_DRIVER_TYPE_SERIAL;
+	sb1250_duart_driver.subtype          = SERIAL_TYPE_NORMAL;
+	sb1250_duart_driver.init_termios     = tty_std_termios;
+	sb1250_duart_driver.flags            = TTY_DRIVER_REAL_RAW;
+	sb1250_duart_driver.refcount         = &ref_count;
+	sb1250_duart_driver.table            = duart_table;
+	sb1250_duart_driver.termios          = duart_termios;
+	sb1250_duart_driver.termios_locked   = duart_termios_locked;
+
+	sb1250_duart_driver.open             = duart_open;
+	sb1250_duart_driver.close            = duart_close;
+	sb1250_duart_driver.write            = duart_write;
+	sb1250_duart_driver.put_char         = duart_put_char;
+	sb1250_duart_driver.write_room       = duart_write_room;
+	sb1250_duart_driver.chars_in_buffer  = duart_chars_in_buffer;
+	sb1250_duart_driver.flush_buffer     = duart_flush_buffer;
+	sb1250_duart_driver.ioctl            = duart_ioctl;
+	sb1250_duart_driver.set_termios      = duart_set_termios;
+	sb1250_duart_driver.stop             = duart_stop;
+	sb1250_duart_driver.start            = duart_start;
+	sb1250_duart_driver.wait_until_sent  = duart_wait_until_sent;
+
+	sb1250_duart_callout_driver          = sb1250_duart_driver;
+#ifdef CONFIG_DEVFS_FS
+	sb1250_duart_callout_driver.name     = "cua/%d";
+#else
+	sb1250_duart_callout_driver.name     = "cua";
+#endif
+	sb1250_duart_callout_driver.major    = TTYAUX_MAJOR;
+	sb1250_duart_callout_driver.subtype  = SERIAL_TYPE_CALLOUT;
+
+	duart_mask_ints(0, 0xf);
+	if (request_irq(K_INT_UART_0, duart_int, 0, "uart0", &uart_states[0])) {
+		panic("Couldn't get uart0 interrupt line");
+	}
+#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1
+	duart_mask_ints(1, 0xf);
+	if (request_irq(K_INT_UART_1, duart_int, 0, "uart1", &uart_states[1])) {
+		panic("Couldn't get uart1 interrupt line");
+	}
+#endif	
+
+	/* Interrupts are now active, our ISR can be called. */
+
+	if (tty_register_driver(&sb1250_duart_driver)) {
+		printk(KERN_ERR "Couldn't register sb1250 duart serial driver\n");
+	}
+	if (tty_register_driver(&sb1250_duart_callout_driver)) {
+		printk(KERN_ERR "Couldn't register sb1250 duart callout driver\n");
+	}
+	duart_set_cflag(0, DEFAULT_CFLAGS);
+#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1
+	duart_set_cflag(1, DEFAULT_CFLAGS);
+#endif
+	return 0;
+}
+
+/* Unload the driver.  Unregister stuff, get ready to go away */
+static void __exit sb1250_duart_fini(void)
+{
+	unsigned long flags;
+	int ret;
+
+	save_flags(flags);
+	cli();
+	ret = tty_unregister_driver(&sb1250_duart_callout_driver);
+	if (ret) {
+		printk(KERN_ERR "Unable to unregister sb1250 duart callout driver (%d)\n", ret);
+	}
+	ret = tty_unregister_driver(&sb1250_duart_driver);
+	if (ret) {
+		printk(KERN_ERR "Unable to unregister sb1250 duart serial driver (%d)\n", ret);
+	}
+	free_irq(K_INT_UART_0, &uart_states[0]);
+	free_irq(K_INT_UART_1, &uart_states[1]);
+
+	/* mask lines in the scd */
+	disable_irq(K_INT_UART_0);
+	disable_irq(K_INT_UART_1);
+
+	restore_flags(flags);
+}
+
+module_init(sb1250_duart_init);
+module_exit(sb1250_duart_fini);
+MODULE_DESCRIPTION("SB1250 Duart serial driver");
+MODULE_AUTHOR("Justin Carlson <carlson@sibyte.com>");
+
+#ifdef CONFIG_SERIAL_CONSOLE
+
+/*
+ * Serial console stuff. 
+ * Very basic, polling driver for doing serial console output. 
+ * FIXME; there is a race here; we can't be sure that
+ * the tx is still empty without holding outp_lock for this line.
+ * Worst that can happen for now, though, is dropped characters.
+ */
+
+static void ser_console_write(struct console *cons, const char *str,
+                              unsigned int count)
+{
+	unsigned int i;
+	unsigned long flags;
+	spin_lock_irqsave(&uart_states[0].outp_lock, flags);
+
+	for (i = 0; i < count; i++) {
+                if (str[i] == '\n') {
+                        /* Expand LF -> CRLF */
+                        while (!(get_status_reg(0) & M_DUART_TX_RDY)) {
+                                /* Spin, doing nothing.  */
+                        }
+			out64('\r', IO_SPACE_BASE | A_DUART_CHANREG(0, R_DUART_TX_HOLD));
+                }
+		while (!(get_status_reg(0) & M_DUART_TX_RDY)) {
+			/* Spin, doing nothing.  */
+		}
+		out64(str[i], IO_SPACE_BASE | A_DUART_CHANREG(0, R_DUART_TX_HOLD));
+	}
+	spin_unlock_irqrestore(&uart_states[0].outp_lock, flags);
+}
+
+static kdev_t ser_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static int ser_console_setup(struct console *cons, char *str)
+{
+	/* Initialize the transmitter */
+	
+	duart_set_cflag(0, DEFAULT_CFLAGS);
+	return 0;
+}
+
+static struct console sb1250_ser_cons = {
+	name:		"ttyS",
+	write:		ser_console_write,
+	device:		ser_console_device,
+	setup:		ser_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init sb1250_serial_console_init(void)
+{
+	register_console(&sb1250_ser_cons);
+}
+
+#endif /* CONFIG_SERIAL_CONSOLE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sc1200wdt.c linux/drivers/char/sc1200wdt.c
--- linux.orig/drivers/char/sc1200wdt.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/sc1200wdt.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,463 @@
+/*
+ *	National Semiconductor PC87307/PC97307 (ala SC1200) WDT driver
+ *	(c) Copyright 2002 Zwane Mwaikambo <zwane@commfireservices.com>,
+ *			All Rights Reserved.
+ *	Based on wdt.c and wdt977.c by Alan Cox and Woody Suwalski respectively.
+ *
+ *	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.
+ *
+ *	The author(s) of this software shall not be held liable for damages
+ *	of any nature resulting due to the use of this software. This
+ *	software is provided AS-IS with no warranties.
+ *
+ *	Changelog:
+ *	20020220 Zwane Mwaikambo	Code based on datasheet, no hardware.
+ *	20020221 Zwane Mwaikambo	Cleanups as suggested by Jeff Garzik and Alan Cox.
+ *	20020222 Zwane Mwaikambo	Added probing.
+ *	20020225 Zwane Mwaikambo	Added ISAPNP support.
+ *	20020412 Rob Radez		Broke out start/stop functions
+ *		 <rob@osinvestor.com>	Return proper status instead of temperature warning
+ *					Add WDIOC_GETBOOTSTATUS and WDIOC_SETOPTIONS ioctls
+ *					Fix CONFIG_WATCHDOG_NOWAYOUT
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/isapnp.h>
+
+#define SC1200_MODULE_VER	"build 20020303"
+#define SC1200_MODULE_NAME	"sc1200wdt"
+#define PFX			SC1200_MODULE_NAME ": "
+
+#define	MAX_TIMEOUT	255	/* 255 minutes */
+#define PMIR		(io)	/* Power Management Index Register */
+#define PMDR		(io+1)	/* Power Management Data Register */
+
+/* Data Register indexes */
+#define FER1		0x00	/* Function enable register 1 */
+#define FER2		0x01	/* Function enable register 2 */
+#define PMC1		0x02	/* Power Management Ctrl 1 */
+#define PMC2		0x03	/* Power Management Ctrl 2 */
+#define PMC3		0x04	/* Power Management Ctrl 3 */
+#define WDTO		0x05	/* Watchdog timeout register */
+#define	WDCF		0x06	/* Watchdog config register */
+#define WDST		0x07	/* Watchdog status register */
+
+/* WDCF bitfields - which devices assert WDO */
+#define KBC_IRQ		0x01	/* Keyboard Controller */
+#define MSE_IRQ		0x02	/* Mouse */
+#define UART1_IRQ	0x03	/* Serial0 */
+#define UART2_IRQ	0x04	/* Serial1 */
+/* 5 -7 are reserved */
+
+static char banner[] __initdata = KERN_INFO PFX SC1200_MODULE_VER;
+static int timeout = 1;
+static int io = -1;
+static int io_len = 2;		/* for non plug and play */
+struct semaphore open_sem;
+static char expect_close;
+spinlock_t sc1200wdt_lock;	/* io port access serialisation */
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static int isapnp = 1;
+static struct pci_dev *wdt_dev;
+
+MODULE_PARM(isapnp, "i");
+MODULE_PARM_DESC(isapnp, "When set to 0 driver ISA PnP support will be disabled");
+#endif
+
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "io port");
+MODULE_PARM(timeout, "i");
+MODULE_PARM_DESC(timeout, "range is 0-255 minutes, default is 1");
+
+
+
+/* Read from Data Register */
+static inline void sc1200wdt_read_data(unsigned char index, unsigned char *data)
+{
+	spin_lock(&sc1200wdt_lock);
+	outb_p(index, PMIR);
+	*data = inb(PMDR);
+	spin_unlock(&sc1200wdt_lock);
+}
+
+
+/* Write to Data Register */
+static inline void sc1200wdt_write_data(unsigned char index, unsigned char data)
+{
+	spin_lock(&sc1200wdt_lock);
+	outb_p(index, PMIR);
+	outb(data, PMDR);
+	spin_unlock(&sc1200wdt_lock);
+}
+
+
+static void sc1200wdt_start(void)
+{
+	unsigned char reg;
+
+	sc1200wdt_read_data(WDCF, &reg);
+	/* assert WDO when any of the following interrupts are triggered too */
+	reg |= (KBC_IRQ | MSE_IRQ | UART1_IRQ | UART2_IRQ);
+	sc1200wdt_write_data(WDCF, reg);
+	/* set the timeout and get the ball rolling */
+	sc1200wdt_write_data(WDTO, timeout);
+}
+
+
+static void sc1200wdt_stop(void)
+{
+	sc1200wdt_write_data(WDTO, 0);
+}
+
+
+/* This returns the status of the WDO signal, inactive high. */
+static inline int sc1200wdt_status(void)
+{
+	unsigned char ret;
+
+	sc1200wdt_read_data(WDST, &ret);
+	/* If the bit is inactive, the watchdog is enabled, so return
+	 * KEEPALIVEPING which is a bit of a kludge because there's nothing
+	 * else for enabled/disabled status
+	 */
+	return (ret & 0x01) ? 0 : WDIOF_KEEPALIVEPING;	/* bits 1 - 7 are undefined */
+}
+
+
+static int sc1200wdt_open(struct inode *inode, struct file *file)
+{
+	/* allow one at a time */
+	if (down_trylock(&open_sem))
+		return -EBUSY;
+
+	if (timeout > MAX_TIMEOUT)
+		timeout = MAX_TIMEOUT;
+
+	sc1200wdt_start();
+	printk(KERN_INFO PFX "Watchdog enabled, timeout = %d min(s)", timeout);
+
+	return 0;
+}
+
+
+static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int new_timeout;
+	static struct watchdog_info ident = {
+		options:		WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+		firmware_version:	0,
+		identity:		"PC87307/PC97307"
+	};
+
+	switch (cmd) {
+		default:
+			return -ENOTTY;	/* Keep Pavel Machek amused ;) */
+
+		case WDIOC_GETSUPPORT:
+			if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident))
+				return -EFAULT;
+			return 0;
+
+		case WDIOC_GETSTATUS:
+			return put_user(sc1200wdt_status(), (int *)arg);
+
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0, (int *)arg);
+
+		case WDIOC_KEEPALIVE:
+			sc1200wdt_write_data(WDTO, timeout);
+			return 0;
+
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_timeout, (int *)arg))
+				return -EFAULT;
+
+			/* the API states this is given in secs */
+			new_timeout /= 60;
+			if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
+				return -EINVAL;
+
+			timeout = new_timeout;
+			sc1200wdt_write_data(WDTO, timeout);
+			/* fall through and return the new timeout */
+
+		case WDIOC_GETTIMEOUT:
+			return put_user(timeout * 60, (int *)arg);
+
+		case WDIOC_SETOPTIONS:
+		{
+			int options, retval = -EINVAL;
+
+			if (get_user(options, (int *)arg))
+				return -EFAULT;
+
+			if (options & WDIOS_DISABLECARD) {
+				sc1200wdt_stop();
+				retval = 0;
+			}
+
+			if (options & WDIOS_ENABLECARD) {
+				sc1200wdt_start();
+				retval = 0;
+			}
+
+			return retval;
+		}
+	}
+}
+
+
+static int sc1200wdt_release(struct inode *inode, struct file *file)
+{
+	if (expect_close == 42) {
+		sc1200wdt_stop();
+		printk(KERN_INFO PFX "Watchdog disabled\n");
+	} else {
+		sc1200wdt_write_data(WDTO, timeout);
+		printk(KERN_CRIT PFX "Unexpected close!, timeout = %d min(s)\n", timeout);
+	}
+	up(&open_sem);
+	expect_close = 0;
+
+	return 0;
+}
+
+
+static ssize_t sc1200wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	
+	if (len) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+		size_t i;
+
+		expect_close = 0;
+
+		for (i = 0; i != len; i++)
+		{
+			if (data[i] == 'V')
+				expect_close = 42;
+		}
+#endif
+		sc1200wdt_write_data(WDTO, timeout);
+		return len;
+	}
+
+	return 0;
+}
+
+
+static int sc1200wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		sc1200wdt_stop();
+
+	return NOTIFY_DONE;
+}
+
+
+static struct notifier_block sc1200wdt_notifier =
+{
+	notifier_call:	sc1200wdt_notify_sys
+};
+
+static struct file_operations sc1200wdt_fops =
+{
+	owner:		THIS_MODULE,
+	write:		sc1200wdt_write,
+	ioctl:		sc1200wdt_ioctl,
+	open:		sc1200wdt_open,
+	release:	sc1200wdt_release
+};
+
+static struct miscdevice sc1200wdt_miscdev =
+{
+	minor:		WATCHDOG_MINOR,
+	name:		"watchdog",
+	fops:		&sc1200wdt_fops,
+};
+
+
+static int __init sc1200wdt_probe(void)
+{
+	/* The probe works by reading the PMC3 register's default value of 0x0e
+	 * there is one caveat, if the device disables the parallel port or any
+	 * of the UARTs we won't be able to detect it.
+	 * Nb. This could be done with accuracy by reading the SID registers, but
+	 * we don't have access to those io regions.
+	 */
+	
+	unsigned char reg;
+
+	sc1200wdt_read_data(PMC3, &reg);
+	reg &= 0x0f;				/* we don't want the UART busy bits */
+	return (reg == 0x0e) ? 0 : -ENODEV;
+}
+
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+
+static int __init sc1200wdt_isapnp_probe(void)
+{
+	int ret;
+
+	/* The WDT is logical device 8 on the main device */
+	wdt_dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('N','S','C'), ISAPNP_FUNCTION(0x08), NULL);
+	if (!wdt_dev)
+		return -ENODEV;
+	
+	if (wdt_dev->prepare(wdt_dev) < 0) {
+		printk(KERN_ERR PFX "ISA PnP found device that could not be autoconfigured\n");
+		return -EAGAIN;
+	}
+
+	if (!(pci_resource_flags(wdt_dev, 0) & IORESOURCE_IO)) {
+		printk(KERN_ERR PFX "ISA PnP could not find io ports\n");
+		return -ENODEV;
+	}
+
+	ret = wdt_dev->activate(wdt_dev);
+	if (ret && (ret != -EBUSY))
+		return -ENOMEM;
+
+	/* io port resource overriding support? */
+	io = pci_resource_start(wdt_dev, 0);
+	io_len = pci_resource_len(wdt_dev, 0);
+
+	printk(KERN_DEBUG PFX "ISA PnP found device at io port %#x/%d\n", io, io_len);
+	return 0;
+}
+
+#endif /* CONFIG_ISAPNP */
+
+
+static int __init sc1200wdt_init(void)
+{
+	int ret;
+
+	printk(banner);
+
+	spin_lock_init(&sc1200wdt_lock);
+	sema_init(&open_sem, 1);
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+	if (isapnp) {
+		ret = sc1200wdt_isapnp_probe();
+		if (ret)
+			goto out_clean;
+	}
+#endif
+
+	if (io == -1) {
+		printk(KERN_ERR PFX "io parameter must be specified\n");
+		ret = -EINVAL;
+		goto out_clean;
+	}
+
+	if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
+		printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
+		ret = -EBUSY;
+		goto out_pnp;
+	}
+
+	ret = sc1200wdt_probe();
+	if (ret)
+		goto out_io;
+
+	ret = register_reboot_notifier(&sc1200wdt_notifier);
+	if (ret) {
+		printk(KERN_ERR PFX "Unable to register reboot notifier err = %d\n", ret);
+		goto out_io;
+	}
+
+	ret = misc_register(&sc1200wdt_miscdev);
+	if (ret) {
+		printk(KERN_ERR PFX "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR);
+		goto out_rbt;
+	}
+
+	/* ret = 0 */
+
+out_clean:
+	return ret;
+
+out_rbt:
+	unregister_reboot_notifier(&sc1200wdt_notifier);
+
+out_io:
+	release_region(io, io_len);
+
+out_pnp:
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+	if (isapnp && wdt_dev)
+		wdt_dev->deactivate(wdt_dev);
+#endif
+	goto out_clean;
+}	
+
+
+static void __exit sc1200wdt_exit(void)
+{
+	misc_deregister(&sc1200wdt_miscdev);
+	unregister_reboot_notifier(&sc1200wdt_notifier);
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+	if(isapnp && wdt_dev)
+		wdt_dev->deactivate(wdt_dev);
+#endif
+
+	release_region(io, io_len);
+}
+
+
+#ifndef MODULE
+static int __init sc1200wdt_setup(char *str)
+{
+	int ints[4];
+
+	str = get_options (str, ARRAY_SIZE(ints), ints);
+
+	if (ints[0] > 0) {
+		io = ints[1];
+		if (ints[0] > 1)
+			timeout = ints[2];
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+		if (ints[0] > 2)
+			isapnp = ints[3];
+#endif
+	}
+
+	return 1;
+}
+
+__setup("sc1200wdt=", sc1200wdt_setup);
+#endif /* MODULE */
+
+
+module_init(sc1200wdt_init);
+module_exit(sc1200wdt_exit);
+
+MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
+MODULE_DESCRIPTION("Driver for National Semiconductor PC87307/PC97307 watchdog component");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sc520_wdt.c linux/drivers/char/sc520_wdt.c
--- linux.orig/drivers/char/sc520_wdt.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/sc520_wdt.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,381 @@
+/*
+ *	AMD Elan SC520 processor Watchdog Timer driver for Linux 2.4.x
+ *
+ *      Based on acquirewdt.c by Alan Cox,
+ *           and sbc60xxwdt.c by Jakob Oestergaard <jakob@ostenfeld.dk>
+ *     
+ *	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.
+ *	
+ *	The authors do NOT admit liability nor provide warranty for 
+ *	any of this software. This material is provided "AS-IS" in 
+ *      the hope that it may be useful for others.
+ *
+ *	(c) Copyright 2001    Scott Jennings <linuxdrivers@oro.net>
+ *           9/27 - 2001      [Initial release]
+ *	
+ *	Additional fixes Alan Cox
+ *	-	Fixed formatting
+ *	-	Removed debug printks
+ *	-	Fixed SMP built kernel deadlock
+ *	-	Switched to private locks not lock_kernel
+ *	-	Used ioremap/writew/readw
+ *	-	Added NOWAYOUT support
+ *
+ *  Theory of operation:
+ *  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 WDT driver
+ *  via the /proc/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.
+ *
+ *  This WDT driver is different from most other Linux WDT
+ *  drivers in that the driver will ping the watchdog by itself,
+ *  because this particular WDT has a very short timeout (1.6
+ *  seconds) and it would be insane to count on any userspace
+ *  daemon always getting scheduled within that time frame.
+ *
+ *  This driver uses memory mapped IO, and spinlock.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/smp_lock.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+
+/*
+ * The SC520 can timeout anywhere from 492us to 32.21s.
+ * If we reset the watchdog every ~250ms we should be safe.
+ */
+
+#define WDT_INTERVAL (HZ/4+1)
+
+/*
+ * We must not require too good response from the userspace daemon.
+ * Here we require the userspace daemon to send us a heartbeat
+ * char to /dev/watchdog every 30 seconds.
+ */
+
+#define WDT_HEARTBEAT (HZ * 30)
+
+/*
+ * AMD Elan SC520 timeout value is 492us times a power of 2 (0-7)
+ *
+ *   0: 492us    2: 1.01s    4: 4.03s   6: 16.22s
+ *   1: 503ms    3: 2.01s    5: 8.05s   7: 32.21s
+ */
+
+#define TIMEOUT_EXPONENT ( 1 << 3 )  /* 0x08 = 2.01s */
+
+/* #define MMCR_BASE_DEFAULT 0xfffef000 */
+#define MMCR_BASE_DEFAULT ((__u16 *)0xffffe)
+#define OFFS_WDTMRCTL ((unsigned int)0xcb0)
+#define WDT_ENB 0x8000		/* [15] Watchdog Timer Enable */
+#define WDT_WRST_ENB 0x4000	/* [14] Watchdog Timer Reset Enable */
+
+#define OUR_NAME "sc520_wdt"
+
+#define WRT_DOG(data) *wdtmrctl=data
+
+static __u16 *wdtmrctl;
+
+static void wdt_timer_ping(unsigned long);
+static struct timer_list timer;
+static unsigned long next_heartbeat;
+static unsigned long wdt_is_open;
+static int wdt_expect_close;
+
+static spinlock_t wdt_spinlock;
+/*
+ *	Whack the dog
+ */
+
+static void wdt_timer_ping(unsigned long data)
+{
+	/* If we got a heartbeat pulse within the WDT_US_INTERVAL
+	 * we agree to ping the WDT 
+	 */
+	if(time_before(jiffies, next_heartbeat)) 
+	{
+		/* Ping the WDT */
+		spin_lock(&wdt_spinlock);
+		writew(0xAAAA, wdtmrctl);
+		writew(0x5555, wdtmrctl);
+		spin_unlock(&wdt_spinlock);
+
+		/* Re-set the timer interval */
+		timer.expires = jiffies + WDT_INTERVAL;
+		add_timer(&timer);
+	} else {
+		printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n");
+	}
+}
+
+/* 
+ * Utility routines
+ */
+
+static void wdt_config(int writeval)
+{
+	__u16 dummy;
+	unsigned long flags;
+
+	/* buy some time (ping) */
+	spin_lock_irqsave(&wdt_spinlock, flags);
+	dummy=readw(wdtmrctl);  /* ensure write synchronization */
+	writew(0xAAAA, wdtmrctl);
+	writew(0x5555, wdtmrctl);
+	/* make WDT configuration register writable one time */
+	writew(0x3333, wdtmrctl);
+	writew(0xCCCC, wdtmrctl);
+	/* write WDT configuration register */
+	writew(writeval, wdtmrctl);
+	spin_unlock_irqrestore(&wdt_spinlock, flags);
+}
+
+static void wdt_startup(void)
+{
+	next_heartbeat = jiffies + WDT_HEARTBEAT;
+
+	/* Start the timer */
+	timer.expires = jiffies + WDT_INTERVAL;	
+	add_timer(&timer);
+
+	wdt_config(WDT_ENB | WDT_WRST_ENB | TIMEOUT_EXPONENT);
+	printk(OUR_NAME ": Watchdog timer is now enabled.\n");  
+}
+
+static void wdt_turnoff(void)
+{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+	/* Stop the timer */
+	del_timer(&timer);
+	wdt_config(0);
+	printk(OUR_NAME ": Watchdog timer is now disabled...\n");
+#endif
+}
+
+
+/*
+ * /dev/watchdog handling
+ */
+
+static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+{
+	/* We can't seek */
+	if(ppos != &file->f_pos)
+		return -ESPIPE;
+
+	/* See if we got the magic character */
+	if(count) 
+	{
+		size_t ofs;
+
+		/* note: just in case someone wrote the magic character
+		 * five months ago... */
+		wdt_expect_close = 0;
+
+		/* now scan */
+		for(ofs = 0; ofs != count; ofs++) 
+			if(buf[ofs] == 'V')
+				wdt_expect_close = 1;
+
+		/* Well, anyhow someone wrote to us, we should return that favour */
+		next_heartbeat = jiffies + WDT_HEARTBEAT;
+		return 1;
+	}
+	return 0;
+}
+
+static int fop_open(struct inode * inode, struct file * file)
+{
+	switch(MINOR(inode->i_rdev)) 
+	{
+		case WATCHDOG_MINOR:
+			/* Just in case we're already talking to someone... */
+			if(test_and_set_bit(0, &wdt_is_open))
+				return -EBUSY;
+			/* Good, fire up the show */
+			wdt_startup();
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+			MOD_INC_USE_COUNT;
+#endif	
+			return 0;
+		default:
+			return -ENODEV;
+	}
+}
+
+static int fop_close(struct inode * inode, struct file * file)
+{
+	if(MINOR(inode->i_rdev) == WATCHDOG_MINOR) 
+	{
+		if(wdt_expect_close)
+			wdt_turnoff();
+		else {
+			del_timer(&timer);
+			printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
+		}
+	}
+	clear_bit(0, &wdt_is_open);
+	return 0;
+}
+
+static long long fop_llseek(struct file *file, long long offset, int origin)
+{
+	return -ESPIPE;
+}
+
+static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	static struct watchdog_info ident=
+	{
+		0,
+		1,
+		"SC520"
+	};
+	
+	switch(cmd)
+	{
+		default:
+			return -ENOIOCTLCMD;
+		case WDIOC_GETSUPPORT:
+			return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+		case WDIOC_KEEPALIVE:
+			next_heartbeat = jiffies + WDT_HEARTBEAT;
+			return 0;
+	}
+}
+
+static struct file_operations wdt_fops = {
+	owner:		THIS_MODULE,
+	llseek:		fop_llseek,
+	write:		fop_write,
+	open:		fop_open,
+	release:	fop_close,
+	ioctl:		fop_ioctl
+};
+
+static struct miscdevice wdt_miscdev = {
+	WATCHDOG_MINOR,
+	"watchdog",
+	&wdt_fops
+};
+
+/*
+ *	Notifier for system down
+ */
+
+static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if(code==SYS_DOWN || code==SYS_HALT) 
+		wdt_turnoff();
+	return NOTIFY_DONE;
+}
+ 
+/*
+ *	The WDT needs to learn about soft shutdowns in order to
+ *	turn the timebomb registers off. 
+ */
+ 
+static struct notifier_block wdt_notifier=
+{
+	wdt_notify_sys,
+	0,
+	0
+};
+
+static void __exit sc520_wdt_unload(void)
+{
+	wdt_turnoff();
+
+	/* Deregister */
+	misc_deregister(&wdt_miscdev);
+	iounmap(wdtmrctl);
+	unregister_reboot_notifier(&wdt_notifier);
+}
+
+static int __init sc520_wdt_init(void)
+{
+	int rc = -EBUSY;
+	unsigned long cbar;
+
+	spin_lock_init(&wdt_spinlock);
+
+	init_timer(&timer);
+	timer.function = wdt_timer_ping;
+	timer.data = 0;
+
+	rc = misc_register(&wdt_miscdev);
+	if (rc)
+		goto err_out_region2;
+
+	rc = register_reboot_notifier(&wdt_notifier);
+	if (rc)
+		goto err_out_miscdev;
+
+	/* get the Base Address Register */
+	cbar = inl_p(0xfffc);
+	printk(OUR_NAME ": CBAR: 0x%08lx\n", cbar);
+	/* check if MMCR aliasing bit is set */
+	if (cbar & 0x80000000) {
+		printk(OUR_NAME ": MMCR Aliasing enabled.\n");
+		wdtmrctl = (__u16 *)(cbar & 0x3fffffff);
+	} else {
+		printk(OUR_NAME "!!! WARNING !!!\n"
+		  "\t MMCR Aliasing found NOT enabled!\n"
+		  "\t Using default value of: %p\n"
+		  "\t This has not been tested!\n"
+		  "\t Please email Scott Jennings <smj@oro.net>\n"
+		  "\t  and Bill Jennings <bj@oro.net> if it works!\n"
+		  , MMCR_BASE_DEFAULT
+		  );
+	  wdtmrctl = MMCR_BASE_DEFAULT;
+	}
+
+	wdtmrctl = (__u16 *)((char *)wdtmrctl + OFFS_WDTMRCTL);
+	wdtmrctl = ioremap((unsigned long)wdtmrctl, 2);
+	printk(KERN_INFO OUR_NAME ": WDT driver for SC520 initialised.\n");
+
+	return 0;
+
+err_out_miscdev:
+	misc_deregister(&wdt_miscdev);
+err_out_region2:
+	return rc;
+}
+
+module_init(sc520_wdt_init);
+module_exit(sc520_wdt_unload);
+
+MODULE_AUTHOR("Scott and Bill Jennings");
+MODULE_DESCRIPTION("Driver for watchdog timer in AMD \"Elan\" SC520 uProcessor");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/serial.c linux/drivers/char/serial.c
--- linux.orig/drivers/char/serial.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/serial.c	2002-07-20 01:08:31.000000000 +0000
@@ -57,6 +57,11 @@
  * 10/00: add in optional software flow control for serial console.
  *	  Kanoj Sarcar <kanoj@sgi.com>  (Modified by Theodore Ts'o)
  *
+ * 02/02: Fix for AMD Elan bug in transmit irq routine, by
+ *        Christer Weinigel <wingel@hog.ctrl-c.liu.se>,
+ *        Robert Schwebel <robert@schwebel.de>,
+ *        Juergen Beisert <jbeisert@eurodsn.de>,
+ *        Theodore Ts'o <tytso@mit.edu>
  */
 
 static char *serial_version = "5.05c";
@@ -321,11 +326,12 @@
 MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA");
 #endif /* CONFIG_SERIAL_RSA  */
 
-static struct serial_state rs_table[RS_TABLE_SIZE] = {
+struct serial_state rs_table[RS_TABLE_SIZE] = {
 	SERIAL_PORT_DFNS	/* Defined in serial.h */
 };
 
 #define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
+int serial_nr_ports = NR_PORTS;
 
 #if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP))
 #define NR_PCI_BOARDS	8
@@ -418,10 +424,6 @@
 	case SERIAL_IO_MEM:
 		return readb((unsigned long) info->iomem_base +
 			     (offset<<info->iomem_reg_shift));
-#ifdef CONFIG_SERIAL_GSC
-	case SERIAL_IO_GSC:
-		return gsc_readb(info->iomem_base + offset);
-#endif
 	default:
 		return inb(info->port + offset);
 	}
@@ -441,11 +443,6 @@
 		writeb(value, (unsigned long) info->iomem_base +
 			      (offset<<info->iomem_reg_shift));
 		break;
-#ifdef CONFIG_SERIAL_GSC
-	case SERIAL_IO_GSC:
-		gsc_writeb(value, info->iomem_base + offset);
-		break;
-#endif
 	default:
 		outb(value, info->port+offset);
 	}
@@ -801,7 +798,7 @@
  */
 static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
-	int status;
+	int status, iir;
 	struct async_struct * info;
 	int pass_counter = 0;
 	struct async_struct *end_mark = 0;
@@ -826,7 +823,7 @@
 
 	do {
 		if (!info->tty ||
-		    (serial_in(info, UART_IIR) & UART_IIR_NO_INT)) {
+		    ((iir=serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) {
 			if (!end_mark)
 				end_mark = info;
 			goto next;
@@ -845,7 +842,9 @@
 		if (status & UART_LSR_DR)
 			receive_chars(info, &status, regs);
 		check_modem_status(info);
-		if (status & UART_LSR_THRE)
+		if ((status & UART_LSR_THRE) ||
+			/* for buggy ELAN processors */
+			((iir & UART_IIR_ID) == UART_IIR_THRI))
 			transmit_chars(info, 0);
 
 	next:
@@ -879,7 +878,7 @@
  */
 static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
 {
-	int status;
+	int status, iir;
 	int pass_counter = 0;
 	struct async_struct * info;
 #ifdef CONFIG_SERIAL_MULTIPORT	
@@ -901,6 +900,7 @@
 		first_multi = inb(multi->port_monitor);
 #endif
 
+	iir = serial_in(info, UART_IIR);
 	do {
 		status = serial_inp(info, UART_LSR);
 #ifdef SERIAL_DEBUG_INTR
@@ -909,18 +909,21 @@
 		if (status & UART_LSR_DR)
 			receive_chars(info, &status, regs);
 		check_modem_status(info);
-		if (status & UART_LSR_THRE)
+		if ((status & UART_LSR_THRE) ||
+		    /* For buggy ELAN processors */
+		    ((iir & UART_IIR_ID) == UART_IIR_THRI))
 			transmit_chars(info, 0);
 		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
-#if 0
+#if SERIAL_DEBUG_INTR
 			printk("rs_single loop break.\n");
 #endif
 			break;
 		}
+		iir = serial_in(info, UART_IIR);
 #ifdef SERIAL_DEBUG_INTR
-		printk("IIR = %x...", serial_in(info, UART_IIR));
+		printk("IIR = %x...", iir);
 #endif
-	} while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT));
+	} while ((iir & UART_IIR_NO_INT) == 0);
 	info->last_active = jiffies;
 #ifdef CONFIG_SERIAL_MULTIPORT	
 	if (multi->port_monitor)
@@ -2133,6 +2136,7 @@
 	if (new_serial.type) {
 		for (i = 0 ; i < NR_PORTS; i++)
 			if ((state != &rs_table[i]) &&
+			    (rs_table[i].io_type == SERIAL_IO_PORT) &&
 			    (rs_table[i].port == new_port) &&
 			    rs_table[i].type)
 				return -EADDRINUSE;
@@ -2195,7 +2199,7 @@
 
 	
 check_and_exit:
-	if (!state->port || !state->type)
+	if ((!state->port && !state->iomem_base) || !state->type)
 		return 0;
 	if (info->flags & ASYNC_INITIALIZED) {
 		if (((old_state.flags & ASYNC_SPD_MASK) !=
@@ -3247,14 +3251,17 @@
 	int	ret;
 	unsigned long flags;
 
+	/*
+	 * Return zero characters for ports not claimed by driver.
+	 */
+	if (state->type == PORT_UNKNOWN) {
+		return 0;	/* ignore unused ports */
+	}
+
 	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
 		      state->line, uart_config[state->type].name, 
-		      state->port, state->irq);
-
-	if (!state->port || (state->type == PORT_UNKNOWN)) {
-		ret += sprintf(buf+ret, "\n");
-		return ret;
-	}
+		      (state->port ? state->port : (long)state->iomem_base),
+		      state->irq);
 
 	/*
 	 * Figure out the current RS-232 lines
@@ -3912,6 +3919,25 @@
 		
 	}
   
+	/* HP's Diva chip puts the 4th/5th serial port further out, and
+	 * some serial ports are supposed to be hidden on certain models.
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_HP &&
+			dev->device == PCI_DEVICE_ID_HP_SAS) {
+		switch (dev->subsystem_device) {
+		case 0x104B: /* Maestro */
+			if (idx == 3) idx++;
+			break;
+		case 0x1282: /* Everest / Longs Peak */
+			if (idx > 0) idx++;
+			if (idx > 2) idx++;
+			break;
+		}
+		if (idx > 2) {
+			offset = 0x18;
+		}
+	}
+
 	port =  pci_resource_start(dev, base_idx) + offset;
 
 	if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
@@ -4081,12 +4107,14 @@
  * interface chip and different configuration methods:
  *     - 10x cards have control registers in IO and/or memory space;
  *     - 20x cards have control registers in standard PCI configuration space.
+ *
+ * SIIG initialization functions exported for use by parport_serial.c module.
  */
 
 #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
 #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
 
-static int __devinit
+int __devinit
 pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
 {
        u16 data, *p;
@@ -4111,11 +4139,12 @@
        iounmap(p);
        return 0;
 }
+EXPORT_SYMBOL(pci_siig10x_fn);
 
 #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
 #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
 
-static int __devinit
+int __devinit
 pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
 {
        u8 data;
@@ -4134,6 +4163,7 @@
        }
        return 0;
 }
+EXPORT_SYMBOL(pci_siig20x_fn);
 
 /* Added for EKF Intel i960 serial boards */
 static int __devinit
@@ -4215,6 +4245,40 @@
 	return 0;
 }
 
+/*
+ * HP's Remote Management Console.  The Diva chip came in several
+ * different versions.  N-class, L2000 and A500 have two Diva chips, each
+ * with 3 UARTs (the third UART on the second chip is unused).  Superdome
+ * and Keystone have one Diva chip with 3 UARTs.  Some later machines have
+ * one Diva chip, but it has been expanded to 5 UARTs.
+ */
+static int __devinit
+pci_hp_diva(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	if (!enable)
+		return 0;
+
+	switch (dev->subsystem_device) {
+	case 0x1049: /* Prelude Diva 1 */
+	case 0x1223: /* Superdome */
+	case 0x1226: /* Keystone */
+	case 0x1282: /* Everest / Longs Peak */
+		board->num_ports = 3;
+		break;
+	case 0x104A: /* Prelude Diva 2 */
+		board->num_ports = 2;
+		break;
+	case 0x104B: /* Maestro */
+		board->num_ports = 4;
+		break;
+	case 0x1227: /* Powerbar */
+		board->num_ports = 1;
+		break;
+	}
+
+	return 0;
+}
+
 static int __devinit
 pci_xircom_fn(struct pci_dev *dev, struct pci_board *board, int enable)
 {
@@ -4244,6 +4308,7 @@
 	pbn_b0_bt_2_115200,
 	pbn_b0_bt_1_460800,
 	pbn_b0_bt_2_460800,
+	pbn_b0_bt_2_921600,
 
 	pbn_b1_1_115200,
 	pbn_b1_2_115200,
@@ -4258,6 +4323,7 @@
 	pbn_b1_4_1382400,
 	pbn_b1_8_1382400,
 
+	pbn_b2_1_115200,
 	pbn_b2_8_115200,
 	pbn_b2_4_460800,
 	pbn_b2_8_460800,
@@ -4278,6 +4344,7 @@
 	pbn_timedia,
 	pbn_intel_i960,
 	pbn_sgi_ioc3,
+	pbn_hp_diva,
 #ifdef CONFIG_DDB5074
 	pbn_nec_nile4,
 #endif
@@ -4322,6 +4389,7 @@
 	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */
 	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */
 	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b0_bt_2_921600 */
 
 	{ SPCI_FL_BASE1, 1, 115200 },		/* pbn_b1_1_115200 */
 	{ SPCI_FL_BASE1, 2, 115200 },		/* pbn_b1_2_115200 */
@@ -4336,6 +4404,7 @@
 	{ SPCI_FL_BASE1, 4, 1382400 },		/* pbn_b1_4_1382400 */
 	{ SPCI_FL_BASE1, 8, 1382400 },		/* pbn_b1_8_1382400 */
 
+	{ SPCI_FL_BASE2, 1, 115200 },		/* pbn_b2_1_115200 */
 	{ SPCI_FL_BASE2, 8, 115200 },		/* pbn_b2_8_115200 */
 	{ SPCI_FL_BASE2, 4, 460800 },		/* pbn_b2_4_460800 */
 	{ SPCI_FL_BASE2, 8, 460800 },		/* pbn_b2_8_460800 */
@@ -4366,6 +4435,7 @@
 		8<<2, 2, pci_inteli960ni_fn, 0x10000},
 	{ SPCI_FL_BASE0 | SPCI_FL_IRQRESOURCE,		   /* pbn_sgi_ioc3 */
 		1, 458333, 0, 0, 0, 0x20178 },
+	{ SPCI_FL_BASE0, 5, 115200, 8, 0, pci_hp_diva, 0},   /* pbn_hp_diva */
 #ifdef CONFIG_DDB5074
 	/*
 	 * NEC Vrc-5074 (Nile 4) builtin UART.
@@ -4657,7 +4727,7 @@
 		pbn_b0_4_115200 },
 	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-		pbn_b0_2_115200 },
+		pbn_b0_bt_2_921600 },
 
 	/* Digitan DS560-558, from jimd@esoft.com */
 	{	PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
@@ -4704,15 +4774,6 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_2 },
@@ -4722,15 +4783,6 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_4 },
@@ -4749,24 +4801,6 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_2 },
@@ -4776,15 +4810,6 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_4 },
@@ -4864,6 +4889,14 @@
 		0xFF00, 0, 0, 0,
 		pbn_sgi_ioc3 },
 
+	/* HP Diva card */
+	{	PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_SAS,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_hp_diva },
+	{	PCI_VENDOR_ID_HP, 0x1290,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b2_1_115200 },
+
 #ifdef CONFIG_DDB5074
 	/*
 	 * NEC Vrc-5074 (Nile 4) builtin UART.
@@ -5486,7 +5519,7 @@
 		    && (state->port != 0 || state->iomem_base != 0))
 			state->irq = detect_uart_irq(state);
 		if (state->io_type == SERIAL_IO_MEM) {
-			printk(KERN_INFO"ttyS%02d%s at 0x%px (irq = %d) is a %s\n",
+			printk(KERN_INFO"ttyS%02d%s at 0x%p (irq = %d) is a %s\n",
 	 		       state->line + SERIAL_DEV_OFFSET,
 			       (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
 			       state->iomem_base, state->irq,
@@ -5661,7 +5694,7 @@
 	if (state->info && state->info->tty)
 		tty_hangup(state->info->tty);
 	state->type = PORT_UNKNOWN;
-	printk(KERN_INFO "tty%02d unloaded\n", state->line);
+	printk(KERN_INFO "ttyS%02d unloaded\n", state->line);
 	/* These will be hidden, because they are devices that will no longer
 	 * be available to the system. (ie, PCMCIA modems, once ejected)
 	 */
@@ -5822,35 +5855,6 @@
 	serial_out(info, UART_IER, ier);
 }
 
-/*
- *	Receive character from the serial port
- */
-static int serial_console_wait_key(struct console *co)
-{
-	static struct async_struct *info;
-	int ier, c;
-
-	info = &async_sercons;
-
-	/*
-	 *	First save the IER then disable the interrupts so
-	 *	that the real driver for the port does not get the
-	 *	character.
-	 */
-	ier = serial_in(info, UART_IER);
-	serial_out(info, UART_IER, 0x00);
- 
-	while ((serial_in(info, UART_LSR) & UART_LSR_DR) == 0);
-	c = serial_in(info, UART_RX);
-
-	/*
-	 *	Restore the interrupts
-	 */
-	serial_out(info, UART_IER, ier);
-
-	return c;
-}
-
 static kdev_t serial_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
@@ -5991,7 +5995,6 @@
 	name:		"ttyS",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/serial167.c linux/drivers/char/serial167.c
--- linux.orig/drivers/char/serial167.c	2001-09-17 04:23:07.000000000 +0000
+++ linux/drivers/char/serial167.c	2002-07-20 01:08:34.000000000 +0000
@@ -1262,7 +1262,7 @@
 			    break;
 		    }
 
-		    cli();
+		    save_flags(flags); cli();		
 		    c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				   SERIAL_XMIT_SIZE - info->xmit_head));
 		    memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
@@ -1277,7 +1277,7 @@
 	    up(&tmp_buf_sem);
     } else {
 	    while (1) {
-		    cli();
+		    save_flags(flags); cli();		
 		    c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				       SERIAL_XMIT_SIZE - info->xmit_head));
 		    if (c <= 0) {
@@ -1377,7 +1377,7 @@
 #ifdef SERIAL_DEBUG_THROTTLE
   char buf[64];
 	
-    printk("throttle %s: %d....\n", _tty_name(tty, buf),
+    printk("throttle %s: %d....\n", tty_name(tty, buf),
 	   tty->ldisc.chars_in_buffer(tty));
     printk("cy_throttle ttyS%d\n", info->line);
 #endif
@@ -1413,7 +1413,7 @@
 #ifdef SERIAL_DEBUG_THROTTLE
   char buf[64];
 	
-    printk("throttle %s: %d....\n", _tty_name(tty, buf),
+    printk("throttle %s: %d....\n", tty_name(tty, buf),
 	   tty->ldisc.chars_in_buffer(tty));
     printk("cy_unthrottle ttyS%d\n", info->line);
 #endif
@@ -2395,7 +2395,11 @@
     
     memset(&cy_serial_driver, 0, sizeof(struct tty_driver));
     cy_serial_driver.magic = TTY_DRIVER_MAGIC;
+#ifdef CONFIG_DEVFS_FS
+    cy_serial_driver.name = "tts/%d";
+#else
     cy_serial_driver.name = "ttyS";
+#endif
     cy_serial_driver.major = TTY_MAJOR;
     cy_serial_driver.minor_start = 64;
     cy_serial_driver.num = NR_PORTS;
@@ -2430,7 +2434,11 @@
      * major number and the subtype code.
      */
     cy_callout_driver = cy_serial_driver;
+#ifdef CONFIG_DEVFS_FS
+    cy_callout_driver.name = "cua/%d";
+#else
     cy_callout_driver.name = "cua";
+#endif
     cy_callout_driver.major = TTYAUX_MAJOR;
     cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
@@ -2806,58 +2814,6 @@
 	restore_flags(flags);
 }
 
-/* This is a hack; if there are multiple chars waiting in the chip we
- * discard all but the last one, and return that.  The cd2401 is not really
- * designed to be driven in polled mode.
- */
-
-int serial167_console_wait_key(struct console *co)
-{
-	volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
-	unsigned long flags;
-	volatile u_char sink;
-	u_char ier;
-	int port;
-	int keypress = 0;
-
-	save_flags(flags); cli();
-
-	/* Ensure receiver is enabled! */
-
-	port = 0;
-	base_addr[CyCAR] = (u_char)port;
-	while (base_addr[CyCCR])
-		;
-	base_addr[CyCCR] = CyENB_RCVR;
-	ier = base_addr[CyIER];
-	base_addr[CyIER] = CyRxData;
-
-	while (!keypress) {
-		if (pcc2chip[PccSCCRICR] & 0x20)
-		{
-			/* We have an Rx int. Acknowledge it */
-			sink = pcc2chip[PccRPIACKR];
-			if ((base_addr[CyLICR] >> 2) == port) {
-				int cnt = base_addr[CyRFOC];
-				while (cnt-- > 0)
-				{
-					keypress = base_addr[CyRDR];
-				}
-				base_addr[CyREOIR] = 0;
-			}
-			else
-				base_addr[CyREOIR] = CyNOTRANS;
-		}
-	}
-
-	base_addr[CyIER] = ier;
-
-	restore_flags(flags);
-
-	return keypress;
-}
-
-
 static kdev_t serial167_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
@@ -2874,7 +2830,6 @@
 	name:		"ttyS",
 	write:		serial167_console_write,
 	device:		serial167_console_device,
-	wait_key:	serial167_console_wait_key,
 	setup:		serial167_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/serial_21285.c linux/drivers/char/serial_21285.c
--- linux.orig/drivers/char/serial_21285.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/char/serial_21285.c	2002-07-20 01:08:29.000000000 +0000
@@ -389,17 +389,6 @@
 	enable_irq(IRQ_CONTX);
 }
 
-static int rs285_console_wait_key(struct console *co)
-{
-	int c;
-
-	disable_irq(IRQ_CONRX);
-	while (*CSR_UARTFLG & 0x10);
-	c = *CSR_UARTDR;
-	enable_irq(IRQ_CONRX);
-	return c;
-}
-
 static kdev_t rs285_console_device(struct console *c)
 {
 	return MKDEV(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
@@ -493,7 +482,6 @@
 	name:		SERIAL_21285_NAME,
 	write:		rs285_console_write,
 	device:		rs285_console_device,
-	wait_key:	rs285_console_wait_key,
 	setup:		rs285_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/serial_amba.c linux/drivers/char/serial_amba.c
--- linux.orig/drivers/char/serial_amba.c	2001-09-17 04:23:14.000000000 +0000
+++ linux/drivers/char/serial_amba.c	2002-07-20 01:08:25.000000000 +0000
@@ -1921,22 +1921,6 @@
 	UART_PUT_CR(port, old_cr);
 }
 
-/*
- *	Receive character from the serial port
- */
-static int ambauart_console_wait_key(struct console *co)
-{
-	struct amba_port *port = &amba_ports[co->index];
-	unsigned int status;
-	int c;
-
-	do {
-		status = UART_GET_FR(port);
-	} while (!UART_RX_DATA(status));
-	c = UART_GET_CHAR(port);
-	return c;
-}
-
 static kdev_t ambauart_console_device(struct console *c)
 {
 	return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + c->index);
@@ -2015,7 +1999,6 @@
 	read:		ambauart_console_read,
 #endif
 	device:		ambauart_console_device,
-	wait_key:	ambauart_console_wait_key,
 	setup:		ambauart_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/serial_tx3912.c linux/drivers/char/serial_tx3912.c
--- linux.orig/drivers/char/serial_tx3912.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/serial_tx3912.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,8 +1,6 @@
 /*
  *  drivers/char/serial_tx3912.c
  *
- *  Copyright (C) 1999 Harald Koerfgen
- *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -15,19 +13,13 @@
 #include <linux/config.h>
 #include <linux/tty.h>
 #include <linux/major.h>
-#include <linux/ptrace.h>
-#include <linux/init.h>
 #include <linux/console.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
+#include <linux/serial.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h>
-#include <asm/wbflush.h>
 #include <asm/tx3912.h>
 #include "serial_tx3912.h"
 
@@ -62,35 +54,19 @@
 }; 
 
 /*
- * Structures and such for TTY sessions and usage counts
+ * Structures and usage counts
  */
 static struct tty_driver rs_driver, rs_callout_driver;
-static struct tty_struct * rs_table[TX3912_UART_NPORTS] = { NULL, };
-static struct termios ** rs_termios;
-static struct termios ** rs_termios_locked;
-struct rs_port *rs_ports;
-int rs_refcount;
-int rs_initialized = 0;
+static struct tty_struct **rs_tty;
+static struct termios **rs_termios;
+static struct termios **rs_termios_locked;
+static struct rs_port *rs_port;
+static int rs_refcount;
+static int rs_initialized;
+
 
 /*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines.  All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt().  They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off.  People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible.  After you are done making modifications, it is not a bad
- * idea to do:
- * 
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
+ * Receive a character
  */
 static inline void receive_char_pio(struct rs_port *port)
 {
@@ -98,83 +74,34 @@
 	unsigned char ch;
 	int counter = 2048;
 
-	/* While there are characters, get them ... */
-	while (counter>0) {
-		if (!(inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL))
+	/* While there are characters */
+	while (counter > 0) {
+		if (!(inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_RXHOLDFULL))
 			break;
-		ch = inb(port->base + TX3912_UART_DATA);
+		ch = inb(TX3912_UARTA_DATA);
 		if (tty->flip.count < TTY_FLIPBUF_SIZE) {
 			*tty->flip.char_buf_ptr++ = ch;
 			*tty->flip.flag_buf_ptr++ = 0;
 			tty->flip.count++;
 		}
-		udelay(1); /* Allow things to happen - it take a while */
+		udelay(1);
 		counter--;
 	}
-	if (!counter)
-		printk( "Ugh, looped in receive_char_pio!\n" );
 
 	tty_flip_buffer_push(tty);
-
-#if 0
-	/* Now handle error conditions */
-	if (*status & (INTTYPE(UART_RXOVERRUN_INT) |
-			INTTYPE(UART_FRAMEERR_INT) |
-			INTTYPE(UART_PARITYERR_INT) |
-			INTTYPE(UART_BREAK_INT))) {
-
-		/*
-		 * Now check to see if character should be
-		 * ignored, and mask off conditions which
-		 * should be ignored.
-	       	 */
-		if (*status & port->ignore_status_mask) {
-			goto ignore_char;
-		}
-		*status &= port->read_status_mask;
-		
-		if (*status & INTTYPE(UART_BREAK_INT)) {
-			rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "handling break....");
-			*tty->flip.flag_buf_ptr = TTY_BREAK;
-		}
-		else if (*status & INTTYPE(UART_PARITYERR_INT)) {
-			*tty->flip.flag_buf_ptr = TTY_PARITY;
-		}
-		else if (*status & INTTYPE(UART_FRAMEERR_INT)) {
-			*tty->flip.flag_buf_ptr = TTY_FRAME;
-		}
-		if (*status & INTTYPE(UART_RXOVERRUN_INT)) {
-			/*
-			 * Overrun is special, since it's
-			 * reported immediately, and doesn't
-			 * affect the current character
-			 */
-			if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-				tty->flip.count++;
-				tty->flip.flag_buf_ptr++;
-				tty->flip.char_buf_ptr++;
-				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
-			}
-		}
-	}
-
-	tty->flip.flag_buf_ptr++;
-	tty->flip.char_buf_ptr++;
-	tty->flip.count++;
-
-ignore_char:
-	tty_flip_buffer_push(tty);
-#endif
 }
 
+/*
+ * Transmit a character
+ */
 static inline void transmit_char_pio(struct rs_port *port)
 {
-	/* While I'm able to transmit ... */
+	/* TX while bytes available */
 	for (;;) {
-		if (!(inl(port->base + TX3912_UART_CTRL1) & UART_TX_EMPTY))
+		if (!(inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_EMPTY))
 			break;
 		else if (port->x_char) {
-			outb(port->x_char, port->base + TX3912_UART_DATA);
+			outb(port->x_char, TX3912_UARTA_DATA);
 			port->icount.tx++;
 			port->x_char = 0;
 		}
@@ -184,14 +111,14 @@
 		}
 		else {
 			outb(port->gs.xmit_buf[port->gs.xmit_tail++],
-				port->base + TX3912_UART_DATA);
+				TX3912_UARTA_DATA);
 			port->icount.tx++;
 			port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
 			if (--port->gs.xmit_cnt <= 0) {
 				break;
 			}
 		}
-		udelay(10); /* Allow things to happen - it take a while */
+		udelay(10);
 	}
 
 	if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
@@ -203,519 +130,418 @@
                 if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
                     port->gs.tty->ldisc.write_wakeup)
                         (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
-                rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
+                rs_dprintk(TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
                             port->gs.wakeup_chars); 
                 wake_up_interruptible(&port->gs.tty->write_wait);
        	}	
 }
 
-
-
+/*
+ * We don't have MSR
+ */
 static inline void check_modem_status(struct rs_port *port)
 {
-        /* We don't have a carrier detect line - but just respond
-           like we had one anyways so that open() becomes unblocked */
 	wake_up_interruptible(&port->gs.open_wait);
 }
 
-int count = 0;
-
 /*
- * This is the serial driver's interrupt routine (inlined, because
- * there are two different versions of this, one for each serial port,
- * differing only by the bits used in interrupt status 2 register)
+ * RX interrupt handler
  */
-
-static inline void rs_rx_interrupt(int irq, void *dev_id,
-				  struct pt_regs * regs, int intshift)
+static inline void rs_rx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct rs_port * port;
-	unsigned long int2status;
-	unsigned long flags;
-	unsigned long ints;
+	unsigned long flags, status;
 
 	save_and_cli(flags);
 
-	port = (struct rs_port *)dev_id;
-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
-
-	/* Get the interrrupts we have enabled */
-	int2status = IntStatus2 & IntEnable2;
+	rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "rs_rx_interrupt...");
 
-	/* Get interrupts in easy to use form */
-	ints = int2status >> intshift;
+	/* Get the interrupts */
+	status = inl(TX3912_INT2_STATUS);
 
 	/* Clear any interrupts we might be about to handle */
-	IntClear2 = int2status & (
-		(INTTYPE(UART_RXOVERRUN_INT) |
-		 INTTYPE(UART_FRAMEERR_INT) |
-		 INTTYPE(UART_BREAK_INT) |
-		 INTTYPE(UART_PARITYERR_INT) |
-		 INTTYPE(UART_RX_INT)) << intshift);
+	outl(TX3912_INT2_UARTA_RX_BITS, TX3912_INT2_CLEAR);
 
-	if (!port || !port->gs.tty) {
+	if(!rs_port || !rs_port->gs.tty) {
 		restore_flags(flags);
 		return;
 	}
 
 	/* RX Receiver Holding Register Overrun */
-	if (ints & INTTYPE(UART_RXOVERRUN_INT)) {
-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "overrun");
-		port->icount.overrun++;
+	if(status & TX3912_INT2_UARTATXOVERRUNINT) {
+		rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "overrun");
+		rs_port->icount.overrun++;
 	}
 
 	/* RX Frame Error */
-	if (ints & INTTYPE(UART_FRAMEERR_INT)) {
-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "frame error");
-		port->icount.frame++;
+	if(status & TX3912_INT2_UARTAFRAMEERRINT) {
+		rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "frame error");
+		rs_port->icount.frame++;
 	}
 
 	/* Break signal received */
-	if (ints & INTTYPE(UART_BREAK_INT)) {
-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "break");
-		port->icount.brk++;
+	if(status & TX3912_INT2_UARTABREAKINT) {
+		rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "break");
+		rs_port->icount.brk++;
       	}
 
 	/* RX Parity Error */
-	if (ints & INTTYPE(UART_PARITYERR_INT)) {
-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "parity error");
-		port->icount.parity++;
+	if(status & TX3912_INT2_UARTAPARITYINT) {
+		rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "parity error");
+		rs_port->icount.parity++;
 	}
 
-	/* Receive byte (non-DMA) */
-	if (ints & INTTYPE(UART_RX_INT)) {
-		receive_char_pio(port);
+	/* Byte received */
+	if(status & TX3912_INT2_UARTARXINT) {
+		receive_char_pio(rs_port);
 	}
 
 	restore_flags(flags);
 
-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+	rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
 }
 
-static inline void rs_tx_interrupt(int irq, void *dev_id,
-				  struct pt_regs * regs, int intshift)
+/*
+ * TX interrupt handler
+ */
+static inline void rs_tx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct rs_port * port;
-	unsigned long int2status;
-	unsigned long flags;
-	unsigned long ints;
+	unsigned long flags, status;
 
 	save_and_cli(flags);
 
-	port = (struct rs_port *)dev_id;
-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
+	rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "rs_tx_interrupt...");
 
-	/* Get the interrrupts we have enabled */
-	int2status = IntStatus2 & IntEnable2;
+	/* Get the interrupts */
+	status = inl(TX3912_INT2_STATUS);
 
-	if (!port || !port->gs.tty) {
+	if(!rs_port || !rs_port->gs.tty) {
 		restore_flags(flags);
 		return;
 	}
 
-	/* Get interrupts in easy to use form */
-	ints = int2status >> intshift;
+	/* Clear interrupts */
+	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
 
-	/* Clear any interrupts we might be about to handle */
-	IntClear2 = int2status & (
-		(INTTYPE(UART_TX_INT) |
-		 INTTYPE(UART_EMPTY_INT) |
-		 INTTYPE(UART_TXOVERRUN_INT)) << intshift);
-
-	/* TX holding register empty, so transmit byte (non-DMA) */
-	if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) {
-		transmit_char_pio(port);
+	/* TX holding register empty - transmit a byte */
+	if(status & TX3912_INT2_UARTAEMPTYINT) {
+		transmit_char_pio(rs_port);
 	}
 
 	/* TX Transmit Holding Register Overrun (shouldn't happen) */
-	if (ints & INTTYPE(UART_TXOVERRUN_INT)) {
-		printk ( "rs: TX overrun\n");
+	if(status & TX3912_INT2_UARTATXOVERRUNINT) {
+		printk( "rs_tx_interrupt: TX overrun\n");
 	}
 
-	/*
-	check_modem_status();
-	*/
-
 	restore_flags(flags);
 
-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
-}
-
-static void rs_rx_interrupt_uarta(int irq, void *dev_id,
-					 struct pt_regs * regs)
-{
-	rs_rx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
-}
-
-static void rs_tx_interrupt_uarta(int irq, void *dev_id,
-					 struct pt_regs * regs)
-{
-	rs_tx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
+	rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
 }
 
 /*
- ***********************************************************************
- *                Here are the routines that actually                  *
- *              interface with the generic_serial driver               *
- ***********************************************************************
+ * Here are the routines that actually interface with the generic driver
  */
 static void rs_disable_tx_interrupts (void * ptr) 
 {
-	struct rs_port *port = ptr; 
 	unsigned long flags;
 
 	save_and_cli(flags);
-        port->gs.flags &= ~GS_TX_INTEN;
 
-	IntEnable2 &= ~((INTTYPE(UART_TX_INT) |
-			INTTYPE(UART_EMPTY_INT) |
-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift);
-
-	IntClear2 = (INTTYPE(UART_TX_INT) |
-			INTTYPE(UART_EMPTY_INT) |
-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+	outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_TX_BITS,
+		TX3912_INT2_ENABLE);
+	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
 
 	restore_flags(flags);
 }
 
 static void rs_enable_tx_interrupts (void * ptr) 
 {
-	struct rs_port *port = ptr; 
 	unsigned long flags;
 
 	save_and_cli(flags);
 
-	IntClear2 = (INTTYPE(UART_TX_INT) |
-			INTTYPE(UART_EMPTY_INT) |
-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
-
-	IntEnable2 |= (INTTYPE(UART_TX_INT) |
-			INTTYPE(UART_EMPTY_INT) |
-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
-
-	/* Send a char to start TX interrupts happening */
-	transmit_char_pio(port);
+	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
+	outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_TX_BITS,
+		TX3912_INT2_ENABLE);
+	transmit_char_pio(rs_port);
 
 	restore_flags(flags);
 }
 
 static void rs_disable_rx_interrupts (void * ptr) 
 {
-	struct rs_port *port = ptr;
 	unsigned long flags;
 
 	save_and_cli(flags);
 
-	IntEnable2 &= ~((INTTYPE(UART_RX_INT) |
-			 INTTYPE(UART_RXOVERRUN_INT) |
-			 INTTYPE(UART_FRAMEERR_INT) |
-			 INTTYPE(UART_BREAK_INT) |
-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift);
-
-	IntClear2 = (INTTYPE(UART_RX_INT) |
-			 INTTYPE(UART_RXOVERRUN_INT) |
-			 INTTYPE(UART_FRAMEERR_INT) |
-			 INTTYPE(UART_BREAK_INT) |
-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+	outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_RX_BITS,
+		TX3912_INT2_ENABLE);
+	outl(TX3912_INT2_UARTA_RX_BITS, TX3912_INT2_CLEAR);
 
 	restore_flags(flags);
 }
 
 static void rs_enable_rx_interrupts (void * ptr) 
 {
-	struct rs_port *port = ptr;
 	unsigned long flags;
 
 	save_and_cli(flags);
 
-	IntEnable2 |= (INTTYPE(UART_RX_INT) |
-			 INTTYPE(UART_RXOVERRUN_INT) |
-			 INTTYPE(UART_FRAMEERR_INT) |
-			 INTTYPE(UART_BREAK_INT) |
-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
-
-	/* Empty the input buffer - apparently this is *vital* */
-	while (inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL) { 
-		inb(port->base + TX3912_UART_DATA);
-	}
-
-	IntClear2 = (INTTYPE(UART_RX_INT) |
-			 INTTYPE(UART_RXOVERRUN_INT) |
-			 INTTYPE(UART_FRAMEERR_INT) |
-			 INTTYPE(UART_BREAK_INT) |
-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+	outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_RX_BITS,
+		TX3912_INT2_ENABLE);
+	while (inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_RXHOLDFULL)
+		inb(TX3912_UARTA_DATA);
+	outl(TX3912_INT2_UARTA_RX_BITS, TX3912_INT2_CLEAR);
 
 	restore_flags(flags);
 }
 
-
+/*
+ * We have no CD
+ */
 static int rs_get_CD (void * ptr) 
 {
-	/* No Carried Detect in Hardware - just return true */
-	func_exit();
-	return (1);
+	return 1;
 }
 
+/*
+ * Shut down the port
+ */
 static void rs_shutdown_port (void * ptr) 
 {
-	struct rs_port *port = ptr; 
-
 	func_enter();
-
-	port->gs.flags &= ~GS_ACTIVE;
-
+	rs_port->gs.flags &= ~GS_ACTIVE;
 	func_exit();
 }
 
 static int rs_set_real_termios (void *ptr)
 {
-	struct rs_port *port = ptr;
-	int t;
+	unsigned int ctrl1 = 0;
+	unsigned int ctrl2 = 0;
 
-	switch (port->gs.baud) {
-		/* Save some typing work... */
-#define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
-		e(300);e(600);e(1200);e(2400);e(4800);e(9600);
-		e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
-	case 0      :t = -1;
-		break;
-	default:
-		/* Can I return "invalid"? */
-		t = TX3912_UART_CTRL2_B9600;
-		printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
-		break;
-	}
-#undef e
-	if (t >= 0) {
-		/* Jim: Set Hardware Baud rate - there is some good
-		   code in drivers/char/serial.c */
-
-	  	/* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
-		UartA_Ctrl1 &= 0xf000000f;
-		UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);
-
-#define CFLAG port->gs.tty->termios->c_cflag
-		if (C_PARENB(port->gs.tty)) {
-			if (!C_PARODD(port->gs.tty))
-				UartA_Ctrl1 |= SER_EVEN_PARITY;
-			else
-				UartA_Ctrl1 |= SER_ODD_PARITY;
-		}
-		if ((CFLAG & CSIZE)==CS6)
-			printk(KERN_ERR "6 bits not supported\n");
-		if ((CFLAG & CSIZE)==CS5)
-			printk(KERN_ERR "5 bits not supported\n");
-		if ((CFLAG & CSIZE)==CS7)
-			UartA_Ctrl1 |= SER_SEVEN_BIT;
-		if (C_CSTOPB(port->gs.tty))
-			UartA_Ctrl1 |= SER_TWO_STOP;
-
-		outl(t, port->base + TX3912_UART_CTRL2);
-		outl(0, port->base + TX3912_UART_DMA_CTRL1);
-		outl(0, port->base + TX3912_UART_DMA_CTRL2);
-        	UartA_Ctrl1 |= TX3912_UART_CTRL1_UARTON;
+	/* Set baud rate */
+	switch (rs_port->gs.baud) {
+		case 0:
+			goto done;
+		case 1200:
+			ctrl2 = TX3912_UART_CTRL2_B1200;
+			break;
+		case 2400:
+			ctrl2 = TX3912_UART_CTRL2_B2400;
+			break;
+		case 4800:
+			ctrl2 = TX3912_UART_CTRL2_B4800;
+			break;
+		case 9600:
+			ctrl2 = TX3912_UART_CTRL2_B9600;
+			break;
+		case 19200:
+			ctrl2 = TX3912_UART_CTRL2_B19200;
+			break;
+		case 38400:
+			ctrl2 = TX3912_UART_CTRL2_B38400;
+			break;
+		case 57600:
+			ctrl2 = TX3912_UART_CTRL2_B57600;
+			break;
+		case 115200:
+		default:
+			ctrl2 = TX3912_UART_CTRL2_B115200;
+			break;
+	}
+
+  	/* Clear current UARTA settings */
+	ctrl1 = inl(TX3912_UARTA_CTRL1) & 0xf000000f;
 
-        /* wait until UARTA is stable */
-        while (~UartA_Ctrl1 & TX3912_UART_CTRL1_UARTON);
+	/* Set parity */
+	if(C_PARENB(rs_port->gs.tty)) {
+		if (!C_PARODD(rs_port->gs.tty))
+			ctrl1 |= (TX3912_UART_CTRL1_ENPARITY |
+				 TX3912_UART_CTRL1_EVENPARITY);
+		else
+			ctrl1 |= TX3912_UART_CTRL1_ENPARITY;
 	}
 
-	func_exit ();
-        return 0;
+	/* Set data size */
+	switch(rs_port->gs.tty->termios->c_cflag & CSIZE) {
+		case CS7:
+			ctrl1 |= TX3912_UART_CTRL1_BIT_7;
+			break;
+		case CS5:
+		case CS6:
+			printk(KERN_ERR "Data byte size unsupported. Defaulting to CS8\n");
+		case CS8:
+		default:
+			ctrl1 &= ~TX3912_UART_CTRL1_BIT_7;
+	}
+
+	/* Set stop bits */
+	if(C_CSTOPB(rs_port->gs.tty))
+		ctrl1 |= TX3912_UART_CTRL1_TWOSTOP;
+
+	/* Write the control registers */
+	outl(ctrl2, TX3912_UARTA_CTRL2);
+	outl(0, TX3912_UARTA_DMA_CTRL1);
+	outl(0, TX3912_UARTA_DMA_CTRL2);
+	outl(ctrl1, TX3912_UARTA_CTRL1);
+
+	/* Loop until the UART is on */
+	while(~inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_UARTON);
+
+done:
+	func_exit();
+	return 0;
 }
 
+/*
+ * Anyone in the buffer?
+ */
 static int rs_chars_in_buffer (void * ptr) 
 {
-	struct rs_port *port = ptr;
-	int scratch;
-
-	scratch = inl(port->base + TX3912_UART_CTRL1);
-
-	return ((scratch & UART_TX_EMPTY) ? 0 : 1);
+	return ((inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_EMPTY) ? 0 : 1);
 }
 
-/* ********************************************************************** *
- *                Here are the routines that actually                     *
- *               interface with the rest of the system                    *
- * ********************************************************************** */
-static int rs_open  (struct tty_struct * tty, struct file * filp)
+/*
+ * Open the serial port
+ */
+static int rs_open(struct tty_struct * tty, struct file * filp)
 {
-	struct rs_port *port;
-	int retval, line;
+	int retval;
 
 	func_enter();
 
-	if (!rs_initialized) {
+	if(!rs_initialized) {
 		return -EIO;
 	}
 
-	line = MINOR(tty->device) - tty->driver.minor_start;
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p)\n", 
-	            (int) current->pid, line, tty, current->tty);
-
-	if ((line < 0) || (line >= TX3912_UART_NPORTS))
+	if(MINOR(tty->device) - tty->driver.minor_start) {
 		return -ENODEV;
+	}
 
-	/* Pre-initialized already */
-	port = & rs_ports[line];
-
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "port = %p\n", port);
-
-	tty->driver_data = port;
-	port->gs.tty = tty;
-	port->gs.count++;
+	rs_dprintk(TX3912_UART_DEBUG_OPEN, "Serial opening...\n");
 
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "starting port\n");
+	tty->driver_data = rs_port;
+	rs_port->gs.tty = tty;
+	rs_port->gs.count++;
 
 	/*
 	 * Start up serial port
 	 */
-	retval = gs_init_port(&port->gs);
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "done gs_init\n");
-	if (retval) {
-		port->gs.count--;
+	retval = gs_init_port(&rs_port->gs);
+	rs_dprintk(TX3912_UART_DEBUG_OPEN, "Finished gs_init...\n");
+	if(retval) {
+		rs_port->gs.count--;
 		return retval;
 	}
 
-	port->gs.flags |= GS_ACTIVE;
-
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
-	            port->gs.count);
-	if (port->gs.count == 1) {
+	rs_port->gs.flags |= GS_ACTIVE;
+	if(rs_port->gs.count == 1) {
 		MOD_INC_USE_COUNT;
 	}
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "after inc_use_count\n");
 
-	/* Jim: Initialize port hardware here */
+	rs_enable_rx_interrupts(rs_port);
+	rs_enable_tx_interrupts(rs_port);
 
-	/* Enable high-priority interrupts for UARTA */
-	IntEnable6 |= INT6_UARTARXINT; 
-	rs_enable_rx_interrupts(&rs_ports[0]); 
-
-	retval = gs_block_til_ready(&port->gs, filp);
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 
-	            retval, port->gs.count);
-
-	if (retval) {
+	retval = gs_block_til_ready(&rs_port->gs, filp);
+	if(retval) {
 		MOD_DEC_USE_COUNT;
-		port->gs.count--;
+		rs_port->gs.count--;
 		return retval;
 	}
-	/* tty->low_latency = 1; */
 
-	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
+	if((rs_port->gs.count == 1) &&
+		(rs_port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = port->gs.normal_termios;
+			*tty->termios = rs_port->gs.normal_termios;
 		else 
-			*tty->termios = port->gs.callout_termios;
-		rs_set_real_termios (port);
+			*tty->termios = rs_port->gs.callout_termios;
+		rs_set_real_termios(rs_port);
 	}
 
-	port->gs.session = current->session;
-	port->gs.pgrp = current->pgrp;
+	rs_port->gs.session = current->session;
+	rs_port->gs.pgrp = current->pgrp;
 	func_exit();
 
-	/* Jim */
-/*	cli(); */
-
 	return 0;
-
 }
 
-
-
-static void rs_close (void *ptr)
+/*
+ * Close the serial port
+ */
+static void rs_close(void *ptr)
 {
-	func_enter ();
-
-	/* Anything to do here? */
-
+	func_enter();
 	MOD_DEC_USE_COUNT;
-	func_exit ();
+	func_exit();
 }
 
-
-/* I haven't the foggiest why the decrement use count has to happen
-   here. The whole linux serial drivers stuff needs to be redesigned.
-   My guess is that this is a hack to minimize the impact of a bug
-   elsewhere. Thinking about it some more. (try it sometime) Try
-   running minicom on a serial port that is driven by a modularized
-   driver. Have the modem hangup. Then remove the driver module. Then
-   exit minicom.  I expect an "oops".  -- REW */
-static void rs_hungup (void *ptr)
+/*
+ * Hang up the serial port
+ */
+static void rs_hungup(void *ptr)
 {
-	func_enter ();
+	func_enter();
 	MOD_DEC_USE_COUNT;
-	func_exit ();
+	func_exit();
 }
 
-static int rs_ioctl (struct tty_struct * tty, struct file * filp, 
+/*
+ * Serial ioctl call
+ */
+static int rs_ioctl(struct tty_struct * tty, struct file * filp, 
                      unsigned int cmd, unsigned long arg)
 {
-	int rc;
-	struct rs_port *port = tty->driver_data;
-	int ival;
+	int ival, rc;
 
 	rc = 0;
 	switch (cmd) {
-	case TIOCGSOFTCAR:
-		rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
+		case TIOCGSOFTCAR:
+			rc = put_user((tty->termios->c_cflag & CLOCAL) ? 1 : 0,
 		              (unsigned int *) arg);
-		break;
-	case TIOCSSOFTCAR:
-		if ((rc = verify_area(VERIFY_READ, (void *) arg,
-		                      sizeof(int))) == 0) {
-			get_user(ival, (unsigned int *) arg);
-			tty->termios->c_cflag =
-				(tty->termios->c_cflag & ~CLOCAL) |
-				(ival ? CLOCAL : 0);
-		}
-		break;
-	case TIOCGSERIAL:
-		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
-		                      sizeof(struct serial_struct))) == 0)
-			rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
-		break;
-	case TIOCSSERIAL:
-		if ((rc = verify_area(VERIFY_READ, (void *) arg,
-		                      sizeof(struct serial_struct))) == 0)
-			rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
-		break;
-	default:
-		rc = -ENOIOCTLCMD;
-		break;
+			break;
+		case TIOCSSOFTCAR:
+			if ((rc = verify_area(VERIFY_READ, (void *) arg,
+				sizeof(int))) == 0) {
+				get_user(ival, (unsigned int *) arg);
+				tty->termios->c_cflag =
+					(tty->termios->c_cflag & ~CLOCAL) |
+					(ival ? CLOCAL : 0);
+			}
+			break;
+		case TIOCGSERIAL:
+			if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+				sizeof(struct serial_struct))) == 0)
+				rc = gs_getserial(&rs_port->gs, (struct serial_struct *) arg);
+			break;
+		case TIOCSSERIAL:
+			if ((rc = verify_area(VERIFY_READ, (void *) arg,
+				sizeof(struct serial_struct))) == 0)
+				rc = gs_setserial(&rs_port->gs, (struct serial_struct *) arg);
+			break;
+		default:
+			rc = -ENOIOCTLCMD;
+			break;
 	}
 
-	/* func_exit(); */
 	return rc;
 }
 
-
 /*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
+ * Send xchar
  */
 static void rs_send_xchar(struct tty_struct * tty, char ch)
 {
-	struct rs_port *port = (struct rs_port *)tty->driver_data;
-	func_enter ();
+	func_enter();
 	
-	port->x_char = ch;
+	rs_port->x_char = ch;
 	if (ch) {
-		/* Make sure transmit interrupts are on */
 		rs_enable_tx_interrupts(tty);
 	}
 
 	func_exit();
 }
 
-
 /*
- * ------------------------------------------------------------
- * rs_throttle()
- * 
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
+ * Throttle characters as directed by upper tty layer
  */
 static void rs_throttle(struct tty_struct * tty)
 {
@@ -726,17 +552,19 @@
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
-	func_enter ();
+	func_enter();
 	
 	if (I_IXOFF(tty))
 		rs_send_xchar(tty, STOP_CHAR(tty));
 
-	func_exit ();
+	func_exit();
 }
 
+/*
+ * Un-throttle characters as directed by upper tty layer
+ */
 static void rs_unthrottle(struct tty_struct * tty)
 {
-	struct rs_port *port = (struct rs_port *)tty->driver_data;
 #ifdef TX3912_UART_DEBUG_THROTTLE
 	char	buf[64];
 	
@@ -747,8 +575,8 @@
 	func_enter();
 	
 	if (I_IXOFF(tty)) {
-		if (port->x_char)
-			port->x_char = 0;
+		if (rs_port->x_char)
+			rs_port->x_char = 0;
 		else
 			rs_send_xchar(tty, START_CHAR(tty));
 	}
@@ -756,105 +584,72 @@
 	func_exit();
 }
 
-
-
-
-
-/* ********************************************************************** *
- *                    Here are the initialization routines.               *
- * ********************************************************************** */
-
-void * ckmalloc (int size)
-{
-        void *p;
-
-        p = kmalloc(size, GFP_KERNEL);
-        if (p) 
-                memset(p, 0, size);
-        return p;
-}
-
-
-
-static int rs_init_portstructs(void)
+/*
+ * Initialize the serial port
+ */
+void __init tx3912_rs_init(void)
 {
-	struct rs_port *port;
-	int i;
-
-	/* Debugging */
 	func_enter();
+	rs_dprintk(TX3912_UART_DEBUG_INIT, "Initializing serial...\n");
 
-	rs_ports          = ckmalloc(TX3912_UART_NPORTS * sizeof (struct rs_port));
-	if (!rs_ports)
-		return -ENOMEM;
-
-	rs_termios        = ckmalloc(TX3912_UART_NPORTS * sizeof (struct termios *));
-	if (!rs_termios) {
-		kfree (rs_ports);
-		return -ENOMEM;
+	/* Allocate critical structures */
+	if(!(rs_tty = kmalloc(sizeof(struct tty_struct), GFP_KERNEL))) {
+		return;
 	}
-
-	rs_termios_locked = ckmalloc(TX3912_UART_NPORTS * sizeof (struct termios *));
-	if (!rs_termios_locked) {
-		kfree (rs_ports);
-		kfree (rs_termios);
-		return -ENOMEM;
+	if(!(rs_port = kmalloc(sizeof(struct rs_port), GFP_KERNEL))) {
+		kfree(rs_tty);
+		return;
+	}
+	if(!(rs_termios = kmalloc(sizeof(struct termios), GFP_KERNEL))) {
+		kfree(rs_port);
+		kfree(rs_tty);
+		return;
+	}
+	if(!(rs_termios_locked = kmalloc(sizeof(struct termios), GFP_KERNEL))) {
+		kfree(rs_termios);
+		kfree(rs_port);
+		kfree(rs_tty);
+		return;
 	}
 
-	/* Adjust the values in the "driver" */
-	rs_driver.termios = rs_termios;
-	rs_driver.termios_locked = rs_termios_locked;
+	/* Zero out the structures */
+	memset(rs_tty, 0, sizeof(struct tty_struct));
+	memset(rs_port, 0, sizeof(struct rs_port));
+	memset(rs_termios, 0, sizeof(struct termios));
+	memset(rs_termios_locked, 0, sizeof(struct termios));
+	memset(&rs_driver, 0, sizeof(rs_driver));
+	memset(&rs_callout_driver, 0, sizeof(rs_callout_driver));
 
-	port = rs_ports;
-	for (i=0; i < TX3912_UART_NPORTS;i++) {
-		rs_dprintk (TX3912_UART_DEBUG_INIT, "initing port %d\n", i);
-		port->gs.callout_termios = tty_std_termios;
-		port->gs.normal_termios	= tty_std_termios;
-		port->gs.magic = SERIAL_MAGIC;
-		port->gs.close_delay = HZ/2;
-		port->gs.closing_wait = 30 * HZ;
-		port->gs.rd = &rs_real_driver;
+	/* Fill in hardware specific port structure */
+	rs_port->gs.callout_termios = tty_std_termios;
+	rs_port->gs.normal_termios	= tty_std_termios;
+	rs_port->gs.magic = SERIAL_MAGIC;
+	rs_port->gs.close_delay = HZ/2;
+	rs_port->gs.closing_wait = 30 * HZ;
+	rs_port->gs.rd = &rs_real_driver;
 #ifdef NEW_WRITE_LOCKING
-		port->gs.port_write_sem = MUTEX;
+	rs_port->gs.port_write_sem = MUTEX;
 #endif
 #ifdef DECLARE_WAITQUEUE
-		init_waitqueue_head(&port->gs.open_wait);
-		init_waitqueue_head(&port->gs.close_wait);
+	init_waitqueue_head(&rs_port->gs.open_wait);
+	init_waitqueue_head(&rs_port->gs.close_wait);
 #endif
-		port->base = (i == 0) ? TX3912_UARTA_BASE : TX3912_UARTB_BASE;
-		port->intshift = (i == 0) ? UARTA_SHIFT : UARTB_SHIFT;
-		rs_dprintk (TX3912_UART_DEBUG_INIT, "base 0x%08lx intshift %d\n",
-			    port->base, port->intshift);
-		port++;
-	}
-
-	func_exit();
-	return 0;
-}
-
-static int rs_init_drivers(void)
-{
-	int error;
-
-	func_enter();
 
-	memset(&rs_driver, 0, sizeof(rs_driver));
+	/* Fill in generic serial driver structures */
 	rs_driver.magic = TTY_DRIVER_MAGIC;
 	rs_driver.driver_name = "serial";
 	rs_driver.name = "ttyS";
 	rs_driver.major = TTY_MAJOR;
 	rs_driver.minor_start = 64;
-	rs_driver.num = TX3912_UART_NPORTS;
+	rs_driver.num = 1;
 	rs_driver.type = TTY_DRIVER_TYPE_SERIAL;
 	rs_driver.subtype = SERIAL_TYPE_NORMAL;
 	rs_driver.init_termios = tty_std_termios;
-	rs_driver.init_termios.c_cflag =
-		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+	rs_driver.init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
 	rs_driver.refcount = &rs_refcount;
-	rs_driver.table = rs_table;
+	rs_driver.table = rs_tty;
 	rs_driver.termios = rs_termios;
 	rs_driver.termios_locked = rs_termios_locked;
-
 	rs_driver.open	= rs_open;
 	rs_driver.close = gs_close;
 	rs_driver.write = gs_write;
@@ -870,92 +665,59 @@
 	rs_driver.stop = gs_stop;
 	rs_driver.start = gs_start;
 	rs_driver.hangup = gs_hangup;
-
 	rs_callout_driver = rs_driver;
 	rs_callout_driver.name = "cua";
 	rs_callout_driver.major = TTYAUX_MAJOR;
 	rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
-	if ((error = tty_register_driver(&rs_driver))) {
-		printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
-		       error);
-		return 1;
+	/* Register serial and callout drivers */
+	if(tty_register_driver(&rs_driver)) {
+		printk(KERN_ERR "Unable to register serial driver\n");
+		goto error;
 	}
-	if ((error = tty_register_driver(&rs_callout_driver))) {
+	if(tty_register_driver(&rs_callout_driver)) {
 		tty_unregister_driver(&rs_driver);
-		printk(KERN_ERR "Couldn't register callout driver, error = %d\n",
-		       error);
-		return 1;
+		printk(KERN_ERR "Unable to register callout driver\n");
+		goto error;
 	}
 
-	func_exit();
-	return 0;
-}
-
-
-void __init tx3912_rs_init(void)
-{
-	int rc;
-
-
-	func_enter();
-	rs_dprintk (TX3912_UART_DEBUG_INIT, "Initing serial module... (rs_debug=%d)\n", rs_debug);
+	/* Assign IRQs */
+	if(request_irq(2, rs_tx_interrupt, SA_SHIRQ,
+		"uarta_tx", rs_port)) {
+		printk(KERN_ERR "Cannot allocate IRQ for UARTA_TX.\n");
+		goto error;
+	}
 
-	rc = rs_init_portstructs ();
-	rs_init_drivers ();
-	if (request_irq(2, rs_tx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
-			"serial", &rs_ports[0])) {
-		printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
-		rc = 0;
-	}
-	if (request_irq(3, rs_rx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
-			"serial", &rs_ports[0])) {
-		printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
-		rc = 0;
+	if(request_irq(3, rs_rx_interrupt, SA_SHIRQ,
+		"uarta_rx", rs_port)) {
+		printk(KERN_ERR "Cannot allocate IRQ for UARTA_RX.\n");
+		goto error;
 	}
 
-	IntEnable6 |= INT6_UARTARXINT; 
-	rs_enable_rx_interrupts(&rs_ports[0]); 
+	/* Enable the serial receive interrupt */
+	rs_enable_rx_interrupts(rs_port); 
 
 #ifndef CONFIG_SERIAL_TX3912_CONSOLE
-{
-	unsigned int scratch = 0;
+	/* Write the control registers */
+	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_CTRL2);
+	outl(0x00000000, TX3912_UARTA_DMA_CTRL1);
+	outl(0x00000000, TX3912_UARTA_DMA_CTRL2);
+	outl(inl(TX3912_UARTA_CTRL1) | TX3912_UART_CTRL1_ENUART,
+		TX3912_UARTA_CTRL1);
 
-	/* Setup master clock for UART */
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
-	scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
-				TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
-			| TX3912_CLK_CTRL_SIBMCLKDIR
-			| TX3912_CLK_CTRL_ENSIBMCLK
-			| TX3912_CLK_CTRL_CSERSEL;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
-
-	/* Configure UARTA clock */
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
-				TX3912_CLK_CTRL_CSERDIV_MASK)
-			| TX3912_CLK_CTRL_ENCSERCLK
-			| TX3912_CLK_CTRL_ENUARTACLK;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
-		
-	/* Setup UARTA for 115200,8N1 */
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
-	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
-
-	/* Enable UARTA */
-	outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
-	while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
-		TX3912_UART_CTRL1_UARTON);
-}
+	/* Loop until the UART is on */
+	while(~inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_UARTON);
 #endif
 
-	/* Note: I didn't do anything to enable the second UART */
-	if (rc >= 0) 
-		rs_initialized++;
+	rs_initialized = 1;
+	func_exit();
+	return;
 
+error:
+	kfree(rs_termios_locked);
+	kfree(rs_termios);
+	kfree(rs_port);
+	kfree(rs_tty);
 	func_exit();
 }
 
@@ -963,55 +725,37 @@
  * Begin serial console routines
  */
 #ifdef CONFIG_SERIAL_TX3912_CONSOLE
-
 void serial_outc(unsigned char c)
 {
 	int i;
 	unsigned long int2;
-	#define BUSY_WAIT 10000
-
-	/*
-	 * Turn UARTA interrupts off
-	 */
-	int2 = IntEnable2;
-	IntEnable2 &=
-		~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
-
-	/*
-	 * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
-	 * not to be very reliable :-(
-	 *
-	 * Wait for the Tx register to become empty
-	 */
-	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
-
-	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
-	UartA_Data = c;
-	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
-	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
 
-	IntEnable2 = int2;
-}
-
-static int serial_console_wait_key(struct console *co)
-{
-	unsigned int int2, res;
-
-	int2 = IntEnable2;
-	IntEnable2 = 0;
+	/* Disable UARTA_TX interrupts */
+	int2 = inl(TX3912_INT2_ENABLE);
+	outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_TX_BITS,
+		 TX3912_INT2_ENABLE);
+
+	/* Wait for UARTA_TX register to empty */
+	i = 10000;
+	while(!(inl(TX3912_INT2_STATUS) & TX3912_INT2_UARTATXINT) && i--);
+	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
+
+	/* Send the character */
+	outl(c, TX3912_UARTA_DATA);
+
+	/* Wait for UARTA_TX register to empty */
+	i = 10000;
+	while(!(inl(TX3912_INT2_STATUS) & TX3912_INT2_UARTATXINT) && i--);
+	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
 
-	while (!(UartA_Ctrl1 & UART_RX_HOLD_FULL));
-	res = UartA_Data;
-	udelay(10);
-	
-	IntEnable2 = int2;
-	return res;
+	/* Enable UARTA_TX interrupts */
+	outl(int2, TX3912_INT2_ENABLE);
 }
 
 static void serial_console_write(struct console *co, const char *s,
-		unsigned count)
+	unsigned count)
 {
-    	unsigned int i;
+	unsigned int i;
 
 	for (i = 0; i < count; i++) {
 		if (*s == '\n')
@@ -1027,36 +771,78 @@
 
 static __init int serial_console_setup(struct console *co, char *options)
 {
-	unsigned int scratch = 0;
+	int baud = 115200;
+	int bits = 8;
+	int parity = 'n';
+	char *s;
+	unsigned int ctrl1 = 0;
+	unsigned int ctrl2 = 0;
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s++ - '0';
+	}
+
+	switch(baud) {
+		case 1200:
+			ctrl2 = TX3912_UART_CTRL2_B1200;
+			break;
+		case 2400:
+			ctrl2 = TX3912_UART_CTRL2_B2400;
+			break;
+		case 4800:
+			ctrl2 = TX3912_UART_CTRL2_B4800;
+			break;
+		case 9600:
+			ctrl2 = TX3912_UART_CTRL2_B9600;
+			break;
+		case 19200:
+			ctrl2 = TX3912_UART_CTRL2_B19200;
+			break;
+		case 38400:
+			ctrl2 = TX3912_UART_CTRL2_B38400;
+			break;
+		case 57600:
+			ctrl2 = TX3912_UART_CTRL2_B57600;
+			break;
+		case 115200:
+		default:
+			ctrl2 = TX3912_UART_CTRL2_B115200;
+			break;
+	}
+
+	switch(bits) {
+		case 7:
+			ctrl1 = TX3912_UART_CTRL1_BIT_7;
+			break;
+		default:
+			break;
+	}
+
+	switch(parity) {
+		case 'o': case 'O':
+			ctrl1 |= TX3912_UART_CTRL1_ENPARITY;
+			break;
+		case 'e': case 'E':
+			ctrl1 |= (TX3912_UART_CTRL1_ENPARITY |
+				 TX3912_UART_CTRL1_EVENPARITY);
+			break;
+		default:
+			break;
+	}
+
+	/* Write the control registers */
+	outl(ctrl2, TX3912_UARTA_CTRL2);
+	outl(0x00000000, TX3912_UARTA_DMA_CTRL1);
+	outl(0x00000000, TX3912_UARTA_DMA_CTRL2);
+	outl((ctrl1 | TX3912_UART_CTRL1_ENUART), TX3912_UARTA_CTRL1);
 
-	/* Setup master clock for UART */
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
-	scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
-				TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
-			| TX3912_CLK_CTRL_SIBMCLKDIR
-			| TX3912_CLK_CTRL_ENSIBMCLK
-			| TX3912_CLK_CTRL_CSERSEL;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
-
-	/* Configure UARTA clock */
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
-				TX3912_CLK_CTRL_CSERDIV_MASK)
-			| TX3912_CLK_CTRL_ENCSERCLK
-			| TX3912_CLK_CTRL_ENUARTACLK;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
-		
-	/* Setup UARTA for 115200,8N1 */
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
-	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
-
-	/* Enable UARTA */
-	outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
-	while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
-		TX3912_UART_CTRL1_UARTON);
+	/* Loop until the UART is on */
+	while(~inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_UARTON);
 
 	return 0;
 }
@@ -1065,7 +851,6 @@
 	name:     "ttyS",
 	write:    serial_console_write,
 	device:   serial_console_device,
-	wait_key: serial_console_wait_key,
 	setup:    serial_console_setup,
 	flags:    CON_PRINTBUFFER,
 	index:    -1
@@ -1075,5 +860,4 @@
 {
 	register_console(&sercons);
 }
-
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/serial_tx3912.h linux/drivers/char/serial_tx3912.h
--- linux.orig/drivers/char/serial_tx3912.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/char/serial_tx3912.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,8 +1,6 @@
 /*
  *  drivers/char/serial_tx3912.h
  *
- *  Copyright (C) 1999 Harald Koerfgen
- *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
  *
  * This program is free software; you can redistribute it and/or modify
@@ -14,27 +12,6 @@
 #include <linux/serialP.h>
 #include <linux/generic_serial.h>
 
-/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */
-#define UART_RX_INT         9  /* receiver holding register full  (31, 21) */
-#define UART_RXOVERRUN_INT  8  /* receiver overrun error          (30, 20) */
-#define UART_FRAMEERR_INT   7  /* receiver frame error            (29, 19) */
-#define UART_BREAK_INT      6  /* received break signal           (28, 18) */
-#define UART_PARITYERR_INT  5  /* receiver parity error           (27, 17) */
-#define UART_TX_INT         4  /* transmit holding register empty (26, 16) */
-#define UART_TXOVERRUN_INT  3  /* transmit overrun error          (25, 15) */
-#define UART_EMPTY_INT      2  /* both trans/recv regs empty      (24, 14) */
-#define UART_DMAFULL_INT    1  /* DMA at end of buffer            (23, 13) */
-#define UART_DMAHALF_INT    0  /* DMA halfway through buffer */   (22, 12) */
-
-#define UARTA_SHIFT        22
-#define UARTB_SHIFT        12
-
-#define INTTYPE(interrupttype)            (1 << interrupttype)
-
-/* 
- * This driver can spew a whole lot of debugging output at you. If you
- * need maximum performance, you should disable the DEBUG define.
- */
 #undef TX3912_UART_DEBUG
 
 #ifdef TX3912_UART_DEBUG
@@ -53,39 +30,28 @@
 #define TX3912_UART_DEBUG_FIRMWARE	0x00001000
 #define TX3912_UART_DEBUG_MEMTEST	0x00002000
 #define TX3912_UART_DEBUG_THROTTLE	0x00004000
+#define TX3912_UART_DEBUG_NO_TX		0xffffffdf
 #define TX3912_UART_DEBUG_ALL		0xffffffff
 
-int rs_debug = TX3912_UART_DEBUG_ALL & ~TX3912_UART_DEBUG_TRANSMIT;
-
-#define rs_dprintk(f, str...) if (rs_debug & f) printk (str)
-#define func_enter() rs_dprintk (TX3912_UART_DEBUG_FLOW,	\
+#define rs_dprintk(f, str...) if(TX3912_UART_DEBUG_NO_TX & f) printk(str)
+#define func_enter() rs_dprintk(TX3912_UART_DEBUG_FLOW,		\
 				"rs: enter " __FUNCTION__ "\n")
-#define func_exit() rs_dprintk (TX3912_UART_DEBUG_FLOW,	\
+#define func_exit() rs_dprintk(TX3912_UART_DEBUG_FLOW,		\
 				"rs: exit " __FUNCTION__ "\n")
-
 #else
 #define rs_dprintk(f, str...)
 #define func_enter()
 #define func_exit()
-
-#endif	/* TX3912_UART_DEBUG */
-
-/*
- * Number of serial ports
- */
-#define TX3912_UART_NPORTS  2
+#endif
 
 /*
  * Hardware specific serial port structure
  */
 struct rs_port { 	
 	struct gs_port		gs;		/* Must be first field! */
-
-	unsigned long		base;
-	int			intshift;	/* Register shift */
 	struct wait_queue	*shutdown_wait; 
 	int			stat_flags;
-        struct async_icount	icount;		/* Counters for 4 input IRQs */
+	struct async_icount	icount;		/* Counters for 4 input IRQs */
 	int			read_status_mask;
 	int			ignore_status_mask;
 	int			x_char;		/* XON/XOFF character */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/serial_txx927.c linux/drivers/char/serial_txx927.c
--- linux.orig/drivers/char/serial_txx927.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/serial_txx927.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,2329 @@
+/*
+ *  drivers/char/serial_txx927.c
+ *  driver for TX[34]927 SIO
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. 
+ *                ahennessy@mvista.com
+ *
+ * Based on drivers/char/serial.c
+ *
+ * Copyright (C) 2000-2001 Toshiba 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define SERIAL_DO_RESTART
+
+/* Set of debugging defines */
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+#undef SERIAL_DEBUG_PCI
+#undef SERIAL_DEBUG_AUTOCONF   
+
+#ifdef MODULE
+#undef CONFIG_TXX927_SERIAL_CONSOLE
+#endif                               
+
+#define CONFIG_SERIAL_RSA
+
+#define RS_STROBE_TIME (10*HZ)
+#define RS_ISR_PASS_LIMIT 256     
+
+/*
+ * End of serial driver configuration section.
+ */
+
+#include <linux/module.h>    
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/circ_buf.h>
+#include <linux/serial_reg.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/serialP.h>
+#include <linux/delay.h>
+#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+#include <linux/console.h>
+#endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif            
+
+#include <asm/system.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/jmr3927/txx927.h>
+#include <asm/bootinfo.h>
+#ifdef CONFIG_TOSHIBA_JMR3927
+#include <asm/jmr3927/jmr3927.h>
+#endif
+
+#define _INLINE_ inline
+
+#ifdef CONFIG_MAC_SERIAL
+#define SERIAL_DEV_OFFSET	2
+#else
+#define SERIAL_DEV_OFFSET	0
+#endif
+	
+static char *serial_name = "TXx927 Serial driver";
+static char *serial_version = "0.02";
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct timer_list serial_timer;
+
+extern unsigned long get_txx927_uart_baud(void);
+
+/* serial subtype definitions */
+#ifndef SERIAL_TYPE_NORMAL
+#define SERIAL_TYPE_NORMAL      1
+#define SERIAL_TYPE_CALLOUT     2
+#endif                          
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/*
+ * IRQ_timeout		- How long the timeout should be for each IRQ
+ * 				should be after the IRQ has been active.
+ */
+
+static struct async_struct *IRQ_ports[NR_IRQS];
+static int IRQ_timeout[NR_IRQS];
+#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+static struct console sercons;
+#endif
+#if defined(CONFIG_TXX927_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+static unsigned long break_pressed; /* break, really ... */
+#endif                                                        
+
+static void change_speed(struct async_struct *info, struct termios *old);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+#ifndef PREPARE_FUNC
+#define PREPARE_FUNC(dev)  (dev->prepare)
+#define ACTIVATE_FUNC(dev)  (dev->activate)
+#define DEACTIVATE_FUNC(dev)  (dev->deactivate)
+#endif
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+
+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
+#else
+#define DBG_CNT(s)
+#endif                                     
+	
+#define SERIAL_DRIVER_NAME "TXx927SIO"
+
+#ifdef CONFIG_SERIAL
+/* "ttyS","cua" is used for standard serial driver */
+#define TXX927_TTY_NAME "ttySC"
+#define TXX927_TTY_MINOR_START	(64 + 16)	/* ttySC0(80), ttySC1(81) */
+#define TXX927_CU_NAME "cuac"
+#define TXX927_SERIAL_BH	TXX927SERIAL_BH
+#else
+/* acts like standard serial driver */
+#define TXX927_TTY_NAME "ttyS"
+#define TXX927_TTY_MINOR_START	64
+#define TXX927_CU_NAME "cua"
+#define TXX927_SERIAL_BH	SERIAL_BH
+#endif
+#define TXX927_TTY_MAJOR	TTY_MAJOR
+#define TXX927_TTYAUX_MAJOR	TTYAUX_MAJOR
+
+#define ASYNC_HAVE_CTS_LINE		ASYNC_BOOT_AUTOCONF	/* reuse */
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif                                 
+
+static inline int serial_paranoia_check(struct async_struct *info,
+					kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null async_struct for (%s) in %s\n";
+
+	if (!info) {
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+static inline struct txx927_sio_reg *sio_reg(struct async_struct *info)
+{
+	return (struct txx927_sio_reg *)info->port;
+}
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct async_struct *info)
+{
+	unsigned int tmout = 1000000;
+
+	do {
+		if (--tmout == 0) break;
+	} while (!(sio_reg(info)->cisr & TXx927_SICISR_TXALS));
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	if (info->IER & UART_IER_THRI) {
+		info->IER &= ~UART_IER_THRI;
+	        sio_reg(info)->dicr &= ~TXx927_SIDICR_TIE;
+	}
+	restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags); cli();
+	if (info->xmit.head != info->xmit.tail
+	    && info->xmit.buf
+	    && !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+	        sio_reg(info)->dicr |= TXx927_SIDICR_TIE;
+	}
+	restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct async_struct *info,
+				  int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(TXX927_SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(struct async_struct *info,
+				 int *status)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	int ignored = 0;
+	struct	async_icount *icount;
+
+	icount = &info->state->icount;
+	do {
+		ch = sio_reg(info)->rfifo;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			break;
+		*tty->flip.char_buf_ptr = ch;
+		icount->rx++;
+		
+#ifdef SERIAL_DEBUG_INTR
+		printk("DR%02x:%02x...", ch, *status);
+#endif
+		*tty->flip.flag_buf_ptr = 0;
+		if (*status & (TXx927_SIDISR_UBRK | TXx927_SIDISR_UPER |
+			       TXx927_SIDISR_UFER | TXx927_SIDISR_UOER)) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & TXx927_SIDISR_UBRK) {
+				*status &= ~(TXx927_SIDISR_UFER | TXx927_SIDISR_UPER);
+				icount->brk++;
+			} else if (*status & TXx927_SIDISR_UPER)
+				icount->parity++;
+			else if (*status & TXx927_SIDISR_UFER)
+				icount->frame++;
+			if (*status & TXx927_SIDISR_UOER)
+				icount->overrun++;
+
+			/*
+			 * Now check to see if character should be
+			 * ignored, and mask off conditions which
+			 * should be ignored.
+			 */
+			if (*status & info->ignore_status_mask) {
+				if (++ignored > 100)
+					break;
+				goto ignore_char;
+			}
+			*status &= info->read_status_mask;
+		
+			if (*status & (TXx927_SIDISR_UBRK)) {
+#ifdef SERIAL_DEBUG_INTR
+				printk("handling break....");
+#endif
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+				if (info->flags & ASYNC_SAK)
+					do_SAK(tty);
+			} else if (*status & TXx927_SIDISR_UPER)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & TXx927_SIDISR_UFER)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+			if (*status & TXx927_SIDISR_UOER) {
+				/*
+				 * Overrun is special, since it's
+				 * reported immediately, and doesn't
+				 * affect the current character
+				 */
+				if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+					tty->flip.count++;
+					tty->flip.flag_buf_ptr++;
+					tty->flip.char_buf_ptr++;
+					*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				}
+			}
+		}
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		tty->flip.count++;
+	ignore_char:
+		*status = sio_reg(info)->disr;
+	} while (!(*status & TXx927_SIDISR_UVALID));
+
+	tty_flip_buffer_push(tty);
+}
+
+static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	int count;
+	
+	wait_for_xmitr(info);
+
+	if (info->x_char) {
+		sio_reg(info)->tfifo = info->x_char;
+		info->state->icount.tx++;
+		info->x_char = 0;
+		if (intr_done)
+			*intr_done = 0;
+		return;
+	}
+	 
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		sio_reg(info)->dicr &= ~TXx927_SIDICR_TIE;
+		return;
+	}
+	
+	count = info->xmit_fifo_size;
+	do {
+		sio_reg(info)->tfifo = info->xmit.buf[info->xmit.tail++];
+		info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+		if (info->xmit.head == info->xmit.tail)
+			break;
+	} while (--count > 0);
+	
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("THRE...");
+#endif
+	if (intr_done)
+		*intr_done = 0;
+
+	if (info->xmit.head == info->xmit.tail) {
+		sio_reg(info)->dicr &= ~TXx927_SIDICR_TIE;
+	}
+}
+
+static _INLINE_ void check_modem_status(struct async_struct *info)
+{
+	/* RTS/CTS are controled by HW. (if possible) */
+}
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status;
+	int pass_counter = 0;
+	struct async_struct * info;
+	
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt_single(%d)...", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info || !info->tty)
+		return;
+
+	do {
+		status = sio_reg(info)->disr;
+#ifdef SERIAL_DEBUG_INTR
+		printk("status = %x...", status);
+#endif
+		if (!(sio_reg(info)->dicr & TXx927_SIDICR_TIE))
+			status &= ~TXx927_SIDISR_TDIS;
+		if (!(status & (TXx927_SIDISR_TDIS | TXx927_SIDISR_RDIS | TXx927_SIDISR_TOUT)))
+			break;
+
+		if (status & TXx927_SIDISR_RDIS)
+			receive_chars(info, &status);
+		check_modem_status(info);
+		if (status & TXx927_SIDISR_TDIS)
+			transmit_chars(info, 0);
+		/* Clear TX/RX Int. Status */
+		sio_reg(info)->disr &= ~(TXx927_SIDISR_TDIS | TXx927_SIDISR_RDIS | TXx927_SIDISR_TOUT);
+
+		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
+#ifdef SERIAL_DEBUG_INTR
+			printk("rs_single loop break.\n");
+#endif
+			break;
+		}
+	} while (1);
+	info->last_active = jiffies;
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct async_struct	*info = (struct async_struct *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif                                                    
+	}
+}
+
+/*
+ * This subroutine is called when the RS_TIMER goes off.  It is used
+ * by the serial driver to handle ports that do not have an interrupt
+ * (irq=0).  This doesn't work very well for 16450's, but gives barely
+ * passable results for a 16550A.  (Although at the expense of much
+ * CPU overhead).
+ */
+static void rs_timer(unsigned long dummy)
+{
+	static unsigned long last_strobe;
+	struct async_struct *info;
+	unsigned int	i;
+	unsigned long flags;
+
+	if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
+		for (i=0; i < NR_IRQS; i++) {
+			info = IRQ_ports[i];
+			if (!info)
+				continue;
+			save_flags(flags); cli();
+				rs_interrupt_single(i, NULL, NULL);
+			restore_flags(flags);
+		}
+	}
+	last_strobe = jiffies;
+	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+
+#if 0
+	if (IRQ_ports[0]) {
+		save_flags(flags); cli();
+		rs_interrupt_single(0, NULL, NULL);
+		restore_flags(flags);
+
+		mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
+	}
+#endif
+}
+
+/*
+ * ---------------------------------------------------------------
+ * Low level utility subroutines for the serial driver:  routines to
+ * figure out the appropriate timeout for an interrupt chain, routines
+ * to initialize and startup a serial port, and routines to shutdown a
+ * serial port.  Useful stuff like that.
+ * ---------------------------------------------------------------
+ */
+
+/*
+ * This routine figures out the correct timeout for a particular IRQ.
+ * It uses the smallest timeout of all of the serial ports in a
+ * particular interrupt chain.  Now only used for IRQ 0....
+ */
+static void figure_IRQ_timeout(int irq)
+{
+	struct	async_struct	*info;
+	int	timeout = 60*HZ;	/* 60 seconds === a long time :-) */
+
+	info = IRQ_ports[irq];
+	if (!info) {
+		IRQ_timeout[irq] = 60*HZ;
+		return;
+	}
+	while (info) {
+		if (info->timeout < timeout)
+			timeout = info->timeout;
+		info = info->next_port;
+	}
+	if (!irq)
+		timeout = timeout / 2;
+	IRQ_timeout[irq] = timeout ? timeout : 1;
+}
+
+static int startup(struct async_struct * info)
+{
+	unsigned long flags;
+	int	retval=0;
+	struct serial_state *state= info->state;
+	unsigned long page;
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!state->port) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+	sio_reg(info)->fcr |= TXx927_SIFCR_TFRST | TXx927_SIFCR_RFRST |
+		TXx927_SIFCR_FRSTE;
+	/* clear reset */
+	sio_reg(info)->fcr &= ~(TXx927_SIFCR_TFRST | TXx927_SIFCR_RFRST |
+				TXx927_SIFCR_FRSTE);
+
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			retval = -EBUSY;
+			goto errout;
+		}
+
+		retval = request_irq(state->irq, rs_interrupt_single,
+				     SA_INTERRUPT,
+				     "txx927serial", NULL);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+	figure_IRQ_timeout(state->irq);
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	sio_reg(info)->disr = 0;
+
+	/*
+	 * Now, initialize the UART 
+	 */
+	/* HW RTS/CTS control */
+	if (state->flags & ASYNC_HAVE_CTS_LINE)
+		sio_reg(info)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES |
+			TXx927_SIFLCR_RTSTL_MAX /* 15 */;
+	/* Enable RX/TX */
+	sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE);
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	sio_reg(info)->dicr = TXx927_SIDICR_RIE;
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit.head = info->xmit.tail = 0;
+
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info, 0);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+	
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct async_struct * info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		retval;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+	figure_IRQ_timeout(state->irq);
+	
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, NULL);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     SA_INTERRUPT, "txx927serial", NULL);
+			
+			if (retval)
+				printk(KERN_WARNING "txx927serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, NULL);
+	}
+
+	if (info->xmit.buf) {
+		free_page((unsigned long) info->xmit.buf);
+		info->xmit.buf = 0;
+	}
+
+	sio_reg(info)->dicr = 0;	/* disable all intrs */
+	
+	/* disable break condition */
+	sio_reg(info)->flcr &= ~TXx927_SIFLCR_TBRK;
+
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+		/* drop RTS */
+		sio_reg(info)->flcr |= TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE;
+		/* TXx927-SIO can not control DTR... */
+	}
+
+	/* reset FIFO's */	
+	sio_reg(info)->fcr |= TXx927_SIFCR_TFRST | TXx927_SIFCR_RFRST |
+		TXx927_SIFCR_FRSTE;
+	/* clear reset */
+	sio_reg(info)->fcr &= ~(TXx927_SIFCR_TFRST | TXx927_SIFCR_RFRST |
+				TXx927_SIFCR_FRSTE);
+
+	/* DON'T disable Rx/Tx here, ie. DON'T set either
+	 * TXx927_SIFLCR_RSDE or TXx927_SIFLCR_TSDE in flcr
+	 */
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct async_struct *info,
+			 struct termios *old_termios)
+{
+	int	quot = 0, baud_base, baud;
+	unsigned cflag, cval;
+	int	bits;
+	unsigned long	flags;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (!info->port)
+		return;
+
+	cval = sio_reg(info)->lcr;
+	/* byte size and parity */
+	cval &= ~TXx927_SILCR_UMODE_MASK;
+	switch (cflag & CSIZE) {
+	case CS7:
+		cval |= TXx927_SILCR_UMODE_7BIT;
+		bits = 9;
+		break;
+	case CS5:	/* not supported */
+	case CS6:	/* not supported */
+	case CS8:
+	default:
+		cval |= TXx927_SILCR_UMODE_8BIT;
+		bits = 10;
+		break;
+	}
+	cval &= ~TXx927_SILCR_USBL_MASK;
+	if (cflag & CSTOPB) {
+		cval |= TXx927_SILCR_USBL_2BIT;
+		bits++;
+	} else {
+		cval |= TXx927_SILCR_USBL_1BIT;
+	}
+
+	cval &= ~(TXx927_SILCR_UPEN|TXx927_SILCR_UEPS);
+	if (cflag & PARENB) {
+		cval |= TXx927_SILCR_UPEN;
+		bits++;
+	}
+	if (!(cflag & PARODD))
+		cval |= TXx927_SILCR_UEPS;
+
+	/* Determine divisor based on baud rate */
+	baud = tty_get_baud_rate(info->tty);
+	if (!baud)
+		baud = 9600;	/* B0 transition handled in rs_set_termios */
+	baud_base = info->state->baud_base;
+	quot = (baud_base + baud / 2) / baud;
+	/* If the quotient is zero refuse the change */
+	if (!quot && old_termios) {
+		info->tty->termios->c_cflag &= ~CBAUD;
+		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+		baud = tty_get_baud_rate(info->tty);
+		if (!baud)
+			baud = 9600;
+		quot = (baud_base + baud / 2) / baud;
+	}
+	/* As a last resort, if the quotient is zero, default to 9600 bps */
+	if (!quot)
+		quot = (baud_base + 9600 / 2) / 9600;
+	info->quot = quot;
+	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
+	info->timeout += HZ/50;		/* Add .02 seconds of slop */
+
+	/* CTS flow control flag */
+	if (cflag & CRTSCTS) {
+		info->flags |= ASYNC_CTS_FLOW;
+		if (info->state->flags & ASYNC_HAVE_CTS_LINE)
+			sio_reg(info)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES |
+				TXx927_SIFLCR_RTSTL_MAX /* 15 */;
+	} else {
+		info->flags &= ~ASYNC_CTS_FLOW;
+		sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES | TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE);
+	}
+
+	/*
+	 * Set up parity check flag
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	info->read_status_mask = TXx927_SIDISR_UOER |
+		TXx927_SIDISR_TDIS | TXx927_SIDISR_RDIS;
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= TXx927_SIDISR_UFER | TXx927_SIDISR_UPER;
+	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+		info->read_status_mask |= TXx927_SIDISR_UBRK;
+	
+	/*
+	 * Characters to ignore
+	 */
+	info->ignore_status_mask = 0;
+	if (I_IGNPAR(info->tty))
+		info->ignore_status_mask |= TXx927_SIDISR_UPER | TXx927_SIDISR_UFER;
+	if (I_IGNBRK(info->tty)) {
+		info->ignore_status_mask |= TXx927_SIDISR_UBRK;
+		/*
+		 * If we're ignore parity and break indicators, ignore 
+		 * overruns too.  (For real raw support).
+		 */
+		if (I_IGNPAR(info->tty))
+			info->ignore_status_mask |= TXx927_SIDISR_UOER;
+	}
+	/*
+	 * !!! ignore all characters if CREAD is not set
+	 */
+	if ((cflag & CREAD) == 0)
+		info->ignore_status_mask |= TXx927_SIDISR_RDIS;
+	save_flags(flags); cli();
+	sio_reg(info)->lcr = cval | TXx927_SILCR_SCS_IMCLK_BG;
+	sio_reg(info)->bgr = quot | TXx927_SIBGR_BCLK_T0;
+	restore_flags(flags);
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+		return;                                          
+
+	if (!tty || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head,
+		       info->xmit.tail,
+		       SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+
+	info->xmit.buf[info->xmit.head++] = ch;
+	info->xmit.head &= SERIAL_XMIT_SIZE-1;
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;                                                  
+	
+	if (info->xmit.head == info->xmit.tail
+	    || tty->stopped
+	    || tty->hw_stopped
+	    || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	sio_reg(info)->dicr |= TXx927_SIDICR_TIE;
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					       info->xmit.tail,
+					       SERIAL_XMIT_SIZE);
+
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	if (info->xmit.head != info->xmit.tail
+	    && !tty->stopped
+	    && !tty->hw_stopped
+	    && !(info->IER & UART_IER_THRI)) 
+		sio_reg(info)->dicr |= TXx927_SIDICR_TIE;
+
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+	        return 0;                                           
+
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;                                                     
+
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+
+	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
+		return;                                        
+
+	info->x_char = ch;
+	if (ch) {
+		/* Make sure transmit interrupts are on */
+		sio_reg(info)->dicr |= TXx927_SIDICR_TIE;
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;                                              
+
+	if (I_IXOFF(tty))
+		rs_send_xchar(tty, STOP_CHAR(tty));
+
+	if (tty->termios->c_cflag & CRTSCTS) {
+		save_flags(flags); cli();
+		/* drop RTS */
+		sio_reg(info)->flcr |= TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE;
+		restore_flags(flags);
+	}
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;                                              
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+	if (tty->termios->c_cflag & CRTSCTS) {
+		save_flags(flags); cli();
+		sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
+		restore_flags(flags);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_modem_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	result =  ((sio_reg(info)->flcr & TXx927_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
+		| ((sio_reg(info)->cisr & TXx927_SICISR_CTSS) ? 0 : TIOCM_CTS);
+	restore_flags(flags);
+	return put_user(result,value);
+}
+
+static int set_modem_info(struct async_struct * info, unsigned int cmd,
+			  unsigned int *value)
+{
+	int error;
+	unsigned int arg;
+	unsigned long flags;
+
+	error = get_user(arg, value);
+	if (error)
+		return error;
+	save_flags(flags); cli();
+	switch (cmd) {
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS)
+			sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS)
+			sio_reg(info)->flcr |= TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE;
+		break;
+	case TIOCMSET:
+		sio_reg(info)->flcr =
+			(sio_reg(info)->flcr & ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE)) |
+			((arg & TIOCM_RTS) ? 0 : TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
+		break;
+	default:
+		error = -EINVAL;
+	}
+	restore_flags(flags);
+	return error;
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_break"))
+		return;                                             
+	
+	if (!info->port)
+		return;
+	save_flags(flags); cli();
+	if (break_state == -1)
+		sio_reg(info)->flcr |= TXx927_SIFLCR_TBRK;
+	else
+		sio_reg(info)->flcr &= ~TXx927_SIFLCR_TBRK;
+	restore_flags(flags);
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;                                
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
+			return 0;
+		case TIOCGSERIAL:
+			printk("TIOCGSERIAL\n");
+			return 0;
+		case TIOCSSERIAL:
+			printk("TIOCSSERIAL\n");
+			return 0;
+		case TIOCSERCONFIG:
+			printk("TIOCSERCONFIG\n");
+			return 0;
+
+		case TIOCSERGETLSR: /* Get line status register */
+			printk("TIOCSERGETLSR\n");
+			return 0;
+
+		case TIOCSERGSTRUCT:
+			printk("TIOCSERGSTRUCT\n");
+			return 0;
+
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+ 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		case TIOCMIWAIT:
+			printk("TIOCMIWAIT\n");
+			return 0;
+
+		/* 
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			printk("TIOCGICOUNT\n");
+			return 0;
+
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	unsigned int cflag = tty->termios->c_cflag;
+	
+	if (   (cflag == old_termios->c_cflag)
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+	change_speed(info, old_termios);
+
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(cflag & CBAUD)) {
+		save_flags(flags); cli();
+		sio_reg(info)->flcr |= TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE;
+		restore_flags(flags);
+	}
+	
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (cflag & CBAUD)) {
+		if (!(tty->termios->c_cflag & CRTSCTS) || 
+		    !test_bit(TTY_THROTTLED, &tty->flags)) {
+			save_flags(flags); cli();
+			sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
+			restore_flags(flags);
+		}
+	}
+	
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	state = info->state;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk(KERN_WARNING "rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk(KERN_WARNING "rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	info->read_status_mask &= ~TXx927_SIDISR_RDIS;
+	if (info->flags & ASYNC_INITIALIZED) {
+#if 0
+		sio_reg(info)->dicr &= ~TXx927_SIDICR_RIE;
+#endif
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		rs_wait_until_sent(tty, info->timeout);
+	}
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	int cisr;
+
+	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+		return;                                            
+
+	if (info->xmit_fifo_size == 0)
+		return; /* Just in case.... */
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 * 
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout)
+	  char_time = MIN(char_time, timeout);
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+	if (!timeout || timeout > 2*info->timeout)
+		timeout = 2*info->timeout;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+	while (!((cisr = sio_reg(info)->cisr) & TXx927_SICISR_TXALS)) {
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+		printk("cisr = %d (jiff=%lu)...", cisr, jiffies);
+#endif
+		current->state = TASK_INTERRUPTIBLE;
+		current->counter = 0;	/* make us low-priority */
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+	current->state = TASK_RUNNING;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("cisr = %d (jiff=%lu)...done\n", cisr, jiffies);
+#endif
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;                                           
+
+	state = info->state;
+	
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct async_struct *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct serial_state *state = info->state;
+	int		retval;
+	int		do_clocal = 0, extra_count = 0;
+	unsigned long	flags;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (state->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, state->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttys%d, count = %d\n",
+	       state->line, state->count);
+#endif
+	save_flags(flags); cli();
+	if (!tty_hung_up_p(filp)) {
+		extra_count = 1;
+		state->count--;
+	}
+	restore_flags(flags);
+	info->blocked_open++;
+	while (1) {
+		save_flags(flags); cli();
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (tty->termios->c_cflag & CBAUD))
+			sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING))
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		       info->line, state->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (extra_count)
+		state->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	       info->line, state->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}
+
+static int get_async_struct(int line, struct async_struct **ret_info)
+{
+	struct async_struct *info;
+	struct serial_state *sstate;
+
+#ifdef REMOTE_DEBUG
+	if (kdb_port_info.state && line == kdb_port_info.line)
+		return -ENODEV;
+#endif
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = sstate->info;
+		return 0;
+	}
+	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+	memset(info, 0, sizeof(struct async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	info->magic = SERIAL_MAGIC;
+	info->port = sstate->port;
+	info->flags = sstate->flags;
+	info->io_type = sstate->io_type;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = sstate->info;
+		return 0;
+	}
+	*ret_info = sstate->info = info;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct	*info;
+	int 			retval, line;
+	unsigned long		page;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		return -ENODEV;
+	}
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+	if (!tmp_buf) {
+		page = get_free_page(GFP_KERNEL);
+		if (!page) {
+			return -ENOMEM;
+		}
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		return retval;
+	}
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else 
+			*tty->termios = info->state->callout_termios;
+		change_speed(info, 0);
+	}
+#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+	if (sercons.cflag && sercons.index == line) {
+		tty->termios->c_cflag = sercons.cflag;
+		sercons.cflag = 0;
+		change_speed(info, 0);
+	}
+#endif
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttys%d successful...", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static inline int line_info(char *buf, struct serial_state *state)
+{
+	struct async_struct *info = state->info, scr_info;
+	char	stat_buf[30];
+	int	ret;
+	unsigned long flags;
+
+	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
+		      state->line, SERIAL_DRIVER_NAME, 
+		      state->port, state->irq);
+
+	if (!state->port) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+	/*
+	 * Figure out the current RS-232 lines
+	 */
+	if (!info) {
+		info = &scr_info;	/* This is just for serial_{in,out} */
+
+		info->magic = SERIAL_MAGIC;
+		info->port = state->port;
+		info->flags = state->flags;
+		info->quot = 0;
+		info->tty = 0;
+	}
+	
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+	save_flags(flags); cli();
+	if (!(sio_reg(info)->flcr & TXx927_SIFLCR_RTSSC))
+		strcat(stat_buf, "|RTS");
+	if (!(sio_reg(info)->cisr & TXx927_SICISR_CTSS))
+		strcat(stat_buf, "|CTS");
+	restore_flags(flags); 
+
+	if (info->quot) {
+		ret += sprintf(buf+ret, " baud:%d",
+			       state->baud_base / info->quot);
+	}
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+		      state->icount.tx, state->icount.rx);
+
+	if (state->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+	
+	if (state->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+	
+	if (state->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+
+	if (state->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+	/*
+	 * Last thing is the RS-232 status lines
+	 */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	return ret;
+}
+
+static int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (begin-off);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static _INLINE_ void show_serial_version(void)
+{
+ 	printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
+}
+
+/*
+ * The serial driver boot-time initialization code!
+ */
+static int __init rs_init(void)
+{
+	int i;
+	struct serial_state * state;
+
+	if (rs_table[0].port == 0)
+		return -ENODEV;
+
+	init_bh(TXX927_SERIAL_BH, do_serial_bh);
+	init_timer(&serial_timer);
+	serial_timer.function = rs_timer;
+	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+
+	for (i = 0; i < NR_IRQS; i++) {
+		IRQ_ports[i] = 0;
+		IRQ_timeout[i] = 0;
+	}
+#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+	/*
+	 *	The interrupt of the serial console port
+	 *	can't be shared.
+	 */
+	if (sercons.flags & CON_CONSDEV) {
+		for(i = 0; i < NR_PORTS; i++)
+			if (i != sercons.index &&
+			    rs_table[i].irq == rs_table[sercons.index].irq)
+				rs_table[i].irq = 0;
+	}
+#endif
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.driver_name = "txx927serial";
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "tts/%d";
+#else
+	serial_driver.name = "ttyS";
+#endif
+	serial_driver.major = TXX927_TTY_MAJOR;
+	serial_driver.minor_start = TXX927_TTY_MINOR_START + SERIAL_DEV_OFFSET;
+	serial_driver.num = NR_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.break_ctl = rs_break;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = rs_read_proc;
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	        callout_driver.name = "cua/%d";
+#else
+		callout_driver.name = "cua";
+#endif                               
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+
+	if (tty_register_driver(&serial_driver)){
+		panic("Couldn't register serial driver\n");
+	}
+	if (tty_register_driver(&callout_driver)) {
+		panic("Couldn't register callout driver\n");
+	}
+	
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		state->magic = SSTATE_MAGIC;
+		state->line = i;
+		state->type = PORT_UNKNOWN;
+		state->custom_divisor = 0;
+		state->close_delay = 5*HZ/10;
+		state->closing_wait = 30*HZ;
+		state->callout_termios = callout_driver.init_termios;
+		state->normal_termios = serial_driver.init_termios;
+		state->icount.cts = state->icount.dsr = 
+			state->icount.rng = state->icount.dcd = 0;
+		state->icount.rx = state->icount.tx = 0;
+		state->icount.frame = state->icount.parity = 0;
+		state->icount.overrun = state->icount.brk = 0;
+		state->irq = irq_cannonicalize(state->irq);
+		state->xmit_fifo_size = TXx927_SIO_TX_FIFO;
+		if (state->hub6)
+			state->io_type = SERIAL_IO_HUB6;
+		if (state->port) {
+			continue;                                
+		}
+	}
+
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+	        if (state->type == PORT_UNKNOWN) {
+		       continue;
+		}                                        
+		printk(KERN_INFO "%s%02d at 0x%04lx (irq = %d) is a %s\n",
+		       TXX927_TTY_NAME,
+		       state->line,
+		       state->port, state->irq,
+		       SERIAL_DRIVER_NAME);
+		tty_register_devfs(&serial_driver, 0,
+		                serial_driver.minor_start + state->line);
+		tty_register_devfs(&callout_driver, 0,
+			       	callout_driver.minor_start + state->line); 
+	}
+	return 0;
+}
+
+static void __exit rs_fini(void) 
+{
+	unsigned long flags;
+	int e1, e2;
+	int i;
+	struct async_struct *info;
+
+	del_timer_sync(&serial_timer);
+	save_flags(flags); cli();
+        remove_bh(TXX927_SERIAL_BH);
+	if ((e1 = tty_unregister_driver(&serial_driver)))
+		printk(KERN_WARNING "serial: failed to unregister serial driver (%d)\n",
+		       e1);
+	if ((e2 = tty_unregister_driver(&callout_driver)))
+		printk(KERN_WARNING "serial: failed to unregister callout driver (%d)\n", 
+		       e2);
+	restore_flags(flags);
+
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((info = rs_table[i].info)) {
+			rs_table[i].info = NULL;
+			kfree(info);
+		}
+	}
+	if (tmp_buf) {
+		unsigned long pg = (unsigned long) tmp_buf;
+		tmp_buf = NULL;
+		free_page(pg);
+	}
+}
+
+module_init(rs_init);
+module_exit(rs_fini);
+MODULE_DESCRIPTION("TXX927 serial driver");
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+
+static struct async_struct async_sercons;
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ */
+static void serial_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+	static struct async_struct *info = &async_sercons;
+	int ier;
+	unsigned i;
+
+	/*
+	 *	First save the IER then disable the interrupts
+	 */
+	ier = sio_reg(info)->dicr;
+	sio_reg(info)->dicr = 0;
+
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(info);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		sio_reg(info)->tfifo = *s;
+		if (*s == 10) {
+			wait_for_xmitr(info);
+			sio_reg(info)->tfifo = 13;
+		}
+	}
+
+	/*
+	 *	Finally, Wait for transmitter & holding register to empty
+	 * 	and restore the IER
+	 */
+	wait_for_xmitr(info);
+	sio_reg(info)->dicr = ier;
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+	return MKDEV(TXX927_TTY_MAJOR, TXX927_TTY_MINOR_START + c->index);
+}
+
+/*
+ *	Setup initial baud/bits/parity. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int serial_console_setup(struct console *co, char *options)
+{
+	static struct async_struct *info;
+	struct serial_state *state;
+	unsigned cval;
+	int	baud = 9600;
+	int	bits = 8;
+	int	parity = 'n';
+	int	cflag = CREAD | HUPCL | CLOCAL;
+	int	quot = 0;
+	char	*s;
+
+	if (co->index < 0 || co->index >= NR_PORTS) {
+		return -1;
+	}
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s - '0';
+	}
+
+	/*
+	 *	Now construct a cflag setting.
+	 */
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 115200:
+			cflag |= B115200;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			break;
+	}
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			break;
+		default:
+		case 8:
+			cflag |= CS8;
+			break;
+	}
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= PARODD;
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			break;
+	}
+	co->cflag = cflag;
+
+	/*
+	 *	Divisor, bytesize and parity
+	 */
+	state = rs_table + co->index;
+	info = &async_sercons;
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+	info->io_type = state->io_type;
+	info->iomem_base = state->iomem_base;
+	info->iomem_reg_shift = state->iomem_reg_shift;
+	quot = state->baud_base / baud;
+
+	switch (cflag & CSIZE) {
+	case CS7: cval = TXx927_SILCR_UMODE_7BIT; break;
+	default:
+	case CS8: cval = TXx927_SILCR_UMODE_8BIT; break;
+	}
+	if (cflag & CSTOPB)
+		cval |= TXx927_SILCR_USBL_2BIT;
+	else
+		cval |= TXx927_SILCR_USBL_1BIT;
+	if (cflag & PARENB)
+		cval |= TXx927_SILCR_UPEN;
+	if (!(cflag & PARODD))
+		cval |= TXx927_SILCR_UEPS;
+
+	/*
+	 *	Disable UART interrupts, set DTR and RTS high
+	 *	and set speed.
+	 */
+	sio_reg(info)->dicr = 0;
+	sio_reg(info)->lcr = cval | TXx927_SILCR_SCS_IMCLK_BG;
+	sio_reg(info)->bgr = quot | TXx927_SIBGR_BCLK_T0;
+	/* HW RTS/CTS control */
+	if (info->flags & ASYNC_HAVE_CTS_LINE)
+		sio_reg(info)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES |
+			TXx927_SIFLCR_RTSTL_MAX /* 15 */;
+	/* Enable RX/TX */
+	sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE);
+
+	return 0;
+}
+
+static struct console sercons = {
+	name:           TXX927_TTY_NAME,
+	write:          serial_console_write,
+	device:	        serial_console_device,
+	setup:	        serial_console_setup,
+	flags:	        CON_PRINTBUFFER,
+	index:	        -1,
+};
+
+/*
+ *	Register console.
+ */
+void __init txx927_console_init(void)
+{
+	register_console(&sercons);
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sh-sci.c linux/drivers/char/sh-sci.c
--- linux.orig/drivers/char/sh-sci.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/sh-sci.c	2002-07-20 01:08:34.000000000 +0000
@@ -1181,15 +1181,6 @@
 	put_string(sercons_port, s, count);
 }
 
-/*
- *	Receive character from the serial port
- */
-static int serial_console_wait_key(struct console *co)
-{
-	/* Not implemented yet */
-	return 0;
-}
-
 static kdev_t serial_console_device(struct console *c)
 {
 	return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index);
@@ -1273,7 +1264,6 @@
 	name:		"ttySC",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/shwdt.c linux/drivers/char/shwdt.c
--- linux.orig/drivers/char/shwdt.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/shwdt.c	2002-07-20 01:08:31.000000000 +0000
@@ -9,6 +9,12 @@
  * 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.
+ *
+ * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ *     Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ * 19-Apr-2002 Rob Radez <rob@osinvestor.com>
+ *     Added expect close support, made emulated timeout runtime changeable
+ *     general cleanups, add some ioctls
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -19,7 +25,6 @@
 #include <linux/watchdog.h>
 #include <linux/reboot.h>
 #include <linux/notifier.h>
-#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 
 #include <asm/io.h>
@@ -47,18 +52,55 @@
 #define WTCSR_CKS1	0x02
 #define WTCSR_CKS0	0x01
 
-#define WTCSR_CKS	0x07
-#define WTCSR_CKS_1	0x00
-#define WTCSR_CKS_4	0x01
-#define WTCSR_CKS_16	0x02
-#define WTCSR_CKS_32	0x03
-#define WTCSR_CKS_64	0x04
-#define WTCSR_CKS_256	0x05
-#define WTCSR_CKS_1024	0x06
+/*
+ * CKS0-2 supports a number of clock division ratios. At the time the watchdog
+ * is enabled, it defaults to a 41 usec overflow period .. we overload this to
+ * something a little more reasonable, and really can't deal with anything
+ * lower than WTCSR_CKS_1024, else we drop back into the usec range.
+ *
+ * Clock Division Ratio         Overflow Period
+ * --------------------------------------------
+ *     1/32 (initial value)       41 usecs
+ *     1/64                       82 usecs
+ *     1/128                     164 usecs
+ *     1/256                     328 usecs
+ *     1/512                     656 usecs
+ *     1/1024                   1.31 msecs
+ *     1/2048                   2.62 msecs
+ *     1/4096                   5.25 msecs
+ */
+#define WTCSR_CKS_32	0x00
+#define WTCSR_CKS_64	0x01
+#define WTCSR_CKS_128	0x02
+#define WTCSR_CKS_256	0x03
+#define WTCSR_CKS_512	0x04
+#define WTCSR_CKS_1024	0x05
+#define WTCSR_CKS_2048	0x06
 #define WTCSR_CKS_4096	0x07
 
-static int sh_is_open = 0;
+/*
+ * Default clock division ratio is 5.25 msecs. Overload this at module load
+ * time. Any value not in the msec range will default to a timeout of one
+ * jiffy, which exceeds the usec overflow periods.
+ */
+static int clock_division_ratio = WTCSR_CKS_4096;
+
+#define msecs_to_jiffies(msecs)	(jiffies + ((HZ * msecs + 999) / 1000))
+#define next_ping_period(cks)	msecs_to_jiffies(cks - 4)
+
+static unsigned long sh_is_open;
 static struct watchdog_info sh_wdt_info;
+static char shwdt_expect_close;
+
+static struct timer_list timer;
+static unsigned long next_heartbeat;
+static int sh_heartbeat = 30;
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
 
 /**
  *	sh_wdt_write_cnt - Write to Counter
@@ -93,6 +135,10 @@
  */
 static void sh_wdt_start(void)
 {
+	timer.expires = next_ping_period(clock_division_ratio);
+	next_heartbeat = jiffies + (sh_heartbeat * HZ);
+	add_timer(&timer);
+
 	sh_wdt_write_csr(WTCSR_WT | WTCSR_CKS_4096);
 	sh_wdt_write_cnt(0);
 	sh_wdt_write_csr((ctrl_inb(WTCSR) | WTCSR_TME));
@@ -105,6 +151,8 @@
  */
 static void sh_wdt_stop(void)
 {
+	del_timer(&timer);
+
 	sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_TME));
 }
 
@@ -117,8 +165,13 @@
  */
 static void sh_wdt_ping(unsigned long data)
 {
-	sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF));
-	sh_wdt_write_cnt(0);
+	if (time_before(jiffies, next_heartbeat)) {
+		sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF));
+		sh_wdt_write_cnt(0);
+
+		timer.expires = next_ping_period(clock_division_ratio);
+		add_timer(&timer);
+	}
 }
 
 /**
@@ -131,19 +184,10 @@
  */
 static int sh_wdt_open(struct inode *inode, struct file *file)
 {
-	switch (MINOR(inode->i_rdev)) {
-		case WATCHDOG_MINOR:
-			if (sh_is_open) {
-				return -EBUSY;
-			}
-
-			sh_is_open = 1;
-			sh_wdt_start();
+	if (test_and_set_bit(0, &sh_is_open))
+		return -EBUSY;
 
-			return 0;
-		default:
-			return -ENODEV;
-	}
+	sh_wdt_start();
 
 	return 0;
 }
@@ -158,37 +202,19 @@
  */
 static int sh_wdt_close(struct inode *inode, struct file *file)
 {
-	lock_kernel();
-	
-	if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
+	if (!nowayout && shwdt_expect_close == 42) {
 		sh_wdt_stop();
-#endif
-		sh_is_open = 0;
+	} else {
+		printk(KERN_CRIT "shwdt: Unexpected close, not stopping watchdog!\n");
+		next_heartbeat = jiffies + (sh_heartbeat * HZ);
 	}
+	clear_bit(0, &sh_is_open);
+	shwdt_expect_close = 0;
 	
-	unlock_kernel();
-
 	return 0;
 }
 
 /**
- * 	sh_wdt_read - Read from Device
- *
- * 	@file: file handle of device
- * 	@buf: buffer to write to
- * 	@count: length of buffer
- * 	@ppos: offset
- *
- * 	Unsupported.
- */
-static ssize_t sh_wdt_read(struct file *file, char *buf,
-			   size_t count, loff_t *ppos)
-{
-	return -EINVAL;
-}
-
-/**
  * 	sh_wdt_write - Write to Device
  *
  * 	@file: file handle of device
@@ -206,11 +232,18 @@
 		return -ESPIPE;
 
 	if (count) {
-		sh_wdt_ping(0);
-		return 1;
+		size_t i;
+
+		shwdt_expect_close = 0;
+
+		for (i = 0; i != count; i++) {
+			if (buf[i] == 'V')
+				shwdt_expect_close = 42;
+		}
+		next_heartbeat = jiffies + (sh_heartbeat * HZ);
 	}
 
-	return 0;
+	return count;
 }
 
 /**
@@ -227,6 +260,8 @@
 static int sh_wdt_ioctl(struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
+	int new_timeout;
+
 	switch (cmd) {
 		case WDIOC_GETSUPPORT:
 			if (copy_to_user((struct watchdog_info *)arg,
@@ -234,20 +269,44 @@
 					  sizeof(sh_wdt_info))) {
 				return -EFAULT;
 			}
-			
+
 			break;
 		case WDIOC_GETSTATUS:
-			if (copy_to_user((int *)arg,
-					 &sh_is_open,
-					 sizeof(int))) {
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0, (int *)arg);
+		case WDIOC_KEEPALIVE:
+			next_heartbeat = jiffies + (sh_heartbeat * HZ);
+
+			break;
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_timeout, (int *)arg))
+				return -EFAULT;
+			if (new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
+				return -EINVAL;
+			sh_heartbeat = new_timeout;
+			next_heartbeat = jiffies + (sh_heartbeat * HZ);
+			/* Fall */
+		case WDIOC_GETTIMEOUT:
+			return put_user(sh_heartbeat, (int *)arg);
+		case WDIOC_SETOPTIONS:
+		{
+			int options, retval = -EINVAL;
+
+			if (get_user(options, (int *)arg))
 				return -EFAULT;
+
+			if (options & WDIOS_DISABLECARD) {
+				sh_wdt_stop();
+				retval = 0;
 			}
 
-			break;
-		case WDIOC_KEEPALIVE:
-			sh_wdt_ping(0);
-			
-			break;
+			if (options & WDIOS_ENABLECARD) {
+				sh_wdt_start();
+				retval = 0;
+			}
+
+			return retval;
+		}
 		default:
 			return -ENOTTY;
 	}
@@ -277,7 +336,7 @@
 
 static struct file_operations sh_wdt_fops = {
 	owner:		THIS_MODULE,
-	read:		sh_wdt_read,
+	llseek:		no_llseek,
 	write:		sh_wdt_write,
 	ioctl:		sh_wdt_ioctl,
 	open:		sh_wdt_open,
@@ -285,9 +344,9 @@
 };
 
 static struct watchdog_info sh_wdt_info = {
-	WDIOF_KEEPALIVEPING,
-	1,
-	"SH WDT",
+	options:		WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+	firmware_version:	0,
+	identity:		"SH WDT",
 };
 
 static struct notifier_block sh_wdt_notifier = {
@@ -297,9 +356,9 @@
 };
 
 static struct miscdevice sh_wdt_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&sh_wdt_fops,
+	minor:		WATCHDOG_MINOR,
+	name:		"watchdog",
+	fops:		&sh_wdt_fops,
 };
 
 /**
@@ -336,6 +395,10 @@
 		return -EINVAL;
 	}
 
+	init_timer(&timer);
+	timer.function = sh_wdt_ping;
+	timer.data = 0;
+
 	return 0;
 }
 
@@ -355,6 +418,11 @@
 
 EXPORT_NO_SYMBOLS;
 
+MODULE_PARM(nowayout,"i");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM(clock_division_ratio, "i");
+MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). Defaults to 0x7.");
+
 MODULE_AUTHOR("Paul Mundt <lethal@chaoticdreams.org>");
 MODULE_DESCRIPTION("SH 3/4 watchdog driver");
 MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/softdog.c linux/drivers/char/softdog.c
--- linux.orig/drivers/char/softdog.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/softdog.c	2002-07-20 01:08:34.000000000 +0000
@@ -68,7 +68,7 @@
 static struct timer_list watchdog_ticktock = {
 	function:	watchdog_fire,
 };
-static int timer_alive;
+static unsigned long timer_alive;
 
 
 /*
@@ -93,7 +93,7 @@
  
 static int softdog_open(struct inode *inode, struct file *file)
 {
-	if(timer_alive)
+	if(test_and_set_bit(0, &timer_alive))
 		return -EBUSY;
 #ifdef CONFIG_WATCHDOG_NOWAYOUT	 
 	MOD_INC_USE_COUNT;
@@ -102,7 +102,6 @@
 	 *	Activate timer
 	 */
 	mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
-	timer_alive=1;
 	return 0;
 }
 
@@ -112,12 +111,10 @@
 	 *	Shut off the timer.
 	 * 	Lock it in if it's a module and we defined ...NOWAYOUT
 	 */
-	 lock_kernel();
 #ifndef CONFIG_WATCHDOG_NOWAYOUT	 
 	del_timer(&watchdog_ticktock);
 #endif	
-	timer_alive=0;
-	unlock_kernel();
+	clear_bit(0, &timer_alive);
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sonypi.c linux/drivers/char/sonypi.c
--- linux.orig/drivers/char/sonypi.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/sonypi.c	2002-07-20 01:08:27.000000000 +0000
@@ -50,6 +50,7 @@
 static int fnkeyinit; /* = 0 */
 static int camera; /* = 0 */
 static int compat; /* = 0 */
+static int nojogdial; /* = 0 */
 
 /* Inits the queue */
 static inline void sonypi_initq(void) {
@@ -310,24 +311,28 @@
 	int i;
 	u8 sonypi_jogger_ev, sonypi_fnkey_ev;
 	u8 sonypi_capture_ev, sonypi_bluetooth_ev;
+	u8 sonypi_pkey_ev;
 
 	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
 		sonypi_jogger_ev = SONYPI_TYPE2_JOGGER_EV;
 		sonypi_fnkey_ev = SONYPI_TYPE2_FNKEY_EV;
 		sonypi_capture_ev = SONYPI_TYPE2_CAPTURE_EV;
 		sonypi_bluetooth_ev = SONYPI_TYPE2_BLUETOOTH_EV;
+		sonypi_pkey_ev = nojogdial ? SONYPI_TYPE2_PKEY_EV 
+					   : SONYPI_TYPE1_PKEY_EV;
 	}
 	else {
 		sonypi_jogger_ev = SONYPI_TYPE1_JOGGER_EV;
 		sonypi_fnkey_ev = SONYPI_TYPE1_FNKEY_EV;
 		sonypi_capture_ev = SONYPI_TYPE1_CAPTURE_EV;
 		sonypi_bluetooth_ev = SONYPI_TYPE1_BLUETOOTH_EV;
+		sonypi_pkey_ev = SONYPI_TYPE1_PKEY_EV;
 	}
 
 	v1 = inb_p(sonypi_device.ioport1);
 	v2 = inb_p(sonypi_device.ioport2);
 
-	if ((v2 & SONYPI_TYPE1_PKEY_EV) == SONYPI_TYPE1_PKEY_EV) {
+	if ((v2 & sonypi_pkey_ev) == sonypi_pkey_ev) {
 		for (i = 0; sonypi_pkeyev[i].event; i++)
 			if (sonypi_pkeyev[i].data == v1) {
 				event = sonypi_pkeyev[i].event;
@@ -480,12 +485,10 @@
 
 static int sonypi_misc_open(struct inode * inode, struct file * file) {
 	down(&sonypi_device.lock);
-	if (sonypi_device.open_count)
-		goto out;
+	/* Flush input queue on first open */
+	if (!sonypi_device.open_count)
+		sonypi_initq();
 	sonypi_device.open_count++;
-	/* Flush input queue */
-	sonypi_initq();
-out:
 	up(&sonypi_device.lock);
 	return 0;
 }
@@ -713,11 +716,15 @@
 	       SONYPI_DRIVER_MAJORVERSION,
 	       SONYPI_DRIVER_MINORVERSION);
 	printk(KERN_INFO "sonypi: detected %s model, "
-	       "camera = %s, compat = %s\n",
+	       "verbose = %s, fnkeyinit = %s, camera = %s, "
+	       "compat = %s, nojogdial = %s\n",
 	       (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ?
 			"type1" : "type2",
+	       verbose ? "on" : "off",
+	       fnkeyinit ? "on" : "off",
 	       camera ? "on" : "off",
-	       compat ? "on" : "off");
+	       compat ? "on" : "off",
+	       nojogdial ? "on" : "off");
 	printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
 	       sonypi_device.irq, 
 	       sonypi_device.ioport1, sonypi_device.ioport2);
@@ -773,7 +780,7 @@
 
 #ifndef MODULE
 static int __init sonypi_setup(char *str)  {
-	int ints[6];
+	int ints[7];
 
 	str = get_options(str, ARRAY_SIZE(ints), ints);
 	if (ints[0] <= 0) 
@@ -791,6 +798,9 @@
 	if (ints[0] == 4)
 		goto out;
 	compat = ints[5];
+	if (ints[0] == 5)
+		goto out;
+	nojogdial = ints[6];
 out:
 	return 1;
 }
@@ -817,5 +827,7 @@
 MODULE_PARM_DESC(camera, "set this if you have a MotionEye camera (PictureBook series)");
 MODULE_PARM(compat,"i");
 MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode");
+MODULE_PARM(nojogdial, "i");
+MODULE_PARM_DESC(nojogdial, "set this if you have a Vaio without a jogdial (like the fx series)");
 
 EXPORT_SYMBOL(sonypi_camera_command);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sonypi.h linux/drivers/char/sonypi.h
--- linux.orig/drivers/char/sonypi.h	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/sonypi.h	2002-07-20 01:08:23.000000000 +0000
@@ -35,7 +35,7 @@
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION	 1
-#define SONYPI_DRIVER_MINORVERSION	10
+#define SONYPI_DRIVER_MINORVERSION	13
 
 #include <linux/types.h>
 #include <linux/pci.h>
@@ -141,6 +141,7 @@
 #define SONYPI_TYPE1_BLUETOOTH_EV	0x30
 #define SONYPI_TYPE2_BLUETOOTH_EV	0x08
 #define SONYPI_TYPE1_PKEY_EV		0x40
+#define SONYPI_TYPE2_PKEY_EV		0x08
 #define SONYPI_BACK_EV			0x08
 #define SONYPI_LID_EV			0x38
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/specialix.c linux/drivers/char/specialix.c
--- linux.orig/drivers/char/specialix.c	2001-11-09 22:01:21.000000000 +0000
+++ linux/drivers/char/specialix.c	2002-07-20 01:08:32.000000000 +0000
@@ -239,28 +239,28 @@
  */
 
 /* Get board number from pointer */
-extern inline int board_No (struct specialix_board * bp)
+static inline int board_No (struct specialix_board * bp)
 {
 	return bp - sx_board;
 }
 
 
 /* Get port number from pointer */
-extern inline int port_No (struct specialix_port const * port)
+static inline int port_No (struct specialix_port const * port)
 {
 	return SX_PORT(port - sx_port); 
 }
 
 
 /* Get pointer to board from pointer to port */
-extern inline struct specialix_board * port_Board(struct specialix_port const * port)
+static inline struct specialix_board * port_Board(struct specialix_port const * port)
 {
 	return &sx_board[SX_BOARD(port - sx_port)];
 }
 
 
 /* Input Byte from CL CD186x register */
-extern inline unsigned char sx_in(struct specialix_board  * bp, unsigned short reg)
+static inline unsigned char sx_in(struct specialix_board  * bp, unsigned short reg)
 {
 	bp->reg = reg | 0x80;
 	outb (reg | 0x80, bp->base + SX_ADDR_REG);
@@ -269,7 +269,7 @@
 
 
 /* Output Byte to CL CD186x register */
-extern inline void sx_out(struct specialix_board  * bp, unsigned short reg,
+static inline void sx_out(struct specialix_board  * bp, unsigned short reg,
 			  unsigned char val)
 {
 	bp->reg = reg | 0x80;
@@ -279,7 +279,7 @@
 
 
 /* Input Byte from CL CD186x register */
-extern inline unsigned char sx_in_off(struct specialix_board  * bp, unsigned short reg)
+static inline unsigned char sx_in_off(struct specialix_board  * bp, unsigned short reg)
 {
 	bp->reg = reg;
 	outb (reg, bp->base + SX_ADDR_REG);
@@ -288,7 +288,7 @@
 
 
 /* Output Byte to CL CD186x register */
-extern inline void sx_out_off(struct specialix_board  * bp, unsigned short reg,
+static inline void sx_out_off(struct specialix_board  * bp, unsigned short reg,
 			  unsigned char val)
 {
 	bp->reg = reg;
@@ -298,7 +298,7 @@
 
 
 /* Wait for Channel Command Register ready */
-extern inline void sx_wait_CCR(struct specialix_board  * bp)
+static inline void sx_wait_CCR(struct specialix_board  * bp)
 {
 	unsigned long delay;
 
@@ -311,7 +311,7 @@
 
 
 /* Wait for Channel Command Register ready */
-extern inline void sx_wait_CCR_off(struct specialix_board  * bp)
+static inline void sx_wait_CCR_off(struct specialix_board  * bp)
 {
 	unsigned long delay;
 
@@ -327,13 +327,13 @@
  *  specialix IO8+ IO range functions.
  */
 
-extern inline int sx_check_io_range(struct specialix_board * bp)
+static inline int sx_check_io_range(struct specialix_board * bp)
 {
 	return check_region (bp->base, SX_IO_SPACE);
 }
 
 
-extern inline void sx_request_io_range(struct specialix_board * bp)
+static inline void sx_request_io_range(struct specialix_board * bp)
 {
 	request_region(bp->base, 
 	               bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
@@ -341,7 +341,7 @@
 }
 
 
-extern inline void sx_release_io_range(struct specialix_board * bp)
+static inline void sx_release_io_range(struct specialix_board * bp)
 {
 	release_region(bp->base, 
 	               bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
@@ -351,7 +351,7 @@
 /* Must be called with enabled interrupts */
 /* Ugly. Very ugly. Don't use this for anything else than initialization 
    code */
-extern inline void sx_long_delay(unsigned long delay)
+static inline void sx_long_delay(unsigned long delay)
 {
 	unsigned long i;
 	
@@ -599,7 +599,7 @@
  *  Interrupt processing routines.
  * */
 
-extern inline void sx_mark_event(struct specialix_port * port, int event)
+static inline void sx_mark_event(struct specialix_port * port, int event)
 {
 	/* 
 	 * I'm not quite happy with current scheme all serial
@@ -616,7 +616,7 @@
 }
 
 
-extern inline struct specialix_port * sx_get_port(struct specialix_board * bp,
+static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
 					       unsigned char const * what)
 {
 	unsigned char channel;
@@ -635,7 +635,7 @@
 }
 
 
-extern inline void sx_receive_exc(struct specialix_board * bp)
+static inline void sx_receive_exc(struct specialix_board * bp)
 {
 	struct specialix_port *port;
 	struct tty_struct *tty;
@@ -701,7 +701,7 @@
 }
 
 
-extern inline void sx_receive(struct specialix_board * bp)
+static inline void sx_receive(struct specialix_board * bp)
 {
 	struct specialix_port *port;
 	struct tty_struct *tty;
@@ -732,7 +732,7 @@
 }
 
 
-extern inline void sx_transmit(struct specialix_board * bp)
+static inline void sx_transmit(struct specialix_board * bp)
 {
 	struct specialix_port *port;
 	struct tty_struct *tty;
@@ -802,7 +802,7 @@
 }
 
 
-extern inline void sx_check_modem(struct specialix_board * bp)
+static inline void sx_check_modem(struct specialix_board * bp)
 {
 	struct specialix_port *port;
 	struct tty_struct *tty;
@@ -962,7 +962,7 @@
 
 
 /* Called with disabled interrupts */
-extern inline int sx_setup_board(struct specialix_board * bp)
+static inline int sx_setup_board(struct specialix_board * bp)
 {
 	int error;
 
@@ -986,7 +986,7 @@
 
 
 /* Called with disabled interrupts */
-extern inline void sx_shutdown_board(struct specialix_board *bp)
+static inline void sx_shutdown_board(struct specialix_board *bp)
 {
 	if (!(bp->flags & SX_BOARD_ACTIVE))
 		return;
@@ -1867,7 +1867,7 @@
 }
 
 
-extern inline void sx_send_break(struct specialix_port * port, unsigned long length)
+static inline void sx_send_break(struct specialix_port * port, unsigned long length)
 {
 	struct specialix_board *bp = port_Board(port);
 	unsigned long flags;
@@ -1886,7 +1886,7 @@
 }
 
 
-extern inline int sx_set_serial_info(struct specialix_port * port,
+static inline int sx_set_serial_info(struct specialix_port * port,
                                      struct serial_struct * newinfo)
 {
 	struct serial_struct tmp;
@@ -1942,7 +1942,7 @@
 }
 
 
-extern inline int sx_get_serial_info(struct specialix_port * port,
+static inline int sx_get_serial_info(struct specialix_port * port,
 				     struct serial_struct * retinfo)
 {
 	struct serial_struct tmp;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/stallion.c linux/drivers/char/stallion.c
--- linux.orig/drivers/char/stallion.c	2001-09-21 17:55:23.000000000 +0000
+++ linux/drivers/char/stallion.c	2002-07-20 01:08:28.000000000 +0000
@@ -188,14 +188,6 @@
  */
 static char		stl_unwanted[SC26198_RXFIFOSIZE];
 
-/*
- *	Keep track of what interrupts we have requested for us.
- *	We don't need to request an interrupt twice if it is being
- *	shared with another Stallion board.
- */
-static int	stl_gotintrs[STL_MAXBRDS];
-static int	stl_numintrs;
-
 /*****************************************************************************/
 
 static stlbrd_t		*stl_brds[STL_MAXBRDS];
@@ -520,7 +512,6 @@
 
 static int	stl_brdinit(stlbrd_t *brdp);
 static int	stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
-static int	stl_mapirq(int irq, char *name);
 static void	stl_getserial(stlport_t *portp, struct serial_struct *sp);
 static int	stl_setserial(stlport_t *portp, struct serial_struct *sp);
 static int	stl_getbrdstats(combrd_t *bp);
@@ -836,6 +827,7 @@
 			}
 			kfree(panelp);
 		}
+		free_irq(brdp->irq, brdp);
 
 		release_region(brdp->ioaddr1, brdp->iosize1);
 		if (brdp->iosize2 > 0)
@@ -844,10 +836,6 @@
 		kfree(brdp);
 		stl_brds[i] = (stlbrd_t *) NULL;
 	}
-
-	for (i = 0; (i < stl_numintrs); i++)
-		free_irq(stl_gotintrs[i], NULL);
-
 	restore_flags(flags);
 }
 
@@ -1553,7 +1541,8 @@
 	printk("stl_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
 #endif
 
-	copy_from_user(&sio, sp, sizeof(struct serial_struct));
+	if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
+		return -EFAULT;
 	if (!capable(CAP_SYS_ADMIN)) {
 		if ((sio.baud_base != portp->baud_base) ||
 		    (sio.close_delay != portp->close_delay) ||
@@ -2083,19 +2072,12 @@
 static void stl_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	stlbrd_t	*brdp;
-	int		i;
 
 #if DEBUG
 	printk("stl_intr(irq=%d,regs=%x)\n", irq, (int) regs);
 #endif
-
-	for (i = 0; (i < stl_nrbrds); i++) {
-		if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
-			continue;
-		if (brdp->state == 0)
-			continue;
-		(* brdp->isr)(brdp);
-	}
+	brdp = (stlbrd_t *) dev_id;
+	(* brdp->isr)(brdp);
 }
 
 /*****************************************************************************/
@@ -2270,39 +2252,6 @@
 /*****************************************************************************/
 
 /*
- *	Map in interrupt vector to this driver. Check that we don't
- *	already have this vector mapped, we might be sharing this
- *	interrupt across multiple boards.
- */
-
-static int __init stl_mapirq(int irq, char *name)
-{
-	int	rc, i;
-
-#if DEBUG
-	printk("stl_mapirq(irq=%d,name=%s)\n", irq, name);
-#endif
-
-	rc = 0;
-	for (i = 0; (i < stl_numintrs); i++) {
-		if (stl_gotintrs[i] == irq)
-			break;
-	}
-	if (i >= stl_numintrs) {
-		if (request_irq(irq, stl_intr, SA_SHIRQ, name, NULL) != 0) {
-			printk("STALLION: failed to register interrupt "
-				"routine for %s irq=%d\n", name, irq);
-			rc = -ENODEV;
-		} else {
-			stl_gotintrs[stl_numintrs++] = irq;
-		}
-	}
-	return(rc);
-}
-
-/*****************************************************************************/
-
-/*
  *	Initialize all the ports on a panel.
  */
 
@@ -2484,7 +2433,12 @@
 	brdp->nrpanels = 1;
 	brdp->state |= BRD_FOUND;
 	brdp->hwid = status;
-	rc = stl_mapirq(brdp->irq, name);
+	if (request_irq(brdp->irq, stl_intr, SA_SHIRQ, name, brdp) != 0) {
+		printk("STALLION: failed to register interrupt "
+		       "routine for %s irq=%d\n", name, brdp->irq);
+		rc = -ENODEV;
+	}
+
 	return(rc);
 }
 
@@ -2684,7 +2638,12 @@
 		outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
 
 	brdp->state |= BRD_FOUND;
-	i = stl_mapirq(brdp->irq, name);
+	if (request_irq(brdp->irq, stl_intr, SA_SHIRQ, name, brdp) != 0) {
+		printk("STALLION: failed to register interrupt "
+		       "routine for %s irq=%d\n", name, brdp->irq);
+		i = -ENODEV;
+	}
+
 	return(i);
 }
 
@@ -2940,7 +2899,8 @@
 	stlpanel_t	*panelp;
 	int		i;
 
-	copy_from_user(&stl_brdstats, bp, sizeof(combrd_t));
+	if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t)))
+		return -EFAULT;
 	if (stl_brdstats.brd >= STL_MAXBRDS)
 		return(-ENODEV);
 	brdp = stl_brds[stl_brdstats.brd];
@@ -2964,8 +2924,7 @@
 		stl_brdstats.panels[i].nrports = panelp->nrports;
 	}
 
-	copy_to_user(bp, &stl_brdstats, sizeof(combrd_t));
-	return(0);
+	return copy_to_user(bp, &stl_brdstats, sizeof(combrd_t)) ? -EFAULT : 0;
 }
 
 /*****************************************************************************/
@@ -3008,7 +2967,8 @@
 	unsigned long	flags;
 
 	if (portp == (stlport_t *) NULL) {
-		copy_from_user(&stl_comstats, cp, sizeof(comstats_t));
+		if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
+			return -EFAULT;
 		portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
 			stl_comstats.port);
 		if (portp == (stlport_t *) NULL)
@@ -3049,8 +3009,8 @@
 
 	portp->stats.signals = (unsigned long) stl_getsignals(portp);
 
-	copy_to_user(cp, &portp->stats, sizeof(comstats_t));
-	return(0);
+	return copy_to_user(cp, &portp->stats,
+			    sizeof(comstats_t)) ? -EFAULT : 0;
 }
 
 /*****************************************************************************/
@@ -3062,7 +3022,8 @@
 static int stl_clrportstats(stlport_t *portp, comstats_t *cp)
 {
 	if (portp == (stlport_t *) NULL) {
-		copy_from_user(&stl_comstats, cp, sizeof(comstats_t));
+		if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
+			return -EFAULT;
 		portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
 			stl_comstats.port);
 		if (portp == (stlport_t *) NULL)
@@ -3073,8 +3034,8 @@
 	portp->stats.brd = portp->brdnr;
 	portp->stats.panel = portp->panelnr;
 	portp->stats.port = portp->portnr;
-	copy_to_user(cp, &portp->stats, sizeof(comstats_t));
-	return(0);
+	return copy_to_user(cp, &portp->stats,
+			    sizeof(comstats_t)) ? -EFAULT : 0;
 }
 
 /*****************************************************************************/
@@ -3087,13 +3048,14 @@
 {
 	stlport_t	*portp;
 
-	copy_from_user(&stl_dummyport, (void *) arg, sizeof(stlport_t));
+	if (copy_from_user(&stl_dummyport, (void *) arg, sizeof(stlport_t)))
+		return -EFAULT;
 	portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr,
 		 stl_dummyport.portnr);
 	if (portp == (stlport_t *) NULL)
 		return(-ENODEV);
-	copy_to_user((void *) arg, portp, sizeof(stlport_t));
-	return(0);
+	return copy_to_user((void *)arg, portp,
+			    sizeof(stlport_t)) ? -EFAULT : 0;
 }
 
 /*****************************************************************************/
@@ -3106,14 +3068,14 @@
 {
 	stlbrd_t	*brdp;
 
-	copy_from_user(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t));
+	if (copy_from_user(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t)))
+		return -EFAULT;
 	if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS))
 		return(-ENODEV);
 	brdp = stl_brds[stl_dummybrd.brdnr];
 	if (brdp == (stlbrd_t *) NULL)
 		return(-ENODEV);
-	copy_to_user((void *) arg, brdp, sizeof(stlbrd_t));
-	return(0);
+	return copy_to_user((void *)arg, brdp, sizeof(stlbrd_t)) ? -EFAULT : 0;
 }
 
 /*****************************************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sx.c linux/drivers/char/sx.c
--- linux.orig/drivers/char/sx.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/sx.c	2002-07-20 01:08:34.000000000 +0000
@@ -353,9 +353,11 @@
                               0xc8000, 0xd8000, 0xe8000};
 static int si_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000, 
                               0xc8000, 0xd8000, 0xe8000, 0xa0000};
+static int si1_probe_addrs[]= { 0xd0000};
 
 #define NR_SX_ADDRS (sizeof(sx_probe_addrs)/sizeof (int))
 #define NR_SI_ADDRS (sizeof(si_probe_addrs)/sizeof (int))
+#define NR_SI1_ADDRS (sizeof(si1_probe_addrs)/sizeof (int))
 
 
 /* Set the mask to all-ones. This alas, only supports 32 interrupts. 
@@ -582,6 +584,8 @@
 		}
 	} else if (IS_EISA_BOARD(board)) {
 		outb(board->irq<<4, board->eisa_base+0xc02);
+	} else if (IS_SI1_BOARD(board)) {
+	        write_sx_byte (board, SI1_ISA_RESET,   0); // value does not matter
 	} else {
 		/* Gory details of the SI/ISA board */
 		write_sx_byte (board, SI2_ISA_RESET,    SI2_ISA_RESET_SET);
@@ -656,6 +660,9 @@
 	} else if (IS_EISA_BOARD(board)) {
 		write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL);
 		outb((board->irq<<4)|4, board->eisa_base+0xc02);
+	} else if (IS_SI1_BOARD(board)) {
+		write_sx_byte (board, SI1_ISA_RESET_CLEAR, 0);
+		write_sx_byte (board, SI1_ISA_INTCL, 0);
 	} else {
 		/* Don't bug me about the clear_set. 
 		   I haven't the foggiest idea what it's about -- REW */
@@ -681,6 +688,9 @@
 		                                 SX_CONF_HOSTIRQ);
 	} else if (IS_EISA_BOARD(board)) {
 		inb(board->eisa_base+0xc03);  
+	} else if (IS_SI1_BOARD(board)) {
+	       write_sx_byte (board, SI1_ISA_INTCL,0);
+	       write_sx_byte (board, SI1_ISA_INTCL_CLEAR,0);
 	} else {
 		switch (board->irq) {
 		case 11:write_sx_byte (board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET);break;
@@ -1690,6 +1700,7 @@
 		if (IS_SX_BOARD (board)) rc = SX_TYPE_SX;
 		if (IS_CF_BOARD (board)) rc = SX_TYPE_CF;
 		if (IS_SI_BOARD (board)) rc = SX_TYPE_SI;
+		if (IS_SI1_BOARD (board)) rc = SX_TYPE_SI;
 		if (IS_EISA_BOARD (board)) rc = SX_TYPE_SI;
 		sx_dprintk (SX_DEBUG_FIRMWARE, "returning type= %d\n", rc);
 		break;
@@ -1720,8 +1731,11 @@
 		Get_user (data,	 descr++);
 		while (nbytes && data) {
 			for (i=0;i<nbytes;i += SX_CHUNK_SIZE) {
-				copy_from_user (tmp, (char *)data+i, 
-				                (i+SX_CHUNK_SIZE>nbytes)?nbytes-i:SX_CHUNK_SIZE);
+				if (copy_from_user(tmp, (char *)data + i, 
+						   (i + SX_CHUNK_SIZE >
+						    nbytes) ? nbytes - i :
+						   	      SX_CHUNK_SIZE))
+					return -EFAULT;
 				memcpy_toio    ((char *) (board->base2 + offset + i), tmp, 
 				                (i+SX_CHUNK_SIZE>nbytes)?nbytes-i:SX_CHUNK_SIZE);
 			}
@@ -2181,13 +2195,20 @@
 	int i;
 
 	func_enter();
-	sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature %lx.\n", 
+	sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at %lx.\n", board->hw_base,
 	            board->base + SI2_ISA_ID_BASE);
 
 	if (sx_debug & SX_DEBUG_PROBE)
 		my_hd ((char *)(board->base + SI2_ISA_ID_BASE), 0x8);
 
-	if (!IS_EISA_BOARD(board)) {
+	if (!IS_EISA_BOARD(board)  ) {
+	  if( IS_SI1_BOARD(board) ) 
+	    {
+		for (i=0;i<8;i++) {
+		  write_sx_byte (board, SI2_ISA_ID_BASE+7-i,i); 
+
+		}
+	    }
 		for (i=0;i<8;i++) {
 			if ((read_sx_byte (board, SI2_ISA_ID_BASE+7-i) & 7) != i) {
 				return 0;
@@ -2203,7 +2224,7 @@
 
 	board->nports = -1;
 
-	/* This resets the processor, and keeps it off the bus. */
+ 	/* This resets the processor, and keeps it off the bus. */
 	if (!sx_reset (board)) 
 		return 0;
 	sx_dprintk (SX_DEBUG_INIT, "reset the board...\n");
@@ -2559,6 +2580,21 @@
 			my_iounmap (board->hw_base, board->base);
 		}
 	}
+	for (i=0;i<NR_SI1_ADDRS;i++) {
+		board = &boards[found];
+		board->hw_base = si1_probe_addrs[i];
+		board->base2 =
+		board->base = (ulong) ioremap(board->hw_base, SI1_ISA_WINDOW_LEN);
+		board->flags &= ~SX_BOARD_TYPE;
+		board->flags |=  SI1_ISA_BOARD;
+		board->irq = sx_irqmask ?-1:0;
+
+		if (probe_si (board)) {
+			found++;
+		} else {
+			my_iounmap (board->hw_base, board->base);
+		}
+	}
 
         sx_dprintk(SX_DEBUG_PROBE, "Probing for EISA cards\n");
         for(eisa_slot=0x1000; eisa_slot<0x10000; eisa_slot+=0x1000)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sx.h linux/drivers/char/sx.h
--- linux.orig/drivers/char/sx.h	2001-06-27 21:13:01.000000000 +0000
+++ linux/drivers/char/sx.h	2002-07-20 01:08:28.000000000 +0000
@@ -73,6 +73,7 @@
 #define SX_CFPCI_BOARD       0x00000008
 #define SX_CFISA_BOARD       0x00000010
 #define SI_EISA_BOARD        0x00000020
+#define SI1_ISA_BOARD        0x00000040
 
 #define SX_BOARD_PRESENT     0x00001000
 #define SX_BOARD_INITIALIZED 0x00002000
@@ -84,6 +85,7 @@
                                             SX_ISA_BOARD | SX_CFISA_BOARD))
 
 #define IS_SI_BOARD(board) (board->flags & SI_ISA_BOARD)
+#define IS_SI1_BOARD(board) (board->flags & SI1_ISA_BOARD)
 
 #define IS_EISA_BOARD(board) (board->flags & SI_EISA_BOARD)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sxboards.h linux/drivers/char/sxboards.h
--- linux.orig/drivers/char/sxboards.h	2000-03-13 03:18:55.000000000 +0000
+++ linux/drivers/char/sxboards.h	2002-07-20 01:08:21.000000000 +0000
@@ -46,12 +46,36 @@
 #define		CARD_BUS(type)		((type>>4)&0xF)
 #define		CARD_PHASE(type)	(type&0xF)
 
+#define		TYPE_SI1_ISA		CARD_TYPE(BUS_ISA,SI1_Z280)
 #define		TYPE_SI2_ISA		CARD_TYPE(BUS_ISA,SI2_Z280)
 #define		TYPE_SI2_EISA		CARD_TYPE(BUS_EISA,SI2_Z280)
 #define		TYPE_SI2_PCI		CARD_TYPE(BUS_PCI,SI2_Z280)
 
 #define		TYPE_SX_ISA		CARD_TYPE(BUS_ISA,SI3_T225)
 #define		TYPE_SX_PCI		CARD_TYPE(BUS_PCI,SI3_T225)
+/*****************************************************************************
+******************************                  ******************************
+******************************   Phase 1 Z280   ******************************
+******************************                  ******************************
+*****************************************************************************/
+
+/* ISA board details... */
+#define		SI1_ISA_WINDOW_LEN	0x10000		/* 64 Kbyte shared memory window */
+//#define 	SI1_ISA_MEMORY_LEN	0x8000		/* Usable memory  - unused define*/
+//#define		SI1_ISA_ADDR_LOW	0x0A0000	/* Lowest address = 640 Kbyte */
+//#define		SI1_ISA_ADDR_HIGH	0xFF8000	/* Highest address = 16Mbyte - 32Kbyte */
+//#define		SI2_ISA_ADDR_STEP	SI2_ISA_WINDOW_LEN/* ISA board address step */
+//#define		SI2_ISA_IRQ_MASK	0x9800		/* IRQs 15,12,11 */
+
+/* ISA board, register definitions... */
+//#define		SI2_ISA_ID_BASE		0x7FF8			/* READ:  Board ID string */
+#define		SI1_ISA_RESET		0x8000		/* WRITE: Host Reset */
+#define		SI1_ISA_RESET_CLEAR	0xc000		/* WRITE: Host Reset clear*/
+#define		SI1_ISA_WAIT	        0x9000		/* WRITE: Host wait */
+#define		SI1_ISA_WAIT_CLEAR	0xd000		/* WRITE: Host wait clear */
+#define		SI1_ISA_INTCL        	0xa000		/* WRITE: Host Reset */
+#define		SI1_ISA_INTCL_CLEAR	0xe000		/* WRITE: Host Reset */
+
 
 /*****************************************************************************
 ******************************                  ******************************
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/synclink.c linux/drivers/char/synclink.c
--- linux.orig/drivers/char/synclink.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/synclink.c	2002-07-20 01:08:32.000000000 +0000
@@ -1811,7 +1811,7 @@
 	/* Allocate and claim adapter resources */
 	retval = mgsl_claim_resources(info);
 	
-	/* perform existance check and diagnostics */
+	/* perform existence check and diagnostics */
 	if ( !retval )
 		retval = mgsl_adapter_test(info);
 		
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/sysrq.c linux/drivers/char/sysrq.c
--- linux.orig/drivers/char/sysrq.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/char/sysrq.c	2002-07-20 01:08:31.000000000 +0000
@@ -186,7 +186,7 @@
  * block devices and malfunctional network filesystems.
  */
 
-int emergency_sync_scheduled;
+volatile int emergency_sync_scheduled;
 
 void do_emergency_sync(void) {
 	struct super_block *sb;
@@ -284,24 +284,20 @@
 
 /* signal sysrq helper function
  * Sends a signal to all user processes */
-static void send_sig_all(int sig, int even_init)
+static void send_sig_all(int sig)
 {
 	struct task_struct *p;
 
 	for_each_task(p) {
-		if (p->mm) { /* Not swapper nor kernel thread */
-			if (p->pid == 1 && even_init)
-				/* Ugly hack to kill init */
-				p->pid = 0x8000;
-			if (p->pid != 1)
-				force_sig(sig, p);
-		}
+		if (p->mm && p->pid != 1)
+			/* Not swapper, init nor kernel thread */
+			force_sig(sig, p);
 	}
 }
 
 static void sysrq_handle_term(int key, struct pt_regs *pt_regs,
 		struct kbd_struct *kbd, struct tty_struct *tty) {
-	send_sig_all(SIGTERM, 0);
+	send_sig_all(SIGTERM);
 	console_loglevel = 8;
 }
 static struct sysrq_key_op sysrq_term_op = {
@@ -312,7 +308,7 @@
 
 static void sysrq_handle_kill(int key, struct pt_regs *pt_regs,
 		struct kbd_struct *kbd, struct tty_struct *tty) {
-	send_sig_all(SIGKILL, 0);
+	send_sig_all(SIGKILL);
 	console_loglevel = 8;
 }
 static struct sysrq_key_op sysrq_kill_op = {
@@ -321,17 +317,6 @@
 	action_msg:	"Kill All Tasks",
 };
 
-static void sysrq_handle_killall(int key, struct pt_regs *pt_regs,
-		struct kbd_struct *kbd, struct tty_struct *tty) {
-	send_sig_all(SIGKILL, 1);
-	console_loglevel = 8;
-}
-static struct sysrq_key_op sysrq_killall_op = {
-	handler:	sysrq_handle_killall,
-	help_msg:	"killalL",
-	action_msg:	"Kill All Tasks (even init)",
-};
-
 /* END SIGNAL SYSRQ HANDLERS BLOCK */
 
 
@@ -366,7 +351,7 @@
 #else
 /* k */	NULL,
 #endif
-/* l */	&sysrq_killall_op,
+/* l */	NULL,
 /* m */	&sysrq_showmem_op,
 /* n */	NULL,
 /* o */	NULL, /* This will often be registered
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c
--- linux.orig/drivers/char/tpqic02.c	2001-09-14 21:40:00.000000000 +0000
+++ linux/drivers/char/tpqic02.c	2002-07-20 01:08:36.000000000 +0000
@@ -1944,12 +1944,8 @@
 			}
 			/* copy buffer to user-space in one go */
 			if (bytes_done > 0) {
-				err =
-				    copy_to_user(buf, buffaddr,
-						 bytes_done);
-				if (err) {
+				if (copy_to_user(buf, buffaddr, bytes_done))
 					return -EFAULT;
-				}
 			}
 #if 1
 			/* Checks Ton's patch below */
@@ -2085,10 +2081,8 @@
 
 		/* copy from user to DMA buffer and initiate transfer. */
 		if (bytes_todo > 0) {
-			err = copy_from_user(buffaddr, buf, bytes_todo);
-			if (err) {
+			if (copy_from_user(buffaddr, buf, bytes_todo))
 				return -EFAULT;
-			}
 
 /****************** similar problem with read() at FM could happen here at EOT.
  ******************/
@@ -2750,7 +2744,9 @@
 	 * the config parameters have been set using MTSETCONFIG.
 	 */
 
-	if (check_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE)) {
+	/* Grab the IO region. */
+	if (!request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE,
+			   TPQIC02_NAME)) {
 		printk(TPQIC02_NAME
 		       ": IO space at 0x%x [%d ports] already reserved\n",
 		       QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
@@ -2764,6 +2760,7 @@
 		printk(TPQIC02_NAME
 		       ": can't allocate IRQ%d for QIC-02 tape\n",
 		       QIC02_TAPE_IRQ);
+		release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
 		return -EBUSY;
 	}
 
@@ -2773,13 +2770,10 @@
 		       ": can't allocate DMA%d for QIC-02 tape\n",
 		       QIC02_TAPE_DMA);
 		free_irq(QIC02_TAPE_IRQ, NULL);
+		release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
 		return -EBUSY;
 	}
 
-	/* Grab the IO region. We already made sure it's available. */
-	request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE,
-		       TPQIC02_NAME);
-
 	/* Setup the page-address for the dma transfer. */
 	buffaddr =
 	    (void *) __get_dma_pages(GFP_KERNEL, get_order(TPQBUF_SIZE));
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- linux.orig/drivers/char/tty_io.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/tty_io.c	2002-07-20 01:08:38.000000000 +0000
@@ -160,6 +160,8 @@
 extern void sci_console_init(void);
 extern void tx3912_console_init(void);
 extern void tx3912_rs_init(void);
+extern void txx927_console_init(void);
+extern void sb1250_serial_console_init(void);
 
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
@@ -601,12 +603,6 @@
 	read_unlock(&tasklist_lock);
 }
 
-void wait_for_keypress(void)
-{
-        struct console *c = console_drivers;
-        if (c) c->wait_key(c);
-}
-
 void stop_tty(struct tty_struct *tty)
 {
 	if (tty->stopped)
@@ -2249,6 +2245,12 @@
 #ifdef CONFIG_SERIAL_TX3912_CONSOLE
 	tx3912_console_init();
 #endif
+#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+	txx927_console_init();
+#endif
+#ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE
+	sb1250_serial_console_init();
+#endif
 }
 
 static struct tty_driver dev_tty_driver, dev_syscons_driver;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/vme_scc.c linux/drivers/char/vme_scc.c
--- linux.orig/drivers/char/vme_scc.c	2001-09-17 04:22:50.000000000 +0000
+++ linux/drivers/char/vme_scc.c	2002-07-20 01:08:22.000000000 +0000
@@ -131,7 +131,11 @@
 	memset(&scc_driver, 0, sizeof(scc_driver));
 	scc_driver.magic = TTY_DRIVER_MAGIC;
 	scc_driver.driver_name = "scc";
+#ifdef CONFIG_DEVFS_FS
+	scc_driver.name = "tts/%d";
+#else
 	scc_driver.name = "ttyS";
+#endif
 	scc_driver.major = TTY_MAJOR;
 	scc_driver.minor_start = SCC_MINOR_BASE;
 	scc_driver.num = 2;
@@ -164,7 +168,11 @@
 	scc_driver.break_ctl = scc_break_ctl;
 
 	scc_callout_driver = scc_driver;
+#ifdef CONFIG_DEVFS_FS
+	scc_callout_driver.name = "cua/%d";
+#else
 	scc_callout_driver.name = "cua";
+#endif
 	scc_callout_driver.major = TTYAUX_MAJOR;
 	scc_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
@@ -214,7 +222,7 @@
 {
 	struct scc_port *port;
 
-	printk("SCC: MVME147 Serial Driver\n");
+	printk(KERN_INFO "SCC: MVME147 Serial Driver\n");
 	/* Init channel A */
 	port = &scc_ports[0];
 	port->channel = CHANNEL_A;
@@ -284,7 +292,7 @@
 	if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA))
 		return (-ENODEV);
 
-	printk("SCC: MVME162 Serial Driver\n");
+	printk(KERN_INFO "SCC: MVME162 Serial Driver\n");
 	/* Init channel A */
 	port = &scc_ports[0];
 	port->channel = CHANNEL_A;
@@ -352,7 +360,7 @@
 {
 	struct scc_port *port;
 
-	printk("SCC: BVME6000 Serial Driver\n");
+	printk(KERN_INFO "SCC: BVME6000 Serial Driver\n");
 	/* Init channel A */
 	port = &scc_ports[0];
 	port->channel = CHANNEL_A;
@@ -449,7 +457,7 @@
 
 	ch = SCCread_NB(RX_DATA_REG);
 	if (!tty) {
-		printk ("scc_rx_int with NULL tty!\n");
+		printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 		return;
 	}
@@ -487,7 +495,7 @@
 	SCC_ACCESS_INIT(port);
 	
 	if (!tty) {
-		printk ("scc_spcond_int with NULL tty!\n");
+		printk(KERN_WARNING "scc_spcond_int with NULL tty!\n");
 		SCCwrite(COMMAND_REG, CR_ERROR_RESET);
 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 		return;
@@ -533,7 +541,7 @@
 	SCC_ACCESS_INIT(port);
 
 	if (!port->gs.tty) {
-		printk ("scc_tx_int with NULL tty!\n");
+		printk(KERN_WARNING "scc_tx_int with NULL tty!\n");
 		SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
 		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
@@ -719,7 +727,7 @@
 	else if ((MACH_IS_MVME16x && (baud < 50 || baud > 38400)) ||
 		 (MACH_IS_MVME147 && (baud < 50 || baud > 19200)) ||
 		 (MACH_IS_BVME6000 &&(baud < 50 || baud > 76800))) {
-		printk("SCC: Bad speed requested, %d\n", baud);
+		printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud);
 		return 0;
 	}
 
@@ -731,12 +739,10 @@
 #ifdef CONFIG_MVME147_SCC
 	if (MACH_IS_MVME147)
 		brgval = (M147_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2;
-	else
 #endif
 #ifdef CONFIG_MVME162_SCC
 	if (MACH_IS_MVME16x)
 		brgval = (MVME_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2;
-	else
 #endif
 #ifdef CONFIG_BVME6000_SCC
 	if (MACH_IS_BVME6000)
@@ -783,6 +789,15 @@
 }
 
 
+/* Comment taken from sx.c (2.4.0):
+   I haven't the foggiest why the decrement use count has to happen
+   here. The whole linux serial drivers stuff needs to be redesigned.
+   My guess is that this is a hack to minimize the impact of a bug
+   elsewhere. Thinking about it some more. (try it sometime) Try
+   running minicom on a serial port that is driven by a modularized
+   driver. Have the modem hangup. Then remove the driver module. Then
+   exit minicom.  I expect an "oops".  -- REW */
+
 static void scc_hungup(void *ptr)
 {
 	scc_disable_tx_interrupts(ptr);
@@ -795,6 +810,7 @@
 {
 	scc_disable_tx_interrupts(ptr);
 	scc_disable_rx_interrupts(ptr);
+	MOD_DEC_USE_COUNT;
 }
 
 
@@ -809,6 +825,7 @@
 	SCC_ACCESS_INIT(port);
 
 	save_flags(flags);
+	cli();
 	t = SCCread(TX_CTRL_REG);
 	if (dtr >= 0) t = dtr? (t | TCR_DTR): (t & ~TCR_DTR);
 	if (rts >= 0) t = rts? (t | TCR_RTS): (t & ~TCR_RTS);
@@ -933,7 +950,7 @@
 	if (port->gs.count == 1) {
 		MOD_INC_USE_COUNT;
 	}
-	retval = block_til_ready(port, filp);
+	retval = gs_block_til_ready(port, filp);
 
 	if (retval) {
 		MOD_DEC_USE_COUNT;
@@ -1065,41 +1082,6 @@
 	restore_flags(flags);
 }
 
-
-static int scc_console_wait_key(struct console *co)
-{
-	unsigned long	flags;
-	volatile char *p = NULL;
-	int c;
-	
-#ifdef CONFIG_MVME147_SCC
-	if (MACH_IS_MVME147)
-		p = (volatile char *)M147_SCC_A_ADDR;
-#endif
-#ifdef CONFIG_MVME162_SCC
-	if (MACH_IS_MVME16x)
-		p = (volatile char *)MVME_SCC_A_ADDR;
-#endif
-#ifdef CONFIG_BVME6000_SCC
-	if (MACH_IS_BVME6000)
-		p = (volatile char *)BVME_SCC_A_ADDR;
-#endif
-
-	save_flags(flags);
-	cli();
-
-	/* wait for rx buf filled */
-	while ((*p & 0x01) == 0)
-		;
-
-	*p = 8;
-	scc_delay();
-	c = *p;
-	restore_flags(flags);
-	return c;
-}
-
-
 static kdev_t scc_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, SCC_MINOR_BASE + c->index);
@@ -1116,7 +1098,6 @@
 	name:		"ttyS",
 	write:		scc_console_write,
 	device:		scc_console_device,
-	wait_key:	scc_console_wait_key,
 	setup:		scc_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/w83877f_wdt.c linux/drivers/char/w83877f_wdt.c
--- linux.orig/drivers/char/w83877f_wdt.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/char/w83877f_wdt.c	2002-07-20 01:08:24.000000000 +0000
@@ -13,9 +13,10 @@
  *	any of this software. This material is provided "AS-IS" in 
  *      the hope that it may be useful for others.
  *
- *	(c) Copyright 2001    Scott Jennings <management@oro.net>
+ *	(c) Copyright 2001    Scott Jennings <linuxdrivers@oro.net>
  *
  *           4/19 - 2001      [Initial revision]
+ *           9/27 - 2001      Added spinlocking
  *
  *
  *  Theory of operation:
@@ -88,8 +89,9 @@
 static void wdt_timer_ping(unsigned long);
 static struct timer_list timer;
 static unsigned long next_heartbeat;
-static int wdt_is_open;
+static unsigned long wdt_is_open;
 static int wdt_expect_close;
+static spinlock_t wdt_spinlock;
 
 /*
  *	Whack the dog
@@ -102,11 +104,18 @@
 	 */
 	if(time_before(jiffies, next_heartbeat)) 
 	{
+		/* Ping the WDT */
+		spin_lock(&wdt_spinlock);
+
 		/* Ping the WDT by reading from WDT_PING */
 		inb_p(WDT_PING);
+
 		/* Re-set the timer interval */
 		timer.expires = jiffies + WDT_INTERVAL;
 		add_timer(&timer);
+
+		spin_unlock(&wdt_spinlock);
+
 	} else {
 		printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n");
 	}
@@ -118,19 +127,24 @@
 
 static void wdt_change(int writeval)
 {
+	unsigned long flags;
+	spin_lock_irqsave(&wdt_spinlock, flags);
+
 	/* buy some time */
 	inb_p(WDT_PING);
 
 	/* make W83877F available */
-	outb_p(ENABLE_W83877F,ENABLE_W83877F_PORT);
-	outb_p(ENABLE_W83877F,ENABLE_W83877F_PORT);
+	outb_p(ENABLE_W83877F,  ENABLE_W83877F_PORT);
+	outb_p(ENABLE_W83877F,  ENABLE_W83877F_PORT);
 
 	/* enable watchdog */
-	outb_p(WDT_REGISTER,ENABLE_W83877F_PORT);
-	outb_p(writeval,ENABLE_W83877F_PORT+1);
+	outb_p(WDT_REGISTER,    ENABLE_W83877F_PORT);
+	outb_p(writeval,        ENABLE_W83877F_PORT+1);
 
 	/* lock the W8387FF away */
-	outb_p(DISABLE_W83877F,ENABLE_W83877F_PORT);
+	outb_p(DISABLE_W83877F, ENABLE_W83877F_PORT);
+
+	spin_unlock_irqrestore(&wdt_spinlock, flags);
 }
 
 static void wdt_startup(void)
@@ -178,7 +192,7 @@
 
 		/* now scan */
 		for(ofs = 0; ofs != count; ofs++)
-		  if(buf[ofs] == 'V')
+			if(buf[ofs] == 'V')
 				wdt_expect_close = 1;
 
 		/* someone wrote to us, we should restart timer */
@@ -200,10 +214,11 @@
 	{
 		case WATCHDOG_MINOR:
 			/* Just in case we're already talking to someone... */
-			if(wdt_is_open)
+			if(test_and_set_bit(0, &wdt_is_open)) {
+				spin_unlock(&wdt_spinlock);
 				return -EBUSY;
+			}
 			/* Good, fire up the show */
-			wdt_is_open = 1;
 			wdt_startup();
 			return 0;
 
@@ -214,7 +229,6 @@
 
 static int fop_close(struct inode * inode, struct file * file)
 {
-	lock_kernel();
 	if(MINOR(inode->i_rdev) == WATCHDOG_MINOR) 
 	{
 		if(wdt_expect_close)
@@ -224,13 +238,11 @@
 			printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
 		}
 	}
-	wdt_is_open = 0;
-	unlock_kernel();
+	clear_bit(0, &wdt_is_open);
 	return 0;
 }
 
-static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-	unsigned long arg)
+static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	static struct watchdog_info ident=
 	{
@@ -307,6 +319,8 @@
 {
 	int rc = -EBUSY;
 
+	spin_lock_init(&wdt_spinlock);
+
 	if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT"))
 		goto err_out;
 	if (!request_region(WDT_PING, 1, "W8387FF WDT"))
@@ -341,4 +355,7 @@
 module_init(w83877f_wdt_init);
 module_exit(w83877f_wdt_unload);
 
+MODULE_AUTHOR("Scott and Bill Jennings");
+MODULE_DESCRIPTION("Driver for watchdog timer in w83877f chip");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/wafer5823wdt.c linux/drivers/char/wafer5823wdt.c
--- linux.orig/drivers/char/wafer5823wdt.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/char/wafer5823wdt.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,220 @@
+/*
+ *	ICP Wafer 5823 Single Board Computer WDT driver for Linux 2.4.x
+ *      http://www.icpamerica.com/wafer_5823.php
+ *      May also work on other similar models
+ *
+ *	(c) Copyright 2002 Justin Cormack <justin@street-vision.com>
+ *
+ *      Release 0.02
+ *
+ *	Based on advantechwdt.c which is based on wdt.c.
+ *	Original copyright messages:
+ *
+ *	(c) Copyright 1996-1997 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *				http://www.redhat.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.
+ *	
+ *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
+ *	warranty for any of this software. This material is provided 
+ *	"AS-IS" and at no charge.	
+ *
+ *	(c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+static unsigned long wafwdt_is_open;
+static spinlock_t wafwdt_lock;
+
+/*
+ *	You must set these - there is no sane way to probe for this board.
+ *
+ *      To enable, write the timeout value in seconds (1 to 255) to I/O
+ *      port WDT_START, then read the port to start the watchdog. To pat
+ *      the dog, read port WDT_STOP to stop the timer, then read WDT_START
+ *      to restart it again.
+ */
+
+#define WDT_START 0x443
+#define WDT_STOP 0x843
+
+#define WD_TIMO 60		/* 1 minute */
+
+static void wafwdt_ping(void)
+{
+	/* pat watchdog */
+        spin_lock(&wafwdt_lock);
+	inb_p(WDT_STOP);
+	inb_p(WDT_START);
+        spin_unlock(&wafwdt_lock);
+}
+
+static void wafwdt_start(void)
+{
+	/* start up watchdog */
+	outb_p(WD_TIMO, WDT_START);
+	inb_p(WDT_START);
+}
+
+static void
+wafwdt_stop(void)
+{
+	/* stop watchdog */
+	inb_p(WDT_STOP);
+}
+
+static ssize_t wafwdt_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if (count) {
+		wafwdt_ping();
+		return 1;
+	}
+	return 0;
+}
+
+static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	     unsigned long arg)
+{
+	static struct watchdog_info ident = {
+		WDIOF_KEEPALIVEPING, 1, "Wafer 5823 WDT"
+	};
+	int one=1;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		if (copy_to_user
+		    ((struct watchdog_info *) arg, &ident, sizeof (ident)))
+			return -EFAULT;
+		break;
+
+	case WDIOC_GETSTATUS:
+		if (copy_to_user((int *) arg, &one, sizeof (int)))
+			return -EFAULT;
+		break;
+
+	case WDIOC_KEEPALIVE:
+		wafwdt_ping();
+		break;
+
+	default:
+		return -ENOTTY;
+	}
+	return 0;
+}
+
+static int wafwdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(0, &wafwdt_is_open))
+		return -EBUSY;
+	wafwdt_start();
+	return 0;
+}
+
+static int
+wafwdt_close(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &wafwdt_is_open);
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+        wafwdt_stop();
+#endif
+	return 0;
+}
+
+/*
+ *	Notifier for system down
+ */
+
+static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT) {
+		/* Turn the WDT off */
+		wafwdt_stop();
+	}
+	return NOTIFY_DONE;
+}
+
+/*
+ *	Kernel Interfaces
+ */
+
+static struct file_operations wafwdt_fops = {
+	owner:THIS_MODULE,
+	write:wafwdt_write,
+	ioctl:wafwdt_ioctl,
+	open:wafwdt_open,
+	release:wafwdt_close,
+};
+
+static struct miscdevice wafwdt_miscdev = {
+	WATCHDOG_MINOR,
+	"watchdog",
+	&wafwdt_fops
+};
+
+/*
+ *	The WDT needs to learn about soft shutdowns in order to
+ *	turn the timebomb registers off. 
+ */
+
+static struct notifier_block wafwdt_notifier = {
+	wafwdt_notify_sys,
+	NULL,
+	0
+};
+
+static int __init wafwdt_init(void)
+{
+	printk(KERN_INFO "WDT driver for Wafer 5823 single board computer initialising.\n");
+
+	spin_lock_init(&wafwdt_lock);
+	if(!request_region(WDT_STOP, 1, "Wafer 5823 WDT"))
+		goto error;
+	if(!request_region(WDT_START, 1, "Wafer 5823 WDT"))
+		goto error2;
+	if(misc_register(&wafwdt_miscdev)<0)
+		goto error3;
+	register_reboot_notifier(&wafwdt_notifier);
+	return 0;
+error3:
+	release_region(WDT_START, 1);
+error2:
+	release_region(WDT_STOP, 1);
+error:
+	return -ENODEV;
+}
+
+static void __exit wafwdt_exit(void)
+{
+	misc_deregister(&wafwdt_miscdev);
+	unregister_reboot_notifier(&wafwdt_notifier);
+	release_region(WDT_STOP, 1);
+	release_region(WDT_START, 1);
+}
+
+module_init(wafwdt_init);
+module_exit(wafwdt_exit);
+
+MODULE_AUTHOR("Justin Cormack");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
+
+/* end of wafer5823wdt.c */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/wdt.c linux/drivers/char/wdt.c
--- linux.orig/drivers/char/wdt.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/wdt.c	2002-07-20 01:08:37.000000000 +0000
@@ -51,7 +51,7 @@
 #include <linux/reboot.h>
 #include <linux/init.h>
 
-static int wdt_is_open;
+static unsigned long wdt_is_open;
 
 /*
  *	You must set these - there is no sane way to probe for this board.
@@ -355,7 +355,7 @@
 	switch(MINOR(inode->i_rdev))
 	{
 		case WATCHDOG_MINOR:
-			if(wdt_is_open)
+			if(test_and_set_bit(0, &wdt_is_open))
 				return -EBUSY;
 			/*
 			 *	Activate 
@@ -392,16 +392,14 @@
  
 static int wdt_release(struct inode *inode, struct file *file)
 {
-	lock_kernel();
 	if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
 	{
 #ifndef CONFIG_WATCHDOG_NOWAYOUT	
 		inb_p(WDT_DC);		/* Disable counters */
 		wdt_ctr_load(2,0);	/* 0 length reset pulses now */
 #endif		
-		wdt_is_open=0;
+		clear_bit(0, &wdt_is_open);
 	}
-	unlock_kernel();
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/wdt285.c linux/drivers/char/wdt285.c
--- linux.orig/drivers/char/wdt285.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/wdt285.c	2002-07-20 01:08:28.000000000 +0000
@@ -138,11 +138,9 @@
 		default:
 			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
-			i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info));
-			if (i)
-				return i;
-			else
-				return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
+			if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+				return -EFAULT;
+			return 0;
 		case WDIOC_GETSTATUS:
 		case WDIOC_GETBOOTSTATUS:
 			return put_user(0,(int *)arg);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/char/wdt_pci.c linux/drivers/char/wdt_pci.c
--- linux.orig/drivers/char/wdt_pci.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/char/wdt_pci.c	2002-07-20 01:08:38.000000000 +0000
@@ -31,6 +31,7 @@
  *		Jeff Garzik	:	PCI cleanups
  *		Tigran Aivazian	:	Restructured wdtpci_init_one() to handle failures
  *		Joel Becker	:	Added WDIOC_GET/SETTIMEOUT
+ *		Zwane Mwaikambo :	Magic char closing, locking changes, cleanups
  */
 
 #include <linux/config.h>
@@ -53,7 +54,8 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <asm/semaphore.h>
 
 #include <linux/pci.h>
 
@@ -72,52 +74,19 @@
 #define PCI_DEVICE_ID_WDG_CSM 0x22c0
 #endif
 
-static int wdt_is_open;
+static struct semaphore open_sem;
+static spinlock_t wdtpci_lock;
+static int expect_close = 0;
 
-/*
- *	You must set these - there is no sane way to probe for this board.
- *	You can use wdt=x,y to set these now.
- */
- 
-static int io=0x240;
-static int irq=11;
+static int io;
+static int irq;
 
 /* Default timeout */
 #define WD_TIMO (100*60)		/* 1 minute */
+#define WD_TIMO_MAX (WD_TIMO*60)	/* 1 hour(?) */
 
 static int wd_margin = WD_TIMO;
 
-#ifndef MODULE
-
-/**
- *	wdtpci_setup:
- *	@str: command line string
- *
- *	Setup options. The board isn't really probe-able so we have to
- *	get the user to tell us the configuration. Sane people build it 
- *	modular but the others come here.
- */
- 
-static int __init wdtpci_setup(char *str)
-{
-	int ints[4];
-
-	str = get_options (str, ARRAY_SIZE(ints), ints);
-
-	if (ints[0] > 0)
-	{
-		io = ints[1];
-		if(ints[0] > 1)
-			irq = ints[2];
-	}
-
-	return 1;
-}
-
-__setup("wdt=", wdtpci_setup);
-
-#endif /* !MODULE */
- 
 /*
  *	Programming support
  */
@@ -233,11 +202,15 @@
  
 static void wdtpci_ping(void)
 {
+	unsigned long flags;
+
 	/* Write a watchdog value */
+	spin_lock_irqsave(&wdtpci_lock, flags);
 	inb_p(WDT_DC);
 	wdtpci_ctr_mode(1,2);
 	wdtpci_ctr_load(1,wd_margin);		/* Timeout */
 	outb_p(0, WDT_DC);
+	spin_unlock_irqrestore(&wdtpci_lock, flags);
 }
 
 /**
@@ -257,12 +230,21 @@
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
 
-	if(count)
-	{
+	if (count) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+		size_t i;
+
+		expect_close = 0;
+
+		for (i = 0; i != count; i++) {
+			if (buf[i] == 'V')
+				expect_close = 1;
+		}
+#endif
 		wdtpci_ping();
-		return 1;
 	}
-	return 0;
+
+	return count;
 }
 
 /**
@@ -343,13 +325,14 @@
 			if (get_user(new_margin, (int *)arg))
 				return -EFAULT;
 			/* Arbitrary, can't find the card's limits */
-			if ((new_margin < 0) || (new_margin > 60))
+			new_margin *= 100;
+			if ((new_margin < 0) || (new_margin > WD_TIMO_MAX))
 				return -EINVAL;
-			wd_margin = new_margin * 100;
+			wd_margin = new_margin;
 			wdtpci_ping();
 			/* Fall */
 		case WDIOC_GETTIMEOUT:
-			return put_user(wd_margin, (int *)arg);
+			return put_user(wd_margin / 100, (int *)arg);
 	}
 }
 
@@ -367,20 +350,22 @@
  
 static int wdtpci_open(struct inode *inode, struct file *file)
 {
+	unsigned long flags;
+
 	switch(MINOR(inode->i_rdev))
 	{
 		case WATCHDOG_MINOR:
-			if(wdt_is_open)
-				return -EBUSY;
+			 if (down_trylock(&open_sem))
+                        	return -EBUSY;
+
 #ifdef CONFIG_WATCHDOG_NOWAYOUT	
 			MOD_INC_USE_COUNT;
 #endif
 			/*
 			 *	Activate 
 			 */
-	 
-			wdt_is_open=1;
-
+			spin_lock_irqsave(&wdtpci_lock, flags);
+			
 			inb_p(WDT_DC);		/* Disable */
 
 			/*
@@ -405,6 +390,7 @@
 			wdtpci_ctr_load(1,wd_margin);/* Timeout 60 seconds */
 			/* DO NOT LOAD CTR2 on PCI card! -- JPN */
 			outb_p(0, WDT_DC);	/* Enable */
+			spin_unlock_irqrestore(&wdtpci_lock, flags);
 			return 0;
 		case TEMP_MINOR:
 			return 0;
@@ -427,15 +413,21 @@
  
 static int wdtpci_release(struct inode *inode, struct file *file)
 {
-	if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
-	{
-		lock_kernel();
-#ifndef CONFIG_WATCHDOG_NOWAYOUT	
-		inb_p(WDT_DC);		/* Disable counters */
-		wdtpci_ctr_load(2,0);	/* 0 length reset pulses now */
+
+	if (MINOR(inode->i_rdev)==WATCHDOG_MINOR) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+		unsigned long flags;
+		if (expect_close) {
+			spin_lock_irqsave(&wdtpci_lock, flags);
+			inb_p(WDT_DC);		/* Disable counters */
+			wdtpci_ctr_load(2,0);	/* 0 length reset pulses now */
+			spin_unlock_irqrestore(&wdtpci_lock, flags);
+		} else {
+			printk(KERN_CRIT PFX "Unexpected close, not stopping timer!");
+			wdtpci_ping();
+		}
 #endif		
-		wdt_is_open=0;
-		unlock_kernel();
+		up(&open_sem);
 	}
 	return 0;
 }
@@ -455,11 +447,14 @@
 static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
 	void *unused)
 {
-	if(code==SYS_DOWN || code==SYS_HALT)
-	{
+	unsigned long flags;
+
+	if (code==SYS_DOWN || code==SYS_HALT) {
 		/* Turn the card off */
+		spin_lock_irqsave(&wdtpci_lock, flags);
 		inb_p(WDT_DC);
 		wdtpci_ctr_load(2,0);
+		spin_unlock_irqrestore(&wdtpci_lock, flags);
 	}
 	return NOTIFY_DONE;
 }
@@ -520,6 +515,9 @@
 			"this driver only supports 1 device\n");
 		return -ENODEV;
 	}
+	
+	sema_init(&open_sem, 1);
+	spin_lock_init(&wdtpci_lock);
 
 	irq = dev->irq;
 	io = pci_resource_start (dev, 2);
@@ -577,7 +575,7 @@
 }
 
 
-static void __exit wdtpci_remove_one (struct pci_dev *pdev)
+static void __devexit wdtpci_remove_one (struct pci_dev *pdev)
 {
 	/* here we assume only one device will ever have
 	 * been picked up and registered by probe function */
@@ -602,7 +600,7 @@
 	name:		"wdt-pci",
 	id_table:	wdtpci_pci_tbl,
 	probe:		wdtpci_init_one,
-	remove:		wdtpci_remove_one,
+	remove:		__devexit_p(wdtpci_remove_one),
 };
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/fc4/soc.c linux/drivers/fc4/soc.c
--- linux.orig/drivers/fc4/soc.c	2001-10-11 16:14:32.000000000 +0000
+++ linux/drivers/fc4/soc.c	2002-07-20 01:08:25.000000000 +0000
@@ -741,7 +741,6 @@
 	
 	for_each_soc(s) {
 		irq = s->port[0].fc.irq;
-		disable_irq (irq);
 		free_irq (irq, s);
 
 		fcp_release(&(s->port[0].fc), 2);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/fc4/socal.c linux/drivers/fc4/socal.c
--- linux.orig/drivers/fc4/socal.c	2001-10-11 16:14:32.000000000 +0000
+++ linux/drivers/fc4/socal.c	2002-07-20 01:08:34.000000000 +0000
@@ -880,7 +880,6 @@
 	
 	for_each_socal(s) {
 		irq = s->port[0].fc.irq;
-		disable_irq (irq);
 		free_irq (irq, s);
 
 		fcp_release(&(s->port[0].fc), 2);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/Config.in linux/drivers/hotplug/Config.in
--- linux.orig/drivers/hotplug/Config.in	2001-11-09 22:01:21.000000000 +0000
+++ linux/drivers/hotplug/Config.in	2002-07-20 01:08:27.000000000 +0000
@@ -4,9 +4,13 @@
 mainmenu_option next_comment
 comment 'PCI Hotplug Support'
 
-dep_tristate 'Support for PCI Hotplug (EXPERIMENTAL)' CONFIG_HOTPLUG_PCI $CONFIG_DDFS $CONFIG_EXPERIMENTAL
+dep_tristate 'Support for PCI Hotplug (EXPERIMENTAL)' CONFIG_HOTPLUG_PCI $CONFIG_EXPERIMENTAL $CONFIG_PCI
 
-dep_tristate '  Compaq PCI Hotplug driver' CONFIG_HOTPLUG_PCI_COMPAQ $CONFIG_HOTPLUG_PCI
+dep_tristate '  Compaq PCI Hotplug driver' CONFIG_HOTPLUG_PCI_COMPAQ $CONFIG_HOTPLUG_PCI $CONFIG_X86
 dep_mbool '    Save configuration into NVRAM on Compaq servers' CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM $CONFIG_HOTPLUG_PCI_COMPAQ
+if [ "$CONFIG_X86_IO_APIC" = "y" ]; then
+   dep_tristate '  IBM PCI Hotplug driver' CONFIG_HOTPLUG_PCI_IBM $CONFIG_HOTPLUG_PCI $CONFIG_X86_IO_APIC $CONFIG_X86
+fi
+dep_tristate '  ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_ACPI $CONFIG_HOTPLUG_PCI
 
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/Makefile linux/drivers/hotplug/Makefile
--- linux.orig/drivers/hotplug/Makefile	2001-11-09 22:01:21.000000000 +0000
+++ linux/drivers/hotplug/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -4,12 +4,14 @@
 
 O_TARGET	:= vmlinux-obj.o
 
-list-multi	:= cpqphp.o pci_hotplug.o
+list-multi	:= cpqphp.o pci_hotplug.o ibmphp.o pcihpacpi.o 
 
 export-objs	:= pci_hotplug_core.o pci_hotplug_util.o
 
 obj-$(CONFIG_HOTPLUG_PCI)		+= pci_hotplug.o
 obj-$(CONFIG_HOTPLUG_PCI_COMPAQ)	+= cpqphp.o
+obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
+obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= pcihpacpi.o
 
 pci_hotplug-objs	:=	pci_hotplug_core.o	\
 				pci_hotplug_util.o
@@ -19,6 +21,22 @@
 				cpqphp_proc.o	\
 				cpqphp_pci.o
 
+ibmphp-objs		:=	ibmphp_core.o	\
+				ibmphp_ebda.o	\
+				ibmphp_pci.o	\
+				ibmphp_res.o	\
+				ibmphp_hpc.o
+
+ifdef CONFIG_HOTPLUG_PCI_ACPI
+  EXTRA_CFLAGS	+= -D_LINUX -I$(CURDIR)/../acpi
+  ifdef CONFIG_ACPI_DEBUG
+    EXTRA_CFLAGS += -DACPI_DEBUG -Wno-unused
+  endif
+endif
+
+pcihp_acpi_objs		:=	pcihp_acpi.o	\
+				pcihp_acpi_glue.o
+
 ifeq ($(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM),y)
 	cpqphp-objs += cpqphp_nvram.o
 endif
@@ -32,3 +50,8 @@
 cpqphp.o: $(cpqphp-objs)
 	$(LD) -r -o $@ $(cpqphp-objs)
 
+ibmphp.o: $(ibmphp-objs)
+	$(LD) -r -o $@ $(ibmphp-objs)
+
+pcihpacpi.o: $(pcihp_acpi_objs)
+	$(LD) -r -o $@ $(pcihp_acpi_objs)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/cpqphp_ctrl.c linux/drivers/hotplug/cpqphp_ctrl.c
--- linux.orig/drivers/hotplug/cpqphp_ctrl.c	2001-11-09 22:01:22.000000000 +0000
+++ linux/drivers/hotplug/cpqphp_ctrl.c	2002-07-20 01:08:32.000000000 +0000
@@ -1707,6 +1707,7 @@
 	struct controller *ctrl;
 	lock_kernel();
 	daemonize();
+	reparent_to_init();
 	
 	//  New name
 	strcpy(current->comm, "phpd_event");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/cpqphp_proc.c linux/drivers/hotplug/cpqphp_proc.c
--- linux.orig/drivers/hotplug/cpqphp_proc.c	2001-11-09 22:01:22.000000000 +0000
+++ linux/drivers/hotplug/cpqphp_proc.c	2002-07-20 01:08:40.000000000 +0000
@@ -177,7 +177,7 @@
 	
 int cpqhp_proc_init_ctrl (void)
 {
-	ctrl_proc_root = proc_mkdir("driver/hpc", NULL);
+	ctrl_proc_root = proc_mkdir("hpc", proc_root_driver);
 	if (!ctrl_proc_root)
 		return -ENOMEM;
 	ctrl_proc_root->owner = THIS_MODULE;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/ibmphp.h linux/drivers/hotplug/ibmphp.h
--- linux.orig/drivers/hotplug/ibmphp.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/ibmphp.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,745 @@
+#ifndef __IBMPHP_H
+#define __IBMPHP_H
+
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include "pci_hotplug.h"
+
+extern int ibmphp_debug;
+
+#if !defined(CONFIG_HOTPLUG_PCI_IBM_MODULE)
+	#define MY_NAME "ibmphpd"
+#else
+	#define MY_NAME THIS_MODULE->name
+#endif
+#define debug(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+
+
+/* EBDA stuff */
+
+/***********************************************************
+* SLOT CAPABILITY                                          *
+***********************************************************/
+
+#define EBDA_SLOT_133_MAX		0x20
+#define EBDA_SLOT_100_MAX		0x10
+#define EBDA_SLOT_66_MAX		0x02
+#define EBDA_SLOT_PCIX_CAP		0x08
+
+
+/************************************************************
+*  RESOURE TYPE                                             *
+************************************************************/
+
+#define EBDA_RSRC_TYPE_MASK		0x03
+#define EBDA_IO_RSRC_TYPE		0x00
+#define EBDA_MEM_RSRC_TYPE		0x01
+#define EBDA_PFM_RSRC_TYPE		0x03
+#define EBDA_RES_RSRC_TYPE		0x02
+
+
+/*************************************************************
+*  IO RESTRICTION TYPE                                       *
+*************************************************************/
+
+#define EBDA_IO_RESTRI_MASK		0x0c
+#define EBDA_NO_RESTRI			0x00
+#define EBDA_AVO_VGA_ADDR		0x04
+#define EBDA_AVO_VGA_ADDR_AND_ALIA	0x08
+#define EBDA_AVO_ISA_ADDR		0x0c
+
+
+/**************************************************************
+*  DEVICE TYPE DEF                                            *
+**************************************************************/
+
+#define EBDA_DEV_TYPE_MASK		0x10
+#define EBDA_PCI_DEV			0x10
+#define EBDA_NON_PCI_DEV		0x00
+
+
+/***************************************************************
+*  PRIMARY DEF DEFINITION                                      *
+***************************************************************/
+
+#define EBDA_PRI_DEF_MASK		0x20
+#define EBDA_PRI_PCI_BUS_INFO		0x20
+#define EBDA_NORM_DEV_RSRC_INFO		0x00
+
+
+//--------------------------------------------------------------
+// RIO TABLE DATA STRUCTURE
+//--------------------------------------------------------------
+
+struct rio_table_hdr {
+	u8 ver_num; 
+	u8 scal_count;
+	u8 riodev_count;
+	u16 offset;
+};
+
+//-------------------------------------------------------------
+// SCALABILITY DETAIL
+//-------------------------------------------------------------
+
+struct scal_detail {
+	u8 node_id;
+	u32 cbar;
+	u8 port0_node_connect;
+	u8 port0_port_connect;
+	u8 port1_node_connect;
+	u8 port1_port_connect;
+	u8 port2_node_connect;
+	u8 port2_port_connect;
+//	struct list_head scal_detail_list;
+};
+
+//--------------------------------------------------------------
+// RIO DETAIL 
+//--------------------------------------------------------------
+
+struct rio_detail {
+	u8 rio_node_id;
+	u32 bbar;
+	u8 rio_type;
+	u8 owner_id;
+	u8 port0_node_connect;
+	u8 port0_port_connect;
+	u8 port1_node_connect;
+	u8 port1_port_connect;
+	u8 first_slot_num;
+	u8 status;
+//	struct list_head rio_detail_list;
+};
+
+
+/****************************************************************
+*  HPC DESCRIPTOR NODE                                          *
+****************************************************************/
+
+struct ebda_hpc_list {
+	u8 format;
+	u16 num_ctlrs;
+	short phys_addr;
+//      struct list_head ebda_hpc_list;
+};
+
+/*****************************************************************
+*   IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS           *
+*   STRUCTURE                                                    *
+*****************************************************************/
+
+struct ebda_hpc_slot {
+	u8 slot_num;
+	u32 slot_bus_num;
+	u8 ctl_index;
+	u8 slot_cap;
+};
+
+struct ebda_hpc_bus {
+	u32 bus_num;
+/*
+	u8 slots_at_33_conv;
+	u8 slots_at_66_conv;
+	u8 slots_at_66_pcix;
+	u8 slots_at_100_pcix;
+	u8 slots_at_133_pcix;
+*/
+};
+
+
+/********************************************************************
+*   THREE TYPE OF HOT PLUG CONTROLER                                *
+********************************************************************/
+
+struct isa_ctlr_access {
+	u16 io_start;
+	u16 io_end;
+};
+
+struct pci_ctlr_access {
+	u8 bus;
+	u8 dev_fun;
+};
+
+struct wpeg_i2c_ctlr_access {
+	ulong wpegbbar;
+	u8 i2c_addr;
+};
+
+/*************************************************************************
+*   RSTC DESCRIPTOR NODE                                                 *
+*************************************************************************/
+
+struct ebda_rsrc_list {
+	u8 format;
+	u16 num_entries;
+	u16 phys_addr;
+	struct ebda_rsrc_list *next;
+};
+
+
+/***************************************************************************
+*   PCI RSRC NODE                                                          *
+***************************************************************************/
+
+struct ebda_pci_rsrc {
+	u8 rsrc_type;
+	u8 bus_num;
+	u8 dev_fun;
+	ulong start_addr;
+	ulong end_addr;
+	struct list_head ebda_pci_rsrc_list;
+};
+
+
+/***********************************************************
+* BUS_INFO DATE STRUCTURE                                  *
+***********************************************************/
+
+struct bus_info {
+	u8 slot_min;
+	u8 slot_max;
+	u8 slot_count;
+	u8 busno;
+	u8 current_speed;
+	u8 supported_speed;
+	u8 controller_id;
+	u8 supported_bus_mode;
+	u8 current_bus_mode;
+	u8 index;
+	struct list_head bus_info_list;
+};
+
+
+/***********************************************************
+* GLOBAL VARIABLES                                         *
+***********************************************************/
+extern struct list_head ibmphp_ebda_pci_rsrc_head;
+extern struct list_head ibmphp_slot_head;
+
+/***********************************************************
+* FUNCTION PROTOTYPES                                      *
+***********************************************************/
+
+extern void ibmphp_free_ebda_hpc_queue (void);
+extern int ibmphp_access_ebda (void);
+extern struct slot *ibmphp_get_slot_from_physical_num (u8);
+extern int ibmphp_get_total_hp_slots (void);
+extern void ibmphp_free_ibm_slot (struct slot *);
+extern void ibmphp_free_bus_info_queue (void);
+extern void ibmphp_free_ebda_pci_rsrc_queue (void);
+extern struct bus_info *ibmphp_find_same_bus_num (u32);
+extern int ibmphp_get_bus_index (u8);
+extern u16 ibmphp_get_total_controllers (void);
+
+/* passed parameters */
+#define MEM		0
+#define IO		1
+#define PFMEM		2
+
+/* bit masks */
+#define RESTYPE		0x03
+#define IOMASK		0x00	/* will need to take its complement */
+#define MMASK		0x01
+#define PFMASK		0x03
+#define PCIDEVMASK	0x10	/* we should always have PCI devices */
+#define PRIMARYBUSMASK	0x20
+
+/* pci specific defines */
+#define PCI_VENDOR_ID_NOTVALID		0xFFFF
+#define PCI_HEADER_TYPE_MULTIDEVICE	0x80
+#define PCI_HEADER_TYPE_MULTIBRIDGE	0x81
+
+#define LATENCY		0x64
+#define CACHE		64
+#define DEVICEENABLE	0x015F		/* CPQ has 0x0157 */
+
+#define IOBRIDGE	0x1000		/* 4k */
+#define MEMBRIDGE	0x100000	/* 1M */
+
+/* irqs */
+#define SCSI_IRQ	0x09
+#define LAN_IRQ		0x0A
+#define OTHER_IRQ	0x0B
+
+/* Data Structures */
+
+/* type is of the form x x xx xx
+ *                     | |  |  |_ 00 - I/O, 01 - Memory, 11 - PFMemory
+ *                     | |  - 00 - No Restrictions, 01 - Avoid VGA, 10 - Avoid
+ *                     | |    VGA and their aliases, 11 - Avoid ISA
+ *                     | - 1 - PCI device, 0 - non pci device
+ *                     - 1 - Primary PCI Bus Information (0 if Normal device)
+ * the IO restrictions [2:3] are only for primary buses
+ */
+
+
+/* we need this struct because there could be several resource blocks
+ * allocated per primary bus in the EBDA
+ */
+struct range_node {
+	int rangeno;
+	u32 start;
+	u32 end;
+	struct range_node *next;
+};
+
+struct bus_node {
+	u8 busno;
+	int noIORanges;
+	struct range_node *rangeIO;
+	int noMemRanges;
+	struct range_node *rangeMem;
+	int noPFMemRanges;
+	struct range_node *rangePFMem;
+	int needIOUpdate;
+	int needMemUpdate;
+	int needPFMemUpdate;
+	struct resource_node *firstIO;	/* first IO resource on the Bus */
+	struct resource_node *firstMem;	/* first memory resource on the Bus */
+	struct resource_node *firstPFMem;	/* first prefetchable memory resource on the Bus */
+	struct resource_node *firstPFMemFromMem;	/* when run out of pfmem available, taking from Mem */
+	struct list_head bus_list;
+};
+
+struct resource_node {
+	int rangeno;
+	u8 busno;
+	u8 devfunc;
+	u32 start;
+	u32 end;
+	u32 len;
+	int type;		/* MEM, IO, PFMEM */
+	u8 fromMem;		/* this is to indicate that the range is from
+				 * from the Memory bucket rather than from PFMem */
+	struct resource_node *next;
+	struct resource_node *nextRange;	/* for the other mem range on bus */
+};
+
+struct res_needed {
+	u32 mem;
+	u32 pfmem;
+	u32 io;
+	u8 not_correct;		/* needed for return */
+	int devices[32];	/* for device numbers behind this bridge */
+};
+
+/* functions */
+
+extern int ibmphp_rsrc_init (void);
+extern int ibmphp_add_resource (struct resource_node *);
+extern int ibmphp_remove_resource (struct resource_node *);
+extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int);
+extern int ibmphp_check_resource (struct resource_node *, u8);
+extern int ibmphp_remove_bus (struct bus_node *, u8);
+extern void ibmphp_free_resources (void);
+extern int ibmphp_add_pfmem_from_mem (struct resource_node *);
+extern struct bus_node *ibmphp_find_res_bus (u8);
+extern void ibmphp_print_test (void);	/* for debugging purposes */
+
+extern void ibmphp_hpc_initvars (void);
+extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *);
+extern int ibmphp_hpc_writeslot (struct slot *, u8);
+extern void ibmphp_lock_operations (void);
+extern void ibmphp_unlock_operations (void);
+extern int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *);
+extern int ibmphp_hpc_start_poll_thread (void);
+extern void ibmphp_hpc_stop_poll_thread (void);
+
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+// HPC return codes
+//----------------------------------------------------------------------------
+#define FALSE				0x00
+#define TRUE				0x01
+#define HPC_ERROR			0xFF
+
+//-----------------------------------------------------------------------------
+// BUS INFO
+//-----------------------------------------------------------------------------
+#define BUS_SPEED			0x30
+#define BUS_MODE			0x40
+#define BUS_MODE_PCIX			0x01
+#define BUS_MODE_PCI			0x00
+#define BUS_SPEED_2			0x20
+#define BUS_SPEED_1			0x10
+#define BUS_SPEED_33			0x00
+#define BUS_SPEED_66			0x01
+#define BUS_SPEED_100			0x02
+#define BUS_SPEED_133			0x03
+#define BUS_SPEED_66PCIX		0x04
+#define BUS_SPEED_66UNKNOWN		0x05
+#define BUS_STATUS_AVAILABLE		0x01
+#define BUS_CONTROL_AVAILABLE		0x02
+#define SLOT_LATCH_REGS_SUPPORTED	0x10
+
+#define PRGM_MODEL_REV_LEVEL		0xF0
+#define MAX_ADAPTER_NONE		0x09
+
+//----------------------------------------------------------------------------
+// HPC 'write' operations/commands
+//----------------------------------------------------------------------------
+//	Command			Code	State	Write to reg
+//					Machine	at index
+//-------------------------	----	-------	------------
+#define HPC_CTLR_ENABLEIRQ	0x00	// N	15
+#define HPC_CTLR_DISABLEIRQ	0x01	// N	15
+#define HPC_SLOT_OFF		0x02	// Y	0-14
+#define HPC_SLOT_ON		0x03	// Y	0-14
+#define HPC_SLOT_ATTNOFF	0x04	// N	0-14
+#define HPC_SLOT_ATTNON		0x05	// N	0-14
+#define HPC_CTLR_CLEARIRQ	0x06	// N	15
+#define HPC_CTLR_RESET		0x07	// Y	15
+#define HPC_CTLR_IRQSTEER	0x08	// N	15
+#define HPC_BUS_33CONVMODE	0x09	// Y	31-34
+#define HPC_BUS_66CONVMODE	0x0A	// Y	31-34
+#define HPC_BUS_66PCIXMODE	0x0B	// Y	31-34
+#define HPC_BUS_100PCIXMODE	0x0C	// Y	31-34
+#define HPC_BUS_133PCIXMODE	0x0D	// Y	31-34
+#define HPC_ALLSLOT_OFF		0x11	// Y	15
+#define HPC_ALLSLOT_ON		0x12	// Y	15
+#define HPC_SLOT_BLINKLED	0x13	// N	0-14
+
+//----------------------------------------------------------------------------
+// read commands
+//----------------------------------------------------------------------------
+#define READ_SLOTSTATUS		0x01
+#define READ_EXTSLOTSTATUS	0x02
+#define READ_BUSSTATUS		0x03
+#define READ_CTLRSTATUS		0x04
+#define READ_ALLSTAT		0x05
+#define READ_ALLSLOT		0x06
+#define READ_SLOTLATCHLOWREG	0x07
+#define READ_REVLEVEL		0x08
+#define READ_HPCOPTIONS		0x09
+//----------------------------------------------------------------------------
+// slot status
+//----------------------------------------------------------------------------
+#define HPC_SLOT_POWER		0x01
+#define HPC_SLOT_CONNECT	0x02
+#define HPC_SLOT_ATTN		0x04
+#define HPC_SLOT_PRSNT2		0x08
+#define HPC_SLOT_PRSNT1		0x10
+#define HPC_SLOT_PWRGD		0x20
+#define HPC_SLOT_BUS_SPEED	0x40
+#define HPC_SLOT_LATCH		0x80
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_POWER status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_POWER_OFF	0x00
+#define HPC_SLOT_POWER_ON	0x01
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_CONNECT status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_CONNECTED	0x00
+#define HPC_SLOT_DISCONNECTED	0x01
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_ATTN status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_ATTN_OFF	0x00
+#define HPC_SLOT_ATTN_ON	0x01
+#define HPC_SLOT_ATTN_BLINK	0x02
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_PRSNT status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_EMPTY		0x00
+#define HPC_SLOT_PRSNT_7	0x01
+#define HPC_SLOT_PRSNT_15	0x02
+#define HPC_SLOT_PRSNT_25	0x03
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_PWRGD status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_PWRGD_FAULT_NONE	0x00
+#define HPC_SLOT_PWRGD_GOOD		0x01
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_BUS_SPEED status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_BUS_SPEED_OK	0x00
+#define HPC_SLOT_BUS_SPEED_MISM	0x01
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_LATCH status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_LATCH_OPEN	0x01	// NOTE : in PCI spec bit off = open
+#define HPC_SLOT_LATCH_CLOSED	0x00	// NOTE : in PCI spec bit on  = closed
+
+
+//----------------------------------------------------------------------------
+// extended slot status
+//----------------------------------------------------------------------------
+#define HPC_SLOT_PCIX		0x01
+#define HPC_SLOT_SPEED1		0x02
+#define HPC_SLOT_SPEED2		0x04
+#define HPC_SLOT_BLINK_ATTN	0x08
+#define HPC_SLOT_RSRVD1		0x10
+#define HPC_SLOT_RSRVD2		0x20
+#define HPC_SLOT_BUS_MODE	0x40
+#define HPC_SLOT_RSRVD3		0x80
+
+//----------------------------------------------------------------------------
+// HPC_XSLOT_PCIX_CAP status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_PCIX_NO	0x00
+#define HPC_SLOT_PCIX_YES	0x01
+
+//----------------------------------------------------------------------------
+// HPC_XSLOT_SPEED status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_SPEED_33	0x00
+#define HPC_SLOT_SPEED_66	0x01
+#define HPC_SLOT_SPEED_133	0x02
+
+//----------------------------------------------------------------------------
+// HPC_XSLOT_ATTN_BLINK status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_ATTN_BLINK_OFF	0x00
+#define HPC_SLOT_ATTN_BLINK_ON	0x01
+
+//----------------------------------------------------------------------------
+// HPC_XSLOT_BUS_MODE status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_BUS_MODE_OK	0x00
+#define HPC_SLOT_BUS_MODE_MISM	0x01
+
+//----------------------------------------------------------------------------
+// Controller status
+//----------------------------------------------------------------------------
+#define HPC_CTLR_WORKING	0x01
+#define HPC_CTLR_FINISHED	0x02
+#define HPC_CTLR_RESULT0	0x04
+#define HPC_CTLR_RESULT1	0x08
+#define HPC_CTLR_RESULE2	0x10
+#define HPC_CTLR_RESULT3	0x20
+#define HPC_CTLR_IRQ_ROUTG	0x40
+#define HPC_CTLR_IRQ_PENDG	0x80
+
+//----------------------------------------------------------------------------
+// HPC_CTLR_WROKING status return codes
+//----------------------------------------------------------------------------
+#define HPC_CTLR_WORKING_NO	0x00
+#define HPC_CTLR_WORKING_YES	0x01
+
+//----------------------------------------------------------------------------
+// HPC_CTLR_FINISHED status return codes
+//----------------------------------------------------------------------------
+#define HPC_CTLR_FINISHED_NO	0x00
+#define HPC_CTLR_FINISHED_YES	0x01
+
+//----------------------------------------------------------------------------
+// HPC_CTLR_RESULT status return codes
+//----------------------------------------------------------------------------
+#define HPC_CTLR_RESULT_SUCCESS	0x00
+#define HPC_CTLR_RESULT_FAILED	0x01
+#define HPC_CTLR_RESULT_RSVD	0x02
+#define HPC_CTLR_RESULT_NORESP	0x03
+
+
+//----------------------------------------------------------------------------
+// macro for slot info
+//----------------------------------------------------------------------------
+#define SLOT_POWER(s)	((u8) ((s & HPC_SLOT_POWER) \
+	? HPC_SLOT_POWER_ON : HPC_SLOT_POWER_OFF))
+
+#define SLOT_CONNECT(s)	((u8) ((s & HPC_SLOT_CONNECT) \
+	? HPC_SLOT_DISCONNECTED : HPC_SLOT_CONNECTED))
+
+#define SLOT_ATTN(s,es)	((u8) ((es & HPC_SLOT_BLINK_ATTN) \
+	? HPC_SLOT_ATTN_BLINK \
+	: ((s & HPC_SLOT_ATTN) ? HPC_SLOT_ATTN_ON : HPC_SLOT_ATTN_OFF)))
+
+#define SLOT_PRESENT(s)	((u8) ((s & HPC_SLOT_PRSNT1) \
+	? ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_EMPTY : HPC_SLOT_PRSNT_15) \
+	: ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_PRSNT_25 : HPC_SLOT_PRSNT_7)))
+
+#define SLOT_PWRGD(s)	((u8) ((s & HPC_SLOT_PWRGD) \
+	? HPC_SLOT_PWRGD_GOOD : HPC_SLOT_PWRGD_FAULT_NONE))
+
+#define SLOT_BUS_SPEED(s)	((u8) ((s & HPC_SLOT_BUS_SPEED) \
+	? HPC_SLOT_BUS_SPEED_MISM : HPC_SLOT_BUS_SPEED_OK))
+
+#define SLOT_LATCH(s)	((u8) ((s & HPC_SLOT_LATCH) \
+	? HPC_SLOT_LATCH_CLOSED : HPC_SLOT_LATCH_OPEN))
+
+#define SLOT_PCIX(es)	((u8) ((es & HPC_SLOT_PCIX) \
+	? HPC_SLOT_PCIX_YES : HPC_SLOT_PCIX_NO))
+
+#define SLOT_SPEED(es)	((u8) ((es & HPC_SLOT_SPEED2) \
+	? ((es & HPC_SLOT_SPEED1) ? HPC_SLOT_SPEED_133   \
+				: HPC_SLOT_SPEED_66)   \
+	: HPC_SLOT_SPEED_33))
+
+#define SLOT_BUS_MODE(es)	((u8) ((es & HPC_SLOT_BUS_MODE) \
+	? HPC_SLOT_BUS_MODE_MISM : HPC_SLOT_BUS_MODE_OK))
+
+//--------------------------------------------------------------------------
+// macro for bus info
+//---------------------------------------------------------------------------
+#define CURRENT_BUS_SPEED(s)	((u8) (s & BUS_SPEED_2) \
+	? ((s & BUS_SPEED_1) ? BUS_SPEED_133 : BUS_SPEED_100) \
+	: ((s & BUS_SPEED_1) ? BUS_SPEED_66 : BUS_SPEED_33))
+
+#define CURRENT_BUS_MODE(s)	((u8) (s & BUS_MODE) ? BUS_MODE_PCIX : BUS_MODE_PCI)
+
+#define READ_BUS_STATUS(s)	((u8) (s->options & BUS_STATUS_AVAILABLE))
+
+#define READ_BUS_MODE(s)	((s->revision & PRGM_MODEL_REV_LEVEL) >= 0x20)
+
+#define SET_BUS_STATUS(s)	((u8) (s->options & BUS_CONTROL_AVAILABLE))
+
+#define READ_SLOT_LATCH(s)	((u8) (s->options & SLOT_LATCH_REGS_SUPPORTED))
+
+//----------------------------------------------------------------------------
+// macro for controller info
+//----------------------------------------------------------------------------
+#define CTLR_WORKING(c) ((u8) ((c & HPC_CTLR_WORKING) \
+	? HPC_CTLR_WORKING_YES : HPC_CTLR_WORKING_NO))
+#define CTLR_FINISHED(c) ((u8) ((c & HPC_CTLR_FINISHED) \
+	? HPC_CTLR_FINISHED_YES : HPC_CTLR_FINISHED_NO))
+#define CTLR_RESULT(c) ((u8) ((c & HPC_CTLR_RESULT1)  \
+	? ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_NORESP \
+				: HPC_CTLR_RESULT_RSVD)  \
+	: ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_FAILED \
+				: HPC_CTLR_RESULT_SUCCESS)))
+
+// command that affect the state machine of HPC
+#define NEEDTOCHECK_CMDSTATUS(c) ((c == HPC_SLOT_OFF)        || \
+				  (c == HPC_SLOT_ON)         || \
+				  (c == HPC_CTLR_RESET)      || \
+				  (c == HPC_BUS_33CONVMODE)  || \
+				  (c == HPC_BUS_66CONVMODE)  || \
+				  (c == HPC_BUS_66PCIXMODE)  || \
+				  (c == HPC_BUS_100PCIXMODE) || \
+				  (c == HPC_BUS_133PCIXMODE) || \
+				  (c == HPC_ALLSLOT_OFF)     || \
+				  (c == HPC_ALLSLOT_ON))
+
+
+/* Core part of the driver */
+
+#define ENABLE		1
+#define DISABLE		0
+
+#define ADD		0
+#define REMOVE		1
+#define DETAIL		2
+
+#define MAX_OPS		3
+#define CARD_INFO	0x07
+#define PCIX133		0x07
+#define PCIX66		0x05
+#define PCI66		0x04
+
+extern struct pci_ops *ibmphp_pci_root_ops;
+
+/* Variables */
+
+struct pci_func {
+	struct pci_dev *dev;	/* from the OS */
+	u8 busno;
+	u8 device;
+	u8 function;
+	struct resource_node *io[6];
+	struct resource_node *mem[6];
+	struct resource_node *pfmem[6];
+	struct pci_func *next;
+	int devices[32];	/* for bridge config */
+	u8 irq[4];		/* for interrupt config */
+	u8 bus;			/* flag for unconfiguring, to say if PPB */
+};
+
+struct slot {
+	u8 bus;
+	u8 device;
+	u8 number;
+	char name[100];
+	u32 capabilities;
+	struct hotplug_slot *hotplug_slot;
+	struct controller *ctrl;
+	struct pci_func *func;
+	u8 irq[4];
+	u8 flag;		/* this is for disable slot and polling */
+	int bit_mode;		/* 0 = 32, 1 = 64 */
+	u8 ctlr_index;
+	struct bus_info *bus_on;
+	struct list_head ibm_slot_list;
+	u8 status;
+	u8 ext_status;
+	u8 busstatus;
+};
+
+struct controller {
+	struct ebda_hpc_slot *slots;
+	struct ebda_hpc_bus *buses;
+	u8 revision;
+	u8 options;		/* which options HPC supports */
+	u8 status;
+	u8 ctlr_id;		/* TONI */
+	u8 slot_count;
+	u8 bus_count;
+	u8 ctlr_relative_id;
+	u32 irq;
+	union {
+		struct isa_ctlr_access isa_ctlr;
+		struct pci_ctlr_access pci_ctlr;
+		struct wpeg_i2c_ctlr_access wpeg_ctlr;
+	} u;
+	u8 ctlr_type;
+	struct list_head ebda_hpc_list;
+};
+
+/* Functions */
+
+extern int ibmphp_init_devno (struct slot **);	/* This function is called from EBDA, so we need it not be static */
+extern int ibmphp_disable_slot (struct hotplug_slot *);	/* This function is called from HPC, so we need it to not be static */
+extern int ibmphp_update_slot_info (struct slot *);	/* This function is called from HPC, so we need it to not be be static */
+extern int ibmphp_configure_card (struct pci_func *, u8);
+extern int ibmphp_unconfigure_card (struct slot **, int);
+extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops;
+
+static inline void long_delay (int delay)
+{
+	set_current_state (TASK_INTERRUPTIBLE);
+	schedule_timeout (delay);
+}
+
+#endif				//__IBMPHP_H
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/ibmphp_core.c linux/drivers/hotplug/ibmphp_core.c
--- linux.orig/drivers/hotplug/ibmphp_core.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/ibmphp_core.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,1480 @@
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/smp_lock.h>
+#include "../../arch/i386/kernel/pci-i386.h"	/* for struct irq_routing_table */
+#include "ibmphp.h"
+
+#define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
+#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
+#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
+#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
+#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
+
+#define DRIVER_VERSION	"0.1"
+#define DRIVER_DESC	"IBM Hot Plug PCI Controller Driver"
+
+int ibmphp_debug;
+
+static int debug;
+MODULE_PARM (debug, "i");
+MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
+MODULE_LICENSE ("GPL");
+MODULE_DESCRIPTION (DRIVER_DESC);
+
+static int *ops[MAX_OPS + 1];
+struct pci_ops *ibmphp_pci_root_ops;
+static int max_slots;
+
+static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */
+
+static int init_flag;
+
+/*
+static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
+
+static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
+{
+	return get_max_adapter_speed_1 (hs, value, 1);
+}
+*/
+static inline int get_cur_bus_info (struct slot **sl) 
+{
+	int rc = 1;
+	struct slot * slot_cur = *sl;
+
+	debug ("options = %x\n", slot_cur->ctrl->options);
+	debug ("revision = %x\n", slot_cur->ctrl->revision);	
+
+	if (READ_BUS_STATUS (slot_cur->ctrl)) 
+		rc = ibmphp_hpc_readslot (slot_cur, READ_BUSSTATUS, NULL);
+	
+	if (rc) 
+		return rc;
+	  
+	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus);
+	if (READ_BUS_MODE (slot_cur->ctrl))
+		slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus);
+
+	debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode);
+	
+	*sl = slot_cur;
+	return 0;
+}
+
+static inline int slot_update (struct slot **sl)
+{
+	int rc;
+ 	rc = ibmphp_hpc_readslot (*sl, READ_ALLSTAT, NULL);
+	if (rc) 
+		return rc;
+	if (!init_flag)
+		return get_cur_bus_info (sl);
+	return rc;
+}
+
+static int get_max_slots (void)
+{
+	struct list_head * tmp;
+	int slot_count = 0;
+
+	list_for_each (tmp, &ibmphp_slot_head) 
+		++slot_count;
+	return slot_count;
+}
+
+/* This routine will put the correct slot->device information per slot.  It's
+ * called from initialization of the slot structures. It will also assign
+ * interrupt numbers per each slot.
+ * Parameters: struct slot
+ * Returns 0 or errors
+ */
+int ibmphp_init_devno (struct slot **cur_slot)
+{
+	struct irq_routing_table *rtable;
+	int len;
+	int loop;
+	int i;
+
+	rtable = pcibios_get_irq_routing_table ();
+	if (!rtable) {
+		err ("no BIOS routing table...\n");
+		return -ENOMEM;
+	}
+
+	len = (rtable->size - sizeof (struct irq_routing_table)) / sizeof (struct irq_info);
+
+	if (!len)
+		return -1;
+	for (loop = 0; loop < len; loop++) {
+		if ((*cur_slot)->number == rtable->slots[loop].slot) {
+		if ((*cur_slot)->bus == rtable->slots[loop].bus) {
+			(*cur_slot)->device = PCI_SLOT (rtable->slots[loop].devfn);
+			for (i = 0; i < 4; i++)
+				(*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector ((int) (*cur_slot)->bus, (int) (*cur_slot)->device, i);
+
+				debug ("(*cur_slot)->irq[0] = %x\n", (*cur_slot)->irq[0]);
+				debug ("(*cur_slot)->irq[1] = %x\n", (*cur_slot)->irq[1]);
+				debug ("(*cur_slot)->irq[2] = %x\n", (*cur_slot)->irq[2]);
+				debug ("(*cur_slot)->irq[3] = %x\n", (*cur_slot)->irq[3]);
+
+				debug ("rtable->exlusive_irqs = %x\n", rtable->exclusive_irqs);
+				debug ("rtable->slots[loop].irq[0].bitmap = %x\n", rtable->slots[loop].irq[0].bitmap);
+				debug ("rtable->slots[loop].irq[1].bitmap = %x\n", rtable->slots[loop].irq[1].bitmap);
+				debug ("rtable->slots[loop].irq[2].bitmap = %x\n", rtable->slots[loop].irq[2].bitmap);
+				debug ("rtable->slots[loop].irq[3].bitmap = %x\n", rtable->slots[loop].irq[3].bitmap);
+
+				debug ("rtable->slots[loop].irq[0].link= %x\n", rtable->slots[loop].irq[0].link);
+				debug ("rtable->slots[loop].irq[1].link = %x\n", rtable->slots[loop].irq[1].link);
+				debug ("rtable->slots[loop].irq[2].link = %x\n", rtable->slots[loop].irq[2].link);
+				debug ("rtable->slots[loop].irq[3].link = %x\n", rtable->slots[loop].irq[3].link);
+				debug ("end of init_devno\n");
+				return 0;
+			}
+		}
+	}
+
+	return -1;
+}
+
+static inline int power_on (struct slot *slot_cur)
+{
+	u8 cmd = HPC_SLOT_ON;
+	int retval;
+
+	retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+	if (retval) {
+		err ("power on failed\n");
+		return retval;
+	}
+	if (CTLR_RESULT (slot_cur->ctrl->status)) {
+		err ("command not completed successfully in power_on \n");
+		return -EIO;
+	}
+	long_delay (3 * HZ); /* For ServeRAID cards, and some 66 PCI */
+	return 0;
+}
+
+static inline int power_off (struct slot *slot_cur)
+{
+	u8 cmd = HPC_SLOT_OFF;
+	int retval;
+
+	retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+	if (retval) {
+		err ("power off failed \n");
+		return retval;
+	}
+	if (CTLR_RESULT (slot_cur->ctrl->status)) {
+		err ("command not completed successfully in power_off \n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 value)
+{
+	int rc = 0;
+	struct slot *pslot;
+	u8 cmd;
+	int hpcrc = 0;
+
+	debug ("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n", (ulong) hotplug_slot, value);
+	ibmphp_lock_operations ();
+	cmd = 0x00;     // avoid compiler warning
+
+	if (hotplug_slot) {
+		switch (value) {
+		case HPC_SLOT_ATTN_OFF:
+			cmd = HPC_SLOT_ATTNOFF;
+			break;
+		case HPC_SLOT_ATTN_ON:
+			cmd = HPC_SLOT_ATTNON;
+			break;
+		case HPC_SLOT_ATTN_BLINK:
+			cmd = HPC_SLOT_BLINKLED;
+			break;
+		default:
+			rc = -ENODEV;
+			err ("set_attention_status - Error : invalid input [%x]\n", value);
+			break;
+		}
+		if (rc == 0) {
+			pslot = (struct slot *) hotplug_slot->private;
+			if (pslot)
+				hpcrc = ibmphp_hpc_writeslot (pslot, cmd);
+			else
+				rc = -ENODEV;
+		}
+	} else	
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+
+	debug ("set_attention_status - Exit rc[%d]\n", rc);
+	return rc;
+}
+
+static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+        
+	ibmphp_lock_operations ();
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+			if (!hpcrc)
+				hpcrc = ibmphp_hpc_readslot (pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
+			if (!hpcrc) {
+				*value = SLOT_ATTN (myslot.status, myslot.ext_status);
+				rc = 0;
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+	debug ("get_attention_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations ();
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+			if (!hpcrc) {
+				*value = SLOT_LATCH (myslot.status);
+				rc = 0;
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+	debug ("get_latch_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+
+static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations ();
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+			if (!hpcrc) {
+				*value = SLOT_POWER (myslot.status);
+				rc = 0;
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+	debug ("get_power_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+static int get_adapter_present (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	u8 present;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations ();
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+			if (!hpcrc) {
+				present = SLOT_PRESENT (myslot.status);
+				if (present == HPC_SLOT_EMPTY)
+					*value = 0;
+				else
+					*value = 1;
+				rc = 0;
+			}
+		}
+	} else
+		rc = -ENODEV;
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+	debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+/*
+static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	u8 mode = 0;
+
+	debug ("get_max_bus_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
+
+	ibmphp_lock_operations ();
+
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			rc = 0;
+			mode = pslot->bus_on->supported_bus_mode;
+			*value = pslot->bus_on->supported_speed;
+			*value &= 0x0f;
+
+			if (mode == BUS_MODE_PCIX)
+				*value |= 0x80;
+			else if (mode == BUS_MODE_PCI)
+				*value |= 0x40;
+			else
+				*value |= 0x20;
+		}
+	} else
+		rc = -ENODEV;
+
+	ibmphp_unlock_operations ();
+	debug ("get_max_bus_speed - Exit rc[%d] value[%x]\n", rc, *value);
+	return rc;
+}
+
+static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	u8 mode = 0;
+
+	debug ("get_cur_bus_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
+
+	ibmphp_lock_operations ();
+
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			rc = get_cur_bus_info (&pslot);
+			if (!rc) {
+				mode = pslot->bus_on->current_bus_mode;
+				*value = pslot->bus_on->current_speed;
+				*value &= 0x0f;
+				
+				if (mode == BUS_MODE_PCIX)
+					*value |= 0x80;
+				else if (mode == BUS_MODE_PCI)
+					*value |= 0x40;
+				else
+					*value |= 0x20;	
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	ibmphp_unlock_operations ();
+	debug ("get_cur_bus_speed - Exit rc[%d] value[%x]\n", rc, *value);
+	return rc;
+}
+
+static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_max_adapter_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
+
+	if (flag)
+		ibmphp_lock_operations ();
+
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+
+			if (!(SLOT_LATCH (myslot.status)) && (SLOT_PRESENT (myslot.status))) {
+				hpcrc = ibmphp_hpc_readslot (pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
+				if (!hpcrc) {
+					*value = SLOT_SPEED (myslot.ext_status);
+					rc = 0;
+				}
+			} else {
+				*value = MAX_ADAPTER_NONE;
+				rc = 0;
+			}
+                }
+        } else
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	if (flag)
+		ibmphp_unlock_operations ();
+
+	debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot = NULL;
+	struct pci_dev * dev = NULL;
+
+	debug ("get_card_bus_names - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot);
+
+	ibmphp_lock_operations ();
+
+	if (hotplug_slot) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			rc = 0;
+			if (pslot->func)
+				dev = pslot->func->dev;
+			else
+                		dev = pci_find_slot (pslot->bus, (pslot->device << 3) | (0x00 & 0x7));
+			if (dev) 
+				snprintf (value, 100, "Bus %d : %s", pslot->bus,dev->name);
+			else
+				snprintf (value, 100, "Bus %d", pslot->bus);
+			
+				
+		}
+	} else
+		rc = -ENODEV;
+
+	ibmphp_unlock_operations ();
+	debug ("get_card_bus_names - Exit rc[%d] value[%x]\n", rc, *value);
+	return rc;
+}
+
+*/
+/*******************************************************************************
+ * This routine will initialize the ops data structure used in the validate
+ * function. It will also power off empty slots that are powered on since BIOS
+ * leaves those on, albeit disconnected
+ ******************************************************************************/
+static int init_ops (void)
+{
+	struct slot *slot_cur;
+	int retval;
+	int j;
+	int rc;
+
+	for (j = 0; j < MAX_OPS; j++) {
+		ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL);
+		if (!ops[j]) {
+			err ("out of system memory \n");
+			return -ENOMEM;
+		}
+	}
+
+	ops[ADD][0] = 0;
+	ops[REMOVE][0] = 0;
+	ops[DETAIL][0] = 0;
+
+	for (j = 1; j <= max_slots; j++) {
+
+		slot_cur = ibmphp_get_slot_from_physical_num (j);
+
+		debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);
+
+		if (slot_cur->ctrl->revision == 0xFF) 
+			if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
+				return -1;
+
+		if (slot_cur->bus_on->current_speed == 0xFF) 
+			if (get_cur_bus_info (&slot_cur)) 
+				return -1;
+
+		if (slot_cur->ctrl->options == 0xFF)
+			if (get_hpc_options (slot_cur, &slot_cur->ctrl->options))
+				return -1;
+
+		retval = slot_update (&slot_cur);
+		if (retval)
+			return retval;
+
+		debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status);
+		debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status));
+
+		if (!(SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
+			/* No power, adapter, and latch closed */
+			ops[ADD][j] = 1;
+		else
+			ops[ADD][j] = 0;
+
+		ops[DETAIL][j] = 1;
+
+		if ((SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
+			/*Power,adapter,latch closed */
+			ops[REMOVE][j] = 1;
+		else
+			ops[REMOVE][j] = 0;
+
+		if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) {
+			debug ("BEFORE POWER OFF COMMAND\n");
+				rc = power_off (slot_cur);
+				if (rc)
+					return rc;
+
+	/*		retval = slot_update (&slot_cur);
+	 *		if (retval)
+	 *			return retval;
+	 *		ibmphp_update_slot_info (slot_cur);
+	 */
+		}
+	}
+	init_flag = 0;
+	return 0;
+}
+
+/* This operation will check whether the slot is within the bounds and
+ * the operation is valid to perform on that slot
+ * Parameters: slot, operation
+ * Returns: 0 or error codes
+ */
+static int validate (struct slot *slot_cur, int opn)
+{
+	int number;
+	int retval;
+
+	if (!slot_cur)
+		return -ENODEV;
+	number = slot_cur->number;
+	if ((number > max_slots) || (number < 0))
+		return -EBADSLT;
+	debug ("slot_number in validate is %d\n", slot_cur->number);
+
+	retval = slot_update (&slot_cur);
+	if (retval)
+		return retval;
+
+	if (!(SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
+	    && !(SLOT_LATCH (slot_cur->status)))
+		ops[ADD][number] = 1;
+	else
+		ops[ADD][number] = 0;
+
+	ops[DETAIL][number] = 1;
+
+	if ((SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
+	    && !(SLOT_LATCH (slot_cur->status)))
+		ops[REMOVE][number] = 1;
+	else
+		ops[REMOVE][number] = 0;
+
+	switch (opn) {
+		case ENABLE:
+			if (ops[ADD][number])
+				return 0;
+			break;
+		case DISABLE:
+			if (ops[REMOVE][number])
+				return 0;
+			break;
+		case DETAIL:
+			if (ops[DETAIL][number])
+				return 0;
+			break;
+		default:
+			return -EINVAL;
+			break;
+	}
+	err ("validate failed....\n");
+	return -EINVAL;
+}
+
+/********************************************************************************
+ * This routine is for updating the data structures in the hotplug core
+ * Parameters: struct slot
+ * Returns: 0 or error
+ *******************************************************************************/
+int ibmphp_update_slot_info (struct slot *slot_cur)
+{
+	struct hotplug_slot_info *info;
+	char buffer[10];
+	int rc;
+//	u8 bus_speed;
+
+	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+	if (!info) {
+		err ("out of system memory \n");
+		return -ENOMEM;
+	}
+        
+	snprintf (buffer, 10, "%d", slot_cur->number);
+	info->power_status = SLOT_POWER (slot_cur->status);
+	info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
+	info->latch_status = SLOT_LATCH (slot_cur->status);
+        if (!SLOT_PRESENT (slot_cur->status)) {
+                info->adapter_status = 0;
+//		info->max_adapter_speed_status = MAX_ADAPTER_NONE;
+	} else {
+                info->adapter_status = 1;
+//		get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
+	}
+/*
+	bus_speed = slot_cur->bus_on->current_speed;
+	bus_speed &= 0x0f;
+                        
+	if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
+		bus_speed |= 0x80;
+	else if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCI)
+		bus_speed |= 0x40;
+	else
+		bus_speed |= 0x20;
+
+	info->cur_bus_speed_status = bus_speed;
+	info->max_bus_speed_status = slot_cur->hotplug_slot->info->max_bus_speed_status;
+	// To do: card_bus_names 
+*/	
+	rc = pci_hp_change_slot_info (buffer, info);
+	kfree (info);
+	return rc;
+}
+
+
+/******************************************************************************
+ * This function will return the pci_func, given bus and devfunc, or NULL.  It
+ * is called from visit routines
+ ******************************************************************************/
+
+static struct pci_func *ibm_slot_find (u8 busno, u8 device, u8 function)
+{
+	struct pci_func *func_cur;
+	struct slot *slot_cur;
+	struct list_head * tmp;
+	list_for_each (tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+		if (slot_cur->func) {
+			func_cur = slot_cur->func;
+			while (func_cur) {
+				if ((func_cur->busno == busno) && (func_cur->device == device) && (func_cur->function == function))
+					return func_cur;
+				func_cur = func_cur->next;
+			}
+		}
+	}
+	return NULL;
+}
+
+/* This routine is to find the pci_bus from kernel structures.
+ * Parameters: bus number
+ * Returns : pci_bus *  or NULL if not found
+ */
+static struct pci_bus *find_bus (u8 busno)
+{
+	const struct list_head *tmp;
+	struct pci_bus *bus;
+	debug ("inside find_bus, busno = %x \n", busno);
+
+	list_for_each (tmp, &pci_root_buses) {
+		bus = (struct pci_bus *) pci_bus_b (tmp);
+		if (bus)
+			if (bus->number == busno)
+				return bus;
+	}
+	return NULL;
+}
+
+/******************************************************************
+ * This function is here because we can no longer use pci_root_ops
+ ******************************************************************/
+static struct pci_ops *get_root_pci_ops (void)
+{
+	struct pci_bus * bus;
+
+	if ((bus = find_bus (0)))
+		return bus->ops;
+	return NULL;
+}
+
+/*************************************************************
+ * This routine frees up memory used by struct slot, including
+ * the pointers to pci_func, bus, hotplug_slot, controller,
+ * and deregistering from the hotplug core
+ *************************************************************/
+static void free_slots (void)
+{
+	struct slot *slot_cur;
+	struct list_head * tmp;
+	struct list_head * next;
+
+	list_for_each_safe (tmp, next, &ibmphp_slot_head) {
+
+		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+
+		pci_hp_deregister (slot_cur->hotplug_slot);
+
+		if (slot_cur->hotplug_slot) {
+			kfree (slot_cur->hotplug_slot);
+			slot_cur->hotplug_slot = NULL;
+		}
+
+		if (slot_cur->ctrl) 
+			slot_cur->ctrl = NULL;
+		
+		if (slot_cur->bus_on) 
+			slot_cur->bus_on = NULL;
+
+		ibmphp_unconfigure_card (&slot_cur, -1);  /* we don't want to actually remove the resources, since free_resources will do just that */
+
+		kfree (slot_cur);
+	}
+}
+
+static int ibm_is_pci_dev_in_use (struct pci_dev *dev)
+{
+	int i = 0;
+	int inuse = 0;
+
+	if (dev->driver)
+		return 1;
+
+	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
+
+		if (!pci_resource_start (dev, i))
+			continue;
+
+		if (pci_resource_flags (dev, i) & IORESOURCE_IO)
+			inuse = check_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
+
+		else if (pci_resource_flags (dev, i) & IORESOURCE_MEM)
+			inuse = check_mem_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
+	}
+
+	return inuse;
+}
+
+static int ibm_pci_hp_remove_device (struct pci_dev *dev)
+{
+	if (ibm_is_pci_dev_in_use (dev)) {
+		err ("***Cannot safely power down device -- it appears to be in use***\n");
+		return -EBUSY;
+	}
+	pci_remove_device (dev);
+	return 0;
+}
+
+static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
+{
+	struct pci_dev *dev = wrapped_dev->dev;
+	struct pci_func *temp_func;
+	int i = 0;
+
+	do {
+		temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
+	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
+
+	if (dev) {
+		if (ibm_pci_hp_remove_device (dev) == 0)
+			kfree (dev);    /* Now, remove */
+		else
+			return -1;
+	}
+
+	if (temp_func)
+		temp_func->dev = NULL;
+	else
+		err ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
+
+	return 0;
+}
+
+static int ibm_unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
+{
+	struct pci_bus *bus = wrapped_bus->bus;
+
+	pci_proc_detach_bus (bus);
+	/* The cleanup code should live in the kernel... */
+	bus->self->subordinate = NULL;
+	/* unlink from parent bus */
+	list_del (&bus->node);
+
+	/* Now, remove */
+	if (bus)
+		kfree (bus);
+
+	return 0;
+}
+
+static int ibm_unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
+{
+	struct pci_dev *dev = wrapped_dev->dev;
+
+	debug ("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT (dev->devfn), PCI_FUNC (dev->devfn));
+
+	/* Now, remove the Linux Driver Representation */
+	if (dev->driver) {
+		debug ("is there a driver?\n");
+		if (dev->driver->remove) {
+			dev->driver->remove (dev);
+			debug ("driver was properly removed\n");
+		}
+		dev->driver = NULL;
+	}
+
+	return ibm_is_pci_dev_in_use (dev);
+}
+
+static struct pci_visit ibm_unconfigure_functions_phase1 = {
+	post_visit_pci_dev:	ibm_unconfigure_visit_pci_dev_phase1,
+};
+
+static struct pci_visit ibm_unconfigure_functions_phase2 = {
+	post_visit_pci_bus:	ibm_unconfigure_visit_pci_bus_phase2,
+	post_visit_pci_dev:	ibm_unconfigure_visit_pci_dev_phase2,
+};
+
+static int ibm_unconfigure_device (struct pci_func *func)
+{
+	int rc = 0;
+	struct pci_dev_wrapped wrapped_dev;
+	struct pci_bus_wrapped wrapped_bus;
+	struct pci_dev *temp;
+	u8 j;
+
+	memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
+	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
+
+	debug ("inside ibm_unconfigure_device\n");
+	debug ("func->device = %x, func->function = %x\n", func->device, func->function);
+	debug ("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
+
+	for (j = 0; j < 0x08; j++) {
+		temp = pci_find_slot (func->busno, (func->device << 3) | j);
+		if (temp) {
+			wrapped_dev.dev = temp;
+			wrapped_bus.bus = temp->bus;
+			rc = pci_visit_dev (&ibm_unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
+			if (rc)
+				break;
+
+			rc = pci_visit_dev (&ibm_unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
+			if (rc)
+				break;
+		}
+	}
+	debug ("rc in ibm_unconfigure_device b4 returning is %d \n", rc);
+	return rc;
+}
+
+static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
+{
+	//      struct pci_bus *bus = wrapped_bus->bus; /* We don't need this, since we don't create in the else statement */
+	struct pci_dev *dev = wrapped_dev->dev;
+	struct pci_func *temp_func;
+	int i = 0;
+
+	do {
+		temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
+	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
+
+	if (temp_func)
+		temp_func->dev = dev;
+	else {
+		/* This should not really happen, since we create functions
+		   first and then call to configure */
+		debug (" We shouldn't come here \n");
+	}
+
+	if (temp_func->dev) {
+		pci_proc_attach_device (temp_func->dev);
+		pci_announce_device_to_drivers (temp_func->dev);
+	}
+
+	return 0;
+}
+
+static struct pci_visit configure_functions = {
+	visit_pci_dev:	configure_visit_pci_dev,
+};
+
+static int ibm_configure_device (struct pci_func *func)
+{
+	unsigned char bus;
+	struct pci_dev dev0;
+	struct pci_bus *child;
+	struct pci_dev *temp;
+	int rc = 0;
+
+	struct pci_dev_wrapped wrapped_dev;
+	struct pci_bus_wrapped wrapped_bus;
+
+	memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
+	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
+	memset (&dev0, 0, sizeof (struct pci_dev));
+
+	if (func->dev == NULL)
+		func->dev = pci_find_slot (func->busno, (func->device << 3) | (func->function & 0x7));
+
+	if (func->dev == NULL) {
+		dev0.bus = find_bus (func->busno);
+		dev0.devfn = ((func->device << 3) + (func->function & 0x7));
+		dev0.sysdata = dev0.bus->sysdata;
+
+		func->dev = pci_scan_slot (&dev0);
+
+		if (func->dev == NULL) {
+			err ("ERROR... : pci_dev still NULL \n");
+			return 0;
+		}
+	}
+	if (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+		pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);
+		child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
+		pci_do_scan_bus (child);
+	}
+
+	temp = func->dev;
+	if (temp) {
+		wrapped_dev.dev = temp;
+		wrapped_bus.bus = temp->bus;
+		rc = pci_visit_dev (&configure_functions, &wrapped_dev, &wrapped_bus);
+	}
+	return rc;
+}
+/*******************************************************
+ * Returns whether the bus is empty or not 
+ *******************************************************/
+static int is_bus_empty (struct slot * slot_cur)
+{
+	int rc;
+	struct slot * tmp_slot;
+	u8 i = slot_cur->bus_on->slot_min;
+
+	while (i <= slot_cur->bus_on->slot_max) {
+		if (i == slot_cur->number) {
+			i++;
+			continue;
+		}
+		tmp_slot = ibmphp_get_slot_from_physical_num (i);
+		rc = slot_update (&tmp_slot);
+		if (rc)
+			return 0;
+		if (SLOT_PRESENT (tmp_slot->status) && SLOT_POWER (tmp_slot->status))
+			return 0;
+		i++;
+	}
+	return 1;
+}
+
+/***********************************************************
+ * If the HPC permits and the bus currently empty, tries to set the 
+ * bus speed and mode at the maximum card capability
+ ***********************************************************/
+static int set_bus (struct slot * slot_cur)
+{
+	int rc;
+	u8 speed;
+	u8 cmd = 0x0;
+
+	debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number);
+	if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
+		rc = slot_update (&slot_cur);
+		if (rc)
+			return rc;
+		speed = SLOT_SPEED (slot_cur->ext_status);
+		debug ("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
+		switch (speed) {
+		case HPC_SLOT_SPEED_33:
+			cmd = HPC_BUS_33CONVMODE;
+			break;
+		case HPC_SLOT_SPEED_66:
+			if (SLOT_PCIX (slot_cur->ext_status))
+				cmd = HPC_BUS_66PCIXMODE;
+			else
+				cmd = HPC_BUS_66CONVMODE;
+			break;
+		case HPC_SLOT_SPEED_133:
+			if (slot_cur->bus_on->slot_count > 1)
+				cmd = HPC_BUS_100PCIXMODE;
+			else
+				cmd = HPC_BUS_133PCIXMODE;
+			break;
+		default:
+			err ("wrong slot speed \n");
+			return -ENODEV;
+		}
+		debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd);
+		rc = ibmphp_hpc_writeslot (slot_cur, cmd);
+		if (rc)
+			return rc;
+	}
+	debug ("%s -Exit \n", __FUNCTION__);
+	return 0;
+}
+
+static inline void print_card_capability (struct slot *slot_cur)
+{
+	info ("capability of the card is ");
+	if ((slot_cur->ext_status & CARD_INFO) == PCIX133) 
+		info ("   133 MHz PCI-X \n");
+	else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
+		info ("    66 MHz PCI-X \n");
+	else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
+		info ("    66 MHz PCI \n");
+	else
+		info ("    33 MHz PCI \n");
+
+}
+
+/* This routine will power on the slot, configure the device(s) and find the
+ * drivers for them.
+ * Parameters: hotplug_slot
+ * Returns: 0 or failure codes
+ */
+static int enable_slot (struct hotplug_slot *hs)
+{
+	int rc, i, rcpr;
+	struct slot *slot_cur;
+	u8 function;
+	u8 faulted = 0;
+	struct pci_func *tmp_func;
+
+	ibmphp_lock_operations ();
+
+	debug ("ENABLING SLOT........ \n");
+	slot_cur = (struct slot *) hs->private;
+
+	if ((rc = validate (slot_cur, ENABLE))) {
+		err ("validate function failed \n");
+		attn_off (slot_cur);	/* need to turn off if was blinking b4 */
+		attn_on (slot_cur);
+		rc = slot_update (&slot_cur);
+		if (rc) {
+			ibmphp_unlock_operations();
+			return rc;
+		}
+		ibmphp_update_slot_info (slot_cur);
+                ibmphp_unlock_operations ();
+		return rc;
+	}
+
+	attn_LED_blink (slot_cur);
+	
+	rc = set_bus (slot_cur);
+	if (rc) {
+		err ("was not able to set the bus \n");
+		attn_off (slot_cur);
+		attn_on (slot_cur);
+		ibmphp_unlock_operations ();
+		return -ENODEV;
+	}
+		
+	rc = power_on (slot_cur);
+
+	if (rc) {
+		err ("something wrong when powering up... please see below for details\n");
+		/* need to turn off before on, otherwise, blinking overwrites */
+		attn_off(slot_cur);
+		attn_on (slot_cur);
+		if (slot_update (&slot_cur)) {
+			attn_off (slot_cur);
+			attn_on (slot_cur);
+			ibmphp_unlock_operations ();
+			return -ENODEV;
+		}
+		/* Check to see the error of why it failed */
+		if (!(SLOT_PWRGD (slot_cur->status)))
+			err ("power fault occured trying to power up \n");
+		else if (SLOT_BUS_SPEED (slot_cur->status)) {
+			err ("bus speed mismatch occured.  please check current bus speed and card capability \n");
+			print_card_capability (slot_cur);
+		} else if (SLOT_BUS_MODE (slot_cur->ext_status)) 
+			err ("bus mode mismatch occured.  please check current bus mode and card capability \n");
+
+		ibmphp_update_slot_info (slot_cur);
+		ibmphp_unlock_operations (); 
+		return rc;
+	}
+	debug ("after power_on\n");
+
+	rc = slot_update (&slot_cur);
+	if (rc) {
+		attn_off (slot_cur);
+		attn_on (slot_cur);
+		rcpr = power_off (slot_cur);
+		if (rcpr) {
+			ibmphp_unlock_operations ();
+			return rcpr;
+		}
+		ibmphp_unlock_operations ();
+		return rc;
+	}
+	
+	if (SLOT_POWER (slot_cur->status) && !(SLOT_PWRGD (slot_cur->status))) {
+		faulted = 1;
+		err ("power fault occured trying to power up...\n");
+	} else if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
+		faulted = 1;
+		err ("bus speed mismatch occured.  please check current bus speed and card capability \n");
+		print_card_capability (slot_cur);
+	} 
+	/* Don't think this case will happen after above checks... but just in case, for paranoia sake */
+	else if (!(SLOT_POWER (slot_cur->status))) {
+		err ("power on failed... \n");
+		faulted = 1;
+	}
+	if (faulted) {
+		attn_off (slot_cur);	/* need to turn off b4 on */
+		attn_on (slot_cur);
+		rcpr = power_off (slot_cur);
+		if (rcpr) {
+			ibmphp_unlock_operations ();
+			return rcpr;
+		}
+			
+		if (slot_update (&slot_cur)) {
+			ibmphp_unlock_operations ();
+			return -ENODEV;
+		}
+		ibmphp_update_slot_info (slot_cur);
+		ibmphp_unlock_operations ();
+		return -EINVAL;
+	}
+
+	slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+	if (!slot_cur->func) { /* We cannot do update_slot_info here, since no memory for kmalloc n.e.ways, and update_slot_info allocates some */
+		err ("out of system memory \n");
+		attn_off (slot_cur);
+		attn_on (slot_cur);
+		rcpr = power_off (slot_cur);
+		if (rcpr) {
+			ibmphp_unlock_operations ();
+			return rcpr;
+		}
+		ibmphp_unlock_operations ();
+		return -ENOMEM;
+	}
+	memset (slot_cur->func, 0, sizeof (struct pci_func));
+	slot_cur->func->busno = slot_cur->bus;
+	slot_cur->func->device = slot_cur->device;
+	for (i = 0; i < 4; i++)
+		slot_cur->func->irq[i] = slot_cur->irq[i];
+
+	debug ("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n", slot_cur->bus, slot_cur->device);
+
+	if (ibmphp_configure_card (slot_cur->func, slot_cur->number)) {
+		err ("configure_card was unsuccessful... \n");
+		ibmphp_unconfigure_card (&slot_cur, 1); /* true because don't need to actually deallocate resources, just remove references */
+		debug ("after unconfigure_card\n");
+		slot_cur->func = NULL;
+		attn_off (slot_cur);	/* need to turn off in case was blinking */
+		attn_on (slot_cur);
+		rcpr = power_off (slot_cur);
+		if (rcpr) {
+			ibmphp_unlock_operations ();
+			return rcpr;
+		}
+		if (slot_update (&slot_cur)) {
+			ibmphp_unlock_operations();
+			return -ENODEV;
+		}
+		ibmphp_update_slot_info (slot_cur);
+		ibmphp_unlock_operations ();
+		return -ENOMEM;
+	}
+	function = 0x00;
+	do {
+		tmp_func = ibm_slot_find (slot_cur->bus, slot_cur->func->device, function++);
+		if (tmp_func && !(tmp_func->dev))
+			ibm_configure_device (tmp_func);
+	} while (tmp_func);
+
+	attn_off (slot_cur);
+	if (slot_update (&slot_cur)) {
+		ibmphp_unlock_operations ();
+		return -EFAULT;
+	}
+	ibmphp_print_test ();
+	rc = ibmphp_update_slot_info (slot_cur);
+	ibmphp_unlock_operations(); 
+	return rc;
+}
+
+/**************************************************************
+* HOT REMOVING ADAPTER CARD                                   *
+* INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
+* OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
+          DISABLE POWER ,                                    *
+**************************************************************/
+int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
+{
+	int rc;
+	struct slot *slot_cur = (struct slot *) hotplug_slot->private;
+	u8 flag = slot_cur->flag;
+
+	slot_cur->flag = TRUE;
+	debug ("DISABLING SLOT... \n"); 
+		
+	ibmphp_lock_operations (); 
+	if (slot_cur == NULL) {
+		ibmphp_unlock_operations ();
+		return -ENODEV;
+	}
+	if (slot_cur->ctrl == NULL) {
+		ibmphp_unlock_operations ();
+		return -ENODEV;
+	}
+	if (flag == TRUE) {
+		rc = validate (slot_cur, DISABLE);	/* checking if powered off already & valid slot # */
+		if (rc) {
+			/*  Need to turn off if was blinking b4 */
+			attn_off (slot_cur);
+			attn_on (slot_cur);
+			if (slot_update (&slot_cur)) {
+				ibmphp_unlock_operations ();
+				return -EFAULT;
+			}
+		
+			ibmphp_update_slot_info (slot_cur);
+			ibmphp_unlock_operations ();
+			return rc;
+		}
+	}
+	attn_LED_blink (slot_cur);
+
+	if (slot_cur->func == NULL) {
+		/* We need this for fncs's that were there on bootup */
+		slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+		if (!slot_cur->func) {
+			err ("out of system memory \n");
+			attn_off (slot_cur);
+			attn_on (slot_cur);
+			ibmphp_unlock_operations ();
+			return -ENOMEM;
+		}
+		memset (slot_cur->func, 0, sizeof (struct pci_func));
+		slot_cur->func->busno = slot_cur->bus;
+		slot_cur->func->device = slot_cur->device;
+	}
+
+	if ((rc = ibm_unconfigure_device (slot_cur->func))) {
+		err ("removing from kernel failed... \n");
+		err ("Please check to see if it was statically linked or is in use otherwise. (perhaps the driver is not 'hot-removable')\n");
+		attn_off (slot_cur);
+		attn_on (slot_cur);
+		ibmphp_unlock_operations ();
+		return rc;
+	}
+
+	rc = ibmphp_unconfigure_card (&slot_cur, 0);
+	slot_cur->func = NULL;
+	debug ("in disable_slot. after unconfigure_card \n");
+	if (rc) {
+		err ("could not unconfigure card.\n");
+		attn_off (slot_cur);	/* need to turn off if was blinking b4 */
+		attn_on (slot_cur);
+
+		if (slot_update (&slot_cur)) {
+			ibmphp_unlock_operations ();
+			return -EFAULT;
+		}
+
+		if (flag) 
+			ibmphp_update_slot_info (slot_cur);
+
+		ibmphp_unlock_operations ();
+		return -EFAULT;
+	}
+
+	rc = ibmphp_hpc_writeslot (hotplug_slot->private, HPC_SLOT_OFF);
+	if (rc) {
+		attn_off (slot_cur);
+		attn_on (slot_cur);
+		if (slot_update (&slot_cur)) {
+			ibmphp_unlock_operations ();
+			return -EFAULT;
+		}
+
+		if (flag)
+			ibmphp_update_slot_info (slot_cur);
+
+		ibmphp_unlock_operations ();
+		return rc;
+	}
+
+	attn_off (slot_cur);
+	if (slot_update (&slot_cur)) {
+		ibmphp_unlock_operations ();
+		return -EFAULT;
+	}
+	if (flag) 
+		rc = ibmphp_update_slot_info (slot_cur);
+	else
+		rc = 0;
+
+	ibmphp_print_test ();
+	ibmphp_unlock_operations();
+	return rc;
+}
+
+struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
+	owner:				THIS_MODULE,
+	set_attention_status:		set_attention_status,
+	enable_slot:			enable_slot,
+	disable_slot:			ibmphp_disable_slot,
+	hardware_test:			NULL,
+	get_power_status:		get_power_status,
+	get_attention_status:		get_attention_status,
+	get_latch_status:		get_latch_status,
+	get_adapter_status:		get_adapter_present,
+/*	get_max_bus_speed_status:	get_max_bus_speed,
+	get_max_adapter_speed_status:	get_max_adapter_speed,
+	get_cur_bus_speed_status:	get_cur_bus_speed,
+	get_card_bus_names_status:	get_card_bus_names,
+*/
+};
+
+static void ibmphp_unload (void)
+{
+	free_slots ();
+	debug ("after slots \n");
+	ibmphp_free_resources ();
+	debug ("after resources \n");
+	ibmphp_free_bus_info_queue ();
+	debug ("after bus info \n");
+	ibmphp_free_ebda_hpc_queue ();
+	debug ("after ebda hpc \n");
+	ibmphp_free_ebda_pci_rsrc_queue ();
+	debug ("after ebda pci rsrc \n");
+}
+
+static int __init ibmphp_init (void)
+{
+	int i = 0;
+	int rc = 0;
+
+	init_flag = 1;
+	ibmphp_pci_root_ops = get_root_pci_ops ();
+	if (ibmphp_pci_root_ops == NULL) {
+		err ("cannot read bus operations... will not be able to read the cards.  Please check your system \n");
+		return -ENODEV;	
+	}
+
+	ibmphp_debug = debug;
+
+	ibmphp_hpc_initvars ();
+
+	for (i = 0; i < 16; i++)
+		irqs[i] = 0;
+
+	if ((rc = ibmphp_access_ebda ())) {
+		ibmphp_unload ();
+		return rc;
+	}
+	debug ("after ibmphp_access_ebda () \n");
+
+	if ((rc = ibmphp_rsrc_init ())) {
+		ibmphp_unload ();
+		return rc;
+	}
+	debug ("AFTER Resource & EBDA INITIALIZATIONS \n");
+
+	max_slots = get_max_slots ();
+
+	if (init_ops ()) {
+		ibmphp_unload ();
+		return -ENODEV;
+	}
+	ibmphp_print_test ();
+	if ((rc = ibmphp_hpc_start_poll_thread ())) {
+		ibmphp_unload ();
+		return -ENODEV;
+	}
+
+	/* lock ourselves into memory with a module count of -1 
+	 * so that no one can unload us. */
+	MOD_DEC_USE_COUNT;
+
+	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
+
+	return 0;
+}
+
+static void __exit ibmphp_exit (void)
+{
+	ibmphp_hpc_stop_poll_thread ();
+	debug ("after polling \n");
+	ibmphp_unload ();
+	debug ("done \n");
+}
+
+module_init (ibmphp_init);
+module_exit (ibmphp_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/ibmphp_ebda.c linux/drivers/hotplug/ibmphp_ebda.c
--- linux.orig/drivers/hotplug/ibmphp_ebda.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/ibmphp_ebda.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,851 @@
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Tong Yu, IBM Corporation
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include "ibmphp.h"
+
+/*
+ * POST builds data blocks(in this data block definition, a char-1
+ * byte, short(or word)-2 byte, long(dword)-4 byte) in the Extended
+ * BIOS Data Area which describe the configuration of the hot-plug
+ * controllers and resources used by the PCI Hot-Plug devices.
+ *
+ * This file walks EBDA, maps data block from physical addr,
+ * reconstruct linked lists about all system resource(MEM, PFM, IO)
+ * already assigned by POST, as well as linked lists about hot plug
+ * controllers (ctlr#, slot#, bus&slot features...)
+ */
+
+/* Global lists */
+LIST_HEAD (ibmphp_ebda_pci_rsrc_head);
+LIST_HEAD (ibmphp_slot_head);
+
+/* Local variables */
+static struct ebda_hpc_list *hpc_list_ptr;
+static struct ebda_rsrc_list *rsrc_list_ptr;
+static struct rio_table_hdr *rio_table_ptr;
+static LIST_HEAD (ebda_hpc_head);
+static LIST_HEAD (bus_info_head);
+static void *io_mem;
+
+/* Local functions */
+static int ebda_rsrc_controller (void);
+static int ebda_rsrc_rsrc (void);
+static int ebda_rio_table (void);
+
+static struct slot *alloc_ibm_slot (void)
+{
+	struct slot *slot;
+
+	slot = kmalloc (sizeof (struct slot), GFP_KERNEL);
+	if (!slot)
+		return NULL;
+	memset (slot, 0, sizeof (*slot));
+	return slot;
+}
+
+static struct ebda_hpc_list *alloc_ebda_hpc_list (void)
+{
+	struct ebda_hpc_list *list;
+
+	list = kmalloc (sizeof (struct ebda_hpc_list), GFP_KERNEL);
+	if (!list)
+		return NULL;
+	memset (list, 0, sizeof (*list));
+	return list;
+}
+
+static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
+{
+	struct controller *controller;
+	struct ebda_hpc_slot *slots;
+	struct ebda_hpc_bus *buses;
+
+	controller = kmalloc (sizeof (struct controller), GFP_KERNEL);
+	if (!controller)
+		return NULL;
+	memset (controller, 0, sizeof (*controller));
+
+	slots = kmalloc (sizeof (struct ebda_hpc_slot) * slot_count, GFP_KERNEL);
+	if (!slots) {
+		kfree (controller);
+		return NULL;
+	}
+	memset (slots, 0, sizeof (*slots) * slot_count);
+	controller->slots = slots;
+
+	buses = kmalloc (sizeof (struct ebda_hpc_bus) * bus_count, GFP_KERNEL);
+	if (!buses) {
+		kfree (controller->slots);
+		kfree (controller);
+		return NULL;
+	}
+	memset (buses, 0, sizeof (*buses) * bus_count);
+	controller->buses = buses;
+
+	return controller;
+}
+
+static void free_ebda_hpc (struct controller *controller)
+{
+	kfree (controller->slots);
+	controller->slots = NULL;
+	kfree (controller->buses);
+	controller->buses = NULL;
+	kfree (controller);
+}
+
+static struct ebda_rsrc_list *alloc_ebda_rsrc_list (void)
+{
+	struct ebda_rsrc_list *list;
+
+	list = kmalloc (sizeof (struct ebda_rsrc_list), GFP_KERNEL);
+	if (!list)
+		return NULL;
+	memset (list, 0, sizeof (*list));
+	return list;
+}
+
+static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
+{
+	struct ebda_pci_rsrc *resource;
+
+	resource = kmalloc (sizeof (struct ebda_pci_rsrc), GFP_KERNEL);
+	if (!resource)
+		return NULL;
+	memset (resource, 0, sizeof (*resource));
+	return resource;
+}
+
+static void print_bus_info (void)
+{
+	struct bus_info *ptr;
+	struct list_head *ptr1;
+	
+	list_for_each (ptr1, &bus_info_head) {
+		ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+		debug ("%s - slot_min = %x\n", __FUNCTION__, ptr->slot_min);
+		debug ("%s - slot_max = %x\n", __FUNCTION__, ptr->slot_max);
+		debug ("%s - slot_count = %x\n", __FUNCTION__, ptr->slot_count);
+		debug ("%s - bus# = %x\n", __FUNCTION__, ptr->busno);
+		debug ("%s - current_speed = %x\n", __FUNCTION__, ptr->current_speed);
+		debug ("%s - supported_speed = %x\n", __FUNCTION__, ptr->supported_speed);
+		debug ("%s - controller_id = %x\n", __FUNCTION__, ptr->controller_id);
+		debug ("%s - bus_mode = %x\n", __FUNCTION__, ptr->supported_bus_mode);
+	}
+}
+
+static void print_ebda_pci_rsrc (void)
+{
+	struct ebda_pci_rsrc *ptr;
+	struct list_head *ptr1;
+
+	list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
+		ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+		debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", 
+			__FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
+	}
+}
+
+static void print_ebda_hpc (void)
+{
+	struct controller *hpc_ptr;
+	struct list_head *ptr1;
+	u16 index;
+
+	list_for_each (ptr1, &ebda_hpc_head) {
+
+		hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list); 
+
+		for (index = 0; index < hpc_ptr->slot_count; index++) {
+			debug ("%s - physical slot#: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_num);
+			debug ("%s - pci bus# of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_bus_num);
+			debug ("%s - index into ctlr addr: %x\n", __FUNCTION__, hpc_ptr->slots[index].ctl_index);
+			debug ("%s - cap of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_cap);
+		}
+
+		for (index = 0; index < hpc_ptr->bus_count; index++) {
+			debug ("%s - bus# of each bus controlled by this ctlr: %x\n", __FUNCTION__, hpc_ptr->buses[index].bus_num);
+		}
+
+		debug ("%s - type of hpc: %x\n", __FUNCTION__, hpc_ptr->ctlr_type);
+		switch (hpc_ptr->ctlr_type) {
+		case 1:
+			debug ("%s - bus: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.bus);
+			debug ("%s - dev_fun: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.dev_fun);
+			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
+			break;
+
+		case 0:
+			debug ("%s - io_start: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_start);
+			debug ("%s - io_end: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_end);
+			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
+			break;
+
+		case 2:
+			debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
+			debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
+			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
+			break;
+		}
+	}
+}
+
+int ibmphp_access_ebda (void)
+{
+	u8 format, num_ctlrs, rio_complete, hs_complete;
+	u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, rc, re, rc_id, re_id, base;
+
+
+	rio_complete = 0;
+	hs_complete = 0;
+
+	io_mem = ioremap ((0x40 << 4) + 0x0e, 2);
+	if (!io_mem )
+		return -ENOMEM;
+	ebda_seg = readw (io_mem);
+	iounmap (io_mem);
+	debug ("returned ebda segment: %x\n", ebda_seg);
+	
+	io_mem = ioremap (ebda_seg<<4, 65000);
+	if (!io_mem )
+		return -ENOMEM;
+	next_offset = 0x180;
+
+	for (;;) {
+		offset = next_offset;
+		next_offset = readw (io_mem + offset);	/* offset of next blk */
+
+		offset += 2;
+		if (next_offset == 0)	/* 0 indicate it's last blk */
+			break;
+		blk_id = readw (io_mem + offset);	/* this blk id */
+
+		offset += 2;
+		/* check if it is hot swap block or rio block */
+		if (blk_id != 0x4853 && blk_id != 0x4752)
+			continue;
+		/* found hs table */
+		if (blk_id == 0x4853) {
+			debug ("now enter hot swap block---\n");
+			debug ("hot blk id: %x\n", blk_id);
+			format = readb (io_mem + offset);
+
+			offset += 1;
+			if (format != 4) {
+				iounmap (io_mem);
+				return -ENODEV;
+			}
+			debug ("hot blk format: %x\n", format);
+			/* hot swap sub blk */
+			base = offset;
+
+			sub_addr = base;
+			re = readw (io_mem + sub_addr);	/* next sub blk */
+
+			sub_addr += 2;
+			rc_id = readw (io_mem + sub_addr); 	/* sub blk id */
+
+			sub_addr += 2;
+			if (rc_id != 0x5243) {
+				iounmap (io_mem);
+				return -ENODEV;
+			}
+			/* rc sub blk signature  */
+			num_ctlrs = readb (io_mem + sub_addr);
+
+			sub_addr += 1;
+			hpc_list_ptr = alloc_ebda_hpc_list ();
+			if (!hpc_list_ptr) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			hpc_list_ptr->format = format;
+			hpc_list_ptr->num_ctlrs = num_ctlrs;
+			hpc_list_ptr->phys_addr = sub_addr;	/*  offset of RSRC_CONTROLLER blk */
+			debug ("info about hpc descriptor---\n");
+			debug ("hot blk format: %x\n", format);
+			debug ("num of controller: %x\n", num_ctlrs);
+			debug ("offset of hpc data structure enteries: %x\n ", sub_addr);
+
+			sub_addr = base + re;	/* re sub blk */
+			rc = readw (io_mem + sub_addr);	/* next sub blk */
+
+			sub_addr += 2;
+			re_id = readw (io_mem + sub_addr);	/* sub blk id */
+
+			sub_addr += 2;
+			if (re_id != 0x5245) {
+				iounmap (io_mem);
+				return -ENODEV;
+			}
+
+			/* signature of re */
+			num_entries = readw (io_mem + sub_addr);
+
+			sub_addr += 2;	/* offset of RSRC_ENTRIES blk */
+			rsrc_list_ptr = alloc_ebda_rsrc_list ();
+			if (!rsrc_list_ptr ) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			rsrc_list_ptr->format = format;
+			rsrc_list_ptr->num_entries = num_entries;
+			rsrc_list_ptr->phys_addr = sub_addr;
+
+			debug ("info about rsrc descriptor---\n");
+			debug ("format: %x\n", format);
+			debug ("num of rsrc: %x\n", num_entries);
+			debug ("offset of rsrc data structure enteries: %x\n ", sub_addr);
+
+			hs_complete = 1;
+		}
+		/* found rio table */
+		else if (blk_id == 0x4752) {
+			debug ("now enter io table ---\n");
+			debug ("rio blk id: %x\n", blk_id);
+
+			rio_table_ptr = kmalloc (sizeof (struct rio_table_hdr), GFP_KERNEL);
+			if (!rio_table_ptr)
+				return -ENOMEM; 
+			memset (rio_table_ptr, 0, sizeof (struct rio_table_hdr) );
+			rio_table_ptr->ver_num = readb (io_mem + offset);
+			rio_table_ptr->scal_count = readb (io_mem + offset + 1);
+			rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
+			rio_table_ptr->offset = offset +3 ;
+			
+			debug ("info about rio table hdr ---\n");
+			debug ("ver_num: %x\nscal_count: %x\nriodev_count: %x\noffset of rio table: %x\n ", rio_table_ptr->ver_num, rio_table_ptr->scal_count, rio_table_ptr->riodev_count, rio_table_ptr->offset);
+
+			rio_complete = 1;
+		}
+
+		if (hs_complete && rio_complete) {
+			rc = ebda_rsrc_controller ();
+			if (rc) {
+				iounmap(io_mem);
+				return rc;
+			}
+			rc = ebda_rsrc_rsrc ();
+			if (rc) {
+				iounmap(io_mem);
+				return rc;
+			}
+			rc = ebda_rio_table ();
+			if (rc) {
+				iounmap(io_mem);
+				return rc;
+			}	
+			iounmap (io_mem);
+			return 0;
+		}
+	}
+	iounmap (io_mem);
+	return -ENODEV;
+}
+
+
+/*
+ * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
+ * each hpc from physical address to a list of hot plug controllers based on
+ * hpc descriptors.
+ */
+static int ebda_rsrc_controller (void)
+{
+	u16 addr, addr_slot, addr_bus;
+	u8 ctlr_id, temp, bus_index;
+	u16 ctlr, slot, bus;
+	u16 slot_num, bus_num, index;
+	struct hotplug_slot *hp_slot_ptr;
+	struct controller *hpc_ptr;
+	struct ebda_hpc_bus *bus_ptr;
+	struct ebda_hpc_slot *slot_ptr;
+	struct bus_info *bus_info_ptr1, *bus_info_ptr2;
+	int rc;
+
+	addr = hpc_list_ptr->phys_addr;
+	for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
+		bus_index = 1;
+		ctlr_id = readb (io_mem + addr);
+		addr += 1;
+		slot_num = readb (io_mem + addr);
+
+		addr += 1;
+		addr_slot = addr;	/* offset of slot structure */
+		addr += (slot_num * 4);
+
+		bus_num = readb (io_mem + addr);
+
+		addr += 1;
+		addr_bus = addr;	/* offset of bus */
+		addr += (bus_num * 9);	/* offset of ctlr_type */
+		temp = readb (io_mem + addr);
+
+		addr += 1;
+		/* init hpc structure */
+		hpc_ptr = alloc_ebda_hpc (slot_num, bus_num);
+		if (!hpc_ptr ) {
+			iounmap (io_mem);
+			return -ENOMEM;
+		}
+		hpc_ptr->ctlr_id = ctlr_id;
+		hpc_ptr->ctlr_relative_id = ctlr;
+		hpc_ptr->slot_count = slot_num;
+		hpc_ptr->bus_count = bus_num;
+		debug ("now enter ctlr data struture ---\n");
+		debug ("ctlr id: %x\n", ctlr_id);
+		debug ("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
+		debug ("count of slots controlled by this ctlr: %x\n", slot_num);
+		debug ("count of buses controlled by this ctlr: %x\n", bus_num);
+
+		/* init slot structure, fetch slot, bus, cap... */
+		slot_ptr = hpc_ptr->slots;
+		for (slot = 0; slot < slot_num; slot++) {
+			slot_ptr->slot_num = readb (io_mem + addr_slot);
+			slot_ptr->slot_bus_num = readb (io_mem + addr_slot + slot_num);
+			slot_ptr->ctl_index = readb (io_mem + addr_slot + 2*slot_num);
+			slot_ptr->slot_cap = readb (io_mem + addr_slot + 3*slot_num);
+
+			// create bus_info lined list --- if only one slot per bus: slot_min = slot_max 
+
+			bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);
+			if (!bus_info_ptr2) {
+				bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL);
+				if (!bus_info_ptr1) {
+					iounmap (io_mem);
+					return -ENOMEM;
+				}
+				memset (bus_info_ptr1, 0, sizeof (struct bus_info));
+				bus_info_ptr1->slot_min = slot_ptr->slot_num;
+				bus_info_ptr1->slot_max = slot_ptr->slot_num;
+				bus_info_ptr1->slot_count += 1;
+				bus_info_ptr1->busno = slot_ptr->slot_bus_num;
+				bus_info_ptr1->index = bus_index++;
+				bus_info_ptr1->current_speed = 0xff;
+				bus_info_ptr1->current_bus_mode = 0xff;
+				if ( ((slot_ptr->slot_cap) & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX )
+					bus_info_ptr1->supported_speed =  3;
+				else if ( ((slot_ptr->slot_cap) & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX )
+					bus_info_ptr1->supported_speed =  2;
+				else if ( ((slot_ptr->slot_cap) & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX )
+					bus_info_ptr1->supported_speed =  1;
+				bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;
+				if ( ((slot_ptr->slot_cap) & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP )
+					bus_info_ptr1->supported_bus_mode = 1;
+				else
+					bus_info_ptr1->supported_bus_mode =0;
+
+
+				list_add_tail (&bus_info_ptr1->bus_info_list, &bus_info_head);
+
+			} else {
+				bus_info_ptr2->slot_min = min (bus_info_ptr2->slot_min, slot_ptr->slot_num);
+				bus_info_ptr2->slot_max = max (bus_info_ptr2->slot_max, slot_ptr->slot_num);
+				bus_info_ptr2->slot_count += 1;
+
+			}
+
+			// end of creating the bus_info linked list
+
+			slot_ptr++;
+			addr_slot += 1;
+		}
+
+		/* init bus structure */
+		bus_ptr = hpc_ptr->buses;
+		for (bus = 0; bus < bus_num; bus++) {
+			bus_ptr->bus_num = readb (io_mem + addr_bus);
+			bus_ptr++;
+			addr_bus += 1;
+		}
+
+		hpc_ptr->ctlr_type = temp;
+
+		switch (hpc_ptr->ctlr_type) {
+			case 1:
+				hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
+				hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
+				hpc_ptr->irq = readb (io_mem + addr + 2);
+				addr += 3; 
+				break;
+
+			case 0:
+				hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
+				hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
+				hpc_ptr->irq = readb (io_mem + addr + 4);
+				addr += 5;
+				break;
+
+			case 2:
+				hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
+				hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
+				/* following 2 lines for testing purpose */
+				if (hpc_ptr->u.wpeg_ctlr.i2c_addr == 0) 
+					hpc_ptr->ctlr_type = 4;	
+				
+
+				hpc_ptr->irq = readb (io_mem + addr + 5);
+				addr += 6;
+				break;
+			case 4:
+				hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
+				hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
+				hpc_ptr->irq = readb (io_mem + addr + 5);
+				addr += 6;
+				break;
+			default:
+				iounmap (io_mem);
+				return -ENODEV;
+		}
+		/* following 3 line: Now our driver only supports I2c ctlrType */
+		if ((hpc_ptr->ctlr_type != 2) && (hpc_ptr->ctlr_type != 4)) {
+			err ("Please run this driver on ibm xseries440\n ");
+			return -ENODEV;
+		}
+
+		hpc_ptr->revision = 0xff;
+		hpc_ptr->options = 0xff;
+
+		// register slots with hpc core as well as create linked list of ibm slot
+		for (index = 0; index < hpc_ptr->slot_count; index++) {
+
+			hp_slot_ptr = (struct hotplug_slot *) kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
+			if (!hp_slot_ptr) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			memset (hp_slot_ptr, 0, sizeof (struct hotplug_slot));
+
+			hp_slot_ptr->info = (struct hotplug_slot_info *) kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+			if (!hp_slot_ptr->info) {
+				iounmap (io_mem);
+				kfree (hp_slot_ptr);
+				return -ENOMEM;
+			}
+			memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info));
+
+			hp_slot_ptr->name = (char *) kmalloc (10, GFP_KERNEL);
+			if (!hp_slot_ptr->name) {
+				iounmap (io_mem);
+				kfree (hp_slot_ptr->info);
+				kfree (hp_slot_ptr);
+				return -ENOMEM;
+			}
+
+			hp_slot_ptr->private = alloc_ibm_slot ();
+			if (!hp_slot_ptr->private) {
+				iounmap (io_mem);
+				kfree (hp_slot_ptr->name);
+				kfree (hp_slot_ptr->info);
+				kfree (hp_slot_ptr);
+				return -ENOMEM;
+			}
+
+			((struct slot *)hp_slot_ptr->private)->flag = TRUE;
+			snprintf (hp_slot_ptr->name, 10, "%d", hpc_ptr->slots[index].slot_num);
+
+			((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap;
+			((struct slot *) hp_slot_ptr->private)->bus = hpc_ptr->slots[index].slot_bus_num;
+
+			bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num);
+			if (!bus_info_ptr1) {
+				iounmap (io_mem);
+				return -ENODEV;
+			}
+			((struct slot *) hp_slot_ptr->private)->bus_on = bus_info_ptr1;
+			bus_info_ptr1 = NULL;
+			((struct slot *) hp_slot_ptr->private)->ctrl = hpc_ptr;
+
+
+			((struct slot *) hp_slot_ptr->private)->ctlr_index = hpc_ptr->slots[index].ctl_index;
+			((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num;
+
+			((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr;
+
+			rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr);
+			if (rc) {
+				iounmap (io_mem);
+				return rc;
+			}
+
+			rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private);
+			if (rc) {
+				iounmap (io_mem);
+				return rc;
+			}
+			hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
+
+			pci_hp_register (hp_slot_ptr);
+
+			// end of registering ibm slot with hotplug core
+
+			list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
+		}
+
+		print_bus_info ();
+		list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
+
+	}			/* each hpc  */
+	print_ebda_hpc ();
+	return 0;
+}
+
+/* 
+ * map info (bus, devfun, start addr, end addr..) of i/o, memory,
+ * pfm from the physical addr to a list of resource.
+ */
+static int ebda_rsrc_rsrc (void)
+{
+	u16 addr;
+	short rsrc;
+	u8 type, rsrc_type;
+	struct ebda_pci_rsrc *rsrc_ptr;
+
+	addr = rsrc_list_ptr->phys_addr;
+	debug ("now entering rsrc land\n");
+	debug ("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr);
+
+	for (rsrc = 0; rsrc < rsrc_list_ptr->num_entries; rsrc++) {
+		type = readb (io_mem + addr);
+
+		addr += 1;
+		rsrc_type = type & EBDA_RSRC_TYPE_MASK;
+
+		if (rsrc_type == EBDA_IO_RSRC_TYPE) {
+			rsrc_ptr = alloc_ebda_pci_rsrc ();
+			if (!rsrc_ptr) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			rsrc_ptr->rsrc_type = type;
+
+			rsrc_ptr->bus_num = readb (io_mem + addr);
+			rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
+			rsrc_ptr->start_addr = readw (io_mem + addr + 2);
+			rsrc_ptr->end_addr = readw (io_mem + addr + 4);
+			addr += 6;
+
+			debug ("rsrc from io type ----\n");
+			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n",
+				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
+
+			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
+		}
+
+		if (rsrc_type == EBDA_MEM_RSRC_TYPE || rsrc_type == EBDA_PFM_RSRC_TYPE) {
+			rsrc_ptr = alloc_ebda_pci_rsrc ();
+			if (!rsrc_ptr ) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			rsrc_ptr->rsrc_type = type;
+
+			rsrc_ptr->bus_num = readb (io_mem + addr);
+			rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
+			rsrc_ptr->start_addr = readl (io_mem + addr + 2);
+			rsrc_ptr->end_addr = readl (io_mem + addr + 6);
+			addr += 10;
+
+			debug ("rsrc from mem or pfm ---\n");
+			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", 
+				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
+
+			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
+		}
+	}
+	kfree (rsrc_list_ptr);
+	rsrc_list_ptr = NULL;
+	print_ebda_pci_rsrc ();
+	return 0;
+}
+
+/*
+ * map info of scalability details and rio details from physical address
+ */
+static int ebda_rio_table(void)
+{
+	u16 offset;
+	u8 i;
+	struct scal_detail *scal_detail_ptr;
+	struct rio_detail *rio_detail_ptr;
+
+	offset = rio_table_ptr->offset;
+	for (i = 0; i < rio_table_ptr->scal_count; i++) {
+		
+		scal_detail_ptr = kmalloc (sizeof (struct scal_detail), GFP_KERNEL );
+		if (!scal_detail_ptr )
+			return -ENOMEM;
+		memset (scal_detail_ptr, 0, sizeof (struct scal_detail) );
+		scal_detail_ptr->node_id = readb (io_mem + offset);
+		scal_detail_ptr->cbar = readl (io_mem+ offset + 1);
+		scal_detail_ptr->port0_node_connect = readb (io_mem + 5);
+		scal_detail_ptr->port0_port_connect = readb (io_mem + 6);
+		scal_detail_ptr->port1_node_connect = readb (io_mem + 7);
+		scal_detail_ptr->port1_port_connect = readb (io_mem + 8);
+		scal_detail_ptr->port2_node_connect = readb (io_mem + 9);
+		scal_detail_ptr->port2_port_connect = readb (io_mem + 10);
+		debug ("node_id: %x\ncbar: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nport2_node: %x\nport2_port: %x\n", scal_detail_ptr->node_id, scal_detail_ptr->cbar, scal_detail_ptr->port0_node_connect, scal_detail_ptr->port0_port_connect, scal_detail_ptr->port1_node_connect, scal_detail_ptr->port1_port_connect, scal_detail_ptr->port2_node_connect, scal_detail_ptr->port2_port_connect);
+//		list_add (&scal_detail_ptr->scal_detail_list, &scal_detail_head);
+		offset += 11;
+	}
+	for (i=0; i < rio_table_ptr->riodev_count; i++) {
+		rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL );
+		if (!rio_detail_ptr )
+			return -ENOMEM;
+		memset (rio_detail_ptr, 0, sizeof (struct rio_detail) );
+		rio_detail_ptr->rio_node_id = readb (io_mem + offset );
+		rio_detail_ptr->bbar = readl (io_mem + offset + 1);
+		rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
+		rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
+		rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
+		rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
+		rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
+		rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
+		rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
+		rio_detail_ptr->status = readb (io_mem + offset + 12);
+		debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
+		offset += 13;
+	}
+	return 0;
+}
+
+u16 ibmphp_get_total_controllers (void)
+{
+	return hpc_list_ptr->num_ctlrs;
+}
+
+struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
+{
+	struct slot *slot;
+	struct list_head *list;
+
+	list_for_each (list, &ibmphp_slot_head) {
+		slot = list_entry (list, struct slot, ibm_slot_list);
+		if (slot->number == physical_num)
+			return slot;
+	}
+	return NULL;
+}
+
+/* To find:
+ *	- the smallest slot number
+ *	- the largest slot number
+ *	- the total number of the slots based on each bus
+ *	  (if only one slot per bus slot_min = slot_max )
+ */
+struct bus_info *ibmphp_find_same_bus_num (u32 num)
+{
+	struct bus_info *ptr;
+	struct list_head  *ptr1;
+
+	list_for_each (ptr1, &bus_info_head) {
+		ptr = list_entry (ptr1, struct bus_info, bus_info_list); 
+		if (ptr->busno == num) 
+			 return ptr;
+	}
+	return NULL;
+}
+
+/*  Finding relative bus number, in order to map corresponding
+ *  bus register
+ */
+int ibmphp_get_bus_index (u8 num)
+{
+	struct bus_info *ptr;
+	struct list_head  *ptr1;
+
+	list_for_each (ptr1, &bus_info_head) {
+		ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+		if (ptr->busno == num)  
+			return ptr->index;
+	}
+	return -ENODEV;
+}
+
+void ibmphp_free_bus_info_queue (void)
+{
+	struct bus_info *bus_info;
+	struct list_head *list;
+	struct list_head *next;
+
+	list_for_each_safe (list, next, &bus_info_head ) {
+		bus_info = list_entry (list, struct bus_info, bus_info_list);
+		kfree (bus_info);
+	}
+}
+
+/*
+ * Calculate the total hot pluggable slots controlled by total hpcs
+ */
+/*
+int ibmphp_get_total_hp_slots (void)
+{
+	struct ebda_hpc *ptr;
+	int slot_num = 0;
+
+	ptr = ebda_hpc_head;
+	while (ptr != NULL) {
+		slot_num += ptr->slot_count;
+		ptr = ptr->next;
+	}
+	return slot_num;
+}
+*/
+
+void ibmphp_free_ebda_hpc_queue (void)
+{
+	struct controller *controller;
+	struct list_head *list;
+	struct list_head *next;
+
+	list_for_each_safe (list, next, &ebda_hpc_head) {
+		controller = list_entry (list, struct controller, ebda_hpc_list);
+		free_ebda_hpc (controller);
+	}
+}
+
+void ibmphp_free_ebda_pci_rsrc_queue (void)
+{
+	struct ebda_pci_rsrc *resource;
+	struct list_head *list;
+	struct list_head *next;
+
+	list_for_each_safe (list, next, &ibmphp_ebda_pci_rsrc_head) {
+		resource = list_entry (list, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+		kfree (resource);
+		resource = NULL;
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/ibmphp_hpc.c linux/drivers/hotplug/ibmphp_hpc.c
--- linux.orig/drivers/hotplug/ibmphp_hpc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/ibmphp_hpc.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,1135 @@
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Jyoti Shah, IBM Corporation
+ *
+ * Copyright (c) 2001,2001 IBM Corp.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *                  <jshah@us.ibm.com>
+ *
+ */
+
+//#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/smp_lock.h>
+#include "ibmphp.h"
+
+#define POLL_NO		0x01
+#define POLL_YES	0x00
+
+static int to_debug = FALSE;
+#define debug_polling(fmt, arg...)	do { if (to_debug) debug (fmt, arg); } while (0)
+
+//----------------------------------------------------------------------------
+// timeout values
+//----------------------------------------------------------------------------
+#define CMD_COMPLETE_TOUT_SEC	60	// give HPC 60 sec to finish cmd
+#define HPC_CTLR_WORKING_TOUT	60	// give HPC 60 sec to finish cmd
+#define HPC_GETACCESS_TIMEOUT	60	// seconds
+#define POLL_INTERVAL_SEC	2	// poll HPC every 2 seconds
+#define POLL_LATCH_CNT		5	// poll latch 5 times, then poll slots
+
+//----------------------------------------------------------------------------
+// Winnipeg Architected Register Offsets
+//----------------------------------------------------------------------------
+#define WPG_I2CMBUFL_OFFSET	0x08	// I2C Message Buffer Low
+#define WPG_I2CMOSUP_OFFSET	0x10	// I2C Master Operation Setup Reg
+#define WPG_I2CMCNTL_OFFSET	0x20	// I2C Master Control Register
+#define WPG_I2CPARM_OFFSET	0x40	// I2C Parameter Register
+#define WPG_I2CSTAT_OFFSET	0x70	// I2C Status Register
+
+//----------------------------------------------------------------------------
+// Winnipeg Store Type commands (Add this commands to the register offset)
+//----------------------------------------------------------------------------
+#define WPG_I2C_AND		0x1000	// I2C AND operation
+#define WPG_I2C_OR		0x2000	// I2C OR operation
+
+//----------------------------------------------------------------------------
+// Command set for I2C Master Operation Setup Regisetr
+//----------------------------------------------------------------------------
+#define WPG_READATADDR_MASK	0x00010000	// read,bytes,I2C shifted,index
+#define WPG_WRITEATADDR_MASK	0x40010000	// write,bytes,I2C shifted,index
+#define WPG_READDIRECT_MASK	0x10010000
+#define WPG_WRITEDIRECT_MASK	0x60010000
+
+
+//----------------------------------------------------------------------------
+// bit masks for I2C Master Control Register
+//----------------------------------------------------------------------------
+#define WPG_I2CMCNTL_STARTOP_MASK	0x00000002	// Start the Operation
+
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+#define WPG_I2C_IOREMAP_SIZE	0x2044	// size of linear address interval
+#define WPG_CTLR_MAX		0x01	// max controllers
+#define WPG_SLOT_MAX		0x06	// max slots
+#define WPG_CTLR_SLOT_MAX	0x06	// max slots per controller
+#define WPG_FIRST_CTLR		0x00	// index of the controller
+
+//----------------------------------------------------------------------------
+// command index
+//----------------------------------------------------------------------------
+#define WPG_1ST_SLOT_INDEX	0x01	// index - 1st slot for ctlr
+#define WPG_CTLR_INDEX		0x0F	// index - ctlr
+#define WPG_1ST_EXTSLOT_INDEX	0x10	// index - 1st ext slot for ctlr
+#define WPG_1ST_BUS_INDEX	0x1F	// index - 1st bus for ctlr
+
+//----------------------------------------------------------------------------
+// macro utilities
+//----------------------------------------------------------------------------
+// if bits 20,22,25,26,27,29,30 are OFF return TRUE
+#define HPC_I2CSTATUS_CHECK(s)	((u8)((s & 0x00000A76) ? FALSE : TRUE))
+
+// return code 0:poll slots, 1-POLL_LATCH_CNT:poll latch register
+#define INCREMENT_POLLCNT(i)	((i < POLL_LATCH_CNT) ? i++ : (i=0))
+//----------------------------------------------------------------------------
+// global variables
+//----------------------------------------------------------------------------
+static int ibmphp_shutdown;
+static int tid_poll;
+static int stop_polling;		// 2 values: poll, don't poll
+static struct semaphore sem_hpcaccess;	// lock access to HPC
+static struct semaphore semOperations;	// lock all operations and
+					// access to data structures
+static struct semaphore sem_exit;	// make sure polling thread goes away
+static struct semaphore sem_poll;	// make sure poll is idle 
+//----------------------------------------------------------------------------
+// local function prototypes
+//----------------------------------------------------------------------------
+static u8 ctrl_read (struct controller *, void *, u8);
+static u8 ctrl_write (struct controller *, void *, u8, u8);
+static u8 hpc_writecmdtoindex (u8, u8);
+static u8 hpc_readcmdtoindex (u8, u8);
+static void get_hpc_access (void);
+static void free_hpc_access (void);
+static void poll_hpc (void);
+static int update_slot (struct slot *, u8);
+static int process_changeinstatus (struct slot *, struct slot *);
+static int process_changeinlatch (u8, u8);
+static int hpc_poll_thread (void *);
+static int hpc_wait_ctlr_notworking (int, struct controller *, void *, u8 *);
+//----------------------------------------------------------------------------
+
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_hpc_initvars
+*
+* Action:  initialize semaphores and variables
+*---------------------------------------------------------------------*/
+void ibmphp_hpc_initvars (void)
+{
+	debug ("%s - Entry\n", __FUNCTION__);
+
+	init_MUTEX (&sem_hpcaccess);
+	init_MUTEX (&semOperations);
+	init_MUTEX_LOCKED (&sem_exit);
+	init_MUTEX_LOCKED (&sem_poll);
+	stop_polling = POLL_YES;
+	to_debug = FALSE;
+	ibmphp_shutdown = FALSE;
+	tid_poll = 0;
+
+	debug ("%s - Exit\n", __FUNCTION__);
+}
+
+/*----------------------------------------------------------------------
+* Name:    ctrl_read
+*
+* Action:  read from HPC over I2C
+*
+*---------------------------------------------------------------------*/
+static u8 ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
+{
+	u8 status;
+	int i;
+	void *wpg_addr;		// base addr + offset
+	ulong wpg_data,		// data to/from WPG LOHI format
+	ultemp, data;		// actual data HILO format
+
+
+	debug_polling ("%s - Entry WPGBbar[%lx] index[%x] \n", __FUNCTION__, (ulong) WPGBbar, index);
+
+	//--------------------------------------------------------------------
+	// READ - step 1
+	// read at address, byte length, I2C address (shifted), index
+	// or read direct, byte length, index
+	if (ctlr_ptr->ctlr_type == 0x02) {
+		data = WPG_READATADDR_MASK;
+		// fill in I2C address
+		ultemp = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr;
+		ultemp = ultemp >> 1;
+		data |= (ultemp << 8);
+
+		// fill in index
+		data |= (ulong) index;
+	} else if (ctlr_ptr->ctlr_type == 0x04) {
+		data = WPG_READDIRECT_MASK;
+
+		// fill in index
+		ultemp = (ulong) index;
+		ultemp = ultemp << 8;
+		data |= ultemp;
+	} else {
+		err ("this controller type is not supported \n");
+		return HPC_ERROR;
+	}
+
+	wpg_data = swab32 (data);	// swap data before writing
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// READ - step 2 : clear the message buffer
+	data = 0x00000000;
+	wpg_data = swab32 (data);
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// READ - step 3 : issue start operation, I2C master control bit 30:ON
+	//                 2020 : [20] OR operation at [20] offset 0x20
+	data = WPG_I2CMCNTL_STARTOP_MASK;
+	wpg_data = swab32 (data);
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) WPG_I2C_OR;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// READ - step 4 : wait until start operation bit clears
+	i = CMD_COMPLETE_TOUT_SEC;
+	while (i) {
+		long_delay (1 * HZ / 100);
+		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET;
+		wpg_data = readl (wpg_addr);
+		data = swab32 (wpg_data);
+		if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
+			break;
+		i--;
+	}
+	if (i == 0) {
+		debug ("%s - Error : WPG timeout\n", __FUNCTION__);
+		return HPC_ERROR;
+	}
+	//--------------------------------------------------------------------
+	// READ - step 5 : read I2C status register
+	i = CMD_COMPLETE_TOUT_SEC;
+	while (i) {
+		long_delay (1 * HZ / 100);
+		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CSTAT_OFFSET;
+		wpg_data = readl (wpg_addr);
+		data = swab32 (wpg_data);
+		if (HPC_I2CSTATUS_CHECK (data))
+			break;
+		i--;
+	}
+	if (i == 0) {
+		debug ("ctrl_read - Exit Error:I2C timeout\n");
+		return HPC_ERROR;
+	}
+
+	//--------------------------------------------------------------------
+	// READ - step 6 : get DATA
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
+	wpg_data = readl (wpg_addr);
+	data = swab32 (wpg_data);
+
+	status = (u8) data;
+
+	debug_polling ("%s - Exit index[%x] status[%x]\n", __FUNCTION__, index, status);
+
+	return (status);
+}
+
+/*----------------------------------------------------------------------
+* Name:    ctrl_write
+*
+* Action:  write to HPC over I2C
+*
+* Return   0 or error codes
+*---------------------------------------------------------------------*/
+static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
+{
+	u8 rc;
+	void *wpg_addr;		// base addr + offset
+	ulong wpg_data,		// data to/from WPG LOHI format 
+	ultemp, data;		// actual data HILO format
+	int i;
+
+
+	debug_polling ("%s - Entry WPGBbar[%lx] index[%x] cmd[%x]\n",
+		       __FUNCTION__, (ulong) WPGBbar, index, cmd);
+
+	rc = 0;
+	//--------------------------------------------------------------------
+	// WRITE - step 1
+	// write at address, byte length, I2C address (shifted), index
+	// or write direct, byte length, index
+	data = 0x00000000;
+
+	if (ctlr_ptr->ctlr_type == 0x02) {
+		data = WPG_WRITEATADDR_MASK;
+		// fill in I2C address
+		ultemp = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr;
+		ultemp = ultemp >> 1;
+		data |= (ultemp << 8);
+
+		// fill in index
+		data |= (ulong) index;
+	} else if (ctlr_ptr->ctlr_type == 0x04) {
+		data = WPG_WRITEDIRECT_MASK;
+
+		// fill in index
+		ultemp = (ulong) index;
+		ultemp = ultemp << 8;
+		data |= ultemp;
+	} else {
+		err ("this controller type is not supported \n");
+		return HPC_ERROR;
+	}
+
+	wpg_data = swab32 (data);	// swap data before writing
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// WRITE - step 2 : clear the message buffer
+	data = 0x00000000 | (ulong) cmd;
+	wpg_data = swab32 (data);
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// WRITE - step 3 : issue start operation,I2C master control bit 30:ON
+	//                 2020 : [20] OR operation at [20] offset 0x20
+	data = WPG_I2CMCNTL_STARTOP_MASK;
+	wpg_data = swab32 (data);
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) WPG_I2C_OR;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// WRITE - step 4 : wait until start operation bit clears
+	i = CMD_COMPLETE_TOUT_SEC;
+	while (i) {
+		long_delay (1 * HZ / 100);
+		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET;
+		wpg_data = readl (wpg_addr);
+		data = swab32 (wpg_data);
+		if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
+			break;
+		i--;
+	}
+	if (i == 0) {
+		debug ("%s - Exit Error:WPG timeout\n", __FUNCTION__);
+		rc = HPC_ERROR;
+	}
+
+	//--------------------------------------------------------------------
+	// WRITE - step 5 : read I2C status register
+	i = CMD_COMPLETE_TOUT_SEC;
+	while (i) {
+		long_delay (1 * HZ / 100);
+		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CSTAT_OFFSET;
+		wpg_data = readl (wpg_addr);
+		data = swab32 (wpg_data);
+		if (HPC_I2CSTATUS_CHECK (data))
+			break;
+		i--;
+	}
+	if (i == 0) {
+		debug ("ctrl_read - Error : I2C timeout\n");
+		rc = HPC_ERROR;
+	}
+
+	debug_polling ("%s Exit rc[%x]\n", __FUNCTION__, rc);
+	return (rc);
+}
+
+/*----------------------------------------------------------------------
+* Name:    hpc_writecmdtoindex()
+*
+* Action:  convert a write command to proper index within a controller
+*
+* Return   index, HPC_ERROR
+*---------------------------------------------------------------------*/
+static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
+{
+	u8 rc;
+
+	switch (cmd) {
+	case HPC_CTLR_ENABLEIRQ:	// 0x00.N.15
+	case HPC_CTLR_CLEARIRQ:	// 0x06.N.15
+	case HPC_CTLR_RESET:	// 0x07.N.15
+	case HPC_CTLR_IRQSTEER:	// 0x08.N.15
+	case HPC_CTLR_DISABLEIRQ:	// 0x01.N.15
+	case HPC_ALLSLOT_ON:	// 0x11.N.15
+	case HPC_ALLSLOT_OFF:	// 0x12.N.15
+		rc = 0x0F;
+		break;
+
+	case HPC_SLOT_OFF:	// 0x02.Y.0-14
+	case HPC_SLOT_ON:	// 0x03.Y.0-14
+	case HPC_SLOT_ATTNOFF:	// 0x04.N.0-14
+	case HPC_SLOT_ATTNON:	// 0x05.N.0-14
+	case HPC_SLOT_BLINKLED:	// 0x13.N.0-14
+		rc = index;
+		break;
+
+	case HPC_BUS_33CONVMODE:
+	case HPC_BUS_66CONVMODE:
+	case HPC_BUS_66PCIXMODE:
+	case HPC_BUS_100PCIXMODE:
+	case HPC_BUS_133PCIXMODE:
+		rc = index + WPG_1ST_BUS_INDEX - 1;
+		break;
+
+	default:
+		err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
+		rc = HPC_ERROR;
+	}
+
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    hpc_readcmdtoindex()
+*
+* Action:  convert a read command to proper index within a controller
+*
+* Return   index, HPC_ERROR
+*---------------------------------------------------------------------*/
+static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
+{
+	u8 rc;
+
+	switch (cmd) {
+	case READ_CTLRSTATUS:
+		rc = 0x0F;
+		break;
+	case READ_SLOTSTATUS:
+	case READ_ALLSTAT:
+		rc = index;
+		break;
+	case READ_EXTSLOTSTATUS:
+		rc = index + WPG_1ST_EXTSLOT_INDEX;
+		break;
+	case READ_BUSSTATUS:
+		rc = index + WPG_1ST_BUS_INDEX - 1;
+		break;
+	case READ_SLOTLATCHLOWREG:
+		rc = 0x28;
+		break;
+	case READ_REVLEVEL:
+		rc = 0x25;
+		break;
+	case READ_HPCOPTIONS:
+		rc = 0x27;
+		break;
+	default:
+		rc = HPC_ERROR;
+	}
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    HPCreadslot()
+*
+* Action:  issue a READ command to HPC
+*
+* Input:   pslot   - can not be NULL for READ_ALLSTAT
+*          pstatus - can be NULL for READ_ALLSTAT
+*
+* Return   0 or error codes
+*---------------------------------------------------------------------*/
+int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
+{
+	void *wpg_bbar;
+	struct controller *ctlr_ptr;
+	struct list_head *pslotlist;
+	u8 index, status;
+	int rc = 0;
+	int busindex;
+
+	debug_polling ("%s - Entry pslot[%lx] cmd[%x] pstatus[%lx]\n",
+		       __FUNCTION__, (ulong) pslot, cmd, (ulong) pstatus);
+
+	if ((pslot == NULL)
+	    || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
+		rc = -EINVAL;
+		err ("%s - Error invalid pointer, rc[%d]\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	if (cmd == READ_BUSSTATUS) {
+		busindex = ibmphp_get_bus_index (pslot->bus);
+		if (busindex < 0) {
+			rc = -EINVAL;
+			err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
+			return rc;
+		} else
+			index = (u8) busindex;
+	} else
+		index = pslot->ctlr_index;
+
+	index = hpc_readcmdtoindex (cmd, index);
+
+	if (index == HPC_ERROR) {
+		rc = -EINVAL;
+		err ("%s - Exit Error:invalid index, rc[%d]\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	ctlr_ptr = pslot->ctrl;
+
+	get_hpc_access ();
+
+	//--------------------------------------------------------------------
+	// map physical address to logical address
+	//--------------------------------------------------------------------
+	wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+
+	//--------------------------------------------------------------------
+	// check controller status before reading
+	//--------------------------------------------------------------------
+	rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
+	if (!rc) {
+		switch (cmd) {
+		case READ_ALLSTAT:
+			// update the slot structure
+			pslot->ctrl->status = status;
+			pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
+						       &status);
+			if (!rc)
+				pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
+
+			break;
+
+		case READ_SLOTSTATUS:
+			// DO NOT update the slot structure
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+
+		case READ_EXTSLOTSTATUS:
+			// DO NOT update the slot structure
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+
+		case READ_CTLRSTATUS:
+			// DO NOT update the slot structure
+			*pstatus = status;
+			break;
+
+		case READ_BUSSTATUS:
+			pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+		case READ_REVLEVEL:
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+		case READ_HPCOPTIONS:
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+		case READ_SLOTLATCHLOWREG:
+			// DO NOT update the slot structure
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+
+			// Not used
+		case READ_ALLSLOT:
+			list_for_each (pslotlist, &ibmphp_slot_head) {
+				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+				index = pslot->ctlr_index;
+				rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr,
+								wpg_bbar, &status);
+				if (!rc) {
+					pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
+					rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT,
+									ctlr_ptr, wpg_bbar, &status);
+					if (!rc)
+						pslot->ext_status =
+						    ctrl_read (ctlr_ptr, wpg_bbar,
+								index + WPG_1ST_EXTSLOT_INDEX);
+				} else {
+					err ("%s - Error ctrl_read failed\n", __FUNCTION__);
+					rc = -EINVAL;
+					break;
+				}
+			}
+			break;
+		default:
+			rc = -EINVAL;
+			break;
+		}
+	}
+	//--------------------------------------------------------------------
+	// cleanup
+	//--------------------------------------------------------------------
+	iounmap (wpg_bbar);	// remove physical to logical address mapping
+	free_hpc_access ();
+
+	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_hpc_writeslot()
+*
+* Action: issue a WRITE command to HPC
+*---------------------------------------------------------------------*/
+int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
+{
+	void *wpg_bbar;
+	struct controller *ctlr_ptr;
+	u8 index, status;
+	int busindex;
+	u8 done;
+	int rc = 0;
+	int timeout;
+
+	debug_polling ("%s - Entry pslot[%lx] cmd[%x]\n", __FUNCTION__, (ulong) pslot, cmd);
+	if (pslot == NULL) {
+		rc = -EINVAL;
+		err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
+		(cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
+		(cmd == HPC_BUS_133PCIXMODE)) {
+		busindex = ibmphp_get_bus_index (pslot->bus);
+		if (busindex < 0) {
+			rc = -EINVAL;
+			err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
+			return rc;
+		} else
+			index = (u8) busindex;
+	} else
+		index = pslot->ctlr_index;
+
+	index = hpc_writecmdtoindex (cmd, index);
+
+	if (index == HPC_ERROR) {
+		rc = -EINVAL;
+		err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	ctlr_ptr = pslot->ctrl;
+
+	get_hpc_access ();
+
+	//--------------------------------------------------------------------
+	// map physical address to logical address
+	//--------------------------------------------------------------------
+	wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+
+	debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
+		ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
+		ctlr_ptr->u.wpeg_ctlr.i2c_addr);
+
+	//--------------------------------------------------------------------
+	// check controller status before writing
+	//--------------------------------------------------------------------
+	rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
+	if (!rc) {
+
+		ctrl_write (ctlr_ptr, wpg_bbar, index, cmd);
+
+		//--------------------------------------------------------------------
+		// check controller is still not working on the command
+		//--------------------------------------------------------------------
+		timeout = CMD_COMPLETE_TOUT_SEC;
+		done = FALSE;
+		while (!done) {
+			rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
+							&status);
+			if (!rc) {
+				if (NEEDTOCHECK_CMDSTATUS (cmd)) {
+					if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
+						done = TRUE;
+				} else
+					done = TRUE;
+			}
+			if (!done) {
+				long_delay (1 * HZ);
+				if (timeout < 1) {
+					done = TRUE;
+					err ("%s - Error command complete timeout\n", __FUNCTION__);
+					rc = -EFAULT;
+				} else
+					timeout--;
+			}
+		}
+		ctlr_ptr->status = status;
+	}
+	// cleanup
+	iounmap (wpg_bbar);	// remove physical to logical address mapping
+	free_hpc_access ();
+
+	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    get_hpc_access()
+*
+* Action: make sure only one process can access HPC at one time
+*---------------------------------------------------------------------*/
+static void get_hpc_access (void)
+{
+	down (&sem_hpcaccess);
+}
+
+/*----------------------------------------------------------------------
+* Name:    free_hpc_access()
+*---------------------------------------------------------------------*/
+void free_hpc_access (void)
+{
+	up (&sem_hpcaccess);
+}
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_lock_operations()
+*
+* Action: make sure only one process can change the data structure
+*---------------------------------------------------------------------*/
+void ibmphp_lock_operations (void)
+{
+	down (&semOperations);
+	stop_polling = POLL_NO;
+	to_debug = TRUE;
+
+	/* waiting for polling to actually stop */
+	down (&sem_poll);
+}
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_unlock_operations()
+*---------------------------------------------------------------------*/
+void ibmphp_unlock_operations (void)
+{
+	debug ("%s - Entry\n", __FUNCTION__);
+	stop_polling = POLL_YES;
+	to_debug = FALSE;
+	up (&semOperations);
+	debug ("%s - Exit\n", __FUNCTION__);
+}
+
+/*----------------------------------------------------------------------
+* Name:    poll_hpc()
+*---------------------------------------------------------------------*/
+static void poll_hpc (void)
+{
+	struct slot myslot, *pslot = NULL;
+	struct list_head *pslotlist;
+	int rc;
+	u8 oldlatchlow = 0x00;
+	u8 curlatchlow = 0x00;
+	int pollcnt = 0;
+	u8 ctrl_count = 0x00;
+
+	debug ("poll_hpc - Entry\n");
+
+	while (!ibmphp_shutdown) {
+		if (stop_polling) {
+			debug ("poll_hpc - stop_polling\n");
+			up (&sem_poll); 
+			/* to prevent deadlock */
+			if (ibmphp_shutdown)
+				break;
+			/* to make the thread sleep */
+			down (&semOperations);
+			up (&semOperations);
+			debug ("poll_hpc - after stop_polling sleep\n");
+		} else {
+			if (pollcnt) {
+				// only poll the latch register
+				oldlatchlow = curlatchlow;
+
+				ctrl_count = 0x00;
+				list_for_each (pslotlist, &ibmphp_slot_head) {
+					if (ctrl_count >= ibmphp_get_total_controllers())
+						break;
+					pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+					if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+						ctrl_count++;
+						if (READ_SLOT_LATCH (pslot->ctrl)) {
+							rc = ibmphp_hpc_readslot (pslot,
+										  READ_SLOTLATCHLOWREG,
+										  &curlatchlow);
+							if (oldlatchlow != curlatchlow)
+								process_changeinlatch (oldlatchlow,
+											curlatchlow);
+						}
+					}
+				}
+			} else {
+				list_for_each (pslotlist, &ibmphp_slot_head) {
+					if (stop_polling)
+						break;
+					pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+					// make a copy of the old status
+					memcpy ((void *) &myslot, (void *) pslot,
+						sizeof (struct slot));
+					rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+					if ((myslot.status != pslot->status)
+					    || (myslot.ext_status != pslot->ext_status))
+						process_changeinstatus (pslot, &myslot);
+				}
+
+				if (!stop_polling) {
+					ctrl_count = 0x00;
+					list_for_each (pslotlist, &ibmphp_slot_head) {
+						if (ctrl_count >= ibmphp_get_total_controllers())
+							break;
+						pslot =
+						    list_entry (pslotlist, struct slot,
+								ibm_slot_list);
+						if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+							ctrl_count++;
+							if (READ_SLOT_LATCH (pslot->ctrl))
+								rc = ibmphp_hpc_readslot (pslot,
+											  READ_SLOTLATCHLOWREG,
+											  &curlatchlow);
+						}
+					}
+				}
+			}
+			INCREMENT_POLLCNT (pollcnt);
+			long_delay (POLL_INTERVAL_SEC * HZ);	// snooze
+		}
+	}
+	up (&sem_poll);
+	up (&sem_exit);
+	debug ("poll_hpc - Exit\n");
+}
+
+
+/* ----------------------------------------------------------------------
+ *  Name:    ibmphp_hpc_fillhpslotinfo(hotplug_slot * phpslot)
+ *
+ *  Action:  fill out the hotplug_slot info
+ *
+ *  Input:   pointer to hotplug_slot
+ *
+ *  Return
+ *  Value:   0 or error codes
+ *-----------------------------------------------------------------------*/
+int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *phpslot)
+{
+	int rc = 0;
+	struct slot *pslot;
+
+	if (phpslot && phpslot->private) {
+		pslot = (struct slot *) phpslot->private;
+		rc = update_slot (pslot, (u8) TRUE);
+		if (!rc) {
+
+			// power - enabled:1  not:0
+			phpslot->info->power_status = SLOT_POWER (pslot->status);
+
+			// attention - off:0, on:1, blinking:2
+			phpslot->info->attention_status = SLOT_ATTN (pslot->status, pslot->ext_status);
+
+			// latch - open:1 closed:0
+			phpslot->info->latch_status = SLOT_LATCH (pslot->status);
+
+			// pci board - present:1 not:0
+			if (SLOT_PRESENT (pslot->status))
+				phpslot->info->adapter_status = 1;
+			else
+				phpslot->info->adapter_status = 0;
+/*
+			if (pslot->bus_on->supported_bus_mode
+				&& (pslot->bus_on->supported_speed == BUS_SPEED_66))
+				phpslot->info->max_bus_speed_status = BUS_SPEED_66PCIX;
+			else
+				phpslot->info->max_bus_speed_status = pslot->bus_on->supported_speed;
+*/		} else
+			rc = -EINVAL;
+	} else
+		rc = -EINVAL;
+
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    update_slot
+*
+* Action:  fill out slot status and extended status, controller status
+*
+* Input:   pointer to slot struct
+*---------------------------------------------------------------------*/
+static int update_slot (struct slot *pslot, u8 update)
+{
+	int rc = 0;
+
+	debug ("%s - Entry pslot[%lx]\n", __FUNCTION__, (ulong) pslot);
+	rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+	debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    process_changeinstatus
+*
+* Action:  compare old and new slot status, process the change in status
+*
+* Input:   pointer to slot struct, old slot struct
+*
+* Return   0 or error codes
+* Value:
+*
+* Side
+* Effects: None.
+*
+* Notes:
+*---------------------------------------------------------------------*/
+static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
+{
+	u8 status;
+	int rc = 0;
+	u8 disable = FALSE;
+	u8 update = FALSE;
+
+	debug ("process_changeinstatus - Entry pslot[%lx], poldslot[%lx]\n", (ulong) pslot,
+	       (ulong) poldslot);
+
+	// bit 0 - HPC_SLOT_POWER
+	if ((pslot->status & 0x01) != (poldslot->status & 0x01))
+		/* ????????? DO WE NEED TO UPDATE BUS SPEED INFO HERE ??? */
+		update = TRUE;
+
+	// bit 1 - HPC_SLOT_CONNECT
+	// ignore
+
+	// bit 2 - HPC_SLOT_ATTN
+	if ((pslot->status & 0x04) != (poldslot->status & 0x04))
+		update = TRUE;
+
+	// bit 3 - HPC_SLOT_PRSNT2
+	// bit 4 - HPC_SLOT_PRSNT1
+	if (((pslot->status & 0x08) != (poldslot->status & 0x08))
+		|| ((pslot->status & 0x10) != (poldslot->status & 0x10)))
+		update = TRUE;
+
+	// bit 5 - HPC_SLOT_PWRGD
+	if ((pslot->status & 0x20) != (poldslot->status & 0x20))
+		// OFF -> ON: ignore, ON -> OFF: disable slot
+		if (poldslot->status & 0x20)
+			disable = TRUE;
+
+	// bit 6 - HPC_SLOT_BUS_SPEED
+	// ignore
+
+	// bit 7 - HPC_SLOT_LATCH
+	if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
+		update = TRUE;
+		// OPEN -> CLOSE
+		if (pslot->status & 0x80) {
+			if (SLOT_POWER (pslot->status)) {
+				// power goes on and off after closing latch
+				// check again to make sure power is still ON
+				long_delay (1 * HZ);
+				rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
+				if (SLOT_POWER (status))
+					update = TRUE;
+				else	// overwrite power in pslot to OFF
+					pslot->status &= ~HPC_SLOT_POWER;
+			}
+		}
+		// CLOSE -> OPEN 
+		else if ((SLOT_POWER (poldslot->status) == HPC_SLOT_POWER_ON)
+			|| (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED)) {
+			disable = TRUE;
+		}
+		// else - ignore
+	}
+	// bit 4 - HPC_SLOT_BLINK_ATTN
+	if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
+		update = TRUE;
+
+	if (disable) {
+		debug ("process_changeinstatus - disable slot\n");
+		pslot->flag = FALSE;
+		rc = ibmphp_disable_slot (pslot->hotplug_slot);
+	}
+
+	if (update || disable) {
+		ibmphp_update_slot_info (pslot);
+	}
+
+	debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __FUNCTION__, rc, disable, update);
+
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    process_changeinlatch
+*
+* Action:  compare old and new latch reg status, process the change
+*
+* Input:   old and current latch register status
+*
+* Return   0 or error codes
+* Value:
+*---------------------------------------------------------------------*/
+static int process_changeinlatch (u8 old, u8 new)
+{
+	struct slot myslot, *pslot;
+	u8 i;
+	u8 mask;
+	int rc = 0;
+
+	debug ("%s - Entry old[%x], new[%x]\n", __FUNCTION__, old, new);
+	// bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
+
+	for (i = 1; i <= 6; i++) {
+		mask = 0x01 << i;
+		if ((mask & old) != (mask & new)) {
+			pslot = ibmphp_get_slot_from_physical_num (i);
+			if (pslot) {
+				memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+				rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+				debug ("%s - call process_changeinstatus for slot[%d]\n", __FUNCTION__, i);
+				process_changeinstatus (pslot, &myslot);
+			} else {
+				rc = -EINVAL;
+				err ("%s - Error bad pointer for slot[%d]\n", __FUNCTION__, i);
+			}
+		}
+	}
+	debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    hpc_poll_thread
+*
+* Action:  polling
+*
+* Return   0
+* Value:
+*---------------------------------------------------------------------*/
+static int hpc_poll_thread (void *data)
+{
+	debug ("%s - Entry\n", __FUNCTION__);
+	lock_kernel ();
+	daemonize ();
+	reparent_to_init ();
+
+	//  New name
+	strcpy (current->comm, "hpc_poll");
+
+	unlock_kernel ();
+
+	poll_hpc ();
+
+	tid_poll = 0;
+	debug ("%s - Exit\n", __FUNCTION__);
+	return 0;
+}
+
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_hpc_start_poll_thread
+*
+* Action:  start polling thread
+*---------------------------------------------------------------------*/
+int ibmphp_hpc_start_poll_thread (void)
+{
+	int rc = 0;
+
+	debug ("ibmphp_hpc_start_poll_thread - Entry\n");
+
+	tid_poll = kernel_thread (hpc_poll_thread, 0, 0);
+	if (tid_poll < 0) {
+		err ("ibmphp_hpc_start_poll_thread - Error, thread not started\n");
+		rc = -1;
+	}
+
+	debug ("ibmphp_hpc_start_poll_thread - Exit tid_poll[%d] rc[%d]\n", tid_poll, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_hpc_stop_poll_thread
+*
+* Action:  stop polling thread and cleanup
+*---------------------------------------------------------------------*/
+void ibmphp_hpc_stop_poll_thread (void)
+{
+	debug ("ibmphp_hpc_stop_poll_thread - Entry\n");
+
+	ibmphp_shutdown = TRUE;
+	ibmphp_lock_operations ();
+
+	// wait for poll thread to exit
+	down (&sem_exit);
+
+	// cleanup
+	free_hpc_access ();
+	ibmphp_unlock_operations ();
+	up (&sem_poll);
+	up (&sem_exit);
+
+	debug ("ibmphp_hpc_stop_poll_thread - Exit\n");
+}
+
+/*----------------------------------------------------------------------
+* Name:    hpc_wait_ctlr_notworking
+*
+* Action:  wait until the controller is in a not working state
+*
+* Return   0, HPC_ERROR
+* Value:
+*---------------------------------------------------------------------*/
+static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void *wpg_bbar,
+				    u8 * pstatus)
+{
+	int rc = 0;
+	u8 done = FALSE;
+
+	debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
+
+	while (!done) {
+		*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
+		if (*pstatus == HPC_ERROR) {
+			rc = HPC_ERROR;
+			done = TRUE;
+		}
+		if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
+			done = TRUE;
+		if (!done) {
+			long_delay (1 * HZ);
+			if (timeout < 1) {
+				done = TRUE;
+				err ("HPCreadslot - Error ctlr timeout\n");
+				rc = HPC_ERROR;
+			} else
+				timeout--;
+		}
+	}
+	debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
+	return rc;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/ibmphp_pci.c linux/drivers/hotplug/ibmphp_pci.c
--- linux.orig/drivers/hotplug/ibmphp_pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/ibmphp_pci.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,1719 @@
+/*
+ * IBM Hot Plug Controller Driver
+ * 
+ * Written By: Irene Zubarev, IBM Corporation
+ * 
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include "ibmphp.h"
+
+
+static int configure_device(struct pci_func *);
+static int configure_bridge(struct pci_func **, u8);
+static struct res_needed *scan_behind_bridge(struct pci_func *, u8);
+static int add_new_bus (struct bus_node *, struct resource_node *, struct resource_node *, struct resource_node *, u8);
+static u8 find_sec_number (u8 primary_busno, u8 slotno);
+
+/*
+ * NOTE..... If BIOS doesn't provide default routing, we assign:
+ * 9 for SCSI, 10 for LAN adapters, and 11 for everything else. 
+ * If adapter is bridged, then we assign 11 to it and devices behind it.
+ * We also assign the same irq numbers for multi function devices.
+ * These are PIC mode, so shouldn't matter n.e.ways (hopefully)
+ */
+static void assign_alt_irq (struct pci_func * cur_func, u8 class_code)
+{
+	int j = 0;
+	for (j = 0; j < 4; j++) {
+		if (cur_func->irq[j] == 0xff) {
+			switch (class_code) {
+				case PCI_BASE_CLASS_STORAGE:
+					cur_func->irq[j] = SCSI_IRQ;
+					break;
+				case PCI_BASE_CLASS_NETWORK:
+					cur_func->irq[j] = LAN_IRQ;
+					break;
+				default:
+					cur_func->irq[j] = OTHER_IRQ;
+					break;
+			}
+		}
+	}
+}
+
+/*
+ * Configures the device to be added (will allocate needed resources if it
+ * can), the device can be a bridge or a regular pci device, can also be
+ * multi-functional
+ * 
+ * Input: function to be added
+ * 
+ * TO DO:  The error case with Multifunction device or multi function bridge,
+ * if there is an error, will need to go through all previous functions and 
+ * unconfigure....or can add some code into unconfigure_card....
+ */
+int ibmphp_configure_card (struct pci_func *func, u8 slotno)
+{
+	u16 vendor_id;
+	u32 class;
+	u8 class_code;
+	u8 hdr_type, device, sec_number;
+	u8 function;
+	struct pci_func *newfunc;	/* for multi devices */
+	struct pci_func *cur_func, *prev_func;
+	int rc, i, j;
+	int cleanup_count;
+	u8 flag;
+	u8 valid_device = 0x00; /* to see if we are able to read from card any device info at all */
+
+	debug ("inside configure_card, func->busno = %x \n", func->busno);
+
+	device = func->device;
+	cur_func = func;
+
+	/* We only get bus and device from IRQ routing table.  So at this point,
+	 * func->busno is correct, and func->device contains only device (at the 5 
+	 * highest bits)
+	 */
+
+	/* For every function on the card */
+	for (function = 0x00; function < 0x08; function++) {
+		cur_func->function = function;
+
+		debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n", cur_func->busno, device, function);
+
+		pci_read_config_word_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_VENDOR_ID, &vendor_id);
+
+		debug ("vendor_id is %x\n", vendor_id);
+		if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
+			/* found correct device!!! */
+			debug ("found valid device, vendor_id = %x\n", vendor_id);
+
+			++valid_device;
+
+			/* header: x x x x x x x x
+			 *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
+			 *         |_=> 0 = single function device, 1 = multi-function device
+			 */
+
+			pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_HEADER_TYPE, &hdr_type);
+			pci_read_config_dword_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_CLASS_REVISION, &class);
+
+			class_code = class >> 24;
+			debug ("hrd_type = %x, class = %x, class_code %x \n", hdr_type, class, class_code);
+			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
+			if (class == PCI_CLASS_NOT_DEFINED_VGA) {
+				err ("The device %x is VGA compatible and as is not supported for hot plugging. "
+				     "Please choose another device.\n", cur_func->device);
+				return -ENODEV;
+			} else if (class == PCI_CLASS_DISPLAY_VGA) {
+				err ("The device %x is not supported for hot plugging. "
+				     "Please choose another device.\n", cur_func->device);
+				return -ENODEV;
+			}
+			switch (hdr_type) {
+				case PCI_HEADER_TYPE_NORMAL:
+					debug ("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class);
+					assign_alt_irq (cur_func, class_code);
+					if ((rc = configure_device (cur_func)) < 0) {
+						/* We need to do this in case some other BARs were properly inserted */
+						err ("was not able to configure devfunc %x on bus %x. \n",
+						     cur_func->device, cur_func->busno);
+						cleanup_count = 6;
+						goto error;
+					}	
+					cur_func->next = NULL;
+					function = 0x8;
+					break;
+				case PCI_HEADER_TYPE_MULTIDEVICE:
+					assign_alt_irq (cur_func, class_code);
+					if ((rc = configure_device (cur_func)) < 0) {
+						/* We need to do this in case some other BARs were properly inserted */
+						err ("was not able to configure devfunc %x on bus %x...bailing out\n",
+						     cur_func->device, cur_func->busno);
+						cleanup_count = 6;
+						goto error;
+					}
+					newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+					if (!newfunc) {
+						err ("out of system memory \n");
+						return -ENOMEM;
+					}
+					memset (newfunc, 0, sizeof (struct pci_func));
+					newfunc->busno = cur_func->busno;
+					newfunc->device = device;
+					cur_func->next = newfunc;
+					cur_func = newfunc;
+					for (j = 0; j < 4; j++)
+						newfunc->irq[j] = cur_func->irq[j];
+					break;
+				case PCI_HEADER_TYPE_MULTIBRIDGE:
+					class >>= 8;
+					if (class != PCI_CLASS_BRIDGE_PCI) {
+						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
+						     "Please insert another card.\n", cur_func->device);
+						return -ENODEV;
+					}
+					assign_alt_irq (cur_func, class_code);
+					rc = configure_bridge (&cur_func, slotno);
+					if (rc == -ENODEV) {
+						err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
+						err ("Bus %x, devfunc %x \n", cur_func->busno, cur_func->device);
+						return rc;
+					}
+					if (rc) {
+						/* We need to do this in case some other BARs were properly inserted */
+						err ("was not able to hot-add PPB properly.\n");
+						func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
+						cleanup_count = 2;
+						goto error;
+					}
+
+					pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_SECONDARY_BUS, &sec_number);
+					flag = FALSE;
+					for (i = 0; i < 32; i++) {
+						if (func->devices[i]) {
+							newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+							if (!newfunc) {
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (newfunc, 0, sizeof (struct pci_func));
+							newfunc->busno = sec_number;
+							newfunc->device = (u8) i;
+							for (j = 0; j < 4; j++)
+								newfunc->irq[j] = cur_func->irq[j];
+
+							if (flag) {
+								for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
+								prev_func->next = newfunc;
+							} else
+								cur_func->next = newfunc;
+
+							rc = ibmphp_configure_card (newfunc, slotno);
+							/* This could only happen if kmalloc failed */
+							if (rc) {
+								/* We need to do this in case bridge itself got configured properly, but devices behind it failed */
+								func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
+								cleanup_count = 2;
+								goto error;
+							}
+							flag = TRUE;
+						}
+					}
+
+					newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+					if (!newfunc) {
+						err ("out of system memory \n");
+						return -ENOMEM;
+					}
+					memset (newfunc, 0, sizeof (struct pci_func));
+					newfunc->busno = cur_func->busno;
+					newfunc->device = device;
+					for (j = 0; j < 4; j++)
+						newfunc->irq[j] = cur_func->irq[j];
+					for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
+					prev_func->next = newfunc;
+					cur_func = newfunc;
+					break;
+				case PCI_HEADER_TYPE_BRIDGE:
+					class >>= 8;
+					debug ("class now is %x\n", class);
+					if (class != PCI_CLASS_BRIDGE_PCI) {
+						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
+						     "Please insert another card.\n", cur_func->device);
+						return -ENODEV;
+					}
+
+					assign_alt_irq (cur_func, class_code);
+
+					debug ("cur_func->busno b4 configure_bridge is %x\n", cur_func->busno);
+					rc = configure_bridge (&cur_func, slotno);
+					if (rc == -ENODEV) {
+						err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
+						err ("Bus %x, devfunc %x \n", cur_func->busno, cur_func->device);
+						return rc;
+					}
+					if (rc) {
+						/* We need to do this in case some other BARs were properly inserted */
+						func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
+						err ("was not able to hot-add PPB properly.\n");
+						cleanup_count = 2;
+						goto error;
+					}
+					debug ("cur_func->busno = %x, device = %x, function = %x\n", cur_func->busno, device, function);
+					pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_SECONDARY_BUS, &sec_number);
+					debug ("after configuring bridge..., sec_number = %x\n", sec_number);
+					flag = FALSE;
+					for (i = 0; i < 32; i++) {
+						if (func->devices[i]) {
+							debug ("inside for loop, device is %x\n", i);
+							newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+							if (!newfunc) {
+								err (" out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (newfunc, 0, sizeof (struct pci_func));
+							newfunc->busno = sec_number;
+							newfunc->device = (u8) i;
+							for (j = 0; j < 4; j++)
+								newfunc->irq[j] = cur_func->irq[j];
+
+							if (flag) {
+								for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
+								prev_func->next = newfunc;
+							} else
+								cur_func->next = newfunc;
+
+							rc = ibmphp_configure_card (newfunc, slotno);
+
+							/* Again, this case should not happen... For complete paranoia, will need to call remove_bus */
+							if (rc) {
+								/* We need to do this in case some other BARs were properly inserted */
+								func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
+								cleanup_count = 2;
+								goto error;
+							}
+							flag = TRUE;
+						}
+					}
+
+					function = 0x8;
+					break;
+				default:
+					err ("MAJOR PROBLEM!!!!, header type not supported? %x\n", hdr_type);
+					return -ENXIO;
+					break;
+			}	/* end of switch */
+		}	/* end of valid device */
+	}	/* end of for */
+
+	if (!valid_device) {
+		err ("Cannot find any valid devices on the card.  Or unable to read from card.\n");
+		return -ENODEV;
+	}
+
+	return 0;
+
+error:
+	for (i = 0; i < cleanup_count; i++) {
+		if (cur_func->io[i]) {
+			ibmphp_remove_resource (cur_func->io[i]);
+			cur_func->io[i] = NULL;
+		} else if (cur_func->pfmem[i]) {
+			ibmphp_remove_resource (cur_func->pfmem[i]);
+			cur_func->pfmem[i] = NULL;
+		} else if (cur_func->mem[i]) {
+			ibmphp_remove_resource (cur_func->mem[i]);
+			cur_func->mem[i] = NULL;
+		}
+	}
+	return rc;
+}
+
+/*
+ * This function configures the pci BARs of a single device.  
+ * Input: pointer to the pci_func
+ * Output: configured PCI, 0, or error
+ */
+static int configure_device (struct pci_func *func)
+{
+	u32 bar[6];
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	u8 irq;
+	int count;
+	int len[6];
+	struct resource_node *io[6];
+	struct resource_node *mem[6];
+	struct resource_node *mem_tmp;
+	struct resource_node *pfmem[6];
+	u8 device;
+	u8 function;
+
+	debug ("%s - inside\n", __FUNCTION__);
+
+	device = func->device;
+	function = func->function;
+
+	for (count = 0; address[count]; count++) {	/* for 6 BARs */
+
+		/* not sure if i need this.  per scott, said maybe need smth like this
+		   if devices don't adhere 100% to the spec, so don't want to write
+		   to the reserved bits
+
+		pcibios_read_config_byte(cur_func->busno, cur_func->device, 
+		PCI_BASE_ADDRESS_0 + 4 * count, &tmp);
+		if (tmp & 0x01) // IO
+			pcibios_write_config_dword(cur_func->busno, cur_func->device, 
+			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFD);
+		else  // Memory
+			pcibios_write_config_dword(cur_func->busno, cur_func->device, 
+			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
+		 */
+		pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0xFFFFFFFF);
+		pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]);
+
+		if (!bar[count])	/* This BAR is not implemented */
+			continue;
+
+		debug ("Device %x BAR %d wants %x\n", func->device, count, bar[count]);
+
+		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			debug ("inside IO SPACE\n");
+
+			len[count] = bar[count] & 0xFFFFFFFC;
+			len[count] = ~len[count] + 1;
+
+			debug ("len[count] in IO %x, count %d\n", len[count], count);
+
+			io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+
+			if (!io[count]) {
+				err ("out of system memory \n");
+				return -ENOMEM;
+			}
+			memset (io[count], 0, sizeof (struct resource_node));
+			io[count]->type = IO;
+			io[count]->busno = func->busno;
+			io[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+			io[count]->len = len[count];
+			if (ibmphp_check_resource(io[count], 0) == 0) {
+				ibmphp_add_resource (io[count]);
+				func->io[count] = io[count];
+			} else {
+				err ("cannot allocate requested io for bus %x device %x function %x len %x\n",
+				     func->busno, func->device, func->function, len[count]);
+				kfree (io[count]);
+				return -EIO;
+			}
+			pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->io[count]->start);
+	
+			/* _______________This is for debugging purposes only_____________________ */ 
+			debug ("b4 writing, the IO address is %x\n", func->io[count]->start);
+			pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]);
+			debug ("after writing.... the start address is %x\n", bar[count]);
+			/* _________________________________________________________________________*/
+
+		} else {
+			/* This is Memory */
+			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+				debug ("PFMEM SPACE\n");
+
+				len[count] = bar[count] & 0xFFFFFFF0;
+				len[count] = ~len[count] + 1;
+
+				debug ("len[count] in PFMEM %x, count %d\n", len[count], count);
+
+				pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+				if (!pfmem[count]) {
+					err ("out of system memory \n");
+					return -ENOMEM;
+				}
+				memset (pfmem[count], 0, sizeof (struct resource_node));
+				pfmem[count]->type = PFMEM;
+				pfmem[count]->busno = func->busno;
+				pfmem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				pfmem[count]->len = len[count];
+				pfmem[count]->fromMem = FALSE;
+				if (ibmphp_check_resource (pfmem[count], 0) == 0) {
+					ibmphp_add_resource (pfmem[count]);
+					func->pfmem[count] = pfmem[count];
+				} else {
+					mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+					if (!mem_tmp) {
+						err ("out of system memory \n");
+						kfree (pfmem[count]);
+						return -ENOMEM;
+					}
+					memset (mem_tmp, 0, sizeof (struct resource_node));
+					mem_tmp->type = MEM;
+					mem_tmp->busno = pfmem[count]->busno;
+					mem_tmp->devfunc = pfmem[count]->devfunc;
+					mem_tmp->len = pfmem[count]->len;
+					debug ("there's no pfmem... going into mem.\n");
+					if (ibmphp_check_resource (mem_tmp, 0) == 0) {
+						ibmphp_add_resource (mem_tmp);
+						pfmem[count]->fromMem = TRUE;
+						pfmem[count]->rangeno = mem_tmp->rangeno;
+						pfmem[count]->start = mem_tmp->start;
+						pfmem[count]->end = mem_tmp->end;
+						ibmphp_add_pfmem_from_mem (pfmem[count]);
+						func->pfmem[count] = pfmem[count];
+					} else {
+						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
+						     func->busno, func->device, len[count]);
+						kfree (mem_tmp);
+						kfree (pfmem[count]);
+						return -EIO;
+					}
+				}
+
+				pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->pfmem[count]->start);
+
+				/*_______________This if for debugging purposes only______________________________*/				
+				debug ("b4 writing, start addres is %x\n", func->pfmem[count]->start);
+				pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]);
+				debug ("after writing, start address is %x\n", bar[count]);
+				/*_________________________________________________________________________________*/
+
+				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
+					debug ("inside the mem 64 case, count %d\n", count);
+					count += 1;
+					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
+					pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000);
+				}
+			} else {
+				/* regular memory */
+				debug ("REGULAR MEM SPACE\n");
+
+				len[count] = bar[count] & 0xFFFFFFF0;
+				len[count] = ~len[count] + 1;
+
+				debug ("len[count] in Mem %x, count %d\n", len[count], count);
+
+				mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+				if (!mem[count]) {
+					err ("out of system memory \n");
+					return -ENOMEM;
+				}
+				memset (mem[count], 0, sizeof (struct resource_node));
+				mem[count]->type = MEM;
+				mem[count]->busno = func->busno;
+				mem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				mem[count]->len = len[count];
+				if (ibmphp_check_resource (mem[count], 0) == 0) {
+					ibmphp_add_resource (mem[count]);
+					func->mem[count] = mem[count];
+				} else {
+					err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
+					     func->busno, func->device, len[count]);
+					kfree (mem[count]);
+					return -EIO;
+				}
+				pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->mem[count]->start);
+				/* _______________________This is for debugging purposes only _______________________*/
+				debug ("b4 writing, start address is %x\n", func->mem[count]->start);
+				pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]);
+				debug ("after writing, the address is %x\n", bar[count]);
+				/* __________________________________________________________________________________*/
+
+				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					debug ("inside mem 64 case, reg. mem, count %d\n", count);
+					count += 1;
+					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
+					pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000);
+				}
+			}
+		}		/* end of mem */
+	}			/* end of for */
+
+	func->bus = 0;		/* To indicate that this is not a PPB */
+	pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_PIN, &irq);
+	if ((irq > 0x00) && (irq < 0x05))
+		pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
+
+	pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_CACHE_LINE_SIZE, CACHE);
+	pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_LATENCY_TIMER, LATENCY);
+
+	pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_ROM_ADDRESS, 0x00L);
+	pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_COMMAND, DEVICEENABLE);
+
+	return 0;
+}
+
+/******************************************************************************
+ * This routine configures a PCI-2-PCI bridge and the functions behind it
+ * Parameters: pci_func
+ * Returns: 
+ ******************************************************************************/
+static int configure_bridge (struct pci_func **func_passed, u8 slotno)
+{
+	int count;
+	int i;
+	int rc;
+	u8 sec_number;
+	u8 io_base;
+	u16 pfmem_base;
+	u32 bar[2];
+	u32 len[2];
+	u8 flag_io = FALSE;
+	u8 flag_mem = FALSE;
+	u8 flag_pfmem = FALSE;
+	u8 need_io_upper = FALSE;
+	u8 need_pfmem_upper = FALSE;
+	struct res_needed *amount_needed = NULL;
+	struct resource_node *io = NULL;
+	struct resource_node *bus_io[2] = {NULL, NULL};
+	struct resource_node *mem = NULL;
+	struct resource_node *bus_mem[2] = {NULL, NULL};
+	struct resource_node *mem_tmp = NULL;
+	struct resource_node *pfmem = NULL;
+	struct resource_node *bus_pfmem[2] = {NULL, NULL};
+	struct bus_node *bus;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		0
+	};
+	struct pci_func *func = *func_passed;
+	u8 function;
+	u8 device;
+	u8 irq;
+	int retval;
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	function = func->function;
+	device = func->device;
+
+	/* Configuring necessary info for the bridge so that we could see the devices
+	 * behind it
+	 */
+
+	pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PRIMARY_BUS, func->busno);
+
+	/* _____________________For debugging purposes only __________________________
+	pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PRIMARY_BUS, &pri_number);
+	debug ("primary # written into the bridge is %x\n", pri_number);
+	 ___________________________________________________________________________*/
+
+	/* in EBDA, only get allocated 1 additional bus # per slot */
+	sec_number = find_sec_number (func->busno, slotno);
+	if (sec_number == 0xff) {
+		err ("cannot allocate secondary bus number for the bridged device \n");
+		return -EINVAL;
+	}
+
+	debug ("after find_sec_number, the number we got is %x\n", sec_number);
+	debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
+
+	pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SECONDARY_BUS, sec_number);
+	
+	/* __________________For debugging purposes only __________________________________
+	pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SECONDARY_BUS, &sec_number);
+	debug ("sec_number after write/read is %x\n", sec_number);
+	 ________________________________________________________________________________*/
+
+	pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SUBORDINATE_BUS, sec_number);
+
+	/* __________________For debugging purposes only ____________________________________
+	pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SUBORDINATE_BUS, &sec_number);
+	debug ("subordinate number after write/read is %x\n", sec_number);
+	 __________________________________________________________________________________*/
+
+	pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_CACHE_LINE_SIZE, CACHE);
+	pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_LATENCY_TIMER, LATENCY);
+	pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SEC_LATENCY_TIMER, LATENCY);
+
+	debug ("func->busno is %x\n", func->busno);
+	debug ("sec_number after writing is %x\n", sec_number);
+
+
+	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	   !!!!!!!!!!!!!!!NEED TO ADD!!!  FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!! 
+	   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+
+
+	/* First we need to allocate mem/io for the bridge itself in case it needs it */
+	for (count = 0; address[count]; count++) {	/* for 2 BARs */
+		pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0xFFFFFFFF);
+		pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]);
+
+		if (!bar[count]) {
+			/* This BAR is not implemented */
+			debug ("so we come here then, eh?, count = %d\n", count);
+			continue;
+		}
+		//  tmp_bar = bar[count];
+
+		debug ("Bar %d wants %x\n", count, bar[count]);
+
+		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			len[count] = bar[count] & 0xFFFFFFFC;
+			len[count] = ~len[count] + 1;
+
+			debug ("len[count] in IO = %x\n", len[count]);
+
+			bus_io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		
+			if (!bus_io[count]) {
+				err ("out of system memory \n");
+				retval = -ENOMEM;
+				goto error;
+			}
+			memset (bus_io[count], 0, sizeof (struct resource_node));
+			bus_io[count]->type = IO;
+			bus_io[count]->busno = func->busno;
+			bus_io[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+			bus_io[count]->len = len[count];
+			if (ibmphp_check_resource (bus_io[count], 0) == 0) {
+				ibmphp_add_resource (bus_io[count]);
+				func->io[count] = bus_io[count];
+			} else {
+				err ("cannot allocate requested io for bus %x, device %x, len %x\n",
+				     func->busno, func->device, len[count]);
+				kfree (bus_io[count]);
+				return -EIO;
+			}
+
+			pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->io[count]->start);
+
+		} else {
+			/* This is Memory */
+			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+				len[count] = bar[count] & 0xFFFFFFF0;
+				len[count] = ~len[count] + 1;
+
+				debug ("len[count] in PFMEM = %x\n", len[count]);
+
+				bus_pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+				if (!bus_pfmem[count]) {
+					err ("out of system memory \n");
+					retval = -ENOMEM;
+					goto error;
+				}
+				memset (bus_pfmem[count], 0, sizeof (struct resource_node));
+				bus_pfmem[count]->type = PFMEM;
+				bus_pfmem[count]->busno = func->busno;
+				bus_pfmem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				bus_pfmem[count]->len = len[count];
+				bus_pfmem[count]->fromMem = FALSE;
+				if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {
+					ibmphp_add_resource (bus_pfmem[count]);
+					func->pfmem[count] = bus_pfmem[count];
+				} else {
+					mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+					if (!mem_tmp) {
+						err ("out of system memory \n");
+						retval = -ENOMEM;
+						goto error;
+					}
+					memset (mem_tmp, 0, sizeof (struct resource_node));
+					mem_tmp->type = MEM;
+					mem_tmp->busno = bus_pfmem[count]->busno;
+					mem_tmp->devfunc = bus_pfmem[count]->devfunc;
+					mem_tmp->len = bus_pfmem[count]->len;
+					if (ibmphp_check_resource (mem_tmp, 0) == 0) {
+						ibmphp_add_resource (mem_tmp);
+						bus_pfmem[count]->fromMem = TRUE;
+						bus_pfmem[count]->rangeno = mem_tmp->rangeno;
+						ibmphp_add_pfmem_from_mem (bus_pfmem[count]);
+						func->pfmem[count] = bus_pfmem[count];
+					} else {
+						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n", 
+						     func->busno, func->device, len[count]);
+						kfree (mem_tmp);
+						kfree (bus_pfmem[count]);
+						return -EIO;
+					}
+				}
+
+				pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->pfmem[count]->start);
+
+				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
+					pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000);
+
+				}
+			} else {
+				/* regular memory */
+				len[count] = bar[count] & 0xFFFFFFF0;
+				len[count] = ~len[count] + 1;
+
+				debug ("len[count] in Memory is %x\n", len[count]);
+
+				bus_mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+				if (!bus_mem[count]) {
+					err ("out of system memory \n");
+					retval = -ENOMEM;
+					goto error;
+				}
+				memset (bus_mem[count], 0, sizeof (struct resource_node));
+				bus_mem[count]->type = MEM;
+				bus_mem[count]->busno = func->busno;
+				bus_mem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				bus_mem[count]->len = len[count];
+				if (ibmphp_check_resource (bus_mem[count], 0) == 0) {
+					ibmphp_add_resource (bus_mem[count]);
+					func->mem[count] = bus_mem[count];
+				} else {
+					err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
+					     func->busno, func->device, len[count]);
+					kfree (bus_mem[count]);
+					return -EIO;
+				}
+
+				pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->mem[count]->start);
+
+				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
+					pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000);
+
+				}
+			}
+		}		/* end of mem */
+	}			/* end of for  */
+
+	/* Now need to see how much space the devices behind the bridge needed */
+	amount_needed = scan_behind_bridge (func, sec_number);
+	if (amount_needed == NULL)
+		return -ENOMEM;
+
+	debug ("after coming back from scan_behind_bridge\n");
+	debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
+	debug ("amount_needed->io = %x\n", amount_needed->io);
+	debug ("amount_needed->mem = %x\n", amount_needed->mem);
+	debug ("amount_needed->pfmem =  %x\n", amount_needed->pfmem);
+
+	if (amount_needed->not_correct) {		
+		debug ("amount_needed is not correct \n");
+		for (count = 0; address[count]; count++) {
+			/* for 2 BARs */
+			if (bus_io[count]) {
+				ibmphp_remove_resource (bus_io[count]);
+				func->io[count] = NULL;
+			} else if (bus_pfmem[count]) {
+				ibmphp_remove_resource (bus_pfmem[count]);
+				func->pfmem[count] = NULL;
+			} else if (bus_mem[count]) {
+				ibmphp_remove_resource (bus_mem[count]);
+				func->mem[count] = NULL;
+			}
+		}
+		kfree (amount_needed);
+		return -ENODEV;
+	}
+
+	if (!amount_needed->io) {
+		debug ("it doesn't want IO?\n");
+		flag_io = TRUE;
+	} else {
+		debug ("it wants %x IO behind the bridge \n", amount_needed->io);
+		io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		
+		if (!io) {
+			err ("out of system memory \n");
+			retval = -ENOMEM;
+			goto error;
+		}
+		memset (io, 0, sizeof (struct resource_node));
+		io->type = IO;
+		io->busno = func->busno;
+		io->devfunc = ((func->device << 3) | (func->function & 0x7));
+		io->len = amount_needed->io;
+		if (ibmphp_check_resource (io, 1) == 0) {
+			debug ("were we able to add io\n");
+			ibmphp_add_resource (io);
+			flag_io = TRUE;
+		}
+	}
+
+	if (!amount_needed->mem) {
+		debug ("it doesn't want n.e.memory?\n");
+		flag_mem = TRUE;
+	} else {
+		debug ("it wants %x memory behind the bridge\n", amount_needed->mem);
+		mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		if (!mem) {
+			err ("out of system memory \n");
+			retval = -ENOMEM;
+			goto error;
+		}
+		memset (mem, 0, sizeof (struct resource_node));
+		mem->type = MEM;
+		mem->busno = func->busno;
+		mem->devfunc = ((func->device << 3) | (func->function & 0x7));
+		mem->len = amount_needed->mem;
+		if (ibmphp_check_resource (mem, 1) == 0) {
+			ibmphp_add_resource (mem);
+			flag_mem = TRUE;
+			debug ("were we able to add mem\n");
+		}
+	}
+
+	if (!amount_needed->pfmem) {
+		debug ("it doesn't want n.e.pfmem mem?\n");
+		flag_pfmem = TRUE;
+	} else {
+		debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
+		pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		if (!pfmem) {
+			err ("out of system memory \n");
+			retval = -ENOMEM;
+			goto error;
+		}
+		memset (pfmem, 0, sizeof (struct resource_node));
+		pfmem->type = PFMEM;
+		pfmem->busno = func->busno;
+		pfmem->devfunc = ((func->device << 3) | (func->function & 0x7));
+		pfmem->len = amount_needed->pfmem;
+		pfmem->fromMem = FALSE;
+		if (ibmphp_check_resource (pfmem, 1) == 0) {
+			ibmphp_add_resource (pfmem);
+			flag_pfmem = TRUE;
+		} else {
+			mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+			if (!mem_tmp) {
+				err ("out of system memory \n");
+				retval = -ENOMEM;
+				goto error;
+			}
+			memset (mem_tmp, 0, sizeof (struct resource_node));
+			mem_tmp->type = MEM;
+			mem_tmp->busno = pfmem->busno;
+			mem_tmp->devfunc = pfmem->devfunc;
+			mem_tmp->len = pfmem->len;
+			if (ibmphp_check_resource (mem_tmp, 1) == 0) {
+				ibmphp_add_resource (mem_tmp);
+				pfmem->fromMem = TRUE;
+				pfmem->rangeno = mem_tmp->rangeno;
+				ibmphp_add_pfmem_from_mem (pfmem);
+				flag_pfmem = TRUE;
+			}
+		}
+	}
+
+	debug ("b4 if (flag_io && flag_mem && flag_pfmem)\n");
+	debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
+
+	if (flag_io && flag_mem && flag_pfmem) {
+		bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+		if (!bus) {
+			err ("out of system memory \n");
+			retval = -ENOMEM;
+			goto error;
+		}
+		memset (bus, 0, sizeof (struct bus_node));
+		bus->busno = sec_number;
+		debug ("b4 adding new bus\n");
+		rc = add_new_bus (bus, io, mem, pfmem, func->busno);
+		if (rc) {
+			if (rc == -ENOMEM) {
+				ibmphp_remove_bus (bus, func->busno);
+				return rc;
+			}
+			retval = rc;
+			goto error;
+		}
+		pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, &io_base);
+		pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, &pfmem_base);
+
+		if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
+			debug ("io 32\n");
+			need_io_upper = TRUE;
+		}
+		if ((io_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
+			debug ("pfmem 64\n");
+			need_pfmem_upper = TRUE;
+		}
+
+		if (bus->noIORanges) {
+			pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
+			pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);	
+
+			/* _______________This is for debugging purposes only ____________________
+			pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, &temp);
+			debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
+			pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, &temp);
+			debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
+			 ________________________________________________________________________*/
+
+			if (need_io_upper) {	/* since can't support n.e.ways */
+				pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE_UPPER16, 0x0000);
+				pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT_UPPER16, 0x0000);
+			}
+		} else {
+			pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, 0x00);
+			pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, 0x00);
+		}
+
+		if (bus->noMemRanges) {
+			pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
+			pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
+			
+			/* ____________________This is for debugging purposes only ________________________
+			pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, &temp);
+			debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+			pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, &temp);
+			debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+			 __________________________________________________________________________________*/
+
+		} else {
+			pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, 0xffff);
+			pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, 0x0000);
+		}
+		if (bus->noPFMemRanges) {
+			pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
+			pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
+
+			/* __________________________This is for debugging purposes only _______________________
+			pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, &temp);
+			debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+			pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, &temp);
+			debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+			 ______________________________________________________________________________________*/
+
+			if (need_pfmem_upper) {	/* since can't support n.e.ways */
+				pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_BASE_UPPER32, 0x00000000);
+				pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_LIMIT_UPPER32, 0x00000000);
+			}
+		} else {
+			pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, 0xffff);
+			pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, 0x0000);
+		}
+
+		debug ("b4 writing control information\n");
+
+		pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_PIN, &irq);
+		if ((irq > 0x00) && (irq < 0x05))
+			pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
+		/*    
+		pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, ctrl);
+		pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
+		pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
+		 */
+
+		pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_COMMAND, DEVICEENABLE);
+		pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, 0x07);
+		for (i = 0; i < 32; i++) {
+			if (amount_needed->devices[i]) {
+				debug ("device where devices[i] is 1 = %x\n", i);
+				func->devices[i] = 1;
+			}
+		}
+		func->bus = 1;	/* For unconfiguring, to indicate it's PPB */
+		func_passed = &func;
+		debug ("func->busno b4 returning is %x\n", func->busno);
+		debug ("func->busno b4 returning in the other structure is %x\n", (*func_passed)->busno);
+		kfree (amount_needed);
+		return 0;
+	} else {
+		err ("Configuring bridge was unsuccessful... \n");
+		mem_tmp = NULL;
+		retval = -EIO;
+		goto error;
+	}
+
+error:
+	if (amount_needed)
+		kfree (amount_needed);
+	if (pfmem)
+		ibmphp_remove_resource (pfmem);
+	if (io)
+		ibmphp_remove_resource (io);
+	if (mem)
+		ibmphp_remove_resource (mem);
+	for (i = 0; i < 2; i++) {	/* for 2 BARs */
+		if (bus_io[i]) {
+			ibmphp_remove_resource (bus_io[i]);
+			func->io[i] = NULL;
+		} else if (bus_pfmem[i]) {
+			ibmphp_remove_resource (bus_pfmem[i]);
+			func->pfmem[i] = NULL;
+		} else if (bus_mem[i]) {
+			ibmphp_remove_resource (bus_mem[i]);
+			func->mem[i] = NULL;
+		}
+	}
+	return retval;
+}
+
+/*****************************************************************************
+ * This function adds up the amount of resources needed behind the PPB bridge
+ * and passes it to the configure_bridge function
+ * Input: bridge function
+ * Ouput: amount of resources needed
+ *****************************************************************************/
+static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
+{
+	int count, len[6];
+	u16 vendor_id;
+	u8 hdr_type;
+	u8 device, function;
+	int howmany = 0;	/*this is to see if there are any devices behind the bridge */
+
+	u32 bar[6], class;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	struct res_needed *amount;
+
+	amount = kmalloc (sizeof (struct res_needed), GFP_KERNEL);
+	if (amount == NULL)
+		return NULL;
+	memset (amount, 0, sizeof (struct res_needed));
+
+	debug ("the bus_no behind the bridge is %x\n", busno);
+	debug ("scanning devices behind the bridge...\n");
+	for (device = 0; device < 32; device++) {
+		amount->devices[device] = 0;
+		for (function = 0; function < 8; function++) {
+
+			pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id);
+
+			if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
+				/* found correct device!!! */
+				howmany++;
+
+				pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type);
+				pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_CLASS_REVISION, &class);
+
+				debug ("hdr_type behind the bridge is %x\n", hdr_type);
+				if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
+					err ("embedded bridges not supported for hot-plugging.\n");
+					amount->not_correct = TRUE;
+					return amount;
+				}
+
+				class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
+				if (class == PCI_CLASS_NOT_DEFINED_VGA) {
+					err ("The device %x is VGA compatible and as is not supported for hot plugging. "
+					     "Please choose another device.\n", device);
+					amount->not_correct = TRUE;
+					return amount;
+				} else if (class == PCI_CLASS_DISPLAY_VGA) {
+					err ("The device %x is not supported for hot plugging. "
+					     "Please choose another device.\n", device);
+					amount->not_correct = TRUE;
+					return amount;
+				}
+
+				amount->devices[device] = 1;
+
+				for (count = 0; address[count]; count++) {
+					/* for 6 BARs */
+					/*
+					pci_read_config_byte_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], &tmp);
+					if (tmp & 0x01) // IO
+						pci_write_config_dword_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFD);
+					else // MEMORY
+						pci_write_config_dword_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF);
+					*/
+					pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF);
+					pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &bar[count]);
+
+					debug ("what is bar[count]? %x, count = %d\n", bar[count], count);
+
+					if (!bar[count])	/* This BAR is not implemented */
+						continue;
+
+					//tmp_bar = bar[count];
+
+					debug ("count %d device %x function %x wants %x resources \n", count, device, function, bar[count]);
+
+					if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
+						/* This is IO */
+						len[count] = bar[count] & 0xFFFFFFFC;
+						len[count] = ~len[count] + 1;
+						amount->io += len[count];
+					} else {
+						/* This is Memory */
+						if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+							/* pfmem */
+							len[count] = bar[count] & 0xFFFFFFF0;
+							len[count] = ~len[count] + 1;
+							amount->pfmem += len[count];
+							if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64)
+								/* takes up another dword */
+								count += 1;
+
+						} else {
+							/* regular memory */
+							len[count] = bar[count] & 0xFFFFFFF0;
+							len[count] = ~len[count] + 1;
+							amount->mem += len[count];
+							if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+								/* takes up another dword */
+								count += 1;
+							}
+						}
+					}
+				}	/* end for */
+			}	/* end if (valid) */
+		}	/* end for */
+	}	/* end for */
+
+	if (!howmany)
+		amount->not_correct = TRUE;
+	else
+		amount->not_correct = FALSE;
+	if ((amount->io) && (amount->io < IOBRIDGE))
+		amount->io = IOBRIDGE;
+	if ((amount->mem) && (amount->mem < MEMBRIDGE))
+		amount->mem = MEMBRIDGE;
+	if ((amount->pfmem) && (amount->pfmem < MEMBRIDGE))
+		amount->pfmem = MEMBRIDGE;
+	return amount;
+}
+
+/* The following 3 unconfigure_boot_ routines deal with the case when we had the card 
+ * upon bootup in the system, since we don't allocate func to such case, we need to read 
+ * the start addresses from pci config space and then find the corresponding entries in 
+ * our resource lists.  The functions return either 0, -ENODEV, or -1 (general failure)
+ * Change: we also call these functions even if we configured the card ourselves (i.e., not
+ * the bootup case), since it should work same way
+ */
+static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
+{
+	u32 start_address;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	int count;
+	struct resource_node *io;
+	struct resource_node *mem;
+	struct resource_node *pfmem;
+	struct bus_node *bus;
+	u32 end_address;
+	u32 temp_end;
+	u32 size;
+	u32 tmp_address;
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	bus = ibmphp_find_res_bus (busno);
+	if (!bus) {
+		debug ("cannot find corresponding bus.\n");
+		return -EINVAL;
+	}
+
+	for (count = 0; address[count]; count++) {	/* for 6 BARs */
+		pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &start_address);
+
+		/* We can do this here, b/c by that time the device driver of the card has been stopped */
+
+		pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF);
+		pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &size);
+		pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], start_address);
+
+		debug ("start_address is %x\n", start_address);
+		debug ("busno, device, function %x %x %x\n", busno, device, function);
+		if (!size) {
+			/* This BAR is not implemented */
+			debug ("is this bar no implemented?, count = %d\n", count);
+			continue;
+		}
+		tmp_address = start_address;
+		if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			start_address &= PCI_BASE_ADDRESS_IO_MASK;
+			size = size & 0xFFFFFFFC;
+			size = ~size + 1;
+			end_address = start_address + size - 1;
+			if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
+				err ("cannot find corresponding IO resource to remove\n");
+				return -EIO;
+			}
+			debug ("io->start = %x\n", io->start);
+			temp_end = io->end;
+			start_address = io->end + 1;
+			ibmphp_remove_resource (io);
+			/* This is needed b/c of the old I/O restrictions in the BIOS */
+			while (temp_end < end_address) {
+				if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
+					err ("cannot find corresponding IO resource to remove\n");
+					return -EIO;
+				}
+				debug ("io->start = %x\n", io->start);
+				temp_end = io->end;
+				start_address = io->end + 1;
+				ibmphp_remove_resource (io);
+			}
+
+			/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
+		} else {
+			/* This is Memory */
+			if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+				debug ("start address of pfmem is %x\n", start_address);
+
+				if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
+					err ("cannot find corresponding PFMEM resource to remove\n");
+					return -EIO;
+				}
+				if (pfmem)
+					debug ("pfmem->start = %x\n", pfmem->start);
+
+				ibmphp_remove_resource (pfmem);
+
+				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+				}
+
+			} else {
+				/* regular memory */
+				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+				debug ("start address of mem is %x\n", start_address);
+				if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
+					err ("cannot find corresponding MEM resource to remove\n");
+					return -EIO;
+				}
+				if (mem)
+					debug ("mem->start = %x\n", mem->start);
+
+				ibmphp_remove_resource (mem);
+
+				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+				}
+			}
+		}	/* end of mem */
+	}	/* end of for */
+
+	return 0;
+}
+
+static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
+{
+	int count;
+	int bus_no, pri_no, sub_no, sec_no = 0;
+	u32 start_address, tmp_address;
+	u8 sec_number, sub_number, pri_number;
+	struct resource_node *io = NULL;
+	struct resource_node *mem = NULL;
+	struct resource_node *pfmem = NULL;
+	struct bus_node *bus;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		0
+	};
+
+	bus_no = (int) busno;
+	debug ("busno is %x\n", busno);
+	pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PRIMARY_BUS, &pri_number);
+	debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number);
+
+	pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_number);
+	debug ("sec_number is %x\n", sec_number);
+	sec_no = (int) sec_number;
+	pri_no = (int) pri_number;
+	if (pri_no != bus_no) {
+		err ("primary numbers in our structures and pci config space don't match.\n");
+		return -EINVAL;
+	}
+
+	pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_number);
+	sec_no = (int) sec_no;
+
+	pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SUBORDINATE_BUS, &sub_number);
+	sub_no = (int) sub_number;
+	debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
+	if (sec_no != sub_number) {
+		err ("there're more buses behind this bridge.  Hot removal is not supported.  Please choose another card\n");
+		return -ENODEV;
+	}
+
+	bus = ibmphp_find_res_bus (sec_number);
+	debug ("bus->busno is %x\n", bus->busno);
+	debug ("sec_number is %x\n", sec_number);
+	if (!bus) {
+		err ("cannot find Bus structure for the bridged device\n");
+		return -EINVAL;
+	}
+
+	ibmphp_remove_bus (bus, busno);
+
+	for (count = 0; address[count]; count++) {
+		/* for 2 BARs */
+		pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &start_address);
+
+		if (!start_address) {
+			/* This BAR is not implemented */
+			continue;
+		}
+
+		tmp_address = start_address;
+
+		if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			start_address &= PCI_BASE_ADDRESS_IO_MASK;
+			if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
+				err ("cannot find corresponding IO resource to remove\n");
+				return -EIO;
+			}
+			if (io)
+				debug ("io->start = %x\n", io->start);
+
+			ibmphp_remove_resource (io);
+
+			/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
+		} else {
+			/* This is Memory */
+			if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+				if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
+					err ("cannot find corresponding PFMEM resource to remove\n");
+					return -EINVAL;
+				}
+				if (pfmem)
+					debug ("pfmem->start = %x\n", pfmem->start);
+
+				ibmphp_remove_resource (pfmem);
+
+				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+				}
+
+			} else {
+				/* regular memory */
+				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+				if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
+					err ("cannot find corresponding MEM resource to remove\n");
+					return -EINVAL;
+				}
+				if (mem)
+					debug ("mem->start = %x\n", mem->start);
+
+				ibmphp_remove_resource (mem);
+
+				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+				}
+			}
+		}	/* end of mem */
+	}	/* end of for */
+	debug ("%s - exiting, returning success\n", __FUNCTION__);
+	return 0;
+}
+
+static int unconfigure_boot_card (struct slot *slot_cur)
+{
+	u16 vendor_id;
+	u32 class;
+	u8 hdr_type;
+	u8 device;
+	u8 busno;
+	u8 function;
+	int rc;
+	u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	device = slot_cur->device;
+	busno = slot_cur->bus;
+
+	debug ("b4 for loop, device is %x\n", device);
+	/* For every function on the card */
+	for (function = 0x0; function < 0x08; function++) {
+
+		pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id);
+
+		if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
+			/* found correct device!!! */
+			++valid_device;
+
+			debug ("%s - found correct device\n", __FUNCTION__);
+
+			/* header: x x x x x x x x
+			 *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
+			 *         |_=> 0 = single function device, 1 = multi-function device
+			 */
+
+			pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type);
+			pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_CLASS_REVISION, &class);
+
+			debug ("hdr_type %x, class %x\n", hdr_type, class);
+			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
+			if (class == PCI_CLASS_NOT_DEFINED_VGA) {
+				err ("The device %x function %x is VGA compatible and is not supported for hot removing. "
+				     "Please choose another device.\n", device, function);
+				return -ENODEV;
+			} else if (class == PCI_CLASS_DISPLAY_VGA) {
+				err ("The device %x function %x is not supported for hot removing. "
+				     "Please choose another device.\n", device, function);
+				return -ENODEV;
+			}
+
+			switch (hdr_type) {
+				case PCI_HEADER_TYPE_NORMAL:
+					rc = unconfigure_boot_device (busno, device, function);
+					if (rc) {
+						err ("was not able to unconfigure device %x func %x on bus %x. bailing out... \n",
+						     device, function, busno);
+						return rc;
+					}
+					function = 0x8;
+					break;
+				case PCI_HEADER_TYPE_MULTIDEVICE:
+					rc = unconfigure_boot_device (busno, device, function);
+					if (rc) {
+						err ("was not able to unconfigure device %x func %x on bus %x. bailing out... \n",
+						     device, function, busno);
+						return rc;
+					}
+					break;
+				case PCI_HEADER_TYPE_BRIDGE:
+					class >>= 8;
+					if (class != PCI_CLASS_BRIDGE_PCI) {
+						err ("This device %x function %x is not PCI-to-PCI bridge, "
+						     "and is not supported for hot-removing. "
+						     "Please try another card.\n", device, function);
+						return -ENODEV;
+					}
+					rc = unconfigure_boot_bridge (busno, device, function);
+					if (rc != 0) {
+						err ("was not able to hot-remove PPB properly.\n");
+						return rc;
+					}
+
+					function = 0x8;
+					break;
+				case PCI_HEADER_TYPE_MULTIBRIDGE:
+					class >>= 8;
+					if (class != PCI_CLASS_BRIDGE_PCI) {
+						err ("This device %x function %x is not PCI-to-PCI bridge, "
+						     "and is not supported for hot-removing. "
+						     "Please try another card.\n", device, function);
+						return -ENODEV;
+					}
+					rc = unconfigure_boot_bridge (busno, device, function);
+					if (rc != 0) {
+						err ("was not able to hot-remove PPB properly.\n");
+						return rc;
+					}
+					break;
+				default:
+					err ("MAJOR PROBLEM!!!! Cannot read device's header \n");
+					return -1;
+					break;
+			}	/* end of switch */
+		}	/* end of valid device */
+	}	/* end of for */
+
+	if (!valid_device) {
+		err ("Could not find device to unconfigure.  Or could not read the card. \n");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * free the resources of the card (multi, single, or bridged)
+ * Parameters: slot, flag to say if this is for removing entire module or just
+ * unconfiguring the device
+ * TO DO:  will probably need to add some code in case there was some resource,
+ * to remove it... this is from when we have errors in the configure_card...
+ * 			!!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!!
+ * Returns: 0, -1, -ENODEV 
+ */
+int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
+{
+	int i;
+	int count;
+	int rc;
+	struct slot *sl = *slot_cur;
+	struct pci_func *cur_func = NULL;
+	struct pci_func *temp_func;
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	if (!the_end) {
+		/* Need to unconfigure the card */
+		rc = unconfigure_boot_card (sl);
+		if ((rc == -ENODEV) || (rc == -EIO) || (rc == -EINVAL)) {
+			/* In all other cases, will still need to get rid of func structure if it exists */
+			return rc;
+		}
+	}
+
+	if (sl->func) {
+		debug ("do we come in here? \n");
+		cur_func = sl->func;
+		while (cur_func) {
+			/* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
+			if (cur_func->bus) {
+				/* in other words, it's a PPB */
+				count = 2;
+			} else {
+				count = 6;
+			}
+
+			for (i = 0; i < count; i++) {
+				if (cur_func->io[count]) {
+					debug ("io[%d] exists \n", count);
+					if (the_end > 0)
+						ibmphp_remove_resource (cur_func->io[count]);
+					cur_func->io[count] = NULL;
+				}
+				if (cur_func->mem[count]) {
+					debug ("mem[%d] exists \n", count);
+					if (the_end > 0)
+						ibmphp_remove_resource (cur_func->mem[count]);
+					cur_func->mem[count] = NULL;
+				}
+				if (cur_func->pfmem[count]) {
+					debug ("pfmem[%d] exists \n", count);
+					if (the_end > 0)
+						ibmphp_remove_resource (cur_func->pfmem[count]);
+					cur_func->pfmem[count] = NULL;
+				}
+			}
+
+			temp_func = cur_func->next;
+			kfree (cur_func);
+			cur_func = temp_func;
+		}
+	}
+
+	sl->func = NULL;
+	*slot_cur = sl;
+	return 0;
+}
+
+/*
+ * add a new bus resulting from hot-plugging a PPB bridge with devices
+ *
+ * Input: bus and the amount of resources needed (we know we can assign those,
+ *        since they've been checked already
+ * Output: bus added to the correct spot
+ *         0, -1, error 
+ */
+static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)
+{
+	struct range_node *io_range = NULL;
+	struct range_node *mem_range = NULL;
+	struct range_node *pfmem_range = NULL;
+	struct bus_node *cur_bus = NULL;
+
+	/* Trying to find the parent bus number */
+	cur_bus	= ibmphp_find_res_bus (parent_busno);
+	if (!cur_bus) {
+		err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
+		return -ENODEV;
+	}
+
+	list_add (&bus->bus_list, &cur_bus->bus_list);
+
+	if (io) {
+		io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		if (!io_range) {
+			err ("out of system memory \n");
+			return -ENOMEM;
+		}
+		memset (io_range, 0, sizeof (struct range_node));
+		io_range->start = io->start;
+		io_range->end = io->end;
+		io_range->rangeno = 1;
+		bus->noIORanges = 1;
+		bus->rangeIO = io_range;
+	}
+	if (mem) {
+		mem_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		if (!mem_range) {
+			err ("out of system memory \n");
+			return -ENOMEM;
+		}
+		memset (mem_range, 0, sizeof (struct range_node));
+		mem_range->start = mem->start;
+		mem_range->end = mem->end;
+		mem_range->rangeno = 1;
+		bus->noMemRanges = 1;
+		bus->rangeMem = mem_range;
+	}
+	if (pfmem) {
+		pfmem_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		if (!pfmem_range) {	
+			err ("out of system memory \n");
+			return -ENOMEM;
+		}
+		memset (pfmem_range, 0, sizeof (struct range_node));
+		pfmem_range->start = pfmem->start;
+		pfmem_range->end = pfmem->end;
+		pfmem_range->rangeno = 1;
+		bus->noPFMemRanges = 1;
+		bus->rangePFMem = pfmem_range;
+	}
+	return 0;
+}
+
+/*
+ * find the 1st available bus number for PPB to set as its secondary bus
+ * Parameters: bus_number of the primary bus
+ * Returns: bus_number of the secondary bus or 0xff in case of failure
+ */
+static u8 find_sec_number (u8 primary_busno, u8 slotno)
+{
+	int min, max;
+	u8 busno;
+	struct bus_info *bus;
+
+	bus = ibmphp_find_same_bus_num (primary_busno);
+	if (!bus) {
+		err ("cannot get slot range of the bus from the BIOS\n");
+		return 0xff;
+	}
+	max = bus->slot_max;
+	min = bus->slot_min;
+	if ((slotno > max) || (slotno < min)) {
+		err ("got the wrong range\n");
+		return 0xff;
+	}
+	busno = (u8) (slotno - (u8) min);
+	busno += primary_busno + 0x01;
+	if (!ibmphp_find_res_bus (busno))
+		return busno;
+	return 0xff;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/ibmphp_res.c linux/drivers/hotplug/ibmphp_res.c
--- linux.orig/drivers/hotplug/ibmphp_res.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/ibmphp_res.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,2067 @@
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Irene Zubarev, IBM Corporation
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include "ibmphp.h"
+
+static int flags = 0;		/* for testing */
+
+static void update_resources (struct bus_node *bus_cur, int type, int rangeno);
+static int once_over (void);
+static int remove_ranges (struct bus_node *, struct bus_node *);
+static int update_bridge_ranges (struct bus_node **);
+static int add_range (int type, struct range_node *, struct bus_node *);
+static void fix_resources (struct bus_node *);
+static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
+
+static LIST_HEAD(gbuses);
+
+static struct bus_node * alloc_error_bus (struct ebda_pci_rsrc * curr)
+{
+	struct bus_node * newbus;
+
+	newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+	if (!newbus) {
+		err ("out of system memory \n");
+		return NULL;
+	}
+
+	memset (newbus, 0, sizeof (struct bus_node));
+	newbus->busno = curr->bus_num;
+	list_add_tail (&newbus->bus_list, &gbuses);
+	return newbus;
+}
+
+static struct resource_node * alloc_resources (struct ebda_pci_rsrc * curr)
+{
+	struct resource_node *rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+	if (!rs) {
+		err ("out of system memory \n");
+		return NULL;
+	}
+	memset (rs, 0, sizeof (struct resource_node));
+	rs->busno = curr->bus_num;
+	rs->devfunc = curr->dev_fun;
+	rs->start = curr->start_addr;
+	rs->end = curr->end_addr;
+	rs->len = curr->end_addr - curr->start_addr + 1;
+	return rs;
+}
+
+static int alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
+{
+	struct bus_node * newbus;
+	struct range_node *newrange;
+	u8 num_ranges = 0;
+
+	if (first_bus) {
+		newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+		if (!newbus) {
+			err ("out of system memory. \n");
+			return -ENOMEM;
+		}
+		memset (newbus, 0, sizeof (struct bus_node));
+		newbus->busno = curr->bus_num;
+	} else {
+		newbus = *new_bus;
+		switch (flag) {
+			case MEM:
+				num_ranges = newbus->noMemRanges;
+				break;
+			case PFMEM:
+				num_ranges = newbus->noPFMemRanges;
+				break;
+			case IO:
+				num_ranges = newbus->noIORanges;
+				break;
+		}
+	}
+
+	newrange = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+	if (!newrange) {
+		if (first_bus)
+			kfree (newbus);
+		err ("out of system memory \n");
+		return -ENOMEM;
+	}
+	memset (newrange, 0, sizeof (struct range_node));
+	newrange->start = curr->start_addr;
+	newrange->end = curr->end_addr;
+		
+	if (first_bus || (!num_ranges))
+		newrange->rangeno = 1;
+	else {
+		/* need to insert our range */
+		add_range (flag, newrange, newbus);
+		debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
+	}
+
+	switch (flag) {
+		case MEM:
+			newbus->rangeMem = newrange;
+			if (first_bus)
+				newbus->noMemRanges = 1;
+			else {
+				debug ("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				++newbus->noMemRanges;
+				fix_resources (newbus);
+			}
+			break;
+		case IO:
+			newbus->rangeIO = newrange;
+			if (first_bus)
+				newbus->noIORanges = 1;
+			else {
+				debug ("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				++newbus->noIORanges;
+				fix_resources (newbus);
+			}
+			break;
+		case PFMEM:
+			newbus->rangePFMem = newrange;
+			if (first_bus)
+				newbus->noPFMemRanges = 1;
+			else {	
+				debug ("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				++newbus->noPFMemRanges;
+				fix_resources (newbus);
+			}
+
+			break;
+	}
+
+	*new_bus = newbus;
+	*new_range = newrange;
+	return 0;
+}
+
+
+/* Notes:
+ * 1. The ranges are ordered.  The buses are not ordered.  (First come)
+ *
+ * 2. If cannot allocate out of PFMem range, allocate from Mem ranges.  PFmemFromMem
+ * are not sorted. (no need since use mem node). To not change the entire code, we
+ * also add mem node whenever this case happens so as not to change
+ * ibmphp_check_mem_resource etc (and since it really is taking Mem resource)
+ */
+
+/*****************************************************************************
+ * This is the Resource Management initialization function.  It will go through
+ * the Resource list taken from EBDA and fill in this module's data structures
+ *
+ * THIS IS NOT TAKING INTO CONSIDERATION IO RESTRICTIONS OF PRIMARY BUSES, 
+ * SINCE WE'RE GOING TO ASSUME FOR NOW WE DON'T HAVE THOSE ON OUR BUSES FOR NOW
+ *
+ * Input: ptr to the head of the resource list from EBDA
+ * Output: 0, -1 or error codes
+ ***************************************************************************/
+int ibmphp_rsrc_init (void)
+{
+	struct ebda_pci_rsrc *curr;
+	struct range_node *newrange = NULL;
+	struct bus_node *newbus = NULL;
+	struct bus_node *bus_cur;
+	struct bus_node *bus_prev;
+	struct list_head *tmp;
+	struct resource_node *new_io = NULL;
+	struct resource_node *new_mem = NULL;
+	struct resource_node *new_pfmem = NULL;
+	int rc;
+	struct list_head *tmp_ebda;
+
+	list_for_each (tmp_ebda, &ibmphp_ebda_pci_rsrc_head) {
+		curr = list_entry (tmp_ebda, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+		if (!(curr->rsrc_type & PCIDEVMASK)) {
+			/* EBDA still lists non PCI devices, so ignore... */
+			debug ("this is not a PCI DEVICE in rsrc_init, please take care\n");
+			// continue;
+		}
+
+		/* this is a primary bus resource */
+		if (curr->rsrc_type & PRIMARYBUSMASK) {
+			/* memory */
+			if ((curr->rsrc_type & RESTYPE) == MMASK) {
+				/* no bus structure exists in place yet */
+				if (list_empty (&gbuses)) {
+					if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
+						return rc;
+					list_add_tail (&newbus->bus_list, &gbuses);
+					debug ("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				} else {
+					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+					/* found our bus */
+					if (bus_cur) {
+						rc = alloc_bus_range (&bus_cur, &newrange, curr, MEM, 0);
+						if (rc)
+							return rc;
+					} else {
+						/* went through all the buses and didn't find ours, need to create a new bus node */
+						if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
+							return rc;
+
+						list_add_tail (&newbus->bus_list, &gbuses);
+						debug ("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+					}
+				}
+			} else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
+				/* prefetchable memory */
+				if (list_empty (&gbuses)) {
+					/* no bus structure exists in place yet */
+					if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
+						return rc;
+					list_add_tail (&newbus->bus_list, &gbuses);
+					debug ("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				} else {
+					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+					if (bus_cur) {
+						/* found our bus */
+						rc = alloc_bus_range (&bus_cur, &newrange, curr, PFMEM, 0);
+						if (rc)
+							return rc;
+					} else {
+						/* went through all the buses and didn't find ours, need to create a new bus node */
+						if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
+							return rc;
+						list_add_tail (&newbus->bus_list, &gbuses);
+						debug ("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+					}
+				}
+			} else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
+				/* IO */
+				if (list_empty (&gbuses)) {
+					/* no bus structure exists in place yet */
+					if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
+						return rc;
+					list_add_tail (&newbus->bus_list, &gbuses);
+					debug ("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				} else {
+					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+					if (bus_cur) {
+						rc = alloc_bus_range (&bus_cur, &newrange, curr, IO, 0);
+						if (rc)
+							return rc;
+					} else {
+						/* went through all the buses and didn't find ours, need to create a new bus node */
+						if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
+							return rc;
+						list_add_tail (&newbus->bus_list, &gbuses);
+						debug ("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+					}
+				}
+
+			} else {
+				;	/* type is reserved  WHAT TO DO IN THIS CASE???
+					   NOTHING TO DO??? */
+			}
+		} else {
+			/* regular pci device resource */
+			if ((curr->rsrc_type & RESTYPE) == MMASK) {
+				/* Memory resource */
+				new_mem = alloc_resources (curr);
+				if (!new_mem)
+					return -ENOMEM;
+				new_mem->type = MEM;
+				/*
+				 * if it didn't find the bus, means PCI dev
+				 * came b4 the Primary Bus info, so need to
+				 * create a bus rangeno becomes a problem...
+				 * assign a -1 and then update once the range
+				 * actually appears...
+				 */
+				if (ibmphp_add_resource (new_mem) < 0) {
+					newbus = alloc_error_bus (curr);
+					if (!newbus)
+						return -ENOMEM;
+					newbus->firstMem = new_mem;
+					++newbus->needMemUpdate;
+					new_mem->rangeno = -1;
+				}
+				debug ("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
+
+			} else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
+				/* PFMemory resource */
+				new_pfmem = alloc_resources (curr);
+				if (!new_pfmem)
+					return -ENOMEM;
+				new_pfmem->type = PFMEM;
+				new_pfmem->fromMem = FALSE;
+				if (ibmphp_add_resource (new_pfmem) < 0) {
+					newbus = alloc_error_bus (curr);
+					if (!newbus)
+						return -ENOMEM;
+					newbus->firstPFMem = new_pfmem;
+					++newbus->needPFMemUpdate;
+					new_pfmem->rangeno = -1;
+				}
+
+				debug ("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
+			} else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
+				/* IO resource */
+				new_io = alloc_resources (curr);
+				if (!new_io)
+					return -ENOMEM;
+				new_io->type = IO;
+
+				/*
+				 * if it didn't find the bus, means PCI dev
+				 * came b4 the Primary Bus info, so need to
+				 * create a bus rangeno becomes a problem...
+				 * Can assign a -1 and then update once the
+				 * range actually appears...
+				 */
+				if (ibmphp_add_resource (new_io) < 0) {
+					newbus = alloc_error_bus (curr);
+					if (!newbus)
+						return -ENOMEM;
+					newbus->firstIO = new_io;
+					++newbus->needIOUpdate;
+					new_io->rangeno = -1;
+				}
+				debug ("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
+			}
+		}
+	}
+
+	debug ("after the while loop in rsrc_init \n");
+
+	list_for_each (tmp, &gbuses) {
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		/* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
+		rc = update_bridge_ranges (&bus_cur);
+		if (rc)
+			return rc;
+	}
+	debug ("b4 once_over in rsrc_init \n");
+	rc = once_over ();  /* This is to align ranges (so no -1) */
+	if (rc)
+		return rc;
+	debug ("after once_over in rsrc_init \n");
+	return 0;
+}
+
+/********************************************************************************
+ * This function adds a range into a sorted list of ranges per bus for a particular
+ * range type, it then calls another routine to update the range numbers on the
+ * pci devices' resources for the appropriate resource
+ *
+ * Input: type of the resource, range to add, current bus
+ * Output: 0 or -1, bus and range ptrs 
+ ********************************************************************************/
+static int add_range (int type, struct range_node *range, struct bus_node *bus_cur)
+{
+	struct range_node *range_cur = NULL;
+	struct range_node *range_prev;
+	int count = 0, i_init;
+	int noRanges = 0;
+
+	switch (type) {
+		case MEM:
+			range_cur = bus_cur->rangeMem;
+			noRanges = bus_cur->noMemRanges;
+			break;
+		case PFMEM:
+			range_cur = bus_cur->rangePFMem;
+			noRanges = bus_cur->noPFMemRanges;
+			break;
+		case IO:
+			range_cur = bus_cur->rangeIO;
+			noRanges = bus_cur->noIORanges;
+			break;
+	}
+
+	range_prev = NULL;
+	while (range_cur) {
+		if (range->start < range_cur->start)
+			break;
+		range_prev = range_cur;
+		range_cur = range_cur->next;
+		count = count + 1;
+	}
+	if (!count) {
+		/* our range will go at the beginning of the list */
+		switch (type) {
+			case MEM:
+				bus_cur->rangeMem = range;
+				break;
+			case PFMEM:
+				bus_cur->rangePFMem = range;
+				break;
+			case IO:
+				bus_cur->rangeIO = range;
+				break;
+		}
+		range->next = range_cur;
+		range->rangeno = 1;
+		i_init = 0;
+	} else if (!range_cur) {
+		/* our range will go at the end of the list */
+		range->next = NULL;
+		range_prev->next = range;
+		range->rangeno = range_prev->rangeno + 1;
+		return 0;
+	} else {
+		/* the range is in the middle */
+		range_prev->next = range;
+		range->next = range_cur;
+		range->rangeno = range_cur->rangeno;
+		i_init = range_prev->rangeno;
+	}
+
+	for (count = i_init; count < noRanges; ++count) {
+		++range_cur->rangeno;
+		range_cur = range_cur->next;
+	}
+
+	update_resources (bus_cur, type, i_init + 1);
+	return 0;
+}
+
+/*******************************************************************************
+ * This routine goes through the list of resources of type 'type' and updates
+ * the range numbers that they correspond to.  It was called from add_range fnc
+ *
+ * Input: bus, type of the resource, the rangeno starting from which to update
+ ******************************************************************************/
+static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
+{
+	struct resource_node *res = NULL;
+	u8 eol = FALSE;	/* end of list indicator */
+
+	switch (type) {
+		case MEM:
+			if (bus_cur->firstMem) 
+				res = bus_cur->firstMem;
+			break;
+		case PFMEM:
+			if (bus_cur->firstPFMem)
+				res = bus_cur->firstPFMem;
+			break;
+		case IO:
+			if (bus_cur->firstIO)
+				res = bus_cur->firstIO;
+			break;
+	}
+
+	if (res) {
+		while (res) {
+			if (res->rangeno == rangeno)
+				break;
+			if (res->next)
+				res = res->next;
+			else if (res->nextRange)
+				res = res->nextRange;
+			else {
+				eol = TRUE;
+				break;
+			}
+		}
+
+		if (!eol) {
+			/* found the range */
+			while (res) {
+				++res->rangeno;
+				res = res->next;
+			}
+		}
+	}
+}
+
+static void fix_me (struct resource_node *res, struct bus_node *bus_cur, struct range_node *range)
+{
+	char * str = "";
+	switch (res->type) {
+		case IO:
+			str = "io";
+			break;
+		case MEM:
+			str = "mem";
+			break;
+		case PFMEM:
+			str = "pfmem";
+			break;
+	}
+
+	while (res) {
+		if (res->rangeno == -1) {
+			while (range) {
+				if ((res->start >= range->start) && (res->end <= range->end)) {
+					res->rangeno = range->rangeno;
+					debug ("%s->rangeno in fix_resources is %d\n", str, res->rangeno);
+					switch (res->type) {
+						case IO:
+							--bus_cur->needIOUpdate;
+							break;
+						case MEM:
+							--bus_cur->needMemUpdate;
+							break;
+						case PFMEM:
+							--bus_cur->needPFMemUpdate;
+							break;
+					}
+					break;
+				}
+				range = range->next;
+			}
+		}
+		if (res->next)
+			res = res->next;
+		else
+			res = res->nextRange;
+	}
+
+}
+
+/*****************************************************************************
+ * This routine reassigns the range numbers to the resources that had a -1
+ * This case can happen only if upon initialization, resources taken by pci dev
+ * appear in EBDA before the resources allocated for that bus, since we don't
+ * know the range, we assign -1, and this routine is called after a new range
+ * is assigned to see the resources with unknown range belong to the added range
+ *
+ * Input: current bus
+ * Output: none, list of resources for that bus are fixed if can be
+ *******************************************************************************/
+static void fix_resources (struct bus_node *bus_cur)
+{
+	struct range_node *range;
+	struct resource_node *res;
+
+	debug ("%s - bus_cur->busno = %d\n", __FUNCTION__, bus_cur->busno);
+
+	if (bus_cur->needIOUpdate) {
+		res = bus_cur->firstIO;
+		range = bus_cur->rangeIO;
+		fix_me (res, bus_cur, range);
+	}
+	if (bus_cur->needMemUpdate) {
+		res = bus_cur->firstMem;
+		range = bus_cur->rangeMem;
+		fix_me (res, bus_cur, range);
+	}
+	if (bus_cur->needPFMemUpdate) {
+		res = bus_cur->firstPFMem;
+		range = bus_cur->rangePFMem;
+		fix_me (res, bus_cur, range);
+	}
+}
+
+/*******************************************************************************
+ * This routine adds a resource to the list of resources to the appropriate bus 
+ * based on their resource type and sorted by their starting addresses.  It assigns
+ * the ptrs to next and nextRange if needed.
+ *
+ * Input: 3 diff. resources (nulled out if not needed)
+ * Output: ptrs assigned (to the node)
+ * 0 or -1
+ *******************************************************************************/
+int ibmphp_add_resource (struct resource_node *res)
+{
+	struct resource_node *res_cur;
+	struct resource_node *res_prev;
+	struct bus_node *bus_cur;
+	struct range_node *range_cur = NULL;
+	struct resource_node *res_start = NULL;
+
+	debug ("%s - enter\n", __FUNCTION__);
+	
+	bus_cur = find_bus_wprev (res->busno, NULL, 0);
+	
+	if (!bus_cur) {
+		/* didn't find a bus, smth's wrong!!! */
+		err ("no bus in the system, either pci_dev's wrong or allocation failed\n");
+		return -ENODEV;
+	}
+
+	/* Normal case */
+	switch (res->type) {
+		case IO:
+			range_cur = bus_cur->rangeIO;
+			res_start = bus_cur->firstIO;
+			break;
+		case MEM:
+			range_cur = bus_cur->rangeMem;
+			res_start = bus_cur->firstMem;
+			break;
+		case PFMEM:
+			range_cur = bus_cur->rangePFMem;
+			res_start = bus_cur->firstPFMem;
+			break;
+		default:
+			err ("cannot read the type of the resource to add... problem \n");
+			return -EINVAL;
+	}
+	while (range_cur) {
+		if ((res->start >= range_cur->start) && (res->end <= range_cur->end)) {
+			res->rangeno = range_cur->rangeno;
+			break;
+		}
+		range_cur = range_cur->next;
+	}
+
+	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	 * this is again the case of rangeno = -1
+	 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	 */
+
+	if (!range_cur) {
+		switch (res->type) {
+			case IO:
+				++bus_cur->needIOUpdate;					
+				break;
+			case MEM:
+				++bus_cur->needMemUpdate;
+				break;
+			case PFMEM:
+				++bus_cur->needPFMemUpdate;
+				break;
+		}
+		res->rangeno = -1;
+	}
+	
+	debug ("The range is %d\n", res->rangeno);
+	if (!res_start) {
+		/* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */
+		switch (res->type) {
+			case IO:
+				bus_cur->firstIO = res;					
+				break;
+			case MEM:
+				bus_cur->firstMem = res;
+				break;
+			case PFMEM:
+				bus_cur->firstPFMem = res;
+				break;
+		}	
+		res->next = NULL;
+		res->nextRange = NULL;
+	} else {
+		res_cur = res_start;
+		res_prev = NULL;
+
+		debug ("res_cur->rangeno is %d\n", res_cur->rangeno);
+
+		while (res_cur) {
+			if (res_cur->rangeno >= res->rangeno)
+				break;
+			res_prev = res_cur;
+			if (res_cur->next)
+				res_cur = res_cur->next;
+			else
+				res_cur = res_cur->nextRange;
+		}
+
+		if (!res_cur) {
+			/* at the end of the resource list */
+			debug ("i should be here, [%x - %x]\n", res->start, res->end);
+			res_prev->nextRange = res;
+			res->next = NULL;
+			res->nextRange = NULL;
+		} else if (res_cur->rangeno == res->rangeno) {
+			/* in the same range */
+			while (res_cur) {
+				if (res->start < res_cur->start)
+					break;
+				res_prev = res_cur;
+				res_cur = res_cur->next;
+			}
+			if (!res_cur) {
+				/* the last resource in this range */
+				res_prev->next = res;
+				res->next = NULL;
+				res->nextRange = res_prev->nextRange;
+				res_prev->nextRange = NULL;
+			} else if (res->start < res_cur->start) {
+				/* at the beginning or middle of the range */
+				if (!res_prev)	{
+					switch (res->type) {
+						case IO:
+							bus_cur->firstIO = res;
+							break;
+						case MEM:
+							bus_cur->firstMem = res;
+							break;
+						case PFMEM:
+							bus_cur->firstPFMem = res;
+							break;
+					}
+				} else if (res_prev->rangeno == res_cur->rangeno)
+					res_prev->next = res;
+				else
+					res_prev->nextRange = res;
+
+				res->next = res_cur;
+				res->nextRange = NULL;
+			}
+		} else {
+			/* this is the case where it is 1st occurence of the range */
+			if (!res_prev) {
+				/* at the beginning of the resource list */
+				res->next = NULL;
+				switch (res->type) {
+					case IO:
+						res->nextRange = bus_cur->firstIO;
+						bus_cur->firstIO = res;
+						break;
+					case MEM:
+						res->nextRange = bus_cur->firstMem;
+						bus_cur->firstMem = res;
+						break;
+					case PFMEM:
+						res->nextRange = bus_cur->firstPFMem;
+						bus_cur->firstPFMem = res;
+						break;
+				}
+			} else if (res_cur->rangeno > res->rangeno) {
+				/* in the middle of the resource list */
+				res_prev->nextRange = res;
+				res->next = NULL;
+				res->nextRange = res_cur;
+			}
+		}
+	}
+
+	debug ("%s - exit\n", __FUNCTION__);
+	return 0;
+}
+
+/****************************************************************************
+ * This routine will remove the resource from the list of resources
+ *
+ * Input: io, mem, and/or pfmem resource to be deleted
+ * Ouput: modified resource list
+ *        0 or error code
+ ****************************************************************************/
+int ibmphp_remove_resource (struct resource_node *res)
+{
+	struct bus_node *bus_cur;
+	struct resource_node *res_cur = NULL;
+	struct resource_node *res_prev;
+	struct resource_node *mem_cur;
+	char * type = "";
+
+	bus_cur = find_bus_wprev (res->busno, NULL, 0);
+
+	if (!bus_cur) {
+		err ("cannot find corresponding bus of the io resource to remove  "
+			"bailing out...\n");
+		return -ENODEV;
+	}
+
+	switch (res->type) {
+		case IO:
+			res_cur = bus_cur->firstIO;
+			type = "io";
+			break;
+		case MEM:
+			res_cur = bus_cur->firstMem;
+			type = "mem";
+			break;
+		case PFMEM:
+			res_cur = bus_cur->firstPFMem;
+			type = "pfmem";
+			break;
+		default:
+			err ("unknown type for resource to remove \n");
+			return -EINVAL;
+	}
+	res_prev = NULL;
+
+	while (res_cur) {
+		/* ???????????DO WE _NEED_ TO BE CHECKING FOR END AS WELL?????????? */
+		if ((res_cur->start == res->start) && (res_cur->end == res->end))
+			break;
+		res_prev = res_cur;
+		if (res_cur->next)
+			res_cur = res_cur->next;
+		else
+			res_cur = res_cur->nextRange;
+	}
+
+	if (!res_cur) {
+		if (res->type == PFMEM) {
+			/* 
+			 * case where pfmem might be in the PFMemFromMem list
+			 * so will also need to remove the corresponding mem
+			 * entry
+			 */
+			res_cur = bus_cur->firstPFMemFromMem;
+			res_prev = NULL;
+
+			while (res_cur) {
+				if ((res_cur->start == res->start) && (res_cur->end == res->end)) {
+					mem_cur = bus_cur->firstMem;
+					while (mem_cur) {
+						if ((mem_cur->start == res_cur->start)
+						    && (mem_cur->end == res_cur->end))
+							break;
+						if (mem_cur->next)
+							mem_cur = mem_cur->next;
+						else
+							mem_cur = mem_cur->nextRange;
+					}
+					if (!mem_cur) {
+						err ("cannot find corresponding mem node for pfmem...\n");
+						return -EINVAL;
+					}
+
+					ibmphp_remove_resource (mem_cur);
+					if (!res_prev)
+						bus_cur->firstPFMemFromMem = res_cur->next;
+					else
+						res_prev->next = res_cur->next;
+					kfree (res_cur);
+					return 0;
+				}
+				res_prev = res_cur;
+				if (res_cur->next)
+					res_cur = res_cur->next;
+				else
+					res_cur = res_cur->nextRange;
+			}
+			if (!res_cur) {
+				err ("cannot find pfmem to delete...\n");
+				return -EINVAL;
+			}
+		} else {
+			err ("the %s resource is not in the list to be deleted...\n", type);
+			return -EINVAL;
+		}
+	}
+	if (!res_prev) {
+		/* first device to be deleted */
+		if (res_cur->next) {
+			switch (res->type) {
+				case IO:
+					bus_cur->firstIO = res_cur->next;
+					break;
+				case MEM:
+					bus_cur->firstMem = res_cur->next;
+					break;
+				case PFMEM:
+					bus_cur->firstPFMem = res_cur->next;
+					break;
+			}
+		} else if (res_cur->nextRange) {
+			switch (res->type) {
+				case IO:
+					bus_cur->firstIO = res_cur->nextRange;
+					break;
+				case MEM:
+					bus_cur->firstMem = res_cur->nextRange;
+					break;
+				case PFMEM:
+					bus_cur->firstPFMem = res_cur->nextRange;
+					break;
+			}
+		} else {
+			switch (res->type) {
+				case IO:
+					bus_cur->firstIO = NULL;
+					break;
+				case MEM:
+					bus_cur->firstMem = NULL;
+					break;
+				case PFMEM:
+					bus_cur->firstPFMem = NULL;
+					break;
+			}
+		}
+		kfree (res_cur);
+		return 0;
+	} else {
+		if (res_cur->next) {
+			if (res_prev->rangeno == res_cur->rangeno)
+				res_prev->next = res_cur->next;
+			else
+				res_prev->nextRange = res_cur->next;
+		} else if (res_cur->nextRange) {
+			res_prev->next = NULL;
+			res_prev->nextRange = res_cur->nextRange;
+		} else {
+			res_prev->next = NULL;
+			res_prev->nextRange = NULL;
+		}
+		kfree (res_cur);
+		return 0;
+	}
+
+	return 0;
+}
+
+static struct range_node * find_range (struct bus_node *bus_cur, struct resource_node * res)
+{
+	struct range_node * range = NULL;
+
+	switch (res->type) {
+		case IO:
+			range = bus_cur->rangeIO;
+			break;
+		case MEM:
+			range = bus_cur->rangeMem;
+			break;
+		case PFMEM:
+			range = bus_cur->rangePFMem;
+			break;
+		default:
+			err ("cannot read resource type in find_range \n");
+	}
+
+	while (range) {
+		if (res->rangeno == range->rangeno)
+			break;
+		range = range->next;
+	}
+	return range;
+}
+
+/*****************************************************************************
+ * This routine will check to make sure the io/mem/pfmem->len that the device asked for 
+ * can fit w/i our list of available IO/MEM/PFMEM resources.  If cannot, returns -EINVAL,
+ * otherwise, returns 0
+ *
+ * Input: resource
+ * Ouput: the correct start and end address are inputted into the resource node,
+ *        0 or -EINVAL
+ *****************************************************************************/
+int ibmphp_check_resource (struct resource_node *res, u8 bridge)
+{
+	struct bus_node *bus_cur;
+	struct range_node *range = NULL;
+	struct resource_node *res_prev;
+	struct resource_node *res_cur = NULL;
+	u32 len_cur = 0, start_cur = 0, len_tmp = 0;
+	int noranges = 0;
+	u32 tmp_start;		/* this is to make sure start address is divisible by the length needed */
+	u32 tmp_divide;
+	u8 flag = FALSE;
+
+	if (!res)
+		return -EINVAL;
+
+	if (bridge) {
+		/* The rules for bridges are different, 4K divisible for IO, 1M for (pf)mem*/
+		if (res->type == IO)
+			tmp_divide = IOBRIDGE;
+		else
+			tmp_divide = MEMBRIDGE;
+	} else
+		tmp_divide = res->len;
+
+	bus_cur = find_bus_wprev (res->busno, NULL, 0);
+
+	if (!bus_cur) {
+		/* didn't find a bus, smth's wrong!!! */
+		err ("no bus in the system, either pci_dev's wrong or allocation failed \n");
+		return -EINVAL;
+	}
+
+	debug ("%s - enter\n", __FUNCTION__);
+	debug ("bus_cur->busno is %d\n", bus_cur->busno);
+
+	/* This is a quick fix to not mess up with the code very much.  i.e.,
+	 * 2000-2fff, len = 1000, but when we compare, we need it to be fff */
+	res->len -= 1;
+
+	switch (res->type) {
+		case IO:
+			res_cur = bus_cur->firstIO;
+			noranges = bus_cur->noIORanges;
+			break;
+		case MEM:
+			res_cur = bus_cur->firstMem;
+			noranges = bus_cur->noMemRanges;
+			break;
+		case PFMEM:
+			res_cur = bus_cur->firstPFMem;
+			noranges = bus_cur->noPFMemRanges;
+			break;
+		default:
+			err ("wrong type of resource to check \n");
+			return -EINVAL;
+	}
+	res_prev = NULL;
+
+	while (res_cur) {
+		range = find_range (bus_cur, res_cur);
+		debug ("%s - rangeno = %d\n", __FUNCTION__, res_cur->rangeno);
+
+		if (!range) {
+			err ("no range for the device exists... bailing out...\n");
+			return -EINVAL;
+		}
+
+		/* found our range */
+		if (!res_prev) {
+			/* first time in the loop */
+			if ((res_cur->start != range->start) && ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
+				debug ("len_tmp = %x\n", len_tmp);
+
+				if ((len_tmp < len_cur) || (len_cur == 0)) {
+
+					if ((range->start % tmp_divide) == 0) {
+						/* just perfect, starting address is divisible by length */
+						flag = TRUE;
+						len_cur = len_tmp;
+						start_cur = range->start;
+					} else {
+						/* Needs adjusting */
+						tmp_start = range->start;
+						flag = FALSE;
+
+						while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
+							if ((tmp_start % tmp_divide) == 0) {
+								flag = TRUE;
+								len_cur = len_tmp;
+								start_cur = tmp_start;
+								break;
+							}
+							tmp_start += tmp_divide - tmp_start % tmp_divide;
+							if (tmp_start >= res_cur->start - 1)
+								break;
+						}
+					}
+			
+					if (flag && len_cur == res->len) {
+						debug ("but we are not here, right?\n");
+						res->start = start_cur;
+						res->len += 1; /* To restore the balance */
+						res->end = res->start + res->len - 1;
+						return 0;
+					}
+				}
+			}
+		}
+		if (!res_cur->next) {
+			/* last device on the range */
+			if ((range->end != res_cur->end) && ((len_tmp = range->end - (res_cur->end + 1)) >= res->len)) {
+				debug ("len_tmp = %x\n", len_tmp);
+				if ((len_tmp < len_cur) || (len_cur == 0)) {
+
+					if (((res_cur->end + 1) % tmp_divide) == 0) {
+						/* just perfect, starting address is divisible by length */
+						flag = TRUE;
+						len_cur = len_tmp;
+						start_cur = res_cur->end + 1;
+					} else {
+						/* Needs adjusting */
+						tmp_start = res_cur->end + 1;
+						flag = FALSE;
+
+						while ((len_tmp = range->end - tmp_start) >= res->len) {
+							if ((tmp_start % tmp_divide) == 0) {
+								flag = TRUE;
+								len_cur = len_tmp;
+								start_cur = tmp_start;
+								break;
+							}
+							tmp_start += tmp_divide - tmp_start % tmp_divide;
+							if (tmp_start >= range->end)
+								break;
+						}
+					}
+					if (flag && len_cur == res->len) {
+						res->start = start_cur;
+						res->len += 1; /* To restore the balance */
+						res->end = res->start + res->len - 1;
+						return 0;
+					}
+				}
+			}
+		}
+
+		if (res_prev) {
+			if (res_prev->rangeno != res_cur->rangeno) {
+				/* 1st device on this range */
+				if ((res_cur->start != range->start) && 
+					((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
+					if ((len_tmp < len_cur) || (len_cur == 0)) {
+						if ((range->start % tmp_divide) == 0) {	
+							/* just perfect, starting address is divisible by length */
+							flag = TRUE;
+							len_cur = len_tmp;
+							start_cur = range->start;
+						} else {
+							/* Needs adjusting */
+							tmp_start = range->start;
+							flag = FALSE;
+
+							while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
+								if ((tmp_start % tmp_divide) == 0) {
+									flag = TRUE;
+									len_cur = len_tmp;
+									start_cur = tmp_start;
+									break;
+								}
+								tmp_start += tmp_divide - tmp_start % tmp_divide;
+								if (tmp_start >= res_cur->start - 1)
+									break;
+							}
+						}
+
+						if (flag && len_cur == res->len) {
+							res->start = start_cur;
+							res->len += 1; /* To restore the balance */
+							res->end = res->start + res->len - 1;
+							return 0;
+						}
+					}
+				}
+			} else {
+				/* in the same range */
+				if ((len_tmp = res_cur->start - 1 - res_prev->end - 1) >= res->len) {
+					if ((len_tmp < len_cur) || (len_cur == 0)) {
+						if (((res_prev->end + 1) % tmp_divide) == 0) {
+							/* just perfect, starting address's divisible by length */
+							flag = TRUE;
+							len_cur = len_tmp;
+							start_cur = res_prev->end + 1;
+						} else {
+							/* Needs adjusting */
+							tmp_start = res_prev->end + 1;
+							flag = FALSE;
+
+							while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
+								if ((tmp_start % tmp_divide) == 0) {
+									flag = TRUE;
+									len_cur = len_tmp;
+									start_cur = tmp_start;
+									break;
+								}
+								tmp_start += tmp_divide - tmp_start % tmp_divide;
+								if (tmp_start >= res_cur->start - 1)
+									break;
+							}
+						}
+
+						if (flag && len_cur == res->len) {
+							res->start = start_cur;
+							res->len += 1; /* To restore the balance */
+							res->end = res->start + res->len - 1;
+							return 0;
+						}
+					}
+				}
+			}
+		}
+		/* end if (res_prev) */
+		res_prev = res_cur;
+		if (res_cur->next)
+			res_cur = res_cur->next;
+		else
+			res_cur = res_cur->nextRange;
+	}	/* end of while */
+
+
+	if (!res_prev) {
+		/* 1st device ever */
+		/* need to find appropriate range */
+		switch (res->type) {
+			case IO:
+				range = bus_cur->rangeIO;
+				break;
+			case MEM:
+				range = bus_cur->rangeMem;
+				break;
+			case PFMEM:
+				range = bus_cur->rangePFMem;
+				break;
+		}
+		while (range) {
+			if ((len_tmp = range->end - range->start) >= res->len) {
+				if ((len_tmp < len_cur) || (len_cur == 0)) {
+					if ((range->start % tmp_divide) == 0) {
+						/* just perfect, starting address's divisible by length */
+						flag = TRUE;
+						len_cur = len_tmp;
+						start_cur = range->start;
+					} else {
+						/* Needs adjusting */
+						tmp_start = range->start;
+						flag = FALSE;
+
+						while ((len_tmp = range->end - tmp_start) >= res->len) {
+							if ((tmp_start % tmp_divide) == 0) {
+								flag = TRUE;
+								len_cur = len_tmp;
+								start_cur = tmp_start;
+								break;
+							}
+							tmp_start += tmp_divide - tmp_start % tmp_divide;
+							if (tmp_start >= range->end)
+								break;
+						}
+					}
+
+					if (flag && len_cur == res->len) {
+						res->start = start_cur;
+						res->len += 1; /* To restore the balance */
+						res->end = res->start + res->len - 1;
+						return 0;
+					}
+				}
+			}
+			range = range->next;
+		}		/* end of while */
+
+		if ((!range) && (len_cur == 0)) {
+			/* have gone through the list of devices and ranges and haven't found n.e.thing */
+			err ("no appropriate range.. bailing out...\n");
+			return -EINVAL;
+		} else if (len_cur) {
+			res->start = start_cur;
+			res->len += 1; /* To restore the balance */
+			res->end = res->start + res->len - 1;
+			return 0;
+		}
+	}
+
+	if (!res_cur) {
+		debug ("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges);
+		if (res_prev->rangeno < noranges) {
+			/* if there're more ranges out there to check */
+			switch (res->type) {
+				case IO:
+					range = bus_cur->rangeIO;
+					break;
+				case MEM:
+					range = bus_cur->rangeMem;
+					break;
+				case PFMEM:
+					range = bus_cur->rangePFMem;
+					break;
+			}
+			while (range) {
+				if ((len_tmp = range->end - range->start) >= res->len) {
+					if ((len_tmp < len_cur) || (len_cur == 0)) {
+						if ((range->start % tmp_divide) == 0) {
+							/* just perfect, starting address's divisible by length */
+							flag = TRUE;
+							len_cur = len_tmp;
+							start_cur = range->start;
+						} else {
+							/* Needs adjusting */
+							tmp_start = range->start;
+							flag = FALSE;
+
+							while ((len_tmp = range->end - tmp_start) >= res->len) {
+								if ((tmp_start % tmp_divide) == 0) {
+									flag = TRUE;
+									len_cur = len_tmp;
+									start_cur = tmp_start;
+									break;
+								}
+								tmp_start += tmp_divide - tmp_start % tmp_divide;
+								if (tmp_start >= range->end)
+									break;
+							}
+						}
+
+						if (flag && len_cur == res->len) {
+							res->start = start_cur;
+							res->len += 1; /* To restore the balance */
+							res->end = res->start + res->len - 1;
+							return 0;
+						}
+					}
+				}
+				range = range->next;
+			}	/* end of while */
+
+			if ((!range) && (len_cur == 0)) {
+				/* have gone through the list of devices and ranges and haven't found n.e.thing */
+				err ("no appropriate range.. bailing out...\n");
+				return -EINVAL;
+			} else if (len_cur) {
+				res->start = start_cur;
+				res->len += 1; /* To restore the balance */
+				res->end = res->start + res->len - 1;
+				return 0;
+			}
+		} else {
+			/* no more ranges to check on */
+			if (len_cur) {
+				res->start = start_cur;
+				res->len += 1; /* To restore the balance */
+				res->end = res->start + res->len - 1;
+				return 0;
+			} else {
+				/* have gone through the list of devices and haven't found n.e.thing */
+				err ("no appropriate range.. bailing out...\n");
+				return -EINVAL;
+			}
+		}
+	}	/* end if(!res_cur) */
+	return -EINVAL;
+}
+
+/********************************************************************************
+ * This routine is called from remove_card if the card contained PPB.
+ * It will remove all the resources on the bus as well as the bus itself
+ * Input: Bus
+ * Ouput: 0, -ENODEV
+ ********************************************************************************/
+int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
+{
+	struct resource_node *res_cur;
+	struct resource_node *res_tmp;
+	struct bus_node *prev_bus;
+	int rc;
+
+	prev_bus = find_bus_wprev (parent_busno, NULL, 0);	
+
+	if (!prev_bus) {
+		err ("something terribly wrong. Cannot find parent bus to the one to remove\n");
+		return -ENODEV;
+	}
+
+	debug ("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno);
+
+	rc = remove_ranges (bus, prev_bus);
+	if (rc)
+		return rc;
+
+	if (bus->firstIO) {
+		res_cur = bus->firstIO;
+		while (res_cur) {
+			res_tmp = res_cur;
+			if (res_cur->next)
+				res_cur = res_cur->next;
+			else
+				res_cur = res_cur->nextRange;
+			kfree (res_tmp);
+			res_tmp = NULL;
+		}
+		bus->firstIO = NULL;
+	}
+	if (bus->firstMem) {
+		res_cur = bus->firstMem;
+		while (res_cur) {
+			res_tmp = res_cur;
+			if (res_cur->next)
+				res_cur = res_cur->next;
+			else
+				res_cur = res_cur->nextRange;
+			kfree (res_tmp);
+			res_tmp = NULL;
+		}
+		bus->firstMem = NULL;
+	}
+	if (bus->firstPFMem) {
+		res_cur = bus->firstPFMem;
+		while (res_cur) {
+			res_tmp = res_cur;
+			if (res_cur->next)
+				res_cur = res_cur->next;
+			else
+				res_cur = res_cur->nextRange;
+			kfree (res_tmp);
+			res_tmp = NULL;
+		}
+		bus->firstPFMem = NULL;
+	}
+
+	if (bus->firstPFMemFromMem) {
+		res_cur = bus->firstPFMemFromMem;
+		while (res_cur) {
+			res_tmp = res_cur;
+			res_cur = res_cur->next;
+
+			kfree (res_tmp);
+			res_tmp = NULL;
+		}
+		bus->firstPFMemFromMem = NULL;
+	}
+
+	list_del (&bus->bus_list);
+	kfree (bus);
+	return 0;
+}
+
+/******************************************************************************
+ * This routine deletes the ranges from a given bus, and the entries from the 
+ * parent's bus in the resources
+ * Input: current bus, previous bus
+ * Output: 0, -EINVAL
+ ******************************************************************************/
+static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
+{
+	struct range_node *range_cur;
+	struct range_node *range_tmp;
+	int i;
+	struct resource_node *res = NULL;
+
+	if (bus_cur->noIORanges) {
+		range_cur = bus_cur->rangeIO;
+		for (i = 0; i < bus_cur->noIORanges; i++) {
+			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, IO) < 0)
+				return -EINVAL;
+			ibmphp_remove_resource (res);
+
+			range_tmp = range_cur;
+			range_cur = range_cur->next;
+			kfree (range_tmp);
+			range_tmp = NULL;
+		}
+		bus_cur->rangeIO = NULL;
+	}
+	if (bus_cur->noMemRanges) {
+		range_cur = bus_cur->rangeMem;
+		for (i = 0; i < bus_cur->noMemRanges; i++) {
+			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, MEM) < 0) 
+				return -EINVAL;
+
+			ibmphp_remove_resource (res);
+			range_tmp = range_cur;
+			range_cur = range_cur->next;
+			kfree (range_tmp);
+			range_tmp = NULL;
+		}
+		bus_cur->rangeMem = NULL;
+	}
+	if (bus_cur->noPFMemRanges) {
+		range_cur = bus_cur->rangePFMem;
+		for (i = 0; i < bus_cur->noPFMemRanges; i++) {
+			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, PFMEM) < 0) 
+				return -EINVAL;
+
+			ibmphp_remove_resource (res);
+			range_tmp = range_cur;
+			range_cur = range_cur->next;
+			kfree (range_tmp);
+			range_tmp = NULL;
+		}
+		bus_cur->rangePFMem = NULL;
+	}
+	return 0;
+}
+
+/*
+ * find the resource node in the bus 
+ * Input: Resource needed, start address of the resource, type or resource
+ */
+int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
+{
+	struct resource_node *res_cur = NULL;
+	char * type = "";
+
+	switch (flag) {
+		case IO:
+			res_cur = bus->firstIO;
+			type = "io";
+			break;
+		case MEM:
+			res_cur = bus->firstMem;
+			type = "mem";
+			break;
+		case PFMEM:
+			res_cur = bus->firstPFMem;
+			type = "pfmem";
+			break;
+		default:
+			err ("wrong type of flag \n");
+			return -EINVAL;
+	}
+	
+	while (res_cur) {
+		if (res_cur->start == start_address) {
+			*res = res_cur;
+			break;
+		}
+		if (res_cur->next)
+			res_cur = res_cur->next;
+		else
+			res_cur = res_cur->nextRange;
+	}
+
+	if (!res_cur) {
+		if (flag == PFMEM) {
+			res_cur = bus->firstPFMemFromMem;
+			while (res_cur) {
+				if (res_cur->start == start_address) {
+					*res = res_cur;
+					break;
+				}
+				res_cur = res_cur->next;
+			}
+			if (!res_cur) {
+				err ("SOS...cannot find %s resource in the bus. \n", type);
+				return -EINVAL;
+			}
+		} else {
+			err ("SOS... cannot find %s resource in the bus. \n", type);
+			return -EINVAL;
+		}
+	}
+
+	if (*res)
+		debug ("*res->start = %x \n", (*res)->start);
+
+	return 0;
+}
+
+/***********************************************************************
+ * This routine will free the resource structures used by the
+ * system.  It is called from cleanup routine for the module
+ * Parameters: none
+ * Returns: none
+ ***********************************************************************/
+void ibmphp_free_resources (void)
+{
+	struct bus_node *bus_cur = NULL;
+	struct bus_node *bus_tmp;
+	struct range_node *range_cur;
+	struct range_node *range_tmp;
+	struct resource_node *res_cur;
+	struct resource_node *res_tmp;
+	struct list_head *tmp;
+	struct list_head *next;
+	int i = 0;
+	flags = 1;
+
+	list_for_each_safe (tmp, next, &gbuses) {
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		if (bus_cur->noIORanges) {
+			range_cur = bus_cur->rangeIO;
+			for (i = 0; i < bus_cur->noIORanges; i++) {
+				if (!range_cur)
+					break;
+				range_tmp = range_cur;
+				range_cur = range_cur->next;
+				kfree (range_tmp);
+				range_tmp = NULL;
+			}
+		}
+		if (bus_cur->noMemRanges) {
+			range_cur = bus_cur->rangeMem;
+			for (i = 0; i < bus_cur->noMemRanges; i++) {
+				if (!range_cur)
+					break;
+				range_tmp = range_cur;
+				range_cur = range_cur->next;
+				kfree (range_tmp);
+				range_tmp = NULL;
+			}
+		}
+		if (bus_cur->noPFMemRanges) {
+			range_cur = bus_cur->rangePFMem;
+			for (i = 0; i < bus_cur->noPFMemRanges; i++) {
+				if (!range_cur)
+					break;
+				range_tmp = range_cur;
+				range_cur = range_cur->next;
+				kfree (range_tmp);
+				range_tmp = NULL;
+			}
+		}
+
+		if (bus_cur->firstIO) {
+			res_cur = bus_cur->firstIO;
+			while (res_cur) {
+				res_tmp = res_cur;
+				if (res_cur->next)
+					res_cur = res_cur->next;
+				else
+					res_cur = res_cur->nextRange;
+				kfree (res_tmp);
+				res_tmp = NULL;
+			}
+			bus_cur->firstIO = NULL;
+		}
+		if (bus_cur->firstMem) {
+			res_cur = bus_cur->firstMem;
+			while (res_cur) {
+				res_tmp = res_cur;
+				if (res_cur->next)
+					res_cur = res_cur->next;
+				else
+					res_cur = res_cur->nextRange;
+				kfree (res_tmp);
+				res_tmp = NULL;
+			}
+			bus_cur->firstMem = NULL;
+		}
+		if (bus_cur->firstPFMem) {
+			res_cur = bus_cur->firstPFMem;
+			while (res_cur) {
+				res_tmp = res_cur;
+				if (res_cur->next)
+					res_cur = res_cur->next;
+				else
+					res_cur = res_cur->nextRange;
+				kfree (res_tmp);
+				res_tmp = NULL;
+			}
+			bus_cur->firstPFMem = NULL;
+		}
+
+		if (bus_cur->firstPFMemFromMem) {
+			res_cur = bus_cur->firstPFMemFromMem;
+			while (res_cur) {
+				res_tmp = res_cur;
+				res_cur = res_cur->next;
+
+				kfree (res_tmp);
+				res_tmp = NULL;
+			}
+			bus_cur->firstPFMemFromMem = NULL;
+		}
+
+		bus_tmp = bus_cur;
+		list_del (&bus_cur->bus_list);
+		kfree (bus_tmp);
+		bus_tmp = NULL;
+	}
+}
+
+/*********************************************************************************
+ * This function will go over the PFmem resources to check if the EBDA allocated
+ * pfmem out of memory buckets of the bus.  If so, it will change the range numbers
+ * and a flag to indicate that this resource is out of memory. It will also move the
+ * Pfmem out of the pfmem resource list to the PFMemFromMem list, and will create
+ * a new Mem node
+ * This routine is called right after initialization
+ *******************************************************************************/
+static int once_over (void)
+{
+	struct resource_node *pfmem_cur;
+	struct resource_node *pfmem_prev;
+	struct resource_node *mem;
+	struct bus_node *bus_cur;
+	struct list_head *tmp;
+
+	list_for_each (tmp, &gbuses) {
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) {
+			for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) {
+				pfmem_cur->fromMem = TRUE;
+				if (pfmem_prev)
+					pfmem_prev->next = pfmem_cur->next;
+				else
+					bus_cur->firstPFMem = pfmem_cur->next;
+
+				if (!bus_cur->firstPFMemFromMem)
+					pfmem_cur->next = NULL;
+				else
+					/* we don't need to sort PFMemFromMem since we're using mem node for
+					   all the real work anyways, so just insert at the beginning of the
+					   list
+					 */
+					pfmem_cur->next = bus_cur->firstPFMemFromMem;
+
+				bus_cur->firstPFMemFromMem = pfmem_cur;
+
+				mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);		
+				if (!mem) {
+					err ("out of system memory \n");
+					return -ENOMEM;
+				}
+				memset (mem, 0, sizeof (struct resource_node));
+				mem->type = MEM;
+				mem->busno = pfmem_cur->busno;
+				mem->devfunc = pfmem_cur->devfunc;
+				mem->start = pfmem_cur->start;
+				mem->end = pfmem_cur->end;
+				mem->len = pfmem_cur->len;
+				if (ibmphp_add_resource (mem) < 0)
+					err ("Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n");
+				pfmem_cur->rangeno = mem->rangeno;
+			}	/* end for pfmem */
+		}	/* end if */
+	}	/* end list_for_each bus */
+	return 0; 
+}
+
+int ibmphp_add_pfmem_from_mem (struct resource_node *pfmem)
+{
+	struct bus_node *bus_cur = find_bus_wprev (pfmem->busno, NULL, 0);
+
+	if (!bus_cur) {
+		err ("cannot find bus of pfmem to add...\n");
+		return -ENODEV;
+	}
+
+	if (bus_cur->firstPFMemFromMem)
+		pfmem->next = bus_cur->firstPFMemFromMem;
+	else
+		pfmem->next = NULL;
+
+	bus_cur->firstPFMemFromMem = pfmem;
+
+	return 0;
+}
+
+/* This routine just goes through the buses to see if the bus already exists.
+ * It is called from ibmphp_find_sec_number, to find out a secondary bus number for
+ * bridged cards
+ * Parameters: bus_number
+ * Returns: Bus pointer or NULL
+ */
+struct bus_node *ibmphp_find_res_bus (u8 bus_number)
+{
+	return find_bus_wprev (bus_number, NULL, 0);
+}
+
+static inline struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u8 flag)
+{
+	struct bus_node *bus_cur;
+	struct list_head *tmp;
+	struct list_head *tmp_prev;
+
+	list_for_each (tmp, &gbuses) {
+		tmp_prev = tmp->prev;
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		if (flag) 
+			*prev = list_entry (tmp_prev, struct bus_node, bus_list);
+		if (bus_cur->busno == bus_number) 
+			return bus_cur;
+	}
+
+	return NULL;
+}
+
+void ibmphp_print_test (void)
+{
+	int i = 0;
+	struct bus_node *bus_cur = NULL;
+	struct range_node *range;
+	struct resource_node *res;
+	struct list_head *tmp;
+
+	if ((!list_empty(&gbuses)) && flags) {
+		err ("The GBUSES is not NULL?!?!?!?!?\n");
+		return;
+	}
+
+	list_for_each (tmp, &gbuses) {
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		debug ("This is bus # %d.  There are \n", bus_cur->busno);
+		debug ("IORanges = %d\t", bus_cur->noIORanges);
+		debug ("MemRanges = %d\t", bus_cur->noMemRanges);
+		debug ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
+		debug ("The IO Ranges are as follows:\n");
+		if (bus_cur->rangeIO) {
+			range = bus_cur->rangeIO;
+			for (i = 0; i < bus_cur->noIORanges; i++) {
+				debug ("rangeno is %d\n", range->rangeno);
+				debug ("[%x - %x]\n", range->start, range->end);
+				range = range->next;
+			}
+		}
+
+		debug ("The Mem Ranges are as follows:\n");
+		if (bus_cur->rangeMem) {
+			range = bus_cur->rangeMem;
+			for (i = 0; i < bus_cur->noMemRanges; i++) {
+				debug ("rangeno is %d\n", range->rangeno);
+				debug ("[%x - %x]\n", range->start, range->end);
+				range = range->next;
+			}
+		}
+
+		debug ("The PFMem Ranges are as follows:\n");
+
+		if (bus_cur->rangePFMem) {
+			range = bus_cur->rangePFMem;
+			for (i = 0; i < bus_cur->noPFMemRanges; i++) {
+				debug ("rangeno is %d\n", range->rangeno);
+				debug ("[%x - %x]\n", range->start, range->end);
+				range = range->next;
+			}
+		}
+
+		debug ("The resources on this bus are as follows\n");
+
+		debug ("IO...\n");
+		if (bus_cur->firstIO) {
+			res = bus_cur->firstIO;
+			while (res) {
+				debug ("The range # is %d\n", res->rangeno);
+				debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				if (res->next)
+					res = res->next;
+				else if (res->nextRange)
+					res = res->nextRange;
+				else
+					break;
+			}
+		}
+		debug ("Mem...\n");
+		if (bus_cur->firstMem) {
+			res = bus_cur->firstMem;
+			while (res) {
+				debug ("The range # is %d\n", res->rangeno);
+				debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				if (res->next)
+					res = res->next;
+				else if (res->nextRange)
+					res = res->nextRange;
+				else
+					break;
+			}
+		}
+		debug ("PFMem...\n");
+		if (bus_cur->firstPFMem) {
+			res = bus_cur->firstPFMem;
+			while (res) {
+				debug ("The range # is %d\n", res->rangeno);
+				debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				if (res->next)
+					res = res->next;
+				else if (res->nextRange)
+					res = res->nextRange;
+				else
+					break;
+			}
+		}
+
+		debug ("PFMemFromMem...\n");
+		if (bus_cur->firstPFMemFromMem) {
+			res = bus_cur->firstPFMemFromMem;
+			while (res) {
+				debug ("The range # is %d\n", res->rangeno);
+				debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				res = res->next;
+			}
+		}
+	}
+}
+
+/* This routine will read the windows for any PPB we have and update the
+ * range info for the secondary bus, and will also input this info into
+ * primary bus, since BIOS doesn't. This is for PPB that are in the system
+ * on bootup
+ * Input: primary busno
+ * Returns: none
+ * Note: this function doesn't take into account IO restrictions etc,
+ *	 so will only work for bridges with no video/ISA devices behind them It
+ *	 also will not work for onboard PPB's that can have more than 1 *bus
+ *	 behind them All these are TO DO.
+ *	 Also need to add more error checkings... (from fnc returns etc)
+ */
+static int update_bridge_ranges (struct bus_node **bus)
+{
+	u8 sec_busno, device, function, busno, hdr_type, start_io_address, end_io_address;
+	u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
+	u32 start_address, end_address, upper_start, upper_end;
+	struct bus_node *bus_sec;
+	struct bus_node *bus_cur;
+	struct resource_node *io;
+	struct resource_node *mem;
+	struct resource_node *pfmem;
+	struct range_node *range;
+	bus_cur = *bus;
+	busno = bus_cur->busno;
+
+	debug ("inside update_bridge_ranges \n");
+	debug ("bus_cur->busno = %x\n", bus_cur->busno);
+
+	for (device = 0; device < 32; device++) {
+		for (function = 0x00; function < 0x08; function++) {
+			pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id);
+
+			if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
+				/* found correct device!!! */
+				pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type);
+
+				switch (hdr_type) {
+					case PCI_HEADER_TYPE_NORMAL:
+						function = 0x8;
+						break;
+					case PCI_HEADER_TYPE_MULTIDEVICE:
+						break;
+					case PCI_HEADER_TYPE_BRIDGE:
+						function = 0x8;
+					case PCI_HEADER_TYPE_MULTIBRIDGE:
+						/* We assume here that only 1 bus behind the bridge 
+						   TO DO: add functionality for several:
+						   temp = secondary;
+						   while (temp < subordinate) {
+						   ...
+						   temp++;
+						   }
+						 */
+						pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_busno);
+						bus_sec = find_bus_wprev (sec_busno, NULL, 0); 
+						pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE, &start_io_address);
+						pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT, &end_io_address);
+						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE_UPPER16, &upper_io_start);
+						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT_UPPER16, &upper_io_end);
+						start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8;
+						start_address |= (upper_io_start << 16);
+						end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
+						end_address |= (upper_io_end << 16);
+
+						if ((start_address) && (start_address <= end_address)) {
+
+							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+
+							if (!range) {
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (range, 0, sizeof (struct range_node));
+							range->start = start_address;
+							range->end = end_address + 0xfff;
+
+							if (bus_sec->noIORanges > 0) 
+								add_range (IO, range, bus_sec);
+							else {
+								/* 1st IO Range on the bus */
+								range->rangeno = 1;
+								bus_sec->rangeIO = range;
+							}
+
+							++bus_sec->noIORanges;
+							fix_resources (bus_sec);
+						
+							io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);							
+							if (!io) {
+								kfree (range);
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (io, 0, sizeof (struct resource_node));
+							io->type = IO;
+							io->busno = bus_cur->busno;
+							io->devfunc = ((device << 3) | (function & 0x7));
+							io->start = start_address;
+							io->end = end_address + 0xfff;
+							io->len = io->end - io->start + 1;
+
+							ibmphp_add_resource (io);
+						}
+
+						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_MEMORY_BASE, &start_mem_address);
+						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_MEMORY_LIMIT, &end_mem_address);
+
+						start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
+						end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
+
+						if ((start_address) && (start_address <= end_address)) {
+
+							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+							if (!range) {
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (range, 0, sizeof (struct range_node));
+							range->start = start_address;
+							range->end = end_address + 0xfffff;
+
+							if (bus_sec->noMemRanges > 0) 
+								add_range (MEM, range, bus_sec);
+							else {
+								/* 1st Mem Range on the bus */
+								range->rangeno = 1;
+								bus_sec->rangeMem = range;
+							}
+
+							++bus_sec->noMemRanges;
+							fix_resources (bus_sec);
+
+							mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+							if (!mem) {
+								kfree (range);
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (mem, 0, sizeof (struct resource_node));
+							mem->type = MEM;
+							mem->busno = bus_cur->busno;
+							mem->devfunc = ((device << 3) | (function & 0x7));
+							mem->start = start_address;
+							mem->end = end_address + 0xfffff;
+							mem->len = mem->end - mem->start + 1;
+							ibmphp_add_resource (mem);
+						}
+						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_MEMORY_BASE, &start_mem_address);
+						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
+						pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_BASE_UPPER32, &upper_start);
+						pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_LIMIT_UPPER32, &upper_end);
+						start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
+						end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
+#if BITS_PER_LONG == 64
+						start_address |= ((long) upper_start) << 32;
+						end_address |= ((long) upper_end) << 32;
+#endif
+
+						if ((start_address) && (start_address <= end_address)) {
+
+							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+							if (!range) {
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (range, 0, sizeof (struct range_node));
+							range->start = start_address;
+							range->end = end_address + 0xfffff;
+
+							if (bus_sec->noPFMemRanges > 0)
+								add_range (PFMEM, range, bus_sec);
+							else {
+								/* 1st PFMem Range on the bus */
+								range->rangeno = 1;
+								bus_sec->rangePFMem = range;
+							}
+
+							++bus_sec->noPFMemRanges;
+							fix_resources (bus_sec);
+
+							pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+							if (!pfmem) {
+								kfree (range);
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (pfmem, 0, sizeof (struct resource_node));
+							pfmem->type = PFMEM;
+							pfmem->busno = bus_cur->busno;
+							pfmem->devfunc = ((device << 3) | (function & 0x7));
+							pfmem->start = start_address;
+							pfmem->end = end_address + 0xfffff;
+							pfmem->len = pfmem->end - pfmem->start + 1;
+							pfmem->fromMem = FALSE;
+							ibmphp_add_resource (pfmem);
+						}
+						break;
+				}	/* end of switch */
+			}	/* end if vendor */
+		}	/* end for function */
+	}	/* end for device */
+
+	bus = &bus_cur;
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/pci_hotplug_core.c linux/drivers/hotplug/pci_hotplug_core.c
--- linux.orig/drivers/hotplug/pci_hotplug_core.c	2001-11-21 17:59:11.000000000 +0000
+++ linux/drivers/hotplug/pci_hotplug_core.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,8 +1,8 @@
 /*
  * PCI HotPlug Controller Core
  *
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
+ * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001-2002 IBM Corp.
  *
  * All rights reserved.
  *
@@ -23,6 +23,8 @@
  *
  * Send feedback to <greg@kroah.com>
  *
+ * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs
+ *
  */
 
 #include <linux/config.h>
@@ -54,7 +56,7 @@
 /* local variables */
 static int debug;
 
-#define DRIVER_VERSION	"0.3"
+#define DRIVER_VERSION	"0.4"
 #define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC	"PCI Hot Plug PCI Core"
 
@@ -74,7 +76,6 @@
 };
 
 static struct super_operations pcihpfs_ops;
-static struct address_space_operations pcihpfs_aops;
 static struct file_operations pcihpfs_dir_operations;
 static struct file_operations default_file_operations;
 static struct inode_operations pcihpfs_dir_inode_operations;
@@ -111,7 +112,6 @@
 		inode->i_blksize = PAGE_CACHE_SIZE;
 		inode->i_blocks = 0;
 		inode->i_rdev = NODEV;
-		inode->i_mapping->a_ops = &pcihpfs_aops;
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 		switch (mode & S_IFMT) {
 		default:
@@ -152,21 +152,6 @@
  	return pcihpfs_mknod (dir, dentry, mode | S_IFREG, 0);
 }
 
-static int pcihpfs_link (struct dentry *old_dentry, struct inode *dir,
-			 struct dentry *dentry)
-{
-	struct inode *inode = old_dentry->d_inode;
-
-	if(S_ISDIR(inode->i_mode))
-		return -EPERM;
-
-	inode->i_nlink++;
-	atomic_inc(&inode->i_count);
- 	dget(dentry);
-	d_instantiate(dentry, inode);
-	return 0;
-}
-
 static inline int pcihpfs_positive (struct dentry *dentry)
 {
 	return dentry->d_inode && !d_unhashed(dentry);
@@ -204,22 +189,6 @@
 	return error;
 }
 
-static int pcihpfs_rename (struct inode *old_dir, struct dentry *old_dentry,
-			   struct inode *new_dir, struct dentry *new_dentry)
-{
-	int error = -ENOTEMPTY;
-
-	if (pcihpfs_empty(new_dentry)) {
-		struct inode *inode = new_dentry->d_inode;
-		if (inode) {
-			inode->i_nlink--;
-			dput(new_dentry);
-		}
-		error = 0;
-	}
-	return error;
-}
-
 #define pcihpfs_rmdir pcihpfs_unlink
 
 /* default file operations */
@@ -266,18 +235,9 @@
 	return 0;
 }
 
-static int default_sync_file (struct file *file, struct dentry *dentry, int datasync)
-{
-	return 0;
-}
-
-static struct address_space_operations pcihpfs_aops = {
-};
-
 static struct file_operations pcihpfs_dir_operations = {
 	read:		generic_read_dir,
 	readdir:	dcache_readdir,
-	fsync:		default_sync_file,
 };
 
 static struct file_operations default_file_operations = {
@@ -285,8 +245,6 @@
 	write:		default_write_file,
 	open:		default_open,
 	llseek:		default_file_lseek,
-	fsync:		default_sync_file,
-	mmap:		generic_file_mmap,
 };
 
 /* file ops for the "power" files */
@@ -297,8 +255,6 @@
 	write:		power_write_file,
 	open:		default_open,
 	llseek:		default_file_lseek,
-	fsync:		default_sync_file,
-	mmap:		generic_file_mmap,
 };
 
 /* file ops for the "attention" files */
@@ -309,8 +265,6 @@
 	write:		attention_write_file,
 	open:		default_open,
 	llseek:		default_file_lseek,
-	fsync:		default_sync_file,
-	mmap:		generic_file_mmap,
 };
 
 /* file ops for the "latch" files */
@@ -320,8 +274,6 @@
 	write:		default_write_file,
 	open:		default_open,
 	llseek:		default_file_lseek,
-	fsync:		default_sync_file,
-	mmap:		generic_file_mmap,
 };
 
 /* file ops for the "presence" files */
@@ -331,8 +283,6 @@
 	write:		default_write_file,
 	open:		default_open,
 	llseek:		default_file_lseek,
-	fsync:		default_sync_file,
-	mmap:		generic_file_mmap,
 };
 
 /* file ops for the "test" files */
@@ -342,19 +292,15 @@
 	write:		test_write_file,
 	open:		default_open,
 	llseek:		default_file_lseek,
-	fsync:		default_sync_file,
-	mmap:		generic_file_mmap,
 };
 
 static struct inode_operations pcihpfs_dir_inode_operations = {
 	create:		pcihpfs_create,
 	lookup:		pcihpfs_lookup,
-	link:		pcihpfs_link,
 	unlink:		pcihpfs_unlink,
 	mkdir:		pcihpfs_mkdir,
 	rmdir:		pcihpfs_rmdir,
 	mknod:		pcihpfs_mknod,
-	rename:		pcihpfs_rename,
 };
 
 static struct super_operations pcihpfs_ops = {
@@ -475,7 +421,7 @@
 
 	if (!parent) {
 		dbg("Ah! can not find a parent!\n");
-		return -EFAULT;
+		return -EINVAL;
 	}
 
 	*dentry = NULL;
@@ -676,7 +622,7 @@
 
 		default:
 			err ("Illegal value specified for power\n");
-			retval = -EFAULT;
+			retval = -EINVAL;
 	}
 
 exit:	
@@ -1009,7 +955,7 @@
 	if (slot == NULL)
 		return -ENODEV;
 	if ((slot->info == NULL) || (slot->ops == NULL))
-		return -EFAULT;
+		return -EINVAL;
 
 	core = kmalloc (sizeof (struct hotplug_slot_core), GFP_KERNEL);
 	if (!core)
@@ -1020,7 +966,7 @@
 	if (get_slot_from_name (slot->name) != NULL) {
 		spin_unlock (&list_lock);
 		kfree (core);
-		return -EFAULT;
+		return -EINVAL;
 	}
 
 	slot->core_priv = core;
@@ -1066,6 +1012,12 @@
 	return 0;
 }
 
+static inline void update_inode_time (struct inode *inode)
+{
+	if (inode)
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+}
+
 /**
  * pci_hp_change_slot_info - changes the slot's information structure in the core
  * @name: the name of the slot whose info has changed
@@ -1079,6 +1031,7 @@
 int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info)
 {
 	struct hotplug_slot *temp;
+	struct hotplug_slot_core *core;
 
 	if (info == NULL)
 		return -ENODEV;
@@ -1090,6 +1043,24 @@
 		return -ENODEV;
 	}
 
+	/*
+	 * check all fields in the info structure, and update timestamps
+	 * for the files referring to the fields that have now changed.
+	 */
+	core = temp->core_priv;
+	if ((core->power_dentry) &&
+	    (temp->info->power_status != info->power_status))
+		update_inode_time (core->power_dentry->d_inode);
+	if ((core->attention_dentry) &&
+	    (temp->info->attention_status != info->attention_status))
+		update_inode_time (core->attention_dentry->d_inode);
+	if ((core->latch_dentry) &&
+	    (temp->info->latch_status != info->latch_status))
+		update_inode_time (core->latch_dentry->d_inode);
+	if ((core->adapter_dentry) &&
+	    (temp->info->adapter_status != info->adapter_status))
+		update_inode_time (core->adapter_dentry->d_inode);
+
 	memcpy (temp->info, info, sizeof (struct hotplug_slot_info));
 	spin_unlock (&list_lock);
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/pcihp_acpi.c linux/drivers/hotplug/pcihp_acpi.c
--- linux.orig/drivers/hotplug/pcihp_acpi.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/pcihp_acpi.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,397 @@
+/*
+ * ACPI PCI Hot Plug Controller Driver
+ *
+ * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001-2002 IBM Corp.
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>,
+ *                  <h-aono@ap.jp.nec.com>,
+ *		    <t-kouchi@cq.jp.nec.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pci_hotplug.h"
+#include "pcihp_acpi.h"
+
+static LIST_HEAD(slot_list);
+
+#if !defined(CONFIG_HOTPLUG_PCI_ACPI_MODULE)
+	#define MY_NAME	"pcihp_acpi"
+#else
+	#define MY_NAME	THIS_MODULE->name
+#endif
+
+/* local variables */
+static int debug = 1;			/* XXX */
+static int num_slots;
+
+#define DRIVER_VERSION	"0.2"
+#define DRIVER_AUTHOR	"Greg Kroah-Hartman <gregkh@us.ibm.com>"
+#define DRIVER_DESC	"ACPI Hot Plug PCI Controller Driver"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+
+static int enable_slot		(struct hotplug_slot *slot);
+static int disable_slot		(struct hotplug_slot *slot);
+static int set_attention_status (struct hotplug_slot *slot, u8 value);
+static int hardware_test	(struct hotplug_slot *slot, u32 value);
+static int get_power_status	(struct hotplug_slot *slot, u8 *value);
+static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
+static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
+static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
+
+static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
+	owner:			THIS_MODULE,
+	enable_slot:		enable_slot,
+	disable_slot:		disable_slot,
+	set_attention_status:	set_attention_status,
+	hardware_test:		hardware_test,
+	get_power_status:	get_power_status,
+	get_attention_status:	get_attention_status,
+	get_latch_status:	get_latch_status,
+	get_adapter_status:	get_adapter_status,
+};
+
+
+/* Inline functions to check the sanity of a pointer that is passed to us */
+static inline int slot_paranoia_check (struct slot *slot, const char *function)
+{
+	if (!slot) {
+		dbg("%s - slot == NULL", function);
+		return -1;
+	}
+	if (slot->magic != SLOT_MAGIC) {
+		dbg("%s - bad magic number for slot", function);
+		return -1;
+	}
+	if (!slot->hotplug_slot) {
+		dbg("%s - slot->hotplug_slot == NULL!", function);
+		return -1;
+	}
+	return 0;
+}
+
+static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
+{ 
+	struct slot *slot;
+
+	if (!hotplug_slot) {
+		dbg("%s - hotplug_slot == NULL", function);
+		return NULL;
+	}
+
+	slot = (struct slot *)hotplug_slot->private;
+	if (slot_paranoia_check (slot, function))
+                return NULL;
+	return slot;
+}
+
+
+static int enable_slot (struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg ("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	/* enable the specified slot */
+	retval = pcihp_acpi_enable_slot (slot->acpi_slot);
+
+	return retval;
+}
+
+static int disable_slot (struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg ("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	/* disable the specified slot */
+	retval = pcihp_acpi_disable_slot (slot->acpi_slot);
+
+	return retval;
+}
+
+static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg ("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	/* TBD
+	 * ACPI doesn't have known method to manipulate
+	 * attention status LED
+	 */
+	switch (status) {
+		case 0:
+			/* FIXME turn light off */
+			slot->attention_status = 0;
+			break;
+
+		case 1:
+		default:
+			/* FIXME turn light on */
+			slot->attention_status = 1;
+			break;
+	}
+
+	return retval;
+}
+
+static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg ("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	err ("No hardware tests are defined for this driver");
+	retval = -ENODEV;
+
+	return retval;
+}
+
+static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	*value = pcihp_acpi_get_power_status (slot->acpi_slot);
+
+	return retval;
+}
+
+static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	*value = slot->attention_status;
+
+	return retval;
+}
+
+static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	*value = pcihp_acpi_get_latch_status (slot->acpi_slot);
+
+	return retval;
+}
+
+static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	*value = pcihp_acpi_get_adapter_status (slot->acpi_slot);
+
+	return retval;
+}
+
+static int init_acpi (void)
+{
+	int retval;
+
+	dbg("init_acpi");		/* XXX */
+	/* initialize internal data structure etc. */
+	retval = pcihp_acpi_glue_init();
+
+	/* read initial number of slots */
+	if (!retval) {
+		num_slots = pcihp_acpi_get_num_slots();
+		if (num_slots == 0)
+			retval = -ENODEV;
+	}
+
+	return retval;
+}
+
+static void exit_acpi (void)
+{
+	/* deallocate internal data structures etc. */
+	pcihp_acpi_glue_exit();
+}
+
+#define SLOT_NAME_SIZE	10
+static void make_slot_name (struct slot *slot)
+{
+	/* FIXME - get this from the ACPI representation of the slot */
+	snprintf (slot->hotplug_slot->name, SLOT_NAME_SIZE, "ACPI%d", slot->number);
+}
+
+static int init_slots (void)
+{
+	struct slot *slot;
+	int retval = 0;
+	int i;
+
+	for (i = 0; i < num_slots; ++i) {
+		slot = kmalloc (sizeof (struct slot), GFP_KERNEL);
+		if (!slot)
+			return -ENOMEM;
+		memset(slot, 0, sizeof(struct slot));
+
+		slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
+		if (!slot->hotplug_slot) {
+			kfree (slot);
+			return -ENOMEM;
+		}
+		memset(slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
+
+		slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+		if (!slot->hotplug_slot->info) {
+			kfree (slot->hotplug_slot);
+			kfree (slot);
+			return -ENOMEM;
+		}
+		memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
+
+		slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
+		if (!slot->hotplug_slot->name) {
+			kfree (slot->hotplug_slot->info);
+			kfree (slot->hotplug_slot);
+			kfree (slot);
+			return -ENOMEM;
+		}
+
+		slot->magic = SLOT_MAGIC;
+		slot->number = i;
+
+		slot->hotplug_slot->private = slot;
+		make_slot_name (slot);
+		slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
+		
+		slot->acpi_slot = get_slot_from_id (i);
+		slot->hotplug_slot->info->power_status = pcihp_acpi_get_power_status(slot->acpi_slot);
+		slot->hotplug_slot->info->attention_status = pcihp_acpi_get_attention_status(slot->acpi_slot);
+		slot->hotplug_slot->info->latch_status = pcihp_acpi_get_latch_status(slot->acpi_slot);
+		slot->hotplug_slot->info->adapter_status = pcihp_acpi_get_adapter_status(slot->acpi_slot);
+
+		dbg ("registering slot %d", i);
+		retval = pci_hp_register (slot->hotplug_slot);
+		if (retval) {
+			err ("pci_hp_register failed with error %d", retval);
+			kfree (slot->hotplug_slot->info);
+			kfree (slot->hotplug_slot->name);
+			kfree (slot->hotplug_slot);
+			kfree (slot);
+			return retval;
+		}
+
+		/* add slot to our internal list */
+		list_add (&slot->slot_list, &slot_list);
+	}
+
+	return retval;
+}
+		
+static void cleanup_slots (void)
+{
+	struct list_head *tmp;
+	struct slot *slot;
+
+	list_for_each (tmp, &slot_list) {
+		slot = list_entry (tmp, struct slot, slot_list);
+		list_del (&slot->slot_list);
+		pci_hp_deregister (slot->hotplug_slot);
+		kfree (slot->hotplug_slot->info);
+		kfree (slot->hotplug_slot->name);
+		kfree (slot->hotplug_slot);
+		kfree (slot);
+	}
+
+	return;
+}
+
+static int __init pcihp_acpi_init(void)
+{
+	int retval;
+
+	/* read all the ACPI info from the system */
+	retval = init_acpi();
+	if (retval)
+		return retval;
+
+	retval = init_slots();
+	if (retval)
+		return retval;
+
+	info (DRIVER_DESC " version: " DRIVER_VERSION);
+	return 0;
+}
+
+static void __exit pcihp_acpi_exit(void)
+{
+	cleanup_slots();
+	exit_acpi();
+}
+
+module_init(pcihp_acpi_init);
+module_exit(pcihp_acpi_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/pcihp_acpi.h linux/drivers/hotplug/pcihp_acpi.h
--- linux.orig/drivers/hotplug/pcihp_acpi.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/pcihp_acpi.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,231 @@
+/*
+ * ACPI PCI Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>,
+ *		    <h-aono@ap.jp.nec.com>,
+ *		    <t-kouchi@cq.jp.nec.com>
+ *
+ */
+
+#ifndef _PCIHP_ACPI_H
+#define _PCIHP_ACPI_H
+
+#include "include/acpi.h"
+
+#if ACPI_CA_VERSION < 0x20020201
+/* until we get a new version of the ACPI driver for both ia32 and ia64 ... */
+#define acpi_util_eval_error(h,p,s)
+
+static acpi_status
+acpi_evaluate_integer (
+	acpi_handle		handle,
+	acpi_string		pathname,
+	acpi_object_list	*arguments,
+	unsigned long		*data)
+{
+	acpi_status             status = AE_OK;
+	acpi_object             element;
+	acpi_buffer		buffer = {sizeof(acpi_object), &element};
+
+	if (!data)
+		return AE_BAD_PARAMETER;
+
+	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_util_eval_error(handle, pathname, status);
+		return status;
+	}
+
+	if (element.type != ACPI_TYPE_INTEGER) {
+		acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
+		return AE_BAD_DATA;
+	}
+
+	*data = element.integer.value;
+
+	return AE_OK;
+}
+#else  /* ACPI_CA_VERSION < 0x20020201 */
+#include "acpi_bus.h"
+#endif /* ACPI_CA_VERSION < 0x20020201 */
+
+/* compatibility stuff */
+#ifndef ACPI_MEMORY_RANGE
+#define ACPI_MEMORY_RANGE MEMORY_RANGE
+#endif
+
+#ifndef ACPI_IO_RANGE
+#define ACPI_IO_RANGE IO_RANGE
+#endif
+
+#ifndef ACPI_BUS_NUMBER_RANGE
+#define ACPI_BUS_NUMBER_RANGE BUS_NUMBER_RANGE
+#endif
+
+#ifndef ACPI_PREFETCHABLE_MEMORY
+#define ACPI_PREFETCHABLE_MEMORY PREFETCHABLE_MEMORY
+#endif
+
+#ifndef ACPI_PRODUCER
+#define ACPI_PRODUCER PRODUCER
+#endif
+
+
+#define dbg(format, arg...)					\
+	do {							\
+		if (debug)					\
+			printk (KERN_DEBUG "%s: " format "\n",	\
+				MY_NAME , ## arg); 		\
+	} while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+
+/*
+ * types and constants
+ */
+
+#define SLOT_MAGIC	0x67267322
+
+struct pcihp_acpi_bridge;
+struct pcihp_acpi_slot;
+
+/* slot information for each *physical* slot */
+
+struct slot {
+	u32 magic;
+	u8 number;
+	struct hotplug_slot	*hotplug_slot;
+	struct list_head	slot_list;
+
+	int			attention_status;
+
+	struct pci_resource	*mem_head;
+	struct pci_resource	*p_mem_head;
+	struct pci_resource	*io_head;
+	struct pci_resource	*bus_head;
+
+	/* if there are multiple corresponding slot objects,
+	   this point to one of them */
+	struct pcihp_acpi_slot	*acpi_slot;
+
+	struct pci_dev		*pci_dev;
+};
+
+#define RESOURCE_TYPE_IO	(1)
+#define RESOURCE_TYPE_MEM	(2)
+#define RESOURCE_TYPE_PREFETCH	(3)
+#define RESOURCE_TYPE_BUS	(4)
+
+/* TBD 64bit resource support */
+struct pci_resource {
+	struct pci_resource * next;
+	u32 base;
+	u32 length;
+};
+
+/* bridge information for each bridge device in ACPI namespace */
+
+struct pcihp_acpi_bridge {
+	struct list_head list;
+	acpi_handle handle;
+	struct pcihp_acpi_slot *slots;
+	int nr_slots;
+	u8 seg;
+	u8 bus;
+	u8 sub;
+	u32 status;
+	u32 flags;
+
+	/* resources on this bus (free resources) */
+	struct pci_resource *free_io;
+	struct pci_resource *free_mem;
+	struct pci_resource *free_prefetch;
+	struct pci_resource *free_bus;
+
+	/* used resources (embedded or owned resources) */
+	struct pci_resource *used_io;
+	struct pci_resource *used_mem;
+	struct pci_resource *used_prefetch;
+	struct pci_resource *used_bus;
+};
+
+/*
+ * slot information for each slot object in ACPI namespace
+ * usually 8 objects per slot (for each PCI function)
+ */
+
+struct pcihp_acpi_slot {
+	struct pcihp_acpi_slot	*next;
+	struct pcihp_acpi_bridge *bridge; /* this slot located on */
+	struct list_head sibling;	/* one slot may have different
+					   objects (i.e. for each function) */
+	acpi_handle	handle;
+	u32		id;		/* slot id (this driver specific) */
+	u8		device;		/* pci device# */
+	u8		function;	/* pci function# */
+	u8		pin;		/* pci interrupt pin */
+	u32		sun;		/* _SUN */
+	u32		flags;		/* see below */
+	u32		status;		/* _STA */
+};
+
+/* PCI bus bridge HID */
+#define ACPI_PCI_ROOT_HID		"PNP0A03"
+
+/* ACPI _STA method value (ignore bit 4; battery present) */
+#define ACPI_STA_PRESENT		(0x00000001)
+#define ACPI_STA_ENABLED		(0x00000002)
+#define ACPI_STA_SHOW_IN_UI		(0x00000004)
+#define ACPI_STA_FUNCTIONAL		(0x00000008)
+#define ACPI_STA_ALL			(0x0000000f)
+
+/* bridge flags */
+#define BRIDGE_HAS_STA	(0x00000001)
+
+/* slot flags */
+
+#define SLOT_HAS_EJ0	(0x00000001)
+#define SLOT_HAS_PS0	(0x00000002)
+#define SLOT_HAS_PS3	(0x00000004)
+
+/* function prototypes */
+
+/* pcihp_acpi_glue.c */
+extern int pcihp_acpi_glue_init (void);
+extern void pcihp_acpi_glue_exit (void);
+extern int pcihp_acpi_get_num_slots (void);
+extern struct pcihp_acpi_slot *get_slot_from_id (int id);
+
+extern int pcihp_acpi_enable_slot (struct pcihp_acpi_slot *slot);
+extern int pcihp_acpi_disable_slot (struct pcihp_acpi_slot *slot);
+extern u8 pcihp_acpi_get_power_status (struct pcihp_acpi_slot *slot);
+extern u8 pcihp_acpi_get_attention_status (struct pcihp_acpi_slot *slot);
+extern u8 pcihp_acpi_get_latch_status (struct pcihp_acpi_slot *slot);
+extern u8 pcihp_acpi_get_adapter_status (struct pcihp_acpi_slot *slot);
+
+#endif /* _PCIHP_ACPI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/pcihp_acpi_ctrl.c linux/drivers/hotplug/pcihp_acpi_ctrl.c
--- linux.orig/drivers/hotplug/pcihp_acpi_ctrl.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/pcihp_acpi_ctrl.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,642 @@
+/*
+ * ACPI PCI HotPlug Utility functions
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>,<h-aono@ap.jp.nec.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+
+#include <linux/ioctl.h>
+#include <linux/fcntl.h>
+
+#include <linux/list.h>
+
+#include <asm/uaccess.h>
+
+#define _LINUX                          /* for acpi subcomponent */
+
+#include "include/acpi.h"
+
+#include "pci_hotplug.h"
+#include "pchihp_acpi.h"
+
+#if !defined(CONFIG_HOTPLUG_PCI_MODULE)
+	#define MY_NAME "pci_hotplug"
+#else
+	#define MY_NAME THIS_MODULE->name
+#endif
+
+#define dbg(fmt, arg...) do { if (debug) printk(KERN_WARNING "%s: "__FUNCTION__": " fmt , MY_NAME , ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+
+
+/* local variables */
+static int debug = 0;
+
+/*
+ * sort_by_size
+ *
+ * Sorts nodes on the list by their length.
+ * Smallest first.
+ *
+ */
+static int sort_by_size(struct pci_resource **head)
+{
+	struct pci_resource *current_res;
+	struct pci_resource *next_res;
+	int out_of_order = 1;
+
+	if (!(*head))
+		return(1);
+
+	if (!((*head)->next))
+		return(0);
+
+	while (out_of_order) {
+		out_of_order = 0;
+
+		// Special case for swapping list head
+		if (((*head)->next) &&
+		    ((*head)->length > (*head)->next->length)) {
+			out_of_order++;
+			current_res = *head;
+			*head = (*head)->next;
+			current_res->next = (*head)->next;
+			(*head)->next = current_res;
+		}
+
+		current_res = *head;
+
+		while (current_res->next && current_res->next->next) {
+			if (current_res->next->length > current_res->next->next->length) {
+				out_of_order++;
+				next_res = current_res->next;
+				current_res->next = current_res->next->next;
+				current_res = current_res->next;
+				next_res->next = current_res->next;
+				current_res->next = next_res;
+			} else
+				current_res = current_res->next;
+		}
+	}  // End of out_of_order loop
+
+	return(0);
+}
+
+
+/*
+ * sort_by_max_size
+ *
+ * Sorts nodes on the list by their length.
+ * Largest first.
+ *
+ */
+static int sort_by_max_size(struct pci_resource **head)
+{
+	struct pci_resource *current_res;
+	struct pci_resource *next_res;
+	int out_of_order = 1;
+
+	if (!(*head))
+		return(1);
+
+	if (!((*head)->next))
+		return(0);
+
+	while (out_of_order) {
+		out_of_order = 0;
+
+		// Special case for swapping list head
+		if (((*head)->next) &&
+		    ((*head)->length < (*head)->next->length)) {
+			out_of_order++;
+			current_res = *head;
+			*head = (*head)->next;
+			current_res->next = (*head)->next;
+			(*head)->next = current_res;
+		}
+
+		current_res = *head;
+
+		while (current_res->next && current_res->next->next) {
+			if (current_res->next->length < current_res->next->next->length) {
+				out_of_order++;
+				next_res = current_res->next;
+				current_res->next = current_res->next->next;
+				current_res = current_res->next;
+				next_res->next = current_res->next;
+				current_res->next = next_res;
+			} else
+				current_res = current_res->next;
+		}
+	}  // End of out_of_order loop
+
+	return(0);
+}
+
+/*
+ * get_io_resource
+ *
+ * this function sorts the resource list by size and then
+ * returns the first node of "size" length that is not in the
+ * ISA aliasing window.  If it finds a node larger than "size"
+ * it will split it up.
+ *
+ * size must be a power of two.
+ */
+struct pci_resource *hotplug_get_io_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *prevnode;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u32 temp_dword;
+
+	if (!(*head))
+		return(NULL);
+
+	if ( hotplug_resource_sort_and_combine(head) )
+		return(NULL);
+
+	if ( sort_by_size(head) )
+		return(NULL);
+
+	for (node = *head; node; node = node->next) {
+		if (node->length < size)
+			continue;
+
+		if (node->base & (size - 1)) {
+			// this one isn't base aligned properly
+			// so we'll make a new entry and split it up
+			temp_dword = (node->base | (size-1)) + 1;
+
+			// Short circuit if adjusted size is too small
+			if ((node->length - (temp_dword - node->base)) < size)
+				continue;
+
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base;
+			split_node->length = temp_dword - node->base;
+			node->base = temp_dword;
+			node->length -= split_node->length;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		} // End of non-aligned base
+
+		// Don't need to check if too small since we already did
+		if (node->length > size) {
+			// this one is longer than we need
+			// so we'll make a new entry and split it up
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base + size;
+			split_node->length = node->length - size;
+			node->length = size;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		}  // End of too big on top end
+
+		// For IO make sure it's not in the ISA aliasing space
+		if (node->base & 0x300L)
+			continue;
+
+		// If we got here, then it is the right size
+		// Now take it out of the list
+		if (*head == node) {
+			*head = node->next;
+		} else {
+			prevnode = *head;
+			while (prevnode->next != node)
+				prevnode = prevnode->next;
+
+			prevnode->next = node->next;
+		}
+		node->next = NULL;
+		// Stop looping
+		break;
+	}
+
+	return(node);
+}
+
+
+/*
+ * get_max_resource
+ *
+ * Gets the largest node that is at least "size" big from the
+ * list pointed to by head.  It aligns the node on top and bottom
+ * to "size" alignment before returning it.
+ */
+struct pci_resource *hotplug_get_max_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *max;
+	struct pci_resource *temp;
+	struct pci_resource *split_node;
+	u32 temp_dword;
+
+	if (!(*head))
+		return(NULL);
+
+	if (hotplug_resource_sort_and_combine(head))
+		return(NULL);
+
+	if (sort_by_max_size(head))
+		return(NULL);
+
+	for (max = *head;max; max = max->next) {
+
+		// If not big enough we could probably just bail, 
+		// instead we'll continue to the next.
+		if (max->length < size)
+			continue;
+
+		if (max->base & (size - 1)) {
+			// this one isn't base aligned properly
+			// so we'll make a new entry and split it up
+			temp_dword = (max->base | (size-1)) + 1;
+
+			// Short circuit if adjusted size is too small
+			if ((max->length - (temp_dword - max->base)) < size)
+				continue;
+
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = max->base;
+			split_node->length = temp_dword - max->base;
+			max->base = temp_dword;
+			max->length -= split_node->length;
+
+			// Put it next in the list
+			split_node->next = max->next;
+			max->next = split_node;
+		}
+
+		if ((max->base + max->length) & (size - 1)) {
+			// this one isn't end aligned properly at the top
+			// so we'll make a new entry and split it up
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+			temp_dword = ((max->base + max->length) & ~(size - 1));
+			split_node->base = temp_dword;
+			split_node->length = max->length + max->base
+					     - split_node->base;
+			max->length -= split_node->length;
+
+			// Put it in the list
+			split_node->next = max->next;
+			max->next = split_node;
+		}
+
+		// Make sure it didn't shrink too much when we aligned it
+		if (max->length < size)
+			continue;
+
+		// Now take it out of the list
+		temp = (struct pci_resource*) *head;
+		if (temp == max) {
+			*head = max->next;
+		} else {
+			while (temp && temp->next != max) {
+				temp = temp->next;
+			}
+
+			temp->next = max->next;
+		}
+
+		max->next = NULL;
+		return(max);
+	}
+
+	// If we get here, we couldn't find one
+	return(NULL);
+}
+
+
+/*
+ * get_resource
+ *
+ * this function sorts the resource list by size and then
+ * returns the first node of "size" length.  If it finds a node
+ * larger than "size" it will split it up.
+ *
+ * size must be a power of two.
+ */
+struct pci_resource *hotplug_get_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *prevnode;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u32 temp_dword;
+
+	if (!(*head))
+		return(NULL);
+
+	if ( hotplug_resource_sort_and_combine(head) )
+		return(NULL);
+
+	if ( sort_by_size(head) )
+		return(NULL);
+
+	for (node = *head; node; node = node->next) {
+		dbg(__FUNCTION__": req_size =%x node=%p, base=%x, length=%x\n",
+		    size, node, node->base, node->length);
+		if (node->length < size)
+			continue;
+
+		if (node->base & (size - 1)) {
+			dbg(__FUNCTION__": not aligned\n");
+			// this one isn't base aligned properly
+			// so we'll make a new entry and split it up
+			temp_dword = (node->base | (size-1)) + 1;
+
+			// Short circuit if adjusted size is too small
+			if ((node->length - (temp_dword - node->base)) < size)
+				continue;
+
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base;
+			split_node->length = temp_dword - node->base;
+			node->base = temp_dword;
+			node->length -= split_node->length;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		} // End of non-aligned base
+
+		// Don't need to check if too small since we already did
+		if (node->length > size) {
+			dbg(__FUNCTION__": too big\n");
+			// this one is longer than we need
+			// so we'll make a new entry and split it up
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base + size;
+			split_node->length = node->length - size;
+			node->length = size;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		}  // End of too big on top end
+
+		dbg(__FUNCTION__": got one!!!\n");
+		// If we got here, then it is the right size
+		// Now take it out of the list
+		if (*head == node) {
+			*head = node->next;
+		} else {
+			prevnode = *head;
+			while (prevnode->next != node)
+				prevnode = prevnode->next;
+
+			prevnode->next = node->next;
+		}
+		node->next = NULL;
+		// Stop looping
+		break;
+	}
+	return(node);
+}
+
+/*
+ * get_resource_with_base
+ *
+ * this function 
+ * returns the first node of "size" length located at specified base address.
+ * If it finds a node larger than "size" it will split it up.
+ *
+ * size must be a power of two.
+ */
+struct pci_resource *hotplug_get_resource_with_base (struct pci_resource **head, u32 base, u32 size)
+{
+	struct pci_resource *prevnode;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u32 temp_dword;
+
+	if (!(*head))
+		return(NULL);
+
+	if ( hotplug_resource_sort_and_combine(head) )
+		return(NULL);
+
+	for (node = *head; node; node = node->next) {
+		dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
+		    base, size, node, node->base, node->length);
+		if (node->base > base)
+			continue;
+
+		if ((node->base + node->length) < (base + size))
+			continue;
+
+		if (node->base < base) {
+			dbg(": split 1\n");
+			// this one isn't base aligned properly
+			// so we'll make a new entry and split it up
+			temp_dword = base;
+
+			// Short circuit if adjusted size is too small
+			if ((node->length - (temp_dword - node->base)) < size)
+				continue;
+
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base;
+			split_node->length = temp_dword - node->base;
+			node->base = temp_dword;
+			node->length -= split_node->length;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		}
+
+		dbg(": 2st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
+		    base, size, node, node->base, node->length);
+
+		// Don't need to check if too small since we already did
+		if (node->length >= size) {
+			dbg(": split 2\n");
+			// this one is longer than we need
+			// so we'll make a new entry and split it up
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base + size;
+			split_node->length = node->length - size;
+			node->length = size;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		}  // End of too big on top end
+
+		dbg(": got one!!!\n");
+		// If we got here, then it is the right size
+		// Now take it out of the list
+		if (*head == node) {
+			*head = node->next;
+		} else {
+			prevnode = *head;
+			while (prevnode->next != node)
+				prevnode = prevnode->next;
+
+			prevnode->next = node->next;
+		}
+		node->next = NULL;
+		// Stop looping
+		break;
+	}
+	return(node);
+}
+
+/*
+ * hotplug_resource_sort_and_combine
+ *
+ * Sorts all of the nodes in the list in ascending order by
+ * their base addresses.  Also does garbage collection by
+ * combining adjacent nodes.
+ *
+ * returns 0 if success
+ */
+int hotplug_resource_sort_and_combine(struct pci_resource **head)
+{
+	struct pci_resource *node1;
+	struct pci_resource *node2;
+	int out_of_order = 1;
+
+	dbg(__FUNCTION__": head = %p, *head = %p\n", head, *head);
+
+	if (!(*head))
+		return(1);
+
+	dbg("*head->next = %p\n",(*head)->next);
+
+	if (!(*head)->next)
+		return(0);	/* only one item on the list, already sorted! */
+
+	dbg("*head->base = 0x%x\n",(*head)->base);
+	dbg("*head->next->base = 0x%x\n",(*head)->next->base);
+	while (out_of_order) {
+		out_of_order = 0;
+
+		// Special case for swapping list head
+		if (((*head)->next) &&
+		    ((*head)->base > (*head)->next->base)) {
+			node1 = *head;
+			(*head) = (*head)->next;
+			node1->next = (*head)->next;
+			(*head)->next = node1;
+			out_of_order++;
+		}
+
+		node1 = (*head);
+
+		while (node1->next && node1->next->next) {
+			if (node1->next->base > node1->next->next->base) {
+				out_of_order++;
+				node2 = node1->next;
+				node1->next = node1->next->next;
+				node1 = node1->next;
+				node2->next = node1->next;
+				node1->next = node2;
+			} else
+				node1 = node1->next;
+		}
+	}  // End of out_of_order loop
+
+	node1 = *head;
+
+	while (node1 && node1->next) {
+		if ((node1->base + node1->length) == node1->next->base) {
+			// Combine
+			dbg("8..\n");
+			node1->length += node1->next->length;
+			node2 = node1->next;
+			node1->next = node1->next->next;
+			kfree(node2);
+		} else
+			node1 = node1->next;
+	}
+
+	return(0);
+}
+
+/*
+EXPORT_SYMBOL(hotplug_get_io_resource);
+EXPORT_SYMBOL(hotplug_get_max_resource);
+EXPORT_SYMBOL(hotplug_get_resource);
+EXPORT_SYMBOL(hotplug_resource_sort_and_combine);
+*/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/hotplug/pcihp_acpi_glue.c linux/drivers/hotplug/pcihp_acpi_glue.c
--- linux.orig/drivers/hotplug/pcihp_acpi_glue.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hotplug/pcihp_acpi_glue.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,757 @@
+/*
+ * ACPI PCI HotPlug glue functions to ACPI CA subsystem
+ *
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <t-kouchi@cq.jp.nec.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pcihp_acpi.h"
+
+/*
+ * TODO:
+ * resource management
+ * irq related interface? (_PRT)
+ * consider locking
+ */
+
+static LIST_HEAD(bridge_list);
+
+static int debug = 1;			/* XXX set 0 after debug */
+#define MY_NAME "pcihp_acpi_glue"
+
+static void handle_hotplug_event (acpi_handle, u32, void *);
+
+/*
+ * initialization & terminatation routines
+ */
+
+/*
+ * Ejectable slot satisfies at least these conditions:
+ *  1. has _ADR method
+ *  2. has _STA method
+ *  3. has _EJ0 method
+ *
+ * optionally
+ *  1. has _PS0 method
+ *  2. has _PS3 method
+ *  3. TBD...
+ */
+
+/* callback routine to check the existence of ejectable slots */
+static acpi_status
+is_ejectable_slot (acpi_handle handle, u32 lvl,	void *context, void **rv)
+{
+	acpi_status status;
+	acpi_handle tmp;
+	int *count = (int *)context;
+
+	status = acpi_get_handle(handle, "_ADR", &tmp);
+
+	if (ACPI_FAILURE(status)) {
+		return AE_OK;
+	}
+
+	status = acpi_get_handle(handle, "_STA", &tmp);
+
+	if (ACPI_FAILURE(status)) {
+		return AE_OK;
+	}
+
+	status = acpi_get_handle(handle, "_EJ0", &tmp);
+
+	if (ACPI_FAILURE(status)) {
+		return AE_OK;
+	}
+
+	(*count)++;
+
+	/* only one ejectable slot is enough */
+	return AE_CTRL_TERMINATE;
+}
+
+
+/* callback routine to register each ACPI PCI slot object */
+static acpi_status
+register_slot (acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	struct pcihp_acpi_bridge *bridge = (struct pcihp_acpi_bridge *)context;
+	struct pcihp_acpi_slot *slot, *newslot;
+	acpi_handle tmp;
+	acpi_status status = AE_OK;
+	static int num_slots = 0;	/* XXX */
+	unsigned long adr, sun, sta;
+
+	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
+
+	if (ACPI_FAILURE(status)) {
+		return AE_OK;
+	}
+
+	status = acpi_get_handle(handle, "_EJ0", &tmp);
+
+	if (ACPI_FAILURE(status)) {
+		dbg("This slot doesn't have _EJ0");
+		//return AE_OK;
+	}
+
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+
+	if (ACPI_FAILURE(status)) {
+		dbg("This slot doesn't have _STA");
+		//return AE_OK;
+	}
+
+	newslot = kmalloc(sizeof(struct pcihp_acpi_slot), GFP_KERNEL);
+	if (!newslot) {
+		return AE_NO_MEMORY;
+	}
+
+	memset(newslot, 0, sizeof(struct pcihp_acpi_slot));
+
+	INIT_LIST_HEAD(&newslot->sibling);
+	newslot->bridge = bridge;
+	newslot->handle = handle;
+	newslot->device = (adr >> 16) & 0xffff;
+	newslot->function = adr & 0xffff;
+	newslot->status = sta;
+	newslot->sun = -1;
+	newslot->flags = SLOT_HAS_EJ0;
+	newslot->id = num_slots++;
+	bridge->nr_slots++;
+
+	dbg("new slot id=%d device=0x%d function=0x%x", newslot->id, newslot->device, newslot->function);
+
+	status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
+	if (ACPI_SUCCESS(status)) {
+		newslot->sun = sun;
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS0", &tmp))) {
+		newslot->flags |= SLOT_HAS_PS0;
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp))) {
+		newslot->flags |= SLOT_HAS_PS3;
+	}
+
+	/* search for objects that share the same slot */
+	for (slot = bridge->slots; slot; slot = slot->next)
+		if (slot->device == newslot->device) {
+			dbg("found a sibling slot!");
+			list_add(&slot->sibling, &newslot->sibling);
+			newslot->id = slot->id;
+			num_slots --;
+			bridge->nr_slots --;
+			break;
+		}
+
+	/* link myself to bridge's slot list */
+	newslot->next = bridge->slots;
+	bridge->slots = newslot;
+
+	return AE_OK;
+}
+
+/* see if it's worth managing this brige */
+static int
+detect_ejectable_slots (acpi_handle *root)
+{
+	acpi_status status;
+	int count;
+
+	count = 0;
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root, ACPI_UINT32_MAX,
+				     is_ejectable_slot, (void *)&count, NULL);
+
+	dbg("%s: count=%d", __FUNCTION__, count);
+	return count;
+}
+
+
+/*
+ * push one resource to resource list
+ *
+ * TBD: use hotplug_resource_sort_and_combine
+ * TBD: 64bit resource handling (is it really used?)
+ */
+static void
+push_resource (u32 base, u32 length, struct pci_resource **resource)
+{
+	struct pci_resource *resp, *newres;
+	int coalesced = 0;
+
+	if (length == 0) {
+		dbg("zero sized resource. ignored.");
+		return;
+	}
+
+	for (resp = *resource; resp; resp = resp->next) {
+
+		/* coalesce contiguous region */
+
+		if (resp->base + resp->length == base) {
+			resp->length += length;
+			coalesced = 1;
+			break;
+		}
+	}
+
+	if (!coalesced) {
+		newres = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+		if (!newres) {
+			/* TBD panic? */
+			return;
+		}
+		newres->base = base;
+		newres->length = length;
+		newres->next = (*resource);
+		*resource = newres;
+	}
+}
+
+
+/* decode ACPI _CRS data and convert into our internal resource list */
+static void
+decode_acpi_resource (acpi_resource *resource, struct pcihp_acpi_bridge *bridge)
+{
+	acpi_resource_address16 *address16_data;
+	acpi_resource_address32 *address32_data;
+	//acpi_resource_address64 *address64_data;
+
+	u32 resource_type, producer_consumer, min_address_range, max_address_range, address_length;
+	u16 cache_attribute = 0;
+
+	int done = 0, found;
+
+	/* shut up gcc */
+	resource_type = producer_consumer = min_address_range = max_address_range = address_length = 0;
+
+	while (!done) {
+		found = 0;
+
+		switch (resource->id) {
+		case ACPI_RSTYPE_ADDRESS16:
+			address16_data = (acpi_resource_address16 *)&resource->data;
+			resource_type = address16_data->resource_type;
+			producer_consumer = address16_data->producer_consumer;
+			min_address_range = address16_data->min_address_range;
+			max_address_range = address16_data->max_address_range;
+			address_length = address16_data->address_length;
+			if (resource_type == ACPI_MEMORY_RANGE)
+				cache_attribute = address16_data->attribute.memory.cache_attribute;
+			found = 1;
+			break;
+
+		case ACPI_RSTYPE_ADDRESS32:
+			address32_data = (acpi_resource_address32 *)&resource->data;
+			resource_type = address32_data->resource_type;
+			producer_consumer = address32_data->producer_consumer;
+			min_address_range = address32_data->min_address_range;
+			max_address_range = address32_data->max_address_range;
+			address_length = address32_data->address_length;
+			if (resource_type == ACPI_MEMORY_RANGE)
+				cache_attribute = address32_data->attribute.memory.cache_attribute;
+			found = 1;
+			break;
+/*
+		case ACPI_RSTYPE_ADDRESS64:
+			address64_data = (acpi_resource_address64 *)&resource->data;
+			resource_type = address64_data->resource_type;
+			break;
+*/
+		case ACPI_RSTYPE_END_TAG:
+			done = 1;
+			break;
+
+		default:
+			/* ignore */
+			break;
+		}
+
+		resource = (acpi_resource *)((char*)resource + resource->length);
+		if (found && producer_consumer == ACPI_PRODUCER) {
+			switch (resource_type) {
+			case ACPI_MEMORY_RANGE:
+				if (cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
+					dbg("resource type: prefetchable memory 0x%x - 0x%x", min_address_range, max_address_range);
+					push_resource(min_address_range,
+						      address_length,
+						      &bridge->free_prefetch);
+				} else {
+					dbg("resource type: memory 0x%x - 0x%x", min_address_range, max_address_range);
+					push_resource(min_address_range,
+						      address_length,
+						      &bridge->free_mem);
+				}
+				break;
+			case ACPI_IO_RANGE:
+				dbg("resource type: io 0x%x - 0x%x", min_address_range, max_address_range);
+				push_resource(min_address_range,
+					      address_length,
+					      &bridge->free_io);
+				break;
+			case ACPI_BUS_NUMBER_RANGE:
+				dbg("resource type: bus number %d - %d", min_address_range, max_address_range);
+				push_resource(min_address_range,
+					      address_length,
+					      &bridge->free_bus);
+				break;
+			default:
+				/* invalid type */
+				break;
+			}
+		}
+	}
+}
+
+
+/* allocate and initialize bridge data structure */
+static int add_bridge (acpi_handle *handle)
+{
+	struct pcihp_acpi_bridge *bridge;
+ 	acpi_status status;
+	acpi_buffer buffer;
+	unsigned long tmp;
+	acpi_handle dummy_handle;
+	int sta = -1;
+
+	status = acpi_get_handle(handle, "_STA", &dummy_handle);
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
+		if (ACPI_FAILURE(status)) {
+			dbg("%s: _STA evaluation failure", __FUNCTION__);
+			return 0;
+		}
+		sta = tmp;
+	}
+
+	if (sta >= 0 && !(sta & ACPI_STA_PRESENT))
+		/* don't register this object */
+		return 0;
+
+	dbg("%s: _STA: 0x%x", __FUNCTION__, (unsigned int)sta);
+
+	/* check if this bridge has ejectable slots */
+
+	detect_ejectable_slots(handle);
+	//if (detect_ejectable_slots(handle) == 0)
+	//return 0;
+
+	/* allocate per-bridge data structure and fill in */
+
+	bridge = kmalloc(sizeof(struct pcihp_acpi_bridge), GFP_KERNEL);
+	if (bridge == NULL)
+		return -ENOMEM;
+
+	memset(bridge, 0, sizeof(struct pcihp_acpi_bridge));
+
+	if (sta >= 0)
+		bridge->flags |= BRIDGE_HAS_STA;
+
+	/* get PCI segment number */
+	status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
+
+	if (ACPI_SUCCESS(status)) {
+		bridge->seg = tmp;
+	} else {
+		bridge->seg = 0;
+	}
+
+	/* get PCI bus number */
+	status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
+
+	if (ACPI_SUCCESS(status)) {
+		bridge->bus = tmp;
+	} else {
+		bridge->bus = 0;
+	}
+
+	/* to be overridden when we decode _CRS	*/
+	bridge->sub = bridge->bus;
+
+	/* register all slot objects under this bridge */
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX,
+				     register_slot, bridge, NULL);
+
+	/* decode resources */
+	buffer.length = 0;
+	buffer.pointer = NULL;
+
+	
+	/* TBD use new ACPI_ALLOCATE_BUFFER */
+	status = acpi_get_current_resources(handle, &buffer);
+	if (status != AE_BUFFER_OVERFLOW) {
+		return -1;
+	}
+
+	buffer.pointer = kmalloc(buffer.length, GFP_KERNEL);
+	if (!buffer.pointer) {
+		return -1;
+	}
+
+	status = acpi_get_current_resources(handle, &buffer);
+	if (ACPI_FAILURE(status)) {
+		return -1;
+	}
+
+	decode_acpi_resource(buffer.pointer, bridge);
+
+	/* TBD decode _HPP (hot plug parameters) */
+	// decode_hpp(bridge);
+
+	kfree(buffer.pointer);
+
+	/* check already allocated resources */
+	/* TBD */
+
+	/* install notify handler */
+	dbg("installing notify handler");
+	status = acpi_install_notify_handler(handle,
+					     ACPI_SYSTEM_NOTIFY,
+					     handle_hotplug_event, NULL);
+
+	if (ACPI_FAILURE(status)) {
+		err("failed to register interrupt notify handler");
+	}
+
+	list_add(&bridge->list, &bridge_list);
+
+	return 0;
+}
+
+
+/* callback routine to enumerate all the bridges in ACPI namespace */
+static acpi_status
+check_pci_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	acpi_device_info info;
+	char objname[5];
+	acpi_buffer buffer = { sizeof(objname), objname };
+
+	status = acpi_get_object_info(handle, &info);
+	if (ACPI_FAILURE(status)) {
+		dbg("%s: failed to get bridge information", __FUNCTION__);
+		return AE_OK;		/* continue */
+	}
+
+	info.hardware_id[sizeof(info.hardware_id)-1] = '\0';
+
+	if (strcmp(info.hardware_id, ACPI_PCI_ROOT_HID) == 0) {
+
+		acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
+		dbg("%s: found PCI root bridge[%s]", __FUNCTION__, objname);
+
+		add_bridge(handle);
+	}
+	return AE_OK;
+}
+
+
+/* interrupt handler */
+static void handle_hotplug_event (acpi_handle handle, u32 type, void *data)
+{
+	char objname[5];
+	acpi_buffer buffer = { sizeof(objname), objname };
+
+	acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
+
+	switch (type) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		/* hot insertion/surprise removal */
+		/* TBD */
+		dbg("%s: Bus check notify on %s", __FUNCTION__, objname);
+		break;
+
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		/* TBD */
+		dbg("%s: Device check notify on %s", __FUNCTION__, objname);
+		break;
+
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		/* eject button pushed */
+		/* TBD */
+		dbg("%s: Device eject notify on %s", __FUNCTION__, objname);
+		break;
+
+	default:
+		warn("notify_handler: unknown event type 0x%x", type);
+		break;
+	}
+}
+
+
+/*
+ * external interfaces
+ */
+
+int pcihp_acpi_glue_init (void)
+{
+	acpi_status status;
+
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX, check_pci_bridge,
+				     NULL, NULL);
+
+	if (ACPI_FAILURE(status)) {
+		dbg("%s: acpi_walk_namespace() failed", __FUNCTION__);
+	}
+
+	return 0;
+}
+
+static void free_all_resources (struct pcihp_acpi_bridge *bridge)
+{
+	struct pci_resource *res, *next;;
+
+	for (res = bridge->free_io; res; ) {
+		next = res->next;
+		kfree(res);
+		res = next;
+	}
+
+	for (res = bridge->free_mem; res; ) {
+		next = res->next;
+		kfree(res);
+		res = next;
+	}
+
+	for (res = bridge->free_prefetch; res; ) {
+		next = res->next;
+		kfree(res);
+		res = next;
+	}
+
+	for (res = bridge->free_bus; res; ) {
+		next = res->next;
+		kfree(res);
+		res = next;
+	}
+}
+
+
+void pcihp_acpi_glue_exit (void)
+{
+	struct list_head *node;
+	struct pcihp_acpi_bridge *bridge;
+	struct pcihp_acpi_slot *slot, *next;
+
+	list_for_each(node, &bridge_list) {
+		bridge = (struct pcihp_acpi_bridge *)node;
+		slot = bridge->slots;
+		while (slot) {
+			next = slot->next;
+			kfree(slot);
+			slot = next;
+		}
+		free_all_resources(bridge);
+		kfree(bridge);
+	}
+}
+
+
+int pcihp_acpi_get_num_slots (void)
+{
+	struct list_head *node;
+	struct pcihp_acpi_bridge *bridge;
+	int num_slots;
+
+	num_slots = 0;
+
+	list_for_each(node, &bridge_list) {
+		bridge = (struct pcihp_acpi_bridge *)node;
+		dbg("Bus:%d num_slots:%d", bridge->bus, bridge->nr_slots);
+		num_slots += bridge->nr_slots;
+	}
+
+	dbg("num_slots = %d", num_slots);
+	return num_slots;
+}
+
+
+/*  TBD: improve performance */
+struct pcihp_acpi_slot *get_slot_from_id (int id)
+{
+	struct list_head *node;
+	struct pcihp_acpi_bridge *bridge;
+	struct pcihp_acpi_slot *slot;
+
+	list_for_each(node, &bridge_list) {
+		bridge = (struct pcihp_acpi_bridge *)node;
+		for (slot = bridge->slots; slot; slot = slot->next)
+			if (slot->id == id)
+				return slot;
+	}
+
+	/* should never happen! */
+	dbg("%s: no object for id %d",__FUNCTION__, id);
+	return 0;
+}
+
+
+/* power on slot */
+int pcihp_acpi_enable_slot (struct pcihp_acpi_slot *slot)
+{
+	acpi_status status;
+
+	if (slot->flags & SLOT_HAS_PS0) {
+		dbg("%s: powering on bus%d/dev%d.", __FUNCTION__,
+		    slot->bridge->bus, slot->device);
+		status = acpi_evaluate_object(slot->handle, "_PS0", NULL, NULL);
+		if (ACPI_FAILURE(status)) {
+			warn("%s: powering on bus%d/dev%d failed",
+			     __FUNCTION__, slot->bridge->bus, slot->device);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+
+/* power off slot */
+int pcihp_acpi_disable_slot (struct pcihp_acpi_slot *slot)
+{
+	acpi_status status;
+
+	if (slot->flags & SLOT_HAS_PS3) {
+		dbg("%s: powering off bus%d/dev%d.", __FUNCTION__,
+		    slot->bridge->bus, slot->device);
+		status = acpi_evaluate_object(slot->handle, "_PS3", NULL, NULL);
+		if (ACPI_FAILURE(status)) {
+			warn("%s: _PS3 on bus%d/dev%d failed",
+			     __FUNCTION__, slot->bridge->bus, slot->device);
+			return -1;
+		}
+	}
+
+	if (slot->flags & SLOT_HAS_EJ0) {
+		dbg("%s: eject bus%d/dev%d.", __FUNCTION__,
+		    slot->bridge->bus, slot->device);
+		status = acpi_evaluate_object(slot->handle, "_EJ0", NULL, NULL);
+		if (ACPI_FAILURE(status)) {
+			warn("%s: _EJ0 bus%d/dev%d failed",
+			     __FUNCTION__, slot->bridge->bus, slot->device);
+			return -1;
+		}
+	}
+
+	/* TBD
+	 * evaluate _STA to check if state is successfully changed
+	 * and update status
+	 */
+
+	return 0;
+}
+
+
+static unsigned int get_slot_status(struct pcihp_acpi_slot *slot)
+{
+	acpi_status status;
+	unsigned long sta;
+
+	status = acpi_evaluate_integer(slot->handle, "_STA", NULL, &sta);
+
+	if (ACPI_FAILURE(status)) {
+		err("%s: _STA evaluation failed", __FUNCTION__);
+		return 0;
+	}
+
+	return (int)sta;
+}
+
+
+/*
+ * slot enabled:  1
+ * slot disabled: 0
+ */
+u8 pcihp_acpi_get_power_status (struct pcihp_acpi_slot *slot)
+{
+	unsigned int sta;
+
+	/* TBD
+	 * . guarantee check _STA on function# 0
+	 * . check configuration space before _STA?
+	 */
+
+	sta = get_slot_status(slot);
+
+	return (sta & ACPI_STA_ENABLED) ? 1 : 0;
+}
+
+
+/* XXX this function is not used */
+/* 
+ * attention LED ON: 1
+ *              OFF: 0
+ */
+u8 pcihp_acpi_get_attention_status (struct pcihp_acpi_slot *slot)
+{
+	/* TBD
+	 * no direct attention led status information via ACPI
+	 */
+
+	return 0;
+}
+
+
+/*
+ * latch closed:  1
+ * latch   open:  0
+ */
+u8 pcihp_acpi_get_latch_status (struct pcihp_acpi_slot *slot)
+{
+	unsigned int sta;
+
+	/* TBD
+	 * no direct latch information via ACPI
+	 */
+
+	sta = get_slot_status(slot);
+
+	return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0;
+}
+
+
+/*
+ * adapter presence : 2
+ *          absence : 0
+ */
+u8 pcihp_acpi_get_adapter_status (struct pcihp_acpi_slot *slot)
+{
+	unsigned int sta;
+
+	/* TBD
+	 * is this information correct?
+	 */
+
+	sta = get_slot_status(slot);
+
+	return (sta == 0) ? 0 : 2;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/i2c/i2c-adap-ite.c linux/drivers/i2c/i2c-adap-ite.c
--- linux.orig/drivers/i2c/i2c-adap-ite.c	2001-10-11 15:05:47.000000000 +0000
+++ linux/drivers/i2c/i2c-adap-ite.c	2002-07-20 01:08:28.000000000 +0000
@@ -241,7 +241,7 @@
 };
 
 /* Called when the module is loaded.  This function starts the
- * cascade of calls up through the heirarchy of i2c modules (i.e. up to the
+ * cascade of calls up through the hierarchy of i2c modules (i.e. up to the
  *  algorithm layer and into to the core layer)
  */
 static int __init iic_ite_init(void) 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/i2c/i2c-algo-bit.c linux/drivers/i2c/i2c-algo-bit.c
--- linux.orig/drivers/i2c/i2c-algo-bit.c	2001-10-11 15:05:47.000000000 +0000
+++ linux/drivers/i2c/i2c-algo-bit.c	2002-07-20 01:08:21.000000000 +0000
@@ -49,7 +49,7 @@
 /* respectively. This makes sure that the algorithm works. Some chips   */
 /* might not like this, as they have an internal timeout of some mils	*/
 /*
-#define SLO_IO      jif=jiffies;while(jiffies<=jif+i2c_table[minor].veryslow)\
+#define SLO_IO      jif=jiffies;while(time_before_eq(jiffies, jif+i2c_table[minor].veryslow))\
                         if (need_resched) schedule();
 */
 
@@ -117,7 +117,7 @@
  		 * while they are processing data internally. 
  		 */
 		setscl(adap,1);
-		if (start+adap->timeout <= jiffies) {
+		if (time_after_eq(jiffies, start+adap->timeout)) {
 			return -ETIMEDOUT;
 		}
 		if (current->need_resched)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/i2c/i2c-core.c linux/drivers/i2c/i2c-core.c
--- linux.orig/drivers/i2c/i2c-core.c	2001-11-06 02:15:40.000000000 +0000
+++ linux/drivers/i2c/i2c-core.c	2002-07-20 01:08:26.000000000 +0000
@@ -381,10 +381,10 @@
 						printk("i2c-core.o: while "
 						       "unregistering driver "
 						       "`%s', the client at "
-						       "address %02x of
-						       adapter `%s' could not
-						       be detached; driver
-						       not unloaded!",
+						       "address %02x of "
+						       "adapter `%s' could not"
+						       "be detached; driver"
+						       "not unloaded!",
 						       driver->name,
 						       client->addr,
 						       adap->name);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/i2c/i2c-keywest.c linux/drivers/i2c/i2c-keywest.c
--- linux.orig/drivers/i2c/i2c-keywest.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/i2c/i2c-keywest.c	2002-07-20 01:08:37.000000000 +0000
@@ -434,7 +434,7 @@
 			u8 isr = wait_interrupt(iface);
 			handle_interrupt(iface, isr);
 		}
-#else /* POLLED_MODE */88
+#else /* POLLED_MODE */
 		DBG("using interrupt mode...\n");
 		wait_for_completion(&iface->complete);	
 #endif /* POLLED_MODE */	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/Config.in linux/drivers/ide/Config.in
--- linux.orig/drivers/ide/Config.in	2001-10-08 18:40:13.000000000 +0000
+++ linux/drivers/ide/Config.in	2002-07-20 01:08:33.000000000 +0000
@@ -14,6 +14,7 @@
 
    dep_tristate '  Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE
    dep_mbool '    Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE $CONFIG_BLK_DEV_IDEDISK
+   dep_mbool '    Auto-Geometry Resizing support' CONFIG_IDEDISK_STROKE $CONFIG_BLK_DEV_IDEDISK
 
    define_bool CONFIG_BLK_DEV_IDEDISK_VENDOR n
    dep_mbool '    Fujitsu Vendor Specific' CONFIG_BLK_DEV_IDEDISK_FUJITSU $CONFIG_BLK_DEV_IDEDISK_VENDOR
@@ -32,6 +33,9 @@
    dep_tristate '  Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
    dep_tristate '  SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI
 
+   bool '  IDE Taskfile Access' CONFIG_IDE_TASK_IOCTL
+#   bool '  IDE Taskfile IO' CONFIG_IDE_TASKFILE_IO
+
    comment 'IDE chipset support/bugfixes'
    if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
       dep_bool '  CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640 $CONFIG_X86
@@ -43,14 +47,17 @@
 	 if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then
 	    bool '    Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ
 	    bool '    Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI
-#	    bool '    Asynchronous DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_ADMA $CONFIG_BLK_DEV_IDEDMA_PCI
-	    define_bool CONFIG_BLK_DEV_ADMA $CONFIG_BLK_DEV_IDEDMA_PCI
 	    bool '    Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
+	    dep_bool '      Force enable legacy 2.0.X HOSTS to use DMA' CONFIG_BLK_DEV_IDEDMA_FORCED $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_bool '      Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
+            dep_bool '    Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
 	    define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_bool '      ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
-#	    dep_bool '      Attempt to HACK around Chipsets that TIMEOUT (WIP)' CONFIG_BLK_DEV_IDEDMA_TIMEOUT $CONFIG_IDEDMA_PCI_WIP
+	    dep_bool '      Attempt to HACK around Chipsets that TIMEOUT (WIP)' CONFIG_BLK_DEV_IDEDMA_TIMEOUT $CONFIG_IDEDMA_PCI_WIP
 	    dep_bool '      Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP
+#	    dep_bool '      Asynchronous DMA support (WIP) (EXPERIMENTAL)' CONFIG_BLK_DEV_ADMA $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_IDEDMA_PCI_WIP $CONFIG_EXPERIMENTAL
+	    define_bool CONFIG_BLK_DEV_ADMA $CONFIG_BLK_DEV_IDEDMA_PCI
+#	    dep_bool '      Tag Command Queue DMA support (WIP) (EXPERIMENTAL)' CONFIG_BLK_DEV_IDEDMA_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_IDEDMA_PCI_WIP $CONFIG_EXPERIMENTAL
 
 	    dep_bool '    AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_mbool '      AEC62XX Tuning support' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX
@@ -59,11 +66,12 @@
 	    dep_bool '    AMD Viper support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_mbool '      AMD Viper ATA-66 Override (WIP)' CONFIG_AMD74XX_OVERRIDE $CONFIG_BLK_DEV_AMD74XX $CONFIG_IDEDMA_PCI_WIP
 	    dep_bool '    CMD64X chipset support' CONFIG_BLK_DEV_CMD64X $CONFIG_BLK_DEV_IDEDMA_PCI
+	    dep_bool '    CMD680 chipset tuning support' CONFIG_BLK_DEV_CMD680 $CONFIG_BLK_DEV_CMD64X
 	    dep_bool '    CY82C693 chipset support' CONFIG_BLK_DEV_CY82C693 $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_bool '    Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI
   	    dep_bool '    HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_mbool '      HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_IDEDMA_PCI_WIP
-	    dep_bool '    HPT366 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI
+	    dep_bool '    HPT366/368/370 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI
 	    if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then
 	       dep_mbool '    Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI
 	       dep_mbool '      PIIXn Tuning support' CONFIG_PIIX_TUNING $CONFIG_BLK_DEV_PIIX $CONFIG_IDEDMA_PCI_AUTO
@@ -72,23 +80,21 @@
 	       dep_mbool '    IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI
 	       dep_mbool '      IT8172 IDE Tuning support' CONFIG_IT8172_TUNING $CONFIG_BLK_DEV_IT8172 $CONFIG_IDEDMA_PCI_AUTO
 	    fi
-	    dep_bool '    NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI
+	    dep_bool '    NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
 	    dep_bool '    OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL
-	    dep_bool '    PROMISE PDC202{46|62|65|67|68} support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI
+#	    dep_mbool '   Pacific Digital A-DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC_ADMA $CONFIG_BLK_DEV_ADMA $CONFIG_IDEDMA_PCI_WIP $CONFIG_EXPERIMENTAL
+	    dep_bool '    PROMISE PDC202{46|62|65|67|68|69|70} support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_bool '      Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX
 	    dep_bool '      Special FastTrak Feature' CONFIG_PDC202XX_FORCE $CONFIG_BLK_DEV_PDC202XX
 	    dep_bool '    ServerWorks OSB4/CSB5 chipsets support' CONFIG_BLK_DEV_SVWKS $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
 	    dep_bool '    SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
 	    dep_bool '    SLC90E66 chipset support' CONFIG_BLK_DEV_SLC90E66 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
-	    dep_bool '    Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI
+	    dep_bool '    Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
 	    dep_bool '    VIA82CXXX chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI
+	    if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
+	       bool '    Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
+	    fi
          fi
-
-#	 dep_mbool '   Pacific Digital A-DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC_ADMA $CONFIG_BLK_DEV_ADMA $CONFIG_IDEDMA_PCI_WIP
-
-	 if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
-	    bool '    Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
-	 fi
       fi
       if [ "$CONFIG_ALL_PPC" = "y" ]; then
 	 bool '    Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC
@@ -101,6 +107,9 @@
 	   define_bool CONFIG_BLK_DEV_IDEPCI $CONFIG_BLK_DEV_IDEDMA_PMAC
 	 fi
       fi
+      if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
+	 bool '  SWARM onboard IDE support' CONFIG_BLK_DEV_IDE_SWARM
+      fi
       if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
 	 dep_bool '    ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN
 	 dep_bool '      ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS $CONFIG_BLK_DEV_IDE_ICSIDE
@@ -113,7 +122,7 @@
 	 dep_mbool '    Amiga IDE Doubler support (EXPERIMENTAL)' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE $CONFIG_EXPERIMENTAL
       fi
       if [ "$CONFIG_ZORRO" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
-	 dep_mbool '  Buddha/Catweasel IDE interface support (EXPERIMENTAL)' CONFIG_BLK_DEV_BUDDHA $CONFIG_ZORRO $CONFIG_EXPERIMENTAL
+	 dep_mbool '  Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)' CONFIG_BLK_DEV_BUDDHA $CONFIG_ZORRO $CONFIG_EXPERIMENTAL
       fi
       if [ "$CONFIG_ATARI" = "y" ]; then
 	 dep_bool '  Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE $CONFIG_ATARI
@@ -173,6 +182,7 @@
 else
   define_bool CONFIG_DMA_NONPCI n
 fi
+
 if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \
      "$CONFIG_BLK_DEV_AEC62XX" = "y" -o \
      "$CONFIG_BLK_DEV_ALI15X3" = "y" -o \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/Makefile linux/drivers/ide/Makefile
--- linux.orig/drivers/ide/Makefile	2001-10-09 16:18:37.000000000 +0000
+++ linux/drivers/ide/Makefile	2002-07-20 01:08:25.000000000 +0000
@@ -10,7 +10,7 @@
 
 O_TARGET := idedriver.o
 
-export-objs		:= ide.o ide-features.o ataraid.o
+export-objs		:= ide.o ide-features.o ide-probe.o ide-taskfile.o ataraid.o
 list-multi		:= ide-mod.o ide-probe-mod.o
 
 obj-y		:=
@@ -24,6 +24,7 @@
 obj-$(CONFIG_BLK_DEV_IDECD)     += ide-cd.o
 obj-$(CONFIG_BLK_DEV_IDETAPE)   += ide-tape.o
 obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o
+
 obj-$(CONFIG_BLK_DEV_IT8172)    += it8172.o
 
 ide-obj-$(CONFIG_BLK_DEV_AEC62XX)	+= aec62xx.o
@@ -48,6 +49,7 @@
 ide-obj-$(CONFIG_BLK_DEV_IDEPCI)	+= ide-pci.o
 ide-obj-$(CONFIG_BLK_DEV_ISAPNP)	+= ide-pnp.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ide-pmac.o
+ide-obj-$(CONFIG_BLK_DEV_IDE_SWARM)	+= ide-swarm.o
 ide-obj-$(CONFIG_BLK_DEV_MAC_IDE)	+= macide.o
 ide-obj-$(CONFIG_BLK_DEV_NS87415)	+= ns87415.o
 ide-obj-$(CONFIG_BLK_DEV_OPTI621)	+= opti621.o
@@ -69,13 +71,13 @@
 
 # The virtualised raid layers MUST come after the ide itself or bad stuff
 # will happen.
-obj-$(CONFIG_BLK_DEV_ATARAID)	+= ataraid.o
+obj-$(CONFIG_BLK_DEV_ATARAID)		+= ataraid.o
 obj-$(CONFIG_BLK_DEV_ATARAID_PDC)	+= pdcraid.o
 obj-$(CONFIG_BLK_DEV_ATARAID_HPT)	+= hptraid.o
 
 ide-obj-$(CONFIG_PROC_FS)		+= ide-proc.o
 
-ide-mod-objs		:= ide.o ide-features.o $(ide-obj-y)
+ide-mod-objs		:= ide.o ide-features.o ide-taskfile.o $(ide-obj-y)
 ide-probe-mod-objs	:= ide-probe.o ide-geometry.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/alim15x3.c linux/drivers/ide/alim15x3.c
--- linux.orig/drivers/ide/alim15x3.c	2001-07-15 23:22:23.000000000 +0000
+++ linux/drivers/ide/alim15x3.c	2002-07-20 01:08:38.000000000 +0000
@@ -453,7 +453,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) {
-			if (id->dma_ultra & 0x002F) {
+			if (id->dma_ultra & 0x003F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive, can_ultra_dma);
 				if ((id->field_valid & 2) &&
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/amd74xx.c linux/drivers/ide/amd74xx.c
--- linux.orig/drivers/ide/amd74xx.c	2001-08-13 21:56:19.000000000 +0000
+++ linux/drivers/ide/amd74xx.c	2002-07-20 01:08:22.000000000 +0000
@@ -75,7 +75,8 @@
 {
 	unsigned int class_rev;
 
-	if (dev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
+	if ((dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) ||
+	    (dev->device == PCI_DEVICE_ID_AMD_VIPER_7441))
 		return 0;
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
@@ -122,8 +123,8 @@
 	pci_read_config_byte(dev, 0x4c, &pio_timing);
 
 #ifdef DEBUG
-	printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
-		drive->name, ultra_timing, dma_pio_timing, pio_timing);
+	printk("%s:%d: Speed 0x%02x UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
+		drive->name, drive->dn, speed, ultra_timing, dma_pio_timing, pio_timing);
 #endif
 
 	ultra_timing	&= ~0xC7;
@@ -131,22 +132,19 @@
 	pio_timing	&= ~(0x03 << drive->dn);
 
 #ifdef DEBUG
-	printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
-		ultra_timing, dma_pio_timing, pio_timing);
+	printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
+		drive->name, ultra_timing, dma_pio_timing, pio_timing);
 #endif
 
 	switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
+		case XFER_UDMA_7:
+		case XFER_UDMA_6:
+			speed = XFER_UDMA_5;
 		case XFER_UDMA_5:
-#undef __CAN_MODE_5
-#ifdef __CAN_MODE_5
 			ultra_timing |= 0x46;
 			dma_pio_timing |= 0x20;
 			break;
-#else
-			printk("%s: setting to mode 4, driver problems in mode 5.\n", drive->name);
-			speed = XFER_UDMA_4;
-#endif /* __CAN_MODE_5 */
 		case XFER_UDMA_4:
 			ultra_timing |= 0x45;
 			dma_pio_timing |= 0x20;
@@ -164,7 +162,7 @@
 			dma_pio_timing |= 0x20;
 			break;
 		case XFER_UDMA_0:
-			ultra_timing |= 0x42;
+		ultra_timing |= 0x42;
 			dma_pio_timing |= 0x20;
 			break;
 		case XFER_MW_DMA_2:
@@ -222,8 +220,8 @@
 	pci_write_config_byte(dev, 0x4c, pio_timing);
 
 #ifdef DEBUG
-	printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
-		ultra_timing, dma_pio_timing, pio_timing);
+	printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
+		drive->name, ultra_timing, dma_pio_timing, pio_timing);
 #endif
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -303,11 +301,15 @@
 	struct pci_dev *dev	= hwif->pci_dev;
 	struct hd_driveid *id	= drive->id;
 	byte udma_66		= eighty_ninty_three(drive);
-	byte udma_100		= (dev->device==PCI_DEVICE_ID_AMD_VIPER_7411) ? 1 : 0;
+	byte udma_100		= ((dev->device==PCI_DEVICE_ID_AMD_VIPER_7411)||
+				   (dev->device==PCI_DEVICE_ID_AMD_VIPER_7441)) ? 1 : 0;
 	byte speed		= 0x00;
 	int  rval;
 
-	if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) {
+	if (udma_100)
+		udma_66 = eighty_ninty_three(drive);
+
+	if ((id->dma_ultra & 0x0020) && (udma_66) && (udma_100)) {
 		speed = XFER_UDMA_5;
 	} else if ((id->dma_ultra & 0x0010) && (udma_66)) {
 		speed = XFER_UDMA_4;
@@ -331,7 +333,7 @@
 
 	(void) amd74xx_tune_chipset(drive, speed);
 
-	rval = (int)(	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+	rval = (int)(	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
 			((id->dma_mword >> 8) & 7) ? ide_dma_on :
 						     ide_dma_off_quietly);
@@ -352,7 +354,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x002F) {
+			if (id->dma_ultra & 0x003F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive);
 				if ((id->field_valid & 2) &&
@@ -442,17 +444,43 @@
 
 unsigned int __init ata66_amd74xx (ide_hwif_t *hwif)
 {
+	struct pci_dev *dev	= hwif->pci_dev;
+	byte cable_80_pin[2]	= { 0, 0 };
+	byte ata66		= 0;
+	byte tmpbyte;
+
+	/*
+	 * Ultra66 cable detection (from Host View)
+	 * 7411, 7441, 0x42, bit0: primary, bit2: secondary 80 pin
+	 */
+	pci_read_config_byte(dev, 0x42, &tmpbyte);
+
+	/*
+	 * 0x42, bit0 is 1 => primary channel
+	 * has 80-pin (from host view)
+	 */
+	if (tmpbyte & 0x01) cable_80_pin[0] = 1;
+
+	/*
+	 * 0x42, bit2 is 1 => secondary channel
+	 * has 80-pin (from host view)
+	 */
+	if (tmpbyte & 0x04) cable_80_pin[1] = 1;
+
+	switch(dev->device) {
+		case PCI_DEVICE_ID_AMD_VIPER_7441:
+		case PCI_DEVICE_ID_AMD_VIPER_7411:
+			ata66 = (hwif->channel) ?
+				cable_80_pin[1] :
+				cable_80_pin[0];
+		default:
+			break;
+	}
 #ifdef CONFIG_AMD74XX_OVERRIDE
-	byte ata66 = 1;
+	return(1);
 #else
-	byte ata66 = 0;
+	return (unsigned int) ata66;
 #endif /* CONFIG_AMD74XX_OVERRIDE */
-
-#if 0
-	pci_read_config_byte(hwif->pci_dev, 0x48, &ata66);
-	return ((ata66 & 0x02) ? 0 : 1);
-#endif
-	return ata66;
 }
 
 void __init ide_init_amd74xx (ide_hwif_t *hwif)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/buddha.c linux/drivers/ide/buddha.c
--- linux.orig/drivers/ide/buddha.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/ide/buddha.c	2002-07-20 01:08:34.000000000 +0000
@@ -1,10 +1,10 @@
 /*
  *  linux/drivers/ide/buddha.c -- Amiga Buddha, Catweasel and X-Surf IDE Driver
  *
- *	Copyright (C) 1997 by Geert Uytterhoeven
+ *	Copyright (C) 1997, 2001 by Geert Uytterhoeven and others
  *
- *  This driver was written by based on the specifications in README.buddha and
- *  the X-Surf info from Inside_XSurf.txt available at 
+ *  This driver was written based on the specifications in README.buddha and
+ *  the X-Surf info from Inside_XSurf.txt available at
  *  http://www.jschoenfeld.com
  *
  *  This file is subject to the terms and conditions of the GNU General Public
@@ -52,7 +52,7 @@
     BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
 };
 
-static const u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = {
+static u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = {
      XSURF_BASE1, XSURF_BASE2
 };
 
@@ -97,7 +97,7 @@
     BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3
 };
 
-static const int xsurf_irqports[XSURF_NUM_HWIFS] __initdata = {
+static int xsurf_irqports[XSURF_NUM_HWIFS] __initdata = {
     XSURF_IRQ1, XSURF_IRQ2
 };
 
@@ -108,8 +108,9 @@
      *  Board information
      */
 
-enum BuddhaType_Enum {BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF};
-typedef enum BuddhaType_Enum BuddhaType;
+typedef enum BuddhaType_Enum {
+    BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF
+} BuddhaType;
 
 
     /*
@@ -175,15 +176,20 @@
 			if (!request_mem_region(board+XSURF_BASE1, 0x1000, "IDE"))
 				continue;
 			if (!request_mem_region(board+XSURF_BASE2, 0x1000, "IDE"))
+				goto fail_base2;
+			if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) {
+				release_mem_region(board+XSURF_BASE2, 0x1000);
+fail_base2:
+				release_mem_region(board+XSURF_BASE1, 0x1000);
 				continue;
-			if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE"))
-				continue;
+			}
 		}	  
 		buddha_board = ZTWO_VADDR(board);
 		
 		/* write to BUDDHA_IRQ_MR to enable the board IRQ */
 		/* X-Surf doesn't have this.  IRQs are always on */
-		if(type != BOARD_XSURF) *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0;
+		if (type != BOARD_XSURF)
+			z_writeb(0, buddha_board+BUDDHA_IRQ_MR);
 		
 		for(i=0;i<buddha_num_hwifs;i++) {
 			if(type != BOARD_XSURF) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c
--- linux.orig/drivers/ide/cmd64x.c	2000-07-27 23:40:57.000000000 +0000
+++ linux/drivers/ide/cmd64x.c	2002-07-20 01:08:33.000000000 +0000
@@ -86,6 +86,7 @@
 #include <linux/proc_fs.h>
 
 static int cmd64x_get_info(char *, char **, off_t, int);
+static int cmd680_get_info(char *, char **, off_t, int);
 extern int (*cmd64x_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 extern char *ide_media_verbose(ide_drive_t *);
 static struct pci_dev *bmide_dev;
@@ -180,24 +181,21 @@
 	return p-buffer;	/* => must be less than 4k! */
 }
 
-#if 0
-static char * cmd64x_chipset_data (char *buf, struct pci_dev *dev)
-{
-	char *p = buf;
-	p += sprintf(p, "thingy stuff\n");
-	return (char *)p;
-}
-static int __init cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
+static int cmd680_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
-	p = cmd64x_chipset_data(buffer, bmide_dev);
-	return p-buffer;	/* hoping it is less than 4K... */
+	p += sprintf(p, "\n                                CMD680 Chipset.\n");
+	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+	p += sprintf(p, "PIO Mode:       %s                %s               %s                 %s\n",
+		"?", "?", "?", "?");
+	return p-buffer;	/* => must be less than 4k! */
 }
-#endif
 
 #endif	/* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
 
 byte cmd64x_proc = 0;
+byte cmd680_proc = 0;
 
 /*
  * Registers and masks for easy access by drive index:
@@ -345,10 +343,58 @@
 		setup_count, active_count, recovery_count);
 }
 
-static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+static byte cmd680_taskfile_timing (ide_hwif_t *hwif)
 {
-	byte speed= 0x00;
-	byte set_pio= ide_get_best_pio_mode(drive, 4, 5, NULL);
+	struct pci_dev *dev	= hwif->pci_dev;
+	byte addr_mask		= (hwif->channel) ? 0xB2 : 0xA2;
+	unsigned short		timing;
+
+	pci_read_config_word(dev, addr_mask, &timing);
+
+	switch (timing) {
+		case 0x10c1:	return 4;
+		case 0x10c3:	return 3;
+		case 0x1281:	return 2;
+		case 0x2283:	return 1;
+		case 0x328a:
+		default:	return 0;
+	}
+}
+
+static void cmd680_tuneproc (ide_drive_t *drive, byte mode_wanted)
+{
+	ide_hwif_t *hwif	= HWIF(drive);
+	struct pci_dev *dev	= hwif->pci_dev;
+	byte			drive_pci;
+	unsigned short		speedt;
+
+	switch (drive->dn) {
+		case 0: drive_pci = 0xA4; break;
+		case 1: drive_pci = 0xA6; break;
+		case 2: drive_pci = 0xB4; break;
+		case 3: drive_pci = 0xB6; break;
+		default: return;
+        }
+
+	pci_read_config_word(dev, drive_pci, &speedt);
+
+	/* cheat for now and use the docs */
+//	switch(cmd680_taskfile_timing(hwif)) {
+	switch(mode_wanted) {
+		case 4:		speedt = 0x10c1; break;
+		case 3:		speedt = 0x10C3; break;
+		case 2:		speedt = 0x1104; break;
+		case 1:		speedt = 0x2283; break;
+		case 0:
+		default:	speedt = 0x328A; break;
+	}
+	pci_write_config_word(dev, drive_pci, speedt);
+}
+
+static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+{
+	byte speed	= 0x00;
+	byte set_pio	= ide_get_best_pio_mode(drive, 4, 5, NULL);
 
 	cmd64x_tuneproc(drive, set_pio);
 	speed = XFER_PIO_0 + set_pio;
@@ -356,6 +402,41 @@
 		(void) ide_config_drive_speed(drive, speed);
 }
 
+static void config_cmd680_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+{
+	ide_hwif_t *hwif	= HWIF(drive);
+	struct pci_dev *dev	= hwif->pci_dev;
+	u8 unit			= (drive->select.b.unit & 0x01);
+	u8 addr_mask		= (hwif->channel) ? 0x84 : 0x80;
+	u8 speed		= 0x00;
+	u8 mode_pci		= 0x00;
+	u8 channel_timings	= cmd680_taskfile_timing(hwif);
+	u8 set_pio		= ide_get_best_pio_mode(drive, 4, 5, NULL);
+
+	pci_read_config_byte(dev, addr_mask, &mode_pci);
+	mode_pci &= ~((unit) ? 0x30 : 0x03);
+
+	/* WARNING PIO timing mess is going to happen b/w devices, argh */
+	if ((channel_timings != set_pio) && (set_pio > channel_timings))
+		set_pio = channel_timings;
+
+	cmd680_tuneproc(drive, set_pio);
+	speed = XFER_PIO_0 + set_pio;
+	if (set_speed) {
+		(void) ide_config_drive_speed(drive, speed);
+		drive->current_speed = speed;
+	}
+}
+
+static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+{
+        if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_CMD_680) {
+		config_cmd680_chipset_for_pio(drive, set_speed);
+	} else {
+		config_cmd64x_chipset_for_pio(drive, set_speed);
+	}
+}
+
 static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -363,7 +444,7 @@
 	struct pci_dev *dev	= hwif->pci_dev;
 	int err			= 0;
 
-	byte unit		= (drive->select.b.unit & 0x01);
+	u8 unit			= (drive->select.b.unit & 0x01);
 	u8 pciU			= (hwif->channel) ? UDIDETCR1 : UDIDETCR0;
 	u8 pciD			= (hwif->channel) ? BMIDESR1 : BMIDESR0;
 	u8 regU			= 0;
@@ -424,8 +505,123 @@
 	return err;
 }
 
+static int cmd680_tune_chipset (ide_drive_t *drive, byte speed)
+{
+	ide_hwif_t *hwif	= HWIF(drive);
+	struct pci_dev *dev	= hwif->pci_dev;
+	u8 addr_mask		= (hwif->channel) ? 0x84 : 0x80;
+	u8 unit			= (drive->select.b.unit & 0x01);
+	u8 dma_pci		= 0;
+	u8 udma_pci		= 0;
+	u8 mode_pci		= 0;
+	u8 scsc			= 0;
+	u16 ultra		= 0;
+	u16 multi		= 0;
+	int err			= 0;
+
+        pci_read_config_byte(dev, addr_mask, &mode_pci);
+	pci_read_config_byte(dev, 0x8A, &scsc);
+
+        switch (drive->dn) {
+		case 0: dma_pci = 0xA8; udma_pci = 0xAC; break;
+		case 1: dma_pci = 0xAA; udma_pci = 0xAE; break;
+		case 2: dma_pci = 0xB8; udma_pci = 0xBC; break;
+		case 3: dma_pci = 0xBA; udma_pci = 0xBE; break;
+		default: return 1;
+	}
+
+	pci_read_config_byte(dev, addr_mask, &mode_pci);
+	mode_pci &= ~((unit) ? 0x30 : 0x03);
+	pci_read_config_word(dev, dma_pci, &multi);
+	pci_read_config_word(dev, udma_pci, &ultra);
+
+	if ((speed == XFER_UDMA_6) && (scsc & 0x30) == 0x00) {
+		pci_write_config_byte(dev, 0x8A, scsc|0x01);
+		pci_read_config_byte(dev, 0x8A, &scsc);
+	}
+
+	switch(speed) {
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		case XFER_UDMA_6:
+			if ((scsc & 0x30) == 0x00)
+				goto speed_break;
+			multi = 0x10C1;
+			ultra &= ~0x3F;
+			ultra |= 0x01;
+			break;
+speed_break :
+			speed = XFER_UDMA_5;
+		case XFER_UDMA_5:
+			multi = 0x10C1;
+			ultra &= ~0x3F;
+			ultra |= (((scsc & 0x30) == 0x00) ? 0x01 : 0x02);
+			break;
+		case XFER_UDMA_4:
+			multi = 0x10C1;
+			ultra &= ~0x3F;
+			ultra |= (((scsc & 0x30) == 0x00) ? 0x02 : 0x03);
+			break;
+		case XFER_UDMA_3:
+			multi = 0x10C1;
+			ultra &= ~0x3F;
+			ultra |= (((scsc & 0x30) == 0x00) ? 0x04 : 0x05);
+			break;
+		case XFER_UDMA_2:
+			multi = 0x10C1;
+			ultra &= ~0x3F;
+			ultra |= (((scsc & 0x30) == 0x00) ? 0x05 : 0x07);
+			break;
+		case XFER_UDMA_1:
+			multi = 0x10C1;
+			ultra &= ~0x3F;
+			ultra |= (((scsc & 0x30) == 0x00) ? 0x07 : 0x0B);
+			break;
+		case XFER_UDMA_0:
+			multi = 0x10C1;
+			ultra &= ~0x3F;
+			ultra |= (((scsc & 0x30) == 0x00) ? 0x0C : 0x0F);
+			break;
+		case XFER_MW_DMA_2:
+			multi = 0x10C1;
+			break;
+		case XFER_MW_DMA_1:
+			multi = 0x10C2;
+			break;
+		case XFER_MW_DMA_0:
+			multi = 0x2208;
+			break;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+		case XFER_PIO_4:	cmd680_tuneproc(drive, 4); break;
+		case XFER_PIO_3:	cmd680_tuneproc(drive, 3); break;
+		case XFER_PIO_2:	cmd680_tuneproc(drive, 2); break;
+		case XFER_PIO_1:	cmd680_tuneproc(drive, 1); break;
+		case XFER_PIO_0:	cmd680_tuneproc(drive, 0); break;
+		default:
+			return 1;
+	}
+
+	
+	if (speed >= XFER_MW_DMA_0) 
+		config_cmd680_chipset_for_pio(drive, 0);
+
+	if (speed >= XFER_UDMA_0)
+		mode_pci |= ((unit) ? 0x30 : 0x03);
+	else if (speed >= XFER_MW_DMA_0)
+		mode_pci |= ((unit) ? 0x20 : 0x02);
+	else
+		mode_pci |= ((unit) ? 0x10 : 0x01);
+
+	pci_write_config_byte(dev, addr_mask, mode_pci);
+	pci_write_config_word(dev, dma_pci, multi);
+	pci_write_config_word(dev, udma_pci, ultra);
+
+	err = ide_config_drive_speed(drive, speed);
+	drive->current_speed = speed;
+	return err;
+}
+
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
+static int config_cmd64x_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
 {
 	struct hd_driveid *id	= drive->id;
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -510,6 +706,55 @@
 	return rval;
 }
 
+static int config_cmd680_chipset_for_dma (ide_drive_t *drive)
+{
+	struct hd_driveid *id	= drive->id;
+	byte udma_66		= eighty_ninty_three(drive);
+	byte speed		= 0x00;
+	byte set_pio		= 0x00;
+	int rval;
+
+	if ((id->dma_ultra & 0x0040) && (udma_66))	speed = XFER_UDMA_6;
+	else if ((id->dma_ultra & 0x0020) && (udma_66))	speed = XFER_UDMA_5;
+	else if ((id->dma_ultra & 0x0010) && (udma_66))	speed = XFER_UDMA_4;
+	else if ((id->dma_ultra & 0x0008) && (udma_66))	speed = XFER_UDMA_3;
+	else if (id->dma_ultra & 0x0004)		speed = XFER_UDMA_2;
+	else if (id->dma_ultra & 0x0002)		speed = XFER_UDMA_1;
+	else if (id->dma_ultra & 0x0001)		speed = XFER_UDMA_0;
+	else if (id->dma_mword & 0x0004)		speed = XFER_MW_DMA_2;
+	else if (id->dma_mword & 0x0002)		speed = XFER_MW_DMA_1;
+	else if (id->dma_mword & 0x0001)		speed = XFER_MW_DMA_0;
+	else {
+		set_pio = 1;
+	}
+
+	if (!drive->init_speed)
+		drive->init_speed = speed;
+
+	config_chipset_for_pio(drive, set_pio);
+
+	if (set_pio)
+		return ((int) ide_dma_off_quietly);
+
+	if (cmd680_tune_chipset(drive, speed))
+		return ((int) ide_dma_off);
+
+	rval = (int)(	((id->dma_ultra >> 14) & 3) ? ide_dma_on :
+			((id->dma_ultra >> 11) & 7) ? ide_dma_on :
+			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
+			((id->dma_mword >> 8) & 7) ? ide_dma_on :
+			((id->dma_1word >> 8) & 7) ? ide_dma_on :
+						     ide_dma_off_quietly);
+	return rval;
+}
+
+static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
+{
+	if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_CMD_680)
+		return (config_cmd680_chipset_for_dma(drive));
+	return (config_cmd64x_chipset_for_dma(drive, rev, ultra_66));
+}
+
 static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
 {
 	struct hd_driveid *id	= drive->id;
@@ -519,12 +764,15 @@
 	byte can_ultra_33	= 0;
 	byte can_ultra_66	= 0;
 	byte can_ultra_100	= 0;
+	byte can_ultra_133	= 0;
 	ide_dma_action_t dma_func = ide_dma_on;
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;	
 
 	switch(dev->device) {
+		case PCI_DEVICE_ID_CMD_680:
+			can_ultra_133 = 1;
 		case PCI_DEVICE_ID_CMD_649:
 			can_ultra_100 = 1;
 		case PCI_DEVICE_ID_CMD_648:
@@ -550,7 +798,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if ((id->field_valid & 4) && (can_ultra_33)) {
-			if (id->dma_ultra & 0x002F) {
+			if (id->dma_ultra & 0x007F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive, class_rev, can_ultra_66);
 				if ((id->field_valid & 2) &&
@@ -586,6 +834,18 @@
 	return HWIF(drive)->dmaproc(dma_func, drive);
 }
 
+static int cmd680_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+{
+	switch (func) {
+		case ide_dma_check:
+			return cmd64x_config_drive_for_dma(drive);
+		default:
+			break;
+	}
+	/* Other cases are done by generic IDE-DMA code. */
+        return ide_dmaproc(func, drive);
+}
+
 static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 {
 	byte dma_stat		= 0;
@@ -663,7 +923,78 @@
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
-unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name)
+static int cmd680_busproc (ide_drive_t * drive, int state)
+{
+#if 0
+	ide_hwif_t *hwif	= HWIF(drive);
+	u8 addr_mask		= (hwif->channel) ? 0xB0 : 0xA0;
+	u32 stat_config		= 0;
+
+        pci_read_config_dword(hwif->pci_dev, addr_mask, &stat_config);
+
+	if (!hwif)
+		return -EINVAL;
+
+	switch (state) {
+		case BUSSTATE_ON:
+			hwif->drives[0].failures = 0;
+			hwif->drives[1].failures = 0;
+			break;
+		case BUSSTATE_OFF:
+			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
+			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+			break;
+		case BUSSTATE_TRISTATE:
+			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
+			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+			break;
+		default:
+			return 0;
+	}
+	hwif->bus_state = state;
+#endif
+	return 0;
+}
+
+void cmd680_reset (ide_drive_t *drive)
+{
+#if 0
+	ide_hwif_t *hwif	= HWIF(drive);
+	u8 addr_mask		= (hwif->channel) ? 0xB0 : 0xA0;
+	byte reset		= 0;
+
+	pci_read_config_byte(hwif->pci_dev, addr_mask, &reset);
+	pci_write_config_byte(hwif->pci_dev, addr_mask, reset|0x03);
+#endif
+}
+
+unsigned int cmd680_pci_init (struct pci_dev *dev, const char *name)
+{
+	u8 tmpbyte	= 0;	
+	pci_write_config_byte(dev, 0x80, 0x00);
+	pci_write_config_byte(dev, 0x84, 0x00);
+	pci_read_config_byte(dev, 0x8A, &tmpbyte);
+	pci_write_config_byte(dev, 0x8A, tmpbyte|0x01);
+	pci_write_config_word(dev, 0xA2, 0x328A);
+	pci_write_config_dword(dev, 0xA4, 0x328A);
+	pci_write_config_dword(dev, 0xA8, 0x4392);
+	pci_write_config_dword(dev, 0xAC, 0x4009);
+	pci_write_config_word(dev, 0xB2, 0x328A);
+	pci_write_config_dword(dev, 0xB4, 0x328A);
+	pci_write_config_dword(dev, 0xB8, 0x4392);
+	pci_write_config_dword(dev, 0xBC, 0x4009);
+
+#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
+	if (!cmd64x_proc) {
+		cmd64x_proc = 1;
+		bmide_dev = dev;
+		cmd64x_display_info = &cmd680_get_info;
+	}
+#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */
+	return 0;
+}
+
+unsigned int cmd64x_pci_init (struct pci_dev *dev, const char *name)
 {
 	unsigned char mrdmode;
 	unsigned int class_rev;
@@ -752,7 +1083,23 @@
 	return 0;
 }
 
-unsigned int __init ata66_cmd64x (ide_hwif_t *hwif)
+unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name)
+{
+	if (dev->device == PCI_DEVICE_ID_CMD_680)
+		return cmd680_pci_init (dev, name);
+	return cmd64x_pci_init (dev, name);
+}
+
+unsigned int cmd680_ata66 (ide_hwif_t *hwif)
+{
+	byte ata66	= 0;
+	byte addr_mask	= (hwif->channel) ? 0xB0 : 0xA0;
+
+	pci_read_config_byte(hwif->pci_dev, addr_mask, &ata66);
+	return (ata66 & 0x01) ? 1 : 0;
+}
+
+unsigned int cmd64x_ata66 (ide_hwif_t *hwif)
 {
 	byte ata66 = 0;
 	byte mask = (hwif->channel) ? 0x02 : 0x01;
@@ -761,6 +1108,14 @@
 	return (ata66 & mask) ? 1 : 0;
 }
 
+unsigned int __init ata66_cmd64x (ide_hwif_t *hwif)
+{
+	struct pci_dev *dev	= hwif->pci_dev;
+	if (dev->device == PCI_DEVICE_ID_CMD_680)
+		return cmd680_ata66(hwif);
+	return cmd64x_ata66(hwif);
+}
+
 void __init ide_init_cmd64x (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -769,8 +1124,6 @@
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
 
-	hwif->tuneproc	= &cmd64x_tuneproc;
-	hwif->speedproc	= &cmd64x_tune_chipset;
 	hwif->drives[0].autotune = 1;
 	hwif->drives[1].autotune = 1;
 
@@ -779,10 +1132,19 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	switch(dev->device) {
+		case PCI_DEVICE_ID_CMD_680:
+			hwif->busproc	= &cmd680_busproc;
+			hwif->dmaproc	= &cmd680_dmaproc;
+			hwif->resetproc = &cmd680_reset;
+			hwif->speedproc	= &cmd680_tune_chipset;
+			hwif->tuneproc	= &cmd680_tuneproc;
+			break;
 		case PCI_DEVICE_ID_CMD_649:
 		case PCI_DEVICE_ID_CMD_648:
 		case PCI_DEVICE_ID_CMD_643:
-			hwif->dmaproc = &cmd64x_dmaproc;
+			hwif->dmaproc	= &cmd64x_dmaproc;
+			hwif->tuneproc	= &cmd64x_tuneproc;
+			hwif->speedproc = &cmd64x_tune_chipset;
 			break;
 		case PCI_DEVICE_ID_CMD_646:
 			hwif->chipset = ide_cmd646;
@@ -791,6 +1153,8 @@
 			} else {
 				hwif->dmaproc = &cmd64x_dmaproc;
 			}
+			hwif->tuneproc	= &cmd64x_tuneproc;
+			hwif->speedproc	= &cmd64x_tune_chipset;
 			break;
 		default:
 			break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/falconide.c linux/drivers/ide/falconide.c
--- linux.orig/drivers/ide/falconide.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/ide/falconide.c	2002-07-20 01:08:34.000000000 +0000
@@ -7,7 +7,7 @@
  *  License.  See the file COPYING in the main directory of this archive for
  *  more details.
  */
-#include <linux/config.h>
+
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/gayle.c linux/drivers/ide/gayle.c
--- linux.orig/drivers/ide/gayle.c	2000-11-28 01:57:34.000000000 +0000
+++ linux/drivers/ide/gayle.c	2002-07-20 01:08:28.000000000 +0000
@@ -16,6 +16,7 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/init.h>
+#include <linux/zorro.h>
 
 #include <asm/setup.h>
 #include <asm/amigahw.h>
@@ -88,7 +89,7 @@
 {
     unsigned char ch;
 
-    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
     if (!(ch & GAYLE_IRQ_IDE))
 	return 0;
     return 1;
@@ -98,11 +99,11 @@
 {
     unsigned char ch;
 
-    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
     if (!(ch & GAYLE_IRQ_IDE))
 	return 0;
-    (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
-    outb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
+    (void)z_readb(hwif->io_ports[IDE_STATUS_OFFSET]);
+    z_writeb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
     return 1;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- linux.orig/drivers/ide/hpt366.c	2001-08-15 03:01:07.000000000 +0000
+++ linux/drivers/ide/hpt366.c	2002-07-20 01:08:26.000000000 +0000
@@ -1,7 +1,8 @@
 /*
- * linux/drivers/ide/hpt366.c		Version 0.18	June. 9, 2000
+ * linux/drivers/ide/hpt366.c		Version 0.22	20 Sep 2001
  *
  * Copyright (C) 1999-2000		Andre Hedrick <andre@linux-ide.org>
+ * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
  * May be copied or modified under the terms of the GNU General Public License
  *
  * Thanks to HighPoint Technologies for their assistance, and hardware.
@@ -11,6 +12,34 @@
  *
  * Note that final HPT370 support was done by force extraction of GPL.
  *
+ * - add function for getting/setting power status of drive
+ * - the HPT370's state machine can get confused. reset it before each dma 
+ *   xfer to prevent that from happening.
+ * - reset state engine whenever we get an error.
+ * - check for busmaster state at end of dma. 
+ * - use new highpoint timings.
+ * - detect bus speed using highpoint register.
+ * - use pll if we don't have a clock table. added a 66MHz table that's
+ *   just 2x the 33MHz table.
+ * - removed turnaround. NOTE: we never want to switch between pll and
+ *   pci clocks as the chip can glitch in those cases. the highpoint
+ *   approved workaround slows everything down too much to be useful. in
+ *   addition, we would have to serialize access to each chip.
+ * 	Adrian Sun <a.sun@sun.com>
+ *
+ * add drive timings for 66MHz PCI bus,
+ * fix ATA Cable signal detection, fix incorrect /proc info
+ * add /proc display for per-drive PIO/DMA/UDMA mode and
+ * per-channel ATA-33/66 Cable detect.
+ * 	Duncan Laurie <void@sun.com>
+ *
+ * fixup /proc output for multiple controllers
+ *	Tim Hockin <thockin@sun.com>
+ *
+ * On hpt366: 
+ * Reset the hpt366 on error, reset on dma
+ * Fix disabling Fast Interrupt hpt366.
+ * 	Mike Waychison <crlf@sun.com>
  */
 
 #include <linux/config.h>
@@ -28,6 +57,7 @@
 #include <linux/init.h>
 #include <linux/ide.h>
 
+#include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -35,6 +65,11 @@
 
 #define DISPLAY_HPT366_TIMINGS
 
+/* various tuning parameters */
+#define HPT_RESET_STATE_ENGINE
+/*#define HPT_DELAY_INTERRUPT*/
+/*#define HPT_SERIALIZE_IO*/
+
 #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
@@ -106,146 +141,302 @@
 
 struct chipset_bus_clock_list_entry {
 	byte		xfer_speed;
-	unsigned int	chipset_settings_write;
-	unsigned int	chipset_settings_read;
+	unsigned int	chipset_settings;
 };
 
+/* key for bus clock timings
+ * bit
+ * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
+ *        DMA. cycles = value + 1
+ * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
+ *        DMA. cycles = value + 1
+ * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
+ *        register access.
+ * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
+ *        register access.
+ * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
+ *        during task file register access.
+ * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
+ *        xfer.
+ * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
+ *        register access.
+ * 28     UDMA enable
+ * 29     DMA enable
+ * 30     PIO_MST enable. if set, the chip is in bus master mode during
+ *        PIO.
+ * 31     FIFO enable.
+ */
 struct chipset_bus_clock_list_entry forty_base [] = {
 
-	{	XFER_UDMA_4,	0x900fd943,	0x900fd943	},
-	{	XFER_UDMA_3,	0x900ad943,	0x900ad943	},
-	{	XFER_UDMA_2,	0x900bd943,	0x900bd943	},
-	{	XFER_UDMA_1,	0x9008d943,	0x9008d943	},
-	{	XFER_UDMA_0,	0x9008d943,	0x9008d943	},
-
-	{	XFER_MW_DMA_2,	0xa008d943,	0xa008d943	},
-	{	XFER_MW_DMA_1,	0xa010d955,	0xa010d955	},
-	{	XFER_MW_DMA_0,	0xa010d9fc,	0xa010d9fc	},
-
-	{	XFER_PIO_4,	0xc008d963,	0xc008d963	},
-	{	XFER_PIO_3,	0xc010d974,	0xc010d974	},
-	{	XFER_PIO_2,	0xc010d997,	0xc010d997	},
-	{	XFER_PIO_1,	0xc010d9c7,	0xc010d9c7	},
-	{	XFER_PIO_0,	0xc018d9d9,	0xc018d9d9	},
-	{	0,		0x0120d9d9,	0x0120d9d9	}
+	{	XFER_UDMA_4,    0x900fd943	},
+	{	XFER_UDMA_3,	0x900ad943	},
+	{	XFER_UDMA_2,	0x900bd943	},
+	{	XFER_UDMA_1,	0x9008d943	},
+	{	XFER_UDMA_0,	0x9008d943	},
+
+	{	XFER_MW_DMA_2,	0xa008d943	},
+	{	XFER_MW_DMA_1,	0xa010d955	},
+	{	XFER_MW_DMA_0,	0xa010d9fc	},
+
+	{	XFER_PIO_4,	0xc008d963	},
+	{	XFER_PIO_3,	0xc010d974	},
+	{	XFER_PIO_2,	0xc010d997	},
+	{	XFER_PIO_1,	0xc010d9c7	},
+	{	XFER_PIO_0,	0xc018d9d9	},
+	{	0,		0x0120d9d9	}
 };
 
 struct chipset_bus_clock_list_entry thirty_three_base [] = {
 
-	{	XFER_UDMA_4,	0x90c9a731,	0x90c9a731	},
-	{	XFER_UDMA_3,	0x90cfa731,	0x90cfa731	},
-	{	XFER_UDMA_2,	0x90caa731,	0x90caa731	},
-	{	XFER_UDMA_1,	0x90cba731,	0x90cba731	},
-	{	XFER_UDMA_0,	0x90c8a731,	0x90c8a731	},
-
-	{	XFER_MW_DMA_2,	0xa0c8a731,	0xa0c8a731	},
-	{	XFER_MW_DMA_1,	0xa0c8a732,	0xa0c8a732	},	/* 0xa0c8a733 */
-	{	XFER_MW_DMA_0,	0xa0c8a797,	0xa0c8a797	},
-
-	{	XFER_PIO_4,	0xc0c8a731,	0xc0c8a731	},
-	{	XFER_PIO_3,	0xc0c8a742,	0xc0c8a742	},
-	{	XFER_PIO_2,	0xc0d0a753,	0xc0d0a753	},
-	{	XFER_PIO_1,	0xc0d0a7a3,	0xc0d0a7a3	},	/* 0xc0d0a793 */
-	{	XFER_PIO_0,	0xc0d0a7aa,	0xc0d0a7aa	},	/* 0xc0d0a7a7 */
-	{	0,		0x0120a7a7,	0x0120a7a7	}
+	{	XFER_UDMA_4,	0x90c9a731	},
+	{	XFER_UDMA_3,	0x90cfa731	},
+	{	XFER_UDMA_2,	0x90caa731	},
+	{	XFER_UDMA_1,	0x90cba731	},
+	{	XFER_UDMA_0,	0x90c8a731	},
+
+	{	XFER_MW_DMA_2,	0xa0c8a731	},
+	{	XFER_MW_DMA_1,	0xa0c8a732	},	/* 0xa0c8a733 */
+	{	XFER_MW_DMA_0,	0xa0c8a797	},
+
+	{	XFER_PIO_4,	0xc0c8a731	},
+	{	XFER_PIO_3,	0xc0c8a742	},
+	{	XFER_PIO_2,	0xc0d0a753	},
+	{	XFER_PIO_1,	0xc0d0a7a3	},	/* 0xc0d0a793 */
+	{	XFER_PIO_0,	0xc0d0a7aa	},	/* 0xc0d0a7a7 */
+	{	0,		0x0120a7a7	}
 };
 
 struct chipset_bus_clock_list_entry twenty_five_base [] = {
 
-	{	XFER_UDMA_4,	0x90c98521,	0x90c98521	},
-	{	XFER_UDMA_3,	0x90cf8521,	0x90cf8521	},
-	{	XFER_UDMA_2,	0x90cf8521,	0x90cf8521	},
-	{	XFER_UDMA_1,	0x90cb8521,	0x90cb8521	},
-	{	XFER_UDMA_0,	0x90cb8521,	0x90cb8521	},
-
-	{	XFER_MW_DMA_2,	0xa0ca8521,	0xa0ca8521	},
-	{	XFER_MW_DMA_1,	0xa0ca8532,	0xa0ca8532	},
-	{	XFER_MW_DMA_0,	0xa0ca8575,	0xa0ca8575	},
-
-	{	XFER_PIO_4,	0xc0ca8521,	0xc0ca8521	},
-	{	XFER_PIO_3,	0xc0ca8532,	0xc0ca8532	},
-	{	XFER_PIO_2,	0xc0ca8542,	0xc0ca8542	},
-	{	XFER_PIO_1,	0xc0d08572,	0xc0d08572	},
-	{	XFER_PIO_0,	0xc0d08585,	0xc0d08585	},
-	{	0,		0x01208585,	0x01208585	}
+	{	XFER_UDMA_4,	0x90c98521	},
+	{	XFER_UDMA_3,	0x90cf8521	},
+	{	XFER_UDMA_2,	0x90cf8521	},
+	{	XFER_UDMA_1,	0x90cb8521	},
+	{	XFER_UDMA_0,	0x90cb8521	},
+
+	{	XFER_MW_DMA_2,	0xa0ca8521	},
+	{	XFER_MW_DMA_1,	0xa0ca8532	},
+	{	XFER_MW_DMA_0,	0xa0ca8575	},
+
+	{	XFER_PIO_4,	0xc0ca8521	},
+	{	XFER_PIO_3,	0xc0ca8532	},
+	{	XFER_PIO_2,	0xc0ca8542	},
+	{	XFER_PIO_1,	0xc0d08572	},
+	{	XFER_PIO_0,	0xc0d08585	},
+	{	0,		0x01208585	}
+};
+
+#if 1
+/* these are the current (4 sep 2001) timings from highpoint */
+struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
+        {       XFER_UDMA_5,    0x12446231      },
+        {       XFER_UDMA_4,    0x12446231      },
+        {       XFER_UDMA_3,    0x126c6231      },
+        {       XFER_UDMA_2,    0x12486231      },
+        {       XFER_UDMA_1,    0x124c6233      },
+        {       XFER_UDMA_0,    0x12506297      },
+
+        {       XFER_MW_DMA_2,  0x22406c31      },
+        {       XFER_MW_DMA_1,  0x22406c33      },
+        {       XFER_MW_DMA_0,  0x22406c97      },
+
+        {       XFER_PIO_4,     0x06414e31      },
+        {       XFER_PIO_3,     0x06414e42      },
+        {       XFER_PIO_2,     0x06414e53      },
+        {       XFER_PIO_1,     0x06814e93      },
+        {       XFER_PIO_0,     0x06814ea7      },
+        {       0,              0x06814ea7      }
 };
 
+/* 2x 33MHz timings */
+struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
+	{       XFER_UDMA_5,    0x1488e673       },
+	{       XFER_UDMA_4,    0x1488e673       },
+	{       XFER_UDMA_3,    0x1498e673       },
+	{       XFER_UDMA_2,    0x1490e673       },
+	{       XFER_UDMA_1,    0x1498e677       },
+	{       XFER_UDMA_0,    0x14a0e73f       },
+
+	{       XFER_MW_DMA_2,  0x2480fa73       },
+	{       XFER_MW_DMA_1,  0x2480fa77       }, 
+	{       XFER_MW_DMA_0,  0x2480fb3f       },
+
+	{       XFER_PIO_4,     0x0c82be73       },
+	{       XFER_PIO_3,     0x0c82be95       },
+	{       XFER_PIO_2,     0x0c82beb7       },
+	{       XFER_PIO_1,     0x0d02bf37       },
+	{       XFER_PIO_0,     0x0d02bf5f       },
+	{       0,              0x0d02bf5f       }
+};
+#else
+/* from highpoint documentation. these are old values */
 struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
-	{	XFER_UDMA_5,	0x1A85F442,	0x16454e31	},
-	{	XFER_UDMA_4,	0x16454e31,	0x16454e31	},
-	{	XFER_UDMA_3,	0x166d4e31,	0x166d4e31	},
-	{	XFER_UDMA_2,	0x16494e31,	0x16494e31	},
-	{	XFER_UDMA_1,	0x164d4e31,	0x164d4e31	},
-	{	XFER_UDMA_0,	0x16514e31,	0x16514e31	},
-
-	{	XFER_MW_DMA_2,	0x26514e21,	0x26514e21	},
-	{	XFER_MW_DMA_1,	0x26514e33,	0x26514e33	},
-	{	XFER_MW_DMA_0,	0x26514e97,	0x26514e97	},
-
-	{	XFER_PIO_4,	0x06514e21,	0x06514e21	},
-	{	XFER_PIO_3,	0x06514e22,	0x06514e22	},
-	{	XFER_PIO_2,	0x06514e33,	0x06514e33	},
-	{	XFER_PIO_1,	0x06914e43,	0x06914e43	},
-	{	XFER_PIO_0,	0x06914e57,	0x06914e57	},
-	{	0,		0x06514e57,	0x06514e57	}
+	{	XFER_UDMA_5,	0x16454e31	},
+	{	XFER_UDMA_4,	0x16454e31	},
+	{	XFER_UDMA_3,	0x166d4e31	},
+	{	XFER_UDMA_2,	0x16494e31	},
+	{	XFER_UDMA_1,	0x164d4e31	},
+	{	XFER_UDMA_0,	0x16514e31	},
+
+	{	XFER_MW_DMA_2,	0x26514e21	},
+	{	XFER_MW_DMA_1,	0x26514e33	},
+	{	XFER_MW_DMA_0,	0x26514e97	},
+
+	{	XFER_PIO_4,	0x06514e21	},
+	{	XFER_PIO_3,	0x06514e22	},
+	{	XFER_PIO_2,	0x06514e33	},
+	{	XFER_PIO_1,	0x06914e43	},
+	{	XFER_PIO_0,	0x06914e57	},
+	{	0,		0x06514e57	}
+};
+
+struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
+	{       XFER_UDMA_5,    0x14846231      },
+	{       XFER_UDMA_4,    0x14886231      },
+	{       XFER_UDMA_3,    0x148c6231      },
+	{       XFER_UDMA_2,    0x148c6231      },
+	{       XFER_UDMA_1,    0x14906231      },
+	{       XFER_UDMA_0,    0x14986231      },
+	
+	{       XFER_MW_DMA_2,  0x26514e21      },
+	{       XFER_MW_DMA_1,  0x26514e33      },
+	{       XFER_MW_DMA_0,  0x26514e97      },
+	
+	{       XFER_PIO_4,     0x06514e21      },
+	{       XFER_PIO_3,     0x06514e22      },
+	{       XFER_PIO_2,     0x06514e33      },
+	{       XFER_PIO_1,     0x06914e43      },
+	{       XFER_PIO_0,     0x06914e57      },
+	{       0,              0x06514e57      }
+};
+#endif
+
+struct chipset_bus_clock_list_entry fifty_base_hpt370[] = {
+	{       XFER_UDMA_5,    0x12848242      },
+	{       XFER_UDMA_4,    0x12ac8242      },
+	{       XFER_UDMA_3,    0x128c8242      },
+	{       XFER_UDMA_2,    0x120c8242      },
+	{       XFER_UDMA_1,    0x12148254      },
+	{       XFER_UDMA_0,    0x121882ea      },
+
+	{       XFER_MW_DMA_2,  0x22808242      },
+	{       XFER_MW_DMA_1,  0x22808254      },
+	{       XFER_MW_DMA_0,  0x228082ea      },
+
+	{       XFER_PIO_4,     0x0a81f442      },
+	{       XFER_PIO_3,     0x0a81f443      },
+	{       XFER_PIO_2,     0x0a81f454      },
+	{       XFER_PIO_1,     0x0ac1f465      },
+	{       XFER_PIO_0,     0x0ac1f48a      },
+	{       0,              0x0ac1f48a      }
 };
 
 #define HPT366_DEBUG_DRIVE_INFO		0
 #define HPT370_ALLOW_ATA100_5		1
 #define HPT366_ALLOW_ATA66_4		1
 #define HPT366_ALLOW_ATA66_3		1
+#define HPT366_MAX_DEVS			8
+
+#define F_LOW_PCI_33      0x23
+#define F_LOW_PCI_40      0x29
+#define F_LOW_PCI_50      0x2d
+#define F_LOW_PCI_66      0x42
+
+static struct pci_dev *hpt_devs[HPT366_MAX_DEVS];
+static int n_hpt_devs;
+
+static unsigned int pci_rev_check_hpt3xx(struct pci_dev *dev);
+static unsigned int pci_rev2_check_hpt3xx(struct pci_dev *dev);
+byte hpt366_proc = 0;
+byte hpt363_shared_irq;
+byte hpt363_shared_pin;
+extern char *ide_xfer_verbose (byte xfer_rate);
 
 #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
 static int hpt366_get_info(char *, char **, off_t, int);
 extern int (*hpt366_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 extern char *ide_media_verbose(ide_drive_t *);
-static struct pci_dev *bmide_dev;
-static struct pci_dev *bmide2_dev;
 
 static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count)
 {
-	char *p		= buffer;
-	u32 bibma	= bmide_dev->resource[4].start;
-	u32 bibma2 	= bmide2_dev->resource[4].start;
-	char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"};
-	u8  c0 = 0, c1 = 0;
-	u32 class_rev;
-
-	pci_read_config_dword(bmide_dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xff;
-
-        /*
-         * at that point bibma+0x2 et bibma+0xa are byte registers
-         * to investigate:
-         */
-	c0 = inb_p((unsigned short)bibma + 0x02);
-	if (bmide2_dev)
-		c1 = inb_p((unsigned short)bibma2 + 0x02);
-
-	p += sprintf(p, "\n                                %s Chipset.\n", chipset_names[class_rev]);
-	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
-	p += sprintf(p, "                %sabled                         %sabled\n",
-			(c0&0x80) ? "dis" : " en",
-			(c1&0x80) ? "dis" : " en");
-	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
-			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
-			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
-
-	p += sprintf(p, "UDMA\n");
-	p += sprintf(p, "DMA\n");
-	p += sprintf(p, "PIO\n");
+	char *p	= buffer;
+	char *chipset_nums[] = {"366", "366", "368", "370", "370A"};
+	int i;
+
+	p += sprintf(p, "\n                             "
+		"HighPoint HPT366/368/370\n");
+	for (i = 0; i < n_hpt_devs; i++) {
+		struct pci_dev *dev = hpt_devs[i];
+		unsigned long iobase = dev->resource[4].start;
+		u32 class_rev;
+		u8 c0, c1;
+
+		pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
+		class_rev &= 0xff;
+
+		p += sprintf(p, "\nController: %d\n", i);
+		p += sprintf(p, "Chipset: HPT%s\n", chipset_nums[class_rev]);
+		p += sprintf(p, "--------------- Primary Channel "
+				"--------------- Secondary Channel "
+				"--------------\n");
+
+		/* get the bus master status registers */
+		c0 = inb_p(iobase + 0x2);
+		c1 = inb_p(iobase + 0xa);
+		p += sprintf(p, "Enabled:        %s"
+				"                             %s\n",
+			(c0 & 0x80) ? "no" : "yes",
+			(c1 & 0x80) ? "no" : "yes");
+
+		if (pci_rev_check_hpt3xx(dev)) {
+			u8 cbl;
+			cbl = inb_p(iobase + 0x7b);
+			outb_p(cbl | 1, iobase + 0x7b);
+			outb_p(cbl & ~1, iobase + 0x7b);
+			cbl = inb_p(iobase + 0x7a);
+			p += sprintf(p, "Cable:          ATA-%d"
+					"                          ATA-%d\n",
+				(cbl & 0x02) ? 33 : 66,
+				(cbl & 0x01) ? 33 : 66);
+			p += sprintf(p, "\n");
+		}
 
+		p += sprintf(p, "--------------- drive0 --------- drive1 "
+				"------- drive0 ---------- drive1 -------\n");
+		p += sprintf(p, "DMA capable:    %s              %s" 
+				"            %s               %s\n",
+			(c0 & 0x20) ? "yes" : "no ", 
+			(c0 & 0x40) ? "yes" : "no ",
+			(c1 & 0x20) ? "yes" : "no ", 
+			(c1 & 0x40) ? "yes" : "no ");
+
+		{
+			u8 c2, c3;
+			/* older revs don't have these registers mapped 
+			 * into io space */
+			pci_read_config_byte(dev, 0x43, &c0);
+			pci_read_config_byte(dev, 0x47, &c1);
+			pci_read_config_byte(dev, 0x4b, &c2);
+			pci_read_config_byte(dev, 0x4f, &c3);
+
+			p += sprintf(p, "Mode:           %s             %s"
+					"           %s              %s\n",
+				(c0 & 0x10) ? "UDMA" : (c0 & 0x20) ? "DMA " : 
+					(c0 & 0x80) ? "PIO " : "off ",
+				(c1 & 0x10) ? "UDMA" : (c1 & 0x20) ? "DMA " :
+					(c1 & 0x80) ? "PIO " : "off ",
+				(c2 & 0x10) ? "UDMA" : (c2 & 0x20) ? "DMA " :
+					(c2 & 0x80) ? "PIO " : "off ",
+				(c3 & 0x10) ? "UDMA" : (c3 & 0x20) ? "DMA " :
+					(c3 & 0x80) ? "PIO " : "off ");
+		}
+	}
+	p += sprintf(p, "\n");
+	
 	return p-buffer;/* => must be less than 4k! */
 }
 #endif  /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */
 
-byte hpt366_proc = 0;
-
-extern char *ide_xfer_verbose (byte xfer_rate);
-byte hpt363_shared_irq;
-byte hpt363_shared_pin;
-
 static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev)
 {
 	unsigned int class_rev;
@@ -282,16 +473,16 @@
 	return 0;
 }
 
-static unsigned int pci_bus_clock_list (byte speed, int direction, struct chipset_bus_clock_list_entry * chipset_table)
+static unsigned int pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
 {
 	for ( ; chipset_table->xfer_speed ; chipset_table++)
 		if (chipset_table->xfer_speed == speed) {
-			return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read;
+			return chipset_table->chipset_settings;
 		}
-	return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read;
+	return chipset_table->chipset_settings;
 }
 
-static void hpt366_tune_chipset (ide_drive_t *drive, byte speed, int direction)
+static void hpt366_tune_chipset (ide_drive_t *drive, byte speed)
 {
 	byte regtime		= (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
 	byte regfast		= (HWIF(drive)->channel) ? 0x55 : 0x51;
@@ -304,7 +495,7 @@
 	byte drive_fast		= 0;
 
 	/*
-	 * Disable the "fast interrupt" prediction.
+	 * Disable the "fast interrupt" prediction. 
 	 */
 	pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast);
 	if (drive_fast & 0x02)
@@ -314,16 +505,22 @@
 	/* detect bus speed by looking at control reg timing: */
 	switch((reg1 >> 8) & 7) {
 		case 5:
-			reg2 = pci_bus_clock_list(speed, direction, forty_base);
+			reg2 = pci_bus_clock_list(speed, forty_base);
 			break;
 		case 9:
-			reg2 = pci_bus_clock_list(speed, direction, twenty_five_base);
+			reg2 = pci_bus_clock_list(speed, twenty_five_base);
 			break;
 		default:
 		case 7:
-			reg2 = pci_bus_clock_list(speed, direction, thirty_three_base);
+			reg2 = pci_bus_clock_list(speed, thirty_three_base);
 			break;
 	}
+#if 0
+	/* this is a nice idea ... */
+	list_conf = pci_bus_clock_list(speed,
+				       (struct chipset_bus_clock_list_entry *)
+				       dev->sysdata);
+#endif
 	/*
 	 * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later)
 	 */
@@ -337,40 +534,47 @@
 	pci_write_config_dword(HWIF(drive)->pci_dev, regtime, reg2);
 }
 
-static void hpt370_tune_chipset (ide_drive_t *drive, byte speed, int direction)
+static void hpt370_tune_chipset (ide_drive_t *drive, byte speed)
 {
 	byte regfast		= (HWIF(drive)->channel) ? 0x55 : 0x51;
-	byte reg5bh		= (speed != XFER_UDMA_5) ? 0x22 : (direction) ? 0x20 : 0x22;
-	unsigned int list_conf	= pci_bus_clock_list(speed, direction, thirty_three_base_hpt370);
+	unsigned int list_conf	= 0;
 	unsigned int drive_conf = 0;
 	unsigned int conf_mask	= (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
-	byte drive_pci		= 0;
-	byte drive_fast		= 0;
+	byte drive_pci		= 0x40 + (drive->dn * 4);
+	byte new_fast, drive_fast		= 0;
+	struct pci_dev *dev 	= HWIF(drive)->pci_dev;
 
-	switch (drive->dn) {
-		case 0: drive_pci = 0x40; break;
-		case 1: drive_pci = 0x44; break;
-		case 2: drive_pci = 0x48; break;
-		case 3: drive_pci = 0x4c; break;
-		default: return;
-	}
 	/*
 	 * Disable the "fast interrupt" prediction.
+	 * don't holdoff on interrupts. (== 0x01 despite what the docs say) 
 	 */
-	pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast);
-	if (drive_fast & 0x80)
-		pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x80);
+	pci_read_config_byte(dev, regfast, &drive_fast);
+	new_fast = drive_fast;
+	if (new_fast & 0x02)
+		new_fast &= ~0x02;
+
+#ifdef HPT_DELAY_INTERRUPT
+	if (new_fast & 0x01)
+		new_fast &= ~0x01;
+#else
+	if ((new_fast & 0x01) == 0)
+		new_fast |= 0x01;
+#endif
+	if (new_fast != drive_fast)
+		pci_write_config_byte(HWIF(drive)->pci_dev, regfast, new_fast);
 
-	pci_read_config_dword(HWIF(drive)->pci_dev, drive_pci, &drive_conf);
-	pci_write_config_byte(HWIF(drive)->pci_dev, 0x5b, reg5bh);
+	list_conf = pci_bus_clock_list(speed, 
+				       (struct chipset_bus_clock_list_entry *)
+				       dev->sysdata);
 
+	pci_read_config_dword(dev, drive_pci, &drive_conf);
 	list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
-	/*
-	 * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later)
-	 */
-	list_conf &= ~0x80000000;
+	
+	if (speed < XFER_MW_DMA_0) {
+		list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
+	}
 
-	pci_write_config_dword(HWIF(drive)->pci_dev, drive_pci, list_conf);
+	pci_write_config_dword(dev, drive_pci, list_conf);
 }
 
 static int hpt3xx_tune_chipset (ide_drive_t *drive, byte speed)
@@ -382,9 +586,9 @@
 		drive->init_speed = speed;
 
 	if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) {
-		hpt370_tune_chipset(drive, speed, 0);
+		hpt370_tune_chipset(drive, speed);
         } else {
-                hpt366_tune_chipset(drive, speed, 0);
+                hpt366_tune_chipset(drive, speed);
         }
 	drive->current_speed = speed;
 	return ((int) ide_config_drive_speed(drive, speed));
@@ -541,13 +745,6 @@
 	}
 }
 
-void hpt370_rw_proc (ide_drive_t *drive, ide_dma_action_t func)
-{
-	if ((func != ide_dma_write) || (func != ide_dma_read))
-		return;
-	hpt370_tune_chipset(drive, drive->current_speed, (func == ide_dma_write));
-}
-
 static int config_drive_xfer_rate (ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
@@ -624,6 +821,13 @@
 				reg50h, reg52h, reg5ah);
 			if (reg5ah & 0x10)
 				pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, reg5ah & ~0x10);
+			/* fall through to a reset */
+#if 0
+		case ide_dma_begin:
+		case ide_dma_end:
+			/* reset the chips state over and over.. */
+			pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, 0x13);
+#endif
 			break;
 		case ide_dma_timeout:
 		default:
@@ -634,9 +838,52 @@
 
 int hpt370_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = HWIF(drive);
+	unsigned long dma_base = hwif->dma_base;
+	byte regstate = hwif->channel ? 0x54 : 0x50;
+	byte reginfo = hwif->channel ? 0x56 : 0x52;
+	byte dma_stat;
+
 	switch (func) {
 		case ide_dma_check:
 			return config_drive_xfer_rate(drive);
+		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
+			dma_stat = inb(dma_base+2);
+			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
+
+		case ide_dma_end:
+			dma_stat = inb(dma_base + 2);
+			if (dma_stat & 0x01) {
+				udelay(20); /* wait a little */
+				dma_stat = inb(dma_base + 2);
+			}
+			if ((dma_stat & 0x01) == 0) 
+				break;
+
+			func = ide_dma_timeout;
+			/* fallthrough */
+
+		case ide_dma_timeout:
+		case ide_dma_lostirq:
+			pci_read_config_byte(hwif->pci_dev, reginfo, 
+					     &dma_stat); 
+			printk("%s: %d bytes in FIFO\n", drive->name, 
+			       dma_stat);
+			pci_write_config_byte(hwif->pci_dev, regstate, 0x37);
+			udelay(10);
+			dma_stat = inb(dma_base);
+			outb(dma_stat & ~0x1, dma_base); /* stop dma */
+			dma_stat = inb(dma_base + 2); 
+			outb(dma_stat | 0x6, dma_base+2); /* clear errors */
+			/* fallthrough */
+
+#ifdef HPT_RESET_STATE_ENGINE
+	        case ide_dma_begin:
+#endif
+			pci_write_config_byte(hwif->pci_dev, regstate, 0x37);
+			udelay(10);
+			break;
+
 		default:
 			break;
 	}
@@ -644,6 +891,210 @@
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
+/*
+ * Since SUN Cobalt is attempting to do this operation, I should disclose
+ * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date
+ * HOTSWAP ATA Infrastructure.
+ */
+void hpt3xx_reset (ide_drive_t *drive)
+{
+#if 0
+	unsigned long high_16	= pci_resource_start(HWIF(drive)->pci_dev, 4);
+	byte reset		= (HWIF(drive)->channel) ? 0x80 : 0x40;
+	byte reg59h		= 0;
+
+	pci_read_config_byte(HWIF(drive)->pci_dev, 0x59, &reg59h);
+	pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h|reset);
+	pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h);
+#endif
+}
+
+static int hpt3xx_tristate (ide_drive_t * drive, int state)
+{
+	ide_hwif_t *hwif	= HWIF(drive);
+	struct pci_dev *dev	= hwif->pci_dev;
+	byte reset		= (hwif->channel) ? 0x80 : 0x40;
+	byte state_reg		= (hwif->channel) ? 0x57 : 0x53;
+	byte reg59h		= 0;
+	byte regXXh		= 0;
+
+	if (!hwif)
+		return -EINVAL;
+
+//	hwif->bus_state = state;
+
+	pci_read_config_byte(dev, 0x59, &reg59h);
+	pci_read_config_byte(dev, state_reg, &regXXh);
+
+	if (state) {
+		(void) ide_do_reset(drive);
+		pci_write_config_byte(dev, state_reg, regXXh|0x80);
+		pci_write_config_byte(dev, 0x59, reg59h|reset);
+	} else {
+		pci_write_config_byte(dev, 0x59, reg59h & ~(reset));
+		pci_write_config_byte(dev, state_reg, regXXh & ~(0x80));
+		(void) ide_do_reset(drive);
+	}
+	return 0;
+}
+
+/* 
+ * set/get power state for a drive.
+ * turning the power off does the following things:
+ *   1) soft-reset the drive
+ *   2) tri-states the ide bus
+ *
+ * when we turn things back on, we need to re-initialize things.
+ */
+#define TRISTATE_BIT  0x8000
+static int hpt370_busproc(ide_drive_t * drive, int state)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	byte tristate, resetmask, bus_reg;
+	u16 tri_reg;
+
+	if (!hwif)
+		return -EINVAL;
+
+	hwif->bus_state = state;
+
+	if (hwif->channel) { 
+		/* secondary channel */
+		tristate = 0x56;
+		resetmask = 0x80; 
+	} else { 
+		/* primary channel */
+		tristate = 0x52;
+		resetmask = 0x40;
+	}
+
+	/* grab status */
+	pci_read_config_word(hwif->pci_dev, tristate, &tri_reg);
+	pci_read_config_byte(hwif->pci_dev, 0x59, &bus_reg);
+
+	/* set the state. we don't set it if we don't need to do so.
+	 * make sure that the drive knows that it has failed if it's off */
+	switch (state) {
+	case BUSSTATE_ON:
+		hwif->drives[0].failures = 0;
+		hwif->drives[1].failures = 0;
+		if ((bus_reg & resetmask) == 0)
+			return 0;
+		tri_reg &= ~TRISTATE_BIT;
+		bus_reg &= ~resetmask;
+		break;
+	case BUSSTATE_OFF:
+		hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
+		hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+		if ((tri_reg & TRISTATE_BIT) == 0 && (bus_reg & resetmask))
+			return 0;
+		tri_reg &= ~TRISTATE_BIT;
+		bus_reg |= resetmask;
+		break;
+	case BUSSTATE_TRISTATE:
+		hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
+		hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+		if ((tri_reg & TRISTATE_BIT) && (bus_reg & resetmask))
+			return 0;
+		tri_reg |= TRISTATE_BIT;
+		bus_reg |= resetmask;
+		break;
+	}
+	pci_write_config_byte(hwif->pci_dev, 0x59, bus_reg);
+	pci_write_config_word(hwif->pci_dev, tristate, tri_reg);
+
+	return 0;
+}
+
+static void __init init_hpt370(struct pci_dev *dev)
+{
+	int adjust, i;
+	u16 freq;
+	u32 pll;
+	byte reg5bh;
+
+	/*
+	 * default to pci clock. make sure MA15/16 are set to output
+	 * to prevent drives having problems with 40-pin cables.
+	 */
+	pci_write_config_byte(dev, 0x5b, 0x23);
+
+	/*
+	 * set up the PLL. we need to adjust it so that it's stable. 
+	 * freq = Tpll * 192 / Tpci
+	 */
+	pci_read_config_word(dev, 0x78, &freq);
+	freq &= 0x1FF;
+	if (freq < 0x9c) {
+		pll = F_LOW_PCI_33;
+		dev->sysdata = (void *) thirty_three_base_hpt370;
+		printk("HPT370: using 33MHz PCI clock\n");
+	} else if (freq < 0xb0) {
+		pll = F_LOW_PCI_40;
+	} else if (freq < 0xc8) {
+		pll = F_LOW_PCI_50;
+		dev->sysdata = (void *) fifty_base_hpt370;
+		printk("HPT370: using 50MHz PCI clock\n");
+	} else {
+		pll = F_LOW_PCI_66;
+		dev->sysdata = (void *) sixty_six_base_hpt370;
+		printk("HPT370: using 66MHz PCI clock\n");
+	}
+	
+	/*
+	 * only try the pll if we don't have a table for the clock
+	 * speed that we're running at. NOTE: the internal PLL will
+	 * result in slow reads when using a 33MHz PCI clock. we also
+	 * don't like to use the PLL because it will cause glitches
+	 * on PRST/SRST when the HPT state engine gets reset.
+	 */
+	if (dev->sysdata) 
+		goto init_hpt370_done;
+	
+	/*
+	 * adjust PLL based upon PCI clock, enable it, and wait for
+	 * stabilization.
+	 */
+	adjust = 0;
+	freq = (pll < F_LOW_PCI_50) ? 2 : 4;
+	while (adjust++ < 6) {
+		pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 |
+				       pll | 0x100);
+
+		/* wait for clock stabilization */
+		for (i = 0; i < 0x50000; i++) {
+			pci_read_config_byte(dev, 0x5b, &reg5bh);
+			if (reg5bh & 0x80) {
+				/* spin looking for the clock to destabilize */
+				for (i = 0; i < 0x1000; ++i) {
+					pci_read_config_byte(dev, 0x5b, 
+							     &reg5bh);
+					if ((reg5bh & 0x80) == 0)
+						goto pll_recal;
+				}
+				pci_read_config_dword(dev, 0x5c, &pll);
+				pci_write_config_dword(dev, 0x5c, 
+						       pll & ~0x100);
+				pci_write_config_byte(dev, 0x5b, 0x21);
+				dev->sysdata = (void *) fifty_base_hpt370;
+				printk("HPT370: using 50MHz internal PLL\n");
+				goto init_hpt370_done;
+			}
+		}
+pll_recal:
+		if (adjust & 1)
+			pll -= (adjust >> 1);
+		else
+			pll += (adjust >> 1);
+	} 
+
+init_hpt370_done:
+	/* reset state engine */
+	pci_write_config_byte(dev, 0x50, 0x37); 
+	pci_write_config_byte(dev, 0x54, 0x37); 
+	udelay(100);
+}
+
 unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name)
 {
 	byte test = 0;
@@ -652,14 +1103,8 @@
 		pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
 
 	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &test);
-
-#if 0
-	if (test != 0x08)
-		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x08);
-#else
 	if (test != (L1_CACHE_BYTES / 4))
 		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
-#endif
 
 	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &test);
 	if (test != 0x78)
@@ -673,17 +1118,18 @@
 	if (test != 0x08)
 		pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
 
+	if (pci_rev_check_hpt3xx(dev)) {
+		init_hpt370(dev);
+		hpt_devs[n_hpt_devs++] = dev;
+	} else {
+		hpt_devs[n_hpt_devs++] = dev;
+	}
+	
 #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
 	if (!hpt366_proc) {
 		hpt366_proc = 1;
-		bmide_dev = dev;
-		if (pci_rev_check_hpt3xx(dev))
-			bmide2_dev = dev;
 		hpt366_display_info = &hpt366_get_info;
 	}
-	if ((hpt366_proc) && ((dev->devfn - bmide_dev->devfn) == 1)) {
-		bmide2_dev = dev;
-	}
 #endif /* DISPLAY_HPT366_TIMINGS && CONFIG_PROC_FS */
 
 	return dev->irq;
@@ -691,38 +1137,58 @@
 
 unsigned int __init ata66_hpt366 (ide_hwif_t *hwif)
 {
-	byte ata66 = 0;
+	byte ata66	= 0;
+	byte regmask	= (hwif->channel) ? 0x01 : 0x02;
 
 	pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66);
 #ifdef DEBUG
 	printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n",
-		ata66, (ata66 & 0x02) ? "33" : "66",
+		ata66, (ata66 & regmask) ? "33" : "66",
 		PCI_FUNC(hwif->pci_dev->devfn));
 #endif /* DEBUG */
-	return ((ata66 & 0x02) ? 0 : 1);
+	return ((ata66 & regmask) ? 0 : 1);
 }
 
 void __init ide_init_hpt366 (ide_hwif_t *hwif)
 {
+	int hpt_rev;
+
 	hwif->tuneproc	= &hpt3xx_tune_drive;
 	hwif->speedproc	= &hpt3xx_tune_chipset;
 	hwif->quirkproc	= &hpt3xx_quirkproc;
 	hwif->intrproc	= &hpt3xx_intrproc;
 	hwif->maskproc	= &hpt3xx_maskproc;
 
+#ifdef HPT_SERIALIZE_IO
+	/* serialize access to this device */
+	if (hwif->mate)
+		hwif->serialized = hwif->mate->serialized = 1;
+#endif
+
+	hpt_rev = pci_rev_check_hpt3xx(hwif->pci_dev);
+	if (hpt_rev) {
+		/* set up ioctl for power status. note: power affects both
+		 * drives on each channel */
+		hwif->busproc   = &hpt370_busproc;
+	}
+
 	if (pci_rev2_check_hpt3xx(hwif->pci_dev)) {
 		/* do nothing now but will split device types */
+		hwif->resetproc = &hpt3xx_reset;
+/*
+ * don't do until we can parse out the cobalt box argh ...
+ *		hwif->busproc   = &hpt3xx_tristate;
+ */
 	}
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
-		if (pci_rev_check_hpt3xx(hwif->pci_dev)) {
+		if (hpt_rev) {
 			byte reg5ah = 0;
 			pci_read_config_byte(hwif->pci_dev, 0x5a, &reg5ah);
 			if (reg5ah & 0x10)	/* interrupt force enable */
 				pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10);
 			hwif->dmaproc = &hpt370_dmaproc;
-			hwif->rwproc = &hpt370_rw_proc;
 		} else {
 			hwif->dmaproc = &hpt366_dmaproc;
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/hptraid.c linux/drivers/ide/hptraid.c
--- linux.orig/drivers/ide/hptraid.c	2001-10-15 20:27:42.000000000 +0000
+++ linux/drivers/ide/hptraid.c	2002-07-20 01:08:37.000000000 +0000
@@ -123,13 +123,8 @@
 			return 0;
 		}
 			
-		case BLKROSET:
-		case BLKROGET:
-		case BLKSSZGET:
-			return blk_ioctl(inode->i_rdev, cmd, arg);
-
 		default:
-			return -EINVAL;
+			return blk_ioctl(inode->i_rdev, cmd, arg);
 	};
 
 	return 0;
@@ -366,7 +361,11 @@
 	probedisk(IDE2_MAJOR, 64, device);
 	probedisk(IDE3_MAJOR,  0, device);
 	probedisk(IDE3_MAJOR, 64, device);
-                                                                	
+	probedisk(IDE4_MAJOR,  0, device);
+	probedisk(IDE4_MAJOR, 64, device);
+	probedisk(IDE5_MAJOR,  0, device);
+	probedisk(IDE5_MAJOR, 64, device);
+
 	fill_cutoff(device);
 	
 	/* Initialize the gendisk structure */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux.orig/drivers/ide/ide-cd.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/ide/ide-cd.c	2002-07-20 01:08:34.000000000 +0000
@@ -2536,8 +2536,8 @@
 	devinfo->dev = MKDEV (HWIF(drive)->major, minor);
 	devinfo->ops = &ide_cdrom_dops;
 	devinfo->mask = 0;
-	*(int *)&devinfo->speed = CDROM_STATE_FLAGS (drive)->current_speed;
-	*(int *)&devinfo->capacity = nslots;
+	devinfo->speed = CDROM_STATE_FLAGS (drive)->current_speed;
+	devinfo->capacity = nslots;
 	devinfo->handle = (void *) drive;
 	strcpy(devinfo->name, drive->name);
 	
@@ -2644,7 +2644,9 @@
 	 * but they do support reading TOC & audio datas
 	 */
 	if (strcmp (drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 ||
-	    strcmp (drive->id->model, "MATSHITADVD-ROM SR-8186") == 0)
+	    strcmp (drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 ||
+	    strcmp (drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 ||
+	    strcmp (drive->id->model, "MATSHITADVD-ROM SR-8174") == 0)
 		CDROM_CONFIG_FLAGS (drive)->audio_play = 1;
 
 #if ! STANDARD_ATAPI
@@ -2961,11 +2963,7 @@
 	return 0;
 }
 
-static
-int ide_cdrom_reinit (ide_drive_t *drive)
-{
-	return 0;
-}
+int ide_cdrom_reinit (ide_drive_t *drive);
 
 static ide_driver_t ide_cdrom_driver = {
 	name:			"ide-cdrom",
@@ -2975,6 +2973,8 @@
 	supports_dma:		1,
 	supports_dsc_overlap:	1,
 	cleanup:		ide_cdrom_cleanup,
+	standby:		NULL,
+	flushcache:		NULL,
 	do_request:		ide_do_rw_cdrom,
 	end_request:		NULL,
 	ioctl:			ide_cdrom_ioctl,
@@ -2986,7 +2986,9 @@
 	capacity:		ide_cdrom_capacity,
 	special:		NULL,
 	proc:			NULL,
-	driver_reinit:		ide_cdrom_reinit,
+	reinit:			ide_cdrom_reinit,
+	ata_prebuilder:		NULL,
+	atapi_prebuilder:	NULL,
 };
 
 int ide_cdrom_init(void);
@@ -3003,6 +3005,39 @@
 MODULE_PARM(ignore, "s");
 MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
 
+int ide_cdrom_reinit (ide_drive_t *drive)
+{
+	struct cdrom_info *info;
+	int failed = 0;
+
+	MOD_INC_USE_COUNT;
+	info = (struct cdrom_info *) kmalloc (sizeof (struct cdrom_info), GFP_KERNEL);
+	if (info == NULL) {
+		printk ("%s: Can't allocate a cdrom structure\n", drive->name);
+		return 1;
+	}
+	if (ide_register_subdriver (drive, &ide_cdrom_driver, IDE_SUBDRIVER_VERSION)) {
+		printk ("%s: Failed to register the driver with ide.c\n", drive->name);
+		kfree (info);
+		return 1;
+	}
+	memset (info, 0, sizeof (struct cdrom_info));
+	drive->driver_data = info;
+	DRIVER(drive)->busy++;
+	if (ide_cdrom_setup (drive)) {
+		DRIVER(drive)->busy--;
+		if (ide_cdrom_cleanup (drive))
+			printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name);
+		return 1;
+	}
+	DRIVER(drive)->busy--;
+	failed--;
+
+	ide_register_module(&ide_cdrom_module);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
 static void __exit ide_cdrom_exit(void)
 {
 	ide_drive_t *drive;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-cd.h linux/drivers/ide/ide-cd.h
--- linux.orig/drivers/ide/ide-cd.h	2001-11-22 19:46:58.000000000 +0000
+++ linux/drivers/ide/ide-cd.h	2002-07-20 01:08:39.000000000 +0000
@@ -38,7 +38,9 @@
 /************************************************************************/
 
 #define SECTOR_BITS 		9
+#ifndef SECTOR_SIZE
 #define SECTOR_SIZE		(1 << SECTOR_BITS)
+#endif
 #define SECTORS_PER_FRAME	(CD_FRAMESIZE >> SECTOR_BITS)
 #define SECTOR_BUFFER_SIZE	(CD_FRAMESIZE * 32)
 #define SECTORS_BUFFER		(SECTOR_BUFFER_SIZE >> SECTOR_BITS)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-cs.c linux/drivers/ide/ide-cs.c
--- linux.orig/drivers/ide/ide-cs.c	2001-09-30 19:26:05.000000000 +0000
+++ linux/drivers/ide/ide-cs.c	2002-07-20 01:08:31.000000000 +0000
@@ -42,6 +42,7 @@
 #include <linux/ioport.h>
 #include <linux/hdreg.h>
 #include <linux/major.h>
+#include <linux/ide.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -226,6 +227,15 @@
 #define CFG_CHECK(fn, args...) \
 if (CardServices(fn, args) != 0) goto next_entry
 
+int idecs_register (int arg1, int arg2, int irq)
+{
+        hw_regs_t hw;
+        ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL);
+        hw.irq = irq;
+        hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */
+        return ide_register_hw(&hw, NULL);
+}
+
 void ide_config(dev_link_t *link)
 {
     client_handle_t handle = link->handle;
@@ -329,10 +339,14 @@
 
     /* retry registration in case device is still spinning up */
     for (i = 0; i < 10; i++) {
-	hd = ide_register(io_base, ctl_base, link->irq.AssignedIRQ);
+	if (ctl_base)
+	    outb(0x02, ctl_base); /* Set nIEN = disable device interrupts */
+	hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ);
 	if (hd >= 0) break;
 	if (link->io.NumPorts1 == 0x20) {
-	    hd = ide_register(io_base+0x10, ctl_base+0x10,
+	    if (ctl_base)
+		outb(0x02, ctl_base+0x10);
+	    hd = idecs_register(io_base+0x10, ctl_base+0x10,
 			      link->irq.AssignedIRQ);
 	    if (hd >= 0) {
 		io_base += 0x10; ctl_base += 0x10;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux.orig/drivers/ide/ide-disk.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ide/ide-disk.c	2002-07-20 01:08:21.000000000 +0000
@@ -27,9 +27,11 @@
  * Version 1.09		added increment of rq->sector in ide_multwrite
  *			added UDMA 3/4 reporting
  * Version 1.10		request queue changes, Ultra DMA 100
+ * Version 1.11		added 48-bit lba
+ * Version 1.12		adding taskfile io access method
  */
 
-#define IDEDISK_VERSION	"1.10"
+#define IDEDISK_VERSION	"1.12"
 
 #undef REALLY_SLOW_IO		/* most systems can safely undef this */
 
@@ -59,6 +61,14 @@
 #define IS_PDC4030_DRIVE (0)	/* auto-NULLs out pdc4030 code */
 #endif
 
+#ifdef CONFIG_IDE_TASKFILE_IO
+#  undef __TASKFILE__IO /* define __TASKFILE__IO */
+#else /* CONFIG_IDE_TASKFILE_IO */
+#  undef __TASKFILE__IO
+#endif /* CONFIG_IDE_TASKFILE_IO */
+
+#ifndef __TASKFILE__IO
+
 static void idedisk_bswap_data (void *buffer, int wcount)
 {
 	u16 *p = buffer;
@@ -86,6 +96,8 @@
 		ide_output_data(drive, buffer, wcount);
 }
 
+#endif /* __TASKFILE__IO */
+
 /*
  * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity"
  * value for this drive (from its reported identification information).
@@ -99,6 +111,11 @@
 {
 	unsigned long lba_sects, chs_sects, head, tail;
 
+	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
+		printk("48-bit Drive: %llu \n", id->lba_capacity_2);
+		return 1;
+	}
+
 	/*
 	 * The ATA spec tells large drives to return
 	 * C/H/S = 16383/16/63 independent of their size.
@@ -131,6 +148,8 @@
 	return 0;	/* lba_capacity value may be bad */
 }
 
+#ifndef __TASKFILE__IO
+
 /*
  * read_intr() is the handler for disk read/multread interrupts
  */
@@ -313,53 +332,218 @@
 	}
 	return ide_error(drive, "multwrite_intr", stat);
 }
+#endif /* __TASKFILE__IO */
+
+#ifdef __TASKFILE__IO
+
+static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block);
+static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block);
+static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long long block);
 
 /*
- * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
+ * do_rw_disk() issues READ and WRITE commands to a disk,
+ * using LBA if supported, or CHS otherwise, to address sectors.
+ * It also takes care of issuing special DRIVE_CMDs.
  */
-static ide_startstop_t set_multmode_intr (ide_drive_t *drive)
+static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
 {
-	byte stat;
+	if (rq->cmd == READ)
+		goto good_command;
+	if (rq->cmd == WRITE)
+		goto good_command;
 
-	if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) {
-		drive->mult_count = drive->mult_req;
-	} else {
-		drive->mult_req = drive->mult_count = 0;
-		drive->special.b.recalibrate = 1;
-		(void) ide_dump_status(drive, "set_multmode", stat);
-	}
+	printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd);
+	ide_end_request(0, HWGROUP(drive));
 	return ide_stopped;
+
+good_command:
+
+#ifdef CONFIG_BLK_DEV_PDC4030
+	if (IS_PDC4030_DRIVE) {
+		extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
+		return promise_rw_disk(drive, rq, block);
+	}
+#endif /* CONFIG_BLK_DEV_PDC4030 */
+
+	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))	/* 48-bit LBA */
+		return lba_48_rw_disk(drive, rq, (unsigned long long) block);
+	if (drive->select.b.lba)		/* 28-bit LBA */
+		return lba_28_rw_disk(drive, rq, (unsigned long) block);
+
+	/* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */
+	return chs_rw_disk(drive, rq, (unsigned long) block);
 }
 
-/*
- * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd.
- */
-static ide_startstop_t set_geometry_intr (ide_drive_t *drive)
+static task_ioreg_t get_command (ide_drive_t *drive, int cmd)
 {
-	byte stat;
+	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
 
-	if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT))
-		return ide_stopped;
+#if 1
+	lba48bit = drive->addressing;
+#endif
 
-	if (stat & (ERR_STAT|DRQ_STAT))
-		return ide_error(drive, "set_geometry_intr", stat);
+	if ((cmd == READ) && (drive->using_dma))
+		return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA;
+	else if ((cmd == READ) && (drive->mult_count))
+		return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD;
+	else if (cmd == READ)
+		return (lba48bit) ? WIN_READ_EXT : WIN_READ;
+	else if ((cmd == WRITE) && (drive->using_dma))
+		return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
+	else if ((cmd == WRITE) && (drive->mult_count))
+		return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
+	else if (cmd == WRITE)
+		return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE;
+	else
+		return WIN_NOP;
+}
+
+static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+{
+	struct hd_drive_task_hdr	taskfile;
+	struct hd_drive_hob_hdr		hobfile;
+	ide_task_t			args;
+
+	task_ioreg_t command	= get_command(drive, rq->cmd);
+	unsigned int track	= (block / drive->sect);
+	unsigned int sect	= (block % drive->sect) + 1;
+	unsigned int head	= (track % drive->head);
+	unsigned int cyl	= (track / drive->head);
+
+	memset(&taskfile, 0, sizeof(task_struct_t));
+	memset(&hobfile, 0, sizeof(hob_struct_t));
+
+	taskfile.sector_count	= (rq->nr_sectors==256)?0x00:rq->nr_sectors;
+	taskfile.sector_number	= sect;
+	taskfile.low_cylinder	= cyl;
+	taskfile.high_cylinder	= (cyl>>8);
+	taskfile.device_head	= head;
+	taskfile.device_head	|= drive->select.all;
+	taskfile.command	= command;
+
+#ifdef DEBUG
+	printk("%s: %sing: ", drive->name, (rq->cmd==READ) ? "read" : "writ");
+	if (lba)	printk("LBAsect=%lld, ", block);
+	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
+	printk("sectors=%ld, ", rq->nr_sectors);
+	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
+#endif
+
+	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
+	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+	args.command_type	= ide_cmd_type_parser(&args);
+	args.prehandler		= ide_pre_handler_parser(&taskfile, &hobfile);
+	args.handler		= ide_handler_parser(&taskfile, &hobfile);
+	args.posthandler	= NULL;
+	args.rq			= (struct request *) rq;
+	args.block		= block;
+	rq->special		= NULL;
+	rq->special		= (ide_task_t *)&args;
+
+	return do_rw_taskfile(drive, &args);
+}
+
+static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+{
+	struct hd_drive_task_hdr	taskfile;
+	struct hd_drive_hob_hdr		hobfile;
+	ide_task_t			args;
+
+	task_ioreg_t command	= get_command(drive, rq->cmd);
+
+	memset(&taskfile, 0, sizeof(task_struct_t));
+	memset(&hobfile, 0, sizeof(hob_struct_t));
+
+	taskfile.sector_count	= (rq->nr_sectors==256)?0x00:rq->nr_sectors;
+	taskfile.sector_number	= block;
+	taskfile.low_cylinder	= (block>>=8);
+	taskfile.high_cylinder	= (block>>=8);
+	taskfile.device_head	= ((block>>8)&0x0f);
+	taskfile.device_head	|= drive->select.all;
+	taskfile.command	= command;
+
+
+#ifdef DEBUG
+	printk("%s: %sing: ", drive->name, (rq->cmd==READ) ? "read" : "writ");
+	if (lba)	printk("LBAsect=%lld, ", block);
+	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
+	printk("sectors=%ld, ", rq->nr_sectors);
+	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
+#endif
 
-	ide_set_handler(drive, &set_geometry_intr, WAIT_CMD, NULL);
-	return ide_started;	
+	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
+	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+	args.command_type	= ide_cmd_type_parser(&args);
+	args.prehandler		= ide_pre_handler_parser(&taskfile, &hobfile);
+	args.handler		= ide_handler_parser(&taskfile, &hobfile);
+	args.posthandler	= NULL;
+	args.rq			= (struct request *) rq;
+	args.block		= block;
+	rq->special		= NULL;
+	rq->special		= (ide_task_t *)&args;
+
+	return do_rw_taskfile(drive, &args);
 }
 
 /*
- * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
+ * 268435455  == 137439 MB or 28bit limit
+ * 320173056  == 163929 MB or 48bit addressing
+ * 1073741822 == 549756 MB or 48bit addressing fake drive
  */
-static ide_startstop_t recal_intr (ide_drive_t *drive)
+
+static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long long block)
 {
-	byte stat = GET_STAT();
+	struct hd_drive_task_hdr	taskfile;
+	struct hd_drive_hob_hdr		hobfile;
+	ide_task_t			args;
+
+	task_ioreg_t command	= get_command(drive, rq->cmd);
+
+	memset(&taskfile, 0, sizeof(task_struct_t));
+	memset(&hobfile, 0, sizeof(hob_struct_t));
+
+	taskfile.sector_count	= rq->nr_sectors;
+	hobfile.sector_count	= (rq->nr_sectors>>8);
+
+	if (rq->nr_sectors == 65536) {
+		taskfile.sector_count	= 0x00;
+		hobfile.sector_count	= 0x00;
+	}
+
+	taskfile.sector_number	= block;	/* low lba */
+	taskfile.low_cylinder	= (block>>=8);	/* mid lba */
+	taskfile.high_cylinder	= (block>>=8);	/* hi  lba */
+	hobfile.sector_number	= (block>>=8);	/* low lba */
+	hobfile.low_cylinder	= (block>>=8);	/* mid lba */
+	hobfile.high_cylinder	= (block>>=8);	/* hi  lba */
+	taskfile.device_head	= drive->select.all;
+	hobfile.device_head	= taskfile.device_head;
+	hobfile.control		= (drive->ctl|0x80);
+	taskfile.command	= command;
 
-	if (!OK_STAT(stat,READY_STAT,BAD_STAT))
-		return ide_error(drive, "recal_intr", stat);
-	return ide_stopped;
+#ifdef DEBUG
+	printk("%s: %sing: ", drive->name, (rq->cmd==READ) ? "read" : "writ");
+	if (lba)	printk("LBAsect=%lld, ", block);
+	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
+	printk("sectors=%ld, ", rq->nr_sectors);
+	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
+#endif
+
+	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
+	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+	args.command_type	= ide_cmd_type_parser(&args);
+	args.prehandler		= ide_pre_handler_parser(&taskfile, &hobfile);
+	args.handler		= ide_handler_parser(&taskfile, &hobfile);
+	args.posthandler	= NULL;
+	args.rq			= (struct request *) rq;
+	args.block		= block;
+	rq->special		= NULL;
+	rq->special		= (ide_task_t *)&args;
+
+	return do_rw_taskfile(drive, &args);
 }
 
+#else /* !__TASKFILE__IO */
 /*
  * do_rw_disk() issues READ and WRITE commands to a disk,
  * using LBA if supported, or CHS otherwise, to address sectors.
@@ -369,22 +553,70 @@
 {
 	if (IDE_CONTROL_REG)
 		OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
-	OUT_BYTE(0x00, IDE_FEATURE_REG);
-	OUT_BYTE(rq->nr_sectors,IDE_NSECTOR_REG);
+
 #ifdef CONFIG_BLK_DEV_PDC4030
 	if (drive->select.b.lba || IS_PDC4030_DRIVE) {
 #else /* !CONFIG_BLK_DEV_PDC4030 */
 	if (drive->select.b.lba) {
 #endif /* CONFIG_BLK_DEV_PDC4030 */
+
+		if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) {
+			task_ioreg_t tasklets[10];
+
+			tasklets[0] = 0;
+			tasklets[1] = 0;
+			tasklets[2] = rq->nr_sectors;
+			tasklets[3] = (rq->nr_sectors>>8);
+			if (rq->nr_sectors == 65536) {
+				tasklets[2] = 0x00;
+				tasklets[3] = 0x00;
+			}
+			tasklets[4] = (task_ioreg_t) block;
+			tasklets[5] = (task_ioreg_t) (block>>8);
+			tasklets[6] = (task_ioreg_t) (block>>16);
+			tasklets[7] = (task_ioreg_t) (block>>24);
+			tasklets[8] = (task_ioreg_t) 0;
+			tasklets[9] = (task_ioreg_t) 0;
+//			tasklets[8] = (task_ioreg_t) (block>>32);
+//			tasklets[9] = (task_ioreg_t) (block>>40);
 #ifdef DEBUG
-		printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n",
-			drive->name, (rq->cmd==READ)?"read":"writ",
-			block, rq->nr_sectors, (unsigned long) rq->buffer);
-#endif
-		OUT_BYTE(block,IDE_SECTOR_REG);
-		OUT_BYTE(block>>=8,IDE_LCYL_REG);
-		OUT_BYTE(block>>=8,IDE_HCYL_REG);
-		OUT_BYTE(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG);
+			printk("%s: %sing: LBAsect=%lu, sectors=%ld, buffer=0x%08lx, LBAsect=0x%012lx\n",
+				drive->name,
+				(rq->cmd==READ)?"read":"writ",
+				block,
+				rq->nr_sectors,
+				(unsigned long) rq->buffer,
+				block);
+			printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n",
+				drive->name, tasklets[3], tasklets[2],
+				tasklets[9], tasklets[8], tasklets[7],
+				tasklets[6], tasklets[5], tasklets[4]);
+#endif
+			OUT_BYTE(tasklets[1], IDE_FEATURE_REG);
+			OUT_BYTE(tasklets[3], IDE_NSECTOR_REG);
+			OUT_BYTE(tasklets[7], IDE_SECTOR_REG);
+			OUT_BYTE(tasklets[8], IDE_LCYL_REG);
+			OUT_BYTE(tasklets[9], IDE_HCYL_REG);
+
+			OUT_BYTE(tasklets[0], IDE_FEATURE_REG);
+			OUT_BYTE(tasklets[2], IDE_NSECTOR_REG);
+			OUT_BYTE(tasklets[4], IDE_SECTOR_REG);
+			OUT_BYTE(tasklets[5], IDE_LCYL_REG);
+			OUT_BYTE(tasklets[6], IDE_HCYL_REG);
+			OUT_BYTE(0x00|drive->select.all,IDE_SELECT_REG);
+		} else {
+#ifdef DEBUG
+			printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n",
+				drive->name, (rq->cmd==READ)?"read":"writ",
+				block, rq->nr_sectors, (unsigned long) rq->buffer);
+#endif
+			OUT_BYTE(0x00, IDE_FEATURE_REG);
+			OUT_BYTE((rq->nr_sectors==256)?0x00:rq->nr_sectors,IDE_NSECTOR_REG);
+			OUT_BYTE(block,IDE_SECTOR_REG);
+			OUT_BYTE(block>>=8,IDE_LCYL_REG);
+			OUT_BYTE(block>>=8,IDE_HCYL_REG);
+			OUT_BYTE(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG);
+		}
 	} else {
 		unsigned int sect,head,cyl,track;
 		track = block / drive->sect;
@@ -392,6 +624,9 @@
 		OUT_BYTE(sect,IDE_SECTOR_REG);
 		head  = track % drive->head;
 		cyl   = track / drive->head;
+
+		OUT_BYTE(0x00, IDE_FEATURE_REG);
+		OUT_BYTE((rq->nr_sectors==256)?0x00:rq->nr_sectors,IDE_NSECTOR_REG);
 		OUT_BYTE(cyl,IDE_LCYL_REG);
 		OUT_BYTE(cyl>>8,IDE_HCYL_REG);
 		OUT_BYTE(head|drive->select.all,IDE_SELECT_REG);
@@ -413,7 +648,11 @@
 			return ide_started;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
-		OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG);
+		if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) {
+			OUT_BYTE(drive->mult_count ? WIN_MULTREAD_EXT : WIN_READ_EXT, IDE_COMMAND_REG);
+		} else {
+			OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG);
+		}
 		return ide_started;
 	}
 	if (rq->cmd == WRITE) {
@@ -422,7 +661,11 @@
 		if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_write, drive)))
 			return ide_started;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-		OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, IDE_COMMAND_REG);
+		if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) {
+			OUT_BYTE(drive->mult_count ? WIN_MULTWRITE_EXT : WIN_WRITE_EXT, IDE_COMMAND_REG);
+		} else {
+			OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, IDE_COMMAND_REG);
+		}
 		if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
 			printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name,
 				drive->mult_count ? "MULTWRITE" : "WRITE");
@@ -432,17 +675,17 @@
 			__cli();	/* local CPU only */
 		if (drive->mult_count) {
 			ide_hwgroup_t *hwgroup = HWGROUP(drive);
-			/*
-			 * Ugh.. this part looks ugly because we MUST set up
-			 * the interrupt handler before outputting the first block
-			 * of data to be written.  If we hit an error (corrupted buffer list)
-			 * in ide_multwrite(), then we need to remove the handler/timer
-			 * before returning.  Fortunately, this NEVER happens (right?).
-			 *
-			 * Except when you get an error it seems...
-			 */
+	/*
+	 * Ugh.. this part looks ugly because we MUST set up
+	 * the interrupt handler before outputting the first block
+	 * of data to be written.  If we hit an error (corrupted buffer list)
+	 * in ide_multwrite(), then we need to remove the handler/timer
+	 * before returning.  Fortunately, this NEVER happens (right?).
+	 *
+	 * Except when you get an error it seems...
+	 */
 			hwgroup->wrq = *rq; /* scratchpad */
-			ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL);
+			ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
 			if (ide_multwrite(drive, drive->mult_count)) {
 				unsigned long flags;
 				spin_lock_irqsave(&io_request_lock, flags);
@@ -462,29 +705,47 @@
 	return ide_stopped;
 }
 
+#endif /* __TASKFILE__IO */
+
 static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
 {
 	MOD_INC_USE_COUNT;
 	if (drive->removable && drive->usage == 1) {
+		struct hd_drive_task_hdr taskfile;
+		struct hd_drive_hob_hdr hobfile;
+		memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+		memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+		taskfile.command = WIN_DOORLOCK;
 		check_disk_change(inode->i_rdev);
 		/*
 		 * Ignore the return code from door_lock,
 		 * since the open() has already succeeded,
 		 * and the door_lock is irrelevant at this point.
 		 */
-		if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORLOCK, 0, 0, 0, NULL))
+		if (drive->doorlocking && ide_wait_taskfile(drive, &taskfile, &hobfile, NULL))
 			drive->doorlocking = 0;
 	}
 	return 0;
 }
 
+static int do_idedisk_flushcache(ide_drive_t *drive);
+
 static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
 {
 	if (drive->removable && !drive->usage) {
+		struct hd_drive_task_hdr taskfile;
+		struct hd_drive_hob_hdr hobfile;
+		memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+		memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+		taskfile.command = WIN_DOORUNLOCK;
 		invalidate_bdev(inode->i_bdev, 0);
-		if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL))
+		if (drive->doorlocking && ide_wait_taskfile(drive, &taskfile, &hobfile, NULL))
 			drive->doorlocking = 0;
 	}
+	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
+		if (do_idedisk_flushcache(drive))
+			printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
+				drive->name);
 	MOD_DEC_USE_COUNT;
 }
 
@@ -501,27 +762,234 @@
 }
 
 /*
+ * Queries for true maximum capacity of the drive.
+ * Returns maximum LBA address (> 0) of the drive, 0 if failed.
+ */
+static unsigned long idedisk_read_native_max_address(ide_drive_t *drive)
+{
+	ide_task_t args;
+	unsigned long addr = 0;
+
+	if (!(drive->id->command_set_1 & 0x0400) &&
+	    !(drive->id->cfs_enable_2 & 0x0100))
+		return addr;
+
+	/* Create IDE/ATA command request structure */
+	memset(&args, 0, sizeof(ide_task_t));
+	args.tfRegister[IDE_SELECT_OFFSET]	= 0x40;
+	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_READ_NATIVE_MAX;
+	args.handler				= task_no_data_intr;
+
+	/* submit command request */
+	ide_raw_taskfile(drive, &args, NULL);
+
+	/* if OK, compute maximum address value */
+	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
+		addr = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24)
+		     | ((args.tfRegister[  IDE_HCYL_OFFSET]       ) << 16)
+		     | ((args.tfRegister[  IDE_LCYL_OFFSET]       ) <<  8)
+		     | ((args.tfRegister[IDE_SECTOR_OFFSET]       ));
+	}
+	addr++;	/* since the return value is (maxlba - 1), we add 1 */
+	return addr;
+}
+
+static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive)
+{
+	ide_task_t args;
+	unsigned long long addr = 0;
+
+	/* Create IDE/ATA command request structure */
+	memset(&args, 0, sizeof(ide_task_t));
+
+	args.tfRegister[IDE_SELECT_OFFSET]	= 0x40;
+	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_READ_NATIVE_MAX_EXT;
+	args.handler				= task_no_data_intr;
+
+        /* submit command request */
+        ide_raw_taskfile(drive, &args, NULL);
+
+	/* if OK, compute maximum address value */
+	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
+		u32 high = ((args.hobRegister[IDE_HCYL_OFFSET_HOB])<<16) |
+			   ((args.hobRegister[IDE_LCYL_OFFSET_HOB])<<8) |
+  			    (args.hobRegister[IDE_SECTOR_OFFSET_HOB]); 
+		u32 low  = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) |
+			   ((args.tfRegister[IDE_LCYL_OFFSET])<<8) |
+			    (args.tfRegister[IDE_SECTOR_OFFSET]);
+		addr = ((__u64)high << 24) | low;
+	}
+	addr++;	/* since the return value is (maxlba - 1), we add 1 */
+	return addr;
+}
+
+#ifdef CONFIG_IDEDISK_STROKE
+/*
+ * Sets maximum virtual LBA address of the drive.
+ * Returns new maximum virtual LBA address (> 0) or 0 on failure.
+ */
+static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req)
+{
+	ide_task_t args;
+	unsigned long addr_set = 0;
+	
+	addr_req--;
+	/* Create IDE/ATA command request structure */
+	memset(&args, 0, sizeof(ide_task_t));
+	args.tfRegister[IDE_SECTOR_OFFSET]	= ((addr_req >>  0) & 0xff);
+	args.tfRegister[IDE_LCYL_OFFSET]	= ((addr_req >>  8) & 0xff);
+	args.tfRegister[IDE_HCYL_OFFSET]	= ((addr_req >> 16) & 0xff);
+	args.tfRegister[IDE_SELECT_OFFSET]	= ((addr_req >> 24) & 0x0f) | 0x40;
+	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SET_MAX;
+	args.handler				= task_no_data_intr;
+	/* submit command request */
+	ide_raw_taskfile(drive, &args, NULL);
+	/* if OK, read new maximum address value */
+	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
+		addr_set = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24)
+			 | ((args.tfRegister[  IDE_HCYL_OFFSET]       ) << 16)
+			 | ((args.tfRegister[  IDE_LCYL_OFFSET]       ) <<  8)
+			 | ((args.tfRegister[IDE_SECTOR_OFFSET]       ));
+	}
+	addr_set++;
+	return addr_set;
+}
+
+static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsigned long long addr_req)
+{
+	ide_task_t args;
+	unsigned long long addr_set = 0;
+
+	addr_req--;
+	/* Create IDE/ATA command request structure */
+	memset(&args, 0, sizeof(ide_task_t));
+	args.tfRegister[IDE_SECTOR_OFFSET]	= ((addr_req >>  0) & 0xff);
+	args.tfRegister[IDE_LCYL_OFFSET]	= ((addr_req >>= 8) & 0xff);
+	args.tfRegister[IDE_HCYL_OFFSET]	= ((addr_req >>= 8) & 0xff);
+	args.tfRegister[IDE_SELECT_OFFSET]      = 0x40;
+	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SET_MAX_EXT;
+	args.hobRegister[IDE_SECTOR_OFFSET_HOB]	= ((addr_req >>= 8) & 0xff);
+	args.hobRegister[IDE_LCYL_OFFSET_HOB]	= ((addr_req >>= 8) & 0xff);
+	args.hobRegister[IDE_HCYL_OFFSET_HOB]	= ((addr_req >>= 8) & 0xff);
+	args.hobRegister[IDE_SELECT_OFFSET_HOB]	= 0x40;
+	args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80);
+        args.handler				= task_no_data_intr;
+	/* submit command request */
+	ide_raw_taskfile(drive, &args, NULL);
+	/* if OK, compute maximum address value */
+	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
+		u32 high = ((args.hobRegister[IDE_HCYL_OFFSET_HOB])<<16) |
+			   ((args.hobRegister[IDE_LCYL_OFFSET_HOB])<<8) |
+			    (args.hobRegister[IDE_SECTOR_OFFSET_HOB]);
+		u32 low  = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) |
+			   ((args.tfRegister[IDE_LCYL_OFFSET])<<8) |
+			    (args.tfRegister[IDE_SECTOR_OFFSET]);
+		addr_set = ((__u64)high << 24) | low;
+	}
+	return addr_set;
+}
+
+/*
+ * Tests if the drive supports Host Protected Area feature.
+ * Returns true if supported, false otherwise.
+ */
+static inline int idedisk_supports_host_protected_area(ide_drive_t *drive)
+{
+	int flag = (drive->id->cfs_enable_1 & 0x0400) ? 1 : 0;
+	printk("%s: host protected area => %d\n", drive->name, flag);
+	return flag;
+}
+
+#endif /* CONFIG_IDEDISK_STROKE */
+
+/*
  * Compute drive->capacity, the full capacity of the drive
  * Called with drive->id != NULL.
+ *
+ * To compute capacity, this uses either of
+ *
+ *    1. CHS value set by user       (whatever user sets will be trusted)
+ *    2. LBA value from target drive (require new ATA feature)
+ *    3. LBA value from system BIOS  (new one is OK, old one may break)
+ *    4. CHS value from system BIOS  (traditional style)
+ *
+ * in above order (i.e., if value of higher priority is available,
+ * reset will be ignored).
  */
 static void init_idedisk_capacity (ide_drive_t  *drive)
 {
 	struct hd_driveid *id = drive->id;
 	unsigned long capacity = drive->cyl * drive->head * drive->sect;
+	unsigned long set_max = idedisk_read_native_max_address(drive);
+	unsigned long long capacity_2 = capacity;
+	unsigned long long set_max_ext;
 
+	drive->capacity48 = 0;
 	drive->select.b.lba = 0;
 
+	if (id->cfs_enable_2 & 0x0400) {
+		capacity_2 = id->lba_capacity_2;
+		drive->head		= drive->bios_head = 255;
+		drive->sect		= drive->bios_sect = 63;
+		drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
+		drive->select.b.lba	= 1;
+		set_max_ext = idedisk_read_native_max_address_ext(drive);
+		if (set_max_ext > capacity_2) {
+#ifdef CONFIG_IDEDISK_STROKE
+			set_max_ext = idedisk_read_native_max_address_ext(drive);
+			set_max_ext = idedisk_set_max_address_ext(drive, set_max_ext);
+			if (set_max_ext) {
+				drive->capacity48 = capacity_2 = set_max_ext;
+				drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect);
+				drive->select.b.lba = 1;
+				drive->id->lba_capacity_2 = capacity_2;
+                        }
+#else /* !CONFIG_IDEDISK_STROKE */
+			printk("%s: setmax_ext LBA %llu, native  %llu\n",
+				drive->name, set_max_ext, capacity_2);
+#endif /* CONFIG_IDEDISK_STROKE */
+		}
+		drive->bios_cyl		= drive->cyl;
+		drive->capacity48	= capacity_2;
+		drive->capacity		= (unsigned long) capacity_2;
+		return;
 	/* Determine capacity, and use LBA if the drive properly supports it */
-	if ((id->capability & 2) && lba_capacity_is_ok(id)) {
+	} else if ((id->capability & 2) && lba_capacity_is_ok(id)) {
 		capacity = id->lba_capacity;
 		drive->cyl = capacity / (drive->head * drive->sect);
 		drive->select.b.lba = 1;
 	}
+
+	if (set_max > capacity) {
+#ifdef CONFIG_IDEDISK_STROKE
+		set_max = idedisk_read_native_max_address(drive);
+		set_max = idedisk_set_max_address(drive, set_max);
+		if (set_max) {
+			drive->capacity = capacity = set_max;
+			drive->cyl = set_max / (drive->head * drive->sect);
+			drive->select.b.lba = 1;
+			drive->id->lba_capacity = capacity;
+		}
+#else /* !CONFIG_IDEDISK_STROKE */
+		printk("%s: setmax LBA %lu, native  %lu\n",
+			drive->name, set_max, capacity);
+#endif /* CONFIG_IDEDISK_STROKE */
+	}
+
 	drive->capacity = capacity;
+
+	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
+                drive->capacity48 = id->lba_capacity_2;
+		drive->head = 255;
+		drive->sect = 63;
+		drive->cyl = (unsigned long)(drive->capacity48) / (drive->head * drive->sect);
+	}
 }
 
-static unsigned long idedisk_capacity (ide_drive_t  *drive)
+static unsigned long idedisk_capacity (ide_drive_t *drive)
 {
+	if (drive->id->cfs_enable_2 & 0x0400)
+		return (drive->capacity48 - drive->sect0);
 	return (drive->capacity - drive->sect0);
 }
 
@@ -530,23 +998,48 @@
 	special_t *s = &drive->special;
 
 	if (s->b.set_geometry) {
-		s->b.set_geometry = 0;
-		OUT_BYTE(drive->sect,IDE_SECTOR_REG);
-		OUT_BYTE(drive->cyl,IDE_LCYL_REG);
-		OUT_BYTE(drive->cyl>>8,IDE_HCYL_REG);
-		OUT_BYTE(((drive->head-1)|drive->select.all)&0xBF,IDE_SELECT_REG);
-		if (!IS_PDC4030_DRIVE)
-			ide_cmd(drive, WIN_SPECIFY, drive->sect, &set_geometry_intr);
+		struct hd_drive_task_hdr taskfile;
+		struct hd_drive_hob_hdr hobfile;
+		ide_handler_t *handler = NULL;
+
+		memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+		memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+
+		s->b.set_geometry	= 0;
+		taskfile.sector_number	= drive->sect;
+		taskfile.low_cylinder	= drive->cyl;
+		taskfile.high_cylinder	= drive->cyl>>8;
+		taskfile.device_head	= ((drive->head-1)|drive->select.all)&0xBF;
+		if (!IS_PDC4030_DRIVE) {
+			taskfile.sector_count	= drive->sect;
+			taskfile.command	= WIN_SPECIFY;
+			handler			= ide_handler_parser(&taskfile, &hobfile);
+		}
+		do_taskfile(drive, &taskfile, &hobfile, handler);
 	} else if (s->b.recalibrate) {
 		s->b.recalibrate = 0;
-		if (!IS_PDC4030_DRIVE)
-			ide_cmd(drive, WIN_RESTORE, drive->sect, &recal_intr);
+		if (!IS_PDC4030_DRIVE) {
+			struct hd_drive_task_hdr taskfile;
+			struct hd_drive_hob_hdr hobfile;
+			memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+			memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+			taskfile.sector_count	= drive->sect;
+			taskfile.command	= WIN_RESTORE;
+			do_taskfile(drive, &taskfile, &hobfile, ide_handler_parser(&taskfile, &hobfile));
+		}
 	} else if (s->b.set_multmode) {
 		s->b.set_multmode = 0;
 		if (drive->id && drive->mult_req > drive->id->max_multsect)
 			drive->mult_req = drive->id->max_multsect;
-		if (!IS_PDC4030_DRIVE)
-			ide_cmd(drive, WIN_SETMULT, drive->mult_req, &set_multmode_intr);
+		if (!IS_PDC4030_DRIVE) {
+			struct hd_drive_task_hdr taskfile;
+			struct hd_drive_hob_hdr hobfile;
+			memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+			memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+			taskfile.sector_count	= drive->mult_req;
+			taskfile.command	= WIN_SETMULT;
+			do_taskfile(drive, &taskfile, &hobfile, ide_handler_parser(&taskfile, &hobfile));
+		}
 	} else if (s->all) {
 		int special = s->all;
 		s->all = 0;
@@ -558,9 +1051,11 @@
 
 static void idedisk_pre_reset (ide_drive_t *drive)
 {
+	int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;
+
 	drive->special.all = 0;
-	drive->special.b.set_geometry = 1;
-	drive->special.b.recalibrate  = 1;
+	drive->special.b.set_geometry = legacy;
+	drive->special.b.recalibrate  = legacy;
 	if (OK_TO_RESET_CONTROLLER)
 		drive->mult_count = 0;
 	if (!drive->keep_settings && !drive->using_dma)
@@ -573,19 +1068,45 @@
 
 static int smart_enable(ide_drive_t *drive)
 {
-	return ide_wait_cmd(drive, WIN_SMART, 0, SMART_ENABLE, 0, NULL);
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	taskfile.feature	= SMART_ENABLE;
+	taskfile.low_cylinder	= SMART_LCYL_PASS;
+	taskfile.high_cylinder	= SMART_HCYL_PASS;
+	taskfile.command	= WIN_SMART;
+	return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
 }
 
 static int get_smart_values(ide_drive_t *drive, byte *buf)
 {
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	taskfile.feature	= SMART_READ_VALUES;
+	taskfile.sector_count	= 0x01;
+	taskfile.low_cylinder	= SMART_LCYL_PASS;
+	taskfile.high_cylinder	= SMART_HCYL_PASS;
+	taskfile.command	= WIN_SMART;
 	(void) smart_enable(drive);
-	return ide_wait_cmd(drive, WIN_SMART, 0, SMART_READ_VALUES, 1, buf);
+	return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
 }
 
 static int get_smart_thresholds(ide_drive_t *drive, byte *buf)
 {
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	taskfile.feature	= SMART_READ_THRESHOLDS;
+	taskfile.sector_count	= 0x01;
+	taskfile.low_cylinder	= SMART_LCYL_PASS;
+	taskfile.high_cylinder	= SMART_HCYL_PASS;
+	taskfile.command	= WIN_SMART;
 	(void) smart_enable(drive);
-	return ide_wait_cmd(drive, WIN_SMART, 0, SMART_READ_THRESHOLDS, 1, buf);
+	return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
 }
 
 static int proc_idedisk_read_cache
@@ -609,7 +1130,7 @@
 	int		len = 0, i = 0;
 
 	if (!get_smart_thresholds(drive, page)) {
-		unsigned short *val = ((unsigned short *)page) + 2;
+		unsigned short *val = (unsigned short *) page;
 		char *out = ((char *)val) + (SECTOR_WORDS * 4);
 		page = out;
 		do {
@@ -628,7 +1149,7 @@
 	int		len = 0, i = 0;
 
 	if (!get_smart_values(drive, page)) {
-		unsigned short *val = ((unsigned short *)page) + 2;
+		unsigned short *val = (unsigned short *) page;
 		char *out = ((char *)val) + (SECTOR_WORDS * 4);
 		page = out;
 		do {
@@ -656,14 +1177,31 @@
 
 static int set_multcount(ide_drive_t *drive, int arg)
 {
+#ifdef __TASKFILE__IO
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+
+	if (drive->special.b.set_multmode)
+		return -EBUSY;
+
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	taskfile.sector_count	= drive->mult_req;
+	taskfile.command	= WIN_SETMULT;
+	drive->mult_req		= arg;
+	drive->special.b.set_multmode = 1;
+	ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
+#else /* !__TASKFILE__IO */
 	struct request rq;
 
 	if (drive->special.b.set_multmode)
 		return -EBUSY;
 	ide_init_drive_cmd (&rq);
+	rq.cmd = IDE_DRIVE_CMD;
 	drive->mult_req = arg;
 	drive->special.b.set_multmode = 1;
 	(void) ide_do_drive_cmd (drive, &rq, ide_wait);
+#endif /* __TASKFILE__IO */
 	return (drive->mult_count == arg) ? 0 : -EIO;
 }
 
@@ -677,6 +1215,79 @@
 	return 0;
 }
 
+static int write_cache (ide_drive_t *drive, int arg)
+{
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	taskfile.feature	= (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
+	taskfile.command	= WIN_SETFEATURES;
+
+	if (!(drive->id->cfs_enable_2 & 0x3000))
+		return 1;
+
+	(void) ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
+	drive->wcache = arg;
+	return 0;
+}
+
+static int do_idedisk_standby (ide_drive_t *drive)
+{
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	taskfile.command	= WIN_STANDBYNOW1;
+	return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
+}
+
+static int do_idedisk_flushcache (ide_drive_t *drive)
+{
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	if (drive->id->cfs_enable_2 & 0x2400) {
+		taskfile.command	= WIN_FLUSH_CACHE_EXT;
+	} else {
+		taskfile.command	= WIN_FLUSH_CACHE;
+	}
+	return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
+}
+
+static int set_acoustic (ide_drive_t *drive, int arg)
+{
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+
+	taskfile.feature	= (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
+	taskfile.sector_count	= arg;
+
+	taskfile.command	= WIN_SETFEATURES;
+	(void) ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
+	drive->acoustic = arg;
+	return 0;
+}
+
+static int probe_lba_addressing (ide_drive_t *drive, int arg)
+{
+	drive->addressing =  0;
+
+	if (!(drive->id->cfs_enable_2 & 0x0400))
+                return -EIO;
+
+	drive->addressing = arg;
+	return 0;
+}
+
+static int set_lba_addressing (ide_drive_t *drive, int arg)
+{
+	return (probe_lba_addressing(drive, arg));
+}
+
 static void idedisk_add_settings(ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
@@ -686,15 +1297,18 @@
 	ide_add_setting(drive,	"bios_cyl",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->bios_cyl,		NULL);
 	ide_add_setting(drive,	"bios_head",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	255,				1,	1,	&drive->bios_head,		NULL);
 	ide_add_setting(drive,	"bios_sect",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	63,				1,	1,	&drive->bios_sect,		NULL);
+	ide_add_setting(drive,	"address",		SETTING_RW,					HDIO_GET_ADDRESS,	HDIO_SET_ADDRESS,	TYPE_INTA,	0,	2,				1,	1,	&drive->addressing,	set_lba_addressing);
 	ide_add_setting(drive,	"bswap",		SETTING_READ,					-1,			-1,			TYPE_BYTE,	0,	1,				1,	1,	&drive->bswap,			NULL);
-	ide_add_setting(drive,	"multcount",		id ? SETTING_RW : SETTING_READ,			HDIO_GET_MULTCOUNT,	HDIO_SET_MULTCOUNT,	TYPE_BYTE,	0,	id ? id->max_multsect : 0,	1,	2,	&drive->mult_count,		set_multcount);
+	ide_add_setting(drive,	"multcount",		id ? SETTING_RW : SETTING_READ,			HDIO_GET_MULTCOUNT,	HDIO_SET_MULTCOUNT,	TYPE_BYTE,	0,	id ? id->max_multsect : 0,	1,	1,	&drive->mult_count,		set_multcount);
 	ide_add_setting(drive,	"nowerr",		SETTING_RW,					HDIO_GET_NOWERR,	HDIO_SET_NOWERR,	TYPE_BYTE,	0,	1,				1,	1,	&drive->nowerr,			set_nowerr);
-	ide_add_setting(drive,	"breada_readahead",	SETTING_RW,					BLKRAGET,		BLKRASET,		TYPE_INT,	0,	255,				1,	2,	&read_ahead[major],		NULL);
+	ide_add_setting(drive,	"breada_readahead",	SETTING_RW,					BLKRAGET,		BLKRASET,		TYPE_INT,	0,	255,				1,	1,	&read_ahead[major],		NULL);
 	ide_add_setting(drive,	"file_readahead",	SETTING_RW,					BLKFRAGET,		BLKFRASET,		TYPE_INTA,	0,	4096,			PAGE_SIZE,	1024,	&max_readahead[major][minor],	NULL);
-	ide_add_setting(drive,	"max_kb_per_request",	SETTING_RW,					BLKSECTGET,		BLKSECTSET,		TYPE_INTA,	1,	255,				1,	2,	&max_sectors[major][minor],	NULL);
+	ide_add_setting(drive,	"max_kb_per_request",	SETTING_RW,					BLKSECTGET,		BLKSECTSET,		TYPE_INTA,	1,	255,				1,	1,	&max_sectors[major][minor],	NULL);
 	ide_add_setting(drive,	"lun",			SETTING_RW,					-1,			-1,			TYPE_INT,	0,	7,				1,	1,	&drive->lun,			NULL);
-	ide_add_setting(drive,	"failures",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->failures,		NULL);
-	ide_add_setting(drive,	"max_failures",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->max_failures,		NULL);
+	ide_add_setting(drive,	"wcache",		SETTING_RW,					HDIO_GET_WCACHE,	HDIO_SET_WCACHE,	TYPE_BYTE,	0,	1,				1,	1,	&drive->wcache,			write_cache);
+	ide_add_setting(drive,	"acoustic",		SETTING_RW,					HDIO_GET_ACOUSTIC,	HDIO_SET_ACOUSTIC,	TYPE_BYTE,	0,	254,				1,	1,	&drive->acoustic,		set_acoustic);
+ 	ide_add_setting(drive,	"failures",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->failures,		NULL);
+ 	ide_add_setting(drive,	"max_failures",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->max_failures,		NULL);
 }
 
 static void idedisk_setup (ide_drive_t *drive)
@@ -764,7 +1378,6 @@
 	if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) &&
 	    (!drive->forced_geom) && drive->bios_sect && drive->bios_head)
 		drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head;
-
 	printk (KERN_INFO "%s: %ld sectors", drive->name, capacity);
 
 	/* Give size in megabytes (MB), not mebibytes (MiB). */
@@ -796,21 +1409,25 @@
 			drive->mult_req = id->max_multsect;
 		if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect))
 			drive->special.b.set_multmode = 1;
-#endif
+#endif	/* CONFIG_IDEDISK_MULTI_MODE */
 	}
 	drive->no_io_32bit = id->dword_io ? 1 : 0;
-}
-
-static int idedisk_reinit (ide_drive_t *drive)
-{
-	return 0;
+	if (drive->id->cfs_enable_2 & 0x3000)
+		write_cache(drive, (id->cfs_enable_2 & 0x3000));
+	(void) probe_lba_addressing(drive, 1);
 }
 
 static int idedisk_cleanup (ide_drive_t *drive)
 {
+	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
+		if (do_idedisk_flushcache(drive))
+			printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
+				drive->name);
 	return ide_unregister_subdriver(drive);
 }
 
+int idedisk_reinit(ide_drive_t *drive);
+
 /*
  *      IDE subdriver functions, registered with ide.c
  */
@@ -822,6 +1439,8 @@
 	supports_dma:		1,
 	supports_dsc_overlap:	0,
 	cleanup:		idedisk_cleanup,
+	standby:		do_idedisk_standby,
+	flushcache:		do_idedisk_flushcache,
 	do_request:		do_rw_disk,
 	end_request:		NULL,
 	ioctl:			NULL,
@@ -833,7 +1452,9 @@
 	capacity:		idedisk_capacity,
 	special:		idedisk_special,
 	proc:			idedisk_proc,
-	driver_reinit:		idedisk_reinit,
+	reinit:			idedisk_reinit,
+	ata_prebuilder:		NULL,
+	atapi_prebuilder:	NULL,
 };
 
 int idedisk_init (void);
@@ -846,6 +1467,32 @@
 
 MODULE_DESCRIPTION("ATA DISK Driver");
 
+int idedisk_reinit (ide_drive_t *drive)
+{
+	int failed = 0;
+
+	MOD_INC_USE_COUNT;
+
+	if (ide_register_subdriver (drive, &idedisk_driver, IDE_SUBDRIVER_VERSION)) {
+		printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
+		return 1;
+	}
+	DRIVER(drive)->busy++;
+	idedisk_setup(drive);
+	if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
+		printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", drive->name, drive->head);
+		(void) idedisk_cleanup(drive);
+		DRIVER(drive)->busy--;
+		return 1;
+	}
+	DRIVER(drive)->busy--;
+	failed--;
+
+	ide_register_module(&idedisk_module);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
 static void __exit idedisk_exit (void)
 {
 	ide_drive_t *drive;
@@ -877,12 +1524,15 @@
 			printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
 			continue;
 		}
+		DRIVER(drive)->busy++;
 		idedisk_setup(drive);
 		if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
 			printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", drive->name, drive->head);
 			(void) idedisk_cleanup(drive);
+			DRIVER(drive)->busy--;
 			continue;
 		}
+		DRIVER(drive)->busy--;
 		failed--;
 	}
 	ide_register_module(&idedisk_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux.orig/drivers/ide/ide-dma.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/drivers/ide/ide-dma.c	2002-07-20 01:08:27.000000000 +0000
@@ -123,6 +123,7 @@
 
 	{ "WDC AC11000H"	,	"ALL"		},
 	{ "WDC AC22100H"	,	"ALL"		},
+	{ "WDC AC31000H"	,	"ALL"		},
 	{ "WDC AC32500H"	,	"ALL"		},
 	{ "WDC AC33100H"	,	"ALL"		},
 	{ "WDC AC31600H"	,	"ALL"		},
@@ -282,6 +283,37 @@
 	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
 }
 
+static int ide_raw_build_sglist (ide_hwif_t *hwif, struct request *rq)
+{
+	struct scatterlist *sg = hwif->sg_table;
+	int nents = 0;
+	ide_task_t *args = rq->special;
+	unsigned char *virt_addr = rq->buffer;
+	int sector_count = rq->nr_sectors;
+
+//	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_WRITEDMA) ||
+//	    (args->tfRegister[IDE_COMMAND_OFFSET] == WIN_WRITEDMA_EXT))
+	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
+		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
+	else
+		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
+	
+	if (sector_count > 128) {
+		memset(&sg[nents], 0, sizeof(*sg));
+		sg[nents].address = virt_addr;
+		sg[nents].length = 128  * SECTOR_SIZE;
+		nents++;
+		virt_addr = virt_addr + (128 * SECTOR_SIZE);
+		sector_count -= 128;
+	}
+	memset(&sg[nents], 0, sizeof(*sg));
+	sg[nents].address = virt_addr;
+	sg[nents].length =  sector_count  * SECTOR_SIZE;
+	nents++;
+   
+	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
+}
+
 /*
  * ide_build_dmatable() prepares a dma request.
  * Returns 0 if all went okay, returns 1 otherwise.
@@ -299,7 +331,10 @@
 	int i;
 	struct scatterlist *sg;
 
-	HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
+	if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE)
+		HWIF(drive)->sg_nents = i = ide_raw_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
+	else
+		HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
 
 	if (!i)
 		return 0;
@@ -429,7 +464,14 @@
 	struct hd_driveid *id = drive->id;
 
 	if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
-	    (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
+	    (id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
+		if ((id->dma_ultra >> 15) & 1) {
+			printk(", UDMA(mode 7)");	/* UDMA BIOS-enabled! */
+		} else {
+			printk(", UDMA(133)");	/* UDMA BIOS-enabled! */
+		}
+	} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
+	  	  (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
 		if ((id->dma_ultra >> 13) & 1) {
 			printk(", UDMA(100)");	/* UDMA BIOS-enabled! */
 		} else if ((id->dma_ultra >> 12) & 1) {
@@ -456,14 +498,24 @@
 
 static int config_drive_for_dma (ide_drive_t *drive)
 {
+	int config_allows_dma = 1;
 	struct hd_driveid *id = drive->id;
 	ide_hwif_t *hwif = HWIF(drive);
 
-	if (id && (id->capability & 1) && hwif->autodma) {
+#ifdef CONFIG_IDEDMA_ONLYDISK
+	if (drive->media != ide_disk)
+		config_allows_dma = 0;
+#endif
+
+	if (id && (id->capability & 1) && hwif->autodma && config_allows_dma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive))
 			return hwif->dmaproc(ide_dma_off, drive);
 
+		/* Enable DMA on any drive that has UltraDMA (mode 6/7/?) enabled */
+		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
+			if ((id->dma_ultra & (id->dma_ultra >> 14) & 2))
+				return hwif->dmaproc(ide_dma_on, drive);
 		/* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */
 		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
 			if ((id->dma_ultra & (id->dma_ultra >> 11) & 7))
@@ -495,7 +547,7 @@
 	printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat);
 #endif /* DEBUG */
 
-#if 1
+#if 0
 	HWGROUP(drive)->expiry = NULL;	/* one free ride for now */
 #endif
 
@@ -550,7 +602,7 @@
  */
 int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 {
-//	ide_hwgroup_t *hwgroup		= HWGROUP(drive);
+//	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
 	ide_hwif_t *hwif		= HWIF(drive);
 	unsigned long dma_base		= hwif->dma_base;
 	byte unit			= (drive->select.b.unit & 0x01);
@@ -582,11 +634,20 @@
 			if (drive->media != ide_disk)
 				return 0;
 #ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
-			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);	/* issue cmd to drive */
+			ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL);	/* issue cmd to drive */
 #else /* !CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry);	/* issue cmd to drive */
 #endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
-			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+			if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+			}
+			return HWIF(drive)->dmaproc(ide_dma_begin, drive);
 		case ide_dma_begin:
 			/* Note that this is done *after* the cmd has
 			 * been issued to the drive, as per the BM-IDE spec.
@@ -604,7 +665,7 @@
 			return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
 		case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
 			dma_stat = inb(dma_base+2);
-#if 0	/* do not set unless you know what you are doing */
+#if 0  /* do not set unless you know what you are doing */
 			if (dma_stat & 4) {
 				byte stat = GET_STAT();
 				outb(dma_base+2, dma_stat & 0xE4);
@@ -649,6 +710,8 @@
 				GET_STAT(), dma_stat);
 
 			return restart_request(drive);  // BUG: return types do not match!!
+//#else
+//			return HWGROUP(drive)->handler(drive);
 #endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
 		case ide_dma_retune:
 		case ide_dma_lostirq:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c
--- linux.orig/drivers/ide/ide-features.c	2001-02-09 19:40:02.000000000 +0000
+++ linux/drivers/ide/ide-features.c	2002-07-20 01:08:26.000000000 +0000
@@ -127,30 +127,14 @@
 		case XFER_UDMA_3:	return XFER_UDMA_2;
 		case XFER_UDMA_2:	return XFER_UDMA_1;
 		case XFER_UDMA_1:	return XFER_UDMA_0;
+			/*
+			 * OOPS we do not goto non Ultra DMA modes
+			 * without iCRC's available we force
+			 * the system to PIO and make the user
+			 * invoke the ATA-1 ATA-2 DMA modes.
+			 */
 		case XFER_UDMA_0:
-			if (drive->id->dma_mword & 0x0004) return XFER_MW_DMA_2;
-			else if (drive->id->dma_mword & 0x0002) return XFER_MW_DMA_1;
-			else if (drive->id->dma_mword & 0x0001) return XFER_MW_DMA_0;
-			else return XFER_PIO_4;
-		case XFER_MW_DMA_2:	return XFER_MW_DMA_1;
-		case XFER_MW_DMA_1:	return XFER_MW_DMA_0;
-		case XFER_MW_DMA_0:
-			if (drive->id->dma_1word & 0x0004) return XFER_SW_DMA_2;
-			else if (drive->id->dma_1word & 0x0002) return XFER_SW_DMA_1;
-			else if (drive->id->dma_1word & 0x0001) return XFER_SW_DMA_0;
-			else return XFER_PIO_4;
-		case XFER_SW_DMA_2:	return XFER_SW_DMA_1;
-		case XFER_SW_DMA_1:	return XFER_SW_DMA_0;
-		case XFER_SW_DMA_0:
-			{
-				return XFER_PIO_4;
-			}
-		case XFER_PIO_4:	return XFER_PIO_3;
-		case XFER_PIO_3:	return XFER_PIO_2;
-		case XFER_PIO_2:	return XFER_PIO_1;
-		case XFER_PIO_1:	return XFER_PIO_0;
-		case XFER_PIO_0:
-		default:		return XFER_PIO_SLOW;
+		default:		return XFER_PIO_4;
 	}
 }
 
@@ -216,11 +200,11 @@
  * in combination with the device (usually a disk) properly detect
  * and acknowledge each end of the ribbon.
  */
-int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
+int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
 {
-	if ((cmd == WIN_SETFEATURES) &&
-	    (nsect > XFER_UDMA_2) &&
-	    (feature == SETFEATURES_XFER)) {
+	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
+	    (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
+	    (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
 		if (!HWIF(drive)->udma_four) {
 			printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", HWIF(drive)->name);
 			return 1;
@@ -243,11 +227,11 @@
  * 1 : Safe to update drive->id DMA registers.
  * 0 : OOPs not allowed.
  */
-int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
+int set_transfer (ide_drive_t *drive, ide_task_t *args)
 {
-	if ((cmd == WIN_SETFEATURES) &&
-	    (nsect >= XFER_SW_DMA_0) &&
-	    (feature == SETFEATURES_XFER) &&
+	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
+	    (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
+	    (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
 	    (drive->id->dma_ultra ||
 	     drive->id->dma_mword ||
 	     drive->id->dma_1word))
@@ -256,17 +240,24 @@
 	return 0;
 }
 
+#ifdef CONFIG_BLK_DEV_IDEDMA
 /*
  *  All hosts that use the 80c ribbon mus use!
  */
 byte eighty_ninty_three (ide_drive_t *drive)
 {
+#ifdef CONFIG_BLK_DEV_IDEPCI
+	if (HWIF(drive)->pci_devid.vid==0x105a)
+	    return(HWIF(drive)->udma_four);
+#endif
+	/* PDC202XX: that's because some HDD will return wrong info */
 	return ((byte) ((HWIF(drive)->udma_four) &&
 #ifndef CONFIG_IDEDMA_IVB
 			(drive->id->hw_config & 0x4000) &&
 #endif /* CONFIG_IDEDMA_IVB */
 			(drive->id->hw_config & 0x6000)) ? 1 : 0);
 }
+#endif // CONFIG_BLK_DEV_IDEDMA
 
 /*
  * Similar to ide_wait_stat(), except it never calls ide_error internally.
@@ -387,5 +378,8 @@
 EXPORT_SYMBOL(ide_driveid_update);
 EXPORT_SYMBOL(ide_ata66_check);
 EXPORT_SYMBOL(set_transfer);
+#ifdef CONFIG_BLK_DEV_IDEDMA
 EXPORT_SYMBOL(eighty_ninty_three);
+#endif // CONFIG_BLK_DEV_IDEDMA
 EXPORT_SYMBOL(ide_config_drive_speed);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux.orig/drivers/ide/ide-floppy.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ide/ide-floppy.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,8 +1,8 @@
 /*
- * linux/drivers/ide/ide-floppy.c	Version 0.97.sv	Jan 14 2001
+ * linux/drivers/ide/ide-floppy.c	Version 0.99	Feb 24 2002
  *
  * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
- * Copyright (C) 2000 - 2001 Paul Bristow <paul@paulbristow.net>
+ * Copyright (C) 2000 - 2002 Paul Bristow <paul@paulbristow.net>
  */
 
 /*
@@ -13,7 +13,7 @@
  *
  * This driver supports the following IDE floppy drives:
  *
- * LS-120 SuperDisk
+ * LS-120/240 SuperDisk
  * Iomega Zip 100/250
  * Iomega PC Card Clik!/PocketZip
  *
@@ -68,12 +68,19 @@
  * Ver 0.94  Oct 27 00   Tidied up to remove strstr(Clik) everywhere
  * Ver 0.95  Nov  7 00   Brought across to kernel 2.4
  * Ver 0.96  Jan  7 01   Actually in line with release version of 2.4.0
- *                       including set_bit patch from Rusty Russel
+ *                       including set_bit patch from Rusty Russell
  * Ver 0.97  Jul 22 01   Merge 0.91-0.96 onto 0.9.sv for ac series
  * Ver 0.97.sv Aug 3 01  Backported from 2.4.7-ac3
+ * Ver 0.98  Oct 26 01   Split idefloppy_transfer_pc into two pieces to
+ *                        fix a lost interrupt problem. It appears the busy
+ *                        bit was being deasserted by my IOMEGA ATAPI ZIP 100
+ *                        drive before the drive was actually ready.
+ * Ver 0.98a Oct 29 01   Expose delay value so we can play.
+ * Ver 0.99  Feb 24 02   Remove duplicate code, modify clik! detection code 
+ *                        to support new PocketZip drives 
  */
 
-#define IDEFLOPPY_VERSION "0.97.sv"
+#define IDEFLOPPY_VERSION "0.99.newide"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -276,6 +283,7 @@
 	 *	Last error information
 	 */
 	byte sense_key, asc, ascq;
+	byte ticks;		/* delay this long before sending packet command */
 	int progress_indication;
 
 	/*
@@ -289,6 +297,8 @@
 	unsigned long flags;			/* Status/Action flags */
 } idefloppy_floppy_t;
 
+#define IDEFLOPPY_TICKS_DELAY	3	/* default delay for ZIP 100 */
+
 /*
  *	Floppy flag bits values.
  */
@@ -297,7 +307,7 @@
 #define IDEFLOPPY_USE_READ12		2	/* Use READ12/WRITE12 or READ10/WRITE10 */
 #define	IDEFLOPPY_FORMAT_IN_PROGRESS	3	/* Format in progress */
 #define IDEFLOPPY_CLIK_DRIVE	        4       /* Avoid commands not supported in Clik drive */
-
+#define IDEFLOPPY_ZIP_DRIVE		5	/* Requires BH algorithm for packets */
 
 /*
  *	ATAPI floppy drive packet commands
@@ -1001,6 +1011,11 @@
 	return ide_started;
 }
 
+/*
+ * This is the original routine that did the packet transfer.
+ * It fails at high speeds on the Iomega ZIP drive, so there's a slower version
+ * for that drive below. The algorithm is chosen based on drive type
+ */
 static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive)
 {
 	ide_startstop_t startstop;
@@ -1021,6 +1036,56 @@
 	return ide_started;
 }
 
+
+/*
+ * What we have here is a classic case of a top half / bottom half
+ * interrupt service routine. In interrupt mode, the device sends
+ * an interrupt to signal it's ready to receive a packet. However,
+ * we need to delay about 2-3 ticks before issuing the packet or we
+ * gets in trouble.
+ *
+ * So, follow carefully. transfer_pc1 is called as an interrupt (or
+ * directly). In either case, when the device says it's ready for a 
+ * packet, we schedule the packet transfer to occur about 2-3 ticks
+ * later in transfer_pc2.
+ */
+static int idefloppy_transfer_pc2 (ide_drive_t *drive)
+{
+	idefloppy_floppy_t *floppy = drive->driver_data;
+
+	atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */
+	return IDEFLOPPY_WAIT_CMD;		/* Timeout for the packet command */
+}
+
+static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
+{
+	idefloppy_floppy_t *floppy = drive->driver_data;
+	ide_startstop_t startstop;
+	idefloppy_ireason_reg_t ireason;
+
+	if (ide_wait_stat (&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
+		printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
+		return startstop;
+	}
+	ireason.all=IN_BYTE (IDE_IREASON_REG);
+	if (!ireason.b.cod || ireason.b.io) {
+		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
+		return ide_do_reset (drive);
+	}
+	/* 
+	 * The following delay solves a problem with ATAPI Zip 100 drives where the
+	 * Busy flag was apparently being deasserted before the unit was ready to
+	 * receive data. This was happening on a 1200 MHz Athlon system. 10/26/01
+	 * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will 
+	 * not be actually used until after the packet is moved in about 50 msec.
+	 */
+	ide_set_handler (drive, 
+	  &idefloppy_pc_intr, 		/* service routine for packet command */
+	  floppy->ticks,			/* wait this long before "failing" */
+	  &idefloppy_transfer_pc2);	/* fail == transfer_pc2 */
+	return ide_started;
+}
+
 /*
  *	Issue a packet command
  */
@@ -1029,6 +1094,7 @@
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	idefloppy_bcount_reg_t bcount;
 	int dma_ok = 0;
+	ide_handler_t *pkt_xfer_routine;
 
 #if IDEFLOPPY_DEBUG_BUGS
 	if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
@@ -1088,13 +1154,20 @@
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
+	/* Can we transfer the packet when we get the interrupt or wait? */
+	if (test_bit (IDEFLOPPY_ZIP_DRIVE, &floppy->flags)) {
+		pkt_xfer_routine = &idefloppy_transfer_pc1;	/* wait */
+	} else {
+		pkt_xfer_routine = &idefloppy_transfer_pc;	/* immediate */
+	}
+	
 	if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
-		ide_set_handler (drive, &idefloppy_transfer_pc, IDEFLOPPY_WAIT_CMD, NULL);
+		ide_set_handler (drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);		/* Issue the packet command */
 		return ide_started;
 	} else {
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
-		return idefloppy_transfer_pc (drive);
+		return (*pkt_xfer_routine) (drive);
 	}
 }
 
@@ -1914,13 +1987,18 @@
 {
 	int major = HWIF(drive)->major;
 	int minor = drive->select.b.unit << PARTN_BITS;
+	idefloppy_floppy_t *floppy = drive->driver_data;
 
+/*
+ *			drive	setting name	read/write	ioctl	ioctl		data type	min	max	mul_factor	div_factor	data pointer		set function
+ */
 	ide_add_setting(drive,	"bios_cyl",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	1023,				1,	1,	&drive->bios_cyl,		NULL);
 	ide_add_setting(drive,	"bios_head",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	255,				1,	1,	&drive->bios_head,		NULL);
 	ide_add_setting(drive,	"bios_sect",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	63,				1,	1,	&drive->bios_sect,		NULL);
 	ide_add_setting(drive,	"breada_readahead",	SETTING_RW,					BLKRAGET,		BLKRASET,		TYPE_INT,	0,	255,				1,	2,	&read_ahead[major],		NULL);
 	ide_add_setting(drive,	"file_readahead",	SETTING_RW,					BLKFRAGET,		BLKFRASET,		TYPE_INTA,	0,	INT_MAX,			1,	1024,	&max_readahead[major][minor],	NULL);
 	ide_add_setting(drive,	"max_kb_per_request",	SETTING_RW,					BLKSECTGET,		BLKSECTSET,		TYPE_INTA,	1,	255,				1,	2,	&max_sectors[major][minor],	NULL);
+	ide_add_setting(drive,	"ticks",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	255,				1,	1,	&floppy->ticks,		NULL);
 
 }
 
@@ -1954,27 +2032,19 @@
 
 	if (strcmp(drive->id->model, "IOMEGA ZIP 100 ATAPI") == 0)
 	{
+		set_bit(IDEFLOPPY_ZIP_DRIVE, &floppy->flags);
+		/* This value will be visible in the /proc/ide/hdx/settings */
+		floppy->ticks = IDEFLOPPY_TICKS_DELAY;
 		for (i = 0; i < 1 << PARTN_BITS; i++)
 			max_sectors[major][minor + i] = 64;
 	}
-  /*
-   *      Guess what?  The IOMEGA Clik! drive also needs the
-   *      above fix.  It makes nasty clicking noises without
-   *      it, so please don't remove this.
-   */
-  if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0)
-  {
-    for (i = 0; i < 1 << PARTN_BITS; i++)
-      max_sectors[major][minor + i] = 64;
-    set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
-  }
 
 	/*
 	*      Guess what?  The IOMEGA Clik! drive also needs the
 	*      above fix.  It makes nasty clicking noises without
 	*      it, so please don't remove this.
 	*/
-	if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0) 
+	if (strncmp(drive->id->model, "IOMEGA Clik!", 11) == 0) 
 	{
 		for (i = 0; i < 1 << PARTN_BITS; i++)
 			max_sectors[major][minor + i] = 64;
@@ -2019,10 +2089,7 @@
 
 #endif	/* CONFIG_PROC_FS */
 
-static int idefloppy_reinit (ide_drive_t *drive)
-{
-	return 0;
-}
+int idefloppy_reinit(ide_drive_t *drive);
 
 /*
  *	IDE subdriver functions, registered with ide.c
@@ -2035,6 +2102,8 @@
 	supports_dma:		1,
 	supports_dsc_overlap:	0,
 	cleanup:		idefloppy_cleanup,
+	standby:		NULL,
+	flushcache:		NULL,
 	do_request:		idefloppy_do_request,
 	end_request:		idefloppy_end_request,
 	ioctl:			idefloppy_ioctl,
@@ -2046,7 +2115,9 @@
 	capacity:		idefloppy_capacity,
 	special:		NULL,
 	proc:			idefloppy_proc,
-	driver_reinit:		idefloppy_reinit,
+	reinit:			idefloppy_reinit,
+	ata_prebuilder:		NULL,
+	atapi_prebuilder:	NULL,
 };
 
 int idefloppy_init (void);
@@ -2057,6 +2128,40 @@
 	NULL
 };
 
+int idefloppy_reinit (ide_drive_t *drive)
+{
+	idefloppy_floppy_t *floppy;
+	int failed = 0;
+
+	MOD_INC_USE_COUNT;
+	while ((drive = ide_scan_devices (ide_floppy, idefloppy_driver.name, NULL, failed++)) != NULL) {
+		if (!idefloppy_identify_device (drive, drive->id)) {
+			printk (KERN_ERR "ide-floppy: %s: not supported by this version of ide-floppy\n", drive->name);
+			continue;
+		}
+		if (drive->scsi) {
+			printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
+			continue;
+		}
+		if ((floppy = (idefloppy_floppy_t *) kmalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
+			printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
+			continue;
+		}
+		if (ide_register_subdriver (drive, &idefloppy_driver, IDE_SUBDRIVER_VERSION)) {
+			printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name);
+			kfree (floppy);
+			continue;
+		}
+		DRIVER(drive)->busy++;
+		idefloppy_setup (drive, floppy);
+		DRIVER(drive)->busy--;
+		failed--;
+	}
+	ide_register_module(&idefloppy_module);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
 MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
 
 static void __exit idefloppy_exit (void)
@@ -2108,7 +2213,9 @@
 			kfree (floppy);
 			continue;
 		}
+		DRIVER(drive)->busy++;
 		idefloppy_setup (drive, floppy);
+		DRIVER(drive)->busy--;
 		failed--;
 	}
 	ide_register_module(&idefloppy_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-geometry.c linux/drivers/ide/ide-geometry.c
--- linux.orig/drivers/ide/ide-geometry.c	2001-11-09 22:23:34.000000000 +0000
+++ linux/drivers/ide/ide-geometry.c	2002-07-20 01:08:22.000000000 +0000
@@ -6,6 +6,8 @@
 #include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
+#ifdef CONFIG_BLK_DEV_IDE
+
 /*
  * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc
  * controller that is BIOS compatible with ST-506, and thus showing up in our
@@ -40,7 +42,11 @@
  * Consequently, also the former "drive->present = 1" below was a mistake.
  *
  * Eventually the entire routine below should be removed.
+ *
+ * 17-OCT-2000 rjohnson@analogic.com Added spin-locks for reading CMOS
+ * chip.
  */
+
 void probe_cmos_for_drives (ide_hwif_t *hwif)
 {
 #ifdef __i386__
@@ -80,9 +86,10 @@
 	}
 #endif
 }
+#endif /* CONFIG_BLK_DEV_IDE */
 
 
-#ifdef CONFIG_BLK_DEV_IDE
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
 
 extern ide_drive_t * get_info_ptr(kdev_t);
 extern unsigned long current_capacity (ide_drive_t *);
@@ -214,4 +221,4 @@
 		       drive->bios_cyl, drive->bios_head, drive->bios_sect);
 	return ret;
 }
-#endif /* CONFIG_BLK_DEV_IDE */
+#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux.orig/drivers/ide/ide-pci.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/ide/ide-pci.c	2002-07-20 01:08:39.000000000 +0000
@@ -30,14 +30,17 @@
 #define DEVID_MPIIX	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82371MX})
 #define DEVID_PIIX3	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82371SB_1})
 #define DEVID_PIIX4	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82371AB})
-#define DEVID_PIIX4E	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801AB_1})
+#define DEVID_ICH0	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801AB_1})
 #define DEVID_PIIX4E2	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82443MX_1})
-#define DEVID_PIIX4U	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801AA_1})
+#define DEVID_ICH	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801AA_1})
 #define DEVID_PIIX4U2	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82372FB_1})
 #define DEVID_PIIX4NX	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82451NX})
-#define DEVID_PIIX4U3	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_9})
-#define DEVID_PIIX4U4	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_8})
-#define DEVID_PIIX4U5	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801CA_10})
+#define DEVID_ICH2	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_9})
+#define DEVID_ICH2M	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_8})
+#define DEVID_ICH3M	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801CA_10})
+#define DEVID_ICH3	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801CA_11})
+#define DEVID_ICH4	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801DB_11})
+#define DEVID_CICH	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801E_11})
 #define DEVID_VIA_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C561})
 #define DEVID_MR_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C576_1})
 #define DEVID_VP_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C586_1})
@@ -46,7 +49,10 @@
 #define DEVID_PDC20265	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265})
 #define DEVID_PDC20267	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267})
 #define DEVID_PDC20268  ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268})
-#define DEVID_PDC20268R ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R})
+#define DEVID_PDC20270  ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270})
+#define DEVID_PDC20269	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269})
+#define DEVID_PDC20275	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275})
+#define DEVID_PDC20276	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276})
 #define DEVID_RZ1000	((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_RZ1000})
 #define DEVID_RZ1001	((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_RZ1001})
 #define DEVID_SAMURAI	((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_SAMURAI_IDE})
@@ -55,6 +61,7 @@
 #define DEVID_CMD646	((ide_pci_devid_t){PCI_VENDOR_ID_CMD,     PCI_DEVICE_ID_CMD_646})
 #define DEVID_CMD648	((ide_pci_devid_t){PCI_VENDOR_ID_CMD,     PCI_DEVICE_ID_CMD_648})
 #define DEVID_CMD649	((ide_pci_devid_t){PCI_VENDOR_ID_CMD,     PCI_DEVICE_ID_CMD_649})
+#define DEVID_CMD680	((ide_pci_devid_t){PCI_VENDOR_ID_CMD,     PCI_DEVICE_ID_CMD_680})
 #define DEVID_SIS5513	((ide_pci_devid_t){PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_5513})
 #define DEVID_OPTI621	((ide_pci_devid_t){PCI_VENDOR_ID_OPTI,    PCI_DEVICE_ID_OPTI_82C621})
 #define DEVID_OPTI621V	((ide_pci_devid_t){PCI_VENDOR_ID_OPTI,    PCI_DEVICE_ID_OPTI_82C558})
@@ -79,6 +86,7 @@
 #define DEVID_AMD7401	((ide_pci_devid_t){PCI_VENDOR_ID_AMD,     PCI_DEVICE_ID_AMD_COBRA_7401})
 #define DEVID_AMD7409	((ide_pci_devid_t){PCI_VENDOR_ID_AMD,     PCI_DEVICE_ID_AMD_VIPER_7409})
 #define DEVID_AMD7411	((ide_pci_devid_t){PCI_VENDOR_ID_AMD,     PCI_DEVICE_ID_AMD_VIPER_7411})
+#define DEVID_AMD7441	((ide_pci_devid_t){PCI_VENDOR_ID_AMD,     PCI_DEVICE_ID_AMD_VIPER_7441})
 #define DEVID_PDCADMA	((ide_pci_devid_t){PCI_VENDOR_ID_PDC,     PCI_DEVICE_ID_PDC_1841})
 #define DEVID_SLC90E66	((ide_pci_devid_t){PCI_VENDOR_ID_EFAR,    PCI_DEVICE_ID_EFAR_SLC90E66_1})
 #define DEVID_OSB4	((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE})
@@ -86,6 +94,7 @@
 #define DEVID_ITE8172G	((ide_pci_devid_t){PCI_VENDOR_ID_ITE,     PCI_DEVICE_ID_ITE_IT8172G})
 
 #define	IDE_IGNORE	((void *)-1)
+#define IDE_NO_DRIVER	((void *)-2)
 
 #ifdef CONFIG_BLK_DEV_AEC62XX
 extern unsigned int pci_init_aec62xx(struct pci_dev *, const char *);
@@ -99,7 +108,7 @@
 #else
 #define PCI_AEC62XX	NULL
 #define ATA66_AEC62XX	NULL
-#define INIT_AEC62XX	NULL
+#define INIT_AEC62XX	IDE_NO_DRIVER
 #define DMA_AEC62XX	NULL
 #endif
 
@@ -115,7 +124,7 @@
 #else
 #define PCI_ALI15X3	NULL
 #define ATA66_ALI15X3	NULL
-#define INIT_ALI15X3	NULL
+#define INIT_ALI15X3	IDE_NO_DRIVER
 #define DMA_ALI15X3	NULL
 #endif
 
@@ -131,7 +140,7 @@
 #else
 #define PCI_AMD74XX	NULL
 #define ATA66_AMD74XX	NULL
-#define INIT_AMD74XX	NULL
+#define INIT_AMD74XX	IDE_NO_DRIVER
 #define DMA_AMD74XX	NULL
 #endif
 
@@ -149,7 +158,7 @@
 #ifdef __sparc_v9__
 #define INIT_CMD64X	IDE_IGNORE
 #else
-#define INIT_CMD64X	NULL
+#define INIT_CMD64X	IDE_NO_DRIVER
 #endif
 #endif
 
@@ -160,7 +169,7 @@
 #define INIT_CY82C693	&ide_init_cy82c693
 #else
 #define PCI_CY82C693	NULL
-#define INIT_CY82C693	NULL
+#define INIT_CY82C693	IDE_NO_DRIVER
 #endif
 
 #ifdef CONFIG_BLK_DEV_CS5530
@@ -170,7 +179,7 @@
 #define INIT_CS5530	&ide_init_cs5530
 #else
 #define PCI_CS5530	NULL
-#define INIT_CS5530	NULL
+#define INIT_CS5530	IDE_NO_DRIVER
 #endif
 
 #ifdef CONFIG_BLK_DEV_HPT34X
@@ -199,7 +208,7 @@
 static byte hpt363_shared_pin;
 #define PCI_HPT366	NULL
 #define ATA66_HPT366	NULL
-#define INIT_HPT366	NULL
+#define INIT_HPT366	IDE_NO_DRIVER
 #define DMA_HPT366	NULL
 #endif
 
@@ -214,7 +223,7 @@
 extern void ide_init_opti621(ide_hwif_t *);
 #define INIT_OPTI621	&ide_init_opti621
 #else
-#define INIT_OPTI621	NULL
+#define INIT_OPTI621	IDE_NO_DRIVER
 #endif
 
 #ifdef CONFIG_BLK_DEV_PDC_ADMA
@@ -256,7 +265,7 @@
 #else
 #define PCI_PIIX	NULL
 #define ATA66_PIIX	NULL
-#define INIT_PIIX	NULL
+#define INIT_PIIX	IDE_NO_DRIVER
 #endif
 
 #ifdef CONFIG_BLK_DEV_IT8172
@@ -290,7 +299,7 @@
 #else
 #define PCI_SVWKS	NULL
 #define ATA66_SVWKS	NULL
-#define INIT_SVWKS	NULL
+#define INIT_SVWKS	IDE_NO_DRIVER
 #endif
 
 #ifdef CONFIG_BLK_DEV_SIS5513
@@ -303,7 +312,7 @@
 #else
 #define PCI_SIS5513	NULL
 #define ATA66_SIS5513	NULL
-#define INIT_SIS5513	NULL
+#define INIT_SIS5513	IDE_NO_DRIVER
 #endif
 
 #ifdef CONFIG_BLK_DEV_SLC90E66
@@ -316,7 +325,7 @@
 #else
 #define PCI_SLC90E66	NULL
 #define ATA66_SLC90E66	NULL
-#define INIT_SLC90E66	NULL
+#define INIT_SLC90E66	IDE_NO_DRIVER
 #endif
 
 #ifdef CONFIG_BLK_DEV_SL82C105
@@ -351,7 +360,7 @@
 #else
 #define PCI_VIA82CXXX	NULL
 #define ATA66_VIA82CXXX	NULL
-#define INIT_VIA82CXXX	NULL
+#define INIT_VIA82CXXX	IDE_NO_DRIVER
 #define DMA_VIA82CXXX	NULL
 #endif
 
@@ -379,21 +388,24 @@
 	{DEVID_MPIIX,	"MPIIX",	NULL,		NULL,		INIT_PIIX,	NULL,		{{0x6D,0x80,0x80}, {0x6F,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_PIIX3,	"PIIX3",	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
 	{DEVID_PIIX4,	"PIIX4",	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}}, 	ON_BOARD,	0 },
-	{DEVID_PIIX4E,	"PIIX4",	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_ICH0,	"ICH0", 	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_PIIX4E2,	"PIIX4",	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
-	{DEVID_PIIX4U,	"PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_ICH,	"ICH",  	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_PIIX4U2,	"PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_PIIX4NX,	"PIIX4",	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
-	{DEVID_PIIX4U3,	"PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
-	{DEVID_PIIX4U4, "PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
-	{DEVID_PIIX4U5, "PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_ICH2,	"ICH2", 	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_ICH2M,	"ICH2M",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_ICH3M,	"ICH3M",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_ICH3,	"ICH3", 	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_ICH4,	"ICH4", 	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_CICH,	"C-ICH",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_VIA_IDE,	"VIA_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_MR_IDE,	"VP_IDE",	PCI_VIA82CXXX,	ATA66_VIA82CXXX,INIT_VIA82CXXX,	DMA_VIA82CXXX,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	ON_BOARD,	0 },
 	{DEVID_VP_IDE,	"VP_IDE",	PCI_VIA82CXXX,	ATA66_VIA82CXXX,INIT_VIA82CXXX,	DMA_VIA82CXXX,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	ON_BOARD,	0 },
 #ifdef CONFIG_PDC202XX_FORCE
         {DEVID_PDC20246,"PDC20246",	PCI_PDC202XX,	NULL,		INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
         {DEVID_PDC20262,"PDC20262",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	48 },
-        {DEVID_PDC20265,"PDC20265",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	48 },
+        {DEVID_PDC20265,"PDC20265",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	48 },
         {DEVID_PDC20267,"PDC20267",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	48 },
 #else /* !CONFIG_PDC202XX_FORCE */
 	{DEVID_PDC20246,"PDC20246",	PCI_PDC202XX,	NULL,		INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}}, 	OFF_BOARD,	16 },
@@ -401,11 +413,14 @@
 	{DEVID_PDC20265,"PDC20265",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}},	OFF_BOARD,	48 },
 	{DEVID_PDC20267,"PDC20267",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}},	OFF_BOARD,	48 },
 #endif
-	{DEVID_PDC20268,"PDC20268",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
+	{DEVID_PDC20268,"PDC20268",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
 	/* Promise used a different PCI ident for the raid card apparently to try and
 	   prevent Linux detecting it and using our own raid code. We want to detect
 	   it for the ataraid drivers, so we have to list both here.. */
-	{DEVID_PDC20268R,"PDC20268",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
+	{DEVID_PDC20270,"PDC20270",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
+	{DEVID_PDC20269,"PDC20269",	PCI_PDC202XX,	ATA66_PDC202XX,	 INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
+	{DEVID_PDC20275,"PDC20275",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
+	{DEVID_PDC20276,"PDC20276",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
 	{DEVID_RZ1000,	"RZ1000",	NULL,		NULL,		INIT_RZ1000,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
 	{DEVID_RZ1001,	"RZ1001",	NULL,		NULL,		INIT_RZ1000,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
 	{DEVID_SAMURAI,	"SAMURAI",	NULL,		NULL,		INIT_SAMURAI,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
@@ -416,6 +431,11 @@
 	{DEVID_CMD646,	"CMD646",	PCI_CMD64X,	NULL,		INIT_CMD64X,	NULL,		{{0x00,0x00,0x00}, {0x51,0x80,0x80}}, 	ON_BOARD,	0 },
 	{DEVID_CMD648,	"CMD648",	PCI_CMD64X,	ATA66_CMD64X,	INIT_CMD64X,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_CMD649,	"CMD649",	PCI_CMD64X,	ATA66_CMD64X,	INIT_CMD64X,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
+#ifndef CONFIG_BLK_DEV_CMD680
+	{DEVID_CMD680,	"CMD680",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
+#else /* CONFIG_BLK_DEV_CMD680 */
+	{DEVID_CMD680,	"CMD680",	PCI_CMD64X,	ATA66_CMD64X,	INIT_CMD64X,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
+#endif /* !CONFIG_BLK_DEV_CMD680 */
 	{DEVID_HT6565,	"HT6565",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
 	{DEVID_OPTI621,	"OPTI621",	NULL,		NULL,		INIT_OPTI621,	NULL,		{{0x45,0x80,0x00}, {0x40,0x08,0x00}}, 	ON_BOARD,	0 },
 	{DEVID_OPTI621X,"OPTI621X",	NULL,		NULL,		INIT_OPTI621,	NULL,		{{0x45,0x80,0x00}, {0x40,0x08,0x00}}, 	ON_BOARD,	0 },
@@ -434,9 +454,10 @@
 	{DEVID_CY82C693,"CY82C693",	PCI_CY82C693,	NULL,		INIT_CY82C693,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_HINT,	"HINT_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_CS5530,	"CS5530",	PCI_CS5530,	NULL,		INIT_CS5530,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_AMD7401,	"AMD7401",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
+	{DEVID_AMD7401,	"AMD7401",	NULL,		NULL,		NULL,		DMA_AMD74XX,	{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
 	{DEVID_AMD7409,	"AMD7409",	PCI_AMD74XX,	ATA66_AMD74XX,	INIT_AMD74XX,	DMA_AMD74XX,	{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
 	{DEVID_AMD7411,	"AMD7411",	PCI_AMD74XX,	ATA66_AMD74XX,	INIT_AMD74XX,	DMA_AMD74XX,	{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
+	{DEVID_AMD7441,	"AMD7441",	PCI_AMD74XX,	ATA66_AMD74XX,	INIT_AMD74XX,	DMA_AMD74XX,	{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
 	{DEVID_PDCADMA,	"PDCADMA",	PCI_PDCADMA,	ATA66_PDCADMA,	INIT_PDCADMA,	DMA_PDCADMA,	{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
 	{DEVID_SLC90E66,"SLC90E66",	PCI_SLC90E66,	ATA66_SLC90E66,	INIT_SLC90E66,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
         {DEVID_OSB4,    "ServerWorks OSB4",		PCI_SVWKS,	ATA66_SVWKS,	INIT_SVWKS,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
@@ -458,6 +479,10 @@
 		case PCI_DEVICE_ID_PROMISE_20265:
 		case PCI_DEVICE_ID_PROMISE_20267:
 		case PCI_DEVICE_ID_PROMISE_20268:
+		case PCI_DEVICE_ID_PROMISE_20270:
+		case PCI_DEVICE_ID_PROMISE_20269:
+		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_ARTOP_ATP850UF:
 		case PCI_DEVICE_ID_ARTOP_ATP860:
 		case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -592,7 +617,15 @@
 		autodma = 1;
 #endif
 
-	pci_enable_device(dev);
+	if (d->init_hwif == IDE_NO_DRIVER) {
+		printk(KERN_WARNING "%s: detected chipset, but driver not compiled in!\n", d->name);
+		d->init_hwif = NULL;
+	}
+
+	if (pci_enable_device(dev)) {
+		printk(KERN_WARNING "%s: (ide_setup_pci_device:) Could not enable device.\n", d->name);
+		return;
+	}
 
 check_if_enabled:
 	if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) {
@@ -636,25 +669,18 @@
 	 */
 	pciirq = dev->irq;
 	
-	if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID)
-	{
-		/* By rights we want to ignore these, but the Promise Fastrak
-		   people have some strange ideas about proprietary so we have
-		   to act otherwise on those. The supertrak however we need
-		   to skip */
-		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265))
-		{
-			printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n");
-			if(dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_INTEL &&
-				dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960)
-			{
-				printk(KERN_INFO "ide: Skipping Promise PDC20265 attached to I2O RAID controller.\n");
-				return;
-			}
+#ifndef CONFIG_PDC202XX_FORCE
+	if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) {
+		/*
+		 * By rights we want to ignore Promise FastTrak and SuperTrak
+		 * series here, those use own driver.
+		 */
+		if (dev->vendor == PCI_VENDOR_ID_PROMISE) {
+			printk(KERN_INFO "ide: Skipping Promise RAID controller.\n");
+			return;
 		}
-		/* Its attached to something else, just a random bridge. 
-		   Suspect a fastrak and fall through */
 	}
+#endif /* CONFIG_PDC202XX_FORCE */
 	if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {
 		printk("%s: not 100%% native mode: will probe irqs later\n", d->name);
 		/*
@@ -752,7 +778,8 @@
 		}
 		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_MPIIX))
 			goto bypass_piix_dma;
-
+		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDCADMA))
+			goto bypass_legacy_dma;
 		if (hwif->udma_four) {
 			printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", d->name);
 		} else {
@@ -769,12 +796,16 @@
 			autodma = 0;
 		if (autodma)
 			hwif->autodma = 1;
+
 		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268) ||
-		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20270) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20269) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20275) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20276) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) ||
@@ -785,6 +816,7 @@
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD648) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD649) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD680) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_OSB4) ||
 		    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) {
 			unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name);
@@ -811,6 +843,7 @@
 			}
 		}
 #endif	/* CONFIG_BLK_DEV_IDEDMA */
+bypass_legacy_dma:
 bypass_piix_dma:
 bypass_umc_dma:
 		if (d->init_hwif)  /* Call chipset-specific routine for each enabled hwif */
@@ -822,20 +855,60 @@
 		printk("%s: neither IDE port enabled (BIOS)\n", d->name);
 }
 
+static void __init pdc20270_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d)
+{
+	struct pci_dev *dev2 = NULL, *findev;
+	ide_pci_device_t *d2;
+
+	if ((dev->bus->self &&
+	     dev->bus->self->vendor == PCI_VENDOR_ID_DEC) &&
+	    (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) {
+		if (PCI_SLOT(dev->devfn) & 2) {
+			return;
+		}
+		d->extra = 0;
+		pci_for_each_dev(findev) {
+			if ((findev->vendor == dev->vendor) &&
+			    (findev->device == dev->device) &&
+			    (PCI_SLOT(findev->devfn) & 2)) {
+				byte irq = 0, irq2 = 0;
+				dev2 = findev;
+				pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+				pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2);
+                                if (irq != irq2) {
+					dev2->irq = dev->irq;
+                                        pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, irq);
+                                }
+
+			}
+		}
+	}
+
+	printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
+	ide_setup_pci_device(dev, d);
+	if (!dev2)
+		return;
+	d2 = d;
+	printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn);
+	ide_setup_pci_device(dev2, d2);
+}
+
 static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d)
 {
 	struct pci_dev *dev2 = NULL, *findev;
 	ide_pci_device_t *d2;
 	unsigned char pin1 = 0, pin2 = 0;
 	unsigned int class_rev;
-	char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"};
+	char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A", "HPT372"};
 
 	if (PCI_FUNC(dev->devfn) & 1)
 		return;
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
-
+	if (class_rev > 5)
+		class_rev = 5;
+	
 	strcpy(d->name, chipset_names[class_rev]);
 
 	switch(class_rev) {
@@ -902,6 +975,8 @@
 		return;	/* UM8886A/BF pair */
 	else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366))
 		hpt366_device_order_fixup(dev, d);
+	else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20270))
+		pdc20270_device_order_fixup(dev, d);
 	else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 		if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL))
 			printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux.orig/drivers/ide/ide-pmac.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/ide/ide-pmac.c	2002-07-20 01:08:27.000000000 +0000
@@ -26,11 +26,14 @@
 #include <linux/ide.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+#include <linux/pci.h>
+
 #include <asm/prom.h>
 #include <asm/io.h>
 #include <asm/dbdma.h>
 #include <asm/ide.h>
 #include <asm/mediabay.h>
+#include <asm/pci-bridge.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
 #include <asm/sections.h>
@@ -55,11 +58,18 @@
 	int				aapl_bus_id;
 	struct device_node*		node;
 	u32				timings[2];
-	struct resource*		reg_resource;
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+	/* Those fields are duplicating what is in hwif. We currently
+	 * can't use the hwif ones because of some assumptions that are
+	 * beeing done by the generic code about the kind of dma controller
+	 * and format of the dma table. This will have to be fixed though.
+	 */
 	volatile struct dbdma_regs*	dma_regs;
-	struct dbdma_cmd*		dma_table;
-	struct resource*		dma_resource;
+	struct dbdma_cmd*		dma_table_cpu;
+	dma_addr_t			dma_table_dma;
+	struct scatterlist*		sg_table;
+	int				sg_nents;
+	int				sg_dma_direction;
 #endif
 	
 } pmac_ide[MAX_HWIFS] __pmacdata;
@@ -308,7 +318,7 @@
 	ide_hwifs[ix].tuneproc = pmac_ide_tuneproc;
 	ide_hwifs[ix].selectproc = pmac_ide_selectproc;
 	ide_hwifs[ix].speedproc = &pmac_ide_tune_chipset;
-	if (pmac_ide[ix].dma_regs && pmac_ide[ix].dma_table) {
+	if (pmac_ide[ix].dma_regs && pmac_ide[ix].dma_table_cpu) {
 		ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO
 		if (!noautodma)
@@ -823,6 +833,8 @@
 		struct pmac_ide_hwif* pmhw;
 		int *bidp;
 		int in_bay = 0;
+		u8 pbus, pid;
+		struct pci_dev *pdev = NULL;
 
 		/*
 		 * If this node is not under a mac-io or dbdma node,
@@ -841,6 +853,15 @@
 			continue;
 		}
 
+		/* We need to find the pci_dev of the mac-io holding the
+		 * IDE interface
+		 */
+		if (pci_device_from_OF_node(tp, &pbus, &pid) == 0)
+			pdev = pci_find_slot(pbus, pid);
+		if (pdev == NULL)
+			printk(KERN_WARNING "ide: no PCI host for device %s, DMA disabled\n",
+			       np->full_name);
+
 		/*
 		 * If this slot is taken (e.g. by ide-pci.c) try the next one.
 		 */
@@ -860,8 +881,7 @@
 		if (np->n_addrs > 1 && np->addrs[1].size > 0x100)
 			np->addrs[1].size = 0x100;
 
-		pmhw->reg_resource = request_OF_resource(np, 0, "  (mac-io IDE IO)");
-		if (!pmhw->reg_resource) {
+		if (request_OF_resource(np, 0, "  (mac-io IDE IO)") == NULL) {
 			printk(KERN_ERR "ide-pmac(%s): can't request IO resource !\n", np->name);
 			continue;
 		}
@@ -935,6 +955,7 @@
 		hwif->chipset = ide_pmac;
 		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay;
 		hwif->udma_four = (pmhw->kind == controller_kl_ata4_80);
+		hwif->pci_dev = pdev;
 #ifdef CONFIG_PMAC_PBOOK
 		if (in_bay && check_media_bay_by_base(base, MB_CD) == 0)
 			hwif->noprobe = 0;
@@ -964,13 +985,14 @@
 static void __init 
 pmac_ide_setup_dma(struct device_node *np, int ix)
 {
-	pmac_ide[ix].dma_resource = request_OF_resource(np, 1, " (mac-io IDE DMA)");
-	if (!pmac_ide[ix].dma_resource) {
+	struct pmac_ide_hwif *pmif = &pmac_ide[ix];
+
+	if (request_OF_resource(np, 1, " (mac-io IDE DMA)") == NULL) {
 		printk(KERN_ERR "ide-pmac(%s): can't request DMA resource !\n", np->name);
 		return;
 	}
 
-	pmac_ide[ix].dma_regs =
+	pmif->dma_regs =
 		(volatile struct dbdma_regs*)ioremap(np->addrs[1].address, 0x200);
 
 	/*
@@ -978,14 +1000,24 @@
 	 * The +2 is +1 for the stop command and +1 to allow for
 	 * aligning the start address to a multiple of 16 bytes.
 	 */
-	pmac_ide[ix].dma_table = (struct dbdma_cmd*)
-	       kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL);
-	if (pmac_ide[ix].dma_table == 0) {
+	pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent(
+		ide_hwifs[ix].pci_dev,
+		(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
+		&pmif->dma_table_dma);
+	if (pmif->dma_table_cpu == NULL) {
 		printk(KERN_ERR "%s: unable to allocate DMA command list\n",
 		       ide_hwifs[ix].name);
 		return;
 	}
 
+	pmif->sg_table = kmalloc(sizeof(struct scatterlist) * MAX_DCMDS,
+				 GFP_KERNEL);
+	if (pmif->sg_table == NULL) {
+		pci_free_consistent(	ide_hwifs[ix].pci_dev,
+					(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
+				    	pmif->dma_table_cpu, pmif->dma_table_dma);
+		return;
+	}
 	ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO
 	if (!noautodma)
@@ -993,65 +1025,118 @@
 #endif
 }
 
+static int
+pmac_ide_build_sglist (int ix, struct request *rq)
+{
+	ide_hwif_t *hwif = &ide_hwifs[ix];
+	struct pmac_ide_hwif *pmif = &pmac_ide[ix];
+	struct buffer_head *bh;
+	struct scatterlist *sg = pmif->sg_table;
+	int nents = 0;
+
+	if (hwif->sg_dma_active)
+		BUG();
+		
+	if (rq->cmd == READ)
+		pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
+	else
+		pmif->sg_dma_direction = PCI_DMA_TODEVICE;
+	bh = rq->bh;
+	do {
+		unsigned char *virt_addr = bh->b_data;
+		unsigned int size = bh->b_size;
+
+		if (nents >= MAX_DCMDS)
+			return 0;
+
+		while ((bh = bh->b_reqnext) != NULL) {
+			if ((virt_addr + size) != (unsigned char *) bh->b_data)
+				break;
+			size += bh->b_size;
+		}
+		memset(&sg[nents], 0, sizeof(*sg));
+		sg[nents].address = virt_addr;
+		sg[nents].length = size;
+		nents++;
+	} while (bh != NULL);
+
+	return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
+}
+
+static int
+pmac_ide_raw_build_sglist (int ix, struct request *rq)
+{
+	ide_hwif_t *hwif = &ide_hwifs[ix];
+	struct pmac_ide_hwif *pmif = &pmac_ide[ix];
+	struct scatterlist *sg = hwif->sg_table;
+	int nents = 0;
+	ide_task_t *args = rq->special;
+	unsigned char *virt_addr = rq->buffer;
+	int sector_count = rq->nr_sectors;
+
+//	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_WRITEDMA) ||
+//	    (args->tfRegister[IDE_COMMAND_OFFSET] == WIN_WRITEDMA_EXT))
+	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
+		pmif->sg_dma_direction = PCI_DMA_TODEVICE;
+	else
+		pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
+	
+	if (sector_count > 128) {
+		memset(&sg[nents], 0, sizeof(*sg));
+		sg[nents].address = virt_addr;
+		sg[nents].length = 128  * SECTOR_SIZE;
+		nents++;
+		virt_addr = virt_addr + (128 * SECTOR_SIZE);
+		sector_count -= 128;
+	}
+	memset(&sg[nents], 0, sizeof(*sg));
+	sg[nents].address = virt_addr;
+	sg[nents].length =  sector_count  * SECTOR_SIZE;
+	nents++;
+   
+	return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
+}
+
 /*
  * pmac_ide_build_dmatable builds the DBDMA command list
  * for a transfer and sets the DBDMA channel to point to it.
  */
-static int __pmac
+static int
 pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr)
 {
-	struct dbdma_cmd *table, *tstart;
-	int count = 0;
+	struct dbdma_cmd *table;
+	int i, count = 0;
 	struct request *rq = HWGROUP(drive)->rq;
-	struct buffer_head *bh = rq->bh;
-	unsigned int size, addr;
 	volatile struct dbdma_regs *dma = pmac_ide[ix].dma_regs;
+	struct scatterlist *sg;
 
-	table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(pmac_ide[ix].dma_table);
+	/* DMA table is already aligned */
+	table = (struct dbdma_cmd *) pmac_ide[ix].dma_table_cpu;
 
-#ifdef IDE_PMAC_DEBUG
-	if (in_le32(&dma->status) & (RUN|ACTIVE))
-		printk("ide-pmac: channel status not stopped ! (%x)\n",
-			in_le32(&dma->status));
-#endif	
-	/* Make sure channel is stopped and all error conditions are clear */
+	/* Make sure DMA controller is stopped (necessary ?) */
 	out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
 	while (in_le32(&dma->status) & RUN)
 		udelay(1);
 
-	do {
-		/*
-		 * Determine addr and size of next buffer area.  We assume that
-		 * individual virtual buffers are always composed linearly in
-		 * physical memory.  For example, we assume that any 8kB buffer
-		 * is always composed of two adjacent physical 4kB pages rather
-		 * than two possibly non-adjacent physical 4kB pages.
-		 */
-		if (bh == NULL) {  /* paging requests have (rq->bh == NULL) */
-			addr = virt_to_bus(rq->buffer);
-			size = rq->nr_sectors << 9;
-		} else {
-			/* group sequential buffers into one large buffer */
-			addr = virt_to_bus(bh->b_data);
-			size = bh->b_size;
-			while ((bh = bh->b_reqnext) != NULL) {
-				if ((addr + size) != virt_to_bus(bh->b_data))
-					break;
-				size += bh->b_size;
-			}
-		}
+	/* Build sglist */
+	if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE)
+		pmac_ide[ix].sg_nents = i = pmac_ide_raw_build_sglist(ix, rq);
+	else
+		pmac_ide[ix].sg_nents = i = pmac_ide_build_sglist(ix, rq);
+	if (!i)
+		return 0;
 
-		/*
-		 * Fill in the next DBDMA command block.
-		 * Note that one DBDMA command can transfer
-		 * at most 65535 bytes.
-		 */
-#ifdef IDE_PMAC_DEBUG
-		if (size & 0x01)
-			printk("ide-pmac: odd size transfer ! (%d)\n", size);
-#endif			
-		while (size) {
-			unsigned int tc = (size < 0xfe00)? size: 0xfe00;
+	/* Build DBDMA commands list */
+	sg = pmac_ide[ix].sg_table;
+	while (i) {
+		u32 cur_addr;
+		u32 cur_len;
+
+		cur_addr = sg_dma_address(sg);
+		cur_len = sg_dma_len(sg);
+
+		while (cur_len) {
+			unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
 
 			if (++count >= MAX_DCMDS) {
 				printk(KERN_WARNING "%s: DMA table too small\n",
@@ -1060,15 +1145,17 @@
 			}
 			st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
 			st_le16(&table->req_count, tc);
-			st_le32(&table->phy_addr, addr);
+			st_le32(&table->phy_addr, cur_addr);
 			table->cmd_dep = 0;
 			table->xfer_status = 0;
 			table->res_count = 0;
-			addr += tc;
-			size -= tc;
+			cur_addr += tc;
+			cur_len -= tc;
 			++table;
 		}
-	} while (bh != NULL);
+		sg++;
+		i--;
+	}
 
 	/* convert the last command to an input/output last command */
 	if (count)
@@ -1080,10 +1167,23 @@
 	memset(table, 0, sizeof(struct dbdma_cmd));
 	out_le16(&table->command, DBDMA_STOP);
 
-	out_le32(&dma->cmdptr, virt_to_bus(tstart));
+	out_le32(&dma->cmdptr, pmac_ide[ix].dma_table_dma);
 	return 1;
 }
 
+/* Teardown mappings after DMA has completed.  */
+static void
+pmac_ide_destroy_dmatable (ide_drive_t *drive, int ix)
+{
+	struct pci_dev *dev = HWIF(drive)->pci_dev;
+	struct scatterlist *sg = pmac_ide[ix].sg_table;
+	int nents = pmac_ide[ix].sg_nents;
+
+	if (nents) {
+		pci_unmap_sg(dev, sg, nents, pmac_ide[ix].sg_dma_direction);
+		pmac_ide[ix].sg_nents = 0;
+	}
+}
 
 static __inline__ unsigned char
 dma_bits_to_command(unsigned char bits)
@@ -1237,6 +1337,7 @@
 	volatile struct dbdma_regs *dma;
 	byte unit = (drive->select.b.unit & 0x01);
 	byte ata4;
+	int reading = 0;
 
 	/* Can we stuff a pointer to our intf structure in config_data
 	 * or select_data in hwif ?
@@ -1259,22 +1360,31 @@
 		pmac_ide_check_dma(drive);
 		break;
 	case ide_dma_read:
+		reading = 1;
 	case ide_dma_write:
-		if (!pmac_ide_build_dmatable(drive, ix, func==ide_dma_write))
+		SELECT_READ_WRITE(HWIF(drive),drive,func);
+		if (!pmac_ide_build_dmatable(drive, ix, !reading))
 			return 1;
 		/* Apple adds 60ns to wrDataSetup on reads */
 		if (ata4 && (pmac_ide[ix].timings[unit] & TR_66_UDMA_EN)) {
 			out_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE),
 				pmac_ide[ix].timings[unit] + 
-				((func == ide_dma_read) ? 0x00800000UL : 0));
+				(reading ? 0x00800000UL : 0));
 			(void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE));
 		}
 		drive->waiting_for_dma = 1;
 		if (drive->media != ide_disk)
 			return 0;
 		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
-		OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
-			 IDE_COMMAND_REG);
+		if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+		    (drive->addressing == 1)) {
+			ide_task_t *args = HWGROUP(drive)->rq->special;
+			OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+		} else if (drive->addressing) {
+			OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+		} else {
+			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+		}
 	case ide_dma_begin:
 		out_le32(&dma->control, (RUN << 16) | RUN);
 		/* Make sure it gets to the controller right now */
@@ -1284,6 +1394,7 @@
 		drive->waiting_for_dma = 0;
 		dstat = in_le32(&dma->status);
 		out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
+		pmac_ide_destroy_dmatable(drive, ix);
 		/* verify good dma status */
 		return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
 	case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux.orig/drivers/ide/ide-probe.c	2001-11-26 13:29:17.000000000 +0000
+++ linux/drivers/ide/ide-probe.c	2002-07-20 01:08:21.000000000 +0000
@@ -58,6 +58,11 @@
 	struct hd_driveid *id;
 
 	id = drive->id = kmalloc (SECTOR_WORDS*4, GFP_ATOMIC);	/* called with interrupts disabled! */
+	if (!id) {
+		printk(KERN_WARNING "(ide-probe::do_identify) Out of memory.\n");
+		goto err_kmalloc;
+	}
+
 	ide_input_data(drive, id, SECTOR_WORDS);		/* read 512 bytes of id info */
 	ide__sti();	/* local CPU only */
 	ide_fix_driveid(id);
@@ -76,8 +81,7 @@
 	if ((id->model[0] == 'P' && id->model[1] == 'M')
 	 || (id->model[0] == 'S' && id->model[1] == 'K')) {
 		printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model);
-		drive->present = 0;
-		return;
+		goto err_misc;
 	}
 #endif /* CONFIG_SCSI_EATA_DMA || CONFIG_SCSI_EATA_PIO */
 
@@ -96,7 +100,7 @@
 	ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap);
 
 	if (strstr(id->model, "E X A B Y T E N E S T"))
-		return;
+		goto err_misc;
 
 	id->model[sizeof(id->model)-1] = '\0';	/* we depend on this a lot! */
 	printk("%s: %s, ", drive->name, id->model);
@@ -111,8 +115,7 @@
 #ifdef CONFIG_BLK_DEV_PDC4030
 		if (HWIF(drive)->channel == 1 && HWIF(drive)->chipset == ide_pdc4030) {
 			printk(" -- not supported on 2nd Promise port\n");
-			drive->present = 0;
-			return;
+			goto err_misc;
 		}
 #endif /* CONFIG_BLK_DEV_PDC4030 */
 		switch (type) {
@@ -174,6 +177,12 @@
 	printk("ATA DISK drive\n");
 	QUIRK_LIST(HWIF(drive),drive);
 	return;
+
+err_misc:
+	kfree(id);
+err_kmalloc:
+	drive->present = 0;
+	return;
 }
 
 /*
@@ -370,7 +379,7 @@
 	OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
 	timeout = jiffies + WAIT_WORSTCASE;
 	do {
-		if (jiffies > timeout) {
+		if (time_after(jiffies, timeout)) {
 			printk("failed (timeout)\n");
 			return;
 		}
@@ -597,6 +606,12 @@
 
 	q->queuedata = HWGROUP(drive);
 	blk_init_queue(q, do_ide_request);
+
+	if (drive->media == ide_disk) {
+#ifdef CONFIG_BLK_DEV_ELEVATOR_NOOP
+		elevator_init(&q->elevator, ELEVATOR_NOOP);
+#endif
+	}
 }
 
 /*
@@ -685,6 +700,10 @@
 #else /* !CONFIG_IDEPCI_SHARE_IRQ */
 		int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT;
 #endif /* CONFIG_IDEPCI_SHARE_IRQ */
+
+		if (hwif->io_ports[IDE_CONTROL_OFFSET])
+			OUT_BYTE(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]); /* clear nIEN */
+
 		if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) {
 			if (!match)
 				kfree(hwgroup);
@@ -752,18 +771,35 @@
 	int *bs, *max_sect, *max_ra;
 	extern devfs_handle_t ide_devfs_handle;
 
+#if 1
+	units = MAX_DRIVES;
+#else
 	/* figure out maximum drive number on the interface */
 	for (units = MAX_DRIVES; units > 0; --units) {
 		if (hwif->drives[units-1].present)
 			break;
 	}
+#endif
+
 	minors    = units * (1<<PARTN_BITS);
 	gd        = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
+	if (!gd)
+		goto err_kmalloc_gd;
 	gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
+	if (!gd->sizes)
+		goto err_kmalloc_gd_sizes;
 	gd->part  = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
+	if (!gd->part)
+		goto err_kmalloc_gd_part;
 	bs        = kmalloc (minors*sizeof(int), GFP_KERNEL);
+	if (!bs)
+		goto err_kmalloc_bs;
 	max_sect  = kmalloc (minors*sizeof(int), GFP_KERNEL);
+	if (!max_sect)
+		goto err_kmalloc_max_sect;
 	max_ra    = kmalloc (minors*sizeof(int), GFP_KERNEL);
+	if (!max_ra)
+		goto err_kmalloc_max_ra;
 
 	memset(gd->part, 0, minors * sizeof(struct hd_struct));
 
@@ -773,12 +809,10 @@
 	max_readahead[hwif->major] = max_ra;
 	for (unit = 0; unit < minors; ++unit) {
 		*bs++ = BLOCK_SIZE;
-#ifdef CONFIG_BLK_DEV_PDC4030
-		*max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : 255);
-#else
-		/* IDE can do up to 128K per request. */
-		*max_sect++ = 255;
-#endif
+		/*
+		 * IDE can do up to 128K per request == 256
+		 */
+		*max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : 128);
 		*max_ra++ = vm_max_readahead;
 	}
 
@@ -804,6 +838,17 @@
 	add_gendisk(gd);
 
 	for (unit = 0; unit < units; ++unit) {
+#if 1
+		char name[64];
+		ide_add_generic_settings(hwif->drives + unit);
+		hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit);
+		sprintf (name, "host%d/bus%d/target%d/lun%d",
+			(hwif->channel && hwif->mate) ?
+			hwif->mate->index : hwif->index,
+			hwif->channel, unit, hwif->drives[unit].lun);
+		if (hwif->drives[unit].present)
+			hwif->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL);
+#else
 		if (hwif->drives[unit].present) {
 			char name[64];
 
@@ -815,7 +860,23 @@
 			hwif->drives[unit].de =
 				devfs_mk_dir (ide_devfs_handle, name, NULL);
 		}
+#endif
 	}
+	return;
+
+err_kmalloc_max_ra:
+	kfree(max_sect);
+err_kmalloc_max_sect:
+	kfree(bs);
+err_kmalloc_bs:
+	kfree(gd->part);
+err_kmalloc_gd_part:
+	kfree(gd->sizes);
+err_kmalloc_gd_sizes:
+	kfree(gd);
+err_kmalloc_gd:
+	printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n");
+	return;
 }
 
 static int hwif_init (ide_hwif_t *hwif)
@@ -880,6 +941,19 @@
 	return hwif->present;
 }
 
+void export_ide_init_queue (ide_drive_t *drive)
+{
+	ide_init_queue(drive);
+}
+
+byte export_probe_for_drive (ide_drive_t *drive)
+{
+	return probe_for_drive(drive);
+}
+
+EXPORT_SYMBOL(export_ide_init_queue);
+EXPORT_SYMBOL(export_probe_for_drive);
+
 int ideprobe_init (void);
 static ide_module_t ideprobe_module = {
 	IDE_PROBE_MODULE,
@@ -913,6 +987,8 @@
 }
 
 #ifdef MODULE
+extern int (*ide_xlate_1024_hook)(kdev_t, int, int, const char *);
+
 int init_module (void)
 {
 	unsigned int index;
@@ -921,12 +997,14 @@
 		ide_unregister(index);
 	ideprobe_init();
 	create_proc_ide_interfaces();
+	ide_xlate_1024_hook = ide_xlate_1024;
 	return 0;
 }
 
 void cleanup_module (void)
 {
 	ide_probe = NULL;
+	ide_xlate_1024_hook = 0;
 }
 MODULE_LICENSE("GPL");
 #endif /* MODULE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c
--- linux.orig/drivers/ide/ide-proc.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/ide/ide-proc.c	2002-07-20 01:08:23.000000000 +0000
@@ -65,6 +65,7 @@
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/ctype.h>
+#include <linux/hdreg.h>
 #include <linux/ide.h>
 
 #include <asm/io.h>
@@ -447,7 +448,15 @@
 
 static int proc_ide_get_identify(ide_drive_t *drive, byte *buf)
 {
-	return ide_wait_cmd(drive, (drive->media == ide_disk) ? WIN_IDENTIFY : WIN_PIDENTIFY, 0, 0, 1, buf);
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr hobfile;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+
+	taskfile.sector_count = 0x01;
+	taskfile.command = (drive->media == ide_disk) ? WIN_IDENTIFY : WIN_PIDENTIFY ;
+
+	return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
 }
 
 static int proc_ide_read_identify
@@ -457,7 +466,7 @@
 	int		len = 0, i = 0;
 
 	if (drive && !proc_ide_get_identify(drive, page)) {
-		unsigned short *val = ((unsigned short *)page) + 2;
+		unsigned short *val = (unsigned short *) page;
 		char *out = ((char *)val) + (SECTOR_WORDS * 4);
 		page = out;
 		do {
@@ -588,7 +597,8 @@
 	if (!driver)
 		len = sprintf(page, "(none)\n");
         else
-		len = sprintf(page,"%li\n", ((ide_driver_t *)drive->driver)->capacity(drive));
+		len = sprintf(page,"%llu\n",
+			      (unsigned long long) ((ide_driver_t *)drive->driver)->capacity(drive));
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
@@ -732,16 +742,38 @@
 	}
 }
 
-void destroy_proc_ide_drives(ide_hwif_t *hwif)
+void recreate_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	int	d;
+	struct proc_dir_entry *ent;
+	struct proc_dir_entry *parent = hwif->proc;
+	char name[64];
+//	ide_driver_t *driver = drive->driver;
 
-	for (d = 0; d < MAX_DRIVES; d++) {
-		ide_drive_t *drive = &hwif->drives[d];
-		ide_driver_t *driver = drive->driver;
+	if (drive->present && !drive->proc) {
+		drive->proc = proc_mkdir(drive->name, parent);
+		if (drive->proc)
+			ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
 
-		if (!drive->proc)
-			continue;
+/*
+ * assume that we have these already, however, should test FIXME!
+ * if (driver) {
+ *      ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
+ *      ide_add_proc_entries(drive->proc, driver->proc, drive);
+ * }
+ *
+ */
+		sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
+		ent = proc_symlink(drive->name, proc_ide_root, name);
+		if (!ent)
+			return;
+	}
+}
+
+void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
+{
+	ide_driver_t *driver = drive->driver;
+
+	if (drive->proc) {
 		if (driver)
 			ide_remove_proc_entries(drive->proc, driver->proc);
 		ide_remove_proc_entries(drive->proc, generic_drive_entries);
@@ -751,6 +783,19 @@
 	}
 }
 
+void destroy_proc_ide_drives(ide_hwif_t *hwif)
+{
+	int	d;
+
+	for (d = 0; d < MAX_DRIVES; d++) {
+		ide_drive_t *drive = &hwif->drives[d];
+//		ide_driver_t *driver = drive->driver;
+
+		if (drive->proc)
+			destroy_proc_ide_device(hwif, drive);
+	}
+}
+
 static ide_proc_entry_t hwif_entries[] = {
 	{ "channel",	S_IFREG|S_IRUGO,	proc_ide_read_channel,	NULL },
 	{ "config",	S_IFREG|S_IRUGO|S_IWUSR,proc_ide_read_config,	proc_ide_write_config },
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-swarm.c linux/drivers/ide/ide-swarm.c
--- linux.orig/drivers/ide/ide-swarm.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ide/ide-swarm.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+/*  Derived loosely from ide-pmac.c, so:
+ *  
+ *  Copyright (C) 1998 Paul Mackerras.
+ *  Copyright (C) 1995-1998 Mark Lord
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/swarm_ide.h>
+
+void __init swarm_ide_probe(void)
+{
+	int i;
+	ide_hwif_t *hwif;
+	/* 
+	 * Find the first untaken slot in hwifs 
+	 */
+	for (i = 0; i < MAX_HWIFS; i++) {
+		if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET]) {
+			break;
+		}
+	}
+	if (i == MAX_HWIFS) {
+		printk("No space for SWARM onboard IDE driver in ide_hwifs[].  Not enabled.\n");
+		return;
+	}
+
+	/* Set up our stuff */
+	hwif = &ide_hwifs[i];
+	hwif->hw.io_ports[IDE_DATA_OFFSET]    = SWARM_IDE_REG(0x1f0);
+	hwif->hw.io_ports[IDE_ERROR_OFFSET]   = SWARM_IDE_REG(0x1f1);
+	hwif->hw.io_ports[IDE_NSECTOR_OFFSET] = SWARM_IDE_REG(0x1f2);
+	hwif->hw.io_ports[IDE_SECTOR_OFFSET]  = SWARM_IDE_REG(0x1f3);
+	hwif->hw.io_ports[IDE_LCYL_OFFSET]    = SWARM_IDE_REG(0x1f4);
+	hwif->hw.io_ports[IDE_HCYL_OFFSET]    = SWARM_IDE_REG(0x1f5);
+	hwif->hw.io_ports[IDE_SELECT_OFFSET]  = SWARM_IDE_REG(0x1f6);
+	hwif->hw.io_ports[IDE_STATUS_OFFSET]  = SWARM_IDE_REG(0x1f7);
+	hwif->hw.io_ports[IDE_CONTROL_OFFSET] = SWARM_IDE_REG(0x3f6);
+	hwif->hw.io_ports[IDE_IRQ_OFFSET]     = SWARM_IDE_REG(0x3f7);
+//	hwif->hw->ack_intr                     = swarm_ide_ack_intr;
+	hwif->hw.irq                          = SWARM_IDE_INT;
+	hwif->ideproc                         = swarm_ideproc;
+
+	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+	hwif->irq = hwif->hw.irq;
+	printk("SWARM onboard IDE configured as device %i\n", i);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux.orig/drivers/ide/ide-tape.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ide/ide-tape.c	2002-07-20 01:08:27.000000000 +0000
@@ -2418,26 +2418,26 @@
 	idetape_tape_t *tape = drive->driver_data;
 	int full = 125, empty = 75;
 
-	if (jiffies > tape->controlled_pipeline_head_time + 120 * HZ) {
+	if (time_after(jiffies, tape->controlled_pipeline_head_time + 120 * HZ)) {
 		tape->controlled_previous_pipeline_head = tape->controlled_last_pipeline_head;
 		tape->controlled_previous_head_time = tape->controlled_pipeline_head_time;
 		tape->controlled_last_pipeline_head = tape->pipeline_head;
 		tape->controlled_pipeline_head_time = jiffies;
 	}
-	if (jiffies > tape->controlled_pipeline_head_time + 60 * HZ)
+	if (time_after(jiffies, tape->controlled_pipeline_head_time + 60 * HZ))
 		tape->controlled_pipeline_head_speed = (tape->pipeline_head - tape->controlled_last_pipeline_head) * 32 * HZ / (jiffies - tape->controlled_pipeline_head_time);
-	else if (jiffies > tape->controlled_previous_head_time)
+	else if (time_after(jiffies, tape->controlled_previous_head_time))
 		tape->controlled_pipeline_head_speed = (tape->pipeline_head - tape->controlled_previous_pipeline_head) * 32 * HZ / (jiffies - tape->controlled_previous_head_time);
 
 	if (tape->nr_pending_stages < tape->max_stages /*- 1 */) { /* -1 for read mode error recovery */
-		if (jiffies > tape->uncontrolled_previous_head_time + 10 * HZ) {
+		if (time_after(jiffies, tape->uncontrolled_previous_head_time + 10 * HZ)) {
 			tape->uncontrolled_pipeline_head_time = jiffies;
 			tape->uncontrolled_pipeline_head_speed = (tape->pipeline_head - tape->uncontrolled_previous_pipeline_head) * 32 * HZ / (jiffies - tape->uncontrolled_previous_head_time);
 		}
 	} else {
 		tape->uncontrolled_previous_head_time = jiffies;
 		tape->uncontrolled_previous_pipeline_head = tape->pipeline_head;
-		if (jiffies > tape->uncontrolled_pipeline_head_time + 30 * HZ) {
+		if (time_after(jiffies, tape->uncontrolled_pipeline_head_time + 30 * HZ)) {
 			tape->uncontrolled_pipeline_head_time = jiffies;
 		}
 	}
@@ -2500,7 +2500,7 @@
 		tape->insert_time = jiffies;
 		tape->insert_size = 0;
 	}
-	if (jiffies > tape->insert_time)
+	if (time_after(jiffies, tape->insert_time))
 		tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
 	if (jiffies - tape->avg_time >= HZ) {
 		tape->avg_speed = tape->avg_size * HZ / (jiffies - tape->avg_time) / 1024;
@@ -2680,11 +2680,11 @@
 		tape->reads_since_buffer_fill = 0;
 		tape->last_buffer_fill = jiffies;
 		idetape_queue_onstream_buffer_fill(drive);
-		if (jiffies > tape->insert_time)
+		if (time_after(jiffies, tape->insert_time))
 			tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
 		return ide_stopped;
 	}
-	if (jiffies > tape->insert_time)
+	if (time_after(jiffies, tape->insert_time))
 		tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
 	calculate_speeds(drive);
 	if (tape->onstream && tape->max_frames &&
@@ -2740,7 +2740,7 @@
 			if (tape->onstream) {
 				if (tape->cur_frames - tape->reads_since_buffer_fill <= 0)
 					tape->req_buffer_fill = 1;
-				if (jiffies > tape->last_buffer_fill + 5 * HZ / 100)
+				if (time_after(jiffies, tape->last_buffer_fill + 5 * HZ / 100))
 					tape->req_buffer_fill = 1;
 			}
 			pc = idetape_next_pc_storage (drive);
@@ -2756,7 +2756,7 @@
 			if (tape->onstream) {
 				if (tape->cur_frames + tape->writes_since_buffer_fill >= tape->max_frames)
 					tape->req_buffer_fill = 1;
-				if (jiffies > tape->last_buffer_fill + 5 * HZ / 100)
+				if (time_after(jiffies, tape->last_buffer_fill + 5 * HZ / 100))
 					tape->req_buffer_fill = 1;
 				calculate_speeds(drive);
 			}
@@ -3096,10 +3096,10 @@
 	idetape_tape_t *tape = drive->driver_data;
 	idetape_read_position_result_t *result;
 	
-//#if IDETAPE_DEBUG_LOG
-//	if (tape->debug_level >= 4)
+#if IDETAPE_DEBUG_LOG
+	if (tape->debug_level >= 4)
 		printk (KERN_INFO "ide-tape: Reached idetape_read_position_callback\n");
-//#endif /* IDETAPE_DEBUG_LOG */
+#endif /* IDETAPE_DEBUG_LOG */
 
 	if (!tape->pc->error) {
 		result = (idetape_read_position_result_t *) tape->pc->buffer;
@@ -3214,7 +3214,7 @@
 	 * Wait for the tape to become ready
 	 */
 	timeout += jiffies;
-	while (jiffies < timeout) {
+	while (time_before(jiffies, timeout)) {
 		idetape_create_test_unit_ready_cmd(&pc);
 		if (!__idetape_queue_pc_tail(drive, &pc))
 			return 0;
@@ -3273,10 +3273,10 @@
 	idetape_pc_t pc;
 	int position;
 
-//#if IDETAPE_DEBUG_LOG
-//        if (tape->debug_level >= 4)
+#if IDETAPE_DEBUG_LOG
+        if (tape->debug_level >= 4)
 	printk (KERN_INFO "ide-tape: Reached idetape_read_position\n");
-//#endif /* IDETAPE_DEBUG_LOG */
+#endif /* IDETAPE_DEBUG_LOG */
 
 #ifdef NO_LONGER_REQUIRED
 	idetape_flush_tape_buffers(drive);
@@ -6132,10 +6132,7 @@
 
 #endif
 
-static int idetape_reinit (ide_drive_t *drive)
-{
-	return 0;
-}
+int idetape_reinit(ide_drive_t *drive);
 
 /*
  *	IDE subdriver functions, registered with ide.c
@@ -6148,6 +6145,8 @@
 	supports_dma:		1,
 	supports_dsc_overlap: 	1,
 	cleanup:		idetape_cleanup,
+	standby:		NULL,
+	flushcache:		NULL,
 	do_request:		idetape_do_request,
 	end_request:		idetape_end_request,
 	ioctl:			idetape_blkdev_ioctl,
@@ -6158,7 +6157,9 @@
 	pre_reset:		idetape_pre_reset,
 	capacity:		NULL,
 	proc:			idetape_proc,
-	driver_reinit:		idetape_reinit,
+	reinit:			idetape_reinit,
+	ata_prebuilder:		NULL,
+	atapi_prebuilder:	NULL,
 };
 
 int idetape_init (void);
@@ -6181,6 +6182,92 @@
 	release:	idetape_chrdev_release,
 };
 
+int idetape_reinit (ide_drive_t *drive)
+{
+#if 0
+	idetape_tape_t *tape;
+	int minor, failed = 0, supported = 0;
+/* DRIVER(drive)->busy++; */
+	MOD_INC_USE_COUNT;
+#if ONSTREAM_DEBUG
+        printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_init\n");
+#endif
+	if (!idetape_chrdev_present)
+		for (minor = 0; minor < MAX_HWIFS * MAX_DRIVES; minor++ )
+			idetape_chrdevs[minor].drive = NULL;
+
+	if ((drive = ide_scan_devices (ide_tape, idetape_driver.name, NULL, failed++)) == NULL) {
+		ide_register_module (&idetape_module);
+		MOD_DEC_USE_COUNT;
+#if ONSTREAM_DEBUG
+		printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n");
+#endif
+		return 0;
+	}
+	if (!idetape_chrdev_present &&
+	    devfs_register_chrdev (IDETAPE_MAJOR, "ht", &idetape_fops)) {
+		printk (KERN_ERR "ide-tape: Failed to register character device interface\n");
+		MOD_DEC_USE_COUNT;
+#if ONSTREAM_DEBUG
+		printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n");
+#endif
+		return -EBUSY;
+	}
+	do {
+		if (!idetape_identify_device (drive, drive->id)) {
+			printk (KERN_ERR "ide-tape: %s: not supported by this version of ide-tape\n", drive->name);
+			continue;
+		}
+		if (drive->scsi) {
+			if (strstr(drive->id->model, "OnStream DI-30")) {
+				printk("ide-tape: ide-scsi emulation is not supported for %s.\n", drive->id->model);
+			} else {
+				printk("ide-tape: passing drive %s to ide-scsi emulation.\n", drive->name);
+				continue;
+			}
+		}
+		tape = (idetape_tape_t *) kmalloc (sizeof (idetape_tape_t), GFP_KERNEL);
+		if (tape == NULL) {
+			printk (KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
+			continue;
+		}
+		if (ide_register_subdriver (drive, &idetape_driver, IDE_SUBDRIVER_VERSION)) {
+			printk (KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name);
+			kfree (tape);
+			continue;
+		}
+		for (minor = 0; idetape_chrdevs[minor].drive != NULL; minor++);
+		idetape_setup (drive, tape, minor);
+		idetape_chrdevs[minor].drive = drive;
+		tape->de_r =
+		    devfs_register (drive->de, "mt", DEVFS_FL_DEFAULT,
+				    HWIF(drive)->major, minor,
+				    S_IFCHR | S_IRUGO | S_IWUGO,
+				    &idetape_fops, NULL);
+		tape->de_n =
+		    devfs_register (drive->de, "mtn", DEVFS_FL_DEFAULT,
+				    HWIF(drive)->major, minor + 128,
+				    S_IFCHR | S_IRUGO | S_IWUGO,
+				    &idetape_fops, NULL);
+		devfs_register_tape (tape->de_r);
+		supported++; failed--;
+	} while ((drive = ide_scan_devices (ide_tape, idetape_driver.name, NULL, failed++)) != NULL);
+	if (!idetape_chrdev_present && !supported) {
+		devfs_unregister_chrdev (IDETAPE_MAJOR, "ht");
+	} else
+		idetape_chrdev_present = 1;
+	ide_register_module (&idetape_module);
+	MOD_DEC_USE_COUNT;
+#if ONSTREAM_DEBUG
+	printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n");
+#endif
+
+	return 0;
+#else
+	return 1;
+#endif
+}
+
 MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
 MODULE_LICENSE("GPL");
 
@@ -6205,7 +6292,7 @@
 	ide_drive_t *drive;
 	idetape_tape_t *tape;
 	int minor, failed = 0, supported = 0;
-
+/* DRIVER(drive)->busy++; */
 	MOD_INC_USE_COUNT;
 #if ONSTREAM_DEBUG
         printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_init\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux.orig/drivers/ide/ide-taskfile.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ide/ide-taskfile.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,1723 @@
+/*
+ * linux/drivers/ide/ide-taskfile.c	Version 0.20	Oct 11, 2000
+ *
+ *  Copyright (C) 2000		Michael Cornwell <cornwell@acm.org>
+ *  Copyright (C) 2000		Andre Hedrick <andre@linux-ide.org>
+ *
+ *  May be copied or modified under the terms of the GNU General Public License
+ *
+ * IDE_DEBUG(__LINE__);
+ */
+
+#include <linux/config.h>
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/genhd.h>
+#include <linux/blkpg.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+
+#include <asm/byteorder.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+
+#ifdef CONFIG_IDE_TASKFILE_IO
+#  define __TASKFILE__IO
+#else /* CONFIG_IDE_TASKFILE_IO */
+#  undef __TASKFILE__IO
+#endif /* CONFIG_IDE_TASKFILE_IO */
+
+#define DEBUG_TASKFILE	0	/* unset when fixed */
+
+#if DEBUG_TASKFILE
+#define DTF(x...) printk(##x)
+#else
+#define DTF(x...)
+#endif
+
+inline u32 task_read_24 (ide_drive_t *drive)
+{
+	return	(IN_BYTE(IDE_HCYL_REG)<<16) |
+		(IN_BYTE(IDE_LCYL_REG)<<8) |
+		 IN_BYTE(IDE_SECTOR_REG);
+}
+
+static void ata_bswap_data (void *buffer, int wcount)
+{
+	u16 *p = buffer;
+
+	while (wcount--) {
+		*p = *p << 8 | *p >> 8; p++;
+		*p = *p << 8 | *p >> 8; p++;
+	}
+}
+
+#if SUPPORT_VLB_SYNC
+/*
+ * Some localbus EIDE interfaces require a special access sequence
+ * when using 32-bit I/O instructions to transfer data.  We call this
+ * the "vlb_sync" sequence, which consists of three successive reads
+ * of the sector count register location, with interrupts disabled
+ * to ensure that the reads all happen together.
+ */
+static inline void task_vlb_sync (ide_ioreg_t port) {
+	(void) inb (port);
+	(void) inb (port);
+	(void) inb (port);
+}
+#endif /* SUPPORT_VLB_SYNC */
+
+/*
+ * This is used for most PIO data transfers *from* the IDE interface
+ */
+void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+{
+	byte io_32bit = drive->io_32bit;
+
+	if (io_32bit) {
+#if SUPPORT_VLB_SYNC
+		if (io_32bit & 2) {
+			unsigned long flags;
+			__save_flags(flags);	/* local CPU only */
+			__cli();		/* local CPU only */
+			task_vlb_sync(IDE_NSECTOR_REG);
+			insl(IDE_DATA_REG, buffer, wcount);
+			__restore_flags(flags);	/* local CPU only */
+		} else
+#endif /* SUPPORT_VLB_SYNC */
+			insl(IDE_DATA_REG, buffer, wcount);
+	} else {
+#if SUPPORT_SLOW_DATA_PORTS
+		if (drive->slow) {
+			unsigned short *ptr = (unsigned short *) buffer;
+			while (wcount--) {
+				*ptr++ = inw_p(IDE_DATA_REG);
+				*ptr++ = inw_p(IDE_DATA_REG);
+			}
+		} else
+#endif /* SUPPORT_SLOW_DATA_PORTS */
+			insw(IDE_DATA_REG, buffer, wcount<<1);
+	}
+}
+
+/*
+ * This is used for most PIO data transfers *to* the IDE interface
+ */
+void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+{
+	byte io_32bit = drive->io_32bit;
+
+	if (io_32bit) {
+#if SUPPORT_VLB_SYNC
+		if (io_32bit & 2) {
+			unsigned long flags;
+			__save_flags(flags);	/* local CPU only */
+			__cli();		/* local CPU only */
+			task_vlb_sync(IDE_NSECTOR_REG);
+			outsl(IDE_DATA_REG, buffer, wcount);
+			__restore_flags(flags);	/* local CPU only */
+		} else
+#endif /* SUPPORT_VLB_SYNC */
+			outsl(IDE_DATA_REG, buffer, wcount);
+	} else {
+#if SUPPORT_SLOW_DATA_PORTS
+		if (drive->slow) {
+			unsigned short *ptr = (unsigned short *) buffer;
+			while (wcount--) {
+				outw_p(*ptr++, IDE_DATA_REG);
+				outw_p(*ptr++, IDE_DATA_REG);
+			}
+		} else
+#endif /* SUPPORT_SLOW_DATA_PORTS */
+			outsw(IDE_DATA_REG, buffer, wcount<<1);
+	}
+}
+
+
+static inline void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+{
+	ata_input_data(drive, buffer, wcount);
+	if (drive->bswap)
+		ata_bswap_data(buffer, wcount);
+}
+
+static inline void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+{
+	if (drive->bswap) {
+		ata_bswap_data(buffer, wcount);
+		ata_output_data(drive, buffer, wcount);
+		ata_bswap_data(buffer, wcount);
+	} else {
+		ata_output_data(drive, buffer, wcount);
+	}
+}
+
+ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
+{
+	task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
+	hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
+	struct hd_driveid *id = drive->id;
+	byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
+
+	/* (ks/hs): Moved to start, do not use for multiple out commands */
+	if (task->handler != task_mulout_intr) {
+		if (IDE_CONTROL_REG)
+			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
+		SELECT_MASK(HWIF(drive), drive, 0);
+	}
+
+	if ((id->command_set_2 & 0x0400) &&
+	    (id->cfs_enable_2 & 0x0400) &&
+	    (drive->addressing == 1)) {
+		OUT_BYTE(hobfile->feature, IDE_FEATURE_REG);
+		OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG);
+		OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG);
+		OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG);
+		OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG);
+	}
+
+	OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
+	OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
+	/* refers to number of sectors to transfer */
+	OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
+	/* refers to sector offset or start sector */
+	OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
+	OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
+
+	OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
+	if (task->handler != NULL) {
+#if 0
+		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
+		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
+		/*
+		 * warning check for race between handler and prehandler for
+		 * writing first block of data.  however since we are well
+		 * inside the boundaries of the seek, we should be okay.
+		 */
+		if (task->prehandler != NULL) {
+			return task->prehandler(drive, task->rq);
+		}
+#else
+		ide_startstop_t startstop;
+
+		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
+		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
+
+		if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+			printk(KERN_ERR "%s: no DRQ after issuing %s\n",
+				drive->name,
+				drive->mult_count ? "MULTWRITE" : "WRITE");
+			return startstop;
+		}
+		/* (ks/hs): Fixed Multi Write */
+		if ((taskfile->command != WIN_MULTWRITE) &&
+		    (taskfile->command != WIN_MULTWRITE_EXT)) {
+			struct request *rq = HWGROUP(drive)->rq;
+		/* For Write_sectors we need to stuff the first sector */
+			taskfile_output_data(drive, rq->buffer, SECTOR_WORDS);
+			rq->current_nr_sectors--;
+		} else {
+		/* Stuff first sector(s) by implicitly calling the handler */
+			if (!(drive_is_ready(drive))) {
+			/* FIXME: Replace hard-coded 100, error handling? */
+				int i;
+				for (i=0; i<100; i++) {
+					if (drive_is_ready(drive))
+						break;
+				}
+			}
+			return task->handler(drive);
+		}
+#endif
+	} else {
+		/* for dma commands we down set the handler */
+		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
+	}
+
+	return ide_started;
+}
+
+void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, ide_handler_t *handler)
+{
+	struct hd_driveid *id = drive->id;
+	byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
+
+	/* (ks/hs): Moved to start, do not use for multiple out commands */
+	if (*handler != task_mulout_intr) {
+		if (IDE_CONTROL_REG)
+			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);  /* clear nIEN */
+		SELECT_MASK(HWIF(drive), drive, 0);
+	}
+
+	if ((id->command_set_2 & 0x0400) &&
+	    (id->cfs_enable_2 & 0x0400) &&
+	    (drive->addressing == 1)) {
+		OUT_BYTE(hobfile->feature, IDE_FEATURE_REG);
+		OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG);
+		OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG);
+		OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG);
+		OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG);
+	}
+
+	OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
+	OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
+	/* refers to number of sectors to transfer */
+	OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
+	/* refers to sector offset or start sector */
+	OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
+	OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
+
+	OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
+	if (handler != NULL) {
+		ide_set_handler (drive, handler, WAIT_CMD, NULL);
+		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
+	} else {
+		/* for dma commands we down set the handler */
+		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
+	}
+}
+
+#if 0
+ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
+{
+	task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
+	hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
+	struct hd_driveid *id = drive->id;
+
+	/*
+	 * (KS) Check taskfile in/out flags.
+	 * If set, then execute as it is defined.
+	 * If not set, then define default settings.
+	 * The default values are:
+	 *	write and read all taskfile registers (except data) 
+	 *	write and read the hob registers (sector,nsector,lcyl,hcyl)
+	 */
+	if (task->tf_out_flags.all == 0) {
+		task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
+		if ((id->command_set_2 & 0x0400) &&
+		    (id->cfs_enable_2 & 0x0400) &&
+		    (drive->addressing == 1)) {
+			task->tf_out_flags.all != (IDE_HOB_STD_OUT_FLAGS << 8);
+		}
+        }
+
+	if (task->tf_in_flags.all == 0) {
+		task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
+		if ((id->command_set_2 & 0x0400) &&
+		    (id->cfs_enable_2 & 0x0400) &&
+		    (drive->addressing == 1)) {
+			task->tf_in_flags.all  != (IDE_HOB_STD_IN_FLAGS  << 8);
+		}
+        }
+
+	if (IDE_CONTROL_REG)
+		OUT_BYTE(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
+	SELECT_MASK(HWIF(drive), drive, 0);
+
+	if (task->tf_out_flags.b.data) {
+		unsigned short data =  taskfile->data + (hobfile->data << 8);
+		OUT_WORD (data, IDE_DATA_REG);
+	}
+
+	/* (KS) send hob registers first */
+	if (task->tf_out_flags.b.nsector_hob)
+		OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG);
+	if (task->tf_out_flags.b.sector_hob)
+		OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG);
+	if (task->tf_out_flags.b.lcyl_hob)
+		OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG);
+	if (task->tf_out_flags.b.hcyl_hob)
+		OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG);
+
+
+	/* (KS) Send now the standard registers */
+	if (task->tf_out_flags.b.error_feature)
+		OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
+	/* refers to number of sectors to transfer */
+	if (task->tf_out_flags.b.nsector)
+		OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
+	/* refers to sector offset or start sector */
+	if (task->tf_out_flags.b.sector)
+		OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
+	if (task->tf_out_flags.b.lcyl)
+		OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
+	if (task->tf_out_flags.b.hcyl)
+		OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
+
+        /*
+	 * (KS) Do not modify the specified taskfile. We want to have a
+	 * universal pass through, so we must execute ALL specified values.
+	 *
+	 * (KS) The drive head register is mandatory.
+	 * Don't care about the out flags !
+	 */
+	OUT_BYTE(taskfile->device_head | drive->select.all, IDE_SELECT_REG);
+	if (task->handler != NULL) {
+#if 0
+		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
+		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
+		/*
+		 * warning check for race between handler and prehandler for
+		 * writing first block of data.  however since we are well
+		 * inside the boundaries of the seek, we should be okay.
+		 */
+		if (task->prehandler != NULL) {
+			return task->prehandler(drive, task->rq);
+		}
+#else
+		ide_startstop_t startstop;
+
+		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
+
+		/*
+		 * (KS) The drive command register is also mandatory.
+		 * Don't care about the out flags !
+		 */
+		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
+
+		if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+			printk(KERN_ERR "%s: no DRQ after issuing %s\n",
+				drive->name,
+				drive->mult_count ? "MULTWRITE" : "WRITE");
+			return startstop;
+		}
+		/* (ks/hs): Fixed Multi Write */
+		if ((taskfile->command != WIN_MULTWRITE) &&
+		    (taskfile->command != WIN_MULTWRITE_EXT)) {
+			struct request *rq = HWGROUP(drive)->rq;
+		/* For Write_sectors we need to stuff the first sector */
+			taskfile_output_data(drive, rq->buffer, SECTOR_WORDS);
+			rq->current_nr_sectors--;
+		} else {
+		/* Stuff first sector(s) by implicitly calling the handler */
+			if (!(drive_is_ready(drive))) {
+			/* FIXME: Replace hard-coded 100, error handling? */
+				int i;
+				for (i=0; i<100; i++) {
+					if (drive_is_ready(drive))
+						break;
+				}
+			}
+			return task->handler(drive);
+		}
+#endif
+	} else {
+		/* for dma commands we down set the handler */
+		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
+	}
+
+	return ide_started;
+}
+#endif
+
+#if 0
+/*
+ * Error reporting, in human readable form (luxurious, but a memory hog).
+ */
+byte taskfile_dump_status (ide_drive_t *drive, const char *msg, byte stat)
+{
+	unsigned long flags;
+	byte err = 0;
+
+	__save_flags (flags);	/* local CPU only */
+	ide__sti();		/* local CPU only */
+	printk("%s: %s: status=0x%02x", drive->name, msg, stat);
+#if FANCY_STATUS_DUMPS
+	printk(" { ");
+	if (stat & BUSY_STAT)
+		printk("Busy ");
+	else {
+		if (stat & READY_STAT)	printk("DriveReady ");
+		if (stat & WRERR_STAT)	printk("DeviceFault ");
+		if (stat & SEEK_STAT)	printk("SeekComplete ");
+		if (stat & DRQ_STAT)	printk("DataRequest ");
+		if (stat & ECC_STAT)	printk("CorrectedError ");
+		if (stat & INDEX_STAT)	printk("Index ");
+		if (stat & ERR_STAT)	printk("Error ");
+	}
+	printk("}");
+#endif  /* FANCY_STATUS_DUMPS */
+	printk("\n");
+	if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
+		err = GET_ERR();
+		printk("%s: %s: error=0x%02x", drive->name, msg, err);
+#if FANCY_STATUS_DUMPS
+		if (drive->media == ide_disk) {
+			printk(" { ");
+			if (err & ABRT_ERR)	printk("DriveStatusError ");
+			if (err & ICRC_ERR)	printk("%s", (err & ABRT_ERR) ? "BadCRC " : "BadSector ");
+			if (err & ECC_ERR)	printk("UncorrectableError ");
+			if (err & ID_ERR)	printk("SectorIdNotFound ");
+			if (err & TRK0_ERR)	printk("TrackZeroNotFound ");
+			if (err & MARK_ERR)	printk("AddrMarkNotFound ");
+			printk("}");
+			if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
+				if ((drive->id->command_set_2 & 0x0400) &&
+				    (drive->id->cfs_enable_2 & 0x0400) &&
+				    (drive->addressing == 1)) {
+					__u64 sectors = 0;
+					u32 low = 0, high = 0;
+					low = task_read_24(drive);
+					OUT_BYTE(0x80, IDE_CONTROL_REG);
+					high = task_read_24(drive);
+					sectors = ((__u64)high << 24) | low;
+					printk(", LBAsect=%lld", sectors);
+				} else {
+					byte cur = IN_BYTE(IDE_SELECT_REG);
+					if (cur & 0x40) {	/* using LBA? */
+						printk(", LBAsect=%ld", (unsigned long)
+						 ((cur&0xf)<<24)
+						 |(IN_BYTE(IDE_HCYL_REG)<<16)
+						 |(IN_BYTE(IDE_LCYL_REG)<<8)
+						 | IN_BYTE(IDE_SECTOR_REG));
+					} else {
+						printk(", CHS=%d/%d/%d",
+						  (IN_BYTE(IDE_HCYL_REG)<<8) +
+						   IN_BYTE(IDE_LCYL_REG),
+						  cur & 0xf,
+						  IN_BYTE(IDE_SECTOR_REG));
+					}
+				}
+				if (HWGROUP(drive)->rq)
+					printk(", sector=%llu", (__u64) HWGROUP(drive)->rq->sector);
+			}
+		}
+#endif  /* FANCY_STATUS_DUMPS */
+		printk("\n");
+	}
+	__restore_flags (flags);	/* local CPU only */
+	return err;
+}
+
+/*
+ * Clean up after success/failure of an explicit taskfile operation.
+ */
+void ide_end_taskfile (ide_drive_t *drive, byte stat, byte err)
+{
+	unsigned long flags;
+	struct request *rq;
+	ide_task_t *args;
+	task_ioreg_t command;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	rq = HWGROUP(drive)->rq;
+	spin_unlock_irqrestore(&io_request_lock, flags);
+	args = (ide_task_t *) rq->special;
+
+	command = args->tfRegister[IDE_COMMAND_OFFSET];
+
+	rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+
+	args->tfRegister[IDE_ERROR_OFFSET]   = err;
+	args->tfRegister[IDE_NSECTOR_OFFSET] = IN_BYTE(IDE_NSECTOR_REG);
+	args->tfRegister[IDE_SECTOR_OFFSET]  = IN_BYTE(IDE_SECTOR_REG);
+	args->tfRegister[IDE_LCYL_OFFSET]    = IN_BYTE(IDE_LCYL_REG);
+	args->tfRegister[IDE_HCYL_OFFSET]    = IN_BYTE(IDE_HCYL_REG);
+	args->tfRegister[IDE_SELECT_OFFSET]  = IN_BYTE(IDE_SELECT_REG);
+	args->tfRegister[IDE_STATUS_OFFSET]  = stat;
+	if ((drive->id->command_set_2 & 0x0400) &&
+	    (drive->id->cfs_enable_2 & 0x0400) &&
+	    (drive->addressing == 1)) {
+		OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
+		args->hobRegister[IDE_FEATURE_OFFSET_HOB] = IN_BYTE(IDE_FEATURE_REG);
+		args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = IN_BYTE(IDE_NSECTOR_REG);
+		args->hobRegister[IDE_SECTOR_OFFSET_HOB]  = IN_BYTE(IDE_SECTOR_REG);
+		args->hobRegister[IDE_LCYL_OFFSET_HOB]    = IN_BYTE(IDE_LCYL_REG);
+		args->hobRegister[IDE_HCYL_OFFSET_HOB]    = IN_BYTE(IDE_HCYL_REG);
+	}
+
+/*	taskfile_settings_update(drive, args, command); */
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	blkdev_dequeue_request(rq);
+	HWGROUP(drive)->rq = NULL;
+	end_that_request_last(rq);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+/*
+ * try_to_flush_leftover_data() is invoked in response to a drive
+ * unexpectedly having its DRQ_STAT bit set.  As an alternative to
+ * resetting the drive, this routine tries to clear the condition
+ * by read a sector's worth of data from the drive.  Of course,
+ * this may not help if the drive is *waiting* for data from *us*.
+ */
+void task_try_to_flush_leftover_data (ide_drive_t *drive)
+{
+	int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
+
+	if (drive->media != ide_disk)
+		return;
+	while (i > 0) {
+		u32 buffer[16];
+		unsigned int wcount = (i > 16) ? 16 : i;
+		i -= wcount;
+		taskfile_input_data (drive, buffer, wcount);
+	}
+}
+
+/*
+ * taskfile_error() takes action based on the error returned by the drive.
+ */
+ide_startstop_t taskfile_error (ide_drive_t *drive, const char *msg, byte stat)
+{
+	struct request *rq;
+	byte err;
+
+        err = taskfile_dump_status(drive, msg, stat);
+	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
+		return ide_stopped;
+	/* retry only "normal" I/O: */
+	if (rq->cmd == IDE_DRIVE_TASKFILE) {
+		rq->errors = 1;
+		ide_end_taskfile(drive, stat, err);
+		return ide_stopped;
+	}
+	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { /* other bits are useless when BUSY */
+		rq->errors |= ERROR_RESET;
+	} else {
+		if (drive->media == ide_disk && (stat & ERR_STAT)) {
+			/* err has different meaning on cdrom and tape */
+			if (err == ABRT_ERR) {
+				if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY)
+					return ide_stopped;	/* some newer drives don't support WIN_SPECIFY */
+			} else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) {
+				drive->crc_count++;	/* UDMA crc error -- just retry the operation */
+			} else if (err & (BBD_ERR | ECC_ERR))	/* retries won't help these */
+				rq->errors = ERROR_MAX;
+			else if (err & TRK0_ERR)	/* help it find track zero */
+                                rq->errors |= ERROR_RECAL;
+                }
+                if ((stat & DRQ_STAT) && rq->cmd != WRITE)
+                        task_try_to_flush_leftover_data(drive);
+	}
+	if (GET_STAT() & (BUSY_STAT|DRQ_STAT))
+		OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);	/* force an abort */
+
+	if (rq->errors >= ERROR_MAX) {
+		if (drive->driver != NULL)
+			DRIVER(drive)->end_request(0, HWGROUP(drive));
+		else
+			ide_end_request(0, HWGROUP(drive));
+	} else {
+		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+			++rq->errors;
+			return ide_do_reset(drive);
+		}
+		if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+			drive->special.b.recalibrate = 1;
+		++rq->errors;
+	}
+	return ide_stopped;
+}
+#endif
+
+/*
+ * Handler for special commands without a data phase from ide-disk
+ */
+
+/*
+ * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
+ */
+ide_startstop_t set_multmode_intr (ide_drive_t *drive)
+{
+	byte stat;
+
+	if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) {
+		drive->mult_count = drive->mult_req;
+	} else {
+		drive->mult_req = drive->mult_count = 0;
+		drive->special.b.recalibrate = 1;
+		(void) ide_dump_status(drive, "set_multmode", stat);
+	}
+	return ide_stopped;
+}
+
+/*
+ * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd.
+ */
+ide_startstop_t set_geometry_intr (ide_drive_t *drive)
+{
+	byte stat;
+
+	if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT))
+		return ide_stopped;
+
+	if (stat & (ERR_STAT|DRQ_STAT))
+		return ide_error(drive, "set_geometry_intr", stat);
+
+	ide_set_handler(drive, &set_geometry_intr, WAIT_CMD, NULL);
+	return ide_started;
+}
+
+/*
+ * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
+ */
+ide_startstop_t recal_intr (ide_drive_t *drive)
+{
+	byte stat = GET_STAT();
+
+	if (!OK_STAT(stat,READY_STAT,BAD_STAT))
+		return ide_error(drive, "recal_intr", stat);
+	return ide_stopped;
+}
+
+/*
+ * Handler for commands without a data phase
+ */
+ide_startstop_t task_no_data_intr (ide_drive_t *drive)
+{
+	ide_task_t *args	= HWGROUP(drive)->rq->special;
+	byte stat		= GET_STAT();
+
+	ide__sti();	/* local CPU only */
+
+	if (!OK_STAT(stat, READY_STAT, BAD_STAT))
+		return ide_error(drive, "task_no_data_intr", stat); /* calls ide_end_drive_cmd */
+
+	if (args)
+		ide_end_drive_cmd (drive, stat, GET_ERR());
+
+	return ide_stopped;
+}
+
+/*
+ * Handler for command with PIO data-in phase
+ */
+ide_startstop_t task_in_intr (ide_drive_t *drive)
+{
+	byte stat		= GET_STAT();
+	byte io_32bit		= drive->io_32bit;
+	struct request *rq	= HWGROUP(drive)->rq;
+	char *pBuf		= NULL;
+
+	if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
+		if (stat & (ERR_STAT|DRQ_STAT)) {
+			return ide_error(drive, "task_in_intr", stat);
+		}
+		if (!(stat & BUSY_STAT)) {
+			DTF("task_in_intr to Soon wait for next interrupt\n");
+			ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
+			return ide_started;  
+		}
+	}
+	DTF("stat: %02x\n", stat);
+	pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
+	DTF("Read: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
+
+	drive->io_32bit = 0;
+	taskfile_input_data(drive, pBuf, SECTOR_WORDS);
+	drive->io_32bit = io_32bit;
+
+	if (--rq->current_nr_sectors <= 0) {
+		/* (hs): swapped next 2 lines */
+		DTF("Request Ended stat: %02x\n", GET_STAT());
+		ide_end_request(1, HWGROUP(drive));
+	} else {
+		ide_set_handler(drive, &task_in_intr,  WAIT_CMD, NULL);
+		return ide_started;
+	}
+	return ide_stopped;
+}
+
+#undef ALTSTAT_SCREW_UP
+
+#ifdef ALTSTAT_SCREW_UP
+/*
+ * (ks/hs): Poll Alternate Status Register to ensure
+ * that drive is not busy.
+ */
+byte altstat_multi_busy (ide_drive_t *drive, byte stat, const char *msg)
+{
+	int i;
+
+	DTF("multi%s: ASR = %x\n", msg, stat);
+	if (stat & BUSY_STAT) {
+		/* (ks/hs): FIXME: Replace hard-coded 100, error handling? */
+		for (i=0; i<100; i++) {
+			stat = GET_ALTSTAT();
+			if ((stat & BUSY_STAT) == 0)
+				break;
+		}
+	}
+	/*
+	 * (ks/hs): Read Status AFTER Alternate Status Register
+	 */
+	return(GET_STAT());
+}
+
+/*
+ * (ks/hs): Poll Alternate status register to wait for drive
+ * to become ready for next transfer
+ */
+byte altstat_multi_poll (ide_drive_t *drive, byte stat, const char *msg)
+{
+	/* (ks/hs): FIXME: Error handling, time-out? */
+	while (stat & BUSY_STAT)
+		stat = GET_ALTSTAT();
+	DTF("multi%s: nsect=1, ASR = %x\n", msg, stat);
+	return(GET_STAT());	/* (ks/hs): Clear pending IRQ */
+}
+#endif /* ALTSTAT_SCREW_UP */
+
+/*
+ * Handler for command with Read Multiple
+ */
+ide_startstop_t task_mulin_intr (ide_drive_t *drive)
+{
+	unsigned int		msect, nsect;
+
+#ifdef ALTSTAT_SCREW_UP
+	byte stat	= altstat_multi_busy(drive, GET_ALTSTAT(), "read");
+#else
+	byte stat		= GET_STAT();
+#endif /* ALTSTAT_SCREW_UP */
+
+	byte io_32bit		= drive->io_32bit;
+	struct request *rq	= HWGROUP(drive)->rq;
+	char *pBuf		= NULL;
+
+	if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
+		if (stat & (ERR_STAT|DRQ_STAT)) {
+			return ide_error(drive, "task_mulin_intr", stat);
+		}
+		/* no data yet, so wait for another interrupt */
+		ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL);
+		return ide_started;
+	}
+
+	/* (ks/hs): Fixed Multi-Sector transfer */
+	msect = drive->mult_count;
+
+#ifdef ALTSTAT_SCREW_UP
+	/*
+	 * Screw the request we do not support bad data-phase setups!
+	 * Either read and learn the ATA standard or crash yourself!
+	 */
+	if (!msect) {
+		/*
+		 * (ks/hs): Drive supports multi-sector transfer,
+		 * drive->mult_count was not set
+		 */
+		nsect = 1;
+		while (rq->current_nr_sectors) {
+			pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
+			DTF("Multiread: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors);
+			drive->io_32bit = 0;
+			taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
+			drive->io_32bit = io_32bit;
+			rq->errors = 0;
+			rq->current_nr_sectors -= nsect;
+			stat = altstat_multi_poll(drive, GET_ALTSTAT(), "read");
+		}
+		ide_end_request(1, HWGROUP(drive));
+		return ide_stopped;
+	}
+#endif /* ALTSTAT_SCREW_UP */
+
+	nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors;
+	pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
+
+	DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
+		pBuf, nsect, rq->current_nr_sectors);
+	drive->io_32bit = 0;
+	taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
+	drive->io_32bit = io_32bit;
+	rq->errors = 0;
+	rq->current_nr_sectors -= nsect;
+	if (rq->current_nr_sectors != 0) {
+		ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL);
+		return ide_started;
+	}
+	ide_end_request(1, HWGROUP(drive));
+	return ide_stopped;
+}
+
+ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
+{
+	ide_task_t *args = rq->special;
+	ide_startstop_t startstop;
+
+	if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+		printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
+		return startstop;
+	}
+
+	/* (ks/hs): Fixed Multi Write */
+	if ((args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE) &&
+	    (args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE_EXT)) {
+		/* For Write_sectors we need to stuff the first sector */
+		taskfile_output_data(drive, rq->buffer, SECTOR_WORDS);
+		rq->current_nr_sectors--;
+		return ide_started;
+	} else {
+		/*
+		 * (ks/hs): Stuff the first sector(s)
+		 * by implicitly calling the handler
+		 */
+		if (!(drive_is_ready(drive))) {
+			int i;
+			/*
+			 * (ks/hs): FIXME: Replace hard-coded
+			 *               100, error handling?
+			 */
+			for (i=0; i<100; i++) {
+				if (drive_is_ready(drive))
+					break;
+			}
+		}
+		return args->handler(drive);
+	}
+	return ide_started;
+}
+
+/*
+ * Handler for command with PIO data-out phase
+ */
+ide_startstop_t task_out_intr (ide_drive_t *drive)
+{
+	byte stat		= GET_STAT();
+	byte io_32bit		= drive->io_32bit;
+	struct request *rq	= HWGROUP(drive)->rq;
+	char *pBuf		= NULL;
+
+	if (!rq->current_nr_sectors) { 
+		ide_end_request(1, HWGROUP(drive));
+		return ide_stopped;
+	}
+
+	if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) {
+		return ide_error(drive, "task_out_intr", stat);
+	}
+	if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) {
+		rq = HWGROUP(drive)->rq;
+		pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
+		DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
+		drive->io_32bit = 0;
+		taskfile_output_data(drive, pBuf, SECTOR_WORDS);
+		drive->io_32bit = io_32bit;
+		rq->errors = 0;
+		rq->current_nr_sectors--;
+	}
+
+	if (rq->current_nr_sectors <= 0) {
+		ide_end_request(1, HWGROUP(drive));
+	} else {
+		ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL);
+		return ide_started;
+	}
+	return ide_stopped;
+}
+
+/*
+ * Handler for command write multiple
+ * Called directly from execute_drive_cmd for the first bunch of sectors,
+ * afterwards only by the ISR
+ */
+ide_startstop_t task_mulout_intr (ide_drive_t *drive)
+{
+	unsigned int		msect, nsect;
+
+#ifdef ALTSTAT_SCREW_UP
+	byte stat	= altstat_multi_busy(drive, GET_ALTSTAT(), "write");
+#else
+	byte stat		= GET_STAT();
+#endif /* ALTSTAT_SCREW_UP */
+
+	byte io_32bit		= drive->io_32bit;
+	struct request *rq	= HWGROUP(drive)->rq;
+	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
+	char *pBuf		= NULL;
+
+	/*
+	 * (ks/hs): Handle last IRQ on multi-sector transfer,
+	 * occurs after all data was sent
+	 */
+	if (rq->current_nr_sectors == 0) {
+		if (stat & (ERR_STAT|DRQ_STAT))
+			return ide_error(drive, "task_mulout_intr", stat);
+		ide_end_request(1, HWGROUP(drive));
+		return ide_stopped;
+	}
+
+	if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
+		if (stat & (ERR_STAT|DRQ_STAT)) {
+			return ide_error(drive, "task_mulout_intr", stat);
+		}
+		/* no data yet, so wait for another interrupt */
+		if (hwgroup->handler == NULL)
+			ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
+		return ide_started;
+	}
+
+	/* (ks/hs): See task_mulin_intr */
+	msect = drive->mult_count;
+
+#ifdef ALTSTAT_SCREW_UP
+	/*
+	 * Screw the request we do not support bad data-phase setups!
+	 * Either read and learn the ATA standard or crash yourself!
+	 */
+	if (!msect) {
+		nsect = 1;
+		while (rq->current_nr_sectors) {
+			pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
+			DTF("Multiwrite: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors);
+			drive->io_32bit = 0;
+			taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
+			drive->io_32bit = io_32bit;
+			rq->errors = 0;
+			rq->current_nr_sectors -= nsect;
+			stat = altstat_multi_poll(drive, GET_ALTSTAT(), "write");
+		}
+		ide_end_request(1, HWGROUP(drive));
+		return ide_stopped;
+	}
+#endif /* ALTSTAT_SCREW_UP */
+
+	nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors;
+	pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
+	DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
+		pBuf, nsect, rq->current_nr_sectors);
+	drive->io_32bit = 0;
+	taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
+	drive->io_32bit = io_32bit;
+	rq->errors = 0;
+	rq->current_nr_sectors -= nsect;
+	if (hwgroup->handler == NULL)
+		ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
+	return ide_started;
+}
+
+/* Called by internal to feature out type of command being called */
+ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile)
+{
+	switch(taskfile->command) {
+				/* IDE_DRIVE_TASK_RAW_WRITE */
+		case CFA_WRITE_MULTI_WO_ERASE:
+		case WIN_MULTWRITE:
+		case WIN_MULTWRITE_EXT:
+//		case WIN_WRITEDMA:
+//		case WIN_WRITEDMA_QUEUED:
+//		case WIN_WRITEDMA_EXT:
+//		case WIN_WRITEDMA_QUEUED_EXT:
+				/* IDE_DRIVE_TASK_OUT */
+		case WIN_WRITE:
+		case WIN_WRITE_VERIFY:
+		case WIN_WRITE_BUFFER:
+		case CFA_WRITE_SECT_WO_ERASE:
+		case WIN_DOWNLOAD_MICROCODE:
+			return &pre_task_out_intr;
+				/* IDE_DRIVE_TASK_OUT */
+		case WIN_SMART:
+			if (taskfile->feature == SMART_WRITE_LOG_SECTOR)
+				return &pre_task_out_intr;
+		default:
+			break;
+	}
+	return(NULL);
+}
+
+/* Called by internal to feature out type of command being called */
+ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile)
+{
+	switch(taskfile->command) {
+		case WIN_IDENTIFY:
+		case WIN_PIDENTIFY:
+		case CFA_TRANSLATE_SECTOR:
+		case WIN_READ_BUFFER:
+		case WIN_READ:
+		case WIN_READ_EXT:
+			return &task_in_intr;
+		case WIN_SECURITY_DISABLE:
+		case WIN_SECURITY_ERASE_UNIT:
+		case WIN_SECURITY_SET_PASS:
+		case WIN_SECURITY_UNLOCK:
+		case WIN_DOWNLOAD_MICROCODE:
+		case CFA_WRITE_SECT_WO_ERASE:
+		case WIN_WRITE_BUFFER:
+		case WIN_WRITE_VERIFY:
+		case WIN_WRITE:
+		case WIN_WRITE_EXT:
+			return &task_out_intr;
+		case WIN_MULTREAD:
+		case WIN_MULTREAD_EXT:
+			return &task_mulin_intr;
+		case CFA_WRITE_MULTI_WO_ERASE:
+		case WIN_MULTWRITE:
+		case WIN_MULTWRITE_EXT:
+			return &task_mulout_intr;
+		case WIN_SMART:
+			switch(taskfile->feature) {
+				case SMART_READ_VALUES:
+				case SMART_READ_THRESHOLDS:
+				case SMART_READ_LOG_SECTOR:
+					return &task_in_intr;
+				case SMART_WRITE_LOG_SECTOR:
+					return &task_out_intr;
+				default:
+					return &task_no_data_intr;
+			}
+		case CFA_REQ_EXT_ERROR_CODE:
+		case CFA_ERASE_SECTORS:
+		case WIN_VERIFY:
+		case WIN_VERIFY_EXT:
+		case WIN_SEEK:
+			return &task_no_data_intr;
+		case WIN_SPECIFY:
+			return &set_geometry_intr;
+		case WIN_RESTORE:
+			return &recal_intr;
+		case WIN_DIAGNOSE:
+		case WIN_FLUSH_CACHE:
+		case WIN_FLUSH_CACHE_EXT:
+		case WIN_STANDBYNOW1:
+		case WIN_STANDBYNOW2:
+		case WIN_SLEEPNOW1:
+		case WIN_SLEEPNOW2:
+		case WIN_SETIDLE1:
+		case WIN_CHECKPOWERMODE1:
+		case WIN_CHECKPOWERMODE2:
+		case WIN_GETMEDIASTATUS:
+		case WIN_MEDIAEJECT:
+			return &task_no_data_intr;
+		case WIN_SETMULT:
+			return &set_multmode_intr;
+		case WIN_READ_NATIVE_MAX:
+		case WIN_SET_MAX:
+		case WIN_READ_NATIVE_MAX_EXT:
+		case WIN_SET_MAX_EXT:
+		case WIN_SECURITY_ERASE_PREPARE:
+		case WIN_SECURITY_FREEZE_LOCK:
+		case WIN_DOORLOCK:
+		case WIN_DOORUNLOCK:
+		case WIN_SETFEATURES:
+			return &task_no_data_intr;
+		case DISABLE_SEAGATE:
+		case EXABYTE_ENABLE_NEST:
+			return &task_no_data_intr;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		case WIN_READDMA:
+		case WIN_IDENTIFY_DMA:
+		case WIN_READDMA_QUEUED:
+		case WIN_READDMA_EXT:
+		case WIN_READDMA_QUEUED_EXT:
+		case WIN_WRITEDMA:
+		case WIN_WRITEDMA_QUEUED:
+		case WIN_WRITEDMA_EXT:
+		case WIN_WRITEDMA_QUEUED_EXT:
+#endif
+		case WIN_FORMAT:
+		case WIN_INIT:
+		case WIN_DEVICE_RESET:
+		case WIN_QUEUED_SERVICE:
+		case WIN_PACKETCMD:
+		default:
+			return(NULL);
+	}	
+}
+
+/* Called by ioctl to feature out type of command being called */
+int ide_cmd_type_parser (ide_task_t *args)
+{
+	struct hd_drive_task_hdr *taskfile = (struct hd_drive_task_hdr *) args->tfRegister;
+	struct hd_drive_hob_hdr *hobfile = (struct hd_drive_hob_hdr *) args->hobRegister;
+
+	args->prehandler = ide_pre_handler_parser(taskfile, hobfile);
+	args->handler = ide_handler_parser(taskfile, hobfile);
+
+	switch(args->tfRegister[IDE_COMMAND_OFFSET]) {
+		case WIN_IDENTIFY:
+		case WIN_PIDENTIFY:
+			return IDE_DRIVE_TASK_IN;
+		case CFA_TRANSLATE_SECTOR:
+		case WIN_READ:
+		case WIN_READ_BUFFER:
+			return IDE_DRIVE_TASK_IN;
+		case WIN_WRITE:
+		case WIN_WRITE_VERIFY:
+		case WIN_WRITE_BUFFER:
+		case CFA_WRITE_SECT_WO_ERASE:
+		case WIN_DOWNLOAD_MICROCODE:
+			return IDE_DRIVE_TASK_RAW_WRITE;
+		case WIN_MULTREAD:
+			return IDE_DRIVE_TASK_IN;
+		case CFA_WRITE_MULTI_WO_ERASE:
+		case WIN_MULTWRITE:
+			return IDE_DRIVE_TASK_RAW_WRITE;
+		case WIN_SECURITY_DISABLE:
+		case WIN_SECURITY_ERASE_UNIT:
+		case WIN_SECURITY_SET_PASS:
+		case WIN_SECURITY_UNLOCK:
+			return IDE_DRIVE_TASK_OUT;
+		case WIN_SMART:
+			args->tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS;
+			args->tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS;
+			switch(args->tfRegister[IDE_FEATURE_OFFSET]) {
+				case SMART_READ_VALUES:
+				case SMART_READ_THRESHOLDS:
+				case SMART_READ_LOG_SECTOR:
+					return IDE_DRIVE_TASK_IN;
+				case SMART_WRITE_LOG_SECTOR:
+					return IDE_DRIVE_TASK_OUT;
+				default:
+					return IDE_DRIVE_TASK_NO_DATA;
+			}
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		case WIN_READDMA:
+		case WIN_IDENTIFY_DMA:
+		case WIN_READDMA_QUEUED:
+		case WIN_READDMA_EXT:
+		case WIN_READDMA_QUEUED_EXT:
+			return IDE_DRIVE_TASK_IN;
+		case WIN_WRITEDMA:
+		case WIN_WRITEDMA_QUEUED:
+		case WIN_WRITEDMA_EXT:
+		case WIN_WRITEDMA_QUEUED_EXT:
+			return IDE_DRIVE_TASK_RAW_WRITE;
+#endif
+		case WIN_SETFEATURES:
+			switch(args->tfRegister[IDE_FEATURE_OFFSET]) {
+				case SETFEATURES_XFER:
+					return IDE_DRIVE_TASK_SET_XFER;
+				case SETFEATURES_DIS_DEFECT:
+				case SETFEATURES_EN_APM:
+				case SETFEATURES_DIS_MSN:
+				case SETFEATURES_EN_RI:
+				case SETFEATURES_EN_SI:
+				case SETFEATURES_DIS_RPOD:
+				case SETFEATURES_DIS_WCACHE:
+				case SETFEATURES_EN_DEFECT:
+				case SETFEATURES_DIS_APM:
+				case SETFEATURES_EN_MSN:
+				case SETFEATURES_EN_RLA:
+				case SETFEATURES_PREFETCH:
+				case SETFEATURES_EN_RPOD:
+				case SETFEATURES_DIS_RI:
+				case SETFEATURES_DIS_SI:
+				default:
+					return IDE_DRIVE_TASK_NO_DATA;
+			}
+		case WIN_NOP:
+		case CFA_REQ_EXT_ERROR_CODE:
+		case CFA_ERASE_SECTORS:
+		case WIN_VERIFY:
+		case WIN_VERIFY_EXT:
+		case WIN_SEEK:
+		case WIN_SPECIFY:
+		case WIN_RESTORE:
+		case WIN_DIAGNOSE:
+		case WIN_FLUSH_CACHE:
+		case WIN_FLUSH_CACHE_EXT:
+		case WIN_STANDBYNOW1:
+		case WIN_STANDBYNOW2:
+		case WIN_SLEEPNOW1:
+		case WIN_SLEEPNOW2:
+		case WIN_SETIDLE1:
+		case DISABLE_SEAGATE:
+		case WIN_CHECKPOWERMODE1:
+		case WIN_CHECKPOWERMODE2:
+		case WIN_GETMEDIASTATUS:
+		case WIN_MEDIAEJECT:
+		case WIN_SETMULT:
+		case WIN_READ_NATIVE_MAX:
+		case WIN_SET_MAX:
+		case WIN_READ_NATIVE_MAX_EXT:
+		case WIN_SET_MAX_EXT:
+		case WIN_SECURITY_ERASE_PREPARE:
+		case WIN_SECURITY_FREEZE_LOCK:
+		case EXABYTE_ENABLE_NEST:
+		case WIN_DOORLOCK:
+		case WIN_DOORUNLOCK:
+			return IDE_DRIVE_TASK_NO_DATA;
+		case WIN_FORMAT:
+		case WIN_INIT:
+		case WIN_DEVICE_RESET:
+		case WIN_QUEUED_SERVICE:
+		case WIN_PACKETCMD:
+		default:
+			return IDE_DRIVE_TASK_INVALID;
+	}
+}
+
+/*
+ * This function is intended to be used prior to invoking ide_do_drive_cmd().
+ */
+void ide_init_drive_taskfile (struct request *rq)
+{
+	memset(rq, 0, sizeof(*rq));
+	rq->cmd = IDE_DRIVE_TASK_NO_DATA;
+}
+
+/*
+ * This is kept for internal use only !!!
+ * This is an internal call and nobody in user-space has a damn
+ * reason to call this taskfile.
+ *
+ * ide_raw_taskfile is the one that user-space executes.
+ */
+int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf)
+{
+	struct request rq;
+	ide_task_t args;
+
+	memset(&args, 0, sizeof(ide_task_t));
+
+	args.tfRegister[IDE_DATA_OFFSET]         = taskfile->data;
+	args.tfRegister[IDE_FEATURE_OFFSET]      = taskfile->feature;
+	args.tfRegister[IDE_NSECTOR_OFFSET]      = taskfile->sector_count;
+	args.tfRegister[IDE_SECTOR_OFFSET]       = taskfile->sector_number;
+	args.tfRegister[IDE_LCYL_OFFSET]         = taskfile->low_cylinder;
+	args.tfRegister[IDE_HCYL_OFFSET]         = taskfile->high_cylinder;
+	args.tfRegister[IDE_SELECT_OFFSET]       = taskfile->device_head;
+	args.tfRegister[IDE_COMMAND_OFFSET]      = taskfile->command;
+
+	args.hobRegister[IDE_DATA_OFFSET_HOB]    = hobfile->data;
+	args.hobRegister[IDE_FEATURE_OFFSET_HOB] = hobfile->feature;
+	args.hobRegister[IDE_NSECTOR_OFFSET_HOB] = hobfile->sector_count;
+	args.hobRegister[IDE_SECTOR_OFFSET_HOB]  = hobfile->sector_number;
+	args.hobRegister[IDE_LCYL_OFFSET_HOB]    = hobfile->low_cylinder;
+	args.hobRegister[IDE_HCYL_OFFSET_HOB]    = hobfile->high_cylinder;
+	args.hobRegister[IDE_SELECT_OFFSET_HOB]  = hobfile->device_head;
+	args.hobRegister[IDE_CONTROL_OFFSET_HOB] = hobfile->control;
+
+	ide_init_drive_taskfile(&rq);
+	/* This is kept for internal use only !!! */
+	args.command_type = ide_cmd_type_parser (&args);
+	if (args.command_type != IDE_DRIVE_TASK_NO_DATA)
+		rq.current_nr_sectors = rq.nr_sectors = (hobfile->sector_count << 8) | taskfile->sector_count;
+
+	rq.cmd = IDE_DRIVE_TASKFILE;
+	rq.buffer = buf;
+	rq.special = &args;
+	return ide_do_drive_cmd(drive, &rq, ide_wait);
+}
+
+int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, byte *buf)
+{
+	struct request rq;
+	ide_init_drive_taskfile(&rq);
+	rq.cmd = IDE_DRIVE_TASKFILE;
+	rq.buffer = buf;
+
+	if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
+		rq.current_nr_sectors = rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET_HOB] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET];
+
+	rq.special = args;
+	return ide_do_drive_cmd(drive, &rq, ide_wait);
+}
+
+
+#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
+char * ide_ioctl_verbose (unsigned int cmd)
+{
+	return("unknown");
+}
+
+char * ide_task_cmd_verbose (byte task)
+{
+	return("unknown");
+}
+#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
+
+/*
+ *  The taskfile glue table
+ *
+ *  reqtask.data_phase	reqtask.req_cmd
+ *  			args.command_type		args.handler
+ *
+ *  TASKFILE_P_OUT_DMAQ	??				??
+ *  TASKFILE_P_IN_DMAQ	??				??
+ *  TASKFILE_P_OUT_DMA	??				??
+ *  TASKFILE_P_IN_DMA	??				??
+ *  TASKFILE_P_OUT	??				??
+ *  TASKFILE_P_IN	??				??
+ *
+ *  TASKFILE_OUT_DMAQ	IDE_DRIVE_TASK_RAW_WRITE	NULL
+ *  TASKFILE_IN_DMAQ	IDE_DRIVE_TASK_IN		NULL
+ *
+ *  TASKFILE_OUT_DMA	IDE_DRIVE_TASK_RAW_WRITE	NULL
+ *  TASKFILE_IN_DMA	IDE_DRIVE_TASK_IN		NULL
+ *
+ *  TASKFILE_IN_OUT	??				??
+ *
+ *  TASKFILE_MULTI_OUT	IDE_DRIVE_TASK_RAW_WRITE	task_mulout_intr
+ *  TASKFILE_MULTI_IN	IDE_DRIVE_TASK_IN		task_mulin_intr
+ *
+ *  TASKFILE_OUT	IDE_DRIVE_TASK_RAW_WRITE	task_out_intr
+ *  TASKFILE_OUT	IDE_DRIVE_TASK_OUT		task_out_intr
+ *
+ *  TASKFILE_IN		IDE_DRIVE_TASK_IN		task_in_intr
+ *  TASKFILE_NO_DATA	IDE_DRIVE_TASK_NO_DATA		task_no_data_intr
+ *
+ *  			IDE_DRIVE_TASK_SET_XFER		task_no_data_intr
+ *  			IDE_DRIVE_TASK_INVALID
+ *
+ */
+
+#define MAX_DMA		(256*SECTOR_WORDS)
+
+int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	ide_task_request_t	*req_task;
+	ide_task_t		args;
+
+	byte *outbuf		= NULL;
+	byte *inbuf		= NULL;
+	task_ioreg_t *argsptr	= args.tfRegister;
+	task_ioreg_t *hobsptr	= args.hobRegister;
+	int err			= 0;
+	int tasksize		= sizeof(struct ide_task_request_s);
+	int taskin		= 0;
+	int taskout		= 0;
+
+	req_task = kmalloc(tasksize, GFP_KERNEL);
+	if (req_task == NULL) return -ENOMEM;
+	memset(req_task, 0, tasksize);
+	if (copy_from_user(req_task, (void *) arg, tasksize)) {
+		kfree(req_task);
+		return -EFAULT;
+	}
+
+	taskout = (int) req_task->out_size;
+	taskin  = (int) req_task->in_size;
+
+	if (taskout) {
+		int outtotal = tasksize;
+		outbuf = kmalloc(taskout, GFP_KERNEL);
+		if (outbuf == NULL) {
+			err = -ENOMEM;
+			goto abort;
+		}
+		memset(outbuf, 0, taskout);
+		if (copy_from_user(outbuf, (void *)arg + outtotal, taskout)) {
+			err = -EFAULT;
+			goto abort;
+		}
+	}
+
+	if (taskin) {
+		int intotal = tasksize + taskout;
+		inbuf = kmalloc(taskin, GFP_KERNEL);
+		if (inbuf == NULL) {
+			err = -ENOMEM;
+			goto abort;
+		}
+		memset(inbuf, 0, taskin);
+		if (copy_from_user(inbuf, (void *)arg + intotal , taskin)) {
+			err = -EFAULT;
+			goto abort;
+		}
+	}
+
+	memset(argsptr, 0, HDIO_DRIVE_TASK_HDR_SIZE);
+	memset(hobsptr, 0, HDIO_DRIVE_HOB_HDR_SIZE);
+	memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
+	memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE);
+
+	args.tf_in_flags  = req_task->in_flags;
+	args.tf_out_flags = req_task->out_flags;
+	args.data_phase   = req_task->data_phase;
+	args.command_type = req_task->req_cmd;
+
+#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
+	DTF("%s: ide_ioctl_cmd %s:  ide_task_cmd %s\n",
+		drive->name,
+		ide_ioctl_verbose(cmd),
+		ide_task_cmd_verbose(args.tfRegister[IDE_COMMAND_OFFSET]));
+#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
+
+	switch(req_task->data_phase) {
+		case TASKFILE_OUT_DMAQ:
+		case TASKFILE_OUT_DMA:
+			args.prehandler = NULL;
+			args.handler = NULL;
+			args.posthandler = NULL;
+			err = ide_raw_taskfile(drive, &args, outbuf);
+			break;
+		case TASKFILE_IN_DMAQ:
+		case TASKFILE_IN_DMA:
+			args.prehandler = NULL;
+			args.handler = NULL;
+			args.posthandler = NULL;
+			err = ide_raw_taskfile(drive, &args, inbuf);
+			break;
+		case TASKFILE_IN_OUT:
+#if 0
+			args.prehandler = &pre_task_out_intr;
+			args.handler = &task_out_intr;
+			args.posthandler = NULL;
+			err = ide_raw_taskfile(drive, &args, outbuf);
+			args.prehandler = NULL;
+			args.handler = &task_in_intr;
+			args.posthandler = NULL;
+			err = ide_raw_taskfile(drive, &args, inbuf);
+			break;
+#else
+			err = -EFAULT;
+			goto abort;
+#endif
+		case TASKFILE_MULTI_OUT:
+			if (drive->mult_count) {
+				args.prehandler = &pre_task_out_intr;
+				args.handler = &task_mulout_intr;
+				args.posthandler = NULL;
+				err = ide_raw_taskfile(drive, &args, outbuf);
+			} else {
+				/* (hs): give up if multcount is not set */
+				printk("%s: %s Multimode Write " \
+					"multcount is not set\n",
+					 drive->name, __FUNCTION__);
+				err = -EPERM;
+				goto abort;
+			}
+			break;
+		case TASKFILE_OUT:
+			args.prehandler = &pre_task_out_intr;
+			args.handler = &task_out_intr;
+			args.posthandler = NULL;
+			err = ide_raw_taskfile(drive, &args, outbuf);
+			break;
+		case TASKFILE_MULTI_IN:
+			if (drive->mult_count) {
+				args.prehandler = NULL;
+				args.handler = &task_mulin_intr;
+				args.posthandler = NULL;
+				err = ide_raw_taskfile(drive, &args, inbuf);
+			} else {
+				/* (hs): give up if multcount is not set */
+				printk("%s: %s Multimode Read failure " \
+					"multcount is not set\n",
+					drive->name, __FUNCTION__);
+				err = -EPERM;
+				goto abort;
+			}
+			break;
+		case TASKFILE_IN:
+			args.prehandler = NULL;
+			args.handler = &task_in_intr;
+			args.posthandler = NULL;
+			err = ide_raw_taskfile(drive, &args, inbuf);
+			break;
+		case TASKFILE_NO_DATA:
+			args.prehandler = NULL;
+			args.handler = &task_no_data_intr;
+			args.posthandler = NULL;
+			err = ide_raw_taskfile(drive, &args, NULL);
+			break;
+		default:
+			args.prehandler = NULL;
+			args.handler = NULL;
+			args.posthandler = NULL;
+			err = -EFAULT;
+			goto abort;
+	}
+
+	memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE);
+	memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE);
+	req_task->in_flags  = args.tf_in_flags;
+	req_task->out_flags = args.tf_out_flags;
+
+	if (copy_to_user((void *)arg, req_task, tasksize)) {
+		err = -EFAULT;
+		goto abort;
+	}
+	if (taskout) {
+		int outtotal = tasksize;
+		if (copy_to_user((void *)arg+outtotal, outbuf, taskout)) {
+			err = -EFAULT;
+			goto abort;
+		}
+	}
+	if (taskin) {
+		int intotal = tasksize + taskout;
+		if (copy_to_user((void *)arg+intotal, inbuf, taskin)) {
+			err = -EFAULT;
+			goto abort;
+		}
+	}
+abort:
+	kfree(req_task);
+	if (outbuf != NULL)
+		kfree(outbuf);
+	if (inbuf != NULL)
+		kfree(inbuf);
+	return err;
+}
+
+EXPORT_SYMBOL(task_read_24);
+EXPORT_SYMBOL(do_rw_taskfile);
+EXPORT_SYMBOL(do_taskfile);
+// EXPORT_SYMBOL(flagged_taskfile);
+
+//EXPORT_SYMBOL(ide_end_taskfile);
+
+EXPORT_SYMBOL(set_multmode_intr);
+EXPORT_SYMBOL(set_geometry_intr);
+EXPORT_SYMBOL(recal_intr);
+
+EXPORT_SYMBOL(task_no_data_intr);
+EXPORT_SYMBOL(task_in_intr);
+EXPORT_SYMBOL(task_mulin_intr);
+EXPORT_SYMBOL(pre_task_out_intr);
+EXPORT_SYMBOL(task_out_intr);
+EXPORT_SYMBOL(task_mulout_intr);
+
+EXPORT_SYMBOL(ide_init_drive_taskfile);
+EXPORT_SYMBOL(ide_wait_taskfile);
+EXPORT_SYMBOL(ide_raw_taskfile);
+EXPORT_SYMBOL(ide_pre_handler_parser);
+EXPORT_SYMBOL(ide_handler_parser);
+EXPORT_SYMBOL(ide_cmd_type_parser);
+EXPORT_SYMBOL(ide_taskfile_ioctl);
+
+#ifdef CONFIG_PKT_TASK_IOCTL
+
+#if 0
+{
+
+{ /* start cdrom */
+
+	struct cdrom_info *info = drive->driver_data;
+
+	if (info->dma) {
+		if (info->cmd == READ) {
+			info->dma = !HWIF(drive)->dmaproc(ide_dma_read, drive);
+		} else if (info->cmd == WRITE) {
+			info->dma = !HWIF(drive)->dmaproc(ide_dma_write, drive);
+		} else {
+			printk("ide-cd: DMA set, but not allowed\n");
+		}
+	}
+
+	/* Set up the controller registers. */
+	OUT_BYTE (info->dma, IDE_FEATURE_REG);
+	OUT_BYTE (0, IDE_NSECTOR_REG);
+	OUT_BYTE (0, IDE_SECTOR_REG);
+
+	OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG);
+	OUT_BYTE (xferlen >> 8  , IDE_HCYL_REG);
+	if (IDE_CONTROL_REG)
+		OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
+
+	if (info->dma)
+		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
+
+	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
+		ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
+		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
+		return ide_started;
+	} else {
+		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
+		return (*handler) (drive);
+	}
+
+} /* end cdrom */
+
+{ /* start floppy */
+
+	idefloppy_floppy_t *floppy = drive->driver_data;
+	idefloppy_bcount_reg_t bcount;
+	int dma_ok = 0;
+
+	floppy->pc=pc;		/* Set the current packet command */
+
+	pc->retries++;
+	pc->actually_transferred=0; /* We haven't transferred any data yet */
+	pc->current_position=pc->buffer;
+	bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024);
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
+		(void) HWIF(drive)->dmaproc(ide_dma_off, drive);
+	}
+	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
+		dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+	if (IDE_CONTROL_REG)
+		OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
+	OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG);	/* Use PIO/DMA */
+	OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);
+	OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);
+	OUT_BYTE (drive->select.all,IDE_SELECT_REG);
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	if (dma_ok) {	/* Begin DMA, if necessary */
+		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
+		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
+	}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+} /* end floppy */
+
+{ /* start tape */
+
+	idetape_tape_t *tape = drive->driver_data;
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
+		printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n");
+		(void) HWIF(drive)->dmaproc(ide_dma_off, drive);
+	}
+	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
+		dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+	if (IDE_CONTROL_REG)
+		OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
+	OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG);	/* Use PIO/DMA */
+	OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);
+	OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);
+	OUT_BYTE (drive->select.all,IDE_SELECT_REG);
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	if (dma_ok) {	/* Begin DMA, if necessary */
+		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
+		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
+	}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+	if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
+		ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
+		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
+		return ide_started;
+	} else {
+		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
+		return idetape_transfer_pc(drive);
+	}
+
+} /* end tape */
+
+}
+#endif
+
+int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+#if 0
+	switch(req_task->data_phase) {
+		case TASKFILE_P_OUT_DMAQ:
+		case TASKFILE_P_IN_DMAQ:
+		case TASKFILE_P_OUT_DMA:
+		case TASKFILE_P_IN_DMA:
+		case TASKFILE_P_OUT:
+		case TASKFILE_P_IN:
+	}
+#endif
+	return -ENOMSG;
+}
+
+EXPORT_SYMBOL(pkt_taskfile_ioctl);
+
+#endif /* CONFIG_PKT_TASK_IOCTL */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide-timing.h linux/drivers/ide/ide-timing.h
--- linux.orig/drivers/ide/ide-timing.h	2001-02-03 19:27:43.000000000 +0000
+++ linux/drivers/ide/ide-timing.h	2002-07-20 01:08:38.000000000 +0000
@@ -2,11 +2,9 @@
 #define _IDE_TIMING_H
 
 /*
- * $Id: ide-timing.h,v 1.5 2001/01/15 21:48:56 vojtech Exp $
+ * $Id: ide-timing.h,v 1.6 2001/12/23 22:47:56 vojtech Exp $
  *
- *  Copyright (c) 1999-2000 Vojtech Pavlik
- *
- *  Sponsored by SuSE
+ *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
 /*
@@ -25,16 +23,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
 #include <linux/hdreg.h>
 
-#ifndef XFER_PIO_5
 #define XFER_PIO_5		0x0d
 #define XFER_UDMA_SLOW		0x4f
-#endif
 
 struct ide_timing {
 	short mode;
@@ -49,13 +45,15 @@
 };
 
 /*
- * PIO 0-5, MWDMA 0-2 and UDMA 0-5 timings (in nanoseconds).
+ * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
  * These were taken from ATA/ATAPI-6 standard, rev 0a, except
- * for PIO 5, which is a nonstandard extension.
+ * for PIO 5, which is a nonstandard extension and UDMA6, which
+ * is currently supported only by Maxtor drives. 
  */
 
 static struct ide_timing ide_timing[] = {
 
+	{ XFER_UDMA_6,     0,   0,   0,   0,   0,   0,   0,  15 },
 	{ XFER_UDMA_5,     0,   0,   0,   0,   0,   0,   0,  20 },
 	{ XFER_UDMA_4,     0,   0,   0,   0,   0,   0,   0,  30 },
 	{ XFER_UDMA_3,     0,   0,   0,   0,   0,   0,   0,  45 },
@@ -105,6 +103,7 @@
 #define EZ(v,unit)	((v)?ENOUGH(v,unit):0)
 
 #define XFER_MODE	0xf0
+#define XFER_UDMA_133	0x48
 #define XFER_UDMA_100	0x44
 #define XFER_UDMA_66	0x42
 #define XFER_UDMA	0x40
@@ -123,6 +122,9 @@
 
 	if ((map & XFER_UDMA) && (id->field_valid & 4)) {	/* Want UDMA and UDMA bitmap valid */
 
+		if ((map & XFER_UDMA_133) == XFER_UDMA_133)
+			if ((best = (id->dma_ultra & 0x0040) ? XFER_UDMA_6 : 0)) return best;
+
 		if ((map & XFER_UDMA_100) == XFER_UDMA_100)
 			if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best;
 
@@ -174,14 +176,14 @@
 
 static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT)
 {
-	q->setup   = EZ(t->setup,   T);
-	q->act8b   = EZ(t->act8b,   T);
-	q->rec8b   = EZ(t->rec8b,   T);
-	q->cyc8b   = EZ(t->cyc8b,   T);
-	q->active  = EZ(t->active,  T);
-	q->recover = EZ(t->recover, T);
-	q->cycle   = EZ(t->cycle,   T);
-	q->udma    = EZ(t->udma,   UT);
+	q->setup   = EZ(t->setup   * 1000,  T);
+	q->act8b   = EZ(t->act8b   * 1000,  T);
+	q->rec8b   = EZ(t->rec8b   * 1000,  T);
+	q->cyc8b   = EZ(t->cyc8b   * 1000,  T);
+	q->active  = EZ(t->active  * 1000,  T);
+	q->recover = EZ(t->recover * 1000,  T);
+	q->cycle   = EZ(t->cycle   * 1000,  T);
+	q->udma    = EZ(t->udma    * 1000, UT);
 }
 
 static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux.orig/drivers/ide/ide.c	2002-02-25 19:37:57.000000000 +0000
+++ linux/drivers/ide/ide.c	2002-07-20 01:08:35.000000000 +0000
@@ -149,6 +149,7 @@
 #include <linux/ide.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/completion.h>
+#include <linux/reboot.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -162,6 +163,16 @@
 #include <linux/kmod.h>
 #endif /* CONFIG_KMOD */
 
+#ifdef CONFIG_IDE_TASKFILE_IO
+#  define __TASKFILE__IO
+#else /* CONFIG_IDE_TASKFILE_IO */
+#  undef __TASKFILE__IO
+#endif /* CONFIG_IDE_TASKFILE_IO */
+
+#ifdef __TASKFILE__IO
+#else /* !__TASKFILE__IO */
+#endif /* __TASKFILE__IO */
+
 /* default maximum number of failures */
 #define IDE_DEFAULT_MAX_FAILURES 	1
 
@@ -515,7 +526,8 @@
 /*
  * Needed for PCI irq sharing
  */
-static inline int drive_is_ready (ide_drive_t *drive)
+//static inline
+int drive_is_ready (ide_drive_t *drive)
 {
 	byte stat = 0;
 	if (drive->waiting_for_dma)
@@ -809,7 +821,11 @@
 	 */
 	OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG);	/* set SRST and nIEN */
 	udelay(10);			/* more than enough time */
-	OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG);	/* clear SRST, leave nIEN */
+	if (drive->quirk_list == 2) {
+		OUT_BYTE(drive->ctl,IDE_CONTROL_REG);	/* clear SRST and nIEN */
+	} else {
+		OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG);	/* clear SRST, leave nIEN */
+	}
 	udelay(10);			/* more than enough time */
 	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
 	ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
@@ -836,6 +852,13 @@
 	return do_reset1 (drive, 0);
 }
 
+static inline u32 read_24 (ide_drive_t *drive)
+{
+	return  (IN_BYTE(IDE_HCYL_REG)<<16) |
+		(IN_BYTE(IDE_LCYL_REG)<<8) |
+		 IN_BYTE(IDE_SECTOR_REG);
+}
+
 /*
  * Clean up after success/failure of an explicit drive cmd
  */
@@ -848,26 +871,66 @@
 	rq = HWGROUP(drive)->rq;
 	spin_unlock_irqrestore(&io_request_lock, flags);
 
-	if (rq->cmd == IDE_DRIVE_CMD) {
-		byte *args = (byte *) rq->buffer;
-		rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-		if (args) {
-			args[0] = stat;
-			args[1] = err;
-			args[2] = IN_BYTE(IDE_NSECTOR_REG);
-		}
-	} else if (rq->cmd == IDE_DRIVE_TASK) {
-		byte *args = (byte *) rq->buffer;
-		rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-		if (args) {
-			args[0] = stat;
-			args[1] = err;
-			args[2] = IN_BYTE(IDE_NSECTOR_REG);
-			args[3] = IN_BYTE(IDE_SECTOR_REG);
-			args[4] = IN_BYTE(IDE_LCYL_REG);
-			args[5] = IN_BYTE(IDE_HCYL_REG);
-			args[6] = IN_BYTE(IDE_SELECT_REG);
+	switch(rq->cmd) {
+		case IDE_DRIVE_CMD:
+		{
+			byte *args = (byte *) rq->buffer;
+			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+			if (args) {
+				args[0] = stat;
+				args[1] = err;
+				args[2] = IN_BYTE(IDE_NSECTOR_REG);
+			}
+			break;
 		}
+		case IDE_DRIVE_TASK:
+		{
+			byte *args = (byte *) rq->buffer;
+			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+			if (args) {
+				args[0] = stat;
+				args[1] = err;
+				args[2] = IN_BYTE(IDE_NSECTOR_REG);
+				args[3] = IN_BYTE(IDE_SECTOR_REG);
+				args[4] = IN_BYTE(IDE_LCYL_REG);
+				args[5] = IN_BYTE(IDE_HCYL_REG);
+				args[6] = IN_BYTE(IDE_SELECT_REG);
+			}
+			break;
+		}
+		case IDE_DRIVE_TASKFILE:
+		{
+			ide_task_t *args = (ide_task_t *) rq->special;
+			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+			if (args) {
+				if (args->tf_in_flags.b.data) {
+					unsigned short data			= IN_WORD(IDE_DATA_REG);
+					args->tfRegister[IDE_DATA_OFFSET]	= (data) & 0xFF;
+					args->hobRegister[IDE_DATA_OFFSET_HOB]	= (data >> 8) & 0xFF;
+				}
+				args->tfRegister[IDE_ERROR_OFFSET]   = err;
+				args->tfRegister[IDE_NSECTOR_OFFSET] = IN_BYTE(IDE_NSECTOR_REG);
+				args->tfRegister[IDE_SECTOR_OFFSET]  = IN_BYTE(IDE_SECTOR_REG);
+				args->tfRegister[IDE_LCYL_OFFSET]    = IN_BYTE(IDE_LCYL_REG);
+				args->tfRegister[IDE_HCYL_OFFSET]    = IN_BYTE(IDE_HCYL_REG);
+				args->tfRegister[IDE_SELECT_OFFSET]  = IN_BYTE(IDE_SELECT_REG);
+				args->tfRegister[IDE_STATUS_OFFSET]  = stat;
+
+				if ((drive->id->command_set_2 & 0x0400) &&
+				    (drive->id->cfs_enable_2 & 0x0400) &&
+				    (drive->addressing == 1)) {
+					OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
+					args->hobRegister[IDE_FEATURE_OFFSET_HOB] = IN_BYTE(IDE_FEATURE_REG);
+					args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = IN_BYTE(IDE_NSECTOR_REG);
+					args->hobRegister[IDE_SECTOR_OFFSET_HOB]  = IN_BYTE(IDE_SECTOR_REG);
+					args->hobRegister[IDE_LCYL_OFFSET_HOB]    = IN_BYTE(IDE_LCYL_REG);
+					args->hobRegister[IDE_HCYL_OFFSET_HOB]    = IN_BYTE(IDE_HCYL_REG);
+				}
+			}
+			break;
+		}
+		default:
+			break;
 	}
 	spin_lock_irqsave(&io_request_lock, flags);
 	blkdev_dequeue_request(rq);
@@ -917,19 +980,34 @@
 			if (err & MARK_ERR)	printk("AddrMarkNotFound ");
 			printk("}");
 			if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
-				byte cur = IN_BYTE(IDE_SELECT_REG);
-				if (cur & 0x40) {	/* using LBA? */
-					printk(", LBAsect=%ld", (unsigned long)
-					 ((cur&0xf)<<24)
-					 |(IN_BYTE(IDE_HCYL_REG)<<16)
-					 |(IN_BYTE(IDE_LCYL_REG)<<8)
-					 | IN_BYTE(IDE_SECTOR_REG));
+				if ((drive->id->command_set_2 & 0x0400) &&
+				    (drive->id->cfs_enable_2 & 0x0400) &&
+				    (drive->addressing == 1)) {
+					__u64 sectors = 0;
+					u32 low = 0, high = 0;
+					low = read_24(drive);
+					OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG);
+					high = read_24(drive);
+
+					sectors = ((__u64)high << 24) | low;
+					printk(", LBAsect=%llu, high=%d, low=%d",
+					       (unsigned long long) sectors,
+					       high, low);
 				} else {
-					printk(", CHS=%d/%d/%d",
-					 (IN_BYTE(IDE_HCYL_REG)<<8) +
-					  IN_BYTE(IDE_LCYL_REG),
-					  cur & 0xf,
-					  IN_BYTE(IDE_SECTOR_REG));
+					byte cur = IN_BYTE(IDE_SELECT_REG);
+					if (cur & 0x40) {	/* using LBA? */
+						printk(", LBAsect=%ld", (unsigned long)
+						 ((cur&0xf)<<24)
+						 |(IN_BYTE(IDE_HCYL_REG)<<16)
+						 |(IN_BYTE(IDE_LCYL_REG)<<8)
+						 | IN_BYTE(IDE_SECTOR_REG));
+					} else {
+						printk(", CHS=%d/%d/%d",
+						 (IN_BYTE(IDE_HCYL_REG)<<8) +
+						  IN_BYTE(IDE_LCYL_REG),
+						  cur & 0xf,
+						  IN_BYTE(IDE_SECTOR_REG));
+					}
 				}
 				if (HWGROUP(drive) && HWGROUP(drive)->rq)
 					printk(", sector=%ld", HWGROUP(drive)->rq->sector);
@@ -980,6 +1058,13 @@
 		ide_end_drive_cmd(drive, stat, err);
 		return ide_stopped;
 	}
+	if (rq->cmd == IDE_DRIVE_TASKFILE) {
+		rq->errors = 1;
+		ide_end_drive_cmd(drive, stat, err);
+//		ide_end_taskfile(drive, stat, err);
+		return ide_stopped;
+	}
+
 	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { /* other bits are useless when BUSY */
 		rq->errors |= ERROR_RESET;
 	} else {
@@ -1141,62 +1226,125 @@
  */
 static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
 {
-	byte *args = rq->buffer;
-	if (args && rq->cmd == IDE_DRIVE_TASK) {
-		byte sel;
+ 	switch(rq->cmd) {
+ 		case IDE_DRIVE_TASKFILE:
+ 		{
+ 			ide_task_t *args = rq->special;
+ 
+ 			if (!(args)) break;
+ 
+#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
+	{
+	printk(KERN_INFO "%s: ", drive->name);
+//	printk("TF.0=x%02x ", args->tfRegister[IDE_DATA_OFFSET]);
+	printk("TF.1=x%02x ", args->tfRegister[IDE_FEATURE_OFFSET]);
+	printk("TF.2=x%02x ", args->tfRegister[IDE_NSECTOR_OFFSET]);
+	printk("TF.3=x%02x ", args->tfRegister[IDE_SECTOR_OFFSET]);
+	printk("TF.4=x%02x ", args->tfRegister[IDE_LCYL_OFFSET]);
+	printk("TF.5=x%02x ", args->tfRegister[IDE_HCYL_OFFSET]);
+	printk("TF.6=x%02x ", args->tfRegister[IDE_SELECT_OFFSET]);
+	printk("TF.7=x%02x\n", args->tfRegister[IDE_COMMAND_OFFSET]);
+	printk(KERN_INFO "%s: ", drive->name);
+//	printk("HTF.0=x%02x ", args->hobRegister[IDE_DATA_OFFSET_HOB]);
+	printk("HTF.1=x%02x ", args->hobRegister[IDE_FEATURE_OFFSET_HOB]);
+	printk("HTF.2=x%02x ", args->hobRegister[IDE_NSECTOR_OFFSET_HOB]);
+	printk("HTF.3=x%02x ", args->hobRegister[IDE_SECTOR_OFFSET_HOB]);
+	printk("HTF.4=x%02x ", args->hobRegister[IDE_LCYL_OFFSET_HOB]);
+	printk("HTF.5=x%02x ", args->hobRegister[IDE_HCYL_OFFSET_HOB]);
+	printk("HTF.6=x%02x ", args->hobRegister[IDE_SELECT_OFFSET_HOB]);
+	printk("HTF.7=x%02x\n", args->hobRegister[IDE_CONTROL_OFFSET_HOB]);
+	}
+#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
+
+//			if (args->tf_out_flags.all == 0) {
+ 			do_taskfile(drive,
+ 				(struct hd_drive_task_hdr *)&args->tfRegister,
+				(struct hd_drive_hob_hdr *)&args->hobRegister,
+ 				args->handler);
+//			} else {
+//				return flagged_taskfile(drive, args);
+//			} 
+
+ 			if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
+ 			     (args->command_type == IDE_DRIVE_TASK_OUT)) &&
+			      args->prehandler && args->handler)
+				return args->prehandler(drive, rq);
+ 			return ide_started;
+ 		}
+ 		case IDE_DRIVE_TASK:
+ 		{
+ 			byte *args = rq->buffer;
+ 			byte sel;
+ 
+ 			if (!(args)) break;
 #ifdef DEBUG
-		printk("%s: DRIVE_TASK_CMD data=x%02x cmd=0x%02x fr=0x%02x ns=0x%02x sc=0x%02x lcyl=0x%02x hcyl=0x%02x sel=0x%02x\n",
-			drive->name,
-			args[0], args[1], args[2], args[3],
-			args[4], args[5], args[6], args[7]);
-#endif
-		OUT_BYTE(args[1], IDE_FEATURE_REG);
-		OUT_BYTE(args[3], IDE_SECTOR_REG);
-		OUT_BYTE(args[4], IDE_LCYL_REG);
-		OUT_BYTE(args[5], IDE_HCYL_REG);
-		sel = (args[6] & ~0x10);
-		if (drive->select.b.unit)
-			sel |= 0x10;
-		OUT_BYTE(sel, IDE_SELECT_REG);
-		ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
-		return ide_started;
-	} else if (args) {
+ 			printk("%s: DRIVE_TASK_CMD ", drive->name);
+ 			printk("cmd=0x%02x ", args[0]);
+ 			printk("fr=0x%02x ", args[1]);
+ 			printk("ns=0x%02x ", args[2]);
+ 			printk("sc=0x%02x ", args[3]);
+ 			printk("lcyl=0x%02x ", args[4]);
+ 			printk("hcyl=0x%02x ", args[5]);
+ 			printk("sel=0x%02x\n", args[6]);
+#endif
+ 			OUT_BYTE(args[1], IDE_FEATURE_REG);
+ 			OUT_BYTE(args[3], IDE_SECTOR_REG);
+ 			OUT_BYTE(args[4], IDE_LCYL_REG);
+ 			OUT_BYTE(args[5], IDE_HCYL_REG);
+ 			sel = (args[6] & ~0x10);
+ 			if (drive->select.b.unit)
+ 				sel |= 0x10;
+ 			OUT_BYTE(sel, IDE_SELECT_REG);
+ 			ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
+ 			return ide_started;
+ 		}
+ 		case IDE_DRIVE_CMD:
+ 		{
+ 			byte *args = rq->buffer;
+ 
+ 			if (!(args)) break;
 #ifdef DEBUG
-		printk("%s: DRIVE_CMD cmd=0x%02x sc=0x%02x fr=0x%02x xx=0x%02x\n",
-		 drive->name, args[0], args[1], args[2], args[3]);
+ 			printk("%s: DRIVE_CMD ", drive->name);
+ 			printk("cmd=0x%02x ", args[0]);
+ 			printk("sc=0x%02x ", args[1]);
+ 			printk("fr=0x%02x ", args[2]);
+ 			printk("xx=0x%02x\n", args[3]);
 #endif
-		if (args[0] == WIN_SMART) {
-			OUT_BYTE(0x4f, IDE_LCYL_REG);
-			OUT_BYTE(0xc2, IDE_HCYL_REG);
-			OUT_BYTE(args[2],IDE_FEATURE_REG);
-			OUT_BYTE(args[1],IDE_SECTOR_REG);
-			ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
-			return ide_started;
-		}
-		OUT_BYTE(args[2],IDE_FEATURE_REG);
-		ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
-		return ide_started;
-	} else {
-		/*
-		 * NULL is actually a valid way of waiting for
-		 * all current requests to be flushed from the queue.
-		 */
+ 			if (args[0] == WIN_SMART) {
+ 				OUT_BYTE(0x4f, IDE_LCYL_REG);
+ 				OUT_BYTE(0xc2, IDE_HCYL_REG);
+ 				OUT_BYTE(args[2],IDE_FEATURE_REG);
+ 				OUT_BYTE(args[1],IDE_SECTOR_REG);
+ 				ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
+ 				return ide_started;
+ 			}
+ 			OUT_BYTE(args[2],IDE_FEATURE_REG);
+ 			ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
+ 			return ide_started;
+ 		}
+ 		default:
+ 			break;
+ 	}
+ 	/*
+ 	 * NULL is actually a valid way of waiting for
+ 	 * all current requests to be flushed from the queue.
+ 	 */
 #ifdef DEBUG
-		printk("%s: DRIVE_CMD (null)\n", drive->name);
+ 	printk("%s: DRIVE_CMD (null)\n", drive->name);
 #endif
-		ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
-		return ide_stopped;
-	}
+ 	ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
+ 	return ide_stopped;
 }
 
 /*
  * start_request() initiates handling of a new I/O request
+ * needed to reverse the perverted changes anonymously made back
+ * 2.3.99-pre6
  */
-static ide_startstop_t start_request (ide_drive_t *drive)
+static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
 {
 	ide_startstop_t startstop;
 	unsigned long block, blockend;
-	struct request *rq = blkdev_entry_next_request(&drive->queue.queue_head);
 	unsigned int minor = MINOR(rq->rq_dev), unit = minor >> PARTN_BITS;
 	ide_hwif_t *hwif = HWIF(drive);
 
@@ -1245,8 +1393,13 @@
 		return startstop;
 	}
 	if (!drive->special.all) {
-		if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) {
-			return execute_drive_cmd(drive, rq);
+		switch(rq->cmd) {
+			case IDE_DRIVE_CMD:
+			case IDE_DRIVE_TASK:
+			case IDE_DRIVE_TASKFILE:
+				return execute_drive_cmd(drive, rq);
+			default:
+				break;
 		}
 		if (drive->driver != NULL) {
 			return (DRIVER(drive)->do_request(drive, rq, block));
@@ -1267,13 +1420,15 @@
 {
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 	unsigned long flags;
+	struct request *rq;
 
 	spin_lock_irqsave(&io_request_lock, flags);
 	hwgroup->handler = NULL;
 	del_timer(&hwgroup->timer);
+	rq = hwgroup->rq;
 	spin_unlock_irqrestore(&io_request_lock, flags);
 
-	return start_request(drive);
+	return start_request(drive, rq);
 }
 
 /*
@@ -1370,10 +1525,11 @@
 /* --BenH: made non-static as ide-pmac.c uses it to kick the hwgroup back
  *         into life on wakeup from machine sleep.
  */ 
-void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
+void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
 {
 	ide_drive_t	*drive;
 	ide_hwif_t	*hwif;
+	struct request	*rq;
 	ide_startstop_t	startstop;
 
 	ide_get_lock(&ide_lock, ide_intr, hwgroup);	/* for atari only: POSSIBLY BROKEN HERE(?) */
@@ -1426,7 +1582,8 @@
 
 		if ( drive->queue.plugged )	/* paranoia */
 			printk("%s: Huh? nuking plugged queue\n", drive->name);
-		hwgroup->rq = blkdev_entry_next_request(&drive->queue.queue_head);
+
+		rq = hwgroup->rq = blkdev_entry_next_request(&drive->queue.queue_head);
 		/*
 		 * Some systems have trouble with IDE IRQs arriving while
 		 * the driver is still setting things up.  So, here we disable
@@ -1439,7 +1596,7 @@
 			disable_irq_nosync(hwif->irq);
 		spin_unlock(&io_request_lock);
 		ide__sti();	/* allow other IRQs while we start this request */
-		startstop = start_request(drive);
+		startstop = start_request(drive, rq);
 		spin_lock_irq(&io_request_lock);
 		if (masked_irq && hwif->irq != masked_irq)
 			enable_irq(hwif->irq);
@@ -1619,7 +1776,7 @@
  * drive is ready to accept one, in which case we know the drive is not
  * trying to interrupt us.  And ide_set_handler() is always invoked before
  * completing the issuance of any new drive command, so we will not be
- * accidently invoked as a result of any valid command completion interrupt.
+ * accidentally invoked as a result of any valid command completion interrupt.
  *
  */
 static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
@@ -1867,7 +2024,7 @@
 	ide_drive_t *drive;
 	ide_hwgroup_t *hwgroup;
 	unsigned int p, major, minor;
-	long flags;
+	unsigned long flags;
 
 	if ((drive = get_info_ptr(i_rdev)) == NULL)
 		return -ENODEV;
@@ -1967,6 +2124,10 @@
 			(void) request_module("ide-tape");
 		if (drive->media == ide_floppy)
 			(void) request_module("ide-floppy");
+#if defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI)
+		if (drive->media == ide_scsi)
+			(void) request_module("ide-scsi");
+#endif /* defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI) */
 	}
 #endif /* CONFIG_KMOD */
 	while (drive->busy)
@@ -2295,6 +2456,7 @@
 	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
 	hwif->irq = hw->irq;
 	hwif->noprobe = 0;
+	hwif->chipset = hw->chipset;
 
 	if (!initializing) {
 		ide_probe_module();
@@ -2590,6 +2752,61 @@
 	return((int) ((!system_bus_speed) ? ide_system_bus_speed() : system_bus_speed ));
 }
 
+int ide_reinit_drive (ide_drive_t *drive)
+{
+	switch (drive->media) {
+#ifdef CONFIG_BLK_DEV_IDECD
+		case ide_cdrom:
+		{
+			extern int ide_cdrom_reinit(ide_drive_t *drive);
+			if (ide_cdrom_reinit(drive))
+				return 1;
+			break;
+		}
+#endif /* CONFIG_BLK_DEV_IDECD */
+#ifdef CONFIG_BLK_DEV_IDEDISK
+		case ide_disk:
+		{
+			extern int idedisk_reinit(ide_drive_t *drive);
+			if (idedisk_reinit(drive))
+				return 1;
+			break;
+		}
+#endif /* CONFIG_BLK_DEV_IDEDISK */
+#ifdef CONFIG_BLK_DEV_IDEFLOPPY
+		case ide_floppy:
+		{
+			extern int idefloppy_reinit(ide_drive_t *drive);
+			if (idefloppy_reinit(drive))
+				return 1;
+			break;
+		}
+#endif /* CONFIG_BLK_DEV_IDEFLOPPY */
+#ifdef CONFIG_BLK_DEV_IDETAPE
+		case ide_tape:
+		{
+			extern int idetape_reinit(ide_drive_t *drive);
+			if (idetape_reinit(drive))
+				return 1;
+			break;
+		}
+#endif /* CONFIG_BLK_DEV_IDETAPE */
+#ifdef CONFIG_BLK_DEV_IDESCSI
+/*
+ *              {
+ *                      extern int idescsi_reinit(ide_drive_t *drive);
+ *                      if (idescsi_reinit(drive))
+ *                              return 1;
+ *                      break;
+ * }
+ */
+#endif /* CONFIG_BLK_DEV_IDESCSI */
+		default:
+			return 1;
+	}
+	return 0;
+}
+
 static int ide_ioctl (struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
@@ -2681,16 +2898,47 @@
 					drive->nice1		<<	IDE_NICE_1		|
 					drive->nice2		<<	IDE_NICE_2,
 					(long *) arg);
+
+#ifdef CONFIG_IDE_TASK_IOCTL
+		case HDIO_DRIVE_TASKFILE:
+		        if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+				return -EACCES;
+			switch(drive->media) {
+				case ide_disk:
+					return ide_taskfile_ioctl(drive, inode, file, cmd, arg);
+#ifdef CONFIG_PKT_TASK_IOCTL
+				case ide_cdrom:
+				case ide_tape:
+				case ide_floppy:
+					return pkt_taskfile_ioctl(drive, inode, file, cmd, arg);
+#endif /* CONFIG_PKT_TASK_IOCTL */
+				default:
+					return -ENOMSG;
+			}
+#endif /* CONFIG_IDE_TASK_IOCTL */
+
 		case HDIO_DRIVE_CMD:
 		{
 			byte args[4], *argbuf = args;
 			byte xfer_rate = 0;
 			int argsize = 4;
-			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES;
+			ide_task_t tfargs;
+
+			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+				return -EACCES;
 			if (NULL == (void *) arg)
 				return ide_do_drive_cmd(drive, &rq, ide_wait);
 			if (copy_from_user(args, (void *)arg, 4))
 				return -EFAULT;
+
+			tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
+			tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
+			tfargs.tfRegister[IDE_SECTOR_OFFSET]  = args[1];
+			tfargs.tfRegister[IDE_LCYL_OFFSET]    = 0x00;
+			tfargs.tfRegister[IDE_HCYL_OFFSET]    = 0x00;
+			tfargs.tfRegister[IDE_SELECT_OFFSET]  = 0x00;
+			tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
+
 			if (args[3]) {
 				argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
 				argbuf = kmalloc(argsize, GFP_KERNEL);
@@ -2699,9 +2947,9 @@
 				memcpy(argbuf, args, 4);
 			}
 
-			if (set_transfer(drive, args[0], args[1], args[2])) {
+			if (set_transfer(drive, &tfargs)) {
 				xfer_rate = args[1];
-				if (ide_ata66_check(drive, args[0], args[1], args[2]))
+				if (ide_ata66_check(drive, &tfargs))
 					goto abort;
 			}
 
@@ -2761,7 +3009,24 @@
 			drive->nice1 = (arg >> IDE_NICE_1) & 1;
 			return 0;
 		case HDIO_DRIVE_RESET:
+		{
+			unsigned long flags;
+			ide_hwgroup_t *hwgroup = HWGROUP(drive);
+
 			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+#if 1
+			spin_lock_irqsave(&io_request_lock, flags);
+			if (hwgroup->handler != NULL) {
+				printk("%s: ide_set_handler: handler not null; %p\n", drive->name, hwgroup->handler);
+				(void) hwgroup->handler(drive);
+//				hwgroup->handler = NULL;
+//				hwgroup->expiry	= NULL;
+				hwgroup->timer.expires = jiffies + 0;;
+				del_timer(&hwgroup->timer);
+			}
+			spin_unlock_irqrestore(&io_request_lock, flags);
+
+#endif
 			(void) ide_do_reset(drive);
 			if (drive->suspend_reset) {
 /*
@@ -2776,7 +3041,7 @@
 				return ide_revalidate_disk(inode->i_rdev);
 			}
 			return 0;
-
+		}
 		case BLKROSET:
 		case BLKROGET:
 		case BLKFLSBUF:
@@ -2799,7 +3064,7 @@
 			if (!capable(CAP_SYS_ADMIN))
 				return -EACCES;
 			if (HWIF(drive)->busproc)
-				HWIF(drive)->busproc(HWIF(drive), arg);
+				HWIF(drive)->busproc(drive, (int)arg);
 			return 0;
 
 		default:
@@ -3351,6 +3616,12 @@
 		pmac_ide_probe();
 	}
 #endif /* CONFIG_BLK_DEV_IDE_PMAC */
+#ifdef CONFIG_BLK_DEV_IDE_SWARM
+	{
+		extern void swarm_ide_probe(void);
+		swarm_ide_probe();
+	}
+#endif /* CONFIG_BLK_DEV_IDE_SWARM */
 #ifdef CONFIG_BLK_DEV_IDE_ICSIDE
 	{
 		extern void icside_init(void);
@@ -3460,6 +3731,16 @@
 	return ide_unregister_subdriver(drive);
 }
 
+static int default_standby (ide_drive_t *drive)
+{
+	return 0;
+}
+
+static int default_flushcache (ide_drive_t *drive)
+{
+	return 0;
+}
+
 static ide_startstop_t default_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
 {
 	ide_end_request(0, HWGROUP(drive));
@@ -3510,7 +3791,7 @@
 	return ide_stopped;
 }
 
-static int default_driver_reinit (ide_drive_t *drive)
+static int default_reinit (ide_drive_t *drive)
 {
 	printk(KERN_ERR "%s: does not support hotswap of device class !\n", drive->name);
 
@@ -3522,6 +3803,8 @@
 	ide_driver_t *d = drive->driver;
 
 	if (d->cleanup == NULL)		d->cleanup = default_cleanup;
+	if (d->standby == NULL)		d->standby = default_standby;
+	if (d->flushcache == NULL)	d->flushcache = default_flushcache;
 	if (d->do_request == NULL)	d->do_request = default_do_request;
 	if (d->end_request == NULL)	d->end_request = default_end_request;
 	if (d->ioctl == NULL)		d->ioctl = default_ioctl;
@@ -3531,7 +3814,7 @@
 	if (d->pre_reset == NULL)	d->pre_reset = default_pre_reset;
 	if (d->capacity == NULL)	d->capacity = default_capacity;
 	if (d->special == NULL)		d->special = default_special;
-	if (d->driver_reinit == NULL)	d->driver_reinit = default_driver_reinit;
+	if (d->reinit == NULL)		d->reinit = default_reinit;
 }
 
 ide_drive_t *ide_scan_devices (byte media, const char *name, ide_driver_t *driver, int n)
@@ -3676,6 +3959,7 @@
 EXPORT_SYMBOL(ide_output_data);
 EXPORT_SYMBOL(atapi_input_bytes);
 EXPORT_SYMBOL(atapi_output_bytes);
+EXPORT_SYMBOL(drive_is_ready);
 EXPORT_SYMBOL(ide_set_handler);
 EXPORT_SYMBOL(ide_dump_status);
 EXPORT_SYMBOL(ide_error);
@@ -3698,6 +3982,8 @@
 EXPORT_SYMBOL(ide_remove_proc_entries);
 EXPORT_SYMBOL(proc_ide_read_geometry);
 EXPORT_SYMBOL(create_proc_ide_interfaces);
+EXPORT_SYMBOL(recreate_proc_ide_device);
+EXPORT_SYMBOL(destroy_proc_ide_device);
 #endif
 EXPORT_SYMBOL(ide_add_setting);
 EXPORT_SYMBOL(ide_remove_setting);
@@ -3712,6 +3998,54 @@
 
 EXPORT_SYMBOL(system_bus_clock);
 
+EXPORT_SYMBOL(ide_reinit_drive);
+
+static int ide_notify_reboot (struct notifier_block *this, unsigned long event, void *x)
+{
+	ide_hwif_t *hwif;
+	ide_drive_t *drive;
+	int i, unit;
+
+	switch (event) {
+		case SYS_HALT:
+		case SYS_POWER_OFF:
+		case SYS_RESTART:
+			break;
+		default:
+			return NOTIFY_DONE;
+	}
+
+	printk("flushing ide devices: ");
+
+	for (i = 0; i < MAX_HWIFS; i++) {
+		hwif = &ide_hwifs[i];
+		if (!hwif->present)
+			continue;
+		for (unit = 0; unit < MAX_DRIVES; ++unit) {
+			drive = &hwif->drives[unit];
+			if (!drive->present)
+				continue;
+
+			/* set the drive to standby */
+			printk("%s ", drive->name);
+			if (event != SYS_RESTART)
+				if (drive->driver != NULL && DRIVER(drive)->standby(drive))
+				continue;
+
+			if (drive->driver != NULL && DRIVER(drive)->cleanup(drive))
+				continue;
+		}
+	}
+	printk("\n");
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ide_notifier = {
+	ide_notify_reboot,
+	NULL,
+	5
+};
+
 /*
  * This is gets invoked once during initialization, to set *everything* up
  */
@@ -3739,6 +4073,7 @@
 			ide_geninit(hwif);
 	}
 
+	register_reboot_notifier(&ide_notifier);
 	return 0;
 }
 
@@ -3771,6 +4106,7 @@
 {
 	int index;
 
+	unregister_reboot_notifier(&ide_notifier);
 	for (index = 0; index < MAX_HWIFS; ++index) {
 		ide_unregister(index);
 #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/it8172.c linux/drivers/ide/it8172.c
--- linux.orig/drivers/ide/it8172.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/ide/it8172.c	2002-07-20 01:08:24.000000000 +0000
@@ -50,7 +50,7 @@
 #if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING)
 static byte it8172_dma_2_pio (byte xfer_rate);
 static int it8172_tune_chipset (ide_drive_t *drive, byte speed);
-static int it8172_config_drive_for_dma (ide_drive_t *drive);
+static int it8172_config_chipset_for_dma (ide_drive_t *drive);
 static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
 #endif
 unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name);
@@ -60,38 +60,44 @@
 static void it8172_tune_drive (ide_drive_t *drive, byte pio)
 {
     unsigned long flags;
-    u16 master_data;
-    u32 slave_data;
+    u16 drive_enables;
+    u32 drive_timing;
     int is_slave	= (&HWIF(drive)->drives[1] == drive);
-    int master_port	= 0x40;
-    int slave_port      = 0x44;
     
-    pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
-    pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
-    pci_read_config_dword(HWIF(drive)->pci_dev, slave_port, &slave_data);
+    pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+    pci_read_config_word(HWIF(drive)->pci_dev, 0x40, &drive_enables);
+    pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, &drive_timing);
 
     /*
      * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
      * are being left at the default values of 8 PCI clocks (242 nsec
      * for a 33 MHz clock). These can be safely shortened at higher
-     * PIO modes.
+     * PIO modes. The DIOR/DIOW pulse width and recovery times only
+     * apply to PIO modes, not to the DMA modes.
      */
     
+    /*
+     * Enable port 0x44. The IT8172G spec is confused; it calls
+     * this register the "Slave IDE Timing Register", but in fact,
+     * it controls timing for both master and slave drives.
+     */
+    drive_enables |= 0x4000;
+
     if (is_slave) {
-	master_data |= 0x4000;
+	drive_enables &= 0xc006;
 	if (pio > 1)
-	    /* enable PPE and IE */
-	    master_data |= 0x0060;
+	    /* enable prefetch and IORDY sample-point */
+	    drive_enables |= 0x0060;
     } else {
-	master_data &= 0xc060;
+	drive_enables &= 0xc060;
 	if (pio > 1)
-	    /* enable PPE and IE */
-	    master_data |= 0x0006;
+	    /* enable prefetch and IORDY sample-point */
+	    drive_enables |= 0x0006;
     }
 
     save_flags(flags);
     cli();
-    pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data);
+    pci_write_config_word(HWIF(drive)->pci_dev, 0x40, drive_enables);
     restore_flags(flags);
 }
 
@@ -160,6 +166,7 @@
     case XFER_UDMA_0:	u_speed = 0 << (drive->dn * 4); break;
     case XFER_MW_DMA_2:
     case XFER_MW_DMA_1:
+    case XFER_MW_DMA_0:
     case XFER_SW_DMA_2:	break;
     default:		return -1;
     }
@@ -182,7 +189,7 @@
     return err;
 }
 
-static int it8172_config_drive_for_dma (ide_drive_t *drive)
+static int it8172_config_chipset_for_dma (ide_drive_t *drive)
 {
     struct hd_driveid *id = drive->id;
     byte speed;
@@ -201,10 +208,12 @@
 	speed = XFER_MW_DMA_2;
     } else if (id->dma_mword & 0x0002) {
 	speed = XFER_MW_DMA_1;
+    } else if (id->dma_mword & 0x0001) {
+	speed = XFER_MW_DMA_0;
     } else if (id->dma_1word & 0x0004) {
 	speed = XFER_SW_DMA_2;
     } else {
-	speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+	speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 4, NULL);
     }
 
     (void) it8172_tune_chipset(drive, speed);
@@ -220,7 +229,7 @@
 {
     switch (func) {
     case ide_dma_check:
-	return ide_dmaproc((ide_dma_action_t)it8172_config_drive_for_dma(drive),
+	return ide_dmaproc((ide_dma_action_t)it8172_config_chipset_for_dma(drive),
 			   drive);
     default :
 	break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux.orig/drivers/ide/pdc202xx.c	2001-11-14 19:44:03.000000000 +0000
+++ linux/drivers/ide/pdc202xx.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,34 +1,59 @@
 /*
- *  linux/drivers/ide/pdc202xx.c	Version 0.30	Mar. 18, 2000
+ *  linux/drivers/ide/pdc202xx.c	Version 0.32	Feb. 27, 2002
  *
  *  Copyright (C) 1998-2000	Andre Hedrick <andre@linux-ide.org>
  *  May be copied or modified under the terms of the GNU General Public License
  *
- *  Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
+ *  Promise Ultra66 cards with BIOS v1.11 this
  *  compiled into the kernel if you have more than one card installed.
- *  Note that BIOS v1.29 is reported to fix the problem.  Since this is
- *  safe chipset tuning, including this support is harmless
  *
- *  Promise Ultra66 cards with BIOS v1.11 this
+ *  Promise Ultra100 cards with BIOS v2.01 this
  *  compiled into the kernel if you have more than one card installed.
  *
- *  Promise Ultra100 cards.
+ *  Promise Ultra100TX2 with BIOS v2.10 & Ultra133TX2 with BIOS v2.20
+ *  support 8 hard drives on UDMA mode.
  *
- *  The latest chipset code will support the following ::
- *  Three Ultra33 controllers and 12 drives.
- *  8 are UDMA supported and 4 are limited to DMA mode 2 multi-word.
- *  The 8/4 ratio is a BIOS code limit by promise.
+ *  Linux kernel will misunderstand FastTrak ATA-RAID series as Ultra
+ *  IDE Controller, UNLESS you enable "CONFIG_PDC202XX_FORCE"
+ *  That's you can use FastTrak ATA-RAID controllers as IDE controllers.
  *
- *  UNLESS you enable "CONFIG_PDC202XX_BURST"
+ *  History :
+ *  05/22/01    v1.20 b1
+ *           (1) support PDC20268
+ *           (2) fix cable judge function
+ *  08/22/01    v1.20 b2
+ *           (1) support ATA-133 PDC20269/75
+ *           (2) support UDMA Mode 6
+ *           (3) fix proc report information
+ *           (4) set ATA133 timing
+ *           (5) fix ultra dma bit 14 selectable
+ *           (6) support 32bit LBA
+ *  09/11/01    v1.20 b3 
+ *           (1) fix eighty_ninty_three()
+ *           (2) fix offset address 0x1c~0x1f
+ *  10/30/01    v1.20 b4
+ *           (1) fix 48bit LBA HOB bit
+ *           (2) force rescan drive under PIO modes if need
+ *  11/02/01    v1.20.0.5
+ *           (1) could be patched with ext3 filesystem code
+ *  11/06/01    v1.20.0.6
+ *           (1) fix LBA48 drive running without Promise controllers
+ *           (2) fix LBA48 drive running under PIO modes
+ *  01/28/02    v1.20.0.6
+ *           (1) release for linux IDE Group kernel 2.4.18
+ *           (2) add version and controller info to proc
+ *  05/23/02    v1.20.0.7
+ *           (1) disable PDC20262 running with 48bit
+ *           (2) Add quirk drive lists for PDC20265/67
  *
- */
-
-/*
- *  Portions Copyright (C) 1999 Promise Technology, Inc.
- *  Author: Frank Tiernan (frankt@promise.com)
+ *  Copyright (C) 1999-2002 Promise Technology, Inc.
+ *  Author: Frank Tiernan <frankt@promise.com>
+ *          PROMISE pdc202xx IDE Controller driver MAINTAINERS
  *  Released under terms of General Public License
  */
-
+ 
+#define VERSION	"1.20.0.7"
+#define VERDATE "2002-05-23"
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -65,41 +90,8 @@
 extern int (*pdc202xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 extern char *ide_media_verbose(ide_drive_t *);
 static struct pci_dev *bmide_dev;
-
-char *pdc202xx_pio_verbose (u32 drive_pci)
-{
-	if ((drive_pci & 0x000ff000) == 0x000ff000) return("NOTSET");
-	if ((drive_pci & 0x00000401) == 0x00000401) return("PIO 4");
-	if ((drive_pci & 0x00000602) == 0x00000602) return("PIO 3");
-	if ((drive_pci & 0x00000803) == 0x00000803) return("PIO 2");
-	if ((drive_pci & 0x00000C05) == 0x00000C05) return("PIO 1");
-	if ((drive_pci & 0x00001309) == 0x00001309) return("PIO 0");
-	return("PIO ?");
-}
-
-char *pdc202xx_dma_verbose (u32 drive_pci)
-{
-	if ((drive_pci & 0x00036000) == 0x00036000) return("MWDMA 2");
-	if ((drive_pci & 0x00046000) == 0x00046000) return("MWDMA 1");
-	if ((drive_pci & 0x00056000) == 0x00056000) return("MWDMA 0");
-	if ((drive_pci & 0x00056000) == 0x00056000) return("SWDMA 2");
-	if ((drive_pci & 0x00068000) == 0x00068000) return("SWDMA 1");
-	if ((drive_pci & 0x000BC000) == 0x000BC000) return("SWDMA 0");
-	return("PIO---");
-}
-
-char *pdc202xx_ultra_verbose (u32 drive_pci, u16 slow_cable)
-{
-	if ((drive_pci & 0x000ff000) == 0x000ff000)
-		return("NOTSET");
-	if ((drive_pci & 0x00012000) == 0x00012000)
-		return((slow_cable) ? "UDMA 2" : "UDMA 4");
-	if ((drive_pci & 0x00024000) == 0x00024000)
-		return((slow_cable) ? "UDMA 1" : "UDMA 3");
-	if ((drive_pci & 0x00036000) == 0x00036000)
-		return("UDMA 0");
-	return(pdc202xx_dma_verbose(drive_pci));
-}
+static struct hd_driveid *id[4];
+static int speed_rate[4];
 
 static char * pdc202xx_info (char *buf, struct pci_dev *dev)
 {
@@ -107,8 +99,10 @@
 
 	u32 bibma  = pci_resource_start(dev, 4);
 	u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0;
-	u16 reg50h = 0, pmask = (1<<10), smask = (1<<11);
-	u8 hi = 0, lo = 0, invalid_data_set = 0;
+	u16 reg50h = 0;
+	u16 word88 = 0;
+	int udmasel[4] = {0,0,0,0}, piosel[4] = {0,0,0,0};
+	int i = 0, hd = 0;
 
         /*
          * at that point bibma+0x2 et bibma+0xa are byte registers
@@ -120,10 +114,10 @@
 	u8 sc11	= inb_p((unsigned short)bibma + 0x11);
 	u8 sc1a	= inb_p((unsigned short)bibma + 0x1a);
 	u8 sc1b	= inb_p((unsigned short)bibma + 0x1b);
-	u8 sc1c	= inb_p((unsigned short)bibma + 0x1c); 
+	/* u8 sc1c	= inb_p((unsigned short)bibma + 0x1c); 
 	u8 sc1d	= inb_p((unsigned short)bibma + 0x1d);
 	u8 sc1e	= inb_p((unsigned short)bibma + 0x1e);
-	u8 sc1f	= inb_p((unsigned short)bibma + 0x1f);
+	u8 sc1f	= inb_p((unsigned short)bibma + 0x1f); */
 
 	pci_read_config_word(dev, 0x50, &reg50h);
 	pci_read_config_dword(dev, 0x60, &reg60h);
@@ -131,45 +125,35 @@
 	pci_read_config_dword(dev, 0x68, &reg68h);
 	pci_read_config_dword(dev, 0x6c, &reg6ch);
 
+	p+=sprintf(p, "\nPROMISE Ultra series driver Ver %s %s Adapter: ", VERSION, VERDATE);
 	switch(dev->device) {
+		case PCI_DEVICE_ID_PROMISE_20275:
+			p += sprintf(p, "MBUltra133\n");
+			break;
+		case PCI_DEVICE_ID_PROMISE_20269:
+			p += sprintf(p, "Ultra133 TX2\n");
+			break;
 		case PCI_DEVICE_ID_PROMISE_20268:
-		case PCI_DEVICE_ID_PROMISE_20268R:
-			p += sprintf(p, "\n                                PDC20268 TX2 Chipset.\n");
-			invalid_data_set = 1;
+			p += sprintf(p, "Ultra100 TX2\n");
 			break;
 		case PCI_DEVICE_ID_PROMISE_20267:
-			p += sprintf(p, "\n                                PDC20267 Chipset.\n");
+			p += sprintf(p, "Ultra100\n");
 			break;
 		case PCI_DEVICE_ID_PROMISE_20265:
-			p += sprintf(p, "\n                                PDC20265 Chipset.\n");
+			p += sprintf(p, "Ultra100 on M/B\n");
 			break;
 		case PCI_DEVICE_ID_PROMISE_20262:
-			p += sprintf(p, "\n                                PDC20262 Chipset.\n");
+			p += sprintf(p, "Ultra66\n");
 			break;
 		case PCI_DEVICE_ID_PROMISE_20246:
-			p += sprintf(p, "\n                                PDC20246 Chipset.\n");
+			p += sprintf(p, "Ultra33\n");
 			reg50h |= 0x0c00;
 			break;
 		default:
-			p += sprintf(p, "\n                                PDC202XX Chipset.\n");
+			p += sprintf(p, "Ultra Series\n");
 			break;
 	}
 
-	p += sprintf(p, "------------------------------- General Status ---------------------------------\n");
-	p += sprintf(p, "Burst Mode                           : %sabled\n", (sc1f & 0x01) ? "en" : "dis");
-	p += sprintf(p, "Host Mode                            : %s\n", (sc1f & 0x08) ? "Tri-Stated" : "Normal");
-	p += sprintf(p, "Bus Clocking                         : %s\n",
-		((sc1f & 0xC0) == 0xC0) ? "100 External" :
-		((sc1f & 0x80) == 0x80) ? "66 External" :
-		((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal");
-	p += sprintf(p, "IO pad select                        : %s mA\n",
-		((sc1c & 0x03) == 0x03) ? "10" :
-		((sc1c & 0x02) == 0x02) ? "8" :
-		((sc1c & 0x01) == 0x01) ? "6" :
-		((sc1c & 0x00) == 0x00) ? "4" : "??");
-	SPLIT_BYTE(sc1e, hi, lo);
-	p += sprintf(p, "Status Polling Period                : %d\n", hi);
-	p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo);
 	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
 	p += sprintf(p, "                %s                         %s\n",
 		(c0&0x80)?"disabled":"enabled ",
@@ -177,47 +161,38 @@
 	p += sprintf(p, "66 Clocking     %s                         %s\n",
 		(sc11&0x02)?"enabled ":"disabled",
 		(sc11&0x08)?"enabled ":"disabled");
-	p += sprintf(p, "           Mode %s                      Mode %s\n",
+	p += sprintf(p, "Mode            %s                           %s\n",
 		(sc1a & 0x01) ? "MASTER" : "PCI   ",
 		(sc1b & 0x01) ? "MASTER" : "PCI   ");
-	if (!(invalid_data_set))
-		p += sprintf(p, "                %s                     %s\n",
-			(sc1d & 0x08) ? "Error       " :
-			((sc1d & 0x05) == 0x05) ? "Not My INTR " :
-			(sc1d & 0x04) ? "Interrupting" :
-			(sc1d & 0x02) ? "FIFO Full   " :
-			(sc1d & 0x01) ? "FIFO Empty  " : "????????????",
-			(sc1d & 0x80) ? "Error       " :
-			((sc1d & 0x50) == 0x50) ? "Not My INTR " :
-			(sc1d & 0x40) ? "Interrupting" :
-			(sc1d & 0x20) ? "FIFO Full   " :
-			(sc1d & 0x10) ? "FIFO Empty  " : "????????????");
 	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
 	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
-		(c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no ");
-	if (!(invalid_data_set))
-		p += sprintf(p, "DMA Mode:       %s           %s          %s            %s\n",
-			pdc202xx_ultra_verbose(reg60h, (reg50h & pmask)),
-			pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)),
-			pdc202xx_ultra_verbose(reg68h, (reg50h & smask)),
-			pdc202xx_ultra_verbose(reg6ch, (reg50h & smask)));
-	if (!(invalid_data_set))
-		p += sprintf(p, "PIO Mode:       %s            %s           %s            %s\n",
-			pdc202xx_pio_verbose(reg60h),
-			pdc202xx_pio_verbose(reg64h),
-			pdc202xx_pio_verbose(reg68h),
-			pdc202xx_pio_verbose(reg6ch));
+		(id[0]!=NULL && (c0&0x20))?"yes":"no ",(id[1]!=NULL && (c0&0x40))?"yes":"no ",
+		(id[2]!=NULL && (c1&0x20))?"yes":"no ",(id[3]!=NULL && (c1&0x40))?"yes":"no ");
+	for( hd = 0; hd < 4 ; hd++) {
+		if (id[hd] == NULL)
+			continue;
+		word88 = id[hd]->dma_ultra;
+		for ( i = 7 ; i >= 0 ; i--)
+			if (word88 >> (i+8)) {
+				udmasel[hd] = i;	/* get select UDMA mode */
+				break;
+			}
+		piosel[hd] = (id[hd]->eide_pio_modes >= 0x02) ? 4 : 3;
+        }
+	p += sprintf(p, "UDMA Mode:      %d                %d               %d                 %d\n",
+		udmasel[0], udmasel[1], udmasel[2], udmasel[3]);
+	p += sprintf(p, "PIO Mode:       %d                %d               %d                 %d\n",
+		piosel[0], piosel[1], piosel[2], piosel[3]);
 #if 0
 	p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n");
 #endif
-	if (invalid_data_set)
-		p += sprintf(p, "--------------- Cannot Decode HOST ---------------\n");
 	return (char *)p;
 }
 
 static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
+	
 	p = pdc202xx_info(buffer, bmide_dev);
 	return p-buffer;	/* => must be less than 4k! */
 }
@@ -228,7 +203,9 @@
 const char *pdc_quirk_drives[] = {
 	"QUANTUM FIREBALLlct08 08",
 	"QUANTUM FIREBALLP KA6.4",
+	"QUANTUM FIREBALLP KA9.1",
 	"QUANTUM FIREBALLP LM20.4",
+	"QUANTUM FIREBALLP KX13.6",
 	"QUANTUM FIREBALLP KX20.5",
 	"QUANTUM FIREBALLP KX27.3",
 	"QUANTUM FIREBALLP LM20.5",
@@ -373,7 +350,7 @@
 	struct pci_dev *dev	= hwif->pci_dev;
 
 	unsigned int		drive_conf;
-	int			err;
+	int			err = 0, i = 0, j = hwif->channel ? 2 : 0 ;
 	byte			drive_pci, AP, BP, CP, DP;
 	byte			TA = 0, TB = 0, TC = 0;
 
@@ -387,9 +364,6 @@
 
 	if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))	return -1;
 
-	if (dev->device == PCI_DEVICE_ID_PROMISE_20268)
-		goto skip_register_hell;
-
 	pci_read_config_dword(dev, drive_pci, &drive_conf);
 	pci_read_config_byte(dev, (drive_pci), &AP);
 	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
@@ -430,8 +404,13 @@
 	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
 	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
 
+	for ( i = 0; i < 2; i++)
+		if (hwif->drives[i].present)
+	  		id[i+j] = hwif->drives[i].id;	/* get identify structs */
+
 	switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
+		/* case XFER_UDMA_6: */
 		case XFER_UDMA_5:
 		case XFER_UDMA_4:	TB = 0x20; TC = 0x01; break;	/* speed 8 == UDMA mode 4 */
 		case XFER_UDMA_3:	TB = 0x40; TC = 0x02; break;	/* speed 7 == UDMA mode 3 */
@@ -477,8 +456,6 @@
 	decode_registers(REG_D, DP);
 #endif /* PDC202XX_DECODE_REGISTER_INFO */
 
-skip_register_hell:
-
 	if (!drive->init_speed)
 		drive->init_speed = speed;
 	err = ide_config_drive_speed(drive, speed);
@@ -494,6 +471,174 @@
 	return err;
 }
 
+static int pdc202xx_new_tune_chipset (ide_drive_t *drive, byte speed)
+{
+	ide_hwif_t *hwif	= HWIF(drive);
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	unsigned long indexreg	= (hwif->dma_base + 1);
+	unsigned long datareg	= (hwif->dma_base + 3);
+#else
+	struct pci_dev *dev	= hwif->pci_dev;
+	unsigned long high_16	= pci_resource_start(dev, 4);
+	unsigned long indexreg	= high_16 + (hwif->channel ? 0x09 : 0x01);
+	unsigned long datareg	= (indexreg + 2);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+	byte thold		= 0x10;
+	byte adj		= (drive->dn%2) ? 0x08 : 0x00;
+	int set_speed		= 0, i=0, j=hwif->channel ? 2:0;
+	int                     err;
+
+	/* Setting tHOLD bit to 0 if using UDMA mode 2 */
+	if (speed == XFER_UDMA_2) {
+		OUT_BYTE((thold + adj), indexreg);
+		OUT_BYTE((IN_BYTE(datareg) & 0x7f), datareg);
+	}
+	
+	/* We need to set ATA133 timing if ATA133 drives exist */
+	if (speed>=XFER_UDMA_6)
+		set_speed=1;
+
+	if (!drive->init_speed)
+		drive->init_speed = speed;
+#if PDC202XX_DEBUG_DRIVE_INFO
+	printk("%s: Before set_feature = %s, word88 = %#x\n",
+		drive->name, ide_xfer_verbose(speed), drive->id->dma_ultra );
+#endif /* PDC202XX_DEBUG_DRIVE_INFO */
+	err = ide_config_drive_speed(drive, speed);
+	drive->current_speed = speed;	
+	for ( i = 0 ; i < 2 ; i++)
+		if (hwif->drives[i].present) {
+	  		id[i+j] = hwif->drives[i].id;	/* get identify structs */
+	 		speed_rate[i+j] = speed;	/* get current speed */
+	 	}
+	if (set_speed) {
+		for (i=0; i<4; i++) {
+			if (id[i]==NULL)
+				continue;
+			switch(speed_rate[i]) {
+#ifdef CONFIG_BLK_DEV_IDEDMA
+				case XFER_UDMA_6:
+					OUT_BYTE((0x10 + adj), indexreg);
+					OUT_BYTE(0x1a, datareg);
+					OUT_BYTE((0x11 + adj), indexreg);
+					OUT_BYTE(0x01, datareg);
+					OUT_BYTE((0x12 + adj), indexreg);
+					OUT_BYTE(0xcb, datareg);
+					break;
+				case XFER_UDMA_5:
+					OUT_BYTE((0x10 + adj), indexreg);
+					OUT_BYTE(0x1a, datareg);
+					OUT_BYTE((0x11 + adj), indexreg);
+					OUT_BYTE(0x02, datareg);
+					OUT_BYTE((0x12 + adj), indexreg);
+					OUT_BYTE(0xcb, datareg);
+					break;
+				case XFER_UDMA_4:
+					OUT_BYTE((0x10 + adj), indexreg);
+					OUT_BYTE(0x1a, datareg);
+					OUT_BYTE((0x11 + adj), indexreg);
+					OUT_BYTE(0x03, datareg);
+					OUT_BYTE((0x12 + adj), indexreg);
+					OUT_BYTE(0xcd, datareg);
+					break;
+				case XFER_UDMA_3:
+					OUT_BYTE((0x10 + adj), indexreg);
+					OUT_BYTE(0x1a, datareg);
+					OUT_BYTE((0x11 + adj), indexreg);
+					OUT_BYTE(0x05, datareg);
+					OUT_BYTE((0x12 + adj), indexreg);
+					OUT_BYTE(0xcd, datareg);
+					break;
+				case XFER_UDMA_2:
+					OUT_BYTE((0x10 + adj), indexreg);
+					OUT_BYTE(0x2a, datareg);
+					OUT_BYTE((0x11 + adj), indexreg);
+					OUT_BYTE(0x07, datareg);
+					OUT_BYTE((0x12 + adj), indexreg);
+					OUT_BYTE(0xcd, datareg);
+					break;
+				case XFER_UDMA_1:
+					OUT_BYTE((0x10 + adj), indexreg);
+					OUT_BYTE(0x3a, datareg);
+					OUT_BYTE((0x11 + adj), indexreg);
+					OUT_BYTE(0x0a, datareg);
+					OUT_BYTE((0x12 + adj), indexreg);
+					OUT_BYTE(0xd0, datareg);
+					break;
+				case XFER_UDMA_0:
+					OUT_BYTE((0x10 + adj), indexreg);
+					OUT_BYTE(0x4a, datareg);
+					OUT_BYTE((0x11 + adj), indexreg);
+					OUT_BYTE(0x0f, datareg);
+					OUT_BYTE((0x12 + adj), indexreg);
+					OUT_BYTE(0xd5, datareg);
+					break;
+				case XFER_MW_DMA_2:
+					OUT_BYTE((0x0e + adj), indexreg);
+					OUT_BYTE(0x69, datareg);
+					OUT_BYTE((0x0f + adj), indexreg);
+					OUT_BYTE(0x25, datareg);
+					break;
+				case XFER_MW_DMA_1:
+					OUT_BYTE((0x0e + adj), indexreg);
+					OUT_BYTE(0x6b, datareg);
+					OUT_BYTE((0x0f+ adj), indexreg);
+					OUT_BYTE(0x27, datareg);
+					break;
+				case XFER_MW_DMA_0:
+					OUT_BYTE((0x0e + adj), indexreg);
+					OUT_BYTE(0xdf, datareg);
+					OUT_BYTE((0x0f + adj), indexreg);
+					OUT_BYTE(0x5f, datareg);
+					break;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+				case XFER_PIO_4:
+					OUT_BYTE((0x0c + adj), indexreg);
+					OUT_BYTE(0x23, datareg);
+					OUT_BYTE((0x0d + adj), indexreg);
+					OUT_BYTE(0x09, datareg);
+					OUT_BYTE((0x13 + adj), indexreg);
+					OUT_BYTE(0x25, datareg);
+					break;
+				case XFER_PIO_3:
+					OUT_BYTE((0x0c + adj), indexreg);
+					OUT_BYTE(0x27, datareg);
+					OUT_BYTE((0x0d + adj), indexreg);
+					OUT_BYTE(0x0d, datareg);
+					OUT_BYTE((0x13 + adj), indexreg);
+					OUT_BYTE(0x35, datareg);
+					break;
+				case XFER_PIO_2:
+					OUT_BYTE((0x0c + adj), indexreg);
+					OUT_BYTE(0x23, datareg);
+					OUT_BYTE((0x0d + adj), indexreg);
+					OUT_BYTE(0x26, datareg);
+					OUT_BYTE((0x13 + adj), indexreg);
+					OUT_BYTE(0x64, datareg);
+					break;
+				case XFER_PIO_1:
+					OUT_BYTE((0x0c + adj), indexreg);
+					OUT_BYTE(0x46, datareg);
+					OUT_BYTE((0x0d + adj), indexreg);
+					OUT_BYTE(0x29, datareg);
+					OUT_BYTE((0x13 + adj), indexreg);
+					OUT_BYTE(0xa4, datareg);
+					break;
+				case XFER_PIO_0:
+					OUT_BYTE((0x0c + adj), indexreg);
+					OUT_BYTE(0xfb, datareg);
+					OUT_BYTE((0x0d + adj), indexreg);
+					OUT_BYTE(0x2b, datareg);
+					OUT_BYTE((0x13 + adj), indexreg);
+					OUT_BYTE(0xac, datareg);
+					break;
+				default:
+			}
+		}
+	}
+	return err;
+}
+
 /*   0    1    2    3    4    5    6   7   8
  * 960, 480, 390, 300, 240, 180, 120, 90, 60
  *           180, 150, 120,  90,  60
@@ -524,17 +669,69 @@
 	struct pci_dev *dev	= hwif->pci_dev;
 	unsigned long high_16   = pci_resource_start(dev, 4);
 	unsigned long dma_base  = hwif->dma_base;
+	unsigned long indexreg	= dma_base + 1;
+	unsigned long datareg	= dma_base + 3;
+	byte iordy		= 0x13;
+	byte adj		= (drive->dn%2) ? 0x08 : 0x00;
+	byte cable		= 0;
+	byte new_chip		= 0;
 	byte unit		= (drive->select.b.unit & 0x01);
-
 	unsigned int		drive_conf;
-	byte			drive_pci;
+	byte			drive_pci = 0;
 	byte			test1, test2, speed = -1;
 	byte			AP;
 	unsigned short		EP;
-	byte CLKSPD		= IN_BYTE(high_16 + 0x11);
-	byte udma_33		= ultra ? (inb(high_16 + 0x001f) & 1) : 0;
+	byte CLKSPD		= 0;
+	byte clockreg		= high_16 + 0x11;
+	byte udma_33		= ultra;
 	byte udma_66		= ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0;
-	byte udma_100		= (((dev->device == PCI_DEVICE_ID_PROMISE_20265) || (dev->device == PCI_DEVICE_ID_PROMISE_20267) || (dev->device == PCI_DEVICE_ID_PROMISE_20268)) && udma_66) ? 1 : 0;
+	byte udma_100		= 0;
+	byte udma_133		= 0;
+	byte mask			= hwif->channel ? 0x08 : 0x02;
+	unsigned short c_mask	= hwif->channel ? (1<<11) : (1<<10);
+
+	byte ultra_66		= ((id->dma_ultra & 0x0010) ||
+				   (id->dma_ultra & 0x0008)) ? 1 : 0;
+	byte ultra_100		= ((id->dma_ultra & 0x0020) ||
+				   (ultra_66)) ? 1 : 0;
+	byte ultra_133		= ((id->dma_ultra & 0x0040) ||
+				   (ultra_100)) ? 1 : 0;
+
+	switch(dev->device) {
+		case PCI_DEVICE_ID_PROMISE_20276:
+		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20269:
+			udma_133 = (udma_66) ? 1 : 0;
+			udma_100 = (udma_66) ? 1 : 0;
+			OUT_BYTE(0x0b, (hwif->dma_base + 1));
+			cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04));
+			new_chip = 1;
+			break;
+		case PCI_DEVICE_ID_PROMISE_20268:
+		case PCI_DEVICE_ID_PROMISE_20270:
+			udma_100 = (udma_66) ? 1 : 0;
+			OUT_BYTE(0x0b, (hwif->dma_base + 1));
+			cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04));
+			new_chip = 1;
+			break;
+		case PCI_DEVICE_ID_PROMISE_20267:
+		case PCI_DEVICE_ID_PROMISE_20265:
+			udma_100 = (udma_66) ? 1 : 0;
+			pci_read_config_word(dev, 0x50, &EP);
+			cable = (EP & c_mask);
+			new_chip = 0;
+			CLKSPD = IN_BYTE(clockreg);
+			break;
+		case PCI_DEVICE_ID_PROMISE_20262:
+			pci_read_config_word(dev, 0x50, &EP);
+			cable = (EP & c_mask);
+			new_chip = 0;
+			CLKSPD = IN_BYTE(clockreg);
+			break;
+		default:
+			udma_100 = 0; udma_133 = 0; cable = 0; new_chip = 1;
+			break;
+	}
 
 	/*
 	 * Set the control register to use the 66Mhz system
@@ -549,47 +746,42 @@
 	 * parameters.
 	 */
 
-	byte mask		= hwif->channel ? 0x08 : 0x02;
-	unsigned short c_mask	= hwif->channel ? (1<<11) : (1<<10);
-	byte ultra_66		= ((id->dma_ultra & 0x0010) ||
-				   (id->dma_ultra & 0x0008)) ? 1 : 0;
-	byte ultra_100		= ((id->dma_ultra & 0x0020) ||
-				   (id->dma_ultra & 0x0010) ||
-				   (id->dma_ultra & 0x0008)) ? 1 : 0;
-
-	if (dev->device == PCI_DEVICE_ID_PROMISE_20268)
-		goto jump_pci_mucking;
-
-	pci_read_config_word(dev, 0x50, &EP);
-
-	if (((ultra_66) || (ultra_100)) && (EP & c_mask)) {
+	if (((ultra_66) || (ultra_100) || (ultra_133)) && (cable)) {
 #ifdef DEBUG
 		printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary");
 		printk("         Switching to Ultra33 mode.\n");
 #endif /* DEBUG */
 		/* Primary   : zero out second bit */
 		/* Secondary : zero out fourth bit */
-		OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
+		//if (!new_chip)
+		OUT_BYTE(CLKSPD & ~mask, clockreg);
+		printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary");
+		printk("%s reduced to Ultra33 mode.\n", drive->name);
+		udma_66 = 0; udma_100 = 0; udma_133 = 0;
 	} else {
-		if ((ultra_66) || (ultra_100)) {
+		if ((ultra_66) || (ultra_100) || (ultra_133)) {
 			/*
 			 * check to make sure drive on same channel
 			 * is u66 capable
 			 */
 			if (hwif->drives[!(drive->dn%2)].id) {
-				if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) ||
+				if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0040) ||
+				    (hwif->drives[!(drive->dn%2)].id->dma_ultra
+& 0x0020) ||
 				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) ||
 				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) {
-					OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
+					OUT_BYTE(CLKSPD | mask, clockreg);
 				} else {
-					OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
+					OUT_BYTE(CLKSPD & ~mask, clockreg);
 				}
 			} else { /* udma4 drive by itself */
-				OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
+				OUT_BYTE(CLKSPD | mask, clockreg);
 			}
 		}
 	}
 
+	if (new_chip)	goto chipset_is_set;
+
 	switch(drive->dn) {
 		case 0:	drive_pci = 0x60;
 			pci_read_config_dword(dev, drive_pci, &drive_conf);
@@ -631,40 +823,49 @@
 
 chipset_is_set:
 
-	if (drive->media != ide_disk)	return ide_dma_off_quietly;
-
-	pci_read_config_byte(dev, (drive_pci), &AP);
-	if (id->capability & 4)	/* IORDY_EN */
-		pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
-	pci_read_config_byte(dev, (drive_pci), &AP);
-	if (drive->media == ide_disk)	/* PREFETCH_EN */
-		pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
-
-jump_pci_mucking:
+	if (drive->media != ide_disk)
+		return ide_dma_off_quietly;
+	
+	if (new_chip) {
+		if (id->capability & 4) {	/* IORDY_EN & PREFETCH_EN */
+			OUT_BYTE((iordy + adj), indexreg);
+			OUT_BYTE((IN_BYTE(datareg)|0x03), datareg);
+		}
+	}
+	else {
+		pci_read_config_byte(dev, (drive_pci), &AP);
+		if (id->capability & 4)	/* IORDY_EN */
+			pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
+		pci_read_config_byte(dev, (drive_pci), &AP);
+		if (drive->media == ide_disk)	/* PREFETCH_EN */
+			pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
+	}
 
-	if ((id->dma_ultra & 0x0020) && (udma_100))	speed = XFER_UDMA_5;
-	else if ((id->dma_ultra & 0x0010) && (udma_66))	speed = XFER_UDMA_4;
-	else if ((id->dma_ultra & 0x0008) && (udma_66))	speed = XFER_UDMA_3;
-	else if ((id->dma_ultra & 0x0004) && (udma_33))	speed = XFER_UDMA_2;
-	else if ((id->dma_ultra & 0x0002) && (udma_33))	speed = XFER_UDMA_1;
-	else if ((id->dma_ultra & 0x0001) && (udma_33))	speed = XFER_UDMA_0;
+	if ((id->dma_ultra & 0x0040)&&(udma_133))	speed = XFER_UDMA_6;
+	else if ((id->dma_ultra & 0x0020)&&(udma_100))	speed = XFER_UDMA_5;
+	else if ((id->dma_ultra & 0x0010)&&(udma_66))	speed = XFER_UDMA_4;
+	else if ((id->dma_ultra & 0x0008)&&(udma_66))	speed = XFER_UDMA_3;
+	else if ((id->dma_ultra & 0x0004)&&(udma_33))	speed = XFER_UDMA_2;
+	else if ((id->dma_ultra & 0x0002)&&(udma_33))	speed = XFER_UDMA_1;
+	else if ((id->dma_ultra & 0x0001)&&(udma_33))	speed = XFER_UDMA_0;
 	else if (id->dma_mword & 0x0004)		speed = XFER_MW_DMA_2;
 	else if (id->dma_mword & 0x0002)		speed = XFER_MW_DMA_1;
 	else if (id->dma_mword & 0x0001)		speed = XFER_MW_DMA_0;
-	else if (id->dma_1word & 0x0004)		speed = XFER_SW_DMA_2;
-	else if (id->dma_1word & 0x0002)		speed = XFER_SW_DMA_1;
-	else if (id->dma_1word & 0x0001)		speed = XFER_SW_DMA_0;
+	else if ((id->dma_1word & 0x0004)&&(!new_chip))	speed = XFER_SW_DMA_2;
+	else if ((id->dma_1word & 0x0002)&&(!new_chip))	speed = XFER_SW_DMA_1;
+	else if ((id->dma_1word & 0x0001)&&(!new_chip))	speed = XFER_SW_DMA_0;
 	else {
 		/* restore original pci-config space */
-		if (dev->device != PCI_DEVICE_ID_PROMISE_20268)
+		if (!new_chip)
 			pci_write_config_dword(dev, drive_pci, drive_conf);
 		return ide_dma_off_quietly;
 	}
 
 	outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
-	(void) pdc202xx_tune_chipset(drive, speed);
+	(void) hwif->speedproc(drive, speed);
 
-	return ((int)	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
+	return ((int)	((id->dma_ultra >> 14) & 3) ? ide_dma_on :
+			((id->dma_ultra >> 11) & 7) ? ide_dma_on :
 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
 			((id->dma_mword >> 8) & 7) ? ide_dma_on : 
 			((id->dma_1word >> 8) & 7) ? ide_dma_on :
@@ -685,7 +886,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x002F) {
+			if (id->dma_ultra & 0x007F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive, 1);
 				if ((id->field_valid & 2) &&
@@ -732,16 +933,73 @@
  */
 int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 {
-	byte dma_stat = 0, sc1d = 0;
-	unsigned long high_16	= pci_resource_start(HWIF(drive)->pci_dev, 4);
-	unsigned long dma_base	= HWIF(drive)->dma_base;
+	byte dma_stat		= 0;
+	byte sc1d		= 0;
+	byte newchip		= 0;
+	byte clock		= 0;
+	byte hardware48fix	= 0;
+	ide_hwif_t *hwif	= HWIF(drive);
+	struct pci_dev *dev	= hwif->pci_dev;
+	unsigned long high_16	= pci_resource_start(dev, 4);
+	unsigned long dma_base	= hwif->dma_base;
+	unsigned long atapi_port= hwif->channel ? high_16+0x24 : high_16+0x20;
+
+	switch (dev->device) {
+		case PCI_DEVICE_ID_PROMISE_20276:
+		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20269:
+		case PCI_DEVICE_ID_PROMISE_20268:
+		case PCI_DEVICE_ID_PROMISE_20270:
+			newchip = 1;
+			break;
+		case PCI_DEVICE_ID_PROMISE_20267:
+		case PCI_DEVICE_ID_PROMISE_20265:
+			hardware48fix = 1;
+			clock = IN_BYTE(high_16 + 0x11);
+		default:
+			break;
+	}
 
 	switch (func) {
 		case ide_dma_check:
 			return config_drive_xfer_rate(drive);
+		case ide_dma_begin:
+			/* Note that this is done *after* the cmd has
+			 * been issued to the drive, as per the BM-IDE spec.
+			 * The Promise Ultra33 doesn't work correctly when
+			 * we do this part before issuing the drive cmd.
+			 */
+			/* Enable ATAPI UDMA port for 48bit data on PDC20267 */
+			if ((drive->addressing) && (hardware48fix)) {
+				struct request *rq = HWGROUP(drive)->rq;
+				unsigned long word_count = 0;
+				unsigned long hankval = 0;
+				byte	clockreg = high_16 + 0x11;
+				
+				OUT_BYTE(clock|(hwif->channel ? 0x08:0x02), clockreg);
+				word_count = (rq->nr_sectors << 8);
+				hankval = (rq->cmd == READ) ? 0x05<<24 : 0x06<<24;
+				hankval = hankval | word_count ;
+				outl(hankval, atapi_port);
+			}  
+			break;
+		case ide_dma_end:
+			/* Disable ATAPI UDMA port for 48bit data on PDC20267 */
+			if ((drive->addressing) && (hardware48fix)) {
+				unsigned long hankval = 0;
+				byte	clockreg = high_16 + 0x11;
+				
+			    	outl(hankval, atapi_port);	/* zero out extra */
+				clock = IN_BYTE(clockreg);
+				OUT_BYTE(clock & ~(hwif->channel ? 0x08:0x02), clockreg);
+			}
+			break;
 		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
-			dma_stat = inb(dma_base+2);
-			sc1d = inb(high_16 + 0x001d);
+			dma_stat = IN_BYTE(dma_base+2);
+			if (newchip)
+				return (dma_stat & 4) == 4;
+
+			sc1d = IN_BYTE(high_16 + 0x001d);
 			if (HWIF(drive)->channel) {
 				if ((sc1d & 0x50) == 0x50) goto somebody_else;
 				else if ((sc1d & 0x40) == 0x40)
@@ -766,59 +1024,57 @@
 
 void pdc202xx_reset (ide_drive_t *drive)
 {
-	unsigned long high_16	= pci_resource_start(HWIF(drive)->pci_dev, 4);
-	byte udma_speed_flag	= inb(high_16 + 0x001f);
+	OUT_BYTE(0x04,IDE_CONTROL_REG);
+	mdelay(1000);
+	OUT_BYTE(0x00,IDE_CONTROL_REG);
+	mdelay(1000);
+	printk("PDC202XX: %s channel reset.\n",
+		HWIF(drive)->channel ? "Secondary" : "Primary");
+}
 
-	OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);
-	mdelay(100);
-	OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
-	mdelay(2000);		/* 2 seconds ?! */
+/*
+ * Since SUN Cobalt is attempting to do this operation, I should disclose
+ * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date
+ * HOTSWAP ATA Infrastructure.
+ */
+static int pdc202xx_tristate (ide_drive_t * drive, int state)
+{
+#if 0
+	ide_hwif_t *hwif	= HWIF(drive);
+	unsigned long high_16	= pci_resource_start(hwif->pci_dev, 4);
+	byte sc1f		= inb(high_16 + 0x001f);
+
+	if (!hwif)
+		return -EINVAL;
+
+//	hwif->bus_state = state;
+
+	if (state) {
+		outb(sc1f | 0x08, high_16 + 0x001f);
+	} else {
+		outb(sc1f & ~0x08, high_16 + 0x001f);
+	}
+#endif
+	return 0;
 }
 
 unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
 {
-	unsigned long high_16 = pci_resource_start(dev, 4);
-	byte udma_speed_flag	= inb(high_16 + 0x001f);
-	byte primary_mode	= inb(high_16 + 0x001a);
-	byte secondary_mode	= inb(high_16 + 0x001b);
-
-	if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) ||
-	    (dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
-	    (dev->device == PCI_DEVICE_ID_PROMISE_20267)) {
-		/*
-		 * software reset -  this is required because the bios
-		 * will set UDMA timing on if the hdd supports it. The
-		 * user may want to turn udma off. A bug in the pdc20262
-		 * is that it cannot handle a downgrade in timing from UDMA
-		 * to DMA. Disk accesses after issuing a set feature command
-		 * will result in errors. A software reset leaves the timing
-		 * registers intact, but resets the drives.
-		 */
-
-		OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);
-		mdelay(100);
-		OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
-		mdelay(2000);	/* 2 seconds ?! */
-	}
+	unsigned long high_16	= pci_resource_start(dev, 4);
+	byte udma_speed_flag	= IN_BYTE(high_16 + 0x001f);
+	byte primary_mode	= IN_BYTE(high_16 + 0x001a);
+	byte secondary_mode	= IN_BYTE(high_16 + 0x001b);
+
+	OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);
+	mdelay(100);
+	OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
+	mdelay(2000);	/* 2 seconds ?! */
 
 	if (dev->resource[PCI_ROM_RESOURCE].start) {
 		pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
 		printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
 	}
-
-	if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
-		byte irq = 0, irq2 = 0;
-		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
-		pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2);	/* 0xbc */
-		if ((irq != irq2) &&
-		    (dev->device != PCI_DEVICE_ID_PROMISE_20265) &&
-		    (dev->device != PCI_DEVICE_ID_PROMISE_20267) &&
-		    (dev->device != PCI_DEVICE_ID_PROMISE_20268)) {
-			pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq);	/* 0xbc */
-			printk("%s: pci-config space interrupt mirror fixed.\n", name);
-		}
-	}
-
+	
 	printk("%s: (U)DMA Burst Bit %sABLED " \
 		"Primary %s Mode " \
 		"Secondary %s Mode.\n",
@@ -830,8 +1086,8 @@
 #ifdef CONFIG_PDC202XX_BURST
 	if (!(udma_speed_flag & 1)) {
 		printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", name, udma_speed_flag, (udma_speed_flag|1));
-		outb(udma_speed_flag|1, high_16 + 0x001f);
-		printk("%sCTIVE\n", (inb(high_16 + 0x001f) & 1) ? "A" : "INA");
+		OUT_BYTE(udma_speed_flag|1, high_16 + 0x001f);
+		printk("%sCTIVE\n", (IN_BYTE(high_16 + 0x001f) & 1) ? "A" : "INA");
 	}
 #endif /* CONFIG_PDC202XX_BURST */
 
@@ -839,15 +1095,15 @@
 	if (!(primary_mode & 1)) {
 		printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ",
 			name, primary_mode, (primary_mode|1));
-		outb(primary_mode|1, high_16 + 0x001a);
-		printk("%s\n", (inb(high_16 + 0x001a) & 1) ? "MASTER" : "PCI");
+		OUT_BYTE(primary_mode|1, high_16 + 0x001a);
+		printk("%s\n", (IN_BYTE(high_16 + 0x001a) & 1) ? "MASTER" : "PCI");
 	}
 
 	if (!(secondary_mode & 1)) {
 		printk("%s: FORCING SECONDARY MODE BIT 0x%02x -> 0x%02x ",
 			name, secondary_mode, (secondary_mode|1));
-		outb(secondary_mode|1, high_16 + 0x001b);
-		printk("%s\n", (inb(high_16 + 0x001b) & 1) ? "MASTER" : "PCI");
+		OUT_BYTE(secondary_mode|1, high_16 + 0x001b);
+		printk("%s\n", (IN_BYTE(high_16 + 0x001b) & 1) ? "MASTER" : "PCI");
 	}
 #endif /* CONFIG_PDC202XX_MASTER */
 
@@ -866,20 +1122,44 @@
 	unsigned short mask = (hwif->channel) ? (1<<11) : (1<<10);
 	unsigned short CIS;
 
-	pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
-	return ((CIS & mask) ? 0 : 1);
+        	switch(hwif->pci_dev->device) {
+		case PCI_DEVICE_ID_PROMISE_20276:
+		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20269:
+		case PCI_DEVICE_ID_PROMISE_20268:
+		case PCI_DEVICE_ID_PROMISE_20270:
+			OUT_BYTE(0x0b, (hwif->dma_base + 1));
+			return (!(IN_BYTE((hwif->dma_base + 3)) & 0x04));
+			/* check 80pin cable */
+		default:
+			pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
+			return (!(CIS & mask));
+			/* check 80pin cable */
+	}
 }
 
 void __init ide_init_pdc202xx (ide_hwif_t *hwif)
 {
-	hwif->tuneproc	= &pdc202xx_tune_drive;
-	hwif->speedproc	= &pdc202xx_tune_chipset;
-	hwif->quirkproc	= &pdc202xx_quirkproc;
-
-	if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) ||
-	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
-	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) {
-		hwif->resetproc	= &pdc202xx_reset;
+	hwif->tuneproc  = &pdc202xx_tune_drive;
+	hwif->quirkproc = &pdc202xx_quirkproc;
+	hwif->resetproc = &pdc202xx_reset;
+
+        switch(hwif->pci_dev->device) {
+		case PCI_DEVICE_ID_PROMISE_20276:
+		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20269:
+		case PCI_DEVICE_ID_PROMISE_20268:
+		case PCI_DEVICE_ID_PROMISE_20270:
+			hwif->speedproc = &pdc202xx_new_tune_chipset;
+			break;
+		case PCI_DEVICE_ID_PROMISE_20267:
+		case PCI_DEVICE_ID_PROMISE_20265:
+		case PCI_DEVICE_ID_PROMISE_20262:
+			hwif->busproc   = &pdc202xx_tristate;
+		case PCI_DEVICE_ID_PROMISE_20246:
+			hwif->speedproc = &pdc202xx_tune_chipset;
+		default:
+			break;
 	}
 
 #undef CONFIG_PDC202XX_32_UNMASK
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c
--- linux.orig/drivers/ide/pdc4030.c	2001-07-18 01:53:55.000000000 +0000
+++ linux/drivers/ide/pdc4030.c	2002-07-20 01:08:28.000000000 +0000
@@ -89,6 +89,12 @@
 
 #include "pdc4030.h"
 
+#ifdef CONFIG_IDE_TASKFILE_IO
+#  define __TASKFILE__IO
+#else /* CONFIG_IDE_TASKFILE_IO */
+#  undef __TASKFILE__IO
+#endif /* CONFIG_IDE_TASKFILE_IO */
+
 /*
  * promise_selectproc() is invoked by ide.c
  * in preparation for access to the specified drive.
@@ -298,8 +304,6 @@
 	}
 }
 
-
-
 /*
  * promise_read_intr() is the handler for disk read/multread interrupts
  */
@@ -495,11 +499,15 @@
  */
 ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq)
 {
+	ide_startstop_t startstop;
 	unsigned long timeout;
 	byte stat;
 
-	if (rq->cmd == READ) {
-		OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
+	switch(rq->cmd) {
+		case READ:
+#ifndef __TASKFILE__IO
+			OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
+#endif
 /*
  * The card's behaviour is odd at this point. If the data is
  * available, DRQ will be true, and no interrupt will be
@@ -510,44 +518,61 @@
  * If neither of these is the case, we wait for up to 50ms (badly I'm
  * afraid!) until one of them is.
  */
-		timeout = jiffies + HZ/20; /* 50ms wait */
-		do {
-			stat=GET_STAT();
-			if (stat & DRQ_STAT) {
-				udelay(1);
-				return promise_read_intr(drive);
-			}
-			if (IN_BYTE(IDE_SELECT_REG) & 0x01) {
+			timeout = jiffies + HZ/20; /* 50ms wait */
+			do {
+				stat=GET_STAT();
+				if (stat & DRQ_STAT) {
+					udelay(1);
+					return promise_read_intr(drive);
+				}
+				if (IN_BYTE(IDE_SELECT_REG) & 0x01) {
 #ifdef DEBUG_READ
-				printk(KERN_DEBUG "%s: read: waiting for "
-				                  "interrupt\n", drive->name);
+	printk(KERN_DEBUG "%s: read: waiting for interrupt\n", drive->name);
 #endif
-				ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
-				return ide_started;
-			}
-			udelay(1);
-		} while (time_before(jiffies, timeout));
-
-		printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n",
-			drive->name);
-		return ide_stopped;
-	} else if (rq->cmd == WRITE) {
-		ide_startstop_t startstop;
-		OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
-		if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
-			printk(KERN_ERR "%s: no DRQ after issuing "
-			       "PROMISE_WRITE\n", drive->name);
-			return startstop;
-	    	}
-		if (!drive->unmask)
-			__cli();	/* local CPU only */
-		HWGROUP(drive)->wrq = *rq; /* scratchpad */
-		return promise_write(drive);
+					ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
+					return ide_started;
+				}
+				udelay(1);
+			} while (time_before(jiffies, timeout));
 
-	} else {
-		printk("KERN_WARNING %s: bad command: %d\n",
-		       drive->name, rq->cmd);
-		ide_end_request(0, HWGROUP(drive));
-		return ide_stopped;
+			printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n", drive->name);
+			return ide_stopped;
+		case WRITE:
+#ifndef __TASKFILE__IO
+			OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
+#endif
+			if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+				printk(KERN_ERR "%s: no DRQ after issuing PROMISE_WRITE\n", drive->name);
+				return startstop;
+		    	}
+			if (!drive->unmask)
+				__cli();	/* local CPU only */
+			HWGROUP(drive)->wrq = *rq; /* scratchpad */
+			return promise_write(drive);
+		default:
+			printk("KERN_WARNING %s: bad command: %d\n", drive->name, rq->cmd);
+			ide_end_request(0, HWGROUP(drive));
+			return ide_stopped;
 	}
 }
+
+#ifdef __TASKFILE__IO
+
+ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+{
+	struct hd_drive_task_hdr taskfile;
+
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+
+	taskfile.sector_count	= rq->nr_sectors;
+	taskfile.sector_number	= block;
+	taskfile.low_cylinder	= (block>>=8);
+	taskfile.high_cylinder	= (block>>=8);
+	taskfile.device_head	= ((block>>8)&0x0f)|drive->select.all;
+	taskfile.command	= (rq->cmd==READ)?PROMISE_READ:PROMISE_WRITE;
+
+	do_taskfile(drive, &taskfile, NULL, NULL);
+	return do_pdc4030_io(drive, rq);
+}
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/piix.c linux/drivers/ide/piix.c
--- linux.orig/drivers/ide/piix.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/ide/piix.c	2002-07-20 01:08:33.000000000 +0000
@@ -92,6 +92,9 @@
 		case PCI_DEVICE_ID_INTEL_82801BA_8:
 		case PCI_DEVICE_ID_INTEL_82801BA_9:
 	        case PCI_DEVICE_ID_INTEL_82801CA_10:
+	        case PCI_DEVICE_ID_INTEL_82801CA_11:
+	        case PCI_DEVICE_ID_INTEL_82801DB_11:
+	        case PCI_DEVICE_ID_INTEL_82801E_11:
 			p += sprintf(p, "\n                                Intel PIIX4 Ultra 100 Chipset.\n");
 			break;
 		case PCI_DEVICE_ID_INTEL_82372FB_1:
@@ -258,8 +261,8 @@
 			master_data = master_data | 0x0070;
 		pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data);
 		slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0);
-		slave_data = slave_data | ((timings[pio][0] << 2) | (timings[pio][1]
-					   << (HWIF(drive)->index ? 4 : 0)));
+		slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1])
+					   << (HWIF(drive)->index ? 4 : 0));
 	} else {
 		master_data = master_data & 0xccf8;
 		if (pio > 1)
@@ -366,7 +369,10 @@
 	byte udma_66		= eighty_ninty_three(drive);
 	int ultra100		= ((dev->device == PCI_DEVICE_ID_INTEL_82801BA_8) ||
 				   (dev->device == PCI_DEVICE_ID_INTEL_82801BA_9) ||
-				   (dev->device == PCI_DEVICE_ID_INTEL_82801CA_10)) ? 1 : 0;
+				   (dev->device == PCI_DEVICE_ID_INTEL_82801CA_10) ||
+				   (dev->device == PCI_DEVICE_ID_INTEL_82801CA_11) ||
+				   (dev->device == PCI_DEVICE_ID_INTEL_82801DB_11) ||
+				   (dev->device == PCI_DEVICE_ID_INTEL_82801E_11)) ? 1 : 0;
 	int ultra66		= ((ultra100) ||
 				   (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ||
 				   (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0;
@@ -425,7 +431,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x002F) {
+			if (id->dma_ultra & 0x003F) {
 				/* Force if Capable UltraDMA */
 				dma_func = piix_config_drive_for_dma(drive);
 				if ((id->field_valid & 2) &&
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/qd65xx.c linux/drivers/ide/qd65xx.c
--- linux.orig/drivers/ide/qd65xx.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/ide/qd65xx.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,14 +1,15 @@
 /*
- *  linux/drivers/ide/qd65xx.c		Version 0.06	Aug 3, 2000
+ *  linux/drivers/ide/qd65xx.c		Version 0.07	Sep 30, 2001
  *
- *  Copyright (C) 1996-2000  Linus Torvalds & author (see below)
+ *  Copyright (C) 1996-2001  Linus Torvalds & author (see below)
  */
 
 /*
  *  Version 0.03	Cleaned auto-tune, added probe
  *  Version 0.04	Added second channel tuning
  *  Version 0.05	Enhanced tuning ; added qd6500 support
- *  Version 0.06	added dos driver's list
+ *  Version 0.06	Added dos driver's list
+ *  Version 0.07	Second channel bug fix 
  *
  * QDI QD6500/QD6580 EIDE controller fast support
  *
@@ -67,6 +68,7 @@
  *        qd6500: 1100
  *        qd6580: either 1010 or 0101
  *
+ *
  * base+0x02: Timer2 (qd6580 only)
  *
  *
@@ -137,12 +139,12 @@
 {
 	byte active_cycle,recovery_cycle;
 
-	if (system_bus_clock()<=33) {
-		active_cycle =   9  - IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 2, 9);
-		recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 0, 15);
+	if (ide_system_bus_speed()<=33) {
+		active_cycle =   9  - IDE_IN(active_time   * ide_system_bus_speed() / 1000 + 1, 2, 9);
+		recovery_cycle = 15 - IDE_IN(recovery_time * ide_system_bus_speed() / 1000 + 1, 0, 15);
 	} else {
-		active_cycle =   8  - IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 1, 8);
-		recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 3, 18);
+		active_cycle =   8  - IDE_IN(active_time   * ide_system_bus_speed() / 1000 + 1, 1, 8);
+		recovery_cycle = 18 - IDE_IN(recovery_time * ide_system_bus_speed() / 1000 + 1, 3, 18);
 	}
 
 	return((recovery_cycle<<4) | 0x08 | active_cycle);
@@ -156,8 +158,8 @@
 
 static byte qd6580_compute_timing (int active_time, int recovery_time)
 {
-	byte active_cycle   = 17-IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 2, 17);
-	byte recovery_cycle = 15-IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 2, 15);
+	byte active_cycle   = 17-IDE_IN(active_time   * ide_system_bus_speed() / 1000 + 1, 2, 17);
+	byte recovery_cycle = 15-IDE_IN(recovery_time * ide_system_bus_speed() / 1000 + 1, 2, 15);
 
 	return((recovery_cycle<<4) | active_cycle);
 }
@@ -427,7 +429,8 @@
 				ide_hwifs[i].tuneproc = &qd6580_tune_drive;
 
 				for (j=0;j<2;j++) {
-					ide_hwifs[i].drives[j].drive_data = QD6580_DEF_DATA;
+					ide_hwifs[i].drives[j].drive_data =
+					       i?QD6580_DEF_DATA2:QD6580_DEF_DATA;
 					ide_hwifs[i].drives[j].io_32bit = 1;
 				}
 			}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/qd65xx.h linux/drivers/ide/qd65xx.h
--- linux.orig/drivers/ide/qd65xx.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/ide/qd65xx.h	2002-07-20 01:08:30.000000000 +0000
@@ -29,7 +29,7 @@
 
 #define QD_CONTR_SEC_DISABLED	0x01
 
-#define QD_ID3			(config & QD_CONFIG_ID3)
+#define QD_ID3			((config & QD_CONFIG_ID3)!=0)
 
 #define QD_CONFIG(hwif)		((hwif)->config_data & 0x00ff)
 #define QD_CONTROL(hwif)	(((hwif)->config_data & 0xff00) >> 8)
@@ -39,6 +39,7 @@
 
 #define QD6500_DEF_DATA		((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08))
 #define QD6580_DEF_DATA		((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00))
+#define QD6580_DEF_DATA2	((QD_TIM2_PORT<<8) | (QD_ID3 ? 0x0a : 0x00))
 #define QD_DEF_CONTR		(0x40 | ((control & 0x02) ? 0x9f : 0x1f))
 
 #define QD_TESTVAL		0x19	/* safe value */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c
--- linux.orig/drivers/ide/serverworks.c	2001-09-09 17:43:02.000000000 +0000
+++ linux/drivers/ide/serverworks.c	2002-07-20 01:08:38.000000000 +0000
@@ -1,16 +1,26 @@
 /*
- * linux/drivers/ide/serverworks.c		Version 0.2	17 Oct 2000
+ * linux/drivers/ide/serverworks.c		Version 0.3	26 Oct 2001
  *
- *  Copyright (C) 2000 Cobalt Networks, Inc. <asun@cobalt.com>
- *  May be copied or modified under the terms of the GNU General Public License
+ * May be copied or modified under the terms of the GNU General Public License
  *
- *  interface borrowed from alim15x3.c:
- *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
- *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
+ * Copyright (C) 1998-2000 Michel Aubry
+ * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
+ * Portions copyright (c) 2001 Sun Microsystems
  *
- *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
  *
- *  IDE support for the ServerWorks OSB4 IDE chipset
+ * RCC/ServerWorks IDE driver for Linux
+ *
+ *   OSB4: `Open South Bridge' IDE Interface (fn 1)
+ *         supports UDMA mode 2 (33 MB/s)
+ *
+ *   CSB5: `Champion South Bridge' IDE Interface (fn 1)
+ *         all revisions support UDMA mode 4 (66 MB/s)
+ *         revision A2.0 and up support UDMA mode 5 (100 MB/s)
+ *
+ *         *** The CSB5 does not provide ANY register ***
+ *         *** to detect 80-conductor cable presence. ***
+ *
  *
  * here's the default lspci:
  *
@@ -83,15 +93,15 @@
 
 #include "ide_modes.h"
 
-#define SVWKS_DEBUG_DRIVE_INFO		0
-
-#define DISPLAY_SVWKS_TIMINGS
+#define DISPLAY_SVWKS_TIMINGS	1
+#undef SVWKS_DEBUG_DRIVE_INFO
 
 #if defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 
 static struct pci_dev *bmide_dev;
+static byte svwks_revision = 0;
 
 static int svwks_get_info(char *, char **, off_t, int);
 extern int (*svwks_display_info)(char *, char **, off_t, int); /* ide-proc.c */
@@ -103,7 +113,7 @@
 	u32 bibma = pci_resource_start(bmide_dev, 4);
 	u32 reg40, reg44;
 	u16 reg48, reg56;
-	u8  c0 = 0, c1 = 0, reg54;
+	u8  reg54, c0=0, c1=0;
 
 	pci_read_config_dword(bmide_dev, 0x40, &reg40);
 	pci_read_config_dword(bmide_dev, 0x44, &reg44);
@@ -120,20 +130,23 @@
 
 	switch(bmide_dev->device) {
 		case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
-			p += sprintf(p, "\n                                ServerWorks CSB5 Chipset.\n");
+			p += sprintf(p, "\n                            "
+				     "ServerWorks CSB5 Chipset (rev %02x)\n",
+				     svwks_revision);
 			break;
-		case PCI_DEVICE_ID_SERVERWORKS_OSB4:
-			p += sprintf(p, "\n                                ServerWorks OSB4 Chipset.\n");
+		case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
+			p += sprintf(p, "\n                            "
+				     "ServerWorks OSB4 Chipset (rev %02x)\n",
+				     svwks_revision);
 			break;
 		default:
-			p += sprintf(p, "\n                                ServerWorks 0x%04x Chipset.\n", bmide_dev->device);
+			p += sprintf(p, "\n                            "
+				     "ServerWorks %04x Chipset (rev %02x)\n",
+				     bmide_dev->device, svwks_revision);
 			break;
 	}
 
 	p += sprintf(p, "------------------------------- General Status ---------------------------------\n");
-#if 0
-	p += sprintf(p, "                                     : %s\n", "str");
-#endif
 	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
 	p += sprintf(p, "                %sabled                         %sabled\n",
 			(c0&0x80) ? "dis" : " en",
@@ -191,11 +204,7 @@
 				((reg44&0x00210000)==0x00210000)?"1":
 				((reg44&0x00770000)==0x00770000)?"0":
 				((reg44&0x00FF0000)==0x00FF0000)?"X":"?");
-#if 0
-	if (bmide_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
-		p += sprintf(p, "PIO  enabled:   %s                %s               %s                 %s\n",
-	if (bmide_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4)
-#endif
+
 		p += sprintf(p, "PIO  enabled:   %s                %s               %s                 %s\n",
 			((reg40&0x00002000)==0x00002000)?"4":
 				((reg40&0x00002200)==0x00002200)?"3":
@@ -221,7 +230,7 @@
 }
 #endif  /* defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) */
 
-static byte svwks_revision = 0;
+#define SVWKS_CSB5_REVISION_NEW	0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
 
 byte svwks_proc = 0;
 
@@ -292,6 +301,7 @@
 			pio_timing |= pio_modes[speed - XFER_PIO_0];
 			csb5_pio   |= ((speed - XFER_PIO_0) << (4*drive->dn));
 			break;
+
 #ifdef CONFIG_BLK_DEV_IDEDMA
 		case XFER_MW_DMA_2:
 		case XFER_MW_DMA_1:
@@ -307,9 +317,9 @@
 		case XFER_UDMA_2:
 		case XFER_UDMA_1:
 		case XFER_UDMA_0:
-			pio_timing |= pio_modes[pio];
-			csb5_pio   |= (pio << (4*drive->dn));
-			dma_timing |= dma_modes[2];
+			pio_timing   |= pio_modes[pio];
+			csb5_pio     |= (pio << (4*drive->dn));
+			dma_timing   |= dma_modes[2];
 			ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit));
 			ultra_enable |= (0x01 << drive->dn);
 #endif
@@ -322,9 +332,9 @@
 		drive->name, ultra_timing, dma_timing, pio_timing);
 #endif
 
-#if OSB4_DEBUG_DRIVE_INFO
+#if SVWKS_DEBUG_DRIVE_INFO
 	printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
-#endif /* OSB4_DEBUG_DRIVE_INFO */
+#endif /* SVWKS_DEBUG_DRIVE_INFO */
 
 	if (!drive->init_speed)
 		drive->init_speed = speed;
@@ -338,11 +348,10 @@
 	pci_write_config_byte(dev, drive_pci3, ultra_timing);
 	pci_write_config_byte(dev, 0x54, ultra_enable);
 	
-	if (speed > XFER_PIO_4) {
+	if (speed > XFER_PIO_4)
 		outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
-	} else {
+	else
 		outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
-	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
 	err = ide_config_drive_speed(drive, speed);
@@ -354,25 +363,24 @@
 {
 	unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
 	unsigned short xfer_pio = drive->id->eide_pio_modes;
-	byte			timing, speed, pio;
+	byte timing, speed, pio;
 
 	pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
 
 	if (xfer_pio> 4)
 		xfer_pio = 0;
 
-	if (drive->id->eide_pio_iordy > 0) {
+	if (drive->id->eide_pio_iordy > 0)
 		for (xfer_pio = 5;
 			xfer_pio>0 &&
 			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
 			xfer_pio--);
-	} else {
+	else
 		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
 			   (drive->id->eide_pio_modes & 2) ? 0x04 :
 			   (drive->id->eide_pio_modes & 1) ? 0x03 :
 			   (drive->id->tPIO & 2) ? 0x02 :
 			   (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-	}
 
 	timing = (xfer_pio >= pio) ? xfer_pio : pio;
 
@@ -407,12 +415,10 @@
 {
 	struct hd_driveid *id	= drive->id;
 	struct pci_dev *dev	= HWIF(drive)->pci_dev;
-	byte udma_66		= eighty_ninty_three(drive);
-	byte			speed;
-
-	int ultra66		= (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ? 1 : 0;
-	/* need specs to figure out if osb4 is capable of ata/66/100 */
-	int ultra100		= (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ? 1 : 0;
+	byte udma_66	= eighty_ninty_three(drive);
+	int ultra66	= (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ? 1 : 0;
+	int ultra100 	= (ultra66 && svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 1 : 0;
+	byte speed;
 
 	if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) {
 		speed = XFER_UDMA_5;
@@ -458,7 +464,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x002F) {
+			if (id->dma_ultra & 0x003F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive);
 				if ((id->field_valid & 2) &&
@@ -499,7 +505,41 @@
 	switch (func) {
 		case ide_dma_check:
 			return config_drive_xfer_rate(drive);
-		default :
+		case ide_dma_end:
+		{
+			ide_hwif_t *hwif		= HWIF(drive);
+			unsigned long dma_base		= hwif->dma_base;
+	
+			if(inb(dma_base+0x02)&1)
+			{
+#if 0		
+				int i;
+				printk(KERN_ERR "Curious - OSB4 thinks the DMA is still running.\n");
+				for(i=0;i<10;i++)
+				{
+					if(!(inb(dma_base+0x02)&1))
+					{
+						printk(KERN_ERR "OSB4 now finished.\n");
+						break;
+					}
+					udelay(5);
+				}
+#endif		
+				printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
+				printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
+				printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
+#if 0		
+				/* Panic might sys_sync -> death by corrupt disk */
+				panic("OSB4: continuing might cause disk corruption.\n");
+#else
+				printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
+				while(1)
+					cpu_relax();
+#endif				
+			}
+			/* and drop through */
+		}
+		default:
 			break;
 	}
 	/* Other cases are done by generic IDE-DMA code. */
@@ -509,30 +549,43 @@
 
 unsigned int __init pci_init_svwks (struct pci_dev *dev, const char *name)
 {
-	unsigned int reg64;
+	unsigned int reg;
+	byte btr;
 
+	/* save revision id to determine DMA capability */
 	pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
 
-	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
-		isa_dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
+	/* force Master Latency Timer value to 64 PCICLKs */
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
 
-		pci_read_config_dword(isa_dev, 0x64, &reg64);
-#ifdef DEBUG
-		printk("%s: reg64 == 0x%08x\n", name, reg64);
-#endif
+	/* OSB4 : South Bridge and IDE */
+	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
+		isa_dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,
+			  PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
+		if (isa_dev) {
+			pci_read_config_dword(isa_dev, 0x64, &reg);
+			reg &= ~0x00002000; /* disable 600ns interrupt mask */
+			reg |=  0x00004000; /* enable UDMA/33 support */
+			pci_write_config_dword(isa_dev, 0x64, reg);
+		}
+	}
 
-//		reg64 &= ~0x0000A000;
-//#ifdef CONFIG_SMP
-//		reg64 |= 0x00008000;
-//#endif
-	/* Assume the APIC was set up properly by the BIOS for now . If it
-	   wasnt we need to do a fix up _way_ earlier. Bits 15,10,3 control
-	   APIC enable, routing and decode */
-	   
-		reg64 &= ~0x00002000;	
-		pci_write_config_dword(isa_dev, 0x64, reg64);
+	/* setup CSB5 : South Bridge and IDE */
+	else if (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) {
+		/* setup the UDMA Control register
+		 *
+		 * 1. clear bit 6 to enable DMA
+		 * 2. enable DMA modes with bits 0-1
+		 *      00 : legacy
+		 *      01 : udma2
+		 *      10 : udma2/udma4
+		 *      11 : udma2/udma4/udma5
+		 */
+		pci_read_config_byte(dev, 0x5A, &btr);
+		btr &= ~0x40;
+		btr |= (svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
+		pci_write_config_byte(dev, 0x5A, btr);
 	}
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
 
 #if defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS)
 	if (!svwks_proc) {
@@ -551,26 +604,46 @@
  * Bit 14 clear = primary IDE channel does not have 80-pin cable.
  * Bit 14 set   = primary IDE channel has 80-pin cable.
  */
-
 static unsigned int __init ata66_svwks_dell (ide_hwif_t *hwif)
 {
-	struct pci_dev *dev	= hwif->pci_dev;
-	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL        &&
-	    dev->vendor           == PCI_VENDOR_ID_SERVERWORKS &&
-	    dev->device           == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
+	struct pci_dev *dev = hwif->pci_dev;
+	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
+	    dev->vendor	== PCI_VENDOR_ID_SERVERWORKS &&
+	    dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
 		return ((1 << (hwif->channel + 14)) &
 			dev->subsystem_device) ? 1 : 0;
-
 	return 0;
+}
 
+/* Sun Cobalt Alpine hardware avoids the 80-pin cable
+ * detect issue by attaching the drives directly to the board.
+ * This check follows the Dell precedent (how scary is that?!)
+ *
+ * WARNING: this only works on Alpine hardware!
+ */
+static unsigned int __init ata66_svwks_cobalt (ide_hwif_t *hwif)
+{
+	struct pci_dev *dev = hwif->pci_dev;
+	if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&
+	    dev->vendor	== PCI_VENDOR_ID_SERVERWORKS &&
+	    dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
+		return ((1 << (hwif->channel + 14)) &
+			dev->subsystem_device) ? 1 : 0;
+	return 0;
 }
 
 unsigned int __init ata66_svwks (ide_hwif_t *hwif)
 {
-	struct pci_dev *dev	= hwif->pci_dev;
+	struct pci_dev *dev = hwif->pci_dev;
+
+	/* Dell PowerEdge */
 	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL)
 		return ata66_svwks_dell (hwif);
-	
+
+	/* Cobalt Alpine */
+	if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN)
+		return ata66_svwks_cobalt (hwif);
+
 	return 0;
 }
 
@@ -586,12 +659,12 @@
 	hwif->drives[0].autotune = 1;
 	hwif->drives[1].autotune = 1;
 	hwif->autodma = 0;
-	return;
 #else /* CONFIG_BLK_DEV_IDEDMA */
-
 	if (hwif->dma_base) {
+#ifdef CONFIG_IDEDMA_AUTO
 		if (!noautodma)
 			hwif->autodma = 1;
+#endif	
 		hwif->dmaproc = &svwks_dmaproc;
 	} else {
 		hwif->autodma = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c
--- linux.orig/drivers/ide/sis5513.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/ide/sis5513.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,11 +1,35 @@
 /*
- * linux/drivers/ide/sis5513.c		Version 0.11	June 9, 2000
+ * linux/drivers/ide/sis5513.c		Version 0.13	March 6, 2002
  *
  * Copyright (C) 1999-2000	Andre Hedrick <andre@linux-ide.org>
+ * Copyright (C) 2002		Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
  * May be copied or modified under the terms of the GNU General Public License
  *
- * Thanks to SIS Taiwan for direct support and hardware.
- * Tested and designed on the SiS620/5513 chipset.
+ *
+ * Thanks :
+ *
+ * SiS Taiwan		: for direct support and hardware.
+ * Daniela Engert	: for initial ATA100 advices and numerous others.
+ * John Fremlin, Manfred Spraul :
+ *			  for checking code correctness, providing patches.
+ *
+ *
+ * Original tests and design on the SiS620/5513 chipset.
+ * ATA100 tests and design on the SiS735/5513 chipset.
+ * ATA16/33 design from specs
+ */
+
+/*
+ * TODO:
+ *	- Get ridden of SisHostChipInfo[] completness dependancy.
+ *	- Get ATA-133 datasheets, implement ATA-133 init code.
+ *	- Study drivers/ide/ide-timing.h.
+ *	- Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them
+ *	  or remove ATA_00 define
+ *	- More checks in the config registers (force values instead of
+ *	  relying on the BIOS setting them correctly).
+ *	- Further optimisations ?
+ *	  . for example ATA66+ regs 0x48 & 0x4A
  */
 
 #include <linux/config.h>
@@ -28,88 +52,165 @@
 
 #include "ide_modes.h"
 
+/* When DEBUG is defined it outputs initial PCI config register
+   values and changes made to them by the driver */   
+// #define DEBUG
+/* When BROKEN_LEVEL is defined it limits the DMA mode
+   at boot time to its value */
+// #define BROKEN_LEVEL XFER_SW_DMA_0
 #define DISPLAY_SIS_TIMINGS
-#define SIS5513_DEBUG_DRIVE_INFO	0
 
-static struct pci_dev *host_dev = NULL;
+/* Miscellaneaous flags */
+#define SIS5513_LATENCY		0x01
+
+/* registers layout and init values are chipset family dependant */
+/* 1/ define families */
+#define ATA_00		0x00
+#define ATA_16		0x01
+#define ATA_33		0x02
+#define ATA_66		0x03
+#define ATA_100a	0x04 // SiS730 is ATA100 with ATA66 layout
+#define ATA_100		0x05
+#define ATA_133		0x06
+/* 2/ variable holding the controller chipset family value */
+static unsigned char chipset_family;
+
+
+/*
+ * Debug code: following IDE config registers' changes
+ */
+#ifdef DEBUG
+/* Copy of IDE Config registers 0x00 -> 0x57
+   Fewer might be used depending on the actual chipset */
+static unsigned char ide_regs_copy[0x58];
+
+static byte sis5513_max_config_register(void) {
+	switch(chipset_family) {
+		case ATA_00:
+		case ATA_16:	return 0x4f;
+		case ATA_33:	return 0x52;
+		case ATA_66:
+		case ATA_100a:
+		case ATA_100:
+		case ATA_133:
+		default:	return 0x57;
+	}
+}
+
+/* Read config registers, print differences from previous read */
+static void sis5513_load_verify_registers(struct pci_dev* dev, char* info) {
+	int i;
+	byte reg_val;
+	byte changed=0;
+	byte max = sis5513_max_config_register();
+
+	printk("SIS5513: %s, changed registers:\n", info);
+	for(i=0; i<=max; i++) {
+		pci_read_config_byte(dev, i, &reg_val);
+		if (reg_val != ide_regs_copy[i]) {
+			printk("%0#x: %0#x -> %0#x\n",
+			       i, ide_regs_copy[i], reg_val);
+			ide_regs_copy[i]=reg_val;
+			changed=1;
+		}
+	}
+
+	if (!changed) {
+		printk("none\n");
+	}
+}
 
-#define SIS5513_FLAG_ATA_00		0x00000000
-#define SIS5513_FLAG_ATA_16		0x00000001
-#define SIS5513_FLAG_ATA_33		0x00000002
-#define SIS5513_FLAG_ATA_66		0x00000004
-#define SIS5513_FLAG_LATENCY		0x00000010
+/* Load config registers, no printing */
+static void sis5513_load_registers(struct pci_dev* dev) {
+	int i;
+	byte max = sis5513_max_config_register();
 
+	for(i=0; i<=max; i++) {
+		pci_read_config_byte(dev, i, &(ide_regs_copy[i]));
+	}
+}
+
+/* Print a register */
+static void sis5513_print_register(int reg) {
+	printk(" %0#x:%0#x", reg, ide_regs_copy[reg]);
+}
+
+/* Print valuable registers */
+static void sis5513_print_registers(struct pci_dev* dev, char* marker) {
+	int i;
+	byte max = sis5513_max_config_register();
+
+	sis5513_load_registers(dev);
+	printk("SIS5513 %s\n", marker);
+	printk("SIS5513 dump:");
+	for(i=0x00; i<0x40; i++) {
+		if ((i % 0x10)==0) printk("\n             ");
+		sis5513_print_register(i);
+	}
+	for(; i<49; i++) {
+		sis5513_print_register(i);
+	}
+	printk("\n             ");
+
+	for(; i<=max; i++) {
+		sis5513_print_register(i);
+	}
+	printk("\n");
+}
+#endif
+
+
+/*
+ * Devices supported
+ */
 static const struct {
 	const char *name;
 	unsigned short host_id;
-	unsigned int flags;
+	unsigned char chipset_family;
+	unsigned char flags;
 } SiSHostChipInfo[] = {
-	{ "SiS530",	PCI_DEVICE_ID_SI_530,	SIS5513_FLAG_ATA_66, },
-	{ "SiS540",	PCI_DEVICE_ID_SI_540,	SIS5513_FLAG_ATA_66, },
-	{ "SiS620",	PCI_DEVICE_ID_SI_620,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS630",	PCI_DEVICE_ID_SI_630,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS635",	PCI_DEVICE_ID_SI_635,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS640",	PCI_DEVICE_ID_SI_640,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS645",	PCI_DEVICE_ID_SI_645,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS650",	PCI_DEVICE_ID_SI_650,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS730",	PCI_DEVICE_ID_SI_730,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS735",	PCI_DEVICE_ID_SI_735,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS740",	PCI_DEVICE_ID_SI_740,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS745",	PCI_DEVICE_ID_SI_745,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS750",	PCI_DEVICE_ID_SI_750,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS5591",	PCI_DEVICE_ID_SI_5591,	SIS5513_FLAG_ATA_33, },
-	{ "SiS5597",	PCI_DEVICE_ID_SI_5597,	SIS5513_FLAG_ATA_33, },
-	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	SIS5513_FLAG_ATA_33, },
-	{ "SiS5511",	PCI_DEVICE_ID_SI_5511,	SIS5513_FLAG_ATA_16, },
+	{ "SiS750",	PCI_DEVICE_ID_SI_750,	ATA_100,	SIS5513_LATENCY },
+	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_100,	SIS5513_LATENCY },
+	{ "SiS740",	PCI_DEVICE_ID_SI_740,	ATA_100,	SIS5513_LATENCY },
+	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100,	SIS5513_LATENCY },
+	{ "SiS730",	PCI_DEVICE_ID_SI_730,	ATA_100a,	SIS5513_LATENCY },
+	{ "SiS650",	PCI_DEVICE_ID_SI_650,	ATA_100,	SIS5513_LATENCY },
+	{ "SiS645",	PCI_DEVICE_ID_SI_645,	ATA_100,	SIS5513_LATENCY },
+	{ "SiS635",	PCI_DEVICE_ID_SI_635,	ATA_100,	SIS5513_LATENCY },
+	{ "SiS640",	PCI_DEVICE_ID_SI_640,	ATA_66,		SIS5513_LATENCY },
+	{ "SiS630",	PCI_DEVICE_ID_SI_630,	ATA_66,		SIS5513_LATENCY },
+	{ "SiS620",	PCI_DEVICE_ID_SI_620,	ATA_66,		SIS5513_LATENCY },
+	{ "SiS540",	PCI_DEVICE_ID_SI_540,	ATA_66,		0},
+	{ "SiS530",	PCI_DEVICE_ID_SI_530,	ATA_66,		0},
+	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	ATA_33,		0},
+	{ "SiS5598",	PCI_DEVICE_ID_SI_5598,	ATA_33,		0},
+	{ "SiS5597",	PCI_DEVICE_ID_SI_5597,	ATA_33,		0},
+	{ "SiS5591",	PCI_DEVICE_ID_SI_5591,	ATA_33,		0},
+	{ "SiS5513",	PCI_DEVICE_ID_SI_5513,	ATA_16,		0},
+	{ "SiS5511",	PCI_DEVICE_ID_SI_5511,	ATA_16,		0},
 };
 
-#if 0
-
-static struct _pio_mode_mapping {
-	byte data_active;
-	byte recovery;
-	byte pio_mode;
-} pio_mode_mapping[] = {
-	{ 8, 12, 0 },
-	{ 6,  7, 1 },
-	{ 4,  4, 2 },
-	{ 3,  3, 3 },
-	{ 3,  1, 4 }
+/* Cycle time bits and values vary accross chip dma capabilities
+   These three arrays hold the register layout and the values to set.
+   Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */
+static byte cycle_time_offset[] = {0,0,5,4,4,0,0};
+static byte cycle_time_range[] = {0,0,2,3,3,4,4};
+static byte cycle_time_value[][XFER_UDMA_5 - XFER_UDMA_0 + 1] = {
+	{0,0,0,0,0,0}, /* no udma */
+	{0,0,0,0,0,0}, /* no udma */
+	{3,2,1,0,0,0},
+	{7,5,3,2,1,0},
+	{7,5,3,2,1,0},
+	{11,7,5,4,2,1},
+	{0,0,0,0,0,0} /* not yet known, ask SiS */
 };
 
-static struct _dma_mode_mapping {
-	byte data_active;
-	byte recovery;
-	byte dma_mode;
-} dma_mode_mapping[] = {
-	{ 8, 8, 0 },
-	{ 3, 2, 1 },
-	{ 3, 1, 2 }
-};
-
-static struct _udma_mode_mapping {
-	byte cycle_time;
-	char * udma_mode;
-} udma_mode_mapping[] = {
-	{ 8, "Mode 0" },
-	{ 6, "Mode 1" },
-	{ 4, "Mode 2" }, 
-	{ 3, "Mode 3" },
-	{ 2, "Mode 4" },
-	{ 0, "Mode 5" }
-};
+static struct pci_dev *host_dev = NULL;
 
-static __inline__ char * find_udma_mode (byte cycle_time)
-{
-	int n;
-	
-	for (n = 0; n <= 4; n++)
-		if (udma_mode_mapping[n].cycle_time <= cycle_time)
-			return udma_mode_mapping[n].udma_mode;
-	return udma_mode_mapping[4].udma_mode;
-}
-#endif
 
+/*
+ * Printing configuration
+ */
 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
@@ -118,12 +219,12 @@
 extern int (*sis_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 static struct pci_dev *bmide_dev;
 
-static char *cable_type[] = {
+static char* cable_type[] = {
 	"80 pins",
 	"40 pins"
 };
 
-static char *recovery_time [] ={
+static char* recovery_time[] ={
 	"12 PCICLK", "1 PCICLK",
 	"2 PCICLK", "3 PCICLK",
 	"4 PCICLK", "5 PCICLCK",
@@ -134,101 +235,184 @@
 	"15 PCICLK", "15 PCICLK"
 };
 
-static char * cycle_time [] = {
-	"2 CLK", "2 CLK",
-	"3 CLK", "4 CLK",
-	"5 CLK", "6 CLK",
-	"7 CLK", "8 CLK"
-};
-
-static char * active_time [] = {
+static char* active_time[] = {
 	"8 PCICLK", "1 PCICLCK",
-	"2 PCICLK", "2 PCICLK",
+	"2 PCICLK", "3 PCICLK",
 	"4 PCICLK", "5 PCICLK",
 	"6 PCICLK", "12 PCICLK"
 };
 
+static char* cycle_time[] = {
+	"Reserved", "2 CLK",
+	"3 CLK", "4 CLK",
+	"5 CLK", "6 CLK",
+	"7 CLK", "8 CLK",
+	"9 CLK", "10 CLK",
+	"11 CLK", "12 CLK",
+	"Reserved", "Reserved",
+	"Reserved", "Reserved"
+};
+
+/* Generic add master or slave info function */
+static char* get_drives_info (char *buffer, byte pos)
+{
+	byte reg00, reg01, reg10, reg11; /* timing registers */
+	char* p = buffer;
+
+/* Postwrite/Prefetch */
+	pci_read_config_byte(bmide_dev, 0x4b, &reg00);
+	p += sprintf(p, "Drive %d:        Postwrite %s \t \t Postwrite %s\n",
+		     pos, (reg00 & (0x10 << pos)) ? "Enabled" : "Disabled",
+		     (reg00 & (0x40 << pos)) ? "Enabled" : "Disabled");
+	p += sprintf(p, "                Prefetch  %s \t \t Prefetch  %s\n",
+		     (reg00 & (0x01 << pos)) ? "Enabled" : "Disabled",
+		     (reg00 & (0x04 << pos)) ? "Enabled" : "Disabled");
+
+	pci_read_config_byte(bmide_dev, 0x40+2*pos, &reg00);
+	pci_read_config_byte(bmide_dev, 0x41+2*pos, &reg01);
+	pci_read_config_byte(bmide_dev, 0x44+2*pos, &reg10);
+	pci_read_config_byte(bmide_dev, 0x45+2*pos, &reg11);
+
+/* UDMA */
+	if (chipset_family >= ATA_33) {
+		p += sprintf(p, "                UDMA %s \t \t \t UDMA %s\n",
+			     (reg01 & 0x80)  ? "Enabled" : "Disabled",
+			     (reg11 & 0x80) ? "Enabled" : "Disabled");
+
+		p += sprintf(p, "                UDMA Cycle Time    ");
+		switch(chipset_family) {
+			case ATA_33:	p += sprintf(p, cycle_time[(reg01 & 0x60) >> 5]); break;
+			case ATA_66:
+			case ATA_100a:	p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break;
+			case ATA_100:	p += sprintf(p, cycle_time[reg01 & 0x0F]); break;
+			case ATA_133:
+			default:	p += sprintf(p, "133+ ?"); break;
+		}
+		p += sprintf(p, " \t UDMA Cycle Time    ");
+		switch(chipset_family) {
+			case ATA_33:	p += sprintf(p, cycle_time[(reg11 & 0x60) >> 5]); break;
+			case ATA_66:
+			case ATA_100a:	p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break;
+			case ATA_100:	p += sprintf(p, cycle_time[reg11 & 0x0F]); break;
+			case ATA_133:
+			default:	p += sprintf(p, "133+ ?"); break;
+		}
+		p += sprintf(p, "\n");
+	}
+
+/* Data Active */
+	p += sprintf(p, "                Data Active Time   ");
+	switch(chipset_family) {
+		case ATA_00:
+		case ATA_16: /* confirmed */
+		case ATA_33:
+		case ATA_66:
+		case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
+		case ATA_100: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
+		case ATA_133:
+		default: p += sprintf(p, "133+ ?"); break;
+	}
+	p += sprintf(p, " \t Data Active Time   ");
+	switch(chipset_family) {
+		case ATA_00:
+		case ATA_16:
+		case ATA_33:
+		case ATA_66:
+		case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
+		case ATA_100: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
+		case ATA_133:
+		default: p += sprintf(p, "133+ ?"); break;
+	}
+	p += sprintf(p, "\n");
+
+/* Data Recovery */
+	/* warning: may need (reg&0x07) for pre ATA66 chips */
+	p += sprintf(p, "                Data Recovery Time %s \t Data Recovery Time %s\n",
+		     recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]);
+
+	return p;
+}
+
+static char* get_masters_info(char* buffer)
+{
+	return get_drives_info(buffer, 0);
+}
+
+static char* get_slaves_info(char* buffer)
+{
+	return get_drives_info(buffer, 1);
+}
+
+/* Main get_info, called on /proc/ide/sis reads */
 static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
 {
-	int rc;
 	char *p = buffer;
-	byte reg,reg1;
+	byte reg;
 	u16 reg2, reg3;
 
+	p += sprintf(p, "\nSiS 5513 ");
+	switch(chipset_family) {
+		case ATA_00: p += sprintf(p, "Unknown???"); break;
+		case ATA_16: p += sprintf(p, "DMA 16"); break;
+		case ATA_33: p += sprintf(p, "Ultra 33"); break;
+		case ATA_66: p += sprintf(p, "Ultra 66"); break;
+		case ATA_100a:
+		case ATA_100: p += sprintf(p, "Ultra 100"); break;
+		case ATA_133:
+		default: p+= sprintf(p, "Ultra 133+"); break;
+	}
+	p += sprintf(p, " chipset\n");
 	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
-	rc = pci_read_config_byte(bmide_dev, 0x4a, &reg);
-	p += sprintf(p, "Channel Status: %s \t \t \t \t %s \n",
-		     (reg & 0x02) ? "On" : "Off",
-		     (reg & 0x04) ? "On" : "Off");
-		     
-	rc = pci_read_config_byte(bmide_dev, 0x09, &reg);
+
+/* Status */
+	pci_read_config_byte(bmide_dev, 0x4a, &reg);
+	p += sprintf(p, "Channel Status: ");
+	if (chipset_family < ATA_66) {
+		p += sprintf(p, "%s \t \t \t \t %s\n",
+			     (reg & 0x04) ? "On" : "Off",
+			     (reg & 0x02) ? "On" : "Off");
+	} else {
+		p += sprintf(p, "%s \t \t \t \t %s \n",
+			     (reg & 0x02) ? "On" : "Off",
+			     (reg & 0x04) ? "On" : "Off");
+	}
+
+/* Operation Mode */
+	pci_read_config_byte(bmide_dev, 0x09, &reg);
 	p += sprintf(p, "Operation Mode: %s \t \t \t %s \n",
 		     (reg & 0x01) ? "Native" : "Compatible",
 		     (reg & 0x04) ? "Native" : "Compatible");
-		     	     
-	rc = pci_read_config_byte(bmide_dev, 0x48, &reg);
-	p += sprintf(p, "Cable Type:     %s \t \t \t %s\n",
-		     (reg & 0x10) ? cable_type[1] : cable_type[0],
-		     (reg & 0x20) ? cable_type[1] : cable_type[0]);
-		     
-	rc = pci_read_config_word(bmide_dev, 0x4c, &reg2);
-	rc = pci_read_config_word(bmide_dev, 0x4e, &reg3);
-	p += sprintf(p, "Prefetch Count: %d \t \t \t \t %d\n",
-		     reg2, reg3);
-
-	rc = pci_read_config_byte(bmide_dev, 0x4b, &reg);	     
-	p += sprintf(p, "Drive 0:        Postwrite %s \t \t Postwrite %s\n",
-		     (reg & 0x10) ? "Enabled" : "Disabled",
-		     (reg & 0x40) ? "Enabled" : "Disabled");
-	p += sprintf(p, "                Prefetch  %s \t \t Prefetch  %s\n",
-		     (reg & 0x01) ? "Enabled" : "Disabled",
-		     (reg & 0x04) ? "Enabled" : "Disabled");
-		          
-	rc = pci_read_config_byte(bmide_dev, 0x41, &reg);
-	rc = pci_read_config_byte(bmide_dev, 0x45, &reg1);
-	p += sprintf(p, "                UDMA %s \t \t \t UDMA %s\n",
-		     (reg & 0x80)  ? "Enabled" : "Disabled",
-		     (reg1 & 0x80) ? "Enabled" : "Disabled");
-	p += sprintf(p, "                UDMA Cycle Time    %s \t UDMA Cycle Time    %s\n",
-		     cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
-	p += sprintf(p, "                Data Active Time   %s \t Data Active Time   %s\n",
-		     active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); 
-
-	rc = pci_read_config_byte(bmide_dev, 0x40, &reg);
-	rc = pci_read_config_byte(bmide_dev, 0x44, &reg1);
-	p += sprintf(p, "                Data Recovery Time %s \t Data Recovery Time %s\n",
-		     recovery_time[(reg & 0x0f)], recovery_time[(reg1 & 0x0f)]);
 
+/* 80-pin cable ? */
+	if (chipset_family > ATA_33) {
+		pci_read_config_byte(bmide_dev, 0x48, &reg);
+		p += sprintf(p, "Cable Type:     %s \t \t \t %s\n",
+			     (reg & 0x10) ? cable_type[1] : cable_type[0],
+			     (reg & 0x20) ? cable_type[1] : cable_type[0]);
+	}
 
-	rc = pci_read_config_byte(bmide_dev, 0x4b, &reg);	     
-	p += sprintf(p, "Drive 1:        Postwrite %s \t \t Postwrite %s\n",
-		     (reg & 0x20) ? "Enabled" : "Disabled",
-		     (reg & 0x80) ? "Enabled" : "Disabled");
-	p += sprintf(p, "                Prefetch  %s \t \t Prefetch  %s\n",
-		     (reg & 0x02) ? "Enabled" : "Disabled",
-		     (reg & 0x08) ? "Enabled" : "Disabled");
+/* Prefetch Count */
+	pci_read_config_word(bmide_dev, 0x4c, &reg2);
+	pci_read_config_word(bmide_dev, 0x4e, &reg3);
+	p += sprintf(p, "Prefetch Count: %d \t \t \t \t %d\n",
+		     reg2, reg3);
 
-	rc = pci_read_config_byte(bmide_dev, 0x43, &reg);
-	rc = pci_read_config_byte(bmide_dev, 0x47, &reg1);
-	p += sprintf(p, "                UDMA %s \t \t \t UDMA %s\n",
-		     (reg & 0x80)  ? "Enabled" : "Disabled",
-		     (reg1 & 0x80) ? "Enabled" : "Disabled");
-	p += sprintf(p, "                UDMA Cycle Time    %s \t UDMA Cycle Time    %s\n",
-		     cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
-	p += sprintf(p, "                Data Active Time   %s \t Data Active Time   %s\n",
-		     active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); 
+	p = get_masters_info(p);
+	p = get_slaves_info(p);
 
-	rc = pci_read_config_byte(bmide_dev, 0x42, &reg);
-	rc = pci_read_config_byte(bmide_dev, 0x46, &reg1);
-	p += sprintf(p, "                Data Recovery Time %s \t Data Recovery Time %s\n",
-		     recovery_time[(reg & 0x0f)], recovery_time[(reg1 & 0x0f)]);
 	return p-buffer;
 }
 #endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
 
+
 byte sis_proc = 0;
 extern char *ide_xfer_verbose (byte xfer_rate);
 
+
+/*
+ * Configuration functions
+ */
+/* Enables per-drive prefetch and postwrite */
 static void config_drive_art_rwp (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -237,14 +421,24 @@
 	byte reg4bh		= 0;
 	byte rw_prefetch	= (0x11 << drive->dn);
 
-	pci_read_config_byte(dev, 0x4b, &reg4bh);
+#ifdef DEBUG
+	printk("SIS5513: config_drive_art_rwp, drive %d\n", drive->dn);
+	sis5513_load_verify_registers(dev, "config_drive_art_rwp start");
+#endif
+
 	if (drive->media != ide_disk)
 		return;
-	
+	pci_read_config_byte(dev, 0x4b, &reg4bh);
+
 	if ((reg4bh & rw_prefetch) != rw_prefetch)
 		pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
+#ifdef DEBUG
+	sis5513_load_verify_registers(dev, "config_drive_art_rwp end");
+#endif
 }
 
+
+/* Set per-drive active and recovery time */
 static void config_art_rwp_pio (ide_drive_t *drive, byte pio)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -255,6 +449,10 @@
 	unsigned short eide_pio_timing[6] = {600, 390, 240, 180, 120, 90};
 	unsigned short xfer_pio = drive->id->eide_pio_modes;
 
+#ifdef DEBUG
+	sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
+#endif
+
 	config_drive_art_rwp(drive);
 	pio = ide_get_best_pio_mode(drive, 255, pio, NULL);
 
@@ -263,8 +461,8 @@
 
 	if (drive->id->eide_pio_iordy > 0) {
 		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
+			(xfer_pio > 0) &&
+			(drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]);
 			xfer_pio--);
 	} else {
 		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
@@ -274,14 +472,10 @@
 
 	timing = (xfer_pio >= pio) ? xfer_pio : pio;
 
-/*
- *               Mode 0       Mode 1     Mode 2     Mode 3     Mode 4
- * Active time    8T (240ns)  6T (180ns) 4T (120ns) 3T  (90ns) 3T  (90ns)
- * 0x41 2:0 bits  000          110        100        011        011
- * Recovery time 12T (360ns)  7T (210ns) 4T (120ns) 3T  (90ns) 1T  (30ns)
- * 0x40 3:0 bits 0000         0111       0100       0011       0001
- * Cycle time    20T (600ns) 13T (390ns) 8T (240ns) 6T (180ns) 4T (120ns)
- */
+#ifdef DEBUG
+	printk("SIS5513: config_drive_art_rwp_pio, drive %d, pio %d, timing %d\n",
+	       drive->dn, pio, timing);
+#endif
 
 	switch(drive->dn) {
 		case 0:		drive_pci = 0x40; break;
@@ -291,31 +485,43 @@
 		default:	return;
 	}
 
-	pci_read_config_byte(dev, drive_pci, &test1);
-	pci_read_config_byte(dev, drive_pci|0x01, &test2);
-
-	/*
-	 * Do a blanket clear of active and recovery timings.
-	 */
-
-	test1 &= ~0x07;
-	test2 &= ~0x0F;
-
-	switch(timing) {
-		case 4:		test1 |= 0x01; test2 |= 0x03; break;
-		case 3:		test1 |= 0x03; test2 |= 0x03; break;
-		case 2:		test1 |= 0x04; test2 |= 0x04; break;
-		case 1:		test1 |= 0x07; test2 |= 0x06; break;
-		default:	break;
+	/* register layout changed with newer ATA100 chips */
+	if (chipset_family < ATA_100) {
+		pci_read_config_byte(dev, drive_pci, &test1);
+		pci_read_config_byte(dev, drive_pci+1, &test2);
+
+		/* Clear active and recovery timings */
+		test1 &= ~0x0F;
+		test2 &= ~0x07;
+
+		switch(timing) {
+			case 4:		test1 |= 0x01; test2 |= 0x03; break;
+			case 3:		test1 |= 0x03; test2 |= 0x03; break;
+			case 2:		test1 |= 0x04; test2 |= 0x04; break;
+			case 1:		test1 |= 0x07; test2 |= 0x06; break;
+			default:	break;
+		}
+		pci_write_config_byte(dev, drive_pci, test1);
+		pci_write_config_byte(dev, drive_pci+1, test2);
+	} else {
+		switch(timing) { /*   active  recovery
+					  v     v */
+			case 4:		test1 = 0x30|0x01; break;
+			case 3:		test1 = 0x30|0x03; break;
+			case 2:		test1 = 0x40|0x04; break;
+			case 1:		test1 = 0x60|0x07; break;
+			default:	break;
+		}
+		pci_write_config_byte(dev, drive_pci, test1);
 	}
 
-	pci_write_config_byte(dev, drive_pci, test1);
-	pci_write_config_byte(dev, drive_pci|0x01, test2);
+#ifdef DEBUG
+	sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
+#endif
 }
 
 static int config_chipset_for_pio (ide_drive_t *drive, byte pio)
 {
-	int err;
 	byte speed;
 
 	switch(pio) {
@@ -328,8 +534,7 @@
 
 	config_art_rwp_pio(drive, pio);
 	drive->current_speed = speed;
-	err = ide_config_drive_speed(drive, speed);
-	return err;
+	return ide_config_drive_speed(drive, speed);
 }
 
 static int sis5513_tune_chipset (ide_drive_t *drive, byte speed)
@@ -337,82 +542,73 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
 
-	byte			drive_pci, test1, test2;
-	byte			unmask, four_two, mask = 0;
-
-	if (host_dev) {
-		switch(host_dev->device) {
-			case PCI_DEVICE_ID_SI_530:
-			case PCI_DEVICE_ID_SI_540:
-			case PCI_DEVICE_ID_SI_620:
-			case PCI_DEVICE_ID_SI_630:
-			case PCI_DEVICE_ID_SI_635:
-			case PCI_DEVICE_ID_SI_640:
-			case PCI_DEVICE_ID_SI_645:
-			case PCI_DEVICE_ID_SI_650:
-			case PCI_DEVICE_ID_SI_730:
-			case PCI_DEVICE_ID_SI_735:
-			case PCI_DEVICE_ID_SI_740:
-			case PCI_DEVICE_ID_SI_745:
-			case PCI_DEVICE_ID_SI_750:
-				unmask   = 0xF0;
-				four_two = 0x01;
-				break;
-			default:
-				unmask   = 0xE0;
-				four_two = 0x00;
-				break;
-		}
-	} else {
-		unmask   = 0xE0;
-		four_two = 0x00;
-	}
+	byte			drive_pci, reg;
 
+#ifdef DEBUG
+	sis5513_load_verify_registers(dev, "sis5513_tune_chipset start");
+	printk("SIS5513: sis5513_tune_chipset, drive %d, speed %d\n",
+	       drive->dn, speed);
+#endif
 	switch(drive->dn) {
-		case 0:		drive_pci = 0x40;break;
-		case 1:		drive_pci = 0x42;break;
-		case 2:		drive_pci = 0x44;break;
-		case 3:		drive_pci = 0x46;break;
+		case 0:		drive_pci = 0x40; break;
+		case 1:		drive_pci = 0x42; break;
+		case 2:		drive_pci = 0x44; break;
+		case 3:		drive_pci = 0x46; break;
 		default:	return ide_dma_off;
 	}
 
-	pci_read_config_byte(dev, drive_pci, &test1);
-	pci_read_config_byte(dev, drive_pci|0x01, &test2);
+#ifdef BROKEN_LEVEL
+#ifdef DEBUG
+	printk("SIS5513: BROKEN_LEVEL activated, speed=%d -> speed=%d\n", speed, BROKEN_LEVEL);
+#endif
+	if (speed > BROKEN_LEVEL) speed = BROKEN_LEVEL;
+#endif
 
-	if ((speed <= XFER_MW_DMA_2) && (test2 & 0x80)) {
-		pci_write_config_byte(dev, drive_pci|0x01, test2 & ~0x80);
-		pci_read_config_byte(dev, drive_pci|0x01, &test2);
-	} else {
-		pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
+	pci_read_config_byte(dev, drive_pci+1, &reg);
+	/* Disable UDMA bit for non UDMA modes on UDMA chips */
+	if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) {
+		reg &= 0x7F;
+		pci_write_config_byte(dev, drive_pci+1, reg);
 	}
 
+	/* Config chip for mode */
 	switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
-		case XFER_UDMA_5: mask = 0x80; break;
-		case XFER_UDMA_4: mask = 0x90; break;
-		case XFER_UDMA_3: mask = 0xA0; break;
-		case XFER_UDMA_2: mask = (four_two) ? 0xB0 : 0xA0; break;
-		case XFER_UDMA_1: mask = (four_two) ? 0xD0 : 0xC0; break;
-		case XFER_UDMA_0: mask = unmask; break;
+		case XFER_UDMA_5:
+		case XFER_UDMA_4:
+		case XFER_UDMA_3:
+		case XFER_UDMA_2:
+		case XFER_UDMA_1:
+		case XFER_UDMA_0:
+			/* Force the UDMA bit on if we want to use UDMA */
+			reg |= 0x80;
+			/* clean reg cycle time bits */
+			reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family]))
+				 << cycle_time_offset[chipset_family]);
+			/* set reg cycle time bits */
+			reg |= cycle_time_value[chipset_family-ATA_00][speed-XFER_UDMA_0]
+				<< cycle_time_offset[chipset_family];
+			pci_write_config_byte(dev, drive_pci+1, reg);
+			break;
 		case XFER_MW_DMA_2:
 		case XFER_MW_DMA_1:
 		case XFER_MW_DMA_0:
 		case XFER_SW_DMA_2:
 		case XFER_SW_DMA_1:
-		case XFER_SW_DMA_0: break;
+		case XFER_SW_DMA_0:
+			break;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 		case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
 		case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
 		case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
 		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
 		case XFER_PIO_0:
-		default:	 return((int) config_chipset_for_pio(drive, 0));
+		default:	 return((int) config_chipset_for_pio(drive, 0));	
 	}
-
-	if (speed > XFER_MW_DMA_2)
-		pci_write_config_byte(dev, drive_pci|0x01, test2|mask);
-
 	drive->current_speed = speed;
+#ifdef DEBUG
+	sis5513_load_verify_registers(dev, "sis5513_tune_chipset end");
+#endif
 	return ((int) ide_config_drive_speed(drive, speed));
 }
 
@@ -430,47 +626,27 @@
 	struct hd_driveid *id	= drive->id;
 	ide_hwif_t *hwif	= HWIF(drive);
 
-	byte			four_two = 0, speed = 0;
-	int			err;
+	byte			speed = 0;
 
 	byte unit		= (drive->select.b.unit & 0x01);
 	byte udma_66		= eighty_ninty_three(drive);
-	byte ultra_100		= 0;
 
-	if (host_dev) {
-		switch(host_dev->device) {
-			case PCI_DEVICE_ID_SI_635:
-			case PCI_DEVICE_ID_SI_640:
-			case PCI_DEVICE_ID_SI_645:
-			case PCI_DEVICE_ID_SI_650:
-			case PCI_DEVICE_ID_SI_730:
-			case PCI_DEVICE_ID_SI_735:
-			case PCI_DEVICE_ID_SI_740:
-			case PCI_DEVICE_ID_SI_745:
-			case PCI_DEVICE_ID_SI_750:
-				ultra_100 = 1;
-			case PCI_DEVICE_ID_SI_530:
-			case PCI_DEVICE_ID_SI_540:
-			case PCI_DEVICE_ID_SI_620:
-			case PCI_DEVICE_ID_SI_630:
-				four_two = 0x01;
-				break;
-			default:
-				four_two = 0x00; break;
-		}
-	}
+#ifdef DEBUG
+	printk("SIS5513: config_chipset_for_dma, drive %d, ultra %d\n",
+	       drive->dn, ultra);
+#endif
 
-	if ((id->dma_ultra & 0x0020) && (ultra) && (udma_66) && (four_two) && (ultra_100))
+	if ((id->dma_ultra & 0x0020) && ultra && udma_66 && (chipset_family >= ATA_100a))
 		speed = XFER_UDMA_5;
-	else if ((id->dma_ultra & 0x0010) && (ultra) && (udma_66) && (four_two))
+	else if ((id->dma_ultra & 0x0010) && ultra && udma_66 && (chipset_family >= ATA_66))
 		speed = XFER_UDMA_4;
-	else if ((id->dma_ultra & 0x0008) && (ultra) && (udma_66) && (four_two))
+	else if ((id->dma_ultra & 0x0008) && ultra && udma_66 && (chipset_family >= ATA_66))
 		speed = XFER_UDMA_3;
-	else if ((id->dma_ultra & 0x0004) && (ultra))
+	else if ((id->dma_ultra & 0x0004) && ultra && (chipset_family >= ATA_33))
 		speed = XFER_UDMA_2;
-	else if ((id->dma_ultra & 0x0002) && (ultra))
+	else if ((id->dma_ultra & 0x0002) && ultra && (chipset_family >= ATA_33))
 		speed = XFER_UDMA_1;
-	else if ((id->dma_ultra & 0x0001) && (ultra))
+	else if ((id->dma_ultra & 0x0001) && ultra && (chipset_family >= ATA_33))
 		speed = XFER_UDMA_0;
 	else if (id->dma_mword & 0x0004)
 		speed = XFER_MW_DMA_2;
@@ -489,11 +665,7 @@
 
 	outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
 
-	err = sis5513_tune_chipset(drive, speed);
-
-#if SIS5513_DEBUG_DRIVE_INFO
-	printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
-#endif /* SIS5513_DEBUG_DRIVE_INFO */
+	sis5513_tune_chipset(drive, speed);
 
 	return ((int)	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
@@ -507,6 +679,8 @@
 	struct hd_driveid *id		= drive->id;
 	ide_dma_action_t dma_func	= ide_dma_off_quietly;
 
+	(void) config_chipset_for_pio(drive, 5);
+
 	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
@@ -550,9 +724,7 @@
 	return HWIF(drive)->dmaproc(dma_func, drive);
 }
 
-/*
- * sis5513_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
- */
+/* initiates/aborts (U)DMA read/write operations on a drive. */
 int sis5513_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 {
 	switch (func) {
@@ -567,15 +739,14 @@
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
+/* Chip detection and general config */
 unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
 {
 	struct pci_dev *host;
 	int i = 0;
-	byte latency = 0;
 
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
-
-	for (i = 0; i < ARRAY_SIZE (SiSHostChipInfo) && !host_dev; i++) {
+	/* Find the chip */
+	for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !host_dev; i++) {
 		host = pci_find_device (PCI_VENDOR_ID_SI,
 					SiSHostChipInfo[i].host_id,
 					NULL);
@@ -583,30 +754,71 @@
 			continue;
 
 		host_dev = host;
+		chipset_family = SiSHostChipInfo[i].chipset_family;
 		printk(SiSHostChipInfo[i].name);
 		printk("\n");
-		if (SiSHostChipInfo[i].flags & SIS5513_FLAG_LATENCY) {
-			if (latency != 0x10)
-				pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);
+
+#ifdef DEBUG
+		sis5513_print_registers(dev, "pci_init_sis5513 start");
+#endif
+
+		if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) {
+			byte latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */
+			pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
 		}
 	}
 
+	/* Make general config ops here
+	   1/ tell IDE channels to operate in Compabitility mode only
+	   2/ tell old chips to allow per drive IDE timings */
 	if (host_dev) {
-		byte reg52h = 0;
-
-		pci_read_config_byte(dev, 0x52, &reg52h);
-		if (!(reg52h & 0x04)) {
-			/* set IDE controller to operate in Compabitility mode only */
-			pci_write_config_byte(dev, 0x52, reg52h|0x04);
+		byte reg;
+		switch(chipset_family) {
+			case ATA_133:
+			case ATA_100:
+				/* Set compatibility bit */
+				pci_read_config_byte(dev, 0x49, &reg);
+				if (!(reg & 0x01)) {
+					pci_write_config_byte(dev, 0x49, reg|0x01);
+				}
+				break;
+			case ATA_100a:
+			case ATA_66:
+				/* On ATA_66 chips the bit was elsewhere */
+				pci_read_config_byte(dev, 0x52, &reg);
+				if (!(reg & 0x04)) {
+					pci_write_config_byte(dev, 0x52, reg|0x04);
+				}
+				break;
+			case ATA_33:
+				/* On ATA_33 we didn't have a single bit to set */
+				pci_read_config_byte(dev, 0x09, &reg);
+				if ((reg & 0x0f) != 0x00) {
+					pci_write_config_byte(dev, 0x09, reg&0xf0);
+				}
+			case ATA_16:
+				/* force per drive recovery and active timings
+				   needed on ATA_33 and below chips */
+				pci_read_config_byte(dev, 0x52, &reg);
+				if (!(reg & 0x08)) {
+					pci_write_config_byte(dev, 0x52, reg|0x08);
+				}
+				break;
+			case ATA_00:
+			default: break;
 		}
+
 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
 		if (!sis_proc) {
 			sis_proc = 1;
 			bmide_dev = dev;
 			sis_display_info = &sis_get_info;
 		}
-#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
+#endif
 	}
+#ifdef DEBUG
+	sis5513_load_verify_registers(dev, "pci_init_sis5513 end");
+#endif
 	return 0;
 }
 
@@ -616,27 +828,10 @@
 	byte mask = hwif->channel ? 0x20 : 0x10;
 	pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);
 
-	if (host_dev) {
-		switch(host_dev->device) {
-			case PCI_DEVICE_ID_SI_530:
-			case PCI_DEVICE_ID_SI_540:
-			case PCI_DEVICE_ID_SI_620:
-			case PCI_DEVICE_ID_SI_630:
-			case PCI_DEVICE_ID_SI_635:
-			case PCI_DEVICE_ID_SI_640:
-			case PCI_DEVICE_ID_SI_645:
-			case PCI_DEVICE_ID_SI_650:
-			case PCI_DEVICE_ID_SI_730:
-			case PCI_DEVICE_ID_SI_735:
-			case PCI_DEVICE_ID_SI_740:
-			case PCI_DEVICE_ID_SI_745:
-			case PCI_DEVICE_ID_SI_750:
-				ata66 = (reg48h & mask) ? 0 : 1;
-			default:
-				break;
-		}
+	if (chipset_family >= ATA_66) {
+		ata66 = (reg48h & mask) ? 0 : 1;
 	}
-        return (ata66);
+        return ata66;
 }
 
 void __init ide_init_sis5513 (ide_hwif_t *hwif)
@@ -651,33 +846,16 @@
 		return;
 
 	if (host_dev) {
-		switch(host_dev->device) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
-			case PCI_DEVICE_ID_SI_530:
-			case PCI_DEVICE_ID_SI_540:
-			case PCI_DEVICE_ID_SI_620:
-			case PCI_DEVICE_ID_SI_630:
-			case PCI_DEVICE_ID_SI_635:
-			case PCI_DEVICE_ID_SI_640:
-			case PCI_DEVICE_ID_SI_645:
-			case PCI_DEVICE_ID_SI_650:
-			case PCI_DEVICE_ID_SI_730:
-			case PCI_DEVICE_ID_SI_735:
-			case PCI_DEVICE_ID_SI_740:
-			case PCI_DEVICE_ID_SI_745:
-			case PCI_DEVICE_ID_SI_750:
-			case PCI_DEVICE_ID_SI_5600:
-			case PCI_DEVICE_ID_SI_5597:
-			case PCI_DEVICE_ID_SI_5591:
-				if (!noautodma)
-					hwif->autodma = 1;
-				hwif->dmaproc = &sis5513_dmaproc;
-				break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-			default:
-				hwif->autodma = 0;
-				break;
+		if (chipset_family > ATA_16) {
+			hwif->autodma = noautodma ? 0 : 1;
+			hwif->dmaproc = &sis5513_dmaproc;
+		} else {
+#endif
+			hwif->autodma = 0;
+#ifdef CONFIG_BLK_DEV_IDEDMA
 		}
+#endif
 	}
 	return;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/slc90e66.c linux/drivers/ide/slc90e66.c
--- linux.orig/drivers/ide/slc90e66.c	2001-07-15 23:22:23.000000000 +0000
+++ linux/drivers/ide/slc90e66.c	2002-07-20 01:08:23.000000000 +0000
@@ -86,8 +86,13 @@
          * at that point bibma+0x2 et bibma+0xa are byte registers
          * to investigate:
          */
+#ifdef __mips__	/* only for mips? */
+	c0 = inb_p(bibma + 0x02);
+	c1 = inb_p(bibma + 0x0a);
+#else
 	c0 = inb_p((unsigned short)bibma + 0x02);
 	c1 = inb_p((unsigned short)bibma + 0x0a);
+#endif
 
 	p += sprintf(p, "                                SLC90E66 Chipset.\n");
 	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
@@ -253,7 +258,9 @@
 		case XFER_MW_DMA_2:
 		case XFER_MW_DMA_1:
 		case XFER_SW_DMA_2:	break;
+#if 0	/* allow PIO modes */
 		default:		return -1;
+#endif
 	}
 
 	if (speed >= XFER_UDMA_0) {
@@ -291,6 +298,13 @@
 	byte speed		= 0;
 	byte udma_66		= eighty_ninty_three(drive);
 
+#if 1 /* allow PIO modes */
+	if (!HWIF(drive)->autodma) {
+		speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+		(void) slc90e66_tune_chipset(drive, speed);
+		return ((int) ide_dma_off_quietly);
+	}
+#endif
 	if ((id->dma_ultra & 0x0010) && (ultra)) {
 		speed = (udma_66) ? XFER_UDMA_4 : XFER_UDMA_2;
 	} else if ((id->dma_ultra & 0x0008) && (ultra)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c
--- linux.orig/drivers/ide/via82cxxx.c	2001-09-11 15:40:36.000000000 +0000
+++ linux/drivers/ide/via82cxxx.c	2002-07-20 01:08:31.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: via82cxxx.c,v 3.29 2001/09/10 10:06:00 vojtech Exp $
+ * $Id: via82cxxx.c,v 3.34 2002/02/12 11:26:11 vojtech Exp $
  *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
@@ -7,23 +7,21 @@
  *	Michel Aubry
  *	Jeff Garzik
  *	Andre Hedrick
- *
- *  Sponsored by SuSE
  */
 
 /*
  * VIA IDE driver for Linux. Supports
  *
  *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
- *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233
+ *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a
  *
  * southbridges, which can be found in
  *
  *  VIA Apollo Master, VP, VP2, VP2/97, VP3, VPX, VPX/97, MVP3, MVP4, P6, Pro,
  *    ProII, ProPlus, Pro133, Pro133+, Pro133A, Pro133A Dual, Pro133T, Pro133Z,
  *    PLE133, PLE133T, Pro266, Pro266T, ProP4X266, PM601, PM133, PN133, PL133T,
- *    PX266, PM266, KX133, KT133, KT133A, KLE133, KT266, KX266, KM133, KM133A,
- *    KL133, KN133, KM266
+ *    PX266, PM266, KX133, KT133, KT133A, KT133E, KLE133, KT266, KX266, KM133,
+ *    KM133A, KL133, KN133, KM266
  *  PC-Chips VXPro, VXPro+, VXTwo, TXPro-III, TXPro-AGP, AGPPro, ViaGra, BXToo,
  *    BXTel, BXpert
  *  AMD 640, 640 AGP, 750 IronGate, 760, 760MP
@@ -32,9 +30,9 @@
  *
  * chipsets. Supports
  *
- *   PIO 0-5, MWDMA 0-2, SWDMA 0-2 and UDMA 0-5
+ *   PIO 0-5, MWDMA 0-2, SWDMA 0-2 and UDMA 0-6
  *
- * (this includes UDMA33, 66 and 100) modes. UDMA66 and higher modes are
+ * (this includes UDMA33, 66, 100 and 133) modes. UDMA66 and higher modes are
  * autoenabled only in case the BIOS has detected a 80 wire cable. To ignore
  * the BIOS data and assume the cable is present, use 'ide0=ata66' or
  * 'ide1=ata66' on the kernel command line.
@@ -56,8 +54,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
 #include <linux/config.h>
@@ -87,10 +85,12 @@
 #define VIA_UDMA_33		0x001
 #define VIA_UDMA_66		0x002
 #define VIA_UDMA_100		0x003
+#define VIA_UDMA_133		0x004
 #define VIA_BAD_PREQ		0x010	/* Crashes if PREQ# till DDACK# set */
 #define VIA_BAD_CLK66		0x020	/* 66 MHz clock doesn't work correctly */
 #define VIA_SET_FIFO		0x040	/* Needs to have FIFO split set */
 #define VIA_NO_UNMASK		0x080	/* Doesn't work with IRQ unmasking on */
+#define VIA_BAD_ID		0x100	/* Has wrong vendor ID (0x1107) */
 
 /*
  * VIA SouthBridge chips.
@@ -104,10 +104,11 @@
 	unsigned short flags;
 } via_isa_bridges[] = {
 #ifdef FUTURE_BRIDGES
-	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_100 },
-	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_100 },
-	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C,    0x00, 0x2f, VIA_UDMA_100 },
+	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 },
+	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 },
 #endif
+	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 },
+	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, VIA_UDMA_100 },
 	{ "vt8233",	PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, VIA_UDMA_100 },
 	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_100 },
 	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 },
@@ -121,6 +122,7 @@
 	{ "vt82c586a",	PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO },
 	{ "vt82c586",	PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
 	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK },
+	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
 	{ NULL }
 };
 
@@ -128,7 +130,7 @@
 static unsigned char via_enabled;
 static unsigned int via_80w;
 static unsigned int via_clock;
-static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" };
+static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
 
 /*
  * VIA /proc entry.
@@ -151,7 +153,7 @@
 
 static int via_get_info(char *buffer, char **addr, off_t offset, int count)
 {
-	short speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
+	int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
 		 uen[4], udma[4], umul[4], active8b[4], recover8b[4];
 	struct pci_dev *dev = bmide_dev;
 	unsigned int v, u, i;
@@ -161,7 +163,7 @@
 
 	via_print("----------VIA BusMastering IDE Configuration----------------");
 
-	via_print("Driver Version:                     3.29");
+	via_print("Driver Version:                     3.34");
 	via_print("South Bridge:                       VIA %s", via_config->name);
 
 	pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
@@ -170,7 +172,7 @@
 	via_print("Highest DMA rate:                   %s", via_dma[via_config->flags & VIA_UDMA]);
 
 	via_print("BM-DMA base:                        %#x", via_base);
-	via_print("PCI clock:                          %dMHz", via_clock);
+	via_print("PCI clock:                          %d.%dMHz", via_clock / 1000, via_clock / 100 % 10);
 
 	pci_read_config_byte(dev, VIA_MISC_1, &t);
 	via_print("Master Read  Cycle IRDY:            %dws", (t & 64) >> 6);
@@ -218,40 +220,45 @@
 		uen[i]       = ((u >> ((3 - i) << 3)) & 0x20);
 		den[i]       = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
 
-		speed[i] = 20 * via_clock / (active[i] + recover[i]);
-		cycle[i] = 1000 / via_clock * (active[i] + recover[i]);
+		speed[i] = 2 * via_clock / (active[i] + recover[i]);
+		cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock;
 
 		if (!uen[i] || !den[i])
 			continue;
 
 		switch (via_config->flags & VIA_UDMA) {
-			
-			case VIA_UDMA_100:
-				speed[i] = 60 * via_clock / udma[i];
-				cycle[i] = 333 / via_clock * udma[i];
+
+			case VIA_UDMA_33:
+				speed[i] = 2 * via_clock / udma[i];
+				cycle[i] = 1000000 * udma[i] / via_clock;
 				break;
 
 			case VIA_UDMA_66:
-				speed[i] = 40 * via_clock / (udma[i] * umul[i]);
-				cycle[i] = 500 / via_clock * (udma[i] * umul[i]);
+				speed[i] = 4 * via_clock / (udma[i] * umul[i]);
+				cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock;
 				break;
 
-			case VIA_UDMA_33:
-				speed[i] = 20 * via_clock / udma[i];
-				cycle[i] = 1000 / via_clock * udma[i];
+			case VIA_UDMA_100:
+				speed[i] = 6 * via_clock / udma[i];
+				cycle[i] = 333333 * udma[i] / via_clock;
+				break;
+
+			case VIA_UDMA_133:
+				speed[i] = 8 * via_clock / udma[i];
+				cycle[i] = 250000 * udma[i] / via_clock;
 				break;
 		}
 	}
 
 	via_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
 
-	via_print_drive("Address Setup: ", "%8dns", (1000 / via_clock) * setup[i]);
-	via_print_drive("Cmd Active:    ", "%8dns", (1000 / via_clock) * active8b[i]);
-	via_print_drive("Cmd Recovery:  ", "%8dns", (1000 / via_clock) * recover8b[i]);
-	via_print_drive("Data Active:   ", "%8dns", (1000 / via_clock) * active[i]);
-	via_print_drive("Data Recovery: ", "%8dns", (1000 / via_clock) * recover[i]);
+	via_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / via_clock);
+	via_print_drive("Cmd Active:    ", "%8dns", 1000000 * active8b[i] / via_clock);
+	via_print_drive("Cmd Recovery:  ", "%8dns", 1000000 * recover8b[i] / via_clock);
+	via_print_drive("Data Active:   ", "%8dns", 1000000 * active[i] / via_clock);
+	via_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / via_clock);
 	via_print_drive("Cycle Time:    ", "%8dns", cycle[i]);
-	via_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 10, speed[i] % 10);
+	via_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
 
 	return p - buffer;	/* hoping it is less than 4K... */
 }
@@ -280,6 +287,7 @@
 		case VIA_UDMA_33:  t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
 		case VIA_UDMA_66:  t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
 		case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
+		case VIA_UDMA_133: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
 		default: return;
 	}
 
@@ -296,20 +304,21 @@
 {
 	ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
 	struct ide_timing t, p;
-	int T, UT;
+	unsigned int T, UT;
 
 	if (speed != XFER_PIO_SLOW && speed != drive->current_speed)
 		if (ide_config_drive_speed(drive, speed))
 			printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n",
 				drive->dn >> 1, drive->dn & 1);
 
-	T = 1000 / via_clock;
+	T = 1000000000 / via_clock;
 
 	switch (via_config->flags & VIA_UDMA) {
 		case VIA_UDMA_33:   UT = T;   break;
 		case VIA_UDMA_66:   UT = T/2; break;
 		case VIA_UDMA_100:  UT = T/3; break;
-		default:	    UT = T;   break;
+		case VIA_UDMA_133:  UT = T/4; break;
+		default: UT = T;
 	}
 
 	ide_timing_compute(drive, speed, &t, T, UT);
@@ -365,7 +374,8 @@
 			XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
 			(via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
 			(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
-			(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0));
+			(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
+			(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
 
 		via_set_drive(drive, speed);
 
@@ -395,14 +405,16 @@
  */
 
 	for (via_config = via_isa_bridges; via_config->id; via_config++)
-		if ((isa = pci_find_device(PCI_VENDOR_ID_VIA, via_config->id, NULL))) {
+		if ((isa = pci_find_device(PCI_VENDOR_ID_VIA +
+			!!(via_config->flags & VIA_BAD_ID), via_config->id, NULL))) {
+
 			pci_read_config_byte(isa, PCI_REVISION_ID, &t);
 			if (t >= via_config->rev_min && t <= via_config->rev_max)
 				break;
 		}
 
 	if (!via_config->id) {
-		printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, contact Vojtech Pavlik <vojtech@suse.cz>\n");
+		printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, contact Vojtech Pavlik <vojtech@ucw.cz>\n");
 		return -ENODEV;
 	}
 
@@ -412,22 +424,28 @@
 
 	switch (via_config->flags & VIA_UDMA) {
 
-		case VIA_UDMA_100:
-
-			pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-			for (i = 24; i >= 0; i -= 8)
-				if (((u >> i) & 0x10) || (((u >> i) & 0x20) && (((u >> i) & 7) < 3)))
-					via_80w |= (1 << (1 - (i >> 4)));	/* BIOS 80-wire bit or UDMA w/ < 50ns/cycle */
-			break;
-
 		case VIA_UDMA_66:
-
 			pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);	/* Enable Clk66 */
 			pci_write_config_dword(dev, VIA_UDMA_TIMING, u | 0x80008);
 			for (i = 24; i >= 0; i -= 8)
 				if (((u >> (i & 16)) & 8) && ((u >> i) & 0x20) && (((u >> i) & 7) < 2))
 					via_80w |= (1 << (1 - (i >> 4)));	/* 2x PCI clock and UDMA w/ < 3T/cycle */
 			break;
+
+		case VIA_UDMA_100:
+			pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+			for (i = 24; i >= 0; i -= 8)
+				if (((u >> i) & 0x10) || (((u >> i) & 0x20) && (((u >> i) & 7) < 4)))
+					via_80w |= (1 << (1 - (i >> 4)));	/* BIOS 80-wire bit or UDMA w/ < 60ns/cycle */
+			break;
+
+		case VIA_UDMA_133:
+			pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+			for (i = 24; i >= 0; i -= 8)
+				if (((u >> i) & 0x10) || (((u >> i) & 0x20) && (((u >> i) & 7) < 8)))
+					via_80w |= (1 << (1 - (i >> 4)));	/* BIOS 80-wire bit or UDMA w/ < 60ns/cycle */
+			break;
+
 	}
 
 	if (via_config->flags & VIA_BAD_CLK66) {			/* Disable Clk66 */
@@ -466,11 +484,18 @@
  * Determine system bus clock.
  */
 
-	via_clock = system_bus_clock();
-	if (via_clock < 20 || via_clock > 50) {
+	via_clock = system_bus_clock() * 1000;
+
+	switch (via_clock) {
+		case 33000: via_clock = 33333; break;
+		case 37000: via_clock = 37500; break;
+		case 41000: via_clock = 41666; break;
+	}
+
+	if (via_clock < 20000 || via_clock > 50000) {
 		printk(KERN_WARNING "VP_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", via_clock);
-		printk(KERN_WARNING "VP_IDE: Use ide0=ata66 if you want to force UDMA66/UDMA100.\n");
-		via_clock = 33;
+		printk(KERN_WARNING "VP_IDE: Use ide0=ata66 if you want to assume 80-wire cable.\n");
+		via_clock = 33333;
 	}
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/Config.in linux/drivers/ieee1394/Config.in
--- linux.orig/drivers/ieee1394/Config.in	2001-07-20 00:48:15.000000000 +0000
+++ linux/drivers/ieee1394/Config.in	2002-07-20 01:08:38.000000000 +0000
@@ -9,17 +9,35 @@
     if [ "$CONFIG_IEEE1394" != "n" ]; then
 
 	comment "Device Drivers"
-	dep_tristate '  Texas Instruments PCILynx support' CONFIG_IEEE1394_PCILYNX $CONFIG_IEEE1394
-	if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then
-	    bool '    Use PCILynx local RAM' CONFIG_IEEE1394_PCILYNX_LOCALRAM
-	    bool '    Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS
+
+	if [ "$CONFIG_I2C" = "n" -o "$CONFIG_I2C_ALGOBIT" = "n" ]; then
+	    comment '  Texas Instruments PCILynx requires I2C bit-banging'
+	else
+	    dep_tristate '  Texas Instruments PCILynx support' CONFIG_IEEE1394_PCILYNX $CONFIG_IEEE1394 $CONFIG_I2C $CONFIG_I2C_ALGOBIT
 	fi
+
+	# Non-maintained pcilynx options
+	# if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then
+	#     bool '    Use PCILynx local RAM' CONFIG_IEEE1394_PCILYNX_LOCALRAM
+	#     bool '    Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS
+	# fi
+
 	dep_tristate '  OHCI-1394 support' CONFIG_IEEE1394_OHCI1394 $CONFIG_IEEE1394
 
 	comment "Protocol Drivers"
 	dep_tristate '  OHCI-1394 Video support' CONFIG_IEEE1394_VIDEO1394 $CONFIG_IEEE1394_OHCI1394
 	dep_tristate '  SBP-2 support (Harddisks etc.)' CONFIG_IEEE1394_SBP2 $CONFIG_SCSI $CONFIG_IEEE1394
+	if [ "$CONFIG_IEEE1394_SBP2" != "n" ]; then
+	    bool '    Enable Phys DMA support for SBP2 (Debug)' CONFIG_IEEE1394_SBP2_PHYS_DMA
+	fi
+	dep_tristate '  Ethernet over 1394' CONFIG_IEEE1394_ETH1394 $CONFIG_IEEE1394
+	dep_tristate '  OHCI-DV I/O support' CONFIG_IEEE1394_DV1394 $CONFIG_IEEE1394_OHCI1394
 	dep_tristate '  Raw IEEE1394 I/O support' CONFIG_IEEE1394_RAWIO $CONFIG_IEEE1394
+	dep_tristate '  IEC61883-1 Plug support' CONFIG_IEEE1394_CMP $CONFIG_IEEE1394
+
+	if [ "$CONFIG_IEEE1394_CMP" != "n" ]; then
+	    dep_tristate '    IEC61883-6 (Audio transmission) support' CONFIG_IEEE1394_AMDTP $CONFIG_IEEE1394_OHCI1394 $CONFIG_IEEE1394_CMP
+	fi
 
 	bool 'Excessive debugging output' CONFIG_IEEE1394_VERBOSEDEBUG
     fi
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/Makefile linux/drivers/ieee1394/Makefile
--- linux.orig/drivers/ieee1394/Makefile	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/ieee1394/Makefile	2002-07-20 01:08:40.000000000 +0000
@@ -4,7 +4,7 @@
 
 O_TARGET := ieee1394drv.o
 
-export-objs := ieee1394_core.o ohci1394.o
+export-objs := ieee1394_core.o ohci1394.o cmp.o
 
 list-multi := ieee1394.o
 ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
@@ -16,6 +16,10 @@
 obj-$(CONFIG_IEEE1394_VIDEO1394) += video1394.o
 obj-$(CONFIG_IEEE1394_RAWIO) += raw1394.o
 obj-$(CONFIG_IEEE1394_SBP2) += sbp2.o
+obj-$(CONFIG_IEEE1394_DV1394) += dv1394.o
+obj-$(CONFIG_IEEE1394_ETH1394) += eth1394.o
+obj-$(CONFIG_IEEE1394_AMDTP) += amdtp.o
+obj-$(CONFIG_IEEE1394_CMP) += cmp.o
 
 include $(TOPDIR)/Rules.make
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/amdtp.c linux/drivers/ieee1394/amdtp.c
--- linux.orig/drivers/ieee1394/amdtp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/amdtp.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,1141 @@
+/* -*- c-basic-offset: 8 -*-
+ *
+ * amdtp.c - Audio and Music Data Transmission Protocol Driver
+ * Copyright (C) 2001 Kristian Høgsberg
+ *
+ * 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.
+ */
+
+/* OVERVIEW
+ * --------
+ *
+ * The AMDTP driver is designed to expose the IEEE1394 bus as a
+ * regular OSS soundcard, i.e. you can link /dev/dsp to /dev/amdtp and
+ * then your favourite MP3 player, game or whatever sound program will
+ * output to an IEEE1394 isochronous channel.  The signal destination
+ * could be a set of IEEE1394 loudspeakers (if and when such things
+ * become available) or an amplifier with IEEE1394 input (like the
+ * Sony STR-LSA1).  The driver only handles the actual streaming, some
+ * connection management is also required for this to actually work.
+ * That is outside the scope of this driver, and furthermore it is not
+ * really standardized yet.
+ *
+ * The Audio and Music Data Tranmission Protocol is avaiable at
+ *
+ *     http://www.1394ta.org/Download/Technology/Specifications/2001/AM20Final-jf2.pdf
+ *
+ *
+ * TODO
+ * ----
+ *
+ * - We should be able to change input sample format between LE/BE, as
+ *   we already shift the bytes around when we construct the iso
+ *   packets.
+ *
+ * - Fix DMA stop after bus reset!
+ *
+ * - Implement poll.
+ *
+ * - Clean up iso context handling in ohci1394.
+ *
+ *
+ * MAYBE TODO
+ * ----------
+ *
+ * - Receive data for local playback or recording.  Playback requires
+ *   soft syncing with the sound card.
+ *
+ * - Signal processing, i.e. receive packets, do some processing, and
+ *   transmit them again using the same packet structure and timestamps
+ *   offset by processing time.
+ *
+ * - Maybe make an ALSA interface, that is, create a file_ops
+ *   implementation that recognizes ALSA ioctls and uses defaults for
+ *   things that can't be controlled through ALSA (iso channel).
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/wait.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+
+#include "hosts.h"
+#include "highlevel.h"
+#include "ieee1394.h"
+#include "ieee1394_core.h"
+#include "ohci1394.h"
+
+#include "amdtp.h"
+#include "cmp.h"
+
+#define FMT_AMDTP 0x10
+#define FDF_AM824 0x00
+#define FDF_SFC_32KHZ  0x00 /* 32kHz */
+#define FDF_SFC_44K1HZ 0x01 /* 44.1kHz */
+#define FDF_SFC_48KHZ  0x02 /* 44.1kHz */
+
+struct descriptor_block {
+	struct output_more_immediate {
+		u32 control;
+		u32 pad0;
+		u32 skip;
+		u32 pad1;
+		u32 header[4];
+	} header_desc;
+
+	struct output_last {
+		u32 control;
+		u32 data_address;
+		u32 branch;
+		u32 status;
+	} payload_desc;
+};
+
+struct packet {
+	struct descriptor_block *db;
+	dma_addr_t db_bus;
+	quadlet_t *payload;
+	dma_addr_t payload_bus;
+};
+
+struct fraction {
+	int integer;
+	int numerator;
+	int denominator;
+	int counter;
+};
+
+#define PACKET_LIST_SIZE 256
+#define MAX_PACKET_LISTS 4
+
+struct packet_list {
+	struct list_head link;
+	int last_cycle_count;
+	struct packet packets[PACKET_LIST_SIZE];
+};
+
+#define BUFFER_SIZE 128
+
+/* This implements a circular buffer for incoming samples. */
+
+struct buffer {
+	int head, tail, length, size;
+	unsigned char data[0];
+};
+
+struct stream {
+	int iso_channel;
+	int format;
+	int rate;
+	int dimension;
+	int fdf;
+	struct cmp_pcr *opcr;
+
+	/* Input samples are copied here. */
+	struct buffer *input;
+
+	/* ISO Packer state */
+	unsigned char dbc;
+	struct packet_list *current_packet_list;
+	int current_packet;
+	struct fraction packet_size_fraction;
+
+	/* We use these to generate control bits when we are packing
+	 * iec958 data.
+	 */
+	int iec958_frame_count;
+	int iec958_rate_code;
+
+	/* The cycle_count and cycle_offset fields are used for the
+	 * synchronization timestamps (syt) in the cip header.  They
+	 * are incremented by at least a cycle every time we put a
+	 * time stamp in a packet.  As we dont time stamp all
+	 * packages, cycle_count isn't updated in every cycle, and
+	 * sometimes it's incremented by 2.  Thus, we have
+	 * cycle_count2, which is simply incremented by one with each
+	 * packet, so we can compare it to the transmission time
+	 * written back in the dma programs.
+	 */
+	atomic_t cycle_count, cycle_count2;
+	int cycle_offset;
+	struct fraction syt_fraction;
+	int syt_interval;
+	int stale_count;
+
+	/* Theses fields control the sample output to the DMA engine.
+	 * The dma_packet_lists list holds packet lists currently
+	 * queued for dma; the head of the list is currently being
+	 * processed.  The last program in a packet list generates an
+	 * interrupt, which removes the head from dma_packet_lists and
+	 * puts it back on the free list.
+	 */
+	struct list_head dma_packet_lists;
+	struct list_head free_packet_lists;
+        wait_queue_head_t packet_list_wait;
+	spinlock_t packet_list_lock;
+	int iso_context;
+	struct pci_pool *descriptor_pool, *packet_pool;
+
+	/* Streams at a host controller are chained through this field. */
+	struct list_head link;
+	struct amdtp_host *host;
+};
+
+struct amdtp_host {
+	struct hpsb_host *host;
+	struct ti_ohci *ohci;
+	struct list_head stream_list;
+	spinlock_t stream_list_lock;
+	struct list_head link;
+};
+
+static struct hpsb_highlevel *amdtp_highlevel;
+static LIST_HEAD(host_list);
+static spinlock_t host_list_lock = SPIN_LOCK_UNLOCKED;
+
+/* FIXME: This doesn't belong here... */
+
+#define OHCI1394_CONTEXT_CYCLE_MATCH 0x80000000
+#define OHCI1394_CONTEXT_RUN         0x00008000
+#define OHCI1394_CONTEXT_WAKE        0x00001000
+#define OHCI1394_CONTEXT_DEAD        0x00000800
+#define OHCI1394_CONTEXT_ACTIVE      0x00000400
+
+static inline int ohci1394_alloc_it_ctx(struct ti_ohci *ohci)
+{
+	int i;
+
+	for (i = 0; i < ohci->nb_iso_xmit_ctx; i++)
+		if (!test_and_set_bit(i, &ohci->it_ctx_usage))
+			return i;
+
+	return -EBUSY;
+}
+	
+static inline void ohci1394_free_it_ctx(struct ti_ohci *ohci, int ctx)
+{
+	clear_bit(ctx, &ohci->it_ctx_usage);
+}
+
+
+void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx,
+			   dma_addr_t first_cmd, int z, int cycle_match)
+{
+	reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << ctx);
+	reg_write(ohci, OHCI1394_IsoXmitCommandPtr + ctx * 16, first_cmd | z);
+	reg_write(ohci, OHCI1394_IsoXmitContextControlClear + ctx * 16, ~0);
+	wmb();
+	reg_write(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16,
+		  OHCI1394_CONTEXT_CYCLE_MATCH | (cycle_match << 16) |
+		  OHCI1394_CONTEXT_RUN);
+}
+
+void ohci1394_wake_it_ctx(struct ti_ohci *ohci, int ctx)
+{
+	reg_write(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16,
+		  OHCI1394_CONTEXT_WAKE);
+}
+
+void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx)
+{
+	u32 control;
+	int wait;
+
+	reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 1 << ctx);
+	reg_write(ohci, OHCI1394_IsoXmitContextControlClear + ctx * 16,
+		  OHCI1394_CONTEXT_RUN);
+	wmb();
+
+	for (wait = 0; wait < 5; wait++) {
+		control = reg_read(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16);
+		if ((control & OHCI1394_CONTEXT_ACTIVE) == 0)
+			break;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+}
+
+/* Note: we can test if free_packet_lists is empty without aquiring
+ * the packet_list_lock.  The interrupt handler only adds to the free
+ * list, there is no race condition between testing the list non-empty
+ * and acquiring the lock.
+ */
+
+static struct packet_list *stream_get_free_packet_list(struct stream *s)
+{
+	struct packet_list *pl;
+	unsigned long flags;
+
+	if (list_empty(&s->free_packet_lists))
+		return NULL;
+
+	spin_lock_irqsave(&s->packet_list_lock, flags);
+	pl = list_entry(s->free_packet_lists.next, struct packet_list, link);
+	list_del(&pl->link);
+	spin_unlock_irqrestore(&s->packet_list_lock, flags);
+
+	return pl;
+}
+
+static void stream_put_dma_packet_list(struct stream *s,
+				       struct packet_list *pl)
+{
+	unsigned long flags;
+	struct packet_list *prev;
+
+	/* Remember the cycle_count used for timestamping the last packet. */
+	pl->last_cycle_count = atomic_read(&s->cycle_count2) - 1;
+	pl->packets[PACKET_LIST_SIZE - 1].db->payload_desc.branch = 0;
+
+	spin_lock_irqsave(&s->packet_list_lock, flags);
+	list_add_tail(&pl->link, &s->dma_packet_lists);
+	spin_unlock_irqrestore(&s->packet_list_lock, flags);
+
+	prev = list_entry(pl->link.prev, struct packet_list, link);
+	if (pl->link.prev != &s->dma_packet_lists) {
+		struct packet *last = &prev->packets[PACKET_LIST_SIZE - 1];
+		last->db->payload_desc.branch = pl->packets[0].db_bus | 3;
+		ohci1394_wake_it_ctx(s->host->ohci, s->iso_context);
+	}
+	else {
+		u32 syt, cycle_count;
+
+		cycle_count = reg_read(s->host->host->hostdata,
+				       OHCI1394_IsochronousCycleTimer) >> 12;
+		syt = (pl->packets[0].payload[1] >> 12) & 0x0f;
+		cycle_count = (cycle_count & ~0x0f) + 32 + syt;
+		if ((cycle_count & 0x1fff) >= 8000)
+			cycle_count = cycle_count - 8000 + 0x2000;
+
+		ohci1394_start_it_ctx(s->host->ohci, s->iso_context,
+				      pl->packets[0].db_bus, 3,
+				      cycle_count & 0x7fff);
+	}
+}
+
+static void stream_shift_packet_lists(struct stream *s)
+{
+	struct packet_list *pl;
+	struct packet *last;
+	int diff;
+
+	if (list_empty(&s->dma_packet_lists)) {
+		HPSB_ERR("empty dma_packet_lists in %s", __FUNCTION__);
+		return;
+	}
+
+	/* Now that we know the list is non-empty, we can get the head
+	 * of the list without locking, because the process context
+	 * only adds to the tail.  
+	 */
+	pl = list_entry(s->dma_packet_lists.next, struct packet_list, link);
+	last = &pl->packets[PACKET_LIST_SIZE - 1];
+
+	/* This is weird... if we stop dma processing in the middle of
+	 * a packet list, the dma context immediately generates an
+	 * interrupt if we enable it again later.  This only happens
+	 * when amdtp_release is interrupted while waiting for dma to
+	 * complete, though.  Anyway, we detect this by seeing that
+	 * the status of the dma descriptor that we expected an
+	 * interrupt from is still 0.
+	 */
+	if (last->db->payload_desc.status == 0) {
+		HPSB_INFO("weird interrupt...");
+		return;
+	}		
+
+	/* If the last descriptor block does not specify a branch
+	 * address, we have a sample underflow.
+	 */
+	if (last->db->payload_desc.branch == 0)
+		HPSB_INFO("FIXME: sample underflow...");
+
+	/* Here we check when (which cycle) the last packet was sent
+	 * and compare it to what the iso packer was using at the
+	 * time.  If there is a mismatch, we adjust the cycle count in
+	 * the iso packer.  However, there are still up to
+	 * MAX_PACKET_LISTS packet lists queued with bad time stamps,
+	 * so we disable time stamp monitoring for the next
+	 * MAX_PACKET_LISTS packet lists.
+	 */
+	diff = (last->db->payload_desc.status - pl->last_cycle_count) & 0xf;
+	if (diff > 0 && s->stale_count == 0) {
+		atomic_add(diff, &s->cycle_count);
+		atomic_add(diff, &s->cycle_count2);
+		s->stale_count = MAX_PACKET_LISTS;
+	}
+
+	if (s->stale_count > 0)
+		s->stale_count--;
+
+	/* Finally, we move the packet list that was just processed
+	 * back to the free list, and notify any waiters.
+	 */
+	spin_lock(&s->packet_list_lock);
+	list_del(&pl->link);
+	list_add_tail(&pl->link, &s->free_packet_lists);
+	spin_unlock(&s->packet_list_lock);
+
+	wake_up_interruptible(&s->packet_list_wait);
+}
+
+static struct packet *stream_current_packet(struct stream *s)
+{
+	if (s->current_packet_list == NULL &&
+	    (s->current_packet_list = stream_get_free_packet_list(s)) == NULL)
+		return NULL;
+
+	return &s->current_packet_list->packets[s->current_packet];
+}
+	
+static void stream_queue_packet(struct stream *s)
+{
+	s->current_packet++;
+	if (s->current_packet == PACKET_LIST_SIZE) {
+		stream_put_dma_packet_list(s, s->current_packet_list);
+		s->current_packet_list = NULL;
+		s->current_packet = 0;
+	}
+}
+
+/* Integer fractional math.  When we transmit a 44k1Hz signal we must
+ * send 5 41/80 samples per isochronous cycle, as these occur 8000
+ * times a second.  Of course, we must send an integral number of
+ * samples in a packet, so we use the integer math to alternate
+ * between sending 5 and 6 samples per packet.
+ */
+
+static void fraction_init(struct fraction *f, int numerator, int denominator)
+{
+	f->integer = numerator / denominator;
+	f->numerator = numerator % denominator;
+	f->denominator = denominator;
+	f->counter = 0;
+}
+
+static int fraction_next_size(struct fraction *f)
+{
+	return f->integer + ((f->counter + f->numerator) / f->denominator);
+}
+
+static void fraction_inc(struct fraction *f)
+{
+	f->counter = (f->counter + f->numerator) % f->denominator;
+}
+
+static void amdtp_irq_handler(int card, quadlet_t isoRecvIntEvent,
+			      quadlet_t isoXmitIntEvent, void *data)
+{
+	struct amdtp_host *host = data;
+	struct list_head *lh;
+	struct stream *s = NULL;
+
+	spin_lock(&host->stream_list_lock);
+	list_for_each(lh, &host->stream_list) {
+		s = list_entry(lh, struct stream, link);
+		if (isoXmitIntEvent & (1 << s->iso_context))
+			break;
+	}
+	spin_unlock(&host->stream_list_lock);
+
+	if (s != NULL)
+		stream_shift_packet_lists(s);
+}
+
+void packet_initialize(struct packet *p, struct packet *next)
+{
+	/* Here we initialize the dma descriptor block for
+	 * transferring one iso packet.  We use two descriptors per
+	 * packet: an OUTPUT_MORE_IMMMEDIATE descriptor for the
+	 * IEEE1394 iso packet header and an OUTPUT_LAST descriptor
+	 * for the payload.
+	 */
+
+	p->db->header_desc.control =
+		DMA_CTL_OUTPUT_MORE | DMA_CTL_IMMEDIATE | 8;
+	p->db->header_desc.skip = 0;
+
+	if (next) {
+		p->db->payload_desc.control = 
+			DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH;
+		p->db->payload_desc.branch = next->db_bus | 3;
+	}
+	else {
+		p->db->payload_desc.control = 
+			DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH |
+			DMA_CTL_UPDATE | DMA_CTL_IRQ;
+		p->db->payload_desc.branch = 0;
+	}
+	p->db->payload_desc.data_address = p->payload_bus;
+	p->db->payload_desc.status = 0;
+}
+
+struct packet_list *packet_list_alloc(struct stream *s)
+{
+	int i;
+	struct packet_list *pl;
+	struct packet *next;
+
+	pl = kmalloc(sizeof *pl, SLAB_KERNEL);
+	if (pl == NULL)
+		return NULL;
+
+	for (i = 0; i < PACKET_LIST_SIZE; i++) {
+		struct packet *p = &pl->packets[i];
+		p->db = pci_pool_alloc(s->descriptor_pool, SLAB_KERNEL,
+				       &p->db_bus);
+		p->payload = pci_pool_alloc(s->packet_pool, SLAB_KERNEL,
+					    &p->payload_bus);
+	}
+
+	for (i = 0; i < PACKET_LIST_SIZE; i++) {
+		if (i < PACKET_LIST_SIZE - 1)
+			next = &pl->packets[i + 1];
+		else 
+			next = NULL;
+		packet_initialize(&pl->packets[i], next);
+	}
+
+	return pl;
+}
+
+void packet_list_free(struct packet_list *pl, struct stream *s)
+{
+	int i;
+
+	for (i = 0; i < PACKET_LIST_SIZE; i++) {
+		struct packet *p = &pl->packets[i];
+		pci_pool_free(s->descriptor_pool, p->db, p->db_bus);
+		pci_pool_free(s->packet_pool, p->payload, p->payload_bus);
+	}
+	kfree(pl);
+}
+
+static struct buffer *buffer_alloc(int size)
+{
+	struct buffer *b;
+
+	b = kmalloc(sizeof *b + size, SLAB_KERNEL);
+	b->head = 0;
+	b->tail = 0;
+	b->length = 0;
+	b->size = size;
+
+	return b;
+}
+
+static unsigned char *buffer_get_bytes(struct buffer *buffer, int size)
+{
+	unsigned char *p;
+
+	if (buffer->head + size > buffer->size)
+		BUG();
+
+	p = &buffer->data[buffer->head];
+	buffer->head += size;
+	if (buffer->head == buffer->size)
+		buffer->head = 0;
+	buffer->length -= size;
+
+	return p;
+}
+
+static unsigned char *buffer_put_bytes(struct buffer *buffer,
+				       int max, int *actual)
+{
+	int length;
+	unsigned char *p;
+
+	p = &buffer->data[buffer->tail];
+	length = min(buffer->size - buffer->length, max);
+	if (buffer->tail + length < buffer->size) {
+		*actual = length;
+		buffer->tail += length;
+	}
+	else {
+		*actual = buffer->size - buffer->tail;
+		 buffer->tail = 0;
+	}
+
+	buffer->length += *actual;
+	return p;
+}
+
+static u32 get_iec958_header_bits(struct stream *s, int sub_frame, u32 sample)
+{
+	int csi, parity, shift;
+	int block_start;
+	u32 bits;
+
+	switch (s->iec958_frame_count) {
+	case 1:
+		csi = s->format == AMDTP_FORMAT_IEC958_AC3;
+		break;
+	case 2:
+	case 9:
+		csi = 1;
+		break;
+	case 24 ... 27:
+		csi = (s->iec958_rate_code >> (27 - s->iec958_frame_count)) & 0x01;
+		break;
+	default:
+		csi = 0;
+		break;
+	}
+
+	block_start = (s->iec958_frame_count == 0 && sub_frame == 0);
+
+	/* The parity bit is the xor of the sample bits and the
+	 * channel status info bit. */
+	for (shift = 16, parity = sample ^ csi; shift > 0; shift >>= 1)
+		parity ^= (parity >> shift);
+
+	bits =  (block_start << 5) |		/* Block start bit */
+		((sub_frame == 0) << 4) |	/* Subframe bit */
+		((parity & 1) << 3) |		/* Parity bit */
+		(csi << 2);			/* Channel status info bit */
+
+	return bits;
+}
+
+static u32 get_header_bits(struct stream *s, int sub_frame, u32 sample)
+{
+	switch (s->format) {
+	case AMDTP_FORMAT_IEC958_PCM:
+	case AMDTP_FORMAT_IEC958_AC3:
+		return get_iec958_header_bits(s, sub_frame, sample);
+		
+	case AMDTP_FORMAT_RAW:
+		return 0x40000000;
+
+	default:
+		return 0;
+	}
+}
+
+
+static void fill_packet(struct stream *s, struct packet *packet, int nevents)
+{
+	int size, node_id, i, j;
+	quadlet_t *event;
+	unsigned char *p;
+	u32 control, sample, bits;
+	int syt_index, syt, next;
+
+	size = (nevents * s->dimension + 2) * sizeof(quadlet_t);
+	node_id = s->host->host->node_id & 0x3f;
+
+	/* Update DMA descriptors */
+	packet->db->payload_desc.status = 0;
+	control = packet->db->payload_desc.control & 0xffff0000;
+	packet->db->payload_desc.control = control | size;
+
+	/* Fill IEEE1394 headers */
+	packet->db->header_desc.header[0] =
+		(SPEED_100 << 16) | (0x01 << 14) | 
+		(s->iso_channel << 8) | (TCODE_ISO_DATA << 4);
+	packet->db->header_desc.header[1] = size << 16;
+	
+	/* Fill cip header */
+	syt_index = s->dbc & (s->syt_interval - 1);
+	if (syt_index == 0 || syt_index + nevents > s->syt_interval) {
+		syt = ((atomic_read(&s->cycle_count) << 12) | 
+		       s->cycle_offset) & 0xffff;
+		next = fraction_next_size(&s->syt_fraction) + s->cycle_offset;
+		/* This next addition should be modulo 8000 (0x1f40),
+		 * but we only use the lower 4 bits of cycle_count, so
+		 * we dont need the modulo. */
+		atomic_add(next / 3072, &s->cycle_count);
+		s->cycle_offset = next % 3072;
+		fraction_inc(&s->syt_fraction);
+	}
+	else {
+		syt = 0xffff;
+		next = 0;
+	}
+	atomic_inc(&s->cycle_count2);
+
+	packet->payload[0] = cpu_to_be32((node_id << 24) | (s->dimension << 16) | s->dbc);
+	packet->payload[1] = cpu_to_be32((1 << 31) | (FMT_AMDTP << 24) | (s->fdf << 16) | syt);
+
+	/* Fill payload */
+	for (i = 0, event = &packet->payload[2]; i < nevents; i++) {
+
+		for (j = 0; j < s->dimension; j++) {
+			p = buffer_get_bytes(s->input, 2);
+			sample = (p[1] << 16) | (p[0] << 8);
+			bits = get_header_bits(s, j, sample);
+			event[j] = cpu_to_be32((bits << 24) | sample);
+		}
+
+		event += s->dimension;
+		if (++s->iec958_frame_count == 192)
+			s->iec958_frame_count = 0;
+	}
+
+	s->dbc += nevents;
+}
+
+static void stream_flush(struct stream *s)
+{
+	struct packet *p;
+	int nevents;
+
+	while (nevents = fraction_next_size(&s->packet_size_fraction),
+	       p = stream_current_packet(s),
+	       nevents * s->dimension * 2 <= s->input->length && p != NULL) {
+		fill_packet(s, p, nevents);
+		fraction_inc(&s->packet_size_fraction);
+		stream_queue_packet(s);
+	}
+}
+
+static int stream_alloc_packet_lists(struct stream *s)
+{
+	int max_nevents, max_packet_size, i;
+
+	max_nevents = s->packet_size_fraction.integer;
+	if (s->packet_size_fraction.numerator > 0)
+		max_nevents++;
+
+	max_packet_size = max_nevents * s->dimension * 4 + 8;
+	s->packet_pool = pci_pool_create("packet pool", s->host->ohci->dev,
+					 max_packet_size, 0, 0, SLAB_KERNEL);
+	if (s->packet_pool == NULL)
+		return -1;
+
+	INIT_LIST_HEAD(&s->free_packet_lists);
+	INIT_LIST_HEAD(&s->dma_packet_lists);
+	for (i = 0; i < MAX_PACKET_LISTS; i++) {
+		struct packet_list *pl = packet_list_alloc(s);
+		if (pl == NULL)
+			break;
+		list_add_tail(&pl->link, &s->free_packet_lists);
+	}
+
+	return i < MAX_PACKET_LISTS ? -1 : 0;
+}
+
+static void stream_free_packet_lists(struct stream *s)
+{
+	struct list_head *lh, *next;
+
+	if (s->current_packet_list != NULL)
+		packet_list_free(s->current_packet_list, s);
+	list_for_each_safe(lh, next, &s->dma_packet_lists)
+		packet_list_free(list_entry(lh, struct packet_list, link), s);
+	list_for_each_safe(lh, next, &s->free_packet_lists)
+		packet_list_free(list_entry(lh, struct packet_list, link), s);
+	if (s->packet_pool != NULL)
+		pci_pool_destroy(s->packet_pool);
+
+	s->current_packet_list = NULL;
+	INIT_LIST_HEAD(&s->free_packet_lists);
+	INIT_LIST_HEAD(&s->dma_packet_lists);
+	s->packet_pool = NULL;
+}
+
+static void plug_update(struct cmp_pcr *plug, void *data)
+{
+	struct stream *s = data;
+
+	HPSB_INFO("plug update: p2p_count=%d, channel=%d",
+		  plug->p2p_count, plug->channel);
+	s->iso_channel = plug->channel;
+	if (plug->p2p_count > 0) {
+		/* start streaming */
+	}
+	else {
+		/* stop streaming */
+	}
+}
+
+static int stream_configure(struct stream *s, int cmd, struct amdtp_ioctl *cfg)
+{
+	if (cfg->format <= AMDTP_FORMAT_IEC958_AC3)
+		s->format = cfg->format;
+	else
+		return -EINVAL;
+
+	switch (cfg->rate) {
+	case 32000:
+		s->syt_interval = 8;
+		s->fdf = FDF_SFC_32KHZ;
+		s->iec958_rate_code = 0x0c;
+		s->rate = cfg->rate;
+		break;
+	case 44100:
+		s->syt_interval = 8;
+		s->fdf = FDF_SFC_44K1HZ;
+		s->iec958_rate_code = 0x00;
+		s->rate = cfg->rate;
+		break;
+	case 48000:
+		s->syt_interval = 8;
+		s->fdf = FDF_SFC_48KHZ;
+		s->iec958_rate_code = 0x04;
+		s->rate = cfg->rate;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	fraction_init(&s->packet_size_fraction, s->rate, 8000);
+
+	/* The syt_fraction is initialized to the number of ticks
+	 * between syt_interval events.  The number of ticks per
+	 * second is 24.576e6, so the number of ticks between
+	 * syt_interval events is 24.576e6 * syt_interval / rate.
+	 */
+	fraction_init(&s->syt_fraction, 24576000 * s->syt_interval, s->rate);
+
+	/* When using the AM824 raw subformat we can stream signals of
+	 * any dimension.  The IEC958 subformat, however, only
+	 * supports 2 channels.
+	 */
+	if (s->format == AMDTP_FORMAT_RAW || cfg->dimension == 2)
+		s->dimension = cfg->dimension;
+	else
+		return -EINVAL;
+
+	if (s->opcr != NULL) {
+		cmp_unregister_opcr(s->host->host, s->opcr);
+		s->opcr = NULL;
+	}
+
+	switch(cmd) {
+	case AMDTP_IOC_PLUG:
+		s->opcr = cmp_register_opcr(s->host->host, cfg->u.plug,
+					   /*payload*/ 12, plug_update, s);
+		if (s->opcr == NULL)
+			return -EINVAL;
+		s->iso_channel = s->opcr->channel;
+		break;
+
+	case AMDTP_IOC_CHANNEL:
+		if (cfg->u.channel >= 0 && cfg->u.channel < 64)
+			s->iso_channel = cfg->u.channel;
+		else
+			return -EINVAL;
+		break;
+	}
+
+	/* The ioctl settings were all valid, so we realloc the packet
+	 * lists to make sure the packet size is big enough.
+	 */
+	if (s->packet_pool != NULL)
+		stream_free_packet_lists(s);
+
+	if (stream_alloc_packet_lists(s) < 0) {
+		stream_free_packet_lists(s);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+struct stream *stream_alloc(struct amdtp_host *host)
+{
+	struct stream *s;
+	unsigned long flags;
+	const int transfer_delay = 8651; /* approx 352 us */
+
+        s = kmalloc(sizeof(struct stream), SLAB_KERNEL);
+        if (s == NULL)
+                return NULL;
+
+        memset(s, 0, sizeof(struct stream));
+	s->host = host;
+
+	s->input = buffer_alloc(BUFFER_SIZE);
+	if (s->input == NULL) {
+		kfree(s);
+		return NULL;
+	}
+
+	s->cycle_offset = transfer_delay % 3072;
+	atomic_set(&s->cycle_count, transfer_delay / 3072);
+	atomic_set(&s->cycle_count2, 0);
+
+	s->descriptor_pool = pci_pool_create("descriptor pool", host->ohci->dev,
+					     sizeof(struct descriptor_block),
+					     16, 0, SLAB_KERNEL);
+	if (s->descriptor_pool == NULL) {
+		kfree(s->input);
+		kfree(s);
+		return NULL;
+	}
+
+	INIT_LIST_HEAD(&s->free_packet_lists);
+	INIT_LIST_HEAD(&s->dma_packet_lists);
+
+        init_waitqueue_head(&s->packet_list_wait);
+        spin_lock_init(&s->packet_list_lock);
+
+	s->iso_context = ohci1394_alloc_it_ctx(host->ohci);
+	if (s->iso_context < 0) {
+		pci_pool_destroy(s->descriptor_pool);
+		kfree(s->input);
+		kfree(s);
+		return NULL;
+	}
+
+	spin_lock_irqsave(&host->stream_list_lock, flags);
+	list_add_tail(&s->link, &host->stream_list);
+	spin_unlock_irqrestore(&host->stream_list_lock, flags);
+
+	return s;
+}
+
+void stream_free(struct stream *s)
+{
+	unsigned long flags;
+
+	/* Stop the DMA.  We wait for the dma packet list to become
+	 * empty and let the dma controller run out of programs.  This
+	 * seems to be more reliable than stopping it directly, since
+	 * that sometimes generates an it transmit interrupt if we
+	 * later re-enable the context.
+	 */
+	wait_event_interruptible(s->packet_list_wait, 
+				 list_empty(&s->dma_packet_lists));
+
+	ohci1394_stop_it_ctx(s->host->ohci, s->iso_context);
+	ohci1394_free_it_ctx(s->host->ohci, s->iso_context);
+
+	if (s->opcr != NULL)
+		cmp_unregister_opcr(s->host->host, s->opcr);
+
+	spin_lock_irqsave(&s->host->stream_list_lock, flags);
+	list_del(&s->link);
+	spin_unlock_irqrestore(&s->host->stream_list_lock, flags);
+
+	kfree(s->input);
+
+	stream_free_packet_lists(s);
+	pci_pool_destroy(s->descriptor_pool);
+
+	kfree(s);
+}
+
+/* File operations */
+
+static ssize_t amdtp_write(struct file *file, const char *buffer, size_t count,
+			   loff_t *offset_is_ignored)
+{
+	struct stream *s = file->private_data;
+	unsigned char *p;
+	int i, length;
+	
+	if (s->packet_pool == NULL)
+		return -EBADFD;
+
+	/* Fill the circular buffer from the input buffer and call the
+	 * iso packer when the buffer is full.  The iso packer may
+	 * leave bytes in the buffer for two reasons: either the
+	 * remaining bytes wasn't enough to build a new packet, or
+	 * there were no free packet lists.  In the first case we
+	 * re-fill the buffer and call the iso packer again or return
+	 * if we used all the data from userspace.  In the second
+	 * case, the wait_event_interruptible will block until the irq
+	 * handler frees a packet list.
+	 */
+
+	for (i = 0; i < count; i += length) {
+		p = buffer_put_bytes(s->input, count, &length);
+		copy_from_user(p, buffer + i, length);
+		if (s->input->length < s->input->size)
+			continue;
+		
+		stream_flush(s);
+		
+		if (s->current_packet_list == NULL &&
+		    wait_event_interruptible(s->packet_list_wait, 
+					     !list_empty(&s->free_packet_lists)))
+			return -EINTR;
+	}
+
+	return count;
+}
+
+static int amdtp_ioctl(struct inode *inode, struct file *file,
+			   unsigned int cmd, unsigned long arg)
+{
+	struct stream *s = file->private_data;
+	struct amdtp_ioctl cfg;
+	int new;
+
+	switch(cmd)
+	{
+	case AMDTP_IOC_PLUG:
+	case AMDTP_IOC_CHANNEL:
+		if (copy_from_user(&cfg, (struct amdtp_ioctl *) arg, sizeof cfg))
+			return -EFAULT;
+		else 
+			return stream_configure(s, cmd, &cfg);
+
+	case AMDTP_IOC_PING:
+		HPSB_INFO("ping: offsetting timpestamps %ld ticks", arg);
+		new = s->cycle_offset + arg;
+		s->cycle_offset = new % 3072;
+		atomic_add(new / 3072, &s->cycle_count);
+		return 0;
+
+	case AMDTP_IOC_ZAP:
+		while (MOD_IN_USE)
+			MOD_DEC_USE_COUNT;
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int amdtp_open(struct inode *inode, struct file *file)
+{
+	struct amdtp_host *host;
+
+	/* FIXME: We just grab the first registered host */
+	spin_lock(&host_list_lock);
+	if (!list_empty(&host_list))
+		host = list_entry(host_list.next, struct amdtp_host, link);
+	else
+		host = NULL;
+	spin_unlock(&host_list_lock);
+
+	if (host == NULL)
+		return -ENODEV;
+
+	file->private_data = stream_alloc(host);
+	if (file->private_data == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int amdtp_release(struct inode *inode, struct file *file)
+{
+	struct stream *s = file->private_data;
+
+	stream_free(s);
+
+	return 0;
+}
+
+static struct file_operations amdtp_fops =
+{
+	owner:		THIS_MODULE,
+	write:		amdtp_write,
+	ioctl:		amdtp_ioctl,
+	open:		amdtp_open,
+	release:	amdtp_release
+};
+
+/* IEEE1394 Subsystem functions */
+
+static void amdtp_add_host(struct hpsb_host *host)
+{
+	struct amdtp_host *ah;
+
+	/* FIXME: check it's an ohci host. */
+
+	ah = kmalloc(sizeof *ah, SLAB_KERNEL);
+	ah->host = host;
+	ah->ohci = host->hostdata;
+	INIT_LIST_HEAD(&ah->stream_list);
+	spin_lock_init(&ah->stream_list_lock);
+
+	spin_lock_irq(&host_list_lock);
+	list_add_tail(&ah->link, &host_list);
+	spin_unlock_irq(&host_list_lock);
+
+	ohci1394_hook_irq(ah->ohci, amdtp_irq_handler, ah);
+}
+
+static void amdtp_remove_host(struct hpsb_host *host)
+{
+	struct list_head *lh;
+	struct amdtp_host *ah;
+
+	spin_lock_irq(&host_list_lock);
+	list_for_each(lh, &host_list) {
+		if (list_entry(lh, struct amdtp_host, link)->host == host) {
+			list_del(lh);
+			break;
+		}
+	}
+	spin_unlock_irq(&host_list_lock);
+	
+	if (lh != &host_list) {
+		ah = list_entry(lh, struct amdtp_host, link);
+		ohci1394_unhook_irq(ah->ohci, amdtp_irq_handler, ah);
+		kfree(ah);
+	}
+	else
+		HPSB_ERR("remove_host: bogus ohci host: %p", host);
+}
+
+static struct hpsb_highlevel_ops amdtp_highlevel_ops = {
+	add_host:	amdtp_add_host,
+	remove_host:	amdtp_remove_host,
+};
+
+/* Module interface */
+
+MODULE_AUTHOR("Kristian Hogsberg <hogsberg@users.sf.net>");
+MODULE_DESCRIPTION("Driver for Audio & Music Data Transmission Protocol "
+		   "on OHCI boards.");
+MODULE_SUPPORTED_DEVICE("amdtp");
+MODULE_LICENSE("GPL");
+
+static int __init amdtp_init_module (void)
+{
+	if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_AMDTP,
+				      THIS_MODULE, &amdtp_fops)) {
+		HPSB_ERR("amdtp: unable to get minor device block");
+ 		return -EIO;
+ 	}
+
+	amdtp_highlevel = hpsb_register_highlevel ("amdtp",
+						   &amdtp_highlevel_ops);
+	if (amdtp_highlevel == NULL) {
+		HPSB_ERR("amdtp: unable to register highlevel ops");
+		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_AMDTP);
+		return -EIO;
+	}
+
+	HPSB_INFO("Loaded AMDTP driver");
+
+	return 0;
+}
+
+static void __exit amdtp_exit_module (void)
+{
+        hpsb_unregister_highlevel(amdtp_highlevel);
+        ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_AMDTP);
+
+	HPSB_INFO("Unloaded AMDTP driver");
+}
+
+module_init(amdtp_init_module);
+module_exit(amdtp_exit_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/amdtp.h linux/drivers/ieee1394/amdtp.h
--- linux.orig/drivers/ieee1394/amdtp.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/amdtp.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,75 @@
+/* -*- c-basic-offset: 8 -*- */
+
+#ifndef __AMDTP_H
+#define __AMDTP_H
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
+/* The userspace interface for the Audio & Music Data Transmission
+ * Protocol driver is really simple. First, open /dev/amdtp, use the
+ * ioctl to configure format, rate, dimension and either plug or
+ * channel, then start writing samples.
+ *
+ * The formats supported by the driver are listed below.
+ * AMDTP_FORMAT_RAW corresponds to the AM824 raw format, which can
+ * carry any number of channels, so use this if you're streaming
+ * multichannel audio.  The AMDTP_FORMAT_IEC958_PCM corresponds to the
+ * AM824 IEC958 encapsulation without the IEC958 data bit set, using
+ * AMDTP_FORMAT_IEC958_AC3 will transmit the samples with the data bit
+ * set, suitable for transmitting compressed AC-3 audio.
+ *
+ * The rate field specifies the transmission rate; supported values are
+ * AMDTP_RATE_32KHZ, AMDTP_RATE_44K1HZ and AMDTP_RATE_48KHZ.
+ *
+ * The dimension field specifies the dimension of the signal, that is,
+ * the number of audio channels.  Only AMDTP_FORMAT_RAW supports
+ * settings greater than 2.  
+ *
+ * The last thing to specify is either the isochronous channel to use
+ * or the output plug to connect to.  If you know what channel the
+ * destination device will listen on, you can specify the channel
+ * directly and use the AMDTP_IOC_CHANNEL ioctl.  However, if the
+ * destination device chooses the channel and uses the IEC61883-1 plug
+ * mechanism, you can specify an output plug to connect to.  The
+ * driver will pick up the channel number from the plug once the
+ * destination device locks the output plug control register.  In this
+ * case set the plug field and use the AMDTP_IOC_PLUG ioctl.
+ *
+ * Having configured the interface, the driver now accepts writes of
+ * regular 16 bit signed little endian samples, with the channels
+ * interleaved.  For example, 4 channels would look like:
+ *
+ *   | sample 0                                      | sample 1    ...
+ *   | ch. 0     | ch. 1     | ch. 2     | ch. 3     | ch. 0     | ...
+ *   | lsb | msb | lsb | msb | lsb | msb | lsb | msb | lsb | msb | ...
+ *
+ */
+
+/* We use '#' for our ioctl magic number because it's cool. */
+
+#define AMDTP_IOC_CHANNEL _IOW('#', 0, sizeof (struct amdtp_ioctl))
+#define AMDTP_IOC_PLUG    _IOW('#', 1, sizeof (struct amdtp_ioctl))
+#define AMDTP_IOC_PING    _IOW('#', 2, sizeof (struct amdtp_ioctl))
+#define AMDTP_IOC_ZAP     _IO('#', 3)
+
+enum {
+	AMDTP_FORMAT_RAW,
+	AMDTP_FORMAT_IEC958_PCM,
+	AMDTP_FORMAT_IEC958_AC3
+};
+
+enum {
+	AMDTP_RATE_32KHZ,
+	AMDTP_RATE_44K1HZ,
+	AMDTP_RATE_48KHZ,
+};
+
+struct amdtp_ioctl {
+	__u32 format;
+	__u32 rate;
+	__u32 dimension;
+	union { __u32 channel; __u32 plug; } u;
+};
+
+#endif /* __AMDTP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/cmp.c linux/drivers/ieee1394/cmp.c
--- linux.orig/drivers/ieee1394/cmp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/cmp.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,348 @@
+/* -*- c-basic-offset: 8 -*-
+ *
+ * cmp.c - Connection Management Procedures
+ * Copyright (C) 2001 Kristian Høgsberg
+ *
+ * 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.
+ */
+
+/* TODO
+ * ----
+ *
+ * - Implement IEC61883-1 output plugs and connection management.
+ *   This should probably be part of the general subsystem, as it could
+ *   be shared with dv1394.
+ *
+ * - Add IEC61883 unit directory when loading this module.  This
+ *   requires a run-time changeable config rom.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+
+#include "hosts.h"
+#include "highlevel.h"
+#include "ieee1394.h"
+#include "ieee1394_core.h"
+#include "cmp.h"
+
+struct plug {
+	union {
+		struct cmp_pcr pcr;
+		quadlet_t quadlet;
+	} u;
+	void (*update)(struct cmp_pcr *plug, void *data);
+	void *data;
+};
+
+struct cmp_host {
+	struct hpsb_host *host;
+
+	union {
+		struct cmp_mpr ompr;
+		quadlet_t ompr_quadlet;
+	} u;
+	struct plug opcr[2];
+
+	union {
+		struct cmp_mpr impr;
+		quadlet_t impr_quadlet;
+	} v;
+	struct plug ipcr[2];
+
+	struct list_head link;
+};
+
+enum {
+	CMP_P2P_CONNECTION,
+	CMP_BC_CONNECTION
+};
+
+#define CSR_PCR_MAP      0x900
+#define CSR_PCR_MAP_END  0x9fc
+
+static struct hpsb_highlevel *cmp_highlevel;
+
+static LIST_HEAD(host_list);
+static spinlock_t host_list_lock = SPIN_LOCK_UNLOCKED;
+
+static struct cmp_host *
+lookup_cmp_host(struct hpsb_host *host)
+{
+	struct cmp_host *ch;
+	struct list_head *lh;
+	unsigned long flags;
+
+	ch = NULL;
+	spin_lock_irqsave(&host_list_lock, flags);
+	list_for_each(lh, &host_list) {
+		ch = list_entry(lh, struct cmp_host, link);
+		if (ch->host == host)
+			break;
+	}
+	spin_unlock_irqrestore(&host_list_lock, flags);
+
+	if (lh == &host_list)
+		return NULL;
+	else
+		return ch;
+}
+
+struct cmp_pcr *
+cmp_register_opcr(struct hpsb_host *host, int opcr_number, int payload,
+		  void (*update)(struct cmp_pcr *pcr, void *data),
+		  void *data)
+{
+	struct cmp_host *ch;
+	struct plug *plug;
+
+	ch = lookup_cmp_host(host);
+
+	if (opcr_number >= ch->u.ompr.nplugs ||
+	    ch->opcr[opcr_number].update != NULL)
+		return NULL;
+
+	plug = &ch->opcr[opcr_number];
+	plug->u.pcr.online = 1;
+	plug->u.pcr.bcast_count = 0;
+	plug->u.pcr.p2p_count = 0;
+	plug->u.pcr.overhead = 0;
+	plug->u.pcr.payload = payload;
+	plug->update = update;
+	plug->data = data;
+
+	return &plug->u.pcr;
+}
+
+void cmp_unregister_opcr(struct hpsb_host *host, struct cmp_pcr *opcr)
+{
+	struct cmp_host *ch;
+	struct plug *plug;
+
+	ch = lookup_cmp_host(host);
+	plug = (struct plug *)opcr;
+	if (plug - ch->opcr >= ch->u.ompr.nplugs) BUG();
+
+	plug->u.pcr.online = 0;
+	plug->update = NULL;
+}
+
+static void reset_plugs(struct cmp_host *ch)
+{
+	int i;
+
+	ch->u.ompr.non_persistent_ext = 0xff;
+	for (i = 0; i < ch->u.ompr.nplugs; i++) {
+		ch->opcr[i].u.pcr.bcast_count = 0;
+		ch->opcr[i].u.pcr.p2p_count = 0;
+		ch->opcr[i].u.pcr.overhead = 0;
+	}
+}
+
+static void cmp_add_host(struct hpsb_host *host)
+{
+	struct cmp_host *ch;
+
+	ch = kmalloc(sizeof *ch, SLAB_KERNEL);
+	if (ch == NULL) {
+		HPSB_ERR("Failed to allocate cmp_host");
+		return;
+	}
+	memset(ch, 0, sizeof *ch);
+	ch->host = host;
+	ch->u.ompr.rate = SPEED_100;
+	ch->u.ompr.bcast_channel_base = 63;
+	ch->u.ompr.nplugs = 2;
+	reset_plugs(ch);
+
+	spin_lock_irq(&host_list_lock);
+	list_add_tail(&ch->link, &host_list);
+	spin_unlock_irq(&host_list_lock);
+}
+
+static void cmp_host_reset(struct hpsb_host *host)
+{
+	struct cmp_host *ch;
+
+	ch = lookup_cmp_host(host);
+	if (ch == NULL) BUG();
+	reset_plugs(ch);
+}
+
+static void cmp_remove_host(struct hpsb_host *host)
+{
+	struct cmp_host *ch;
+
+	ch = lookup_cmp_host(host);
+	if (ch == NULL) BUG();
+
+	spin_lock_irq(&host_list_lock);
+	list_del(&ch->link);
+	spin_unlock_irq(&host_list_lock);
+
+	kfree(ch);
+}
+
+static int pcr_read(struct hpsb_host *host, int nodeid, quadlet_t *buf,
+		    u64 addr, unsigned int length)
+{
+	int csraddr = addr - CSR_REGISTER_BASE;
+	int plug;
+	struct cmp_host *ch;
+	
+	if (length != 4)
+		return RCODE_TYPE_ERROR;
+
+	ch = lookup_cmp_host(host);
+	if (csraddr == 0x900) {
+		*buf = cpu_to_be32(ch->u.ompr_quadlet);
+		return RCODE_COMPLETE;   
+	}
+	else if (csraddr < 0x904 + ch->u.ompr.nplugs * 4) {
+		plug = (csraddr - 0x904) / 4;
+		*buf = cpu_to_be32(ch->opcr[plug].u.quadlet);
+		return RCODE_COMPLETE;
+	}
+	else if (csraddr < 0x980) {
+		return RCODE_ADDRESS_ERROR;
+	}
+	else if (csraddr == 0x980) {
+		*buf = cpu_to_be32(ch->v.impr_quadlet);
+		return RCODE_COMPLETE;   
+	}
+	else if (csraddr < 0x984 + ch->v.impr.nplugs * 4) {
+		plug = (csraddr - 0x984) / 4;
+		*buf = cpu_to_be32(ch->ipcr[plug].u.quadlet);
+		return RCODE_COMPLETE;
+	}
+	else
+		return RCODE_ADDRESS_ERROR;
+}
+
+static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
+		    u64 addr, quadlet_t data, quadlet_t arg, int extcode)
+{
+	int csraddr = addr - CSR_REGISTER_BASE;
+	int plug;
+	struct cmp_host *ch;
+
+	ch = lookup_cmp_host(host);
+	
+	if (extcode != EXTCODE_COMPARE_SWAP) 
+		return RCODE_TYPE_ERROR;
+	
+	if (csraddr == 0x900) {
+		/* FIXME: Ignore writes to bits 30-31 and 0-7 */
+		*store = cpu_to_be32(ch->u.ompr_quadlet);
+		if (arg == cpu_to_be32(ch->u.ompr_quadlet))
+			ch->u.ompr_quadlet = be32_to_cpu(data);
+
+		return RCODE_COMPLETE;
+	}
+	if (csraddr < 0x904 + ch->u.ompr.nplugs * 4) {
+		plug = (csraddr - 0x904) / 4;
+		*store = cpu_to_be32(ch->opcr[plug].u.quadlet);
+
+		if (arg == *store)
+			ch->opcr[plug].u.quadlet = be32_to_cpu(data);
+
+		if (be32_to_cpu(*store) != ch->opcr[plug].u.quadlet &&
+		    ch->opcr[plug].update != NULL)
+			ch->opcr[plug].update(&ch->opcr[plug].u.pcr,
+					      ch->opcr[plug].data);
+
+		return RCODE_COMPLETE;
+	}
+	else if (csraddr < 0x980) {
+		return RCODE_ADDRESS_ERROR;
+	}
+	else if (csraddr == 0x980) {
+		/* FIXME: Ignore writes to bits 24-31 and 0-7 */
+		*store = cpu_to_be32(ch->u.ompr_quadlet);
+		if (arg == cpu_to_be32(ch->u.ompr_quadlet))
+			ch->u.ompr_quadlet = be32_to_cpu(data);
+
+		return RCODE_COMPLETE;
+	}
+	else if (csraddr < 0x984 + ch->v.impr.nplugs * 4) {
+		plug = (csraddr - 0x984) / 4;
+		*store = cpu_to_be32(ch->ipcr[plug].u.quadlet);
+
+		if (arg == *store)
+			ch->ipcr[plug].u.quadlet = be32_to_cpu(data);
+
+		if (be32_to_cpu(*store) != ch->ipcr[plug].u.quadlet &&
+		    ch->ipcr[plug].update != NULL)
+			ch->ipcr[plug].update(&ch->ipcr[plug].u.pcr,
+					      ch->ipcr[plug].data);
+
+		return RCODE_COMPLETE;
+	}
+	else
+		return RCODE_ADDRESS_ERROR;
+}
+
+
+static struct hpsb_highlevel_ops cmp_highlevel_ops = {
+	add_host:	cmp_add_host,
+	remove_host:	cmp_remove_host,
+        host_reset:	cmp_host_reset,
+};
+
+static struct hpsb_address_ops pcr_ops = {
+        read: pcr_read,
+        lock: pcr_lock,
+};
+
+/* Module interface */
+
+MODULE_AUTHOR("Kristian Hogsberg <hogsberg@users.sf.net>");
+MODULE_DESCRIPTION("Connection Management Procedures (CMP)");
+MODULE_SUPPORTED_DEVICE("cmp");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(cmp_register_opcr);
+EXPORT_SYMBOL(cmp_unregister_opcr);
+
+static int __init cmp_init_module (void)
+{
+	cmp_highlevel = hpsb_register_highlevel ("cmp",
+						 &cmp_highlevel_ops);
+	if (cmp_highlevel == NULL) {
+		HPSB_ERR("cmp: unable to register highlevel ops");
+		return -EIO;
+	}
+
+	hpsb_register_addrspace(cmp_highlevel, &pcr_ops,
+				CSR_REGISTER_BASE + CSR_PCR_MAP,
+				CSR_REGISTER_BASE + CSR_PCR_MAP_END);
+
+	HPSB_INFO("Loaded CMP driver");
+
+	return 0;
+}
+
+static void __exit cmp_exit_module (void)
+{
+        hpsb_unregister_highlevel(cmp_highlevel);
+
+	HPSB_INFO("Unloaded CMP driver");
+}
+
+module_init(cmp_init_module);
+module_exit(cmp_exit_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/cmp.h linux/drivers/ieee1394/cmp.h
--- linux.orig/drivers/ieee1394/cmp.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/cmp.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,31 @@
+#ifndef __CMP_H
+#define __CMP_H
+
+struct cmp_mpr {
+	u32 nplugs:5;
+	u32 reserved:3;
+	u32 persistent_ext:8;
+	u32 non_persistent_ext:8;
+	u32 bcast_channel_base:6;
+	u32 rate:2;
+} __attribute__((packed));
+
+struct cmp_pcr {
+	u32 payload:10;
+	u32 overhead:4;
+	u32 speed:2;
+	u32 channel:6;
+	u32 reserved:2;
+	u32 p2p_count:6;
+	u32 bcast_count:1;
+	u32 online:1;
+} __attribute__((packed));
+
+struct cmp_pcr *cmp_register_opcr(struct hpsb_host *host, int plug,
+				  int payload,
+				  void (*update)(struct cmp_pcr *plug,
+						 void *data),
+				  void *data);
+void cmp_unregister_opcr(struct hpsb_host *host, struct cmp_pcr *plug);
+
+#endif /* __CMP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/csr.c linux/drivers/ieee1394/csr.c
--- linux.orig/drivers/ieee1394/csr.c	2001-07-20 00:48:15.000000000 +0000
+++ linux/drivers/ieee1394/csr.c	2002-07-20 01:08:28.000000000 +0000
@@ -70,7 +70,7 @@
 {
         host->csr.lock = SPIN_LOCK_UNLOCKED;
 
-        host->csr.rom_size = host->template->get_rom(host, &host->csr.rom);
+        host->csr.rom_size = host->ops->get_rom(host, &host->csr.rom);
 
         host->csr.state                 = 0;
         host->csr.node_ids              = 0;
@@ -152,7 +152,7 @@
         case CSR_CYCLE_TIME:
                 oldcycle = host->csr.cycle_time;
                 host->csr.cycle_time =
-                        host->template->devctl(host, GET_CYCLE_COUNTER, 0);
+                        host->ops->devctl(host, GET_CYCLE_COUNTER, 0);
 
                 if (oldcycle > host->csr.cycle_time) {
                         /* cycle time wrapped around */
@@ -163,7 +163,7 @@
         case CSR_BUS_TIME:
                 oldcycle = host->csr.cycle_time;
                 host->csr.cycle_time =
-                        host->template->devctl(host, GET_CYCLE_COUNTER, 0);
+                        host->ops->devctl(host, GET_CYCLE_COUNTER, 0);
 
                 if (oldcycle > host->csr.cycle_time) {
                         /* cycle time wrapped around */
@@ -181,32 +181,32 @@
                 return RCODE_ADDRESS_ERROR;
 
         case CSR_BUS_MANAGER_ID:
-                if (host->template->hw_csr_reg)
-                        ret = host->template->hw_csr_reg(host, 0, 0, 0);
+                if (host->ops->hw_csr_reg)
+                        ret = host->ops->hw_csr_reg(host, 0, 0, 0);
                 else
                         ret = host->csr.bus_manager_id;
 
                 *(buf++) = cpu_to_be32(ret);
                 out;
         case CSR_BANDWIDTH_AVAILABLE:
-                if (host->template->hw_csr_reg)
-                        ret = host->template->hw_csr_reg(host, 1, 0, 0);
+                if (host->ops->hw_csr_reg)
+                        ret = host->ops->hw_csr_reg(host, 1, 0, 0);
                 else
                         ret = host->csr.bandwidth_available;
 
                 *(buf++) = cpu_to_be32(ret);
                 out;
         case CSR_CHANNELS_AVAILABLE_HI:
-                if (host->template->hw_csr_reg)
-                        ret = host->template->hw_csr_reg(host, 2, 0, 0);
+                if (host->ops->hw_csr_reg)
+                        ret = host->ops->hw_csr_reg(host, 2, 0, 0);
                 else
                         ret = host->csr.channels_available_hi;
 
                 *(buf++) = cpu_to_be32(ret);
                 out;
         case CSR_CHANNELS_AVAILABLE_LO:
-                if (host->template->hw_csr_reg)
-                        ret = host->template->hw_csr_reg(host, 3, 0, 0);
+                if (host->ops->hw_csr_reg)
+                        ret = host->ops->hw_csr_reg(host, 3, 0, 0);
                 else
                         ret = host->csr.channels_available_lo;
 
@@ -244,7 +244,7 @@
                 host->csr.node_ids &= NODE_MASK << 16;
                 host->csr.node_ids |= be32_to_cpu(*(data++)) & (BUS_MASK << 16);
                 host->node_id = host->csr.node_ids >> 16;
-                host->template->devctl(host, SET_BUS_ID, host->node_id >> 6);
+                host->ops->devctl(host, SET_BUS_ID, host->node_id >> 6);
                 out;
 
         case CSR_RESET_START:
@@ -269,7 +269,7 @@
         case CSR_CYCLE_TIME:
                 /* should only be set by cycle start packet, automatically */
                 host->csr.cycle_time = be32_to_cpu(*data);
-                host->template->devctl(host, SET_CYCLE_COUNTER,
+                host->ops->devctl(host, SET_CYCLE_COUNTER,
                                        be32_to_cpu(*(data++)));
                 out;
         case CSR_BUS_TIME:
@@ -318,10 +318,10 @@
         data = be32_to_cpu(data);
         arg = be32_to_cpu(arg);
 
-        if (host->template->hw_csr_reg) {
+        if (host->ops->hw_csr_reg) {
                 quadlet_t old;
 
-                old = host->template->
+                old = host->ops->
                         hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
                                    data, arg);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/dv1394-private.h linux/drivers/ieee1394/dv1394-private.h
--- linux.orig/drivers/ieee1394/dv1394-private.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/dv1394-private.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,611 @@
+/*
+ * dv1394-private.h - DV input/output over IEEE 1394 on OHCI chips
+ *   Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
+ *     receive, proc_fs by Dan Dennedy <dan@dennedy.org>
+ *
+ * based on:
+ *   video1394.h - driver for OHCI 1394 boards
+ *   Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
+ *                          Peter Schlaile <udbz@rz.uni-karlsruhe.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.
+ */
+
+#ifndef _DV_1394_PRIVATE_H
+#define _DV_1394_PRIVATE_H
+
+#include "ieee1394.h"
+#include <linux/pci.h>
+#include <asm/scatterlist.h>
+
+/* data structures private to the dv1394 driver */
+/* none of this is exposed to user-space */
+
+
+/* 
+   the 8-byte CIP (Common Isochronous Packet) header that precedes
+   each packet of DV data.
+
+   See the IEC 61883 standard. 
+*/
+
+struct CIP_header { unsigned char b[8]; };
+
+static inline void fill_cip_header(struct CIP_header *cip,
+				   unsigned char source_node_id,
+				   unsigned long counter,
+				   enum pal_or_ntsc format,
+				   unsigned long timestamp)
+{
+	cip->b[0] = source_node_id;
+	cip->b[1] = 0x78; /* packet size in quadlets (480/4) - even for empty packets! */
+	cip->b[2] = 0x00;
+	cip->b[3] = counter;
+
+	cip->b[4] = 0x80; /* const */
+
+	switch(format) {
+	case DV1394_PAL:
+		cip->b[5] = 0x80;
+		break;
+	case DV1394_NTSC:
+		cip->b[5] = 0x00;
+		break;
+	}
+
+	cip->b[6] = timestamp >> 8;
+	cip->b[7] = timestamp & 0xFF;
+}
+
+
+
+/* 
+   DMA commands used to program the OHCI's DMA engine
+
+   See the Texas Instruments OHCI 1394 chipset documentation. 
+*/
+
+struct output_more_immediate { u32 q[8]; };
+struct output_more { u32 q[4]; };
+struct output_last { u32 q[4]; };
+struct input_more { u32 q[4]; };
+struct input_last { u32 q[4]; };
+
+/* outputs */
+
+static inline void fill_output_more_immediate(struct output_more_immediate *omi,
+					      unsigned char tag,
+					      unsigned char channel,
+					      unsigned char sync_tag,
+					      unsigned int  payload_size)
+{
+	omi->q[0] = 0x02000000 | 8 ; /* OUTPUT_MORE_IMMEDIATE; 8 is the size of the IT header */
+	omi->q[1] = 0;
+	omi->q[2] = 0;
+	omi->q[3] = 0;
+	
+	/* IT packet header */
+	omi->q[4] = (0x0 << 16)  /* DMA_SPEED_100 */
+			| (tag << 14)
+			| (channel << 8)
+			| (TCODE_ISO_DATA << 4) 
+			| (sync_tag);
+
+	omi->q[5] = payload_size << 16;
+	omi->q[5] |= (0x7F << 8) | 0xA0; /* reserved field; mimic behavior of my Sony DSR-40 */
+	
+	omi->q[6] = 0;
+	omi->q[7] = 0;
+}
+
+static inline void fill_output_more(struct output_more *om,
+				    unsigned int data_size,
+				    unsigned long data_phys_addr)
+{
+	om->q[0] = 0; /* OUTPUT_MORE */
+	om->q[0] |= data_size;
+
+	om->q[1] = data_phys_addr;
+	om->q[2] = 0;
+	om->q[3] = 0;
+}
+
+static inline void fill_output_last(struct output_last *ol,
+				    int want_timestamp,
+				    int want_interrupt,
+				    unsigned int data_size,
+				    unsigned long data_phys_addr)
+{
+	ol->q[0] = 0;
+	ol->q[0] |= 1 << 28; /* OUTPUT_LAST */
+
+	if(want_timestamp) /* controller will update timestamp at DMA time */
+		ol->q[0] |= 1 << 27;
+
+	if(want_interrupt)
+		ol->q[0] |= 3 << 20;
+
+	ol->q[0] |= 3 << 18; /* must take branch */
+	ol->q[0] |= data_size;
+	
+	ol->q[1] = data_phys_addr;
+	ol->q[2] = 0;
+	ol->q[3] = 0;
+}
+
+/* inputs */
+
+static inline void fill_input_more(struct input_more *im,
+				   int want_interrupt,
+				   unsigned int data_size,
+				   unsigned long data_phys_addr)
+{
+	im->q[0] =  2 << 28; /* INPUT_MORE */
+	im->q[0] |= 8 << 24; /* s = 1, update xferStatus and resCount */
+	if (want_interrupt)
+		im->q[0] |= 0 << 20; /* interrupts, i=0 in packet-per-buffer mode */
+	im->q[0] |= 0x0 << 16; /* disable branch to address for packet-per-buffer mode */
+	                       /* disable wait on sync field, not used in DV :-( */
+       	im->q[0] |= data_size;
+
+	im->q[1] = data_phys_addr;
+	im->q[2] = 0; /* branchAddress and Z not use in packet-per-buffer mode */
+	im->q[3] = 0; /* xferStatus & resCount, resCount must be initialize to data_size */
+}
+ 
+static inline void fill_input_last(struct input_last *il,
+				    unsigned int data_size,
+				    unsigned long data_phys_addr)
+{
+	il->q[0] =  3 << 28; /* INPUT_LAST */
+	il->q[0] |= 8 << 24; /* s = 1, update xferStatus and resCount */
+	il->q[0] |= 3 << 20; /* enable interrupts */
+	il->q[0] |= 0xC << 16; /* enable branch to address */
+	                       /* disable wait on sync field, not used in DV :-( */
+	il->q[0] |= data_size;
+
+	il->q[1] = data_phys_addr;
+	il->q[2] = 1; /* branchAddress (filled in later) and Z = 1 descriptor in next block */
+	il->q[3] = data_size; /* xferStatus & resCount, resCount must be initialize to data_size */
+}
+
+
+
+/* 
+   A "DMA descriptor block" consists of several contiguous DMA commands.
+   struct DMA_descriptor_block encapsulates all of the commands necessary 
+   to send one packet of DV data. 
+   
+   There are three different types of these blocks:
+
+        1) command to send an empty packet (CIP header only, no DV data):
+
+	    OUTPUT_MORE-Immediate <-- contains the iso header in-line
+	    OUTPUT_LAST           <-- points to the CIP header
+
+	2) command to send a full packet when the DV data payload does NOT
+	   cross a page boundary:
+
+	    OUTPUT_MORE-Immediate <-- contains the iso header in-line
+	    OUTPUT_MORE           <-- points to the CIP header
+	    OUTPUT_LAST           <-- points to entire DV data payload
+
+	3) command to send a full packet when the DV payload DOES cross
+	   a page boundary:
+
+	    OUTPUT_MORE-Immediate <-- contains the iso header in-line
+	    OUTPUT_MORE           <-- points to the CIP header
+	    OUTPUT_MORE           <-- points to first part of DV data payload
+	    OUTPUT_LAST           <-- points to second part of DV data payload
+
+   This struct describes all three block types using unions.
+
+   !!! It is vital that an even number of these descriptor blocks fit on one
+   page of memory, since a block cannot cross a page boundary !!!
+
+ */
+
+struct DMA_descriptor_block {
+
+	union {
+		struct {
+			/*  iso header, common to all output block types */
+			struct output_more_immediate omi; 
+			
+			union {
+				/* empty packet */
+				struct {
+					struct output_last ol;  /* CIP header */
+				} empty;
+			
+				/* full packet */
+				struct {
+					struct output_more om;  /* CIP header */
+					
+					union {
+				               /* payload does not cross page boundary */
+						struct {
+							struct output_last ol;  /* data payload */
+						} nocross;
+						
+				               /* payload crosses page boundary */
+						struct {
+							struct output_more om;  /* data payload */
+							struct output_last ol;  /* data payload */
+						} cross;
+					} u;
+					
+				} full;
+			} u;
+		} out;
+
+		struct {
+			struct input_last il; 
+		} in;
+
+	} u;
+
+	/* ensure that PAGE_SIZE % sizeof(struct DMA_descriptor_block) == 0 
+	   by padding out to 128 bytes */
+	u32 __pad__[12]; 
+};
+
+
+/* struct frame contains all data associated with one frame in the
+   ringbuffer these are allocated when the DMA context is initialized
+   do_dv1394_init().  They are re-used after the card finishes
+   transmitting the frame. */
+
+struct video_card; /* forward declaration */
+
+struct frame {
+
+	/* points to the struct video_card that owns this frame */
+	struct video_card *video;
+
+	/* index of this frame in video_card->frames[] */
+	unsigned int frame_num;
+
+	/* FRAME_CLEAR - DMA program not set up, waiting for data 
+	   FRAME_READY - DMA program written, ready to transmit
+
+	   Changes to these should be locked against the interrupt
+	*/
+	enum {
+		FRAME_CLEAR = 0,
+		FRAME_READY
+	} state;
+	
+	/* whether this frame has been DMA'ed already; used only from
+	   the IRQ handler to determine whether the frame can be reset */
+	int done;
+
+
+	/* kernel virtual pointer to the start of this frame's data in
+	   the user ringbuffer. Use only for CPU access; to get the DMA
+	   bus address you must go through the video->user_dma mapping */
+	unsigned long data; 
+
+	/* Max # of packets per frame */
+        #define MAX_PACKETS 320
+
+
+	/* a PAGE_SIZE memory pool for allocating CIP headers
+	   !header_pool must be aligned to PAGE_SIZE! */
+	struct CIP_header *header_pool;
+	dma_addr_t         header_pool_dma;
+
+	
+	/* a physically contiguous memory pool for allocating DMA
+	   descriptor blocks; usually around 64KB in size
+	   !descriptor_pool must be aligned to PAGE_SIZE! */
+	struct DMA_descriptor_block *descriptor_pool;
+	dma_addr_t                   descriptor_pool_dma;
+	unsigned long                descriptor_pool_size;
+
+
+	/* # of packets allocated for this frame */
+	unsigned int n_packets;
+
+
+	/* below are several pointers (kernel virtual addresses, not
+	   DMA bus addresses) to parts of the DMA program.  These are
+	   set each time the DMA program is written in
+	   frame_prepare(). They are used later on, e.g. from the
+	   interrupt handler, to check the status of the frame */
+
+	/* points to status/timestamp field of first DMA packet */
+	/* (we'll check it later to monitor timestamp accuracy) */
+	u32 *frame_begin_timestamp;
+
+	/* the timestamp we assigned to the first packet in the frame */
+	u32 assigned_timestamp;
+
+	/* pointer to the first packet's CIP header (where the timestamp goes) */
+	struct CIP_header *cip_syt1;
+	
+	/* pointer to the second packet's CIP header
+	   (only set if the first packet was empty) */
+	struct CIP_header *cip_syt2;
+
+	/* in order to figure out what caused an interrupt,
+	   store pointers to the status fields of the two packets
+	   that can cause interrupts. We'll check these from the
+	   interrupt handler.
+	*/
+	u32 *mid_frame_timestamp;
+	u32 *frame_end_timestamp;
+
+	/* branch address field of final packet. This is effectively
+	   the "tail" in the chain of DMA descriptor blocks.
+	   We will fill it with the address of the first DMA descriptor
+	   block in the subsequent frame, once it is ready.
+	*/
+	u32 *frame_end_branch;
+
+	/* the number of descriptors in the first descriptor block
+	   of the frame. Needed to start DMA */
+	int first_n_descriptors;
+};
+
+
+struct packet {
+	u16	timestamp;
+	u16	invalid;
+	u16	iso_header;
+	u16	data_length;
+	u32	cip_h1;
+	u32	cip_h2;
+	unsigned char data[480];
+	unsigned char padding[16]; /* force struct size =512 for page alignment */
+};
+
+
+/* allocate/free a frame */
+static struct frame* frame_new(unsigned int frame_num, struct video_card *video);
+static void frame_delete(struct frame *f);
+
+/* reset f so that it can be used again */
+static void frame_reset(struct frame *f);
+
+
+/* structure for bookkeeping of a large non-physically-contiguous DMA buffer */
+
+struct dma_region {
+	unsigned int n_pages;
+	unsigned int n_dma_pages;
+	struct scatterlist *sglist;
+};
+
+/* return the DMA bus address of the byte with the given offset
+   relative to the beginning of the dma_region */
+
+static inline dma_addr_t dma_offset_to_bus(struct dma_region *dma, unsigned long offset)
+{
+	int i;
+	struct scatterlist *sg;
+	
+	for(i = 0, sg = &dma->sglist[0]; i < dma->n_dma_pages; i++, sg++) {
+		if(offset < sg_dma_len(sg)) {
+			return sg_dma_address(sg) + offset;
+		} 
+		offset -= sg_dma_len(sg);
+	}
+	
+	printk(KERN_ERR "dv1394: dma_offset_to_bus failed for offset %lu!\n", offset);
+	return 0;
+}
+
+
+/* struct video_card contains all data associated with one instance
+   of the dv1394 driver 
+*/
+enum modes {
+	MODE_RECEIVE,
+	MODE_TRANSMIT
+};
+
+struct video_card {
+
+	/* ohci card to which this instance corresponds */
+	struct ti_ohci *ohci;
+
+	/* OHCI card id; the link between the VFS inode and a specific video_card
+	   (essentially the device minor number) */
+	int id;
+
+	/* entry in dv1394_cards */
+	struct list_head list;
+
+	/* handle to /dev/ieee1394/dv/N, NULL if devfs not in use */
+	devfs_handle_t devfs_handle;
+
+	/* OHCI card IT DMA context number, -1 if not in use */
+	int ohci_it_ctx;
+
+	/* register offsets for current IT DMA context, 0 if not in use */
+	u32 ohci_IsoXmitContextControlSet;
+	u32 ohci_IsoXmitContextControlClear;
+	u32 ohci_IsoXmitCommandPtr;
+	
+	/* OHCI card IR DMA context number, -1 if not in use */
+	int ohci_ir_ctx;
+
+	/* register offsets for current IR DMA context, 0 if not in use */
+	u32 ohci_IsoRcvContextControlSet;
+	u32 ohci_IsoRcvContextControlClear;
+	u32 ohci_IsoRcvCommandPtr;
+	u32 ohci_IsoRcvContextMatch;
+	
+	
+	/* CONCURRENCY CONTROL */
+	
+	/* there are THREE levels of locking associated with video_card. */
+
+	/*
+	   1) the 'open' flag - this prevents more than one process from
+	   opening the device. (the driver currently assumes only one opener).
+	   This is a regular int, but use test_and_set_bit() (on bit zero) 
+	   for atomicity.
+	 */
+	unsigned long open;
+
+	/* 
+	   2) the spinlock - this provides mutual exclusion between the interrupt
+	   handler and process-context operations. Generally you must take the
+	   spinlock under the following conditions:
+	     1) DMA (and hence the interrupt handler) may be running
+	     AND
+	     2) you need to operate on the video_card, especially active_frame
+
+	     It is OK to play with video_card without taking the spinlock if
+	     you are certain that DMA is not running. Even if DMA is running,
+	     it is OK to *read* active_frame with the lock, then drop it
+	     immediately. This is safe because the interrupt handler will never
+	     advance active_frame onto a frame that is not READY (and the spinlock
+	     must be held while marking a frame READY).
+	 */
+	spinlock_t spinlock;
+
+	/*
+	  3) the sleeping semaphore 'sem' - this is used from process context only,
+	  to serialize various operations on the video_card. Even though only one
+	  open() is allowed, we still need to prevent multiple threads of execution
+	  from entering calls like read, write, ioctl, etc.
+
+	  I honestly can't think of a good reason to use dv1394 from several threads
+	  at once, but we need to serialize anyway to prevent oopses =).
+
+	  NOTE: if you need both spinlock and sem, take sem first to avoid deadlock!
+	 */
+	struct semaphore sem;
+
+	/* people waiting for buffer space, please form a line here... */
+	wait_queue_head_t waitq;
+
+	/* support asynchronous I/O signals (SIGIO) */
+	struct fasync_struct *fasync;
+	
+	/* the large, non-contiguous (rvmalloc()) ringbuffer for DV
+           data, exposed to user-space via mmap() */
+	unsigned char     *user_buf;
+	unsigned long      user_buf_size;
+	struct dma_region  user_dma;
+	
+	/* next byte in the ringbuffer that a write() call will fill */
+	size_t write_off;
+
+	struct frame *frames[DV1394_MAX_FRAMES];
+	
+	/* n_frames also serves as an indicator that this struct video_card is
+	   intialized and ready to run DMA buffers */
+
+	int n_frames;
+
+	/* this is the frame that is currently "owned" by the OHCI DMA controller
+	   (set to -1 iff DMA is not running) 
+
+	   ! must lock against the interrupt handler when accessing it !
+
+	   RULES:
+
+	       Only the interrupt handler may change active_frame if DMA
+	          is running; if not, process may change it
+
+	       If the next frame is READY, the interrupt handler will advance
+	       active_frame when the current frame is finished.
+
+	       If the next frame is CLEAR, the interrupt handler will re-transmit
+	       the current frame, and the dropped_frames counter will be  incremented.
+
+	       The interrupt handler will NEVER advance active_frame to a
+	       frame that is not READY.
+	       
+	*/
+	int active_frame;
+	int first_run;
+
+	/* the same locking rules apply to these three fields also: */
+
+	/* altered ONLY from process context. Must check first_clear_frame->state;
+	   if it's READY, that means the ringbuffer is full with READY frames;
+	   if it's CLEAR, that means one or more ringbuffer frames are CLEAR */
+	unsigned int first_clear_frame; 
+
+	/* altered both by process and interrupt */
+	unsigned int n_clear_frames;   
+
+	/* only altered by the interrupt */
+	unsigned int dropped_frames;
+
+
+
+	/* the CIP accumulator and continuity counter are properties
+	   of the DMA stream as a whole (not a single frame), so they
+	   are stored here in the video_card */
+
+	unsigned long cip_accum;
+	unsigned long cip_n, cip_d;
+	unsigned int syt_offset;
+	unsigned int continuity_counter;
+
+	enum pal_or_ntsc pal_or_ntsc;
+
+	/* redundant, but simplifies the code somewhat */
+	unsigned int frame_size; /* in bytes */
+
+	/* the isochronous channel to use, -1 if video card is inactive */
+	int channel;
+
+	
+	/* physically contiguous packet ringbuffer for receive */
+#define MAX_PACKET_BUFFER 30
+	struct packet *packet_buffer;
+	dma_addr_t     packet_buffer_dma;
+	unsigned long  packet_buffer_size;
+	
+	unsigned int current_packet;
+	int first_frame; 	/* received first start frame marker? */
+	enum modes mode;
+};
+
+/* 
+   if the video_card is not initialized, then the ONLY fields that are valid are:
+   ohci
+   open
+   n_frames
+*/
+
+static inline int video_card_initialized(struct video_card *v)
+{
+	return v->n_frames > 0;
+}
+
+static int do_dv1394_init(struct video_card *video, struct dv1394_init *init);
+static int do_dv1394_init_default(struct video_card *video);
+static int do_dv1394_shutdown(struct video_card *video, int free_user_buf);
+
+
+/* NTSC empty packet rate accurate to within 0.01%, 
+   calibrated against a Sony DSR-40 DVCAM deck */
+
+#define CIP_N_NTSC   68000000
+#define CIP_D_NTSC 1000000000
+
+#define CIP_N_PAL  1
+#define CIP_D_PAL 16
+
+#endif /* _DV_1394_PRIVATE_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/dv1394.c linux/drivers/ieee1394/dv1394.c
--- linux.orig/drivers/ieee1394/dv1394.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/dv1394.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,3066 @@
+/*
+ * dv1394.c - DV input/output over IEEE 1394 on OHCI chips
+ *   Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
+ *     receive, proc_fs by Dan Dennedy <dan@dennedy.org>
+ *
+ * based on:
+ *  video1394.c - video driver for OHCI 1394 boards
+ *  Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
+ *
+ * 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.
+ */
+
+/*
+  OVERVIEW
+
+  I designed dv1394 as a "pipe" that you can use to shoot DV onto a
+  FireWire bus. In transmission mode, dv1394 does the following:
+
+   1. accepts contiguous frames of DV data from user-space, via write()
+      or mmap() (see dv1394.h for the complete API)
+   2. wraps IEC 61883 packets around the DV data, inserting
+      empty synchronization packets as necessary
+   3. assigns accurate SYT timestamps to the outgoing packets
+   4. shoots them out using the OHCI card's IT DMA engine
+
+   Thanks to Dan Dennedy, we now have a receive mode that does the following:
+
+   1. accepts raw IEC 61883 packets from the OHCI card
+   2. re-assembles the DV data payloads into contiguous frames,
+      discarding empty packets
+   3. sends the DV data to user-space via read() or mmap()
+*/
+
+/*
+  TODO:
+
+  - tunable frame-drop behavior: either loop last frame, or halt transmission
+  
+  - use a scatter/gather buffer for DMA programs (f->descriptor_pool)
+    so that we don't rely on allocating 64KB of contiguous kernel memory
+    via pci_alloc_consistent()
+    
+  DONE:
+  - restart IT DMA after a bus reset
+  - safely obtain and release ISO Tx channels in cooperation with OHCI driver
+  - map received DIF blocks to their proper location in DV frame (ensure
+    recovery if dropped packet)
+  - handle bus resets gracefully (OHCI card seems to take care of this itself(!))
+  - do not allow resizing the user_buf once allocated; eliminate nuke_buffer_mappings
+  - eliminated #ifdef DV1394_DEBUG_LEVEL by inventing macros debug_printk and irq_printk
+  - added wmb() and mb() to places where PCI read/write ordering needs to be enforced
+  - set video->id correctly
+  - store video_cards in an array indexed by OHCI card ID, rather than a list
+  - implement DMA context allocation to cooperate with other users of the OHCI
+  - fix all XXX showstoppers
+  - disable IR/IT DMA interrupts on shutdown
+  - flush pci writes to the card by issuing a read
+  - devfs and character device dispatching (* needs testing with Linux 2.2.x)
+  - switch over to the new kernel DMA API (pci_map_*()) (* needs testing on platforms with IOMMU!)
+  - keep all video_cards in a list (for open() via chardev), set file->private_data = video
+  - dv1394_poll should indicate POLLIN when receiving buffers are available
+  - add proc fs interface to set cip_n, cip_d, syt_offset, and video signal
+  - expose xmit and recv as separate devices (not exclusive)
+  - expose NTSC and PAL as separate devices (can be overridden)
+  - read/edit channel in procfs
+
+*/
+     
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/smp_lock.h>
+#include <asm/byteorder.h>
+#include <asm/atomic.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/tqueue.h>
+#include <linux/delay.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/wrapper.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+
+#include "ieee1394.h"
+#include "ieee1394_types.h"
+#include "hosts.h"
+#include "ieee1394_core.h"
+#include "highlevel.h"	
+#include "dv1394.h"
+#include "dv1394-private.h"
+
+#include "ohci1394.h"
+
+#ifndef virt_to_page
+#define virt_to_page(x) MAP_NR(x)
+#endif
+
+#ifndef vmalloc_32
+#define vmalloc_32(x) vmalloc(x)
+#endif
+
+
+/* DEBUG LEVELS:
+   0 - no debugging messages
+   1 - some debugging messages, but none during DMA frame transmission
+   2 - lots of messages, including during DMA frame transmission
+       (will cause undeflows if your machine is too slow!)
+*/
+
+#define DV1394_DEBUG_LEVEL 0
+
+/* for debugging use ONLY: allow more than one open() of the device */
+/* #define DV1394_ALLOW_MORE_THAN_ONE_OPEN 1 */
+
+#if DV1394_DEBUG_LEVEL >= 2
+#define irq_printk( args... ) printk( args )
+#else
+#define irq_printk( args... )
+#endif
+
+#if DV1394_DEBUG_LEVEL >= 1
+#define debug_printk( args... ) printk( args)
+#else
+#define debug_printk( args... )
+#endif
+
+/* issue a dummy PCI read to force the preceding write
+   to be posted to the PCI bus immediately */
+
+static inline void flush_pci_write(struct ti_ohci *ohci)
+{
+	mb();
+	reg_read(ohci, OHCI1394_IsochronousCycleTimer);
+}
+
+static void irq_handler(int card, quadlet_t isoRecvIntEvent, 
+			quadlet_t isoXmitIntEvent, void *data);
+
+
+/* GLOBAL DATA */
+
+/* list of all video_cards */
+static LIST_HEAD(dv1394_cards);
+static spinlock_t dv1394_cards_lock = SPIN_LOCK_UNLOCKED;
+
+static struct hpsb_highlevel *hl_handle; /* = NULL; */
+
+static LIST_HEAD(dv1394_devfs);
+struct dv1394_devfs_entry {
+	struct list_head list;
+    devfs_handle_t devfs;
+	char name[32];
+	struct dv1394_devfs_entry *parent;
+};
+static spinlock_t dv1394_devfs_lock = SPIN_LOCK_UNLOCKED;
+
+/* translate from a struct file* to the corresponding struct video_card* */
+
+static inline struct video_card* file_to_video_card(struct file *file)
+{
+	return (struct video_card*) file->private_data;
+}
+
+
+/* Taken from bttv.c */
+/*******************************/
+/* Memory management functions */
+/*******************************/
+
+static void * rvmalloc(unsigned long size)
+{
+	void * mem;
+	unsigned long adr;
+
+	size = PAGE_ALIGN(size);
+	mem=vmalloc_32(size);
+	if (mem) {
+		memset(mem, 0, size); /* Clear the ram out, 
+					 no junk to the user */
+	        adr=(unsigned long) mem;
+		while (size > 0) {
+			mem_map_reserve(vmalloc_to_page((void *)adr));
+			adr+=PAGE_SIZE;
+			size-=PAGE_SIZE;
+		}
+	}
+	return mem;
+}
+
+static void rvfree(void * mem, unsigned long size)
+{
+        unsigned long adr;
+
+	if (mem) {
+	        adr=(unsigned long) mem;
+		while (size > 0) {
+			mem_map_unreserve(vmalloc_to_page((void *)adr));
+			adr+=PAGE_SIZE;
+			size-=PAGE_SIZE;
+		}
+		vfree(mem);
+	}
+}
+
+/***********************************/
+/* END Memory management functions */
+/***********************************/
+
+
+/*** FRAME METHODS *********************************************************/
+
+static void frame_reset(struct frame *f)
+{
+	f->state = FRAME_CLEAR;
+	f->done = 0;
+	f->n_packets = 0;
+	f->frame_begin_timestamp = NULL;
+	f->assigned_timestamp = 0;
+	f->cip_syt1 = NULL;
+	f->cip_syt2 = NULL;
+	f->mid_frame_timestamp = NULL;
+	f->frame_end_timestamp = NULL;
+	f->frame_end_branch = NULL;
+}
+
+static struct frame* frame_new(unsigned int frame_num, struct video_card *video)
+{
+	struct frame *f = kmalloc(sizeof(*f), GFP_KERNEL);
+	if(!f)
+		return NULL;
+
+	f->video = video;
+	f->frame_num = frame_num;
+
+	f->header_pool = pci_alloc_consistent(f->video->ohci->dev, PAGE_SIZE, &f->header_pool_dma);
+	if(!f->header_pool) {
+		printk(KERN_ERR "dv1394: failed to allocate CIP header pool\n");
+		kfree(f);
+		return NULL;
+	}
+
+	debug_printk("dv1394: frame_new: allocated CIP header pool at virt 0x%08lx (contig) dma 0x%08lx size %ld\n",
+		     (unsigned long) f->header_pool, (unsigned long) f->header_pool_dma, PAGE_SIZE);
+	
+	f->descriptor_pool_size = MAX_PACKETS * sizeof(struct DMA_descriptor_block);
+	/* make it an even # of pages */
+	f->descriptor_pool_size += PAGE_SIZE - (f->descriptor_pool_size%PAGE_SIZE);
+
+	f->descriptor_pool = pci_alloc_consistent(f->video->ohci->dev,
+						  f->descriptor_pool_size,
+						  &f->descriptor_pool_dma);
+	if(!f->descriptor_pool) {
+		pci_free_consistent(f->video->ohci->dev, PAGE_SIZE, f->header_pool, f->header_pool_dma);
+		kfree(f);
+		return NULL;
+	}
+	
+	debug_printk("dv1394: frame_new: allocated DMA program memory at virt 0x%08lx (contig) dma 0x%08lx size %ld\n",
+		     (unsigned long) f->descriptor_pool, (unsigned long) f->descriptor_pool_dma, f->descriptor_pool_size);
+	
+	f->data = 0;
+	frame_reset(f);
+
+	return f;
+}
+
+static void frame_delete(struct frame *f)
+{
+	pci_free_consistent(f->video->ohci->dev, PAGE_SIZE, f->header_pool, f->header_pool_dma);
+	pci_free_consistent(f->video->ohci->dev, f->descriptor_pool_size, f->descriptor_pool, f->descriptor_pool_dma);
+	kfree(f);
+}
+
+
+
+
+/* 
+   frame_prepare() - build the DMA program for transmitting
+   
+   Frame_prepare() must be called OUTSIDE the video->spinlock.
+   However, frame_prepare() must still be serialized, so
+   it should be called WITH the video->sem taken.
+ */
+
+static void frame_prepare(struct video_card *video, unsigned int this_frame)
+{
+	struct frame *f = video->frames[this_frame];
+	int last_frame;
+
+	struct DMA_descriptor_block *block;
+	dma_addr_t block_dma;
+	struct CIP_header *cip;
+	dma_addr_t cip_dma;
+	
+	unsigned int n_descriptors, full_packets, packets_per_frame, payload_size;
+
+	/* these flags denote packets that need special attention */
+	int empty_packet, first_packet, last_packet, mid_packet;
+
+	u32 *branch_address, *last_branch_address = NULL;
+	unsigned long data_p;
+	int first_packet_empty = 0;
+	u32 cycleTimer, ct_sec, ct_cyc, ct_off;
+	unsigned long irq_flags;
+
+	irq_printk("frame_prepare( %d ) ---------------------\n", this_frame);
+	
+	full_packets = 0;
+
+
+
+	if(video->pal_or_ntsc == DV1394_PAL)
+		packets_per_frame = DV1394_PAL_PACKETS_PER_FRAME;
+	else
+		packets_per_frame = DV1394_NTSC_PACKETS_PER_FRAME;
+
+	while( full_packets < packets_per_frame ) {
+		empty_packet = first_packet = last_packet = mid_packet = 0;
+
+		data_p = f->data + full_packets * 480;
+
+		/************************************************/
+		/* allocate a descriptor block and a CIP header */
+		/************************************************/
+
+		/* note: these should NOT cross a page boundary (DMA restriction) */
+
+		if(f->n_packets >= MAX_PACKETS) {
+			printk(KERN_ERR "dv1394: FATAL ERROR: max packet count exceeded\n");
+			return;
+		}
+
+		/* the block surely won't cross a page boundary, 
+		   since an even number of descriptor_blocks fit on a page */
+		block = &(f->descriptor_pool[f->n_packets]);
+
+		/* DMA address of the block = offset of block relative
+		    to the kernel base address of the descriptor pool
+		    + DMA base address of the descriptor pool */
+		block_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma;
+		
+
+		/* the whole CIP pool fits on one page, so no worries about boundaries */
+		if( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) 
+		    > PAGE_SIZE) {
+			printk(KERN_ERR "dv1394: FATAL ERROR: no room to allocate CIP header\n");
+			return;
+		}
+
+		cip = &(f->header_pool[f->n_packets]);
+		
+		/* DMA address of the CIP header = offset of cip
+		   relative to kernel base address of the header pool
+		   + DMA base address of the header pool */
+		cip_dma = (unsigned long) cip % PAGE_SIZE + f->header_pool_dma;
+		
+		/* is this an empty packet? */
+
+		if(video->cip_accum > video->cip_d) {
+			empty_packet = 1;
+			payload_size = 8;
+			video->cip_accum -= video->cip_d;
+		} else {
+			payload_size = 488;
+			video->cip_accum += video->cip_n;
+		}
+
+		/* there are three important packets each frame:
+
+		   the first packet in the frame - we ask the card to record the timestamp when
+		                                   this packet is actually sent, so we can monitor
+						   how accurate our timestamps are. Also, the first
+						   packet serves as a semaphore to let us know that
+						   it's OK to free the *previous* frame's DMA buffer
+
+		   the last packet in the frame -  this packet is used to detect buffer underflows.
+		                                   if this is the last ready frame, the last DMA block
+						   will have a branch back to the beginning of the frame
+						   (so that the card will re-send the frame on underflow).
+						   if this branch gets taken, we know that at least one
+						   frame has been dropped. When the next frame is ready,
+						   the branch is pointed to its first packet, and the
+						   semaphore is disabled.
+
+		   a "mid" packet slightly before the end of the frame - this packet should trigger
+		                   an interrupt so we can go and assign a timestamp to the first packet
+				   in the next frame. We don't use the very last packet in the frame
+				   for this purpose, because that would leave very little time to set
+				   the timestamp before DMA starts on the next frame.
+		*/
+		
+		if(f->n_packets == 0) {
+			first_packet = 1;
+		} else if ( full_packets == (packets_per_frame-1) ) {
+			last_packet = 1;
+		} else if (f->n_packets == packets_per_frame) {
+			mid_packet = 1;
+		}
+		
+
+		/********************/
+		/* setup CIP header */
+		/********************/
+
+		/* the timestamp will be written later from the
+		   mid-frame interrupt handler. For now we just
+		   store the address of the CIP header(s) that
+		   need a timestamp. */
+
+		/* first packet in the frame needs a timestamp */
+		if(first_packet) {
+			f->cip_syt1 = cip;
+			if(empty_packet)
+				first_packet_empty = 1;
+
+		} else if(first_packet_empty && (f->n_packets == 1) ) {
+			/* if the first packet was empty, the second
+			   packet's CIP header also needs a timestamp */
+			f->cip_syt2 = cip;
+		}
+
+		fill_cip_header(cip,
+				/* the node ID number of the OHCI card */
+				reg_read(video->ohci, OHCI1394_NodeID) & 0x3F,
+				video->continuity_counter, 
+				video->pal_or_ntsc,
+				0xFFFF /* the timestamp is filled in later */);
+		
+		/* advance counter, only for full packets */
+		if( ! empty_packet )
+			video->continuity_counter++;
+
+		/******************************/
+		/* setup DMA descriptor block */
+		/******************************/
+
+		/* first descriptor - OUTPUT_MORE_IMMEDIATE, for the controller's IT header */
+		fill_output_more_immediate( &(block->u.out.omi),
+					    /* tag - what is this??? */ 1,
+					    video->channel,
+					    /* sync tag - what is this??? */ 0,
+					    payload_size);
+
+		if(empty_packet) {
+			/* second descriptor - OUTPUT_LAST for CIP header */
+			fill_output_last( &(block->u.out.u.empty.ol),
+
+					  /* want completion status on all interesting packets */
+					  (first_packet || mid_packet || last_packet) ? 1 : 0,
+
+					  /* want interrupts on all interesting packets */
+					  (first_packet || mid_packet || last_packet) ? 1 : 0,
+
+					  sizeof(struct CIP_header), /* data size */
+					  cip_dma);
+			
+			if(first_packet)
+				f->frame_begin_timestamp = &(block->u.out.u.empty.ol.q[3]);
+			else if(mid_packet)
+				f->mid_frame_timestamp = &(block->u.out.u.empty.ol.q[3]);
+			else if(last_packet) {
+				f->frame_end_timestamp = &(block->u.out.u.empty.ol.q[3]);
+				f->frame_end_branch = &(block->u.out.u.empty.ol.q[2]);
+			}
+
+			branch_address = &(block->u.out.u.empty.ol.q[2]);
+			n_descriptors = 3;
+			if(first_packet)
+				f->first_n_descriptors = n_descriptors;
+
+		} else { /* full packet */
+
+			/* second descriptor - OUTPUT_MORE for CIP header */
+			fill_output_more( &(block->u.out.u.full.om),
+					  sizeof(struct CIP_header), /* data size */
+					  cip_dma);
+
+			
+			/* third (and possibly fourth) descriptor - for DV data */
+			/* the 480-byte payload can cross a page boundary; if so,
+			   we need to split it into two DMA descriptors */
+
+			/* does the 480-byte data payload cross a page boundary? */
+			if( (PAGE_SIZE- ((unsigned long)data_p % PAGE_SIZE) ) < 480 ) {
+
+				/* page boundary crossed */
+
+				fill_output_more( &(block->u.out.u.full.u.cross.om),
+						  /* data size - how much of data_p fits on the first page */
+						  PAGE_SIZE - (data_p % PAGE_SIZE),
+
+						  /* DMA address of data_p */
+						  dma_offset_to_bus(&f->video->user_dma,
+								    data_p - (unsigned long) f->video->user_buf));
+
+				fill_output_last( &(block->u.out.u.full.u.cross.ol),
+					  
+						  /* want completion status on all interesting packets */
+						  (first_packet || mid_packet || last_packet) ? 1 : 0, 
+
+						  /* want interrupt on all interesting packets */
+						  (first_packet || mid_packet || last_packet) ? 1 : 0,
+
+						  /* data size - remaining portion of data_p */
+						  480 - (PAGE_SIZE - (data_p % PAGE_SIZE)),
+
+						  /* DMA address of data_p + PAGE_SIZE - (data_p % PAGE_SIZE) */
+						  dma_offset_to_bus(&f->video->user_dma,
+								    data_p + PAGE_SIZE - (data_p % PAGE_SIZE) - (unsigned long) f->video->user_buf));
+
+				if(first_packet)
+					f->frame_begin_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
+				else if(mid_packet)
+					f->mid_frame_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
+				else if(last_packet) {
+					f->frame_end_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
+					f->frame_end_branch = &(block->u.out.u.full.u.cross.ol.q[2]);
+				}
+
+				branch_address = &(block->u.out.u.full.u.cross.ol.q[2]);
+
+				n_descriptors = 5;
+				if(first_packet)
+					f->first_n_descriptors = n_descriptors;
+				
+				full_packets++;
+
+			} else {
+				/* fits on one page */
+
+				fill_output_last( &(block->u.out.u.full.u.nocross.ol),
+					  
+						  /* want completion status on all interesting packets */
+						  (first_packet || mid_packet || last_packet) ? 1 : 0,
+
+						  /* want interrupt on all interesting packets */
+						  (first_packet || mid_packet || last_packet) ? 1 : 0,
+
+						  480, /* data size (480 bytes of DV data) */
+
+						  
+						  /* DMA address of data_p */
+						  dma_offset_to_bus(&f->video->user_dma,
+								    data_p - (unsigned long) f->video->user_buf));
+				
+				if(first_packet)
+					f->frame_begin_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
+				else if(mid_packet)
+					f->mid_frame_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
+				else if(last_packet) {
+					f->frame_end_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
+					f->frame_end_branch = &(block->u.out.u.full.u.nocross.ol.q[2]);
+				}
+
+				branch_address = &(block->u.out.u.full.u.nocross.ol.q[2]);
+
+				n_descriptors = 4;
+				if(first_packet)
+					f->first_n_descriptors = n_descriptors;
+
+				full_packets++;
+			}
+		}
+		
+		/* link this descriptor block into the DMA program by filling in 
+		   the branch address of the previous block */
+
+		/* note: we are not linked into the active DMA chain yet */
+
+		if(last_branch_address) {
+			*(last_branch_address) = block_dma | n_descriptors; 
+		}
+
+		last_branch_address = branch_address;
+
+
+		f->n_packets++;
+		
+	}
+
+	/* when we first assemble a new frame, set the final branch 
+	   to loop back up to the top */
+	*(f->frame_end_branch) = f->descriptor_pool_dma | f->first_n_descriptors;
+
+
+	/* make the latest version of the frame buffer visible to the PCI card */
+	/* could optimize this by only syncing the pages associated with this frame */
+	pci_dma_sync_sg(video->ohci->dev,
+			&video->user_dma.sglist[0],
+			video->user_dma.n_dma_pages,
+			PCI_DMA_TODEVICE);
+
+	/* lock against DMA interrupt */
+	spin_lock_irqsave(&video->spinlock, irq_flags);
+
+	f->state = FRAME_READY;
+
+	video->n_clear_frames--;
+
+	last_frame = video->first_clear_frame - 1;
+	if(last_frame == -1)
+		last_frame = video->n_frames-1;
+
+	video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
+
+	irq_printk("   frame %d prepared, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n last=%d\n",
+		   this_frame, video->active_frame, video->n_clear_frames, video->first_clear_frame, last_frame);
+
+	irq_printk("   begin_ts %08lx mid_ts %08lx end_ts %08lx end_br %08lx\n",
+		   (unsigned long) f->frame_begin_timestamp, 
+		   (unsigned long) f->mid_frame_timestamp, 
+		   (unsigned long) f->frame_end_timestamp, 
+		   (unsigned long) f->frame_end_branch);
+	
+	if(video->active_frame != -1) {
+
+		/* if DMA is already active, we are almost done */
+		/* just link us onto the active DMA chain */
+		if(video->frames[last_frame]->frame_end_branch) {
+
+			/* point the previous frame's tail to this frame's head */
+			*(video->frames[last_frame]->frame_end_branch) = f->descriptor_pool_dma | f->first_n_descriptors; 
+
+			/* this write MUST precede the next one, or we could silently drop frames */
+			wmb();
+			
+			/* disable the want_status semaphore on the last packet */
+			*(video->frames[last_frame]->frame_end_branch - 2) &= 0xF7CFFFFF;
+
+			/* flush these writes to memory ASAP */
+			flush_pci_write(video->ohci);
+
+			/* NOTE:
+			   ideally the writes should be "atomic": if
+			   the OHCI card reads the want_status flag in
+			   between them, we'll falsely report a
+			   dropped frame. Hopefully this window is too
+			   small to really matter, and the consequence
+			   is rather harmless. */
+			
+
+			irq_printk("     new frame %d linked onto DMA chain\n", this_frame);
+
+		} else {
+			printk(KERN_ERR "dv1394: last frame not ready???\n");
+		}
+
+	} else {
+		
+		u32 transmit_sec, transmit_cyc;
+		u32 ts_cyc, ts_off;
+
+		/* DMA is stopped, so this is the very first frame */
+		video->active_frame = this_frame;
+		
+	        /* set CommandPtr to address and size of first descriptor block */
+		reg_write(video->ohci, video->ohci_IsoXmitCommandPtr,
+			  video->frames[video->active_frame]->descriptor_pool_dma |
+			  f->first_n_descriptors);
+
+		/* assign a timestamp based on the current cycle time...
+		   We'll tell the card to begin DMA 100 cycles from now,
+		   and assign a timestamp 103 cycles from now */
+
+		cycleTimer = reg_read(video->ohci, OHCI1394_IsochronousCycleTimer);
+
+		ct_sec = cycleTimer >> 25;
+		ct_cyc = (cycleTimer >> 12) & 0x1FFF;
+		ct_off = cycleTimer & 0xFFF;
+
+		transmit_sec = ct_sec;
+		transmit_cyc = ct_cyc + 100;
+
+		transmit_sec += transmit_cyc/8000;
+		transmit_cyc %= 8000;
+		
+		ts_off = ct_off;
+		ts_cyc = transmit_cyc + 3;
+		ts_cyc %= 8000;
+
+		f->assigned_timestamp = (ts_cyc&0xF) << 12;
+
+		/* now actually write the timestamp into the appropriate CIP headers */
+		if(f->cip_syt1) {
+			f->cip_syt1->b[6] = f->assigned_timestamp >> 8;
+			f->cip_syt1->b[7] = f->assigned_timestamp & 0xFF;
+		}
+		if(f->cip_syt2) {
+			f->cip_syt2->b[6] = f->assigned_timestamp >> 8;
+			f->cip_syt2->b[7] = f->assigned_timestamp & 0xFF;
+		}
+		
+		/* --- start DMA --- */
+
+		/* clear all bits in ContextControl register */
+
+		reg_write(video->ohci, video->ohci_IsoXmitContextControlClear, 0xFFFFFFFF);
+		wmb();
+
+		/* the OHCI card has the ability to start ISO transmission on a
+		   particular cycle (start-on-cycle). This way we can ensure that
+		   the first DV frame will have an accurate timestamp.
+		   
+		   However, start-on-cycle only appears to work if the OHCI card 
+		   is cycle master! Since the consequences of messing up the first
+		   timestamp are minimal*, just disable start-on-cycle for now.
+
+		   * my DV deck drops the first few frames before it "locks in;"
+		     so the first frame having an incorrect timestamp is inconsequential.
+		*/
+
+#if 0
+		reg_write(video->ohci, video->ohci_IsoXmitContextControlSet,
+			  (1 << 31) /* enable start-on-cycle */
+			  | ( (transmit_sec & 0x3) << 29)
+			  | (transmit_cyc << 16));
+		wmb();
+#endif
+
+		
+
+		/* set the 'run' bit */
+		reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, 0x8000);
+		flush_pci_write(video->ohci);
+		
+		/* --- DMA should be running now --- */
+
+		debug_printk("    Cycle = %4u ContextControl = %08x CmdPtr = %08x\n",
+			     (reg_read(video->ohci, OHCI1394_IsochronousCycleTimer) >> 12) & 0x1FFF,
+			     reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
+			     reg_read(video->ohci, video->ohci_IsoXmitCommandPtr));
+
+		debug_printk("    DMA start - current cycle %4u, transmit cycle %4u (%2u), assigning ts cycle %2u\n",
+			     ct_cyc, transmit_cyc, transmit_cyc & 0xF, ts_cyc & 0xF);
+
+#if DV1394_DEBUG_LEVEL >= 2
+		{
+			/* check if DMA is really running */
+			int i = 0;
+			while(i < 20) {
+				mb();
+				mdelay(1);
+				if(reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) {
+					printk("DMA ACTIVE after %d msec\n", i);
+					break;
+				}
+				i++;
+			}
+
+			printk("set = %08x, cmdPtr = %08x\n", 
+			       reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
+			       reg_read(video->ohci, video->ohci_IsoXmitCommandPtr)
+			       );
+			
+			if( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) &  (1 << 10)) ) {
+				printk("DMA did NOT go active after 20ms, event = %x\n", 
+				       reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & 0x1F);
+			} else
+				printk("DMA is RUNNING!\n");
+		}
+#endif
+		
+	}
+
+
+	spin_unlock_irqrestore(&video->spinlock, irq_flags);
+}
+
+
+
+/*** RECEIVE FUNCTIONS *****************************************************/
+
+/* 
+	frame method put_packet
+
+	map and copy the packet data to its location in the frame 
+	based upon DIF section and sequence 
+*/
+
+static void inline
+frame_put_packet (struct frame *f, struct packet *p)
+{
+	int section_type = p->data[0] >> 5;           /* section type is in bits 5 - 7 */
+	int dif_sequence = p->data[1] >> 4;           /* dif sequence number is in bits 4 - 7 */
+	int dif_block = p->data[2];
+
+	switch (section_type) {
+	case 0:           /* 1 Header block */
+	        memcpy( (void *) f->data + dif_sequence * 150 * 80, p->data, 480);
+	        break;
+	
+	case 1:           /* 2 Subcode blocks */
+	        memcpy( (void *) f->data + dif_sequence * 150 * 80 + (1 + dif_block) * 80, p->data, 480);
+	        break;
+	
+	case 2:           /* 3 VAUX blocks */
+	        memcpy( (void *) f->data + dif_sequence * 150 * 80 + (3 + dif_block) * 80, p->data, 480);
+	        break;
+	
+	case 3:           /* 9 Audio blocks interleaved with video */
+	        memcpy( (void *) f->data + dif_sequence * 150 * 80 + (6 + dif_block * 16) * 80, p->data, 480);
+	        break;
+	
+	case 4:           /* 135 Video blocks interleaved with audio */
+	        memcpy( (void *) f->data + dif_sequence * 150 * 80 + (7 + (dif_block / 15) + dif_block) * 80, p->data, 480);
+	        break;
+	
+	default:           /* we can not handle any other data */
+	        break;
+	}
+}
+
+
+static void start_dma_receive(struct video_card *video, struct frame *frame)
+{
+	/* reset iso recv control register */
+	reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, 0xFFFFFFFF);
+	wmb();
+	
+	/* clear bufferFill, set isochHeader and speed (0=100) */
+	reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x40000000);
+
+	/* match on all tags, listen on channel */
+	reg_write(video->ohci, video->ohci_IsoRcvContextMatch, 0xf0000000 | video->channel);
+	
+	/* address and first descriptor block + Z=1 */
+	reg_write(video->ohci, video->ohci_IsoRcvCommandPtr,             
+		  frame->descriptor_pool_dma | 1); /* Z=1 */
+	wmb();
+	
+	/* run */
+	reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x8000);
+	flush_pci_write(video->ohci);
+	
+	debug_printk("dv1394: DMA started\n");
+
+#if DV1394_DEBUG_LEVEL >= 2
+	{
+		int i;
+	
+		for(i = 0; i < 1000; ++i) {
+			mdelay(1);
+			if(reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) {
+				printk("DMA ACTIVE after %d msec\n", i);
+				break;
+			}
+		}
+		if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) &  (1 << 11) ) {
+			printk("DEAD, event = %x\n", 
+			       reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F);
+		} else
+			printk("RUNNING!\n");
+	}
+#endif
+}
+
+
+/* 
+   receive_packets() - build the DMA program for receiving
+*/
+
+static void receive_packets(struct video_card *video, struct frame *f)
+{
+	struct DMA_descriptor_block *block = NULL;
+	dma_addr_t block_dma = 0;
+	struct packet *data = NULL;
+	dma_addr_t data_dma = 0;
+	u32 *last_branch_address = NULL;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&video->spinlock, irq_flags);
+
+	video->n_clear_frames = 0;
+	video->first_clear_frame = -1;
+
+	for (video->current_packet = 0; video->current_packet < MAX_PACKET_BUFFER; ++video->current_packet) {
+		/* locate a descriptor block and packet from the buffer */
+		block = &(f->descriptor_pool[video->current_packet]);
+		block_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma;
+		
+		data = &(video->packet_buffer[video->current_packet]);
+		data_dma = ((unsigned long) data - (unsigned long) video->packet_buffer) + video->packet_buffer_dma;
+		
+		/* setup DMA descriptor block */
+		fill_input_last( &(block->u.in.il), 512, data_dma);
+
+		/* link descriptors */
+		last_branch_address = f->frame_end_branch;
+
+		if (last_branch_address)
+			*(last_branch_address) = block_dma | 1; /* set Z=1 */
+
+		f->frame_end_branch = &(block->u.in.il.q[2]);
+	}
+	
+	/* loop tail to head */
+	if (f->frame_end_branch)
+		*(f->frame_end_branch) =  f->descriptor_pool_dma | 1; /* set Z=1 */
+
+	spin_unlock_irqrestore(&video->spinlock, irq_flags);
+
+	if (video->first_run) {
+		/* start DMA once all of the frames are READY */
+		video->first_run = 0;
+		video->current_packet = 0;
+		video->active_frame = f->frame_num;
+		start_dma_receive(video, f);
+	} 
+	else if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) &  (1 << 11) ) {
+		debug_printk("DEAD, event = %x\n", 
+			     reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F);
+
+		/* wake */
+		reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12));
+	}
+}
+
+
+
+/*** MANAGEMENT FUNCTIONS **************************************************/
+
+static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
+{
+	unsigned long flags, new_buf_size;
+	int i;
+	u64 chan_mask;
+	int retval = -EINVAL;
+
+	if(init->api_version != DV1394_API_VERSION)
+		goto err;
+	
+	/* first sanitize all the parameters */
+	if( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) )
+		goto err;
+
+	if( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) )
+		goto err;
+
+	if( (init->syt_offset == 0) || (init->syt_offset > 50) )
+		/* default SYT offset is 3 cycles */
+		init->syt_offset = 3;
+
+	if( (init->channel > 63) || (init->channel < 0) )
+		init->channel = 63;
+
+	chan_mask = (u64)1 << init->channel;
+
+	/* calculate what size DMA buffer is needed */
+	if(init->format == DV1394_NTSC)
+		new_buf_size = DV1394_NTSC_FRAME_SIZE * init->n_frames;
+	else
+		new_buf_size = DV1394_PAL_FRAME_SIZE * init->n_frames;
+
+	/* round up to PAGE_SIZE */
+	if(new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE);
+
+	/* don't allow the user to allocate the DMA buffer more than once */
+	if( (video->user_buf) &&
+	    (video->user_buf_size != new_buf_size) ) {
+		goto err;
+	}
+	
+	/* shutdown the card if it's currently active */
+	/* (the card should not be reset if the parameters are screwy) */
+	if( video_card_initialized(video) )
+		do_dv1394_shutdown(video, 0);
+
+
+	/* try to claim the ISO channel */
+	spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
+	if(video->ohci->ISO_channel_usage & chan_mask) {
+		spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
+		retval = -EBUSY;
+		goto err;
+	}
+	video->ohci->ISO_channel_usage |= chan_mask;
+	spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
+
+	video->channel = init->channel;
+
+	
+	/* find and claim DMA contexts on the OHCI card */
+	
+	if(video->ohci_it_ctx == -1) {
+
+		for(i = 0; i < video->ohci->nb_iso_xmit_ctx; i++) {
+
+			if(! test_and_set_bit(i, &video->ohci->it_ctx_usage)) {
+				video->ohci_it_ctx = i;
+				debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx);
+				break;
+			}
+		}
+				
+		if(i == video->ohci->nb_iso_xmit_ctx) {
+			printk(KERN_ERR "dv1394: could not find an available IT DMA context\n");
+			retval = -EBUSY;
+			goto err_ctx;
+		}
+	}
+	
+
+	if(video->ohci_ir_ctx == -1) {
+		for(i = 0; i < video->ohci->nb_iso_rcv_ctx; i++) {
+
+			if(! test_and_set_bit(i, &video->ohci->ir_ctx_usage)) {
+				video->ohci_ir_ctx = i;
+				debug_printk("dv1394: claimed IR DMA context %d\n", video->ohci_ir_ctx);
+				break;
+			}
+		}
+				
+		if(i == video->ohci->nb_iso_rcv_ctx) {
+			printk(KERN_ERR "dv1394: could not find an available IR DMA context\n");
+			retval = -EBUSY;
+			goto err_ctx;
+		}
+	}
+
+	
+	/* allocate struct frames */
+	for(i = 0; i < init->n_frames; i++) {
+		video->frames[i] = frame_new(i, video);
+
+		if(!video->frames[i]) {
+			printk(KERN_ERR "dv1394: Cannot allocate frame structs\n");
+			retval = -ENOMEM;
+			goto err_frames;
+		}
+	}
+
+	/* initialize misc. fields of video */
+	video->n_frames = init->n_frames;
+	video->pal_or_ntsc = init->format;
+	
+
+	video->cip_accum = 0;
+	video->continuity_counter = 0;
+
+	video->active_frame = -1;
+	video->first_clear_frame = 0;
+	video->n_clear_frames = video->n_frames;
+	video->dropped_frames = 0;
+
+	video->write_off = 0;
+
+	video->first_run = 1;
+	video->current_packet = -1;
+	video->first_frame = 0;
+
+
+	if(video->pal_or_ntsc == DV1394_NTSC) {
+		video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_NTSC;
+		video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_NTSC;
+		video->frame_size = DV1394_NTSC_FRAME_SIZE;
+	} else {
+		video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_PAL;
+		video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_PAL;
+		video->frame_size = DV1394_PAL_FRAME_SIZE;
+	}
+
+	video->syt_offset = init->syt_offset;
+
+	if(video->user_buf == NULL) {
+		unsigned int i;
+		
+		/* allocate the ringbuffer */
+		video->user_buf = rvmalloc(new_buf_size);
+		if(!video->user_buf) {
+			printk(KERN_ERR "dv1394: Cannot allocate frame buffers\n");
+			goto err_frames;
+		}
+		video->user_buf_size = new_buf_size;
+
+		/* allocate the sglist to hold the DMA addresses */
+		video->user_dma.n_pages = video->user_buf_size / PAGE_SIZE;
+		video->user_dma.sglist = kmalloc(video->user_dma.n_pages * sizeof(struct scatterlist), GFP_KERNEL);
+		if(!video->user_dma.sglist) {
+			printk(KERN_ERR "dv1394: Cannot allocate sglist for user buffer\n");
+			goto err_user_buf;
+		}
+
+		/* initialize all fields of all sglist entries to zero
+		   (new requirement due to PCI changes in 2.4.13) */
+
+		memset(video->user_dma.sglist, 0, video->user_dma.n_pages * sizeof(struct scatterlist));
+
+		
+		/* fill the sglist with the kernel addresses of pages in the non-contiguous buffer */
+		for(i = 0; i < video->user_dma.n_pages; i++) {
+			unsigned long va = (unsigned long) video->user_buf + i * PAGE_SIZE;
+			
+			video->user_dma.sglist[i].page = vmalloc_to_page((void *)va);
+			video->user_dma.sglist[i].length = PAGE_SIZE;
+		}
+		
+		/* map the buffer in the IOMMU */
+		/* the user_data buffer only allows DMA *to* the card for transmission;
+		   incoming DV data comes through the packet_buffer first, and then is copied to user_data */
+		video->user_dma.n_dma_pages = pci_map_sg(video->ohci->dev,
+							 &video->user_dma.sglist[0],
+							 video->user_dma.n_pages,
+							 PCI_DMA_TODEVICE);
+		if(video->user_dma.n_dma_pages == 0) {
+			printk(KERN_ERR "dv1394: Error mapping user buffer to the IOMMU\n");
+			goto err_user_buf;
+		}
+		
+		debug_printk("dv1394: Allocated %d frame buffers, total %u pages (%u DMA pages), %lu bytes\n", 
+			     video->n_frames, video->user_dma.n_pages,
+			     video->user_dma.n_dma_pages, video->user_buf_size);
+	}
+	
+	/* set up the frame->data pointers */
+	for(i = 0; i < video->n_frames; i++)
+		video->frames[i]->data = (unsigned long) video->user_buf + i * video->frame_size;
+
+	/* allocate packet buffers */
+	video->packet_buffer_size = sizeof(struct packet) * MAX_PACKET_BUFFER;
+	if (video->packet_buffer_size % PAGE_SIZE)
+		video->packet_buffer_size += PAGE_SIZE - (video->packet_buffer_size % PAGE_SIZE);
+
+	
+	video->packet_buffer = kmalloc(video->packet_buffer_size, GFP_KERNEL);
+	
+	if(!video->packet_buffer) {
+		printk(KERN_ERR "dv1394: Cannot allocate packet buffers");
+		retval = -ENOMEM;
+		goto err_user_buf;
+	}
+
+	/* map the packet buffer into the IOMMU */
+	video->packet_buffer_dma = pci_map_single(video->ohci->dev,
+						  video->packet_buffer,
+						  video->packet_buffer_size,
+						  PCI_DMA_FROMDEVICE);
+	if(!video->packet_buffer_dma) {
+		printk(KERN_ERR "dv1394: Cannot map packet buffer to IOMMU");
+		kfree(video->packet_buffer);
+		video->packet_buffer = NULL;
+		retval = -ENOMEM;
+		goto err_user_buf;
+	}
+
+	debug_printk("dv1394: Allocated %d packet buffers for receive, total %lu bytes\n", 
+		     MAX_PACKET_BUFFER, video->packet_buffer_size);
+
+
+	/* set up register offsets for IT context */
+	/* IT DMA context registers are spaced 16 bytes apart */
+	video->ohci_IsoXmitContextControlSet = OHCI1394_IsoXmitContextControlSet+16*video->ohci_it_ctx;
+	video->ohci_IsoXmitContextControlClear = OHCI1394_IsoXmitContextControlClear+16*video->ohci_it_ctx;
+	video->ohci_IsoXmitCommandPtr = OHCI1394_IsoXmitCommandPtr+16*video->ohci_it_ctx;
+
+	/* enable interrupts for IT context */
+	reg_write(video->ohci, OHCI1394_IsoXmitIntMaskSet, (1 << video->ohci_it_ctx));
+	debug_printk("dv1394: interrupts enabled for IT context %d\n", video->ohci_it_ctx);
+
+	/* set up register offsets for IR context */
+	/* IR DMA context registers are spaced 32 bytes apart */
+	video->ohci_IsoRcvContextControlSet = OHCI1394_IsoRcvContextControlSet+32*video->ohci_ir_ctx;
+	video->ohci_IsoRcvContextControlClear = OHCI1394_IsoRcvContextControlClear+32*video->ohci_ir_ctx;
+	video->ohci_IsoRcvCommandPtr = OHCI1394_IsoRcvCommandPtr+32*video->ohci_ir_ctx;
+	video->ohci_IsoRcvContextMatch = OHCI1394_IsoRcvContextMatch+32*video->ohci_ir_ctx;
+
+	/* enable interrupts for IR context */
+	reg_write(video->ohci, OHCI1394_IsoRecvIntMaskSet, (1 << video->ohci_ir_ctx) );
+	debug_printk("dv1394: interrupts enabled for IR context %d\n", video->ohci_ir_ctx);
+	
+	return 0;
+
+ err_user_buf:
+	if(video->user_buf) {
+		if(video->user_dma.sglist) {
+			if(video->user_dma.n_dma_pages > 0) {
+				/* unmap it from the IOMMU */
+				pci_unmap_sg(video->ohci->dev,
+					     video->user_dma.sglist,
+					     video->user_dma.n_pages,
+					     PCI_DMA_TODEVICE);
+				video->user_dma.n_dma_pages = 0;
+			}
+			kfree(video->user_dma.sglist);
+			video->user_dma.sglist = NULL;
+			video->user_dma.n_pages = 0;
+		}
+		rvfree(video->user_buf, video->user_buf_size);
+		video->user_buf = NULL;
+		video->user_buf_size = 0;
+	}
+		
+ err_frames:
+	for(i = 0; i < DV1394_MAX_FRAMES; i++) {
+		if(video->frames[i])
+			frame_delete(video->frames[i]);
+	}	
+	video->n_frames = 0;
+
+ err_ctx:
+	if(video->ohci_it_ctx != -1) {
+		clear_bit(video->ohci_it_ctx, &video->ohci->it_ctx_usage);
+		video->ohci_it_ctx = -1;
+	}
+	if(video->ohci_ir_ctx != -1) {
+		clear_bit(video->ohci_ir_ctx, &video->ohci->ir_ctx_usage);
+		video->ohci_ir_ctx = -1;
+	}
+	
+	spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
+	video->ohci->ISO_channel_usage &= ~chan_mask;
+	spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
+ err:
+	return retval;
+}
+
+/* if the user doesn't bother to call ioctl(INIT) before starting
+   mmap() or read()/write(), just give him some default values */
+
+static int do_dv1394_init_default(struct video_card *video)
+{
+	struct dv1394_init init;
+
+	init.api_version = DV1394_API_VERSION;
+	init.n_frames = 2;
+	/* the following are now set via proc_fs or devfs */
+	init.channel = video->channel;
+	init.format = video->pal_or_ntsc;
+	init.cip_n = video->cip_n; 
+	init.cip_d = video->cip_d;
+	init.syt_offset = video->syt_offset;
+
+	return do_dv1394_init(video, &init);
+}
+
+/* do NOT call from interrupt context */
+static void stop_dma(struct video_card *video)
+{
+	unsigned long flags;
+	int i;
+	
+	/* no interrupts */
+	spin_lock_irqsave(&video->spinlock, flags);
+
+	/* stop DMA if in progress */
+	if( (video->active_frame != -1) ||
+	    (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
+	    (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) &  (1 << 10)) ) {
+
+		/* clear the .run bits */
+		reg_write(video->ohci, video->ohci_IsoXmitContextControlClear, (1 << 15));
+		reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, (1 << 15));
+		flush_pci_write(video->ohci);
+		
+		video->active_frame = -1;
+		video->first_run = 1;
+
+		
+		/* wait until DMA really stops */
+		i = 0;
+		while(i < 1000) {
+				
+			/* wait 0.1 millisecond */
+			udelay(100); 
+			
+			if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
+			    (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear)  & (1 << 10)) ) {
+				/* still active */
+				mb();
+			} else {
+				debug_printk("dv1394: stop_dma: DMA stopped safely after %d ms\n", i/10);
+				break;
+			}
+				
+			i++;
+		}
+			
+		if(i == 1000) {
+			printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10);
+		}
+	}
+
+	spin_unlock_irqrestore(&video->spinlock, flags);
+}
+
+
+
+static int do_dv1394_shutdown(struct video_card *video, int free_user_buf)
+{
+	int i;
+
+	debug_printk("dv1394: shutdown...\n");
+
+	/* stop DMA if in progress */
+	stop_dma(video);
+	
+	/* release the ISO channel */
+	if(video->channel != -1) {
+		u64 chan_mask;
+		unsigned long flags;
+		
+		chan_mask = (u64)1 << video->channel;
+		
+		spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
+		video->ohci->ISO_channel_usage &= ~(chan_mask);
+		spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
+		
+		video->channel = -1;
+	}
+
+	/* release the DMA contexts */
+	if(video->ohci_it_ctx != -1) {
+		video->ohci_IsoXmitContextControlSet = 0;
+		video->ohci_IsoXmitContextControlClear = 0;
+		video->ohci_IsoXmitCommandPtr = 0;
+
+		/* disable interrupts for IT context */
+		reg_write(video->ohci, OHCI1394_IsoXmitIntMaskClear, (1 << video->ohci_it_ctx));
+		
+		clear_bit(video->ohci_it_ctx, &video->ohci->it_ctx_usage);
+		debug_printk("dv1394: IT context %d released\n", video->ohci_it_ctx);
+		video->ohci_it_ctx = -1;
+	}
+
+	if(video->ohci_ir_ctx != -1) {
+		video->ohci_IsoRcvContextControlSet = 0;
+		video->ohci_IsoRcvContextControlClear = 0;
+		video->ohci_IsoRcvCommandPtr = 0;
+		video->ohci_IsoRcvContextMatch = 0;
+
+		/* disable interrupts for IR context */
+		reg_write(video->ohci, OHCI1394_IsoRecvIntMaskClear, (1 << video->ohci_ir_ctx));
+
+		clear_bit(video->ohci_ir_ctx, &video->ohci->ir_ctx_usage);
+		debug_printk("dv1394: IR context %d released\n", video->ohci_ir_ctx);
+		video->ohci_ir_ctx = -1;
+	}
+
+	/* free the frame structs */
+	for(i = 0; i < DV1394_MAX_FRAMES; i++) {
+		if(video->frames[i])
+			frame_delete(video->frames[i]);
+		video->frames[i] = NULL;
+	}
+
+	video->n_frames = 0;
+		
+	/* we can't free the DMA buffer unless it is guaranteed that
+	   no more user-space mappings exist */
+	
+	if(free_user_buf && video->user_buf) {
+		if(video->user_dma.sglist) {
+			if(video->user_dma.n_dma_pages > 0) {
+				/* unmap it from the IOMMU */
+				pci_unmap_sg(video->ohci->dev,
+					     video->user_dma.sglist,
+					     video->user_dma.n_pages,
+					     PCI_DMA_TODEVICE);
+				video->user_dma.n_dma_pages = 0;
+			}
+			kfree(video->user_dma.sglist);
+			video->user_dma.sglist = NULL;
+			video->user_dma.n_pages = 0;
+		}
+		rvfree(video->user_buf, video->user_buf_size);
+		video->user_buf = NULL;
+		video->user_buf_size = 0;
+	}
+	
+	if (video->packet_buffer) {
+		pci_unmap_single(video->ohci->dev,
+				 video->packet_buffer_dma,
+				 video->packet_buffer_size,
+				 PCI_DMA_FROMDEVICE);
+		kfree(video->packet_buffer);
+		video->packet_buffer = NULL;
+		video->packet_buffer_size = 0;
+	}
+
+	debug_printk("dv1394: shutdown complete\n");
+
+	return 0;
+}
+
+
+
+/*
+       **********************************
+       *** MMAP() THEORY OF OPERATION ***
+       **********************************
+
+        The ringbuffer cannot be re-allocated or freed while
+        a user program maintains a mapping of it. (note that a mapping
+	can persist even after the device fd is closed!)
+
+	So, only let the user process allocate the DMA buffer once.
+	To resize or deallocate it, you must close the device file
+	and open it again.
+
+	Previously Dan M. hacked out a scheme that allowed the DMA
+	buffer to change by forcefully unmapping it from the user's
+	address space. It was prone to error because it's very hard to
+	track all the places the buffer could have been mapped (we
+	would have had to walk the vma list of every process in the
+	system to be sure we found all the mappings!). Instead, we
+	force the user to choose one buffer size and stick with
+	it. This small sacrifice is worth the huge reduction in
+	error-prone code in dv1394.
+
+	Note: dv1394_mmap does no page table manipulation. The page
+	table entries are created by the dv1394_nopage() handler as
+	page faults are taken by the user.
+*/
+
+static struct page * dv1394_nopage(struct vm_area_struct * area, unsigned long address, int write_access)
+{
+	unsigned long offset;
+	unsigned long kernel_virt_addr;
+	struct page *ret = NOPAGE_SIGBUS;
+
+	struct video_card *video = (struct video_card*) area->vm_private_data;
+	
+	/* guard against process-context operations and the interrupt */
+	/* (by definition page faults are taken in interrupt context) */
+	spin_lock(&video->spinlock);
+
+	if(!video->user_buf)
+		goto out;
+
+	if( (address < (unsigned long) area->vm_start) ||
+	    (address > (unsigned long) area->vm_start + video->user_buf_size) )
+		goto out;
+
+	offset = address - area->vm_start;
+	kernel_virt_addr = (unsigned long) video->user_buf + offset;
+	ret = vmalloc_to_page((void *)kernel_virt_addr);
+	get_page(ret);
+
+ out:
+	spin_unlock(&video->spinlock);
+	return ret;
+}
+
+static struct vm_operations_struct dv1394_vm_ops = {
+	nopage: dv1394_nopage
+};
+
+/*
+  dv1394_mmap does no page table manipulation. The page table entries
+  are created by the dv1394_nopage() handler as page faults are taken
+  by the user.
+*/
+
+int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct video_card *video = file_to_video_card(file);
+	unsigned long size;
+	int res = -EINVAL;
+
+	/* serialize mmap */
+	down(&video->sem);
+
+	if( ! video_card_initialized(video) ) {
+		res = do_dv1394_init_default(video);
+		if(res)
+			goto err;
+	}
+
+	/* region must be page-aligned */
+	if(vma->vm_pgoff != 0)
+		goto err;
+	
+	/* check the size the user is trying to map */
+	size = vma->vm_end - vma->vm_start;
+	if(size > video->user_buf_size)
+		goto err;
+
+	/* 
+	   we don't actually mess with the page tables here.
+	   (nopage() takes care of that from the page fault handler)
+	   Just set up the vma->vm_ops.
+	*/
+
+        vma->vm_ops = &dv1394_vm_ops;
+	vma->vm_private_data = video;
+	vma->vm_file = file;
+
+	/* don't try to swap this out =) */
+	vma->vm_flags |= VM_RESERVED;
+
+	up(&video->sem);
+	return 0;
+ err:
+	up(&video->sem);
+	return res;
+}
+
+
+/*** DEVICE FILE INTERFACE *************************************************/
+
+/* no need to serialize, multiple threads OK */
+static unsigned int dv1394_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct video_card *video = file_to_video_card(file);
+	unsigned int mask = 0;
+	unsigned long flags;
+
+	poll_wait(file, &video->waitq, wait);
+
+	spin_lock_irqsave(&video->spinlock, flags);
+	if( video->n_frames == 0 ) {
+
+	} else if( video->active_frame == -1 ) {
+		/* nothing going on */
+		mask |= POLLOUT;
+	} else {
+		/* any clear/ready buffers? */
+		if(video->n_clear_frames >0)
+			mask |= POLLOUT | POLLIN;
+	}
+	spin_unlock_irqrestore(&video->spinlock, flags);
+
+	return mask;
+}
+
+static int dv1394_fasync(int fd, struct file *file, int on)
+{
+	/* I just copied this code verbatim from Alan Cox's mouse driver example
+	   (linux/Documentation/DocBook/) */
+	
+	struct video_card *video = file_to_video_card(file);
+	
+	int retval = fasync_helper(fd, file, on, &video->fasync);
+	 
+	if (retval < 0)
+		return retval;
+        return 0;
+}
+
+static ssize_t dv1394_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+	struct video_card *video = file_to_video_card(file);
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t ret;
+	size_t cnt;
+	unsigned long flags;
+	int target_frame;
+
+	/* serialize this to prevent multi-threaded mayhem */
+	if(file->f_flags & O_NONBLOCK) {
+		if(down_trylock(&video->sem))
+			return -EAGAIN;
+	} else {
+		if(down_interruptible(&video->sem))
+			return -ERESTARTSYS;
+	}
+
+	if( !video_card_initialized(video) ) {
+		ret = do_dv1394_init_default(video);
+		if(ret) {
+			up(&video->sem);
+			return ret;
+		}
+	}
+
+	ret = 0;
+	add_wait_queue(&video->waitq, &wait);
+	
+	while(count > 0) {
+
+		/* must set TASK_INTERRUPTIBLE *before* checking for free
+		   buffers; otherwise we could miss a wakeup if the interrupt
+		   fires between the check and the schedule() */
+		
+		set_current_state(TASK_INTERRUPTIBLE);
+		
+		spin_lock_irqsave(&video->spinlock, flags);
+		
+		target_frame = video->first_clear_frame;
+		
+		spin_unlock_irqrestore(&video->spinlock, flags);
+
+		if(video->frames[target_frame]->state == FRAME_CLEAR) {
+
+			/* how much room is left in the target frame buffer */
+			cnt = video->frame_size - (video->write_off - target_frame * video->frame_size);
+
+		} else {
+			/* buffer is already used */
+			cnt = 0;
+		}
+
+		if(cnt > count)
+			cnt = count;
+
+		if (cnt <= 0) { 
+			/* no room left, gotta wait */
+			if(file->f_flags & O_NONBLOCK) {
+				if (!ret)
+					ret = -EAGAIN;
+				break;
+			}
+			if (signal_pending(current)) {
+				if (!ret)
+					ret = -ERESTARTSYS;
+				break;
+			}
+
+			schedule();
+			
+			continue; /* start over from 'while(count > 0)...' */
+		}
+
+		if(copy_from_user(video->user_buf + video->write_off, buffer, cnt)) {
+			if(!ret)
+				ret = -EFAULT;
+			break;
+		}
+
+		video->write_off = (video->write_off + cnt) % (video->n_frames * video->frame_size);
+
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+
+		if(video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames))
+				frame_prepare(video, target_frame);
+	}
+	
+	remove_wait_queue(&video->waitq, &wait);
+	set_current_state(TASK_RUNNING);
+	up(&video->sem);
+	return ret;
+}
+
+
+static ssize_t dv1394_read(struct file *file,  char *buffer, size_t count, loff_t *ppos)
+{
+	struct video_card *video = file_to_video_card(file);
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t ret;
+	size_t cnt;
+	unsigned long flags;
+	int target_frame;
+
+	/* serialize this to prevent multi-threaded mayhem */
+	if(file->f_flags & O_NONBLOCK) {
+		if(down_trylock(&video->sem))
+			return -EAGAIN;
+	} else {
+		if(down_interruptible(&video->sem))
+			return -ERESTARTSYS;
+	}
+
+	if( !video_card_initialized(video) ) {
+		ret = do_dv1394_init_default(video);
+		if(ret) {
+			up(&video->sem);
+			return ret;
+		}
+		receive_packets(video, video->frames[video->first_clear_frame]);
+	}
+
+	ret = 0;
+	add_wait_queue(&video->waitq, &wait);
+
+	while(count > 0) {
+
+		/* must set TASK_INTERRUPTIBLE *before* checking for free
+		   buffers; otherwise we could miss a wakeup if the interrupt
+		   fires between the check and the schedule() */
+		
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		spin_lock_irqsave(&video->spinlock, flags);
+
+		target_frame = video->first_clear_frame;
+
+		spin_unlock_irqrestore(&video->spinlock, flags);
+
+		if(target_frame >= 0 &&
+			video->n_clear_frames > 0 &&
+			video->frames[target_frame]->state == FRAME_CLEAR) {
+
+			/* how much room is left in the target frame buffer */
+			cnt = video->frame_size - (video->write_off - target_frame * video->frame_size);
+
+		} else {
+			/* buffer is already used */
+			cnt = 0;
+		}
+
+		if(cnt > count)
+			cnt = count;
+
+		if (cnt <= 0) { 
+			/* no room left, gotta wait */
+			if(file->f_flags & O_NONBLOCK) {
+				if (!ret)
+					ret = -EAGAIN;
+				break;
+			}
+			if (signal_pending(current)) {
+				if (!ret)
+					ret = -ERESTARTSYS;
+				break;
+			}
+
+			schedule();
+			
+			continue; /* start over from 'while(count > 0)...' */
+		}
+
+		if(copy_to_user(buffer, video->user_buf + video->write_off, cnt)) {
+				if(!ret)
+					ret = -EFAULT;
+				break;
+		}
+
+		video->write_off = (video->write_off + cnt) % (video->n_frames * video->frame_size);
+
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+
+		if(video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) {
+			spin_lock_irqsave(&video->spinlock, flags);
+			video->n_clear_frames--;
+			video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
+			spin_unlock_irqrestore(&video->spinlock, flags);
+		}
+	}
+	
+	remove_wait_queue(&video->waitq, &wait);
+	set_current_state(TASK_RUNNING);
+	up(&video->sem);
+	return ret;
+}
+
+
+/*** DEVICE IOCTL INTERFACE ************************************************/
+
+/* I *think* the VFS serializes ioctl() for us, so we don't have to worry
+   about situations like having two threads in here at once... */
+
+static int dv1394_ioctl(struct inode *inode, struct file *file,
+			   unsigned int cmd, unsigned long arg)
+{
+	struct video_card *video = file_to_video_card(file);
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	DECLARE_WAITQUEUE(wait, current);
+
+	/* serialize this to prevent multi-threaded mayhem */
+	if(file->f_flags & O_NONBLOCK) {
+		if(down_trylock(&video->sem))
+			return -EAGAIN;
+	} else {
+		if(down_interruptible(&video->sem))
+			return -ERESTARTSYS;
+	}
+
+	switch(cmd)
+	{
+	case DV1394_SUBMIT_FRAMES: {
+		unsigned int n_submit;
+
+		if( !video_card_initialized(video) ) {
+			ret = do_dv1394_init_default(video);
+			if(ret)
+				goto out;
+		}
+
+		n_submit = (unsigned int) arg;
+
+		if(n_submit > video->n_frames) {
+			ret = -EINVAL;
+			goto out;
+		}
+			
+		while(n_submit > 0) {
+
+			add_wait_queue(&video->waitq, &wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+				
+			spin_lock_irqsave(&video->spinlock, flags);
+
+			/* wait until video->first_clear_frame is really CLEAR */
+			while(video->frames[video->first_clear_frame]->state != FRAME_CLEAR) {
+
+				spin_unlock_irqrestore(&video->spinlock, flags);
+					
+				if(signal_pending(current)) {
+					remove_wait_queue(&video->waitq, &wait);
+					set_current_state(TASK_RUNNING);
+					ret = -EINTR;
+					goto out;
+				}
+
+				schedule();
+				set_current_state(TASK_INTERRUPTIBLE);
+				
+				spin_lock_irqsave(&video->spinlock, flags);
+			}
+			spin_unlock_irqrestore(&video->spinlock, flags);
+
+			remove_wait_queue(&video->waitq, &wait);
+			set_current_state(TASK_RUNNING);
+				
+			frame_prepare(video, video->first_clear_frame);
+
+			n_submit--;
+		}
+
+		ret = 0;
+		break;
+	}
+
+	case DV1394_WAIT_FRAMES: {
+		unsigned int n_wait;
+
+		if( !video_card_initialized(video) ) {
+			ret = -EINVAL;
+			goto out;
+		}
+		
+		n_wait = (unsigned int) arg;
+
+		/* since we re-run the last frame on underflow, we will
+		   never actually have n_frames clear frames; at most only
+		   n_frames - 1 */
+
+		if(n_wait > (video->n_frames-1) ) {
+			ret = -EINVAL;
+			goto out;
+		}
+			
+		add_wait_queue(&video->waitq, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
+		
+		spin_lock_irqsave(&video->spinlock, flags);
+
+		while(video->n_clear_frames < n_wait) {
+			
+			spin_unlock_irqrestore(&video->spinlock, flags);
+					
+			if(signal_pending(current)) {
+				remove_wait_queue(&video->waitq, &wait);
+				set_current_state(TASK_RUNNING);
+				ret = -EINTR;
+				goto out;
+			}
+
+			schedule();
+			set_current_state(TASK_INTERRUPTIBLE);
+			
+			spin_lock_irqsave(&video->spinlock, flags);
+		}
+
+		spin_unlock_irqrestore(&video->spinlock, flags);
+
+		remove_wait_queue(&video->waitq, &wait);
+		set_current_state(TASK_RUNNING);
+		ret = 0;
+		break;
+	}
+
+	case DV1394_RECEIVE_FRAMES: {
+		unsigned int n_recv;
+
+		if( !video_card_initialized(video) ) {
+			ret = -EINVAL;
+			goto out;
+		}
+		
+		n_recv = (unsigned int) arg;
+
+		/* at least one frame must be active */
+		if(n_recv > (video->n_frames-1) ) {
+			ret = -EINVAL;
+			goto out;
+		}
+			
+		spin_lock_irqsave(&video->spinlock, flags);
+
+		/* release the clear frames */
+		video->n_clear_frames -= n_recv;
+
+		/* advance the clear frame cursor */
+		video->first_clear_frame = (video->first_clear_frame + n_recv) % video->n_frames;
+
+		/* reset dropped_frames */
+		video->dropped_frames = 0;
+			
+		spin_unlock_irqrestore(&video->spinlock, flags);
+
+		ret = 0;
+		break;
+	}
+
+	case DV1394_START_RECEIVE: {
+
+		if( !video_card_initialized(video) ) {
+			ret = do_dv1394_init_default(video);
+			if(ret)
+				goto out;
+		}
+	
+		receive_packets(video, video->frames[video->first_clear_frame]);
+
+		ret = 0;
+		break;
+	}
+
+	case DV1394_INIT: {
+		struct dv1394_init init;
+		if(arg == (unsigned long) NULL) {
+			ret = do_dv1394_init_default(video);
+		} else {
+			if(copy_from_user(&init, (void*)arg, sizeof(init))) {
+				ret = -EFAULT;
+				goto out;
+			}
+			ret = do_dv1394_init(video, &init);
+		}
+		break;
+	}
+
+	case DV1394_SHUTDOWN:
+		ret = do_dv1394_shutdown(video, 0);
+		break;
+
+
+        case DV1394_GET_STATUS: {
+		struct dv1394_status status;
+
+		if( !video_card_initialized(video) ) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		status.init.api_version = DV1394_API_VERSION;
+		status.init.channel = video->channel;
+		status.init.n_frames = video->n_frames;
+		status.init.format = video->pal_or_ntsc;
+		status.init.cip_n = video->cip_n;
+		status.init.cip_d = video->cip_d;
+		status.init.syt_offset = video->syt_offset;
+
+		status.first_clear_frame = video->first_clear_frame;
+
+		/* the rest of the fields need to be locked against the interrupt */
+		spin_lock_irqsave(&video->spinlock, flags);
+
+		status.active_frame = video->active_frame;
+		status.n_clear_frames = video->n_clear_frames;
+
+		status.dropped_frames = video->dropped_frames;
+
+		/* reset dropped_frames */
+		video->dropped_frames = 0;
+			
+		spin_unlock_irqrestore(&video->spinlock, flags);
+
+		if(copy_to_user((void*)arg, &status, sizeof(status))) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		ret = 0;
+		break;
+	}
+
+	default:
+		break;
+	}
+
+ out:
+	up(&video->sem);
+	return ret;
+}
+
+
+
+/*** DEVICE FILE INTERFACE CONTINUED ***************************************/
+
+static int dv1394_open(struct inode *inode, struct file *file)
+{
+	struct video_card *video = NULL;
+
+	/* if the device was opened through devfs, then file->private_data
+	   has already been set to video by devfs */
+	if(file->private_data) {
+		video = (struct video_card*) file->private_data;
+		
+	} else {
+		/* look up the card by ID */
+		
+		struct list_head *lh;
+		unsigned long flags;
+		
+		spin_lock_irqsave(&dv1394_cards_lock, flags);
+		if(!list_empty(&dv1394_cards)) {
+			struct video_card *p;
+			list_for_each(lh, &dv1394_cards) {
+				p = list_entry(lh, struct video_card, list);
+				if((p->id >> 2) == ieee1394_file_to_instance(file)) {
+					video = p;
+					break;
+				}
+			}
+		}
+		spin_unlock_irqrestore(&dv1394_cards_lock, flags);
+
+		if(!video) {
+			debug_printk("dv1394: OHCI card %d not found", ieee1394_file_to_instance(file));
+			return -ENODEV;
+		}
+		
+		file->private_data = (void*) video;
+	}
+	
+#ifndef DV1394_ALLOW_MORE_THAN_ONE_OPEN
+
+	if( test_and_set_bit(0, &video->open) ) {
+		/* video is already open by someone else */
+		return -EBUSY;
+ 	}
+
+#endif
+
+	return 0;
+}
+
+
+static int dv1394_release(struct inode *inode, struct file *file)
+{
+	struct video_card *video = file_to_video_card(file);
+
+	/* OK to free the DMA buffer, no more mappings can exist */
+	do_dv1394_shutdown(video, 1);
+
+	/* clean up async I/O users */
+	dv1394_fasync(-1, file, 0);
+	
+	/* give someone else a turn */
+	clear_bit(0, &video->open);
+
+	return 0;
+}
+
+
+/*** PROC_FS INTERFACE ******************************************************/
+#ifdef CONFIG_PROC_FS
+static LIST_HEAD(dv1394_procfs);
+struct dv1394_procfs_entry {
+	struct list_head list;
+    struct proc_dir_entry *procfs;
+	char name[32];
+	struct dv1394_procfs_entry *parent;
+};
+static spinlock_t dv1394_procfs_lock = SPIN_LOCK_UNLOCKED;
+
+static int dv1394_procfs_read( char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	struct video_card *video = (struct video_card*) data;
+
+	snprintf( page, count, 
+		"\
+format=%s\n\
+channel=%d\n\
+cip_n=%lu\n\
+cip_d=%lu\n\
+syt_offset=%u\n",
+		(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
+		video->channel,
+		video->cip_n, video->cip_d, video->syt_offset );
+	return strlen(page);
+}
+
+/* lifted from the stallion.c driver */
+#undef  TOLOWER
+#define TOLOWER(x)      ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
+static unsigned long atol(char *str)
+{
+	unsigned long   val;
+	int             base, c;
+	char            *sp;
+
+	val = 0;
+	sp = str;
+	if ((*sp == '0') && (*(sp+1) == 'x')) {
+		base = 16;
+		sp += 2;
+	} else if (*sp == '0') {
+		base = 8;
+		sp++;
+	} else {
+		base = 10;
+	}
+
+	for (; (*sp != 0); sp++) {
+		c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
+		if ((c < 0) || (c >= base)) {
+			printk(KERN_ERR "dv1394: atol() invalid argument %s\n", str);
+			val = 0;
+			break;
+		}
+		val = (val * base) + c;
+	}
+	return(val);
+}
+
+static int dv1394_procfs_write( struct file *file,
+			const char *buffer, unsigned long count, void *data)
+{
+	int len = 0;
+	char new_value[64];
+	char *pos;
+	struct video_card *video = (struct video_card*) data;
+	
+	if (count > 64)
+		len = 64;
+	else
+		len = count;
+				
+	if (copy_from_user( new_value, buffer, len))
+		return -EFAULT;
+	
+	pos = strchr(new_value, '=');
+	if (pos != NULL) {
+		int val_len = len - (pos-new_value) - 1;
+		char buf[64];
+		memset(buf, 0, 64);
+		strncpy(buf, pos+1, val_len);
+		if (buf[val_len-1] == '\n') buf[val_len-1] = 0;
+		
+		if (strnicmp( new_value, "format", (pos-new_value)) == 0) {
+			if (strnicmp( buf, "NTSC", val_len) == 0)
+				video->pal_or_ntsc = DV1394_NTSC;
+			else if (strnicmp( buf, "PAL", val_len) == 0)
+				video->pal_or_ntsc = DV1394_PAL;
+				
+		} else if (strnicmp( new_value, "cip_n", (pos-new_value)) == 0) {
+			video->cip_n = atol(buf);
+		} else if (strnicmp( new_value, "cip_d", (pos-new_value)) == 0) {
+			video->cip_d = atol(buf);
+		} else if (strnicmp( new_value, "syt_offset", (pos-new_value)) == 0) {
+			video->syt_offset = atol(buf);
+		} else if (strnicmp( new_value, "channel", (pos-new_value)) == 0) {
+			video->channel = atol(buf);
+		}
+	}
+	
+	return len;
+}
+
+struct dv1394_procfs_entry *
+dv1394_procfs_find( char *name)
+{
+	struct list_head *lh;
+	struct dv1394_procfs_entry *p;
+		
+	spin_lock( &dv1394_procfs_lock);
+	if(!list_empty(&dv1394_procfs)) {
+		list_for_each(lh, &dv1394_procfs) {
+			p = list_entry(lh, struct dv1394_procfs_entry, list);
+			if(!strncmp(p->name, name, sizeof(p->name))) {
+				spin_unlock( &dv1394_procfs_lock);
+				return p;
+			}
+		}
+	}
+	spin_unlock( &dv1394_procfs_lock);
+	return NULL;
+}
+
+static int dv1394_procfs_add_entry(struct video_card *video)
+{
+	char buf[32];
+	struct dv1394_procfs_entry *p;
+	struct dv1394_procfs_entry *parent;
+
+	p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL);
+	if(!p) {
+		printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n");
+		goto err;
+	}
+	memset(p, 0, sizeof(struct dv1394_procfs_entry));
+	
+	snprintf(buf, sizeof(buf), "dv/host%d/%s", (video->id>>2),
+						(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"));
+		
+	parent = dv1394_procfs_find(buf);
+	if (parent == NULL) {
+		printk(KERN_ERR "dv1394: unable to locate parent procfs of %s\n", buf);
+		goto err_free;
+	}
+	
+	p->procfs = create_proc_entry( 
+						(video->mode == MODE_RECEIVE ? "in" : "out"),
+						0666, parent->procfs);
+
+	if (p->procfs == NULL) {
+		printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/%s/%s\n",
+			parent->name,
+			(video->mode == MODE_RECEIVE ? "in" : "out"));
+		goto err_free;
+	}
+	
+	p->procfs->owner = THIS_MODULE;
+	p->procfs->data = video;
+	p->procfs->read_proc = dv1394_procfs_read;
+	p->procfs->write_proc = dv1394_procfs_write;
+
+	spin_lock( &dv1394_procfs_lock);
+	INIT_LIST_HEAD(&p->list);
+	list_add_tail(&p->list, &dv1394_procfs);
+	spin_unlock( &dv1394_procfs_lock);
+	
+	return 0;
+	
+ err_free:
+	kfree(p);
+ err:
+	return -ENOMEM;
+}
+
+static int
+dv1394_procfs_add_dir( char *name,
+					struct dv1394_procfs_entry *parent, 
+					struct dv1394_procfs_entry **out)
+{
+	struct dv1394_procfs_entry *p;
+
+	p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL);
+	if(!p) {
+		printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n");
+		goto err;
+	}
+	memset(p, 0, sizeof(struct dv1394_procfs_entry));
+	
+	if (parent == NULL) {
+		snprintf(p->name, sizeof(p->name), "%s", name);
+		p->procfs = proc_mkdir( name, ieee1394_procfs_entry);
+	} else {
+		snprintf(p->name, sizeof(p->name), "%s/%s", parent->name, name);
+		p->procfs = proc_mkdir( name, parent->procfs);
+	}
+	if (p->procfs == NULL) {
+		printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/%s\n", p->name);
+		goto err_free;
+	}
+
+	p->procfs->owner = THIS_MODULE;
+	p->parent = parent;
+	if (out != NULL) *out = p;
+
+	spin_lock( &dv1394_procfs_lock);
+	INIT_LIST_HEAD(&p->list);
+	list_add_tail(&p->list, &dv1394_procfs);
+	spin_unlock( &dv1394_procfs_lock);
+
+	return 0;
+	
+ err_free:
+	kfree(p);
+ err:
+	return -ENOMEM;
+}
+
+void dv1394_procfs_del( char *name)
+{
+	struct dv1394_procfs_entry *p = dv1394_procfs_find(name);
+	if (p != NULL) {
+		if (p->parent == NULL)
+			remove_proc_entry(p->name, ieee1394_procfs_entry);
+		else
+			remove_proc_entry(p->name, p->parent->procfs);
+		
+		spin_lock( &dv1394_procfs_lock);
+		list_del(&p->list);
+		spin_unlock( &dv1394_procfs_lock);
+		kfree(p);
+	}
+}
+#endif /* CONFIG_PROC_FS */
+
+/*** DEVICE DRIVER HANDLERS ************************************************/
+
+static void irq_handler(int card, quadlet_t isoRecvIntEvent, 
+			quadlet_t isoXmitIntEvent, void *data)
+{
+	int wake = 0;
+	struct video_card *video = (struct video_card*) data;
+
+	irq_printk("INTERRUPT! Video = %08lx Iso event Recv: %08x Xmit: %08x\n",
+		   (unsigned long) video, isoRecvIntEvent, isoXmitIntEvent);
+	irq_printk("ContextControl = %08x, CommandPtr = %08x\n", 
+	       reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
+	       reg_read(video->ohci, video->ohci_IsoXmitCommandPtr)
+	       );
+
+	
+	if( (video->ohci_it_ctx != -1) &&
+	    (isoXmitIntEvent & (1 << video->ohci_it_ctx)) &&
+	    (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) {
+
+		struct frame *f;
+		unsigned int frame, i;
+
+		spin_lock(&video->spinlock);
+		if(video->active_frame == -1)
+			frame = 0;
+		else
+			frame = video->active_frame;
+
+		/* check all the DMA-able frames */
+		for(i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) {
+
+			irq_printk("IRQ checking frame %d...", frame);
+			f = video->frames[frame];
+			if(f->state != FRAME_READY) {
+				irq_printk("clear, skipping\n");
+				/* we don't own this frame */
+				continue;
+			}
+
+			irq_printk("DMA\n");
+
+			/* check the frame begin semaphore to see if we can free the previous frame */
+			if( *(f->frame_begin_timestamp) ) {
+				int prev_frame;
+				struct frame *prev_f;
+
+				
+
+				/* don't reset, need this later *(f->frame_begin_timestamp) = 0; */
+				irq_printk("  BEGIN\n");
+
+				prev_frame = frame - 1;
+				if(prev_frame == -1)
+					prev_frame += video->n_frames;
+				prev_f = video->frames[prev_frame];
+				
+				/* make sure we can actually garbage collect
+				   this frame */
+				if( (prev_f->state == FRAME_READY) &&
+				    prev_f->done && (!f->done) ) 
+				{
+					frame_reset(prev_f);
+					video->n_clear_frames++;
+					wake = 1;
+					video->active_frame = frame;
+
+					irq_printk("  BEGIN - freeing previous frame %d, new active frame is %d\n", prev_frame, frame);
+				} else {
+					irq_printk("  BEGIN - can't free yet\n");
+				}
+
+				f->done = 1;
+			}
+
+		     
+			/* see if we need to set the timestamp for the next frame */
+			if( *(f->mid_frame_timestamp) ) {
+				struct frame *next_frame;
+				u32 ts_cyc, ts_off;
+
+				*(f->mid_frame_timestamp) = 0;
+
+				irq_printk("  MIDDLE - first packet was sent at cycle %4u (%2u), assigned timestamp was (%2u) %4u\n",
+				       *(f->frame_begin_timestamp) & 0x1FFF, *(f->frame_begin_timestamp) & 0xF,
+				       f->assigned_timestamp >> 12,       f->assigned_timestamp & 0xFFF);
+
+				/* prepare next frame and assign timestamp */
+				next_frame = video->frames[ (frame+1) % video->n_frames ];
+
+				if(next_frame->state == FRAME_READY) {
+					irq_printk("  MIDDLE - next frame is ready, good\n");
+				} else {
+					debug_printk("dv1394: Underflow! At least one frame has been dropped.\n");
+					next_frame = f;
+				}
+
+				/* set the timestamp to the timestamp of the last frame sent,
+				   plus the length of the last frame sent, plus the syt latency */
+				ts_cyc = *(f->frame_begin_timestamp) & 0xF;
+				/* advance one frame, plus syt latency (typically 2-3) */
+				ts_cyc += f->n_packets + video->syt_offset ; 
+
+				ts_off = 0; 
+
+				ts_cyc += ts_off/3072;
+				ts_off %= 3072;
+
+				next_frame->assigned_timestamp = ((ts_cyc&0xF) << 12) + ts_off;
+				if(next_frame->cip_syt1) {
+					next_frame->cip_syt1->b[6] = next_frame->assigned_timestamp >> 8;
+					next_frame->cip_syt1->b[7] = next_frame->assigned_timestamp & 0xFF;
+				}
+				if(next_frame->cip_syt2) {
+					next_frame->cip_syt2->b[6] = next_frame->assigned_timestamp >> 8;
+					next_frame->cip_syt2->b[7] = next_frame->assigned_timestamp & 0xFF;
+				}
+
+			}
+
+			/* see if the frame looped */
+			if( *(f->frame_end_timestamp) ) {
+
+				*(f->frame_end_timestamp) = 0;
+
+				debug_printk("  END - the frame looped at least once\n");
+
+				video->dropped_frames++;
+			}
+
+
+		
+		} /* for(each frame) */
+
+		spin_unlock(&video->spinlock);
+		
+	} /* end XMIT portion */
+
+	/***** RECEIVE INTERRUPT and DMA ACTIVE *****/
+
+	else if( (video->ohci_ir_ctx != -1) &&
+		 (isoRecvIntEvent & (1 << video->ohci_ir_ctx)) &&
+		 (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) { 
+
+		int sof=0; /* start-of-frame flag */
+		struct frame *f;
+
+		spin_lock(&video->spinlock);
+
+		irq_printk("received packet %02d, timestamp=%04x, length=%04x, sof=%02x%02x\n", video->current_packet,
+			   video->packet_buffer[video->current_packet].timestamp, video->packet_buffer[video->current_packet].data_length, 
+			   video->packet_buffer[video->current_packet].data[0], video->packet_buffer[video->current_packet].data[1]);
+		
+		f = video->frames[video->active_frame];
+
+		/* exclude empty packet */
+		if (video->packet_buffer[video->current_packet].data_length > 8) {
+		
+			/* check for start of frame */
+			sof = (video->packet_buffer[video->current_packet].data[0] == 0x1f &&
+				video->packet_buffer[video->current_packet].data[1] == 0x07);
+
+			if (!video->first_frame) {
+				if (sof) {
+					video->first_frame = 1;
+				}
+
+			} else if (sof) {
+				/* close current frame */
+				frame_reset(f);  /* f->state = STATE_CLEAR */
+				video->n_clear_frames++;
+				if (video->n_clear_frames > video->n_frames) {
+					video->n_clear_frames = video->n_frames;
+					video->dropped_frames++;
+				}
+				if (video->first_clear_frame == -1)
+					video->first_clear_frame = video->active_frame;
+
+				/* get the next frame */
+				video->active_frame = (video->active_frame + 1) % video->n_frames;
+				f = video->frames[video->active_frame];
+			
+				irq_printk("   frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n",
+					   video->active_frame, video->n_clear_frames, video->first_clear_frame);
+ 			}
+			if (video->first_frame) {
+				if (sof) {
+					/* open next frame */
+					f->state = FRAME_READY;
+				}
+				
+				/* copy to buffer */
+				if (f->n_packets > (video->frame_size / 480)) {
+					printk(KERN_ERR "frame buffer overflow during receive\n");
+				}
+
+				/* make sure we are seeing the latest changes to packet_buffer */
+				pci_dma_sync_single(video->ohci->dev,
+						    video->packet_buffer_dma,
+						    video->packet_buffer_size,
+						    PCI_DMA_FROMDEVICE);
+				
+				frame_put_packet( f, &video->packet_buffer[video->current_packet]);
+				
+			} /* first_frame */
+ 
+		} /* not empty packet */
+ 
+		/* advance packet_buffer cursor */
+		video->current_packet = (video->current_packet + 1) % MAX_PACKET_BUFFER;
+ 
+ 		spin_unlock(&video->spinlock);
+
+		wake = 1; /* why the hell not? */
+
+	} /* receive interrupt */
+
+	if(wake) {
+		
+		/* send SIGIO */
+		
+		if(isoRecvIntEvent & (1))
+			kill_fasync(&video->fasync, SIGIO, POLL_IN);
+		
+		if(isoXmitIntEvent & (1))
+			kill_fasync(&video->fasync, SIGIO, POLL_OUT);
+		
+		/* wake readers/writers/ioctl'ers */
+		wake_up_interruptible(&video->waitq);
+	}
+}
+
+static struct file_operations dv1394_fops=
+{
+	owner:		THIS_MODULE,
+	poll:           dv1394_poll,
+	ioctl:		dv1394_ioctl,
+	mmap:		dv1394_mmap,
+	open:		dv1394_open,
+	write:          dv1394_write,
+	read:           dv1394_read,
+	release:	dv1394_release,
+	fasync:         dv1394_fasync,
+};
+
+
+/*** DEVFS HELPERS *********************************************************/
+
+struct dv1394_devfs_entry *
+dv1394_devfs_find( char *name)
+{
+	struct list_head *lh;
+	struct dv1394_devfs_entry *p;
+
+	spin_lock( &dv1394_devfs_lock);
+	if(!list_empty(&dv1394_devfs)) {
+		list_for_each(lh, &dv1394_devfs) {
+			p = list_entry(lh, struct dv1394_devfs_entry, list);
+			if(!strncmp(p->name, name, sizeof(p->name))) {
+				spin_unlock( &dv1394_devfs_lock);
+				return p;
+			}
+		}
+	}
+	return NULL;
+}
+
+static int dv1394_devfs_add_entry(struct video_card *video)
+{
+	char buf[32];
+	struct dv1394_devfs_entry *p;
+	struct dv1394_devfs_entry *parent;
+
+	p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL);
+	if(!p) {
+		printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n");
+		goto err;
+	}
+	memset(p, 0, sizeof(struct dv1394_devfs_entry));
+	
+	snprintf(buf, sizeof(buf), "dv/host%d/%s", (video->id>>2),
+						(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"));
+		
+	parent = dv1394_devfs_find(buf);
+	if (parent == NULL) {
+		printk(KERN_ERR "dv1394: unable to locate parent devfs of %s\n", buf);
+		goto err_free;
+	}
+	
+	video->devfs_handle = devfs_register(
+						 parent->devfs,
+					     (video->mode == MODE_RECEIVE ? "in" : "out"),
+						 DEVFS_FL_NONE,
+					     IEEE1394_MAJOR,
+					     IEEE1394_MINOR_BLOCK_DV1394*16 + video->id,
+					     S_IFCHR | S_IRUGO | S_IWUGO,
+					     &dv1394_fops,
+					     (void*) video);
+	p->devfs = video->devfs_handle;
+
+	if (p->devfs == NULL) {
+		printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/%s/%s\n",
+			parent->name,
+			(video->mode == MODE_RECEIVE ? "in" : "out"));
+		goto err_free;
+	}
+	
+	spin_lock( &dv1394_devfs_lock);
+	INIT_LIST_HEAD(&p->list);
+	list_add_tail(&p->list, &dv1394_devfs);
+	spin_unlock( &dv1394_devfs_lock);
+	
+	return 0;
+	
+ err_free:
+	kfree(p);
+ err:
+	return -ENOMEM;
+}
+
+static int
+dv1394_devfs_add_dir( char *name,
+					struct dv1394_devfs_entry *parent, 
+					struct dv1394_devfs_entry **out)
+{
+	struct dv1394_devfs_entry *p;
+
+	p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL);
+	if(!p) {
+		printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n");
+		goto err;
+	}
+	memset(p, 0, sizeof(struct dv1394_devfs_entry));
+	
+	if (parent == NULL) {
+		snprintf(p->name, sizeof(p->name), "%s", name);
+		p->devfs = devfs_mk_dir(ieee1394_devfs_handle, name, NULL);
+	} else {
+		snprintf(p->name, sizeof(p->name), "%s/%s", parent->name, name);
+		p->devfs = devfs_mk_dir(parent->devfs, name, NULL);
+	}
+	if (p->devfs == NULL) {
+		printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/%s\n", p->name);
+		goto err_free;
+	}
+
+	p->parent = parent;
+	if (out != NULL) *out = p;
+
+	spin_lock( &dv1394_devfs_lock);
+	INIT_LIST_HEAD(&p->list);
+	list_add_tail(&p->list, &dv1394_devfs);
+	spin_unlock( &dv1394_devfs_lock);
+
+	return 0;
+	
+ err_free:
+	kfree(p);
+ err:
+	return -ENOMEM;
+}
+
+void dv1394_devfs_del( char *name)
+{
+	struct dv1394_devfs_entry *p = dv1394_devfs_find(name);
+	if (p != NULL) {
+		devfs_unregister(p->devfs);
+		
+		spin_lock( &dv1394_devfs_lock);
+		list_del(&p->list);
+		spin_unlock( &dv1394_devfs_lock);
+		kfree(p);
+	}
+}
+
+/*** IEEE1394 HPSB CALLBACKS ***********************************************/
+
+static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes mode)
+{
+	struct video_card *video;
+	unsigned long flags;
+	int i;
+
+	video = kmalloc(sizeof(struct video_card), GFP_KERNEL);
+	if(!video) {
+		printk(KERN_ERR "dv1394: cannot allocate video_card\n");
+		goto err;
+	}
+	
+	memset(video, 0, sizeof(struct video_card));
+	
+	if (ohci1394_hook_irq(ohci, irq_handler, (void*) video) != 0) {
+		printk(KERN_ERR "dv1394: ohci1394_hook_irq() failed\n");
+		goto err_free;
+	}
+
+	
+	video->ohci = ohci;
+	/* lower 2 bits of id indicate which of four "plugs"
+	   per host */
+	video->id = ohci->id << 2; 
+
+	video->ohci_it_ctx = -1;
+	video->ohci_ir_ctx = -1;
+
+	video->ohci_IsoXmitContextControlSet = 0;
+	video->ohci_IsoXmitContextControlClear = 0;
+	video->ohci_IsoXmitCommandPtr = 0;
+	
+	video->ohci_IsoRcvContextControlSet = 0;
+	video->ohci_IsoRcvContextControlClear = 0;
+	video->ohci_IsoRcvCommandPtr = 0;
+	video->ohci_IsoRcvContextMatch = 0;
+		
+	video->n_frames = 0; /* flag that video is not initialized */
+	video->channel = 63; /* default to broadcast channel */
+	video->active_frame = -1;
+	
+	/* initialize the following for proc_fs */
+	video->pal_or_ntsc = format;
+	video->cip_n = 0; /* 0 = use builtin default */
+	video->cip_d = 0;
+	video->syt_offset = 0;
+	video->mode = mode;
+
+#ifdef CONFIG_PROC_FS
+	if ( dv1394_procfs_add_entry(video) < 0 )
+		goto err_free;
+#endif
+
+	for(i = 0; i < DV1394_MAX_FRAMES; i++)
+		video->frames[i] = NULL;
+
+	video->user_buf = NULL;
+	video->user_buf_size = 0;
+
+	clear_bit(0, &video->open);
+	spin_lock_init(&video->spinlock);
+	init_MUTEX(&video->sem);
+	init_waitqueue_head(&video->waitq);
+	video->fasync = NULL;
+
+	spin_lock_irqsave(&dv1394_cards_lock, flags);
+	INIT_LIST_HEAD(&video->list);
+	list_add_tail(&video->list, &dv1394_cards);
+	spin_unlock_irqrestore(&dv1394_cards_lock, flags);
+	
+	if (format == DV1394_NTSC)
+		video->id |= mode;
+	else video->id |= 2 + mode;
+	
+	if (dv1394_devfs_add_entry(video) < 0)
+			goto err_free;
+
+	debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id);
+	
+	return 0;
+
+ err_free:
+	kfree(video);
+ err:
+	return -1;
+}
+
+static void dv1394_un_init(struct video_card *video)
+{
+	char buf[32];
+	
+	/* obviously nobody has the driver open at this point */
+	do_dv1394_shutdown(video, 1);
+	ohci1394_unhook_irq(video->ohci, irq_handler, (void*) video);
+	snprintf(buf, sizeof(buf), "dv/host%d/%s/%s", (video->id >> 2),
+		(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
+		(video->mode == MODE_RECEIVE ? "in" : "out")
+		);
+	dv1394_devfs_del(buf);
+#ifdef CONFIG_PROC_FS
+	dv1394_procfs_del(buf);
+#endif
+	list_del(&video->list);
+	kfree(video);
+}
+
+	
+static void dv1394_remove_host (struct hpsb_host *host)
+{
+	struct ti_ohci *ohci;
+	struct video_card *video = NULL;
+	unsigned long flags;
+	struct list_head *lh;
+	char buf[32];
+	int	n;
+	
+	/* We only work with the OHCI-1394 driver */
+	if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
+		return;
+
+	ohci = (struct ti_ohci *)host->hostdata;
+
+
+	/* find the corresponding video_cards */
+	spin_lock_irqsave(&dv1394_cards_lock, flags);
+	if(!list_empty(&dv1394_cards)) {
+		list_for_each(lh, &dv1394_cards) {
+			video = list_entry(lh, struct video_card, list);
+			if((video->id >> 2) == ohci->id)
+				dv1394_un_init(video);
+		}
+	}
+	spin_unlock_irqrestore(&dv1394_cards_lock, flags);
+
+	n = (video->id >> 2);
+	snprintf(buf, sizeof(buf), "dv/host%d/NTSC", n);
+	dv1394_devfs_del(buf);
+	snprintf(buf, sizeof(buf), "dv/host%d/PAL", n);
+	dv1394_devfs_del(buf);
+	snprintf(buf, sizeof(buf), "dv/host%d", n);
+	dv1394_devfs_del(buf);
+
+#ifdef CONFIG_PROC_FS
+	snprintf(buf, sizeof(buf), "dv/host%d/NTSC", n);
+	dv1394_procfs_del(buf);
+	snprintf(buf, sizeof(buf), "dv/host%d/PAL", n);
+	dv1394_procfs_del(buf);
+	snprintf(buf, sizeof(buf), "dv/host%d", n);
+	dv1394_procfs_del(buf);
+#endif	
+}
+
+static void dv1394_add_host (struct hpsb_host *host)
+{
+	struct ti_ohci *ohci;
+	char buf[16];
+	struct dv1394_devfs_entry *devfs_entry;
+
+	/* We only work with the OHCI-1394 driver */
+	if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
+		return;
+
+	ohci = (struct ti_ohci *)host->hostdata;
+
+#ifdef CONFIG_PROC_FS
+{
+	struct dv1394_procfs_entry *p;
+	p = dv1394_procfs_find("dv");
+	if (p != NULL) {
+		snprintf(buf, sizeof(buf), "host%d", ohci->id);
+		dv1394_procfs_add_dir(buf, p, &p);
+		dv1394_procfs_add_dir("NTSC", p, NULL);
+		dv1394_procfs_add_dir("PAL", p, NULL);
+	}
+}
+#endif
+
+	devfs_entry = dv1394_devfs_find("dv");
+	if (devfs_entry != NULL) {
+		snprintf(buf, sizeof(buf), "host%d", ohci->id);
+		dv1394_devfs_add_dir(buf, devfs_entry, &devfs_entry);
+		dv1394_devfs_add_dir("NTSC", devfs_entry, NULL);
+		dv1394_devfs_add_dir("PAL", devfs_entry, NULL);
+	}
+	
+	dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
+	dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
+	dv1394_init(ohci, DV1394_PAL, MODE_RECEIVE);
+	dv1394_init(ohci, DV1394_PAL, MODE_TRANSMIT);
+}
+
+
+/* Bus reset handler. In the event of a bus reset, we may need to
+   re-start the DMA contexts - otherwise the user program would
+   end up waiting forever.
+*/
+
+static void dv1394_host_reset(struct hpsb_host *host)
+{
+	struct ti_ohci *ohci;
+	struct video_card *video = NULL;
+	unsigned long flags;
+	struct list_head *lh;
+	
+	/* We only work with the OHCI-1394 driver */
+	if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
+		return;
+
+	ohci = (struct ti_ohci *)host->hostdata;
+
+
+	/* find the corresponding video_cards */
+	spin_lock_irqsave(&dv1394_cards_lock, flags);
+	if(!list_empty(&dv1394_cards)) {
+		list_for_each(lh, &dv1394_cards) {
+			video = list_entry(lh, struct video_card, list);
+			if((video->id >> 2) == ohci->id)
+				break;
+		}
+	}
+	spin_unlock_irqrestore(&dv1394_cards_lock, flags);
+
+	if(!video)
+		return;
+
+	/* check IT context */
+	if(video->ohci_it_ctx != -1) {
+		u32 ctx;
+		
+		spin_lock_irqsave(&video->spinlock, flags);
+		
+		ctx = reg_read(video->ohci, video->ohci_IsoXmitContextControlSet);
+
+		/* if(RUN but not ACTIVE) */
+		if( (ctx & (1<<15)) &&
+		    !(ctx & (1<<10)) ) {
+
+			debug_printk("dv1394: IT context stopped due to bus reset; waking it up\n");
+
+			/* to be safe, assume a frame has been dropped. User-space programs
+			   should handle this condition like an underflow. */
+			video->dropped_frames++;
+			
+			/* for some reason you must clear, then re-set the RUN bit to restart DMA */
+			
+			/* clear RUN */
+			reg_write(video->ohci, video->ohci_IsoXmitContextControlClear, (1 << 15));
+			flush_pci_write(video->ohci);
+			
+			/* set RUN */
+			reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, (1 << 15));
+			flush_pci_write(video->ohci);
+			
+			/* set the WAKE bit (just in case; this isn't strictly necessary) */
+			reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, (1 << 12));
+			flush_pci_write(video->ohci);
+
+			irq_printk("dv1394: AFTER IT restart ctx 0x%08x ptr 0x%08x\n",
+				   reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
+				   reg_read(video->ohci, video->ohci_IsoXmitCommandPtr));
+		}
+
+		spin_unlock_irqrestore(&video->spinlock, flags);
+	}
+	
+	/* check IR context */
+	if(video->ohci_ir_ctx != -1) {
+		u32 ctx;
+		
+		spin_lock_irqsave(&video->spinlock, flags);
+		
+		ctx = reg_read(video->ohci, video->ohci_IsoRcvContextControlSet);
+
+		/* if(RUN but not ACTIVE) */
+		if( (ctx & (1<<15)) &&
+		    !(ctx & (1<<10)) ) {
+
+			debug_printk("dv1394: IR context stopped due to bus reset; waking it up\n");
+
+			/* to be safe, assume a frame has been dropped. User-space programs
+			   should handle this condition like an overflow. */
+			video->dropped_frames++;
+
+			/* for some reason you must clear, then re-set the RUN bit to restart DMA */
+			/* XXX this doesn't work for me, I can't get IR DMA to restart :[ */
+			
+			/* clear RUN */
+			reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, (1 << 15));
+			flush_pci_write(video->ohci);
+			
+			/* set RUN */
+			reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 15));
+			flush_pci_write(video->ohci);
+			
+			/* set the WAKE bit (just in case; this isn't strictly necessary) */
+			reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12));
+			flush_pci_write(video->ohci);
+
+			irq_printk("dv1394: AFTER IR restart ctx 0x%08x ptr 0x%08x\n",
+				   reg_read(video->ohci, video->ohci_IsoRcvContextControlSet),
+				   reg_read(video->ohci, video->ohci_IsoRcvCommandPtr));
+		}
+
+		spin_unlock_irqrestore(&video->spinlock, flags);
+	}
+
+	/* wake readers/writers/ioctl'ers */
+	wake_up_interruptible(&video->waitq);
+}
+
+static struct hpsb_highlevel_ops hl_ops = {
+	add_host:	dv1394_add_host,
+	remove_host:	dv1394_remove_host,
+	host_reset:     dv1394_host_reset,
+};
+
+
+/*** KERNEL MODULE HANDLERS ************************************************/
+
+MODULE_AUTHOR("Dan Maas <dmaas@dcine.com>, Dan Dennedy <dan@dennedy.org>");
+MODULE_DESCRIPTION("driver for DV input/output on OHCI board");
+MODULE_SUPPORTED_DEVICE("dv1394");
+MODULE_LICENSE("GPL");
+
+static void __exit dv1394_exit_module(void)
+{
+	hpsb_unregister_highlevel (hl_handle);
+	ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
+	dv1394_devfs_del("dv");
+#ifdef CONFIG_PROC_FS
+	dv1394_procfs_del("dv");
+#endif
+}
+
+static int __init dv1394_init_module(void)
+{
+	if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_DV1394,
+				      THIS_MODULE, &dv1394_fops)) {
+		printk(KERN_ERR "dv1394: unable to register character device\n");
+		return -EIO;
+	}
+
+	if (dv1394_devfs_add_dir("dv", NULL, NULL) < 0) {
+		printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/dv\n");
+		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
+		return -ENOMEM;
+	}
+
+#ifdef CONFIG_PROC_FS
+	if (dv1394_procfs_add_dir("dv",NULL,NULL) < 0) {
+		printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/dv\n");
+		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
+		dv1394_devfs_del("dv");
+		return -ENOMEM;
+	}
+#endif
+
+	hl_handle = hpsb_register_highlevel ("dv1394", &hl_ops);
+	if (hl_handle == NULL) {
+		printk(KERN_ERR "dv1394: hpsb_register_highlevel failed\n");
+		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
+		dv1394_devfs_del("dv");
+#ifdef CONFIG_PROC_FS
+		dv1394_procfs_del("dv");
+#endif
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+module_init(dv1394_init_module);
+module_exit(dv1394_exit_module);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/dv1394.h linux/drivers/ieee1394/dv1394.h
--- linux.orig/drivers/ieee1394/dv1394.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/dv1394.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,346 @@
+/*
+ * dv1394.h - DV input/output over IEEE 1394 on OHCI chips
+ *   Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
+ *     receive, proc_fs by Dan Dennedy <dan@dennedy.org>
+ *
+ * based on:
+ *   video1394.h - driver for OHCI 1394 boards
+ *   Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
+ *                          Peter Schlaile <udbz@rz.uni-karlsruhe.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.
+ */
+
+#ifndef _DV_1394_H
+#define _DV_1394_H
+
+/* This is the public user-space interface. Try not to break it. */
+
+#define DV1394_API_VERSION 0x20011127
+
+/* ********************
+   **                **
+   **   DV1394 API   **
+   **                **
+   ********************
+
+   There are two methods of operating the DV1394 DV output device.
+
+   1)
+
+   The simplest is an interface based on write(): simply write
+   full DV frames of data to the device, and they will be transmitted
+   as quickly as possible. The FD may be set for non-blocking I/O,
+   in which case you can use select() or poll() to wait for output
+   buffer space.
+
+   To set the DV output parameters (e.g. whether you want NTSC or PAL
+   video), use the DV1394_INIT ioctl, passing in the parameters you
+   want in a struct dv1394_init.
+ 
+   Example 1:
+         To play a raw .DV file:   cat foo.DV > /dev/dv1394
+	 (cat will use write() internally)
+
+   Example 2:
+           static struct dv1394_init init = {
+	      0x63,        (broadcast channel)
+              4,           (four-frame ringbuffer)
+	      DV1394_NTSC, (send NTSC video)
+	      0, 0         (default empty packet rate)
+           }
+
+	   ioctl(fd, DV1394_INIT, &init);
+
+	   while(1) {
+	          read( <a raw DV file>, buf, DV1394_NTSC_FRAME_SIZE );
+		  write( <the dv1394 FD>, buf, DV1394_NTSC_FRAME_SIZE );
+           }
+
+   2)
+
+   For more control over buffering, and to avoid unnecessary copies
+   of the DV data, you can use the more sophisticated the mmap() interface. 
+   First, call the DV1394_INIT ioctl to specify your parameters, 
+   including the number of frames in the ringbuffer. Then, calling mmap() 
+   on the dv1394 device will give you direct access to the ringbuffer
+   from which the DV card reads your frame data.
+
+   The ringbuffer is simply one large, contiguous region of memory
+   containing two or more frames of packed DV data. Each frame of DV data
+   is 120000 bytes (NTSC) or 144000 bytes (PAL).
+
+   Fill one or more frames in the ringbuffer, then use the DV1394_SUBMIT_FRAMES
+   ioctl to begin I/O. You can use either the DV1394_WAIT_FRAMES ioctl
+   or select()/poll() to wait until the frames are transmitted. Next, you'll
+   need to call the DV1394_GET_STATUS ioctl to determine which ringbuffer
+   frames are clear (ready to be filled with new DV data). Finally, use
+   DV1394_SUBMIT_FRAMES again to send the new data to the DV output.
+
+
+   Example: here is what a four-frame ringbuffer might look like
+            during DV transmission:
+
+
+         frame 0   frame 1   frame 2   frame 3
+
+	*--------------------------------------*
+        | CLEAR   | DV data | DV data | CLEAR  |
+        *--------------------------------------*
+                   <ACTIVE> 
+
+	transmission goes in this direction --->>>
+
+
+   The DV hardware is currently transmitting the data in frame 1.
+   Once frame 1 is finished, it will automatically transmit frame 2.
+   (if frame 2 finishes before frame 3 is submitted, the device
+   will continue to transmit frame 2, and will increase the dropped_frames
+   counter each time it repeats the transmission).
+
+ 
+   If you called DV1394_GET_STATUS at this instant, you would
+   receive the following values:
+   
+                  n_frames          = 4
+		  active_frame      = 1
+		  first_clear_frame = 3
+		  n_clear_frames    = 2
+
+   At this point, you should write new DV data into frame 3 and optionally
+   frame 0. Then call DV1394_SUBMIT_FRAMES to inform the device that
+   it may transmit the new frames.
+
+   ERROR HANDLING
+
+   An error (buffer underflow/overflow or a break in the DV stream due
+   to a 1394 bus reset) can be detected by checking the dropped_frames
+   field of struct dv1394_status (obtained through the
+   DV1394_GET_STATUS ioctl).
+
+   The best way to recover from such an error is to re-initialize
+   dv1394, either by using the DV1394_INIT ioctl call, or closing the
+   file descriptor and opening it again. (note that you must unmap all
+   ringbuffer mappings when closing the file descriptor, or else
+   dv1394 will still be considered 'in use').
+
+   MAIN LOOP
+
+   For maximum efficiency and robustness against bus errors, you are
+   advised to model the main loop of your application after the
+   following pseudo-code example:
+
+   (checks of system call return values omitted for brevity; always
+   check return values in your code!)
+   
+   while( frames left ) {
+   
+    struct pollfd *pfd = ...;
+
+    pfd->fd = dv1394_fd;
+    pfd->revents = 0;
+    pfd->events = POLLOUT | POLLIN; (OUT for transmit, IN for receive)
+
+    (add other sources of I/O here)
+    
+    poll(pfd, 1, -1); (or select(); add a timeout if you want)
+
+    if(pfd->revents) {
+         struct dv1394_status status;
+	 
+         ioctl(dv1394_fd, DV1394_GET_STATUS, &status);
+
+	 if(status.dropped_frames > 0) {
+	      reset_dv1394();
+         } else {
+              for(int i = 0; i < status.n_clear_frames; i++) {
+	          copy_DV_frame();
+              }
+         }
+    }
+   }
+
+   where copy_DV_frame() reads or writes on the dv1394 file descriptor
+   (read/write mode) or copies data to/from the mmap ringbuffer and
+   then calls ioctl(DV1394_SUBMIT_FRAMES) to notify dv1394 that new
+   frames are availble (mmap mode).
+
+   reset_dv1394() is called in the event of a buffer
+   underflow/overflow or a halt in the DV stream (e.g. due to a 1394
+   bus reset). To guarantee recovery from the error, this function
+   should close the dv1394 file descriptor (and munmap() all
+   ringbuffer mappings, if you are using them), then re-open the
+   dv1394 device (and re-map the ringbuffer).
+   
+*/
+
+
+/* maximum number of frames in the ringbuffer */
+#define DV1394_MAX_FRAMES 32
+
+/* number of *full* isochronous packets per DV frame */
+#define DV1394_NTSC_PACKETS_PER_FRAME 250
+#define DV1394_PAL_PACKETS_PER_FRAME  300
+
+/* size of one frame's worth of DV data, in bytes */
+#define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME)
+#define DV1394_PAL_FRAME_SIZE  (480 * DV1394_PAL_PACKETS_PER_FRAME)
+
+
+/* ioctl() commands */
+
+enum {
+	/* I don't like using 0 as a valid ioctl() */
+	DV1394_INVALID = 0,
+
+
+	/* get the driver ready to transmit video.
+	   pass a struct dv1394_init* as the parameter (see below),
+	   or NULL to get default parameters */
+	DV1394_INIT,
+
+
+	/* stop transmitting video and free the ringbuffer */
+	DV1394_SHUTDOWN,
+
+
+	/* submit N new frames to be transmitted, where
+	   the index of the first new frame is first_clear_buffer,
+	   and the index of the last new frame is
+	   (first_clear_buffer + N) % n_frames */
+	DV1394_SUBMIT_FRAMES,
+
+
+	/* block until N buffers are clear (pass N as the parameter)
+	   Because we re-transmit the last frame on underrun, there
+	   will at most be n_frames - 1 clear frames at any time */
+	DV1394_WAIT_FRAMES,
+
+	/* capture new frames that have been received, where
+	   the index of the first new frame is first_clear_buffer,
+	   and the index of the last new frame is
+	   (first_clear_buffer + N) % n_frames */
+	DV1394_RECEIVE_FRAMES,
+
+
+	DV1394_START_RECEIVE,
+
+
+	/* pass a struct dv1394_status* as the parameter (see below) */
+	DV1394_GET_STATUS,
+};
+
+
+
+enum pal_or_ntsc {
+	DV1394_NTSC = 0,
+	DV1394_PAL
+};
+
+
+
+
+/* this is the argument to DV1394_INIT */
+struct dv1394_init {
+	/* DV1394_API_VERSION */
+	unsigned int api_version;
+	
+	/* isochronous transmission channel to use */
+	unsigned int channel;
+
+	/* number of frames in the ringbuffer. Must be at least 2
+	   and at most DV1394_MAX_FRAMES. */
+	unsigned int n_frames;
+
+	/* send/receive PAL or NTSC video format */
+	enum pal_or_ntsc format;
+
+	/* the following are used only for transmission */
+ 
+	/* set these to zero unless you want a
+	   non-default empty packet rate (see below) */
+	unsigned long cip_n;
+	unsigned long cip_d;
+
+	/* set this to zero unless you want a
+	   non-default SYT cycle offset (default = 3 cycles) */
+	unsigned int syt_offset;
+};
+
+/* NOTE: you may only allocate the DV frame ringbuffer once each time
+   you open the dv1394 device. DV1394_INIT will fail if you call it a
+   second time with different 'n_frames' or 'format' arguments (which
+   would imply a different size for the ringbuffer). If you need a
+   different buffer size, simply close and re-open the device, then
+   initialize it with your new settings. */
+   
+/* Q: What are cip_n and cip_d? */
+
+/*
+  A: DV video streams do not utilize 100% of the potential bandwidth offered
+  by IEEE 1394 (FireWire). To achieve the correct rate of data transmission,
+  DV devices must periodically insert empty packets into the 1394 data stream.
+  Typically there is one empty packet per 14-16 data-carrying packets.
+
+  Some DV devices will accept a wide range of empty packet rates, while others
+  require a precise rate. If the dv1394 driver produces empty packets at
+  a rate that your device does not accept, you may see ugly patterns on the
+  DV output, or even no output at all.
+
+  The default empty packet insertion rate seems to work for many people; if
+  your DV output is stable, you can simply ignore this discussion. However,
+  we have exposed the empty packet rate as a parameter to support devices that
+  do not work with the default rate. 
+
+  The decision to insert an empty packet is made with a numerator/denominator
+  algorithm. Empty packets are produced at an average rate of CIP_N / CIP_D.
+  You can alter the empty packet rate by passing non-zero values for cip_n
+  and cip_d to the INIT ioctl.
+  
+ */
+
+
+
+struct dv1394_status {
+	/* this embedded init struct returns the current dv1394
+	   parameters in use */
+	struct dv1394_init init;
+
+	/* the ringbuffer frame that is currently being
+	   displayed. (-1 if the device is not transmitting anything) */
+	int active_frame;
+
+	/* index of the first buffer (ahead of active_frame) that
+	   is ready to be filled with data */
+	unsigned int first_clear_frame;
+
+	/* how many buffers, including first_clear_buffer, are
+	   ready to be filled with data */
+	unsigned int n_clear_frames;
+
+	/* how many times the DV stream has underflowed, overflowed,
+	   or otherwise encountered an error, since the previous call
+	   to DV1394_GET_STATUS */
+	unsigned int dropped_frames;
+
+	/* N.B. The dropped_frames counter is only a lower bound on the actual
+	   number of dropped frames, with the special case that if dropped_frames
+	   is zero, then it is guaranteed that NO frames have been dropped
+	   since the last call to DV1394_GET_STATUS.
+	*/
+};
+
+
+#endif /* _DV_1394_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/eth1394.c linux/drivers/ieee1394/eth1394.c
--- linux.orig/drivers/ieee1394/eth1394.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/eth1394.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,741 @@
+/*
+ * eth1394.c -- Ethernet driver for Linux IEEE-1394 Subsystem
+ * 
+ * Copyright (C) 2001 Ben Collins <bcollins@debian.org>
+ *               2000 Bonin Franck <boninf@free.fr>
+ *
+ * Mainly based on work by Emanuel Pirker and Andreas E. Bombe
+ *
+ * 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.
+ */
+
+/* State of this driver:
+ *
+ * This driver intends to support RFC 2734, which describes a method for
+ * transporting IPv4 datagrams over IEEE-1394 serial busses. This driver
+ * will ultimately support that method, but currently falls short in
+ * several areas. A few issues are:
+ *
+ *   - Does not support send/recv over Async streams using GASP
+ *     packet formats, as per the RFC for ARP requests.
+ *   - Does not yet support fragmented packets.
+ *   - Relies on hardware address being equal to the nodeid for some things.
+ *   - Does not support multicast
+ *   - Hardcoded address for sending packets, instead of using discovery
+ *     (ARP, see first item)
+ */
+
+#include <linux/module.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <asm/delay.h>
+#include <asm/semaphore.h>
+#include <asm/bitops.h>
+#include <net/arp.h>
+
+#include "ieee1394_types.h"
+#include "ieee1394_core.h"
+#include "ieee1394_transactions.h"
+#include "ieee1394.h"
+#include "highlevel.h"
+#include "eth1394.h"
+
+#define ETH1394_PRINT_G(level, fmt, args...) \
+	printk(level ETHER1394_DRIVER_NAME": "fmt, ## args)
+
+#define ETH1394_PRINT(level, dev_name, fmt, args...) \
+	printk(level ETHER1394_DRIVER_NAME": %s: " fmt, dev_name, ## args)
+
+#define DEBUG(fmt, args...) \
+	printk(KERN_ERR fmt, ## args)
+
+static char version[] __devinitdata =
+	"eth1394.c:v0.50 15/Jul/01 Ben Collins <bcollins@debian.org>";
+
+/* Our ieee1394 highlevel driver */
+#define ETHER1394_DRIVER_NAME "ether1394"
+
+static kmem_cache_t *packet_task_cache;
+static struct hpsb_highlevel *hl_handle = NULL;
+
+/* Card handling */
+static LIST_HEAD (host_info_list);
+static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
+
+/* Use common.lf to determine header len */
+static int hdr_type_len[] = {
+	sizeof (struct eth1394_uf_hdr),
+	sizeof (struct eth1394_ff_hdr),
+	sizeof (struct eth1394_sf_hdr),
+	sizeof (struct eth1394_sf_hdr)
+};
+
+MODULE_AUTHOR("Ben Collins (bcollins@debian.org)");
+MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)");
+
+/* Find our host_info struct for a given host pointer. Must be called
+ * under spinlock.  */
+static inline struct host_info *find_host_info (struct hpsb_host *host)
+{
+	struct list_head *lh;
+	struct host_info *hi;
+
+	lh = host_info_list.next;
+	while (lh != &host_info_list) {
+		hi = list_entry (lh, struct host_info, list);
+
+		if (hi->host == host)
+			return hi;
+
+		lh = lh->next;
+	}
+	return NULL;
+}
+
+/* Find the network device for our host */
+static inline struct net_device *ether1394_find_dev (struct hpsb_host *host)
+{
+	struct host_info *hi;
+
+	spin_lock_irq (&host_info_lock);
+	hi = find_host_info (host);
+	spin_unlock_irq (&host_info_lock);
+
+	if (hi == NULL)
+		return NULL;
+
+	return hi->dev;
+}
+
+/* This is called after an "ifup" */
+static int ether1394_open (struct net_device *dev)
+{
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+
+	/* Set the spinlock before grabbing IRQ! */
+	priv->lock = SPIN_LOCK_UNLOCKED;
+
+	netif_start_queue (dev);
+	return 0;
+}
+
+/* This is called after an "ifdown" */
+static int ether1394_stop (struct net_device *dev)
+{
+	netif_stop_queue (dev);
+	return 0;
+}
+
+/* Return statistics to the caller */
+static struct net_device_stats *ether1394_stats (struct net_device *dev)
+{
+	return &(((struct eth1394_priv *)dev->priv)->stats);
+}
+
+/* What to do if we timeout. I think a host reset is probably in order, so
+ * that's what we do. Should we increment the stat counters too?  */
+static void ether1394_tx_timeout (struct net_device *dev)
+{
+	ETH1394_PRINT (KERN_ERR, dev->name, "Timeout, resetting host %s\n",
+		       ((struct eth1394_priv *)(dev->priv))->host->driver->name);
+
+	highlevel_host_reset (((struct eth1394_priv *)(dev->priv))->host);
+
+	netif_wake_queue (dev);
+}
+
+/* We need to encapsulate the standard header with our own. We use the
+ * ethernet header's proto for our own.
+ *
+ * XXX: This is where we need to create a list of skb's for fragmented
+ * packets.  */
+static inline void ether1394_encapsulate (struct sk_buff *skb, struct net_device *dev,
+			    int proto)
+{
+	union eth1394_hdr *hdr =
+		(union eth1394_hdr *)skb_push (skb, hdr_type_len[ETH1394_HDR_LF_UF]);
+
+	hdr->common.lf = ETH1394_HDR_LF_UF;
+	hdr->words.word1 = htons(hdr->words.word1);
+	hdr->uf.ether_type = proto;
+
+	return;
+}
+
+/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the
+ * entire arphdr) is the same format as the ip1394 header, so they
+ * overlap. The rest needs to be munged a bit. The remainder of the
+ * arphdr is formatted based on hwaddr len and ipaddr len. We know what
+ * they'll be, so it's easy to judge.  */
+static inline void ether1394_arp_to_1394arp (struct sk_buff *skb, struct net_device *dev)
+{
+	struct eth1394_priv *priv =
+		(struct eth1394_priv *)(dev->priv);
+	u16 phy_id = priv->host->node_id & NODE_MASK;
+
+	unsigned char *arp_ptr = (unsigned char *)skb->data;
+	struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data;
+	unsigned char arp_data[2*(dev->addr_len+4)];
+
+	/* Copy the main data that we need */
+	arp_ptr = memcpy (arp_data, arp_ptr + sizeof(struct arphdr), sizeof (arp_data));
+
+	/* Extend the buffer enough for our new header */
+	skb_put (skb, sizeof (struct eth1394_arp) -
+		 (sizeof (arp_data) + sizeof (struct arphdr)));
+
+#define PROCESS_MEMBER(ptr,val,len) \
+  memcpy (val, ptr, len); ptr += len
+	arp_ptr += arp1394->hw_addr_len;
+	PROCESS_MEMBER (arp_ptr, &arp1394->sip, arp1394->ip_addr_len);
+	arp_ptr += arp1394->hw_addr_len;
+	PROCESS_MEMBER (arp_ptr, &arp1394->tip, arp1394->ip_addr_len);
+#undef PROCESS_MEMBER
+
+	/* Now add our own flavor of arp header fields to the orig one */
+	arp1394->hw_addr_len	= IP1394_HW_ADDR_LEN;
+	arp1394->hw_type	= __constant_htons (ARPHRD_IEEE1394);
+	arp1394->s_uniq_id	= cpu_to_le64 (priv->eui[phy_id]);
+	arp1394->max_rec	= priv->max_rec[phy_id];
+	arp1394->sspd		= priv->sspd[phy_id];
+	arp1394->fifo_hi	= htons (priv->fifo_hi[phy_id]);
+	arp1394->fifo_lo	= htonl (priv->fifo_lo[phy_id]);
+
+	return;
+}
+
+static int ether1394_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if ((new_mtu < 68) || (new_mtu > ETHER1394_REGION_ADDR_LEN))
+		return -EINVAL;
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+static inline void ether1394_register_limits (int nodeid, unsigned char max_rec,
+				       unsigned char sspd, u64 eui, u16 fifo_hi,
+				       u32 fifo_lo, struct eth1394_priv *priv)
+{
+	int i;
+
+	if (nodeid < 0 || nodeid >= ALL_NODES) {
+		ETH1394_PRINT_G (KERN_ERR, "Cannot register invalid nodeid %d\n", nodeid);
+		return;
+	}
+
+	priv->max_rec[nodeid]	= max_rec;
+	priv->sspd[nodeid]	= sspd;
+	priv->fifo_hi[nodeid]	= fifo_hi;
+	priv->fifo_lo[nodeid]	= fifo_lo;
+	priv->eui[nodeid]	= eui;
+
+	/* 63 is used for broadcasts to all hosts. It is equal to the
+	 * minimum of all registered nodes. A registered node is one with
+	 * a nonzero offset. Set the values rediculously high to start. We
+	 * know we have atleast one to change the default to.  */
+	sspd = 0xff;
+	max_rec = 0xff;
+	for (i = 0; i < ALL_NODES; i++) {
+		if (!priv->fifo_hi && !priv->fifo_lo) continue; /* Unregistered */
+		if (priv->max_rec[i] < max_rec) max_rec = priv->max_rec[i];
+		if (priv->sspd[i] < sspd) sspd = priv->sspd[i];
+	}
+
+	priv->max_rec[ALL_NODES] = max_rec;
+	priv->sspd[ALL_NODES] = sspd;
+
+	return;
+}
+
+static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
+{
+	int flags;
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+	int phy_id = priv->host->node_id & NODE_MASK;
+
+	spin_lock_irqsave (&priv->lock, flags);
+
+	/* Clear the speed/payload/offset tables */
+	memset (priv->max_rec, 0, sizeof (priv->max_rec));
+	memset (priv->sspd, 0, sizeof (priv->sspd));
+	memset (priv->fifo_hi, 0, sizeof (priv->fifo_hi));
+	memset (priv->fifo_lo, 0, sizeof (priv->fifo_lo));
+
+	/* Register our limits now */
+	ether1394_register_limits (phy_id, (be32_to_cpu(priv->host->csr.rom[2]) >> 12) & 0xf,
+				   priv->host->speed_map[(phy_id << 6) + phy_id],
+				   (u64)(((u64)be32_to_cpu(priv->host->csr.rom[3]) << 32) |
+				   be32_to_cpu(priv->host->csr.rom[4])),
+				   ETHER1394_REGION_ADDR >> 32,
+				   ETHER1394_REGION_ADDR & 0xffffffff, priv);
+
+	/* We'll use our max_rec as the default mtu */
+	if (set_mtu)
+		dev->mtu = (1 << (priv->max_rec[phy_id] + 1)) - sizeof (union eth1394_hdr);
+
+	/* Set our hardware address while we're at it */
+	*(nodeid_t *)dev->dev_addr = htons (priv->host->node_id);
+
+	spin_unlock_irqrestore (&priv->lock, flags);
+}
+
+static int ether1394_tx (struct sk_buff *skb, struct net_device *dev);
+
+/* This function is called by register_netdev */
+static int ether1394_init_dev (struct net_device *dev)
+{
+	/* Our functions */
+	dev->open		= ether1394_open;
+	dev->stop		= ether1394_stop;
+	dev->hard_start_xmit	= ether1394_tx;
+	dev->get_stats		= ether1394_stats;
+	dev->tx_timeout		= ether1394_tx_timeout;
+	dev->change_mtu		= ether1394_change_mtu;
+
+	/* Some constants */
+	dev->watchdog_timeo	= ETHER1394_TIMEOUT;
+	dev->flags		= IFF_BROADCAST; /* TODO: Support MCAP */
+	dev->features		= NETIF_F_NO_CSUM|NETIF_F_SG|NETIF_F_HIGHDMA|NETIF_F_FRAGLIST;
+	dev->addr_len		= 2;
+
+	ether1394_reset_priv (dev, 1);
+
+	return 0;
+}
+
+/*
+ * This function is called every time a card is found. It is generally called
+ * when the module is installed. This is where we add all of our ethernet
+ * devices. One for each host.
+ */
+static void ether1394_add_host (struct hpsb_host *host)
+{
+	struct host_info *hi = NULL;
+	struct net_device *dev = NULL;
+	struct eth1394_priv *priv;
+	static int version_printed = 0;
+
+	if (version_printed++ == 0)
+		ETH1394_PRINT_G (KERN_INFO, "%s\n", version);
+
+	dev = alloc_etherdev(sizeof (struct eth1394_priv));
+
+	if (dev == NULL)
+		goto out;
+
+	SET_MODULE_OWNER(dev);
+
+	dev->init = ether1394_init_dev;
+
+	priv = (struct eth1394_priv *)dev->priv;
+
+	priv->host = host;
+
+	hi = (struct host_info *)kmalloc (sizeof (struct host_info),
+					  GFP_KERNEL);
+
+	if (hi == NULL)
+		goto out;
+
+	if (register_netdev (dev)) {
+		ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n");
+		kfree (dev);
+		return;
+	}
+
+	ETH1394_PRINT (KERN_ERR, dev->name, "IEEE-1394 IPv4 over 1394 Ethernet (%s)\n",
+		       host->driver->name);
+
+	INIT_LIST_HEAD (&hi->list);
+	hi->host = host;
+	hi->dev = dev;
+
+	spin_lock_irq (&host_info_lock);
+	list_add_tail (&hi->list, &host_info_list);
+	spin_unlock_irq (&host_info_lock);
+
+	return;
+
+out:
+	if (dev != NULL)
+		kfree (dev);
+	ETH1394_PRINT_G (KERN_ERR, "Out of memory\n");
+
+	return;
+}
+
+/* Remove a card from our list */
+static void ether1394_remove_host (struct hpsb_host *host)
+{
+	struct host_info *hi;
+
+	spin_lock_irq (&host_info_lock);
+	hi = find_host_info (host);
+	if (hi != NULL) {
+		unregister_netdev (hi->dev);
+		kfree (hi->dev);
+		list_del (&hi->list);
+		kfree (hi);
+	}
+	spin_unlock_irq (&host_info_lock);
+
+	return;
+}
+
+/* A reset has just arisen */
+static void ether1394_host_reset (struct hpsb_host *host)
+{
+	struct net_device *dev = ether1394_find_dev(host);
+
+	/* This can happen for hosts that we don't use */
+	if (dev == NULL)
+		return;
+
+	/* Reset our private host data, but not our mtu */
+	netif_stop_queue (dev);
+	ether1394_reset_priv (dev, 0);
+	netif_wake_queue (dev);
+}
+
+/* Copied from net/ethernet/eth.c */
+static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ethhdr *eth;
+	unsigned char *rawp;
+
+	skb->mac.raw = skb->data;
+	skb_pull (skb, ETH_HLEN);
+	eth = skb->mac.ethernet;
+#if 0
+	if(*eth->h_dest & 1) {
+		if(memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0)
+			skb->pkt_type = PACKET_BROADCAST;
+		else
+			skb->pkt_type = PACKET_MULTICAST;
+	} else {
+		if(memcmp(eth->h_dest, dev->dev_addr, dev->addr_len))
+			skb->pkt_type = PACKET_OTHERHOST;
+        }
+#endif
+	if (ntohs (eth->h_proto) >= 1536)
+		return eth->h_proto;
+
+	rawp = skb->data;
+
+        if (*(unsigned short *)rawp == 0xFFFF)
+		return htons (ETH_P_802_3);
+
+        return htons (ETH_P_802_2);
+}
+
+/* Parse an encapsulated IP1394 header into an ethernet frame packet.
+ * We also perform ARP translation here, if need be.  */
+static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct net_device *dev,
+					     nodeid_t srcid, nodeid_t destid)
+{
+	union eth1394_hdr *hdr = (union eth1394_hdr *)skb->data;
+	unsigned char src_hw[ETH_ALEN], dest_hw[ETH_ALEN];
+	unsigned short ret = 0;
+
+	/* Setup our hw addresses. We use these to build the
+	 * ethernet header.  */
+	*(u16 *)dest_hw = htons(destid);
+	*(u16 *)src_hw = htons(srcid);
+
+	/* Remove the encapsulation header */
+	hdr->words.word1 = ntohs(hdr->words.word1);
+	skb_pull (skb, hdr_type_len[hdr->common.lf]);
+
+	/* If this is an ARP packet, convert it. First, we want to make
+	 * use of some of the fields, since they tell us a little bit
+	 * about the sending machine.  */
+	if (hdr->uf.ether_type == __constant_htons (ETH_P_ARP)) {
+		int flags;
+		u16 phy_id = srcid & NODE_MASK;
+		struct eth1394_priv *priv =
+			(struct eth1394_priv *)dev->priv;
+		struct eth1394_arp arp1394;
+		struct arphdr *arp = (struct arphdr *)skb->data;
+		unsigned char *arp_ptr = (unsigned char *)(arp + 1);
+
+		memcpy (&arp1394, arp, sizeof (struct eth1394_arp));
+
+		/* Update our speed/payload/fifo_offset table */
+		spin_lock_irqsave (&priv->lock, flags);
+		ether1394_register_limits (phy_id, arp1394.max_rec, arp1394.sspd,
+					   le64_to_cpu (arp1394.s_uniq_id),
+					   ntohs (arp1394.fifo_hi),
+					   ntohl (arp1394.fifo_lo), priv);
+		spin_unlock_irqrestore (&priv->lock, flags);
+
+#define PROCESS_MEMBER(ptr,val,len) \
+  ptr = memcpy (ptr, val, len) + len
+                PROCESS_MEMBER (arp_ptr, src_hw, dev->addr_len);
+                PROCESS_MEMBER (arp_ptr, &arp1394.sip, 4);
+                PROCESS_MEMBER (arp_ptr, dest_hw, dev->addr_len);
+                PROCESS_MEMBER (arp_ptr, &arp1394.tip, 4);
+#undef PROCESS_MEMBER
+
+		arp->ar_hln = dev->addr_len;
+		arp->ar_hrd = __constant_htons (ARPHRD_ETHER);
+
+		skb_trim (skb, sizeof (struct arphdr) + 2*(dev->addr_len+4));
+	}
+
+	/* Now add the ethernet header. */
+	if (dev->hard_header (skb, dev, __constant_ntohs (hdr->uf.ether_type),
+			      dest_hw, src_hw, skb->len) >= 0)
+		ret = ether1394_type_trans(skb, dev);
+
+	return ret;
+}
+
+/* Packet reception. We convert the IP1394 encapsulation header to an
+ * ethernet header, and fill it with some of our other fields. This is
+ * an incoming packet from the 1394 bus.  */
+static int ether1394_write (struct hpsb_host *host, int srcid, int destid,
+			    quadlet_t *data, u64 addr, unsigned int len)
+{
+	struct sk_buff *skb;
+	char *buf = (char *)data;
+	int flags;
+	struct net_device *dev = ether1394_find_dev (host);
+	struct eth1394_priv *priv;
+
+	if (dev == NULL) {
+		ETH1394_PRINT_G (KERN_ERR, "Could not find net device for host %p\n",
+				 host);
+		return RCODE_ADDRESS_ERROR;
+	}
+
+	priv = (struct eth1394_priv *)dev->priv;
+
+	/* A packet has been received by the ieee1394 bus. Build an skbuff
+	 * around it so we can pass it to the high level network layer. */
+
+	skb = dev_alloc_skb (len + dev->hard_header_len + 15);
+	if (!skb) {
+		HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
+		priv->stats.rx_dropped++;
+		return RCODE_ADDRESS_ERROR;
+	}
+
+	skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
+
+	memcpy (skb_put (skb, len), buf, len);
+
+	/* Write metadata, and then pass to the receive level */
+	skb->dev = dev;
+	skb->ip_summed = CHECKSUM_UNNECESSARY;	/* don't check it */
+
+	/* Parse the encapsulation header. This actually does the job of
+	 * converting to an ethernet frame header, aswell as arp
+	 * conversion if needed. ARP conversion is easier in this
+	 * direction, since we are using ethernet as our backend.  */
+	skb->protocol = ether1394_parse_encap (skb, dev, srcid, destid);
+
+	spin_lock_irqsave (&priv->lock, flags);
+	if (!skb->protocol) {
+		priv->stats.rx_errors++;
+		priv->stats.rx_dropped++;
+		dev_kfree_skb_any(skb);
+		goto bad_proto;
+	}
+
+	netif_stop_queue(dev);
+	if (netif_rx (skb) == NET_RX_DROP) {
+		priv->stats.rx_errors++;
+		priv->stats.rx_dropped++;
+		goto bad_proto;
+	}
+
+	/* Statistics */
+	priv->stats.rx_packets++;
+	priv->stats.rx_bytes += skb->len;
+
+bad_proto:
+	netif_start_queue(dev);
+	spin_unlock_irqrestore (&priv->lock, flags);
+
+	dev->last_rx = jiffies;
+
+	return RCODE_COMPLETE;
+}
+
+/* This function is our scheduled write */
+static void hpsb_write_sched (void *__ptask)
+{
+	struct packet_task *ptask = (struct packet_task *)__ptask;
+	struct sk_buff *skb = ptask->skb;
+	struct net_device *dev = ptask->skb->dev;
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+	int flags;
+
+	/* Statistics */
+	spin_lock_irqsave (&priv->lock, flags);
+	if (!hpsb_write(priv->host, ptask->dest_node,
+			get_hpsb_generation(priv->host),
+			ptask->addr, (quadlet_t *)skb->data, skb->len)) {
+		priv->stats.tx_bytes += skb->len;
+		priv->stats.tx_packets++;
+	} else {
+		//printk("Failed in hpsb_write_sched\n");
+		priv->stats.tx_dropped++;
+		priv->stats.tx_errors++;
+		if (netif_queue_stopped (dev))
+			netif_wake_queue (dev);
+	}
+	spin_unlock_irqrestore (&priv->lock, flags);
+
+	dev->trans_start = jiffies;
+	dev_kfree_skb(skb);
+	kmem_cache_free(packet_task_cache, ptask);
+
+	return;
+}
+
+/* Transmit a packet (called by kernel) */
+static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
+{
+	int kmflags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
+	struct ethhdr *eth;
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+	int proto, flags;
+	nodeid_t dest_node;
+	u64 addr;
+	struct packet_task *ptask = NULL;
+	int ret = 0;
+
+	if ((skb = skb_share_check (skb, kmflags)) == NULL) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* Get rid of the ethernet header, but save a pointer */
+	eth = (struct ethhdr *)skb->data;
+	skb_pull (skb, ETH_HLEN);
+
+	/* Save the destination id, and proto for our encapsulation, then
+	 * toss the ethernet header aside like the cheap whore it is.  */
+	dest_node = ntohs (*(nodeid_t *)(eth->h_dest));
+	proto = eth->h_proto;
+
+	/* If this is an ARP packet, convert it */
+	if (proto == __constant_htons (ETH_P_ARP))
+		ether1394_arp_to_1394arp (skb, dev);
+
+	/* Now add our encapsulation header */
+	ether1394_encapsulate (skb, dev, proto);
+
+	/* TODO: The above encapsulate function needs to recognize when a
+	 * packet needs to be split for a specified node. It should create
+	 * a list of skb's that we could then iterate over for the below
+	 * call to schedule our writes.  */
+
+	/* XXX: Right now we accept that we don't exactly follow RFC. When
+	 * we do, we will send ARP requests via GASP format, and so we wont
+	 * need this hack.  */
+
+	spin_lock_irqsave (&priv->lock, flags);
+	addr = (u64)priv->fifo_hi[dest_node & NODE_MASK] << 32 |
+		priv->fifo_lo[dest_node & NODE_MASK];
+	spin_unlock_irqrestore (&priv->lock, flags);
+
+	if (!addr)
+		addr = ETHER1394_REGION_ADDR;
+
+	ptask = kmem_cache_alloc(packet_task_cache, kmflags);
+	if (ptask == NULL) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	ptask->skb = skb;
+	ptask->addr = addr;
+	ptask->dest_node = dest_node;
+	INIT_TQUEUE(&ptask->tq, hpsb_write_sched, ptask);
+	schedule_task(&ptask->tq);
+
+	return 0;
+fail:
+	printk("Failed in ether1394_tx\n");
+
+	if (skb != NULL)
+		dev_kfree_skb (skb);
+
+	spin_lock_irqsave (&priv->lock, flags);
+	priv->stats.tx_dropped++;
+	priv->stats.tx_errors++;
+	if (netif_queue_stopped (dev))
+		netif_wake_queue (dev);
+	spin_unlock_irqrestore (&priv->lock, flags);
+
+	return ret;
+}
+
+/* Function for incoming 1394 packets */
+static struct hpsb_address_ops addr_ops = {
+	write:		ether1394_write,
+};
+
+/* Ieee1394 highlevel driver functions */
+static struct hpsb_highlevel_ops hl_ops = {
+	add_host:	ether1394_add_host,
+	remove_host:	ether1394_remove_host,
+	host_reset:	ether1394_host_reset,
+};
+
+static int __init ether1394_init_module (void)
+{
+	packet_task_cache = kmem_cache_create("packet_task", sizeof(struct packet_task),
+					      0, 0, NULL, NULL);
+
+	/* Register ourselves as a highlevel driver */
+	hl_handle = hpsb_register_highlevel (ETHER1394_DRIVER_NAME, &hl_ops);
+
+	if (hl_handle == NULL) {
+		ETH1394_PRINT_G (KERN_ERR, "No more memory for driver\n");
+		return -ENOMEM;
+	}
+
+	hpsb_register_addrspace (hl_handle, &addr_ops, ETHER1394_REGION_ADDR,
+				 ETHER1394_REGION_ADDR_END);
+
+	return 0;
+}
+
+static void __exit ether1394_exit_module (void)
+{
+	hpsb_unregister_highlevel (hl_handle);
+	kmem_cache_destroy(packet_task_cache);
+}
+
+module_init(ether1394_init_module);
+module_exit(ether1394_exit_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/eth1394.h linux/drivers/ieee1394/eth1394.h
--- linux.orig/drivers/ieee1394/eth1394.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/ieee1394/eth1394.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,190 @@
+/*
+ * eth1394.h -- Ethernet driver for Linux IEEE-1394 Subsystem
+ *
+ * Copyright (C) 2000 Bonin Franck <boninf@free.fr>
+ *           (C) 2001 Ben Collins <bcollins@debian.org>
+ *
+ * Mainly based on work by Emanuel Pirker and Andreas E. Bombe
+ *
+ * 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.
+ */
+
+#ifndef __ETH1394_H
+#define __ETH1394_H
+
+/* Register for incoming packets. This is 8192 bytes, which supports up to
+ * 1600mbs. We'll need to change this if that ever becomes "small" :)  */
+#define ETHER1394_REGION_ADDR_LEN	8192
+#define ETHER1394_REGION_ADDR		0xfffff0200000ULL
+#define ETHER1394_REGION_ADDR_END	(ETHER1394_REGION_ADDR + ETHER1394_REGION_ADDR_LEN)
+
+/* Node set == 64 */
+#define NODE_SET			(ALL_NODES + 1)
+
+/* Private structure for our ethernet driver */
+struct eth1394_priv {
+	struct net_device_stats stats;	/* Device stats			 */
+	struct hpsb_host *host;		/* The card for this dev	 */
+	unsigned char max_rec[NODE_SET];/* Max payload per node		 */
+	unsigned char sspd[NODE_SET];	/* Max speed per node		 */
+	u16 fifo_hi[ALL_NODES];		/* 16bit hi fifo offset per node */
+	u32 fifo_lo[ALL_NODES];		/* 32bit lo fifo offset per node */
+	u64 eui[ALL_NODES];		/* EUI-64 per node		 */
+	spinlock_t lock;		/* Private lock			 */
+};
+
+struct host_info {
+	struct list_head list;
+	struct hpsb_host *host;
+	struct net_device *dev;
+};
+
+/* This is our task struct. It's used for the complete_tq callback.  */
+struct packet_task {
+	struct sk_buff *skb;	/* Socket buffer we are sending */
+	nodeid_t dest_node;	/* Destination of the packet */
+	u64 addr;		/* Address */
+	struct tq_struct tq;	/* The task */
+};
+
+/* IP1394 headers */
+#include <asm/byteorder.h>
+
+/* Unfragmented */
+#if defined __BIG_ENDIAN_BITFIELD
+struct eth1394_uf_hdr {
+	u8 lf:2;
+	u16 res:14;
+	u16 ether_type;		/* Ethernet packet type */
+} __attribute__((packed));
+#elif defined __LITTLE_ENDIAN_BITFIELD
+struct eth1394_uf_hdr {
+	u16 res:14;
+	u8 lf:2;
+	u16 ether_type;
+} __attribute__((packed));
+#else
+#error Unknown bit field type
+#endif
+
+/* First fragment */
+#if defined __BIG_ENDIAN_BITFIELD
+struct eth1394_ff_hdr {
+	u8 lf:2;
+	u8 res1:2;
+	u16 dg_size:12;		/* Datagram size */
+	u16 ether_type;		/* Ethernet packet type */
+	u16 dgl;		/* Datagram label */
+	u16 res2;
+} __attribute__((packed));
+#elif defined __LITTLE_ENDIAN_BITFIELD
+struct eth1394_ff_hdr {
+	u16 dg_size:12;
+	u8 res1:2;
+	u8 lf:2;
+	u16 ether_type;
+	u16 dgl;
+	u16 res2;
+} __attribute__((packed));
+#else
+#error Unknown bit field type
+#endif
+
+/* XXX: Subsequent fragments, including last */
+#if defined __BIG_ENDIAN_BITFIELD
+struct eth1394_sf_hdr {
+	u8 lf:2;
+	u8 res1:2;
+	u16 dg_size:12;		/* Datagram size */
+	u8 res2:6;
+	u16 fg_off:10;		/* Fragment offset */
+	u16 dgl;		/* Datagram label */
+	u16 res3;
+} __attribute__((packed));
+#elif defined __LITTLE_ENDIAN_BITFIELD
+struct eth1394_sf_hdr {
+	u16 dg_size:12;
+	u8 res1:2;
+	u8 lf:2;
+	u16 fg_off:10;
+	u8 res2:6;
+	u16 dgl;
+	u16 res3;
+} __attribute__((packed));
+#else
+#error Unknown bit field type
+#endif
+
+#if defined __BIG_ENDIAN_BITFIELD
+struct eth1394_common_hdr {
+	u8 lf:2;
+	u16 pad1:14;
+} __attribute__((packed));
+#elif defined __LITTLE_ENDIAN_BITFIELD
+struct eth1394_common_hdr {
+	u16 pad1:14;
+	u8 lf:2;
+} __attribute__((packed));
+#else
+#error Unknown bit field type
+#endif
+
+struct eth1394_hdr_words {
+	u16 word1;
+	u16 word2;
+	u16 word3;
+	u16 word4;
+};
+
+union eth1394_hdr {
+	struct eth1394_common_hdr common;
+	struct eth1394_uf_hdr uf;
+	struct eth1394_ff_hdr ff;
+	struct eth1394_sf_hdr sf;
+	struct eth1394_hdr_words words;
+};
+
+/* End of IP1394 headers */
+
+/* Fragment types */
+#define ETH1394_HDR_LF_UF	0	/* unfragmented		*/
+#define ETH1394_HDR_LF_FF	1	/* first fragment	*/
+#define ETH1394_HDR_LF_LF	2	/* last fragment	*/
+#define ETH1394_HDR_LF_IF	3	/* interior fragment	*/
+
+#define IP1394_HW_ADDR_LEN	16	/* As per RFC		*/
+
+/* Our arp packet (ARPHRD_IEEE1394) */
+struct eth1394_arp {
+	u16 hw_type;		/* 0x0018	*/
+	u16 proto_type;		/* 0x0806	*/
+	u8 hw_addr_len;		/* 16 		*/
+	u8 ip_addr_len;		/* 4		*/
+	u16 opcode;		/* ARP Opcode	*/
+	/* Above is exactly the same format as struct arphdr */
+
+	u64 s_uniq_id;		/* Sender's 64bit EUI			*/
+	u8 max_rec;		/* Sender's max packet size		*/
+	u8 sspd;		/* Sender's max speed			*/
+	u16 fifo_hi;		/* hi 16bits of sender's FIFO addr	*/
+	u32 fifo_lo;		/* lo 32bits of sender's FIFO addr	*/
+	u32 sip;		/* Sender's IP Address			*/
+	u32 tip;		/* IP Address of requested hw addr	*/
+};
+
+/* Network timeout */
+#define ETHER1394_TIMEOUT	100000
+
+#endif /* __ETH1394_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/highlevel.c linux/drivers/ieee1394/highlevel.c
--- linux.orig/drivers/ieee1394/highlevel.c	2001-10-02 04:24:24.000000000 +0000
+++ linux/drivers/ieee1394/highlevel.c	2002-07-20 01:08:31.000000000 +0000
@@ -44,10 +44,11 @@
         hl->op = ops;
 
         write_lock_irq(&hl_drivers_lock);
-        hl_all_hosts(hl, 1);
         list_add_tail(&hl->hl_list, &hl_drivers);
         write_unlock_irq(&hl_drivers_lock);
 
+        hl_all_hosts(hl->op->add_host);
+
         return hl;
 }
 
@@ -73,9 +74,11 @@
 
         write_lock_irq(&hl_drivers_lock);
         list_del(&hl->hl_list);
-        hl_all_hosts(hl, 0);
         write_unlock_irq(&hl_drivers_lock);
 
+        if (hl->op->remove_host)
+		hl_all_hosts(hl->op->remove_host);
+
         kfree(hl);
 }
 
@@ -87,7 +90,7 @@
         int retval = 0;
 
         if (((start|end) & 3) || (start >= end) || (end > 0x1000000000000ULL)) {
-                HPSB_ERR(__FUNCTION__ " called with invalid addresses");
+                HPSB_ERR("%s called with invalid addresses", __FUNCTION__);
                 return 0;
         }
 
@@ -131,12 +134,12 @@
                          unsigned int channel)
 {
         if (channel > 63) {
-                HPSB_ERR(__FUNCTION__ " called with invalid channel");
+                HPSB_ERR("%s called with invalid channel", __FUNCTION__);
                 return;
         }
 
         if (host->iso_listen_count[channel]++ == 0) {
-                host->template->devctl(host, ISO_LISTEN_CHANNEL, channel);
+                host->ops->devctl(host, ISO_LISTEN_CHANNEL, channel);
         }
 }
 
@@ -144,46 +147,58 @@
                            unsigned int channel)
 {
         if (channel > 63) {
-                HPSB_ERR(__FUNCTION__ " called with invalid channel");
+                HPSB_ERR("%s called with invalid channel", __FUNCTION__);
                 return;
         }
 
         if (--host->iso_listen_count[channel] == 0) {
-                host->template->devctl(host, ISO_UNLISTEN_CHANNEL, channel);
+                host->ops->devctl(host, ISO_UNLISTEN_CHANNEL, channel);
         }
 }
 
 
-#define DEFINE_MULTIPLEXER(Function)			\
-void highlevel_##Function(struct hpsb_host *host)	\
-{							\
-	struct list_head *lh;				\
-	void (*funcptr)(struct hpsb_host*);		\
-	read_lock(&hl_drivers_lock);			\
-	list_for_each(lh, &hl_drivers) {		\
-		funcptr = list_entry(lh, struct hpsb_highlevel, hl_list) \
-				->op->Function;		\
-		if (funcptr) funcptr(host);		\
-	}						\
-	read_unlock(&hl_drivers_lock);			\
-}
-
-DEFINE_MULTIPLEXER(add_host)
-DEFINE_MULTIPLEXER(remove_host)
-DEFINE_MULTIPLEXER(host_reset)
-#undef DEFINE_MULTIPLEXER
-
-/* Add one host to our list */
-void highlevel_add_one_host (struct hpsb_host *host)
-{
-	if (host->template->initialize_host)
-		if (!host->template->initialize_host(host))
-			goto fail;
-	host->initialized = 1;
-	highlevel_add_host (host);
-	hpsb_reset_bus (host, LONG_RESET);
-fail:
-	host->template->number_of_hosts++;
+void highlevel_add_host(struct hpsb_host *host)
+{
+        struct list_head *entry;
+        struct hpsb_highlevel *hl;
+
+        read_lock(&hl_drivers_lock);
+        list_for_each(entry, &hl_drivers) {
+                hl = list_entry(entry, struct hpsb_highlevel, hl_list);
+
+		hl->op->add_host(host);
+        }
+        read_unlock(&hl_drivers_lock);
+}
+
+void highlevel_remove_host(struct hpsb_host *host)
+{
+        struct list_head *entry;
+        struct hpsb_highlevel *hl;
+
+        write_lock_irq(&hl_drivers_lock);
+	list_for_each(entry, &hl_drivers) {
+                hl = list_entry(entry, struct hpsb_highlevel, hl_list);
+
+		if (hl->op->remove_host)
+			hl->op->remove_host(host);
+        }
+        write_unlock_irq(&hl_drivers_lock);
+}
+
+void highlevel_host_reset(struct hpsb_host *host)
+{
+        struct list_head *entry;
+        struct hpsb_highlevel *hl;
+
+	read_lock(&hl_drivers_lock);
+	list_for_each(entry, &hl_drivers) {
+                hl = list_entry(entry, struct hpsb_highlevel, hl_list);
+
+                if (hl->op->host_reset)
+                        hl->op->host_reset(host);
+        }
+	read_unlock(&hl_drivers_lock);
 }
 
 void highlevel_iso_receive(struct hpsb_host *host, quadlet_t *data,
@@ -242,12 +257,11 @@
 
         while (as->start <= addr) {
                 if (as->end > addr) {
-                        partlength = MIN((unsigned int)(as->end - addr),
-                                         length);
+                        partlength = min(as->end - addr, (u64) length);
 
                         if (as->op->read != NULL) {
-                                rcode = as->op->read(host, nodeid, buffer, addr,
-                                                     partlength);
+                                rcode = as->op->read(host, nodeid, buffer,
+						     addr, partlength);
                         } else {
                                 rcode = RCODE_TYPE_ERROR;
                         }
@@ -288,12 +302,11 @@
 
         while (as->start <= addr) {
                 if (as->end > addr) {
-                        partlength = MIN((unsigned int)(as->end - addr),
-                                         length);
+                        partlength = min(as->end - addr, (u64) length);
 
                         if (as->op->write != NULL) {
-                                rcode = as->op->write(host, nodeid, destid, data,
-						      addr, partlength);
+                                rcode = as->op->write(host, nodeid, destid,
+						      data, addr, partlength);
                         } else {
                                 rcode = RCODE_TYPE_ERROR;
                         }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/highlevel.h linux/drivers/ieee1394/highlevel.h
--- linux.orig/drivers/ieee1394/highlevel.h	2001-07-20 00:48:15.000000000 +0000
+++ linux/drivers/ieee1394/highlevel.h	2002-07-20 01:08:32.000000000 +0000
@@ -91,7 +91,6 @@
 void init_hpsb_highlevel(void);
 
 void highlevel_add_host(struct hpsb_host *host);
-void highlevel_add_one_host(struct hpsb_host *host);
 void highlevel_remove_host(struct hpsb_host *host);
 void highlevel_host_reset(struct hpsb_host *host);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/hosts.c linux/drivers/ieee1394/hosts.c
--- linux.orig/drivers/ieee1394/hosts.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ieee1394/hosts.c	2002-07-20 01:08:33.000000000 +0000
@@ -11,101 +11,125 @@
  */
 
 #include <linux/config.h>
-
 #include <linux/types.h>
+#include <linux/list.h>
 #include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/wait.h>
+#include <linux/slab.h>
 
 #include "ieee1394_types.h"
 #include "hosts.h"
 #include "ieee1394_core.h"
 #include "highlevel.h"
 
+static struct list_head hosts = LIST_HEAD_INIT(hosts);
+static struct list_head host_drivers = LIST_HEAD_INIT(host_drivers);
 
-static LIST_HEAD(templates);
-static spinlock_t templates_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * This function calls the add_host/remove_host hooks for every host currently
- * registered.  Init == TRUE means add_host.
- */
-void hl_all_hosts(struct hpsb_highlevel *hl, int init)
-{
-	struct list_head *tlh, *hlh;
-        struct hpsb_host_template *tmpl;
-        struct hpsb_host *host;
+spinlock_t hosts_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t host_drivers_lock = SPIN_LOCK_UNLOCKED;
 
-        spin_lock(&templates_lock);
 
-	list_for_each(tlh, &templates) {
-                tmpl = list_entry(tlh, struct hpsb_host_template, list);
-		list_for_each(hlh, &tmpl->hosts) {
-			host = list_entry(hlh, struct hpsb_host, list);
-                        if (host->initialized) {
-                                if (init) {
-                                        if (hl->op->add_host) {
-                                                hl->op->add_host(host);
-                                        }
-                                } else {
-                                        if (hl->op->remove_host) {
-                                                hl->op->remove_host(host);
-                                        }
-                                }
-                        }
-                }
-        }
+static int dummy_transmit_packet(struct hpsb_host *h, struct hpsb_packet *p)
+{
+        return 0;
+}
 
-        spin_unlock(&templates_lock);
+static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg)
+{
+        return -1;
 }
 
-int hpsb_inc_host_usage(struct hpsb_host *host)
+static struct hpsb_host_operations dummy_ops = {
+        transmit_packet:  dummy_transmit_packet,
+        devctl:           dummy_devctl
+};
+
+/**
+ * hpsb_ref_host - increase reference count for host controller.
+ * @host: the host controller
+ *
+ * Increase the reference count for the specified host controller.
+ * When holding a reference to a host, the memory allocated for the
+ * host struct will not be freed and the host is guaranteed to be in a
+ * consistent state.  The driver may be unloaded or the controller may
+ * be removed (PCMCIA), but the host struct will remain valid.
+ */
+
+int hpsb_ref_host(struct hpsb_host *host)
 {
-	struct list_head *tlh, *hlh;
-        struct hpsb_host_template *tmpl;
-        int retval = 0;
+        struct list_head *lh;
 	unsigned long flags;
+        int retval = 0;
 
-        spin_lock_irqsave(&templates_lock, flags);
-
-	list_for_each(tlh, &templates) {
-                tmpl = list_entry(tlh, struct hpsb_host_template, list);
-		list_for_each(hlh, &tmpl->hosts) {
-			if (host == list_entry(hlh, struct hpsb_host, list)) {
-                                tmpl->devctl(host, MODIFY_USAGE, 1);
-                                retval = 1;
-                                break;
-                        }
-                }
-		if (retval)
+        spin_lock_irqsave(&hosts_lock, flags);
+        list_for_each(lh, &hosts) {
+                if (host == list_entry(lh, struct hpsb_host, host_list)) {
+                        host->ops->devctl(host, MODIFY_USAGE, 1);
+			host->refcount++;
+                        retval = 1;
 			break;
+        	}
         }
-
-        spin_unlock_irqrestore(&templates_lock, flags);
+        spin_unlock_irqrestore(&hosts_lock, flags);
 
         return retval;
 }
 
-void hpsb_dec_host_usage(struct hpsb_host *host)
+/**
+ * hpsb_unref_host - decrease reference count for host controller.
+ * @host: the host controller
+ *
+ * Decrease the reference count for the specified host controller.
+ * When the reference count reaches zero, the memory allocated for the
+ * &hpsb_host will be freed.
+ */
+
+void hpsb_unref_host(struct hpsb_host *host)
 {
-        host->template->devctl(host, MODIFY_USAGE, 0);
-}
+        unsigned long flags;
 
-/*
- * The following function is exported for module usage.  It will be called from
- * the detect function of a adapter driver.
+        host->ops->devctl(host, MODIFY_USAGE, 0);
+
+        spin_lock_irqsave(&hosts_lock, flags);
+        host->refcount--;
+
+        if (!host->refcount && host->is_shutdown)
+                kfree(host);
+        spin_unlock_irqrestore(&hosts_lock, flags);
+}
+
+/**
+ * hpsb_alloc_host - allocate a new host controller.
+ * @drv: the driver that will manage the host controller
+ * @extra: number of extra bytes to allocate for the driver
+ *
+ * Allocate a &hpsb_host and initialize the general subsystem specific
+ * fields.  If the driver needs to store per host data, as drivers
+ * usually do, the amount of memory required can be specified by the
+ * @extra parameter.  Once allocated, the driver should initialize the
+ * driver specific parts, enable the controller and make it available
+ * to the general subsystem using hpsb_add_host().
+ *
+ * The &hpsb_host is allocated with an single initial reference
+ * belonging to the driver.  Once the driver is done with the struct,
+ * for example, when the driver is unloaded, it should release this
+ * reference using hpsb_unref_host().
+ *
+ * Return Value: a pointer to the &hpsb_host if succesful, %NULL if
+ * no memory was available.
  */
-struct hpsb_host *hpsb_get_host(struct hpsb_host_template *tmpl, 
-                                size_t hd_size)
+
+struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
 {
         struct hpsb_host *h;
 
-        h = vmalloc(sizeof(struct hpsb_host) + hd_size);
+        h = kmalloc(sizeof(struct hpsb_host) + extra, SLAB_KERNEL);
         if (!h) return NULL;
+        memset(h, 0, sizeof(struct hpsb_host) + extra);
 
-        memset(h, 0, sizeof(struct hpsb_host) + hd_size);
-
-        atomic_set(&h->generation, 0);
+	h->hostdata = h + 1;
+        h->driver = drv;
+        h->ops = drv->ops;
+	h->refcount = 1;
 
         INIT_LIST_HEAD(&h->pending_packets);
         spin_lock_init(&h->pending_pkt_lock);
@@ -113,113 +137,90 @@
         sema_init(&h->tlabel_count, 64);
         spin_lock_init(&h->tlabel_lock);
 
+	atomic_set(&h->generation, 0);
+
 	INIT_TQUEUE(&h->timeout_tq, (void (*)(void*))abort_timedouts, h);
 
         h->topology_map = h->csr.topology_map + 3;
         h->speed_map = (u8 *)(h->csr.speed_map + 2);
 
-        h->template = tmpl;
-        if (hd_size)
-                h->hostdata = &h->embedded_hostdata[0];
+	return h;
+}
+
+void hpsb_add_host(struct hpsb_host *host)
+{
+        unsigned long flags;
 
-	list_add_tail(&h->list, &tmpl->hosts);
+        spin_lock_irqsave(&hosts_lock, flags);
+        host->driver->number_of_hosts++;
+        list_add_tail(&host->driver_list, &host->driver->hosts);
+        list_add_tail(&host->host_list, &hosts);
+        spin_unlock_irqrestore(&hosts_lock, flags);
 
-        return h;
+        highlevel_add_host(host);
+        host->ops->devctl(host, RESET_BUS, 0);
 }
 
-static void free_all_hosts(struct hpsb_host_template *tmpl)
+void hpsb_remove_host(struct hpsb_host *host)
 {
-	struct list_head *hlh, *next;
-        struct hpsb_host *host;
+        struct hpsb_host_driver *drv = host->driver;
+        unsigned long flags;
 
-	list_for_each_safe(hlh, next, &tmpl->hosts) {
-		host = list_entry(hlh, struct hpsb_host, list);
-                vfree(host);
-        }
+        host->is_shutdown = 1;
+        host->ops = &dummy_ops;
+        highlevel_remove_host(host);
+
+        spin_lock_irqsave(&hosts_lock, flags);
+        list_del(&host->driver_list);
+        list_del(&host->host_list);
+        drv->number_of_hosts--;
+        spin_unlock_irqrestore(&hosts_lock, flags);
 }
 
 
-static void init_hosts(struct hpsb_host_template *tmpl)
+struct hpsb_host_driver *hpsb_register_lowlevel(struct hpsb_host_operations *op,
+                                                const char *name)
 {
-        int count;
-	struct list_head *hlh;
-        struct hpsb_host *host;
+        struct hpsb_host_driver *drv;
 
-        count = tmpl->detect_hosts(tmpl);
+        drv = kmalloc(sizeof(struct hpsb_host_driver), SLAB_KERNEL);
+        if (!drv) return NULL;
 
-	list_for_each(hlh, &tmpl->hosts) {
-		host = list_entry(hlh, struct hpsb_host, list);
-                if (tmpl->initialize_host(host)) {
-                        host->initialized = 1;
-
-                        highlevel_add_host(host);
-                        hpsb_reset_bus(host, LONG_RESET);
-                }
-        }
+        INIT_LIST_HEAD(&drv->list);
+        INIT_LIST_HEAD(&drv->hosts);
+        drv->number_of_hosts = 0;
+        drv->name = name;
+        drv->ops = op;
+
+        spin_lock(&host_drivers_lock);
+        list_add_tail(&drv->list, &host_drivers);
+        spin_unlock(&host_drivers_lock);
 
-        tmpl->number_of_hosts = count;
-        HPSB_INFO("detected %d %s adapter%s", count, tmpl->name,
-                  (count != 1 ? "s" : ""));
+        return drv;
 }
 
-static void shutdown_hosts(struct hpsb_host_template *tmpl)
+void hpsb_unregister_lowlevel(struct hpsb_host_driver *drv)
 {
-	struct list_head *hlh;
-        struct hpsb_host *host;
-
-	list_for_each(hlh, &tmpl->hosts) {
-		host = list_entry(hlh, struct hpsb_host, list);
-                if (host->initialized) {
-                        highlevel_remove_host(host);
-
-                        host->initialized = 0;
-                        abort_requests(host);
-
-                        tmpl->release_host(host);
-                        while (test_bit(0, &host->timeout_tq.sync)) {
-                                schedule();
-                        }
-                }
-        }
-        free_all_hosts(tmpl);
-        tmpl->release_host(NULL);
+        spin_lock(&host_drivers_lock);
+        list_del(&drv->list);
+        spin_unlock(&host_drivers_lock);
 
-        tmpl->number_of_hosts = 0;
+        kfree(drv);
 }
 
 
 /*
- * The following two functions are exported symbols for module usage.
+ * This function calls the given function for every host currently registered.
  */
-int hpsb_register_lowlevel(struct hpsb_host_template *tmpl)
+void hl_all_hosts(void (*function)(struct hpsb_host*))
 {
-	INIT_LIST_HEAD(&tmpl->hosts);
-	tmpl->number_of_hosts = 0;
-
-        spin_lock(&templates_lock);
-	list_add_tail(&tmpl->list, &templates);
-        spin_unlock(&templates_lock);
-
-	/* PCI cards should be smart and use the PCI detection layer, and
-	 * not this one shot deal. detect_hosts() will be obsoleted soon. */
-	if (tmpl->detect_hosts != NULL) {
-		HPSB_DEBUG("Registered %s driver, initializing now", tmpl->name);
-		init_hosts(tmpl);
-	}
-
-        return 0;
-}
-
-void hpsb_unregister_lowlevel(struct hpsb_host_template *tmpl)
-{
-        shutdown_hosts(tmpl);
+        struct list_head *lh;
+        struct hpsb_host *host;
 
-        if (tmpl->number_of_hosts)
-                HPSB_PANIC("attempted to remove busy host template "
-			   "of %s at address 0x%p", tmpl->name, tmpl);
-	else {
-		spin_lock(&templates_lock);
-		list_del(&tmpl->list);
-		spin_unlock(&templates_lock);
+        spin_lock_irq(&hosts_lock);
+        list_for_each (lh, &hosts) {
+                host = list_entry(lh, struct hpsb_host, host_list);
+                function(host);
 	}
+        spin_unlock_irq(&hosts_lock);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/hosts.h linux/drivers/ieee1394/hosts.h
--- linux.orig/drivers/ieee1394/hosts.h	2001-10-02 04:24:24.000000000 +0000
+++ linux/drivers/ieee1394/hosts.h	2002-07-20 01:08:27.000000000 +0000
@@ -13,11 +13,15 @@
 struct hpsb_packet;
 
 struct hpsb_host {
-/* private fields (hosts, do not use them) */
-	struct list_head list;
+        struct list_head host_list;
+
+        struct hpsb_host_operations *ops;
+        void *hostdata;
 
         atomic_t generation;
 
+        int refcount;
+
         struct list_head pending_packets;
         spinlock_t pending_pkt_lock;
         struct tq_struct timeout_tq;
@@ -27,27 +31,21 @@
         u32 tlabel_pool[2];
         struct semaphore tlabel_count;
         spinlock_t tlabel_lock;
-
-        int reset_retries;
-        quadlet_t *topology_map;
-        u8 *speed_map;
-        struct csr_control csr;
+	u32 tlabel_current;
 
         unsigned char iso_listen_count[64];
 
-/* readonly fields for hosts */
-        struct hpsb_host_template *template;
-
         int node_count; /* number of identified nodes on this bus */
         int selfid_count; /* total number of SelfIDs received */
+	int nodes_active; /* number of nodes that are actually active */
 
         nodeid_t node_id; /* node ID of this host */
         nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
         nodeid_t busmgr_id; /* ID of this bus' bus manager */
 
-        unsigned initialized:1; /* initialized and usable */
-        unsigned in_bus_reset:1; /* in bus reset / SelfID stage */
-        unsigned attempt_root:1; /* attempt to become root during next reset */
+        /* this nodes state */
+        unsigned in_bus_reset:1;
+        unsigned is_shutdown:1;
 
         /* this nodes' duties on the bus */
         unsigned is_root:1;
@@ -55,11 +53,15 @@
         unsigned is_irm:1;
         unsigned is_busmgr:1;
 
-/* fields readable and writeable by the hosts */
+        int reset_retries;
+        quadlet_t *topology_map;
+        u8 *speed_map;
+        struct csr_control csr;
+
+        struct hpsb_host_driver *driver;
+        struct list_head driver_list;
 
-        void *hostdata;
 	struct pci_dev *pdev;
-        int embedded_hostdata[0];
 };
 
 
@@ -88,8 +90,10 @@
          * Return void. */
         CANCEL_REQUESTS,
 
-        /* Decrease module usage count if arg == 0, increase otherwise.  Return
-         * void. */
+        /* Decrease host usage count if arg == 0, increase otherwise.  Return
+         * 1 for success, 0 for failure.  Increase usage may fail if the driver
+         * is in the process of shutting itself down.  Decrease usage can not
+         * fail. */
         MODIFY_USAGE,
 
         /* Start or stop receiving isochronous channel in arg.  Return void.
@@ -109,37 +113,7 @@
         SHORT_RESET
 };
 
-struct hpsb_host_template {
-	struct list_head list;
-
-        struct list_head hosts;
-        int number_of_hosts;
-
-        /* fields above will be ignored and overwritten after registering */
-
-        /* This should be the name of the driver (single word) and must not be
-         * NULL. */
-        const char *name;
-
-        /* This function shall detect all available adapters of this type and
-         * call hpsb_get_host for each one.  The initialize_host function will
-         * be called to actually set up these adapters.  The number of detected
-         * adapters or zero if there are none must be returned.
-         */
-        int (*detect_hosts) (struct hpsb_host_template *template);
-
-        /* After detecting and registering hosts, this function will be called
-         * for every registered host.  It shall set up the host to be fully
-         * functional for bus operations and return 0 for failure.
-         */
-        int (*initialize_host) (struct hpsb_host *host);
-
-        /* To unload modules, this function is provided.  It shall free all
-         * resources this host is using (if host is not NULL) or free all
-         * resources globally allocated by the driver (if host is NULL).
-         */
-        void (*release_host) (struct hpsb_host *host); 
-
+struct hpsb_host_operations {
         /* This function must store a pointer to the configuration ROM into the
          * location referenced to by pointer and return the size of the ROM. It
          * may not fail.  If any allocation is required, it must be done
@@ -175,34 +149,43 @@
                                  quadlet_t data, quadlet_t compare);
 };
 
+struct hpsb_host_driver {
+        struct list_head list;
 
+        struct list_head hosts;
 
-/* mid level internal use */
+        int number_of_hosts;
+        const char *name;
+
+        struct hpsb_host_operations *ops;
+};
+
+
+/* core internal use */
 void register_builtin_lowlevels(void);
 
 /* high level internal use */
 struct hpsb_highlevel;
-void hl_all_hosts(struct hpsb_highlevel *hl, int init);
+void hl_all_hosts(void (*function)(struct hpsb_host*));
 
-/* 
- * These functions are for lowlevel (host) driver use.
- */
-int hpsb_register_lowlevel(struct hpsb_host_template *tmpl);
-void hpsb_unregister_lowlevel(struct hpsb_host_template *tmpl);
 
 /*
- * Get a initialized host structure with hostdata_size bytes allocated in
- * embedded_hostdata for free usage.  Returns NULL for failure.  
+ * In order to prevent hosts from unloading, use hpsb_ref_host().  This prevents
+ * the host from going away (e.g. makes module unloading of the driver
+ * impossible), but still can not guarantee it (e.g. PC-Card being pulled by the
+ * user).  hpsb_ref_host() returns false if host could not be locked.  If it is
+ * successful, host is valid as a pointer until hpsb_unref_host() (not just
+ * until after remove_host).
  */
-struct hpsb_host *hpsb_get_host(struct hpsb_host_template *tmpl, 
-                                size_t hostdata_size);
+int hpsb_ref_host(struct hpsb_host *host);
+void hpsb_unref_host(struct hpsb_host *host);
 
-/*
- * Increase / decrease host usage counter.  Increase function will return true
- * only if successful (host still existed).  Decrease function expects host to
- * exist.
- */
-int hpsb_inc_host_usage(struct hpsb_host *host);
-void hpsb_dec_host_usage(struct hpsb_host *host);
+struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra);
+void hpsb_add_host(struct hpsb_host *host);
+void hpsb_remove_host(struct hpsb_host *h);
+
+struct hpsb_host_driver *hpsb_register_lowlevel(struct hpsb_host_operations *op,
+                                                const char *name);
+void hpsb_unregister_lowlevel(struct hpsb_host_driver *drv);
 
 #endif /* _IEEE1394_HOSTS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/ieee1394.h linux/drivers/ieee1394/ieee1394.h
--- linux.orig/drivers/ieee1394/ieee1394.h	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/ieee1394/ieee1394.h	2002-07-20 01:08:30.000000000 +0000
@@ -39,10 +39,10 @@
 #define ACK_TYPE_ERROR           0xe 
 
 /* Non-standard "ACK codes" for internal use */
-#define ACKX_NONE                -1
-#define ACKX_SEND_ERROR          -2
-#define ACKX_ABORTED             -3
-#define ACKX_TIMEOUT             -4
+#define ACKX_NONE                (-1)
+#define ACKX_SEND_ERROR          (-2)
+#define ACKX_ABORTED             (-3)
+#define ACKX_TIMEOUT             (-4)
 
 
 #define SPEED_100                0x0
@@ -116,7 +116,7 @@
 
 /*
  * Note: these mean to be bit fields of a big endian SelfID as seen on a little
- * endian machine.
+ * endian machine.  Without swapping.
  */
 
 struct selfid {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/ieee1394_core.c linux/drivers/ieee1394/ieee1394_core.c
--- linux.orig/drivers/ieee1394/ieee1394_core.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ieee1394/ieee1394_core.c	2002-07-20 01:08:29.000000000 +0000
@@ -18,9 +18,11 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/proc_fs.h>
 #include <asm/bitops.h>
 #include <asm/byteorder.h>
 #include <asm/semaphore.h>
+#include <asm/smplock.h>
 
 #include "ieee1394_types.h"
 #include "ieee1394.h"
@@ -39,6 +41,10 @@
 MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
 static int disable_nodemgr = 0;
 
+MODULE_PARM(disable_hotplug, "i");
+MODULE_PARM_DESC(disable_hotplug, "Disable hotplug for detected nodes.");
+static int disable_hotplug = 0;
+
 /* We are GPL, so treat us special */
 MODULE_LICENSE("GPL");
 
@@ -106,7 +112,7 @@
                 packet->data_size = data_size;
         }
 
-        INIT_TQ_HEAD(packet->complete_tq);
+        INIT_LIST_HEAD(&packet->complete_tq);
         INIT_LIST_HEAD(&packet->list);
         sema_init(&packet->state_change, 0);
         packet->state = hpsb_unused;
@@ -135,12 +141,8 @@
 
 int hpsb_reset_bus(struct hpsb_host *host, int type)
 {
-        if (!host->initialized) {
-                return 1;
-        }
-
         if (!host->in_bus_reset) {
-                host->template->devctl(host, RESET_BUS, type);
+                host->ops->devctl(host, RESET_BUS, type);
                 return 0;
         } else {
                 return 1;
@@ -151,8 +153,8 @@
 int hpsb_bus_reset(struct hpsb_host *host)
 {
         if (host->in_bus_reset) {
-                HPSB_NOTICE(__FUNCTION__ 
-                            " called while bus reset already in progress");
+                HPSB_NOTICE("%s called while bus reset already in progress",
+			    __FUNCTION__);
                 return 1;
         }
 
@@ -171,14 +173,16 @@
  * Verify num_of_selfids SelfIDs and return number of nodes.  Return zero in
  * case verification failed.
  */
-static int check_selfids(struct hpsb_host *host, unsigned int num_of_selfids)
+static int check_selfids(struct hpsb_host *host)
 {
         int nodeid = -1;
-        int rest_of_selfids = num_of_selfids;
+        int rest_of_selfids = host->selfid_count;
         struct selfid *sid = (struct selfid *)host->topology_map;
         struct ext_selfid *esid;
         int esid_seq = 23;
 
+	host->nodes_active = 0;
+
         while (rest_of_selfids--) {
                 if (!sid->extended) {
                         nodeid++;
@@ -190,9 +194,11 @@
                                 return 0;
                         }
                         
-                        if (sid->contender && sid->link_active) {
-                                host->irm_id = LOCAL_BUS | sid->phy_id;
-                        }
+			if (sid->link_active) {
+				host->nodes_active++;
+				if (sid->contender)
+					host->irm_id = LOCAL_BUS | sid->phy_id;
+			}
                 } else {
                         esid = (struct ext_selfid *)sid;
 
@@ -226,7 +232,8 @@
                         return 0;
         }
 
-        return nodeid + 1;
+	host->node_count = nodeid + 1;
+        return 1;
 }
 
 static void build_speed_map(struct hpsb_host *host, int nodecount)
@@ -318,15 +325,17 @@
 
 void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
 {
+	if (!host->in_bus_reset)
+		HPSB_NOTICE("SelfID completion called outside of bus reset!");
+
         host->node_id = LOCAL_BUS | phyid;
-        host->in_bus_reset = 0;
         host->is_root = isroot;
 
-        host->node_count = check_selfids(host, host->selfid_count);
-        if (!host->node_count) {
+        if (!check_selfids(host)) {
                 if (host->reset_retries++ < 20) {
                         /* selfid stage did not complete without error */
                         HPSB_NOTICE("Error in SelfID stage, resetting");
+			host->in_bus_reset = 0;
                         hpsb_reset_bus(host, LONG_RESET);
                         return;
                 } else {
@@ -346,8 +355,9 @@
         }
 
         host->reset_retries = 0;
-        atomic_inc(&host->generation);
-        if (isroot) host->template->devctl(host, ACT_CYCLE_MASTER, 1);
+        if (isroot) host->ops->devctl(host, ACT_CYCLE_MASTER, 1);
+	atomic_inc(&host->generation);
+	host->in_bus_reset = 0;
         highlevel_host_reset(host);
 }
 
@@ -402,7 +412,7 @@
 {
         struct hpsb_host *host = packet->host;
 
-        if (!host->initialized || host->in_bus_reset 
+        if (host->is_shutdown || host->in_bus_reset
             || (packet->generation != get_hpsb_generation(host))) {
                 return 0;
         }
@@ -431,7 +441,7 @@
         }
 #endif
 
-        return host->template->transmit_packet(host, packet);
+        return host->ops->transmit_packet(host, packet);
 }
 
 static void send_packet_nocare(struct hpsb_packet *packet)
@@ -727,7 +737,7 @@
         struct list_head *lh;
         LIST_HEAD(llist);
 
-        host->template->devctl(host, CANCEL_REQUESTS, 0);
+        host->ops->devctl(host, CANCEL_REQUESTS, 0);
 
         spin_lock_irqsave(&host->pending_pkt_lock, flags);
         list_splice(&host->pending_packets, &llist);
@@ -786,14 +796,209 @@
 }
 
 
+/*
+ * character device dispatching (see ieee1394_core.h)
+ * Dan Maas <dmaas@dcine.com>
+ */
+
+static struct {
+	struct file_operations *file_ops;
+	struct module *module;
+} ieee1394_chardevs[16];
+
+static rwlock_t ieee1394_chardevs_lock = RW_LOCK_UNLOCKED;
+
+static int ieee1394_dispatch_open(struct inode *inode, struct file *file);
+
+static struct file_operations ieee1394_chardev_ops = {
+	owner:	THIS_MODULE,
+	open:	ieee1394_dispatch_open,
+};
+
+devfs_handle_t ieee1394_devfs_handle;
+
+
+/* claim a block of minor numbers */
+int ieee1394_register_chardev(int blocknum,
+			      struct module *module,
+			      struct file_operations *file_ops)
+{
+	int retval;
+	
+	if( (blocknum < 0) || (blocknum > 15) )
+		return -EINVAL;
+
+	write_lock(&ieee1394_chardevs_lock);
+
+	if(ieee1394_chardevs[blocknum].file_ops == NULL) {
+		/* grab the minor block */
+		ieee1394_chardevs[blocknum].file_ops = file_ops;
+		ieee1394_chardevs[blocknum].module = module;
+		
+		retval = 0;
+	} else {
+		/* block already taken */
+		retval = -EBUSY;
+	}
+	
+	write_unlock(&ieee1394_chardevs_lock);
+
+	return retval;
+}
+
+/* release a block of minor numbers */
+void ieee1394_unregister_chardev(int blocknum)
+{
+	if( (blocknum < 0) || (blocknum > 15) )
+		return;
+	
+	write_lock(&ieee1394_chardevs_lock);
+	
+	if(ieee1394_chardevs[blocknum].file_ops) {
+		ieee1394_chardevs[blocknum].file_ops = NULL;
+		ieee1394_chardevs[blocknum].module = NULL;
+	}
+	
+	write_unlock(&ieee1394_chardevs_lock);
+}
+
+/* the point of entry for open() on any ieee1394 character device */
+static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
+{
+	struct file_operations *file_ops;
+	struct module *module;
+	int blocknum;
+	int retval = -ENODEV;
+
+	/*
+	  Maintaining correct module reference counts is tricky here!
+
+	  For Linux v2.4 and later:
+	  
+	  The key thing to remember is that the VFS increments the
+	  reference count of ieee1394 before it calls
+	  ieee1394_dispatch_open().
+
+	  If the open() succeeds, then we need to transfer this extra
+	  reference to the task-specific driver module (e.g. raw1394).
+	  The VFS will deref the driver module automatically when the
+	  file is later released.
+
+	  If the open() fails, then the VFS will drop the
+	  reference count of whatever module file->f_op->owner points
+	  to, immediately after this function returns.
+
+	  The comments below refer to the 2.4 case, since the 2.2
+	  case is trivial.
+	  
+	*/
+
+#define INCREF(mod_) do { struct module *mod = (struct module*) mod_; \
+                          if(mod != NULL) __MOD_INC_USE_COUNT(mod); } while(0)
+#define DECREF(mod_) do { struct module *mod = (struct module*) mod_; \
+                          if(mod != NULL) __MOD_DEC_USE_COUNT(mod); } while(0)
+	
+        /* shift away lower four bits of the minor
+	   to get the index of the ieee1394_driver
+	   we want */
+	
+	blocknum = (minor(inode->i_rdev) >> 4) & 0xF;
+
+	/* printk("ieee1394_dispatch_open(%d)", blocknum); */
+
+	read_lock(&ieee1394_chardevs_lock);
+	module = ieee1394_chardevs[blocknum].module;
+	/* bump the reference count of the driver that
+	   will receive the open() */
+	INCREF(module);
+	file_ops = ieee1394_chardevs[blocknum].file_ops;
+	read_unlock(&ieee1394_chardevs_lock);
+
+	if(file_ops == NULL) {
+		DECREF(module);
+		goto out_fail;
+	}
+
+	/* redirect all subsequent requests to the driver's
+	   own file_operations */
+	file->f_op = file_ops;
+
+	/* at this point BOTH ieee1394 and the task-specific driver have
+	   an extra reference */
+
+	/* follow through with the open() */
+	retval = file_ops->open(inode, file);
+
+	if(retval) {
+		
+		/* if the open() failed, then we need to drop the
+                   extra reference we gave to the task-specific
+                   driver */
+
+		DECREF(module);
+		goto out_fail;
+		
+	} else {
+
+		/* if the open() succeeded, then ieee1394 will be left
+		   with an extra module reference, so we discard it here.*/
+
+		DECREF(THIS_MODULE);
+
+		/* the task-specific driver still has the extra
+		   reference we gave it. This extra reference prevents
+		   the module from unloading while the file is open,
+		   and will be dropped by the VFS when the file is
+		   released. */
+		
+		return 0;
+	}
+	       
+out_fail:
+	/* point the file's f_ops back to ieee1394. The VFS will then
+	   decrement ieee1394's reference count immediately after this
+	   function returns. */
+	
+	file->f_op = &ieee1394_chardev_ops;
+	return retval;
+
+#undef INCREF
+#undef DECREF
+	     
+}
+
+struct proc_dir_entry *ieee1394_procfs_entry;
+
 static int __init ieee1394_init(void)
 {
 	hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet),
 					      0, 0, NULL, NULL);
+
+	ieee1394_devfs_handle = devfs_mk_dir(NULL, "ieee1394", NULL);
+
+	if (register_chrdev(IEEE1394_MAJOR, "ieee1394", &ieee1394_chardev_ops)) {
+		HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR);
+		devfs_unregister(ieee1394_devfs_handle);
+		return -ENODEV;
+	}
+
+#ifdef CONFIG_PROC_FS
+	/* Must be done before we start everything else, since the drivers
+	 * may use it.  */
+	ieee1394_procfs_entry = proc_mkdir( "ieee1394", proc_bus);
+	if (ieee1394_procfs_entry == NULL) {
+		HPSB_ERR("unable to create /proc/bus/ieee1394\n");
+		unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
+		devfs_unregister(ieee1394_devfs_handle);
+		return -ENOMEM;
+	}
+	ieee1394_procfs_entry->owner = THIS_MODULE;
+#endif
+
 	init_hpsb_highlevel();
 	init_csr();
 	if (!disable_nodemgr)
-		init_ieee1394_nodemgr();
+		init_ieee1394_nodemgr(disable_hotplug);
 	else
 		HPSB_INFO("nodemgr functionality disabled");
 
@@ -807,6 +1012,13 @@
 
 	cleanup_csr();
 	kmem_cache_destroy(hpsb_packet_cache);
+
+	unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
+	
+	/* it's ok to pass a NULL devfs_handle to devfs_unregister */
+	devfs_unregister(ieee1394_devfs_handle);
+	
+	remove_proc_entry("ieee1394", proc_bus);
 }
 
 module_init(ieee1394_init);
@@ -815,9 +1027,11 @@
 /* Exported symbols */
 EXPORT_SYMBOL(hpsb_register_lowlevel);
 EXPORT_SYMBOL(hpsb_unregister_lowlevel);
-EXPORT_SYMBOL(hpsb_get_host);
-EXPORT_SYMBOL(hpsb_inc_host_usage);
-EXPORT_SYMBOL(hpsb_dec_host_usage);
+EXPORT_SYMBOL(hpsb_alloc_host);
+EXPORT_SYMBOL(hpsb_add_host);
+EXPORT_SYMBOL(hpsb_remove_host);
+EXPORT_SYMBOL(hpsb_ref_host);
+EXPORT_SYMBOL(hpsb_unref_host);
 EXPORT_SYMBOL(hpsb_speedto_str);
 
 EXPORT_SYMBOL(alloc_hpsb_packet);
@@ -867,12 +1081,19 @@
 EXPORT_SYMBOL(highlevel_add_host);
 EXPORT_SYMBOL(highlevel_remove_host);
 EXPORT_SYMBOL(highlevel_host_reset);
-EXPORT_SYMBOL(highlevel_add_one_host);
 
 EXPORT_SYMBOL(hpsb_guid_get_entry);
 EXPORT_SYMBOL(hpsb_nodeid_get_entry);
-EXPORT_SYMBOL(hpsb_get_host_by_ne);
-EXPORT_SYMBOL(hpsb_guid_fill_packet);
+EXPORT_SYMBOL(hpsb_node_fill_packet);
+EXPORT_SYMBOL(hpsb_node_read);
+EXPORT_SYMBOL(hpsb_node_write);
+EXPORT_SYMBOL(hpsb_node_lock);
 EXPORT_SYMBOL(hpsb_register_protocol);
 EXPORT_SYMBOL(hpsb_unregister_protocol);
 EXPORT_SYMBOL(hpsb_release_unit_directory);
+
+EXPORT_SYMBOL(ieee1394_register_chardev);
+EXPORT_SYMBOL(ieee1394_unregister_chardev);
+EXPORT_SYMBOL(ieee1394_devfs_handle);
+
+EXPORT_SYMBOL(ieee1394_procfs_entry);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/ieee1394_core.h linux/drivers/ieee1394/ieee1394_core.h
--- linux.orig/drivers/ieee1394/ieee1394_core.h	2001-10-02 04:24:24.000000000 +0000
+++ linux/drivers/ieee1394/ieee1394_core.h	2002-07-20 01:08:27.000000000 +0000
@@ -4,6 +4,8 @@
 
 #include <linux/tqueue.h>
 #include <linux/slab.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/proc_fs.h>
 #include <asm/semaphore.h>
 #include "hosts.h"
 
@@ -96,7 +98,6 @@
         return atomic_read(&host->generation);
 }
 
-
 /*
  * Queue packet for transmitting, return 0 for failure.
  */
@@ -152,4 +153,66 @@
 void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
                           int write_acked);
 
+
+/*
+ * CHARACTER DEVICE DISPATCHING
+ *
+ * All ieee1394 character device drivers share the same major number
+ * (major 171).  The 256 minor numbers are allocated to the various
+ * task-specific interfaces (raw1394, video1394, dv1394, etc) in
+ * blocks of 16.
+ *
+ * The core ieee1394.o modules handles the initial open() for all
+ * character devices on major 171; it then dispatches to the
+ * appropriate task-specific driver.
+ *
+ * Minor device number block allocations:
+ *
+ * Block 0  (  0- 15)  raw1394
+ * Block 1  ( 16- 31)  video1394
+ * Block 2  ( 32- 47)  dv1394
+ *
+ * Blocks 3-14 free for future allocation
+ *
+ * Block 15 (240-255)  reserved for drivers under development, etc.
+ */
+
+#define IEEE1394_MAJOR               171
+
+#define IEEE1394_MINOR_BLOCK_RAW1394       0
+#define IEEE1394_MINOR_BLOCK_VIDEO1394     1
+#define IEEE1394_MINOR_BLOCK_DV1394        2
+#define IEEE1394_MINOR_BLOCK_AMDTP         3
+#define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15
+
+/* return the index (within a minor number block) of a file */
+static inline unsigned char ieee1394_file_to_instance(struct file *file)
+{
+	unsigned char minor = minor(file->f_dentry->d_inode->i_rdev);
+	
+	/* return lower 4 bits */
+	return minor & 0xF;
+}
+
+/* 
+ * Task-specific drivers should call ieee1394_register_chardev() to
+ * request a block of 16 minor numbers.
+ *
+ * Returns 0 if the request was successful, -EBUSY if the block was
+ * already taken.
+ */
+
+int  ieee1394_register_chardev(int blocknum,           /* 0-15 */
+			       struct module *module,  /* THIS_MODULE */
+			       struct file_operations *file_ops);
+
+/* release a block of minor numbers */
+void ieee1394_unregister_chardev(int blocknum);
+
+/* the devfs handle for /dev/ieee1394; NULL if devfs is not in use */
+extern devfs_handle_t ieee1394_devfs_handle;
+
+/* the proc_fs entry for /proc/ieee1394 */
+extern struct proc_dir_entry *ieee1394_procfs_entry;
+
 #endif /* _IEEE1394_CORE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/ieee1394_transactions.c linux/drivers/ieee1394/ieee1394_transactions.c
--- linux.orig/drivers/ieee1394/ieee1394_transactions.c	2001-10-02 04:24:24.000000000 +0000
+++ linux/drivers/ieee1394/ieee1394_transactions.c	2002-07-20 01:08:31.000000000 +0000
@@ -169,8 +169,9 @@
  */
 int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)
 {
-	int tlabel;
+	int tlabel = 0;
 	unsigned long flags;
+	int found_tlabel = 0;
 
 	if (wait) {
 		down(&host->tlabel_count);
@@ -180,15 +181,18 @@
 
 	spin_lock_irqsave(&host->tlabel_lock, flags);
 
-	if (host->tlabel_pool[0] != ~0) {
-		tlabel = ffz(host->tlabel_pool[0]);
-		host->tlabel_pool[0] |= 1 << tlabel;
-	} else {
-		tlabel = ffz(host->tlabel_pool[1]);
-		host->tlabel_pool[1] |= 1 << tlabel;
-		tlabel += 32;
+	while (!found_tlabel) {
+		tlabel = host->tlabel_current;
+		if (tlabel < 32 && !(host->tlabel_pool[0] & 1 << tlabel)) {
+			host->tlabel_pool[0] |= 1 << tlabel;
+			found_tlabel = 1;
+		} else if (!(host->tlabel_pool[1] & 1 << (tlabel - 32))) {
+			host->tlabel_pool[1] |= 1 << (tlabel - 32);
+			found_tlabel = 1;
+		}
+		host->tlabel_current = (host->tlabel_current + 1) % 64;
 	}
-
+	
 	spin_unlock_irqrestore(&host->tlabel_lock, flags);
 
 	return tlabel;
@@ -246,7 +250,7 @@
                                  packet->node_id);
                         return -EAGAIN;
                 }
-                HPSB_PANIC("reached unreachable code 1 in " __FUNCTION__);
+                HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
 
         case ACK_BUSY_X:
         case ACK_BUSY_A:
@@ -290,7 +294,7 @@
                 return -EAGAIN;
         }
 
-        HPSB_PANIC("reached unreachable code 2 in " __FUNCTION__);
+        HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
 }
 
 
@@ -415,8 +419,8 @@
  * avoid in kernel buffers for user space callers
  */
 
-int hpsb_read(struct hpsb_host *host, nodeid_t node, u64 addr,
-              quadlet_t *buffer, size_t length)
+int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+	      u64 addr, quadlet_t *buffer, size_t length)
 {
         struct hpsb_packet *packet;
         int retval = 0;
@@ -447,7 +451,7 @@
                 return -ENOMEM;
         }
 
-	packet->generation = get_hpsb_generation(host);
+	packet->generation = generation;
         if (!hpsb_send_packet(packet)) {
 		retval = -EINVAL;
 		goto hpsb_read_fail;
@@ -496,8 +500,8 @@
 	return packet;
 }
 
-int hpsb_write(struct hpsb_host *host, nodeid_t node, u64 addr,
-	       quadlet_t *buffer, size_t length)
+int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+	       u64 addr, quadlet_t *buffer, size_t length)
 {
 	struct hpsb_packet *packet;
 	int retval;
@@ -522,7 +526,7 @@
 	if (!packet)
 		return -ENOMEM;
 
-	packet->generation = get_hpsb_generation(host);
+	packet->generation = generation;
         if (!hpsb_send_packet(packet)) {
 		retval = -EINVAL;
 		goto hpsb_write_fail;
@@ -541,8 +545,8 @@
 
 
 /* We need a hpsb_lock64 function for the 64 bit equivalent.  Probably. */
-int hpsb_lock(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode,
-              quadlet_t *data, quadlet_t arg)
+int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+	      u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
 {
         struct hpsb_packet *packet;
         int retval = 0, length;
@@ -588,7 +592,7 @@
         }
         fill_async_lock(packet, addr, extcode, length);
 
-	packet->generation = get_hpsb_generation(host);
+	packet->generation = generation;
         if (!hpsb_send_packet(packet)) {
 		retval = -EINVAL;
 		goto hpsb_lock_fail;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/ieee1394_transactions.h linux/drivers/ieee1394/ieee1394_transactions.h
--- linux.orig/drivers/ieee1394/ieee1394_transactions.h	2001-07-20 00:48:15.000000000 +0000
+++ linux/drivers/ieee1394/ieee1394_transactions.h	2002-07-20 01:08:31.000000000 +0000
@@ -63,14 +63,16 @@
  * The generic read, write and lock functions.  All recognize the local node ID
  * and act accordingly.  Read and write automatically use quadlet commands if
  * length == 4 and and block commands otherwise (however, they do not yet
- * support lengths that are not a multiple of 4).
+ * support lengths that are not a multiple of 4).  You must explicitly specifiy
+ * the generation for which the node ID is valid, to avoid sending packets to
+ * the wrong nodes when we race with a bus reset.
  */
-int hpsb_read(struct hpsb_host *host, nodeid_t node, u64 addr,
-              quadlet_t *buffer, size_t length);
-int hpsb_write(struct hpsb_host *host, nodeid_t node, u64 addr,
-               quadlet_t *buffer, size_t length);
-int hpsb_lock(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode,
-              quadlet_t *data, quadlet_t arg);
+int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+	      u64 addr, quadlet_t *buffer, size_t length);
+int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+	       u64 addr, quadlet_t *buffer, size_t length);
+int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+	      u64 addr, int extcode, quadlet_t *data, quadlet_t arg);
 
 /* Generic packet creation. Used by hpsb_write. Also useful for protocol
  * drivers that want to implement their own hpsb_write replacement.  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/ieee1394_types.h linux/drivers/ieee1394/ieee1394_types.h
--- linux.orig/drivers/ieee1394/ieee1394_types.h	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/ieee1394/ieee1394_types.h	2002-07-20 01:08:39.000000000 +0000
@@ -6,18 +6,18 @@
 #include <linux/types.h>
 #include <linux/version.h>
 #include <linux/list.h>
+#include <linux/init.h>
 #include <asm/byteorder.h>
 
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#include "linux22compat.h"
-#else
-#define V22_COMPAT_MOD_INC_USE_COUNT do {} while (0)
-#define V22_COMPAT_MOD_DEC_USE_COUNT do {} while (0)
-#define OWNER_THIS_MODULE owner: THIS_MODULE,
+/* The great kdev_t changeover in 2.5.x */
+#include <linux/kdev_t.h>
+#ifndef minor
+#define minor(dev) MINOR(dev)
+#endif
 
-#define INIT_TQ_LINK(tq) INIT_LIST_HEAD(&(tq).list)
-#define INIT_TQ_HEAD(tq) INIT_LIST_HEAD(&(tq))
+#ifndef __devexit_p
+#define __devexit_p(x) x
 #endif
 
 /* This showed up around this time */
@@ -37,11 +37,7 @@
 
 #endif /* Linux version < 2.4.12 */
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
-#include <asm/spinlock.h>
-#else
 #include <linux/spinlock.h>
-#endif
 
 #ifndef list_for_each_safe
 #define list_for_each_safe(pos, n, head) \
@@ -50,6 +46,10 @@
 
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5)
+#define pte_offset_kernel pte_offset
+#endif
+
 #ifndef MIN
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
@@ -67,7 +67,8 @@
 #define LOCAL_BUS 0xffc0
 #define ALL_NODES 0x003f
 
-#define NODE_BUS_FMT    "%d:%d"
+/* Can be used to consistently print a node/bus ID. */
+#define NODE_BUS_FMT    "%02d:%04d"
 #define NODE_BUS_ARGS(nodeid) \
 	(nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/nodemgr.c linux/drivers/ieee1394/nodemgr.c
--- linux.orig/drivers/ieee1394/nodemgr.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ieee1394/nodemgr.c	2002-07-20 01:08:24.000000000 +0000
@@ -12,10 +12,14 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <asm/byteorder.h>
-#include <asm/atomic.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/kmod.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif
 
 #include "ieee1394_types.h"
 #include "ieee1394.h"
@@ -57,23 +61,254 @@
 static LIST_HEAD(host_info_list);
 static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
 
+/* Disables use of the hotplug calls.  */
+static int nodemgr_disable_hotplug = 0;
+
 struct host_info {
 	struct hpsb_host *host;
-	struct tq_struct task;
 	struct list_head list;
+	struct completion exited;
+	struct semaphore reset_sem;
+	int pid;
 };
 
+#ifdef CONFIG_PROC_FS
+
+#define PUTF(fmt, args...) out += sprintf(out, fmt, ## args)
+
+static int raw1394_read_proc(char *page, char **start, off_t off,
+			     int count, int *eof, void *data)
+{
+	struct list_head *lh;
+	struct node_entry *ne;
+	int len;
+	char *out = page;
+
+	list_for_each(lh, &node_list) {
+		struct list_head *l;
+		int ud_count = 0;
+
+		ne = list_entry(lh, struct node_entry, list);
+		if (!ne)
+			continue;
+
+		PUTF("Node[" NODE_BUS_FMT "]  GUID[%016Lx]:\n",
+		     NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid);
+
+		/* Generic Node information */
+		PUTF("  Vendor ID: `%s' [0x%06x]\n",
+		     ne->vendor_name ?: "Unknown", ne->vendor_id);
+		PUTF("  Capabilities: 0x%06x\n", ne->capabilities);
+		PUTF("  Bus Options:\n");
+		PUTF("    IRMC(%d) CMC(%d) ISC(%d) BMC(%d) PMC(%d) GEN(%d)\n"
+		     "    LSPD(%d) MAX_REC(%d) CYC_CLK_ACC(%d)\n",
+		     ne->busopt.irmc, ne->busopt.cmc, ne->busopt.isc, ne->busopt.bmc,
+		     ne->busopt.pmc, ne->busopt.generation, ne->busopt.lnkspd,
+		     ne->busopt.max_rec, ne->busopt.cyc_clk_acc);
+
+		/* If this is the host entry, output some info about it aswell */
+		if (ne->host != NULL && ne->host->node_id == ne->nodeid) {
+			PUTF("  Host Node Status:\n");
+			PUTF("    Host Driver     : %s\n", ne->host->driver->name);
+			PUTF("    Nodes connected : %d\n", ne->host->node_count);
+			PUTF("    Nodes active    : %d\n", ne->host->nodes_active);
+			PUTF("    SelfIDs received: %d\n", ne->host->selfid_count);
+			PUTF("    Irm ID          : [" NODE_BUS_FMT "]\n",
+			     NODE_BUS_ARGS(ne->host->irm_id));
+			PUTF("    BusMgr ID       : [" NODE_BUS_FMT "]\n",
+			     NODE_BUS_ARGS(ne->host->busmgr_id));
+			PUTF("    In Bus Reset    : %s\n", ne->host->in_bus_reset ? "yes" : "no");
+			PUTF("    Root            : %s\n", ne->host->is_root ? "yes" : "no");
+			PUTF("    Cycle Master    : %s\n", ne->host->is_cycmst ? "yes" : "no");
+			PUTF("    IRM             : %s\n", ne->host->is_irm ? "yes" : "no");
+			PUTF("    Bus Manager     : %s\n", ne->host->is_busmgr ? "yes" : "no");
+		}
+
+		/* Now the unit directories */
+		list_for_each (l, &ne->unit_directories) {
+			struct unit_directory *ud = list_entry (l, struct unit_directory, node_list);
+			PUTF("  Unit Directory %d:\n", ud_count++);
+			if (ud->flags & UNIT_DIRECTORY_VENDOR_ID)
+				PUTF("    Vendor/Model ID: %s [%06x]",
+				     ud->vendor_name ?: "Unknown", ud->vendor_id);
+			else if (ud->flags & UNIT_DIRECTORY_MODEL_ID) /* Have to put something */
+				PUTF("    Vendor/Model ID: %s [%06x]",
+				      ne->vendor_name ?: "Unknown", ne->vendor_id);
+			if (ud->flags & UNIT_DIRECTORY_MODEL_ID)
+				PUTF(" / %s [%06x]", ud->model_name ?: "Unknown", ud->model_id);
+			PUTF("\n");
+			if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
+				PUTF("    Software Specifier ID: %06x\n", ud->specifier_id);
+			if (ud->flags & UNIT_DIRECTORY_VERSION)
+				PUTF("    Software Version: %06x\n", ud->version);
+			if (ud->driver)
+				PUTF("    Driver: %s\n", ud->driver->name);
+			PUTF("    Length (in quads): %d\n", ud->count);
+		}
+
+	}
+
+	len = out - page;
+	len -= off;
+	if (len < count) {
+		*eof = 1;
+		if (len <= 0)
+			return 0;
+	} else
+		len = count;
+
+        *start = page + off;
+
+	return len;
+}
+
+#undef PUTF
+#endif /* CONFIG_PROC_FS */
+
 static void nodemgr_process_config_rom(struct node_entry *ne, 
 				       quadlet_t busoptions);
 
+static int nodemgr_read_quadlet(struct hpsb_host *host,
+				nodeid_t nodeid, unsigned int generation,
+				octlet_t address, quadlet_t *quad)
+{
+	int i;
+	int ret = 0;
+
+	for (i = 0; i < 3; i++) {
+		ret = hpsb_read(host, nodeid, generation, address, quad, 4);
+		if (!ret)
+			break;
+	}
+	*quad = be32_to_cpu(*quad);
+
+	return ret;
+}
+
+static int nodemgr_size_text_leaf(struct hpsb_host *host,
+				  nodeid_t nodeid, unsigned int generation,
+				  octlet_t address)
+{
+	quadlet_t quad;
+	int size = 0;
+	if (nodemgr_read_quadlet(host, nodeid, generation, address, &quad))
+		return -1;
+	if (CONFIG_ROM_KEY(quad) == CONFIG_ROM_DESCRIPTOR_LEAF) {
+		/* This is the offset.  */
+		address += 4 * CONFIG_ROM_VALUE(quad); 
+		if (nodemgr_read_quadlet(host, nodeid, generation, address, &quad))
+			return -1;
+		/* Now we got the size of the text descriptor leaf. */
+		size = CONFIG_ROM_LEAF_LENGTH(quad);
+	}
+	return size;
+}
+
+static int nodemgr_read_text_leaf(struct node_entry *ne,
+				  octlet_t address,
+				  quadlet_t *quadp)
+{
+	quadlet_t quad;
+	int i, size, ret;
+
+	if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, &quad)
+	    && CONFIG_ROM_KEY(quad) != CONFIG_ROM_DESCRIPTOR_LEAF)
+		return -1;
+
+	/* This is the offset.  */
+	address += 4 * CONFIG_ROM_VALUE(quad);
+	if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, &quad))
+		return -1;
+
+	/* Now we got the size of the text descriptor leaf. */
+	size = CONFIG_ROM_LEAF_LENGTH(quad) - 2;
+	if (size <= 0)
+		return -1;
+
+	address += 4;
+	for (i = 0; i < 2; i++, address += 4, quadp++) {
+		if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, quadp))
+			return -1;
+	}
+
+	/* Now read the text string.  */
+	ret = -ENXIO;
+	for (; size > 0; size--, address += 4, quadp++) {
+		for (i = 0; i < 3; i++) {
+			ret = hpsb_read(ne->host, ne->nodeid, ne->generation, address, quadp, 4);
+			if (ret != -EAGAIN)
+				break;
+		}
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static struct node_entry *nodemgr_scan_root_directory
+	(struct hpsb_host *host, nodeid_t nodeid, unsigned int generation)
+{
+	octlet_t address;
+	quadlet_t quad;
+	int length;
+	int code, size, total_size;
+	struct node_entry *ne;
+
+	address = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
+	
+	if (nodemgr_read_quadlet(host, nodeid, generation, address, &quad))
+		return NULL;
+	address += 4 + CONFIG_ROM_BUS_INFO_LENGTH(quad) * 4;
+
+	if (nodemgr_read_quadlet(host, nodeid, generation, address, &quad))
+		return NULL;
+	length = CONFIG_ROM_ROOT_LENGTH(quad);
+	address += 4;
+
+	size = 0;
+	total_size = sizeof(struct node_entry);
+	for (; length > 0; length--, address += 4) {
+		if (nodemgr_read_quadlet(host, nodeid, generation, address, &quad))
+			return NULL;
+		code = CONFIG_ROM_KEY(quad);
+
+		if (code == CONFIG_ROM_VENDOR_ID && length > 0) {
+			/* Check if there is a text descriptor leaf
+			   immediately after this.  */
+			size = nodemgr_size_text_leaf(host, nodeid, generation,
+						      address + 4);
+			if (size > 0) {
+				address += 4;
+				length--;
+				total_size += (size + 1) * sizeof (quadlet_t);
+			}
+			else if (size < 0)
+				return NULL;
+		}
+	}
+	ne = kmalloc(total_size, SLAB_ATOMIC);
+	if (ne != NULL) {
+		if (size != 0) {
+			ne->vendor_name
+				= (const char *) &(ne->quadlets[2]);
+			ne->quadlets[size] = 0;
+		}
+		else {
+			ne->vendor_name = NULL;
+		}
+	}
+	return ne; 
+}
 
 static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoptions,
-					      struct hpsb_host *host, nodeid_t nodeid)
+					      struct hpsb_host *host,
+					      nodeid_t nodeid, unsigned int generation)
 {
         struct node_entry *ne;
         unsigned long flags;
 
-        ne = kmalloc(sizeof(struct node_entry), SLAB_ATOMIC);
+	ne = nodemgr_scan_root_directory (host, nodeid, generation);
         if (!ne) return NULL;
 
         INIT_LIST_HEAD(&ne->list);
@@ -81,7 +316,7 @@
         ne->host = host;
         ne->nodeid = nodeid;
         ne->guid = guid;
-	atomic_set(&ne->generation, get_hpsb_generation(ne->host));
+	ne->generation = generation;
 
         write_lock_irqsave(&node_lock, flags);
         list_add_tail(&ne->list, &node_list);
@@ -89,9 +324,10 @@
 
 	nodemgr_process_config_rom (ne, busoptions);
 
-	HPSB_DEBUG("%s added: node " NODE_BUS_FMT ", GUID %016Lx",
-		   (host->node_id == nodeid) ? "Local host" : "Device",
-		   NODE_BUS_ARGS(nodeid), (unsigned long long)guid);
+	HPSB_DEBUG("%s added: Node[" NODE_BUS_FMT "]  GUID[%016Lx]  [%s]",
+		   (host->node_id == nodeid) ? "Host" : "Device",
+		   NODE_BUS_ARGS(nodeid), (unsigned long long)guid,
+		   ne->vendor_name ?: "Unknown");
 
         return ne;
 }
@@ -122,30 +358,102 @@
 	return NULL;
 }
 
-int nodemgr_read_quadlet(struct node_entry *ne,
-			 octlet_t address, quadlet_t *quad)
+static struct unit_directory *nodemgr_scan_unit_directory
+	(struct node_entry *ne, octlet_t address)
 {
-	int i;
-	int ret = 0;
+	struct unit_directory *ud;
+	quadlet_t quad;
+	u8 flags, todo;
+	int length, size, total_size, count;
+	int vendor_name_size, model_name_size;
 
-	for (i = 0; i < 3; i++) {
-		ret = hpsb_read(ne->host, ne->nodeid, address, quad, 4);
-		if (ret != -EAGAIN)
+	if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, &quad))
+		return NULL;
+	length = CONFIG_ROM_DIRECTORY_LENGTH(quad) ;
+	address += 4;
+
+	size = 0;
+	total_size = sizeof (struct unit_directory);
+	flags = 0;
+	count = 0;
+	vendor_name_size = 0;
+	model_name_size = 0;
+	for (; length > 0; length--, address += 4) {
+		int code;
+		quadlet_t value;
+
+		if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation,
+					 address, &quad))
+			return NULL;
+		code = CONFIG_ROM_KEY(quad);
+		value = CONFIG_ROM_VALUE(quad);
+
+		todo = 0;
+		switch (code) {
+		case CONFIG_ROM_VENDOR_ID:
+			todo = UNIT_DIRECTORY_VENDOR_TEXT;
 			break;
-	}
-	*quad = be32_to_cpu(*quad);
 
-	return ret;
-}
+		case CONFIG_ROM_MODEL_ID:
+			todo = UNIT_DIRECTORY_MODEL_TEXT;
+			break;
+
+		case CONFIG_ROM_SPECIFIER_ID:
+		case CONFIG_ROM_UNIT_SW_VERSION:
+			break;
+
+		case CONFIG_ROM_DESCRIPTOR_LEAF:
+		case CONFIG_ROM_DESCRIPTOR_DIRECTORY:
+			/* TODO: read strings... icons? */
+			break;
 
-#define CONFIG_ROM_VENDOR_ID		0x03
-#define CONFIG_ROM_MODEL_ID		0x17
-#define CONFIG_ROM_NODE_CAPABILITES	0x0C
-#define CONFIG_ROM_UNIT_DIRECTORY	0xd1
-#define CONFIG_ROM_SPECIFIER_ID		0x12 
-#define CONFIG_ROM_VERSION		0x13
-#define CONFIG_ROM_DESCRIPTOR_LEAF	0x81
-#define CONFIG_ROM_DESCRIPTOR_DIRECTORY	0xc1
+		default:
+			/* Which types of quadlets do we want to
+			   store?  Only count immediate values and
+			   CSR offsets for now.  */
+			code &= CONFIG_ROM_KEY_TYPE_MASK;
+			if ((code & 0x80) == 0)
+				count++;
+			break;
+		}
+
+		if (todo && length > 0) {
+			/* Check if there is a text descriptor leaf
+			   immediately after this.  */
+			size = nodemgr_size_text_leaf(ne->host,
+						      ne->nodeid,
+						      ne->generation,
+						      address + 4);
+
+			if (todo == UNIT_DIRECTORY_VENDOR_TEXT)
+				vendor_name_size = size;
+			else
+				model_name_size = size;
+
+			if (size > 0) {
+				address += 4;
+				length--;
+				flags |= todo;
+				total_size += (size + 1) * sizeof (quadlet_t);
+			}
+			else if (size < 0)
+				return NULL;
+		}
+	}
+	total_size += count * sizeof (quadlet_t);
+	ud = kmalloc (total_size, GFP_KERNEL);
+	if (ud != NULL) {
+		memset (ud, 0, sizeof *ud);
+		ud->flags = flags;
+		ud->count = count;
+		ud->vendor_name_size = vendor_name_size;
+		ud->model_name_size = model_name_size;
+		/* If there is no vendor name in the unit directory,
+		   use the one in the root directory.  */
+		ud->vendor_name = ne->vendor_name;
+	}
+	return ud;
+}
 
 /* This implementation currently only scans the config rom and its
  * immediate unit directories looking for software_id and
@@ -156,41 +464,73 @@
 					   octlet_t address)
 {
 	struct unit_directory *ud;
-	octlet_t a;
 	quadlet_t quad;
-	int length, i;
+	quadlet_t *infop;
+	int length;
 
-	if (!(ud = kmalloc (sizeof *ud, GFP_KERNEL)))
+	if (!(ud = nodemgr_scan_unit_directory(ne, address)))
 		goto unit_directory_error;
 
-	memset (ud, 0, sizeof *ud);
 	ud->ne = ne;
 	ud->address = address;
-	ud->arb_count = 0;
 
-	if (nodemgr_read_quadlet(ne, address, &quad))
+	if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation,
+				 address, &quad))
 		goto unit_directory_error;
-	length = quad >> 16;
-	a = address + 4;
+	length = CONFIG_ROM_DIRECTORY_LENGTH(quad) ;
+	address += 4;
 
-	for (i = 0; i < length; i++, a += 4) {
+	infop = (quadlet_t *) ud->quadlets;
+	for (; length > 0; length--, address += 4, infop++) {
 		int code;
 		quadlet_t value;
+		quadlet_t *quadp;
 
-		if (nodemgr_read_quadlet(ne, a, &quad))
+		if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation,
+					 address, &quad))
 			goto unit_directory_error;
-		code = quad >> 24;
-		value = quad & 0xffffff;
+		code = CONFIG_ROM_KEY(quad) ;
+		value = CONFIG_ROM_VALUE(quad);
 
 		switch (code) {
 		case CONFIG_ROM_VENDOR_ID:
 			ud->vendor_id = value;
 			ud->flags |= UNIT_DIRECTORY_VENDOR_ID;
+			if ((ud->flags & UNIT_DIRECTORY_VENDOR_TEXT) != 0) {
+				length--;
+				address += 4;
+				quadp = &(ud->quadlets[ud->count]);
+				if (nodemgr_read_text_leaf(ne, address,
+							   quadp) == 0
+				    && quadp[0] == 0
+				    && quadp[1] == 0) {
+				    	/* We only support minimal
+					   ASCII and English. */
+					quadp[ud->vendor_name_size] = 0;
+					ud->vendor_name
+						= (const char *) &(quadp[2]);
+				}
+			}
 			break;
 
 		case CONFIG_ROM_MODEL_ID:
 			ud->model_id = value;
 			ud->flags |= UNIT_DIRECTORY_MODEL_ID;
+			if ((ud->flags & UNIT_DIRECTORY_MODEL_TEXT) != 0) {
+				length--;
+				address += 4;
+				quadp = &(ud->quadlets[ud->count + ud->vendor_name_size + 1]);
+				if (nodemgr_read_text_leaf(ne, address,
+							   quadp) == 0
+				    && quadp[0] == 0
+				    && quadp[1] == 0) {
+				    	/* We only support minimal
+					   ASCII and English. */
+					quadp[ud->model_name_size] = 0;
+					ud->model_name
+						= (const char *) &(quadp[2]);
+				}
+			}
 			break;
 
 		case CONFIG_ROM_SPECIFIER_ID:
@@ -198,7 +538,7 @@
 			ud->flags |= UNIT_DIRECTORY_SPECIFIER_ID;
 			break;
 
-		case CONFIG_ROM_VERSION:
+		case CONFIG_ROM_UNIT_SW_VERSION:
 			ud->version = value;
 			ud->flags |= UNIT_DIRECTORY_VERSION;
 			break;
@@ -209,12 +549,13 @@
 			break;
 
 		default:
-			if (ud->arb_count < 16) {
-				/* Place them in the arbitrary pairs */
-				ud->arb_keys[ud->arb_count] = code;
-				ud->arb_values[ud->arb_count] = value;
-				ud->arb_count++;
-			}
+			/* Which types of quadlets do we want to
+			   store?  Only count immediate values and
+			   CSR offsets for now.  */
+			code &= CONFIG_ROM_KEY_TYPE_MASK;
+			if ((code & 0x80) == 0)
+				*infop = quad;
+			break;
 		}
 	}
 
@@ -233,53 +574,74 @@
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 	struct list_head *l;
 
-	HPSB_DEBUG("vendor_id=0x%06x, capabilities=0x%06x",
-		   ne->vendor_id, ne->capabilities);
+	HPSB_DEBUG("vendor_id=0x%06x [%s], capabilities=0x%06x",
+		   ne->vendor_id, ne->vendor_name ?: "Unknown",
+		   ne->capabilities);
 	list_for_each (l, &ne->unit_directories) {
 		struct unit_directory *ud = list_entry (l, struct unit_directory, node_list);
 		HPSB_DEBUG("unit directory:");
 		if (ud->flags & UNIT_DIRECTORY_VENDOR_ID)
-			HPSB_DEBUG("  vendor_id=0x%06x ", ud->vendor_id);
+			HPSB_DEBUG("  vendor_id=0x%06x [%s]",
+				   ud->vendor_id,
+				   ud->vendor_name ?: "Unknown");
 		if (ud->flags & UNIT_DIRECTORY_MODEL_ID)
-			HPSB_DEBUG("  model_id=0x%06x ", ud->model_id);
+			HPSB_DEBUG("  model_id=0x%06x [%s]",
+				   ud->model_id,
+				   ud->model_name ?: "Unknown");
 		if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
 			HPSB_DEBUG("  sw_specifier_id=0x%06x ", ud->specifier_id);
 		if (ud->flags & UNIT_DIRECTORY_VERSION)
 			HPSB_DEBUG("  sw_version=0x%06x ", ud->version);
 	}
-#else
-	return;
 #endif
+	return;
 }
 
 static void nodemgr_process_root_directory(struct node_entry *ne)
 {
 	octlet_t address;
 	quadlet_t quad;
-	int length, i;
+	int length;
 
 	address = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
 	
-	if (nodemgr_read_quadlet(ne, address, &quad))
+	if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation,
+				 address, &quad))
 		return;
-	address += 4 + (quad >> 24) * 4;
+	address += 4 + CONFIG_ROM_BUS_INFO_LENGTH(quad) * 4;
 
-	if (nodemgr_read_quadlet(ne, address, &quad))
+	if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation,
+				 address, &quad))
 		return;
-	length = quad >> 16;
+	length = CONFIG_ROM_ROOT_LENGTH(quad);
 	address += 4;
 
-	for (i = 0; i < length; i++, address += 4) {
+	for (; length > 0; length--, address += 4) {
 		int code, value;
 
-		if (nodemgr_read_quadlet(ne, address, &quad))
+		if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation,
+					 address, &quad))
 			return;
-		code = quad >> 24;
-		value = quad & 0xffffff;
+		code = CONFIG_ROM_KEY(quad);
+		value = CONFIG_ROM_VALUE(quad);
 
 		switch (code) {
 		case CONFIG_ROM_VENDOR_ID:
 			ne->vendor_id = value;
+			/* Now check if there is a vendor name text
+			   string.  */
+			if (ne->vendor_name != NULL) {
+				length--;
+				address += 4;
+				if (nodemgr_read_text_leaf(ne, address,
+							   ne->quadlets)
+				    != 0
+				    || ne->quadlets [0] != 0
+				    || ne->quadlets [1] != 0)
+				    	/* We only support minimal
+					   ASCII and English. */
+					ne->vendor_name = NULL;
+			}
 			break;
 
 		case CONFIG_ROM_NODE_CAPABILITES:
@@ -307,6 +669,10 @@
 	char *argv [3], **envp, *buf, *scratch;
 	int i = 0, value;
 
+	/* User requested to disable hotplug when module was loaded. */
+	if (nodemgr_disable_hotplug)
+		return;
+
 	if (!hotplug_path [0])
 		return;
 	if (!current->fs->root)
@@ -578,7 +944,8 @@
  * the to take whatever actions required.
  */
 static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions,
-                               struct hpsb_host *host, nodeid_t nodeid)
+                               struct hpsb_host *host,
+				nodeid_t nodeid, unsigned int generation)
 {
 	struct list_head *lh;
 	struct unit_directory *ud;
@@ -593,7 +960,7 @@
 		nodemgr_process_config_rom (ne, busoptions);
 
 	/* Since that's done, we can declare this record current */
-	atomic_set(&ne->generation, get_hpsb_generation(ne->host));
+	ne->generation = generation;
 
 	list_for_each (lh, &ne->unit_directories) {
 		ud = list_entry (lh, struct unit_directory, node_list);
@@ -602,70 +969,75 @@
 	}
 }
 
-static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid,
+static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned int generation,
 			      quadlet_t *buffer, int buffer_length)
 {
-	octlet_t base = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
-	int retries = 3;
-	int header_count;
+	octlet_t addr = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
 	unsigned header_size;
-	quadlet_t quad;
-
-retry_configrom:
-
-	if (!retries--) {
-		HPSB_ERR("Giving up on node " NODE_BUS_FMT
-			 " for ConfigROM probe, too many errors",
-			 NODE_BUS_ARGS(nodeid));
-		return -1;
-	}
+	int i;
 
-	header_count = 0;
-	header_size = 0;
+	/* IEEE P1212 says that devices should support 64byte block
+	 * reads, aligned on 64byte boundaries. That doesn't seem to
+	 * work though, and we are forced to doing quadlet sized
+	 * reads.  */
 
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 	HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT,
 		  NODE_BUS_ARGS(nodeid));
 #endif
+	/* 
+	 * Must retry a few times if config rom read returns zero (how long?). Will
+	 * not normally occur, but we should do the right thing. For example, with
+	 * some sbp2 devices, the bridge chipset cannot return valid config rom reads
+	 * immediately after power-on, since they need to detect the type of 
+	 * device attached (disk or CD-ROM).
+	 */
+	for (i = 0; i < 4; i++) {
+		if (nodemgr_read_quadlet(host, nodeid, generation,
+					 addr, &buffer[0]) < 0) {
+			HPSB_ERR("ConfigROM quadlet transaction error for node "
+				 NODE_BUS_FMT, NODE_BUS_ARGS(nodeid));
+			return -1;
+		}
+		if (buffer[0])
+			break;
 
-	/* Now, P1212 says that devices should support 64byte block
-	 * reads, aligned on 64byte boundaries. That doesn't seem
-	 * to work though, and we are forced to doing quadlet
-	 * sized reads.  */
-
-	if (hpsb_read(host, nodeid, base, &quad, 4)) {
-		HPSB_ERR("ConfigROM quadlet transaction error for node " NODE_BUS_FMT,
-			 NODE_BUS_ARGS(nodeid));
-		goto retry_configrom;
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (schedule_timeout (HZ/4))
+			return -1;
 	}
-	buffer[header_count++] = be32_to_cpu(quad);
 
 	header_size = buffer[0] >> 24;
+	addr += 4;
 
 	if (header_size < 4) {
-		HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM format (%d quads), "
-			  "cannot parse", NODE_BUS_ARGS(nodeid), header_size);
+		HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM "
+			  "format (%d quads), cannot parse",
+			  NODE_BUS_ARGS(nodeid), header_size);
 		return -1;
 	}
 
-	while (header_count <= header_size && header_count < buffer_length) {
-		if (hpsb_read(host, nodeid, base + (header_count<<2), &quad, 4)) {
-			HPSB_ERR("ConfigROM quadlet transaction error for " NODE_BUS_FMT,
+	for (i = 1; i < buffer_length; i++, addr += 4) {
+		if (nodemgr_read_quadlet(host, nodeid, generation,
+					 addr, &buffer[i]) < 0) {
+			HPSB_ERR("ConfigROM quadlet transaction "
+				 "error for node " NODE_BUS_FMT,
 				 NODE_BUS_ARGS(nodeid));
-			goto retry_configrom;
+			return -1;
 		}
-		buffer[header_count++] = be32_to_cpu(quad);
 	}
 
 	return 0;
-}
+}		
 
 static void nodemgr_remove_node(struct node_entry *ne)
 {
 	unsigned long flags;
 
-	HPSB_DEBUG("Device removed: node " NODE_BUS_FMT ", GUID %016Lx",
-		   NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid);
+	HPSB_DEBUG("%s removed: Node[" NODE_BUS_FMT "]  GUID[%016Lx]  [%s]",
+		   (ne->host->node_id == ne->nodeid) ? "Host" : "Device",
+		   NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid,
+		   ne->vendor_name ?: "Unknown");
 
 	write_lock_irqsave(&unit_directory_lock, flags);
 	nodemgr_free_unit_directories(ne);
@@ -676,19 +1048,11 @@
 	return;
 }
 
-/* Used to schedule each nodes config rom probe */
-struct node_probe_task {
-	nodeid_t nodeid;
-	struct hpsb_host *host;
-	atomic_t *count;
-	struct tq_struct task;
-};
-
 /* This is where we probe the nodes for their information and provided
  * features.  */
-static void nodemgr_node_probe_one(void *__npt)
+static void nodemgr_node_probe_one(struct hpsb_host *host,
+				   nodeid_t nodeid, int generation)
 {
-	struct node_probe_task *npt = (struct node_probe_task *)__npt;
 	struct node_entry *ne;
 	quadlet_t buffer[5];
 	octlet_t guid;
@@ -696,130 +1060,126 @@
 	/* We need to detect when the ConfigROM's generation has changed,
 	 * so we only update the node's info when it needs to be.  */
 
-	if (read_businfo_block (npt->host, npt->nodeid, buffer, sizeof(buffer) >> 2))
-		goto probe_complete;
+	if (read_businfo_block (host, nodeid, generation,
+				buffer, sizeof(buffer) >> 2))
+		return;
 
 	if (buffer[1] != IEEE1394_BUSID_MAGIC) {
-		/* This isn't a 1394 device */
-		HPSB_ERR("Node " NODE_BUS_FMT " isn't an IEEE 1394 device",
-			 NODE_BUS_ARGS(npt->nodeid));
-		goto probe_complete;
+		/* This isn't a 1394 device, but we let it slide. There
+		 * was a report of a device with broken firmware which
+		 * reported '2394' instead of '1394', which is obviously a
+		 * mistake. One would hope that a non-1394 device never
+		 * gets connected to Firewire bus. If someone does, we
+		 * shouldn't be held responsible, so we'll allow it with a
+		 * warning.  */
+		HPSB_WARN("Node " NODE_BUS_FMT " has invalid busID magic [0x%08x]",
+			 NODE_BUS_ARGS(nodeid), buffer[1]);
 	}
 
 	guid = ((u64)buffer[3] << 32) | buffer[4];
 	ne = hpsb_guid_get_entry(guid);
 
 	if (!ne)
-		nodemgr_create_node(guid, buffer[2], npt->host, npt->nodeid);
+		nodemgr_create_node(guid, buffer[2], host, nodeid, generation);
 	else
-		nodemgr_update_node(ne, buffer[2], npt->host, npt->nodeid);
-
-probe_complete:
-	atomic_dec(npt->count);
-
-	kfree(npt);
+		nodemgr_update_node(ne, buffer[2], host, nodeid, generation);
 
 	return;
 }
 
-static void nodemgr_node_probe_cleanup(void *__npt)
+static void nodemgr_node_probe_cleanup(struct hpsb_host *host, unsigned int generation)
 {
-	struct node_probe_task *npt = (struct node_probe_task *)__npt;
 	unsigned long flags;
 	struct list_head *lh, *next;
 	struct node_entry *ne;
 
-	/* If things aren't done yet, reschedule ourselves. */
-        if (atomic_read(npt->count)) {
-                schedule_task(&npt->task);
-		return;
-	}
-
-	kfree(npt->count);
-
 	/* Now check to see if we have any nodes that aren't referenced
 	 * any longer.  */
 	write_lock_irqsave(&node_lock, flags);
-	for (lh = node_list.next; lh != &node_list; lh = next) {
+	list_for_each_safe(lh, next, &node_list) {
 		ne = list_entry(lh, struct node_entry, list);
-		next = lh->next;
 
 		/* Only checking this host */
-		if (ne->host != npt->host)
+		if (ne->host != host)
 			continue;
 
 		/* If the generation didn't get updated, then either the
 		 * node was removed, or it failed the above probe. Either
 		 * way, we remove references to it, since they are
 		 * invalid.  */
-		if (!hpsb_node_entry_valid(ne))
+		if (ne->generation != generation)
 			nodemgr_remove_node(ne);
 	}
 	write_unlock_irqrestore(&node_lock, flags);
 
-	kfree(npt);
-
 	return;
 }
 
-static void nodemgr_node_probe(void *__host)
+static void nodemgr_node_probe(struct hpsb_host *host)
 {
-	struct hpsb_host *host = (struct hpsb_host *)__host;
-	int nodecount = host->node_count;
+	int count;
 	struct selfid *sid = (struct selfid *)host->topology_map;
 	nodeid_t nodeid = LOCAL_BUS;
-	struct node_probe_task *npt;
-	atomic_t *count;
-
-	count = kmalloc(sizeof (*count), GFP_KERNEL);
+	unsigned int generation;
 
-	if (count == NULL) {
-		HPSB_ERR ("NodeMgr: out of memory in nodemgr_node_probe");
+	/* Pause for 1/4 second, to make sure things settle down. If
+	 * schedule_timeout returns non-zero, it means we caught a signal
+	 * and need to return. */
+	set_current_state(TASK_INTERRUPTIBLE);
+	if (schedule_timeout (HZ/4))
 		return;
-	}
-
-	atomic_set(count, 0);
 
-	for (; nodecount; nodecount--, nodeid++, sid++) {
-		while (sid->extended)
-			sid++;
-		if (!sid->link_active || nodeid == host->node_id)
+	/* Now get the generation in which the node ID's we collect
+	 * are valid.  During the bus scan we will use this generation
+	 * for the read transactions, so that if another reset occurs
+	 * during the scan the transactions will fail instead of
+	 * returning bogus data. */
+	generation = get_hpsb_generation(host);
+
+	/* Scan each node on the bus */
+	for (count = host->selfid_count; count; count--, sid++) {
+		if (sid->extended)
 			continue;
 
-		npt = kmalloc(sizeof (*npt), GFP_KERNEL);
-
-		if (npt == NULL) {
-			HPSB_ERR ("NodeMgr: out of memory in nodemgr_node_probe");
-			break;
+		if (!sid->link_active) {
+			nodeid++;
+			continue;
 		}
 
-		INIT_TQUEUE(&npt->task, nodemgr_node_probe_one, npt);
-		npt->host = host;
-		npt->nodeid = nodeid;
-		npt->count = count;
+		nodemgr_node_probe_one(host, nodeid++, generation);
+	}
 
-		atomic_inc(count);
+	/* If we had a bus reset while we were scanning the bus, it is
+	 * possible that we did not probe all nodes.  In that case, we
+	 * skip the clean up for now, since we could remove nodes that
+	 * were still on the bus.  The bus reset increased
+	 * hi->reset_sem, so there's a bus scan pending which will do
+	 * the clean up eventually. */
+	if (generation == get_hpsb_generation(host))
+		nodemgr_node_probe_cleanup(host, generation);
 
-		schedule_task(&npt->task);
-	}
+	return;
+}
 
-	/* Now schedule a task to clean things up after the node probes
-	 * are done.  */
-	npt = kmalloc (sizeof (*npt), GFP_KERNEL);
+static int nodemgr_host_thread(void *__hi)
+{
+	struct host_info *hi = (struct host_info *)__hi;
 
-	if (npt == NULL) {
-		HPSB_ERR ("NodeMgr: out of memory in nodemgr_node_probe");
-		return;
-	}
+	/* No userlevel access needed */
+	daemonize();
 
-	INIT_TQUEUE(&npt->task, nodemgr_node_probe_cleanup, npt);
-	npt->host = host;
-	npt->nodeid = 0;
-	npt->count = count;
+	strcpy(current->comm, "knodemgrd");
 
-	schedule_task(&npt->task);
+	/* Sit and wait for a signal to probe the nodes on the bus. This
+	 * happens when we get a bus reset. */
+	while (!down_interruptible(&hi->reset_sem))
+		nodemgr_node_probe(hi->host);
 
-	return;
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	HPSB_DEBUG ("NodeMgr: Exiting thread for %s", hi->host->driver->name);
+#endif
+
+	complete_and_exit(&hi->exited, 0);
 }
 
 struct node_entry *hpsb_guid_get_entry(u64 guid)
@@ -846,23 +1206,57 @@
 	return ne;
 }
 
-struct hpsb_host *hpsb_get_host_by_ne(struct node_entry *ne)
+/* The following four convenience functions use a struct node_entry
+ * for addressing a node on the bus.  They are intended for use by any
+ * process context, not just the nodemgr thread, so we need to be a
+ * little careful when reading out the node ID and generation.  The
+ * thing that can go wrong is that we get the node ID, then a bus
+ * reset occurs, and then we read the generation.  The node ID is
+ * possibly invalid, but the generation is current, and we end up
+ * sending a packet to a the wrong node.
+ *
+ * The solution is to make sure we read the generation first, so that
+ * if a reset occurs in the process, we end up with a stale generation
+ * and the transactions will fail instead of silently using wrong node
+ * ID's.
+ */
+
+void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
 {
-        if (atomic_read(&ne->generation) != get_hpsb_generation(ne->host))
-		return NULL;
-        if (ne->nodeid == ne->host->node_id) return ne->host;
-        return NULL;
+        pkt->host = ne->host;
+        pkt->generation = ne->generation;
+	barrier();
+        pkt->node_id = ne->nodeid;
 }
 
-int hpsb_guid_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
+int hpsb_node_read(struct node_entry *ne, u64 addr,
+		   quadlet_t *buffer, size_t length)
 {
-        if (atomic_read(&ne->generation) != get_hpsb_generation(ne->host))
-		return 0;
+	unsigned int generation = ne->generation;
 
-        pkt->host = ne->host;
-        pkt->node_id = ne->nodeid;
-        pkt->generation = atomic_read(&ne->generation);
-        return 1;
+	barrier();
+	return hpsb_read(ne->host, ne->nodeid, generation,
+			 addr, buffer, length);
+}
+
+int hpsb_node_write(struct node_entry *ne, u64 addr, 
+		    quadlet_t *buffer, size_t length)
+{
+	unsigned int generation = ne->generation;
+
+	barrier();
+	return hpsb_write(ne->host, ne->nodeid, generation,
+			  addr, buffer, length);
+}
+
+int hpsb_node_lock(struct node_entry *ne, u64 addr, 
+		   int extcode, quadlet_t *data, quadlet_t arg)
+{
+	unsigned int generation = ne->generation;
+
+	barrier();
+	return hpsb_lock(ne->host, ne->nodeid, generation,
+			 addr, extcode, data, arg);
 }
 
 static void nodemgr_add_host(struct hpsb_host *host)
@@ -875,11 +1269,23 @@
 		return;
 	}
 
-	/* We simply initialize the struct here. We don't start the thread
-	 * until the first bus reset.  */
+	/* Initialize the hostinfo here and start the thread.  The
+	 * thread blocks on the reset semaphore until a bus reset
+	 * happens. */
 	hi->host = host;
 	INIT_LIST_HEAD(&hi->list);
-	INIT_TQUEUE(&hi->task, nodemgr_node_probe, host);
+	init_completion(&hi->exited);
+        sema_init(&hi->reset_sem, 0);
+
+	hi->pid = kernel_thread(nodemgr_host_thread, hi,
+				CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+	
+	if (hi->pid < 0) {
+		HPSB_ERR ("NodeMgr: failed to start NodeMgr thread for %s",
+			  host->driver->name);
+		kfree(hi);
+		return;
+	}
 
 	spin_lock_irqsave (&host_info_lock, flags);
 	list_add_tail (&hi->list, &host_info_list);
@@ -908,7 +1314,10 @@
 		goto done_reset_host;
 	}
 
-	schedule_task(&hi->task);
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	HPSB_DEBUG ("NodeMgr: Processing host reset for %s", host->driver->name);
+#endif
+	up(&hi->reset_sem);
 
 done_reset_host:
 	spin_unlock_irqrestore (&host_info_lock, flags);
@@ -921,40 +1330,42 @@
 	struct list_head *lh, *next;
 	struct node_entry *ne;
 	unsigned long flags;
+	struct host_info *hi = NULL;
+
+	spin_lock_irqsave (&host_info_lock, flags);
+	list_for_each_safe(lh, next, &host_info_list) {
+		struct host_info *myhi = list_entry(lh, struct host_info, list);
+		if (myhi->host == host) {
+			list_del(&myhi->list);
+			hi = myhi;
+			break;
+		}
+	}
 
-	/* Make sure we have no active scans */
-	flush_scheduled_tasks();
+	if (!hi)
+		HPSB_ERR ("NodeMgr: host %s does not exist, cannot remove",
+			  host->driver->name);
+	spin_unlock_irqrestore (&host_info_lock, flags);
 
-	/* First remove all node entries for this host */
+	/* Even if we fail the host_info part, remove all the node
+	 * entries.  */
 	write_lock_irqsave(&node_lock, flags);
-
-	for (lh = node_list.next; lh != &node_list; lh = next) {
+	list_for_each_safe(lh, next, &node_list) {
 		ne = list_entry(lh, struct node_entry, list);
-		next = lh->next;
 
-		/* Only checking this host */
-		if (ne->host != host)
-			continue;
-
-		nodemgr_remove_node(ne);
+		if (ne->host == host)
+			nodemgr_remove_node(ne);
 	}
 	write_unlock_irqrestore(&node_lock, flags);
 
-	spin_lock_irqsave (&host_info_lock, flags);
-	list_for_each_safe(lh, next, &host_info_list) {
-		struct host_info *hi = list_entry(lh, struct host_info, list);
-		if (hi->host == host) {
-			list_del(&hi->list);
-			kfree (hi);
-			break;
+	if (hi) {
+		if (hi->pid >= 0) {
+			kill_proc(hi->pid, SIGTERM, 1);
+			wait_for_completion(&hi->exited);
 		}
+		kfree(hi);
 	}
 
-	if (lh == host_info_list.next)
-		HPSB_ERR ("NodeMgr: could not remove non-existent host");
-
-	spin_unlock_irqrestore (&host_info_lock, flags);
-
 	return;
 }
 
@@ -966,8 +1377,15 @@
 
 static struct hpsb_highlevel *hl;
 
-void init_ieee1394_nodemgr(void)
+#define PROC_ENTRY "devices"
+
+void init_ieee1394_nodemgr(int disable_hotplug)
 {
+	nodemgr_disable_hotplug = disable_hotplug;
+#ifdef CONFIG_PROC_FS
+	if (!create_proc_read_entry(PROC_ENTRY, 0444, ieee1394_procfs_entry, raw1394_read_proc, NULL))
+		HPSB_ERR("Can't create devices procfs entry");
+#endif
         hl = hpsb_register_highlevel("Node manager", &nodemgr_ops);
         if (!hl) {
 		HPSB_ERR("NodeMgr: out of memory during ieee1394 initialization");
@@ -977,4 +1395,7 @@
 void cleanup_ieee1394_nodemgr(void)
 {
         hpsb_unregister_highlevel(hl);
+#ifdef CONFIG_PROC_FS
+	remove_proc_entry(PROC_ENTRY, ieee1394_procfs_entry);
+#endif
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/nodemgr.h linux/drivers/ieee1394/nodemgr.h
--- linux.orig/drivers/ieee1394/nodemgr.h	2001-10-02 04:24:24.000000000 +0000
+++ linux/drivers/ieee1394/nodemgr.h	2002-07-20 01:08:22.000000000 +0000
@@ -20,6 +20,44 @@
 #ifndef _IEEE1394_NODEMGR_H
 #define _IEEE1394_NODEMGR_H
 
+#define CONFIG_ROM_BUS_INFO_LENGTH(q)		((q) >> 24)
+#define CONFIG_ROM_BUS_CRC_LENGTH(q)		(((q) >> 16) & 0xff)
+#define CONFIG_ROM_BUS_CRC(q)			((q) & 0xffff)
+
+#define CONFIG_ROM_ROOT_LENGTH(q)		((q) >> 16)
+#define CONFIG_ROM_ROOT_CRC(q)			((q) & 0xffff)
+
+#define CONFIG_ROM_DIRECTORY_LENGTH(q)		((q) >> 16)
+#define CONFIG_ROM_DIRECTORY_CRC(q)		((q) & 0xffff)
+
+#define CONFIG_ROM_LEAF_LENGTH(q)		((q) >> 16)
+#define CONFIG_ROM_LEAF_CRC(q)			((q) & 0xffff)
+
+#define CONFIG_ROM_DESCRIPTOR_TYPE(q)		((q) >> 24)
+#define CONFIG_ROM_DESCRIPTOR_SPECIFIER_ID(q)	((q) & 0xffffff)
+#define CONFIG_ROM_DESCRIPTOR_WIDTH(q)		((q) >> 28)
+#define CONFIG_ROM_DESCRIPTOR_CHAR_SET(q)	(((q) >> 16) & 0xfff)
+#define CONFIG_ROM_DESCRIPTOR_LANG(q)		((q) & 0xffff)
+
+#define CONFIG_ROM_KEY_ID_MASK			0x3f
+#define CONFIG_ROM_KEY_TYPE_MASK		0xc0
+#define CONFIG_ROM_KEY_TYPE_IMMEDIATE		0x00
+#define CONFIG_ROM_KEY_TYPE_OFFSET		0x40
+#define CONFIG_ROM_KEY_TYPE_LEAF		0x80
+#define CONFIG_ROM_KEY_TYPE_DIRECTORY		0xc0
+
+#define CONFIG_ROM_KEY(q)			((q) >> 24)
+#define CONFIG_ROM_VALUE(q)			((q) & 0xffffff)
+
+#define CONFIG_ROM_VENDOR_ID			0x03
+#define CONFIG_ROM_MODEL_ID			0x17
+#define CONFIG_ROM_NODE_CAPABILITES		0x0C
+#define CONFIG_ROM_UNIT_DIRECTORY		0xd1
+#define CONFIG_ROM_SPECIFIER_ID			0x12 
+#define CONFIG_ROM_UNIT_SW_VERSION		0x13
+#define CONFIG_ROM_DESCRIPTOR_LEAF		0x81
+#define CONFIG_ROM_DESCRIPTOR_DIRECTORY		0xc1
+
 /* '1' '3' '9' '4' in ASCII */
 #define IEEE1394_BUSID_MAGIC	0x31333934
 
@@ -42,6 +80,8 @@
 #define UNIT_DIRECTORY_MODEL_ID		0x02
 #define UNIT_DIRECTORY_SPECIFIER_ID	0x04
 #define UNIT_DIRECTORY_VERSION		0x08
+#define UNIT_DIRECTORY_VENDOR_TEXT	0x10
+#define UNIT_DIRECTORY_MODEL_TEXT	0x20
 
 /*
  * A unit directory corresponds to a protocol supported by the
@@ -58,17 +98,14 @@
 	octlet_t address;	/* Address of the unit directory on the node */
 	u8 flags;		/* Indicates which entries were read */
 	quadlet_t vendor_id;
-	char *vendor_name;
+	const char *vendor_name;
+	int vendor_name_size;
 	quadlet_t model_id;
-	char *model_name;
+	const char *model_name;
+	int model_name_size;
 	quadlet_t specifier_id;
 	quadlet_t version;
 
-	/* Groupings for arbitrary key/value pairs */
-	int arb_count;			/* Number of arbitrary key/values */
-	char arb_keys[16];		/* Up to 16 keys */
-	quadlet_t arb_values[16];	/* Same for values */
-
 	struct hpsb_protocol_driver *driver;
 	void *driver_data;
 
@@ -77,6 +114,9 @@
 
 	/* For linking directories belonging to a node */
 	struct list_head node_list;
+
+	int count;		/* Number of quadlets */
+	quadlet_t quadlets[0];
 };
 
 struct node_entry {
@@ -85,17 +125,20 @@
 	struct hpsb_host *host;		/* Host this node is attached to */
 	nodeid_t nodeid;		/* NodeID */
 	struct bus_options busopt;	/* Bus Options */
-	atomic_t generation;		/* Synced with hpsb generation */
+	unsigned int generation;	/* Synced with hpsb generation */
 
 	/* The following is read from the config rom */
 	u32 vendor_id;
 	u32 capabilities;	
 	struct list_head unit_directories;
+
+	const char *vendor_name;
+	quadlet_t quadlets[0];
 };
 
 static inline int hpsb_node_entry_valid(struct node_entry *ne)
 {
-	return atomic_read(&ne->generation) == get_hpsb_generation(ne->host);
+	return ne->generation == get_hpsb_generation(ne->host);
 }
 
 /*
@@ -127,10 +170,17 @@
  * number).  It will at least reliably fail so that you don't accidentally and
  * unknowingly send your packet to the wrong node.
  */
-int hpsb_guid_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt);
+void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt);
+
+int hpsb_node_read(struct node_entry *ne, u64 addr,
+		   quadlet_t *buffer, size_t length);
+int hpsb_node_write(struct node_entry *ne, u64 addr, 
+		    quadlet_t *buffer, size_t length);
+int hpsb_node_lock(struct node_entry *ne, u64 addr, 
+		   int extcode, quadlet_t *data, quadlet_t arg);
 
 
-void init_ieee1394_nodemgr(void);
+void init_ieee1394_nodemgr(int disable_hotplug);
 void cleanup_ieee1394_nodemgr(void);
 
 #endif /* _IEEE1394_NODEMGR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/ohci1394.c linux/drivers/ieee1394/ohci1394.c
--- linux.orig/drivers/ieee1394/ohci1394.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ieee1394/ohci1394.c	2002-07-20 01:08:31.000000000 +0000
@@ -37,7 +37,7 @@
  * . DMA error recovery
  *
  * Known bugs:
- * . Apple PowerBook detected but not working yet (still true?)
+ * . devctl BUS_RESET arg confusion (reset type or root holdoff?)
  */
 
 /* 
@@ -90,7 +90,6 @@
 #include <linux/poll.h>
 #include <asm/byteorder.h>
 #include <asm/atomic.h>
-#include <asm/io.h>
 #include <asm/uaccess.h>
 #include <linux/tqueue.h>
 #include <linux/delay.h>
@@ -99,7 +98,6 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <linux/sched.h>
-#include <asm/segment.h>
 #include <linux/types.h>
 #include <linux/wrapper.h>
 #include <linux/vmalloc.h>
@@ -136,10 +134,10 @@
 
 #ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
 #define OHCI_DMA_ALLOC(fmt, args...) \
-	HPSB_ERR("%s("__FUNCTION__")alloc(%d): "fmt, OHCI1394_DRIVER_NAME, \
+	HPSB_ERR("%s(%s)alloc(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \
 		++global_outstanding_dmas, ## args)
 #define OHCI_DMA_FREE(fmt, args...) \
-	HPSB_ERR("%s("__FUNCTION__")free(%d): "fmt, OHCI1394_DRIVER_NAME, \
+	HPSB_ERR("%s(%s)free(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \
 		--global_outstanding_dmas, ## args)
 u32 global_outstanding_dmas = 0;
 #else
@@ -155,35 +153,27 @@
 #define PRINT(level, card, fmt, args...) \
 printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 
-#define PCI_CLASS_FIREWIRE_OHCI     ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
-
-static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
-	{
-		class: 		PCI_CLASS_FIREWIRE_OHCI,
-		class_mask: 	0x00ffffff,
-		vendor:		PCI_ANY_ID,
-		device:		PCI_ANY_ID,
-		subvendor:	PCI_ANY_ID,
-		subdevice:	PCI_ANY_ID,
-	},
-	{ 0, },
-};
-MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
-
 static char version[] __devinitdata =
-	"$Revision: 1.80 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 515 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 MODULE_PARM(attempt_root,"i");
-MODULE_PARM_DESC(attempt_root, "Attempt to make the host root.");
+MODULE_PARM_DESC(attempt_root, "Attempt to make the host root (default = 0).");
 static int attempt_root = 0;
 
-static unsigned int card_id_counter = 0;
+MODULE_PARM(phys_dma,"i");
+MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
+static int phys_dma = 1;
 
 static void dma_trm_tasklet(unsigned long data);
-static void remove_card(struct ti_ohci *ohci);
 static void dma_trm_reset(struct dma_trm_ctx *d);
 
+static void ohci1394_pci_remove(struct pci_dev *pdev);
+
+static inline void ohci1394_run_irq_hooks(struct ti_ohci *ohci,
+					  quadlet_t isoRecvEvent, 
+					  quadlet_t isoXmitEvent);
+
 #ifndef __LITTLE_ENDIAN
 /* Swap a series of quads inplace. */
 static __inline__ void block_swab32(quadlet_t *data, size_t size) {
@@ -232,7 +222,7 @@
 
 	spin_lock_irqsave (&ohci->phy_reg_lock, flags);
 
-	reg_write(ohci, OHCI1394_PhyControl, (((u16)addr << 8) & 0x00000f00) | 0x00008000);
+	reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000);
 
 	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
 		if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000)
@@ -260,7 +250,7 @@
 
 	spin_lock_irqsave (&ohci->phy_reg_lock, flags);
 
-	reg_write(ohci, OHCI1394_PhyControl, 0x00004000 | (((u16)addr << 8) & 0x00000f00) | data);
+	reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000);
 
 	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
 		r = reg_read(ohci, OHCI1394_PhyControl);
@@ -299,8 +289,6 @@
 	size_t size;
 	quadlet_t q0, q1;
 
-	mdelay(10);
-
 	/* Check status of self-id reception */
 
 	if (ohci->selfid_swap)
@@ -311,8 +299,8 @@
 	if ((self_id_count & 0x80000000) || 
 	    ((self_id_count & 0x00FF0000) != (q0 & 0x00FF0000))) {
 		PRINT(KERN_ERR, ohci->id, 
-		      "Error in reception of SelfID packets [0x%08x/0x%08x]",
-		      self_id_count, q0);
+		      "Error in reception of SelfID packets [0x%08x/0x%08x] (count: %d)",
+		      self_id_count, q0, ohci->self_id_errors);
 
 		/* Tip by James Goodwin <jamesg@Filanet.com>:
 		 * We had an error, generate another bus reset in response.  */
@@ -325,6 +313,9 @@
 		}
 		return;
 	}
+
+	/* SelfID Ok, reset error counter. */
+	ohci->self_id_errors = 0;
 	
 	size = ((self_id_count & 0x00001FFC) >> 2) - 1;
 	q++;
@@ -358,7 +349,7 @@
 	return;
 }
 
-static int ohci_soft_reset(struct ti_ohci *ohci) {
+static void ohci_soft_reset(struct ti_ohci *ohci) {
 	int i;
 
 	reg_write(ohci, OHCI1394_HCControlSet, 0x00010000);
@@ -368,10 +359,7 @@
 			break;
 		mdelay(1);
 	}
-
 	DBGMSG (ohci->id, "Soft reset finished");
-
-	return 0;
 }
 
 static int run_context(struct ti_ohci *ohci, int reg, char *msg)
@@ -412,8 +400,7 @@
 	for (i=0; i<d->num_desc; i++) {
 		u32 c;
 		
-		c = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
-			DMA_CTL_BRANCH;
+		c = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | DMA_CTL_BRANCH;
 		if (generate_irq)
 			c |= DMA_CTL_IRQ;
 				
@@ -486,36 +473,48 @@
 static void ohci_init_config_rom(struct ti_ohci *ohci);
 
 /* Global initialization */
-static int ohci_initialize(struct hpsb_host *host)
+static void ohci_initialize(struct ti_ohci *ohci)
 {
-	struct ti_ohci *ohci=host->hostdata;
-	int retval, i;
 	quadlet_t buf;
 
+	/* Start off with a soft reset, to clear everything to a sane
+	 * state. */
+	ohci_soft_reset(ohci);
+
+	/* Now enable LPS, which we need in order to start accessing
+	 * most of the registers.  In fact, on some cards (ALI M5251),
+	 * accessing registers in the SClk domain without LPS enabled
+	 * will lock up the machine.  Wait 50msec to make sure we have
+	 * full link enabled.  */
+	reg_write(ohci, OHCI1394_HCControlSet, 0x00080000);
+	mdelay(50);
+
+	/* Determine the number of available IR and IT contexts. */
+	ohci->nb_iso_rcv_ctx =
+		get_nb_iso_ctx(ohci, OHCI1394_IsoRecvIntMaskSet);
+	DBGMSG(ohci->id, "%d iso receive contexts available",
+	       ohci->nb_iso_rcv_ctx);
+
+	ohci->nb_iso_xmit_ctx = 
+		get_nb_iso_ctx(ohci, OHCI1394_IsoXmitIntMaskSet);
+	DBGMSG(ohci->id, "%d iso transmit contexts available",
+	       ohci->nb_iso_xmit_ctx);
+
+	/* Set the usage bits for non-existent contexts so they can't
+	 * be allocated */
+	ohci->ir_ctx_usage |= ~0 << ohci->nb_iso_rcv_ctx;
+	ohci->it_ctx_usage |= ~0 << ohci->nb_iso_xmit_ctx;
+	
 	spin_lock_init(&ohci->phy_reg_lock);
 	spin_lock_init(&ohci->event_lock);
   
-	/* Soft reset */
-	if ((retval = ohci_soft_reset(ohci)) < 0)
-		return retval;
-
 	/* Put some defaults to these undefined bus options */
 	buf = reg_read(ohci, OHCI1394_BusOptions);
-	buf |=  0x60000000; /* Enable CMC and ISC */
+	buf |=  0xE0000000; /* Enable IRMC, CMC and ISC */
 	buf &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */
-	buf &= ~0x98000000; /* Disable PMC, IRMC and BMC */
+	buf &= ~0x18000000; /* Disable PMC and BMC */
 	reg_write(ohci, OHCI1394_BusOptions, buf);
 
-	/* Set Link Power Status (LPS) */
-	reg_write(ohci, OHCI1394_HCControlSet, 0x00080000);
-
-	/* After enabling LPS, we need to wait for the connection
-	 * between phy and link to be established.  This should be
-	 * signaled by the LPS bit becoming 1, but this happens
-	 * immediately.  There seems to be no consistent way to wait
-	 * for this, but 50ms seems to be enough. */
-	mdelay(50);
-
 	/* Set the bus number */
 	reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0);
 
@@ -525,8 +524,10 @@
 	/* Clear link control register */
 	reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
   
-	/* Enable cycle timer and cycle master */
+	/* Enable cycle timer and cycle master and set the IRM
+	 * contender bit in our self ID packets. */
 	reg_write(ohci, OHCI1394_LinkControlSet, 0x00300000);
+	set_phy_reg_mask(ohci, 4, 0xc0);
 
 	/* Clear interrupt registers */
 	reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff);
@@ -551,18 +552,6 @@
 	/* Don't accept phy packets into AR request context */ 
 	reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400);
 
-	/* Initialize IR dma */
-	ohci->nb_iso_rcv_ctx = 
-		get_nb_iso_ctx(ohci, OHCI1394_IsoRecvIntMaskSet);
-	DBGMSG(ohci->id, "%d iso receive contexts available",
-	       ohci->nb_iso_rcv_ctx);
-	for (i=0;i<ohci->nb_iso_rcv_ctx;i++) {
-		reg_write(ohci, OHCI1394_IsoRcvContextControlClear+32*i,
-			  0xffffffff);
-		reg_write(ohci, OHCI1394_IsoRcvContextMatch+32*i, 0);
-		reg_write(ohci, OHCI1394_IsoRcvCommandPtr+32*i, 0);
-	}
-
 	/* Set bufferFill, isochHeader, multichannel for IR context */
 	reg_write(ohci, OHCI1394_IsoRcvContextControlSet, 0xd0000000);
 			
@@ -573,17 +562,6 @@
 	reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff);
 	reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff);
 
-	/* Initialize IT dma */
-	ohci->nb_iso_xmit_ctx = 
-		get_nb_iso_ctx(ohci, OHCI1394_IsoXmitIntMaskSet);
-	DBGMSG(ohci->id, "%d iso transmit contexts available",
-	       ohci->nb_iso_xmit_ctx);
-	for (i=0;i<ohci->nb_iso_xmit_ctx;i++) {
-		reg_write(ohci, OHCI1394_IsoXmitContextControlClear+32*i,
-			  0xffffffff);
-		reg_write(ohci, OHCI1394_IsoXmitCommandPtr+32*i, 0);
-	}
-	
 	/* Clear the interrupt mask */
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff);
 	reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);
@@ -640,31 +618,19 @@
 		  OHCI1394_reqTxComplete |
 		  OHCI1394_isochRx |
 		  OHCI1394_isochTx |
-		  OHCI1394_unrecoverableError
-		);
+		  OHCI1394_cycleInconsistent);
 
 	/* Enable link */
 	reg_write(ohci, OHCI1394_HCControlSet, 0x00020000);
 
 	buf = reg_read(ohci, OHCI1394_Version);
-	PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%d]  MMIO=[%lx-%lx]"
-	      "  Max Packet=[%d]", ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
+	PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%d]  "
+	      "MMIO=[%lx-%lx]  Max Packet=[%d]",
+	      ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
 	      ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq,
 	      pci_resource_start(ohci->dev, 0),
-	      pci_resource_start(ohci->dev, 0) + pci_resource_len(ohci->dev, 0),
+	      pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE,
 	      ohci->max_packet_size);
-
-	return 1;
-}
-
-static void ohci_remove(struct hpsb_host *host)
-{
-	struct ti_ohci *ohci;
-
-	if (host != NULL) {
-		ohci = host->hostdata;
-		remove_card(ohci);
-	}
 }
 
 /* 
@@ -686,7 +652,7 @@
 	d->prg_cpu[idx]->begin.address = 0;
 	d->prg_cpu[idx]->begin.branchAddress = 0;
 
-	if (d->ctx==1) {
+	if (d->type == DMA_CTX_ASYNC_RESP) {
 		/* 
 		 * For response packets, we need to put a timeout value in
 		 * the 16 lower bits of the status... let's try 1 sec timeout 
@@ -735,9 +701,9 @@
                         if (cross_bound((unsigned long)packet->data, 
                                         packet->data_size)>0) {
                                 /* FIXME: do something about it */
-                                PRINT(KERN_ERR, ohci->id, __FUNCTION__
-                                      ": packet data addr: %p size %Zd bytes "
-                                      "cross page boundary", 
+                                PRINT(KERN_ERR, ohci->id,
+                                      "%s: packet data addr: %p size %Zd bytes "
+                                      "cross page boundary", __FUNCTION__,
                                       packet->data, packet->data_size);
                         }
 
@@ -927,10 +893,8 @@
 	switch (cmd) {
 	case RESET_BUS:
 		DBGMSG(ohci->id, "devctl: Bus reset requested%s",
-		       ((host->attempt_root || attempt_root) ? 
-		       " and attempting to become root" : ""));
-		set_phy_reg_mask (ohci, 1, 0x40 | ((host->attempt_root || attempt_root) ?
-				  0x80 : 0));
+		       attempt_root ? " and attempting to become root" : "");
+		set_phy_reg_mask (ohci, 1, 0x40 | (attempt_root ? 0x80 : 0));
 		break;
 
 	case GET_CYCLE_COUNTER:
@@ -975,6 +939,7 @@
                 } else {
                         MOD_DEC_USE_COUNT;
                 }
+		retval = 1;
                 break;
 
 	case ISO_LISTEN_CHANNEL:
@@ -982,9 +947,9 @@
 		u64 mask;
 
 		if (arg<0 || arg>63) {
-			PRINT(KERN_ERR, ohci->id, __FUNCTION__
-			      "IS0 listen channel %d is out of range", 
-			      arg);
+			PRINT(KERN_ERR, ohci->id,
+			      "%s: IS0 listen channel %d is out of range", 
+			      __FUNCTION__, arg);
 			return -EFAULT;
 		}
 
@@ -993,9 +958,9 @@
                 spin_lock_irqsave(&ohci->IR_channel_lock, flags);
 
 		if (ohci->ISO_channel_usage & mask) {
-			PRINT(KERN_ERR, ohci->id, __FUNCTION__
-			      "IS0 listen channel %d is already used", 
-			      arg);
+			PRINT(KERN_ERR, ohci->id,
+			      "%s: IS0 listen channel %d is already used", 
+			      __FUNCTION__, arg);
 			spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
 			return -EFAULT;
 		}
@@ -1018,9 +983,9 @@
 		u64 mask;
 
 		if (arg<0 || arg>63) {
-			PRINT(KERN_ERR, ohci->id, __FUNCTION__
-			      "IS0 unlisten channel %d is out of range", 
-			      arg);
+			PRINT(KERN_ERR, ohci->id,
+			      "%s: IS0 unlisten channel %d is out of range", 
+			      __FUNCTION__, arg);
 			return -EFAULT;
 		}
 
@@ -1029,9 +994,9 @@
                 spin_lock_irqsave(&ohci->IR_channel_lock, flags);
 
 		if (!(ohci->ISO_channel_usage & mask)) {
-			PRINT(KERN_ERR, ohci->id, __FUNCTION__
-			      "IS0 unlisten channel %d is not used", 
-			      arg);
+			PRINT(KERN_ERR, ohci->id,
+			      "%s: IS0 unlisten channel %d is not used", 
+			      __FUNCTION__, arg);
 			spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
 			return -EFAULT;
 		}
@@ -1134,10 +1099,17 @@
 	/* Die right here an now */
 	if (event & OHCI1394_unrecoverableError) {
 		PRINT(KERN_ERR, ohci->id, "Unrecoverable error, shutting down card!");
-		remove_card(ohci);
 		return;
 	}
 
+	if (event & OHCI1394_cycleInconsistent) {
+		/* We subscribe to the cycleInconsistent event only to
+		 * clear the corresponding event bit... otherwise,
+		 * isochronous cycleMatch DMA wont work. */
+		DBGMSG(ohci->id, "OHCI1394_cycleInconsistent");
+		event &= ~OHCI1394_cycleInconsistent;
+	}
+
 	if (event & OHCI1394_busReset) {
 		/* The busReset event bit can't be cleared during the
 		 * selfID phase, so we disable busReset interrupts, to
@@ -1157,8 +1129,8 @@
 		spin_unlock_irqrestore(&ohci->event_lock, flags);
 		if (!host->in_bus_reset) {
 			DBGMSG(ohci->id, "irq_handler: Bus reset requested%s",
-			      ((host->attempt_root || attempt_root) ?
-			      " and attempting to become root" : ""));
+			      (attempt_root) ? " and attempting to become root"
+			       : "");
 
 			/* Subsystem call */
 			hpsb_bus_reset(ohci->host);
@@ -1229,9 +1201,9 @@
 			else
 				tasklet_schedule(&d->task);
 		}
-		if (ohci->video_tmpl) 
-			ohci->video_tmpl->irq_handler(ohci->id, isoRecvIntEvent,
-						      0);
+
+		ohci1394_run_irq_hooks(ohci, isoRecvIntEvent, 0);
+
 		event &= ~OHCI1394_isochRx;
 	}
 	if (event & OHCI1394_isochTx) {
@@ -1244,9 +1216,9 @@
                        DBGMSG(ohci->id, "Got isochTx interrupt "
                                "status=0x%08x isoXmitIntEvent=%08x",
                               reg_read(ohci, d->ctrlSet), isoXmitIntEvent);
-		if (ohci->video_tmpl) 
-			ohci->video_tmpl->irq_handler(ohci->id, 0,
-						      isoXmitIntEvent);
+
+		ohci1394_run_irq_hooks(ohci, 0, isoXmitIntEvent);
+		
 		if (isoXmitIntEvent & 0x1) {
 			if (reg_read(ohci, d->ctrlSet) & 0x800)
 				ohci1394_stop_context(ohci, d->ctrlClear, "isochTx");
@@ -1289,15 +1261,6 @@
 				  0xffffffff);
 			reg_write(ohci,OHCI1394_AsReqFilterLoSet, 
 				  0xffffffff);
-			/* Turn on phys dma reception. We should
-			 * probably manage the filtering somehow, 
-			 * instead of blindly turning it on.  */
-			reg_write(ohci,OHCI1394_PhyReqFilterHiSet,
-				  0xffffffff);
-			reg_write(ohci,OHCI1394_PhyReqFilterLoSet,
-				  0xffffffff);
-                       	reg_write(ohci,OHCI1394_PhyUpperBound,
-				  0xffff0000);
 		} else
 			PRINT(KERN_ERR, ohci->id, 
 			      "SelfID received outside of bus reset sequence");
@@ -1305,10 +1268,35 @@
 		/* Finally, we clear the busReset event and reenable
 		 * the busReset interrupt. */
 		spin_lock_irqsave(&ohci->event_lock, flags);
-		reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); 
 		reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
+		reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); 
 		spin_unlock_irqrestore(&ohci->event_lock, flags);
 		event &= ~OHCI1394_selfIDComplete;	
+
+		/* Turn on phys dma reception. We should
+		 * probably manage the filtering somehow, 
+		 * instead of blindly turning it on.  */
+
+		/*
+		 * CAUTION!
+		 * Some chips (TI TSB43AB22) won't take a value in
+		 * the PhyReqFilter register until after the IntEvent
+		 * is cleared for bus reset, and even then a short
+		 * delay is required.
+		 */
+		if (phys_dma) {
+			mdelay(1);
+			reg_write(ohci,OHCI1394_PhyReqFilterHiSet,
+				  0xffffffff);
+			reg_write(ohci,OHCI1394_PhyReqFilterLoSet,
+				  0xffffffff);
+			reg_write(ohci,OHCI1394_PhyUpperBound,
+				  0xffff0000);
+		}
+
+		DBGMSG(ohci->id, "PhyReqFilter=%08x%08x\n",
+		       reg_read(ohci,OHCI1394_PhyReqFilterHiSet),
+		       reg_read(ohci,OHCI1394_PhyReqFilterLoSet));
 	}
 
 	/* Make sure we handle everything, just in case we accidentally
@@ -1353,7 +1341,7 @@
 {
 	int length = -1;
 
-	if (d->ctx < 2) { /* Async Receive Response/Request */
+	if (d->type == DMA_CTX_ASYNC_REQ || d->type == DMA_CTX_ASYNC_RESP) {
 		length = TCODE_SIZE[tcode];
 		if (length == 0) {
 			if (offset + 12 >= d->buf_size) {
@@ -1364,7 +1352,7 @@
 			}
 			length += 20;
 		}
-	} else if (d->ctx == 2) { /* Iso receive */
+	} else if (d->type == DMA_CTX_ISO) {
 		/* Assumption: buffer fill mode with header/trailer */
 		length = (cond_le32_to_cpu(buf_ptr[0], noswap) >> 16) + 8;
 	}
@@ -1394,11 +1382,8 @@
 	offset = d->buf_offset;
 	buf_ptr = d->buf_cpu[idx] + offset/4;
 
-	dma_cache_wback_inv(&(d->prg_cpu[idx]->status), sizeof(d->prg_cpu[idx]->status));
 	rescount = le32_to_cpu(d->prg_cpu[idx]->status) & 0xffff;
-
 	bytes_left = d->buf_size - rescount - offset;
-	dma_cache_wback_inv(buf_ptr, bytes_left);
 
 	while (bytes_left > 0) {
 		tcode = (cond_le32_to_cpu(buf_ptr[0], ohci->no_swap_incoming) >> 4) & 0xf;
@@ -1450,7 +1435,6 @@
 			insert_dma_buffer(d, idx);
 			idx = (idx+1) % d->num_desc;
 			buf_ptr = d->buf_cpu[idx];
-			dma_cache_wback_inv(buf_ptr, d->buf_size);
 			offset=0;
 
 			while (split_left >= d->buf_size) {
@@ -1460,7 +1444,6 @@
 				insert_dma_buffer(d, idx);
 				idx = (idx+1) % d->num_desc;
 				buf_ptr = d->buf_cpu[idx];
-                                dma_cache_wback_inv(buf_ptr, d->buf_size);
 			}
 
 			if (split_left > 0) {
@@ -1507,8 +1490,6 @@
 			       d->ctx);
 #endif
 
-                dma_cache_wback_inv(&(d->prg_cpu[idx]->status),
-                        sizeof(d->prg_cpu[idx]->status));
 	       	rescount = le32_to_cpu(d->prg_cpu[idx]->status) & 0xffff;
 
 		bytes_left = d->buf_size - rescount - offset;
@@ -1556,6 +1537,15 @@
 			/* this packet hasn't been sent yet*/
 			break;
 
+		if (!(ack & 0x10)) {
+			/* XXX: This is an OHCI evt_* code. We need to handle
+			 * this specially! For right now, we just fake an
+			 * ackx_send_error. */
+			PRINT(KERN_DEBUG, ohci->id, "Received OHCI evt_* error 0x%x",
+			       ack & 0xf);
+			ack = (ack & 0xffe0) | ACK_BUSY_A;
+		}
+
 #ifdef OHCI1394_DEBUG
 		if (datasize)
 			DBGMSG(ohci->id,
@@ -1647,6 +1637,11 @@
 	}
 	if ((*d)->spb) kfree((*d)->spb);
 
+	/* clear ISO context usage bit */
+	if ((*d)->type == DMA_CTX_ISO) {
+		clear_bit((*d)->ctx, &ohci->ir_ctx_usage);
+	}
+	       
 	kfree(*d);
 	*d = NULL;
 
@@ -1654,15 +1649,21 @@
 }
 
 static struct dma_rcv_ctx *
-alloc_dma_rcv_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
-		  int buf_size, int split_buf_size, 
-		  int ctrlSet, int ctrlClear, int cmdPtr)
+alloc_dma_rcv_ctx(struct ti_ohci *ohci, enum context_type type, int ctx, int num_desc,
+		  int buf_size, int split_buf_size, int context_base)
 {
-	struct dma_rcv_ctx *d=NULL;
+	struct dma_rcv_ctx *d;
 	int i;
 
-	d = (struct dma_rcv_ctx *)kmalloc(sizeof(struct dma_rcv_ctx), 
-					  GFP_KERNEL);
+	if (type == DMA_CTX_ISO) {
+		/* try to claim the ISO context usage bit */
+		if (test_and_set_bit(ctx, &ohci->ir_ctx_usage)) {
+			PRINT(KERN_ERR, ohci->id, "IR DMA context %d is not available", ctx);
+			return NULL;
+		}
+	}
+	
+	d = kmalloc(sizeof(struct dma_rcv_ctx), GFP_KERNEL);
 
 	if (d == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate dma_rcv_ctx");
@@ -1671,21 +1672,17 @@
 
 	memset (d, 0, sizeof (struct dma_rcv_ctx));
 
-	d->ohci = (void *)ohci;
+	d->ohci = ohci;
+	d->type = type;
 	d->ctx = ctx;
 
 	d->num_desc = num_desc;
 	d->buf_size = buf_size;
 	d->split_buf_size = split_buf_size;
-	d->ctrlSet = ctrlSet;
-	d->ctrlClear = ctrlClear;
-	d->cmdPtr = cmdPtr;
-
-	d->buf_cpu = NULL;
-	d->buf_bus = NULL;
-	d->prg_cpu = NULL;
-	d->prg_bus = NULL;
-	d->spb = NULL;
+
+	d->ctrlSet = context_base + OHCI1394_ContextControlSet;
+	d->ctrlClear = context_base + OHCI1394_ContextControlClear;
+	d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
 
 	d->buf_cpu = kmalloc(d->num_desc * sizeof(quadlet_t*), GFP_KERNEL);
 	d->buf_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL);
@@ -1784,36 +1781,47 @@
 		kfree((*d)->prg_bus);
 	}
 
+	/* clear the ISO context usage bit */
+	if ((*d)->type == DMA_CTX_ISO) {
+		clear_bit((*d)->ctx, &ohci->it_ctx_usage);
+	}
+
 	kfree(*d);
 	*d = NULL;
 	return 0;
 }
 
 static struct dma_trm_ctx *
-alloc_dma_trm_ctx(struct ti_ohci *ohci, int ctx, int num_desc,
-		  int ctrlSet, int ctrlClear, int cmdPtr)
+alloc_dma_trm_ctx(struct ti_ohci *ohci, enum context_type type, int ctx, int num_desc,
+		  int context_base)
 {
-	struct dma_trm_ctx *d=NULL;
+	struct dma_trm_ctx *d;
 	int i;
 
-	d = (struct dma_trm_ctx *)kmalloc(sizeof(struct dma_trm_ctx), 
-					  GFP_KERNEL);
+	if (type == DMA_CTX_ISO) {
+		/* try to claim the ISO context usage bit */
+		if (test_and_set_bit(ctx, &ohci->it_ctx_usage)) {
+			PRINT(KERN_ERR, ohci->id, "IT DMA context %d is not available", ctx);
+			return NULL;
+		}
+	}
+	
+	d = kmalloc(sizeof(struct dma_trm_ctx), GFP_KERNEL);
 
-	if (d==NULL) {
+	if (d == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate dma_trm_ctx");
 		return NULL;
 	}
 
 	memset (d, 0, sizeof (struct dma_trm_ctx));
 
-	d->ohci = (void *)ohci;
+	d->ohci = ohci;
+	d->type = type;
 	d->ctx = ctx;
 	d->num_desc = num_desc;
-	d->ctrlSet = ctrlSet;
-	d->ctrlClear = ctrlClear;
-	d->cmdPtr = cmdPtr;
-	d->prg_cpu = NULL;
-	d->prg_bus = NULL;
+	d->ctrlSet = context_base + OHCI1394_ContextControlSet;
+	d->ctrlClear = context_base + OHCI1394_ContextControlClear;
+	d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
 
 	d->prg_cpu = kmalloc(d->num_desc * sizeof(struct at_dma_prg*), 
 			     GFP_KERNEL);
@@ -1827,7 +1835,7 @@
 	memset(d->prg_cpu, 0, d->num_desc * sizeof(struct at_dma_prg*));
 	memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
 
-	for (i=0; i<d->num_desc; i++) {
+	for (i = 0; i < d->num_desc; i++) {
                 d->prg_cpu[i] = pci_alloc_consistent(ohci->dev, 
 						     sizeof(struct at_dma_prg),
 						     d->prg_bus+i);
@@ -1858,7 +1866,7 @@
 
 	crc = 0;
 	for (; length > 0; length--) {
-		data = *ptr++;
+		data = be32_to_cpu(*ptr++);
 		for (shift = 28; shift >= 0; shift -= 4) {
 			sum = ((crc >> 12) ^ (data >> shift)) & 0x000f;
 			crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ sum;
@@ -1890,6 +1898,21 @@
 
 #define cf_put_keyval(cr, key, val) (((cr)->data++)[0] = cpu_to_be32(((key) << 24) | (val)))
 
+static inline void cf_put_str(struct config_rom_ptr *cr, const char *str)
+{
+	int t;
+	char fourb[4];
+
+	while (str[0]) {
+		memset(fourb, 0, 4);
+		for (t = 0; t < 4 && str[t]; t++)
+			fourb[t] = str[t];
+		cf_put_4bytes(cr, fourb[0], fourb[1], fourb[2], fourb[3]);
+		str += strlen(str) < 4 ? strlen(str) : 4;
+	}
+	return;
+}
+
 static inline void cf_put_crc16(struct config_rom_ptr *cr, int unit)
 {
 	*cr->unitdir[unit].start =
@@ -1956,7 +1979,8 @@
 
 	/* Root directory */
 	cf_unit_begin(&cr, 1);
-	cf_put_keyval(&cr, 0x03, 0x00005e);	/* Vendor ID */
+	/* Vendor ID */
+	cf_put_keyval(&cr, 0x03, reg_read(ohci,OHCI1394_VendorID) & 0xFFFFFF);
 	cf_put_refer(&cr, 0x81, 2);		/* Textual description unit */
 	cf_put_keyval(&cr, 0x0c, 0x0083c0);	/* Node capabilities */
 	/* NOTE: Add other unit referers here, and append at bottom */
@@ -1966,9 +1990,7 @@
 	cf_unit_begin(&cr, 2);
 	cf_put_keyval(&cr, 0, 0);
 	cf_put_1quad(&cr, 0);
-	cf_put_4bytes(&cr, 'L', 'i', 'n', 'u');
-	cf_put_4bytes(&cr, 'x', ' ', '1', '3');
-	cf_put_4bytes(&cr, '9', '4', 0x0, 0x0);
+	cf_put_str(&cr, "Linux OHCI-1394");
 	cf_unit_end(&cr);
 
 	ohci->csr_config_rom_length = cr.data - ohci->csr_config_rom_cpu;
@@ -1986,13 +2008,15 @@
 	return ohci->csr_config_rom_length * 4;
 }
 
-int ohci_compare_swap(struct ti_ohci *ohci, quadlet_t *data,
-                      quadlet_t compare, int sel)
+static quadlet_t ohci_hw_csr_reg(struct hpsb_host *host, int reg,
+                                 quadlet_t data, quadlet_t compare)
 {
+	struct ti_ohci *ohci = host->hostdata;
 	int i;
-	reg_write(ohci, OHCI1394_CSRData, *data);
+
+	reg_write(ohci, OHCI1394_CSRData, data);
 	reg_write(ohci, OHCI1394_CSRCompareData, compare);
-	reg_write(ohci, OHCI1394_CSRControl, sel & 0x3);
+	reg_write(ohci, OHCI1394_CSRControl, reg & 0x3);
 
 	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
 		if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000)
@@ -2001,68 +2025,59 @@
 		mdelay(1);
 	}
 
-	*data = reg_read(ohci, OHCI1394_CSRData);
-	return 0;
-}
-
-static quadlet_t ohci_hw_csr_reg(struct hpsb_host *host, int reg,
-                                 quadlet_t data, quadlet_t compare)
-{
-	struct ti_ohci *ohci=host->hostdata;
-
-	ohci_compare_swap (ohci, &data, compare, reg);
-
-	return data;
+	return reg_read(ohci, OHCI1394_CSRData);
 }
 
-static struct hpsb_host_template ohci_template = {
-	name:			OHCI1394_DRIVER_NAME,
-	initialize_host:	ohci_initialize,
-	release_host:		ohci_remove,
+static struct hpsb_host_operations ohci1394_ops = {
 	get_rom:		ohci_get_rom,
 	transmit_packet:	ohci_transmit,
 	devctl:			ohci_devctl,
 	hw_csr_reg:		ohci_hw_csr_reg,
 };
 
+static struct hpsb_host_driver *ohci1394_driver;
+
+
 
-#define FAIL(fmt, args...)			\
+/***********************************
+ * PCI Driver Interface functions  *
+ ***********************************/
+
+#define FAIL(err, fmt, args...)			\
 do {						\
 	PRINT_G(KERN_ERR, fmt , ## args);	\
-	remove_card(ohci);			\
-	return 1;				\
+        ohci1394_pci_remove(dev);               \
+	return err;				\
 } while(0)
 
-static int __devinit ohci1394_add_one(struct pci_dev *dev, const struct pci_device_id *ent)
+static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
+					const struct pci_device_id *ent)
 {
-	struct ti_ohci *ohci;	/* shortcut to currently handled device */
-	struct hpsb_host *host;
-	unsigned long ohci_base, ohci_len;
+	static unsigned int card_id_counter = 0;
 	static int version_printed = 0;
 
+	struct hpsb_host *host;
+	struct ti_ohci *ohci;	/* shortcut to currently handled device */
+	unsigned long ohci_base;
+	int i;
+	
 	if (version_printed++ == 0)
 		PRINT_G(KERN_INFO, "%s", version);
 
-        if (pci_enable_device(dev)) {
-		/* Skip ID's that fail */
-		PRINT_G(KERN_NOTICE, "Failed to enable OHCI hardware %d",
-			card_id_counter++);
-		return -ENXIO;
-        }
+        if (pci_enable_device(dev))
+		FAIL(-ENXIO, "Failed to enable OHCI hardware %d",
+		        card_id_counter++);
         pci_set_master(dev);
 
-	host = hpsb_get_host(&ohci_template, sizeof (struct ti_ohci));
-	if (!host) {
-		PRINT_G(KERN_ERR, "Out of memory trying to allocate host structure");
-		return -ENOMEM;
-	}
+	host = hpsb_alloc_host(ohci1394_driver, sizeof(struct ti_ohci));
+	if (!host) FAIL(-ENOMEM, "Failed to allocate host structure");
+
 	ohci = host->hostdata;
-	ohci->host = host;
-	INIT_LIST_HEAD(&ohci->list);
 	ohci->id = card_id_counter++;
 	ohci->dev = dev;
-	host->pdev = dev;
 	ohci->host = host;
+	ohci->init_state = OHCI_INIT_ALLOC_HOST;
+	host->pdev = dev;
 	pci_set_drvdata(dev, ohci);
 
 	/* We don't want hardware swapping */
@@ -2077,184 +2092,201 @@
 	 * zero. Should this work? Obviously it's not defined what these
 	 * registers will read when they aren't supported. Bleh! */
 	if (dev->vendor == PCI_VENDOR_ID_APPLE && 
-		dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW) {
-			ohci->no_swap_incoming = 1;
-			ohci->selfid_swap = 0;
+	    dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW) {
+		ohci->no_swap_incoming = 1;
+		ohci->selfid_swap = 0;
 	} else
 		ohci->selfid_swap = 1;
 #endif
 
+	/* We hardwire the MMIO length, since some CardBus adaptors
+	 * fail to report the right length.  Anyway, the ohci spec
+	 * clearly says it's 2kb, so this shouldn't be a problem. */ 
+	ohci_base = pci_resource_start(dev, 0);
+	if (pci_resource_len(dev, 0) != OHCI1394_REGISTER_SIZE)
+		PRINT(KERN_WARNING, ohci->id, "Unexpected PCI resource length of %lx!",
+		      pci_resource_len(dev, 0));
+
+	/* Seems PCMCIA handles this internally. Not sure why. Seems
+	 * pretty bogus to force a driver to special case this.  */
+#ifndef PCMCIA
+	if (!request_mem_region (ohci_base, OHCI1394_REGISTER_SIZE, OHCI1394_DRIVER_NAME))
+		FAIL(-ENOMEM, "MMIO resource (0x%lx - 0x%lx) unavailable",
+		     ohci_base, ohci_base + OHCI1394_REGISTER_SIZE);
+#endif
+	ohci->init_state = OHCI_INIT_HAVE_MEM_REGION;
+
+	ohci->registers = ioremap(ohci_base, OHCI1394_REGISTER_SIZE);
+	if (ohci->registers == NULL)
+		FAIL(-ENXIO, "Failed to remap registers - card not accessible");
+	ohci->init_state = OHCI_INIT_HAVE_IOMAPPING;
+	DBGMSG(ohci->id, "Remapped memory spaces reg 0x%p", ohci->registers);
+
 	/* csr_config rom allocation */
-	ohci->csr_config_rom_cpu = 
+	ohci->csr_config_rom_cpu =
 		pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
 				     &ohci->csr_config_rom_bus);
 	OHCI_DMA_ALLOC("consistent csr_config_rom");
 	if (ohci->csr_config_rom_cpu == NULL)
-		FAIL("Failed to allocate buffer config rom");
+		FAIL(-ENOMEM, "Failed to allocate buffer config rom");
+	ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER;
 
-	/* 
-	 * self-id dma buffer allocation
-	 */
+	/* self-id dma buffer allocation */
 	ohci->selfid_buf_cpu = 
 		pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE,
                       &ohci->selfid_buf_bus);
 	OHCI_DMA_ALLOC("consistent selfid_buf");
+	
 	if (ohci->selfid_buf_cpu == NULL)
-		FAIL("Failed to allocate DMA buffer for self-id packets");
+		FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets");
+	ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER;
 
 	if ((unsigned long)ohci->selfid_buf_cpu & 0x1fff)
 		PRINT(KERN_INFO, ohci->id, "SelfID buffer %p is not aligned on "
 		      "8Kb boundary... may cause problems on some CXD3222 chip", 
 		      ohci->selfid_buf_cpu);  
 
-	ohci->it_context =
-		alloc_dma_trm_ctx(ohci, 2, IT_NUM_DESC,
-				  OHCI1394_IsoXmitContextControlSet,
-				  OHCI1394_IsoXmitContextControlClear,
-				  OHCI1394_IsoXmitCommandPtr);
-
-	if (ohci->it_context == NULL)
-		FAIL("Failed to allocate IT context");
-
-	ohci_base = pci_resource_start(dev, 0);
-	ohci_len = pci_resource_len(dev, 0);
-
-	if (!request_mem_region (ohci_base, ohci_len, host->template->name))
-		FAIL("MMIO resource (0x%lx@0x%lx) unavailable, aborting.",
-		     ohci_base, ohci_len);
-
-	ohci->registers = ioremap(ohci_base, ohci_len);
-
-	if (ohci->registers == NULL)
-		FAIL("Failed to remap registers - card not accessible");
-
-	DBGMSG(ohci->id, "Remapped memory spaces reg 0x%p",
-	      ohci->registers);
+	/* No self-id errors at startup */
+	ohci->self_id_errors = 0;
 
+	ohci->init_state = OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE;
+	/* AR DMA request context allocation */
 	ohci->ar_req_context = 
-		alloc_dma_rcv_ctx(ohci, 0, AR_REQ_NUM_DESC,
+		alloc_dma_rcv_ctx(ohci, DMA_CTX_ASYNC_REQ, 0, AR_REQ_NUM_DESC,
 				  AR_REQ_BUF_SIZE, AR_REQ_SPLIT_BUF_SIZE,
-				  OHCI1394_AsReqRcvContextControlSet,
-				  OHCI1394_AsReqRcvContextControlClear,
-				  OHCI1394_AsReqRcvCommandPtr);
+				  OHCI1394_AsReqRcvContextBase);
 
 	if (ohci->ar_req_context == NULL)
-		FAIL("Failed to allocate AR Req context");
+		FAIL(-ENOMEM, "Failed to allocate AR Req context");
 
+	/* AR DMA response context allocation */
 	ohci->ar_resp_context = 
-		alloc_dma_rcv_ctx(ohci, 1, AR_RESP_NUM_DESC,
+		alloc_dma_rcv_ctx(ohci, DMA_CTX_ASYNC_RESP, 0, AR_RESP_NUM_DESC,
 				  AR_RESP_BUF_SIZE, AR_RESP_SPLIT_BUF_SIZE,
-				  OHCI1394_AsRspRcvContextControlSet,
-				  OHCI1394_AsRspRcvContextControlClear,
-				  OHCI1394_AsRspRcvCommandPtr);
+				  OHCI1394_AsRspRcvContextBase);
 	
 	if (ohci->ar_resp_context == NULL)
-		FAIL("Failed to allocate AR Resp context");
+		FAIL(-ENOMEM, "Failed to allocate AR Resp context");
 
+	/* AT DMA request context */
 	ohci->at_req_context = 
-		alloc_dma_trm_ctx(ohci, 0, AT_REQ_NUM_DESC,
-				  OHCI1394_AsReqTrContextControlSet,
-				  OHCI1394_AsReqTrContextControlClear,
-				  OHCI1394_AsReqTrCommandPtr);
+		alloc_dma_trm_ctx(ohci, DMA_CTX_ASYNC_REQ, 0, AT_REQ_NUM_DESC,
+				  OHCI1394_AsReqTrContextBase);
 	
 	if (ohci->at_req_context == NULL)
-		FAIL("Failed to allocate AT Req context");
+		FAIL(-ENOMEM, "Failed to allocate AT Req context");
 
+	/* AT DMA response context */
 	ohci->at_resp_context = 
-		alloc_dma_trm_ctx(ohci, 1, AT_RESP_NUM_DESC,
-				  OHCI1394_AsRspTrContextControlSet,
-				  OHCI1394_AsRspTrContextControlClear,
-				  OHCI1394_AsRspTrCommandPtr);
+		alloc_dma_trm_ctx(ohci, DMA_CTX_ASYNC_RESP, 1, AT_RESP_NUM_DESC,
+				  OHCI1394_AsRspTrContextBase);
 	
 	if (ohci->at_resp_context == NULL)
-		FAIL("Failed to allocate AT Resp context");
+		FAIL(-ENOMEM, "Failed to allocate AT Resp context");
 
+	ohci->ir_ctx_usage = 0;
+	ohci->it_ctx_usage = 0;
+	
+	/* IR DMA context */
 	ohci->ir_context =
-		alloc_dma_rcv_ctx(ohci, 2, IR_NUM_DESC,
+		alloc_dma_rcv_ctx(ohci, DMA_CTX_ISO, 0, IR_NUM_DESC,
 				  IR_BUF_SIZE, IR_SPLIT_BUF_SIZE,
-				  OHCI1394_IsoRcvContextControlSet,
-				  OHCI1394_IsoRcvContextControlClear,
-				  OHCI1394_IsoRcvCommandPtr);
+				  OHCI1394_IsoRcvContextBase);
 
 	if (ohci->ir_context == NULL)
-		FAIL("Failed to allocate IR context");
+		FAIL(-ENOMEM, "Failed to allocate IR context");
+
+	
+	/* IT DMA context allocation */
+	ohci->it_context =
+		alloc_dma_trm_ctx(ohci, DMA_CTX_ISO, 0, IT_NUM_DESC,
+				  OHCI1394_IsoXmitContextBase);
+
+	if (ohci->it_context == NULL)
+		FAIL(-ENOMEM, "Failed to allocate IT context");
 
 	ohci->ISO_channel_usage = 0;
         spin_lock_init(&ohci->IR_channel_lock);
 
+	for(i = 0; i < OHCI1394_MAX_IRQ_HOOKS; i++) {
+		ohci->irq_hooks[i].irq_handler = NULL;
+		ohci->irq_hooks[i].data = NULL;
+	}
+	
 	if (request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ,
 			 OHCI1394_DRIVER_NAME, ohci))
-		FAIL("Failed to allocate shared interrupt %d", dev->irq);
+		FAIL(-ENOMEM, "Failed to allocate shared interrupt %d", dev->irq);
+
+	ohci->init_state = OHCI_INIT_HAVE_IRQ;
+	ohci_initialize(ohci);
 
 	/* Tell the highlevel this host is ready */
-	highlevel_add_one_host (host);
+	hpsb_add_host(host);
+	ohci->init_state = OHCI_INIT_DONE;
 
 	return 0;
 #undef FAIL
 }
 
-static void remove_card(struct ti_ohci *ohci)
+static void ohci1394_pci_remove(struct pci_dev *pdev)
 {
-	quadlet_t buf;
+	struct ti_ohci *ohci;
 
-	/* Soft reset before we start */
-	ohci_soft_reset(ohci);
+	ohci = pci_get_drvdata(pdev);
+	if (!ohci)
+		return;
 
-	/* Free AR dma */
-	free_dma_rcv_ctx(&ohci->ar_req_context);
-	free_dma_rcv_ctx(&ohci->ar_resp_context);
-
-	/* Free AT dma */
-	free_dma_trm_ctx(&ohci->at_req_context);
-	free_dma_trm_ctx(&ohci->at_resp_context);
-
-	/* Free IR dma */
-	free_dma_rcv_ctx(&ohci->ir_context);
-
-        /* Free IT dma */
-        free_dma_trm_ctx(&ohci->it_context);
-
-	/* Disable all interrupts */
-	reg_write(ohci, OHCI1394_IntMaskClear, 0x80000000);
-	free_irq(ohci->dev->irq, ohci);
+	switch (ohci->init_state) {
+	case OHCI_INIT_DONE:
+		hpsb_remove_host(ohci->host);
+
+	case OHCI_INIT_HAVE_IRQ:
+		/* Soft reset before we start - this disables
+		 * interrupts and clears linkEnable and LPS. */
+		ohci_soft_reset(ohci);
+		free_irq(ohci->dev->irq, ohci);
+
+	case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE:
+		/* Free AR dma */
+		free_dma_rcv_ctx(&ohci->ar_req_context);
+		free_dma_rcv_ctx(&ohci->ar_resp_context);
+
+		/* Free AT dma */
+		free_dma_trm_ctx(&ohci->at_req_context);
+		free_dma_trm_ctx(&ohci->at_resp_context);
 
-	/* Free self-id buffer */
-	if (ohci->selfid_buf_cpu) {
+		/* Free IR dma */
+		free_dma_rcv_ctx(&ohci->ir_context);
+		
+		/* Free IT dma */
+		free_dma_trm_ctx(&ohci->it_context);
+	
+	case OHCI_INIT_HAVE_SELFID_BUFFER:
 		pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, 
 				    ohci->selfid_buf_cpu,
 				    ohci->selfid_buf_bus);
 		OHCI_DMA_FREE("consistent selfid_buf");
-	}
-	
-	/* Free config rom */
-	if (ohci->csr_config_rom_cpu) {
+		
+	case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER:
 		pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
-				    ohci->csr_config_rom_cpu, 
+				    ohci->csr_config_rom_cpu,
 				    ohci->csr_config_rom_bus);
 		OHCI_DMA_FREE("consistent csr_config_rom");
-	}
-
-	/* Disable our bus options */
-	buf = reg_read(ohci, OHCI1394_BusOptions);
-	buf &= ~0xf8000000;
-	buf |=  0x00ff0000;
-	reg_write(ohci, OHCI1394_BusOptions, buf);
 
-	/* Clear LinkEnable and LPS */
-	reg_write(ohci, OHCI1394_HCControlClear, 0x000a0000);
-
-	if (ohci->registers)
+	case OHCI_INIT_HAVE_IOMAPPING:
 		iounmap(ohci->registers);
 
-	release_mem_region (pci_resource_start(ohci->dev, 0),
-			    pci_resource_len(ohci->dev, 0));
+	case OHCI_INIT_HAVE_MEM_REGION:
+#ifndef PCMCIA
+		release_mem_region(pci_resource_start(ohci->dev, 0),
+				   OHCI1394_REGISTER_SIZE);
+#endif
 
 #ifdef CONFIG_ALL_PPC
-	/* On UniNorth, power down the cable and turn off the
-	 * chip clock when the module is removed to save power
-	 * on laptops. Turning it back ON is done by the arch
-	 * code when pci_enable_device() is called
-	 */
+	/* On UniNorth, power down the cable and turn off the chip
+	 * clock when the module is removed to save power on
+	 * laptops. Turning it back ON is done by the arch code when
+	 * pci_enable_device() is called */
 	{
 		struct device_node* of_node;
 
@@ -2266,9 +2298,44 @@
 	}
 #endif /* CONFIG_ALL_PPC */
 
-	pci_set_drvdata(ohci->dev, NULL);
+	case OHCI_INIT_ALLOC_HOST:
+		pci_set_drvdata(ohci->dev, NULL);
+		hpsb_unref_host(ohci->host);
+	}
 }
 
+#define PCI_CLASS_FIREWIRE_OHCI     ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
+
+static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
+	{
+		class: 		PCI_CLASS_FIREWIRE_OHCI,
+		class_mask: 	0x00ffffff,
+		vendor:		PCI_ANY_ID,
+		device:		PCI_ANY_ID,
+		subvendor:	PCI_ANY_ID,
+		subdevice:	PCI_ANY_ID,
+	},
+	{ 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
+
+static struct pci_driver ohci1394_pci_driver = {
+	name:		OHCI1394_DRIVER_NAME,
+	id_table:	ohci1394_pci_tbl,
+	probe:		ohci1394_pci_probe,
+	remove:		ohci1394_pci_remove,
+};
+
+
+
+/***********************************
+ * OHCI1394 Video Interface        *
+ ***********************************/
+
+/* essentially the only purpose of this code is to allow another
+   module to hook into ohci's interrupt handler */
+
 void ohci1394_stop_context(struct ti_ohci *ohci, int reg, char *msg)
 {
 	int i=0;
@@ -2288,111 +2355,96 @@
 	if (msg) PRINT(KERN_ERR, ohci->id, "%s: dma prg stopped", msg);
 }
 
-int ohci1394_register_video(struct ti_ohci *ohci,
-			    struct video_template *tmpl)
+static inline void ohci1394_run_irq_hooks(struct ti_ohci *ohci,
+					  quadlet_t isoRecvEvent, 
+					  quadlet_t isoXmitEvent)
 {
-	if (ohci->video_tmpl)
-		return -ENFILE;
-	ohci->video_tmpl = tmpl;
-	MOD_INC_USE_COUNT;
-	return 0;
+	int i;
+	for(i = 0; i < OHCI1394_MAX_IRQ_HOOKS; i++) {
+		if(ohci->irq_hooks[i].irq_handler != NULL) {
+			ohci->irq_hooks[i].irq_handler(ohci->id, isoRecvEvent, isoXmitEvent,
+						       ohci->irq_hooks[i].data);
+		}
+	}
 }
-	
-void ohci1394_unregister_video(struct ti_ohci *ohci,
-			       struct video_template *tmpl)
+
+int ohci1394_hook_irq(struct ti_ohci *ohci,
+		      void (*irq_handler) (int, quadlet_t, quadlet_t, void *),
+		      void *data)
 {
-	if (ohci->video_tmpl != tmpl) {
-		PRINT(KERN_ERR, ohci->id, 
-		      "Trying to unregister wrong video device");
-	} else {
-		ohci->video_tmpl = NULL;
-		MOD_DEC_USE_COUNT;
+	int i;
+	
+	/* find a free slot */
+	for(i = 0; i < OHCI1394_MAX_IRQ_HOOKS; i++) {
+		if(ohci->irq_hooks[i].irq_handler == NULL)
+			break;
 	}
+
+	if(i >= OHCI1394_MAX_IRQ_HOOKS)
+		return -EBUSY;
+
+	ohci->irq_hooks[i].irq_handler = irq_handler;
+	ohci->irq_hooks[i].data = data;
+
+	/* ohci1394 will never be unloaded while an IRQ hook is
+	   in use, because the user must reference this symbol */
+	
+	return 0;
 }
 
-#if 0
-int ohci1394_request_channel(struct ti_ohci *ohci, int channel)
+void ohci1394_unhook_irq(struct ti_ohci *ohci,
+			 void (*irq_handler) (int, quadlet_t, quadlet_t, void *),
+			 void *data)
 {
-	int csrSel;
-	quadlet_t chan, data1=0, data2=0;
-	int timeout = 32;
-
-	if (channel<32) {
-		chan = 1<<channel;
-		csrSel = 2;
-	}
-	else {
-		chan = 1<<(channel-32);
-		csrSel = 3;
-	}
-	if (ohci_compare_swap(ohci, &data1, 0, csrSel)<0) {
-		PRINT(KERN_INFO, ohci->id, "request_channel timeout");
-		return -1;
+	int i;
+	
+	for(i = 0; i < OHCI1394_MAX_IRQ_HOOKS; i++) {
+		if( (ohci->irq_hooks[i].irq_handler == irq_handler) &&
+		    (ohci->irq_hooks[i].data == data) )
+			break;
 	}
-	while (timeout--) {
-		if (data1 & chan) {
-			PRINT(KERN_INFO, ohci->id, 
-			      "request channel %d failed", channel);
-			return -1;
-		}
-		data2 = data1;
-		data1 |= chan;
-		if (ohci_compare_swap(ohci, &data1, data2, csrSel)<0) {
-			PRINT(KERN_INFO, ohci->id, "request_channel timeout");
-			return -1;
-		}
-		if (data1==data2) {
-			PRINT(KERN_INFO, ohci->id, 
-			      "request channel %d succeded", channel);
-			return 0;
-		}
+	
+	if(i < OHCI1394_MAX_IRQ_HOOKS) {
+		ohci->irq_hooks[i].irq_handler = NULL;
+		ohci->irq_hooks[i].data = NULL;
 	}
-	PRINT(KERN_INFO, ohci->id, "request channel %d failed", channel);
-	return -1;
 }
-#endif
 
 EXPORT_SYMBOL(ohci1394_stop_context);
-EXPORT_SYMBOL(ohci1394_register_video);
-EXPORT_SYMBOL(ohci1394_unregister_video);
+EXPORT_SYMBOL(ohci1394_hook_irq);
+EXPORT_SYMBOL(ohci1394_unhook_irq);
 
-MODULE_AUTHOR("Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>");
-MODULE_DESCRIPTION("Driver for PCI OHCI IEEE-1394 controllers");
-MODULE_LICENSE("GPL");
 
-static void __devexit ohci1394_remove_one(struct pci_dev *pdev)
-{
-	struct ti_ohci *ohci = pci_get_drvdata(pdev);
 
-	if (ohci) {
-		remove_card (ohci);
-		pci_set_drvdata(pdev, NULL);
-	}
-}
+/***********************************
+ * General module initialization   *
+ ***********************************/
 
-static struct pci_driver ohci1394_driver = {
-	name:		OHCI1394_DRIVER_NAME,
-	id_table:	ohci1394_pci_tbl,
-	probe:		ohci1394_add_one,
-	remove:		__devexit_p(ohci1394_remove_one),
-};
+MODULE_AUTHOR("Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>");
+MODULE_DESCRIPTION("Driver for PCI OHCI IEEE-1394 controllers");
+MODULE_LICENSE("GPL");
 
 static void __exit ohci1394_cleanup (void)
 {
-	hpsb_unregister_lowlevel(&ohci_template);
-	pci_unregister_driver(&ohci1394_driver);
+	pci_unregister_driver(&ohci1394_pci_driver);
+	hpsb_unregister_lowlevel(ohci1394_driver);
 }
 
 static int __init ohci1394_init(void)
 {
 	int ret;
-	if (hpsb_register_lowlevel(&ohci_template)) {
-		PRINT_G(KERN_ERR, "Registering failed");
-		return -ENXIO;
-	}
-	if ((ret = pci_module_init(&ohci1394_driver))) {
-		PRINT_G(KERN_ERR, "PCI module init failed");
-		hpsb_unregister_lowlevel(&ohci_template);
+
+	ohci1394_driver = hpsb_register_lowlevel(&ohci1394_ops,
+						 OHCI1394_DRIVER_NAME);
+	if (!ohci1394_driver) {
+		PRINT_G(KERN_ERR, "hpsb_register_lowlevel failed");
+		return -ENOMEM;
+	}
+
+	ret = pci_module_init(&ohci1394_pci_driver);
+	if (ret < 0) {
+		PRINT_G(KERN_ERR, "pci_module_init failed");
+		hpsb_unregister_lowlevel(ohci1394_driver);
 		return ret;
 	}
 	return ret;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/ohci1394.h linux/drivers/ieee1394/ohci1394.h
--- linux.orig/drivers/ieee1394/ohci1394.h	2001-10-02 04:24:24.000000000 +0000
+++ linux/drivers/ieee1394/ohci1394.h	2002-07-20 01:08:26.000000000 +0000
@@ -21,7 +21,10 @@
 #ifndef _OHCI1394_H
 #define _OHCI1394_H
 
+#include <asm/io.h>
+
 #include "ieee1394_types.h"
+#include <asm/io.h>
 
 #define OHCI1394_DRIVER_NAME      "ohci1394"
 
@@ -76,9 +79,13 @@
 	quadlet_t pad[4]; /* FIXME: quick hack for memory alignment */
 };
 
+/* identify whether a DMA context is asynchronous or isochronous */
+enum context_type { DMA_CTX_ASYNC_REQ, DMA_CTX_ASYNC_RESP, DMA_CTX_ISO };
+
 /* DMA receive context */
 struct dma_rcv_ctx {
-	void *ohci;
+	struct ti_ohci *ohci;
+	enum context_type type;
 	int ctx;
 	unsigned int num_desc;
 
@@ -105,7 +112,8 @@
 
 /* DMA transmit context */	
 struct dma_trm_ctx {
-	void *ohci;
+	struct ti_ohci *ohci;
+	enum context_type type;
 	int ctx;
 	unsigned int num_desc;
 
@@ -133,21 +141,21 @@
 	int cmdPtr;
 };
 
-/* video device template */
-struct video_template {
-	void (*irq_handler) (int card, quadlet_t isoRecvEvent, 
-			     quadlet_t isoXmitEvent);
-};
-
-
 struct ti_ohci {
         int id; /* sequential card number */
 
-	struct list_head list;
-
         struct pci_dev *dev;
 
-        u32 state;
+	enum { 
+		OHCI_INIT_ALLOC_HOST,
+		OHCI_INIT_HAVE_MEM_REGION,
+		OHCI_INIT_HAVE_IOMAPPING,
+		OHCI_INIT_HAVE_CONFIG_ROM_BUFFER,
+		OHCI_INIT_HAVE_SELFID_BUFFER,
+		OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE,
+		OHCI_INIT_HAVE_IRQ,
+		OHCI_INIT_DONE,
+	} init_state;
         
         /* remapped memory spaces */
         void *registers; 
@@ -175,11 +183,13 @@
 	struct dma_rcv_ctx *ir_context;
         spinlock_t IR_channel_lock;
 	int nb_iso_rcv_ctx;
-
+	unsigned long ir_ctx_usage; /* use test_and_set_bit() for atomicity */
+	
         /* iso transmit */
 	struct dma_trm_ctx *it_context;
 	int nb_iso_xmit_ctx;
-
+	unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */
+	
         u64 ISO_channel_usage;
 
         /* IEEE-1394 part follows */
@@ -192,8 +202,15 @@
 
 	int self_id_errors;
 
-	/* video device */
-	struct video_template *video_tmpl;
+	/* IRQ hooks, for video1394 and dv1394 */
+	
+#define OHCI1394_MAX_IRQ_HOOKS 16
+	
+	struct ohci1394_irq_hook {
+		void (*irq_handler) (int card, quadlet_t isoRecvEvent, 
+				     quadlet_t isoXmitEvent, void *data);
+		void *data;
+	} irq_hooks[OHCI1394_MAX_IRQ_HOOKS];
 
 	/* Swap the selfid buffer? */
 	unsigned int selfid_swap:1;
@@ -230,6 +247,12 @@
 /* 2 KiloBytes of register space */
 #define OHCI1394_REGISTER_SIZE                0x800       
 
+/* Offsets relative to context bases defined below */
+
+#define OHCI1394_ContextControlSet            0x000
+#define OHCI1394_ContextControlClear          0x004
+#define OHCI1394_ContextCommandPtr            0x00C
+
 /* register map */
 #define OHCI1394_Version                      0x000
 #define OHCI1394_GUID_ROM                     0x004
@@ -281,27 +304,37 @@
 #define OHCI1394_PhyReqFilterLoSet            0x118
 #define OHCI1394_PhyReqFilterLoClear          0x11C
 #define OHCI1394_PhyUpperBound                0x120
+
+#define OHCI1394_AsReqTrContextBase           0x180
 #define OHCI1394_AsReqTrContextControlSet     0x180
 #define OHCI1394_AsReqTrContextControlClear   0x184
 #define OHCI1394_AsReqTrCommandPtr            0x18C
+
+#define OHCI1394_AsRspTrContextBase           0x1A0
 #define OHCI1394_AsRspTrContextControlSet     0x1A0
 #define OHCI1394_AsRspTrContextControlClear   0x1A4
 #define OHCI1394_AsRspTrCommandPtr            0x1AC
+
+#define OHCI1394_AsReqRcvContextBase          0x1C0
 #define OHCI1394_AsReqRcvContextControlSet    0x1C0
 #define OHCI1394_AsReqRcvContextControlClear  0x1C4
 #define OHCI1394_AsReqRcvCommandPtr           0x1CC
+
+#define OHCI1394_AsRspRcvContextBase          0x1E0
 #define OHCI1394_AsRspRcvContextControlSet    0x1E0
 #define OHCI1394_AsRspRcvContextControlClear  0x1E4
 #define OHCI1394_AsRspRcvCommandPtr           0x1EC
 
 /* Isochronous transmit registers */
-/* Add (32 * n) for context n */
+/* Add (16 * n) for context n */
+#define OHCI1394_IsoXmitContextBase           0x200
 #define OHCI1394_IsoXmitContextControlSet     0x200
 #define OHCI1394_IsoXmitContextControlClear   0x204
 #define OHCI1394_IsoXmitCommandPtr            0x20C
 
 /* Isochronous receive registers */
 /* Add (32 * n) for context n */
+#define OHCI1394_IsoRcvContextBase            0x400
 #define OHCI1394_IsoRcvContextControlSet      0x400
 #define OHCI1394_IsoRcvContextControlClear    0x404
 #define OHCI1394_IsoRcvCommandPtr             0x40C
@@ -342,14 +375,39 @@
 #define DMA_CTL_BRANCH                   0x000c0000
 #define DMA_CTL_WAIT                     0x00030000
 
+/* OHCI evt_* error types, table 3-2 of the OHCI 1.1 spec. */
+#define EVT_NO_STATUS		0x0	/* No event status */
+#define EVT_RESERVED		0x1	/* Reserved, not used !!! */
+#define EVT_LONG_PACKET		0x2	/* The revc data was longer than the buf */
+#define EVT_MISSING_ACK		0x3	/* A subaction gap was detected before an ack
+					   arrived, or recv'd ack had a parity error */
+#define EVT_UNDERRUN		0x4	/* Underrun on corresponding FIFO, packet
+					   truncated */
+#define EVT_OVERRUN		0x5	/* A recv FIFO overflowed on reception of ISO
+					   packet */
+#define EVT_DESCRIPTOR_READ	0x6	/* An unrecoverable error occured while host was
+					   reading a descriptor block */
+#define EVT_DATA_READ		0x7	/* An error occured while host controller was
+					   attempting to read from host memory in the data
+					   stage of descriptor processing */
+#define EVT_DATA_WRITE		0x8	/* An error occured while host controller was
+					   attempting to write either during the data stage
+					   of descriptor processing, or when processing a single
+					   16-bit host memory write */
+#define EVT_BUS_RESET		0x9	/* Identifies a PHY packet in the recv buffer as
+					   being a synthesized bus reset packet */
+
 #define OHCI1394_TCODE_PHY               0xE
 
 void ohci1394_stop_context(struct ti_ohci *ohci, int reg, char *msg);
 struct ti_ohci *ohci1394_get_struct(int card_num);
-int ohci1394_register_video(struct ti_ohci *ohci,
-			    struct video_template *tmpl);
-void ohci1394_unregister_video(struct ti_ohci *ohci,
-			       struct video_template *tmpl);
 
+int ohci1394_hook_irq(struct ti_ohci *ohci,
+		      void (*irq_handler) (int, quadlet_t, quadlet_t, void *),
+		      void *data);
+
+void ohci1394_unhook_irq(struct ti_ohci *ohci,
+			 void (*irq_handler) (int, quadlet_t, quadlet_t, void *),
+			 void *data);
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/pcilynx.c linux/drivers/ieee1394/pcilynx.c
--- linux.orig/drivers/ieee1394/pcilynx.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ieee1394/pcilynx.c	2002-07-20 01:08:32.000000000 +0000
@@ -2,6 +2,7 @@
  * ti_pcilynx.c - Texas Instruments PCILynx driver
  * Copyright (C) 1999,2000 Andreas Bombe <andreas.bombe@munich.netsurf.de>,
  *                         Stephan Linz <linz@mazet.de>
+ *                         Manfred Weihs <weihs@ict.tuwien.ac.at>
  *
  * 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
@@ -41,10 +42,8 @@
 #include "highlevel.h"
 #include "pcilynx.h"
 
-
-#if MAX_PCILYNX_CARDS > PCILYNX_MINOR_ROM_START
-#error Max number of cards is bigger than PCILYNX_MINOR_ROM_START - this does not work.
-#endif
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
 
 /* print general (card independent) information */
 #define PRINT_G(level, fmt, args...) printk(level "pcilynx: " fmt "\n" , ## args)
@@ -60,9 +59,84 @@
 #endif
 
 
-static struct ti_lynx cards[MAX_PCILYNX_CARDS];
-static int num_of_cards = 0;
-static struct hpsb_host_template lynx_template;
+/* Module Parameters */
+MODULE_PARM(skip_eeprom,"i");
+MODULE_PARM_DESC(skip_eeprom, "Do not try to read bus info block from serial eeprom, but user generic one (default = 0).");
+static int skip_eeprom = 0;
+
+
+static struct hpsb_host_driver *lynx_driver;
+static unsigned int card_id;
+
+
+
+/*
+ * I2C stuff
+ */
+
+/* the i2c stuff was inspired by i2c-philips-par.c */
+
+static void bit_setscl(void *data, int state)
+{
+	if (state) {
+		  ((struct ti_lynx *) data)->i2c_driven_state |= 0x00000040;
+	} else {
+		  ((struct ti_lynx *) data)->i2c_driven_state &= ~0x00000040;
+	}
+	reg_write((struct ti_lynx *) data, SERIAL_EEPROM_CONTROL, ((struct ti_lynx *) data)->i2c_driven_state);
+}
+
+static void bit_setsda(void *data, int state)
+{
+	if (state) {
+		  ((struct ti_lynx *) data)->i2c_driven_state |= 0x00000010;
+	} else {
+		  ((struct ti_lynx *) data)->i2c_driven_state &= ~0x00000010;
+	}
+	reg_write((struct ti_lynx *) data, SERIAL_EEPROM_CONTROL, ((struct ti_lynx *) data)->i2c_driven_state);
+}
+
+static int bit_getscl(void *data)
+{
+	return reg_read((struct ti_lynx *) data, SERIAL_EEPROM_CONTROL) & 0x00000040;
+}
+
+static int bit_getsda(void *data)
+{
+	return reg_read((struct ti_lynx *) data, SERIAL_EEPROM_CONTROL) & 0x00000010;
+}
+
+static int bit_reg(struct i2c_client *client)
+{
+	return 0;
+}
+
+static int bit_unreg(struct i2c_client *client)
+{
+	return 0;
+}
+
+static struct i2c_algo_bit_data bit_data = {
+	NULL,
+	bit_setsda,
+	bit_setscl,
+	bit_getsda,
+	bit_getscl,
+	5, 5, 100,		/*	waits, timeout */
+}; 
+
+static struct i2c_adapter bit_ops = {
+	"PCILynx I2C adapter",
+	0xAA, //FIXME: probably we should get an id in i2c-id.h
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	bit_reg,
+	bit_unreg,
+};
+
+
 
 /*
  * PCL handling functions.
@@ -143,10 +217,6 @@
 #endif
 
 
-static int add_card(struct pci_dev *dev, const struct pci_device_id *devid);
-static void remove_card(struct pci_dev *dev);
-
-
 
 /***********************************
  * IEEE-1394 functionality section *
@@ -161,8 +231,9 @@
         unsigned long flags;
 
         if (addr > 15) {
-                PRINT(KERN_ERR, lynx->id, __FUNCTION__
-                      ": PHY register address %d out of range", addr);
+                PRINT(KERN_ERR, lynx->id,
+                      "%s: PHY register address %d out of range",
+		      __FUNCTION__, addr);
                 return -1;
         }
 
@@ -173,8 +244,8 @@
                 retval = reg_read(lynx, LINK_PHY);
 
                 if (i > 10000) {
-                        PRINT(KERN_ERR, lynx->id, __FUNCTION__ 
-                              ": runaway loop, aborting");
+                        PRINT(KERN_ERR, lynx->id, "%s: runaway loop, aborting",
+			      __FUNCTION__);
                         retval = -1;
                         break;
                 }
@@ -196,14 +267,14 @@
         unsigned long flags;
 
         if (addr > 15) {
-                PRINT(KERN_ERR, lynx->id, __FUNCTION__
-                      ": PHY register address %d out of range", addr);
+                PRINT(KERN_ERR, lynx->id,
+                      "%s: PHY register address %d out of range", __FUNCTION__, addr);
                 return -1;
         }
 
         if (val > 0xff) {
-                PRINT(KERN_ERR, lynx->id, __FUNCTION__
-                      ": PHY register value %d out of range", val);
+                PRINT(KERN_ERR, lynx->id,
+                      "%s: PHY register value %d out of range", __FUNCTION__, val);
                 return -1;
         }
 
@@ -222,8 +293,8 @@
         int reg;
 
         if (page > 7) {
-                PRINT(KERN_ERR, lynx->id, __FUNCTION__
-                      ": PHY page %d out of range", page);
+                PRINT(KERN_ERR, lynx->id,
+                      "%s: PHY page %d out of range", __FUNCTION__, page);
                 return -1;
         }
 
@@ -244,8 +315,8 @@
         int reg;
 
         if (port > 15) {
-                PRINT(KERN_ERR, lynx->id, __FUNCTION__
-                      ": PHY port %d out of range", port);
+                PRINT(KERN_ERR, lynx->id,
+                      "%s: PHY port %d out of range", __FUNCTION__, port);
                 return -1;
         }
 
@@ -377,7 +448,7 @@
 
         hpsb_selfid_complete(host, phyid, isroot);
 
-        if (host->in_bus_reset) return;
+        if (host->in_bus_reset) return; /* in bus reset again */
 
         if (isroot) reg_set_bits(lynx, LINK_CONTROL, LINK_CONTROL_CYCMASTER);
         reg_set_bits(lynx, LINK_CONTROL,
@@ -440,160 +511,7 @@
 }
 
 
-#if 0
-static int lynx_detect(struct hpsb_host_template *tmpl)
-{
-        struct hpsb_host *host;
-        int i;
-
-        init_driver();
-
-        for (i = 0; i < num_of_cards; i++) {
-                host = hpsb_get_host(tmpl, 0);
-                if (host == NULL) {
-                        /* simply don't init more after out of mem */
-                        return i;
-                }
-                host->hostdata = &cards[i];
-                cards[i].host = host;
-        }
-
-        return num_of_cards;
-}
-#endif
-
-static int lynx_initialize(struct hpsb_host *host)
-{
-        struct ti_lynx *lynx = host->hostdata;
-        struct ti_pcl pcl;
-        int i;
-        u32 *pcli;
-
-        lynx->selfid_size = -1;
-        lynx->phy_reg0 = -1;
-
-        lynx->async.queue = NULL;
-        
-        pcl.next = pcl_bus(lynx, lynx->rcv_pcl);
-        put_pcl(lynx, lynx->rcv_pcl_start, &pcl);
-        
-        pcl.next = PCL_NEXT_INVALID;
-        pcl.async_error_next = PCL_NEXT_INVALID;
-#ifdef __BIG_ENDIAN
-        pcl.buffer[0].control = PCL_CMD_RCV | 16;
-        pcl.buffer[1].control = PCL_LAST_BUFF | 4080;
-#else
-        pcl.buffer[0].control = PCL_CMD_RCV | PCL_BIGENDIAN | 16;
-        pcl.buffer[1].control = PCL_LAST_BUFF | 4080;
-#endif
-        pcl.buffer[0].pointer = lynx->rcv_page_dma;
-        pcl.buffer[1].pointer = lynx->rcv_page_dma + 16;
-        put_pcl(lynx, lynx->rcv_pcl, &pcl);
-        
-        pcl.next = pcl_bus(lynx, lynx->async.pcl);
-        pcl.async_error_next = pcl_bus(lynx, lynx->async.pcl);
-        put_pcl(lynx, lynx->async.pcl_start, &pcl);
-
-        pcl.next = pcl_bus(lynx, lynx->iso_send.pcl);
-        pcl.async_error_next = PCL_NEXT_INVALID;
-        put_pcl(lynx, lynx->iso_send.pcl_start, &pcl);
-
-        pcl.next = PCL_NEXT_INVALID;
-        pcl.async_error_next = PCL_NEXT_INVALID;
-        pcl.buffer[0].control = PCL_CMD_RCV | 4;
-#ifndef __BIG_ENDIAN
-        pcl.buffer[0].control |= PCL_BIGENDIAN;
-#endif
-        pcl.buffer[1].control = PCL_LAST_BUFF | 2044;
-
-        for (i = 0; i < NUM_ISORCV_PCL; i++) {
-                int page = i / ISORCV_PER_PAGE;
-                int sec = i % ISORCV_PER_PAGE;
-
-                pcl.buffer[0].pointer = lynx->iso_rcv.page_dma[page] 
-                        + sec * MAX_ISORCV_SIZE;
-                pcl.buffer[1].pointer = pcl.buffer[0].pointer + 4;
-                put_pcl(lynx, lynx->iso_rcv.pcl[i], &pcl);
-        }
-
-        pcli = (u32 *)&pcl;
-        for (i = 0; i < NUM_ISORCV_PCL; i++) {
-                pcli[i] = pcl_bus(lynx, lynx->iso_rcv.pcl[i]);
-        }
-        put_pcl(lynx, lynx->iso_rcv.pcl_start, &pcl);
-
-        /* FIFO sizes from left to right: ITF=48 ATF=48 GRF=160 */
-        reg_write(lynx, FIFO_SIZES, 0x003030a0);
-        /* 20 byte threshold before triggering PCI transfer */
-        reg_write(lynx, DMA_GLOBAL_REGISTER, 0x2<<24);
-        /* threshold on both send FIFOs before transmitting:
-           FIFO size - cache line size - 1 */
-        i = reg_read(lynx, PCI_LATENCY_CACHELINE) & 0xff;
-        i = 0x30 - i - 1;
-        reg_write(lynx, FIFO_XMIT_THRESHOLD, (i << 8) | i);
-        
-        reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_1394);
-
-        reg_write(lynx, LINK_INT_ENABLE, LINK_INT_PHY_TIMEOUT
-                  | LINK_INT_PHY_REG_RCVD  | LINK_INT_PHY_BUSRESET
-                  | LINK_INT_ISO_STUCK     | LINK_INT_ASYNC_STUCK 
-                  | LINK_INT_SENT_REJECT   | LINK_INT_TX_INVALID_TC
-                  | LINK_INT_GRF_OVERFLOW  | LINK_INT_ITF_UNDERFLOW
-                  | LINK_INT_ATF_UNDERFLOW);
-        
-        reg_write(lynx, DMA_WORD0_CMP_VALUE(CHANNEL_ASYNC_RCV), 0);
-        reg_write(lynx, DMA_WORD0_CMP_ENABLE(CHANNEL_ASYNC_RCV), 0xa<<4);
-        reg_write(lynx, DMA_WORD1_CMP_VALUE(CHANNEL_ASYNC_RCV), 0);
-        reg_write(lynx, DMA_WORD1_CMP_ENABLE(CHANNEL_ASYNC_RCV),
-                  DMA_WORD1_CMP_MATCH_LOCAL_NODE | DMA_WORD1_CMP_MATCH_BROADCAST
-                  | DMA_WORD1_CMP_MATCH_EXACT    | DMA_WORD1_CMP_MATCH_BUS_BCAST
-                  | DMA_WORD1_CMP_ENABLE_SELF_ID | DMA_WORD1_CMP_ENABLE_MASTER);
-
-        run_pcl(lynx, lynx->rcv_pcl_start, CHANNEL_ASYNC_RCV);
-
-        reg_write(lynx, DMA_WORD0_CMP_VALUE(CHANNEL_ISO_RCV), 0);
-        reg_write(lynx, DMA_WORD0_CMP_ENABLE(CHANNEL_ISO_RCV), 0x9<<4);
-        reg_write(lynx, DMA_WORD1_CMP_VALUE(CHANNEL_ISO_RCV), 0);
-        reg_write(lynx, DMA_WORD1_CMP_ENABLE(CHANNEL_ISO_RCV), 0);
-
-        run_sub_pcl(lynx, lynx->iso_rcv.pcl_start, 0, CHANNEL_ISO_RCV);
-
-        reg_write(lynx, LINK_CONTROL, LINK_CONTROL_RCV_CMP_VALID
-                  | LINK_CONTROL_TX_ISO_EN   | LINK_CONTROL_RX_ISO_EN
-                  | LINK_CONTROL_TX_ASYNC_EN | LINK_CONTROL_RX_ASYNC_EN
-                  | LINK_CONTROL_RESET_TX    | LINK_CONTROL_RESET_RX);
-
-        if (!lynx->phyic.reg_1394a) {
-                /* attempt to enable contender bit -FIXME- would this work
-                 * elsewhere? */
-                reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
-                reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1); 
-        } else {
-                /* set the contender bit in the extended PHY register
-                 * set. (Should check that bis 0,1,2 (=0xE0) is set
-                 * in register 2?)
-                 */
-                i = get_phy_reg(lynx, 4);
-                if (i != -1) set_phy_reg(lynx, 4, i | 0x40);
-        }
-
-        return 1;
-}
-
-static void lynx_release(struct hpsb_host *host)
-{
-        struct ti_lynx *lynx;
-        
-        if (host != NULL) {
-                lynx = host->hostdata;
-                remove_card(lynx->dev);
-        } else {
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-                unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME);
-#endif
-        }
-}
-
+/* called from subsystem core */
 static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
 {
         struct ti_lynx *lynx = host->hostdata;
@@ -642,6 +560,8 @@
         return 1;
 }
 
+
+/* called from subsystem core */
 static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
 {
         struct ti_lynx *lynx = host->hostdata;
@@ -666,9 +586,7 @@
                 arg |= (retval == -1 ? 63 : retval);
                 retval = 0;
 
-                PRINT(KERN_INFO, lynx->id, "resetting bus on request%s",
-                      (host->attempt_root ? " and attempting to become root"
-                       : ""));
+                PRINT(KERN_INFO, lynx->id, "resetting bus on request");
 
                 lynx->selfid_size = -1;
                 lynx->phy_reg0 = -1;
@@ -721,6 +639,8 @@
                 } else {
                         MOD_DEC_USE_COUNT;
                 }
+
+                retval = 1;
                 break;
 
         case ISO_LISTEN_CHANNEL:
@@ -773,7 +693,7 @@
 
 
 static struct file_operations aux_ops = {
-        OWNER_THIS_MODULE
+	owner:		THIS_MODULE,
         read:           mem_read,
         write:          mem_write,
         poll:           aux_poll,
@@ -794,46 +714,35 @@
 
 static int mem_open(struct inode *inode, struct file *file)
 {
-        int cid = MINOR(inode->i_rdev);
+        int cid = minor(inode->i_rdev);
         enum { t_rom, t_aux, t_ram } type;
         struct memdata *md;
         
-        V22_COMPAT_MOD_INC_USE_COUNT;
-
         if (cid < PCILYNX_MINOR_AUX_START) {
                 /* just for completeness */
-                V22_COMPAT_MOD_DEC_USE_COUNT;
                 return -ENXIO;
         } else if (cid < PCILYNX_MINOR_ROM_START) {
                 cid -= PCILYNX_MINOR_AUX_START;
-                if (cid >= num_of_cards || !cards[cid].aux_port) {
-                        V22_COMPAT_MOD_DEC_USE_COUNT;
+                if (cid >= num_of_cards || !cards[cid].aux_port)
                         return -ENXIO;
-                }
                 type = t_aux;
         } else if (cid < PCILYNX_MINOR_RAM_START) {
                 cid -= PCILYNX_MINOR_ROM_START;
-                if (cid >= num_of_cards || !cards[cid].local_rom) {
-                        V22_COMPAT_MOD_DEC_USE_COUNT;
+                if (cid >= num_of_cards || !cards[cid].local_rom)
                         return -ENXIO;
-                }
                 type = t_rom;
         } else {
                 /* WARNING: Know what you are doing when opening RAM.
                  * It is currently used inside the driver! */
                 cid -= PCILYNX_MINOR_RAM_START;
-                if (cid >= num_of_cards || !cards[cid].local_ram) {
-                        V22_COMPAT_MOD_DEC_USE_COUNT;
+                if (cid >= num_of_cards || !cards[cid].local_ram)
                         return -ENXIO;
-                }
                 type = t_ram;
         }
 
         md = (struct memdata *)kmalloc(sizeof(struct memdata), SLAB_KERNEL);
-        if (md == NULL) {
-                V22_COMPAT_MOD_DEC_USE_COUNT;
+        if (md == NULL)
                 return -ENOMEM;
-        }
 
         md->lynx = &cards[cid];
         md->cid = cid;
@@ -859,11 +768,7 @@
 
 static int mem_release(struct inode *inode, struct file *file)
 {
-        struct memdata *md = (struct memdata *)file->private_data;
-
-        kfree(md);
-
-        V22_COMPAT_MOD_DEC_USE_COUNT;
+        kfree(file->private_data);
         return 0;
 }
 
@@ -1010,8 +915,8 @@
                 membase = md->lynx->aux_port;
                 break;
         default:
-                panic("pcilynx%d: unsupported md->type %d in " __FUNCTION__,
-                      md->lynx->id, md->type);
+                panic("pcilynx%d: unsupported md->type %d in %s",
+                      md->lynx->id, md->type, __FUNCTION__);
         }
 
         down(&md->lynx->mem_dma_mutex);
@@ -1291,6 +1196,7 @@
         }
 }
 
+
 static void iso_rcv_bh(struct ti_lynx *lynx)
 {
         unsigned int idx;
@@ -1335,44 +1241,102 @@
 }
 
 
+static void remove_card(struct pci_dev *dev)
+{
+        struct ti_lynx *lynx;
+        int i;
+
+        lynx = pci_get_drvdata(dev);
+        if (!lynx) return;
+        pci_set_drvdata(dev, NULL);
+
+        switch (lynx->state) {
+        case is_host:
+                reg_write(lynx, PCI_INT_ENABLE, 0);
+                hpsb_remove_host(lynx->host);
+        case have_intr:
+                reg_write(lynx, PCI_INT_ENABLE, 0);
+                free_irq(lynx->dev->irq, lynx);
+        case have_iomappings:
+                reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
+                /* Fix buggy cards with autoboot pin not tied low: */
+                reg_write(lynx, DMA0_CHAN_CTRL, 0);
+                iounmap(lynx->registers);
+                iounmap(lynx->local_rom);
+                iounmap(lynx->local_ram);
+                iounmap(lynx->aux_port);
+        case have_1394_buffers:
+                for (i = 0; i < ISORCV_PAGES; i++) {
+                        if (lynx->iso_rcv.page[i]) {
+                                pci_free_consistent(lynx->dev, PAGE_SIZE,
+                                                    lynx->iso_rcv.page[i],
+                                                    lynx->iso_rcv.page_dma[i]);
+                        }
+                }
+                pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page,
+                                    lynx->rcv_page_dma);
+        case have_aux_buf:
+#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
+                pci_free_consistent(lynx->dev, 65536, lynx->mem_dma_buffer,
+                                    lynx->mem_dma_buffer_dma);
+#endif
+        case have_pcl_mem:
+#ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM
+                pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem,
+                                    lynx->pcl_mem_dma);
+#endif
+        case clear:
+                /* do nothing - already freed */
+                ;
+        }
+
+	tasklet_kill(&lynx->iso_rcv.tq);
+	hpsb_unref_host(lynx->host);
+}
+
+
 static int __devinit add_card(struct pci_dev *dev,
-                              const struct pci_device_id *devid)
+                              const struct pci_device_id *devid_is_unused)
 {
 #define FAIL(fmt, args...) do { \
         PRINT_G(KERN_ERR, fmt , ## args); \
-        num_of_cards--; \
         remove_card(dev); \
-        return -1; \
+        return error; \
         } while (0)
 
+	struct hpsb_host *host;
         struct ti_lynx *lynx; /* shortcut to currently handled device */
-        unsigned int i;
+        struct ti_pcl pcl;
+        u32 *pcli;
+        int i;
+        int error;
 
-        if (num_of_cards == MAX_PCILYNX_CARDS) {
-                PRINT_G(KERN_WARNING, "cannot handle more than %d cards.  "
-                        "Adjust MAX_PCILYNX_CARDS in pcilynx.h.",
-                        MAX_PCILYNX_CARDS);
-                return -1;
-        }
+        /* needed for i2c communication with serial eeprom */
+        struct i2c_adapter i2c_adapter;
+        struct i2c_algo_bit_data i2c_adapter_data;
+
+        int got_valid_bus_info_block = 0; /* set to 1, if we were able to get a valid bus info block from serial eeprom */
 
-        lynx = &cards[num_of_cards++];
+        error = -ENXIO;
 
         if (pci_set_dma_mask(dev, 0xffffffff))
-                FAIL("DMA address limits not supported for PCILynx hardware %d",
-                     lynx->id);
+                FAIL("DMA address limits not supported for PCILynx hardware");
         if (pci_enable_device(dev))
-                FAIL("failed to enable PCILynx hardware %d", lynx->id);
+                FAIL("failed to enable PCILynx hardware");
         pci_set_master(dev);
 
-        lynx->host = hpsb_get_host(&lynx_template, 0);
-        if (!lynx->host)
-                FAIL("failed to allocate host structure");
-
-        lynx->state = have_host_struct;
-	lynx->host->hostdata = lynx;
-        lynx->id = num_of_cards-1;
+        error = -ENOMEM;
+
+	host = hpsb_alloc_host(lynx_driver, sizeof(struct ti_lynx));
+        if (!host) FAIL("failed to allocate control structure memory");
+
+        lynx = host->hostdata;
+	lynx->id = card_id++;
         lynx->dev = dev;
-	lynx->host->pdev = dev;
+        lynx->state = clear;
+	lynx->host = host;
+        host->pdev = dev;
+        pci_set_drvdata(dev, lynx);
 
         lynx->lock = SPIN_LOCK_UNLOCKED;
         lynx->phy_reg_lock = SPIN_LOCK_UNLOCKED;
@@ -1435,7 +1399,9 @@
         }
 #endif
 
-        reg_write(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
+        reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
+        /* Fix buggy cards with autoboot pin not tied low: */
+        reg_write(lynx, DMA0_CHAN_CTRL, 0);
 
         if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ,
                          PCILYNX_DRIVER_NAME, lynx)) {
@@ -1502,116 +1468,218 @@
                 PRINT(KERN_INFO, lynx->id, "found old 1394 PHY");
         }
 
-	/* Tell the highlevel this host is ready */
-	highlevel_add_one_host (lynx->host);
-
-        return 0;
-#undef FAIL
-}
+        lynx->selfid_size = -1;
+        lynx->phy_reg0 = -1;
 
-static void remove_card(struct pci_dev *dev)
-{
-        struct ti_lynx *lynx;
-        int i;
+        lynx->async.queue = NULL;
 
-        lynx = cards;
-        while (lynx->dev != dev) lynx++;
+        pcl.next = pcl_bus(lynx, lynx->rcv_pcl);
+        put_pcl(lynx, lynx->rcv_pcl_start, &pcl);
 
-        switch (lynx->state) {
-        case have_intr:
-                reg_write(lynx, PCI_INT_ENABLE, 0);
-                free_irq(lynx->dev->irq, lynx);
-        case have_iomappings:
-                reg_write(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
-                iounmap(lynx->registers);
-                iounmap(lynx->local_rom);
-                iounmap(lynx->local_ram);
-                iounmap(lynx->aux_port);
-        case have_1394_buffers:
-                for (i = 0; i < ISORCV_PAGES; i++) {
-                        if (lynx->iso_rcv.page[i]) {
-                                pci_free_consistent(lynx->dev, PAGE_SIZE,
-                                                    lynx->iso_rcv.page[i],
-                                                    lynx->iso_rcv.page_dma[i]);
-                        }
-                }
-                pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page,
-                                    lynx->rcv_page_dma);
-        case have_aux_buf:
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-                pci_free_consistent(lynx->dev, 65536, lynx->mem_dma_buffer,
-                                    lynx->mem_dma_buffer_dma);
+        pcl.next = PCL_NEXT_INVALID;
+        pcl.async_error_next = PCL_NEXT_INVALID;
+#ifdef __BIG_ENDIAN
+        pcl.buffer[0].control = PCL_CMD_RCV | 16;
+        pcl.buffer[1].control = PCL_LAST_BUFF | 4080;
+#else
+        pcl.buffer[0].control = PCL_CMD_RCV | PCL_BIGENDIAN | 16;
+        pcl.buffer[1].control = PCL_LAST_BUFF | 4080;
 #endif
-        case have_pcl_mem:
-#ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM
-                pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem,
-                                    lynx->pcl_mem_dma);
+        pcl.buffer[0].pointer = lynx->rcv_page_dma;
+        pcl.buffer[1].pointer = lynx->rcv_page_dma + 16;
+        put_pcl(lynx, lynx->rcv_pcl, &pcl);
+        
+        pcl.next = pcl_bus(lynx, lynx->async.pcl);
+        pcl.async_error_next = pcl_bus(lynx, lynx->async.pcl);
+        put_pcl(lynx, lynx->async.pcl_start, &pcl);
+
+        pcl.next = pcl_bus(lynx, lynx->iso_send.pcl);
+        pcl.async_error_next = PCL_NEXT_INVALID;
+        put_pcl(lynx, lynx->iso_send.pcl_start, &pcl);
+
+        pcl.next = PCL_NEXT_INVALID;
+        pcl.async_error_next = PCL_NEXT_INVALID;
+        pcl.buffer[0].control = PCL_CMD_RCV | 4;
+#ifndef __BIG_ENDIAN
+        pcl.buffer[0].control |= PCL_BIGENDIAN;
 #endif
-        case have_host_struct:
-                /* FIXME - verify host freeing */
-        case clear:;
-                /* do nothing - already freed */
+        pcl.buffer[1].control = PCL_LAST_BUFF | 2044;
+
+        for (i = 0; i < NUM_ISORCV_PCL; i++) {
+                int page = i / ISORCV_PER_PAGE;
+                int sec = i % ISORCV_PER_PAGE;
+
+                pcl.buffer[0].pointer = lynx->iso_rcv.page_dma[page] 
+                        + sec * MAX_ISORCV_SIZE;
+                pcl.buffer[1].pointer = pcl.buffer[0].pointer + 4;
+                put_pcl(lynx, lynx->iso_rcv.pcl[i], &pcl);
         }
 
-	tasklet_kill(&lynx->iso_rcv.tq);
+        pcli = (u32 *)&pcl;
+        for (i = 0; i < NUM_ISORCV_PCL; i++) {
+                pcli[i] = pcl_bus(lynx, lynx->iso_rcv.pcl[i]);
+        }
+        put_pcl(lynx, lynx->iso_rcv.pcl_start, &pcl);
 
-        lynx->state = clear;
-}
+        /* FIFO sizes from left to right: ITF=48 ATF=48 GRF=160 */
+        reg_write(lynx, FIFO_SIZES, 0x003030a0);
+        /* 20 byte threshold before triggering PCI transfer */
+        reg_write(lynx, DMA_GLOBAL_REGISTER, 0x2<<24);
+        /* threshold on both send FIFOs before transmitting:
+           FIFO size - cache line size - 1 */
+        i = reg_read(lynx, PCI_LATENCY_CACHELINE) & 0xff;
+        i = 0x30 - i - 1;
+        reg_write(lynx, FIFO_XMIT_THRESHOLD, (i << 8) | i);
 
-#if 0
-static int init_driver()
-{
-        struct pci_dev *dev = NULL;
-        int success = 0;
+        reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_1394);
 
-        if (num_of_cards) {
-                PRINT_G(KERN_DEBUG, __PRETTY_FUNCTION__ " called again");
-                return 0;
+        reg_write(lynx, LINK_INT_ENABLE, LINK_INT_PHY_TIMEOUT
+                  | LINK_INT_PHY_REG_RCVD  | LINK_INT_PHY_BUSRESET
+                  | LINK_INT_ISO_STUCK     | LINK_INT_ASYNC_STUCK 
+                  | LINK_INT_SENT_REJECT   | LINK_INT_TX_INVALID_TC
+                  | LINK_INT_GRF_OVERFLOW  | LINK_INT_ITF_UNDERFLOW
+                  | LINK_INT_ATF_UNDERFLOW);
+        
+        reg_write(lynx, DMA_WORD0_CMP_VALUE(CHANNEL_ASYNC_RCV), 0);
+        reg_write(lynx, DMA_WORD0_CMP_ENABLE(CHANNEL_ASYNC_RCV), 0xa<<4);
+        reg_write(lynx, DMA_WORD1_CMP_VALUE(CHANNEL_ASYNC_RCV), 0);
+        reg_write(lynx, DMA_WORD1_CMP_ENABLE(CHANNEL_ASYNC_RCV),
+                  DMA_WORD1_CMP_MATCH_LOCAL_NODE | DMA_WORD1_CMP_MATCH_BROADCAST
+                  | DMA_WORD1_CMP_MATCH_EXACT    | DMA_WORD1_CMP_MATCH_BUS_BCAST
+                  | DMA_WORD1_CMP_ENABLE_SELF_ID | DMA_WORD1_CMP_ENABLE_MASTER);
+
+        run_pcl(lynx, lynx->rcv_pcl_start, CHANNEL_ASYNC_RCV);
+
+        reg_write(lynx, DMA_WORD0_CMP_VALUE(CHANNEL_ISO_RCV), 0);
+        reg_write(lynx, DMA_WORD0_CMP_ENABLE(CHANNEL_ISO_RCV), 0x9<<4);
+        reg_write(lynx, DMA_WORD1_CMP_VALUE(CHANNEL_ISO_RCV), 0);
+        reg_write(lynx, DMA_WORD1_CMP_ENABLE(CHANNEL_ISO_RCV), 0);
+
+        run_sub_pcl(lynx, lynx->iso_rcv.pcl_start, 0, CHANNEL_ISO_RCV);
+
+        reg_write(lynx, LINK_CONTROL, LINK_CONTROL_RCV_CMP_VALID
+                  | LINK_CONTROL_TX_ISO_EN   | LINK_CONTROL_RX_ISO_EN
+                  | LINK_CONTROL_TX_ASYNC_EN | LINK_CONTROL_RX_ASYNC_EN
+                  | LINK_CONTROL_RESET_TX    | LINK_CONTROL_RESET_RX);
+
+        if (!lynx->phyic.reg_1394a) {
+                /* attempt to enable contender bit -FIXME- would this work
+                 * elsewhere? */
+                reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
+                reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1); 
+        } else {
+                /* set the contender bit in the extended PHY register
+                 * set. (Should check that bis 0,1,2 (=0xE0) is set
+                 * in register 2?)
+                 */
+                i = get_phy_reg(lynx, 4);
+                if (i != -1) set_phy_reg(lynx, 4, i | 0x40);
         }
 
-        PRINT_G(KERN_INFO, "looking for PCILynx cards");
 
-        while ((dev = pci_find_device(PCI_VENDOR_ID_TI,
-                                      PCI_DEVICE_ID_TI_PCILYNX, dev)) 
-               != NULL) {
-                if (add_card(dev) == 0) {
-                        success = 1;
+        if (!skip_eeprom)
+        {
+                i2c_adapter = bit_ops;
+                i2c_adapter_data = bit_data;
+                i2c_adapter.algo_data = &i2c_adapter_data;
+                i2c_adapter_data.data = lynx;
+
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+                PRINT(KERN_DEBUG, lynx->id,"original eeprom control: %d",reg_read(lynx,SERIAL_EEPROM_CONTROL));
+#endif
+
+        	/* reset hardware to sane state */
+        	lynx->i2c_driven_state = 0x00000070;
+        	reg_write(lynx, SERIAL_EEPROM_CONTROL, lynx->i2c_driven_state);
+
+        	if (i2c_bit_add_bus(&i2c_adapter) < 0)
+        	{
+	        	PRINT(KERN_ERR, lynx->id,  "unable to register i2c");
+        	}
+        	else
+        	{
+                        /* do i2c stuff */
+                        unsigned char i2c_cmd = 0x10;
+                        struct i2c_msg msg[2] = { { 0x50, 0, 1, &i2c_cmd }, 
+                                                  { 0x50, I2C_M_RD, 20, (unsigned char*) lynx->config_rom }
+                                                };
+
+
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+                        union i2c_smbus_data data;
+
+                        if (i2c_smbus_xfer(&i2c_adapter, 80, 0, I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE,NULL))
+                                PRINT(KERN_ERR, lynx->id,"eeprom read start has failed");
+                        else
+                        {
+                                u16 addr;
+                                for (addr=0x00; addr < 0x100; addr++) {
+                                        if (i2c_smbus_xfer(&i2c_adapter, 80, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE,& data)) {
+                                                PRINT(KERN_ERR, lynx->id, "unable to read i2c %x", addr);
+                                                break;
+                                        }
+                                        else
+                                                PRINT(KERN_DEBUG, lynx->id,"got serial eeprom data at %x: %x",addr, data.byte);
+                                }
+                        }
+#endif
+
+                        /* we use i2c_transfer, because i2c_smbus_read_block_data does not work properly and we
+                           do it more efficiently in one transaction rather then using several reads */
+                        if (i2c_transfer(&i2c_adapter, msg, 2) < 0) {
+                                PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c");
+                        } else {
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+                                int i;
+#endif
+                                PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom");
+                                /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a), generation(1394a) and link_spd(1394a) field
+                                   and recalculate the CRC */
+
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+                                for (i=0; i < 5 ; i++)
+                                        PRINT(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x",i, be32_to_cpu(lynx->config_rom[i]));
+#endif
+
+                                /* info_length, crc_length and 1394 magic number to check, if it is really a bus info block */
+                                if (((be32_to_cpu(lynx->config_rom[0]) & 0xffff0000) == 0x04040000) &&
+                                    (lynx->config_rom[1] == __constant_cpu_to_be32(0x31333934)))
+                                {
+                                        PRINT(KERN_DEBUG, lynx->id, "read a valid bus info block from");
+                                        got_valid_bus_info_block = 1;
+                                } else {
+                                        PRINT(KERN_WARNING, lynx->id, "read something from serial eeprom, but it does not seem to be a valid bus info block");
+                                }
+
+                        }
+
+                        i2c_bit_del_bus(&i2c_adapter);
                 }
         }
 
-        if (success == 0) {
-                PRINT_G(KERN_WARNING, "no operable PCILynx cards found");
-                return -ENXIO;
+        if (got_valid_bus_info_block) {
+                memcpy(lynx->config_rom+5,lynx_csr_rom+5,sizeof(lynx_csr_rom)-20);
+        } else {
+                PRINT(KERN_INFO, lynx->id, "since we did not get a bus info block from serial eeprom, we use a generic one with a hard coded GUID");
+                memcpy(lynx->config_rom,lynx_csr_rom,sizeof(lynx_csr_rom));
         }
 
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        if (register_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME, &aux_ops)) {
-                PRINT_G(KERN_ERR, "allocation of char major number %d failed",
-                        PCILYNX_MAJOR);
-                return -EBUSY;
-        }
-#endif
+        hpsb_add_host(host);
+        lynx->state = is_host;
 
         return 0;
+#undef FAIL
 }
-#endif
+
 
 
 static size_t get_lynx_rom(struct hpsb_host *host, const quadlet_t **ptr)
 {
-        *ptr = lynx_csr_rom;
+        struct ti_lynx *lynx = host->hostdata;
+        *ptr = lynx->config_rom;
         return sizeof(lynx_csr_rom);
 }
 
-static struct hpsb_host_template lynx_template = {
-	name:             PCILYNX_DRIVER_NAME,
-	initialize_host:  lynx_initialize,
-	release_host:     lynx_release,
-	get_rom:          get_lynx_rom,
-	transmit_packet:  lynx_transmit,
-	devctl:           lynx_devctl
-};
-
 static struct pci_device_id pci_table[] __devinitdata = {
 	{
                 vendor:     PCI_VENDOR_ID_TI,
@@ -1622,11 +1690,17 @@
 	{ }			/* Terminating entry */
 };
 
-static struct pci_driver lynx_pcidriver = {
+static struct pci_driver lynx_pci_driver = {
         name:      PCILYNX_DRIVER_NAME,
         id_table:  pci_table,
         probe:     add_card,
-        remove:    remove_card,
+        remove:    __devexit_p(remove_card),
+};
+
+static struct hpsb_host_operations lynx_ops = {
+        get_rom:          get_lynx_rom,
+        transmit_packet:  lynx_transmit,
+        devctl:           lynx_devctl,
 };
 
 MODULE_AUTHOR("Andreas E. Bombe <andreas.bombe@munich.netsurf.de>");
@@ -1635,30 +1709,52 @@
 MODULE_SUPPORTED_DEVICE("pcilynx");
 MODULE_DEVICE_TABLE(pci, pci_table);
 
-static void __exit pcilynx_cleanup(void)
-{
-        hpsb_unregister_lowlevel(&lynx_template);
-	pci_unregister_driver(&lynx_pcidriver);
-        PRINT_G(KERN_INFO, "removed " PCILYNX_DRIVER_NAME " module");
-}
-
 static int __init pcilynx_init(void)
 {
         int ret;
 
-        if (hpsb_register_lowlevel(&lynx_template)) {
-                PRINT_G(KERN_ERR, "registering failed");
-                return -ENXIO;
+#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
+        if (register_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME, &aux_ops)) {
+                PRINT_G(KERN_ERR, "allocation of char major number %d failed",
+                        PCILYNX_MAJOR);
+                return -EBUSY;
+        }
+#endif
+
+        lynx_driver = hpsb_register_lowlevel(&lynx_ops, PCILYNX_DRIVER_NAME);
+        if (!lynx_driver) {
+                ret = -ENOMEM;
+                goto free_char_dev;
         }
 
-        ret = pci_module_init(&lynx_pcidriver);
+        ret = pci_module_init(&lynx_pci_driver);
         if (ret < 0) {
                 PRINT_G(KERN_ERR, "PCI module init failed");
-                hpsb_unregister_lowlevel(&lynx_template);
+                goto unregister_lowlevel;
         }
 
+        return 0;
+
+ unregister_lowlevel:
+        hpsb_unregister_lowlevel(lynx_driver);
+ free_char_dev:
+#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
+        unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME);
+#endif
+
         return ret;
 }
 
+static void __exit pcilynx_cleanup(void)
+{
+        pci_unregister_driver(&lynx_pci_driver);
+        hpsb_unregister_lowlevel(lynx_driver);
+
+#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
+        unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME);
+#endif
+}
+
+
 module_init(pcilynx_init);
 module_exit(pcilynx_cleanup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/pcilynx.h linux/drivers/ieee1394/pcilynx.h
--- linux.orig/drivers/ieee1394/pcilynx.h	2001-08-12 19:39:02.000000000 +0000
+++ linux/drivers/ieee1394/pcilynx.h	2002-07-20 01:08:22.000000000 +0000
@@ -25,6 +25,8 @@
 #define CHANNEL_ASYNC_SEND       3
 #define CHANNEL_ISO_SEND         4
 
+#define PCILYNX_CONFIG_ROM_LENGTH   1024
+
 typedef int pcl_t;
 
 struct ti_lynx {
@@ -40,15 +42,15 @@
                 u32 product;
         } phyic;
 
-        enum { clear, have_host_struct,  have_intr, have_aux_buf, have_pcl_mem,
-               have_1394_buffers, have_iomappings } state;
+        enum { clear, have_intr, have_aux_buf, have_pcl_mem,
+               have_1394_buffers, have_iomappings, is_host } state;
         
         /* remapped memory spaces */
         void *registers;
         void *local_rom;
         void *local_ram;
         void *aux_port;
-
+        quadlet_t config_rom[PCILYNX_CONFIG_ROM_LENGTH/4];
 
 #ifdef CONFIG_IEEE1394_PCILYNX_PORTS
         atomic_t aux_intr_seen;
@@ -109,6 +111,8 @@
                 struct tasklet_struct tq;
                 spinlock_t lock;
         } iso_rcv;
+
+	u32 i2c_driven_state; /* the state we currently drive the Serial EEPROM Control register */
 };
 
 /* the per-file data structure for mem space access */
@@ -156,6 +160,8 @@
 #define MISC_CONTROL                      0x40
 #define MISC_CONTROL_SWRESET              (1<<0)
 
+#define SERIAL_EEPROM_CONTROL             0x44
+
 #define PCI_INT_STATUS                    0x48
 #define PCI_INT_ENABLE                    0x4c               
 /* status and enable have identical bit numbers */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/raw1394.c linux/drivers/ieee1394/raw1394.c
--- linux.orig/drivers/ieee1394/raw1394.c	2001-10-02 04:24:24.000000000 +0000
+++ linux/drivers/ieee1394/raw1394.c	2002-07-20 01:08:22.000000000 +0000
@@ -21,10 +21,7 @@
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)
 #include <linux/devfs_fs_kernel.h>
-#endif
 
 #include "ieee1394.h"
 #include "ieee1394_types.h"
@@ -192,6 +189,8 @@
         }
 
         kfree(hi);
+
+        atomic_inc(&internal_generation);
 }
 
 static void host_reset(struct hpsb_host *host)
@@ -226,8 +225,6 @@
                 }
         }
         spin_unlock_irqrestore(&host_info_lock, flags);
-
-        atomic_inc(&internal_generation);
 }
 
 static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
@@ -467,7 +464,7 @@
                                 hi = list_entry(lh, struct host_info, list);
 
                                 khl->nodes = hi->host->node_count;
-                                strcpy(khl->name, hi->host->template->name);
+                                strcpy(khl->name, hi->host->driver->name);
 
                                 khl++;
                         }
@@ -495,7 +492,7 @@
                                 lh = lh->next;
                         }
                         hi = list_entry(lh, struct host_info, list);
-                        hpsb_inc_host_usage(hi->host);
+                        hpsb_ref_host(hi->host);
                         list_add_tail(&fi->list, &hi->file_info_list);
                         fi->host = hi->host;
                         fi->state = connected;
@@ -915,17 +912,13 @@
 {
         struct file_info *fi;
 
-        if (MINOR(inode->i_rdev)) {
+        if (ieee1394_file_to_instance(file) > 0) {
                 return -ENXIO;
         }
 
-        V22_COMPAT_MOD_INC_USE_COUNT;
-
         fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL);
-        if (fi == NULL) {
-                V22_COMPAT_MOD_DEC_USE_COUNT;
+        if (fi == NULL)
                 return -ENOMEM;
-        }
         
         memset(fi, 0, sizeof(struct file_info));
 
@@ -949,7 +942,6 @@
         struct pending_request *req;
         int done = 0, i;
 
-        lock_kernel();
         for (i = 0; i < 64; i++) {
                 if (fi->listen_channels & (1ULL << i)) {
                         hpsb_unlisten_channel(hl_handle, fi->host, i);
@@ -984,13 +976,11 @@
                 list_del(&fi->list);
                 spin_unlock_irq(&host_info_lock);
 
-                hpsb_dec_host_usage(fi->host);
+                hpsb_unref_host(fi->host);
         }
 
         kfree(fi);
 
-        V22_COMPAT_MOD_DEC_USE_COUNT;
-        unlock_kernel();
         return 0;
 }
 
@@ -1003,12 +993,12 @@
 };
 
 static struct file_operations file_ops = {
-        OWNER_THIS_MODULE
-        read:     raw1394_read, 
-        write:    raw1394_write, 
-        poll:     raw1394_poll, 
-        open:     raw1394_open, 
-        release:  raw1394_release, 
+	owner:		THIS_MODULE,
+        read:		raw1394_read, 
+        write:		raw1394_write, 
+        poll:		raw1394_poll, 
+        open:		raw1394_open, 
+        release:	raw1394_release, 
 };
 
 static int __init init_raw1394(void)
@@ -1019,14 +1009,18 @@
                 return -ENOMEM;
         }
 
-	devfs_handle = devfs_register(NULL, RAW1394_DEVICE_NAME, DEVFS_FL_NONE,
-                                      RAW1394_DEVICE_MAJOR, 0,
+	devfs_handle = devfs_register(NULL,
+				      RAW1394_DEVICE_NAME, DEVFS_FL_NONE,
+                                      IEEE1394_MAJOR,
+				      IEEE1394_MINOR_BLOCK_RAW1394 * 16,
                                       S_IFCHR | S_IRUSR | S_IWUSR, &file_ops,
                                       NULL);
 
-        if (devfs_register_chrdev(RAW1394_DEVICE_MAJOR, RAW1394_DEVICE_NAME, 
-                                  &file_ops)) {
-                HPSB_ERR("raw1394 failed to register /dev/raw1394 device");
+        if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_RAW1394,
+				      THIS_MODULE, &file_ops)) {
+                HPSB_ERR("raw1394 failed to register minor device block");
+		devfs_unregister(devfs_handle);
+		hpsb_unregister_highlevel(hl_handle);
                 return -EBUSY;
         }
 	printk(KERN_INFO "raw1394: /dev/%s device initialized\n", RAW1394_DEVICE_NAME);
@@ -1035,7 +1029,7 @@
 
 static void __exit cleanup_raw1394(void)
 {
-        devfs_unregister_chrdev(RAW1394_DEVICE_MAJOR, RAW1394_DEVICE_NAME);
+        ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_RAW1394);
 	devfs_unregister(devfs_handle);
         hpsb_unregister_highlevel(hl_handle);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/sbp2.c linux/drivers/ieee1394/sbp2.c
--- linux.orig/drivers/ieee1394/sbp2.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/ieee1394/sbp2.c	2002-07-20 01:08:26.000000000 +0000
@@ -2,7 +2,7 @@
  * sbp2.c - SBP-2 protocol driver for IEEE-1394
  *
  * Copyright (C) 2000 James Goodwin, Filanet Corporation (www.filanet.com)
- * jamesg@filanet.com
+ * jamesg@filanet.com (JSG)
  *
  * 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
@@ -27,6 +27,7 @@
  * driver. It also registers as a SCSI lower-level driver in order to accept
  * SCSI commands for transport using SBP-2.
  *
+ *
  * Driver Loading:
  *
  * Currently, the SBP-2 driver is supported only as a module. Because the 
@@ -45,7 +46,7 @@
  *
  * Currently, the SBP-2 driver will catch any attached SBP-2 devices during the
  * initial scsi bus scan (when the driver is first loaded). To add or remove
- * SBP-2 devices after this initial scan (i.e. if you plug-in or un-plug a 
+ * SBP-2 devices "after" this initial scan (i.e. if you plug-in or un-plug a 
  * device after the SBP-2 driver is loaded), you must either use the scsi procfs
  * add-single-device, remove-single-device, or a shell script such as 
  * rescan-scsi-bus.sh.
@@ -76,14 +77,31 @@
  * fdisk, mkfs, etc.).
  *
  *
+ * Module Load Options:
+ *
+ * sbp2_max_speed 		- Force max speed allowed 
+ *				  (2 = 400mb, 1 = 200mb, 0 = 100mb. default = 2)
+ * sbp2_serialize_io		- Serialize all I/O coming down from the scsi drivers 
+ *				  (0 = deserialized, 1 = serialized, default = 0)
+ * sbp2_max_sectors, 		- Change max sectors per I/O supported (default = 255)
+ * sbp2_max_outstanding_cmds	- Change max outstanding concurrent commands (default = 8)
+ * sbp2_max_cmds_per_lun	- Change max concurrent commands per sbp2 device (default = 1)
+ * sbp2_exclusive_login		- Set to zero if you'd like to allow multiple hosts the ability
+ *				  to log in at the same time. Sbp2 device must support this,
+ *				  and you must know what you're doing (default = 1)
+ *
+ * (e.g. insmod sbp2 sbp2_serialize_io = 1)
+ *
+ *
  * Current Support:
  *
  * The SBP-2 driver is still in an early state, but supports a variety of devices.
  * I have read/written many gigabytes of data from/to SBP-2 drives, and have seen 
- * performance of more than 16 MBytes/s on individual drives (limit of the media 
+ * performance of more than 25 MBytes/s on individual drives (limit of the media 
  * transfer rate).
  *
- * Following are the devices that have been tested successfully:
+ *
+ * Following are a sampling of devices that have been tested successfully:
  *
  *	- Western Digital IEEE-1394 hard drives
  *	- Maxtor IEEE-1394 hard drives
@@ -91,7 +109,7 @@
  *	- LaCie IEEE-1394 hard drives (several flavors)
  *	- QPS IEEE-1394 CD-RW/DVD drives and hard drives
  *	- BusLink IEEE-1394 hard drives
- *	- Iomega IEEE-1394 Zip/Jazz drives
+ *	- Iomega IEEE-1394 Zip/Jazz/Peerless drives
  *	- ClubMac IEEE-1394 hard drives
  *	- FirePower IEEE-1394 hard drives
  *	- EzQuest IEEE-1394 hard drives and CD-RW drives
@@ -102,9 +120,8 @@
  *	- APDrives IEEE-1394 hard drives
  *	- Fujitsu IEEE-1394 MO drives
  *	- Sony IEEE-1394 CD-RW drives
- *	- Epson IEEE-1394 scanner
+ *	- Epson IEEE-1394 scanners
  *	- ADS IEEE-1394 memory stick and compact flash readers 
- *	  (e.g. "insmod sbp2 mode_sense_hack=1" for mem stick and flash readers))
  *	- SBP-2 bridge-based devices (LSI, Oxford Semiconductor, Indigita bridges)
  *	- Various other standard IEEE-1394 hard drives and enclosures
  *
@@ -118,21 +135,16 @@
  *
  * Current Issues:
  *
- *	- Currently, all I/O from the scsi stack is serialized by default, as there
- *	  are some stress issues under investigation with deserialized I/O. To enable
- *	  deserialized I/O for testing, do "insmod sbp2 serialize_io=0"
- *
  *	- Error Handling: SCSI aborts and bus reset requests are handled somewhat
  *	  but the code needs additional debugging.
  *
- *	- The SBP-2 driver is currently only supported as a module. It would not take
+ *	- Module: The SBP-2 driver is currently only supported as a module. It would not take
  *	  much work to allow it to be compiled into the kernel, but you'd have to 
  *	  add some init code to the kernel to support this... and modules are much
  *	  more flexible anyway.   ;-)
  *
- *     - The scsi stack in recent kernels pass down the data transfer
- *       direction as scsicmd->sc_data_direction, which we should use
- *       instead of the sbp2scsi_direction_table.
+ *	- Hot-plugging: Interaction with the SCSI stack and support for hot-plugging could
+ *	  stand some improvement.
  *
  *
  * History:
@@ -239,9 +251,55 @@
  *                   upon module unload.  Moved much initialization
  *                   from sbp2scsi_detect to sbp2_module_init.
  *                                 Kristian Hogsberg <hogsberg@users.sf.net>
+ *	01/06/02 - Misc bug fixes/enhancements:	(JSG)
+ *		   * Enable use_new_eh_code for scsi stuff.
+ *		   * Do not write all ones for NULL ORB high/low fields, but
+ *		     rather leave reserved areas zeroed (per SBP2 spec).
+ *		   * Use newer scsi transfer direction passed down instead of our
+ *		     direction table.
+ *		   * Bumped login time-out to 20 seconds, as some devices are slow.
+ *		   * Fixed a couple scsi unregister bugs on module unload
+ *	01/13/02 - Fixed compatibility with certain SBP2 devices, such as Iomega
+ *		   1394 devices (Peerless, Jazz). Also a bit of clean-up of the 
+ *		   driver, thanks to H.J.Lu (hjl@lucon.org). Removed mode_sense_hack
+ *		   module load option, as it's been fixed in the 2.4 scsi stack.
+ *	02/10/02 - Added support for max_sectors, minor fix for inquiry command, make
+ *		   up sbp2 device type from inquiry response data if not part of 
+ *		   device's 1394 unit directory. (JSG)
+ *	02/18/02 - Code clean-up and enhancements: (JSG)
+ *		   * Finish cleaning out hacked code for dealing with broken sbp2 devices
+ *		     which do not support requests of 128KB or greater. Now use 
+ *		     max_sectors scsi host entry to limit transfer sizes.
+ *		   * Change status fifo address from a single address to a set of addresses,
+ *		     with each sbp2 device having its own status fifo address. This makes
+ *		     it easier to match the status write to the sbp2 device instance.
+ *		   * Minor change to use lun when logging into sbp2 devices. First step in
+ *		     supporting multi-lun devices such as CD/DVD changer devices.
+ *		   * Added a new module load option for setting max sectors. For use by folk
+ *		     who'd like to bump up the max scsi transfer size supported.
+ *		   * Enabled deserialized operation by default, allowing for better performance,
+ *		     particularily when running with multiple sbp2 devices. For debugging,
+ *		     you may enable serialization through use of the sbp2_serialize_io module
+ *		     load option (e.g. insmod sbp2 sbp2_serialize_io=1).
+ *	02/20/02 - Added a couple additional module load options. 
+ *		   Needed to bump down max commands per lun because of the !%@&*^# QPS CDRW 
+ *		   drive I have, which doesn't seem to get along with other sbp2 devices 
+ *		   (or handle linked commands well).
+ *	04/21/02 - Added some additional debug capabilities:
+ *		   * Able to handle phys dma requests directly, if host controller has phys
+ *		     dma disabled (e.g. insmod ohci1394 phys_dma=0). Undefine CONFIG_IEEE1394_SBP2_PHYS_DMA
+ *		     if you'd like to disable sbp2 driver from registering for phys address range. 
+ *		   * New packet dump debug define (CONFIG_IEEE1394_SBP2_PACKET_DUMP) which allows
+ *		     dumping of all sbp2 related packets sent and received. Especially effective
+ *		     when phys dma is disabled on ohci controller (e.g. insmod ohci1394 phys_dma=0).
+ *		   * Added new sbp2 module load option (sbp2_exclusive_login) for allowing
+ *		     non-exclusive login to sbp2 device, for special multi-host applications.
+ *	04/23/02 - Fix for Sony CD-ROM drives. Only send fetch agent reset to sbp2 device if it
+ *		   returns the dead bit in status. Thanks to Chandan (chandan@toad.net) for this one.
+ *	04/27/02 - Fix sbp2 login problem on SMP systems, enable real spinlocks by default. (JSG)
+ *	06/09/02 - Don't force 36-bute SCSI inquiry, but leave in a define for badly behaved devices. (JSG)   
  */
 
-
 
 /*
  * Includes
@@ -266,10 +324,21 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
+#include <asm/atomic.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/scatterlist.h>
 
+#ifdef CONFIG_KBUILD_2_5
+#include <scsi.h>
+#include <hosts.h>
+#include <sd.h>
+#else
+#include "../scsi/scsi.h"
+#include "../scsi/hosts.h"
+#include "../scsi/sd.h"
+#endif
+
 #include "ieee1394.h"
 #include "ieee1394_types.h"
 #include "ieee1394_core.h"
@@ -278,27 +347,17 @@
 #include "highlevel.h"
 #include "ieee1394_transactions.h"
 #include "ieee1394_hotplug.h"
-#include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
-#include "../scsi/sd.h"
 #include "sbp2.h"
 
-/*
- * Module load parameter definitions
- */
+static char version[] __devinitdata =
+	"$Rev: 515 $ James Goodwin <jamesg@filanet.com>";
 
 /*
- * Set mode_sense_hack to 1 if you have some sort of unusual sbp2 device,
- * like a 1394 memory stick reader, compact flash reader, or MO drive that
- * does not support mode sense. Allows you to mount the media rw instead
- * of ro.
+ * Module load parameter definitions
  */
-MODULE_PARM(mode_sense_hack,"i");
-MODULE_PARM_DESC(mode_sense_hack, "Emulate mode sense for devices like 1394 memory stick readers");
-static int mode_sense_hack = 0;
 
 /*
- * Change max_speed on module load if you have a bad IEEE-1394 controller
+ * Change sbp2_max_speed on module load if you have a bad IEEE-1394 controller
  * that has trouble running 2KB packets at 400mb.
  *
  * NOTE: On certain OHCI parts I have seen short packets on async transmit
@@ -306,31 +365,63 @@
  * bump down the speed if you are running into problems.
  *
  * Valid values:
- * max_speed = 2 (default: max speed 400mb)
- * max_speed = 1 (max speed 200mb)
- * max_speed = 0 (max speed 100mb)
+ * sbp2_max_speed = 2 (default: max speed 400mb)
+ * sbp2_max_speed = 1 (max speed 200mb)
+ * sbp2_max_speed = 0 (max speed 100mb)
+ */
+MODULE_PARM(sbp2_max_speed,"i");
+MODULE_PARM_DESC(sbp2_max_speed, "Force max speed (2 = 400mb default, 1 = 200mb, 0 = 100mb)");
+static int sbp2_max_speed = SPEED_400;
+
+/*
+ * Set sbp2_serialize_io to 1 if you'd like only one scsi command sent down to
+ * us at a time (debugging). This might be necessary for very badly behaved sbp2 devices.
+ */
+MODULE_PARM(sbp2_serialize_io,"i");
+MODULE_PARM_DESC(sbp2_serialize_io, "Serialize all I/O coming down from the scsi drivers (default = 0)");
+static int sbp2_serialize_io = 0;	/* serialize I/O - available for debugging purposes */
+
+/*
+ * Bump up sbp2_max_sectors if you'd like to support very large sized transfers. Please note 
+ * that some older sbp2 bridge chips are broken for transfers greater or equal to 128KB.
+ * Default is a value of 255 sectors, or just under 128KB (at 512 byte sector size). I can note
+ * that the Oxsemi sbp2 chipsets have no problems supporting very large transfer sizes.
  */
-MODULE_PARM(max_speed,"i");
-MODULE_PARM_DESC(max_speed, "Force down max speed (2 = 400mb default, 1 = 200mb, 0 = 100mb)");
-static int max_speed = SPEED_400;
+MODULE_PARM(sbp2_max_sectors,"i");
+MODULE_PARM_DESC(sbp2_max_sectors, "Change max sectors per I/O supported (default = 255)");
+static int sbp2_max_sectors = SBP2_MAX_SECTORS;
 
 /*
- * Set serialize_io to 1 if you'd like only one scsi command sent down to
- * us at a time (debugging).
+ * Adjust sbp2_max_outstanding_cmds to tune performance if you have many sbp2 devices attached
+ * (or if you need to do some debugging).
  */
-MODULE_PARM(serialize_io,"i");
-MODULE_PARM_DESC(serialize_io, "Serialize all I/O coming down from the scsi drivers (debugging)");
-static int serialize_io = 1;	/* serialize I/O until stress issues are resolved */
+MODULE_PARM(sbp2_max_outstanding_cmds,"i");
+MODULE_PARM_DESC(sbp2_max_outstanding_cmds, "Change max outstanding concurrent commands (default = 8)");
+static int sbp2_max_outstanding_cmds = SBP2SCSI_MAX_OUTSTANDING_CMDS;
 
 /*
- * Set no_large_packets to 1 if you'd like to limit the size of requests
- * sent down to us (normally the sbp2 driver will break up any requests to
- * any individual devices with 128KB transfer size limits).  Sets max s/g
- * list elements to 0x1f in size and disables s/g clustering.
+ * Adjust sbp2_max_cmds_per_lun to tune performance. Enabling more than one concurrent/linked 
+ * command per sbp2 device may allow some performance gains, but some older sbp2 devices have 
+ * firmware bugs resulting in problems when linking commands... so, enable this with care. 
+ * I can note that the Oxsemi OXFW911 sbp2 chipset works very well with large numbers of 
+ * concurrent/linked commands.  =)
  */
-MODULE_PARM(no_large_packets,"i");
-MODULE_PARM_DESC(no_large_packets, "Do not allow large transfers from scsi drivers (debugging)");
-static int no_large_packets = 0;
+MODULE_PARM(sbp2_max_cmds_per_lun,"i");
+MODULE_PARM_DESC(sbp2_max_cmds_per_lun, "Change max concurrent commands per sbp2 device (default = 1)");
+static int sbp2_max_cmds_per_lun = SBP2SCSI_MAX_CMDS_PER_LUN;
+
+/*
+ * Exclusive login to sbp2 device? In most cases, the sbp2 driver should do an exclusive login, as it's
+ * generally unsafe to have two hosts talking to a single sbp2 device at the same time (filesystem
+ * coherency, etc.). If you're running an sbp2 device that supports multiple logins, and you're either
+ * running read-only filesystems or some sort of special filesystem supporting multiple hosts, then
+ * set sbp2_exclusive_login to zero. Note: The Oxsemi OXFW911 sbp2 chipset supports up to four
+ * concurrent logins.
+ */
+MODULE_PARM(sbp2_exclusive_login,"i");
+MODULE_PARM_DESC(sbp2_exclusive_login, "Exclusive login to sbp2 device (default = 1)");
+static int sbp2_exclusive_login = 1;
+
 
 /*
  * Export information about protocols/devices supported by this driver.
@@ -348,11 +439,17 @@
 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
 
 /*
- * Debug levels, configured via kernel config.
+ * Debug levels, configured via kernel config, or enable here.
  */
 
+/* #define CONFIG_IEEE1394_SBP2_DEBUG_ORBS */
+/* #define CONFIG_IEEE1394_SBP2_DEBUG_DMA */
+/* #define CONFIG_IEEE1394_SBP2_DEBUG 1 */
+/* #define CONFIG_IEEE1394_SBP2_DEBUG 2 */
+/* #define CONFIG_IEEE1394_SBP2_PACKET_DUMP */
+
 #ifdef CONFIG_IEEE1394_SBP2_DEBUG_ORBS
-#define SBP2_ORB_DEBUG(fmt, args...)	HPSB_ERR("sbp2("__FUNCTION__"): "fmt, ## args)
+#define SBP2_ORB_DEBUG(fmt, args...)	HPSB_ERR("sbp2(%s): "fmt, __FUNCTION__, ## args)
 static u32 global_outstanding_command_orbs = 0;
 #define outstanding_orb_incr global_outstanding_command_orbs++
 #define outstanding_orb_decr global_outstanding_command_orbs--
@@ -364,10 +461,10 @@
 
 #ifdef CONFIG_IEEE1394_SBP2_DEBUG_DMA
 #define SBP2_DMA_ALLOC(fmt, args...) \
-	HPSB_ERR("sbp2("__FUNCTION__")alloc(%d): "fmt, \
+	HPSB_ERR("sbp2(%s)alloc(%d): "fmt, __FUNCTION__, \
 		 ++global_outstanding_dmas, ## args)
 #define SBP2_DMA_FREE(fmt, args...) \
-	HPSB_ERR("sbp2("__FUNCTION__")free(%d): "fmt, \
+	HPSB_ERR("sbp2(%s)free(%d): "fmt, __FUNCTION__, \
 		 --global_outstanding_dmas, ## args)
 static u32 global_outstanding_dmas = 0;
 #else
@@ -375,7 +472,6 @@
 #define SBP2_DMA_FREE(fmt, args...)
 #endif
 
-
 #if CONFIG_IEEE1394_SBP2_DEBUG >= 2
 #define SBP2_DEBUG(fmt, args...)	HPSB_ERR("sbp2: "fmt, ## args)
 #define SBP2_INFO(fmt, args...)		HPSB_ERR("sbp2: "fmt, ## args)
@@ -388,18 +484,18 @@
 #define SBP2_WARN(fmt, args...)		HPSB_WARN("sbp2: "fmt, ## args)
 #else 
 #define SBP2_DEBUG(fmt, args...)
-#define SBP2_INFO(fmt, args...)
-#define SBP2_NOTICE(fmt, args...)
-#define SBP2_WARN(fmt, args...)
+#define SBP2_INFO(fmt, args...)		HPSB_INFO("sbp2: "fmt, ## args)
+#define SBP2_NOTICE(fmt, args...)       HPSB_NOTICE("sbp2: "fmt, ## args)
+#define SBP2_WARN(fmt, args...)         HPSB_WARN("sbp2: "fmt, ## args)
 #endif
 
 #define SBP2_ERR(fmt, args...)		HPSB_ERR("sbp2: "fmt, ## args)
 
 /*
- * Spinlock debugging stuff. I'm playing it safe until the driver has been
- * debugged on SMP. (JSG)
+ * Spinlock debugging stuff.
  */
-/* #define SBP2_USE_REAL_SPINLOCKS */
+#define SBP2_USE_REAL_SPINLOCKS
+
 #ifdef SBP2_USE_REAL_SPINLOCKS
 #define sbp2_spin_lock(lock, flags)	spin_lock_irqsave(lock, flags)	
 #define sbp2_spin_unlock(lock, flags)	spin_unlock_irqrestore(lock, flags);
@@ -410,6 +506,14 @@
 #endif
 
 /*
+ * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on if your sbp2 device
+ * is not properly handling the SCSI inquiry command. This hack makes the inquiry look more 
+ * like a typical MS Windows inquiry.
+ */
+
+/* #define SBP2_FORCE_36_BYTE_INQUIRY */
+
+/*
  * Globals
  */
 
@@ -418,7 +522,6 @@
 static u8 sbp2_speedto_maxrec[] = { 0x7, 0x8, 0x9 };
 
 static LIST_HEAD(sbp2_host_info_list);
-static int sbp2_host_count = 0;
 
 static struct hpsb_highlevel *sbp2_hl_handle = NULL;
 
@@ -431,6 +534,13 @@
 	write: sbp2_handle_status_write
 };
 
+#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
+static struct hpsb_address_ops sbp2_physdma_ops = {
+        read: sbp2_handle_physdma_read,
+        write: sbp2_handle_physdma_write,
+};
+#endif
+
 static struct hpsb_protocol_driver sbp2_driver = {
 	name:		"SBP2 Driver",
 	id_table: 	sbp2_id_table,
@@ -439,7 +549,6 @@
 	update: 	sbp2_update
 };
 
-
 
 /**************************************
  * General utility functions
@@ -478,6 +587,56 @@
 #define sbp2util_cpu_to_be32_buffer(x,y)
 #endif
 
+#ifdef CONFIG_IEEE1394_SBP2_PACKET_DUMP
+/*
+ * Debug packet dump routine. Length is in bytes.
+ */
+static void sbp2util_packet_dump(void *buffer, int length, char *dump_name, u32 dump_phys_addr)
+{
+	int i;
+	unsigned char *dump = buffer;
+
+	if (!dump || !length || !dump_name)
+		return;
+
+	if (dump_phys_addr)
+		printk("[%s, 0x%x]", dump_name, dump_phys_addr);
+	else
+		printk("[%s]", dump_name);
+	for (i = 0; i < length; i++) {
+		if (i > 0x3f) {
+			printk("\n   ...");
+			break;
+		}
+		if ((i & 0x3) == 0)
+			printk("  ");
+		if ((i & 0xf) == 0)
+			printk("\n   ");
+		printk("%02x ", (int) dump[i]);
+	}
+	printk("\n");
+
+	return;
+}
+#else
+#define sbp2util_packet_dump(w,x,y,z)
+#endif
+
+/*
+ * Goofy routine that basically does a down_timeout function.
+ */
+static int sbp2util_down_timeout(atomic_t *done, int timeout)
+{
+	int i;
+
+	for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (schedule_timeout(HZ/10))	/* 100ms */
+			return(1);
+	}
+	return ((i > 0) ? 0:1);
+}
+
 /*
  * This function is called to initially create a packet pool for use in
  * sbp2 I/O requests. This packet pool is used when sending out sbp2
@@ -489,7 +648,19 @@
 	struct hpsb_packet *packet;
 	int i;
 
-	/* Create SBP2_MAX_REQUEST_PACKETS number of request packets. */
+	hi->request_packet = kmalloc(sizeof(struct sbp2_request_packet) * SBP2_MAX_REQUEST_PACKETS, 
+				     GFP_KERNEL);
+
+	if (!hi->request_packet) {
+		SBP2_ERR("sbp2util_create_request_packet_pool - packet allocation failed!");
+		return(-ENOMEM);
+	}
+	memset(hi->request_packet, 0, sizeof(struct sbp2_request_packet) * SBP2_MAX_REQUEST_PACKETS);
+
+	/* 
+	 * Create a pool of request packets. Just take the max supported 
+	 * concurrent commands and multiply by two to be safe... 
+	 */
 	for (i=0; i<SBP2_MAX_REQUEST_PACKETS; i++) {
 
 		/*
@@ -546,6 +717,7 @@
 		}
 
 	}
+	kfree(hi->request_packet);
 	sbp2_spin_unlock(&hi->sbp2_request_packet_lock, flags);
 
 	return;
@@ -560,7 +732,7 @@
  */
 static struct sbp2_request_packet *
 sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
-				       nodeid_t node, u64 addr,
+				       struct node_entry *ne, u64 addr,
 				       size_t data_size,
 				       quadlet_t data) {
 	struct list_head *lh;
@@ -589,12 +761,11 @@
 		INIT_LIST_HEAD(&packet->list);
 		sema_init(&packet->state_change, 0);
 		packet->state = hpsb_unused;
-		packet->generation = get_hpsb_generation(hi->host);
 		packet->data_be = 1;
+		
+		hpsb_node_fill_packet(ne, packet);
 
-		packet->host = hi->host;
-		packet->tlabel = get_tlabel(hi->host, node, 1);
-		packet->node_id = node;
+		packet->tlabel = get_tlabel(hi->host, packet->node_id, 0);
 
 		if (!data_size) {
 			fill_async_writequad(packet, addr, data);
@@ -716,8 +887,8 @@
 }
 
 /* 
- * This functions finds the sbp2_command for a given outstanding command
- * orb. Only looks at the inuse list.
+ * This function finds the sbp2_command for a given outstanding command
+ * orb.Only looks at the inuse list.
  */
 static struct sbp2_command_info *sbp2util_find_command_for_orb(
 		struct scsi_id_instance_data *scsi_id, dma_addr_t orb)
@@ -744,7 +915,7 @@
 }
 
 /* 
- * This functions finds the sbp2_command for a given outstanding SCpnt.
+ * This function finds the sbp2_command for a given outstanding SCpnt.
  * Only looks at the inuse list.
  */
 static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt)
@@ -787,7 +958,6 @@
 		command = list_entry(lh, struct sbp2_command_info, list);
 		command->Current_done = Current_done;
 		command->Current_SCpnt = Current_SCpnt;
-		command->linked = 0;
 		list_add_tail(&command->list, &scsi_id->sbp2_command_orb_inuse);
 	} else {
 		SBP2_ERR("sbp2util_allocate_command_orb - No orbs available!");
@@ -804,14 +974,26 @@
 	hi = (struct sbp2scsi_host_info *) command->Current_SCpnt->host->hostdata[0];
 
 	if (hi == NULL) {
-		printk(KERN_ERR __FUNCTION__": hi == NULL\n");
+		printk(KERN_ERR "%s: hi == NULL\n", __FUNCTION__);
 		return;
 	}
 
 	if (command->cmd_dma) {
-		pci_unmap_single(hi->host->pdev, command->cmd_dma,
-				 command->dma_size, command->dma_dir);
-		SBP2_DMA_FREE("single bulk");
+		if (command->dma_type == CMD_DMA_SINGLE) {
+			pci_unmap_single(hi->host->pdev, command->cmd_dma,
+					 command->dma_size, command->dma_dir);
+			SBP2_DMA_FREE("single bulk");
+		} else if (command->dma_type == CMD_DMA_PAGE) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13)
+			pci_unmap_single(hi->host->pdev, command->cmd_dma,
+					 command->dma_size, command->dma_dir);
+#else
+			pci_unmap_page(hi->host->pdev, command->cmd_dma,
+				       command->dma_size, command->dma_dir);
+#endif /* Linux version < 2.4.13 */
+			SBP2_DMA_FREE("single page");
+		} /* XXX: Check for CMD_DMA_NONE bug */
+		command->dma_type = CMD_DMA_NONE;
 		command->cmd_dma = 0;
 	}
 
@@ -865,7 +1047,15 @@
 	 * Register our sbp2 status address space...
 	 */
 	hpsb_register_addrspace(sbp2_hl_handle, &sbp2_ops, SBP2_STATUS_FIFO_ADDRESS,
-				SBP2_STATUS_FIFO_ADDRESS + sizeof(struct sbp2_status_block));
+				SBP2_STATUS_FIFO_ADDRESS + 
+				SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(SBP2SCSI_MAX_SCSI_IDS+1));
+
+	/*
+	 * Handle data movement if physical dma is not enabled/supported on host controller
+	 */
+#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
+	hpsb_register_addrspace(sbp2_hl_handle, &sbp2_physdma_ops, 0x0ULL, 0xfffffffcULL);
+#endif
 
 	hpsb_register_protocol(&sbp2_driver);
 
@@ -923,7 +1113,8 @@
 
 	if (sbp2_reconnect_device(hi, scsi_id)) {
 		
-		/* Ok, reconnect has failed.  Perhaps we didn't
+		/* 
+		 * Ok, reconnect has failed. Perhaps we didn't
 		 * reconnect fast enough. Try doing a regular login.
 		 */
 		if (sbp2_login_device(hi, scsi_id)) {
@@ -991,13 +1182,14 @@
 
 	sbp2_spin_lock(&sbp2_host_info_lock, flags);
 	list_add_tail(&hi->list, &sbp2_host_info_list);
-	sbp2_host_count++;
 	sbp2_spin_unlock(&sbp2_host_info_lock, flags);
 
 	/* Register our host with the SCSI stack. */
 	hi->scsi_host = scsi_register (&scsi_driver_template, sizeof(void *));
-	if (hi->scsi_host)
+	if (hi->scsi_host) {
 		hi->scsi_host->hostdata[0] = (unsigned long)hi;
+		hi->scsi_host->max_id = SBP2SCSI_MAX_SCSI_IDS;
+	}
 	scsi_driver_template.present++;
 
 	return;
@@ -1014,12 +1206,29 @@
 
 	list_for_each (lh, &sbp2_host_info_list) {
 		hi = list_entry(lh, struct sbp2scsi_host_info, list);
-		if (hi->host == host) {
+		if (hi->host == host)
 			return hi;
-		}
 	}
 
-	return(NULL);
+	return NULL;
+}
+
+/*
+ * This function returns a host info structure for a given Scsi_Host
+ * struct.
+ */
+static struct sbp2scsi_host_info *sbp2_find_host_info_scsi(struct Scsi_Host *host)
+{
+	struct list_head *lh;
+	struct sbp2scsi_host_info *hi;
+
+	list_for_each (lh, &sbp2_host_info_list) {
+		hi = list_entry(lh, struct sbp2scsi_host_info, list);
+		if (hi->scsi_host == host)
+			return hi;
+	}
+
+	return NULL;
 }
 
 /*
@@ -1037,10 +1246,7 @@
 	hi = sbp2_find_host_info(host);
 	if (hi != NULL) {
 		sbp2util_remove_request_packet_pool(hi);
-		sbp2_host_count--;
 		list_del(&hi->list);
-		scsi_unregister(hi->scsi_host);
-		scsi_driver_template.present--;
 		kfree(hi);
 	}
 	else
@@ -1142,7 +1348,7 @@
 	scsi_id->max_payload_size = sbp2_speedto_maxrec[SPEED_100];
 	ud->driver_data = scsi_id;
 
-	init_waitqueue_head(&scsi_id->sbp2_login_wait);
+	atomic_set(&scsi_id->sbp2_login_complete, 0);
 
 	/* 
 	 * Initialize structures needed for the command orb pool.
@@ -1164,19 +1370,11 @@
 	/* 
 	 * Knock the total command orbs down if we are serializing I/O
 	 */
-	if (serialize_io) {
+	if (sbp2_serialize_io) {
 		scsi_id->sbp2_total_command_orbs = 2;	/* one extra for good measure */
 	}
 
 	/*
-	 * Allocate some extra command orb structures for devices with
-	 * 128KB limit.
-	 */
-	if (scsi_id->sbp2_firmware_revision == SBP2_128KB_BROKEN_FIRMWARE) {
-		scsi_id->sbp2_total_command_orbs *= 4;
-	} 
-
-	/*
 	 * Find an empty spot to stick our scsi id instance data. 
 	 */
 	for (i = 0; i < SBP2SCSI_MAX_SCSI_IDS; i++) {
@@ -1288,20 +1486,62 @@
 	kfree(scsi_id);
 }
 
-
+#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
+/*
+ * This function deals with physical dma write requests (for adapters that do not support
+ * physical dma in hardware). Mostly just here for debugging...
+ */
+static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data,
+                                     u64 addr, unsigned int length)
+{
+
+        /*
+         * Manually put the data in the right place.
+         */
+        memcpy(bus_to_virt((u32)addr), data, length);
+	sbp2util_packet_dump(data, length, "sbp2 phys dma write by device", (u32)addr);
+        return(RCODE_COMPLETE);
+}
+
+/*
+ * This function deals with physical dma read requests (for adapters that do not support
+ * physical dma in hardware). Mostly just here for debugging...
+ */
+static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
+                                    u64 addr, unsigned int length)
+{
+
+        /*
+         * Grab data from memory and send a read response.
+         */
+        memcpy(data, bus_to_virt((u32)addr), length);
+	sbp2util_packet_dump(data, length, "sbp2 phys dma read by device", (u32)addr);
+        return(RCODE_COMPLETE);
+}
+#endif
+
 
 /**************************************
  * SBP-2 protocol related section
  **************************************/
 
 /*
+ * This function determines if we should convert scsi commands for a particular sbp2 device type
+ */
+static __inline__ int sbp2_command_conversion_device_type(u8 device_type)
+{
+	return (((device_type == TYPE_DISK) ||
+		 (device_type == TYPE_SDAD) ||
+		 (device_type == TYPE_ROM)) ? 1:0);
+}
+
+/*
  * This function is called in order to login to a particular SBP-2 device,
  * after a bus reset.
  */
 static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id) 
 {
 	quadlet_t data[2];
-	unsigned long flags;
 
 	SBP2_DEBUG("sbp2_login_device");
 
@@ -1321,15 +1561,20 @@
 
 	scsi_id->login_orb->lun_misc = ORB_SET_FUNCTION(LOGIN_REQUEST);
 	scsi_id->login_orb->lun_misc |= ORB_SET_RECONNECT(0);	/* One second reconnect time */
-	scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(1);	/* Exclusive access to device */
-	scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1);		/* Notify us of login complete */
+	scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(sbp2_exclusive_login);	/* Exclusive access to device */
+	scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1);	/* Notify us of login complete */
+	/* Set the lun if we were able to pull it from the device's unit directory */
+	if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
+		scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
+	}
 	SBP2_DEBUG("sbp2_login_device: lun_misc initialized");
 
 	scsi_id->login_orb->passwd_resp_lengths =
 		ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response));
 	SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized");
 
-	scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO;
+	scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + 
+					     SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->id);
 	scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) |
 					      SBP2_STATUS_FIFO_ADDRESS_HI);
 	SBP2_DEBUG("sbp2_login_device: status FIFO initialized");
@@ -1341,6 +1586,9 @@
 
 	SBP2_DEBUG("sbp2_login_device: orb byte-swapped");
 
+	sbp2util_packet_dump(scsi_id->login_orb, sizeof(struct sbp2_login_orb), 
+			     "sbp2 login orb", scsi_id->login_orb_dma);
+
 	/*
 	 * Initialize login response and status fifo
 	 */
@@ -1356,35 +1604,28 @@
 	data[1] = scsi_id->login_orb_dma;
 	sbp2util_cpu_to_be32_buffer(data, 8);
 
+	atomic_set(&scsi_id->sbp2_login_complete, 0);
+
 	SBP2_DEBUG("sbp2_login_device: prepared to write");
-	hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, scsi_id->sbp2_management_agent_addr, data, 8);
+	hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8);
 	SBP2_DEBUG("sbp2_login_device: written");
 
 	/*
-	 * Wait for login status... but, only if the device has not
-	 * already logged-in (some devices are fast)
+	 * Wait for login status (up to 20 seconds)... 
 	 */
-
-	save_flags(flags);
-	cli();
-	/* 10 second timeout */
-	if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma)
-		sleep_on_timeout(&scsi_id->sbp2_login_wait, 10*HZ);
-	restore_flags(flags);
-
-	SBP2_DEBUG("sbp2_login_device: initial check");
+	if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 20*HZ)) {
+		SBP2_ERR("Error logging into SBP-2 device - login timed-out");
+		return(-EIO);
+	}
 
 	/*
-	 * Match status to the login orb. If they do not match, it's
-	 * probably because the login timed-out.
+	 * Sanity. Make sure status returned matches login orb.
 	 */
 	if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) {
 		SBP2_ERR("Error logging into SBP-2 device - login timed-out");
 		return(-EIO);
 	}
 
-	SBP2_DEBUG("sbp2_login_device: second check");
-
 	/*
 	 * Check status
 	 */
@@ -1446,7 +1687,8 @@
 	scsi_id->logout_orb->login_ID_misc |= ORB_SET_NOTIFY(1);
 
 	scsi_id->logout_orb->reserved5 = 0x0;
-	scsi_id->logout_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO;
+	scsi_id->logout_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + 
+					      SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->id);
 	scsi_id->logout_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) |
 					       SBP2_STATUS_FIFO_ADDRESS_HI);
 
@@ -1455,6 +1697,9 @@
 	 */
 	sbp2util_cpu_to_be32_buffer(scsi_id->logout_orb, sizeof(struct sbp2_logout_orb));
 
+	sbp2util_packet_dump(scsi_id->logout_orb, sizeof(struct sbp2_logout_orb), 
+			     "sbp2 logout orb", scsi_id->logout_orb_dma);
+
 	/*
 	 * Ok, let's write to the target's management agent register
 	 */
@@ -1462,10 +1707,12 @@
 	data[1] = scsi_id->logout_orb_dma;
 	sbp2util_cpu_to_be32_buffer(data, 8);
 
-	hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, scsi_id->sbp2_management_agent_addr, data, 8);
+	atomic_set(&scsi_id->sbp2_login_complete, 0);
+
+	hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8);
 
 	/* Wait for device to logout...1 second. */
-	sleep_on_timeout(&scsi_id->sbp2_login_wait, HZ);
+	sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ);
 
 	SBP2_INFO("Logged out of SBP-2 device");
 
@@ -1480,7 +1727,6 @@
 static int sbp2_reconnect_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id) 
 {
 	quadlet_t data[2];
-	unsigned long flags;
 
 	SBP2_DEBUG("sbp2_reconnect_device");
 
@@ -1500,7 +1746,8 @@
 	scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_NOTIFY(1);
 
 	scsi_id->reconnect_orb->reserved5 = 0x0;
-	scsi_id->reconnect_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO;
+	scsi_id->reconnect_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + 
+						 SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->id);
 	scsi_id->reconnect_orb->status_FIFO_hi =
 		(ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI);
 
@@ -1509,6 +1756,9 @@
 	 */
 	sbp2util_cpu_to_be32_buffer(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb));
 
+	sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb), 
+			     "sbp2 reconnect orb", scsi_id->reconnect_orb_dma);
+
 	/*
 	 * Initialize status fifo
 	 */
@@ -1521,22 +1771,20 @@
 	data[1] = scsi_id->reconnect_orb_dma;
 	sbp2util_cpu_to_be32_buffer(data, 8);
 
-	hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, scsi_id->sbp2_management_agent_addr, data, 8);
+	atomic_set(&scsi_id->sbp2_login_complete, 0);
+
+	hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8);
 
 	/*
-	 * Wait for reconnect status... but, only if the device has not
-	 * already reconnected (some devices are fast).
+	 * Wait for reconnect status (up to 1 second)...
 	 */
-	save_flags(flags);
-	cli();
-	/* One second timout */
-	if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma)
-		sleep_on_timeout(&scsi_id->sbp2_login_wait, HZ);
-	restore_flags(flags);
+	if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) {
+		SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
+		return(-EIO);
+	}
 
 	/*
-	 * Match status to the reconnect orb. If they do not match, it's
-	 * probably because the reconnect timed-out.
+	 * Sanity. Make sure status returned matches reconnect orb.
 	 */
 	if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) {
 		SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
@@ -1575,7 +1823,7 @@
 	 */
 	data = cpu_to_be32(SBP2_BUSY_TIMEOUT_VALUE);
 
-	if (hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) {
+	if (hpsb_node_write(scsi_id->ne, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) {
 		SBP2_ERR("sbp2_set_busy_timeout error");
 	}
 
@@ -1594,16 +1842,24 @@
 
 	SBP2_DEBUG("sbp2_parse_unit_directory");
 
+	/* Initialize some fields, in case an entry does not exist */
+	scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED;
+	scsi_id->sbp2_management_agent_addr = 0x0;
+	scsi_id->sbp2_command_set_spec_id = 0x0;
+	scsi_id->sbp2_command_set = 0x0;
+	scsi_id->sbp2_unit_characteristics = 0x0;
+	scsi_id->sbp2_firmware_revision = 0x0;
+
 	ud = scsi_id->ud;
 
 	/* Handle different fields in the unit directory, based on keys */
-	for (i = 0; i < ud->arb_count; i++) {
-		switch (ud->arb_keys[i]) {
+	for (i = 0; i < ud->count; i++) {
+		switch (CONFIG_ROM_KEY(ud->quadlets[i])) {
 		case SBP2_CSR_OFFSET_KEY:
 			/* Save off the management agent address */
 			scsi_id->sbp2_management_agent_addr =
-				CONFIG_ROM_INITIAL_MEMORY_SPACE + 
-				(ud->arb_values[i] << 2);
+				CSR_REGISTER_BASE + 
+				(CONFIG_ROM_VALUE(ud->quadlets[i]) << 2);
 
 			SBP2_DEBUG("sbp2_management_agent_addr = %x",
 				   (unsigned int) scsi_id->sbp2_management_agent_addr);
@@ -1611,14 +1867,16 @@
 
 		case SBP2_COMMAND_SET_SPEC_ID_KEY:
 			/* Command spec organization */
-			scsi_id->sbp2_command_set_spec_id = ud->arb_values[i];
+			scsi_id->sbp2_command_set_spec_id
+				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_command_set_spec_id = %x",
 				   (unsigned int) scsi_id->sbp2_command_set_spec_id);
 			break;
 
 		case SBP2_COMMAND_SET_KEY:
 			/* Command set used by sbp2 device */
-			scsi_id->sbp2_command_set = ud->arb_values[i];
+			scsi_id->sbp2_command_set
+				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_command_set = %x",
 				   (unsigned int) scsi_id->sbp2_command_set);
 			break;
@@ -1628,7 +1886,8 @@
 			 * Unit characterisitcs (orb related stuff
 			 * that I'm not yet paying attention to)
 			 */
-			scsi_id->sbp2_unit_characteristics = ud->arb_values[i];
+			scsi_id->sbp2_unit_characteristics
+				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_unit_characteristics = %x",
 				   (unsigned int) scsi_id->sbp2_unit_characteristics);
 			break;
@@ -1638,7 +1897,8 @@
 			 * Device type and lun (used for
 			 * detemining type of sbp2 device)
 			 */
-			scsi_id->sbp2_device_type_and_lun = ud->arb_values[i];
+			scsi_id->sbp2_device_type_and_lun
+				= CONFIG_ROM_VALUE(ud->quadlets[i]);
 			SBP2_DEBUG("sbp2_device_type_and_lun = %x",
 				   (unsigned int) scsi_id->sbp2_device_type_and_lun);
 			break;
@@ -1651,8 +1911,11 @@
 			 * bridge with 128KB max transfer size
 			 * limitation.
 			 */
-			scsi_id->sbp2_firmware_revision = ud->arb_values[i];
-			if (scsi_id->sbp2_firmware_revision ==
+			scsi_id->sbp2_firmware_revision
+				= CONFIG_ROM_VALUE(ud->quadlets[i]);
+			SBP2_DEBUG("sbp2_firmware_revision = %x",
+				   (unsigned int) scsi_id->sbp2_firmware_revision);
+			if ((scsi_id->sbp2_firmware_revision & 0xffff00) ==
 			    SBP2_128KB_BROKEN_FIRMWARE) {
 				SBP2_WARN("warning: Bridge chipset supports 128KB max transfer size");
 			}
@@ -1682,8 +1945,8 @@
 						  + (scsi_id->ne->nodeid & NODE_MASK)];
 
 	/* Bump down our speed if the user requested it */
-	if (scsi_id->speed_code > max_speed) {
-		scsi_id->speed_code = max_speed;
+	if (scsi_id->speed_code > sbp2_max_speed) {
+		scsi_id->speed_code = sbp2_max_speed;
 		SBP2_ERR("Forcing SBP-2 max speed down to %s",
 			 hpsb_speedto_str[scsi_id->speed_code]);
 	}
@@ -1693,7 +1956,7 @@
 	scsi_id->max_payload_size = min(sbp2_speedto_maxrec[scsi_id->speed_code],
 					(u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1));
 
-	SBP2_ERR("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]",
+	SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]",
 		 NODE_BUS_ARGS(scsi_id->ne->nodeid), hpsb_speedto_str[scsi_id->speed_code],
 		 1 << ((u32)scsi_id->max_payload_size + 2));
 
@@ -1713,7 +1976,7 @@
 	 * Ok, let's write to the target's management agent register
 	 */
 	agent_reset_request_packet =
-		sbp2util_allocate_write_request_packet(hi, LOCAL_BUS | scsi_id->ne->nodeid,
+		sbp2util_allocate_write_request_packet(hi, scsi_id->ne,
 						       scsi_id->sbp2_command_block_agent_addr +
 						       SBP2_AGENT_RESET_OFFSET,
 						       0, ntohl(SBP2_AGENT_RESET_DATA));
@@ -1753,13 +2016,15 @@
 				   unchar *scsi_cmd,
 				   unsigned int scsi_use_sg,
 				   unsigned int scsi_request_bufflen,
-				   void *scsi_request_buffer, int dma_dir)
+				   void *scsi_request_buffer, 
+				   unsigned char scsi_dir)
 {
 	struct scatterlist *sgpnt = (struct scatterlist *) scsi_request_buffer;
 	struct sbp2_command_orb *command_orb = &command->command_orb;
 	struct sbp2_unrestricted_page_table *scatter_gather_element =
 		&command->scatter_gather_element[0];
-	u32 sg_count, sg_len;
+	int dma_dir = scsi_to_pci_dma_dir (scsi_dir);
+	u32 sg_count, sg_len, orb_direction;
 	dma_addr_t sg_addr;
 	int i;
 
@@ -1771,25 +2036,49 @@
 	 * that data_size becomes the number of s/g elements, and
 	 * page_size should be zero (for unrestricted).
 	 */
-	command_orb->next_ORB_hi = 0xffffffff;
-	command_orb->next_ORB_lo = 0xffffffff;
+	command_orb->next_ORB_hi = ORB_SET_NULL_PTR(1);
+	command_orb->next_ORB_lo = 0x0;
 	command_orb->misc = ORB_SET_MAX_PAYLOAD(scsi_id->max_payload_size);
 	command_orb->misc |= ORB_SET_SPEED(scsi_id->speed_code);
 	command_orb->misc |= ORB_SET_NOTIFY(1);		/* Notify us when complete */
 
 	/*
+	 * Get the direction of the transfer. If the direction is unknown, then use our
+	 * goofy table as a back-up.
+	 */
+	switch (scsi_dir) {
+		case SCSI_DATA_NONE:
+			orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER;
+			break;
+		case SCSI_DATA_WRITE:
+			orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA;
+			break;
+		case SCSI_DATA_READ:
+			orb_direction = ORB_DIRECTION_READ_FROM_MEDIA;
+			break;
+		case SCSI_DATA_UNKNOWN:
+		default:
+			SBP2_ERR("SCSI data transfer direction not specified. "
+				 "Update the SBP2 direction table in sbp2.h if " 
+				 "necessary for your application");
+			print_command (scsi_cmd);
+			orb_direction = sbp2scsi_direction_table[*scsi_cmd];
+			break;
+	}
+
+	/*
 	 * Set-up our pagetable stuff... unfortunately, this has become
 	 * messier than I'd like. Need to clean this up a bit.   ;-)
 	 */
-	if (sbp2scsi_direction_table[*scsi_cmd] == ORB_DIRECTION_NO_DATA_TRANSFER) {
+	if (orb_direction == ORB_DIRECTION_NO_DATA_TRANSFER) {
 
 		SBP2_DEBUG("No data transfer");
 
 		/*
 		 * Handle no data transfer
 		 */
-		command_orb->data_descriptor_hi = 0xffffffff;
-		command_orb->data_descriptor_lo = 0xffffffff;
+		command_orb->data_descriptor_hi = 0x0;
+		command_orb->data_descriptor_lo = 0x0;
 		command_orb->misc |= ORB_SET_DIRECTION(1);
 
 	} else if (scsi_use_sg) {
@@ -1804,15 +2093,24 @@
 			SBP2_DEBUG("Only one s/g element");
 			command->dma_dir = dma_dir;
 			command->dma_size = sgpnt[0].length;
+			command->dma_type = CMD_DMA_PAGE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13)
 			command->cmd_dma = pci_map_single (hi->host->pdev, sgpnt[0].address,
 							   command->dma_size,
 							   command->dma_dir);
-			SBP2_DMA_ALLOC("single scatter element");
+#else
+			command->cmd_dma = pci_map_page(hi->host->pdev,
+							sgpnt[0].page,
+							sgpnt[0].offset,
+							command->dma_size,
+							command->dma_dir);
+#endif /* Linux version < 2.4.13 */
+			SBP2_DMA_ALLOC("single page scatter element");
 
 			command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
 			command_orb->data_descriptor_lo = command->cmd_dma;
 			command_orb->misc |= ORB_SET_DATA_SIZE(command->dma_size);
-			command_orb->misc |= ORB_SET_DIRECTION(sbp2scsi_direction_table[*scsi_cmd]);
+			command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
 
 		} else {
 			int count = pci_map_sg(hi->host->pdev, sgpnt, scsi_use_sg, dma_dir);
@@ -1824,7 +2122,7 @@
 
 			/* use page tables (s/g) */
 			command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
-			command_orb->misc |= ORB_SET_DIRECTION(sbp2scsi_direction_table[*scsi_cmd]);
+			command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
 			command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
 			command_orb->data_descriptor_lo = command->sge_dma;
 
@@ -1854,6 +2152,10 @@
 			/* Number of page table (s/g) elements */
 			command_orb->misc |= ORB_SET_DATA_SIZE(sg_count);
 
+			sbp2util_packet_dump(scatter_gather_element, 
+					     (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, 
+					     "sbp2 s/g list", command->sge_dma);
+
 			/*
 			 * Byte swap page tables if necessary
 			 */
@@ -1869,6 +2171,7 @@
 
 		command->dma_dir = dma_dir;
 		command->dma_size = scsi_request_bufflen;
+		command->dma_type = CMD_DMA_SINGLE;
 		command->cmd_dma = pci_map_single (hi->host->pdev, scsi_request_buffer,
 						   command->dma_size,
 						   command->dma_dir);
@@ -1883,15 +2186,15 @@
 			command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
 			command_orb->data_descriptor_lo = command->cmd_dma;
 			command_orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen);
-			command_orb->misc |= ORB_SET_DIRECTION(sbp2scsi_direction_table[*scsi_cmd]);
+			command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
 
 			/*
 			 * Sanity, in case our direction table is not
 			 * up-to-date
 			 */
 			if (!scsi_request_bufflen) {
-				command_orb->data_descriptor_hi = 0xffffffff;
-				command_orb->data_descriptor_lo = 0xffffffff;
+				command_orb->data_descriptor_hi = 0x0;
+				command_orb->data_descriptor_lo = 0x0;
 				command_orb->misc |= ORB_SET_DIRECTION(1);
 			}
 
@@ -1905,7 +2208,7 @@
 
 			/* Use page tables (s/g) */
 			command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
-			command_orb->misc |= ORB_SET_DIRECTION(sbp2scsi_direction_table[*scsi_cmd]);
+			command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
 
 			/*
 			 * fill out our sbp-2 page tables (and split up
@@ -1932,6 +2235,10 @@
 			/* Number of page table (s/g) elements */
 			command_orb->misc |= ORB_SET_DATA_SIZE(sg_count);
 
+			sbp2util_packet_dump(scatter_gather_element, 
+					     (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, 
+					     "sbp2 s/g list", command->sge_dma);
+
 			/*
 			 * Byte swap page tables if necessary
 			 */
@@ -1967,9 +2274,15 @@
 	struct sbp2_command_orb *command_orb = &command->command_orb;
 
 	outstanding_orb_incr;
-	SBP2_ORB_DEBUG("sending command orb %p, linked = %x, total orbs = %x",
-			command_orb, command->linked, global_outstanding_command_orbs);
+	SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x",
+			command_orb, global_outstanding_command_orbs);
 
+	pci_dma_sync_single(hi->host->pdev, command->command_orb_dma,
+			    sizeof(struct sbp2_command_orb),
+			    PCI_DMA_BIDIRECTIONAL);
+	pci_dma_sync_single(hi->host->pdev, command->sge_dma,
+			    sizeof(command->scatter_gather_element),
+			    PCI_DMA_BIDIRECTIONAL);
 	/*
 	 * Check to see if there are any previous orbs to use
 	 */
@@ -1981,7 +2294,7 @@
 		if (hpsb_node_entry_valid(scsi_id->ne)) {
 
 			command_request_packet =
-				sbp2util_allocate_write_request_packet(hi, LOCAL_BUS | scsi_id->ne->nodeid,
+				sbp2util_allocate_write_request_packet(hi, scsi_id->ne,
 								scsi_id->sbp2_command_block_agent_addr +
 								SBP2_ORB_POINTER_OFFSET, 8, 0);
 		
@@ -2006,6 +2319,7 @@
 		}
 
 		scsi_id->last_orb = command_orb;
+		scsi_id->last_orb_dma = command->command_orb_dma;
 
 	} else {
 
@@ -2020,15 +2334,17 @@
 			cpu_to_be32(command->command_orb_dma);
 		/* Tells hardware that this pointer is valid */
 		scsi_id->last_orb->next_ORB_hi = 0x0;
+		pci_dma_sync_single(hi->host->pdev, scsi_id->last_orb_dma,
+				    sizeof(struct sbp2_command_orb),
+				    PCI_DMA_BIDIRECTIONAL);
 
 		/*
-		 * Only ring the doorbell if we need to (first parts of
-		 * linked orbs don't need this).
+		 * Ring the doorbell
 		 */
-		if (!command->linked && hpsb_node_entry_valid(scsi_id->ne)) {
+		if (hpsb_node_entry_valid(scsi_id->ne)) {
 
 			command_request_packet = sbp2util_allocate_write_request_packet(hi,
-				LOCAL_BUS | scsi_id->ne->nodeid,
+				scsi_id->ne,
 				scsi_id->sbp2_command_block_agent_addr + SBP2_DOORBELL_OFFSET,
 				0, cpu_to_be32(command->command_orb_dma));
 	
@@ -2047,6 +2363,7 @@
 		}
 
 		scsi_id->last_orb = command_orb;
+		scsi_id->last_orb_dma = command->command_orb_dma;
 
 	}
        	return(0);
@@ -2059,33 +2376,18 @@
 			     Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
 	unchar *cmd = (unchar *) SCpnt->cmnd;
-	u32 device_type = (scsi_id->sbp2_device_type_and_lun & 0x00ff0000) >> 16;
+	unsigned int request_bufflen = SCpnt->request_bufflen;
 	struct sbp2_command_info *command;
 
 	SBP2_DEBUG("sbp2_send_command");
-	SBP2_DEBUG("SCSI command = %02x", *cmd);
-	SBP2_DEBUG("SCSI transfer size = %x", SCpnt->request_bufflen);
+#if (CONFIG_IEEE1394_SBP2_DEBUG >= 2) || defined(CONFIG_IEEE1394_SBP2_PACKET_DUMP)
+	printk("[scsi command]\n   ");
+	print_command (cmd);
+#endif
+	SBP2_DEBUG("SCSI transfer size = %x", request_bufflen);
 	SBP2_DEBUG("SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg);
 
 	/*
-	 * Check for broken devices that can't handle greater than 128K
-	 * transfers, and deal with them in a hacked ugly way.
-	 */
-	if ((scsi_id->sbp2_firmware_revision == SBP2_128KB_BROKEN_FIRMWARE) && 
-	    (SCpnt->request_bufflen > SBP2_BROKEN_FIRMWARE_MAX_TRANSFER) && 
-	    (device_type == TYPE_DISK) &&
-	    (SCpnt->use_sg) &&
-	    (*cmd == 0x28 || *cmd == 0x2a || *cmd == 0x0a || *cmd == 0x08)) {
-
-		/*
-		 * Darn, a broken device. We'll need to split up the
-		 * transfer ourselves.
-		 */
-		sbp2_send_split_command(hi, scsi_id, SCpnt, done);
-		return(0);
-	}
-
-	/*
 	 * Allocate a command orb and s/g structure
 	 */
 	command = sbp2util_allocate_command_orb(scsi_id, SCpnt, done, hi);
@@ -2094,20 +2396,32 @@
 	}
 
 	/*
+	 * The scsi stack sends down a request_bufflen which does not match the
+	 * length field in the scsi cdb. This causes some sbp2 devices to 
+	 * reject this inquiry command. Fix the request_bufflen. 
+	 */
+	if (*cmd == INQUIRY) {
+#ifdef SBP2_FORCE_36_BYTE_INQUIRY
+		request_bufflen = cmd[4] = 0x24;
+#else
+		request_bufflen = cmd[4];
+#endif
+	}
+
+	/*
 	 * Now actually fill in the comamnd orb and sbp2 s/g list
 	 */
 	sbp2_create_command_orb(hi, scsi_id, command, cmd, SCpnt->use_sg,
-			SCpnt->request_bufflen, SCpnt->request_buffer,
-			scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); 
+				request_bufflen, SCpnt->request_buffer,
+				SCpnt->sc_data_direction); 
 	/*
 	 * Update our cdb if necessary (to handle sbp2 RBC command set
-	 * differences).  This is where the command set hacks go!   =)
+	 * differences). This is where the command set hacks go!   =)
 	 */
-	if ((device_type == TYPE_DISK) ||
-	    (device_type == TYPE_SDAD) ||
-	    (device_type == TYPE_ROM)) {
-		sbp2_check_sbp2_command(command->command_orb.cdb);
-	}
+	sbp2_check_sbp2_command(scsi_id, command->command_orb.cdb);
+
+	sbp2util_packet_dump(&command->command_orb, sizeof(struct sbp2_command_orb), 
+			     "sbp2 command orb", command->command_orb_dma);
 
 	/*
 	 * Initialize status fifo
@@ -2122,128 +2436,15 @@
 	return(0);
 }
 
-/*
- * This function is called for broken sbp2 device, where we have to break
- * up large transfers.
- */
-static int sbp2_send_split_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id,
-				   Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
-{
-	unchar *cmd = (unchar *) SCpnt->cmnd;
-	struct scatterlist *sgpnt = (struct scatterlist *) SCpnt->request_buffer;
-	struct sbp2_command_info *command;
-	unsigned int i, block_count, block_address, block_size;
-	unsigned int current_sg = 0;
-	unsigned int total_transfer = 0;
-	unsigned int total_sg = 0;
-	unchar new_cmd[12];
-
-	memset(new_cmd, 0, 12);
-	memcpy(new_cmd, cmd, COMMAND_SIZE(*cmd));
-
-	/*
-	 * Turns command into 10 byte version
-	 */
-	sbp2_check_sbp2_command(new_cmd);
-        
-	/*
-	 * Pull block size, block address, block count from command sent down
-	 */
-	block_count = (cmd[7] << 8) | cmd[8];
-	block_address = (cmd[2] << 24) | (cmd[3] << 16) | (cmd[4] << 8) | cmd[5]; 
-	block_size = SCpnt->request_bufflen/block_count;
-
-	/*
-	 * Walk the scsi s/g list to determine how much we can transfer in one pop
-	 */
-	for (i=0; i<SCpnt->use_sg; i++) {
-
-		total_transfer+=sgpnt[i].length;
-		total_sg++;
-
-		if (total_transfer > SBP2_BROKEN_FIRMWARE_MAX_TRANSFER) {
-
-			/*
-			 * Back everything up one, so that we're less than 128KB
-			 */
-			total_transfer-=sgpnt[i].length;
-			total_sg--;
-			i--;
-
-			command = sbp2util_allocate_command_orb(scsi_id, SCpnt, done, hi);
-			if (!command) {
-				return(-EIO);
-			}
-
-			/*
-			 * This is not the final piece, so mark it as linked
-			 */
-			command->linked = 1;
-
-			block_count = total_transfer/block_size;
-			new_cmd[2] = (unchar) (block_address >> 24) & 0xff;
-			new_cmd[3] = (unchar) (block_address >> 16) & 0xff;
-			new_cmd[4] = (unchar) (block_address >> 8) & 0xff;
-			new_cmd[5] = (unchar) block_address & 0xff;
-			new_cmd[7] = (unchar) (block_count >> 8) & 0xff;
-			new_cmd[8] = (unchar) block_count & 0xff;
-			block_address+=block_count;
-
-			sbp2_create_command_orb(hi, scsi_id, command, new_cmd, total_sg, 
-						total_transfer, &sgpnt[current_sg],
-						scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
-
-			/*
-			 * Link up the orb, and ring the doorbell if needed
-			 */
-			memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
-			sbp2_link_orb_command(hi, scsi_id, command);
-
-			current_sg += total_sg;
-			total_sg = 0;
-			total_transfer = 0;
-
-		}
-
-	}
-
-	/*
-	 * Get the last piece...
-	 */
-	command = sbp2util_allocate_command_orb(scsi_id, SCpnt, done, hi);
-	if (!command) {
-		return(-EIO);
-	}
-
-	block_count = total_transfer/block_size;
-	new_cmd[2] = (unchar) (block_address >> 24) & 0xff;
-	new_cmd[3] = (unchar) (block_address >> 16) & 0xff;
-	new_cmd[4] = (unchar) (block_address >> 8) & 0xff;
-	new_cmd[5] = (unchar) block_address & 0xff;
-	new_cmd[7] = (unchar) (block_count >> 8) & 0xff;
-	new_cmd[8] = (unchar) block_count & 0xff;
-
-	sbp2_create_command_orb(hi, scsi_id, command, new_cmd, total_sg, 
-				total_transfer, &sgpnt[current_sg],
-				scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
-
-	/*
-	 * Link up the orb, and ring the doorbell if needed
-	 */
-	memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
-	sbp2_link_orb_command(hi, scsi_id, command);
-
-
-	return(0);
-}
 
 /*
  * This function deals with command set differences between Linux scsi
  * command set and sbp2 RBC command set.
  */
-static void sbp2_check_sbp2_command(unchar *cmd)
+static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
 {
 	unchar new_cmd[16];
+	u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
 
 	SBP2_DEBUG("sbp2_check_sbp2_command");
 
@@ -2251,67 +2452,79 @@
 		
 		case READ_6:
 
-			SBP2_DEBUG("Convert READ_6 to READ_10");
+			if (sbp2_command_conversion_device_type(device_type)) {
 
-			/*
-			 * Need to turn read_6 into read_10
-			 */
-			new_cmd[0] = 0x28;
-			new_cmd[1] = (cmd[1] & 0xe0);
-			new_cmd[2] = 0x0;
-			new_cmd[3] = (cmd[1] & 0x1f);
-			new_cmd[4] = cmd[2];
-			new_cmd[5] = cmd[3];
-			new_cmd[6] = 0x0;
-			new_cmd[7] = 0x0;
-			new_cmd[8] = cmd[4];
-			new_cmd[9] = cmd[5];
+				SBP2_DEBUG("Convert READ_6 to READ_10");
+					    
+				/*
+				 * Need to turn read_6 into read_10
+				 */
+				new_cmd[0] = 0x28;
+				new_cmd[1] = (cmd[1] & 0xe0);
+				new_cmd[2] = 0x0;
+				new_cmd[3] = (cmd[1] & 0x1f);
+				new_cmd[4] = cmd[2];
+				new_cmd[5] = cmd[3];
+				new_cmd[6] = 0x0;
+				new_cmd[7] = 0x0;
+				new_cmd[8] = cmd[4];
+				new_cmd[9] = cmd[5];
+	
+				memcpy(cmd, new_cmd, 10);
 
-			memcpy(cmd, new_cmd, 10);
+			}
 
 			break;
 
 		case WRITE_6:
 
-			SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
+			if (sbp2_command_conversion_device_type(device_type)) {
 
-			/*
-			 * Need to turn write_6 into write_10
-			 */
-			new_cmd[0] = 0x2a;
-			new_cmd[1] = (cmd[1] & 0xe0);
-			new_cmd[2] = 0x0;
-			new_cmd[3] = (cmd[1] & 0x1f);
-			new_cmd[4] = cmd[2];
-			new_cmd[5] = cmd[3];
-			new_cmd[6] = 0x0;
-			new_cmd[7] = 0x0;
-			new_cmd[8] = cmd[4];
-			new_cmd[9] = cmd[5];
+				SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
+	
+				/*
+				 * Need to turn write_6 into write_10
+				 */
+				new_cmd[0] = 0x2a;
+				new_cmd[1] = (cmd[1] & 0xe0);
+				new_cmd[2] = 0x0;
+				new_cmd[3] = (cmd[1] & 0x1f);
+				new_cmd[4] = cmd[2];
+				new_cmd[5] = cmd[3];
+				new_cmd[6] = 0x0;
+				new_cmd[7] = 0x0;
+				new_cmd[8] = cmd[4];
+				new_cmd[9] = cmd[5];
+	
+				memcpy(cmd, new_cmd, 10);
 
-			memcpy(cmd, new_cmd, 10);
+			}
 
 			break;
 
 		case MODE_SENSE:
 
-			SBP2_DEBUG("Convert MODE_SENSE_6 to MOSE_SENSE_10");
+			if (sbp2_command_conversion_device_type(device_type)) {
 
-			/*
-			 * Need to turn mode_sense_6 into mode_sense_10
-			 */
-			new_cmd[0] = 0x5a;
-			new_cmd[1] = cmd[1];
-			new_cmd[2] = cmd[2];
-			new_cmd[3] = 0x0;
-			new_cmd[4] = 0x0;
-			new_cmd[5] = 0x0;
-			new_cmd[6] = 0x0;
-			new_cmd[7] = 0x0;
-			new_cmd[8] = cmd[4];
-			new_cmd[9] = cmd[5];
+				SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
+
+				/*
+				 * Need to turn mode_sense_6 into mode_sense_10
+				 */
+				new_cmd[0] = 0x5a;
+				new_cmd[1] = cmd[1];
+				new_cmd[2] = cmd[2];
+				new_cmd[3] = 0x0;
+				new_cmd[4] = 0x0;
+				new_cmd[5] = 0x0;
+				new_cmd[6] = 0x0;
+				new_cmd[7] = 0x0;
+				new_cmd[8] = cmd[4];
+				new_cmd[9] = cmd[5];
+	
+				memcpy(cmd, new_cmd, 10);
 
-			memcpy(cmd, new_cmd, 10);
+			}
 
 			break;
 
@@ -2362,20 +2575,33 @@
  * This function is called after a command is completed, in order to do any necessary SBP-2
  * response data translations for the SCSI stack
  */
-static void sbp2_check_sbp2_response(struct sbp2scsi_host_info *hi,
-				     struct scsi_id_instance_data *scsi_id, 
+static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, 
 				     Scsi_Cmnd *SCpnt)
 {
 	u8 *scsi_buf = SCpnt->request_buffer;
-	u32 device_type = (scsi_id->sbp2_device_type_and_lun & 0x00ff0000) >> 16;
-        
+	u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
+
 	SBP2_DEBUG("sbp2_check_sbp2_response");
 
 	switch (SCpnt->cmnd[0]) {
 		
 		case INQUIRY:
 
-			SBP2_DEBUG("Check Inquiry data");
+			/*
+			 * If scsi_id->sbp2_device_type_and_lun is uninitialized, then fill 
+			 * this information in from the inquiry response data. Lun is set to zero.
+			 */
+			if (scsi_id->sbp2_device_type_and_lun == SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
+				SBP2_DEBUG("Creating sbp2_device_type_and_lun from scsi inquiry data");
+				scsi_id->sbp2_device_type_and_lun = (scsi_buf[0] & 0x1f) << 16;
+			}
+
+			/*
+			 * Make sure data length is ok. Minimum length is 36 bytes
+			 */
+			if (scsi_buf[4] == 0) {
+				scsi_buf[4] = 36 - 5;
+			}
 
 			/*
 			 * Check for Simple Direct Access Device and change it to TYPE_DISK
@@ -2395,18 +2621,16 @@
 
 		case MODE_SENSE:
 
-			if ((device_type == TYPE_DISK) ||
-			    (device_type == TYPE_SDAD) ||
-			    (device_type == TYPE_ROM)) {
-
+			if (sbp2_command_conversion_device_type(device_type)) {
+			
 				SBP2_DEBUG("Modify mode sense response (10 byte version)");
-	
+
 				scsi_buf[0] = scsi_buf[1];	/* Mode data length */
 				scsi_buf[1] = scsi_buf[2];	/* Medium type */
 				scsi_buf[2] = scsi_buf[3];	/* Device specific parameter */
 				scsi_buf[3] = scsi_buf[7];	/* Block descriptor length */
 				memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]);
-
+	
 			}
 
 			break;
@@ -2431,7 +2655,7 @@
 {
 	struct sbp2scsi_host_info *hi = NULL;
 	struct scsi_id_instance_data *scsi_id = NULL;
-	int i;
+	u32 id;
 	unsigned long flags;
 	Scsi_Cmnd *SCpnt = NULL;
 	u32 scsi_status = SBP2_SCSI_STATUS_GOOD;
@@ -2439,6 +2663,8 @@
 
 	SBP2_DEBUG("sbp2_handle_status_write");
 
+	sbp2util_packet_dump(data, length, "sbp2 status write by device", (u32)addr);
+
 	if (!host) {
 		SBP2_ERR("host is NULL - this is bad!");
 		return(RCODE_ADDRESS_ERROR);
@@ -2456,17 +2682,11 @@
 	sbp2_spin_lock(&hi->sbp2_command_lock, flags);
 
 	/*
-	 * Find our scsi_id structure
+	 * Find our scsi_id structure by looking at the status fifo address written to by
+	 * the sbp2 device.
 	 */
-	for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
-		if (hi->scsi_id[i]) {
-			if ((hi->scsi_id[i]->ne->nodeid & NODE_MASK) == (nodeid & NODE_MASK)) {
-				scsi_id = hi->scsi_id[i];
-				SBP2_DEBUG("SBP-2 status write from node %x", scsi_id->ne->nodeid);
-				break;
-			}
-		}
-	}
+	id = SBP2_STATUS_FIFO_OFFSET_TO_ENTRY((u32)(addr - SBP2_STATUS_FIFO_ADDRESS)); 
+	scsi_id = hi->scsi_id[id];
 
 	if (!scsi_id) {
 		SBP2_ERR("scsi_id is NULL - device is gone?");
@@ -2491,6 +2711,12 @@
 	if (command) {
 
 		SBP2_DEBUG("Found status for command ORB");
+		pci_dma_sync_single(hi->host->pdev, command->command_orb_dma,
+				    sizeof(struct sbp2_command_orb),
+				    PCI_DMA_BIDIRECTIONAL);
+		pci_dma_sync_single(hi->host->pdev, command->sge_dma,
+				    sizeof(command->scatter_gather_element),
+				    PCI_DMA_BIDIRECTIONAL);
 
 		SBP2_ORB_DEBUG("matched command orb %p", &command->command_orb);
 		outstanding_orb_decr;
@@ -2501,25 +2727,30 @@
 		SCpnt = command->Current_SCpnt;
 		sbp2util_mark_command_completed(scsi_id, command);
 
-		if (SCpnt && !command->linked) {
+		if (SCpnt) {
 
 			/*
-			 * Handle check conditions
+			 * See if the target stored any scsi status information
 			 */
-			if (STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
-
-				SBP2_DEBUG("CHECK CONDITION");
-
+			if (STATUS_GET_LENGTH(scsi_id->status_block.ORB_offset_hi_misc) > 1) {
 				/*
 				 * Translate SBP-2 status to SCSI sense data
 				 */
+				SBP2_DEBUG("CHECK CONDITION");
 				scsi_status = sbp2_status_to_sense_data((unchar *)&scsi_id->status_block, SCpnt->sense_buffer);
+			}
+
+			/*
+			 * Check to see if the dead bit is set. If so, we'll have to initiate
+			 * a fetch agent reset.
+			 */
+			if (STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc)) {
 
 				/*
 				 * Initiate a fetch agent reset. 
 				 */
-				sbp2_agent_reset(hi, scsi_id, SBP2_SEND_NO_WAIT);
-
+				SBP2_DEBUG("Dead bit set - initiating fetch agent reset");
+                                sbp2_agent_reset(hi, scsi_id, SBP2_SEND_NO_WAIT);
 			}
 
 			SBP2_ORB_DEBUG("completing command orb %p", &command->command_orb);
@@ -2541,14 +2772,22 @@
 			scsi_id->last_orb = NULL;
 		}
 
+	} else {
+		
+		/* 
+		 * It's probably a login/logout/reconnect status.
+		 */
+		if ((scsi_id->login_orb_dma == scsi_id->status_block.ORB_offset_lo) ||
+		    (scsi_id->reconnect_orb_dma == scsi_id->status_block.ORB_offset_lo) ||
+		    (scsi_id->logout_orb_dma == scsi_id->status_block.ORB_offset_lo)) {
+			atomic_set(&scsi_id->sbp2_login_complete, 1);
+		}
 	}
 
 	sbp2_spin_unlock(&hi->sbp2_command_lock, flags);
-	wake_up(&scsi_id->sbp2_login_wait);
 	return(RCODE_COMPLETE);
 }
 
-
 
 /**************************************
  * SCSI interface related section
@@ -2613,8 +2852,7 @@
 	}
 
 	/*
-	 * Check to see if there is a command in progress and just return
-	 * busy (to be queued later)
+	 * Check to see if we are in the middle of a bus reset.
 	 */
 	if (!hpsb_node_entry_valid(scsi_id->ne)) {
 		SBP2_ERR("Bus reset in progress - rejecting command");
@@ -2653,8 +2891,14 @@
 		SBP2_DEBUG("Found pending command to complete");
 		lh = scsi_id->sbp2_command_orb_inuse.next;
 		command = list_entry(lh, struct sbp2_command_info, list);
+		pci_dma_sync_single(hi->host->pdev, command->command_orb_dma,
+				    sizeof(struct sbp2_command_orb),
+				    PCI_DMA_BIDIRECTIONAL);
+		pci_dma_sync_single(hi->host->pdev, command->sge_dma,
+				    sizeof(command->scatter_gather_element),
+				    PCI_DMA_BIDIRECTIONAL);
 		sbp2util_mark_command_completed(scsi_id, command);
-		if (command->Current_SCpnt && !command->linked) {
+		if (command->Current_SCpnt) {
 			void (*done)(Scsi_Cmnd *) = command->Current_done;
 			command->Current_SCpnt->result = status << 16;
 			done (command->Current_SCpnt);
@@ -2710,13 +2954,17 @@
 			/*
 			 * Debug stuff
 			 */
+#if CONFIG_IEEE1394_SBP2_DEBUG >= 1
+			print_command (SCpnt->cmnd);
 			print_sense("bh", SCpnt);
+#endif
 
 			break;
 
 		case SBP2_SCSI_STATUS_SELECTION_TIMEOUT:
 			SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
 			SCpnt->result = DID_NO_CONNECT << 16;
+			print_command (SCpnt->cmnd);
 			break;
 
 		case SBP2_SCSI_STATUS_CONDITION_MET:
@@ -2724,6 +2972,7 @@
 		case SBP2_SCSI_STATUS_COMMAND_TERMINATED:
 			SBP2_ERR("Bad SCSI status = %x", scsi_status);
 			SCpnt->result = DID_ERROR << 16;
+			print_command (SCpnt->cmnd);
 			break;
 
 		default:
@@ -2735,20 +2984,7 @@
 	 * Take care of any sbp2 response data mucking here (RBC stuff, etc.)
 	 */
 	if (SCpnt->result == DID_OK) {
-		sbp2_check_sbp2_response(hi, scsi_id, SCpnt);
-	}
-
-	/*
-	 * One more quick hack (not enabled by default). Some sbp2 devices
-	 * do not support mode sense. Turn-on this hack to allow the
-	 * device to pass the sd driver's write-protect test (so that you
-	 * can mount the device rw).
-	 */
-	if (mode_sense_hack && SCpnt->result != DID_OK && SCpnt->cmnd[0] == MODE_SENSE) {
-		SBP2_INFO("Returning success to mode sense command");
-		SCpnt->result = DID_OK;
-		SCpnt->sense_buffer[0] = 0;
-		memset (SCpnt->request_buffer, 0, 8);
+		sbp2_check_sbp2_response(scsi_id, SCpnt);
 	}
 
 	/*
@@ -2765,17 +3001,26 @@
 	 * retried... it could have happened because of a 1394 bus reset
 	 * or hot-plug...
 	 */
-	if ((scsi_status == SBP2_SCSI_STATUS_CHECK_CONDITION) && (SCpnt->sense_buffer[2] == UNIT_ATTENTION)) {
-		SBP2_INFO("UNIT ATTENTION - return busy");
+#if 0
+	if ((scsi_status == SBP2_SCSI_STATUS_CHECK_CONDITION) && 
+	    (SCpnt->sense_buffer[2] == UNIT_ATTENTION)) {
+		SBP2_DEBUG("UNIT ATTENTION - return busy");
 		SCpnt->result = DID_BUS_BUSY << 16;
 	}
+#endif
 
 	/*
 	 * Tell scsi stack that we're done with this command
 	 */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	spin_lock_irq(&io_request_lock);
 	done (SCpnt);
 	spin_unlock_irq(&io_request_lock);
+#else
+	spin_lock_irq(hi->scsi_host->host_lock);
+	done (SCpnt);
+	spin_unlock_irq(hi->scsi_host->host_lock);
+#endif
 
 	return;
 }
@@ -2792,27 +3037,33 @@
 	unsigned long flags;
 
 	SBP2_ERR("aborting sbp2 command");
-
+	print_command (SCpnt->cmnd);
+        
 	if (scsi_id) {
 
 		/*
 		 * Right now, just return any matching command structures
-		 * to the free pool (there may be more than one because of
-		 * broken up/linked commands).
+		 * to the free pool.
 		 */
 		sbp2_spin_lock(&hi->sbp2_command_lock, flags);
-		do {
-			command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt);
-			if (command) {
-				SBP2_DEBUG("Found command to abort");
-				sbp2util_mark_command_completed(scsi_id, command);
-				if (command->Current_SCpnt && !command->linked) {
-					void (*done)(Scsi_Cmnd *) = command->Current_done;
-					command->Current_SCpnt->result = DID_ABORT << 16;
-					done (command->Current_SCpnt);
-				}
+		command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt);
+		if (command) {
+			SBP2_DEBUG("Found command to abort");
+			pci_dma_sync_single(hi->host->pdev,
+					    command->command_orb_dma,
+					    sizeof(struct sbp2_command_orb),
+					    PCI_DMA_BIDIRECTIONAL);
+			pci_dma_sync_single(hi->host->pdev,
+					    command->sge_dma,
+					    sizeof(command->scatter_gather_element),
+					    PCI_DMA_BIDIRECTIONAL);
+			sbp2util_mark_command_completed(scsi_id, command);
+			if (command->Current_SCpnt) {
+				void (*done)(Scsi_Cmnd *) = command->Current_done;
+				command->Current_SCpnt->result = DID_ABORT << 16;
+				done (command->Current_SCpnt);
 			}
-		} while (command);
+		}
 
 		/*
 		 * Initiate a fetch agent reset. 
@@ -2822,24 +3073,25 @@
 		sbp2_spin_unlock(&hi->sbp2_command_lock, flags);
 	}
 
-	return(SCSI_ABORT_SUCCESS);
+	return(SUCCESS);
 }
 
 /*
  * Called by scsi stack when something has really gone wrong.
  */
-static int sbp2scsi_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags) 
+static int sbp2scsi_reset (Scsi_Cmnd *SCpnt) 
 {
 	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0];
+	struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->target];
 
 	SBP2_ERR("reset requested");
 
-	if (hi) {
-		SBP2_ERR("Generating IEEE-1394 bus reset");
-		hpsb_reset_bus(hi->host, LONG_RESET);
+	if (scsi_id) {
+		SBP2_ERR("Generating sbp2 fetch agent reset");
+		sbp2_agent_reset(hi, scsi_id, SBP2_SEND_NO_WAIT);
 	}
 
-	return(SCSI_RESET_SUCCESS);
+	return(SUCCESS);
 }
 
 /*
@@ -2868,12 +3120,15 @@
 	return(0);
 }
 
+/*
+ * Called by scsi stack after scsi driver is registered
+ */
 static int sbp2scsi_detect (Scsi_Host_Template *tpnt) 
 {
 	SBP2_DEBUG("sbp2scsi_detect");
 
 	/*
-	 * Call sbp2_init to register with the ieee1394 stack.  This
+	 * Call sbp2_init to register with the ieee1394 stack. This
 	 * results in a callback to sbp2_add_host for each ieee1394
 	 * host controller currently registered, and for each of those
 	 * we register a scsi host with the scsi stack.
@@ -2881,9 +3136,42 @@
 	sbp2_init();
 
 	/* We return the number of hosts registered. */
-	return sbp2_host_count;
+	return scsi_driver_template.present;
 }
 
+
+/*
+ * Called for contents of procfs
+ */
+static const char *sbp2scsi_info (struct Scsi_Host *host)
+{
+	struct sbp2scsi_host_info *hi = sbp2_find_host_info_scsi(host);
+	static char info[1024];
+
+	if (!hi) /* shouldn't happen, but... */
+        	return "IEEE-1394 SBP-2 protocol driver";
+
+	sprintf(info, "IEEE-1394 SBP-2 protocol driver (host: %s)\n%s\n"
+		"SBP-2 module load options:\n"
+		"- Max speed supported: %s\n"
+		"- Max sectors per I/O supported: %d\n"
+		"- Max outstanding commands supported: %d\n"
+		"- Max outstanding commands per lun supported: %d\n"
+                "- Serialized I/O (debug): %s\n"
+		"- Exclusive login: %s",
+		hi->host->driver->name,
+		version,
+		hpsb_speedto_str[sbp2_max_speed],
+		sbp2_max_sectors,
+		sbp2_max_outstanding_cmds,
+		sbp2_max_cmds_per_lun,
+		sbp2_serialize_io ? "yes" : "no",
+		sbp2_exclusive_login ? "yes" : "no");
+
+	return info;
+}
+
+
 MODULE_AUTHOR("James Goodwin <jamesg@filanet.com>");
 MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver");
 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
@@ -2891,24 +3179,23 @@
 
 /* SCSI host template */
 static Scsi_Host_Template scsi_driver_template = {
-	name:		"IEEE-1394 SBP-2 protocol driver",
-	detect:		sbp2scsi_detect,
-	queuecommand:	sbp2scsi_queuecommand,
-	abort:		sbp2scsi_abort,
-	reset:		sbp2scsi_reset,
-	bios_param:	sbp2scsi_biosparam,
-	can_queue:	SBP2SCSI_MAX_OUTSTANDING_CMDS,
-	this_id:	-1,
-	sg_tablesize:	SBP2_MAX_SG_ELEMENTS,
-	cmd_per_lun:	SBP2SCSI_MAX_CMDS_PER_LUN,
-	use_clustering:	SBP2_CLUSTERING,
-	emulated:	1,
-
-	module:         THIS_MODULE,
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,26)
-	proc_name: SBP2_DEVICE_NAME
+	name:			"IEEE-1394 SBP-2 protocol driver",
+	info:			sbp2scsi_info,
+	detect:			sbp2scsi_detect,
+	queuecommand:		sbp2scsi_queuecommand,
+	eh_abort_handler:	sbp2scsi_abort,
+	eh_device_reset_handler:sbp2scsi_reset,
+	eh_bus_reset_handler:	sbp2scsi_reset,
+	eh_host_reset_handler:	sbp2scsi_reset,
+	bios_param:		sbp2scsi_biosparam,
+	this_id:		-1,
+	sg_tablesize:		SBP2_MAX_SG_ELEMENTS,
+	use_clustering:		SBP2_CLUSTERING,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	use_new_eh_code:	TRUE,
 #endif
+	emulated:		1,
+	proc_name:	SBP2_DEVICE_NAME,
 };
 
 static int sbp2_module_init(void)
@@ -2916,38 +3203,32 @@
 	SBP2_DEBUG("sbp2_module_init");
 
 	/*
-	 * Module load option for force one command at a time
+	 * Module load debug option to force one command at a time (serializing I/O)
 	 */
-	if (serialize_io) {
+	if (sbp2_serialize_io) {
 		SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)");
 		scsi_driver_template.can_queue = 1;
 		scsi_driver_template.cmd_per_lun = 1;
+	} else {
+		scsi_driver_template.can_queue = sbp2_max_outstanding_cmds;
+		scsi_driver_template.cmd_per_lun = sbp2_max_cmds_per_lun;
 	}
 
-	/*
-	 * Module load option to limit max size of requests from the
-	 * scsi drivers
+	/* 
+	 * Set max sectors (module load option). Default is 255 sectors. 
 	 */
-	if (no_large_packets) {
-		SBP2_ERR("Driver forced to limit max transfer size "
-			 "(no_large_packets = 1)");
-		scsi_driver_template.sg_tablesize = 0x1f;
-		scsi_driver_template.use_clustering = DISABLE_CLUSTERING;
-	}
-
-	if (mode_sense_hack) {
-		SBP2_ERR("Mode sense emulation enabled (mode_sense_hack = 1)");
-	}
+	scsi_driver_template.max_sectors = sbp2_max_sectors;
 
 	/*
 	 * Ideally we would register our scsi_driver_template with the
 	 * scsi stack and after that register with the ieee1394 stack
-	 * and process the add_host callbacks.  However, the detect
+	 * and process the add_host callbacks. However, the detect
 	 * function in the scsi host template requires that we find at
 	 * least one host, so we "nest" the registrations by calling
 	 * sbp2_init from the detect function.
 	 */
-	if (scsi_register_module(MODULE_SCSI_HA, &scsi_driver_template) ||
+	scsi_driver_template.module = THIS_MODULE;
+	if (SCSI_REGISTER_HOST(&scsi_driver_template) ||
 	    !scsi_driver_template.present) {
 		SBP2_ERR("Please load the lower level IEEE-1394 driver "
 			 "(e.g. ohci1394) before sbp2...");
@@ -2970,8 +3251,9 @@
 	 */
 	sbp2_cleanup();
 
-	if (scsi_unregister_module(MODULE_SCSI_HA, &scsi_driver_template))
+	if (SCSI_UNREGISTER_HOST(&scsi_driver_template))
 		SBP2_ERR("sbp2_module_exit: couldn't unregister scsi driver");
+
 }
 
 module_init(sbp2_module_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/sbp2.h linux/drivers/ieee1394/sbp2.h
--- linux.orig/drivers/ieee1394/sbp2.h	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/ieee1394/sbp2.h	2002-07-20 01:08:27.000000000 +0000
@@ -22,6 +22,15 @@
 #ifndef SBP2_H
 #define SBP2_H
 
+/* Some compatibility code */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define SCSI_REGISTER_HOST(tmpl)	scsi_register_module(MODULE_SCSI_HA, tmpl)
+#define SCSI_UNREGISTER_HOST(tmpl)	scsi_unregister_module(MODULE_SCSI_HA, tmpl)
+#else
+#define SCSI_REGISTER_HOST(tmpl)	scsi_register_host(tmpl)
+#define SCSI_UNREGISTER_HOST(tmpl)	scsi_unregister_host(tmpl)
+#endif
+
 #define SBP2_DEVICE_NAME		"sbp2"
 #define SBP2_DEVICE_NAME_SIZE		4
 
@@ -36,6 +45,7 @@
 #define ORB_DIRECTION_READ_FROM_MEDIA   0x1
 #define ORB_DIRECTION_NO_DATA_TRANSFER  0x2
 
+#define ORB_SET_NULL_PTR(value)			((value & 0x1) << 31)
 #define ORB_SET_NOTIFY(value)                   ((value & 0x1) << 31)
 #define ORB_SET_RQ_FMT(value)                   ((value & 0x3) << 29)
 #define ORB_SET_NODE_ID(value)			((value & 0xffff) << 16)
@@ -185,10 +195,28 @@
  * Miscellaneous SBP2 related config rom defines
  */
 
-#define SBP2_STATUS_FIFO_ADDRESS				0xfffe00000000ULL     /* for write posting! */
+/* 
+ * The status fifo address definition below is used as a status base, with a chunk
+ * separately assigned for each sbp2 device detected. For example, 0xfffe00000000ULL 
+ * is used for the first sbp2 device detected, 0xfffe00000020ULL for the next sbp2 
+ * device, and so on.
+ *
+ * Note: We could use a single status fifo address for all sbp2 devices, and figure 
+ * out which sbp2 device the status belongs to by looking at the source node id of
+ * the status write... but, using separate addresses for each sbp2 device allows for
+ * better code and the ability to support multiple luns within a single 1394 node.
+ *
+ * Also note that we choose the address range below as it is a region specified for
+ * write posting, where the ohci controller will automatically send an ack_complete
+ * when the status is written by the sbp2 device... saving a split transaction.   =)
+ */ 
+#define SBP2_STATUS_FIFO_ADDRESS				0xfffe00000000ULL
 #define SBP2_STATUS_FIFO_ADDRESS_HI                             0xfffe
 #define SBP2_STATUS_FIFO_ADDRESS_LO                             0x0
 
+#define SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(entry)			((entry) << 5)
+#define SBP2_STATUS_FIFO_OFFSET_TO_ENTRY(offset)		((offset) >> 5)
+
 #define SBP2_UNIT_DIRECTORY_OFFSET_KEY				0xd1
 #define SBP2_CSR_OFFSET_KEY					0x54
 #define SBP2_UNIT_SPEC_ID_KEY					0x12
@@ -199,6 +227,9 @@
 #define SBP2_DEVICE_TYPE_AND_LUN_KEY				0x14
 #define SBP2_FIRMWARE_REVISION_KEY				0x3c
 
+#define SBP2_DEVICE_TYPE(q)					(((q) >> 16) & 0x1f)
+#define SBP2_DEVICE_LUN(q)					((q) & 0xffff)
+
 #define SBP2_AGENT_STATE_OFFSET					0x00ULL
 #define SBP2_AGENT_RESET_OFFSET					0x04ULL
 #define SBP2_ORB_POINTER_OFFSET					0x08ULL
@@ -219,18 +250,13 @@
 #define SBP2_SW_VERSION_ENTRY					0x00010483
 
 /*
- * Miscellaneous general config rom related defines
+ * Other misc defines
  */
-
-#define CONFIG_ROM_INITIAL_MEMORY_SPACE 			0xfffff0000000ULL
-
-#define CONFIG_ROM_BASE_ADDRESS					0xfffff0000400ULL
-#define CONFIG_ROM_ROOT_DIR_BASE				0xfffff0000414ULL
-#define CONFIG_ROM_UNIT_DIRECTORY_OFFSET			0xfffff0000424ULL
-
 #define SBP2_128KB_BROKEN_FIRMWARE				0xa0b800
 #define SBP2_BROKEN_FIRMWARE_MAX_TRANSFER			0x20000
 
+#define SBP2_DEVICE_TYPE_LUN_UNINITIALIZED			0xffffffff
+
 /*
  * Flags for SBP-2 functions
  */
@@ -243,16 +269,18 @@
 #define SBP2_MAX_SG_ELEMENTS		SG_ALL
 #define SBP2_CLUSTERING			ENABLE_CLUSTERING
 #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
-#define SBP2SCSI_MAX_SCSI_IDS		8
+#define SBP2SCSI_MAX_SCSI_IDS		16	/* Max sbp2 device instances supported */
 #define SBP2SCSI_MAX_OUTSTANDING_CMDS	8	/* Max total outstanding sbp2 commands allowed at a time! */
-#define SBP2SCSI_MAX_CMDS_PER_LUN	4 	/* Max outstanding sbp2 commands per device - tune as needed */
+#define SBP2SCSI_MAX_CMDS_PER_LUN	1 	/* Max outstanding sbp2 commands per device - tune as needed */
+#define SBP2_MAX_SECTORS		255	/* Max sectors supported */
 
 #ifndef TYPE_SDAD
 #define TYPE_SDAD			0x0e	/* simplified direct access device */
 #endif
 
 /*
- * SCSI direction table... since the scsi stack doesn't specify direction...   =(
+ * SCSI direction table... 
+ * (now used as a back-up in case the direction passed down from above is "unknown")
  *
  * DIN = IN data direction
  * DOU = OUT data direction
@@ -286,13 +314,8 @@
 	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN
 };
 
-
-/*
- * Number of request packets available for actual sbp2 I/O requests (these are used
- * for sending command and agent reset packets).
- */
-#define SBP2_MAX_REQUEST_PACKETS	SBP2SCSI_MAX_OUTSTANDING_CMDS	/* Per host adapter instance */
-#define SBP2_MAX_COMMAND_ORBS		SBP2SCSI_MAX_CMDS_PER_LUN * 2	/* Per sbp2 device instance */
+#define SBP2_MAX_REQUEST_PACKETS	(sbp2_max_outstanding_cmds * 2)
+#define SBP2_MAX_COMMAND_ORBS		(sbp2_max_cmds_per_lun * 2)
 
 /*
  * Request packets structure (used for sending command and agent reset packets)
@@ -306,21 +329,26 @@
 
 };
 
+
+/* This is the two dma types we use for cmd_dma below */
+#define CMD_DMA_NONE   0x0
+#define CMD_DMA_PAGE   0x1
+#define CMD_DMA_SINGLE 0x2
+
 /* 
  * Encapsulates all the info necessary for an outstanding command. 
  */
 struct sbp2_command_info {
 
 	struct list_head list;
-	struct sbp2_command_orb command_orb;
-	dma_addr_t command_orb_dma;
+	struct sbp2_command_orb command_orb ____cacheline_aligned;
+	dma_addr_t command_orb_dma ____cacheline_aligned;
 	Scsi_Cmnd *Current_SCpnt;
 	void (*Current_done)(Scsi_Cmnd *);
-	unsigned int linked;
 
 	/* Also need s/g structure for each sbp2 command */
-	struct sbp2_unrestricted_page_table scatter_gather_element[SBP2_MAX_SG_ELEMENTS];
-	dma_addr_t sge_dma;
+	struct sbp2_unrestricted_page_table scatter_gather_element[SBP2_MAX_SG_ELEMENTS] ____cacheline_aligned;
+	dma_addr_t sge_dma ____cacheline_aligned;
 	void *sge_buffer;
 	dma_addr_t cmd_dma;
 	int dma_type;
@@ -340,6 +368,7 @@
 	 * Various sbp2 specific structures
 	 */
 	struct sbp2_command_orb *last_orb;
+	dma_addr_t last_orb_dma;
 	struct sbp2_login_orb *login_orb;
 	dma_addr_t login_orb_dma;
 	struct sbp2_login_response *login_response;
@@ -369,9 +398,9 @@
 	u32 sbp2_firmware_revision;
 
 	/* 
-	 * Wait queue used for logins, reconnects, logouts 
+	 * Variable used for logins, reconnects, logouts 
 	 */
-	wait_queue_head_t sbp2_login_wait;
+	atomic_t sbp2_login_complete;
 
 	/* 
 	 * Pool of command orbs, so we can have more than overlapped command per id
@@ -422,7 +451,7 @@
 	 * Here is the pool of request packets. All the hpsb packets (for 1394 bus transactions)
 	 * are allocated at init and simply re-initialized when needed.
 	 */
-	struct sbp2_request_packet request_packet[SBP2_MAX_REQUEST_PACKETS];
+	struct sbp2_request_packet *request_packet;
 
 	/*
 	 * SCSI ID instance data (one for each sbp2 device instance possible)
@@ -441,7 +470,7 @@
 static int sbp2util_create_request_packet_pool(struct sbp2scsi_host_info *hi);
 static void sbp2util_remove_request_packet_pool(struct sbp2scsi_host_info *hi);
 static struct sbp2_request_packet *sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
-									  nodeid_t node, u64 addr,
+									  struct node_entry *ne, u64 addr,
 									  size_t data_size,
 									  quadlet_t data);
 static void sbp2util_free_request_packet(struct sbp2_request_packet *request_packet);
@@ -472,6 +501,13 @@
 static void sbp2_remove_device(struct sbp2scsi_host_info *hi, 
 			       struct scsi_id_instance_data *scsi_id);
 
+#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
+static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data,
+                                     u64 addr, unsigned int length);
+static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
+                                    u64 addr, unsigned int length);
+#endif
+
 /*
  * SBP-2 protocol related prototypes
  */
@@ -487,17 +523,15 @@
 				   unchar *scsi_cmd,
 				   unsigned int scsi_use_sg,
 				   unsigned int scsi_request_bufflen,
-				   void *scsi_request_buffer, int dma_dir);
+				   void *scsi_request_buffer, 
+				   unsigned char scsi_dir);
 static int sbp2_link_orb_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id,
 				 struct sbp2_command_info *command);
 static int sbp2_send_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id,
 			     Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
-static int sbp2_send_split_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id,
-				   Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
 static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data);
-static void sbp2_check_sbp2_command(unchar *cmd);
-static void sbp2_check_sbp2_response(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, 
-				     Scsi_Cmnd *SCpnt);
+static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd);
+static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, Scsi_Cmnd *SCpnt);
 static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id);
 static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
 static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
@@ -506,10 +540,11 @@
  * Scsi interface related prototypes
  */
 static int sbp2scsi_detect (Scsi_Host_Template *tpnt);
+static const char *sbp2scsi_info (struct Scsi_Host *host);
 void sbp2scsi_setup(char *str, int *ints);
 static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[]);
 static int sbp2scsi_abort (Scsi_Cmnd *SCpnt); 
-static int sbp2scsi_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags); 
+static int sbp2scsi_reset (Scsi_Cmnd *SCpnt); 
 static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
 static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, 
 					   u32 status);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/ieee1394/video1394.c linux/drivers/ieee1394/video1394.c
--- linux.orig/drivers/ieee1394/video1394.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/ieee1394/video1394.c	2002-07-20 01:08:26.000000000 +0000
@@ -18,6 +18,9 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+/* jds -- add private data to file to keep track of iso contexts associated
+   with each open -- so release won't kill all iso transfers */
+
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -31,19 +34,12 @@
 #include <linux/fs.h>
 #include <linux/poll.h>
 #include <linux/smp_lock.h>
-#include <asm/byteorder.h>
-#include <asm/atomic.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
 #include <linux/proc_fs.h>
 #include <linux/tqueue.h>
 #include <linux/delay.h>
 #include <linux/devfs_fs_kernel.h>
 
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <asm/segment.h>
+#include <asm/bitops.h>
 #include <linux/types.h>
 #include <linux/wrapper.h>
 #include <linux/vmalloc.h>
@@ -59,7 +55,6 @@
 
 #include "ohci1394.h"
 
-#define VIDEO1394_MAJOR 172
 #define ISO_CHANNELS 64
 #define ISO_RECEIVE 0
 #define ISO_TRANSMIT 1
@@ -72,6 +67,14 @@
 #define vmalloc_32(x) vmalloc(x)
 #endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,3))
+#define remap_page_range_1394(vma, start, addr, size, prot) \
+	remap_page_range(start, addr, size, prot)
+#else
+#define remap_page_range_1394(vma, start, addr, size, prot) \
+	remap_page_range(vma, start, addr, size, prot)
+#endif
+
 struct it_dma_prg {
 	struct dma_cmd begin;
 	quadlet_t data[4];
@@ -81,6 +84,7 @@
 
 struct dma_iso_ctx {
 	struct ti_ohci *ohci;
+	int type; /* ISO_TRANSMIT or ISO_RECEIVE */
 	int ctx;
 	int channel;
 	int last_buffer;
@@ -108,6 +112,8 @@
 	spinlock_t lock;
 	unsigned int syt_offset;
 	int flags;
+
+	struct list_head link;
 };
 
 struct video_card {
@@ -115,9 +121,12 @@
 	struct list_head list;
 	int id;
 	devfs_handle_t devfs;
+};
 
-	struct dma_iso_ctx **ir_context;
-	struct dma_iso_ctx **it_context;
+
+struct file_ctx {
+	struct video_card *video;
+	struct list_head context_list;
 	struct dma_iso_ctx *current_ctx;
 };
 
@@ -145,7 +154,7 @@
 printk(level "video1394_%d: " fmt "\n" , card , ## args)
 
 static void irq_handler(int card, quadlet_t isoRecvIntEvent, 
-		 quadlet_t isoXmitIntEvent);
+			quadlet_t isoXmitIntEvent, void *data);
 
 static LIST_HEAD(video1394_cards);
 static spinlock_t video1394_cards_lock = SPIN_LOCK_UNLOCKED;
@@ -153,94 +162,41 @@
 static devfs_handle_t devfs_handle;
 static struct hpsb_highlevel *hl_handle = NULL;
 
-static struct video_template video_tmpl = { irq_handler };
-
 /* Code taken from bttv.c */
 
 /*******************************/
 /* Memory management functions */
 /*******************************/
 
-#define MDEBUG(x)	do { } while(0)		/* Debug memory management */
-
-/* [DaveM] I've recoded most of this so that:
- * 1) It's easier to tell what is happening
- * 2) It's more portable, especially for translating things
- *    out of vmalloc mapped areas in the kernel.
- * 3) Less unnecessary translations happen.
- *
- * The code used to assume that the kernel vmalloc mappings
- * existed in the page tables of every process, this is simply
- * not guaranteed.  We now use pgd_offset_k which is the
- * defined way to get at the kernel page tables.
- */
-
-/* Given PGD from the address space's page table, return the kernel
- * virtual mapping of the physical memory mapped at ADR.
- */
-static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
-{
-        unsigned long ret = 0UL;
-	pmd_t *pmd;
-	pte_t *ptep, pte;
-  
-	if (!pgd_none(*pgd)) {
-                pmd = pmd_offset(pgd, adr);
-                if (!pmd_none(*pmd)) {
-                        ptep = pte_offset(pmd, adr);
-                        pte = *ptep;
-                        if(pte_present(pte)) {
-				ret = (unsigned long) 
-					page_address(pte_page(pte));
-                                ret |= (adr & (PAGE_SIZE - 1));
-			}
-                }
-        }
-        MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
-	return ret;
-}
-
-static inline unsigned long uvirt_to_bus(unsigned long adr) 
-{
-        unsigned long kva, ret;
-
-        kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
-	ret = virt_to_bus((void *)kva);
-        MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
-        return ret;
-}
-
 static inline unsigned long kvirt_to_bus(unsigned long adr) 
 {
-        unsigned long va, kva, ret;
+	unsigned long kva, ret;
 
-        va = VMALLOC_VMADDR(adr);
-        kva = uvirt_to_kva(pgd_offset_k(va), va);
+	kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
+	kva |= adr & (PAGE_SIZE-1); /* restore the offset */
 	ret = virt_to_bus((void *)kva);
-        MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
-        return 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.
+ * This is used when initializing the contents of the area.
  */
 static inline unsigned long kvirt_to_pa(unsigned long adr) 
 {
-        unsigned long va, kva, ret;
+        unsigned long kva, ret;
 
-        va = VMALLOC_VMADDR(adr);
-        kva = uvirt_to_kva(pgd_offset_k(va), va);
+	kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
+	kva |= adr & (PAGE_SIZE-1); /* restore the offset */
 	ret = __pa(kva);
-        MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
         return ret;
 }
 
 static void * rvmalloc(unsigned long size)
 {
 	void * mem;
-	unsigned long adr, page;
-        
+	unsigned long adr;
+
+	size=PAGE_ALIGN(size);
 	mem=vmalloc_32(size);
 	if (mem) 
 	{
@@ -249,8 +205,7 @@
 	        adr=(unsigned long) mem;
 		while (size > 0) 
                 {
-	                page = kvirt_to_pa(adr);
-			mem_map_reserve(virt_to_page(__va(page)));
+			mem_map_reserve(vmalloc_to_page((void *)adr));
 			adr+=PAGE_SIZE;
 			size-=PAGE_SIZE;
 		}
@@ -260,15 +215,14 @@
 
 static void rvfree(void * mem, unsigned long size)
 {
-        unsigned long adr, page;
-        
+        unsigned long adr;
+
 	if (mem) 
 	{
 	        adr=(unsigned long) mem;
-		while (size > 0) 
+		while ((long) size > 0) 
                 {
-	                page = kvirt_to_pa(adr);
-			mem_map_unreserve(virt_to_page(__va(page)));
+			mem_map_unreserve(vmalloc_to_page((void *)adr));
 			adr+=PAGE_SIZE;
 			size-=PAGE_SIZE;
 		}
@@ -277,56 +231,75 @@
 }
 /* End of code taken from bttv.c */
 
-static int free_dma_iso_ctx(struct dma_iso_ctx **d)
+static int free_dma_iso_ctx(struct dma_iso_ctx *d)
 {
 	int i;
-	struct ti_ohci *ohci;
+	unsigned long *usage;
 	
-	if ((*d)==NULL) return -1;
-
-	ohci = (struct ti_ohci *)(*d)->ohci;
-
-	DBGMSG(ohci->id, "Freeing dma_iso_ctx %d", (*d)->ctx);
-
-	ohci1394_stop_context(ohci, (*d)->ctrlClear, NULL);
+	DBGMSG(d->ohci->id, "Freeing dma_iso_ctx %d", d->ctx);
 
-	if ((*d)->buf) rvfree((void *)(*d)->buf, 
-			      (*d)->num_desc * (*d)->buf_size);
+	ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
+	ohci1394_unhook_irq(d->ohci, irq_handler, d);
 
-	if ((*d)->ir_prg) {
-		for (i=0;i<(*d)->num_desc;i++) 
-			if ((*d)->ir_prg[i]) kfree((*d)->ir_prg[i]);
-		kfree((*d)->ir_prg);
-	}
-
-	if ((*d)->it_prg) {
-		for (i=0;i<(*d)->num_desc;i++) 
-			if ((*d)->it_prg[i]) kfree((*d)->it_prg[i]);
-		kfree((*d)->it_prg);
-	}
+	if (d->buf)
+		rvfree((void *)d->buf, d->num_desc * d->buf_size);
 
-	if ((*d)->buffer_status)
-		kfree((*d)->buffer_status);
-	if ((*d)->buffer_time)
-		kfree((*d)->buffer_time);
-	if ((*d)->last_used_cmd)
-		kfree((*d)->last_used_cmd);
-	if ((*d)->next_buffer)
-		kfree((*d)->next_buffer);
+	if (d->ir_prg) {
+		for (i=0;i<d->num_desc;i++) 
+			if (d->ir_prg[i]) kfree(d->ir_prg[i]);
+		kfree(d->ir_prg);
+	}
+
+	if (d->it_prg) {
+		for (i=0;i<d->num_desc;i++) 
+			if (d->it_prg[i]) kfree(d->it_prg[i]);
+		kfree(d->it_prg);
+	}
+
+	if (d->buffer_status)
+		kfree(d->buffer_status);
+	if (d->buffer_time)
+		kfree(d->buffer_time);
+	if (d->last_used_cmd)
+		kfree(d->last_used_cmd);
+	if (d->next_buffer)
+		kfree(d->next_buffer);
+
+	usage = (d->type == ISO_RECEIVE) ? &d->ohci->ir_ctx_usage :
+		&d->ohci->it_ctx_usage;
+       
+	/* clear the ISO context usage bit */
+	clear_bit(d->ctx, usage);
+	list_del(&d->link);
 
-	kfree(*d);
-	*d = NULL;
+	kfree(d);
 
 	return 0;
 }
 
 static struct dma_iso_ctx *
-alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int ctx, int num_desc,
+alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
 		  int buf_size, int channel, unsigned int packet_size)
 {
 	struct dma_iso_ctx *d=NULL;
 	int i;
 
+	unsigned long *usage = (type == ISO_RECEIVE) ? &ohci->ir_ctx_usage :
+		                                       &ohci->it_ctx_usage;
+
+	/* try to claim the ISO context usage bit */
+	for (i = 0; i < ohci->nb_iso_rcv_ctx; i++) {
+		if (!test_and_set_bit(i, usage)) {
+			PRINT(KERN_ERR, ohci->id, "Free iso ctx %d found", i);
+			break;
+		}
+	}
+
+	if (i == ohci->nb_iso_rcv_ctx) {
+		PRINT(KERN_ERR, ohci->id, "No DMA contexts available");
+		return NULL;
+	}
+	
 	d = (struct dma_iso_ctx *)kmalloc(sizeof(struct dma_iso_ctx), 
 					  GFP_KERNEL);
 	if (d==NULL) {
@@ -337,7 +310,8 @@
 	memset(d, 0, sizeof(struct dma_iso_ctx));
 
 	d->ohci = (void *)ohci;
-	d->ctx = ctx;
+	d->type = type;
+	d->ctx = i;
 	d->channel = channel;
 	d->num_desc = num_desc;
 	d->frame_size = buf_size;
@@ -350,11 +324,17 @@
 	d->ir_prg = NULL;
 	init_waitqueue_head(&d->waitq);
 
+	if (ohci1394_hook_irq(ohci, irq_handler, d) != 0) {
+		PRINT(KERN_ERR, ohci->id, "ohci1394_hook_irq() failed");
+		free_dma_iso_ctx(d);
+		return NULL;
+	}
+
 	d->buf = rvmalloc(d->num_desc * d->buf_size);
 
 	if (d->buf == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate dma buffer");
-		free_dma_iso_ctx(&d);
+		free_dma_iso_ctx(d);
 		return NULL;
 	}
 	memset(d->buf, 0, d->num_desc * d->buf_size);
@@ -371,7 +351,7 @@
 		if (d->ir_prg == NULL) {
 			PRINT(KERN_ERR, ohci->id, 
 			      "Failed to allocate dma ir prg");
-			free_dma_iso_ctx(&d);
+			free_dma_iso_ctx(d);
 			return NULL;
 		}
 		memset(d->ir_prg, 0, d->num_desc * sizeof(struct dma_cmd *));
@@ -387,7 +367,7 @@
 			if (d->ir_prg[i] == NULL) {
 				PRINT(KERN_ERR, ohci->id, 
 				      "Failed to allocate dma ir prg");
-				free_dma_iso_ctx(&d);
+				free_dma_iso_ctx(d);
 				return NULL;
 			}
 		}
@@ -403,7 +383,7 @@
 		if (d->it_prg == NULL) {
 			PRINT(KERN_ERR, ohci->id, 
 			      "Failed to allocate dma it prg");
-			free_dma_iso_ctx(&d);
+			free_dma_iso_ctx(d);
 			return NULL;
 		}
 		memset(d->it_prg, 0, d->num_desc*sizeof(struct it_dma_prg *));
@@ -415,7 +395,7 @@
 			      "Packet size %d (page_size: %ld) "
 			      "not yet supported\n",
 			      packet_size, PAGE_SIZE);
-			free_dma_iso_ctx(&d);
+			free_dma_iso_ctx(d);
 			return NULL;
 		}
 
@@ -434,7 +414,7 @@
 			if (d->it_prg[i] == NULL) {
 				PRINT(KERN_ERR, ohci->id, 
 				      "Failed to allocate dma it prg");
-				free_dma_iso_ctx(&d);
+				free_dma_iso_ctx(d);
 				return NULL;
 			}
 		}
@@ -451,22 +431,22 @@
 
 	if (d->buffer_status == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate buffer_status");
-		free_dma_iso_ctx(&d);
+		free_dma_iso_ctx(d);
 		return NULL;
 	}
 	if (d->buffer_time == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate buffer_time");
-		free_dma_iso_ctx(&d);
+		free_dma_iso_ctx(d);
 		return NULL;
 	}
 	if (d->last_used_cmd == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate last_used_cmd");
-		free_dma_iso_ctx(&d);
+		free_dma_iso_ctx(d);
 		return NULL;
 	}
 	if (d->next_buffer == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate next_buffer");
-		free_dma_iso_ctx(&d);
+		free_dma_iso_ctx(d);
 		return NULL;
 	}
 	memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int));
@@ -487,11 +467,11 @@
 static void reset_ir_status(struct dma_iso_ctx *d, int n)
 {
 	int i;
-	d->ir_prg[n][0].status = 4;
-	d->ir_prg[n][1].status = PAGE_SIZE-4;
+	d->ir_prg[n][0].status = cpu_to_le32(4);
+	d->ir_prg[n][1].status = cpu_to_le32(PAGE_SIZE-4);
 	for (i=2;i<d->nb_cmd-1;i++)
-		d->ir_prg[n][i].status = PAGE_SIZE;
-	d->ir_prg[n][i].status = d->left_size;
+		d->ir_prg[n][i].status = cpu_to_le32(PAGE_SIZE);
+	d->ir_prg[n][i].status = cpu_to_le32(d->left_size);
 }
 
 static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags)
@@ -501,38 +481,38 @@
 	int i;
 
 	/* the first descriptor will read only 4 bytes */
-	ir_prg[0].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
-		DMA_CTL_BRANCH | 4;
+	ir_prg[0].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
+		DMA_CTL_BRANCH | 4);
 
 	/* set the sync flag */
 	if (flags & VIDEO1394_SYNC_FRAMES)
-		ir_prg[0].control |= DMA_CTL_WAIT;
+		ir_prg[0].control |= cpu_to_le32(DMA_CTL_WAIT);
 
-	ir_prg[0].address = kvirt_to_bus(buf);
-	ir_prg[0].branchAddress =  (virt_to_bus(&(ir_prg[1].control)) 
-				    & 0xfffffff0) | 0x1;
+	ir_prg[0].address = cpu_to_le32(kvirt_to_bus(buf));
+	ir_prg[0].branchAddress =  cpu_to_le32((virt_to_bus(&(ir_prg[1].control)) 
+				    & 0xfffffff0) | 0x1);
 
 	/* the second descriptor will read PAGE_SIZE-4 bytes */
-	ir_prg[1].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
-		DMA_CTL_BRANCH | (PAGE_SIZE-4);
-	ir_prg[1].address = kvirt_to_bus(buf+4);
-	ir_prg[1].branchAddress =  (virt_to_bus(&(ir_prg[2].control)) 
-				    & 0xfffffff0) | 0x1;
+	ir_prg[1].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
+		DMA_CTL_BRANCH | (PAGE_SIZE-4));
+	ir_prg[1].address = cpu_to_le32(kvirt_to_bus(buf+4));
+	ir_prg[1].branchAddress =  cpu_to_le32((virt_to_bus(&(ir_prg[2].control)) 
+				    & 0xfffffff0) | 0x1);
 	
 	for (i=2;i<d->nb_cmd-1;i++) {
-		ir_prg[i].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | 
-			DMA_CTL_BRANCH | PAGE_SIZE;
-		ir_prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE);
+		ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | 
+			DMA_CTL_BRANCH | PAGE_SIZE);
+		ir_prg[i].address = cpu_to_le32(kvirt_to_bus(buf+(i-1)*PAGE_SIZE));
 
 		ir_prg[i].branchAddress =  
-			(virt_to_bus(&(ir_prg[i+1].control)) 
-			 & 0xfffffff0) | 0x1;
+			cpu_to_le32((virt_to_bus(&(ir_prg[i+1].control)) 
+			 & 0xfffffff0) | 0x1);
 	}
 
 	/* the last descriptor will generate an interrupt */
-	ir_prg[i].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | 
-		DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size;
-	ir_prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE);
+	ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | 
+		DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size);
+	ir_prg[i].address = cpu_to_le32(kvirt_to_bus(buf+(i-1)*PAGE_SIZE));
 }
 	
 static void initialize_dma_ir_ctx(struct dma_iso_ctx *d, int tag, int flags)
@@ -568,38 +548,19 @@
 }
 
 /* find which context is listening to this channel */
-int ir_ctx_listening(struct video_card *video, int channel)
-{
-	int i;
-	struct ti_ohci *ohci = video->ohci;
-
-	for (i=0;i<ohci->nb_iso_rcv_ctx-1;i++) 
-		if (video->ir_context[i]) {
-			if (video->ir_context[i]->channel==channel)
-				return i;
-		}
-		
-	PRINT(KERN_ERR, ohci->id, "No iso context is listening to channel %d",
-	      channel);
-
-	return -1;
-}
-
-int it_ctx_talking(struct video_card *video, int channel)
+static struct dma_iso_ctx *
+find_ctx(struct list_head *list, int type, int channel)
 {
-	int i;
-	struct ti_ohci *ohci = video->ohci;
+	struct list_head *lh;
 
-	for (i=0;i<ohci->nb_iso_xmit_ctx;i++) 
-		if (video->it_context[i]) {
-			if (video->it_context[i]->channel==channel)
-				return i;
-		}
-		
-	PRINT(KERN_ERR, ohci->id, "No iso context is talking to channel %d",
-	      channel);
+	list_for_each(lh, list) {
+		struct dma_iso_ctx *ctx;
+		ctx = list_entry(lh, struct dma_iso_ctx, link);
+		if (ctx->type == type && ctx->channel == channel)
+			return ctx;
+	}
 
-	return -1;
+	return NULL;
 }
 
 int wakeup_dma_ir_ctx(struct ti_ohci *ohci, struct dma_iso_ctx *d) 
@@ -614,10 +575,14 @@
 
 	spin_lock(&d->lock);
 	for (i=0;i<d->num_desc;i++) {
-		if (d->ir_prg[i][d->nb_cmd-1].status & 0xFFFF0000) {
+		if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) {
 			reset_ir_status(d, i);
 			d->buffer_status[i] = VIDEO1394_BUFFER_READY;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
+			get_fast_time(&d->buffer_time[i]);
+#else
 			do_gettimeofday(&d->buffer_time[i]);
+#endif
 		}
 	}
 	spin_unlock(&d->lock);
@@ -646,7 +611,7 @@
 	buf[7] = timeStamp & 0xff; 
 
     /* if first packet is empty packet, then put timestamp into the next full one too */
-    if ( (d->it_prg[n][0].data[1] >>16) == 0x008) {
+    if ( (le32_to_cpu(d->it_prg[n][0].data[1]) >>16) == 0x008) {
    	    buf += d->packet_size;
     	buf[6] = timeStamp >> 8;
 	    buf[7] = timeStamp & 0xff;
@@ -665,7 +630,7 @@
 	buf[7] = timeStamp & 0xff;
 
     /* if first packet is empty packet, then put timestamp into the next full one too */
-    if ( (d->it_prg[n][0].data[1] >>16) == 0x008) {
+    if ( (le32_to_cpu(d->it_prg[n][0].data[1]) >>16) == 0x008) {
    	    buf += d->packet_size;
     	buf[6] = timeStamp >> 8;
 	    buf[7] = timeStamp & 0xff;
@@ -689,7 +654,8 @@
 
 	spin_lock(&d->lock);
 	for (i=0;i<d->num_desc;i++) {
-		if (d->it_prg[i][d->last_used_cmd[i]].end.status& 0xFFFF0000) {
+		if (d->it_prg[i][d->last_used_cmd[i]].end.status& 
+			cpu_to_le32(0xFFFF0000)) {
 			int next = d->next_buffer[i];
 			put_timestamp(ohci, d, next);
 			d->it_prg[i][d->last_used_cmd[i]].end.status = 0;
@@ -709,39 +675,40 @@
 	d->last_used_cmd[n] = d->nb_cmd - 1;
 	for (i=0;i<d->nb_cmd;i++) {
 				 
-		it_prg[i].begin.control = DMA_CTL_OUTPUT_MORE |
-			DMA_CTL_IMMEDIATE | 8 ;
+		it_prg[i].begin.control = cpu_to_le32(DMA_CTL_OUTPUT_MORE |
+			DMA_CTL_IMMEDIATE | 8) ;
 		it_prg[i].begin.address = 0;
 		
 		it_prg[i].begin.status = 0;
 		
-		it_prg[i].data[0] = 
+		it_prg[i].data[0] = cpu_to_le32(
 			(SPEED_100 << 16) 
 			| (/* tag */ 1 << 14)
 			| (d->channel << 8) 
-			| (TCODE_ISO_DATA << 4);
-		if (i==0) it_prg[i].data[0] |= sync_tag;
-		it_prg[i].data[1] = d->packet_size << 16;
+			| (TCODE_ISO_DATA << 4));
+		if (i==0) it_prg[i].data[0] |= cpu_to_le32(sync_tag);
+		it_prg[i].data[1] = cpu_to_le32(d->packet_size << 16);
 		it_prg[i].data[2] = 0;
 		it_prg[i].data[3] = 0;
 		
-		it_prg[i].end.control = DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH;
+		it_prg[i].end.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST |
+			    	    	     DMA_CTL_BRANCH);
 		it_prg[i].end.address =
-			kvirt_to_bus(buf+i*d->packet_size);
+			cpu_to_le32(kvirt_to_bus(buf+i*d->packet_size));
 
 		if (i<d->nb_cmd-1) {
-			it_prg[i].end.control |= d->packet_size;
+			it_prg[i].end.control |= cpu_to_le32(d->packet_size);
 			it_prg[i].begin.branchAddress = 
-				(virt_to_bus(&(it_prg[i+1].begin.control)) 
-				 & 0xfffffff0) | 0x3;
+				cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control)) 
+				 & 0xfffffff0) | 0x3);
 			it_prg[i].end.branchAddress = 
-				(virt_to_bus(&(it_prg[i+1].begin.control)) 
-				 & 0xfffffff0) | 0x3;
+				cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control)) 
+				 & 0xfffffff0) | 0x3);
 		}
 		else {
 			/* the last prg generates an interrupt */
-			it_prg[i].end.control |= DMA_CTL_UPDATE | 
-				DMA_CTL_IRQ | d->left_size;
+			it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE | 
+				DMA_CTL_IRQ | d->left_size);
 			/* the last prg doesn't branch */
 			it_prg[i].begin.branchAddress = 0;
 			it_prg[i].end.branchAddress = 0;
@@ -780,21 +747,21 @@
 		} else {
 			size = packet_sizes[i];
 		}
-		it_prg[i].data[1] = size << 16; 
-		it_prg[i].end.control = DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH;
+		it_prg[i].data[1] = cpu_to_le32(size << 16); 
+		it_prg[i].end.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH);
 
 		if (i < d->nb_cmd-1 && packet_sizes[i+1] != 0) {
-			it_prg[i].end.control |= size;
+			it_prg[i].end.control |= cpu_to_le32(size);
 			it_prg[i].begin.branchAddress = 
-				(virt_to_bus(&(it_prg[i+1].begin.control)) 
-				 & 0xfffffff0) | 0x3;
+				cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control)) 
+				 & 0xfffffff0) | 0x3);
 			it_prg[i].end.branchAddress = 
-				(virt_to_bus(&(it_prg[i+1].begin.control)) 
-				 & 0xfffffff0) | 0x3;
+				cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control)) 
+				 & 0xfffffff0) | 0x3);
 		} else {
 			/* the last prg generates an interrupt */
-			it_prg[i].end.control |= DMA_CTL_UPDATE | 
-				DMA_CTL_IRQ | size;
+			it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE | 
+				DMA_CTL_IRQ | size);
 			/* the last prg doesn't branch */
 			it_prg[i].begin.branchAddress = 0;
 			it_prg[i].end.branchAddress = 0;
@@ -822,13 +789,14 @@
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1<<d->ctx);
 }
 
-static int do_iso_mmap(struct ti_ohci *ohci, struct dma_iso_ctx *d, 
-		       const char *adr, unsigned long size)
+static int do_iso_mmap(struct ti_ohci *ohci, struct dma_iso_ctx *d,
+		       struct vm_area_struct *vma)
 {
-        unsigned long start=(unsigned long) adr;
-        unsigned long page,pos;
+        unsigned long start = vma->vm_start;
+	unsigned long size = vma->vm_end - vma->vm_start;
+        unsigned long page, pos;
 
-        if (size>d->num_desc * d->buf_size) {
+        if (size > d->num_desc * d->buf_size) {
 		PRINT(KERN_ERR, ohci->id, 
 		      "iso context %d buf size is different from mmap size", 
 		      d->ctx);
@@ -840,14 +808,14 @@
 		return -EINVAL;
 	}
 
-        pos=(unsigned long) d->buf;
+	pos = (unsigned long) d->buf;
         while (size > 0) {
                 page = kvirt_to_pa(pos);
-                if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+                if (remap_page_range_1394(vma, start, page, PAGE_SIZE, PAGE_SHARED))
                         return -EAGAIN;
-                start+=PAGE_SIZE;
-                pos+=PAGE_SIZE;
-                size-=PAGE_SIZE;
+                start += PAGE_SIZE;
+                pos += PAGE_SIZE;
+                size -= PAGE_SIZE;
         }
         return 0;
 }
@@ -855,29 +823,10 @@
 static int video1394_ioctl(struct inode *inode, struct file *file,
 			   unsigned int cmd, unsigned long arg)
 {
-	struct video_card *video = NULL;
-	struct ti_ohci *ohci = NULL;
+	struct file_ctx *ctx = (struct file_ctx *)file->private_data;
+	struct video_card *video = ctx->video;
+	struct ti_ohci *ohci = video->ohci;
 	unsigned long flags;
-	struct list_head *lh;
-
-	spin_lock_irqsave(&video1394_cards_lock, flags);
-	if (!list_empty(&video1394_cards)) {
-		struct video_card *p;
-		list_for_each(lh, &video1394_cards) {
-			p = list_entry(lh, struct video_card, list);
-			if (p->id == MINOR(inode->i_rdev)) {
-				video = p;
-				ohci = video->ohci;
-				break;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&video1394_cards_lock, flags);
-
-	if (video == NULL) {
-		PRINT_G(KERN_ERR, __FUNCTION__": Unknown video card for minor %d", MINOR(inode->i_rdev));
-		return -EFAULT;
-	}
 
 	switch(cmd)
 	{
@@ -886,6 +835,7 @@
 	{
 		struct video1394_mmap v;
 		u64 mask;
+		struct dma_iso_ctx *d;
 		int i;
 
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
@@ -897,7 +847,7 @@
 		    for (i=0; i<ISO_CHANNELS; i++) {
 			if (!(ohci->ISO_channel_usage & mask)) {
 			    v.channel = i;
-			    PRINT(KERN_INFO, ohci->id, "Found free channel %d\n", i);
+			    PRINT(KERN_INFO, ohci->id, "Found free channel %d", i);
 			    break;
 			}
 			mask = mask << 1;
@@ -920,7 +870,7 @@
 			return -EFAULT;
 		}
 		ohci->ISO_channel_usage |= mask;
-		
+
 		if (v.buf_size<=0) {
 			PRINT(KERN_ERR, ohci->id,
 			      "Invalid %d length buffer requested",v.buf_size);
@@ -941,67 +891,47 @@
 		}
 
 		if (cmd == VIDEO1394_LISTEN_CHANNEL) {
-			/* find a free iso receive context */
-			for (i=0;i<ohci->nb_iso_rcv_ctx-1;i++) 
-				if (video->ir_context[i]==NULL) break;
-			    
-			if (i==(ohci->nb_iso_rcv_ctx-1)) {
-				PRINT(KERN_ERR, ohci->id, 
-				      "No iso context available");
-				return -EFAULT;
-			}
+			d = alloc_dma_iso_ctx(ohci, ISO_RECEIVE,
+					      v.nb_buffers, v.buf_size, 
+					      v.channel, 0);
 
-			video->ir_context[i] = 
-				alloc_dma_iso_ctx(ohci, ISO_RECEIVE, i+1, 
-						  v.nb_buffers, v.buf_size, 
-						  v.channel, 0);
-
-			if (video->ir_context[i] == NULL) {
+			if (d == NULL) {
 				PRINT(KERN_ERR, ohci->id, 
 				      "Couldn't allocate ir context");
 				return -EFAULT;
 			}
-			initialize_dma_ir_ctx(video->ir_context[i], 
-					      v.sync_tag, v.flags);
+			initialize_dma_ir_ctx(d, v.sync_tag, v.flags);
 
-			video->current_ctx = video->ir_context[i];
+			ctx->current_ctx = d;
 
-			v.buf_size = video->ir_context[i]->buf_size;
+			v.buf_size = d->buf_size;
+			list_add_tail(&d->link, &ctx->context_list);
 
 			PRINT(KERN_INFO, ohci->id, 
-			      "iso context %d listen on channel %d", i+1, 
-			      v.channel);
+			      "iso context %d listen on channel %d",
+			      d->ctx, v.channel);
 		}
 		else {
-			/* find a free iso transmit context */
-			for (i=0;i<ohci->nb_iso_xmit_ctx;i++) 
-				if (video->it_context[i]==NULL) break;
-			    
-			if (i==ohci->nb_iso_xmit_ctx) {
-				PRINT(KERN_ERR, ohci->id, 
-				      "No iso context available");
-				return -EFAULT;
-			}
-			
-			video->it_context[i] = 
-				alloc_dma_iso_ctx(ohci, ISO_TRANSMIT, i, 
-						  v.nb_buffers, v.buf_size, 
-						  v.channel, v.packet_size);
+			d = alloc_dma_iso_ctx(ohci, ISO_TRANSMIT,
+					      v.nb_buffers, v.buf_size, 
+					      v.channel, v.packet_size);
 
-			if (video->it_context[i] == NULL) {
+			if (d == NULL) {
 				PRINT(KERN_ERR, ohci->id, 
 				      "Couldn't allocate it context");
 				return -EFAULT;
 			}
-			initialize_dma_it_ctx(video->it_context[i], 
-					      v.sync_tag, v.syt_offset, v.flags);
+			initialize_dma_it_ctx(d, v.sync_tag, 
+					      v.syt_offset, v.flags);
 
-			video->current_ctx = video->it_context[i];
+			ctx->current_ctx = d;
 
-			v.buf_size = video->it_context[i]->buf_size;
+			v.buf_size = d->buf_size;
+
+			list_add_tail(&d->link, &ctx->context_list);
 
 			PRINT(KERN_INFO, ohci->id, 
-			      "Iso context %d talk on channel %d", i, 
+			      "Iso context %d talk on channel %d", d->ctx,
 			      v.channel);
 		}
 
@@ -1015,7 +945,7 @@
 	{
 		int channel;
 		u64 mask;
-		int i;
+		struct dma_iso_ctx *d;
 
 		if(copy_from_user(&channel, (void *)arg, sizeof(int)))
 			return -EFAULT;
@@ -1031,28 +961,19 @@
 			      "Channel %d is not being used", channel);
 			return -EFAULT;
 		}
-		ohci->ISO_channel_usage &= ~mask;
-
-		if (cmd == VIDEO1394_UNLISTEN_CHANNEL) {
-			i = ir_ctx_listening(video, channel);
-			if (i<0) return -EFAULT;
 
-			free_dma_iso_ctx(&video->ir_context[i]);
-
-			PRINT(KERN_INFO, ohci->id, 
-			      "Iso context %d stop listening on channel %d", 
-			      i+1, channel);
-		}
-		else {
-			i = it_ctx_talking(video, channel);
-			if (i<0) return -EFAULT;
+		/* Mark this channel as unused */
+		ohci->ISO_channel_usage &= ~mask;
 
-			free_dma_iso_ctx(&video->it_context[i]);
+		if (cmd == VIDEO1394_UNLISTEN_CHANNEL)
+			d = find_ctx(&ctx->context_list, ISO_RECEIVE, channel);
+		else
+			d = find_ctx(&ctx->context_list, ISO_TRANSMIT, channel);
 
-			PRINT(KERN_INFO, ohci->id, 
-			      "Iso context %d stop talking on channel %d", 
-			      i, channel);
-		}
+		if (d == NULL) return -EFAULT;
+		PRINT(KERN_INFO, ohci->id, "Iso context %d "
+		      "stop talking on channel %d", d->ctx, channel);
+		free_dma_iso_ctx(d);
 		
 		return 0;
 	}
@@ -1060,14 +981,11 @@
 	{
 		struct video1394_wait v;
 		struct dma_iso_ctx *d;
-		int i;
 
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
-		i = ir_ctx_listening(video, v.channel);
-		if (i<0) return -EFAULT;
-		d = video->ir_context[i];
+		d = find_ctx(&ctx->context_list, ISO_RECEIVE, v.channel);
 
 		if ((v.buffer<0) || (v.buffer>d->num_desc)) {
 			PRINT(KERN_ERR, ohci->id, 
@@ -1088,8 +1006,8 @@
 
 		if (d->last_buffer>=0) 
 			d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = 
-				(virt_to_bus(&(d->ir_prg[v.buffer][0].control)) 
-				 & 0xfffffff0) | 0x1;
+				cpu_to_le32((virt_to_bus(&(d->ir_prg[v.buffer][0].control)) 
+				 & 0xfffffff0) | 0x1);
 
 		d->last_buffer = v.buffer;
 
@@ -1129,9 +1047,7 @@
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
-		i = ir_ctx_listening(video, v.channel);
-		if (i<0) return -EFAULT;
-		d = video->ir_context[i];
+		d = find_ctx(&ctx->context_list, ISO_RECEIVE, v.channel);
 
 		if ((v.buffer<0) || (v.buffer>d->num_desc)) {
 			PRINT(KERN_ERR, ohci->id, 
@@ -1208,14 +1124,11 @@
 		struct video1394_wait v;
 		struct video1394_queue_variable qv;
 		struct dma_iso_ctx *d;
-		int i;
 
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
-		i = it_ctx_talking(video, v.channel);
-		if (i<0) return -EFAULT;
-		d = video->it_context[i];
+		d = find_ctx(&ctx->context_list, ISO_TRANSMIT, v.channel);
 
 		if ((v.buffer<0) || (v.buffer>d->num_desc)) {
 			PRINT(KERN_ERR, ohci->id, 
@@ -1253,14 +1166,14 @@
 			d->it_prg[d->last_buffer]
 				[ d->last_used_cmd[d->last_buffer]
 					].end.branchAddress = 
-				(virt_to_bus(&(d->it_prg[v.buffer][0].begin.control)) 
-				 & 0xfffffff0) | 0x3;
+				cpu_to_le32((virt_to_bus(&(d->it_prg[v.buffer][0].begin.control)) 
+				 & 0xfffffff0) | 0x3);
 
 			d->it_prg[d->last_buffer]
 				[d->last_used_cmd[d->last_buffer]
 					].begin.branchAddress = 
-				(virt_to_bus(&(d->it_prg[v.buffer][0].begin.control)) 
-				 & 0xfffffff0) | 0x3;
+				cpu_to_le32((virt_to_bus(&(d->it_prg[v.buffer][0].begin.control)) 
+				 & 0xfffffff0) | 0x3);
 			d->next_buffer[d->last_buffer] = v.buffer;
 		}
 		d->last_buffer = v.buffer;
@@ -1300,14 +1213,11 @@
 	{
 		struct video1394_wait v;
 		struct dma_iso_ctx *d;
-		int i;
 
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
-		i = it_ctx_talking(video, v.channel);
-		if (i<0) return -EFAULT;
-		d = video->it_context[i];
+		d = find_ctx(&ctx->context_list, ISO_TRANSMIT, v.channel);
 
 		if ((v.buffer<0) || (v.buffer>d->num_desc)) {
 			PRINT(KERN_ERR, ohci->id, 
@@ -1357,60 +1267,36 @@
 
 int video1394_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct video_card *video = NULL;
-	struct ti_ohci *ohci;
+	struct file_ctx *ctx = (struct file_ctx *)file->private_data;
+	struct video_card *video = ctx->video;
+	struct ti_ohci *ohci = video->ohci;
 	int res = -EINVAL;
-	unsigned long flags;
-	struct list_head *lh;
-
-        spin_lock_irqsave(&video1394_cards_lock, flags);
-        if (!list_empty(&video1394_cards)) {
-		struct video_card *p;
-		list_for_each(lh, &video1394_cards) {
-			p = list_entry(lh, struct video_card, list);
-			if (p->id == MINOR(file->f_dentry->d_inode->i_rdev)) {
-				video = p;
-				break;
-			}
-                }
-        }
-        spin_unlock_irqrestore(&video1394_cards_lock, flags);
-
-	if (video == NULL) {
-		PRINT_G(KERN_ERR, __FUNCTION__": Unknown video card for minor %d",
-			MINOR(file->f_dentry->d_inode->i_rdev));
-		return -EFAULT;
-	}
 
 	lock_kernel();
 	ohci = video->ohci;
 
-	if (video->current_ctx == NULL) {
+	if (ctx->current_ctx == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Current iso context not set");
 	} else
-		res = do_iso_mmap(ohci, video->current_ctx, 
-			   (char *)vma->vm_start, 
-			   (unsigned long)(vma->vm_end-vma->vm_start));
+		res = do_iso_mmap(ohci, ctx->current_ctx, vma);
 	unlock_kernel();
 	return res;
 }
 
 static int video1394_open(struct inode *inode, struct file *file)
 {
-	int i = MINOR(inode->i_rdev);
+	int i = ieee1394_file_to_instance(file);
 	unsigned long flags;
 	struct video_card *video = NULL;
 	struct list_head *lh;
+	struct file_ctx *ctx;
 
 	spin_lock_irqsave(&video1394_cards_lock, flags);
-	if (!list_empty(&video1394_cards)) {
-		struct video_card *p;
-		list_for_each(lh, &video1394_cards) {
-			p = list_entry(lh, struct video_card, list);
-			if (p->id == i) {
-				video = p;
-				break;
-			}
+	list_for_each(lh, &video1394_cards) {
+		struct video_card *p = list_entry(lh, struct video_card, list);
+		if (p->id == i) {
+			video = p;
+			break;
 		}
 	}
 	spin_unlock_irqrestore(&video1394_cards_lock, flags);
@@ -1418,124 +1304,71 @@
         if (video == NULL)
                 return -EIO;
 
-	V22_COMPAT_MOD_INC_USE_COUNT;
+	ctx = kmalloc(sizeof(struct file_ctx), GFP_KERNEL);
+	if (ctx == NULL)  {
+		PRINT(KERN_ERR, video->ohci->id, "Cannot malloc file_ctx");
+		return -ENOMEM;
+	}
+
+	memset(ctx, 0, sizeof(struct file_ctx));
+	ctx->video = video;
+	INIT_LIST_HEAD(&ctx->context_list);
+	ctx->current_ctx = NULL;
+	file->private_data = ctx;
 
 	return 0;
 }
 
 static int video1394_release(struct inode *inode, struct file *file)
 {
-	struct video_card *video = NULL;
-	struct ti_ohci *ohci;
+	struct file_ctx *ctx = (struct file_ctx *)file->private_data;
+	struct video_card *video = ctx->video;
+	struct ti_ohci *ohci = video->ohci;
+	struct list_head *lh, *next;
 	u64 mask;
-	int i;
-	unsigned long flags;
-	struct list_head *lh;
 
-        spin_lock_irqsave(&video1394_cards_lock, flags);
-        if (!list_empty(&video1394_cards)) {
-		struct video_card *p;
-		list_for_each(lh, &video1394_cards) {
-			p = list_entry(lh, struct video_card, list);
-			if (p->id == MINOR(inode->i_rdev)) {
-				video = p;
-				break;
-			}
-		}
-	}
-        spin_unlock_irqrestore(&video1394_cards_lock, flags);
-
-	if (video == NULL) {
-		PRINT_G(KERN_ERR, __FUNCTION__": Unknown device for minor %d",
-				MINOR(inode->i_rdev));
-		return 1;
+	lock_kernel();
+	list_for_each_safe(lh, next, &ctx->context_list) {
+		struct dma_iso_ctx *d;
+		d = list_entry(lh, struct dma_iso_ctx, link);
+		mask = (u64) 1 << d->channel;
+		
+		if (!(ohci->ISO_channel_usage & mask))
+			PRINT(KERN_ERR, ohci->id, "On release: Channel %d "
+			      "is not being used", d->channel);
+		else
+			ohci->ISO_channel_usage &= ~mask;
+		PRINT(KERN_INFO, ohci->id, "On release: Iso %s context "
+		      "%d stop listening on channel %d",
+		      d->type == ISO_RECEIVE ? "receive" : "transmit",
+		      d->ctx, d->channel);
+		free_dma_iso_ctx(d);
 	}
 
-	ohci = video->ohci;
-
-	lock_kernel();
-	for (i=0;i<ohci->nb_iso_rcv_ctx-1;i++) 
-		if (video->ir_context[i]) {
-			mask = (u64)0x1<<video->ir_context[i]->channel;
-			if (!(ohci->ISO_channel_usage & mask))
-				PRINT(KERN_ERR, ohci->id, 
-				      "Channel %d is not being used", 
-				      video->ir_context[i]->channel);
-			else
-				ohci->ISO_channel_usage &= ~mask;
-			PRINT(KERN_INFO, ohci->id, 
-			      "Iso receive context %d stop listening "
-			      "on channel %d", i+1, 
-			      video->ir_context[i]->channel);
-			free_dma_iso_ctx(&video->ir_context[i]);
-		}
+	kfree(ctx);
+	file->private_data = NULL;
 	
-	for (i=0;i<ohci->nb_iso_xmit_ctx;i++) 
-		if (video->it_context[i]) {
-			mask = (u64)0x1<<video->it_context[i]->channel;
-			if (!(ohci->ISO_channel_usage & mask))
-				PRINT(KERN_ERR, ohci->id, 
-				      "Channel %d is not being used", 
-				      video->it_context[i]->channel);
-			else
-				ohci->ISO_channel_usage &= ~mask;
-			PRINT(KERN_INFO, ohci->id, 
-			      "Iso transmit context %d stop talking "
-			      "on channel %d", i+1, 
-			      video->it_context[i]->channel);
-			free_dma_iso_ctx(&video->it_context[i]);
-		}
-
-	V22_COMPAT_MOD_DEC_USE_COUNT;
-
 	unlock_kernel();
 	return 0;
 }
 
 static void irq_handler(int card, quadlet_t isoRecvIntEvent, 
-		 quadlet_t isoXmitIntEvent)
+			quadlet_t isoXmitIntEvent, void *data)
 {
-	int i;
-	unsigned long flags;
-	struct video_card *video = NULL;
-	struct list_head *lh;
-
-	spin_lock_irqsave(&video1394_cards_lock, flags);
-	if (!list_empty(&video1394_cards)) {
-		struct video_card *p;
-		list_for_each(lh, &video1394_cards) {
-			p = list_entry(lh, struct video_card, list);
-			if (p->id == card) {
-				video = p;
-				break;
-			}
-                }
-        }
-        spin_unlock_irqrestore(&video1394_cards_lock, flags);
+	struct dma_iso_ctx *d = (struct dma_iso_ctx *) data;
 
-	if (video == NULL) {
-		PRINT_G(KERN_ERR, __FUNCTION__": Unknown card number %d!!",
-				card);
-		return;
-	}
-	
 	DBGMSG(card, "Iso event Recv: %08x Xmit: %08x",
 	       isoRecvIntEvent, isoXmitIntEvent);
 
-	for (i=0;i<video->ohci->nb_iso_rcv_ctx-1;i++)
-		if (isoRecvIntEvent & (1<<(i+1))) 
-			wakeup_dma_ir_ctx(video->ohci,
-					  video->ir_context[i]);
-
-	for (i=0;i<video->ohci->nb_iso_xmit_ctx;i++)
-		if (isoXmitIntEvent & (1<<i)) 
-			wakeup_dma_it_ctx(video->ohci,
-					  video->it_context[i]);
+	if (d->type == ISO_RECEIVE && isoRecvIntEvent & (1 << d->ctx))
+		wakeup_dma_ir_ctx(d->ohci, d);
+	if (d->type == ISO_TRANSMIT && isoXmitIntEvent & (1 << d->ctx))
+		wakeup_dma_it_ctx(d->ohci, d);
 }
 
 static struct file_operations video1394_fops=
 {
-        OWNER_THIS_MODULE
+	owner:		THIS_MODULE,
 	ioctl:		video1394_ioctl,
 	mmap:		video1394_mmap,
 	open:		video1394_open,
@@ -1544,10 +1377,12 @@
 
 static int video1394_init(struct ti_ohci *ohci)
 {
-	struct video_card *video = kmalloc(sizeof(struct video_card), GFP_KERNEL);
+	struct video_card *video;
 	unsigned long flags;
 	char name[16];
+	int minor;
 
+	video = kmalloc(sizeof(struct video_card), GFP_KERNEL);
 	if (video == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Cannot allocate video_card");
 		return -1;
@@ -1560,42 +1395,14 @@
 	list_add_tail(&video->list, &video1394_cards);
 	spin_unlock_irqrestore(&video1394_cards_lock, flags);
 
-	if (ohci1394_register_video(ohci, &video_tmpl)<0) {
-		PRINT(KERN_ERR, ohci->id, "Register_video failed");
-		return -1;
-	}
-
 	video->id = ohci->id;
 	video->ohci = ohci;
 
-	/* Iso receive dma contexts */
-	video->ir_context = (struct dma_iso_ctx **)
-		kmalloc((ohci->nb_iso_rcv_ctx-1)*
-			sizeof(struct dma_iso_ctx *), GFP_KERNEL);
-	if (video->ir_context) 
-		memset(video->ir_context, 0,
-		       (ohci->nb_iso_rcv_ctx-1)*sizeof(struct dma_iso_ctx *));
-	else {
-		PRINT(KERN_ERR, ohci->id, "Cannot allocate ir_context");
-		return -1;
-	}
-
-	/* Iso transmit dma contexts */
-	video->it_context = (struct dma_iso_ctx **)
-		kmalloc(ohci->nb_iso_xmit_ctx *
-			sizeof(struct dma_iso_ctx *), GFP_KERNEL);
-	if (video->it_context) 
-		memset(video->it_context, 0,
-		       ohci->nb_iso_xmit_ctx * sizeof(struct dma_iso_ctx *));
-	else {
-		PRINT(KERN_ERR, ohci->id, "Cannot allocate it_context");
-		return -1;
-	}
-
 	sprintf(name, "%d", video->id);
+	minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + video->id;
 	video->devfs = devfs_register(devfs_handle, name,
 				      DEVFS_FL_AUTO_OWNER,
-				      VIDEO1394_MAJOR, 0,
+				      IEEE1394_MAJOR, minor,
 				      S_IFCHR | S_IRUSR | S_IWUSR,
 				      &video1394_fops, NULL);
 
@@ -1605,27 +1412,7 @@
 /* Must be called under spinlock */
 static void remove_card(struct video_card *video)
 {
-	int i;
-
-	ohci1394_unregister_video(video->ohci, &video_tmpl);
-
 	devfs_unregister(video->devfs);
-
-	/* Free the iso receive contexts */
-	if (video->ir_context) {
-		for (i=0;i<video->ohci->nb_iso_rcv_ctx-1;i++) {
-			free_dma_iso_ctx(&video->ir_context[i]);
-		}
-		kfree(video->ir_context);
-	}
-
-	/* Free the iso transmit contexts */
-	if (video->it_context) {
-		for (i=0;i<video->ohci->nb_iso_xmit_ctx;i++) {
-			free_dma_iso_ctx(&video->it_context[i]);
-		}
-		kfree(video->it_context);
-	}
 	list_del(&video->list);
 
 	kfree(video);
@@ -1639,7 +1426,7 @@
 	struct video_card *p;
 
 	/* We only work with the OHCI-1394 driver */
-	if (strcmp(host->template->name, OHCI1394_DRIVER_NAME))
+	if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
 		return;
 
 	ohci = (struct ti_ohci *)host->hostdata;
@@ -1662,7 +1449,7 @@
 	struct ti_ohci *ohci;
 
 	/* We only work with the OHCI-1394 driver */
-	if (strcmp(host->template->name, OHCI1394_DRIVER_NAME))
+	if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
 		return;
 
 	ohci = (struct ti_ohci *)host->hostdata;
@@ -1687,19 +1474,19 @@
 	hpsb_unregister_highlevel (hl_handle);
 
 	devfs_unregister(devfs_handle);
-	devfs_unregister_chrdev(VIDEO1394_MAJOR, VIDEO1394_DRIVER_NAME);
-
+	ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394);
+	
 	PRINT_G(KERN_INFO, "Removed " VIDEO1394_DRIVER_NAME " module");
 }
 
 static int __init video1394_init_module (void)
 {
-	if (devfs_register_chrdev(VIDEO1394_MAJOR, VIDEO1394_DRIVER_NAME,
-				&video1394_fops)) {
-		PRINT_G(KERN_ERR, "video1394: unable to get major %d\n",
-				VIDEO1394_MAJOR);
-		return -EIO;
-	}
+	if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394,
+				      THIS_MODULE, &video1394_fops)) {
+		PRINT_G(KERN_ERR, "video1394: unable to get minor device block");
+ 		return -EIO;
+ 	}
+	
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
 	devfs_handle = devfs_mk_dir(NULL, VIDEO1394_DRIVER_NAME,
 			strlen(VIDEO1394_DRIVER_NAME), NULL);
@@ -1711,7 +1498,7 @@
 	if (hl_handle == NULL) {
 		PRINT_G(KERN_ERR, "No more memory for driver\n");
 		devfs_unregister(devfs_handle);
-		devfs_unregister_chrdev(VIDEO1394_MAJOR, VIDEO1394_DRIVER_NAME);
+		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394);
 		return -ENOMEM;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/input/joydev.c linux/drivers/input/joydev.c
--- linux.orig/drivers/input/joydev.c	2001-09-30 19:26:05.000000000 +0000
+++ linux/drivers/input/joydev.c	2002-07-20 01:08:36.000000000 +0000
@@ -363,7 +363,7 @@
 			return copy_to_user((struct js_corr *) arg, joydev->corr,
 						sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
 		case JSIOCSAXMAP:
-			if (copy_from_user((__u8 *) arg, joydev->abspam, sizeof(__u8) * ABS_MAX))
+			if (copy_from_user(joydev->abspam, (__u8 *) arg, sizeof(__u8) * ABS_MAX))
 				return -EFAULT;
 			for (i = 0; i < ABS_MAX; i++) {
 				if (joydev->abspam[i] > ABS_MAX) return -EINVAL;
@@ -374,7 +374,7 @@
 			return copy_to_user((__u8 *) arg, joydev->abspam,
 						sizeof(__u8) * ABS_MAX) ? -EFAULT : 0;
 		case JSIOCSBTNMAP:
-			if (copy_from_user((__u16 *) arg, joydev->absmap, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
+			if (copy_from_user(joydev->absmap, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
 				return -EFAULT;
 			for (i = 0; i < KEY_MAX - BTN_MISC; i++); {
 				if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
@@ -411,7 +411,7 @@
 static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev)
 {
 	struct joydev *joydev;
-	int i, j, minor;
+	int i, j, t, minor;
 
 	if (!(test_bit(EV_KEY, dev->evbit) && test_bit(EV_ABS, dev->evbit) &&
 	     (test_bit(ABS_X, dev->absbit) || test_bit(ABS_Y, dev->absbit)) &&
@@ -470,8 +470,10 @@
 		joydev->corr[i].prec = dev->absfuzz[j];
 		joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
 		joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
-		joydev->corr[i].coef[2] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]);
-		joydev->corr[i].coef[3] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]);
+		if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j])))
+			continue;
+		joydev->corr[i].coef[2] = (1 << 29) / t;
+		joydev->corr[i].coef[3] = (1 << 29) / t;
 
 		joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/Config.in linux/drivers/isdn/Config.in
--- linux.orig/drivers/isdn/Config.in	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/Config.in	2002-07-20 01:08:22.000000000 +0000
@@ -4,6 +4,7 @@
 
 # only included if CONFIG_ISDN != n
 
+define_bool CONFIG_ISDN_BOOL y
 if [ "$CONFIG_INET" != "n" ]; then
    bool '  Support synchronous PPP' CONFIG_ISDN_PPP
    if [ "$CONFIG_ISDN_PPP" != "n" ]; then
@@ -32,6 +33,7 @@
 comment 'Passive ISDN cards'
 dep_tristate 'HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
 if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
+   define_bool CONFIG_ISDN_HISAX y
    comment '  D-channel protocol features'
    bool '  HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
    if [ "$CONFIG_HISAX_EURO" != "n" ]; then
@@ -79,10 +81,12 @@
    fi
    bool '  HiSax debugging' CONFIG_HISAX_DEBUG
 
-   dep_tristate 'Sedlbauer PCMCIA cards' CONFIG_HISAX_SEDLBAUER_CS $CONFIG_PCMCIA
-   dep_tristate 'ELSA PCMCIA MicroLink cards' CONFIG_HISAX_ELSA_CS $CONFIG_PCMCIA
-   dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)' CONFIG_HISAX_ST5481 $CONFIG_HISAX $CONFIG_USB $CONFIG_EXPERIMENTAL
-   dep_tristate 'Fritz!PCIv2 support (EXPERIMENTAL)' CONFIG_HISAX_FRITZ_PCIPNP $CONFIG_HISAX $CONFIG_EXPERIMENTAL
+   dep_tristate 'Sedlbauer PCMCIA cards'                              CONFIG_HISAX_SEDLBAUER_CS  $CONFIG_ISDN_DRV_HISAX $CONFIG_PCMCIA
+   dep_tristate 'ELSA PCMCIA MicroLink cards'                         CONFIG_HISAX_ELSA_CS       $CONFIG_ISDN_DRV_HISAX $CONFIG_PCMCIA
+   dep_tristate 'AVM A1 PCMCIA cards'                                 CONFIG_HISAX_AVM_A1_CS     $CONFIG_ISDN_DRV_HISAX $CONFIG_PCMCIA $CONFIG_HISAX_AVM_A1_PCMCIA
+   dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)'                CONFIG_HISAX_ST5481        $CONFIG_ISDN_DRV_HISAX $CONFIG_USB    $CONFIG_EXPERIMENTAL
+   dep_tristate 'AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)' CONFIG_HISAX_FRITZ_PCIPNP  $CONFIG_ISDN_DRV_HISAX                $CONFIG_EXPERIMENTAL
+
 fi
 endmenu
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/Makefile linux/drivers/isdn/Makefile
--- linux.orig/drivers/isdn/Makefile	2001-07-02 21:07:55.000000000 +0000
+++ linux/drivers/isdn/Makefile	2002-07-20 01:08:40.000000000 +0000
@@ -2,7 +2,7 @@
 
 # The target object and module list name.
 
-O_TARGET	:= isdn.a
+O_TARGET	:= vmlinux-obj.o
 
 # Objects that export symbols.
 
@@ -32,9 +32,9 @@
 
 # Object files in subdirectories
 
-mod-subdirs				:= avmb1 eicon
+mod-subdirs				:= avmb1 eicon hisax
 subdir-$(CONFIG_ISDN_DIVERSION)		+= divert
-subdir-$(CONFIG_ISDN_DRV_HISAX)		+= hisax
+subdir-$(CONFIG_ISDN_HISAX)		+= hisax
 subdir-$(CONFIG_ISDN_DRV_ICN)		+= icn
 subdir-$(CONFIG_ISDN_DRV_PCBIT)		+= pcbit
 subdir-$(CONFIG_ISDN_DRV_SC)		+= sc
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/act2000/act2000.h linux/drivers/isdn/act2000/act2000.h
--- linux.orig/drivers/isdn/act2000/act2000.h	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/act2000/act2000.h	2002-07-20 01:08:21.000000000 +0000
@@ -178,19 +178,19 @@
         char regname[35];                /* Name used for request_region     */
 } act2000_card;
 
-extern __inline__ void act2000_schedule_tx(act2000_card *card)
+static inline void act2000_schedule_tx(act2000_card *card)
 {
         queue_task(&card->snd_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
 }
 
-extern __inline__ void act2000_schedule_rx(act2000_card *card)
+static inline void act2000_schedule_rx(act2000_card *card)
 {
         queue_task(&card->rcv_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
 }
 
-extern __inline__ void act2000_schedule_poll(act2000_card *card)
+static inline void act2000_schedule_poll(act2000_card *card)
 {
         queue_task(&card->poll_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/act2000/act2000_isa.c linux/drivers/isdn/act2000/act2000_isa.c
--- linux.orig/drivers/isdn/act2000/act2000_isa.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/act2000/act2000_isa.c	2002-07-20 01:08:34.000000000 +0000
@@ -178,7 +178,8 @@
                 card->flags &= ~ACT2000_FLAGS_PVALID;
         }
         if (!check_region(portbase, ISA_REGION)) {
-                request_region(portbase, ACT2000_PORTLEN, card->regname);
+                if (request_region(portbase, ACT2000_PORTLEN, card->regname) == NULL)
+			return -EIO;
                 card->port = portbase;
                 card->flags |= ACT2000_FLAGS_PVALID;
                 return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/act2000/capi.h linux/drivers/isdn/act2000/capi.h
--- linux.orig/drivers/isdn/act2000/capi.h	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/act2000/capi.h	2002-07-20 01:08:40.000000000 +0000
@@ -330,7 +330,7 @@
 	} msg;
 } actcapi_msg;
 
-extern __inline__ unsigned short
+static inline unsigned short
 actcapi_nextsmsg(act2000_card *card)
 {
 	unsigned long flags;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c
--- linux.orig/drivers/isdn/avmb1/kcapi.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/avmb1/kcapi.c	2002-07-20 01:08:39.000000000 +0000
@@ -103,8 +103,8 @@
 #define APPL(a)		   (&applications[(a)-1])
 #define	VALID_APPLID(a)	   ((a) && (a) <= CAPI_MAXAPPL && APPL(a)->applid == a)
 #define APPL_IS_FREE(a)    (APPL(a)->applid == 0)
-#define APPL_MARK_FREE(a)  do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0);
-#define APPL_MARK_USED(a)  do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0);
+#define APPL_MARK_FREE(a)  do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0)
+#define APPL_MARK_USED(a)  do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0)
 
 #define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/eicon/eicon.h linux/drivers/isdn/eicon/eicon.h
--- linux.orig/drivers/isdn/eicon/eicon.h	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/eicon/eicon.h	2002-07-20 01:08:30.000000000 +0000
@@ -348,19 +348,19 @@
 extern char *eicon_ctype_name[];
 
 
-extern __inline__ void eicon_schedule_tx(eicon_card *card)
+static inline void eicon_schedule_tx(eicon_card *card)
 {
         queue_task(&card->snd_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
 }
 
-extern __inline__ void eicon_schedule_rx(eicon_card *card)
+static inline void eicon_schedule_rx(eicon_card *card)
 {
         queue_task(&card->rcv_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
 }
 
-extern __inline__ void eicon_schedule_ack(eicon_card *card)
+static inline void eicon_schedule_ack(eicon_card *card)
 {
         queue_task(&card->ack_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/eicon/eicon_mod.c linux/drivers/isdn/eicon/eicon_mod.c
--- linux.orig/drivers/isdn/eicon/eicon_mod.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/eicon/eicon_mod.c	2002-07-20 01:08:25.000000000 +0000
@@ -665,8 +665,11 @@
 			else
 				cnt = skb->len;
 
-			if (user)
+			if (user) {
+				spin_unlock_irqrestore(&eicon_lock, flags);
 				copy_to_user(p, skb->data, cnt);
+				spin_lock_irqsave(&eicon_lock, flags);
+			}
 			else
 				memcpy(p, skb->data, cnt);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/Makefile linux/drivers/isdn/hisax/Makefile
--- linux.orig/drivers/isdn/hisax/Makefile	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/hisax/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -10,7 +10,7 @@
 
 # Objects that export symbols.
 
-export-objs	  := config.o fsm.o hisax_isac.o
+export-objs	  := config.o hisax_isac.o
 
 # Multipart objects.
 
@@ -61,6 +61,7 @@
 obj-$(CONFIG_ISDN_DRV_HISAX)		+= hisax.o
 obj-$(CONFIG_HISAX_SEDLBAUER_CS)	+= sedlbauer_cs.o
 obj-$(CONFIG_HISAX_ELSA_CS)		+= elsa_cs.o
+obj-$(CONFIG_HISAX_AVM_A1_CS)		+= avma1_cs.o
 obj-$(CONFIG_HISAX_ST5481)		+= hisax_st5481.o
 obj-$(CONFIG_HISAX_FRITZ_PCIPNP)        += hisax_isac.o hisax_fcpcipnp.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/avma1_cs.c linux/drivers/isdn/hisax/avma1_cs.c
--- linux.orig/drivers/isdn/hisax/avma1_cs.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/isdn/hisax/avma1_cs.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,552 @@
+/*
+ * PCMCIA client driver for AVM A1 / Fritz!PCMCIA
+ *
+ * Author       Carsten Paeth
+ * Copyright    1998-2001 by Carsten Paeth <calle@calle.in-berlin.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#include <linux/module.h>
+
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA cards");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
+
+int avm_a1_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot);
+void HiSax_closecard(int cardnr);
+
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
+static char *version =
+"avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+/* Parameters that can be set with 'insmod' */
+
+static int default_irq_list[11] = { 15, 13, 12, 11, 10, 9, 7, 5, 4, 3, -1 };
+static int irq_list[11] = { -1 };
+static int isdnprot = 2;
+
+MODULE_PARM(irq_list, "1-11i");
+MODULE_PARM(isdnprot, "1-4i");
+
+/*====================================================================*/
+
+/*
+   The event() function is this driver's Card Services event handler.
+   It will be called by Card Services when an appropriate card status
+   event is received.  The config() and release() entry points are
+   used to configure or release a socket, in response to card insertion
+   and ejection events.  They are invoked from the skeleton event
+   handler.
+*/
+
+static void avma1cs_config(dev_link_t *link);
+static void avma1cs_release(u_long arg);
+static int avma1cs_event(event_t event, int priority,
+			  event_callback_args_t *args);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static dev_link_t *avma1cs_attach(void);
+static void avma1cs_detach(dev_link_t *);
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static dev_info_t dev_info = "avma1_cs";
+
+/*
+   A linked list of "instances" of the skeleton device.  Each actual
+   PCMCIA card corresponds to one device instance, and is described
+   by one dev_link_t structure (defined in ds.h).
+
+   You may not want to use a linked list for this -- for example, the
+   memory card driver uses an array of dev_link_t pointers, where minor
+   device numbers are used to derive the corresponding array index.
+*/
+
+static dev_link_t *dev_list = NULL;
+
+/*
+   A dev_link_t structure has fields for most things that are needed
+   to keep track of a socket, but there will usually be some device
+   specific information that also needs to be kept track of.  The
+   'priv' pointer in a dev_link_t structure can be used to point to
+   a device-specific private data structure, like this.
+
+   A driver needs to provide a dev_node_t structure for each device
+   on a card.  In some cases, there is only one device per card (for
+   example, ethernet cards, modems).  In other cases, there may be
+   many actual or logical devices (SCSI adapters, memory cards with
+   multiple partitions).  The dev_node_t structures need to be kept
+   in a linked list starting at the 'dev' field of a dev_link_t
+   structure.  We allocate them in the card's private data structure,
+   because they generally can't be allocated dynamically.
+*/
+   
+typedef struct local_info_t {
+    dev_node_t	node;
+} local_info_t;
+
+/*====================================================================*/
+
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+    error_info_t err = { func, ret };
+    CardServices(ReportError, handle, &err);
+}
+
+/*======================================================================
+
+    avma1cs_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+    
+======================================================================*/
+
+static dev_link_t *avma1cs_attach(void)
+{
+    client_reg_t client_reg;
+    dev_link_t *link;
+    local_info_t *local;
+    int ret, i;
+    
+    DEBUG(0, "avma1cs_attach()\n");
+
+    /* Initialize the dev_link_t structure */
+    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+    memset(link, 0, sizeof(struct dev_link_t));
+    link->release.function = &avma1cs_release;
+    link->release.data = (u_long)link;
+
+    /* The io structure describes IO port mapping */
+    link->io.NumPorts1 = 16;
+    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+    link->io.NumPorts2 = 16;
+    link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
+    link->io.IOAddrLines = 5;
+
+    /* Interrupt setup */
+    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
+
+    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
+    if (irq_list[0] != -1) {
+	    for (i = 0; i < 10 && irq_list[i] > 0; i++)
+	       link->irq.IRQInfo2 |= 1 << irq_list[i];
+    } else {
+	    for (i = 0; i < 10 && default_irq_list[i] > 0; i++)
+	       link->irq.IRQInfo2 |= 1 << default_irq_list[i];
+    }
+    
+    /* General socket configuration */
+    link->conf.Attributes = CONF_ENABLE_IRQ;
+    link->conf.Vcc = 50;
+    link->conf.IntType = INT_MEMORY_AND_IO;
+    link->conf.ConfigIndex = 1;
+    link->conf.Present = PRESENT_OPTION;
+
+    /* Allocate space for private device-specific data */
+    local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+    memset(local, 0, sizeof(local_info_t));
+    link->priv = local;
+    
+    /* Register with Card Services */
+    link->next = dev_list;
+    dev_list = link;
+    client_reg.dev_info = &dev_info;
+    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+    client_reg.EventMask =
+	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+    client_reg.event_handler = &avma1cs_event;
+    client_reg.Version = 0x0210;
+    client_reg.event_callback_args.client_data = link;
+    ret = CardServices(RegisterClient, &link->handle, &client_reg);
+    if (ret != 0) {
+	cs_error(link->handle, RegisterClient, ret);
+	avma1cs_detach(link);
+	return NULL;
+    }
+
+    return link;
+} /* avma1cs_attach */
+
+/*======================================================================
+
+    This deletes a driver "instance".  The device is de-registered
+    with Card Services.  If it has been released, all local data
+    structures are freed.  Otherwise, the structures will be freed
+    when the device is released.
+
+======================================================================*/
+
+static void avma1cs_detach(dev_link_t *link)
+{
+    dev_link_t **linkp;
+
+    DEBUG(0, "avma1cs_detach(0x%p)\n", link);
+    
+    /* Locate device structure */
+    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+	if (*linkp == link) break;
+    if (*linkp == NULL)
+	return;
+
+    /*
+       If the device is currently configured and active, we won't
+       actually delete it yet.  Instead, it is marked so that when
+       the release() function is called, that will trigger a proper
+       detach().
+    */
+    if (link->state & DEV_CONFIG) {
+#ifdef PCMCIA_DEBUG
+	printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' "
+	       "still locked\n", link->dev->dev_name);
+#endif
+	link->state |= DEV_STALE_LINK;
+	return;
+    }
+
+    /* Break the link with Card Services */
+    if (link->handle)
+	CardServices(DeregisterClient, link->handle);
+    
+    /* Unlink device structure, free pieces */
+    *linkp = link->next;
+    if (link->priv) {
+	kfree(link->priv);
+    }
+    kfree(link);
+    
+} /* avma1cs_detach */
+
+/*======================================================================
+
+    avma1cs_config() is scheduled to run after a CARD_INSERTION event
+    is received, to configure the PCMCIA socket, and to make the
+    ethernet device available to the system.
+    
+======================================================================*/
+
+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
+		     cisparse_t *parse)
+{
+    int i;
+    i = CardServices(fn, handle, tuple);
+    if (i != CS_SUCCESS) return i;
+    i = CardServices(GetTupleData, handle, tuple);
+    if (i != CS_SUCCESS) return i;
+    return CardServices(ParseTuple, handle, tuple, parse);
+}
+
+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
+
+static void avma1cs_config(dev_link_t *link)
+{
+    client_handle_t handle;
+    tuple_t tuple;
+    cisparse_t parse;
+    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+    local_info_t *dev;
+    int i;
+    u_char buf[64];
+    char devname[128];
+    int busy = 0;
+    
+    handle = link->handle;
+    dev = link->priv;
+
+    DEBUG(0, "avma1cs_config(0x%p)\n", link);
+
+    /*
+       This reads the card's CONFIG tuple to find its configuration
+       registers.
+    */
+    do {
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	i = CardServices(GetFirstTuple, handle, &tuple);
+	if (i != CS_SUCCESS) break;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = 64;
+	tuple.TupleOffset = 0;
+	i = CardServices(GetTupleData, handle, &tuple);
+	if (i != CS_SUCCESS) break;
+	i = CardServices(ParseTuple, handle, &tuple, &parse);
+	if (i != CS_SUCCESS) break;
+	link->conf.ConfigBase = parse.config.base;
+    } while (0);
+    if (i != CS_SUCCESS) {
+	cs_error(link->handle, ParseTuple, i);
+	link->state &= ~DEV_CONFIG_PENDING;
+	return;
+    }
+    
+    /* Configure card */
+    link->state |= DEV_CONFIG;
+
+    do {
+
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = 254;
+	tuple.TupleOffset = 0;
+	tuple.DesiredTuple = CISTPL_VERS_1;
+
+	devname[0] = 0;
+	if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
+	    strncpy(devname,parse.version_1.str + parse.version_1.ofs[1], 
+			sizeof(devname));
+	}
+	/*
+         * find IO port
+         */
+	tuple.TupleData = (cisdata_t *)buf;
+	tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
+	tuple.Attributes = 0;
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	i = first_tuple(handle, &tuple, &parse);
+	while (i == CS_SUCCESS) {
+	    if (cf->io.nwin > 0) {
+		link->conf.ConfigIndex = cf->index;
+		link->io.BasePort1 = cf->io.win[0].base;
+		link->io.NumPorts1 = cf->io.win[0].len;
+		link->io.NumPorts2 = 0;
+                printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
+			link->io.BasePort1,
+		        link->io.BasePort1+link->io.NumPorts1 - 1);
+		i = CardServices(RequestIO, link->handle, &link->io);
+		if (i == CS_SUCCESS) goto found_port;
+	    }
+	    i = next_tuple(handle, &tuple, &parse);
+	}
+
+found_port:
+	if (i != CS_SUCCESS) {
+	    cs_error(link->handle, RequestIO, i);
+	    break;
+	}
+	
+	/*
+	 * allocate an interrupt line
+	 */
+	i = CardServices(RequestIRQ, link->handle, &link->irq);
+	if (i != CS_SUCCESS) {
+	    cs_error(link->handle, RequestIRQ, i);
+	    CardServices(ReleaseIO, link->handle, &link->io);
+	    break;
+	}
+	
+	/*
+         * configure the PCMCIA socket
+	  */
+	i = CardServices(RequestConfiguration, link->handle, &link->conf);
+	if (i != CS_SUCCESS) {
+	    cs_error(link->handle, RequestConfiguration, i);
+	    CardServices(ReleaseIO, link->handle, &link->io);
+	    CardServices(ReleaseIRQ, link->handle, &link->irq);
+	    break;
+	}
+
+    } while (0);
+
+    /* At this point, the dev_node_t structure(s) should be
+       initialized and arranged in a linked list at link->dev. */
+
+    strcpy(dev->node.dev_name, "A1");
+    dev->node.major = 45;
+    dev->node.minor = 0;
+    link->dev = &dev->node;
+    
+    link->state &= ~DEV_CONFIG_PENDING;
+    /* If any step failed, release any partially configured state */
+    if (i != 0) {
+	avma1cs_release((u_long)link);
+	return;
+    }
+
+    printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
+				link->io.BasePort1, link->irq.AssignedIRQ);
+
+    if (avm_a1_init_pcmcia((void *)(int)link->io.BasePort1,
+                           link->irq.AssignedIRQ,
+                           &busy, isdnprot) != 0) {
+       printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);
+       return;
+    }
+
+    i = 0; /* no returncode for cardnr :-( */
+
+    dev->node.minor = i;
+
+} /* avma1cs_config */
+
+/*======================================================================
+
+    After a card is removed, avma1cs_release() will unregister the net
+    device, and release the PCMCIA configuration.  If the device is
+    still open, this will be postponed until it is closed.
+    
+======================================================================*/
+
+static void avma1cs_release(u_long arg)
+{
+    dev_link_t *link = (dev_link_t *)arg;
+    local_info_t *local = link->priv;
+
+    DEBUG(0, "avma1cs_release(0x%p)\n", link);
+
+    /*
+       If the device is currently in use, we won't release until it
+       is actually closed.
+    */
+    if (link->open) {
+	DEBUG(1, "avma1_cs: release postponed, '%s' still open\n",
+	      link->dev->dev_name);
+	link->state |= DEV_STALE_CONFIG;
+	return;
+    }
+
+    /* no unregister function with hisax */
+    HiSax_closecard(local->node.minor);
+
+    /* Unlink the device chain */
+    link->dev = NULL;
+    
+    /* Don't bother checking to see if these succeed or not */
+    CardServices(ReleaseConfiguration, link->handle);
+    CardServices(ReleaseIO, link->handle, &link->io);
+    CardServices(ReleaseIRQ, link->handle, &link->irq);
+    link->state &= ~DEV_CONFIG;
+    
+    if (link->state & DEV_STALE_LINK)
+	avma1cs_detach(link);
+    
+} /* avma1cs_release */
+
+/*======================================================================
+
+    The card status event handler.  Mostly, this schedules other
+    stuff to run after an event is received.  A CARD_REMOVAL event
+    also sets some flags to discourage the net drivers from trying
+    to talk to the card any more.
+
+    When a CARD_REMOVAL event is received, we immediately set a flag
+    to block future accesses to this device.  All the functions that
+    actually access the device should check this flag to make sure
+    the card is still present.
+    
+======================================================================*/
+
+static int avma1cs_event(event_t event, int priority,
+			  event_callback_args_t *args)
+{
+    dev_link_t *link = args->client_data;
+
+    DEBUG(1, "avma1cs_event(0x%06x)\n", event);
+    
+    switch (event) {
+    case CS_EVENT_CARD_REMOVAL:
+	link->state &= ~DEV_PRESENT;
+	if (link->state & DEV_CONFIG) {
+	    link->release.expires =  jiffies + HZ/20;
+	    add_timer(&link->release);
+	}
+	break;
+    case CS_EVENT_CARD_INSERTION:
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	avma1cs_config(link);
+	break;
+    case CS_EVENT_PM_SUSPEND:
+	link->state |= DEV_SUSPEND;
+	/* Fall through... */
+    case CS_EVENT_RESET_PHYSICAL:
+	if (link->state & DEV_CONFIG)
+	    CardServices(ReleaseConfiguration, link->handle);
+	break;
+    case CS_EVENT_PM_RESUME:
+	link->state &= ~DEV_SUSPEND;
+	/* Fall through... */
+    case CS_EVENT_CARD_RESET:
+	if (link->state & DEV_CONFIG)
+	    CardServices(RequestConfiguration, link->handle, &link->conf);
+	break;
+    }
+    return 0;
+} /* avma1cs_event */
+
+/*====================================================================*/
+
+static int __init init_avma1_cs(void)
+{
+    servinfo_t serv;
+    DEBUG(0, "%s\n", version);
+    CardServices(GetCardServicesInfo, &serv);
+    if (serv.Revision != CS_RELEASE_CODE) {
+        printk(KERN_NOTICE "avma1_cs: Card Services release "
+               "does not match!\n");
+        return -1;
+    }
+    register_pccard_driver(&dev_info, &avma1cs_attach, &avma1cs_detach);
+    return 0;
+}
+
+static void __exit exit_avma1_cs(void)
+{
+    DEBUG(0, "avma1_cs: unloading\n");
+    unregister_pccard_driver(&dev_info);
+    while (dev_list != NULL)
+	if (dev_list->state & DEV_CONFIG)
+	    avma1cs_release((u_long)dev_list);
+        avma1cs_detach(dev_list);
+}
+
+module_init(init_avma1_cs);
+module_exit(exit_avma1_cs);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- linux.orig/drivers/isdn/hisax/config.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/hisax/config.c	2002-07-20 01:08:39.000000000 +0000
@@ -2150,3 +2150,11 @@
 
 module_init(HiSax_init);
 module_exit(HiSax_exit);
+
+EXPORT_SYMBOL(FsmNew);
+EXPORT_SYMBOL(FsmFree);
+EXPORT_SYMBOL(FsmEvent);
+EXPORT_SYMBOL(FsmChangeState);
+EXPORT_SYMBOL(FsmInitTimer);
+EXPORT_SYMBOL(FsmDelTimer);
+EXPORT_SYMBOL(FsmRestartTimer);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/fsm.c linux/drivers/isdn/hisax/fsm.c
--- linux.orig/drivers/isdn/hisax/fsm.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/hisax/fsm.c	2002-07-20 01:08:28.000000000 +0000
@@ -21,14 +21,6 @@
 
 #define FSM_TIMER_DEBUG 0
 
-EXPORT_SYMBOL(FsmNew);
-EXPORT_SYMBOL(FsmFree);
-EXPORT_SYMBOL(FsmEvent);
-EXPORT_SYMBOL(FsmChangeState);
-EXPORT_SYMBOL(FsmInitTimer);
-EXPORT_SYMBOL(FsmDelTimer);
-EXPORT_SYMBOL(FsmRestartTimer);
-
 int __init
 FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c
--- linux.orig/drivers/isdn/hisax/hfc_pci.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/hisax/hfc_pci.c	2002-07-20 01:08:34.000000000 +0000
@@ -76,6 +76,8 @@
 {
 	unsigned long flags;
 
+	printk(KERN_INFO "HiSax: release hfcpci at %p\n",
+		cs->hw.hfcpci.pci_io);
 	save_flags(flags);
 	cli();
 	cs->hw.hfcpci.int_m2 = 0;	/* interrupt output off ! */
@@ -86,13 +88,11 @@
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout((30 * HZ) / 1000);	/* Timeout 30ms */
 	Write_hfc(cs, HFCPCI_CIRM, 0);	/* Reset Off */
-#if CONFIG_PCI
 	pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, 0);	/* disable memory mapped ports + busmaster */
-#endif				/* CONFIG_PCI */
 	del_timer(&cs->hw.hfcpci.timer);
 	kfree(cs->hw.hfcpci.share_start);
 	cs->hw.hfcpci.share_start = NULL;
-	vfree(cs->hw.hfcpci.pci_io);
+	iounmap((void *)cs->hw.hfcpci.pci_io);
 }
 
 /********************************************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/hisax_fcpcipnp.c linux/drivers/isdn/hisax/hisax_fcpcipnp.c
--- linux.orig/drivers/isdn/hisax/hisax_fcpcipnp.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/isdn/hisax/hisax_fcpcipnp.c	2002-07-20 01:08:30.000000000 +0000
@@ -32,6 +32,9 @@
 #include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+
+#include <asm/io.h>
+
 #include "hisax_fcpcipnp.h"
 
 // debugging cruft
@@ -65,6 +68,7 @@
 
 static int protocol = 2;       /* EURO-ISDN Default */
 MODULE_PARM(protocol, "i");
+MODULE_LICENSE("GPL");
 
 // ----------------------------------------------------------------------
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/hisax_isac.c linux/drivers/isdn/hisax/hisax_isac.c
--- linux.orig/drivers/isdn/hisax/hisax_isac.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/hisax/hisax_isac.c	2002-07-20 01:08:26.000000000 +0000
@@ -44,6 +44,7 @@
 
 MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
 MODULE_DESCRIPTION("ISAC/ISAC-SX driver");
+MODULE_LICENSE("GPL");
 
 #define DBG_WARN      0x0001
 #define DBG_IRQ       0x0002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/md5sums.asc linux/drivers/isdn/hisax/md5sums.asc
--- linux.orig/drivers/isdn/hisax/md5sums.asc	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/isdn/hisax/md5sums.asc	2002-07-20 01:08:33.000000000 +0000
@@ -21,13 +21,13 @@
 3d22d2f2fe9af693eb3b471beecf596d  elsa.c
 fd6aedade5b5bbd73683a3de878b76d2  diva.c
 def8d69efd25186878dc123df73d9319  sedlbauer.c
-6c5bd0fdc59f33319823fa5367357983  hfc_pci.c
+8200d818771e3cbdef2a3c3e818d25ac  hfc_pci.c
 # end of md5sums
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.0.6 (GNU/Linux)
 Comment: For info see http://www.gnupg.org
 
-iD8DBQE8UYO9DiY0VZsg4ukRAqLzAKCKK7rFSNAWpBMtpJZ0kYvF+y+b1wCZAY8u
-hf6AL732sGhUsfRpwwdENVU=
-=B3yd
+iD8DBQE86l0pDiY0VZsg4ukRAt5eAKCjKt86NE4seQTp88McDaifcz8O8gCguMp3
+56AcQOgPpMtw0OpcYCY+iS8=
+=tfsn
 -----END PGP SIGNATURE-----
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/hisax/w6692.c linux/drivers/isdn/hisax/w6692.c
--- linux.orig/drivers/isdn/hisax/w6692.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/hisax/w6692.c	2002-07-20 01:08:39.000000000 +0000
@@ -29,11 +29,17 @@
 
 static const PCI_ENTRY id_list[] =
 {
-	{PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH, "Dynalink/AsusCom", "IS64PH"},
 	{PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, "Winbond", "W6692"},
-	{0, 0, NULL, NULL}
+	{PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH, "Dynalink/AsusCom", "IS64PH"},
+	{0, 0, "U.S.Robotics", "ISDN PCI Card TA"}
 };
 
+#define W6692_SV_USR   0x16ec
+#define W6692_SD_USR   0x3409
+#define W6692_WINBOND  0
+#define W6692_DYNALINK 1
+#define W6692_USR      2
+
 extern const char *CardType[];
 
 const char *w6692_revision = "$Revision: 1.1.4.1 $";
@@ -859,6 +865,28 @@
 	return (0);
 }
 
+void resetW6692(struct IsdnCardState *cs)
+{
+	cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
+	schedule_timeout((10*HZ)/1000);
+	cs->writeW6692(cs, W_D_CTL, 0x00);
+	schedule_timeout((10*HZ)/1000);
+	cs->writeW6692(cs, W_IMASK, 0xff);
+	cs->writeW6692(cs, W_D_SAM, 0xff);
+	cs->writeW6692(cs, W_D_TAM, 0xff);
+	cs->writeW6692(cs, W_D_EXIM, 0x00);
+	cs->writeW6692(cs, W_D_MODE, W_D_MODE_RACT);
+	cs->writeW6692(cs, W_IMASK, 0x18);
+	if (cs->subtyp == W6692_USR) {
+		/* seems that USR implemented some power control features
+		 * Pin 79 is connected to the oscilator circuit so we
+		 * have to handle it here
+		 */
+		cs->writeW6692(cs, W_PCTL, 0x80);
+		cs->writeW6692(cs, W_XDATA, 0x00);
+	}
+}
+
 void __init initW6692(struct IsdnCardState *cs, int part)
 {
 	if (part & 1) {
@@ -868,15 +896,7 @@
 		cs->dbusytimer.function = (void *) dbusy_timer_handler;
 		cs->dbusytimer.data = (long) cs;
 		init_timer(&cs->dbusytimer);
-
-		cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
-		cs->writeW6692(cs, W_D_CTL, 0x00);
-		cs->writeW6692(cs, W_IMASK, 0xff);
-		cs->writeW6692(cs, W_D_SAM, 0xff);
-		cs->writeW6692(cs, W_D_TAM, 0xff);
-		cs->writeW6692(cs, W_D_EXIM, 0x00);
-		cs->writeW6692(cs, W_D_MODE, W_D_MODE_RACT);
-		cs->writeW6692(cs, W_IMASK, 0x18);
+		resetW6692(cs);
 		ph_command(cs, W_L1CMD_RST);
 		cs->dc.w6692.ph_state = W_L1CMD_RST;
 		W6692_new_ph(cs);
@@ -943,9 +963,14 @@
 {
 	switch (mt) {
 		case CARD_RESET:
+			resetW6692(cs);
 			return (0);
 		case CARD_RELEASE:
+			cs->writeW6692(cs, W_IMASK, 0xff);
 			release_region(cs->hw.w6692.iobase, 256);
+			if (cs->subtyp == W6692_USR) {
+				cs->writeW6692(cs, W_XDATA, 0x04);
+			}
 			return (0);
 		case CARD_INIT:
 			initW6692(cs, 3);
@@ -988,6 +1013,7 @@
 		if (dev_w6692) {
 			if (pci_enable_device(dev_w6692))
 				continue;
+			cs->subtyp = id_idx;
 			break;
 		}
 		id_idx++;
@@ -998,6 +1024,13 @@
 		/* I think address 0 is allways the configuration area */
 		/* and address 1 is the real IO space KKe 03.09.99 */
 		pci_ioaddr = pci_resource_start(dev_w6692, 1);
+		/* USR ISDN PCI card TA need some special handling */
+		if (cs->subtyp == W6692_WINBOND) {
+			if ((W6692_SV_USR == dev_w6692->subsystem_vendor) &&
+			    (W6692_SD_USR == dev_w6692->subsystem_device)) {
+				cs->subtyp = W6692_USR;
+			}
+		}
 	}
 	if (!found) {
 		printk(KERN_WARNING "W6692: No PCI card found\n");
@@ -1014,18 +1047,18 @@
 	}
 	cs->hw.w6692.iobase = pci_ioaddr;
 	printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n",
-	       id_list[id_idx].vendor_name, id_list[id_idx].card_name,
-	       pci_ioaddr, dev_w6692->irq);
+	       id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name,
+	       pci_ioaddr, pci_irq);
 	if (check_region((cs->hw.w6692.iobase), 256)) {
 		printk(KERN_WARNING
 		       "HiSax: %s I/O ports %x-%x already in use\n",
-		       id_list[id_idx].card_name,
+		       id_list[cs->subtyp].card_name,
 		       cs->hw.w6692.iobase,
 		       cs->hw.w6692.iobase + 255);
 		return (0);
 	} else {
 		request_region(cs->hw.w6692.iobase, 256,
-			       id_list[id_idx].card_name);
+			       id_list[cs->subtyp].card_name);
 	}
 #else
 	printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n");
@@ -1035,7 +1068,7 @@
 
 	printk(KERN_INFO
 	       "HiSax: %s config irq:%d I/O:%x\n",
-	       id_list[id_idx].card_name, cs->irq,
+	       id_list[cs->subtyp].card_name, cs->irq,
 	       cs->hw.w6692.iobase);
 
 	cs->readW6692 = &ReadW6692;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- linux.orig/drivers/isdn/isdn_common.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/isdn_common.c	2002-07-20 01:08:32.000000000 +0000
@@ -75,9 +75,11 @@
 isdn_lock_drivers(void)
 {
 	int i;
+	isdn_ctrl cmd;
 
-	for (i = 0; i < dev->drivers; i++) {
-		isdn_ctrl cmd;
+	for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
+		if (!dev->drv[i])
+			continue;
 
 		cmd.driver = i;
 		cmd.arg = 0;
@@ -99,7 +101,10 @@
 {
 	int i;
 
-	for (i = 0; i < dev->drivers; i++)
+	for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
+		if (!dev->drv[i])
+			continue;
+
 		if (dev->drv[i]->locks > 0) {
 			isdn_ctrl cmd;
 
@@ -109,6 +114,7 @@
 			isdn_command(&cmd);
 			dev->drv[i]->locks--;
 		}
+	}
 }
 
 void
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- linux.orig/drivers/isdn/isdn_ppp.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/isdn/isdn_ppp.c	2002-07-20 01:08:38.000000000 +0000
@@ -1786,8 +1786,10 @@
 	memset(&t, 0, sizeof(struct ppp_stats));
 	if (dev->flags & IFF_UP) {
 		t.p.ppp_ipackets = lp->stats.rx_packets;
+		t.p.ppp_ibytes = lp->stats.rx_bytes;
 		t.p.ppp_ierrors = lp->stats.rx_errors;
 		t.p.ppp_opackets = lp->stats.tx_packets;
+		t.p.ppp_obytes = lp->stats.tx_bytes;
 		t.p.ppp_oerrors = lp->stats.tx_errors;
 #ifdef CONFIG_ISDN_PPP_VJ
 		if (slot >= 0 && ippp_table[slot]->slcomp) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/isdn/pcbit/capi.h linux/drivers/isdn/pcbit/capi.h
--- linux.orig/drivers/isdn/pcbit/capi.h	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/isdn/pcbit/capi.h	2002-07-20 01:08:39.000000000 +0000
@@ -63,8 +63,7 @@
 extern int capi_decode_debug_188(u_char *hdr, ushort hdrlen);
 #endif
 
-extern __inline__ 
-struct pcbit_chan * 
+static inline struct pcbit_chan * 
 capi_channel(struct pcbit_dev *dev, struct sk_buff *skb)
 {
 	ushort callref;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/adb.c linux/drivers/macintosh/adb.c
--- linux.orig/drivers/macintosh/adb.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/macintosh/adb.c	2002-07-20 01:08:36.000000000 +0000
@@ -64,7 +64,7 @@
 #ifdef CONFIG_ADB_IOP
 	&adb_iop_driver,
 #endif
-#ifdef CONFIG_ADB_PMU
+#if defined(CONFIG_ADB_PMU) || defined(CONFIG_ADB_PMU68K)
 	&via_pmu_driver,
 #endif
 #ifdef CONFIG_ADB_MACIO
@@ -78,7 +78,7 @@
 static int adb_got_sleep = 0;
 static int adb_inited = 0;
 static pid_t adb_probe_task_pid;
-static int adb_probe_task_flag;
+static DECLARE_MUTEX(adb_probe_mutex);
 static struct completion adb_probe_task_comp;
 static int sleepy_trackpad;
 int __adb_probe_sync;
@@ -242,7 +242,8 @@
 	printk(KERN_INFO "adb: finished probe task...\n");
 	
 	adb_probe_task_pid = 0;
-	clear_bit(0, &adb_probe_task_flag);
+	up(&adb_probe_mutex);
+	
 	return 0;
 }
 
@@ -264,14 +265,8 @@
 		do_adb_reset_bus();
 		return 0;
 	}
-		
-	/* We need to get a lock on the probe thread */
-	while (test_and_set_bit(0, &adb_probe_task_flag))
-		schedule();
 
-	/* Just wait for PID to be 0 just in case (possible race) */
-	while (adb_probe_task_pid != 0)
-		schedule();
+	down(&adb_probe_mutex);
 
 	/* Create probe thread as a child of keventd */
 	if (current_is_keventd())
@@ -341,21 +336,20 @@
 	case PBOOK_SLEEP_REQUEST:
 		adb_got_sleep = 1;
 		/* We need to get a lock on the probe thread */
-		while (test_and_set_bit(0, &adb_probe_task_flag))
-			schedule();
-		/* Just wait for PID to be 0 just in case (possible race) */
-		while (adb_probe_task_pid != 0)
-			schedule();
+		down(&adb_probe_mutex);
+		/* Stop autopoll */
 		if (adb_controller->autopoll)
 			adb_controller->autopoll(0);
 		ret = notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
-		if (ret & NOTIFY_STOP_MASK)
+		if (ret & NOTIFY_STOP_MASK) {
+			up(&adb_probe_mutex);
 			return PBOOK_SLEEP_REFUSE;
+		}
 		break;
 	case PBOOK_SLEEP_REJECT:
 		if (adb_got_sleep) {
 			adb_got_sleep = 0;
-			clear_bit(0, &adb_probe_task_flag);
+			up(&adb_probe_mutex);
 			adb_reset_bus();
 		}
 		break;
@@ -364,7 +358,7 @@
 		break;
 	case PBOOK_WAKE:
 		adb_got_sleep = 0;
-		clear_bit(0, &adb_probe_task_flag);
+		up(&adb_probe_mutex);
 		adb_reset_bus();
 		break;
 	}
@@ -773,9 +767,9 @@
 
 	atomic_inc(&state->n_pending);
 
-	/* If a probe is in progress, wait for it to complete */
-	while (adb_probe_task_pid != 0 || test_bit(0, &adb_probe_task_flag))
-		schedule();
+	/* If a probe is in progress or we are sleeping, wait for it to complete */
+	down(&adb_probe_mutex);
+	up(&adb_probe_mutex);
 
 	/* Special case for ADB_BUSRESET request, all others are sent to
 	   the controller */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/adbhid.c linux/drivers/macintosh/adbhid.c
--- linux.orig/drivers/macintosh/adbhid.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/macintosh/adbhid.c	2002-07-20 01:08:37.000000000 +0000
@@ -96,6 +96,11 @@
 static struct adb_ids mouse_ids;
 static struct adb_ids buttons_ids;
 
+#ifdef CONFIG_PMAC_BACKLIGHT
+/* Exported to via-pmu.c */
+int disable_kernel_backlight = 0;
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
 /* Kind of keyboard, see Apple technote 1152  */
 #define ADB_KEYBOARD_UNKNOWN	0
 #define ADB_KEYBOARD_ANSI	0x0100
@@ -284,44 +289,48 @@
 
 		switch (data[1] & 0x0f) {
 		case 0x8:	/* mute */
-			input_report_key(&adbhid[id]->input, KEY_MUTE,
-				data[1] == (data[1] & 0xf));
+			input_report_key(&adbhid[id]->input, KEY_MUTE, down);
 			break;
 
 		case 0x7:	/* volume decrease */
-			input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN,
-				data[1] == (data[1] & 0xf));
+			input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
 			break;
 
 		case 0x6:	/* volume increase */
-			input_report_key(&adbhid[id]->input, KEY_VOLUMEUP,
-				data[1] == (data[1] & 0xf));
+			input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down);
  			break;
 
 		case 0xb:	/* eject */
-			input_report_key(&adbhid[id]->input, KEY_EJECTCD,
-				data[1] == (data[1] & 0xf));
+			input_report_key(&adbhid[id]->input, KEY_EJECTCD, down);
 			break;
-
-#ifdef CONFIG_PMAC_BACKLIGHT
 		case 0xa:	/* brightness decrease */
-			if (!down || backlight < 0)
+#ifdef CONFIG_PMAC_BACKLIGHT
+			if (!disable_kernel_backlight) {
+				if (!down || backlight < 0)
+					break;
+				if (backlight > BACKLIGHT_OFF)
+					set_backlight_level(backlight-1);
+				else
+					set_backlight_level(BACKLIGHT_OFF);
 				break;
-			if (backlight > BACKLIGHT_OFF)
-				set_backlight_level(backlight-1);
-			else
-				set_backlight_level(BACKLIGHT_OFF);
+			}
+#endif /* CONFIG_PMAC_BACKLIGHT */
+			input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
 			break;
-
 		case 0x9:	/* brightness increase */
-			if (!down || backlight < 0)
+#ifdef CONFIG_PMAC_BACKLIGHT
+			if (!disable_kernel_backlight) {
+				if (!down || backlight < 0)
+					break;
+				if (backlight < BACKLIGHT_MAX)
+					set_backlight_level(backlight+1);
+				else 
+					set_backlight_level(BACKLIGHT_MAX);
 				break;
-			if (backlight < BACKLIGHT_MAX)
-				set_backlight_level(backlight+1);
-			else 
-				set_backlight_level(BACKLIGHT_MAX);
-			break;
+			}
 #endif /* CONFIG_PMAC_BACKLIGHT */
+			input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down);
+			break;
 		}
 	  }
 	  break;
@@ -521,6 +530,8 @@
 			set_bit(KEY_MUTE, adbhid[id]->input.keybit);
 			set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit);
 			set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit);
+			set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit);
+			set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit);
 			set_bit(KEY_EJECTCD, adbhid[id]->input.keybit);
 			break;
 		}
@@ -900,8 +911,10 @@
 
 static int __init adbhid_init(void)
 {
+#ifndef CONFIG_MAC
 	if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
 	    return 0;
+#endif
 
 	led_request.complete = 1;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/apm_emu.c linux/drivers/macintosh/apm_emu.c
--- linux.orig/drivers/macintosh/apm_emu.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/macintosh/apm_emu.c	2002-07-20 01:08:35.000000000 +0000
@@ -436,15 +436,18 @@
 	int		percentage     = -1;
 	int             time_units     = -1;
 	int		real_count     = 0;
+	int		charge         = -1;
+	int		current        = 0;
 	int		i;
 	char *		p = buf;
+	char		charging       = 0;
 
 	ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0);
 	for (i=0; i<pmu_battery_count; i++) {
 		if (percentage < 0)
 			percentage = 0;
-		if (time_units < 0)
-			time_units = 0;
+		if (charge < 0)
+			charge = 0;
 		if (pmu_batteries[i].flags & PMU_BATT_PRESENT) {
 			percentage += (pmu_batteries[i].charge * 100) /
 				pmu_batteries[i].max_charge;
@@ -452,14 +455,19 @@
 			 * time when AC is plugged ? If yes, just remove
 			 * that test --BenH
 			 */
-			if (!ac_line_status)
-				time_units += pmu_batteries[i].time_remaining / 60;
+			if (!ac_line_status) {
+				charge += pmu_batteries[i].charge;
+				current += pmu_batteries[i].current;
+			}
 			real_count++;
-			if (!(pmu_batteries[i].flags & PMU_BATT_CHARGING))
-				battery_flag &= ~0x08;
+			if ((pmu_batteries[i].flags & PMU_BATT_CHARGING))
+				charging++;
 		}
 	}
 	if (real_count) {
+		time_units = (charge * 59) / (current * -1);
+		if(!charging)
+			battery_flag &= ~0x08;
 		percentage /= real_count;
 		if (battery_flag & 0x08) {
 			battery_status = 0x03;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/mac_hid.c linux/drivers/macintosh/mac_hid.c
--- linux.orig/drivers/macintosh/mac_hid.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/macintosh/mac_hid.c	2002-07-20 01:08:30.000000000 +0000
@@ -204,7 +204,8 @@
 	0, 0, 0, 0, 0, KEY_VOLUMEDOWN, KEY_MUTE, 0,		/* 0x20-0x27 */
 	0, 0, 0, 0, 0, 0, 0, 0,					/* 0x28-0x2f */
 	0, 0, 0, 0, 0, KEY_KPSLASH, 0, KEY_SYSRQ,		/* 0x30-0x37 */
-	KEY_RIGHTALT, 0, 0, KEY_EJECTCD, 0, 0, 0, 0,		/* 0x38-0x3f */
+	KEY_RIGHTALT, KEY_BRIGHTNESSUP, KEY_BRIGHTNESSDOWN, 
+		KEY_EJECTCD, 0, 0, 0, 0,			/* 0x38-0x3f */
 	0, 0, 0, 0, 0, 0, 0, KEY_HOME,				/* 0x40-0x47 */
 	KEY_UP, KEY_PAGEUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END, /* 0x48-0x4f */
 	KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE, 0, 0, 0, 0, /* 0x50-0x57 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/mac_keyb.c linux/drivers/macintosh/mac_keyb.c
--- linux.orig/drivers/macintosh/mac_keyb.c	2001-09-18 21:23:14.000000000 +0000
+++ linux/drivers/macintosh/mac_keyb.c	2002-07-20 01:08:34.000000000 +0000
@@ -256,7 +256,6 @@
 #endif
 
 extern struct kbd_struct kbd_table[];
-extern wait_queue_head_t keypress_wait;
 
 extern void handle_scancode(unsigned char, int);
 
@@ -423,7 +422,6 @@
 	struct tty_struct *tty;
 
 	tty = console_driver.table? console_driver.table[fg_console]: NULL;
-	wake_up(&keypress_wait);
 	if (tty) {
 		tty_insert_flip_char(tty, ch, 0);
 		con_schedule_flip(tty);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- linux.orig/drivers/macintosh/macserial.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/macintosh/macserial.c	2002-07-20 01:08:34.000000000 +0000
@@ -2866,30 +2866,6 @@
 	/* Don't disable the transmitter. */
 }
 
-/*
- *	Receive character from the serial port
- */
-static int serial_console_wait_key(struct console *co)
-{
-	struct mac_serial *info = zs_soft + co->index;
-	int           val;
-
-	/* Turn of interrupts and enable the transmitter. */
-	write_zsreg(info->zs_channel, R1, info->curregs[1] & ~INT_ALL_Rx);
-	write_zsreg(info->zs_channel, R3, info->curregs[3] | RxENABLE);
-
-	/* Wait for something in the receive buffer. */
-	while((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) == 0)
-		eieio();
-	val = read_zsdata(info->zs_channel);
-
-	/* Restore the values in the registers. */
-	write_zsreg(info->zs_channel, R1, info->curregs[1]);
-	write_zsreg(info->zs_channel, R3, info->curregs[3]);
-
-	return val;
-}
-
 static kdev_t serial_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
@@ -3080,7 +3056,6 @@
 	name:		"ttyS",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/via-cuda.c linux/drivers/macintosh/via-cuda.c
--- linux.orig/drivers/macintosh/via-cuda.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/macintosh/via-cuda.c	2002-07-20 01:08:25.000000000 +0000
@@ -222,12 +222,19 @@
 static int
 cuda_init(void)
 {
+#ifdef CONFIG_PPC
     if (via == NULL)
 	return -ENODEV;
-#ifndef CONFIG_PPC
+    return 0;
+#else 
+    int err = cuda_init_via();
+    if (err) {
+	printk(KERN_ERR "cuda_init_via() failed\n");
+	return -ENODEV;
+    }
+
     return via_cuda_start();
 #endif
-    return 0;
 }
 #endif /* CONFIG_ADB */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/via-macii.c linux/drivers/macintosh/via-macii.c
--- linux.orig/drivers/macintosh/via-macii.c	2000-12-04 01:48:19.000000000 +0000
+++ linux/drivers/macintosh/via-macii.c	2002-07-20 01:08:24.000000000 +0000
@@ -10,6 +10,8 @@
  * Rewrite for Unified ADB by Joshua M. Thompson (funaho@jurai.org)
  *
  * 1999-08-02 (jmt) - Initial rewrite for Unified ADB.
+ * 2000-03-29 Tony Mantler <tonym@mac.linux-m68k.org>
+ * 				- Big overhaul, should actually work now.
  */
  
 #include <stdarg.h>
@@ -98,7 +100,6 @@
 
 static enum macii_state {
 	idle,
-	sent_first_byte,
 	sending,
 	reading,
 	read_done,
@@ -133,7 +134,7 @@
 
 	via = via1;
 
-	printk("adb: Mac II ADB Driver v0.4 for Unified ADB\n");
+	printk("adb: Mac II ADB Driver v1.0 for Unified ADB\n");
 	return 0;
 }
 
@@ -186,7 +187,7 @@
 	static int in_poll=0;
 	static struct adb_request req;
 	unsigned long flags;
-
+	
 	if (in_poll) printk("macii_queue_poll: double poll!\n");
 
 	in_poll++;
@@ -212,7 +213,7 @@
 	static int in_retransmit = 0;
 	static struct adb_request rt;
 	unsigned long flags;
-
+	
 	if (in_retransmit) printk("macii_retransmit: double retransmit!\n");
 
 	in_retransmit++;
@@ -256,11 +257,11 @@
 {
 	unsigned long flags;
 
-	if (req->nbytes < 2 || req->data[0] != ADB_PACKET) {
+	if (req->nbytes < 2 || req->data[0] != ADB_PACKET || req->nbytes > 15) {
 		req->complete = 1;
 		return -EINVAL;
 	}
-
+	
 	req->next = 0;
 	req->sent = 0;
 	req->complete = 0;
@@ -319,7 +320,7 @@
 
 	req = current_req;
 	if (!req) return;
-
+	
 	/* assert macii_state == idle */
 	if (macii_state != idle) {
 		printk("macii_start: called while driver busy (%p %x %x)!\n",
@@ -333,7 +334,9 @@
 	 * IRQ signaled ?? (means ADB controller wants to send, or might 
 	 * be end of packet if we were reading)
 	 */
+#if 0 /* FIXME: This is broke broke broke, for some reason */
 	if ((via[B] & TREQ) == 0) {
+		printk("macii_start: weird poll stuff. huh?\n");
 		/*
 		 *	FIXME - we need to restart this on a timer
 		 *	or a collision at boot hangs us.
@@ -359,6 +362,7 @@
 			need_poll = 0;
 		}
 	}
+#endif
 	/*
 	 * Another retry pending? (sanity check)
 	 */
@@ -368,7 +372,7 @@
 
 	/* Now send it. Be careful though, that first byte of the request */
 	/* is actually ADB_PACKET; the real data begins at index 1!	  */
-
+	
 	/* store command byte */
 	command_byte = req->data[1];
 	/* Output mode */
@@ -378,7 +382,7 @@
 	/* set ADB state to 'command' */
 	via[B] = (via[B] & ~ST_MASK) | ST_CMD;
 
-	macii_state = sent_first_byte;
+	macii_state = sending;
 	data_index = 2;
 
 	restore_flags(flags);
@@ -441,7 +445,7 @@
 			reply_len = 1;
 			prefix_len = 1;
 			reading_reply = 0;
-
+			
 			macii_state = reading;
 			break;
 
@@ -461,15 +465,14 @@
 			macii_state = reading;			
 			break;
 
-		case sent_first_byte:
+		case sending:
 			req = current_req;
-			/* maybe we're already done (Talk, or Poll)? */
 			if (data_index >= req->nbytes) {
-				/* reset to shift in */
-				/* If it's a Listen command and we're done, someone's doing weird stuff. */
+				/* print an error message if a listen command has no data */
 				if (((command_byte & 0x0C) == 0x08)
-				    && (console_loglevel == 10))
-					printk("macii_interrupt: listen command with no data: %x!\n", 
+				 /* && (console_loglevel == 10) */
+				    && (data_index == 2))
+					printk("MacII ADB: listen command with no data: %x!\n", 
 						command_byte);
 				/* reset to shift in */
 				via[ACR] &= ~SR_OUT;
@@ -492,42 +495,15 @@
 						macii_retransmit((command_byte & 0xF0) >> 4);
 				}
 			} else {
-				/* SR already set to shift out; send byte */
-				via[SR] = current_req->data[data_index++];
-				/* set state to ST_EVEN (first byte was: ST_CMD) */
-				via[B] = (via[B] & ~ST_MASK) | ST_EVEN;
-				macii_state = sending;
-			}
-			break;
-
-		case sending:
-			req = current_req;
-			if (data_index >= req->nbytes) {
-				/* reset to shift in */
-				via[ACR] &= ~SR_OUT;
-				x = via[SR];
-				/* set ADB state idle - might get SRQ */
-				via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
-
-				req->sent = 1;
+				via[SR] = req->data[data_index++];
 
-				if (req->reply_expected) {
-					macii_state = awaiting_reply;
+				if ( (via[B] & ST_MASK) == ST_CMD ) {
+					/* just sent the command byte, set to EVEN */
+					via[B] = (via[B] & ~ST_MASK) | ST_EVEN;
 				} else {
-					req->complete = 1;
-					current_req = req->next;
-					if (req->done) (*req->done)(req);
-					macii_state = idle;
-					if (current_req || retry_req)
-						macii_start();
-					else
-						macii_retransmit((command_byte & 0xF0) >> 4);
+					/* invert state bits, toggle ODD/EVEN */
+					via[B] ^= ST_MASK;
 				}
-			} else {
-				via[SR] = req->data[data_index++];
-
-				/* invert state bits, toggle ODD/EVEN */
-				via[B] ^= ST_MASK;
 			}
 			break;
 
@@ -551,7 +527,7 @@
 				 * on /INT, meaning we missed it :-(
 				 */
 				x = via[SR];
-				if (x != 0xFF) printk("macii_interrupt: mistaken timeout/SRQ!\n");
+				if (x != 0xFF) printk("MacII ADB: mistaken timeout/SRQ!\n");
 
 				if ((status & TREQ) == (last_status & TREQ)) {
 					/* Not a timeout. Unsolicited SRQ? weird. */
@@ -598,7 +574,7 @@
 			 * byte of timeout packet! 
 			 * Timeouts are signaled by 4x FF.
 			 */
-			if (!(status & TREQ) && (x == 0x00)) { /* != 0xFF */
+			if (((status & TREQ) == 0) && (x == 0x00)) { /* != 0xFF */
 				/* invert state bits, toggle ODD/EVEN */
 				via[B] ^= ST_MASK;
 
@@ -646,12 +622,12 @@
 				need_poll = 0;
 				break;
 			}
-
+			
+			/* set ADB state to idle */
+			via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
+			
 			/* /IRQ seen, so the ADB controller has data for us */
-			if (!(status & TREQ)) {
-				/* set ADB state to idle */
-				via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
-
+			if ((via[B] & TREQ) != 0) {
 				macii_state = reading;
 
 				reply_buf[0] = command_byte;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/via-maciisi.c linux/drivers/macintosh/via-maciisi.c
--- linux.orig/drivers/macintosh/via-maciisi.c	2000-02-13 19:21:42.000000000 +0000
+++ linux/drivers/macintosh/via-maciisi.c	2002-07-20 01:08:39.000000000 +0000
@@ -9,7 +9,11 @@
  *
  * Original sources (c) Alan Cox, Paul Mackerras, and others.
  *
- * Rewritten for Unified ADB by David Huggins-Daines <dhd@debian.org> */
+ * Rewritten for Unified ADB by David Huggins-Daines <dhd@debian.org>
+ * 
+ * 7/13/2000- extensive changes by Andrew McPherson <andrew@macduff.dhs.org>
+ * Works about 30% of the time now.
+ */
 
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -56,6 +60,8 @@
 
 #define ADB_DELAY 150
 
+#undef DEBUG_MACIISI_ADB
+
 static struct adb_request* current_req = NULL;
 static struct adb_request* last_req = NULL;
 static unsigned char maciisi_rbuf[16];
@@ -63,6 +69,8 @@
 static int data_index;
 static int reading_reply;
 static int reply_len;
+static int tmp;
+static int need_sync;
 
 static enum maciisi_state {
     idle,
@@ -73,12 +81,13 @@
 static int maciisi_probe(void);
 static int maciisi_init(void);
 static int maciisi_send_request(struct adb_request* req, int sync);
+static void maciisi_sync(struct adb_request *req);
 static int maciisi_write(struct adb_request* req);
 static void maciisi_interrupt(int irq, void* arg, struct pt_regs* regs);
 static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs);
 static int maciisi_init_via(void);
 static void maciisi_poll(void);
-static void maciisi_start(void);
+static int maciisi_start(void);
 
 struct adb_driver via_maciisi_driver = {
 	"Mac IIsi",
@@ -114,63 +123,105 @@
 		return err;
 	}
 
-	if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK, 
+	if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST, 
 			"ADB", maciisi_interrupt)) {
 		printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);
 		return -EAGAIN;
 	}
 
-	printk("adb: Mac IIsi driver v0.1 for Unified ADB.\n");
+	printk("adb: Mac IIsi driver v0.2 for Unified ADB.\n");
 	return 0;
 }
 
+/* Flush data from the ADB controller */
 static void
 maciisi_stfu(void)
 {
 	int status = via[B] & (TIP|TREQ);
 
 	if (status & TREQ) {
+#ifdef DEBUG_MACIISI_ADB
 		printk (KERN_DEBUG "maciisi_stfu called with TREQ high!\n");
+#endif
 		return;
 	}
+	
+	udelay(ADB_DELAY);
+	via[ACR] &= ~SR_OUT;
+	via[IER] = IER_CLR | SR_INT;
 
-	/* start transfer */
-	via[B] |= TIP;
-	while (!(status & TREQ)) {
-		int poll_timeout = ADB_DELAY * 5;
-		/* Poll for SR interrupt */
-		while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
-			status = via[B] & (TIP|TREQ);
-		via[SR]; /* Clear shift register */
-		printk(KERN_DEBUG "maciisi_stfu: status %x timeout %d\n",
-		       status, poll_timeout);
-		
-		/* ACK on-off */
-		via[B] |= TACK;
+	udelay(ADB_DELAY);
+
+	status = via[B] & (TIP|TREQ);
+
+	if (!(status & TREQ))
+	{
+		via[B] |= TIP;
+
+		while(1)
+		{
+			int poll_timeout = ADB_DELAY * 5;
+			/* Poll for SR interrupt */
+			while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
+				status = via[B] & (TIP|TREQ);
+
+			tmp = via[SR]; /* Clear shift register */
+#ifdef DEBUG_MACIISI_ADB
+			printk(KERN_DEBUG "maciisi_stfu: status %x timeout %d data %x\n",
+			       status, poll_timeout, tmp);
+#endif	
+			if(via[B] & TREQ)
+				break;
+	
+			/* ACK on-off */
+			via[B] |= TACK;
+			udelay(ADB_DELAY);
+			via[B] &= ~TACK;
+		}
+
+		/* end frame */
+		via[B] &= ~TIP;
 		udelay(ADB_DELAY);
-		via[B] &= ~TACK;
 	}
-	/* end frame */
-	via[B] &= ~TIP;
+
+	via[IER] = IER_SET | SR_INT;	
 }
 
 /* All specifically VIA-related initialization goes here */
 static int
 maciisi_init_via(void)
 {
+	int	i;
+	
 	/* Set the lines up. We want TREQ as input TACK|TIP as output */
 	via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
 	/* Shift register on input */
 	via[ACR]  = (via[ACR] & ~SR_CTRL) | SR_EXT;
+#ifdef DEBUG_MACIISI_ADB
 	printk(KERN_DEBUG "maciisi_init_via: initial status %x\n", via[B] & (TIP|TREQ));
+#endif
+	/* Wipe any pending data and int */
+	tmp = via[SR];
+	/* Enable keyboard interrupts */
+	via[IER] = IER_SET | SR_INT;
 	/* Set initial state: idle */
 	via[B] &= ~(TACK|TIP);
-	/* Wipe any pending data and int */
-	via[SR];
-	if (!(via[B] & TREQ))
+	/* Clear interrupt bit */
+	via[IFR] = SR_INT;
+
+	for(i = 0; i < 60; i++) {
+		udelay(ADB_DELAY);
 		maciisi_stfu();
-	via[IER] = IER_SET | SR_INT;
+		udelay(ADB_DELAY);
+		if(via[B] & TREQ)
+			break;
+	}
+	if (i == 60)
+		printk(KERN_ERR "maciisi_init_via: bus jam?\n");
+
 	maciisi_state = idle;
+	need_sync = 0;
+
 	return 0;
 }
 
@@ -179,41 +230,77 @@
 maciisi_send_request(struct adb_request* req, int sync)
 {
 	int i;
-	static int dump_packet = 1;
+	int count;
+
+#ifdef DEBUG_MACIISI_ADB
+	static int dump_packet = 0;
+#endif
 
 	if (via == NULL) {
 		req->complete = 1;
 		return -ENXIO;
 	}
 
+#ifdef DEBUG_MACIISI_ADB
 	if (dump_packet) {
 		printk(KERN_DEBUG "maciisi_send_request:");
 		for (i = 0; i < req->nbytes; i++) {
 			printk(" %.2x", req->data[i]);
 		}
-		printk("\n");
+		printk(" sync %d\n", sync);
 	}
+#endif
+
 	req->reply_expected = 1;
 	
 	i = maciisi_write(req);
 	if (i)
+	{
+		/* Normally, if a packet requires syncing, that happens at the end of
+		 * maciisi_send_request. But if the transfer fails, it will be restarted
+		 * by maciisi_interrupt(). We use need_sync to tell maciisi_interrupt
+		 * when to sync a packet that it sends out.
+		 * 
+		 * Suggestions on a better way to do this are welcome.
+		 */
+		if(i == -EBUSY && sync)
+			need_sync = 1;
+		else
+			need_sync = 0;
 		return i;
-	
-	if (sync) {
-		while (!req->complete) {
-			maciisi_poll();
-		}
 	}
+	if(sync)
+		maciisi_sync(req);
+	
 	return 0;
 }
 
+/* Poll the ADB chip until the request completes */
+static void maciisi_sync(struct adb_request *req)
+{
+	int count = 0; 
+
+#ifdef DEBUG_MACIISI_ADB
+	printk(KERN_DEBUG "maciisi_sync called\n");
+#endif
+
+	/* If for some reason the ADB chip shuts up on us, we want to avoid an endless loop. */
+	while (!req->complete && count++ < 50) {
+		maciisi_poll();
+	}
+	/* This could be BAD... when the ADB controller doesn't respond
+	 * for this long, it's probably not coming back :-( */
+	if(count >= 50) /* Hopefully shouldn't happen */
+		printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
+}
+
 /* Enqueue a request, and run the queue if possible */
 static int
 maciisi_write(struct adb_request* req)
 {
 	unsigned long flags;
+	int i;
 
-  	printk(KERN_DEBUG "maciisi_write called, state=%d ifr=%x\n", maciisi_state, via[IFR]);
 	/* We will accept CUDA packets - the VIA sends them to us, so
            it figures that we should be able to send them to it */
 	if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
@@ -225,7 +312,9 @@
 	req->sent = 0;
 	req->complete = 0;
 	req->reply_len = 0;
-	save_flags(flags); cli();
+	
+	save_flags(flags);
+	cli();
 
 	if (current_req) {
 		last_req->next = req;
@@ -235,44 +324,68 @@
 		last_req = req;
 	}
 	if (maciisi_state == idle)
-		maciisi_start();
+	{
+		i = maciisi_start();
+		if(i != 0)
+		{
+			restore_flags(flags);
+			return i;
+		}
+	}
 	else
+	{
+#ifdef DEBUG_MACIISI_ADB
 		printk(KERN_DEBUG "maciisi_write: would start, but state is %d\n", maciisi_state);
+#endif
+		restore_flags(flags);
+		return -EBUSY;
+	}
 
 	restore_flags(flags);
+
 	return 0;
 }
 
-static void
+static int
 maciisi_start(void)
 {
 	struct adb_request* req;
 	int status;
 
-	printk(KERN_DEBUG "maciisi_start called, state=%d, ifr=%x\n", maciisi_state, via[IFR]);
+#ifdef DEBUG_MACIISI_ADB
+	status = via[B] & (TIP | TREQ);
+
+	printk(KERN_DEBUG "maciisi_start called, state=%d, status=%x, ifr=%x\n", maciisi_state, status, via[IFR]);
+#endif
+
 	if (maciisi_state != idle) {
 		/* shouldn't happen */
 		printk(KERN_ERR "maciisi_start: maciisi_start called when driver busy!\n");
-		return;
+		return -EBUSY;
 	}
 
 	req = current_req;
 	if (req == NULL)
-		return;
+		return -EINVAL;
 
 	status = via[B] & (TIP|TREQ);
 	if (!(status & TREQ)) {
-		/* Bus is busy, set up for reading */
+#ifdef DEBUG_MACIISI_ADB
 		printk(KERN_DEBUG "maciisi_start: bus busy - aborting\n");
-		return;
+#endif
+		return -EBUSY;
 	}
 
 	/* Okay, send */
+#ifdef DEBUG_MACIISI_ADB
 	printk(KERN_DEBUG "maciisi_start: sending\n");
+#endif
 	/* Set state to active */
 	via[B] |= TIP;
 	/* ACK off */
 	via[B] &= ~TACK;
+	/* Delay */
+	udelay(ADB_DELAY);
 	/* Shift out and send */
 	via[ACR] |= SR_OUT;
 	via[SR] = req->data[0];
@@ -280,6 +393,8 @@
 	/* ACK on */
 	via[B] |= TACK;
 	maciisi_state = sending;
+
+	return 0;
 }
 
 void
@@ -292,6 +407,9 @@
 	if (via[IFR] & SR_INT) {
 		maciisi_interrupt(0, 0, 0);
 	}
+	else /* avoid calling this function too quickly in a loop */
+		udelay(ADB_DELAY);
+
 	restore_flags(flags);
 }
 
@@ -303,31 +421,44 @@
 {
 	int status;
 	struct adb_request *req;
-	static int dump_reply = 1;
+#ifdef DEBUG_MACIISI_ADB
+	static int dump_reply = 0;
+#endif
+	int i;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	status = via[B] & (TIP|TREQ);
+#ifdef DEBUG_MACIISI_ADB
+	printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);
+#endif
 
 	if (!(via[IFR] & SR_INT)) {
 		/* Shouldn't happen, we hope */
-		printk(KERN_DEBUG "maciisi_interrupt: called without interrupt flag set\n");
+		printk(KERN_ERR "maciisi_interrupt: called without interrupt flag set\n");
+		restore_flags(flags);
 		return;
 	}
 
-	status = via[B] & (TIP|TREQ);
-	printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);
+	/* Clear the interrupt */
+	/* via[IFR] = SR_INT; */
 
  switch_start:
 	switch (maciisi_state) {
 	case idle:
-		printk(KERN_DEBUG "maciisi_interrupt: state=idle, status %x\n", status);
 		if (status & TIP)
-			printk(KERN_DEBUG "maciisi_interrupt: state is idle but TIP asserted!\n");
+			printk(KERN_ERR "maciisi_interrupt: state is idle but TIP asserted!\n");
 
-		udelay(ADB_DELAY);
+		if(!reading_reply)
+			udelay(ADB_DELAY);
 		/* Shift in */
 		via[ACR] &= ~SR_OUT;
  		/* Signal start of frame */
 		via[B] |= TIP;
 		/* Clear the interrupt (throw this value on the floor, it's useless) */
-		via[SR];
+		tmp = via[SR];
 		/* ACK adb chip, high-low */
 		via[B] |= TACK;
 		udelay(ADB_DELAY);
@@ -337,37 +468,39 @@
 		if (reading_reply) {
 			reply_ptr = current_req->reply;
 		} else {
-			printk(KERN_DEBUG "maciisi_interrupt: received unsolicited packet\n");
 			reply_ptr = maciisi_rbuf;
 		}
 		break;
 
 	case sending:
-		printk(KERN_DEBUG "maciisi_interrupt: state=sending, status=%x\n", status);
-		/* Clear interrupt */
-		via[SR];
+		/* via[SR]; */
 		/* Set ACK off */
 		via[B] &= ~TACK;
 		req = current_req;
 
 		if (!(status & TREQ)) {
 			/* collision */
-			printk(KERN_DEBUG "maciisi_interrupt: send collision\n");
+			printk(KERN_ERR "maciisi_interrupt: send collision\n");
 			/* Set idle and input */
-			via[B] &= ~TIP;
 			via[ACR] &= ~SR_OUT;
+			tmp = via[SR];
+			via[B] &= ~TIP;
 			/* Must re-send */
 			reading_reply = 0;
 			reply_len = 0;
 			maciisi_state = idle;
+			udelay(ADB_DELAY);
 			/* process this now, because the IFR has been cleared */
 			goto switch_start;
 		}
 
+		udelay(ADB_DELAY);
+
 		if (data_index >= req->nbytes) {
 			/* Sent the whole packet, put the bus back in idle state */
 			/* Shift in, we are about to read a reply (hopefully) */
 			via[ACR] &= ~SR_OUT;
+			tmp = via[SR];
 			/* End of frame */
 			via[B] &= ~TIP;
 			req->sent = 1;
@@ -380,13 +513,19 @@
 				current_req = req->next;
 				if (req->done)
 					(*req->done)(req);
+				/* Do any queued requests now */
+				i = maciisi_start();
+				if(i == 0 && need_sync) {
+					/* Packet needs to be synced */
+					maciisi_sync(current_req);
+				}
+				if(i != -EBUSY)
+					need_sync = 0;
 			}
 		} else {
 			/* Sending more stuff */
 			/* Shift out */
 			via[ACR] |= SR_OUT;
-			/* Delay */
-			udelay(ADB_DELAY);
 			/* Write */
 			via[SR] = req->data[data_index++];
 			/* Signal 'byte ready' */
@@ -395,18 +534,24 @@
 		break;
 
 	case reading:
-		printk(KERN_DEBUG "maciisi_interrupt: state=reading, status=%x\n", status);
 		/* Shift in */
-		via[ACR] &= ~SR_OUT;
+		/* via[ACR] &= ~SR_OUT; */ /* Not in 2.2 */
 		if (reply_len++ > 16) {
 			printk(KERN_ERR "maciisi_interrupt: reply too long, aborting read\n");
 			via[B] |= TACK;
 			udelay(ADB_DELAY);
 			via[B] &= ~(TACK|TIP);
 			maciisi_state = idle;
-			maciisi_start();
+			i = maciisi_start();
+			if(i == 0 && need_sync) {
+				/* Packet needs to be synced */
+				maciisi_sync(current_req);
+			}
+			if(i != -EBUSY)
+				need_sync = 0;
 			break;
 		}
+		/* Read data */
 		*reply_ptr++ = via[SR];
 		status = via[B] & (TIP|TREQ);
 		/* ACK on/off */
@@ -418,6 +563,8 @@
 		
 		/* end of frame */
 		via[B] &= ~TIP;
+		tmp = via[SR]; /* That's what happens in 2.2 */
+		udelay(ADB_DELAY); /* Give controller time to recover */
 
 		/* end of packet, deal with it */
 		if (reading_reply) {
@@ -434,6 +581,7 @@
 					memmove(req->reply, req->reply + 2, req->reply_len);
 				}
 			}
+#ifdef DEBUG_MACIISI_ADB
 			if (dump_reply) {
 				int i;
 				printk(KERN_DEBUG "maciisi_interrupt: reply is ");
@@ -441,6 +589,7 @@
 					printk(" %.2x", req->reply[i]);
 				printk("\n");
 			}
+#endif
 			req->complete = 1;
 			current_req = req->next;
 			if (req->done)
@@ -453,34 +602,62 @@
 		maciisi_state = idle;
 		status = via[B] & (TIP|TREQ);
 		if (!(status & TREQ)) {
-			/* Timeout?! */
+			/* Timeout?! More likely, another packet coming in already */
+#ifdef DEBUG_MACIISI_ADB
 			printk(KERN_DEBUG "extra data after packet: status %x ifr %x\n",
 			       status, via[IFR]);
-			maciisi_stfu();
+#endif
+#if 0
+			udelay(ADB_DELAY);
+			via[B] |= TIP;
+
+			maciisi_state = reading;
+			reading_reply = 0;
+			reply_ptr = maciisi_rbuf;
+#else
+			/* Process the packet now */
+			reading_reply = 0;
+			goto switch_start;
+#endif
+			/* We used to do this... but the controller might actually have data for us */
+			/* maciisi_stfu(); */
+		}
+		else {
+			/* Do any queued requests now if possible */
+			i = maciisi_start();
+			if(i == 0 && need_sync) {
+				/* Packet needs to be synced */
+				maciisi_sync(current_req);
+			}
+			if(i != -EBUSY)
+				need_sync = 0;
 		}
-		/* Do any queued requests now if possible */
-		maciisi_start();
 		break;
 
 	default:
 		printk("maciisi_interrupt: unknown maciisi_state %d?\n", maciisi_state);
 	}
+	restore_flags(flags);
 }
 
 static void
 maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs)
 {
+#ifdef DEBUG_MACIISI_ADB
     int i;
+#endif
 
     switch (buf[0]) {
     case ADB_PACKET:
 	    adb_input(buf+2, nb-2, regs, buf[1] & 0x40);
 	    break;
     default:
+#ifdef DEBUG_MACIISI_ADB
 	    printk(KERN_DEBUG "data from IIsi ADB (%d bytes):", nb);
 	    for (i = 0; i < nb; ++i)
 		    printk(" %.2x", buf[i]);
 	    printk("\n");
-
+#endif
+	    break;
     }
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
--- linux.orig/drivers/macintosh/via-pmu.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/macintosh/via-pmu.c	2002-07-20 01:08:32.000000000 +0000
@@ -58,7 +58,9 @@
 /* Some compile options */
 #undef SUSPEND_USES_PMU
 #define DEBUG_SLEEP
+#undef VERBOSE_WAKEUP
 #undef HACKED_PCI_SAVE
+#define NEW_OHARE_CODE
 
 /* Misc minor number allocated for /dev/pmu */
 #define PMU_MINOR		154
@@ -151,6 +153,10 @@
 static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES];
 #endif /* CONFIG_PMAC_PBOOK */
 
+#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
+extern int disable_kernel_backlight;
+#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
+
 int __fake_sleep;
 int asleep;
 struct notifier_block *sleep_notifier_list;
@@ -544,6 +550,74 @@
 /* 
  * WARNING ! This code probably needs some debugging... -- BenH.
  */
+#ifdef NEW_OHARE_CODE
+static void __pmac
+done_battery_state_ohare(struct adb_request* req)
+{
+	unsigned int bat_flags = 0;
+	int current = 0;
+	unsigned int capa, max, voltage, time;
+	int lrange[] = { 0, 275, 850, 1680, 2325, 
+				2765, 3160, 3500, 3830, 4115, 
+				4360, 4585, 4795, 4990, 5170, 
+				5340, 5510, 5710, 5930, 6150, 
+				6370, 6500
+				};
+	
+	if (req->reply[0] & 0x01)
+		pmu_power_flags |= PMU_PWR_AC_PRESENT;
+	else
+		pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
+
+	if (req->reply[0] & 0x04) {
+		int vb, i, j, k, charge, pcharge;
+		bat_flags |= PMU_BATT_PRESENT;
+		vb = (req->reply[1] << 8) | req->reply[2];
+		voltage = ((vb * 2650) + 726650)/100;
+		vb *= 100;
+		current = req->reply[5];
+		if ((req->reply[0] & 0x01) == 0 && (current > 200))
+			vb += (current - 200) * 15;
+		else if (req->reply[0] & 0x02)
+			vb = (vb - 2000);
+	  	i = (33000 - vb) / 10;
+	  	j = i - (i % 100);
+		k = j/100;
+		if (k <= 0)
+	       		charge = 0;
+		else if (k >= 21)
+	       		charge = 650000;
+	  	else
+			charge = (lrange[k + 1] - lrange[k]) * (i - j) + (lrange[k] * 100);
+		charge = (1000 - charge / 650) / 10;
+		if (req->reply[0] & 0x40) {
+			pcharge = (req->reply[6] << 8) + req->reply[7];
+			if (pcharge > 6500)
+				pcharge = 6500;
+			pcharge *= 100;
+			pcharge = (1000 - pcharge / 650) / 10;
+			if (pcharge < charge)
+				charge = pcharge;
+		}
+		capa = charge;
+		max = 100;
+		time = (charge * 16440) / current;
+		current = -current;
+		
+	} else
+		capa = max = current = voltage = time = 0;
+
+	if (req->reply[0] & 0x02)
+		bat_flags |= PMU_BATT_CHARGING;
+
+	pmu_batteries[pmu_cur_battery].flags = bat_flags;
+	pmu_batteries[pmu_cur_battery].charge = capa;
+	pmu_batteries[pmu_cur_battery].max_charge = max;
+	pmu_batteries[pmu_cur_battery].current = current;
+	pmu_batteries[pmu_cur_battery].voltage = voltage;
+	pmu_batteries[pmu_cur_battery].time_remaining = time;
+}
+#else /* NEW_OHARE_CODE */
 static void __pmac
 done_battery_state_ohare(struct adb_request* req)
 {
@@ -610,6 +684,88 @@
 	pmu_batteries[pmu_cur_battery].voltage = voltage;
 	pmu_batteries[pmu_cur_battery].time_remaining = time;
 }
+#endif /* NEW_OHARE_CODE */
+
+ static void __pmac
+done_battery_state_comet(struct adb_request* req)
+{
+	/* format:
+	 *  [0]    :  flags
+	 *    0x01 :  AC indicator
+	 *    0x02 :  charging
+	 *    0x04 :  battery exist
+	 *    0x08 :  
+	 *    0x10 :  
+	 *    0x20 :  full charged
+	 *    0x40 :  pcharge reset
+	 *    0x80 :  battery exist
+	 *
+	 *  [1][2] :  battery voltage
+	 *  [3]    :  CPU temperature
+	 *  [4]    :  battery temperature
+	 *  [5]    :  current
+	 *  [6][7] :  pcharge
+	 *              --tkoba
+	 */
+
+	unsigned int bat_flags = 0;
+	int current = 0;
+	unsigned int max = 100;
+	unsigned int charge, voltage, time;
+	int lrange[] = { 0, 600, 750, 900, 1000, 1080, 
+				1180, 1250, 1300, 1340, 1360, 
+				1390, 1420, 1440, 1470, 1490, 
+				1520, 1550, 1580, 1610, 1650, 
+				1700
+				};
+	
+	if (req->reply[0] & 0x01)
+		pmu_power_flags |= PMU_PWR_AC_PRESENT;
+	else
+		pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
+
+	if (req->reply[0] & 0x04) {	/* battery exist */
+		int vb, i;
+		bat_flags |= PMU_BATT_PRESENT;
+		vb = (req->reply[1] << 8) | req->reply[2];
+		voltage = ((vb * 2650) + 726650)/100;
+		vb *= 10;
+		current = req->reply[5];
+		if ((req->reply[0] & 0x01) == 0 && (current > 200))
+			vb += ((current - 200) * 3);	/* vb = 500<->1800 */
+		else if (req->reply[0] & 0x02)
+			vb = ((vb - 800) * 1700/13)/100;	/*  in charging vb = 1300<->2130 */
+
+		if (req->reply[0] & 0x20) {	/* full charged */
+			charge = max;
+		} else {
+			if (lrange[21] < vb)
+				charge = max;
+			else {
+				if (vb < lrange[1])
+					charge = 0;
+				else {
+					for (i=21; vb < lrange[i]; --i);
+					charge = (i * 100)/21;
+				}
+			}
+			if (charge > max) charge = max;
+		}
+		time = (charge * 72);
+		current = -current;
+	} else
+		max = current = voltage = time = 0;
+
+	if (req->reply[0] & 0x02)
+		bat_flags |= PMU_BATT_CHARGING;
+
+	pmu_batteries[pmu_cur_battery].flags = bat_flags;
+	pmu_batteries[pmu_cur_battery].charge = charge;
+	pmu_batteries[pmu_cur_battery].max_charge = max;
+	pmu_batteries[pmu_cur_battery].current = current;
+	pmu_batteries[pmu_cur_battery].voltage = voltage;
+	pmu_batteries[pmu_cur_battery].time_remaining = time;
+}
 
 static void __pmac
 done_battery_state_smart(struct adb_request* req)
@@ -691,10 +847,17 @@
 {
 	if (!batt_req.complete)
 		return;
-	if (pmu_kind == PMU_OHARE_BASED)
-		pmu_request(&batt_req, done_battery_state_ohare,
-			1, PMU_BATTERY_STATE);
-	else
+	if (pmu_kind == PMU_OHARE_BASED) {
+		int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+			NULL, PMAC_MB_INFO_MODEL, 0);
+
+		if (mb == PMAC_TYPE_COMET)
+			pmu_request(&batt_req, done_battery_state_comet,
+				1, PMU_BATTERY_STATE);
+		else
+			pmu_request(&batt_req, done_battery_state_ohare,
+				1, PMU_BATTERY_STATE);
+	} else
 		pmu_request(&batt_req, done_battery_state_smart,
 			2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
 }
@@ -1372,8 +1535,11 @@
 		/* Sound/brightness button pressed */
 		if ((data[0] & PMU_INT_SNDBRT) && len == 3) {
 #ifdef CONFIG_PMAC_BACKLIGHT
-			set_backlight_level(data[1] >> 4);
-#endif
+#ifdef CONFIG_INPUT_ADBHID
+			if (!disable_kernel_backlight)
+#endif /* CONFIG_INPUT_ADBHID */
+				set_backlight_level(data[1] >> 4);
+#endif /* CONFIG_PMAC_BACKLIGHT */
 		}
 #ifdef CONFIG_PMAC_PBOOK
 		/* Environement or tick interrupt, query batteries */
@@ -1588,7 +1754,15 @@
 	for (list = sleep_notifiers.next; list != &sleep_notifiers;
 	     list = list->next) {
 		notifier = list_entry(list, struct pmu_sleep_notifier, list);
+#ifdef VERBOSE_WAKEUP
+		if (notifier->priority < SLEEP_LEVEL_VIDEO)
+			xmon_printf("wake, before notifier %x\n", notifier);		
+#endif
 		notifier->notifier_call(notifier, PBOOK_WAKE);
+#ifdef VERBOSE_WAKEUP
+		if (notifier->priority <= SLEEP_LEVEL_VIDEO)
+			xmon_printf("wake, after notifier %x\n", notifier);		
+#endif
 	}
 	return ret;
 }
@@ -1607,28 +1781,48 @@
 	u32	config[16];
 #endif	
 } *pbook_pci_saves;
-static int n_pbook_pci_saves;
+static int pbook_npci_saves;
 
 static void __openfirmware
-pbook_pci_save(void)
+pbook_alloc_pci_save(void)
 {
 	int npci;
 	struct pci_dev *pd;
-	struct pci_save *ps;
 
 	npci = 0;
 	pci_for_each_dev(pd) {
 		++npci;
 	}
-	n_pbook_pci_saves = npci;
 	if (npci == 0)
 		return;
-	ps = (struct pci_save *) kmalloc(npci * sizeof(*ps), GFP_KERNEL);
-	pbook_pci_saves = ps;
+	pbook_pci_saves = (struct pci_save *)
+		kmalloc(npci * sizeof(struct pci_save), GFP_KERNEL);
+	pbook_npci_saves = npci;
+}
+
+static void __openfirmware
+pbook_free_pci_save(void)
+{
+	if (pbook_pci_saves == NULL)
+		return;
+	kfree(pbook_pci_saves);
+	pbook_pci_saves = NULL;
+	pbook_npci_saves = 0;
+}
+
+static void __openfirmware
+pbook_pci_save(void)
+{
+	struct pci_save *ps = pbook_pci_saves;
+	struct pci_dev *pd;
+	int npci = pbook_npci_saves;
+	
 	if (ps == NULL)
 		return;
 
 	pci_for_each_dev(pd) {
+		if (npci-- == 0)
+			return;
 #ifndef HACKED_PCI_SAVE
 		pci_read_config_word(pd, PCI_COMMAND, &ps->command);
 		pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
@@ -1653,16 +1847,22 @@
 	u16 cmd;
 	struct pci_save *ps = pbook_pci_saves - 1;
 	struct pci_dev *pd;
+	int npci = pbook_npci_saves;
 	int j;
 
 	pci_for_each_dev(pd) {
 #ifdef HACKED_PCI_SAVE
 		int i;
+		if (npci-- == 0)
+			return;
 		ps++;
 		for (i=2;i<16;i++)
 			pci_write_config_dword(pd, i<<4, ps->config[i]);
 		pci_write_config_dword(pd, 4, ps->config[1]);
 #else
+		if (npci-- == 0)
+			return;
+		ps++;
 		if (ps->command == 0)
 			continue;
 		pci_read_config_word(pd, PCI_COMMAND, &cmd);
@@ -2115,9 +2315,13 @@
 	}
 	mem_ctrl_sleep = (unsigned int *) (mem_ctrl + PB3400_MEM_CTRL_SLEEP);
 
+	/* Allocate room for PCI save */
+	pbook_alloc_pci_save();
+
 	/* Notify device drivers */
 	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
 	if (ret != PBOOK_SLEEP_OK) {
+		pbook_free_pci_save();
 		printk("pmu: sleep rejected\n");
 		return -EBUSY;
 	}
@@ -2138,6 +2342,7 @@
 	ret = broadcast_sleep(PBOOK_SLEEP_NOW, PBOOK_WAKE);
 	if (ret != PBOOK_SLEEP_OK) {
 		printk("pmu: sleep failed\n");
+		pbook_free_pci_save();
 		return -EBUSY;
 	}
 
@@ -2211,6 +2416,7 @@
 	/* Notify drivers */
 	broadcast_wake();
 
+	pbook_free_pci_save();
 	iounmap(mem_ctrl);
 	return 0;
 }
@@ -2229,6 +2435,9 @@
 	}	rb_buf[RB_SIZE];
 	wait_queue_head_t wait;
 	spinlock_t lock;
+#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
+	int	backlight_locker;
+#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */	
 };
 
 static LIST_HEAD(all_pmu_pvt);
@@ -2274,9 +2483,13 @@
 	spin_lock_init(&pp->lock);
 	init_waitqueue_head(&pp->wait);
 	spin_lock_irqsave(&all_pvt_lock, flags);
+#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
+	pp->backlight_locker = 0;
+#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */	
 	list_add(&pp->list, &all_pmu_pvt);
 	spin_unlock_irqrestore(&all_pvt_lock, flags);
 	file->private_data = pp;
+	
 	return 0;
 }
 
@@ -2365,6 +2578,13 @@
 		spin_lock_irqsave(&all_pvt_lock, flags);
 		list_del(&pp->list);
 		spin_unlock_irqrestore(&all_pvt_lock, flags);
+#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
+		if (pp->backlight_locker) {
+			spin_lock_irqsave(&pmu_lock, flags);
+			disable_kernel_backlight--;
+			spin_unlock_irqrestore(&pmu_lock, flags);
+		}
+#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
 		kfree(pp);
 	}
 	unlock_kernel();
@@ -2375,6 +2595,7 @@
 static int pmu_ioctl(struct inode * inode, struct file *filp,
 		     u_int cmd, u_long arg)
 {
+	struct pmu_private *pp = filp->private_data;
 	int error;
 
 	switch (cmd) {
@@ -2424,6 +2645,18 @@
 			error = set_backlight_level(value);
 		return error;
 	}
+#ifdef CONFIG_INPUT_ADBHID
+	case PMU_IOC_GRAB_BACKLIGHT: {
+		unsigned long flags;
+		if (pp->backlight_locker)
+			return 0;
+		pp->backlight_locker = 1;
+		spin_lock_irqsave(&pmu_lock, flags);
+		disable_kernel_backlight++;
+		spin_unlock_irqrestore(&pmu_lock, flags);
+		return 0;
+	}
+#endif /* CONFIG_INPUT_ADBHID */
 #endif /* CONFIG_PMAC_BACKLIGHT */
 	case PMU_IOC_GET_MODEL:
 	    	return put_user(pmu_kind, (__u32 *)arg);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/md/lvm-fs.c linux/drivers/md/lvm-fs.c
--- linux.orig/drivers/md/lvm-fs.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/md/lvm-fs.c	2002-07-20 01:08:24.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2001 Sistina Software
  *
- * January,February 2001
+ * January-April 2001
  *
  * LVM driver is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,7 +36,6 @@
 
 #include <linux/config.h>
 #include <linux/version.h>
-#include <linux/module.h>
 
 #include <linux/kernel.h>
 #include <linux/vmalloc.h>
@@ -65,7 +64,9 @@
 
 static void _show_uuid(const char *src, char *b, char *e);
 
+#if 0
 static devfs_handle_t lvm_devfs_handle;
+#endif
 static devfs_handle_t vg_devfs_handle[MAX_VG];
 static devfs_handle_t ch_devfs_handle[MAX_VG];
 static devfs_handle_t lv_devfs_handle[MAX_LV];
@@ -79,12 +80,13 @@
 void __init lvm_init_fs() {
 	struct proc_dir_entry *pde;
 
-	/*  Must create device node. Think about "devfs=only" situation  */
+/* User-space has already registered this */
+#if 0
 	lvm_devfs_handle = devfs_register(
 		0 , "lvm", 0, LVM_CHAR_MAJOR, 0,
 		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
 		&lvm_chr_fops, NULL);
-
+#endif
 	lvm_proc_dir = create_proc_entry(LVM_DIR, S_IFDIR, &proc_root);
 	if (lvm_proc_dir) {
 		lvm_proc_vg_subdir = create_proc_entry(LVM_VG_SUBDIR, S_IFDIR,
@@ -95,8 +97,9 @@
 }
 
 void lvm_fin_fs() {
+#if 0
 	devfs_unregister (lvm_devfs_handle);
-
+#endif
 	remove_proc_entry(LVM_GLOBAL, lvm_proc_dir);
 	remove_proc_entry(LVM_VG_SUBDIR, lvm_proc_dir);
 	remove_proc_entry(LVM_DIR, &proc_root);
@@ -135,13 +138,14 @@
 	devfs_unregister(ch_devfs_handle[vg_ptr->vg_number]);
 	ch_devfs_handle[vg_ptr->vg_number] = NULL;
 
+	/* remove pv's */
+	for(i = 0; i < vg_ptr->pv_max; i++)
+		if(vg_ptr->pv[i]) lvm_fs_remove_pv(vg_ptr, vg_ptr->pv[i]);
+
 	/* remove lv's */
 	for(i = 0; i < vg_ptr->lv_max; i++)
 		if(vg_ptr->lv[i]) lvm_fs_remove_lv(vg_ptr, vg_ptr->lv[i]);
 
-	/* remove pv's */
-	for(i = 0; i < vg_ptr->pv_max; i++)
-		if(vg_ptr->pv[i]) lvm_fs_remove_pv(vg_ptr, vg_ptr->pv[i]);
 
 	/* must not remove directory before leaf nodes */
 	devfs_unregister(vg_devfs_handle[vg_ptr->vg_number]);
@@ -276,12 +280,12 @@
 	sz += sprintf(page + sz, "number:       %u\n", lv->lv_number);
 	sz += sprintf(page + sz, "open:         %u\n", lv->lv_open);
 	sz += sprintf(page + sz, "allocation:   %u\n", lv->lv_allocation);
-       if(lv->lv_stripes > 1) {
-               sz += sprintf(page + sz, "stripes:      %u\n",
-                             lv->lv_stripes);
-               sz += sprintf(page + sz, "stripesize:   %u\n",
-                             lv->lv_stripesize);
-       }
+	if(lv->lv_stripes > 1) {
+		sz += sprintf(page + sz, "stripes:      %u\n",
+			      lv->lv_stripes);
+		sz += sprintf(page + sz, "stripesize:   %u\n",
+			      lv->lv_stripesize);
+	}
 	sz += sprintf(page + sz, "device:       %02u:%02u\n",
 		      MAJOR(lv->lv_dev), MINOR(lv->lv_dev));
 
@@ -620,4 +624,3 @@
 	}
 	*b = '\0';
 }
-MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/md/lvm-internal.h linux/drivers/md/lvm-internal.h
--- linux.orig/drivers/md/lvm-internal.h	2001-11-11 18:09:32.000000000 +0000
+++ linux/drivers/md/lvm-internal.h	2002-07-20 01:08:33.000000000 +0000
@@ -1,5 +1,6 @@
+
 /*
- * kernel/lvm-internal.h
+ * kernel/lvm_internal.h
  *
  * Copyright (C) 2001 Sistina Software
  *
@@ -24,7 +25,9 @@
 /*
  * Changelog
  *
- *    05/01/2001:Joe Thornber - Factored this file out of lvm.c
+ *    05/01/2001 - Factored this file out of lvm.c (Joe Thornber)
+ *    11/01/2001 - Renamed lvm_internal and added declarations
+ *                 for lvm_fs.c stuff
  *
  */
 
@@ -33,7 +36,7 @@
 
 #include <linux/lvm.h>
 
-#define _LVM_INTERNAL_H_VERSION "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
+#define	_LVM_INTERNAL_H_VERSION	"LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
 
 /* global variables, defined in lvm.c */
 extern char *lvm_version;
@@ -42,11 +45,15 @@
 extern const char *const lvm_name;
 
 
+extern uint vg_count;
 extern vg_t *vg[];
 extern struct file_operations lvm_chr_fops;
 
 extern struct block_device_operations lvm_blk_dops;
 
+#define lvm_sectsize(dev) get_hardsect_size(dev)
+
+/* 2.4.8 had no global min/max macros, and 2.4.9's were flawed */
 
 /* debug macros */
 #ifdef DEBUG_IOCTL
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/md/lvm-snap.c linux/drivers/md/lvm-snap.c
--- linux.orig/drivers/md/lvm-snap.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/md/lvm-snap.c	2002-07-20 01:08:38.000000000 +0000
@@ -2,22 +2,22 @@
  * kernel/lvm-snap.c
  *
  * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
- *                    Heinz Mauelshagen, Sistina Software (persistent snapshots)
+ *               2000 - 2001 Heinz Mauelshagen, Sistina Software
  *
  * LVM snapshot driver 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, or (at your option)
  * any later version.
- * 
+ *
  * LVM snapshot driver 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA. 
+ * Boston, MA 02111-1307, USA.
  *
  */
 
@@ -28,52 +28,66 @@
  *    23/11/2000 - used cpu_to_le64 rather than my own macro
  *    25/01/2001 - Put LockPage back in
  *    01/02/2001 - A dropped snapshot is now set as inactive
+ *    14/02/2001 - tidied debug statements
+ *    19/02/2001 - changed rawio calls to pass in preallocated buffer_heads
+ *    26/02/2001 - introduced __brw_kiovec to remove a lot of conditional
+ *                 compiles.
+ *    07/03/2001 - fixed COW exception table not persistent on 2.2 (HM)
  *    12/03/2001 - lvm_pv_get_number changes:
  *                 o made it static
  *                 o renamed it to _pv_get_number
  *                 o pv number is returned in new uint * arg
  *                 o -1 returned on error
  *                 lvm_snapshot_fill_COW_table has a return value too.
+ *    15/10/2001 - fix snapshot alignment problem [CM]
+ *               - fix snapshot full oops (always check lv_block_exception) [CM]
  *
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/blkdev.h>
 #include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/iobuf.h>
 #include <linux/lvm.h>
+#include <linux/devfs_fs_kernel.h>
 
 
 #include "lvm-internal.h"
 
-static char *lvm_snap_version __attribute__ ((unused)) =
-   "LVM "LVM_RELEASE_NAME" snapshot code ("LVM_RELEASE_DATE")\n";
+static char *lvm_snap_version __attribute__ ((unused)) = "LVM "LVM_RELEASE_NAME" snapshot code ("LVM_RELEASE_DATE")\n";
 
 
 extern const char *const lvm_name;
 extern int lvm_blocksizes[];
 
 void lvm_snapshot_release(lv_t *);
+
 static int _write_COW_table_block(vg_t *vg, lv_t *lv, int idx,
-                                 const char **reason);
+				  const char **reason);
 static void _disable_snapshot(vg_t *vg, lv_t *lv);
 
 
-static int _pv_get_number(vg_t * vg, kdev_t rdev, uint *pvn) {
+static inline int __brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
+			       kdev_t dev, unsigned long b[], int size,
+			       lv_t *lv) {
+	return brw_kiovec(rw, nr, iovec, dev, b, size);
+}
+
+
+static int _pv_get_number(vg_t * vg, kdev_t rdev, uint *pvn)
+{
 	uint p;
-	for(p = 0; p < vg->pv_max; p++) {
-		if(vg->pv[p] == NULL)
+	for (p = 0; p < vg->pv_max; p++) {
+		if (vg->pv[p] == NULL)
 			continue;
 
-		if(vg->pv[p]->pv_dev == rdev)
+		if (vg->pv[p]->pv_dev == rdev)
 			break;
-
 	}
 
- 	if(p >= vg->pv_max) {
+	if (p >= vg->pv_max) {
 		/* bad news, the snapshot COW table is probably corrupt */
 		printk(KERN_ERR
 		       "%s -- _pv_get_number failed for rdev = %u\n",
@@ -85,6 +99,7 @@
 	return 0;
 }
 
+
 #define hashfn(dev,block,mask,chunk_size) \
 	((HASHDEV(dev)^((block)/(chunk_size))) & (mask))
 
@@ -129,10 +144,20 @@
 	unsigned long mask = lv->lv_snapshot_hash_mask;
 	int chunk_size = lv->lv_chunk_size;
 
+	if (!hash_table)
+		BUG();
 	hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)];
 	list_add(&exception->hash, hash_table);
 }
 
+/*
+ * Determine if we already have a snapshot chunk for this block.
+ * Return: 1 if it the chunk already exists
+ *         0 if we need to COW this block and allocate a new chunk
+ *        -1 if the snapshot was disabled because it ran out of space
+ *
+ * We need to be holding at least a read lock on lv->lv_lock.
+ */
 int lvm_snapshot_remap_block(kdev_t * org_dev, unsigned long * org_sector,
 			     unsigned long pe_start, lv_t * lv)
 {
@@ -142,6 +167,9 @@
 	int chunk_size = lv->lv_chunk_size;
 	lv_block_exception_t * exception;
 
+	if (!lv->lv_block_exception)
+		return -1;
+
 	pe_off = pe_start % chunk_size;
 	pe_adjustment = (*org_sector-pe_off) % chunk_size;
 	__org_start = *org_sector - pe_adjustment;
@@ -166,8 +194,8 @@
 	   or error on this snapshot --> release it */
 	invalidate_buffers(lv_snap->lv_dev);
 
-       /* wipe the snapshot since it's inconsistent now */
-       _disable_snapshot(vg, lv_snap);
+	/* wipe the snapshot since it's inconsistent now */
+	_disable_snapshot(vg, lv_snap);
 
 	for (i = last_dev = 0; i < lv_snap->lv_remap_ptr; i++) {
 		if ( lv_snap->lv_block_exception[i].rdev_new != last_dev) {
@@ -186,15 +214,15 @@
 }
 
 static inline int lvm_snapshot_prepare_blocks(unsigned long *blocks,
-					      unsigned long start,
-					      int nr_sectors,
-					      int blocksize)
+					       unsigned long start,
+					       int nr_sectors,
+					       int blocksize)
 {
 	int i, sectors_per_block, nr_blocks;
 
 	sectors_per_block = blocksize / SECTOR_SIZE;
 
-	if(start & (sectors_per_block - 1))
+	if (start & (sectors_per_block - 1))
 		return 0;
 
 	nr_blocks = nr_sectors / sectors_per_block;
@@ -245,49 +273,51 @@
 
 int lvm_snapshot_fill_COW_page(vg_t * vg, lv_t * lv_snap)
 {
-       uint pvn;
-       int id = 0, is = lv_snap->lv_remap_ptr;
-       ulong blksize_snap;
-       lv_COW_table_disk_t * lv_COW_table = (lv_COW_table_disk_t *)
-               page_address(lv_snap->lv_COW_table_iobuf->maplist[0]);
+	int id = 0, is = lv_snap->lv_remap_ptr;
+	ulong blksize_snap;
+	lv_COW_table_disk_t * lv_COW_table = (lv_COW_table_disk_t *)
+		page_address(lv_snap->lv_COW_table_iobuf->maplist[0]);
 
-       if (is == 0)
-               return 0;
+	if (is == 0)
+		return 0;
 
 	is--;
-        blksize_snap =
-               lvm_get_blksize(lv_snap->lv_block_exception[is].rdev_new);
-        is -= is % (blksize_snap / sizeof(lv_COW_table_disk_t));
+	blksize_snap =
+		lvm_get_blksize(lv_snap->lv_block_exception[is].rdev_new);
+	is -= is % (blksize_snap / sizeof(lv_COW_table_disk_t));
 
 	memset(lv_COW_table, 0, blksize_snap);
 	for ( ; is < lv_snap->lv_remap_ptr; is++, id++) {
 		/* store new COW_table entry */
-               lv_block_exception_t *be = lv_snap->lv_block_exception + is;
-               if(_pv_get_number(vg, be->rdev_org, &pvn))
-                       goto bad;
+		lv_block_exception_t *be = lv_snap->lv_block_exception + is;
+		uint pvn;
 
-               lv_COW_table[id].pv_org_number = cpu_to_le64(pvn);
-               lv_COW_table[id].pv_org_rsector = cpu_to_le64(be->rsector_org);
-               if(_pv_get_number(vg, be->rdev_new, &pvn))
-                       goto bad;
+		if (_pv_get_number(vg, be->rdev_org, &pvn))
+			goto bad;
 
-               lv_COW_table[id].pv_snap_number = cpu_to_le64(pvn);
-               lv_COW_table[id].pv_snap_rsector =
-                       cpu_to_le64(be->rsector_new);
+		lv_COW_table[id].pv_org_number = cpu_to_le64(pvn);
+		lv_COW_table[id].pv_org_rsector = cpu_to_le64(be->rsector_org);
+
+		if (_pv_get_number(vg, be->rdev_new, &pvn))
+			goto bad;
+
+		lv_COW_table[id].pv_snap_number = cpu_to_le64(pvn);
+		lv_COW_table[id].pv_snap_rsector = cpu_to_le64(be->rsector_new);
 	}
 
-       return 0;
+	return 0;
 
  bad:
-       printk(KERN_ERR "%s -- lvm_snapshot_fill_COW_page failed", lvm_name);
-       return -1;
+	printk(KERN_ERR "%s -- lvm_snapshot_fill_COW_page failed", lvm_name);
+	return -1;
 }
 
 
 /*
  * writes a COW exception table sector to disk (HM)
+ *
+ * We need to hold a write lock on lv_snap->lv_lock.
  */
-
 int lvm_write_COW_table_block(vg_t * vg, lv_t *lv_snap)
 {
 	int r;
@@ -305,6 +335,10 @@
  * if there is no exception storage space free any longer --> release snapshot.
  *
  * this routine gets called for each _first_ write to a physical chunk.
+ *
+ * We need to hold a write lock on lv_snap->lv_lock.  It is assumed that
+ * lv->lv_block_exception is non-NULL (checked by lvm_snapshot_remap_block())
+ * when this function is called.
  */
 int lvm_snapshot_COW(kdev_t org_phys_dev,
 		     unsigned long org_phys_sector,
@@ -314,8 +348,10 @@
 {
 	const char * reason;
 	unsigned long org_start, snap_start, snap_phys_dev, virt_start, pe_off;
+	unsigned long phys_start;
 	int idx = lv_snap->lv_remap_ptr, chunk_size = lv_snap->lv_chunk_size;
-	struct kiobuf * iobuf;
+	struct kiobuf * iobuf = lv_snap->lv_iobuf;
+	unsigned long *blocks = iobuf->blocks;
 	int blksize_snap, blksize_org, min_blksize, max_blksize;
 	int max_sectors, nr_sectors;
 
@@ -345,10 +381,8 @@
 	       org_virt_sector);
 #endif
 
-	iobuf = lv_snap->lv_iobuf;
-
-	blksize_org = lvm_get_blksize(org_phys_dev);
-	blksize_snap = lvm_get_blksize(snap_phys_dev);
+	blksize_org = lvm_sectsize(org_phys_dev);
+	blksize_snap = lvm_sectsize(snap_phys_dev);
 	max_blksize = max(blksize_org, blksize_snap);
 	min_blksize = min(blksize_org, blksize_snap);
 	max_sectors = KIO_MAX_SECTORS * (min_blksize>>9);
@@ -356,6 +390,9 @@
 	if (chunk_size % (max_blksize>>9))
 		goto fail_blksize;
 
+	/* Don't change org_start, we need it to fill in the exception table */
+	phys_start = org_start;
+
 	while (chunk_size)
 	{
 		nr_sectors = min(chunk_size, max_sectors);
@@ -363,21 +400,24 @@
 
 		iobuf->length = nr_sectors << 9;
 
-		if(!lvm_snapshot_prepare_blocks(iobuf->blocks, org_start,
-						nr_sectors, blksize_org))
+		if (!lvm_snapshot_prepare_blocks(blocks, phys_start,
+						 nr_sectors, blksize_org))
 			goto fail_prepare;
 
-		if (brw_kiovec(READ, 1, &iobuf, org_phys_dev,
-			       iobuf->blocks, blksize_org) != (nr_sectors<<9))
+		if (__brw_kiovec(READ, 1, &iobuf, org_phys_dev, blocks,
+				 blksize_org, lv_snap) != (nr_sectors<<9))
 			goto fail_raw_read;
 
-		if(!lvm_snapshot_prepare_blocks(iobuf->blocks, snap_start,
-						nr_sectors, blksize_snap))
+		if (!lvm_snapshot_prepare_blocks(blocks, snap_start,
+						 nr_sectors, blksize_snap))
 			goto fail_prepare;
 
-		if (brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev,
-			       iobuf->blocks, blksize_snap) != (nr_sectors<<9))
+		if (__brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev, blocks,
+				 blksize_snap, lv_snap) != (nr_sectors<<9))
 			goto fail_raw_write;
+
+		phys_start += nr_sectors;
+		snap_start += nr_sectors;
 	}
 
 #ifdef DEBUG_SNAPSHOT
@@ -401,24 +441,24 @@
 	return 0;
 
 	/* slow path */
- out:
+out:
 	lvm_drop_snapshot(vg, lv_snap, reason);
 	return 1;
 
- fail_out_of_space:
+fail_out_of_space:
 	reason = "out of space";
 	goto out;
- fail_raw_read:
+fail_raw_read:
 	reason = "read error";
 	goto out;
- fail_raw_write:
+fail_raw_write:
 	reason = "write error";
 	goto out;
- fail_blksize:
+fail_blksize:
 	reason = "blocksize error";
 	goto out;
 
- fail_prepare:
+fail_prepare:
 	reason = "couldn't prepare kiovec blocks "
 		"(start probably isn't block aligned)";
 	goto out;
@@ -441,8 +481,7 @@
 		struct page * page;
 
 		page = alloc_page(GFP_KERNEL);
-		if (!page)
-			goto out;
+		if (!page) goto out;
 
 		iobuf->maplist[i] = page;
 		LockPage(page);
@@ -451,7 +490,8 @@
 	iobuf->offset = 0;
 
 	err = 0;
- out:
+
+out:
 	return err;
 }
 
@@ -515,13 +555,12 @@
 	if (ret) goto out_free_kiovec;
 
 	ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_COW_table_iobuf,
-                                            PAGE_SIZE/SECTOR_SIZE);
+					     PAGE_SIZE/SECTOR_SIZE);
 	if (ret) goto out_free_both_kiovecs;
 
 	ret = lvm_snapshot_alloc_hash_table(lv_snap);
 	if (ret) goto out_free_both_kiovecs;
 
-
 out:
 	return ret;
 
@@ -534,8 +573,7 @@
 	unmap_kiobuf(lv_snap->lv_iobuf);
 	free_kiovec(1, &lv_snap->lv_iobuf);
 	lv_snap->lv_iobuf = NULL;
-	if (lv_snap->lv_snapshot_hash_table != NULL)
-		vfree(lv_snap->lv_snapshot_hash_table);
+	vfree(lv_snap->lv_snapshot_hash_table);
 	lv_snap->lv_snapshot_hash_table = NULL;
 	goto out;
 }
@@ -562,10 +600,10 @@
 	}
 	if (lv->lv_COW_table_iobuf)
 	{
-               kiobuf_wait_for_io(lv->lv_COW_table_iobuf);
-               unmap_kiobuf(lv->lv_COW_table_iobuf);
-               free_kiovec(1, &lv->lv_COW_table_iobuf);
-               lv->lv_COW_table_iobuf = NULL;
+	        kiobuf_wait_for_io(lv->lv_COW_table_iobuf);
+		unmap_kiobuf(lv->lv_COW_table_iobuf);
+		free_kiovec(1, &lv->lv_COW_table_iobuf);
+		lv->lv_COW_table_iobuf = NULL;
 	}
 }
 
@@ -577,11 +615,11 @@
 	int idx_COW_table;
 	uint pvn;
 	ulong snap_pe_start, COW_table_sector_offset,
-		COW_entries_per_pe, COW_chunks_per_pe, COW_entries_per_block;
+	      COW_entries_per_pe, COW_chunks_per_pe, COW_entries_per_block;
 	ulong blocks[1];
 	kdev_t snap_phys_dev;
 	lv_block_exception_t *be;
-	struct kiobuf * COW_table_iobuf = lv_snap->lv_COW_table_iobuf;
+	struct kiobuf *COW_table_iobuf = lv_snap->lv_COW_table_iobuf;
 	lv_COW_table_disk_t * lv_COW_table =
 	   ( lv_COW_table_disk_t *) page_address(lv_snap->lv_COW_table_iobuf->maplist[0]);
 
@@ -592,46 +630,47 @@
 	snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
 	snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size;
 
-	blksize_snap = lvm_get_blksize(snap_phys_dev);
+	blksize_snap = lvm_sectsize(snap_phys_dev);
 
         COW_entries_per_block = blksize_snap / sizeof(lv_COW_table_disk_t);
         idx_COW_table = idx % COW_entries_per_pe % COW_entries_per_block;
 
 	if ( idx_COW_table == 0) memset(lv_COW_table, 0, blksize_snap);
 
-       /* sector offset into the on disk COW table */
+	/* sector offset into the on disk COW table */
 	COW_table_sector_offset = (idx % COW_entries_per_pe) / (SECTOR_SIZE / sizeof(lv_COW_table_disk_t));
 
         /* COW table block to write next */
 	blocks[0] = (snap_pe_start + COW_table_sector_offset) >> (blksize_snap >> 10);
 
 	/* store new COW_table entry */
-       be = lv_snap->lv_block_exception + idx;
-       if(_pv_get_number(vg, be->rdev_org, &pvn))
-               goto fail_pv_get_number;
-
-       lv_COW_table[idx_COW_table].pv_org_number = cpu_to_le64(pvn);
-       lv_COW_table[idx_COW_table].pv_org_rsector =
-               cpu_to_le64(be->rsector_org);
-       if(_pv_get_number(vg, snap_phys_dev, &pvn))
-               goto fail_pv_get_number;
-
-       lv_COW_table[idx_COW_table].pv_snap_number = cpu_to_le64(pvn);
-       lv_COW_table[idx_COW_table].pv_snap_rsector =
-               cpu_to_le64(be->rsector_new);
+	be = lv_snap->lv_block_exception + idx;
+	if(_pv_get_number(vg, be->rdev_org, &pvn))
+		goto fail_pv_get_number;
+
+	lv_COW_table[idx_COW_table].pv_org_number = cpu_to_le64(pvn);
+	lv_COW_table[idx_COW_table].pv_org_rsector =
+		cpu_to_le64(be->rsector_org);
+	if(_pv_get_number(vg, snap_phys_dev, &pvn))
+		goto fail_pv_get_number;
+
+	lv_COW_table[idx_COW_table].pv_snap_number = cpu_to_le64(pvn);
+	lv_COW_table[idx_COW_table].pv_snap_rsector =
+		cpu_to_le64(be->rsector_new);
 
 	COW_table_iobuf->length = blksize_snap;
+	/* COW_table_iobuf->nr_pages = 1; */
 
-	if (brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
-		       blocks, blksize_snap) != blksize_snap)
+	if (__brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
+			 blocks, blksize_snap, lv_snap) != blksize_snap)
 		goto fail_raw_write;
 
-       /* initialization of next COW exception table block with zeroes */
+	/* initialization of next COW exception table block with zeroes */
 	end_of_table = idx % COW_entries_per_pe == COW_entries_per_pe - 1;
 	if (idx_COW_table % COW_entries_per_block == COW_entries_per_block - 1 || end_of_table)
 	{
 		/* don't go beyond the end */
-               if (idx + 1 >= lv_snap->lv_remap_end) goto out;
+		if (idx + 1 >= lv_snap->lv_remap_end) goto out;
 
 		memset(lv_COW_table, 0, blksize_snap);
 
@@ -640,24 +679,24 @@
 			idx++;
 			snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
 			snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size;
-			blksize_snap = lvm_get_blksize(snap_phys_dev);
+			blksize_snap = lvm_sectsize(snap_phys_dev);
 			blocks[0] = snap_pe_start >> (blksize_snap >> 10);
 		} else blocks[0]++;
 
-               if (brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
-                                 blocks, blksize_snap) !=
+		if (__brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
+                                 blocks, blksize_snap, lv_snap) !=
                     blksize_snap)
 			goto fail_raw_write;
 	}
 
- out:
+out:
 	return 0;
 
- fail_raw_write:
+fail_raw_write:
 	*reason = "write error";
 	return 1;
 
- fail_pv_get_number:
+fail_pv_get_number:
 	*reason = "_pv_get_number failed";
 	return 1;
 }
@@ -681,5 +720,3 @@
 		       lvm_name, err);
 	}
 }
-
-MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/md/lvm.c linux/drivers/md/lvm.c
--- linux.orig/drivers/md/lvm.c	2001-11-19 17:56:04.000000000 +0000
+++ linux/drivers/md/lvm.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,13 +1,13 @@
 /*
  * kernel/lvm.c
  *
- * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
+ * Copyright (C) 1997 - 2001  Heinz Mauelshagen, Sistina Software
  *
  * February-November 1997
  * April-May,July-August,November 1998
  * January-March,May,July,September,October 1999
  * January,February,July,September-November 2000
- * January 2001
+ * January-April 2001
  *
  *
  * LVM driver is free software; you can redistribute it and/or modify
@@ -43,7 +43,8 @@
  *                 support for free (eg. longer) logical volume names
  *    12/05/1998 - added spin_locks (thanks to Pascal van Dam
  *                 <pascal@ramoth.xs4all.nl>)
- *    25/05/1998 - fixed handling of locked PEs in lvm_map() and lvm_chr_ioctl()
+ *    25/05/1998 - fixed handling of locked PEs in lvm_map() and
+ *                 lvm_chr_ioctl()
  *    26/05/1998 - reactivated verify_area by access_ok
  *    07/06/1998 - used vmalloc/vfree instead of kmalloc/kfree to go
  *                 beyond 128/256 KB max allocation limit per call
@@ -125,7 +126,8 @@
  *    14/02/2000 - support for 2.3.43
  *               - integrated Andrea Arcagneli's snapshot code
  *    25/06/2000 - james (chip) , IKKHAYD! roffl
- *    26/06/2000 - enhanced lv_extend_reduce for snapshot logical volume support
+ *    26/06/2000 - enhanced lv_extend_reduce for snapshot logical volume
+ *                 support
  *    06/09/2000 - added devfs support
  *    07/09/2000 - changed IOP version to 9
  *               - started to add new char ioctl LV_STATUS_BYDEV_T to support
@@ -147,15 +149,24 @@
  *    08/01/2001 - Removed conditional compiles related to PROC_FS,
  *                 procfs is always supported now. (JT)
  *    12/01/2001 - avoided flushing logical volume in case of shrinking
- *                 because of unnecessary overhead in case of heavy updates
+ *                 because of unecessary overhead in case of heavy updates
  *    25/01/2001 - Allow RO open of an inactive LV so it can be reactivated.
- *    31/01/2001 - If you try and BMAP a snapshot you now get an -EPERM
- *    01/02/2001 - factored __remap_snapshot out of lvm_map
+ *    31/01/2001 - removed blk_init_queue/blk_cleanup_queue queueing will be
+ *                 handled by the proper devices.
+ *               - If you try and BMAP a snapshot you now get an -EPERM
+ *    01/01/2001 - lvm_map() now calls buffer_IO_error on error for 2.4
+ *               - factored __remap_snapshot out of lvm_map
  *    12/02/2001 - move devfs code to create VG before LVs
- *    14/02/2001 - tidied device defines for blk.h
+ *    13/02/2001 - allow VG_CREATE on /dev/lvm
+ *    14/02/2001 - removed modversions.h
+ *               - tidied device defines for blk.h
  *               - tidied debug statements
+ *               - bug: vg[] member not set back to NULL if activation fails
  *               - more lvm_map tidying
- *    14/02/2001 - bug: vg[] member not set back to NULL if activation fails
+ *    15/02/2001 - register /dev/lvm with devfs correctly (major/minor
+ *                 were swapped)
+ *    19/02/2001 - preallocated buffer_heads for rawio when using
+ *                 snapshots [JT]
  *    28/02/2001 - introduced the P_DEV macro and changed some internel
  *                 functions to be static [AD]
  *    28/02/2001 - factored lvm_get_snapshot_use_rate out of blk_ioctl [AD]
@@ -163,25 +174,50 @@
  *                 where the check for an existing LV takes place right at
  *                 the beginning
  *    01/03/2001 - Add VG_CREATE_OLD for IOP 10 compatibility
- *    02/03/2001 - Don't destroy usermode pointers in lv_t structures duing LV_
- *                 STATUS_BYxxx and remove redundant lv_t variables from same.
+ *    02/03/2001 - Don't destroy usermode pointers in lv_t structures duing
+ *                 LV_STATUS_BYxxx
+ *                 and remove redundant lv_t variables from same.
+ *               - avoid compilation of lvm_dummy_device_request in case of
+ *                 Linux >= 2.3.0 to avoid a warning
+ *               - added lvm_name argument to printk in buffer allocation
+ *                 in order to avoid a warning
+ *    04/03/2001 - moved linux/version.h above first use of KERNEL_VERSION
+ *                 macros
  *    05/03/2001 - restore copying pe_t array in lvm_do_lv_status_byname. For
  *                 lvdisplay -v (PC)
  *               - restore copying pe_t array in lvm_do_lv_status_byindex (HM)
  *               - added copying pe_t array in lvm_do_lv_status_bydev (HM)
  *               - enhanced lvm_do_lv_status_by{name,index,dev} to be capable
  *                 to copy the lv_block_exception_t array to userspace (HM)
- *    08/03/2001 - factored lvm_do_pv_flush out of lvm_chr_ioctl [HM]
+ *    08/03/2001 - initialize new lv_ptr->lv_COW_table_iobuf for snapshots;
+ *                 removed obsolete lv_ptr->lv_COW_table_page initialization
+ *               - factored lvm_do_pv_flush out of lvm_chr_ioctl (HM)
  *    09/03/2001 - Added _lock_open_count to ensure we only drop the lock
  *                 when the locking process closes.
- *    05/04/2001 - lvm_map bugs: don't use b_blocknr/b_dev in lvm_map, it
- *		   destroys stacking devices. call b_end_io on failed maps.
- *		   (Jens Axboe)
- *               - Defer writes to an extent that is being moved [JT + AD]
- *    28/05/2001 - implemented missing BLKSSZGET ioctl [AD]
+ *    05/04/2001 - Defer writes to an extent that is being moved [JT]
+ *    05/04/2001 - use b_rdev and b_rsector rather than b_dev and b_blocknr in
+ *                 lvm_map() in order to make stacking devices more happy (HM)
+ *    11/04/2001 - cleaned up the pvmove queue code. I no longer retain the
+ *                 rw flag, instead WRITEA's are just dropped [JT]
+ *    30/04/2001 - added KERNEL_VERSION > 2.4.3 get_hardsect_size() rather
+ *                 than get_hardblocksize() call
+ *    03/05/2001 - Use copy_to/from_user to preserve pointers in
+ *                 lvm_do_status_by*
+ *    11/05/2001 - avoid accesses to inactive snapshot data in
+ *                 __update_hardsectsize() and lvm_do_lv_extend_reduce() (JW)
+ *    28/05/2001 - implemented missing BLKSSZGET ioctl
+ *    05/06/2001 - Move _pe_lock out of fast path for lvm_map when no PEs
+ *                 locked.  Make buffer queue flush not need locking.
+ *                 Fix lvm_user_bmap() to set b_rsector for new lvm_map(). [AED]
+ *    30/06/2001 - Speed up __update_hardsectsize() by checking if PVs have
+ *                 the same hardsectsize (very likely) before scanning all LEs
+ *                 in the LV each time.  [AED]
+ *    12/10/2001 - Use add/del_gendisk() routines in 2.4.10+
+ *    01/11/2001 - Backport read_ahead change from Linus kernel [AED]
  *
  */
 
+#include <linux/version.h>
 
 #define MAJOR_NR LVM_BLK_MAJOR
 #define DEVICE_OFF(device)
@@ -191,11 +227,10 @@
 /* #define	LVM_VFS_ENHANCEMENT */
 
 #include <linux/config.h>
-
 #include <linux/module.h>
-
 #include <linux/kernel.h>
 #include <linux/vmalloc.h>
+
 #include <linux/slab.h>
 #include <linux/init.h>
 
@@ -206,6 +241,8 @@
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
 #include <linux/locks.h>
+
+
 #include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
 #include <asm/ioctl.h>
@@ -224,9 +261,13 @@
 
 #include "lvm-internal.h"
 
-#define	LVM_CORRECT_READ_AHEAD( a) \
-   if      ( a < LVM_MIN_READ_AHEAD || \
-             a > LVM_MAX_READ_AHEAD) a = LVM_MAX_READ_AHEAD;
+#define	LVM_CORRECT_READ_AHEAD(a)		\
+do {						\
+	if ((a) < LVM_MIN_READ_AHEAD ||		\
+	    (a) > LVM_MAX_READ_AHEAD)		\
+		(a) = LVM_DEFAULT_READ_AHEAD;	\
+	read_ahead[MAJOR_NR] = (a);		\
+} while(0)
 
 #ifndef WRITEA
 #  define WRITEA WRITE
@@ -236,13 +277,14 @@
 /*
  * External function prototypes
  */
-static int lvm_make_request_fn(request_queue_t*, int, struct buffer_head*);
+static int lvm_make_request_fn(request_queue_t *, int,
+			       struct buffer_head *);
 
 static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong);
 static int lvm_blk_open(struct inode *, struct file *);
 
 static int lvm_blk_close(struct inode *, struct file *);
-static int lvm_get_snapshot_use_rate(lv_t *lv_ptr, void *arg);
+static int lvm_get_snapshot_use_rate(lv_t * lv_ptr, void *arg);
 static int lvm_user_bmap(struct inode *, struct lv_bmap *);
 
 static int lvm_chr_open(struct inode *, struct file *);
@@ -272,13 +314,13 @@
 static int lvm_do_lv_extend_reduce(int, char *, lv_t *);
 static int lvm_do_lv_remove(int, char *, int);
 static int lvm_do_lv_rename(vg_t *, lv_req_t *, lv_t *);
-static int lvm_do_lv_status_byname(vg_t *r, void *);
+static int lvm_do_lv_status_byname(vg_t * r, void *);
 static int lvm_do_lv_status_byindex(vg_t *, void *);
 static int lvm_do_lv_status_bydev(vg_t *, void *);
 
-static int lvm_do_pe_lock_unlock(vg_t *r, void *);
+static int lvm_do_pe_lock_unlock(vg_t * r, void *);
 
-static int lvm_do_pv_change(vg_t*, void*);
+static int lvm_do_pv_change(vg_t *, void *);
 static int lvm_do_pv_status(vg_t *, void *);
 static int lvm_do_pv_flush(void *);
 
@@ -288,15 +330,15 @@
 static int lvm_do_vg_rename(vg_t *, void *);
 static int lvm_do_vg_remove(int);
 static void lvm_geninit(struct gendisk *);
-static void __update_hardsectsize(lv_t *lv);
+static void __update_hardsectsize(lv_t * lv);
 
 
 static void _queue_io(struct buffer_head *bh, int rw);
 static struct buffer_head *_dequeue_io(void);
 static void _flush_io(struct buffer_head *bh);
 
-static int _open_pv(pv_t *pv);
-static void _close_pv(pv_t *pv);
+static int _open_pv(pv_t * pv);
+static void _close_pv(pv_t * pv);
 
 static unsigned long _sectors_to_k(unsigned long sect);
 
@@ -307,7 +349,8 @@
 
 
 /* variables */
-char *lvm_version = "LVM version "LVM_RELEASE_NAME"("LVM_RELEASE_DATE")";
+char *lvm_version =
+    "LVM version " LVM_RELEASE_NAME "(" LVM_RELEASE_DATE ")";
 ushort lvm_iop_version = LVM_DRIVER_IOP_VERSION;
 int loadtime = 0;
 const char *const lvm_name = LVM_NAME;
@@ -351,18 +394,17 @@
 
 
 struct file_operations lvm_chr_fops = {
-	open:		lvm_chr_open,
-	release:	lvm_chr_close,
-	ioctl:		lvm_chr_ioctl,
+	open:lvm_chr_open,
+	release:lvm_chr_close,
+	ioctl:lvm_chr_ioctl,
 };
 
 /* block device operations structure needed for 2.3.38? and above */
-struct block_device_operations lvm_blk_dops =
-{
-	owner:		THIS_MODULE,
-	open: 		lvm_blk_open,
-	release:	lvm_blk_close,
-	ioctl:		lvm_blk_ioctl,
+struct block_device_operations lvm_blk_dops = {
+	owner:THIS_MODULE,
+	open:lvm_blk_open,
+	release:lvm_blk_close,
+	ioctl:lvm_blk_ioctl,
 };
 
 
@@ -372,17 +414,17 @@
 static int lvm_hardsectsizes[MAX_LV];
 static int lvm_size[MAX_LV];
 
-static struct gendisk lvm_gendisk =
-{
-	major:		MAJOR_NR,
-	major_name:	LVM_NAME,
-	minor_shift:	0,
-	max_p:		1,
-	part:		lvm_hd_struct,
-	sizes:		lvm_size,
-	nr_real:	MAX_LV,
+static struct gendisk lvm_gendisk = {
+	major:MAJOR_NR,
+	major_name:LVM_NAME,
+	minor_shift:0,
+	max_p:1,
+	part:lvm_hd_struct,
+	sizes:lvm_size,
+	nr_real:MAX_LV,
 };
 
+
 /*
  * Driver initialization...
  */
@@ -394,7 +436,6 @@
 		       lvm_name);
 		return -EIO;
 	}
-
 	if (devfs_register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_dops) < 0)
 	{
 		printk("%s -- devfs_register_blkdev failed\n", lvm_name);
@@ -409,6 +450,7 @@
 	lvm_init_vars();
 	lvm_geninit(&lvm_gendisk);
 
+	/* insert our gendisk at the corresponding major */
 	add_gendisk(&lvm_gendisk);
 
 #ifdef LVM_HD_NAME
@@ -416,7 +458,8 @@
 	lvm_hd_name_ptr = lvm_hd_name;
 #endif
 
-	blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_make_request_fn);
+	blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR),
+			       lvm_make_request_fn);
 
 
 	/* initialise the pe lock */
@@ -434,12 +477,12 @@
 #endif
 
 	return 0;
-} /* lvm_init() */
-
+}				/* lvm_init() */
 
 /*
  * cleanup...
  */
+
 static void lvm_cleanup(void)
 {
 	if (devfs_unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0)
@@ -449,6 +492,9 @@
 		printk(KERN_ERR "%s -- devfs_unregister_blkdev failed\n",
 		       lvm_name);
 
+
+
+	/* delete our gendisk from chain */
 	del_gendisk(&lvm_gendisk);
 
 	blk_size[MAJOR_NR] = NULL;
@@ -464,11 +510,12 @@
 	lvm_fin_fs();
 
 #ifdef MODULE
-	printk(KERN_INFO "%s -- Module successfully deactivated\n", lvm_name);
+	printk(KERN_INFO "%s -- Module successfully deactivated\n",
+	       lvm_name);
 #endif
 
 	return;
-}	/* lvm_cleanup() */
+}				/* lvm_cleanup() */
 
 /*
  * support function to initialize lvm variables
@@ -487,7 +534,8 @@
 	pe_lock_req.data.pv_offset = 0;
 
 	/* Initialize VG pointers */
-	for (v = 0; v < ABS_MAX_VG; v++) vg[v] = NULL;
+	for (v = 0; v < ABS_MAX_VG; v++)
+		vg[v] = NULL;
 
 	/* Initialize LV -> VG association */
 	for (v = 0; v < ABS_MAX_LV; v++) {
@@ -497,7 +545,7 @@
 	}
 
 	return;
-} /* lvm_init_vars() */
+}				/* lvm_init_vars() */
 
 
 /********************************************************************
@@ -514,28 +562,30 @@
  */
 static int lvm_chr_open(struct inode *inode, struct file *file)
 {
-	unsigned int minor = MINOR(inode->i_rdev);
+	int minor = MINOR(inode->i_rdev);
 
 	P_DEV("chr_open MINOR: %d  VG#: %d  mode: %s%s  lock: %d\n",
 	      minor, VG_CHR(minor), MODE_TO_STR(file->f_mode), lock);
 
 	/* super user validation */
-	if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
 
 	/* Group special file open */
-	if (VG_CHR(minor) > MAX_VG) return -ENXIO;
+	if (VG_CHR(minor) > MAX_VG)
+		return -ENXIO;
 
-       spin_lock(&lvm_lock);
-       if(lock == current->pid)
-               _lock_open_count++;
-       spin_unlock(&lvm_lock);
+	spin_lock(&lvm_lock);
+	if (lock == current->pid)
+		_lock_open_count++;
+	spin_unlock(&lvm_lock);
 
 	lvm_chr_open_count++;
 
 	MOD_INC_USE_COUNT;
 
 	return 0;
-} /* lvm_chr_open() */
+}				/* lvm_chr_open() */
 
 
 /*
@@ -546,22 +596,25 @@
  *
  */
 static int lvm_chr_ioctl(struct inode *inode, struct file *file,
-		  uint command, ulong a)
+			 uint command, ulong a)
 {
 	int minor = MINOR(inode->i_rdev);
 	uint extendable, l, v;
 	void *arg = (void *) a;
 	lv_t lv;
-	vg_t* vg_ptr = vg[VG_CHR(minor)];
+	vg_t *vg_ptr = vg[VG_CHR(minor)];
 
 	/* otherwise cc will complain about unused variables */
 	(void) lvm_lock;
 
-	P_IOCTL("chr MINOR: %d  command: 0x%X  arg: %p  VG#: %d  mode: %s%s\n",
-		minor, command, arg, VG_CHR(minor), MODE_TO_STR(file->f_mode));
+	P_IOCTL
+	    ("chr MINOR: %d  command: 0x%X  arg: %p  VG#: %d  mode: %s%s\n",
+	     minor, command, arg, VG_CHR(minor),
+	     MODE_TO_STR(file->f_mode));
 
 #ifdef LVM_TOTAL_RESET
-	if (lvm_reset_spindown > 0) return -EACCES;
+	if (lvm_reset_spindown > 0)
+		return -EACCES;
 #endif
 
 	/* Main command switch */
@@ -573,8 +626,8 @@
 	case LVM_GET_IOP_VERSION:
 		/* check lvm version to ensure driver/tools+lib
 		   interoperability */
-		if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != 0)
-			return -EFAULT;
+		if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) !=
+		    0) return -EFAULT;
 		return 0;
 
 #ifdef LVM_TOTAL_RESET
@@ -582,7 +635,8 @@
 		/* lock reset function */
 		lvm_reset_spindown = 1;
 		for (v = 0; v < ABS_MAX_VG; v++) {
-			if (vg[v] != NULL) lvm_do_vg_remove(v);
+			if (vg[v] != NULL)
+				lvm_do_vg_remove(v);
 		}
 
 #ifdef MODULE
@@ -590,28 +644,28 @@
 			MOD_INC_USE_COUNT;
 		while (GET_USE_COUNT(&__this_module) > 1)
 			MOD_DEC_USE_COUNT;
-#endif /* MODULE */
+#endif				/* MODULE */
 		lock = 0;	/* release lock */
 		wake_up_interruptible(&lvm_wait);
 		return 0;
-#endif /* LVM_TOTAL_RESET */
+#endif				/* LVM_TOTAL_RESET */
 
 
 	case LE_REMAP:
 		/* remap a logical extent (after moving the physical extent) */
-		return lvm_do_le_remap(vg_ptr,arg);
+		return lvm_do_le_remap(vg_ptr, arg);
 
 	case PE_LOCK_UNLOCK:
 		/* lock/unlock i/o to a physical extent to move it to another
 		   physical volume (move's done in user space's pvmove) */
-		return lvm_do_pe_lock_unlock(vg_ptr,arg);
+		return lvm_do_pe_lock_unlock(vg_ptr, arg);
 
 	case VG_CREATE_OLD:
 		/* create a VGDA */
 		return lvm_do_vg_create(arg, minor);
 
-       case VG_CREATE:
-               /* create a VGDA, assume VG number is filled in */
+	case VG_CREATE:
+		/* create a VGDA, assume VG number is filled in */
 		return lvm_do_vg_create(arg, -1);
 
 	case VG_EXTEND:
@@ -633,9 +687,10 @@
 
 	case VG_SET_EXTENDABLE:
 		/* set/clear extendability flag of volume group */
-		if (vg_ptr == NULL) return -ENXIO;
-		if (copy_from_user(&extendable, arg, sizeof(extendable)) != 0)
-			return -EFAULT;
+		if (vg_ptr == NULL)
+			return -ENXIO;
+		if (copy_from_user(&extendable, arg, sizeof(extendable)) !=
+		    0) return -EFAULT;
 
 		if (extendable == VG_EXTENDABLE ||
 		    extendable == ~VG_EXTENDABLE) {
@@ -643,13 +698,15 @@
 				vg_ptr->vg_status |= VG_EXTENDABLE;
 			else
 				vg_ptr->vg_status &= ~VG_EXTENDABLE;
-		} else return -EINVAL;
+		} else
+			return -EINVAL;
 		return 0;
 
 
 	case VG_STATUS:
 		/* get volume group data (only the vg_t struct) */
-		if (vg_ptr == NULL) return -ENXIO;
+		if (vg_ptr == NULL)
+			return -ENXIO;
 		if (copy_to_user(arg, vg_ptr, sizeof(vg_t)) != 0)
 			return -EFAULT;
 		return 0;
@@ -682,21 +739,25 @@
 	case LV_REMOVE:
 	case LV_RENAME:
 		/* create, extend, reduce, remove or rename a logical volume */
-		if (vg_ptr == NULL) return -ENXIO;
+		if (vg_ptr == NULL)
+			return -ENXIO;
 		if (copy_from_user(&lv_req, arg, sizeof(lv_req)) != 0)
 			return -EFAULT;
 
 		if (command != LV_REMOVE) {
-			if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != 0)
-				return -EFAULT;
+			if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) !=
+			    0) return -EFAULT;
 		}
 		switch (command) {
 		case LV_CREATE:
-			return lvm_do_lv_create(minor, lv_req.lv_name, &lv);
+			return lvm_do_lv_create(minor, lv_req.lv_name,
+						&lv);
 
 		case LV_EXTEND:
 		case LV_REDUCE:
-			return lvm_do_lv_extend_reduce(minor, lv_req.lv_name, &lv);
+			return lvm_do_lv_extend_reduce(minor,
+						       lv_req.lv_name,
+						       &lv);
 		case LV_REMOVE:
 			return lvm_do_lv_remove(minor, lv_req.lv_name, -1);
 
@@ -724,17 +785,17 @@
 
 	case PV_CHANGE:
 		/* change a physical volume */
-		return lvm_do_pv_change(vg_ptr,arg);
+		return lvm_do_pv_change(vg_ptr, arg);
 
 
 	case PV_STATUS:
 		/* get physical volume data (pv_t structure only) */
-		return lvm_do_pv_status(vg_ptr,arg);
+		return lvm_do_pv_status(vg_ptr, arg);
 
 
 	case PV_FLUSH:
 		/* physical volume buffer flush/invalidate */
-               return lvm_do_pv_flush(arg);
+		return lvm_do_pv_flush(arg);
 
 
 	default:
@@ -745,7 +806,7 @@
 	}
 
 	return 0;
-} /* lvm_chr_ioctl */
+}				/* lvm_chr_ioctl */
 
 
 /*
@@ -763,23 +824,25 @@
 	}
 #endif
 
-	if (lvm_chr_open_count > 0) lvm_chr_open_count--;
+	if (lvm_chr_open_count > 0)
+		lvm_chr_open_count--;
 
-       spin_lock(&lvm_lock);
-       if(lock == current->pid) {
-               if(!_lock_open_count) {
-			P_DEV("chr_close: unlocking LVM for pid %d\n", lock);
-                       lock = 0;
-                       wake_up_interruptible(&lvm_wait);
-               } else
-                       _lock_open_count--;
+	spin_lock(&lvm_lock);
+	if (lock == current->pid) {
+		if (!_lock_open_count) {
+			P_DEV("chr_close: unlocking LVM for pid %d\n",
+			      lock);
+			lock = 0;
+			wake_up_interruptible(&lvm_wait);
+		} else
+			_lock_open_count--;
 	}
-       spin_unlock(&lvm_lock);
+	spin_unlock(&lvm_lock);
 
 	MOD_DEC_USE_COUNT;
 
 	return 0;
-} /* lvm_chr_close() */
+}				/* lvm_chr_close() */
 
 
 
@@ -799,7 +862,8 @@
 	vg_t *vg_ptr = vg[VG_BLK(minor)];
 
 	P_DEV("blk_open MINOR: %d  VG#: %d  LV#: %d  mode: %s%s\n",
-	      minor, VG_BLK(minor), LV_BLK(minor), MODE_TO_STR(file->f_mode));
+	      minor, VG_BLK(minor), LV_BLK(minor),
+	      MODE_TO_STR(file->f_mode));
 
 #ifdef LVM_TOTAL_RESET
 	if (lvm_reset_spindown > 0)
@@ -809,26 +873,25 @@
 	if (vg_ptr != NULL &&
 	    (vg_ptr->vg_status & VG_ACTIVE) &&
 	    (lv_ptr = vg_ptr->lv[LV_BLK(minor)]) != NULL &&
-	    LV_BLK(minor) >= 0 &&
-	    LV_BLK(minor) < vg_ptr->lv_max) {
+	    LV_BLK(minor) >= 0 && LV_BLK(minor) < vg_ptr->lv_max) {
 
 		/* Check parallel LV spindown (LV remove) */
-		if (lv_ptr->lv_status & LV_SPINDOWN) return -EPERM;
+		if (lv_ptr->lv_status & LV_SPINDOWN)
+			return -EPERM;
 
 		/* Check inactive LV and open for read/write */
 		/* We need to be able to "read" an inactive LV
 		   to re-activate it again */
 		if ((file->f_mode & FMODE_WRITE) &&
-		    (!(lv_ptr->lv_status & LV_ACTIVE)))
-		    return -EPERM;
+		    (!(lv_ptr->lv_status & LV_ACTIVE))) return -EPERM;
 
 		if (!(lv_ptr->lv_access & LV_WRITE) &&
-		    (file->f_mode & FMODE_WRITE))
-			return -EACCES;
+		    (file->f_mode & FMODE_WRITE)) return -EACCES;
 
 
-                /* be sure to increment VG counter */
-		if (lv_ptr->lv_open == 0) vg_ptr->lv_open++;
+		/* be sure to increment VG counter */
+		if (lv_ptr->lv_open == 0)
+			vg_ptr->lv_open++;
 		lv_ptr->lv_open++;
 
 		MOD_INC_USE_COUNT;
@@ -838,7 +901,7 @@
 		return 0;
 	}
 	return -ENXIO;
-} /* lvm_blk_open() */
+}				/* lvm_blk_open() */
 
 
 /*
@@ -860,24 +923,26 @@
 	switch (command) {
 	case BLKSSZGET:
 		/* get block device sector size as needed e.g. by fdisk */
-		return put_user(get_hardsect_size(inode->i_rdev), (int *) arg);
+		return put_user(lvm_sectsize(inode->i_rdev), (int *) arg);
 
 	case BLKGETSIZE:
 		/* return device size */
 		P_IOCTL("BLKGETSIZE: %u\n", lv_ptr->lv_size);
-		if (put_user(lv_ptr->lv_size, (unsigned long *)arg))
+		if (put_user(lv_ptr->lv_size, (unsigned long *) arg))
 			return -EFAULT;
 		break;
 
+#ifdef BLKGETSIZE64
 	case BLKGETSIZE64:
-		if (put_user((u64)lv_ptr->lv_size << 9, (u64 *)arg))
+		if (put_user((u64) lv_ptr->lv_size << 9, (u64 *) arg))
 			return -EFAULT;
 		break;
-
+#endif
 
 	case BLKFLSBUF:
 		/* flush buffer cache */
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
 
 		P_IOCTL("BLKFLSBUF\n");
 
@@ -888,22 +953,24 @@
 
 	case BLKRASET:
 		/* set read ahead for block device */
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
 
 		P_IOCTL("BLKRASET: %ld sectors for %s\n",
 			(long) arg, kdevname(inode->i_rdev));
 
 		if ((long) arg < LVM_MIN_READ_AHEAD ||
-		    (long) arg > LVM_MAX_READ_AHEAD)
-			return -EINVAL;
+		    (long) arg > LVM_MAX_READ_AHEAD) return -EINVAL;
 		lv_ptr->lv_read_ahead = (long) arg;
+		LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead);
+		read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead;
 		break;
 
 
 	case BLKRAGET:
 		/* get current read ahead setting */
 		P_IOCTL("BLKRAGET %d\n", lv_ptr->lv_read_ahead);
-		if (put_user(lv_ptr->lv_read_ahead, (long *)arg))
+		if (put_user(lv_ptr->lv_read_ahead, (long *) arg))
 			return -EFAULT;
 		break;
 
@@ -917,16 +984,18 @@
 			unsigned char heads = 64;
 			unsigned char sectors = 32;
 			long start = 0;
-			short cylinders = lv_ptr->lv_size / heads / sectors;
+			short cylinders =
+			    lv_ptr->lv_size / heads / sectors;
 
 			if (copy_to_user((char *) &hd->heads, &heads,
 					 sizeof(heads)) != 0 ||
 			    copy_to_user((char *) &hd->sectors, &sectors,
 					 sizeof(sectors)) != 0 ||
 			    copy_to_user((short *) &hd->cylinders,
-				   &cylinders, sizeof(cylinders)) != 0 ||
-			    copy_to_user((long *) &hd->start, &start,
-					 sizeof(start)) != 0)
+					 &cylinders,
+					 sizeof(cylinders)) != 0
+			    || copy_to_user((long *) &hd->start, &start,
+					    sizeof(start)) != 0)
 				return -EFAULT;
 
 			P_IOCTL("%s -- lvm_blk_ioctl -- cylinders: %d\n",
@@ -937,9 +1006,10 @@
 
 	case LV_SET_ACCESS:
 		/* set access flags of a logical volume */
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
 		lv_ptr->lv_access = (ulong) arg;
-		if ( lv_ptr->lv_access & LV_WRITE)
+		if (lv_ptr->lv_access & LV_WRITE)
 			set_device_ro(lv_ptr->lv_dev, 0);
 		else
 			set_device_ro(lv_ptr->lv_dev, 1);
@@ -948,23 +1018,25 @@
 
 	case LV_SET_STATUS:
 		/* set status flags of a logical volume */
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
 		if (!((ulong) arg & LV_ACTIVE) && lv_ptr->lv_open > 1)
 			return -EPERM;
 		lv_ptr->lv_status = (ulong) arg;
 		break;
 
 	case LV_BMAP:
-                /* turn logical block into (dev_t, block).  non privileged. */
-                /* don't bmap a snapshot, since the mapping can change */
-		if(lv_ptr->lv_access & LV_SNAPSHOT)
+		/* turn logical block into (dev_t, block). non privileged. */
+		/* don't bmap a snapshot, since the mapping can change */
+		if (lv_ptr->lv_access & LV_SNAPSHOT)
 			return -EPERM;
 
 		return lvm_user_bmap(inode, (struct lv_bmap *) arg);
 
 	case LV_SET_ALLOCATION:
 		/* set allocation flags of a logical volume */
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
 		lv_ptr->lv_allocation = (ulong) arg;
 		break;
 
@@ -979,7 +1051,7 @@
 	}
 
 	return 0;
-} /* lvm_blk_ioctl() */
+}				/* lvm_blk_ioctl() */
 
 
 /*
@@ -994,15 +1066,16 @@
 	P_DEV("blk_close MINOR: %d  VG#: %d  LV#: %d\n",
 	      minor, VG_BLK(minor), LV_BLK(minor));
 
-	if (lv_ptr->lv_open == 1) vg_ptr->lv_open--;
+	if (lv_ptr->lv_open == 1)
+		vg_ptr->lv_open--;
 	lv_ptr->lv_open--;
 
 	MOD_DEC_USE_COUNT;
 
 	return 0;
-} /* lvm_blk_close() */
+}				/* lvm_blk_close() */
 
-static int lvm_get_snapshot_use_rate(lv_t *lv, void *arg)
+static int lvm_get_snapshot_use_rate(lv_t * lv, void *arg)
 {
 	lv_snapshot_use_rate_req_t lv_rate_req;
 
@@ -1020,7 +1093,7 @@
 		lv->lv_snapshot_use_rate = lv_rate_req.rate;
 		if (lv->lv_remap_ptr * 100 / lv->lv_remap_end <
 		    lv->lv_snapshot_use_rate)
-			interruptible_sleep_on(&lv->lv_snapshot_wait);
+			    interruptible_sleep_on(&lv->lv_snapshot_wait);
 		break;
 
 	case O_NONBLOCK:
@@ -1044,19 +1117,20 @@
 	if (get_user(block, &user_result->lv_block))
 		return -EFAULT;
 
-	memset(&bh,0,sizeof bh);
+	memset(&bh, 0, sizeof bh);
 	bh.b_blocknr = block;
 	bh.b_dev = bh.b_rdev = inode->i_rdev;
 	bh.b_size = lvm_get_blksize(bh.b_dev);
- 	bh.b_rsector = block * (bh.b_size >> 9);
-	if ((err=lvm_map(&bh, READ)) < 0)  {
+	bh.b_rsector = block * (bh.b_size >> 9);
+	bh.b_end_io = NULL;
+	if ((err = lvm_map(&bh, READ)) < 0) {
 		printk("lvm map failed: %d\n", err);
 		return -EINVAL;
 	}
 
 	return put_user(kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) ||
-	       put_user(bh.b_rsector/(bh.b_size>>9), &user_result->lv_block) ?
-	       -EFAULT : 0;
+	    put_user(bh.b_rsector / (bh.b_size >> 9),
+		     &user_result->lv_block) ? -EFAULT : 0;
 }
 
 
@@ -1065,7 +1139,8 @@
  * (see init_module/lvm_init)
  */
 static void __remap_snapshot(kdev_t rdev, ulong rsector,
-			     ulong pe_start, lv_t *lv, vg_t *vg) {
+			     ulong pe_start, lv_t * lv, vg_t * vg)
+{
 
 	/* copy a chunk from the origin to a snapshot device */
 	down_write(&lv->lv_lock);
@@ -1080,7 +1155,8 @@
 }
 
 static inline void _remap_snapshot(kdev_t rdev, ulong rsector,
-				   ulong pe_start, lv_t *lv, vg_t *vg) {
+				   ulong pe_start, lv_t * lv, vg_t * vg)
+{
 	int r;
 
 	/* check to see if this chunk is already in the snapshot */
@@ -1097,7 +1173,8 @@
 /*
  * extents destined for a pe that is on the move should be deferred
  */
-static inline int _should_defer(kdev_t pv, ulong sector, uint32_t pe_size) {
+static inline int _should_defer(kdev_t pv, ulong sector, uint32_t pe_size)
+{
 	return ((pe_lock_req.lock == LOCK_PE) &&
 		(pv == pe_lock_req.data.pv_dev) &&
 		(sector >= pe_lock_req.data.pv_offset) &&
@@ -1122,6 +1199,7 @@
 	return 0;
 }
 
+
 static int lvm_map(struct buffer_head *bh, int rw)
 {
 	int minor = MINOR(bh->b_rdev);
@@ -1143,34 +1221,32 @@
 		goto bad;
 	}
 
-	if ((rw == WRITE || rw == WRITEA) &&
-	    !(lv->lv_access & LV_WRITE)) {
+	if ((rw == WRITE || rw == WRITEA) && !(lv->lv_access & LV_WRITE)) {
 		printk(KERN_CRIT
 		       "%s - lvm_map: ll_rw_blk write for readonly LV %s\n",
 		       lvm_name, lv->lv_name);
 		goto bad;
 	}
 
-	P_MAP("%s - lvm_map minor: %d  *rdev: %s  *rsector: %lu  size:%lu\n",
-	      lvm_name, minor,
-	      kdevname(bh->b_rdev),
-	      rsector_org, size);
+	P_MAP
+	    ("%s - lvm_map minor: %d  *rdev: %s  *rsector: %lu  size:%lu\n",
+	     lvm_name, minor, kdevname(bh->b_rdev), rsector_org, size);
 
 	if (rsector_org + size > lv->lv_size) {
 		printk(KERN_ALERT
 		       "%s - lvm_map access beyond end of device; *rsector: "
-                       "%lu or size: %lu wrong for minor: %2d\n",
-                       lvm_name, rsector_org, size, minor);
+		       "%lu or size: %lu wrong for minor: %2d\n",
+		       lvm_name, rsector_org, size, minor);
 		goto bad;
 	}
 
 
-	if (lv->lv_stripes < 2) { /* linear mapping */
+	if (lv->lv_stripes < 2) {	/* linear mapping */
 		/* get the index */
 		index = rsector_org / vg_this->pe_size;
 		pe_start = lv->lv_current_pe[index].pe;
 		rsector_map = lv->lv_current_pe[index].pe +
-			(rsector_org % vg_this->pe_size);
+		    (rsector_org % vg_this->pe_size);
 		rdev_map = lv->lv_current_pe[index].dev;
 
 		P_MAP("lv_current_pe[%ld].pe: %d  rdev: %s  rsector:%ld\n",
@@ -1183,22 +1259,23 @@
 
 		stripe_length = vg_this->pe_size * lv->lv_stripes;
 		stripe_index = (rsector_org % stripe_length) /
-			lv->lv_stripesize;
+		    lv->lv_stripesize;
 		index = rsector_org / stripe_length +
-			(stripe_index % lv->lv_stripes) *
-			(lv->lv_allocated_le / lv->lv_stripes);
+		    (stripe_index % lv->lv_stripes) *
+		    (lv->lv_allocated_le / lv->lv_stripes);
 		pe_start = lv->lv_current_pe[index].pe;
 		rsector_map = lv->lv_current_pe[index].pe +
-			(rsector_org % stripe_length) -
-			(stripe_index % lv->lv_stripes) * lv->lv_stripesize -
-			stripe_index / lv->lv_stripes *
-			(lv->lv_stripes - 1) * lv->lv_stripesize;
+		    (rsector_org % stripe_length) -
+		    (stripe_index % lv->lv_stripes) * lv->lv_stripesize -
+		    stripe_index / lv->lv_stripes *
+		    (lv->lv_stripes - 1) * lv->lv_stripesize;
 		rdev_map = lv->lv_current_pe[index].dev;
 
 		P_MAP("lv_current_pe[%ld].pe: %d  rdev: %s  rsector:%ld\n"
 		      "stripe_length: %ld  stripe_index: %ld\n",
-		      index, lv->lv_current_pe[index].pe, kdevname(rdev_map),
-		      rsector_map, stripe_length, stripe_index);
+		      index, lv->lv_current_pe[index].pe,
+		      kdevname(rdev_map), rsector_map, stripe_length,
+		      stripe_index);
 	}
 
 	/*
@@ -1207,8 +1284,8 @@
 	 * we need to queue this request, because this is in the fast path.
 	 */
 	if (rw == WRITE || rw == WRITEA) {
-		if(_defer_extent(bh, rw, rdev_map,
-				 rsector_map, vg_this->pe_size)) {
+		if (_defer_extent(bh, rw, rdev_map,
+				  rsector_map, vg_this->pe_size)) {
 
 			up_read(&lv->lv_lock);
 			return 0;
@@ -1219,17 +1296,14 @@
 		lv->lv_current_pe[index].reads++;	/* statistic */
 
 	/* snapshot volume exception handling on physical device address base */
-	if (!(lv->lv_access & (LV_SNAPSHOT|LV_SNAPSHOT_ORG)))
+	if (!(lv->lv_access & (LV_SNAPSHOT | LV_SNAPSHOT_ORG)))
 		goto out;
 
-	if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */
-		if (lv->lv_block_exception)
-			lvm_snapshot_remap_block(&rdev_map, &rsector_map,
-						 pe_start, lv);
-		else
-			goto bad;
-
-	} else if (rw == WRITE || rw == WRITEA) { /* snapshot origin */
+	if (lv->lv_access & LV_SNAPSHOT) {	/* remap snapshot */
+		if (lvm_snapshot_remap_block
+		    (&rdev_map, &rsector_map, pe_start, lv) < 0)
+				goto bad;
+	} else if (rw == WRITE || rw == WRITEA) {	/* snapshot origin */
 		lv_t *snap;
 
 		/* start with first snapshot and loop through all of
@@ -1243,21 +1317,21 @@
 			/* Serializes the COW with the accesses to the
 			   snapshot device */
 			_remap_snapshot(rdev_map, rsector_map,
-					 pe_start, snap, vg_this);
+					pe_start, snap, vg_this);
 		}
- 	}
+	}
 
- out:
+      out:
 	bh->b_rdev = rdev_map;
 	bh->b_rsector = rsector_map;
 	up_read(&lv->lv_lock);
 	return 1;
 
- bad:
-	buffer_IO_error(bh);
+      bad:
+	if (bh->b_end_io) buffer_IO_error(bh);
 	up_read(&lv->lv_lock);
 	return -1;
-} /* lvm_map() */
+}				/* lvm_map() */
 
 
 /*
@@ -1284,12 +1358,14 @@
 #endif
 
 
+
+
 /*
  * make request function
  */
-static int lvm_make_request_fn(request_queue_t *q,
-			       int rw,
-			       struct buffer_head *bh) {
+static int lvm_make_request_fn(request_queue_t * q,
+			       int rw, struct buffer_head *bh)
+{
 	return (lvm_map(bh, rw) <= 0) ? 0 : 1;
 }
 
@@ -1304,7 +1380,7 @@
  */
 static int lvm_do_lock_lvm(void)
 {
-lock_try_again:
+      lock_try_again:
 	spin_lock(&lvm_lock);
 	if (lock != 0 && lock != current->pid) {
 		P_DEV("lvm_do_lock_lvm: locked by pid %d ...\n", lock);
@@ -1322,19 +1398,20 @@
 	P_DEV("lvm_do_lock_lvm: locking LVM for pid %d\n", lock);
 	spin_unlock(&lvm_lock);
 	return 0;
-} /* lvm_do_lock_lvm */
+}				/* lvm_do_lock_lvm */
 
 
 /*
  * character device support function lock/unlock physical extend
  */
-static int lvm_do_pe_lock_unlock(vg_t *vg_ptr, void *arg)
+static int lvm_do_pe_lock_unlock(vg_t * vg_ptr, void *arg)
 {
 	pe_lock_req_t new_lock;
 	struct buffer_head *bh;
 	uint p;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (copy_from_user(&new_lock, arg, sizeof(new_lock)) != 0)
 		return -EFAULT;
 
@@ -1345,7 +1422,8 @@
 			    new_lock.data.pv_dev == vg_ptr->pv[p]->pv_dev)
 				break;
 		}
-		if (p == vg_ptr->pv_max) return -ENXIO;
+		if (p == vg_ptr->pv_max)
+			return -ENXIO;
 
 		/*
 		 * this sync releaves memory pressure to lessen the
@@ -1396,21 +1474,20 @@
 /*
  * character device support function logical extend remap
  */
-static int lvm_do_le_remap(vg_t *vg_ptr, void *arg)
+static int lvm_do_le_remap(vg_t * vg_ptr, void *arg)
 {
 	uint l, le;
 	lv_t *lv_ptr;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (copy_from_user(&le_remap_req, arg,
-			   sizeof(le_remap_req_t)) != 0)
-		return -EFAULT;
+			   sizeof(le_remap_req_t)) != 0) return -EFAULT;
 
 	for (l = 0; l < vg_ptr->lv_max; l++) {
 		lv_ptr = vg_ptr->lv[l];
 		if (lv_ptr != NULL &&
-		    strcmp(lv_ptr->lv_name,
-			       le_remap_req.lv_name) == 0) {
+		    strcmp(lv_ptr->lv_name, le_remap_req.lv_name) == 0) {
 			for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
 				if (lv_ptr->lv_current_pe[le].dev ==
 				    le_remap_req.old_dev &&
@@ -1429,7 +1506,7 @@
 		}
 	}
 	return -ENXIO;
-} /* lvm_do_le_remap() */
+}				/* lvm_do_le_remap() */
 
 
 /*
@@ -1443,7 +1520,7 @@
 	vg_t *vg_ptr;
 	lv_t **snap_lv_ptr;
 
-	if ((vg_ptr = kmalloc(sizeof(vg_t),GFP_KERNEL)) == NULL) {
+	if ((vg_ptr = kmalloc(sizeof(vg_t), GFP_KERNEL)) == NULL) {
 		printk(KERN_CRIT
 		       "%s -- VG_CREATE: kmalloc error VG at line %d\n",
 		       lvm_name, __LINE__);
@@ -1451,20 +1528,22 @@
 	}
 	/* get the volume group structure */
 	if (copy_from_user(vg_ptr, arg, sizeof(vg_t)) != 0) {
-		P_IOCTL("lvm_do_vg_create ERROR: copy VG ptr %p (%d bytes)\n",
-			arg, sizeof(vg_t));
+		P_IOCTL
+		    ("lvm_do_vg_create ERROR: copy VG ptr %p (%d bytes)\n",
+		     arg, sizeof(vg_t));
 		kfree(vg_ptr);
 		return -EFAULT;
 	}
 
-        /* VG_CREATE now uses minor number in VG structure */
-        if (minor == -1) minor = vg_ptr->vg_number;
+	/* VG_CREATE now uses minor number in VG structure */
+	if (minor == -1)
+		minor = vg_ptr->vg_number;
 
 	/* Validate it */
-        if (vg[VG_CHR(minor)] != NULL) {
+	if (vg[VG_CHR(minor)] != NULL) {
 		P_IOCTL("lvm_do_vg_create ERROR: VG %d in use\n", minor);
 		kfree(vg_ptr);
-  	     	return -EPERM;
+		return -EPERM;
 	}
 
 	/* we are not that active so far... */
@@ -1481,7 +1560,7 @@
 
 	if (vg_ptr->lv_max > ABS_MAX_LV) {
 		printk(KERN_WARNING
-		"%s -- Can't activate VG: ABS_MAX_LV too small for %u\n",
+		       "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n",
 		       lvm_name, vg_ptr->lv_max);
 		kfree(vg_ptr);
 		return -EPERM;
@@ -1499,7 +1578,7 @@
 		/* user space address */
 		if ((pvp = vg_ptr->pv[p]) != NULL) {
 			ret = lvm_do_pv_create(pvp, vg_ptr, p);
-			if ( ret != 0) {
+			if (ret != 0) {
 				lvm_do_vg_remove(minor);
 				return ret;
 			}
@@ -1507,7 +1586,7 @@
 	}
 
 	size = vg_ptr->lv_max * sizeof(lv_t *);
-	if ((snap_lv_ptr = vmalloc ( size)) == NULL) {
+	if ((snap_lv_ptr = vmalloc(size)) == NULL) {
 		printk(KERN_CRIT
 		       "%s -- VG_CREATE: vmalloc error snapshot LVs at line %d\n",
 		       lvm_name, __LINE__);
@@ -1523,12 +1602,13 @@
 		/* user space address */
 		if ((lvp = vg_ptr->lv[l]) != NULL) {
 			if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) {
-				P_IOCTL("ERROR: copying LV ptr %p (%d bytes)\n",
-					lvp, sizeof(lv_t));
+				P_IOCTL
+				    ("ERROR: copying LV ptr %p (%d bytes)\n",
+				     lvp, sizeof(lv_t));
 				lvm_do_vg_remove(minor);
 				return -EFAULT;
 			}
-			if ( lv.lv_access & LV_SNAPSHOT) {
+			if (lv.lv_access & LV_SNAPSHOT) {
 				snap_lv_ptr[ls] = lvp;
 				vg_ptr->lv[l] = NULL;
 				ls++;
@@ -1568,24 +1648,26 @@
 	vg_ptr->vg_status |= VG_ACTIVE;
 
 	return 0;
-} /* lvm_do_vg_create() */
+}				/* lvm_do_vg_create() */
 
 
 /*
  * character device support function VGDA extend
  */
-static int lvm_do_vg_extend(vg_t *vg_ptr, void *arg)
+static int lvm_do_vg_extend(vg_t * vg_ptr, void *arg)
 {
 	int ret = 0;
 	uint p;
 	pv_t *pv_ptr;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (vg_ptr->pv_cur < vg_ptr->pv_max) {
 		for (p = 0; p < vg_ptr->pv_max; p++) {
-			if ( ( pv_ptr = vg_ptr->pv[p]) == NULL) {
+			if ((pv_ptr = vg_ptr->pv[p]) == NULL) {
 				ret = lvm_do_pv_create(arg, vg_ptr, p);
-				if ( ret != 0) return ret;
+				if (ret != 0)
+					return ret;
 				pv_ptr = vg_ptr->pv[p];
 				vg_ptr->pe_total += pv_ptr->pe_total;
 				return 0;
@@ -1593,26 +1675,28 @@
 		}
 	}
 	return -EPERM;
-} /* lvm_do_vg_extend() */
+}				/* lvm_do_vg_extend() */
 
 
 /*
  * character device support function VGDA reduce
  */
-static int lvm_do_vg_reduce(vg_t *vg_ptr, void *arg) {
+static int lvm_do_vg_reduce(vg_t * vg_ptr, void *arg)
+{
 	uint p;
 	pv_t *pv_ptr;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (copy_from_user(pv_name, arg, sizeof(pv_name)) != 0)
 		return -EFAULT;
 
 	for (p = 0; p < vg_ptr->pv_max; p++) {
 		pv_ptr = vg_ptr->pv[p];
 		if (pv_ptr != NULL &&
-		    strcmp(pv_ptr->pv_name,
-			       pv_name) == 0) {
-			if (pv_ptr->lv_cur > 0) return -EPERM;
+		    strcmp(pv_ptr->pv_name, pv_name) == 0) {
+			if (pv_ptr->lv_cur > 0)
+				return -EPERM;
 			lvm_do_pv_remove(vg_ptr, p);
 			/* Make PV pointer array contiguous */
 			for (; p < vg_ptr->pv_max - 1; p++)
@@ -1622,52 +1706,55 @@
 		}
 	}
 	return -ENXIO;
-} /* lvm_do_vg_reduce */
+}				/* lvm_do_vg_reduce */
 
 
 /*
  * character device support function VG rename
  */
-static int lvm_do_vg_rename(vg_t *vg_ptr, void *arg)
+static int lvm_do_vg_rename(vg_t * vg_ptr, void *arg)
 {
 	int l = 0, p = 0, len = 0;
-	char vg_name[NAME_LEN] = { 0,};
-	char lv_name[NAME_LEN] = { 0,};
+	char vg_name[NAME_LEN] = { 0, };
+	char lv_name[NAME_LEN] = { 0, };
 	char *ptr = NULL;
 	lv_t *lv_ptr = NULL;
 	pv_t *pv_ptr = NULL;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	/* If the VG doesn't exist in the kernel then just exit */
+	if (!vg_ptr)
+		return 0;
 
 	if (copy_from_user(vg_name, arg, sizeof(vg_name)) != 0)
 		return -EFAULT;
 
 	lvm_fs_remove_vg(vg_ptr);
 
-	strncpy ( vg_ptr->vg_name, vg_name, sizeof ( vg_name)-1);
-	for ( l = 0; l < vg_ptr->lv_max; l++)
-	{
-		if ((lv_ptr = vg_ptr->lv[l]) == NULL) continue;
-		strncpy(lv_ptr->vg_name, vg_name, sizeof ( vg_name));
+	strncpy(vg_ptr->vg_name, vg_name, sizeof(vg_name) - 1);
+	for (l = 0; l < vg_ptr->lv_max; l++) {
+		if ((lv_ptr = vg_ptr->lv[l]) == NULL)
+			continue;
+		strncpy(lv_ptr->vg_name, vg_name, sizeof(vg_name));
 		ptr = strrchr(lv_ptr->lv_name, '/');
-		if (ptr == NULL) ptr = lv_ptr->lv_name;
-		strncpy(lv_name, ptr, sizeof ( lv_name));
+		if (ptr == NULL)
+			ptr = lv_ptr->lv_name;
+		strncpy(lv_name, ptr, sizeof(lv_name));
 		len = sizeof(LVM_DIR_PREFIX);
 		strcpy(lv_ptr->lv_name, LVM_DIR_PREFIX);
 		strncat(lv_ptr->lv_name, vg_name, NAME_LEN - len);
-		len += strlen ( vg_name);
+		len += strlen(vg_name);
 		strncat(lv_ptr->lv_name, lv_name, NAME_LEN - len);
 	}
-	for ( p = 0; p < vg_ptr->pv_max; p++)
-	{
-		if ( (pv_ptr = vg_ptr->pv[p]) == NULL) continue;
+	for (p = 0; p < vg_ptr->pv_max; p++) {
+		if ((pv_ptr = vg_ptr->pv[p]) == NULL)
+			continue;
 		strncpy(pv_ptr->vg_name, vg_name, NAME_LEN);
 	}
 
 	lvm_fs_create_vg(vg_ptr);
 
 	return 0;
-} /* lvm_do_vg_rename */
+}				/* lvm_do_vg_rename */
 
 
 /*
@@ -1679,7 +1766,8 @@
 	vg_t *vg_ptr = vg[VG_CHR(minor)];
 	pv_t *pv_ptr;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 
 #ifdef LVM_TOTAL_RESET
 	if (vg_ptr->lv_open > 0 && lvm_reset_spindown == 0)
@@ -1730,17 +1818,18 @@
 	MOD_DEC_USE_COUNT;
 
 	return 0;
-} /* lvm_do_vg_remove() */
+}				/* lvm_do_vg_remove() */
 
 
 /*
  * character device support function physical volume create
  */
-static int lvm_do_pv_create(pv_t *pvp, vg_t *vg_ptr, ulong p) {
+static int lvm_do_pv_create(pv_t * pvp, vg_t * vg_ptr, ulong p)
+{
 	pv_t *pv;
 	int err;
 
-	pv = kmalloc(sizeof(pv_t),GFP_KERNEL);
+	pv = kmalloc(sizeof(pv_t), GFP_KERNEL);
 	if (pv == NULL) {
 		printk(KERN_CRIT
 		       "%s -- PV_CREATE: kmalloc error PV at line %d\n",
@@ -1751,8 +1840,9 @@
 	memset(pv, 0, sizeof(*pv));
 
 	if (copy_from_user(pv, pvp, sizeof(pv_t)) != 0) {
-		P_IOCTL("lvm_do_pv_create ERROR: copy PV ptr %p (%d bytes)\n",
-			pvp, sizeof(pv_t));
+		P_IOCTL
+		    ("lvm_do_pv_create ERROR: copy PV ptr %p (%d bytes)\n",
+		     pvp, sizeof(pv_t));
 		kfree(pv);
 		return -EFAULT;
 	}
@@ -1773,13 +1863,14 @@
 
 	vg_ptr->pv[p] = pv;
 	return 0;
-} /* lvm_do_pv_create() */
+}				/* lvm_do_pv_create() */
 
 
 /*
  * character device support function physical volume remove
  */
-static int lvm_do_pv_remove(vg_t *vg_ptr, ulong p) {
+static int lvm_do_pv_remove(vg_t * vg_ptr, ulong p)
+{
 	pv_t *pv = vg_ptr->pv[p];
 
 	lvm_fs_remove_pv(vg_ptr, pv);
@@ -1797,37 +1888,68 @@
 }
 
 
-static void __update_hardsectsize(lv_t *lv) {
-	int le, e;
-	int max_hardsectsize = 0, hardsectsize;
-
-	for (le = 0; le < lv->lv_allocated_le; le++) {
-		hardsectsize = get_hardsect_size(lv->lv_current_pe[le].dev);
-		if (hardsectsize == 0)
-			hardsectsize = 512;
-		if (hardsectsize > max_hardsectsize)
-			max_hardsectsize = hardsectsize;
-	}
-
-	/* only perform this operation on active snapshots */
-	if ((lv->lv_access & LV_SNAPSHOT) &&
-	    (lv->lv_status & LV_ACTIVE)) {
-		for (e = 0; e < lv->lv_remap_end; e++) {
-			hardsectsize = get_hardsect_size( lv->lv_block_exception[e].rdev_new);
-			if (hardsectsize == 0)
-				hardsectsize = 512;
-			if (hardsectsize > max_hardsectsize)
+static void __update_hardsectsize(lv_t * lv)
+{
+	int max_hardsectsize = 0, hardsectsize = 0;
+	int p;
+
+	/* Check PVs first to see if they all have same sector size */
+	for (p = 0; p < lv->vg->pv_cur; p++) {
+		pv_t *pv = lv->vg->pv[p];
+		if (pv && (hardsectsize = lvm_sectsize(pv->pv_dev))) {
+			if (max_hardsectsize == 0)
+				max_hardsectsize = hardsectsize;
+			else if (hardsectsize != max_hardsectsize) {
+				P_DEV
+				    ("%s PV[%d] (%s) sector size %d, not %d\n",
+				     lv->lv_name, p, kdevname(pv->pv_dev),
+				     hardsectsize, max_hardsectsize);
+				break;
+			}
+		}
+	}
+
+	/* PVs have different block size, need to check each LE sector size */
+	if (hardsectsize != max_hardsectsize) {
+		int le;
+		for (le = 0; le < lv->lv_allocated_le; le++) {
+			hardsectsize =
+			    lvm_sectsize(lv->lv_current_pe[le].dev);
+			if (hardsectsize > max_hardsectsize) {
+				P_DEV
+				    ("%s LE[%d] (%s) blocksize %d not %d\n",
+				     lv->lv_name, le,
+				     kdevname(lv->lv_current_pe[le].dev),
+				     hardsectsize, max_hardsectsize);
 				max_hardsectsize = hardsectsize;
+			}
+		}
+
+		/* only perform this operation on active snapshots */
+		if ((lv->lv_access & LV_SNAPSHOT) &&
+		    (lv->lv_status & LV_ACTIVE)) {
+			int e;
+			for (e = 0; e < lv->lv_remap_end; e++) {
+				hardsectsize =
+				    lvm_sectsize(lv->lv_block_exception[e].
+						 rdev_new);
+				if (hardsectsize > max_hardsectsize)
+					max_hardsectsize = hardsectsize;
+			}
 		}
 	}
 
+	if (max_hardsectsize == 0)
+		max_hardsectsize = SECTOR_SIZE;
+	P_DEV("hardblocksize for LV %s is %d\n",
+	      kdevname(lv->lv_dev), max_hardsectsize);
 	lvm_hardsectsizes[MINOR(lv->lv_dev)] = max_hardsectsize;
 }
 
 /*
  * character device support function logical volume create
  */
-static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
+static int lvm_do_lv_create(int minor, char *lv_name, lv_t * lv)
 {
 	int e, ret, l, le, l_new, p, size, activate = 1;
 	ulong lv_status_save;
@@ -1855,14 +1977,18 @@
 	else {
 		for (l = 0; l < vg_ptr->lv_max; l++) {
 			if (vg_ptr->lv[l] == NULL)
-				if (l_new == -1) l_new = l;
+				if (l_new == -1)
+					l_new = l;
 		}
 	}
-	if (l_new == -1) return -EPERM;
-	else             l = l_new;
+	if (l_new == -1)
+		return -EPERM;
+	else
+		l = l_new;
 
-	if ((lv_ptr = kmalloc(sizeof(lv_t),GFP_KERNEL)) == NULL) {;
-		printk(KERN_CRIT "%s -- LV_CREATE: kmalloc error LV at line %d\n",
+	if ((lv_ptr = kmalloc(sizeof(lv_t), GFP_KERNEL)) == NULL) {;
+		printk(KERN_CRIT
+		       "%s -- LV_CREATE: kmalloc error LV at line %d\n",
 		       lvm_name, __LINE__);
 		return -ENOMEM;
 	}
@@ -1876,7 +2002,7 @@
 	lv_ptr->lv_snapshot_next = NULL;
 	lv_ptr->lv_block_exception = NULL;
 	lv_ptr->lv_iobuf = NULL;
-       lv_ptr->lv_COW_table_iobuf = NULL;
+	lv_ptr->lv_COW_table_iobuf = NULL;
 	lv_ptr->lv_snapshot_hash_table = NULL;
 	lv_ptr->lv_snapshot_hash_table_size = 0;
 	lv_ptr->lv_snapshot_hash_mask = 0;
@@ -1894,8 +2020,7 @@
 		if ((lv_ptr->lv_current_pe = vmalloc(size)) == NULL) {
 			printk(KERN_CRIT
 			       "%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte "
-			       "at line %d\n",
-			       lvm_name, size, __LINE__);
+			       "at line %d\n", lvm_name, size, __LINE__);
 			P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__);
 			kfree(lv_ptr);
 			vg_ptr->lv[l] = NULL;
@@ -1924,9 +2049,11 @@
 			lv_ptr->lv_snapshot_org =
 			    vg_ptr->lv[LV_BLK(lv_ptr->lv_snapshot_minor)];
 			if (lv_ptr->lv_snapshot_org != NULL) {
-				size = lv_ptr->lv_remap_end * sizeof(lv_block_exception_t);
+				size =
+				    lv_ptr->lv_remap_end *
+				    sizeof(lv_block_exception_t);
 
-				if(!size) {
+				if (!size) {
 					printk(KERN_WARNING
 					       "%s -- zero length exception table requested\n",
 					       lvm_name);
@@ -1934,34 +2061,37 @@
 					return -EINVAL;
 				}
 
-				if ((lv_ptr->lv_block_exception = vmalloc(size)) == NULL) {
+				if (
+				    (lv_ptr->lv_block_exception =
+				     vmalloc(size)) == NULL) {
 					printk(KERN_CRIT
 					       "%s -- lvm_do_lv_create: vmalloc error LV_BLOCK_EXCEPTION "
 					       "of %d byte at line %d\n",
 					       lvm_name, size, __LINE__);
-					P_KFREE("%s -- kfree %d\n", lvm_name,
-						__LINE__);
+					P_KFREE("%s -- kfree %d\n",
+						lvm_name, __LINE__);
 					kfree(lv_ptr);
 					vg_ptr->lv[l] = NULL;
 					return -ENOMEM;
 				}
-				if (copy_from_user(lv_ptr->lv_block_exception, lvbe, size)) {
+				if (copy_from_user
+				    (lv_ptr->lv_block_exception, lvbe,
+				     size)) {
 					vfree(lv_ptr->lv_block_exception);
 					kfree(lv_ptr);
 					vg_ptr->lv[l] = NULL;
 					return -EFAULT;
 				}
 
-				if(lv_ptr->lv_block_exception[0].rsector_org ==
-				   LVM_SNAPSHOT_DROPPED_SECTOR)
-				{
+				if (lv_ptr->lv_block_exception[0].
+				    rsector_org ==
+				    LVM_SNAPSHOT_DROPPED_SECTOR) {
 					printk(KERN_WARNING
-    "%s -- lvm_do_lv_create: snapshot has been dropped and will not be activated\n",
+					       "%s -- lvm_do_lv_create: snapshot has been dropped and will not be activated\n",
 					       lvm_name);
 					activate = 0;
 				}
 
-
 				/* point to the original logical volume */
 				lv_ptr = lv_ptr->lv_snapshot_org;
 
@@ -1971,36 +2101,54 @@
 				   which can be the original logical volume */
 				lv_ptr = vg_ptr->lv[l];
 				/* now lv_ptr points to our new last snapshot logical volume */
-				lv_ptr->lv_current_pe = lv_ptr->lv_snapshot_org->lv_current_pe;
-				lv_ptr->lv_allocated_snapshot_le = lv_ptr->lv_allocated_le;
-				lv_ptr->lv_allocated_le = lv_ptr->lv_snapshot_org->lv_allocated_le;
-				lv_ptr->lv_current_le = lv_ptr->lv_snapshot_org->lv_current_le;
-				lv_ptr->lv_size = lv_ptr->lv_snapshot_org->lv_size;
-				lv_ptr->lv_stripes = lv_ptr->lv_snapshot_org->lv_stripes;
-				lv_ptr->lv_stripesize = lv_ptr->lv_snapshot_org->lv_stripesize;
+				lv_ptr->lv_current_pe =
+				    lv_ptr->lv_snapshot_org->lv_current_pe;
+				lv_ptr->lv_allocated_snapshot_le =
+				    lv_ptr->lv_allocated_le;
+				lv_ptr->lv_allocated_le =
+				    lv_ptr->lv_snapshot_org->
+				    lv_allocated_le;
+				lv_ptr->lv_current_le =
+				    lv_ptr->lv_snapshot_org->lv_current_le;
+				lv_ptr->lv_size =
+				    lv_ptr->lv_snapshot_org->lv_size;
+				lv_ptr->lv_stripes =
+				    lv_ptr->lv_snapshot_org->lv_stripes;
+				lv_ptr->lv_stripesize =
+				    lv_ptr->lv_snapshot_org->lv_stripesize;
 
 				/* Update the VG PE(s) used by snapshot reserve space. */
-				vg_ptr->pe_allocated += lv_ptr->lv_allocated_snapshot_le;
+				vg_ptr->pe_allocated +=
+				    lv_ptr->lv_allocated_snapshot_le;
 
-				if ((ret = lvm_snapshot_alloc(lv_ptr)) != 0)
-				{
+				if ((ret = lvm_snapshot_alloc(lv_ptr)) !=
+				    0) {
 					vfree(lv_ptr->lv_block_exception);
 					kfree(lv_ptr);
 					vg_ptr->lv[l] = NULL;
 					return ret;
 				}
-				for ( e = 0; e < lv_ptr->lv_remap_ptr; e++)
-					lvm_hash_link (lv_ptr->lv_block_exception + e,
-						       lv_ptr->lv_block_exception[e].rdev_org,
-						       lv_ptr->lv_block_exception[e].rsector_org, lv_ptr);
+				for (e = 0; e < lv_ptr->lv_remap_ptr; e++)
+					lvm_hash_link(lv_ptr->
+						      lv_block_exception +
+						      e,
+						      lv_ptr->
+						      lv_block_exception
+						      [e].rdev_org,
+						      lv_ptr->
+						      lv_block_exception
+						      [e].rsector_org,
+						      lv_ptr);
 				/* need to fill the COW exception table data
 				   into the page for disk i/o */
-                               if(lvm_snapshot_fill_COW_page(vg_ptr, lv_ptr)) {
-                                       kfree(lv_ptr);
-                                       vg_ptr->lv[l] = NULL;
-                                       return -EINVAL;
-                               }
-				init_waitqueue_head(&lv_ptr->lv_snapshot_wait);
+				if (lvm_snapshot_fill_COW_page
+				    (vg_ptr, lv_ptr)) {
+					kfree(lv_ptr);
+					vg_ptr->lv[l] = NULL;
+					return -EINVAL;
+				}
+				init_waitqueue_head(&lv_ptr->
+						    lv_snapshot_wait);
 			} else {
 				kfree(lv_ptr);
 				vg_ptr->lv[l] = NULL;
@@ -2011,7 +2159,7 @@
 			vg_ptr->lv[l] = NULL;
 			return -EINVAL;
 		}
-	} /* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */
+	}			/* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */
 
 	lv_ptr = vg_ptr->lv[l];
 	lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = 0;
@@ -2022,6 +2170,7 @@
 	LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead);
 	vg_ptr->lv_cur++;
 	lv_ptr->lv_status = lv_status_save;
+	lv_ptr->vg = vg_ptr;
 
 	__update_hardsectsize(lv_ptr);
 
@@ -2038,22 +2187,24 @@
 
 		down_write(&org->lv_lock);
 		org->lv_access |= LV_SNAPSHOT_ORG;
-		lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; /* this can only hide an userspace bug */
+		lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG;	/* this can only hide an userspace bug */
+
 
 		/* Link in the list of snapshot volumes */
-		for (last = org; last->lv_snapshot_next; last = last->lv_snapshot_next);
+		for (last = org; last->lv_snapshot_next;
+		     last = last->lv_snapshot_next);
 		lv_ptr->lv_snapshot_prev = last;
 		last->lv_snapshot_next = lv_ptr;
 		up_write(&org->lv_lock);
 	}
 
 	/* activate the logical volume */
-	if(activate)
+	if (activate)
 		lv_ptr->lv_status |= LV_ACTIVE;
 	else
 		lv_ptr->lv_status &= ~LV_ACTIVE;
 
-	if ( lv_ptr->lv_access & LV_WRITE)
+	if (lv_ptr->lv_access & LV_WRITE)
 		set_device_ro(lv_ptr->lv_dev, 0);
 	else
 		set_device_ro(lv_ptr->lv_dev, 1);
@@ -2064,13 +2215,10 @@
 		unlockfs(lv_ptr->lv_snapshot_org->lv_dev);
 #endif
 
-	lv_ptr->vg = vg_ptr;
-
 	lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].de =
-		lvm_fs_create_lv(vg_ptr, lv_ptr);
-
+	    lvm_fs_create_lv(vg_ptr, lv_ptr);
 	return 0;
-} /* lvm_do_lv_create() */
+}				/* lvm_do_lv_create() */
 
 
 /*
@@ -2090,7 +2238,8 @@
 			}
 		}
 	}
-	if (l == vg_ptr->lv_max) return -ENXIO;
+	if (l == vg_ptr->lv_max)
+		return -ENXIO;
 
 	lv_ptr = vg_ptr->lv[l];
 #ifdef LVM_TOTAL_RESET
@@ -2113,11 +2262,12 @@
 		 * Atomically make the the snapshot invisible
 		 * to the original lv before playing with it.
 		 */
-		lv_t * org = lv_ptr->lv_snapshot_org;
+		lv_t *org = lv_ptr->lv_snapshot_org;
 		down_write(&org->lv_lock);
 
 		/* remove this snapshot logical volume from the chain */
-		lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next;
+		lv_ptr->lv_snapshot_prev->lv_snapshot_next =
+		    lv_ptr->lv_snapshot_next;
 		if (lv_ptr->lv_snapshot_next != NULL) {
 			lv_ptr->lv_snapshot_next->lv_snapshot_prev =
 			    lv_ptr->lv_snapshot_prev;
@@ -2156,7 +2306,7 @@
 	vg_lv_map[MINOR(lv_ptr->lv_dev)].lv_number = -1;
 
 	/* correct the PE count in PVs if this is not a snapshot
-           logical volume */
+	   logical volume */
 	if (!(lv_ptr->lv_access & LV_SNAPSHOT)) {
 		/* only if this is no snapshot logical volume because
 		   we share the lv_current_pe[] structs with the
@@ -2177,228 +2327,240 @@
 	vg_ptr->lv[l] = NULL;
 	vg_ptr->lv_cur--;
 	return 0;
-} /* lvm_do_lv_remove() */
+}				/* lvm_do_lv_remove() */
 
 
 /*
  * logical volume extend / reduce
  */
-static int __extend_reduce_snapshot(vg_t *vg_ptr, lv_t *old_lv, lv_t *new_lv) {
-        ulong size;
-        lv_block_exception_t *lvbe;
-
-        if (!new_lv->lv_block_exception)
-                return -ENXIO;
-
-        size = new_lv->lv_remap_end * sizeof(lv_block_exception_t);
-        if ((lvbe = vmalloc(size)) == NULL) {
-                printk(KERN_CRIT
-                       "%s -- lvm_do_lv_extend_reduce: vmalloc "
-                       "error LV_BLOCK_EXCEPTION of %lu Byte at line %d\n",
-                       lvm_name, size, __LINE__);
-                return -ENOMEM;
-        }
-
-        if ((new_lv->lv_remap_end > old_lv->lv_remap_end) &&
-            (copy_from_user(lvbe, new_lv->lv_block_exception, size))) {
-                vfree(lvbe);
-                return -EFAULT;
-        }
-        new_lv->lv_block_exception = lvbe;
-
-        if (lvm_snapshot_alloc_hash_table(new_lv)) {
-                vfree(new_lv->lv_block_exception);
-                return -ENOMEM;
-        }
+static int __extend_reduce_snapshot(vg_t * vg_ptr, lv_t * old_lv,
+				    lv_t * new_lv)
+{
+	ulong size;
+	lv_block_exception_t *lvbe;
 
-        return 0;
+	if (!new_lv->lv_block_exception)
+		return -ENXIO;
+
+	size = new_lv->lv_remap_end * sizeof(lv_block_exception_t);
+	if ((lvbe = vmalloc(size)) == NULL) {
+		printk(KERN_CRIT
+		       "%s -- lvm_do_lv_extend_reduce: vmalloc "
+		       "error LV_BLOCK_EXCEPTION of %lu Byte at line %d\n",
+		       lvm_name, size, __LINE__);
+		return -ENOMEM;
+	}
+
+	if ((new_lv->lv_remap_end > old_lv->lv_remap_end) &&
+	    (copy_from_user(lvbe, new_lv->lv_block_exception, size))) {
+		vfree(lvbe);
+		return -EFAULT;
+	}
+	new_lv->lv_block_exception = lvbe;
+
+	if (lvm_snapshot_alloc_hash_table(new_lv)) {
+		vfree(new_lv->lv_block_exception);
+		return -ENOMEM;
+	}
+
+	return 0;
 }
 
-static int __extend_reduce(vg_t *vg_ptr, lv_t *old_lv, lv_t *new_lv) {
-        ulong size, l, p, end;
-        pe_t *pe;
-
-        /* allocate space for new pe structures */
-        size = new_lv->lv_current_le * sizeof(pe_t);
-        if ((pe = vmalloc(size)) == NULL) {
-                printk(KERN_CRIT
-                       "%s -- lvm_do_lv_extend_reduce: "
-                       "vmalloc error LV_CURRENT_PE of %lu Byte at line %d\n",
-                       lvm_name, size, __LINE__);
-                return -ENOMEM;
-        }
-
-        /* get the PE structures from user space */
-        if (copy_from_user(pe, new_lv->lv_current_pe, size)) {
-                if(old_lv->lv_access & LV_SNAPSHOT)
-                        vfree(new_lv->lv_snapshot_hash_table);
-                vfree(pe);
-                return -EFAULT;
-        }
-
-        new_lv->lv_current_pe = pe;
-
-        /* reduce allocation counters on PV(s) */
-        for (l = 0; l < old_lv->lv_allocated_le; l++) {
-                vg_ptr->pe_allocated--;
-                for (p = 0; p < vg_ptr->pv_cur; p++) {
-                        if (vg_ptr->pv[p]->pv_dev ==
-                            old_lv->lv_current_pe[l].dev) {
-                                vg_ptr->pv[p]->pe_allocated--;
-                                break;
-                        }
-                }
-        }
-
-        /* extend the PE count in PVs */
-        for (l = 0; l < new_lv->lv_allocated_le; l++) {
-                vg_ptr->pe_allocated++;
-                for (p = 0; p < vg_ptr->pv_cur; p++) {
-                        if (vg_ptr->pv[p]->pv_dev ==
-                            new_lv->lv_current_pe[l].dev) {
-                                vg_ptr->pv[p]->pe_allocated++;
-                                break;
-                        }
-                }
-        }
-
-        /* save availiable i/o statistic data */
-        if (old_lv->lv_stripes < 2) {   /* linear logical volume */
-                end = min(old_lv->lv_current_le, new_lv->lv_current_le);
-                for (l = 0; l < end; l++) {
-                        new_lv->lv_current_pe[l].reads +=
-                                old_lv->lv_current_pe[l].reads;
-
-                        new_lv->lv_current_pe[l].writes +=
-                                old_lv->lv_current_pe[l].writes;
-                }
-
-        } else {                /* striped logical volume */
-                uint i, j, source, dest, end, old_stripe_size, new_stripe_size;
-
-                old_stripe_size = old_lv->lv_allocated_le / old_lv->lv_stripes;
-                new_stripe_size = new_lv->lv_allocated_le / new_lv->lv_stripes;
-                end = min(old_stripe_size, new_stripe_size);
-
-                for (i = source = dest = 0;
-                     i < new_lv->lv_stripes; i++) {
-                        for (j = 0; j < end; j++) {
-                                new_lv->lv_current_pe[dest + j].reads +=
-                                    old_lv->lv_current_pe[source + j].reads;
-                                new_lv->lv_current_pe[dest + j].writes +=
-                                    old_lv->lv_current_pe[source + j].writes;
-                        }
-                        source += old_stripe_size;
-                        dest += new_stripe_size;
-                }
-        }
+static int __extend_reduce(vg_t * vg_ptr, lv_t * old_lv, lv_t * new_lv)
+{
+	ulong size, l, p, end;
+	pe_t *pe;
+
+	/* allocate space for new pe structures */
+	size = new_lv->lv_current_le * sizeof(pe_t);
+	if ((pe = vmalloc(size)) == NULL) {
+		printk(KERN_CRIT
+		       "%s -- lvm_do_lv_extend_reduce: "
+		       "vmalloc error LV_CURRENT_PE of %lu Byte at line %d\n",
+		       lvm_name, size, __LINE__);
+		return -ENOMEM;
+	}
+
+	/* get the PE structures from user space */
+	if (copy_from_user(pe, new_lv->lv_current_pe, size)) {
+		if (old_lv->lv_access & LV_SNAPSHOT)
+			vfree(new_lv->lv_snapshot_hash_table);
+		vfree(pe);
+		return -EFAULT;
+	}
+
+	new_lv->lv_current_pe = pe;
+
+	/* reduce allocation counters on PV(s) */
+	for (l = 0; l < old_lv->lv_allocated_le; l++) {
+		vg_ptr->pe_allocated--;
+		for (p = 0; p < vg_ptr->pv_cur; p++) {
+			if (vg_ptr->pv[p]->pv_dev ==
+			    old_lv->lv_current_pe[l].dev) {
+				vg_ptr->pv[p]->pe_allocated--;
+				break;
+			}
+		}
+	}
+
+	/* extend the PE count in PVs */
+	for (l = 0; l < new_lv->lv_allocated_le; l++) {
+		vg_ptr->pe_allocated++;
+		for (p = 0; p < vg_ptr->pv_cur; p++) {
+			if (vg_ptr->pv[p]->pv_dev ==
+			    new_lv->lv_current_pe[l].dev) {
+				vg_ptr->pv[p]->pe_allocated++;
+				break;
+			}
+		}
+	}
+
+	/* save availiable i/o statistic data */
+	if (old_lv->lv_stripes < 2) {	/* linear logical volume */
+		end = min(old_lv->lv_current_le, new_lv->lv_current_le);
+		for (l = 0; l < end; l++) {
+			new_lv->lv_current_pe[l].reads +=
+			    old_lv->lv_current_pe[l].reads;
+
+			new_lv->lv_current_pe[l].writes +=
+			    old_lv->lv_current_pe[l].writes;
+		}
+
+	} else {		/* striped logical volume */
+		uint i, j, source, dest, end, old_stripe_size,
+		    new_stripe_size;
+
+		old_stripe_size =
+		    old_lv->lv_allocated_le / old_lv->lv_stripes;
+		new_stripe_size =
+		    new_lv->lv_allocated_le / new_lv->lv_stripes;
+		end = min(old_stripe_size, new_stripe_size);
+
+		for (i = source = dest = 0; i < new_lv->lv_stripes; i++) {
+			for (j = 0; j < end; j++) {
+				new_lv->lv_current_pe[dest + j].reads +=
+				    old_lv->lv_current_pe[source +
+							  j].reads;
+				new_lv->lv_current_pe[dest + j].writes +=
+				    old_lv->lv_current_pe[source +
+							  j].writes;
+			}
+			source += old_stripe_size;
+			dest += new_stripe_size;
+		}
+	}
 
-        return 0;
+	return 0;
 }
 
-static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *new_lv)
+static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t * new_lv)
 {
-        int r;
-        ulong l, e, size;
-        vg_t *vg_ptr = vg[VG_CHR(minor)];
-        lv_t *old_lv;
-        pe_t *pe;
+	int r;
+	ulong l, e, size;
+	vg_t *vg_ptr = vg[VG_CHR(minor)];
+	lv_t *old_lv;
+	pe_t *pe;
 
-        if ((pe = new_lv->lv_current_pe) == NULL)
-                return -EINVAL;
+	if ((pe = new_lv->lv_current_pe) == NULL)
+		return -EINVAL;
 
-        for (l = 0; l < vg_ptr->lv_max; l++)
-                if (vg_ptr->lv[l] && !strcmp(vg_ptr->lv[l]->lv_name, lv_name))
-                        break;
+	for (l = 0; l < vg_ptr->lv_max; l++)
+		if (vg_ptr->lv[l]
+		    && !strcmp(vg_ptr->lv[l]->lv_name, lv_name)) break;
 
-        if (l == vg_ptr->lv_max)
-                return -ENXIO;
+	if (l == vg_ptr->lv_max)
+		return -ENXIO;
 
-        old_lv = vg_ptr->lv[l];
+	old_lv = vg_ptr->lv[l];
 
 	if (old_lv->lv_access & LV_SNAPSHOT) {
 		/* only perform this operation on active snapshots */
 		if (old_lv->lv_status & LV_ACTIVE)
-                r = __extend_reduce_snapshot(vg_ptr, old_lv, new_lv);
-        else
+			r =
+			    __extend_reduce_snapshot(vg_ptr, old_lv,
+						     new_lv);
+		else
 			r = -EPERM;
 
 	} else
-                r = __extend_reduce(vg_ptr, old_lv, new_lv);
+		r = __extend_reduce(vg_ptr, old_lv, new_lv);
 
-        if(r)
-                return r;
+	if (r)
+		return r;
 
-        /* copy relevent fields */
+	/* copy relevent fields */
 	down_write(&old_lv->lv_lock);
 
-        if(new_lv->lv_access & LV_SNAPSHOT) {
-                size = (new_lv->lv_remap_end > old_lv->lv_remap_end) ?
-                        old_lv->lv_remap_ptr : new_lv->lv_remap_end;
-                size *= sizeof(lv_block_exception_t);
-                memcpy(new_lv->lv_block_exception,
-                       old_lv->lv_block_exception, size);
-
-                old_lv->lv_remap_end = new_lv->lv_remap_end;
-                old_lv->lv_block_exception = new_lv->lv_block_exception;
-                old_lv->lv_snapshot_hash_table =
-                        new_lv->lv_snapshot_hash_table;
-                old_lv->lv_snapshot_hash_table_size =
-                        new_lv->lv_snapshot_hash_table_size;
-                old_lv->lv_snapshot_hash_mask =
-                        new_lv->lv_snapshot_hash_mask;
-
-                for (e = 0; e < new_lv->lv_remap_ptr; e++)
-                        lvm_hash_link(new_lv->lv_block_exception + e,
-                                      new_lv->lv_block_exception[e].rdev_org,
-                                    new_lv->lv_block_exception[e].rsector_org,
-                                      new_lv);
-
-        } else {
-
-                vfree(old_lv->lv_current_pe);
-                vfree(old_lv->lv_snapshot_hash_table);
-
-                old_lv->lv_size = new_lv->lv_size;
-                old_lv->lv_allocated_le = new_lv->lv_allocated_le;
-                old_lv->lv_current_le = new_lv->lv_current_le;
-                old_lv->lv_current_pe = new_lv->lv_current_pe;
-                lvm_gendisk.part[MINOR(old_lv->lv_dev)].nr_sects =
-                        old_lv->lv_size;
-                lvm_size[MINOR(old_lv->lv_dev)] = old_lv->lv_size >> 1;
-
-                if (old_lv->lv_access & LV_SNAPSHOT_ORG) {
-                        lv_t *snap;
-                        for(snap = old_lv->lv_snapshot_next; snap;
-                            snap = snap->lv_snapshot_next) {
+	if (new_lv->lv_access & LV_SNAPSHOT) {
+		size = (new_lv->lv_remap_end > old_lv->lv_remap_end) ?
+		    old_lv->lv_remap_ptr : new_lv->lv_remap_end;
+		size *= sizeof(lv_block_exception_t);
+		memcpy(new_lv->lv_block_exception,
+		       old_lv->lv_block_exception, size);
+
+		old_lv->lv_remap_end = new_lv->lv_remap_end;
+		old_lv->lv_block_exception = new_lv->lv_block_exception;
+		old_lv->lv_snapshot_hash_table =
+		    new_lv->lv_snapshot_hash_table;
+		old_lv->lv_snapshot_hash_table_size =
+		    new_lv->lv_snapshot_hash_table_size;
+		old_lv->lv_snapshot_hash_mask =
+		    new_lv->lv_snapshot_hash_mask;
+
+		for (e = 0; e < new_lv->lv_remap_ptr; e++)
+			lvm_hash_link(new_lv->lv_block_exception + e,
+				      new_lv->lv_block_exception[e].
+				      rdev_org,
+				      new_lv->lv_block_exception[e].
+				      rsector_org, new_lv);
+
+	} else {
+
+		vfree(old_lv->lv_current_pe);
+		vfree(old_lv->lv_snapshot_hash_table);
+
+		old_lv->lv_size = new_lv->lv_size;
+		old_lv->lv_allocated_le = new_lv->lv_allocated_le;
+		old_lv->lv_current_le = new_lv->lv_current_le;
+		old_lv->lv_current_pe = new_lv->lv_current_pe;
+		lvm_gendisk.part[MINOR(old_lv->lv_dev)].nr_sects =
+		    old_lv->lv_size;
+		lvm_size[MINOR(old_lv->lv_dev)] = old_lv->lv_size >> 1;
+
+		if (old_lv->lv_access & LV_SNAPSHOT_ORG) {
+			lv_t *snap;
+			for (snap = old_lv->lv_snapshot_next; snap;
+			     snap = snap->lv_snapshot_next) {
 				down_write(&snap->lv_lock);
-                                snap->lv_current_pe = old_lv->lv_current_pe;
-                                snap->lv_allocated_le =
-                                        old_lv->lv_allocated_le;
-                                snap->lv_current_le = old_lv->lv_current_le;
-                                snap->lv_size = old_lv->lv_size;
-
-                                lvm_gendisk.part[MINOR(snap->lv_dev)].nr_sects
-                                        = old_lv->lv_size;
-                                lvm_size[MINOR(snap->lv_dev)] =
-                                        old_lv->lv_size >> 1;
-                                __update_hardsectsize(snap);
+				snap->lv_current_pe =
+				    old_lv->lv_current_pe;
+				snap->lv_allocated_le =
+				    old_lv->lv_allocated_le;
+				snap->lv_current_le =
+				    old_lv->lv_current_le;
+				snap->lv_size = old_lv->lv_size;
+
+				lvm_gendisk.part[MINOR(snap->lv_dev)].
+				    nr_sects = old_lv->lv_size;
+				lvm_size[MINOR(snap->lv_dev)] =
+				    old_lv->lv_size >> 1;
+				__update_hardsectsize(snap);
 				up_write(&snap->lv_lock);
-                        }
-                }
-        }
+			}
+		}
+	}
 
-        __update_hardsectsize(old_lv);
+	__update_hardsectsize(old_lv);
 	up_write(&old_lv->lv_lock);
 
-        return 0;
-} /* lvm_do_lv_extend_reduce() */
+	return 0;
+}				/* lvm_do_lv_extend_reduce() */
 
 
 /*
  * character device support function logical volume status by name
  */
-static int lvm_do_lv_status_byname(vg_t *vg_ptr, void *arg)
+static int lvm_do_lv_status_byname(vg_t * vg_ptr, void *arg)
 {
 	uint l;
 	lv_status_byname_req_t lv_status_byname_req;
@@ -2406,184 +2568,206 @@
 	void *saved_ptr2;
 	lv_t *lv_ptr;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (copy_from_user(&lv_status_byname_req, arg,
 			   sizeof(lv_status_byname_req_t)) != 0)
 		return -EFAULT;
 
-	if (lv_status_byname_req.lv == NULL) return -EINVAL;
+	if (lv_status_byname_req.lv == NULL)
+		return -EINVAL;
 
 	for (l = 0; l < vg_ptr->lv_max; l++) {
 		if ((lv_ptr = vg_ptr->lv[l]) != NULL &&
 		    strcmp(lv_ptr->lv_name,
 			   lv_status_byname_req.lv_name) == 0) {
-		        /* Save usermode pointers */
-		        if (copy_from_user(&saved_ptr1, &lv_status_byname_req.lv->lv_current_pe, sizeof(void*)) != 0)
+			/* Save usermode pointers */
+			if (copy_from_user
+			    (&saved_ptr1,
+			     &lv_status_byname_req.lv->lv_current_pe,
+			     sizeof(void *)) != 0)
 				return -EFAULT;
-			if (copy_from_user(&saved_ptr2, &lv_status_byname_req.lv->lv_block_exception, sizeof(void*)) != 0)
-			        return -EFAULT;
-		        if (copy_to_user(lv_status_byname_req.lv,
-					 lv_ptr,
-					 sizeof(lv_t)) != 0)
+			if (copy_from_user
+			    (&saved_ptr2,
+			     &lv_status_byname_req.lv->lv_block_exception,
+			     sizeof(void *)) != 0)
+				return -EFAULT;
+			if (copy_to_user(lv_status_byname_req.lv,
+					 lv_ptr, sizeof(lv_t)) != 0)
 				return -EFAULT;
-
 			if (saved_ptr1 != NULL) {
 				if (copy_to_user(saved_ptr1,
 						 lv_ptr->lv_current_pe,
 						 lv_ptr->lv_allocated_le *
-				       		 sizeof(pe_t)) != 0)
+						 sizeof(pe_t)) != 0)
 					return -EFAULT;
 			}
 			/* Restore usermode pointers */
-			if (copy_to_user(&lv_status_byname_req.lv->lv_current_pe, &saved_ptr1, sizeof(void*)) != 0)
-			        return -EFAULT;
+			if (copy_to_user
+			    (&lv_status_byname_req.lv->lv_current_pe,
+			     &saved_ptr1, sizeof(void *)) != 0)
+				return -EFAULT;
 			return 0;
 		}
 	}
 	return -ENXIO;
-} /* lvm_do_lv_status_byname() */
+}				/* lvm_do_lv_status_byname() */
 
 
 /*
  * character device support function logical volume status by index
  */
-static int lvm_do_lv_status_byindex(vg_t *vg_ptr,void *arg)
+static int lvm_do_lv_status_byindex(vg_t * vg_ptr, void *arg)
 {
 	lv_status_byindex_req_t lv_status_byindex_req;
 	void *saved_ptr1;
 	void *saved_ptr2;
 	lv_t *lv_ptr;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (copy_from_user(&lv_status_byindex_req, arg,
 			   sizeof(lv_status_byindex_req)) != 0)
 		return -EFAULT;
 
 	if (lv_status_byindex_req.lv == NULL)
 		return -EINVAL;
-	if (lv_status_byindex_req.lv_index <0 ||
-		lv_status_byindex_req.lv_index >= MAX_LV)
+	if (lv_status_byindex_req.lv_index < 0 ||
+	    lv_status_byindex_req.lv_index >= MAX_LV)
 		return -EINVAL;
-	if ( ( lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL)
+	if ((lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL)
 		return -ENXIO;
 
 	/* Save usermode pointers */
-	if (copy_from_user(&saved_ptr1, &lv_status_byindex_req.lv->lv_current_pe, sizeof(void*)) != 0)
-	        return -EFAULT;
-	if (copy_from_user(&saved_ptr2, &lv_status_byindex_req.lv->lv_block_exception, sizeof(void*)) != 0)
-	        return -EFAULT;
-
-	if (copy_to_user(lv_status_byindex_req.lv, lv_ptr, sizeof(lv_t)) != 0)
+	if (copy_from_user
+	    (&saved_ptr1, &lv_status_byindex_req.lv->lv_current_pe,
+	     sizeof(void *)) != 0)
+		return -EFAULT;
+	if (copy_from_user
+	    (&saved_ptr2, &lv_status_byindex_req.lv->lv_block_exception,
+	     sizeof(void *)) != 0)
 		return -EFAULT;
+
+	if (copy_to_user(lv_status_byindex_req.lv, lv_ptr, sizeof(lv_t)) !=
+	    0) return -EFAULT;
 	if (saved_ptr1 != NULL) {
 		if (copy_to_user(saved_ptr1,
 				 lv_ptr->lv_current_pe,
 				 lv_ptr->lv_allocated_le *
-		       		 sizeof(pe_t)) != 0)
-			return -EFAULT;
+				 sizeof(pe_t)) != 0) return -EFAULT;
 	}
 
 	/* Restore usermode pointers */
-	if (copy_to_user(&lv_status_byindex_req.lv->lv_current_pe, &saved_ptr1, sizeof(void *)) != 0)
-	        return -EFAULT;
+	if (copy_to_user
+	    (&lv_status_byindex_req.lv->lv_current_pe, &saved_ptr1,
+	     sizeof(void *)) != 0)
+		return -EFAULT;
 
 	return 0;
-} /* lvm_do_lv_status_byindex() */
+}				/* lvm_do_lv_status_byindex() */
 
 
 /*
  * character device support function logical volume status by device number
  */
-static int lvm_do_lv_status_bydev(vg_t * vg_ptr, void * arg) {
+static int lvm_do_lv_status_bydev(vg_t * vg_ptr, void *arg)
+{
 	int l;
 	lv_status_bydev_req_t lv_status_bydev_req;
 	void *saved_ptr1;
 	void *saved_ptr2;
 	lv_t *lv_ptr;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (copy_from_user(&lv_status_bydev_req, arg,
 			   sizeof(lv_status_bydev_req)) != 0)
 		return -EFAULT;
 
-	for ( l = 0; l < vg_ptr->lv_max; l++) {
-		if ( vg_ptr->lv[l] == NULL) continue;
-		if ( vg_ptr->lv[l]->lv_dev == lv_status_bydev_req.dev) break;
+	for (l = 0; l < vg_ptr->lv_max; l++) {
+		if (vg_ptr->lv[l] == NULL)
+			continue;
+		if (vg_ptr->lv[l]->lv_dev == lv_status_bydev_req.dev)
+			break;
 	}
 
-	if ( l == vg_ptr->lv_max) return -ENXIO;
+	if (l == vg_ptr->lv_max)
+		return -ENXIO;
 	lv_ptr = vg_ptr->lv[l];
 
 	/* Save usermode pointers */
-	if (copy_from_user(&saved_ptr1, &lv_status_bydev_req.lv->lv_current_pe, sizeof(void*)) != 0)
-	        return -EFAULT;
-	if (copy_from_user(&saved_ptr2, &lv_status_bydev_req.lv->lv_block_exception, sizeof(void*)) != 0)
-	        return -EFAULT;
-
-	if (copy_to_user(lv_status_bydev_req.lv, lv_ptr, sizeof(lv_t)) != 0)
+	if (copy_from_user
+	    (&saved_ptr1, &lv_status_bydev_req.lv->lv_current_pe,
+	     sizeof(void *)) != 0)
 		return -EFAULT;
+	if (copy_from_user
+	    (&saved_ptr2, &lv_status_bydev_req.lv->lv_block_exception,
+	     sizeof(void *)) != 0)
+		return -EFAULT;
+
+	if (copy_to_user(lv_status_bydev_req.lv, lv_ptr, sizeof(lv_t)) !=
+	    0) return -EFAULT;
 	if (saved_ptr1 != NULL) {
 		if (copy_to_user(saved_ptr1,
 				 lv_ptr->lv_current_pe,
 				 lv_ptr->lv_allocated_le *
-		       		 sizeof(pe_t)) != 0)
-			return -EFAULT;
+				 sizeof(pe_t)) != 0) return -EFAULT;
 	}
 	/* Restore usermode pointers */
-	if (copy_to_user(&lv_status_bydev_req.lv->lv_current_pe, &saved_ptr1, sizeof(void *)) != 0)
-	        return -EFAULT;
+	if (copy_to_user
+	    (&lv_status_bydev_req.lv->lv_current_pe, &saved_ptr1,
+	     sizeof(void *)) != 0)
+		return -EFAULT;
 
 	return 0;
-} /* lvm_do_lv_status_bydev() */
+}				/* lvm_do_lv_status_bydev() */
 
 
 /*
  * character device support function rename a logical volume
  */
-static int lvm_do_lv_rename(vg_t *vg_ptr, lv_req_t *lv_req, lv_t *lv)
+static int lvm_do_lv_rename(vg_t * vg_ptr, lv_req_t * lv_req, lv_t * lv)
 {
 	int l = 0;
 	int ret = 0;
 	lv_t *lv_ptr = NULL;
 
-	for (l = 0; l < vg_ptr->lv_max; l++)
-	{
-		if ( (lv_ptr = vg_ptr->lv[l]) == NULL) continue;
-		if (lv_ptr->lv_dev == lv->lv_dev)
-		{
+	for (l = 0; l < vg_ptr->lv_max; l++) {
+		if ((lv_ptr = vg_ptr->lv[l]) == NULL)
+			continue;
+		if (lv_ptr->lv_dev == lv->lv_dev) {
 			lvm_fs_remove_lv(vg_ptr, lv_ptr);
-			strncpy(lv_ptr->lv_name,
-				lv_req->lv_name,
+			strncpy(lv_ptr->lv_name, lv_req->lv_name,
 				NAME_LEN);
 			lvm_fs_create_lv(vg_ptr, lv_ptr);
 			break;
 		}
 	}
-	if (l == vg_ptr->lv_max) ret = -ENODEV;
+	if (l == vg_ptr->lv_max)
+		ret = -ENODEV;
 
 	return ret;
-} /* lvm_do_lv_rename */
+}				/* lvm_do_lv_rename */
 
 
 /*
  * character device support function physical volume change
  */
-static int lvm_do_pv_change(vg_t *vg_ptr, void *arg)
+static int lvm_do_pv_change(vg_t * vg_ptr, void *arg)
 {
 	uint p;
 	pv_t *pv_ptr;
 	struct block_device *bd;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (copy_from_user(&pv_change_req, arg,
-			   sizeof(pv_change_req)) != 0)
-		return -EFAULT;
+			   sizeof(pv_change_req)) != 0) return -EFAULT;
 
 	for (p = 0; p < vg_ptr->pv_max; p++) {
 		pv_ptr = vg_ptr->pv[p];
 		if (pv_ptr != NULL &&
-		    strcmp(pv_ptr->pv_name,
-			       pv_change_req.pv_name) == 0) {
+		    strcmp(pv_ptr->pv_name, pv_change_req.pv_name) == 0) {
 
 			bd = pv_ptr->bd;
 			if (copy_from_user(pv_ptr,
@@ -2599,53 +2783,52 @@
 		}
 	}
 	return -ENXIO;
-} /* lvm_do_pv_change() */
+}				/* lvm_do_pv_change() */
 
 /*
  * character device support function get physical volume status
  */
-static int lvm_do_pv_status(vg_t *vg_ptr, void *arg)
+static int lvm_do_pv_status(vg_t * vg_ptr, void *arg)
 {
 	uint p;
 	pv_t *pv_ptr;
 
-	if (vg_ptr == NULL) return -ENXIO;
+	if (vg_ptr == NULL)
+		return -ENXIO;
 	if (copy_from_user(&pv_status_req, arg,
-			   sizeof(pv_status_req)) != 0)
-		return -EFAULT;
+			   sizeof(pv_status_req)) != 0) return -EFAULT;
 
 	for (p = 0; p < vg_ptr->pv_max; p++) {
 		pv_ptr = vg_ptr->pv[p];
 		if (pv_ptr != NULL &&
-		    strcmp(pv_ptr->pv_name,
-			       pv_status_req.pv_name) == 0) {
+		    strcmp(pv_ptr->pv_name, pv_status_req.pv_name) == 0) {
 			if (copy_to_user(pv_status_req.pv,
-					 pv_ptr,
-				         sizeof(pv_t)) != 0)
+					 pv_ptr, sizeof(pv_t)) != 0)
 				return -EFAULT;
 			return 0;
 		}
 	}
 	return -ENXIO;
-} /* lvm_do_pv_status() */
+}				/* lvm_do_pv_status() */
+
 
 /*
  * character device support function flush and invalidate all buffers of a PV
  */
 static int lvm_do_pv_flush(void *arg)
 {
-       pv_flush_req_t pv_flush_req;
+	pv_flush_req_t pv_flush_req;
 
-       if (copy_from_user(&pv_flush_req, arg,
-                          sizeof(pv_flush_req)) != 0)
-               return -EFAULT;
+	if (copy_from_user(&pv_flush_req, arg, sizeof(pv_flush_req)) != 0)
+		return -EFAULT;
 
-       fsync_dev(pv_flush_req.pv_dev);
-       invalidate_buffers(pv_flush_req.pv_dev);
+	fsync_dev(pv_flush_req.pv_dev);
+	invalidate_buffers(pv_flush_req.pv_dev);
 
-       return 0;
+	return 0;
 }
 
+
 /*
  * support function initialize gendisk variables
  */
@@ -2668,13 +2851,15 @@
 	hardsect_size[MAJOR_NR] = lvm_hardsectsizes;
 
 	return;
-} /* lvm_gen_init() */
+}				/* lvm_gen_init() */
 
 
 
 /* Must have down_write(_pe_lock) when we enqueue buffers */
-static void _queue_io(struct buffer_head *bh, int rw) {
-	if (bh->b_reqnext) BUG();
+static void _queue_io(struct buffer_head *bh, int rw)
+{
+	if (bh->b_reqnext)
+		BUG();
 	bh->b_reqnext = _pe_requests;
 	_pe_requests = bh;
 }
@@ -2708,17 +2893,19 @@
 	}
 }
 
+
 /*
  * we must open the pv's before we use them
  */
-static int _open_pv(pv_t *pv) {
+static int _open_pv(pv_t * pv)
+{
 	int err;
 	struct block_device *bd;
 
 	if (!(bd = bdget(kdev_t_to_nr(pv->pv_dev))))
 		return -ENOMEM;
 
-	err = blkdev_get(bd, FMODE_READ|FMODE_WRITE, 0, BDEV_FILE);
+	err = blkdev_get(bd, FMODE_READ | FMODE_WRITE, 0, BDEV_FILE);
 	if (err)
 		return err;
 
@@ -2726,7 +2913,8 @@
 	return 0;
 }
 
-static void _close_pv(pv_t *pv) {
+static void _close_pv(pv_t * pv)
+{
 	if (pv) {
 		struct block_device *bdev = pv->bd;
 		pv->bd = NULL;
@@ -2735,15 +2923,21 @@
 	}
 }
 
+
 static unsigned long _sectors_to_k(unsigned long sect)
 {
-	if(SECTOR_SIZE > 1024) {
+	if (SECTOR_SIZE > 1024) {
 		return sect * (SECTOR_SIZE / 1024);
 	}
 
 	return sect / (1024 / SECTOR_SIZE);
 }
 
+MODULE_AUTHOR("Heinz Mauelshagen, Sistina Software");
+MODULE_DESCRIPTION("Logical Volume Manager");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
 module_init(lvm_init);
 module_exit(lvm_cleanup);
-MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/md/md.c linux/drivers/md/md.c
--- linux.orig/drivers/md/md.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/md/md.c	2002-07-20 01:08:30.000000000 +0000
@@ -3332,6 +3332,10 @@
 	wake_up(&mddev->recovery_wait);
 	if (!ok) {
 		// stop recovery, signal do_sync ....
+		if (mddev->pers->stop_resync)
+			mddev->pers->stop_resync(mddev);
+		if (mddev->recovery_running)
+			md_interrupt_thread(md_recovery_thread);
 	}
 }
 
@@ -3486,7 +3490,7 @@
 	 * this also signals 'finished resyncing' to md_stop
 	 */
 out:
-	wait_event(mddev->recovery_wait, atomic_read(&mddev->recovery_active)==0);
+	wait_disk_event(mddev->recovery_wait, atomic_read(&mddev->recovery_active)==0);
 	up(&mddev->resync_sem);
 out_nolock:
 	mddev->curr_resync = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/md/raid1.c linux/drivers/md/raid1.c
--- linux.orig/drivers/md/raid1.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/md/raid1.c	2002-07-20 01:08:21.000000000 +0000
@@ -269,8 +269,9 @@
 static int raid1_grow_buffers (raid1_conf_t *conf, int cnt)
 {
 	int i = 0;
+	struct raid1_bh *head = NULL, **tail;
+	tail = &head;
 
-	md_spin_lock_irq(&conf->device_lock);
 	while (i < cnt) {
 		struct raid1_bh *r1_bh;
 		struct page *page;
@@ -287,24 +288,36 @@
 		memset(r1_bh, 0, sizeof(*r1_bh));
 		r1_bh->bh_req.b_page = page;
 		r1_bh->bh_req.b_data = page_address(page);
-		r1_bh->next_r1 = conf->freebuf;
-		conf->freebuf = r1_bh;
+		*tail = r1_bh;
+		r1_bh->next_r1 = NULL;
+		tail = & r1_bh->next_r1;
 		i++;
 	}
+	/* this lock probably isn't needed, as at the time when
+	 * we are allocating buffers, nobody else will be touching the
+	 * freebuf list.  But it doesn't hurt....
+	 */
+	md_spin_lock_irq(&conf->device_lock);
+	*tail = conf->freebuf;
+	conf->freebuf = head;
 	md_spin_unlock_irq(&conf->device_lock);
 	return i;
 }
 
 static void raid1_shrink_buffers (raid1_conf_t *conf)
 {
+	struct raid1_bh *head;
 	md_spin_lock_irq(&conf->device_lock);
-	while (conf->freebuf) {
-		struct raid1_bh *r1_bh = conf->freebuf;
-		conf->freebuf = r1_bh->next_r1;
+	head = conf->freebuf;
+	conf->freebuf = NULL;
+	md_spin_unlock_irq(&conf->device_lock);
+
+	while (head) {
+		struct raid1_bh *r1_bh = head;
+		head = r1_bh->next_r1;
 		__free_page(r1_bh->bh_req.b_page);
 		kfree(r1_bh);
 	}
-	md_spin_unlock_irq(&conf->device_lock);
 }
 
 static int raid1_map (mddev_t *mddev, kdev_t *rdev)
@@ -825,7 +838,7 @@
 	conf->start_ready = conf->start_pending;
 	wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
 	conf->start_active =conf->start_ready = conf->start_pending = conf->start_future;
-	conf->start_future = mddev->sb->size+1;
+	conf->start_future = (mddev->sb->size<<1)+1;
 	conf->cnt_pending = conf->cnt_future;
 	conf->cnt_future = 0;
 	conf->phase = conf->phase ^1;
@@ -849,6 +862,14 @@
 	mdk_rdev_t *spare_rdev, *failed_rdev;
 
 	print_raid1_conf(conf);
+
+	switch (state) {
+	case DISKOP_SPARE_ACTIVE:
+	case DISKOP_SPARE_INACTIVE:
+		/* need to wait for pending sync io before locking device */
+		close_sync(conf);
+	}
+
 	md_spin_lock_irq(&conf->device_lock);
 	/*
 	 * find the disk ...
@@ -951,7 +972,11 @@
 	 * Deactivate a spare disk:
 	 */
 	case DISKOP_SPARE_INACTIVE:
-		close_sync(conf);
+		if (conf->start_future > 0) {
+			MD_BUG();
+			err = -EBUSY;
+			break;
+		}
 		sdisk = conf->mirrors + spare_disk;
 		sdisk->operational = 0;
 		sdisk->write_only = 0;
@@ -964,7 +989,11 @@
 	 * property)
 	 */
 	case DISKOP_SPARE_ACTIVE:
-		close_sync(conf);
+		if (conf->start_future > 0) {
+			MD_BUG();
+			err = -EBUSY;
+			break;
+		}
 		sdisk = conf->mirrors + spare_disk;
 		fdisk = conf->mirrors + failed_disk;
 
@@ -1123,9 +1152,12 @@
 	struct raid1_bh *r1_bh;
 	struct buffer_head *bh;
 	unsigned long flags;
-	mddev_t *mddev;
+	raid1_conf_t *conf = data;
+	mddev_t *mddev = conf->mddev;
 	kdev_t dev;
 
+	if (mddev->sb_dirty)
+		md_update_sb(mddev);
 
 	for (;;) {
 		md_spin_lock_irqsave(&retry_list_lock, flags);
@@ -1136,8 +1168,6 @@
 		md_spin_unlock_irqrestore(&retry_list_lock, flags);
 
 		mddev = r1_bh->mddev;
-		if (mddev->sb_dirty)
-			md_update_sb(mddev);
 		bh = &r1_bh->bh_req;
 		switch(r1_bh->cmd) {
 		case SPECIAL:
@@ -1148,7 +1178,6 @@
 				int i, sum_bhs = 0;
 				int disks = MD_SB_DISKS;
 				struct buffer_head *bhl, *mbh;
-				raid1_conf_t *conf;
 				
 				conf = mddev_to_conf(mddev);
 				bhl = raid1_alloc_bh(conf, conf->raid_disks); /* don't really need this many */
@@ -1328,23 +1357,25 @@
 	int bsize;
 	int disk;
 	int block_nr;
+	int buffs;
 
+	if (!sector_nr) {
+		/* we want enough buffers to hold twice the window of 128*/
+		buffs = 128 *2 / (PAGE_SIZE>>9);
+		buffs = raid1_grow_buffers(conf, buffs);
+		if (buffs < 2)
+			goto nomem;
+		conf->window = buffs*(PAGE_SIZE>>9)/2;
+	}
 	spin_lock_irq(&conf->segment_lock);
 	if (!sector_nr) {
 		/* initialize ...*/
-		int buffs;
 		conf->start_active = 0;
 		conf->start_ready = 0;
 		conf->start_pending = 0;
 		conf->start_future = 0;
 		conf->phase = 0;
-		/* we want enough buffers to hold twice the window of 128*/
-		buffs = 128 *2 / (PAGE_SIZE>>9);
-		buffs = raid1_grow_buffers(conf, buffs);
-		if (buffs < 2)
-			goto nomem;
 		
-		conf->window = buffs*(PAGE_SIZE>>9)/2;
 		conf->cnt_future += conf->cnt_done+conf->cnt_pending;
 		conf->cnt_done = conf->cnt_pending = 0;
 		if (conf->cnt_ready || conf->cnt_active)
@@ -1429,7 +1460,6 @@
 
 nomem:
 	raid1_shrink_buffers(conf);
-	spin_unlock_irq(&conf->segment_lock);
 	return -ENOMEM;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/radio/radio-sf16fmi.c linux/drivers/media/radio/radio-sf16fmi.c
--- linux.orig/drivers/media/radio/radio-sf16fmi.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/media/radio/radio-sf16fmi.c	2002-07-20 01:08:32.000000000 +0000
@@ -85,23 +85,12 @@
 {
         int myport = dev->port;
 	unsigned long freq = dev->curfreq;
-	int i;
 	
 	down(&lock);
-	
 	outbits(16, RSF16_ENCODE(freq), myport);
 	outbits(8, 0xC0, myport);
-	for(i=0; i< 100; i++)
-	{
-		udelay(1400);
-		if(current->need_resched)
-			schedule();
-	}
-/* If this becomes allowed use it ... 	
 	current->state = TASK_UNINTERRUPTIBLE;
 	schedule_timeout(HZ/7);
-*/	
-
 	up(&lock);
 	if (dev->curvol) fmi_unmute(myport);
 	return 0;
@@ -112,22 +101,13 @@
 	int val;
 	int res;
 	int myport = dev->port;
-	int i;
 	
 	down(&lock);
 	val = dev->curvol ? 0x08 : 0x00;	/* unmute/mute */
 	outb(val, myport);
 	outb(val | 0x10, myport);
-	for(i=0; i< 100; i++)
-	{
-		udelay(1400);
-		if(current->need_resched)
-			schedule();
-	}
-/* If this becomes allowed use it ... 	
 	current->state = TASK_UNINTERRUPTIBLE;
 	schedule_timeout(HZ/7);
-*/	
 	res = (int)inb(myport+1);
 	outb(val, myport);
 	
@@ -324,7 +304,7 @@
 	if (io < 0)
 		io = isapnp_fmi_probe();
 	if (io < 0) {
-		printk(KERN_ERR "radio-sf16fmi: No PnP card found.");
+		printk(KERN_ERR "radio-sf16fmi: No PnP card found.\n");
 		return io;
 	}
 	if (!request_region(io, 2, "radio-sf16fmi")) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/radio/radio-zoltrix.c linux/drivers/media/radio/radio-zoltrix.c
--- linux.orig/drivers/media/radio/radio-zoltrix.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/media/radio/radio-zoltrix.c	2002-07-20 01:08:36.000000000 +0000
@@ -23,6 +23,7 @@
  *		(can detect if station is in stereo)
  *	      - Added unmute function
  *	      - Reworked ioctl functions
+ * 2002-07-15 - Fix Stereo typo
  */
 
 #include <linux/module.h>	/* Modules                        */
@@ -280,7 +281,7 @@
 			struct video_audio v;
 			memset(&v, 0, sizeof(v));
 			v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
-			v.mode != zol_is_stereo(zol)
+			v.mode |= zol_is_stereo(zol)
 				? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
 			v.volume = zol->curvol * 4096;
 			v.step = 4096;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/bttv-cards.c linux/drivers/media/video/bttv-cards.c
--- linux.orig/drivers/media/video/bttv-cards.c	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/bttv-cards.c	2002-07-20 01:08:36.000000000 +0000
@@ -39,9 +39,9 @@
 #include "tuner.h"
 
 /* fwd decl */
+static void boot_msp34xx(struct bttv *btv, int pin);
 static void hauppauge_eeprom(struct bttv *btv);
 static void avermedia_eeprom(struct bttv *btv);
-
 static void init_PXC200(struct bttv *btv);
 #if 0
 static void init_tea5757(struct bttv *btv);
@@ -55,6 +55,9 @@
 static void gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set);
 static void winfast2000_audio(struct bttv *btv, struct video_audio *v, int set);
 static void pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set);
+static void fv2000s_audio(struct bttv *btv, struct video_audio *v, int set);
+static void windvr_audio(struct bttv *btv, struct video_audio *v, int set);
+static void rv605_muxsel(struct bttv *btv, unsigned int input);
 
 /* config variables */
 static int triton1=0;
@@ -77,7 +80,8 @@
 MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
 		 "[enable bug compatibility for triton1 + others]");
 MODULE_PARM(vsfx,"i");
-MODULE_PARM_DESC(vsfx,"set VSFX pci config bit [yet another chipset flaw workaround]");
+MODULE_PARM_DESC(vsfx,"set VSFX pci config bit "
+		 "[yet another chipset flaw workaround]");
 MODULE_PARM(no_overlay,"i");
 MODULE_PARM(card,"1-4i");
 MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
@@ -151,7 +155,7 @@
 	{ 0x00041461, BTTV_AVERMEDIA98,   "AVerMedia TVCapture 98" },
 
 	{ 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" },
-	{ 0x300214ff, BTTV_PHOEBE_TVMAS,  "Phoebe TV Master" },
+	{ 0x300214ff, BTTV_PHOEBE_TVMAS,  "Phoebe TV Master (CPH060)" },
 
 	{ 0x1117153b, BTTV_TERRATVALUE,   "Terratec TValue" },
 	{ 0x1118153b, BTTV_TERRATVALUE,   "Terratec TValue" },
@@ -161,6 +165,7 @@
 	{ 0x1127153b, BTTV_TERRATV,       "Terratec TV+"    },
 	{ 0x1134153b, BTTV_TERRATVALUE,   "Terratec TValue" },
 	{ 0x1135153b, BTTV_TERRATVALUER,  "Terratec TValue Radio" },
+	{ 0x5018153b, BTTV_TERRATVALUE,   "Terratec TValue" },
 
 	{ 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
 	{ 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
@@ -168,12 +173,14 @@
 	{ 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
 
     	{ 0x010115cb, BTTV_GMV1,          "AG GMV1" },
-	{ 0x010114c7, BTTV_MODTEC_205,    "Modular Technology PCTV" },
+	{ 0x010114c7, BTTV_MODTEC_205,    "Modular Technology MM205 PCTV" },
 	{ 0x18501851, BTTV_CHRONOS_VS2,   "Flyvideo 98 (LR50)/ Chronos Video Shuttle II" },
 	{ 0x18511851, BTTV_FLYVIDEO98EZ,  "Flyvideo 98EZ (LR51)/ CyberMail AV" },
 	{ 0x18521852, BTTV_TYPHOON_TVIEW, "Flyvideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
 	{ 0x10b42636, BTTV_HAUPPAUGE878,  "STB ???" },
 	{ 0x217d6606, BTTV_WINFAST2000,   "Leadtek WinFast TV 2000" },
+	{ 0x03116000, BTTV_SENSORAY311,   "Sensoray 311" },
+	{ 0x00790e11, BTTV_WINDVR,        "Canopus WinDVR PCI" },
 
 	{ 0, -1, NULL }
 };
@@ -276,8 +283,8 @@
 },{
 
 /* ---- card 0x08 ---------------------------------- */
-	name:		"Fly Video II (Bt848)",
-	video_inputs:	3,
+	name:		"FlyVideo II (Bt848) LR26",
+	video_inputs:	4,
 	audio_inputs:	1,
 	tuner:		0,
 	svhs:		2,
@@ -285,9 +292,10 @@
 	muxsel:		{ 2, 3, 1, 1},
 	audiomux:	{ 0, 0xc00, 0x800, 0x400, 0xc00, 0},
 	needs_tvaudio:	1,
+	pll:		PLL_28,
 	tuner_type:	-1,
 },{
-	name:		"TurboTV",
+	name:		"IXMicro TurboTV",
 	video_inputs:	3,
 	audio_inputs:	1,
 	tuner:		0,
@@ -346,14 +354,14 @@
 	pll:		PLL_28,
 	tuner_type:	-1,
 },{
-	name:		"Aimslab VHX",
+	name:		"Aimslab Video Highway Xtreme (VHX)",
 	video_inputs:	3,
 	audio_inputs:	1,
 	tuner:		0,
 	svhs:		2,
 	gpiomask:	7,
 	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 1, 2, 3, 4},
+	audiomux:	{ 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
 	needs_tvaudio:	1,
 	tuner_type:	-1,
 },{
@@ -393,6 +401,7 @@
 	needs_tvaudio:	1,
 	tuner_type:	-1,
 	audio_hook:	winview_audio,
+	has_radio:	1,
 },{
 	name:		"AVEC Intercapture",
 	video_inputs:	3,
@@ -438,7 +447,7 @@
 	pll:		PLL_28,
 	tuner_type:	TUNER_PHILIPS_PAL_I,
 },{
-	name:		"Phoebe Tv Master + FM",
+	name:		"Phoebe Tv Master + FM (CPH050)",
 	video_inputs:	3,
 	audio_inputs:	1,
 	tuner:		0,
@@ -752,6 +761,7 @@
 	gpiomask:	0x1f0000,
 	muxsel:		{ 2, 3, 1, 1},
 	audiomux:	{ 0xe2ffff, 0xebffff, 0, 0, 0xe0ffff, 0xe2ffff },
+	needs_tvaudio:	1,
 	no_msp34xx:	1,
 	pll:		PLL_35,
 	tuner_type:	1,
@@ -788,7 +798,7 @@
 	video_inputs:	4,
 	audio_inputs:	1,
 	tuner:		0,
-	svhs:		2,
+	svhs:		3,
 	gpiomask:	0xAA0000,
 	muxsel:		{ 2,3,1,1 },
 	audiomux:	{ 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000  },
@@ -860,7 +870,7 @@
 },{
 	/* Miguel Angel Alvarez <maacruz@navegalia.com>
 	   old Easy TV BT848 version (model CPH031) */
-	name:           "BESTBUY Easy TV",
+	name:           "BESTBUY Easy TV (CPH031)",
 	video_inputs:	4,
 	audio_inputs:   1,
 	tuner:          0,
@@ -890,7 +900,7 @@
 	/* This is the ultimate cheapo capture card 
 	 * just a BT848A on a small PCB!
 	 * Steve Hosgood <steve@equiinet.com> */
-	name:           "GrandTec 'Grand Video Capture'",
+	name:           "GrandTec 'Grand Video Capture' (Bt848)",
 	video_inputs:   2,
 	audio_inputs:   0,
 	tuner:          -1,
@@ -904,7 +914,7 @@
 	tuner_type:     -1,
 },{
         /* Daniel Herrington <daniel.herrington@home.com> */
-        name:           "Phoebe TV Master Only (No FM)",
+        name:           "Phoebe TV Master Only (No FM) CPH060",
         video_inputs:   3,
         audio_inputs:   1,
         tuner:          0,
@@ -917,7 +927,7 @@
         tuner_type:     TUNER_TEMIC_4036FY5_NTSC,
 },{
 	/* Matti Mottus <mottus@physic.ut.ee> */
-	name:		"TV Capturer",
+	name:		"TV Capturer (CPH03X)",
 	video_inputs:	4,
 	audio_inputs:	1,
 	tuner:		0,
@@ -931,7 +941,7 @@
 
 /* ---- card 0x3c ---------------------------------- */
 	/* Philip Blundell <philb@gnu.org> */
-	name:           "MM100PCTV",
+	name:           "Modular Technology MM100PCTV",
 	video_inputs:   2,
 	audio_inputs:   2,
 	gpiomask:       11,
@@ -977,7 +987,7 @@
 	tuner:		0,
 	svhs:		2,
 	gpiomask:	0xf03f,
-	muxsel:		{ 2, 3, 0, 1},
+	muxsel:		{ 2, 3, 1, 0 },
 	audiomux:	{ 0xbffe, 0, 0xbfff, 0, 0xbffe},
 	pll:		PLL_28,
 	tuner_type:	TUNER_TEMIC_4006FN5_MULTI_PAL,
@@ -1005,7 +1015,13 @@
 	svhs:           2,
 	gpiomask:	0x18e0,
 	muxsel:		{ 2, 3, 0, 1},
-	audiomux:	{ 0,0x18e0,0x1000,0x1000,0x1080, 0x1080 },
+			/* Radio changed from 1e80 to 0x800 to make
+			   Flyvideo2000S in .hu happy (gm)*/
+			/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
+	audiomux:	{ 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
+	audio_hook:	fv2000s_audio,
+	no_msp34xx:	1,
+	no_tda9875:	1,
 	needs_tvaudio:  1,
 	pll:            PLL_28,
 	tuner_type:     5,
@@ -1047,11 +1063,12 @@
         tuner:          0,
         svhs:           -1,
         gpiomask:       0x4f8a00,
-	                // 0x100000: 1=MSP enabled (0=disable again)
-			// 0x010000: somehow influences tuner picture quality (?)
-        audiomux:       {0x947fff, 0x987fff,0x947fff,0x947fff},
-                        //tvtuner, radio,   external,internal,mute,stereo
-        muxsel:         { 2, 3 ,0 ,1}, /* tuner, Composit, SVid, Composit-on-Svid-adapter*/
+	// 0x100000: 1=MSP enabled (0=disable again)
+	// 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC)
+        audiomux:       {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
+	// tvtuner, radio,   external,internal, mute,  stereo
+	/* tuner, Composit, SVid, Composit-on-Svid-adapter*/
+        muxsel:         { 2, 3 ,0 ,1},
         tuner_type:     TUNER_MT2032,
 	pll:		PLL_28,
 	has_radio:	1,
@@ -1106,8 +1123,84 @@
 	tuner_type:	-1,
 	audio_hook:	pvbt878p9b_audio,
 	has_radio:	1,
-}
-};
+},{
+	/* Clay Kunz <ckunz@mail.arc.nasa.gov> */
+	/* you must jumper JP5 for the card to work */
+	name:           "Sensoray 311",
+	video_inputs:   5,
+	audio_inputs:   0,
+	tuner:          -1,
+	svhs:           4,
+	gpiomask:       0,
+	muxsel:         { 2, 3, 1, 0, 0},
+	audiomux:       { 0 },
+	needs_tvaudio:  0,
+	tuner_type:     -1,
+},{
+	/* Miguel Freitas <miguel@cetuc.puc-rio.br> */
+	name:           "RemoteVision MX (RV605)",
+	video_inputs:   16,
+	audio_inputs:   0,
+	tuner:          0,
+	svhs:           0,
+	gpiomask:       0x00,
+	gpiomask2:      0x07ff,
+	muxsel:         { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
+			  0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
+	no_msp34xx:     1,
+	no_tda9875:     1,
+	tuner_type:     -1,
+	muxsel_hook:    rv605_muxsel,
+},{
+        name:           "Powercolor MTV878/ MTV878R/ MTV878F",
+        video_inputs:   3,
+        audio_inputs:   2, 
+        svhs:           2,
+        gpiomask:       0x1C800F,  // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset
+        muxsel:         { 2, 1, 1, },
+        audiomux:       { 0, 1, 2, 2, 4 },
+        needs_tvaudio:  0,
+        tuner_type:     TUNER_PHILIPS_PAL,
+	pll:		PLL_28,
+	has_radio:	1,
+},{
+
+/* ---- card 0x4c ---------------------------------- */
+        /* Masaki Suzuki <masaki@btree.org> */
+        name:           "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
+        video_inputs:   3,
+        audio_inputs:   1,
+        tuner:          0,
+        svhs:           2,
+        gpiomask:       0x140007,
+        muxsel:         { 2, 3, 1, 1 },
+        audiomux:       { 0, 1, 2, 3, 4, 0 },
+        tuner_type:     TUNER_PHILIPS_NTSC,
+        audio_hook:     windvr_audio,
+},{
+        name:           "GrandTec Multi Capture Card (Bt878)",
+        video_inputs:   4,
+        audio_inputs:   0,
+        tuner:          -1,
+        svhs:           -1,
+        gpiomask:       0,
+        muxsel:         { 2, 3, 1, 0 },
+        audiomux:       { 0 },
+        needs_tvaudio:  0,
+        no_msp34xx:     1,
+        pll:            PLL_28,
+        tuner_type:     -1,
+},{
+	/* http://www.aopen.com/products/video/va1000.htm */
+	name:           "AOPEN VA1000",
+	video_inputs:   3, /* coax, AV, s-vid */
+	audio_inputs:   1,
+	tuner:          0,
+	tuner_type:     TUNER_LG_PAL, /* actually TP18PSB12P (PAL B/G) */
+	audiomux:       { 2, 0, 0, 0 },
+	muxsel:         { 2, 3, 1, 0 },
+	pll:            PLL_28,
+}};
 
 const int bttv_num_tvcards = (sizeof(bttv_tvcards)/sizeof(struct tvcard));
 
@@ -1195,12 +1288,58 @@
  * (most) board specific initialisations goes here
  */
 
+static void flyvideo_gpio(struct bttv *btv)
+{
+	int gpio,outbits;
+	int tuner=-1,ttype;
+	
+	outbits = btread(BT848_GPIO_OUT_EN);
+	btwrite(0x00, BT848_GPIO_OUT_EN);
+	udelay(8);  // without this we would see the 0x1800 mask
+	gpio=btread(BT848_GPIO_DATA);
+	btwrite(outbits, BT848_GPIO_OUT_EN);
+	// all cards provide GPIO info, some have an additional eeprom
+	
+	// lowest 3 bytes are remote control codes (no handshake needed)
+	ttype=(gpio&0x0f0000)>>16;
+	switch(ttype) {
+	case 0: tuner=4; // None
+		break;
+	case 4: tuner=5; // Philips PAL
+		break;
+	case 6: tuner=37; // LG PAL (newer TAPC series)
+		break;
+	case 0xC: tuner=3; // Philips SECAM(+PAL)
+		break;
+	default:
+		printk(KERN_INFO "bttv%d: flyvideo_gpio: unknown tuner type.\n", btv->nr);
+	}
+	
+	printk(KERN_INFO "bttv%d: Flyvideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", 
+	       btv->nr,
+	       gpio&0x400000? "yes":"no",
+	       gpio&0x800000? "yes":"no", tuner, gpio);
+	
+	btv->tuner_type = tuner;
+	btv->has_radio = gpio&0x400000? 1:0; 
+}
+
 int miro_tunermap[] = { 0,6,2,3,   4,5,6,0,  3,0,4,5,  5,2,16,1,
 			14,2,17,1, 4,1,4,3,  1,2,16,1, 4,4,4,4 };
 int miro_fmtuner[]  = { 0,0,0,0,   0,0,0,0,  0,0,0,0,  0,0,0,1,
 			1,1,1,1,   1,1,1,0,  0,0,0,0,  0,0,0,0 };
 
-void __devinit bttv_init_card(struct bttv *btv)
+/* initialization part one -- before registering i2c bus */
+void __devinit bttv_init_card1(struct bttv *btv)
+{
+        if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878)
+                boot_msp34xx(btv,5);
+	if (btv->type == BTTV_VOODOOTV_FM)
+		boot_msp34xx(btv,20);
+}
+
+/* initialization part one -- after registering i2c bus */
+void __devinit bttv_init_card2(struct bttv *btv)
 {
 	/* miro/pinnacle */
         if (btv->type == BTTV_MIRO      ||
@@ -1246,6 +1385,15 @@
 #endif
 	}
 
+	if (btv->type == BTTV_FLYVIDEO_98    ||
+	    btv->type == BTTV_FLYVIDEO       ||
+	    btv->type == BTTV_TYPHOON_TVIEW  ||
+	    btv->type == BTTV_CHRONOS_VS2    ||
+	    btv->type == BTTV_FLYVIDEO_98FM  ||
+	    btv->type == BTTV_FLYVIDEO2000   ||
+	    btv->type == BTTV_FLYVIDEO98EZ)
+		flyvideo_gpio(btv);
+
         if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878) {
 		/* pick up some config infos from the eeprom */
 		bttv_readee(btv,eeprom_data,0xa0);
@@ -1449,22 +1597,24 @@
 		       btv->tuner_type, radio ? "yes" : "no");
 }
 
-// AVermedia specific stuff...
-// from  bktr_card.c
+
+/* ----------------------------------------------------------------------- */
+/* AVermedia specific stuff, from  bktr_card.c                             */
+
 int tuner_0_table[] = {
         TUNER_PHILIPS_NTSC,  TUNER_PHILIPS_PAL,
         TUNER_PHILIPS_PAL,   TUNER_PHILIPS_PAL,
         TUNER_PHILIPS_PAL,   TUNER_PHILIPS_PAL,
         TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
         TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL};
-/*
+#if 0
 int tuner_0_fm_table[] = {
         PHILIPS_FR1236_NTSC,  PHILIPS_FR1216_PAL,
         PHILIPS_FR1216_PAL,   PHILIPS_FR1216_PAL,
         PHILIPS_FR1216_PAL,   PHILIPS_FR1216_PAL,
         PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM,
         PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};
-*/
+#endif
 
 int tuner_1_table[] = {
         TUNER_TEMIC_NTSC,  TUNER_TEMIC_PAL,
@@ -1475,11 +1625,12 @@
 
 static void __devinit avermedia_eeprom(struct bttv *btv)
 {
-        int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
+        int tuner_make,tuner_tv_fm,tuner_format,tuner=0,remote;
 
 	tuner_make   = (eeprom_data[0x41] & 0x7);
         tuner_tv_fm  = (eeprom_data[0x41] & 0x18) >> 3;
         tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
+	remote       = (eeprom_data[0x42] & 0x01);
 
 	if (tuner_make == 0 || tuner_make == 2)
 		if(tuner_format <=9)
@@ -1492,11 +1643,32 @@
 		btv->nr,eeprom_data[0x41],eeprom_data[0x42]);
 	if(tuner) {
 		btv->tuner_type=tuner;
-		printk("%d\n",tuner);
+		printk("%d",tuner);
 	} else
-		printk("Unknown type\n");
+		printk("Unknown type");
+	printk(" radio:%s remote control:%s\n",
+		tuner_tv_fm?"yes":"no",
+		remote?"yes":"no");
 }
 
+/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
+void bttv_tda9880_setnorm(struct bttv *btv, int norm)
+{
+	// fix up our card entry
+	if(norm==VIDEO_MODE_NTSC) {
+		bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff;
+		bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff;
+		dprintk("bttv_tda9880_setnorm to NTSC\n");
+	}
+	else {
+	        bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff;
+                bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff;
+		dprintk("bttv_tda9880_setnorm to PAL\n");
+	}
+	// set GPIO according
+	btaor(bttv_tvcards[btv->type].audiomux[btv->audio],
+              ~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
+}
 
 
 /*
@@ -1506,7 +1678,7 @@
  * Hauppauge:  pin  5
  * Voodoo:     pin 20
  */
-void __devinit bttv_boot_msp34xx(struct bttv *btv, int pin)
+static void __devinit boot_msp34xx(struct bttv *btv, int pin)
 {
 	int mask = (1 << pin);
 
@@ -1918,10 +2090,116 @@
 		}
 	} else {
 		v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
-			  VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+			VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
 	}
 }
 
+/*
+ * Dariusz Kowalewski <darekk@automex.pl>
+ * sound control for FlyVideo 2000S (with tda9874 decoder) 
+ * based on pvbt878p9b_audio() - this is not tested, please fix!!!
+ */
+static void
+fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
+{
+	unsigned int val = 0xffff;
+
+#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
+	if (btv->radio_user)
+		return;
+#else
+	if (btv->radio)
+		return;
+#endif
+	if (set) {
+		if (v->mode & VIDEO_SOUND_MONO)	{
+			val = 0x0000;
+		}
+		if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
+		    || (v->mode & VIDEO_SOUND_STEREO)) {
+			val = 0x1080; //-dk-???: 0x0880, 0x0080, 0x1800 ...
+		}
+		if (val != 0xffff) {
+			btaor(val, ~0x1800, BT848_GPIO_DATA);
+			if (bttv_gpio)
+				bttv_gpio_tracking(btv,"fv2000s");
+		}
+	} else {
+		v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
+			VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+	}
+}
+
+/*
+ * sound control for Canopus WinDVR PCI
+ * Masaki Suzuki <masaki@btree.org>
+ */
+static void
+windvr_audio(struct bttv *btv, struct video_audio *v, int set)
+{
+        unsigned long val = 0;
+
+        if (set) {
+                if (v->mode & VIDEO_SOUND_MONO)
+                        val = 0x040000;
+                if (v->mode & VIDEO_SOUND_LANG1)
+                        val = 0;
+                if (v->mode & VIDEO_SOUND_LANG2)
+                        val = 0x100000;
+                if (v->mode & VIDEO_SOUND_STEREO)
+                        val = 0;
+                if (val) {
+                        btaor(val, ~0x140000, BT848_GPIO_DATA);
+                        if (bttv_gpio)
+                                bttv_gpio_tracking(btv,"windvr");
+                }
+        } else {
+                v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
+                          VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+        }
+}
+
+/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas]
+ *
+ * This is needed because rv605 don't use a normal multiplex, but a crosspoint
+ * switch instead (CD22M3494E). This IC can have multiple active connections
+ * between Xn (input) and Yn (output) pins. We need to clear any existing
+ * connection prior to establish a new one, pulsing the STROBE pin.
+ *
+ * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin.
+ * GPIO pins are wired as:
+ *  GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroler)
+ *  GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroler)
+ *  GPIO[7]   - DATA (xpoint)    - P1[7] (microcontroler)
+ *  GPIO[8]   -                  - P3[5] (microcontroler)
+ *  GPIO[9]   - RESET (xpoint)   - P3[6] (microcontroler)
+ *  GPIO[10]  - STROBE (xpoint)  - P3[7] (microcontroler)
+ *  GPINTR    -                  - P3[4] (microcontroler)
+ *
+ * The microcontroler is a 80C32 like. It should be possible to change xpoint
+ * configuration either directly (as we are doing) or using the microcontroler
+ * which is also wired to I2C interface. I have no further info on the
+ * microcontroler features, one would need to disassembly the firmware.
+ * note: the vendor refused to give any information on this product, all
+ *       that stuff was found using a multimeter! :)
+ */
+static void rv605_muxsel(struct bttv *btv, unsigned int input)
+{
+	/* reset all conections */
+	btaor(0x200,~0x200, BT848_GPIO_DATA);
+	mdelay(1);
+	btaor(0x000,~0x200, BT848_GPIO_DATA);
+	mdelay(1);
+
+	/* create a new conection */
+	btaor(0x080,~0x480, BT848_GPIO_DATA);
+	btaor(0x480,~0x480, BT848_GPIO_DATA);
+	mdelay(1);
+	btaor(0x080,~0x480, BT848_GPIO_DATA);
+	mdelay(1);
+}
+
+
 /* ----------------------------------------------------------------------- */
 /* motherboard chipset specific stuff                                      */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- linux.orig/drivers/media/video/bttv-driver.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/media/video/bttv-driver.c	2002-07-20 01:08:39.000000000 +0000
@@ -37,7 +37,6 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <linux/sched.h>
-#include <asm/segment.h>
 #include <linux/types.h>
 #include <linux/wrapper.h>
 #include <linux/interrupt.h>
@@ -70,6 +69,9 @@
 static unsigned int gbufsize = BTTV_MAX_FBUF;
 static unsigned int combfilter = 0;
 static unsigned int lumafilter = 0;
+static unsigned int automute = 1;
+static unsigned int chroma_agc = 0;
+static unsigned int adc_crush = 1;
 static int video_nr = -1;
 static int radio_nr = -1;
 static int vbi_nr = -1;
@@ -96,8 +98,15 @@
 MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (64 max)");
 MODULE_PARM(gbufsize,"i");
 MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
+
 MODULE_PARM(combfilter,"i");
 MODULE_PARM(lumafilter,"i");
+MODULE_PARM(automute,"i");
+MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");
+MODULE_PARM(chroma_agc,"i");
+MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)");
+MODULE_PARM(adc_crush,"i");
+MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)");
 
 MODULE_PARM(video_nr,"i");
 MODULE_PARM(radio_nr,"i");
@@ -279,7 +288,7 @@
 static char *audio_modes[] = { "audio: tuner", "audio: radio", "audio: extern",
 			       "audio: intern", "audio: off" };
 
-static void audio(struct bttv *btv, int mode, int no_irq_context)
+static void audio(struct bttv *btv, int mode)
 {
 	btaor(bttv_tvcards[btv->type].gpiomask, ~bttv_tvcards[btv->type].gpiomask,
               BT848_GPIO_OUT_EN);
@@ -313,12 +322,12 @@
               ~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,audio_modes[mode]);
-	if (no_irq_context)
+	if (!in_interrupt())
 		bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(mode));
 }
 
 
-extern inline void bt848_dma(struct bttv *btv, uint state)
+static inline void bt848_dma(struct bttv *btv, uint state)
 {
 	if (state)
 		btor(3, BT848_GPIO_DMA_CTL);
@@ -425,18 +434,16 @@
 
 static void bt848_muxsel(struct bttv *btv, unsigned int input)
 {
-
-#if 0 /* seems no card uses this ... */
+        /* needed by RemoteVideo MX */
 	btaor(bttv_tvcards[btv->type].gpiomask2,~bttv_tvcards[btv->type].gpiomask2,
               BT848_GPIO_OUT_EN);
-#endif
 
 	/* This seems to get rid of some synchronization problems */
 	btand(~(3<<5), BT848_IFORM);
-	mdelay(10); 
-        
+	mdelay(10);
+
 	input %= bttv_tvcards[btv->type].video_inputs;
-	if (input==bttv_tvcards[btv->type].svhs) 
+	if (input==bttv_tvcards[btv->type].svhs)
 	{
 		btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
 		btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
@@ -446,20 +453,25 @@
 		btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
 		btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
 	}
-	btaor((bttv_tvcards[btv->type].muxsel[input&7]&3)<<5, ~(3<<5), BT848_IFORM);
-	audio(btv, (input!=bttv_tvcards[btv->type].tuner) ? 
-              AUDIO_EXTERN : AUDIO_TUNER, 1);
 
-#if 0 /* seems no card uses this ... */
+	btaor((bttv_tvcards[btv->type].muxsel[input]&3)<<5, ~(3<<5), BT848_IFORM);
+	audio(btv, (input!=bttv_tvcards[btv->type].tuner) ?
+              AUDIO_EXTERN : AUDIO_TUNER);
+
 	btaor(bttv_tvcards[btv->type].muxsel[input]>>4,
 		~bttv_tvcards[btv->type].gpiomask2, BT848_GPIO_DATA);
+
+	/* card specific hook */
+	if( bttv_tvcards[btv->type].muxsel_hook )
+		bttv_tvcards[btv->type].muxsel_hook ( btv, input );
+
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,"muxsel");
-#endif
+
 }
 
 
-struct tvnorm 
+struct tvnorm
 {
         u32 Fsc;
         u16 swidth, sheight; /* scaled standard width, height */
@@ -582,7 +594,7 @@
 #define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int))
 
 static int make_rawrisctab(struct bttv *btv, unsigned int *ro,
-                            unsigned int *re, unsigned int *vbuf)
+			   unsigned int *re, unsigned int *vbuf)
 {
         unsigned long line;
 	unsigned long bpl=1024;		/* bytes per line */
@@ -1054,8 +1066,7 @@
 }
 
 
-static void bt848_set_geo(struct bttv *btv,
-			  int no_irq_context)
+static void bt848_set_geo(struct bttv *btv)
 {
 	u16 ewidth, eheight, owidth, oheight;
 	u16 format, bswap;
@@ -1070,7 +1081,7 @@
 	btwrite(1, BT848_VBI_PACK_DEL);
 
         btv->pll.pll_ofreq = tvn->Fsc;
-	if (no_irq_context)
+	if (!in_interrupt())
 		set_pll(btv);
 
 	btv->win.interlace = (btv->win.height>tvn->sheight/2) ? 1 : 0;
@@ -1162,7 +1173,7 @@
 	else
 	        btor(BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
 
-        bt848_set_geo(btv,1);
+        bt848_set_geo(btv);
 }
 
 /*
@@ -1194,7 +1205,7 @@
 	if (mp->height*mp->width*fmtbppx2[palette2fmt[mp->format]&0x0f]/2
 	    > gbufsize)
 		return -EINVAL;
-	if(-1 == palette2fmt[mp->format])
+	if (-1 == palette2fmt[mp->format])
 		return -EINVAL;
 
 	/*
@@ -1352,7 +1363,7 @@
 	spin_lock_irqsave(&btv->s_lock, irq_flags);
 	btv->errors = 0;
 	btv->needs_restart = 0;
-	bt848_set_geo(btv,0);
+	bt848_set_geo(btv);
 	bt848_set_risc_jmps(btv,-1);
 	spin_unlock_irqrestore(&btv->s_lock, irq_flags);
 }
@@ -1452,17 +1463,17 @@
 /* ioctls and supporting functions */
 /***********************************/
 
-extern inline void bt848_bright(struct bttv *btv, uint bright)
+static inline void bt848_bright(struct bttv *btv, uint bright)
 {
 	btwrite(bright&0xff, BT848_BRIGHT);
 }
 
-extern inline void bt848_hue(struct bttv *btv, uint hue)
+static inline void bt848_hue(struct bttv *btv, uint hue)
 {
 	btwrite(hue&0xff, BT848_HUE);
 }
 
-extern inline void bt848_contrast(struct bttv *btv, uint cont)
+static inline void bt848_contrast(struct bttv *btv, uint cont)
 {
 	unsigned int conthi;
 
@@ -1472,7 +1483,7 @@
 	btaor(conthi, ~4, BT848_O_CONTROL);
 }
 
-extern inline void bt848_sat_u(struct bttv *btv, unsigned long data)
+static inline void bt848_sat_u(struct bttv *btv, unsigned long data)
 {
 	u32 datahi;
 
@@ -1495,7 +1506,6 @@
 /*
  *	ioctl routine
  */
- 
 
 static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
@@ -1573,6 +1583,8 @@
 		bt848_muxsel(btv, v.channel);
 		btv->channel=v.channel;
 		if (btv->win.norm != v.norm) {
+			if(btv->type== BTTV_VOODOOTV_FM)
+				bttv_tda9880_setnorm(btv,v.norm);
 			btv->win.norm = v.norm;
 			make_vbitab(btv);
 			spin_lock_irqsave(&btv->s_lock, irq_flags);
@@ -1638,10 +1650,12 @@
 	case VIDIOCSPICT:
 	{
 		struct video_picture p;
-		if(copy_from_user(&p, arg,sizeof(p)))
+		if (copy_from_user(&p, arg,sizeof(p)))
 			return -EFAULT;
 		if (p.palette > PALETTEFMT_MAX)
 			return -EINVAL;
+		if (-1 == palette2fmt[p.palette])
+			return -EINVAL;
 		down(&btv->lock);
 		/* We want -128 to 127 we get 0-65535 */
 		bt848_bright(btv, (p.brightness>>8)-128);
@@ -1875,7 +1889,7 @@
 			return -EFAULT;
 		down(&btv->lock);
 		if(v.flags&VIDEO_AUDIO_MUTE)
-			audio(btv, AUDIO_MUTE, 1);
+			audio(btv, AUDIO_MUTE);
 		/* One audio source per tuner -- huh? <GA> */
 		if(v.audio<0 || v.audio >= bttv_tvcards[btv->type].audio_inputs) {
 			up(&btv->lock);
@@ -1883,7 +1897,7 @@
 		}
 		/* bt848_muxsel(btv,v.audio); */
 		if(!(v.flags&VIDEO_AUDIO_MUTE))
-			audio(btv, AUDIO_UNMUTE, 1);
+			audio(btv, AUDIO_UNMUTE);
 
 		bttv_call_i2c_clients(btv,cmd,&v);
 		
@@ -2368,6 +2382,12 @@
 			flags |= 0x03;
 		if (btv->vbi_on)
 			flags |= 0x0c;
+#if 0
+		/* Hmm ... */
+		if ((0 != btv->risc_cap_even) ||
+		    (0 != btv->risc_cap_odd))
+			flags |= 0x0c;
+#endif
 	}
 
 	if (bttv_debug > 1)
@@ -2467,15 +2487,19 @@
 
 static int __devinit init_video_dev(struct bttv *btv)
 {
-	audio(btv, AUDIO_MUTE, 1);
+	audio(btv, AUDIO_MUTE);
         
 	if(do_video_register(&btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
 		return -1;
+	printk(KERN_INFO "bttv%d: registered device video%d\n",
+	       btv->nr,btv->video_dev.minor & 0x1f);
 	if(do_video_register(&btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 
         {
 	        video_unregister_device(&btv->video_dev);
 		return -1;
 	}
+	printk(KERN_INFO "bttv%d: registered device vbi%d\n",
+	       btv->nr,btv->vbi_dev.minor & 0x1f);
 	if (btv->has_radio)
 	{
 		if(do_video_register(&btv->radio_dev, VFL_TYPE_RADIO, radio_nr)<0) 
@@ -2484,13 +2508,15 @@
 		        video_unregister_device(&btv->video_dev);
 			return -1;
 		}
+		printk(KERN_INFO "bttv%d: registered device radio%d\n",
+		       btv->nr,btv->radio_dev.minor & 0x1f);
 	}
         return 1;
 }
 
 static int __devinit init_bt848(struct bttv *btv)
 {
-	int j;
+	int j,val;
  	unsigned long irq_flags;
 
 	btv->user=0; 
@@ -2592,8 +2618,8 @@
 
 	btwrite(0x20, BT848_E_VSCALE_HI);
 	btwrite(0x20, BT848_O_VSCALE_HI);
-	btwrite(/*BT848_ADC_SYNC_T|*/
-		BT848_ADC_RESERVED|BT848_ADC_CRUSH, BT848_ADC);
+	btwrite(BT848_ADC_RESERVED | (adc_crush ? BT848_ADC_CRUSH : 0),
+		BT848_ADC);
 
 	if (lumafilter) {
 		btwrite(0, BT848_E_CONTROL);
@@ -2608,8 +2634,9 @@
 	btv->picture.hue=128<<8;
 	btv->picture.contrast=0xd8<<7;
 
-	btwrite(0x00, BT848_E_SCLOOP);
-	btwrite(0x00, BT848_O_SCLOOP);
+	val = chroma_agc ? BT848_SCLOOP_CAGC : 0;
+        btwrite(val, BT848_E_SCLOOP);
+        btwrite(val, BT848_O_SCLOOP);
 
 	/* clear interrupt status */
 	btwrite(0xfffffUL, BT848_INT_STAT);
@@ -2633,17 +2660,14 @@
 	spin_unlock_irqrestore(&btv->s_lock, irq_flags);
 
 	/* needs to be done before i2c is registered */
-        if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878)
-                bttv_boot_msp34xx(btv,5);
-	if (btv->type == BTTV_VOODOOTV_FM)
-		bttv_boot_msp34xx(btv,20);
+	bttv_init_card1(btv);
 
 	/* register i2c */
         btv->tuner_type=-1;
         init_bttv_i2c(btv);
 
 	/* some card-specific stuff (needs working i2c) */
-	bttv_init_card(btv);
+	bttv_init_card2(btv);
 
 	/*
 	 *	Now add the template and register the device unit.
@@ -2722,7 +2746,7 @@
 				btand(~15, BT848_GPIO_DMA_CTL);
 				btwrite(virt_to_bus(btv->risc_jmp+2),
 					BT848_RISC_STRT_ADD);
-				bt848_set_geo(btv,0);
+				bt848_set_geo(btv);
 				bt848_set_risc_jmps(btv,-1);
 				spin_unlock(&btv->s_lock);
 			} else {
@@ -2764,14 +2788,14 @@
                                         btv->risc_cap_odd  = btv->gbuf[btv->gq_grab].ro;
 					btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
 					bt848_set_risc_jmps(btv,-1);
-					bt848_set_geo(btv,0);
+					bt848_set_geo(btv);
 					btwrite(BT848_COLOR_CTL_GAMMA,
 						BT848_COLOR_CTL);
 				} else {
                                         btv->risc_cap_odd  = 0;
 					btv->risc_cap_even = 0;
 					bt848_set_risc_jmps(btv,-1);
-                                        bt848_set_geo(btv,0);
+                                        bt848_set_geo(btv);
 					btwrite(btv->fb_color_ctl | BT848_COLOR_CTL_GAMMA,
 						BT848_COLOR_CTL);
 				}
@@ -2790,18 +2814,18 @@
 				btv->risc_cap_odd  = btv->gbuf[btv->gq_grab].ro;
 				btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
 				bt848_set_risc_jmps(btv,-1);
-				bt848_set_geo(btv,0);
+				bt848_set_geo(btv);
 				btwrite(BT848_COLOR_CTL_GAMMA,
 					BT848_COLOR_CTL);
 				spin_unlock(&btv->s_lock);
 			}
 		}
 
-		if (astat&BT848_INT_HLOCK) {
+		if (automute && (astat&BT848_INT_HLOCK)) {
 			if ((dstat&BT848_DSTATUS_HLOC) || (btv->radio))
-				audio(btv, AUDIO_ON,0);
+				audio(btv, AUDIO_ON);
 			else
-				audio(btv, AUDIO_OFF,0);
+				audio(btv, AUDIO_OFF);
 		}
     
 		count++;
@@ -2869,7 +2893,7 @@
         if (btv->vbibuf)
                 vfree((void *) btv->vbibuf);
 
-        free_irq(btv->irq,btv);
+        free_irq(btv->dev->irq,btv);
         DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%p.\n", btv->bt848_mem));
         if (btv->bt848_mem)
                 iounmap(btv->bt848_mem);
@@ -2904,6 +2928,8 @@
         unsigned int cmd;
 #endif
 
+	if (bttv_num == BTTV_MAX)
+		return -ENOMEM;
 	printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
 
         btv=&bttvs[bttv_num];
@@ -2926,10 +2952,17 @@
 	memcpy(&btv->radio_dev,&radio_template,sizeof(radio_template));
 	
         btv->id=dev->device;
-        btv->irq=dev->irq;
 	btv->bt848_adr=pci_resource_start(dev,0);
-	if (pci_enable_device(dev))
+	if (pci_enable_device(dev)) {
+                printk(KERN_WARNING "bttv%d: Can't enable device.\n",
+		       btv->nr);
+		return -EIO;
+	}
+        if (pci_set_dma_mask(dev, 0xffffffff)) {
+                printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
+		       btv->nr);
 		return -EIO;
+        }
 	if (!request_mem_region(pci_resource_start(dev,0),
 				pci_resource_len(dev,0),
 				"bttv")) {
@@ -2946,7 +2979,7 @@
                bttv_num,btv->id, btv->revision, dev->bus->number,
 	       PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
         printk("irq: %d, latency: %d, memory: 0x%lx\n",
-	       btv->irq, lat, btv->bt848_adr);
+	       btv->dev->irq, lat, btv->bt848_adr);
 	
 	bttv_idcard(btv);
 
@@ -2967,7 +3000,7 @@
         /* clear interrupt mask */
 	btwrite(0, BT848_INT_MASK);
 
-        result = request_irq(btv->irq, bttv_irq,
+        result = request_irq(btv->dev->irq, bttv_irq,
                              SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
         if (result==-EINVAL) 
         {
@@ -2977,7 +3010,7 @@
         }
         if (result==-EBUSY)
         {
-                printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
+                printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->dev->irq);
 		goto fail1;
         }
         if (result < 0) 
@@ -3000,7 +3033,7 @@
         return 0;
 
  fail2:
-        free_irq(btv->irq,btv);
+        free_irq(btv->dev->irq,btv);
  fail1:
 	release_mem_region(pci_resource_start(btv->dev,0),
 			   pci_resource_len(btv->dev,0));
@@ -3028,7 +3061,7 @@
         remove:   bttv_remove,
 };
 
-int bttv_init_module(void)
+static int bttv_init_module(void)
 {
 	bttv_num = 0;
 
@@ -3049,7 +3082,7 @@
 	return pci_module_init(&bttv_pci_driver);
 }
 
-void bttv_cleanup_module(void)
+static void bttv_cleanup_module(void)
 {
 	pci_unregister_driver(&bttv_pci_driver);
 	return;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/bttv.h linux/drivers/media/video/bttv.h
--- linux.orig/drivers/media/video/bttv.h	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/bttv.h	2002-07-20 01:08:26.000000000 +0000
@@ -87,7 +87,9 @@
 #define BTTV_PV_BT878P_PLUS 0x46
 #define BTTV_FLYVIDEO98EZ   0x47
 #define BTTV_PV_BT878P_9B   0x48
-
+#define BTTV_SENSORAY311    0x49
+#define BTTV_RV605          0x4a
+#define BTTV_WINDVR         0x4c
 
 /* i2c address list */
 #define I2C_TSA5522        0xc2
@@ -95,7 +97,7 @@
 #define I2C_TDA8425        0x82
 #define I2C_TDA9840        0x84
 #define I2C_TDA9850        0xb6 /* also used by 9855,9873 */
-#define I2C_TDA9874A       0xb0 /* also used by 9875 */
+#define I2C_TDA9874        0xb0 /* also used by 9875 */
 #define I2C_TDA9875        0xb0
 #define I2C_HAUPEE         0xa0
 #define I2C_STBEE          0xae
@@ -123,7 +125,7 @@
         int tuner;
         int svhs;
         u32 gpiomask;
-        u32 muxsel[8];
+        u32 muxsel[16];
         u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
         u32 gpiomask2;   /* GPIO MUX mask */
 
@@ -141,6 +143,7 @@
 	int tuner_type;
 	int has_radio;
 	void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
+	void (*muxsel_hook)(struct bttv *btv, unsigned int input);
 };
 
 extern struct tvcard bttv_tvcards[];
@@ -148,11 +151,12 @@
 
 /* identification / initialization of the card */
 extern void bttv_idcard(struct bttv *btv);
-extern void bttv_init_card(struct bttv *btv);
+extern void bttv_init_card1(struct bttv *btv);
+extern void bttv_init_card2(struct bttv *btv);
 
 /* card-specific funtions */
 extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern void bttv_boot_msp34xx(struct bttv *btv, int pin);
+extern void bttv_tda9880_setnorm(struct bttv *btv, int norm);
 
 /* kernel cmd line parse helper */
 extern int bttv_parse(char *str, int max, int *vals);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/bttvp.h linux/drivers/media/video/bttvp.h
--- linux.orig/drivers/media/video/bttvp.h	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/bttvp.h	2002-07-20 01:08:33.000000000 +0000
@@ -25,7 +25,7 @@
 #ifndef _BTTVP_H_
 #define _BTTVP_H_
 
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,83)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,91)
 
 
 #include <linux/types.h>
@@ -136,7 +136,6 @@
         unsigned int nr;
 	unsigned short id;
 	struct pci_dev *dev;
-	unsigned int irq;          /* IRQ used by Bt848 card */
 	unsigned char revision;
 	unsigned long bt848_adr;      /* bus address of IO mem returned by PCI BIOS */
 	unsigned char *bt848_mem;   /* pointer to mapped IO memory */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/bw-qcam.c linux/drivers/media/video/bw-qcam.c
--- linux.orig/drivers/media/video/bw-qcam.c	2001-10-11 16:14:32.000000000 +0000
+++ linux/drivers/media/video/bw-qcam.c	2002-07-20 01:08:29.000000000 +0000
@@ -89,27 +89,27 @@
 MODULE_PARM(video_nr,"i");
 #endif
 
-extern __inline__ int read_lpstatus(struct qcam_device *q)
+static inline int read_lpstatus(struct qcam_device *q)
 {
 	return parport_read_status(q->pport);
 }
 
-extern __inline__ int read_lpcontrol(struct qcam_device *q)
+static inline int read_lpcontrol(struct qcam_device *q)
 {
 	return parport_read_control(q->pport);
 }
 
-extern __inline__ int read_lpdata(struct qcam_device *q)
+static inline int read_lpdata(struct qcam_device *q)
 {
 	return parport_read_data(q->pport);
 }
 
-extern __inline__ void write_lpdata(struct qcam_device *q, int d)
+static inline void write_lpdata(struct qcam_device *q, int d)
 {
 	parport_write_data(q->pport, d);
 }
 
-extern __inline__ void write_lpcontrol(struct qcam_device *q, int d)
+static inline void write_lpcontrol(struct qcam_device *q, int d)
 {
 	parport_write_control(q->pport, d);
 }
@@ -506,7 +506,7 @@
    the supplied buffer.  It returns the number of bytes read,
    or -1 on error. */
 
-extern __inline__ int qc_readbytes(struct qcam_device *q, char buffer[])
+static inline int qc_readbytes(struct qcam_device *q, char buffer[])
 {
 	int ret=1;
 	unsigned int hi, lo;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/id.h linux/drivers/media/video/id.h
--- linux.orig/drivers/media/video/id.h	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/id.h	2002-07-20 01:08:36.000000000 +0000
@@ -24,6 +24,12 @@
 #ifndef  I2C_DRIVERID_TDA7432
 # define I2C_DRIVERID_TDA7432 I2C_DRIVERID_EXP0+6
 #endif
-#ifndef  I2C_DRIVERID_TDA9874A
-# define I2C_DRIVERID_TDA9874A I2C_DRIVERID_EXP0+7
+#ifndef  I2C_DRIVERID_TDA9874
+# define I2C_DRIVERID_TDA9874 I2C_DRIVERID_EXP0+7
 #endif
+
+/* algorithms */
+#ifndef I2C_ALGO_SAA7134
+# define I2C_ALGO_SAA7134 0x090000
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/meye.c linux/drivers/media/video/meye.c
--- linux.orig/drivers/media/video/meye.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/media/video/meye.c	2002-07-20 01:08:23.000000000 +0000
@@ -115,77 +115,29 @@
 /* Memory allocation routines (stolen from bttv-driver.c)                   */
 /****************************************************************************/
 
-#define MDEBUG(x)	do {} while (0)
-/* #define MDEBUG(x)	x */
-
-/* Given PGD from the address space's page table, return the kernel
- * virtual mapping of the physical memory mapped at ADR.
- */
-static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) {
-        unsigned long ret = 0UL;
-	pmd_t *pmd;
-	pte_t *ptep, pte;
-  
-	if (!pgd_none(*pgd)) {
-                pmd = pmd_offset(pgd, adr);
-                if (!pmd_none(*pmd)) {
-                        ptep = pte_offset(pmd, adr);
-                        pte = *ptep;
-                        if(pte_present(pte)) {
-				ret = (unsigned long)page_address(pte_page(pte));
-				ret |= (adr & (PAGE_SIZE - 1));
-				
-			}
-                }
-        }
-        MDEBUG(printk("uv2kva(%lx-->%lx)\n", adr, ret));
-	return ret;
-}
-
-static inline unsigned long uvirt_to_bus(unsigned long adr) {
-        unsigned long kva, ret;
-
-        kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
-	ret = virt_to_bus((void *)kva);
-        MDEBUG(printk("uv2b(%lx-->%lx)\n", adr, ret));
-        return ret;
-}
-
-static inline unsigned long kvirt_to_bus(unsigned long adr) {
-        unsigned long va, kva, ret;
-
-        va = VMALLOC_VMADDR(adr);
-        kva = uvirt_to_kva(pgd_offset_k(va), va);
-	ret = virt_to_bus((void *)kva);
-        MDEBUG(printk("kv2b(%lx-->%lx)\n", 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.
+ * This is used when initializing the contents of the area.
  */
 static inline unsigned long kvirt_to_pa(unsigned long adr) {
-        unsigned long va, kva, ret;
+        unsigned long kva, ret;
 
-        va = VMALLOC_VMADDR(adr);
-        kva = uvirt_to_kva(pgd_offset_k(va), va);
+        kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
+	kva |= adr & (PAGE_SIZE-1); /* restore the offset */
 	ret = __pa(kva);
-        MDEBUG(printk("kv2pa(%lx-->%lx)\n", adr, ret));
         return ret;
 }
 
-static void *rvmalloc(signed long size) {
+static void *rvmalloc(unsigned long size) {
 	void *mem;
-	unsigned long adr, page;
+	unsigned long adr;
 
+	size = PAGE_ALIGN(size);
 	mem = vmalloc_32(size);
 	if (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);
-			mem_map_reserve(virt_to_page(__va(page)));
+			mem_map_reserve(vmalloc_to_page((void *)adr));
 			adr += PAGE_SIZE;
 			size -= PAGE_SIZE;
 		}
@@ -193,14 +145,13 @@
 	return mem;
 }
 
-static void rvfree(void * mem, signed long size) {
-        unsigned long adr, page;
-        
+static void rvfree(void * mem, unsigned long size) {
+        unsigned long adr;
+
 	if (mem) {
 	        adr = (unsigned long) mem;
-		while (size > 0) {
-	                page = kvirt_to_pa(adr);
-			mem_map_unreserve(virt_to_page(__va(page)));
+		while ((long) size > 0) {
+			mem_map_unreserve(vmalloc_to_page((void *)adr));
 			adr += PAGE_SIZE;
 			size -= PAGE_SIZE;
 		}
@@ -209,31 +160,64 @@
 }
 
 /* return a page table pointing to N pages of locked memory */
-static void *ptable_alloc(int npages, u32 *pt_addr) {
+static int ptable_alloc(void) {
+	u32 *pt;
 	int i;
-	void *vmem;
-	u32 *ptable;
-	unsigned long adr;
 
-	vmem = rvmalloc((npages + 1) * PAGE_SIZE);
-	if (!vmem)
-		return NULL;
+	memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
+
+	meye.mchip_ptable[MCHIP_NB_PAGES] = pci_alloc_consistent(meye.mchip_dev, 
+								 PAGE_SIZE, 
+								 &meye.mchip_dmahandle);
+	if (!meye.mchip_ptable[MCHIP_NB_PAGES])
+		return -1;
 
-        adr = (unsigned long)vmem;
-	ptable = (u32 *)(vmem + npages * PAGE_SIZE);
-	for (i = 0; i < npages; i++) {
-		ptable[i] = (u32) kvirt_to_bus(adr);
-		adr += PAGE_SIZE;
+	pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
+	for (i = 0; i < MCHIP_NB_PAGES; i++) {
+		meye.mchip_ptable[i] = pci_alloc_consistent(meye.mchip_dev, 
+							    PAGE_SIZE,
+							    pt);
+		if (!meye.mchip_ptable[i])
+			return -1;
+		pt++;
 	}
+	return 0;
+}
+
+static void ptable_free(void) {
+	u32 *pt;
+	int i;
 
-	*pt_addr = (u32) kvirt_to_bus(adr);
-	return vmem;
+	pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
+	for (i = 0; i < MCHIP_NB_PAGES; i++)
+		if (meye.mchip_ptable[i])
+			pci_free_consistent(meye.mchip_dev, 
+					    PAGE_SIZE, 
+					    meye.mchip_ptable[i], *pt);
+
+	if (meye.mchip_ptable[MCHIP_NB_PAGES])
+		pci_free_consistent(meye.mchip_dev, 
+				    PAGE_SIZE, 
+				    meye.mchip_ptable[MCHIP_NB_PAGES], 
+				    meye.mchip_dmahandle);
+
+	memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
+	meye.mchip_dmahandle = 0;
 }
 
-static void ptable_free(void *vmem, int npages) {
-	rvfree(vmem, (npages + 1) * PAGE_SIZE);
+/* copy data from ptable into buf */
+static void ptable_copy(u8 *buf, int start, int size, int pt_pages) {
+	int i;
+	
+	for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) {
+		memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE);
+		if (start >= pt_pages)
+			start = 0;
+	}
+	memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE);
 }
 
+
 /****************************************************************************/
 /* JPEG tables at different qualities to load into the VRJ chip             */
 /****************************************************************************/
@@ -587,29 +571,23 @@
 
 /* setup for DMA transfers - also zeros the framebuffer */
 static int mchip_dma_alloc(void) {
-	if (!meye.mchip_fbuffer) {
-		meye.mchip_fbuffer = ptable_alloc(MCHIP_NB_PAGES, 
-				                  &meye.mchip_ptaddr);
-		if (!meye.mchip_fbuffer)
+	if (!meye.mchip_dmahandle)
+		if (ptable_alloc())
 			return -1;
-	}
 	return 0;
 }
 
 /* frees the DMA buffer */
 static void mchip_dma_free(void) {
-	if (meye.mchip_fbuffer) {
-		ptable_free(meye.mchip_fbuffer, MCHIP_NB_PAGES);
-		meye.mchip_fbuffer = 0;
-		meye.mchip_ptaddr = 0;
-	}
+	if (meye.mchip_dmahandle)
+		ptable_free();
 }
 
 /* sets the DMA parameters into the chip */
 static void mchip_dma_setup(void) {
 	int i;
 
-	mchip_set(MCHIP_MM_PT_ADDR, meye.mchip_ptaddr);
+	mchip_set(MCHIP_MM_PT_ADDR, meye.mchip_dmahandle);
 	for (i = 0; i < 4; i++)
 		mchip_set(MCHIP_MM_FIR(i), 0);
 	meye.mchip_fnum = 0;
@@ -658,60 +636,41 @@
 	meye.mchip_fnum %= 4;
 }
 
-
 /* read one frame from the framebuffer assuming it was captured using
    a uncompressed transfer */
-static void  mchip_cont_read_frame(u32 v, u8 *buf, int size) {
+static void mchip_cont_read_frame(u32 v, u8 *buf, int size) {
 	int pt_id;
-	int avail;
 
 	pt_id = (v >> 17) & 0x3FF;
-	avail = MCHIP_NB_PAGES - pt_id;
 
-	if (size > avail*PAGE_SIZE) {
-		memcpy(buf, meye.mchip_fbuffer + pt_id * PAGE_SIZE, 
-		       avail * PAGE_SIZE);
-		memcpy(buf +avail * PAGE_SIZE, meye.mchip_fbuffer,
-		       size - avail * PAGE_SIZE);
-	}
-	else
-		memcpy(buf, meye.mchip_fbuffer + pt_id * PAGE_SIZE, size);
+	ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES);
+
 }
 
 /* read a compressed frame from the framebuffer */
 static int mchip_comp_read_frame(u32 v, u8 *buf, int size) {
 	int pt_start, pt_end, trailer;
-	int fsize, fsize2;
+	int fsize;
 	int i;
 
 	pt_start = (v >> 19) & 0xFF;
 	pt_end = (v >> 11) & 0xFF;
 	trailer = (v >> 1) & 0x3FF;
 
-	if (pt_end < pt_start) {
-		fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE;
-		fsize2 = pt_end * PAGE_SIZE + trailer * 4;
-		if (fsize + fsize2 > size) {
-			printk(KERN_WARNING "meye: oversized compressed frame %d %d\n", 
-			       fsize, fsize2);
-			return -1;
-		} else {
-			memcpy(buf, meye.mchip_fbuffer + pt_start * PAGE_SIZE, 
-			       fsize);
-			memcpy(buf + fsize, meye.mchip_fbuffer, fsize2); 
-			fsize += fsize2;
-		}
-	} else {
+	if (pt_end < pt_start)
+		fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE +
+			pt_end * PAGE_SIZE + trailer * 4;
+	else
 		fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4;
-		if (fsize > size) {
-			printk(KERN_WARNING "meye: oversized compressed frame %d\n", 
-			       fsize);
-			return -1;
-		} else
-			memcpy(buf, meye.mchip_fbuffer + pt_start * PAGE_SIZE, 
-			       fsize);
+
+	if (fsize > size) {
+		printk(KERN_WARNING "meye: oversized compressed frame %d\n", 
+		       fsize);
+		return -1;
 	}
 
+	ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG);
+
 
 #ifdef MEYE_JPEG_CORRECTION
 
@@ -909,124 +868,108 @@
 /* video4linux integration                                                  */
 /****************************************************************************/
 
-static int meye_open(struct video_device *dev, int flags) {
-	int i;
+static int meye_open(struct inode *inode, struct file *file) {
+	int i, err;
 
-	down(&meye.lock);
-	if (meye.open_count) {
-		up(&meye.lock);
-		return -EBUSY;
-	}
-	meye.open_count++;
+	err = video_exclusive_open(inode,file);
+	if (err < 0)
+		return err;
+			
 	if (mchip_dma_alloc()) {
 		printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
-		up(&meye.lock);
+		video_exclusive_release(inode,file);
 		return -ENOBUFS;
 	}
 	mchip_hic_stop();
 	meye_initq(&meye.grabq);
 	for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
 		meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
-	up(&meye.lock);
 	return 0;
 }
 
-static void meye_close(struct video_device *dev) {
-	down(&meye.lock);
-	meye.open_count--;
+static int meye_release(struct inode *inode, struct file *file) {
 	mchip_hic_stop();
-	up(&meye.lock);
+	video_exclusive_release(inode,file);
+	return 0;
 }
 
-static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
+static int meye_do_ioctl(struct inode *inode, struct file *file,
+			 unsigned int cmd, void *arg) {
 
 	switch (cmd) {
 
 	case VIDIOCGCAP: {
-		struct video_capability b;
-		strcpy(b.name,meye.video_dev.name);
-		b.type = VID_TYPE_CAPTURE;
-		b.channels = 1;
-		b.audios = 0;
-		b.maxwidth = 640;
-		b.maxheight = 480;
-		b.minwidth = 320;
-		b.minheight = 240;
-		if(copy_to_user(arg,&b,sizeof(b)))
-			return -EFAULT;
+		struct video_capability *b = arg;
+		strcpy(b->name,meye.video_dev.name);
+		b->type = VID_TYPE_CAPTURE;
+		b->channels = 1;
+		b->audios = 0;
+		b->maxwidth = 640;
+		b->maxheight = 480;
+		b->minwidth = 320;
+		b->minheight = 240;
 		break;
 	}
 
 	case VIDIOCGCHAN: {
-		struct video_channel v;
-		if(copy_from_user(&v, arg,sizeof(v)))
-			return -EFAULT;
-		v.flags = 0;
-		v.tuners = 0;
-		v.type = VIDEO_TYPE_CAMERA;
-		if (v.channel != 0)
-			return -EINVAL;
-		strcpy(v.name,"Camera");
-		if(copy_to_user(arg,&v,sizeof(v)))
-			return -EFAULT;
+		struct video_channel *v = arg;
+		v->flags = 0;
+		v->tuners = 0;
+		v->type = VIDEO_TYPE_CAMERA;
+		if (v->channel != 0)
+			return -EINVAL;
+		strcpy(v->name,"Camera");
 		break;
 	}
 
 	case VIDIOCSCHAN: {
-		struct video_channel v;
-		if(copy_from_user(&v, arg,sizeof(v)))
-			return -EFAULT;
-		if (v.channel != 0)
+		struct video_channel *v = arg;
+		if (v->channel != 0)
 			return -EINVAL;
 		break;
 	}
 
 	case VIDIOCGPICT: {
-		struct video_picture p = meye.picture;
-		if(copy_to_user(arg, &p, sizeof(p)))
-			return -EFAULT;
+		struct video_picture *p = arg;
+		*p = meye.picture;
 		break;
 	}
 
 	case VIDIOCSPICT: {
-		struct video_picture p;
-		if(copy_from_user(&p, arg,sizeof(p)))
-			return -EFAULT;
-		if (p.depth != 2)
+		struct video_picture *p = arg;
+		if (p->depth != 2)
 			return -EINVAL;
-		if (p.palette != VIDEO_PALETTE_YUV422)
+		if (p->palette != VIDEO_PALETTE_YUV422)
 			return -EINVAL;
 		down(&meye.lock);
 		sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, 
-				      p.brightness >> 10);
+				      p->brightness >> 10);
 		sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, 
-				      p.hue >> 10);
+				      p->hue >> 10);
 		sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, 
-				      p.colour >> 10);
+				      p->colour >> 10);
 		sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, 
-				      p.contrast >> 10);
-		memcpy(&meye.picture, &p, sizeof(p));
+				      p->contrast >> 10);
+		meye.picture = *p;
 		up(&meye.lock);
 		break;
 	}
 
 	case VIDIOCSYNC: {
-		int i;
+		int *i = arg;
 		DECLARE_WAITQUEUE(wait, current);
 
-		if(copy_from_user((void *)&i,arg,sizeof(int)))
-			return -EFAULT;
-		if (i < 0 || i >= gbuffers)
+		if (*i < 0 || *i >= gbuffers)
 			return -EINVAL;
 
-		switch (meye.grab_buffer[i].state) {
+		switch (meye.grab_buffer[*i].state) {
 
 		case MEYE_BUF_UNUSED:
 			return -EINVAL;
 		case MEYE_BUF_USING:
 			add_wait_queue(&meye.grabq.proc_list, &wait);
 			current->state = TASK_INTERRUPTIBLE;
-			while (meye.grab_buffer[i].state == MEYE_BUF_USING) {
+			while (meye.grab_buffer[*i].state == MEYE_BUF_USING) {
 				schedule();
 				if(signal_pending(current)) {
 					remove_wait_queue(&meye.grabq.proc_list, &wait);
@@ -1038,36 +981,34 @@
 			current->state = TASK_RUNNING;
 			/* fall through */
 		case MEYE_BUF_DONE:
-			meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
+			meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
 		}
 		break;
 	}
 
 	case VIDIOCMCAPTURE: {
-		struct video_mmap vm;
+		struct video_mmap *vm = arg;
 		int restart = 0;
 
-		if(copy_from_user((void *) &vm, (void *) arg, sizeof(vm)))
-			return -EFAULT;
-		if (vm.frame >= gbuffers || vm.frame < 0)
+		if (vm->frame >= gbuffers || vm->frame < 0)
 			return -EINVAL;
-		if (vm.format != VIDEO_PALETTE_YUV422)
+		if (vm->format != VIDEO_PALETTE_YUV422)
 			return -EINVAL;
-		if (vm.height * vm.width * 2 > gbufsize)
+		if (vm->height * vm->width * 2 > gbufsize)
 			return -EINVAL;
 		if (!meye.grab_fbuffer)
 			return -EINVAL;
-		if (meye.grab_buffer[vm.frame].state != MEYE_BUF_UNUSED)
+		if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED)
 			return -EBUSY;
 
 		down(&meye.lock);
-		if (vm.width == 640 && vm.height == 480) {
+		if (vm->width == 640 && vm->height == 480) {
 			if (meye.params.subsample) {
 				meye.params.subsample = 0;
 				restart = 1;
 			}
 		}
-		else if (vm.width == 320 && vm.height == 240) {
+		else if (vm->width == 320 && vm->height == 240) {
 			if (!meye.params.subsample) {
 				meye.params.subsample = 1;
 				restart = 1;
@@ -1080,49 +1021,45 @@
 
 		if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT)
 			mchip_continuous_start();
-		meye.grab_buffer[vm.frame].state = MEYE_BUF_USING;
-		meye_pushq(&meye.grabq, vm.frame);
+		meye.grab_buffer[vm->frame].state = MEYE_BUF_USING;
+		meye_pushq(&meye.grabq, vm->frame);
 		up(&meye.lock);
 		break;
 	}
 
 	case VIDIOCGMBUF: {
-		struct video_mbuf vm;
+		struct video_mbuf *vm = arg;
 		int i;
 
-		memset(&vm, 0 , sizeof(vm));
-		vm.size = gbufsize * gbuffers;
-		vm.frames = gbuffers;
+		memset(vm, 0 , sizeof(*vm));
+		vm->size = gbufsize * gbuffers;
+		vm->frames = gbuffers;
 		for (i = 0; i < gbuffers; i++)
-			vm.offsets[i] = i * gbufsize;
-		if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
-			return -EFAULT;
+			vm->offsets[i] = i * gbufsize;
 		break;
 	}
 
 	case MEYEIOC_G_PARAMS: {
-		if (copy_to_user(arg, &meye.params, sizeof(meye.params)))
-			return -EFAULT;
+		struct meye_params *p = arg;
+		*p = meye.params;
 		break;
 	}
 
 	case MEYEIOC_S_PARAMS: {
-		struct meye_params jp;
-		if (copy_from_user(&jp, arg, sizeof(jp)))
-			return -EFAULT;
-		if (jp.subsample > 1)
+		struct meye_params *jp = arg;
+		if (jp->subsample > 1)
 			return -EINVAL;
-		if (jp.quality > 10)
+		if (jp->quality > 10)
 			return -EINVAL;
-		if (jp.sharpness > 63 || jp.agc > 63 || jp.picture > 63)
+		if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)
 			return -EINVAL;
-		if (jp.framerate > 31)
+		if (jp->framerate > 31)
 			return -EINVAL;
 		down(&meye.lock);
-		if (meye.params.subsample != jp.subsample ||
-		    meye.params.quality != jp.quality)
+		if (meye.params.subsample != jp->subsample ||
+		    meye.params.quality != jp->quality)
 			mchip_hic_stop();	/* need restart */
-		memcpy(&meye.params, &jp, sizeof(jp));
+		meye.params = *jp;
 		sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS,
 				      meye.params.sharpness);
 		sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC,
@@ -1134,48 +1071,43 @@
 	}
 
 	case MEYEIOC_QBUF_CAPT: {
-		int nb;
-
-		if (copy_from_user((void *) &nb, (void *) arg, sizeof(int)))
-			return -EFAULT;
+		int *nb = arg;
 
 		if (!meye.grab_fbuffer) 
 			return -EINVAL;
-		if (nb >= gbuffers)
+		if (*nb >= gbuffers)
 			return -EINVAL;
-		if (nb < 0) {
+		if (*nb < 0) {
 			/* stop capture */
 			mchip_hic_stop();
 			return 0;
 		}
-		if (meye.grab_buffer[nb].state != MEYE_BUF_UNUSED)
+		if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
 			return -EBUSY;
 		down(&meye.lock);
 		if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
 			mchip_cont_compression_start();
-		meye.grab_buffer[nb].state = MEYE_BUF_USING;
-		meye_pushq(&meye.grabq, nb);
+		meye.grab_buffer[*nb].state = MEYE_BUF_USING;
+		meye_pushq(&meye.grabq, *nb);
 		up(&meye.lock);
 		break;
 	}
 
 	case MEYEIOC_SYNC: {
-		int i;
+		int *i = arg;
 		DECLARE_WAITQUEUE(wait, current);
 
-		if(copy_from_user((void *)&i,arg,sizeof(int)))
-			return -EFAULT;
-		if (i < 0 || i >= gbuffers)
+		if (*i < 0 || *i >= gbuffers)
 			return -EINVAL;
 
-		switch (meye.grab_buffer[i].state) {
+		switch (meye.grab_buffer[*i].state) {
 
 		case MEYE_BUF_UNUSED:
 			return -EINVAL;
 		case MEYE_BUF_USING:
 			add_wait_queue(&meye.grabq.proc_list, &wait);
 			current->state = TASK_INTERRUPTIBLE;
-			while (meye.grab_buffer[i].state == MEYE_BUF_USING) {
+			while (meye.grab_buffer[*i].state == MEYE_BUF_USING) {
 				schedule();
 				if(signal_pending(current)) {
 					remove_wait_queue(&meye.grabq.proc_list, &wait);
@@ -1187,11 +1119,9 @@
 			current->state = TASK_RUNNING;
 			/* fall through */
 		case MEYE_BUF_DONE:
-			meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
+			meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
 		}
-		i = meye.grab_buffer[i].size;
-		if (copy_to_user(arg, (void *)&i, sizeof(int)))
-			return -EFAULT;
+		*i = meye.grab_buffer[*i].size;
 		break;
 	}
 
@@ -1213,7 +1143,7 @@
 	}
 
 	case MEYEIOC_STILLJCAPT: {
-		int len = -1;
+		int *len = arg;
 
 		if (!meye.grab_fbuffer) 
 			return -EINVAL;
@@ -1221,14 +1151,13 @@
 			return -EBUSY;
 		down(&meye.lock);
 		meye.grab_buffer[0].state = MEYE_BUF_USING;
-		while (len == -1) {
+		*len = -1;
+		while (*len == -1) {
 			mchip_take_picture();
-			len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
+			*len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
 		}
 		meye.grab_buffer[0].state = MEYE_BUF_DONE;
 		up(&meye.lock);
-		if (copy_to_user(arg, (void *)&len, sizeof(int)))
-			return -EFAULT;
 		break;
 	}
 
@@ -1240,10 +1169,16 @@
 	return 0;
 }
 
-static int meye_mmap(struct video_device *dev, const char *adr, 
-		     unsigned long size) {
-	unsigned long start=(unsigned long) adr;
-	unsigned long page,pos;
+static int meye_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg)
+{
+	return video_usercopy(inode, file, cmd, arg, meye_do_ioctl);
+}
+
+static int meye_mmap(struct file *file, struct vm_area_struct *vma) {
+	unsigned long start = vma->vm_start;
+	unsigned long size  = vma->vm_end - vma->vm_start;
+	unsigned long page, pos;
 
 	down(&meye.lock);
 	if (size > gbuffers * gbufsize) {
@@ -1275,15 +1210,21 @@
 	return 0;
 }
 
+static struct file_operations meye_fops = {
+	owner:		THIS_MODULE,
+	open:		meye_open,
+	release:	meye_release,
+	mmap:		meye_mmap,
+	ioctl:		meye_ioctl,
+	llseek:		no_llseek,
+};
+
 static struct video_device meye_template = {
 	owner:		THIS_MODULE,
 	name:		"meye",
 	type:		VID_TYPE_CAPTURE,
 	hardware:	VID_HARDWARE_MEYE,
-	open:		meye_open,
-	close:		meye_close,
-	ioctl:		meye_ioctl,
-	mmap:		meye_mmap,
+	fops:		&meye_fops,
 };
 
 static int __devinit meye_probe(struct pci_dev *pcidev, 
@@ -1301,7 +1242,6 @@
 	sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1);
 
 	meye.mchip_dev = pcidev;
-	meye.mchip_irq = pcidev->irq;
 	memcpy(&meye.video_dev, &meye_template, sizeof(meye_template));
 
 	if (mchip_dma_alloc()) {
@@ -1315,6 +1255,7 @@
 		goto out3;
 	}
 
+	meye.mchip_irq = pcidev->irq;
 	mchip_adr = pci_resource_start(meye.mchip_dev,0);
 	if (!mchip_adr) {
 		printk(KERN_ERR "meye: mchip has no device base address\n");
@@ -1479,6 +1420,27 @@
 	pci_unregister_driver(&meye_driver);
 }
 
+#ifndef MODULE
+static int __init meye_setup(char *str) {
+	int ints[4];
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+	if (ints[0] <= 0) 
+		goto out;
+	gbuffers = ints[1];
+	if (ints[0] == 1)
+		goto out;
+	gbufsize = ints[2];
+	if (ints[0] == 2)
+		goto out;
+	video_nr = ints[3];
+out:
+	return 1;
+}
+
+__setup("meye=", meye_setup);
+#endif
+
 MODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>");
 MODULE_DESCRIPTION("video4linux driver for the MotionEye camera");
 MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/meye.h linux/drivers/media/video/meye.h
--- linux.orig/drivers/media/video/meye.h	2001-07-28 19:35:55.000000000 +0000
+++ linux/drivers/media/video/meye.h	2002-07-20 01:08:21.000000000 +0000
@@ -29,7 +29,7 @@
 #define _MEYE_PRIV_H_
 
 #define MEYE_DRIVER_MAJORVERSION	1
-#define MEYE_DRIVER_MINORVERSION	1
+#define MEYE_DRIVER_MINORVERSION	4
 
 /****************************************************************************/
 /* Motion JPEG chip registers                                               */
@@ -292,15 +292,14 @@
 	u8 mchip_fnum;			/* current mchip frame number */
 
 	unsigned char *mchip_mmregs;	/* mchip: memory mapped registers */
-	unsigned char *mchip_fbuffer;	/* mchip: framebuffer */
-	u32 mchip_ptaddr;		/* mchip: pointer to framebuffer */
+	u8 *mchip_ptable[MCHIP_NB_PAGES+1];/* mchip: ptable + ptable toc */
+	dma_addr_t mchip_dmahandle;	/* mchip: dma handle to ptable toc */
 
 	unsigned char *grab_fbuffer;	/* capture framebuffer */
 					/* list of buffers */
 	struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
 
 	/* other */
-	unsigned int open_count;	/* open() count */
 	struct semaphore lock;		/* semaphore for open/mmap... */
 
 	struct meye_queue grabq;	/* queue for buffers to be grabbed */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/msp3400.c linux/drivers/media/video/msp3400.c
--- linux.orig/drivers/media/video/msp3400.c	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/msp3400.c	2002-07-20 01:08:24.000000000 +0000
@@ -97,6 +97,7 @@
 	int nicam_on;
 	int acb;
 	int main, second;	/* sound carrier */
+	int input;
 
 	int muted;
 	int left, right;	/* volume */
@@ -462,6 +463,8 @@
 /* turn on/off nicam + stereo */
 static void msp3400c_setstereo(struct i2c_client *client, int mode)
 {
+	static char *strmode[] = { "0", "mono", "stereo", "3",
+				   "lang1", "5", "6", "7", "lang2" };
 	struct msp3400c *msp = client->data;
 	int nicam=0; /* channel source: FM/AM or nicam */
 	int src=0;
@@ -469,7 +472,7 @@
 	/* switch demodulator */
 	switch (msp->mode) {
 	case MSP_MODE_FM_TERRA:
-		dprintk("msp3400: FM setstereo: %d\n",mode);
+		dprintk("msp3400: FM setstereo: %s\n",strmode[mode]);
 		msp3400c_setcarrier(client,msp->second,msp->main);
 		switch (mode) {
 		case VIDEO_SOUND_STEREO:
@@ -483,7 +486,7 @@
 		}
 		break;
 	case MSP_MODE_FM_SAT:
-		dprintk("msp3400: SAT setstereo: %d\n",mode);
+		dprintk("msp3400: SAT setstereo: %s\n",strmode[mode]);
 		switch (mode) {
 		case VIDEO_SOUND_MONO:
 			msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
@@ -502,21 +505,21 @@
 	case MSP_MODE_FM_NICAM1:
 	case MSP_MODE_FM_NICAM2:
 	case MSP_MODE_AM_NICAM:
-		dprintk("msp3400: NICAM setstereo: %d\n",mode);
+		dprintk("msp3400: NICAM setstereo: %s\n",strmode[mode]);
 		msp3400c_setcarrier(client,msp->second,msp->main);
 		if (msp->nicam_on)
 			nicam=0x0100;
 		break;
 	case MSP_MODE_BTSC:
-		dprintk("msp3400: BTSC setstereo: %d\n",mode);
+		dprintk("msp3400: BTSC setstereo: %s\n",strmode[mode]);
 		nicam=0x0300;
 		break;
 	case MSP_MODE_EXTERN:
-		dprintk("msp3400: extern setstereo: %d\n", mode);
+		dprintk("msp3400: extern setstereo: %s\n",strmode[mode]);
 		nicam = 0x0200;
 		break;
 	case MSP_MODE_FM_RADIO:
-		dprintk("msp3400: FM-Radio setstereo: %d\n", mode);
+		dprintk("msp3400: FM-Radio setstereo: %s\n",strmode[mode]);
 		break;
 	default:
 		dprintk("msp3400: mono setstereo\n");
@@ -627,7 +630,7 @@
 	switch (msp->mode) {
 	case MSP_MODE_FM_TERRA:
 		val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
-		if (val > 32768)
+		if (val > 32767)
 			val -= 65536;
 		dprintk("msp34xx: stereo detect register: %d\n",val);
 		
@@ -822,7 +825,7 @@
 				msp->restart = 0;
 
 			val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
-			if (val > 32768)
+			if (val > 32767)
 				val -= 65536;
 			if (val1 < val)
 				val1 = val, max1 = this;
@@ -859,7 +862,7 @@
 				goto restart;
 
 			val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
-			if (val > 32768)
+			if (val > 32767)
 				val -= 65536;
 			if (val2 < val)
 				val2 = val, max2 = this;
@@ -1221,6 +1224,7 @@
 static struct i2c_client client_template = 
 {
 	name:   "(unset)",
+	flags:  I2C_CLIENT_ALLOW_USE,
         driver: &driver,
 };
 
@@ -1253,6 +1257,7 @@
 	msp->right  = 65535;
 	msp->bass   = 32768;
 	msp->treble = 32768;
+	msp->input  = -1;
 	for (i = 0; i < DFP_COUNT; i++)
 		msp->dfp_regs[i] = -1;
 
@@ -1391,6 +1396,9 @@
 		     - IN1 is often used for external input
 		     - Hauppauge uses IN2 for the radio */
 		dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg);
+		if (*sarg == msp->input)
+			break;
+		msp->input = *sarg;
 		switch (*sarg) {
 		case AUDIO_RADIO:
 			msp->mode   = MSP_MODE_FM_RADIO;
@@ -1420,6 +1428,7 @@
 		break;
 
 	case AUDC_SET_RADIO:
+		dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n");
 		msp->norm = VIDEO_MODE_RADIO;
 		msp->watch_stereo=0;
 		del_timer(&msp->wake_stereo);
@@ -1471,6 +1480,7 @@
 	{
 		struct video_audio *va = arg;
 
+		dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n");
 		va->flags |= VIDEO_AUDIO_VOLUME |
 			VIDEO_AUDIO_BASS |
 			VIDEO_AUDIO_TREBLE |
@@ -1497,6 +1507,7 @@
 	{
 		struct video_audio *va = arg;
 
+		dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n");
 		msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
 		msp->left = (MIN(65536 - va->balance,32768) *
 			     va->volume) / 32768;
@@ -1520,6 +1531,7 @@
 	{
 		struct video_channel *vc = arg;
 		
+		dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN\n");
 		dprintk("msp34xx: switching to TV mode\n");
 		msp->norm = vc->norm;
 		break;
@@ -1527,6 +1539,7 @@
 	case VIDIOCSFREQ:
 	{
 		/* new channel -- kick audio carrier scan */
+		dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n");
 		msp_wake_thread(client);
 		break;
 	}
@@ -1540,13 +1553,13 @@
 
 /* ----------------------------------------------------------------------- */
 
-int msp3400_init_module(void)
+static int msp3400_init_module(void)
 {
 	i2c_add_driver(&driver);
 	return 0;
 }
 
-void msp3400_cleanup_module(void)
+static void msp3400_cleanup_module(void)
 {
 	i2c_del_driver(&driver);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/planb.c linux/drivers/media/video/planb.c
--- linux.orig/drivers/media/video/planb.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/media/video/planb.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,14 +1,17 @@
 /* 
-    planb - PlanB frame grabber driver
+    planb - v4l-compatible frame grabber driver for the PlanB hardware
 
     PlanB is used in the 7x00/8x00 series of PowerMacintosh
     Computers as video input DMA controller.
 
-    Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
+    Copyright (C) 1998 - 2002  Michel Lanners <mailto:mlan@cpu.lu>
 
-    Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
+    Based largely on the old bttv driver by Ralph Metzler
+
+    Additional debugging and coding by Takashi Oe <mailto:toe@unlserve.unl.edu>
+
+    For more information, see <http://www.cpu.lu/~mlan/planb.html>
 
-    Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -25,7 +28,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-/* $Id: planb.c,v 1.18 1999/05/02 17:36:34 mlan Exp $ */
+/* $Id: planb.c,v 2.11 2002/04/03 15:57:57 mlan Exp mlan $ */
 
 #include <linux/version.h>
 #include <linux/init.h>
@@ -40,6 +43,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/poll.h>
 #include <linux/wrapper.h>
 #include <linux/tqueue.h>
 #include <linux/videodev.h>
@@ -52,37 +56,41 @@
 #include <asm/irq.h>
 #include <asm/semaphore.h>
 
-#include "planb.h"
-#include "saa7196.h"
+/* Define these to get general / interrupt debugging */
+#undef DEBUG
+#undef IDEBUG
 
-/* Would you mind for some ugly debugging? */
-#if 0
-#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
+//#define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(KERN_DEBUG ## x)
 #else
-#define DEBUG(x...) 		/* Don't debug driver */
+#define DBG(x...)
 #endif
-
-#if 0
-#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
+#ifdef IDEBUG
+#define IDBG(x...) printk(KERN_DEBUG ## x)
 #else
-#define IDEBUG(x...) 		/* Don't debug interrupt part */
+#define IDBG(x...)
 #endif
 
-/* Ever seen a Mac with more than 1 of these? */
-#define PLANB_MAX 1
+#include "planb.h"
+#include "saa7196.h"
 
-static int planb_num;
-static struct planb planbs[PLANB_MAX];
+static struct planb planbs;
 static volatile struct planb_registers *planb_regs;
 
 static int def_norm = PLANB_DEF_NORM;	/* default norm */
 static int video_nr = -1;
+static int vbi_nr = -1;
 
 MODULE_PARM(def_norm, "i");
 MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
 MODULE_PARM(video_nr,"i");
-MODULE_LICENSE("GPL");
+MODULE_PARM(vbi_nr,"i");
 
+MODULE_DESCRIPTION("planb - v4l driver module for Apple PlanB video in");
+MODULE_AUTHOR("Michel Lanners & Takashi Oe - see: http://www.cpu.lu/planb.html");
+MODULE_LICENSE("GPL");
 
 /* ------------------ PlanB Exported Functions ------------------ */
 static long planb_write(struct video_device *, const char *, unsigned long, int);
@@ -92,12 +100,23 @@
 static int planb_ioctl(struct video_device *, unsigned int, void *);
 static int planb_mmap(struct video_device *, const char *, unsigned long);
 static void planb_irq(int, void *, struct pt_regs *);
+static int planb_vbi_open(struct video_device *, int);
+static void planb_vbi_close(struct video_device *);
+static long planb_vbi_read(struct video_device *, char *, unsigned long, int);
+static unsigned int planb_vbi_poll(struct video_device *, struct file *,
+	poll_table *);
+static int planb_vbi_ioctl(struct video_device *, unsigned int, void *);
 static void release_planb(void);
-static int init_planbs(void);
+static int __init init_planbs(void);
+static void __exit exit_planbs(void);
 
 /* ------------------ PlanB Internal Functions ------------------ */
 static int planb_prepare_open(struct planb *);
+static int planb_prepare_vbi(struct planb *);
+static int planb_prepare_video(struct planb *);
 static void planb_prepare_close(struct planb *);
+static void planb_close_vbi(struct planb *);
+static void planb_close_video(struct planb *);
 static void saa_write_reg(unsigned char, unsigned char);
 static unsigned char saa_status(int, struct planb *);
 static void saa_set(unsigned char, unsigned char, struct planb *);
@@ -107,28 +126,41 @@
 static void add_clip(struct planb *, struct video_clip *);
 static void fill_cmd_buff(struct planb *);
 static void cmd_buff(struct planb *);
-static volatile struct dbdma_cmd *setup_grab_cmd(int, struct planb *);
+static dbdma_cmd_ptr setup_grab_cmd(int, struct planb *);
 static void overlay_start(struct planb *);
 static void overlay_stop(struct planb *);
-static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *, unsigned short,
-	unsigned int);
-static inline void tab_cmd_store(volatile struct dbdma_cmd *, unsigned int,
-	unsigned int);
-static inline void tab_cmd_gen(volatile struct dbdma_cmd *, unsigned short,
-	unsigned short, unsigned int, unsigned int);
+static inline void tab_cmd_dbdma(dbdma_cmd_ptr, unsigned short, unsigned int);
+static inline void tab_cmd_store(dbdma_cmd_ptr, unsigned int, unsigned int);
+static inline void tab_cmd_gen(dbdma_cmd_ptr, unsigned short, unsigned short,
+	unsigned int, unsigned int);
 static int init_planb(struct planb *);
 static int find_planb(void);
-static void planb_pre_capture(int, int, struct planb *);
-static volatile struct dbdma_cmd *cmd_geo_setup(volatile struct dbdma_cmd *,
-					int, int, int, int, int, struct planb *);
-static inline void planb_dbdma_stop(volatile struct dbdma_regs *);
-static unsigned int saa_geo_setup(int, int, int, int, struct planb *);
+static void planb_pre_capture(int, struct planb *);
+static dbdma_cmd_ptr cmd_geo_setup(dbdma_cmd_ptr, int, int, int, int, int,
+	struct planb *);
+static inline void planb_dbdma_stop(dbdma_regs_ptr);
+static inline void planb_dbdma_restart(dbdma_regs_ptr);
+static void saa_geo_setup(int, int, int, int, struct planb *);
 static inline int overlay_is_active(struct planb *);
 
 /*******************************/
 /* Memory management functions */
 /*******************************/
 
+/* I know this is not the right way to allocate memory. Whoever knows
+ * the right way to allocate a huge buffer for DMA that can be mapped
+ * to user space, please tell me... or better, fix the code and send
+ * patches.
+ *
+ *					Michel Lanners (mlan@cpu.lu)
+ */
+/* FIXME: As subsequent calls to __get_free_pages don't necessarily return
+ * contiguous pages, we need to do horrible things later on when setting
+ * up DMA, to make sure a single DMA transfer doesn't cross a page boundary.
+ * At least, I hope it's done right later on ;-) ......
+ * Anyway, there should be a way to get hold of a large buffer of contiguous
+ * pages for DMA....
+ */
 static int grabbuf_alloc(struct planb *pb)
 {
 	int i, npage;
@@ -142,14 +174,14 @@
 				* sizeof(unsigned long), GFP_KERNEL)) == 0)
 		return -ENOMEM;
 	for (i = 0; i < npage; i++) {
-		pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL
-								|GFP_DMA, 0);
+		pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL |
+								GFP_DMA, 0);
 		if (!pb->rawbuf[i])
 			break;
 		mem_map_reserve(virt_to_page(pb->rawbuf[i]));
 	}
 	if (i-- < npage) {
-		printk(KERN_DEBUG "PlanB: init_grab: grab buffer not allocated\n");
+		DBG("PlanB: init_grab: grab buffer not allocated\n");
 		for (; i > 0; i--) {
 			mem_map_unreserve(virt_to_page(pb->rawbuf[i]));
 			free_pages((unsigned long)pb->rawbuf[i], 0);
@@ -157,7 +189,7 @@
 		kfree(pb->rawbuf);
 		return -ENOBUFS;
 	}
-	pb->rawbuf_size = npage;
+	pb->rawbuf_nchunks = npage;
 	return 0;
 }
 
@@ -181,12 +213,7 @@
 
 	/* Let's wait 30msec for this one */
 	current->state = TASK_INTERRUPTIBLE;
-#if LINUX_VERSION_CODE >= 0x02017F
 	schedule_timeout(30 * HZ / 1000);
-#else
-	current->timeout = jiffies + 30 * HZ / 1000;	/* 30 ms */;
-	schedule();
-#endif
 
 	return (unsigned char)in_8 (&planb_regs->saa_status);
 }
@@ -208,25 +235,15 @@
 		saa_write_reg (i, saa_regs[pb->win.norm][i]);
 }
 
-static unsigned int saa_geo_setup(int width, int height, int interlace, int bpp,
-	struct planb *pb)
+static void saa_geo_setup(int width, int height, int interlace,
+	int fmt, struct planb *pb)
 {
 	int ht, norm = pb->win.norm;
 
-	switch(bpp) {
-	case 2:
-		/* RGB555+a 1x16-bit + 16-bit transparent */
-		saa_regs[norm][SAA7196_FMTS] &= ~0x3;
-		break;
-	case 1:
-	case 4:
-		/* RGB888 1x24-bit + 8-bit transparent */
-		saa_regs[norm][SAA7196_FMTS] &= ~0x1;
-		saa_regs[norm][SAA7196_FMTS] |= 0x2;
-		break;
-	default:
-		return -EINVAL;
-	}
+	/* bits FS0, FS1 according to format spec */
+	saa_regs[norm][SAA7196_FMTS] &= ~0x3;
+	saa_regs[norm][SAA7196_FMTS] |= (palette2fmt[fmt].saa_fmt & 0x3);
+
 	ht = (interlace ? height / 2 : height);
 	saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff);
 	saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3)
@@ -240,93 +257,99 @@
 					: (saa_regs[norm][SAA7196_FMTS] | 0x60);
 	/* transparent mode; extended format enabled */
 	saa_regs[norm][SAA7196_DPATH] |= 0x3;
-
-	return 0;
+	/* bits LLV, MCT according to format spec */
+	saa_regs[norm][SAA7196_DPATH] &= ~0x30;
+	saa_regs[norm][SAA7196_DPATH] |= (palette2fmt[fmt].saa_fmt & 0x30);
 }
 
 /***************************/
 /* DBDMA support functions */
 /***************************/
 
-static inline void planb_dbdma_restart(volatile struct dbdma_regs *ch)
+static inline void planb_dbdma_restart(dbdma_regs_ptr ch)
 {
-	out_le32(&ch->control, PLANB_CLR(RUN));
-	out_le32(&ch->control, PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE));
+	writel(PLANB_CLR(RUN), &ch->control);
+	writel(PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE), &ch->control);
 }
 
-static inline void planb_dbdma_stop(volatile struct dbdma_regs *ch)
+static inline void planb_dbdma_stop(dbdma_regs_ptr ch)
 {
 	int i = 0;
 
-	out_le32(&ch->control, PLANB_CLR(RUN) | PLANB_SET(FLUSH));
-	while((in_le32(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) {
-		IDEBUG("PlanB: waiting for DMA to stop\n");
+	writel(PLANB_CLR(RUN) | PLANB_SET(FLUSH), &ch->control);
+	while((readl(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) {
+		IDBG("PlanB: waiting for DMA to stop\n");
 		i++;
 	}
 }
 
-static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *ch,
-	unsigned short command, unsigned int cmd_dep)
+static inline void tab_cmd_dbdma(dbdma_cmd_ptr ch, unsigned short command,
+	unsigned int cmd_dep)
 {
 	st_le16(&ch->command, command);
+	st_le16(&ch->req_count, 0);
+	st_le32(&ch->phy_addr, 0);
 	st_le32(&ch->cmd_dep, cmd_dep);
+	/* really clears res_count & xfer_status */
+	st_le32((unsigned int *)&ch->res_count, 0);
 }
 
-static inline void tab_cmd_store(volatile struct dbdma_cmd *ch,
-	unsigned int phy_addr, unsigned int cmd_dep)
+static inline void tab_cmd_store(dbdma_cmd_ptr ch, unsigned int phy_addr,
+	unsigned int cmd_dep)
 {
 	st_le16(&ch->command, STORE_WORD | KEY_SYSTEM);
 	st_le16(&ch->req_count, 4);
 	st_le32(&ch->phy_addr, phy_addr);
 	st_le32(&ch->cmd_dep, cmd_dep);
+	st_le32((unsigned int *)&ch->res_count, 0);
 }
 
-static inline void tab_cmd_gen(volatile struct dbdma_cmd *ch,
-	unsigned short command, unsigned short req_count,
-	unsigned int phy_addr, unsigned int cmd_dep)
+static inline void tab_cmd_gen(dbdma_cmd_ptr ch, unsigned short command,
+	unsigned short req_count, unsigned int phy_addr, unsigned int cmd_dep)
 {
 	st_le16(&ch->command, command);
 	st_le16(&ch->req_count, req_count);
 	st_le32(&ch->phy_addr, phy_addr);
 	st_le32(&ch->cmd_dep, cmd_dep);
+	st_le32((unsigned int *)&ch->res_count, 0);
 }
 
-static volatile struct dbdma_cmd *cmd_geo_setup(
-	volatile struct dbdma_cmd *c1, int width, int height, int interlace,
-	int bpp, int clip, struct planb *pb)
+static dbdma_cmd_ptr cmd_geo_setup(dbdma_cmd_ptr c1, int width, int height,
+	int interlace, int fmt, int clip, struct planb *pb)
 {
 	int norm = pb->win.norm;
 
-	if((saa_geo_setup(width, height, interlace, bpp, pb)) != 0)
-		return (volatile struct dbdma_cmd *)NULL;
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_FMTS);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_FMTS]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_DPATH);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_DPATH]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->even),
-					bpp | ((clip)? PLANB_CLIPMASK: 0));
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->odd),
-					bpp | ((clip)? PLANB_CLIPMASK: 0));
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_OUTPIX);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_OUTPIX]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_HFILT);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_HFILT]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
+	saa_geo_setup(width, height, interlace, fmt, pb);
+	/* if the number of DBDMA commands here (14) changes, lots of
+	 * things need to be corrected accordingly... */
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
+								SAA7196_FMTS);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
+						saa_regs[norm][SAA7196_FMTS]);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
+								SAA7196_DPATH);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
+						saa_regs[norm][SAA7196_DPATH]);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->even),
+			palette2fmt[fmt].pb_fmt | ((clip)? PLANB_CLIPMASK: 0));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->odd),
+			palette2fmt[fmt].pb_fmt | ((clip)? PLANB_CLIPMASK: 0));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
+								SAA7196_OUTPIX);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
+						saa_regs[norm][SAA7196_OUTPIX]);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
+								SAA7196_HFILT);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
+						saa_regs[norm][SAA7196_HFILT]);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
 							SAA7196_OUTLINE);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
 					saa_regs[norm][SAA7196_OUTLINE]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_VYP);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_VYP]);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
+								SAA7196_VYP);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
+						saa_regs[norm][SAA7196_VYP]);
 	return c1;
 }
 
@@ -336,11 +359,13 @@
 
 static inline void planb_lock(struct planb *pb)
 {
+	DBG("PlanB: planb_lock\n");
 	down(&pb->lock);
 }
 
 static inline void planb_unlock(struct planb *pb)
 {
+	DBG("PlanB: planb_unlock\n");
 	up(&pb->lock);
 }
 
@@ -348,47 +373,116 @@
 /* Driver Core */
 /***************/
 
+/* number of entries in the circular DBDMA command buffer
+ * initial stop, odd/even vbi, odd/even video, branch back */
+#define NUMJUMPS 6
 static int planb_prepare_open(struct planb *pb)
 {
+	dbdma_cmd_ptr	c;
+	int		size, i;
+
+	size = (NUMJUMPS + 1) * sizeof(struct dbdma_cmd);
+
+	if((pb->jump_raw = kmalloc (size, GFP_KERNEL|GFP_DMA)) == 0)
+		return -ENOMEM;
+	memset(pb->jump_raw, 0, size);
+	c = pb->jumpbuf = (dbdma_cmd_ptr) DBDMA_ALIGN (pb->jump_raw);
+
+	/* circular DBDMA command buffer, to hold jumps to transfer commands */
+	tab_cmd_dbdma(c++, DBDMA_STOP, 0);
+	for (i=1; i<NUMJUMPS-1; i++)
+		tab_cmd_dbdma(c++, DBDMA_NOP, 0);
+	tab_cmd_dbdma(c, DBDMA_NOP|BR_ALWAYS,
+		(unsigned int)pb->jumpbuf);
+
+	DBG("PlanB: planb_prepare_open, jumpbuffer at 0x%08x, length %d.\n",
+		(unsigned int)pb->jumpbuf, size); 
+	return 0;
+}
+
+#define VBIDUMMY 40	/* must be even !! */
+static int planb_prepare_vbi(struct planb *pb)
+{
+	int	size;
+
+	/* allocate VBI comand buffer memory
+	   (2 fields * VBI_MAXLINES + 40 handling + alignment) */
+	size = (2*VBI_MAXLINES + VBIDUMMY + 1) * sizeof(struct dbdma_cmd);
+
+	if ((pb->vbi_raw = kmalloc (size, GFP_KERNEL|GFP_DMA)) == 0)
+		return -ENOMEM;
+	memset (pb->vbi_raw, 0, size);
+	size = (VBI_MAXLINES + VBIDUMMY/2) * sizeof(struct dbdma_cmd);
+	pb->vbi_cbo.start = (dbdma_cmd_ptr) DBDMA_ALIGN (pb->vbi_raw);
+	pb->vbi_cbo.size = pb->vbi_cbe.size = size;
+	pb->vbi_cbe.start = pb->vbi_cbo.start + pb->vbi_cbo.size;
+	pb->vbi_cbo.jumpaddr = pb->jumpbuf + 1;
+	pb->vbi_cbe.jumpaddr = pb->jumpbuf + 3;
+
+	DBG("PlanB: planb_prepare_vbi, dbdma cmd_buf at 0x%08x, length %d.\n",
+		(unsigned int)pb->vbi_cbo.start, 2*size); 
+	return 0;
+}
+
+static int planb_prepare_video(struct planb *pb)
+{
 	int	i, size;
 
+	/* FIXME: This is stressing kmalloc to its limits...
+		  We really should allocate smaller chunks. */
+
 	/* allocate memory for two plus alpha command buffers (size: max lines,
 	   plus 40 commands handling, plus 1 alignment), plus dummy command buf,
 	   plus clipmask buffer, plus frame grabbing status */
-	size = (pb->tab_size*(2+MAX_GBUFFERS*TAB_FACTOR)+1+MAX_GBUFFERS
-		* PLANB_DUMMY)*sizeof(struct dbdma_cmd)
-		+(PLANB_MAXLINES*((PLANB_MAXPIXELS+7)& ~7))/8
-		+MAX_GBUFFERS*sizeof(unsigned int);
-	if ((pb->priv_space = kmalloc (size, GFP_KERNEL)) == 0)
+	size = (pb->tab_size * (2 + MAX_GBUFFERS * TAB_FACTOR)
+		    + MAX_GBUFFERS * PLANB_DUMMY + 1) * sizeof(struct dbdma_cmd)
+		+ (PLANB_MAXLINES * ((PLANB_MAXPIXELS + 7) & ~7)) / 8
+		+ MAX_GBUFFERS * sizeof(unsigned int);
+	if ((pb->vid_raw = kmalloc (size, GFP_KERNEL|GFP_DMA)) == 0)
 		return -ENOMEM;
-	memset ((void *) pb->priv_space, 0, size);
-	pb->overlay_last1 = pb->ch1_cmd = (volatile struct dbdma_cmd *)
-						DBDMA_ALIGN (pb->priv_space);
-	pb->overlay_last2 = pb->ch2_cmd = pb->ch1_cmd + pb->tab_size;
-	pb->ch1_cmd_phys = virt_to_bus(pb->ch1_cmd);
-	pb->cap_cmd[0] = pb->ch2_cmd + pb->tab_size;
-	pb->pre_cmd[0] = pb->cap_cmd[0] + pb->tab_size * TAB_FACTOR;
+	memset (pb->vid_raw, 0, size);
+	pb->vid_cbo.start = (dbdma_cmd_ptr) DBDMA_ALIGN (pb->vid_raw);
+	pb->vid_cbo.size = pb->vid_cbe.size = pb->tab_size/2;
+	pb->vid_cbe.start = pb->vid_cbo.start + pb->vid_cbo.size;
+	pb->vid_cbo.jumpaddr = pb->jumpbuf + 2;
+	pb->vid_cbe.jumpaddr = pb->jumpbuf + 4;
+	pb->overlay_last1 = pb->vid_cbo.start;
+	pb->vid_cbo.bus = virt_to_bus(pb->vid_cbo.start);
+	pb->vid_cbe.bus = virt_to_bus(pb->vid_cbe.start);
+	pb->clip_cbo.start = pb->vid_cbe.start + pb->vid_cbe.size;
+	pb->clip_cbo.size = pb->clip_cbe.size = pb->tab_size/2;
+	pb->clip_cbe.start = pb->clip_cbo.start + pb->clip_cbo.size;
+	pb->overlay_last2 = pb->clip_cbo.start;
+	pb->clip_cbo.bus = virt_to_bus(pb->clip_cbo.start);
+	pb->clip_cbe.bus = virt_to_bus(pb->clip_cbe.start);
+	pb->gbuf[0].cap_cmd = pb->clip_cbe.start + pb->clip_cbe.size;
+	pb->gbuf[0].pre_cmd = pb->gbuf[0].cap_cmd + pb->tab_size * TAB_FACTOR;
 	for (i = 1; i < MAX_GBUFFERS; i++) {
-		pb->cap_cmd[i] = pb->pre_cmd[i-1] + PLANB_DUMMY;
-		pb->pre_cmd[i] = pb->cap_cmd[i] + pb->tab_size * TAB_FACTOR;
-	}
-	pb->frame_stat=(volatile unsigned int *)(pb->pre_cmd[MAX_GBUFFERS-1]
-						+ PLANB_DUMMY);
-	pb->mask = (unsigned char *)(pb->frame_stat+MAX_GBUFFERS);
+		pb->gbuf[i].cap_cmd = pb->gbuf[i-1].pre_cmd + PLANB_DUMMY;
+		pb->gbuf[i].pre_cmd = pb->gbuf[i].cap_cmd +
+						pb->tab_size * TAB_FACTOR;
+	}
+	pb->gbuf[0].status = (volatile unsigned int *)
+			(pb->gbuf[MAX_GBUFFERS-1].pre_cmd + PLANB_DUMMY);
+	for (i = 1; i < MAX_GBUFFERS; i++)
+		pb->gbuf[i].status = pb->gbuf[i-1].status;
+	pb->mask = (unsigned char *)(pb->gbuf[MAX_GBUFFERS-1].status + 1);
 
 	pb->rawbuf = NULL;
-	pb->rawbuf_size = 0;
+	pb->rawbuf_nchunks = 0;
 	pb->grabbing = 0;
 	for (i = 0; i < MAX_GBUFFERS; i++) {
-		pb->frame_stat[i] = GBUFFER_UNUSED;
-		pb->gwidth[i] = 0;
-		pb->gheight[i] = 0;
-		pb->gfmt[i] = 0;
-		pb->gnorm_switch[i] = 0;
+		gbuf_ptr	gbuf = &pb->gbuf[i];
+
+		*gbuf->status = GBUFFER_UNUSED;
+		gbuf->width = 0;
+		gbuf->height = 0;
+		gbuf->fmt = 0;
+		gbuf->norm_switch = 0;
 #ifndef PLANB_GSCANLINE
-		pb->lsize[i] = 0;
-		pb->lnum[i] = 0;
-#endif /* PLANB_GSCANLINE */
+		gbuf->lsize = 0;
+		gbuf->lnum = 0;
+#endif
 	}
 	pb->gcount = 0;
 	pb->suspend = 0;
@@ -399,30 +493,74 @@
 	planb_dbdma_stop(&pb->planb_base->ch2);
 	planb_dbdma_stop(&pb->planb_base->ch1);
 
+	DBG("PlanB: planb_prepare_video, dbdma cmd_buf at 0x%08x, "
+		"length %d.\n", (unsigned int)pb->vid_cbo.start, 2*size);
 	return 0;
 }
 
 static void planb_prepare_close(struct planb *pb)
 {
-	int i;
-
 	/* make sure the dma's are idle */
 	planb_dbdma_stop(&pb->planb_base->ch2);
 	planb_dbdma_stop(&pb->planb_base->ch1);
-	/* free kernel memory of command buffers */
-	if(pb->priv_space != 0) {
-		kfree (pb->priv_space);
-		pb->priv_space = 0;
+
+	if(pb->jump_raw != 0) {
+		kfree(pb->jump_raw);
+		pb->jump_raw = 0;
+	}
+	return;
+}
+
+static void planb_close_vbi(struct planb *pb)
+{
+	/* FIXME: stop running DMA */
+
+	/* Make sure the DMA controller doesn't jump here anymore */
+	tab_cmd_dbdma(pb->vbi_cbo.jumpaddr, DBDMA_NOP, 0);
+	tab_cmd_dbdma(pb->vbi_cbe.jumpaddr, DBDMA_NOP, 0);
+
+	if(pb->vbi_raw != 0) {
+		kfree (pb->vbi_raw);
+		pb->vbi_raw = 0;
+	}
+
+	/* FIXME: deallocate VBI data buffer */
+
+	/* FIXME: restart running DMA if app. */
+	return;
+}
+
+static void planb_close_video(struct planb *pb)
+{
+	int i;
+
+	/* FIXME: stop running DMA */
+
+	/* Make sure the DMA controller doesn't jump here anymore */
+	tab_cmd_dbdma(pb->vid_cbo.jumpaddr, DBDMA_NOP, 0);
+	tab_cmd_dbdma(pb->vid_cbe.jumpaddr, DBDMA_NOP, 0);
+/* No clipmask jumpbuffer yet  */
+#if 0
+	tab_cmd_dbdma(pb->clip_cbo.jumpaddr, DBDMA_NOP, 0);
+	tab_cmd_dbdma(pb->clip_cbe.jumpaddr, DBDMA_NOP, 0);
+#endif
+
+	if(pb->vid_raw != 0) {
+		kfree (pb->vid_raw);
+		pb->vid_raw = 0;
 		pb->cmd_buff_inited = 0;
 	}
 	if(pb->rawbuf) {
-		for (i = 0; i < pb->rawbuf_size; i++) {
+		for (i = 0; i < pb->rawbuf_nchunks; i++) {
 			mem_map_unreserve(virt_to_page(pb->rawbuf[i]));
 			free_pages((unsigned long)pb->rawbuf[i], 0);
 		}
 		kfree(pb->rawbuf);
 	}
 	pb->rawbuf = NULL;
+
+	/* FIXME: restart running DMA if app. */
+	return;
 }
 
 /*****************************/
@@ -431,43 +569,37 @@
 
 static void overlay_start(struct planb *pb)
 {
+	DBG("PlanB: overlay_start()\n");
 
-	DEBUG("PlanB: overlay_start()\n");
-
-	if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
+	if(ACTIVE & readl(&pb->planb_base->ch1.status)) {
 
-		DEBUG("PlanB: presumably, grabbing is in progress...\n");
+		DBG("PlanB: presumably, grabbing is in progress...\n");
 
 		planb_dbdma_stop(&pb->planb_base->ch2);
-		out_le32 (&pb->planb_base->ch2.cmdptr,
-						virt_to_bus(pb->ch2_cmd));
+		writel(pb->clip_cbo.bus, &pb->planb_base->ch2.cmdptr);
 		planb_dbdma_restart(&pb->planb_base->ch2);
-		st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
-		tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
-					DBDMA_NOP | BR_ALWAYS,
-					virt_to_bus(pb->ch1_cmd));
+		st_le16 (&pb->vid_cbo.start->command, DBDMA_NOP);
+		tab_cmd_dbdma(pb->gbuf[pb->last_fr].last_cmd,
+			DBDMA_NOP | BR_ALWAYS, pb->vid_cbo.bus);
 		eieio();
 		pb->prev_last_fr = pb->last_fr;
 		pb->last_fr = -2;
-		if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
-			IDEBUG("PlanB: became inactive "
+		if(!(ACTIVE & readl(&pb->planb_base->ch1.status))) {
+			IDBG("PlanB: became inactive "
 				"in the mean time... reactivating\n");
 			planb_dbdma_stop(&pb->planb_base->ch1);
-			out_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->ch1_cmd));
+			writel(pb->vid_cbo.bus, &pb->planb_base->ch1.cmdptr);
 			planb_dbdma_restart(&pb->planb_base->ch1);
 		}
 	} else {
 
-		DEBUG("PlanB: currently idle, so can do whatever\n");
+		DBG("PlanB: currently idle, so can do whatever\n");
 
 		planb_dbdma_stop(&pb->planb_base->ch2);
 		planb_dbdma_stop(&pb->planb_base->ch1);
-		st_le32 (&pb->planb_base->ch2.cmdptr,
-						virt_to_bus(pb->ch2_cmd));
-		st_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->ch1_cmd));
-		out_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
+		st_le32(&pb->planb_base->ch2.cmdptr, pb->clip_cbo.bus);
+		st_le32(&pb->planb_base->ch1.cmdptr, pb->vid_cbo.bus);
+		writew(DBDMA_NOP, &pb->vid_cbo.start->command);
 		planb_dbdma_restart(&pb->planb_base->ch2);
 		planb_dbdma_restart(&pb->planb_base->ch1);
 		pb->last_fr = -1;
@@ -477,29 +609,29 @@
 
 static void overlay_stop(struct planb *pb)
 {
-	DEBUG("PlanB: overlay_stop()\n");
+	DBG("PlanB: overlay_stop()\n");
 
 	if(pb->last_fr == -1) {
 
-		DEBUG("PlanB: no grabbing, it seems...\n");
+		DBG("PlanB: no grabbing, it seems...\n");
 
 		planb_dbdma_stop(&pb->planb_base->ch2);
 		planb_dbdma_stop(&pb->planb_base->ch1);
 		pb->last_fr = -999;
 	} else if(pb->last_fr == -2) {
 		unsigned int cmd_dep;
-		tab_cmd_dbdma(pb->cap_cmd[pb->prev_last_fr], DBDMA_STOP, 0);
+		tab_cmd_dbdma(pb->gbuf[pb->prev_last_fr].cap_cmd, DBDMA_STOP, 0);
 		eieio();
-		cmd_dep = (unsigned int)in_le32(&pb->overlay_last1->cmd_dep);
+		cmd_dep = (unsigned int)readl(&pb->overlay_last1->cmd_dep);
 		if(overlay_is_active(pb)) {
 
-			DEBUG("PlanB: overlay is currently active\n");
+			DBG("PlanB: overlay is currently active\n");
 
 			planb_dbdma_stop(&pb->planb_base->ch2);
 			planb_dbdma_stop(&pb->planb_base->ch1);
-			if(cmd_dep != pb->ch1_cmd_phys) {
-				out_le32(&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->overlay_last1));
+			if(cmd_dep != pb->vid_cbo.bus) {
+				writel(virt_to_bus(pb->overlay_last1),
+					&pb->planb_base->ch1.cmdptr);
 				planb_dbdma_restart(&pb->planb_base->ch1);
 			}
 		}
@@ -514,15 +646,15 @@
 	int fr = -1;
 	struct dbdma_cmd last;
 
-	DEBUG("PlanB: suspend_overlay: %d\n", pb->suspend);
+	DBG("PlanB: suspend_overlay: %d\n", pb->suspend);
 
 	if(pb->suspend++)
 		return;
-	if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
+	if(ACTIVE & readl(&pb->planb_base->ch1.status)) {
 		if(pb->last_fr == -2) {
 			fr = pb->prev_last_fr;
-			memcpy(&last, (void*)pb->last_cmd[fr], sizeof(last));
-			tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
+			memcpy(&last, (void*)pb->gbuf[fr].last_cmd, sizeof(last));
+			tab_cmd_dbdma(pb->gbuf[fr].last_cmd, DBDMA_STOP, 0);
 		}
 		if(overlay_is_active(pb)) {
 			planb_dbdma_stop(&pb->planb_base->ch2);
@@ -542,38 +674,38 @@
 static void resume_overlay(struct planb *pb)
 {
 
-	DEBUG("PlanB: resume_overlay: %d\n", pb->suspend);
+	DBG("PlanB: resume_overlay: %d\n", pb->suspend);
 
 	if(pb->suspend > 1)
 		return;
 	if(pb->suspended.frame != -1) {
-		memcpy((void*)pb->last_cmd[pb->suspended.frame],
-				&pb->suspended.cmd, sizeof(pb->suspended.cmd));
+		memcpy((void*)pb->gbuf[pb->suspended.frame].last_cmd,
+			&pb->suspended.cmd, sizeof(pb->suspended.cmd));
 	}
-	if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
+	if(ACTIVE & readl(&pb->planb_base->ch1.status)) {
 		goto finish;
 	}
 	if(pb->suspended.overlay) {
 
-		DEBUG("PlanB: overlay being resumed\n");
+		DBG("PlanB: overlay being resumed\n");
 
-		st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
-		st_le16 (&pb->ch2_cmd->command, DBDMA_NOP);
+		st_le16 (&pb->vid_cbo.start->command, DBDMA_NOP);
+		st_le16 (&pb->clip_cbo.start->command, DBDMA_NOP);
 		/* Set command buffer addresses */
-		st_le32(&pb->planb_base->ch1.cmdptr,
-					virt_to_bus(pb->overlay_last1));
-		out_le32(&pb->planb_base->ch2.cmdptr,
-					virt_to_bus(pb->overlay_last2));
+		writel(virt_to_bus(pb->overlay_last1),
+			&pb->planb_base->ch1.cmdptr);
+		writel(virt_to_bus(pb->overlay_last2),
+			&pb->planb_base->ch2.cmdptr);
 		/* Start the DMA controller */
-		out_le32 (&pb->planb_base->ch2.control,
-				PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
-		out_le32 (&pb->planb_base->ch1.control,
-				PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
+		writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),
+			&pb->planb_base->ch2.control);
+		writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),
+			&pb->planb_base->ch1.control);
 	} else if(pb->suspended.frame != -1) {
-		out_le32(&pb->planb_base->ch1.cmdptr,
-				virt_to_bus(pb->last_cmd[pb->suspended.frame]));
-		out_le32 (&pb->planb_base->ch1.control,
-				PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
+		writel(virt_to_bus(pb->gbuf[pb->suspended.frame].last_cmd),
+			&pb->planb_base->ch1.cmdptr);
+		writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),
+			&pb->planb_base->ch1.control);
 	}
 
 finish:
@@ -589,7 +721,7 @@
 	int	ww = pb->win.width, hw = pb->win.height;
 	int	x, y, xtmp1, xtmp2;
 
-	DEBUG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc);
+	DBG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc);
 
 	if(xc < 0) {
 		wc += xc;
@@ -626,47 +758,48 @@
 
 static void fill_cmd_buff(struct planb *pb)
 {
-	int restore = 0;
-	volatile struct dbdma_cmd last;
+	int		restore = 0;
+	dbdma_cmd_t	last;
 
-	DEBUG("PlanB: fill_cmd_buff()\n");
+	DBG("PlanB: fill_cmd_buff()\n");
 
-	if(pb->overlay_last1 != pb->ch1_cmd) {
+	if(pb->overlay_last1 != pb->vid_cbo.start) {
 		restore = 1;
 		last = *(pb->overlay_last1);
 	}
-	memset ((void *) pb->ch1_cmd, 0, 2 * pb->tab_size
+	memset ((void *) pb->vid_cbo.start, 0, 2 * pb->tab_size
 					* sizeof(struct dbdma_cmd));
 	cmd_buff (pb);
 	if(restore)
 		*(pb->overlay_last1) = last;
 	if(pb->suspended.overlay) {
-		unsigned long jump_addr = in_le32(&pb->overlay_last1->cmd_dep);
-		if(jump_addr != pb->ch1_cmd_phys) {
+		unsigned long jump_addr = readl(&pb->overlay_last1->cmd_dep);
+		if(jump_addr != pb->vid_cbo.bus) {
 			int i;
 
-			DEBUG("PlanB: adjusting ch1's jump address\n");
+			DBG("PlanB: adjusting ch1's jump address\n");
 
 			for(i = 0; i < MAX_GBUFFERS; i++) {
-				if(pb->need_pre_capture[i]) {
-				    if(jump_addr == virt_to_bus(pb->pre_cmd[i]))
+				if(pb->gbuf[i].need_pre_capture) {
+				    if(jump_addr == virt_to_bus(pb->gbuf[i].pre_cmd))
 					goto found;
 				} else {
-				    if(jump_addr == virt_to_bus(pb->cap_cmd[i]))
+				    if(jump_addr ==
+					    virt_to_bus(pb->gbuf[i].cap_cmd))
 					goto found;
 				}
 			}
 
-			DEBUG("PlanB: not found...\n");
+			DBG("       not found!\n");
 
 			goto out;
 found:
-			if(pb->need_pre_capture[i])
-				out_le32(&pb->pre_cmd[i]->phy_addr,
-						virt_to_bus(pb->overlay_last1));
+			if(pb->gbuf[i].need_pre_capture)
+				writel(virt_to_bus(pb->overlay_last1),
+					&pb->gbuf[i].pre_cmd->phy_addr);
 			else
-				out_le32(&pb->cap_cmd[i]->phy_addr,
-						virt_to_bus(pb->overlay_last1));
+				writel(virt_to_bus(pb->overlay_last1),
+					&pb->gbuf[i].cap_cmd->phy_addr);
 		}
 	}
 out:
@@ -679,8 +812,8 @@
 {
 	int		i, bpp, count, nlines, stepsize, interlace;
 	unsigned long	base, jump, addr_com, addr_dep;
-	volatile struct dbdma_cmd *c1 = pb->ch1_cmd;
-	volatile struct dbdma_cmd *c2 = pb->ch2_cmd;
+	dbdma_cmd_ptr	c1 = pb->vid_cbo.start;
+	dbdma_cmd_ptr	c2 = pb->clip_cbo.start;
 
 	interlace = pb->win.interlace;
 	bpp = pb->win.bpp;
@@ -696,33 +829,28 @@
 	addr_dep = virt_to_bus(&c1->cmd_dep);
 	tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
 	jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */
-	if((c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,
-					bpp, 1, pb)) == NULL) {
-		printk(KERN_WARNING "PlanB: encountered serious problems\n");
-		tab_cmd_dbdma(pb->ch1_cmd + 1, DBDMA_STOP, 0);
-		tab_cmd_dbdma(pb->ch2_cmd + 1, DBDMA_STOP, 0);
-		return;
-	}
+	c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,
+						pb->win.color_fmt, 1, pb);
 	tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16);
 	tab_cmd_store(c1++, addr_dep, jump);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.wait_sel),
 							PLANB_SET(FIELD_SYNC));
 		/* (1) wait for field sync to be set */
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
 							PLANB_SET(ODD_FIELD));
 		/* wait for field sync to be cleared */
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
 		/* if not odd field, wait until field sync is set again */
 	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
 		/* assert ch_sync to ch2 */
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch2.control),
 							PLANB_SET(CH_SYNC));
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
 							PLANB_SET(DMA_ABORT));
 
-	base = (pb->frame_buffer_phys + pb->offset + pb->win.y * (pb->win.bpl
-					+ pb->win.pad) + pb->win.x * bpp);
+	base = (pb->fb.phys + pb->fb.offset + pb->win.y * (pb->win.bpl +
+					pb->win.pad) + pb->win.x * bpp);
 
 	if (interlace) {
 		stepsize = 2;
@@ -744,16 +872,16 @@
 	/* Resync to odd field */
 		/* (2) wait for field sync to be set */
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
 							PLANB_SET(ODD_FIELD));
 		/* wait for field sync to be cleared */
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
 		/* if not odd field, wait until field sync is set again */
 	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
 		/* assert ch_sync to ch2 */
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch2.control),
 							PLANB_SET(CH_SYNC));
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
 							PLANB_SET(DMA_ABORT));
 	
 	/* odd field data: */
@@ -765,22 +893,22 @@
 	/* And jump back to the start */
 cmd_tab_data_end:
 	pb->overlay_last1 = c1;	/* keep a pointer to the last command */
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch1_cmd));
+	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, pb->vid_cbo.bus);
 
 	/* Clipmask command buffer */
 
 	/* Preamble commands: */
 	tab_cmd_dbdma(c2++, DBDMA_NOP, 0);
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
+	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.wait_sel),
 							PLANB_SET(CH_SYNC));
 		/* wait until ch1 asserts ch_sync */
 	tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
 		/* clear ch_sync asserted by ch1 */
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.control),
+	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.control),
 							PLANB_CLR(CH_SYNC));
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
+	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.wait_sel),
 							PLANB_SET(FIELD_SYNC));
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
+	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.br_sel),
 							PLANB_SET(ODD_FIELD));
 
 	/* jump to end of even field if appropriate */
@@ -791,7 +919,7 @@
 	tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump);
 
 	/* even field mask: */
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
+	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.br_sel),
 							PLANB_SET(DMA_ABORT));
 	/* this points to pos. B */
 	jump = (interlace) ? virt_to_bus(c2 + nlines + 1):
@@ -806,7 +934,7 @@
 		goto cmd_tab_mask_end;
 
 	/* odd field mask: */
-/* C */	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
+/* C */	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.br_sel),
 							PLANB_SET(DMA_ABORT));
 	/* this points to pos. B */
 	jump = virt_to_bus(c2 + nlines / 2);
@@ -824,13 +952,13 @@
 		/* corresponds to fsync (1) of ch1 */
 /* B */	tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
 		/* restart ch1, meant to clear any dead bit or something */
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
+	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch1.control),
 							PLANB_CLR(RUN));
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
+	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch1.control),
 							PLANB_SET(RUN));
 	pb->overlay_last2 = c2;	/* keep a pointer to the last command */
 		/* start over even field clipmasking */
-	tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch2_cmd));
+	tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, pb->clip_cbo.bus);
 
 	eieio();
 	return;
@@ -840,40 +968,22 @@
 /* grabdisplay support functions */
 /*********************************/
 
-static int palette2fmt[] = {
-       0,
-       PLANB_GRAY,
-       0,
-       0,
-       0,
-       PLANB_COLOUR32,
-       PLANB_COLOUR15,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-};
-
-#define PLANB_PALETTE_MAX 15
-
 static inline int overlay_is_active(struct planb *pb)
 {
 	unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd);
-	unsigned int caddr = (unsigned)in_le32(&pb->planb_base->ch1.cmdptr);
+	unsigned int caddr = (unsigned)readl(&pb->planb_base->ch1.cmdptr);
 
-	return (in_le32(&pb->overlay_last1->cmd_dep) == pb->ch1_cmd_phys)
-			&& (caddr < (pb->ch1_cmd_phys + size))
-			&& (caddr >= (unsigned)pb->ch1_cmd_phys);
+	return (readl(&pb->overlay_last1->cmd_dep) == pb->vid_cbo.bus)
+			&& (caddr < (pb->vid_cbo.bus + size))
+			&& (caddr >= (unsigned)pb->vid_cbo.bus);
 }
 
 static int vgrab(struct planb *pb, struct video_mmap *mp)
 {
-	unsigned int fr = mp->frame;
-	unsigned int format;
+	unsigned int	fr = mp->frame;
+	unsigned int	fmt = mp->format;
+	unsigned int	bpp = palette2fmt[fmt].bpp;
+	gbuf_ptr	gbuf = &pb->gbuf[fr];
 
 	if(pb->rawbuf==NULL) {
 		int err;
@@ -881,211 +991,225 @@
 			return err;
 	}
 
-	IDEBUG("PlanB: grab %d: %dx%d(%u)\n", pb->grabbing,
-						mp->width, mp->height, fr);
+	DBG("PlanB: grab %d: %dx%d fmt %d (%u)\n", pb->grabbing, mp->width,
+						mp->height, fmt, fr);
 
-	if(pb->grabbing >= MAX_GBUFFERS)
+	if(pb->grabbing >= MAX_GBUFFERS) {
+		DBG("       no buffer\n");
 		return -ENOBUFS;
-	if(fr > (MAX_GBUFFERS - 1) || fr < 0)
+	}
+	if(fr > (MAX_GBUFFERS - 1) || fr < 0) {
+		DBG("       invalid buffer\n");
 		return -EINVAL;
-	if(mp->height <= 0 || mp->width <= 0)
+	}
+	if(mp->height <= 0 || mp->width <= 0) {
+		DBG("       negative height or width\n");
 		return -EINVAL;
-	if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX)
+	}
+	if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX) {
+		DBG("       format out of range\n");
 		return -EINVAL;
-	if((format = palette2fmt[mp->format]) == 0)
+	}
+	if(bpp == 0) {
+		DBG("       unsupported format %d\n", mp->format);
 		return -EINVAL;
-	if (mp->height * mp->width * format > PLANB_MAX_FBUF) /* format = bpp */
+	}
+	if (mp->height * mp->width * bpp > PLANB_MAX_FBUF) {
+		DBG("       grab bigger than buffer\n");
 		return -EINVAL;
+	}
 
 	planb_lock(pb);
-	if(mp->width != pb->gwidth[fr] || mp->height != pb->gheight[fr] ||
-			format != pb->gfmt[fr] || (pb->gnorm_switch[fr])) {
+	if(mp->width != gbuf->width || mp->height != gbuf->height ||
+			fmt != gbuf->fmt || (gbuf->norm_switch)) {
 		int i;
 #ifndef PLANB_GSCANLINE
-		unsigned int osize = pb->gwidth[fr] * pb->gheight[fr]
-								* pb->gfmt[fr];
-		unsigned int nsize = mp->width * mp->height * format;
+		unsigned int osize = gbuf->width * gbuf->height *
+					palette2fmt[gbuf->fmt].bpp;
+		unsigned int nsize = mp->width * mp->height * bpp;
 #endif
 
-		IDEBUG("PlanB: gwidth = %d, gheight = %d, mp->format = %u\n",
-					mp->width, mp->height, mp->format);
+		DBG("PlanB: changed gwidth = %d, gheight = %d, format = %u, "
+			"osize = %d, nsize = %d\n", mp->width, mp->height, fmt,
+								osize, nsize);
 
+/* Do we _really_ need to clear the grab buffers?? */
+#if 0
 #ifndef PLANB_GSCANLINE
-		if(pb->gnorm_switch[fr])
+		if(gbuf->norm_switch)
 			nsize = 0;
 		if (nsize < osize) {
-			for(i = pb->gbuf_idx[fr]; osize > 0; i++) {
+			for(i = gbuf->idx; osize > 0; i++) {
 				memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
 				osize -= PAGE_SIZE;
 			}
 		}
-		for(i = pb->l_fr_addr_idx[fr]; i < pb->l_fr_addr_idx[fr]
-							+ pb->lnum[fr]; i++)
+		for(i = gbuf->l_fr_addr_idx; i <
+				gbuf->l_fr_addr_idx + gbuf->lnum; i++)
 			memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
 #else
 /* XXX TODO */
 /*
-		if(pb->gnorm_switch[fr])
+		if(gbuf->norm_switch)
 			memset((void *)pb->gbuffer[fr], 0,
-					pb->gbytes_per_line * pb->gheight[fr]);
+					pb->gbytes_per_line * gbuf->height);
 		else {
 			if(mp->
-			for(i = 0; i < pb->gheight[fr]; i++) {
+			for(i = 0; i < gbuf->height; i++) {
 				memset((void *)(pb->gbuffer[fr]
 					+ pb->gbytes_per_line * i
 			}
 		}
 */
 #endif
-		pb->gwidth[fr] = mp->width;
-		pb->gheight[fr] = mp->height;
-		pb->gfmt[fr] = format;
-		pb->last_cmd[fr] = setup_grab_cmd(fr, pb);
-		planb_pre_capture(fr, pb->gfmt[fr], pb); /* gfmt = bpp */
-		pb->need_pre_capture[fr] = 1;
-		pb->gnorm_switch[fr] = 0;
+#endif /* if 0 */
+		gbuf->width = mp->width;
+		gbuf->height = mp->height;
+		gbuf->fmt = fmt;
+		gbuf->last_cmd = setup_grab_cmd(fr, pb);
+		planb_pre_capture(fr, pb);
+		gbuf->need_pre_capture = 1;
+		gbuf->norm_switch = 0;
 	} else
-		pb->need_pre_capture[fr] = 0;
-	pb->frame_stat[fr] = GBUFFER_GRABBING;
-	if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
+		gbuf->need_pre_capture = 0;
+
+	*gbuf->status = GBUFFER_GRABBING;
+	if(!(ACTIVE & readl(&pb->planb_base->ch1.status))) {
 
-		IDEBUG("PlanB: ch1 inactive, initiating grabbing\n");
+		IDBG("PlanB: ch1 inactive, initiating grabbing\n");
 
 		planb_dbdma_stop(&pb->planb_base->ch1);
-		if(pb->need_pre_capture[fr]) {
+		if(gbuf->need_pre_capture) {
 
-			IDEBUG("PlanB: padding pre-capture sequence\n");
+			DBG("PlanB: padding pre-capture sequence\n");
 
-			out_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->pre_cmd[fr]));
+			writel(virt_to_bus(gbuf->pre_cmd),
+				&pb->planb_base->ch1.cmdptr);
 		} else {
-			tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
-			tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
+			tab_cmd_dbdma(gbuf->last_cmd, DBDMA_STOP, 0);
+			tab_cmd_dbdma(gbuf->cap_cmd, DBDMA_NOP, 0);
 		/* let's be on the safe side. here is not timing critical. */
-			tab_cmd_dbdma((pb->cap_cmd[fr] + 1), DBDMA_NOP, 0);
-			out_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->cap_cmd[fr]));
+			tab_cmd_dbdma((gbuf->cap_cmd + 1), DBDMA_NOP, 0);
+			writel(virt_to_bus(gbuf->cap_cmd),
+				&pb->planb_base->ch1.cmdptr);
 		}
 		planb_dbdma_restart(&pb->planb_base->ch1);
 		pb->last_fr = fr;
 	} else {
 		int i;
 
-		IDEBUG("PlanB: ch1 active, grabbing being queued\n");
+		DBG("PlanB: ch1 active, grabbing being queued\n");
 
 		if((pb->last_fr == -1) || ((pb->last_fr == -2) &&
 						overlay_is_active(pb))) {
 
-			IDEBUG("PlanB: overlay is active, grabbing defered\n");
+			DBG("PlanB: overlay is active, grabbing defered\n");
 
-			tab_cmd_dbdma(pb->last_cmd[fr],
-					DBDMA_NOP | BR_ALWAYS,
-					virt_to_bus(pb->ch1_cmd));
-			if(pb->need_pre_capture[fr]) {
+			tab_cmd_dbdma(gbuf->last_cmd, DBDMA_NOP | BR_ALWAYS,
+					pb->vid_cbo.bus);
+			if(gbuf->need_pre_capture) {
 
-				IDEBUG("PlanB: padding pre-capture sequence\n");
+				DBG("PlanB: padding pre-capture sequence\n");
 
-				tab_cmd_store(pb->pre_cmd[fr],
+				tab_cmd_store(gbuf->pre_cmd,
 				    virt_to_bus(&pb->overlay_last1->cmd_dep),
-						virt_to_bus(pb->ch1_cmd));
+				    pb->vid_cbo.bus);
 				eieio();
-				out_le32 (&pb->overlay_last1->cmd_dep,
-						virt_to_bus(pb->pre_cmd[fr]));
+				writel(virt_to_bus(gbuf->pre_cmd),
+					&pb->overlay_last1->cmd_dep);
 			} else {
-				tab_cmd_store(pb->cap_cmd[fr],
+				tab_cmd_store(gbuf->cap_cmd,
 				    virt_to_bus(&pb->overlay_last1->cmd_dep),
-						virt_to_bus(pb->ch1_cmd));
-				tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
+				    pb->vid_cbo.bus);
+				tab_cmd_dbdma((gbuf->cap_cmd + 1),
 								DBDMA_NOP, 0);
 				eieio();
-				out_le32 (&pb->overlay_last1->cmd_dep,
-						virt_to_bus(pb->cap_cmd[fr]));
+				writel(virt_to_bus(gbuf->cap_cmd),
+					&pb->overlay_last1->cmd_dep);
 			}
 			for(i = 0; overlay_is_active(pb) && i < 999; i++)
-				IDEBUG("PlanB: waiting for overlay done\n");
-			tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
+				DBG("PlanB: waiting for overlay done\n");
+			tab_cmd_dbdma(pb->vid_cbo.start, DBDMA_NOP, 0);
 			pb->prev_last_fr = fr;
 			pb->last_fr = -2;
 		} else if(pb->last_fr == -2) {
 
-			IDEBUG("PlanB: mixed mode detected, grabbing"
+			DBG("PlanB: mixed mode detected, grabbing"
 				" will be done before activating overlay\n");
 
-			tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
-			if(pb->need_pre_capture[fr]) {
+			tab_cmd_dbdma(pb->vid_cbo.start, DBDMA_NOP, 0);
+			if(gbuf->need_pre_capture) {
 
-				IDEBUG("PlanB: padding pre-capture sequence\n");
+				DBG("PlanB: padding pre-capture sequence\n");
 
-				tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
+				tab_cmd_dbdma(pb->gbuf[pb->prev_last_fr].last_cmd,
 						DBDMA_NOP | BR_ALWAYS,
-						virt_to_bus(pb->pre_cmd[fr]));
+						virt_to_bus(gbuf->pre_cmd));
 				eieio();
 			} else {
-				tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
-				if(pb->gwidth[pb->prev_last_fr] !=
-								pb->gwidth[fr]
-					|| pb->gheight[pb->prev_last_fr] !=
-								pb->gheight[fr]
-					|| pb->gfmt[pb->prev_last_fr] !=
-								pb->gfmt[fr])
-					tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
+				tab_cmd_dbdma(gbuf->cap_cmd, DBDMA_NOP, 0);
+				if(pb->gbuf[pb->prev_last_fr].width !=
+								gbuf->width
+					|| pb->gbuf[pb->prev_last_fr].height !=
+								gbuf->height
+					|| pb->gbuf[pb->prev_last_fr].fmt !=
+								gbuf->fmt)
+					tab_cmd_dbdma((gbuf->cap_cmd + 1),
 								DBDMA_NOP, 0);
 				else
-					tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
+					tab_cmd_dbdma((gbuf->cap_cmd + 1),
 					    DBDMA_NOP | BR_ALWAYS,
-					    virt_to_bus(pb->cap_cmd[fr] + 16));
-				tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
+					    virt_to_bus(gbuf->cap_cmd + 16));
+				tab_cmd_dbdma(pb->gbuf[pb->prev_last_fr].last_cmd,
 						DBDMA_NOP | BR_ALWAYS,
-						virt_to_bus(pb->cap_cmd[fr]));
+						virt_to_bus(gbuf->cap_cmd));
 				eieio();
 			}
-			tab_cmd_dbdma(pb->last_cmd[fr],
-					DBDMA_NOP | BR_ALWAYS,
-					virt_to_bus(pb->ch1_cmd));
+			tab_cmd_dbdma(gbuf->last_cmd, DBDMA_NOP | BR_ALWAYS,
+				pb->vid_cbo.bus);
 			eieio();
 			pb->prev_last_fr = fr;
 			pb->last_fr = -2;
 		} else {
+			gbuf_ptr	lastgbuf = &pb->gbuf[pb->last_fr];
 
-			IDEBUG("PlanB: active grabbing session detected\n");
+			DBG("PlanB: active grabbing session detected\n");
 
-			if(pb->need_pre_capture[fr]) {
+			if(gbuf->need_pre_capture) {
 
-				IDEBUG("PlanB: padding pre-capture sequence\n");
+				DBG("PlanB: padding pre-capture sequence\n");
 
-				tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
+				tab_cmd_dbdma(lastgbuf->last_cmd,
 						DBDMA_NOP | BR_ALWAYS,
-						virt_to_bus(pb->pre_cmd[fr]));
+						virt_to_bus(gbuf->pre_cmd));
 				eieio();
 			} else {
-				tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
-				tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
-				if(pb->gwidth[pb->last_fr] != pb->gwidth[fr]
-					|| pb->gheight[pb->last_fr] !=
-								pb->gheight[fr]
-					|| pb->gfmt[pb->last_fr] !=
-								pb->gfmt[fr])
-					tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
+				tab_cmd_dbdma(gbuf->last_cmd, DBDMA_STOP, 0);
+				tab_cmd_dbdma(gbuf->cap_cmd, DBDMA_NOP, 0);
+				if(lastgbuf->width != gbuf->width
+				    || lastgbuf->height != gbuf->height
+				    || lastgbuf->fmt != gbuf->fmt)
+					tab_cmd_dbdma((gbuf->cap_cmd + 1),
 								DBDMA_NOP, 0);
 				else
-					tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
+					tab_cmd_dbdma((gbuf->cap_cmd + 1),
 					    DBDMA_NOP | BR_ALWAYS,
-					    virt_to_bus(pb->cap_cmd[fr] + 16));
-				tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
+					    virt_to_bus(gbuf->cap_cmd + 16));
+				tab_cmd_dbdma(lastgbuf->last_cmd,
 						DBDMA_NOP | BR_ALWAYS,
-						virt_to_bus(pb->cap_cmd[fr]));
+						virt_to_bus(gbuf->cap_cmd));
 				eieio();
 			}
 			pb->last_fr = fr;
 		}
-		if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
+		if(!(ACTIVE & readl(&pb->planb_base->ch1.status))) {
 
-			IDEBUG("PlanB: became inactive in the mean time..."
+			DBG("PlanB: became inactive in the mean time... "
 				"reactivating\n");
 
 			planb_dbdma_stop(&pb->planb_base->ch1);
-			out_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->cap_cmd[fr]));
+			writel(virt_to_bus(gbuf->cap_cmd),
+				&pb->planb_base->ch1.cmdptr);
 			planb_dbdma_restart(&pb->planb_base->ch1);
 		}
 	}
@@ -1095,49 +1219,58 @@
 	return 0;
 }
 
-static void planb_pre_capture(int fr, int bpp, struct planb *pb)
+static void planb_pre_capture(int fr, struct planb *pb)
 {
-	volatile struct dbdma_cmd *c1 = pb->pre_cmd[fr];
-	int interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
+	gbuf_ptr	gbuf = &pb->gbuf[fr];
+	dbdma_cmd_ptr	c1 = gbuf->pre_cmd;
+	int		height = gbuf->height;
+	int		interlace = (height > pb->maxlines/2)? 1: 0;
 
 	tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
-	if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
-						bpp, 0, pb)) == NULL) {
-		printk(KERN_WARNING "PlanB: encountered some problems\n");
-		tab_cmd_dbdma(pb->pre_cmd[fr] + 1, DBDMA_STOP, 0);
-		return;
-	}
+	c1 = cmd_geo_setup(c1, gbuf->width, height, interlace, gbuf->fmt,
+									0, pb);
 	/* Sync to even field */
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
-		PLANB_SET(FIELD_SYNC));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.wait_sel),
+							PLANB_SET(FIELD_SYNC));
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(ODD_FIELD));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
+							PLANB_SET(ODD_FIELD));
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
 	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
 	tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(DMA_ABORT));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
+							PLANB_SET(DMA_ABORT));
 	/* For non-interlaced, we use even fields only */
-	if (pb->gheight[fr] <= pb->maxlines/2)
+	if (interlace == 0)
 		goto cmd_tab_data_end;
 	/* Sync to odd field */
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(ODD_FIELD));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
+							PLANB_SET(ODD_FIELD));
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
 	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(DMA_ABORT));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
+							PLANB_SET(DMA_ABORT));
 cmd_tab_data_end:
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->cap_cmd[fr]));
+	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(gbuf->cap_cmd));
 
 	eieio();
 }
 
-static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb)
+/* This needs some explanation.
+ * What we do here is write the DBDMA commands to fill the grab buffer.
+ * Since the grab buffer is made up of physically non-contiguous chunks,
+ * we need to make sure to not make the DMA engine write across a chunk
+ * boundary: the DMA engine needs a physically contiguous memory chunk for
+ * a single scan line.
+ * So all those scan lines that cross a chunk boundary are written do spare
+ * scratch buffers, and we keep track of this fact.
+ * Later, in the interrupt routine, we copy those scan lines (in two pieces)
+ * back to where they belong in the right sequence in the grab buffer.
+ */
+static dbdma_cmd_ptr setup_grab_cmd(int fr, struct planb *pb)
 {
-	int		i, bpp, count, nlines, stepsize, interlace;
+	int		i, count, nlines, stepsize, interlace;
 #ifdef PLANB_GSCANLINE
 	int		scanline;
 #else
@@ -1146,19 +1279,20 @@
 #endif
 	unsigned long	jump;
 	int		pagei;
-	volatile struct dbdma_cmd *c1;
-	volatile struct dbdma_cmd *jump_addr;
-
-	c1 = pb->cap_cmd[fr];
-	interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
-	bpp = pb->gfmt[fr];	/* gfmt = bpp */
-	count = bpp * pb->gwidth[fr];
-	nlines = pb->gheight[fr];
+	dbdma_cmd_ptr	c1;
+	dbdma_cmd_ptr	jump_addr;
+	gbuf_ptr	gbuf = &pb->gbuf[fr];
+	int		fmt = gbuf->fmt;
+
+	c1 = gbuf->cap_cmd;
+	nlines = gbuf->height;
+	interlace = (nlines > pb->maxlines/2) ? 1 : 0;
+	count = palette2fmt[fmt].bpp * gbuf->width;
 #ifdef PLANB_GSCANLINE
 	scanline = pb->gbytes_per_line;
 #else
-	pb->lsize[fr] = count;
-	pb->lnum[fr] = 0;
+	gbuf->lsize = count;
+	gbuf->lnum = 0;
 #endif
 
 	/* Do video in: */
@@ -1166,22 +1300,17 @@
 	/* Preamble commands: */
 	tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
 	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++;
-	if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
-						bpp, 0, pb)) == NULL) {
-		printk(KERN_WARNING "PlanB: encountered serious problems\n");
-		tab_cmd_dbdma(pb->cap_cmd[fr] + 1, DBDMA_STOP, 0);
-		return (pb->cap_cmd[fr] + 2);
-	}
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
-		PLANB_SET(FIELD_SYNC));
+	c1 = cmd_geo_setup(c1, gbuf->width, nlines, interlace, fmt, 0, pb);
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.wait_sel),
+							PLANB_SET(FIELD_SYNC));
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(ODD_FIELD));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
+							PLANB_SET(ODD_FIELD));
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
 	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
 	tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(DMA_ABORT));
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
+							PLANB_SET(DMA_ABORT));
 
 	if (interlace) {
 		stepsize = 2;
@@ -1194,12 +1323,12 @@
 
 	/* even field data: */
 
-	pagei = pb->gbuf_idx[fr];
+	pagei = gbuf->idx;
 #ifdef PLANB_GSCANLINE
 	for (i = 0; i < nlines; i += stepsize) {
-		tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
-					virt_to_bus(pb->rawbuf[pagei
-					+ i * scanline / PAGE_SIZE]), jump);
+		tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
+		    virt_to_bus(pb->rawbuf[pagei + i * scanline / PAGE_SIZE]),
+									jump);
 	}
 #else
 	i = 0;
@@ -1219,18 +1348,25 @@
 		    leftover1 = 0;
 		else {
 		    if(lov0 >= count) {
+			/* can happen only when interlacing; then other field
+			 * uses up leftover space (lov0 - count). */
 			tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base
 				+ count * nlpp * stepsize + leftover1, jump);
 		    } else {
-			pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
+			/* start of free space at end of page: */
+			pb->l_to_addr[fr][gbuf->lnum] = pb->rawbuf[pagei]
 					+ count * nlpp * stepsize + leftover1;
-			pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
-			pb->l_to_next_size[fr][pb->lnum[fr]] = count - lov0;
+			/* index where continuation is: */
+			pb->l_to_next_idx[fr][gbuf->lnum] = pagei + 1;
+			/* How much is left to do in next page: */
+			pb->l_to_next_size[fr][gbuf->lnum] = count - lov0;
 			tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
-				virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
-						+ pb->lnum[fr]]), jump);
-			if(++pb->lnum[fr] > MAX_LNUM)
-				pb->lnum[fr]--;
+				virt_to_bus(pb->rawbuf[gbuf->l_fr_addr_idx
+						+ gbuf->lnum]), jump);
+			if(++gbuf->lnum > MAX_LNUM) {
+				/* FIXME: error condition! */
+				gbuf->lnum--;
+		    	}
 		    }
 		    leftover1 = count * stepsize - lov0;
 		    i += stepsize;
@@ -1248,11 +1384,11 @@
 
 	/* Sync to odd field */
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
 		PLANB_SET(ODD_FIELD));
 	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
 	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
 		PLANB_SET(DMA_ABORT));
 	
 	/* odd field data: */
@@ -1260,14 +1396,14 @@
 	jump = virt_to_bus(jump_addr);
 #ifdef PLANB_GSCANLINE
 	for (i = 1; i < nlines; i += stepsize) {
-		tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
+		tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
 					virt_to_bus(pb->rawbuf[pagei
 					+ i * scanline / PAGE_SIZE]), jump);
 	}
 #else
 	i = 1;
 	leftover1 = 0;
-	pagei = pb->gbuf_idx[fr];
+	pagei = gbuf->idx;
 	if(nlines <= 1)
 	    goto skip;
 	do {
@@ -1290,16 +1426,18 @@
 		    leftover1 = 0;
 		else {
 		    if(lov0 > count) {
-			pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
+			pb->l_to_addr[fr][gbuf->lnum] = pb->rawbuf[pagei]
 				+ count * (nlpp * stepsize + 1) + leftover1;
-			pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
-			pb->l_to_next_size[fr][pb->lnum[fr]] = count * stepsize
+			pb->l_to_next_idx[fr][gbuf->lnum] = pagei + 1;
+			pb->l_to_next_size[fr][gbuf->lnum] = count * stepsize
 									- lov0;
 			tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
-				virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
-							+ pb->lnum[fr]]), jump);
-			if(++pb->lnum[fr] > MAX_LNUM)
-				pb->lnum[fr]--;
+				virt_to_bus(pb->rawbuf[gbuf->l_fr_addr_idx
+							+ gbuf->lnum]), jump);
+			if(++gbuf->lnum > MAX_LNUM) {
+				/* FIXME: error condition! */
+				gbuf->lnum--;
+			}
 			i += stepsize;
 		    }
 		    leftover1 = count * stepsize - lov0;
@@ -1313,7 +1451,7 @@
 #endif /* PLANB_GSCANLINE */
 
 cmd_tab_data_end:
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->intr_stat),
+	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->intr_stat),
 			(fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ);
 	/* stop it */
 	tab_cmd_dbdma(c1, DBDMA_STOP, 0);
@@ -1327,50 +1465,54 @@
 	unsigned int stat, astat;
 	struct planb *pb = (struct planb *)dev_id;
 
-	IDEBUG("PlanB: planb_irq()\n");
+	IDBG("PlanB: planb_irq()\n");
 
 	/* get/clear interrupt status bits */
 	eieio();
-	stat = in_le32(&pb->planb_base->intr_stat);
+	stat = readl(&pb->planb_base->intr_stat);
 	astat = stat & pb->intr_mask;
-	out_le32(&pb->planb_base->intr_stat, PLANB_FRM_IRQ
-					& ~astat & stat & ~PLANB_GEN_IRQ);
-	IDEBUG("PlanB: stat = %X, astat = %X\n", stat, astat);
+	writel(PLANB_FRM_IRQ & ~astat & stat & ~PLANB_GEN_IRQ,
+		&pb->planb_base->intr_stat);
+	IDBG("PlanB: stat = %X, astat = %X\n", stat, astat);
 
 	if(astat & PLANB_FRM_IRQ) {
-		unsigned int fr = stat >> 9;
+		unsigned int	fr = stat >> 9;
+		gbuf_ptr	gbuf = &pb->gbuf[fr];
 #ifndef PLANB_GSCANLINE
-		int i;
+		int		i;
 #endif
-		IDEBUG("PlanB: PLANB_FRM_IRQ\n");
+		IDBG("PlanB: PLANB_FRM_IRQ\n");
 
 		pb->gcount++;
 
-		IDEBUG("PlanB: grab %d: fr = %d, gcount = %d\n",
+		IDBG("PlanB: grab %d: fr = %d, gcount = %d\n",
 				pb->grabbing, fr, pb->gcount);
 #ifndef PLANB_GSCANLINE
-		IDEBUG("PlanB: %d * %d bytes are being copied over\n",
-				pb->lnum[fr], pb->lsize[fr]);
-		for(i = 0; i < pb->lnum[fr]; i++) {
-			int first = pb->lsize[fr] - pb->l_to_next_size[fr][i];
+		/* Now that the buffer is full, copy those lines that fell
+		 * on a page boundary from the spare buffers back to where
+		 * they belong. */
+		IDBG("PlanB: %d * %d bytes are being copied over\n",
+				gbuf->lnum, gbuf->lsize);
+		for(i = 0; i < gbuf->lnum; i++) {
+			int first = gbuf->lsize - pb->l_to_next_size[fr][i];
 
 			memcpy(pb->l_to_addr[fr][i],
-				pb->rawbuf[pb->l_fr_addr_idx[fr] + i],
+				pb->rawbuf[gbuf->l_fr_addr_idx + i],
 				first);
 			memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]],
-				pb->rawbuf[pb->l_fr_addr_idx[fr] + i] + first,
+				pb->rawbuf[gbuf->l_fr_addr_idx + i] + first,
 						pb->l_to_next_size[fr][i]);
 		}
 #endif
-		pb->frame_stat[fr] = GBUFFER_DONE;
+		*gbuf->status = GBUFFER_DONE;
 		pb->grabbing--;
 		wake_up_interruptible(&pb->capq);
 		return;
 	}
 	/* incorrect interrupts? */
 	pb->intr_mask = PLANB_CLR_IRQ;
-	out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
-	printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts"
+	writel(PLANB_CLR_IRQ, &pb->planb_base->intr_stat);
+	printk(KERN_ERR "PlanB: IRQ lockup, cleared interrupts"
 							" unconditionally\n");
 }
 
@@ -1380,16 +1522,22 @@
 
 static int planb_open(struct video_device *dev, int mode)
 {
-	struct planb *pb = (struct planb *)dev;
+	struct planb	*pb = (struct planb *)dev->priv;
+	int		err;
 
-	if (pb->user == 0) {
-		int err;
+	/* first open on driver? */
+	if(pb->vid_user + pb->vbi_user == 0) {
 		if((err = planb_prepare_open(pb)) != 0)
 			return err;
 	}
-	pb->user++;
+	/* first open on video dev? */
+	if(pb->vid_user == 0) {
+		if((err = planb_prepare_video(pb)) != 0)
+			return err;
+	}
+	pb->vid_user++;
 
-	DEBUG("PlanB: device opened\n");
+	DBG("PlanB: device opened\n");
 
 	MOD_INC_USE_COUNT;
 	return 0;   
@@ -1397,44 +1545,46 @@
 
 static void planb_close(struct video_device *dev)
 {
-	struct planb *pb = (struct planb *)dev;
+	struct planb *pb = (struct planb *)dev->priv;
 
-	if(pb->user < 1) /* ??? */
-		return;
 	planb_lock(pb);
-	if (pb->user == 1) {
-		if (pb->overlay) {
+	/* last close? then stop everything... */
+	if(--pb->vid_user == 0) {
+		if(pb->overlay) {
 			planb_dbdma_stop(&pb->planb_base->ch2);
 			planb_dbdma_stop(&pb->planb_base->ch1);
 			pb->overlay = 0;
 		}
-		planb_prepare_close(pb);
+		planb_close_video(pb);
 	}
-	pb->user--;
+	/* last open on PlanB hardware? */
+	if(pb->vid_user + pb->vbi_user == 0)
+		planb_prepare_close(pb);
 	planb_unlock(pb);
 
-	DEBUG("PlanB: device closed\n");
+	DBG("PlanB: device closed\n");
 
-	MOD_DEC_USE_COUNT;  
+	MOD_DEC_USE_COUNT;
+	return;
 }
 
 static long planb_read(struct video_device *v, char *buf, unsigned long count,
 				int nonblock)
 {
-	DEBUG("planb: read request\n");
+	DBG("planb: read request\n");
 	return -EINVAL;
 }
 
 static long planb_write(struct video_device *v, const char *buf,
 				unsigned long count, int nonblock)
 {
-	DEBUG("planb: write request\n");
+	DBG("planb: write request\n");
 	return -EINVAL;
 }
 
 static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
-	struct planb *pb=(struct planb *)dev;
+	struct planb *pb=(struct planb *)dev->priv;
   	
 	switch (cmd)
 	{	
@@ -1442,7 +1592,7 @@
 		{
 			struct video_capability b;
 
-			DEBUG("PlanB: IOCTL VIDIOCGCAP\n");
+			DBG("PlanB: IOCTL VIDIOCGCAP\n");
 
 			strcpy (b.name, pb->video_dev.name);
 			b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
@@ -1461,50 +1611,48 @@
 		case VIDIOCSFBUF:
 		{
                         struct video_buffer v;
-			unsigned short bpp;
 			unsigned int fmt;
 
-			DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
+			DBG("PlanB: IOCTL VIDIOCSFBUF\n");
 
-                        if (!capable(CAP_SYS_ADMIN)
-			|| !capable(CAP_SYS_RAWIO))
+                        if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
                                 return -EPERM;
-                        if (copy_from_user(&v, arg,sizeof(v)))
+                        if (copy_from_user(&v, arg, sizeof(v)))
                                 return -EFAULT;
 			planb_lock(pb);
 			switch(v.depth) {
-			case 8:
-				bpp = 1;
-				fmt = PLANB_GRAY;
+			    /* xawtv only asks for 8 bit in static grey, but
+			     * there is no way to know what it really means.. */
+			    case 8:
+				fmt = VIDEO_PALETTE_GREY;
 				break;
-			case 15:
-			case 16:
-				bpp = 2;
-				fmt = PLANB_COLOUR15;
+			    case 15:
+				fmt = VIDEO_PALETTE_RGB555;
 				break;
-			case 24:
-			case 32:
-				bpp = 4;
-				fmt = PLANB_COLOUR32;
+			    case 32:
+				fmt = VIDEO_PALETTE_RGB32;
 				break;
-			default:
+			    /* We don't deliver these two... */
+			    case 16:
+			    case 24:
+			    default:
 				planb_unlock(pb);
                                 return -EINVAL;
 			}
-			if (bpp * v.width > v.bytesperline) {
+			if (palette2fmt[fmt].bpp * v.width > v.bytesperline) {
 				planb_unlock(pb);
 				return -EINVAL;
 			}
-			pb->win.bpp = bpp;
+			pb->win.bpp = palette2fmt[fmt].bpp;
 			pb->win.color_fmt = fmt;
-			pb->frame_buffer_phys = (unsigned long) v.base;
+			pb->fb.phys = (unsigned long) v.base;
 			pb->win.sheight = v.height;
 			pb->win.swidth = v.width;
 			pb->picture.depth = pb->win.depth = v.depth;
 			pb->win.bpl = pb->win.bpp * pb->win.swidth;
 			pb->win.pad = v.bytesperline - pb->win.bpl;
 
-                        DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"
+                        DBG("PlanB: Display at %p is %d by %d, bytedepth %d,"
 				" bpl %d (+ %d)\n", v.base, v.width,v.height,
 				pb->win.bpp, pb->win.bpl, pb->win.pad);
 
@@ -1521,9 +1669,9 @@
 		{
                         struct video_buffer v;
 
-			DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");
+			DBG("PlanB: IOCTL VIDIOCGFBUF\n");
 
-			v.base = (void *)pb->frame_buffer_phys;
+			v.base = (void *)pb->fb.phys;
 			v.height = pb->win.sheight;
 			v.width = pb->win.swidth;
 			v.depth = pb->win.depth;
@@ -1539,7 +1687,7 @@
                         if(copy_from_user(&i, arg, sizeof(i)))
                                 return -EFAULT;
 			if(i==0) {
-				DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
+				DBG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
 
 				if (!(pb->overlay))
 					return 0;
@@ -1548,9 +1696,9 @@
 				overlay_stop(pb);
 				planb_unlock(pb);
 			} else {
-				DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n");
+				DBG("PlanB: IOCTL VIDIOCCAPTURE Start\n");
 
-				if (pb->frame_buffer_phys == 0 ||
+				if (pb->fb.phys == 0 ||
 					  pb->win.width == 0 ||
 					  pb->win.height == 0)
 					return -EINVAL;
@@ -1569,7 +1717,7 @@
 		{
 			struct video_channel v;
 
-			DEBUG("PlanB: IOCTL VIDIOCGCHAN\n");
+			DBG("PlanB: IOCTL VIDIOCGCHAN\n");
 
 			if(copy_from_user(&v, arg,sizeof(v)))
 				return -EFAULT;
@@ -1598,7 +1746,7 @@
 		{
 			struct video_channel v;
 
-			DEBUG("PlanB: IOCTL VIDIOCSCHAN\n");
+			DBG("PlanB: IOCTL VIDIOCSCHAN\n");
 
 			if(copy_from_user(&v, arg, sizeof(v)))
 				return -EFAULT;
@@ -1616,6 +1764,7 @@
 					maxlines = PLANB_NTSC_MAXLINES;
 					break;
 				default:
+					DBG("       invalid norm %d.\n", v.norm);
 					return -EINVAL;
 					break;
 				}
@@ -1628,7 +1777,7 @@
 				/* Stop overlay if running */
 				suspend_overlay(pb);
 				for(i = 0; i < MAX_GBUFFERS; i++)
-					pb->gnorm_switch[i] = 1;
+					pb->gbuf[i].norm_switch = 1;
 				/* I know it's an overkill, but.... */
 				fill_cmd_buff(pb);
 				/* ok, now init it accordingly */
@@ -1651,6 +1800,7 @@
 					  ~7) | 4), pb);
 				break;
 			default:
+				DBG("       invalid channel %d.\n", v.channel);
 				return -EINVAL;
 				break;
 			}
@@ -1661,22 +1811,9 @@
 		{
 			struct video_picture vp = pb->picture;
 
-			DEBUG("PlanB: IOCTL VIDIOCGPICT\n");
-
-			switch(pb->win.color_fmt) {
-			case PLANB_GRAY:
-				vp.palette = VIDEO_PALETTE_GREY;
-			case PLANB_COLOUR15:
-				vp.palette = VIDEO_PALETTE_RGB555;
-				break;
-			case PLANB_COLOUR32:
-				vp.palette = VIDEO_PALETTE_RGB32;
-				break;
-			default:
-				vp.palette = 0;
-				break;
-			}
+			DBG("PlanB: IOCTL VIDIOCGPICT\n");
 
+			vp.palette = pb->win.color_fmt;
 			if(copy_to_user(arg,&vp,sizeof(vp)))
 				return -EFAULT;
 			return 0;
@@ -1685,12 +1822,13 @@
 		{
 			struct video_picture vp;
 
-			DEBUG("PlanB: IOCTL VIDIOCSPICT\n");
+			DBG("PlanB: IOCTL VIDIOCSPICT\n");
 
 			if(copy_from_user(&vp,arg,sizeof(vp)))
 				return -EFAULT;
 			pb->picture = vp;
 			/* Should we do sanity checks here? */
+			planb_lock(pb);
 			saa_set (SAA7196_BRIG, (unsigned char)
 			    ((pb->picture.brightness) >> 8), pb);
 			saa_set (SAA7196_HUEC, (unsigned char)
@@ -1699,6 +1837,7 @@
 			    ((pb->picture.colour) >> 9), pb);
 			saa_set (SAA7196_CONT, (unsigned char)
 			    ((pb->picture.contrast) >> 9), pb);
+			planb_unlock(pb);
 
 			return 0;
 		}
@@ -1708,7 +1847,7 @@
 			struct video_clip	clip;
 			int 			i;
 			
-			DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
+			DBG("PlanB: IOCTL VIDIOCSWIN\n");
 
 			if(copy_from_user(&vw,arg,sizeof(vw)))
 				return -EFAULT;
@@ -1728,6 +1867,9 @@
 				pb->win.height = vw.height;
 				fill_cmd_buff(pb);
 			}
+                        DBG("PlanB: Window at (%d,%d) size %dx%d\n", vw.x, vw.y, vw.width,
+				vw.height);
+
 			/* Reset clip mask */
 			memset ((void *) pb->mask, 0xff, (pb->maxlines
 					* ((PLANB_MAXPIXELS + 7) & ~7)) / 8);
@@ -1747,7 +1889,7 @@
 		{
 			struct video_window vw;
 
-			DEBUG("PlanB: IOCTL VIDIOCGWIN\n");
+			DBG("PlanB: IOCTL VIDIOCGWIN\n");
 
 			vw.x=pb->win.x;
 			vw.y=pb->win.y;
@@ -1762,30 +1904,32 @@
 			return 0;
 		}
 	        case VIDIOCSYNC: {
-			int i;
+			int		i;
+			gbuf_ptr	gbuf;
 
-			IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");
+			DBG("PlanB: IOCTL VIDIOCSYNC\n");
 
 			if(copy_from_user((void *)&i,arg,sizeof(int)))
 				return -EFAULT;
 
-			IDEBUG("PlanB: sync to frame %d\n", i);
+			DBG("PlanB: sync to frame %d\n", i);
 
                         if(i > (MAX_GBUFFERS - 1) || i < 0)
                                 return -EINVAL;
+			gbuf = &pb->gbuf[i];
 chk_grab:
-                        switch (pb->frame_stat[i]) {
+                        switch (*gbuf->status) {
                         case GBUFFER_UNUSED:
                                 return -EINVAL;
 			case GBUFFER_GRABBING:
-				IDEBUG("PlanB: waiting for grab"
+				DBG("PlanB: waiting for grab"
 							" done (%d)\n", i);
  			        interruptible_sleep_on(&pb->capq);
 				if(signal_pending(current))
 					return -EINTR;
 				goto chk_grab;
                         case GBUFFER_DONE:
-                                pb->frame_stat[i] = GBUFFER_UNUSED;
+                                *gbuf->status = GBUFFER_UNUSED;
                                 break;
                         }
                         return 0;
@@ -1794,17 +1938,19 @@
 	        case VIDIOCMCAPTURE:
 		{
                         struct video_mmap vm;
-			volatile unsigned int status;
+			int		  fr;
 
-			IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
+			DBG("PlanB: IOCTL VIDIOCMCAPTURE\n");
 
 			if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
 				return -EFAULT;
-                        status = pb->frame_stat[vm.frame];
-                        if (status != GBUFFER_UNUSED)
-                                return -EBUSY;
+			fr = vm.frame;
+                        if(fr > (MAX_GBUFFERS - 1) || fr < 0)
+                                return -EINVAL;
+			if (*pb->gbuf[fr].status != GBUFFER_UNUSED)
+				return -EBUSY;
 
-		        return vgrab(pb, &vm);
+			return vgrab(pb, &vm);
 		}
 		
 		case VIDIOCGMBUF:
@@ -1812,7 +1958,7 @@
 			int i;
 			struct video_mbuf vm;
 
-			DEBUG("PlanB: IOCTL VIDIOCGMBUF\n");
+			DBG("PlanB: IOCTL VIDIOCGMBUF\n");
 
 			memset(&vm, 0 , sizeof(vm));
 			vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS;
@@ -1824,11 +1970,27 @@
 			return 0;
 		}
 		
+		case VIDIOCGUNIT:
+		{
+			struct video_unit vu;
+
+			DBG("PlanB: IOCTL VIDIOCGUNIT\n");
+
+			vu.video=pb->video_dev.minor;
+			vu.vbi=pb->vbi_dev.minor;
+			vu.radio=VIDEO_NO_UNIT;
+			vu.audio=VIDEO_NO_UNIT;
+			vu.teletext=VIDEO_NO_UNIT;
+			if(copy_to_user((void *)arg, (void *)&vu, sizeof(vu)))
+				return -EFAULT;
+			return 0;
+		}
+
 		case PLANBIOCGSAAREGS:
 		{
 			struct planb_saa_regs preg;
 
-			DEBUG("PlanB: IOCTL PLANBIOCGSAAREGS\n");
+			DBG("PlanB: IOCTL PLANBIOCGSAAREGS\n");
 
 			if(copy_from_user(&preg, arg, sizeof(preg)))
 				return -EFAULT;
@@ -1845,7 +2007,7 @@
 		{
 			struct planb_saa_regs preg;
 
-			DEBUG("PlanB: IOCTL PLANBIOCSSAAREGS\n");
+			DBG("PlanB: IOCTL PLANBIOCSSAAREGS\n");
 
 			if(copy_from_user(&preg, arg, sizeof(preg)))
 				return -EFAULT;
@@ -1859,10 +2021,14 @@
 		{
 			struct planb_stat_regs pstat;
 
-			DEBUG("PlanB: IOCTL PLANBIOCGSTAT\n");
+			DBG("PlanB: IOCTL PLANBIOCGSTAT\n");
 
-			pstat.ch1_stat = in_le32(&pb->planb_base->ch1.status);
-			pstat.ch2_stat = in_le32(&pb->planb_base->ch2.status);
+			pstat.ch1_stat = readl(&pb->planb_base->ch1.status);
+			pstat.ch2_stat = readl(&pb->planb_base->ch2.status);
+			pstat.ch1_cmdbase = (unsigned long)pb->vid_cbo.start;
+			pstat.ch2_cmdbase = (unsigned long)pb->clip_cbo.start;
+			pstat.ch1_cmdptr = readl(&pb->planb_base->ch1.cmdptr);
+			pstat.ch2_cmdptr = readl(&pb->planb_base->ch2.cmdptr);
 			pstat.saa_stat0 = saa_status(0, pb);
 			pstat.saa_stat1 = saa_status(1, pb);
 
@@ -1871,11 +2037,11 @@
 				return -EFAULT;
 			return 0;
 		}
-		
+
 		case PLANBIOCSMODE: {
 			int v;
 
-			DEBUG("PlanB: IOCTL PLANBIOCSMODE\n");
+			DBG("PlanB: IOCTL PLANBIOCSMODE\n");
 
 			if(copy_from_user(&v, arg, sizeof(v)))
 				return -EFAULT;
@@ -1902,7 +2068,7 @@
 		case PLANBIOCGMODE: {
 			int v=pb->win.mode;
 
-			DEBUG("PlanB: IOCTL PLANBIOCGMODE\n");
+			DBG("PlanB: IOCTL PLANBIOCGMODE\n");
 
 			if(copy_to_user(arg,&v,sizeof(v)))
 				return -EFAULT;
@@ -1912,25 +2078,28 @@
 		case PLANBG_GRAB_BPL: {
 			int v=pb->gbytes_per_line;
 
-			DEBUG("PlanB: IOCTL PLANBG_GRAB_BPL\n");
+			DBG("PlanB: IOCTL PLANBG_GRAB_BPL\n");
 
 			if(copy_to_user(arg,&v,sizeof(v)))
 				return -EFAULT;
 			return 0;
 		}
 #endif /* PLANB_GSCANLINE */
+
+/* These serve only for debugging... */
+#ifdef DEBUG
 		case PLANB_INTR_DEBUG: {
 			int i;
 
-			DEBUG("PlanB: IOCTL PLANB_INTR_DEBUG\n");
+			DBG("PlanB: IOCTL PLANB_INTR_DEBUG\n");
 
 			if(copy_from_user(&i, arg, sizeof(i)))
 				return -EFAULT;
 
 			/* avoid hang ups all together */
 			for (i = 0; i < MAX_GBUFFERS; i++) {
-				if(pb->frame_stat[i] == GBUFFER_GRABBING) {
-					pb->frame_stat[i] = GBUFFER_DONE;
+				if(*pb->gbuf[i].status == GBUFFER_GRABBING) {
+					*pb->gbuf[i].status = GBUFFER_DONE;
 				}
 			}
 			if(pb->grabbing)
@@ -1942,7 +2111,7 @@
 			int i;
 			struct planb_any_regs any;
 
-			DEBUG("PlanB: IOCTL PLANB_INV_REGS\n");
+			DBG("PlanB: IOCTL PLANB_INV_REGS\n");
 
 			if(copy_from_user(&any, arg, sizeof(any)))
 				return -EFAULT;
@@ -1952,42 +2121,70 @@
 				return -EINVAL;
 			for (i = 0; i < any.bytes; i++) {
 				any.data[i] =
-					in_8((unsigned char *)pb->planb_base
+					readb((unsigned char *)pb->planb_base
 							+ any.offset + i);
 			}
 			if(copy_to_user(arg,&any,sizeof(any)))
 				return -EFAULT;
 			return 0;
 		}
+		case PLANBIOCGDBDMABUF:
+		{
+			struct planb_buf_regs buf;
+			dbdma_cmd_ptr dc;
+			int i;
+
+			DBG("PlanB: IOCTL PLANBIOCGDBDMABUF\n");
+
+			if(copy_from_user(&buf, arg, sizeof(buf)))
+				return -EFAULT;
+			buf.end &= ~0xf;
+			if( (buf.start < 0) || (buf.end < 0x10) ||
+			    (buf.end < buf.start+0x10) ||
+			    (buf.end > 2*pb->tab_size) )
+				return -EINVAL;
+
+			printk ("PlanB DBDMA command buffer:\n");
+			for (i=(buf.start>>4); i<=(buf.end>>4); i++) {
+				printk(" 0x%04x:", i<<4);
+				dc = pb->vid_cbo.start + i;
+				printk (" %04x %04x %08x %08x %04x %04x\n",
+				  dc->req_count, dc->command, dc->phy_addr,
+				  dc->cmd_dep, dc->res_count, dc->xfer_status);
+			}
+			return 0;
+		}
+#endif /* DEBUG */
+
 		default:
 		{
-			DEBUG("PlanB: Unimplemented IOCTL\n");
+			DBG("PlanB: Unimplemented IOCTL: %d (0x%x)\n", cmd, cmd);
 			return -ENOIOCTLCMD;
 		}
 	/* Some IOCTLs are currently unsupported on PlanB */
 		case VIDIOCGTUNER: {
-		DEBUG("PlanB: IOCTL VIDIOCGTUNER\n");
+		DBG("PlanB: IOCTL VIDIOCGTUNER\n");
 			goto unimplemented; }
 		case VIDIOCSTUNER: {
-		DEBUG("PlanB: IOCTL VIDIOCSTUNER\n");
+		DBG("PlanB: IOCTL VIDIOCSTUNER\n");
 			goto unimplemented; }
 		case VIDIOCSFREQ: {
-		DEBUG("PlanB: IOCTL VIDIOCSFREQ\n");
+		DBG("PlanB: IOCTL VIDIOCSFREQ\n");
 			goto unimplemented; }
 		case VIDIOCGFREQ: {
-		DEBUG("PlanB: IOCTL VIDIOCGFREQ\n");
+		DBG("PlanB: IOCTL VIDIOCGFREQ\n");
 			goto unimplemented; }
 		case VIDIOCKEY: {
-		DEBUG("PlanB: IOCTL VIDIOCKEY\n");
+		DBG("PlanB: IOCTL VIDIOCKEY\n");
 			goto unimplemented; }
 		case VIDIOCSAUDIO: {
-		DEBUG("PlanB: IOCTL VIDIOCSAUDIO\n");
+		DBG("PlanB: IOCTL VIDIOCSAUDIO\n");
 			goto unimplemented; }
 		case VIDIOCGAUDIO: {
-		DEBUG("PlanB: IOCTL VIDIOCGAUDIO\n");
+		DBG("PlanB: IOCTL VIDIOCGAUDIO\n");
 			goto unimplemented; }
 unimplemented:
-		DEBUG("       Unimplemented\n");
+		DBG("       Unimplemented\n");
 			return -ENOIOCTLCMD;
 	}
 	return 0;
@@ -1995,9 +2192,9 @@
 
 static int planb_mmap(struct video_device *dev, const char *adr, unsigned long size)
 {
-	int i;
-	struct planb *pb = (struct planb *)dev;
-        unsigned long start = (unsigned long)adr;
+	struct planb	*pb = (struct planb *)dev->priv;
+        unsigned long	start = (unsigned long)adr;
+	int		i;
 
 	if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
 	        return -EINVAL;
@@ -2006,7 +2203,7 @@
 		if((err=grabbuf_alloc(pb)))
 			return err;
 	}
-	for (i = 0; i < pb->rawbuf_size; i++) {
+	for (i = 0; i < pb->rawbuf_nchunks; i++) {
 		if (remap_page_range(start, virt_to_phys((void *)pb->rawbuf[i]),
 						PAGE_SIZE, PAGE_SHARED))
 			return -EAGAIN;
@@ -2018,77 +2215,223 @@
 	return 0;
 }
 
+/**********************************
+ * VBI device operation functions *
+ **********************************/
+
+static long planb_vbi_read(struct video_device *dev, char *buf,
+	unsigned long count, int nonblock)
+{
+	struct planb	*pb = (struct planb *)dev->priv;
+	int		q,todo;
+	DECLARE_WAITQUEUE(wait, current);
+
+/* Dummy for now */
+	printk ("PlanB: VBI read %li bytes.\n", count);
+	return (0);
+
+	todo=count;
+	while (todo && todo>(q=VBIBUF_SIZE-pb->vbip)) 
+	{
+		if(copy_to_user((void *) buf, (void *) pb->vbibuf+pb->vbip, q))
+			return -EFAULT;
+		todo-=q;
+		buf+=q;
+
+		add_wait_queue(&pb->vbiq, &wait);
+		current->state = TASK_INTERRUPTIBLE;
+		if (todo && q==VBIBUF_SIZE-pb->vbip) {
+			if(nonblock) {
+				remove_wait_queue(&pb->vbiq, &wait);
+				current->state = TASK_RUNNING;
+				if(count==todo)
+					return -EWOULDBLOCK;
+				return count-todo;
+			}
+			schedule();
+			if(signal_pending(current)) {
+				remove_wait_queue(&pb->vbiq, &wait);
+				current->state = TASK_RUNNING;
+				if(todo==count)
+					return -EINTR;
+				else
+					return count-todo;
+			}
+		}
+		remove_wait_queue(&pb->vbiq, &wait);
+		current->state = TASK_RUNNING;
+	}
+	if (todo) {
+		if(copy_to_user((void *) buf, (void *) pb->vbibuf+pb->vbip,
+		    todo))
+			return -EFAULT;
+		pb->vbip+=todo;
+	}
+	return count;
+}
+
+static unsigned int planb_vbi_poll(struct video_device *dev,
+	struct file *file, poll_table *wait)
+{
+	struct planb	*pb = (struct planb *)dev->priv;
+	unsigned int	mask = 0;
+
+	printk ("PlanB: VBI poll.\n");
+	poll_wait(file, &pb->vbiq, wait);
+
+	if (pb->vbip < VBIBUF_SIZE)
+		mask |= (POLLIN | POLLRDNORM);
+
+	return mask;
+}
+
+static int planb_vbi_open(struct video_device *dev, int flags)
+{
+	struct planb	*pb = (struct planb *)dev->priv;
+	int		err;
+
+	/* first open on the driver? */
+	if(pb->vid_user + pb->vbi_user == 0) {
+		if((err = planb_prepare_open(pb)) != 0)
+			return err;
+	}
+	/* first open on the vbi device? */
+	if(pb->vbi_user == 1) {
+		if((err = planb_prepare_vbi(pb)) != 0)
+			return err;
+	}
+	++pb->vbi_user;
+
+	DBG("PlanB: VBI open\n");
+
+	MOD_INC_USE_COUNT;
+	return 0;   
+}
+
+static void planb_vbi_close(struct video_device *dev)
+{
+	struct planb	*pb = (struct planb *)dev->priv;
+
+	/* last close on vbi device? */
+	if(--pb->vbi_user == 0) {
+		planb_close_vbi(pb);
+	}
+	/* last close on any planb device? */
+	if(pb->vid_user + pb->vbi_user == 0) {
+		planb_prepare_close(pb);
+	}
+
+	DBG("PlanB: VBI close\n");
+
+	MOD_DEC_USE_COUNT;  
+	return;
+}
+
+static int planb_vbi_ioctl(struct video_device *dev, unsigned int cmd,
+	void *arg)
+{
+	switch (cmd) {  
+		/* This is only for alevt */
+		case BTTV_VBISIZE:
+			DBG("PlanB: IOCTL BTTV_VBISIZE.\n");
+			return VBIBUF_SIZE;
+		default:
+			DBG("PlanB: Unimplemented VBI IOCTL no. %i.\n", cmd);
+			return -EINVAL;
+	}
+}
+
 static struct video_device planb_template=
 {
 	owner:		THIS_MODULE,
 	name:		PLANB_DEVICE_NAME,
-	type:		VID_TYPE_OVERLAY,
+	type:		VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
 	hardware:	VID_HARDWARE_PLANB,
 	open:		planb_open,
 	close:		planb_close,
 	read:		planb_read,
-	write:		planb_write,
+	write:		planb_write,	/* not implemented */
 	ioctl:		planb_ioctl,
 	mmap:		planb_mmap,	/* mmap? */
 };
 
-static int init_planb(struct planb *pb)
+static struct video_device planb_vbi_template=
+{
+	owner:		THIS_MODULE,
+	name:		PLANB_VBI_NAME,
+	type:		VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
+	hardware:	VID_HARDWARE_PLANB,
+	open:		planb_vbi_open,
+	close:		planb_vbi_close,
+	read:		planb_vbi_read,
+	write:		planb_write,	/* not implemented */
+	poll:		planb_vbi_poll,
+	ioctl:		planb_vbi_ioctl,
+};
+
+static int __devinit init_planb(struct planb *pb)
 {
 	unsigned char saa_rev;
 	int i, result;
 	unsigned long flags;
 
-	memset ((void *) &pb->win, 0, sizeof (struct planb_window));
+	printk(KERN_INFO "PlanB: PowerMacintosh video input driver rev. %s\n", PLANB_REV);
+
+	pb->video_dev.minor = -1;
+	pb->vid_user = 0;
+
 	/* Simple sanity check */
 	if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) {
 		printk(KERN_ERR "PlanB: Option(s) invalid\n");
 		return -2;
 	}
+	memset ((void *) &pb->win, 0, sizeof (struct planb_window));
 	pb->win.norm = def_norm;
 	pb->win.mode = PLANB_TV_MODE;	/* TV mode */
-	pb->win.interlace=1;
-	pb->win.x=0;
-	pb->win.y=0;
-	pb->win.width=768; /* 640 */
-	pb->win.height=576; /* 480 */
-	pb->maxlines=576;
-#if 0
-	btv->win.cropwidth=768; /* 640 */
-	btv->win.cropheight=576; /* 480 */
-	btv->win.cropx=0;
-	btv->win.cropy=0;
-#endif
-	pb->win.pad=0;
-	pb->win.bpp=4;
-	pb->win.depth=32;
-	pb->win.color_fmt=PLANB_COLOUR32;
-	pb->win.bpl=1024*pb->win.bpp;
-	pb->win.swidth=1024;
-	pb->win.sheight=768;
+	pb->win.interlace = 1;
+	pb->win.x = 0;
+	pb->win.y = 0;
+	pb->win.width = 768; /* 640 */
+	pb->win.height = 576; /* 480 */
+	pb->win.pad = 0;
+	pb->win.bpp = 4;
+	pb->win.depth = 32;
+	pb->win.color_fmt = VIDEO_PALETTE_RGB32;
+	pb->win.bpl = 1024 * pb->win.bpp;
+	pb->win.swidth = 1024;
+	pb->win.sheight = 768;
+	pb->maxlines = 576;
 #ifdef PLANB_GSCANLINE
 	if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE
 				|| (pb->gbytes_per_line <= 0))
 		return -3;
 	else {
 		/* page align pb->gbytes_per_line for DMA purpose */
-		for(i = PAGE_SIZE; pb->gbytes_per_line < (i>>1);)
-			i>>=1;
+		for(i = PAGE_SIZE; pb->gbytes_per_line < (i >> 1);)
+			i >>= 1;
 		pb->gbytes_per_line = i;
 	}
 #endif
 	pb->tab_size = PLANB_MAXLINES + 40;
 	pb->suspend = 0;
 	init_MUTEX(&pb->lock);
-	pb->ch1_cmd = 0;
-	pb->ch2_cmd = 0;
+	pb->vid_cbo.start = 0;
+	pb->clip_cbo.start = 0;
 	pb->mask = 0;
-	pb->priv_space = 0;
-	pb->offset = 0;
-	pb->user = 0;
+	pb->vid_raw = 0;
 	pb->overlay = 0;
 	init_waitqueue_head(&pb->suspendq);
 	pb->cmd_buff_inited = 0;
-	pb->frame_buffer_phys = 0;
+	pb->fb.phys = 0;
+	pb->fb.offset = 0;
+
+	/* VBI stuff: */
+	pb->vbi_dev.minor = -1;
+	pb->vbi_user = 0;
+	pb->vbirunning = 0;
+	pb->vbip = 0;
+	pb->vbibuf = 0;
+	init_waitqueue_head(&pb->vbiq);
 
 	/* Reset DMA controllers */
 	planb_dbdma_stop(&pb->planb_base->ch2);
@@ -2117,9 +2460,6 @@
 	disable_irq(pb->irq);
 	restore_flags(flags);
         
-	/* Now add the template and register the device unit. */
-	memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
-
 	pb->picture.brightness=0x90<<8;
 	pb->picture.contrast = 0x70 << 8;
 	pb->picture.colour = 0x70<<8;
@@ -2127,170 +2467,131 @@
 	pb->picture.whiteness = 0;
 	pb->picture.depth = pb->win.depth;
 
-	pb->frame_stat=NULL;
 	init_waitqueue_head(&pb->capq);
 	for(i=0; i<MAX_GBUFFERS; i++) {
-		pb->gbuf_idx[i] = PLANB_MAX_FBUF * i / PAGE_SIZE;
-		pb->gwidth[i]=0;
-		pb->gheight[i]=0;
-		pb->gfmt[i]=0;
-		pb->cap_cmd[i]=NULL;
+		gbuf_ptr	gbuf = &pb->gbuf[i];
+
+		gbuf->idx = PLANB_MAX_FBUF * i / PAGE_SIZE;
+		gbuf->width=0;
+		gbuf->height=0;
+		gbuf->fmt=0;
+		gbuf->cap_cmd=NULL;
 #ifndef PLANB_GSCANLINE
-		pb->l_fr_addr_idx[i] = MAX_GBUFFERS * (PLANB_MAX_FBUF
+		gbuf->l_fr_addr_idx = MAX_GBUFFERS * (PLANB_MAX_FBUF
 						/ PAGE_SIZE + 1) + MAX_LNUM * i;
-		pb->lsize[i] = 0;
-		pb->lnum[i] = 0;
+		gbuf->lsize = 0;
+		gbuf->lnum = 0;
 #endif
 	}
 	pb->rawbuf=NULL;
 	pb->grabbing=0;
 
 	/* enable interrupts */
-	out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
+	writel(PLANB_CLR_IRQ, &pb->planb_base->intr_stat);
 	pb->intr_mask = PLANB_FRM_IRQ;
 	enable_irq(pb->irq);
 
+	/* Now add the templates and register the device units. */
+	memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
+	pb->video_dev.priv = pb;
+	memcpy(&pb->vbi_dev,&planb_vbi_template,sizeof(planb_vbi_template));
+	
 	if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0)
 		return -1;
+	if(video_register_device(&pb->vbi_dev, VFL_TYPE_VBI, vbi_nr)<0) {
+		video_unregister_device(&pb->video_dev);
+		return -1;
+	}
 
 	return 0;
 }
 
 /*
- *	Scan for a PlanB controller, request the irq and map the io memory 
+ *	Scan for a PlanB controller and map the io memory 
  */
-
 static int find_planb(void)
 {
 	struct planb		*pb;
-	struct device_node	*planb_devices;
-	unsigned char		dev_fn, confreg, bus;
-	unsigned int		old_base, new_base;
-	unsigned int		irq;
-	struct pci_dev 		*pdev;
+	struct pci_dev 		*pdev = NULL;
+	unsigned long		base;
+	int			planb_num = 0;
 
 	if (_machine != _MACH_Pmac)
 		return 0;
 
-	planb_devices = find_devices("planb");
-	if (planb_devices == 0) {
-		planb_num=0;
+	pdev = pci_find_device(APPLE_VENDOR_ID, PLANB_DEV_ID, pdev);
+	if (pdev == NULL) {
 		printk(KERN_WARNING "PlanB: no device found!\n");
 		return planb_num;
 	}
 
-	if (planb_devices->next != NULL)
-		printk(KERN_ERR "Warning: only using first PlanB device!\n");
-	pb = &planbs[0];
+	pb = &planbs;
 	planb_num = 1;
+	base = pdev->resource[0].start;
 
-        if (planb_devices->n_addrs != 1) {
-                printk (KERN_WARNING "PlanB: expecting 1 address for planb "
-                	"(got %d)", planb_devices->n_addrs);
-		return 0;
-	}
-
-	if (planb_devices->n_intrs == 0) {
-		printk(KERN_WARNING "PlanB: no intrs for device %s\n",
-		       planb_devices->full_name);
-		return 0;
-	} else {
-		irq = planb_devices->intrs[0].line;
-	}
-
-	/* Initialize PlanB's PCI registers */
-
-	/* There is a bug with the way OF assigns addresses
-	   to the devices behind the chaos bridge.
-	   control needs only 0x1000 of space, but decodes only
-	   the upper 16 bits. It therefore occupies a full 64K.
-	   OF assigns the planb controller memory within this space;
-	   so we need to change that here in order to access planb. */
-
-	/* We remap to 0xf1000000 in hope that nobody uses it ! */
-
-	bus = (planb_devices->addrs[0].space >> 16) & 0xff;
-	dev_fn = (planb_devices->addrs[0].space >> 8) & 0xff;
-	confreg = planb_devices->addrs[0].space & 0xff;
-	old_base = planb_devices->addrs[0].address;
-	new_base = 0xf1000000;
-
-	DEBUG("PlanB: Found on bus %d, dev %d, func %d, "
-		"membase 0x%x (base reg. 0x%x)\n",
-		bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
-
-	pdev = pci_find_slot (bus, dev_fn);
-	if (!pdev) {
-		printk(KERN_ERR "cannot find slot\n");
-		/* XXX handle error */
-	}
+	DBG("PlanB: Found device %s, membase 0x%lx, irq %d\n",
+		pdev->slot_name, base, pdev->irq);
 
 	/* Enable response in memory space, bus mastering,
 	   use memory write and invalidate */
-	pci_write_config_word (pdev, PCI_COMMAND,
-		PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
-		PCI_COMMAND_INVALIDATE);
-	/* Set PCI Cache line size & latency timer */
-	pci_write_config_byte (pdev, PCI_CACHE_LINE_SIZE, 0x8);
+	pci_enable_device (pdev);
+	pci_set_master (pdev);
+	pci_set_mwi(pdev);
+	/* value copied from MacOS... */
 	pci_write_config_byte (pdev, PCI_LATENCY_TIMER, 0x40);
 
-	/* Set the new base address */
-	pci_write_config_dword (pdev, confreg, new_base);
-
 	planb_regs = (volatile struct planb_registers *)
-						ioremap (new_base, 0x400);
+						ioremap (base, 0x400);
 	pb->planb_base = planb_regs;
-	pb->planb_base_phys = (struct planb_registers *)new_base;
-	pb->irq	= irq;
+	pb->planb_base_bus = (struct planb_registers *)base;
+	pb->irq	= pdev->irq;
 	
 	return planb_num;
 }
 
 static void release_planb(void)
 {
-	int i;
 	struct planb *pb;
 
-	for (i=0;i<planb_num; i++) 
-	{
-		pb=&planbs[i];
+	pb=&planbs;
 
-		/* stop and flash DMAs unconditionally */
-		planb_dbdma_stop(&pb->planb_base->ch2);
-		planb_dbdma_stop(&pb->planb_base->ch1);
+	/* stop and flush DMAs unconditionally */
+	planb_dbdma_stop(&pb->planb_base->ch2);
+	planb_dbdma_stop(&pb->planb_base->ch1);
 
-		/* clear and free interrupts */
-		pb->intr_mask = PLANB_CLR_IRQ;
-		out_le32 (&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
-		free_irq(pb->irq, pb);
+	/* clear and free interrupts */
+	pb->intr_mask = PLANB_CLR_IRQ;
+	writel(PLANB_CLR_IRQ, &pb->planb_base->intr_stat);
+	free_irq(pb->irq, pb);
 
-		/* make sure all allocated memory are freed */
-		planb_prepare_close(pb);
+	/* make sure all allocated memory are freed */
+	planb_prepare_close(pb);
 
-		printk(KERN_INFO "PlanB: unregistering with v4l\n");
-		video_unregister_device(&pb->video_dev);
+	printk(KERN_INFO "PlanB: unregistering with v4l\n");
+	video_unregister_device(&pb->video_dev);
+	video_unregister_device(&pb->vbi_dev);
 
-		/* note that iounmap() does nothing on the PPC right now */
-		iounmap ((void *)pb->planb_base);
-	}
+	/* note that iounmap() does nothing on the PPC right now */
+	iounmap ((void *)pb->planb_base);
 }
 
 static int __init init_planbs(void)
 {
-	int i;
-  
-	if (find_planb()<=0)
+	int planb_num;
+
+	planb_num=find_planb();
+
+	if (planb_num < 0)
 		return -EIO;
+	if (planb_num == 0)
+		return -ENXIO;
 
-	for (i=0; i<planb_num; i++) {
-		if (init_planb(&planbs[i])<0) {
-			printk(KERN_ERR "PlanB: error registering device %d"
-							" with v4l\n", i);
-			release_planb();
-			return -EIO;
-		} 
-		printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
-	}  
+	if (init_planb(&planbs) < 0) {
+		printk(KERN_ERR "PlanB: error registering planb device"
+						" with v4l\n");
+		release_planb();
+		return -EIO;
+	} 
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/planb.h linux/drivers/media/video/planb.h
--- linux.orig/drivers/media/video/planb.h	2001-06-28 00:10:55.000000000 +0000
+++ linux/drivers/media/video/planb.h	2002-07-20 01:08:33.000000000 +0000
@@ -1,14 +1,16 @@
 /* 
-    planb - PlanB frame grabber driver
+    planb - v4l-compatible frame grabber driver for the PlanB hardware
 
     PlanB is used in the 7x00/8x00 series of PowerMacintosh
     Computers as video input DMA controller.
 
-    Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
+    Copyright (C) 1998 - 2002  Michel Lanners <mailto:mlan@cpu.lu>
 
-    Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
+    Based largely on the old bttv driver by Ralph Metzler
 
-    Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
+    Additional debugging and coding by Takashi Oe <mailto:toe@unlserve.unl.edu>
+
+    For more information, see <http://www.cpu.lu/~mlan/planb.html>
 
 
     This program is free software; you can redistribute it and/or modify
@@ -26,18 +28,17 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-/* $Id: planb.h,v 1.13 1999/05/03 19:28:56 mlan Exp $ */
+/* $Id: planb.h,v 2.9 2002/04/03 15:57:57 mlan Exp mlan $ */
 
 #ifndef _PLANB_H_
 #define _PLANB_H_
 
-#ifdef __KERNEL__
-#include <asm/dbdma.h>
-#include "saa7196.h"
-#endif /* __KERNEL__ */
-
 #define PLANB_DEVICE_NAME	"Apple PlanB Video-In"
-#define PLANB_REV		"1.0"
+#define PLANB_VBI_NAME		"Apple PlanB VBI"
+#define PLANB_REV		"2.11"
+
+#define APPLE_VENDOR_ID		0x106b
+#define PLANB_DEV_ID		0x0004
 
 #ifdef __KERNEL__
 //#define PLANB_GSCANLINE	/* use this if apps have the notion of */
@@ -47,15 +48,24 @@
 #define PLANB_MAXLINES 576
 #define PLANB_NTSC_MAXLINES 480
 
+/* Max VBI data buffer size */
+#define VBI_LINESIZE 1024	/* on SAA7196, a line can be max. 1024 pixels */
+#define VBI_START 7		/* VBI starts at line 7 */
+#define VBI_MAXLINES 16		/* 16 lines per field */
+/* We have 2 of these, but return them one at a time */
+#define VBIBUF_SIZE (VBI_LINESIZE * VBI_MAXLINES)
+
+#define LINE_OFFSET 1		/* between line 1 and SAA's first valid line */
+
 /* Uncomment your preferred norm ;-) */
 #define PLANB_DEF_NORM VIDEO_MODE_PAL
 //#define PLANB_DEF_NORM VIDEO_MODE_NTSC
 //#define PLANB_DEF_NORM VIDEO_MODE_SECAM
 
 /* fields settings */
-#define PLANB_GRAY	0x1	/*  8-bit mono? */
-#define PLANB_COLOUR15	0x2	/* 16-bit mode */
-#define PLANB_COLOUR32	0x4	/* 32-bit mode */
+#define PLANB_SIZE8	0x1	/*  8-bit mono? */
+#define PLANB_SIZE16	0x2	/* 16-bit mode */
+#define PLANB_SIZE32	0x4	/* 32-bit mode */
 #define PLANB_CLIPMASK	0x8	/* hardware clipmasking */
 
 /* misc. flags for PlanB DMA operation */
@@ -67,6 +77,41 @@
 #define DMA_ABORT	0x2	/* error or just out of sync if set */
 #define ODD_FIELD	0x4	/* odd field is detected if set */
 
+/* format info and correspondance */
+struct fmts {
+	int	bpp;		/* bytes per pixel */
+	int	pb_fmt;		/* planb format (DMA engine sub 0x40/0x44 ) */
+	int	saa_fmt;	/* saa format:				bit
+				   SAA7196 sub 0x20: bits FS0		0
+				   			  FS1		1
+					   sub 0x30: bit  MCT		4
+							  LLV		5 */
+};
+
+/* This is supposed to match the VIDEO_PALETTE_* defines in
+ * struct video_picture in videodev.h */
+static struct fmts palette2fmt[] = {
+	{ 0, 0,			   0 },
+	{ 1, PLANB_SIZE8,	0x33 },	/* VIDEO_PALETTE_GREY */
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 4, PLANB_SIZE32,	   2 },	/* VIDEO_PALETTE_RGB32 */
+	{ 2, PLANB_SIZE16,	   0 },	/* VIDEO_PALETTE_RGB555 */
+	{ 2, PLANB_SIZE16,	0x21 },	/* VIDEO_PALETTE_YUV422 */
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+	{ 0, 0,			   0 },
+};
+
+#define PLANB_PALETTE_MAX (sizeof palette2fmt / sizeof (struct fmts))
+
 /* for capture operations */
 #define MAX_GBUFFERS	2
 /* note PLANB_MAX_FBUF must be divisible by PAGE_SIZE */
@@ -87,6 +132,10 @@
 struct planb_stat_regs {
 	unsigned int ch1_stat;
 	unsigned int ch2_stat;
+	unsigned long ch1_cmdbase;
+	unsigned long ch2_cmdbase;
+	unsigned int ch1_cmdptr;
+	unsigned int ch2_cmdptr;
 	unsigned char saa_stat0;
 	unsigned char saa_stat1;
 };
@@ -97,23 +146,43 @@
 	unsigned char data[128];
 };
 
+struct planb_buf_regs {
+	unsigned int start;
+	unsigned int end;
+};
+
 /* planb private ioctls */
-#define PLANBIOCGSAAREGS	_IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs)	/* Read a saa7196 reg value */
-#define PLANBIOCSSAAREGS	_IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs)	/* Set a saa7196 reg value */
-#define PLANBIOCGSTAT		_IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs)	/* Read planb status */
+/* Read a saa7196 reg value */
+#define PLANBIOCGSAAREGS	_IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs)
+/* Set a saa7196 reg value */
+#define PLANBIOCSSAAREGS	_IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs)
+/* Read planb status */
+#define PLANBIOCGSTAT		_IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs)
+/* Get TV/VTR mode */
 #define PLANB_TV_MODE		1
 #define PLANB_VTR_MODE		2
-#define PLANBIOCGMODE		_IOR('v', BASE_VIDIOCPRIVATE + 3, int)	/* Get TV/VTR mode */
-#define PLANBIOCSMODE		_IOW('v', BASE_VIDIOCPRIVATE + 4, int)	/* Set TV/VTR mode */
+#define PLANBIOCGMODE		_IOR('v', BASE_VIDIOCPRIVATE + 3, int)
+/* Set TV/VTR mode */
+#define PLANBIOCSMODE		_IOW('v', BASE_VIDIOCPRIVATE + 4, int)
 
 #ifdef PLANB_GSCANLINE
-#define PLANBG_GRAB_BPL		_IOR('v', BASE_VIDIOCPRIVATE + 5, int)	/* # of bytes per scanline in grab buffer */
+/* # of bytes per scanline in grab buffer */
+#define PLANBG_GRAB_BPL		_IOR('v', BASE_VIDIOCPRIVATE + 5, int)
 #endif
 
+/* This doesn't really belong here, but until someone cleans up (or defines
+   in the first place ;-) the VBI API, it helps alevt... */
+#define BTTV_VBISIZE		_IOR('v', BASE_VIDIOCPRIVATE + 8, int)
+
+/* Various debugging IOCTLs */
+#ifdef DEBUG
 /* call wake_up_interruptible() with appropriate actions */
 #define PLANB_INTR_DEBUG	_IOW('v', BASE_VIDIOCPRIVATE + 20, int)
 /* investigate which reg does what */
 #define PLANB_INV_REGS		_IOWR('v', BASE_VIDIOCPRIVATE + 21, struct planb_any_regs)
+/* Dump DBDMA command buffer from (int) to (int) */
+#define PLANBIOCGDBDMABUF	_IOW('v', BASE_VIDIOCPRIVATE + 22, struct planb_buf_regs)
+#endif /* DEBUG */
 
 #ifdef __KERNEL__
 
@@ -121,27 +190,44 @@
 #define PLANB_SET(x)	((x) << 16 | (x))
 #define PLANB_CLR(x)	((x) << 16)
 
-/* This represents the physical register layout */
-struct planb_registers {
-	volatile struct dbdma_regs	ch1;		/* 0x00: video in */
-	volatile unsigned int		even;		/* 0x40: even field setting */
-	volatile unsigned int		odd;		/* 0x44; odd field setting */
-	unsigned int			pad1[14];	/* empty? */
-	volatile struct dbdma_regs	ch2;		/* 0x80: clipmask out */
-	unsigned int			pad2[16];	/* 0xc0: empty? */
-	volatile unsigned int		reg3;		/* 0x100: ???? */
-	volatile unsigned int		intr_stat;	/* 0x104: irq status */
+typedef volatile struct dbdma_cmd dbdma_cmd_t;
+typedef volatile struct dbdma_cmd *dbdma_cmd_ptr;
+typedef volatile struct dbdma_regs dbdma_regs_t;
+typedef volatile struct dbdma_regs *dbdma_regs_ptr;
+
+typedef struct gbuffer gbuf_t;
+typedef struct gbuffer *gbuf_ptr;
+
+/* grab buffer status */
+#define GBUFFER_UNUSED		0x00U
+#define GBUFFER_GRABBING	0x01U
+#define GBUFFER_DONE		0x02U
+
+/* planb interrupt status values (0x104: irq status) */
 #define PLANB_CLR_IRQ		0x00		/* clear Plan B interrupt */
 #define PLANB_GEN_IRQ		0x01		/* assert Plan B interrupt */
 #define PLANB_FRM_IRQ		0x0100		/* end of frame */
-	unsigned int			pad3[1];	/* empty? */
-	volatile unsigned int		reg5;		/* 0x10c: ??? */
-	unsigned int			pad4[60];	/* empty? */
-	volatile unsigned char		saa_addr;	/* 0x200: SAA subadr */
-	char				pad5[3];
-	volatile unsigned char		saa_regval;	/* SAA7196 write reg. val */
-	char				pad6[3];
-	volatile unsigned char		saa_status;	/* SAA7196 status byte */
+
+#define PLANB_DUMMY 40	/* # of command buf's allocated for pre-capture seq. */
+
+/* This represents the physical register layout */
+struct planb_registers {
+	dbdma_regs_t		ch1;		/* 0x00: video in */
+	volatile u32		even;		/* 0x40: even field setting */
+	volatile u32		odd;		/* 0x44; odd field setting */
+	u32			pad1[14];	/* empty? */
+	dbdma_regs_t		ch2;		/* 0x80: clipmask out */
+	u32			pad2[16];	/* 0xc0: empty? */
+	volatile u32		reg3;		/* 0x100: ???? */
+	volatile u32		intr_stat;	/* 0x104: irq status */
+	u32			pad3[1];	/* empty? */
+	volatile u32		reg5;		/* 0x10c: ??? */
+	u32			pad4[60];	/* empty? */
+	volatile u8		saa_addr;	/* 0x200: SAA subadr */
+	u8			pad5[3];
+	volatile u8		saa_regval;	/* SAA7196 write reg. val */
+	u8			pad6[3];
+	volatile u8		saa_status;	/* SAA7196 status byte */
 	/* There is more unused stuff here */
 };
 
@@ -163,67 +249,105 @@
 	struct dbdma_cmd cmd;
 };
 
+/* Framebuffer info */
+struct planb_fb {
+	unsigned long	phys;		/* Framebuffer phys. base address */
+	int		offset;		/* offset of pixel 1 */
+};
+
+/* DBDMA command buffer descriptor */
+struct dbdma_cmd_buf {
+	dbdma_cmd_ptr	start;
+	dbdma_cmd_ptr	jumpaddr;	/* where are we called from? */
+	unsigned int	size;
+	unsigned long	bus;		/* start address as seen from the bus */
+};
+
+/* grab buffer descriptor */
+struct gbuffer {
+	dbdma_cmd_ptr		cap_cmd;
+	dbdma_cmd_ptr		last_cmd;
+	dbdma_cmd_ptr		pre_cmd;
+	int			idx;
+	int			need_pre_capture;
+	int			width;
+	int			height;
+	unsigned int		fmt;
+	int			norm_switch;
+#ifndef PLANB_GSCANLINE
+	int			l_fr_addr_idx;
+	int			lsize;
+	int			lnum;
+#endif
+        volatile unsigned int	*status;	/* ptr to status value */
+};
+
 struct planb {
-	struct	video_device video_dev;
-	struct	video_picture picture;		/* Current picture params */
-	struct	video_audio audio_dev;		/* Current audio params */
+/* the video device: */
+	struct video_device	video_dev;
+	struct video_picture	picture;	/* Current picture params */
+	int			vid_user;	/* Users on video device */
+	void			*vid_raw;	/* Org. alloc. mem for kfree */
+	struct dbdma_cmd_buf	vid_cbo;	/* odd video dbdma cmd buf */
+	struct dbdma_cmd_buf	vid_cbe;	/* even */
+	void			*clip_raw;
+	struct dbdma_cmd_buf	clip_cbo;	/* odd clip dbdma cmd buf */
+	struct dbdma_cmd_buf	clip_cbe;	/* even */
+	dbdma_cmd_ptr		overlay_last1;
+	dbdma_cmd_ptr		overlay_last2;
   
-	volatile struct planb_registers *planb_base;	/* virt base of planb */
-	struct planb_registers *planb_base_phys;	/* phys base of planb */
-	void	*priv_space;			/* Org. alloc. mem for kfree */
-	int	user;
-	unsigned int tab_size;
-	int     maxlines;
-	struct semaphore lock;
-	unsigned int	irq;			/* interrupt number */
-	volatile unsigned int intr_mask;
-
-	int	overlay;			/* overlay running? */
-	struct	planb_window win;
-	unsigned long frame_buffer_phys;	/* We need phys for DMA */
-	int	offset;				/* offset of pixel 1 */
-	volatile struct dbdma_cmd *ch1_cmd;	/* Video In DMA cmd buffer */
-	volatile struct dbdma_cmd *ch2_cmd;	/* Clip Out DMA cmd buffer */
-	volatile struct dbdma_cmd *overlay_last1;
-	volatile struct dbdma_cmd *overlay_last2;
-	unsigned long ch1_cmd_phys;
-	volatile unsigned char *mask;		/* Clipmask buffer */
-	int suspend;
-	wait_queue_head_t suspendq;
-	struct planb_suspend suspended;
-	int	cmd_buff_inited;		/* cmd buffer inited? */
-
-	int grabbing;
-	unsigned int gcount;
-	wait_queue_head_t capq;
-	int last_fr;
-	int prev_last_fr;
-	unsigned char **rawbuf;
-	int rawbuf_size;
-	int gbuf_idx[MAX_GBUFFERS];
-	volatile struct dbdma_cmd *cap_cmd[MAX_GBUFFERS];
-	volatile struct dbdma_cmd *last_cmd[MAX_GBUFFERS];
-	volatile struct dbdma_cmd *pre_cmd[MAX_GBUFFERS];
-	int need_pre_capture[MAX_GBUFFERS];
-#define PLANB_DUMMY 40	/* # of command buf's allocated for pre-capture seq. */
-	int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
-	unsigned int gfmt[MAX_GBUFFERS];
-	int gnorm_switch[MAX_GBUFFERS];
-        volatile unsigned int *frame_stat;
-#define GBUFFER_UNUSED       0x00U
-#define GBUFFER_GRABBING     0x01U
-#define GBUFFER_DONE         0x02U
+/* the hardware: */
+	volatile struct planb_registers
+				*planb_base;	/* virt base of planb */
+	struct planb_registers	*planb_base_bus; /* phys base of planb */
+	unsigned int		tab_size;
+	int     		maxlines;
+	unsigned int		irq;		/* interrupt number */
+	volatile unsigned int	intr_mask;
+	struct planb_fb		fb;		/* Framebuffer info */
+
+/* generic stuff: */
+	void			*jump_raw;	/* jump buffer raw space */
+	dbdma_cmd_ptr		jumpbuf;	/* same, DBDMA_ALIGN'ed */
+	struct semaphore	lock;
+	int			overlay;	/* overlay running? */
+	struct planb_window	win;
+	volatile unsigned char	*mask;		/* Clipmask buffer */
+	int			suspend;
+	wait_queue_head_t	suspendq;
+	struct planb_suspend	suspended;
+	int			cmd_buff_inited; /* cmd buffer inited? */
+
+/* grabbing stuff: */ 
+	int			grabbing;
+	unsigned int		gcount;
+	wait_queue_head_t	capq;
+	int			last_fr;
+	int			prev_last_fr;
+	unsigned char		**rawbuf;
+	int			rawbuf_nchunks;
+	struct gbuffer		gbuf[MAX_GBUFFERS];
+
 #ifdef PLANB_GSCANLINE
-	int gbytes_per_line;
+	int			gbytes_per_line;
 #else
-#define MAX_LNUM 431	/* change this if PLANB_MAXLINES or */
+#define MAX_LNUM 576	/* change this if PLANB_MAXLINES or */
 			/* PLANB_MAXPIXELS changes */
-	int l_fr_addr_idx[MAX_GBUFFERS];
-	unsigned char *l_to_addr[MAX_GBUFFERS][MAX_LNUM];
-	int l_to_next_idx[MAX_GBUFFERS][MAX_LNUM];
-	int l_to_next_size[MAX_GBUFFERS][MAX_LNUM];
-	int lsize[MAX_GBUFFERS], lnum[MAX_GBUFFERS];
-#endif
+	unsigned char		*l_to_addr[MAX_GBUFFERS][MAX_LNUM];
+	int			l_to_next_idx[MAX_GBUFFERS][MAX_LNUM];
+	int			l_to_next_size[MAX_GBUFFERS][MAX_LNUM];
+#endif /* PLANB_GSCANLINE */
+
+/* VBI stuff: */
+	struct video_device	vbi_dev;	/* VBI data device */
+	int			vbi_user;	/* Users on vbi device */
+	void			*vbi_raw;
+	struct dbdma_cmd_buf	vbi_cbo;	/* odd VBI dbdma cmd buf */
+	struct dbdma_cmd_buf	vbi_cbe;	/* even */
+	int			vbirunning;
+	int			vbip;		/* pointer into VBI buffer */
+	unsigned char		*vbibuf;	/* buffer for VBI data */
+	wait_queue_head_t	vbiq;
 };
 
 #endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/pms.c linux/drivers/media/video/pms.c
--- linux.orig/drivers/media/video/pms.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/media/video/pms.c	2002-07-20 01:08:30.000000000 +0000
@@ -69,12 +69,12 @@
 
 	
 
-extern __inline__ void mvv_write(u8 index, u8 value)
+static inline void mvv_write(u8 index, u8 value)
 {
 	outw(index|(value<<8), io_port);
 }
 
-extern __inline__ u8 mvv_read(u8 index)
+static inline u8 mvv_read(u8 index)
 {
 	outb(index, io_port);
 	return inb(data_port);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/saa7196.h linux/drivers/media/video/saa7196.h
--- linux.orig/drivers/media/video/saa7196.h	1999-05-07 18:05:30.000000000 +0000
+++ linux/drivers/media/video/saa7196.h	2002-07-20 01:08:26.000000000 +0000
@@ -3,19 +3,17 @@
     scaler, and clock generator circuit (DESCpro), as used in
     the PlanB video input of the Powermac 7x00/8x00 series.
   
-    Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
+    Copyright (C) 1998 - 2002 Michel Lanners <mailto:mlan@cpu.lu>
 
     The register defines are shamelessly copied from the meteor
-    driver out of NetBSD (with permission),
+    driver out of FreeBSD (with permission),
     and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe
     (Thanks !)
   
-    Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu)
-
     The default values used for PlanB are my mistakes.
 */
 
-/* $Id: saa7196.h,v 1.5 1999/03/26 23:28:47 mlan Exp $ */
+/* $Id: saa7196.h,v 2.3 2002/04/03 15:57:57 mlan Exp mlan $ */
 
 #ifndef _SAA7196_H_
 #define _SAA7196_H_
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/stradis.c linux/drivers/media/video/stradis.c
--- linux.orig/drivers/media/video/stradis.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/media/video/stradis.c	2002-07-20 01:08:32.000000000 +0000
@@ -1972,7 +1972,9 @@
 {
 	struct saa7146 *saa = (struct saa7146 *) dev;
 
-	saa->video_dev.busy = 0;
+	/* FIXME: Don't do it this way, use the video_device->fops
+	 * registration for a sane implementation of multiple opens */
+	saa->video_dev.users--;
 	saa->user++;
 	if (saa->user > 1)
 		return 0;	/* device open already, don't reset */
@@ -1984,7 +1986,7 @@
 {
 	struct saa7146 *saa = (struct saa7146 *) dev;
 	saa->user--;
-	saa->video_dev.busy = 0;
+	saa->video_dev.users++;
 	if (saa->user > 0)	/* still someone using device */
 		return;
 	saawrite(0x007f0000, SAA7146_MC1);	/* stop all overlay dma */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/tda7432.c linux/drivers/media/video/tda7432.c
--- linux.orig/drivers/media/video/tda7432.c	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/tda7432.c	2002-07-20 01:08:27.000000000 +0000
@@ -518,7 +518,7 @@
         &driver
 };
 
-int tda7432_init(void)
+static int tda7432_init(void)
 {
 
 	if ( (loudness < 0) || (loudness > 15) )
@@ -531,7 +531,7 @@
 	return 0;
 }
 
-void tda7432_fini(void)
+static void tda7432_fini(void)
 {
 	i2c_del_driver(&driver);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/tda9875.c linux/drivers/media/video/tda9875.c
--- linux.orig/drivers/media/video/tda9875.c	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/tda9875.c	2002-07-20 01:08:34.000000000 +0000
@@ -147,6 +147,24 @@
 }
 #endif
 
+static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
+{
+        unsigned char write[1];
+        unsigned char read[1];
+        struct i2c_msg msgs[2] = {
+                { addr, 0,        1, write },
+                { addr, I2C_M_RD, 1, read  }
+        };
+        write[0] = reg;
+
+        if (2 != i2c_transfer(adap,msgs,2)) {
+                printk(KERN_WARNING "tda9875: I/O error (read2)\n");
+                return -1;
+        }
+        dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
+        return read[0];
+}
+
 static void tda9875_set(struct i2c_client *client)
 {
 	struct tda9875 *tda = client->data;
@@ -215,6 +233,22 @@
  * i2c interface functions *
  * *********************** */
 
+static int tda9875_checkit(struct i2c_adapter *adap, int addr)
+{
+	int dic,rev;
+
+	dic=i2c_read_register(adap,addr,254);
+	rev=i2c_read_register(adap,addr,255);
+
+	if(dic==0 || dic==2) { // tda9875 and tda9875A
+		printk("tda9875: TDA9875%s Rev.%d detected at 0x%x\n",
+		dic==0?"":"A", rev,addr<<1);
+		return 1;
+	}
+	printk("tda9875: no such chip at 0x%x (dic=0x%x rev=0x%x)\n",addr<<1,dic,rev);
+	return(0);
+}
+
 static int tda9875_attach(struct i2c_adapter *adap, int addr,
 			  unsigned short flags, int kind)
 {
@@ -232,6 +266,11 @@
         client->adapter = adap;
         client->addr = addr;
 	client->data = t;
+
+	if(!tda9875_checkit(adap,addr)) {
+		kfree(t);
+		return 1;
+	}
 	
 	do_tda9875_init(client);
 	MOD_INC_USE_COUNT;
@@ -375,22 +414,19 @@
         &driver
 };
 
-#ifdef MODULE
-int init_module(void)
-#else
-int tda9875_init(void)
-#endif
+static int tda9875_init(void)
 {
 	i2c_add_driver(&driver);
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void tda9875_fini(void)
 {
 	i2c_del_driver(&driver);
 }
-#endif
+
+module_init(tda9875_init);
+module_exit(tda9875_fini);
 
 /*
  * Local variables:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/tuner.c linux/drivers/media/video/tuner.c
--- linux.orig/drivers/media/video/tuner.c	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/tuner.c	2002-07-20 01:08:30.000000000 +0000
@@ -154,7 +154,7 @@
 	  16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
         { "Alps TSBE1",TEMIC,PAL,
 	  16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
-        { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modtec MM205 */
+        { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
 	  16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
 
         { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
@@ -175,7 +175,7 @@
         { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
           16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
 
-        { "Temic PAL (4009 FR5)", TEMIC, PAL,
+        { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
           16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
         { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
           16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
@@ -271,7 +271,7 @@
 }
 #endif
 // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
-int mt2032_init(struct i2c_client *c)
+static int mt2032_init(struct i2c_client *c)
 {
         unsigned char buf[21];
         int ret,xogc,xok=0;
@@ -345,7 +345,7 @@
 
 
 // IsSpurInBand()?
-int mt2032_spurcheck(int f1, int f2, int spectrum_from,int spectrum_to)
+static int mt2032_spurcheck(int f1, int f2, int spectrum_from,int spectrum_to)
 {
 	int n1=1,n2,f;
 
@@ -373,7 +373,7 @@
 	return 1;
 }
 
-int mt2032_compute_freq(int rfin, int if1, int if2, int spectrum_from,
+static int mt2032_compute_freq(int rfin, int if1, int if2, int spectrum_from,
 	int spectrum_to, unsigned char *buf, int *ret_sel, int xogc) //all in Hz
 {
         int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
@@ -449,7 +449,7 @@
 	return 0;
 }
 
-int mt2032_check_lo_lock(struct i2c_client *c)
+static int mt2032_check_lo_lock(struct i2c_client *c)
 {
 	int try,lock=0;
 	unsigned char buf[2];
@@ -469,7 +469,7 @@
         return lock;
 }
 
-int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
+static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
 {
 	unsigned char buf[2];
 	int tad1;
@@ -505,7 +505,7 @@
 }
 
 
-void mt2032_set_if_freq(struct i2c_client *c,int rfin, int if1, int if2, int from, int to)
+static void mt2032_set_if_freq(struct i2c_client *c,int rfin, int if1, int if2, int from, int to)
 {
 	unsigned char buf[21];
 	int lint_try,ret,sel,lock=0;
@@ -560,7 +560,7 @@
 }
 
 
-void mt2032_set_tv_freq(struct i2c_client *c, int freq, int norm)
+static void mt2032_set_tv_freq(struct i2c_client *c, int freq, int norm)
 {
 	int if2,from,to;
 
@@ -815,14 +815,27 @@
 
 static int tuner_probe(struct i2c_adapter *adap)
 {
+	int rc;
+
 	if (0 != addr) {
 		normal_i2c_range[0] = addr;
 		normal_i2c_range[1] = addr;
 	}
 	this_adap = 0;
-	if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
-		return i2c_probe(adap, &addr_data, tuner_attach);
-	return 0;
+	switch (adap->id) {
+	case I2C_ALGO_BIT | I2C_HW_B_BT848:
+	case I2C_ALGO_SAA7134:
+		printk("tuner: probing %s i2c adapter [id=0x%x]\n",
+		       adap->name,adap->id);
+		rc = i2c_probe(adap, &addr_data, tuner_attach);
+		break;
+	default:
+		printk("tuner: ignoring %s i2c adapter [id=0x%x]\n",
+		       adap->name,adap->id);
+		rc = 0;
+		/* nothing */
+	}
+	return rc;
 }
 
 static int tuner_detach(struct i2c_client *client)
@@ -948,39 +961,34 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-        "i2c TV tuner driver",
-        I2C_DRIVERID_TUNER,
-        I2C_DF_NOTIFY,
-        tuner_probe,
-        tuner_detach,
-        tuner_command,
+        name:           "i2c TV tuner driver",
+        id:             I2C_DRIVERID_TUNER,
+        flags:          I2C_DF_NOTIFY,
+        attach_adapter: tuner_probe,
+        detach_client:  tuner_detach,
+        command:        tuner_command,
 };
-
 static struct i2c_client client_template =
 {
-        "(unset)",		/* name       */
-        -1,
-        0,
-        0,
-        NULL,
-        &driver
+        name:   "(unset)",
+	flags:  I2C_CLIENT_ALLOW_USE,
+        driver: &driver,
 };
 
-EXPORT_NO_SYMBOLS;
-
-int tuner_init_module(void)
+static int tuner_init_module(void)
 {
 	i2c_add_driver(&driver);
 	return 0;
 }
 
-void tuner_cleanup_module(void)
+static void tuner_cleanup_module(void)
 {
 	i2c_del_driver(&driver);
 }
 
 module_init(tuner_init_module);
 module_exit(tuner_cleanup_module);
+EXPORT_NO_SYMBOLS;
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/tuner.h linux/drivers/media/video/tuner.h
--- linux.orig/drivers/media/video/tuner.h	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/tuner.h	2002-07-20 01:08:27.000000000 +0000
@@ -22,6 +22,8 @@
 #ifndef _TUNER_H
 #define _TUNER_H
 
+#include "id.h"
+
 #define TUNER_TEMIC_PAL     0        /* 4002 FH5 (3X 7756, 9483) */
 #define TUNER_PHILIPS_PAL_I 1
 #define TUNER_PHILIPS_NTSC  2
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/tvaudio.c linux/drivers/media/video/tvaudio.c
--- linux.orig/drivers/media/video/tvaudio.c	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/tvaudio.c	2002-07-20 01:08:31.000000000 +0000
@@ -120,14 +120,17 @@
 	/* current settings */
 	__u16 left,right,treble,bass,mode;
 	int prevmode;
+	int norm;
 	/* thread */
 	struct task_struct  *thread;
 	struct semaphore    *notify;
 	wait_queue_head_t    wq;
 	struct timer_list    wt;
 	int                  done;
+	int                  watch_stereo;
 };
 
+#define VIDEO_MODE_RADIO 16      /* norm magic for radio mode */
 
 /* ---------------------------------------------------------------------- */
 /* i2c addresses                                                          */
@@ -139,7 +142,7 @@
 	I2C_TDA9840   >> 1,
 	I2C_TDA985x_L >> 1,
 	I2C_TDA985x_H >> 1,
-	I2C_TDA9874A  >> 1,
+	I2C_TDA9874   >> 1,
 	I2C_PIC16C54  >> 1,
 	I2C_CLIENT_END };
 static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
@@ -296,9 +299,9 @@
 		dprintk("%s: thread wakeup\n", chip->c.name);
 		if (chip->done || signal_pending(current))
 			break;
-		
-		if (0 != chip->mode)
-			/* don't do anything if mode != auto */
+
+		/* don't do anything for radio or if mode != auto */
+		if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0)
 			continue;
 		
 		/* have a look what's going on */
@@ -316,7 +319,7 @@
 	return 0;
 }
 
-void generic_checkmode(struct CHIPSTATE *chip)
+static void generic_checkmode(struct CHIPSTATE *chip)
 {
 	struct CHIPDESC  *desc = chiplist + chip->type;
 	int mode = desc->getmode(chip);
@@ -327,12 +330,12 @@
 	dprintk("%s: thread checkmode\n", chip->c.name);
 	chip->prevmode = mode;
 
-	if (mode & VIDEO_SOUND_LANG1)
+	if (mode & VIDEO_SOUND_STEREO)
+		desc->setmode(chip,VIDEO_SOUND_STEREO);
+	else if (mode & VIDEO_SOUND_LANG1)
 		desc->setmode(chip,VIDEO_SOUND_LANG1);
 	else if (mode & VIDEO_SOUND_LANG2)
 		desc->setmode(chip,VIDEO_SOUND_LANG2);
-	else if (mode & VIDEO_SOUND_STEREO)
-		desc->setmode(chip,VIDEO_SOUND_STEREO);
 	else
 		desc->setmode(chip,VIDEO_SOUND_MONO);
 }
@@ -360,7 +363,7 @@
 #define TDA9840_TEST_INT1SN 0x1 /* Integration time 0.5s when set */
 #define TDA9840_TEST_INTFU 0x02 /* Disables integrator function */
 
-int  tda9840_getmode(struct CHIPSTATE *chip)
+static int tda9840_getmode(struct CHIPSTATE *chip)
 {
 	int val, mode;
 	
@@ -376,7 +379,7 @@
 	return mode;
 }
 
-void tda9840_setmode(struct CHIPSTATE *chip, int mode)
+static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
 {
 	int update = 1;
 	int t = chip->shadow.bytes[TDA9840_SW + 1] & ~0x7e;
@@ -502,11 +505,11 @@
  * -10% (0x2), nominal (0x3), +10% (0x6), +20% (0x5), +30% (0x4) */
 #define TDA985x_ADJ	1<<7 /* Stereo adjust on/off (wideband and spectral */
 
-int tda9855_volume(int val) { return val/0x2e8+0x27; }
-int tda9855_bass(int val)   { return val/0xccc+0x06; }
-int tda9855_treble(int val) { return (val/0x1c71+0x3)<<1; }
+static int tda9855_volume(int val) { return val/0x2e8+0x27; }
+static int tda9855_bass(int val)   { return val/0xccc+0x06; }
+static int tda9855_treble(int val) { return (val/0x1c71+0x3)<<1; }
 
-int  tda985x_getmode(struct CHIPSTATE *chip)
+static int  tda985x_getmode(struct CHIPSTATE *chip)
 {
 	int mode;
 
@@ -517,7 +520,7 @@
 	return mode | VIDEO_SOUND_MONO;
 }
 
-void tda985x_setmode(struct CHIPSTATE *chip, int mode)
+static void tda985x_setmode(struct CHIPSTATE *chip, int mode)
 {
 	int update = 1;
 	int c6 = chip->shadow.bytes[TDA985x_C6+1] & 0x3f;
@@ -657,7 +660,7 @@
 #define TDA9873_STEREO      2 /* Stereo sound is identified     */
 #define TDA9873_DUAL        4 /* Dual sound is identified       */
 
-int tda9873_getmode(struct CHIPSTATE *chip)
+static int tda9873_getmode(struct CHIPSTATE *chip)
 {
 	int val,mode;
 
@@ -672,7 +675,7 @@
 	return mode;
 }
 
-void tda9873_setmode(struct CHIPSTATE *chip, int mode)
+static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
 {
 	int sw_data  = chip->shadow.bytes[TDA9873_SW+1] & ~ TDA9873_TR_MASK;
 	/*	int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
@@ -708,7 +711,7 @@
 		mode, sw_data);
 }
 
-int tda9873_checkit(struct CHIPSTATE *chip)
+static int tda9873_checkit(struct CHIPSTATE *chip)
 {
 	int rc;
 
@@ -719,10 +722,10 @@
 
 
 /* ---------------------------------------------------------------------- */
-/* audio chip description - defines+functions for tda9874a                */
+/* audio chip description - defines+functions for tda9874h and tda9874a   */
 /* Dariusz Kowalewski <darekk@automex.pl>                                 */
 
-/* Subaddresses for TDA9874A (slave rx) */
+/* Subaddresses for TDA9874H and TDA9874A (slave rx) */
 #define TDA9874A_AGCGR		0x00	/* AGC gain */
 #define TDA9874A_GCONR		0x01	/* general config */
 #define TDA9874A_MSR		0x02	/* monitor select */
@@ -747,10 +750,10 @@
 #define TDA9874A_DAICONR	0x15	/* digital audio interface config */
 #define TDA9874A_I2SOSR		0x16	/* I2S-bus output select */
 #define TDA9874A_I2SOLAR	0x17	/* I2S-bus output level adj. */
-#define TDA9874A_MDACOSR	0x18	/* mono DAC output select */
-#define TDA9874A_ESP		0xFF	/* easy standard progr. */
+#define TDA9874A_MDACOSR	0x18	/* mono DAC output select (tda9874a) */
+#define TDA9874A_ESP		0xFF	/* easy standard progr. (tda9874a) */
 
-/* Subaddresses for TDA9874A (slave tx) */
+/* Subaddresses for TDA9874H and TDA9874A (slave tx) */
 #define TDA9874A_DSR		0x00	/* device status */
 #define TDA9874A_NSR		0x01	/* NICAM status */
 #define TDA9874A_NECR		0x02	/* NICAM error count */
@@ -767,37 +770,91 @@
 
 static int tda9874a_mode = 1;		/* 0: A2, 1: NICAM */
 static int tda9874a_GCONR = 0xc0;	/* default config. input pin: SIFSEL=0 */
+static int tda9874a_NCONR = 0x01;	/* default NICAM config.: AMSEL=0,AMUTE=1 */
 static int tda9874a_ESP = 0x07;		/* default standard: NICAM D/K */
+static int tda9874a_dic = -1;		/* device id. code */
 
 /* insmod options for tda9874a */
 static int tda9874a_SIF = -1;
+static int tda9874a_AMSEL = -1;
 static int tda9874a_STD = -1;
 MODULE_PARM(tda9874a_SIF,"i");
+MODULE_PARM(tda9874a_AMSEL,"i");
 MODULE_PARM(tda9874a_STD,"i");
 
+/*
+ * initialization table for tda9874 decoder:
+ *  - carrier 1 freq. registers (3 bytes)
+ *  - carrier 2 freq. registers (3 bytes)
+ *  - demudulator config register
+ *  - FM de-emphasis register (slow identification mode)
+ * Note: frequency registers must be written in single i2c transfer.
+ */
+static struct tda9874a_MODES {
+	char *name;
+	audiocmd cmd;
+} tda9874a_modelist[9] = {
+  {	"A2, B/G",
+	{ 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x77,0xA0,0x00, 0x00,0x00 }} },
+  {	"A2, M (Korea)",
+	{ 9, { TDA9874A_C1FRA, 0x5D,0xC0,0x00, 0x62,0x6A,0xAA, 0x20,0x22 }} },
+  {	"A2, D/K (1)",
+	{ 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x82,0x60,0x00, 0x00,0x00 }} },
+  {	"A2, D/K (2)",
+	{ 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x8C,0x75,0x55, 0x00,0x00 }} },
+  {	"A2, D/K (3)",
+	{ 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x77,0xA0,0x00, 0x00,0x00 }} },
+  {	"NICAM, I",
+	{ 9, { TDA9874A_C1FRA, 0x7D,0x00,0x00, 0x88,0x8A,0xAA, 0x08,0x33 }} },
+  {	"NICAM, B/G",
+	{ 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x79,0xEA,0xAA, 0x08,0x33 }} },
+  {	"NICAM, D/K", /* default */
+	{ 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x08,0x33 }} },
+  {	"NICAM, L",
+	{ 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x09,0x33 }} }
+};
 
 static int tda9874a_setup(struct CHIPSTATE *chip)
 {
 	chip_write(chip, TDA9874A_AGCGR, 0x00); /* 0 dB */
 	chip_write(chip, TDA9874A_GCONR, tda9874a_GCONR);
 	chip_write(chip, TDA9874A_MSR, (tda9874a_mode) ? 0x03:0x02);
-	chip_write(chip, TDA9874A_FMMR, 0x80);
+	if(tda9874a_dic == 0x11) {
+		chip_write(chip, TDA9874A_FMMR, 0x80);
+	} else { /* dic == 0x07 */
+		chip_cmd(chip,"tda9874_modelist",&tda9874a_modelist[tda9874a_STD].cmd);
+		chip_write(chip, TDA9874A_FMMR, 0x00);
+	}
 	chip_write(chip, TDA9874A_C1OLAR, 0x00); /* 0 dB */
 	chip_write(chip, TDA9874A_C2OLAR, 0x00); /* 0 dB */
-	chip_write(chip, TDA9874A_NCONR, 0x00); /* not 0x04 as doc. table 10 says! */
+	chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);
 	chip_write(chip, TDA9874A_NOLAR, 0x00); /* 0 dB */
-	chip_write(chip, TDA9874A_AMCONR, 0xf9);
-	chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); /* 0x81 */
-	chip_write(chip, TDA9874A_AOSR, 0x80);
-	chip_write(chip, TDA9874A_MDACOSR, (tda9874a_mode) ? 0x82:0x80);
-	chip_write(chip, TDA9874A_ESP, tda9874a_ESP);
-
+	/* Note: If signal quality is poor you may want to change NICAM */
+	/* error limit registers (NLELR and NUELR) to some greater values. */
+	/* Then the sound would remain stereo, but won't be so clear. */
+	chip_write(chip, TDA9874A_NLELR, 0x14); /* default */
+	chip_write(chip, TDA9874A_NUELR, 0x50); /* default */
+
+	if(tda9874a_dic == 0x11) {
+		chip_write(chip, TDA9874A_AMCONR, 0xf9);
+		chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
+		chip_write(chip, TDA9874A_AOSR, 0x80);
+		chip_write(chip, TDA9874A_MDACOSR, (tda9874a_mode) ? 0x82:0x80);
+		chip_write(chip, TDA9874A_ESP, tda9874a_ESP);
+	} else { /* dic == 0x07 */
+		chip_write(chip, TDA9874A_AMCONR, 0xfb);
+		chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
+		chip_write(chip, TDA9874A_AOSR, 0x00); // or 0x10
+	}
+	dprintk("tda9874a_setup(): %s [0x%02X].\n",
+		tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
 	return 1;
 }
 
-int tda9874a_getmode(struct CHIPSTATE *chip)
+static int tda9874a_getmode(struct CHIPSTATE *chip)
 {
 	int dsr,nsr,mode;
+	int necr; /* just for debugging */
 
 	mode = VIDEO_SOUND_MONO;
 
@@ -805,55 +862,125 @@
 		return mode;
 	if(-1 == (nsr = chip_read2(chip,TDA9874A_NSR)))
 		return mode;
+	if(-1 == (necr = chip_read2(chip,TDA9874A_NECR)))
+		return mode;
+
+	/* need to store dsr/nsr somewhere */
+	chip->shadow.bytes[MAXREGS-2] = dsr;
+	chip->shadow.bytes[MAXREGS-1] = nsr;
 
 	if(tda9874a_mode) {
-		/* check also DSR.RSSF and DSR.AMSTAT bits? */
-		if(nsr & 0x02) /* NSR.S/MB */
+		/* Note: DSR.RSSF and DSR.AMSTAT bits are also checked.
+		 * If NICAM auto-muting is enabled, DSR.AMSTAT=1 indicates
+		 * that sound has (temporarily) switched from NICAM to
+		 * mono FM (or AM) on 1st sound carrier due to high NICAM bit
+		 * error count. So in fact there is no stereo in this case :-(
+		 * But changing the mode to VIDEO_SOUND_MONO would switch
+		 * external 4052 multiplexer in audio_hook().
+		 */
+#if 0
+		if((nsr & 0x02) && !(dsr & 0x10)) /* NSR.S/MB=1 and DSR.AMSTAT=0 */
+			mode |= VIDEO_SOUND_STEREO;
+#else
+		if(nsr & 0x02) /* NSR.S/MB=1 */
 			mode |= VIDEO_SOUND_STEREO;
-		if(nsr & 0x01) /* NSR.D/SB */ 
+#endif
+		if(nsr & 0x01) /* NSR.D/SB=1 */ 
 			mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
 	} else {
-		if(dsr & 0x02) /* DSR.IDSTE */
+		if(dsr & 0x02) /* DSR.IDSTE=1 */
 			mode |= VIDEO_SOUND_STEREO;
-		if(dsr & 0x04) /* DSR.IDDUA */
+		if(dsr & 0x04) /* DSR.IDDUA=1 */
 			mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
 	}
 
-	dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, return: %d.\n",
-		 dsr, nsr, mode);
+	dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
+		 dsr, nsr, necr, mode);
 	return mode;
 }
 
-void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
+static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
 {
-	int aosr=0x80,mdacosr=0x82;
-
-	/* note: TDA9874A has auto-select function for audio output */
-	switch(mode) {
-	case VIDEO_SOUND_MONO:
-	case VIDEO_SOUND_STEREO:
-		break;
-	case VIDEO_SOUND_LANG1:
-		aosr = 0x80; /* dual A/A */
-		mdacosr = (tda9874a_mode) ? 0x82:0x80;
-		break;
-	case VIDEO_SOUND_LANG2:
-		aosr = 0xa0; /* dual B/B */
-		mdacosr = (tda9874a_mode) ? 0x83:0x81;
-		break;
-	default:
-		chip->mode = 0;
-		return;
+	/* Disable/enable NICAM auto-muting (based on DSR.RSSF status bit). */
+	/* If auto-muting is disabled, we can hear a signal of degrading quality. */
+	if(tda9874a_mode) {
+		if(chip->shadow.bytes[MAXREGS-2] & 0x20) /* DSR.RSSF=1 */
+			tda9874a_NCONR &= 0xfe; /* enable */
+		else
+			tda9874a_NCONR |= 0x01; /* disable */
+		chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);
 	}
 
-	chip_write(chip, TDA9874A_AOSR, aosr);
-	chip_write(chip, TDA9874A_MDACOSR, mdacosr);
+	/* Note: TDA9874A supports automatic FM dematrixing (FMMR register)
+	 * and has auto-select function for audio output (AOSR register).
+	 * Old TDA9874H doesn't support these features.
+	 * TDA9874A also has additional mono output pin (OUTM), which
+	 * on same (all?) tv-cards is not used, anyway (as well as MONOIN).
+	 */
+	if(tda9874a_dic == 0x11) {
+		int aosr = 0x80;
+		int mdacosr = (tda9874a_mode) ? 0x82:0x80;
+
+		switch(mode) {
+		case VIDEO_SOUND_MONO:
+		case VIDEO_SOUND_STEREO:
+			break;
+		case VIDEO_SOUND_LANG1:
+			aosr = 0x80; /* auto-select, dual A/A */
+			mdacosr = (tda9874a_mode) ? 0x82:0x80;
+			break;
+		case VIDEO_SOUND_LANG2:
+			aosr = 0xa0; /* auto-select, dual B/B */
+			mdacosr = (tda9874a_mode) ? 0x83:0x81;
+			break;
+		default:
+			chip->mode = 0;
+			return;
+		}
+		chip_write(chip, TDA9874A_AOSR, aosr);
+		chip_write(chip, TDA9874A_MDACOSR, mdacosr);
+
+		dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
+			mode, aosr, mdacosr);
+
+	} else { /* dic == 0x07 */
+		int fmmr,aosr;
+
+		switch(mode) {
+		case VIDEO_SOUND_MONO:
+			fmmr = 0x00; /* mono */
+			aosr = 0x10; /* A/A */
+			break;
+		case VIDEO_SOUND_STEREO:
+			if(tda9874a_mode) {
+				fmmr = 0x00;
+				aosr = 0x00; /* handled by NICAM auto-mute */
+			} else {
+				fmmr = (tda9874a_ESP == 1) ? 0x05 : 0x04; /* stereo */
+				aosr = 0x00;
+			}
+			break;
+		case VIDEO_SOUND_LANG1:
+			fmmr = 0x02; /* dual */
+			aosr = 0x10; /* dual A/A */
+			break;
+		case VIDEO_SOUND_LANG2:
+			fmmr = 0x02; /* dual */
+			aosr = 0x20; /* dual B/B */
+			break;
+		default:
+			chip->mode = 0;
+			return;
+		}
+		chip_write(chip, TDA9874A_FMMR, fmmr);
+		chip_write(chip, TDA9874A_AOSR, aosr);
 
-	dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
-		mode, aosr, mdacosr);
+		dprintk("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
+			mode, fmmr, aosr);
+	}
 }
 
-int tda9874a_checkit(struct CHIPSTATE *chip)
+static int tda9874a_checkit(struct CHIPSTATE *chip)
 {
 	int dic,sic;	/* device id. and software id. codes */
 
@@ -864,10 +991,15 @@
 
 	dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
 
-	return((dic & 0xff) == 0x11);
+	if((dic == 0x11)||(dic == 0x07)) {
+		dprintk("tvaudio: found tda9874%s.\n",(dic == 0x11) ? "a (new)":"h (old)");
+		tda9874a_dic = dic;	/* remember device id. */
+		return 1;
+	}
+	return 0;	/* not found */
 }
 
-int tda9874a_initialize(struct CHIPSTATE *chip)
+static int tda9874a_initialize(struct CHIPSTATE *chip)
 {
 	if(tda9874a_SIF != -1) {
 		if(tda9874a_SIF == 1)
@@ -887,6 +1019,15 @@
 		}
 	}
 
+	if(tda9874a_AMSEL != -1) {
+		if(tda9874a_AMSEL == 0)
+			tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */
+		else if(tda9874a_AMSEL == 1)
+			tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */
+		else
+			printk(KERN_WARNING "tda9874a: AMSEL parameter must be 0 or 1.\n");
+	}
+
 	tda9874a_setup(chip);
 
 	return 0;
@@ -915,8 +1056,8 @@
 #define TEA6420_S_SE       0x04  /* stereo E */
 #define TEA6420_S_GMU      0x05  /* general mute */
 
-int tea6300_shift10(int val) { return val >> 10; }
-int tea6300_shift12(int val) { return val >> 12; }
+static int tea6300_shift10(int val) { return val >> 10; }
+static int tea6300_shift12(int val) { return val >> 12; }
 
 
 /* ---------------------------------------------------------------------- */
@@ -931,8 +1072,8 @@
 #define TDA8425_S1_OFF     0xEE  /* audio off (mute on) */
 #define TDA8425_S1_ON      0xCE  /* audio on (mute off) - "linear stereo" mode */
 
-int tda8425_shift10(int val) { return val >> 10 | 0xc0; }
-int tda8425_shift12(int val) { return val >> 12 | 0xf0; }
+static int tda8425_shift10(int val) { return val >> 10 | 0xc0; }
+static int tda8425_shift12(int val) { return val >> 12 | 0xf0; }
 
 
 /* ---------------------------------------------------------------------- */
@@ -1015,13 +1156,13 @@
 		
 	},
 	{
-		name:       "tda9874a",
-		id:         I2C_DRIVERID_TDA9874A,
+		name:       "tda9874h/a",
+		id:         I2C_DRIVERID_TDA9874,
 		checkit:    tda9874a_checkit,
 		initialize: tda9874a_initialize,
 		insmodopt:  &tda9874a,
-		addr_lo:    I2C_TDA9874A >> 1,
-		addr_hi:    I2C_TDA9874A >> 1,
+		addr_lo:    I2C_TDA9874 >> 1,
+		addr_hi:    I2C_TDA9874 >> 1,
 
 		getmode:    tda9874a_getmode,
 		setmode:    tda9874a_setmode,
@@ -1160,7 +1301,7 @@
 	chip->c.data = chip;
 
 	/* find description for the chip */
-	dprintk("tvaudio: chip @ addr=0x%x\n", addr<<1);
+	dprintk("tvaudio: chip found @ i2c-addr=0x%x\n", addr<<1);
 	for (desc = chiplist; desc->name != NULL; desc++) {
 		if (0 == *(desc->insmodopt))
 			continue;
@@ -1175,7 +1316,8 @@
 		dprintk("tvaudio: no matching chip description found\n");
 		return -EIO;
 	}
-	dprintk("tvaudio: %s matches:%s%s%s\n",desc->name,
+	printk("tvaudio: found %s\n",desc->name);
+	dprintk("tvaudio: matches:%s%s%s.\n",
 		(desc->flags & CHIP_HAS_VOLUME)     ? " volume"      : "",
 		(desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
 		(desc->flags & CHIP_HAS_INPUTSEL)   ? " audiomux"    : "");
@@ -1272,6 +1414,14 @@
 				chip_write_masked(chip,desc->inputreg,desc->inputmap[*sarg],desc->inputmask);
 		}
 		break;
+
+	case AUDC_SET_RADIO:
+		dprintk(KERN_DEBUG "tvaudio: AUDC_SET_RADIO\n");
+		chip->norm = VIDEO_MODE_RADIO;
+		chip->watch_stereo = 0;
+		/* del_timer(&chip->wt); */
+		break;
+
 	/* --- v4l ioctls --- */
 	/* take care: bttv does userspace copying, we'll get a
 	   kernel pointer here... */
@@ -1290,10 +1440,12 @@
 			va->bass   = chip->bass;
 			va->treble = chip->treble;
 		}
-		if (desc->getmode)
-			va->mode = desc->getmode(chip);
-		else
-			va->mode = VIDEO_SOUND_MONO;
+		if (chip->norm != VIDEO_MODE_RADIO) {
+			if (desc->getmode)
+				va->mode = desc->getmode(chip);
+			else
+				va->mode = VIDEO_SOUND_MONO;
+		}
 		break;
 	}
 
@@ -1316,11 +1468,21 @@
 			chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
 		}
 		if (desc->setmode && va->mode) {
+			chip->watch_stereo = 0;
+			/* del_timer(&chip->wt); */
 			chip->mode = va->mode;
 			desc->setmode(chip,va->mode);
 		}
 		break;
 	}
+	case VIDIOCSCHAN:
+	{
+		struct video_channel *vc = arg;
+		
+		dprintk(KERN_DEBUG "tvaudio: VIDIOCSCHAN\n");
+		chip->norm = vc->norm;
+		break;
+	}
 	case VIDIOCSFREQ:
 	{
 	    	chip->mode = 0; /* automatic */
@@ -1339,7 +1501,7 @@
 
 static struct i2c_driver driver = {
         name:            "generic i2c audio driver",
-        id:              I2C_DRIVERID_TVAUDIO, /* FIXME */
+        id:              I2C_DRIVERID_TVAUDIO,
         flags:           I2C_DF_NOTIFY,
         attach_adapter:  chip_probe,
         detach_client:   chip_detach,
@@ -1349,10 +1511,11 @@
 static struct i2c_client client_template =
 {
         name:   "(unset)",
+	flags:  I2C_CLIENT_ALLOW_USE,
         driver: &driver,
 };
 
-int audiochip_init_module(void)
+static int audiochip_init_module(void)
 {
 	struct CHIPDESC  *desc;
 	printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
@@ -1364,7 +1527,7 @@
 	return 0;
 }
 
-void audiochip_cleanup_module(void)
+static void audiochip_cleanup_module(void)
 {
 	i2c_del_driver(&driver);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/tvaudio.h linux/drivers/media/video/tvaudio.h
--- linux.orig/drivers/media/video/tvaudio.h	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/tvaudio.h	2002-07-20 01:08:22.000000000 +0000
@@ -6,7 +6,7 @@
 #define I2C_TDA9840        0x84
 #define I2C_TDA985x_L      0xb4 /* also used by 9873 */
 #define I2C_TDA985x_H      0xb6
-#define I2C_TDA9874A       0xb0 /* also used by 9875 */
+#define I2C_TDA9874        0xb0 /* also used by 9875 */
 
 #define I2C_TEA6300        0x80
 #define I2C_TEA6420	   0x98
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/tvmixer.c linux/drivers/media/video/tvmixer.c
--- linux.orig/drivers/media/video/tvmixer.c	2001-10-17 21:19:20.000000000 +0000
+++ linux/drivers/media/video/tvmixer.c	2002-07-20 01:08:32.000000000 +0000
@@ -8,8 +8,9 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/videodev.h>
-#include <asm/semaphore.h>
 #include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <asm/semaphore.h>
 
 #include <linux/sound.h>
 #include <linux/soundcard.h>
@@ -177,7 +178,7 @@
 
 static int tvmixer_open(struct inode *inode, struct file *file)
 {
-        int i, minor = MINOR(inode->i_rdev);
+        int i, minor = minor(inode->i_rdev);
         struct TVMIXER *mix = NULL;
 	struct i2c_client *client = NULL;
 
@@ -320,7 +321,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-int tvmixer_init_module(void)
+static int tvmixer_init_module(void)
 {
 	int i;
 	
@@ -330,7 +331,7 @@
 	return 0;
 }
 
-void tvmixer_cleanup_module(void)
+static void tvmixer_cleanup_module(void)
 {
 	int i;
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/videodev.c linux/drivers/media/video/videodev.c
--- linux.orig/drivers/media/video/videodev.c	2001-10-11 16:14:32.000000000 +0000
+++ linux/drivers/media/video/videodev.c	2002-07-20 01:08:26.000000000 +0000
@@ -25,15 +25,14 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/videodev.h>
 #include <linux/init.h>
-
+#include <linux/kmod.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/semaphore.h>
 
-#include <linux/kmod.h>
-
+#include <linux/videodev.h>
 
 #define VIDEO_NUM_DEVICES	256 
 
@@ -42,6 +41,7 @@
  */
  
 static struct video_device *video_device[VIDEO_NUM_DEVICES];
+static DECLARE_MUTEX(videodev_lock);
 
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
@@ -70,7 +70,7 @@
 static ssize_t video_read(struct file *file,
 	char *buf, size_t count, loff_t *ppos)
 {
-	struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
+	struct video_device *vfl = video_devdata(file);
 	if(vfl->read)
 		return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
 	else
@@ -86,13 +86,18 @@
 static ssize_t video_write(struct file *file, const char *buf, 
 	size_t count, loff_t *ppos)
 {
-	struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
+	struct video_device *vfl = video_devdata(file);
 	if(vfl->write)
 		return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
 	else
 		return 0;
 }
 
+struct video_device* video_devdata(struct file *file)
+{
+	return video_device[minor(file->f_dentry->d_inode->i_rdev)];
+}
+
 /*
  *	Poll to see if we're readable, can probably be used for timing on incoming
  *	frames, etc..
@@ -100,7 +105,7 @@
 
 static unsigned int video_poll(struct file *file, poll_table * wait)
 {
-	struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
+	struct video_device *vfl = video_devdata(file);
 	if(vfl->poll)
 		return vfl->poll(vfl, file, wait);
 	else
@@ -114,52 +119,64 @@
 
 static int video_open(struct inode *inode, struct file *file)
 {
-	unsigned int minor = MINOR(inode->i_rdev);
-	int err, retval = 0;
+	unsigned int minor = minor(inode->i_rdev);
+	int err = 0;
 	struct video_device *vfl;
 	
 	if(minor>=VIDEO_NUM_DEVICES)
 		return -ENODEV;
-	lock_kernel();		
+	down(&videodev_lock);
 	vfl=video_device[minor];
 	if(vfl==NULL) {
 		char modname[20];
 
+		up(&videodev_lock);
 		sprintf (modname, "char-major-%d-%d", VIDEO_MAJOR, minor);
 		request_module(modname);
+		down(&videodev_lock);
 		vfl=video_device[minor];
 		if (vfl==NULL) {
-			retval = -ENODEV;
-			goto error_out;
+			err = -ENODEV;
+			goto unlock_out;
 		}
 	}
-	if(vfl->busy) {
-		retval = -EBUSY;
-		goto error_out;
+	if (vfl->fops) {
+		struct file_operations *old_fops;
+
+		old_fops = file->f_op;
+                file->f_op = fops_get(vfl->fops);
+                if(file->f_op->open)
+                        err = file->f_op->open(inode,file);
+                if (err) {
+                        fops_put(file->f_op);
+                        file->f_op = fops_get(old_fops);
+                }
+                fops_put(old_fops);
+		goto unlock_out;
+	}
+	if(vfl->users) {
+		err = -EBUSY;
+		goto unlock_out;
 	}
-	vfl->busy=1;		/* In case vfl->open sleeps */
+	vfl->users++;		/* In case vfl->open sleeps */
 	
 	if(vfl->owner)
 		__MOD_INC_USE_COUNT(vfl->owner);
 	
-	if(vfl->open)
-	{
+	if (vfl->open) {
 		err=vfl->open(vfl,0);	/* Tell the device it is open */
-		if(err)
-		{
-			vfl->busy=0;
+		if (err) {
+			vfl->users--;
 			if(vfl->owner)
 				__MOD_DEC_USE_COUNT(vfl->owner);
-			
-			unlock_kernel();
-			return err;
+			goto unlock_out;
 		}
 	}
-	unlock_kernel();
-	return 0;
-error_out:
-	unlock_kernel();
-	return retval;
+	err = 0;
+	
+unlock_out:
+	up(&videodev_lock);
+	return err;
 }
 
 /*
@@ -169,21 +186,22 @@
 static int video_release(struct inode *inode, struct file *file)
 {
 	struct video_device *vfl;
-	lock_kernel();
-	vfl=video_device[MINOR(inode->i_rdev)];
+
+	down(&videodev_lock);
+	vfl = video_devdata(file);
 	if(vfl->close)
 		vfl->close(vfl);
-	vfl->busy=0;
+	vfl->users--;
 	if(vfl->owner)
 		__MOD_DEC_USE_COUNT(vfl->owner);
-	unlock_kernel();
+	up(&videodev_lock);
 	return 0;
 }
 
 static int video_ioctl(struct inode *inode, struct file *file,
 	unsigned int cmd, unsigned long arg)
 {
-	struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
+	struct video_device *vfl = video_devdata(file);
 	int err=vfl->ioctl(vfl, cmd, (void *)arg);
 
 	if(err!=-ENOIOCTLCMD)
@@ -203,7 +221,7 @@
 int video_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	int ret = -EINVAL;
-	struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
+	struct video_device *vfl = video_devdata(file);
 	if(vfl->mmap) {
 		lock_kernel();
 		ret = vfl->mmap(vfl, (char *)vma->vm_start, 
@@ -214,6 +232,93 @@
 }
 
 /*
+ * helper function -- handles userspace copying for ioctl arguments
+ */
+int
+video_usercopy(struct inode *inode, struct file *file,
+	       unsigned int cmd, unsigned long arg,
+	       int (*func)(struct inode *inode, struct file *file,
+			   unsigned int cmd, void *arg))
+{
+	char	sbuf[128];
+	void    *mbuf = NULL;
+	void	*parg = NULL;
+	int	err  = -EINVAL;
+
+	/*  Copy arguments into temp kernel buffer  */
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:
+		parg = (void *)arg;
+		break;
+	case _IOC_READ: /* some v4l ioctls are marked wrong ... */
+	case _IOC_WRITE:
+	case (_IOC_WRITE | _IOC_READ):
+		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
+			parg = sbuf;
+		} else {
+			/* too big to allocate from stack */
+			mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
+			if (NULL == mbuf)
+				return -ENOMEM;
+			parg = mbuf;
+		}
+		
+		err = -EFAULT;
+		if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd)))
+			goto out;
+		break;
+	}
+
+	/* call driver */
+	err = func(inode, file, cmd, parg);
+	if (err == -ENOIOCTLCMD)
+		err = -EINVAL;
+	if (err < 0)
+		goto out;
+
+	/*  Copy results into user buffer  */
+	switch (_IOC_DIR(cmd))
+	{
+	case _IOC_READ:
+	case (_IOC_WRITE | _IOC_READ):
+		if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd)))
+			err = -EFAULT;
+		break;
+	}
+
+out:
+	if (mbuf)
+		kfree(mbuf);
+	return err;
+}
+
+/*
+ * open/release helper functions -- handle exclusive opens
+ */
+extern int video_exclusive_open(struct inode *inode, struct file *file)
+{
+	struct  video_device *vfl = video_devdata(file);
+	int retval = 0;
+
+	down(&vfl->lock);
+	if (vfl->users) {
+		retval = -EBUSY;
+	} else {
+		vfl->users++;
+	}
+	up(&vfl->lock);
+	return retval;
+}
+
+extern int video_exclusive_release(struct inode *inode, struct file *file)
+{
+	struct  video_device *vfl = video_devdata(file);
+	
+	vfl->users--;
+	return 0;
+}
+
+/*
  *	/proc support
  */
 
@@ -307,7 +412,6 @@
 	video_dev_proc_entry->owner = THIS_MODULE;
 }
 
-#ifdef MODULE
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 static void videodev_proc_destroy(void)
 {
@@ -318,7 +422,6 @@
 		remove_proc_entry("video", &proc_root);
 }
 #endif
-#endif
 
 static void videodev_proc_create_dev (struct video_device *vfd, char *name)
 {
@@ -392,8 +495,6 @@
  *	%VFL_TYPE_RADIO - A radio card	
  */
 
-static DECLARE_MUTEX(videodev_register_lock);
-
 int video_register_device(struct video_device *vfd, int type, int nr)
 {
 	int i=0;
@@ -430,27 +531,27 @@
 	}
 
 	/* pick a minor number */
-	down(&videodev_register_lock);
+	down(&videodev_lock);
 	if (-1 == nr) {
 		/* use first free */
 		for(i=base;i<end;i++)
 			if (NULL == video_device[i])
 				break;
 		if (i == end) {
-			up(&videodev_register_lock);
+			up(&videodev_lock);
 			return -ENFILE;
 		}
 	} else {
 		/* use the one the driver asked for */
 		i = base+nr;
 		if (NULL != video_device[i]) {
-			up(&videodev_register_lock);
+			up(&videodev_lock);
 			return -ENFILE;
 		}
 	}
 	video_device[i]=vfd;
 	vfd->minor=i;
-	up(&videodev_register_lock);
+	up(&videodev_lock);
 
 	/* The init call may sleep so we book the slot out
 	   then call */
@@ -474,6 +575,7 @@
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				&video_fops,
 				NULL);
+	init_MUTEX(&vfd->lock);
 	
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 	sprintf (name, "%s%d", name_base, i - base);
@@ -492,8 +594,10 @@
  
 void video_unregister_device(struct video_device *vfd)
 {
+	down(&videodev_lock);
+
 	if(video_device[vfd->minor]!=vfd)
-		panic("vfd: bad unregister");
+		panic("videodev: bad unregister");
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 	videodev_proc_destroy_dev (vfd);
@@ -502,6 +606,7 @@
 	devfs_unregister (vfd->devfs_handle);
 	video_device[vfd->minor]=NULL;
 	MOD_DEC_USE_COUNT;
+	up(&videodev_lock);
 }
 
 
@@ -540,12 +645,9 @@
 
 static void __exit videodev_exit(void)
 {
-#ifdef MODULE		
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 	videodev_proc_destroy ();
 #endif
-#endif
-	
 	devfs_unregister_chrdev(VIDEO_MAJOR, "video_capture");
 }
 
@@ -554,6 +656,10 @@
 
 EXPORT_SYMBOL(video_register_device);
 EXPORT_SYMBOL(video_unregister_device);
+EXPORT_SYMBOL(video_devdata);
+EXPORT_SYMBOL(video_usercopy);
+EXPORT_SYMBOL(video_exclusive_open);
+EXPORT_SYMBOL(video_exclusive_release);
 
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/vino.c linux/drivers/media/video/vino.c
--- linux.orig/drivers/media/video/vino.c	2001-03-02 19:12:10.000000000 +0000
+++ linux/drivers/media/video/vino.c	2002-07-20 01:08:31.000000000 +0000
@@ -1,6 +1,4 @@
-/* $Id: vino.c,v 1.5 1999/10/09 00:01:14 ralf Exp $
- * drivers/char/vino.c
- *
+/*
  * (incomplete) Driver for the Vino Video input system found in SGI Indys.
  *
  * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
@@ -57,9 +55,7 @@
 		".set\tat\n\t"
 		".set\tmips0"
 		:
-		:"r" (virt_addr),
-		 "r" (&ret)
-		:"$1");
+		:"r" (virt_addr), "r" (&ret));
 	restore_flags(flags);
 
 	return ret;
@@ -83,9 +79,7 @@
 		".set\tat\n\t"
 		".set\tmips0"
 		:
-		:"r" (&value),
-		 "r" (virt_addr)
-		:"$1");
+		:"r" (&value), "r" (virt_addr));
 	restore_flags(flags);
 }
 
@@ -93,45 +87,41 @@
 				    unsigned long addr)
 {
 	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
-	unsigned long flags;
+	unsigned long tmp, flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	__asm__ __volatile__(
-		".set\tmips3\n\t"
+		".set\tmips3\t\t\t# vino_reg_and\n\t"
 		".set\tnoat\n\t"
-		"ld\t$1,(%0)\n\t"
-		"ld\t$2,(%1)\n\t"
-		"and\t$1,$1,$2\n\t"
-		"sd\t$1,(%0)\n\t"
+		"ld\t$1, (%1)\n\t"
+		"ld\t%0, (%2)\n\t"
+		"and\t$1, $1, %0\n\t"
+		"sd\t$1, (%1)\n\t"
 		".set\tat\n\t"
 		".set\tmips0"
-		:
-		:"r" (virt_addr),
-		 "r" (&value)
-		:"$1","$2");
-	restore_flags(flags);
+		: "=&r" (tmp)
+		: "r" (virt_addr), "r" (&value));
+	__restore_flags(flags);
 }
 
 static __inline__ void vino_reg_or(unsigned long long value,
 				   unsigned long addr)
 {
 	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
-	unsigned long flags;
+	unsigned long tmp, flags;
 
 	save_and_cli(flags);
 	__asm__ __volatile__(
 		".set\tmips3\n\t"
 		".set\tnoat\n\t"
-		"ld\t$1,(%0)\n\t"
-		"ld\t$2,(%1)\n\t"
-		"or\t$1,$1,$2\n\t"
-		"sd\t$1,(%0)\n\t"
+		"ld\t$1, (%1)\n\t"
+		"ld\t%0, (%2)\n\t"
+		"or\t$1, $1, %0\n\t"
+		"sd\t$1, (%1)\n\t"
 		".set\tat\n\t"
 		".set\tmips0"
-		:
-		:"r" (virt_addr),
-		 "r" (&value)
-		:"$1","$2");
+		: "=&r" (tmp)
+		: "r" (virt_addr), "r" (&value));
 	restore_flags(flags);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/w9966.c linux/drivers/media/video/w9966.c
--- linux.orig/drivers/media/video/w9966.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/media/video/w9966.c	2002-07-20 01:08:29.000000000 +0000
@@ -19,18 +19,25 @@
 */
 /*
 	Supported devices:
-	  * Lifeview FlyCam Supra (using the Philips saa7111a chip)
+	  * Lifeview Flycam Supra (Philips saa7111a chip)
+
+	  * Mikrotek Eyestar2 (Sanyo lc99053 chip)
+	    Very rudimentary support, total lack of ccd-control chip settings.
+	    Only green video data and no image properties (brightness, etc..)
+	    If anyone can parse the Japanese data-sheet for the Sanyo lc99053
+	    chip, feel free to help.
+	    <http://service.semic.sanyo.co.jp/semi/ds_pdf_j/LC99053.pdf>
+	    Thanks to Steven Griffiths <steve@sgriff.com> and
+	    James Murray <jsm@jsm-net.demon.co.uk> for testing.
 
 	Todo:
-	  * Add a working EPP mode
-	  * Support other ccd-control chips than the saa7111
-	    (what combinations exists?)
+	  * Add a working EPP mode (Is this a parport or a w9966 issue?)
 	  * Add proper probing. IEEE1284 probing of w9966 chips haven't
 	    worked since parport drivers changed in 2.4.x.
-	  * Probe for onboard SRAM, port directions etc. (if possible)
+	  * Probe for onboard SRAM, port directions etc. (possible?)
 
 	Changes:
-	
+
 	Alan Cox:	Removed RGB mode for kernel merge, added THIS_MODULE
 			and owner support for newer module locks
 */
@@ -43,112 +50,155 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 
-//#define DEBUG				// Undef me for production
+//#define DEBUG				// Define for debug output.
 
 #ifdef DEBUG
-#define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: "__FUNCTION__ "(): "x, ##a)
+#   define DPRINTF(f, a...)						\
+        do {								\
+            printk ("%s%s, %d (DEBUG) %s(): ",				\
+                KERN_DEBUG, __FILE__, __LINE__, __func__);		\
+            printk (f, ##a);						\
+        } while (0)
+#   define DASSERT(x)							\
+        do {								\
+            if (!x)							\
+                DPRINTF("Assertion failed at line %d.\n", __LINE__);	\
+        } while (0)
 #else
-#define DPRINTF(x...)
+#   define DPRINTF(f, a...) do {} while(0)
+#   define DASSERT(f, a...) do {} while(0)
 #endif
 
 /*
  *	Defines, simple typedefs etc.
  */
 
-#define W9966_DRIVERNAME	"W9966CF Webcam"
+#define W9966_DRIVERNAME	"w9966cf"
 #define W9966_MAXCAMS		4	// Maximum number of cameras
-#define W9966_RBUFFER		2048	// Read buffer (must be an even number)
-#define W9966_SRAMSIZE		131072	// 128kb
-#define W9966_SRAMID		0x02	// check w9966cf.pdf
-
-// Empirically determined window limits
-#define W9966_WND_MIN_X		16
-#define W9966_WND_MIN_Y		14
-#define W9966_WND_MAX_X		705
-#define W9966_WND_MAX_Y		253
-#define W9966_WND_MAX_W		(W9966_WND_MAX_X - W9966_WND_MIN_X)
-#define W9966_WND_MAX_H		(W9966_WND_MAX_Y - W9966_WND_MIN_Y)
+#define W9966_RBUFFER		8096	// Read buffer (must be an even number)
+
+#define W9966_WND_MIN_W		2
+#define W9966_WND_MIN_H		1
 
 // Keep track of our current state
-#define W9966_STATE_PDEV	0x01
-#define W9966_STATE_CLAIMED	0x02
-#define W9966_STATE_VDEV	0x04
+#define W9966_STATE_PDEV	0x01	// pdev registered
+#define W9966_STATE_CLAIMED	0x02	// pdev claimed
+#define W9966_STATE_VDEV	0x04	// vdev registered
+#define W9966_STATE_BUFFER	0x08	// buffer allocated
+#define W9966_STATE_DETECTED	0x10	// model identified
+
+#define W9966_SAA7111_ID	0x24	// I2C device id
 
-#define W9966_I2C_W_ID		0x48
-#define W9966_I2C_R_ID		0x49
+#define W9966_I2C_UDELAY	5
+#define W9966_I2C_TIMEOUT	100
 #define W9966_I2C_R_DATA	0x08
 #define W9966_I2C_R_CLOCK	0x04
 #define W9966_I2C_W_DATA	0x02
 #define W9966_I2C_W_CLOCK	0x01
 
+#define MAX(a, b) ((a > b) ? a : b)
+#define MIN(a, b) ((a > b) ? b : a)
+
 struct w9966_dev {
-	u8 dev_state;
-	u8 i2c_state;
-	int ppmode;
-	struct parport* pport;
-	struct pardevice* pdev;
 	struct video_device vdev;
+	struct parport*     pport;
+	struct pardevice*   pdev;
+	int ppmode;
+
+	u8* buffer;
+	u8  dev_state;
+	u8  i2c_state;
 	u16 width;
 	u16 height;
+
+	// Image properties
 	u8 brightness;
 	s8 contrast;
 	s8 color;
 	s8 hue;
-	u8* buffer;
+
+	// Model specific:
+	const char* name;
+	u32 sramsize;
+	u8  sramid;		// reg 0x0c, bank layout
+	u8  cmask;		// reg 0x01, for polarity
+	u16 min_x, max_x;	// Capture window limits
+	u16 min_y, max_y;
+	int (*image)(struct w9966_dev* cam);
 };
 
 /*
- *	Module specific properties
+ *	Module properties
  */
 
 MODULE_AUTHOR("Jakob Kemi <jakob.kemi@telia.com>");
-MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (FlyCam Supra and others)");
+MODULE_DESCRIPTION("Winbond w9966cf webcam driver (Flycam Supra and others)");
 MODULE_LICENSE("GPL");
 
 
-static const char* pardev[] = {[0 ... W9966_MAXCAMS] = "auto"};
+static const char* pardev[] = {[0 ... W9966_MAXCAMS-1] = "auto"};
 MODULE_PARM(pardev, "0-" __MODULE_STRING(W9966_MAXCAMS) "s");
 MODULE_PARM_DESC(pardev,"\n\
 <auto|name|none[,...]> Where to find cameras.\n\
-  auto = probe all parports for camera\n\
+  auto = probe all parports for camera (default)\n\
   name = name of parport (eg parport0)\n\
-  none = don't search for this camera\n\
-You can specify all cameras this way, for example:
+  none = don't use this camera\n\
+You can specify all cameras this way, for example:\n\
   pardev=parport2,auto,none,parport0 would search for cam1 on parport2, search\n\
   for cam2 on all parports, skip cam3 and search for cam4 on parport0");
 
-static int parmode = 0;
+static int parmode = 1;
 MODULE_PARM(parmode, "i");
-MODULE_PARM_DESC(parmode, "\n<0|1|2> transfer mode (0=auto, 1=ecp, 2=epp)");
+MODULE_PARM_DESC(parmode, "\n<0|1|2|3> transfer mode (0=auto, 1=ecp(default), 2=epp, 3=forced hw-ecp)");
 
-static int video_nr = -1;
-MODULE_PARM(video_nr, "i");
+static int video_nr[] = {[0 ... W9966_MAXCAMS-1] = -1};
+MODULE_PARM(video_nr, "0-" __MODULE_STRING(W9966_MAXCAMS) "i");
+MODULE_PARM_DESC(video_nr,"\n\
+<-1|n[,...]> Specify V4L minor mode number.\n\
+  -1 = use next available (default)\n\
+   n = use minor number n (integer >= 0)\n\
+You can specify all cameras this way, for example:\n\
+  video_nr=-1,2,-1 would assign minor number 2 for cam2 and use auto for cam1,\n\
+  cam3 and cam4");
 
 /*
  *	Private data
  */
 
-static struct w9966_dev w9966_cams[W9966_MAXCAMS];
+static struct w9966_dev* w9966_cams;
 
 /*
- *	Private function declares
+ *	Private function declarations
  */
 
-static inline void w9966_setState(struct w9966_dev* cam, int mask, int val);
-static inline int  w9966_getState(struct w9966_dev* cam, int mask, int val);
-static inline void w9966_pdev_claim(struct w9966_dev *vdev);
+static inline void w9966_flag_set(struct w9966_dev* cam, int flag) {
+	cam->dev_state |= flag;}
+
+static inline void w9966_flag_clear(struct w9966_dev* cam, int flag) {
+	cam->dev_state &= ~flag;}
+
+static inline int  w9966_flag_test(struct w9966_dev* cam, int flag) {
+	return (cam->dev_state & flag);}
+
+static inline int  w9966_pdev_claim(struct w9966_dev *vdev);
 static inline void w9966_pdev_release(struct w9966_dev *vdev);
 
-static int w9966_rReg(struct w9966_dev* cam, int reg);
-static int w9966_wReg(struct w9966_dev* cam, int reg, int data);
-static int w9966_rReg_i2c(struct w9966_dev* cam, int reg);
-static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data);
-static int w9966_findlen(int near, int size, int maxlen);
-static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor);
-static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h);
+static int w9966_rreg(struct w9966_dev* cam, int reg);
+static int w9966_wreg(struct w9966_dev* cam, int reg, int data);
 
-static int  w9966_init(struct w9966_dev* cam, struct parport* port);
+static int  w9966_init(struct w9966_dev* cam, struct parport* port, int vidnr);
 static void w9966_term(struct w9966_dev* cam);
+static int  w9966_setup(struct w9966_dev* cam);
+static int  w9966_findlen(int near, int size, int maxlen);
+static int  w9966_calcscale(int size, int min, int max,
+			int* beg, int* end, u8* factor);
+static int  w9966_window(struct w9966_dev* cam, int x1, int y1,
+			int x2, int y2, int w, int h);
+
+static int w9966_saa7111_init(struct w9966_dev* cam);
+static int w9966_saa7111_image(struct w9966_dev* cam);
+static int w9966_lc99053_init(struct w9966_dev* cam);
+static int w9966_lc99053_image(struct w9966_dev* cam);
 
 static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
 static inline int  w9966_i2c_setscl(struct w9966_dev* cam, int state);
@@ -156,116 +206,104 @@
 static inline int  w9966_i2c_getscl(struct w9966_dev* cam);
 static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
 static int w9966_i2c_rbyte(struct w9966_dev* cam);
+static int w9966_i2c_rreg(struct w9966_dev* cam, int device, int reg);
+static int w9966_i2c_wreg(struct w9966_dev* cam, int device, int reg, int data);
 
 static int  w9966_v4l_open(struct video_device *vdev, int mode);
 static void w9966_v4l_close(struct video_device *vdev);
-static int  w9966_v4l_ioctl(struct video_device *vdev, unsigned int cmd, void *arg);
-static long w9966_v4l_read(struct video_device *vdev, char *buf, unsigned long count, int noblock);
+static int  w9966_v4l_ioctl(struct video_device *vdev,
+			unsigned int cmd, void *arg);
+static long w9966_v4l_read(struct video_device *vdev,
+			char *buf, unsigned long count, int noblock);
 
 /*
- *	Private function defines
+ *	Private function definitions
  */
 
-
-// Set camera phase flags, so we know what to uninit when terminating 
-static inline void w9966_setState(struct w9966_dev* cam, int mask, int val)
-{
-	cam->dev_state = (cam->dev_state & ~mask) ^ val;
-}
-
-// Get camera phase flags
-static inline int w9966_getState(struct w9966_dev* cam, int mask, int val)
-{
-	return ((cam->dev_state & mask) == val);
-}
-
 // Claim parport for ourself
-static inline void w9966_pdev_claim(struct w9966_dev* cam)
+// 1 on success, else 0
+static inline int w9966_pdev_claim(struct w9966_dev* cam)
 {
-	if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
-		return;
-	parport_claim_or_block(cam->pdev);
-	w9966_setState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
+	if (w9966_flag_test(cam, W9966_STATE_CLAIMED))
+		return 1;
+	if (parport_claim_or_block(cam->pdev) < 0)
+		return 0;
+	w9966_flag_set(cam, W9966_STATE_CLAIMED);
+	return 1;
 }
 
 // Release parport for others to use
 static inline void w9966_pdev_release(struct w9966_dev* cam)
 {
-	if (w9966_getState(cam, W9966_STATE_CLAIMED, 0))
+	if (!w9966_flag_test(cam, W9966_STATE_CLAIMED))
 		return;
 	parport_release(cam->pdev);
-	w9966_setState(cam, W9966_STATE_CLAIMED, 0);
+	w9966_flag_clear(cam, W9966_STATE_CLAIMED);
 }
- 
-// Read register from W9966 interface-chip
+
+// Read register from w9966 interface-chip
 // Expects a claimed pdev
 // -1 on error, else register data (byte)
-static int w9966_rReg(struct w9966_dev* cam, int reg)
+static int w9966_rreg(struct w9966_dev* cam, int reg)
 {
 	// ECP, read, regtransfer, REG, REG, REG, REG, REG
-	const unsigned char addr = 0x80 | (reg & 0x1f);
-	unsigned char val;
-	
-	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
-		return -1;
-	if (parport_write(cam->pport, &addr, 1) != 1)
-		return -1;
-	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
-		return -1;
-	if (parport_read(cam->pport, &val, 1) != 1)
+	const u8 addr = 0x80 | (reg & 0x1f);
+	u8 val;
+
+	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0 ||
+	    parport_write(cam->pport, &addr, 1) != 1 ||
+	    parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0 ||
+	    parport_read(cam->pport, &val, 1) != 1)
 		return -1;
 
 	return val;
 }
 
-// Write register to W9966 interface-chip
+// Write register to w9966 interface-chip
 // Expects a claimed pdev
-// -1 on error
-static int w9966_wReg(struct w9966_dev* cam, int reg, int data)
+// 1 on success, else 0
+static int w9966_wreg(struct w9966_dev* cam, int reg, int data)
 {
 	// ECP, write, regtransfer, REG, REG, REG, REG, REG
-	const unsigned char addr = 0xc0 | (reg & 0x1f);
-	const unsigned char val = data;
-	
-	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
-		return -1;
-	if (parport_write(cam->pport, &addr, 1) != 1)
-		return -1;
-	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
-		return -1;
-	if (parport_write(cam->pport, &val, 1) != 1)
-		return -1;
+	const u8 addr = 0xc0 | (reg & 0x1f);
+	const u8 val = data;
 
-	return 0;
+	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0 ||
+	    parport_write(cam->pport, &addr, 1) != 1 ||
+	    parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0 ||
+	    parport_write(cam->pport, &val, 1) != 1)
+		return 0;
+
+	return 1;
 }
 
 // Initialize camera device. Setup all internal flags, set a
 // default video mode, setup ccd-chip, register v4l device etc..
 // Also used for 'probing' of hardware.
-// -1 on error
-static int w9966_init(struct w9966_dev* cam, struct parport* port)
+// 1 on success, else 0
+static int w9966_init(struct w9966_dev* cam, struct parport* port, int vidnr)
 {
 	if (cam->dev_state != 0)
-		return -1;
-	
+		return 0;
+
 	cam->pport = port;
 	cam->brightness = 128;
 	cam->contrast = 64;
 	cam->color = 64;
 	cam->hue = 0;
 
-// Select requested transfer mode
+	// Select requested transfer mode
 	switch(parmode)
 	{
 	default:	// Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
 	case 0:
 		if (port->modes & PARPORT_MODE_ECP)
 			cam->ppmode = IEEE1284_MODE_ECP;
-/*		else if (port->modes & PARPORT_MODE_EPP)
-			cam->ppmode = IEEE1284_MODE_EPP;*/
+		else if (port->modes & PARPORT_MODE_EPP)
+			cam->ppmode = IEEE1284_MODE_EPP;
 		else
 			cam->ppmode = IEEE1284_MODE_ECPSWE;
-		break;	
+		break;
 	case 1:		// hw- or sw-ecp
 		if (port->modes & PARPORT_MODE_ECP)
 			cam->ppmode = IEEE1284_MODE_ECP;
@@ -278,27 +316,55 @@
 		else
 			cam->ppmode = IEEE1284_MODE_EPPSWE;
 		break;
+	case 3:		// hw-ecp
+		cam->ppmode = IEEE1284_MODE_ECP;
+		break;
 	}
-	
-// Tell the parport driver that we exists
-	cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
+
+	// Tell the parport driver that we exists
+	cam->pdev = parport_register_device(
+	    port, W9966_DRIVERNAME, NULL, NULL, NULL, 0, NULL);
+
 	if (cam->pdev == NULL) {
-		DPRINTF("parport_register_device() failed\n");
-		return -1;
+		DPRINTF("parport_register_device() failed.\n");
+		return 0;
 	}
-	w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
+	w9966_flag_set(cam, W9966_STATE_PDEV);
 
-	w9966_pdev_claim(cam);
-	
-// Setup a default capture mode
-	if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
+	// Claim parport
+	if (!w9966_pdev_claim(cam)) {
+		DPRINTF("w9966_pdev_claim() failed.\n");
+		return 0;
+	}
+
+	// Perform initial w9966 setup
+	if (!w9966_setup(cam)) {
 		DPRINTF("w9966_setup() failed.\n");
-		return -1;
+		return 0;
+	}
+
+	// Detect model
+	if (!w9966_saa7111_init(cam)) {
+		DPRINTF("w9966_saa7111_init() failed.\n");
+		return 0;
+	}
+	if (!w9966_lc99053_init(cam)) {
+		DPRINTF("w9966_lc99053_init() failed.\n");
+		return 0;
+	}
+	if (!w9966_flag_test(cam, W9966_STATE_DETECTED)) {
+		DPRINTF("Camera model not identified.\n");
+		return 0;
 	}
 
+	// Setup w9966 with a default capture mode (QCIF res.)
+	if (!w9966_window(cam, 0, 0, 1023, 1023, 176, 144)) {
+		DPRINTF("w9966_window() failed.\n");
+		return 0;
+	}
 	w9966_pdev_release(cam);
 
-// Fill in the video_device struct and register us to v4l
+	// Fill in the video_device struct and register us to v4l
 	memset(&cam->vdev, 0, sizeof(struct video_device));
 	strcpy(cam->vdev.name, W9966_DRIVERNAME);
 	cam->vdev.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
@@ -310,51 +376,73 @@
 	cam->vdev.priv = (void*)cam;
 	cam->vdev.owner = THIS_MODULE;
 
-	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1)		 
-		return -1;
-	
-	w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
-	
-	cam->buffer = NULL;
-	
+	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, vidnr) == -1) {
+		DPRINTF("video_register_device() failed (minor: %d).\n", vidnr);
+		return 0;
+	}
+	w9966_flag_set(cam, W9966_STATE_VDEV);
+
 	// All ok
-	printk(
-		"w9966cf: Found and initialized a webcam on %s.\n",
-		cam->pport->name
-	);
-	return 0;
+	printk("w9966: Found and initialized %s on %s.\n",
+		cam->name, cam->pport->name);
+	return 1;
 }
 
-
 // Terminate everything gracefully
 static void w9966_term(struct w9966_dev* cam)
 {
-// Delete allocated buffer if needed
-	if (cam->buffer != NULL) {
+	// Delete allocated buffer
+	if (w9966_flag_test(cam, W9966_STATE_BUFFER))
 		kfree(cam->buffer);
-		cam->buffer = NULL;
-	}
 
-// Unregister from v4l
-	if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
+	// Unregister from v4l
+	if (w9966_flag_test(cam, W9966_STATE_VDEV))
 		video_unregister_device(&cam->vdev);
-		w9966_setState(cam, W9966_STATE_VDEV, 0);
-	}
 
-// Terminate from IEEE1284 mode and release pdev block
-	if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
-		w9966_pdev_claim(cam);
-		parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
-		w9966_pdev_release(cam);
-	}
+	// Terminate from IEEE1284 mode and unregister from parport
+	if (w9966_flag_test(cam, W9966_STATE_PDEV)) {
+		if (w9966_pdev_claim(cam))
+			parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
 
-// Unregister from parport
-	if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
+		w9966_pdev_release(cam);
 		parport_unregister_device(cam->pdev);
-		w9966_setState(cam, W9966_STATE_PDEV, 0);
 	}
+
+	cam->dev_state = 0x00;
 }
 
+// Do initial setup for the w9966 chip, init i2c bus, etc.
+// this is generic for all models
+// expects a claimed pdev
+// 1 on success, else 0
+static int w9966_setup(struct w9966_dev* cam)
+{
+	const u8 i2c = cam->i2c_state = W9966_I2C_W_DATA | W9966_I2C_W_CLOCK;
+	const u8 regs[] = {
+		0x40,			// 0x13 - VEE control (raw 4:2:2)
+		0x00, 0x00, 0x00,	// 0x14 - 0x16
+		0x00,			// 0x17 - ???
+		i2c,			// 0x18 - Serial bus
+		0xff,			// 0x19 - I/O port direction control
+		0xff,			// 0x1a - I/O port data register
+		0x10			// 0x1b - ???
+	};
+	int i;
+
+	DASSERT(w9966_flag_test(cam, W9966_STATE_CLAIMED));
+
+	// Reset (ECP-fifo & serial-bus)
+	if (!w9966_wreg(cam, 0x00, 0x03) ||
+	    !w9966_wreg(cam, 0x00, 0x00))
+		return 0;
+
+	// Write regs to w9966cf chip
+	for (i = 0x13; i < 0x1c; i++)
+		if (!w9966_wreg(cam, i, regs[i-0x13]))
+			return 0;
+
+	return 1;
+}
 
 // Find a good length for capture window (used both for W and H)
 // A bit ugly but pretty functional. The capture length
@@ -365,7 +453,7 @@
 	int besterr = abs(near - bestlen);
 	int len;
 
-	for(len = size+1;len < maxlen;len++)
+	for(len = size+1; len < maxlen; len++)
 	{
 		int err;
 		if ( ((64*size) %len) != 0)
@@ -376,7 +464,7 @@
 		// Only continue as long as we keep getting better values
 		if (err > besterr)
 			break;
-		
+
 		besterr = err;
 		bestlen = len;
 	}
@@ -384,19 +472,19 @@
 	return bestlen;
 }
 
-// Modify capture window (if necessary) 
+// Modify capture window (if necessary)
 // and calculate downscaling
-// Return -1 on error
-static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor)
+// 1 on success, else 0
+static int w9966_calcscale(int size, int min, int max, int* beg, int* end, u8* factor)
 {
-	int maxlen = max - min;
-	int len = *end - *beg + 1;
-	int newlen = w9966_findlen(len, size, maxlen);
-	int err = newlen - len; 
+	const int maxlen = max - min;
+	const int len = *end - *beg + 1;
+	const int newlen = w9966_findlen(len, size, maxlen);
+	const int err = newlen - len;
 
 	// Check for bad format
 	if (newlen > maxlen || newlen < size)
-		return -1;
+		return 0;
 
 	// Set factor (6 bit fixed)
 	*factor = (64*size) / newlen;
@@ -419,62 +507,49 @@
 		*end -= *end - max;
 	}
 
-	return 0;
+	return 1;
 }
 
-// Setup the cameras capture window etc.
-// Expects a claimed pdev
-// return -1 on error
-static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
+// Setup the w9966 capture window and also set SRAM settings
+// expects a claimed pdev and detected camera model
+// 1 on success, else 0
+static int w9966_window(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
 {
-	unsigned int i;
 	unsigned int enh_s, enh_e;
 	u8 scale_x, scale_y;
-	u8 regs[0x1c];
-	u8 saa7111_regs[] = {
-		0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
-		0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
-		0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
-	};
-	
-	
-	if (w*h*2 > W9966_SRAMSIZE)
-	{
-		DPRINTF("capture window exceeds SRAM size!.\n");
-		w = 200; h = 160;	// Pick default values
-	}
+	u8 regs[0x13];
+	int i;
 
+	// Modify width and height to match capture window and SRAM
+	w = MAX(W9966_WND_MIN_W, w);
+	h = MAX(W9966_WND_MIN_H, h);
+	w = MIN(cam->max_x - cam->min_x, w);
+	h = MIN(cam->max_y - cam->min_y, h);
 	w &= ~0x1;
-	if (w < 2) w = 2;
-	if (h < 1) h = 1;
-	if (w > W9966_WND_MAX_W) w = W9966_WND_MAX_W;
-	if (h > W9966_WND_MAX_H) h = W9966_WND_MAX_H;
+	if (w*h*2 > cam->sramsize)
+		h = cam->sramsize / (w*2);
 
 	cam->width = w;
 	cam->height = h;
 
-	enh_s = 0;	
+	enh_s = 0;
 	enh_e = w*h*2;
-	
-// Modify capture window if necessary and calculate downscaling
-	if (
-		w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
-		w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0
-	) return -1;
-
-	DPRINTF(
-		"%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
-		w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80
-	);
-	
-// Setup registers
+
+	// Calculate downscaling
+	if (!w9966_calcscale(w, cam->min_x, cam->max_x, &x1, &x2, &scale_x) ||
+	    !w9966_calcscale(h, cam->min_y, cam->max_y, &y1, &y2, &scale_y))
+		return 0;
+
+	DPRINTF("%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
+		w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80);
+
+	// Setup registers
 	regs[0x00] = 0x00;			// Set normal operation
-	regs[0x01] = 0x18;			// Capture mode
+	regs[0x01] = cam->cmask;		// Capture mode
 	regs[0x02] = scale_y;			// V-scaling
 	regs[0x03] = scale_x;			// H-scaling
-	
-	// Capture window	
+
+	// Capture window
 	regs[0x04] = (x1 & 0x0ff);		// X-start (8 low bits)
 	regs[0x05] = (x1 & 0x300)>>8;		// X-start (2 high bits)
 	regs[0x06] = (y1 & 0x0ff);		// Y-start (8 low bits)
@@ -483,8 +558,8 @@
 	regs[0x09] = (x2 & 0x300)>>8;		// X-end (2 high bits)
 	regs[0x0a] = (y2 & 0x0ff);		// Y-end (8 low bits)
 
-	regs[0x0c] = W9966_SRAMID;		// SRAM-banks (1x 128kb)
-	
+	regs[0x0c] = cam->sramid;		// SRAM layout
+
 	// Enhancement layer
 	regs[0x0d] = (enh_s& 0x000ff);		// Enh. start (0-7)
 	regs[0x0e] = (enh_s& 0x0ff00)>>8;	// Enh. start (8-15)
@@ -493,35 +568,110 @@
 	regs[0x11] = (enh_e& 0x0ff00)>>8;	// Enh. end (8-15)
 	regs[0x12] = (enh_e& 0x70000)>>16;	// Enh. end (16-17/18??)
 
-	// Misc
-	regs[0x13] = 0x40;			// VEE control (raw 4:2:2)
-	regs[0x17] = 0x00;			// ???
-	regs[0x18] = cam->i2c_state = 0x00;	// Serial bus
-	regs[0x19] = 0xff;			// I/O port direction control
-	regs[0x1a] = 0xff;			// I/O port data register
-	regs[0x1b] = 0x10;			// ???
-	
-	// SAA7111 chip settings
-	saa7111_regs[0x0a] = cam->brightness;
-	saa7111_regs[0x0b] = cam->contrast;
-	saa7111_regs[0x0c] = cam->color;
-	saa7111_regs[0x0d] = cam->hue;
+	// Write regs to w9966cf chip
+	for (i = 0x01; i < 0x13; i++)
+		if (!w9966_wreg(cam, i, regs[i]))
+			return 0;
+
+	return 1;
+}
+
+// Detect and initialize saa7111 ccd-controller chip.
+// expects a claimed parport
+// expected to always return 1 unless error is _fatal_
+// 1 on success, else 0
+static int w9966_saa7111_init(struct w9966_dev* cam)
+{
+	// saa7111 regs 0x00 trough 0x12
+	const u8 regs[] = {
+		0x00, // not written
+		0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00, 0x88, 0x10,
+		cam->brightness,	// 0x0a
+		cam->contrast,		// 0x0b
+		cam->color,		// 0x0c
+		cam->hue,		// 0x0d
+		0x01, 0x00, 0x48, 0x0c, 0x00,
+	};
+	int i;
 
-// Reset (ECP-fifo & serial-bus)
-	if (w9966_wReg(cam, 0x00, 0x03) == -1)
-		return -1;
+	if (w9966_flag_test(cam, W9966_STATE_DETECTED))
+		return 1;
 
-// Write regs to w9966cf chip
-	for (i = 0; i < 0x1c; i++)
-		if (w9966_wReg(cam, i, regs[i]) == -1)
-			return -1;
+	// Write regs to saa7111 chip
+	for (i = 1; i < 0x13; i++)
+		if (!w9966_i2c_wreg(cam, W9966_SAA7111_ID, i, regs[i]))
+			return 1;
+
+	// Read back regs
+	for (i = 1; i < 0x13; i++)
+		if (w9966_i2c_rreg(cam, W9966_SAA7111_ID, i) != regs[i])
+			return 1;
+
+	// Fill in model specific data
+	cam->name = "Lifeview Flycam Supra";
+	cam->sramsize = 128 << 10;	// 128 kib
+	cam->sramid = 0x02;		// see w9966.pdf
+
+	cam->cmask = 0x18;		// normal polarity
+	cam->min_x = 16;		// empirically determined
+	cam->max_x = 705;
+	cam->min_y = 14;
+	cam->max_y = 253;
+	cam->image = &w9966_saa7111_image;
+
+	DPRINTF("Found and initialized a saa7111 chip.\n");
+	w9966_flag_set(cam, W9966_STATE_DETECTED);
+
+	return 1;
+}
+
+// Setup image properties (brightness, hue, etc.) for the saa7111 chip
+// expects a claimed parport
+// 1 on success, else 0
+static int w9966_saa7111_image(struct w9966_dev* cam)
+{
+	if (!w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0a, cam->brightness) ||
+	    !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0b, cam->contrast) ||
+	    !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0c, cam->color) ||
+	    !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0d, cam->hue))
+		return 0;
 
-// Write regs to saa7111 chip
-	for (i = 0; i < 0x20; i++)
-		if (w9966_wReg_i2c(cam, i, saa7111_regs[i]) == -1)
-			return -1;
+	return 1;
+}
 
-	return 0;
+// Detect and initialize lc99053 ccd-controller chip.
+// expects a claimed parport
+// this is currently a hack, no detection is done, we just assume an Eyestar2
+// 1 on success, else 0
+static int w9966_lc99053_init(struct w9966_dev* cam)
+{
+	if (w9966_flag_test(cam, W9966_STATE_DETECTED))
+		return 1;
+
+	// Fill in model specific data
+	cam->name = "Microtek Eyestar2";
+	cam->sramsize = 128 << 10;	// 128 kib
+	cam->sramid = 0x02;		// w9966cf.pdf
+
+	cam->cmask = 0x10;		// reverse polarity
+	cam->min_x = 16;		// empirically determined
+	cam->max_x = 705;
+	cam->min_y = 14;
+	cam->max_y = 253;
+	cam->image = &w9966_lc99053_image;
+
+	DPRINTF("Found and initialized a lc99053 chip.\n");
+	w9966_flag_set(cam, W9966_STATE_DETECTED);
+
+	return 1;
+}
+
+// Setup image properties (brightness, hue, etc.) for the lc99053 chip
+// expects a claimed parport
+// 1 on success, else 0
+static int w9966_lc99053_image(struct w9966_dev* cam)
+{
+	return 1;
 }
 
 /*
@@ -536,91 +686,90 @@
 		cam->i2c_state |= W9966_I2C_W_DATA;
 	else
 		cam->i2c_state &= ~W9966_I2C_W_DATA;
-	
-	w9966_wReg(cam, 0x18, cam->i2c_state);
-	udelay(5);
+
+	w9966_wreg(cam, 0x18, cam->i2c_state);
+	udelay(W9966_I2C_UDELAY);
 }
 
 // Sets the clock line on the i2c bus.
-// Expects a claimed pdev. -1 on error
+// Expects a claimed pdev.
+// 1 on success, else 0
 static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
 {
-	int timeout;
 	if (state)
 		cam->i2c_state |= W9966_I2C_W_CLOCK;
 	else
 		cam->i2c_state &= ~W9966_I2C_W_CLOCK;
 
-	w9966_wReg(cam, 0x18, cam->i2c_state);
-	udelay(5);
-	
-	// we go to high, we also expect the peripheral to ack.
+	w9966_wreg(cam, 0x18, cam->i2c_state);
+	udelay(W9966_I2C_UDELAY);
+
+	// when we go to high, we also expect the peripheral to ack.
 	if (state) {
-		timeout = jiffies + 100;
+		const int timeout = jiffies + W9966_I2C_TIMEOUT;
 		while (!w9966_i2c_getscl(cam)) {
-			if (jiffies > timeout)
-				return -1;
+			if (time_after(jiffies, timeout))
+				return 0;
 		}
 	}
-	return 0;
+	return 1;
 }
 
 // Get peripheral data line
 // Expects a claimed pdev.
 static inline int w9966_i2c_getsda(struct w9966_dev* cam)
 {
-	const unsigned char state = w9966_rReg(cam, 0x18);
-	return ((state & W9966_I2C_R_DATA) > 0);
+	const u8 pins = w9966_rreg(cam, 0x18);
+	return ((pins & W9966_I2C_R_DATA) > 0);
 }
 
 // Get peripheral clock line
 // Expects a claimed pdev.
 static inline int w9966_i2c_getscl(struct w9966_dev* cam)
 {
-	const unsigned char state = w9966_rReg(cam, 0x18);
-	return ((state & W9966_I2C_R_CLOCK) > 0);
+	const u8 pins = w9966_rreg(cam, 0x18);
+	return ((pins & W9966_I2C_R_CLOCK) > 0);
 }
 
 // Write a byte with ack to the i2c bus.
-// Expects a claimed pdev. -1 on error
+// Expects a claimed pdev.
+// 1 on success, else 0
 static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
 {
 	int i;
-	for (i = 7; i >= 0; i--)
-	{
+	for (i = 7; i >= 0; i--) {
 		w9966_i2c_setsda(cam, (data >> i) & 0x01);
 
-		if (w9966_i2c_setscl(cam, 1) == -1)
-			return -1;			
-		w9966_i2c_setscl(cam, 0);
+		if (!w9966_i2c_setscl(cam, 1) ||
+		    !w9966_i2c_setscl(cam, 0))
+			return 0;
 	}
-
 	w9966_i2c_setsda(cam, 1);
-	
-	if (w9966_i2c_setscl(cam, 1) == -1)
-		return -1;
-	w9966_i2c_setscl(cam, 0);
-	
-	return 0;
+
+	if (!w9966_i2c_setscl(cam, 1) ||
+	    !w9966_i2c_setscl(cam, 0))
+		return 0;
+
+	return 1;
 }
 
 // Read a data byte with ack from the i2c-bus
 // Expects a claimed pdev. -1 on error
 static int w9966_i2c_rbyte(struct w9966_dev* cam)
 {
-	unsigned char data = 0x00;
-	int i;	
-	
+	u8 data = 0x00;
+	int i;
+
 	w9966_i2c_setsda(cam, 1);
 
 	for (i = 0; i < 8; i++)
 	{
-		if (w9966_i2c_setscl(cam, 1) == -1)
+		if (!w9966_i2c_setscl(cam, 1))
 			return -1;
 		data = data << 1;
 		if (w9966_i2c_getsda(cam))
 			data |= 0x01;
-		
+
 		w9966_i2c_setscl(cam, 0);
 	}
 	return data;
@@ -628,75 +777,81 @@
 
 // Read a register from the i2c device.
 // Expects claimed pdev. -1 on error
-static int w9966_rReg_i2c(struct w9966_dev* cam, int reg)
+static int w9966_i2c_rreg(struct w9966_dev* cam, int device, int reg)
 {
 	int data;
 
 	w9966_i2c_setsda(cam, 0);
 	w9966_i2c_setscl(cam, 0);
 
-	if (
-		w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
-		w9966_i2c_wbyte(cam, reg) == -1
-	)
+	if (!w9966_i2c_wbyte(cam, device << 1) ||
+	    !w9966_i2c_wbyte(cam, reg))
 		return -1;
 
 	w9966_i2c_setsda(cam, 1);
-	if (w9966_i2c_setscl(cam, 1) == -1)
+	if (!w9966_i2c_setscl(cam, 1))
 		return -1;
+
 	w9966_i2c_setsda(cam, 0);
 	w9966_i2c_setscl(cam, 0);
 
-	if (
-		w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1 ||
-		(data = w9966_i2c_rbyte(cam)) == -1
-	)
+	if (!w9966_i2c_wbyte(cam, (device << 1) | 1) ||
+	    (data = w9966_i2c_rbyte(cam)) == -1)
 		return -1;
 
 	w9966_i2c_setsda(cam, 0);
-	
-	if (w9966_i2c_setscl(cam, 1) == -1)
+
+	if (!w9966_i2c_setscl(cam, 1))
 		return -1;
+
 	w9966_i2c_setsda(cam, 1);
-	
+
 	return data;
 }
 
-
 // Write a register to the i2c device.
-// Expects claimed pdev. -1 on error
-static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
+// Expects claimed pdev.
+// 1 on success, else 0
+static int w9966_i2c_wreg(struct w9966_dev* cam, int device, int reg, int data)
 {
 	w9966_i2c_setsda(cam, 0);
 	w9966_i2c_setscl(cam, 0);
 
-	if (
-		w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
-		w9966_i2c_wbyte(cam, reg) == -1 ||
-		w9966_i2c_wbyte(cam, data) == -1
-	)
-		return -1;
+	if (!w9966_i2c_wbyte(cam, device << 1) ||
+	    !w9966_i2c_wbyte(cam, reg) ||
+	    !w9966_i2c_wbyte(cam, data))
+		return 0;
 
 	w9966_i2c_setsda(cam, 0);
-	if (w9966_i2c_setscl(cam, 1) == -1)
-		return -1;
-		
+	if (!w9966_i2c_setscl(cam, 1))
+		return 0;
+
 	w9966_i2c_setsda(cam, 1);
 
-	return 0;
+	return 1;
 }
 
 /*
- *	Video4linux interfacing
+ *	Video4linux interface
  */
 
 static int w9966_v4l_open(struct video_device *vdev, int flags)
 {
 	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
-	cam->buffer = (u8*)kmalloc(W9966_RBUFFER, GFP_KERNEL);
-	
-	if (cam->buffer == NULL)
+
+	// Claim parport
+	if (!w9966_pdev_claim(cam)) {
+		DPRINTF("Unable to claim parport");
 		return -EFAULT;
+	}
+
+	// Allocate read buffer
+	cam->buffer = (u8*)kmalloc(W9966_RBUFFER, GFP_KERNEL);
+	if (cam->buffer == NULL) {
+		w9966_pdev_release(cam);
+		return -ENOMEM;
+	}
+	w9966_flag_set(cam, W9966_STATE_BUFFER);
 
 	return 0;
 }
@@ -704,17 +859,22 @@
 static void w9966_v4l_close(struct video_device *vdev)
 {
 	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
-	
-	if (cam->buffer != NULL) {
+
+	// Free read buffer
+	if (w9966_flag_test(cam, W9966_STATE_BUFFER)) {
 		kfree(cam->buffer);
-		cam->buffer = NULL;
+		w9966_flag_clear(cam, W9966_STATE_BUFFER);
 	}
+
+	// release parport
+	w9966_pdev_release(cam);
 }
 
+// expects a claimed parport
 static int w9966_v4l_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
 {
 	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
-	
+
 	switch(cmd)
 	{
 	case VIDIOCGCAP:
@@ -723,9 +883,10 @@
 			W9966_DRIVERNAME,	// name
 			VID_TYPE_CAPTURE | VID_TYPE_SCALES,	// type
 			1, 0,			// vid, aud channels
-			W9966_WND_MAX_W,	// max w
-			W9966_WND_MAX_H,	// max h
-			2, 1			// min w, min h
+			cam->max_x - cam->min_x,
+			cam->max_y - cam->min_y,
+			W9966_WND_MIN_W,
+			W9966_WND_MIN_H
 		};
 
 		if(copy_to_user(arg, &vcap, sizeof(vcap)) != 0)
@@ -747,10 +908,10 @@
 		vch.tuners = 0;
 		vch.type = VIDEO_TYPE_CAMERA;
 		vch.norm = 0;		// ???
-		
+
 		if(copy_to_user(arg, &vch, sizeof(vch)) != 0)
 			return -EFAULT;
-		
+
 		return 0;
 	}
 	case VIDIOCSCHAN:
@@ -758,10 +919,10 @@
 		struct video_channel vch;
 		if(copy_from_user(&vch, arg, sizeof(vch) ) != 0)
 			return -EFAULT;
-		
+
 		if(vch.channel != 0)
 			return -EINVAL;
-		
+
 		return 0;
 	}
 	case VIDIOCGTUNER:
@@ -769,20 +930,20 @@
 		struct video_tuner vtune;
 		if(copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
 			return -EFAULT;
-		
+
 		if(vtune.tuner != 0);
 			return -EINVAL;
-		
+
 		strcpy(vtune.name, "no tuner");
 		vtune.rangelow = 0;
 		vtune.rangehigh = 0;
 		vtune.flags = VIDEO_TUNER_NORM;
 		vtune.mode = VIDEO_MODE_AUTO;
 		vtune.signal = 0xffff;
-		
+
 		if(copy_to_user(arg, &vtune, sizeof(vtune)) != 0)
 			return -EFAULT;
-		
+
 		return 0;
 	}
 	case VIDIOCSTUNER:
@@ -790,13 +951,13 @@
 		struct video_tuner vtune;
 		if (copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
 			return -EFAULT;
-		
+
 		if (vtune.tuner != 0)
 			return -EINVAL;
-		
+
 		if (vtune.mode != VIDEO_MODE_AUTO)
 			return -EINVAL;
-		
+
 		return 0;
 	}
 	case VIDIOCGPICT:
@@ -820,73 +981,58 @@
 		struct video_picture vpic;
 		if(copy_from_user(&vpic, arg, sizeof(vpic)) != 0)
 			return -EFAULT;
-		
+
 		if (vpic.depth != 16 || vpic.palette != VIDEO_PALETTE_YUV422)
 			return -EINVAL;
-			
+
 		cam->brightness = vpic.brightness >> 8;
 		cam->hue = (vpic.hue >> 8) - 128;
 		cam->color = vpic.colour >> 9;
 		cam->contrast = vpic.contrast >> 9;
 
-		w9966_pdev_claim(cam);
-		
-		if (
-			w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
-			w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
-			w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
-			w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
-		) {
-			w9966_pdev_release(cam);
+		if (!cam->image(cam))
 			return -EFAULT;
-		}
-		
-		w9966_pdev_release(cam);
+
 		return 0;
 	}
 	case VIDIOCSWIN:
 	{
-		int ret;
 		struct video_window vwin;
-		
+
 		if (copy_from_user(&vwin, arg, sizeof(vwin)) != 0)
-			return -EFAULT;		
-		if (vwin.flags != 0)
-			return -EINVAL;
-		if (vwin.clipcount != 0)
+			return -EFAULT;
+		if (
+		  vwin.flags != 0 ||
+		  vwin.clipcount != 0)
 			return -EINVAL;
-		if (vwin.width < 2 || vwin.width > W9966_WND_MAX_W)
-			return -EINVAL;		
-		if (vwin.height < 1 || vwin.height > W9966_WND_MAX_H)
+
+		if (vwin.width  > cam->max_x - cam->min_x ||
+		    vwin.height > cam->max_y - cam->min_y ||
+		    vwin.width  < W9966_WND_MIN_W ||
+		    vwin.height < W9966_WND_MIN_H)
 			return -EINVAL;
 
 		// Update camera regs
-		w9966_pdev_claim(cam);
-		ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin.width, vwin.height);
-		w9966_pdev_release(cam);
-		
-		if (ret != 0) {
-			DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
+		if (!w9966_window(cam, 0, 0, 1023, 1023, vwin.width, vwin.height))
 			return -EFAULT;
-		}
-		
+
 		return 0;
 	}
 	case VIDIOCGWIN:
 	{
 		struct video_window vwin;
 		memset(&vwin, 0, sizeof(vwin));
-		
+
 		vwin.width = cam->width;
 		vwin.height = cam->height;
-		
+
 		if(copy_to_user(arg, &vwin, sizeof(vwin)) != 0)
 			return -EFAULT;
-		
+
 		return 0;
 	}
 	// Unimplemented
-	case VIDIOCCAPTURE:	
+	case VIDIOCCAPTURE:
 	case VIDIOCGFBUF:
 	case VIDIOCSFBUF:
 	case VIDIOCKEY:
@@ -902,69 +1048,62 @@
 }
 
 // Capture data
+// expects a claimed parport and allocated read buffer
 static long w9966_v4l_read(struct video_device *vdev, char *buf, unsigned long count,  int noblock)
 {
 	struct w9966_dev *cam = (struct w9966_dev *)vdev->priv;
-	unsigned char addr = 0xa0;	// ECP, read, CCD-transfer, 00000
-	unsigned char* dest = (unsigned char*)buf;
+	const u8 addr = 0xa0;	// ECP, read, CCD-transfer, 00000
+	u8* dest = (u8*)buf;
 	unsigned long dleft = count;
-	
+
 	// Why would anyone want more than this??
 	if (count > cam->width * cam->height * 2)
-		return -EINVAL;
-	
-	w9966_pdev_claim(cam);
-	w9966_wReg(cam, 0x00, 0x02);	// Reset ECP-FIFO buffer
-	w9966_wReg(cam, 0x00, 0x00);	// Return to normal operation
-	w9966_wReg(cam, 0x01, 0x98);	// Enable capture
-
-	// write special capture-addr and negotiate into data transfer	
-	if (
-		(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0	)||
-		(parport_write(cam->pport, &addr, 1) != 1						)||
-		(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0	)
-	) {
-		w9966_pdev_release(cam);
+		count = cam->width * cam->height * 2;
+
+	w9966_wreg(cam, 0x00, 0x02);	// Reset ECP-FIFO buffer
+	w9966_wreg(cam, 0x00, 0x00);	// Return to normal operation
+	w9966_wreg(cam, 0x01, cam->cmask | 0x80);	// Enable capture
+
+	// write special capture-addr and negotiate into data transfer
+	if (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 ||
+	    parport_write(cam->pport, &addr, 1) != 1 ||
+	    parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0) {
+		DPRINTF("Unable to write capture-addr.\n");
 		return -EFAULT;
 	}
-	
+
 	while(dleft > 0)
 	{
-		unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
-	
-		if (parport_read(cam->pport, cam->buffer, tsize) < tsize) {
-			w9966_pdev_release(cam);
+		const size_t tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
+
+		if (parport_read(cam->pport, cam->buffer, tsize) < tsize)
 			return -EFAULT;
-		}
-		if (copy_to_user(dest, cam->buffer, tsize) != 0) {
-			w9966_pdev_release(cam);
+
+		if (copy_to_user(dest, cam->buffer, tsize) != 0)
 			return -EFAULT;
-		}
+
 		dest += tsize;
 		dleft -= tsize;
 	}
-	
-	w9966_wReg(cam, 0x01, 0x18);	// Disable capture
-	w9966_pdev_release(cam);
+
+	w9966_wreg(cam, 0x01, cam->cmask);	// Disable capture
 
 	return count;
 }
 
-
 // Called once for every parport on init
 static void w9966_attach(struct parport *port)
 {
 	int i;
-	
-	for (i = 0; i < W9966_MAXCAMS; i++)
-	{
-		if (strcmp(pardev[i], "none") == 0)	// Skip if 'none'
-			continue;
-		if (w9966_cams[i].dev_state != 0)	// Cam is already assigned
+
+	for (i = 0; i < W9966_MAXCAMS; i++) {
+		if (strcmp(pardev[i], "none") == 0 ||	// Skip if 'none' or if
+		    w9966_cams[i].dev_state != 0)	// cam already assigned
 			continue;
+
 		if (strcmp(pardev[i], "auto") == 0 ||
 		    strcmp(pardev[i], port->name) == 0) {
-			if (w9966_init(&w9966_cams[i], port) != 0)
+			if (!w9966_init(&w9966_cams[i], port, video_nr[i]))
 				w9966_term(&w9966_cams[i]);
 			break;	// return
 		}
@@ -991,16 +1130,33 @@
 // Module entry point
 static int __init w9966_mod_init(void)
 {
-	int i;
+	int i, err;
+
+	w9966_cams = kmalloc(
+		sizeof(struct w9966_dev) * W9966_MAXCAMS, GFP_KERNEL);
+
+	if (!w9966_cams)
+		return -ENOMEM;
+
 	for (i = 0; i < W9966_MAXCAMS; i++)
 		w9966_cams[i].dev_state = 0;
 
-	return parport_register_driver(&w9966_ppd);
+	// Register parport driver
+	if ((err = parport_register_driver(&w9966_ppd)) != 0) {
+		kfree(w9966_cams);
+		w9966_cams = 0;
+		return err;
+	}
+
+	return 0;
 }
 
 // Module cleanup
 static void __exit w9966_mod_term(void)
 {
+	if (w9966_cams)
+		kfree(w9966_cams);
+
 	parport_unregister_driver(&w9966_ppd);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/media/video/zr36067.c linux/drivers/media/video/zr36067.c
--- linux.orig/drivers/media/video/zr36067.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/media/video/zr36067.c	2002-07-20 01:08:35.000000000 +0000
@@ -3265,7 +3265,10 @@
 
 			btwrite(IRQ_MASK, ZR36057_ISR);	// Clears interrupts
 			btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);
-			dev->busy = 0;	/* Allow second open */
+			/* FIXME: Don't do it this way, use the
+			 * video_device->fops registration for a sane
+			 * implementation of multiple opens */
+			dev->users--;	/* Allow second open */
 		}
 
 		break;
@@ -3323,6 +3326,7 @@
 		}
 	}
 
+	dev->users++;
 	zr->user--;
 
 	MOD_DEC_USE_COUNT;
@@ -4205,9 +4209,7 @@
 
 			/* sleep 1 second */
 
-			timeout = jiffies + 1 * HZ;
-			while (jiffies < timeout)
-				schedule();
+			schedule_timeout(HZ);
 
 			/* Get status of video decoder */
 
@@ -4397,22 +4399,18 @@
 }
 
 static struct video_device zoran_template = {
-	THIS_MODULE,
-	ZORAN_NAME,
-	VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
-	    VID_TYPE_FRAMERAM | VID_TYPE_SCALES | VID_TYPE_SUBCAPTURE,
-	ZORAN_HARDWARE,
-	zoran_open,
-	zoran_close,
-	zoran_read,
-	zoran_write,
-	NULL,
-	zoran_ioctl,
-	zoran_mmap,
-	zoran_init_done,
-	NULL,
-	0,
-	0
+	owner:		THIS_MODULE,
+	name:		ZORAN_NAME,
+	type:		VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
+			VID_TYPE_FRAMERAM | VID_TYPE_SCALES | VID_TYPE_SUBCAPTURE,
+	hardware:	ZORAN_HARDWARE,
+	open:		zoran_open,
+	close:		zoran_close,
+	read:		zoran_read,
+	write:		zoran_write,
+	ioctl:		zoran_ioctl,
+	mmap:		zoran_mmap,
+	initialize:	zoran_init_done,
 };
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/Config.in linux/drivers/message/fusion/Config.in
--- linux.orig/drivers/message/fusion/Config.in	2001-07-07 00:03:11.000000000 +0000
+++ linux/drivers/message/fusion/Config.in	2002-07-20 01:08:30.000000000 +0000
@@ -7,10 +7,8 @@
 
   if [ "$CONFIG_BLK_DEV_SD" = "y" -a "$CONFIG_FUSION" = "y" ]; then
     define_bool CONFIG_FUSION_BOOT y
-    comment "(ability to boot linux kernel from Fusion device is ENABLED!)"
   else
     define_bool CONFIG_FUSION_BOOT n
-    comment "(ability to boot linux kernel from Fusion device is DISABLED!)"
   fi
 
   if [ "$CONFIG_MODULES" = "y" ]; then
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/Makefile linux/drivers/message/fusion/Makefile
--- linux.orig/drivers/message/fusion/Makefile	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/Makefile	2002-07-20 01:08:25.000000000 +0000
@@ -27,6 +27,7 @@
 #EXTRA_CFLAGS += -DDEBUG
 #EXTRA_CFLAGS += -DMPT_DEBUG
 #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
+#EXTRA_CFLAGS += -DMPT_DEBUG_SG
 #
 # driver/module specifics...
 #
@@ -34,11 +35,13 @@
 #CFLAGS_mptbase.o += -DMPT_DEBUG_HANDSHAKE
 #CFLAGS_mptbase.o += -DMPT_DEBUG_IRQ
 #
-#  For {mptscsih, mptctl}:
+#  For mptscsih:
 #CFLAGS_mptscsih.o += -DMPT_SCSI_USE_NEW_EH
 #CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV
-#CFLAGS_mptscsih.o += -DMPT_DEBUG_SG
-#CFLAGS_mptctl.o += -DMPT_DEBUG_SG
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_RESET
+#
+#  For mptctl:
+#CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL
 #
 #  For mptlan:
 #CFLAGS_mptlan.o += -DMPT_LAN_IO_DEBUG
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/isense.c linux/drivers/message/fusion/isense.c
--- linux.orig/drivers/message/fusion/isense.c	2001-10-11 16:14:32.000000000 +0000
+++ linux/drivers/message/fusion/isense.c	2002-07-20 01:08:36.000000000 +0000
@@ -5,12 +5,13 @@
  *      Error Report logging output.  This module implements SCSI-3
  *      Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings.
  *
- *  Copyright (c) 1991-2001 Steven J. Ralston
+ *  Copyright (c) 1991-2002 Steven J. Ralston
  *  Written By: Steven J. Ralston
  *  (yes I wrote some of the orig. code back in 1991!)
- *  (mailto:Steve.Ralston@lsil.com)
+ *  (mailto:sjralston1@netscape.net)
+ *  (mailto:Pam.Delaney@lsil.com)
  *
- *  $Id: isense.c,v 1.28.14.1 2001/08/24 20:07:04 sralston Exp $
+ *  $Id: isense.c,v 1.33 2002/02/27 18:44:19 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -49,11 +50,15 @@
 */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include <linux/module.h>
+#include <linux/version.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/version.h>
+#include <asm/io.h>
+#if defined (__sparc__)
+#include <linux/timer.h>
+#endif
 
 /* Hmmm, avoid undefined spinlock_t on lk-2.2.14-5.0 */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
@@ -61,7 +66,7 @@
 #endif
 
 #define MODULEAUTHOR "Steven J. Ralston"
-#define COPYRIGHT "Copyright (c) 2001 " MODULEAUTHOR
+#define COPYRIGHT "Copyright (c) 2001-2002 " MODULEAUTHOR
 #include "mptbase.h"
 
 #include "isense.h"
@@ -87,7 +92,6 @@
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
-MODULE_LICENSE("GPL");
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 int __init isense_init(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/linux_compat.h linux/drivers/message/fusion/linux_compat.h
--- linux.orig/drivers/message/fusion/linux_compat.h	2001-07-07 00:03:11.000000000 +0000
+++ linux/drivers/message/fusion/linux_compat.h	2002-07-20 01:08:31.000000000 +0000
@@ -11,6 +11,10 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
+#ifndef rwlock_init
+#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+#endif
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
 #	if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
 		typedef unsigned int dma_addr_t;
@@ -51,19 +55,40 @@
 typedef void (*__cleanup_module_func_t)(void);
 #define module_init(x) \
 	int init_module(void) __attribute__((alias(#x))); \
-	extern inline __init_module_func_t __init_module_inline(void) \
+	static inline __init_module_func_t __init_module_inline(void) \
 	{ return x; }
 #define module_exit(x) \
 	void cleanup_module(void) __attribute__((alias(#x))); \
-	extern inline __cleanup_module_func_t __cleanup_module_inline(void) \
+	static inline __cleanup_module_func_t __cleanup_module_inline(void) \
 	{ return x; }
 
-#else 
+#else
 #define module_init(x)	__initcall(x);
 #define module_exit(x)	__exitcall(x);
 #endif
 /* } block snipped from lk-2.2.18/include/linux/init.h */
 
+/* This block snipped from lk-2.2.18/include/linux/sched.h { */
+/*
+ * Used prior to schedule_timeout calls..
+ */
+#define __set_current_state(state_value)	do { current->state = state_value; } while (0)
+#ifdef __SMP__
+#define set_current_state(state_value)		do { __set_current_state(state_value); mb(); } while (0)
+#else
+#define set_current_state(state_value)		__set_current_state(state_value)
+#endif
+/* } block snipped from lk-2.2.18/include/linux/sched.h */
+
+/* procfs compat stuff... */
+#define proc_mkdir(x,y)			create_proc_entry(x, S_IFDIR, y)
+
+/* MUTEX compat stuff... */
+#define DECLARE_MUTEX(name)		struct semaphore name=MUTEX
+#define DECLARE_MUTEX_LOCKED(name)	struct semaphore name=MUTEX_LOCKED
+#define init_MUTEX(x)			*(x)=MUTEX
+#define init_MUTEX_LOCKED(x)		*(x)=MUTEX_LOCKED
+
 /* Wait queues. */
 #define DECLARE_WAIT_QUEUE_HEAD(name)	\
 	struct wait_queue * (name) = NULL
@@ -90,6 +115,17 @@
 #endif		/* LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) */
 
 
+/*
+ * Inclined to use:
+ *   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
+ * here, but MODULE_LICENSE defined in 2.4.9-6 and 2.4.9-13
+ * breaks the rule:-(
+ */
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(license)
+#endif
+
+
 /* PCI/driver subsystem { */
 #ifndef pci_for_each_dev
 #define pci_for_each_dev(dev)		for((dev)=pci_devices; (dev)!=NULL; (dev)=(dev)->next)
@@ -120,26 +156,6 @@
 #endif		/* } ifndef pci_for_each_dev */
 
 
-/* procfs compat stuff... */
-#ifdef CONFIG_PROC_FS
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,28)
-#define CREATE_PROCDIR_ENTRY(x,y)  create_proc_entry(x, S_IFDIR, y)
-/* This is a macro so we don't need to pull all the procfs
- * headers into this file. -DaveM
- */
-#define create_proc_read_entry(name, mode, base, __read_proc, __data) \
-({      struct proc_dir_entry *__res=create_proc_entry(name,mode,base); \
-        if (__res) { \
-                __res->read_proc=(__read_proc); \
-                __res->data=(__data); \
-        } \
-        __res; \
-})
-#else
-#define CREATE_PROCDIR_ENTRY(x,y)  proc_mkdir(x, y)
-#endif
-#endif
-
 /* Compatability for the 2.3.x PCI DMA API. */
 #ifndef PCI_DMA_BIDIRECTIONAL
 /*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -194,6 +210,7 @@
 /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif /* PCI_DMA_BIDIRECTIONAL */
 
+
 /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif /* _LINUX_COMPAT_H */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/fc_log.h linux/drivers/message/fusion/lsi/fc_log.h
--- linux.orig/drivers/message/fusion/lsi/fc_log.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/lsi/fc_log.h	2002-07-20 01:08:24.000000000 +0000
@@ -7,7 +7,7 @@
  *                  in the IOCLogInfo field of a MPI Default Reply Message.
  *
  *  CREATION DATE:  6/02/2000
- *  ID:             $Id: fc_log.h,v 4.5 2001/06/07 19:18:00 sschremm Exp $
+ *  ID:             $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $
  */
 
 
@@ -62,7 +62,7 @@
     MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP     = 0x2100000a, /* Manual Response not sent due to a LIP */
     MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3             = 0x2100000b, /* not sent because remote node does not support Class 3 */
     MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID        = 0x2100000c, /* not sent because login to remote node not validated */
-    MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND          = 0x2100000e, /* cleared from the outbound after a logout */
+    MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND          = 0x2100000e, /* cleared from the outbound queue after a logout */
     MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN    = 0x2100000f, /* cleared waiting for data after a logout */
 
     MPI_IOCLOGINFO_FC_LAN_BASE                      = 0x22000000,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi.h linux/drivers/message/fusion/lsi/mpi.h
--- linux.orig/drivers/message/fusion/lsi/mpi.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi.h	2002-07-20 01:08:26.000000000 +0000
@@ -6,7 +6,7 @@
  *          Title:  MPI Message independent structures and definitions
  *  Creation Date:  July 27, 2000
  *
- *    MPI Version:  01.01.07
+ *    MPI Version:  01.02.03
  *
  *  Version History
  *  ---------------
@@ -39,6 +39,11 @@
  *                      Added function codes for RAID.
  *  04-09-01  01.01.07  Added alternate define for MPI_DOORBELL_ACTIVE,
  *                      MPI_DOORBELL_USED, to better match the spec.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *                      Changed MPI_VERSION_MINOR from 0x01 to 0x02.
+ *                      Added define MPI_FUNCTION_TOOLBOX.
+ *  09-28-01  01.02.02  New function code MPI_SCSI_ENCLOSURE_PROCESSOR.
+ *  11-01-01  01.02.03  Changed name to MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR.
  *  --------------------------------------------------------------------------
  */
 
@@ -53,7 +58,7 @@
 *****************************************************************************/
 
 #define MPI_VERSION_MAJOR                   (0x01)
-#define MPI_VERSION_MINOR                   (0x01)
+#define MPI_VERSION_MINOR                   (0x02)
 #define MPI_VERSION            ((MPI_VERSION_MAJOR << 8) | MPI_VERSION_MINOR)
 
 /* Note: The major versions of 0xe0 through 0xff are reserved */
@@ -216,9 +221,13 @@
 #define MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND       (0x13)
 #define MPI_FUNCTION_FC_PRIMITIVE_SEND              (0x14)
 
-#define MPI_FUNCTION_RAID_VOLUME                    (0x15)
+#define MPI_FUNCTION_RAID_ACTION                    (0x15)
 #define MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH       (0x16)
 
+#define MPI_FUNCTION_TOOLBOX                        (0x17)
+
+#define MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR       (0x18)
+
 #define MPI_FUNCTION_LAN_SEND                       (0x20)
 #define MPI_FUNCTION_LAN_RECEIVE                    (0x21)
 #define MPI_FUNCTION_LAN_RESET                      (0x22)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_cnfg.h linux/drivers/message/fusion/lsi/mpi_cnfg.h
--- linux.orig/drivers/message/fusion/lsi/mpi_cnfg.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_cnfg.h	2002-07-20 01:08:21.000000000 +0000
@@ -6,7 +6,7 @@
  *          Title:  MPI Config message, structures, and Pages
  *  Creation Date:  July 27, 2000
  *
- *    MPI Version:  01.01.11
+ *    MPI Version:  01.02.05
  *
  *  Version History
  *  ---------------
@@ -72,6 +72,42 @@
  *                      Added IO Unit Page 3.
  *                      Modified defines for Scsi Port Page 2.
  *                      Modified RAID Volume Pages.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *                      Added SepID and SepBus to RVP2 IMPhysicalDisk struct.
+ *                      Added defines for the SEP bits in RVP2 VolumeSettings.
+ *                      Modified the DeviceSettings field in RVP2 to use the
+ *                      proper structure.
+ *                      Added defines for SES, SAF-TE, and cross channel for
+ *                      IOCPage2 CapabilitiesFlags.
+ *                      Removed define for MPI_IOUNITPAGE2_FLAGS_RAID_DISABLE.
+ *                      Removed define for
+ *                      MPI_SCSIPORTPAGE2_PORT_FLAGS_PARITY_ENABLE.
+ *                      Added define for MPI_CONFIG_PAGEATTR_RO_PERSISTENT.
+ *  08-29-01 01.02.02   Fixed value for MPI_MANUFACTPAGE_DEVID_53C1035.
+ *                      Added defines for MPI_FCPORTPAGE1_FLAGS_HARD_ALPA_ONLY
+ *                      and MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY.
+ *                      Removed MPI_SCSIPORTPAGE0_CAP_PACING_TRANSFERS,
+ *                      MPI_SCSIDEVPAGE0_NP_PACING_TRANSFERS, and
+ *                      MPI_SCSIDEVPAGE1_RP_PACING_TRANSFERS, and
+ *                      MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED.
+ *                      Added defines for MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED
+ *                      and MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED.
+ *                      Added OnBusTimerValue to CONFIG_PAGE_SCSI_PORT_1.
+ *                      Added rejected bits to SCSI Device Page 0 Information.
+ *                      Increased size of ALPA array in FC Port Page 2 by one
+ *                      and removed a one byte reserved field.
+ *  09-28-01 01.02.03   Swapped NegWireSpeedLow and NegWireSpeedLow in
+ *                      CONFIG_PAGE_LAN_1 to match preferred 64-bit ordering.
+ *                      Added structures for Manufacturing Page 4, IO Unit
+ *                      Page 3, IOC Page 3, IOC Page 4, RAID Volume Page 0, and
+ *                      RAID PhysDisk Page 0.
+ *  10-04-01 01.02.04   Added define for MPI_CONFIG_PAGETYPE_RAID_PHYSDISK.
+ *                      Modified some of the new defines to make them 32
+ *                      character unique.
+ *                      Modified how variable length pages (arrays) are defined.
+ *                      Added generic defines for hot spare pools and RAID
+ *                      volume types.
+ *  11-01-01 01.02.05   Added define for MPI_IOUNITPAGE1_DISABLE_IR.
  *  --------------------------------------------------------------------------
  */
 
@@ -104,12 +140,13 @@
   fCONFIG_PAGE_HEADER_UNION, MPI_POINTER PTR_CONFIG_PAGE_HEADER_UNION;
 
 
-/****************************************************************************/
-/*  PageType field values                                                   */
-/****************************************************************************/
+/****************************************************************************
+*   PageType field values
+****************************************************************************/
 #define MPI_CONFIG_PAGEATTR_READ_ONLY               (0x00)
 #define MPI_CONFIG_PAGEATTR_CHANGEABLE              (0x10)
 #define MPI_CONFIG_PAGEATTR_PERSISTENT              (0x20)
+#define MPI_CONFIG_PAGEATTR_RO_PERSISTENT           (0x30)
 #define MPI_CONFIG_PAGEATTR_MASK                    (0xF0)
 
 #define MPI_CONFIG_PAGETYPE_IO_UNIT                 (0x00)
@@ -122,29 +159,21 @@
 #define MPI_CONFIG_PAGETYPE_LAN                     (0x07)
 #define MPI_CONFIG_PAGETYPE_RAID_VOLUME             (0x08)
 #define MPI_CONFIG_PAGETYPE_MANUFACTURING           (0x09)
+#define MPI_CONFIG_PAGETYPE_RAID_PHYSDISK           (0x0A)
 #define MPI_CONFIG_PAGETYPE_MASK                    (0x0F)
 
 #define MPI_CONFIG_TYPENUM_MASK                     (0x0FFF)
 
 
 /****************************************************************************
- *  PageAddres field values
- ****************************************************************************/
+*   PageAddress field values
+****************************************************************************/
 #define MPI_SCSI_PORT_PGAD_PORT_MASK                (0x000000FF)
 
-#define MPI_SCSI_DEVICE_FORM_MASK                   (0xF0000000)
-#define MPI_SCSI_DEVICE_FORM_TARGETID               (0x00000000)
-#define MPI_SCSI_DEVICE_FORM_RAID_PHYS_DEV_NUM      (0x10000000)
 #define MPI_SCSI_DEVICE_TARGET_ID_MASK              (0x000000FF)
 #define MPI_SCSI_DEVICE_TARGET_ID_SHIFT             (0)
 #define MPI_SCSI_DEVICE_BUS_MASK                    (0x0000FF00)
 #define MPI_SCSI_DEVICE_BUS_SHIFT                   (8)
-#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_MASK         (0x000000FF)
-#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_SHIFT        (0)
-#define MPI_SCSI_DEVICE_VOLUME_BUS_MASK             (0x0000FF00)
-#define MPI_SCSI_DEVICE_VOLUME_BUS_SHIFT            (8)
-#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_MASK          (0x00FF0000)
-#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_SHIFT         (16)
 
 #define MPI_FC_PORT_PGAD_PORT_MASK                  (0xF0000000)
 #define MPI_FC_PORT_PGAD_PORT_SHIFT                 (28)
@@ -167,10 +196,14 @@
 #define MPI_FC_DEVICE_PGAD_BT_TID_MASK              (0x000000FF)
 #define MPI_FC_DEVICE_PGAD_BT_TID_SHIFT             (0)
 
+#define MPI_PHYSDISK_PGAD_PHYSDISKNUM_MASK          (0x000000FF)
+#define MPI_PHYSDISK_PGAD_PHYSDISKNUM_SHIFT         (0)
+
+
 
-/****************************************************************************/
-/*  Config Request Message                                                          */
-/****************************************************************************/
+/****************************************************************************
+*   Config Request Message
+****************************************************************************/
 typedef struct _MSG_CONFIG
 {
     U8                      Action;                     /* 00h */
@@ -181,16 +214,16 @@
     U8                      MsgFlags;                   /* 07h */
     U32                     MsgContext;                 /* 08h */
     U8                      Reserved2[8];               /* 0Ch */
-   fCONFIG_PAGE_HEADER      Header;                     /* 14h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 14h */
     U32                     PageAddress;                /* 18h */
     SGE_IO_UNION            PageBufferSGE;              /* 1Ch */
 } MSG_CONFIG, MPI_POINTER PTR_MSG_CONFIG,
   Config_t, MPI_POINTER pConfig_t;
 
 
-/****************************************************************************/
-/*  Action field values                                                     */
-/****************************************************************************/
+/****************************************************************************
+*   Action field values
+****************************************************************************/
 #define MPI_CONFIG_ACTION_PAGE_HEADER               (0x00)
 #define MPI_CONFIG_ACTION_PAGE_READ_CURRENT         (0x01)
 #define MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT        (0x02)
@@ -213,7 +246,7 @@
     U8                      Reserved2[2];               /* 0Ch */
     U16                     IOCStatus;                  /* 0Eh */
     U32                     IOCLogInfo;                 /* 10h */
-   fCONFIG_PAGE_HEADER      Header;                     /* 14h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 14h */
 } MSG_CONFIG_REPLY, MPI_POINTER PTR_MSG_CONFIG_REPLY,
   ConfigReply_t, MPI_POINTER pConfigReply_t;
 
@@ -225,19 +258,24 @@
 *
 *****************************************************************************/
 
-/****************************************************************************/
-/*  Manufacturing Config pages                                              */
-/****************************************************************************/
+/****************************************************************************
+*   Manufacturing Config pages
+****************************************************************************/
 #define MPI_MANUFACTPAGE_DEVICEID_FC909             (0x0621)
 #define MPI_MANUFACTPAGE_DEVICEID_FC919             (0x0624)
 #define MPI_MANUFACTPAGE_DEVICEID_FC929             (0x0622)
+#define MPI_MANUFACTPAGE_DEVICEID_FC919X            (0x0628)
+#define MPI_MANUFACTPAGE_DEVICEID_FC929X            (0x0626)
 #define MPI_MANUFACTPAGE_DEVID_53C1030              (0x0030)
 #define MPI_MANUFACTPAGE_DEVID_53C1030ZC            (0x0031)
-#define MPI_MANUFACTPAGE_DEVID_53C1035              (0x0035)
+#define MPI_MANUFACTPAGE_DEVID_1030_53C1035         (0x0032)
+#define MPI_MANUFACTPAGE_DEVID_1030ZC_53C1035       (0x0033)
+#define MPI_MANUFACTPAGE_DEVID_53C1035              (0x0040)
+#define MPI_MANUFACTPAGE_DEVID_53C1035ZC            (0x0041)
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_0
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U8                      ChipName[16];               /* 04h */
     U8                      ChipRevision[8];            /* 14h */
     U8                      BoardName[16];              /* 1Ch */
@@ -252,7 +290,7 @@
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_1
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U8                      VPD[256];                   /* 04h */
 } fCONFIG_PAGE_MANUFACTURING_1, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_1,
   ManufacturingPage1_t, MPI_POINTER pManufacturingPage1_t;
@@ -269,35 +307,72 @@
   MpiChipRevisionId_t, MPI_POINTER pMpiChipRevisionId_t;
 
 
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_MAN_PAGE_2_HW_SETTINGS_WORDS
+#define MPI_MAN_PAGE_2_HW_SETTINGS_WORDS    (1)
+#endif
+
 typedef struct _CONFIG_PAGE_MANUFACTURING_2
 {
-   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
-    MPI_CHIP_REVISION_ID                ChipId;         /* 04h */
-    U32                                 HwSettings[1];  /* 08h */
+    fCONFIG_PAGE_HEADER      Header;                                 /* 00h */
+    MPI_CHIP_REVISION_ID    ChipId;                                 /* 04h */
+    U32                     HwSettings[MPI_MAN_PAGE_2_HW_SETTINGS_WORDS];/* 08h */
 } fCONFIG_PAGE_MANUFACTURING_2, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_2,
   ManufacturingPage2_t, MPI_POINTER pManufacturingPage2_t;
 
 #define MPI_MANUFACTURING2_PAGEVERSION                  (0x00)
 
 
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_MAN_PAGE_3_INFO_WORDS
+#define MPI_MAN_PAGE_3_INFO_WORDS           (1)
+#endif
+
 typedef struct _CONFIG_PAGE_MANUFACTURING_3
 {
-   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
-    MPI_CHIP_REVISION_ID                ChipId;         /* 04h */
-    U32                                 Info[1];        /* 08h */
+    fCONFIG_PAGE_HEADER                  Header;                     /* 00h */
+    MPI_CHIP_REVISION_ID                ChipId;                     /* 04h */
+    U32                                 Info[MPI_MAN_PAGE_3_INFO_WORDS];/* 08h */
 } fCONFIG_PAGE_MANUFACTURING_3, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_3,
   ManufacturingPage3_t, MPI_POINTER pManufacturingPage3_t;
 
 #define MPI_MANUFACTURING3_PAGEVERSION                  (0x00)
 
 
-/****************************************************************************/
-/*  IO Unit Config Pages                                                    */
-/****************************************************************************/
+typedef struct _CONFIG_PAGE_MANUFACTURING_4
+{
+    fCONFIG_PAGE_HEADER              Header;             /* 00h */
+    U32                             Reserved1;          /* 04h */
+    U8                              InfoOffset0;        /* 08h */
+    U8                              InfoSize0;          /* 09h */
+    U8                              InfoOffset1;        /* 0Ah */
+    U8                              InfoSize1;          /* 0Bh */
+    U8                              InquirySize;        /* 0Ch */
+    U8                              Reserved2;          /* 0Dh */
+    U16                             Reserved3;          /* 0Eh */
+    U8                              InquiryData[56];    /* 10h */
+    U32                             ISVolumeSettings;   /* 48h */
+    U32                             IMEVolumeSettings;  /* 4Ch */
+    U32                             IMVolumeSettings;   /* 50h */
+} fCONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
+  ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
+
+#define MPI_MANUFACTURING4_PAGEVERSION                  (0x00)
+
+
+/****************************************************************************
+*   IO Unit Config Pages
+****************************************************************************/
 
 typedef struct _CONFIG_PAGE_IO_UNIT_0
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U64                     UniqueValue;                /* 04h */
 } fCONFIG_PAGE_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_0,
   IOUnitPage0_t, MPI_POINTER pIOUnitPage0_t;
@@ -307,18 +382,20 @@
 
 typedef struct _CONFIG_PAGE_IO_UNIT_1
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
 } fCONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
   IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
 
 #define MPI_IOUNITPAGE1_PAGEVERSION                     (0x00)
 
+/* IO Unit Page 1 Flags defines */
+
 #define MPI_IOUNITPAGE1_MULTI_FUNCTION                  (0x00000000)
 #define MPI_IOUNITPAGE1_SINGLE_FUNCTION                 (0x00000001)
 #define MPI_IOUNITPAGE1_MULTI_PATHING                   (0x00000002)
 #define MPI_IOUNITPAGE1_SINGLE_PATHING                  (0x00000000)
-
+#define MPI_IOUNITPAGE1_DISABLE_IR                      (0x00000040)
 #define MPI_IOUNITPAGE1_FORCE_32                        (0x00000080)
 
 
@@ -335,7 +412,7 @@
 
 typedef struct _CONFIG_PAGE_IO_UNIT_2
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
     U32                     BiosVersion;                /* 08h */
     MPI_ADAPTER_INFO        AdapterOrder[4];            /* 0Ch */
@@ -344,38 +421,45 @@
 
 #define MPI_IOUNITPAGE2_PAGEVERSION                     (0x00)
 
-#define MPI_IOUNITPAGE2_FLAGS_RAID_DISABLE              (0x00000001)
 #define MPI_IOUNITPAGE2_FLAGS_PAUSE_ON_ERROR            (0x00000002)
 #define MPI_IOUNITPAGE2_FLAGS_VERBOSE_ENABLE            (0x00000004)
 #define MPI_IOUNITPAGE2_FLAGS_COLOR_VIDEO_DISABLE       (0x00000008)
 #define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40          (0x00000010)
 
 
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_IO_UNIT_PAGE_3_GPIO_VAL_MAX
+#define MPI_IO_UNIT_PAGE_3_GPIO_VAL_MAX     (1)
+#endif
+
 typedef struct _CONFIG_PAGE_IO_UNIT_3
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
-    U32                     VolumeSettings;             /* 04h */
-    U8                      InfoOffset0;                /* 08h */
-    U8                      InfoSize0;                  /* 09h */
-    U8                      InfoOffset1;                /* 0Ah */
-    U8                      InfoSize1;                  /* 0Bh */
-    U8                      InquirySize;                /* 0Ch */
-    U8                      Reserved;                   /* 0Dh */
-    U16                     Reserved2;                  /* 0Eh */
-    U8                      InquiryData[56];            /* 10h */
+    fCONFIG_PAGE_HEADER      Header;                                   /* 00h */
+    U8                      GPIOCount;                                /* 04h */
+    U8                      Reserved1;                                /* 05h */
+    U16                     Reserved2;                                /* 06h */
+    U16                     GPIOVal[MPI_IO_UNIT_PAGE_3_GPIO_VAL_MAX]; /* 08h */
 } fCONFIG_PAGE_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_3,
   IOUnitPage3_t, MPI_POINTER pIOUnitPage3_t;
 
-#define MPI_IOUNITPAGE3_PAGEVERSION                     (0x00)
+#define MPI_IOUNITPAGE3_PAGEVERSION                     (0x01)
 
+#define MPI_IOUNITPAGE3_GPIO_FUNCTION_MASK              (0xFC)
+#define MPI_IOUNITPAGE3_GPIO_FUNCTION_SHIFT             (2)
+#define MPI_IOUNITPAGE3_GPIO_SETTING_OFF                (0x00)
+#define MPI_IOUNITPAGE3_GPIO_SETTING_ON                 (0x01)
 
-/****************************************************************************/
-/*  IOC Config Pages                                                        */
-/****************************************************************************/
+
+/****************************************************************************
+*   IOC Config Pages
+****************************************************************************/
 
 typedef struct _CONFIG_PAGE_IOC_0
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     TotalNVStore;               /* 04h */
     U32                     FreeNVStore;                /* 08h */
     U16                     VendorID;                   /* 0Ch */
@@ -393,7 +477,7 @@
 
 typedef struct _CONFIG_PAGE_IOC_1
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
     U32                     CoalescingTimeout;          /* 08h */
     U8                      CoalescingDepth;            /* 0Ch */
@@ -408,53 +492,120 @@
 
 typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
 {
-    U8                      VolumeTargetID;             /* 00h */
-    U8                      VolumeBus;                  /* 01h */
-    U16                     Reserved;                   /* 02h */
-    U8                      VolumeVersionMinor;         /* 04h */
-    U8                      VolumeVersionMajor;         /* 05h */
-    U8                      VolumeRaidType;             /* 06h */
-    U8                      Reserved1;                  /* 07h */
+    U8                          VolumeID;               /* 00h */
+    U8                          VolumeBus;              /* 01h */
+    U8                          VolumeIOC;              /* 02h */
+    U8                          VolumePageNumber;       /* 03h */
+    U8                          VolumeType;             /* 04h */
+    U8                          Reserved2;              /* 05h */
+    U16                         Reserved3;              /* 06h */
 } fCONFIG_PAGE_IOC_2_RAID_VOL, MPI_POINTER PTR_CONFIG_PAGE_IOC_2_RAID_VOL,
   ConfigPageIoc2RaidVol_t, MPI_POINTER pConfigPageIoc2RaidVol_t;
 
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_IOC_PAGE_2_RAID_VOLUME_MAX
+#define MPI_IOC_PAGE_2_RAID_VOLUME_MAX      (1)
+#endif
+
 typedef struct _CONFIG_PAGE_IOC_2
 {
-   fCONFIG_PAGE_HEADER          Header;                 /* 00h */
-    U32                         CapabilitiesFlags;      /* 04h */
-    U8                          NumActiveVolumes;       /* 08h */
-    U8                          MaxVolumes;             /* 09h */
-    U16                         Reserved;               /* 0Ah */
-   fCONFIG_PAGE_IOC_2_RAID_VOL  RaidVolume[1];          /* 0Ch */
+    fCONFIG_PAGE_HEADER          Header;                              /* 00h */
+    U32                         CapabilitiesFlags;                   /* 04h */
+    U8                          NumActiveVolumes;                    /* 08h */
+    U8                          MaxVolumes;                          /* 09h */
+    U8                          NumActivePhysDisks;                  /* 0Ah */
+    U8                          MaxPhysDisks;                        /* 0Bh */
+    fCONFIG_PAGE_IOC_2_RAID_VOL  RaidVolume[MPI_IOC_PAGE_2_RAID_VOLUME_MAX];/* 0Ch */
 } fCONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
   IOCPage2_t, MPI_POINTER pIOCPage2_t;
 
-#define MPI_IOCPAGE2_PAGEVERSION                        (0x00)
+#define MPI_IOCPAGE2_PAGEVERSION                        (0x01)
 
 /* IOC Page 2 Capabilities flags */
 
-#define MPI_IOCPAGE2_CAP_FLAGS_RAID_0_SUPPORT           (0x00000001)
-#define MPI_IOCPAGE2_CAP_FLAGS_RAID_1_SUPPORT           (0x00000002)
-#define MPI_IOCPAGE2_CAP_FLAGS_LSI_MIRROR_SUPPORT       (0x00000004)
-#define MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT           (0x00000008)
-#define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT          (0x00000010)
-
-/* IOC Page 2 Volume RAID Type values */
-
-#define MPI_IOCPAGE2_VOL_TYPE_RAID_0                    (0x00)
-#define MPI_IOCPAGE2_VOL_TYPE_RAID_1                    (0x01)
-#define MPI_IOCPAGE2_VOL_TYPE_LSI_MIRROR                (0x02)
-#define MPI_IOCPAGE2_VOL_TYPE_RAID_5                    (0x05)
-#define MPI_IOCPAGE2_VOL_TYPE_RAID_10                   (0x0A)
-
-
-/****************************************************************************/
-/*  SCSI Port Config Pages                                                  */
-/****************************************************************************/
+#define MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT               (0x00000001)
+#define MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT              (0x00000002)
+#define MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT               (0x00000004)
+#define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT              (0x20000000)
+#define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT            (0x40000000)
+#define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT    (0x80000000)
+
+/* IOC Page 2 Volume RAID Type values, also used in RAID Volume pages */
+
+#define MPI_RAID_VOL_TYPE_IS                        (0x00)
+#define MPI_RAID_VOL_TYPE_IME                       (0x01)
+#define MPI_RAID_VOL_TYPE_IM                        (0x02)
+
+
+typedef struct _IOC_3_PHYS_DISK
+{
+    U8                          PhysDiskID;             /* 00h */
+    U8                          PhysDiskBus;            /* 01h */
+    U8                          PhysDiskIOC;            /* 02h */
+    U8                          PhysDiskNum;            /* 03h */
+} IOC_3_PHYS_DISK, MPI_POINTER PTR_IOC_3_PHYS_DISK,
+  Ioc3PhysDisk_t, MPI_POINTER pIoc3PhysDisk_t;
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_IOC_PAGE_3_PHYSDISK_MAX
+#define MPI_IOC_PAGE_3_PHYSDISK_MAX         (1)
+#endif
+
+typedef struct _CONFIG_PAGE_IOC_3
+{
+    fCONFIG_PAGE_HEADER          Header;                                /* 00h */
+    U8                          NumPhysDisks;                          /* 04h */
+    U8                          Reserved1;                             /* 05h */
+    U16                         Reserved2;                             /* 06h */
+    IOC_3_PHYS_DISK             PhysDisk[MPI_IOC_PAGE_3_PHYSDISK_MAX]; /* 08h */
+} fCONFIG_PAGE_IOC_3, MPI_POINTER PTR_CONFIG_PAGE_IOC_3,
+  IOCPage3_t, MPI_POINTER pIOCPage3_t;
+
+#define MPI_IOCPAGE3_PAGEVERSION                        (0x00)
+
+
+typedef struct _IOC_4_SEP
+{
+    U8                          SEPTargetID;            /* 00h */
+    U8                          SEPBus;                 /* 01h */
+    U16                         Reserved;               /* 02h */
+} IOC_4_SEP, MPI_POINTER PTR_IOC_4_SEP,
+  Ioc4Sep_t, MPI_POINTER pIoc4Sep_t;
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_IOC_PAGE_4_SEP_MAX
+#define MPI_IOC_PAGE_4_SEP_MAX              (1)
+#endif
+
+typedef struct _CONFIG_PAGE_IOC_4
+{
+    fCONFIG_PAGE_HEADER          Header;                         /* 00h */
+    U8                          ActiveSEP;                      /* 04h */
+    U8                          MaxSEP;                         /* 05h */
+    U16                         Reserved1;                      /* 06h */
+    IOC_4_SEP                   SEP[MPI_IOC_PAGE_4_SEP_MAX];    /* 08h */
+} fCONFIG_PAGE_IOC_4, MPI_POINTER PTR_CONFIG_PAGE_IOC_4,
+  IOCPage4_t, MPI_POINTER pIOCPage4_t;
+
+#define MPI_IOCPAGE4_PAGEVERSION                        (0x00)
+
+
+/****************************************************************************
+*   SCSI Port Config Pages
+****************************************************************************/
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_0
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Capabilities;               /* 04h */
     U32                     PhysicalInterface;          /* 08h */
 } fCONFIG_PAGE_SCSI_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_0,
@@ -465,7 +616,6 @@
 #define MPI_SCSIPORTPAGE0_CAP_IU                        (0x00000001)
 #define MPI_SCSIPORTPAGE0_CAP_DT                        (0x00000002)
 #define MPI_SCSIPORTPAGE0_CAP_QAS                       (0x00000004)
-#define MPI_SCSIPORTPAGE0_CAP_PACING_TRANSFERS          (0x00000008)
 #define MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK      (0x0000FF00)
 #define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK      (0x00FF0000)
 #define MPI_SCSIPORTPAGE0_CAP_WIDE                      (0x20000000)
@@ -479,12 +629,13 @@
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_1
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Configuration;              /* 04h */
+    U32                     OnBusTimerValue;            /* 08h */
 } fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
   SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t;
 
-#define MPI_SCSIPORTPAGE1_PAGEVERSION                   (0x01)
+#define MPI_SCSIPORTPAGE1_PAGEVERSION                   (0x02)
 
 #define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK         (0x000000FF)
 #define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK     (0xFFFF0000)
@@ -500,7 +651,7 @@
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_2
 {
-   fCONFIG_PAGE_HEADER  Header;                         /* 00h */
+    fCONFIG_PAGE_HEADER  Header;                         /* 00h */
     U32                 PortFlags;                      /* 04h */
     U32                 PortSettings;                   /* 08h */
     MPI_DEVICE_INFO     DeviceSettings[16];             /* 0Ch */
@@ -510,7 +661,6 @@
 #define MPI_SCSIPORTPAGE2_PAGEVERSION                       (0x01)
 
 #define MPI_SCSIPORTPAGE2_PORT_FLAGS_SCAN_HIGH_TO_LOW       (0x00000001)
-#define MPI_SCSIPORTPAGE2_PORT_FLAGS_PARITY_ENABLE          (0x00000002)
 #define MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET       (0x00000004)
 #define MPI_SCSIPORTPAGE2_PORT_FLAGS_ALTERNATE_CHS          (0x00000008)
 #define MPI_SCSIPORTPAGE2_PORT_FLAGS_TERMINATION_DISABLE    (0x00000010)
@@ -536,47 +686,48 @@
 #define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE                (0x0020)
 
 
-/****************************************************************************/
-/*  SCSI Target Device Config Pages                                         */
-/****************************************************************************/
+/****************************************************************************
+*   SCSI Target Device Config Pages
+****************************************************************************/
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     NegotiatedParameters;       /* 04h */
     U32                     Information;                /* 08h */
 } fCONFIG_PAGE_SCSI_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_0,
   SCSIDevicePage0_t, MPI_POINTER pSCSIDevicePage0_t;
 
-#define MPI_SCSIDEVPAGE0_PAGEVERSION                    (0x01)
+#define MPI_SCSIDEVPAGE0_PAGEVERSION                    (0x02)
 
 #define MPI_SCSIDEVPAGE0_NP_IU                          (0x00000001)
 #define MPI_SCSIDEVPAGE0_NP_DT                          (0x00000002)
 #define MPI_SCSIDEVPAGE0_NP_QAS                         (0x00000004)
-#define MPI_SCSIDEVPAGE0_NP_PACING_TRANSFERS            (0x00000008)
 #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK        (0x0000FF00)
 #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK        (0x00FF0000)
 #define MPI_SCSIDEVPAGE0_NP_WIDE                        (0x20000000)
 #define MPI_SCSIDEVPAGE0_NP_AIP                         (0x80000000)
 
 #define MPI_SCSIDEVPAGE0_INFO_PARAMS_NEGOTIATED         (0x00000001)
+#define MPI_SCSIDEVPAGE0_INFO_SDTR_REJECTED             (0x00000002)
+#define MPI_SCSIDEVPAGE0_INFO_WDTR_REJECTED             (0x00000004)
+#define MPI_SCSIDEVPAGE0_INFO_PPR_REJECTED              (0x00000008)
 
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     RequestedParameters;        /* 04h */
     U32                     Reserved;                   /* 08h */
     U32                     Configuration;              /* 0Ch */
 } fCONFIG_PAGE_SCSI_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_1,
   SCSIDevicePage1_t, MPI_POINTER pSCSIDevicePage1_t;
 
-#define MPI_SCSIDEVPAGE1_PAGEVERSION                    (0x02)
+#define MPI_SCSIDEVPAGE1_PAGEVERSION                    (0x03)
 
 #define MPI_SCSIDEVPAGE1_RP_IU                          (0x00000001)
 #define MPI_SCSIDEVPAGE1_RP_DT                          (0x00000002)
 #define MPI_SCSIDEVPAGE1_RP_QAS                         (0x00000004)
-#define MPI_SCSIDEVPAGE1_RP_PACING_TRANSFERS            (0x00000008)
 #define MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK        (0x0000FF00)
 #define MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK        (0x00FF0000)
 #define MPI_SCSIDEVPAGE1_RP_WIDE                        (0x20000000)
@@ -585,12 +736,13 @@
 #define MPI_SCSIDEVPAGE1_DV_LVD_DRIVE_STRENGTH_MASK     (0x00000003)
 #define MPI_SCSIDEVPAGE1_DV_SE_SLEW_RATE_MASK           (0x00000300)
 
-#define MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED               (0x00000001)
+#define MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED           (0x00000002)
+#define MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED           (0x00000004)
 
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_2
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     DomainValidation;           /* 04h */
     U32                     ParityPipeSelect;           /* 08h */
     U32                     DataPipeSelect;             /* 0Ch */
@@ -629,13 +781,13 @@
 #define MPI_SCSIDEVPAGE2_DPS_BIT_15_PL_SELECT_MASK      (0xC0000000)
 
 
-/****************************************************************************/
-/*  FC Port Config Pages                                                    */
-/****************************************************************************/
+/****************************************************************************
+*   FC Port Config Pages
+****************************************************************************/
 
 typedef struct _CONFIG_PAGE_FC_PORT_0
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
     U8                      MPIPortNumber;              /* 08h */
     U8                      LinkType;                   /* 09h */
@@ -715,7 +867,7 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_1
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
     U64                     NoSEEPROMWWNN;              /* 08h */
     U64                     NoSEEPROMWWPN;              /* 10h */
@@ -726,8 +878,10 @@
 } fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
   FCPortPage1_t, MPI_POINTER pFCPortPage1_t;
 
-#define MPI_FCPORTPAGE1_PAGEVERSION                     (0x01)
+#define MPI_FCPORTPAGE1_PAGEVERSION                     (0x02)
 
+#define MPI_FCPORTPAGE1_FLAGS_EXT_FCP_STATUS_EN         (0x08000000)
+#define MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY     (0x04000000)
 #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_DID               (0x00000001)
 #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_WWN               (0x00000000)
 
@@ -747,22 +901,21 @@
 #define MPI_FCPORTPAGE1_LCONFIG_SPEED_10GIG             (0x03)
 #define MPI_FCPORTPAGE1_LCONFIG_SPEED_AUTO              (0x0F)
 
-#define MPI_FCPORTPAGE1_TOPOLGY_MASK                    (0x0F)
-#define MPI_FCPORTPAGE1_TOPOLGY_NLPORT                  (0x01)
-#define MPI_FCPORTPAGE1_TOPOLGY_NPORT                   (0x02)
-#define MPI_FCPORTPAGE1_TOPOLGY_AUTO                    (0x0F)
+#define MPI_FCPORTPAGE1_TOPOLOGY_MASK                   (0x0F)
+#define MPI_FCPORTPAGE1_TOPOLOGY_NLPORT                 (0x01)
+#define MPI_FCPORTPAGE1_TOPOLOGY_NPORT                  (0x02)
+#define MPI_FCPORTPAGE1_TOPOLOGY_AUTO                   (0x0F)
 
 
 typedef struct _CONFIG_PAGE_FC_PORT_2
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U8                      NumberActive;               /* 04h */
-    U8                      ALPA[126];                  /* 05h */
-    U8                      Reserved;                   /* 83h */
+    U8                      ALPA[127];                  /* 05h */
 } fCONFIG_PAGE_FC_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_2,
   FCPortPage2_t, MPI_POINTER pFCPortPage2_t;
 
-#define MPI_FCPORTPAGE2_PAGEVERSION                     (0x00)
+#define MPI_FCPORTPAGE2_PAGEVERSION                     (0x01)
 
 
 typedef struct _WWN_FORMAT
@@ -795,10 +948,18 @@
 #define MPI_PERSISTENT_FLAGS_BOOT_DEVICE                (0x0008)
 #define MPI_PERSISTENT_FLAGS_BY_DID                     (0x0080)
 
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_FC_PORT_PAGE_3_ENTRY_MAX
+#define MPI_FC_PORT_PAGE_3_ENTRY_MAX        (1)
+#endif
+
 typedef struct _CONFIG_PAGE_FC_PORT_3
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
-    FC_PORT_PERSISTENT      Entry[1];                   /* 04h */
+    fCONFIG_PAGE_HEADER      Header;                                 /* 00h */
+    FC_PORT_PERSISTENT      Entry[MPI_FC_PORT_PAGE_3_ENTRY_MAX];    /* 04h */
 } fCONFIG_PAGE_FC_PORT_3, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_3,
   FCPortPage3_t, MPI_POINTER pFCPortPage3_t;
 
@@ -807,7 +968,7 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_4
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     PortFlags;                  /* 04h */
     U32                     PortSettings;               /* 08h */
 } fCONFIG_PAGE_FC_PORT_4, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_4,
@@ -833,13 +994,22 @@
     U16     Reserved;                                   /* 02h */
     U64     AliasWWNN;                                  /* 04h */
     U64     AliasWWPN;                                  /* 0Ch */
-} fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
+} fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
+  MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
   FcPortPage5AliasInfo_t, MPI_POINTER pFcPortPage5AliasInfo_t;
 
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_FC_PORT_PAGE_5_ALIAS_MAX
+#define MPI_FC_PORT_PAGE_5_ALIAS_MAX        (1)
+#endif
+
 typedef struct _CONFIG_PAGE_FC_PORT_5
 {
-   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
-   fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO    AliasInfo[1];   /* 04h */
+    fCONFIG_PAGE_HEADER                  Header;                     /* 00h */
+    fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO    AliasInfo[MPI_FC_PORT_PAGE_5_ALIAS_MAX];/* 04h */
 } fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
   FCPortPage5_t, MPI_POINTER pFCPortPage5_t;
 
@@ -851,7 +1021,7 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_6
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Reserved;                   /* 04h */
     U64                     TimeSinceReset;             /* 08h */
     U64                     TxFrames;                   /* 10h */
@@ -877,7 +1047,7 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_7
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Reserved;                   /* 04h */
     U8                      PortSymbolicName[256];      /* 08h */
 } fCONFIG_PAGE_FC_PORT_7, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_7,
@@ -888,7 +1058,7 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_8
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     BitVector[8];               /* 04h */
 } fCONFIG_PAGE_FC_PORT_8, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_8,
   FCPortPage8_t, MPI_POINTER pFCPortPage8_t;
@@ -898,7 +1068,7 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_9
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Reserved;                   /* 04h */
     U64                     GlobalWWPN;                 /* 08h */
     U64                     GlobalWWNN;                 /* 10h */
@@ -916,13 +1086,13 @@
 #define MPI_FCPORTPAGE9_PAGEVERSION                     (0x00)
 
 
-/****************************************************************************/
-/*  FC Device Config Pages                                                  */
-/****************************************************************************/
+/****************************************************************************
+*   FC Device Config Pages
+****************************************************************************/
 
 typedef struct _CONFIG_PAGE_FC_DEVICE_0
 {
-   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U64                     WWNN;                       /* 04h */
     U64                     WWPN;                       /* 0Ch */
     U32                     PortIdentifier;             /* 14h */
@@ -947,112 +1117,191 @@
 #define MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET             (0x02)
 #define MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR          (0x04)
 
-#define MPI_FC_DEVICE_PAGE0_PGAD_PORT_MASK              (MPI_FC_DEVICE_PGAD_PORT_MASK)
-#define MPI_FC_DEVICE_PAGE0_PGAD_FORM_MASK              (MPI_FC_DEVICE_PGAD_FORM_MASK)
-#define MPI_FC_DEVICE_PAGE0_PGAD_FORM_NEXT_DID          (MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
-#define MPI_FC_DEVICE_PAGE0_PGAD_FORM_BUS_TID           (MPI_FC_DEVICE_PGAD_FORM_BUS_TID)
-#define MPI_FC_DEVICE_PAGE0_PGAD_DID_MASK               (MPI_FC_DEVICE_PGAD_ND_DID_MASK)
-#define MPI_FC_DEVICE_PAGE0_PGAD_BUS_MASK               (MPI_FC_DEVICE_PGAD_BT_BUS_MASK)
-#define MPI_FC_DEVICE_PAGE0_PGAD_BUS_SHIFT              (MPI_FC_DEVICE_PGAD_BT_BUS_SHIFT)
-#define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK               (MPI_FC_DEVICE_PGAD_BT_TID_MASK)
-
-
-/****************************************************************************/
-/*  RAID Volume Config Pages                                                  */
-/****************************************************************************/
-
-typedef struct _RAIDVOL2_IM_PHYS_ID
-{
-    U8                      TargetID;                   /* 00h */
-    U8                      Bus;                        /* 01h */
-    U8                      IocNumber;                  /* 02h */
-    U8                      PhysDiskNumber;             /* 03h */
-    U8                      Reserved[8];                /* 04h */
-    U8                      PhysicalDiskIdentifier[16]; /* 0Ch */
-    U8                      VendorId[8];                /* 1Ch */
-    U8                      ProductId[16];              /* 24h */
-    U8                      ProductRevLevel[4];         /* 34h */
-    U32                     Reserved1;                  /* 38h */
-    U8                      Info[32];                   /* 3Ch */
-} RAIDVOL2_IM_PHYS_ID, MPI_POINTER PTR_RAIDVOL2_IM_PHYS_ID,
-  RaidVol2ImPhysicalID_t, MPI_POINTER pRaidVol2ImPhysicalID_t;
-
-typedef struct _RAIDVOL2_IM_DISK_INFO
-{
-    U32                     DiskStatus;                 /* 00h */
-    U32                     DeviceSettings;             /* 04h */
-    U16                     ErrorCount;                 /* 08h */
-    U16                     Reserved;                   /* 0Ah */
-    U8                      ErrorCdbByte;               /* 0Ch */
-    U8                      ErrorSenseKey;              /* 0Dh */
-    U8                      ErrorASC;                   /* 0Eh */
-    U8                      ErrorASCQ;                  /* 0Fh */
-    U16                     SmartCount;                 /* 10h */
-    U8                      SmartASC;                   /* 12h */
-    U8                      SmartASCQ;                  /* 13h */
-} RAIDVOL2_IM_DISK_INFO, MPI_POINTER PTR_RAIDVOL2_IM_DISK_INFO,
-  RaidVol2ImDiskInfo_t, MPI_POINTER pRaidVol2ImDiskInfo_t;
+#define MPI_FC_DEVICE_PAGE0_PGAD_PORT_MASK      (MPI_FC_DEVICE_PGAD_PORT_MASK)
+#define MPI_FC_DEVICE_PAGE0_PGAD_FORM_MASK      (MPI_FC_DEVICE_PGAD_FORM_MASK)
+#define MPI_FC_DEVICE_PAGE0_PGAD_FORM_NEXT_DID  (MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
+#define MPI_FC_DEVICE_PAGE0_PGAD_FORM_BUS_TID   (MPI_FC_DEVICE_PGAD_FORM_BUS_TID)
+#define MPI_FC_DEVICE_PAGE0_PGAD_DID_MASK       (MPI_FC_DEVICE_PGAD_ND_DID_MASK)
+#define MPI_FC_DEVICE_PAGE0_PGAD_BUS_MASK       (MPI_FC_DEVICE_PGAD_BT_BUS_MASK)
+#define MPI_FC_DEVICE_PAGE0_PGAD_BUS_SHIFT      (MPI_FC_DEVICE_PGAD_BT_BUS_SHIFT)
+#define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK       (MPI_FC_DEVICE_PGAD_BT_TID_MASK)
+
+
+/****************************************************************************
+*   RAID Volume Config Pages
+****************************************************************************/
+
+typedef struct _RAID_VOL0_PHYS_DISK
+{
+    U16                         Reserved;               /* 00h */
+    U8                          PhysDiskMap;            /* 02h */
+    U8                          PhysDiskNum;            /* 03h */
+} RAID_VOL0_PHYS_DISK, MPI_POINTER PTR_RAID_VOL0_PHYS_DISK,
+  RaidVol0PhysDisk_t, MPI_POINTER pRaidVol0PhysDisk_t;
+
+#define MPI_RAIDVOL0_PHYSDISK_PRIMARY                   (0x01)
+#define MPI_RAIDVOL0_PHYSDISK_SECONDARY                 (0x02)
+
+typedef struct _RAID_VOL0_STATUS
+{
+    U8                          Flags;                  /* 00h */
+    U8                          State;                  /* 01h */
+    U16                         Reserved;               /* 02h */
+} RAID_VOL0_STATUS, MPI_POINTER PTR_RAID_VOL0_STATUS,
+  RaidVol0Status_t, MPI_POINTER pRaidVol0Status_t;
+
+/* RAID Volume Page 0 VolumeStatus defines */
+
+#define MPI_RAIDVOL0_STATUS_FLAG_ENABLED                (0x01)
+#define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED               (0x02)
+#define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS     (0x04)
+
+#define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL               (0x00)
+#define MPI_RAIDVOL0_STATUS_STATE_DEGRADED              (0x01)
+#define MPI_RAIDVOL0_STATUS_STATE_FAILED                (0x02)
+
+typedef struct _RAID_VOL0_SETTINGS
+{
+    U16                         Settings;       /* 00h */
+    U8                          HotSparePool;   /* 01h */ /* MPI_RAID_HOT_SPARE_POOL_ */
+    U8                          Reserved;       /* 02h */
+} RAID_VOL0_SETTINGS, MPI_POINTER PTR_RAID_VOL0_SETTINGS,
+  RaidVol0Settings, MPI_POINTER pRaidVol0Settings;
+
+/* RAID Volume Page 0 VolumeSettings defines */
+
+#define MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE       (0x0001)
+#define MPI_RAIDVOL0_SETTING_OFFLINE_ON_SMART           (0x0002)
+#define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE             (0x0004)
+#define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC            (0x0008)
+#define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX      (0x0010)
+#define MPI_RAIDVOL0_SETTING_USE_DEFAULTS               (0x8000)
+
+/* RAID Volume Page 0 HotSparePool defines, also used in RAID Physical Disk */
+#define MPI_RAID_HOT_SPARE_POOL_0                       (0x01)
+#define MPI_RAID_HOT_SPARE_POOL_1                       (0x02)
+#define MPI_RAID_HOT_SPARE_POOL_2                       (0x04)
+#define MPI_RAID_HOT_SPARE_POOL_3                       (0x08)
+#define MPI_RAID_HOT_SPARE_POOL_4                       (0x10)
+#define MPI_RAID_HOT_SPARE_POOL_5                       (0x20)
+#define MPI_RAID_HOT_SPARE_POOL_6                       (0x40)
+#define MPI_RAID_HOT_SPARE_POOL_7                       (0x80)
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX
+#define MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX        (1)
+#endif
+
+typedef struct _CONFIG_PAGE_RAID_VOL_0
+{
+    fCONFIG_PAGE_HEADER      Header;         /* 00h */
+    U8                      VolumeID;       /* 04h */
+    U8                      VolumeBus;      /* 05h */
+    U8                      VolumeIOC;      /* 06h */
+    U8                      VolumeType;     /* 07h */ /* MPI_RAID_VOL_TYPE_ */
+    RAID_VOL0_STATUS        VolumeStatus;   /* 08h */
+    RAID_VOL0_SETTINGS      VolumeSettings; /* 0Ch */
+    U32                     MaxLBA;         /* 10h */
+    U32                     Reserved1;      /* 14h */
+    U32                     StripeSize;     /* 18h */
+    U32                     Reserved2;      /* 1Ch */
+    U32                     Reserved3;      /* 20h */
+    U8                      NumPhysDisks;   /* 24h */
+    U8                      Reserved4;      /* 25h */
+    U16                     Reserved5;      /* 26h */
+    RAID_VOL0_PHYS_DISK     PhysDisk[MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX];/* 28h */
+} fCONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
+  RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
+
+#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x00)
+
+
+/****************************************************************************
+*   RAID Physical Disk Config Pages
+****************************************************************************/
+
+typedef struct _RAID_PHYS_DISK0_ERROR_DATA
+{
+    U8                      ErrorCdbByte;               /* 00h */
+    U8                      ErrorSenseKey;              /* 01h */
+    U16                     Reserved;                   /* 02h */
+    U16                     ErrorCount;                 /* 04h */
+    U8                      ErrorASC;                   /* 06h */
+    U8                      ErrorASCQ;                  /* 07h */
+    U16                     SmartCount;                 /* 08h */
+    U8                      SmartASC;                   /* 0Ah */
+    U8                      SmartASCQ;                  /* 0Bh */
+} RAID_PHYS_DISK0_ERROR_DATA, MPI_POINTER PTR_RAID_PHYS_DISK0_ERROR_DATA,
+  RaidPhysDisk0ErrorData_t, MPI_POINTER pRaidPhysDisk0ErrorData_t;
+
+typedef struct _RAID_PHYS_DISK_INQUIRY_DATA
+{
+    U8                          VendorID[8];            /* 00h */
+    U8                          ProductID[16];          /* 08h */
+    U8                          ProductRevLevel[4];     /* 18h */
+    U8                          Info[32];               /* 1Ch */
+} RAID_PHYS_DISK0_INQUIRY_DATA, MPI_POINTER PTR_RAID_PHYS_DISK0_INQUIRY_DATA,
+  RaidPhysDisk0InquiryData, MPI_POINTER pRaidPhysDisk0InquiryData;
+
+typedef struct _RAID_PHYS_DISK0_SETTINGS
+{
+    U8              SepID;              /* 00h */
+    U8              SepBus;             /* 01h */
+    U8              HotSparePool;       /* 02h */ /* MPI_RAID_HOT_SPARE_POOL_ */
+    U8              PhysDiskSettings;   /* 03h */
+} RAID_PHYS_DISK0_SETTINGS, MPI_POINTER PTR_RAID_PHYS_DISK0_SETTINGS,
+  RaidPhysDiskSettings_t, MPI_POINTER pRaidPhysDiskSettings_t;
+
+typedef struct _RAID_PHYS_DISK0_STATUS
+{
+    U8                              Flags;              /* 00h */
+    U8                              State;              /* 01h */
+    U16                             Reserved;           /* 02h */
+} RAID_PHYS_DISK0_STATUS, MPI_POINTER PTR_RAID_PHYS_DISK0_STATUS,
+  RaidPhysDiskStatus_t, MPI_POINTER pRaidPhysDiskStatus_t;
 
 /* RAID Volume 2 IM Physical Disk DiskStatus flags */
 
-#define MPI_RVP2_PHYS_DISK_PRIMARY                      (0x00000001)
-#define MPI_RVP2_PHYS_DISK_SECONDARY                    (0x00000002)
-#define MPI_RVP2_PHYS_DISK_HOT_SPARE                    (0x00000004)
-#define MPI_RVP2_PHYS_DISK_OUT_OF_SYNC                  (0x00000008)
-#define MPI_RVP2_PHYS_DISK_STATUS_MASK                  (0x00000F00)
-#define MPI_RVP2_PHYS_DISK_STATUS_ONLINE                (0x00000000)
-#define MPI_RVP2_PHYS_DISK_STATUS_MISSING               (0x00000100)
-#define MPI_RVP2_PHYS_DISK_STATUS_NOT_COMPATIBLE        (0x00000200)
-#define MPI_RVP2_PHYS_DISK_STATUS_FAILED                (0x00000300)
-#define MPI_RVP2_PHYS_DISK_STATUS_INITIALIZING          (0x00000400)
-#define MPI_RVP2_PHYS_DISK_STATUS_OFFLINE_REQUESTED     (0x00000500)
-#define MPI_RVP2_PHYS_DISK_STATUS_OTHER_OFFLINE         (0x00000F00)
-
-
-typedef struct _RAIDVOL2_IM_PHYSICAL_DISK
-{
-    RAIDVOL2_IM_PHYS_ID     Id;                         /* 00h */
-    RAIDVOL2_IM_DISK_INFO   Info;                       /* 5Ch */
-} RAIDVOL2_IM_PHYSICAL_DISK, MPI_POINTER PTR_RAIDVOL2_IM_PHYSICAL_DISK,
-  RaidVol2ImPhysicalDisk_t, MPI_POINTER pRaidVol2ImPhysicalDisk_t;
-
-#define MPI_RAIDVOLPAGE2_MAX_DISKS                      (3)
-
-typedef struct _CONFIG_PAGE_RAID_VOL_2
-{
-   fCONFIG_PAGE_HEADER          Header;                 /* 00h */
-    U32                         VolumeStatus;           /* 04h */
-    U32                         VolumeSettings;         /* 08h */
-    U32                         Reserved;               /* 0Ch */
-    U64                         MaxLba;                 /* 10h */
-    U32                         BlockSize;              /* 18h */
-    U8                          Reserved1;              /* 1Ch */
-    U8                          NumPhysicalDisks;       /* 1Dh */
-    U16                         Reserved2;              /* 1Eh */
-    RAIDVOL2_IM_PHYSICAL_DISK   IMPhysicalDisk[MPI_RAIDVOLPAGE2_MAX_DISKS];
-} fCONFIG_PAGE_RAID_VOL_2, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_2,
-  RaidVolumePage2_t, MPI_POINTER pRaidVolumePage2_t;
-
-#define MPI_RAIDVOLPAGE2_PAGEVERSION                    (0x00)
-
-/* RAID Volume Page 2 VolumeStatus defines */
-
-#define MPI_RAIDVOLPAGE2_STATUS_ENABLED                 (0x00000001)
-#define MPI_RAIDVOLPAGE2_STATUS_QUIESCED                (0x00000002)
-#define MPI_RAIDVOLPAGE2_STATUS_RESYNC_IN_PROGRESS      (0x00000004)
-#define MPI_RAIDVOLPAGE2_STATUS_DEGRADED                (0x00000008)
-
-/* RAID Volume Page 2 VolumeSettings defines */
-
-#define MPI_RAIDVOLPAGE2_SETTING_WRITE_CACHING_ENABLE   (0x00000001)
-#define MPI_RAIDVOLPAGE2_SETTING_OFFLINE_ON_SMART       (0x00000002)
-#define MPI_RAIDVOLPAGE2_SETTING_AUTO_CONFIGURE         (0x00000004)
-#define MPI_RAIDVOLPAGE2_SETTING_USE_DEFAULTS           (0x80000000)
-
-
-/****************************************************************************/
-/* LAN Config Pages                                                         */
-/****************************************************************************/
+#define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC           (0x01)
+#define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED              (0x02)
+
+#define MPI_PHYSDISK0_STATUS_ONLINE                     (0x00)
+#define MPI_PHYSDISK0_STATUS_MISSING                    (0x01)
+#define MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE             (0x02)
+#define MPI_PHYSDISK0_STATUS_FAILED                     (0x03)
+#define MPI_PHYSDISK0_STATUS_INITIALIZING               (0x04)
+#define MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED          (0x05)
+#define MPI_PHYSDISK0_STATUS_FAILED_REQUESTED           (0x06)
+#define MPI_PHYSDISK0_STATUS_OTHER_OFFLINE              (0xFF)
+
+typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_0
+{
+    fCONFIG_PAGE_HEADER              Header;             /* 00h */
+    U8                              PhysDiskID;         /* 04h */
+    U8                              PhysDiskBus;        /* 05h */
+    U8                              PhysDiskIOC;        /* 06h */
+    U8                              PhysDiskNum;        /* 07h */
+    RAID_PHYS_DISK0_SETTINGS        PhysDiskSettings;   /* 08h */
+    U32                             Reserved1;          /* 0Ch */
+    U32                             Reserved2;          /* 10h */
+    U32                             Reserved3;          /* 14h */
+    U8                              DiskIdentifier[16]; /* 18h */
+    RAID_PHYS_DISK0_INQUIRY_DATA    InquiryData;        /* 28h */
+    RAID_PHYS_DISK0_STATUS          PhysDiskStatus;     /* 64h */
+    U32                             MaxLBA;             /* 68h */
+    RAID_PHYS_DISK0_ERROR_DATA      ErrorData;          /* 6Ch */
+} fCONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0,
+  RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t;
+
+#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION           (0x00)
+
+
+/****************************************************************************
+*   LAN Config Pages
+****************************************************************************/
 
 typedef struct _CONFIG_PAGE_LAN_0
 {
@@ -1083,8 +1332,8 @@
     U32                     MaxWireSpeedHigh;           /* 1Ch */
     U32                     BucketsRemaining;           /* 20h */
     U32                     MaxReplySize;               /* 24h */
-    U32                     NegWireSpeedHigh;           /* 28h */
-    U32                     NegWireSpeedLow;            /* 2Ch */
+    U32                     NegWireSpeedLow;            /* 28h */
+    U32                     NegWireSpeedHigh;           /* 2Ch */
 } fCONFIG_PAGE_LAN_1, MPI_POINTER PTR_CONFIG_PAGE_LAN_1,
   LANPage1_t, MPI_POINTER pLANPage1_t;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_fc.h linux/drivers/message/fusion/lsi/mpi_fc.h
--- linux.orig/drivers/message/fusion/lsi/mpi_fc.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_fc.h	2002-07-20 01:08:27.000000000 +0000
@@ -6,7 +6,7 @@
  *          Title:  MPI Fibre Channel messages and structures
  *  Creation Date:  June 12, 2000
  *
- *    MPI Version:  01.01.07
+ *    MPI Version:  01.02.02
  *
  *  Version History
  *  ---------------
@@ -32,6 +32,9 @@
  *                      Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
  *                      Added structure offset comments.
  *  04-09-01  01.01.07  Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  09-28-01  01.02.02  Change name of reserved field in
+ *                      MSG_LINK_SERVICE_RSP_REPLY.
  *  --------------------------------------------------------------------------
  */
 
@@ -172,7 +175,7 @@
     U8                      MsgLength;          /* 02h */
     U8                      Function;           /* 03h */
     U16                     Reserved1;          /* 04h */
-    U8                      Reserved2;          /* 06h */
+    U8                      Reserved_0100_InitiatorIndex; /* 06h */ /* obsolete InitiatorIndex */
     U8                      MsgFlags;           /* 07h */
     U32                     MsgContext;         /* 08h */
     U16                     Reserved3;          /* 0Ch */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_init.h linux/drivers/message/fusion/lsi/mpi_init.h
--- linux.orig/drivers/message/fusion/lsi/mpi_init.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_init.h	2002-07-20 01:08:24.000000000 +0000
@@ -6,7 +6,7 @@
  *          Title:  MPI initiator mode messages and structures
  *  Creation Date:  June 8, 2000
  *
- *    MPI Version:  01.01.05
+ *    MPI Version:  01.02.04
  *
  *  Version History
  *  ---------------
@@ -22,6 +22,13 @@
  *  02-20-01  01.01.03  Started using MPI_POINTER.
  *  03-27-01  01.01.04  Added structure offset comments.
  *  04-10-01  01.01.05  Added new MsgFlag for MSG_SCSI_TASK_MGMT.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  08-29-01  01.02.02  Added MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET.
+ *                      Added MPI_SCSI_STATE_QUEUE_TAG_REJECTED for
+ *                      MSG_SCSI_IO_REPLY.
+ *  09-28-01  01.02.03  Added structures and defines for SCSI Enclosure
+ *                      Processor messages.
+ *  10-04-01  01.02.04  Added defines for SEP request Action field.
  *  --------------------------------------------------------------------------
  */
 
@@ -151,6 +158,7 @@
 #define MPI_SCSI_STATE_NO_SCSI_STATUS           (0x04)
 #define MPI_SCSI_STATE_TERMINATED               (0x08)
 #define MPI_SCSI_STATE_RESPONSE_INFO_VALID      (0x10)
+#define MPI_SCSI_STATE_QUEUE_TAG_REJECTED       (0x20)
 
 /* SCSIIO Reply ResponseInfo values */
 /* (FCP-1 RSP_CODE values and SPI-3 Packetized Failure codes) */
@@ -191,6 +199,7 @@
 #define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET         (0x02)
 #define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET          (0x03)
 #define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS             (0x04)
+#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET    (0x05)
 
 /* MsgFlags bits */
 #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION   (0x00)
@@ -216,4 +225,91 @@
 } MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY,
   SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t;
 
+
+/****************************************************************************/
+/*  SCSI Enclosure Processor messages                                       */
+/****************************************************************************/
+
+typedef struct _MSG_SEP_REQUEST
+{
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Action;             /* 04h */
+    U8                      Reserved1;          /* 05h */
+    U8                      Reserved2;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     SlotStatus;         /* 0Ch */
+} MSG_SEP_REQUEST, MPI_POINTER PTR_MSG_SEP_REQUEST,
+  SEPRequest_t, MPI_POINTER pSEPRequest_t;
+
+/* Action defines */
+#define MPI_SEP_REQ_ACTION_WRITE_STATUS                 (0x00)
+#define MPI_SEP_REQ_ACTION_READ_STATUS                  (0x01)
+
+/* SlotStatus bits for MSG_SEP_REQUEST */
+#define MPI_SEP_REQ_SLOTSTATUS_NO_ERROR                 (0x00000001)
+#define MPI_SEP_REQ_SLOTSTATUS_DEV_FAULTY               (0x00000002)
+#define MPI_SEP_REQ_SLOTSTATUS_DEV_REBUILDING           (0x00000004)
+#define MPI_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY          (0x00000008)
+#define MPI_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY        (0x00000010)
+#define MPI_SEP_REQ_SLOTSTATUS_PARITY_CHECK             (0x00000020)
+#define MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT          (0x00000040)
+#define MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED             (0x00000080)
+#define MPI_SEP_REQ_SLOTSTATUS_HOT_SPARE                (0x00000100)
+#define MPI_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED          (0x00000200)
+#define MPI_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST         (0x00020000)
+#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE           (0x00040000)
+#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_INSERT           (0x00080000)
+#define MPI_SEP_REQ_SLOTSTATUS_DO_NOT_MOVE              (0x00400000)
+#define MPI_SEP_REQ_SLOTSTATUS_B_ENABLE_BYPASS          (0x04000000)
+#define MPI_SEP_REQ_SLOTSTATUS_A_ENABLE_BYPASS          (0x08000000)
+#define MPI_SEP_REQ_SLOTSTATUS_DEV_OFF                  (0x10000000)
+#define MPI_SEP_REQ_SLOTSTATUS_SWAP_RESET               (0x80000000)
+
+
+typedef struct _MSG_SEP_REPLY
+{
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Action;             /* 04h */
+    U8                      Reserved1;          /* 05h */
+    U8                      Reserved2;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved3;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     SlotStatus;         /* 14h */
+} MSG_SEP_REPLY, MPI_POINTER PTR_MSG_SEP_REPLY,
+  SEPReply_t, MPI_POINTER pSEPReply_t;
+
+/* SlotStatus bits for MSG_SEP_REPLY */
+#define MPI_SEP_REPLY_SLOTSTATUS_NO_ERROR               (0x00000001)
+#define MPI_SEP_REPLY_SLOTSTATUS_DEV_FAULTY             (0x00000002)
+#define MPI_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING         (0x00000004)
+#define MPI_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY        (0x00000008)
+#define MPI_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY      (0x00000010)
+#define MPI_SEP_REPLY_SLOTSTATUS_PARITY_CHECK           (0x00000020)
+#define MPI_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT        (0x00000040)
+#define MPI_SEP_REPLY_SLOTSTATUS_UNCONFIGURED           (0x00000080)
+#define MPI_SEP_REPLY_SLOTSTATUS_HOT_SPARE              (0x00000100)
+#define MPI_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED        (0x00000200)
+#define MPI_SEP_REPLY_SLOTSTATUS_REPORT                 (0x00010000)
+#define MPI_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST       (0x00020000)
+#define MPI_SEP_REPLY_SLOTSTATUS_REMOVE_READY           (0x00040000)
+#define MPI_SEP_REPLY_SLOTSTATUS_INSERT_READY           (0x00080000)
+#define MPI_SEP_REPLY_SLOTSTATUS_DO_NOT_REMOVE          (0x00400000)
+#define MPI_SEP_REPLY_SLOTSTATUS_B_BYPASS_ENABLED       (0x01000000)
+#define MPI_SEP_REPLY_SLOTSTATUS_A_BYPASS_ENABLED       (0x02000000)
+#define MPI_SEP_REPLY_SLOTSTATUS_B_ENABLE_BYPASS        (0x04000000)
+#define MPI_SEP_REPLY_SLOTSTATUS_A_ENABLE_BYPASS        (0x08000000)
+#define MPI_SEP_REPLY_SLOTSTATUS_DEV_OFF                (0x10000000)
+#define MPI_SEP_REPLY_SLOTSTATUS_FAULT_SENSED           (0x40000000)
+#define MPI_SEP_REPLY_SLOTSTATUS_SWAPPED                (0x80000000)
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_ioc.h linux/drivers/message/fusion/lsi/mpi_ioc.h
--- linux.orig/drivers/message/fusion/lsi/mpi_ioc.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_ioc.h	2002-07-20 01:08:31.000000000 +0000
@@ -6,7 +6,7 @@
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  August 11, 2000
  *
- *    MPI Version:  01.01.07
+ *    MPI Version:  01.02.04
  *
  *  Version History
  *  ---------------
@@ -38,6 +38,19 @@
  *  03-27-01  01.01.06  Added defines for ProductId field of MPI_FW_HEADER.
  *                      Added structure offset comments.
  *  04-09-01  01.01.07  Added structure EVENT_DATA_EVENT_CHANGE.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *                      New format for FWVersion and ProductId in
+ *                      MSG_IOC_FACTS_REPLY and MPI_FW_HEADER.
+ *  08-31-01  01.02.02  Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and
+ *                      related structure and defines.
+ *                      Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED.
+ *                      Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE.
+ *                      Replaced a reserved field in MSG_IOC_FACTS_REPLY with
+ *                      IOCExceptions and changed DataImageSize to reserved.
+ *                      Added MPI_FW_DOWNLOAD_ITYPE_NVSTORE_DATA and
+ *                      MPI_FW_UPLOAD_ITYPE_NVDATA.
+ *  09-28-01  01.02.03  Modified Event Data for Integrated RAID.
+ *  11-01-01  01.02.04  Added defines for MPI_EXT_IMAGE_HEADER ImageType field.
  *  --------------------------------------------------------------------------
  */
 
@@ -73,6 +86,17 @@
 } MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
   IOCInit_t, MPI_POINTER pIOCInit_t;
 
+/* WhoInit values */
+#define MPI_WHOINIT_NO_ONE                      (0x00)
+#define MPI_WHOINIT_SYSTEM_BIOS                 (0x01)
+#define MPI_WHOINIT_ROM_BIOS                    (0x02)
+#define MPI_WHOINIT_PCI_PEER                    (0x03)
+#define MPI_WHOINIT_HOST_DRIVER                 (0x04)
+#define MPI_WHOINIT_MANUFACTURER                (0x05)
+
+/* Flags values */
+#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE      (0x01)
+
 typedef struct _MSG_IOC_INIT_REPLY
 {
     U8                      WhoInit;                    /* 00h */
@@ -90,14 +114,6 @@
 } MSG_IOC_INIT_REPLY, MPI_POINTER PTR_MSG_IOC_INIT_REPLY,
   IOCInitReply_t, MPI_POINTER pIOCInitReply_t;
 
-/* WhoInit values */
-
-#define MPI_WHOINIT_NO_ONE                      (0x00)
-#define MPI_WHOINIT_SYSTEM_BIOS                 (0x01)
-#define MPI_WHOINIT_ROM_BIOS                    (0x02)
-#define MPI_WHOINIT_PCI_PEER                    (0x03)
-#define MPI_WHOINIT_HOST_DRIVER                 (0x04)
-#define MPI_WHOINIT_MANUFACTURER                (0x05)
 
 
 /****************************************************************************/
@@ -115,8 +131,21 @@
 } MSG_IOC_FACTS, MPI_POINTER PTR_IOC_FACTS,
   IOCFacts_t, MPI_POINTER pIOCFacts_t;
 
-/* IOC Facts Reply */
+typedef struct _MPI_FW_VERSION_STRUCT
+{
+    U8                      Dev;                        /* 00h */
+    U8                      Unit;                       /* 01h */
+    U8                      Minor;                      /* 02h */
+    U8                      Major;                      /* 03h */
+} MPI_FW_VERSION_STRUCT;
+
+typedef union _MPI_FW_VERSION
+{
+    MPI_FW_VERSION_STRUCT   Struct;
+    U32                     Word;
+} MPI_FW_VERSION;
 
+/* IOC Facts Reply */
 typedef struct _MSG_IOC_FACTS_REPLY
 {
     U16                     MsgVersion;                 /* 00h */
@@ -126,7 +155,7 @@
     U8                      IOCNumber;                  /* 06h */
     U8                      MsgFlags;                   /* 07h */
     U32                     MsgContext;                 /* 08h */
-    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCExceptions;              /* 0Ch */
     U16                     IOCStatus;                  /* 0Eh */
     U32                     IOCLogInfo;                 /* 10h */
     U8                      MaxChainDepth;              /* 14h */
@@ -135,7 +164,7 @@
     U8                      Flags;                      /* 17h */
     U16                     ReplyQueueDepth;            /* 18h */
     U16                     RequestFrameSize;           /* 1Ah */
-    U16                     FWVersion;                  /* 1Ch */
+    U16                     Reserved_0101_FWVersion;    /* 1Ch */ /* obsolete 16-bit FWVersion */
     U16                     ProductID;                  /* 1Eh */
     U32                     CurrentHostMfaHighAddr;     /* 20h */
     U16                     GlobalCredits;              /* 24h */
@@ -146,18 +175,20 @@
     U8                      MaxDevices;                 /* 2Eh */
     U8                      MaxBuses;                   /* 2Fh */
     U32                     FWImageSize;                /* 30h */
-    U32                     DataImageSize;              /* 34h */
+    U32                     Reserved4;                  /* 34h */
+    MPI_FW_VERSION          FWVersion;                  /* 38h */
 } MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
   IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
 
-#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK      (0xFF00)
-#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK      (0x00FF)
+#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK          (0xFF00)
+#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK          (0x00FF)
+
+#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL    (0x0001)
 
-#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT     (0x01)
-#define MPI_IOCFACTS_FLAGS_DATA_IMAGE_UPLOAD    (0x02)
+#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT         (0x01)
 
-#define MPI_IOCFACTS_EVENTSTATE_DISABLED        (0x00)
-#define MPI_IOCFACTS_EVENTSTATE_ENABLED         (0x01)
+#define MPI_IOCFACTS_EVENTSTATE_DISABLED            (0x00)
+#define MPI_IOCFACTS_EVENTSTATE_ENABLED             (0x01)
 
 
 
@@ -326,7 +357,6 @@
 } MSG_EVENT_ACK_REPLY, MPI_POINTER PTR_MSG_EVENT_ACK_REPLY,
   EventAckReply_t, MPI_POINTER pEventAckReply_t;
 
-
 /* Switch */
 
 #define MPI_EVENT_NOTIFICATION_SWITCH_OFF   (0x00)
@@ -345,7 +375,9 @@
 #define MPI_EVENT_LOOP_STATE_CHANGE         (0x00000008)
 #define MPI_EVENT_LOGOUT                    (0x00000009)
 #define MPI_EVENT_EVENT_CHANGE              (0x0000000A)
-#define MPI_EVENT_RAID_STATUS_CHANGE        (0x0000000B)
+#define MPI_EVENT_INTEGRATED_RAID           (0x0000000B)
+#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
+#define MPI_EVENT_ON_BUS_TIMER_EXPIRED      (0x0000000D)
 
 /* AckRequired field values */
 
@@ -372,6 +404,27 @@
 } EVENT_DATA_SCSI, MPI_POINTER PTR_EVENT_DATA_SCSI,
   EventDataScsi_t, MPI_POINTER pEventDataScsi_t;
 
+/* SCSI Device Status Change Event data */
+
+typedef struct _EVENT_DATA_SCSI_DEVICE_STATUS_CHANGE
+{
+    U8                      TargetID;                   /* 00h */
+    U8                      Bus;                        /* 01h */
+    U8                      ReasonCode;                 /* 02h */
+    U8                      LUN;                        /* 03h */
+    U8                      ASC;                        /* 04h */
+    U8                      ASCQ;                       /* 05h */
+    U16                     Reserved;                   /* 06h */
+} EVENT_DATA_SCSI_DEVICE_STATUS_CHANGE,
+  MPI_POINTER PTR_EVENT_DATA_SCSI_DEVICE_STATUS_CHANGE,
+  MpiEventDataScsiDeviceStatusChange_t,
+  MPI_POINTER pMpiEventDataScsiDeviceStatusChange_t;
+
+/* MPI SCSI Device Status Change Event data ReasonCode values */
+#define MPI_EVENT_SCSI_DEV_STAT_RC_ADDED                (0x03)
+#define MPI_EVENT_SCSI_DEV_STAT_RC_NOT_RESPONDING       (0x04)
+#define MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA           (0x05)
+
 /* MPI Link Status Change Event data */
 
 typedef struct _EVENT_DATA_LINK_STATUS
@@ -417,29 +470,34 @@
 } EVENT_DATA_LOGOUT, MPI_POINTER PTR_EVENT_DATA_LOGOUT,
   EventDataLogout_t, MPI_POINTER pEventDataLogout_t;
 
-/* MPI RAID Status Change Event data */
+/* MPI Integrated RAID Event data */
 
-typedef struct _EVENT_DATA_RAID_STATUS_CHANGE
+typedef struct _EVENT_DATA_RAID
 {
-    U8                      VolumeTargetID;             /* 00h */
+    U8                      VolumeID;                   /* 00h */
     U8                      VolumeBus;                  /* 01h */
     U8                      ReasonCode;                 /* 02h */
     U8                      PhysDiskNum;                /* 03h */
     U8                      ASC;                        /* 04h */
     U8                      ASCQ;                       /* 05h */
     U16                     Reserved;                   /* 06h */
-} EVENT_DATA_RAID_STATUS_CHANGE, MPI_POINTER PTR_EVENT_DATA_RAID_STATUS_CHANGE,
-  MpiEventDataRaidStatusChange_t, MPI_POINTER pMpiEventDataRaidStatusChange_t;
-
-
-/* MPI RAID Status Change Event data ReasonCode values */
-
-#define MPI_EVENT_RAID_DATA_RC_VOLUME_OPTIMAL       (0x00)
-#define MPI_EVENT_RAID_DATA_RC_VOLUME_DEGRADED      (0x01)
-#define MPI_EVENT_RAID_DATA_RC_STARTED_RESYNC       (0x02)
-#define MPI_EVENT_RAID_DATA_RC_DISK_ADDED           (0x03)
-#define MPI_EVENT_RAID_DATA_RC_DISK_NOT_RESPONDING  (0x04)
-#define MPI_EVENT_RAID_DATA_RC_SMART_DATA           (0x05)
+    U32                     SettingsStatus;             /* 08h */
+} EVENT_DATA_RAID, MPI_POINTER PTR_EVENT_DATA_RAID,
+  MpiEventDataRaid_t, MPI_POINTER pMpiEventDataRaid_t;
+
+/* MPI Integrated RAID Event data ReasonCode values */
+#define MPI_EVENT_RAID_RC_VOLUME_CREATED                (0x00)
+#define MPI_EVENT_RAID_RC_VOLUME_DELETED                (0x01)
+#define MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED       (0x02)
+#define MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED         (0x03)
+#define MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED       (0x04)
+#define MPI_EVENT_RAID_RC_PHYSDISK_CREATED              (0x05)
+#define MPI_EVENT_RAID_RC_PHYSDISK_DELETED              (0x06)
+#define MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED     (0x07)
+#define MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED       (0x08)
+#define MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED             (0x09)
+#define MPI_EVENT_RAID_RC_SMART_DATA                    (0x0A)
+#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED        (0x0B)
 
 
 /*****************************************************************************
@@ -468,6 +526,7 @@
 #define MPI_FW_DOWNLOAD_ITYPE_RESERVED      (0x00)
 #define MPI_FW_DOWNLOAD_ITYPE_FW            (0x01)
 #define MPI_FW_DOWNLOAD_ITYPE_BIOS          (0x02)
+#define MPI_FW_DOWNLOAD_ITYPE_NVDATA        (0x03)
 
 
 typedef struct _FWDownloadTCSGE
@@ -476,7 +535,7 @@
     U8                      ContextSize;                /* 01h */
     U8                      DetailsLength;              /* 02h */
     U8                      Flags;                      /* 03h */
-    U32                     Reserved1;                  /* 04h */
+    U32                     Reserved_0100_Checksum;     /* 04h */ /* obsolete Checksum */
     U32                     ImageOffset;                /* 08h */
     U32                     ImageSize;                  /* 0Ch */
 } FW_DOWNLOAD_TCSGE, MPI_POINTER PTR_FW_DOWNLOAD_TCSGE,
@@ -519,7 +578,7 @@
 #define MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM      (0x00)
 #define MPI_FW_UPLOAD_ITYPE_FW_FLASH        (0x01)
 #define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH      (0x02)
-#define MPI_FW_UPLOAD_ITYPE_DATA_IOC_MEM    (0x03)
+#define MPI_FW_UPLOAD_ITYPE_NVDATA          (0x03)
 
 typedef struct _FWUploadTCSGE
 {
@@ -563,11 +622,10 @@
     U32                     Checksum;                   /* 1Ch */
     U16                     VendorId;                   /* 20h */
     U16                     ProductId;                  /* 22h */
-    U16                     FwVersion;                  /* 24h */
-    U16                     Reserved1;                  /* 26h */
+    MPI_FW_VERSION          FWVersion;                  /* 24h */
     U32                     SeqCodeVersion;             /* 28h */
     U32                     ImageSize;                  /* 2Ch */
-    U32                     Reserved2;                  /* 30h */
+    U32                     NextImageHeaderOffset;      /* 30h */
     U32                     LoadStartAddress;           /* 34h */
     U32                     IopResetVectorValue;        /* 38h */
     U32                     IopResetRegAddr;            /* 3Ch */
@@ -581,30 +639,49 @@
 #define MPI_FW_HEADER_WHAT_SIGNATURE        (0x29232840)
 
 /* defines for using the ProductId field */
-#define MPI_FW_HEADER_PID_TYPE_MASK         (0xF000)
-#define MPI_FW_HEADER_PID_TYPE_SCSI         (0x0000)
-#define MPI_FW_HEADER_PID_TYPE_FC           (0x1000)
-
-#define MPI_FW_HEADER_PID_FW_VENDOR_MASK    (0x0F00)
-#define MPI_FW_HEADER_PID_FW_VENDOR_LSI     (0x0000)
-
-#define MPI_FW_HEADER_PID_FAMILY_MASK       (0x000F)
-#define MPI_FW_HEADER_PID_FAMILY_1030_SCSI  (0x0000)
-#define MPI_FW_HEADER_PID_FAMILY_909_FC     (0x0000)
-#define MPI_FW_HEADER_PID_FAMILY_919_FC     (0x0001)
-#define MPI_FW_HEADER_PID_FAMILY_919X_FC    (0x0002)
-
-
-typedef struct _MPI_DATA_HEADER
-{
-    U32                     Signature;                  /* 00h */
-    U16                     FunctionNumber;             /* 04h */
-    U16                     Length;                     /* 06h */
-    U32                     Checksum;                   /* 08h */
-    U32                     LoadStartAddress;           /* 0Ch */
-} MPI_DATA_HEADER, MPI_POINTER PTR_MPI_DATA_HEADER,
-  MpiDataHeader_t, MPI_POINTER pMpiDataHeader_t;
+#define MPI_FW_HEADER_PID_TYPE_MASK             (0xF000)
+#define MPI_FW_HEADER_PID_TYPE_SCSI             (0x0000)
+#define MPI_FW_HEADER_PID_TYPE_FC               (0x1000)
+
+#define MPI_FW_HEADER_PID_PROD_MASK                     (0x0F00)
+#define MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI           (0x0100)
+#define MPI_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI    (0x0200)
+#define MPI_FW_HEADER_PID_PROD_TARGET_SCSI              (0x0300)
+#define MPI_FW_HEADER_PID_PROD_IM_SCSI                  (0x0400)
+#define MPI_FW_HEADER_PID_PROD_IS_SCSI                  (0x0500)
+#define MPI_FW_HEADER_PID_PROD_CTX_SCSI                 (0x0600)
+
+#define MPI_FW_HEADER_PID_FAMILY_MASK           (0x00FF)
+#define MPI_FW_HEADER_PID_FAMILY_1030A0_SCSI    (0x0001)
+#define MPI_FW_HEADER_PID_FAMILY_1030B0_SCSI    (0x0002)
+#define MPI_FW_HEADER_PID_FAMILY_1030B1_SCSI    (0x0003)
+#define MPI_FW_HEADER_PID_FAMILY_1030C0_SCSI    (0x0004)
+#define MPI_FW_HEADER_PID_FAMILY_1020A0_SCSI    (0x0005)
+#define MPI_FW_HEADER_PID_FAMILY_1020B0_SCSI    (0x0006)
+#define MPI_FW_HEADER_PID_FAMILY_1020B1_SCSI    (0x0007)
+#define MPI_FW_HEADER_PID_FAMILY_1020C0_SCSI    (0x0008)
+#define MPI_FW_HEADER_PID_FAMILY_1035A0_SCSI    (0x0009)
+#define MPI_FW_HEADER_PID_FAMILY_1035B0_SCSI    (0x000A)
+#define MPI_FW_HEADER_PID_FAMILY_909_FC         (0x0000)
+#define MPI_FW_HEADER_PID_FAMILY_919_FC         (0x0001)
+#define MPI_FW_HEADER_PID_FAMILY_919X_FC        (0x0002)
 
-#define MPI_DATA_HEADER_SIGNATURE           (0x43504147)
+typedef struct _MPI_EXT_IMAGE_HEADER
+{
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U16                     Reserved1;                  /* 02h */
+    U32                     Checksum;                   /* 04h */
+    U32                     ImageSize;                  /* 08h */
+    U32                     NextImageHeaderOffset;      /* 0Ch */
+    U32                     LoadStartAddress;           /* 10h */
+    U32                     Reserved2;                  /* 14h */
+} MPI_EXT_IMAGE_HEADER, MPI_POINTER PTR_MPI_EXT_IMAGE_HEADER,
+  MpiExtImageHeader_t, MPI_POINTER pMpiExtImageHeader_t;
+
+/* defines for the ImageType field */
+#define MPI_EXT_IMAGE_TYPE_UNSPECIFIED          (0x00)
+#define MPI_EXT_IMAGE_TYPE_FW                   (0x01)
+#define MPI_EXT_IMAGE_TYPE_NVDATA               (0x03)
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_lan.h linux/drivers/message/fusion/lsi/mpi_lan.h
--- linux.orig/drivers/message/fusion/lsi/mpi_lan.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_lan.h	2002-07-20 01:08:37.000000000 +0000
@@ -6,7 +6,7 @@
  *          Title:  MPI LAN messages and structures
  *  Creation Date:  June 30, 2000
  *
- *    MPI Version:  01.01.03
+ *    MPI Version:  01.02.01
  *
  *  Version History
  *  ---------------
@@ -27,6 +27,7 @@
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Started using MPI_POINTER.
  *  03-27-01  01.01.03  Added structure offset comments.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
  *  --------------------------------------------------------------------------
  */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_raid.h linux/drivers/message/fusion/lsi/mpi_raid.h
--- linux.orig/drivers/message/fusion/lsi/mpi_raid.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_raid.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,178 @@
+/*
+ *  Copyright (c) 2001 LSI Logic Corporation.
+ *
+ *
+ *           Name:  MPI_RAID.H
+ *          Title:  MPI RAID message and structures
+ *  Creation Date:  February 27, 2001
+ *
+ *    MPI Version:  01.02.04
+ *
+ *  Version History
+ *  ---------------
+ *
+ *  Date      Version   Description
+ *  --------  --------  ------------------------------------------------------
+ *  02-27-01  01.01.01  Original release for this file.
+ *  03-27-01  01.01.02  Added structure offset comments.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  09-28-01  01.02.02  Major rework for MPI v1.2 Integrated RAID changes.
+ *  10-04-01  01.02.03  Added ActionData defines for
+ *                      MPI_RAID_ACTION_DELETE_VOLUME action.
+ *  11-01-01  01.02.04  Added define for MPI_RAID_ACTION_ADATA_DO_NOT_SYNC.
+ *  --------------------------------------------------------------------------
+ */
+
+#ifndef MPI_RAID_H
+#define MPI_RAID_H
+
+
+/******************************************************************************
+*
+*        R A I D    M e s s a g e s
+*
+*******************************************************************************/
+
+
+/****************************************************************************/
+/* RAID Volume Request                                                      */
+/****************************************************************************/
+
+typedef struct _MSG_RAID_ACTION
+{
+    U8                      Action;             /* 00h */
+    U8                      Reserved1;          /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      VolumeID;           /* 04h */
+    U8                      VolumeBus;          /* 05h */
+    U8                      PhysDiskNum;        /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     Reserved2;          /* 0Ch */
+    U32                     ActionDataWord;     /* 10h */
+    SGE_SIMPLE_UNION        ActionDataSGE;      /* 14h */
+} MSG_RAID_ACTION_REQUEST, MPI_POINTER PTR_MSG_RAID_ACTION_REQUEST,
+  MpiRaidActionRequest_t , MPI_POINTER pMpiRaidActionRequest_t;
+
+
+/* RAID Action request Action values */
+
+#define MPI_RAID_ACTION_STATUS                      (0x00)
+#define MPI_RAID_ACTION_INDICATOR_STRUCT            (0x01)
+#define MPI_RAID_ACTION_CREATE_VOLUME               (0x02)
+#define MPI_RAID_ACTION_DELETE_VOLUME               (0x03)
+#define MPI_RAID_ACTION_DISABLE_VOLUME              (0x04)
+#define MPI_RAID_ACTION_ENABLE_VOLUME               (0x05)
+#define MPI_RAID_ACTION_QUIESCE_PHYS_IO             (0x06)
+#define MPI_RAID_ACTION_ENABLE_PHYS_IO              (0x07)
+#define MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS      (0x08)
+#define MPI_RAID_ACTION_PHYSDISK_OFFLINE            (0x0A)
+#define MPI_RAID_ACTION_PHYSDISK_ONLINE             (0x0B)
+#define MPI_RAID_ACTION_CHANGE_PHYSDISK_SETTINGS    (0x0C)
+#define MPI_RAID_ACTION_CREATE_PHYSDISK             (0x0D)
+#define MPI_RAID_ACTION_DELETE_PHYSDISK             (0x0E)
+#define MPI_RAID_ACTION_FAIL_PHYSDISK               (0x0F)
+#define MPI_RAID_ACTION_REPLACE_PHYSDISK            (0x10)
+
+/* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */
+#define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC           (0x00000001)
+
+/* ActionDataWord defines for use with MPI_RAID_ACTION_DELETE_VOLUME action */
+#define MPI_RAID_ACTION_ADATA_KEEP_PHYS_DISKS       (0x00000000)
+#define MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS        (0x00000001)
+
+
+/* RAID Action reply message */
+
+typedef struct _MSG_RAID_ACTION_REPLY
+{
+    U8                      Action;             /* 00h */
+    U8                      Reserved;           /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      VolumeID;           /* 04h */
+    U8                      VolumeBus;          /* 05h */
+    U8                      PhysDiskNum;        /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     ActionStatus;       /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     VolumeStatus;       /* 14h */
+    U32                     ActionData;         /* 18h */
+} MSG_RAID_ACTION_REPLY, MPI_POINTER PTR_MSG_RAID_ACTION_REPLY,
+  MpiRaidActionReply_t, MPI_POINTER pMpiRaidActionReply_t;
+
+
+/* RAID Volume reply ActionStatus values */
+
+#define MPI_RAID_ACTION_ASTATUS_SUCCESS             (0x0000)
+#define MPI_RAID_ACTION_ASTATUS_INVALID_ACTION      (0x0001)
+#define MPI_RAID_ACTION_ASTATUS_FAILURE             (0x0002)
+#define MPI_RAID_ACTION_ASTATUS_IN_PROGRESS         (0x0003)
+
+
+/* RAID Volume reply RAID Volume Indicator structure */
+
+typedef struct _MPI_RAID_VOL_INDICATOR
+{
+    U64                     TotalBlocks;        /* 00h */
+    U64                     BlocksRemaining;    /* 08h */
+} MPI_RAID_VOL_INDICATOR, MPI_POINTER PTR_MPI_RAID_VOL_INDICATOR,
+  MpiRaidVolIndicator_t, MPI_POINTER pMpiRaidVolIndicator_t;
+
+
+/****************************************************************************/
+/* SCSI IO RAID Passthrough Request                                         */
+/****************************************************************************/
+
+typedef struct _MSG_SCSI_IO_RAID_PT_REQUEST
+{
+    U8                      PhysDiskNum;        /* 00h */
+    U8                      Reserved1;          /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      CDBLength;          /* 04h */
+    U8                      SenseBufferLength;  /* 05h */
+    U8                      Reserved2;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      LUN[8];             /* 0Ch */
+    U32                     Control;            /* 14h */
+    U8                      CDB[16];            /* 18h */
+    U32                     DataLength;         /* 28h */
+    U32                     SenseBufferLowAddr; /* 2Ch */
+    SGE_IO_UNION            SGL;                /* 30h */
+} MSG_SCSI_IO_RAID_PT_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO_RAID_PT_REQUEST,
+  SCSIIORaidPassthroughRequest_t, MPI_POINTER pSCSIIORaidPassthroughRequest_t;
+
+
+/* SCSI IO RAID Passthrough reply structure */
+
+typedef struct _MSG_SCSI_IO_RAID_PT_REPLY
+{
+    U8                      PhysDiskNum;        /* 00h */
+    U8                      Reserved1;          /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      CDBLength;          /* 04h */
+    U8                      SenseBufferLength;  /* 05h */
+    U8                      Reserved2;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      SCSIStatus;         /* 0Ch */
+    U8                      SCSIState;          /* 0Dh */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     TransferCount;      /* 14h */
+    U32                     SenseCount;         /* 18h */
+    U32                     ResponseInfo;       /* 1Ch */
+} MSG_SCSI_IO_RAID_PT_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_RAID_PT_REPLY,
+  SCSIIORaidPassthroughReply_t, MPI_POINTER pSCSIIORaidPassthroughReply_t;
+
+
+#endif
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_targ.h linux/drivers/message/fusion/lsi/mpi_targ.h
--- linux.orig/drivers/message/fusion/lsi/mpi_targ.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_targ.h	2002-07-20 01:08:26.000000000 +0000
@@ -6,7 +6,7 @@
  *          Title:  MPI Target mode messages and structures
  *  Creation Date:  June 22, 2000
  *
- *    MPI Version:  01.01.04
+ *    MPI Version:  01.02.04
  *
  *  Version History
  *  ---------------
@@ -26,6 +26,14 @@
  *                      Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
  *                      MPI_TARGET_FCP_CMD_BUFFER.
  *  03-27-01  01.01.04  Added structure offset comments.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  09-28-01  01.02.02  Added structure for MPI_TARGET_SCSI_SPI_STATUS_IU.
+ *                      Added PriorityReason field to some replies and
+ *                      defined more PriorityReason codes.
+ *                      Added some defines for to support previous version
+ *                      of MPI.
+ *  10-04-01  01.02.03  Added PriorityReason to MSG_TARGET_ERROR_REPLY.
+ *  11-01-01  01.02.04  Added define for TARGET_STATUS_SEND_FLAGS_HIGH_PRIORITY.
  *  --------------------------------------------------------------------------
  */
 
@@ -78,6 +86,7 @@
 #define CMD_BUFFER_POST_FLAGS_64_BIT_ADDR       (0x80)
 
 #define CMD_BUFFER_POST_IO_INDEX_MASK           (0x00003FFF)
+#define CMD_BUFFER_POST_IO_INDEX_MASK_0100      (0x000003FF) /* obsolete */
 
 
 typedef struct _MSG_TARGET_CMD_BUFFER_POST_REPLY
@@ -97,7 +106,7 @@
 } MSG_TARGET_CMD_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REPLY,
   TargetCmdBufferPostReply_t, MPI_POINTER pTargetCmdBufferPostReply_t;
 
-
+/* the following structure is obsolete as of MPI v1.2 */
 typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY
 {
     U16                     Reserved;                   /* 00h */
@@ -117,6 +126,13 @@
 
 #define PRIORITY_REASON_NO_DISCONNECT           (0x00)
 #define PRIORITY_REASON_SCSI_TASK_MANAGEMENT    (0x01)
+#define PRIORITY_REASON_CMD_PARITY_ERR          (0x02)
+#define PRIORITY_REASON_MSG_OUT_PARITY_ERR      (0x03)
+#define PRIORITY_REASON_LQ_CRC_ERR              (0x04)
+#define PRIORITY_REASON_CMD_CRC_ERR             (0x05)
+#define PRIORITY_REASON_PROTOCOL_ERR            (0x06)
+#define PRIORITY_REASON_DATA_OUT_PARITY_ERR     (0x07)
+#define PRIORITY_REASON_DATA_OUT_CRC_ERR        (0x08)
 #define PRIORITY_REASON_UNKNOWN                 (0xFF)
 
 
@@ -129,7 +145,8 @@
     U8                      Reserved2;                  /* 06h */
     U8                      MsgFlags;                   /* 07h */
     U32                     MsgContext;                 /* 08h */
-    U16                     Reserved3;                  /* 0Ch */
+    U8                      PriorityReason;             /* 0Ch */
+    U8                      Reserved3;                  /* 0Dh */
     U16                     IOCStatus;                  /* 0Eh */
     U32                     IOCLogInfo;                 /* 10h */
     U32                     ReplyWord;                  /* 14h */
@@ -204,7 +221,8 @@
     U8                      Reserved2;                  /* 06h */
     U8                      MsgFlags;                   /* 07h */
     U32                     MsgContext;                 /* 08h */
-    U16                     Reserved3;                  /* 0Ch */
+    U8                      PriorityReason;             /* 0Ch */
+    U8                      Reserved3;                  /* 0Dh */
     U16                     IOCStatus;                  /* 0Eh */
     U32                     IOCLogInfo;                 /* 10h */
     U32                     ReplyWord;                  /* 14h */
@@ -234,8 +252,34 @@
   TargetStatusSendRequest_t, MPI_POINTER pTargetStatusSendRequest_t;
 
 #define TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS   (0x01)
+#define TARGET_STATUS_SEND_FLAGS_HIGH_PRIORITY      (0x04)
 #define TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER  (0x80)
 
+typedef struct _MPI_TARGET_FCP_RSP_BUFFER
+{
+    U8      Reserved0[8];                               /* 00h */
+    U8      FcpStatus;                                  /* 08h */
+    U8      FcpFlags;                                   /* 09h */
+    U8      Reserved1[2];                               /* 0Ah */
+    U32     FcpResid;                                   /* 0Ch */
+    U32     FcpSenseLength;                             /* 10h */
+    U32     FcpResponseLength;                          /* 14h */
+    U8      FcpResponseData[8];                         /* 18h */
+    U8      FcpSenseData[32]; /* Pad to 64 bytes */     /* 20h */
+} MPI_TARGET_FCP_RSP_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_RSP_BUFFER,
+  MpiTargetFcpRspBuffer, MPI_POINTER pMpiTargetFcpRspBuffer;
+
+typedef struct _MPI_TARGET_SCSI_SPI_STATUS_IU
+{
+    U8      Reserved0;                                  /* 00h */
+    U8      Reserved1;                                  /* 01h */
+    U8      Valid;                                      /* 02h */
+    U8      Status;                                     /* 03h */
+    U32     SenseDataListLength;                        /* 04h */
+    U32     PktFailuresListLength;                      /* 08h */
+    U8      SenseData[52]; /* Pad the IU to 64 bytes */ /* 0Ch */
+} MPI_TARGET_SCSI_SPI_STATUS_IU, MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_STATUS_IU,
+  TargetScsiSpiStatusIU_t, MPI_POINTER pTargetScsiSpiStatusIU_t;
 
 /****************************************************************************/
 /* Target Mode Abort Request                                                */
@@ -324,6 +368,41 @@
                                     (((p) << TARGET_MODE_REPLY_PORT_SHIFT) &   \
                                                   TARGET_MODE_REPLY_PORT_MASK))
 
+/* the following obsolete values are for MPI v1.0 support */
+#define TARGET_MODE_REPLY_0100_MASK_HOST_INDEX       (0x000003FF)
+#define TARGET_MODE_REPLY_0100_SHIFT_HOST_INDEX      (0)
+#define TARGET_MODE_REPLY_0100_MASK_IOC_INDEX        (0x001FF800)
+#define TARGET_MODE_REPLY_0100_SHIFT_IOC_INDEX       (11)
+#define TARGET_MODE_REPLY_0100_PORT_MASK             (0x00400000)
+#define TARGET_MODE_REPLY_0100_PORT_SHIFT            (22)
+#define TARGET_MODE_REPLY_0100_MASK_INITIATOR_INDEX  (0x1F800000)
+#define TARGET_MODE_REPLY_0100_SHIFT_INITIATOR_INDEX (23)
+
+#define GET_HOST_INDEX_0100(x) (((x) & TARGET_MODE_REPLY_0100_MASK_HOST_INDEX) \
+                                  >> TARGET_MODE_REPLY_0100_SHIFT_HOST_INDEX)
+
+#define SET_HOST_INDEX_0100(t, hi)                                             \
+            ((t) = ((t) & ~TARGET_MODE_REPLY_0100_MASK_HOST_INDEX) |           \
+                         (((hi) << TARGET_MODE_REPLY_0100_SHIFT_HOST_INDEX) &  \
+                                      TARGET_MODE_REPLY_0100_MASK_HOST_INDEX))
+
+#define GET_IOC_INDEX_0100(x)   (((x) & TARGET_MODE_REPLY_0100_MASK_IOC_INDEX) \
+                                  >> TARGET_MODE_REPLY_0100_SHIFT_IOC_INDEX)
+
+#define SET_IOC_INDEX_0100(t, ii)                                              \
+            ((t) = ((t) & ~TARGET_MODE_REPLY_0100_MASK_IOC_INDEX) |            \
+                        (((ii) << TARGET_MODE_REPLY_0100_SHIFT_IOC_INDEX) &    \
+                                     TARGET_MODE_REPLY_0100_MASK_IOC_INDEX))
+
+#define GET_INITIATOR_INDEX_0100(x)                                            \
+            (((x) & TARGET_MODE_REPLY_0100_MASK_INITIATOR_INDEX)               \
+                              >> TARGET_MODE_REPLY_0100_SHIFT_INITIATOR_INDEX)
+
+#define SET_INITIATOR_INDEX_0100(t, ii)                                        \
+        ((t) = ((t) & ~TARGET_MODE_REPLY_0100_MASK_INITIATOR_INDEX) |          \
+                   (((ii) << TARGET_MODE_REPLY_0100_SHIFT_INITIATOR_INDEX) &   \
+                                TARGET_MODE_REPLY_0100_MASK_INITIATOR_INDEX))
+
 
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_tool.h linux/drivers/message/fusion/lsi/mpi_tool.h
--- linux.orig/drivers/message/fusion/lsi/mpi_tool.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_tool.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,129 @@
+/*
+ *  Copyright (c) 2001 LSI Logic Corporation.
+ *
+ *
+ *           Name:  MPI_TOOL.H
+ *          Title:  MPI Toolbox structures and definitions
+ *  Creation Date:  July 30, 2001
+ *
+ *    MPI Version:  01.02.02
+ *
+ *  Version History
+ *  ---------------
+ *
+ *  Date      Version   Description
+ *  --------  --------  ------------------------------------------------------
+ *  08-08-01  01.02.01  Original release.
+ *  08-29-01  01.02.02  Added DIAG_DATA_UPLOAD_HEADER and related defines.
+ *  --------------------------------------------------------------------------
+ */
+
+#ifndef MPI_TOOL_H
+#define MPI_TOOL_H
+
+#define MPI_TOOLBOX_CLEAN_TOOL                      (0x00)
+#define MPI_TOOLBOX_MEMORY_MOVE_TOOL                (0x01)
+#define MPI_TOOLBOX_DIAG_DATA_UPLOAD_TOOL           (0x02)
+
+
+/****************************************************************************/
+/* Toolbox reply                                                            */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_REPLY
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved3;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+} MSG_TOOLBOX_REPLY, MPI_POINTER PTR_MSG_TOOLBOX_REPLY,
+  ToolboxReply_t, MPI_POINTER pToolboxReply_t;
+
+
+/****************************************************************************/
+/* Toolbox Clean Tool request                                               */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_CLEAN_REQUEST
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     Flags;                      /* 0Ch */
+} MSG_TOOLBOX_CLEAN_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_CLEAN_REQUEST,
+  ToolboxCleanRequest_t, MPI_POINTER pToolboxCleanRequest_t;
+
+#define MPI_TOOLBOX_CLEAN_NVSRAM                    (0x00000001)
+#define MPI_TOOLBOX_CLEAN_SEEPROM                   (0x00000002)
+#define MPI_TOOLBOX_CLEAN_FLASH                     (0x00000004)
+
+
+/****************************************************************************/
+/* Toolbox Memory Move request                                              */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_MEM_MOVE_REQUEST
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    SGE_SIMPLE_UNION        SGL;                        /* 0Ch */
+} MSG_TOOLBOX_MEM_MOVE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_MEM_MOVE_REQUEST,
+  ToolboxMemMoveRequest_t, MPI_POINTER pToolboxMemMoveRequest_t;
+
+
+/****************************************************************************/
+/* Toolbox Diagnostic Data Upload request                                   */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     Flags;                      /* 0Ch */
+    U32                     Reserved3;                  /* 10h */
+    SGE_SIMPLE_UNION        SGL;                        /* 14h */
+} MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
+  ToolboxDiagDataUploadRequest_t, MPI_POINTER pToolboxDiagDataUploadRequest_t;
+
+typedef struct _DIAG_DATA_UPLOAD_HEADER
+{
+    U32                     DiagDataLength;             /* 00h */
+    U8                      FormatCode;                 /* 04h */
+    U8                      Reserved;                   /* 05h */
+    U16                     Reserved1;                  /* 06h */
+} DIAG_DATA_UPLOAD_HEADER, MPI_POINTER PTR_DIAG_DATA_UPLOAD_HEADER,
+  DiagDataUploadHeader_t, MPI_POINTER pDiagDataUploadHeader_t;
+
+#define MPI_TB_DIAG_FORMAT_SCSI_PRINTF_1            (0x01)
+#define MPI_TB_DIAG_FORMAT_SCSI_2                   (0x02)
+#define MPI_TB_DIAG_FORMAT_SCSI_3                   (0x03)
+#define MPI_TB_DIAG_FORMAT_FC_TRACE_1               (0x04)
+
+
+#endif
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/lsi/mpi_type.h linux/drivers/message/fusion/lsi/mpi_type.h
--- linux.orig/drivers/message/fusion/lsi/mpi_type.h	2001-07-07 00:03:11.000000000 +0000
+++ linux/drivers/message/fusion/lsi/mpi_type.h	2002-07-20 01:08:24.000000000 +0000
@@ -6,7 +6,7 @@
  *          Title:  MPI Basic type definitions
  *  Creation Date:  June 6, 2000
  *
- *    MPI Version:  01.01.02
+ *    MPI Version:  01.02.01
  *
  *  Version History
  *  ---------------
@@ -17,6 +17,7 @@
  *  06-06-00  01.00.01  Update version number for 1.0 release.
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Added define and ifdef for MPI_POINTER.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
  *  --------------------------------------------------------------------------
  */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/mptbase.c linux/drivers/message/fusion/mptbase.c
--- linux.orig/drivers/message/fusion/mptbase.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/message/fusion/mptbase.c	2002-07-20 01:08:28.000000000 +0000
@@ -20,6 +20,12 @@
  *      And to Roger Hickerson (LSI Logic) for tirelessly supporting
  *      this driver project.
  *
+ *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
+ *      and countless enhancements while adding support for the 1030
+ *      chip family.  Pam has been instrumental in the development of
+ *      of the 2.xx.xx series fusion drivers, and her contributions are
+ *      far too numerous to hope to list in one place.
+ *
  *      All manner of help from Stephen Shirron (LSI Logic):
  *      low-level FC analysis, debug + various fixes in FCxx firmware,
  *      initial port to alpha platform, various driver code optimizations,
@@ -38,11 +44,12 @@
  *      for gobs of hard work fixing and optimizing LAN code.
  *      THANK YOU!
  *
- *  Copyright (c) 1999-2001 LSI Logic Corporation
+ *  Copyright (c) 1999-2002 LSI Logic Corporation
  *  Originally By: Steven J. Ralston
- *  (mailto:Steve.Ralston@lsil.com)
+ *  (mailto:sjralston1@netscape.net)
+ *  (mailto:Pam.Delaney@lsil.com)
  *
- *  $Id: mptbase.c,v 1.53.4.3 2001/09/18 03:54:54 sralston Exp $
+ *  $Id: mptbase.c,v 1.110 2002/02/27 18:44:20 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -93,11 +100,14 @@
 #include <linux/kdev_t.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
-#include <linux/proc_fs.h>
+#include <linux/interrupt.h>		/* needed for in_interrupt() proto */
 #include <asm/io.h>
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #endif
+#ifdef __sparc__
+#include <asm/irq.h>			/* needed for __irq_itoa() proto */
+#endif
 
 #include "mptbase.h"
 
@@ -110,27 +120,33 @@
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
-
 /*
  *  cmd line parameters
  */
 MODULE_PARM(PortIo, "0-1i");
 MODULE_PARM_DESC(PortIo, "[0]=Use mmap, 1=Use port io");
-MODULE_PARM(HardReset, "0-1i");
-MODULE_PARM_DESC(HardReset, "0=Disable HardReset, [1]=Enable HardReset");
 static int PortIo = 0;
-static int HardReset = 1;
+
+#ifdef MFCNT
+static int mfcounter = 0;
+#define PRINT_MF_COUNT 20000
+#endif
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Public data...
  */
-int mpt_lan_index = 0;
-int mpt_stm_index = 0;
+int mpt_lan_index = -1;
+int mpt_stm_index = -1;
+
+struct proc_dir_entry *mpt_proc_root_dir;
+
+DmpServices_t *DmpService;
+
+void *mpt_v_ASCQ_TablePtr;
+const char **mpt_ScsiOpcodesPtr;
+int mpt_ASCQ_TableSz;
 
-void *mpt_v_ASCQ_TablePtr = NULL;
-const char **mpt_ScsiOpcodesPtr = NULL;
-int mpt_ASCQ_TableSz = 0;
 
 #define WHOINIT_UNKNOWN		0xAA
 
@@ -139,12 +155,12 @@
  *  Private data...
  */
 					/* Adapter lookup table */
-static MPT_ADAPTER		*mpt_adapters[MPT_MAX_ADAPTERS] = {0};
+       MPT_ADAPTER		*mpt_adapters[MPT_MAX_ADAPTERS];
 static MPT_ADAPTER_TRACKER	 MptAdapters;
 					/* Callback lookup table */
 static MPT_CALLBACK		 MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
 					/* Protocol driver class lookup table */
-static int	 		 MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
+static int			 MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
 					/* Event handler lookup table */
 static MPT_EVHANDLER		 MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 					/* Reset handler lookup table */
@@ -152,6 +168,10 @@
 
 static int	FusionInitCalled = 0;
 static int	mpt_base_index = -1;
+static int	last_drv_idx = -1;
+static int	isense_idx = -1;
+
+static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -160,49 +180,84 @@
 static void	mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
 static int	mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
 
-static int 	mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason);
-static int 	mpt_adapter_install(struct pci_dev *pdev);
-static void	mpt_detect_929_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
+static int	mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
+static int	mpt_adapter_install(struct pci_dev *pdev);
+static void	mpt_detect_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
 static void	mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
 static void	mpt_adapter_dispose(MPT_ADAPTER *ioc);
 
 static void	MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
-static int	MakeIocReady(MPT_ADAPTER *ioc, int force);
-static u32	GetIocState(MPT_ADAPTER *ioc, int cooked);
-static int	GetIocFacts(MPT_ADAPTER *ioc);
-static int	GetPortFacts(MPT_ADAPTER *ioc, int portnum);
-static int	SendIocInit(MPT_ADAPTER *ioc);
-static int	SendPortEnable(MPT_ADAPTER *ioc, int portnum);
-static int	mpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore);
-static int	KickStart(MPT_ADAPTER *ioc, int ignore);
-static int	SendIocReset(MPT_ADAPTER *ioc, u8 reset_type);
+static int	MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
+//static u32	mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
+static int	GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
+static int	GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
+static int	SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
+static int	SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
+static int	mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
+static int	mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
+static int	mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
+static int	KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
+static int	SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
 static int	PrimeIocFifos(MPT_ADAPTER *ioc);
-static int	HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait);
-static int	WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong);
-static int	WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong);
-static int	WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong);
+static int	WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
+static int	WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
+static int	WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 static int	GetLanConfigPages(MPT_ADAPTER *ioc);
+static int	GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
+static int	GetIoUnitPage2(MPT_ADAPTER *ioc);
+static int	mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
+static int	mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
+static int	mpt_findImVolumes(MPT_ADAPTER *ioc);
+static void	mpt_timer_expired(unsigned long data);
 static int	SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
 static int	SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
 
-static int	procmpt_create(void);
 #ifdef CONFIG_PROC_FS
+static int	procmpt_create(void);
 static int	procmpt_destroy(void);
+static int	procmpt_summary_read(char *buf, char **start, off_t offset,
+				int request, int *eof, void *data);
+static int	procmpt_version_read(char *buf, char **start, off_t offset,
+				int request, int *eof, void *data);
+static int	procmpt_iocinfo_read(char *buf, char **start, off_t offset,
+				int request, int *eof, void *data);
 #endif
-static int	procmpt_read_summary(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int	procmpt_read_dbg(char *page, char **start, off_t off, int count, int *eof, void *data);
-/*static int	procmpt_info(char *buf, char **start, off_t offset, int len);*/
+static void	mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
 
+//int		mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
 static int	ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
 static void	mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
 static void	mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
 
-static struct proc_dir_entry	*procmpt_root_dir = NULL;
-
 int		fusion_init(void);
 static void	fusion_exit(void);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  more Private data...
+ */
+#ifdef CONFIG_PROC_FS
+struct _mpt_proc_list {
+	const char	*name;
+	int		(*f)(char *, char **, off_t, int, int *, void *);
+} mpt_proc_list[] = {
+	{ "summary", procmpt_summary_read},
+	{ "version", procmpt_version_read},
+};
+#define MPT_PROC_ENTRIES (sizeof(mpt_proc_list)/sizeof(mpt_proc_list[0]))
+
+struct _mpt_ioc_proc_list {
+	const char	*name;
+	int		(*f)(char *, char **, off_t, int, int *, void *);
+} mpt_ioc_proc_list[] = {
+	{ "info", procmpt_iocinfo_read},
+	{ "summary", procmpt_summary_read},
+};
+#define MPT_IOC_PROC_ENTRIES (sizeof(mpt_ioc_proc_list)/sizeof(mpt_ioc_proc_list[0]))
+
+#endif
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /* 20000207 -sralston
  *  GRRRRR...  IOSpace (port i/o) register access (for the 909) is back!
  * 20000517 -sralston
@@ -225,9 +280,18 @@
 		writel(v, a);
 }
 
+static inline void CHIPREG_PIO_WRITE32(volatile u32 *a, u32 v)
+{
+	outl(v, (unsigned long)a);
+}
+
+static inline u32 CHIPREG_PIO_READ32(volatile u32 *a)
+{
+	return inl((unsigned long)a);
+}
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
+/*
  *	mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
  *	@irq: irq number (not used)
  *	@bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
@@ -252,8 +316,7 @@
 	MPT_FRAME_HDR	*mf;
 	MPT_FRAME_HDR	*mr;
 	u32		 pa;
-	u32		*m;
-	int		 req_idx;
+	int		 req_idx = -1;
 	int		 cb_idx;
 	int		 type;
 	int		 freeme;
@@ -262,6 +325,21 @@
 	ioc = bus_id;
 
 	/*
+	 * Verify ioc pointer is ok
+	 */
+	{
+		MPT_ADAPTER	*iocCmp;
+		iocCmp = mpt_adapter_find_first();
+		while ((ioc != iocCmp)  && iocCmp)
+			iocCmp = mpt_adapter_find_next(iocCmp);
+
+		if (!iocCmp) {
+			printk(KERN_WARNING "mpt_interrupt: Invalid ioc!\n");
+			return;
+		}
+	}
+
+	/*
 	 *  Drain the reply FIFO!
 	 *
 	 * NOTES: I've seen up to 10 replies processed in this loop, so far...
@@ -281,25 +359,27 @@
 		 *  Check for non-TURBO reply!
 		 */
 		if (pa & MPI_ADDRESS_REPLY_A_BIT) {
-			dma_addr_t reply_dma_addr;
+			u32 reply_dma_low;
 			u16 ioc_stat;
 
 			/* non-TURBO reply!  Hmmm, something may be up...
 			 *  Newest turbo reply mechanism; get address
 			 *  via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
 			 */
-			reply_dma_addr = (pa = (pa << 1));
 
-			/* Map DMA address of reply header to cpu address. */
-			m = (u32 *) ((u8 *)ioc->reply_frames +
-					(reply_dma_addr - ioc->reply_frames_dma));
+			/* Map DMA address of reply header to cpu address.
+			 * pa is 32 bits - but the dma address may be 32 or 64 bits
+			 * get offset based only only the low addresses
+			 */
+			reply_dma_low = (pa = (pa << 1));
+			mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
+					 (reply_dma_low - ioc->reply_frames_low_dma));
 
-			mr = (MPT_FRAME_HDR *) m;
 			req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
 			cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
 			mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
 
-			dprintk((KERN_INFO MYNAM ": %s: Got non-TURBO reply=%p\n",
+			dprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p\n",
 					ioc->name, mr));
 			DBG_DUMP_REPLY_FRAME(mr)
 
@@ -307,7 +387,7 @@
 			 *  Check/log IOC log info
 			 */
 			ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
-	 		if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
+			if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
 				u32	 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
 				if ((int)ioc->chip_type <= (int)FC929)
 					mpt_fc_log_info(ioc, log_info);
@@ -318,7 +398,7 @@
 			/*
 			 *  Process turbo (context) reply...
 			 */
-			dirqprintk((KERN_INFO MYNAM ": %s: Got TURBO reply(=%08x)\n", ioc->name, pa));
+			dirqprintk((MYIOC_s_INFO_FMT "Got TURBO reply(=%08x)\n", ioc->name, pa));
 			type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
 			if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
 				cb_idx = mpt_stm_index;
@@ -357,6 +437,34 @@
 			pa = 0;					/* No reply flush! */
 		}
 
+		if ((int)ioc->chip_type > (int)FC929) {
+			/* Verify mf, mf are reasonable.
+			 */
+			if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
+				|| (mf < ioc->req_frames)) ) {
+				printk(MYIOC_s_WARN_FMT 
+					"mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, mf, req_idx);
+				cb_idx = 0;
+				pa = 0;
+				freeme = 0;
+			}
+			if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
+				|| (mr < ioc->reply_frames)) ) {
+				printk(MYIOC_s_WARN_FMT 
+					"mpt_interrupt: Invalid rf (%p)!\n", ioc->name, mr);
+				cb_idx = 0;
+				pa = 0;
+				freeme = 0;
+			}
+			if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
+				printk(MYIOC_s_WARN_FMT 
+					"mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
+				cb_idx = 0;
+				pa = 0;
+				freeme = 0;
+			}
+		}
+
 		/*  Check for (valid) IO callback!  */
 		if (cb_idx) {
 			/*  Do the callback!  */
@@ -374,15 +482,18 @@
 			/*  Put Request back on FreeQ!  */
 			spin_lock_irqsave(&ioc->FreeQlock, flags);
 			Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
+#ifdef MFCNT
+			ioc->mfcnt--;
+#endif
 			spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 		}
 
 		count++;
-		dirqprintk((KERN_INFO MYNAM ": %s: ISR processed frame #%d\n", ioc->name, count));
+		dirqprintk((MYIOC_s_INFO_FMT "ISR processed frame #%d\n", ioc->name, count));
 		mb();
 
 		if (count >= MPT_MAX_REPLIES_PER_ISR) {
-			dirqprintk((KERN_INFO MYNAM ": %s: ISR processed %d replies.",
+			dirqprintk((MYIOC_s_INFO_FMT "ISR processed %d replies.",
 					ioc->name, count));
 			dirqprintk((" Giving this ISR a break!\n"));
 			return;
@@ -409,17 +520,17 @@
 	int freereq = 1;
 	u8 func;
 
-	dprintk((KERN_INFO MYNAM ": %s: mpt_base_reply() called\n", ioc->name));
+	dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
 
 	if ((mf == NULL) ||
 	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
-		printk(KERN_ERR MYNAM ": %s: ERROR - NULL or BAD request frame ptr! (=%p)\n",
+		printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
 				ioc->name, mf);
 		return 1;
 	}
 
 	if (reply == NULL) {
-		dprintk((KERN_ERR MYNAM ": %s: ERROR - Unexpected NULL Event (turbo?) reply!\n",
+		dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
 				ioc->name));
 		return 1;
 	}
@@ -430,7 +541,7 @@
 	}
 
 	func = reply->u.hdr.Function;
-	dprintk((KERN_INFO MYNAM ": %s: mpt_base_reply, Function=%02Xh\n",
+	dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
 			ioc->name, func));
 
 	if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
@@ -441,30 +552,77 @@
 		results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
 		if (results != evHandlers) {
 			/* CHECKME! Any special handling needed here? */
-			dprintk((KERN_WARNING MYNAM ": %s: Hmmm... Called %d event handlers, sum results = %d\n",
+			dprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
 					ioc->name, evHandlers, results));
 		}
 
 		/*
-		 *  Hmmm...  It seems that EventNotificationReply is an exception
-		 *  to the rule of one reply per request.
+		 *	Hmmm...  It seems that EventNotificationReply is an exception
+		 *	to the rule of one reply per request.
 		 */
 		if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
 			freereq = 0;
+
 #ifdef CONFIG_PROC_FS
 //		LogEvent(ioc, pEvReply);
 #endif
+
 	} else if (func == MPI_FUNCTION_EVENT_ACK) {
-		dprintk((KERN_INFO MYNAM ": %s: mpt_base_reply, EventAck reply received\n",
+		dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
 				ioc->name));
+	} else if (func == MPI_FUNCTION_CONFIG) {
+		CONFIGPARMS *pCfg;
+		unsigned long flags;
+
+		dprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
+				ioc->name, mf, reply));
+
+		pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
+
+		if (pCfg) {
+			/* disable timer and remove from linked list */
+			del_timer(&pCfg->timer);
+
+			spin_lock_irqsave(&ioc->FreeQlock, flags);
+			Q_DEL_ITEM(&pCfg->linkage);
+			spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+			/*
+			 *	If IOC Status is SUCCESS, save the header
+			 *	and set the status code to GOOD.
+			 */
+			pCfg->status = MPT_CONFIG_ERROR;
+			if (reply) {
+				ConfigReply_t	*pReply = (ConfigReply_t *)reply;
+				u16		 status;
+
+				status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+				dprintk((KERN_NOTICE "  IOCStatus=%04xh, IOCLogInfo=%08xh\n",
+				     status, le32_to_cpu(pReply->IOCLogInfo)));
+
+				pCfg->status = status;
+				if (status == MPI_IOCSTATUS_SUCCESS) {
+					pCfg->hdr->PageVersion = pReply->Header.PageVersion;
+					pCfg->hdr->PageLength = pReply->Header.PageLength;
+					pCfg->hdr->PageNumber = pReply->Header.PageNumber;
+					pCfg->hdr->PageType = pReply->Header.PageType;
+				}
+			}
+
+			/*
+			 *	Wake up the original calling thread
+			 */
+			pCfg->wait_done = 1;
+			wake_up(&mpt_waitq);
+		}
 	} else {
-		printk(KERN_ERR MYNAM ": %s: ERROR - Unexpected msg function (=%02Xh) reply received!\n",
+		printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
 				ioc->name, func);
 	}
 
 	/*
-	 *  Conditionally tell caller to free the original
-	 *  EventNotification/EventAck/unexpected request frame!
+	 *	Conditionally tell caller to free the original
+	 *	EventNotification/EventAck/unexpected request frame!
 	 */
 	return freereq;
 }
@@ -480,21 +638,22 @@
  *	protocol-specific driver must do this before it will be able to
  *	use any IOC resources, such as obtaining request frames.
  *
- *	NOTES: The SCSI protocol driver currently calls this routine twice
- *	in order to register separate callbacks; one for "normal" SCSI IO
- *	and another for MptScsiTaskMgmt requests.
+ *	NOTES: The SCSI protocol driver currently calls this routine thrice
+ *	in order to register separate callbacks; one for "normal" SCSI IO;
+ *	one for MptScsiTaskMgmt requests; one for Scan/DV requests.
  *
  *	Returns a positive integer valued "handle" in the
- *	range (and S.O.D. order) {7,6,...,1} if successful.
+ *	range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
  *	Any non-positive return value (including zero!) should be considered
  *	an error by the caller.
  */
 int
 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
 {
-	int r = -1;
 	int i;
 
+	last_drv_idx = -1;
+
 #ifndef MODULE
 	/*
 	 *  Handle possibility of the mptscsih_detect() routine getting
@@ -512,7 +671,7 @@
 #endif
 
 	/*
-	 *  Search for empty callback slot in this order: {7,6,...,1}
+	 *  Search for empty callback slot in this order: {N,...,7,6,5,...,1}
 	 *  (slot/handle 0 is reserved!)
 	 */
 	for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
@@ -520,7 +679,7 @@
 			MptCallbacks[i] = cbfunc;
 			MptDriverClass[i] = dclass;
 			MptEvHandlers[i] = NULL;
-			r = i;
+			last_drv_idx = i;
 			if (cbfunc != mpt_base_reply) {
 				MOD_INC_USE_COUNT;
 			}
@@ -528,7 +687,7 @@
 		}
 	}
 
-	return r;
+	return last_drv_idx;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -546,6 +705,11 @@
 		MptCallbacks[cb_idx] = NULL;
 		MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
 		MptEvHandlers[cb_idx] = NULL;
+
+		last_drv_idx++;
+		if (isense_idx != -1 && isense_idx <= cb_idx)
+			isense_idx++;
+
 		if (cb_idx != mpt_base_index) {
 			MOD_DEC_USE_COUNT;
 		}
@@ -639,7 +803,8 @@
  *	@handle: Handle of registered MPT protocol driver
  *	@iocid: IOC unique identifier (integer)
  *
- *	Returns pointer to a MPT request frame or %NULL if none are available.
+ *	Returns pointer to a MPT request frame or %NULL if none are available
+ *	or IOC is not active.
  */
 MPT_FRAME_HDR*
 mpt_get_msg_frame(int handle, int iocid)
@@ -650,6 +815,16 @@
 
 	/* validate handle and ioc identifier */
 	iocp = mpt_adapters[iocid];
+
+#ifdef MFCNT
+	if (!iocp->active)
+		printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
+#endif
+
+	/* If interrupts are not attached, do not return a request frame */
+	if (!iocp->active)
+		return NULL;
+
 	spin_lock_irqsave(&iocp->FreeQlock, flags);
 	if (! Q_IS_EMPTY(&iocp->FreeQ)) {
 		int req_offset;
@@ -662,8 +837,20 @@
 		mf->u.frame.hwhdr.msgctxu.fld.req_idx =
 				cpu_to_le16(req_offset / iocp->req_sz);
 		mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
+#ifdef MFCNT
+		iocp->mfcnt++;
+#endif
 	}
 	spin_unlock_irqrestore(&iocp->FreeQlock, flags);
+
+#ifdef MFCNT
+	if (mf == NULL)
+		printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", iocp->mfcnt, iocp->req_depth);
+	mfcounter++;
+	if (mfcounter == PRINT_MF_COUNT)
+		printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", iocp->mfcnt, iocp->req_depth);
+#endif
+
 	dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
 			iocp->name, handle, iocid, mf));
 	return mf;
@@ -687,7 +874,7 @@
 
 	iocp = mpt_adapters[iocid];
 	if (iocp != NULL) {
-		dma_addr_t mf_dma_addr;
+		u32 mf_dma_addr;
 		int req_offset;
 
 		/* ensure values are reset properly! */
@@ -700,23 +887,23 @@
 #ifdef MPT_DEBUG_MSG_FRAME
 		{
 			u32	*m = mf->u.frame.hwhdr.__hdr;
-			int	 i, n;
+			int	 ii, n;
 
 			printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
 					iocp->name, m);
 			n = iocp->req_sz/4 - 1;
 			while (m[n] == 0)
 				n--;
-			for (i=0; i<=n; i++) {
-				if (i && ((i%8)==0))
+			for (ii=0; ii<=n; ii++) {
+				if (ii && ((ii%8)==0))
 					printk("\n" KERN_INFO " ");
-				printk(" %08x", le32_to_cpu(m[i]));
+				printk(" %08x", le32_to_cpu(m[ii]));
 			}
 			printk("\n");
 		}
 #endif
 
-		mf_dma_addr = iocp->req_frames_dma + req_offset;
+		mf_dma_addr = iocp->req_frames_low_dma + req_offset;
 		CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);
 	}
 }
@@ -742,6 +929,9 @@
 		/*  Put Request back on FreeQ!  */
 		spin_lock_irqsave(&iocp->FreeQlock, flags);
 		Q_ADD_TAIL(&iocp->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
+#ifdef MFCNT
+		iocp->mfcnt--;
+#endif
 		spin_unlock_irqrestore(&iocp->FreeQlock, flags);
 	}
 }
@@ -754,8 +944,9 @@
  *	@iocid: IOC unique identifier (integer)
  *	@reqBytes: Size of the request in bytes
  *	@req: Pointer to MPT request frame
+ *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
  *
- *	This routine is used exclusively by mptscsih to send MptScsiTaskMgmt
+ *	This routine is used exclusively to send MptScsiTaskMgmt
  *	requests since they are required to be sent via doorbell handshake.
  *
  *	NOTE: It is the callers responsibility to byte-swap fields in the
@@ -764,41 +955,30 @@
  *	Returns 0 for success, non-zero for failure.
  */
 int
-mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req)
+mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sleepFlag)
 {
 	MPT_ADAPTER	*iocp;
 	int		 r = 0;
 
 	iocp = mpt_adapters[iocid];
 	if (iocp != NULL) {
-		u8		*req_as_bytes;
-		u32		 ioc_raw_state;
-		int		 i;
-
-		/* YIKES!  We already know something is amiss.
-		 * Do upfront check on IOC state.
-		 */
-		ioc_raw_state = GetIocState(iocp, 0);
-		if ((ioc_raw_state & MPI_DOORBELL_ACTIVE) ||
-		    ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL)) {
-			printk(KERN_WARNING MYNAM ": %s: Bad IOC state (%08x) WARNING!\n",
-					iocp->name, ioc_raw_state);
-			if ((r = mpt_do_ioc_recovery(iocp, MPT_HOSTEVENT_IOC_RECOVER)) != 0) {
-				printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
-						r, iocp->name);
-				return r;
-			}
-		}
+		u8	*req_as_bytes;
+		int	 ii;
+
+		/* State is known to be good upon entering
+		 * this function so issue the bus reset
+		 * request.
+		 */
 
 		/*
 		 * Emulate what mpt_put_msg_frame() does /wrt to sanity
 		 * setting cb_idx/req_idx.  But ONLY if this request
 		 * is in proper (pre-alloc'd) request buffer range...
 		 */
-		i = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
-		if (reqBytes >= 12 && i >= 0 && i < iocp->req_depth) {
+		ii = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
+		if (reqBytes >= 12 && ii >= 0 && ii < iocp->req_depth) {
 			MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
-			mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(i);
+			mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
 			mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
 		}
 
@@ -810,36 +990,40 @@
 				 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
 
 		/* Wait for IOC doorbell int */
-		if ((i = WaitForDoorbellInt(iocp, 2)) < 0) {
-			return i;
+		if ((ii = WaitForDoorbellInt(iocp, 2, sleepFlag)) < 0) {
+			return ii;
 		}
 
+		/* Read doorbell and check for active bit */
+		if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
+				return -5;
+
 		dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
-				iocp->name, i));
+				iocp->name, ii));
 
 		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
 
-		if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {
+		if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) {
 			return -2;
 		}
 
 		/* Send request via doorbell handshake */
 		req_as_bytes = (u8 *) req;
-		for (i = 0; i < reqBytes/4; i++) {
+		for (ii = 0; ii < reqBytes/4; ii++) {
 			u32 word;
 
-			word = ((req_as_bytes[(i*4) + 0] <<  0) |
-				(req_as_bytes[(i*4) + 1] <<  8) |
-				(req_as_bytes[(i*4) + 2] << 16) |
-				(req_as_bytes[(i*4) + 3] << 24));
+			word = ((req_as_bytes[(ii*4) + 0] <<  0) |
+				(req_as_bytes[(ii*4) + 1] <<  8) |
+				(req_as_bytes[(ii*4) + 2] << 16) |
+				(req_as_bytes[(ii*4) + 3] << 24));
 			CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
-			if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {
+			if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) {
 				r = -3;
 				break;
 			}
 		}
 
-		if ((r = WaitForDoorbellInt(iocp, 2)) >= 0)
+		if ((r = WaitForDoorbellInt(iocp, 10, sleepFlag)) >= 0)
 			r = 0;
 		else
 			r = -4;
@@ -871,8 +1055,8 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- * 	mpt_adapter_find_next - Find next MPT adapter pointer.
- * 	@prev: Pointer to previous MPT adapter
+ *	mpt_adapter_find_next - Find next MPT adapter pointer.
+ *	@prev: Pointer to previous MPT adapter
  *
  *	Returns next MPT adapter pointer or %NULL if there are no more.
  */
@@ -888,13 +1072,13 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
+/*
  *	mpt_pci_scan - Scan PCI devices for MPT adapters.
  *
  *	Returns count of MPT adapters found, keying off of PCI vendor and
  *	device_id's.
  */
-int __init
+static int __init
 mpt_pci_scan(void)
 {
 	struct pci_dev *pdev;
@@ -906,7 +1090,7 @@
 	dprintk((KERN_INFO MYNAM ": Checking for MPT adapters...\n"));
 
 	/*
-	 *  NOTE: The 929 (I believe) will appear as 2 separate PCI devices,
+	 *  NOTE: The 929 and 1030 will appear as 2 separate PCI devices,
 	 *  one for each channel.
 	 */
 	pci_for_each_dev(pdev) {
@@ -917,9 +1101,9 @@
 		if ((pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC909) &&
 		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929) &&
 		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919) &&
+		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
 #if 0
 		    /* FIXME! C103x family */
-		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
 		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030_ZC) &&
 		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1035) &&
 #endif
@@ -929,7 +1113,7 @@
 		}
 
 		/* GRRRRR
-		 * 929 dual function devices may be presented in Func 1,0 order,
+		 * dual function devices (929, 1030) may be presented in Func 1,0 order,
 		 * but we'd really really rather have them in Func 0,1 order.
 		 * Do some kind of look ahead here...
 		 */
@@ -937,11 +1121,11 @@
 			pdev2 = pci_peek_next_dev(pdev);
 			if (pdev2 && (pdev2->vendor == 0x1000) &&
 			    (PCI_SLOT(pdev2->devfn) == PCI_SLOT(pdev->devfn)) &&
-			    (pdev2->device == MPI_MANUFACTPAGE_DEVICEID_FC929) &&
+			    (pdev2->device == pdev->device) &&
 			    (pdev2->bus->number == pdev->bus->number) &&
 			    !(pdev2->devfn & 1)) {
 				dprintk((KERN_INFO MYNAM ": MPT adapter found: PCI bus/dfn=%02x/%02xh, class=%08x, id=%xh\n",
-			 		pdev2->bus->number, pdev2->devfn, pdev2->class, pdev2->device));
+					pdev2->bus->number, pdev2->devfn, pdev2->class, pdev2->device));
 				found++;
 				if ((r = mpt_adapter_install(pdev2)) == 0)
 					count++;
@@ -969,9 +1153,7 @@
 	}
 
 #ifdef CONFIG_PROC_FS
-	if (procmpt_create() != 0)
-		printk(KERN_WARNING MYNAM ": WARNING! - %s creation failed!\n",
-				MPT_PROCFS_MPTBASEDIR);
+	(void) procmpt_create();
 #endif
 
 	return count;
@@ -1004,7 +1186,7 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
+/*
  *	mpt_adapter_install - Install a PCI intelligent MPT adapter.
  *	@pdev: Pointer to pci_dev structure
  *
@@ -1030,7 +1212,7 @@
 	unsigned long	 port;
 	u32		 msize;
 	u32		 psize;
-	int		 i;
+	int		 ii;
 	int		 r = -ENODEV;
 	int		 len;
 
@@ -1040,41 +1222,68 @@
 		return -ENOMEM;
 	}
 	memset(ioc, 0, sizeof(*ioc));
-	ioc->req_sz = MPT_REQ_SIZE;			/* avoid div by zero! */
 	ioc->alloc_total = sizeof(MPT_ADAPTER);
+	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
+	ioc->reply_sz = ioc->req_sz;
 
 	ioc->pcidev = pdev;
+	ioc->diagPending = 0;
+	spin_lock_init(&ioc->diagLock);
+
+	/* Initialize the event logging.
+	 */
+	ioc->eventTypes = 0;	/* None */
+	ioc->eventContext = 0;
+	ioc->eventLogSize = 0;
+	ioc->events = NULL;
+
+#ifdef MFCNT
+	ioc->mfcnt = 0;
+#endif
+
+	/* Initialize the FW and Data image pointers.
+	 */
+	ioc->FWImage = NULL;
+	ioc->FWImage_dma = 0;
+
+	/* Initilize SCSI Config Data structure
+	 */
+	memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
+
+	/* Initialize the running configQ head.
+	 */
+	Q_INIT(&ioc->configQ, Q_ITEM);
 
 	/* Find lookup slot. */
-	for (i=0; i < MPT_MAX_ADAPTERS; i++) {
-		if (mpt_adapters[i] == NULL) {
-			ioc->id = i;		/* Assign adapter unique id (lookup) */
+	for (ii=0; ii < MPT_MAX_ADAPTERS; ii++) {
+		if (mpt_adapters[ii] == NULL) {
+			ioc->id = ii;		/* Assign adapter unique id (lookup) */
 			break;
 		}
 	}
-	if (i == MPT_MAX_ADAPTERS) {
-		printk(KERN_ERR MYNAM ": ERROR - mpt_adapters[%d] table overflow!\n", i);
+	if (ii == MPT_MAX_ADAPTERS) {
+		printk(KERN_ERR MYNAM ": ERROR - mpt_adapters[%d] table overflow!\n", ii);
 		kfree(ioc);
 		return -ENFILE;
 	}
 
 	mem_phys = msize = 0;
 	port = psize = 0;
-	for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
-		if (pdev->PCI_BASEADDR_FLAGS(i) & PCI_BASE_ADDRESS_SPACE_IO) {
+	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
+		if (pdev->PCI_BASEADDR_FLAGS(ii) & PCI_BASE_ADDRESS_SPACE_IO) {
 			/* Get I/O space! */
-			port = pdev->PCI_BASEADDR_START(i);
-			psize = PCI_BASEADDR_SIZE(pdev,i);
+			port = pdev->PCI_BASEADDR_START(ii);
+			psize = PCI_BASEADDR_SIZE(pdev,ii);
 		} else {
 			/* Get memmap */
-			mem_phys = pdev->PCI_BASEADDR_START(i);
-			msize = PCI_BASEADDR_SIZE(pdev,i);
+			mem_phys = pdev->PCI_BASEADDR_START(ii);
+			msize = PCI_BASEADDR_SIZE(pdev,ii);
 			break;
 		}
 	}
 	ioc->mem_size = msize;
 
-	if (i == DEVICE_COUNT_RESOURCE) {
+	if (ii == DEVICE_COUNT_RESOURCE) {
 		printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
 		kfree(ioc);
 		return -EINVAL;
@@ -1098,6 +1307,8 @@
 	}
 	dprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
 
+	dprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
+			&ioc->facts, &ioc->pfacts[0]));
 	if (PortIo) {
 		u8 *pmem = (u8*)port;
 		ioc->mem_phys = port;
@@ -1107,6 +1318,13 @@
 		ioc->chip = (SYSIF_REGS*)mem;
 	}
 
+	/* Save Port IO values incase we need to do downloadboot */
+	{
+		u8 *pmem = (u8*)port;
+		ioc->pio_mem_phys = port;
+		ioc->pio_chip = (SYSIF_REGS*)pmem;
+	}
+
 	ioc->chip_type = FCUNK;
 	if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
 		ioc->chip_type = FC909;
@@ -1120,12 +1338,19 @@
 		ioc->chip_type = FC919;
 		ioc->prod_name = "LSIFC919";
 	}
-#if 0
-	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_53C1030) {
+	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
 		ioc->chip_type = C1030;
 		ioc->prod_name = "LSI53C1030";
+		{
+			/* 1030 Chip Fix. Disable Split transactions
+			 * for PCIX. Set bits 4 - 6 to zero.
+			 */
+			u16 pcixcmd = 0;
+			pci_read_config_word(pdev, 0x6a, &pcixcmd);
+			pcixcmd &= 0xFF8F;
+			pci_write_config_word(pdev, 0x6a, pcixcmd);
+		}
 	}
-#endif
 
 	myname = "iocN";
 	len = strlen(myname);
@@ -1145,8 +1370,13 @@
 		r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
 
 		if (r < 0) {
-			printk(KERN_ERR MYNAM ": %s: ERROR - Unable to allocate interrupt %d!\n",
+#ifndef __sparc__
+			printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
 					ioc->name, pdev->irq);
+#else
+			printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
+					ioc->name, __irq_itoa(pdev->irq));
+#endif
 			iounmap(mem);
 			kfree(ioc);
 			return -EBUSY;
@@ -1156,7 +1386,11 @@
 
 		pci_set_master(pdev);			/* ?? */
 
+#ifndef __sparc__
 		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
+#else
+		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
+#endif
 	}
 
 	/* tack onto tail of our MPT adapter list */
@@ -1166,12 +1400,12 @@
 	mpt_adapters[ioc->id] = ioc;
 
 	/* NEW!  20010220 -sralston
-	 * Check for "929 bound ports" to reduce redundant resets.
+	 * Check for "bound ports" (929, 1030) to reduce redundant resets.
 	 */
-	if (ioc->chip_type == FC929)
-		mpt_detect_929_bound_ports(ioc, pdev);
+	if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030))
+		mpt_detect_bound_ports(ioc, pdev);
 
-	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
+	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
 		printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n",
 				ioc->name, r);
 	}
@@ -1180,10 +1414,11 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
+/*
  *	mpt_do_ioc_recovery - Initialize or recover MPT adapter.
  *	@ioc: Pointer to MPT adapter structure
  *	@reason: Event word / reason
+ *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
  *
  *	This routine performs all the steps necessary to bring the IOC
  *	to a OPERATIONAL state.
@@ -1191,16 +1426,21 @@
  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
  *	MPT adapter.
  *
- *	Returns 0 for success.
+ *	Returns:
+ *		 0 for success
+ *		-1 if failed to get board READY
+ *		-2 if READY but IOCFacts Failed
+ *		-3 if READY but PrimeIOCFifos Failed
+ *		-4 if READY but IOCInit Failed
  */
 static int
-mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason)
+mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 {
 	int	 hard_reset_done = 0;
 	int	 alt_ioc_ready = 0;
 	int	 hard;
 	int	 r;
-	int	 i;
+	int	 ii;
 	int	 handlers;
 
 	printk(KERN_INFO MYNAM ": Initiating %s %s\n",
@@ -1211,156 +1451,106 @@
 	ioc->active = 0;
 	/* NOTE: Access to IOC's request FreeQ is now blocked! */
 
-// FIXME? Cleanup all IOC requests here! (or below?)
-// But watch out for event associated request?
+	if (ioc->alt_ioc) {
+		/* Disable alt-IOC's reply interrupts for a bit ... */
+		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
+		ioc->alt_ioc->active = 0;
+		/* NOTE: Access to alt-IOC's request FreeQ is now blocked! */
+	}
 
-	hard = HardReset;
-	if (ioc->alt_ioc && (reason == MPT_HOSTEVENT_IOC_BRINGUP))
+	hard = 1;
+	if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
 		hard = 0;
 
-	if ((hard_reset_done = MakeIocReady(ioc, hard)) < 0) {
+	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
 		printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
 				ioc->name);
 		return -1;
 	}
 
-// NEW!
-#if 0						// Kiss-of-death!?!
-	if (ioc->alt_ioc) {
-// Grrr... Hold off any alt-IOC interrupts (and events) while
-// handshaking to <this> IOC, needed because?
-		/* Disable alt-IOC's reply interrupts for a bit ... */
-		alt_ioc_intmask = CHIPREG_READ32(&ioc->alt_ioc->chip->IntMask);
-		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
-		ioc->alt_ioc->active = 0;
-		/* NOTE: Access to alt-IOC's request FreeQ is now blocked! */
-	}
-#endif
-
+	/* hard_reset_done = 0 if a soft reset was performed
+	 * and 1 if a hard reset was performed.
+	 */
 	if (hard_reset_done && ioc->alt_ioc) {
-		if ((r = MakeIocReady(ioc->alt_ioc, 0)) == 0)
+		if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
 			alt_ioc_ready = 1;
 		else
-			printk(KERN_WARNING MYNAM ": alt-%s: (%d) Not ready WARNING!\n",
+			printk(KERN_WARNING MYNAM
+					": alt-%s: (%d) Not ready WARNING!\n",
 					ioc->alt_ioc->name, r);
 	}
 
+	/* Get IOC facts! */
+	if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0)
+		return -2;
 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
-		/* Get IOC facts! */
-		if ((r = GetIocFacts(ioc)) != 0)
-			return -2;
 		MptDisplayIocCapabilities(ioc);
 	}
 
-	/*
-	 * Call each currently registered protocol IOC reset handler
-	 * with pre-reset indication.
-	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
-	 * MptResetHandlers[] registered yet.
-	 */
-	if (hard_reset_done) {
-		r = handlers = 0;
-		for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
-			if (MptResetHandlers[i]) {
-				dprintk((KERN_INFO MYNAM ": %s: Calling IOC pre_reset handler #%d\n",
-						ioc->name, i));
-				r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_PRE_RESET);
-				handlers++;
-
-				if (alt_ioc_ready) {
-					dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC pre_reset handler #%d\n",
-							ioc->alt_ioc->name, i));
-					r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
-					handlers++;
-				}
-			}
-		}
-		/* FIXME?  Examine results here? */
-	}
-
-	// May need to check/upload firmware & data here!
-
-	if ((r = SendIocInit(ioc)) != 0)
-		return -3;
-// NEW!
 	if (alt_ioc_ready) {
-		if ((r = SendIocInit(ioc->alt_ioc)) != 0) {
-			alt_ioc_ready = 0;
-			printk(KERN_WARNING MYNAM ": alt-%s: (%d) init failure WARNING!\n",
-					ioc->alt_ioc->name, r);
-		}
-	}
-
-	/*
-	 * Call each currently registered protocol IOC reset handler
-	 * with post-reset indication.
-	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
-	 * MptResetHandlers[] registered yet.
-	 */
-	if (hard_reset_done) {
-		r = handlers = 0;
-		for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
-			if (MptResetHandlers[i]) {
-				dprintk((KERN_INFO MYNAM ": %s: Calling IOC post_reset handler #%d\n",
-						ioc->name, i));
-				r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_POST_RESET);
-				handlers++;
-
-				if (alt_ioc_ready) {
-					dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC post_reset handler #%d\n",
-							ioc->alt_ioc->name, i));
-					r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
-					handlers++;
-				}
-			}
+		if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0)
+			return -2;
+		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+			MptDisplayIocCapabilities(ioc->alt_ioc);
 		}
-		/* FIXME?  Examine results here? */
 	}
 
 	/*
 	 * Prime reply & request queues!
-	 * (mucho alloc's)
+	 * (mucho alloc's) Must be done prior to
+	 * init as upper addresses are needed for init.
 	 */
 	if ((r = PrimeIocFifos(ioc)) != 0)
+		return -3;
+
+	// May need to check/upload firmware & data here!
+	if ((r = SendIocInit(ioc, sleepFlag)) != 0)
 		return -4;
 // NEW!
 	if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
 		printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
 				ioc->alt_ioc->name, r);
+		alt_ioc_ready = 0;
 	}
 
-// FIXME! Cleanup all IOC (and alt-IOC?) requests here!
+	if (alt_ioc_ready) {
+		if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
+			alt_ioc_ready = 0;
+			printk(KERN_WARNING MYNAM
+				": alt-%s: (%d) init failure WARNING!\n",
+					ioc->alt_ioc->name, r);
+		}
+	}
 
-	if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
-	    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
-		/*
-		 *  Pre-fetch the ports LAN MAC address!
-		 *  (LANPage1_t stuff)
-		 */
-		(void) GetLanConfigPages(ioc);
-#ifdef MPT_DEBUG
-		{
-			u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
-			dprintk((KERN_INFO MYNAM ": %s: LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
-					ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
+	if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
+		if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
+			dprintk((MYIOC_s_INFO_FMT
+				"firmware upload required!\n", ioc->name));
+
+			r = mpt_do_upload(ioc, sleepFlag);
+			if (r != 0)
+				printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
+			/* Handle the alt IOC too */
+			if (alt_ioc_ready){
+				r = mpt_do_upload(ioc->alt_ioc, sleepFlag);
+				if (r != 0)
+					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
+			}
 		}
-#endif
 	}
 
+
 	/* Enable! (reply interrupt) */
 	CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
 	ioc->active = 1;
 
-// NEW!
-#if 0						// Kiss-of-death!?!
-	if (alt_ioc_ready && (r==0)) {
+	if (ioc->alt_ioc) {
 		/* (re)Enable alt-IOC! (reply interrupt) */
 		dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
 				ioc->alt_ioc->name));
 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
 		ioc->alt_ioc->active = 1;
 	}
-#endif
 
 	/* NEW!  20010120 -sralston
 	 *  Enable MPT base driver management of EventNotification
@@ -1368,19 +1558,95 @@
 	 */
 	if (!ioc->facts.EventState)
 		(void) SendEventNotification(ioc, 1);	/* 1=Enable EventNotification */
-// NEW!
-// FIXME!?!
-//	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) {
-//		(void) SendEventNotification(ioc->alt_ioc, 1);	/* 1=Enable EventNotification */
-//	}
+
+	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
+		(void) SendEventNotification(ioc->alt_ioc, 1);	/* 1=Enable EventNotification */
+
+	/* (Bugzilla:fibrebugs, #513)
+	 * Bug fix (part 2)!  20010905 -sralston
+	 *	Add additional "reason" check before call to GetLanConfigPages
+	 *	(combined with GetIoUnitPage2 call).  This prevents a somewhat
+	 *	recursive scenario; GetLanConfigPages times out, timer expired
+	 *	routine calls HardResetHandler, which calls into here again,
+	 *	and we try GetLanConfigPages again...
+	 */
+	if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+		if ((int)ioc->chip_type <= (int)FC929) {
+			/*
+			 *  Pre-fetch FC port WWN and stuff...
+			 *  (FCPortPage0_t stuff)
+			 */
+			for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
+				(void) GetFcPortPage0(ioc, ii);
+			}
+
+			if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
+			    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
+				/*
+				 *  Pre-fetch the ports LAN MAC address!
+				 *  (LANPage1_t stuff)
+				 */
+				(void) GetLanConfigPages(ioc);
+#ifdef MPT_DEBUG
+				{
+					u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
+					dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
+							ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
+				}
+#endif
+			}
+		} else {
+			/* Get NVRAM and adapter maximums from SPP 0 and 2
+			 */
+			mpt_GetScsiPortSettings(ioc, 0);
+
+			/* Get version and length of SDP 1 
+			 */
+			mpt_readScsiDevicePageHeaders(ioc, 0);
+
+			/* Find IM volumes 
+			 */
+			if (ioc->facts.MsgVersion >= 0x0102)
+				mpt_findImVolumes(ioc);
+		}
+
+		GetIoUnitPage2(ioc);
+	}
+
+	/*
+	 * Call each currently registered protocol IOC reset handler
+	 * with post-reset indication.
+	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
+	 * MptResetHandlers[] registered yet.
+	 */
+	if (hard_reset_done) {
+		r = handlers = 0;
+		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
+			if (MptResetHandlers[ii]) {
+				dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
+						ioc->name, ii));
+				r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
+				handlers++;
+
+				if (alt_ioc_ready) {
+					dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
+							ioc->name, ioc->alt_ioc->name, ii));
+					r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
+					handlers++;
+				}
+			}
+		}
+		/* FIXME?  Examine results here? */
+	}
 
 	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mpt_detect_929_bound_ports - Search for PCI bus/dev_function
- *	which matches PCI bus/dev_function (+/-1) for newly discovered 929.
+ *	mpt_detect_bound_ports - Search for PCI bus/dev_function
+ *	which matches PCI bus/dev_function (+/-1) for newly discovered 929
+ *	or 1030.
  *	@ioc: Pointer to MPT adapter structure
  *	@pdev: Pointer to (struct pci_dev) structure
  *
@@ -1388,22 +1654,22 @@
  *	using alt_ioc pointer fields in their %MPT_ADAPTER structures.
  */
 static void
-mpt_detect_929_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
+mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
 {
 	MPT_ADAPTER *ioc_srch = mpt_adapter_find_first();
 	unsigned int match_lo, match_hi;
 
 	match_lo = pdev->devfn-1;
 	match_hi = pdev->devfn+1;
-	dprintk((KERN_INFO MYNAM ": %s: PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
+	dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
 			ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));
 
 	while (ioc_srch != NULL) {
 		struct pci_dev *_pcidev = ioc_srch->pcidev;
 
-		if ( (_pcidev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) &&
-		     (_pcidev->bus->number == pdev->bus->number) &&
-		     (_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {
+		if ((_pcidev->device == pdev->device) &&
+		    (_pcidev->bus->number == pdev->bus->number) &&
+		    (_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {
 			/* Paranoia checks */
 			if (ioc->alt_ioc != NULL) {
 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
@@ -1418,8 +1684,6 @@
 					ioc->name, ioc_srch->name));
 			ioc_srch->alt_ioc = ioc;
 			ioc->alt_ioc = ioc_srch;
-			ioc->sod_reset = ioc->alt_ioc->sod_reset;
-			ioc->last_kickstart = ioc->alt_ioc->last_kickstart;
 			break;
 		}
 		ioc_srch = mpt_adapter_find_next(ioc_srch);
@@ -1440,10 +1704,10 @@
 		u32 state;
 
 		/* Disable the FW */
-		state = GetIocState(this, 1);
+		state = mpt_GetIocState(this, 1);
 		if (state == MPI_IOC_STATE_OPERATIONAL) {
-			if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) != 0)
-				(void) KickStart(this, 1);
+			if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP) != 0)
+				(void) KickStart(this, 1, NO_SLEEP);
 		}
 
 		/* Disable adapter interrupts! */
@@ -1475,12 +1739,37 @@
 		}
 
 		if (freeup && this->sense_buf_pool != NULL) {
-			sz = (this->req_depth * 256);
+			sz = (this->req_depth * MPT_SENSE_BUFFER_ALLOC);
 			pci_free_consistent(this->pcidev, sz,
 					this->sense_buf_pool, this->sense_buf_pool_dma);
 			this->sense_buf_pool = NULL;
 			this->alloc_total -= sz;
 		}
+
+		if (freeup && this->events != NULL){
+			sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
+			kfree(this->events);
+			this->events = NULL;
+			this->alloc_total -= sz;
+		}
+
+		if (freeup && this->FWImage != NULL) {
+			sz = this->facts.FWImageSize;
+			pci_free_consistent(this->pcidev, sz,
+					this->FWImage, this->FWImage_dma);
+			this->FWImage = NULL;
+			this->alloc_total -= sz;
+		}
+
+		if (freeup && this->spi_data.nvram != NULL) {
+			kfree(this->spi_data.nvram);
+			this->spi_data.nvram = NULL;
+		}
+
+		if (freeup && this->spi_data.pIocPg3 != NULL) {
+			kfree(this->spi_data.pIocPg3);
+			this->spi_data.pIocPg3 = NULL;
+		}
 	}
 }
 
@@ -1575,23 +1864,30 @@
 /*
  *	MakeIocReady - Get IOC to a READY state, using KickStart if needed.
  *	@ioc: Pointer to MPT_ADAPTER structure
- *	@kick: Force hard KickStart of IOC
+ *	@force: Force hard KickStart of IOC
+ *	@sleepFlag: Specifies whether the process can sleep
  *
- *	Returns 0 for already-READY, 1 for hard reset success,
- *	else negative for failure.
+ *	Returns:
+ *		 1 - DIAG reset and READY
+ *		 0 - READY initially OR soft reset and READY 
+ *		-1 - Any failure on KickStart 
+ *		-2 - Msg Unit Reset Failed
+ *		-3 - IO Unit Reset Failed
+ *		-4 - IOC owned by a PEER
  */
 static int
-MakeIocReady(MPT_ADAPTER *ioc, int force)
+MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
 {
 	u32	 ioc_state;
 	int	 statefault = 0;
-	int 	 cntdn;
+	int	 cntdn;
 	int	 hard_reset_done = 0;
 	int	 r;
-	int	 i;
+	int	 ii;
+	int	 whoinit;
 
 	/* Get current [raw] IOC state  */
-	ioc_state = GetIocState(ioc, 0);
+	ioc_state = mpt_GetIocState(ioc, 0);
 	dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
 
 	/*
@@ -1600,7 +1896,7 @@
 	 */
 	if (ioc_state & MPI_DOORBELL_ACTIVE) {
 		statefault = 1;
-		printk(KERN_WARNING MYNAM ": %s: Uh-oh, unexpected doorbell active!\n",
+		printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
 				ioc->name);
 	}
 
@@ -1613,7 +1909,7 @@
 	 */
 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
 		statefault = 2;
-		printk(KERN_WARNING MYNAM ": %s: Uh-oh, IOC is in FAULT state!!!\n",
+		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
 				ioc->name);
 		printk(KERN_WARNING "           FAULT code = %04xh\n",
 				ioc_state & MPI_DOORBELL_DATA_MASK);
@@ -1623,28 +1919,49 @@
 	 *	Hmmm...  Did it get left operational?
 	 */
 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
-		statefault = 3;
-		dprintk((KERN_WARNING MYNAM ": %s: Hmmm... IOC operational unexpected\n",
+		dprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
 				ioc->name));
+
+		/* Check WhoInit.
+		 * If PCI Peer, exit.
+		 * Else, if no fault conditions are present, issue a MessageUnitReset
+		 * Else, fall through to KickStart case
+		 */
+		whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
+		dprintk((KERN_WARNING MYNAM
+			": whoinit 0x%x\n statefault %d force %d\n",
+			whoinit, statefault, force));
+		if (whoinit == MPI_WHOINIT_PCI_PEER)
+			return -4;
+		else {
+			if ((statefault == 0 ) && (force == 0)) {
+				if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
+					return 0;
+			}
+			statefault = 3;
+		}
 	}
 
-	hard_reset_done = KickStart(ioc, statefault||force);
+	hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
 	if (hard_reset_done < 0)
 		return -1;
 
 	/*
 	 *  Loop here waiting for IOC to come READY.
 	 */
-	i = 0;
+	ii = 0;
 	cntdn = HZ * 15;
-	while ((ioc_state = GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
+	if (sleepFlag != CAN_SLEEP)
+		cntdn *= 10;	/* 1500 iterations @ 1msec per */
+
+	while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
 		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
 			/*
 			 *  BIOS or previous driver load left IOC in OP state.
 			 *  Reset messaging FIFOs.
 			 */
-			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)) != 0) {
-				printk(KERN_ERR MYNAM ": %s: ERROR - IOC msg unit reset failed!\n", ioc->name);
+			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
+				printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
 				return -2;
 			}
 		} else if (ioc_state == MPI_IOC_STATE_RESET) {
@@ -1652,25 +1969,30 @@
 			 *  Something is wrong.  Try to get IOC back
 			 *  to a known state.
 			 */
-			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET)) != 0) {
-				printk(KERN_ERR MYNAM ": %s: ERROR - IO unit reset failed!\n", ioc->name);
+			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
+				printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
 				return -3;
 			}
 		}
 
-		i++; cntdn--;
+		ii++; cntdn--;
 		if (!cntdn) {
-			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
-					ioc->name, (i+5)/HZ);
+			printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
+					ioc->name, (ii+5)/HZ);
 			return -ETIME;
 		}
 
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
+		if (sleepFlag == CAN_SLEEP) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		} else {
+			mdelay (1);	/* 1 msec delay */
+		}
+
 	}
 
 	if (statefault < 3) {
-		printk(KERN_WARNING MYNAM ": %s: Whew!  Recovered from %s\n",
+		printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
 				ioc->name,
 				statefault==1 ? "stuck handshake" : "IOC FAULT");
 	}
@@ -1680,21 +2002,21 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	GetIocState - Get the current state of a MPT adapter.
+ *	mpt_GetIocState - Get the current state of a MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@cooked: Request raw or cooked IOC state
  *
  *	Returns all IOC Doorbell register bits if cooked==0, else just the
  *	Doorbell bits in MPI_IOC_STATE_MASK.
  */
-static u32
-GetIocState(MPT_ADAPTER *ioc, int cooked)
+u32
+mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
 {
 	u32 s, sc;
 
 	/*  Get!  */
 	s = CHIPREG_READ32(&ioc->chip->Doorbell);
-	dprintk((KERN_INFO MYNAM ": %s: raw state = %08x\n", ioc->name, s));
+//	dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
 	sc = s & MPI_IOC_STATE_MASK;
 
 	/*  Save!  */
@@ -1707,11 +2029,13 @@
 /*
  *	GetIocFacts - Send IOCFacts request to MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@sleepFlag: Specifies whether the process can sleep
+ *	@reason: If recovery, only update facts.
  *
  *	Returns 0 for success, non-zero for failure.
  */
 static int
-GetIocFacts(MPT_ADAPTER *ioc)
+GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
 {
 	IOCFacts_t		 get_facts;
 	IOCFactsReply_t		*facts;
@@ -1741,14 +2065,13 @@
 	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
 	/* Assert: All other get_facts fields are zero! */
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending get IocFacts request\n", ioc->name));
+	dprintk((MYIOC_s_INFO_FMT "Sending get IocFacts request\n", ioc->name));
 
 	/* No non-zero fields in the get_facts request are greater than
 	 * 1 byte in size, so we can just fire it off as is.
 	 */
-	r = HandShakeReqAndReply(ioc,
-			req_sz, (u32*)&get_facts,
-			reply_sz, (u16*)facts, 3);
+	r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
+			reply_sz, (u16*)facts, 3 /*seconds*/, sleepFlag);
 	if (r != 0)
 		return r;
 
@@ -1761,14 +2084,17 @@
 	 */
 	/* Did we get a valid reply? */
 	if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
-		/*
-		 * If not been here, done that, save off first WhoInit value
-		 */
-		if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
-			ioc->FirstWhoInit = facts->WhoInit;
+		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+			/*
+			 * If not been here, done that, save off first WhoInit value
+			 */
+			if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
+				ioc->FirstWhoInit = facts->WhoInit;
+		}
 
 		facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
 		facts->MsgContext = le32_to_cpu(facts->MsgContext);
+		facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
 		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
 		facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
 		status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
@@ -1776,7 +2102,23 @@
 
 		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
 		facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
-		facts->FWVersion = le16_to_cpu(facts->FWVersion);
+
+		/*
+		 * FC f/w version changed between 1.1 and 1.2 
+		 *	Old: u16{Major(4),Minor(4),SubMinor(8)}
+		 *	New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
+		 */
+		if (facts->MsgVersion < 0x0102) {
+			/*
+			 *	Handle old FC f/w style, convert to new...
+			 */
+			u16	 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
+			facts->FWVersion.Word =
+					((oldv<<12) & 0xFF000000) |
+					((oldv<<8)  & 0x000FFF00);
+		} else
+			facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
+
 		facts->ProductID = le16_to_cpu(facts->ProductID);
 		facts->CurrentHostMfaHighAddr =
 				le32_to_cpu(facts->CurrentHostMfaHighAddr);
@@ -1791,52 +2133,42 @@
 		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
 		 * to 14 in MPI-1.01.0x.
 		 */
-		if (facts->MsgLength >= sizeof(IOCFactsReply_t)/sizeof(u32) && facts->MsgVersion > 0x0100) {
+		if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
+		    facts->MsgVersion > 0x0100) {
 			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
-			facts->DataImageSize = le32_to_cpu(facts->DataImageSize);
 		}
 
-		if (facts->RequestFrameSize) {
-			/*
-			 * Set values for this IOC's REQUEST queue size & depth...
-			 */
-			ioc->req_sz = MIN(MPT_REQ_SIZE, facts->RequestFrameSize * 4);
-
-			/*
-			 *  Set values for this IOC's REPLY queue size & depth...
-			 *
-			 * BUG? FIX?  20000516 -nromer & sralston 
-			 *  GRRR...  The following did not translate well from MPI v0.09:
-			 *	ioc->reply_sz = MIN(MPT_REPLY_SIZE, facts->ReplySize * 4);
-			 *  to 0.10:
-			 *	ioc->reply_sz = MIN(MPT_REPLY_SIZE, facts->BlockSize * 4);
-			 *  Was trying to minimally optimize to smallest possible reply size
-			 *  (and greatly reduce kmalloc size).  But LAN may need larger reply?
-			 *
-			 *  So for now, just set reply size to request size.  FIXME?
-			 */
-			ioc->reply_sz = ioc->req_sz;
-		} else {
+		if (!facts->RequestFrameSize) {
 			/*  Something is wrong!  */
-			printk(KERN_ERR MYNAM ": %s: ERROR - IOC reported invalid 0 request size!\n",
+			printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
 					ioc->name);
-			ioc->req_sz = MPT_REQ_SIZE;
-			ioc->reply_sz = MPT_REPLY_SIZE;
 			return -55;
 		}
-		ioc->req_depth = MIN(MPT_REQ_DEPTH, facts->GlobalCredits);
-		ioc->reply_depth = MIN(MPT_REPLY_DEPTH, facts->ReplyQueueDepth);
 
-		dprintk((KERN_INFO MYNAM ": %s: reply_sz=%3d, reply_depth=%4d\n",
+		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+			/*
+			 * Set values for this IOC's request & reply frame sizes,
+			 * and request & reply queue depths...
+			 */
+			ioc->req_sz = MIN(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
+			ioc->req_depth = MIN(MPT_DEFAULT_REQ_DEPTH, facts->GlobalCredits);
+			ioc->reply_sz = ioc->req_sz;
+			ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
+
+			/* 1030 - should we use a smaller DEFAULT_REPLY_DEPTH?
+			 * FIX
+			 */
+			dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
 				ioc->name, ioc->reply_sz, ioc->reply_depth));
-		dprintk((KERN_INFO MYNAM ": %s: req_sz  =%3d, req_depth  =%4d\n",
+			dprintk((MYIOC_s_INFO_FMT "req_sz  =%3d, req_depth  =%4d\n",
 				ioc->name, ioc->req_sz, ioc->req_depth));
 
-		/* Get port facts! */
-		if ( (r = GetPortFacts(ioc, 0)) != 0 )
-			return r;
+			/* Get port facts! */
+			if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
+				return r;
+		}
 	} else {
-		printk(KERN_ERR MYNAM ": %s: ERROR - Invalid IOC facts reply!\n",
+		printk(MYIOC_s_ERR_FMT "Invalid IOC facts reply!\n",
 				ioc->name);
 		return -66;
 	}
@@ -1849,15 +2181,16 @@
  *	GetPortFacts - Send PortFacts request to MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@portnum: Port number
+ *	@sleepFlag: Specifies whether the process can sleep
  *
  *	Returns 0 for success, non-zero for failure.
  */
 static int
-GetPortFacts(MPT_ADAPTER *ioc, int portnum)
+GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
 {
 	PortFacts_t		 get_pfacts;
 	PortFactsReply_t	*pfacts;
-	int			 i;
+	int			 ii;
 	int			 req_sz;
 	int			 reply_sz;
 
@@ -1883,16 +2216,16 @@
 	get_pfacts.PortNumber = portnum;
 	/* Assert: All other get_pfacts fields are zero! */
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending get PortFacts(%d) request\n",
+	dprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
 			ioc->name, portnum));
 
 	/* No non-zero fields in the get_pfacts request are greater than
 	 * 1 byte in size, so we can just fire it off as is.
 	 */
-	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&get_pfacts,
-				reply_sz, (u16*)pfacts, 3);
-	if (i != 0)
-		return i;
+	ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
+				reply_sz, (u16*)pfacts, 3 /*seconds*/, sleepFlag);
+	if (ii != 0)
+		return ii;
 
 	/* Did we get a valid reply? */
 
@@ -1914,13 +2247,14 @@
 /*
  *	SendIocInit - Send IOCInit request to MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@sleepFlag: Specifies whether the process can sleep
  *
  *	Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
  *
  *	Returns 0 for success, non-zero for failure.
  */
 static int
-SendIocInit(MPT_ADAPTER *ioc)
+SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
 {
 	IOCInit_t		 ioc_init;
 	MPIDefaultReply_t	 init_reply;
@@ -1937,20 +2271,35 @@
 	ioc_init.Function = MPI_FUNCTION_IOC_INIT;
 /*	ioc_init.Flags = 0;				*/
 
-	/*ioc_init.MaxDevices = 16;*/
-	ioc_init.MaxDevices = 255;
-/*	ioc_init.MaxBuses = 16;				*/
-	ioc_init.MaxBuses = 1;
+	if ((int)ioc->chip_type <= (int)FC929) {
+		ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
+	}
+	else {
+		ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
+	}
+	ioc_init.MaxBuses = MPT_MAX_BUS;
 
 /*	ioc_init.MsgFlags = 0;				*/
 /*	ioc_init.MsgContext = cpu_to_le32(0x00000000);	*/
 	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */
-	ioc_init.HostMfaHighAddr = cpu_to_le32(0);	/* Say we 32-bit! for now */
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending IOCInit (req @ %p)\n", ioc->name, &ioc_init));
+#ifdef __ia64__
+	/* Save the upper 32-bits of the request
+	 * (reply) and sense buffers.
+	 */
+	ioc_init.HostMfaHighAddr = cpu_to_le32((u32)(ioc->req_frames_dma >> 32));
+	ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)(ioc->sense_buf_pool_dma >> 32));
+#else
+	/* Force 32-bit addressing */
+	ioc_init.HostMfaHighAddr = cpu_to_le32(0);
+	ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
+#endif
 
-	r = HandShakeReqAndReply(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
-			sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10);
+	dprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
+			ioc->name, &ioc_init));
+
+	r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
+				sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
 	if (r != 0)
 		return r;
 
@@ -1958,7 +2307,7 @@
 	 * since we don't even look at it's contents.
 	 */
 
-	if ((r = SendPortEnable(ioc, 0)) != 0)
+	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
 		return r;
 
 	/* YIKES!  SUPER IMPORTANT!!!
@@ -1967,21 +2316,27 @@
 	 */
 	count = 0;
 	cntdn = HZ * 60;					/* chg'd from 30 to 60 seconds */
-	state = GetIocState(ioc, 1);
+	if (sleepFlag != CAN_SLEEP)
+		cntdn *= 10;					/* scale for 1msec delays */
+	state = mpt_GetIocState(ioc, 1);
 	while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
+		if (sleepFlag == CAN_SLEEP) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		} else {
+			mdelay(1);
+		}
 
 		if (!cntdn) {
-			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_OP state timeout(%d)!\n",
+			printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
 					ioc->name, (count+5)/HZ);
 			return -9;
 		}
 
-		state = GetIocState(ioc, 1);
+		state = mpt_GetIocState(ioc, 1);
 		count++;
 	}
-	dhsprintk((KERN_INFO MYNAM ": %s: INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
+	dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
 			ioc->name, count));
 
 	return r;
@@ -1992,17 +2347,18 @@
  *	SendPortEnable - Send PortEnable request to MPT adapter port.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@portnum: Port number to enable
+ *	@sleepFlag: Specifies whether the process can sleep
  *
  *	Send PortEnable to bring IOC to OPERATIONAL state.
  *
  *	Returns 0 for success, non-zero for failure.
  */
 static int
-SendPortEnable(MPT_ADAPTER *ioc, int portnum)
+SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
 {
 	PortEnable_t		 port_enable;
 	MPIDefaultReply_t	 reply_buf;
-	int	 i;
+	int	 ii;
 	int	 req_sz;
 	int	 reply_sz;
 
@@ -2019,13 +2375,21 @@
 /*	port_enable.MsgFlags = 0;		*/
 /*	port_enable.MsgContext = 0;		*/
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending Port(%d)Enable (req @ %p)\n",
+	dprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
 			ioc->name, portnum, &port_enable));
 
-	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&port_enable,
-			reply_sz, (u16*)&reply_buf, 65);
-	if (i != 0)
-		return i;
+	/* RAID FW may take a long time to enable
+	 */
+	if ((int)ioc->chip_type <= (int)FC929) {
+		ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
+				reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
+	} else {
+		ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
+				reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
+	}
+
+	if (ii != 0)
+		return ii;
 
 	/* We do not even look at the reply, so we need not
 	 * swap the multi-byte fields.
@@ -2036,19 +2400,341 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
+ *	mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@sleepFlag: Specifies whether the process can sleep
+ *
+ *	Returns 0 for success, >0 for handshake failure
+ *		<0 for fw upload failure.
+ *
+ *	Remark: If bound IOC and a successful FWUpload was performed
+ *	on the bound IOC, the second image is discarded
+ *	and memory is free'd. Both channels must upload to prevent
+ *	IOC from running in degraded mode.
+ */
+static int
+mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
+{
+	u8			 request[sizeof(FWUpload_t) +  24];
+	u8			 reply[sizeof(FWUploadReply_t)];
+	FWUpload_t		*prequest;
+	FWUploadReply_t		*preply;
+	FWUploadTCSGE_t		*ptcsge = NULL;
+	MptSge_t		*psge;
+	u8			*mem;
+	dma_addr_t		 dma_addr;
+	int			 sgeoffset;
+	int			 i, sz, req_sz, reply_sz;
+	int			 cmdStatus, freeMem = 0;
+
+	/* If the image size is 0 or if the pointer is
+	 * not NULL (error), we are done.
+	 */
+	if (((sz = ioc->facts.FWImageSize) == 0) || ioc->FWImage)
+		return 0;
+
+	/* Allocate memory
+	 */
+	mem = pci_alloc_consistent(ioc->pcidev, sz, &ioc->FWImage_dma);
+	if (mem == NULL)
+		return -1;
+
+	memset(mem, 0, sz);
+	ioc->alloc_total += sz;
+	ioc->FWImage = mem;
+	dprintk((KERN_INFO MYNAM ": FW Image  @ %p[%p], sz=%d bytes\n",
+			mem, (void *)(ulong)ioc->FWImage_dma, sz));
+
+	dma_addr = ioc->FWImage_dma;
+
+	prequest = (FWUpload_t *)&request;
+	preply = (FWUploadReply_t *)&reply;
+
+	/*  Destination...  */
+	req_sz = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION)
+			+ sizeof(FWUploadTCSGE_t) + sizeof(MptSge_t);
+	memset(prequest, 0, req_sz);
+
+	reply_sz = sizeof(reply);
+	memset(preply, 0, reply_sz);
+
+	prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
+	prequest->Function = MPI_FUNCTION_FW_UPLOAD;
+	prequest->MsgContext = 0;		/* anything */
+
+	ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
+	ptcsge->Reserved = 0;
+	ptcsge->ContextSize = 0;
+	ptcsge->DetailsLength = 12;
+	ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
+	ptcsge->Reserved1 = 0;
+	ptcsge->ImageOffset = 0;
+	ptcsge->ImageSize = cpu_to_le32(sz);
+
+	sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
+	psge = (MptSge_t *) &request[sgeoffset];
+	psge->FlagsLength = cpu_to_le32(MPT_SGE_FLAGS_SSIMPLE_READ | (u32) sz);
+
+	cpu_to_leXX(dma_addr, psge->Address);
+
+	dprintk((MYIOC_s_INFO_FMT "Sending FW Upload (req @ %p)\n",
+			ioc->name, prequest));
+
+	i = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)prequest,
+				reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
+
+	cmdStatus = -EFAULT;
+	if (i == 0) {
+		/* Handshake transfer was complete and successful.
+		 * Check the Reply Frame.
+		 */
+		int status, transfer_sz;
+		status = le16_to_cpu(preply->IOCStatus);
+		if (status == MPI_IOCSTATUS_SUCCESS) {
+			transfer_sz = le32_to_cpu(preply->ActualImageSize);
+			if (transfer_sz == sz)
+				cmdStatus = 0;
+		}
+	}
+	dprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
+			ioc->name, cmdStatus));
+
+	/* Check to see if we have a copy of this image in
+	 * host memory already.
+	 */
+	if (cmdStatus == 0) {
+		if (ioc->alt_ioc && ioc->alt_ioc->FWImage)
+			freeMem = 1;
+	}
+
+	/* We already have a copy of this image or
+	 * we had some type of an error  - either the handshake
+	 * failed (i != 0) or the command did not complete successfully.
+	 */
+	if (cmdStatus || freeMem) {
+		dprintk((MYIOC_s_INFO_FMT ": do_upload freeing %s image \n",
+			ioc->name, cmdStatus ? "incomplete" : "duplicate"));
+
+		pci_free_consistent(ioc->pcidev, sz,
+					ioc->FWImage, ioc->FWImage_dma);
+		ioc->FWImage = NULL;
+		ioc->alloc_total -= sz;
+	}
+
+	return cmdStatus;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mpt_downloadboot - DownloadBoot code
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@flag: Specify which part of IOC memory is to be uploaded.
+ *	@sleepFlag: Specifies whether the process can sleep
+ *
+ *	FwDownloadBoot requires Programmed IO access.
+ *
+ *	Returns 0 for success
+ *		-1 FW Image size is 0
+ *		-2 No valid FWImage Pointer
+ *		<0 for fw upload failure.
+ */
+static int
+mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
+{
+	MpiFwHeader_t		*FwHdr = NULL;
+	MpiExtImageHeader_t 	*ExtHdr;
+	int			 fw_sz;
+	u32			 diag0val;
+#ifdef MPT_DEBUG
+	u32			 diag1val = 0;
+#endif
+	int			 count = 0;
+	u32			*ptru32 = NULL;
+	u32			 diagRwData;
+	u32			 nextImage;
+
+	dprintk((MYIOC_s_INFO_FMT "DbGb0: downloadboot entered.\n",
+				ioc->name));
+#ifdef MPT_DEBUG
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+	if (ioc->alt_ioc)
+		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+	dprintk((MYIOC_s_INFO_FMT "DbGb1: diag0=%08x, diag1=%08x\n",
+				ioc->name, diag0val, diag1val));
+#endif
+
+	dprintk((MYIOC_s_INFO_FMT "fw size 0x%x, ioc FW Ptr %p\n",
+				ioc->name, ioc->facts.FWImageSize, ioc->FWImage));
+	if (ioc->alt_ioc)
+		dprintk((MYIOC_s_INFO_FMT "alt ioc FW Ptr %p\n",
+				ioc->name, ioc->alt_ioc->FWImage));
+
+	/* Get dma_addr and data transfer size.
+	 */
+	if ((fw_sz = ioc->facts.FWImageSize) == 0)
+		return -1;
+
+	/* Get the DMA from ioc or ioc->alt_ioc */
+	if (ioc->FWImage)
+		FwHdr = (MpiFwHeader_t *)ioc->FWImage;
+	else if (ioc->alt_ioc && ioc->alt_ioc->FWImage)
+		FwHdr = (MpiFwHeader_t *)ioc->alt_ioc->FWImage;
+
+	dprintk((MYIOC_s_INFO_FMT "DbGb2: FW Image @ %p\n",
+			ioc->name, FwHdr));
+
+	if (!FwHdr)
+		return -2;
+
+	/* Write magic sequence to WriteSequence register
+	 * until enter diagnostic mode
+	 */
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+	while ((diag0val & MPI_DIAG_DRWE) == 0) {
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+
+		/* wait 100 msec */
+		if (sleepFlag == CAN_SLEEP) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(100 * HZ / 1000);
+		} else {
+			mdelay (100);
+		}
+
+		count++;
+		if (count > 20) {
+			printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
+					ioc->name, diag0val);
+			return -EFAULT;
+
+		}
+
+		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+		if (ioc->alt_ioc)
+			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+		dprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
+				ioc->name, diag0val, diag1val));
+#endif
+		dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
+				ioc->name, diag0val));
+	}
+
+	/* Set the DiagRwEn and Disable ARM bits */
+	diag0val |= (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM);
+	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
+
+#ifdef MPT_DEBUG
+	if (ioc->alt_ioc)
+		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+	dprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
+			ioc->name, diag0val, diag1val));
+#endif
+
+	/* Write the LoadStartAddress to the DiagRw Address Register
+	 * using Programmed IO
+	 */
+
+	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, FwHdr->LoadStartAddress);
+	dprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
+		ioc->name, FwHdr->LoadStartAddress));
+
+	nextImage = FwHdr->NextImageHeaderOffset;
+
+	/* round up count to a 32bit alignment */
+	ptru32 = (u32 *) FwHdr;
+	count = (FwHdr->ImageSize + 3)/4;
+
+	dprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x u32's @ %p\n",
+				ioc->name, count, ptru32));
+	while (count-- ) {
+		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptru32);
+		ptru32++;
+	}
+
+	dprintk((MYIOC_s_INFO_FMT "FW Image done! \n", ioc->name));
+		
+	while (nextImage) {
+
+		/* Set the pointer to the extended image
+		 */
+		ExtHdr = (MpiExtImageHeader_t *) ((char *) FwHdr + nextImage);
+
+		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, ExtHdr->LoadStartAddress);
+
+		count = (ExtHdr->ImageSize + 3 )/4;
+
+		ptru32 = (u32 *) ExtHdr;
+		dprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x u32's @ %p\n",
+				ioc->name, count, ptru32));
+		while (count-- ) {
+			CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptru32);
+			ptru32++;
+		}
+		nextImage = ExtHdr->NextImageHeaderOffset;
+	}
+
+
+	/* Write the IopResetVectorRegAddr */
+	dprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr! \n", ioc->name));
+	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, FwHdr->IopResetRegAddr);
+
+	/* Write the IopResetVectorValue */
+	dprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value! \n", ioc->name));
+	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, FwHdr->IopResetVectorValue);
+
+	/* Clear the internal flash bad bit - autoincrementing register,
+	 * so must do two writes.
+	 */
+	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
+	diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
+	diagRwData |= 0x4000000;
+	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
+	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
+
+	/* clear the RW enable and DISARM bits */
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+	diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_FLASH_BAD_SIG);
+	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
+
+	/* Write 0xFF to reset the sequencer */
+	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
  *	KickStart - Perform hard reset of MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@force: Force hard reset
+ *	@sleepFlag: Specifies whether the process can sleep
  *
  *	This routine places MPT adapter in diagnostic mode via the
  *	WriteSequence register, and then performs a hard reset of adapter
  *	via the Diagnostic register.
  *
- *	Returns 0 for soft reset success, 1 for hard reset success,
- *	else a negative value for failure.
+ *	Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
+ *			or NO_SLEEP (interrupt thread, use mdelay)
+ *		  force - 1 if doorbell active, board fault state
+ *				board operational, IOC_RECOVERY or
+ *				IOC_BRINGUP and there is an alt_ioc.
+ *			  0 else
+ *
+ *	Returns:
+ *		 1 - hard reset, READY	
+ *		 0 - no reset due to History bit, READY	
+ *		-1 - no reset due to History bit but not READY	
+ *		     OR reset but failed to come READY
+ *		-2 - no reset, could not enter DIAG mode 
+ *		-3 - reset but bad FW bit 
  */
 static int
-KickStart(MPT_ADAPTER *ioc, int force)
+KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
 {
 	int hard_reset_done = 0;
 	u32 ioc_state;
@@ -2056,183 +2742,295 @@
 
 	dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
 
-	hard_reset_done = mpt_fc9x9_reset(ioc, force);
-#if 0
-	if (ioc->chip_type == FC909 || ioc->chip-type == FC919) {
-		hard_reset_done = mpt_fc9x9_reset(ioc, force);
-	} else if (ioc->chip_type == FC929) {
-		unsigned long delta;
-
-		delta = jiffies - ioc->last_kickstart;
-		dprintk((KERN_INFO MYNAM ": %s: 929 KickStart, last=%ld, delta = %ld\n",
-				ioc->name, ioc->last_kickstart, delta));
-		if ((ioc->sod_reset == 0) || (delta >= 10*HZ))
-			hard_reset_done = mpt_fc9x9_reset(ioc, ignore);
-		else {
-			dprintk((KERN_INFO MYNAM ": %s: Skipping KickStart (delta=%ld)!\n",
-					ioc->name, delta));
-			return 0;
-		}
-	/* TODO! Add C1030!
-	} else if (ioc->chip_type == C1030) {
-	 */
-	} else {
-		printk(KERN_ERR MYNAM ": %s: ERROR - Bad chip_type (0x%x)\n",
-				ioc->name, ioc->chip_type);
-		return -5;
-	}
-#endif
-
+	hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
 	if (hard_reset_done < 0)
 		return hard_reset_done;
 
-	dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset successful\n",
+	dprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
 			ioc->name));
 
 	for (cnt=0; cnt<HZ*20; cnt++) {
-		if ((ioc_state = GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {
-			dprintk((KERN_INFO MYNAM ": %s: KickStart successful! (cnt=%d)\n",
+		if ((ioc_state = mpt_GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {
+			dprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
 					ioc->name, cnt));
 			return hard_reset_done;
 		}
-		/* udelay(10000) ? */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
+		if (sleepFlag == CAN_SLEEP) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		} else {
+			mdelay (10);
+		}
 	}
 
-	printk(KERN_ERR MYNAM ": %s: ERROR - Failed to come READY after reset!\n",
+	printk(MYIOC_s_ERR_FMT "Failed to come READY after reset!\n",
 			ioc->name);
 	return -1;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mpt_fc9x9_reset - Perform hard reset of FC9x9 adapter.
+ *	mpt_diag_reset - Perform hard reset of the adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
- *
- *	This routine places FC9x9 adapter in diagnostic mode via the
- *	WriteSequence register, and then performs a hard reset of adapter
- *	via the Diagnostic register.
- *
- *	Returns 0 for success, non-zero for failure.
+ *	@ignore: Set if to honor and clear to ignore
+ *		the reset history bit
+ *	@sleepflag: CAN_SLEEP if called in a non-interrupt thread,
+ *		else set to NO_SLEEP (use mdelay instead)
+ *
+ *	This routine places the adapter in diagnostic mode via the
+ *	WriteSequence register and then performs a hard reset of adapter
+ *	via the Diagnostic register. Adapter should be in ready state
+ *	upon successful completion.
+ *
+ *	Returns:  1  hard reset successful
+ *		  0  no reset performed because reset history bit set
+ *		 -2  enabling diagnostic mode failed
+ *		 -3  diagnostic reset failed
  */
 static int
-mpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore)
+mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
 {
 	u32 diag0val;
+	u32 doorbell;
 	int hard_reset_done = 0;
+	int count = 0;
+#ifdef MPT_DEBUG
+	u32 diag1val = 0;
+#endif
 
-	/* Use "Diagnostic reset" method! (only thing available!) */
+	/* Clear any existing interrupts */
+	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
+	/* Use "Diagnostic reset" method! (only thing available!) */
 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+
 #ifdef MPT_DEBUG
-{
-	u32 diag1val = 0;
 	if (ioc->alt_ioc)
 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
-	dprintk((KERN_INFO MYNAM ": %s: DBG1: diag0=%08x, diag1=%08x\n",
+	dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
 			ioc->name, diag0val, diag1val));
-}
 #endif
-	if (diag0val & MPI_DIAG_DRWE) {
-		dprintk((KERN_INFO MYNAM ": %s: DiagWriteEn bit already set\n",
-				ioc->name));
-	} else {
-		/* Write magic sequence to WriteSequence register */
-		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
-		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
-		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
-		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
-		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
-		dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#1]\n",
-				ioc->name));
-	}
 
-	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+	/* Do the reset if we are told to ignore the reset history
+	 * or if the reset history is 0
+	 */
+	if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
+		while ((diag0val & MPI_DIAG_DRWE) == 0) {
+			/* Write magic sequence to WriteSequence register
+			 * Loop until in diagnostic mode
+			 */
+			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
+			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
+			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
+			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
+			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+
+			/* wait 100 msec */
+			if (sleepFlag == CAN_SLEEP) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(100 * HZ / 1000);
+			} else {
+				mdelay (100);
+			}
+
+			count++;
+			if (count > 20) {
+				printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
+						ioc->name, diag0val);
+				return -2;
+
+			}
+
+			diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+
+			dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
+					ioc->name, diag0val));
+		}
+
 #ifdef MPT_DEBUG
-{
-	u32 diag1val = 0;
-	if (ioc->alt_ioc)
-		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
-	dprintk((KERN_INFO MYNAM ": %s: DbG2: diag0=%08x, diag1=%08x\n",
-			ioc->name, diag0val, diag1val));
-}
+		if (ioc->alt_ioc)
+			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+		dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
+				ioc->name, diag0val, diag1val));
 #endif
-	if (!ignore && (diag0val & MPI_DIAG_RESET_HISTORY)) {
-		dprintk((KERN_INFO MYNAM ": %s: Skipping due to ResetHistory bit set!\n",
-				ioc->name));
-	} else {
+		/* Write the PreventIocBoot bit */
+		if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
+			diag0val |= MPI_DIAG_PREVENT_IOC_BOOT;
+			CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
+		}
+
+		/*
+		 * Disable the ARM (Bug fix)
+		 * 
+		 */
+		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
+		mdelay (1);
+
 		/*
 		 * Now hit the reset bit in the Diagnostic register
-		 * (THE BIG HAMMER!)
+		 * (THE BIG HAMMER!) (Clears DRWE bit).
 		 */
-		CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER);
+		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
 		hard_reset_done = 1;
-		dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset performed\n",
+		dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
 				ioc->name));
 
-		/* want udelay(100) */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
+		/*
+		 * Call each currently registered protocol IOC reset handler
+		 * with pre-reset indication.
+		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
+		 * MptResetHandlers[] registered yet.
+		 */
+		{
+			int	 ii;
+			int	 r = 0;
+
+			for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
+				if (MptResetHandlers[ii]) {
+					dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
+							ioc->name, ii));
+					r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
+					if (ioc->alt_ioc) {
+						dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
+								ioc->name, ioc->alt_ioc->name, ii));
+						r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
+					}
+				}
+			}
+			/* FIXME?  Examine results here? */
+		}
+
+		if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
+			/* If the DownloadBoot operation fails, the
+			 * IOC will be left unusable. This is a fatal error
+			 * case.  _diag_reset will return < 0
+			 */
+			for (count = 0; count < 30; count ++) {
+				diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+				if (ioc->alt_ioc)
+					diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+				dprintk((MYIOC_s_INFO_FMT 
+					"DbG2b: diag0=%08x, diag1=%08x\n",
+					ioc->name, diag0val, diag1val));
+#endif
+				if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
+					break;
+				}
+
+				/* wait 1 sec */
+				if (sleepFlag == CAN_SLEEP) {
+					set_current_state(TASK_INTERRUPTIBLE);
+					schedule_timeout(HZ);
+				} else {
+					mdelay (1000);
+				}
+			}
+			if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
+				printk(KERN_WARNING MYNAM 
+					": firmware downloadboot failure (%d)!\n", count);
+			}
+
+		} else {
+			/* Wait for FW to reload and for board
+			 * to go to the READY state.
+			 * Maximum wait is 30 seconds.
+			 * If fail, no error will check again
+			 * with calling program.
+			 */
+			for (count = 0; count < 30; count ++) {
+				doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
+				doorbell &= MPI_IOC_STATE_MASK;
+
+				if (doorbell == MPI_IOC_STATE_READY) {
+					break;
+				}
+
+				/* wait 1 sec */
+				if (sleepFlag == CAN_SLEEP) {
+					set_current_state(TASK_INTERRUPTIBLE);
+					schedule_timeout(HZ);
+				} else {
+					mdelay (1000);
+				}
+			}
+		}
+	}
 
-		/* Write magic sequence to WriteSequence register */
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+	if (ioc->alt_ioc)
+		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+	dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
+		ioc->name, diag0val, diag1val));
+#endif
+
+	/* Clear RESET_HISTORY bit!  Place board in the
+	 * diagnostic mode to update the diag register.
+	 */
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+	count = 0;
+	while ((diag0val & MPI_DIAG_DRWE) == 0) {
+		/* Write magic sequence to WriteSequence register
+		 * Loop until in diagnostic mode
+		 */
 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
-		dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#2]\n",
-				ioc->name));
-	}
 
-	/* Clear RESET_HISTORY bit! */
-	CHIPREG_WRITE32(&ioc->chip->Diagnostic, 0x0);
+		/* wait 100 msec */
+		if (sleepFlag == CAN_SLEEP) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(100 * HZ / 1000);
+		} else {
+			mdelay (100);
+		}
 
+		count++;
+		if (count > 20) {
+			printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
+					ioc->name, diag0val);
+			break;
+		}
+		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+	}
+	diag0val &= ~MPI_DIAG_RESET_HISTORY;
+	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
-#ifdef MPT_DEBUG
-{
-	u32 diag1val = 0;
-	if (ioc->alt_ioc)
-		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
-	dprintk((KERN_INFO MYNAM ": %s: DbG3: diag0=%08x, diag1=%08x\n",
-			ioc->name, diag0val, diag1val));
-}
-#endif
 	if (diag0val & MPI_DIAG_RESET_HISTORY) {
-		printk(KERN_WARNING MYNAM ": %s: WARNING - ResetHistory bit failed to clear!\n",
+		printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
 				ioc->name);
 	}
 
+	/* Disable Diagnostic Mode
+	 */
+	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
+
+	/* Check FW reload status flags.
+	 */
 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+	if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
+		printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
+				ioc->name, diag0val);
+		return -3;
+	}
+
 #ifdef MPT_DEBUG
-{
-	u32 diag1val = 0;
 	if (ioc->alt_ioc)
 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
-	dprintk((KERN_INFO MYNAM ": %s: DbG4: diag0=%08x, diag1=%08x\n",
+	dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
 			ioc->name, diag0val, diag1val));
-}
 #endif
-	if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
-		printk(KERN_ERR MYNAM ": %s: ERROR - Diagnostic reset FAILED! (%02xh)\n",
-				ioc->name, diag0val);
-		return -3;
-	}
 
 	/*
 	 * Reset flag that says we've enabled event notification
 	 */
 	ioc->facts.EventState = 0;
 
-	/* NEW!  20010220 -sralston
-	 * Try to avoid redundant resets of the 929.
-	 */
-	ioc->sod_reset++;
-	ioc->last_kickstart = jiffies;
-	if (ioc->alt_ioc) {
-		ioc->alt_ioc->sod_reset = ioc->sod_reset;
-		ioc->alt_ioc->last_kickstart = ioc->last_kickstart;
-	}
+	if (ioc->alt_ioc)
+		ioc->alt_ioc->facts.EventState = 0;
 
 	return hard_reset_done;
 }
@@ -2249,16 +3047,45 @@
  *	Returns 0 for success, non-zero for failure.
  */
 static int
-SendIocReset(MPT_ADAPTER *ioc, u8 reset_type)
+SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
 {
 	int r;
+	u32 state;
+	int cntdn, count;
 
 	dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
 			ioc->name, reset_type));
 	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
-	if ((r = WaitForDoorbellAck(ioc, 2)) < 0)
+	if ((r = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
 		return r;
 
+	/* FW ACK'd request, wait for READY state 
+	 */
+	cntdn = HZ * 15;
+	count = 0;
+	if (sleepFlag != CAN_SLEEP)
+		cntdn *= 10;	/* 1500 iterations @ 1msec per */
+
+	while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
+		cntdn--;
+		count++;
+		if (!cntdn) {
+			if (sleepFlag != CAN_SLEEP)
+				count *= 10;
+
+			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
+					ioc->name, (count+5)/HZ);
+			return -ETIME;
+		}
+
+		if (sleepFlag == CAN_SLEEP) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		} else {
+			mdelay (1);	/* 1 msec delay */
+		}
+	}
+
 	/* TODO!
 	 *  Cleanup all event stuff for this IOC; re-issue EventNotification
 	 *  request if needed.
@@ -2275,7 +3102,8 @@
  *	@ioc: Pointer to MPT_ADAPTER structure
  *
  *	This routine allocates memory for the MPT reply and request frame
- *	pools, and primes the IOC reply FIFO with reply frames.
+ *	pools (if necessary), and primes the IOC reply FIFO with
+ *	reply frames.
  *
  *	Returns 0 for success, non-zero for failure.
  */
@@ -2284,6 +3112,7 @@
 {
 	MPT_FRAME_HDR *mf;
 	unsigned long b;
+	unsigned long flags;
 	dma_addr_t aligned_mem_dma;
 	u8 *mem, *aligned_mem;
 	int i, sz;
@@ -2299,8 +3128,8 @@
 		memset(mem, 0, sz);
 		ioc->alloc_total += sz;
 		ioc->reply_alloc = mem;
-		dprintk((KERN_INFO MYNAM ": %s.reply_alloc  @ %p[%08x], sz=%d bytes\n",
-			 ioc->name, mem, ioc->reply_alloc_dma, sz));
+		dprintk((KERN_INFO MYNAM ": %s.reply_alloc  @ %p[%p], sz=%d bytes\n",
+			 	ioc->name, mem, (void *)(ulong)ioc->reply_alloc_dma, sz));
 
 		b = (unsigned long) mem;
 		b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
@@ -2308,15 +3137,20 @@
 		ioc->reply_frames = (MPT_FRAME_HDR *) aligned_mem;
 		ioc->reply_frames_dma =
 			(ioc->reply_alloc_dma + (aligned_mem - mem));
-		aligned_mem_dma = ioc->reply_frames_dma;
-		dprintk((KERN_INFO MYNAM ": %s.reply_frames @ %p[%08x]\n",
-			 ioc->name, aligned_mem, aligned_mem_dma));
-
-		for (i = 0; i < ioc->reply_depth; i++) {
-			/*  Write each address to the IOC!  */
-			CHIPREG_WRITE32(&ioc->chip->ReplyFifo, aligned_mem_dma);
-			aligned_mem_dma += ioc->reply_sz;
-		}
+
+		ioc->reply_frames_low_dma = (u32) (ioc->reply_frames_dma & 0xFFFFFFFF);
+	}
+
+	/* Post Reply frames to FIFO
+	 */
+	aligned_mem_dma = ioc->reply_frames_dma;
+	dprintk((KERN_INFO MYNAM ": %s.reply_frames @ %p[%p]\n",
+		 	ioc->name, ioc->reply_frames, (void *)(ulong)aligned_mem_dma));
+
+	for (i = 0; i < ioc->reply_depth; i++) {
+		/*  Write each address to the IOC!  */
+		CHIPREG_WRITE32(&ioc->chip->ReplyFifo, aligned_mem_dma);
+		aligned_mem_dma += ioc->reply_sz;
 	}
 
 
@@ -2336,8 +3170,8 @@
 		memset(mem, 0, sz);
 		ioc->alloc_total += sz;
 		ioc->req_alloc = mem;
-		dprintk((KERN_INFO MYNAM ": %s.req_alloc    @ %p[%08x], sz=%d bytes\n",
-			 ioc->name, mem, ioc->req_alloc_dma, sz));
+		dprintk((KERN_INFO MYNAM ": %s.req_alloc    @ %p[%p], sz=%d bytes\n",
+			 	ioc->name, mem, (void *)(ulong)ioc->req_alloc_dma, sz));
 
 		b = (unsigned long) mem;
 		b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
@@ -2345,18 +3179,18 @@
 		ioc->req_frames = (MPT_FRAME_HDR *) aligned_mem;
 		ioc->req_frames_dma =
 			(ioc->req_alloc_dma + (aligned_mem - mem));
-		aligned_mem_dma = ioc->req_frames_dma;
 
-		dprintk((KERN_INFO MYNAM ": %s.req_frames   @ %p[%08x]\n",
-			 ioc->name, aligned_mem, aligned_mem_dma));
+		ioc->req_frames_low_dma = (u32) (ioc->req_frames_dma & 0xFFFFFFFF);
 
-		for (i = 0; i < ioc->req_depth; i++) {
-			mf = (MPT_FRAME_HDR *) aligned_mem;
-
-			/*  Queue REQUESTs *internally*!  */
-			Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
-			aligned_mem += ioc->req_sz;
+#ifdef __ia64__
+		/* Check: upper 32-bits of the request and reply frame
+		 * physical addresses must be the same.
+		 * ia64 check only
+		 */
+		if ((ioc->req_frames_dma >> 32) != (ioc->reply_frames_dma >> 32)){
+			goto out_fail;
 		}
+#endif
 
 #if defined(CONFIG_MTRR) && 0
 		/*
@@ -2367,20 +3201,38 @@
 		ioc->mtrr_reg = mtrr_add(ioc->req_alloc_dma,
 					 sz,
 					 MTRR_TYPE_WRCOMB, 1);
-		dprintk((KERN_INFO MYNAM ": %s: MTRR region registered (base:size=%08x:%x)\n",
-				ioc->name, ioc->req_alloc_dma,
-				sz ));
+		dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
+				ioc->name, ioc->req_alloc_dma, sz));
 #endif
+	}
+
+	/* Initialize Request frames linked list
+	 */
+	aligned_mem_dma = ioc->req_frames_dma;
+	aligned_mem = (u8 *) ioc->req_frames;
+	dprintk((KERN_INFO MYNAM ": %s.req_frames   @ %p[%p]\n",
+		 	ioc->name, aligned_mem, (void *)(ulong)aligned_mem_dma));
 
+	spin_lock_irqsave(&ioc->FreeQlock, flags);
+	Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
+	for (i = 0; i < ioc->req_depth; i++) {
+		mf = (MPT_FRAME_HDR *) aligned_mem;
+
+		/*  Queue REQUESTs *internally*!  */
+		Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
+		aligned_mem += ioc->req_sz;
 	}
+	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
 
 	if (ioc->sense_buf_pool == NULL) {
-		sz = (ioc->req_depth * 256);
+		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
 		ioc->sense_buf_pool =
 				pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
 		if (ioc->sense_buf_pool == NULL)
 			goto out_fail;
 
+		ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
 		ioc->alloc_total += sz;
 	}
 
@@ -2408,7 +3260,7 @@
 #if defined(CONFIG_MTRR) && 0
 		if (ioc->mtrr_reg > 0) {
 			mtrr_del(ioc->mtrr_reg, 0, 0);
-			dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n",
+			dprintk((MYIOC_s_INFO_FMT "MTRR region de-registered\n",
 					ioc->name));
 		}
 #endif
@@ -2417,7 +3269,7 @@
 		ioc->alloc_total -= sz;
 	}
 	if (ioc->sense_buf_pool != NULL) {
-		sz = (ioc->req_depth * 256);
+		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
 		pci_free_consistent(ioc->pcidev,
 				sz,
 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
@@ -2427,8 +3279,8 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	HandShakeReqAndReply - Send MPT request to and receive reply from
+/**
+ *	mpt_handshake_req_reply_wait - Send MPT request to and receive reply from
  *	IOC via doorbell handshake method.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@reqBytes: Size of the request in bytes
@@ -2436,6 +3288,7 @@
  *	@replyBytes: Expected size of the reply in bytes
  *	@u16reply: Pointer to area where reply should be written
  *	@maxwait: Max wait time for a reply (in seconds)
+ *	@sleepFlag: Specifies whether the process can sleep
  *
  *	NOTES: It is the callers responsibility to byte-swap fields in the
  *	request which are greater than 1 byte in size.  It is also the
@@ -2444,8 +3297,9 @@
  *
  *	Returns 0 for success, non-zero for failure.
  */
-static int
-HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait)
+int
+mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
+				int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
 {
 	MPIDefaultReply_t *mptReply;
 	int failcnt = 0;
@@ -2471,57 +3325,61 @@
 	/*
 	 * Wait for IOC's doorbell handshake int
 	 */
-	if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
+	if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
 		failcnt++;
 
-	dhsprintk((KERN_INFO MYNAM ": %s: HandShake request start, WaitCnt=%d%s\n",
+	dhsprintk((MYIOC_s_INFO_FMT "HandShake request start, WaitCnt=%d%s\n",
 			ioc->name, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
 
+	/* Read doorbell and check for active bit */
+	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
+			return -1;
+
 	/*
 	 * Clear doorbell int (WRITE 0 to IntStatus reg),
 	 * then wait for IOC to ACKnowledge that it's ready for
 	 * our handshake request.
 	 */
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-	if (!failcnt && (t = WaitForDoorbellAck(ioc, 2)) < 0)
+	if (!failcnt && (t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
 		failcnt++;
 
 	if (!failcnt) {
-		int	 i;
+		int	 ii;
 		u8	*req_as_bytes = (u8 *) req;
 
 		/*
 		 * Stuff request words via doorbell handshake,
 		 * with ACK from IOC for each.
 		 */
-		for (i = 0; !failcnt && i < reqBytes/4; i++) {
-			u32 word = ((req_as_bytes[(i*4) + 0] <<  0) |
-				    (req_as_bytes[(i*4) + 1] <<  8) |
-				    (req_as_bytes[(i*4) + 2] << 16) |
-				    (req_as_bytes[(i*4) + 3] << 24));
+		for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
+			u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
+				    (req_as_bytes[(ii*4) + 1] <<  8) |
+				    (req_as_bytes[(ii*4) + 2] << 16) |
+				    (req_as_bytes[(ii*4) + 3] << 24));
 
 			CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
-			if ((t = WaitForDoorbellAck(ioc, 2)) < 0)
+			if ((t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
 				failcnt++;
 		}
 
 		dmfprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
 		DBG_DUMP_REQUEST_FRAME_HDR(req)
 
-		dhsprintk((KERN_INFO MYNAM ": %s: HandShake request post done, WaitCnt=%d%s\n",
+		dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
 				ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
 
 		/*
 		 * Wait for completion of doorbell handshake reply from the IOC
 		 */
-		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait)) < 0)
+		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
 			failcnt++;
 
 		/*
 		 * Copy out the cached reply...
 		 */
-		for(i=0; i < MIN(replyBytes/2,mptReply->MsgLength*2); i++)
-			u16reply[i] = ioc->hs_reply[i];
+		for (ii=0; ii < MIN(replyBytes/2,mptReply->MsgLength*2); ii++)
+			u16reply[ii] = ioc->hs_reply[ii];
 	} else {
 		return -99;
 	}
@@ -2535,6 +3393,7 @@
  *	in it's IntStatus register.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@howlong: How long to wait (in seconds)
+ *	@sleepFlag: Specifies whether the process can sleep
  *
  *	This routine waits (up to ~2 seconds max) for IOC doorbell
  *	handshake ACKnowledge.
@@ -2542,28 +3401,40 @@
  *	Returns a negative value on failure, else wait loop count.
  */
 static int
-WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong)
+WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
 {
 	int cntdn = HZ * howlong;
 	int count = 0;
 	u32 intstat;
 
-	while (--cntdn) {
-		intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
-		if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
-			break;
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
-		count++;
+	if (sleepFlag == CAN_SLEEP) {
+		while (--cntdn) {
+			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
+				break;
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+			count++;
+		}
+	} else {
+		cntdn *= 10; /* convert to msec */
+		while (--cntdn) {
+			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
+				break;
+			mdelay (1);
+			count++;
+		}
+		count /= 10;
 	}
 
 	if (cntdn) {
-		dhsprintk((KERN_INFO MYNAM ": %s: WaitForDoorbell ACK (cnt=%d)\n",
+		dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (cnt=%d)\n",
 				ioc->name, count));
 		return count;
 	}
 
-	printk(KERN_ERR MYNAM ": %s: ERROR - Doorbell ACK timeout(%d)!\n",
+	printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout(%d)!\n",
 			ioc->name, (count+5)/HZ);
 	return -1;
 }
@@ -2574,34 +3445,47 @@
  *	in it's IntStatus register.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@howlong: How long to wait (in seconds)
+ *	@sleepFlag: Specifies whether the process can sleep
  *
  *	This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
  *
  *	Returns a negative value on failure, else wait loop count.
  */
 static int
-WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong)
+WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
 {
 	int cntdn = HZ * howlong;
 	int count = 0;
 	u32 intstat;
 
-	while (--cntdn) {
-		intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
-		if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
-			break;
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
-		count++;
+	if (sleepFlag == CAN_SLEEP) {
+		while (--cntdn) {
+			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
+				break;
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+			count++;
+		}
+	} else {
+		cntdn *= 10; /* convert to msec */
+		while (--cntdn) {
+			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
+				break;
+			mdelay(1);
+			count++;
+		}
+		count /= 10;
 	}
 
 	if (cntdn) {
-		dhsprintk((KERN_INFO MYNAM ": %s: WaitForDoorbell INT (cnt=%d)\n",
+		dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d)\n",
 				ioc->name, count));
 		return count;
 	}
 
-	printk(KERN_ERR MYNAM ": %s: ERROR - Doorbell INT timeout(%d)!\n",
+	printk(MYIOC_s_ERR_FMT "Doorbell INT timeout(%d)!\n",
 			ioc->name, (count+5)/HZ);
 	return -1;
 }
@@ -2611,6 +3495,7 @@
  *	WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@howlong: How long to wait (in seconds)
+ *	@sleepFlag: Specifies whether the process can sleep
  *
  *	This routine polls the IOC for a handshake reply, 16 bits at a time.
  *	Reply is cached to IOC private area large enough to hold a maximum
@@ -2619,13 +3504,13 @@
  *	Returns a negative value on failure, else size of reply in WORDS.
  */
 static int
-WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong)
+WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
 {
 	int u16cnt = 0;
 	int failcnt = 0;
 	int t;
 	u16 *hs_reply = ioc->hs_reply;
- 	volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
+	volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
 	u16 hword;
 
 	hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
@@ -2634,12 +3519,12 @@
 	 * Get first two u16's so we can look at IOC's intended reply MsgLength
 	 */
 	u16cnt=0;
-	if ((t = WaitForDoorbellInt(ioc, howlong)) < 0) {
+	if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
 		failcnt++;
 	} else {
 		hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-		if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
+		if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
 			failcnt++;
 		else {
 			hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
@@ -2647,7 +3532,7 @@
 		}
 	}
 
-	dhsprintk((KERN_INFO MYNAM ": %s: First handshake reply word=%08x%s\n",
+	dhsprintk((MYIOC_s_INFO_FMT "First handshake reply word=%08x%s\n",
 			ioc->name, le32_to_cpu(*(u32 *)hs_reply),
 			failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
 
@@ -2656,7 +3541,7 @@
 	 * reply 16 bits at a time.
 	 */
 	for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
-		if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
+		if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
 			failcnt++;
 		hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
 		/* don't overflow our IOC hs_reply[] buffer! */
@@ -2665,12 +3550,12 @@
 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 	}
 
-	if (!failcnt && (t = WaitForDoorbellInt(ioc, 2)) < 0)
+	if (!failcnt && (t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
 		failcnt++;
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
 	if (failcnt) {
-		printk(KERN_ERR MYNAM ": %s: ERROR - Handshake reply failure!\n",
+		printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
 				ioc->name);
 		return -failcnt;
 	}
@@ -2681,130 +3566,631 @@
 	else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
 		return -102;
 	}
-#endif
+#endif
+
+	dmfprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
+	DBG_DUMP_REPLY_FRAME(mptReply)
+
+	dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY (sz=%d)\n",
+			ioc->name, u16cnt/2));
+	return u16cnt/2;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	GetLanConfigPages - Fetch LANConfig pages.
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *
+ *	Return: 0 for success
+ *	-ENOMEM if no memory available
+ *		-EPERM if not allowed due to ISR context
+ *		-EAGAIN if no msg frames currently available
+ *		-EFAULT for non-successful reply or no reply (timeout)
+ */
+static int
+GetLanConfigPages(MPT_ADAPTER *ioc)
+{
+	ConfigPageHeader_t	 hdr;
+	CONFIGPARMS		 cfg;
+	LANPage0_t		*ppage0_alloc;
+	dma_addr_t		 page0_dma;
+	LANPage1_t		*ppage1_alloc;
+	dma_addr_t		 page1_dma;
+	int			 rc = 0;
+	int			 data_sz;
+	int			 copy_sz;
+
+	/* Get LAN Page 0 header */
+	hdr.PageVersion = 0;
+	hdr.PageLength = 0;
+	hdr.PageNumber = 0;
+	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
+	cfg.hdr = &hdr;
+	cfg.physAddr = -1;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	cfg.pageAddr = 0;
+	cfg.timeout = 0;
+
+	if ((rc = mpt_config(ioc, &cfg)) != 0)
+		return rc;
+
+	if (hdr.PageLength > 0) {
+		data_sz = hdr.PageLength * 4;
+		ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
+		rc = -ENOMEM;
+		if (ppage0_alloc) {
+			memset((u8 *)ppage0_alloc, 0, data_sz);
+			cfg.physAddr = page0_dma;
+			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+			if ((rc = mpt_config(ioc, &cfg)) == 0) {
+				/* save the data */
+				copy_sz = MIN(sizeof(LANPage0_t), data_sz);
+				memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
+
+			}
+
+			pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
+
+			/* FIXME!
+			 *	Normalize endianness of structure data,
+			 *	by byte-swapping all > 1 byte fields!
+			 */
+
+		}
+
+		if (rc)
+			return rc;
+	}
+
+	/* Get LAN Page 1 header */
+	hdr.PageVersion = 0;
+	hdr.PageLength = 0;
+	hdr.PageNumber = 1;
+	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
+	cfg.hdr = &hdr;
+	cfg.physAddr = -1;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	cfg.pageAddr = 0;
+
+	if ((rc = mpt_config(ioc, &cfg)) != 0)
+		return rc;
+
+	if (hdr.PageLength == 0)
+		return 0;
+
+	data_sz = hdr.PageLength * 4;
+	rc = -ENOMEM;
+	ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
+	if (ppage1_alloc) {
+		memset((u8 *)ppage1_alloc, 0, data_sz);
+		cfg.physAddr = page1_dma;
+		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+		if ((rc = mpt_config(ioc, &cfg)) == 0) {
+			/* save the data */
+			copy_sz = MIN(sizeof(LANPage1_t), data_sz);
+			memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
+		}
+
+		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
+
+		/* FIXME!
+		 *	Normalize endianness of structure data,
+		 *	by byte-swapping all > 1 byte fields!
+		 */
+
+	}
+
+	return rc;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	GetFcPortPage0 - Fetch FCPort config Page0.
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@portnum: IOC Port number
+ *
+ *	Return: 0 for success
+ *	-ENOMEM if no memory available
+ *		-EPERM if not allowed due to ISR context
+ *		-EAGAIN if no msg frames currently available
+ *		-EFAULT for non-successful reply or no reply (timeout)
+ */
+static int
+GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
+{
+	ConfigPageHeader_t	 hdr;
+	CONFIGPARMS		 cfg;
+	FCPortPage0_t		*ppage0_alloc;
+	FCPortPage0_t		*pp0dest;
+	dma_addr_t		 page0_dma;
+	int			 data_sz;
+	int			 copy_sz;
+	int			 rc;
+
+	/* Get FCPort Page 0 header */
+	hdr.PageVersion = 0;
+	hdr.PageLength = 0;
+	hdr.PageNumber = 0;
+	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
+	cfg.hdr = &hdr;
+	cfg.physAddr = -1;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	cfg.pageAddr = portnum;
+	cfg.timeout = 0;
+
+	if ((rc = mpt_config(ioc, &cfg)) != 0)
+		return rc;
+
+	if (hdr.PageLength == 0)
+		return 0;
+
+	data_sz = hdr.PageLength * 4;
+	rc = -ENOMEM;
+	ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
+	if (ppage0_alloc) {
+		memset((u8 *)ppage0_alloc, 0, data_sz);
+		cfg.physAddr = page0_dma;
+		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+		if ((rc = mpt_config(ioc, &cfg)) == 0) {
+			/* save the data */
+			pp0dest = &ioc->fc_port_page0[portnum];
+			copy_sz = MIN(sizeof(FCPortPage0_t), data_sz);
+			memcpy(pp0dest, ppage0_alloc, copy_sz);
+
+			/*
+			 *	Normalize endianness of structure data,
+			 *	by byte-swapping all > 1 byte fields!
+			 */
+			pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
+			pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
+			pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
+			pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
+			pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
+			pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
+			pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
+			pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
+			pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
+			pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
+			pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
+			pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
+			pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
+			pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
+			pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
+			pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
+
+		}
+
+		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
+	}
+
+	return rc;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	GetIoUnitPage2 - Retrieve BIOS version and boot order information.
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *
+ *	Returns: 0 for success
+ *	-ENOMEM if no memory available
+ *		-EPERM if not allowed due to ISR context
+ *		-EAGAIN if no msg frames currently available
+ *		-EFAULT for non-successful reply or no reply (timeout)
+ */
+static int
+GetIoUnitPage2(MPT_ADAPTER *ioc)
+{
+	ConfigPageHeader_t	 hdr;
+	CONFIGPARMS		 cfg;
+	IOUnitPage2_t		*ppage_alloc;
+	dma_addr_t		 page_dma;
+	int			 data_sz;
+	int			 rc;
+
+	/* Get the page header */
+	hdr.PageVersion = 0;
+	hdr.PageLength = 0;
+	hdr.PageNumber = 2;
+	hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
+	cfg.hdr = &hdr;
+	cfg.physAddr = -1;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	cfg.pageAddr = 0;
+	cfg.timeout = 0;
+
+	if ((rc = mpt_config(ioc, &cfg)) != 0)
+		return rc;
+
+	if (hdr.PageLength == 0)
+		return 0;
+
+	/* Read the config page */
+	data_sz = hdr.PageLength * 4;
+	rc = -ENOMEM;
+	ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
+	if (ppage_alloc) {
+		memset((u8 *)ppage_alloc, 0, data_sz);
+		cfg.physAddr = page_dma;
+		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+		/* If Good, save data */
+		if ((rc = mpt_config(ioc, &cfg)) == 0)
+			ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
+
+		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
+	}
+
+	return rc;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
+ *	@ioc: Pointer to a Adapter Strucutre
+ *	@portnum: IOC port number
+ *
+ *	Return: -EFAULT if read of config page header fails
+ *			or if no nvram
+ *	If read of SCSI Port Page 0 fails,
+ *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
+ *		Adapter settings: async, narrow
+ *		Return 1
+ *	If read of SCSI Port Page 2 fails,
+ *		Adapter settings valid
+ *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
+ *		Return 1
+ *	Else
+ *		Both valid
+ *		Return 0
+ *	CHECK - what type of locking mechanisms should be used????
+ */
+static int
+mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
+{
+	u8			*pbuf = NULL;
+	dma_addr_t		 buf_dma;
+	CONFIGPARMS		 cfg;
+	ConfigPageHeader_t	 header;
+	int			 ii;
+	int			 data, rc = 0;
+
+	/* Allocate memory 
+	 */
+	if (!ioc->spi_data.nvram) {
+		int	 sz;
+		u8	*mem;
+		sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
+		mem = kmalloc(sz, GFP_KERNEL);
+		if (mem == NULL)
+			return -EFAULT;
+
+		ioc->spi_data.nvram = (int *) mem;
+
+		dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
+			ioc->name, ioc->spi_data.nvram, sz));
+	}
+
+	/* Invalidate NVRAM information
+	 */
+	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
+		ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
+	}
+
+	/* Read SPP0 header, allocate memory, then read page.
+	 */
+	header.PageVersion = 0;
+	header.PageLength = 0;
+	header.PageNumber = 0;
+	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
+	cfg.hdr = &header;
+	cfg.physAddr = -1;
+	cfg.pageAddr = portnum;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	cfg.timeout = 0;	/* use default */
+	if (mpt_config(ioc, &cfg) != 0)
+		 return -EFAULT;
+
+	if (header.PageLength > 0) {
+		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
+		if (pbuf) {
+			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+			cfg.physAddr = buf_dma;
+			if (mpt_config(ioc, &cfg) != 0) {
+				ioc->spi_data.maxBusWidth = MPT_NARROW;
+				ioc->spi_data.maxSyncOffset = 0;
+				ioc->spi_data.minSyncFactor = MPT_ASYNC;
+				ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
+				rc = 1;
+			} else {
+				/* Save the Port Page 0 data
+				 */
+				SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
+				pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
+				pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
+
+				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
+				data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
+				if (data) {
+					ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
+					data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
+					ioc->spi_data.minSyncFactor = (u8) (data >> 8);
+				} else {
+					ioc->spi_data.maxSyncOffset = 0;
+					ioc->spi_data.minSyncFactor = MPT_ASYNC;
+				}
+
+				ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
+
+				/* Update the minSyncFactor based on bus type.
+				 */
+				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
+					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
+
+					if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
+						ioc->spi_data.minSyncFactor = MPT_ULTRA;
+				}
+			}
+			if (pbuf) {
+				pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
+				pbuf = NULL;
+			}
+		}
+	}
+
+	/* SCSI Port Page 2 - Read the header then the page.
+	 */
+	header.PageVersion = 0;
+	header.PageLength = 0;
+	header.PageNumber = 2;
+	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
+	cfg.hdr = &header;
+	cfg.physAddr = -1;
+	cfg.pageAddr = portnum;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	if (mpt_config(ioc, &cfg) != 0)
+		return -EFAULT;
+
+	if (header.PageLength > 0) {
+		/* Allocate memory and read SCSI Port Page 2
+		 */
+		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
+		if (pbuf) {
+			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
+			cfg.physAddr = buf_dma;
+			if (mpt_config(ioc, &cfg) != 0) {
+				/* Nvram data is left with INVALID mark
+				 */
+				rc = 1;
+			} else {
+				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
+				MpiDeviceInfo_t	*pdevice = NULL;
+
+				/* Save the Port Page 2 data
+				 * (reformat into a 32bit quantity)
+				 */
+				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
+					pdevice = &pPP2->DeviceSettings[ii];
+					data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
+						(pdevice->SyncFactor << 8) | pdevice->Timeout;
+					ioc->spi_data.nvram[ii] = data;
+				}
+			}
+
+			pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
+			pbuf = NULL;
+		}
+	}
 
-	dmfprintk((KERN_INFO MYNAM ": %s: Got Handshake reply:\n", ioc->name));
-	DBG_DUMP_REPLY_FRAME(mptReply)
+	/* Update Adapter limits with those from NVRAM
+	 * Comment: Don't need to do this. Target performance
+	 * parameters will never exceed the adapters limits.
+	 */
 
-	dhsprintk((KERN_INFO MYNAM ": %s: WaitForDoorbell REPLY (sz=%d)\n",
-			ioc->name, u16cnt/2));
-	return u16cnt/2;
+	return rc;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	GetLanConfigPages - Fetch LANConfig pages.
- *	@ioc: Pointer to MPT_ADAPTER structure
+/*	mpt_readScsiDevicePageHeaders - save version and length of SDP1
+ *	@ioc: Pointer to a Adapter Strucutre
+ *	@portnum: IOC port number
  *
- *	Returns 0 for success, non-zero for failure.
+ *	Return: -EFAULT if read of config page header fails
+ *		or 0 if success.
  */
 static int
-GetLanConfigPages(MPT_ADAPTER *ioc)
+mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
 {
-	Config_t		 config_req;
-	ConfigReply_t		 config_reply;
-	LANPage0_t		*page0;
-	dma_addr_t		 page0_dma;
-	LANPage1_t		*page1;
-	dma_addr_t		 page1_dma;
-	int			 i;
-	int			 req_sz;
-	int			 reply_sz;
-	int			 data_sz;
+	CONFIGPARMS		 cfg;
+	ConfigPageHeader_t	 header;
 
-/* LANPage0 */
-	/*  Immediate destination (reply area)...  */
-	reply_sz = sizeof(config_reply);
-	memset(&config_reply, 0, reply_sz);
-
-	/*  Ultimate destination...  */
-	page0 = &ioc->lan_cnfg_page0;
-	data_sz = sizeof(*page0);
-	memset(page0, 0, data_sz);
-
-	/*  Request area (config_req on the stack right now!)  */
-	req_sz = sizeof(config_req);
-	memset(&config_req, 0, req_sz);
-	config_req.Function = MPI_FUNCTION_CONFIG;
-	config_req.Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-	/*	config_req.Header.PageVersion = 0;	*/
-	/*	config_req.Header.PageLength = 0;	*/
-	config_req.Header.PageNumber = 0;
-	config_req.Header.PageType = MPI_CONFIG_PAGETYPE_LAN;
-	/*	config_req.PageAddress = 0;		*/
-	config_req.PageBufferSGE.u.Simple.FlagsLength = cpu_to_le32(
-			((MPI_SGE_FLAGS_LAST_ELEMENT |
-			  MPI_SGE_FLAGS_END_OF_BUFFER |
-			  MPI_SGE_FLAGS_END_OF_LIST |
-			  MPI_SGE_FLAGS_SIMPLE_ELEMENT |
-			  MPI_SGE_FLAGS_SYSTEM_ADDRESS |
-			  MPI_SGE_FLAGS_32_BIT_ADDRESSING |
-			  MPI_SGE_FLAGS_32_BIT_CONTEXT) << MPI_SGE_FLAGS_SHIFT) |
-			(u32)data_sz
-	);
-	page0_dma = pci_map_single(ioc->pcidev, page0, data_sz, PCI_DMA_FROMDEVICE);
-	config_req.PageBufferSGE.u.Simple.u.Address32 = cpu_to_le32(page0_dma);
+	/* Read the SCSI Device Page 1 header
+	 */
+	header.PageVersion = 0;
+	header.PageLength = 0;
+	header.PageNumber = 1;
+	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+	cfg.hdr = &header;
+	cfg.physAddr = -1;
+	cfg.pageAddr = portnum;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	cfg.timeout = 0;
+	if (mpt_config(ioc, &cfg) != 0)
+		 return -EFAULT;
+
+	ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
+	ioc->spi_data.sdp1length = cfg.hdr->PageLength;
+
+	header.PageVersion = 0;
+	header.PageLength = 0;
+	header.PageNumber = 0;
+	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+	if (mpt_config(ioc, &cfg) != 0)
+		 return -EFAULT;
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending Config request LAN_PAGE_0\n",
-			ioc->name));
+	ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
+	ioc->spi_data.sdp0length = cfg.hdr->PageLength;
 
-	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&config_req,
-				reply_sz, (u16*)&config_reply, 3);
-	pci_unmap_single(ioc->pcidev, page0_dma, data_sz, PCI_DMA_FROMDEVICE);
-	if (i != 0)
-		return i;
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes 
+ *	@ioc: Pointer to a Adapter Strucutre
+ *	@portnum: IOC port number
+ *
+ *	Return:
+ *	0 on success
+ *	-EFAULT if read of config page header fails or data pointer not NULL
+ *	-ENOMEM if pci_alloc failed
+ */
+static int
+mpt_findImVolumes(MPT_ADAPTER *ioc)
+{
+	IOCPage2_t		*pIoc2 = NULL;
+	IOCPage3_t		*pIoc3 = NULL;
+	ConfigPageIoc2RaidVol_t	*pIocRv = NULL;
+	u8			*mem;
+	dma_addr_t		 ioc2_dma;
+	dma_addr_t		 ioc3_dma;
+	CONFIGPARMS		 cfg;
+	ConfigPageHeader_t	 header;
+	int			 jj;
+	int			 rc = 0;
+	int			 iocpage2sz;
+	int			 iocpage3sz = 0;
+	u8			 nVols, nPhys;
+	u8			 vid, vbus, vioc;
+
+	if (ioc->spi_data.pIocPg3)
+		return -EFAULT;	
+
+	/* Read IOCP2 header then the page.
+	 */
+	header.PageVersion = 0;
+	header.PageLength = 0;
+	header.PageNumber = 2;
+	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
+	cfg.hdr = &header;
+	cfg.physAddr = -1;
+	cfg.pageAddr = 0;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	cfg.timeout = 0;
+	if (mpt_config(ioc, &cfg) != 0)
+		 return -EFAULT;
+
+	if (header.PageLength == 0)
+		return -EFAULT;
+
+	iocpage2sz = header.PageLength * 4;
+	pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
+	if (!pIoc2)
+		return -ENOMEM;
+
+	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+	cfg.physAddr = ioc2_dma;
+	if (mpt_config(ioc, &cfg) != 0)
+		goto done_and_free;
+
+	/* Identify RAID Volume Id's */
+	nVols = pIoc2->NumActiveVolumes;
+	if ( nVols == 0) {
+		/* No RAID Volumes.  Done.
+		 */
+	} else {
+		/* At least 1 RAID Volume
+		 */
+		pIocRv = pIoc2->RaidVolume;
+		ioc->spi_data.isRaid = 0;
+		for (jj = 0; jj < nVols; jj++, pIocRv++) {
+			vid = pIocRv->VolumeID;
+			vbus = pIocRv->VolumeBus;
+			vioc = pIocRv->VolumeIOC;
+
+			/* find the match
+			 */
+			if (vbus == 0) {
+				ioc->spi_data.isRaid |= (1 << vid);
+			} else {
+				/* Error! Always bus 0
+				 */
+			}
+		}
+	}
 
-	/*  Now byte swap the necessary LANPage0 fields  */
+	/* Identify Hidden Physical Disk Id's */
+	nPhys = pIoc2->NumActivePhysDisks;
+	if (nPhys == 0) {
+		/* No physical disks. Done.
+		 */
+	} else {
+		/* There is at least one physical disk.
+		 * Read and save IOC Page 3
+		 */
+		header.PageVersion = 0;
+		header.PageLength = 0;
+		header.PageNumber = 3;
+		header.PageType = MPI_CONFIG_PAGETYPE_IOC;
+		cfg.hdr = &header;
+		cfg.physAddr = -1;
+		cfg.pageAddr = 0;
+		cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+		cfg.dir = 0;
+		cfg.timeout = 0;
+		if (mpt_config(ioc, &cfg) != 0)
+			goto done_and_free;
 
-/* LANPage1 */
-	/*  Immediate destination (reply area)...  */
-	reply_sz = sizeof(config_reply);
-	memset(&config_reply, 0, reply_sz);
-
-	/*  Ultimate destination...  */
-	page1 = &ioc->lan_cnfg_page1;
-	data_sz = sizeof(*page1);
-	memset(page1, 0, data_sz);
-
-	/*  Request area (config_req on the stack right now!)  */
-	req_sz = sizeof(config_req);
-	memset(&config_req, 0, req_sz);
-	config_req.Function = MPI_FUNCTION_CONFIG;
-	config_req.Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-	/*	config_req.Header.PageVersion = 0;	*/
-	/*	config_req.Header.PageLength = 0;	*/
-	config_req.Header.PageNumber = 1;
-	config_req.Header.PageType = MPI_CONFIG_PAGETYPE_LAN;
-	/*	config_req.PageAddress = 0;		*/
-	config_req.PageBufferSGE.u.Simple.FlagsLength = cpu_to_le32(
-			((MPI_SGE_FLAGS_LAST_ELEMENT |
-			  MPI_SGE_FLAGS_END_OF_BUFFER |
-			  MPI_SGE_FLAGS_END_OF_LIST |
-			  MPI_SGE_FLAGS_SIMPLE_ELEMENT |
-			  MPI_SGE_FLAGS_SYSTEM_ADDRESS |
-			  MPI_SGE_FLAGS_32_BIT_ADDRESSING |
-			  MPI_SGE_FLAGS_32_BIT_CONTEXT) << MPI_SGE_FLAGS_SHIFT) |
-			(u32)data_sz
-	);
-	page1_dma = pci_map_single(ioc->pcidev, page1, data_sz, PCI_DMA_FROMDEVICE);
-	config_req.PageBufferSGE.u.Simple.u.Address32 = cpu_to_le32(page1_dma);
+		if (header.PageLength == 0)
+			goto done_and_free;
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending Config request LAN_PAGE_1\n",
-			ioc->name));
+		/* Read Header good, alloc memory
+		 */
+		iocpage3sz = header.PageLength * 4;
+		pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
+		if (!pIoc3)
+			goto done_and_free;
 
-	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&config_req,
-				reply_sz, (u16*)&config_reply, 3);
-	pci_unmap_single(ioc->pcidev, page1_dma, data_sz, PCI_DMA_FROMDEVICE);
-	if (i != 0)
-		return i;
+		/* Read the Page and save the data
+		 * into malloc'd memory.
+		 */
+		cfg.physAddr = ioc3_dma;
+		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+		if (mpt_config(ioc, &cfg) == 0) {
+			mem = kmalloc(iocpage3sz, GFP_KERNEL);
+			if (mem) {
+				memcpy(mem, (u8 *)pIoc3, iocpage3sz);
+				ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
+			}
+		}
+	}
 
-	/*  Now byte swap the necessary LANPage1 fields  */
+done_and_free:
+	if (pIoc2) {
+		pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
+		pIoc2 = NULL;
+	}
 
-	return 0;
+	if (pIoc3) {
+		pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
+		pIoc3 = NULL;
+	}
+
+	return rc;
 }
 
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
+/*
  *	SendEventNotification - Send EventNotification (on or off) request
  *	to MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
@@ -2817,13 +4203,13 @@
 
 	evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc->id);
 	if (evnp == NULL) {
-		dprintk((KERN_WARNING MYNAM ": %s: WARNING - Unable to allocate a event request frame!\n",
+		dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
 				ioc->name));
 		return 0;
 	}
 	memset(evnp, 0, sizeof(*evnp));
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending EventNotification(%d)\n", ioc->name, EvSwitch));
+	dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
 
 	evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
 	evnp->ChainOffset = 0;
@@ -2847,13 +4233,13 @@
 	EventAck_t	*pAck;
 
 	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
-		printk(KERN_WARNING MYNAM ": %s: WARNING - Unable to allocate event ACK request frame!\n",
+		printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
 				ioc->name);
 		return -1;
 	}
 	memset(pAck, 0, sizeof(*pAck));
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending EventAck\n", ioc->name));
+	dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
 
 	pAck->Function     = MPI_FUNCTION_EVENT_ACK;
 	pAck->ChainOffset  = 0;
@@ -2866,25 +4252,212 @@
 	return 0;
 }
 
-#ifdef CONFIG_PROC_FS		/* { */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mpt_config - Generic function to issue config message
+ *	@ioc - Pointer to an adapter structure
+ *	@cfg - Pointer to a configuration structure. Struct contains
+ *		action, page address, direction, physical address
+ *		and pointer to a configuration page header
+ *		Page header is updated.
+ *
+ *	Returns 0 for success
+ *	-EPERM if not allowed due to ISR context
+ *	-EAGAIN if no msg frames currently available
+ *	-EFAULT for non-successful reply or no reply (timeout)
+ */
+int
+mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
+{
+	Config_t	*pReq;
+	MPT_FRAME_HDR	*mf;
+	MptSge_t	*psge;
+	unsigned long	 flags;
+	int		 ii, rc;
+	int		 flagsLength;
+	int		 in_isr;
+
+	/* (Bugzilla:fibrebugs, #513)
+	 * Bug fix (part 1)!  20010905 -sralston
+	 *	Prevent calling wait_event() (below), if caller happens
+	 *	to be in ISR context, because that is fatal!
+	 */
+	in_isr = in_interrupt();
+	if (in_isr) {
+		dprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
+				ioc->name));
+		return -EPERM;
+	}
+
+	/* Get and Populate a free Frame
+	 */
+	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
+		dprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
+				ioc->name));
+		return -EAGAIN;
+	}
+	pReq = (Config_t *)mf;
+	pReq->Action = pCfg->action;
+	pReq->Reserved = 0;
+	pReq->ChainOffset = 0;
+	pReq->Function = MPI_FUNCTION_CONFIG;
+	pReq->Reserved1[0] = 0;
+	pReq->Reserved1[1] = 0;
+	pReq->Reserved1[2] = 0;
+	pReq->MsgFlags = 0;
+	for (ii=0; ii < 8; ii++)
+		pReq->Reserved2[ii] = 0;
+
+	pReq->Header.PageVersion = pCfg->hdr->PageVersion;
+	pReq->Header.PageLength = pCfg->hdr->PageLength;
+	pReq->Header.PageNumber = pCfg->hdr->PageNumber;
+	pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
+	pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
+
+	/* Add a SGE to the config request.
+	 */
+	flagsLength = ((MPI_SGE_FLAGS_LAST_ELEMENT |
+			MPI_SGE_FLAGS_END_OF_BUFFER |
+			MPI_SGE_FLAGS_END_OF_LIST |
+			MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+			MPT_SGE_ADDRESS_SIZE ) << MPI_SGE_FLAGS_SHIFT) |
+			pCfg->hdr->PageLength * 4;
+
+	if (pCfg->dir)
+		flagsLength |= (MPI_SGE_FLAGS_DIRECTION << MPI_SGE_FLAGS_SHIFT);
+
+	psge = (MptSge_t *) &pReq->PageBufferSGE;
+	psge->FlagsLength = cpu_to_le32(flagsLength);
+	cpu_to_leXX(pCfg->physAddr, psge->Address);
+
+	dprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
+		ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
+
+	/* Append pCfg pointer to end of mf
+	 */
+	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
+
+	/* Initalize the timer
+	 */
+	init_timer(&pCfg->timer);
+	pCfg->timer.data = (unsigned long) ioc;
+	pCfg->timer.function = mpt_timer_expired;
+	pCfg->wait_done = 0;
+
+	/* Set the timer; ensure 10 second minimum */
+	if (pCfg->timeout < 10)
+		pCfg->timer.expires = jiffies + HZ*10;
+	else
+		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
+
+	/* Add to end of Q, set timer and then issue this command */
+	spin_lock_irqsave(&ioc->FreeQlock, flags);
+	Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
+	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+	add_timer(&pCfg->timer);
+	mpt_put_msg_frame(mpt_base_index, ioc->id, mf);
+	wait_event(mpt_waitq, pCfg->wait_done);
+
+	/* mf has been freed - do not access */
+
+	rc = pCfg->status;
+
+	return rc;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
+ *	mpt_timer_expired - Call back for timer process.
+ *	Used only internal config functionality.
+ *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
+ */
+static void
+mpt_timer_expired(unsigned long data)
+{
+	MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
+
+	dprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
+
+	/* Perform a FW reload */
+	if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
+		printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
+
+	/* No more processing.
+	 * Hard reset clean-up will wake up
+	 * process and free all resources.
+	 */
+	dprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
+
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mpt_ioc_reset - Base cleanup for hard reset
+ *	@ioc: Pointer to the adapter structure
+ *	@reset_phase: Indicates pre- or post-reset functionality
+ *
+ *	Remark: Free's resources with internally generated commands.
  */
+static int
+mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+	CONFIGPARMS *pCfg;
+	unsigned long flags;
+
+	dprintk((KERN_WARNING MYNAM
+			": IOC %s_reset routed to MPT base driver!\n",
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+	if (reset_phase == MPT_IOC_PRE_RESET) {
+		/* If the internal config Q is not empty -
+		 * delete timer. MF resources will be freed when
+		 * the FIFO's are primed.
+		 */
+		spin_lock_irqsave(&ioc->FreeQlock, flags);
+		if (! Q_IS_EMPTY(&ioc->configQ)){
+			pCfg = (CONFIGPARMS *)ioc->configQ.head;
+			do {
+				del_timer(&pCfg->timer);
+				pCfg = (CONFIGPARMS *) (pCfg->linkage.forw);
+			} while (pCfg != (CONFIGPARMS *)&ioc->configQ);
+		}
+		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+	} else {
+		CONFIGPARMS *pNext;
+
+		/* Search the configQ for internal commands. 
+		 * Flush the Q, and wake up all suspended threads.
+		 */
+		spin_lock_irqsave(&ioc->FreeQlock, flags);
+		if (! Q_IS_EMPTY(&ioc->configQ)){
+			pCfg = (CONFIGPARMS *)ioc->configQ.head;
+			do {
+				pNext = (CONFIGPARMS *) pCfg->linkage.forw;
 
-#define PROC_MPT_READ_RETURN(page,start,off,count,eof,len) \
-{ \
-	len -= off;			\
-	if (len < count) {		\
-		*eof = 1;		\
-		if (len <= 0)		\
-			return 0;	\
-	} else				\
-		len = count;		\
-	*start = page + off;		\
-	return len;			\
+				Q_DEL_ITEM(&pCfg->linkage);
+
+				pCfg->status = MPT_CONFIG_ERROR;
+				pCfg->wait_done = 1;
+				wake_up(&mpt_waitq);
+
+				pCfg = pNext;
+			} while (pCfg != (CONFIGPARMS *)&ioc->configQ);
+		}
+		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+	}
+
+	return 1;		/* currently means nothing really */
 }
 
+
+#ifdef CONFIG_PROC_FS		/* { */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
+ */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
@@ -2894,71 +4467,62 @@
 static int
 procmpt_create(void)
 {
-	MPT_ADAPTER *ioc;
-	struct proc_dir_entry *ent;
-	int errcnt = 0;
+	MPT_ADAPTER		*ioc;
+	struct proc_dir_entry	*ent;
+	int	 ii;
 
 	/*
-	 * 	BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
-	 * 	(single level) to multi level (e.g. "driver/message/fusion")
-	 * 	something here needs to change.  -sralston
+	 *	BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
+	 *	(single level) to multi level (e.g. "driver/message/fusion")
+	 *	something here needs to change.  -sralston
 	 */
-	procmpt_root_dir = CREATE_PROCDIR_ENTRY(MPT_PROCFS_MPTBASEDIR, NULL);
-	if (procmpt_root_dir == NULL)
+	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
+	if (mpt_proc_root_dir == NULL)
 		return -ENOTDIR;
 
-	if ((ioc = mpt_adapter_find_first()) != NULL) {
-		ent = create_proc_read_entry(MPT_PROCFS_SUMMARY_NODE, 0, NULL, procmpt_read_summary, NULL);
-		if (ent == NULL) {
-			printk(KERN_WARNING MYNAM ": WARNING - Could not create %s entry!\n",
-					MPT_PROCFS_SUMMARY_PATHNAME);
-			errcnt++;
+	for (ii=0; ii < MPT_PROC_ENTRIES; ii++) {
+		ent = create_proc_entry(mpt_proc_list[ii].name,
+				S_IFREG|S_IRUGO, mpt_proc_root_dir);
+		if (!ent) {
+			printk(KERN_WARNING MYNAM
+					": WARNING - Could not create /proc/mpt/%s entry\n",
+					mpt_proc_list[ii].name);
+			continue;
 		}
+		ent->read_proc = mpt_proc_list[ii].f;
+		ent->data      = NULL;
 	}
 
+	ioc = mpt_adapter_find_first();
 	while (ioc != NULL) {
-		char pname[32];
-		int namelen;
+		struct proc_dir_entry	*dent;
 		/*
 		 *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
 		 */
-		namelen = sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
-		if ((ent = CREATE_PROCDIR_ENTRY(pname, NULL)) != NULL) {
+		if ((dent = proc_mkdir(ioc->name, mpt_proc_root_dir)) != NULL) {
 			/*
-			 *  And populate it with: "summary" and "dbg" file entries.
+			 *  And populate it with mpt_ioc_proc_list[] entries.
 			 */
-			(void) sprintf(pname+namelen, "/summary");
-			ent = create_proc_read_entry(pname, 0, NULL, procmpt_read_summary, ioc);
-			if (ent == NULL) {
-				errcnt++;
-				printk(KERN_WARNING MYNAM ": %s: WARNING - Could not create /proc/%s entry!\n",
-						ioc->name, pname);
-			}
-//#ifdef MPT_DEBUG
-			/* DEBUG aid! */
-			(void) sprintf(pname+namelen, "/dbg");
-			ent = create_proc_read_entry(pname, 0, NULL, procmpt_read_dbg, ioc);
-			if (ent == NULL) {
-				errcnt++;
-				printk(KERN_WARNING MYNAM ": %s: WARNING - Could not create /proc/%s entry!\n",
-						ioc->name, pname);
+			for (ii=0; ii < MPT_IOC_PROC_ENTRIES; ii++) {
+				ent = create_proc_entry(mpt_ioc_proc_list[ii].name,
+						S_IFREG|S_IRUGO, dent);
+				if (!ent) {
+					printk(KERN_WARNING MYNAM
+							": WARNING - Could not create /proc/mpt/%s/%s entry!\n",
+							ioc->name,
+							mpt_ioc_proc_list[ii].name);
+					continue;
+				}
+				ent->read_proc = mpt_ioc_proc_list[ii].f;
+				ent->data      = ioc;
 			}
-//#endif
 		} else {
-			errcnt++;
-			printk(KERN_WARNING MYNAM ": %s: WARNING - Could not create /proc/%s entry!\n",
-					ioc->name, pname);
-
+			printk(MYIOC_s_WARN_FMT "Could not create /proc/mpt/%s subdir entry!\n",
+					ioc->name, mpt_ioc_proc_list[ii].name);
 		}
-
 		ioc = mpt_adapter_find_next(ioc);
 	}
 
-	if (errcnt) {
-//		remove_proc_entry("mpt", 0);
-		return -ENOTDIR;
-	}
-
 	return 0;
 }
 
@@ -2971,44 +4535,44 @@
 static int
 procmpt_destroy(void)
 {
-	MPT_ADAPTER *ioc;
+	MPT_ADAPTER	*ioc;
+	int		 ii;
 
-	if (!procmpt_root_dir)
+	if (!mpt_proc_root_dir)
 		return 0;
 
 	/*
-	 * 	BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
-	 * 	(single level) to multi level (e.g. "driver/message/fusion")
-	 * 	something here needs to change.  -sralston
+	 *	BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
+	 *	(single level) to multi level (e.g. "driver/message/fusion")
+	 *	something here needs to change.  -sralston
 	 */
 
 	ioc = mpt_adapter_find_first();
-	if (ioc != NULL) {
-		remove_proc_entry(MPT_PROCFS_SUMMARY_NODE, 0);
-	}
-
 	while (ioc != NULL) {
 		char pname[32];
 		int namelen;
+
+		namelen = sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
+
 		/*
 		 *  Tear down each "/proc/mpt/iocN" subdirectory.
 		 */
-		namelen = sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
-		(void) sprintf(pname+namelen, "/summary");
-		remove_proc_entry(pname, 0);
-//#ifdef MPT_DEBUG
-		(void) sprintf(pname+namelen, "/dbg");
-		remove_proc_entry(pname, 0);
-//#endif
-		(void) sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
-		remove_proc_entry(pname, 0);
+		for (ii=0; ii < MPT_IOC_PROC_ENTRIES; ii++) {
+			(void) sprintf(pname+namelen, "/%s", mpt_ioc_proc_list[ii].name);
+			remove_proc_entry(pname, NULL);
+		}
+
+		remove_proc_entry(ioc->name, mpt_proc_root_dir);
 
 		ioc = mpt_adapter_find_next(ioc);
 	}
 
-	if (atomic_read((atomic_t *)&procmpt_root_dir->count) == 0) {
-		remove_proc_entry(MPT_PROCFS_MPTBASEDIR, 0);
-		procmpt_root_dir = NULL;
+	for (ii=0; ii < MPT_PROC_ENTRIES; ii++)
+		remove_proc_entry(mpt_proc_list[ii].name, mpt_proc_root_dir);
+
+	if (atomic_read((atomic_t *)&mpt_proc_root_dir->count) == 0) {
+		remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
+		mpt_proc_root_dir = NULL;
 		return 0;
 	}
 
@@ -3016,23 +4580,23 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	procmpt_read_summary - Handle read request from /proc/mpt/summary
+/*
+ *	procmpt_summary_read - Handle read request from /proc/mpt/summary
  *	or from /proc/mpt/iocN/summary.
- *	@page: Pointer to area to write information
+ *	@buf: Pointer to area to write information
  *	@start: Pointer to start pointer
- *	@off: Offset to start writing
- *	@count: 
+ *	@offset: Offset to start writing
+ *	@request:
  *	@eof: Pointer to EOF integer
- *	@data: Pointer 
+ *	@data: Pointer
  *
- *	Returns numbers of characters written to process performing the read.
+ *	Returns number of characters written to process performing the read.
  */
 static int
-procmpt_read_summary(char *page, char **start, off_t off, int count, int *eof, void *data)
+procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
 {
 	MPT_ADAPTER *ioc;
-	char *out = page;
+	char *out = buf;
 	int len;
 
 	if (data == NULL)
@@ -3040,84 +4604,196 @@
 	else
 		ioc = data;
 
-// Too verbose!
-//	out += sprintf(out, "Attached Fusion MPT I/O Controllers:%s\n", ioc ? "" : " none");
-
 	while (ioc) {
 		int	more = 0;
 
-// Too verbose!
-//		mpt_print_ioc_facts(ioc, out, &more, 0);
 		mpt_print_ioc_summary(ioc, out, &more, 0, 1);
 
 		out += more;
-		if ((out-page) >= count) {
+		if ((out-buf) >= request) {
 			break;
 		}
 
 		if (data == NULL)
 			ioc = mpt_adapter_find_next(ioc);
 		else
-			ioc = NULL;				/* force exit for iocN */
+			ioc = NULL;		/* force exit for iocN */
 	}
-	len = out - page;
+	len = out - buf;
 
-	PROC_MPT_READ_RETURN(page,start,off,count,eof,len);
+	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
 }
 
-// debug aid!
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	procmpt_read_dbg - Handle read request from /proc/mpt/iocN/dbg.
- *	@page: Pointer to area to write information
+/*
+ *	procmpt_version_read - Handle read request from /proc/mpt/version.
+ *	@buf: Pointer to area to write information
  *	@start: Pointer to start pointer
- *	@off: Offset to start writing
- *	@count: 
+ *	@offset: Offset to start writing
+ *	@request:
  *	@eof: Pointer to EOF integer
- *	@data: Pointer 
+ *	@data: Pointer
  *
- *	Returns numbers of characters written to process performing the read.
+ *	Returns number of characters written to process performing the read.
  */
 static int
-procmpt_read_dbg(char *page, char **start, off_t off, int count, int *eof, void *data)
+procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
 {
-	MPT_ADAPTER *ioc;
-	char *out = page;
-	int len;
+	int	 ii;
+	int	 scsi, lan, ctl, targ, dmp;
+	char	*drvname;
+	int	 len;
+
+	len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
+	len += sprintf(buf+len, "  Fusion MPT base driver\n");
+
+	scsi = lan = ctl = targ = dmp = 0;
+	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
+		drvname = NULL;
+		if (MptCallbacks[ii]) {
+			switch (MptDriverClass[ii]) {
+			case MPTSCSIH_DRIVER:
+				if (!scsi++) drvname = "SCSI host";
+				break;
+			case MPTLAN_DRIVER:
+				if (!lan++) drvname = "LAN";
+				break;
+			case MPTSTM_DRIVER:
+				if (!targ++) drvname = "SCSI target";
+				break;
+			case MPTCTL_DRIVER:
+				if (!ctl++) drvname = "ioctl";
+				break;
+			case MPTDMP_DRIVER:
+				if (!dmp++) drvname = "DMP";
+				break;
+			}
+
+			if (drvname)
+				len += sprintf(buf+len, "  Fusion MPT %s driver\n", drvname);
+			/*
+			 *	Handle isense special case, because it
+			 *	doesn't do a formal mpt_register call.
+			 */
+			if (isense_idx == ii)
+				len += sprintf(buf+len, "  Fusion MPT isense driver\n");
+		} else
+			break;
+	}
 
-	ioc = data;
+	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
+}
 
-	while (ioc) {
-		int	more = 0;
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
+ *	@buf: Pointer to area to write information
+ *	@start: Pointer to start pointer
+ *	@offset: Offset to start writing
+ *	@request:
+ *	@eof: Pointer to EOF integer
+ *	@data: Pointer
+ *
+ *	Returns number of characters written to process performing the read.
+ */
+static int
+procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
+{
+	MPT_ADAPTER	*ioc = data;
+	int		 len;
+	char		 expVer[32];
+	int		 sz;
+	int		 p;
 
-		mpt_print_ioc_facts(ioc, out, &more, 0);
+	mpt_get_fw_exp_ver(expVer, ioc);
 
-		out += more;
-		if ((out-page) >= count) {
-			break;
+	len = sprintf(buf, "%s:", ioc->name);
+	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
+		len += sprintf(buf+len, "  (f/w download boot flag set)");
+//	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
+//		len += sprintf(buf+len, "  CONFIG_CHECKSUM_FAIL!");
+
+	len += sprintf(buf+len, "\n  ProductID = 0x%04x (%s)\n",
+			ioc->facts.ProductID,
+			ioc->prod_name);
+	len += sprintf(buf+len, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
+	if (ioc->facts.FWImageSize)
+		len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
+	len += sprintf(buf+len, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
+	len += sprintf(buf+len, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
+	len += sprintf(buf+len, "  EventState = 0x%02x\n", ioc->facts.EventState);
+
+	len += sprintf(buf+len, "  CurrentHostMfaHighAddr = 0x%08x\n",
+			ioc->facts.CurrentHostMfaHighAddr);
+	len += sprintf(buf+len, "  CurrentSenseBufferHighAddr = 0x%08x\n",
+			ioc->facts.CurrentSenseBufferHighAddr);
+
+	len += sprintf(buf+len, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
+	len += sprintf(buf+len, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
+
+	len += sprintf(buf+len, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
+					ioc->req_alloc, (void *)(ulong)ioc->req_alloc_dma);
+	/*
+	 *  Rounding UP to nearest 4-kB boundary here...
+	 */
+	sz = (ioc->req_sz * ioc->req_depth) + 128;
+	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
+	len += sprintf(buf+len, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
+					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
+	len += sprintf(buf+len, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
+					4*ioc->facts.RequestFrameSize,
+					ioc->facts.GlobalCredits);
+
+	len += sprintf(buf+len, "  ReplyFrames   @ 0x%p (Dma @ 0x%p)\n",
+					ioc->reply_alloc, (void *)(ulong)ioc->reply_alloc_dma);
+	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
+	len += sprintf(buf+len, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
+					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
+	len += sprintf(buf+len, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
+					ioc->facts.CurReplyFrameSize,
+					ioc->facts.ReplyQueueDepth);
+
+	len += sprintf(buf+len, "  MaxDevices = %d\n",
+			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
+	len += sprintf(buf+len, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
+
+	/* per-port info */
+	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
+		len += sprintf(buf+len, "  PortNumber = %d (of %d)\n",
+				p+1,
+				ioc->facts.NumberOfPorts);
+		if ((int)ioc->chip_type <= (int)FC929) {
+			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
+				len += sprintf(buf+len, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
+						a[5], a[4], a[3], a[2], a[1], a[0]);
+			}
+			len += sprintf(buf+len, "    WWN = %08X%08X:%08X%08X\n",
+					ioc->fc_port_page0[p].WWNN.High,
+					ioc->fc_port_page0[p].WWNN.Low,
+					ioc->fc_port_page0[p].WWPN.High,
+					ioc->fc_port_page0[p].WWPN.Low);
 		}
-		ioc = NULL;
 	}
-	len = out - page;
 
-	PROC_MPT_READ_RETURN(page,start,off,count,eof,len);
+	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
 }
+
 #endif		/* CONFIG_PROC_FS } */
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static void
 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
 {
-	if ((ioc->facts.FWVersion & 0xF000) == 0xE000)
+	buf[0] ='\0';
+	if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
 		sprintf(buf, " (Exp %02d%02d)",
-			(ioc->facts.FWVersion & 0x0F00) >> 8,	/* Month */
-			ioc->facts.FWVersion & 0x001F);		/* Day */
-	else
-		buf[0] ='\0';
+			(ioc->facts.FWVersion.Word >> 16) & 0x00FF,	/* Month */
+			(ioc->facts.FWVersion.Word >> 8) & 0x1F);	/* Day */
 
-	/* insider hack! */
-	if (ioc->facts.FWVersion & 0x0080) {
-		strcat(buf, " [MDBG]");
+		/* insider hack! */
+		if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
+			strcat(buf, " [MDBG]");
 	}
 }
 
@@ -3130,8 +4806,8 @@
  *	@len: Offset at which to start writing in buffer
  *	@showlan: Display LAN stuff?
  *
- * 	This routine writes (english readable) ASCII text, which represents
- * 	a summary of IOC information, to a buffer.
+ *	This routine writes (english readable) ASCII text, which represents
+ *	a summary of IOC information, to a buffer.
  */
 void
 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
@@ -3144,11 +4820,11 @@
 	/*
 	 *  Shorter summary of attached ioc's...
 	 */
-	y = sprintf(buffer+len, "%s: %s, %s%04xh%s, Ports=%d, MaxQ=%d",
+	y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
 			ioc->name,
 			ioc->prod_name,
 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
-			ioc->facts.FWVersion,
+			ioc->facts.FWVersion.Word,
 			expVer,
 			ioc->facts.NumberOfPorts,
 			ioc->req_depth);
@@ -3159,8 +4835,11 @@
 			a[5], a[4], a[3], a[2], a[1], a[0]);
 	}
 
-	if (ioc->pci_irq < 100)
-		y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
+#ifndef __sparc__
+	y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
+#else
+	y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
+#endif
 
 	if (!ioc->active)
 		y += sprintf(buffer+len+y, " (disabled)");
@@ -3171,75 +4850,66 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	Reset Handling
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mpt_print_ioc_facts - Write ASCII summary of IOC facts to a buffer.
+ *	mpt_HardResetHandler - Generic reset handler, issue SCSI Task
+ *	Management call based on input arg values.  If TaskMgmt fails,
+ *	return associated SCSI request.
  *	@ioc: Pointer to MPT_ADAPTER structure
- *	@buffer: Pointer to buffer where IOC facts should be written
- *	@size: Pointer to number of bytes we wrote (set by this routine)
- *	@len: Offset at which to start writing in buffer
+ *	@sleepFlag: Indicates if sleep or schedule must be called.
+ *
+ *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
+ *	or a non-interrupt thread.  In the former, must not call schedule().
  *
- * 	This routine writes (english readable) ASCII text, which represents
- * 	a summary of the IOC facts, to a buffer.
+ *	Remark: A return of -1 is a FATAL error case, as it means a
+ *	FW reload/initialization failed.
+ *
+ *	Returns 0 for SUCCESS or -1 if FAILED.
  */
-void
-mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buffer, int *size, int len)
+int
+mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
 {
-	char expVer[32];
-	char iocName[16];
-	int sz;
-	int y;
-	int p;
-
-	mpt_get_fw_exp_ver(expVer, ioc);
+	int		 rc;
+	unsigned long	 flags;
 
-	strcpy(iocName, ioc->name);
-	y = sprintf(buffer+len, "%s:\n", iocName);
+	dprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
+#ifdef MFCNT
+	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
+	printk("MF count 0x%x !\n", ioc->mfcnt);
+#endif
 
-	y += sprintf(buffer+len+y, "  ProductID = 0x%04x\n", ioc->facts.ProductID);
-	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
-		y += sprintf(buffer+len+y, "  PortNumber = %d (of %d)\n",
-			p+1,
-			ioc->facts.NumberOfPorts);
-		if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
-			u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
-			y += sprintf(buffer+len+y, "  LanAddr = 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-				a[5], a[4], a[3], a[2], a[1], a[0]);
-		}
-	}
-	y += sprintf(buffer+len+y, "  FWVersion = 0x%04x%s\n", ioc->facts.FWVersion, expVer);
-	y += sprintf(buffer+len+y, "  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
-	y += sprintf(buffer+len+y, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
-	y += sprintf(buffer+len+y, "  EventState = 0x%02x\n", ioc->facts.EventState);
-	y += sprintf(buffer+len+y, "  CurrentHostMfaHighAddr = 0x%08x\n",
-		 	ioc->facts.CurrentHostMfaHighAddr);
-	y += sprintf(buffer+len+y, "  CurrentSenseBufferHighAddr = 0x%08x\n",
-			ioc->facts.CurrentSenseBufferHighAddr);
-	y += sprintf(buffer+len+y, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
-	y += sprintf(buffer+len+y, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
+	/* Reset the adapter. Prevent more than 1 call to
+	 * mpt_do_ioc_recovery at any instant in time.
+	 */
+	spin_lock_irqsave(&ioc->diagLock, flags);
+	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
+		spin_unlock_irqrestore(&ioc->diagLock, flags);
+		return 0;
+	} else {
+		ioc->diagPending = 1;
+	}
+	spin_unlock_irqrestore(&ioc->diagLock, flags);
 
-	y += sprintf(buffer+len+y, "  RequestFrames @ 0x%p (Dma @ 0x%08x)\n",
-					ioc->req_alloc, ioc->req_alloc_dma);
-	/*
-	 *  Rounding UP to nearest 4-kB boundary here...
+	/* FIXME: If do_ioc_recovery fails, repeat....
 	 */
-	sz = (ioc->req_sz * ioc->req_depth) + 128;
-	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
-	y += sprintf(buffer+len+y, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
-					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
-	y += sprintf(buffer+len+y, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
-					4*ioc->facts.RequestFrameSize,
-					ioc->facts.GlobalCredits);
 
-	y += sprintf(buffer+len+y, "  ReplyFrames   @ 0x%p (Dma @ 0x%08x)\n",
-					ioc->reply_alloc, ioc->reply_alloc_dma);
-	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
-	y += sprintf(buffer+len+y, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
-					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
-	y += sprintf(buffer+len+y, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
-					ioc->facts.CurReplyFrameSize,
-					ioc->facts.ReplyQueueDepth);
+	if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
+		printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
+			rc, ioc->name);
+	}
 
-	*size = y;
+	spin_lock_irqsave(&ioc->diagLock, flags);
+	ioc->diagPending = 0;
+	if (ioc->alt_ioc)
+		ioc->alt_ioc->diagPending = 0;
+	spin_unlock_irqrestore(&ioc->diagLock, flags);
+
+	dprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
+
+	return rc;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -3268,7 +4938,7 @@
 		ds = "External Bus Reset";
 		break;
 	case MPI_EVENT_RESCAN:
-		ds = "Bus Rescan Event"; 
+		ds = "Bus Rescan Event";
 		/* Ok, do we need to do anything here? As far as
 		   I can tell, this is when a new device gets added
 		   to the loop. */
@@ -3296,6 +4966,9 @@
 		else
 			ds = "Events(OFF) Change";
 		break;
+	case MPI_EVENT_INTEGRATED_RAID:
+		ds = "Integrated Raid";
+		break;
 	/*
 	 *  MPT base "custom" events may be added here...
 	 */
@@ -3307,7 +4980,7 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
+/*
  *	ProcessEventNotification - Route a received EventNotificationReply to
  *	all currently regeistered event handlers.
  *	@ioc: Pointer to MPT_ADAPTER structure
@@ -3322,7 +4995,7 @@
 	u16 evDataLen;
 	u32 evData0 = 0;
 //	u32 evCtx;
-	int i;
+	int ii;
 	int r = 0;
 	int handlers = 0;
 	char *evStr;
@@ -3339,15 +5012,15 @@
 	}
 
 	evStr = EventDescriptionStr(event, evData0);
-	dprintk((KERN_INFO MYNAM ": %s: MPT event (%s=%02Xh) detected!\n",
+	dprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
 			ioc->name,
 			evStr,
 			event));
 
 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
 	printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
-	for (i = 0; i < evDataLen; i++)
-		printk(" %08x", le32_to_cpu(pEventReply->Data[i]));
+	for (ii = 0; ii < evDataLen; ii++)
+		printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
 	printk("\n");
 #endif
 
@@ -3365,6 +5038,8 @@
 	case MPI_EVENT_LINK_STATUS_CHANGE:	/* 07 */
 	case MPI_EVENT_LOOP_STATE_CHANGE:	/* 08 */
 	case MPI_EVENT_LOGOUT:			/* 09 */
+	case MPI_EVENT_INTEGRATED_RAID:		/* 0B */
+	case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:	/* 0C */
 	default:
 		break;
 	case MPI_EVENT_EVENT_CHANGE:		/* 0A */
@@ -3382,13 +5057,36 @@
 	}
 
 	/*
+	 * Should this event be logged? Events are written sequentially.
+	 * When buffer is full, start again at the top.
+	 */
+	if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
+		int idx;
+
+		idx = ioc->eventContext % ioc->eventLogSize;
+
+		ioc->events[idx].event = event;
+		ioc->events[idx].eventContext = ioc->eventContext;
+
+		for (ii = 0; ii < 2; ii++) {
+			if (ii < evDataLen)
+				ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
+			else
+				ioc->events[idx].data[ii] =  0;
+		}
+
+		ioc->eventContext++;
+	}
+
+
+	/*
 	 *  Call each currently registered protocol event handler.
 	 */
-	for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
-		if (MptEvHandlers[i]) {
-			dprintk((KERN_INFO MYNAM ": %s: Routing Event to event handler #%d\n",
-					ioc->name, i));
-			r += (*(MptEvHandlers[i]))(ioc, pEventReply);
+	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
+		if (MptEvHandlers[ii]) {
+			dprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
+					ioc->name, ii));
+			r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
 			handlers++;
 		}
 	}
@@ -3398,7 +5096,9 @@
 	 *  If needed, send (a single) EventAck.
 	 */
 	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
-		if ((i = SendEventAck(ioc, pEventReply)) != 0) {
+		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
+			printk(MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
+					ioc->name, ii);
 		}
 	}
 
@@ -3427,7 +5127,7 @@
 
 	switch(log_info) {
 /* FCP Initiator */
-    	case MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME:
+	case MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME:
 		desc = "Received an out of order frame - unsupported";
 		break;
 	case MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME:
@@ -3483,7 +5183,7 @@
 		desc = "Not sent because login to remote node not validated";
 		break;
 	case MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND:
-		desc = "Cleared from the outbound after a logout";
+		desc = "Cleared from the outbound queue after a logout";
 		break;
 	case MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN:
 		desc = "Cleared waiting for data after a logout";
@@ -3516,7 +5216,7 @@
 		break;
 	}
 
-	printk(KERN_INFO MYNAM ": %s: LogInfo(0x%08x): SubCl={%s}",
+	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}",
 			ioc->name, log_info, subcl_str[subcl]);
 	if (SubCl == MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET)
 		printk(", byte_offset=%d\n", log_info & MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET);
@@ -3539,7 +5239,7 @@
 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
 {
 	/* FIXME! */
-	printk(KERN_INFO MYNAM ": %s: LogInfo(0x%08x)\n", ioc->name, log_info);
+	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x)\n", ioc->name, log_info);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -3553,7 +5253,7 @@
  *	Specialized driver registration routine for the isense driver.
  */
 int
-mpt_register_ascqops_strings(/*ASCQ_Table_t*/void *ascqTable, int ascqtbl_sz, const char **opsTable)
+mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable)
 {
 	int r = 0;
 
@@ -3562,6 +5262,7 @@
 		mpt_ASCQ_TableSz = ascqtbl_sz;
 		mpt_ScsiOpcodesPtr = opsTable;
 		printk(KERN_INFO MYNAM ": English readable SCSI-3 strings enabled:-)\n");
+		isense_idx = last_drv_idx;
 		r = 1;
 	}
 	MOD_INC_USE_COUNT;
@@ -3582,11 +5283,15 @@
 	mpt_ASCQ_TableSz = 0;
 	mpt_ScsiOpcodesPtr = NULL;
 	printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n");
+	isense_idx = -1;
 	MOD_DEC_USE_COUNT;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
+EXPORT_SYMBOL(mpt_adapters);
+EXPORT_SYMBOL(mpt_proc_root_dir);
+EXPORT_SYMBOL(DmpService);
 EXPORT_SYMBOL(mpt_register);
 EXPORT_SYMBOL(mpt_deregister);
 EXPORT_SYMBOL(mpt_event_register);
@@ -3597,12 +5302,16 @@
 EXPORT_SYMBOL(mpt_put_msg_frame);
 EXPORT_SYMBOL(mpt_free_msg_frame);
 EXPORT_SYMBOL(mpt_send_handshake_request);
+EXPORT_SYMBOL(mpt_handshake_req_reply_wait);
 EXPORT_SYMBOL(mpt_adapter_find_first);
 EXPORT_SYMBOL(mpt_adapter_find_next);
 EXPORT_SYMBOL(mpt_verify_adapter);
+EXPORT_SYMBOL(mpt_GetIocState);
 EXPORT_SYMBOL(mpt_print_ioc_summary);
 EXPORT_SYMBOL(mpt_lan_index);
 EXPORT_SYMBOL(mpt_stm_index);
+EXPORT_SYMBOL(mpt_HardResetHandler);
+EXPORT_SYMBOL(mpt_config);
 
 EXPORT_SYMBOL(mpt_register_ascqops_strings);
 EXPORT_SYMBOL(mpt_deregister_ascqops_strings);
@@ -3611,12 +5320,13 @@
 EXPORT_SYMBOL(mpt_ScsiOpcodesPtr);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
+/*
  *	fusion_init - Fusion MPT base driver initialization routine.
  *
  *	Returns 0 for success, non-zero for failure.
  */
-int __init fusion_init(void)
+int __init
+fusion_init(void)
 {
 	int i;
 
@@ -3636,12 +5346,22 @@
 		MptResetHandlers[i] = NULL;
 	}
 
+	DmpService = NULL;
+
 	/* NEW!  20010120 -sralston
 	 *  Register ourselves (mptbase) in order to facilitate
 	 *  EventNotification handling.
 	 */
 	mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
 
+	/* Register for hard reset handling callbacks.
+	 */
+	if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
+		dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
+	} else {
+		/* FIXME! */
+	}
+
 	if ((i = mpt_pci_scan()) < 0)
 		return i;
 
@@ -3649,13 +5369,14 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
+/*
  *	fusion_exit - Perform driver unload cleanup.
  *
  *	This routine frees all resources associated with each MPT adapter
  *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
  */
-static void fusion_exit(void)
+static void
+fusion_exit(void)
 {
 	MPT_ADAPTER *this;
 
@@ -3665,7 +5386,7 @@
 	 *  Moved this *above* removal of all MptAdapters!
 	 */
 #ifdef CONFIG_PROC_FS
-	procmpt_destroy();
+	(void) procmpt_destroy();
 #endif
 
 	while (! Q_IS_EMPTY(&MptAdapters)) {
@@ -3673,6 +5394,8 @@
 		Q_DEL_ITEM(this);
 		mpt_adapter_dispose(this);
 	}
+
+	mpt_reset_deregister(mpt_base_index);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/mptbase.h linux/drivers/message/fusion/mptbase.h
--- linux.orig/drivers/message/fusion/mptbase.h	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/message/fusion/mptbase.h	2002-07-20 01:08:27.000000000 +0000
@@ -8,11 +8,12 @@
  *  Credits:
  *     (see mptbase.c)
  *
- *  Copyright (c) 1999-2001 LSI Logic Corporation
+ *  Copyright (c) 1999-2002 LSI Logic Corporation
  *  Originally By: Steven J. Ralston
- *  (mailto:Steve.Ralston@lsil.com)
+ *  (mailto:sjralston1@netscape.net)
+ *  (mailto:Pam.Delaney@lsil.com)
  *
- *  $Id: mptbase.h,v 1.46.2.2.2.2 2001/09/18 03:22:29 sralston Exp $
+ *  $Id: mptbase.h,v 1.103 2002/02/27 20:24:38 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -55,6 +56,7 @@
 /*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 #include "linux_compat.h"	/* linux-2.2.x (vs. -2.4.x) tweaks */
+#include "scsi3.h"		/* SCSI defines */
 
 #include "lsi/mpi_type.h"
 #include "lsi/mpi.h"		/* Fusion MPI(nterface) basic defs */
@@ -62,6 +64,7 @@
 #include "lsi/mpi_cnfg.h"	/* IOC configuration support */
 #include "lsi/mpi_init.h"	/* SCSI Host (initiator) protocol support */
 #include "lsi/mpi_lan.h"	/* LAN over FC protocol support */
+#include "lsi/mpi_raid.h"	/* Integrated Mirroring support */
 
 #include "lsi/mpi_fc.h"		/* Fibre Channel (lowlevel) support */
 #include "lsi/mpi_targ.h"	/* SCSI/FCP Target protcol support */
@@ -74,11 +77,11 @@
 #endif
 
 #ifndef COPYRIGHT
-#define COPYRIGHT	"Copyright (c) 1999-2001 " MODULEAUTHOR
+#define COPYRIGHT	"Copyright (c) 1999-2002 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"1.02.02"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-1.02.02"
+#define MPT_LINUX_VERSION_COMMON	"2.00.11"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-2.00.11"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -89,39 +92,77 @@
  *  Fusion MPT(linux) driver configurable stuff...
  */
 #define MPT_MAX_ADAPTERS		16
-#define MPT_MAX_PROTOCOL_DRIVERS	8
+#define MPT_MAX_PROTOCOL_DRIVERS	16
+#define MPT_MAX_BUS			1
 #define MPT_MAX_FC_DEVICES		255
+#define MPT_MAX_SCSI_DEVICES		16
+#define MPT_LAST_LUN			31
+#define MPT_SENSE_BUFFER_ALLOC		64
+	/* allow for 256 max sense alloc, but only 255 max request */
+#if MPT_SENSE_BUFFER_ALLOC >= 256
+#	undef MPT_SENSE_BUFFER_ALLOC
+#	define MPT_SENSE_BUFFER_ALLOC	256
+#	define MPT_SENSE_BUFFER_SIZE	255
+#else
+#	define MPT_SENSE_BUFFER_SIZE	MPT_SENSE_BUFFER_ALLOC
+#endif
 
-#define MPT_MISCDEV_BASENAME		"mptctl"
-#define MPT_MISCDEV_PATHNAME		"/dev/" MPT_MISCDEV_BASENAME
+#define MPT_NAME_LENGTH			32
 
 #define MPT_PROCFS_MPTBASEDIR		"mpt"
 						/* chg it to "driver/fusion" ? */
-#define MPT_PROCFS_SUMMARY_NODE		MPT_PROCFS_MPTBASEDIR "/summary"
-#define MPT_PROCFS_SUMMARY_PATHNAME	"/proc/" MPT_PROCFS_SUMMARY_NODE
-#define MPT_FW_REV_MAGIC_ID_STRING	"FwRev="
+#define MPT_PROCFS_SUMMARY_ALL_NODE		MPT_PROCFS_MPTBASEDIR "/summary"
+#define MPT_PROCFS_SUMMARY_ALL_PATHNAME		"/proc/" MPT_PROCFS_SUMMARY_ALL_NODE
+#define MPT_FW_REV_MAGIC_ID_STRING		"FwRev="
 
-#ifdef __KERNEL__	/* { */
 #define  MPT_MAX_REQ_DEPTH		1023
-#define  MPT_REQ_DEPTH			256
+#define  MPT_DEFAULT_REQ_DEPTH		256
 #define  MPT_MIN_REQ_DEPTH		128
 
 #define  MPT_MAX_REPLY_DEPTH		MPT_MAX_REQ_DEPTH
-#define  MPT_REPLY_DEPTH		128
+#define  MPT_DEFAULT_REPLY_DEPTH	128
 #define  MPT_MIN_REPLY_DEPTH		8
 #define  MPT_MAX_REPLIES_PER_ISR	32
 
 #define  MPT_MAX_FRAME_SIZE		128
-#define  MPT_REQ_SIZE			128
-#define  MPT_REPLY_SIZE			128
+#define  MPT_DEFAULT_FRAME_SIZE		128
 
-#define  MPT_SG_BUCKETS_PER_HUNK	1
+#define  MPT_SG_REQ_128_SCALE		1
+#define  MPT_SG_REQ_96_SCALE		2
+#define  MPT_SG_REQ_64_SCALE		4
 
-#ifdef MODULE
-#define  MPT_REQ_DEPTH_RANGE_STR	__MODULE_STRING(MPT_MIN_REQ_DEPTH) "-" __MODULE_STRING(MPT_MAX_REQ_DEPTH)
-#define  MPT_REPLY_DEPTH_RANGE_STR	__MODULE_STRING(MPT_MIN_REPLY_DEPTH) "-" __MODULE_STRING(MPT_MAX_REPLY_DEPTH)
-#define  MPT_REPLY_SIZE_RANGE_STR	__MODULE_STRING(MPT_MIN_REPLY_SIZE) "-" __MODULE_STRING(MPT_MAX_FRAME_SIZE)
-#endif
+#define	 CAN_SLEEP			1
+#define  NO_SLEEP			0
+
+/* 
+ * SCSI transfer rate defines. 
+ */
+#define MPT_ULTRA320			0x08
+#define MPT_ULTRA160			0x09
+#define MPT_ULTRA2			0x0A
+#define MPT_ULTRA			0x0C
+#define MPT_FAST			0x19
+#define MPT_SCSI			0x32
+#define MPT_ASYNC			0xFF
+
+#define MPT_NARROW			0
+#define MPT_WIDE			1
+
+#ifdef __KERNEL__	/* { */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+#include <linux/proc_fs.h>
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * Attempt semi-consistent error & warning msgs across
+ * MPT drivers.  NOTE: Users of these macro defs must
+ * themselves define their own MYNAM.
+ */
+#define MYIOC_s_INFO_FMT		KERN_INFO MYNAM ": %s: "
+#define MYIOC_s_NOTE_FMT		KERN_NOTICE MYNAM ": %s: "
+#define MYIOC_s_WARN_FMT		KERN_WARNING MYNAM ": %s: WARNING - "
+#define MYIOC_s_ERR_FMT			KERN_ERR MYNAM ": %s: ERROR - "
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -133,6 +174,7 @@
 	MPTSCSIH_DRIVER,	/* MPT SCSI host (initiator) class */
 	MPTLAN_DRIVER,		/* MPT LAN class */
 	MPTSTM_DRIVER,		/* MPT SCSI target mode class */
+	MPTDMP_DRIVER,		/* MPT Dynamic Multi-pathing class */
 	MPTUNKNOWN_DRIVER
 } MPT_DRIVER_CLASS;
 
@@ -145,10 +187,21 @@
 		struct _MPT_FRAME_HDR	*forw;
 		struct _MPT_FRAME_HDR	*back;
 		u32			 arg1;
+		u32			 pad;
 		void			*argp1;
+#ifndef MPT_SCSI_USE_NEW_EH
+		void			*argp2;
+#endif
 	} linkage;
 	/*
-	 * NOTE: On non-32-bit systems, where pointers are LARGE,
+	 * NOTE: When request frames are free, on the linkage structure
+	 * contets are valid.  All other values are invalid.
+	 * In particular, do NOT reply on offset [2]
+	 * (in words) being the * message context.
+	 * The message context must be reset (computed via base address
+	 * + an offset) prior to issuing any command.
+	 *
+	 * NOTE2: On non-32-bit systems, where pointers are LARGE,
 	 * using the linkage pointers destroys our sacred MsgContext
 	 * field contents.  But we don't care anymore because these
 	 * are now reset in mpt_put_msg_frame() just prior to sending
@@ -169,6 +222,12 @@
 			} fld;
 		} msgctxu;
 	} hwhdr;
+	/*
+	 * Remark: 32 bit identifier:
+	 *  31-24: reserved
+	 *  23-16: call back index
+	 *  15-0 : request index
+	 */
 } MPT_FRAME_TRACKER;
 
 /*
@@ -189,6 +248,11 @@
 	} u;
 } MPT_FRAME_HDR;
 
+#define MPT_REQ_MSGFLAGS_DROPME		0x80
+
+/* Used for tracking the free request frames
+ * and free reply frames.
+ */
 typedef struct _MPT_Q_TRACKER {
 	MPT_FRAME_HDR	*head;
 	MPT_FRAME_HDR	*tail;
@@ -214,9 +278,20 @@
 	struct _Q_ITEM	*tail;
 } Q_TRACKER;
 
+typedef struct _MPT_DONE_Q {
+	struct _MPT_DONE_Q	*forw;
+	struct _MPT_DONE_Q	*back;
+	void			*argp;
+} MPT_DONE_Q;
+
+typedef struct _DONE_Q_TRACKER {
+	MPT_DONE_Q	*head;
+	MPT_DONE_Q	*tail;
+} DONE_Q_TRACKER;
 
 /*
- *  Chip-specific stuff...
+ *  Chip-specific stuff... FC929 delineates break between
+ *  FC and Parallel SCSI parts. Do NOT re-order.
  */
 
 typedef enum {
@@ -237,7 +312,9 @@
 	u32	WriteSequence;	/* 04     Write Sequence register    */
 	u32	Diagnostic;	/* 08     Diagnostic register        */
 	u32	TestBase;	/* 0C     Test Base Address          */
-	u32	Reserved1[8];	/* 10-2F  reserved for future use    */
+	u32	DiagRwData;	/* 10     Read Write Data (fw download)   */
+	u32	DiagRwAddress;	/* 14     Read Write Address (fw download)*/
+	u32	Reserved1[6];	/* 18-2F  reserved for future use    */
 	u32	IntStatus;	/* 30     Interrupt Status           */
 	u32	IntMask;	/* 34     Interrupt Mask             */
 	u32	Reserved2[2];	/* 38-3F  reserved for future use    */
@@ -256,60 +333,271 @@
  */
 
 
+/*
+ *	Dynamic Multi-Pathing specific stuff...
+ */
+#define DMP_MAX_PATHS	8
+
+typedef struct _PathInfo {
+	u8		 ioc;
+	u8		 target;
+	u8		 pad;
+	u8		 pflags;
+} PathInfo;
+
+#define PATHINFO_FLAGS_OWNED		0x01
+#define PATHINFO_FLAGS_EXISTS		0x02
+#define PATHINFO_FLAGS_AVAILABLE	0x04
+#define PATHINFO_FLAGS_SECONDARY	0x08
+
+#define PFLAGS_EXISTS_AND_AVAIL		(PATHINFO_FLAGS_EXISTS|PATHINFO_FLAGS_AVAILABLE)
+#define PFLAGS_AVAIL_AND_OWNED		(PATHINFO_FLAGS_AVAILABLE|PATHINFO_FLAGS_OWNED)
+
+typedef struct _ScsiCmndTracker {
+	void			*head;
+	void			*tail;
+} ScsiCmndTracker;
+
+
+/*
+ *	VirtDevice - FC LUN device or SCSI target device
+ *	(used to be FCSCSI_TARGET)
+ */
+typedef struct _VirtDevice {
+	struct _VirtDevice	*forw;
+	struct _VirtDevice	*back;
+	rwlock_t		 VdevLock;
+	int			 ref_cnt;
+	u8			 tflags;
+	u8			 ioc_id;
+	u8			 target_id;
+	u8			 bus_id;
+	u8			 minSyncFactor;	/* 0xFF is async */
+	u8			 maxOffset;	/* 0 if async */
+	u8			 maxWidth;	/* 0 if narrow, 1 if wide*/
+	u8			 negoFlags;	/* 0 if WDTR/SDTR allowed */
+	u8			 raidVolume;	/* set, if RAID Volume */
+	u8			 rsvd;		/* alignment */
+	u16			 rsvd1raid;
+	int			 npaths;
+	u16			 fc_phys_lun;
+	u16			 fc_xlat_lun;
+	int			 stall_detected;
+	PathInfo		 path[DMP_MAX_PATHS];
+	struct timer_list	 stall_timer;
+	struct timer_list	 retry_timer;
+	struct timer_list	 gone_timer;
+	ScsiCmndTracker		 WaitQ;
+	ScsiCmndTracker		 SentQ;
+	ScsiCmndTracker		 DoneQ;
+//--- LUN split here?
+	u8			 sense[SCSI_STD_SENSE_BYTES];		/* 18 */
+	u8			 rsvd2[2];	/* alignment */
+	u32			 luns;		/* Max LUNs is 32 */
+	u8			 inq_data[SCSI_STD_INQUIRY_BYTES];	/* 36 */
+	u8			 pad0[4];
+	u8			 uniq_prepad[8];
+	u8			 inq00_data[20];
+	u8			 pad1[4];
+		/* IEEE Registered Extended Identifier
+		   obtained via INQUIRY VPD page 0x83 */
+	u8			 uniq_data[20];
+	u8			 pad2[4];
+	u8			 inqC3_data[12];
+	u8			 pad3[4];
+	u8			 inqC9_data[12];
+	u8			 pad4[4];
+	u8			 dev_vol_name[64];
+} VirtDevice;
+
+/*
+ *  Fibre Channel (SCSI) target device and associated defines...
+ */
+#define MPT_TARGET_DEFAULT_DV_STATUS	0
+#define MPT_TARGET_FLAGS_VALID_NEGO	0x01
+#define MPT_TARGET_FLAGS_VALID_INQUIRY	0x02
+#define MPT_TARGET_FLAGS_VALID_SENSE	0x04
+#define MPT_TARGET_FLAGS_Q_YES		0x08
+
+#define MPT_TARGET_NO_NEGO_WIDE		0x01
+#define MPT_TARGET_NO_NEGO_SYNC		0x02
+
+typedef struct _VirtDevTracker {
+	struct _VirtDevice	*head;
+	struct _VirtDevice	*tail;
+	rwlock_t		 VlistLock;
+	int			 pad;
+} VirtDevTracker;
+
+
+/*
+ *	/proc/mpt interface
+ */
+typedef struct {
+	const char	*name;
+	mode_t		 mode;
+	int		 pad;
+	read_proc_t	*read_proc;
+	write_proc_t	*write_proc;
+} mpt_proc_entry_t;
+
+#define MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len) \
+do { \
+	len -= offset;			\
+	if (len < request) {		\
+		*eof = 1;		\
+		if (len <= 0)		\
+			return 0;	\
+	} else				\
+		len = request;		\
+	*start = buf + offset;		\
+	return len;			\
+} while (0)
+
+
+/*
+ *	IOCTL structure and associated defines
+ */
+
+#define MPT_IOCTL_STATUS_DID_TIMEOUT	0x01	/* The current IOCTL timed out */
+#define MPT_IOCTL_STATUS_RF_VALID	0x02	/* The Reply Frame is VALID */
+#define MPT_IOCTL_STATUS_TIMER_ACTIVE	0x04	/* The timer is running */
+#define MPT_IOCTL_STATUS_SENSE_VALID	0x08	/* Sense data is valid */
+#define MPT_IOCTL_STATUS_COMMAND_GOOD	0x10	/* Command Status GOOD */
+
+typedef struct _MPT_IOCTL {
+	struct _MPT_ADAPTER	*ioc;
+	struct timer_list	 timer;		/* timer function for this adapter */
+	u8			 ReplyFrame[MPT_DEFAULT_FRAME_SIZE];	/* reply frame data */
+	u8			 sense[MPT_SENSE_BUFFER_ALLOC];
+	int			 wait_done;	/* wake-up value for this ioc */
+	u8			 cmd;		/* current command */
+	u8			 status;	/* current command status */
+	u8			 pad[2];
+} MPT_IOCTL;
+
+/*
+ *  Event Structure and define
+ */
+#define MPTCTL_EVENT_LOG_SIZE		(0x0000000A)
+typedef struct _mpt_ioctl_events {
+	u32	event;		/* Specified by define above */
+	u32	eventContext;	/* Index or counter */
+	int	data[2];	/* First 8 bytes of Event Data */
+} MPT_IOCTL_EVENTS;
+
+/*
+ * CONFIGPARM status  defines
+ */
+#define MPT_CONFIG_GOOD		MPI_IOCSTATUS_SUCCESS
+#define MPT_CONFIG_ERROR	0x002F
+
+/*
+ *	Substructure to store SCSI specific configuration page data
+ */
+#define MPT_SCSICFG_NEGOTIATE		0x01	/* Negotiate on next IO */
+#define MPT_SCSICFG_NEED_DV		0x02	/* Schedule DV */
+#define MPT_SCSICFG_DV_PENDING		0x04	/* DV on this physical id pending */
+#define MPT_SCSICFG_DV_DONE		0x08	/* DV on this physical id complete */
+
+#define MPT_SCSICFG_USE_NVRAM		0x01	/* WriteSDP1 using NVRAM */
+#define MPT_SCSICFG_ALL_IDS		0x02	/* WriteSDP1 to all IDS */
+
+typedef	struct _ScsiCfgData {
+	int		*nvram;			/* table of device NVRAM values */
+	IOCPage3_t	*pIocPg3;		/* table of physical disks */
+	u8		 dvStatus[MPT_MAX_SCSI_DEVICES];
+	int		 isRaid;		/* bit field, 1 if RAID */
+	u8		 minSyncFactor;		/* 0xFF if async */
+	u8		 maxSyncOffset;		/* 0 if async */
+	u8		 maxBusWidth;		/* 0 if narrow, 1 if wide */
+	u8		 busType;		/* SE, LVD, HD */
+	u8		 sdp1version;		/* SDP1 version */
+	u8		 sdp1length;		/* SDP1 length  */
+	u8		 sdp0version;		/* SDP0 version */
+	u8		 sdp0length;		/* SDP0 length  */
+	u8		 dvScheduled;		/* 1 if scheduled */
+	u8		 forceDv;		/* 1 to force DV scheduling */
+	u8		 rsvd[2];
+} ScsiCfgData;
+
+/*
+ *  Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
+ */
 typedef struct _MPT_ADAPTER
 {
 	struct _MPT_ADAPTER	*forw;
 	struct _MPT_ADAPTER	*back;
-	int			 id;		/* Unique adapter id {0,1,2,...} */
-	int			 pci_irq;
-	char			 name[32];	/* "iocN"             */
+	int			 id;		/* Unique adapter id N {0,1,2,...} */
+	int			 pci_irq;	/* This irq           */
+	char			 name[MPT_NAME_LENGTH];	/* "iocN"             */
 	char			*prod_name;	/* "LSIFC9x9"         */
-	u32			 mem_phys;	/* == f4020000 (mmap) */
 	volatile SYSIF_REGS	*chip;		/* == c8817000 (mmap) */
-	CHIP_TYPE		 chip_type;
-	int			 mem_size;
+	volatile SYSIF_REGS	*pio_chip;	/* Programmed IO (downloadboot) */
+	u32			 mem_phys;	/* == f4020000 (mmap) */
+	u32			 pio_mem_phys;	/* Programmed IO (downloadboot) */
+	int			 mem_size;	/* mmap memory size */
 	int			 alloc_total;
 	u32			 last_state;
 	int			 active;
-	int			 sod_reset;
-	unsigned long		 last_kickstart;
-	u8			*reply_alloc;		/* Reply frames alloc ptr */
+	u8			*reply_alloc;	/* Reply frames alloc ptr */
 	dma_addr_t		 reply_alloc_dma;
-	MPT_FRAME_HDR		*reply_frames;		/* Reply frames - rounded up! */
+	MPT_FRAME_HDR		*reply_frames;	/* Reply msg frames - rounded up! */
 	dma_addr_t		 reply_frames_dma;
-	int			 reply_depth;
-	int			 reply_sz;
+	u32			 reply_frames_low_dma;
+	int			 reply_depth;	/* Num Allocated reply frames */
+	int			 reply_sz;	/* Reply frame size */
+	CHIP_TYPE		 chip_type;
 		/* We (host driver) get to manage our own RequestQueue! */
-	u8			*req_alloc;		/* Request frames alloc ptr */
+	u8			*req_alloc;	/* Request frames alloc ptr */
 	dma_addr_t		 req_alloc_dma;
-	MPT_FRAME_HDR		*req_frames;		/* Request msg frames for PULL mode! */
+	MPT_FRAME_HDR		*req_frames;	/* Request msg frames - rounded up! */
 	dma_addr_t		 req_frames_dma;
-	int			 req_depth;
-	int			 req_sz;
-	MPT_Q_TRACKER		 FreeQ;
+	u32			 req_frames_low_dma;
+	int			 req_depth;	/* Number of request frames */
+	int			 req_sz;	/* Request frame size (bytes) */
 	spinlock_t		 FreeQlock;
+	MPT_Q_TRACKER		 FreeQ;
 		/* Pool of SCSI sense buffers for commands coming from
 		 * the SCSI mid-layer.  We have one 256 byte sense buffer
 		 * for each REQ entry.
 		 */
 	u8			*sense_buf_pool;
 	dma_addr_t		 sense_buf_pool_dma;
-	struct pci_dev		*pcidev;
-/*	atomic_t		 userCnt;	*/
-	u8			*memmap;
+	u32			 sense_buf_low_dma;
 	int			 mtrr_reg;
-	struct Scsi_Host	*sh;
+	void			*pcidev;	/* struct pci_dev pointer */
+	u8			*memmap;	/* mmap address */
+	struct Scsi_Host	*sh;		/* Scsi Host pointer */
+	ScsiCfgData		spi_data;	/* Scsi config. data */
+	MPT_IOCTL		*ioctl;		/* ioctl data pointer */
 	struct proc_dir_entry	*ioc_dentry;
-	struct _MPT_ADAPTER	*alt_ioc;
+	struct _MPT_ADAPTER	*alt_ioc;	/* ptr to 929 bound adapter port */
+	spinlock_t		 diagLock;	/* diagnostic reset lock */
+	int			 diagPending;
+	u32			 biosVersion;	/* BIOS version from IO Unit Page 2 */
+	int			 eventTypes;	/* Event logging parameters */
+	int			 eventContext;	/* Next event context */
+	int			 eventLogSize;	/* Max number of cached events */
+	struct _mpt_ioctl_events *events;	/* pointer to event log */
+	u8			*FWImage;	/* Pointer to FW */
+	dma_addr_t		 FWImage_dma;
+	Q_TRACKER		 configQ;	/* linked list of config. requests */
 	int			 hs_reply_idx;
+#ifndef MFCNT
+	u32			 pad0;
+#else
+	u32			 mfcnt;
+#endif
 	u32			 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
 	u16			 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
 	IOCFactsReply_t		 facts;
 	PortFactsReply_t	 pfacts[2];
+	FCPortPage0_t		 fc_port_page0[2];
 	LANPage0_t		 lan_cnfg_page0;
 	LANPage1_t		 lan_cnfg_page1;
 	u8			 FirstWhoInit;
-	u8			 pad1[3];
+	u8			 pad1[7];
 } MPT_ADAPTER;
 
 
@@ -324,7 +612,6 @@
  *    0 = not Ok ...
  */
 typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
-
 typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);
 typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
 /* reset_phase defs */
@@ -344,6 +631,47 @@
 #define MPT_HOSTEVENT_IOC_BRINGUP	0x91
 #define MPT_HOSTEVENT_IOC_RECOVER	0x92
 
+/* 32 vs 64 bit SGL code.
+ *
+ */
+#if defined(__ia64__)
+typedef SGESimple64_t	MptSge_t;
+typedef SGEChain64_t	MptChain_t;
+
+#define cpu_to_leXX(y, p) { \
+	u32 low = (u32) (y & 0xFFFFFFFF); \
+	u32 high = (u32) (y >> 32); \
+	p.Low = cpu_to_le32(low); \
+	p.High = cpu_to_le32(high); \
+}
+
+#define leXX_to_cpu(y, p) { \
+	y = (dma_addr_t) le32_to_cpu(p.High); \
+	y = (y << 32); \
+	y |= le32_to_cpu(p.Low); \
+}
+
+#define MPT_SGE_ADDRESS_SIZE		MPI_SGE_FLAGS_64_BIT_ADDRESSING
+#define MPT_SCSIIO_MSG_FLAGS		MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64
+
+
+#else
+
+typedef SGESimple32_t	MptSge_t;
+typedef SGEChain32_t	MptChain_t;
+#define cpu_to_leXX(y,p) { \
+	p = cpu_to_le32(y); \
+}
+
+#define leXX_to_cpu(y,p) { \
+	y = le32_to_cpu(p); \
+}
+
+#define MPT_SGE_ADDRESS_SIZE		MPI_SGE_FLAGS_32_BIT_ADDRESSING
+#define MPT_SCSIIO_MSG_FLAGS		MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32
+
+#endif
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Funky (private) macros...
@@ -360,7 +688,8 @@
 #define dhsprintk(x)
 #endif
 
-#if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
+//#if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
+#if defined(MPT_DEBUG_MSG_FRAME)
 #define dmfprintk(x)  printk x
 #else
 #define dmfprintk(x)
@@ -372,24 +701,35 @@
 #define dirqprintk(x)
 #endif
 
-#ifdef MPT_DEBUG_EVENTS
-#define deventprintk(x)  printk x
+#ifdef MPT_DEBUG_SG
+#define dsgprintk(x)  printk x
 #else
-#define deventprintk(x)
+#define dsgprintk(x)
 #endif
 
-#ifdef MPT_DEBUG_SPINLOCK
-#define dslprintk(x)  printk x
+#ifdef MPT_DEBUG_DV
+#define ddvprintk(x)  printk x
 #else
-#define dslprintk(x)
+#define ddvprintk(x)
 #endif
 
-#ifdef MPT_DEBUG_SG
-#define dsgprintk(x)  printk x
+#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
+#define ddvtprintk(x)  printk x
 #else
-#define dsgprintk(x)
+#define ddvtprintk(x)
 #endif
 
+#ifdef MPT_DEBUG_IOCTL
+#define dctlprintk(x) printk x
+#else
+#define dctlprintk(x)
+#endif
+
+#ifdef MPT_DEBUG_RESET
+#define dtmprintk(x) printk x
+#else
+#define dtmprintk(x)
+#endif
 
 #define MPT_INDEX_2_MFPTR(ioc,idx) \
 	(MPT_FRAME_HDR*)( (u8*)(ioc)->req_frames + (ioc)->req_sz * (idx) )
@@ -397,6 +737,9 @@
 #define MFPTR_2_MPT_INDEX(ioc,mf) \
 	(int)( ((u8*)mf - (u8*)(ioc)->req_frames) / (ioc)->req_sz )
 
+#define MPT_INDEX_2_RFPTR(ioc,idx) \
+	(MPT_FRAME_HDR*)( (u8*)(ioc)->reply_frames + (ioc)->req_sz * (idx) )
+
 #define Q_INIT(q,type)  (q)->head = (q)->tail = (type*)(q)
 #define Q_IS_EMPTY(q)   ((Q_ITEM*)(q)->head == (Q_ITEM*)(q))
 
@@ -425,7 +768,6 @@
 	_forw->back = _back; \
 }
 
-
 #define SWAB4(value) \
 	(u32)(   (((value) & 0x000000ff) << 24) \
 	       | (((value) & 0x0000ff00) << 8)  \
@@ -457,64 +799,143 @@
 
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#endif		/* } __KERNEL__ */
 
+/*
+ * MPT_SCSI_HOST defines - Used by the IOCTL and the SCSI drivers
+ * Private to the driver.
+ */
+/* LOCAL structure and fields used when processing
+ * internally generated commands. These include:
+ * bus scan, dv and config requests.
+ */
+typedef struct _MPT_LOCAL_REPLY {
+	ConfigPageHeader_t header;
+	int	completion;
+	u8	sense[SCSI_STD_SENSE_BYTES];
+	u8	scsiStatus;
+	u8	skip;
+	u32	pad;
+} MPT_LOCAL_REPLY;
+
+#define MPT_HOST_BUS_UNKNOWN		(0xFF)
+#define MPT_HOST_TOO_MANY_TM		(0x05)
+#define MPT_HOST_NVRAM_INVALID		(0xFFFFFFFF)
+#define MPT_HOST_NO_CHAIN		(0xFFFFFFFF)
+#define MPT_NVRAM_MASK_TIMEOUT		(0x000000FF)
+#define MPT_NVRAM_SYNC_MASK		(0x0000FF00)
+#define MPT_NVRAM_SYNC_SHIFT		(8)
+#define MPT_NVRAM_DISCONNECT_ENABLE	(0x00010000)
+#define MPT_NVRAM_ID_SCAN_ENABLE	(0x00020000)
+#define MPT_NVRAM_LUN_SCAN_ENABLE	(0x00040000)
+#define MPT_NVRAM_TAG_QUEUE_ENABLE	(0x00080000)
+#define MPT_NVRAM_WIDE_DISABLE		(0x00100000)
+#define MPT_NVRAM_BOOT_CHOICE		(0x00200000)
+
+typedef struct _MPT_SCSI_HOST {
+	MPT_ADAPTER		 *ioc;
+	int			  port;
+	u32			  pad0;
+	struct scsi_cmnd	**ScsiLookup;
+		/* Pool of buffers for chaining. ReqToChain
+		 * and ChainToChain track index of chain buffers.
+		 * ChainBuffer (DMA) virt/phys addresses.
+		 * FreeChainQ (lock) locking mechanisms.
+		 */
+	int			 *ReqToChain;
+	int			 *ChainToChain;
+	u8			 *ChainBuffer;
+	dma_addr_t		  ChainBufferDMA;
+	MPT_Q_TRACKER		  FreeChainQ;
+	spinlock_t		  FreeChainQlock;
+	u32			  qtag_tick;
+	VirtDevice		**Targets;
+	MPT_LOCAL_REPLY		 *pLocal;		/* used for internal commands */
+	struct timer_list	  timer;
+	struct timer_list	  TMtimer;		/* Timer for TM commands ONLY */
+		/* Pool of memory for holding SCpnts before doing
+		 * OS callbacks. freeQ is the free pool.
+		 */
+	u8			 *memQ;
+	DONE_Q_TRACKER		  freeQ;
+	DONE_Q_TRACKER		  doneQ;		/* Holds Linux formmatted requests */
+	DONE_Q_TRACKER		  pendingQ;		/* Holds MPI formmatted requests */
+	MPT_Q_TRACKER		  taskQ;		/* TM request Q */
+	spinlock_t		  freedoneQlock;
+	int			  taskQcnt;
+	u8			  numTMrequests;
+	u8			  tmPending;
+	u8			  resetPending;
+	u8			  is_spi;		/* Parallel SCSI i/f */
+	u8			  negoNvram;		/* DV disabled, nego NVRAM */
+	u8			  is_multipath;		/* Multi-path compatible */
+	u8			  rsvd[2];
+	MPT_FRAME_HDR		 *tmPtr;		/* Ptr to TM request*/
+	MPT_FRAME_HDR		 *cmdPtr;		/* Ptr to nonOS request */
+	struct scsi_cmnd	 *abortSCpnt;
+	MPT_LOCAL_REPLY		  localReply;		/* internal cmd reply struct */
+} MPT_SCSI_HOST;
+
+/*
+ *	Structure for overlaying onto scsi_cmnd->SCp area
+ *	NOTE: SCp area is 36 bytes min, 44 bytes max?
+ */
+typedef struct _scPrivate {
+	struct scsi_cmnd	*forw;
+	struct scsi_cmnd	*back;
+	void			*p1;
+	void			*p2;
+	u8			 io_path_id;	/* DMP */
+	u8			 pad[7];
+} scPrivate;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	More Dynamic Multi-Pathing stuff...
+ */
+
+/* Forward decl, a strange C thing, to prevent gcc compiler warnings */
+struct scsi_cmnd;
 
 /*
- *  MPT Control IOCTLs and structures
+ *	DMP service layer structure / API interface
  */
-#define MPT_MAGIC_NUMBER	'm'
-#define MPTRWPERF		_IOWR(MPT_MAGIC_NUMBER,0,struct mpt_raw_r_w)
-#define MPTRWPERF_CHK		_IOR(MPT_MAGIC_NUMBER,13,struct mpt_raw_r_w)
-#define MPTRWPERF_RESET		_IOR(MPT_MAGIC_NUMBER,14,struct mpt_raw_r_w)
-#define MPTFWDOWNLOAD		_IOWR(MPT_MAGIC_NUMBER,15,struct mpt_fw_xfer)
-#define MPTSCSICMD		_IOWR(MPT_MAGIC_NUMBER,16,struct mpt_scsi_cmd)
-
-/*
- *  Define something *vague* enough that caller doesn't
- *  really need to know anything about device parameters
- *  (blk_size, capacity, etc.)
- */
-struct mpt_raw_r_w {
-	unsigned int	 iocnum;	/* IOC unit number */
-	unsigned int	 port;		/* IOC port number */
-	unsigned int	 target;	/* SCSI Target */
-	unsigned int	 lun;		/* SCSI LUN */
-	unsigned int	 iters;		/* N iterations */
-	unsigned short	 nblks;		/* number of blocks per IO */
-	unsigned short	 qdepth;	/* max Q depth on this device */
-	unsigned char	 range;		/* 0-100% of FULL disk capacity, 0=use (nblks X iters) */
-	unsigned char	 skip;		/* % of disk to skip */
-	unsigned char	 rdwr;		/* 0-100%, 0=pure ReaDs, 100=pure WRites */
-	unsigned char	 seqran;	/* 0-100%, 0=pure SEQential, 100=pure RANdom */
-	unsigned int	 cache_sz;	/* In Kb!  Optimize hits to N Kb cache size */
-};
-
-struct mpt_fw_xfer {
-	unsigned int	 iocnum;	/* IOC unit number */
-/*	u8		 flags;*/	/* Message flags - bit field */
-	unsigned int	 fwlen;
-	void		*bufp;		/* Pointer to firmware buffer */
-};
-
-struct mpt_scsi_cmd {
-	unsigned int	 iocnum;	/* IOC unit number */
-	unsigned int	 port;		/* IOC port number */
-	unsigned int	 target;	/* SCSI Target */
-	unsigned int	 lun;		/* SCSI LUN */
-	SCSIIORequest_t	 scsi_req;
-	SCSIIOReply_t	 scsi_reply;
-};
-
-struct mpt_ioctl_sanity {
-	unsigned int	 iocnum;
-};
+typedef struct _DmpServices {
+	VirtDevTracker	  VdevList;
+	struct semaphore *Daemon;
+	int		(*ScsiPathSelect)
+				(struct scsi_cmnd *, MPT_SCSI_HOST **hd, int *target, int *lun);
+	int		(*DmpIoDoneChk)
+				(MPT_SCSI_HOST *, struct scsi_cmnd *,
+				 SCSIIORequest_t *,
+				 SCSIIOReply_t *);
+	void		(*mptscsih_scanVlist)
+				(MPT_SCSI_HOST *, int portnum);
+	int		(*ScsiAbort)
+				(struct scsi_cmnd *);
+	int		(*ScsiBusReset)
+				(struct scsi_cmnd *);
+} DmpServices_t;
 
-#ifdef __KERNEL__	/* { */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * Generic structure passed to the base mpt_config function.
+ */
+typedef struct _x_config_parms {
+	Q_ITEM			 linkage;	/* linked list */
+	struct timer_list	 timer;		/* timer function for this request  */
+	ConfigPageHeader_t	*hdr;
+	dma_addr_t		 physAddr;
+	int			 wait_done;	/* wait for this request */
+	u32			 pageAddr;	/* properly formatted */
+	u8			 action;
+	u8			 dir;
+	u8			 timeout;	/* seconds */
+	u8			 pad1;
+	u16			 status;
+	u16			 pad2;
+} CONFIGPARMS;
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Public entry points...
  */
@@ -524,21 +945,28 @@
 extern void	 mpt_event_deregister(int cb_idx);
 extern int	 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
 extern void	 mpt_reset_deregister(int cb_idx);
-extern int	 mpt_register_ascqops_strings(/*ASCQ_Table_t*/void *ascqTable, int ascqtbl_sz, const char **opsTable);
+extern int	 mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
 extern void	 mpt_deregister_ascqops_strings(void);
 extern MPT_FRAME_HDR	*mpt_get_msg_frame(int handle, int iocid);
 extern void	 mpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf);
 extern void	 mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf);
-extern int	 mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req);
+extern int	 mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sleepFlag);
+extern int	 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, int sleepFlag);
 extern int	 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
 extern MPT_ADAPTER	*mpt_adapter_find_first(void);
 extern MPT_ADAPTER	*mpt_adapter_find_next(MPT_ADAPTER *prev);
+extern u32	 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
 extern void	 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
-extern void	 mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buf, int *size, int len);
+extern int	 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
+extern int	 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
 
 /*
  *  Public data decl's...
  */
+extern MPT_ADAPTER	 	*mpt_adapters[MPT_MAX_ADAPTERS];
+extern struct proc_dir_entry	*mpt_proc_root_dir;
+extern DmpServices_t		*DmpService;
+
 extern int		  mpt_lan_index;	/* needed by mptlan.c */
 extern int		  mpt_stm_index;	/* needed by mptstm.c */
 
@@ -563,7 +991,7 @@
 #define offsetof(t, m)	((size_t) (&((t *)0)->m))
 #endif
 
-#if defined(__alpha__) || defined(__sparc_v9__)
+#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__)
 #define CAST_U32_TO_PTR(x)	((void *)(u64)x)
 #define CAST_PTR_TO_U32(x)	((u32)(u64)x)
 #else
@@ -577,6 +1005,40 @@
 	((pflags) & MPI_PORTFACTS_PROTOCOL_LAN)		? 'L' : 'l',	\
 	((pflags) & MPI_PORTFACTS_PROTOCOL_LOGBUSADDR)	? 'B' : 'b'
 
+/*
+ *  Shifted SGE Defines - Use in SGE with FlagsLength member.
+ *  Otherwise, use MPI_xxx defines (refer to "lsi/mpi.h" header).
+ *  Defaults: 32 bit SGE, SYSTEM_ADDRESS if direction bit is 0, read
+ */
+#define MPT_TRANSFER_IOC_TO_HOST		(0x00000000)
+#define MPT_TRANSFER_HOST_TO_IOC		(0x04000000)
+#define MPT_SGE_FLAGS_LAST_ELEMENT		(0x80000000)
+#define MPT_SGE_FLAGS_END_OF_BUFFER		(0x40000000)
+#define MPT_SGE_FLAGS_LOCAL_ADDRESS		(0x08000000)
+#define MPT_SGE_FLAGS_DIRECTION			(0x04000000)
+#define MPT_SGE_FLAGS_ADDRESSING		(MPT_SGE_ADDRESS_SIZE << MPI_SGE_FLAGS_SHIFT)
+#define MPT_SGE_FLAGS_END_OF_LIST		(0x01000000)
+
+#define MPT_SGE_FLAGS_TRANSACTION_ELEMENT	(0x00000000)
+#define MPT_SGE_FLAGS_SIMPLE_ELEMENT		(0x10000000)
+#define MPT_SGE_FLAGS_CHAIN_ELEMENT		(0x30000000)
+#define MPT_SGE_FLAGS_ELEMENT_MASK		(0x30000000)
+
+#define MPT_SGE_FLAGS_SSIMPLE_READ \
+	(MPT_SGE_FLAGS_LAST_ELEMENT |	\
+	 MPT_SGE_FLAGS_END_OF_BUFFER |	\
+	 MPT_SGE_FLAGS_END_OF_LIST |	\
+	 MPT_SGE_FLAGS_SIMPLE_ELEMENT |	\
+	 MPT_SGE_FLAGS_ADDRESSING |	\
+	 MPT_TRANSFER_IOC_TO_HOST)
+#define MPT_SGE_FLAGS_SSIMPLE_WRITE \
+	(MPT_SGE_FLAGS_LAST_ELEMENT |	\
+	 MPT_SGE_FLAGS_END_OF_BUFFER |	\
+	 MPT_SGE_FLAGS_END_OF_LIST |	\
+	 MPT_SGE_FLAGS_SIMPLE_ELEMENT |	\
+	 MPT_SGE_FLAGS_ADDRESSING |	\
+	 MPT_TRANSFER_HOST_TO_IOC)
+
 /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/mptctl.c linux/drivers/message/fusion/mptctl.c
--- linux.orig/drivers/message/fusion/mptctl.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/message/fusion/mptctl.c	2002-07-20 01:08:23.000000000 +0000
@@ -9,6 +9,12 @@
  *      This driver would not exist if not for Alan Cox's development
  *      of the linux i2o driver.
  *
+ *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
+ *      and countless enhancements while adding support for the 1030
+ *      chip family.  Pam has been instrumental in the development of
+ *      of the 2.xx.xx series fusion drivers, and her contributions are
+ *      far too numerous to hope to list in one place.
+ *
  *      A huge debt of gratitude is owed to David S. Miller (DaveM)
  *      for fixing much of the stupid and broken stuff in the early
  *      driver while porting to sparc64 platform.  THANK YOU!
@@ -18,16 +24,17 @@
  *      (plus Eddie's other helpful hints and insights)
  *
  *      Thanks to Arnaldo Carvalho de Melo for finding and patching
- *      a potential memory leak in mpt_ioctl_do_fw_download(),
+ *      a potential memory leak in mptctl_do_fw_download(),
  *      and for some kmalloc insight:-)
  *
  *      (see also mptbase.c)
  *
- *  Copyright (c) 1999-2001 LSI Logic Corporation
+ *  Copyright (c) 1999-2002 LSI Logic Corporation
  *  Originally By: Steven J. Ralston, Noah Romer
- *  (mailto:Steve.Ralston@lsil.com)
+ *  (mailto:sjralston1@netscape.net)
+ *  (mailto:Pam.Delaney@lsil.com)
  *
- *  $Id: mptctl.c,v 1.25.4.1 2001/08/24 20:07:06 sralston Exp $
+ *  $Id: mptctl.c,v 1.52 2002/02/27 18:44:24 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -79,11 +86,16 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#include <linux/proc_fs.h>
+#include <linux/kdev_t.h>	/* needed for access to Scsi_Host struct */
+#include <linux/blkdev.h>
+#include <linux/blk.h>          /* for io_request_lock (spinlock) decl */
+#include "../../scsi/scsi.h"
+#include "../../scsi/hosts.h"
 
 #define COPYRIGHT	"Copyright (c) 1999-2001 LSI Logic Corporation"
-#define MODULEAUTHOR	"Steven J. Ralston, Noah Romer"
+#define MODULEAUTHOR	"Steven J. Ralston, Noah Romer, Pamela Delaney"
 #include "mptbase.h"
+#include "mptctl.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #define my_NAME		"Fusion MPT misc device (ioctl) driver"
@@ -95,21 +107,59 @@
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 static int mptctl_id = -1;
-static int rwperf_reset = 0;
 static struct semaphore mptctl_syscall_sem_ioc[MPT_MAX_ADAPTERS];
 
+static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-static int mpt_ioctl_rwperf(unsigned long arg);
-static int mpt_ioctl_rwperf_status(unsigned long arg);
-static int mpt_ioctl_rwperf_reset(unsigned long arg);
-static int mpt_ioctl_fw_download(unsigned long arg);
-static int mpt_ioctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen);
-static int mpt_ioctl_scsi_cmd(unsigned long arg);
+struct buflist {
+	u8	*kptr;
+	int	 len;
+};
+
+/*
+ * Function prototypes. Called from OS entry point mptctl_ioctl.
+ * arg contents specific to function.
+ */
+static int mptctl_fw_download(unsigned long arg);
+static int mptctl_getiocinfo (unsigned long arg);
+static int mptctl_gettargetinfo (unsigned long arg);
+static int mptctl_readtest (unsigned long arg);
+static int mptctl_mpt_command (unsigned long arg);
+static int mptctl_eventquery (unsigned long arg);
+static int mptctl_eventenable (unsigned long arg);
+static int mptctl_eventreport (unsigned long arg);
+static int mptctl_replace_fw (unsigned long arg);
+
+static int mptctl_do_reset(unsigned long arg);
+
+static int mptctl_compaq_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+static int mptctl_cpq_getpciinfo(unsigned long arg);
+static int mptctl_cpq_getdriver(unsigned long arg);
+static int mptctl_cpq_ctlr_status(unsigned long arg);
+static int mptctl_cpq_target_address(unsigned long arg);
+static int mptctl_cpq_passthru(unsigned long arg);
+static int mptctl_compaq_scsiio(VENDOR_IOCTL_REQ *pVenReq, cpqfc_passthru_t *pPass);
+
+/*
+ * Private function calls.
+ */
+static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local);
+static int mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen);
+static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags,
+		struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
+static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma,
+		struct buflist *buflist, MPT_ADAPTER *ioc);
+static void mptctl_timer_expired (unsigned long data);
+
+/*
+ * Reset Handler cleanup function
+ */
+static int  mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -132,26 +182,27 @@
 /* linux only seems to ever give 128kB MAX contiguous (GFP_USER) mem bytes */
 #define MAX_KMALLOC_SZ		(128*1024)
 
-struct buflist {
-	u8	*kptr;
-	int	 len;
-};
-
-#define myMAX_TARGETS	(1<<4)
-#define myMAX_LUNS	(1<<3)
-#define myMAX_T_MASK	(myMAX_TARGETS-1)
-#define myMAX_L_MASK	(myMAX_LUNS-1)
-static u8  DevInUse[myMAX_TARGETS][myMAX_LUNS] = {{0,0}};
-static u32 DevIosCount[myMAX_TARGETS][myMAX_LUNS] = {{0,0}};
+#define MPT_IOCTL_DEFAULT_TIMEOUT 10	/* Default timeout value (seconds) */
 
 static u32 fwReplyBuffer[16];
 static pMPIDefaultReply_t ReplyMsg = NULL;
 
-/* some private forw protos */
-static SGESimple32_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int *frags,
-		struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
-static void kfree_sgl( SGESimple32_t *sgl, dma_addr_t sgl_dma,
-		struct buflist *buflist, MPT_ADAPTER *ioc);
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	Function to return 0 if the sge Address member is 0 and
+ *	non-zero else.  Used in the mpt_do_fw_download routines.
+ */
+static inline int
+mptctl_test_address(MptSge_t *sge)
+{
+#ifdef __ia64__
+	if ((sge->Address.Low) || (sge->Address.High))
+		return 1;
+	else
+		return 0;
+#else
+	return sge->Address;
+#endif
+}
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
@@ -159,7 +210,7 @@
  *	@ioc: Pointer to MPT adapter
  *	@nonblock: boolean, non-zero if O_NONBLOCK is set
  *
- *	All of the mptctl commands can potentially sleep, which is illegal
+ *	All of the ioctl commands can potentially sleep, which is illegal
  *	with a spinlock held, thus we perform mutual exclusion here.
  *
  *	Returns negative errno on error, or zero for success.
@@ -167,16 +218,27 @@
 static inline int
 mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
 {
-	dprintk((KERN_INFO MYNAM "::mpt_syscall_down(%p,%d) called\n", ioc, nonblock));
+	int rc = 0;
+	dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));
 
+#if defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+	if (!nonblock) {
+		if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id]))
+			rc = -ERESTARTSYS;
+	} else {
+		rc = -EPERM;
+	}
+#else
 	if (nonblock) {
 		if (down_trylock(&mptctl_syscall_sem_ioc[ioc->id]))
-			return -EAGAIN;
+			rc = -EAGAIN;
 	} else {
 		if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id]))
-			return -ERESTARTSYS;
+			rc = -ERESTARTSYS;
 	}
-	return 0;
+#endif
+	dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
+	return rc;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -189,18 +251,150 @@
 static int
 mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
 {
-	u8 targ;
+	char *sense_data;
+	int sz, req_index;
+	u16 iocStatus;
+	u8 cmd;
+
+	dctlprintk((MYIOC_s_INFO_FMT ": mptctl_reply()!\n", ioc->name));
+	if (req)
+		 cmd = req->u.hdr.Function;
+	else
+		return 1;
+
+	if (ioc->ioctl) {
+		/* If timer is not running, then an error occurred.
+		 * A timeout will call the reset routine to reload the messaging
+		 * queues.
+		 * Main callback will free message and reply frames.
+		 */
+		if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) {
+			/* Delete this timer
+			 */
+			del_timer (&ioc->ioctl->timer);
+			ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
+
+			/* Set the overall status byte.  Good if:
+			 * IOC status is good OR if no reply and a SCSI IO request
+			 */
+			if (reply) {
+				/* Copy the reply frame (which much exist
+				 * for non-SCSI I/O) to the IOC structure.
+				 */
+				dctlprintk((MYIOC_s_INFO_FMT ": Copying Reply Frame @%p to IOC!\n",
+						ioc->name, reply));
+				memcpy(ioc->ioctl->ReplyFrame, reply,
+					MIN(ioc->reply_sz, 4*reply->u.reply.MsgLength));
+				ioc->ioctl->status |= MPT_IOCTL_STATUS_RF_VALID;
+
+				/* Set the command status to GOOD if IOC Status is GOOD
+				 * OR if SCSI I/O cmd and data underrun or recovered error.
+				 */
+				iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
+				if (iocStatus  == MPI_IOCSTATUS_SUCCESS)
+					ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
+
+				if ((iocStatus  == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN) || 
+						(iocStatus  == MPI_IOCSTATUS_SCSI_RECOVERED_ERROR)) {
+					if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
+						(cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
+						ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
+					}
+				}
+
+				/* Copy the sense data - if present
+				 */
+				if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) &&
+					(reply->u.sreply.SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)){
+
+					sz = req->u.scsireq.SenseBufferLength;
+					req_index = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
+					sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
+					memcpy(ioc->ioctl->sense, sense_data, sz);
+					ioc->ioctl->status |= MPT_IOCTL_STATUS_SENSE_VALID;
+				}
+			} else if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
+					(cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
+				ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
+			}
+
+			/* We are done, issue wake up
+			 */
+			ioc->ioctl->wait_done = 1;
+			wake_up (&mptctl_wait);
+		} else if (reply && cmd == MPI_FUNCTION_FW_DOWNLOAD) {
+			/* Two paths to FW DOWNLOAD! */
+			// NOTE: Expects/requires non-Turbo reply!
+			dctlprintk((MYIOC_s_INFO_FMT ":Caching MPI_FUNCTION_FW_DOWNLOAD reply!\n",
+				ioc->name));
+			memcpy(fwReplyBuffer, reply, MIN(sizeof(fwReplyBuffer), 4*reply->u.reply.MsgLength));
+			ReplyMsg = (pMPIDefaultReply_t) fwReplyBuffer;
+		}
+	}
+	return 1;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* mptctl_timer_expired
+ *
+ * Call back for timer process. Used only for ioctl functionality.
+ *
+ */
+static void mptctl_timer_expired (unsigned long data)
+{
+	MPT_IOCTL *ioctl = (MPT_IOCTL *) data;
+
+	dctlprintk((KERN_NOTICE MYNAM ": Timer Expired! Host %d\n",
+				ioctl->ioc->id));
 
-	//dprintk((KERN_DEBUG MYNAM ": Got mptctl_reply()!\n"));
+	/* Issue a reset for this device.
+	 * The IOC is not responding.
+	 */
+	mpt_HardResetHandler(ioctl->ioc, NO_SLEEP);
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* mptctl_ioc_reset
+ *
+ * Clean-up functionality. Used only if there has been a
+ * reload of the FW due.
+ *
+ */
+static int
+mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+	MPT_IOCTL *ioctl = ioc->ioctl;
+	dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n",
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+	if (reset_phase == MPT_IOC_PRE_RESET){
+
+		/* Someone has called the reset handler to
+		 * do a hard reset. No more replies from the FW.
+		 * Delete the timer.
+		 */
+		if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
+
+			/* Delete this timer
+			 */
+			del_timer(&ioctl->timer);
+		}
 
-	if (req && req->u.hdr.Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
-		targ = req->u.scsireq.TargetID & myMAX_T_MASK;
-		DevIosCount[targ][0]--;
-	} else if (reply && req && req->u.hdr.Function == MPI_FUNCTION_FW_DOWNLOAD) {
-		// NOTE: Expects/requires non-Turbo reply!
-		dprintk((KERN_INFO MYNAM ": Caching MPI_FUNCTION_FW_DOWNLOAD reply!\n"));
-		memcpy(fwReplyBuffer, reply, MIN(sizeof(fwReplyBuffer), 4*reply->u.reply.MsgLength));
-		ReplyMsg = (pMPIDefaultReply_t) fwReplyBuffer;
+	} else {
+		/* Set the status and continue IOCTL
+		 * processing. All memory will be free'd
+		 * by originating thread after wake_up is
+		 * called.
+		 */
+		if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
+			ioctl->status = MPT_IOCTL_STATUS_DID_TIMEOUT;
+
+			/* Wake up the calling process
+			 */
+			ioctl->wait_done = 1;
+			wake_up(&mptctl_wait);
+		}
 	}
 
 	return 1;
@@ -208,7 +402,7 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *  struct file_operations functionality. 
+ *  struct file_operations functionality.
  *  Members:
  *	llseek, write, read, ioctl, open, release
  */
@@ -234,63 +428,93 @@
 static ssize_t
 mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr)
 {
+	printk(KERN_ERR MYNAM ": ioctl READ not yet supported\n");
 	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  MPT ioctl handler
+ *  cmd - specify the particular IOCTL command to be issued
+ *  arg - data specific to the command. Must not be null.
  */
 static int
-mpt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
-	struct mpt_ioctl_sanity	*usanity = (struct mpt_ioctl_sanity *) arg;
-	struct mpt_ioctl_sanity	 ksanity;
+	mpt_ioctl_header	*uhdr = (mpt_ioctl_header *) arg;
+	mpt_ioctl_header	 khdr;
 	int iocnum;
 	unsigned iocnumX;
 	int nonblock = (file->f_flags & O_NONBLOCK);
 	int ret;
 	MPT_ADAPTER *iocp = NULL;
 
-	dprintk((KERN_INFO MYNAM "::mpt_ioctl() called\n"));
+	dctlprintk(("mptctl_ioctl() called\n"));
 
-	if (copy_from_user(&ksanity, usanity, sizeof(ksanity))) {
-		printk(KERN_ERR "%s::mpt_ioctl() @%d - "
-				"Unable to copy mpt_ioctl_sanity data @ %p\n",
-				__FILE__, __LINE__, (void*)usanity);
+	if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
+		printk(KERN_ERR "%s::mptctl_ioctl() @%d - "
+				"Unable to copy mpt_ioctl_header data @ %p\n",
+				__FILE__, __LINE__, (void*)uhdr);
 		return -EFAULT;
 	}
 	ret = -ENXIO;				/* (-6) No such device or address */
 
-	/* Verify intended MPT adapter */
-	iocnumX = ksanity.iocnum & 0xFF;
+	/* Test for Compaq-specific IOCTL's.
+	 */
+	if ((cmd == CPQFCTS_GETPCIINFO) || (cmd == CPQFCTS_CTLR_STATUS) ||
+		(cmd == CPQFCTS_GETDRIVER) || (cmd == CPQFCTS_SCSI_PASSTHRU) ||
+		(cmd == CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS))
+		return mptctl_compaq_ioctl(file, cmd, arg);
+
+	/* Verify intended MPT adapter - set iocnum and the adapter
+	 * pointer (iocp)
+	 */
+	iocnumX = khdr.iocnum & 0xFF;
 	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
 	    (iocp == NULL)) {
-		printk(KERN_ERR "%s::mpt_ioctl() @%d - ioc%d not found!\n",
+		printk(KERN_ERR "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
 				__FILE__, __LINE__, iocnumX);
 		return -ENODEV;
 	}
 
+	/* Handle those commands that are just returning
+	 * information stored in the driver.
+	 * These commands should never time out and are unaffected
+	 * by TM and FW reloads.
+	 */
+	if (cmd == MPTIOCINFO) {
+		return mptctl_getiocinfo(arg);
+	} else if (cmd == MPTTARGETINFO) {
+		return mptctl_gettargetinfo(arg);
+	} else if (cmd == MPTTEST) {
+		return mptctl_readtest(arg);
+	} else if (cmd == MPTEVENTQUERY) {
+		return mptctl_eventquery(arg);
+	} else if (cmd == MPTEVENTENABLE) {
+		return mptctl_eventenable(arg);
+	} else if (cmd == MPTEVENTREPORT) {
+		return mptctl_eventreport(arg);
+	} else if (cmd == MPTFWREPLACE) {
+		return mptctl_replace_fw(arg);
+	}
+
+	/* All of these commands require an interrupt or
+	 * are unknown/illegal.
+	 */
 	if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
 		return ret;
 
-	dprintk((KERN_INFO MYNAM "::mpt_ioctl() - Using %s\n", iocp->name));
+	dctlprintk((MYIOC_s_INFO_FMT ": mptctl_ioctl()\n", iocp->name));
 
 	switch(cmd) {
-	case MPTRWPERF:
-		ret = mpt_ioctl_rwperf(arg);
-		break;
-	case MPTRWPERF_CHK:
-		ret = mpt_ioctl_rwperf_status(arg);
-		break;
-	case MPTRWPERF_RESET:
-		ret = mpt_ioctl_rwperf_reset(arg);
-		break;
 	case MPTFWDOWNLOAD:
-		ret = mpt_ioctl_fw_download(arg);
+		ret = mptctl_fw_download(arg);
+		break;
+	case MPTCOMMAND:
+		ret = mptctl_mpt_command(arg);
 		break;
-	case MPTSCSICMD:
-		ret = mpt_ioctl_scsi_cmd(arg);
+	case MPTHARDRESET:
+		ret = mptctl_do_reset(arg);
 		break;
 	default:
 		ret = -EINVAL;
@@ -301,6 +525,36 @@
 	return ret;
 }
 
+static int mptctl_do_reset(unsigned long arg)
+{
+	struct mpt_ioctl_diag_reset *urinfo = (struct mpt_ioctl_diag_reset *) arg;
+	struct mpt_ioctl_diag_reset krinfo;
+	MPT_ADAPTER		*iocp;
+
+	dctlprintk((KERN_INFO "mptctl_do_reset called.\n"));
+
+	if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
+		printk(KERN_ERR "%s@%d::mptctl_do_reset - "
+				"Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
+				__FILE__, __LINE__, (void*)urinfo);
+		return -EFAULT;
+	}
+
+	if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
+		printk(KERN_ERR "%s@%d::mptctl_do_reset - ioc%d not found!\n",
+				__FILE__, __LINE__, krinfo.hdr.iocnum);
+		return -ENXIO; /* (-6) No such device or address */
+	}
+
+	if (mpt_HardResetHandler(iocp, NO_SLEEP) != 0) {
+		printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+	return 0;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int mptctl_open(struct inode *inode, struct file *file)
 {
@@ -317,13 +571,29 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * MPT FW download function.  Cast the arg into the mpt_fw_xfer structure.
+ * This structure contains: iocnum, firmware length (bytes),
+ *      pointer to user space memory where the fw image is stored.
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EFAULT if data unavailable
+ *		-ENXIO  if no such device
+ *		-EAGAIN if resource problem
+ *		-ENOMEM if no memory for SGE
+ *		-EMLINK if too many chain buffers required
+ *		-EBADRQC if adapter does not support FW download
+ *		-EBUSY if adapter is busy
+ *		-ENOMSG if FW upload returned bad status
+ */
 static int
-mpt_ioctl_fw_download(unsigned long arg)
+mptctl_fw_download(unsigned long arg)
 {
 	struct mpt_fw_xfer	*ufwdl = (struct mpt_fw_xfer *) arg;
 	struct mpt_fw_xfer	 kfwdl;
 
-	dprintk((KERN_INFO "mpt_ioctl_fwdl called. mptctl_id = %xh\n", mptctl_id)); //tc
+	dctlprintk((KERN_INFO "mptctl_fwdl called. mptctl_id = %xh\n", mptctl_id)); //tc
 	if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
 		printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
 				"Unable to copy mpt_fw_xfer struct @ %p\n",
@@ -331,44 +601,52 @@
 		return -EFAULT;
 	}
 
-	return mpt_ioctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
+	return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- * MPT FW Download
+ * FW Download engine.
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EFAULT if data unavailable
+ *		-ENXIO  if no such device
+ *		-EAGAIN if resource problem
+ *		-ENOMEM if no memory for SGE
+ *		-EMLINK if too many chain buffers required
+ *		-EBADRQC if adapter does not support FW download
+ *		-EBUSY if adapter is busy
+ *		-ENOMSG if FW upload returned bad status
  */
 static int
-mpt_ioctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
+mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
 {
 	FWDownload_t		*dlmsg;
 	MPT_FRAME_HDR		*mf;
 	MPT_ADAPTER		*iocp;
-//	char			*fwbuf;
-//	dma_addr_t		 fwbuf_dma;
-	FWDownloadTCSGE_t	*fwVoodoo;
-//	SGEAllUnion_t		*fwSgl;
+	FWDownloadTCSGE_t	*ptsge;
+	MptSge_t		*sgl;
+	MptSge_t		*sgOut, *sgIn;
+	struct buflist		*buflist;
+	struct buflist		*bl;
+	dma_addr_t		 sgl_dma;
 	int			 ret;
-
-	SGESimple32_t	*sgl;
-	SGESimple32_t	*sgOut, *sgIn;
-	dma_addr_t	 sgl_dma;
-	struct buflist	*buflist = NULL;
-	struct buflist	*bl = NULL;
-	int		 numfrags = 0;
-	int		 maxfrags;
-	int		 n = 0;
-	u32		 sgdir;
-	u32		 nib;
-	int		 fw_bytes_copied = 0;
-	u16		 iocstat;
-	int		 i;
-
-	dprintk((KERN_INFO "mpt_ioctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));
-
-	dprintk((KERN_INFO "DbG: kfwdl.bufp  = %p\n", ufwbuf));
-	dprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen));
-	dprintk((KERN_INFO "DbG: kfwdl.ioc   = %04xh\n", ioc));
+	int			 numfrags = 0;
+	int			 maxfrags;
+	int			 n = 0;
+	u32			 sgdir;
+	u32			 nib;
+	int			 fw_bytes_copied = 0;
+	int			 i;
+	int			 cntdn;
+	int			 sge_offset = 0;
+	u16			 iocstat;
+
+	dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));
+
+	dctlprintk((KERN_INFO "DbG: kfwdl.bufp  = %p\n", ufwbuf));
+	dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen));
+	dctlprintk((KERN_INFO "DbG: kfwdl.ioc   = %04xh\n", ioc));
 
 	if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) {
 		printk("%s@%d::_ioctl_fwdl - ioc%d not found!\n",
@@ -376,11 +654,13 @@
 		return -ENXIO; /* (-6) No such device or address */
 	}
 
+	/*  Valid device. Get a message frame and construct the FW download message.
+	 */
 	if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
 		return -EAGAIN;
 	dlmsg = (FWDownload_t*) mf;
-	fwVoodoo = (FWDownloadTCSGE_t *) &dlmsg->SGL;
-	sgOut = (SGESimple32_t *) (fwVoodoo + 1);
+	ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
+	sgOut = (MptSge_t *) (ptsge + 1);
 
 	/*
 	 * Construct f/w download request
@@ -392,27 +672,36 @@
 	dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
 	dlmsg->MsgFlags = 0;
 
-	fwVoodoo->Reserved = 0;
-	fwVoodoo->ContextSize = 0;
-	fwVoodoo->DetailsLength = 12;
-	fwVoodoo->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
-	fwVoodoo->Reserved1 = 0;
-	fwVoodoo->ImageOffset = 0;
-	fwVoodoo->ImageSize = cpu_to_le32(fwlen);
+	/* Set up the Transaction SGE.
+	 */
+	ptsge->Reserved = 0;
+	ptsge->ContextSize = 0;
+	ptsge->DetailsLength = 12;
+	ptsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
+	ptsge->Reserved_0100_Checksum = 0;
+	ptsge->ImageOffset = 0;
+	ptsge->ImageSize = cpu_to_le32(fwlen);
+
+	/* Add the SGL
+	 */
 
 	/*
 	 * Need to kmalloc area(s) for holding firmware image bytes.
 	 * But we need to do it piece meal, using a proper
 	 * scatter gather list (with 128kB MAX hunks).
-	 * 
+	 *
 	 * A practical limit here might be # of sg hunks that fit into
 	 * a single IOC request frame; 12 or 8 (see below), so:
 	 * For FC9xx: 12 x 128kB == 1.5 mB (max)
 	 * For C1030:  8 x 128kB == 1   mB (max)
 	 * We could support chaining, but things get ugly(ier:)
+	 *
+	 * Set the sge_offset to the start of the sgl (bytes).
 	 */
 	sgdir = 0x04000000;		/* IOC will READ from sys mem */
-	if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
+	sge_offset = sizeof(MPIHeader_t) + sizeof(FWDownloadTCSGE_t);
+	if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, sge_offset,
+				    &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
 		return -ENOMEM;
 
 	/*
@@ -420,16 +709,19 @@
 	 * for FC9xx f/w image, but calculate max number of sge hunks
 	 * we can fit into a request frame, and limit ourselves to that.
 	 * (currently no chain support)
-	 * For FC9xx: (128-12-16)/8 = 12.5 = 12
-	 * For C1030:  (96-12-16)/8 =  8.5 =  8
+	 * maxfrags = (Request Size - FWdownload Size ) / Size of 32 bit SGE
+	 *	Request		maxfrags
+	 *	128		12
+	 *	96		8
+	 *	64		4
 	 */
-	maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) - sizeof(FWDownloadTCSGE_t)) / sizeof(SGESimple32_t);
+	maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) - sizeof(FWDownloadTCSGE_t)) / sizeof(MptSge_t);
 	if (numfrags > maxfrags) {
 		ret = -EMLINK;
 		goto fwdl_out;
 	}
 
-	dprintk((KERN_INFO "DbG: sgl buffer  = %p, sgfrags = %d\n", sgl, numfrags));
+	dctlprintk((KERN_INFO "DbG: sgl buffer  = %p, sgfrags = %d\n", sgl, numfrags));
 
 	/*
 	 * Parse SG list, copying sgl itself,
@@ -439,11 +731,17 @@
 	sgIn = sgl;
 	bl = buflist;
 	for (i=0; i < numfrags; i++) {
-		nib = (le32_to_cpu(sgIn->FlagsLength) & 0xF0000000) >> 28;
-		/* skip ignore/chain. */
+
+		/* Get the SGE type: 0 - TCSGE, 3 - Chain, 1 - Simple SGE
+		 * Skip everything but Simple. If simple, copy from
+		 *	user space into kernel space.
+		 * Note: we should not have anything but Simple as
+		 *	Chain SGE are illegal.
+		 */
+		nib = (le32_to_cpu(sgIn->FlagsLength) & 0x30000000) >> 28;
 		if (nib == 0 || nib == 3) {
 			;
-		} else if (sgIn->Address) {
+		} else if (mptctl_test_address(sgIn)) {
 			*sgOut = *sgIn;
 			n++;
 			if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
@@ -478,26 +776,24 @@
 	/*
 	 *  Wait until the reply has been received
 	 */
-	{
-		int	 foo = 0;
-
-		while (ReplyMsg == NULL) {
-			if (!(foo%1000000)) {
-				dprintk((KERN_INFO "DbG::_do_fwdl: "
-					   "In ReplyMsg loop - iteration %d\n",
-					   foo)); //tc
-			}
+	for (cntdn=HZ*60, i=1; ReplyMsg == NULL; cntdn--, i++) {
+		if (!cntdn) {
 			ret = -ETIME;
-			if (++foo > 60000000)
-				goto fwdl_out;
-			mb();
-			schedule();
-			barrier();
+			goto fwdl_out;
 		}
+
+		if (!(i%HZ)) {
+			dctlprintk((KERN_INFO "DbG::_do_fwdl: "
+				   "In ReplyMsg loop - iteration %d\n",
+				   i));
+		}
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
 	}
 
 	if (sgl)
-        	kfree_sgl(sgl, sgl_dma, buflist, iocp);
+		kfree_sgl(sgl, sgl_dma, buflist, iocp);
 
 	iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
 	if (iocstat == MPI_IOCSTATUS_SUCCESS) {
@@ -527,32 +823,46 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *  NEW rwperf (read/write performance) stuff starts here...
+ * SGE Allocation routine
+ *
+ * Inputs:	bytes - number of bytes to be transferred
+ *		sgdir - data direction
+ *		sge_offset - offset (in bytes) from the start of the request
+ *			frame to the first SGE
+ *		ioc - pointer to the mptadapter
+ * Outputs:	frags - number of scatter gather elements
+ *		blp - point to the buflist pointer
+ *		sglbuf_dma - pointer to the (dma) sgl
+ * Returns:	Null if failes
+ *		pointer to the (virtual) sgl if successful.
  */
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static SGESimple32_t *
-kbuf_alloc_2_sgl(int bytes, u32 sgdir, int *frags,
+static MptSge_t *
+kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
 		 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc)
 {
-	SGESimple32_t	*sglbuf = NULL;
-	struct buflist	*buflist = NULL;
+	MptSge_t	*sglbuf = NULL;		/* pointer to array of SGE
+						 * and chain buffers */
+	struct buflist	*buflist = NULL;	/* kernel routine */
+	MptSge_t	*sgl;
+	MptChain_t	*last_chain = NULL;
 	int		 numfrags = 0;
 	int		 fragcnt = 0;
 	int		 alloc_sz = MIN(bytes,MAX_KMALLOC_SZ);	// avoid kernel warning msg!
 	int		 bytes_allocd = 0;
 	int		 this_alloc;
-	SGESimple32_t	*sgl;
-	u32		 pa;					// phys addr
-	SGEChain32_t	*last_chain = NULL;
-	SGEChain32_t	*old_chain = NULL;
+	dma_addr_t	 pa;					// phys addr
 	int		 chaincnt = 0;
 	int		 i, buflist_ent;
 	int		 sg_spill = MAX_FRAGS_SPILL1;
 	int		 dir;
 
+	/* initialization */
 	*frags = 0;
 	*blp = NULL;
+
+	/* Allocate and initialize an array of kernel
+	 * structures for the SG elements.
+	 */
 	i = MAX_SGL_BYTES / 8;
 	buflist = kmalloc(i, GFP_USER);
 	if (buflist == NULL)
@@ -560,6 +870,11 @@
 	memset(buflist, 0, i);
 	buflist_ent = 0;
 
+	/* Allocate a single block of memory to store the sg elements and
+	 * the chain buffers.  The calling routine is responsible for
+	 * copying the data in this array into the correct place in the
+	 * request and chain buffers.
+	 */
 	sglbuf = pci_alloc_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf_dma);
 	if (sglbuf == NULL)
 		goto free_and_fail;
@@ -569,7 +884,15 @@
 	else
 		dir = PCI_DMA_FROMDEVICE;
 
+	/* At start:
+	 *	sgl = sglbuf = point to beginning of sg buffer
+	 *	buflist_ent = 0 = first kernel structure
+	 *	sg_spill = number of SGE that can be written before the first
+	 *		chain element.
+	 *
+	 */
 	sgl = sglbuf;
+	sg_spill = ((ioc->req_sz  - sge_offset)/ sizeof(MptSge_t)) - 1;
 	while (bytes_allocd < bytes) {
 		this_alloc = MIN(alloc_sz, bytes-bytes_allocd);
 		buflist[buflist_ent].len = this_alloc;
@@ -594,7 +917,7 @@
 			/* Write one SIMPLE sge */
 			sgl->FlagsLength = cpu_to_le32(0x10000000|sgdir|this_alloc);
 			dma_addr = pci_map_single(ioc->pcidev, buflist[buflist_ent].kptr, this_alloc, dir);
-			sgl->Address = cpu_to_le32(dma_addr);
+			cpu_to_leXX(dma_addr, sgl->Address);
 
 			fragcnt++;
 			numfrags++;
@@ -609,24 +932,43 @@
 		if (fragcnt == sg_spill) {
 			dma_addr_t chain_link;
 
-			if (last_chain != NULL)
-				last_chain->NextChainOffset = 0x1E;
-
-			fragcnt = 0;
-			sg_spill = MAX_FRAGS_SPILL2;
+			/* If there is a chain element, set the offset
+			 * (in 32 bit words) to the next chain element.
+			 * fragcnt = # sge = 8 bytes = 2 words
+			 *
+			 * Set the length of the chain element (bytes)
+			 * This includes the size of the next chain element.
+			 *
+			 * We are now done with last_chain and the previous
+			 * buffer.
+			 */
+			if (last_chain != NULL) {
+				last_chain->NextChainOffset = fragcnt * 2;
+				last_chain->Length = cpu_to_le16((fragcnt+1) * 8);
+			}
 
-			/* fixup previous SIMPLE sge */
+			/* Finish the current buffer:
+			 * - add the LE bit to last sge
+			 * - add the chain element
+			*/
 			sgl[-1].FlagsLength |= cpu_to_le32(0x80000000);
 
 			chain_link = (*sglbuf_dma) +
 				((u8 *)(sgl+1) - (u8 *)sglbuf);
 
 			/* Write one CHAIN sge */
-			sgl->FlagsLength = cpu_to_le32(0x30000080);
-			sgl->Address = cpu_to_le32(chain_link);
+//			sgl->FlagsLength = cpu_to_le32(0x30000080);
+			sgl->FlagsLength = cpu_to_le32(0x30000000);
+			cpu_to_leXX(chain_link, sgl->Address);
+
+			/* Reset everything for the next SGE series,
+			 * save a ptr to the chain element in last_chain
+			 */
+			fragcnt = 0;
+//			sg_spill = MAX_FRAGS_SPILL2;
+			sg_spill = (ioc->req_sz / sizeof(MptSge_t)) - 1;
 
-			old_chain = last_chain;
-			last_chain = (SGEChain32_t*)sgl;
+			last_chain = (MptChain_t*)sgl;
 			chaincnt++;
 			numfrags++;
 			sgl++;
@@ -646,18 +988,19 @@
 	/* Last sge fixup: set LE+eol+eob bits */
 	sgl[-1].FlagsLength |= cpu_to_le32(0xC1000000);
 
-	/* Chain fixup needed? */
-	if (last_chain != NULL && fragcnt < 16)
+	/* Chain fixup needed? */	/* SteveR CHECKME!!! */
+//	if (last_chain != NULL && fragcnt < 16)
+	if (last_chain != NULL)
 		last_chain->Length = cpu_to_le16(fragcnt * 8);
 
 	*frags = numfrags;
 	*blp = buflist;
 
-	dprintk((KERN_INFO MYNAM "-SG: kbuf_alloc_2_sgl() - "
+	dctlprintk((KERN_INFO MYNAM "-SG: kbuf_alloc_2_sgl() - "
 			   "%d SG frags generated!  (%d CHAIN%s)\n",
 			   numfrags, chaincnt, chaincnt>1?"s":""));
 
-	dprintk((KERN_INFO MYNAM "-SG: kbuf_alloc_2_sgl() - "
+	dctlprintk((KERN_INFO MYNAM "-SG: kbuf_alloc_2_sgl() - "
 			   "last (big) alloc_sz=%d\n",
 			   alloc_sz));
 
@@ -675,7 +1018,7 @@
 			if ((le32_to_cpu(sglbuf[i].FlagsLength) >> 24) == 0x30)
 				continue;
 
-			dma_addr = le32_to_cpu(sglbuf[i].Address);
+			leXX_to_cpu(dma_addr, sglbuf[i].Address);
 			kptr = buflist[i].kptr;
 			len = buflist[i].len;
 
@@ -688,16 +1031,19 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * Routine to free the SGL elements.
+ */
 static void
-kfree_sgl(SGESimple32_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
+kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
 {
-	SGESimple32_t	*sg = sgl;
+	MptSge_t	*sg = sgl;
 	struct buflist	*bl = buflist;
 	u32		 nib;
 	int		 dir;
 	int		 n = 0;
 
-	if (le32_to_cpu(sg->FlagsLength) & 0x04000000)
+	if ((le32_to_cpu(sg->FlagsLength) & 0x04000000))
 		dir = PCI_DMA_TODEVICE;
 	else
 		dir = PCI_DMA_FROMDEVICE;
@@ -707,12 +1053,12 @@
 		/* skip ignore/chain. */
 		if (nib == 0 || nib == 3) {
 			;
-		} else if (sg->Address) {
+		} else if (mptctl_test_address(sg)) {
 			dma_addr_t dma_addr;
 			void *kptr;
 			int len;
 
-			dma_addr = le32_to_cpu(sg->Address);
+			leXX_to_cpu(dma_addr, sg->Address);
 			kptr = bl->kptr;
 			len = bl->len;
 			pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
@@ -725,12 +1071,12 @@
 	}
 
 	/* we're at eob! */
-	if (sg->Address) {
+	if (mptctl_test_address(sg)) {
 		dma_addr_t dma_addr;
 		void *kptr;
 		int len;
 
-		dma_addr = le32_to_cpu(sg->Address);
+		leXX_to_cpu(dma_addr, sg->Address);
 		kptr = bl->kptr;
 		len = bl->len;
 		pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
@@ -740,392 +1086,1686 @@
 
 	pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sgl, sgl_dma);
 	kfree(buflist);
-	dprintk((KERN_INFO MYNAM "-SG: Free'd 1 SGL buf + %d kbufs!\n", n));
+	dctlprintk((KERN_INFO MYNAM "-SG: Free'd 1 SGL buf + %d kbufs!\n", n));
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptctl_getiocinfo - Query the host adapter for IOC information.
+ *	@arg: User space argument
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EFAULT if data unavailable
+ *		-ENODEV  if no such device/adapter
+ */
 static int
-mpt_ioctl_rwperf_init(struct mpt_raw_r_w *dest, unsigned long src,
-		      char *caller, MPT_ADAPTER **iocpp)
+mptctl_getiocinfo (unsigned long arg)
 {
-	char	*myname = "_rwperf_init()";
-	int	 ioc;
+	struct mpt_ioctl_iocinfo *uarg = (struct mpt_ioctl_iocinfo *) arg;
+	struct mpt_ioctl_iocinfo karg;
+	MPT_ADAPTER		*ioc;
+	struct pci_dev		*pdev;
+	struct Scsi_Host	*sh;
+	MPT_SCSI_HOST		*hd;
+	int			iocnum;
+	int			numDevices = 0;
+	unsigned int		max_id;
+	int			ii;
+	int			port;
+	u8			revision;
+
+	dctlprintk((": mptctl_getiocinfo called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_iocinfo))) {
+		printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
+			"Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
 
-	/* get copy of structure passed from user space */
-	if (copy_from_user(dest, (void*)src, sizeof(*dest))) {
-		printk(KERN_ERR MYNAM "::%s() @%d - Can't copy mpt_raw_r_w data @ %p\n",
-				myname, __LINE__, (void*)src);
-		return -EFAULT;				/* (-14) Bad address */
-	} else {
-		dprintk((KERN_INFO MYNAM "-perf: PerfInfo.{ioc,targ,qd,iters,nblks}"
-				   ": %d %d %d %d %d\n",
-				   dest->iocnum, dest->target,
-				   (int)dest->qdepth, dest->iters, dest->nblks ));
-		dprintk((KERN_INFO MYNAM "-perf: PerfInfo.{cache,skip,range,rdwr,seqran}"
-				   ": %d %d %d %d %d\n",
-				   dest->cache_sz, dest->skip, dest->range,
-				   dest->rdwr, dest->seqran ));
-
-		/* Get the MPT adapter id. */
-		if ((ioc = mpt_verify_adapter(dest->iocnum, iocpp)) < 0) {
-			printk(KERN_ERR MYNAM "::%s() @%d - ioc%d not found!\n",
-					myname, __LINE__, dest->iocnum);
-			return -ENXIO;			/* (-6) No such device or address */
-		} else {
-			dprintk((MYNAM "-perf: %s using mpt/ioc%x, target %02xh\n",
-					caller, dest->iocnum, dest->target));
-		}
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
 	}
 
-	return ioc;
-}
+	/* Verify the data transfer size is correct.
+	 * Ignore the port setting.
+	 */
+	if (karg.hdr.maxDataSize != sizeof(struct mpt_ioctl_iocinfo)) {
+		printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
+			"Structure size mismatch. Command not completed.\n",
+				__FILE__, __LINE__);
+		return -EFAULT;
+	}
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+	/* Fill in the data and return the structure to the calling
+	 * program
+	 */
+	if (ioc->chip_type == C1030)
+		karg.adapterType = MPT_IOCTL_INTERFACE_SCSI;
+	else
+		karg.adapterType = MPT_IOCTL_INTERFACE_FC;
 
-/*  Treat first N blocks of disk as sacred!  */
-#define SACRED_BLOCKS	100
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
-mpt_ioctl_rwperf(unsigned long arg)
-{
-	struct mpt_raw_r_w	 kPerfInfo;
-				/* NOTE: local copy, on stack==KERNEL_SPACE! */
-	u8		 target, targetM;
-	u8		 lun, lunM;
-	u8		 scsiop;
-	int		 qdepth;
-	int		 iters;
-	int		 cache_sz;
-	u32		 xferbytes;
-	u32		 scsidir;
-	u32		 qtag;
-	u32		 scsictl;
-	u32		 sgdir;
-	u32		 blkno;
-	u32		 sbphys;
-	SGESimple32_t	*sgl;
-	dma_addr_t	 sgl_dma;
-	struct buflist	*buflist;
-	SGESimple32_t	*sgOut, *sgIn;
-	int		 numfrags;
-	u32		*msg;
-	int		 i;
-	int		 ioc;
-	MPT_FRAME_HDR	*mf;
-	MPT_ADAPTER	*iocp;
-	int		 sgfragcpycnt;
-	int		 blklo, blkhi;
-	u8		 nextchainoffset;
-	u8		*SenseBuf;
-	dma_addr_t	 SenseBufDMA;
-	char		*myname = "_rwperf()";
-
-    dprintk((KERN_INFO "%s - starting...\n", myname));
-
-    /* Validate target device */
-    if ((ioc = mpt_ioctl_rwperf_init(&kPerfInfo, arg, myname, &iocp)) < 0)
-        return ioc;
-
-    /* Allocate DMA'able memory for the sense buffer. */
-    SenseBuf = pci_alloc_consistent(iocp->pcidev, 256, &SenseBufDMA);
-
-    /* set perf parameters from input */
-    target = kPerfInfo.target & 0x0FF;
-    targetM = target & myMAX_T_MASK;
-    lun = kPerfInfo.lun & 0x1F;			// LUN=31 max
-    lunM = lun & myMAX_L_MASK;
-    qdepth = kPerfInfo.qdepth;
-    iters = kPerfInfo.iters;
-    xferbytes = ((u32)kPerfInfo.nblks)<<9;
-
-    DevInUse[targetM][lunM] = 1;
-    DevIosCount[targetM][lunM] = 0;
-
-    cache_sz = kPerfInfo.cache_sz * 1024;	// CacheSz in kB!
-
-    /* ToDo: */
-    /* get capacity (?) */
-
-
-    // pre-build, one time, everything we can for speed in the loops below...
-
-    scsiop = 0x28;				// default to SCSI READ!
-    scsidir = MPI_SCSIIO_CONTROL_READ;		// DATA IN  (host<--ioc<--dev)
-						// 02000000
-    qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;		// 00000000
-
-    if (xferbytes == 0) {
-        // Do 0-byte READ!!!
-        //  IMPORTANT!  Need to set no SCSI DIR for this!
-        scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
-    }
-
-    scsictl = scsidir | qtag;
-
-    /*
-     *  Set sgdir for DMA transfer.
-     */
-//    sgdir   = 0x04000000;		// SCSI WRITE
-    sgdir = 0x00000000;			// SCSI READ
-
-    if ((sgl = kbuf_alloc_2_sgl(MAX(512,xferbytes), sgdir, &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
-        return -ENOMEM;
-
-    sgfragcpycnt = MIN(10,numfrags);
-    nextchainoffset = 0;
-    if (numfrags > 10)
-        nextchainoffset = 0x1E;
-
-    sbphys = SenseBufDMA;
-
-    rwperf_reset = 0;
-
-//    do {	// target-loop
-
-        blkno = SACRED_BLOCKS;		// Treat first N blocks as sacred!
-					// FIXME!  Skip option
-        blklo = blkno;
-        blkhi = blkno;
-
-        do {    // inner-loop
-
-            while ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
-                mb();
-                schedule();
-                barrier();
-            }
-            msg = (u32*)mf;
-
-            /* Start piecing the SCSIIORequest together */
-            msg[0] = 0x00000000 | nextchainoffset<<16 | target;
-            msg[1] = 0x0000FF0A;				// 255 sense bytes, 10-byte CDB!
-            msg[3] = lun << 8;
-            msg[4] = 0;
-            msg[5] = scsictl;
-
-            // 16 bytes of CDB @ msg[6,7,8,9] are below...
-
-            msg[6] = (   ((blkno & 0xFF000000) >> 8)
-                       | ((blkno & 0x00FF0000) << 8)
-                       | scsiop );
-            msg[7] = (   (((u32)kPerfInfo.nblks & 0x0000FF00) << 16)
-                       | ((blkno & 0x000000FF) << 8)
-                       | ((blkno & 0x0000FF00) >> 8) );
-            msg[8] = (kPerfInfo.nblks & 0x00FF);
-            msg[9] = 0;
-
-            msg[10] = xferbytes;
-
-//            msg[11] = 0xD0000100;
-//            msg[12] = sbphys;
-//            msg[13] = 0;
-            msg[11] = sbphys;
-
-            // Copy the SGL...
-            if (xferbytes) {
-                sgOut = (SGESimple32_t*)&msg[12];
-                sgIn  = sgl;
-                for (i=0; i < sgfragcpycnt; i++)
-                    *sgOut++ = *sgIn++;
-            }
-
-            // fubar!  QueueDepth issue!!!
-            while (    !rwperf_reset
-                    && (DevIosCount[targetM][lunM] >= MIN(qdepth,64)) )
-            {
-                mb();
-                schedule();
-                barrier();
-            }
-
-//            blkno += kPerfInfo.nblks;
-// EXP Stuff!
-// Try optimizing to certain cache size for the target!
-// by keeping blkno within cache range if at all possible
-#if 0
-            if (    cache_sz
-                 && ((2 * kPerfInfo.nblks) <= (cache_sz>>9))
-                 && ((blkno + kPerfInfo.nblks) > ((cache_sz>>9) + SACRED_BLOCKS)) )
-                blkno = SACRED_BLOCKS;
-            else
-                blkno += kPerfInfo.nblks;
-#endif
-// Ok, cheat!
-            if (cache_sz && ((blkno + kPerfInfo.nblks) > ((cache_sz>>9) + SACRED_BLOCKS)) )
-                   blkno = SACRED_BLOCKS;
-            else
-                blkno += kPerfInfo.nblks;
+	port = karg.hdr.port;
+
+	karg.port = port;
+	pdev = (struct pci_dev *) ioc->pcidev;
 
-            if (blkno > blkhi)
-                blkhi = blkno;
+	karg.pciId = pdev->device;
+	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+	karg.hwRev = revision;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	karg.subSystemDevice = pdev->subsystem_device;
+	karg.subSystemVendor = pdev->subsystem_vendor;
+#endif
 
-            DevIosCount[targetM][lunM]++;
+	/* Get number of devices
+         */
+	if ( (sh = ioc->sh) != NULL) {
+
+		 /* sh->max_id = maximum target ID + 1
+		 */
+		max_id = sh->max_id - 1;
+		hd = (MPT_SCSI_HOST *) sh->hostdata;
+
+		/* Check all of the target structures and
+		 * keep a counter.
+		 */
+		if (hd && hd->Targets) {
+			for (ii = 0; ii <= max_id; ii++) {
+				if (hd->Targets[ii])
+					numDevices++;
+			}
+		}
+	}
+	karg.numDevices = numDevices;
 
-            /*
-             *  Finally, post the request
-             */
-            mpt_put_msg_frame(mptctl_id, ioc, mf);
+	/* Set the BIOS and FW Version
+	 */
+	karg.FWVersion = ioc->facts.FWVersion.Word;
+	karg.BIOSVersion = ioc->biosVersion;
 
+	/* Set the Version Strings.
+	 */
+	strncpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
 
-            /* let linux breath! */
-            mb();
-            schedule();
-            barrier();
+	karg.busChangeEvent = 0;
+	karg.hostId = ioc->pfacts[port].PortSCSIID;
+	karg.rsvd[0] = karg.rsvd[1] = 0;
 
-            //dprintk((KERN_DEBUG MYNAM "-perf: inner-loop, cnt=%d\n", iters));
+	/* Copy the data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *)arg, &karg,
+				sizeof(struct mpt_ioctl_iocinfo))) {
+		printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
+			"Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
 
-        } while ((--iters > 0) && !rwperf_reset);
+	return 0;
+}
 
-        dprintk((KERN_INFO MYNAM "-perf: DbG: blklo=%d, blkhi=%d\n", blklo, blkhi));
-        dprintk((KERN_INFO MYNAM "-perf: target-loop, thisTarget=%d\n", target));
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptctl_gettargetinfo - Query the host adapter for target information.
+ *	@arg: User space argument
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EFAULT if data unavailable
+ *		-ENODEV  if no such device/adapter
+ */
+static int
+mptctl_gettargetinfo (unsigned long arg)
+{
+	struct mpt_ioctl_targetinfo *uarg = (struct mpt_ioctl_targetinfo *) arg;
+	struct mpt_ioctl_targetinfo karg;
+	MPT_ADAPTER		*ioc;
+	struct Scsi_Host	*sh;
+	MPT_SCSI_HOST		*hd;
+	char			*pmem;
+	int			*pdata;
+	int			iocnum;
+	int			numDevices = 0;
+	unsigned int		max_id;
+	int			ii, jj, lun;
+	int			maxWordsLeft;
+	int			numBytes;
+	u8			port;
+
+	dctlprintk(("mptctl_gettargetinfo called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
+		printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
+			"Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
 
-//        //  TEMPORARY!
-//        target = 0;
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
 
-//    } while (target);
+	/* Get the port number and set the maximum number of bytes
+	 * in the returned structure.
+	 * Ignore the port setting.
+	 */
+	numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
+	maxWordsLeft = numBytes/sizeof(int);
+	port = karg.hdr.port;
+
+	if (maxWordsLeft <= 0) {
+		printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",
+				__FILE__, __LINE__);
+		return -ENOMEM;
+	}
 
+	/* Fill in the data and return the structure to the calling
+	 * program
+	 */
 
-    if (DevIosCount[targetM][lunM]) {
-        dprintk((KERN_INFO "  DbG: DevIosCount[%d][%d]=%d\n",
-                targetM, lunM, DevIosCount[targetM][lunM]));
-    }
+	/* struct mpt_ioctl_targetinfo does not contain sufficient space
+	 * for the target structures so when the IOCTL is called, there is
+	 * not sufficient stack space for the structure. Allocate memory,
+	 * populate the memory, copy back to the user, then free memory.
+	 * targetInfo format:
+	 * bits 31-24: reserved
+	 *      23-16: LUN
+	 *      15- 8: Bus Number
+	 *       7- 0: Target ID
+	 */
+	pmem = kmalloc(numBytes, GFP_KERNEL);
+	if (pmem == NULL) {
+		printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",
+				__FILE__, __LINE__);
+		return -ENOMEM;
+	}
+	memset(pmem, 0, numBytes);
+	pdata =  (int *) pmem;
 
-    while (DevIosCount[targetM][lunM]) {
-        //dprintk((KERN_DEBUG "  DbG: Waiting... DevIosCount[%d][%d]=%d\n",
-        //        targetM, lunM, DevIosCount[targetM][lunM]));
-        mb();
-        schedule();
-        barrier();
-    }
-    DevInUse[targetM][lunM] = 0;
+	/* Get number of devices
+         */
+	if ( (sh = ioc->sh) != NULL) {
+
+		max_id = sh->max_id - 1;
+		hd = (MPT_SCSI_HOST *) sh->hostdata;
+
+		/* Check all of the target structures.
+		 * Save the Id and increment the counter,
+		 * if ptr non-null.
+		 * sh->max_id = maximum target ID + 1
+		 */
+		if (hd && hd->Targets) {
+			ii = 0;
+			while (ii <= max_id) {
+				if (hd->Targets[ii]) {
+					for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
+						lun = (1 << jj);
+						if (hd->Targets[ii]->luns & lun) {
+							numDevices++;
+							*pdata = (jj << 16) | ii;
+							--maxWordsLeft;
+
+							pdata++;
+
+							if (maxWordsLeft <= 0) {
+								break;
+							}
+						}
+					}
+				}
+				ii++;
+			}
+		}
+	}
+	karg.numDevices = numDevices;
 
-    pci_free_consistent(iocp->pcidev, 256, SenseBuf, SenseBufDMA);
+	/* Copy part of the data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *)arg, &karg,
+				sizeof(struct mpt_ioctl_targetinfo))) {
+		printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
+			"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		kfree(pmem);
+		return -EFAULT;
+	}
 
-    if (sgl)
-        kfree_sgl(sgl, sgl_dma, buflist, iocp);
+	/* Copy the remaining data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *) uarg->targetInfo, pmem, numBytes)) {
+		printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
+			"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
+				__FILE__, __LINE__, (void*)pdata);
+		kfree(pmem);
+		return -EFAULT;
+	}
 
-    dprintk((KERN_INFO "  *** done ***\n"));
+	kfree(pmem);
 
-    return 0;
+	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* MPT IOCTL Test function.
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EFAULT if data unavailable
+ *		-ENODEV  if no such device/adapter
+ */
 static int
-mpt_ioctl_rwperf_status(unsigned long arg)
+mptctl_readtest (unsigned long arg)
 {
-	struct mpt_raw_r_w	 kPerfInfo;
-				/* NOTE: local copy, on stack==KERNEL_SPACE! */
-	MPT_ADAPTER	*iocp;
-	int		 ioc;
-//	u8		 targ;
-//	u8		 lun;
-	int		 T, L;
-	char		*myname = "_rwperf_status()";
+	struct mpt_ioctl_test	*uarg = (struct mpt_ioctl_test *) arg;
+	struct mpt_ioctl_test	 karg;
+	MPT_ADAPTER *ioc;
+	int iocnum;
 
+	dctlprintk(("mptctl_readtest called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
+		printk(KERN_ERR "%s@%d::mptctl_readtest - "
+			"Unable to read in mpt_ioctl_test struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
 
-	dprintk((KERN_INFO "%s - starting...\n", myname));
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_readtest() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
 
-	/* Get a pointer to the MPT adapter. */
-	if ((ioc = mpt_ioctl_rwperf_init(&kPerfInfo, arg, myname, &iocp)) < 0)
-		return ioc;
+	/* Fill in the data and return the structure to the calling
+	 * program
+	 */
 
-	/* set perf parameters from input */
-//	targ = kPerfInfo.target & 0xFF;
-//	lun = kPerfInfo.lun & 0x1F;
+#ifdef MFCNT
+	karg.chip_type = ioc->mfcnt;
+#else
+	karg.chip_type = ioc->chip_type;
+#endif
+	strncpy (karg.name, ioc->name, MPT_MAX_NAME);
+	strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
 
-	for (T=0; T < myMAX_TARGETS; T++)
-		for (L=0; L < myMAX_LUNS; L++)
-			if (DevIosCount[T][L]) {
-				printk(KERN_INFO "%s: ioc%d->00:%02x:%02x"
-						 ", IosCnt=%d\n",
-						 myname, ioc, T, L, DevIosCount[T][L] );
-			}
+	/* Copy the data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
+		printk(KERN_ERR "%s@%d::mptctl_readtest - "
+			"Unable to write out mpt_ioctl_test struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
 
 	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptctl_eventquery - Query the host adapter for the event types
+ *	that are being logged.
+ *	@arg: User space argument
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EFAULT if data unavailable
+ *		-ENODEV  if no such device/adapter
+ */
 static int
-mpt_ioctl_rwperf_reset(unsigned long arg)
+mptctl_eventquery (unsigned long arg)
 {
-	struct mpt_raw_r_w	 kPerfInfo;
-				/* NOTE: local copy, on stack==KERNEL_SPACE! */
-	MPT_ADAPTER	*iocp;
-	int		 ioc;
-//	u8		 targ;
-//	u8		 lun;
-	int		 T, L;
-	int		 i;
-	char		*myname = "_rwperf_reset()";
-
-	dprintk((KERN_INFO "%s - starting...\n", myname));
-
-	/* Get MPT adapter id. */
-	if ((ioc = mpt_ioctl_rwperf_init(&kPerfInfo, arg, myname, &iocp)) < 0)
-		return ioc;
-
-	/* set perf parameters from input */
-//	targ = kPerfInfo.target & 0xFF;
-//	lun = kPerfInfo.lun & 0x1F;
-
-	rwperf_reset = 1;
-	for (i=0; i < 1000000; i++) {
-		mb();
-		schedule();
-		barrier();
-	}
-	rwperf_reset = 0;
-
-	for (T=0; T < myMAX_TARGETS; T++)
-		for (L=0; L < myMAX_LUNS; L++)
-			if (DevIosCount[T][L]) {
-				printk(KERN_INFO "%s: ioc%d->00:%02x:%02x, "
-						 "IosCnt RESET! (from %d to 0)\n",
-						 myname, ioc, T, L, DevIosCount[T][L] );
-				DevIosCount[T][L] = 0;
-				DevInUse[T][L] = 0;
-			}
+	struct mpt_ioctl_eventquery	*uarg = (struct mpt_ioctl_eventquery *) arg;
+	struct mpt_ioctl_eventquery	 karg;
+	MPT_ADAPTER *ioc;
+	int iocnum;
+
+	dctlprintk(("mptctl_eventquery called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
+		printk(KERN_ERR "%s@%d::mptctl_eventquery - "
+			"Unable to read in mpt_ioctl_eventquery struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
 
+	karg.eventEntries = ioc->eventLogSize;
+	karg.eventTypes = ioc->eventTypes;
+
+	/* Copy the data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
+		printk(KERN_ERR "%s@%d::mptctl_eventquery - "
+			"Unable to write out mpt_ioctl_eventquery struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
 	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
-mpt_ioctl_scsi_cmd(unsigned long arg)
+mptctl_eventenable (unsigned long arg)
 {
-	return -ENOSYS;
+	struct mpt_ioctl_eventenable	*uarg = (struct mpt_ioctl_eventenable *) arg;
+	struct mpt_ioctl_eventenable	 karg;
+	MPT_ADAPTER *ioc;
+	int iocnum;
+
+	dctlprintk(("mptctl_eventenable called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
+		printk(KERN_ERR "%s@%d::mptctl_eventenable - "
+			"Unable to read in mpt_ioctl_eventenable struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+
+	if (ioc->events == NULL) {
+		/* Have not yet allocated memory - do so now.
+		 */
+		int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
+		ioc->events = kmalloc(sz, GFP_KERNEL);
+		if (ioc->events == NULL) {
+			printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
+			return -ENOMEM;
+		}
+		memset(ioc->events, 0, sz);
+		ioc->alloc_total += sz;
+
+		ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE;
+		ioc->eventContext = 0;
+        }
+
+	/* Update the IOC event logging flag.
+	 */
+	ioc->eventTypes = karg.eventTypes;
+
+	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mptctl_eventreport (unsigned long arg)
+{
+	struct mpt_ioctl_eventreport	*uarg = (struct mpt_ioctl_eventreport *) arg;
+	struct mpt_ioctl_eventreport	 karg;
+	MPT_ADAPTER		 *ioc;
+	int			 iocnum;
+	int			 numBytes, maxEvents, max;
+
+	dctlprintk(("mptctl_eventreport called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
+		printk(KERN_ERR "%s@%d::mptctl_eventreport - "
+			"Unable to read in mpt_ioctl_eventreport struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
-#define	owner_THIS_MODULE  owner:		THIS_MODULE,
-#else
-#define	owner_THIS_MODULE
-#endif
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
 
-static struct file_operations mptctl_fops = {
-	owner_THIS_MODULE
-	llseek:		no_llseek,
-	read:		mptctl_read,
-	write:		mptctl_write,
-	ioctl:		mpt_ioctl,
-	open:		mptctl_open,
-	release:	mptctl_release,
-};
+	numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
+	maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
 
-static struct miscdevice mptctl_miscdev = {
-	MPT_MINOR,
-	MYNAM,
-	&mptctl_fops
-};
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+	max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents;
 
-#if defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+	/* If fewer than 1 event is requested, there must have
+	 * been some type of error.
+	 */
+	if ((max < 1) || !ioc->events)
+		return -ENODATA;
 
-/* The dynamic ioctl32 compat. registry only exists in >2.3.x sparc64 kernels */
+	/* Copy the data from kernel memory to user memory
+	 */
+	numBytes = max * sizeof(MPT_IOCTL_EVENTS);
+	if (copy_to_user((char *) uarg->eventData, ioc->events, numBytes)) {
+		printk(KERN_ERR "%s@%d::mptctl_eventreport - "
+			"Unable to write out mpt_ioctl_eventreport struct @ %p\n",
+				__FILE__, __LINE__, (void*)ioc->events);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mptctl_replace_fw (unsigned long arg)
+{
+	struct mpt_ioctl_replace_fw	*uarg = (struct mpt_ioctl_replace_fw *) arg;
+	struct mpt_ioctl_replace_fw	 karg;
+	MPT_ADAPTER		 *ioc;
+	int			 iocnum;
+	u8			 *mem = NULL;
+	dma_addr_t		 mem_dma;
+	int			 oldFwSize, newFwSize;
+
+	dctlprintk(("mptctl_replace_fw called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
+		printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
+			"Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+
+	/* If not caching FW, return 0
+	 */
+	if ((ioc->FWImage == NULL) && (ioc->alt_ioc) && (ioc->alt_ioc->FWImage == NULL)) {
+		return 0;
+	}
+
+
+	/* Allocate memory for the new FW image
+	 */
+	newFwSize = karg.newImageSize;
+	mem = pci_alloc_consistent(ioc->pcidev, newFwSize, &mem_dma);
+	if (mem == NULL)
+		return -ENOMEM;
+
+	ioc->alloc_total += newFwSize;	
+
+	/* Copy the data from user memory to kernel space
+	 */
+	if (copy_from_user(mem, uarg->newImage, newFwSize)) {
+		printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
+			"Unable to read in mpt_ioctl_replace_fw image @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		pci_free_consistent(ioc->pcidev, newFwSize, mem, mem_dma);
+		ioc->alloc_total -= newFwSize;	
+		return -EFAULT;
+	}
+
+	/* Free the old FW image 
+	 */
+	oldFwSize = ioc->facts.FWImageSize;
+	if (ioc->FWImage) {
+		pci_free_consistent(ioc->pcidev, oldFwSize, ioc->FWImage, ioc->FWImage_dma);
+		ioc->alloc_total -= oldFwSize;	
+		ioc->FWImage = mem;
+		ioc->FWImage_dma = mem_dma;
+		
+	} else if ((ioc->alt_ioc) && (ioc->alt_ioc->FWImage)) {
+		pci_free_consistent(ioc->pcidev, oldFwSize, ioc->alt_ioc->FWImage, ioc->alt_ioc->FWImage_dma);
+		ioc->alloc_total -= oldFwSize;	
+		ioc->alt_ioc->FWImage = mem;
+		ioc->alt_ioc->FWImage_dma = mem_dma;
+	}
+
+	/* Update IOCFactsReply
+	 */
+	ioc->facts.FWImageSize = newFwSize;
+	if (ioc->alt_ioc)
+		ioc->alt_ioc->facts.FWImageSize = newFwSize;
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* MPT IOCTL MPTCOMMAND function.
+ * Cast the arg into the mpt_ioctl_mpt_command structure.
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EBUSY  if previous command timout and IOC reset is not complete.
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ *		-ETIME	if timer expires
+ *		-ENOMEM if memory allocation error
+ */
+static int
+mptctl_mpt_command (unsigned long arg)
+{
+	struct mpt_ioctl_command *uarg = (struct mpt_ioctl_command *) arg;
+	struct mpt_ioctl_command  karg;
+	MPT_ADAPTER	*ioc;
+	int		iocnum;
+	int		rc;
+
+	dctlprintk(("mptctl_command called.\n"));
+
+	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
+		printk(KERN_ERR "%s@%d::mptctl_mpt_command - "
+			"Unable to read in mpt_ioctl_command struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+
+	rc = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
+
+	return rc;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands.
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EBUSY  if previous command timout and IOC reset is not complete.
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ *		-ETIME	if timer expires
+ *		-ENOMEM if memory allocation error
+ */
+static int
+mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
+{
+	MPT_ADAPTER	*ioc;
+	MPT_FRAME_HDR	*mf = NULL;
+	MPIHeader_t	*hdr;
+	MptSge_t	*psge;
+	MptSge_t	*this_sge = NULL;
+	MptSge_t	*sglbuf = NULL;
+	struct buflist	bufIn;	/* data In buffer */
+	struct buflist	bufOut; /* data Out buffer */
+	dma_addr_t	sglbuf_dma;
+	dma_addr_t	dma_addr;
+	int		dir;	/* PCI data direction */
+	int		sgSize = 0;	/* Num SG elements */
+	int		this_alloc;
+	int iocnum, flagsLength;
+	int sz, rc = 0;
+	int msgContext;
+	u16		req_idx;
+
+	dctlprintk(("mptctl_do_mpt_command called.\n"));
+
+	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+	if (!ioc->ioctl) {
+		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+			"No memory available during driver init.\n",
+				__FILE__, __LINE__);
+		return -ENOMEM;
+	} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_TIMEOUT) {
+		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+			"Busy with IOC Reset \n", __FILE__, __LINE__);
+		return -EBUSY;
+	}
+
+	/* Verify that the final request frame will not be too large.
+	 */
+	sz = karg.dataSgeOffset * 4;
+	if (karg.dataInSize > 0)
+		sz += sizeof (MptSge_t);
+	if (karg.dataOutSize > 0)
+		sz += sizeof (MptSge_t);
+
+	if ( sz > ioc->req_sz) {
+		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+			"Request frame too large (%d) maximum (%d)\n",
+				__FILE__, __LINE__, sz, ioc->req_sz);
+		return -EFAULT;
+	}
+
+	/* Get a free request frame and save the message context.
+	 */
+        if ((mf = mpt_get_msg_frame(mptctl_id, ioc->id)) == NULL)
+                return -EAGAIN;
+
+	hdr = (MPIHeader_t *) mf;
+	msgContext = le32_to_cpu(hdr->MsgContext);
+	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+
+	/* Copy the request frame
+	 * Reset the saved message context.
+	 */
+        if (local) {
+		/* Request frame in kernel space
+		 */
+		memcpy((char *)mf, (char *) mfPtr, karg.dataSgeOffset * 4);
+        } else {
+		/* Request frame in user space
+		 */
+		if (copy_from_user((char *)mf, (char *) mfPtr,
+					karg.dataSgeOffset * 4)){
+			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+				"Unable to read MF from mpt_ioctl_command struct @ %p\n",
+				__FILE__, __LINE__, (void*)mfPtr);
+			rc = -EFAULT;
+			goto done_free_mem;
+		}
+        }
+	hdr->MsgContext = cpu_to_le32(msgContext);
+
+
+	/* Verify that this request is allowed.
+	 */
+	switch (hdr->Function) {
+	case MPI_FUNCTION_IOC_FACTS:
+	case MPI_FUNCTION_PORT_FACTS:
+	case MPI_FUNCTION_CONFIG:
+	case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
+	case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
+	case MPI_FUNCTION_FW_UPLOAD:
+	case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
+	case MPI_FUNCTION_FW_DOWNLOAD:
+		break;
+
+	case MPI_FUNCTION_SCSI_IO_REQUEST:
+		if (ioc->sh) {
+			SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
+			VirtDevice	*pTarget = NULL;
+			MPT_SCSI_HOST	*hd = NULL;
+			int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
+			int scsidir = 0;
+			int target = (int) pScsiReq->TargetID;
+			int dataSize;
+
+			pScsiReq->MsgFlags = MPT_SCSIIO_MSG_FLAGS;
+
+			/* verify that app has not requested
+			 *	more sense data than driver
+			 *	can provide, if so, reset this parameter
+			 * set the sense buffer pointer low address
+			 * update the control field to specify Q type
+			 */
+			if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
+				pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
+
+			pScsiReq->SenseBufferLowAddr =
+				cpu_to_le32(ioc->sense_buf_low_dma
+				   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
+
+			if ( (hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
+				if (hd->Targets)
+					pTarget = hd->Targets[target];
+			}
+
+			if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
+				qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
+
+			/* Have the IOCTL driver set the direction based
+			 * on the dataOutSize (ordering issue with Sparc).
+			 */
+			if (karg.dataOutSize > 0 ) {
+				scsidir = MPI_SCSIIO_CONTROL_WRITE;
+				dataSize = karg.dataOutSize;
+			}
+			else {
+				scsidir = MPI_SCSIIO_CONTROL_READ;
+				dataSize = karg.dataInSize;
+			}
+
+			pScsiReq->Control = cpu_to_le32(scsidir | qtag);
+			pScsiReq->DataLength = cpu_to_le32(dataSize);
+
+		} else {
+			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+				"SCSI driver is not loaded. \n",
+					__FILE__, __LINE__);
+			rc = -EFAULT;
+			goto done_free_mem;
+		}
+		break;
+
+	case MPI_FUNCTION_RAID_ACTION:
+		/* Just add a SGE
+		 */
+		break;
+
+	case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
+		if (ioc->sh) {
+			SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
+			int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
+			int scsidir = MPI_SCSIIO_CONTROL_READ;
+			int dataSize;
+
+			pScsiReq->MsgFlags = MPT_SCSIIO_MSG_FLAGS;
+
+			/* verify that app has not requested
+			 *	more sense data than driver
+			 *	can provide, if so, reset this parameter
+			 * set the sense buffer pointer low address
+			 * update the control field to specify Q type
+			 */
+			if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
+				pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
+
+			pScsiReq->SenseBufferLowAddr =
+				cpu_to_le32(ioc->sense_buf_low_dma
+				   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
+
+			/* All commands to physical devices are tagged
+			 */
+
+			/* Have the IOCTL driver set the direction based
+			 * on the dataOutSize (ordering issue with Sparc).
+			 */
+			if (karg.dataOutSize > 0 ) {
+				scsidir = MPI_SCSIIO_CONTROL_WRITE;
+				dataSize = karg.dataOutSize;
+			}
+			else {
+				scsidir = MPI_SCSIIO_CONTROL_READ;
+				dataSize = karg.dataInSize;
+			}
+
+			pScsiReq->Control = cpu_to_le32(scsidir | qtag);
+			pScsiReq->DataLength = cpu_to_le32(dataSize);
+
+		} else {
+			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+				"SCSI driver is not loaded. \n",
+					__FILE__, __LINE__);
+			rc = -EFAULT;
+			goto done_free_mem;
+		}
+		break;
+
+	default:
+		/*
+		 * MPI_FUNCTION_IOC_INIT
+		 * MPI_FUNCTION_PORT_ENABLE
+		 * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
+		 * MPI_FUNCTION_TARGET_ASSIST
+		 * MPI_FUNCTION_TARGET_STATUS_SEND
+		 * MPI_FUNCTION_TARGET_MODE_ABORT
+		 * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
+		 * MPI_FUNCTION_IO_UNIT_RESET
+		 * MPI_FUNCTION_HANDSHAKE
+		 * MPI_FUNCTION_REPLY_FRAME_REMOVAL
+		 * MPI_FUNCTION_EVENT_NOTIFICATION
+		 *  (driver handles event notification)
+		 * MPI_FUNCTION_EVENT_ACK
+		 * MPI_FUNCTION_SCSI_TASK_MGMT
+		 */
+
+		/*  What to do with these???  CHECK ME!!!
+			MPI_FUNCTION_FC_LINK_SRVC_BUF_POST
+			MPI_FUNCTION_FC_LINK_SRVC_RSP
+			MPI_FUNCTION_FC_ABORT
+			MPI_FUNCTION_FC_PRIMITIVE_SEND
+			MPI_FUNCTION_LAN_SEND
+			MPI_FUNCTION_LAN_RECEIVE
+		 	MPI_FUNCTION_LAN_RESET
+		*/
+
+		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+			"Illegal request (function 0x%x) \n",
+			__FILE__, __LINE__, hdr->Function);
+		rc = -EFAULT;
+		goto done_free_mem;
+	}
+
+	/* Add the SGL ( at most one data in SGE and one data out SGE )
+	 * In the case of two SGE's - the data out (write) will always
+	 * preceede the data in (read) SGE. psgList is used to free the
+	 * allocated memory.
+	 */
+	psge = (MptSge_t *) ( ((int *) mf) + karg.dataSgeOffset);
+	flagsLength = 0;
+
+	/* bufIn and bufOut are used for user to kernel space transfers
+	 */
+	bufIn.kptr = bufOut.kptr = NULL;
+	bufIn.len = bufOut.len = 0;
+
+	if (karg.dataOutSize > 0 )
+		sgSize ++;
+
+	if (karg.dataInSize > 0 )
+		sgSize ++;
+
+	if (sgSize > 0) {
+
+		/* Allocate memory for the SGL.
+		 * Used to free kernel memory once
+		 * the MF is freed.
+		 */
+		sglbuf = pci_alloc_consistent (ioc->pcidev,
+			sgSize*sizeof(MptSge_t), &sglbuf_dma);
+		if (sglbuf == NULL) {
+			rc = -ENOMEM;
+			goto done_free_mem;
+		}
+		this_sge = sglbuf;
+
+		/* Set up the dataOut memory allocation */
+		if (karg.dataOutSize > 0) {
+			dir = PCI_DMA_TODEVICE;
+			if (karg.dataInSize > 0 ) {
+				flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+						MPI_SGE_FLAGS_DIRECTION |
+						MPT_SGE_ADDRESS_SIZE )
+						<< MPI_SGE_FLAGS_SHIFT;
+			} else {
+				flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
+			}
+			flagsLength |= karg.dataOutSize;
+
+			this_alloc = karg.dataOutSize;
+			bufOut.len = this_alloc;
+			bufOut.kptr = pci_alloc_consistent(
+					ioc->pcidev, this_alloc, &dma_addr);
+
+			if (bufOut.kptr == NULL) {
+				rc = -ENOMEM;
+				goto done_free_mem;
+			} else {
+				/* Copy user data to kernel space.
+				 */
+				if (copy_from_user(bufOut.kptr,
+						karg.dataOutBufPtr,
+						bufOut.len)) {
+
+					printk(KERN_ERR
+						"%s@%d::mptctl_do_mpt_command - Unable "
+						"to read user data "
+						"struct @ %p\n",
+						__FILE__, __LINE__,(void*)karg.dataOutBufPtr);
+					rc =  -EFAULT;
+					goto done_free_mem;
+				}
+
+				/* Set up this SGE.
+				 * Copy to MF and to sglbuf
+				 */
+
+				psge->FlagsLength = cpu_to_le32 (flagsLength);
+				cpu_to_leXX(dma_addr, psge->Address);
+				psge++;
+
+				this_sge->FlagsLength=cpu_to_le32(flagsLength);
+				cpu_to_leXX(dma_addr, this_sge->Address);
+				this_sge++;
+			}
+		}
+
+		if (karg.dataInSize > 0) {
+			dir = PCI_DMA_FROMDEVICE;
+			flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
+			flagsLength |= karg.dataInSize;
+
+			this_alloc = karg.dataInSize;
+			bufIn.len = this_alloc;
+			bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
+							this_alloc, &dma_addr);
+			if (bufIn.kptr == NULL) {
+				rc = -ENOMEM;
+				goto done_free_mem;
+			} else {
+				/* Set up this SGE
+				 * Copy to MF and to sglbuf
+				 */
+				psge->FlagsLength = cpu_to_le32 (flagsLength);
+				cpu_to_leXX(dma_addr, psge->Address);
+
+				this_sge->FlagsLength=cpu_to_le32(flagsLength);
+				cpu_to_leXX(dma_addr, this_sge->Address);
+				this_sge++;
+			}
+		}
+	} else  {
+		/* Add a NULL SGE
+		 */
+		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
+		psge->FlagsLength = cpu_to_le32 (flagsLength);
+		cpu_to_leXX( (dma_addr_t) -1, psge->Address);
+	}
+
+	/* The request is complete. Set the timer parameters
+	 * and issue the request.
+	 */
+	if (karg.timeout > 0) {
+		ioc->ioctl->timer.expires = jiffies + HZ*karg.timeout;
+	} else {
+		ioc->ioctl->timer.expires = jiffies + HZ*MPT_IOCTL_DEFAULT_TIMEOUT;
+	}
+
+	ioc->ioctl->wait_done = 0;
+	ioc->ioctl->status |= MPT_IOCTL_STATUS_TIMER_ACTIVE;
+	add_timer(&ioc->ioctl->timer);
+
+	mpt_put_msg_frame(mptctl_id, ioc->id, mf);
+	wait_event(mptctl_wait, ioc->ioctl->wait_done);
+
+	/* The command is complete.  * Return data to the user.
+	 *
+	 * If command completed,  mf has been freed so cannot
+	 * use this memory.
+	 *
+	 * If timeout, a recovery  mechanism has been called.
+	 * Need to free the mf.
+	 */
+	if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_TIMEOUT) {
+
+		/* A timeout - there is no data to return to the
+		 * the user other than an error.
+		 * The timer callback deleted the
+		 * timer and reset the adapter queues.
+		 */
+		printk(KERN_WARNING "%s@%d::mptctl_do_mpt_command - "
+			"Timeout Occurred on IOCTL! Resetting IOC.\n", __FILE__, __LINE__);
+		rc = -ETIME;
+
+		/* Free memory and return to the calling function
+		 */
+		goto done_free_mem;
+
+	} else {
+		/* Callback freed request frame.
+		 */
+		mf = NULL;
+
+		/* If a valid reply frame, copy to the user.
+		 * Offset 2: reply length in U32's
+		 */
+		if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) {
+			if (karg.maxReplyBytes < ioc->reply_sz) {
+				 sz = MIN(karg.maxReplyBytes, 4*ioc->ioctl->ReplyFrame[2]);
+			} else {
+				 sz = MIN(ioc->reply_sz, 4*ioc->ioctl->ReplyFrame[2]);
+			}
+
+			if (sz > 0) {
+				if (copy_to_user((char *)karg.replyFrameBufPtr,
+					 &ioc->ioctl->ReplyFrame, sz)){
+
+					 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+					 "Unable to write out reply frame %p\n",
+					 __FILE__, __LINE__, (void*)karg.replyFrameBufPtr);
+					 rc =  -ENODATA;
+					 goto done_free_mem;
+				}
+			}
+		}
+
+		/* If valid sense data, copy to user.
+		 */
+		if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {
+			sz = MIN(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
+			if (sz > 0) {
+				if (copy_to_user((char *)karg.senseDataPtr, ioc->ioctl->sense, sz)) {
+					printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+					"Unable to write sense data to user %p\n",
+					__FILE__, __LINE__,
+					(void*)karg.senseDataPtr);
+					rc =  -ENODATA;
+					goto done_free_mem;
+				}
+			}
+		}
+
+		/* If the overall status is _GOOD and data in, copy data
+		 * to user.
+		 */
+		if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&
+					(karg.dataInSize > 0) && (bufIn.kptr)) {
+
+			if (copy_to_user((char *)karg.dataInBufPtr,
+					 bufIn.kptr, karg.dataInSize)) {
+				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+					"Unable to write data to user %p\n",
+					__FILE__, __LINE__,
+					(void*)karg.dataInBufPtr);
+				rc =  -ENODATA;
+			}
+		}
+	}
+
+done_free_mem:
+	/* Clear status bits.
+	 */
+	ioc->ioctl->status = 0;
+
+	if (sglbuf) {
+		this_sge = sglbuf;
+
+		/* Free the allocated memory.
+		 */
+		 if (bufOut.kptr != NULL ) {
+
+			leXX_to_cpu (dma_addr, this_sge->Address);
+
+			this_sge++;	/* go to next structure */
+			this_alloc = bufOut.len;
+			pci_free_consistent(ioc->pcidev,
+				this_alloc, (void *) &bufOut, dma_addr);
+		}
+
+		if (bufIn.kptr != NULL ) {
+			leXX_to_cpu (dma_addr, this_sge->Address);
+			this_alloc = bufIn.len;
+
+			pci_free_consistent(ioc->pcidev,
+					this_alloc, (void *) &bufIn, dma_addr);
+		}
+
+		this_alloc = sgSize * sizeof(MptSge_t);
+		pci_free_consistent(ioc->pcidev,
+				this_alloc, (void *) sglbuf, sglbuf_dma);
+
+	}
+
+	/* mf will be null if allocation failed OR
+	 * if command completed OK (callback freed)
+	 */
+	if (mf)
+		mpt_free_msg_frame(mptctl_id, ioc->id, mf);
+
+	return rc;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* Routine for the Compaq IOCTL commands.
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EBUSY  if previous command timout and IOC reset is not complete.
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ *		-ETIME	if timer expires
+ *		-ENOMEM if memory allocation error
+ */
+static int
+mptctl_compaq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int iocnum = 0;
+	unsigned iocnumX = 0;
+	int ret;
+	int nonblock = (file->f_flags & O_NONBLOCK);
+	MPT_ADAPTER *iocp = NULL;
+
+	if (cmd == CPQFCTS_SCSI_PASSTHRU) {
+		/* Update the iocnum */
+		if (copy_from_user(&iocnumX, (int *)arg, sizeof(int))) {
+			printk(KERN_ERR "%s::mptctl_compaq_ioctl() @%d - "
+				"Unable to read controller number @ %p\n",
+				__FILE__, __LINE__, (void*)arg);
+			return -EFAULT;
+		}
+		iocnumX &= 0xFF;
+	}
+
+	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
+	    (iocp == NULL)) {
+		printk(KERN_ERR "%s::mptctl_compaq_ioctl() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnumX);
+		return -ENODEV;
+	}
+
+	/* All of these commands require an interrupt or
+	 * are unknown/illegal.
+	 */
+	if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
+		return ret;
+
+	dctlprintk((MYIOC_s_INFO_FMT ": mptctl_compaq_ioctl()\n", iocp->name));
+
+	switch(cmd) {
+	case CPQFCTS_GETPCIINFO:
+		ret = mptctl_cpq_getpciinfo(arg);
+		break;
+	case CPQFCTS_GETDRIVER:
+		ret = mptctl_cpq_getdriver(arg);
+		break;
+	case CPQFCTS_CTLR_STATUS:
+		ret = mptctl_cpq_ctlr_status(arg);
+		break;
+	case CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS:
+		ret = mptctl_cpq_target_address(arg);
+		break;
+	case CPQFCTS_SCSI_PASSTHRU:
+		ret = mptctl_cpq_passthru(arg);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	up(&mptctl_syscall_sem_ioc[iocp->id]);
+
+	return ret;
+
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* mptctl_cpq_getpciinfo - Get PCI Information in format desired by Compaq
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EBUSY  if previous command timout and IOC reset is not complete.
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ *		-ETIME	if timer expires
+ */
+static int
+mptctl_cpq_getpciinfo(unsigned long arg)
+{
+	cpqfc_pci_info_struct *uarg = (cpqfc_pci_info_struct *) arg;
+	cpqfc_pci_info_struct karg;
+	MPT_ADAPTER		*ioc;
+	struct pci_dev		*pdev;
+	CONFIGPARMS		cfg;
+	ConfigPageHeader_t	hdr;
+	int			iocnum = 0, iocnumX = 0;
+	dma_addr_t		buf_dma;
+	u8			*pbuf = NULL;
+	int			failed;
+
+	dctlprintk((": mptctl_cpq_pciinfo called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(cpqfc_pci_info_struct))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_pciinfo - "
+			"Unable to read in cpqfc_pci_info_struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_pciinfo() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+
+	pdev = (struct pci_dev *) ioc->pcidev;
+
+	/* Populate the structure. */
+	karg.bus = pdev->bus->number;
+	karg.bus_type = 1;	/* 1 = PCI; 4 = unknown */
+	karg.device_fn = PCI_FUNC(pdev->devfn);
+	karg.slot_number = PCI_SLOT(pdev->devfn);
+	karg.vendor_id = pdev->vendor;
+	karg.device_id = pdev->device;
+	karg.board_id = (karg.device_id | (karg.vendor_id << 16));
+	karg.class_code = pdev->class;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	karg.sub_vendor_id = pdev->subsystem_vendor;
+	karg.sub_device_id = pdev->subsystem_device;
+#endif
+
+	/* Issue a config request to get the device serial number
+	 */
+	hdr.PageVersion = 0;
+	hdr.PageLength = 0;
+	hdr.PageNumber = 0;
+	hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
+	cfg.hdr = &hdr;
+	cfg.physAddr = -1;
+	cfg.pageAddr = 0;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;	/* read */
+	cfg.timeout = 10;
+
+	failed = 1;
+
+	if (mpt_config(ioc, &cfg) == 0) {
+		if (cfg.hdr->PageLength > 0) {
+			/* Issue the second config page request */
+			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+			pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
+			if (pbuf) {
+				cfg.physAddr = buf_dma;
+				if (mpt_config(ioc, &cfg) == 0) {
+					ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
+					strncpy(karg.serial_number, pdata->BoardTracerNumber, 17);
+					failed = 0;
+				}
+				pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
+				pbuf = NULL;
+			}
+		}
+	}
+	if (failed)
+		strncpy(karg.serial_number, " ", 17);
+
+	/* Copy the data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *)arg, &karg,
+				sizeof(cpqfc_pci_info_struct))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_pciinfo - "
+			"Unable to write out cpqfc_pci_info_struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* mptctl_cpq_getdriver - Get Driver Version in format desired by Compaq
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ */
+static int
+mptctl_cpq_getdriver(unsigned long arg)
+{
+	int		*uarg = (int *)arg;
+	int		karg;
+	MPT_ADAPTER	*ioc = NULL;
+	int		iocnum = 0, iocnumX = 0;
+	int		ii, jj;
+	char		version[10];
+	char		val;
+	char		*vptr = NULL;
+	char		*pptr = NULL;
+
+	dctlprintk((": mptctl_cpq_getdriver called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(int))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_getdriver - "
+			"Unable to read in struct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_cpq_getdriver() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+
+	strncpy(version, MPT_LINUX_VERSION_COMMON, 8);
+
+	karg = 0;
+	vptr = version;
+	ii = 3;
+	while (ii > 0) {
+		pptr = strchr(vptr, '.');
+		if (pptr) {
+			*pptr = '\0';
+			val = 0;
+			for (jj=0; vptr[jj]>='0' && vptr[jj]<='9'; jj++)
+				val = 10 * val + (vptr[jj] - '0');
+			karg |= (val << (8*ii));
+			pptr++;
+			vptr = pptr;
+		} else
+			break;
+		ii--;
+	}
+
+	/* Copy the data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *)arg, &karg,
+				sizeof(int))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_getdriver - "
+			"Unable to write out stuct @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* mptctl_cpq_ctlr_status - Get controller status in format desired by Compaq
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ */
+static int
+mptctl_cpq_ctlr_status(unsigned long arg)
+{
+	cpqfc_ctlr_status *uarg = (cpqfc_ctlr_status *) arg;
+	cpqfc_ctlr_status karg;
+	MPT_ADAPTER		*ioc;
+	int			iocnum = 0, iocnumX = 0;
+
+	dctlprintk((": mptctl_cpq_pciinfo called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(cpqfc_ctlr_status))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_ctlr_status - "
+			"Unable to read in cpqfc_ctlr_status @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_cpq_ctlr_status() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+
+	karg.status = ioc->last_state;
+	karg.offline_reason = 0;
+
+	/* Copy the data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *)arg, &karg,
+				sizeof(cpqfc_ctlr_status))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_ctlr_status - "
+			"Unable to write out cpqfc_ctlr_status @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* mptctl_cpq_target_address - Get WWN Information in format desired by Compaq
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EBUSY  if previous command timout and IOC reset is not complete.
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ *		-ETIME	if timer expires
+ */
+static int
+mptctl_cpq_target_address(unsigned long arg)
+{
+	Scsi_FCTargAddress *uarg = (Scsi_FCTargAddress *) arg;
+	Scsi_FCTargAddress karg;
+	MPT_ADAPTER		*ioc;
+	int			iocnum = 0, iocnumX = 0;
+	CONFIGPARMS		cfg;
+	ConfigPageHeader_t	hdr;
+	dma_addr_t		buf_dma;
+	u8			*pbuf = NULL;
+	FCPortPage0_t		*ppp0;
+	int			ii, failed;
+	u32			low, high;
+
+	dctlprintk((": mptctl_cpq_target_address called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(Scsi_FCTargAddress))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_target_address - "
+			"Unable to read in Scsi_FCTargAddress @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_cpq_target_address() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+
+	karg.host_port_id = 0;
+
+	/* Issue a config request to get the device wwn
+	 */
+	hdr.PageVersion = 0;
+	hdr.PageLength = 0;
+	hdr.PageNumber = 0;
+	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
+	cfg.hdr = &hdr;
+	cfg.physAddr = -1;
+	cfg.pageAddr = 0;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;	/* read */
+	cfg.timeout = 10;
+
+	failed = 1;
+
+	if (mpt_config(ioc, &cfg) == 0) {
+		if (cfg.hdr->PageLength > 0) {
+			/* Issue the second config page request */
+			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+			pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
+			if (pbuf) {
+				cfg.physAddr = buf_dma;
+				if (mpt_config(ioc, &cfg) == 0) {
+					ppp0 = (FCPortPage0_t *) pbuf;
+
+					low = le32_to_cpu(ppp0->WWNN.Low);
+					high = le32_to_cpu(ppp0->WWNN.High);
+
+					for (ii = 0; ii < 4; ii++) {
+						karg.host_wwn[7-ii] = low & 0xFF;
+						karg.host_wwn[3-ii] = high & 0xFF;
+						low = (low >> 8);
+						high = (high >> 8);
+					}
+					failed = 0;
+				}
+				pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
+				pbuf = NULL;
+			}
+		}
+	}
+
+	if (failed) {
+		for (ii = 7; ii >= 0; ii--)
+			karg.host_wwn[ii] = 0;
+	}
+
+	/* Copy the data from kernel memory to user memory
+	 */
+	if (copy_to_user((char *)arg, &karg,
+				sizeof(Scsi_FCTargAddress))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_target_address - "
+			"Unable to write out Scsi_FCTargAddress @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* mptctl_cpq_passthru - Construct and issue a SCSI IO Passthru
+ *
+ * Requires the SCSI host driver to be loaded.
+ * I386 version.
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EBUSY  if previous command timout and IOC reset is not complete.
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ *		-ETIME	if timer expires
+ */
+static int
+mptctl_cpq_passthru(unsigned long arg)
+{
+	VENDOR_IOCTL_REQ	*uarg = (VENDOR_IOCTL_REQ *) arg;
+	VENDOR_IOCTL_REQ	karg;
+	cpqfc_passthru_t	kpass;
+	MPT_ADAPTER		*ioc;
+	int			iocnum = 0, iocnumX = 0;
+	int			rc;
+
+	dctlprintk((": mptctl_cpq_passthru called.\n"));
+	if (copy_from_user(&karg, uarg, sizeof(VENDOR_IOCTL_REQ))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_passthru - "
+			"Unable to read in VENDOR_IOCTL_REQ @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	/* Set the IOC number */
+	iocnumX = karg.lc & 0xFF;
+	if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR "%s::mptctl_cpq_passthru() @%d - ioc%d not found!\n",
+				__FILE__, __LINE__, iocnum);
+		return -ENODEV;
+	}
+
+	if (ioc->sh == NULL) {
+		printk(KERN_ERR "%s::mptctl_cpq_passthru() @%d - SCSI Host driver not loaded!\n",
+				__FILE__, __LINE__);
+		return -EFAULT;
+	}
+
+	/* Read in the second buffer */
+	if (copy_from_user(&kpass, uarg->argp, sizeof(cpqfc_passthru_t))) {
+		printk(KERN_ERR "%s@%d::mptctl_cpq_passthru - "
+			"Unable to read in cpqfc_passthru_t @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+
+	/* Generate the SCSI IO command and issue */
+	rc = mptctl_compaq_scsiio(&karg, &kpass);
+	return rc;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* mptctl_compaq_scsiio - Reformat Compaq structures into driver structures
+ * Call the generic _do_mpt_command function.
+ *
+ * Requires the SCSI host driver to be loaded.
+ * I386 version.
+ *
+ * Outputs:	None.
+ * Return:	0 if successful
+ *		-EBUSY  if previous command timout and IOC reset is not complete.
+ *		-EFAULT if data unavailable
+ *		-ENODEV if no such device/adapter
+ *		-ETIME	if timer expires
+ */
+static int
+mptctl_compaq_scsiio(VENDOR_IOCTL_REQ *pVenReq, cpqfc_passthru_t *pPass)
+{
+	struct mpt_ioctl_command karg;
+	SCSIIORequest_t		 request ;
+	SCSIIORequest_t		 *pMf;
+	int			 ii, rc;
+	u8			 opcode;
+
+	/* Fill in parameters to karg */
+	karg.hdr.iocnum = pVenReq->lc;
+	karg.hdr.port = 0;
+	karg.hdr.maxDataSize = 0;	/* not used */
+	karg.timeout = 0;		/* use default */
+
+	karg.replyFrameBufPtr = NULL;	/* no reply data */
+	karg.maxReplyBytes = 0;
+
+	karg.senseDataPtr = pPass->sense_data;
+	karg.maxSenseBytes = pPass->sense_len;	/* max is 40 */
+
+	if (pPass->rw_flag == MPT_COMPAQ_WRITE) {
+		karg.dataOutBufPtr = pPass->bufp;
+		karg.dataOutSize = pPass->len;
+		karg.dataInBufPtr = NULL;
+		karg.dataInSize = 0;
+	} else {
+		karg.dataInBufPtr = pPass->bufp;
+		karg.dataInSize = pPass->len;
+		karg.dataOutBufPtr = NULL;
+		karg.dataOutSize = 0;
+	}
+
+	karg.dataSgeOffset = (sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION))/4;
+
+	/* Construct the Message frame */
+	pMf = &request;
+
+	pMf->TargetID =	(u8) pVenReq->ld;			/* ???? FIXME */
+	pMf->Bus = (u8) pPass->bus;
+	pMf->ChainOffset = 0;
+	pMf->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
+
+	/* May need some tweaking here */
+	opcode = (u8) pPass->cdb[0];
+	if (opcode < 0x20)
+		pMf->CDBLength = 6;
+	else if (opcode < 0x60)
+		pMf->CDBLength = 10;
+	else if ((opcode < 0xC0) && (opcode >= 0xA0))
+		pMf->CDBLength = 12;
+	else
+		pMf->CDBLength = 16;
+
+	pMf->SenseBufferLength = karg.maxSenseBytes;	/* max is 40 */
+	pMf->Reserved = 0;
+	pMf->MsgFlags = 0;				/* set later */
+	pMf->MsgContext = 0;				/* set later */
+
+	for (ii = 0; ii < 8; ii++)
+		pMf->LUN[ii] = 0;
+	pMf->LUN[1] = 0;				/* ???? FIXME */
+
+	/* Tag values set by _do_mpt_command */
+	if (pPass->rw_flag == MPT_COMPAQ_WRITE)
+		pMf->Control = MPI_SCSIIO_CONTROL_WRITE;
+	else
+		pMf->Control = MPI_SCSIIO_CONTROL_READ;
+
+	for (ii = 0; ii < 16; ii++)
+		pMf->CDB[ii] = pPass->cdb[ii];
+
+	pMf->DataLength = pPass->len;
+
+	/* All remaining fields are set by the next function
+	 */
+	rc = mptctl_do_mpt_command (karg, (char *)pMf, 1);
+	return rc;
+}
+
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
+#define	owner_THIS_MODULE  owner:		THIS_MODULE,
+#else
+#define	owner_THIS_MODULE
+#endif
+
+static struct file_operations mptctl_fops = {
+	owner_THIS_MODULE
+	llseek:		no_llseek,
+	read:		mptctl_read,
+	write:		mptctl_write,
+	ioctl:		mptctl_ioctl,
+	open:		mptctl_open,
+	release:	mptctl_release,
+};
+
+static struct miscdevice mptctl_miscdev = {
+	MPT_MINOR,
+	MYNAM,
+	&mptctl_fops
+};
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+#if defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+
+/* The dynamic ioctl32 compat. registry only exists in >2.3.x sparc64 kernels */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)		/*{*/
 extern int register_ioctl32_conversion(unsigned int cmd,
 				       int (*handler)(unsigned int,
@@ -1133,18 +2773,15 @@
 						      unsigned long,
 						      struct file *));
 int unregister_ioctl32_conversion(unsigned int cmd);
-
-struct mpt_fw_xfer32 {
-	unsigned int iocnum;
-	unsigned int fwlen;
-	u32 bufp;
-};
-
-#define MPTFWDOWNLOAD32     _IOWR(MPT_MAGIC_NUMBER,15,struct mpt_fw_xfer32)
-
 extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* sparc32_XXX functions are used to provide a conversion between
+ * pointers and u32's. If the arg does not contain any pointers, then
+ * a specialized function (sparc32_XXX) is not needed. If the arg
+ * does contain pointer(s), then the specialized function is used
+ * to ensure the structure contents is properly processed by mptctl.
+ */
 static int
 sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
 			unsigned long arg, struct file *filp)
@@ -1156,7 +2793,7 @@
 	int nonblock = (filp->f_flags & O_NONBLOCK);
 	int ret;
 
-	dprintk((KERN_INFO MYNAM "::sparc32_mptfwxfer_ioctl() called\n"));
+	dctlprintk((KERN_INFO MYNAM "::sparc32_mptfwxfer_ioctl() called\n"));
 
 	if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32)))
 		return -EFAULT;
@@ -1177,13 +2814,131 @@
 	kfw.fwlen = kfw32.fwlen;
 	kfw.bufp = (void *)(unsigned long)kfw32.bufp;
 
-	ret = mpt_ioctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
+	ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
+
+	up(&mptctl_syscall_sem_ioc[iocp->id]);
+
+	return ret;
+}
+
+static int
+sparc32_mpt_command(unsigned int fd, unsigned int cmd,
+			unsigned long arg, struct file *filp)
+{
+	struct mpt_ioctl_command32 karg32;
+	struct mpt_ioctl_command32 *uarg = (struct mpt_ioctl_command32 *) arg;
+	struct mpt_ioctl_command karg;
+	MPT_ADAPTER *iocp = NULL;
+	int iocnum, iocnumX;
+	int nonblock = (filp->f_flags & O_NONBLOCK);
+	int ret;
+
+	dctlprintk((KERN_INFO MYNAM "::sparc32_mpt_command() called\n"));
+
+	if (copy_from_user(&karg32, (char *)arg, sizeof(karg32)))
+		return -EFAULT;
+
+	/* Verify intended MPT adapter */
+	iocnumX = karg32.hdr.iocnum & 0xFF;
+	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
+	    (iocp == NULL)) {
+		printk(KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n",
+				__LINE__, iocnumX);
+		return -ENODEV;
+	}
+
+	if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
+		return ret;
+
+	/* Copy data to karg */
+	karg.hdr.iocnum = karg32.hdr.iocnum;
+	karg.hdr.port = karg32.hdr.port;
+	karg.timeout = karg32.timeout;
+	karg.maxReplyBytes = karg32.maxReplyBytes;
+
+	karg.dataInSize = karg32.dataInSize;
+	karg.dataOutSize = karg32.dataOutSize;
+	karg.maxSenseBytes = karg32.maxSenseBytes;
+	karg.dataSgeOffset = karg32.dataSgeOffset;
+
+	karg.replyFrameBufPtr = (char *)(unsigned long)karg32.replyFrameBufPtr;
+	karg.dataInBufPtr = (char *)(unsigned long)karg32.dataInBufPtr;
+	karg.dataOutBufPtr = (char *)(unsigned long)karg32.dataOutBufPtr;
+	karg.senseDataPtr = (char *)(unsigned long)karg32.senseDataPtr;
+
+	/* Pass new structure to do_mpt_command
+	 */
+	ret = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
 
 	up(&mptctl_syscall_sem_ioc[iocp->id]);
 
 	return ret;
 }
 
+static int
+sparc32_mptctl_cpq_passthru(unsigned int fd, unsigned int cmd,
+			unsigned long arg, struct file *filp)
+{
+	VENDOR_IOCTL_REQ32	*uarg = (VENDOR_IOCTL_REQ32 *) arg;
+	VENDOR_IOCTL_REQ32	karg32;
+	VENDOR_IOCTL_REQ	karg;
+	cpqfc_passthru32_t	kpass32;
+	cpqfc_passthru_t	kpass;
+	MPT_ADAPTER		*ioc;
+	int			nonblock = (filp->f_flags & O_NONBLOCK);
+	int			iocnum = 0, iocnumX = 0;
+	int			rc;
+	int			ii;
+
+	dctlprintk((KERN_INFO MYNAM "::sparc32_mptctl_cpq_passthru() called\n"));
+
+	if (copy_from_user(&karg32, (char *)arg, sizeof(karg32)))
+		return -EFAULT;
+
+	/* Verify intended MPT adapter */
+	iocnumX = karg32.lc & 0xFF;
+	if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
+	    (ioc == NULL)) {
+		printk(KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n",
+				__LINE__, iocnumX);
+		return -ENODEV;
+	}
+
+	if ((rc = mptctl_syscall_down(ioc, nonblock)) != 0)
+		return rc;
+
+	/* Copy data to karg */
+	karg.ld = karg32.ld;
+	karg.node = karg32.node;
+	karg.lc = karg32.lc;
+	karg.nexus = karg32.nexus;
+	karg.argp = (void *)(unsigned long)karg32.argp;
+
+	/* Read in the second buffer */
+	if (copy_from_user(&kpass32, karg.argp, sizeof(cpqfc_passthru32_t))) {
+		printk(KERN_ERR "%s@%d::sparc32_mptctl_cpq_passthru - "
+			"Unable to read in cpqfc_passthru_t @ %p\n",
+				__FILE__, __LINE__, (void*)uarg);
+		return -EFAULT;
+	}
+
+	/* Copy the 32bit buffer to kpass */
+	for (ii = 0; ii < 16; ii++)
+		kpass.cdb[ii] = kpass32.cdb[ii];
+	kpass.bus = kpass32.bus;
+	kpass.pdrive = kpass32.pdrive;
+	kpass.len = kpass32.len;
+	kpass.sense_len = kpass32.sense_len;
+	kpass.bufp = (void *)(unsigned long)kpass32.bufp;
+	kpass.rw_flag = kpass32.rw_flag;
+
+	/* Generate the SCSI IO command and issue */
+	rc = mptctl_compaq_scsiio(&karg, &kpass);
+
+	up(&mptctl_syscall_sem_ioc[ioc->id]);
+	return rc;
+}
+
 #endif		/*} linux >= 2.3.x */
 #endif		/*} sparc */
 
@@ -1193,26 +2948,76 @@
 	int err;
 	int i;
 	int where = 1;
+	int sz;
+	u8 *mem;
+	MPT_ADAPTER *ioc = NULL;
+	int iocnum;
 
 	show_mptmod_ver(my_NAME, my_VERSION);
 
 	for (i=0; i<MPT_MAX_ADAPTERS; i++) {
 		sema_init(&mptctl_syscall_sem_ioc[i], 1);
+
+		ioc = NULL;
+		if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
+		    (ioc == NULL)) {
+			continue;
+		}
+		else {
+			/* This adapter instance is found.
+			 * Allocate and inite a MPT_IOCTL structure
+			 */
+			sz = sizeof (MPT_IOCTL);
+			mem = kmalloc(sz, GFP_KERNEL);
+			if (mem == NULL) {
+				err = -ENOMEM;
+				goto out_fail;
+			}
+
+			memset(mem, 0, sz);
+			ioc->ioctl = (MPT_IOCTL *) mem;
+			ioc->ioctl->ioc = ioc;
+			init_timer (&ioc->ioctl->timer);
+			ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
+			ioc->ioctl->timer.function = mptctl_timer_expired;
+		}
 	}
 
 #if defined(__sparc__) && defined(__sparc_v9__)		/*{*/
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)		/*{*/
-	err = register_ioctl32_conversion(MPTRWPERF, NULL);
+	err = register_ioctl32_conversion(MPTIOCINFO, NULL);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(MPTTARGETINFO, NULL);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(MPTTEST, NULL);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(MPTEVENTQUERY, NULL);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(MPTEVENTENABLE, NULL);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(MPTEVENTREPORT, NULL);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(MPTHARDRESET, NULL);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(MPTCOMMAND32, sparc32_mpt_command);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
+					  sparc32_mptfwxfer_ioctl);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(CPQFCTS_GETPCIINFO, NULL);
+	if (++where && err) goto out_fail;
+	err = register_ioctl32_conversion(CPQFCTS_CTLR_STATUS, NULL);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTRWPERF_CHK, NULL);
+	err = register_ioctl32_conversion(CPQFCTS_GETDRIVER, NULL);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTRWPERF_RESET, NULL);
+	err = register_ioctl32_conversion(CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS, NULL);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTFWDOWNLOAD32, sparc32_mptfwxfer_ioctl);
+	err = register_ioctl32_conversion(CPQFCTS_SCSI_PASSTHRU32, sparc32_mptctl_cpq_passthru);
 	if (++where && err) goto out_fail;
 #endif		/*} linux >= 2.3.x */
 #endif		/*} sparc */
 
+	/* Register this device */
 	if (misc_register(&mptctl_miscdev) == -1) {
 		printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
 		err = -EBUSY;
@@ -1226,13 +3031,19 @@
 	 *  Install our handler
 	 */
 	++where;
-	if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) <= 0) {
+	if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) {
 		printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
 		misc_deregister(&mptctl_miscdev);
 		err = -EBUSY;
 		goto out_fail;
 	}
 
+	if (mpt_reset_register(mptctl_id, mptctl_ioc_reset) == 0) {
+		dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+	} else {
+		/* FIXME! */
+	}
+
 	return 0;
 
 out_fail:
@@ -1241,35 +3052,72 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)		/*{*/
 	printk(KERN_ERR MYNAM ": ERROR: Failed to register ioctl32_conversion!"
 			" (%d:err=%d)\n", where, err);
-	unregister_ioctl32_conversion(MPTRWPERF);
-	unregister_ioctl32_conversion(MPTRWPERF_CHK);
-	unregister_ioctl32_conversion(MPTRWPERF_RESET);
+	unregister_ioctl32_conversion(MPTIOCINFO);
+	unregister_ioctl32_conversion(MPTTARGETINFO);
+	unregister_ioctl32_conversion(MPTTEST);
+	unregister_ioctl32_conversion(MPTEVENTQUERY);
+	unregister_ioctl32_conversion(MPTEVENTENABLE);
+	unregister_ioctl32_conversion(MPTEVENTREPORT);
+	unregister_ioctl32_conversion(MPTHARDRESET);
+	unregister_ioctl32_conversion(MPTCOMMAND32);
 	unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
+	unregister_ioctl32_conversion(CPQFCTS_GETPCIINFO);
+	unregister_ioctl32_conversion(CPQFCTS_GETDRIVER);
+	unregister_ioctl32_conversion(CPQFCTS_CTLR_STATUS);
+	unregister_ioctl32_conversion(CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS);
+	unregister_ioctl32_conversion(CPQFCTS_SCSI_PASSTHRU32);
 #endif		/*} linux >= 2.3.x */
 #endif		/*} sparc */
 
+	for (i=0; i<MPT_MAX_ADAPTERS; i++) {
+		ioc = NULL;
+		if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
+		    (ioc == NULL)) {
+			continue;
+		}
+		else {
+			if (ioc->ioctl) {
+				kfree ( ioc->ioctl );
+				ioc->ioctl = NULL;
+			}
+		}
+	}
 	return err;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 void mptctl_exit(void)
 {
-
-#if defined(__sparc__) && defined(__sparc_v9__)		/*{*/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)		/*{*/
-	unregister_ioctl32_conversion(MPTRWPERF);
-	unregister_ioctl32_conversion(MPTRWPERF_CHK);
-	unregister_ioctl32_conversion(MPTRWPERF_RESET);
-	unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
-#endif		/*} linux >= 2.3.x */
-#endif		/*} sparc */
+	int i;
+	MPT_ADAPTER *ioc;
+	int iocnum;
 
 	misc_deregister(&mptctl_miscdev);
-	printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
+	printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
 			 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
-	printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n");
 
+	/* De-register reset handler from base module */
+	mpt_reset_deregister(mptctl_id);
+	dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
+
+	/* De-register callback handler from base module */
 	mpt_deregister(mptctl_id);
+	printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n");
+
+	/* Free allocated memory */
+	for (i=0; i<MPT_MAX_ADAPTERS; i++) {
+		ioc = NULL;
+		if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
+		    (ioc == NULL)) {
+			continue;
+		}
+		else {
+			if (ioc->ioctl) {
+				kfree ( ioc->ioctl );
+				ioc->ioctl = NULL;
+			}
+		}
+	}
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/mptctl.h linux/drivers/message/fusion/mptctl.h
--- linux.orig/drivers/message/fusion/mptctl.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/message/fusion/mptctl.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,395 @@
+/*
+ *  linux/drivers/message/fusion/mptioctl.h
+ *      Fusion MPT misc device (ioctl) driver.
+ *      For use with PCI chip/adapter(s):
+ *          LSIFC9xx/LSI409xx Fibre Channel
+ *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
+ *
+ *  Credits:
+ *      This driver would not exist if not for Alan Cox's development
+ *      of the linux i2o driver.
+ *
+ *      A huge debt of gratitude is owed to David S. Miller (DaveM)
+ *      for fixing much of the stupid and broken stuff in the early
+ *      driver while porting to sparc64 platform.  THANK YOU!
+ *
+ *      (see also mptbase.c)
+ *
+ *  Copyright (c) 1999-2002 LSI Logic Corporation
+ *  Originally By: Steven J. Ralston
+ *  (mailto:sjralston1@netscape.net)
+ *  (mailto:Pam.Delaney@lsil.com)
+ *
+ *  $Id: mptctl.h,v 1.9 2002/02/27 18:44:26 sralston Exp $
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+    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 of the License.
+
+    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.
+
+    NO WARRANTY
+    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+    solely responsible for determining the appropriateness of using and
+    distributing the Program and assumes all risks associated with its
+    exercise of rights under this Agreement, including but not limited to
+    the risks and costs of program errors, damage to or loss of data,
+    programs or equipment, and unavailability or interruption of operations.
+
+    DISCLAIMER OF LIABILITY
+    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+    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
+*/
+
+#ifndef MPTCTL_H_INCLUDED
+#define MPTCTL_H_INCLUDED
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+#include "linux/version.h"
+
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *
+ */
+#define MPT_MISCDEV_BASENAME            "mptctl"
+#define MPT_MISCDEV_PATHNAME            "/dev/" MPT_MISCDEV_BASENAME
+
+#define MPT_PRODUCT_LENGTH              12
+
+/*
+ *  Generic MPT Control IOCTLs and structures
+ */
+#define MPT_MAGIC_NUMBER	'm'
+
+#define MPTRWPERF		_IOWR(MPT_MAGIC_NUMBER,0,struct mpt_raw_r_w)
+
+#define MPTFWDOWNLOAD		_IOWR(MPT_MAGIC_NUMBER,15,struct mpt_fw_xfer)
+#define MPTCOMMAND		_IOWR(MPT_MAGIC_NUMBER,20,struct mpt_ioctl_command)
+
+#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+#define MPTFWDOWNLOAD32		_IOWR(MPT_MAGIC_NUMBER,15,struct mpt_fw_xfer32)
+#define MPTCOMMAND32		_IOWR(MPT_MAGIC_NUMBER,20,struct mpt_ioctl_command32)
+#endif	/*}*/
+
+#define MPTIOCINFO		_IOWR(MPT_MAGIC_NUMBER,17,struct mpt_ioctl_iocinfo)
+#define MPTTARGETINFO		_IOWR(MPT_MAGIC_NUMBER,18,struct mpt_ioctl_targetinfo)
+#define MPTTEST			_IOWR(MPT_MAGIC_NUMBER,19,struct mpt_ioctl_test)
+#define MPTEVENTQUERY		_IOWR(MPT_MAGIC_NUMBER,21,struct mpt_ioctl_eventquery)
+#define MPTEVENTENABLE		_IOWR(MPT_MAGIC_NUMBER,22,struct mpt_ioctl_eventenable)
+#define MPTEVENTREPORT		_IOWR(MPT_MAGIC_NUMBER,23,struct mpt_ioctl_eventreport)
+#define MPTHARDRESET		_IOWR(MPT_MAGIC_NUMBER,24,struct mpt_ioctl_diag_reset)
+#define MPTFWREPLACE		_IOWR(MPT_MAGIC_NUMBER,25,struct mpt_ioctl_replace_fw)
+
+/*
+ * SPARC PLATFORM REMARK:
+ * IOCTL data structures that contain pointers
+ * will have different sizes in the driver and applications
+ * (as the app. will not use 8-byte pointers).
+ * Apps should use MPTFWDOWNLOAD and MPTCOMMAND.
+ * The driver will convert data from
+ * mpt_fw_xfer32 (mpt_ioctl_command32) to mpt_fw_xfer (mpt_ioctl_command)
+ * internally.
+ */
+struct mpt_fw_xfer {
+	unsigned int	 iocnum;	/* IOC unit number */
+	unsigned int	 fwlen;
+	void		*bufp;		/* Pointer to firmware buffer */
+};
+
+#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+struct mpt_fw_xfer32 {
+	unsigned int iocnum;
+	unsigned int fwlen;
+	u32 bufp;
+};
+#endif	/*}*/
+
+
+/*
+ *  IOCTL header structure.
+ *  iocnum - must be defined.
+ *  port - must be defined for all IOCTL commands other than MPTIOCINFO
+ *  maxDataSize - ignored on MPTCOMMAND commands
+ *		- ignored on MPTFWREPLACE commands
+ *		- on query commands, reports the maximum number of bytes to be returned
+ *		  to the host driver (count includes the header).
+ *		  That is, set to sizeof(struct mpt_ioctl_iocinfo) for fixed sized commands.
+ *		  Set to sizeof(struct mpt_ioctl_targetinfo) + datasize for variable
+ *			sized commands. (MPTTARGETINFO, MPTEVENTREPORT)
+ */
+typedef struct _mpt_ioctl_header {
+	unsigned int	 iocnum;	/* IOC unit number */
+	unsigned int	 port;		/* IOC port number */
+	int		 maxDataSize;	/* Maximum Num. bytes to transfer on read */
+} mpt_ioctl_header;
+
+/*
+ * Issue a diagnostic reset
+ */
+struct mpt_ioctl_diag_reset {
+	mpt_ioctl_header hdr;
+};
+
+
+/*
+ *  Adapter Information Page
+ *  Read only.
+ *  Data starts at offset 0xC
+ */
+#define MPT_IOCTL_INTERFACE_FC		(0x01)
+#define MPT_IOCTL_INTERFACE_SCSI	(0x00)
+#define MPT_IOCTL_VERSION_LENGTH	(32)
+
+struct mpt_ioctl_iocinfo {
+	mpt_ioctl_header hdr;
+	int		 adapterType;	/* SCSI or FCP */
+	int		 port;		/* port number */
+	int		 pciId;		/* PCI Id. */
+	int		 hwRev;		/* hardware revision */
+	int		 subSystemDevice;	/* PCI subsystem Device ID */
+	int		 subSystemVendor;	/* PCI subsystem Vendor ID */
+	int		 numDevices;		/* number of devices */
+	int		 FWVersion;		/* FW Version (integer) */
+	int		 BIOSVersion;		/* BIOS Version (integer) */
+	char		 driverVersion[MPT_IOCTL_VERSION_LENGTH];	/* Driver Version (string) */
+	char		 busChangeEvent;
+	char		 hostId;
+	char		 rsvd[2];
+};
+
+/*
+ * Device Information Page
+ * Report the number of, and ids of, all targets
+ * on this IOC.  The ids array is a packed structure
+ * of the known targetInfo.
+ * bits 31-24: reserved
+ *      23-16: LUN
+ *      15- 8: Bus Number
+ *       7- 0: Target ID
+ */
+struct mpt_ioctl_targetinfo {
+	mpt_ioctl_header hdr;
+	int		 numDevices;	/* Num targets on this ioc */
+	int		 targetInfo[1];
+};
+
+
+/*
+ * Event reporting IOCTL's.  These IOCTL's will
+ * use the following defines:
+ */
+struct mpt_ioctl_eventquery {
+	mpt_ioctl_header hdr;
+	unsigned short	 eventEntries;
+	unsigned short	 reserved;
+	unsigned int	 eventTypes;
+};
+
+struct mpt_ioctl_eventenable {
+	mpt_ioctl_header hdr;
+	unsigned int	 eventTypes;
+};
+
+#ifndef __KERNEL__
+typedef struct {
+	uint	event;
+	uint	eventContext;
+	uint	data[2];
+} MPT_IOCTL_EVENTS;
+#endif
+
+struct mpt_ioctl_eventreport {
+	mpt_ioctl_header	hdr;
+	MPT_IOCTL_EVENTS	eventData[1];
+};
+
+#define MPT_MAX_NAME	32
+struct mpt_ioctl_test {
+	mpt_ioctl_header hdr;
+	u8		 name[MPT_MAX_NAME];
+	int		 chip_type;
+	u8		 product [MPT_PRODUCT_LENGTH];
+};
+
+/* Replace the FW image cached in host driver memory
+ * newImageSize - image size in bytes
+ * newImage - first byte of the new image
+ */
+typedef struct mpt_ioctl_replace_fw {
+	mpt_ioctl_header hdr;
+	int		 newImageSize;
+	u8		 newImage[1];
+} mpt_ioctl_replace_fw_t;
+
+/* General MPT Pass through data strucutre
+ *
+ * iocnum
+ * timeout - in seconds, command timeout. If 0, set by driver to
+ *		default value.
+ * replyFrameBufPtr - reply location
+ * dataInBufPtr - destination for read
+ * dataOutBufPtr - data source for write
+ * senseDataPtr - sense data location
+ * maxReplyBytes - maximum number of reply bytes to be sent to app.
+ * dataInSize - num bytes for data transfer in (read)
+ * dataOutSize - num bytes for data transfer out (write)
+ * dataSgeOffset - offset in words from the start of the request message
+ *		to the first SGL
+ * MF[1];
+ *
+ * Remark:  Some config pages have bi-directional transfer,
+ * both a read and a write. The basic structure allows for
+ * a bidirectional set up. Normal messages will have one or
+ * both of these buffers NULL.
+ */
+struct mpt_ioctl_command {
+	mpt_ioctl_header hdr;
+	int		timeout;	/* optional (seconds) */
+	char		*replyFrameBufPtr;
+	char		*dataInBufPtr;
+	char		*dataOutBufPtr;
+	char		*senseDataPtr;
+	int		maxReplyBytes;
+	int		dataInSize;
+	int		dataOutSize;
+	int		maxSenseBytes;
+	int		dataSgeOffset;
+	char		MF[1];
+};
+
+/*
+ * SPARC PLATFORM: See earlier remark.
+ */
+#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+struct mpt_ioctl_command32 {
+	mpt_ioctl_header hdr;
+	int	timeout;
+	u32	replyFrameBufPtr;
+	u32	dataInBufPtr;
+	u32	dataOutBufPtr;
+	u32	senseDataPtr;
+	int	maxReplyBytes;
+	int	dataInSize;
+	int	dataOutSize;
+	int	maxSenseBytes;
+	int	dataSgeOffset;
+	char	MF[1];
+};
+#endif	/*}*/
+
+
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+ /*
+  *	COMPAQ Specific IOCTL Defines and Structures
+  */
+
+#define CPQFCTS_IOC_MAGIC 'Z'
+
+#define CPQFCTS_GETPCIINFO		_IOR(CPQFCTS_IOC_MAGIC, 1, cpqfc_pci_info_struct)
+#define CPQFCTS_GETDRIVER		_IOR(CPQFCTS_IOC_MAGIC, 2, int)
+#define CPQFCTS_CTLR_STATUS		_IOR(CPQFCTS_IOC_MAGIC, 3, struct _cpqfc_ctlr_status)
+#define CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS	_IOR(CPQFCTS_IOC_MAGIC, 4, struct scsi_fctargaddress)
+#define CPQFCTS_SCSI_PASSTHRU		_IOWR(CPQFCTS_IOC_MAGIC, 5, VENDOR_IOCTL_REQ)
+#if defined(__sparc__) && defined(__sparc_v9__)
+#define CPQFCTS_SCSI_PASSTHRU32		_IOWR(CPQFCTS_IOC_MAGIC, 5, VENDOR_IOCTL_REQ32)
+#endif
+
+typedef struct {
+	unsigned short bus;
+	unsigned short bus_type;
+	unsigned short device_fn;
+	u32 board_id;
+	u32 slot_number;
+	unsigned short vendor_id;
+	unsigned short device_id;
+	unsigned short class_code;
+	unsigned short sub_vendor_id;
+	unsigned short sub_device_id;
+	u8 serial_number[81];
+} cpqfc_pci_info_struct;
+
+
+typedef struct scsi_fctargaddress {
+	unsigned int host_port_id;
+	u8 host_wwn[8];	/* WW Network Name */
+} Scsi_FCTargAddress;
+
+typedef struct _cpqfc_ctlr_status {
+	u32 status;
+	u32 offline_reason;
+} cpqfc_ctlr_status;
+
+
+/* Compaq SCSI I/O Passthru structures.
+ */
+#define MPT_COMPAQ_READ		0x26
+#define MPT_COMPAQ_WRITE	0x27
+
+typedef struct {
+	int lc;		/* controller number */
+	int node;	/* node number */
+	int ld;		/* target logical id */
+	u32 nexus;
+	void *argp;
+} VENDOR_IOCTL_REQ;
+
+#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+typedef struct {
+	int lc;		/* controller number */
+	int node;	/* node number */
+	int ld;		/* target logical id */
+	u32 nexus;
+	u32 argp;
+} VENDOR_IOCTL_REQ32;
+#endif
+
+typedef struct {
+	char cdb[16];		/* cdb */
+	unsigned short bus;	/* bus number */
+	unsigned short pdrive;	/* physical drive */
+	int len;		/* data area size */
+	int sense_len;		/* sense size */
+	char sense_data[40];	/* sense buffer */
+	void *bufp;		/* data buffer pointer */
+	char rw_flag;
+} cpqfc_passthru_t;
+
+#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+typedef struct {
+	char cdb[16];		/* cdb */
+	unsigned short bus;	/* bus number */
+	unsigned short pdrive;	/* physical drive */
+	int len;		/* data area size */
+	int sense_len;		/* sense size */
+	char sense_data[40];	/* sense buffer */
+	u32 bufp;		/* data buffer pointer */
+	char rw_flag;
+} cpqfc_passthru32_t;
+#endif
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/mptlan.c linux/drivers/message/fusion/mptlan.c
--- linux.orig/drivers/message/fusion/mptlan.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/message/fusion/mptlan.c	2002-07-20 01:08:37.000000000 +0000
@@ -23,10 +23,10 @@
  *
  *      (see also mptbase.c)
  *
- *  Copyright (c) 2000-2001 LSI Logic Corporation
+ *  Copyright (c) 2000-2002 LSI Logic Corporation
  *  Originally By: Noah Romer
  *
- *  $Id: mptlan.c,v 1.32.2.2 2001/07/12 19:43:33 nromer Exp $
+ *  $Id: mptlan.c,v 1.51 2002/02/11 14:40:55 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -79,6 +79,8 @@
 
 #define MYNAM		"mptlan"
 
+MODULE_LICENSE("GPL");
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * MPT LAN message sizes without variable part.
@@ -109,8 +111,8 @@
 	MPT_ADAPTER *mpt_dev;
 	u8 pnum; /* Port number in the IOC. This is not a Unix network port! */
 
-	atomic_t buckets_out;	  	/* number of unused buckets on IOC */
-	int bucketthresh;		/* Send more when this many used */
+	atomic_t buckets_out;		/* number of unused buckets on IOC */
+	int bucketthresh;		/* Send more when this many left */
 
 	int *mpt_txfidx; /* Free Tx Context list */
 	int mpt_txfidx_tail;
@@ -123,8 +125,8 @@
 	struct BufferControl *RcvCtl;	/* Receive BufferControl structs */
 	struct BufferControl *SendCtl;	/* Send BufferControl structs */
 
-	int max_buckets_out;	   	/* Max buckets to send to IOC */
-	int tx_max_out;		   	/* IOC's Tx queue len */
+	int max_buckets_out;		/* Max buckets to send to IOC */
+	int tx_max_out;			/* IOC's Tx queue len */
 
 	u32 total_posted;
 	u32 total_received;
@@ -152,7 +154,8 @@
 static int  mpt_lan_reset(struct net_device *dev);
 static int  mpt_lan_close(struct net_device *dev);
 static void mpt_lan_post_receive_buckets(void *dev_id);
-static void mpt_lan_wake_post_buckets_task(struct net_device *dev);
+static void mpt_lan_wake_post_buckets_task(struct net_device *dev, 
+					   int priority);
 static int  mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg);
 static int  mpt_lan_receive_post_reply(struct net_device *dev,
 				       LANReceivePostReply_t *pRecvRep);
@@ -175,8 +178,10 @@
 
 static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1];
 
+#ifdef QLOGIC_NAA_WORKAROUND
 static struct NAA_Hosed *mpt_bad_naa = NULL;
 rwlock_t bad_naa_lock;
+#endif
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -229,7 +234,7 @@
 		case LAN_REPLY_FORM_SEND_SINGLE:
 //			dioprintk((MYNAM "/lan_reply: "
 //				  "calling mpt_lan_send_reply (turbo)\n"));
-  
+
 			// Potential BUG here?  -sralston
 			//	FreeReqFrame = mpt_lan_send_turbo(dev, tmsg);
 			//  If/when mpt_lan_send_turbo would return 1 here,
@@ -333,7 +338,7 @@
 	struct net_device *dev = mpt_landev[ioc->id];
 	struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
 
-	dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
+	dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
 			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
 
 	if (priv->mpt_rxfidx == NULL)
@@ -342,9 +347,11 @@
 	if (reset_phase == MPT_IOC_PRE_RESET) {
 		int i;
 		unsigned long flags;
-		
+
 		netif_stop_queue(dev);
 
+		dlprintk ((KERN_INFO "mptlan/ioc_reset: called netif_stop_queue for %s.\n", dev->name));
+
 		atomic_set(&priv->buckets_out, 0);
 
 		/* Reset Rx Free Tail index and re-populate the queue. */
@@ -365,7 +372,7 @@
 static int
 mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 {
-	dprintk((KERN_INFO MYNAM ": MPT event routed to LAN driver!\n"));
+	dlprintk((KERN_INFO MYNAM ": MPT event routed to LAN driver!\n"));
 
 	switch (le32_to_cpu(pEvReply->Event)) {
 	case MPI_EVENT_NONE:				/* 00 */
@@ -403,9 +410,9 @@
 
 	if (mpt_lan_reset(dev) != 0) {
 		MPT_ADAPTER *mpt_dev = priv->mpt_dev;
-		
+
 		printk (KERN_WARNING MYNAM "/lan_open: lan_reset failed.");
-		
+
 		if (mpt_dev->active)
 			printk ("The ioc is active. Perhaps it needs to be"
 				" reset?\n");
@@ -429,7 +436,7 @@
 		priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i;
 	}
 
-	dprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
+	dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
 
 	priv->mpt_rxfidx = kmalloc(priv->max_buckets_out * sizeof(int),
 				   GFP_KERNEL);
@@ -447,12 +454,12 @@
 		priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
 	}
 
-/**/	dprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));
+/**/	dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));
 /**/	for (i = 0; i < priv->tx_max_out; i++)
-/**/		dprintk((" %xh", priv->mpt_txfidx[i]));
-/**/	dprintk(("\n"));
+/**/		dlprintk((" %xh", priv->mpt_txfidx[i]));
+/**/	dlprintk(("\n"));
 
-	dprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n"));
+	dlprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n"));
 
 	mpt_lan_post_receive_buckets(dev);
 	printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n",
@@ -466,7 +473,7 @@
 	}
 
 	netif_start_queue(dev);
-	dprintk((KERN_INFO MYNAM "/lo: Done.\n"));
+	dlprintk((KERN_INFO MYNAM "/lo: Done.\n"));
 
 	return 0;
 out_mpt_rxfidx:
@@ -494,7 +501,7 @@
 	mf = mpt_get_msg_frame(LanCtx, priv->mpt_dev->id);
 
 	if (mf == NULL) {
-/*		dprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! "
+/*		dlprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! "
 		"Unable to allocate a request frame.\n"));
 */
 		return -1;
@@ -523,11 +530,11 @@
 	unsigned int timeout;
 	int i;
 
-	dprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
+	dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
 
 	mpt_event_deregister(LanCtx);
 
-	dprintk((KERN_INFO MYNAM ":lan_close: Posted %d buckets "
+	dlprintk((KERN_INFO MYNAM ":lan_close: Posted %d buckets "
 		  "since driver was loaded, %d still out\n",
 		  priv->total_posted,atomic_read(&priv->buckets_out)));
 
@@ -537,18 +544,18 @@
 
 	timeout = 2 * HZ;
 	while (atomic_read(&priv->buckets_out) && --timeout) {
-		current->state = TASK_INTERRUPTIBLE;
+		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
 	}
 
 	for (i = 0; i < priv->max_buckets_out; i++) {
 		if (priv->RcvCtl[i].skb != NULL) {
-/**/			dprintk((KERN_INFO MYNAM "/lan_close: bucket %05x "
+/**/			dlprintk((KERN_INFO MYNAM "/lan_close: bucket %05x "
 /**/				  "is still out\n", i));
 			pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[i].dma,
-				 	 priv->RcvCtl[i].len,
+					 priv->RcvCtl[i].len,
 					 PCI_DMA_FROMDEVICE);
- 			dev_kfree_skb(priv->RcvCtl[i].skb);
+			dev_kfree_skb(priv->RcvCtl[i].skb);
 		}
 	}
 
@@ -556,11 +563,11 @@
 	kfree (priv->mpt_rxfidx);
 
 	for (i = 0; i < priv->tx_max_out; i++) {
- 		if (priv->SendCtl[i].skb != NULL) {
+		if (priv->SendCtl[i].skb != NULL) {
 			pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[i].dma,
 					 priv->SendCtl[i].len,
 					 PCI_DMA_TODEVICE);
- 			dev_kfree_skb(priv->SendCtl[i].skb);
+			dev_kfree_skb(priv->SendCtl[i].skb);
 		}
 	}
 
@@ -599,7 +606,13 @@
 static void
 mpt_lan_tx_timeout(struct net_device *dev)
 {
-	netif_wake_queue(dev);  
+	struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
+	MPT_ADAPTER *mpt_dev = priv->mpt_dev;
+
+	if (mpt_dev->active) {
+		dlprintk (("mptlan/tx_timeout: calling netif_wake_queue for %s.\n", dev->name));
+		netif_wake_queue(dev);
+	}
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -722,7 +735,6 @@
 	dma_addr_t dma;
 	unsigned long flags;
 	int ctx;
-	struct NAA_Hosed *nh;
 	u16 cur_naa = 0x1000;
 
 	dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n",
@@ -741,7 +753,6 @@
 	mf = mpt_get_msg_frame(LanCtx, mpt_dev->id);
 	if (mf == NULL) {
 		netif_stop_queue(dev);
-		dev_kfree_skb(skb);
 		spin_unlock_irqrestore(&priv->txfidx_lock, flags);
 
 		printk (KERN_ERR "%s: Unable to alloc request frame\n",
@@ -791,6 +802,10 @@
 //			IOC_AND_NETDEV_NAMES_s_s(dev),
 //			ctx, skb, skb->data));
 
+#ifdef QLOGIC_NAA_WORKAROUND
+{
+	struct NAA_Hosed *nh;
+
 	/* Munge the NAA for Tx packets to QLogic boards, which don't follow
 	   RFC 2625. The longer I look at this, the more my opinion of Qlogic
 	   drops. */
@@ -803,12 +818,14 @@
 		    (nh->ieee[4] == skb->mac.raw[4]) &&
 		    (nh->ieee[5] == skb->mac.raw[5])) {
 			cur_naa = nh->NAA;
-			dprintk ((KERN_INFO "mptlan/sdu_send: using NAA value "
+			dlprintk ((KERN_INFO "mptlan/sdu_send: using NAA value "
 				  "= %04x.\n", cur_naa));
 			break;
 		}
 	}
 	read_unlock_irq(&bad_naa_lock);
+}
+#endif
 
 	pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa         << 16) |
 						    (skb->mac.raw[0] <<  8) |
@@ -821,10 +838,10 @@
 	pSimple = (SGESimple64_t *) &pTrans->TransactionDetails[2];
 
 	/* If we ever decide to send more than one Simple SGE per LANSend, then
-	   we will need to make sure that LAST_ELEMENT only gets set on the 
+	   we will need to make sure that LAST_ELEMENT only gets set on the
 	   last one. Otherwise, bad voodoo and evil funkiness will commence. */
 	pSimple->FlagsLength = cpu_to_le32(
-			((MPI_SGE_FLAGS_LAST_ELEMENT | 
+			((MPI_SGE_FLAGS_LAST_ELEMENT |
 			  MPI_SGE_FLAGS_END_OF_BUFFER |
 			  MPI_SGE_FLAGS_SIMPLE_ELEMENT |
 			  MPI_SGE_FLAGS_SYSTEM_ADDRESS |
@@ -842,23 +859,32 @@
 	dev->trans_start = jiffies;
 
 	dioprintk((KERN_INFO MYNAM ": %s/%s: Sending packet. FlagsLength = %08x.\n",
-		 	IOC_AND_NETDEV_NAMES_s_s(dev),
-		       	le32_to_cpu(pSimple->FlagsLength)));
+			IOC_AND_NETDEV_NAMES_s_s(dev),
+			le32_to_cpu(pSimple->FlagsLength)));
 
 	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static inline void
-mpt_lan_wake_post_buckets_task(struct net_device *dev)
+mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority)
+/* 
+ * @priority: 0 = put it on the timer queue, 1 = put it on the immediate queue
+ */
 {
 	struct mpt_lan_priv *priv = dev->priv;
-
+	
 	if (test_and_set_bit(0, &priv->post_buckets_active) == 0) {
-		queue_task(&priv->post_buckets_task, &tq_immediate);
-		mark_bh(IMMEDIATE_BH);
-		dioprintk((KERN_INFO MYNAM ": %s/%s: Queued post_buckets task.\n",
-				IOC_AND_NETDEV_NAMES_s_s(dev) ));
+		if (priority) {
+			queue_task(&priv->post_buckets_task, &tq_immediate);
+			mark_bh(IMMEDIATE_BH);
+		} else {
+			queue_task(&priv->post_buckets_task, &tq_timer);
+			dioprintk((KERN_INFO MYNAM ": post_buckets queued on "
+				   "timer.\n"));
+		}
+	        dioprintk((KERN_INFO MYNAM ": %s/%s: Queued post_buckets task.\n",
+			   IOC_AND_NETDEV_NAMES_s_s(dev) ));
 	}
 }
 
@@ -870,7 +896,7 @@
 
 	skb->protocol = mpt_lan_type_trans(skb, dev);
 
-	dioprintk((KERN_INFO MYNAM ": %s/%s: Incoming packet (%d bytes) " 
+	dioprintk((KERN_INFO MYNAM ": %s/%s: Incoming packet (%d bytes) "
 		 "delivered to upper level.\n",
 			IOC_AND_NETDEV_NAMES_s_s(dev), skb->len));
 
@@ -884,7 +910,7 @@
 		 atomic_read(&priv->buckets_out)));
 
 	if (atomic_read(&priv->buckets_out) < priv->bucketthresh)
-		mpt_lan_wake_post_buckets_task(dev);
+		mpt_lan_wake_post_buckets_task(dev, 1);
 
 	dioprintk((KERN_INFO MYNAM "/receive_post_reply: %d buckets "
 		  "remaining, %d received back since sod\n",
@@ -956,12 +982,12 @@
 	unsigned long flags;
 	struct sk_buff *skb;
 	u32 ctx;
-	u8 count;
+	int count;
 	int i;
 
 	count = pRecvRep->NumberOfContexts;
 
-/**/	dprintk((KERN_INFO MYNAM "/receive_post_reply: "
+/**/	dlprintk((KERN_INFO MYNAM "/receive_post_reply: "
 		  "IOC returned %d buckets, freeing them...\n", count));
 
 	spin_lock_irqsave(&priv->rxfidx_lock, flags);
@@ -970,11 +996,11 @@
 
 		skb = priv->RcvCtl[ctx].skb;
 
-//		dprintk((KERN_INFO MYNAM ": %s: dev_name = %s\n",
+//		dlprintk((KERN_INFO MYNAM ": %s: dev_name = %s\n",
 //				IOC_AND_NETDEV_NAMES_s_s(dev)));
-//		dprintk((KERN_INFO MYNAM "@rpr[2], priv = %p, buckets_out addr = %p",
-//			  	priv, &(priv->buckets_out)));
-//		dprintk((KERN_INFO MYNAM "@rpr[2] TC + 3\n"));
+//		dlprintk((KERN_INFO MYNAM "@rpr[2], priv = %p, buckets_out addr = %p",
+//				priv, &(priv->buckets_out)));
+//		dlprintk((KERN_INFO MYNAM "@rpr[2] TC + 3\n"));
 
 		priv->RcvCtl[ctx].skb = NULL;
 		pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
@@ -989,13 +1015,13 @@
 
 //	for (i = 0; i < priv->max_buckets_out; i++)
 //		if (priv->RcvCtl[i].skb != NULL)
-//			dprintk((KERN_INFO MYNAM "@rpr: bucket %03x "
+//			dlprintk((KERN_INFO MYNAM "@rpr: bucket %03x "
 //				  "is still out\n", i));
 
-/*	dprintk((KERN_INFO MYNAM "/receive_post_reply: freed %d buckets\n",
+/*	dlprintk((KERN_INFO MYNAM "/receive_post_reply: freed %d buckets\n",
 		  count));
 */
-/**/	dprintk((KERN_INFO MYNAM "@receive_post_reply: %d buckets "
+/**/	dlprintk((KERN_INFO MYNAM "@receive_post_reply: %d buckets "
 /**/		  "remaining, %d received back since sod.\n",
 /**/		  atomic_read(&priv->buckets_out), priv->total_received));
 	return 0;
@@ -1010,9 +1036,9 @@
 	MPT_ADAPTER *mpt_dev = priv->mpt_dev;
 	struct sk_buff *skb, *old_skb;
 	unsigned long flags;
-	u32 len, ctx;
-	u32 offset;
-	u8 count;
+	u32 len, ctx, offset;
+	u32 remaining = le32_to_cpu(pRecvRep->BucketsRemaining);
+	int count;
 	int i, l;
 
 	dioprintk((KERN_INFO MYNAM ": mpt_lan_receive_post_reply called\n"));
@@ -1059,7 +1085,7 @@
 		if (!skb) {
 			printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n",
 					IOC_AND_NETDEV_NAMES_s_s(dev),
-			       		__FILE__, __LINE__);
+					__FILE__, __LINE__);
 			return -ENOMEM;
 		}
 
@@ -1096,7 +1122,7 @@
 		if (!skb) {
 			printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n",
 					IOC_AND_NETDEV_NAMES_s_s(dev),
-			       		__FILE__, __LINE__);
+					__FILE__, __LINE__);
 			return -ENOMEM;
 		}
 
@@ -1140,25 +1166,32 @@
 				"Arrgghh! We've done it again!\n");
 	}
 
-#if 0
-	{
-		u32 remaining = le32_to_cpu(pRecvRep->BucketsRemaining);
-		if (remaining < priv->bucketthresh)
-			mpt_lan_wake_post_buckets_task(dev);
-
-		if (remaining == 0)
-			printk (KERN_WARNING MYNAM ": %s/%s: WARNING - IOC out of buckets! "
-				"(priv->buckets_out = %d)\n",
-					IOC_AND_NETDEV_NAMES_s_s(dev),
-					atomic_read(&priv->buckets_out));
-		else
-			printk (KERN_INFO MYNAM ": %s/%s: IOC says %d buckets left. "
-				"(priv->buckets_out = %d)\n",
-					IOC_AND_NETDEV_NAMES_s_s(dev),
-					remaining, atomic_read(&priv->buckets_out));
+	if (remaining == 0)
+		printk (KERN_WARNING MYNAM ": %s/%s: WARNING - IOC out of buckets! "
+			"(priv->buckets_out = %d)\n",
+			IOC_AND_NETDEV_NAMES_s_s(dev),
+			atomic_read(&priv->buckets_out));
+	else if (remaining < 10)
+		printk (KERN_INFO MYNAM ": %s/%s: IOC says %d buckets left. "
+			"(priv->buckets_out = %d)\n",
+			IOC_AND_NETDEV_NAMES_s_s(dev),
+			remaining, atomic_read(&priv->buckets_out));
+	
+	if ((remaining < priv->bucketthresh) &&
+	    ((atomic_read(&priv->buckets_out) - remaining) > 
+	     MPT_LAN_BUCKETS_REMAIN_MISMATCH_THRESH)) {
+		
+		printk (KERN_WARNING MYNAM " Mismatch between driver's "
+			"buckets_out count and fw's BucketsRemaining "
+			"count has crossed the threshold, issuing a "
+			"LanReset to clear the fw's hashtable. You may "
+			"want to check your /var/log/messages for \"CRC "
+			"error\" event notifications.\n");
+		
+		mpt_lan_reset(dev);
+		mpt_lan_wake_post_buckets_task(dev, 0);
 	}
-#endif
-
+	
 	return mpt_lan_receive_skb(dev, skb);
 }
 
@@ -1242,15 +1275,15 @@
 			if (skb == NULL) {
 				skb = dev_alloc_skb(len);
 				if (skb == NULL) {
-/**/					printk (KERN_WARNING
-/**/						MYNAM "/%s: Can't alloc skb\n",
-/**/						__FUNCTION__);
+					printk (KERN_WARNING
+						MYNAM "/%s: Can't alloc skb\n",
+						__FUNCTION__);
 					priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
 					spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
 					break;
 				}
 
-		    		dma = pci_map_single(mpt_dev->pcidev, skb->data,
+				dma = pci_map_single(mpt_dev->pcidev, skb->data,
 						     len, PCI_DMA_FROMDEVICE);
 
 				priv->RcvCtl[ctx].skb = skb;
@@ -1308,7 +1341,7 @@
 	dioprintk((KERN_INFO MYNAM "/%s: End_buckets = %u, priv->buckets_out = %u\n",
 		  __FUNCTION__, buckets, atomic_read(&priv->buckets_out)));
 	dioprintk((KERN_INFO MYNAM "/%s: Posted %u buckets and received %u back\n",
-	__FUNCTION__, priv->total_posted, priv->total_received)); 
+	__FUNCTION__, priv->total_posted, priv->total_received));
 
 	clear_bit(0, &priv->post_buckets_active);
 }
@@ -1336,7 +1369,7 @@
 	priv->post_buckets_task.data = dev;
 	priv->post_buckets_active = 0;
 
-	dprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
+	dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
 			__LINE__, dev->mtu + dev->hard_header_len + 4));
 
 	atomic_set(&priv->buckets_out, 0);
@@ -1346,7 +1379,7 @@
 	if (mpt_dev->pfacts[0].MaxLanBuckets < max_buckets_out)
 		priv->max_buckets_out = mpt_dev->pfacts[0].MaxLanBuckets;
 
-	dprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n",
+	dlprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n",
 			__LINE__,
 			mpt_dev->pfacts[0].MaxLanBuckets,
 			max_buckets_out,
@@ -1389,7 +1422,7 @@
 	dev->tx_timeout = mpt_lan_tx_timeout;
 	dev->watchdog_timeo = MPT_LAN_TX_TIMEOUT;
 
-	dprintk((KERN_INFO MYNAM ": Finished registering dev "
+	dlprintk((KERN_INFO MYNAM ": Finished registering dev "
 		"and setting initial values\n"));
 
 	SET_MODULE_OWNER(dev);
@@ -1407,9 +1440,11 @@
 
 	show_mptmod_ver(LANAME, LANVER);
 
-	/* Init the global r/w lock for the bad_naa list. We want to do this 
+#ifdef QLOGIC_NAA_WORKAROUND
+	/* Init the global r/w lock for the bad_naa list. We want to do this
 	   before any boards are initialized and may be used. */
 	rwlock_init(&bad_naa_lock);
+#endif
 
 	if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
 		printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
@@ -1419,10 +1454,10 @@
 	/* Set the callback index to be used by driver core for turbo replies */
 	mpt_lan_index = LanCtx;
 
-	dprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
+	dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
 
 	if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) {
-		dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+		dlprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
 	} else {
 		printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
 		       "handler with mptbase! The world is at an end! "
@@ -1458,7 +1493,7 @@
 //							IOC_AND_NETDEV_NAMES_s_s(dev),
 //							NETDEV_TO_LANPRIV_PTR(dev)->tx_max_out);
 					mpt_landev[j] = dev;
-					dprintk((KERN_INFO MYNAM "/init: dev_addr=%p, mpt_landev[%d]=%p\n",
+					dlprintk((KERN_INFO MYNAM "/init: dev_addr=%p, mpt_landev[%d]=%p\n",
 							dev, j,  mpt_landev[j]));
 
 					j++;
@@ -1508,18 +1543,15 @@
 MODULE_PARM(tx_max_out_p, "i");
 MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME!
 
-MODULE_LICENSE("GPL");
-
 module_init(mpt_lan_init);
 module_exit(mpt_lan_exit);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static unsigned short
-mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) 
+mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	struct mpt_lan_ohdr *fch = (struct mpt_lan_ohdr *)skb->data;
 	struct fcllc *fcllc;
-	u16 source_naa = fch->stype, found = 0;
 
 	skb->mac.raw = skb->data;
 	skb_pull(skb, sizeof(struct mpt_lan_ohdr));
@@ -1535,7 +1567,7 @@
 		printk (KERN_WARNING MYNAM ": %s: WARNING - Broadcast swap F/W bug detected!\n",
 				NETDEV_PTR_TO_IOC_NAME_s(dev));
 		printk (KERN_WARNING MYNAM ": Please update sender @ MAC_addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-		       		fch->saddr[0], fch->saddr[1], fch->saddr[2],
+				fch->saddr[0], fch->saddr[1], fch->saddr[2],
 				fch->saddr[3], fch->saddr[4], fch->saddr[5]);
 	}
 
@@ -1555,6 +1587,10 @@
 
 	fcllc = (struct fcllc *)skb->data;
 
+#ifdef QLOGIC_NAA_WORKAROUND
+{
+	u16 source_naa = fch->stype, found = 0;
+
 	/* Workaround for QLogic not following RFC 2625 in regards to the NAA
 	   value. */
 
@@ -1562,15 +1598,15 @@
 		source_naa = swab16(source_naa);
 
 	if (fcllc->ethertype == htons(ETH_P_ARP))
-	    dprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of "
+	    dlprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of "
 		      "%04x.\n", source_naa));
 
-	if ((fcllc->ethertype == htons(ETH_P_ARP)) && 
+	if ((fcllc->ethertype == htons(ETH_P_ARP)) &&
 	   ((source_naa >> 12) !=  MPT_LAN_NAA_RFC2625)){
 		struct NAA_Hosed *nh, *prevnh;
 		int i;
 
-		dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from "
+		dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from "
 			  "system with non-RFC 2625 NAA value (%04x).\n",
 			  source_naa));
 
@@ -1584,17 +1620,17 @@
 			    (nh->ieee[4] == fch->saddr[4]) &&
 			    (nh->ieee[5] == fch->saddr[5])) {
 				found = 1;
-				dprintk ((KERN_INFO "mptlan/type_trans: ARP Re"
+				dlprintk ((KERN_INFO "mptlan/type_trans: ARP Re"
 					 "q/Rep w/ bad NAA from system already"
 					 " in DB.\n"));
 				break;
 			}
 		}
-		
+
 		if ((!found) && (nh == NULL)) {
 
 			nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL);
-			dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/"
+			dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/"
 				 " bad NAA from system not yet in DB.\n"));
 
 			if (nh != NULL) {
@@ -1603,11 +1639,11 @@
 					mpt_bad_naa = nh;
 				if (prevnh)
 					prevnh->next = nh;
-				
+
 				nh->NAA = source_naa; /* Set the S_NAA value. */
 				for (i = 0; i < FC_ALEN; i++)
 					nh->ieee[i] = fch->saddr[i];
-				dprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:"
+				dlprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:"
 					  "%02x:%02x with non-compliant S_NAA value.\n",
 					  fch->saddr[0], fch->saddr[1], fch->saddr[2],
 					  fch->saddr[3], fch->saddr[4],fch->saddr[5]));
@@ -1622,9 +1658,10 @@
 		}
 		write_unlock_irq(&bad_naa_lock);
 	}
-		
+}
+#endif
 
-	/* Strip the SNAP header from ARP packets since we don't 
+	/* Strip the SNAP header from ARP packets since we don't
 	 * pass them through to the 802.2/SNAP layers.
 	 */
 	if (fcllc->dsap == EXTENDED_SAP &&
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/mptlan.h linux/drivers/message/fusion/mptlan.h
--- linux.orig/drivers/message/fusion/mptlan.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/mptlan.h	2002-07-20 01:08:31.000000000 +0000
@@ -21,6 +21,7 @@
 #include <linux/miscdevice.h>
 #include <linux/spinlock.h>
 #include <linux/tqueue.h>
+#include <linux/delay.h>
 // #include <linux/trdevice.h>
 
 #include <asm/uaccess.h>
@@ -43,13 +44,15 @@
 
 #define MPT_LAN_MAX_BUCKETS_OUT 256
 #define MPT_LAN_BUCKET_THRESH	18 /* 9 buckets in one message */
+#define MPT_LAN_BUCKETS_REMAIN_MISMATCH_THRESH 10
 #define MPT_LAN_RX_COPYBREAK	200
-#define MPT_LAN_TX_TIMEOUT 	(1*HZ)
+#define MPT_LAN_TX_TIMEOUT	(1*HZ)
 #define MPT_TX_MAX_OUT_LIM      127
 
 #define MPT_LAN_MIN_MTU		96		/* RFC2625 */
 #define MPT_LAN_MAX_MTU		65280		/* RFC2625 */
-#define MPT_LAN_MTU             16128		/* be nice to slab allocator */
+#define MPT_LAN_MTU             13312		/* Max perf range + lower mem
+						   usage than 16128 */
 
 #define MPT_LAN_NAA_RFC2625     0x1
 #define MPT_LAN_NAA_QLOGIC      0x2
@@ -66,6 +69,12 @@
 #define dioprintk(x)
 #endif
 
+#ifdef MPT_LAN_DEBUG
+#define dlprintk(x)  printk x
+#else
+#define dlprintk(x)
+#endif
+
 #define NETDEV_TO_LANPRIV_PTR(d)	((struct mpt_lan_priv *)(d)->priv)
 #define NETDEV_PTR_TO_IOC_NAME_s(d)	(NETDEV_TO_LANPRIV_PTR(d)->mpt_dev->name)
 #define IOC_AND_NETDEV_NAMES_s_s(d)	NETDEV_PTR_TO_IOC_NAME_s(d), (d)->name
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/mptscsih.c linux/drivers/message/fusion/mptscsih.c
--- linux.orig/drivers/message/fusion/mptscsih.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/message/fusion/mptscsih.c	2002-07-20 01:08:34.000000000 +0000
@@ -9,17 +9,24 @@
  *      This driver would not exist if not for Alan Cox's development
  *      of the linux i2o driver.
  *
+ *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
+ *      and countless enhancements while adding support for the 1030
+ *      chip family.  Pam has been instrumental in the development of
+ *      of the 2.xx.xx series fusion drivers, and her contributions are
+ *      far too numerous to hope to list in one place.
+ *
  *      A huge debt of gratitude is owed to David S. Miller (DaveM)
  *      for fixing much of the stupid and broken stuff in the early
  *      driver while porting to sparc64 platform.  THANK YOU!
  *
  *      (see mptbase.c)
  *
- *  Copyright (c) 1999-2001 LSI Logic Corporation
+ *  Copyright (c) 1999-2002 LSI Logic Corporation
  *  Original author: Steven J. Ralston
- *  (mailto:Steve.Ralston@lsil.com)
+ *  (mailto:sjralston1@netscape.net)
+ *  (mailto:Pam.Delaney@lsil.com)
  *
- *  $Id: mptscsih.c,v 1.29.4.1 2001/09/18 03:22:30 sralston Exp $
+ *  $Id: mptscsih.c,v 1.80 2002/02/27 18:44:27 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -66,6 +73,9 @@
 #include <linux/kdev_t.h>
 #include <linux/blkdev.h>
 #include <linux/blk.h>		/* for io_request_lock (spinlock) decl */
+#include <linux/delay.h>	/* for mdelay */
+#include <linux/interrupt.h>	/* needed for in_interrupt() proto */
+#include <linux/reboot.h>	/* notifier code */
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
 #include "../../scsi/sd.h"
@@ -83,52 +93,131 @@
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
+/* Set string for command line args from insmod */
+#ifdef MODULE
+char *mptscsih = 0;
+MODULE_PARM(mptscsih, "s");
+#endif
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 typedef struct _BIG_SENSE_BUF {
-	u8		data[256];
+	u8		data[MPT_SENSE_BUFFER_ALLOC];
 } BIG_SENSE_BUF;
 
-typedef struct _MPT_SCSI_HOST {
-	MPT_ADAPTER		 *ioc;
-	int			  port;
-	struct scsi_cmnd	**ScsiLookup;
-	u8			 *SgHunks;
-	dma_addr_t		  SgHunksDMA;
-	u32			  qtag_tick;
-} MPT_SCSI_HOST;
-
-typedef struct _MPT_SCSI_DEV {
-	struct _MPT_SCSI_DEV	 *forw;
-	struct _MPT_SCSI_DEV	 *back;
-	MPT_ADAPTER		 *ioc;
-	int			  sense_sz;
-	BIG_SENSE_BUF		  CachedSense;
-	unsigned long		  io_cnt;
-	unsigned long		  read_cnt;
-} MPT_SCSI_DEV;
+#define MPT_SCANDV_GOOD			(0x00000000) /* must be 0 */
+#define MPT_SCANDV_DID_RESET		(0x00000001)
+#define MPT_SCANDV_SENSE		(0x00000002)
+#define MPT_SCANDV_SOME_ERROR		(0x00000004)
+#define MPT_SCANDV_SELECTION_TIMEOUT	(0x00000008)
+
+#define MPT_SCANDV_MAX_RETRIES		(10)
+
+#define MPT_ICFLAG_BUF_CAP	0x01	/* ReadBuffer Read Capacity format */
+#define MPT_ICFLAG_ECHO		0x02	/* ReadBuffer Echo buffer format */
+#define MPT_ICFLAG_PHYS_DISK	0x04	/* Any SCSI IO but do Phys Disk Format */
+#define MPT_ICFLAG_TAGGED_CMD	0x08	/* Do tagged IO */
+#define MPT_ICFLAG_DID_RESET	0x20	/* Bus Reset occured with this command */
+#define MPT_ICFLAG_RESERVED	0x40	/* Reserved has been issued */
+
+typedef struct _internal_cmd {
+	char		*data;		/* data pointer */
+	dma_addr_t	data_dma;	/* data dma address */
+	int		size;		/* transfer size */
+	u8		cmd;		/* SCSI Op Code */
+	u8		bus;		/* bus number */
+	u8		id;		/* SCSI ID (virtual) */
+	u8		lun;
+	u8		flags;		/* Bit Field - See above */
+	u8		physDiskNum;	/* Phys disk number, -1 else */
+	u8		rsvd2;
+	u8		rsvd;
+} INTERNAL_CMD;
+
+typedef struct _negoparms {
+	u8 width;
+	u8 offset;
+	u8 factor;
+	u8 flags;
+} NEGOPARMS;
+
+typedef struct _dv_parameters {
+	NEGOPARMS	 max;
+	NEGOPARMS	 now;
+	u8		 cmd;
+	u8		 id;
+	u16		 pad1;
+} DVPARAMETERS;
+
 
 /*
  *  Other private/forward protos...
  */
-
 static int	mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static void	mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
 static int	mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static int	mptscsih_io_direction(Scsi_Cmnd *cmd);
+
+static int	mptscsih_Add32BitSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt,
+				 SCSIIORequest_t *pReq, int req_idx);
+static void	mptscsih_AddNullSGE(SCSIIORequest_t *pReq);
+static int	mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex);
+static void	mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx);
+static int	mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init);
+
 static void	copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
-static u32	SCPNT_TO_MSGCTX(Scsi_Cmnd *sc);
+#ifndef MPT_SCSI_USE_NEW_EH
+static void	search_taskQ_for_cmd(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd);
+#endif
+static u32	SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc);
+static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx);
+static void	post_pendingQ_commands(MPT_SCSI_HOST *hd);
+
+static int	mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag);
+static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag);
 
 static int	mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 static int	mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
+static VirtDevice	*mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
+void		mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target);
+static void	clear_sense_flag(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
+static void	mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq, char *data);
+static void	mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
+static int	mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
+static int	mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
+static void	mptscsih_timer_expired(unsigned long data);
+static void	mptscsih_taskmgmt_timeout(unsigned long data);
+static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
+static int	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
+
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+static int	mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
+static void	mptscsih_domainValidation(void *hd);
+static void	mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int target);
+static void	mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
+static void	mptscsih_fillbuf(char *buffer, int size, int index, int width);
+#endif
+static int	mptscsih_setup(char *str);
+static int	mptscsih_halt(struct notifier_block *nb, ulong event, void *buf);
+
+/*
+ *	Reboot Notification
+ */
+static struct notifier_block mptscsih_notifier = {
+	mptscsih_halt, NULL, 0
+};
+
+/*
+ *	Private data...
+ */
 
 static int	mpt_scsi_hosts = 0;
 static atomic_t	queue_depth;
 
 static int	ScsiDoneCtx = -1;
 static int	ScsiTaskCtx = -1;
+static int	ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,28)
 static struct proc_dir_entry proc_mpt_scsihost =
@@ -141,23 +230,40 @@
 };
 #endif
 
-#define SNS_LEN(scp)  sizeof((scp)->sense_buffer)
+#define SNS_LEN(scp)	sizeof((scp)->sense_buffer)
 
 #ifndef MPT_SCSI_USE_NEW_EH
 /*
  *  Stuff to handle single-threading SCSI TaskMgmt
  *  (abort/reset) requests...
  */
-static spinlock_t mpt_scsih_taskQ_lock = SPIN_LOCK_UNLOCKED;
-static MPT_Q_TRACKER mpt_scsih_taskQ = {
-	(MPT_FRAME_HDR*) &mpt_scsih_taskQ,
-	(MPT_FRAME_HDR*) &mpt_scsih_taskQ
-};
-static int mpt_scsih_taskQ_cnt = 0;
-static int mpt_scsih_taskQ_bh_active = 0;
-static MPT_FRAME_HDR *mpt_scsih_active_taskmgmt_mf = NULL;
+static spinlock_t mytaskQ_lock = SPIN_LOCK_UNLOCKED;
+static int mytaskQ_bh_active = 0;
+static struct tq_struct	mptscsih_ptaskfoo;
+static atomic_t	mpt_taskQdepth;
+#endif
+
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+/*
+ * Domain Validation task structure
+ */
+static spinlock_t dvtaskQ_lock = SPIN_LOCK_UNLOCKED;
+static int dvtaskQ_active = 0;
+static int dvtaskQ_release = 0;
+static struct tq_struct	mptscsih_dvTask;
 #endif
 
+/*
+ * Wait Queue setup
+ */
+static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
+static int scandv_wait_done = 1;
+
+/* Driver default setup
+ */
+static struct mptscsih_driver_setup
+	driver_setup = MPTSCSIH_DRIVER_SETUP;
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	mptscsih_io_done - Main SCSI IO callback routine registered to
@@ -174,123 +280,109 @@
  *	Returns 1 indicating alloc'd request frame ptr should be freed.
  */
 static int
-mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r)
+mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 {
 	Scsi_Cmnd	*sc;
 	MPT_SCSI_HOST	*hd;
-	MPT_SCSI_DEV	*mpt_sdev = NULL;
+	SCSIIORequest_t	*pScsiReq;
+	SCSIIOReply_t	*pScsiReply;
+	unsigned long	 flags;
 	u16		 req_idx;
 
+	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+
 	if ((mf == NULL) ||
 	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
-		printk(KERN_ERR MYNAM ": ERROR! NULL or BAD req frame ptr (=%p)!\n", mf);
-		return 1;
+		printk(MYIOC_s_ERR_FMT "%s req frame ptr! (=%p)!\n",
+				ioc->name, mf?"BAD":"NULL", mf);
+		/* return 1; CHECKME SteveR. Don't free. */
+		return 0;
 	}
 
-	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
 	sc = hd->ScsiLookup[req_idx];
-	hd->ScsiLookup[req_idx] = NULL;
+	if (sc == NULL) {
+		MPIHeader_t *hdr = (MPIHeader_t *)mf;
 
-	dmfprintk((KERN_INFO MYNAM ": ScsiDone (req:sc:reply=%p:%p:%p)\n", mf, sc, r));
+		atomic_dec(&queue_depth);
 
-	atomic_dec(&queue_depth);
+		/* writeSDP1 will use the ScsiDoneCtx
+		 * There is no processing for the reply.
+		 * Just return to the calling function.
+		 */
+		if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
+			printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n", ioc->name);
 
-	/*
-	 *  Check for {1st} {IO} completion to "new" device.
-	 *  How do we know it's a new device?
-	 *  If we haven't set SDpnt->hostdata I guess...
-	 */
-	if (sc && sc->device) {
-		mpt_sdev = (MPT_SCSI_DEV*)sc->device->hostdata;
-		if (!mpt_sdev) {
-			dprintk((KERN_INFO MYNAM ": *NEW* SCSI device (%d:%d:%d)!\n",
-					   sc->device->id, sc->device->lun, sc->device->channel));
-			if ((sc->device->hostdata = kmalloc(sizeof(MPT_SCSI_DEV), GFP_ATOMIC)) == NULL) {
-				printk(KERN_ERR MYNAM ": ERROR - kmalloc(%d) FAILED!\n", (int)sizeof(MPT_SCSI_DEV));
-			} else {
-				memset(sc->device->hostdata, 0, sizeof(MPT_SCSI_DEV));
-				mpt_sdev = (MPT_SCSI_DEV *) sc->device->hostdata;
-				mpt_sdev->ioc = ioc;
-			}
-		} else {
-			if (++mpt_sdev->io_cnt && mptscsih_io_direction(sc) < 0) {
-				if (++mpt_sdev->read_cnt == 3) {
-					dprintk((KERN_INFO MYNAM ": 3rd DATA_IN, CDB[0]=%02x\n",
-							sc->cmnd[0]));
-				}
-			}
-#if 0
-			if (mpt_sdev->sense_sz) {
-				/*
-				 *  Completion of first IO down this path
-				 *  *should* invalidate device SenseData...
-				 */
-				mpt_sdev->sense_sz = 0;
-			}
-#endif
-		}
+		mptscsih_freeChainBuffers(hd, req_idx);
+		return 1;
 	}
 
-#if 0
-{
-	MPT_FRAME_HDR	*mf_chk;
+	dmfprintk((MYIOC_s_INFO_FMT "ScsiDone (mf=%p,mr=%p,sc=%p)\n",
+			ioc->name, mf, mr, sc));
 
-	/* This, I imagine, is a costly check, but...
-	 *  If abort/reset active, check to see if this is a IO
-	 *  that completed while ABORT/RESET for it is waiting
-	 *  on our taskQ!
-	 */
-	if (! Q_IS_EMPTY(&mpt_scsih_taskQ)) {
-		/* If ABORT for this IO is queued, zap it! */
-		mf_chk = search_taskQ(1,sc,MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
-		if (mf_chk != NULL) {
-			sc->result = DID_ABORT << 16;
-			spin_lock_irqsave(&io_request_lock, flags);
-			sc->scsi_done(sc);
-			spin_unlock_irqrestore(&io_request_lock, flags);
-			return 1;
-		}
-	}
-}
-#endif
+	atomic_dec(&queue_depth);
 
-	if (r != NULL && sc != NULL) {
-		SCSIIOReply_t	*pScsiReply;
-		SCSIIORequest_t *pScsiReq;
-		u16		 status;
+	sc->result = DID_OK << 16;		/* Set default reply as OK */
+	pScsiReq = (SCSIIORequest_t *) mf;
+	pScsiReply = (SCSIIOReply_t *) mr;
+
+	if (pScsiReply == NULL) {
+		/* special context reply handling */
+
+		/* If regular Inquiry cmd - save inquiry data
+		 */
+		if (pScsiReq->CDB[0] == INQUIRY && !(pScsiReq->CDB[1] & 0x3)) {
+			int	 dlen;
 
-		pScsiReply = (SCSIIOReply_t *) r;
-		pScsiReq = (SCSIIORequest_t *) mf;
+			dlen = le32_to_cpu(pScsiReq->DataLength);
+			if (dlen >= SCSI_STD_INQUIRY_BYTES) {
+				mptscsih_initTarget(hd,
+						hd->port,
+						sc->target,
+						pScsiReq->LUN[1],
+						sc->buffer,
+						dlen);
+			}
+		}
+		clear_sense_flag(hd, pScsiReq);
+
+		if (hd->is_spi)
+			mptscsih_set_dvflags(hd, pScsiReq, sc->buffer);
+	} else {
+		u32	 xfer_cnt;
+		u16	 status;
+		u8	 scsi_state;
 
 		status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+		scsi_state = pScsiReply->SCSIState;
 
-		dprintk((KERN_NOTICE MYNAM ": Uh-Oh!  (req:sc:reply=%p:%p:%p)\n", mf, sc, r));
+		dprintk((KERN_NOTICE "  Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
+				ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
+				mf, mr, sc));
 		dprintk((KERN_NOTICE "  IOCStatus=%04xh, SCSIState=%02xh"
-				     ", SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
-				     status, pScsiReply->SCSIState, pScsiReply->SCSIStatus,
-				     le32_to_cpu(pScsiReply->IOCLogInfo)));
+				", SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
+				status, scsi_state, pScsiReply->SCSIStatus,
+				le32_to_cpu(pScsiReply->IOCLogInfo)));
+
+		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
+			copy_sense_data(sc, hd, mf, pScsiReply);
 
 		/*
 		 *  Look for + dump FCP ResponseInfo[]!
 		 */
-		if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
+		if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
 			dprintk((KERN_NOTICE "  FCP_ResponseInfo=%08xh\n",
 					     le32_to_cpu(pScsiReply->ResponseInfo)));
 		}
 
 		switch(status) {
 		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
-			/*sc->result = DID_BUS_BUSY << 16;*/		/* YIKES! - Seems to
-									 * kill linux interrupt
-									 * handler
-									 */
-			sc->result = STS_BUSY;				/* Try SCSI BUSY! */
-			break;
-
-		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
-			/*  Not real sure here...  */
-			sc->result = DID_OK << 16;
+			/* CHECKME!
+			 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
+			 * But not: DID_BUS_BUSY lest one risk
+			 * killing interrupt handler:-(
+			 */
+			sc->result = STS_BUSY;
 			break;
 
 		case MPI_IOCSTATUS_SCSI_INVALID_BUS:		/* 0x0041 */
@@ -299,10 +391,29 @@
 			break;
 
 		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
-			/*  Spoof to SCSI Selection Timeout!  */
+			/* Spoof to SCSI Selection Timeout! */
 			sc->result = DID_NO_CONNECT << 16;
 			break;
 
+		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
+#ifndef MPT_SCSI_USE_NEW_EH
+			search_taskQ_for_cmd(sc, hd);
+#endif
+			/* Linux handles an unsolicited DID_RESET better 
+			 * than an unsolicited DID_ABORT.
+			 */
+			sc->result = DID_RESET << 16;
+			break;
+
+		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
+		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
+#ifndef MPT_SCSI_USE_NEW_EH
+			search_taskQ_for_cmd(sc, hd);
+#endif
+			sc->result = DID_RESET << 16;
+			break;
+
+		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
 			/*
 			 *  YIKES!  I just discovered that SCSI IO which
@@ -312,78 +423,148 @@
 			 *  Do upfront check for valid SenseData and give it
 			 *  precedence!
 			 */
+			sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus;
+			clear_sense_flag(hd, pScsiReq);
 			if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
-				copy_sense_data(sc, hd, mf, pScsiReply);
-				sc->result = pScsiReply->SCSIStatus;
-				break;
+				/* Have already saved the status and sense data
+				 */
+				;
+			} else if (pScsiReply->SCSIState & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
+				/* What to do?
+				 */
+				sc->result = DID_SOFT_ERROR << 16;
+			}
+			else if (pScsiReply->SCSIState & MPI_SCSI_STATE_TERMINATED) {
+				/*  Not real sure here either...  */
+				sc->result = DID_RESET << 16;
 			}
 
-			dprintk((KERN_NOTICE MYNAM ": sc->underflow={report ERR if < %02xh bytes xfer'd}\n", sc->underflow));
-			dprintk((KERN_NOTICE MYNAM ": ActBytesXferd=%02xh\n", le32_to_cpu(pScsiReply->TransferCount)));
+			/* Give report and update residual count.
+			 */
+			xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
+			dprintk((KERN_NOTICE "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
+					sc->underflow));
+			dprintk((KERN_NOTICE "  ActBytesXferd=%02xh\n", xfer_cnt));
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-			sc->resid = sc->request_bufflen - le32_to_cpu(pScsiReply->TransferCount);
-			dprintk((KERN_NOTICE MYNAM ": SET sc->resid=%02xh\n", sc->resid));
+			sc->resid = sc->request_bufflen - xfer_cnt;
+			dprintk((KERN_NOTICE "  SET sc->resid=%02xh\n", sc->resid));
 #endif
 
-			if (pScsiReq->CDB[0] == INQUIRY) {
-				sc->result = (DID_OK << 16);
-				break;
-			}
+			/* Report Queue Full
+			 */
+			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
+				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 
-			/* workaround attempts... */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-			if (sc->resid >= 0x200) {
-				/* GRRRRR...
-				 *   //sc->result = DID_SOFT_ERROR << 16;
-				 * Try spoofing to BUSY
-				 */
-				sc->result = STS_BUSY;
-			} else {
-				sc->result = 0;
+			/* If regular Inquiry cmd and some data was transferred,
+			 * save inquiry data
+			 */
+			if (    pScsiReq->CDB[0] == INQUIRY
+			     && !(pScsiReq->CDB[1] & 0x3)
+			     && xfer_cnt >= SCSI_STD_INQUIRY_BYTES
+			   ) {
+				mptscsih_initTarget(hd,
+						hd->port,
+						sc->target,
+						pScsiReq->LUN[1],
+						sc->buffer,
+						xfer_cnt);
 			}
-#else
-			sc->result = 0;
-#endif
-			break;
 
-		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
-			sc->result = DID_ABORT << 16;
-			break;
-
-		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
-		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
-			sc->result = DID_RESET << 16;
+			if (hd->is_spi)
+				mptscsih_set_dvflags(hd, pScsiReq, sc->buffer);
 			break;
 
+		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
-			sc->result = pScsiReply->SCSIStatus;
+			sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus;
+			clear_sense_flag(hd, pScsiReq);
 
 			if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
-				copy_sense_data(sc, hd, mf, pScsiReply);
-
-				/*  If running agains circa 200003dd 909 MPT f/w,
-				 *  may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
-				 *  (QUEUE_FULL) returned from device!	--> get 0x0000?128
-				 *  and with SenseBytes set to 0.
+				/*
+				 * If running agains circa 200003dd 909 MPT f/w,
+				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
+				 * (QUEUE_FULL) returned from device! --> get 0x0000?128
+				 * and with SenseBytes set to 0.
 				 */
 				if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
 					mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
+
+#ifndef MPT_SCSI_USE_NEW_EH
+				/* ADDED 20011120 -sralston
+				 * Scsi mid-layer (old_eh) doesn't seem to like it
+				 * when RAID returns SCSIStatus=02 (CHECK CONDITION),
+				 * SenseKey=01 (RECOVERED ERROR), ASC/ASCQ=95/01.
+				 * Seems to be * treating this as a IO error:-(
+				 *
+				 * So just lie about it altogether here.
+				 *
+				 * NOTE: It still gets reported to syslog via
+				 * mpt_ScsiHost_ErrorReport from copy_sense_data
+				 * call far above.
+				 */
+				if (    pScsiReply->SCSIStatus == STS_CHECK_CONDITION
+				     && SD_Sense_Key(sc->sense_buffer) == SK_RECOVERED_ERROR
+				   ) {
+					sc->result = 0;
+				}
+#endif
+
 			}
-			else if (pScsiReply->SCSIState & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
+			else if (pScsiReply->SCSIState &
+			         (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
+			   ) {
 				/*
-				 *  What to do?
+				 * What to do?
 				 */
 				sc->result = DID_SOFT_ERROR << 16;
 			}
 			else if (pScsiReply->SCSIState & MPI_SCSI_STATE_TERMINATED) {
 				/*  Not real sure here either...  */
-				sc->result = DID_ABORT << 16;
+				sc->result = DID_RESET << 16;
+			}
+			else if (pScsiReply->SCSIState & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
+				/* Device Inq. data indicates that it supports
+				 * QTags, but rejects QTag messages.
+				 * This command completed OK.
+				 *
+				 * Not real sure here either so do nothing...  */
 			}
 
 			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 
+			/* Add handling of:
+			 * Reservation Conflict, Busy,
+			 * Command Terminated, CHECK
+			 */
+
+			/* If regular Inquiry cmd - save inquiry data
+			 */
+			xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
+			if (    sc->result == (DID_OK << 16)
+			     && pScsiReq->CDB[0] == INQUIRY
+			     && !(pScsiReq->CDB[1] & 0x3)
+			     && xfer_cnt >= SCSI_STD_INQUIRY_BYTES
+			   ) {
+				mptscsih_initTarget(hd,
+						hd->port,
+						sc->target,
+						pScsiReq->LUN[1],
+						sc->buffer,
+						xfer_cnt);
+			}
+
+			if (hd->is_spi)
+				mptscsih_set_dvflags(hd, pScsiReq, sc->buffer);
+			break;
+
+		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
+			if (pScsiReply->SCSIState & MPI_SCSI_STATE_TERMINATED) {
+				/*  Not real sure here either...  */
+				sc->result = DID_RESET << 16;
+			} else
+				sc->result = DID_SOFT_ERROR << 16;
 			break;
 
 		case MPI_IOCSTATUS_INVALID_FUNCTION:		/* 0x0001 */
@@ -395,50 +576,50 @@
 		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
 		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
-		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
-		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
 		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
 		default:
 			/*
-			 *  What to do?
+			 * What to do?
 			 */
 			sc->result = DID_SOFT_ERROR << 16;
 			break;
 
 		}	/* switch(status) */
 
-		dprintk((KERN_NOTICE MYNAM ": sc->result set to %08xh\n", sc->result));
+		dprintk((KERN_NOTICE "  sc->result set to %08xh\n", sc->result));
+	} /* end of address reply case */
+
+	/* Unmap the DMA buffers, if any. */
+	if (sc->use_sg) {
+		pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
+			    sc->use_sg, scsi_to_pci_dma_dir(sc->sc_data_direction));
+	} else if (sc->request_bufflen) {
+		scPrivate	*my_priv;
+
+		my_priv = (scPrivate *) &sc->SCp;
+		pci_unmap_single(ioc->pcidev, (dma_addr_t)(ulong)my_priv->p1,
+			   sc->request_bufflen,
+			   scsi_to_pci_dma_dir(sc->sc_data_direction));
 	}
 
-	if (sc != NULL) {
-		unsigned long flags;
+	hd->ScsiLookup[req_idx] = NULL;
 
-		/* Unmap the DMA buffers, if any. */
-		if (sc->use_sg) {
-			pci_unmap_sg(ioc->pcidev,
-				     (struct scatterlist *) sc->request_buffer,
-				     sc->use_sg,
-				     scsi_to_pci_dma_dir(sc->sc_data_direction));
-		} else if (sc->request_bufflen) {
-			pci_unmap_single(ioc->pcidev,
-					 (dma_addr_t)((long)sc->SCp.ptr),
-					 sc->request_bufflen,
-					 scsi_to_pci_dma_dir(sc->sc_data_direction));
-		}
+	sc->host_scribble = NULL;	/* CHECKME! - Do we need to clear this??? */
 
-		spin_lock_irqsave(&io_request_lock, flags);
-		sc->scsi_done(sc);
-		spin_unlock_irqrestore(&io_request_lock, flags);
-	}
+	spin_lock_irqsave(&io_request_lock, flags);
+	sc->scsi_done(sc);		/* Issue the command callback */
+	spin_unlock_irqrestore(&io_request_lock, flags);
 
+	/* Free Chain buffers */
+	mptscsih_freeChainBuffers(hd, req_idx);
 	return 1;
 }
 
-#ifndef MPT_SCSI_USE_NEW_EH
+#ifndef MPT_SCSI_USE_NEW_EH	/* { */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	search_taskQ - Search SCSI task mgmt request queue for specific
- *			request type
+ *	request type.
  *	@remove: (Boolean) Should request be removed if found?
  *	@sc: Pointer to Scsi_Cmnd structure
  *	@task_type: Task type to search for
@@ -447,42 +628,55 @@
  *	was not found.
  */
 static MPT_FRAME_HDR *
-search_taskQ(int remove, Scsi_Cmnd *sc, u8 task_type)
+search_taskQ(int remove, Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, u8 task_type)
 {
 	MPT_FRAME_HDR *mf = NULL;
 	unsigned long flags;
 	int count = 0;
 	int list_sz;
 
-	dslprintk((KERN_INFO MYNAM ": spinlock#1\n"));
-	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-	list_sz = mpt_scsih_taskQ_cnt;
-	if (! Q_IS_EMPTY(&mpt_scsih_taskQ)) {
-		mf = mpt_scsih_taskQ.head;
+	dprintk((KERN_INFO MYNAM ": search_taskQ(%d,sc=%p,%d) called\n",
+			remove, sc, task_type));
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	list_sz = hd->taskQcnt;
+	if (! Q_IS_EMPTY(&hd->taskQ)) {
+		mf = hd->taskQ.head;
 		do {
 			count++;
 			if (mf->u.frame.linkage.argp1 == sc &&
 			    mf->u.frame.linkage.arg1 == task_type) {
 				if (remove) {
 					Q_DEL_ITEM(&mf->u.frame.linkage);
-					mpt_scsih_taskQ_cnt--;
+					hd->taskQcnt--;
+					atomic_dec(&mpt_taskQdepth);
+
+					/* Don't save mf into nextmf because
+					 * exit after command has been deleted.
+					 */
+
+					/* Place the MF back on the FreeQ */
+					Q_ADD_TAIL(&hd->ioc->FreeQ,
+						&mf->u.frame.linkage,
+						MPT_FRAME_HDR);
+#ifdef MFCNT
+					hd->ioc->mfcnt--;
+#endif
 				}
 				break;
 			}
-		} while ((mf = mf->u.frame.linkage.forw) != (MPT_FRAME_HDR*)&mpt_scsih_taskQ);
-		if (mf == (MPT_FRAME_HDR*)&mpt_scsih_taskQ) {
+		} while ((mf = mf->u.frame.linkage.forw) != (MPT_FRAME_HDR*)&hd->taskQ);
+		if (mf == (MPT_FRAME_HDR*)&hd->taskQ) {
 			mf = NULL;
 		}
 	}
-	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
 
 	if (list_sz) {
-		dprintk((KERN_INFO MYNAM ": search_taskQ(%d,%p,%d) results=%p (%sFOUND%s)!\n",
-				   remove, sc, task_type,
+		dprintk((KERN_INFO "  Results=%p (%sFOUND%s)!\n",
 				   mf,
 				   mf ? "" : "NOT_",
 				   (mf && remove) ? "+REMOVED" : "" ));
-		dprintk((KERN_INFO MYNAM ": (searched thru %d of %d items on taskQ)\n",
+		dprintk((KERN_INFO "  (searched thru %d of %d items on taskQ)\n",
 				   count,
 				   list_sz ));
 	}
@@ -490,2107 +684,6547 @@
 	return mf;
 }
 
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/*
- *  Hack!  I'd like to report if a device is returning QUEUE_FULL
- *  but maybe not each and every time...
- */
-static long last_queue_full = 0;
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
- *	from a SCSI target device.
- *	@sc: Pointer to Scsi_Cmnd structure
- *	@pScsiReply: Pointer to SCSIIOReply_t
- *	@pScsiReq: Pointer to original SCSI request
+ *	clean_taskQ - Clean the  SCSI task mgmt request for
+ *			this SCSI host instance.
+ *	@hd: MPT_SCSI_HOST pointer
  *
- *	This routine periodically reports QUEUE_FULL status returned from a
- *	SCSI target device.  It reports this to the console via kernel
- *	printk() API call, not more than once every 10 seconds.
+ *	Returns: None.
  */
 static void
-mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
+clean_taskQ(MPT_SCSI_HOST *hd)
 {
-	long time = jiffies;
+	MPT_FRAME_HDR *mf = NULL;
+	MPT_FRAME_HDR *nextmf = NULL;
+	MPT_ADAPTER *ioc = hd->ioc;
+	unsigned long flags;
 
-	if (time - last_queue_full > 10 * HZ) {
-		printk(KERN_WARNING MYNAM ": Device reported QUEUE_FULL!  SCSI bus:target:lun = %d:%d:%d\n",
-				0, sc->target, sc->lun);
-		last_queue_full = time;
+	dprintk((KERN_INFO MYNAM ": clean_taskQ called\n"));
+	spin_lock_irqsave(&ioc->FreeQlock, flags);
+	if (! Q_IS_EMPTY(&hd->taskQ)) {
+		mf = hd->taskQ.head;
+		do {
+			Q_DEL_ITEM(&mf->u.frame.linkage);
+			hd->taskQcnt--;
+			atomic_dec(&mpt_taskQdepth);
+
+			nextmf = mf->u.frame.linkage.forw;
+
+			/* Place the MF back on the FreeQ */
+			Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage,
+				MPT_FRAME_HDR);
+#ifdef MFCNT
+			hd->ioc->mfcnt--;
+#endif
+		} while ((mf = nextmf) != (MPT_FRAME_HDR*)&hd->taskQ);
 	}
-}
+	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int BeenHereDoneThat = 0;
+	return;
+}
 
-/*  SCSI fops start here...  */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_detect - Register MPT adapter(s) as SCSI host(s) with
- *	linux scsi mid-layer.
- *	@tpnt: Pointer to Scsi_Host_Template structure
- *
- *	(linux Scsi_Host_Template.detect routine)
+/*
+ *	search_taskQ_for_cmd - Search the  SCSI task mgmt request queue for
+ *			the specified command. If found, delete
+ *	@hd: MPT_SCSI_HOST pointer
  *
- *	Returns number of SCSI host adapters that were successfully
- *	registered with the linux scsi mid-layer via the scsi_register()
- *	API call.
+ *	Returns: None.
  */
-int
-mptscsih_detect(Scsi_Host_Template *tpnt)
+static void
+search_taskQ_for_cmd(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd)
 {
-	struct Scsi_Host	*sh = NULL;
-	MPT_SCSI_HOST		*hd = NULL;
-	MPT_ADAPTER		*this;
-	unsigned long		 flags;
-	int			 sz;
-	u8			*mem;
+	MPT_FRAME_HDR *mf = NULL;
+	unsigned long flags;
+	int count = 0;
 
-	if (! BeenHereDoneThat++) {
-		show_mptmod_ver(my_NAME, my_VERSION);
+	dprintk((KERN_INFO MYNAM ": search_taskQ_for_cmd(sc=%p) called\n", sc));
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	if (! Q_IS_EMPTY(&hd->taskQ)) {
+		mf = hd->taskQ.head;
+		do {
+			count++;
+			if (mf->u.frame.linkage.argp1 == sc) {
+				Q_DEL_ITEM(&mf->u.frame.linkage);
+				hd->taskQcnt--;
+				atomic_dec(&mpt_taskQdepth);
+				dprintk((KERN_INFO MYNAM
+					": Cmd %p found! Deleting.\n", sc));
 
-		if ((ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER)) <= 0) {
-			printk(KERN_ERR MYNAM ": Failed to register callback1 with MPT base driver\n");
-			return mpt_scsi_hosts;
-		}
-		if ((ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER)) <= 0) {
-			printk(KERN_ERR MYNAM ": Failed to register callback2 with MPT base driver\n");
-			return mpt_scsi_hosts;
-		}
+				/* Don't save mf into nextmf because
+				 * exit after command has been deleted.
+				 */
 
-#ifndef MPT_SCSI_USE_NEW_EH
-		Q_INIT(&mpt_scsih_taskQ, MPT_FRAME_HDR);
-		spin_lock_init(&mpt_scsih_taskQ_lock);
+				/* Place the MF back on the FreeQ */
+				Q_ADD_TAIL(&hd->ioc->FreeQ,
+					&mf->u.frame.linkage,
+					MPT_FRAME_HDR);
+#ifdef MFCNT
+				hd->ioc->mfcnt--;
 #endif
+				break;
+			}
+		} while ((mf = mf->u.frame.linkage.forw) != (MPT_FRAME_HDR*)&hd->taskQ);
+	}
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
 
-		if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
-			dprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n"));
-		} else {
-			/* FIXME! */
-		}
+	return;
+}
 
-		if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
-			dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
-		} else {
-			/* FIXME! */
-		}
-	}
+#endif		/* } MPT_SCSI_USE_NEW_EH */
 
-	dprintk((KERN_INFO MYNAM ": mpt_scsih_detect()\n"));
 
-	this = mpt_adapter_find_first();
-	while (this != NULL) {
-		/* FIXME!  Multi-port (aka FC929) support...
-		 * for (i = 0; i < this->facts.NumberOfPorts; i++)
-		 */
+/*
+ * Flush all commands on the doneQ.
+ * Lock Q when deleting/adding members
+ * Lock io_request_lock for OS callback.
+ */
+static void
+flush_doneQ(MPT_SCSI_HOST *hd)
+{
+	MPT_DONE_Q	*buffer;
+	Scsi_Cmnd	*SCpnt;
+	unsigned long	 flags;
 
-		/* 20010215 -sralston
-		 *  Added sanity check on SCSI Initiator-mode enabled
-		 *  for this MPT adapter.
-		 */
-		if (!(this->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
-			printk(KERN_ERR MYNAM ": Skipping %s because SCSI Initiator mode is NOT enabled!\n",
-					this->name);
-			this = mpt_adapter_find_next(this);
-			continue;
+	/* Flush the doneQ.
+	 */
+	dprintk((KERN_INFO MYNAM ": flush_doneQ called\n"));
+	while (1) {
+		spin_lock_irqsave(&hd->freedoneQlock, flags);
+		if (Q_IS_EMPTY(&hd->doneQ)) {
+			spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+			break;
 		}
 
-		/* 20010202 -sralston
-		 *  Added sanity check on readiness of the MPT adapter.
+		buffer = hd->doneQ.head;
+		/* Delete from Q
 		 */
-		if (this->last_state != MPI_IOC_STATE_OPERATIONAL) {
-			printk(KERN_ERR MYNAM ": ERROR - Skipping %s because it's not operational!\n",
-					this->name);
-			this = mpt_adapter_find_next(this);
-			continue;
-		}
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-		tpnt->proc_dir = &proc_mpt_scsihost;
-#endif
-		sh = scsi_register(tpnt, sizeof(MPT_SCSI_HOST));
-		if (sh != NULL) {
-			save_flags(flags);
-			cli();
-			sh->io_port = 0;
-			sh->n_io_port = 0;
-			sh->irq = 0;
-
-			/* Yikes!  This is important!
-			 * Otherwise, by default, linux only scans target IDs 0-7!
-			 *
-			 * BUG FIX!  20010618 -sralston & pdelaney
-			 * FC919 testing was encountering "duplicate" FC devices,
-			 * as it turns out because the 919 was returning 512
-			 * for PortFacts.MaxDevices, causing a wraparound effect
-			 * in SCSI IO requests.  So instead of using:
-			 *     sh->max_id = this->pfacts[0].MaxDevices - 1
-			 * we'll use a definitive max here.
-			 */
-			sh->max_id = MPT_MAX_FC_DEVICES;
-
-			sh->this_id = this->pfacts[0].PortSCSIID;
-
-			restore_flags(flags);
-
-			hd = (MPT_SCSI_HOST *) sh->hostdata;
-			hd->ioc = this;
-			hd->port = 0;		/* FIXME! */
-
-			/* SCSI needs Scsi_Cmnd lookup table!
-			 * (with size equal to req_depth*PtrSz!)
-			 */
-			sz = hd->ioc->req_depth * sizeof(void *);
-			mem = kmalloc(sz, GFP_KERNEL);
-			if (mem == NULL)
-				return mpt_scsi_hosts;
-
-			memset(mem, 0, sz);
-			hd->ScsiLookup = (struct scsi_cmnd **) mem;
-
-			dprintk((KERN_INFO MYNAM ": ScsiLookup @ %p, sz=%d\n",
-				 hd->ScsiLookup, sz));
-
-			/* SCSI also needs SG buckets/hunk management!
-			 * (with size equal to N * req_sz * req_depth!)
-			 * (where N is number of SG buckets per hunk)
-			 */
-			sz = MPT_SG_BUCKETS_PER_HUNK * hd->ioc->req_sz * hd->ioc->req_depth;
-			mem = pci_alloc_consistent(hd->ioc->pcidev, sz,
-						   &hd->SgHunksDMA);
-			if (mem == NULL)
-				return mpt_scsi_hosts;
+		Q_DEL_ITEM(buffer);
 
-			memset(mem, 0, sz);
-			hd->SgHunks = (u8*)mem;
-
-			dprintk((KERN_INFO MYNAM ": SgHunks    @ %p(%08x), sz=%d\n",
-				 hd->SgHunks, hd->SgHunksDMA, sz));
+		/* Set the Scsi_Cmnd pointer
+		 */
+		SCpnt = (Scsi_Cmnd *) buffer->argp;
+		buffer->argp = NULL;
 
-			hd->qtag_tick = jiffies;
+		/* Add to the freeQ
+		 */
+		Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);
+		spin_unlock_irqrestore(&hd->freedoneQlock, flags);
 
-			this->sh = sh;
-			mpt_scsi_hosts++;
-		}
-		this = mpt_adapter_find_next(this);
+		/* Do the OS callback.
+		 */
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
 	}
 
-	return mpt_scsi_hosts;
+	return;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-    static char *info_kbuf = NULL;
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_release - Unregister SCSI host from linux scsi mid-layer
- *	@host: Pointer to Scsi_Host structure
+/*
+ * Search the doneQ for a specific command. If found, delete from Q.
+ * Calling function will finish processing.
+ */
+static void
+search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt)
+{
+	unsigned long	 flags;
+	MPT_DONE_Q	*buffer;
+
+	spin_lock_irqsave(&hd->freedoneQlock, flags);
+	if (!Q_IS_EMPTY(&hd->doneQ)) {
+		buffer = hd->doneQ.head;
+		do {
+			Scsi_Cmnd *sc = (Scsi_Cmnd *) buffer->argp;
+			if (SCpnt == sc) {
+				Q_DEL_ITEM(buffer);
+				SCpnt->result = sc->result;
+
+				/* Set the Scsi_Cmnd pointer
+				 */
+				buffer->argp = NULL;
+
+				/* Add to the freeQ
+				 */
+				Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);
+				break;
+			}
+		} while ((buffer = buffer->forw) != (MPT_DONE_Q *) &hd->doneQ);
+	}
+	spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+	return;
+}
+
+/*
+ *	mptscsih_flush_running_cmds - For each command found, search
+ *		Scsi_Host instance taskQ and reply to OS.
+ *		Called only if recovering from a FW reload.
+ *	@hd: Pointer to a SCSI HOST structure
  *
- *	(linux Scsi_Host_Template.release routine)
- *	This routine releases all resources associated with the SCSI host
- *	adapter.
+ *	Returns: None.
  *
- *	Returns 0 for success.
+ *	Must be called while new I/Os are being queued.
  */
-int
-mptscsih_release(struct Scsi_Host *host)
+static void
+mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
 {
-	MPT_SCSI_HOST	*hd;
-#ifndef MPT_SCSI_USE_NEW_EH
+	Scsi_Cmnd	*SCpnt = NULL;
+	MPT_FRAME_HDR	*mf = NULL;
+	int		 ii;
+	int		 max = hd->ioc->req_depth;
 	unsigned long	 flags;
 
-	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-	if (mpt_scsih_taskQ_bh_active) {
-		int count = 10 * HZ;
+	dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
+	for (ii= 0; ii < max; ii++) {
+		if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
 
-		dprintk((KERN_INFO MYNAM ": Info: Zapping TaskMgmt thread!\n"));
+			/* Command found.
+			 */
+
+#ifndef MPT_SCSI_USE_NEW_EH
+			/* Search taskQ, if found, delete.
+			 */
+			search_taskQ_for_cmd(SCpnt, hd);
+#endif
+
+			/* Search pendingQ, if found, 
+			 * delete from Q. If found, do not decrement
+			 * queue_depth, command never posted.
+			 */
+			if (mptscsih_search_pendingQ(hd, ii) == NULL)
+				atomic_dec(&queue_depth);
 
-		/* Zap the taskQ! */
-		Q_INIT(&mpt_scsih_taskQ, MPT_FRAME_HDR);
-		spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
+			/* Null ScsiLookup index
+			 */
+			hd->ScsiLookup[ii] = NULL;
 
-		while(mpt_scsih_taskQ_bh_active && --count) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(1);
+			mf = MPT_INDEX_2_MFPTR(hd->ioc, ii);
+			dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
+					mf, SCpnt));
+
+			/* Set status
+			 * Do OS callback
+			 * Free chain buffers
+			 * Free message frame
+			 */
+			SCpnt->result = DID_RESET << 16;
+			SCpnt->host_scribble = NULL;
+			spin_lock_irqsave(&io_request_lock, flags);
+			SCpnt->scsi_done(SCpnt);	/* Issue the command callback */
+			spin_unlock_irqrestore(&io_request_lock, flags);
+
+			/* Free Chain buffers */
+			mptscsih_freeChainBuffers(hd, ii);
+
+			/* Free Message frames */
+			mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
 		}
-		if (!count)
-			printk(KERN_ERR MYNAM ": ERROR! TaskMgmt thread still active!\n");
 	}
-	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
-#endif
+	return;
+}
 
-	hd = (MPT_SCSI_HOST *) host->hostdata;
-	if (hd != NULL) {
-		int sz1, sz2;
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_initChainBuffers - Allocate memory for and initialize
+ *	chain buffers, chain buffer control arrays and spinlock.
+ *	@hd: Pointer to MPT_SCSI_HOST structure
+ *	@init: If set, initialize the spin lock.
+ */
+static int
+mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init)
+{
+	MPT_FRAME_HDR	*chain;
+	u8		*mem;
+	unsigned long	flags;
+	int		sz, ii, numChain;
 
-		sz1 = sz2 = 0;
-		if (hd->ScsiLookup != NULL) {
-			sz1 = hd->ioc->req_depth * sizeof(void *);
-			kfree(hd->ScsiLookup);
-			hd->ScsiLookup = NULL;
-		}
 
-		if (hd->SgHunks != NULL) {
+        /* Chain buffer allocations
+	 * Allocate and initialize tracker structures
+	 */
+	if (hd->ioc->req_sz <= 64)
+		numChain = MPT_SG_REQ_64_SCALE * hd->ioc->req_depth;
+	else if (hd->ioc->req_sz <= 96)
+		numChain = MPT_SG_REQ_96_SCALE * hd->ioc->req_depth;
+	else
+		numChain = MPT_SG_REQ_128_SCALE * hd->ioc->req_depth;
 
-			sz2 = MPT_SG_BUCKETS_PER_HUNK * hd->ioc->req_sz * hd->ioc->req_depth;
-			pci_free_consistent(hd->ioc->pcidev, sz2,
-					    hd->SgHunks, hd->SgHunksDMA);
-			hd->SgHunks = NULL;
-		}
-		dprintk((KERN_INFO MYNAM ": Free'd ScsiLookup (%d) and SgHunks (%d) memory\n", sz1, sz2));
+	sz = numChain * sizeof(int);
+
+	if (hd->ReqToChain == NULL) {
+		mem = kmalloc(sz, GFP_KERNEL);
+		if (mem == NULL)
+			return -1;
+
+		hd->ReqToChain = (int *) mem;
+	} else {
+		mem = (u8 *) hd->ReqToChain;
 	}
+	memset(mem, 0xFF, sz);
 
-	if (mpt_scsi_hosts) {
-		if (--mpt_scsi_hosts == 0) {
-#if 0
-			mptscsih_flush_pending();
-#endif
-			mpt_reset_deregister(ScsiDoneCtx);
-			dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
+	if (hd->ChainToChain == NULL) {
+		mem = kmalloc(sz, GFP_KERNEL);
+		if (mem == NULL)
+			return -1;
 
-			mpt_event_deregister(ScsiDoneCtx);
-			dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));
+		hd->ChainToChain = (int *) mem;
+	} else {
+		mem = (u8 *) hd->ChainToChain;
+	}
+	memset(mem, 0xFF, sz);
 
-			mpt_deregister(ScsiDoneCtx);
-			mpt_deregister(ScsiTaskCtx);
+	if (hd->ChainBuffer == NULL) {
+		/* Allocate free chain buffer pool
+		 */
+		sz = numChain * hd->ioc->req_sz;
+		mem = pci_alloc_consistent(hd->ioc->pcidev, sz, &hd->ChainBufferDMA);
+		if (mem == NULL)
+			return -1;
 
-			if (info_kbuf != NULL)
-				kfree(info_kbuf);
-		}
+		hd->ChainBuffer = (u8*)mem;
+	} else {
+		mem = (u8 *) hd->ChainBuffer;
+	}
+	memset(mem, 0, sz);
+
+	dprintk((KERN_INFO "  ChainBuffer    @ %p(%p), sz=%d\n",
+		 hd->ChainBuffer, (void *)(ulong)hd->ChainBufferDMA, sz));
+
+	/* Initialize the free chain Q.
+	 */
+	if (init) {
+		spin_lock_init(&hd->FreeChainQlock);
 	}
 
+	spin_lock_irqsave (&hd->FreeChainQlock, flags);
+	Q_INIT(&hd->FreeChainQ, MPT_FRAME_HDR);
+
+	/* Post the chain buffers to the FreeChainQ.
+	 */
+	mem = (u8 *)hd->ChainBuffer;
+	for (ii=0; ii < numChain; ii++) {
+		chain = (MPT_FRAME_HDR *) mem;
+		Q_ADD_TAIL(&hd->FreeChainQ.head, &chain->u.frame.linkage, MPT_FRAME_HDR);
+		mem += hd->ioc->req_sz;
+	}
+	spin_unlock_irqrestore(&hd->FreeChainQlock, flags);
+
 	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_info - Return information about MPT adapter
- *	@SChost: Pointer to Scsi_Host structure
- *
- *	(linux Scsi_Host_Template.info routine)
+/*
+ *  Hack! It might be nice to report if a device is returning QUEUE_FULL
+ *  but maybe not each and every time...
+ */
+static long last_queue_full = 0;
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
+ *	from a SCSI target device.
+ *	@sc: Pointer to Scsi_Cmnd structure
+ *	@pScsiReply: Pointer to SCSIIOReply_t
+ *	@pScsiReq: Pointer to original SCSI request
  *
- *	Returns pointer to buffer where information was written.
+ *	This routine periodically reports QUEUE_FULL status returned from a
+ *	SCSI target device.  It reports this to the console via kernel
+ *	printk() API call, not more than once every 10 seconds.
  */
-const char *
-mptscsih_info(struct Scsi_Host *SChost)
+static void
+mptscsih_report_queue_full(Scsi_Cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
 {
-	MPT_SCSI_HOST *h;
-	int size = 0;
-
-	if (info_kbuf == NULL)
-		if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
-			return info_kbuf;
+	long time = jiffies;
 
-	h = (MPT_SCSI_HOST *)SChost->hostdata;
-	info_kbuf[0] = '\0';
-	mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
-	info_kbuf[size-1] = '\0';
+	if (time - last_queue_full > 10 * HZ) {
+		char *ioc_str = "ioc?";
 
-	return info_kbuf;
+		if (sc->host && sc->host->hostdata)
+			ioc_str = ((MPT_SCSI_HOST *)sc->host->hostdata)->ioc->name;
+		printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
+				ioc_str, 0, sc->target, sc->lun);
+		last_queue_full = time;
+	}
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-	static int max_qd = 1;
-#ifdef MPT_DEBUG
-	static int max_sges = 0;
-	static int max_xfer = 0;
-#endif
-#if 0
-	static int max_num_sges = 0;
-	static int max_sgent_len = 0;
-#endif
-#if 0
-static int index_log[128];
-static int index_ent = 0;
-static __inline__ void ADD_INDEX_LOG(int req_ent)
-{
-	int i = index_ent++;
+static int BeenHereDoneThat = 0;
 
-	index_log[i & (128 - 1)] = req_ent;
-}
-#else
-#define ADD_INDEX_LOG(req_ent)	do { } while(0)
-#endif
+/*  SCSI host fops start here...  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
- *	@SCpnt: Pointer to Scsi_Cmnd structure
- *	@done: Pointer SCSI mid-layer IO completion function
+ *	mptscsih_detect - Register MPT adapter(s) as SCSI host(s) with
+ *	linux scsi mid-layer.
+ *	@tpnt: Pointer to Scsi_Host_Template structure
  *
- *	(linux Scsi_Host_Template.queuecommand routine)
- *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
- *	from a linux Scsi_Cmnd request and send it to the IOC.
+ *	(linux Scsi_Host_Template.detect routine)
  *
- *	Returns 0. (rtn value discarded by linux scsi mid-layer)
+ *	Returns number of SCSI host adapters that were successfully
+ *	registered with the linux scsi mid-layer via the scsi_register()
+ *	API call.
  */
 int
-mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+mptscsih_detect(Scsi_Host_Template *tpnt)
 {
-	struct Scsi_Host	*host;
-	MPT_SCSI_HOST		*hd;
-	MPT_FRAME_HDR		*mf;
-	SCSIIORequest_t		*pScsiReq;
-	int	 datadir;
-	u32	 len;
-	u32	 sgdir;
-	u32	 scsictl;
-	u32	 scsidir;
-	u32	 qtag;
-	u32	*mptr;
-	int	 sge_spill1;
-	int	 frm_sz;
-	int	 sges_left;
-	u32	 chain_offset;
-	int	 my_idx;
-	int	 i;
+	struct Scsi_Host	*sh = NULL;
+	MPT_SCSI_HOST		*hd = NULL;
+	MPT_ADAPTER		*this;
+	MPT_DONE_Q		*freedoneQ;
+	unsigned long		 flags;
+	int			 sz, ii;
+	int			 numSGE = 0;
+	int			 scale;
+	u8			*mem;
 
-	dmfprintk((KERN_INFO MYNAM "_qcmd: SCpnt=%p, done()=%p\n",
-		    SCpnt, done));
+	if (! BeenHereDoneThat++) {
+		show_mptmod_ver(my_NAME, my_VERSION);
 
-	host = SCpnt->host;
-	hd = (MPT_SCSI_HOST *) host->hostdata;
-	
-#if 0
-	if (host->host_busy >= 60) {
-		MPT_ADAPTER *ioc = hd->ioc;
-		u16 pci_command, pci_status;
-
-		/* The IOC is probably hung, investigate status. */
-		printk("MPI: IOC probably hung IOCSTAT[%08x] INTSTAT[%08x] REPLYFIFO[%08x]\n",
-		       readl(&ioc->chip.fc9xx->DoorbellValue),
-		       readl(&ioc->chip.fc9xx->IntStatus),
-		       readl(&ioc->chip.fc9xx->ReplyFifo));
-		pci_read_config_word(ioc->pcidev, PCI_COMMAND, &pci_command);
-		pci_read_config_word(ioc->pcidev, PCI_STATUS, &pci_status);
-		printk("MPI: PCI command[%04x] status[%04x]\n", pci_command, pci_status);
-		{
-			/* DUMP req index logger. */
-			int begin, end;
+		ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
+		ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
+		ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
 
-			begin = (index_ent - 65) & (128 - 1);
-			end = index_ent & (128 - 1);
-			printk("MPI: REQ_INDEX_HIST[");
-			while (begin != end) {
-				printk("(%04x)", index_log[begin]);
-				begin = (begin + 1) & (128 - 1);
-			}
-			printk("\n");
-		}
-		sti();
-		while(1)
-			barrier();
-	}
+#ifndef MPT_SCSI_USE_NEW_EH
+		spin_lock_init(&mytaskQ_lock);
 #endif
 
-	SCpnt->scsi_done = done;
+		if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
+			dprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n"));
+		} else {
+			/* FIXME! */
+		}
 
-	/* 20000617 -sralston
-	 *  GRRRRR...  Shouldn't have to do this but...
-	 *  Do explicit check for REQUEST_SENSE and cached SenseData.
-	 *  If yes, return cached SenseData.
-	 */
-#ifdef MPT_SCSI_CACHE_AUTOSENSE
-	{
-		MPT_SCSI_DEV	*mpt_sdev;
+		if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
+			dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+		} else {
+			/* FIXME! */
+		}
+	}
+	dprintk((KERN_INFO MYNAM ": mpt_scsih_detect()\n"));
 
-		mpt_sdev = (MPT_SCSI_DEV *) SCpnt->device->hostdata;
-		if (mpt_sdev && SCpnt->cmnd[0] == REQUEST_SENSE) {
-			u8 *dest = NULL;
+#ifdef MODULE
+	/* Evaluate the command line arguments, if any */
+	if (mptscsih)
+		mptscsih_setup(mptscsih);
+#endif
+#ifndef MPT_SCSI_USE_NEW_EH
+	atomic_set(&mpt_taskQdepth, 0);
+#endif
 
-			if (!SCpnt->use_sg)
-				dest = SCpnt->request_buffer;
-			else {
-				struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
-				if (sg)
-					dest = (u8 *) (unsigned long)sg_dma_address(sg);
+	this = mpt_adapter_find_first();
+	while (this != NULL) {
+		int	 portnum;
+		for (portnum=0; portnum < this->facts.NumberOfPorts; portnum++) {
+
+			/* 20010215 -sralston
+			 *  Added sanity check on SCSI Initiator-mode enabled
+			 *  for this MPT adapter.
+			 */
+			if (!(this->pfacts[portnum].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
+				printk(MYIOC_s_WARN_FMT "Skipping because SCSI Initiator mode is NOT enabled!\n",
+						this->name);
+				continue;
 			}
 
-			if (dest && mpt_sdev->sense_sz) {
-				memcpy(dest, mpt_sdev->CachedSense.data, mpt_sdev->sense_sz);
-#ifdef MPT_DEBUG
-				{
-					int  i;
-					u8  *sb;
-
-					sb = mpt_sdev->CachedSense.data;
-					if (sb && ((sb[0] & 0x70) == 0x70)) {
-						printk(KERN_WARNING MYNAM ": Returning last cached SCSI (hex) SenseData:\n");
-						printk(KERN_WARNING " ");
-						for (i = 0; i < (8 + sb[7]); i++)
-							printk("%s%02x", i == 13 ? "-" : " ", sb[i]);
-						printk("\n");
-					}
-				}
-#endif
+			/* 20010202 -sralston
+			 *  Added sanity check on readiness of the MPT adapter.
+			 */
+			if (this->last_state != MPI_IOC_STATE_OPERATIONAL) {
+				printk(MYIOC_s_WARN_FMT "Skipping because it's not operational!\n",
+						this->name);
+				continue;
 			}
-			SCpnt->resid = SCpnt->request_bufflen - mpt_sdev->sense_sz;
-			SCpnt->result = 0;
-/*			spin_lock(&io_request_lock);	*/
-			SCpnt->scsi_done(SCpnt);
-/*			spin_unlock(&io_request_lock);	*/
-			return 0;
-		}
-	}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+			tpnt->proc_dir = &proc_mpt_scsihost;
 #endif
+			sh = scsi_register(tpnt, sizeof(MPT_SCSI_HOST));
+			if (sh != NULL) {
+				save_flags(flags);
+				cli();
+				sh->io_port = 0;
+				sh->n_io_port = 0;
+				sh->irq = 0;
+
+				/* Yikes!  This is important!
+				 * Otherwise, by default, linux
+				 * only scans target IDs 0-7!
+				 * pfactsN->MaxDevices unreliable
+				 * (not supported in early
+				 *	versions of the FW).
+				 * max_id = 1 + actual max id,
+				 * max_lun = 1 + actual last lun,
+				 *	see hosts.h :o(
+				 */
+				if ((int)this->chip_type > (int)FC929)
+					sh->max_id = MPT_MAX_SCSI_DEVICES;
+				else {
+					/* For FC, increase the queue depth
+					 * from MPT_SCSI_CAN_QUEUE (31)
+					 * to MPT_FC_CAN_QUEUE (63).
+					 */
+					sh->can_queue = MPT_FC_CAN_QUEUE;
+					sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
+				}
+				sh->max_lun = MPT_LAST_LUN + 1;
 
-	if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc->id)) == NULL) {
-/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/
-		SCpnt->result = STS_BUSY;
-		SCpnt->scsi_done(SCpnt);
-/*		return 1;				*/
-		return 0;
-	}
-	pScsiReq = (SCSIIORequest_t *) mf;
+				sh->this_id = this->pfacts[portnum].PortSCSIID;
 
-	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+				/* OS entry to allow host drivers to force
+				 * a queue depth on a per device basis.
+				 */
+				sh->select_queue_depths = mptscsih_select_queue_depths;
 
-	ADD_INDEX_LOG(my_idx);
+				/* Verify that we won't exceed the maximum
+				 * number of chain buffers
+				 * We can optimize:  ZZ = req_sz/sizeof(MptSge_t)
+				 * For 32bit SGE's:
+				 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
+				 *               + (req_sz - 64)/sizeof(MptSge_t)
+				 * A slightly different algorithm is required for
+				 * 64bit SGEs.
+				 */
+				scale = this->req_sz/sizeof(MptSge_t);
+				if (sizeof(MptSge_t) == sizeof(SGESimple32_t)) {
+					numSGE = 1 + (scale - 1) * (this->facts.MaxChainDepth-1) + scale +
+						(this->req_sz - 64) / (sizeof(MptSge_t));
+				} else if (sizeof(MptSge_t) == sizeof(SGESimple64_t)) {
+					numSGE = (scale - 1) * (this->facts.MaxChainDepth-1) + scale +
+						(this->req_sz - 60) / (sizeof(MptSge_t));
+				}
 
-	/* Map the data portion, if any. */
-	sges_left = SCpnt->use_sg;
-	if (sges_left) {
-		sges_left = pci_map_sg(hd->ioc->pcidev,
-				       (struct scatterlist *) SCpnt->request_buffer,
-				       sges_left,
-				       scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
-	} else if (SCpnt->request_bufflen) {
-		dma_addr_t buf_dma_addr;
+				if (numSGE < sh->sg_tablesize) {
+					/* Reset this value */
+					dprintk((MYIOC_s_INFO_FMT
+						 "Resetting sg_tablesize to %d from %d\n",
+						 this->name, numSGE, sh->sg_tablesize));
+					sh->sg_tablesize = numSGE;
+				}
 
-		buf_dma_addr = pci_map_single(hd->ioc->pcidev,
-					      SCpnt->request_buffer,
-					      SCpnt->request_bufflen,
-					      scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+				restore_flags(flags);
 
-		/* We hide it here for later unmap. */
-		SCpnt->SCp.ptr = (char *)(unsigned long) buf_dma_addr;
-	}
+				hd = (MPT_SCSI_HOST *) sh->hostdata;
+				hd->ioc = this;
 
-	/*
-	 *  Put together a MPT SCSI request...
-	 */
+				if ((int)this->chip_type > (int)FC929)
+					hd->is_spi = 1;
 
-	/* Assume SimpleQ, NO DATA XFER for now */
+				if (DmpService &&
+				    (this->chip_type == FC919 || this->chip_type == FC929))
+					hd->is_multipath = 1;
 
-	len = SCpnt->request_bufflen;
-	sgdir = 0x00000000;		/* SGL IN  (host<--ioc) */
-	scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
+				hd->port = 0;		/* FIXME! */
 
-	/*
-	 *  The scsi layer should be handling this stuff
-	 *  (In 2.3.x it does -DaveM)
-	 */
-
-	/*  BUG FIX!  19991030 -sralston
-	 *    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
-	 *    Seems we may receive a buffer (len>0) even when there
-	 *    will be no data transfer!  GRRRRR...
-	 */
-	datadir = mptscsih_io_direction(SCpnt);
-	if (datadir < 0) {
-		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
-	} else if (datadir > 0) {
-		sgdir	= 0x04000000;			/* SGL OUT  (host-->ioc) */
-		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
-	} else {
-		len = 0;
-	}
-
-	qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
-
-	/*
-	 *  Attach tags to the devices
-	 */
-	if (SCpnt->device->tagged_supported) {
-		/*
-		 *  Some drives are too stupid to handle fairness issues
-		 *  with tagged queueing. We throw in the odd ordered
-		 *  tag to stop them starving themselves.
-		 */
-		if ((jiffies - hd->qtag_tick) > (5*HZ)) {
-			qtag = MPI_SCSIIO_CONTROL_ORDEREDQ;
-			hd->qtag_tick = jiffies;
+				/* SCSI needs Scsi_Cmnd lookup table!
+				 * (with size equal to req_depth*PtrSz!)
+				 */
+				sz = hd->ioc->req_depth * sizeof(void *);
+				mem = kmalloc(sz, GFP_KERNEL);
+				if (mem == NULL)
+					goto done;
 
-#if 0
-			/* These are ALWAYS zero!
-			 * (Because this is a place for the device driver to dynamically
-			 *  assign tag numbers any way it sees fit.  That's why -DaveM)
-			 */
-			dprintk((KERN_DEBUG MYNAM ": sc->device->current_tag = %08x\n",
-					SCpnt->device->current_tag));
-			dprintk((KERN_DEBUG MYNAM ": sc->tag                 = %08x\n",
-					SCpnt->tag));
-#endif
-		}
-#if 0
-		else {
-			/* Hmmm...  I always see value of 0 here,
-			 *  of which {HEAD_OF, ORDERED, SIMPLE} are NOT!  -sralston
-			 * (Because this is a place for the device driver to dynamically
-			 *  assign tag numbers any way it sees fit.  That's why -DaveM)
-			 *
-			 * if (SCpnt->tag == HEAD_OF_QUEUE_TAG)
-			 */
-			if (SCpnt->device->current_tag == HEAD_OF_QUEUE_TAG)
-				qtag = MPI_SCSIIO_CONTROL_HEADOFQ;
-			else if (SCpnt->tag == ORDERED_QUEUE_TAG)
-				qtag = MPI_SCSIIO_CONTROL_ORDEREDQ;
-		}
-#endif
-	}
+				memset(mem, 0, sz);
+				hd->ScsiLookup = (struct scsi_cmnd **) mem;
 
-	scsictl = scsidir | qtag;
+				dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
+					 this->name, hd->ScsiLookup, sz));
 
-	frm_sz = hd->ioc->req_sz;
+				if (mptscsih_initChainBuffers(hd, 1) < 0)
+					goto done;
 
-	/* Ack!
-	 * sge_spill1 = 9;
-	 */
-	sge_spill1 = (frm_sz - (sizeof(SCSIIORequest_t) - sizeof(SGEIOUnion_t) + sizeof(SGEChain32_t))) / 8;
-	/*  spill1: for req_sz == 128 (128-48==80, 80/8==10 SGEs max, first time!), --> use 9
-	 *  spill1: for req_sz ==  96 ( 96-48==48, 48/8== 6 SGEs max, first time!), --> use 5
-	 */
-	dsgprintk((KERN_INFO MYNAM ": SG: %x     spill1 = %d\n",
-		   my_idx, sge_spill1));
-
-#ifdef MPT_DEBUG
-	if (sges_left > max_sges) {
-		max_sges = sges_left;
-		dprintk((KERN_INFO MYNAM ": MPT_MaxSges = %d\n", max_sges));
-	}
-#endif
-#if 0
-	if (sges_left > max_num_sges) {
-		max_num_sges = sges_left;
-		printk(KERN_INFO MYNAM ": MPT_MaxNumSges = %d\n", max_num_sges);
-	}
-#endif
+				/* Allocate memory for free and doneQ's
+				 */
+				sz = sh->can_queue * sizeof(MPT_DONE_Q);
+				mem = kmalloc(sz, GFP_KERNEL);
+				if (mem == NULL)
+					goto done;
 
-	dsgprintk((KERN_INFO MYNAM ": SG: %x     sges_left = %d (initially)\n",
-		   my_idx, sges_left));
+				memset(mem, 0xFF, sz);
+				hd->memQ = mem;
 
-	chain_offset = 0;
-	if (sges_left > (sge_spill1+1)) {
-#if 0
-		chain_offset = 0x1E;
-#endif
-		chain_offset = (frm_sz - 8) / 4;
-	}
+				/* Initialize the free, done and pending Qs.
+				 */
+				Q_INIT(&hd->freeQ, MPT_DONE_Q);
+				Q_INIT(&hd->doneQ, MPT_DONE_Q);
+				Q_INIT(&hd->pendingQ, MPT_DONE_Q);
+				spin_lock_init(&hd->freedoneQlock);
+
+				mem = hd->memQ;
+				for (ii=0; ii < sh->can_queue; ii++) {
+					freedoneQ = (MPT_DONE_Q *) mem;
+					Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q);
+					mem += sizeof(MPT_DONE_Q);
+				}
 
-	pScsiReq->TargetID = SCpnt->target;
-	pScsiReq->Bus = hd->port;
-	pScsiReq->ChainOffset = chain_offset;
-	pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
-	pScsiReq->CDBLength = SCpnt->cmd_len;
+				/* Initialize this Scsi_Host
+				 * internal task Q.
+				 */
+				Q_INIT(&hd->taskQ, MPT_FRAME_HDR);
+				hd->taskQcnt = 0;
 
-/* We have 256 bytes alloc'd per IO; let's use it. */
-/*	pScsiReq->SenseBufferLength = SNS_LEN(SCpnt);	*/
-	pScsiReq->SenseBufferLength = 255;
+				/* Allocate memory for the device structures.
+				 * A non-Null pointer at an offset
+				 * indicates a device exists.
+				 * max_id = 1 + maximum id (hosts.h)
+				 */
+				sz = sh->max_id * sizeof(void *);
+				mem = kmalloc(sz, GFP_KERNEL);
+				if (mem == NULL)
+					goto done;
 
-	pScsiReq->Reserved = 0;
-	pScsiReq->MsgFlags = 0;
-	pScsiReq->LUN[0] = 0;
-	pScsiReq->LUN[1] = SCpnt->lun;
-	pScsiReq->LUN[2] = 0;
-	pScsiReq->LUN[3] = 0;
-	pScsiReq->LUN[4] = 0;
-	pScsiReq->LUN[5] = 0;
-	pScsiReq->LUN[6] = 0;
-	pScsiReq->LUN[7] = 0;
-	pScsiReq->Control = cpu_to_le32(scsictl);
+				memset(mem, 0, sz);
+				hd->Targets = (VirtDevice **) mem;
 
-	/*
-	 *  Write SCSI CDB into the message
-	 */
-	for (i = 0; i < 12; i++)
-		pScsiReq->CDB[i] = SCpnt->cmnd[i];
-	for (i = 12; i < 16; i++)
-		pScsiReq->CDB[i] = 0;
+				dprintk((KERN_INFO "  Targets @ %p, sz=%d\n", hd->Targets, sz));
 
-	/* DataLength */
-	pScsiReq->DataLength = cpu_to_le32(len);
 
-	/* SenseBuffer low address */
-	pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_pool_dma + (my_idx * 256));
+				/* Clear the TM flags
+				 */
+				hd->tmPending = 0;
+				hd->resetPending = 0;
+				hd->abortSCpnt = NULL;
+				hd->tmPtr = NULL;
+				hd->numTMrequests = 0;
+
+				/* Clear the pointer used to store
+				 * single-threaded commands, i.e., those
+				 * issued during a bus scan, dv and
+				 * configuration pages.
+				 */
+				hd->cmdPtr = NULL;
 
-	mptr = (u32 *) &pScsiReq->SGL;
+				/* Attach the SCSI Host to the IOC structure
+				 */
+				this->sh = sh;
 
-	/*
-	 *  Now fill in the SGList...
-	 *  NOTES: For 128 byte req_sz, we can hold up to 10 simple SGE's
-	 *  in the remaining request frame.  We -could- do unlimited chains
-	 *  but each chain buffer can only be req_sz bytes in size, and
-	 *  we lose one SGE whenever we chain.
-	 *  For 128 req_sz, we can hold up to 16 SGE's per chain buffer.
-	 *  For practical reasons, limit ourselves to 1 overflow chain buffer;
-	 *  giving us 9 + 16 == 25 SGE's max.
-	 *  At 4 Kb per SGE, that yields 100 Kb max transfer.
-	 *
-	 *  (This code needs to be completely changed when/if 64-bit DMA
-	 *   addressing is used, since we will be able to fit much less than
-	 *   10 embedded SG entries. -DaveM)
-	 */
-	if (sges_left) {
-		struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
-		u32  v1, v2;
-		int  sge_spill2;
-		int  sge_cur_spill;
-		int  sgCnt;
-		u8  *pSgBucket;
-		int  chain_sz;
-
-		len = 0;
-
-		/*	sge_spill2 = 15;
-		 *  spill2: for req_sz == 128 (128/8==16 SGEs max, first time!), --> use 15
-		 *  spill2: for req_sz ==  96 ( 96/8==12 SGEs max, first time!), --> use 11
-		 */
-		sge_spill2 = frm_sz / 8 - 1;
-		dsgprintk((KERN_INFO MYNAM ": SG: %x     spill2 = %d\n",
-			   my_idx, sge_spill2));
-
-		pSgBucket = NULL;
-		sgCnt = 0;
-		sge_cur_spill = sge_spill1;
-		while (sges_left) {
-#if 0
-			if (sg_dma_len(sg) > max_sgent_len) {
-				max_sgent_len = sg_dma_len(sg);
-				printk(KERN_INFO MYNAM ": MPT_MaxSgentLen = %d\n", max_sgent_len);
-			}
-#endif
-			/* Write one simple SGE */
-			v1 = sgdir | 0x10000000 | sg_dma_len(sg);
-			len += sg_dma_len(sg);
-			v2 = sg_dma_address(sg);
-			dsgprintk((KERN_INFO MYNAM ": SG: %x     Writing SGE @%p: %08x %08x, sges_left=%d\n",
-				   my_idx, mptr, v1, v2, sges_left));
-			*mptr++ = cpu_to_le32(v1);
-			*mptr++ = cpu_to_le32(v2);
-			sg++;
-			sgCnt++;
-
-			if (--sges_left == 0) {
-				/* re-write 1st word of previous SGE with SIMPLE,
-				 * LE, EOB, and EOL bits!
-				 */
-				v1 = 0xD1000000 | sgdir | sg_dma_len(sg-1);
-				dsgprintk((KERN_INFO MYNAM ": SG: %x (re)Writing SGE @%p: %08x (VERY LAST SGE!)\n",
-					   my_idx, mptr-2, v1));
-				*(mptr - 2) = cpu_to_le32(v1);
-			} else {
-				if ((sges_left > 1) && ((sgCnt % sge_cur_spill) == 0)) {
-					dsgprintk((KERN_INFO MYNAM ": SG: %x     SG spill at modulo 0!\n",
-						   my_idx));
-
-					/* Fixup previous SGE with LE bit! */
-					v1 = sgdir | 0x90000000 | sg_dma_len(sg-1);
-					dsgprintk((KERN_INFO MYNAM ": SG: %x (re)Writing SGE @%p: %08x (LAST BUCKET SGE!)\n",
-						   my_idx, mptr-2, v1));
-					*(mptr - 2) = cpu_to_le32(v1);
-
-					chain_offset = 0;
-					/* Going to need another chain? */
-					if (sges_left > (sge_spill2+1)) {
-#if 0
-						chain_offset = 0x1E;
+				/* Initialize this SCSI Hosts' timers
+				 * To use, set the timer expires field
+				 * and add_timer
+				 */
+				init_timer(&hd->timer);
+				hd->timer.data = (unsigned long) hd;
+				hd->timer.function = mptscsih_timer_expired;
+
+				init_timer(&hd->TMtimer);
+				hd->TMtimer.data = (unsigned long) hd;
+				hd->TMtimer.function = mptscsih_taskmgmt_timeout;
+				hd->qtag_tick = jiffies;
+
+				/* Moved Earlier Pam D */
+				/* this->sh = sh;	*/
+
+				if (hd->is_spi) {
+					/* Update with the driver setup
+					 * values.
+					 */
+					if (hd->ioc->spi_data.maxBusWidth > driver_setup.max_width)
+						hd->ioc->spi_data.maxBusWidth = driver_setup.max_width;
+					if (hd->ioc->spi_data.minSyncFactor < driver_setup.min_sync_fac)
+						hd->ioc->spi_data.minSyncFactor = driver_setup.min_sync_fac;
+
+					if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC)
+						hd->ioc->spi_data.maxSyncOffset = 0;
+
+					hd->negoNvram = 0;
+#ifdef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+					hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
 #endif
-						chain_offset = (frm_sz - 8) / 4;
-						chain_sz = frm_sz;
-					} else {
-						chain_sz = sges_left * 8;
-					}
-
-					/* write chain SGE at mptr. */
-					v1 = 0x30000000 | chain_offset<<16 | chain_sz;
-					if (pSgBucket == NULL) {
-						pSgBucket = hd->SgHunks
-							+ (my_idx * frm_sz * MPT_SG_BUCKETS_PER_HUNK);
-					} else {
-						pSgBucket += frm_sz;
-					}
-					v2 = (hd->SgHunksDMA +
-					      ((u8 *)pSgBucket - (u8 *)hd->SgHunks));
-					dsgprintk((KERN_INFO MYNAM ": SG: %x     Writing SGE @%p: %08x %08x (CHAIN!)\n",
-						   my_idx, mptr, v1, v2));
-					*(mptr++) = cpu_to_le32(v1);
-					*(mptr) = cpu_to_le32(v2);
+					if (driver_setup.dv == 0)
+						hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
 
-					mptr = (u32 *) pSgBucket;
-					sgCnt = 0;
-					sge_cur_spill = sge_spill2;
-				}
-			}
-		}
-	} else {
-		dsgprintk((KERN_INFO MYNAM ": SG: non-SG for %p, len=%d\n",
-			   SCpnt, SCpnt->request_bufflen));
+					hd->ioc->spi_data.forceDv = 0;
+					for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
+						hd->ioc->spi_data.dvStatus[ii] = MPT_SCSICFG_NEGOTIATE;
 
-		if (len > 0) {
-			dma_addr_t buf_dma_addr;
 
-			buf_dma_addr = (dma_addr_t) (unsigned long)SCpnt->SCp.ptr;
-			*(mptr++) = cpu_to_le32(0xD1000000|sgdir|SCpnt->request_bufflen);
-			*(mptr++) = cpu_to_le32(buf_dma_addr);
-		}
-	}
+					ddvprintk((MYIOC_s_INFO_FMT
+						"dv %x width %x factor %x \n",
+						hd->ioc->name, driver_setup.dv,
+						driver_setup.max_width,
+						driver_setup.min_sync_fac));
 
-#ifdef MPT_DEBUG
-	/* if (SCpnt->request_bufflen > max_xfer) */
-	if (len > max_xfer) {
-		max_xfer = len;
-		dprintk((KERN_INFO MYNAM ": MPT_MaxXfer = %d\n", max_xfer));
-	}
-#endif
+				}
 
-	hd->ScsiLookup[my_idx] = SCpnt;
+				mpt_scsi_hosts++;
+			}
 
-	/* Main banana... */
-	mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
+		}	/* for each adapter port */
 
-	atomic_inc(&queue_depth);
-	if (atomic_read(&queue_depth) > max_qd) {
-		max_qd = atomic_read(&queue_depth);
-		dprintk((KERN_INFO MYNAM ": Queue depth now %d.\n", max_qd));
+		this = mpt_adapter_find_next(this);
 	}
 
-	dmfprintk((KERN_INFO MYNAM ": Issued SCSI cmd (%p)\n", SCpnt));
+done:
+	if (mpt_scsi_hosts > 0)
+		register_reboot_notifier(&mptscsih_notifier);
 
-	return 0;
+	return mpt_scsi_hosts;
 }
 
-#ifdef MPT_SCSI_USE_NEW_EH		/* { */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
-    mptscsih_abort
-    Returns: 0=SUCCESS, else FAILED
-*/
+    static char *info_kbuf = NULL;
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_abort - Abort linux Scsi_Cmnd routine, new_eh variant
- *	@SCpnt: Pointer to Scsi_Cmnd structure, IO to be aborted
+ *	mptscsih_release - Unregister SCSI host from linux scsi mid-layer
+ *	@host: Pointer to Scsi_Host structure
  *
- *	(linux Scsi_Host_Template.eh_abort_handler routine)
+ *	(linux Scsi_Host_Template.release routine)
+ *	This routine releases all resources associated with the SCSI host
+ *	adapter.
  *
- *	Returns SUCCESS or FAILED.  
+ *	Returns 0 for success.
  */
 int
-mptscsih_abort(Scsi_Cmnd * SCpnt)
+mptscsih_release(struct Scsi_Host *host)
 {
-	MPT_FRAME_HDR	*mf;
-	SCSITaskMgmt_t	*pScsiTm;
 	MPT_SCSI_HOST	*hd;
-	u32		*msg;
-	u32		 ctx2abort;
-	int		 i;
+	int 		 count;
 	unsigned long	 flags;
 
-	printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO (=%p)\n", SCpnt);
-	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
+	hd = (MPT_SCSI_HOST *) host->hostdata;
 
-	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
+#ifndef MPT_SCSI_USE_NEW_EH
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+	spin_lock_irqsave(&dvtaskQ_lock, flags);
+	dvtaskQ_release = 1;
+	spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+#endif
 
-	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
-/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/
-		SCpnt->result = STS_BUSY;
-		SCpnt->scsi_done(SCpnt);
-		return FAILED;
+	spin_lock_irqsave(&mytaskQ_lock, flags);
+	if (mytaskQ_bh_active) {
+		count = 10 * HZ;
+
+		spin_unlock_irqrestore(&mytaskQ_lock, flags);
+		dprintk((KERN_INFO MYNAM ": Info: Zapping TaskMgmt thread!\n"));
+		clean_taskQ(hd);
+
+		while(mytaskQ_bh_active && --count) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		}
+		if (!count)
+			printk(KERN_ERR MYNAM ": ERROR - TaskMgmt thread still active!\n");
 	}
+	spin_unlock_irqrestore(&mytaskQ_lock, flags);
+#endif
 
-	pScsiTm = (SCSITaskMgmt_t *) mf;
-	msg = (u32 *) mf;
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+	/* Check DV thread active */
+	count = 10 * HZ;
+	spin_lock_irqsave(&dvtaskQ_lock, flags);
+	while(dvtaskQ_active && --count) {
+		spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+		spin_lock_irqsave(&dvtaskQ_lock, flags);
+	}
+	spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+	if (!count)
+		printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
+#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
+	else
+		printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
+#endif
+#endif
 
-	pScsiTm->TargetID = SCpnt->target;
-	pScsiTm->Bus = hd->port;
-	pScsiTm->ChainOffset = 0;
-	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
+	unregister_reboot_notifier(&mptscsih_notifier);
 
-	pScsiTm->Reserved = 0;
-	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK;
-	pScsiTm->Reserved1 = 0;
-	pScsiTm->MsgFlags = 0;
+	if (hd != NULL) {
+		int sz1, sz2, sz3, sztarget=0;
+		int szchain = 0;
+		int szQ = 0;
+		int scale;
 
-	for (i = 0; i < 8; i++) {
-		u8 val = 0;
-		if (i == 1)
-			val = SCpnt->lun;
-		pScsiTm->LUN[i] = val;
-	}
+		/* Synchronize disk caches
+		 */
+		(void) mptscsih_synchronize_cache(hd, 0);
 
-	for (i = 0; i < 7; i++)
-		pScsiTm->Reserved2[i] = 0;
+		sz1 = sz2 = sz3 = 0;
 
-	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
-	 * (the IO to be ABORT'd)
-	 *
-	 * NOTE: Since we do not byteswap MsgContext, we do not
-	 *	 swap it here either.  It is an opaque cookie to
-	 *	 the controller, so it does not matter. -DaveM
-	 */
-	ctx2abort = SCPNT_TO_MSGCTX(SCpnt);
-	if (ctx2abort == -1) {
-		printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#2) for SCpnt=%p\n", SCpnt);
-		SCpnt->result = DID_SOFT_ERROR << 16;
-		spin_lock_irqsave(&io_request_lock, flags);
-		SCpnt->scsi_done(SCpnt);
-		spin_unlock_irqrestore(&io_request_lock, flags);
-		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
-	} else {
-		dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
-		pScsiTm->TaskMsgContext = ctx2abort;
+		if (hd->ioc->req_sz <= 64)
+			scale = MPT_SG_REQ_64_SCALE;
+		else if (hd->ioc->req_sz <= 96)
+			scale = MPT_SG_REQ_96_SCALE;
+		else
+			scale = MPT_SG_REQ_128_SCALE;
 
+		if (hd->ScsiLookup != NULL) {
+			sz1 = hd->ioc->req_depth * sizeof(void *);
+			kfree(hd->ScsiLookup);
+			hd->ScsiLookup = NULL;
+		}
 
-		/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
-			mpt_put_msg_frame(hd->ioc->id, mf);
-		*/
-		if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
-					sizeof(SCSITaskMgmt_t), msg))
-		    != 0) {
-			printk(KERN_WARNING MYNAM
-					": WARNING[2] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
-					i, mf, SCpnt);
-			SCpnt->result = DID_SOFT_ERROR << 16;
-			spin_lock_irqsave(&io_request_lock, flags);
-			SCpnt->scsi_done(SCpnt);
-			spin_unlock_irqrestore(&io_request_lock, flags);
-			mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+		if (hd->ReqToChain != NULL) {
+			szchain += scale * hd->ioc->req_depth * sizeof(int);
+			kfree(hd->ReqToChain);
+			hd->ReqToChain = NULL;
 		}
-	}
 
-	//return SUCCESS;
-	return FAILED;
-}
+		if (hd->ChainToChain != NULL) {
+			szchain += scale * hd->ioc->req_depth * sizeof(int);
+			kfree(hd->ChainToChain);
+			hd->ChainToChain = NULL;
+		}
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
- *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
- *
- *	(linux Scsi_Host_Template.eh_dev_reset_handler routine)
- *
- *	Returns SUCCESS or FAILED.
- */
-int
-mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
-{
-	MPT_FRAME_HDR	*mf;
-	SCSITaskMgmt_t	*pScsiTm;
-	MPT_SCSI_HOST	*hd;
-	u32		*msg;
-	int		 i;
-	unsigned long	 flags;
+		if (hd->ChainBuffer != NULL) {
+			sz2 = scale * hd->ioc->req_depth * hd->ioc->req_sz;
+			szchain += sz2;
 
-	printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);
-	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
+			pci_free_consistent(hd->ioc->pcidev, sz2,
+				    hd->ChainBuffer, hd->ChainBufferDMA);
+			hd->ChainBuffer = NULL;
+		}
 
-	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
+		if (hd->memQ != NULL) {
+			szQ = host->can_queue * sizeof(MPT_DONE_Q);
+			kfree(hd->memQ);
+			hd->memQ = NULL;
+		}
 
-	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
-/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/
-		SCpnt->result = STS_BUSY;
-		SCpnt->scsi_done(SCpnt);
-		return FAILED;
-	}
+		if (hd->Targets != NULL) {
+			int max, ii;
 
-	pScsiTm = (SCSITaskMgmt_t *) mf;
-	msg = (u32*)mf;
+			/*
+			 * Free any target structures that were allocated.
+			 */
+			if (hd->is_spi) {
+				max = MPT_MAX_SCSI_DEVICES;
+			} else {
+				max = MPT_MAX_FC_DEVICES;
+			}
+			for (ii=0; ii < max; ii++) {
+				if (hd->Targets[ii]) {
+					kfree(hd->Targets[ii]);
+					hd->Targets[ii] = NULL;
+					sztarget += sizeof(VirtDevice);
+				}
+			}
 
-	pScsiTm->TargetID = SCpnt->target;
-	pScsiTm->Bus = hd->port;
-	pScsiTm->ChainOffset = 0;
-	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
+			/*
+			 * Free pointer array.
+			 */
+			sz3 = max * sizeof(void *);
+			kfree(hd->Targets);
+			hd->Targets = NULL;
+		}
 
-	pScsiTm->Reserved = 0;
-	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-	pScsiTm->Reserved1 = 0;
-	pScsiTm->MsgFlags = 0;
+		dprintk((MYIOC_s_INFO_FMT "Free'd ScsiLookup (%d), chain (%d) and Target (%d+%d) memory\n",
+				hd->ioc->name, sz1, szchain, sz3, sztarget));
+		dprintk(("Free'd done and free Q (%d) memory\n", szQ));
+	}
+	/* NULL the Scsi_Host pointer
+	 */
+	hd->ioc->sh = NULL;
+	scsi_unregister(host);
+
+	if (mpt_scsi_hosts) {
+		if (--mpt_scsi_hosts == 0) {
+			mpt_reset_deregister(ScsiDoneCtx);
+			dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
 
-	/* _TARGET_RESET goes to LUN 0 always! */
-	for (i = 0; i < 8; i++)
-		pScsiTm->LUN[i] = 0;
-
-	/* Control: No data direction, set task mgmt bit? */
-	for (i = 0; i < 7; i++)
-		pScsiTm->Reserved2[i] = 0;
+			mpt_event_deregister(ScsiDoneCtx);
+			dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));
 
-	pScsiTm->TaskMsgContext = cpu_to_le32(0);
+			mpt_deregister(ScsiScanDvCtx);
+			mpt_deregister(ScsiTaskCtx);
+			mpt_deregister(ScsiDoneCtx);
 
-/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
-	mpt_put_msg_frame(hd->ioc->id, mf);
-*/
-/* FIXME!  Check return status! */
-	if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
-				sizeof(SCSITaskMgmt_t), msg))
-	    != 0) {
-		printk(KERN_WARNING MYNAM
-				": WARNING[3] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
-				i, mf, SCpnt);
-		SCpnt->result = DID_SOFT_ERROR << 16;
-		spin_lock_irqsave(&io_request_lock, flags);
-		SCpnt->scsi_done(SCpnt);
-		spin_unlock_irqrestore(&io_request_lock, flags);
-		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+			if (info_kbuf != NULL)
+				kfree(info_kbuf);
+		}
 	}
 
-	//return SUCCESS;
-	return FAILED;
+	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
- *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
+ *	mptscsih_halt - Process the reboot notification
+ *	@nb: Pointer to a struct notifier_block (ignored)
+ *	@event: event (SYS_HALT, SYS_RESTART, SYS_POWER_OFF)
+ *	@buf: Pointer to a data buffer (ignored)
  *
- *	(linux Scsi_Host_Template.eh_bus_reset_handler routine)
+ *	This routine called if a system shutdown or reboot is to occur.
  *
- *	Returns SUCCESS or FAILED.
+ *	Return NOTIFY_DONE if this is something other than a reboot message.
+ *		NOTIFY_OK if this is a reboot message.
  */
-int
-mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
+static int
+mptscsih_halt(struct notifier_block *nb, ulong event, void *buf)
 {
-	MPT_FRAME_HDR	*mf;
-	SCSITaskMgmt_t	*pScsiTm;
-	MPT_SCSI_HOST	*hd;
-	u32		*msg;
-	int		 i;
-	unsigned long	 flags;
-
-	printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);
-	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
+	MPT_ADAPTER *ioc = NULL;
+	MPT_SCSI_HOST *hd = NULL;
 
-	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
+	/* Ignore all messages other than reboot message
+	 */
+	if ((event != SYS_RESTART) && (event != SYS_HALT)
+		&& (event != SYS_POWER_OFF))
+		return (NOTIFY_DONE);
 
-	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
-/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/
-		SCpnt->result = STS_BUSY;
-		SCpnt->scsi_done(SCpnt);
-		return FAILED;
+	for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc =	mpt_adapter_find_next(ioc)) {
+		/* Flush the cache of this adapter
+		 */
+		if (ioc->sh) {
+			hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+			if (hd) {
+				mptscsih_synchronize_cache(hd, 0);
+			}
+		}
 	}
 
-	pScsiTm = (SCSITaskMgmt_t *) mf;
-	msg = (u32 *) mf;
-
-	pScsiTm->TargetID = SCpnt->target;
-	pScsiTm->Bus = hd->port;
-	pScsiTm->ChainOffset = 0;
-	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
+	unregister_reboot_notifier(&mptscsih_notifier);
+	return NOTIFY_OK;
+}
 
-	pScsiTm->Reserved = 0;
-	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
-	pScsiTm->Reserved1 = 0;
-	pScsiTm->MsgFlags = 0;
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_info - Return information about MPT adapter
+ *	@SChost: Pointer to Scsi_Host structure
+ *
+ *	(linux Scsi_Host_Template.info routine)
+ *
+ *	Returns pointer to buffer where information was written.
+ */
+const char *
+mptscsih_info(struct Scsi_Host *SChost)
+{
+	MPT_SCSI_HOST *h;
+	int size = 0;
 
-	for (i = 0; i < 8; i++)
-		pScsiTm->LUN[i] = 0;
+	if (info_kbuf == NULL)
+		if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
+			return info_kbuf;
 
-	/* Control: No data direction, set task mgmt bit? */
-	for (i = 0; i < 7; i++)
-		pScsiTm->Reserved2[i] = 0;
+	h = (MPT_SCSI_HOST *)SChost->hostdata;
+	info_kbuf[0] = '\0';
+	mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
+	info_kbuf[size-1] = '\0';
 
-	pScsiTm->TaskMsgContext = cpu_to_le32(0);
+	return info_kbuf;
+}
 
-/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
-	mpt_put_msg_frame(hd->ioc->id, mf);
-*/
-/* FIXME!  Check return status! */
-	if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
-				sizeof(SCSITaskMgmt_t), msg))
-	    != 0) {
-		printk(KERN_WARNING MYNAM
-				": WARNING[4] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
-				i, mf, SCpnt);
-		SCpnt->result = DID_SOFT_ERROR << 16;
-		spin_lock_irqsave(&io_request_lock, flags);
-		SCpnt->scsi_done(SCpnt);
-		spin_unlock_irqrestore(&io_request_lock, flags);
-		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
-	}
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+	static int max_qd = 1;
+#if 0
+static int index_log[128];
+static int index_ent = 0;
+static __inline__ void ADD_INDEX_LOG(int req_ent)
+{
+	int i = index_ent++;
 
-	return SUCCESS;
+	index_log[i & (128 - 1)] = req_ent;
 }
+#else
+#define ADD_INDEX_LOG(req_ent)	do { } while(0)
+#endif
+
+#ifdef	DROP_TEST
+#define DROP_IOC	1	/* IOC to force failures */
+#define DROP_TARGET	3	/* Target ID to force failures */
+#define	DROP_THIS_CMD	10000	/* iteration to drop command */
+static int dropCounter = 0;
+static int dropTestOK = 0;	/* num did good */
+static int dropTestBad = 0;	/* num did bad */
+static int dropTestNum = 0;	/* total = good + bad + incomplete */
+static int numTotCmds = 0;
+static MPT_FRAME_HDR *dropMfPtr = NULL;
+static int numTMrequested = 0;
+#endif
 
-#if 0	/* { */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_host_reset - Perform a SCSI host adapter RESET!
- *	new_eh variant
- *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
+/*
+ *	mptscsih_put_msgframe - Wrapper routine to post message frame to F/W.
+ *	@context: Call back context (ScsiDoneCtx, ScsiScanDvCtx) 
+ *	@id: IOC id number 
+ *	@mf: Pointer to message frame 
  *
- *	(linux Scsi_Host_Template.eh_host_reset_handler routine)
+ *	Handles the call to mptbase for posting request and queue depth 
+ *	tracking.
  *
- *	Returns SUCCESS or FAILED.
+ *	Returns none.
  */
-int
-mptscsih_host_reset(Scsi_Cmnd * SCpnt)
+static void
+mptscsih_put_msgframe(int context, int id, MPT_FRAME_HDR *mf)
 {
-	return FAILED;
+	/* Main banana... */
+	atomic_inc(&queue_depth);
+	if (atomic_read(&queue_depth) > max_qd) {
+		max_qd = atomic_read(&queue_depth);
+		dprintk((KERN_INFO MYNAM ": Queue depth now %d.\n", max_qd));
+	}
+
+	mpt_put_msg_frame(context, id, mf);
+
+	return;
 }
-#endif	/* } */
 
-#else		/* MPT_SCSI old EH stuff... */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_old_abort - Abort linux Scsi_Cmnd routine
- *	@SCpnt: Pointer to Scsi_Cmnd structure, IO to be aborted
+ *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
+ *	@SCpnt: Pointer to Scsi_Cmnd structure
+ *	@done: Pointer SCSI mid-layer IO completion function
  *
- *	(linux Scsi_Host_Template.abort routine)
+ *	(linux Scsi_Host_Template.queuecommand routine)
+ *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
+ *	from a linux Scsi_Cmnd request and send it to the IOC.
  *
- *	Returns SCSI_ABORT_{SUCCESS,BUSY,PENDING}.
+ *	Returns 0. (rtn value discarded by linux scsi mid-layer)
  */
 int
-mptscsih_old_abort(Scsi_Cmnd *SCpnt)
+mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
 	MPT_SCSI_HOST		*hd;
 	MPT_FRAME_HDR		*mf;
-	struct tq_struct	*ptaskfoo;
+	SCSIIORequest_t		*pScsiReq;
+	VirtDevice		*pTarget;
+	MPT_DONE_Q		*buffer = NULL;
 	unsigned long		 flags;
+	int	 target;
+	int	 lun;
+	int	 datadir;
+	u32	 datalen;
+	u32	 scsictl;
+	u32	 scsidir;
+	u32	 qtag;
+	u32	 cmd_len;
+	int	 my_idx;
+	int	 ii;
+	int	 rc;
+	int	 did_errcode;
+	int	 issueCmd;
 
-	printk(KERN_WARNING MYNAM ": Scheduling _ABORT SCSI IO (=%p)\n", SCpnt);
-	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
+	did_errcode = 0;
+	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
+	target = SCpnt->target;
+	lun = SCpnt->lun;
+	SCpnt->scsi_done = done;
 
-	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
-		SCpnt->result = DID_ABORT << 16;
-		SCpnt->scsi_done(SCpnt);
-		return SCSI_ABORT_SUCCESS;
-	}
+	pTarget = hd->Targets[target];
 
-	/*
-	 *  Check to see if there's already an ABORT queued for this guy.
+	dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
+			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
+
+	/* 20000617 -sralston
+	 *  GRRRRR...  Shouldn't have to do this but...
+	 *  Do explicit check for REQUEST_SENSE and cached SenseData.
+	 *  If yes, return cached SenseData.
 	 */
-	mf = search_taskQ(0,SCpnt,MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
-	if (mf != NULL) {
-		return SCSI_ABORT_PENDING;
+	if (SCpnt->cmnd[0] == REQUEST_SENSE) {
+		u8 *dest = NULL;
+		int sz;
+
+		if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_VALID_SENSE)) {
+			pTarget->tflags &= ~MPT_TARGET_FLAGS_VALID_SENSE;	//sjr-moved-here
+			if (!SCpnt->use_sg) {
+				dest = SCpnt->request_buffer;
+			} else {
+				struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
+				if (sg)
+					dest = (u8 *)(ulong)sg_dma_address(sg);
+			}
+
+			if (dest) {
+				sz = MIN (SCSI_STD_SENSE_BYTES, SCpnt->request_bufflen);
+				memcpy(dest, pTarget->sense, sz);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+				SCpnt->resid = SCpnt->request_bufflen - sz;
+#endif
+				SCpnt->result = 0;
+				SCpnt->scsi_done(SCpnt);
+
+				//sjr-moved-up//pTarget->tflags &= ~MPT_TARGET_FLAGS_VALID_SENSE;
+
+				return 0;
+			}
+		}
 	}
 
-	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
-/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/
-		SCpnt->result = STS_BUSY;
-		SCpnt->scsi_done(SCpnt);
-		return SCSI_ABORT_BUSY;
+	if (hd->resetPending) {
+		/* Prevent new commands from being issued
+		 * while reloading the FW.
+		 */
+		did_errcode = 1;
+		goto did_error;
 	}
 
 	/*
-	 *  Add ourselves to (end of) mpt_scsih_taskQ.
-	 *  Check to see if our _bh is running.  If NOT, schedule it.
+	 *  Put together a MPT SCSI request...
 	 */
-	dslprintk((KERN_INFO MYNAM ": spinlock#2\n"));
-	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-	Q_ADD_TAIL(&mpt_scsih_taskQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
-	mpt_scsih_taskQ_cnt++;
-	/* Yikes - linkage! */
-/*	SCpnt->host_scribble = (unsigned char *)mf;	*/
-	mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK;
-	mf->u.frame.linkage.argp1 = SCpnt;
-	if (! mpt_scsih_taskQ_bh_active) {
-		mpt_scsih_taskQ_bh_active = 1;
-		/*
-		 *  Oh how cute, no alloc/free/mgmt needed if we use
-		 *  (bottom/unused portion of) MPT request frame.
-		 */
-		ptaskfoo = (struct tq_struct *) ((u8*)mf + hd->ioc->req_sz - sizeof(*ptaskfoo));
-		ptaskfoo->sync = 0;
-		ptaskfoo->routine = mptscsih_taskmgmt_bh;
-		ptaskfoo->data = SCpnt;
-
-		SCHEDULE_TASK(ptaskfoo);
+	if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc->id)) == NULL) {
+		dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
+				hd->ioc->name));
+		did_errcode = 2;
+		goto did_error;
 	}
-	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
-
-	return SCSI_ABORT_PENDING;
-}
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_old_reset - Perform a SCSI BUS_RESET!
- *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
- *	@reset_flags: (not used?)
- *
- *	(linux Scsi_Host_Template.reset routine)
- *
- *	Returns SCSI_RESET_{SUCCESS,PUNT,PENDING}.
- */
-int
-mptscsih_old_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
-{
-	MPT_SCSI_HOST		*hd;
-	MPT_FRAME_HDR		*mf;
-	struct tq_struct	*ptaskfoo;
-	unsigned long		 flags;
+	pScsiReq = (SCSIIORequest_t *) mf;
 
-	printk(KERN_WARNING MYNAM ": Scheduling _BUS_RESET (=%p)\n", SCpnt);
-	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
+	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
 
-	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
-		SCpnt->result = DID_RESET << 16;
-		SCpnt->scsi_done(SCpnt);
-		return SCSI_RESET_SUCCESS;
-	}
+	ADD_INDEX_LOG(my_idx);
 
 	/*
-	 *  Check to see if there's already a BUS_RESET queued for this guy.
+	 *  The scsi layer should be handling this stuff
+	 *  (In 2.3.x it does -DaveM)
 	 */
-	mf = search_taskQ(0,SCpnt,MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS);
-	if (mf != NULL) {
-		return SCSI_RESET_PENDING;
-	}
 
-	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
-/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/
-		SCpnt->result = STS_BUSY;
-		SCpnt->scsi_done(SCpnt);
-		return SCSI_RESET_PUNT;
+	/*  BUG FIX!  19991030 -sralston
+	 *    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
+	 *    Seems we may receive a buffer (datalen>0) even when there
+	 *    will be no data transfer!  GRRRRR...
+	 */
+	datadir = mptscsih_io_direction(SCpnt);
+	if (datadir < 0) {
+		datalen = SCpnt->request_bufflen;
+		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
+	} else if (datadir > 0) {
+		datalen = SCpnt->request_bufflen;
+		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
+	} else {
+		datalen = 0;
+		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
 	}
 
-	/*
-	 *  Add ourselves to (end of) mpt_scsih_taskQ.
-	 *  Check to see if our _bh is running.  If NOT, schedule it.
+	/* Default to untagged. Once a target structure has been allocated,
+	 * use the Inquiry data to determine if device supports tagged.
 	 */
-	dslprintk((KERN_INFO MYNAM ": spinlock#3\n"));
-	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-	Q_ADD_TAIL(&mpt_scsih_taskQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
-	mpt_scsih_taskQ_cnt++;
-	/* Yikes - linkage! */
-/*	SCpnt->host_scribble = (unsigned char *)mf;	*/
-	mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
-	mf->u.frame.linkage.argp1 = SCpnt;
-	if (! mpt_scsih_taskQ_bh_active) {
-		mpt_scsih_taskQ_bh_active = 1;
+	qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
+	if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+			&& (SCpnt->device->tagged_supported)) {
 		/*
-		 *  Oh how cute, no alloc/free/mgmt needed if we use
-		 *  (bottom/unused portion of) MPT request frame.
+		 *  Some drives are too stupid to handle fairness issues
+		 *  with tagged queueing. We throw in the odd ordered
+		 *  tag to stop them starving themselves.
 		 */
-		ptaskfoo = (struct tq_struct *) ((u8*)mf + hd->ioc->req_sz - sizeof(*ptaskfoo));
-		ptaskfoo->sync = 0;
-		ptaskfoo->routine = mptscsih_taskmgmt_bh;
-		ptaskfoo->data = SCpnt;
-
-		SCHEDULE_TASK(ptaskfoo);
+		if ((jiffies - hd->qtag_tick) > (5*HZ)) {
+			qtag = MPI_SCSIIO_CONTROL_ORDEREDQ;
+			hd->qtag_tick = jiffies;
+		}
+		else
+			qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
 	}
-	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
+	scsictl = scsidir | qtag;
 
-	return SCSI_RESET_PENDING;
-}
+	/* Use the above information to set up the message frame
+	 */
+	pScsiReq->TargetID = target;
+	pScsiReq->Bus = hd->port;
+	pScsiReq->ChainOffset = 0;
+	pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
+	pScsiReq->CDBLength = SCpnt->cmd_len;
+	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
+	pScsiReq->Reserved = 0;
+	pScsiReq->MsgFlags = MPT_SCSIIO_MSG_FLAGS;
+	pScsiReq->LUN[0] = 0;
+	pScsiReq->LUN[1] = lun;
+	pScsiReq->LUN[2] = 0;
+	pScsiReq->LUN[3] = 0;
+	pScsiReq->LUN[4] = 0;
+	pScsiReq->LUN[5] = 0;
+	pScsiReq->LUN[6] = 0;
+	pScsiReq->LUN[7] = 0;
+	pScsiReq->Control = cpu_to_le32(scsictl);
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	mptscsih_taskmgmt_bh - SCSI task mgmt bottom half handler
- *	@sc: (unused)
- *
- *	This routine (thread) is active whenever there are any outstanding
- *	SCSI task management requests for a SCSI host adapter.
- *	IMPORTANT!  This routine is scheduled therefore should never be
- *	running in ISR context.  i.e., it's safe to sleep here.
- */
-void
-mptscsih_taskmgmt_bh(void *sc)
-{
-	Scsi_Cmnd	*SCpnt;
-	MPT_FRAME_HDR	*mf;
-	SCSITaskMgmt_t	*pScsiTm;
-	MPT_SCSI_HOST	*hd;
-	u32		 ctx2abort = 0;
-	int		 i;
-	unsigned long	 flags;
-	u8		 task_type;
+	/*
+	 *  Write SCSI CDB into the message
+	 */
+	cmd_len = SCpnt->cmd_len;
+	for (ii=0; ii < cmd_len; ii++)
+		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
+	for (ii=cmd_len; ii < 16; ii++)
+		pScsiReq->CDB[ii] = 0;
 
-	dslprintk((KERN_INFO MYNAM ": spinlock#4\n"));
-	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-	mpt_scsih_taskQ_bh_active = 1;
-	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
+	/* DataLength */
+	pScsiReq->DataLength = cpu_to_le32(datalen);
 
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(HZ/4);
+	/* SenseBuffer low address */
+	pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
+					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
 
-		/*
-		 *  We MUST remove item from taskQ *before* we format the
-		 *  frame as a SCSITaskMgmt request and send it down to the IOC.
+	/* Now add the SG list
+	 * Always have a SGE even if null length.
+	 */
+	rc = SUCCESS;
+	if (datalen == 0) {
+		/* Add a NULL SGE */
+		mptscsih_AddNullSGE(pScsiReq);
+	} else {
+		/* Add a 32 or 64 bit SGE */
+		rc = mptscsih_Add32BitSGE(hd, SCpnt, pScsiReq, my_idx);
+	}
+
+
+	if (rc == SUCCESS) {
+		hd->ScsiLookup[my_idx] = SCpnt;
+		SCpnt->host_scribble = NULL;
+
+#ifdef	DROP_TEST
+		numTotCmds++;
+		/* If the IOC number and target match, increment
+		 * counter. If counter matches DROP_THIS, do not
+		 * issue command to FW to force a reset.
+		 * Save the MF pointer so we can free resources
+		 * when task mgmt completes.
 		 */
-		dslprintk((KERN_INFO MYNAM ": spinlock#5\n"));
-		spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-		if (Q_IS_EMPTY(&mpt_scsih_taskQ)) {
-			spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
-			break;
-		}
-		mf = mpt_scsih_taskQ.head;
-		Q_DEL_ITEM(&mf->u.frame.linkage);
-		mpt_scsih_taskQ_cnt--;
-		mpt_scsih_active_taskmgmt_mf = mf;
-		spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
-
-		SCpnt = (Scsi_Cmnd*)mf->u.frame.linkage.argp1;
-		if (SCpnt == NULL) {
-			printk(KERN_ERR MYNAM ": ERROR - TaskMgmt has NULL SCpnt! (%p:%p)\n", mf, SCpnt);
-			continue;
-		}
-		hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
-		pScsiTm = (SCSITaskMgmt_t *) mf;
+		if ((hd->ioc->id == DROP_IOC) && (target == DROP_TARGET)) {
+			dropCounter++;
 
-		for (i = 0; i < 8; i++) {
-			pScsiTm->LUN[i] = 0;
-		}
+			if (dropCounter == DROP_THIS_CMD) {
+				dropCounter = 0;
 
-		task_type = mf->u.frame.linkage.arg1;
-		if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
-			printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO! (mf=%p:sc=%p)\n",
-					mf, SCpnt);
-
-			/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
-			 * (the IO to be ABORT'd)
-			 *
-			 * NOTE: Since we do not byteswap MsgContext, we do not
-			 *	 swap it here either.  It is an opaque cookie to
-			 *	 the controller, so it does not matter. -DaveM
-			 */
-			ctx2abort = SCPNT_TO_MSGCTX(SCpnt);
-			if (ctx2abort == -1) {
-				printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#1) for SCpnt=%p\n", SCpnt);
-				SCpnt->result = DID_SOFT_ERROR << 16;
-				spin_lock_irqsave(&io_request_lock, flags);
-				SCpnt->scsi_done(SCpnt);
-				spin_unlock_irqrestore(&io_request_lock, flags);
-				mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
-				continue;
+				/* If global is set, then we are already
+				 * doing something - so keep issuing commands.
+				 */
+				if (dropMfPtr == NULL) {
+					dropTestNum++;
+					dropMfPtr = mf;
+					atomic_inc(&queue_depth);
+					printk(MYIOC_s_INFO_FMT
+						"Dropped SCSI cmd (%p)\n",
+						hd->ioc->name, SCpnt);
+					printk("mf (%p) req (%4x) tot cmds (%d)\n",
+						mf, my_idx, numTotCmds);
+
+					return 0;
+				}
 			}
-			pScsiTm->LUN[1] = SCpnt->lun;
 		}
-		else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
-		{
-			printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET! (against SCSI IO mf=%p:sc=%p)\n", mf, SCpnt);
-		}
-#if 0
-		else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {}
-		else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET) {}
 #endif
 
-		printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
+		/* SCSI specific processing */
+		issueCmd = 1;
+		if (hd->is_spi) {
+			int dvStatus = hd->ioc->spi_data.dvStatus[target];
+
+			if (dvStatus || hd->ioc->spi_data.forceDv) {
+
+				/* Write SDP1 on 1st I/O to this target */
+				if (dvStatus & MPT_SCSICFG_NEGOTIATE) {
+					mptscsih_writeSDP1(hd, 0, target, hd->negoNvram);
+					dvStatus &= ~MPT_SCSICFG_NEGOTIATE;
+					hd->ioc->spi_data.dvStatus[target] =  dvStatus;
+				}
 
-		pScsiTm->TargetID = SCpnt->target;
-		pScsiTm->Bus = hd->port;
-		pScsiTm->ChainOffset = 0;
-		pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+				if ((dvStatus & MPT_SCSICFG_NEED_DV) || hd->ioc->spi_data.forceDv) {
+					unsigned long lflags;
+					/* Schedule DV if necessary */
+					spin_lock_irqsave(&dvtaskQ_lock, lflags);
+					if (!dvtaskQ_active) {
+						dvtaskQ_active = 1;
+						mptscsih_dvTask.sync = 0;
+						mptscsih_dvTask.routine = mptscsih_domainValidation;
+						mptscsih_dvTask.data = (void *) hd;
 
-		pScsiTm->Reserved = 0;
-		pScsiTm->TaskType = task_type;
-		pScsiTm->Reserved1 = 0;
-		pScsiTm->MsgFlags = 0;
+						SCHEDULE_TASK(&mptscsih_dvTask);
+					}
+					hd->ioc->spi_data.forceDv = 0;
+					spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
+				}
 
-		for (i = 0; i < 7; i++)
-			pScsiTm->Reserved2[i] = 0;
+				/* Trying to do DV to this target, extend timeout.
+				 * Wait to issue intil flag is clear 
+				 */
+				if (dvStatus & MPT_SCSICFG_DV_PENDING) {
+					mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
+					issueCmd = 0;
+				}
+#endif
+			}
+		}
 
-		dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
-		pScsiTm->TaskMsgContext = ctx2abort;
+		if (issueCmd) {
+			mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+			dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p)\n",
+					hd->ioc->name, SCpnt));
+		} else {
+			ddvtprintk((MYIOC_s_INFO_FMT "Pending SCSI cmd (%p)\n",
+					hd->ioc->name, SCpnt));
+			/* Place this command on the pendingQ if possible */
+			spin_lock_irqsave(&hd->freedoneQlock, flags);
+			if (!Q_IS_EMPTY(&hd->freeQ)) {
+				buffer = hd->freeQ.head;
+				Q_DEL_ITEM(buffer);
 
-		/* Control: No data direction, set task mgmt bit? */
+				/* Save the mf pointer
+				 */
+				buffer->argp = (void *)mf;
 
-		/*
-		 *  As of MPI v0.10 this request can NOT be sent (normally)
-		 *  via FIFOs.	So we can't:
-		 *		mpt_put_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
-		 *  SCSITaskMgmt requests MUST be sent ONLY via
-		 *  Doorbell/handshake now.   :-(
-		 */
-		if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
-					sizeof(SCSITaskMgmt_t), (u32*) mf))
-		    != 0) {
-			printk(KERN_WARNING MYNAM ": WARNING[1] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt);
-			SCpnt->result = DID_SOFT_ERROR << 16;
-			spin_lock_irqsave(&io_request_lock, flags);
-			SCpnt->scsi_done(SCpnt);
-			spin_unlock_irqrestore(&io_request_lock, flags);
-			mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
-		} else {
-			/* Spin-Wait for TaskMgmt complete!!! */
-			while (mpt_scsih_active_taskmgmt_mf != NULL) {
-				current->state = TASK_INTERRUPTIBLE;
-				schedule_timeout(HZ/4);
+				/* Add to the pendingQ
+				 */
+				Q_ADD_TAIL(&hd->pendingQ.head, buffer, MPT_DONE_Q);
+				spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+			} else {
+				spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+				SCpnt->result = (DID_BUS_BUSY << 16);
+				SCpnt->scsi_done(SCpnt);
 			}
 		}
+	} else {
+		mptscsih_freeChainBuffers(hd, my_idx);
+		mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
+		did_errcode = 3;
+		goto did_error;
 	}
 
-	dslprintk((KERN_INFO MYNAM ": spinlock#6\n"));
-	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-	mpt_scsih_taskQ_bh_active = 0;
-	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
+	return 0;
 
-	return;
-}
+did_error:
+	dprintk((MYIOC_s_WARN_FMT "_qcmd did_errcode=%d (sc=%p)\n",
+			hd->ioc->name, did_errcode, SCpnt));
+	/* Just wish OS to issue a retry */
+	SCpnt->result = (DID_BUS_BUSY << 16);
+	spin_lock_irqsave(&hd->freedoneQlock, flags);
+	if (!Q_IS_EMPTY(&hd->freeQ)) {
+		buffer = hd->freeQ.head;
+		Q_DEL_ITEM(buffer);
 
-#endif		/* } */
+		/* Set the Scsi_Cmnd pointer
+		 */
+		buffer->argp = (void *)SCpnt;
+
+		/* Add to the doneQ
+		 */
+		Q_ADD_TAIL(&hd->doneQ.head, buffer, MPT_DONE_Q);
+		spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+	} else {
+		spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+		SCpnt->scsi_done(SCpnt);
+	}
+
+	return 0;
+}
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_taskmgmt_complete - Callback routine, gets registered to
- *	Fusion MPT base	driver
- *	@ioc: Pointer to MPT_ADAPTER structure
- *	@mf: Pointer to SCSI task mgmt request frame
- *	@r: Pointer to SCSI task mgmt reply frame
- *
- *	This routine is called from mptbase.c::mpt_interrupt() at the completion
- *	of any SCSI task management request.
- *	This routine is registered with the MPT (base) driver at driver
- *	load/init time via the mpt_register() API call.
+/*
+ *	mptscsih_Add32BitSGE - Add a 32Bit SGE (plus chain buffers) to the
+ *	SCSIIORequest_t Message Frame.
+ *	@hd: Pointer to MPT_SCSI_HOST structure
+ *	@SCpnt: Pointer to Scsi_Cmnd structure
+ *	@pReq: Pointer to SCSIIORequest_t structure
  *
- *	Returns 1 indicating alloc'd request frame ptr should be freed.
+ *	Returns ...
  */
 static int
-mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r)
+mptscsih_Add32BitSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt,
+				 SCSIIORequest_t *pReq, int req_idx)
 {
-	SCSITaskMgmtReply_t	*pScsiTmReply;
-	SCSITaskMgmt_t		*pScsiTmReq;
-	u8			 tmType;
-#ifndef MPT_SCSI_USE_NEW_EH
-	unsigned long		 flags;
-#endif
+	MptSge_t *psge;
+	MptChain_t  *chainSge;
+	struct scatterlist *sg;
+	int	 frm_sz;
+	int	 sges_left, sg_done;
+	int	 chain_idx = MPT_HOST_NO_CHAIN;
+	int	 sgeOffset;
+	int	 numSgeSlots, numSgeThisFrame;
+	u32	 sgflags, sgdir, len, thisxfer = 0;
+	int	 offset;
+	int	 newIndex;
+	int	 ii;
+	dma_addr_t v2;
+
+	sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
+	if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
+		sgdir = MPT_TRANSFER_HOST_TO_IOC;
+	} else {
+		sgdir = MPT_TRANSFER_IOC_TO_HOST;
+	}
 
-	dprintk((KERN_INFO MYNAM ": SCSI TaskMgmt completed mf=%p, r=%p\n",
-		 mf, r));
+	psge = (MptSge_t *) &pReq->SGL;
+	frm_sz = hd->ioc->req_sz;
 
-#ifndef MPT_SCSI_USE_NEW_EH
-	dslprintk((KERN_INFO MYNAM ": spinlock#7\n"));
-	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-	/* It better be the active one! */
-	if (mf != mpt_scsih_active_taskmgmt_mf) {
-		printk(KERN_ERR MYNAM ": ERROR! Non-active TaskMgmt (=%p) completed!\n", mf);
-		mpt_scsih_active_taskmgmt_mf = NULL;
-		spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
-		return 1;
+	/* Map the data portion, if any.
+	 * sges_left  = 0 if no data transfer.
+	 */
+	sges_left = SCpnt->use_sg;
+	if (SCpnt->use_sg) {
+		sges_left = pci_map_sg(hd->ioc->pcidev,
+			       (struct scatterlist *) SCpnt->request_buffer,
+			       SCpnt->use_sg,
+			       scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+	} else if (SCpnt->request_bufflen) {
+		dma_addr_t	 buf_dma_addr;
+		scPrivate	*my_priv;
+
+		buf_dma_addr = pci_map_single(hd->ioc->pcidev,
+				      SCpnt->request_buffer,
+				      SCpnt->request_bufflen,
+				      scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+
+		/* We hide it here for later unmap. */
+		my_priv = (scPrivate *) &SCpnt->SCp;
+		my_priv->p1 = (void *)(ulong) buf_dma_addr;
+
+		dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
+				hd->ioc->name, SCpnt, SCpnt->request_bufflen));
+
+		/* 0xD1000000 = LAST | EOB | SIMPLE | EOL */
+		psge->FlagsLength = cpu_to_le32(
+				0xD1000000|sgdir|SCpnt->request_bufflen);
+		cpu_to_leXX(buf_dma_addr, psge->Address);
+
+		return SUCCESS;
 	}
 
-#ifdef MPT_DEBUG
-	if ((mf == NULL) ||
-	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
-		printk(KERN_ERR MYNAM ": ERROR! NULL or BAD TaskMgmt ptr (=%p)!\n", mf);
-		mpt_scsih_active_taskmgmt_mf = NULL;
-		spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
-		return 1;
+	/* Handle the SG case.
+	 */
+	sg = (struct scatterlist *) SCpnt->request_buffer;
+	sg_done  = 0;
+	sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
+	chainSge = NULL;
+
+	/* Prior to entering this loop - the following must be set
+	 * current MF:  sgeOffset (bytes)
+	 *              chainSge (Null if original MF is not a chain buffer)
+	 *              sg_done (num SGE done for this MF)
+	 */
+
+nextSGEset:
+	numSgeSlots = ((frm_sz - sgeOffset) / sizeof(MptSge_t));
+	numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
+
+	sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
+
+	/* Get first (num - 1) SG elements
+	 * Skip any SG entries with a length of 0
+	 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
+	 */
+	for (ii=0; ii < (numSgeThisFrame-1); ii++) {
+		thisxfer = sg_dma_len(sg);
+		if (thisxfer == 0) {
+			sg ++; /* Get next SG element from the OS */
+			sg_done++;
+			continue;
+		}
+
+		len += thisxfer;
+		psge->FlagsLength = cpu_to_le32( sgflags | thisxfer );
+		v2 = sg_dma_address(sg);
+		cpu_to_leXX(v2, psge->Address);
+
+		sg++;		/* Get next SG element from the OS */
+		psge++;		/* Point to next SG location in this MF */
+		sgeOffset += sizeof(MptSge_t);
+		sg_done++;
 	}
-#endif
-	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
-#endif
 
-	if (r != NULL) {
-		pScsiTmReply = (SCSITaskMgmtReply_t*)r;
-		pScsiTmReq = (SCSITaskMgmt_t*)mf;
+	if (numSgeThisFrame == sges_left) {
+		/* Add last element, end of buffer and end of list flags.
+		 */
+		sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
+				MPT_SGE_FLAGS_END_OF_BUFFER |
+				MPT_SGE_FLAGS_ADDRESSING |
+				MPT_SGE_FLAGS_END_OF_LIST;
 
-		/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
-		tmType = pScsiTmReq->TaskType;
+		/* Add last SGE and set termination flags.
+		 * Note: Last SGE may have a length of 0 - which should be ok.
+		 */
+		thisxfer = sg_dma_len(sg);
+		len += thisxfer;
+
+		psge->FlagsLength = cpu_to_le32( sgflags | thisxfer );
+		v2 = sg_dma_address(sg);
+		cpu_to_leXX(v2, psge->Address);
+
+		sg_done++;
+
+		if (chainSge) {
+			/* The current buffer is a chain buffer,
+			 * but there is not another one.
+			 * Update the chain element
+			 * Offset and Length fields.
+			 */
+			chainSge->NextChainOffset = 0;
+			sgeOffset += sizeof(MptSge_t);
+			chainSge->Length = cpu_to_le16(sgeOffset);
+		} else {
+			/* The current buffer is the original MF
+			 * and there is no Chain buffer.
+			 */
+			pReq->ChainOffset = 0;
+		}
+	} else {
+		/* At least one chain buffer is needed.
+		 * Complete the first MF
+		 *  - last SGE element, set the LastElement bit
+		 *  - set ChainOffset (words) for orig MF
+		 *             (OR finish previous MF chain buffer)
+		 *  - update MFStructPtr ChainIndex
+		 *  - Populate chain element
+		 * Also
+		 * Loop until done.
+		 */
 
-		dprintk((KERN_INFO MYNAM ": TaskType = %d\n", tmType));
-		dprintk((KERN_INFO MYNAM ": TerminationCount = %d\n",
-			 le32_to_cpu(pScsiTmReply->TerminationCount)));
+		dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
+				hd->ioc->name, sg_done));
 
-		/* Error?  (anything non-zero?) */
-		if (*(u32 *)&pScsiTmReply->Reserved2[0]) {
-			dprintk((KERN_INFO MYNAM ": SCSI TaskMgmt (%d) - Oops!\n", tmType));
-			dprintk((KERN_INFO MYNAM ": IOCStatus = %04xh\n",
-				 le16_to_cpu(pScsiTmReply->IOCStatus)));
-			dprintk((KERN_INFO MYNAM ": IOCLogInfo = %08xh\n",
-				 le32_to_cpu(pScsiTmReply->IOCLogInfo)));
+		/* Set LAST_ELEMENT flag for last non-chain element
+		 * in the buffer. Since psge points at the NEXT
+		 * SGE element, go back one SGE element, update the flags
+		 * and reset the pointer. (Note: sgflags & thisxfer are already
+		 * set properly).
+		 */
+		if (sg_done) {
+			psge--;
+			sgflags = le32_to_cpu (psge->FlagsLength);
+			sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
+			psge->FlagsLength = cpu_to_le32( sgflags );
+			psge++;
+		}
+
+		if (chainSge) {
+			/* The current buffer is a chain buffer.
+			 * chainSge points to the previous Chain Element.
+			 * Update its chain element Offset and Length (must
+			 * include chain element size) fields.
+			 * Old chain element is now complete.
+			 */
+			chainSge->NextChainOffset = (u8) (sgeOffset >> 2);
+			sgeOffset += sizeof(MptSge_t);
+			chainSge->Length = cpu_to_le16(sgeOffset);
 		} else {
-			dprintk((KERN_INFO MYNAM ": SCSI TaskMgmt (%d) SUCCESS!\n", tmType));
+			/* The original MF buffer requires a chain buffer -
+			 * set the offset.
+			 * Last element in this MF is a chain element.
+			 */
+			pReq->ChainOffset = (u8) (sgeOffset >> 2);
 		}
-	}
 
-#ifndef MPT_SCSI_USE_NEW_EH
-	/*
-	 *  Signal to _bh thread that we finished.
-	 */
-	dslprintk((KERN_INFO MYNAM ": spinlock#8\n"));
-	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);
-	mpt_scsih_active_taskmgmt_mf = NULL;
-	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
-#endif
+		sges_left -= sg_done;
 
-	return 1;
+
+		/* NOTE: psge points to the beginning of the chain element
+		 * in current buffer. Get a chain buffer.
+		 */
+		if ((mptscsih_getFreeChainBuffer(hd, &newIndex)) == FAILED)
+			return FAILED;
+
+		/* Update the tracking arrays.
+		 * If chainSge == NULL, update ReqToChain, else ChainToChain
+		 */
+		if (chainSge) {
+			hd->ChainToChain[chain_idx] = newIndex;
+		} else {
+			hd->ReqToChain[req_idx] = newIndex;
+		}
+		chain_idx = newIndex;
+		offset = hd->ioc->req_sz * chain_idx;
+
+		/* Populate the chainSGE for the current buffer.
+		 * - Set chain buffer pointer to psge and fill
+		 *   out the Address and Flags fields.
+		 */
+		chainSge = (MptChain_t *) psge;
+		chainSge->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
+		cpu_to_leXX ((hd->ChainBufferDMA + offset), chainSge->Address);
+
+		dsgprintk((KERN_INFO "  Current buff @ %p (index 0x%x)",
+				psge, req_idx));
+
+		/* Start the SGE for the next buffer
+		 */
+		psge = (MptSge_t *) (hd->ChainBuffer + offset);
+		sgeOffset = 0;
+		sg_done = 0;
+
+		dsgprintk((KERN_INFO "  Chain buff @ %p (index 0x%x)\n",
+				psge, chain_idx));
+
+		/* Start the SGE for the next buffer
+		 */
+
+		goto nextSGEset;
+	}
+
+	return SUCCESS;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	This is anyones guess quite frankly.
+ *	mptscsih_AddNullSGE - Add a NULL SGE to the SCSIIORequest_t
+ *	Message Frame.
+ *	@pReq: Pointer to SCSIIORequest_t structure
  */
-
-int
-mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip)
+static void
+mptscsih_AddNullSGE(SCSIIORequest_t *pReq)
 {
-	int size;
+	MptSge_t *psge;
 
-	size = disk->capacity;
-	ip[0] = 64;				/* heads			*/
-	ip[1] = 32;				/* sectors			*/
-	if ((ip[2] = size >> 11) > 1024) {	/* cylinders, test for big disk */
-		ip[0] = 255;			/* heads			*/
-		ip[1] = 63;			/* sectors			*/
-		ip[2] = size / (255 * 63);	/* cylinders			*/
-	}
-	return 0;
+	psge = (MptSge_t *) &pReq->SGL;
+	psge->FlagsLength = cpu_to_le32(MPT_SGE_FLAGS_SSIMPLE_READ | 0);
+
+	cpu_to_leXX( (dma_addr_t) -1, psge->Address);
+
+	return;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *  Private routines...
- */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* 19991030 -sralston
- *  Return absolute SCSI data direction:
- *     1 = _DATA_OUT
- *     0 = _DIR_NONE
- *    -1 = _DATA_IN
+ *	mptscsih_getFreeChainBuffes - Function to get a free chain
+ *	from the MPT_SCSI_HOST FreeChainQ.
+ *	@hd: Pointer to the MPT_SCSI_HOST instance
+ *	@req_idx: Index of the SCSI IO request frame. (output)
+ *
+ *	return SUCCESS or FAILED
  */
 static int
-mptscsih_io_direction(Scsi_Cmnd *cmd)
+mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
 {
-	switch (cmd->cmnd[0]) {
-	/*  _DATA_OUT commands	*/
-	case WRITE_6:		case WRITE_10:		case WRITE_12:
-	case WRITE_LONG:	case WRITE_SAME:	case WRITE_BUFFER:
-	case WRITE_VERIFY:	case WRITE_VERIFY_12:
-	case COMPARE:		case COPY:		case COPY_VERIFY:
-	case SEARCH_EQUAL:	case SEARCH_HIGH:	case SEARCH_LOW:
-	case SEARCH_EQUAL_12:	case SEARCH_HIGH_12:	case SEARCH_LOW_12:
-	case MODE_SELECT:	case MODE_SELECT_10:	case LOG_SELECT:
-	case SEND_DIAGNOSTIC:	case CHANGE_DEFINITION: case UPDATE_BLOCK:
-	case SET_WINDOW:	case MEDIUM_SCAN:	case SEND_VOLUME_TAG:
-	case REASSIGN_BLOCKS:
-	case PERSISTENT_RESERVE_OUT:
-	case 0xea:
-		return 1;
+	MPT_FRAME_HDR *chainBuf = NULL;
+	unsigned long flags;
+	int rc = FAILED;
+	int chain_idx = MPT_HOST_NO_CHAIN;
 
-	/*  No data transfer commands  */
-	case SEEK_6:		case SEEK_10:
-	case RESERVE:		case RELEASE:
-	case TEST_UNIT_READY:
-	case START_STOP:
-	case ALLOW_MEDIUM_REMOVAL:
-		return 0;
+	//spin_lock_irqsave(&hd->FreeChainQlock, flags);
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	if (!Q_IS_EMPTY(&hd->FreeChainQ)) {
 
-	/*  Conditional data transfer commands	*/
-	case FORMAT_UNIT:
-		if (cmd->cmnd[1] & 0x10)	/* FmtData (data out phase)? */
-			return 1;
-		else
-			return 0;
+		int offset;
 
-	case VERIFY:
-		if (cmd->cmnd[1] & 0x02)	/* VERIFY:BYTCHK (data out phase)? */
-			return 1;
-		else
-			return 0;
+		chainBuf = hd->FreeChainQ.head;
+		Q_DEL_ITEM(&chainBuf->u.frame.linkage);
+		offset = (u8 *)chainBuf - (u8 *)hd->ChainBuffer;
+		chain_idx = offset / hd->ioc->req_sz;
+		rc = SUCCESS;
+	}
+	//spin_unlock_irqrestore(&hd->FreeChainQlock, flags);
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
 
-	case RESERVE_10:
-		if (cmd->cmnd[1] & 0x03)	/* RESERSE:{LongID|Extent} (data out phase)? */
-			return 1;
-		else
-			return 0;
 
-#if 0
-	case REZERO_UNIT:	/* (or REWIND) */
-	case SPACE:
-	case ERASE:		case ERASE_10:
-	case SYNCHRONIZE_CACHE:
-	case LOCK_UNLOCK_CACHE:
-#endif
+	*retIndex = chain_idx;
 
-	/*  Must be data _IN!  */
-	default:
-		return -1;
-	}
+	dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
+			hd->ioc->name, *retIndex, chainBuf));
+
+	return rc;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_freeChainBuffers - Function to free chain buffers associated
+ *	with a SCSI IO request
+ *	@hd: Pointer to the MPT_SCSI_HOST instance
+ *	@req_idx: Index of the SCSI IO request frame.
+ *
+ *	Called if SG chain buffer allocation fails and mptscsih callbacks.
+ *	No return.
+ */
 static void
-copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
+mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx)
 {
-	MPT_SCSI_DEV	*mpt_sdev = NULL;
-	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
-	char		 devFoo[32];
-	IO_Info_t	 thisIo;
-
-	if (sc && sc->device)
-		mpt_sdev = (MPT_SCSI_DEV*) sc->device->hostdata;
-
-	if (sense_count) {
-		u8 *sense_data;
-		int req_index;
+	MPT_FRAME_HDR *chain = NULL;
+	unsigned long flags;
+	int chain_idx;
+	int next;
 
-		/* Copy the sense received into the scsi command block. */
-		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
-		sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * 256));
-		memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
-		/* Cache SenseData for this SCSI device! */
-		if (mpt_sdev) {
-			memcpy(mpt_sdev->CachedSense.data, sense_data, sense_count);
-			mpt_sdev->sense_sz = sense_count;
-		}
-	} else {
-		dprintk((KERN_INFO MYNAM ": Hmmm... SenseData len=0! (?)\n"));
-	}
+	/* Get the first chain index and reset
+	 * tracker state.
+	 */
+	chain_idx = hd->ReqToChain[req_idx];
+	hd->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
 
+	while (chain_idx != MPT_HOST_NO_CHAIN) {
 
-	thisIo.cdbPtr = sc->cmnd;
-	thisIo.sensePtr = sc->sense_buffer;
-	thisIo.SCSIStatus = pScsiReply->SCSIStatus;
-	thisIo.DoDisplay = 1;
-	sprintf(devFoo, "ioc%d,scsi%d:%d", hd->ioc->id, sc->target, sc->lun);
-	thisIo.DevIDStr = devFoo;
-/* fubar */
-	thisIo.dataPtr = NULL;
-	thisIo.inqPtr = NULL;
-	if (sc->device) {
-		thisIo.inqPtr = sc->device->vendor-8;		/* FIXME!!! */
-	}
-	(void) mpt_ScsiHost_ErrorReport(&thisIo);
+		/* Save the next chain buffer index */
+		next = hd->ChainToChain[chain_idx];
 
-	return;
-}
+		/* Free this chain buffer and reset
+		 * tracker
+		 */
+		hd->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static u32
-SCPNT_TO_MSGCTX(Scsi_Cmnd *sc)
-{
-	MPT_SCSI_HOST *hd;
-	MPT_FRAME_HDR *mf;
-	int i;
+		chain = (MPT_FRAME_HDR *) (hd->ChainBuffer
+					+ (chain_idx * hd->ioc->req_sz));
+		//spin_lock_irqsave(&hd->FreeChainQlock, flags);
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		Q_ADD_TAIL(&hd->FreeChainQ.head,
+					&chain->u.frame.linkage, MPT_FRAME_HDR);
+		//spin_unlock_irqrestore(&hd->FreeChainQlock, flags);
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
 
-	hd = (MPT_SCSI_HOST *) sc->host->hostdata;
+		dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
+				hd->ioc->name, chain_idx));
 
-	for (i = 0; i < hd->ioc->req_depth; i++) {
-		if (hd->ScsiLookup[i] == sc) {
-			mf = MPT_INDEX_2_MFPTR(hd->ioc, i);
-			return mf->u.frame.hwhdr.msgctxu.MsgContext;
-		}
+		/* handle next */
+		chain_idx = next;
 	}
-
-	return -1;
+	return;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	Reset Handling
+ */
 
-/* see mptscsih.h */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_TMHandler - Generic handler for SCSI Task Management.
+ *	Fall through to mpt_HardResetHandler if: not operational, too many
+ *	failed TM requests or handshake failure.
+ *
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@type: Task Management type
+ *	@target: Logical Target ID for reset (if appropriate)
+ *	@lun: Logical Unit for reset (if appropriate)
+ *	@ctx2abort: Context for the task to be aborted (if appropriate)
+ *	@sleepFlag: If set, use udelay instead of schedule in handshake code.
+ *
+ *	Remark: Currently invoked from a non-interrupt thread (_bh).
+ *
+ *	Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
+ *	will be active.
+ *
+ *	Returns 0 for SUCCESS or -1 if FAILED.
+ */
+static int
+mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag)
+{
+	MPT_ADAPTER	*ioc = NULL;
+	int		 rc = -1;
+	int		 doTask = 1;
+	u32		 ioc_raw_state;
+	unsigned long	 flags;
 
-#ifdef MPT_SCSIHOST_NEED_ENTRY_EXIT_HOOKUPS
-	static Scsi_Host_Template driver_template = MPT_SCSIHOST;
-#	include "../../scsi/scsi_module.c"
+	/* If FW is being reloaded currently, return success to
+	 * the calling function.
+	 */
+	if (!hd)
+		return 0;
+
+	ioc = hd->ioc;
+	dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
+
+	if (ioc == NULL) {
+		printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
+		return 0;
+	}
+
+	// SJR - CHECKME - Can we avoid this here?
+	// (mpt_HardResetHandler has this check...)
+	spin_lock_irqsave(&ioc->diagLock, flags);
+	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
+		spin_unlock_irqrestore(&ioc->diagLock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(&ioc->diagLock, flags);
+
+	/* Do not do a Task Management if there are
+	 * too many failed TMs on this adapter.
+	 */
+	if (hd->numTMrequests > MPT_HOST_TOO_MANY_TM)
+		doTask = 0;
+
+	/* Is operational?
+	 */
+	ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
+
+#ifdef MPT_DEBUG_RESET
+	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
+		printk(MYIOC_s_WARN_FMT 
+			"TM Handler: IOC Not operational! state 0x%x Calling HardResetHandler\n", 
+			hd->ioc->name, ioc_raw_state);
+	}
 #endif
 
+	if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
+				&& !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
+
+		/* Isse the Task Mgmt request.
+		 */
+		rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, sleepFlag);
+		if (rc) {
+			printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
+		} else {
+			printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name);
+		}
+	}
+#ifdef DROP_TEST
+	numTMrequested++;
+	if (numTMrequested > 5) {
+		rc = 0;		/* set to 1 to force a hard reset */
+		numTMrequested = 0;
+	}
+#endif
+
+	if (rc) {
+		dtmprintk((MYIOC_s_INFO_FMT "Falling through to HardReset! \n",
+			 hd->ioc->name));
+		rc = mpt_HardResetHandler(hd->ioc, sleepFlag);
+	}
+
+	dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
+#ifndef MPT_SCSI_USE_NEW_EH
+	dtmprintk((MYIOC_s_INFO_FMT "TMHandler: _bh_handler state (%d) taskQ count (%d)\n",
+		ioc->name, mytaskQ_bh_active, hd->taskQcnt));
+#endif
+
+	return rc;
+}
+
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
+ *	@hd: Pointer to MPT_SCSI_HOST structure
+ *	@type: Task Management type
+ *	@target: Logical Target ID for reset (if appropriate)
+ *	@lun: Logical Unit for reset (if appropriate)
+ *	@ctx2abort: Context for the task to be aborted (if appropriate)
+ *	@sleepFlag: If set, use udelay instead of schedule in handshake code.
+ *
+ *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
+ *	or a non-interrupt thread.  In the former, must not call schedule().
+ *
+ *	Not all fields are meaningfull for all task types.
+ *
+ *	Returns 0 for SUCCESS, -999 for "no msg frames",
+ *	else other non-zero value returned.
+ */
 static int
-mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag)
 {
-	dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to SCSI host driver!\n",
-			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+	MPT_FRAME_HDR	*mf;
+	SCSITaskMgmt_t	*pScsiTm;
+	int		 ii;
+	int		 retval = 0;
 
-	if (reset_phase == MPT_IOC_PRE_RESET) {
-		/* FIXME! Do pre-reset cleanup */
-	} else {
-		/* FIXME! Do post-reset cleanup */
+	/* Return Fail to calling function if no message frames available.
+	 */
+	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
+		dtmprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
+				hd->ioc->name));
+		//return FAILED;
+		return -999;
 	}
+	dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
+			hd->ioc->name, mf));
 
-	return 1;		/* currently means nothing really */
+	/* Format the Request
+	 */
+	pScsiTm = (SCSITaskMgmt_t *) mf;
+	pScsiTm->TargetID = target;
+	pScsiTm->Bus = hd->port;
+	pScsiTm->ChainOffset = 0;
+	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
+
+	pScsiTm->Reserved = 0;
+	pScsiTm->TaskType = type;
+	pScsiTm->Reserved1 = 0;
+	pScsiTm->MsgFlags = 0;
+
+	for (ii= 0; ii < 8; ii++) {
+		pScsiTm->LUN[ii] = 0;
+	}
+	pScsiTm->LUN[1] = lun;
+
+	for (ii=0; ii < 7; ii++)
+		pScsiTm->Reserved2[ii] = 0;
+
+	pScsiTm->TaskMsgContext = ctx2abort;
+	dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt, ctx2abort (0x%08x), type (%d)\n",
+			hd->ioc->name, ctx2abort, type));
+
+	/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
+		mpt_put_msg_frame(hd->ioc->id, mf);
+	* Save the MF pointer in case the request times out.
+	*/
+	hd->tmPtr = mf;
+	hd->numTMrequests++;
+	hd->TMtimer.expires = jiffies + HZ*20;  /* 20 seconds */
+	add_timer(&hd->TMtimer);
+
+	if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+				sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag))
+	!= 0) {
+		dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!"
+			" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, hd->ioc, mf));
+		hd->numTMrequests--;
+		hd->tmPtr = NULL;
+		del_timer(&hd->TMtimer);
+		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+		return ii;
+	}
+
+	return retval;
 }
 
+#ifdef MPT_SCSI_USE_NEW_EH		/* { */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
-mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
+/**
+ *	mptscsih_abort - Abort linux Scsi_Cmnd routine, new_eh variant
+ *	@SCpnt: Pointer to Scsi_Cmnd structure, IO to be aborted
+ *
+ *	(linux Scsi_Host_Template.eh_abort_handler routine)
+ *
+ *	Returns SUCCESS or FAILED.
+ */
+int
+mptscsih_abort(Scsi_Cmnd * SCpnt)
 {
-	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
+	MPT_SCSI_HOST	*hd;
+	MPT_FRAME_HDR	*mf;
+	unsigned long	 flags;
+	u32		 ctx2abort;
+	int		 scpnt_idx;
+	u8		 type;
 
-	dprintk((KERN_INFO MYNAM ": MPT event (=%02Xh) routed to SCSI host driver!\n", event));
+	printk(KERN_WARNING MYNAM ": Attempting ABORT SCSI IO (=%p)\n", SCpnt);
+	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
-	switch (event) {
-	case MPI_EVENT_UNIT_ATTENTION:			/* 03 */
-		/* FIXME! */
-		break;
-	case MPI_EVENT_IOC_BUS_RESET:			/* 04 */
-		/* FIXME! */
-		break;
-	case MPI_EVENT_EXT_BUS_RESET:			/* 05 */
-		/* FIXME! */
-		break;
-	case MPI_EVENT_LOGOUT:				/* 09 */
-		/* FIXME! */
-		break;
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
+		SCpnt->result = DID_RESET << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return SUCCESS;
+	}
 
-		/*
-		 *  CHECKME! Don't think we need to do
-		 *  anything for these, but...
+	/* Find this command
+	 */
+	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
+		/* Cmd not found in ScsiLookup. If found in 
+		 * doneQ, delete from Q. Do OS callback.
 		 */
-	case MPI_EVENT_RESCAN:				/* 06 */
-	case MPI_EVENT_LINK_STATUS_CHANGE:		/* 07 */
-	case MPI_EVENT_LOOP_STATE_CHANGE:		/* 08 */
-		/*
-		 *  CHECKME!  Falling thru...
+		search_doneQ_for_cmd(hd, SCpnt);
+
+		SCpnt->result = DID_RESET << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return SUCCESS;
+	}
+
+	/* If this command is pended, then timeout/hang occurred
+	 * during DV. Post command and flush pending Q 
+	 * and then following up with the reset request.
+	 */
+	if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
+		mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+		post_pendingQ_commands(hd);
+	}
+
+	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
+	 * (the IO to be ABORT'd)
+	 *
+	 * NOTE: Since we do not byteswap MsgContext, we do not
+	 *	 swap it here either.  It is an opaque cookie to
+	 *	 the controller, so it does not matter. -DaveM
+	 */
+	mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
+	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
+
+	/* This thread will not exit until tmPending is cleared
+	 * FIXME - must ensure single threaded....DV conflict possible
+	 */
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	hd->tmPending = 1;
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+
+	if (hd->is_spi)
+		type = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
+	else {
+		type = MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK;
+		hd->abortSCpnt = SCpnt;
+		printk(KERN_WARNING MYNAM ": Attempting ABORT SCSI IO! (sc=%p)\n", SCpnt);
+	}
+
+	if (mptscsih_TMHandler(hd, type,
+			SCpnt->target, SCpnt->lun, ctx2abort, CAN_SLEEP) < 0) {
+
+		/* The TM request failed and the subsequent FW-reload failed!
+		 * Fatal error case.
 		 */
+		printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
+				hd->ioc->name, SCpnt);
 
-	case MPI_EVENT_NONE:				/* 00 */
-	case MPI_EVENT_LOG_DATA:			/* 01 */
-	case MPI_EVENT_STATE_CHANGE:			/* 02 */
-	case MPI_EVENT_EVENT_CHANGE:			/* 0A */
-	default:
-		dprintk((KERN_INFO MYNAM ": Ignoring event (=%02Xh)\n", event));
-		break;
+		/* If command not found, do not do callback,
+		 *  just return failed.  CHECKME 
+		 */
+		if (hd->ScsiLookup[scpnt_idx] != NULL) {
+			//atomic_dec(&queue_depth);
+			SCpnt->result = STS_BUSY;
+			spin_lock_irqsave(&io_request_lock, flags);
+			SCpnt->scsi_done(SCpnt);
+			spin_unlock_irqrestore(&io_request_lock, flags);
+		}
+
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		hd->tmPending = 0;
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
 	}
 
-	return 1;		/* currently means nothing really */
+
+	/* Spin on tmPending until we get the interrupt for this TM request.
+	 */
+	while (1) {
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		if (!hd->tmPending) {
+			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+			break;
+		}
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ/4);
+	}
+
+	return FAILED;
 }
 
-#if 0		/* { */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	scsiherr.c - Fusion MPT SCSI Host driver error handling/reporting.
+/**
+ *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
+ *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *	drivers/message/fusion/scsiherr.c
+ *	(linux Scsi_Host_Template.eh_dev_reset_handler routine)
+ *
+ *	Returns SUCCESS or FAILED.
  */
+int
+mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
+{
+	MPT_SCSI_HOST	*hd;
+	MPT_FRAME_HDR	*mf;
+	unsigned long	 flags;
+	int		 scpnt_idx;
+	u8		 type;
 
-//extern const char	**mpt_ScsiOpcodesPtr;	/* needed by mptscsih.c */
-//extern ASCQ_Table_t	 *mpt_ASCQ_TablePtr;
-//extern int		  mpt_ASCQ_TableSz;
+	printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);
+	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
-/*  Lie!  */
-#define MYNAM	"mptscsih"
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
+		SCpnt->result = DID_RESET << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return SUCCESS;
+	}
 
-#endif		/* } */
+	/* Find this command
+	 */
+	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
+		/* Cmd not found in ScsiLookup. If found in 
+		 * doneQ, delete from Q. Do OS callback.
+		 */
+		search_doneQ_for_cmd(hd, SCpnt);
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  Private data...
- */
-static ASCQ_Table_t *mptscsih_ASCQ_TablePtr;
+		SCpnt->result = DID_RESET << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return SUCCESS;
+	}
+
+	/* If this command is pended, then timeout/hang occurred
+	 * during DV. Force bus reset by posting command to F/W
+	 * and then following up with the reset request.
+	 */
+	if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
+		mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+		post_pendingQ_commands(hd);
+	}
+
+	/* This thread will not exit until tmPending is cleared
+	 */
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	hd->tmPending = 1;
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+
+	if (hd->is_spi)
+		type = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
+	else {
+		type = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
+		printk(KERN_WARNING MYNAM ": Attempting Target Reset! (sc=%p)\n", SCpnt);
+	}
+
+	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
+				SCpnt->target, 0, 0, CAN_SLEEP) < 0) {
+		/* The TM request failed and the subsequent FW-reload failed!
+		 * Fatal error case.
+		 */
+		printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
+		 		hd->ioc->name, SCpnt);
+
+		/* If command not found, do not do callback,
+		 * just returned failed. CHECKME.
+		 */
+		if (hd->ScsiLookup[scpnt_idx] != NULL) {
+			//atomic_dec(&queue_depth);
+			SCpnt->result = STS_BUSY;
+			spin_lock_irqsave(&io_request_lock, flags);
+			SCpnt->scsi_done(SCpnt);
+			spin_unlock_irqrestore(&io_request_lock, flags);
+		}
+
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		hd->tmPending = 0;
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+	}
+
+	/* Spin on tmPending until we get the interrupt for this TM request.
+	 */
+	while (1) {
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		if (!hd->tmPending) {
+			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+			break;
+		}
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ/4);
+	}
+
+	//return SUCCESS;
+	return FAILED;
+}
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* old symsense.c stuff... */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * Private data...
- * To protect ourselves against those that would pass us bogus pointers
+/**
+ *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
+ *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
+ *
+ *	(linux Scsi_Host_Template.eh_bus_reset_handler routine)
+ *
+ *	Returns SUCCESS or FAILED.
  */
-static u8 dummyInqData[SCSI_STD_INQUIRY_BYTES]
-    = { 0x1F, 0x00, 0x00, 0x00,
-	0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static u8 dummySenseData[SCSI_STD_SENSE_BYTES]
-    = { 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00 };
-static u8 dummyCDB[16]
-    = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static u8 dummyScsiData[16]
-    = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+int
+mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
+{
+	MPT_SCSI_HOST	*hd;
+	MPT_FRAME_HDR	*mf;
+	unsigned long	 flags;
+	int		 scpnt_idx;
 
-#if 0
-static const char *PeripheralDeviceTypeString[32] = {
-	"Direct-access",		/* 00h */
-	"Sequential-access",		/* 01h */
-	"Printer",			/* 02h */
-	"Processor",			/* 03h */
-			/*"Write-Once-Read-Multiple",*/	/* 04h */
-	"WORM",				/* 04h */
-	"CD-ROM",			/* 05h */
-	"Scanner",			/* 06h */
-	"Optical memory",		/* 07h */
-	"Media Changer",		/* 08h */
-	"Communications",		/* 09h */
-	"(Graphics arts pre-press)",	/* 0Ah */
-	"(Graphics arts pre-press)",	/* 0Bh */
-	"Array controller",		/* 0Ch */
-	"Enclosure services",		/* 0Dh */
-	"Simplified direct-access",	/* 0Eh */
-	"Reserved-0Fh",			/* 0Fh */
-	"Reserved-10h",			/* 10h */
-	"Reserved-11h",			/* 11h */
-	"Reserved-12h",			/* 12h */
-	"Reserved-13h",			/* 13h */
-	"Reserved-14h",			/* 14h */
-	"Reserved-15h",			/* 15h */
-	"Reserved-16h",			/* 16h */
-	"Reserved-17h",			/* 17h */
-	"Reserved-18h",			/* 18h */
-	"Reserved-19h",			/* 19h */
-	"Reserved-1Ah",			/* 1Ah */
-	"Reserved-1Bh",			/* 1Bh */
-	"Reserved-1Ch",			/* 1Ch */
-	"Reserved-1Dh",			/* 1Dh */
-	"Reserved-1Eh",			/* 1Eh */
-	"Unknown"			/* 1Fh */
-};
-#endif
+	printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);
+	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
-static char *ScsiStatusString[] = {
-	"GOOD",					/* 00h */
-	NULL,					/* 01h */
-	"CHECK CONDITION",			/* 02h */
-	NULL,					/* 03h */
-	"CONDITION MET",			/* 04h */
-	NULL,					/* 05h */
-	NULL,					/* 06h */
-	NULL,					/* 07h */
-	"BUSY",					/* 08h */
-	NULL,					/* 09h */
-	NULL,					/* 0Ah */
-	NULL,					/* 0Bh */
-	NULL,					/* 0Ch */
-	NULL,					/* 0Dh */
-	NULL,					/* 0Eh */
-	NULL,					/* 0Fh */
-	"INTERMEDIATE",				/* 10h */
-	NULL,					/* 11h */
-	NULL,					/* 12h */
-	NULL,					/* 13h */
-	"INTERMEDIATE-CONDITION MET",		/* 14h */
-	NULL,					/* 15h */
-	NULL,					/* 16h */
-	NULL,					/* 17h */
-	"RESERVATION CONFLICT",			/* 18h */
-	NULL,					/* 19h */
-	NULL,					/* 1Ah */
-	NULL,					/* 1Bh */
-	NULL,					/* 1Ch */
-	NULL,					/* 1Dh */
-	NULL,					/* 1Eh */
-	NULL,					/* 1Fh */
-	NULL,					/* 20h */
-	NULL,					/* 21h */
-	"COMMAND TERMINATED",			/* 22h */
-	NULL,					/* 23h */
-	NULL,					/* 24h */
-	NULL,					/* 25h */
-	NULL,					/* 26h */
-	NULL,					/* 27h */
-	"TASK SET FULL",			/* 28h */
-	NULL,					/* 29h */
-	NULL,					/* 2Ah */
-	NULL,					/* 2Bh */
-	NULL,					/* 2Ch */
-	NULL,					/* 2Dh */
-	NULL,					/* 2Eh */
-	NULL,					/* 2Fh */
-	"ACA ACTIVE",				/* 30h */
-	NULL
-};
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
+		SCpnt->result = DID_RESET << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return SUCCESS;
+	}
 
-static const char *ScsiCommonOpString[] = {
-	"TEST UNIT READY",			/* 00h */
-	"REZERO UNIT (REWIND)",			/* 01h */
-	NULL,					/* 02h */
-	"REQUEST_SENSE",			/* 03h */
-	"FORMAT UNIT (MEDIUM)",			/* 04h */
-	"READ BLOCK LIMITS",			/* 05h */
-	NULL,					/* 06h */
-	"REASSIGN BLOCKS",			/* 07h */
-	"READ(6)",				/* 08h */
-	NULL,					/* 09h */
-	"WRITE(6)",				/* 0Ah */
-	"SEEK(6)",				/* 0Bh */
-	NULL,					/* 0Ch */
-	NULL,					/* 0Dh */
-	NULL,					/* 0Eh */
-	"READ REVERSE",				/* 0Fh */
-	"WRITE_FILEMARKS",			/* 10h */
-	"SPACE(6)",				/* 11h */
-	"INQUIRY",				/* 12h */
-	NULL
-};
+	/* Find this command
+	 */
+	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
+		/* Cmd not found in ScsiLookup. If found in 
+		 * doneQ, delete from Q. Do OS callback.
+		 */
+		search_doneQ_for_cmd(hd, SCpnt);
 
-static const char *SenseKeyString[] = {
-	"NO SENSE",				/* 0h */
-	"RECOVERED ERROR",			/* 1h */
-	"NOT READY",				/* 2h */
-	"MEDIUM ERROR",				/* 3h */
-	"HARDWARE ERROR",			/* 4h */
-	"ILLEGAL REQUEST",			/* 5h */
-	"UNIT ATTENTION",			/* 6h */
-	"DATA PROTECT",				/* 7h */
-	"BLANK CHECK",				/* 8h */
-	"VENDOR-SPECIFIC",			/* 9h */
-	"ABORTED COPY",				/* Ah */
-	"ABORTED COMMAND",			/* Bh */
-	"EQUAL (obsolete)",			/* Ch */
-	"VOLUME OVERFLOW",			/* Dh */
-	"MISCOMPARE",				/* Eh */
-	"RESERVED",				/* Fh */
-	NULL
-};
+		SCpnt->result = DID_RESET << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return SUCCESS;
+	}
 
-#define SPECIAL_ASCQ(c,q) \
-	(((c) == 0x40 && (q) != 0x00) || ((c) == 0x4D) || ((c) == 0x70))
+	/* If this command is pended, then timeout/hang occurred
+	 * during DV. Force bus reset by posting command to F/W
+	 * and then following up with the reset request.
+	 */
+	if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
+		mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+		post_pendingQ_commands(hd);
+	}
+
+	/* This thread will not exit until tmPending is cleared
+	 */
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	hd->tmPending = 1;
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+
+	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
+						0, 0, 0, CAN_SLEEP) < 0) {
+
+		/* The TM request failed and the subsequent FW-reload failed!
+		 * Fatal error case.
+		 */
+		printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
+		 		hd->ioc->name, SCpnt);
+
+		/* If command not found, do not do callback,
+		 * just returned failed. CHECKME.
+		 */
+		if (hd->ScsiLookup[scpnt_idx] != NULL) {
+			//atomic_dec(&queue_depth);
+			SCpnt->result = STS_BUSY;
+			spin_lock_irqsave(&io_request_lock, flags);
+			SCpnt->scsi_done(SCpnt);
+			spin_unlock_irqrestore(&io_request_lock, flags);
+		}
+
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		hd->tmPending = 0;
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+
+		return FAILED;
+	}
+
+	/* Spin on tmPending until we get the interrupt for this TM request.
+	 */
+	while (1) {
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		if (!hd->tmPending) {
+			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+			break;
+		}
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ/4);
+	}
+
+	return SUCCESS;
+}
 
 #if 0
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  Sense_Key_Specific() - If Sense_Key_Specific_Valid bit is set,
- *			   then print additional information via
- *			   a call to SDMS_SystemAlert().
+/**
+ *	mptscsih_host_reset - Perform a SCSI host adapter RESET!
+ *	new_eh variant
+ *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *  Return: nothing
+ *	(linux Scsi_Host_Template.eh_host_reset_handler routine)
+ *
+ *	Returns SUCCESS or FAILED.
  */
-static void Sense_Key_Specific(IO_Info_t *ioop, char *msg1)
+int
+mptscsih_host_reset(Scsi_Cmnd *SCpnt)
 {
-	u8	*sd;
-	u8	 BadValue;
-	u8	 SenseKey;
-	int	 Offset;
-	int	 len = strlen(msg1);
+	MPT_SCSI_HOST	*hd;
+	MPT_FRAME_HDR	*mf;
 
-	sd = ioop->sensePtr;
-	if (SD_Additional_Sense_Length(sd) < 8)
-		return;
+	printk(KERN_WARNING MYNAM ": Attempting HOST_RESET (%p)\n", SCpnt);
+	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
-	SenseKey = SD_Sense_Key(sd);
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
+		SCpnt->result = DID_RESET << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return SUCCESS;
+	}
+
+	/* If this command is pended, then timeout/hang occurred
+	 * during DV. Force bus reset by posting command to F/W
+	 * and then following up with the reset request.
+	 */
+	if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
+		mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+		post_pendingQ_commands(hd);
+	}
+
+	/* This thread will not exit until tmPending is cleared
+	 */
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	hd->tmPending = 1;
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+
+	if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) {
+		SCpnt->result = STS_BUSY;
+		spin_lock_irqsave(&io_request_lock, flags);		// sjr-added
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);	// sjr-added
+		return FAILED;
+	}
+
+	/* Spin on tmPending until we get the interrupt for this TM request.
+	 */
+	while (1) {
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		if (!hd->tmPending) {
+			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+			break;
+		}
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ/4);
+	}
+
+	return SUCCESS;
+}
+#endif
+
+#else		/* MPT_SCSI old EH stuff... */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_old_abort - Abort linux Scsi_Cmnd routine
+ *	@SCpnt: Pointer to Scsi_Cmnd structure, IO to be aborted
+ *
+ *	(linux Scsi_Host_Template.abort routine)
+ *
+ *	Returns SCSI_ABORT_{SUCCESS,BUSY,PENDING}.
+ */
+int
+mptscsih_old_abort(Scsi_Cmnd *SCpnt)
+{
+	MPT_SCSI_HOST		*hd;
+	MPT_FRAME_HDR		*mf;
+	struct tq_struct	*ptaskfoo;
+	unsigned long		 flags;
+	int			 scpnt_idx;
+
+	printk(KERN_WARNING MYNAM ": OldAbort scheduling ABORT SCSI IO (sc=%p)\n", SCpnt);
+	printk(KERN_WARNING "  IOs outstanding = %d\n", atomic_read(&queue_depth));
+
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
+		printk(KERN_WARNING "  WARNING - OldAbort, NULL hostdata ptr!!\n");
+		SCpnt->result = DID_ERROR << 16;
+		SCpnt->scsi_done(SCpnt);
+		return SCSI_ABORT_NOT_RUNNING;
+	}
+
+	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
+		/* Cmd not found in ScsiLookup.
+		 * If found in doneQ, delete from Q.
+		 * Do OS callback.
+		 */
+		search_doneQ_for_cmd(hd, SCpnt);
+
+		SCpnt->result = DID_RESET << 16;
+		SCpnt->scsi_done(SCpnt);
+		return SCSI_ABORT_SUCCESS;
+	} else {
+		/* If this command is pended, then timeout/hang occurred
+		 * during DV. Force bus reset by posting command to F/W
+		 * and then following up with the reset request.
+		 */
+		if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
+			mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+			post_pendingQ_commands(hd);
+		}
+	}
+
+	/*
+	 *  Check to see if there's already an ABORT queued for this guy.
+	 */
+	mf = search_taskQ(0, SCpnt, hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
+	if (mf != NULL) {
+		dtmprintk((MYIOC_s_INFO_FMT "OldAbort:Abort Task PENDING cmd (%p) taskQ depth (%d)\n",
+			hd->ioc->name, SCpnt, hd->taskQcnt));
+		return SCSI_ABORT_PENDING;
+	}
+
+	// SJR - CHECKME - Can we avoid this here?
+	// (mpt_HardResetHandler has this check...)
+	/* If IOC is reloading FW, return PENDING.
+	 */
+	spin_lock_irqsave(&hd->ioc->diagLock, flags);
+	if (hd->ioc->diagPending) {
+		spin_unlock_irqrestore(&hd->ioc->diagLock, flags);
+		return SCSI_ABORT_PENDING;
+	}
+	spin_unlock_irqrestore(&hd->ioc->diagLock, flags);
+
+	/* If there are no message frames what should we do?
+	 */
+	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
+		printk((KERN_WARNING "  WARNING - OldAbort, no msg frames!!\n"));
+		/* We are out of message frames!
+		 * Call the reset handler to do a FW reload.
+		 */
+		printk((KERN_WARNING " Reloading Firmware!!\n"));
+		if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
+			printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
+		}
+		return SCSI_ABORT_PENDING;
+	}
+
+	/*
+	 *  Add ourselves to (end of) taskQ .
+	 *  Check to see if our _bh is running.  If NOT, schedule it.
+	 */
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	Q_ADD_TAIL(&hd->taskQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
+	hd->taskQcnt++;
+	atomic_inc(&mpt_taskQdepth);
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+
+	spin_lock_irqsave(&mytaskQ_lock, flags);
+
+	/* Save the original SCpnt mf pointer
+	 */
+	SCpnt->host_scribble = (u8 *) MPT_INDEX_2_MFPTR (hd->ioc, scpnt_idx);
+
+	/* For the time being, force bus reset on any abort
+	 * requests for the 1030 FW.
+	 */
+	if (hd->is_spi)
+		mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
+	else
+		mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK;
+
+	mf->u.frame.linkage.argp1 = SCpnt;
+	mf->u.frame.linkage.argp2 = (void *) hd;
+
+	dtmprintk((MYIOC_s_INFO_FMT "OldAbort:_bh_handler state (%d) taskQ count (%d)\n",
+		hd->ioc->name, mytaskQ_bh_active, hd->taskQcnt));
+
+	if (! mytaskQ_bh_active) {
+		mytaskQ_bh_active = 1;
+		/*
+		 *  Oh how cute, no alloc/free/mgmt needed if we use
+		 *  (bottom/unused portion of) MPT request frame.
+		 */
+		ptaskfoo = (struct tq_struct *) &mptscsih_ptaskfoo;
+		ptaskfoo->sync = 0;
+		ptaskfoo->routine = mptscsih_taskmgmt_bh;
+		ptaskfoo->data = SCpnt;
+
+		SCHEDULE_TASK(ptaskfoo);
+	}
+	spin_unlock_irqrestore(&mytaskQ_lock, flags);
+
+	return SCSI_ABORT_PENDING;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_old_reset - Perform a SCSI BUS_RESET!
+ *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
+ *	@reset_flags: (not used?)
+ *
+ *	(linux Scsi_Host_Template.reset routine)
+ *
+ *	Returns SCSI_RESET_{SUCCESS,PUNT,PENDING}.
+ */
+int
+mptscsih_old_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+{
+	MPT_SCSI_HOST		*hd;
+	MPT_FRAME_HDR		*mf;
+	struct tq_struct	*ptaskfoo;
+	unsigned long		 flags;
+	int			 scpnt_idx;
+
+	printk(KERN_WARNING MYNAM ": OldReset scheduling BUS_RESET (sc=%p)\n", SCpnt);
+	printk(KERN_WARNING "  IOs outstanding = %d\n", atomic_read(&queue_depth));
+
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
+		SCpnt->result = DID_RESET << 16;
+		SCpnt->scsi_done(SCpnt);
+		return SCSI_RESET_SUCCESS;
+	}
+
+	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
+		/* Cmd not found in ScsiLookup.
+		 * If found in doneQ, delete from Q.
+		 * Do OS callback.
+		 */
+		search_doneQ_for_cmd(hd, SCpnt);
+
+		SCpnt->result = DID_RESET << 16;
+		SCpnt->scsi_done(SCpnt);
+		return SCSI_RESET_SUCCESS;
+	} else {
+		/* If this command is pended, then timeout/hang occurred
+		 * during DV. Force bus reset by posting command to F/W
+		 * and then following up with the reset request.
+		 */
+		if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
+			mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+			post_pendingQ_commands(hd);
+		}
+	}
+
+	/*
+	 *  Check to see if there's an ABORT_TASK queued for this guy.
+	 *  If so, delete.
+	 */
+	search_taskQ(1, SCpnt, hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
+
+	/*
+	 *  Check to see if there's already a BUS_RESET queued for this guy.
+	 */
+	mf = search_taskQ(0, SCpnt, hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS);
+	if (mf != NULL) {
+		dtmprintk((MYIOC_s_INFO_FMT "OldReset:Reset Task PENDING cmd (%p) taskQ depth (%d)\n",
+			hd->ioc->name, SCpnt, hd->taskQcnt));
+		return SCSI_RESET_PENDING;
+	}
+
+	// SJR - CHECKME - Can we avoid this here?
+	// (mpt_HardResetHandler has this check...)
+	/* If IOC is reloading FW, return PENDING.
+	 */
+	spin_lock_irqsave(&hd->ioc->diagLock, flags);
+	if (hd->ioc->diagPending) {
+		spin_unlock_irqrestore(&hd->ioc->diagLock, flags);
+		return SCSI_RESET_PENDING;
+	}
+	spin_unlock_irqrestore(&hd->ioc->diagLock, flags);
+
+	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {
+		/* We are out of message frames!
+		 * Call the reset handler to do a FW reload.
+		 */
+		printk((KERN_WARNING " Reloading Firmware!!\n"));
+		if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
+			printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
+		}
+		return SCSI_RESET_PENDING;
+	}
+
+	/*
+	 *  Add ourselves to (end of) taskQ.
+	 *  Check to see if our _bh is running.  If NOT, schedule it.
+	 */
+	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+	Q_ADD_TAIL(&hd->taskQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
+	hd->taskQcnt++;
+	atomic_inc(&mpt_taskQdepth);
+	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+
+	spin_lock_irqsave(&mytaskQ_lock, flags);
+
+	/* Save the original SCpnt mf pointer
+	 */
+	SCpnt->host_scribble = (u8 *) MPT_INDEX_2_MFPTR (hd->ioc, scpnt_idx);
+
+	mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
+	mf->u.frame.linkage.argp1 = SCpnt;
+	mf->u.frame.linkage.argp2 = (void *) hd;
+
+	dtmprintk((MYIOC_s_INFO_FMT "OldReset: _bh_handler state (%d) taskQ count (%d)\n",
+		hd->ioc->name, mytaskQ_bh_active, hd->taskQcnt));
+
+	if (! mytaskQ_bh_active) {
+		mytaskQ_bh_active = 1;
+		/*
+		 *  Oh how cute, no alloc/free/mgmt needed if we use
+		 *  (bottom/unused portion of) MPT request frame.
+		 */
+		ptaskfoo = (struct tq_struct *) &mptscsih_ptaskfoo;
+		ptaskfoo->sync = 0;
+		ptaskfoo->routine = mptscsih_taskmgmt_bh;
+		ptaskfoo->data = SCpnt;
+
+		SCHEDULE_TASK(ptaskfoo);
+	}
+	spin_unlock_irqrestore(&mytaskQ_lock, flags);
+	return SCSI_RESET_PENDING;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_taskmgmt_bh - SCSI task mgmt bottom half handler
+ *	@sc: (unused)
+ *
+ *	This routine (thread) is active whenever there are any outstanding
+ *	SCSI task management requests for a SCSI host adapter.
+ *	IMPORTANT!  This routine is scheduled therefore should never be
+ *	running in ISR context.  i.e., it's safe to sleep here.
+ */
+void
+mptscsih_taskmgmt_bh(void *sc)
+{
+	MPT_ADAPTER	*ioc;
+	Scsi_Cmnd	*SCpnt;
+	MPT_FRAME_HDR	*mf = NULL;
+	MPT_SCSI_HOST	*hd;
+	u32		 ctx2abort = 0;
+	unsigned long	 flags;
+	int		 scpnt_idx;
+	int		 did;
+	u8		 task_type;
+
+	spin_lock_irqsave(&mytaskQ_lock, flags);
+	mytaskQ_bh_active = 1;
+	spin_unlock_irqrestore(&mytaskQ_lock, flags);
+
+	do {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ/4);
+		did = 0;
+
+		for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) {
+			if (ioc->sh) {
+				hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+				if (hd == NULL) {
+					printk(KERN_ERR MYNAM
+							": ERROR - TaskMgmt NULL SCSI Host!"
+							"(ioc=%p, sh=%p hd=%p)\n",
+							ioc, ioc->sh, hd);
+					continue;
+				}
+
+				spin_lock_irqsave(&ioc->FreeQlock, flags);
+				if (Q_IS_EMPTY(&hd->taskQ)) {
+					spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+					continue;
+				}
+
+				/* If we ever find a non-empty queue,
+				 * keep the handler alive
+				 */
+				did++;
+
+				/* tmPending is SMP lock-protected */
+				if (hd->tmPending || hd->tmPtr) {
+					spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+					continue;
+				}
+				hd->tmPending = 1;
+
+				/* Process this request
+				 */
+                                mf = hd->taskQ.head;
+				Q_DEL_ITEM(&mf->u.frame.linkage);
+				hd->taskQcnt--;
+				atomic_dec(&mpt_taskQdepth);
+				spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+				SCpnt = (Scsi_Cmnd*)mf->u.frame.linkage.argp1;
+				if (SCpnt == NULL) {
+					printk(KERN_ERR MYNAM ": ERROR - TaskMgmt has NULL SCpnt! (mf=%p:sc=%p)\n",
+							mf, SCpnt);
+					mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+					spin_lock_irqsave(&ioc->FreeQlock, flags);
+					hd->tmPending = 0;
+					spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+					continue;
+				}
+
+				/* Get the ScsiLookup index pointer
+				 * from the SC pointer.
+				 */
+				if (!SCpnt->host_scribble || ((MPT_SCSI_HOST *)SCpnt->host->hostdata != hd)) {
+					/* The command associated with the
+					 * abort/reset request must have
+					 * completed and this is a stale
+					 * request. We are done.
+					 * Free the current MF and continue.
+					 */
+					mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+					spin_lock_irqsave(&ioc->FreeQlock, flags);
+					hd->tmPending = 0;
+					spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+					continue;
+				}
+
+				scpnt_idx = MFPTR_2_MPT_INDEX(hd->ioc, SCpnt->host_scribble);
+				if (scpnt_idx != SCPNT_TO_LOOKUP_IDX(SCpnt)) {
+					/* Error! this should never happen!!
+					 */
+					mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+					spin_lock_irqsave(&ioc->FreeQlock, flags);
+					hd->tmPending = 0;
+					spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+					continue;
+				}
+
+				task_type = mf->u.frame.linkage.arg1;
+				ctx2abort = 0;
+				if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
+					MPT_FRAME_HDR	*SCpntMf;
+
+					/*
+					 * Most important!  Set TaskMsgContext to SCpnt's MsgContext!
+					 * (the IO to be ABORT'd)
+					 *
+					 * NOTE: Since we do not byteswap MsgContext, we do not
+					 *	 swap it here either.  It is an opaque cookie to
+					 *	 the controller, so it does not matter. -DaveM
+					 */
+					SCpntMf = (MPT_FRAME_HDR *) SCpnt->host_scribble;
+					ctx2abort = SCpntMf->u.frame.hwhdr.msgctxu.MsgContext;
+
+					hd->abortSCpnt = SCpnt;
+					printk(KERN_WARNING MYNAM ": Attempting ABORT SCSI IO! (mf=%p:sc=%p)\n",
+							mf, SCpnt);
+				}
+
+				/* The TM handler will allocate a new mf,
+				 * so free the current mf.
+				 */
+				mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+				mf = NULL;
+
+				if (mptscsih_TMHandler(hd, task_type, SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP) < 0) {
+
+					/* The TM request failed and the subsequent FW-reload failed!
+					 * Fatal error case.
+					 */
+					printk(KERN_WARNING MYNAM
+						": WARNING[1] - IOC error processing TaskMgmt request (sc=%p)\n", SCpnt);
+
+					if (hd->ScsiLookup[scpnt_idx] != NULL) {
+						atomic_dec(&queue_depth);
+						SCpnt->result = DID_SOFT_ERROR << 16;
+						spin_lock_irqsave(&io_request_lock, flags);
+						SCpnt->scsi_done(SCpnt);
+						spin_unlock_irqrestore(&io_request_lock, flags);
+						mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+					}
+					spin_lock_irqsave(&ioc->FreeQlock, flags);
+					hd->tmPending = 0;
+					spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+					hd->abortSCpnt = NULL;
+				}
+			}
+		}
+		if (atomic_read(&mpt_taskQdepth) > 0)
+			did++;
+
+	} while ( did );
+
+	spin_lock_irqsave(&mytaskQ_lock, flags);
+	mytaskQ_bh_active = 0;
+	spin_unlock_irqrestore(&mytaskQ_lock, flags);
+
+	return;
+}
+#endif		/* } */
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@mf: Pointer to SCSI task mgmt request frame
+ *	@mr: Pointer to SCSI task mgmt reply frame
+ *
+ *	This routine is called from mptbase.c::mpt_interrupt() at the completion
+ *	of any SCSI task management request.
+ *	This routine is registered with the MPT (base) driver at driver
+ *	load/init time via the mpt_register() API call.
+ *
+ *	Returns 1 indicating alloc'd request frame ptr should be freed.
+ */
+static int
+mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
+{
+	SCSITaskMgmtReply_t	*pScsiTmReply;
+	SCSITaskMgmt_t		*pScsiTmReq;
+	MPT_SCSI_HOST		*hd = NULL;
+	unsigned long		 flags;
+	u8			 tmType = 0;
+
+	dtmprintk((MYIOC_s_INFO_FMT "SCSI TaskMgmt completed (mf=%p,r=%p)\n",
+			ioc->name, mf, mr));
+	if (ioc->sh) {
+		/* Depending on the thread, a timer is activated for
+		 * the TM request.  Delete this timer on completion of TM.
+		 * Decrement count of outstanding TM requests.
+		 */
+		hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+		if (hd->tmPtr) {
+			del_timer(&hd->TMtimer);
+		}
+		dtmprintk((MYIOC_s_INFO_FMT "taskQcnt (%d)\n",
+			ioc->name, hd->taskQcnt));
+	} else {
+		dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
+			ioc->name));
+		return 1;
+	}
+
+	if (mr == NULL) {
+		dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
+			ioc->name, mf));
+		return 1;
+	} else {
+		pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
+		pScsiTmReq = (SCSITaskMgmt_t*)mf;
+
+		/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
+		tmType = pScsiTmReq->TaskType;
+
+		dtmprintk((KERN_INFO "  TaskType = %d, TerminationCount=%d\n",
+				tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
+
+		/* Error?  (anything non-zero?) */
+		if (*(u32 *)&pScsiTmReply->Reserved2[0]) {
+			u16	 iocstatus;
+
+			iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+			dtmprintk((KERN_INFO "  SCSI TaskMgmt (%d) - Oops!\n", tmType));
+			dtmprintk((KERN_INFO "  IOCStatus = %04xh\n", iocstatus));
+			dtmprintk((KERN_INFO "  IOCLogInfo = %08xh\n",
+				 le32_to_cpu(pScsiTmReply->IOCLogInfo)));
+
+			/* clear flags and continue.
+			 */
+			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
+				hd->abortSCpnt = NULL;
+#ifdef	DROP_TEST
+			if (dropMfPtr)
+				dropTestBad++;
+#endif
+			/* If an internal command is present
+			 * or the TM failed - reload the FW.
+			 * FC FW may respond FAILED to an ABORT
+			 */
+			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
+				if ((hd->cmdPtr) ||
+				    (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
+					if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
+						printk((KERN_WARNING
+							" Firmware Reload FAILED!!\n"));
+					}
+				}
+			}
+		} else {
+			dtmprintk((KERN_INFO "  SCSI TaskMgmt SUCCESS!\n"));
+
+#ifndef MPT_SCSI_USE_NEW_EH
+			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
+				/* clean taskQ - remove tasks associated with
+				 * completed commands.
+				 */
+				clean_taskQ(hd);
+			} else if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
+				/* If taskQ contains another request
+				 * for this SCpnt, delete this request.
+				 */
+				search_taskQ_for_cmd(hd->abortSCpnt, hd);
+			}
+#endif
+			hd->numTMrequests--;
+			hd->abortSCpnt = NULL;
+			flush_doneQ(hd);
+
+#ifdef	DROP_TEST
+			if (dropMfPtr)
+				dropTestOK++;
+#endif
+		}
+	}
+
+#ifdef	DROP_TEST
+	{
+		Scsi_Cmnd	*sc;
+		unsigned long	 flags;
+		u16		 req_idx;
+
+		/* Free resources for the drop test MF and chain buffers.
+		 */
+		if (dropMfPtr) {
+			req_idx = le16_to_cpu(dropMfPtr->u.frame.hwhdr.msgctxu.fld.req_idx);
+			sc = hd->ScsiLookup[req_idx];
+			if (sc == NULL) {
+				printk(MYIOC_s_ERR_FMT
+					"Drop Test: NULL ScsiCmd ptr!\n",
+					ioc->name);
+			} else {
+				sc->host_scribble = NULL;
+				if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
+					sc->result = DID_RESET << 16;
+				else
+					sc->result = DID_ABORT << 16;
+
+				hd->ScsiLookup[req_idx] = NULL;
+				atomic_dec(&queue_depth);
+				spin_lock_irqsave(&io_request_lock, flags);
+				sc->scsi_done(sc);	/* Issue callback */
+				spin_unlock_irqrestore(&io_request_lock, flags);
+
+				mptscsih_freeChainBuffers(hd, req_idx);
+				mpt_free_msg_frame(ScsiDoneCtx, ioc->id, dropMfPtr);
+
+				printk(MYIOC_s_INFO_FMT
+						"Free'd Dropped cmd (%p)\n",
+						hd->ioc->name, sc);
+				printk(MYIOC_s_INFO_FMT
+						"mf (%p) reqidx (%4x)\n",
+						hd->ioc->name, dropMfPtr,
+						req_idx);
+				printk(MYIOC_s_INFO_FMT
+					"Num Tot (%d) Good (%d) Bad (%d) \n",
+					hd->ioc->name, dropTestNum,
+					dropTestOK, dropTestBad);
+			}
+			dropMfPtr = NULL;
+		}
+	}
+#endif
+
+#ifndef MPT_SCSI_USE_NEW_EH
+	/*
+	 *  Signal to _bh thread that we finished.
+	 *  This IOC can now process another TM command.
+	 */
+	dtmprintk((MYIOC_s_INFO_FMT "taskmgmt_complete: (=%p) done! Num Failed(%d) Task Count (%d)\n",
+			ioc->name, mf, hd->numTMrequests, hd->taskQcnt));
+#endif
+	hd->tmPtr = NULL;
+	spin_lock_irqsave(&ioc->FreeQlock, flags);
+	hd->tmPending = 0;
+	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+	return 1;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	This is anyones guess quite frankly.
+ */
+
+int
+mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip)
+{
+	int size;
+
+	size = disk->capacity;
+	ip[0] = 64;				/* heads			*/
+	ip[1] = 32;				/* sectors			*/
+	if ((ip[2] = size >> 11) > 1024) {	/* cylinders, test for big disk */
+		ip[0] = 255;			/* heads			*/
+		ip[1] = 63;			/* sectors			*/
+		ip[2] = size / (255 * 63);	/* cylinders			*/
+	}
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	OS entry point to adjust the queue_depths on a per-device basis.
+ *	Called once per device the bus scan. Use it to force the queue_depth
+ *	member to 1 if a device does not support Q tags.
+ */
+void
+mptscsih_select_queue_depths(struct Scsi_Host *sh, Scsi_Device *sdList)
+{
+	struct scsi_device	*device;
+	VirtDevice		*pTarget;
+	MPT_SCSI_HOST		*hd;
+	int			 ii, max;
+
+	for (device = sdList; device; device = device->next) {
+
+		if (device->host != sh)
+			continue;
+
+		hd = (MPT_SCSI_HOST *) sh->hostdata;
+		if (!hd)
+			continue;
+
+		if (hd->Targets) {
+			if (hd->is_spi)
+				max = MPT_MAX_SCSI_DEVICES;
+			else
+				max = MPT_MAX_FC_DEVICES;
+
+			for (ii=0; ii < max; ii++) {
+				pTarget = hd->Targets[ii];
+				if (pTarget && !(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) {
+					device->queue_depth = 1;
+				}
+			}
+		}
+	}
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  Private routines...
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* 19991030 -sralston
+ *  Return absolute SCSI data direction:
+ *     1 = _DATA_OUT
+ *     0 = _DIR_NONE
+ *    -1 = _DATA_IN
+ */
+static int
+mptscsih_io_direction(Scsi_Cmnd *cmd)
+{
+	switch (cmd->cmnd[0]) {
+	/*  _DATA_OUT commands	*/
+	case WRITE_6:		case WRITE_10:		case WRITE_12:
+	case WRITE_LONG:	case WRITE_SAME:	case WRITE_BUFFER:
+	case WRITE_VERIFY:	case WRITE_VERIFY_12:
+	case COMPARE:		case COPY:		case COPY_VERIFY:
+	case SEARCH_EQUAL:	case SEARCH_HIGH:	case SEARCH_LOW:
+	case SEARCH_EQUAL_12:	case SEARCH_HIGH_12:	case SEARCH_LOW_12:
+	case MODE_SELECT:	case MODE_SELECT_10:	case LOG_SELECT:
+	case SEND_DIAGNOSTIC:	case CHANGE_DEFINITION: case UPDATE_BLOCK:
+	case SET_WINDOW:	case MEDIUM_SCAN:	case SEND_VOLUME_TAG:
+	case REASSIGN_BLOCKS:
+	case PERSISTENT_RESERVE_OUT:
+	case 0xea:
+	case 0xa3:
+		return 1;
+
+	/*  No data transfer commands  */
+	case SEEK_6:		case SEEK_10:
+	case RESERVE:		case RELEASE:
+	case TEST_UNIT_READY:
+	case START_STOP:
+	case ALLOW_MEDIUM_REMOVAL:
+		return 0;
+
+	/*  Conditional data transfer commands	*/
+	case FORMAT_UNIT:
+		if (cmd->cmnd[1] & 0x10)	/* FmtData (data out phase)? */
+			return 1;
+		else
+			return 0;
+
+	case VERIFY:
+		if (cmd->cmnd[1] & 0x02)	/* VERIFY:BYTCHK (data out phase)? */
+			return 1;
+		else
+			return 0;
+
+	case RESERVE_10:
+		if (cmd->cmnd[1] & 0x03)	/* RESERVE:{LongID|Extent} (data out phase)? */
+			return 1;
+		else
+			return 0;
+
+#if 0
+	case REZERO_UNIT:	/* (or REWIND) */
+	case SPACE:
+	case ERASE:		case ERASE_10:
+	case SYNCHRONIZE_CACHE:
+	case LOCK_UNLOCK_CACHE:
+#endif
+
+	/*  Must be data _IN!  */
+	default:
+		return -1;
+	}
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* Utility function to copy sense data from the scsi_cmnd buffer
+ * to the FC and SCSI target structures.
+ *
+ */
+static void
+copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
+{
+	VirtDevice	*target;
+	SCSIIORequest_t	*pReq;
+	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
+	int		 index;
+	char		 devFoo[96];
+	IO_Info_t	 thisIo;
+
+	/* Get target structure
+	 */
+	pReq = (SCSIIORequest_t *) mf;
+	index = (int) pReq->TargetID;
+	target = hd->Targets[index];
+	if (hd->is_multipath && sc->device->hostdata)
+		target = (VirtDevice *) sc->device->hostdata;
+
+	if (sense_count) {
+		u8 *sense_data;
+		int req_index;
+
+		/* Copy the sense received into the scsi command block. */
+		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+		sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
+		memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
+
+		/* save sense data to the target device
+		 */
+		if (target) {
+			int sz;
+
+			sz = MIN(pReq->SenseBufferLength, sense_count);
+			if (sz > SCSI_STD_SENSE_BYTES)
+				sz =  SCSI_STD_SENSE_BYTES;
+			memcpy(target->sense, sense_data, sz);
+			target->tflags |= MPT_TARGET_FLAGS_VALID_SENSE;
+		}
+
+		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
+		 */
+		if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
+			if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
+				int idx;
+				MPT_ADAPTER *ioc = hd->ioc;
+
+				idx = ioc->eventContext % ioc->eventLogSize;
+				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
+				ioc->events[idx].eventContext = ioc->eventContext;
+
+				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
+					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
+					(pReq->Bus << 8) || pReq->TargetID;
+
+				ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
+
+				ioc->eventContext++;
+			}
+		}
+
+		/* Print an error report for the user.
+		 */
+		thisIo.cdbPtr = sc->cmnd;
+		thisIo.sensePtr = sc->sense_buffer;
+		thisIo.SCSIStatus = pScsiReply->SCSIStatus;
+		thisIo.DoDisplay = 1;
+		if (hd->is_multipath)
+			sprintf(devFoo, "%d:%d:%d \"%s\"",
+					hd->ioc->id,
+					pReq->TargetID,
+					pReq->LUN[1],
+					target->dev_vol_name);
+		else
+			sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->target, sc->lun);
+		thisIo.DevIDStr = devFoo;
+/* fubar */
+		thisIo.dataPtr = NULL;
+		thisIo.inqPtr = NULL;
+		if (sc->device) {
+			thisIo.inqPtr = sc->device->vendor-8;	/* FIXME!!! */
+		}
+		(void) mpt_ScsiHost_ErrorReport(&thisIo);
+
+	} else {
+		dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
+				hd->ioc->name));
+	}
+
+	return;
+}
+
+static u32
+SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc)
+{
+	MPT_SCSI_HOST *hd;
+	int i;
+
+	hd = (MPT_SCSI_HOST *) sc->host->hostdata;
+
+	for (i = 0; i < hd->ioc->req_depth; i++) {
+		if (hd->ScsiLookup[i] == sc) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+/* see mptscsih.h */
+
+#ifdef MPT_SCSIHOST_NEED_ENTRY_EXIT_HOOKUPS
+	static Scsi_Host_Template driver_template = MPT_SCSIHOST;
+#	include "../../scsi/scsi_module.c"
+#endif
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* Search the pendingQ for a command with specific index.
+ * If found, delete and return mf pointer  
+ * If not found, return NULL
+ */
+static MPT_FRAME_HDR *
+mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx)
+{
+	unsigned long	 flags;
+	MPT_DONE_Q	*buffer;
+	MPT_FRAME_HDR	*mf = NULL;
+	MPT_FRAME_HDR	*cmdMfPtr = NULL;
+
+	ddvtprintk((MYIOC_s_INFO_FMT ": search_pendingQ called...", hd->ioc->name));
+	cmdMfPtr = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
+	spin_lock_irqsave(&hd->freedoneQlock, flags);
+	if (!Q_IS_EMPTY(&hd->pendingQ)) {
+		buffer = hd->pendingQ.head;
+		do {
+			mf = (MPT_FRAME_HDR *) buffer->argp;
+			if (mf == cmdMfPtr) {
+				Q_DEL_ITEM(buffer);
+
+				/* clear the arg pointer
+				 */
+				buffer->argp = NULL;
+
+				/* Add to the freeQ
+				 */
+				Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);
+				break;
+			}
+			mf = NULL;
+		} while ((buffer = buffer->forw) != (MPT_DONE_Q *) &hd->pendingQ);
+	}
+	spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+	ddvtprintk((" ...return %p\n", mf));
+	return mf;
+}
+
+/* Post all commands on the pendingQ to the FW.
+ * Lock Q when deleting/adding members
+ * Lock io_request_lock for OS callback.
+ */
+static void
+post_pendingQ_commands(MPT_SCSI_HOST *hd)
+{
+	MPT_FRAME_HDR	*mf;
+	MPT_DONE_Q	*buffer;
+	unsigned long	 flags;
+
+	/* Flush the pendingQ.
+	 */
+	ddvtprintk((MYIOC_s_INFO_FMT ": post_pendingQ_commands called\n", hd->ioc->name));
+	while (1) {
+		spin_lock_irqsave(&hd->freedoneQlock, flags);
+		if (Q_IS_EMPTY(&hd->pendingQ)) {
+			spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+			break;
+		}
+
+		buffer = hd->pendingQ.head;
+		/* Delete from Q
+		 */
+		Q_DEL_ITEM(buffer);
+
+		mf = (MPT_FRAME_HDR *) buffer->argp;
+		if (!mf) {
+			/* This should never happen */
+			printk(MYIOC_s_WARN_FMT "post_pendingQ_commands: mf %p\n", hd->ioc->name, mf);
+			spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+			continue;
+		}
+
+		mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+		ddvtprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (mf=%p)\n",
+				hd->ioc->name, mf));
+
+		buffer->argp = NULL;
+
+		/* Add to the freeQ
+		 */
+		Q_ADD_TAIL(&hd->freeQ.head, buffer, MPT_DONE_Q);
+		spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+	}
+
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+	MPT_SCSI_HOST	*hd = NULL;
+	unsigned long	 flags;
+
+	dtmprintk((KERN_WARNING MYNAM
+			": IOC %s_reset routed to SCSI host driver!\n",
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+	/* If a FW reload request arrives after base installed but
+	 * before all scsi hosts have been attached, then an alt_ioc
+	 * may have a NULL sh pointer.
+	 */
+	if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
+		return 0;
+	else
+		hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+
+	if (reset_phase == MPT_IOC_PRE_RESET) {
+		dtmprintk((MYIOC_s_WARN_FMT "Do Pre-Diag Reset handling\n",
+			ioc->name));
+
+		/* Clean Up:
+		 * 1. Set Hard Reset Pending Flag
+		 * All new commands go to doneQ
+		 */
+		hd->resetPending = 1;
+
+		/* 2. Flush running commands
+		 *	Clean drop test code - if compiled
+		 *	Clean ScsiLookup (and associated memory)
+		 *	AND clean mytaskQ
+		 */
+
+		/* 2a. Drop Test Command.
+		 */
+#ifdef	DROP_TEST
+		{
+			Scsi_Cmnd	*sc;
+			unsigned long	 flags;
+			u16		 req_idx;
+
+			/* Free resources for the drop test MF
+			 * and chain buffers.
+			 */
+			if (dropMfPtr) {
+				req_idx = le16_to_cpu(dropMfPtr->u.frame.hwhdr.msgctxu.fld.req_idx);
+				sc = hd->ScsiLookup[req_idx];
+				if (sc == NULL) {
+					printk(MYIOC_s_ERR_FMT
+					"Drop Test: NULL ScsiCmd ptr!\n",
+					ioc->name);
+				} else {
+					sc->host_scribble = NULL;
+					sc->result = DID_RESET << 16;
+					hd->ScsiLookup[req_idx] = NULL;
+					atomic_dec(&queue_depth);
+					spin_lock_irqsave(&io_request_lock, flags);
+					sc->scsi_done(sc);	/* Issue callback */
+					spin_unlock_irqrestore(&io_request_lock, flags);
+				}
+
+				mptscsih_freeChainBuffers(hd, req_idx);
+				mpt_free_msg_frame(ScsiDoneCtx, ioc->id, dropMfPtr);
+				printk(MYIOC_s_INFO_FMT
+						"Free'd: mf (%p) reqidx (%4x)\n",
+						hd->ioc->name, dropMfPtr,
+						req_idx);
+			}
+			dropMfPtr = NULL;
+		}
+#endif
+
+		/* 2b. Reply to OS all known outstanding I/O commands.
+		 */
+		mptscsih_flush_running_cmds(hd);
+
+		/* 2c. If there was an internal command that
+		 * has not completed, configuration or io request,
+		 * free these resources.
+		 */
+		if (hd->cmdPtr) {
+			del_timer(&hd->timer);
+			mpt_free_msg_frame(ScsiScanDvCtx, ioc->id, hd->cmdPtr);
+			atomic_dec(&queue_depth);
+		}
+
+		/* 2d. If a task management has not completed,
+		 * free resources associated with this request.
+		 */
+		if (hd->tmPtr) {
+			del_timer(&hd->TMtimer);
+			mpt_free_msg_frame(ScsiTaskCtx, ioc->id, hd->tmPtr);
+		}
+
+#ifndef MPT_SCSI_USE_NEW_EH
+		/* 2e. Delete all commands on taskQ
+		 * Should be superfluous - as this taskQ should
+		 * be empty.
+		 */
+		clean_taskQ(hd);
+#endif
+		dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset handling complete.\n",
+			ioc->name));
+
+	} else {
+		dtmprintk((MYIOC_s_WARN_FMT "Do Post-Diag Reset handling\n",
+			ioc->name));
+
+		/* Once a FW reload begins, all new OS commands are
+		 * redirected to the doneQ w/ a reset status.
+		 * Init all control structures.
+		 */
+
+		/* ScsiLookup initialization
+		 */
+		{
+			int ii;
+			for (ii=0; ii < hd->ioc->req_depth; ii++)
+				hd->ScsiLookup[ii] = NULL;
+		}
+
+		/* 2. Chain Buffer initialization
+		 */
+		mptscsih_initChainBuffers(hd, 0);
+
+		/* 3. tmPtr clear
+		 */
+		if (hd->tmPtr) {
+			hd->tmPtr = NULL;
+		}
+
+		/* 4. Renegotiate to all devices, if SCSI
+		 */
+		if (hd->is_spi)
+			mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
+
+		/* 5. Enable new commands to be posted
+		 */
+		spin_lock_irqsave(&ioc->FreeQlock, flags);
+		hd->tmPending = 0;
+		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+		hd->resetPending = 0;
+		hd->numTMrequests = 0;
+
+		/* 6. If there was an internal command,
+		 * wake this process up.
+		 */
+		if (hd->cmdPtr) {
+			/*
+			 * Wake up the original calling thread
+			 */
+			hd->pLocal = &hd->localReply;
+			hd->pLocal->completion = MPT_SCANDV_DID_RESET;
+			scandv_wait_done = 1;
+			wake_up(&scandv_waitq);
+			hd->cmdPtr = NULL;
+		}
+
+		/* 7. Flush doneQ
+		 */
+		flush_doneQ(hd);
+
+		dtmprintk((MYIOC_s_WARN_FMT "Post-Reset handling complete.\n",
+			ioc->name));
+	}
+
+	return 1;		/* currently means nothing really */
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
+{
+	MPT_SCSI_HOST *hd;
+	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
+
+	dprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
+			ioc->name, event));
+
+	switch (event) {
+	case MPI_EVENT_UNIT_ATTENTION:			/* 03 */
+		/* FIXME! */
+		break;
+	case MPI_EVENT_IOC_BUS_RESET:			/* 04 */
+		/* FIXME! */
+		break;
+	case MPI_EVENT_EXT_BUS_RESET:			/* 05 */
+		/* FIXME! */
+		break;
+	case MPI_EVENT_LOGOUT:				/* 09 */
+		/* FIXME! */
+		break;
+
+		/*
+		 *  CHECKME! Don't think we need to do
+		 *  anything for these, but...
+		 */
+	case MPI_EVENT_RESCAN:				/* 06 */
+	case MPI_EVENT_LINK_STATUS_CHANGE:		/* 07 */
+	case MPI_EVENT_LOOP_STATE_CHANGE:		/* 08 */
+		/*
+		 *  CHECKME!  Falling thru...
+		 */
+
+	case MPI_EVENT_INTEGRATED_RAID:			/* 0B */
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+		/* negoNvram set to 0 if DV enabled and to USE_NVRAM if 
+		 * if DV disabled
+		 */
+		hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+		if (hd->negoNvram == 0) {
+			ScsiCfgData	*pSpi;
+			Ioc3PhysDisk_t	*pPDisk;
+			int		 numPDisk;
+			u8		 reason;
+			u8		 physDiskNum;
+			
+			reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
+			if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
+				/* New or replaced disk. 
+				 * Set DV flag and schedule DV.
+				 */
+				pSpi = &ioc->spi_data;
+				physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
+				if (pSpi->pIocPg3) {
+					pPDisk =  pSpi->pIocPg3->PhysDisk;
+					numPDisk =pSpi->pIocPg3->NumPhysDisks;
+
+					while (numPDisk) {
+						if (physDiskNum == pPDisk->PhysDiskNum) {
+							pSpi->dvStatus[pPDisk->PhysDiskID] = MPT_SCSICFG_NEED_DV;
+							pSpi->forceDv = MPT_SCSICFG_NEED_DV;
+							ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
+							break;
+						}
+						pPDisk++;
+						numPDisk--;
+					}
+				}
+			}
+		}
+#endif
+
+#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
+		printk("Raid Event RF: ");
+		{
+			u32 *m = (u32 *)pEvReply;
+			int ii;
+			int n = (int)pEvReply->MsgLength;
+			for (ii=6; ii < n; ii++)
+				printk(" %08x", le32_to_cpu(m[ii]));
+			printk("\n");
+		}
+#endif
+		break;
+
+	case MPI_EVENT_NONE:				/* 00 */
+	case MPI_EVENT_LOG_DATA:			/* 01 */
+	case MPI_EVENT_STATE_CHANGE:			/* 02 */
+	case MPI_EVENT_EVENT_CHANGE:			/* 0A */
+	default:
+		dprintk((KERN_INFO "  Ignoring event (=%02Xh)\n", event));
+		break;
+	}
+
+	return 1;		/* currently means nothing really */
+}
+
+#if 0		/* { */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	scsiherr.c - Fusion MPT SCSI Host driver error handling/reporting.
+ *
+ *	drivers/message/fusion/scsiherr.c
+ */
+
+//extern const char	**mpt_ScsiOpcodesPtr;	/* needed by mptscsih.c */
+//extern ASCQ_Table_t	 *mpt_ASCQ_TablePtr;
+//extern int		  mpt_ASCQ_TableSz;
+
+#define MYNAM	"mptscsih"
+
+#endif		/* } */
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  Private data...
+ */
+static ASCQ_Table_t *mptscsih_ASCQ_TablePtr;
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* old symsense.c stuff... */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * Private data...
+ * To protect ourselves against those that would pass us bogus pointers
+ */
+static u8 dummyInqData[SCSI_STD_INQUIRY_BYTES]
+    = { 0x1F, 0x00, 0x00, 0x00,
+	0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static u8 dummySenseData[SCSI_STD_SENSE_BYTES]
+    = { 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00 };
+static u8 dummyCDB[16]
+    = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static u8 dummyScsiData[16]
+    = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+#if 0
+static const char *PeripheralDeviceTypeString[32] = {
+	"Direct-access",		/* 00h */
+	"Sequential-access",		/* 01h */
+	"Printer",			/* 02h */
+	"Processor",			/* 03h */
+			/*"Write-Once-Read-Multiple",*/	/* 04h */
+	"WORM",				/* 04h */
+	"CD-ROM",			/* 05h */
+	"Scanner",			/* 06h */
+	"Optical memory",		/* 07h */
+	"Media Changer",		/* 08h */
+	"Communications",		/* 09h */
+	"(Graphics arts pre-press)",	/* 0Ah */
+	"(Graphics arts pre-press)",	/* 0Bh */
+	"Array controller",		/* 0Ch */
+	"Enclosure services",		/* 0Dh */
+	"Simplified direct-access",	/* 0Eh */
+	"Reserved-0Fh",			/* 0Fh */
+	"Reserved-10h",			/* 10h */
+	"Reserved-11h",			/* 11h */
+	"Reserved-12h",			/* 12h */
+	"Reserved-13h",			/* 13h */
+	"Reserved-14h",			/* 14h */
+	"Reserved-15h",			/* 15h */
+	"Reserved-16h",			/* 16h */
+	"Reserved-17h",			/* 17h */
+	"Reserved-18h",			/* 18h */
+	"Reserved-19h",			/* 19h */
+	"Reserved-1Ah",			/* 1Ah */
+	"Reserved-1Bh",			/* 1Bh */
+	"Reserved-1Ch",			/* 1Ch */
+	"Reserved-1Dh",			/* 1Dh */
+	"Reserved-1Eh",			/* 1Eh */
+	"Unknown"			/* 1Fh */
+};
+#endif
+
+static char *ScsiStatusString[] = {
+	"GOOD",					/* 00h */
+	NULL,					/* 01h */
+	"CHECK CONDITION",			/* 02h */
+	NULL,					/* 03h */
+	"CONDITION MET",			/* 04h */
+	NULL,					/* 05h */
+	NULL,					/* 06h */
+	NULL,					/* 07h */
+	"BUSY",					/* 08h */
+	NULL,					/* 09h */
+	NULL,					/* 0Ah */
+	NULL,					/* 0Bh */
+	NULL,					/* 0Ch */
+	NULL,					/* 0Dh */
+	NULL,					/* 0Eh */
+	NULL,					/* 0Fh */
+	"INTERMEDIATE",				/* 10h */
+	NULL,					/* 11h */
+	NULL,					/* 12h */
+	NULL,					/* 13h */
+	"INTERMEDIATE-CONDITION MET",		/* 14h */
+	NULL,					/* 15h */
+	NULL,					/* 16h */
+	NULL,					/* 17h */
+	"RESERVATION CONFLICT",			/* 18h */
+	NULL,					/* 19h */
+	NULL,					/* 1Ah */
+	NULL,					/* 1Bh */
+	NULL,					/* 1Ch */
+	NULL,					/* 1Dh */
+	NULL,					/* 1Eh */
+	NULL,					/* 1Fh */
+	NULL,					/* 20h */
+	NULL,					/* 21h */
+	"COMMAND TERMINATED",			/* 22h */
+	NULL,					/* 23h */
+	NULL,					/* 24h */
+	NULL,					/* 25h */
+	NULL,					/* 26h */
+	NULL,					/* 27h */
+	"TASK SET FULL",			/* 28h */
+	NULL,					/* 29h */
+	NULL,					/* 2Ah */
+	NULL,					/* 2Bh */
+	NULL,					/* 2Ch */
+	NULL,					/* 2Dh */
+	NULL,					/* 2Eh */
+	NULL,					/* 2Fh */
+	"ACA ACTIVE",				/* 30h */
+	NULL
+};
+
+static const char *ScsiCommonOpString[] = {
+	"TEST UNIT READY",			/* 00h */
+	"REZERO UNIT (REWIND)",			/* 01h */
+	NULL,					/* 02h */
+	"REQUEST_SENSE",			/* 03h */
+	"FORMAT UNIT (MEDIUM)",			/* 04h */
+	"READ BLOCK LIMITS",			/* 05h */
+	NULL,					/* 06h */
+	"REASSIGN BLOCKS",			/* 07h */
+	"READ(6)",				/* 08h */
+	NULL,					/* 09h */
+	"WRITE(6)",				/* 0Ah */
+	"SEEK(6)",				/* 0Bh */
+	NULL,					/* 0Ch */
+	NULL,					/* 0Dh */
+	NULL,					/* 0Eh */
+	"READ REVERSE",				/* 0Fh */
+	"WRITE_FILEMARKS",			/* 10h */
+	"SPACE(6)",				/* 11h */
+	"INQUIRY",				/* 12h */
+	NULL
+};
+
+static const char *SenseKeyString[] = {
+	"NO SENSE",				/* 0h */
+	"RECOVERED ERROR",			/* 1h */
+	"NOT READY",				/* 2h */
+	"MEDIUM ERROR",				/* 3h */
+	"HARDWARE ERROR",			/* 4h */
+	"ILLEGAL REQUEST",			/* 5h */
+	"UNIT ATTENTION",			/* 6h */
+	"DATA PROTECT",				/* 7h */
+	"BLANK CHECK",				/* 8h */
+	"VENDOR-SPECIFIC",			/* 9h */
+	"ABORTED COPY",				/* Ah */
+	"ABORTED COMMAND",			/* Bh */
+	"EQUAL (obsolete)",			/* Ch */
+	"VOLUME OVERFLOW",			/* Dh */
+	"MISCOMPARE",				/* Eh */
+	"RESERVED",				/* Fh */
+	NULL
+};
+
+#define SPECIAL_ASCQ(c,q) \
+	(((c) == 0x40 && (q) != 0x00) || ((c) == 0x4D) || ((c) == 0x70))
+
+#if 0
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  Sense_Key_Specific() - If Sense_Key_Specific_Valid bit is set,
+ *			   then print additional information via
+ *			   a call to SDMS_SystemAlert().
+ */
+static void Sense_Key_Specific(IO_Info_t *ioop, char *msg1)
+{
+	u8	*sd;
+	u8	 BadValue;
+	u8	 SenseKey;
+	int	 Offset;
+	int	 len = strlen(msg1);
+
+	sd = ioop->sensePtr;
+	if (SD_Additional_Sense_Length(sd) < 8)
+		return;
+
+	SenseKey = SD_Sense_Key(sd);
+
+	if (SD_Sense_Key_Specific_Valid(sd)) {
+		if (SenseKey == SK_ILLEGAL_REQUEST) {
+			Offset = SD_Bad_Byte(sd);
+			if (SD_Was_Illegal_Request(sd)) {
+				BadValue = ioop->cdbPtr[Offset];
+				len += sprintf(msg1+len, "\n  Illegal CDB value=%02Xh found at CDB ",
+						BadValue);
+		} else {
+			BadValue = ioop->dataPtr[Offset];
+			len += sprintf(msg1+len, "\n  Illegal DATA value=%02Xh found at DATA ",
+					BadValue);
+		}
+		len += sprintf(msg1+len, "byte=%02Xh", Offset);
+		if (SD_SKS_Bit_Pointer_Valid(sd))
+			len += sprintf(msg1+len, "/bit=%1Xh", SD_SKS_Bit_Pointer(sd));
+		} else if ((SenseKey == SK_RECOVERED_ERROR) ||
+			   (SenseKey == SK_HARDWARE_ERROR) ||
+			   (SenseKey == SK_MEDIUM_ERROR)) {
+			len += sprintf(msg1+len, "\n  Recovery algorithm Actual_Retry_Count=%02Xh",
+			SD_Actual_Retry_Count(sd));
+		}
+	}
+}
+#endif
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int dump_cdb(char *foo, unsigned char *cdb)
+{
+	int i, grpCode, cdbLen;
+	int l = 0;
+
+	grpCode = cdb[0] >> 5;
+	if (grpCode < 1)
+		cdbLen = 6;
+	else if (grpCode < 3)
+		cdbLen = 10;
+	else if (grpCode == 5)
+		cdbLen = 12;
+	else
+		cdbLen = 16;
+
+	for (i=0; i < cdbLen; i++)
+		l += sprintf(foo+l, " %02X", cdb[i]);
+
+	return l;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int dump_sd(char *foo, unsigned char *sd)
+{
+	int snsLen = 8 + SD_Additional_Sense_Length(sd);
+	int l = 0;
+	int i;
+
+	for (i=0; i < MIN(snsLen,18); i++)
+		l += sprintf(foo+l, " %02X", sd[i]);
+	l += sprintf(foo+l, "%s", snsLen>18 ? " ..." : "");
+
+	return l;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*  Do ASC/ASCQ lookup/grindage to English readable string(s)  */
+static const char * ascq_set_strings_4max(
+		u8 ASC, u8 ASCQ,
+		const char **s1, const char **s2, const char **s3, const char **s4)
+{
+	static const char *asc_04_part1_string = "LOGICAL UNIT ";
+	static const char *asc_04_part2a_string = "NOT READY, ";
+	static const char *asc_04_part2b_string = "IS ";
+	static const char *asc_04_ascq_NN_part3_strings[] = {	/* ASC ASCQ (hex) */
+	  "CAUSE NOT REPORTABLE",				/* 04 00 */
+	  "IN PROCESS OF BECOMING READY",			/* 04 01 */
+	  "INITIALIZING CMD. REQUIRED",				/* 04 02 */
+	  "MANUAL INTERVENTION REQUIRED",			/* 04 03 */
+	  /* Add	" IN PROGRESS" to all the following... */
+	  "FORMAT",						/* 04 04 */
+	  "REBUILD",						/* 04 05 */
+	  "RECALCULATION",					/* 04 06 */
+	  "OPERATION",						/* 04 07 */
+	  "LONG WRITE",						/* 04 08 */
+	  "SELF-TEST",						/* 04 09 */
+	  NULL
+	};
+	static char *asc_04_part4_string = " IN PROGRESS";
+
+	static char *asc_29_ascq_NN_strings[] = {		/* ASC ASCQ (hex) */
+	  "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED",	/* 29 00 */
+	  "POWER ON OCCURRED",					/* 29 01 */
+	  "SCSI BUS RESET OCCURRED",				/* 29 02 */
+	  "BUS DEVICE RESET FUNCTION OCCURRED",			/* 29 03 */
+	  "DEVICE INTERNAL RESET",				/* 29 04 */
+	  "TRANSCEIVER MODE CHANGED TO SINGLE-ENDED",		/* 29 05 */
+	  "TRANSCEIVER MODE CHANGED TO LVD",			/* 29 06 */
+	  NULL
+	};
+	static char *ascq_vendor_uniq = "(Vendor Unique)";
+	static char *ascq_noone = "(no matching ASC/ASCQ description found)";
+	int idx;
+
+	*s1 = *s2 = *s3 = *s4 = "";		/* set'em all to the empty "" string */
+
+	/* CHECKME! Need lock/sem?
+	 *  Update and examine for isense module presense.
+	 */
+	mptscsih_ASCQ_TablePtr = (ASCQ_Table_t *)mpt_v_ASCQ_TablePtr;
+
+	if (mptscsih_ASCQ_TablePtr == NULL) {
+		/* 2nd chances... */
+		if (ASC == 0x04 && (ASCQ < sizeof(asc_04_ascq_NN_part3_strings)/sizeof(char*)-1)) {
+			*s1 = asc_04_part1_string;
+			*s2 = (ASCQ == 0x01) ? asc_04_part2b_string : asc_04_part2a_string;
+			*s3 = asc_04_ascq_NN_part3_strings[ASCQ];
+			/* check for " IN PROGRESS" ones */
+			if (ASCQ >= 0x04)
+				*s4 = asc_04_part4_string;
+		} else if (ASC == 0x29 && (ASCQ < sizeof(asc_29_ascq_NN_strings)/sizeof(char*)-1))
+			*s1 = asc_29_ascq_NN_strings[ASCQ];
+		/*
+		 *	Else { leave all *s[1-4] values pointing to the empty "" string }
+		 */
+		return *s1;
+	}
+
+	/*
+	 * Need to check ASC here; if it is "special," then
+	 * the ASCQ is variable, and indicates failed component number.
+	 * We must treat the ASCQ as a "dont care" while searching the
+	 * mptscsih_ASCQ_Table[] by masking it off, and then restoring it later
+	 * on when we actually need to identify the failed component.
+	 */
+	if (SPECIAL_ASCQ(ASC,ASCQ))
+		ASCQ = 0xFF;
+
+	/* OK, now search mptscsih_ASCQ_Table[] for a matching entry */
+	for (idx = 0; mptscsih_ASCQ_TablePtr && idx < mpt_ASCQ_TableSz; idx++)
+		if ((ASC == mptscsih_ASCQ_TablePtr[idx].ASC) && (ASCQ == mptscsih_ASCQ_TablePtr[idx].ASCQ)) {
+			*s1 = mptscsih_ASCQ_TablePtr[idx].Description;
+			return *s1;
+		}
+
+	if ((ASC >= 0x80) || (ASCQ >= 0x80))
+		*s1 = ascq_vendor_uniq;
+	else
+		*s1 = ascq_noone;
+
+	return *s1;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  SCSI Error Report; desired output format...
+ *---
+SCSI Error Report =-=-=-=-=-=-=-=-=-=-=-=-=-= (ioc0,scsi0:0)
+  SCSI_Status=02h (CHECK CONDITION)
+  Original_CDB[]: 00 00 00 00 00 00 - TestUnitReady
+  SenseData[12h]: 70 00 06 00 00 00 00 0A 00 00 00 00 29 00 03 00 00 00
+  SenseKey=6h (UNIT ATTENTION); FRU=03h
+  ASC/ASCQ=29h/00h, "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED"
+ *---
+ */
+
+int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop)
+{
+	char		 foo[512];
+	char		 buf2[32];
+	char		*statstr;
+	const char	*opstr;
+	int		 sk		= SD_Sense_Key(ioop->sensePtr);
+	const char	*skstr		= SenseKeyString[sk];
+	unsigned char	 asc		= SD_ASC(ioop->sensePtr);
+	unsigned char	 ascq		= SD_ASCQ(ioop->sensePtr);
+	int		 l;
+
+	/*
+	 *  More quiet mode.
+	 *  Filter out common, repetitive, warning-type errors...  like:
+	 *    POWER ON (06,29/00 or 06,29/01),
+	 *    SPINNING UP (02,04/01),
+	 *    LOGICAL UNIT NOT SUPPORTED (05,25/00), etc.
+	 */
+	if (sk == SK_NO_SENSE) {
+		return 0;
+	}
+	if (	(sk==SK_UNIT_ATTENTION	&& asc==0x29 && (ascq==0x00 || ascq==0x01))
+	     || (sk==SK_NOT_READY	&& asc==0x04 && ascq==0x01)
+	     || (sk==SK_ILLEGAL_REQUEST && asc==0x25 && ascq==0x00)
+	   )
+	{
+		/* Do nothing! */
+		return 0;
+	}
+
+	/*
+	 *  Protect ourselves...
+	 */
+	if (ioop->cdbPtr == NULL)
+		ioop->cdbPtr = dummyCDB;
+	if (ioop->sensePtr == NULL)
+		ioop->sensePtr = dummySenseData;
+	if (ioop->inqPtr == NULL)
+		ioop->inqPtr = dummyInqData;
+	if (ioop->dataPtr == NULL)
+		ioop->dataPtr = dummyScsiData;
+
+	statstr = NULL;
+	if ((ioop->SCSIStatus >= sizeof(ScsiStatusString)/sizeof(char*)-1) ||
+	    ((statstr = (char*)ScsiStatusString[ioop->SCSIStatus]) == NULL)) {
+		(void) sprintf(buf2, "Bad-Reserved-%02Xh", ioop->SCSIStatus);
+		statstr = buf2;
+	}
+
+	opstr = NULL;
+	if (1+ioop->cdbPtr[0] <= sizeof(ScsiCommonOpString)/sizeof(char*))
+		opstr = ScsiCommonOpString[ioop->cdbPtr[0]];
+	else if (mpt_ScsiOpcodesPtr)
+		opstr = mpt_ScsiOpcodesPtr[ioop->cdbPtr[0]];
+
+	l = sprintf(foo, "SCSI Error Report =-=-= (%s)\n"
+	  "  SCSI_Status=%02Xh (%s)\n"
+	  "  Original_CDB[]:",
+			ioop->DevIDStr,
+			ioop->SCSIStatus,
+			statstr);
+	l += dump_cdb(foo+l, ioop->cdbPtr);
+	if (opstr)
+		l += sprintf(foo+l, " - \"%s\"", opstr);
+	l += sprintf(foo+l, "\n  SenseData[%02Xh]:", 8+SD_Additional_Sense_Length(ioop->sensePtr));
+	l += dump_sd(foo+l, ioop->sensePtr);
+	l += sprintf(foo+l, "\n  SenseKey=%Xh (%s); FRU=%02Xh\n  ASC/ASCQ=%02Xh/%02Xh",
+			sk, skstr, SD_FRU(ioop->sensePtr), asc, ascq );
+
+	{
+		const char	*x1, *x2, *x3, *x4;
+		x1 = x2 = x3 = x4 = "";
+		x1 = ascq_set_strings_4max(asc, ascq, &x1, &x2, &x3, &x4);
+		if (x1 != NULL) {
+			if (x1[0] != '(')
+				l += sprintf(foo+l, " \"%s%s%s%s\"", x1,x2,x3,x4);
+			else
+				l += sprintf(foo+l, " %s%s%s%s", x1,x2,x3,x4);
+		}
+	}
+
+#if 0
+	if (SPECIAL_ASCQ(asc,ascq))
+		l += sprintf(foo+l, " (%02Xh)", ascq);
+#endif
+
+	PrintF(("%s\n", foo));
+
+	return l;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_initTarget - Target, LUN alloc/free functionality.
+ *	@hd: Pointer to MPT_SCSI_HOST structure
+ *	@bus_id: Bus number (?)
+ *	@target_id: SCSI target id
+ *	@lun: SCSI LUN id
+ *	@data: Pointer to data
+ *	@dlen: Number of INQUIRY bytes
+ *
+ *	NOTE: It's only SAFE to call this routine if data points to
+ *	sane & valid STANDARD INQUIRY data!
+ *
+ *	Allocate and initialize memory for this target.
+ *	Save inquiry data.
+ *
+ *	Returns pointer to VirtDevice structure.
+ */
+static VirtDevice *
+mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
+{
+	VirtDevice	*vdev;
+	int		 sz;
+
+	dprintk((MYIOC_s_INFO_FMT "initTarget (%d,%d,%d) called, hd=%p\n",
+			hd->ioc->name, bus_id, target_id, lun, hd));
+
+	if ((vdev = hd->Targets[target_id]) == NULL) {
+		if ((vdev = kmalloc(sizeof(VirtDevice), GFP_ATOMIC)) == NULL) {
+			printk(MYIOC_s_ERR_FMT "initTarget kmalloc(%d) FAILED!\n",
+					hd->ioc->name, (int)sizeof(VirtDevice));
+		} else {
+			memset(vdev, 0, sizeof(VirtDevice));
+			rwlock_init(&vdev->VdevLock);
+			Q_INIT(&vdev->WaitQ, void);
+			Q_INIT(&vdev->SentQ, void);
+			Q_INIT(&vdev->DoneQ, void);
+			vdev->tflags = 0;
+			vdev->ioc_id = hd->ioc->id;
+			vdev->target_id = target_id;
+			vdev->bus_id = bus_id;
+
+			hd->Targets[target_id] = vdev;
+			dprintk((KERN_INFO "  *NEW* Target structure (id %d) @ %p\n",
+					target_id, vdev));
+		}
+	}
+
+	if (vdev && data) {
+		if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
+
+			/* Copy the inquiry data  - if we haven't yet.
+			*/
+			sz = MIN(dlen, SCSI_STD_INQUIRY_BYTES);
+
+			memcpy (vdev->inq_data, data, sz);
+			vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+
+			/* Update the target capabilities
+			 */
+			mptscsih_setTargetNegoParms(hd, vdev);
+		}
+
+		/* Is LUN supported? If so, upper 3 bits will be 0
+		 * in first byte of inquiry data.
+		 */
+		if ((*data & 0xe0) == 0)
+			vdev->luns |= (1 << lun);
+	}
+
+	if (vdev) {
+		if (hd->ioc->spi_data.isRaid & (1 << target_id))
+			vdev->raidVolume = 1;
+		else
+			vdev->raidVolume = 0;
+	}
+
+	dprintk((KERN_INFO "  target = %p\n", vdev));
+	return vdev;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  Update the target negotiation parameters based on the
+ *  the Inquiry data, adapter capabilities, and NVRAM settings.
+ *
+ */
+void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target)
+{
+	int  id = (int) target->target_id;
+	int  nvram;
+	char canQ = 0;
+	u8 width = MPT_NARROW;
+	u8 factor = MPT_ASYNC;
+	u8 offset = 0;
+	u8 version, nfactor;
+	ScsiCfgData *pspi_data = &hd->ioc->spi_data;
+
+	/* Set flags based on Inquiry data
+	 */
+	if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
+		version = target->inq_data[2] & 0x03;
+		if (version < 2) {
+			width = 0;
+			factor = MPT_ULTRA2;
+			offset = pspi_data->maxSyncOffset;
+		} else {
+			if (target->inq_data[7] & 0x20) {
+				width = 1;
+			}
+
+			if (target->inq_data[7] & 0x10) {
+				if (version == 2)
+					factor = MPT_ULTRA2;
+				else
+					factor = MPT_ULTRA320;
+
+				offset = pspi_data->maxSyncOffset;
+			} else {
+				factor = MPT_ASYNC;
+				offset = 0;
+			}
+		}
+
+		if (target->inq_data[7] & 0x02) {
+			canQ = 1;
+		}
+
+		/* Update tflags based on NVRAM settings. (SCSI only)
+		 */
+		if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+			nvram = pspi_data->nvram[id];
+			nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
+
+			if (width)
+				width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
+
+			if (offset > 0) {
+				/* Ensure factor is set to the
+				 * maximum of: adapter, nvram, inquiry
+				 */
+				if (nfactor) {
+					if (nfactor < pspi_data->minSyncFactor )
+						nfactor = pspi_data->minSyncFactor;
+
+					factor = MAX (factor, nfactor);
+					if (factor == MPT_ASYNC)
+						offset = 0;
+				} else {
+					offset = 0;
+					factor = MPT_ASYNC;
+				}
+			} else {
+				factor = MPT_ASYNC;
+			}
+		}
+
+		/* Make sure data is consistent
+		 */
+		if ((!width) && (factor < MPT_ULTRA2)) {
+			factor = MPT_ULTRA2;
+		}
+
+		/* Save the data to the target structure.
+		 */
+		target->minSyncFactor = factor;
+		target->maxOffset = offset;
+		target->maxWidth = width;
+		if (canQ) {
+			target->tflags |= MPT_TARGET_FLAGS_Q_YES;
+		}
+
+		target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
+
+		/* Disable all wide (sync) extended messages
+		 * if device is narrow (async).
+		 */
+		target->negoFlags = 0;
+		if (!width)
+			target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
+
+		if (!offset)
+			target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
+	}
+
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  Clear sense valid flag.
+ */
+static void clear_sense_flag(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
+{
+	VirtDevice	*target;
+	int		 index = (int) pReq->TargetID;
+
+	if ((target = hd->Targets[index])) {
+		target->tflags &= ~MPT_TARGET_FLAGS_VALID_SENSE;
+	}
+
+	return;
+}
+
+/* 
+ * If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
+ * Else set the NEED_DV flag after Read Capacity Issued (disks) 
+ * or Mode Sense (cdroms). Tapes, key off of Inquiry command.
+ */
+static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq, char *data)
+{
+	u8 cmd = pReq->CDB[0];
+	
+	if (pReq->LUN[1] != 0)
+		return;
+
+	if (hd->negoNvram != 0)
+		return;
+
+	if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE) || 
+		((cmd == INQUIRY) && ((data[0] & 0x1F) == 0x01))) {
+		u8 dvStatus = hd->ioc->spi_data.dvStatus[pReq->TargetID];
+		if (!(dvStatus & MPT_SCSICFG_DV_DONE)) {
+			ScsiCfgData *pSpi = &hd->ioc->spi_data;
+			if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
+				/* Set NEED_DV for all hidden disks
+				 */
+				Ioc3PhysDisk_t *pPDisk =  pSpi->pIocPg3->PhysDisk;
+				int		numPDisk = pSpi->pIocPg3->NumPhysDisks;
+				
+				while (numPDisk) {
+					pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
+					ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
+					pPDisk++;
+					numPDisk--;
+				}
+			}
+			pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
+			ddvtprintk(("NEED_DV set for visible disk id %d\n", 
+					pReq->TargetID));
+		};
+	}
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  SCSI Config Page functionality ...
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	mptscsih_setDevicePage1Flags  - add Requested and Configuration fields flags
+ *	based on width, factor and offset parameters.
+ *	@width: bus width
+ *	@factor: sync factor
+ *	@offset: sync offset
+ *	@requestedPtr: pointer to requested values (updated)
+ *	@configurationPtr: pointer to configuration values (updated)
+ *	@flags: flags to block WDTR or SDTR negotiation
+ *
+ *	Return: None.
+ *
+ *	Remark: Called by writeSDP1 and _dv_params
+ */
+static void
+mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
+{
+	u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
+	u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
+
+	*configurationPtr = 0;
+	*requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
+	*requestedPtr |= (offset << 16) | (factor << 8);
+
+	if (width && offset && !nowide && !nosync) {
+		if (factor < MPT_ULTRA160) {
+			*requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT +
+						MPI_SCSIDEVPAGE1_RP_QAS);
+		} else if (factor < MPT_ULTRA2) {
+			*requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
+		}
+	}
+
+	if (nowide)
+		*configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
+
+	if (nosync)
+		*configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
+
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	mptscsih_writeSDP1  - write SCSI Device Page 1
+ *	@hd: Pointer to a SCSI Host Strucutre
+ *	@portnum: IOC port number
+ *	@target_id: writeSDP1 for single ID
+ *	@flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM
+ *
+ *	Return: -EFAULT if read of config page header fails
+ *		or 0 if success.
+ *
+ *	Remark: If a target has been found, the settings from the
+ *		target structure are used, else the device is set
+ *		to async/narrow.
+ *
+ *	Remark: Called during init and after a FW reload.
+ *	Remark: We do not wait for a return, write pages sequentially.
+ */
+static int
+mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
+{
+	MPT_ADAPTER		*ioc = hd->ioc;
+	Config_t		*pReq = NULL;
+	SCSIDevicePage1_t	*pData = NULL;
+	VirtDevice		*pTarget = NULL;
+	MPT_FRAME_HDR		*mf;
+	MptSge_t		*psge;
+	dma_addr_t		 dataDma;
+	u16			 req_idx;
+	u32			 frameOffset;
+	u32			 requested, configuration, flagsLength;
+	int			 ii, nvram;
+	int			 id = 0, maxid = 0;
+	u8			 width;
+	u8			 factor;
+	u8			 offset;
+	u8			 bus = 0;
+	u8			 negoFlags;
+
+	if (ioc->spi_data.sdp1length == 0)
+		return 0;
+
+	if (flags & MPT_SCSICFG_ALL_IDS) {
+		id = 0;
+		maxid = ioc->sh->max_id - 1;
+	} else if (ioc->sh) {
+		id = target_id;
+		maxid = MIN(id, ioc->sh->max_id - 1);
+	}
+
+	for (; id <= maxid; id++) {
+		if (id == ioc->pfacts[portnum].PortSCSIID)
+			continue;
+
+		if (flags & MPT_SCSICFG_USE_NVRAM) {
+			/* Use NVRAM, adapter maximums and target settings.
+			 * Data over-riden by target structure information, if present
+			 */
+			width = ioc->spi_data.maxBusWidth;
+			offset = ioc->spi_data.maxSyncOffset;
+			factor = ioc->spi_data.minSyncFactor;
+			if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+				nvram = ioc->spi_data.nvram[id];
+
+				if (width)
+					width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
+
+				if (offset > 0) {
+					factor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
+					if (factor == 0) {
+						/* Key for async */
+						factor = MPT_ASYNC;
+						offset = 0;
+					} else if (factor < ioc->spi_data.minSyncFactor) {
+						factor = ioc->spi_data.minSyncFactor;
+					}
+				} else
+					factor = MPT_ASYNC;
+			}
+
+			/* Set the negotiation flags.
+			 */
+			negoFlags = 0;
+			if (!width)
+				negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
+	
+			if (!offset)
+				negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
+		} else {
+			width = 0;
+			factor = MPT_ASYNC;
+			offset = 0;
+			negoFlags = MPT_TARGET_NO_NEGO_SYNC;
+		}
+
+		/* If id is not a raid volume, get the updated
+		 * transmission settings from the target structure.
+		 */
+		if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
+			width = pTarget->maxWidth;
+			factor = pTarget->minSyncFactor;
+			offset = pTarget->maxOffset;
+			negoFlags = pTarget->negoFlags;
+			pTarget = NULL;
+		}
+		mptscsih_setDevicePage1Flags(width, factor, offset,
+					&requested, &configuration, negoFlags);
+
+
+		if (negoFlags == (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC))
+			continue;
+
+		/* Get a MF for this command.
+		 */
+		if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) {
+			dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
+						ioc->name));
+			return -EAGAIN;
+		}
+
+		/* Set the request and the data pointers.
+		 * Request takes: 36 bytes (32 bit SGE)
+		 * SCSI Device Page 1 requires 16 bytes
+		 * 40 + 16 <= size of SCSI IO Request = 56 bytes
+		 * and MF size >= 64 bytes.
+		 * Place data at end of MF.
+		 */
+		pReq = (Config_t *)mf;
+
+		req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+		frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
+
+		pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
+		dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
+
+		/* Complete the request frame (same for all requests).
+		 */
+		pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+		pReq->Reserved = 0;
+		pReq->ChainOffset = 0;
+		pReq->Function = MPI_FUNCTION_CONFIG;
+		pReq->Reserved1[0] = 0;
+		pReq->Reserved1[1] = 0;
+		pReq->Reserved1[2] = 0;
+		pReq->MsgFlags = 0;
+		for (ii=0; ii < 8; ii++) {
+			pReq->Reserved2[ii] = 0;
+		}
+		pReq->Header.PageVersion = ioc->spi_data.sdp1version;
+		pReq->Header.PageLength = ioc->spi_data.sdp1length;
+		pReq->Header.PageNumber = 1;
+		pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+		pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
+
+		/* Add a SGE to the config request.
+		 */
+		flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
+
+		psge = (MptSge_t *) &pReq->PageBufferSGE;
+		psge->FlagsLength = cpu_to_le32(flagsLength);
+		cpu_to_leXX(dataDma, psge->Address);
+
+		/* Set up the common data portion
+		 */
+		pData->Header.PageVersion = pReq->Header.PageVersion;
+		pData->Header.PageLength = pReq->Header.PageLength;
+		pData->Header.PageNumber = pReq->Header.PageNumber;
+		pData->Header.PageType = pReq->Header.PageType;
+		pData->RequestedParameters = cpu_to_le32(requested);
+		pData->Reserved = 0;
+		pData->Configuration = cpu_to_le32(configuration);
+
+		dprintk((MYIOC_s_INFO_FMT 
+			"write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
+				ioc->name, id, (id | (bus<<8)), 
+				requested, configuration));
+
+		mptscsih_put_msgframe(ScsiDoneCtx, ioc->id, mf);
+	}
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	mptscsih_taskmgmt_timeout - Call back for timeout on a
+ *	task management request.
+ *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
+ *
+ */
+static void mptscsih_taskmgmt_timeout(unsigned long data)
+{
+	MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
+
+	dprintk((MYIOC_s_WARN_FMT "TM request timed out!\n", hd->ioc->name));
+	/* Delete the timer that triggered this callback.
+	 * Remark: del_timer checks to make sure timer is active
+	 * before deleting.
+	 */
+	del_timer(&hd->TMtimer);
+
+	/* Call the reset handler. Already had a TM request
+	 * timeout - so issue a diagnostic reset
+	 */
+	if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
+		printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
+	}
+
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  Bus Scan and Domain Validation functionality ...
+ */
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_scandv_complete - Scan and DV callback routine registered
+ *	to Fustion MPT (base) driver.
+ *
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@mf: Pointer to original MPT request frame
+ *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
+ *
+ *	This routine is called from mpt.c::mpt_interrupt() at the completion
+ *	of any SCSI IO request.
+ *	This routine is registered with the Fusion MPT (base) driver at driver
+ *	load/init time via the mpt_register() API call.
+ *
+ *	Returns 1 indicating alloc'd request frame ptr should be freed.
+ *
+ *	Remark: Sets a completion code and (possibly) saves sense data
+ *	in the IOC member localReply structure.
+ *	Used ONLY for bus scan, DV and other internal commands.
+ */
+static int
+mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
+{
+	MPT_SCSI_HOST	*hd;
+	SCSIIORequest_t *pReq;
+	int		 completionCode;
+	u16		 req_idx;
+
+	if ((mf == NULL) ||
+	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
+		printk(MYIOC_s_ERR_FMT
+			"ScanDvComplete, %s req frame ptr! (=%p)\n",
+				ioc->name, mf?"BAD":"NULL", mf);
+		goto wakeup;
+	}
+
+	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+	del_timer(&hd->timer);
+	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+	hd->ScsiLookup[req_idx] = NULL;
+	pReq = (SCSIIORequest_t *) mf;
+
+	if (mf != hd->cmdPtr) {
+		printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p)\n",
+				hd->ioc->name, mf, hd->cmdPtr);
+	}
+	hd->cmdPtr = NULL;
+
+	ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p)\n",
+			hd->ioc->name, mf, mr));
+
+	atomic_dec(&queue_depth);
+
+	hd->pLocal = &hd->localReply;
+
+	/* If target struct exists, clear sense valid flag.
+	 */
+	clear_sense_flag(hd, pReq);
+
+	if (mr == NULL) {
+		completionCode = MPT_SCANDV_GOOD;
+	} else {
+		SCSIIOReply_t	*pReply;
+		u16		 status;
+
+		pReply = (SCSIIOReply_t *) mr;
+
+		status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+
+		ddvprintk((KERN_NOTICE "  IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
+			     status, pReply->SCSIState, pReply->SCSIStatus,
+			     le32_to_cpu(pReply->IOCLogInfo)));
+
+		switch(status) {
+
+		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
+			completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
+			break;
+
+		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
+		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
+		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
+		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
+			completionCode = MPT_SCANDV_DID_RESET;
+			break;
+
+		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
+		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
+		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
+			if (pReply->Function == MPI_FUNCTION_CONFIG) {
+				ConfigReply_t *pr = (ConfigReply_t *)mr;
+				completionCode = MPT_SCANDV_GOOD;
+				hd->pLocal->header.PageVersion = pr->Header.PageVersion;
+				hd->pLocal->header.PageLength = pr->Header.PageLength;
+				hd->pLocal->header.PageNumber = pr->Header.PageNumber;
+				hd->pLocal->header.PageType = pr->Header.PageType;
+
+			} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
+				/* If the RAID Volume request is successful,
+				 * return GOOD, else indicate that
+				 * some type of error occurred.
+				 */
+				MpiRaidActionReply_t	*pr = (MpiRaidActionReply_t *)mr;
+				if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
+					completionCode = MPT_SCANDV_GOOD;
+				else
+					completionCode = MPT_SCANDV_SOME_ERROR;
+
+			} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
+				VirtDevice	*target;
+				u8		*sense_data;
+				int		 sz;
+
+				/* save sense data in global & target structure
+				 */
+				completionCode = MPT_SCANDV_SENSE;
+				hd->pLocal->scsiStatus = pReply->SCSIStatus;
+				sense_data = ((u8 *)hd->ioc->sense_buf_pool +
+					(req_idx * MPT_SENSE_BUFFER_ALLOC));
+
+				sz = MIN (pReq->SenseBufferLength,
+							SCSI_STD_SENSE_BYTES);
+				memcpy(hd->pLocal->sense, sense_data, sz);
+
+				target = hd->Targets[pReq->TargetID];
+				if (target) {
+					memcpy(target->sense, sense_data, sz);
+					target->tflags
+						|= MPT_TARGET_FLAGS_VALID_SENSE;
+				}
+
+				ddvprintk((KERN_NOTICE "  Check Condition, sense ptr %p\n",
+						sense_data));
+			} else if (pReply->SCSIState & (MPI_SCSI_STATE_AUTOSENSE_FAILED |
+							MPI_SCSI_STATE_NO_SCSI_STATUS)) {
+				completionCode = MPT_SCANDV_DID_RESET;
+			} else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED) {
+				completionCode = MPT_SCANDV_DID_RESET;
+			} else {
+				/* If no error, this will be equivalent
+				 * to MPT_SCANDV_GOOD
+				 */
+				completionCode = (int) pReply->SCSIStatus;
+			}
+			break;
+
+		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
+			if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
+				completionCode = MPT_SCANDV_DID_RESET;
+			else
+				completionCode = MPT_SCANDV_SOME_ERROR;
+			break;
+
+		default:
+			completionCode = MPT_SCANDV_SOME_ERROR;
+			break;
+
+		}	/* switch(status) */
+
+		ddvprintk((KERN_NOTICE "  completionCode set to %08xh\n",
+				completionCode));
+	} /* end of address reply case */
+
+	hd->pLocal->completion = completionCode;
+
+	/* MF and RF are freed in mpt_interrupt
+	 */
+wakeup:
+	/* Free Chain buffers (will never chain) in scan or dv */
+	//mptscsih_freeChainBuffers(hd, req_idx);
+
+	/*
+	 * Wake up the original calling thread
+	 */
+	scandv_wait_done = 1;
+	wake_up(&scandv_waitq);
+
+	return 1;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	mptscsih_timer_expired - Call back for timer process.
+ *	Used only for dv functionality.
+ *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
+ *
+ */
+static void mptscsih_timer_expired(unsigned long data)
+{
+	MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
+#ifndef MPT_SCSI_USE_NEW_EH
+	unsigned long  flags;
+#endif
+
+
+	ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
+
+	if (hd->cmdPtr) {
+		MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
+
+		if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
+			/* Desire to issue a task management request here.
+			 * TM requests MUST be single threaded.
+			 * If old eh code and no TM current, issue request.
+			 * If new eh code, do nothing. Wait for OS cmd timeout
+			 *	for bus reset.
+			 */
+#ifndef MPT_SCSI_USE_NEW_EH
+			spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+			if (hd->tmPending) {
+				spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+				return;
+			} else 
+				hd->tmPending = 1;
+			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+
+			if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
+							0, 0, 0, NO_SLEEP) < 0) {
+				printk(MYIOC_s_WARN_FMT "TM FAILED!\n", hd->ioc->name);
+			}
+#else
+			ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
+#endif
+		} else {
+			/* Perform a FW reload */
+			if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
+				printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
+			}
+		}
+	} else {
+		/* This should NEVER happen */
+		printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
+	}
+
+	/* No more processing.
+	 * TM call will generate an interrupt for SCSI TM Management.
+	 * The FW will reply to all outstanding commands, callback will finish cleanup.
+	 * Hard reset clean-up will free all resources.
+	 */
+	ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
+
+	return;
+}
+
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	mptscsih_do_raid - Format and Issue a RAID volume request message.
+ *	@hd: Pointer to scsi host structure
+ *	@action: What do be done.
+ *	@id: Logical target id.
+ *	@bus: Target locations bus.
+ *
+ *	Returns: < 0 on a fatal error
+ *		0 on success
+ *
+ *	Remark: Wait to return until reply processed by the ISR.
+ */
+static int
+mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
+{
+	MpiRaidActionRequest_t	*pReq;
+	MPT_FRAME_HDR		*mf;
+	MptSge_t		*psge;
+	int			flagsLength;
+	int			in_isr;
+
+	in_isr = in_interrupt();
+	if (in_isr) {
+		dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
+       				hd->ioc->name));
+		return -EPERM;
+	}
+
+	/* Get and Populate a free Frame
+	 */
+	if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc->id)) == NULL) {
+		ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
+					hd->ioc->name));
+		return -EAGAIN;
+	}
+	pReq = (MpiRaidActionRequest_t *)mf;
+	pReq->Action = action;
+	pReq->Reserved1 = 0;
+	pReq->ChainOffset = 0;
+	pReq->Function = MPI_FUNCTION_RAID_ACTION;
+	pReq->VolumeID = io->id;
+	pReq->VolumeBus = io->bus;
+	pReq->PhysDiskNum = io->physDiskNum;
+	pReq->MsgFlags = 0;
+	pReq->Reserved2 = 0;
+	pReq->ActionDataWord = 0; /* Reserved for this action */
+	//pReq->ActionDataSGE = 0;
+
+	psge = (MptSge_t *) &pReq->ActionDataSGE;
+
+	/* Add a SGE to the config request.
+	 */
+	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 0;
+
+	psge->FlagsLength = cpu_to_le32(flagsLength);
+	cpu_to_leXX( (dma_addr_t) -1, psge->Address);
+
+	ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
+			hd->ioc->name, action, io->id));
+
+	hd->pLocal = NULL;
+	hd->timer.expires = jiffies + HZ*2; /* 2 second timeout */
+	scandv_wait_done = 0;
+
+	/* Save cmd pointer, for resource free if timeout or
+	 * FW reload occurs
+	 */
+	hd->cmdPtr = mf;
+
+	add_timer(&hd->timer);
+	mptscsih_put_msgframe(ScsiScanDvCtx, hd->ioc->id, mf);
+	wait_event(scandv_waitq, scandv_wait_done);
+
+	if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
+		return -1;
+
+	return 0;
+}
+#endif /* ~MPTSCSIH_DISABLE_DOMAIN_VALIDATION */
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_do_cmd - Do internal command.
+ *	@hd: MPT_SCSI_HOST pointer
+ *	@io: INTERNAL_CMD pointer.
+ *
+ *	Issue the specified internally generated command and do command
+ *	specific cleanup. For bus scan / DV only.
+ *	NOTES: If command is Inquiry and status is good,
+ *	initialize a target structure, save the data
+ *
+ *	Remark: Single threaded access only.
+ *
+ *	Return:
+ *		< 0 if an illegal command or no resources
+ *
+ *		   0 if good
+ *
+ *		 > 0 if command complete but some type of completion error.
+ */
+static int
+mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
+{
+	MPT_FRAME_HDR	*mf;
+	MptSge_t	*mpisge;
+	SCSIIORequest_t	*pScsiReq;
+	SCSIIORequest_t	 ReqCopy;
+	int		 my_idx, ii, dir;
+	int		 rc, cmdTimeout;
+	int		in_isr;
+	char		 cmdLen;
+	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	char		 cmd = io->cmd;
+
+	in_isr = in_interrupt();
+	if (in_isr) {
+		dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
+       				hd->ioc->name));
+		return -EPERM;
+	}
+
+
+	/* Set command specific information
+	 */
+	switch (cmd) {
+	case CMD_Inquiry:
+		cmdLen = 6;
+		dir = MPI_SCSIIO_CONTROL_READ;
+		CDB[0] = cmd;
+		CDB[4] = io->size;
+		cmdTimeout = 10;
+		break;
+
+	case CMD_TestUnitReady:
+		cmdLen = 6;
+		dir = MPI_SCSIIO_CONTROL_READ;
+		cmdTimeout = 10;
+		break;
+
+	case CMD_StartStopUnit:
+		cmdLen = 6;
+		dir = MPI_SCSIIO_CONTROL_READ;
+		CDB[0] = cmd;
+		CDB[4] = 1;	/*Spin up the disk */
+		cmdTimeout = 15;
+		break;
+
+	case CMD_ReadBuffer:
+		cmdLen = 10;
+		dir = MPI_SCSIIO_CONTROL_READ;
+		CDB[0] = cmd;
+		if (io->flags & MPT_ICFLAG_ECHO) {
+			CDB[1] = 0x0A;
+		} else {
+			CDB[1] = 0x02;
+		}
+
+		if (io->flags & MPT_ICFLAG_BUF_CAP) {
+			CDB[1] |= 0x01;
+		}
+		CDB[6] = (io->size >> 16) & 0xFF;
+		CDB[7] = (io->size >>  8) & 0xFF;
+		CDB[8] = io->size & 0xFF;
+		cmdTimeout = 10;
+		break;
+
+	case CMD_WriteBuffer:
+		cmdLen = 10;
+		dir = MPI_SCSIIO_CONTROL_WRITE;
+		CDB[0] = cmd;
+		if (io->flags & MPT_ICFLAG_ECHO) {
+			CDB[1] = 0x0A;
+		} else {
+			CDB[1] = 0x02;
+		}
+		CDB[6] = (io->size >> 16) & 0xFF;
+		CDB[7] = (io->size >>  8) & 0xFF;
+		CDB[8] = io->size & 0xFF;
+		cmdTimeout = 10;
+		break;
+
+	case CMD_Reserve6:
+		cmdLen = 6;
+		dir = MPI_SCSIIO_CONTROL_READ;
+		CDB[0] = cmd;
+		cmdTimeout = 10;
+		break;
+
+	case CMD_Release6:
+		cmdLen = 6;
+		dir = MPI_SCSIIO_CONTROL_READ;
+		CDB[0] = cmd;
+		cmdTimeout = 10;
+		break;
+
+	case CMD_SynchronizeCache:
+		cmdLen = 10;
+		dir = MPI_SCSIIO_CONTROL_READ;
+		CDB[0] = cmd;
+//		CDB[1] = 0x02;	/* set immediate bit */
+		cmdTimeout = 10;
+		break;
+
+	default:
+		/* Error Case */
+		return -EFAULT;
+	}
+
+	/* Get and Populate a free Frame
+	 */
+	if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc->id)) == NULL) {
+		ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
+					hd->ioc->name));
+		return -EBUSY;
+	}
+
+	pScsiReq = (SCSIIORequest_t *) mf;
+
+	/* Get the request index */
+	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+	ADD_INDEX_LOG(my_idx); /* for debug */
+
+	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
+		pScsiReq->TargetID = io->physDiskNum;
+		pScsiReq->Bus = 0;
+		pScsiReq->ChainOffset = 0;
+		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
+	} else {
+		pScsiReq->TargetID = io->id;
+		pScsiReq->Bus = io->bus;
+		pScsiReq->ChainOffset = 0;
+		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
+	}
+
+	pScsiReq->CDBLength = cmdLen;
+	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
+
+	pScsiReq->Reserved = 0;
+
+	pScsiReq->MsgFlags = MPT_SCSIIO_MSG_FLAGS;
+	/* MsgContext set in mpt_get_msg_fram call  */
+
+	for (ii=0; ii < 8; ii++)
+		pScsiReq->LUN[ii] = 0;
+	pScsiReq->LUN[1] = io->lun;
+
+	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
+		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
+	else
+		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
+
+	for (ii=0; ii < 16; ii++)
+		pScsiReq->CDB[ii] = CDB[ii];
+
+	pScsiReq->DataLength = cpu_to_le32(io->size);
+	pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
+					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
+
+	ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
+			hd->ioc->name, cmd, io->bus, io->id, io->lun));
+
+	/* 32 bit SG only */
+	mpisge = (MptSge_t *) &pScsiReq->SGL;
+
+	if (dir == MPI_SCSIIO_CONTROL_READ) {
+		mpisge->FlagsLength = cpu_to_le32(
+			MPT_SGE_FLAGS_SSIMPLE_READ | io->size);
+	} else {
+		mpisge->FlagsLength = cpu_to_le32(
+			MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size);
+	}
+
+	/* data_dma defaults to -1
+	 */
+	cpu_to_leXX(io->data_dma, mpisge->Address);
+
+	/* The ISR will free the request frame, but we need
+	 * the information to initialize the target. Duplicate.
+	 */
+	memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
+
+	/* Issue this command after:
+	 *	finish init
+	 *	add timer
+	 * Wait until the reply has been received
+	 *  ScsiScanDvCtx callback function will
+	 *	set hd->pLocal;
+	 *	set scandv_wait_done and call wake_up
+	 */
+	hd->pLocal = NULL;
+	hd->timer.expires = jiffies + HZ*cmdTimeout;
+	scandv_wait_done = 0;
+
+	/* Save cmd pointer, for resource free if timeout or
+	 * FW reload occurs
+	 */
+	hd->cmdPtr = mf;
+
+	add_timer(&hd->timer);
+	mptscsih_put_msgframe(ScsiScanDvCtx, hd->ioc->id, mf);
+	wait_event(scandv_waitq, scandv_wait_done);
+
+	if (hd->pLocal) {
+		rc = hd->pLocal->completion;
+		hd->pLocal->skip = 0;
+
+		/* Always set fatal error codes in some cases.
+		 */
+		if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
+			rc = -ENXIO;
+		else if (rc == MPT_SCANDV_SOME_ERROR)
+			rc =  -rc;
+	} else {
+		rc = -EFAULT;
+		/* This should never happen. */
+		ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
+				hd->ioc->name));
+	}
+
+	return rc;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
+ *	@hd: Pointer to MPT_SCSI_HOST structure
+ *	@portnum: IOC port number
+ *
+ *	Uses the ISR, but with special processing.
+ *	MUST be single-threaded.
+ *
+ *	Return: 0 on completion
+ */
+static int
+mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
+{
+	MPT_ADAPTER		*ioc= hd->ioc;
+	VirtDevice		*pTarget = NULL;
+	SCSIDevicePage1_t	*pcfg1Data = NULL;
+	INTERNAL_CMD		 iocmd;
+	CONFIGPARMS		 cfg;
+	dma_addr_t		 cfg1_dma_addr = -1;
+	ConfigPageHeader_t	 header1;
+	int			 bus = 0;
+	int			 id = 0;
+	int			 lun = 0;
+	int			 hostId = ioc->pfacts[portnum].PortSCSIID;
+	int			 max_id;
+	int			 requested, configuration, data;
+	int			 doConfig = 0;
+	u8			 flags, factor;
+
+	max_id = ioc->sh->max_id - 1;
+
+	/* Following parameters will not change
+	 * in this routine.
+	 */
+	iocmd.cmd = CMD_SynchronizeCache;
+	iocmd.flags = 0;
+	iocmd.physDiskNum = -1;
+	iocmd.data = NULL;
+	iocmd.data_dma = -1;
+	iocmd.size = 0;
+	iocmd.rsvd = iocmd.rsvd2 = 0;
+
+	/* No SCSI hosts
+	 */
+	if (hd->Targets == NULL)
+		return 0;
+
+	/* Skip the host
+	 */
+	if (id == hostId)
+		id++;
+
+	/* Write SDP1 for all SCSI devices 
+	 * Alloc memory and set up config buffer
+	 */
+	if (hd->is_spi) {
+		if (ioc->spi_data.sdp1length > 0) {
+			pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
+					 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
+	
+			if (pcfg1Data != NULL) {
+				doConfig = 1;
+				header1.PageVersion = ioc->spi_data.sdp1version;
+				header1.PageLength = ioc->spi_data.sdp1length;
+				header1.PageNumber = 1;
+				header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+				cfg.hdr = &header1;
+				cfg.physAddr = cfg1_dma_addr;
+				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+				cfg.dir = 1;
+				cfg.timeout = 0;
+			}
+		}
+	}
+
+	/* loop through all devices on this port
+	 */
+	while (bus < MPT_MAX_BUS) {
+		iocmd.bus = bus;
+		iocmd.id = id;
+		pTarget = hd->Targets[(int)id];
+
+		if (doConfig) {
+
+			/* Set the negotiation flags */
+			if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
+				flags = pTarget->negoFlags;
+			} else {
+				flags = 0;
+				if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+					data = hd->ioc->spi_data.nvram[id];
+	
+					if (data & MPT_NVRAM_WIDE_DISABLE)
+						flags |= MPT_TARGET_NO_NEGO_WIDE;
+
+					factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
+					if ((factor == 0) || (factor == MPT_ASYNC))
+						flags |= MPT_TARGET_NO_NEGO_SYNC;
+				}
+			}
+	
+			/* Force to async, narrow */
+			mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
+					&configuration, flags);
+			pcfg1Data->RequestedParameters = le32_to_cpu(requested);
+			pcfg1Data->Reserved = 0;
+			pcfg1Data->Configuration = le32_to_cpu(configuration);
+			cfg.pageAddr = (bus<<8) | id;
+			mpt_config(hd->ioc, &cfg);
+		}
+
+		/* If target Ptr NULL or if this target is NOT a disk, skip.
+		 */
+	//	if (pTarget && ((pTarget->inq_data[0] & 0x1F) == 0)) {
+		if (pTarget) {
+			for (lun=0; lun <= MPT_LAST_LUN; lun++) {
+				/* If LUN present, issue the command
+				 */
+				if (pTarget->luns & (1<<lun)) {
+					iocmd.lun = lun;
+					(void) mptscsih_do_cmd(hd, &iocmd);
+				}
+			}
+		}
+
+		/* get next relevant device */
+		id++;
+
+		if (id == hostId)
+			id++;
+
+		if (id > max_id) {
+			id = 0;
+			bus++;
+		}
+	}
+
+	if (pcfg1Data) {
+		pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
+	}
+
+	return 0;
+}
+
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_domainValidation - Top level handler for domain validation.
+ *	@hd: Pointer to MPT_SCSI_HOST structure.
+ *
+ *	Uses the ISR, but with special processing.
+ *	Called from schedule, should not be in interrupt mode.
+ *	While thread alive, do dv for all devices needing dv
+ *
+ *	Return: None.
+ */
+static void
+mptscsih_domainValidation(void *arg)
+{
+	MPT_SCSI_HOST		*hd = NULL;
+	MPT_ADAPTER		*ioc = NULL;
+	unsigned long		 flags;
+	int 			 id, maxid, dvStatus, did;
+	int			 ii, isPhysDisk;
+
+	spin_lock_irqsave(&dvtaskQ_lock, flags);
+	dvtaskQ_active = 1;
+	if (dvtaskQ_release) {
+		dvtaskQ_active = 0;
+		spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+		return;
+	}
+	spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+
+	/* For this ioc, loop through all devices and do dv to each device.
+	 * When complete with this ioc, search through the ioc list, and 
+	 * for each scsi ioc found, do dv for all devices. Exit when no
+	 * device needs dv.
+	 */
+	did = 1;
+	while (did) {
+		did = 0;
+		for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) {
+			spin_lock_irqsave(&dvtaskQ_lock, flags);
+			if (dvtaskQ_release) {
+				dvtaskQ_active = 0;
+				spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+				return;
+			}
+			spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ/4);
+
+			/* DV only to SCSI adapters */
+			if ((int)ioc->chip_type <= (int)FC929)
+				continue;
+			
+			/* Make sure everything looks ok */
+			if (ioc->sh == NULL)
+				continue;
+
+			hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+			if (hd == NULL)
+				continue;
+
+			maxid = MIN (ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
+
+			for (id = 0; id < maxid; id++) {
+				spin_lock_irqsave(&dvtaskQ_lock, flags);
+				if (dvtaskQ_release) {
+					dvtaskQ_active = 0;
+					spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+					return;
+				}
+				spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+				dvStatus = hd->ioc->spi_data.dvStatus[id];
+
+				if (dvStatus & MPT_SCSICFG_NEED_DV) {
+
+					hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
+					hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
+
+					set_current_state(TASK_INTERRUPTIBLE);
+					schedule_timeout(HZ/4);
+
+					/* If hidden phys disk, block IO's to all
+					 *	raid volumes
+					 * else, process normally
+					 */
+					isPhysDisk = 0;
+					if (ioc->spi_data.pIocPg3) {
+						/* Search IOC page 3 to determine if
+						 * this is hidden physical disk
+						 */
+						Ioc3PhysDisk_t *pPDisk =  ioc->spi_data.pIocPg3->PhysDisk;
+						int		numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
+						
+						while (numPDisk) {
+							if (pPDisk->PhysDiskID == id) {
+								isPhysDisk = 1;
+								break;
+							}
+							pPDisk++;
+							numPDisk--;
+						}
+					}
+
+					if (isPhysDisk) {
+						for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
+							if (hd->ioc->spi_data.isRaid & (1 << ii)) {
+								hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
+							}
+						}
+					}
+
+					mptscsih_doDv(hd, 0, id);
+					did++;
+					hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_DONE;
+					hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
+
+					if (isPhysDisk) {
+						for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
+							if (hd->ioc->spi_data.isRaid & (1 << ii)) {
+								hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
+							}
+						}
+					}
+
+					/* Post OS IOs that were pended while
+					 * DV running.
+					 */
+					post_pendingQ_commands(hd);
+				}
+			}
+		}
+	}
+
+	spin_lock_irqsave(&dvtaskQ_lock, flags);
+	dvtaskQ_active = 0;
+	spin_unlock_irqrestore(&dvtaskQ_lock, flags);
+
+	return;
+}
+
+
+#define MPT_GET_NVRAM_VALS	0x01
+#define MPT_UPDATE_MAX		0x02
+#define MPT_SET_MAX		0x04
+#define MPT_SET_MIN		0x08
+#define MPT_FALLBACK		0x10
+#define MPT_SAVE		0x20
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_doDv - Perform domain validation to a target.
+ *	@hd: Pointer to MPT_SCSI_HOST structure.
+ *	@portnum: IOC port number.
+ *	@target: Physical ID of this target
+ *
+ *	Uses the ISR, but with special processing.
+ *	MUST be single-threaded.
+ *	Test will exit if target is at async & narrow.
+ *
+ *	Return: None.
+ */
+static void
+mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
+{
+	MPT_ADAPTER		*ioc = hd->ioc;
+	VirtDevice		*pTarget = NULL;
+	u8			*pbuf1 = NULL;
+	u8			*pbuf2 = NULL;
+	dma_addr_t		 buf1_dma = -1;
+	dma_addr_t		 buf2_dma = -1;
+	ConfigPageHeader_t	 header1;
+	SCSIDevicePage1_t	*pcfg1Data = NULL;
+	dma_addr_t		 cfg1_dma_addr = -1;
+	ConfigPageHeader_t	 header0;
+	SCSIDevicePage0_t	*pcfg0Data = NULL;
+	dma_addr_t		 cfg0_dma_addr = -1;
+	DVPARAMETERS		 dv;
+	INTERNAL_CMD		 iocmd;
+	CONFIGPARMS		 cfg;
+	int			 rc, sz = 0;
+	int			 bufsize = 0;
+	int			 dataBufSize = 0;
+	int			 echoBufSize = 0;
+	int			 notDone;
+	int			 patt;
+	int			 repeat;
+	char			 firstPass = 1;
+	char			 doFallback = 0;
+	char			 readPage0;
+	char			 bus, lun;
+
+	if (ioc->spi_data.sdp1length == 0)
+		return;
+
+	if (ioc->spi_data.sdp0length == 0)
+		return;
+
+	if (id == ioc->pfacts[portnum].PortSCSIID)
+		return;
+
+	lun = 0;
+	bus = 0;
+	ddvtprintk((MYIOC_s_NOTE_FMT 
+			"DV started: numIOs %d bus=%d, id %d dv @ %p\n",
+			ioc->name, atomic_read(&queue_depth), bus, id, &dv));
+
+	/* Prep DV structure
+	 */
+	memset (&dv, 0, sizeof(DVPARAMETERS));
+	dv.id = id;
+
+	/* Populate tmax with the current maximum
+	 * transfer parameters for this target.
+	 * Exit if narrow and async.
+	 */
+	dv.cmd = MPT_GET_NVRAM_VALS;
+	mptscsih_dv_parms(hd, &dv, NULL);
+	if ((!dv.max.width) && (!dv.max.offset))
+		return;
+
+	/* Prep SCSI IO structure
+	 */
+	iocmd.id = id;
+	iocmd.bus = bus;
+	iocmd.lun = lun;
+	iocmd.flags = 0;
+	iocmd.physDiskNum = -1;
+	iocmd.rsvd = iocmd.rsvd2 = 0;
+
+	/* Use tagged commands if possible.
+	 */
+	pTarget = hd->Targets[id];
+	if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
+		iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
+
+	/* Prep cfg structure
+	 */
+	cfg.pageAddr = (bus<<8) | id;
+	cfg.hdr = NULL;
+
+	/* Prep SDP0 header
+	 */
+	header0.PageVersion = ioc->spi_data.sdp0version;
+	header0.PageLength = ioc->spi_data.sdp0length;
+	header0.PageNumber = 0;
+	header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+	pcfg0Data = (SCSIDevicePage0_t *)pci_alloc_consistent(ioc->pcidev,
+				 header0.PageLength * 4, &cfg0_dma_addr);
+	if (!pcfg0Data)
+		return;
+
+	/* Prep SDP1 header
+	 */
+	header1.PageVersion = ioc->spi_data.sdp1version;
+	header1.PageLength = ioc->spi_data.sdp1length;
+	header1.PageNumber = 1;
+	header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+	pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
+				 header1.PageLength * 4, &cfg1_dma_addr);
+	if (!pcfg1Data)
+		goto target_done;
+
+	/* Skip this ID? Set cfg.hdr to force config page write
+	 */
+	if ((ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID) &&
+			(!(ioc->spi_data.nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE))) { 
+
+		ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
+			ioc->name, bus, id, lun));
+
+		dv.cmd = MPT_SET_MAX;
+		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+		cfg.hdr = &header1;
+		goto target_done;
+	}
+
+	/* Finish iocmd inititialization - hidden or visible disk? */
+	if (ioc->spi_data.pIocPg3) {
+		/* Searc IOC page 3 for matching id
+		 */
+		Ioc3PhysDisk_t *pPDisk =  ioc->spi_data.pIocPg3->PhysDisk;
+		int		numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
+
+		while (numPDisk) {
+			if (pPDisk->PhysDiskID == id) {
+				/* match */
+				iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
+				iocmd.physDiskNum = pPDisk->PhysDiskNum;
+
+				/* Quiesce the IM
+				 */
+				if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
+					ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
+					goto target_done;
+				}
+				break;
+			}
+			pPDisk++;
+			numPDisk--;
+		}
+	}
+
+	/* RAID Volume ID's may double for a physical device. If RAID but
+	 * not a physical ID as well, skip DV.
+	 */
+	if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
+		goto target_done;
+
+
+	/* Basic Test.
+	 * Async & Narrow - Inquiry
+	 * Async & Narrow - Inquiry
+	 * Maximum transfer rate - Inquiry
+	 * Compare buffers:
+	 *	If compare, test complete.
+	 *	If miscompare and first pass, repeat
+	 *	If miscompare and not first pass, fall back and repeat
+	 */
+	hd->pLocal = NULL;
+	readPage0 = 0;
+	sz = SCSI_STD_INQUIRY_BYTES;
+	pbuf1 = pci_alloc_consistent(ioc->pcidev, sz, &buf1_dma);
+	pbuf2 = pci_alloc_consistent(ioc->pcidev, sz, &buf2_dma);
+	if (!pbuf1 || !pbuf2)
+		goto target_done;
+
+	while (1) {
+		ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test.\n", ioc->name));
+		dv.cmd = MPT_SET_MIN;
+		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+
+		cfg.hdr = &header1;
+		cfg.physAddr = cfg1_dma_addr;
+		cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+		cfg.dir = 1;
+		if (mpt_config(hd->ioc, &cfg) != 0)
+			goto target_done;
+
+		iocmd.cmd = CMD_Inquiry;
+		iocmd.data_dma = buf1_dma;
+		iocmd.data = pbuf1;
+		iocmd.size = sz;
+		if (mptscsih_do_cmd(hd, &iocmd) < 0)
+			goto target_done;
+
+		/* Another GEM workaround. Check peripheral device type,
+		 * if PROCESSOR, quit DV.
+		 */
+		if (((pbuf1[0] & 0x1F) == 0x03) || ((pbuf1[0] & 0x1F) > 0x08))
+			goto target_done;
+
+		if (mptscsih_do_cmd(hd, &iocmd) < 0)
+			goto target_done;
+
+		if (doFallback)
+			dv.cmd = MPT_FALLBACK;
+		else
+			dv.cmd = MPT_SET_MAX;
+
+		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+		if (mpt_config(hd->ioc, &cfg) != 0)
+			goto target_done;
+
+		if ((!dv.now.width) && (!dv.now.offset))
+			goto target_done;
+
+		iocmd.cmd = CMD_Inquiry;
+		iocmd.data_dma = buf2_dma;
+		iocmd.data = pbuf2;
+		iocmd.size = sz;
+		if (mptscsih_do_cmd(hd, &iocmd) < 0)
+			goto target_done;
+		else if (hd->pLocal == NULL)
+			goto target_done;
+		else {
+			/* Save the return code.
+			 * If this is the first pass,
+			 * read SCSI Device Page 0
+			 * and update the target max parameters.
+			 */
+			rc = hd->pLocal->completion;
+			doFallback = 0;
+			if (rc == MPT_SCANDV_GOOD) {
+				if (!readPage0) {
+					u32 sdp0_info;
+					u32 sdp0_nego;
+
+					cfg.hdr = &header0;
+					cfg.physAddr = cfg0_dma_addr;
+					cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+					cfg.dir = 0;
+					if (mpt_config(hd->ioc, &cfg) != 0)
+						goto target_done;
+
+					sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
+					sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
+
+					/* Quantum and Fujitsu workarounds.
+					 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
+					 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
+					 * Resetart with a request for U160.
+					 */
+					if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) { 
+							doFallback = 1;
+					} else {
+						dv.cmd = MPT_UPDATE_MAX;
+						mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
+						/* Update the SCSI device page 1 area
+						 */
+						pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
+						readPage0 = 1;
+					}
+				}
+
+				/* Quantum workaround. Restart this test will the fallback
+				 * flag set.
+				 */
+				if (doFallback == 0) {
+					if (memcmp(pbuf1, pbuf2, sz) != 0) {
+						if (!firstPass)
+							doFallback = 1;
+					} else
+						break;	/* test complete */
+				}
+
+
+			} else if ((rc == MPT_SCANDV_DID_RESET) || (rc == MPT_SCANDV_SENSE))
+				doFallback = 1;	/* set fallback flag */
+			else
+				goto target_done;
+
+			firstPass = 0;
+		}
+	}
+	/* Free pbuf2, but use pbuf1 for
+	 * acquiring the (echo) buffer size.
+	 */
+	pci_free_consistent(ioc->pcidev, sz, pbuf2, buf2_dma);
+	pbuf2 = NULL;
+	ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test completed OK.\n", ioc->name));
+
+	/* Start the Enhanced Test.
+	 * 0) issue TUR to clear out check conditions
+	 * 1) read capacity of echo (regular) buffer
+	 * 2) reserve device
+	 * 3) do write-read-compare data pattern test
+	 * 4) release
+	 * 5) update nego parms to target struct
+	 */
+	cfg.hdr = &header1;
+	cfg.physAddr = cfg1_dma_addr;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+	cfg.dir = 1;
+
+	iocmd.cmd = CMD_TestUnitReady;
+	iocmd.data_dma = -1;
+	iocmd.data = NULL;
+	iocmd.size = 0;
+	notDone = 1;
+	while (notDone) {
+		if (mptscsih_do_cmd(hd, &iocmd) < 0)
+			goto target_done;
+
+		if (hd->pLocal == NULL)
+			goto target_done;
+
+		rc = hd->pLocal->completion;
+		if (rc == MPT_SCANDV_GOOD)
+			notDone = 0;
+		else if (rc == MPT_SCANDV_SENSE) {
+			u8 skey = hd->pLocal->sense[2] & 0x0F;
+			u8 asc = hd->pLocal->sense[12];
+			u8 ascq = hd->pLocal->sense[13];
+			ddvprintk((MYIOC_s_INFO_FMT
+				"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
+				ioc->name, skey, asc, ascq));
+
+			if (skey == SK_UNIT_ATTENTION)
+				notDone++; /* repeat */
+			else if ((skey == SK_NOT_READY) &&
+					(asc == 0x04)&&(ascq == 0x01)) {
+				/* wait then repeat */
+				mdelay (2000);
+				notDone++;
+			} else if ((skey == SK_NOT_READY) && (asc == 0x3A)) {
+				/* no medium, try read test anyway */
+				notDone = 0;
+			} else {
+				/* All other errors are fatal.
+				 */
+				ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
+						ioc->name));
+				goto target_done;
+			}
+		} else
+			goto target_done;
+	}
+
+	iocmd.cmd = CMD_ReadBuffer;
+	iocmd.data_dma = buf1_dma;
+	iocmd.data = pbuf1;
+	iocmd.size = 4;
+	iocmd.flags |= MPT_ICFLAG_BUF_CAP;
+
+	dataBufSize = 0;
+	echoBufSize = 0;
+	for (patt = 0; patt < 2; patt++) {
+		if (patt == 0)
+			iocmd.flags |= MPT_ICFLAG_ECHO;
+		else
+			iocmd.flags &= ~MPT_ICFLAG_ECHO;
+
+		notDone = 1;
+		while (notDone) {
+			bufsize = 0;
+
+			/* If not ready after 8 trials,
+			 * give up on this device.
+			 */
+			if (notDone > 8)
+				goto target_done;
+
+			if (mptscsih_do_cmd(hd, &iocmd) < 0)
+				goto target_done;
+			else if (hd->pLocal == NULL)
+				goto target_done;
+			else {
+				rc = hd->pLocal->completion;
+				ddvprintk(("ReadBuffer Comp Code %d", rc));
+				ddvprintk(("  buff: %0x %0x %0x %0x\n",
+					pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
+
+				if (rc == MPT_SCANDV_GOOD) {
+					notDone = 0;
+					if (iocmd.flags & MPT_ICFLAG_ECHO) {
+						bufsize =  ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
+					} else {
+						bufsize =  pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
+					}
+				} else if (rc == MPT_SCANDV_SENSE) {
+					u8 skey = hd->pLocal->sense[2] & 0x0F;
+					u8 asc = hd->pLocal->sense[12];
+					u8 ascq = hd->pLocal->sense[13];
+					ddvprintk((MYIOC_s_INFO_FMT
+						"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
+						ioc->name, skey, asc, ascq));
+					if (skey == SK_ILLEGAL_REQUEST) {
+						notDone = 0;
+					} else if (skey == SK_UNIT_ATTENTION) {
+						notDone++; /* repeat */
+					} else if ((skey == SK_NOT_READY) &&
+						(asc == 0x04)&&(ascq == 0x01)) {
+						/* wait then repeat */
+						mdelay (2000);
+						notDone++;
+					} else {
+						/* All other errors are fatal.
+						 */
+						ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
+							ioc->name));
+						goto target_done;
+					}
+				} else {
+					/* All other errors are fatal
+					 */
+					goto target_done;
+				}
+			}
+		}
+
+		if (iocmd.flags & MPT_ICFLAG_ECHO)
+			echoBufSize = bufsize;
+		else
+			dataBufSize = bufsize;
+	}
+	pci_free_consistent(ioc->pcidev, sz, pbuf1, buf1_dma);
+	pbuf1 = NULL;
+	sz = 0;
+	iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
+
+	/* Use echo buffers if possible,
+	 * Exit if both buffers are 0.
+	 */
+	if (echoBufSize > 0) {
+		iocmd.flags |= MPT_ICFLAG_ECHO;
+		if (dataBufSize > 0)
+			bufsize = MIN(echoBufSize, dataBufSize);
+		else
+			bufsize = echoBufSize;
+	} else if (dataBufSize == 0)
+		goto target_done;
+
+	ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
+		(iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
+
+	/* Allocate data buffers for write-read-compare test.
+	 */
+	sz = MIN(bufsize, 1024);
+	pbuf1 = pci_alloc_consistent(ioc->pcidev, sz, &buf1_dma);
+	pbuf2 = pci_alloc_consistent(ioc->pcidev, sz, &buf2_dma);
+	if (!pbuf1 || !pbuf2)
+		goto target_done;
+
+	/* --- loop ----
+	 * On first pass, always issue a reserve.
+	 * On additional loops, only if a reset has occurred.
+	 * iocmd.flags indicates if echo or regular buffer
+	 */
+	for (patt = 0; patt < 4; patt++) {
+		ddvprintk(("Pattern %d\n", patt));
+		if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
+			iocmd.cmd = CMD_TestUnitReady;
+			iocmd.data_dma = -1;
+			iocmd.data = NULL;
+			iocmd.size = 0;
+			if (mptscsih_do_cmd(hd, &iocmd) < 0)
+				goto target_done;
+
+			iocmd.cmd = CMD_Release6;
+			iocmd.data_dma = -1;
+			iocmd.data = NULL;
+			iocmd.size = 0;
+			if (mptscsih_do_cmd(hd, &iocmd) < 0)
+				goto target_done;
+			else if (hd->pLocal == NULL)
+				goto target_done;
+			else {
+				rc = hd->pLocal->completion;
+				ddvprintk(("Release rc %d\n", rc));
+				if (rc == MPT_SCANDV_GOOD)
+					iocmd.flags &= ~MPT_ICFLAG_RESERVED;
+				else
+					goto target_done;
+			}
+			iocmd.flags &= ~MPT_ICFLAG_RESERVED;
+		}
+		iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
+
+		repeat = 5;
+		while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
+			iocmd.cmd = CMD_Reserve6;
+			iocmd.data_dma = -1;
+			iocmd.data = NULL;
+			iocmd.size = 0;
+			if (mptscsih_do_cmd(hd, &iocmd) < 0)
+				goto target_done;
+			else if (hd->pLocal == NULL)
+				goto target_done;
+			else {
+				rc = hd->pLocal->completion;
+				if (rc == MPT_SCANDV_GOOD) {
+					iocmd.flags |= MPT_ICFLAG_RESERVED;
+				} else if (rc == MPT_SCANDV_SENSE) {
+					/* Wait if coming ready
+					 */
+					u8 skey = hd->pLocal->sense[2] & 0x0F;
+					u8 asc = hd->pLocal->sense[12];
+					u8 ascq = hd->pLocal->sense[13];
+					ddvprintk((MYIOC_s_INFO_FMT
+						"DV: Reserve Failed: ", ioc->name));
+					ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
+							skey, asc, ascq));
+
+					if ((skey == SK_NOT_READY) && (asc == 0x04)&&
+									(ascq == 0x01)) {
+						/* wait then repeat */
+						mdelay (2000);
+						notDone++;
+					} else {
+						ddvprintk((MYIOC_s_INFO_FMT 
+							"DV: Reserved Failed.", ioc->name));
+						goto target_done;
+					}
+				} else {
+					ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
+							 ioc->name));
+					goto target_done;
+				}
+			}
+		}
+
+		mptscsih_fillbuf(pbuf1, sz, patt, 1);
+		iocmd.cmd = CMD_WriteBuffer;
+		iocmd.data_dma = buf1_dma;
+		iocmd.data = pbuf1;
+		iocmd.size = sz;
+		if (mptscsih_do_cmd(hd, &iocmd) < 0)
+			goto target_done;
+		else if (hd->pLocal == NULL)
+			goto target_done;
+		else {
+			rc = hd->pLocal->completion;
+			if (rc == MPT_SCANDV_GOOD)
+				;		/* Issue read buffer */
+			else if (rc == MPT_SCANDV_DID_RESET) {
+				/* If using echo buffers, reset to data buffers.
+				 * Else do Fallback and restart
+				 * this test (re-issue reserve
+				 * because of bus reset).
+				 */
+				if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
+					iocmd.flags &= ~MPT_ICFLAG_ECHO;
+				} else {
+					dv.cmd = MPT_FALLBACK;
+					mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+
+					if (mpt_config(hd->ioc, &cfg) != 0)
+						goto target_done;
+
+					if ((!dv.now.width) && (!dv.now.offset))
+						goto target_done;
+				}
+
+				iocmd.flags |= MPT_ICFLAG_DID_RESET;
+				patt = -1;
+				continue;
+			} else if (rc == MPT_SCANDV_SENSE) {
+				/* Restart data test if UA, else quit.
+				 */
+				u8 skey = hd->pLocal->sense[2] & 0x0F;
+				ddvprintk((MYIOC_s_INFO_FMT
+					"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
+					hd->pLocal->sense[12], hd->pLocal->sense[13]));
+				if (skey == SK_UNIT_ATTENTION) {
+					patt = -1;
+					continue;
+				} else if (skey == SK_ILLEGAL_REQUEST) {
+					if (iocmd.flags & MPT_ICFLAG_ECHO) {
+						if (dataBufSize >= bufsize) {
+							iocmd.flags &= ~MPT_ICFLAG_ECHO;
+							patt = -1;
+							continue;
+						}
+					} 
+					goto target_done;
+				}
+				else
+					goto target_done;
+			} else {
+				/* fatal error */
+				goto target_done;
+			}
+		}
+
+		iocmd.cmd = CMD_ReadBuffer;
+		iocmd.data_dma = buf2_dma;
+		iocmd.data = pbuf2;
+		iocmd.size = sz;
+		if (mptscsih_do_cmd(hd, &iocmd) < 0)
+			goto target_done;
+		else if (hd->pLocal == NULL)
+			goto target_done;
+		else {
+			rc = hd->pLocal->completion;
+			if (rc == MPT_SCANDV_GOOD) {
+				 /* If buffers compare,
+				  * go to next pattern,
+				  * else, do a fallback and restart
+				  * data transfer test.
+				  */
+				if (memcmp (pbuf1, pbuf2, sz) == 0) {
+					; /* goto next pattern */
+				} else {
+					/* Miscompare with Echo buffer, go to data buffer,
+					 * if that buffer exists.
+					 * Miscompare with Data buffer, check first 4 bytes,
+					 * some devices return capacity. Exit in this case.
+					 */
+					if (iocmd.flags & MPT_ICFLAG_ECHO) {
+						if (dataBufSize >= bufsize)
+							iocmd.flags &= ~MPT_ICFLAG_ECHO;
+						else
+							goto target_done;
+					} else {
+						if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
+							/* Argh. Device returning wrong data.
+							 * Quit DV for this device.
+							 */
+							goto target_done;
+						}
+
+						/* Had an actual miscompare. Slow down.*/
+						dv.cmd = MPT_FALLBACK;
+						mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+
+						if (mpt_config(hd->ioc, &cfg) != 0)
+							goto target_done;
+
+						if ((!dv.now.width) && (!dv.now.offset))
+							goto target_done;
+					}
+
+					patt = -1;
+					continue;
+				}
+			} else if (rc == MPT_SCANDV_DID_RESET) {
+				/* Do Fallback and restart
+				 * this test (re-issue reserve
+				 * because of bus reset).
+				 */
+				dv.cmd = MPT_FALLBACK;
+				mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+
+				if (mpt_config(hd->ioc, &cfg) != 0)
+					 goto target_done;
+
+				if ((!dv.now.width) && (!dv.now.offset))
+					goto target_done;
+
+				iocmd.flags |= MPT_ICFLAG_DID_RESET;
+				patt = -1;
+				continue;
+			} else if (rc == MPT_SCANDV_SENSE) {
+				/* Restart data test if UA, else quit.
+				 */
+				u8 skey = hd->pLocal->sense[2] & 0x0F;
+				ddvprintk((MYIOC_s_INFO_FMT
+					"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
+					hd->pLocal->sense[12], hd->pLocal->sense[13]));
+				if (skey == SK_UNIT_ATTENTION) {
+					patt = -1;
+					continue;
+				}
+				else
+					goto target_done;
+			} else {
+				/* fatal error */
+				goto target_done;
+			}
+		}
+
+	} /* --- end of patt loop ---- */
+
+target_done:
+	if (iocmd.flags & MPT_ICFLAG_RESERVED) {
+		iocmd.cmd = CMD_Release6;
+		iocmd.data_dma = -1;
+		iocmd.data = NULL;
+		iocmd.size = 0;
+		if (mptscsih_do_cmd(hd, &iocmd) < 0)
+			printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
+					ioc->name, id);
+		else if (hd->pLocal) {
+			if (hd->pLocal->completion == MPT_SCANDV_GOOD)
+				iocmd.flags &= ~MPT_ICFLAG_RESERVED;
+		} else {
+			printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d", 
+						ioc->name, id);
+		}
+	}
+
+
+	/* Set if cfg1_dma_addr contents is valid
+	 */
+	if (cfg.hdr != NULL) {
+		dv.cmd = MPT_SAVE;
+		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+
+		/* Save the final negotiated settings to
+		 * SCSI device page 1.
+		 */
+		cfg.hdr = &header1;
+		cfg.physAddr = cfg1_dma_addr;
+		cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+		cfg.dir = 1;
+		mpt_config(hd->ioc, &cfg);
+	}
+
+	/* If this is a RAID Passthrough, enable internal IOs
+	 */
+	if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
+		if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
+			ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
+	}
+
+	/* Done with the DV scan of the current target
+	 */
+	if (pcfg0Data) {
+		pci_free_consistent(ioc->pcidev, header0.PageLength * 4,
+						pcfg0Data, cfg0_dma_addr);
+	}
+
+	if (pcfg1Data) {
+		pci_free_consistent(ioc->pcidev, header1.PageLength * 4,
+						pcfg1Data, cfg1_dma_addr);
+	}
+
+	if (pbuf1) {
+		pci_free_consistent(ioc->pcidev, sz, pbuf1, buf1_dma);
+		pbuf1 = NULL;
+	}
+
+	if (pbuf2) {
+		pci_free_consistent(ioc->pcidev, sz, pbuf2, buf2_dma);
+		pbuf2 = NULL;
+	}
+
+	ddvtprintk((MYIOC_s_INFO_FMT "DV Done. IOs outstanding = %d\n",
+			ioc->name, atomic_read(&queue_depth)));
+
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	mptscsih_dv_parms - perform a variety of operations on the
+ *	parameters used for negotiation.
+ *	@hd: Pointer to a SCSI host.
+ *	@dv: Pointer to a structure that contains the maximum and current
+ *		negotiated parameters.
+ */
+static void
+mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
+{
+	VirtDevice		*pTarget = NULL;
+	SCSIDevicePage0_t	*pPage0 = NULL;
+	SCSIDevicePage1_t	*pPage1 = NULL;
+	int			val = 0, data, configuration;
+	u8			width = 0;
+	u8			offset = 0;
+	u8			factor = 0;
+	u8			negoFlags = 0;
+	u8			cmd = dv->cmd;
+	u8			id = dv->id;
+
+	switch (cmd) {
+	case MPT_GET_NVRAM_VALS:
+		ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
+							 hd->ioc->name));
+		/* Get the NVRAM values and save in tmax
+		 * If not an LVD bus, the adapter minSyncFactor has been
+		 * already throttled back.
+		 */
+		if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
+			width = pTarget->maxWidth;
+			offset = pTarget->maxOffset;
+			factor = pTarget->minSyncFactor;
+			negoFlags = pTarget->negoFlags;
+		} else {
+			if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+				data = hd->ioc->spi_data.nvram[id];
+				width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
+				if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
+					factor = MPT_ASYNC;
+				else {
+					factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
+					if ((factor == 0) || (factor == MPT_ASYNC)){
+						factor = MPT_ASYNC;
+						offset = 0;
+					}
+				}
+			} else {
+				width = MPT_NARROW;
+				offset = 0;
+				factor = MPT_ASYNC;
+			}
+
+			/* Set the negotiation flags */
+			negoFlags = 0;
+			if (!width)
+				negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
+
+			if (!offset)
+				negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
+		}
+
+		/* limit by adapter capabilities */
+		width = MIN(width, hd->ioc->spi_data.maxBusWidth);
+		offset = MIN(offset, hd->ioc->spi_data.maxSyncOffset);
+		factor = MAX(factor, hd->ioc->spi_data.minSyncFactor);
+
+		/* Check Consistency */
+		if (offset && (factor < MPT_ULTRA2) && !width)
+			factor = MPT_ULTRA2;
+
+		dv->max.width = width;
+		dv->max.offset = offset;
+		dv->max.factor = factor;
+		dv->max.flags = negoFlags;
+		ddvprintk((" width %d, factor %x, offset %x flags %x\n",
+				width, factor, offset, negoFlags));
+		break;
+
+	case MPT_UPDATE_MAX:
+		ddvprintk((MYIOC_s_NOTE_FMT
+			"Updating with SDP0 Data: ", hd->ioc->name));
+		/* Update tmax values with those from Device Page 0.*/
+		pPage0 = (SCSIDevicePage0_t *) pPage;
+		if (pPage0) {
+			val = cpu_to_le32(pPage0->NegotiatedParameters);
+			dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
+			dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
+			dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
+		}
+
+		dv->now.width = dv->max.width;
+		dv->now.offset = dv->max.offset;
+		dv->now.factor = dv->max.factor;
+		ddvprintk(("width %d, factor %x, offset %x, flags %x\n",
+				dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
+		break;
+
+	case MPT_SET_MAX:
+		ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
+								hd->ioc->name));
+		/* Set current to the max values. Update the config page.*/
+		dv->now.width = dv->max.width;
+		dv->now.offset = dv->max.offset;
+		dv->now.factor = dv->max.factor;
+		dv->now.flags = dv->max.flags;
+
+		pPage1 = (SCSIDevicePage1_t *)pPage;
+		if (pPage1) {
+			mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
+				dv->now.offset, &val, &configuration, dv->now.flags);
+			pPage1->RequestedParameters = le32_to_cpu(val);
+			pPage1->Reserved = 0;
+			pPage1->Configuration = le32_to_cpu(configuration);
+
+		}
+
+		ddvprintk(("width %d, factor %x, offset %x request %x, config %x\n",
+				dv->now.width, dv->now.factor, dv->now.offset, val, configuration));
+		break;
+
+	case MPT_SET_MIN:
+		ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
+								hd->ioc->name));
+		/* Set page to asynchronous and narrow 
+		 * Do not update now, breaks fallback routine. */
+		width = MPT_NARROW;
+		offset = 0;
+		factor = MPT_ASYNC;
+		negoFlags = dv->max.flags;
+
+		pPage1 = (SCSIDevicePage1_t *)pPage;
+		if (pPage1) {
+			mptscsih_setDevicePage1Flags (width, factor,
+				offset, &val, &configuration, negoFlags);
+			pPage1->RequestedParameters = le32_to_cpu(val);
+			pPage1->Reserved = 0;
+			pPage1->Configuration = le32_to_cpu(configuration);
+		}
+		ddvprintk(("width %d, factor %x, offset %x request %x config %x\n",
+				dv->now.width, dv->now.factor,
+				dv->now.offset, val, configuration));
+		break;
+
+	case MPT_FALLBACK:
+		ddvprintk((MYIOC_s_NOTE_FMT
+			"Fallback: Start: offset %d, factor %x, width %d \n",
+				hd->ioc->name, dv->now.offset, 
+				dv->now.factor, dv->now.width));
+		width = dv->now.width;
+		offset = dv->now.offset;
+		factor = dv->now.factor;
+		if ((offset) && (dv->max.width)) {
+			if (factor < MPT_ULTRA160)
+				factor = MPT_ULTRA160;
+			else if (factor < MPT_ULTRA2) {
+				factor = MPT_ULTRA2;
+				width = MPT_WIDE;
+			} else if ((factor == MPT_ULTRA2) && width) {
+				factor = MPT_ULTRA2;
+				width = MPT_NARROW;
+			} else if (factor < MPT_ULTRA) {
+				factor = MPT_ULTRA;
+				width = MPT_WIDE;
+			} else if ((factor == MPT_ULTRA) && width) {
+				factor = MPT_ULTRA;
+				width = MPT_NARROW;
+			} else if (factor < MPT_FAST) {
+				factor = MPT_FAST;
+				width = MPT_WIDE;
+			} else if ((factor == MPT_FAST) && width) {
+				factor = MPT_FAST;
+				width = MPT_NARROW;
+			} else if (factor < MPT_SCSI) {
+				factor = MPT_SCSI;
+				width = MPT_WIDE;
+			} else if ((factor == MPT_SCSI) && width) {
+				factor = MPT_SCSI;
+				width = MPT_NARROW;
+			} else {
+				factor = MPT_ASYNC;
+				offset = 0;
+			}
+
+		} else if (offset) {
+			width = MPT_NARROW;
+			if (factor < MPT_ULTRA)
+				factor = MPT_ULTRA;
+			else if (factor < MPT_FAST)
+				factor = MPT_FAST;
+			else if (factor < MPT_SCSI)
+				factor = MPT_SCSI;
+			else {
+				factor = MPT_ASYNC;
+				offset = 0;
+			}
 
-	if (SD_Sense_Key_Specific_Valid(sd)) {
-		if (SenseKey == SK_ILLEGAL_REQUEST) {
-			Offset = SD_Bad_Byte(sd);
-			if (SD_Was_Illegal_Request(sd)) {
-				BadValue = ioop->cdbPtr[Offset];
-				len += sprintf(msg1+len, "\n  Illegal CDB value=%02Xh found at CDB ",
-						BadValue);
 		} else {
-			BadValue = ioop->dataPtr[Offset];
-			len += sprintf(msg1+len, "\n  Illegal DATA value=%02Xh found at DATA ",
-					BadValue);
+			width = MPT_NARROW;
+			factor = MPT_ASYNC;
 		}
-		len += sprintf(msg1+len, "byte=%02Xh", Offset);
-		if (SD_SKS_Bit_Pointer_Valid(sd))
-			len += sprintf(msg1+len, "/bit=%1Xh", SD_SKS_Bit_Pointer(sd));
-		} else if ((SenseKey == SK_RECOVERED_ERROR) ||
-			   (SenseKey == SK_HARDWARE_ERROR) ||
-			   (SenseKey == SK_MEDIUM_ERROR)) {
-			len += sprintf(msg1+len, "\n  Recovery algorithm Actual_Retry_Count=%02Xh",
-			SD_Actual_Retry_Count(sd));
+
+		dv->now.width = width;
+		dv->now.offset = offset;
+		dv->now.factor = factor;
+		dv->now.flags = dv->max.flags;
+
+		pPage1 = (SCSIDevicePage1_t *)pPage;
+		if (pPage1) {
+			mptscsih_setDevicePage1Flags (width, factor, offset, &val,
+						&configuration, dv->now.flags);
+
+			pPage1->RequestedParameters = le32_to_cpu(val);
+			pPage1->Reserved = 0;
+			pPage1->Configuration = le32_to_cpu(configuration);
 		}
-	}
-}
-#endif
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int dump_cdb(char *foo, unsigned char *cdb)
-{
-	int i, grpCode, cdbLen;
-	int l = 0;
+		ddvprintk(("Finish: offset %d, factor %x, width %d, request %x config %x\n",
+			     dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
+		break;
 
-	grpCode = cdb[0] >> 5;
-	if (grpCode < 1)
-		cdbLen = 6;
-	else if (grpCode < 3)
-		cdbLen = 10;
-	else if (grpCode == 5)
-		cdbLen = 12;
-	else
-		cdbLen = 16;
+	case MPT_SAVE:
+		ddvprintk((MYIOC_s_NOTE_FMT
+			"Saving to Target structure: ", hd->ioc->name));
+		ddvprintk(("offset %d, factor %x, width %d \n",
+			     dv->now.offset, dv->now.factor, dv->now.width));
 
-	for (i=0; i < cdbLen; i++)
-		l += sprintf(foo+l, " %02X", cdb[i]);
+		/* Save these values to target structures
+		 * or overwrite nvram (phys disks only).
+		 */
 
-	return l;
-}
+		if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
+			pTarget->maxWidth = dv->now.width;
+			pTarget->maxOffset = dv->now.offset;
+			pTarget->minSyncFactor = dv->now.factor;
+		} else {
+			/* Preserv all flags, use
+			 * read-modify-write algorithm
+			 */
+			data = hd->ioc->spi_data.nvram[id];
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int dump_sd(char *foo, unsigned char *sd)
-{
-	int snsLen = 8 + SD_Additional_Sense_Length(sd);
-	int l = 0;
-	int i;
+			if (dv->now.width)
+				data &= ~MPT_NVRAM_WIDE_DISABLE;
+			else
+				data |= MPT_NVRAM_WIDE_DISABLE;
 
-	for (i=0; i < MIN(snsLen,18); i++)
-		l += sprintf(foo+l, " %02X", sd[i]);
-	l += sprintf(foo+l, "%s", snsLen>18 ? " ..." : "");
+			if (!dv->now.offset)
+				factor = MPT_ASYNC;
 
-	return l;
+			data &= ~MPT_NVRAM_SYNC_MASK;
+			data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
+
+			hd->ioc->spi_data.nvram[id] = data;
+		}
+		break;
+	}
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*  Do ASC/ASCQ lookup/grindage to English readable string(s)  */
-static const char * ascq_set_strings_4max(
-		u8 ASC, u8 ASCQ,
-		const char **s1, const char **s2, const char **s3, const char **s4)
+/*	mptscsih_fillbuf - fill a buffer with a special data pattern
+ *		cleanup. For bus scan only.
+ *
+ *	@buffer: Pointer to data buffer to be filled.
+ *	@size: Number of bytes to fill
+ *	@index: Pattern index
+ *	@width: bus width, 0 (8 bits) or 1 (16 bits)
+ */
+static void
+mptscsih_fillbuf(char *buffer, int size, int index, int width)
 {
-	static const char *asc_04_part1_string = "LOGICAL UNIT ";
-	static const char *asc_04_part2a_string = "NOT READY, ";
-	static const char *asc_04_part2b_string = "IS ";
-	static const char *asc_04_ascq_NN_part3_strings[] = {	/* ASC ASCQ (hex) */
-	  "CAUSE NOT REPORTABLE",				/* 04 00 */
-	  "IN PROCESS OF BECOMING READY",			/* 04 01 */
-	  "INITIALIZING CMD. REQUIRED",				/* 04 02 */
-	  "MANUAL INTERVENTION REQUIRED",			/* 04 03 */
-	  /* Add	" IN PROGRESS" to all the following... */
-	  "FORMAT",						/* 04 04 */
-	  "REBUILD",						/* 04 05 */
-	  "RECALCULATION",					/* 04 06 */
-	  "OPERATION",						/* 04 07 */
-	  "LONG WRITE",						/* 04 08 */
-	  "SELF-TEST",						/* 04 09 */
-	  NULL
-	};
-	static char *asc_04_part4_string = " IN PROGRESS";
+	char *ptr = buffer;
+	int ii;
+	char byte;
+	short val;
 
-	static char *asc_29_ascq_NN_strings[] = {		/* ASC ASCQ (hex) */
-	  "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED",	/* 29 00 */
-	  "POWER ON OCCURRED",					/* 29 01 */
-	  "SCSI BUS RESET OCCURRED",				/* 29 02 */
-	  "BUS DEVICE RESET FUNCTION OCCURRED",			/* 29 03 */
-	  "DEVICE INTERNAL RESET",				/* 29 04 */
-	  "TRANSCEIVER MODE CHANGED TO SINGLE-ENDED",		/* 29 05 */
-	  "TRANSCEIVER MODE CHANGED TO LVD",			/* 29 06 */
-	  NULL
-	};
-	static char *ascq_vendor_uniq = "(Vendor Unique)";
-	static char *ascq_noone = "(no matching ASC/ASCQ description found)";
-	int idx;
+	switch (index) {
+	case 0:
 
-	*s1 = *s2 = *s3 = *s4 = "";		/* set'em all to the empty "" string */
+		if (width) {
+			/* Pattern:  0000 FFFF 0000 FFFF
+			 */
+			for (ii=0; ii < size; ii++, ptr++) {
+				if (ii & 0x02)
+					*ptr = 0xFF;
+				else
+					*ptr = 0x00;
+			}
+		} else {
+			/* Pattern:  00 FF 00 FF
+			 */
+			for (ii=0; ii < size; ii++, ptr++) {
+				if (ii & 0x01)
+					*ptr = 0xFF;
+				else
+					*ptr = 0x00;
+			}
+		}
+		break;
 
-	/* CHECKME! Need lock/sem?
-	 *  Update and examine for isense module presense.
-	 */
-	mptscsih_ASCQ_TablePtr = (ASCQ_Table_t *)mpt_v_ASCQ_TablePtr;
+	case 1:
+		if (width) {
+			/* Pattern:  5555 AAAA 5555 AAAA 5555
+			 */
+			for (ii=0; ii < size; ii++, ptr++) {
+				if (ii & 0x02)
+					*ptr = 0xAA;
+				else
+					*ptr = 0x55;
+			}
+		} else {
+			/* Pattern:  55 AA 55 AA 55
+			 */
+			for (ii=0; ii < size; ii++, ptr++) {
+				if (ii & 0x01)
+					*ptr = 0xAA;
+				else
+					*ptr = 0x55;
+			}
+		}
+		break;
 
-	if (mptscsih_ASCQ_TablePtr == NULL) {
-		/* 2nd chances... */
-		if (ASC == 0x04 && (ASCQ < sizeof(asc_04_ascq_NN_part3_strings)/sizeof(char*)-1)) {
-			*s1 = asc_04_part1_string;
-			*s2 = (ASCQ == 0x01) ? asc_04_part2b_string : asc_04_part2a_string;
-			*s3 = asc_04_ascq_NN_part3_strings[ASCQ];
-			/* check for " IN PROGRESS" ones */
-			if (ASCQ >= 0x04)
-				*s4 = asc_04_part4_string;
-		} else if (ASC == 0x29 && (ASCQ < sizeof(asc_29_ascq_NN_strings)/sizeof(char*)-1))
-			*s1 = asc_29_ascq_NN_strings[ASCQ];
-		/*
-		 *	else { leave all *s[1-4] values pointing to the empty "" string }
+	case 2:
+		/* Pattern:  00 01 02 03 04 05
+		 * ... FE FF 00 01..
 		 */
-		return *s1;
-	}
+		for (ii=0; ii < size; ii++, ptr++)
+			*ptr = (char) ii;
+		break;
 
-	/*
-	 *  Need to check ASC here; if it is "special," then
-	 *  the ASCQ is variable, and indicates failed component number.
-	 *  We must treat the ASCQ as a "don't care" while searching the
-	 *  mptscsih_ASCQ_Table[] by masking it off, and then restoring it later
-	 *  on when we actually need to identify the failed component.
-	 */
-	if (SPECIAL_ASCQ(ASC,ASCQ))
-		ASCQ = 0xFF;
+	case 3:
+		if (width) {
+			/* Wide Pattern:  FFFE 0001 FFFD 0002
+			 * ...  4000 DFFF 8000 EFFF
+			 */
+			byte = 0;
+			for (ii=0; ii < size/2; ii++) {
+				/* Create the base pattern
+				 */
+				val = (1 << byte);
+				/* every 64 (0x40) bytes flip the pattern
+				 * since we fill 2 bytes / iteration,
+				 * test for ii = 0x20
+				 */
+				if (ii & 0x20)
+					val = ~(val);
 
-	/*  OK, now search mptscsih_ASCQ_Table[] for a matching entry  */
-	for (idx = 0; mptscsih_ASCQ_TablePtr && idx < mpt_ASCQ_TableSz; idx++)
-		if ((ASC == mptscsih_ASCQ_TablePtr[idx].ASC) && (ASCQ == mptscsih_ASCQ_TablePtr[idx].ASCQ))
-			return (*s1 = mptscsih_ASCQ_TablePtr[idx].Description);
+				if (ii & 0x01) {
+					*ptr = (char)( (val & 0xFF00) >> 8);
+					ptr++;
+					*ptr = (char)(val & 0xFF);
+					byte++;
+					byte &= 0x0F;
+				} else {
+					val = ~val;
+					*ptr = (char)( (val & 0xFF00) >> 8);
+					ptr++;
+					*ptr = (char)(val & 0xFF);
+				}
 
-	if ((ASC >= 0x80) || (ASCQ >= 0x80))
-		*s1 = ascq_vendor_uniq;
-	else
-		*s1 = ascq_noone;
+				ptr++;
+			}
+		} else {
+			/* Narrow Pattern:  FE 01 FD 02 FB 04
+			 * .. 7F 80 01 FE 02 FD ...  80 7F
+			 */
+			byte = 0;
+			for (ii=0; ii < size; ii++, ptr++) {
+				/* Base pattern - first 32 bytes
+				 */
+				if (ii & 0x01) {
+					*ptr = (1 << byte);
+					byte++;
+					byte &= 0x07;
+				} else {
+					*ptr = (char) (~(1 << byte));
+				}
 
-	return *s1;
+				/* Flip the pattern every 32 bytes
+				 */
+				if (ii & 0x20)
+					*ptr = ~(*ptr);
+			}
+		}
+		break;
+	}
 }
+#endif /* ~MPTSCSIH_DISABLE_DOMAIN_VALIDATION */
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  SCSI Error Report; desired output format...
- *---
-SCSI Error Report =-=-=-=-=-=-=-=-=-=-=-=-=-= (ioc0,scsi0:0)
-  SCSI_Status=02h (CHECK CONDITION)
-  Original_CDB[]: 00 00 00 00 00 00 - TestUnitReady
-  SenseData[12h]: 70 00 06 00 00 00 00 0A 00 00 00 00 29 00 03 00 00 00
-  SenseKey=6h (UNIT ATTENTION); FRU=03h
-  ASC/ASCQ=29h/00h, "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED"
- *---
+/* Commandline Parsing routines and defines.
+ *
+ * insmod format:
+ *	insmod mptscsih mptscsih="width:1 dv:n factor:0x09"
+ *  boot format:
+ *	mptscsih=width:1,dv:n,factor:0x8
+ *
  */
+#ifdef MODULE
+#define	ARG_SEP	' '
+#else
+#define	ARG_SEP	','
+#endif
 
-int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop)
-{
-	char		 foo[512];
-	char		 buf2[32];
-	char		*statstr;
-	const char	*opstr;
-	int		 sk		= SD_Sense_Key(ioop->sensePtr);
-	const char	*skstr		= SenseKeyString[sk];
-	unsigned char	 asc		= SD_ASC(ioop->sensePtr);
-	unsigned char	 ascq		= SD_ASCQ(ioop->sensePtr);
-	int		 l;
+static char setup_token[] __initdata =
+	"dv:"
+	"width:"
+	"factor:"
+       ;	/* DONNOT REMOVE THIS ';' */
+
+#define OPT_DV			1
+#define OPT_MAX_WIDTH		2
+#define OPT_MIN_SYNC_FACTOR	3
 
-	/*
-	 *  More quiet mode.
-	 *  Filter out common, repetitive, warning-type errors...  like:
-	 *    POWER ON (06,29/00 or 06,29/01),
-	 *    SPINNING UP (02,04/01),
-	 *    LOGICAL UNIT NOT SUPPORTED (05,25/00), etc.
-	 */
-	if (	(sk==SK_UNIT_ATTENTION	&& asc==0x29 && (ascq==0x00 || ascq==0x01))
-	     || (sk==SK_NOT_READY	&& asc==0x04 && ascq==0x01)
-	     || (sk==SK_ILLEGAL_REQUEST && asc==0x25 && ascq==0x00)
-	   )
-	{
-		/* Do nothing! */
-		return 0;
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+__init get_setup_token(char *p)
+{
+	char *cur = setup_token;
+	char *pc;
+	int i = 0;
+
+	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+		++pc;
+		++i;
+		if (!strncmp(p, cur, pc - cur))
+			return i;
+		cur = pc;
 	}
+	return 0;
+}
 
-	/*
-	 *  Protect ourselves...
-	 */
-	if (ioop->cdbPtr == NULL)
-		ioop->cdbPtr = dummyCDB;
-	if (ioop->sensePtr == NULL)
-		ioop->sensePtr = dummySenseData;
-	if (ioop->inqPtr == NULL)
-		ioop->inqPtr = dummyInqData;
-	if (ioop->dataPtr == NULL)
-		ioop->dataPtr = dummyScsiData;
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+__init mptscsih_setup(char *str)
+{
+	char *cur = str;
+	char *pc, *pv;
+	unsigned long val;
+	int  c;
+
+	printk("KERN_WARNING: mptscsih_setup arg %s\n", str);
+
+	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+		char *pe;
+
+		val = 0;
+		pv = pc;
+		c = *++pv;
+
+		if	(c == 'n')
+			val = 0;
+		else if	(c == 'y')
+			val = 1;
+		else
+			val = (int) simple_strtoul(pv, &pe, 0);
 
-	statstr = NULL;
-	if ((ioop->SCSIStatus >= sizeof(ScsiStatusString)/sizeof(char*)-1) ||
-	    ((statstr = (char*)ScsiStatusString[ioop->SCSIStatus]) == NULL)) {
-		(void) sprintf(buf2, "Bad-Reserved-%02Xh", ioop->SCSIStatus);
-		statstr = buf2;
-	}
+		printk("Found Token: %s, value %x\n", cur, (int)val);
+		switch (get_setup_token(cur)) {
+		case OPT_DV:
+			driver_setup.dv = val;
+			break;
 
-	opstr = NULL;
-	if (1+ioop->cdbPtr[0] <= sizeof(ScsiCommonOpString)/sizeof(char*))
-		opstr = ScsiCommonOpString[ioop->cdbPtr[0]];
-	else if (mpt_ScsiOpcodesPtr)
-		opstr = mpt_ScsiOpcodesPtr[ioop->cdbPtr[0]];
+		case OPT_MAX_WIDTH:
+			driver_setup.max_width = val;
+			break;
 
-	l = sprintf(foo, "SCSI Error Report =-=-= (%s)\n"
-	  "  SCSI_Status=%02Xh (%s)\n"
-	  "  Original_CDB[]:",
-			ioop->DevIDStr,
-			ioop->SCSIStatus,
-			statstr);
-	l += dump_cdb(foo+l, ioop->cdbPtr);
-	if (opstr)
-		l += sprintf(foo+l, " - \"%s\"", opstr);
-	l += sprintf(foo+l, "\n  SenseData[%02Xh]:", 8+SD_Additional_Sense_Length(ioop->sensePtr));
-	l += dump_sd(foo+l, ioop->sensePtr);
-	l += sprintf(foo+l, "\n  SenseKey=%Xh (%s); FRU=%02Xh\n  ASC/ASCQ=%02Xh/%02Xh",
-			sk, skstr, SD_FRU(ioop->sensePtr), asc, ascq );
+		case OPT_MIN_SYNC_FACTOR:
+			driver_setup.min_sync_fac = val;
+			break;
 
-	{
-		const char	*x1, *x2, *x3, *x4;
-		x1 = x2 = x3 = x4 = "";
-		x1 = ascq_set_strings_4max(asc, ascq, &x1, &x2, &x3, &x4);
-		if (x1 != NULL) {
-			if (x1[0] != '(')
-				l += sprintf(foo+l, " \"%s%s%s%s\"", x1,x2,x3,x4);
-			else
-				l += sprintf(foo+l, " %s%s%s%s", x1,x2,x3,x4);
+		default:
+			printk("mptscsih_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
+			break;
 		}
-	}
-
-#if 0
-	if (SPECIAL_ASCQ(asc,ascq))
-		l += sprintf(foo+l, " (%02Xh)", ascq);
-#endif
-
-	PrintF(("%s\n", foo));
 
-	return l;
+		if ((cur = strchr(cur, ARG_SEP)) != NULL)
+			++cur;
+	}
+	return 1;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/mptscsih.h linux/drivers/message/fusion/mptscsih.h
--- linux.orig/drivers/message/fusion/mptscsih.h	2001-07-07 00:03:11.000000000 +0000
+++ linux/drivers/message/fusion/mptscsih.h	2002-07-20 01:08:40.000000000 +0000
@@ -15,11 +15,12 @@
  *
  *      (see also mptbase.c)
  *
- *  Copyright (c) 1999-2001 LSI Logic Corporation
+ *  Copyright (c) 1999-2002 LSI Logic Corporation
  *  Originally By: Steven J. Ralston
- *  (mailto:Steve.Ralston@lsil.com)
+ *  (mailto:netscape.net)
+ *  (mailto:Pam.Delaney@lsil.com)
  *
- *  $Id: mptscsih.h,v 1.7 2001/01/11 16:56:43 sralston Exp $
+ *  $Id: mptscsih.h,v 1.16 2002/02/27 18:44:30 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -68,14 +69,47 @@
  *	SCSI Public stuff...
  */
 
-#ifdef __sparc__
-#define MPT_SCSI_CAN_QUEUE	63
-#define MPT_SCSI_CMD_PER_LUN	63
-	/* FIXME!  Still investigating qd=64 hang on sparc64... */
-#else
-#define MPT_SCSI_CAN_QUEUE	64
-#define MPT_SCSI_CMD_PER_LUN	64
-#endif
+/*
+ *	Try to keep these at 2^N-1
+ */
+#define MPT_FC_CAN_QUEUE	63
+#define MPT_SCSI_CAN_QUEUE	31
+#define MPT_SCSI_CMD_PER_LUN	 7
+
+#define MPT_SCSI_SG_DEPTH	40
+
+/* To disable domain validation, uncomment the
+ * following line. No effect for FC devices.
+ * For SCSI devices, driver will negotiate to
+ * NVRAM settings (if available) or to maximum adapter
+ * capabilities.
+ */
+/* #define MPTSCSIH_DISABLE_DOMAIN_VALIDATION */
+
+
+/* SCSI driver setup structure. Settings can be overridden
+ * by command line options.
+ */
+#define MPTSCSIH_DOMAIN_VALIDATION      1
+#define MPTSCSIH_MAX_WIDTH              1
+#define MPTSCSIH_MIN_SYNC               0x08
+
+struct mptscsih_driver_setup
+{
+        u8      dv;
+        u8      max_width;
+        u8      min_sync_fac;
+};
+
+
+#define MPTSCSIH_DRIVER_SETUP                   \
+{                                               \
+        MPTSCSIH_DOMAIN_VALIDATION,             \
+        MPTSCSIH_MAX_WIDTH,                     \
+        MPTSCSIH_MIN_SYNC,                      \
+}
+
+
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -143,6 +177,7 @@
 #define x_scsi_dev_reset	mptscsih_dev_reset
 #define x_scsi_host_reset	mptscsih_host_reset
 #define x_scsi_bios_param	mptscsih_bios_param
+#define x_scsi_select_queue_depths	mptscsih_select_queue_depths
 
 #define x_scsi_taskmgmt_bh	mptscsih_taskmgmt_bh
 #define x_scsi_old_abort	mptscsih_old_abort
@@ -155,7 +190,6 @@
 extern	int		 x_scsi_detect(Scsi_Host_Template *);
 extern	int		 x_scsi_release(struct Scsi_Host *host);
 extern	const char	*x_scsi_info(struct Scsi_Host *);
-/*extern	int		 x_scsi_command(Scsi_Cmnd *);*/
 extern	int		 x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 #ifdef MPT_SCSI_USE_NEW_EH
 extern	int		 x_scsi_abort(Scsi_Cmnd *);
@@ -167,6 +201,7 @@
 extern	int		 x_scsi_old_reset(Scsi_Cmnd *, unsigned int);
 #endif
 extern	int		 x_scsi_bios_param(Disk *, kdev_t, int *);
+extern	void		 x_scsi_select_queue_depths(struct Scsi_Host *, Scsi_Device *);
 extern	void		 x_scsi_taskmgmt_bh(void *);
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
@@ -194,7 +229,7 @@
 	bios_param:			x_scsi_bios_param,	\
 	can_queue:			MPT_SCSI_CAN_QUEUE,	\
 	this_id:			-1,			\
-	sg_tablesize:			25,			\
+	sg_tablesize:			MPT_SCSI_SG_DEPTH,	\
 	cmd_per_lun:			MPT_SCSI_CMD_PER_LUN,	\
 	unchecked_isa_dma:		0,			\
 	use_clustering:			ENABLE_CLUSTERING,	\
@@ -217,7 +252,7 @@
 	bios_param:			x_scsi_bios_param,	\
 	can_queue:			MPT_SCSI_CAN_QUEUE,	\
 	this_id:			-1,			\
-	sg_tablesize:			25,			\
+	sg_tablesize:			MPT_SCSI_SG_DEPTH,	\
 	cmd_per_lun:			MPT_SCSI_CMD_PER_LUN,	\
 	unchecked_isa_dma:		0,			\
 	use_clustering:			ENABLE_CLUSTERING	\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/fusion/scsi3.h linux/drivers/message/fusion/scsi3.h
--- linux.orig/drivers/message/fusion/scsi3.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/message/fusion/scsi3.h	2002-07-20 01:08:34.000000000 +0000
@@ -4,11 +4,12 @@
  *      (Ultimately) SCSI-3 definitions; for now, inheriting
  *      SCSI-2 definitions.
  *
- *  Copyright (c) 1996-2001 Steven J. Ralston
+ *  Copyright (c) 1996-2002 Steven J. Ralston
  *  Written By: Steven J. Ralston (19960517)
- *  (mailto:Steve.Ralston@lsil.com)
+ *  (mailto:sjralston1@netscape.net)
+ *  (mailto:Pam.Delaney@lsil.com)
  *
- *  $Id: scsi3.h,v 1.5 2001/04/06 14:31:32 sralston Exp $
+ *  $Id: scsi3.h,v 1.9 2002/02/27 18:45:02 sralston Exp $
  */
 
 #ifndef SCSI3_H_INCLUDED
@@ -63,7 +64,10 @@
 #define CMD_Write10            0x2A
 #define CMD_WriteVerify        0x2E
 #define CMD_Verify             0x2F
+#define CMD_SynchronizeCache   0x35
 #define CMD_ReadDefectData     0x37
+#define CMD_WriteBuffer        0x3B
+#define CMD_ReadBuffer         0x3C
 #define CMD_ReadLong           0x3E
 #define CMD_LogSelect          0x4C
 #define CMD_LogSense           0x4D
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/Makefile linux/drivers/message/i2o/Makefile
--- linux.orig/drivers/message/i2o/Makefile	2000-12-29 22:07:21.000000000 +0000
+++ linux/drivers/message/i2o/Makefile	2002-07-20 01:08:26.000000000 +0000
@@ -9,8 +9,13 @@
 
 export-objs	:= i2o_pci.o i2o_core.o i2o_config.o i2o_block.o i2o_lan.o i2o_scsi.o i2o_proc.o
 
+#
+# Do not touch the order here 
+# We must link i2o_core, then i2o_pci, then protocols
+#
+obj-$(CONFIG_I2O)	+= i2o_core.o
 obj-$(CONFIG_I2O_PCI)	+= i2o_pci.o
-obj-$(CONFIG_I2O)	+= i2o_core.o i2o_config.o
+obj-$(CONFIG_I2O)	+= i2o_config.o
 obj-$(CONFIG_I2O_BLOCK)	+= i2o_block.o
 obj-$(CONFIG_I2O_LAN)	+= i2o_lan.o
 obj-$(CONFIG_I2O_SCSI)	+= i2o_scsi.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/README linux/drivers/message/i2o/README
--- linux.orig/drivers/message/i2o/README	2000-06-19 20:30:55.000000000 +0000
+++ linux/drivers/message/i2o/README	2002-07-20 01:08:33.000000000 +0000
@@ -1,49 +1,99 @@
-
-	Linux I2O Support	(c) Copyright 1999 Red Hat Software
-					and others.
+	Linux I2O Support	(c) Copyright 1999-2002 Red Hat and others.
 
 	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.
 
-AUTHORS (so far)
 
-Alan Cox, Building Number Three Ltd.
-	Core code, SCSI and Block OSMs
+Hardware Compatibility
+-----------------------
+
+This is an informal test summary. It is not definitive as a reference work
+or guaranteed of any accuracy.
+
+Last updated for 2.4.19pre7-ac1
 
-Steve Ralston, LSI Logic Corp.
-	Debugging SCSI and Block OSM
 
-Deepak Saxena, Intel Corp.
-	Various core/block extensions
-	/proc interface, bug fixes
-	Ioctl interfaces for control
-	Debugging LAN OSM
-
-Philip Rumpf
-	Fixed assorted dumb SMP locking bugs
-
-Juha Sievanen, University of Helsinki Finland
-	LAN OSM code
-	/proc interface to LAN class
-	Bug fixes
-	Core code extensions
-
-Auvo Häkkinen, University of Helsinki Finland
-	LAN OSM code
-	/Proc interface to LAN class
-	Bug fixes
-	Core code extensions
+Tested Hardware			block	config	lan	proc	scsi
+-----------------------------------------------------------------------
+Current Release
+	AMI MegaRAID[0]		YES	YES	N/A	YES	N/A
+
+
+Previous Stable Release (2.4.18ac3)
+	AMI MegaRAID[0]		FAIL
+	DPT Smartraid		------------ Use dpt_i2o module ------------
+	Intel SCU RAID		FAIL[2]	???	N/A	???	FAIL[2]
+	Promise Supertrak100	YES[3]	YES[3]	N/A	YES[3]	N/A
+	Promise SX6000		YES[3]	YES[3]	N/A	YES[3]	N/A
+	Symbios FC920		YES	YES[4]	N/A	YES	YES
+
+
+[0] In I2O mode. For normal mode use the megaraid driver
+[1] Initialisation oddities and scsi failure. Use dpt_i2o module instead.
+[2] Card hangs under certain load patterns.
+[3] The driver works correctly. Certain values are misreported by this
+card but the results are only cosmetic. Firmware updates are required for some
+very early cards. Set the card into I2O not 'Linux' mode.
+[4] HTML configuration mode not available.
+
+Requirements
+------------
+
+I2O 1.5 compliant hardware
+PCI bus interrupt driven I2O devices
+Devices in classes Block, Lan or SCSI.
+32bit I2O messages supported
+
+Limitations
+-----------
+64bit message formats are not supported (64bit I2O is basically a whole 
+		different driver variant)
+I2O Tape class is not supported (no known devices using this..)
+Currently only 32bit x86 platforms are supported.
+
+
+Authors
+--------
+	Alan Cox, Building Number Three Ltd.
+		Core code, SCSI and Block OSMs
+
+	Steve Ralston, LSI Logic Corp.
+		Debugging SCSI and Block OSM
+
+	Deepak Saxena, Intel Corp.
+		Various core/block extensions
+		/proc interface, bug fixes
+		Ioctl interfaces for control
+		Debugging LAN OSM
+
+	Philip Rumpf
+		Fixed assorted dumb SMP locking bugs
+
+	Juha Sievanen, University of Helsinki Finland
+		LAN OSM code
+		/proc interface to LAN class
+		Bug fixes
+		Core code extensions
+
+	Auvo Häkkinen, University of Helsinki Finland
+		LAN OSM code
+		/Proc interface to LAN class
+		Bug fixes
+		Core code extensions
 
-Taneli Vähäkangas, University of Helsinki Finland
-	Fixes to i2o_config
+	Taneli Vähäkangas, University of Helsinki Finland
+		Fixes to i2o_config
 
-CREDITS
+	Boji T Kannanthanam
+		Intel i2o controller work, extending proc/config stuff
 
+Credits
+--------
 	This work was made possible by 
 
-Red Hat Software
+Red Hat
 	Funding for the Building #3 part of the project
 
 Symbios Logic (Now LSI)
@@ -62,32 +112,26 @@
 ASUSTeK
         Loan of I2O motherboard 
 
-STATUS:
+Promise
+	Providing a Supertrak 100 board and support info
 
-o	The core setup works within limits.
-o	The scsi layer seems to almost work. 
-           I'm still chasing down the hang bug.
-o	The block OSM is mostly functional
-o	LAN OSM works with FDDI and Ethernet cards.
+DPT (now Adaptec)
+	Providing a DPT smartraid I2O card (use dpt_i2o for this
+	board however)
 
-TO DO:
 
 General:
-o	Provide hidden address space if asked
-o	Long term message flow control
+o	Finish 64bit and big endian cleanup
+o	Switch to new PCI mapping layer throughout
+o	Hotswap of controllers
 o	PCI IOP's without interrupts are not supported yet
 o	Push FAIL handling into the core
-o	DDM control interfaces for module load etc
-o       Add I2O 2.0 support (Deffered to 2.5 kernel)
 
 Block:
-o	Multiple major numbers
-o	Read ahead and cache handling stuff. Talk to Ingo and people
+o	Multiple major numbers (problem goes away in 2.5)
 o	Power management
-o	Finish Media changers
 
 SCSI:
-o	Find the right way to associate drives/luns/busses
 
 Lan:	
 o	Performance tuning
@@ -95,4 +139,3 @@
 
 Tape:
 o	Anyone seen anything implementing this ?
-           (D.S: Will attempt to do so if spare cycles permit)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/i2o_block.c linux/drivers/message/i2o/i2o_block.c
--- linux.orig/drivers/message/i2o/i2o_block.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/message/i2o/i2o_block.c	2002-07-20 01:08:27.000000000 +0000
@@ -21,6 +21,11 @@
  *	Alan Cox:	
  *		FC920 has an rmw bug. Dont or in the end marker.
  *		Removed queue walk, fixed for 64bitness.
+ *		Rewrote much of the code over time
+ *		Added indirect block lists
+ *		Handle 64K limits on many controllers
+ *		Don't use indirects on the Promise (breaks)
+ *		Heavily chop down the queue depths
  *	Deepak Saxena:
  *		Independent queues per IOP
  *		Support for dynamic device creation/deletion
@@ -75,7 +80,7 @@
 
 #define MAX_I2OB	16
 
-#define MAX_I2OB_DEPTH	128
+#define MAX_I2OB_DEPTH	8
 #define MAX_I2OB_RETRIES 4
 
 //#define DRIVERDEBUG
@@ -140,9 +145,12 @@
 	struct request *head, *tail;
 	request_queue_t *req_queue;
 	int max_segments;
+	int max_direct;		/* Not yet used properly */
 	int done_flag;
-	int constipated;
 	int depth;
+	int rcache;
+	int wcache;
+	int power;
 };
 
 /*
@@ -150,6 +158,7 @@
  *	We should cache align these to avoid ping-ponging lines on SMP
  *	boxes under heavy I/O load...
  */
+
 struct i2ob_request
 {
 	struct i2ob_request *next;
@@ -173,8 +182,6 @@
 	request_queue_t req_queue;
 };
 static struct i2ob_iop_queue *i2ob_queues[MAX_I2O_CONTROLLERS];
-static struct i2ob_request *i2ob_backlog[MAX_I2O_CONTROLLERS];
-static struct i2ob_request *i2ob_backlog_tail[MAX_I2O_CONTROLLERS];
 
 /*
  *	Each I2O disk is one of these.
@@ -192,10 +199,7 @@
 static DECLARE_MUTEX_LOCKED(i2ob_evt_sem);
 static DECLARE_COMPLETION(i2ob_thread_dead);
 static spinlock_t i2ob_evt_lock = SPIN_LOCK_UNLOCKED;
-static u32 evt_msg[MSG_FRAME_SIZE>>2];
-
-static struct timer_list i2ob_timer;
-static int i2ob_timer_started = 0;
+static u32 evt_msg[MSG_FRAME_SIZE];
 
 static void i2o_block_reply(struct i2o_handler *, struct i2o_controller *,
 	 struct i2o_message *);
@@ -205,7 +209,6 @@
 static int i2ob_install_device(struct i2o_controller *, struct i2o_device *, int);
 static void i2ob_end_request(struct request *);
 static void i2ob_request(request_queue_t *);
-static int i2ob_backlog_request(struct i2o_controller *, struct i2ob_device *);
 static int i2ob_init_iop(unsigned int);
 static request_queue_t* i2ob_get_queue(kdev_t);
 static int i2ob_query_device(struct i2ob_device *, int, int, void*, int);
@@ -230,8 +233,12 @@
 	I2O_CLASS_RANDOM_BLOCK_STORAGE
 };
 
-/*
- *	Get a message
+/**
+ *	i2ob_get	-	Get an I2O message
+ *	@dev:  I2O block device
+ *
+ *	Get a message from the FIFO used for this block device. The message is returned
+ *	or the I2O 'no message' value of 0xFFFFFFFF if nothing is available.
  */
 
 static u32 i2ob_get(struct i2ob_device *dev)
@@ -240,10 +247,24 @@
    	return I2O_POST_READ32(c);
 }
  
-/*
- *	Turn a Linux block request into an I2O block read/write.
+/**
+ *	i2ob_send		-	Turn a request into a message and send it
+ *	@m: Message offset
+ *	@dev: I2O device
+ *	@ireq: Request structure
+ *	@base: Partition offset
+ *	@unit: Device identity
+ *
+ *	Generate an I2O BSAREAD request. This interface function is called for devices that
+ *	appear to explode when they are fed indirect chain pointers (notably right now this
+ *	appears to afflict Promise hardwre, so be careful what you feed the hardware
+ *
+ *	No cleanup is done by this interface. It is done on the interrupt side when the
+ *	reply arrives
+ *
+ *	To Fix: Generate PCI maps of the buffers
  */
-
+ 
 static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq, u32 base, int unit)
 {
 	struct i2o_controller *c = dev->controller;
@@ -290,9 +311,9 @@
 				size += bh->b_size;
 				last += bh->b_size;
 				if(bh->b_reqnext)
-					__raw_writel(0x14000000|(size), mptr-8);
+					__raw_writel(0x10000000|(size), mptr-8);
 				else
-					__raw_writel(0xD4000000|(size), mptr-8);
+					__raw_writel(0xD0000000|(size), mptr-8);
 			}
 			else
 			{
@@ -309,16 +330,22 @@
 			count -= bh->b_size;
 			bh = bh->b_reqnext;
 		}
-		/*
-		 *	Heuristic for now since the block layer doesnt give
-		 *	us enough info. If its a big write assume sequential
-		 *	readahead on controller. If its small then don't read
-		 *	ahead but do use the controller cache.
-		 */
-		if(size >= 8192)
-			__raw_writel((8<<24)|(1<<16)|8, msg+16);
-		else
-			__raw_writel((8<<24)|(1<<16)|4, msg+16);
+		switch(dev->rcache)
+		{
+			case CACHE_NULL:
+				__raw_writel(0, msg+16);break;
+			case CACHE_PREFETCH:
+				__raw_writel(0x201F0008, msg+16);break;
+			case CACHE_SMARTFETCH:
+				if(req->nr_sectors > 16)
+					__raw_writel(0x201F0008, msg+16);
+				else
+					__raw_writel(0x001F0000, msg+16);
+				break;
+		}				
+				
+//		printk("Reading %d entries %d bytes.\n",
+//			mptr-msg-8, req->nr_sectors<<9);
 	}
 	else if(req->cmd == WRITE)
 	{
@@ -350,28 +377,29 @@
 			bh = bh->b_reqnext;
 		}
 
-		if(c->battery)
-		{
-			
-			if(size>16384)
-				__raw_writel(4, msg+16);
-			else
-				/* 
-				 * Allow replies to come back once data is cached in the controller
-				 * This allows us to handle writes quickly thus giving more of the
-				 * queue to reads.
-				 */
-				__raw_writel(16, msg+16);
-		}
-		else
+		switch(dev->wcache)
 		{
-			/* Large write, don't cache */
-			if(size>8192)
-				__raw_writel(4, msg+16);
-			else
-			/* write through */
-				__raw_writel(8, msg+16);
+			case CACHE_NULL:
+				__raw_writel(0, msg+16);break;
+			case CACHE_WRITETHROUGH:
+				__raw_writel(0x001F0008, msg+16);break;
+			case CACHE_WRITEBACK:
+				__raw_writel(0x001F0010, msg+16);break;
+			case CACHE_SMARTBACK:
+				if(req->nr_sectors > 16)
+					__raw_writel(0x001F0004, msg+16);
+				else
+					__raw_writel(0x001F0010, msg+16);
+				break;
+			case CACHE_SMARTTHROUGH:
+				if(req->nr_sectors > 16)
+					__raw_writel(0x001F0004, msg+16);
+				else
+					__raw_writel(0x001F0010, msg+16);
 		}
+				
+//		printk("Writing %d entries %d bytes.\n",
+//			mptr-msg-8, req->nr_sectors<<9);
 	}
 	__raw_writel(I2O_MESSAGE_SIZE(mptr-msg)>>2 | SGL_OFFSET_8, msg);
 	
@@ -405,6 +433,8 @@
  
 static inline void i2ob_end_request(struct request *req)
 {
+	/* FIXME  - pci unmap the request */
+
 	/*
 	 * Loop until all of the buffers that are linked
 	 * to this request have been marked updated and
@@ -423,6 +453,7 @@
 /*
  * Request merging functions
  */
+
 static inline int i2ob_new_segment(request_queue_t *q, struct request *req,
 				  int __max_segments)
 {
@@ -491,11 +522,11 @@
 	 *	thing for other cases too.
 	 */
 	 	
-	__raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
-	__raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4);
-	__raw_writel(i2ob_context|(unit<<8), msg+8);
-	__raw_writel(0, msg+12);
-	__raw_writel(60<<16, msg+16);
+	i2o_raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
+	i2o_raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4);
+	i2o_raw_writel(i2ob_context|(unit<<8), msg+8);
+	i2o_raw_writel(0, msg+12);
+	i2o_raw_writel(60<<16, msg+16);
 	DEBUG("FLUSH");
 	i2o_post_message(c,m);
 	return 0;
@@ -531,7 +562,7 @@
 		 * We increment the error count and abort it
 		 *
 		 * In theory this will never happen.  The I2O block class
-		 * speficiation states that block devices never return
+		 * specification states that block devices never return
 		 * FAILs but instead use the REQ status field...but
 		 * better be on the safe side since no one really follows
 		 * the spec to the book :)
@@ -561,17 +592,6 @@
 		return;
 	}
 
-	if(msg->function == I2O_CMD_BLOCK_CFLUSH)
-	{
-		spin_lock_irqsave(&io_request_lock, flags);
-		dev->constipated=0;
-		DEBUG("unconstipated\n");
-		if(i2ob_backlog_request(c, dev)==0)
-			i2ob_request(dev->req_queue);
-		spin_unlock_irqrestore(&io_request_lock, flags);
-		return;
-	}
-
 	if(!dev->i2odev)
 	{
 		/*
@@ -629,64 +649,12 @@
 		 *	The second is that you have a SuperTrak 100 and the
 		 *	firmware got constipated. Unlike standard i2o card
 		 *	setups the supertrak returns an error rather than
-		 *	blocking for the timeout in these cases.
+		 *	blocking for the timeout in these cases. 
+		 *
+		 *	Don't stick a supertrak100 into cache aggressive modes
 		 */
 		 
 		
-		spin_lock_irqsave(&io_request_lock, flags);
-		if(err==4)
-		{
-			/*
-			 *	Time to uncork stuff
-			 */
-			
-			if(!dev->constipated)
-			{
-				dev->constipated = 1;
-				DEBUG(("constipated\n"));
-				/* Now pull the chain */
-				if(i2ob_flush(c, dev, unit)<0)
-				{
-					DEBUG(("i2ob: Unable to queue flush. Retrying I/O immediately.\n"));
-					dev->constipated=0;
-				}
-				DEBUG(("flushing\n"));
-			}
-			
-			/*
-			 *	Recycle the request
-			 */
-			 
-//			i2ob_unhook_request(ireq, c->unit);
-			
-			/*
-			 *	Place it on the recycle queue
-			 */
-			 
-			ireq->next = NULL;
-			if(i2ob_backlog_tail[c->unit]!=NULL)
-				i2ob_backlog_tail[c->unit]->next = ireq;
-			else
-				i2ob_backlog[c->unit] = ireq;			
-			i2ob_backlog_tail[c->unit] = ireq;
-			
-			atomic_dec(&i2ob_queues[c->unit]->queue_depth);
-
-			/*
-			 *	If the constipator flush failed we want to
-			 *	poke the queue again. 
-			 */
-			 
-			i2ob_request(dev->req_queue);
-			spin_unlock_irqrestore(&io_request_lock, flags);
-			
-			/*
-			 *	and out
-			 */
-			 
-			return;	
-		}
-		spin_unlock_irqrestore(&io_request_lock, flags);
 		printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, 
 			bsa_errors[m[4]&0XFFFF]);
 		if(m[4]&0x00FF0000)
@@ -706,14 +674,12 @@
 	i2ob_unhook_request(ireq, c->unit);
 	i2ob_end_request(ireq->req);
 	atomic_dec(&i2ob_queues[c->unit]->queue_depth);
-
+	
 	/*
 	 *	We may be able to do more I/O
 	 */
-
-	if(i2ob_backlog_request(c, dev)==0)
-		i2ob_request(dev->req_queue);
-
+	 
+	i2ob_request(dev->req_queue);
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
@@ -734,6 +700,7 @@
 		u32 evt_indicator;
 		u8 ASC;
 		u8 ASCQ;
+		u16 pad;
 		u8 data[16];
 		} *evt_local;
 
@@ -764,8 +731,8 @@
 		evt_local = (struct i2o_reply *)evt_msg;
 		spin_unlock_irqrestore(&i2ob_evt_lock, flags);
 
-		unit = evt_local->header[3];
-		evt = evt_local->evt_indicator;
+		unit = le32_to_cpu(evt_local->header[3]);
+		evt = le32_to_cpu(evt_local->evt_indicator);
 
 		switch(evt)
 		{
@@ -864,6 +831,15 @@
 			 * An event we didn't ask for.  Call the card manufacturer
 			 * and tell them to fix their firmware :)
 			 */
+			 
+			case 0x20:
+				/*
+				 * If a promise card reports 0x20 event then the brown stuff
+				 * hit the fan big time. The card seems to recover but loses
+				 * the pending writes. Deeply ungood except for testing fsck
+				 */
+				if(i2ob_dev[unit].i2odev->controller->bus.pci.promise)
+					panic("I2O controller firmware failed. Reboot and force a filesystem check.\n");
 			default:
 				printk(KERN_INFO "%s: Received event 0x%X we didn't register for\n"
 					KERN_INFO "   Blame the I2O card manufacturer 8)\n", 
@@ -877,68 +853,6 @@
 }
 
 /*
- * The timer handler will attempt to restart requests 
- * that are queued to the driver.  This handler
- * currently only gets called if the controller
- * had no more room in its inbound fifo.  
- */
-
-static void i2ob_timer_handler(unsigned long q)
-{
-	unsigned long flags;
-
-	/*
-	 * We cannot touch the request queue or the timer
-         * flag without holding the io_request_lock.
-	 */
-	spin_lock_irqsave(&io_request_lock,flags);
-
-	/* 
-	 * Clear the timer started flag so that 
-	 * the timer can be queued again.
-	 */
-	i2ob_timer_started = 0;
-
-	/* 
-	 * Restart any requests.
-	 */
-	i2ob_request((request_queue_t*)q);
-
-	/* 
-	 * Free the lock.
-	 */
-	spin_unlock_irqrestore(&io_request_lock,flags);
-}
-
-static int i2ob_backlog_request(struct i2o_controller *c, struct i2ob_device *dev)
-{
-	u32 m;
-	struct i2ob_request *ireq;
-	
-	while((ireq=i2ob_backlog[c->unit])!=NULL)
-	{
-		int unit;
-
-		if(atomic_read(&i2ob_queues[c->unit]->queue_depth) > dev->depth/4)
-			break;
-
-		m = i2ob_get(dev);
-		if(m == 0xFFFFFFFF)
-			break;
-
-		i2ob_backlog[c->unit] = ireq->next;
-		if(i2ob_backlog[c->unit] == NULL)
-			i2ob_backlog_tail[c->unit] = NULL;
-			
-		unit = MINOR(ireq->req->rq_dev);
-		i2ob_send(m, dev, ireq, i2ob[unit].start_sect, unit);
-	}
-	if(i2ob_backlog[c->unit])
-		return 1;
-	return 0;
-}
-
-/*
  *	The I2O block driver is listed as one of those that pulls the
  *	front entry off the queue before processing it. This is important
  *	to remember here. If we drop the io lock then CURRENT will change
@@ -954,7 +868,6 @@
 	struct i2ob_device *dev;
 	u32 m;
 	
-	
 	while (!list_empty(&q->queue_head)) {
 		/*
 		 *	On an IRQ completion if there is an inactive
@@ -977,49 +890,15 @@
 		if(atomic_read(&i2ob_queues[dev->unit]->queue_depth) >= dev->depth)
 			break;
 		
-		/*
-		 *	Is the channel constipated ?
-		 */
-
-		if(i2ob_backlog[dev->unit]!=NULL)
-			break;
-			
 		/* Get a message */
 		m = i2ob_get(dev);
 
 		if(m==0xFFFFFFFF)
 		{
-			/* 
-			 * See if the timer has already been queued.
-			 */
-			if (!i2ob_timer_started)
-			{
-				DEBUG((KERN_ERR "i2ob: starting timer\n"));
-
-				/*
-				 * Set the timer_started flag to insure
-				 * that the timer is only queued once.
-				 * Queing it more than once will corrupt
-				 * the timer queue.
-				 */
-				i2ob_timer_started = 1;
-
-				/* 
-				 * Set up the timer to expire in
-				 * 500ms.
-				 */
-				i2ob_timer.expires = jiffies + (HZ >> 1);
-				i2ob_timer.data = (unsigned int)q;
-
-				/*
-				 * Start it.
-				 */
-				 
-				add_timer(&i2ob_timer);
-				return;
-			}
+			if(atomic_read(&i2ob_queues[dev->unit]->queue_depth) == 0)
+				printk(KERN_ERR "i2o_block: message queue and request queue empty!!\n");
+			break;
 		}
-
 		/*
 		 * Everything ok, so pull from kernel queue onto our queue
 		 */
@@ -1151,11 +1030,6 @@
 
 	dev = &i2ob_dev[minor];
 	switch (cmd) {
-		case BLKGETSIZE:
-			return put_user(i2ob[minor].nr_sects, (long *) arg);
-		case BLKGETSIZE64:
-			return put_user((u64)i2ob[minor].nr_sects << 9, (u64 *)arg);
-
 		case HDIO_GETGEO:
 		{
 			struct hd_geometry g;
@@ -1165,23 +1039,31 @@
 			g.start = i2ob[minor].start_sect;
 			return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0;
 		}
+		
+		case BLKI2OGRSTRAT:
+			return put_user(dev->rcache, (int *)arg);
+		case BLKI2OGWSTRAT:
+			return put_user(dev->wcache, (int *)arg);
+		case BLKI2OSRSTRAT:
+			if(arg<0||arg>CACHE_SMARTFETCH)
+				return -EINVAL;
+			dev->rcache = arg;
+			break;
+		case BLKI2OSWSTRAT:
+			if(arg!=0 && (arg<CACHE_WRITETHROUGH || arg>CACHE_SMARTBACK))
+				return -EINVAL;
+			dev->wcache = arg;
+			break;
 	
 		case BLKRRPART:
 			if(!capable(CAP_SYS_ADMIN))
 				return -EACCES;
 			return do_i2ob_revalidate(inode->i_rdev,1);
 			
-		case BLKFLSBUF:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKRASET:
-		case BLKRAGET:
-		case BLKPG:
-			return blk_ioctl(inode->i_rdev, cmd, arg);
-			
 		default:
-			return -EINVAL;
+			return blk_ioctl(inode->i_rdev, cmd, arg);
 	}
+	return 0;
 }
 
 /*
@@ -1219,7 +1101,7 @@
 		 */
 		u32 msg[5];
 		int *query_done = &dev->done_flag;
-		msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+		msg[0] = (FIVE_WORD_MSG_SIZE|SGL_OFFSET_0);
 		msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid;
 		msg[2] = i2ob_context|0x40000000;
 		msg[3] = (u32)query_done;
@@ -1238,7 +1120,17 @@
 		DEBUG("Unlocking...");
 		i2o_post_wait(dev->controller, msg, 20, 2);
 		DEBUG("Unlocked.\n");
-	
+
+		msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+		msg[1] = I2O_CMD_BLOCK_POWER<<24 | HOST_TID << 12 | dev->tid;
+		if(dev->flags & (1<<3|1<<4))	/* Removable */
+			msg[4] = 0x21 << 24;
+		else
+			msg[4] = 0x24 << 24;
+
+		if(i2o_post_wait(dev->controller, msg, 20, 60)==0)
+			dev->power = 0x24;
+
 		/*
  		 * Now unclaim the device.
 		 */
@@ -1282,7 +1174,19 @@
 			return -EBUSY;
 		}
 		DEBUG("Claimed ");
-		
+		/*
+	 	 *	Power up if needed
+	 	 */
+
+		if(dev->power > 0x1f)
+		{
+			msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+			msg[1] = I2O_CMD_BLOCK_POWER<<24 | HOST_TID << 12 | dev->tid;
+			msg[4] = 0x02 << 24;
+			if(i2o_post_wait(dev->controller, msg, 20, 60) == 0)
+				dev->power = 0x02;
+		}
+
 		/*
 		 *	Mount the media if needed. Note that we don't use
 		 *	the lock bit. Since we have to issue a lock if it
@@ -1329,8 +1233,8 @@
 {
 	u64 size;
 	u32 blocksize;
-	u32 limit;
 	u8 type;
+	u16 power;
 	u32 flags, status;
 	struct i2ob_device *dev=&i2ob_dev[unit];
 	int i;
@@ -1352,6 +1256,8 @@
 		i2ob_query_device(dev, 0x0000, 4, &size, 8);
 	}
 	
+	if(i2ob_query_device(dev, 0x0000, 2, &power, 2)!=0)
+		power = 0;
 	i2ob_query_device(dev, 0x0000, 5, &flags, 4);
 	i2ob_query_device(dev, 0x0000, 6, &status, 4);
 	i2ob_sizes[unit] = (int)(size>>10);
@@ -1360,28 +1266,29 @@
 	i2ob_gendisk.part[unit].nr_sects = size>>9;
 	i2ob[unit].nr_sects = (int)(size>>9);
 
-	/* Set limit based on inbound frame size */
-	limit = (d->controller->status_block->inbound_frame_size - 8)/2;
-	limit = limit<<9;
-
 	/*
 	 * Max number of Scatter-Gather Elements
 	 */	
 
+	i2ob_dev[unit].power = power;	/* Save power state in device proper */
+	i2ob_dev[unit].flags = flags;
+
 	for(i=unit;i<=unit+15;i++)
 	{
-		i2ob_max_sectors[i] = 256;
-		i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 8)/2;
-
-		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 2)
-			i2ob_dev[i].depth = 32;
+		i2ob_dev[i].power = power;	/* Save power state */
+		i2ob_dev[unit].flags = flags;	/* Keep the type info */
+		i2ob_max_sectors[i] = 96;	/* 256 might be nicer but many controllers 
+						   explode on 65536 or higher */
+		i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 7) / 2;
+		
+		i2ob_dev[i].rcache = CACHE_SMARTFETCH;
+		i2ob_dev[i].wcache = CACHE_WRITETHROUGH;
+		
+		if(d->controller->battery == 0)
+			i2ob_dev[i].wcache = CACHE_WRITETHROUGH;
 
-		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 1)
-		{
-			i2ob_max_sectors[i] = 32;
-			i2ob_dev[i].max_segments = 8;
-			i2ob_dev[i].depth = 4;
-		}
+		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.promise)
+			i2ob_dev[i].wcache = CACHE_WRITETHROUGH;
 
 		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req)
 		{
@@ -1390,11 +1297,10 @@
 		}
 	}
 
-
 	sprintf(d->dev_name, "%s%c", i2ob_gendisk.major_name, 'a' + (unit>>4));
 
 	printk(KERN_INFO "%s: Max segments %d, queue depth %d, byte limit %d.\n",
-		 d->dev_name, i2ob_dev[unit].max_segments, i2ob_dev[unit].depth, limit);
+		 d->dev_name, i2ob_dev[unit].max_segments, i2ob_dev[unit].depth, i2ob_max_sectors[unit]<<9);
 
 	i2ob_query_device(dev, 0x0000, 0, &type, 1);
 
@@ -1410,14 +1316,19 @@
 	}
 	if(status&(1<<10))
 		printk("(RAID)");
-	if(((flags & (1<<3)) && !(status & (1<<3))) ||
-	   ((flags & (1<<4)) && !(status & (1<<4))))
+
+	if((flags^status)&(1<<4|1<<3))	/* Missing media or device */
 	{
 		printk(KERN_INFO " Not loaded.\n");
-		return 1;
+		/* Device missing ? */
+		if((flags^status)&(1<<4))
+			return 1;
+	}
+	else
+	{
+		printk(": %dMB, %d byte sectors",
+			(int)(size>>20), blocksize);
 	}
-	printk(": %dMB, %d byte sectors",
-		(int)(size>>20), blocksize);
 	if(status&(1<<0))
 	{
 		u32 cachesize;
@@ -1427,7 +1338,6 @@
 			printk(", %dMb cache", cachesize>>10);
 		else
 			printk(", %dKb cache", cachesize);
-		
 	}
 	printk(".\n");
 	printk(KERN_INFO "%s: Maximum sectors/read set to %d.\n", 
@@ -1471,7 +1381,7 @@
 {
 	int i;
 
-	i2ob_queues[unit] = (struct i2ob_iop_queue*) kmalloc(sizeof(struct i2ob_iop_queue), GFP_ATOMIC);
+	i2ob_queues[unit] = (struct i2ob_iop_queue *) kmalloc(sizeof(struct i2ob_iop_queue), GFP_ATOMIC);
 	if(!i2ob_queues[unit])
 	{
 		printk(KERN_WARNING "Could not allocate request queue for I2O block device!\n");
@@ -1671,8 +1581,7 @@
 
 	if(i2o_claim_device(d, &i2o_block_handler))
 	{
-		printk(KERN_INFO 
-			"i2o_block: Unable to claim device. Installation aborted\n");
+		printk(KERN_INFO "i2o_block: Unable to claim device. Installation aborted\n");
 		return;
 	}
 
@@ -1859,11 +1768,7 @@
  *  (Just smiley confuses emacs :-)
  */
 
-#ifdef MODULE
-#define i2o_block_init init_module
-#endif
-
-int i2o_block_init(void)
+static int i2o_block_init(void)
 {
 	int i;
 
@@ -1918,14 +1823,6 @@
 	}
 
 	/*
-	 *	Timers
-	 */
-	 
-	init_timer(&i2ob_timer);
-	i2ob_timer.function = i2ob_timer_handler;
-	i2ob_timer.data = 0;
-	
-	/*
 	 *	Register the OSM handler as we will need this to probe for
 	 *	drives, geometry and other goodies.
 	 */
@@ -1968,15 +1865,8 @@
 	return 0;
 }
 
-#ifdef MODULE
 
-EXPORT_NO_SYMBOLS;
-MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Block Device OSM");
-MODULE_LICENSE("GPL");
-
-
-void cleanup_module(void)
+static void i2o_block_exit(void)
 {
 	int i;
 	
@@ -2036,4 +1926,11 @@
 
 	del_gendisk(&i2ob_gendisk);
 }
-#endif
+
+EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Red Hat Software");
+MODULE_DESCRIPTION("I2O Block Device OSM");
+MODULE_LICENSE("GPL");
+
+module_init(i2o_block_init);
+module_exit(i2o_block_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/i2o_config.c linux/drivers/message/i2o/i2o_config.c
--- linux.orig/drivers/message/i2o/i2o_config.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/message/i2o/i2o_config.c	2002-07-20 01:08:39.000000000 +0000
@@ -447,7 +447,7 @@
 	int token;
 	u32 len;
 	u32 reslen;
-	u32 msg[MSG_FRAME_SIZE/4];
+	u32 msg[MSG_FRAME_SIZE];
 
 	if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_html)))
 	{
@@ -908,11 +908,7 @@
 	&config_fops
 };	
 
-#ifdef MODULE
-int init_module(void)
-#else
-int __init i2o_config_init(void)
-#endif
+static int __init i2o_config_init(void)
 {
 	printk(KERN_INFO "I2O configuration manager v 0.04.\n");
 	printk(KERN_INFO "  (C) Copyright 1999 Red Hat Software\n");
@@ -946,9 +942,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-
-void cleanup_module(void)
+static void i2o_config_exit(void)
 {
 	misc_deregister(&i2o_miscdev);
 	
@@ -963,4 +957,5 @@
 MODULE_DESCRIPTION("I2O Configuration");
 MODULE_LICENSE("GPL");
 
-#endif
+module_init(i2o_config_init);
+module_exit(i2o_config_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/i2o_core.c linux/drivers/message/i2o/i2o_core.c
--- linux.orig/drivers/message/i2o/i2o_core.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/message/i2o/i2o_core.c	2002-07-20 01:08:38.000000000 +0000
@@ -70,7 +70,7 @@
 static int core_context;
 
 /* Initialization && shutdown functions */
-static void i2o_sys_init(void);
+void i2o_sys_init(void);
 static void i2o_sys_shutdown(void);
 static int i2o_reset_controller(struct i2o_controller *);
 static int i2o_reboot_event(struct notifier_block *, unsigned long , void *);
@@ -120,28 +120,6 @@
  */
 static spinlock_t i2o_dev_lock = SPIN_LOCK_UNLOCKED;
 
-#ifdef MODULE
-/* 
- * Function table to send to bus specific layers
- * See <include/linux/i2o.h> for explanation of this
- */
-static struct i2o_core_func_table i2o_core_functions =
-{
-	i2o_install_controller,
-	i2o_activate_controller,
-	i2o_find_controller,
-	i2o_unlock_controller,
-	i2o_run_queue,
-	i2o_delete_controller
-};
-
-#ifdef CONFIG_I2O_PCI_MODULE
-extern int i2o_pci_core_attach(struct i2o_core_func_table *);
-extern void i2o_pci_core_detach(void);
-#endif /* CONFIG_I2O_PCI_MODULE */
-
-#endif /* MODULE */
-
 /*
  * Structures and definitions for synchronous message posting.
  * See i2o_post_wait() for description.
@@ -2013,10 +1991,10 @@
  	 */
 	msg[6] = 0x54000000 | sys_tbl_len;
 	msg[7] = virt_to_bus(sys_tbl);
-	msg[8] = 0x54000000 | 8;
-	msg[9] = virt_to_bus(privbuf);
-	msg[10] = 0xD4000000 | 8;
-	msg[11] = virt_to_bus(privbuf+2);
+	msg[8] = 0x54000000 | privbuf[1];
+	msg[9] = privbuf[0];
+	msg[10] = 0xD4000000 | privbuf[3];
+	msg[11] = privbuf[2];
 
 	ret=i2o_post_wait_mem(iop, msg, sizeof(msg), 120, privbuf, NULL);
 	
@@ -2044,7 +2022,7 @@
 /*
  * Initialize I2O subsystem.
  */
-static void __init i2o_sys_init(void)
+void __init i2o_sys_init(void)
 {
 	struct i2o_controller *iop, *niop = NULL;
 
@@ -2220,9 +2198,8 @@
 	msg[2]= core_context;
 	msg[3]= 0x0106;				/* Transaction context */
 	msg[4]= 4096;				/* Host page frame size */
-	/* Frame size is in words. Pick 128, its what everyone elses uses and
-		other sizes break some adapters. */
-	msg[5]= MSG_FRAME_SIZE<<16|0x80;	/* Outbound msg frame size and Initcode */
+	/* Frame size is in words. 256 bytes a frame for now */
+	msg[5]= MSG_FRAME_SIZE<<16|0x80;	/* Outbound msg frame size in words and Initcode */
 	msg[6]= 0xD0000004;			/* Simple SG LE, EOB */
 	msg[7]= virt_to_bus(status);
 
@@ -2295,7 +2272,7 @@
 	for(i=0; i< NMBR_MSG_FRAMES; i++) {
 		I2O_REPLY_WRITE32(c,m);
 		mb();
-		m += MSG_FRAME_SIZE;
+		m += (MSG_FRAME_SIZE << 2);
 	}
 
 	return 0;
@@ -2479,9 +2456,8 @@
 		sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
 		sys_tbl->iops[count].iop_capabilities = 
 				iop->status_block->iop_capabilities;
-		sys_tbl->iops[count].inbound_low = 
-				(u32)virt_to_bus(iop->post_port);
-		sys_tbl->iops[count].inbound_high = 0;	// TODO: 64-bit support
+		sys_tbl->iops[count].inbound_low = iop->post_port;
+		sys_tbl->iops[count].inbound_high = 0;	// FIXME: 64-bit support
 
 		count++;
 	}
@@ -3433,6 +3409,10 @@
 EXPORT_SYMBOL(i2o_install_handler);
 EXPORT_SYMBOL(i2o_remove_handler);
 
+EXPORT_SYMBOL(i2o_install_controller);
+EXPORT_SYMBOL(i2o_delete_controller);
+EXPORT_SYMBOL(i2o_run_queue);
+
 EXPORT_SYMBOL(i2o_claim_device);
 EXPORT_SYMBOL(i2o_release_device);
 EXPORT_SYMBOL(i2o_device_notify_on);
@@ -3457,37 +3437,27 @@
 
 EXPORT_SYMBOL(i2o_get_class_name);
 
-#ifdef MODULE
+EXPORT_SYMBOL_GPL(i2o_sys_init);
 
 MODULE_AUTHOR("Red Hat Software");
 MODULE_DESCRIPTION("I2O Core");
 MODULE_LICENSE("GPL");
 
-
-
-int init_module(void)
+static int i2o_core_init(void)
 {
 	printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n");
 	if (i2o_install_handler(&i2o_core_handler) < 0)
 	{
-		printk(KERN_ERR 
-			"i2o_core: Unable to install core handler.\nI2O stack not loaded!");
+		printk(KERN_ERR "i2o_core: Unable to install core handler.\nI2O stack not loaded!");
 		return 0;
 	}
 
 	core_context = i2o_core_handler.context;
 
 	/*
-	 * Attach core to I2O PCI transport (and others as they are developed)
-	 */
-#ifdef CONFIG_I2O_PCI_MODULE
-	if(i2o_pci_core_attach(&i2o_core_functions) < 0)
-		printk(KERN_INFO "i2o: No PCI I2O controllers found\n");
-#endif
-
-	/*
 	 * Initialize event handling thread
 	 */	
+
 	init_MUTEX_LOCKED(&evt_sem);
 	evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND);
 	if(evt_pid < 0)
@@ -3507,7 +3477,7 @@
 	return 0;
 }
 
-void cleanup_module(void)
+static void i2o_core_exit(void)
 {
 	int stat;
 
@@ -3528,73 +3498,10 @@
 		}
 		printk("done.\n");
 	}
-
-#ifdef CONFIG_I2O_PCI_MODULE
-	i2o_pci_core_detach();
-#endif
-
 	i2o_remove_handler(&i2o_core_handler);
-
 	unregister_reboot_notifier(&i2o_reboot_notifier);
 }
 
-#else
-
-extern int i2o_block_init(void);
-extern int i2o_config_init(void);
-extern int i2o_lan_init(void);
-extern int i2o_pci_init(void);
-extern int i2o_proc_init(void);
-extern int i2o_scsi_init(void);
-
-int __init i2o_init(void)
-{
-	printk(KERN_INFO "Loading I2O Core - (c) Copyright 1999 Red Hat Software\n");
-	
-	if (i2o_install_handler(&i2o_core_handler) < 0)
-	{
-		printk(KERN_ERR 
-			"i2o_core: Unable to install core handler.\nI2O stack not loaded!");
-		return 0;
-	}
-
-	core_context = i2o_core_handler.context;
-
-	/*
-	 * Initialize event handling thread
-	 * We may not find any controllers, but still want this as 
-	 * down the road we may have hot pluggable controllers that
-	 * need to be dealt with.
-	 */	
-	init_MUTEX_LOCKED(&evt_sem);
-	if((evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND)) < 0)
-	{
-		printk(KERN_ERR "I2O: Could not create event handler kernel thread\n");
-		i2o_remove_handler(&i2o_core_handler);
-		return 0;
-	}
-
+module_init(i2o_core_init);
+module_exit(i2o_core_exit);
 
-#ifdef CONFIG_I2O_PCI
-	i2o_pci_init();
-#endif
-
-	if(i2o_num_controllers)
-		i2o_sys_init();
-
-	register_reboot_notifier(&i2o_reboot_notifier);
-
-	i2o_config_init();
-#ifdef CONFIG_I2O_BLOCK
-	i2o_block_init();
-#endif
-#ifdef CONFIG_I2O_LAN
-	i2o_lan_init();
-#endif
-#ifdef CONFIG_I2O_PROC
-	i2o_proc_init();
-#endif
-	return 0;
-}
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/i2o_lan.c linux/drivers/message/i2o/i2o_lan.c
--- linux.orig/drivers/message/i2o/i2o_lan.c	2001-10-22 15:39:56.000000000 +0000
+++ linux/drivers/message/i2o/i2o_lan.c	2002-07-20 01:08:27.000000000 +0000
@@ -1430,11 +1430,7 @@
 	return dev;
 }
 
-#ifdef MODULE
-#define i2o_lan_init	init_module
-#endif
-
-int __init i2o_lan_init(void)
+static int __init i2o_lan_init(void)
 {
 	struct net_device *dev;
 	int i;
@@ -1515,9 +1511,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-
-void cleanup_module(void)
+static void i2o_lan_exit(void)
 {
 	int i;
 
@@ -1576,4 +1570,5 @@
 MODULE_PARM(tx_batch_mode, "0-2" "i");
 MODULE_PARM_DESC(tx_batch_mode, "0=Send immediatelly, 1=Send in batches, 2=Switch automatically");
 
-#endif
+module_init(i2o_lan_init);
+module_exit(i2o_lan_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/i2o_pci.c linux/drivers/message/i2o/i2o_pci.c
--- linux.orig/drivers/message/i2o/i2o_pci.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/message/i2o/i2o_pci.c	2002-07-20 01:08:27.000000000 +0000
@@ -15,6 +15,8 @@
  *
  *	TODO:
  *		Support polled I2O PCI controllers. 
+ *		2.4 hotplug support
+ *		Finish verifying 64bit/bigendian clean
  */
 
 #include <linux/config.h>
@@ -31,21 +33,17 @@
 #include <asm/mtrr.h>
 #endif // CONFIG_MTRR
 
-#ifdef MODULE
-/*
- * Core function table
- * See <include/linux/i2o.h> for an explanation
- */
-static struct i2o_core_func_table *core;
-
-/* Core attach function */
-extern int i2o_pci_core_attach(struct i2o_core_func_table *);
-extern void i2o_pci_core_detach(void);
-#endif /* MODULE */
+static int dpt = 0;
 
-/*
- *	Free bus specific resources
+
+/**
+ *	i2o_pci_dispose		-	Free bus specific resources
+ *	@c: I2O controller
+ *
+ *	Disable interrupts and then free interrupt, I/O and mtrr resources 
+ *	used by this controller. Called by the I2O core on unload.
  */
+ 
 static void i2o_pci_dispose(struct i2o_controller *c)
 {
 	I2O_IRQ_WRITE32(c,0xFFFFFFFF);
@@ -61,9 +59,13 @@
 #endif
 }
 
-/*
- *	No real bus specific handling yet (note that later we will
- *	need to 'steal' PCI devices on i960 mainboards)
+/**
+ *	i2o_pci_bind		-	Bind controller and devices
+ *	@c: i2o controller
+ *	@dev: i2o device
+ *
+ *	Bind a device driver to a controller. In the case of PCI all we need to do
+ *	is module housekeeping.
  */
  
 static int i2o_pci_bind(struct i2o_controller *c, struct i2o_device *dev)
@@ -72,51 +74,83 @@
 	return 0;
 }
 
+/**
+ *	i2o_pci_unbind		-	Bind controller and devices
+ *	@c: i2o controller
+ *	@dev: i2o device
+ *
+ *	Unbind a device driver from a controller. In the case of PCI all we need to do
+ *	is module housekeeping.
+ */
+ 
+
 static int i2o_pci_unbind(struct i2o_controller *c, struct i2o_device *dev)
 {
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
-/*
- * Bus specific enable/disable functions
+/**
+ *	i2o_pci_enable		-	Enable controller
+ *	@c: controller
+ *
+ *	Called by the I2O core code in order to enable bus specific
+ *	resources for this controller. In our case that means unmasking the 
+ *	interrupt line.
  */
+
 static void i2o_pci_enable(struct i2o_controller *c)
 {
 	I2O_IRQ_WRITE32(c, 0);
 	c->enabled = 1;
 }
 
+/**
+ *	i2o_pci_disable		-	Enable controller
+ *	@c: controller
+ *
+ *	Called by the I2O core code in order to enable bus specific
+ *	resources for this controller. In our case that means masking the 
+ *	interrupt line.
+ */
+
 static void i2o_pci_disable(struct i2o_controller *c)
 {
 	I2O_IRQ_WRITE32(c, 0xFFFFFFFF);
 	c->enabled = 0;
 }
 
-/*
- *	Bus specific interrupt handler
+/**
+ *	i2o_pci_interrupt	-	Bus specific interrupt handler
+ *	@irq: interrupt line
+ *	@dev_id: cookie
+ *
+ *	Handle an interrupt from a PCI based I2O controller. This turns out
+ *	to be rather simple. We keep the controller pointer in the cookie.
  */
  
 static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
 {
 	struct i2o_controller *c = dev_id;
-#ifdef MODULE
-	core->run_queue(c);
-#else
 	i2o_run_queue(c);
-#endif /* MODULE */
 }	
 
-/*
- *	Install a PCI (or in theory AGP) i2o controller
+/**
+ *	i2o_pci_install		-	Install a PCI i2o controller
+ *	@dev: PCI device of the I2O controller
+ *
+ *	Install a PCI (or in theory AGP) i2o controller. Devices are
+ *	initialized, configured and registered with the i2o core subsystem. Be
+ *	very careful with ordering. There may be pending interrupts.
  *
- * TODO: Add support for polled controllers
+ *	To Do: Add support for polled controllers
  */
+
 int __init i2o_pci_install(struct pci_dev *dev)
 {
 	struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
 						GFP_KERNEL);
-	u8 *mem;
+	unsigned long mem;
 	u32 memptr = 0;
 	u32 size;
 	
@@ -150,8 +184,8 @@
 	/* Map the I2O controller */
 	
 	printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
-	mem = ioremap(memptr, size);
-	if(mem==NULL)
+	mem = (unsigned long)ioremap(memptr, size);
+	if(mem==0)
 	{
 		printk(KERN_ERR "i2o: Unable to map controller.\n");
 		kfree(c);
@@ -159,17 +193,16 @@
 	}
 
 	c->bus.pci.irq = -1;
-	c->bus.pci.queue_buggy = 0;
 	c->bus.pci.dpt = 0;
 	c->bus.pci.short_req = 0;
 	c->pdev = dev;
 
-	c->irq_mask = (volatile u32 *)(mem+0x34);
-	c->post_port = (volatile u32 *)(mem+0x40);
-	c->reply_port = (volatile u32 *)(mem+0x44);
+	c->irq_mask = mem+0x34;
+	c->post_port = mem+0x40;
+	c->reply_port = mem+0x44;
 
 	c->mem_phys = memptr;
-	c->mem_offset = (u32)mem;
+	c->mem_offset = mem;
 	c->destructor = i2o_pci_dispose;
 	
 	c->bind = i2o_pci_bind;
@@ -186,14 +219,12 @@
 	 
 	if(dev->vendor == PCI_VENDOR_ID_NCR && dev->device == 0x0630)
 	{
-		c->bus.pci.short_req=1;
+		c->bus.pci.short_req = 1;
 		printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
 	}
 	if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
 	{
-		c->bus.pci.queue_buggy=1;
-		if (dev->subsystem_device == 0x0000) /* SX6000 ???? */
-			c->bus.pci.queue_buggy=2;
+		c->bus.pci.promise = 1;
 		printk(KERN_INFO "I2O: Promise workarounds activated.\n");
 	}
 
@@ -211,10 +242,11 @@
 #ifdef CONFIG_MTRR
 	c->bus.pci.mtrr_reg0 =
 		mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
-/*
-* If it is an INTEL i960 I/O processor then set the first 64K to Uncacheable
-* since the region contains the Messaging unit which shouldn't be cached.
-*/
+	/*
+	 * If it is an INTEL i960 I/O processor then set the first 64K to
+	 * Uncacheable since the region contains the Messaging unit which
+	 * shouldn't be cached.
+	 */
 	c->bus.pci.mtrr_reg1 = -1;
 	if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
 	{
@@ -232,17 +264,13 @@
 
 	I2O_IRQ_WRITE32(c,0xFFFFFFFF);
 
-#ifdef MODULE
-	i = core->install(c);
-#else
 	i = i2o_install_controller(c);
-#endif /* MODULE */
 	
 	if(i<0)
 	{
 		printk(KERN_ERR "i2o: Unable to install controller.\n");
 		kfree(c);
-		iounmap(mem);
+		iounmap((void *)mem);
 		return i;
 	}
 
@@ -256,12 +284,8 @@
 			printk(KERN_ERR "%s: unable to allocate interrupt %d.\n",
 				c->name, dev->irq);
 			c->bus.pci.irq = -1;
-#ifdef MODULE
-			core->delete(c);
-#else
 			i2o_delete_controller(c);
-#endif /* MODULE */	
-			iounmap(mem);
+			iounmap((void *)mem);
 			return -EBUSY;
 		}
 	}
@@ -272,6 +296,16 @@
 	return 0;	
 }
 
+/**
+ *	i2o_pci_scan	-	Scan the pci bus for controllers
+ *	
+ *	Scan the PCI devices on the system looking for any device which is a 
+ *	memory of the Intelligent, I2O class. We attempt to set up each such device
+ *	and register it with the core.
+ *
+ *	Returns the number of controllers registered
+ */
+ 
 int __init i2o_pci_scan(void)
 {
 	struct pci_dev *dev;
@@ -283,7 +317,7 @@
 	{
 		if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
 			continue;
-		if(dev->vendor == PCI_VENDOR_ID_DPT)
+		if(dev->vendor == PCI_VENDOR_ID_DPT && !dpt)
 		{
 			if(dev->device == 0xA501 || dev->device == 0xA511)
 			{
@@ -310,84 +344,44 @@
 	return count?count:-ENODEV;
 }
 
-#ifdef I2O_HOTPLUG_SUPPORT
-/*
- * Activate a newly found PCI I2O controller
- * Not used now, but will be needed in future for
- * hot plug PCI support
+
+/**
+ *	i2o_pci_core_attach	-	PCI initialisation for I2O
+ *
+ *	Find any I2O controllers and if present initialise them and bring up
+ *	the I2O subsystem.
+ *
+ *	Returns 0 on success or an error code
  */
-static void i2o_pci_activate(i2o_controller * c)
+ 
+static int i2o_pci_core_attach(void)
 {
-	int i=0;
-	struct i2o_controller *c;
-	
-	if(c->type == I2O_TYPE_PCI)
+	printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
+	if(i2o_pci_scan()>0)
 	{
-		I2O_IRQ_WRITE32(c,0);
-#ifdef MODULE
-		if(core->activate(c))
-#else
-		if(i2o_activate_controller(c))
-#endif /* MODULE */
-		{
-			printk("%s: Failed to initialize.\n", c->name);
-#ifdef MODULE
-			core->unlock(c);
-			core->delete(c);
-#else
-			i2o_unlock_controller(c);
-			i2o_delete_controller(c);
-#endif
-			continue;
-		}
+		i2o_sys_init();
+		return 0;
 	}
-}
-#endif // I2O_HOTPLUG_SUPPORT
-
-#ifdef MODULE
-
-int i2o_pci_core_attach(struct i2o_core_func_table *table)
-{
-	MOD_INC_USE_COUNT;
-
-	core = table;
-
-	return i2o_pci_scan();
-}
-
-void i2o_pci_core_detach(void)
-{
-	core = NULL;
-
-	MOD_DEC_USE_COUNT;
+	return -ENODEV;
 }
 
-int init_module(void)
-{
-	printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
-	
-	core = NULL;
-
- 	return 0;
+/**
+ *	i2o_pci_core_detach	-	PCI unload for I2O
+ *
+ *	Free up any resources not released when the controllers themselves were
+ *	shutdown and unbound from the bus and drivers
+ */
  
-}
-
-void cleanup_module(void)
+static void i2o_pci_core_detach(void)
 {
 }
 
-EXPORT_SYMBOL(i2o_pci_core_attach);
-EXPORT_SYMBOL(i2o_pci_core_detach);
-
 MODULE_AUTHOR("Red Hat Software");
 MODULE_DESCRIPTION("I2O PCI Interface");
 MODULE_LICENSE("GPL");
 
-
-#else
-void __init i2o_pci_init(void)
-{
-	printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
-	i2o_pci_scan();
-}
-#endif
+MODULE_PARM(dpt, "i");
+MODULE_PARM_DESC(dpt, "Set this if you want to drive DPT cards normally handled by dpt_i2o");
+module_init(i2o_pci_core_attach);
+module_exit(i2o_pci_core_detach);
+ 
\ No newline at end of file
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/i2o_proc.c linux/drivers/message/i2o/i2o_proc.c
--- linux.orig/drivers/message/i2o/i2o_proc.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/message/i2o/i2o_proc.c	2002-07-20 01:08:24.000000000 +0000
@@ -20,18 +20,12 @@
  *   LAN entries by Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
  *		    Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
  *   University of Helsinki, Department of Computer Science
- */
-
-/*
- * set tabstop=3
- */
-
-/*
- * TODO List
  *
- * - Add support for any version 2.0 spec changes once 2.0 IRTOS is
- *   is available to test with
- * - Clean up code to use official structure definitions 
+ *   Some cleanup (c) 2002 Red Hat <alan@redhat.com>
+ *   Working to make I2O 64bit safe and following the PCI API
+ *
+ *   TODO List
+ *	- Clean up code to use official structure definitions 
  */
 
 // FIXME!
@@ -3371,8 +3365,5 @@
 	i2o_remove_handler(&i2o_proc_handler);
 }
 
-#ifdef MODULE
 module_init(i2o_proc_init);
-#endif
 module_exit(i2o_proc_exit);
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/i2o_scsi.c linux/drivers/message/i2o/i2o_scsi.c
--- linux.orig/drivers/message/i2o/i2o_scsi.c	2001-10-22 15:39:56.000000000 +0000
+++ linux/drivers/message/i2o/i2o_scsi.c	2002-07-20 01:08:29.000000000 +0000
@@ -119,14 +119,12 @@
 	int i;
 	unsigned long flags;
 	
-	save_flags(flags);
-	cli();
-
+	spin_lock_irqsave(&io_request_lock, flags);
 	for(i=0;i<retry_ct;i++)
 		i2o_post_message(retry_ctrl[i], virt_to_bus(retry[i]));
 	retry_ct=0;
 	
-	restore_flags(flags);
+	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 static void flush_pending(void)
@@ -134,8 +132,7 @@
 	int i;
 	unsigned long flags;
 	
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&io_request_lock, flags);
 
 	for(i=0;i<retry_ct;i++)
 	{
@@ -145,7 +142,7 @@
 	}
 	retry_ct=0;
 	
-	restore_flags(flags);
+	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
@@ -212,9 +209,9 @@
 	 *	Low byte is device status, next is adapter status,
 	 *	(then one byte reserved), then request status.
 	 */
-	ds=(u8)m[4]; 
-	as=(u8)(m[4]>>8);
-	st=(u8)(m[4]>>24);
+	ds=(u8)le32_to_cpu(m[4]); 
+	as=(u8)le32_to_cpu(m[4]>>8);
+	st=(u8)le32_to_cpu(m[4]>>24);
 	
 	dprintk(("i2o got a scsi reply %08X: ", m[0]));
 	dprintk(("m[2]=%08X: ", m[2]));
@@ -231,7 +228,10 @@
 		printk(KERN_ERR "i2o_scsi: bus reset reply.\n");
 		return;
 	}
-	
+
+	/*
+ 	 *	FIXME: 64bit breakage
+	 */
 	current_command = (Scsi_Cmnd *)m[3];
 	
 	/*
@@ -252,11 +252,11 @@
 	
 	if(st == 0x06)
 	{
-		if(m[5] < current_command->underflow)
+		if(le32_to_cpu(m[5]) < current_command->underflow)
 		{
 			int i;
 			printk(KERN_ERR "SCSI: underflow 0x%08X 0x%08X\n",
-				m[5], current_command->underflow);
+				le32_to_cpu(m[5]), current_command->underflow);
 			printk("Cmd: ");
 			for(i=0;i<15;i++)
 				printk("%02X ", current_command->cmnd[i]);
@@ -319,7 +319,7 @@
 	return 0;
 }
 
-void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_Host *shpnt)
+static void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_Host *shpnt)
 {
 	struct i2o_device *unit;
 	struct i2o_scsi_host *h =(struct i2o_scsi_host *)shpnt->hostdata;
@@ -379,7 +379,7 @@
 	}		
 }
 
-int i2o_scsi_detect(Scsi_Host_Template * tpnt)
+static int i2o_scsi_detect(Scsi_Host_Template * tpnt)
 {
 	unsigned long flags;
 	struct Scsi_Host *shpnt = NULL;
@@ -473,7 +473,7 @@
 	return count;
 }
 
-int i2o_scsi_release(struct Scsi_Host *host)
+static int i2o_scsi_release(struct Scsi_Host *host)
 {
 	if(--i2o_scsi_hosts==0)
 	{
@@ -490,45 +490,14 @@
 }
 
 
-const char *i2o_scsi_info(struct Scsi_Host *SChost)
+static const char *i2o_scsi_info(struct Scsi_Host *SChost)
 {
 	struct i2o_scsi_host *hostdata;
-
 	hostdata = (struct i2o_scsi_host *)SChost->hostdata;
-
 	return(&hostdata->controller->name[0]);
 }
 
-
-/*
- * From the wd93 driver:
- * Returns true if there will be a DATA_OUT phase with this command, 
- * false otherwise.
- * (Thanks to Joerg Dorchain for the research and suggestion.)
- *
- */
-static int is_dir_out(Scsi_Cmnd *cmd)
-{
-	switch (cmd->cmnd[0]) 
-	{
-     		case WRITE_6:           case WRITE_10:          case WRITE_12:
-      		case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:
-      		case WRITE_VERIFY:      case WRITE_VERIFY_12:      
-      		case COMPARE:           case COPY:              case COPY_VERIFY:
-      		case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:
-      		case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:      
-      		case FORMAT_UNIT:       case REASSIGN_BLOCKS:   case RESERVE:
-      		case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:
-      		case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:
-      		case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:
-      		case 0xea:
-        		return 1;
-		default:
-        		return 0;
-	}
-}
-
-int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
 	int i;
 	int tid;
@@ -594,9 +563,10 @@
 	do
 	{
 		mb();
-		m = I2O_POST_READ32(c);
+		m = le32_to_cpu(I2O_POST_READ32(c));
 	}
 	while(m==0xFFFFFFFF);
+
 	msg = (u32 *)(c->mem_offset + m);
 	
 	/*
@@ -606,28 +576,29 @@
 	len = SCpnt->request_bufflen;
 	direction = 0x00000000;			// SGL IN  (osm<--iop)
 	
-	/*
-	 *	The scsi layer should be handling this stuff
-	 */
-	
-	scsidir = 0x00000000;			// DATA NO XFER
-	if(len)
+	if(SCpnt->sc_data_direction == SCSI_DATA_NONE)
+		scsidir = 0x00000000;			// DATA NO XFER
+	else if(SCpnt->sc_data_direction == SCSI_DATA_WRITE)
 	{
-		if(is_dir_out(SCpnt))
-		{
-			direction=0x04000000;	// SGL OUT  (osm-->iop)
-			scsidir  =0x80000000;	// DATA OUT (iop-->dev)
-		}
-		else
-		{
-			scsidir  =0x40000000;	// DATA IN  (iop<--dev)
-		}
+		direction=0x04000000;	// SGL OUT  (osm-->iop)
+		scsidir  =0x80000000;	// DATA OUT (iop-->dev)
+	}
+	else if(SCpnt->sc_data_direction == SCSI_DATA_READ)
+	{
+		scsidir  =0x40000000;	// DATA IN  (iop<--dev)
+	}
+	else
+	{
+		/* Unknown - kill the command */
+		SCpnt->result = DID_NO_CONNECT << 16;
+		done(SCpnt);
+		return 0;
 	}
 	
-	__raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]);
-	__raw_writel(scsi_context, &msg[2]);	/* So the I2O layer passes to us */
+	i2o_raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]);
+	i2o_raw_writel(scsi_context, &msg[2]);	/* So the I2O layer passes to us */
 	/* Sorry 64bit folks. FIXME */
-	__raw_writel((u32)SCpnt, &msg[3]);	/* We want the SCSI control block back */
+	i2o_raw_writel((u32)SCpnt, &msg[3]);	/* We want the SCSI control block back */
 
 	/* LSI_920_PCI_QUIRK
 	 *
@@ -670,7 +641,7 @@
 	}
 
 	/* Direction, disconnect ok, tag, CDBLen */
-	__raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]);
+	i2o_raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]);
 
 	mptr=msg+5;
 
@@ -690,6 +661,8 @@
 	 *	FIXME: we need to set the sglist limits according to the 
 	 *	message size of the I2O controller. We might only have room
 	 *	for 6 or so worst case
+	 *
+	 *	FIXME: pci dma mapping
 	 */
 	
 	if(SCpnt->use_sg)
@@ -705,8 +678,8 @@
 			/*
 			 *	Need to chain!
 			 */
-			__raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++);
-			__raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr);
+			i2o_raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++);
+			i2o_raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr);
 			mptr = (u32*)(sg_chain_pool + sg_chain_tag);
 			if (SCpnt->use_sg > max_sg_len)
 			{
@@ -729,22 +702,22 @@
 		{		
 			for(i = 0 ; i < SCpnt->use_sg; i++)
 			{
-				__raw_writel(direction|0x10000000|sg->length, mptr++);
+				i2o_raw_writel(direction|0x10000000|sg->length, mptr++);
 				len+=sg->length;
-				__raw_writel(virt_to_bus(sg->address), mptr++);
+				i2o_raw_writel(virt_to_bus(sg->address), mptr++);
 				sg++;
 			}
 
 			/* Make this an end of list. Again evade the 920 bug and
 			   unwanted PCI read traffic */
 		
-			__raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]);
+			i2o_raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]);
 		}
 		
 		if(!chain)
 			reqlen = mptr - msg;
 		
-		__raw_writel(len, lenptr);
+		i2o_raw_writel(len, lenptr);
 		
 		if(len != SCpnt->underflow)
 			printk("Cmd len %08X Cmd underflow %08X\n",
@@ -754,15 +727,15 @@
 	{
 		dprintk(("non sg for %p, %d\n", SCpnt->request_buffer,
 				SCpnt->request_bufflen));
-		__raw_writel(len = SCpnt->request_bufflen, lenptr);
+		i2o_raw_writel(len = SCpnt->request_bufflen, lenptr);
 		if(len == 0)
 		{
 			reqlen = 9;
 		}
 		else
 		{
-			__raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++);
-			__raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++);
+			i2o_raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++);
+			i2o_raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++);
 		}
 	}
 	
@@ -770,7 +743,7 @@
 	 *	Stick the headers on 
 	 */
 
-	__raw_writel(reqlen<<16 | SGL_OFFSET_10, msg);
+	i2o_raw_writel(reqlen<<16 | SGL_OFFSET_10, msg);
 	
 	/* Queue the message */
 	i2o_post_message(c,m);
@@ -794,7 +767,7 @@
 	SCpnt->SCp.Status++;
 }
 
-int i2o_scsi_command(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_command(Scsi_Cmnd * SCpnt)
 {
 	i2o_scsi_queuecommand(SCpnt, internal_done);
 	SCpnt->SCp.Status = 0;
@@ -803,12 +776,12 @@
 	return SCpnt->result;
 }
 
-int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
 {
 	struct i2o_controller *c;
 	struct Scsi_Host *host;
 	struct i2o_scsi_host *hostdata;
-	u32 *msg;
+	unsigned long msg;
 	u32 m;
 	int tid;
 	
@@ -832,30 +805,30 @@
 	do
 	{
 		mb();
-		m = I2O_POST_READ32(c);
+		m = le32_to_cpu(I2O_POST_READ32(c));
 	}
 	while(m==0xFFFFFFFF);
-	msg = (u32 *)(c->mem_offset + m);
+	msg = c->mem_offset + m;
 	
-	__raw_writel(FIVE_WORD_MSG_SIZE, &msg[0]);
-	__raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, &msg[1]);
-	__raw_writel(scsi_context, &msg[2]);
-	__raw_writel(0, &msg[3]);	/* Not needed for an abort */
-	__raw_writel((u32)SCpnt, &msg[4]);	
+	i2o_raw_writel(FIVE_WORD_MSG_SIZE, msg);
+	i2o_raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, msg+4);
+	i2o_raw_writel(scsi_context, msg+8);
+	i2o_raw_writel(0, msg+12);	/* Not needed for an abort */
+	i2o_raw_writel((u32)SCpnt, msg+16);	/* FIXME 32bitism */
 	wmb();
 	i2o_post_message(c,m);
 	wmb();
 	return SCSI_ABORT_PENDING;
 }
 
-int i2o_scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+static int i2o_scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
 {
 	int tid;
 	struct i2o_controller *c;
 	struct Scsi_Host *host;
 	struct i2o_scsi_host *hostdata;
 	u32 m;
-	u32 *msg;
+	unsigned long msg;
 
 	/*
 	 *	Find the TID for the bus
@@ -874,7 +847,7 @@
 	 *	possibly ?
 	 */
 	 
-	m = I2O_POST_READ32(c);
+	m = le32_to_cpu(I2O_POST_READ32(c));
 	
 	/*
 	 *	No free messages, try again next time - no big deal
@@ -883,13 +856,13 @@
 	if(m == 0xFFFFFFFF)
 		return SCSI_RESET_PUNT;
 	
-	msg = (u32 *)(c->mem_offset + m);
-	__raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
-	__raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, &msg[1]);
-	__raw_writel(scsi_context|0x80000000, &msg[2]);
+	msg = c->mem_offset + m;
+	i2o_raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
+	i2o_raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, msg+4);
+	i2o_raw_writel(scsi_context|0x80000000, msg+8);
 	/* We use the top bit to split controller and unit transactions */
 	/* Now store unit,tid so we can tie the completion back to a specific device */
-	__raw_writel(c->unit << 16 | tid, &msg[3]);
+	i2o_raw_writel(c->unit << 16 | tid, msg+12);
 	wmb();
 	i2o_post_message(c,m);
 	return SCSI_RESET_PENDING;
@@ -899,7 +872,7 @@
  *	This is anyones guess quite frankly.
  */
  
-int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip)
+static int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip)
 {
 	int size;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/message/i2o/i2o_scsi.h linux/drivers/message/i2o/i2o_scsi.h
--- linux.orig/drivers/message/i2o/i2o_scsi.h	2000-12-11 21:20:04.000000000 +0000
+++ linux/drivers/message/i2o/i2o_scsi.h	2002-07-20 01:08:35.000000000 +0000
@@ -14,15 +14,15 @@
 #define I2O_SCSI_CAN_QUEUE 4
 #define I2O_SCSI_CMD_PER_LUN 6
 
-extern int i2o_scsi_detect(Scsi_Host_Template *);
-extern const char *i2o_scsi_info(struct Scsi_Host *);
-extern int i2o_scsi_command(Scsi_Cmnd *);
-extern int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int i2o_scsi_abort(Scsi_Cmnd *);
-extern int i2o_scsi_reset(Scsi_Cmnd *, unsigned int);
-extern int i2o_scsi_bios_param(Disk *, kdev_t, int *);
+static int i2o_scsi_detect(Scsi_Host_Template *);
+static const char *i2o_scsi_info(struct Scsi_Host *);
+static int i2o_scsi_command(Scsi_Cmnd *);
+static int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int i2o_scsi_abort(Scsi_Cmnd *);
+static int i2o_scsi_reset(Scsi_Cmnd *, unsigned int);
+static int i2o_scsi_bios_param(Disk *, kdev_t, int *);
 extern void i2o_scsi_setup(char *str, int *ints);
-extern int i2o_scsi_release(struct Scsi_Host *host);
+static int i2o_scsi_release(struct Scsi_Host *host);
 
 #define I2OSCSI {                                          \
 		  next: NULL,				    \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/Config.in linux/drivers/mtd/Config.in
--- linux.orig/drivers/mtd/Config.in	2001-10-11 16:14:32.000000000 +0000
+++ linux/drivers/mtd/Config.in	2002-07-20 01:08:26.000000000 +0000
@@ -1,5 +1,5 @@
 
-# $Id: Config.in,v 1.71 2001/10/03 11:38:38 dwmw2 Exp $
+# $Id: Config.in,v 1.73 2002/03/08 16:34:35 rkaiser Exp $
 
 mainmenu_option next_comment
 comment 'Memory Technology Devices (MTD)'
@@ -12,6 +12,7 @@
       int '  Debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_MTD_DEBUG_VERBOSE 0
    fi
    dep_tristate '  MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
+   dep_tristate '  MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD
    dep_tristate '  RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
    if [ "$CONFIG_ARM" = "y" ]; then
       dep_tristate '  Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/Makefile linux/drivers/mtd/Makefile
--- linux.orig/drivers/mtd/Makefile	2001-10-04 22:13:18.000000000 +0000
+++ linux/drivers/mtd/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definitions are now inherited from the
 # parent makes..
 #
-# $Id: Makefile,v 1.63 2001/06/13 09:43:07 dwmw2 Exp $
+# $Id: Makefile,v 1.65 2002/03/22 07:10:34 dwmw2 Exp $
 
 
 obj-y           += chips/chipslink.o maps/mapslink.o \
@@ -19,7 +19,7 @@
 
 O_TARGET	:= mtdlink.o
 
-export-objs	:= mtdcore.o mtdpart.o redboot.o bootldr.o afs.o
+export-objs	:= mtdcore.o mtdpart.o redboot.o bootldr.o afs.o mtdconcat.o
 list-multi	:= nftl.o
 
 mod-subdirs	:= 
@@ -44,6 +44,7 @@
 
 # Core functionality.
 obj-$(CONFIG_MTD)		+= mtdcore.o
+obj-$(CONFIG_MTD_CONCAT)		+= mtdconcat.o
 obj-$(CONFIG_MTD_PARTITIONS)	+= mtdpart.o
 obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
 obj-$(CONFIG_MTD_BOOTLDR_PARTS) += bootldr.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/afs.c linux/drivers/mtd/afs.c
--- linux.orig/drivers/mtd/afs.c	2001-10-04 22:14:41.000000000 +0000
+++ linux/drivers/mtd/afs.c	2002-07-20 01:08:33.000000000 +0000
@@ -21,7 +21,7 @@
    This is access code for flashes using ARM's flash partitioning 
    standards.
 
-   $Id: afs.c,v 1.6 2001/10/02 10:04:51 rmk Exp $
+   $Id: afs.c,v 1.7 2001/11/01 20:04:54 rmk Exp $
 
 ======================================================================*/
 
@@ -82,6 +82,12 @@
 	if (fs.signature != 0xa0ffff9f)
 		ret = 1;
 
+	/*
+	 * Don't touch the SIB.
+	 */
+	if (fs.type == 2)
+		ret = 1;
+
 	*iis_start = fs.image_info_base & mask;
 	*img_start = fs.image_start & mask;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/chips/Makefile linux/drivers/mtd/chips/Makefile
--- linux.orig/drivers/mtd/chips/Makefile	2001-10-05 19:05:47.000000000 +0000
+++ linux/drivers/mtd/chips/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -1,7 +1,7 @@
 #
 # linux/drivers/chips/Makefile
 #
-# $Id: Makefile,v 1.7 2001/10/05 06:53:51 dwmw2 Exp $
+# $Id: Makefile,v 1.8 2002/01/10 20:27:40 eric Exp $
 
 O_TARGET	:= chipslink.o
 
@@ -20,7 +20,6 @@
 obj-$(CONFIG_MTD_CFI_AMDSTD)	+= cfi_cmdset_0002.o
 obj-$(CONFIG_MTD_CFI_INTELEXT)	+= cfi_cmdset_0001.o
 obj-$(CONFIG_MTD_GEN_PROBE)	+= gen_probe.o
-obj-$(CONFIG_MTD_INTELPROBE)	+= intel_probe.o
 obj-$(CONFIG_MTD_JEDEC)		+= jedec.o
 obj-$(CONFIG_MTD_JEDECPROBE)	+= jedec_probe.o
 obj-$(CONFIG_MTD_RAM)		+= map_ram.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/chips/amd_flash.c linux/drivers/mtd/chips/amd_flash.c
--- linux.orig/drivers/mtd/chips/amd_flash.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/chips/amd_flash.c	2002-07-20 01:08:30.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * Author: Jonas Holmberg <jonas.holmberg@axis.com>
  *
- * $Id: amd_flash.c,v 1.15 2001/10/02 15:05:11 dwmw2 Exp $
+ * $Id: amd_flash.c,v 1.17 2002/03/05 17:00:37 jonashg Exp $
  *
  * Copyright (c) 2001 Axis Communications AB
  *
@@ -52,6 +52,7 @@
 
 /* Manufacturers */
 #define MANUFACTURER_AMD	0x0001
+#define MANUFACTURER_ATMEL	0x001F
 #define MANUFACTURER_FUJITSU	0x0004
 #define MANUFACTURER_ST		0x0020
 #define MANUFACTURER_SST	0x00BF
@@ -67,6 +68,9 @@
 #define AM29BDS323D     0x22D1
 #define AM29BDS643D	0x227E
 
+/* Atmel */
+#define AT49xV16x	0x00C0
+#define AT49xV16xT	0x00C2
 
 /* Fujitsu */
 #define MBM29LV160TE	0x22C4
@@ -613,6 +617,26 @@
 			{ offset: 0x600000, erasesize: 0x10000, numblocks: 31 },
 			{ offset: 0x7f0000, erasesize: 0x02000, numblocks:  8 },
 		}
+	}, {
+		mfr_id: MANUFACTURER_ATMEL,
+		dev_id: AT49xV16x,
+		name: "Atmel AT49xV16x",
+		size: 0x00200000,
+		numeraseregions: 2,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x02000, numblocks:  8 },
+			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_ATMEL,
+		dev_id: AT49xV16xT,
+		name: "Atmel AT49xV16xT",
+		size: 0x00200000,
+		numeraseregions: 2,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
+			{ offset: 0x1F0000, erasesize: 0x02000, numblocks:  8 }
+		}
 	} 
 	};
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/chips/jedec.c linux/drivers/mtd/chips/jedec.c
--- linux.orig/drivers/mtd/chips/jedec.c	2001-11-09 22:29:40.000000000 +0000
+++ linux/drivers/mtd/chips/jedec.c	2002-07-20 01:08:38.000000000 +0000
@@ -11,7 +11,7 @@
  * not going to guess how to send commands to them, plus I expect they will
  * all speak CFI..
  *
- * $Id: jedec.c,v 1.12 2001/11/06 14:37:35 dwmw2 Exp $
+ * $Id: jedec.c,v 1.13 2002/02/08 15:57:21 rkaiser Exp $
  */
 
 #include <linux/mtd/jedec.h>
@@ -738,6 +738,7 @@
    }
        	    
    //printk("done\n");
+   instr->state = MTD_ERASE_DONE;
    if (instr->callback)
 	instr->callback(instr);
    return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/chips/sharp.c linux/drivers/mtd/chips/sharp.c
--- linux.orig/drivers/mtd/chips/sharp.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/chips/sharp.c	2002-07-20 01:08:22.000000000 +0000
@@ -4,7 +4,7 @@
  * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
  *           2000,2001 Lineo, Inc.
  *
- * $Id: sharp.c,v 1.6 2001/10/02 15:05:12 dwmw2 Exp $
+ * $Id: sharp.c,v 1.7 2002/02/13 15:49:07 dwmw2 Exp $
  *
  * Devices supported:
  *   LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -440,7 +440,7 @@
 
 	timeo = jiffies + HZ;
 
-	while(jiffies<timeo){
+	while(time_before(jiffies, timeo)){
 		map->write32(map,CMD_READ_STATUS,adr);
 		status = map->read32(map,adr);
 		if((status & SR_READY)==SR_READY){
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/devices/doc1000.c linux/drivers/mtd/devices/doc1000.c
--- linux.orig/drivers/mtd/devices/doc1000.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/devices/doc1000.c	2002-07-20 01:08:25.000000000 +0000
@@ -1,6 +1,6 @@
 /*======================================================================
 
-  $Id: doc1000.c,v 1.15 2001/10/02 15:05:13 dwmw2 Exp $
+  $Id: doc1000.c,v 1.16 2001/12/28 22:45:17 dwmw2 Exp $
 
 ======================================================================*/
 
@@ -483,7 +483,7 @@
 			else
 				priv->devstat[erase->dev] = erase->state = MTD_ERASE_PENDING;
 		}
-		else if (erase->time + erase_timeout < jiffies)
+		else if (time_after(jiffies, erase->time + erase_timeout))
 		{
 			printk("Flash erase timed out. The world is broken.\n");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/devices/mtdram.c linux/drivers/mtd/devices/mtdram.c
--- linux.orig/drivers/mtd/devices/mtdram.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/devices/mtdram.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * mtdram - a test mtd device
- * $Id: mtdram.c,v 1.25 2001/10/02 15:05:13 dwmw2 Exp $
+ * $Id: mtdram.c,v 1.26 2001/12/01 10:24:18 dwmw2 Exp $
  * Author: Alexander Larsson <alex@cendio.se>
  *
  * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
@@ -123,7 +123,7 @@
    // Allocate some memory
    mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
    if (!mtd_info)
-      return 0;
+      return -ENOMEM;
    
    memset(mtd_info, 0, sizeof(*mtd_info));
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/devices/pmc551.c linux/drivers/mtd/devices/pmc551.c
--- linux.orig/drivers/mtd/devices/pmc551.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/devices/pmc551.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: pmc551.c,v 1.19 2001/10/02 15:05:13 dwmw2 Exp $
+ * $Id: pmc551.c,v 1.20 2002/03/05 13:47:08 dwmw2 Exp $
  *
  * PMC551 PCI Mezzanine Ram Device
  *
@@ -716,7 +716,7 @@
                 }
 
 		/*
-		 * This is needed untill the driver is capable of reading the
+		 * This is needed until the driver is capable of reading the
 		 * onboard I2C SROM to discover the "real" memory size.
 		 */
 		if(msize) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
--- linux.orig/drivers/mtd/ftl.c	2001-10-25 20:58:35.000000000 +0000
+++ linux/drivers/mtd/ftl.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,5 +1,5 @@
 /* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $
+ * $Id: ftl.c,v 1.43 2002/02/13 15:31:37 dwmw2 Exp $
  *
  * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -87,7 +87,7 @@
 #define register_disk(dev, drive, minors, ops, size) \
     do { (dev)->part[(drive)*(minors)].nr_sects = size; \
         if (size == 0) (dev)->part[(drive)*(minors)].start_sect = -1; \
-        resetup_one_dev(dev, drive); } while (0);
+        resetup_one_dev(dev, drive); } while (0)
 #endif
 
 #if (LINUX_VERSION_CODE < 0x20320)
@@ -99,6 +99,13 @@
 #define request_arg_t           request_queue_t *q
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
+#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
+#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
+#else
+#define BLK_INC_USE_COUNT do {} while(0)
+#define BLK_DEC_USE_COUNT do {} while(0)
+#endif
 
 /*====================================================================*/
 
@@ -235,7 +242,9 @@
 };
 #else
 static struct block_device_operations ftl_blk_fops = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
     owner:	THIS_MODULE,
+#endif
     open:	ftl_open,
     release:	ftl_close,
     ioctl:	ftl_ioctl,
@@ -895,11 +904,16 @@
     if (ftl_gendisk.part[minor].nr_sects == 0)
 	return -ENXIO;
 
-    if (!get_mtd_device(partition->mtd, -1))
-	    return /* -E'SBUGGEREDOFF */ -ENXIO;
+    BLK_INC_USE_COUNT;
 
+    if (!get_mtd_device(partition->mtd, -1)) {
+	    BLK_DEC_USE_COUNT;
+	    return -ENXIO;
+    }
+    
     if ((file->f_mode & 2) && !(partition->mtd->flags & MTD_CLEAR_BITS) ) {
 	    put_mtd_device(partition->mtd);
+	    BLK_DEC_USE_COUNT;
             return -EROFS;
     }
     
@@ -920,9 +934,6 @@
     
     DEBUG(0, "ftl_cs: ftl_close(%d)\n", minor);
 
-    /* Flush all writes */
-    invalidate_device(inode->i_rdev, 1);
-
     /* Wait for any pending erase operations to complete */
     if (part->mtd->sync)
 	    part->mtd->sync(part->mtd);
@@ -935,6 +946,7 @@
     atomic_dec(&part->open);
 
     put_mtd_device(part->mtd);
+    BLK_DEC_USE_COUNT;
     release_return(0);
 } /* ftl_close */
 
@@ -1171,9 +1183,11 @@
     case BLKGETSIZE:
 	ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg);
 	break;
+#ifdef BLKGETSIZE64
     case BLKGETSIZE64:
 	ret = put_user((u64)ftl_hd[minor].nr_sects << 9, (u64 *)arg);
 	break;
+#endif
     case BLKRRPART:
 	ret = ftl_reread_partitions(minor);
 	break;
@@ -1401,7 +1415,7 @@
 
     memset(myparts, 0, sizeof(myparts));
     
-    DEBUG(0, "$Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $\n");
+    DEBUG(0, "$Id: ftl.c,v 1.43 2002/02/13 15:31:37 dwmw2 Exp $\n");
     
     if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) {
 	printk(KERN_NOTICE "ftl_cs: unable to grab major "
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/Config.in linux/drivers/mtd/maps/Config.in
--- linux.orig/drivers/mtd/maps/Config.in	2001-10-04 22:13:18.000000000 +0000
+++ linux/drivers/mtd/maps/Config.in	2002-07-20 01:08:37.000000000 +0000
@@ -1,12 +1,12 @@
 # drivers/mtd/maps/Config.in
 
-# $Id: Config.in,v 1.16 2001/09/19 18:28:37 dwmw2 Exp $
+# $Id: Config.in,v 1.28 2002/03/08 16:34:35 rkaiser Exp $
 
 mainmenu_option next_comment
 
 comment 'Mapping drivers for chip access'
 
-dep_tristate '  CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI
+dep_tristate '  CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE
 if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then
    hex '    Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000
    hex '    Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
@@ -23,20 +23,33 @@
    dep_tristate '  CFI Flash device mapped on AMD NetSc520'  CONFIG_MTD_NETSC520 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
    dep_tristate '  CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
    dep_tristate '  CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
+   dep_tristate '  CFI Flash device mapped on DIL/Net PC' CONFIG_MTD_DILNETPC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_CONCAT
+   if [ "$CONFIG_MTD_DILNETPC" = "y" -o "$CONFIG_MTD_DILNETPC" = "m" ]; then
+     hex '    Size of boot partition' CONFIG_MTD_DILNETPC_BOOTSIZE 0x80000
+   fi
    dep_tristate '  JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
    dep_tristate '  JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
    dep_tristate '  JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
-   dep_tristate '  BIOS flash chip on Intel L440GX boards' CONFIG_MTD_L440GX $CONFIG_I386 $CONFIG_MTD_JEDEC
+   dep_tristate '  BIOS flash chip on Intel L440GX boards' CONFIG_MTD_L440GX $CONFIG_MTD_JEDECPROBE
+   dep_tristate ' ROM connected to AMD766 southbridge' CONFIG_MTD_AMD766ROM $CONFIG_MTD_GEN_PROBE   
+   dep_tristate ' ROM connected to Intel Hub Controller 2' CONFIG_MTD_ICH2ROM $CONFIG_MTD_JEDECPROBE
 fi
 
 if [ "$CONFIG_PPC" = "y" ]; then
-   dep_tristate '  CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI $CONFIG_TQM8xxL $CONFIG_PPC
-   dep_tristate '  CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI $CONFIG_PPC
-   dep_tristate '  CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI_INTELSTD $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI_AMDSTD
+   dep_tristate '  CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI $CONFIG_TQM8xxL
+   dep_tristate '  CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI
+   dep_tristate '  System flash on MBX860 board' CONFIG_MTD_MBX860 $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI
    dep_tristate '  CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI
 fi
 
 if [ "$CONFIG_MIPS" = "y" ]; then
+   dep_tristate '  Pb1000 boot flash device' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
+   dep_tristate '  Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
+   if [ "$CONFIG_MTD_PB1500" = "y" -o "$CONFIG_MTD_PB1500" = "m" ]; then
+      bool '  Pb1500 boot flash device' CONFIG_MTD_PB1500_BOOT 
+      bool '  Pb1500 user flash device (2nd 32MB bank)' CONFIG_MTD_PB1500_USER
+   fi
    dep_tristate '  Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS 
    if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then
       hex '    Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000
@@ -46,8 +59,12 @@
    dep_tristate '  Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT
 fi
 
-if [ "$CONFIG_SH" = "y" ]; then
-   dep_tristate '  CFI Flash device mapped on Hitachi SolutionEngine' CONFIG_MTD_SOLUTIONENGINE $CONFIG_MTD_CFI $CONFIG_SH $CONFIG_MTD_REDBOOT_PARTS
+if [ "$CONFIG_SUPERH" = "y" ]; then
+   dep_tristate '  CFI Flash device mapped on Hitachi SolutionEngine' \
+      CONFIG_MTD_SOLUTIONENGINE $CONFIG_MTD_PARTITIONS $CONFIG_MTD_CFI
+   if [ "$CONFIG_MTD_SOLUTIONENGINE" != "n" ]; then
+      hex '  Default reserved Flash size'  CONFIG_MTD_SUPERH_RESERVE 0x00010000
+   fi
 fi
 
 if [ "$CONFIG_ARM" = "y" ]; then
@@ -57,6 +74,14 @@
    dep_tristate '  CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS
    dep_tristate '  CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_PARTITIONS
    dep_tristate '  CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_ARCH_IQ80310
+   dep_tristate '  CFI Flash device mapped on Epxa10db' CONFIG_MTD_EPXA10DB $CONFIG_MTD_CFI  $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT
+   dep_tristate '  NV-RAM mapping AUTCPU12 board' CONFIG_MTD_AUTCPU12 $CONFIG_ARCH_AUTCPU12
 fi
+if [ "$CONFIG_ALPHA" = "y" ]; then
+   dep_tristate '  Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE
+fi
+
+# This needs CFI or JEDEC, depending on the cards found.
+dep_tristate '  PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI
 
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/Makefile linux/drivers/mtd/maps/Makefile
--- linux.orig/drivers/mtd/maps/Makefile	2001-10-04 22:13:18.000000000 +0000
+++ linux/drivers/mtd/maps/Makefile	2002-07-20 01:08:21.000000000 +0000
@@ -1,7 +1,7 @@
 #
 # linux/drivers/maps/Makefile
 #
-# $Id: Makefile,v 1.13 2001/08/16 15:16:58 rmk Exp $
+# $Id: Makefile,v 1.21 2002/02/22 09:34:44 gleixner Exp $
 
 O_TARGET	:= mapslink.o
 
@@ -11,9 +11,15 @@
 obj-$(CONFIG_MTD_CFI_FLAGADM)	+= cfi_flagadm.o
 obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o
 obj-$(CONFIG_MTD_DC21285)       += dc21285.o
+obj-$(CONFIG_MTD_DILNETPC)      += dilnetpc.o
 obj-$(CONFIG_MTD_ELAN_104NC)    += elan-104nc.o
+obj-$(CONFIG_MTD_EPXA10DB)      += epxa10db-flash.o
 obj-$(CONFIG_MTD_IQ80310)	+= iq80310.o
 obj-$(CONFIG_MTD_L440GX)	+= l440gx.o
+obj-$(CONFIG_MTD_AMD766ROM)	+= amd766rom.o
+obj-$(CONFIG_MTD_ICH2ROM)	+= ich2rom.o
+obj-$(CONFIG_MTD_TSUNAMI)	+= tsunami_flash.o
+obj-$(CONFIG_MTD_MBX860)	+= mbx860.o
 obj-$(CONFIG_MTD_NORA)		+= nora.o
 obj-$(CONFIG_MTD_OCTAGON)	+= octagon-5066.o
 obj-$(CONFIG_MTD_PHYSMAP)	+= physmap.o 
@@ -29,5 +35,9 @@
 obj-$(CONFIG_MTD_DBOX2)		+= dbox2-flash.o
 obj-$(CONFIG_MTD_OCELOT)	+= ocelot.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
+obj-$(CONFIG_MTD_PCI)		+= pci.o
+obj-$(CONFIG_MTD_PB1000)        += pb1xxx-flash.o
+obj-$(CONFIG_MTD_PB1500)        += pb1xxx-flash.o
+obj-$(CONFIG_MTD_AUTCPU12)      += autcpu12-nvram.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/amd766rom.c linux/drivers/mtd/maps/amd766rom.c
--- linux.orig/drivers/mtd/maps/amd766rom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/amd766rom.c	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,245 @@
+/*
+ * amd766rom.c
+ *
+ * Normal mappings of chips in physical memory
+ * $Id: amd766rom.c,v 1.1 2002/01/10 22:59:13 eric Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+
+
+struct amd766rom_map_info {
+	struct map_info map;
+	struct mtd_info *mtd;
+	unsigned long window_addr;
+	u32 window_start, window_size;
+	struct pci_dev *pdev;
+};
+
+static __u8 amd766rom_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+static __u16 amd766rom_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+static __u32 amd766rom_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+static void amd766rom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+static void amd766rom_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+static void amd766rom_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+static void amd766rom_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+static void amd766rom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+static struct amd766rom_map_info amd766rom_map = {
+	map: {
+		name: "AMD766 rom",
+		size: 0,
+		buswidth: 1,
+		read8: amd766rom_read8,
+		read16: amd766rom_read16,
+		read32: amd766rom_read32,
+		copy_from: amd766rom_copy_from,
+		write8: amd766rom_write8,
+		write16: amd766rom_write16,
+		write32: amd766rom_write32,
+		copy_to: amd766rom_copy_to,
+		/* The standard rom socket is for single power supply chips
+		 * that don't have an extra vpp.
+		 */
+	},
+	mtd: 0,
+	window_addr: 0,
+};
+
+static int __devinit amd766rom_init_one (struct pci_dev *pdev,
+	const struct pci_device_id *ent)
+{
+	struct rom_window {
+		u32 start;
+		u32 size;
+		u8 segen_bits;
+	};
+	static struct rom_window rom_window[] = {
+		{ 0xffb00000, 5*1024*1024, (1<<7) | (1<<6), },
+		{ 0xffc00000, 4*1024*1024, (1<<7), },
+		{ 0xffff0000, 64*1024,     0 },
+		{ 0         , 0,           0 },
+	};
+	static const u32 rom_probe_sizes[] = { 
+		5*1024*1024, 4*1024*1024, 2*1024*1024, 1024*1024, 512*1024, 
+		256*1024, 128*1024, 64*1024, 0};
+	static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", 0 };
+	u8 byte;
+	struct amd766rom_map_info *info = &amd766rom_map;
+	struct rom_window *window;
+	int i;
+	u32 rom_size;
+
+	window = &rom_window[0];
+	while(window->size) {
+		if (request_mem_region(window->start, window->size, "amd766rom")) {
+			break;
+		}
+		window++;
+	}
+	if (!window->size) {
+		printk(KERN_ERR "amd766rom: cannot reserve rom window");
+		goto err_out_none;
+	}
+
+	/* Enable the selected rom window */
+	pci_read_config_byte(pdev, 0x43, &byte);
+	pci_write_config_byte(pdev, 0x43, byte | window->segen_bits);
+
+	/* Enable writes through the rom window */
+	pci_read_config_byte(pdev, 0x40, &byte);
+	pci_write_config_byte(pdev, 0x40, byte | 1);
+
+	/* FIXME handle registers 0x80 - 0x8C the bios region locks */
+
+	printk(KERN_NOTICE "amd766rom window : %x at %x\n", 
+		window->size, window->start);
+	/* For write accesses caches are useless */
+	info->window_addr = (unsigned long)ioremap_nocache(window->start, window->size);
+
+	if (!info->window_addr) {
+		printk(KERN_ERR "Failed to ioremap\n");
+		goto err_out_free_mmio_region;
+	}
+	info->mtd = 0;
+	for(i = 0; (rom_size = rom_probe_sizes[i]); i++) {
+		char **chip_type;
+		if (rom_size > window->size) {
+			continue;
+		}
+		info->map.map_priv_1 = 
+			info->window_addr + window->size - rom_size;
+		info->map.size = rom_size;
+		chip_type = rom_probe_types;
+		for(; !info->mtd && *chip_type; chip_type++) {
+			info->mtd = do_map_probe(*chip_type, &amd766rom_map.map);
+		}
+		if (info->mtd) {
+			break;
+		}
+	}
+	if (!info->mtd) {
+		goto err_out_iounmap;
+	}
+	printk(KERN_NOTICE "amd766rom chip at offset: %x\n",
+		window->size - rom_size);
+		
+	info->mtd->module = THIS_MODULE;
+	add_mtd_device(info->mtd);
+	info->window_start = window->start;
+	info->window_size = window->size;
+	return 0;
+
+err_out_iounmap:
+	iounmap((void *)(info->window_addr));
+err_out_free_mmio_region:
+	release_mem_region(window->start, window->size);
+err_out_none:
+	return -ENODEV;
+}
+
+
+static void __devexit amd766rom_remove_one (struct pci_dev *pdev)
+{
+	struct amd766rom_map_info *info = &amd766rom_map;
+	u8 byte;
+
+	del_mtd_device(info->mtd);
+	map_destroy(info->mtd);
+	info->mtd = 0;
+	info->map.map_priv_1 = 0;
+
+	iounmap((void *)(info->window_addr));
+	info->window_addr = 0;
+
+	/* Disable writes through the rom window */
+	pci_read_config_byte(pdev, 0x40, &byte);
+	pci_write_config_byte(pdev, 0x40, byte & ~1);
+	
+	release_mem_region(info->window_start, info->window_size);
+}
+
+static struct pci_device_id amd766rom_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 
+	  PCI_ANY_ID, PCI_ANY_ID, },
+};
+
+MODULE_DEVICE_TABLE(pci, amd766rom_pci_tbl);
+
+#if 0
+static struct pci_driver amd766rom_driver = {
+	name:	  "amd766rom",
+	id_table: amd766rom_pci_tbl,
+	probe:    amd766rom_init_one,
+	remove:   amd766rom_remove_one,
+};
+#endif
+
+int __init init_amd766rom(void)
+{
+	struct pci_dev *pdev;
+	pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 0);
+	if (pdev) {
+		amd766rom_map.pdev = pdev;
+		return amd766rom_init_one(pdev, &amd766rom_pci_tbl[0]);
+	}
+	return -ENXIO;
+#if 0
+	return pci_module_init(&amd766rom_driver);
+#endif
+}
+
+static void __exit cleanup_amd766rom(void)
+{
+	amd766rom_remove_one(amd766rom_map.pdev);
+}
+
+module_init(init_amd766rom);
+module_exit(cleanup_amd766rom);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>");
+MODULE_DESCRIPTION("MTD map driver for BIOS chips on the AMD766 southbridge");
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/autcpu12-nvram.c linux/drivers/mtd/maps/autcpu12-nvram.c
--- linux.orig/drivers/mtd/maps/autcpu12-nvram.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/autcpu12-nvram.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,179 @@
+/*
+ * NV-RAM memory access on autcpu12 
+ * (C) 2002 Thomas Gleixner (gleixner@autronix.de)
+ *
+ * $Id: autcpu12-nvram.c,v 1.1 2002/02/22 09:30:24 gleixner Exp $ 
+ *
+ * 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/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/sizes.h>
+#include <asm/hardware.h>
+#include <asm/arch/autcpu12.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+__u8 autcpu12_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 autcpu12_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 autcpu12_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void autcpu12_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void autcpu12_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void autcpu12_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void autcpu12_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void autcpu12_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	while(len) {
+		__raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
+		from++;
+		to++;
+		len--;
+	}
+}
+
+static struct mtd_info *sram_mtd;
+
+struct map_info autcpu12_sram_map = {
+	name: "SRAM",
+	size: 32768,
+	buswidth: 8,
+	read8: autcpu12_read8,
+	read16: autcpu12_read16,
+	read32: autcpu12_read32,
+	copy_from: autcpu12_copy_from,
+	write8: autcpu12_write8,
+	write16: autcpu12_write16,
+	write32: autcpu12_write32,
+	copy_to: autcpu12_copy_to
+};
+
+static int __init init_autcpu12_sram (void)
+{
+	int err, save0, save1;
+
+	autcpu12_sram_map.map_priv_1 = (unsigned long)ioremap(0x12000000, SZ_128K);
+	if (!autcpu12_sram_map.map_priv_1) {
+		printk("Failed to ioremap autcpu12 NV-RAM space\n");
+		err = -EIO;
+		goto out;
+	}
+	
+	/* 
+	 * Check for 32K/128K 
+	 * read ofs 0 
+	 * read ofs 0x10000 
+	 * Write complement to ofs 0x100000
+	 * Read	and check result on ofs 0x0
+	 * Restore contents
+	 */
+	save0 = autcpu12_read32(&autcpu12_sram_map,0);
+	save1 = autcpu12_read32(&autcpu12_sram_map,0x10000);
+	autcpu12_write32(&autcpu12_sram_map,~save0,0x10000);
+	/* if we find this pattern on 0x0, we have 32K size 
+	 * restore contents and exit
+	 */
+	if ( autcpu12_read32(&autcpu12_sram_map,0) != save0) {
+		autcpu12_write32(&autcpu12_sram_map,save0,0x0);
+		goto map;
+	}
+	/* We have a 128K found, restore 0x10000 and set size
+	 * to 128K
+	 */
+	autcpu12_write32(&autcpu12_sram_map,save1,0x10000);
+	autcpu12_sram_map.size = SZ_128K;
+
+map:
+	sram_mtd = do_map_probe("map_ram", &autcpu12_sram_map);
+	if (!sram_mtd) {
+		printk("NV-RAM probe failed\n");
+		err = -ENXIO;
+		goto out_ioremap;
+	}
+
+	sram_mtd->module = THIS_MODULE;
+	sram_mtd->erasesize = 16;
+	
+	if (add_mtd_device(sram_mtd)) {
+		printk("NV-RAM device addition failed\n");
+		err = -ENOMEM;
+		goto out_probe;
+	}
+
+	printk("NV-RAM device size %ldK registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
+		
+	return 0;
+
+out_probe:
+	map_destroy(sram_mtd);
+	sram_mtd = 0;
+
+out_ioremap:
+	iounmap((void *)autcpu12_sram_map.map_priv_1);
+out:
+	return err;
+}
+
+static void __exit cleanup_autcpu12_maps(void)
+{
+	if (sram_mtd) {
+		del_mtd_device(sram_mtd);
+		map_destroy(sram_mtd);
+		iounmap((void *)autcpu12_sram_map.map_priv_1);
+	}
+}
+
+module_init(init_autcpu12_sram);
+module_exit(cleanup_autcpu12_maps);
+
+MODULE_AUTHOR("Thomas Gleixner");
+MODULE_DESCRIPTION("autcpu12 NV-RAM map driver");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/dc21285.c linux/drivers/mtd/maps/dc21285.c
--- linux.orig/drivers/mtd/maps/dc21285.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/maps/dc21285.c	2002-07-20 01:08:34.000000000 +0000
@@ -5,7 +5,7 @@
  *
  * This code is GPL
  * 
- * $Id: dc21285.c,v 1.6 2001/10/02 15:05:14 dwmw2 Exp $
+ * $Id: dc21285.c,v 1.7 2001/10/11 16:17:51 nico Exp $
  */
 
 #include <linux/module.h>
@@ -44,15 +44,15 @@
 
 void dc21285_write8(struct map_info *map, __u8 d, unsigned long adr)
 {
-	*CSR_ROMWRITEREG = adr;
+	*CSR_ROMWRITEREG = adr & 3;
 	adr &= ~3;
 	*(__u8*)(map->map_priv_1 + adr) = d;
 }
 
 void dc21285_write16(struct map_info *map, __u16 d, unsigned long adr)
 {
-	*CSR_ROMWRITEREG = adr;
-	adr &= ~1;
+	*CSR_ROMWRITEREG = adr & 3;
+	adr &= ~3;
 	*(__u16*)(map->map_priv_1 + adr) = d;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/dilnetpc.c linux/drivers/mtd/maps/dilnetpc.c
--- linux.orig/drivers/mtd/maps/dilnetpc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/dilnetpc.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,540 @@
+/* dilnetpc.c -- MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP"
+ *
+ * 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
+ *
+ * $Id: dilnetpc.c,v 1.8 2002/03/12 13:07:26 rkaiser Exp $
+ *
+ * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
+ * featuring the AMD Elan SC410 processor. There are two variants of this
+ * board: DNP/1486 and ADNP/1486. The DNP version has 2 megs of flash
+ * ROM (Intel 28F016S3) and 8 megs of DRAM, the ADNP version has 4 megs
+ * flash and 16 megs of RAM.
+ * For details, see http://www.ssv-embedded.de/ssv/pc104/p169.htm
+ * and http://www.ssv-embedded.de/ssv/pc104/p170.htm
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/concat.h>
+
+/*
+** The DIL/NetPC keeps it's BIOS in two distinct flash blocks.
+** Destroying any of these blocks transforms the DNPC into
+** a paperweight (albeit not a very useful one, considering
+** it only weighs a few grams).
+**
+** Therefore, the BIOS blocks must never be erased or written to
+** except by people who know exactly what they are doing (e.g.
+** to install a BIOS update). These partitions are marked read-only
+** by default, but can be made read/write by undefining
+** DNPC_BIOS_BLOCKS_WRITEPROTECTED:
+*/
+#define DNPC_BIOS_BLOCKS_WRITEPROTECTED
+
+/*
+** The ID string (in ROM) is checked to determine whether we
+** are running on a DNP/1486 or ADNP/1486
+*/
+#define BIOSID_BASE	0x000fe100
+
+#define ID_DNPC	"DNP1486"
+#define ID_ADNP	"ADNP1486"
+
+/*
+** Address where the flash should appear in CPU space
+*/
+#define FLASH_BASE	0x2000000
+
+/*
+** Chip Setup and Control (CSC) indexed register space
+*/
+#define CSC_INDEX	0x22
+#define CSC_DATA	0x23
+
+#define CSC_MMSWAR	0x30	/* MMS window C-F attributes register */
+#define CSC_MMSWDSR	0x31	/* MMS window C-F device select register */
+
+#define CSC_RBWR	0xa7	/* GPIO Read-Back/Write Register B */
+
+#define CSC_CR		0xd0	/* internal I/O device disable/Echo */
+				/* Z-bus/configuration register */
+
+#define CSC_PCCMDCR	0xf1	/* PC card mode and DMA control register */
+
+
+/*
+** PC Card indexed register space:
+*/
+
+#define PCC_INDEX	0x3e0
+#define PCC_DATA	0x3e1
+
+#define PCC_AWER_B		0x46	/* Socket B Address Window enable register */
+#define PCC_MWSAR_1_Lo	0x58	/* memory window 1 start address low register */
+#define PCC_MWSAR_1_Hi	0x59	/* memory window 1 start address high register */
+#define PCC_MWEAR_1_Lo	0x5A	/* memory window 1 stop address low register */
+#define PCC_MWEAR_1_Hi	0x5B	/* memory window 1 stop address high register */
+#define PCC_MWAOR_1_Lo	0x5C	/* memory window 1 address offset low register */
+#define PCC_MWAOR_1_Hi	0x5D	/* memory window 1 address offset high register */
+
+
+/*
+** Access to SC4x0's Chip Setup and Control (CSC)
+** and PC Card (PCC) indexed registers:
+*/
+static inline void setcsc(int reg, unsigned char data)
+{
+	outb(reg, CSC_INDEX);
+	outb(data, CSC_DATA);
+}
+
+static inline unsigned char getcsc(int reg)
+{
+	outb(reg, CSC_INDEX);
+	return(inb(CSC_DATA));
+}
+
+static inline void setpcc(int reg, unsigned char data)
+{
+	outb(reg, PCC_INDEX);
+	outb(data, PCC_DATA);
+}
+
+static inline unsigned char getpcc(int reg)
+{
+	outb(reg, PCC_INDEX);
+	return(inb(PCC_DATA));
+}
+
+
+/*
+************************************************************
+** Enable access to DIL/NetPC's flash by mapping it into
+** the SC4x0's MMS Window C.
+************************************************************
+*/
+static void dnpc_map_flash(unsigned long flash_base, unsigned long flash_size)
+{
+	unsigned long flash_end = flash_base + flash_size - 1;
+
+	/*
+	** enable setup of MMS windows C-F:
+	*/
+	/* - enable PC Card indexed register space */
+	setcsc(CSC_CR, getcsc(CSC_CR) | 0x2);
+	/* - set PC Card controller to operate in standard mode */
+	setcsc(CSC_PCCMDCR, getcsc(CSC_PCCMDCR) & ~1);
+
+	/*
+	** Program base address and end address of window
+	** where the flash ROM should appear in CPU address space
+	*/
+	setpcc(PCC_MWSAR_1_Lo, (flash_base >> 12) & 0xff);
+	setpcc(PCC_MWSAR_1_Hi, (flash_base >> 20) & 0x3f);
+	setpcc(PCC_MWEAR_1_Lo, (flash_end >> 12) & 0xff);
+	setpcc(PCC_MWEAR_1_Hi, (flash_end >> 20) & 0x3f);
+
+	/* program offset of first flash location to appear in this window (0) */
+	setpcc(PCC_MWAOR_1_Lo, ((0 - flash_base) >> 12) & 0xff);
+	setpcc(PCC_MWAOR_1_Hi, ((0 - flash_base)>> 20) & 0x3f);
+
+	/* set attributes for MMS window C: non-cacheable, write-enabled */
+	setcsc(CSC_MMSWAR, getcsc(CSC_MMSWAR) & ~0x11);
+
+	/* select physical device ROMCS0 (i.e. flash) for MMS Window C */
+	setcsc(CSC_MMSWDSR, getcsc(CSC_MMSWDSR) & ~0x03);
+
+	/* enable memory window 1 */
+	setpcc(PCC_AWER_B, getpcc(PCC_AWER_B) | 0x02);
+
+	/* now disable PC Card indexed register space again */
+	setcsc(CSC_CR, getcsc(CSC_CR) & ~0x2);
+}
+
+
+/*
+************************************************************
+** Disable access to DIL/NetPC's flash by mapping it into
+** the SC4x0's MMS Window C.
+************************************************************
+*/
+static void dnpc_unmap_flash(void)
+{
+	/* - enable PC Card indexed register space */
+	setcsc(CSC_CR, getcsc(CSC_CR) | 0x2);
+
+	/* disable memory window 1 */
+	setpcc(PCC_AWER_B, getpcc(PCC_AWER_B) & ~0x02);
+
+	/* now disable PC Card indexed register space again */
+	setcsc(CSC_CR, getcsc(CSC_CR) & ~0x2);
+}
+
+
+static __u8 dnpc_read8(struct map_info *map, unsigned long ofs)
+{
+	return readb(map->map_priv_1 + ofs);
+}
+
+static __u16 dnpc_read16(struct map_info *map, unsigned long ofs)
+{
+	return readw(map->map_priv_1 + ofs);
+}
+
+static __u32 dnpc_read32(struct map_info *map, unsigned long ofs)
+{
+	return readl(map->map_priv_1 + ofs);
+}
+
+static void dnpc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void dnpc_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	writeb(d, map->map_priv_1 + adr);
+}
+
+static void dnpc_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	writew(d, map->map_priv_1 + adr);
+}
+
+static void dnpc_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	writel(d, map->map_priv_1 + adr);
+}
+
+static void dnpc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio((void *)(map->map_priv_1 + to), from, len);
+}
+
+/*
+************************************************************
+** Enable/Disable VPP to write to flash
+************************************************************
+*/
+
+static spinlock_t dnpc_spin   = SPIN_LOCK_UNLOCKED;
+static int        vpp_counter = 0;
+/*
+** This is what has to be done for the DNP board ..
+*/
+static void dnp_set_vpp(struct map_info *not_used, int on)
+{
+	spin_lock_irq(&dnpc_spin);
+
+	if (on)
+	{
+		if(++vpp_counter == 1)
+			setcsc(CSC_RBWR, getcsc(CSC_RBWR) & ~0x4);
+	}
+	else
+	{
+		if(--vpp_counter == 0)
+			setcsc(CSC_RBWR, getcsc(CSC_RBWR) | 0x4);
+		else if(vpp_counter < 0)
+			BUG();
+	}
+	spin_unlock_irq(&dnpc_spin);
+}
+
+/*
+** .. and this the ADNP version:
+*/
+static void adnp_set_vpp(struct map_info *not_used, int on)
+{
+	spin_lock_irq(&dnpc_spin);
+
+	if (on)
+	{
+		if(++vpp_counter == 1)
+			setcsc(CSC_RBWR, getcsc(CSC_RBWR) & ~0x8);
+	}
+	else
+	{
+		if(--vpp_counter == 0)
+			setcsc(CSC_RBWR, getcsc(CSC_RBWR) | 0x8);
+		else if(vpp_counter < 0)
+			BUG();
+	}
+	spin_unlock_irq(&dnpc_spin);
+}
+
+
+
+#define DNP_WINDOW_SIZE		0x00200000	/*  DNP flash size is 2MiB  */
+#define ADNP_WINDOW_SIZE	0x00400000	/* ADNP flash size is 4MiB */
+#define WINDOW_ADDR			FLASH_BASE
+
+static struct map_info dnpc_map = {
+	name: "ADNP Flash Bank",
+	size: ADNP_WINDOW_SIZE,
+	buswidth: 1,
+	read8: dnpc_read8,
+	read16: dnpc_read16,
+	read32: dnpc_read32,
+	copy_from: dnpc_copy_from,
+	write8: dnpc_write8,
+	write16: dnpc_write16,
+	write32: dnpc_write32,
+	copy_to: dnpc_copy_to,
+	set_vpp: adnp_set_vpp,
+	map_priv_2: WINDOW_ADDR
+};
+
+/*
+** The layout of the flash is somewhat "strange":
+**
+** 1.  960 KiB (15 blocks) : Space for ROM Bootloader and user data
+** 2.   64 KiB (1 block)   : System BIOS
+** 3.  960 KiB (15 blocks) : User Data (DNP model) or
+** 3. 3008 KiB (47 blocks) : User Data (ADNP model)
+** 4.   64 KiB (1 block)   : System BIOS Entry
+*/
+
+static struct mtd_partition partition_info[]=
+{
+	{ 
+		name:		"ADNP boot", 
+		offset:		0, 
+		size:		0xf0000,
+	},
+	{ 
+		name:		"ADNP system BIOS", 
+		offset:		MTDPART_OFS_NXTBLK,
+		size:		0x10000,
+#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
+		mask_flags:	MTD_WRITEABLE,
+#endif
+	},
+	{
+		name:		"ADNP file system",
+		offset:		MTDPART_OFS_NXTBLK,
+		size:		0x2f0000,
+	},
+	{
+		name:		"ADNP system BIOS entry", 
+		offset:		MTDPART_OFS_NXTBLK,
+		size:		MTDPART_SIZ_FULL,
+#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
+		mask_flags:	MTD_WRITEABLE,
+#endif
+	},
+};
+
+#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
+
+static struct mtd_info *mymtd;
+static struct mtd_info *lowlvl_parts[NUM_PARTITIONS];
+static struct mtd_info *merged_mtd;
+
+/*
+** "Highlevel" partition info:
+**
+** Using the MTD concat layer, we can re-arrange partitions to our
+** liking: we construct a virtual MTD device by concatenating the
+** partitions, specifying the sequence such that the boot block
+** is immediately followed by the filesystem block (i.e. the stupid
+** system BIOS block is mapped to a different place). When re-partitioning
+** this concatenated MTD device, we can set the boot block size to
+** an arbitrary (though erase block aligned) value i.e. not one that
+** is dictated by the flash's physical layout. We can thus set the
+** boot block to be e.g. 64 KB (which is fully sufficient if we want
+** to boot an etherboot image) or to -say- 1.5 MB if we want to boot
+** a large kernel image. In all cases, the remainder of the flash
+** is available as file system space.
+*/
+
+static struct mtd_partition higlvl_partition_info[]=
+{
+	{ 
+		name:		"ADNP boot block", 
+		offset:		0, 
+		size:		CONFIG_MTD_DILNETPC_BOOTSIZE,
+	},
+	{
+		name:		"ADNP file system space",
+		offset:		MTDPART_OFS_NXTBLK,
+		size:		ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
+	},
+	{ 
+		name:		"ADNP system BIOS + BIOS Entry", 
+		offset:		MTDPART_OFS_NXTBLK,
+		size:		MTDPART_SIZ_FULL,
+#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
+		mask_flags:	MTD_WRITEABLE,
+#endif
+	},
+};
+
+#define NUM_HIGHLVL_PARTITIONS (sizeof(higlvl_partition_info)/sizeof(partition_info[0]))
+
+
+static int dnp_adnp_probe(void)
+{
+	char *biosid, rc = -1;
+
+	biosid = (char*)ioremap(BIOSID_BASE, 16);
+	if(biosid)
+	{
+		if(!strcmp(biosid, ID_DNPC))
+			rc = 1;		/* this is a DNPC  */
+		else if(!strcmp(biosid, ID_ADNP))
+			rc = 0;		/* this is a ADNPC */
+	}
+	iounmap((void *)biosid);
+	return(rc);
+}
+
+
+static int __init init_dnpc(void)
+{
+	int is_dnp;
+
+	/*
+	** determine hardware (DNP/ADNP/invalid)
+	*/	
+	if((is_dnp = dnp_adnp_probe()) < 0)
+		return -ENXIO;
+
+	/*
+	** Things are set up for ADNP by default
+	** -> modify all that needs to be different for DNP
+	*/
+	if(is_dnp)
+	{	/*
+		** Adjust window size, select correct set_vpp function.
+		** The partitioning scheme is identical on both DNP
+		** and ADNP except for the size of the third partition.
+		*/
+		int i;
+		dnpc_map.size          = DNP_WINDOW_SIZE;
+		dnpc_map.set_vpp       = dnp_set_vpp;
+		partition_info[2].size = 0xf0000;
+
+		/*
+		** increment all string pointers so the leading 'A' gets skipped,
+		** thus turning all occurrences of "ADNP ..." into "DNP ..."
+		*/
+		++dnpc_map.name;
+		for(i = 0; i < NUM_PARTITIONS; i++)
+			++partition_info[i].name;
+		higlvl_partition_info[1].size = DNP_WINDOW_SIZE - 
+			CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000;
+		for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++)
+			++higlvl_partition_info[i].name;
+	}
+
+	printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n", 
+		is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.map_priv_2);
+
+	dnpc_map.map_priv_1 = (unsigned long)ioremap_nocache(dnpc_map.map_priv_2, dnpc_map.size);
+
+	dnpc_map_flash(dnpc_map.map_priv_2, dnpc_map.size);
+
+	if (!dnpc_map.map_priv_1) {
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+
+	printk("FLASH virtual address: 0x%lx\n", dnpc_map.map_priv_1);
+
+	mymtd = do_map_probe("jedec_probe", &dnpc_map);
+
+	if (!mymtd)
+		mymtd = do_map_probe("cfi_probe", &dnpc_map);
+
+	/*
+	** If flash probes fail, try to make flashes accessible
+	** at least as ROM. Ajust erasesize in this case since
+	** the default one (128M) will break our partitioning
+	*/
+	if (!mymtd)
+		if((mymtd = do_map_probe("map_rom", &dnpc_map)))
+			mymtd->erasesize = 0x10000;
+
+	if (!mymtd) {
+		iounmap((void *)dnpc_map.map_priv_1);
+		return -ENXIO;
+	}
+		
+	mymtd->module = THIS_MODULE;
+
+	/*
+	** Supply pointers to lowlvl_parts[] array to add_mtd_partitions()
+	** -> add_mtd_partitions() will _not_ register MTD devices for
+	** the partitions, but will instead store pointers to the MTD
+	** objects it creates into our lowlvl_parts[] array.
+	** NOTE: we arrange the pointers such that the sequence of the
+	**       partitions gets re-arranged: partition #2 follows
+	**       partition #0.
+	*/
+	partition_info[0].mtdp = &lowlvl_parts[0];
+	partition_info[1].mtdp = &lowlvl_parts[2];
+	partition_info[2].mtdp = &lowlvl_parts[1];
+	partition_info[3].mtdp = &lowlvl_parts[3];
+
+	add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
+
+	/*
+	** now create a virtual MTD device by concatenating the for partitions
+	** (in the sequence given by the lowlvl_parts[] array.
+	*/
+	merged_mtd = mtd_concat_create(lowlvl_parts, NUM_PARTITIONS, "(A)DNP Flash Concatenated");
+	if(merged_mtd)
+	{	/*
+		** now partition the new device the way we want it. This time,
+		** we do not supply mtd pointers in higlvl_partition_info, so
+		** add_mtd_partitions() will register the devices.
+		*/
+		add_mtd_partitions(merged_mtd, higlvl_partition_info, NUM_HIGHLVL_PARTITIONS);
+	}
+
+	return 0;
+}
+
+static void __exit cleanup_dnpc(void)
+{
+	if(merged_mtd) {
+		del_mtd_partitions(merged_mtd);
+		mtd_concat_destroy(merged_mtd);
+	}
+
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (dnpc_map.map_priv_1) {
+		iounmap((void *)dnpc_map.map_priv_1);
+		dnpc_unmap_flash();
+		dnpc_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_dnpc);
+module_exit(cleanup_dnpc);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sysgo Real-Time Solutions GmbH");
+MODULE_DESCRIPTION("MTD map driver for SSV DIL/NetPC DNP & ADNP");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/elan-104nc.c linux/drivers/mtd/maps/elan-104nc.c
--- linux.orig/drivers/mtd/maps/elan-104nc.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/mtd/maps/elan-104nc.c	2002-07-20 01:08:36.000000000 +0000
@@ -16,7 +16,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
-   $Id: elan-104nc.c,v 1.12 2001/10/02 15:05:14 dwmw2 Exp $
+   $Id: elan-104nc.c,v 1.13 2002/02/13 15:30:20 dwmw2 Exp $
 
 The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
 mode.  This drivers uses the CFI probe and Intel Extended Command Set drivers.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/epxa10db-flash.c linux/drivers/mtd/maps/epxa10db-flash.c
--- linux.orig/drivers/mtd/maps/epxa10db-flash.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/epxa10db-flash.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,219 @@
+/*
+ * Flash memory access on EPXA based devices
+ *
+ * (C) 2000 Nicolas Pitre <nico@cam.org>
+ *  Copyright (C) 2001 Altera Corporation
+ *  Copyright (C) 2001 Red Hat, Inc.
+ *
+ * $Id: epxa10db-flash.c,v 1.2 2001/12/19 13:00:19 jskov Exp $ 
+ *
+ * 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/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/hardware.h>
+
+static int nr_parts = 0;
+static struct mtd_partition *parts;
+
+static struct mtd_info *mymtd;
+
+extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
+static int epxa10db_default_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+
+static __u8 epxa10db_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+static __u16 epxa10db_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+static __u32 epxa10db_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+static void epxa10db_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void epxa10db_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+static void epxa10db_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+static void epxa10db_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+static void epxa10db_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio((void *)(map->map_priv_1 + to), from, len);
+}
+
+
+
+static struct map_info epxa10db_map = {
+	name:		"EPXA10DB flash",
+	size:		FLASH_SIZE,
+	buswidth:	2,
+	read8:		epxa10db_read8,
+	read16:		epxa10db_read16,
+	read32:		epxa10db_read32,
+	copy_from:	epxa10db_copy_from,
+	write8:		epxa10db_write8,
+	write16:	epxa10db_write16,
+	write32:	epxa10db_write32,
+	copy_to:	epxa10db_copy_to
+};
+
+
+static int __init epxa10db_mtd_init(void)
+{
+	int i;
+	printk(KERN_NOTICE "Epxa10db flash device: %x at %x\n", FLASH_SIZE, FLASH_START);
+	epxa10db_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
+	if (!epxa10db_map.map_priv_1) {
+		printk("Failed to ioremap Epxa10db flash\n");
+		return -EIO;
+	}
+
+	mymtd = do_map_probe("cfi_probe", &epxa10db_map);
+	if (!mymtd) {
+		iounmap((void *)epxa10db_map.map_priv_1);
+		return -ENXIO;
+	}
+
+	mymtd->module = THIS_MODULE;
+
+	/* Unlock the flash device. */
+	for (i=0; i<mymtd->numeraseregions;i++){
+		int j;
+		for(j=0;j<mymtd->eraseregions[i].numblocks;j++){
+			mymtd->unlock(mymtd,mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize,4);
+		}
+	}
+
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+	nr_parts = parse_redboot_partitions(mymtd, &parts);
+
+	if (nr_parts > 0) {
+		add_mtd_partitions(mymtd, parts, nr_parts);
+		return 0;
+	}
+#endif
+#ifdef CONFIG_MTD_AFS_PARTS
+	nr_parts = parse_afs_partitions(mymtd, &parts);
+
+	if (nr_parts > 0) {
+		add_mtd_partitions(mymtd, parts, nr_parts);
+		return 0;
+	}
+#endif
+
+	/* No recognised partitioning schemes found - use defaults */
+	nr_parts = epxa10db_default_partitions(mymtd, &parts);
+	if (nr_parts > 0) {
+		add_mtd_partitions(mymtd, parts, nr_parts);
+		return 0;
+	}
+
+	/* If all else fails... */
+	add_mtd_device(mymtd);
+	return 0;
+}
+
+static void __exit epxa10db_mtd_cleanup(void)
+{
+	if (mymtd) {
+		if (nr_parts)
+			del_mtd_partitions(mymtd);
+		else
+			del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (epxa10db_map.map_priv_1) {
+		iounmap((void *)epxa10db_map.map_priv_1);
+		epxa10db_map.map_priv_1 = 0;
+	}
+}
+
+
+/* 
+ * This will do for now, once we decide which bootldr we're finally 
+ * going to use then we'll remove this function and do it properly
+ *
+ * Partions are currently (as offsets from base of flash):
+ * 0x00000000 - 0x003FFFFF - bootloader (!)
+ * 0x00400000 - 0x00FFFFFF - Flashdisk
+ */
+
+static int __init epxa10db_default_partitions(struct mtd_info *master, struct mtd_partition **pparts)
+{
+	struct mtd_partition *parts;
+	int ret, i;
+	int npartitions = 0;
+	char *names; 
+	const char *name = "jffs";
+
+	printk("Using default partitions for epxa10db\n");
+	npartitions=1;
+	parts = kmalloc(npartitions*sizeof(*parts)+strlen(name), GFP_KERNEL);
+	if (!parts) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	i=0;
+	names = (char *)&parts[npartitions];	
+	parts[i].name = names;
+	names += strlen(name) + 1;
+	strcpy(parts[i].name, name);
+
+	parts[i].size = FLASH_SIZE-0x00400000;
+	parts[i].offset = 0x00400000;
+	parts[i].mask_flags = 0;
+
+ out:
+	*pparts = parts;
+	return npartitions;
+}
+
+module_init(epxa10db_mtd_init);
+module_exit(epxa10db_mtd_cleanup);
+
+MODULE_AUTHOR("Clive Davies");
+MODULE_DESCRIPTION("Altera epxa10db mtd flash map");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/ich2rom.c linux/drivers/mtd/maps/ich2rom.c
--- linux.orig/drivers/mtd/maps/ich2rom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/ich2rom.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,302 @@
+/*
+ * ich2rom.c
+ *
+ * Normal mappings of chips in physical memory
+ * $Id: ich2rom.c,v 1.1 2002/01/10 22:59:13 eric Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+
+#define RESERVE_MEM_REGION 0
+
+#define ICH2_FWH_REGION_START	0xFF000000UL
+#define ICH2_FWH_REGION_SIZE	0x01000000UL
+#define BIOS_CNTL	0x4e
+#define FWH_DEC_EN1	0xE3
+#define FWH_DEC_EN2	0xF0
+#define FWH_SEL1	0xE8
+#define FWH_SEL2	0xEE
+
+struct ich2rom_map_info {
+	struct map_info map;
+	struct mtd_info *mtd;
+	unsigned long window_addr;
+};
+
+static inline unsigned long addr(struct map_info *map, unsigned long ofs)
+{
+	unsigned long offset;
+	offset = ((8*1024*1024) - map->size) + ofs;
+	if (offset >= (4*1024*1024)) {
+		offset += 0x400000;
+	}
+	return map->map_priv_1 + 0x400000 + offset;
+}
+
+static inline unsigned long dbg_addr(struct map_info *map, unsigned long addr)
+{
+	return addr - map->map_priv_1 + ICH2_FWH_REGION_START;
+}
+	
+static __u8 ich2rom_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(addr(map, ofs));
+}
+
+static __u16 ich2rom_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(addr(map, ofs));
+}
+
+static __u32 ich2rom_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(addr(map, ofs));
+}
+
+static void ich2rom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, addr(map, from), len);
+}
+
+static void ich2rom_write8(struct map_info *map, __u8 d, unsigned long ofs)
+{
+	__raw_writeb(d, addr(map,ofs));
+	mb();
+}
+
+static void ich2rom_write16(struct map_info *map, __u16 d, unsigned long ofs)
+{
+	__raw_writew(d, addr(map, ofs));
+	mb();
+}
+
+static void ich2rom_write32(struct map_info *map, __u32 d, unsigned long ofs)
+{
+	__raw_writel(d, addr(map, ofs));
+	mb();
+}
+
+static void ich2rom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(addr(map, to), from, len);
+}
+
+static struct ich2rom_map_info ich2rom_map = {
+	map: {
+		name: "ICH2 rom",
+		size: 0,
+		buswidth: 1,
+		read8: ich2rom_read8,
+		read16: ich2rom_read16,
+		read32: ich2rom_read32,
+		copy_from: ich2rom_copy_from,
+		write8: ich2rom_write8,
+		write16: ich2rom_write16,
+		write32: ich2rom_write32,
+		copy_to: ich2rom_copy_to,
+		/* Firmware hubs only use vpp when being programmed
+		 * in a factory setting.  So in place programming
+		 * needs to use a different method.
+		 */
+	},
+	mtd: 0,
+	window_addr: 0,
+};
+
+enum fwh_lock_state {
+	FWH_DENY_WRITE = 1,
+	FWH_IMMUTABLE  = 2,
+	FWH_DENY_READ  = 4,
+};
+
+static int ich2rom_set_lock_state(struct mtd_info *mtd, loff_t ofs, size_t len,
+	enum fwh_lock_state state)
+{
+	struct map_info *map = mtd->priv;
+	unsigned long start = ofs;
+	unsigned long end = start + len -1;
+
+	/* FIXME do I need to guard against concurrency here? */
+	/* round down to 64K boundaries */
+	start = start & ~0xFFFF;
+	end = end & ~0xFFFF;
+	while (start <= end) {
+		unsigned long ctrl_addr;
+		ctrl_addr = addr(map, start) - 0x400000 + 2;
+		writeb(state, ctrl_addr);
+		start = start + 0x10000;
+	}
+	return 0;
+}
+
+static int ich2rom_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	return ich2rom_set_lock_state(mtd, ofs, len, FWH_DENY_WRITE);
+}
+
+static int ich2rom_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	return ich2rom_set_lock_state(mtd, ofs, len, 0);
+}
+
+static int __devinit ich2rom_init_one (struct pci_dev *pdev,
+	const struct pci_device_id *ent)
+{
+	u16 word;
+	struct ich2rom_map_info *info = &ich2rom_map;
+	unsigned long map_size;
+
+	/* For now I just handle the ich2 and I assume there
+	 * are not a lot of resources up at the top of the address
+	 * space.  It is possible to handle other devices in the
+	 * top 16MB but it is very painful.  Also since
+	 * you can only really attach a FWH to an ICH2 there
+	 * a number of simplifications you can make.
+	 *
+	 * Also you can page firmware hubs if an 8MB window isn't enough 
+	 * but don't currently handle that case either.
+	 */
+
+#if RESERVE_MEM_REGION
+	/* Some boards have this reserved and I haven't found a good work
+	 * around to say I know what I'm doing!
+	 */
+	if (!request_mem_region(ICH2_FWH_REGION_START, ICH2_FWH_REGION_SIZE, "ich2rom")) {
+		printk(KERN_ERR "ich2rom: cannot reserve rom window\n");
+		goto err_out_none;
+	}
+#endif /* RESERVE_MEM_REGION */
+	
+	/* Enable writes through the rom window */
+	pci_read_config_word(pdev, BIOS_CNTL, &word);
+	if (!(word & 1)  && (word & (1<<1))) {
+		/* The BIOS will generate an error if I enable
+		 * this device, so don't even try.
+		 */
+		printk(KERN_ERR "ich2rom: firmware access control, I can't enable writes\n");
+		goto err_out_none;
+	}
+	pci_write_config_word(pdev, BIOS_CNTL, word | 1);
+
+
+	/* Map the firmware hub into my address space. */
+	/* Does this use to much virtual address space? */
+	info->window_addr = (unsigned long)ioremap(
+		ICH2_FWH_REGION_START, ICH2_FWH_REGION_SIZE);
+	if (!info->window_addr) {
+		printk(KERN_ERR "Failed to ioremap\n");
+		goto err_out_free_mmio_region;
+	}
+
+	/* For now assume the firmware has setup all relavent firmware
+	 * windows.  We don't have enough information to handle this case
+	 * intelligently.
+	 */
+
+	/* FIXME select the firmware hub and enable a window to it. */
+
+	info->mtd = 0;
+	info->map.map_priv_1 = 	info->window_addr;
+
+	map_size = ICH2_FWH_REGION_SIZE;
+	while(!info->mtd && (map_size > 0)) {
+		info->map.size = map_size;
+		info->mtd = do_map_probe("jedec_probe", &ich2rom_map.map);
+		map_size -= 512*1024;
+	}
+	if (!info->mtd) {
+		goto err_out_iounmap;
+	}
+	/* I know I can only be a firmware hub here so put
+	 * in the special lock and unlock routines.
+	 */
+	info->mtd->lock = ich2rom_lock;
+	info->mtd->unlock = ich2rom_unlock;
+		
+	info->mtd->module = THIS_MODULE;
+	add_mtd_device(info->mtd);
+	return 0;
+
+err_out_iounmap:
+	iounmap((void *)(info->window_addr));
+err_out_free_mmio_region:
+#if RESERVE_MEM_REGION
+	release_mem_region(ICH2_FWH_REGION_START, ICH2_FWH_REGION_SIZE);
+#endif
+err_out_none:
+	return -ENODEV;
+}
+
+
+static void __devexit ich2rom_remove_one (struct pci_dev *pdev)
+{
+	struct ich2rom_map_info *info = &ich2rom_map;
+	u16 word;
+
+	del_mtd_device(info->mtd);
+	map_destroy(info->mtd);
+	info->mtd = 0;
+	info->map.map_priv_1 = 0;
+
+	iounmap((void *)(info->window_addr));
+	info->window_addr = 0;
+
+	/* Disable writes through the rom window */
+	pci_read_config_word(pdev, BIOS_CNTL, &word);
+	pci_write_config_word(pdev, BIOS_CNTL, word & ~1);
+
+#if RESERVE_MEM_REGION	
+	release_mem_region(ICH2_FWH_REGION_START, ICH2_FWH_REGION_SIZE);
+#endif
+}
+
+static struct pci_device_id ich2rom_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, 
+	  PCI_ANY_ID, PCI_ANY_ID, },
+};
+
+MODULE_DEVICE_TABLE(pci, ich2rom_pci_tbl);
+
+#if 0
+static struct pci_driver ich2rom_driver = {
+	name:	  "ich2rom",
+	id_table: ich2rom_pci_tbl,
+	probe:    ich2rom_init_one,
+	remove:   ich2rom_remove_one,
+};
+#endif
+
+static struct pci_dev *mydev;
+int __init init_ich2rom(void)
+{
+	struct pci_dev *pdev;
+	pdev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, 0);
+	if (pdev) {
+		mydev = pdev;
+		return ich2rom_init_one(pdev, &ich2rom_pci_tbl[0]);
+	}
+	return -ENXIO;
+#if 0
+	return pci_module_init(&ich2rom_driver);
+#endif
+}
+
+static void __exit cleanup_ich2rom(void)
+{
+	ich2rom_remove_one(mydev);
+}
+
+module_init(init_ich2rom);
+module_exit(cleanup_ich2rom);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>");
+MODULE_DESCRIPTION("MTD map driver for BIOS chips on the ICH2 southbridge");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/integrator-flash.c linux/drivers/mtd/maps/integrator-flash.c
--- linux.orig/drivers/mtd/maps/integrator-flash.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/maps/integrator-flash.c	2002-07-20 01:08:29.000000000 +0000
@@ -21,7 +21,7 @@
    This is access code for flashes using ARM's flash partitioning 
    standards.
 
-   $Id: integrator-flash.c,v 1.6 2001/10/02 16:00:01 dwmw2 Exp $
+   $Id: integrator-flash.c,v 1.7 2001/11/01 20:55:47 rmk Exp $
 
 ======================================================================*/
 
@@ -208,10 +208,10 @@
 };
 
 static struct mtd_info *mtd;
+static struct mtd_partition *parts;
 
 static int __init armflash_cfi_init(void *base, u_int size)
 {
-	struct mtd_partition *parts;
 	int ret;
 
 	armflash_flash_init();
@@ -238,8 +238,6 @@
 	ret = parse_afs_partitions(mtd, &parts);
 	if (ret > 0) {
 		ret = add_mtd_partitions(mtd, parts, ret);
-		/* we don't need the partition info any longer */
-		kfree(parts);
 		if (ret)
 			printk(KERN_ERR "mtd partition registration "
 				"failed: %d\n", ret);
@@ -262,6 +260,8 @@
 		del_mtd_partitions(mtd);
 		map_destroy(mtd);
 	}
+	if (parts)
+		kfree(parts);
 }
 
 static int __init armflash_init(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/iq80310.c linux/drivers/mtd/maps/iq80310.c
--- linux.orig/drivers/mtd/maps/iq80310.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/maps/iq80310.c	2002-07-20 01:08:32.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: iq80310.c,v 1.8 2001/10/02 15:05:14 dwmw2 Exp $
+ * $Id: iq80310.c,v 1.9 2002/01/01 22:45:02 rmk Exp $
  *
  * Mapping for the Intel XScale IQ80310 evaluation board
  *
@@ -116,7 +116,7 @@
 	int parsed_nr_parts = 0;
 	char *part_type = "static";
 
-	iq80310_map.map_priv_1 = (unsigned long)__ioremap(WINDOW_ADDR, WINDOW_SIZE, 0);
+	iq80310_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
 	if (!iq80310_map.map_priv_1) {
 		printk("Failed to ioremap\n");
 		return -EIO;
@@ -161,7 +161,6 @@
 	}
 	if (iq80310_map.map_priv_1)
 		iounmap((void *)iq80310_map.map_priv_1);
-	return 0;
 }
 
 module_init(init_iq80310);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/l440gx.c linux/drivers/mtd/maps/l440gx.c
--- linux.orig/drivers/mtd/maps/l440gx.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/maps/l440gx.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,7 +1,9 @@
 /*
- * $Id: l440gx.c,v 1.7 2001/10/02 15:05:14 dwmw2 Exp $
+ * $Id: l440gx.c,v 1.8 2002/01/10 20:27:40 eric Exp $
  *
  * BIOS Flash chip on Intel 440GX board.
+ *
+ * Bugs this currently does not work under linuxBIOS.
  */
 
 #include <linux/module.h>
@@ -12,12 +14,14 @@
 #include <linux/mtd/map.h>
 #include <linux/config.h>
 
+#define PIIXE_IOBASE_RESOURCE	11
 
 #define WINDOW_ADDR 0xfff00000
 #define WINDOW_SIZE 0x00100000
 #define BUSWIDTH 1
 
-#define IOBASE 0xc00
+static u32 iobase;
+#define IOBASE iobase
 #define TRIBUF_PORT (IOBASE+0x37)
 #define VPP_PORT (IOBASE+0x28)
 
@@ -66,12 +70,17 @@
 	memcpy_toio(map->map_priv_1 + to, from, len);
 }
 
+/* Is this really the vpp port? */
 void l440gx_set_vpp(struct map_info *map, int vpp)
 {
 	unsigned long l;
 
 	l = inl(VPP_PORT);
-	l = vpp?(l | 1):(l & ~1);
+	if (vpp) {
+		l |= 1;
+	} else {
+		l &= ~1;
+	}
 	outl(l, VPP_PORT);
 }
 
@@ -87,44 +96,86 @@
 	write16: l440gx_write16,
 	write32: l440gx_write32,
 	copy_to: l440gx_copy_to,
+#if 0
+	/* FIXME verify that this is the 
+	 * appripriate code for vpp enable/disable
+	 */
 	set_vpp: l440gx_set_vpp
+#endif
 };
 
 static int __init init_l440gx(void)
 {
-	struct pci_dev *dev;
-	unsigned char b;
-	__u16 w;
+	struct pci_dev *dev, *pm_dev;
+	struct resource *pm_iobase;
+	__u16 word;
+
+	dev = pci_find_device(PCI_VENDOR_ID_INTEL, 
+		PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
 
-	dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
-			      NULL);
 
-	if (!dev) {
+	pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, 
+		PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
+
+	if (!dev || !pm_dev) {
 		printk(KERN_NOTICE "L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue\n");
 		return -ENODEV;
 	}
 
 
-	l440gx_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+	l440gx_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
 
 	if (!l440gx_map.map_priv_1) {
-		printk("Failed to ioremap L440GX flash region\n");
+		printk(KERN_WARNING "Failed to ioremap L440GX flash region\n");
 		return -ENOMEM;
 	}
 
+	printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.map_priv_1);
+
+	/* Setup the pm iobase resource 
+	 * This code should move into some kind of generic bridge
+	 * driver but for the moment I'm content with getting the
+	 * allocation correct. 
+	 */
+	pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE];
+	if (!(pm_iobase->flags & IORESOURCE_IO)) {
+		pm_iobase->name = "pm iobase";
+		pm_iobase->start = 0;
+		pm_iobase->end = 63;
+		pm_iobase->flags = IORESOURCE_IO;
+
+		/* Put the current value in the resource */
+		pci_read_config_dword(pm_dev, 0x40, &iobase);
+		iobase &= ~1;
+		pm_iobase->start += iobase & ~1;
+		pm_iobase->end += iobase & ~1;
+
+		/* Allocate the resource region */
+		if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) {
+			printk(KERN_WARNING "Could not allocate pm iobase resource\n");
+			iounmap((void *)l440gx_map.map_priv_1);
+			return -ENXIO;
+		}
+	}
+	/* Set the iobase */
+	iobase = pm_iobase->start;
+	pci_write_config_dword(pm_dev, 0x40, iobase | 1);
+	
+
 	/* Set XBCS# */
-	pci_read_config_word(dev, 0x4e, &w);
-	w |= 0x4;
-        pci_write_config_word(dev, 0x4e, w);
+	pci_read_config_word(dev, 0x4e, &word);
+	word |= 0x4;
+        pci_write_config_word(dev, 0x4e, word);
+
+	/* Supply write voltage to the chip */
+	l440gx_set_vpp(&l440gx_map, 1);
 
 	/* Enable the gate on the WE line */
-	b = inb(TRIBUF_PORT);
-	b |= 1;
-	outb(b, TRIBUF_PORT);
+	outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT);
 	
        	printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n");
 
-	mymtd = do_map_probe("jedec", &l440gx_map);
+	mymtd = do_map_probe("jedec_probe", &l440gx_map);
 	if (!mymtd) {
 		printk(KERN_NOTICE "JEDEC probe on BIOS chip failed. Using ROM\n");
 		mymtd = do_map_probe("map_rom", &l440gx_map);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/mbx860.c linux/drivers/mtd/maps/mbx860.c
--- linux.orig/drivers/mtd/maps/mbx860.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/mbx860.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,144 @@
+/*
+ * $Id: mbx860.c,v 1.1 2001/11/18 19:43:09 dwmw2 Exp $
+ *
+ * Handle mapping of the flash on MBX860 boards
+ *
+ * Author:	Anton Todorov
+ * Copyright:	(C) 2001 Emness Technology
+ * 
+ * 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/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+
+#define WINDOW_ADDR 0xfe000000
+#define WINDOW_SIZE 0x00200000
+
+/* Flash / Partition sizing */
+#define MAX_SIZE_KiB              8192
+#define BOOT_PARTITION_SIZE_KiB    512
+#define KERNEL_PARTITION_SIZE_KiB 5632
+#define APP_PARTITION_SIZE_KiB    2048
+
+#define NUM_PARTITIONS 3
+
+/* partition_info gives details on the logical partitions that the split the
+ * single flash device into. If the size if zero we use up to the end of the
+ * device. */
+static struct mtd_partition partition_info[]={
+	{ name: "MBX flash BOOT partition",
+	offset: 0,
+	size:   BOOT_PARTITION_SIZE_KiB*1024 },
+	{ name: "MBX flash DATA partition",
+	offset: BOOT_PARTITION_SIZE_KiB*1024,
+	size: (KERNEL_PARTITION_SIZE_KiB)*1024 },
+	{ name: "MBX flash APPLICATION partition",
+	offset: (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
+};
+				   
+
+static struct mtd_info *mymtd;
+
+__u8 mbx_read8(struct map_info *map, unsigned long ofs)
+{
+	return readb(map->map_priv_1 + ofs);
+}
+
+__u16 mbx_read16(struct map_info *map, unsigned long ofs)
+{
+	return readw(map->map_priv_1 + ofs);
+}
+
+__u32 mbx_read32(struct map_info *map, unsigned long ofs)
+{
+	return readl(map->map_priv_1 + ofs);
+}
+
+void mbx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
+}
+
+void mbx_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	writeb(d, map->map_priv_1 + adr);
+}
+
+void mbx_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	writew(d, map->map_priv_1 + adr);
+}
+
+void mbx_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	writel(d, map->map_priv_1 + adr);
+}
+
+void mbx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio((void *)(map->map_priv_1 + to), from, len);
+}
+
+struct map_info mbx_map = {
+	name: "MBX flash",
+	size: WINDOW_SIZE,
+	buswidth: 4,
+	read8: mbx_read8,
+	read16: mbx_read16,
+	read32: mbx_read32,
+	copy_from: mbx_copy_from,
+	write8: mbx_write8,
+	write16: mbx_write16,
+	write32: mbx_write32,
+	copy_to: mbx_copy_to
+};
+
+int __init init_mbx(void)
+{
+	printk(KERN_NOTICE "Motorola MBX flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
+	mbx_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
+
+	if (!mbx_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("jedec_probe", &mbx_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+		add_mtd_device(mymtd);
+                add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
+		return 0;
+	}
+
+	iounmap((void *)mbx_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_mbx(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (mbx_map.map_priv_1) {
+		iounmap((void *)mbx_map.map_priv_1);
+		mbx_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_mbx);
+module_exit(cleanup_mbx);
+
+MODULE_AUTHOR("Anton Todorov <a.todorov@emness.com>");
+MODULE_DESCRIPTION("MTD map driver for Motorola MBX860 board");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/pb1xxx-flash.c linux/drivers/mtd/maps/pb1xxx-flash.c
--- linux.orig/drivers/mtd/maps/pb1xxx-flash.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/pb1xxx-flash.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,253 @@
+/*
+ * Flash memory access on Alchemy Pb1xxx boards
+ * 
+ * (C) 2001 Pete Popov <ppopov@mvista.com>
+ * 
+ * $Id: pb1xxx-flash.c,v 1.2 2002/02/14 19:36:45 ppopov Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/au1000.h>
+
+#ifdef 	DEBUG_RW
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+#ifdef CONFIG_MIPS_PB1000
+#define WINDOW_ADDR 0x1F800000
+#define WINDOW_SIZE 0x800000
+#endif
+
+__u8 physmap_read8(struct map_info *map, unsigned long ofs)
+{
+	__u8 ret;
+	ret = __raw_readb(map->map_priv_1 + ofs);
+	DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
+	return ret;
+}
+
+__u16 physmap_read16(struct map_info *map, unsigned long ofs)
+{
+	__u16 ret;
+	ret = __raw_readw(map->map_priv_1 + ofs);
+	DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
+	return ret;
+}
+
+__u32 physmap_read32(struct map_info *map, unsigned long ofs)
+{
+	__u32 ret;
+	ret = __raw_readl(map->map_priv_1 + ofs);
+	DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
+	return ret;
+}
+
+void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to);
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from);
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+
+
+static struct map_info pb1xxx_map = {
+	name:		"Pb1xxx flash",
+	read8: physmap_read8,
+	read16: physmap_read16,
+	read32: physmap_read32,
+	copy_from: physmap_copy_from,
+	write8: physmap_write8,
+	write16: physmap_write16,
+	write32: physmap_write32,
+	copy_to: physmap_copy_to,
+};
+
+
+#ifdef CONFIG_MIPS_PB1000
+
+static unsigned long flash_size = 0x00800000;
+static unsigned char flash_buswidth = 4;
+static struct mtd_partition pb1xxx_partitions[] = {
+        {
+                name: "yamon env",
+                size: 0x00020000,
+                offset: 0,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "User FS",
+                size: 0x003e0000,
+                offset: 0x20000,
+        },{
+                name: "boot code",
+                size: 0x100000,
+                offset: 0x400000,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "raw/kernel",
+                size: 0x300000,
+                offset: 0x500000
+        }
+};
+
+#elif defined(CONFIG_MIPS_PB1500)
+
+static unsigned char flash_buswidth = 4;
+#if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
+/* both 32MB banks will be used. Combine the first 32MB bank and the
+ * first 28MB of the second bank together into a single jffs/jffs2
+ * partition.
+ */
+static unsigned long flash_size = 0x04000000;
+#define WINDOW_ADDR 0x1C000000
+#define WINDOW_SIZE 0x4000000
+static struct mtd_partition pb1xxx_partitions[] = {
+        {
+                name: "User FS",
+                size:   0x3c00000,
+                offset: 0x0000000
+        },{
+                name: "yamon",
+                size: 0x0100000,
+                offset: 0x3c00000,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "raw kernel",
+                size: 0x02c0000,
+                offset: 0x3d00000
+        }
+};
+#elif defined(CONFIG_MTD_PB1500_BOOT) && !defined(CONFIG_MTD_PB1500_USER)
+static unsigned long flash_size = 0x02000000;
+#define WINDOW_ADDR 0x1E000000
+#define WINDOW_SIZE 0x2000000
+static struct mtd_partition pb1xxx_partitions[] = {
+        {
+                name: "User FS",
+                size:   0x1c00000,
+                offset: 0x0000000
+        },{
+                name: "yamon",
+                size: 0x0100000,
+                offset: 0x1c00000,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "raw kernel",
+                size: 0x02c0000,
+                offset: 0x1d00000
+        }
+};
+#elif !defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
+static unsigned long flash_size = 0x02000000;
+#define WINDOW_ADDR 0x1C000000
+#define WINDOW_SIZE 0x2000000
+static struct mtd_partition pb1xxx_partitions[] = {
+        {
+                name: "User FS",
+                size:   0x1e00000,
+                offset: 0x0000000
+        },{
+                name: "raw kernel",
+                size: 0x0200000,
+                offset: 0x1e00000,
+        }
+};
+#else
+#error MTD_PB1500 define combo error /* should never happen */
+#endif
+#else
+#error Unsupported board
+#endif
+
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_partition *parsed_parts;
+static struct mtd_info *mymtd;
+
+int __init pb1xxx_mtd_init(void)
+{
+	struct mtd_partition *parts;
+	int nb_parts = 0;
+	char *part_type;
+	
+	/* Default flash buswidth */
+	pb1xxx_map.buswidth = flash_buswidth;
+
+	/*
+	 * Static partition definition selection
+	 */
+	part_type = "static";
+	parts = pb1xxx_partitions;
+	nb_parts = NB_OF(pb1xxx_partitions);
+	pb1xxx_map.size = flash_size;
+
+	/*
+	 * Now let's probe for the actual flash.  Do it here since
+	 * specific machine settings might have been set above.
+	 */
+	printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n", 
+			pb1xxx_map.buswidth*8);
+	pb1xxx_map.map_priv_1 = 
+		(unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+	mymtd = do_map_probe("cfi_probe", &pb1xxx_map);
+	if (!mymtd) return -ENXIO;
+	mymtd->module = THIS_MODULE;
+
+	add_mtd_partitions(mymtd, parts, nb_parts);
+	return 0;
+}
+
+static void __exit pb1xxx_mtd_cleanup(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+		if (parsed_parts)
+			kfree(parsed_parts);
+	}
+}
+
+module_init(pb1xxx_mtd_init);
+module_exit(pb1xxx_mtd_cleanup);
+
+MODULE_AUTHOR("Pete Popov");
+MODULE_DESCRIPTION("Pb1xxx CFI map driver");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/pci.c linux/drivers/mtd/maps/pci.c
--- linux.orig/drivers/mtd/maps/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/pci.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,385 @@
+/*
+ *  linux/drivers/mtd/maps/pci.c
+ *
+ *  Copyright (C) 2001 Russell King, 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  $Id: pci.c,v 1.1 2001/09/27 20:28:45 rmk Exp $
+ * 
+ * Generic PCI memory map driver.  We support the following boards:
+ *  - Intel IQ80310 ATU.
+ *  - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+struct map_pci_info;
+
+struct mtd_pci_info {
+	int  (*init)(struct pci_dev *dev, struct map_pci_info *map);
+	void (*exit)(struct pci_dev *dev, struct map_pci_info *map);
+	unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs);
+	const char *map_name;
+};
+
+struct map_pci_info {
+	struct map_info map;
+	void *base;
+	void (*exit)(struct pci_dev *dev, struct map_pci_info *map);
+	unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs);
+	struct pci_dev *dev;
+};	
+
+/*
+ * Intel IOP80310 Flash driver
+ */
+
+static int
+intel_iq80310_init(struct pci_dev *dev, struct map_pci_info *map)
+{
+	u32 win_base;
+
+	map->map.buswidth = 1;
+	map->map.size     = 0x00800000;
+	map->base         = ioremap_nocache(pci_resource_start(dev, 0),
+					    pci_resource_len(dev, 0));
+
+	if (!map->base)
+		return -ENOMEM;
+
+	/*
+	 * We want to base the memory window at Xscale
+	 * bus address 0, not 0x1000.
+	 */
+	pci_read_config_dword(dev, 0x44, &win_base);
+	pci_write_config_dword(dev, 0x44, 0);
+
+	map->map.map_priv_2 = win_base;
+
+	return 0;
+}
+
+static void
+intel_iq80310_exit(struct pci_dev *dev, struct map_pci_info *map)
+{
+	if (map->base)
+		iounmap((void *)map->base);
+	pci_write_config_dword(dev, 0x44, map->map.map_priv_2);
+}
+
+static unsigned long
+intel_iq80310_translate(struct map_pci_info *map, unsigned long ofs)
+{
+	unsigned long page_addr = ofs & 0x00400000;
+
+	/*
+	 * This mundges the flash location so we avoid
+	 * the first 80 bytes (they appear to read nonsense).
+	 */
+	if (page_addr) {
+		writel(0x00000008, map->base + 0x1558);
+		writel(0x00000000, map->base + 0x1550);
+	} else {
+		writel(0x00000007, map->base + 0x1558);
+		writel(0x00800000, map->base + 0x1550);
+		ofs += 0x00800000;
+	}
+
+	return ofs;
+}
+
+static struct mtd_pci_info intel_iq80310_info = {
+	init:		intel_iq80310_init,
+	exit:		intel_iq80310_exit,
+	translate:	intel_iq80310_translate,
+	map_name:	"cfi_probe",
+};
+
+/*
+ * Intel DC21285 driver
+ */
+
+static int
+intel_dc21285_init(struct pci_dev *dev, struct map_pci_info *map)
+{
+	unsigned long base, len;
+
+	base = pci_resource_start(dev, PCI_ROM_RESOURCE);
+	len  = pci_resource_len(dev, PCI_ROM_RESOURCE);
+
+	if (!len || !base) {
+		/*
+		 * No ROM resource
+		 */
+		base = pci_resource_start(dev, 2);
+		len  = pci_resource_len(dev, 2);
+
+		/*
+		 * We need to re-allocate PCI BAR2 address range to the
+		 * PCI ROM BAR, and disable PCI BAR2.
+		 */
+	} else {
+		/*
+		 * Hmm, if an address was allocated to the ROM resource, but
+		 * not enabled, should we be allocating a new resource for it
+		 * or simply enabling it?
+		 */
+		if (!(pci_resource_flags(dev, PCI_ROM_RESOURCE) &
+		     PCI_ROM_ADDRESS_ENABLE)) {
+		     	u32 val;
+			pci_resource_flags(dev, PCI_ROM_RESOURCE) |= PCI_ROM_ADDRESS_ENABLE;
+			pci_read_config_dword(dev, PCI_ROM_ADDRESS, &val);
+			val |= PCI_ROM_ADDRESS_ENABLE;
+			pci_write_config_dword(dev, PCI_ROM_ADDRESS, val);
+			printk("%s: enabling expansion ROM\n", dev->slot_name);
+		}
+	}
+
+	if (!len || !base)
+		return -ENXIO;
+
+	map->map.buswidth = 4;
+	map->map.size     = len;
+	map->base         = ioremap_nocache(base, len);
+
+	if (!map->base)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void
+intel_dc21285_exit(struct pci_dev *dev, struct map_pci_info *map)
+{
+	u32 val;
+
+	if (map->base)
+		iounmap((void *)map->base);
+
+	/*
+	 * We need to undo the PCI BAR2/PCI ROM BAR address alteration.
+	 */
+	pci_resource_flags(dev, PCI_ROM_RESOURCE) &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_read_config_dword(dev, PCI_ROM_ADDRESS, &val);
+	val &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, PCI_ROM_ADDRESS, val);
+}
+
+static unsigned long
+intel_dc21285_translate(struct map_pci_info *map, unsigned long ofs)
+{
+	return ofs & 0x00ffffc0 ? ofs : (ofs ^ (1 << 5));
+}
+
+static struct mtd_pci_info intel_dc21285_info = {
+	init:		intel_dc21285_init,
+	exit:		intel_dc21285_exit,
+	translate:	intel_dc21285_translate,
+	map_name:	"jedec_probe",
+};
+
+/*
+ * PCI device ID table
+ */
+
+static struct pci_device_id mtd_pci_ids[] __devinitdata = {
+	{
+		vendor:		PCI_VENDOR_ID_INTEL,
+		device:		0x530d,
+		subvendor:	PCI_ANY_ID,
+		subdevice:	PCI_ANY_ID,
+		class:		PCI_CLASS_MEMORY_OTHER << 8,
+		class_mask:	0xffff00,
+		driver_data:	(unsigned long)&intel_iq80310_info,
+	},
+	{
+		vendor:		PCI_VENDOR_ID_DEC,
+		device:		PCI_DEVICE_ID_DEC_21285,
+		subvendor:	0,	/* DC21285 defaults to 0 on reset */
+		subdevice:	0,	/* DC21285 defaults to 0 on reset */
+		class:		0,
+		class_mask:	0,
+		driver_data:	(unsigned long)&intel_dc21285_info,
+	},
+	{ 0, }
+};
+
+/*
+ * Generic code follows.
+ */
+
+static u8 mtd_pci_read8(struct map_info *_map, unsigned long ofs)
+{
+	struct map_pci_info *map = (struct map_pci_info *)_map;
+	u8 val = readb(map->base + map->translate(map, ofs));
+//	printk("read8 : %08lx => %02x\n", ofs, val);
+	return val;
+}
+
+static u16 mtd_pci_read16(struct map_info *_map, unsigned long ofs)
+{
+	struct map_pci_info *map = (struct map_pci_info *)_map;
+	u16 val = readw(map->base + map->translate(map, ofs));
+//	printk("read16: %08lx => %04x\n", ofs, val);
+	return val;
+}
+
+static u32 mtd_pci_read32(struct map_info *_map, unsigned long ofs)
+{
+	struct map_pci_info *map = (struct map_pci_info *)_map;
+	u32 val = readl(map->base + map->translate(map, ofs));
+//	printk("read32: %08lx => %08x\n", ofs, val);
+	return val;
+}
+
+static void mtd_pci_copyfrom(struct map_info *_map, void *to, unsigned long from, ssize_t len)
+{
+	struct map_pci_info *map = (struct map_pci_info *)_map;
+	memcpy_fromio(to, map->base + map->translate(map, from), len);
+}
+
+static void mtd_pci_write8(struct map_info *_map, u8 val, unsigned long ofs)
+{
+	struct map_pci_info *map = (struct map_pci_info *)_map;
+//	printk("write8 : %08lx <= %02x\n", ofs, val);
+	writeb(val, map->base + map->translate(map, ofs));
+}
+
+static void mtd_pci_write16(struct map_info *_map, u16 val, unsigned long ofs)
+{
+	struct map_pci_info *map = (struct map_pci_info *)_map;
+//	printk("write16: %08lx <= %04x\n", ofs, val);
+	writew(val, map->base + map->translate(map, ofs));
+}
+
+static void mtd_pci_write32(struct map_info *_map, u32 val, unsigned long ofs)
+{
+	struct map_pci_info *map = (struct map_pci_info *)_map;
+//	printk("write32: %08lx <= %08x\n", ofs, val);
+	writel(val, map->base + map->translate(map, ofs));
+}
+
+static void mtd_pci_copyto(struct map_info *_map, unsigned long to, const void *from, ssize_t len)
+{
+	struct map_pci_info *map = (struct map_pci_info *)_map;
+	memcpy_toio(map->base + map->translate(map, to), from, len);
+}
+
+static struct map_info mtd_pci_map = {
+	read8:		mtd_pci_read8,
+	read16:		mtd_pci_read16,
+	read32:		mtd_pci_read32,
+	copy_from:	mtd_pci_copyfrom,
+	write8:		mtd_pci_write8,
+	write16:	mtd_pci_write16,
+	write32:	mtd_pci_write32,
+	copy_to:	mtd_pci_copyto,
+};
+
+static int __devinit
+mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct mtd_pci_info *info = (struct mtd_pci_info *)id->driver_data;
+	struct map_pci_info *map = NULL;
+	struct mtd_info *mtd = NULL;
+	int err;
+
+	err = pci_enable_device(dev);
+	if (err)
+		goto out;
+
+	err = pci_request_regions(dev, "pci mtd");
+	if (err)
+		goto out;
+
+	map = kmalloc(sizeof(*map), GFP_KERNEL);
+	err = -ENOMEM;
+	if (!map)
+		goto release;
+
+	map->map       = mtd_pci_map;
+	map->map.name  = dev->slot_name;
+	map->dev       = dev;
+	map->exit      = info->exit;
+	map->translate = info->translate;
+
+	err = info->init(dev, map);
+	if (err)
+		goto release;
+
+	/* tsk - do_map_probe should take const char * */
+	mtd = do_map_probe((char *)info->map_name, &map->map);
+	err = -ENODEV;
+	if (!mtd)
+		goto release;
+
+	mtd->module = THIS_MODULE;
+	add_mtd_device(mtd);
+
+	pci_set_drvdata(dev, mtd);
+
+	return 0;
+
+release:
+	if (mtd)
+		map_destroy(mtd);
+
+	if (map) {
+		map->exit(dev, map);
+		kfree(map);
+	}
+
+	pci_release_regions(dev);
+out:
+	return err;
+}
+
+static void __devexit
+mtd_pci_remove(struct pci_dev *dev)
+{
+	struct mtd_info *mtd = pci_get_drvdata(dev);
+	struct map_pci_info *map = mtd->priv;
+
+	del_mtd_device(mtd);
+	map_destroy(mtd);
+	map->exit(dev, map);
+	kfree(map);
+
+	pci_set_drvdata(dev, NULL);
+	pci_release_regions(dev);
+}
+
+static struct pci_driver mtd_pci_driver = {
+	name:		"MTD PCI",
+	probe:		mtd_pci_probe,
+	remove:		__devexit_p(mtd_pci_remove),
+	id_table:	mtd_pci_ids,
+};
+
+static int __init mtd_pci_maps_init(void)
+{
+	return pci_module_init(&mtd_pci_driver);
+}
+
+static void __exit mtd_pci_maps_exit(void)
+{
+	pci_unregister_driver(&mtd_pci_driver);
+}
+
+module_init(mtd_pci_maps_init);
+module_exit(mtd_pci_maps_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("Generic PCI map driver");
+MODULE_DEVICE_TABLE(pci, mtd_pci_ids);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/sa1100-flash.c linux/drivers/mtd/maps/sa1100-flash.c
--- linux.orig/drivers/mtd/maps/sa1100-flash.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/maps/sa1100-flash.c	2002-07-20 01:08:29.000000000 +0000
@@ -3,12 +3,13 @@
  * 
  * (C) 2000 Nicolas Pitre <nico@cam.org>
  * 
- * $Id: sa1100-flash.c,v 1.22 2001/10/02 10:04:52 rmk Exp $
+ * $Id: sa1100-flash.c,v 1.26 2002/03/13 16:30:44 rmk Exp $
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/ioport.h>
 #include <linux/kernel.h>
 
 #include <linux/mtd/mtd.h>
@@ -66,32 +67,6 @@
 	memcpy((void *)(map->map_priv_1 + to), from, len);
 }
 
-
-#ifdef CONFIG_SA1100_H3600
-
-static void h3600_set_vpp(struct map_info *map, int vpp)
-{
-	if (vpp)
-		set_h3600_egpio(EGPIO_H3600_VPP_ON);
-	else
-		clr_h3600_egpio(EGPIO_H3600_VPP_ON);
-}
-
-#endif
-
-#ifdef CONFIG_SA1100_JORNADA720
-
-static void jornada720_set_vpp(int vpp)
-{
-  if (vpp)
-      PPSR |= 0x80;
-  else
-      PPSR &= ~0x80;
-  PPDR |= 0x80;
-}
-
-#endif
-
 static struct map_info sa1100_map = {
 	name:		"SA1100 flash",
 	read8:		sa1100_read8,
@@ -104,6 +79,7 @@
 	copy_to:	sa1100_copy_to,
 
 	map_priv_1:	WINDOW_ADDR,
+	map_priv_2:	-1,
 };
 
 
@@ -111,425 +87,687 @@
  * Here are partition information for all known SA1100-based devices.
  * See include/linux/mtd/partitions.h for definition of the mtd_partition
  * structure.
- * 
+ *
  * The *_max_flash_size is the maximum possible mapped flash size which
- * is not necessarily the actual flash size.  It must correspond to the 
- * value specified in the mapping definition defined by the
- * "struct map_desc *_io_desc" for the corresponding machine.
+ * is not necessarily the actual flash size.  It must be no more than
+ * the value specified in the "struct map_desc *_io_desc" mapping
+ * definition for the corresponding machine.
+ *
+ * Please keep these in alphabetical order, and formatted as per existing
+ * entries.  Thanks.
  */
 
-#ifdef CONFIG_SA1100_ASSABET
+#ifdef CONFIG_SA1100_ADSBITSY
+#define ADSBITSY_FLASH_SIZE		0x02000000
+static struct mtd_partition adsbitsy_partitions[] = {
+	{
+		name:		"bootROM",
+		size:		0x80000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"zImage",
+		size:		0x100000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"ramdisk.gz",
+		size:		0x300000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"User FS",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
+	}
+};
+#endif
 
+#ifdef CONFIG_SA1100_ASSABET
 /* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */
-static unsigned long assabet4_max_flash_size = 0x00400000;
+#define ASSABET4_FLASH_SIZE		0x00400000
 static struct mtd_partition assabet4_partitions[] = {
-        {
-                name: "bootloader",
-                size: 0x00020000,
-                offset: 0,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "bootloader params",
-                size: 0x00020000,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "jffs",
-                size: MTDPART_SIZ_FULL,
-                offset: MTDPART_OFS_APPEND
-        }
+	{
+		name:		"bootloader",
+		size:		0x00020000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"bootloader params",
+		size:		0x00020000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"jffs",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
+	}
 };
 
 /* Phase 5 Assabet has two 28F128J3A flash parts in bank 0: */
-static unsigned long assabet5_max_flash_size = 0x02000000;
+#define ASSABET5_FLASH_SIZE		0x02000000
 static struct mtd_partition assabet5_partitions[] = {
-        {
-                name: "bootloader",
-                size: 0x00040000,
-                offset: 0,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "bootloader params",
-                size: 0x00040000,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "jffs",
-                size: MTDPART_SIZ_FULL,
-                offset: MTDPART_OFS_APPEND
-        }
+	{
+		name:		"bootloader",
+		size:		0x00040000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"bootloader params",
+		size:		0x00040000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"jffs",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
+	}
 };
 
-#define assabet_max_flash_size assabet5_max_flash_size
-#define assabet_partitions     assabet5_partitions
-
+#define ASSABET_FLASH_SIZE	ASSABET5_FLASH_SIZE
+#define assabet_partitions	assabet5_partitions
 #endif
 
-#ifdef CONFIG_SA1100_FLEXANET
+#ifdef CONFIG_SA1100_BADGE4
 
-/* Flexanet has two 28F128J3A flash parts in bank 0: */
-static unsigned long flexanet_max_flash_size = 0x02000000;
-static struct mtd_partition flexanet_partitions[] = {
-        {
-                name: "bootloader",
-                size: 0x00040000,
-                offset: 0,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "bootloader params",
-                size: 0x00040000,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "kernel",
-                size: 0x000C0000,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "altkernel",
-                size: 0x000C0000,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "root",
-                size: 0x00400000,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "free1",
-                size: 0x00300000,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "free2",
-                size: 0x00300000,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        },{
-                name: "free3",
-                size: MTDPART_SIZ_FULL,
-                offset: MTDPART_OFS_APPEND,
-                mask_flags: MTD_WRITEABLE
-        }
+/*
+ * 1 x Intel 28F320C3BA100 Advanced+ Boot Block Flash (32 Mi bit)
+ *   Eight 4 KiW Parameter Bottom Blocks (64 KiB)
+ *   Sixty-three 32 KiW Main Blocks (4032 Ki b)
+ */
+#define BADGE4_FLASH_SIZE		0x00400000
+static struct mtd_partition badge4_partitions[] = {
+	{
+		name:		"BLOB boot loader",
+		offset:		0,
+		size:		0x0000A000
+	}, {
+		name:		"params",
+		offset:		MTDPART_OFS_APPEND,
+		size:		0x00006000
+	}, {
+		name:		"kernel",
+		offset:		MTDPART_OFS_APPEND,
+		size:		0x00100000
+	}, {
+		name:		"root",
+		offset:		MTDPART_OFS_APPEND,
+		size:		MTDPART_SIZ_FULL
+	}
 };
 
 #endif
 
-#ifdef CONFIG_SA1100_HUW_WEBPANEL
-static unsigned long huw_webpanel_max_flash_size = 0x01000000;
-static struct mtd_partition huw_webpanel_partitions[] = {
-	{ 
-	  name: "Loader",
-	  size: 0x00040000,
-	  offset: 0,
-	},{
-	  name: "Sector 1",
-	  size: 0x00040000,
-	  offset: MTDPART_OFS_APPEND,
-	},{
-	  size: MTDPART_SIZ_FULL,
-	  offset: MTDPART_OFS_APPEND,
+
+#ifdef CONFIG_SA1100_CERF
+#ifdef CONFIG_SA1100_CERF_FLASH_32MB
+#define CERF_FLASH_SIZE			0x02000000
+static struct mtd_partition cerf_partitions[] = {
+	{
+		name:		"firmware",
+		size:		0x00040000,
+		offset:		0,
+	}, {
+		name:		"params",
+		size:		0x00040000,
+		offset:		0x00040000,
+	}, {
+		name:		"kernel",
+		size:		0x00100000,
+		offset:		0x00080000,
+	}, {
+		name:		"rootdisk",
+		size:		0x01E80000,
+		offset:		0x00180000,
 	}
 };
-#endif /* CONFIG_SA1100_HUW_WEBPANEL */
-
-
-#ifdef CONFIG_SA1100_H3600
-
-static unsigned long h3600_max_flash_size = 0x02000000;
-static struct mtd_partition h3600_partitions[] = {
+#elif defined CONFIG_SA1100_CERF_FLASH_16MB
+#define CERF_FLASH_SIZE			0x01000000
+static struct mtd_partition cerf_partitions[] = {
 	{
-		name: "H3600 boot firmware",
-		size: 0x00040000,
-		offset: 0,
-		mask_flags: MTD_WRITEABLE  /* force read-only */
-	},{
-		name: "H3600 kernel",
-		size: 0x00080000,
-		offset: 0x40000
-	},{
-		name: "H3600 params",
-		size: 0x00040000,
-		offset: 0xC0000
-	},{
-#ifdef CONFIG_JFFS2_FS
-		name: "H3600 root jffs2",
-		offset: 0x00100000,
-		size: MTDPART_SIZ_FULL
+		name:		"firmware",
+		size:		0x00020000,
+		offset:		0,
+	}, {
+		name:		"params",
+		size:		0x00020000,
+		offset:		0x00020000,
+	}, {
+		name:		"kernel",
+		size:		0x00100000,
+		offset:		0x00040000,
+	}, {
+		name:		"rootdisk",
+		size:		0x00EC0000,
+		offset:		0x00140000,
+	}
+};
+#elif defined CONFIG_SA1100_CERF_FLASH_8MB
+#   error "Unwritten type definition"
 #else
-		name: "H3600 initrd",
-		size: 0x00100000,
-		offset: 0x00100000
-	},{
-		name: "H3600 root cramfs",
-		size: 0x00300000,
-		offset: 0x00200000
-	},{
-		name: "H3600 usr cramfs",
-		size: 0x00800000,
-		offset: 0x00500000
-	},{
-		name: "H3600 usr local",
-		offset: 0x00d00000,
-		size: MTDPART_SIZ_FULL
+#   error "Undefined memory orientation for CERF in sa1100-flash.c"
 #endif
+#endif
+
+#ifdef CONFIG_SA1100_CONSUS
+#define CONSUS_FLASH_SIZE		0x02000000
+static struct mtd_partition consus_partitions[] = {
+	{
+		name:		"Consus boot firmware",
+		offset:		0,
+		size:		0x00040000,
+		mask_flags:	MTD_WRITABLE, /* force read-only */
+	}, {
+		name:		"Consus kernel",
+		offset:		0x00040000,
+		size:		0x00100000,
+		mask_flags:	0,
+	}, {
+		name:		"Consus disk",
+		offset:		0x00140000,
+		/* The rest (up to 16M) for jffs.  We could put 0 and
+		   make it find the size automatically, but right now
+		   i have 32 megs.  jffs will use all 32 megs if given
+		   the chance, and this leads to horrible problems
+		   when you try to re-flash the image because blob
+		   won't erase the whole partition. */
+		size:		0x01000000 - 0x00140000,
+		mask_flags:	0,
+	}, {
+		/* this disk is a secondary disk, which can be used as
+		   needed, for simplicity, make it the size of the other
+		   consus partition, although realistically it could be
+		   the remainder of the disk (depending on the file
+		   system used) */
+		 name:		"Consus disk2",
+		 offset:	0x01000000,
+		 size:		0x01000000 - 0x00140000,
+		 mask_flags:	0,
 	}
 };
+#endif
 
+#ifdef CONFIG_SA1100_FLEXANET
+/* Flexanet has two 28F128J3A flash parts in bank 0: */
+#define FLEXANET_FLASH_SIZE		0x02000000
+static struct mtd_partition flexanet_partitions[] = {
+	{
+		name:		"bootloader",
+		size:		0x00040000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"bootloader params",
+		size:		0x00040000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"kernel",
+		size:		0x000C0000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"altkernel",
+		size:		0x000C0000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"root",
+		size:		0x00400000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"free1",
+		size:		0x00300000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"free2",
+		size:		0x00300000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}, {
+		name:		"free3",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,
+	}
+};
 #endif
+
 #ifdef CONFIG_SA1100_FREEBIRD
-static unsigned long freebird_max_flash_size = 0x02000000;
+#define FREEBIRD_FLASH_SIZE		0x02000000
 static struct mtd_partition freebird_partitions[] = {
 #if CONFIG_SA1100_FREEBIRD_NEW
-    {
-     name: "firmware",
-     size: 0x00040000,
-     offset: 0,
-     mask_flags: MTD_WRITEABLE  /* force read-only */
-    },{
-     name: "kernel",
-     size: 0x00080000,
-     offset: 0x40000
-    },{
-     name: "params",
-     size: 0x00040000,
-     offset: 0xC0000
-    },{
-     name: "initrd",
-     size: 0x00100000,
-     offset: 0x00100000
-    },{
-     name: "root cramfs",
-     size: 0x00300000,
-     offset: 0x00200000
-    },{
-     name: "usr cramfs",
-     size: 0x00C00000,
-     offset: 0x00500000
-    },{
-	 name: "local",
-	 offset: 0x01100000,
-	 size: MTDPART_SIZ_FULL 
+	{
+		name:		"firmware",
+		size:		0x00040000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"kernel",
+		size:		0x00080000,
+		offset:		0x00040000,
+	}, {
+		name:		"params",
+		size:		0x00040000,
+		offset:		0x000C0000,
+	}, {
+		name:		"initrd",
+		size:		0x00100000,
+		offset:		0x00100000,
+	}, {
+		name:		"root cramfs",
+		size:		0x00300000,
+		offset:		0x00200000,
+	}, {
+		name:		"usr cramfs",
+		size:		0x00C00000,
+		offset:		0x00500000,
+	}, {
+		name:		"local",
+		size:		MTDPART_SIZ_FULL,
+		offset:		0x01100000,
 	}
 #else
-	{ offset: 0,            		size: 0x00040000,   },
-	{ offset: MTDPART_OFS_APPEND,   size: 0x000c0000,   },
-	{ offset: MTDPART_OFS_APPEND,	size: 0x00400000,	},
-	{ offset: MTDPART_OFS_APPEND,   size: MTDPART_SIZ_FULL  }
+	{
+		size:		0x00040000,
+		offset:		0,
+	}, {
+		size:		0x000c0000,
+		offset:		MTDPART_OFS_APPEND,
+	}, {
+		size:		0x00400000,
+		offset:		MTDPART_OFS_APPEND,
+	}, {
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
+	}
 #endif
-	};
+};
 #endif
-																									
 
-#ifdef CONFIG_SA1100_CERF
-
-static unsigned long cerf_max_flash_size = 0x01000000;
-static struct mtd_partition cerf_partitions[] = {
-	{ offset: 0,			size: 0x00800000 	},
-	{ offset: MTDPART_OFS_APPEND,	size: 0x00800000 	}
+#ifdef CONFIG_SA1100_FRODO
+/* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */
+#define FRODO_FLASH_SIZE		0x02000000
+static struct mtd_partition frodo_partitions[] =
+{
+	{
+		name:		"bootloader",
+		size:		0x00040000,
+		offset:		0x00000000,
+		mask_flags:	MTD_WRITEABLE
+	}, {
+		name:		"bootloader params",
+		size:		0x00040000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE
+	}, {
+		name:		"kernel",
+		size:		0x00100000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE
+	}, {
+		name:		"ramdisk",
+		size:		0x00400000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE
+	}, {
+		name:		"file system",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND
+	}
 };
-
 #endif
 
 #ifdef CONFIG_SA1100_GRAPHICSCLIENT
-
-static unsigned long graphicsclient_max_flash_size = 0x01000000;
+#define GRAPHICSCLIENT_FLASH_SIZE	0x02000000
 static struct mtd_partition graphicsclient_partitions[] = {
-	{ 
-	 name: "zImage",
-	 offset: 0,
-	 size: 0x100000
-	},
-	{ 
-         name: "ramdisk.gz",
-         offset: MTDPART_OFS_APPEND,
-         size: 0x300000 		
-	},
-	{ 
-	  name: "User FS",
-          offset: MTDPART_OFS_APPEND,	
-          size: MTDPART_SIZ_FULL
+	{
+		name:		"zImage",
+		size:		0x100000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"ramdisk.gz",
+		size:		0x300000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"User FS",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
 	}
 };
-
 #endif
 
 #ifdef CONFIG_SA1100_GRAPHICSMASTER
-
-static unsigned long graphicsmaster_max_flash_size = 0x01000000;
+#define GRAPHICSMASTER_FLASH_SIZE	0x01000000
 static struct mtd_partition graphicsmaster_partitions[] = {
-	{ 
-	 name: "zImage",
-	 offset: 0,
-	 size: 0x100000
+	{
+		name:		"zImage",
+		size:		0x100000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
 	},
-	{ 
-         name: "ramdisk.gz",
-         offset: MTDPART_OFS_APPEND,
-         size: 0x300000 		
+	{
+		name:		"ramdisk.gz",
+		size:		0x300000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
 	},
-	{ 
-	  name: "User FS",
-          offset: MTDPART_OFS_APPEND,	
-          size: MTDPART_SIZ_FULL
+	{
+		name:		"User FS",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
 	}
 };
+#endif
 
+#ifdef CONFIG_SA1100_H3600
+#define H3600_FLASH_SIZE		0x02000000
+static struct mtd_partition h3600_partitions[] = {
+	{
+		name:		"H3600 boot firmware",
+		size:		0x00040000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"H3600 kernel",
+		size:		0x00080000,
+		offset:		0x00040000,
+	}, {
+		name:		"H3600 params",
+		size:		0x00040000,
+		offset:		0x000C0000,
+	}, {
+#ifdef CONFIG_JFFS2_FS
+		name:		"H3600 root jffs2",
+		size:		MTDPART_SIZ_FULL,
+		offset:		0x00100000,
+#else
+		name:		"H3600 initrd",
+		size:		0x00100000,
+		offset:		0x00100000,
+	}, {
+		name:		"H3600 root cramfs",
+		size:		0x00300000,
+		offset:		0x00200000,
+	}, {
+		name:		"H3600 usr cramfs",
+		size:		0x00800000,
+		offset:		0x00500000,
+	}, {
+		name:		"H3600 usr local",
+		size:		MTDPART_SIZ_FULL,
+		offset:		0x00d00000,
 #endif
+	}
+};
 
-#ifdef CONFIG_SA1100_PANGOLIN
+static void h3600_set_vpp(struct map_info *map, int vpp)
+{
+	assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp);
+}
+#endif
 
-static unsigned long pangolin_max_flash_size = 0x04000000;
-static struct mtd_partition pangolin_partitions[] = {
-	{
-	  name: "boot firmware",
-	  offset: 0x00000000,
-	  size: 0x00080000,
-	  mask_flags: MTD_WRITEABLE,  /* force read-only */
-	},
-	{
-	  name: "kernel",
-	  offset: 0x00080000,
-	  size: 0x00100000,
-	},
+#ifdef CONFIG_SA1100_HUW_WEBPANEL
+#define HUW_WEBPANEL_FLASH_SIZE		0x01000000
+static struct mtd_partition huw_webpanel_partitions[] = {
 	{
-	  name: "initrd",
-	  offset: 0x00180000,
-	  size: 0x00280000,
-	},
+		name:		"Loader",
+		size:		0x00040000,
+		offset:		0,
+	}, {
+		name:		"Sector 1",
+		size:		0x00040000,
+		offset:		MTDPART_OFS_APPEND,
+	}, {
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
+	}
+};
+#endif
+
+#ifdef CONFIG_SA1100_JORNADA720
+#define JORNADA720_FLASH_SIZE		0x02000000
+static struct mtd_partition jornada720_partitions[] = {
 	{
-	  name: "initrd-test",
-	  offset: 0x00400000,
-	  size: 0x03C00000,
+		name:		"JORNADA720 boot firmware",
+		size:		0x00040000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"JORNADA720 kernel",
+		size:		0x000c0000,
+		offset:		0x00040000,
+	}, {
+		name:		"JORNADA720 params",
+		size:		0x00040000,
+		offset:		0x00100000,
+	}, {
+		name:		"JORNADA720 initrd",
+		size:		0x00100000,
+		offset:		0x00140000,
+	}, {
+		name:		"JORNADA720 root cramfs",
+		size:		0x00300000,
+		offset:		0x00240000,
+	}, {
+		name:		"JORNADA720 usr cramfs",
+		size:		0x00800000,
+		offset:		0x00540000,
+	}, {
+		name:		"JORNADA720 usr local",
+		size:		0  /* will expand to the end of the flash */
+		offset:		0x00d00000,
 	}
 };
 
+static void jornada720_set_vpp(int vpp)
+{
+	if (vpp)
+		PPSR |= 0x80;
+	else
+		PPSR &= ~0x80;
+	PPDR |= 0x80;
+}
+
 #endif
 
-#ifdef CONFIG_SA1100_YOPY
+#ifdef CONFIG_SA1100_PANGOLIN
+#define PANGOLIN_FLASH_SIZE		0x04000000
+static struct mtd_partition pangolin_partitions[] = {
+	{
+		name:		"boot firmware",
+		size:		0x00080000,
+		offset:		0x00000000,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"kernel",
+		size:		0x00100000,
+		offset:		0x00080000,
+	}, {
+		name:		"initrd",
+		size:		0x00280000,
+		offset:		0x00180000,
+	}, {
+		name:		"initrd-test",
+		size:		0x03C00000,
+		offset:		0x00400000,
+	}
+};
+#endif
 
-static unsigned long yopy_max_flash_size = 0x08000000;
-static struct mtd_partition yopy_partitions[] = {
+#ifdef CONFIG_SA1100_PT_SYSTEM3
+/* erase size is 0x40000 == 256k partitions have to have this boundary */
+#define SYSTEM3_FLASH_SIZE		0x01000000
+static struct mtd_partition system3_partitions[] = {
 	{
-		name: "boot firmware",
-		offset: 0x00000000,
-		size: 0x00040000,
-		mask_flags: MTD_WRITEABLE,  /* force read-only */
+		name:		"BLOB",
+		size:		0x00040000,
+		offset:		0x00000000,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"config",
+		size:		0x00040000,
+		offset:		MTDPART_OFS_APPEND,
+	}, {
+		name:		"kernel",
+		size:		0x00100000,
+		offset:		MTDPART_OFS_APPEND,
+	}, {
+		name:		"root",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
+	}
+};
+#endif
+
+#ifdef CONFIG_SA1100_SHANNON
+#define SHANNON_FLASH_SIZE		0x00400000
+static struct mtd_partition shannon_partitions[] = {
+	{
+		name: "BLOB boot loader",
+		offset: 0,
+		size: 0x20000
 	},
 	{
 		name: "kernel",
-		offset: 0x00080000,
-		size: 0x00080000,
+		offset: MTDPART_OFS_APPEND,
+		size: 0xe0000
 	},
-	{
+	{ 
 		name: "initrd",
-		offset: 0x00100000,
-		size: 0x00300000,
-	},
-	{
-		name: "root",
-		offset: 0x00400000,
-		size: 0x01000000,
-	},
+		offset: MTDPART_OFS_APPEND,	
+		size: MTDPART_SIZ_FULL
+	}
 };
 
 #endif
 
-#ifdef CONFIG_SA1100_JORNADA720
-
-static unsigned long jornada720_max_flash_size = 0x02000000;
-static struct mtd_partition jornada720_partitions[] = {
+#ifdef CONFIG_SA1100_SHERMAN
+#define SHERMAN_FLASH_SIZE		0x02000000
+static struct mtd_partition sherman_partitions[] = {
 	{
-		name: "JORNADA720 boot firmware",
-		size: 0x00040000,
-		offset: 0,
-		mask_flags: MTD_WRITEABLE  /* force read-only */
-	},{
-		name: "JORNADA720 kernel",
-		size: 0x000c0000,
-		offset: 0x40000
-	},{
-		name: "JORNADA720 params",
-		size: 0x00040000,
-		offset: 0x100000
-	},{
-		name: "JORNADA720 initrd",
-		size: 0x00100000,
-		offset: 0x00140000
-	},{
-		name: "JORNADA720 root cramfs",
-		size: 0x00300000,
-		offset: 0x00240000
-	},{
-		name: "JORNADA720 usr cramfs",
-		size: 0x00800000,
-		offset: 0x00540000
-	},{
-		name: "JORNADA720 usr local",
-		offset: 0x00d00000,
-		size: 0  /* will expand to the end of the flash */
+		size:		0x50000,
+		offset:		0,
+	}, {
+		size:		0x70000,
+		offset:		MTDPART_OFS_APPEND,
+	}, {
+		size:		0x600000,
+		offset:		MTDPART_OFS_APPEND,
+	}, {
+		size:		0xA0000,
+		offset:		MTDPART_OFS_APPEND,
 	}
 };
 #endif
 
-#ifdef CONFIG_SA1100_SHERMAN
-
-static unsigned long sherman_max_flash_size = 0x02000000;
-static struct mtd_partition sherman_partitions[] = {
-	{ offset: 0,			size: 0x50000 	},
-	{ offset: MTDPART_OFS_APPEND,	size: 0x70000 	},
-	{ offset: MTDPART_OFS_APPEND,	size: 0x600000 	},
-	{ offset: MTDPART_OFS_APPEND,	size: 0xA0000 	}
-};
-
+#ifdef CONFIG_SA1100_SIMPAD
+#define SIMPAD_FLASH_SIZE		0x02000000
+static struct mtd_partition simpad_partitions[] = {
+	{
+		name:		"SIMpad boot firmware",
+		size:		0x00080000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"SIMpad kernel",
+		size:		0x00100000,
+		offset:		0x00080000,
+	}, {
+#ifdef CONFIG_JFFS2_FS
+		name:		"SIMpad root jffs2",
+		size:		MTDPART_SIZ_FULL,
+		offset:		0x00180000,
+#else
+		name:		"SIMpad initrd",
+		size:		0x00300000,
+		offset:		0x00180000,
+	}, {
+		name:		"SIMpad root cramfs",
+		size:		0x00300000,
+		offset:		0x00480000,
+	}, {
+		name:		"SIMpad usr cramfs",
+		size:		0x005c0000,
+		offset:		0x00780000,
+	}, {
+		name:		"SIMpad usr local",
+		size:		MTDPART_SIZ_FULL,
+		offset:		0x00d40000,
 #endif
+	}
+};
+#endif /* CONFIG_SA1100_SIMPAD */
 
 #ifdef CONFIG_SA1100_STORK
-
-static unsigned long stork_max_flash_size = 0x02000000;
+#define STORK_FLASH_SIZE		0x02000000
 static struct mtd_partition stork_partitions[] = {
 	{
-		name: "STORK boot firmware",
-		size: 0x00040000,
-		offset: 0,
-		mask_flags: MTD_WRITEABLE  /* force read-only */
-	},{
-		name: "STORK params",
-		size: 0x00040000,
-		offset: 0x40000
-	},{
-		name: "STORK kernel",
-		size: 0x00100000,
-		offset: 0x80000
-	},{
+		name:		"STORK boot firmware",
+		size:		0x00040000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"STORK params",
+		size:		0x00040000,
+		offset:		0x00040000,
+	}, {
+		name:		"STORK kernel",
+		size:		0x00100000,
+		offset:		0x00080000,
+	}, {
 #ifdef CONFIG_JFFS2_FS
-		name: "STORK root jffs2",
-		offset: 0x00180000,
-		size: MTDPART_SIZ_FULL
+		name:		"STORK root jffs2",
+		offset:		0x00180000,
+		size:		MTDPART_SIZ_FULL,
 #else
-		name: "STORK initrd",
-		size: 0x00100000,
-		offset: 0x00180000
-	},{
-		name: "STORK root cramfs",
-		size: 0x00300000,
-		offset: 0x00280000
-	},{
-		name: "STORK usr cramfs",
-		size: 0x00800000,
-		offset: 0x00580000
-	},{
-		name: "STORK usr local",
-		offset: 0x00d80000,
-		size: MTDPART_SIZ_FULL
+		name:		"STORK initrd",
+		size:		0x00100000,
+		offset:		0x00180000,
+	}, {
+		name:		"STORK root cramfs",
+		size:		0x00300000,
+		offset:		0x00280000,
+	}, {
+		name:		"STORK usr cramfs",
+		size:		0x00800000,
+		offset:		0x00580000,
+	}, {
+		name:		"STORK usr local",
+		offset:		0x00d80000,
+		size:		MTDPART_SIZ_FULL,
 #endif
 	}
 };
-
 #endif
 
-#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
-
+#ifdef CONFIG_SA1100_YOPY
+#define YOPY_FLASH_SIZE			0x08000000
+static struct mtd_partition yopy_partitions[] = {
+	{
+		name:		"boot firmware",
+		size:		0x00040000,
+		offset:		0x00000000,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"kernel",
+		size:		0x00080000,
+		offset:		0x00080000,
+	}, {
+		name:		"initrd",
+		size:		0x00300000,
+		offset:		0x00100000,
+	}, {
+		name:		"root",
+		size:		0x01000000,
+		offset:		0x00400000,
+	}
+};
+#endif
 
 extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
 extern int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts);
@@ -540,10 +778,11 @@
 int __init sa1100_mtd_init(void)
 {
 	struct mtd_partition *parts;
-	int nb_parts = 0;
+	int nb_parts = 0, ret;
 	int parsed_nr_parts = 0;
-	char *part_type;
-	
+	const char *part_type;
+	unsigned long base = -1UL;
+
 	/* Default flash buswidth */
 	sa1100_map.buswidth = (MSC0 & MSC_RBW) ? 2 : 4;
 
@@ -551,103 +790,166 @@
 	 * Static partition definition selection
 	 */
 	part_type = "static";
+
+#ifdef CONFIG_SA1100_ADSBITSY
+	if (machine_is_adsbitsy()) {
+		parts = adsbitsy_partitions;
+		nb_parts = ARRAY_SIZE(adsbitsy_partitions);
+		sa1100_map.size = ADSBITSY_FLASH_SIZE;
+		sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4;
+	}
+#endif
 #ifdef CONFIG_SA1100_ASSABET
 	if (machine_is_assabet()) {
 		parts = assabet_partitions;
-		nb_parts = NB_OF(assabet_partitions);
-		sa1100_map.size = assabet_max_flash_size;
+		nb_parts = ARRAY_SIZE(assabet_partitions);
+		sa1100_map.size = ASSABET_FLASH_SIZE;
 	}
 #endif
-
-#ifdef CONFIG_SA1100_HUW_WEBPANEL
-	if (machine_is_huw_webpanel()) {
-		parts = huw_webpanel_partitions;
-		nb_parts = NB_OF(huw_webpanel_partitions);
-		sa1100_map.size = huw_webpanel_max_flash_size;
+#ifdef CONFIG_SA1100_BADGE4
+	if (machine_is_badge4()) {
+		parts = badge4_partitions;
+		nb_parts = ARRAY_SIZE(badge4_partitions);
+		sa1100_map.size = BADGE4_FLASH_SIZE;
 	}
 #endif
-
-#ifdef CONFIG_SA1100_H3600
-	if (machine_is_h3600()) {
-		parts = h3600_partitions;
-		nb_parts = NB_OF(h3600_partitions);
-		sa1100_map.size = h3600_max_flash_size;
-		sa1100_map.set_vpp = h3600_set_vpp;
+#ifdef CONFIG_SA1100_CERF
+	if (machine_is_cerf()) {
+		parts = cerf_partitions;
+		nb_parts = ARRAY_SIZE(cerf_partitions);
+		sa1100_map.size = CERF_FLASH_SIZE;
+	}
+#endif
+#ifdef CONFIG_SA1100_CONSUS
+	if (machine_is_consus()) {
+		parts = consus_partitions;
+		nb_parts = ARRAY_SIZE(consus_partitions);
+		sa1100_map.size = CONSUS_FLASH_SIZE;
+	}
+#endif
+#ifdef CONFIG_SA1100_FLEXANET
+	if (machine_is_flexanet()) {
+		parts = flexanet_partitions;
+		nb_parts = ARRAY_SIZE(flexanet_partitions);
+		sa1100_map.size = FLEXANET_FLASH_SIZE;
 	}
 #endif
 #ifdef CONFIG_SA1100_FREEBIRD
 	if (machine_is_freebird()) {
 		parts = freebird_partitions;
-		nb_parts = NB_OF(freebird_partitions);
-		sa1100_map.size = freebird_max_flash_size;
+		nb_parts = ARRAY_SIZE(freebird_partitions);
+		sa1100_map.size = FREEBIRD_FLASH_SIZE;
 	}
 #endif
-#ifdef CONFIG_SA1100_CERF
-	if (machine_is_cerf()) {
-		parts = cerf_partitions;
-		nb_parts = NB_OF(cerf_partitions);
-		sa1100_map.size = cerf_max_flash_size;
+#ifdef CONFIG_SA1100_FRODO
+	if (machine_is_frodo()) {
+		parts = frodo_partitions;
+		nb_parts = ARRAY_SIZE(frodo_partitions);
+		sa1100_map.size = FRODO_FLASH_SIZE;
+		base = 0x00000000;
 	}
-#endif
 #ifdef CONFIG_SA1100_GRAPHICSCLIENT
 	if (machine_is_graphicsclient()) {
 		parts = graphicsclient_partitions;
-		nb_parts = NB_OF(graphicsclient_partitions);
-		sa1100_map.size = graphicsclient_max_flash_size;
+		nb_parts = ARRAY_SIZE(graphicsclient_partitions);
+		sa1100_map.size = GRAPHICSCLIENT_FLASH_SIZE;
 		sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
 	}
 #endif
 #ifdef CONFIG_SA1100_GRAPHICSMASTER
 	if (machine_is_graphicsmaster()) {
 		parts = graphicsmaster_partitions;
-		nb_parts = NB_OF(graphicsmaster_partitions);
-		sa1100_map.size = graphicsmaster_max_flash_size;
+		nb_parts = ARRAY_SIZE(graphicsmaster_partitions);
+		sa1100_map.size = GRAPHICSMASTER_FLASH_SIZE;
 		sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
 	}
 #endif
-#ifdef CONFIG_SA1100_PANGOLIN
-	if (machine_is_pangolin()) {
-		parts = pangolin_partitions;
-		nb_parts = NB_OF(pangolin_partitions);
-		sa1100_map.size = pangolin_max_flash_size;
+#ifdef CONFIG_SA1100_H3600
+	if (machine_is_h3600()) {
+		parts = h3600_partitions;
+		nb_parts = ARRAY_SIZE(h3600_partitions);
+		sa1100_map.size = H3600_FLASH_SIZE;
+		sa1100_map.set_vpp = h3600_set_vpp;
+	}
+#endif
+#ifdef CONFIG_SA1100_HUW_WEBPANEL
+	if (machine_is_huw_webpanel()) {
+		parts = huw_webpanel_partitions;
+		nb_parts = ARRAY_SIZE(huw_webpanel_partitions);
+		sa1100_map.size = HUW_WEBPANEL_FLASH_SIZE;
 	}
 #endif
 #ifdef CONFIG_SA1100_JORNADA720
 	if (machine_is_jornada720()) {
 		parts = jornada720_partitions;
-		nb_parts = NB_OF(jornada720_partitions);
-		sa1100_map.size = jornada720_max_flash_size;
+		nb_parts = ARRAY_SIZE(jornada720_partitions);
+		sa1100_map.size = JORNADA720_FLASH_SIZE;
 		sa1100_map.set_vpp = jornada720_set_vpp;
 	}
 #endif
-#ifdef CONFIG_SA1100_YOPY
-	if (machine_is_yopy()) {
-		parts = yopy_partitions;
-		nb_parts = NB_OF(yopy_partitions);
-		sa1100_map.size = yopy_max_flash_size;
+#ifdef CONFIG_SA1100_PANGOLIN
+	if (machine_is_pangolin()) {
+		parts = pangolin_partitions;
+		nb_parts = ARRAY_SIZE(pangolin_partitions);
+		sa1100_map.size = PANGOLIN_FLASH_SIZE;
+	}
+#endif
+#ifdef CONFIG_SA1100_PT_SYSTEM3
+	if (machine_is_pt_system3()) {
+		parts = system3_partitions;
+		nb_parts = ARRAY_SIZE(system3_partitions);
+		sa1100_map.size = SYSTEM3_FLASH_SIZE;
+	}
+#endif
+#ifdef CONFIG_SA1100_SHANNON
+	if (machine_is_shannon()) {
+		parts = shannon_partitions;
+		nb_parts = ARRAY_SIZE(shannon_partitions);
+		sa1100_map.size = SHANNON_FLASH_SIZE;
 	}
 #endif
 #ifdef CONFIG_SA1100_SHERMAN
 	if (machine_is_sherman()) {
 		parts = sherman_partitions;
-		nb_parts = NB_OF(sherman_partitions);
-		sa1100_map.size = sherman_max_flash_size;
+		nb_parts = ARRAY_SIZE(sherman_partitions);
+		sa1100_map.size = SHERMAN_FLASH_SIZE;
 	}
 #endif
-#ifdef CONFIG_SA1100_FLEXANET
-	if (machine_is_flexanet()) {
-		parts = flexanet_partitions;
-		nb_parts = NB_OF(flexanet_partitions);
-		sa1100_map.size = flexanet_max_flash_size;
+#ifdef CONFIG_SA1100_SIMPAD
+	if (machine_is_simpad()) {
+		parts = simpad_partitions;
+		nb_parts = ARRAY_SIZE(simpad_partitions);
+		sa1100_map.size = SIMPAD_FLASH_SIZE;
 	}
 #endif
 #ifdef CONFIG_SA1100_STORK
 	if (machine_is_stork()) {
 		parts = stork_partitions;
-		nb_parts = NB_OF(stork_partitions);
-		sa1100_map.size = stork_max_flash_size;
+		nb_parts = ARRAY_SIZE(stork_partitions);
+		sa1100_map.size = STORK_FLASH_SIZE;
 	}
 #endif
+#ifdef CONFIG_SA1100_YOPY
+	if (machine_is_yopy()) {
+		parts = yopy_partitions;
+		nb_parts = ARRAY_SIZE(yopy_partitions);
+		sa1100_map.size = YOPY_FLASH_SIZE;
+	}
+#endif
+
+	/*
+	 * For simple flash devices, use ioremap to map the flash.
+	 */
+	if (base != (unsigned long)-1) {
+		if (!request_mem_region(base, sa1100_map.size, "flash"))
+			return -EBUSY;
+		sa1100_map.map_priv_2 = base;
+		sa1100_map.map_priv_1 = (unsigned long)
+				ioremap(base, sa1100_map.size);
+		ret = -ENOMEM;
+		if (!sa1100_map.map_priv_1)
+			goto out_err;
+	}
 
 	/*
 	 * Now let's probe for the actual flash.  Do it here since
@@ -655,8 +957,9 @@
 	 */
 	printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8);
 	mymtd = do_map_probe("cfi_probe", &sa1100_map);
+	ret = -ENXIO;
 	if (!mymtd)
-		return -ENXIO;
+		goto out_err;
 	mymtd->module = THIS_MODULE;
 
 	/*
@@ -665,7 +968,7 @@
 #ifdef CONFIG_MTD_REDBOOT_PARTS
 	if (parsed_nr_parts == 0) {
 		int ret = parse_redboot_partitions(mymtd, &parsed_parts);
-		
+
 		if (ret > 0) {
 			part_type = "RedBoot";
 			parsed_nr_parts = ret;
@@ -695,6 +998,13 @@
 		add_mtd_partitions(mymtd, parts, nb_parts);
 	}
 	return 0;
+
+ out_err:
+	if (sa1100_map.map_priv_2 != -1) {
+		iounmap((void *)sa1100_map.map_priv_1);
+		release_mem_region(sa1100_map.map_priv_2, sa1100_map.size);
+	}
+	return ret;
 }
 
 static void __exit sa1100_mtd_cleanup(void)
@@ -705,6 +1015,10 @@
 		if (parsed_parts)
 			kfree(parsed_parts);
 	}
+	if (sa1100_map.map_priv_2 != -1) {
+		iounmap((void *)sa1100_map.map_priv_1);
+		release_mem_region(sa1100_map.map_priv_2, sa1100_map.size);
+	}
 }
 
 module_init(sa1100_mtd_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/sbc_gxx.c linux/drivers/mtd/maps/sbc_gxx.c
--- linux.orig/drivers/mtd/maps/sbc_gxx.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/mtd/maps/sbc_gxx.c	2002-07-20 01:08:38.000000000 +0000
@@ -17,7 +17,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
-   $Id: sbc_gxx.c,v 1.19 2001/10/02 15:05:14 dwmw2 Exp $
+   $Id: sbc_gxx.c,v 1.20 2002/02/13 15:30:20 dwmw2 Exp $
 
 The SBC-MediaGX / SBC-GXx has up to 16 MiB of 
 Intel StrataFlash (28F320/28F640) in x8 mode.  
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/sc520cdp.c linux/drivers/mtd/maps/sc520cdp.c
--- linux.orig/drivers/mtd/maps/sc520cdp.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/maps/sc520cdp.c	2002-07-20 01:08:33.000000000 +0000
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  *
- * $Id: sc520cdp.c,v 1.9 2001/10/02 15:05:14 dwmw2 Exp $
+ * $Id: sc520cdp.c,v 1.11 2002/03/08 16:34:35 rkaiser Exp $
  *
  *
  * The SC520CDP is an evaluation board for the Elan SC520 processor available
@@ -25,13 +25,14 @@
  * For details see http://www.amd.com/products/epd/desiging/evalboards/18.elansc520/520_cdp_brief/index.html
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
-
+#include <linux/mtd/concat.h>
 
 /*
 ** The Embedded Systems BIOS decodes the first FLASH starting at
@@ -171,6 +172,7 @@
 #define NUM_FLASH_BANKS	(sizeof(sc520cdp_map)/sizeof(struct map_info))
 
 static struct mtd_info *mymtd[NUM_FLASH_BANKS];
+static struct mtd_info *merged_mtd;
 
 #ifdef REPROGRAM_PAR
 
@@ -307,19 +309,26 @@
 		}
 		mymtd[i] = do_map_probe("cfi_probe", &sc520cdp_map[i]);
 		if(!mymtd[i])
-			mymtd[i] = do_map_probe("jedec", &sc520cdp_map[i]);
+			mymtd[i] = do_map_probe("jedec_probe", &sc520cdp_map[i]);
 		if(!mymtd[i])
 			mymtd[i] = do_map_probe("map_rom", &sc520cdp_map[i]);
 
 		if (mymtd[i]) {
 			mymtd[i]->module = THIS_MODULE;
-			add_mtd_device(mymtd[i]);
 			++devices_found;
 		}
 		else {
 			iounmap((void *)sc520cdp_map[i].map_priv_1);
 		}
 	}
+	if(devices_found >= 2) {
+		/* Combine the two flash banks into a single MTD device & register it: */
+		merged_mtd = mtd_concat_create(mymtd, 2, "SC520CDP Flash Banks #0 and #1");
+		if(merged_mtd)
+			add_mtd_device(merged_mtd);
+	}
+	if(devices_found == 3) /* register the third (DIL-Flash) device */
+		add_mtd_device(mymtd[2]);
 	return(devices_found ? 0 : -ENXIO);
 }
 
@@ -327,11 +336,16 @@
 {
 	int i;
 	
+	if (merged_mtd) {
+		del_mtd_device(merged_mtd);
+		mtd_concat_destroy(merged_mtd);
+	}
+	if (mymtd[2])
+		del_mtd_device(mymtd[2]);
+
 	for (i = 0; i < NUM_FLASH_BANKS; i++) {
-		if (mymtd[i]) {
-			del_mtd_device(mymtd[i]);
+		if (mymtd[i])
 			map_destroy(mymtd[i]);
-		}
 		if (sc520cdp_map[i].map_priv_1) {
 			iounmap((void *)sc520cdp_map[i].map_priv_1);
 			sc520cdp_map[i].map_priv_1 = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/solutionengine.c linux/drivers/mtd/maps/solutionengine.c
--- linux.orig/drivers/mtd/maps/solutionengine.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/maps/solutionengine.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: solutionengine.c,v 1.3 2001/10/02 15:05:14 dwmw2 Exp $
+ * $Id: solutionengine.c,v 1.4 2001/11/07 01:20:59 jsiegel Exp $
  *
  * Flash and EPROM on Hitachi Solution Engine and similar boards.
  *
@@ -15,6 +15,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
+#include <linux/config.h>
 
 
 extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
@@ -57,20 +58,38 @@
 	write32: soleng_write32,
 };
 
+#ifdef CONFIG_MTD_SUPERH_RESERVE
+static struct mtd_partition superh_se_partitions[] = {
+	/* Reserved for boot code, read-only */
+	{
+		name: "flash_boot",
+		offset: 0x00000000,
+		size: CONFIG_MTD_SUPERH_RESERVE,
+		mask_flags: MTD_WRITEABLE,
+	},
+	/* All else is writable (e.g. JFFS) */
+	{
+		name: "Flash FS",
+		offset: MTDPART_OFS_NXTBLK,
+		size: MTDPART_SIZ_FULL,
+	}
+};
+#endif /* CONFIG_MTD_SUPERH_RESERVE */
+
 static int __init init_soleng_maps(void)
 {
-	int nr_parts;
+	int nr_parts = 0;
 
 	/* First probe at offset 0 */
 	soleng_flash_map.map_priv_1 = P2SEGADDR(0);
-	soleng_eprom_map.map_priv_1 = P1SEGADDR(0x400000);
+	soleng_eprom_map.map_priv_1 = P1SEGADDR(0x01000000);
 
-	printk(KERN_NOTICE "Probing for flash chips at 0x000000:\n");
+	printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
 	flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
 	if (!flash_mtd) {
 		/* Not there. Try swapping */
-		printk(KERN_NOTICE "Probing for flash chips at 0x400000:\n");
-		soleng_flash_map.map_priv_1 = P2SEGADDR(0x400000);
+		printk(KERN_NOTICE "Probing for flash chips at 0x01000000:\n");
+		soleng_flash_map.map_priv_1 = P2SEGADDR(0x01000000);
 		soleng_eprom_map.map_priv_1 = P1SEGADDR(0);
 		flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
 		if (!flash_mtd) {
@@ -90,9 +109,23 @@
 		add_mtd_device(eprom_mtd);
 	}
 
+#ifdef CONFIG_MTD_REDBOOT_PARTS
 	nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
+	if (nr_parts > 0)
+		printk(KERN_NOTICE "Found RedBoot partition table.\n");
+	else if (nr_parts < 0)
+		printk(KERN_NOTICE "Error looking for RedBoot partitions.\n");
+#endif /* CONFIG_MTD_REDBOOT_PARTS */
+#if CONFIG_MTD_SUPERH_RESERVE
+	if (nr_parts == 0) {
+		printk(KERN_NOTICE "Using configured partition at 0x%08x.\n",
+		       CONFIG_MTD_SUPERH_RESERVE);
+		parsed_parts = superh_se_partitions;
+		nr_parts = sizeof(superh_se_partitions)/sizeof(*parsed_parts);
+	}
+#endif /* CONFIG_MTD_SUPERH_RESERVE */
 
-	if (nr_parts)
+	if (nr_parts > 0)
 		add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
 	else
 		add_mtd_device(flash_mtd);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/maps/tsunami_flash.c linux/drivers/mtd/maps/tsunami_flash.c
--- linux.orig/drivers/mtd/maps/tsunami_flash.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/maps/tsunami_flash.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,110 @@
+/*
+ * tsunami_flash.c
+ *
+ * flash chip on alpha ds10...
+ * $Id: tsunami_flash.c,v 1.1 2002/01/10 22:59:13 eric Exp $
+ */
+#include <asm/io.h>
+#include <asm/core_tsunami.h>
+#include <linux/mtd/map.h>
+
+#define FLASH_ENABLE_PORT 0x00C00001
+#define FLASH_ENABLE_BYTE 0x01
+#define FLASH_DISABLE_BYTE 0x00
+
+#define MAX_TIG_FLASH_SIZE (12*1024*1024)
+static inline  __u8 tsunami_flash_read8(struct map_info *map, unsigned long offset)
+{
+	return tsunami_tig_readb(offset);
+}
+
+static void tsunami_flash_write8(struct map_info *map, __u8 value, unsigned long offset)
+{
+	tsunami_tig_writeb(value, offset);
+}
+
+static void tsunami_flash_copy_from(
+	struct map_info *map, void *addr, unsigned long offset, ssize_t len)
+{
+	unsigned char *dest;
+	dest = addr;
+	while(len && (offset < MAX_TIG_FLASH_SIZE)) {
+		*dest = tsunami_tig_readb(offset);
+		offset++;
+		dest++;
+		len--;
+	}
+}
+
+static void tsunami_flash_copy_to(
+	struct map_info *map, unsigned long offset, 
+	const void *addr, ssize_t len)
+{
+	const unsigned char *src;
+	src = addr;
+	while(len && (offset < MAX_TIG_FLASH_SIZE)) {
+		tsunami_tig_writeb(*src, offset);
+		offset++;
+		src++;
+		len--;
+	}
+}
+
+/*
+ * Deliberately don't provide operations wider than 8 bits.  I don't
+ * have then and it scares me to think how you could mess up if
+ * you tried to use them.   Buswidth is correctly so I'm safe.
+ */
+static struct map_info tsunami_flash_map = {
+	.name = "flash chip on the Tsunami TIG bus",
+	.size = MAX_TIG_FLASH_SIZE,
+	.buswidth = 1,
+	.read8 = tsunami_flash_read8,
+	.read16 = 0,
+	.read32 = 0, 
+	.copy_from = tsunami_flash_copy_from,
+	.write8 = tsunami_flash_write8,
+	.write16 = 0,
+	.write32 = 0,
+	.copy_to = tsunami_flash_copy_to,
+	.set_vpp = 0,
+	.map_priv_1 = 0,
+
+};
+
+static struct mtd_info *tsunami_flash_mtd;
+
+static void __exit  cleanup_tsunami_flash(void)
+{
+	struct mtd_info *mtd;
+	mtd = tsunami_flash_mtd;
+	if (mtd) {
+		del_mtd_device(mtd);
+		map_destroy(mtd);
+	}
+	tsunami_flash_mtd = 0;
+}
+
+
+static int __init init_tsunami_flash(void)
+{
+	static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 };
+	char **type;
+
+	tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
+	
+	tsunami_flash_mtd = 0;
+	type = rom_probe_types;
+	for(; !tsunami_flash_mtd && *type; type++) {
+		tsunami_flash_mtd = do_map_probe(*type, &tsunami_flash_map);
+	}
+	if (tsunami_flash_mtd) {
+		tsunami_flash_mtd->module = THIS_MODULE;
+		add_mtd_device(tsunami_flash_mtd);
+		return 0;
+	}
+	return -ENXIO;
+}
+
+module_init(init_tsunami_flash);
+module_exit(cleanup_tsunami_flash);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c
--- linux.orig/drivers/mtd/mtdblock.c	2001-10-25 20:58:35.000000000 +0000
+++ linux/drivers/mtd/mtdblock.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,7 +1,7 @@
 /* 
  * Direct MTD block device access
  *
- * $Id: mtdblock.c,v 1.47 2001/10/02 15:05:11 dwmw2 Exp $
+ * $Id: mtdblock.c,v 1.51 2001/11/20 11:42:33 dwmw2 Exp $
  *
  * 02-nov-2000	Nicolas Pitre		Added read-modify-write with cache
  */
@@ -60,6 +60,13 @@
 static int mtd_sizes[MAX_MTD_DEVICES];
 static int mtd_blksizes[MAX_MTD_DEVICES];
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
+#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
+#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
+#else
+#define BLK_INC_USE_COUNT do {} while(0)
+#define BLK_DEC_USE_COUNT do {} while(0)
+#endif
 
 /*
  * Cache stuff...
@@ -287,11 +294,14 @@
 	if (dev >= MAX_MTD_DEVICES)
 		return -EINVAL;
 
+	BLK_INC_USE_COUNT;
+
 	mtd = get_mtd_device(NULL, dev);
 	if (!mtd)
 		return -ENODEV;
 	if (MTD_ABSENT == mtd->type) {
 		put_mtd_device(mtd);
+		BLK_DEC_USE_COUNT;
 		return -ENODEV;
 	}
 	
@@ -314,6 +324,7 @@
 	mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
 	if (!mtdblk) {
 		put_mtd_device(mtd);
+		BLK_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
 	memset(mtdblk, 0, sizeof(*mtdblk));
@@ -329,6 +340,7 @@
 		if (!mtdblk->cache_data) {
 			put_mtd_device(mtdblk->mtd);
 			kfree(mtdblk);
+			BLK_DEC_USE_COUNT;
 			return -ENOMEM;
 		}
 	}
@@ -371,8 +383,6 @@
 	if (inode == NULL)
 		release_return(-ENODEV);
 
-	invalidate_device(inode->i_rdev, 1);
-
 	dev = MINOR(inode->i_rdev);
 	mtdblk = mtdblks[dev];
 
@@ -396,6 +406,7 @@
 
 	DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
 
+	BLK_DEC_USE_COUNT;
 	release_return(0);
 }  
 
@@ -535,8 +546,11 @@
 	switch (cmd) {
 	case BLKGETSIZE:   /* Return device size */
 		return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg);
+
+#ifdef BLKGETSIZE64
 	case BLKGETSIZE64:
 		return put_user((u64)mtdblk->mtd->size, (u64 *)arg);
+#endif
 		
 	case BLKFLSBUF:
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
@@ -569,7 +583,9 @@
 #else
 static struct block_device_operations mtd_fops = 
 {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
 	owner: THIS_MODULE,
+#endif
 	open: mtdblock_open,
 	release: mtdblock_release,
 	ioctl: mtdblock_ioctl
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/mtdblock_ro.c linux/drivers/mtd/mtdblock_ro.c
--- linux.orig/drivers/mtd/mtdblock_ro.c	2001-10-25 20:58:35.000000000 +0000
+++ linux/drivers/mtd/mtdblock_ro.c	2002-07-20 01:08:36.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdblock_ro.c,v 1.9 2001/10/02 15:05:11 dwmw2 Exp $
+ * $Id: mtdblock_ro.c,v 1.12 2001/11/20 11:42:33 dwmw2 Exp $
  *
  * Read-only version of the mtdblock device, without the 
  * read/erase/modify/writeback stuff
@@ -37,6 +37,13 @@
 MODULE_PARM(debug, "i");
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
+#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
+#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
+#else
+#define BLK_INC_USE_COUNT do {} while(0)
+#define BLK_DEC_USE_COUNT do {} while(0)
+#endif
 
 static int mtd_sizes[MAX_MTD_DEVICES];
 
@@ -62,6 +69,8 @@
 		return -EINVAL;
 	}
 
+	BLK_INC_USE_COUNT;
+
 	mtd_sizes[dev] = mtd->size>>9;
 
 	DEBUG(1, "ok\n");
@@ -79,13 +88,12 @@
 	if (inode == NULL)
 		release_return(-ENODEV);
    
-	invalidate_device(inode->i_rdev, 1);
-
 	dev = MINOR(inode->i_rdev);
 	mtd = __get_mtd_device(NULL, dev);
 
 	if (!mtd) {
 		printk(KERN_WARNING "MTD device is absent on mtd_release!\n");
+		BLK_DEC_USE_COUNT;
 		release_return(-ENODEV);
 	}
 	
@@ -96,6 +104,7 @@
 
 	DEBUG(1, "ok\n");
 
+	BLK_DEC_USE_COUNT;
 	release_return(0);
 }  
 
@@ -210,9 +219,12 @@
 	switch (cmd) {
 	case BLKGETSIZE:   /* Return device size */
 		return put_user((mtd->size >> 9), (unsigned long *) arg);
+
+#ifdef BLKGETSIZE64
 	case BLKGETSIZE64:
 		return put_user((u64)mtd->size, (u64 *)arg);
-		
+#endif
+
 	case BLKFLSBUF:
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
 		if(!capable(CAP_SYS_ADMIN))  return -EACCES;
@@ -240,7 +252,9 @@
 #else
 static struct block_device_operations mtd_fops = 
 {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
 	owner: THIS_MODULE,
+#endif
 	open: mtdblock_open,
 	release: mtdblock_release,
 	ioctl: mtdblock_ioctl
@@ -254,7 +268,7 @@
 	if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
 		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
 		       MTD_BLOCK_MAJOR);
-		return EAGAIN;
+		return -EAGAIN;
 	}
 	
 	/* We fill it in at open() time. */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/mtdconcat.c linux/drivers/mtd/mtdconcat.c
--- linux.orig/drivers/mtd/mtdconcat.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/mtd/mtdconcat.c	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,672 @@
+/*
+ * MTD device concatenation layer
+ *
+ * (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
+ *
+ * This code is GPL
+ *
+ * $Id: mtdconcat.c,v 1.2 2002/03/22 08:45:22 dwmw2 Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/concat.h>
+
+/*
+ * Our storage structure:
+ * Subdev points to an array of pointers to struct mtd_info objects
+ * which is allocated along with this structure
+ *
+ */
+struct mtd_concat {
+	struct mtd_info mtd;
+	int             num_subdev;
+	struct mtd_info **subdev;
+};
+
+/*
+ * how to calculate the size required for the above structure,
+ * including the pointer array subdev points to:
+ */
+#define SIZEOF_STRUCT_MTD_CONCAT(num_subdev)	\
+	((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *)))
+
+
+/*
+ * Given a pointer to the MTD object in the mtd_concat structure,
+ * we can retrieve the pointer to that structure with this macro.
+ */
+#define CONCAT(x)  ((struct mtd_concat *)(x))
+
+	
+/* 
+ * MTD methods which look up the relevant subdevice, translate the
+ * effective address and pass through to the subdevice.
+ */
+
+static int concat_read (struct mtd_info *mtd, loff_t from, size_t len, 
+			size_t *retlen, u_char *buf)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	int err = -EINVAL;
+	int i;
+
+	*retlen = 0;
+
+	for(i = 0; i < concat->num_subdev; i++)
+	{
+		struct mtd_info *subdev = concat->subdev[i];
+		size_t size, retsize;
+
+		if (from >= subdev->size)
+		{
+			size  = 0;
+			from -= subdev->size;
+		}
+		else
+		{
+			if (from + len > subdev->size)
+				size = subdev->size - from;
+			else
+				size = len;
+
+			err = subdev->read(subdev, from, size, &retsize, buf);
+
+			if(err)
+				break;
+
+			*retlen += retsize;
+			len -= size;
+			if(len == 0)
+				break;
+
+			err = -EINVAL;
+			buf += size;
+			from = 0;
+		}
+	}
+	return err;
+}
+
+static int concat_write (struct mtd_info *mtd, loff_t to, size_t len,
+			size_t *retlen, const u_char *buf)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	int err = -EINVAL;
+	int i;
+
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+
+	*retlen = 0;
+
+	for(i = 0; i < concat->num_subdev; i++)
+	{
+		struct mtd_info *subdev = concat->subdev[i];
+		size_t size, retsize;
+
+		if (to >= subdev->size)
+		{
+			size  = 0;
+			to -= subdev->size;
+		}
+		else
+		{
+			if (to + len > subdev->size)
+				size = subdev->size - to;
+			else
+				size = len;
+
+			if (!(subdev->flags & MTD_WRITEABLE))
+				err = -EROFS;
+			else
+				err = subdev->write(subdev, to, size, &retsize, buf);
+
+			if(err)
+				break;
+
+			*retlen += retsize;
+			len -= size;
+			if(len == 0)
+				break;
+
+			err = -EINVAL;
+			buf += size;
+			to = 0;
+		}
+	}
+	return err;
+}
+
+static void concat_erase_callback (struct erase_info *instr)
+{
+	wake_up((wait_queue_head_t *)instr->priv);
+}
+
+static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
+{
+	int err;
+	wait_queue_head_t waitq;
+	DECLARE_WAITQUEUE(wait, current);
+
+	/*
+	 * This code was stol^H^H^H^Hinspired by mtdchar.c
+	 */
+	init_waitqueue_head(&waitq);
+
+	erase->mtd = mtd;
+	erase->callback = concat_erase_callback;
+	erase->priv = (unsigned long)&waitq;
+			
+	/*
+	 * FIXME: Allow INTERRUPTIBLE. Which means
+	 * not having the wait_queue head on the stack.
+	 */
+	err = mtd->erase(mtd, erase);
+	if (!err)
+	{
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&waitq, &wait);
+		if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED)
+			schedule();
+		remove_wait_queue(&waitq, &wait);
+		set_current_state(TASK_RUNNING);
+
+		err = (erase->state == MTD_ERASE_FAILED) ? -EIO : 0;
+	}
+	return err;
+}
+
+static int concat_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	struct mtd_info *subdev;
+	int i, err;
+	u_int32_t length;
+	struct erase_info *erase;
+
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+
+	if(instr->addr > concat->mtd.size)
+		return -EINVAL;
+
+	if(instr->len + instr->addr > concat->mtd.size)
+		return -EINVAL;
+
+	/*
+	 * Check for proper erase block alignment of the to-be-erased area.
+	 * It is easier to do this based on the super device's erase
+	 * region info rather than looking at each particular sub-device
+	 * in turn.
+	 */
+	if (!concat->mtd.numeraseregions)
+	{	/* the easy case: device has uniform erase block size */
+		if(instr->addr & (concat->mtd.erasesize - 1))
+			return -EINVAL;
+		if(instr->len & (concat->mtd.erasesize - 1))
+			return -EINVAL;
+	}
+	else
+	{	/* device has variable erase size */
+		struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions;
+
+		/*
+		 * Find the erase region where the to-be-erased area begins:
+		 */
+		for(i = 0; i < concat->mtd.numeraseregions && 
+		           instr->addr >= erase_regions[i].offset; i++)
+			;
+		--i;
+
+		/*
+		 * Now erase_regions[i] is the region in which the
+		 * to-be-erased area begins. Verify that the starting
+		 * offset is aligned to this region's erase size:
+		 */
+		if (instr->addr & (erase_regions[i].erasesize-1))
+			return -EINVAL;
+
+		/*
+		 * now find the erase region where the to-be-erased area ends:
+		 */
+		for(; i < concat->mtd.numeraseregions && 
+		      (instr->addr + instr->len) >=  erase_regions[i].offset ; ++i)
+			;
+		--i;
+		/*
+		 * check if the ending offset is aligned to this region's erase size
+		 */
+		if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1))
+			return -EINVAL;
+	}
+
+	/* make a local copy of instr to avoid modifying the caller's struct */
+	erase = kmalloc(sizeof(struct erase_info),GFP_KERNEL);
+
+	if (!erase)
+		return -ENOMEM;
+
+	*erase = *instr;
+	length = instr->len;
+
+	/*
+	 * find the subdevice where the to-be-erased area begins, adjust
+	 * starting offset to be relative to the subdevice start
+	 */
+	for(i = 0; i < concat->num_subdev; i++)
+	{
+		subdev = concat->subdev[i];
+		if(subdev->size <= erase->addr)
+			erase->addr -= subdev->size;
+		else
+			break;
+    }
+	if(i >= concat->num_subdev)	/* must never happen since size */
+		BUG();					/* limit has been verified above */
+
+	/* now do the erase: */
+	err = 0;
+	for(;length > 0; i++)	/* loop for all subevices affected by this request */
+	{
+		subdev = concat->subdev[i];		/* get current subdevice */
+
+		/* limit length to subdevice's size: */
+		if(erase->addr + length > subdev->size)
+			erase->len = subdev->size - erase->addr;
+		else
+			erase->len = length;
+
+		if (!(subdev->flags & MTD_WRITEABLE))
+		{
+			err = -EROFS;
+			break;
+		}
+		length -= erase->len;
+		if ((err = concat_dev_erase(subdev, erase)))
+		{
+			if(err == -EINVAL)	/* sanity check: must never happen since */
+				BUG();			/* block alignment has been checked above */
+			break;
+		}
+		/*
+		 * erase->addr specifies the offset of the area to be
+		 * erased *within the current subdevice*. It can be
+		 * non-zero only the first time through this loop, i.e.
+		 * for the first subdevice where blocks need to be erased.
+		 * All the following erases must begin at the start of the
+		 * current subdevice, i.e. at offset zero.
+		 */
+		erase->addr = 0;
+	}
+	instr->state = MTD_ERASE_DONE;
+	if (instr->callback)
+		instr->callback(instr);
+	kfree(erase);
+	return err;
+}
+
+static int concat_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	int i, err = -EINVAL;
+
+	if ((len + ofs) > mtd->size) 
+		return -EINVAL;
+
+	for(i = 0; i < concat->num_subdev; i++)
+	{
+		struct mtd_info *subdev = concat->subdev[i];
+		size_t size;
+
+		if (ofs >= subdev->size)
+		{
+			size  = 0;
+			ofs -= subdev->size;
+		}
+		else
+		{
+			if (ofs + len > subdev->size)
+				size = subdev->size - ofs;
+			else
+				size = len;
+
+			err = subdev->lock(subdev, ofs, size);
+
+			if(err)
+				break;
+
+			len -= size;
+			if(len == 0)
+				break;
+
+			err = -EINVAL;
+			ofs = 0;
+		}
+	}
+	return err;
+}
+
+static int concat_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	int i, err = 0;
+
+	if ((len + ofs) > mtd->size) 
+		return -EINVAL;
+
+	for(i = 0; i < concat->num_subdev; i++)
+	{
+		struct mtd_info *subdev = concat->subdev[i];
+		size_t size;
+
+		if (ofs >= subdev->size)
+		{
+			size  = 0;
+			ofs -= subdev->size;
+		}
+		else
+		{
+			if (ofs + len > subdev->size)
+				size = subdev->size - ofs;
+			else
+				size = len;
+
+			err = subdev->unlock(subdev, ofs, size);
+
+			if(err)
+				break;
+
+			len -= size;
+			if(len == 0)
+				break;
+
+			err = -EINVAL;
+			ofs = 0;
+		}
+	}
+	return err;
+}
+
+static void concat_sync(struct mtd_info *mtd)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	int i;
+
+	for(i = 0; i < concat->num_subdev; i++)
+	{
+		struct mtd_info *subdev = concat->subdev[i];
+		subdev->sync(subdev);
+	}
+}
+
+static int concat_suspend(struct mtd_info *mtd)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	int i, rc = 0;
+
+	for(i = 0; i < concat->num_subdev; i++)
+	{
+		struct mtd_info *subdev = concat->subdev[i];
+		if((rc = subdev->suspend(subdev)) < 0)
+			return rc;
+	}
+	return rc;
+}
+
+static void concat_resume(struct mtd_info *mtd)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	int i;
+
+	for(i = 0; i < concat->num_subdev; i++)
+	{
+		struct mtd_info *subdev = concat->subdev[i];
+		subdev->resume(subdev);
+	}
+}
+
+/*
+ * This function constructs a virtual MTD device by concatenating
+ * num_devs MTD devices. A pointer to the new device object is
+ * stored to *new_dev upon success. This function does _not_
+ * register any devices: this is the caller's responsibility.
+ */
+struct mtd_info *mtd_concat_create(
+	struct mtd_info *subdev[],	/* subdevices to concatenate */
+	int num_devs,				/* number of subdevices      */
+	char *name)					/* name for the new device   */
+{
+	int i;
+	size_t size;
+	struct mtd_concat *concat;
+	u_int32_t max_erasesize, curr_erasesize;
+	int num_erase_region;
+
+	printk(KERN_NOTICE "Concatenating MTD devices:\n");
+	for(i = 0; i < num_devs; i++)
+		printk(KERN_NOTICE "(%d): \"%s\"\n", i, subdev[i]->name);
+	printk(KERN_NOTICE "into device \"%s\"\n", name);
+
+	/* allocate the device structure */
+	size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);
+	concat = kmalloc (size, GFP_KERNEL);
+	if(!concat)
+	{
+		printk ("memory allocation error while creating concatenated device \"%s\"\n",
+				name);
+			return NULL;
+	}
+	memset(concat, 0, size);
+	concat->subdev = (struct mtd_info **)(concat + 1);
+
+	/*
+	 * Set up the new "super" device's MTD object structure, check for
+	 * incompatibilites between the subdevices.
+	 */
+	concat->mtd.type      = subdev[0]->type;
+	concat->mtd.flags     = subdev[0]->flags;
+	concat->mtd.size      = subdev[0]->size;
+	concat->mtd.erasesize = subdev[0]->erasesize;
+	concat->mtd.oobblock  = subdev[0]->oobblock;
+	concat->mtd.oobsize   = subdev[0]->oobsize;
+	concat->mtd.ecctype   = subdev[0]->ecctype;
+	concat->mtd.eccsize   = subdev[0]->eccsize;
+
+	concat->subdev[0]   = subdev[0];
+
+	for(i = 1; i < num_devs; i++)
+	{
+		if(concat->mtd.type != subdev[i]->type)
+		{
+			kfree(concat);
+			printk ("Incompatible device type on \"%s\"\n", subdev[i]->name);
+			return NULL;
+		}
+		if(concat->mtd.flags != subdev[i]->flags)
+		{	/*
+			 * Expect all flags except MTD_WRITEABLE to be equal on
+			 * all subdevices.
+			 */
+			if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE)
+			{
+				kfree(concat);
+				printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name);
+				return NULL;
+			}
+			else	/* if writeable attribute differs, make super device writeable */
+				concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE;
+		}
+		concat->mtd.size += subdev[i]->size;
+		if(concat->mtd.oobblock != subdev[i]->oobblock ||
+		   concat->mtd.oobsize  != subdev[i]->oobsize  ||
+		   concat->mtd.ecctype  != subdev[i]->ecctype  ||
+		   concat->mtd.eccsize  != subdev[i]->eccsize)
+		{
+			kfree(concat);
+			printk ("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name);
+			return NULL;
+		}
+		concat->subdev[i] = subdev[i];
+		
+	}
+
+	concat->num_subdev  = num_devs;
+	concat->mtd.name    = name;
+
+	/*
+	 * NOTE: for now, we do not provide any readv()/writev() methods
+	 *       because they are messy to implement and they are not
+	 *       used to a great extent anyway.
+	 */
+	concat->mtd.erase   = concat_erase;
+	concat->mtd.read    = concat_read;
+	concat->mtd.write   = concat_write;
+	concat->mtd.sync    = concat_sync;
+	concat->mtd.lock    = concat_lock;
+	concat->mtd.unlock  = concat_unlock;
+	concat->mtd.suspend = concat_suspend;
+	concat->mtd.resume  = concat_resume;
+
+
+	/*
+	 * Combine the erase block size info of the subdevices:
+	 *
+	 * first, walk the map of the new device and see how
+	 * many changes in erase size we have
+	 */
+	max_erasesize = curr_erasesize = subdev[0]->erasesize;
+	num_erase_region = 1;
+	for(i = 0; i < num_devs; i++)
+	{
+		if(subdev[i]->numeraseregions == 0)
+		{	/* current subdevice has uniform erase size */
+			if(subdev[i]->erasesize != curr_erasesize)
+			{	/* if it differs from the last subdevice's erase size, count it */
+				++num_erase_region;
+				curr_erasesize = subdev[i]->erasesize;
+				if(curr_erasesize > max_erasesize)
+					max_erasesize = curr_erasesize;
+			}
+		}
+		else
+		{	/* current subdevice has variable erase size */
+			int j;
+			for(j = 0; j < subdev[i]->numeraseregions; j++)
+			{	/* walk the list of erase regions, count any changes */
+				if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
+				{
+					++num_erase_region;
+					curr_erasesize = subdev[i]->eraseregions[j].erasesize;
+					if(curr_erasesize > max_erasesize)
+						max_erasesize = curr_erasesize;
+				}
+			}
+		}
+	}
+
+	if(num_erase_region == 1)
+	{	/*
+		 * All subdevices have the same uniform erase size.
+		 * This is easy:
+		 */
+		concat->mtd.erasesize = curr_erasesize;
+		concat->mtd.numeraseregions = 0;
+	}
+	else
+	{	/*
+		 * erase block size varies across the subdevices: allocate
+		 * space to store the data describing the variable erase regions
+		 */
+		struct mtd_erase_region_info *erase_region_p;
+		u_int32_t begin, position;
+
+		concat->mtd.erasesize = max_erasesize;
+		concat->mtd.numeraseregions = num_erase_region;
+		concat->mtd.eraseregions = erase_region_p = kmalloc (
+		     num_erase_region * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
+		if(!erase_region_p)
+		{
+			kfree(concat);
+			printk ("memory allocation error while creating erase region list"
+			        " for device \"%s\"\n", name);
+			return NULL;
+		}
+
+		/*
+		 * walk the map of the new device once more and fill in
+		 * in erase region info:
+		 */
+		curr_erasesize = subdev[0]->erasesize;
+		begin = position = 0;
+		for(i = 0; i < num_devs; i++)
+		{
+			if(subdev[i]->numeraseregions == 0)
+			{	/* current subdevice has uniform erase size */
+				if(subdev[i]->erasesize != curr_erasesize)
+				{	/*
+					 *  fill in an mtd_erase_region_info structure for the area
+					 *  we have walked so far:
+					 */
+					erase_region_p->offset    = begin;
+					erase_region_p->erasesize = curr_erasesize;
+					erase_region_p->numblocks = (position - begin) / curr_erasesize;
+					begin = position;
+
+					curr_erasesize = subdev[i]->erasesize;
+					++erase_region_p;
+				}
+				position += subdev[i]->size;
+			}
+			else
+			{	/* current subdevice has variable erase size */
+				int j;
+				for(j = 0; j < subdev[i]->numeraseregions; j++)
+				{	/* walk the list of erase regions, count any changes */
+					if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
+					{
+						erase_region_p->offset    = begin;
+						erase_region_p->erasesize = curr_erasesize;
+						erase_region_p->numblocks = (position - begin) / curr_erasesize;
+						begin = position;
+
+						curr_erasesize = subdev[i]->eraseregions[j].erasesize;
+						++erase_region_p;
+					}
+					position += subdev[i]->eraseregions[j].numblocks * curr_erasesize;
+				}
+			}
+		}
+		/* Now write the final entry */
+		erase_region_p->offset    = begin;
+		erase_region_p->erasesize = curr_erasesize;
+		erase_region_p->numblocks = (position - begin) / curr_erasesize;
+	}
+
+	return &concat->mtd;
+}
+
+/* 
+ * This function destroys an MTD object obtained from concat_mtd_devs()
+ */
+
+void mtd_concat_destroy(struct mtd_info *mtd)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	if(concat->mtd.numeraseregions)
+		kfree(concat->mtd.eraseregions);
+	kfree(concat);
+}
+
+
+EXPORT_SYMBOL(mtd_concat_create);
+EXPORT_SYMBOL(mtd_concat_destroy);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Kaiser <rkaiser@sysgo.de>");
+MODULE_DESCRIPTION("Generic support for concatenating of MTD devices");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/mtdcore.c linux/drivers/mtd/mtdcore.c
--- linux.orig/drivers/mtd/mtdcore.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/mtdcore.c	2002-07-20 01:08:36.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdcore.c,v 1.31 2001/10/02 15:05:11 dwmw2 Exp $
+ * $Id: mtdcore.c,v 1.32 2002/03/07 18:38:10 joern Exp $
  *
  * Core registration and callback routines for MTD
  * drivers and users.
@@ -296,7 +296,7 @@
 	up(&mtd_table_mutex);
         if (off >= len+begin)
                 return 0;
-        *start = page + (begin-off);
+        *start = page + (off-begin);
         return ((count < begin+len-off) ? count : begin+len-off);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/mtdpart.c linux/drivers/mtd/mtdpart.c
--- linux.orig/drivers/mtd/mtdpart.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/mtdpart.c	2002-07-20 01:08:28.000000000 +0000
@@ -5,8 +5,12 @@
  *
  * This code is GPL
  *
- * $Id: mtdpart.c,v 1.23 2001/10/02 15:05:11 dwmw2 Exp $
- */
+ * $Id: mtdpart.c,v 1.27 2002/03/08 16:34:35 rkaiser Exp $
+ * - with protection register access removed until that code is merged in 2.4.
+ *
+ * 	02-21-2002	Thomas Gleixner <gleixner@autronix.de>
+ *			added support for read_oob, write_oob
+ */	
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -28,6 +32,7 @@
 	u_int32_t offset;
 	int index;
 	struct list_head list;
+	int registered;
 };
 
 /*
@@ -54,6 +59,18 @@
 					len, retlen, buf);
 }
 
+static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len, 
+			size_t *retlen, u_char *buf)
+{
+	struct mtd_part *part = PART(mtd);
+	if (from >= mtd->size)
+		len = 0;
+	else if (from + len > mtd->size)
+		len = mtd->size - from;
+	return part->master->read_oob (part->master, from + part->offset, 
+					len, retlen, buf);
+}
+
 static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
 			size_t *retlen, const u_char *buf)
 {
@@ -68,6 +85,20 @@
 					len, retlen, buf);
 }
 
+static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
+			size_t *retlen, const u_char *buf)
+{
+	struct mtd_part *part = PART(mtd);
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+	if (to >= mtd->size)
+		len = 0;
+	else if (to + len > mtd->size)
+		len = mtd->size - to;
+	return part->master->write_oob (part->master, to + part->offset, 
+					len, retlen, buf);
+}
+
 static int part_writev (struct mtd_info *mtd,  const struct iovec *vecs,
 			 unsigned long count, loff_t to, size_t *retlen)
 {
@@ -148,7 +179,8 @@
 		if (slave->master == master) {
 			struct list_head *prev = node->prev;
 			__list_del(prev, node->next);
-			del_mtd_device(&slave->mtd);
+			if(slave->registered)
+				del_mtd_device(&slave->mtd);
 			kfree(slave);
 			node = prev;
 		}
@@ -198,18 +230,21 @@
 
 		slave->mtd.name = parts[i].name;
 		slave->mtd.bank_size = master->bank_size;
-
 		slave->mtd.module = master->module;
 
 		slave->mtd.read = part_read;
 		slave->mtd.write = part_write;
+
+		if (master->read_oob)
+			slave->mtd.read_oob = part_read_oob;
+		if (master->write_oob)
+			slave->mtd.write_oob = part_write_oob;
 		if (master->sync)
 			slave->mtd.sync = part_sync;
 		if (!i && master->suspend && master->resume) {
 				slave->mtd.suspend = part_suspend;
 				slave->mtd.resume = part_resume;
 		}
-
 		if (master->writev)
 			slave->mtd.writev = part_writev;
 		if (master->readv)
@@ -225,6 +260,15 @@
 
 		if (slave->offset == MTDPART_OFS_APPEND)
 			slave->offset = cur_offset;
+		if (slave->offset == MTDPART_OFS_NXTBLK) {
+			u_int32_t emask = master->erasesize-1;
+			slave->offset = (cur_offset + emask) & ~emask;
+			if (slave->offset != cur_offset) {
+				printk(KERN_NOTICE "Moving partition %d: "
+				       "0x%08x -> 0x%08x\n", i,
+				       cur_offset, slave->offset);
+			}
+		}
 		if (slave->mtd.size == MTDPART_SIZ_FULL)
 			slave->mtd.size = master->size - slave->offset;
 		cur_offset = slave->offset + slave->mtd.size;
@@ -279,8 +323,17 @@
 				parts[i].name);
 		}
 
-		/* register our partition */
-		add_mtd_device(&slave->mtd);
+		if(parts[i].mtdp)
+		{	/* store the object pointer (caller may or may not register it */
+			*parts[i].mtdp = &slave->mtd;
+			slave->registered = 0;
+		}
+		else
+		{
+			/* register our partition */
+			add_mtd_device(&slave->mtd);
+			slave->registered = 1;
+		}
 	}
 
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/nand/nand_ecc.c linux/drivers/mtd/nand/nand_ecc.c
--- linux.orig/drivers/mtd/nand/nand_ecc.c	2001-06-28 21:43:02.000000000 +0000
+++ linux/drivers/mtd/nand/nand_ecc.c	2002-07-20 01:08:30.000000000 +0000
@@ -4,7 +4,7 @@
  *  Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
  *                     Toshiba America Electronics Components, Inc.
  *
- * $Id: nand_ecc.c,v 1.6 2001/06/28 10:52:26 dwmw2 Exp $
+ * $Id: nand_ecc.c,v 1.7 2002/03/21 14:13:50 dwmw2 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
@@ -207,3 +207,7 @@
 
 EXPORT_SYMBOL(nand_calculate_ecc);
 EXPORT_SYMBOL(nand_correct_data);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Steven J. Hill <sjhill@cotw.com>");
+MODULE_DESCRIPTION("Generic NAND ECC support");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/nand/spia.c linux/drivers/mtd/nand/spia.c
--- linux.orig/drivers/mtd/nand/spia.c	2001-10-04 22:14:59.000000000 +0000
+++ linux/drivers/mtd/nand/spia.c	2002-07-20 01:08:23.000000000 +0000
@@ -113,7 +113,7 @@
 	this->ALE = 0x02;
 	this->NCE = 0x04;
 
-	/* Scan to find existance of the device */
+	/* Scan to find existence of the device */
 	if (nand_scan (spia_mtd)) {
 		kfree (spia_mtd);
 		return -ENXIO;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c
--- linux.orig/drivers/mtd/nftlcore.c	2001-10-25 20:58:35.000000000 +0000
+++ linux/drivers/mtd/nftlcore.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,7 +1,7 @@
 /* Linux driver for NAND Flash Translation Layer      */
 /* (c) 1999 Machine Vision Holdings, Inc.             */
 /* Author: David Woodhouse <dwmw2@infradead.org>      */
-/* $Id: nftlcore.c,v 1.82 2001/10/02 15:05:11 dwmw2 Exp $ */
+/* $Id: nftlcore.c,v 1.85 2001/11/20 11:42:33 dwmw2 Exp $ */
 
 /*
   The contents of this file are distributed under the GNU General
@@ -77,6 +77,14 @@
 	sizes:		nftl_sizes,     /* block sizes */
 };
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
+#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
+#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
+#else
+#define BLK_INC_USE_COUNT do {} while(0)
+#define BLK_DEC_USE_COUNT do {} while(0)
+#endif
+
 struct NFTLrecord *NFTLs[MAX_NFTLS];
 
 static void NFTL_setup(struct mtd_info *mtd)
@@ -805,9 +813,12 @@
 	case BLKGETSIZE:   /* Return device size */
 		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
                                 (unsigned long *) arg);
+
+#ifdef BLKGETSIZE64
 	case BLKGETSIZE64:
 		return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
                                 (u64 *)arg);
+#endif
 
 	case BLKFLSBUF:
 		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
@@ -984,8 +995,11 @@
 #endif /* !CONFIG_NFTL_RW */
 
 	thisNFTL->usecount++;
-	if (!get_mtd_device(thisNFTL->mtd, -1))
-		return /* -E'SBUGGEREDOFF */ -ENXIO;
+	BLK_INC_USE_COUNT;
+	if (!get_mtd_device(thisNFTL->mtd, -1)) {
+		BLK_DEC_USE_COUNT;
+		return -ENXIO;
+	}
 
 	return 0;
 }
@@ -998,11 +1012,10 @@
 
 	DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
 
-	invalidate_device(inode->i_rdev, 1);
-
 	if (thisNFTL->mtd->sync)
 		thisNFTL->mtd->sync(thisNFTL->mtd);
 	thisNFTL->usecount--;
+	BLK_DEC_USE_COUNT;
 
 	put_mtd_device(thisNFTL->mtd);
 
@@ -1020,7 +1033,9 @@
 #else
 static struct block_device_operations nftl_fops = 
 {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
 	owner:		THIS_MODULE,
+#endif
 	open:		nftl_open,
 	release:	nftl_release,
 	ioctl: 		nftl_ioctl
@@ -1047,7 +1062,7 @@
 	int i;
 
 #ifdef PRERELEASE 
-	printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.82 $, nftlmount.c %s\n", nftlmountrev);
+	printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.85 $, nftlmount.c %s\n", nftlmountrev);
 #endif
 
 	if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/3c501.c linux/drivers/net/3c501.c
--- linux.orig/drivers/net/3c501.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/net/3c501.c	2002-07-20 01:08:22.000000000 +0000
@@ -334,7 +334,7 @@
 
 		if (autoirq == 0)
 		{
-			printk("%s probe at %#x failed to detect IRQ line.\n",
+			printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n",
 				mname, ioaddr);
 			release_region(ioaddr, EL1_IO_EXTENT);
 			return -EAGAIN;
@@ -358,7 +358,7 @@
 #endif
 
 	if (el_debug)
-		printk("%s", version);
+		printk(KERN_DEBUG "%s", version);
 
 	/*
 	 *	Initialize the device structure.
@@ -417,7 +417,7 @@
 	unsigned long flags;
 
 	if (el_debug > 2)
-		printk("%s: Doing el_open()...", dev->name);
+		printk(KERN_DEBUG "%s: Doing el_open()...", dev->name);
 
 	if ((retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev)))
 		return retval;
@@ -541,13 +541,13 @@
 			lp->loading=0;
 			dev->trans_start = jiffies;
 			if (el_debug > 2)
-				printk(" queued xmit.\n");
+				printk(KERN_DEBUG " queued xmit.\n");
 			dev_kfree_skb (skb);
 			return 0;
 		}
 		/* A receive upset our load, despite our best efforts */
 		if(el_debug>2)
-			printk("%s: burped during tx load.\n", dev->name);
+			printk(KERN_DEBUG "%s: burped during tx load.\n", dev->name);
 		spin_lock_irqsave(&lp->lock, flags);
 	}
 	while(1);
@@ -622,7 +622,7 @@
 			if(el_debug > 2)
 			{
 				printk(KERN_DEBUG "%s: Interrupt while loading [", dev->name);
-				printk(" txsr=%02x gp=%04x rp=%04x]\n", txsr, inw(GP_LOW),inw(RX_LOW));
+				printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x]\n", txsr, inw(GP_LOW),inw(RX_LOW));
 			}
 			lp->loading=2;		/* Force a reload */
 			spin_unlock(&lp->lock);
@@ -639,7 +639,7 @@
 			 *	reset immediately ?
 			 */
 			if(el_debug>1)
-				printk("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x"
+				printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x"
 			  		" gp=%03x rp=%03x.\n", dev->name, txsr, axsr,
 			inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR));
 			lp->txing = 0;
@@ -651,7 +651,7 @@
 			 *	Timed out
 			 */
 			if (el_debug)
-				printk("%s: Transmit failed 16 times, Ethernet jammed?\n",dev->name);
+				printk (KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n",dev->name);
 			outb(AX_SYS, AX_CMD);
 			lp->txing = 0;
 			lp->stats.tx_aborted_errors++;
@@ -664,7 +664,7 @@
 			 */
 
 			if (el_debug > 6)
-				printk(" retransmitting after a collision.\n");
+				printk(KERN_DEBUG " retransmitting after a collision.\n");
 			/*
 			 *	Poor little chip can't reset its own start pointer
 			 */
@@ -683,7 +683,7 @@
 			 */
 			lp->stats.tx_packets++;
 			if (el_debug > 6)
-				printk(" Tx succeeded %s\n",
+				printk(KERN_DEBUG " Tx succeeded %s\n",
 		       			(txsr & TX_RDY) ? "." : "but tx is busy!");
 			/*
 			 *	This is safe the interrupt is atomic WRT itself.
@@ -701,7 +701,7 @@
 
 		int rxsr = inb(RX_STATUS);
 		if (el_debug > 5)
-			printk(" rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),inw(RX_LOW));
+			printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),inw(RX_LOW));
 		/*
 		 *	Just reading rx_status fixes most errors.
 		 */
@@ -711,7 +711,7 @@
 		{	/* Handled to avoid board lock-up. */
 			lp->stats.rx_length_errors++;
 			if (el_debug > 5)
-				printk(" runt.\n");
+				printk(KERN_DEBUG " runt.\n");
 		}
 		else if (rxsr & RX_GOOD)
 		{
@@ -726,12 +726,12 @@
 			 *	Nothing?  Something is broken!
 			 */
 			if (el_debug > 2)
-				printk("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
+				printk(KERN_DEBUG "%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
 					dev->name, rxsr);
 			el_reset(dev);
 		}
 		if (el_debug > 3)
-			printk(".\n");
+			printk(KERN_DEBUG ".\n");
 	}
 
 	/*
@@ -767,12 +767,12 @@
 	pkt_len = inw(RX_LOW);
 
 	if (el_debug > 4)
-		printk(" el_receive %d.\n", pkt_len);
+		printk(KERN_DEBUG " el_receive %d.\n", pkt_len);
 
 	if ((pkt_len < 60)  ||  (pkt_len > 1536))
 	{
 		if (el_debug)
-			printk("%s: bogus packet, length=%d\n", dev->name, pkt_len);
+			printk(KERN_DEBUG "%s: bogus packet, length=%d\n", dev->name, pkt_len);
 		lp->stats.rx_over_errors++;
 		return;
 	}
@@ -791,7 +791,7 @@
 	outw(0x00, GP_LOW);
 	if (skb == NULL)
 	{
-		printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+		printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", dev->name);
 		lp->stats.rx_dropped++;
 		return;
 	}
@@ -829,7 +829,7 @@
 	int ioaddr = dev->base_addr;
 
 	if (el_debug> 2)
-		printk("3c501 reset...");
+		printk(KERN_INFO "3c501 reset...");
 	outb(AX_RESET, AX_CMD);		/* Reset the chip */
 	outb(AX_LOOP, AX_CMD);		/* Aux control, irq and loopback enabled */
 	{
@@ -862,7 +862,7 @@
 	int ioaddr = dev->base_addr;
 
 	if (el_debug > 2)
-		printk("%s: Shutting down Ethernet card at %#x.\n", dev->name, ioaddr);
+		printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n", dev->name, ioaddr);
 
 	netif_stop_queue(dev);
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/3c503.c linux/drivers/net/3c503.c
--- linux.orig/drivers/net/3c503.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/net/3c503.c	2002-07-20 01:08:27.000000000 +0000
@@ -692,9 +692,11 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
 MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
-MODULE_PARM_DESC(io, "EtherLink II I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherLink II IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr, "EtherLink II tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(io, "I/O base address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
+MODULE_PARM_DESC(xcvr, "tranceiver(s) (0=internal, 1=external)");
+MODULE_DESCRIPTION("3Com ISA EtherLink II, II/16 (3c503, 3c503/16) driver");
+MODULE_LICENSE("GPL");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
@@ -742,7 +744,6 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/3c509.c linux/drivers/net/3c509.c
--- linux.orig/drivers/net/3c509.c	2002-02-25 19:37:58.000000000 +0000
+++ linux/drivers/net/3c509.c	2002-07-20 01:08:23.000000000 +0000
@@ -45,11 +45,15 @@
 			- Reviewed against 1.18 from scyld.com
 		v1.18a 17Nov2001 Jeff Garzik <jgarzik@mandrakesoft.com>
 			- ethtool support
+		v1.18b 1Mar2002 Zwane Mwaikambo <zwane@commfireservices.com>
+			- Power Management support
+                v1.18c 1Mar2002 David Ruggiero <jdr@farfalle.com>
+                        - Full duplex support
 */
 
 #define DRV_NAME	"3c509"
-#define DRV_VERSION	"1.18a"
-#define DRV_RELDATE	"17Nov2001"
+#define DRV_VERSION	"1.18c"
+#define DRV_RELDATE	"1Mar2002"
 
 /* A few values that may be tweaked. */
 
@@ -82,8 +86,9 @@
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <linux/pm.h>
 
-static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE "becker@scyld.com\n";
+static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
 static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n";
 
 #ifdef EL3_DEBUG
@@ -116,7 +121,8 @@
 	FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
 	SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
 	SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
-	StatsDisable = 22<<11, StopCoax = 23<<11,};
+	StatsDisable = 22<<11, StopCoax = 23<<11, PowerUp = 27<<11,
+	PowerDown = 28<<11, PowerAuto = 29<<11};
 
 enum c509status {
 	IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
@@ -137,6 +143,8 @@
 #define WN0_IRQ		0x08		/* Window 0: Set IRQ line in bits 12-15. */
 #define WN4_MEDIA	0x0A		/* Window 4: Various transcvr/media bits. */
 #define  MEDIA_TP	0x00C0		/* Enable link beat and jabber for 10baseT. */
+#define WN4_NETDIAG	0x06		/* Window 4: Net diagnostic */
+#define FD_ENABLE	0x8000		/* Enable full-duplex ("external loopback") */  
 
 /*
  * Must be a power of two (we use a binary and in the
@@ -152,6 +160,9 @@
 	int head, size;
 	struct sk_buff *queue[SKB_QUEUE_SIZE];
 	char mca_slot;
+#ifdef CONFIG_PM
+	struct pm_dev *pmdev;
+#endif
 };
 static int id_port __initdata = 0x110;	/* Start with 0x110 to avoid new sound cards.*/
 static struct net_device *el3_root_dev;
@@ -168,6 +179,13 @@
 static void set_multicast_list(struct net_device *dev);
 static void el3_tx_timeout (struct net_device *dev);
 static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
+static void el3_down(struct net_device *dev);
+static void el3_up(struct net_device *dev);
+#ifdef CONFIG_PM
+static int el3_suspend(struct pm_dev *pdev);
+static int el3_resume(struct pm_dev *pdev);
+static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
+#endif
 
 #ifdef CONFIG_MCA
 struct el3_mca_adapters_struct {
@@ -219,7 +237,7 @@
 #endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
 static int nopnp;
 
-int __init el3_probe(struct net_device *dev)
+int __init el3_probe(struct net_device *dev, int card_idx)
 {
 	struct el3_private *lp;
 	short lrs_state = 0xff, i;
@@ -486,12 +504,18 @@
 	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
-	dev->if_port = (dev->mem_start & 0x1f) ? dev->mem_start & 3 : if_port;
+        
+	if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
+		dev->if_port = (dev->mem_start & 0x0f);
+        } else { /* xcvr codes 0/8 */
+		/* use eeprom value, but save user's full-duplex selection */
+		dev->if_port = (if_port | (dev->mem_start & 0x08) );
+	}
 
 	{
 		const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
 		printk("%s: 3c5x9 at %#3.3lx, %s port, address ",
-			   dev->name, dev->base_addr, if_names[dev->if_port]);
+			dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)]);
 	}
 
 	/* Read in the station address. */
@@ -525,6 +549,16 @@
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->do_ioctl = netdev_ioctl;
 
+#ifdef CONFIG_PM
+	/* register power management */
+	lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
+	if (lp->pmdev) {
+		struct pm_dev *p;
+		p = lp->pmdev;
+		p->data = (struct net_device *)dev;
+	}
+#endif
+
 	/* Fill in the generic fields of the device structure. */
 	ether_setup(dev);
 	return 0;
@@ -533,7 +567,7 @@
 /* Read a word from the EEPROM using the regular EEPROM access register.
    Assume that we are in register window zero.
  */
-static ushort __init read_eeprom(int ioaddr, int index)
+static ushort read_eeprom(int ioaddr, int index)
 {
 	outw(EEPROM_READ + index, ioaddr + 10);
 	/* Pause for at least 162 us. for the read to take place. */
@@ -581,53 +615,7 @@
 		printk("%s: Opening, IRQ %d	 status@%x %4.4x.\n", dev->name,
 			   dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
 
-	/* Activate board: this is probably unnecessary. */
-	outw(0x0001, ioaddr + 4);
-
-	/* Set the IRQ line. */
-	outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
-
-	/* Set the station address in window 2 each time opened. */
-	EL3WINDOW(2);
-
-	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + i);
-
-	if (dev->if_port == 3)
-		/* Start the thinnet transceiver. We should really wait 50ms...*/
-		outw(StartCoax, ioaddr + EL3_CMD);
-	else if (dev->if_port == 0) {
-		/* 10baseT interface, enabled link beat and jabber check. */
-		EL3WINDOW(4);
-		outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
-	}
-
-	/* Switch to the stats window, and clear all stats by reading. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-	EL3WINDOW(6);
-	for (i = 0; i < 9; i++)
-		inb(ioaddr + i);
-	inw(ioaddr + 10);
-	inw(ioaddr + 12);
-
-	/* Switch to register set 1 for normal use. */
-	EL3WINDOW(1);
-
-	/* Accept b-case and phys addr only. */
-	outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
-	outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
-
-	netif_start_queue(dev);
-
-	outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
-	outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
-	/* Allow status bits to be seen. */
-	outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
-	/* Ack all pending events, and set active indicator mask. */
-	outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
-		 ioaddr + EL3_CMD);
-	outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
-		 ioaddr + EL3_CMD);
+	el3_up(dev);
 
 	if (el3_debug > 3)
 		printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
@@ -986,23 +974,7 @@
 	if (el3_debug > 2)
 		printk("%s: Shutting down ethercard.\n", dev->name);
 
-	netif_stop_queue(dev);
-
-	/* Turn off statistics ASAP.  We update lp->stats below. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-
-	/* Disable the receiver and transmitter. */
-	outw(RxDisable, ioaddr + EL3_CMD);
-	outw(TxDisable, ioaddr + EL3_CMD);
-
-	if (dev->if_port == 3)
-		/* Turn off thinnet power.  Green! */
-		outw(StopCoax, ioaddr + EL3_CMD);
-	else if (dev->if_port == 0) {
-		/* Disable link beat and jabber, if_port may change ere next open(). */
-		EL3WINDOW(4);
-		outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
-	}
+	el3_down(dev);
 
 	free_irq(dev->irq, dev);
 	/* Switching back to window 0 disables the IRQ. */
@@ -1010,7 +982,6 @@
 	/* But we explicitly zero the IRQ line select anyway. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
 
-	update_stats(dev);
 	return 0;
 }
 
@@ -1092,25 +1063,208 @@
 
 	return rc;
 }
- 
+
+static void el3_down(struct net_device *dev)
+{
+	int ioaddr = dev->base_addr;
+
+	netif_stop_queue(dev);
+
+	/* Turn off statistics ASAP.  We update lp->stats below. */
+	outw(StatsDisable, ioaddr + EL3_CMD);
+
+	/* Disable the receiver and transmitter. */
+	outw(RxDisable, ioaddr + EL3_CMD);
+	outw(TxDisable, ioaddr + EL3_CMD);
+
+	if (dev->if_port == 3)
+		/* Turn off thinnet power.  Green! */
+		outw(StopCoax, ioaddr + EL3_CMD);
+	else if (dev->if_port == 0) {
+		/* Disable link beat and jabber, if_port may change ere next open(). */
+		EL3WINDOW(4);
+		outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
+	}
+
+	outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
+
+	update_stats(dev);
+}
+
+static void el3_up(struct net_device *dev)
+{
+	int i, sw_info, net_diag;
+	int ioaddr = dev->base_addr;
+	
+	/* Activating the board required and does no harm otherwise */
+	outw(0x0001, ioaddr + 4);
+
+	/* Set the IRQ line. */
+	outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
+
+	/* Set the station address in window 2 each time opened. */
+	EL3WINDOW(2);
+
+	for (i = 0; i < 6; i++)
+		outb(dev->dev_addr[i], ioaddr + i);
+
+	if ((dev->if_port & 0x03) == 3) /* BNC interface */
+		/* Start the thinnet transceiver. We should really wait 50ms...*/
+		outw(StartCoax, ioaddr + EL3_CMD);
+	else if ((dev->if_port & 0x03) == 0) { /* 10baseT interface */
+		/* Combine secondary sw_info word (the adapter level) and primary
+			sw_info word (duplex setting plus other useless bits) */
+		EL3WINDOW(0);
+		sw_info = (read_eeprom(ioaddr, 0x14) & 0x400f) | 
+			(read_eeprom(ioaddr, 0x0d) & 0xBff0);
+
+		EL3WINDOW(4);
+		net_diag = inw(ioaddr + WN4_NETDIAG);
+		net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
+		printk("%s: ", dev->name);
+		switch (dev->if_port & 0x0c) {
+			case 12:
+				/* force full-duplex mode if 3c5x9b */
+				if (sw_info & 0x000f) {
+					printk("Forcing 3c5x9b full-duplex mode");
+					break;
+				}
+			case 8:
+				/* set full-duplex mode based on eeprom config setting */
+				if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
+					printk("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
+					break;
+				}
+			default:
+				/* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
+				printk("Setting 3c5x9/3c5x9B half-duplex mode");
+				net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
+		}
+
+		outw(net_diag, ioaddr + WN4_NETDIAG);
+		printk(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
+		if (el3_debug > 3)
+			printk("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
+		/* Enable link beat and jabber check. */
+		outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
+	}
+
+	/* Switch to the stats window, and clear all stats by reading. */
+	outw(StatsDisable, ioaddr + EL3_CMD);
+	EL3WINDOW(6);
+	for (i = 0; i < 9; i++)
+		inb(ioaddr + i);
+	inw(ioaddr + 10);
+	inw(ioaddr + 12);
+
+	/* Switch to register set 1 for normal use. */
+	EL3WINDOW(1);
+
+	/* Accept b-case and phys addr only. */
+	outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
+	outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
+
+	outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
+	outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+	/* Allow status bits to be seen. */
+	outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
+	/* Ack all pending events, and set active indicator mask. */
+	outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
+		 ioaddr + EL3_CMD);
+	outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
+		 ioaddr + EL3_CMD);
+
+	netif_start_queue(dev);
+}
+
+/* Power Management support functions */
+#ifdef CONFIG_PM
+
+static int el3_suspend(struct pm_dev *pdev)
+{
+	unsigned long flags;
+	struct net_device *dev;
+	struct el3_private *lp;
+	int ioaddr;
+	
+	if (!pdev && !pdev->data)
+		return -EINVAL;
+
+	dev = (struct net_device *)pdev->data;
+	lp = (struct el3_private *)dev->priv;
+	ioaddr = dev->base_addr;
+
+	spin_lock_irqsave(&lp->lock, flags);
+
+	if (netif_running(dev))
+		netif_device_detach(dev);
+
+	el3_down(dev);
+	outw(PowerDown, ioaddr + EL3_CMD);
+
+	spin_unlock_irqrestore(&lp->lock, flags);
+	return 0;
+}
+
+static int el3_resume(struct pm_dev *pdev)
+{
+	unsigned long flags;
+	struct net_device *dev;
+	struct el3_private *lp;
+	int ioaddr;
+	
+	if (!pdev && !pdev->data)
+		return -EINVAL;
+
+	dev = (struct net_device *)pdev->data;
+	lp = (struct el3_private *)dev->priv;
+	ioaddr = dev->base_addr;
+
+	spin_lock_irqsave(&lp->lock, flags);
+
+	outw(PowerUp, ioaddr + EL3_CMD);
+	el3_up(dev);
+
+	if (netif_running(dev))
+		netif_device_attach(dev);
+		
+	spin_unlock_irqrestore(&lp->lock, flags);
+	return 0;
+}
+
+static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
+{
+	switch (rqst) {
+		case PM_SUSPEND:
+			return el3_suspend(pdev);
+
+		case PM_RESUME:
+			return el3_resume(pdev);
+	}
+	return 0;
+}
+
+#endif /* CONFIG_PM */
+
 #ifdef MODULE
 /* Parameters that may be passed into the module. */
 static int debug = -1;
 static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
 
 MODULE_PARM(debug,"i");
 MODULE_PARM(irq,"1-8i");
-MODULE_PARM(xcvr,"1-8i");
+MODULE_PARM(xcvr,"1-12i");
 MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM_DESC(debug, "EtherLink III debug level (0-6)");
-MODULE_PARM_DESC(irq, "EtherLink III IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr,"EtherLink III tranceiver(s) (0=internal, 1=external)");
-MODULE_PARM_DESC(max_interrupt_work, "EtherLink III maximum events handled per interrupt");
+MODULE_PARM_DESC(debug, "debug level (0-6)");
+MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
+MODULE_PARM_DESC(xcvr,"tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
 #ifdef CONFIG_ISAPNP
 MODULE_PARM(nopnp, "i");
-MODULE_PARM_DESC(nopnp, "EtherLink III disable ISA PnP support (0-1)");
+MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
 #endif	/* CONFIG_ISAPNP */
+MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver");
 
 int
 init_module(void)
@@ -1121,7 +1275,7 @@
 		el3_debug = debug;
 
 	el3_root_dev = NULL;
-	while (el3_probe(0) == 0) {
+	while (el3_probe(0, el3_cards) == 0) {
 		if (irq[el3_cards] > 1)
 			el3_root_dev->irq = irq[el3_cards];
 		if (xcvr[el3_cards] >= 0)
@@ -1143,7 +1297,12 @@
 #ifdef CONFIG_MCA		
 		if(lp->mca_slot!=-1)
 			mca_mark_as_unused(lp->mca_slot);
-#endif			
+#endif
+
+#ifdef CONFIG_PM
+		if (lp->pmdev)
+			pm_unregister(lp->pmdev);
+#endif
 		next_dev = lp->next_dev;
 		unregister_netdev(el3_root_dev);
 		release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/7990.c linux/drivers/net/7990.c
--- linux.orig/drivers/net/7990.c	2001-02-13 21:15:05.000000000 +0000
+++ linux/drivers/net/7990.c	2002-07-20 01:08:38.000000000 +0000
@@ -25,6 +25,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -569,7 +570,7 @@
         struct dev_mc_list *dmi=dev->mc_list;
         char *addrs;
         int i, j, bit, byte;
-        u32 crc, poly = CRC_POLYNOMIAL_LE;
+        u32 crc;
         
         /* set all multicast bits */
         if (dev->flags & IFF_ALLMULTI){ 
@@ -590,21 +591,7 @@
                 if (!(*addrs & 1))
                         continue;
                 
-                crc = 0xffffffff;
-                for (byte = 0; byte < 6; byte++)
-                        for (bit = *addrs++, j = 0; j < 8; j++, bit>>=1)
-                        {
-                                int test;
-
-                                test = ((bit ^ crc) & 0x01);
-                                crc >>= 1;
-
-                                if (test)
-                                {
-                                        crc = crc ^ poly;
-                                }
-                        }
-                
+		crc = ether_crc_le(6, addrs);
                 crc = crc >> 26;
                 mcast_table [crc >> 4] |= 1 << (crc & 0xf);
         }
@@ -643,3 +630,4 @@
 		netif_start_queue (dev);
 }
 
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/7990.h linux/drivers/net/7990.h
--- linux.orig/drivers/net/7990.h	2001-01-04 21:00:55.000000000 +0000
+++ linux/drivers/net/7990.h	2002-07-20 01:08:26.000000000 +0000
@@ -132,9 +132,6 @@
 	char tx_full;
 };
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 /*
  *              Am7990 Control and Status Registers
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/8139cp.c linux/drivers/net/8139cp.c
--- linux.orig/drivers/net/8139cp.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/8139cp.c	2002-07-20 01:08:36.000000000 +0000
@@ -1,7 +1,8 @@
 /* 8139cp.c: A Linux PCI Ethernet driver for the RealTek 8139C+ chips. */
 /*
-	Copyright 2001 Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2001,2002 Jeff Garzik <jgarzik@mandrakesoft.com>
 
+	Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) [tg3.c]
 	Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com) [sungem.c]
 	Copyright 2001 Manfred Spraul				    [natsemi.c]
 	Copyright 1999-2001 by Donald Becker.			    [natsemi.c]
@@ -29,26 +30,29 @@
 	* Consider Rx interrupt mitigation using TimerIntr
 	* Implement 8139C+ statistics dump; maybe not...
 	  h/w stats can be reset only by software reset
-	* Rx checksumming
 	* Tx checksumming
+	* Handle netif_rx return value
 	* ETHTOOL_GREGS, ETHTOOL_[GS]WOL,
-	* Jumbo frames / dev->change_mtu
 	* Investigate using skb->priority with h/w VLAN priority
 	* Investigate using High Priority Tx Queue with skb->priority
 	* Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
 	* Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error
-        * Implement Tx software interrupt mitigation via
-	          Tx descriptor bit
+	* Implement Tx software interrupt mitigation via
+	  Tx descriptor bit
+	* The real minimum of CP_MIN_MTU is 4 bytes.  However,
+	  for this to be supported, one must(?) turn on packet padding.
 
  */
 
 #define DRV_NAME		"8139cp"
-#define DRV_VERSION		"0.0.6"
-#define DRV_RELDATE		"Nov 19, 2001"
+#define DRV_VERSION		"0.0.7"
+#define DRV_RELDATE		"Feb 27, 2002"
 
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/compiler.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
@@ -56,9 +60,21 @@
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/if_vlan.h>
+#include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define CP_VLAN_TAG_USED 1
+#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \
+	do { (tx_desc)->opts2 = (vlan_tag_value); } while (0)
+#else
+#define CP_VLAN_TAG_USED 0
+#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \
+	do { (tx_desc)->opts2 = 0; } while (0)
+#endif
+
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
 KERN_INFO DRV_NAME " 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
@@ -106,8 +122,11 @@
 #define TX_EARLY_THRESH		256	/* Early Tx threshold, in bytes */
 
 /* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (6*HZ)
+#define TX_TIMEOUT		(6*HZ)
 
+/* hardware minimum and maximum for a single frame's data payload */
+#define CP_MIN_MTU		60	/* TODO: allow lower, but pad */
+#define CP_MAX_MTU		4096
 
 enum {
 	/* NIC register offsets */
@@ -149,12 +168,17 @@
 	IPCS		= (1 << 18), /* Calculate IP checksum */
 	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
 	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
+	TxVlanTag	= (1 << 17), /* Add VLAN tag */
+	RxVlanTagged	= (1 << 16), /* Rx VLAN tag available */
 	IPFail		= (1 << 15), /* IP checksum failed */
 	UDPFail		= (1 << 14), /* UDP/IP checksum failed */
 	TCPFail		= (1 << 13), /* TCP/IP checksum failed */
 	NormalTxPoll	= (1 << 6),  /* One or more normal Tx packets to send */
 	PID1		= (1 << 17), /* 2 protocol id bits:  0==non-IP, */
 	PID0		= (1 << 16), /* 1==UDP/IP, 2==TCP/IP, 3==IP */
+	RxProtoTCP	= 2,
+	RxProtoUDP	= 1,
+	RxProtoIP	= 3,
 	TxFIFOUnder	= (1 << 25), /* Tx FIFO underrun */
 	TxOWC		= (1 << 22), /* Tx Out-of-window collision */
 	TxLinkFail	= (1 << 21), /* Link failed during Tx of packet */
@@ -204,6 +228,7 @@
 	TxOn		= (1 << 2),  /* Tx mode enable */
 
 	/* C+ mode command register */
+	RxVlanOn	= (1 << 6),  /* Rx VLAN de-tagging enable */
 	RxChkSum	= (1 << 5),  /* Rx checksum offload enable */
 	PCIMulRW	= (1 << 3),  /* Enable PCI read/write multiple */
 	CpRxOn		= (1 << 1),  /* Rx mode enable */
@@ -274,6 +299,10 @@
 	unsigned		rx_buf_sz;
 	dma_addr_t		ring_dma;
 
+#if CP_VLAN_TAG_USED
+	struct vlan_group	*vlgrp;
+#endif
+
 	u32			msg_enable;
 
 	struct net_device_stats net_stats;
@@ -320,14 +349,32 @@
 };
 MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
 
-static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb)
+static inline void cp_set_rxbufsize (struct cp_private *cp)
+{
+	unsigned int mtu = cp->dev->mtu;
+	
+	if (mtu > ETH_DATA_LEN)
+		/* MTU + ethernet header + FCS + optional VLAN tag */
+		cp->rx_buf_sz = mtu + ETH_HLEN + 8;
+	else
+		cp->rx_buf_sz = PKT_BUF_SZ;
+}
+
+static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
+			      struct cp_desc *desc)
 {
 	skb->protocol = eth_type_trans (skb, cp->dev);
 
 	cp->net_stats.rx_packets++;
 	cp->net_stats.rx_bytes += skb->len;
 	cp->dev->last_rx = jiffies;
-	netif_rx (skb);
+
+#if CP_VLAN_TAG_USED
+	if (cp->vlgrp && (desc->opts2 & RxVlanTagged)) {
+		vlan_hwaccel_rx(skb, cp->vlgrp, desc->opts2 & 0xffff);
+	} else
+#endif
+		netif_rx(skb);
 }
 
 static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
@@ -410,13 +457,26 @@
 			cp_rx_err_acct(cp, rx_tail, status, len);
 			dev_kfree_skb_irq(copy_skb);
 		} else
-			cp_rx_skb(cp, copy_skb);
+			cp_rx_skb(cp, copy_skb, &cp->rx_ring[rx_tail]);
 		cp->frag_skb = NULL;
 	} else {
 		cp->frag_skb = copy_skb;
 	}
 }
 
+static inline unsigned int cp_rx_csum_ok (u32 status)
+{
+	unsigned int protocol = (status >> 16) & 0x3;
+	
+	if (likely((protocol == RxProtoTCP) && (!(status & TCPFail))))
+		return 1;
+	else if ((protocol == RxProtoUDP) && (!(status & UDPFail)))
+		return 1;
+	else if ((protocol == RxProtoIP) && (!(status & IPFail)))
+		return 1;
+	return 0;
+}
+
 static void cp_rx (struct cp_private *cp)
 {
 	unsigned rx_tail = cp->rx_tail;
@@ -426,13 +486,15 @@
 		u32 status, len;
 		dma_addr_t mapping;
 		struct sk_buff *skb, *new_skb;
+		struct cp_desc *desc;
 		unsigned buflen;
 
 		skb = cp->rx_skb[rx_tail].skb;
 		if (!skb)
 			BUG();
-		rmb();
-		status = le32_to_cpu(cp->rx_ring[rx_tail].opts1);
+
+		desc = &cp->rx_ring[rx_tail];
+		status = le32_to_cpu(desc->opts1);
 		if (status & DescOwn)
 			break;
 
@@ -465,7 +527,13 @@
 
 		pci_unmap_single(cp->pdev, mapping,
 				 buflen, PCI_DMA_FROMDEVICE);
-		skb->ip_summed = CHECKSUM_NONE;
+
+		/* Handle checksum offloading for incoming packets. */
+		if (cp_rx_csum_ok(status))
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else
+			skb->ip_summed = CHECKSUM_NONE;
+
 		skb_put(skb, len);
 
 		mapping =
@@ -474,15 +542,14 @@
 				       buflen, PCI_DMA_FROMDEVICE);
 		cp->rx_skb[rx_tail].skb = new_skb;
 
-		cp_rx_skb(cp, skb);
+		cp_rx_skb(cp, skb, desc);
 
 rx_next:
 		if (rx_tail == (CP_RX_RING_SIZE - 1))
-			cp->rx_ring[rx_tail].opts1 =
-				cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
+			desc->opts1 = cpu_to_le32(DescOwn | RingEnd |
+						  cp->rx_buf_sz);
 		else
-			cp->rx_ring[rx_tail].opts1 =
-				cpu_to_le32(DescOwn | cp->rx_buf_sz);
+			desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz);
 		cp->rx_ring[rx_tail].opts2 = 0;
 		cp->rx_ring[rx_tail].addr_lo = cpu_to_le32(mapping);
 		rx_tail = NEXT_RX(rx_tail);
@@ -582,7 +649,7 @@
 
 	cp->tx_tail = tx_tail;
 
-	if (netif_queue_stopped(cp->dev) && (TX_BUFFS_AVAIL(cp) > 1))
+	if (netif_queue_stopped(cp->dev) && (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1)))
 		netif_wake_queue(cp->dev);
 }
 
@@ -591,15 +658,26 @@
 	struct cp_private *cp = dev->priv;
 	unsigned entry;
 	u32 eor;
+#if CP_VLAN_TAG_USED
+	u32 vlan_tag = 0;
+#endif
 
 	spin_lock_irq(&cp->lock);
 
+	/* This is a hard error, log it. */
 	if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
 		netif_stop_queue(dev);
 		spin_unlock_irq(&cp->lock);
+		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+		       dev->name);
 		return 1;
 	}
 
+#if CP_VLAN_TAG_USED
+	if (cp->vlgrp && vlan_tx_tag_present(skb))
+		vlan_tag = TxVlanTag | vlan_tx_tag_get(skb);
+#endif
+
 	entry = cp->tx_head;
 	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
 	if (skb_shinfo(skb)->nr_frags == 0) {
@@ -609,7 +687,7 @@
 		len = skb->len;
 		mapping = pci_map_single(cp->pdev, skb->data, len, PCI_DMA_TODEVICE);
 		eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
-		txd->opts2 = 0;
+		CP_VLAN_TX_TAG(txd, vlan_tag);
 		txd->addr_lo = cpu_to_le32(mapping);
 		wmb();
 
@@ -662,7 +740,7 @@
 				ctrl |= LastFrag;
 
 			txd = &cp->tx_ring[entry];
-			txd->opts2 = 0;
+			CP_VLAN_TX_TAG(txd, vlan_tag);
 			txd->addr_lo = cpu_to_le32(mapping);
 			wmb();
 
@@ -676,7 +754,7 @@
 		}
 
 		txd = &cp->tx_ring[first_entry];
-		txd->opts2 = 0;
+		CP_VLAN_TX_TAG(txd, vlan_tag);
 		txd->addr_lo = cpu_to_le32(first_mapping);
 		wmb();
 
@@ -691,9 +769,7 @@
 	if (netif_msg_tx_queued(cp))
 		printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n",
 		       dev->name, entry, skb->len);
-	if (TX_BUFFS_AVAIL(cp) < 0)
-		BUG();
-	if (TX_BUFFS_AVAIL(cp) == 0)
+	if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
 		netif_stop_queue(dev);
 
 	spin_unlock_irq(&cp->lock);
@@ -707,22 +783,6 @@
 /* Set or clear the multicast filter for this adaptor.
    This routine is not state sensitive and need not be SMP locked. */
 
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc (int length, unsigned char *data)
-{
-	int crc = -1;
-
-	while (--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
-			crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ?
-			     ethernet_polynomial : 0);
-	}
-
-	return crc;
-}
-
 static void __cp_set_rx_mode (struct net_device *dev)
 {
 	struct cp_private *cp = dev->priv;
@@ -752,7 +812,7 @@
 		     i++, mclist = mclist->next) {
 			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 
-			mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
+			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 			rx_mode |= AcceptMulticast;
 		}
 	}
@@ -827,6 +887,12 @@
 	printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
 }
 
+static inline void cp_start_hw (struct cp_private *cp)
+{
+	cpw8(Cmd, RxOn | TxOn);
+	cpw16(CpCmd, PCIMulRW | RxChkSum | CpRxOn | CpTxOn);
+}
+
 static void cp_init_hw (struct cp_private *cp)
 {
 	struct net_device *dev = cp->dev;
@@ -839,8 +905,7 @@
 	cpw32_f (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
 	cpw32_f (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
 
-	cpw8(Cmd, RxOn | TxOn);
-	cpw16(CpCmd, PCIMulRW | CpRxOn | CpTxOn);
+	cp_start_hw(cp);
 	cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
 
 	__cp_set_rx_mode(dev);
@@ -972,8 +1037,6 @@
 	if (netif_msg_ifup(cp))
 		printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
 
-	cp->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
-
 	rc = cp_alloc_rings(cp);
 	if (rc)
 		return rc;
@@ -1008,6 +1071,38 @@
 	return 0;
 }
 
+static int cp_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct cp_private *cp = dev->priv;
+	int rc;
+
+	/* check for invalid MTU, according to hardware limits */
+	if (new_mtu < CP_MIN_MTU || new_mtu > CP_MAX_MTU)
+		return -EINVAL;
+
+	/* if network interface not up, no need for complexity */
+	if (!netif_running(dev)) {
+		dev->mtu = new_mtu;
+		cp_set_rxbufsize(cp);	/* set new rx buf size */
+		return 0;
+	}
+
+	spin_lock_irq(&cp->lock);
+
+	cp_stop_hw(cp);			/* stop h/w and free rings */
+	cp_clean_rings(cp);
+
+	dev->mtu = new_mtu;
+	cp_set_rxbufsize(cp);		/* set new rx buf size */
+
+	rc = cp_init_rings(cp);		/* realloc and restart h/w */
+	cp_start_hw(cp);
+
+	spin_unlock_irq(&cp->lock);
+
+	return rc;
+}
+
 static char mii_2_8139_map[8] = {
 	BasicModeCtrl,
 	BasicModeStatus,
@@ -1142,7 +1237,28 @@
 	return rc;
 }
 
+#if CP_VLAN_TAG_USED
+static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct cp_private *cp = dev->priv;
+
+	spin_lock_irq(&cp->lock);
+	cp->vlgrp = grp;
+	cpw16(CpCmd, cpr16(CpCmd) | RxVlanOn);
+	spin_unlock_irq(&cp->lock);
+}
+
+static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct cp_private *cp = dev->priv;
 
+	spin_lock_irq(&cp->lock);
+	cpw16(CpCmd, cpr16(CpCmd) & ~RxVlanOn);
+	if (cp->vlgrp)
+		cp->vlgrp->vlan_devices[vid] = NULL;
+	spin_unlock_irq(&cp->lock);
+}
+#endif
 
 /* Serial EEPROM section. */
 
@@ -1246,6 +1362,7 @@
 	cp->mii_if.mdio_read = mdio_read;
 	cp->mii_if.mdio_write = mdio_write;
 	cp->mii_if.phy_id = CP_INTERNAL_PHY;
+	cp_set_rxbufsize(cp);
 
 	rc = pci_enable_device(pdev);
 	if (rc)
@@ -1299,6 +1416,7 @@
 	dev->hard_start_xmit = cp_start_xmit;
 	dev->get_stats = cp_get_stats;
 	dev->do_ioctl = cp_ioctl;
+	dev->change_mtu = cp_change_mtu;
 #if 0
 	dev->tx_timeout = cp_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
@@ -1306,6 +1424,11 @@
 #ifdef CP_TX_CHECKSUM
 	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
 #endif
+#if CP_VLAN_TAG_USED
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->vlan_rx_register = cp_vlan_rx_register;
+	dev->vlan_rx_kill_vid = cp_vlan_rx_kill_vid;
+#endif
 
 	dev->irq = pdev->irq;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/8139too.c linux/drivers/net/8139too.c
--- linux.orig/drivers/net/8139too.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/8139too.c	2002-07-20 01:08:21.000000000 +0000
@@ -92,7 +92,7 @@
 */
 
 #define DRV_NAME	"8139too"
-#define DRV_VERSION	"0.9.24"
+#define DRV_VERSION	"0.9.25"
 
 
 #include <linux/config.h>
@@ -109,6 +109,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/completion.h>
+#include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -597,7 +598,6 @@
 static int rtl8139_close (struct net_device *dev);
 static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
-static inline u32 ether_crc (int length, unsigned char *data);
 static void rtl8139_set_rx_mode (struct net_device *dev);
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
@@ -1008,6 +1008,7 @@
 	} else
 #endif
 		tp->phys[0] = 32;
+	tp->mii.phy_id = tp->phys[0];
 
 	/* The lower four bits are the media type. */
 	option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
@@ -2329,7 +2330,7 @@
 
 	if (cmd != SIOCETHTOOL) {
 		/* With SIOCETHTOOL, this would corrupt the pointer.  */
-		data->phy_id &= 0x1f;
+		data->phy_id &= 0x3f;
 		data->reg_num &= 0x1f;
 	}
 
@@ -2397,23 +2398,6 @@
 /* Set or clear the multicast filter for this adaptor.
    This routine is not state sensitive and need not be SMP locked. */
 
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc (int length, unsigned char *data)
-{
-	int crc = -1;
-
-	while (--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
-			crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ?
-			     ethernet_polynomial : 0);
-	}
-
-	return crc;
-}
-
-
 static void __set_rx_mode (struct net_device *dev)
 {
 	struct rtl8139_private *tp = dev->priv;
@@ -2447,7 +2431,7 @@
 		     i++, mclist = mclist->next) {
 			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 
-			mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
+			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 			rx_mode |= AcceptMulticast;
 		}
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/82596.c linux/drivers/net/82596.c
--- linux.orig/drivers/net/82596.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/82596.c	2002-07-20 01:08:27.000000000 +0000
@@ -64,7 +64,7 @@
 #include <asm/pgalloc.h>
 
 static char version[] __initdata =
-	"82596.c $Revision: 1.4 $\n";
+	"82596.c $Revision: 1.5 $\n";
 
 /* DEBUG flags
  */
@@ -421,7 +421,7 @@
 	while (--delcnt && lp->iscp.stat)
 		udelay(10);
 	if (!delcnt) {
-		printk("%s: %s, status %4.4x, cmd %4.4x.\n",
+		printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
 		     dev->name, str, lp->scb.status, lp->scb.command);
 		return -1;
 	}
@@ -435,7 +435,7 @@
 	while (--delcnt && lp->scb.command)
 		udelay(10);
 	if (!delcnt) {
-		printk("%s: %s, status %4.4x, cmd %4.4x.\n",
+		printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
 		     dev->name, str, lp->scb.status, lp->scb.command);
 		return -1;
 	}
@@ -444,6 +444,21 @@
 }
 
 
+static inline int wait_cfg(struct net_device *dev, struct i596_cmd *cmd, int delcnt, char *str)
+{
+	volatile struct i596_cmd *c = cmd;
+	
+	while (--delcnt && c->command)
+		udelay(10);
+	if (!delcnt) {
+		printk(KERN_ERR "%s: %s.\n", dev->name, str);
+		return -1;
+	}
+	else
+		return 0;
+}
+
+ 
 static void i596_display_data(struct net_device *dev)
 {
 	struct i596_private *lp = (struct i596_private *) dev->priv;
@@ -451,37 +466,37 @@
 	struct i596_rfd *rfd;
 	struct i596_rbd *rbd;
 
-	printk("lp and scp at %p, .sysbus = %08lx, .iscp = %p\n",
+	printk(KERN_ERR "lp and scp at %p, .sysbus = %08lx, .iscp = %p\n",
 	       &lp->scp, lp->scp.sysbus, lp->scp.iscp);
-	printk("iscp at %p, iscp.stat = %08lx, .scb = %p\n",
+	printk(KERN_ERR "iscp at %p, iscp.stat = %08lx, .scb = %p\n",
 	       &lp->iscp, lp->iscp.stat, lp->iscp.scb);
-	printk("scb at %p, scb.status = %04x, .command = %04x,"
+	printk(KERN_ERR "scb at %p, scb.status = %04x, .command = %04x,"
 		" .cmd = %p, .rfd = %p\n",
 	       &lp->scb, lp->scb.status, lp->scb.command,
 		lp->scb.cmd, lp->scb.rfd);
-	printk("   errors: crc %lx, align %lx, resource %lx,"
+	printk(KERN_ERR "   errors: crc %lx, align %lx, resource %lx,"
                " over %lx, rcvdt %lx, short %lx\n",
 		lp->scb.crc_err, lp->scb.align_err, lp->scb.resource_err,
 		lp->scb.over_err, lp->scb.rcvdt_err, lp->scb.short_err);
 	cmd = lp->cmd_head;
 	while (cmd != I596_NULL) {
-		printk("cmd at %p, .status = %04x, .command = %04x, .b_next = %p\n",
+		printk(KERN_ERR "cmd at %p, .status = %04x, .command = %04x, .b_next = %p\n",
 		  cmd, cmd->status, cmd->command, cmd->b_next);
 		cmd = cmd->v_next;
 	}
 	rfd = lp->rfd_head;
-	printk("rfd_head = %p\n", rfd);
+	printk(KERN_ERR "rfd_head = %p\n", rfd);
 	do {
-		printk ("   %p .stat %04x, .cmd %04x, b_next %p, rbd %p,"
+		printk(KERN_ERR "   %p .stat %04x, .cmd %04x, b_next %p, rbd %p,"
                         " count %04x\n",
 			rfd, rfd->stat, rfd->cmd, rfd->b_next, rfd->rbd,
 			rfd->count);
 		rfd = rfd->v_next;
 	} while (rfd != lp->rfd_head);
 	rbd = lp->rbd_head;
-	printk("rbd_head = %p\n", rbd);
+	printk(KERN_ERR "rbd_head = %p\n", rbd);
 	do {
-		printk("   %p .count %04x, b_next %p, b_data %p, size %04x\n",
+		printk(KERN_ERR "   %p .count %04x, b_next %p, b_data %p, size %04x\n",
 			rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size);
 		rbd = rbd->v_next;
 	} while (rbd != lp->rbd_head);
@@ -492,11 +507,23 @@
 static void i596_error(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_id;
-	volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
+#ifdef ENABLE_MVME16x_NET
+	if (MACH_IS_MVME16x) {
+		volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
+
+		pcc2[0x28] = 1;
+		pcc2[0x2b] = 0x1d;
+	}
+#endif
+#ifdef ENABLE_BVME6000_NET
+	if (MACH_IS_BVME6000) {
+		volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG;
 
-	pcc2[0x28] = 1;
-	pcc2[0x2b] = 0x1d;
-	printk("%s: Error interrupt\n", dev->name);
+		*ethirq = 1;
+		*ethirq = 3;
+	}
+#endif
+	printk(KERN_ERR "%s: Error interrupt\n", dev->name);
 	i596_display_data(dev);
 }
 #endif
@@ -660,7 +687,14 @@
 
 	lp->cmd_head = lp->scb.cmd = I596_NULL;
 
-	DEB(DEB_INIT,printk("%s: starting i82596.\n", dev->name));
+#ifdef ENABLE_BVME6000_NET
+	if (MACH_IS_BVME6000) {
+		lp->scb.t_on  = 7 * 25;
+		lp->scb.t_off = 1 * 25;
+	}
+#endif
+
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: starting i82596.\n", dev->name));
 
 #if defined(ENABLE_APRICOT)
 	(void) inb(ioaddr + 0x10);
@@ -670,7 +704,7 @@
 
 	if (wait_istat(dev,lp,1000,"initialization timed out"))
 		goto failed;
-	DEB(DEB_INIT,printk("%s: i82596 initialization successful\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: i82596 initialization successful\n", dev->name));
 
 	/* Ensure rx frame/buffer descriptors are tidy */
 	rebuild_rx_bufs(dev);
@@ -694,17 +728,17 @@
 #endif
 
 
-	DEB(DEB_INIT,printk("%s: queuing CmdConfigure\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdConfigure\n", dev->name));
 	memcpy(lp->cf_cmd.i596_config, init_setup, 14);
 	lp->cf_cmd.cmd.command = CmdConfigure;
 	i596_add_cmd(dev, &lp->cf_cmd.cmd);
 
-	DEB(DEB_INIT,printk("%s: queuing CmdSASetup\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name));
 	memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6);
 	lp->sa_cmd.cmd.command = CmdSASetup;
 	i596_add_cmd(dev, &lp->sa_cmd.cmd);
 
-	DEB(DEB_INIT,printk("%s: queuing CmdTDR\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdTDR\n", dev->name));
 	lp->tdr_cmd.cmd.command = CmdTDR;
 	i596_add_cmd(dev, &lp->tdr_cmd.cmd);
 
@@ -714,7 +748,7 @@
 		spin_unlock_irqrestore (&lp->lock, flags);
 		goto failed;
 	}
-	DEB(DEB_INIT,printk("%s: Issuing RX_START\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Issuing RX_START\n", dev->name));
 	lp->scb.command = RX_START;
 	CA(dev);
 
@@ -722,11 +756,11 @@
 
 	if (wait_cmd(dev,lp,1000,"RX_START not processed"))
 		goto failed;
-	DEB(DEB_INIT,printk("%s: Receive unit started OK\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Receive unit started OK\n", dev->name));
 	return 0;
 
 failed:
-	printk("%s: Failed to initialise 82596\n", dev->name);
+	printk(KERN_CRIT "%s: Failed to initialise 82596\n", dev->name);
 	MPU_PORT(dev, PORT_RESET, 0);
 	return -1;
 }
@@ -738,7 +772,7 @@
 	struct i596_rbd *rbd;
 	int frames = 0;
 
-	DEB(DEB_RXFRAME,printk ("i596_rx(), rfd_head %p, rbd_head %p\n",
+	DEB(DEB_RXFRAME,printk(KERN_DEBUG "i596_rx(), rfd_head %p, rbd_head %p\n",
 			lp->rfd_head, lp->rbd_head));
 
 	rfd = lp->rfd_head;		/* Ref next frame to check */
@@ -749,11 +783,11 @@
 		else if (rfd->rbd == lp->rbd_head->b_addr)
 			rbd = lp->rbd_head;
 		else {
-			printk("%s: rbd chain broken!\n", dev->name);
+			printk(KERN_CRIT "%s: rbd chain broken!\n", dev->name);
 			/* XXX Now what? */
 			rbd = I596_NULL;
 		}
-		DEB(DEB_RXFRAME, printk("  rfd %p, rfd.rbd %p, rfd.stat %04x\n",
+		DEB(DEB_RXFRAME, printk(KERN_DEBUG "  rfd %p, rfd.rbd %p, rfd.stat %04x\n",
 			rfd, rfd->rbd, rfd->stat));
 		
 		if (rbd != I596_NULL && ((rfd->stat) & STAT_OK)) {
@@ -794,7 +828,7 @@
 memory_squeeze:
 			if (skb == NULL) {
 				/* XXX tulip.c can defer packets here!! */
-				printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
+				printk(KERN_WARNING "%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
 			}
 			else {
@@ -817,7 +851,7 @@
 			}
 		}
 		else {
-			DEB(DEB_ERRORS, printk("%s: Error, rfd.stat = 0x%04x\n",
+			DEB(DEB_ERRORS, printk(KERN_DEBUG "%s: Error, rfd.stat = 0x%04x\n",
 					dev->name, rfd->stat));
 			lp->stats.rx_errors++;
 			if ((rfd->stat) & 0x0001)
@@ -861,7 +895,7 @@
 		rfd = lp->rfd_head;
 	}
 
-	DEB(DEB_RXFRAME,printk ("frames %d\n", frames));
+	DEB(DEB_RXFRAME,printk(KERN_DEBUG "frames %d\n", frames));
 
 	return 0;
 }
@@ -904,7 +938,7 @@
 {
 	unsigned long flags;
 
-	DEB(DEB_RESET,printk("i596_reset\n"));
+	DEB(DEB_RESET,printk(KERN_DEBUG "i596_reset\n"));
 
 	spin_lock_irqsave (&lp->lock, flags);
 
@@ -932,7 +966,7 @@
 	int ioaddr = dev->base_addr;
 	unsigned long flags;
 
-	DEB(DEB_ADDCMD,printk("i596_add_cmd\n"));
+	DEB(DEB_ADDCMD,printk(KERN_DEBUG "i596_add_cmd\n"));
 
 	cmd->status = 0;
 	cmd->command |= (CMD_EOL | CMD_INTR);
@@ -961,7 +995,7 @@
 		if (tickssofar < ticks_limit)
 			return;
 
-		printk("%s: command unit timed out, status resetting.\n", dev->name);
+		printk(KERN_NOTICE "%s: command unit timed out, status resetting.\n", dev->name);
 
 		i596_reset(dev, lp, ioaddr);
 	}
@@ -971,10 +1005,10 @@
 {
 	int res = 0;
 
-	DEB(DEB_OPEN,printk("%s: i596_open() irq %d.\n", dev->name, dev->irq));
+	DEB(DEB_OPEN,printk(KERN_DEBUG "%s: i596_open() irq %d.\n", dev->name, dev->irq));
 
 	if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
-		printk("%s: IRQ %d not free\n", dev->name, dev->irq);
+		printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
 #ifdef ENABLE_MVME16x_NET
@@ -1004,19 +1038,19 @@
 	int ioaddr = dev->base_addr;
 
 	/* Transmitter timeout, serious problems. */
-	DEB(DEB_ERRORS,printk("%s: transmit timed out, status resetting.\n",
+	DEB(DEB_ERRORS,printk(KERN_ERR "%s: transmit timed out, status resetting.\n",
 			dev->name));
 
 	lp->stats.tx_errors++;
 
 	/* Try to restart the adaptor */
 	if (lp->last_restart == lp->stats.tx_packets) {
-		DEB(DEB_ERRORS,printk ("Resetting board.\n"));
+		DEB(DEB_ERRORS,printk(KERN_ERR "Resetting board.\n"));
 		/* Shutdown and restart */
 		i596_reset (dev, lp, ioaddr);
 	} else {
 		/* Issue a channel attention signal */
-		DEB(DEB_ERRORS,printk ("Kicking board.\n"));
+		DEB(DEB_ERRORS,printk(KERN_ERR "Kicking board.\n"));
 		lp->scb.command = CUC_START | RX_START;
 		CA (dev);
 		lp->last_restart = lp->stats.tx_packets;
@@ -1035,7 +1069,7 @@
 	short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 	dev->trans_start = jiffies;
 
-	DEB(DEB_STARTTX,printk("%s: i596_start_xmit(%x,%x) called\n", dev->name,
+	DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%x) called\n", dev->name,
 				skb->len, (unsigned int)skb->data));
 
 	netif_stop_queue(dev);
@@ -1044,8 +1078,8 @@
 	tbd = lp->tbds + lp->next_tx_cmd;
 
 	if (tx_cmd->cmd.command) {
-		DEB(DEB_ERRORS,printk ("%s: xmit ring full, dropping packet.\n",
-				dev->name));
+		printk(KERN_NOTICE "%s: xmit ring full, dropping packet.\n",
+				dev->name);
 		lp->stats.tx_dropped++;
 
 		dev_kfree_skb(skb);
@@ -1084,7 +1118,7 @@
 {
 	int i;
 
-	printk("i596 0x%p, ", add);
+	printk(KERN_DEBUG "i596 0x%p, ", add);
 	for (i = 0; i < 6; i++)
 		printk(" %02X", add[i + 6]);
 	printk(" -->");
@@ -1106,7 +1140,7 @@
 #ifdef ENABLE_MVME16x_NET
 	if (MACH_IS_MVME16x) {
 		if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
-			printk("Ethernet probe disabled - chip not present\n");
+			printk(KERN_NOTICE "Ethernet probe disabled - chip not present\n");
 			return -ENODEV;
 		}
 		memcpy(eth_addr, (void *) 0xfffc1f2c, 6);	/* YUCK! Get addr from NOVRAM */
@@ -1137,7 +1171,7 @@
 		/* first check nothing is already registered here */
 
 		if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) {
-			printk("82596: IO address 0x%04x in use\n", ioaddr);
+			printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
 			return -EBUSY;
 		}
 
@@ -1171,14 +1205,14 @@
 	}
 
 	ether_setup(dev);
-	DEB(DEB_PROBE,printk("%s: 82596 at %#3lx,", dev->name, dev->base_addr));
+	DEB(DEB_PROBE,printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
 
 	for (i = 0; i < 6; i++)
 		DEB(DEB_PROBE,printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]));
 
 	DEB(DEB_PROBE,printk(" IRQ %d.\n", dev->irq));
 
-	DEB(DEB_PROBE,printk(version));
+	DEB(DEB_PROBE,printk(KERN_INFO "%s", version));
 
 	/* The 82596-specific entries in the device structure. */
 	dev->open = i596_open;
@@ -1192,7 +1226,7 @@
 	dev->priv = (void *)(dev->mem_start);
 
 	lp = (struct i596_private *) dev->priv;
-	DEB(DEB_INIT,printk ("%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n",
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n",
 			dev->name, (unsigned long)lp,
 			sizeof(struct i596_private), (unsigned long)&lp->scb));
 	memset((void *) lp, 0, sizeof(struct i596_private));
@@ -1220,13 +1254,13 @@
 #ifdef ENABLE_BVME6000_NET
 	if (MACH_IS_BVME6000) {
 		if (*(char *) BVME_LOCAL_IRQ_STAT & BVME_ETHERR) {
-			i596_error(BVME_IRQ_I596, NULL, NULL);
+			i596_error(irq, dev_id, regs);
 			return;
 		}
 	}
 #endif
 	if (dev == NULL) {
-		printk("i596_interrupt(): irq %d for unknown device.\n", irq);
+		printk(KERN_ERR "i596_interrupt(): irq %d for unknown device.\n", irq);
 		return;
 	}
 
@@ -1238,7 +1272,7 @@
 	wait_cmd(dev,lp,100,"i596 interrupt, timeout");
 	status = lp->scb.status;
 
-	DEB(DEB_INTS,printk("%s: i596 interrupt, IRQ %d, status %4.4x.\n",
+	DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt, IRQ %d, status %4.4x.\n",
 			dev->name, irq, status));
 
 	ack_cmd = status & 0xf000;
@@ -1247,14 +1281,14 @@
 		struct i596_cmd *ptr;
 
 		if ((status & 0x8000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt completed command.\n", dev->name));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt completed command.\n", dev->name));
 		if ((status & 0x2000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
 
 		while ((lp->cmd_head != I596_NULL) && (lp->cmd_head->status & STAT_C)) {
 			ptr = lp->cmd_head;
 
-			DEB(DEB_STATUS,printk("cmd_head->status = %04x, ->command = %04x\n",
+			DEB(DEB_STATUS,printk(KERN_DEBUG "cmd_head->status = %04x, ->command = %04x\n",
 				       lp->cmd_head->status, lp->cmd_head->command));
 			lp->cmd_head = ptr->v_next;
 			lp->cmd_backlog--;
@@ -1291,20 +1325,21 @@
 				unsigned short status = ((struct tdr_cmd *)ptr)->status;
 
 				if (status & 0x8000) {
-					DEB(DEB_ANY,printk("%s: link ok.\n", dev->name));
+					DEB(DEB_TDR,printk(KERN_INFO "%s: link ok.\n", dev->name));
 				} else {
 					if (status & 0x4000)
-						printk("%s: Transceiver problem.\n", dev->name);
+						printk(KERN_ERR "%s: Transceiver problem.\n", dev->name);
 					if (status & 0x2000)
-						printk("%s: Termination problem.\n", dev->name);
+						printk(KERN_ERR "%s: Termination problem.\n", dev->name);
 					if (status & 0x1000)
-						printk("%s: Short circuit.\n", dev->name);
+						printk(KERN_ERR "%s: Short circuit.\n", dev->name);
 
-					DEB(DEB_TDR,printk("%s: Time %d.\n", dev->name, status & 0x07ff));
+					DEB(DEB_TDR,printk(KERN_INFO "%s: Time %d.\n", dev->name, status & 0x07ff));
 				}
 				break;
 			    }
 			case CmdConfigure:
+			case CmdMulticastList:
 				/* Zap command so set_multicast_list() knows it is free */
 				ptr->command = 0;
 				break;
@@ -1325,12 +1360,12 @@
 	}
 	if ((status & 0x1000) || (status & 0x4000)) {
 		if ((status & 0x4000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt received a frame.\n", dev->name));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt received a frame.\n", dev->name));
 		i596_rx(dev);
 		/* Only RX_START if stopped - RGH 07-07-96 */
 		if (status & 0x1000) {
 			if (netif_running(dev)) {
-				DEB(DEB_ERRORS,printk("%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
+				DEB(DEB_ERRORS,printk(KERN_ERR "%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
 				ack_cmd |= RX_START;
 				lp->stats.rx_errors++;
 				lp->stats.rx_fifo_errors++;
@@ -1364,7 +1399,7 @@
 #endif
 	CA(dev);
 
-	DEB(DEB_INTS,printk("%s: exiting interrupt.\n", dev->name));
+	DEB(DEB_INTS,printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name));
 
 	spin_unlock (&lp->lock);
 	return;
@@ -1377,7 +1412,7 @@
 
 	netif_stop_queue(dev);
 
-	DEB(DEB_INIT,printk("%s: Shutting down ethercard, status was %4.4x.\n",
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
 		       dev->name, lp->scb.status));
 
 	save_flags(flags);
@@ -1434,7 +1469,13 @@
 	struct i596_private *lp = (struct i596_private *) dev->priv;
 	int config = 0, cnt;
 
-	DEB(DEB_MULTI,printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n", dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF", dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
+	DEB(DEB_MULTI,printk(KERN_DEBUG "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
+		dev->name, dev->mc_count,
+		dev->flags & IFF_PROMISC  ? "ON" : "OFF",
+		dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
+
+	if (wait_cfg(dev, &lp->cf_cmd.cmd, 1000, "config change request timed out"))
+		return;
 
 	if ((dev->flags & IFF_PROMISC) && !(lp->cf_cmd.i596_config[8] & 0x01)) {
 		lp->cf_cmd.i596_config[8] |= 0x01;
@@ -1453,20 +1494,15 @@
 		config = 1;
 	}
 	if (config) {
-		if (lp->cf_cmd.cmd.command)
-			printk("%s: config change request already queued\n",
-			       dev->name);
-		else {
-			lp->cf_cmd.cmd.command = CmdConfigure;
-			i596_add_cmd(dev, &lp->cf_cmd.cmd);
-		}
+		lp->cf_cmd.cmd.command = CmdConfigure;
+		i596_add_cmd(dev, &lp->cf_cmd.cmd);
 	}
 
 	cnt = dev->mc_count;
 	if (cnt > MAX_MC_CNT)
 	{
 		cnt = MAX_MC_CNT;
-		printk("%s: Only %d multicast addresses supported",
+		printk(KERN_ERR "%s: Only %d multicast addresses supported",
 			dev->name, cnt);
 	}
 	
@@ -1475,6 +1511,8 @@
 		unsigned char *cp;
 		struct mc_cmd *cmd;
 
+		if (wait_cfg(dev, &lp->mc_cmd.cmd, 1000, "multicast list change request timed out"))
+			return;
 		cmd = &lp->mc_cmd;
 		cmd->cmd.command = CmdMulticastList;
 		cmd->mc_cnt = dev->mc_count * 6;
@@ -1482,7 +1520,7 @@
 		for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) {
 			memcpy(cp, dmi->dmi_addr, 6);
 			if (i596_debug > 1)
-				DEB(DEB_MULTI,printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
+				DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
 						dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5]));
 		}
 		i596_add_cmd(dev, &cmd->cmd);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/8390.c linux/drivers/net/8390.c
--- linux.orig/drivers/net/8390.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/8390.c	2002-07-20 01:08:25.000000000 +0000
@@ -68,6 +68,7 @@
 #include <linux/in.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -885,27 +886,6 @@
 }
 
 /*
- * Update the given Autodin II CRC value with another data byte.
- */
-
-static inline u32 update_crc(u8 byte, u32 current_crc)
-{
-	int bit;
-	u8 ah = 0;
-	for (bit=0; bit<8; bit++) 
-	{
-		u8 carry = (current_crc>>31);
-		current_crc <<= 1;
-		ah = ((ah<<1) | carry) ^ byte;
-		if (ah&1)
-			current_crc ^= 0x04C11DB7;	/* CRC polynomial */
-		ah >>= 1;
-		byte >>= 1;
-	}
-	return current_crc;
-}
-
-/*
  * Form the 64 bit 8390 multicast table from the linked list of addresses
  * associated with this dev structure.
  */
@@ -916,16 +896,13 @@
 
 	for (dmi=dev->mc_list; dmi; dmi=dmi->next) 
 	{
-		int i;
 		u32 crc;
 		if (dmi->dmi_addrlen != ETH_ALEN) 
 		{
 			printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
 			continue;
 		}
-		crc = 0xffffffff;	/* initial CRC value */
-		for (i=0; i<ETH_ALEN; i++)
-			crc = update_crc(dmi->dmi_addr[i], crc);
+		crc = ether_crc(ETH_ALEN, dmi->dmi_addr);
 		/* 
 		 * The 8390 uses the 6 most significant bits of the
 		 * CRC to index the multicast table.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/8390.h linux/drivers/net/8390.h
--- linux.orig/drivers/net/8390.h	2001-11-22 19:48:14.000000000 +0000
+++ linux/drivers/net/8390.h	2002-07-20 01:08:27.000000000 +0000
@@ -112,13 +112,24 @@
 
 /*
  *	Only generate indirect loads given a machine that needs them.
+ *      - removed AMIGA_PCMCIA from this list, handled as ISA io now
  */
  
-#if defined(CONFIG_MAC) || defined(CONFIG_AMIGA_PCMCIA) || \
+#if defined(CONFIG_MAC) ||  \
     defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE) || \
     defined(CONFIG_HYDRA) || defined(CONFIG_HYDRA_MODULE) || \
     defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE)
 #define EI_SHIFT(x)	(ei_local->reg_offset[x])
+#undef inb
+#undef inb_p
+#undef outb
+#undef outb_p
+
+#define inb(port)   in_8(port)
+#define outb(val,port)  out_8(port,val)
+#define inb_p(port)   in_8(port)
+#define outb_p(val,port)  out_8(port,val)
+
 #else
 #define EI_SHIFT(x)	(x)
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/Config.in linux/drivers/net/Config.in
--- linux.orig/drivers/net/Config.in	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/Config.in	2002-07-20 01:08:24.000000000 +0000
@@ -3,7 +3,6 @@
 #
 
 source drivers/net/arcnet/Config.in
-source drivers/net/appletalk/Config.in
 
 tristate 'Dummy net driver support' CONFIG_DUMMY
 tristate 'Bonding driver support' CONFIG_BONDING
@@ -62,6 +61,9 @@
    if [ "$CONFIG_MIPS_AU1000" = "y" ]; then
       bool '  MIPS AU1000 Ethernet support' CONFIG_MIPS_AU1000_ENET
    fi
+   if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+      tristate '  SB1250 Ethernet support' CONFIG_NET_SB1250_MAC
+   fi
    if [ "$CONFIG_SGI_IP27" = "y" ]; then
       bool '  SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH
    fi
@@ -153,7 +155,7 @@
    fi
    if [ "$CONFIG_NET_PCI" = "y" ]; then
       dep_tristate '    AMD PCnet32 PCI support' CONFIG_PCNET32 $CONFIG_PCI
-      dep_tristate '    Adaptec Starfire support (EXPERIMENTAL)' CONFIG_ADAPTEC_STARFIRE $CONFIG_PCI $CONFIG_EXPERIMENTAL
+      dep_tristate '    Adaptec Starfire/DuraLAN support' CONFIG_ADAPTEC_STARFIRE $CONFIG_PCI
       if [ "$CONFIG_ISA" = "y" -o "$CONFIG_EISA" = "y" ]; then
 	 dep_tristate '    Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 $CONFIG_EXPERIMENTAL
       fi
@@ -161,6 +163,7 @@
       dep_tristate '    Apricot Xen-II on board Ethernet' CONFIG_APRICOT $CONFIG_ISA
       dep_tristate '    CS89x0 support' CONFIG_CS89x0 $CONFIG_ISA
       dep_tristate '    DECchip Tulip (dc21x4x) PCI support' CONFIG_TULIP $CONFIG_PCI
+      dep_tristate '    TOSHIBA TC35815 Ethernet support' CONFIG_TC35815 $CONFIG_PCI
       if [ "$CONFIG_TULIP" = "y" -o "$CONFIG_TULIP" = "m" ]; then
          dep_bool '      New bus configuration (EXPERIMENTAL)' CONFIG_TULIP_MWI $CONFIG_EXPERIMENTAL
          bool '      Use PCI shared mem for NIC registers' CONFIG_TULIP_MMIO
@@ -214,11 +217,14 @@
       bool '  SGI Seeq ethernet controller support' CONFIG_SGISEEQ
    fi
    if [ "$CONFIG_DECSTATION" = "y" ]; then
-      bool '  DEC LANCE ethernet controller support' CONFIG_DECLANCE
-   fi 
+      tristate '  DEC LANCE ethernet controller support' CONFIG_DECLANCE
+   fi
    if [ "$CONFIG_BAGET_MIPS" = "y" ]; then
       tristate '  Baget AMD LANCE support' CONFIG_BAGETLANCE
    fi
+   if [ "$CONFIG_NEC_OSPREY" = "y" ]; then
+      bool '  Memory-mapped onboard NE2000-compatible ethernet' CONFIG_NE2000
+   fi
 fi
 
 endmenu
@@ -240,6 +246,7 @@
 dep_tristate 'Packet Engines Hamachi GNIC-II support' CONFIG_HAMACHI $CONFIG_PCI
 dep_tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN $CONFIG_PCI
+dep_tristate 'Broadcom Tigon3 support' CONFIG_TIGON3 $CONFIG_PCI
 
 endmenu
 
@@ -281,7 +288,7 @@
       dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
    fi
    if [ ! "$CONFIG_ATM" = "n" ]; then
-      dep_tristate '  PPP over ATM (EXPERIMENTAL)' CONFIG_PPPOATM $CONFIG_PPP
+      dep_tristate '  PPP over ATM (EXPERIMENTAL)' CONFIG_PPPOATM $CONFIG_PPP $CONFIG_EXPERIMENTAL
    fi
 fi
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/Makefile linux/drivers/net/Makefile
--- linux.orig/drivers/net/Makefile	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/Makefile	2002-07-20 01:08:30.000000000 +0000
@@ -37,7 +37,7 @@
 subdir-$(CONFIG_WAN) += wan
 subdir-$(CONFIG_NET_FC) += fc
 subdir-$(CONFIG_ARCNET) += arcnet
-subdir-$(CONFIG_APPLETALK) += appletalk
+subdir-$(CONFIG_DEV_APPLETALK) += appletalk
 subdir-$(CONFIG_SK98LIN) += sk98lin
 subdir-$(CONFIG_SKFP) += skfp
 
@@ -78,6 +78,8 @@
 obj-$(CONFIG_NS83820) += ns83820.o
 obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_FEALNX) += fealnx.o mii.o
+obj-$(CONFIG_TC35815) += tc35815.o
+obj-$(CONFIG_TIGON3) += tg3.o
 
 ifeq ($(CONFIG_SK98LIN),y)
 obj-y += sk98lin/sk98lin.o
@@ -129,6 +131,7 @@
 obj-$(CONFIG_ES3210) += es3210.o 8390.o
 obj-$(CONFIG_LNE390) += lne390.o 8390.o
 obj-$(CONFIG_NE3210) += ne3210.o 8390.o
+obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
 
 obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
 obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
@@ -149,6 +152,7 @@
 obj-$(CONFIG_DE620) += de620.o
 obj-$(CONFIG_AT1500) += lance.o
 obj-$(CONFIG_LANCE) += lance.o
+obj-$(CONFIG_SUN3_82586) += sun3_82586.o
 obj-$(CONFIG_SUN3LANCE) += sun3lance.o
 obj-$(CONFIG_DEFXX) += defxx.o
 obj-$(CONFIG_SGISEEQ) += sgiseeq.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/Space.c linux/drivers/net/Space.c
--- linux.orig/drivers/net/Space.c	2001-09-13 22:21:32.000000000 +0000
+++ linux/drivers/net/Space.c	2002-07-20 01:08:25.000000000 +0000
@@ -86,6 +86,7 @@
 extern int sgiseeq_probe(struct net_device *);
 extern int atarilance_probe(struct net_device *);
 extern int sun3lance_probe(struct net_device *);
+extern int sun3_82586_probe(struct net_device *);
 extern int apne_probe(struct net_device *);
 extern int bionet_probe(struct net_device *);
 extern int pamsnet_probe(struct net_device *);
@@ -96,7 +97,7 @@
 extern int mvme147lance_probe(struct net_device *dev);
 extern int tc515_probe(struct net_device *dev);
 extern int lance_probe(struct net_device *dev);
-extern int mace68k_probe(struct net_device *dev);
+extern int mace_probe(struct net_device *dev);
 extern int macsonic_probe(struct net_device *dev);
 extern int mac8390_probe(struct net_device *dev);
 extern int mac89x0_probe(struct net_device *dev);
@@ -332,6 +333,9 @@
 #ifdef CONFIG_SUN3LANCE         /* sun3 onboard Lance chip */
 	{sun3lance_probe, 0},
 #endif
+#ifdef CONFIG_SUN3_82586        /* sun3 onboard Intel 82586 chip */
+	{sun3_82586_probe, 0},
+#endif
 #ifdef CONFIG_APNE		/* A1200 PCMCIA NE2000 */
 	{apne_probe, 0},
 #endif
@@ -348,7 +352,7 @@
 	{mvme147lance_probe, 0},
 #endif
 #ifdef CONFIG_MACMACE		/* Mac 68k Quadra AV builtin Ethernet */
-	{mace68k_probe, 0},
+	{mace_probe, 0},
 #endif
 #ifdef CONFIG_MACSONIC		/* Mac SONIC-based Ethernet of all sorts */ 
 	{macsonic_probe, 0},
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/a2065.c linux/drivers/net/a2065.c
--- linux.orig/drivers/net/a2065.c	2001-10-17 04:56:29.000000000 +0000
+++ linux/drivers/net/a2065.c	2002-07-20 01:08:22.000000000 +0000
@@ -6,6 +6,7 @@
  * Fixes and tips by:
  *	- Janos Farkas (CHEXUM@sparta.banki.hu)
  *	- Jes Degn Soerensen (jds@kom.auc.dk)
+ *	- Matt Domsch (Matt_Domsch@dell.com)
  *
  * ----------------------------------------------------------------------------
  *
@@ -47,9 +48,10 @@
 #include <linux/string.h>
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 
 #include <asm/bitops.h>
-#include <asm/io.h>
+
 #include <asm/irq.h>
 #include <linux/errno.h>
 
@@ -494,15 +496,15 @@
 
 	last_dev = dev;
 
+	/* Stop the Lance */
+	ll->rap = LE_CSR0;
+	ll->rdp = LE_C0_STOP;
+
 	/* Install the Interrupt handler */
 	ret = request_irq(IRQ_AMIGA_PORTS, lance_interrupt, SA_SHIRQ,
 			  dev->name, dev);
 	if (ret) return ret;
 
-	/* Stop the Lance */
-	ll->rap = LE_CSR0;
-	ll->rdp = LE_C0_STOP;
-
 	load_csrs (lp);
 	lance_init_ring (dev);
 
@@ -638,8 +640,8 @@
 	volatile u16 *mcast_table = (u16 *)&ib->filter;
 	struct dev_mc_list *dmi=dev->mc_list;
 	char *addrs;
-	int i, j, bit, byte;
-	u32 crc, poly = CRC_POLYNOMIAL_LE;
+	int i;
+	u32 crc;
 	
 	/* set all multicast bits */
 	if (dev->flags & IFF_ALLMULTI){ 
@@ -660,21 +662,7 @@
 		if (!(*addrs & 1))
 			continue;
 		
-		crc = 0xffffffff;
-		for (byte = 0; byte < 6; byte++)
-			for (bit = *addrs++, j = 0; j < 8; j++, bit>>=1)
-			{
-				int test;
-
-				test = ((bit ^ crc) & 0x01);
-				crc >>= 1;
-
-				if (test)
-				{
-					crc = crc ^ poly;
-				}
-			}
-		
+		crc = ether_crc_le(6, addrs);
 		crc = crc >> 26;
 		mcast_table [crc >> 4] |= 1 << (crc & 0xf);
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/a2065.h linux/drivers/net/a2065.h
--- linux.orig/drivers/net/a2065.h	2000-01-26 20:45:20.000000000 +0000
+++ linux/drivers/net/a2065.h	2002-07-20 01:08:27.000000000 +0000
@@ -43,9 +43,6 @@
 };
 
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 /*
  *		Am7990 Control and Status Registers
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ac3200.c linux/drivers/net/ac3200.c
--- linux.orig/drivers/net/ac3200.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/ac3200.c	2002-07-20 01:08:25.000000000 +0000
@@ -346,9 +346,11 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
-MODULE_PARM_DESC(io, "ac3200 I/O base adress(es)");
-MODULE_PARM_DESC(irq, "ac3200 IRQ number(s)");
-MODULE_PARM_DESC(mem, "ac3200 Memory base address(es)");
+MODULE_PARM_DESC(io, "I/O base adress(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(mem, "Memory base address(es)");
+MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
+MODULE_LICENSE("GPL");
 
 int
 init_module(void)
@@ -395,7 +397,6 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/acenic.c linux/drivers/net/acenic.c
--- linux.orig/drivers/net/acenic.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/acenic.c	2002-07-20 01:08:36.000000000 +0000
@@ -2,7 +2,7 @@
  * acenic.c: Linux driver for the Alteon AceNIC Gigabit Ethernet card
  *           and other Tigon based cards.
  *
- * Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>.
+ * Copyright 1998-2002 by Jes Sorensen, <jes@trained-monkey.org>.
  *
  * Thanks to Alteon and 3Com for providing hardware and documentation
  * enabling me to write this driver.
@@ -30,6 +30,7 @@
  *   Pierrick Pinasseau (CERN): For lending me an Ultra 5 to test the
  *                              driver under Linux/Sparc64
  *   Matt Domsch <Matt_Domsch@dell.com>: Detect Alteon 1000baseT cards
+ *                                       ETHTOOL_GDRVINFO support
  *   Chip Salzenberg <chip@valinux.com>: Fix race condition between tx
  *                                       handler and close() cleanup.
  *   Ken Aaker <kdaaker@rchland.vnet.ibm.com>: Correct check for whether
@@ -65,6 +66,10 @@
 #include <linux/highmem.h>
 #include <linux/sockios.h>
 
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#include <linux/if_vlan.h>
+#endif
+
 #ifdef SIOCETHTOOL
 #include <linux/ethtool.h>
 #endif
@@ -83,8 +88,10 @@
 
 #ifdef CONFIG_ACENIC_OMIT_TIGON_I
 #define ACE_IS_TIGON_I(ap)	0
+#define ACE_TX_RING_ENTRIES(ap)	MAX_TX_RING_ENTRIES
 #else
 #define ACE_IS_TIGON_I(ap)	(ap->version == 1)
+#define ACE_TX_RING_ENTRIES(ap)	ap->tx_ring_entries
 #endif
 
 #ifndef PCI_VENDOR_ID_ALTEON
@@ -113,6 +120,10 @@
 #ifndef PCI_DEVICE_ID_FARALLON_PN9000SX
 #define PCI_DEVICE_ID_FARALLON_PN9000SX	0x1a
 #endif
+#ifndef PCI_DEVICE_ID_FARALLON_PN9100T
+#define PCI_DEVICE_ID_FARALLON_PN9100T  0xfa
+#endif
+
 #ifndef PCI_VENDOR_ID_SGI
 #define PCI_VENDOR_ID_SGI		0x10a9
 #endif
@@ -137,6 +148,9 @@
 	 */
 	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_FARALLON_PN9000SX,
 	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
+	{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_FARALLON_PN9100T,
+	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
+
 	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_ACENIC,
 	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
 	{ }
@@ -314,6 +328,14 @@
 #define BOARD_IDX_STATIC	0
 #define BOARD_IDX_OVERFLOW	-1
 
+#if (defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)) && \
+	defined(NETIF_F_HW_VLAN_RX)
+#define ACENIC_DO_VLAN		1
+#define ACE_RCB_VLAN_FLAG	RCB_FLG_VLAN_ASSIST
+#else
+#define ACENIC_DO_VLAN		0
+#define ACE_RCB_VLAN_FLAG	0
+#endif
 
 #include "acenic.h"
 
@@ -553,7 +575,7 @@
 static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
 
 static char version[] __initdata = 
-  "acenic.c: v0.85 11/08/2001  Jes Sorensen, linux-acenic@SunSITE.dk\n"
+  "acenic.c: v0.89 03/15/2002  Jes Sorensen, linux-acenic@SunSITE.dk\n"
   "                            http://home.cern.ch/~jes/gige/acenic.html\n";
 
 static struct net_device *root_dev;
@@ -596,6 +618,8 @@
 		 */
 		    !((pdev->vendor == PCI_VENDOR_ID_DEC) &&
 		      (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX)) &&
+		    !((pdev->vendor == PCI_VENDOR_ID_ALTEON) &&
+		      (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T)) &&
 		    !((pdev->vendor == PCI_VENDOR_ID_SGI) &&
 		      (pdev->device == PCI_DEVICE_ID_SGI_ACENIC)))
 			continue;
@@ -620,10 +644,14 @@
 		ap = dev->priv;
 		ap->pdev = pdev;
 
-		dev->irq = pdev->irq;
 		dev->open = &ace_open;
 		dev->hard_start_xmit = &ace_start_xmit;
 		dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+#if ACENIC_DO_VLAN
+		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+		dev->vlan_rx_register = ace_vlan_rx_register;
+		dev->vlan_rx_kill_vid = ace_vlan_rx_kill_vid;
+#endif
 		if (1) {
 			static void ace_watchdog(struct net_device *dev);
 			dev->tx_timeout = &ace_watchdog;
@@ -689,6 +717,13 @@
 
 		switch(pdev->vendor) {
 		case PCI_VENDOR_ID_ALTEON:
+			if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T) {
+				strncpy(ap->name, "Farallon PN9100-T "
+					"Gigabit Ethernet", sizeof (ap->name));
+				printk(KERN_INFO "%s: Farallon PN9100-T ",
+				       dev->name);
+				break;
+			}
 			strncpy(ap->name, "AceNIC Gigabit Ethernet",
 				sizeof (ap->name));
 			printk(KERN_INFO "%s: Alteon AceNIC ", dev->name);
@@ -725,9 +760,9 @@
 		ap->name [sizeof (ap->name) - 1] = '\0';
 		printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr);
 #ifdef __sparc__
-		printk("irq %s\n", __irq_itoa(dev->irq));
+		printk("irq %s\n", __irq_itoa(pdev->irq));
 #else
-		printk("irq %i\n", dev->irq);
+		printk("irq %i\n", pdev->irq);
 #endif
 
 #ifdef CONFIG_ACENIC_OMIT_TIGON_I
@@ -960,6 +995,13 @@
 				    ap->evt_ring_dma);
 		ap->evt_ring = NULL;
 	}
+	if (ap->tx_ring != NULL && !ACE_IS_TIGON_I(ap)) {
+		size = (sizeof(struct tx_desc) * MAX_TX_RING_ENTRIES);
+		pci_free_consistent(ap->pdev, size, ap->tx_ring,
+				    ap->tx_ring_dma);
+	}
+	ap->tx_ring = NULL;
+
 	if (ap->evt_prd != NULL) {
 		pci_free_consistent(ap->pdev, sizeof(u32),
 				    (void *)ap->evt_prd, ap->evt_prd_dma);
@@ -1006,12 +1048,19 @@
 	if (ap->evt_ring == NULL)
 		goto fail;
 
-	size = (sizeof(struct tx_desc) * TX_RING_ENTRIES);
+	/*
+	 * Only allocate a host TX ring for the Tigon II, the Tigon I
+	 * has to use PCI registers for this ;-(
+	 */
+	if (!ACE_IS_TIGON_I(ap)) {
+		size = (sizeof(struct tx_desc) * MAX_TX_RING_ENTRIES);
 
-	ap->tx_ring = pci_alloc_consistent(ap->pdev, size, &ap->tx_ring_dma);
+		ap->tx_ring = pci_alloc_consistent(ap->pdev, size,
+						   &ap->tx_ring_dma);
 
-	if (ap->tx_ring == NULL)
-		goto fail;
+		if (ap->tx_ring == NULL)
+			goto fail;
+	}
 
 	ap->evt_prd = pci_alloc_consistent(ap->pdev, sizeof(u32),
 					   &ap->evt_prd_dma);
@@ -1086,6 +1135,7 @@
 	struct ace_private *ap;
 	struct ace_regs *regs;
 	struct ace_info *info = NULL;
+	struct pci_dev *pdev;
 	unsigned long myjif;
 	u64 tmp_ptr;
 	u32 tig_ver, mac1, mac2, tmp, pci_state;
@@ -1144,6 +1194,7 @@
 		       tigonFwReleaseFix);
 		writel(0, &regs->LocalCtrl);
 		ap->version = 1;
+		ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES;
 		break;
 #endif
 	case 6:
@@ -1159,6 +1210,7 @@
 		writel(SRAM_BANK_512K, &regs->LocalCtrl);
 		writel(SYNC_SRAM_TIMING, &regs->MiscCfg);
 		ap->version = 2;
+		ap->tx_ring_entries = MAX_TX_RING_ENTRIES;
 		break;
 	default:
 		printk(KERN_WARNING "  Unsupported Tigon version detected "
@@ -1224,7 +1276,8 @@
 	 * Ie. having two NICs in the machine, one will have the cache
 	 * line set at boot time, the other will not.
 	 */
-	pci_read_config_byte(ap->pdev, PCI_CACHE_LINE_SIZE, &cache_size);
+	pdev = ap->pdev;
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_size);
 	cache_size <<= 2;
 	if (cache_size != SMP_CACHE_BYTES) {
 		printk(KERN_INFO "  PCI cache line size set incorrectly "
@@ -1233,7 +1286,7 @@
 			printk("expecting %i\n", SMP_CACHE_BYTES);
 		else {
 			printk("correcting to %i\n", SMP_CACHE_BYTES);
-			pci_write_config_byte(ap->pdev, PCI_CACHE_LINE_SIZE,
+			pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
 					      SMP_CACHE_BYTES >> 2);
 		}
 	}
@@ -1265,7 +1318,7 @@
 		    dis_pci_mem_inval[board_idx]) {
 			if (ap->pci_command & PCI_COMMAND_INVALIDATE) {
 				ap->pci_command &= ~PCI_COMMAND_INVALIDATE;
-				pci_write_config_word(ap->pdev, PCI_COMMAND,
+				pci_write_config_word(pdev, PCI_COMMAND,
 						      ap->pci_command);
 				printk(KERN_INFO "  Disabling PCI memory "
 				       "write and invalidate\n");
@@ -1292,7 +1345,7 @@
 				       "supported, PCI write and invalidate "
 				       "disabled\n", SMP_CACHE_BYTES);
 				ap->pci_command &= ~PCI_COMMAND_INVALIDATE;
-				pci_write_config_word(ap->pdev, PCI_COMMAND,
+				pci_write_config_word(pdev, PCI_COMMAND,
 						      ap->pci_command);
 			}
 		}
@@ -1334,16 +1387,16 @@
 	if (!(ap->pci_command & PCI_COMMAND_FAST_BACK)) {
 		printk(KERN_INFO "  Enabling PCI Fast Back to Back\n");
 		ap->pci_command |= PCI_COMMAND_FAST_BACK;
-		pci_write_config_word(ap->pdev, PCI_COMMAND, ap->pci_command);
+		pci_write_config_word(pdev, PCI_COMMAND, ap->pci_command);
 	}
 #endif
 		
 	/*
 	 * Configure DMA attributes.
 	 */
-	if (!pci_set_dma_mask(ap->pdev, 0xffffffffffffffffULL)) {
+	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
 		ap->pci_using_dac = 1;
-	} else if (!pci_set_dma_mask(ap->pdev, 0xffffffffULL)) {
+	} else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) {
 		ap->pci_using_dac = 0;
 	} else {
 		ecode = -ENODEV;
@@ -1370,12 +1423,14 @@
 		goto init_error;
 	}
 
-	ecode = request_irq(dev->irq, ace_interrupt, SA_SHIRQ, dev->name, dev);
+	ecode = request_irq(pdev->irq, ace_interrupt, SA_SHIRQ,
+			    dev->name, dev);
 	if (ecode) {
 		printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
-		       dev->name, dev->irq);
+		       dev->name, pdev->irq);
 		goto init_error;
-	}
+	} else
+		dev->irq = pdev->irq;
 
 	/*
 	 * Register the device here to be able to catch allocated
@@ -1386,7 +1441,7 @@
 
 #ifdef INDEX_DEBUG
 	spin_lock_init(&ap->debug_lock);
-	ap->last_tx = TX_RING_ENTRIES - 1;
+	ap->last_tx = ACE_TX_RING_ENTRIES(ap) - 1;
 	ap->last_std_rx = 0;
 	ap->last_mini_rx = 0;
 #endif
@@ -1427,7 +1482,8 @@
 
 	set_aceaddr(&info->rx_std_ctrl.rngptr, ap->rx_ring_base_dma);
 	info->rx_std_ctrl.max_len = ACE_STD_MTU + ETH_HLEN + 4;
-	info->rx_std_ctrl.flags = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR;
+	info->rx_std_ctrl.flags =
+	  RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
 
 	memset(ap->rx_std_ring, 0,
 	       RX_STD_RING_ENTRIES * sizeof(struct rx_desc));
@@ -1442,7 +1498,8 @@
 		    (ap->rx_ring_base_dma +
 		     (sizeof(struct rx_desc) * RX_STD_RING_ENTRIES)));
 	info->rx_jumbo_ctrl.max_len = 0;
-	info->rx_jumbo_ctrl.flags = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR;
+	info->rx_jumbo_ctrl.flags =
+	  RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
 
 	memset(ap->rx_jumbo_ring, 0,
 	       RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc));
@@ -1464,7 +1521,7 @@
 			       RX_JUMBO_RING_ENTRIES))));
 		info->rx_mini_ctrl.max_len = ACE_MINI_SIZE;
 		info->rx_mini_ctrl.flags = 
-			RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR;
+		  RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|ACE_RCB_VLAN_FLAG;
 
 		for (i = 0; i < RX_MINI_RING_ENTRIES; i++)
 			ap->rx_mini_ring[i].flags =
@@ -1494,12 +1551,30 @@
 	*(ap->rx_ret_prd) = 0;
 
 	writel(TX_RING_BASE, &regs->WinBase);
-	memset(ap->tx_ring, 0, TX_RING_ENTRIES * sizeof(struct tx_desc));
 
-	set_aceaddr(&info->tx_ctrl.rngptr, ap->tx_ring_dma);
+	if (ACE_IS_TIGON_I(ap)) {
+		ap->tx_ring = (struct tx_desc *)regs->Window;
+		for (i = 0; i < (TIGON_I_TX_RING_ENTRIES * 
+				 sizeof(struct tx_desc) / 4); i++) {
+			writel(0, (unsigned long)ap->tx_ring + i * 4);
+		}
+
+		set_aceaddr(&info->tx_ctrl.rngptr, TX_RING_BASE);
+	} else {
+		memset(ap->tx_ring, 0,
+		       MAX_TX_RING_ENTRIES * sizeof(struct tx_desc));
+
+		set_aceaddr(&info->tx_ctrl.rngptr, ap->tx_ring_dma);
+	}
 
-	info->tx_ctrl.max_len = TX_RING_ENTRIES;
-	tmp = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|RCB_FLG_TX_HOST_RING;
+	info->tx_ctrl.max_len = ACE_TX_RING_ENTRIES(ap);
+	tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
+
+	/*
+	 * The Tigon I does not like having the TX ring in host memory ;-(
+	 */
+	if (!ACE_IS_TIGON_I(ap))
+		tmp |= RCB_FLG_TX_HOST_RING;
 #if TX_COAL_INTS_ONLY
 	tmp |= RCB_FLG_COAL_INT_ONLY;
 #endif
@@ -1528,7 +1603,7 @@
 	ace_set_rxtx_parms(dev, 0);
 
 	if (board_idx == BOARD_IDX_OVERFLOW) {
-		printk(KERN_WARNING "%s: more then %i NICs detected, "
+		printk(KERN_WARNING "%s: more than %i NICs detected, "
 		       "ignoring module parameters!\n",
 		       dev->name, ACE_MAX_MOD_PARMS);
 	} else if (board_idx >= 0) {
@@ -2201,7 +2276,13 @@
 			skb->ip_summed = CHECKSUM_NONE;
 		}
 
-		netif_rx(skb);		/* send it up */
+		/* send it up */
+#if ACENIC_DO_VLAN
+		if (ap->vlgrp && (bd_flags & BD_FLG_VLAN_TAG)) {
+			vlan_hwaccel_rx(skb, ap->vlgrp, retdesc->vlan);
+		} else
+#endif
+			netif_rx(skb);
 
 		dev->last_rx = jiffies;
 		ap->stats.rx_packets++;
@@ -2260,7 +2341,7 @@
 			info->skb = NULL;
 		}
 
-		idx = (idx + 1) % TX_RING_ENTRIES;
+		idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
 	} while (idx != txcsm);
 
 	if (netif_queue_stopped(dev))
@@ -2353,7 +2434,7 @@
 		 * update releases enough of space, otherwise we just
 		 * wait for device to make more work.
 		 */
-		if (!tx_ring_full(txcsm, ap->tx_prd))
+		if (!tx_ring_full(ap, txcsm, ap->tx_prd))
 			ace_tx_int(dev, txcsm, idx);
 	}
 
@@ -2425,6 +2506,37 @@
 }
 
 
+#if ACENIC_DO_VLAN
+static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct ace_private *ap = dev->priv;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	ap->vlgrp = grp;
+
+	restore_flags(flags);
+}
+
+
+static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct ace_private *ap = dev->priv;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	if (ap->vlgrp)
+		ap->vlgrp->vlan_devices[vid] = NULL;
+
+	restore_flags(flags);
+}
+#endif /* ACENIC_DO_VLAN */
+
+
 static int ace_open(struct net_device *dev)
 {
 	struct ace_private *ap;
@@ -2527,7 +2639,7 @@
 	save_flags(flags);
 	cli();
 
-	for (i = 0; i < TX_RING_ENTRIES; i++) {
+	for (i = 0; i < ACE_TX_RING_ENTRIES(ap); i++) {
 		struct sk_buff *skb;
 		dma_addr_t mapping;
 		struct tx_ring_info *info;
@@ -2537,7 +2649,13 @@
 		mapping = pci_unmap_addr(info, mapping);
 
 		if (mapping) {
-			memset(ap->tx_ring + i, 0, sizeof(struct tx_desc));
+			if (ACE_IS_TIGON_I(ap)) {
+				writel(0, &ap->tx_ring[i].addr.addrhi);
+				writel(0, &ap->tx_ring[i].addr.addrlo);
+				writel(0, &ap->tx_ring[i].flagsize);
+			} else
+				memset(ap->tx_ring + i, 0,
+				       sizeof(struct tx_desc));
 			pci_unmap_page(ap->pdev, mapping,
 				       pci_unmap_len(info, maplen),
 				       PCI_DMA_TODEVICE);
@@ -2562,6 +2680,7 @@
 	return 0;
 }
 
+
 static inline dma_addr_t
 ace_map_tx_skb(struct ace_private *ap, struct sk_buff *skb,
 	       struct sk_buff *tail, u32 idx)
@@ -2582,15 +2701,28 @@
 
 
 static inline void
-ace_load_tx_bd(struct tx_desc *desc, u64 addr, u32 flagsize)
+ace_load_tx_bd(struct ace_private *ap, struct tx_desc *desc, u64 addr,
+	       u32 flagsize, u32 vlan_tag)
 {
 #if !USE_TX_COAL_NOW
 	flagsize &= ~BD_FLG_COAL_NOW;
 #endif
 
-	desc->addr.addrhi = addr >> 32;
-	desc->addr.addrlo = addr;
-	desc->flagsize = flagsize;
+	if (ACE_IS_TIGON_I(ap)) {
+		writel(addr >> 32, &desc->addr.addrhi);
+		writel(addr & 0xffffffff, &desc->addr.addrlo);
+		writel(flagsize, &desc->flagsize);
+#if ACENIC_DO_VLAN
+		writel(vlan_tag, &desc->vlanres);
+#endif
+	} else {
+		desc->addr.addrhi = addr >> 32;
+		desc->addr.addrlo = addr;
+		desc->flagsize = flagsize;
+#if ACENIC_DO_VLAN
+		desc->vlanres = vlan_tag;
+#endif
+	}
 }
 
 
@@ -2607,11 +2739,10 @@
 	if (early_stop_netif_stop_queue(dev))
  		return 1;
 
-
 restart:
 	idx = ap->tx_prd;
 
-	if (tx_ring_full(ap->tx_ret_csm, idx))
+	if (tx_ring_full(ap, ap->tx_ret_csm, idx))
 		goto overflow;
 
 #if MAX_SKB_FRAGS
@@ -2619,33 +2750,47 @@
 #endif
 	{
 		dma_addr_t mapping;
+		u32 vlan_tag = 0;
 
 		mapping = ace_map_tx_skb(ap, skb, skb, idx);
 		flagsize = (skb->len << 16) | (BD_FLG_END);
 		if (skb->ip_summed == CHECKSUM_HW)
 			flagsize |= BD_FLG_TCP_UDP_SUM;
+#if ACENIC_DO_VLAN
+		if (vlan_tx_tag_present(skb)) {
+			flagsize |= BD_FLG_VLAN_TAG;
+			vlan_tag = vlan_tx_tag_get(skb);
+		}
+#endif
 		desc = ap->tx_ring + idx;
-		idx = (idx + 1) % TX_RING_ENTRIES;
+		idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
 
 		/* Look at ace_tx_int for explanations. */
-		if (tx_ring_full(ap->tx_ret_csm, idx))
+		if (tx_ring_full(ap, ap->tx_ret_csm, idx))
 			flagsize |= BD_FLG_COAL_NOW;
 
-		ace_load_tx_bd(desc, mapping, flagsize);
+		ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
 	}
 #if MAX_SKB_FRAGS
 	else {
 		dma_addr_t mapping;
+		u32 vlan_tag = 0;
 		int i, len = 0;
 
 		mapping = ace_map_tx_skb(ap, skb, NULL, idx);
 		flagsize = ((skb->len - skb->data_len) << 16);
 		if (skb->ip_summed == CHECKSUM_HW)
 			flagsize |= BD_FLG_TCP_UDP_SUM;
+#if ACENIC_DO_VLAN
+		if (vlan_tx_tag_present(skb)) {
+			flagsize |= BD_FLG_VLAN_TAG;
+			vlan_tag = vlan_tx_tag_get(skb);
+		}
+#endif
 
-		ace_load_tx_bd(ap->tx_ring + idx, mapping, flagsize);
+		ace_load_tx_bd(ap, ap->tx_ring + idx, mapping, flagsize, vlan_tag);
 
-		idx = (idx + 1) % TX_RING_ENTRIES;
+		idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
 
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -2662,11 +2807,11 @@
 			flagsize = (frag->size << 16);
 			if (skb->ip_summed == CHECKSUM_HW)
 				flagsize |= BD_FLG_TCP_UDP_SUM;
-			idx = (idx + 1) % TX_RING_ENTRIES;
+			idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
 
 			if (i == skb_shinfo(skb)->nr_frags - 1) {
 				flagsize |= BD_FLG_END;
-				if (tx_ring_full(ap->tx_ret_csm, idx))
+				if (tx_ring_full(ap, ap->tx_ret_csm, idx))
 					flagsize |= BD_FLG_COAL_NOW;
 
 				/*
@@ -2679,7 +2824,7 @@
 			}
 			pci_unmap_addr_set(info, mapping, mapping);
 			pci_unmap_len_set(info, maplen, frag->size);
-			ace_load_tx_bd(desc, mapping, flagsize);
+			ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
 		}
 	}
 #endif
@@ -2697,7 +2842,7 @@
 		 * serialized, this is the only situation we have to
 		 * re-test.
 		 */
-		if (!tx_ring_full(ap->tx_ret_csm, idx))
+		if (!tx_ring_full(ap, ap->tx_ret_csm, idx))
 			netif_wake_queue(dev);
 	}
 
@@ -2776,8 +2921,8 @@
 		return -EOPNOTSUPP;
 	if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd)))
 		return -EFAULT;
-
-	if (ecmd.cmd == ETHTOOL_GSET) {
+	switch (ecmd.cmd) {
+	case ETHTOOL_GSET:
 		ecmd.supported =
 			(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
 			 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
@@ -2825,7 +2970,8 @@
 		if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd)))
 			return -EFAULT;
 		return 0;
-	} else if (ecmd.cmd == ETHTOOL_SSET) {
+
+	case ETHTOOL_SSET:
 		if(!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
@@ -2882,7 +3028,24 @@
 			ace_issue_cmd(regs, &cmd);
 		}
 		return 0;
+
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strncpy(info.driver, "acenic", sizeof(info.driver) - 1);
+		sprintf(info.fw_version, "%i.%i.%i", 
+			 tigonFwReleaseMajor, tigonFwReleaseMinor,
+			 tigonFwReleaseFix);
+		strncpy(info.version, version, sizeof(info.version) - 1);
+		if (ap && ap->pdev)
+			strcpy(info.bus_info, ap->pdev->slot_name);
+		if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
 	}
+	default:
+		break;
+	}
+	
 #endif
 
 	return -EOPNOTSUPP;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/acenic.h linux/drivers/net/acenic.h
--- linux.orig/drivers/net/acenic.h	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/acenic.h	2002-07-20 01:08:36.000000000 +0000
@@ -417,7 +417,16 @@
 #define BD_FLG_TCP_UDP_SUM	0x01
 #define BD_FLG_IP_SUM		0x02
 #define BD_FLG_END		0x04
+#define BD_FLG_MORE		0x08
 #define BD_FLG_JUMBO		0x10
+#define BD_FLG_UCAST		0x20
+#define BD_FLG_MCAST		0x40
+#define BD_FLG_BCAST		0x60
+#define BD_FLG_TYP_MASK		0x60
+#define BD_FLG_IP_FRAG		0x80
+#define BD_FLG_IP_FRAG_END	0x100
+#define BD_FLG_VLAN_TAG		0x200
+#define BD_FLG_FRAME_ERROR	0x400
 #define BD_FLG_COAL_NOW		0x800
 #define BD_FLG_MINI		0x1000
 
@@ -437,11 +446,12 @@
 
 
 /*
- * TX ring
+ * TX ring - maximum TX ring entries for Tigon I's is 128
  */
-#define TX_RING_ENTRIES	256	
-#define TX_RING_SIZE	(TX_RING_ENTRIES * sizeof(struct tx_desc))
-#define TX_RING_BASE	0x3800
+#define MAX_TX_RING_ENTRIES	256
+#define TIGON_I_TX_RING_ENTRIES	128
+#define TX_RING_SIZE		(MAX_TX_RING_ENTRIES * sizeof(struct tx_desc))
+#define TX_RING_BASE		0x3800
 
 struct tx_desc{
         aceaddr	addr;
@@ -608,7 +618,7 @@
  */
 struct ace_skb
 {
-	struct tx_ring_info	tx_skbuff[TX_RING_ENTRIES];
+	struct tx_ring_info	tx_skbuff[MAX_TX_RING_ENTRIES];
 	struct ring_info	rx_std_skbuff[RX_STD_RING_ENTRIES];
 	struct ring_info	rx_mini_skbuff[RX_MINI_RING_ENTRIES];
 	struct ring_info	rx_jumbo_skbuff[RX_JUMBO_RING_ENTRIES];
@@ -641,7 +651,7 @@
 	struct tx_desc		*tx_ring;
 	u32			tx_prd;
 	volatile u32		tx_ret_csm;
-	struct timer_list	timer;
+	int			tx_ring_entries;
 
 	/*
 	 * RX elements
@@ -660,6 +670,10 @@
 	struct rx_desc		*rx_mini_ring;
 	struct rx_desc		*rx_return_ring;
 
+#if ACENIC_DO_VLAN
+	struct vlan_group	*vlgrp;
+#endif
+
 	int			tasklet_pending, jumbo;
 	struct tasklet_struct	ace_tasklet;
 
@@ -692,17 +706,17 @@
 
 #define TX_RESERVED	MAX_SKB_FRAGS
 
-static inline int tx_space (u32 csm, u32 prd)
+static inline int tx_space (struct ace_private *ap, u32 csm, u32 prd)
 {
-	return (csm - prd - 1) & (TX_RING_ENTRIES - 1);
+	return (csm - prd - 1) & (ACE_TX_RING_ENTRIES(ap) - 1);
 }
 
-#define tx_free(ap) 		tx_space((ap)->tx_ret_csm, (ap)->tx_prd)
+#define tx_free(ap) 		tx_space((ap)->tx_ret_csm, (ap)->tx_prd, ap)
 
 #if MAX_SKB_FRAGS
-#define tx_ring_full(csm, prd)	(tx_space(csm, prd) <= TX_RESERVED)
+#define tx_ring_full(ap, csm, prd)	(tx_space(ap, csm, prd) <= TX_RESERVED)
 #else
-#define tx_ring_full		0
+#define tx_ring_full			0
 #endif
 
 
@@ -711,7 +725,7 @@
 	u64 baddr = (u64) addr;
 	aa->addrlo = baddr & 0xffffffff;
 	aa->addrhi = baddr >> 32;
-	mb();
+	wmb();
 }
 
 
@@ -758,5 +772,9 @@
 static void ace_init_cleanup(struct net_device *dev);
 static struct net_device_stats *ace_get_stats(struct net_device *dev);
 static int read_eeprom_byte(struct net_device *dev, unsigned long offset);
+#if ACENIC_DO_VLAN
+static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
+static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
+#endif
 
 #endif /* _ACENIC_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/aironet4500.h linux/drivers/net/aironet4500.h
--- linux.orig/drivers/net/aironet4500.h	2001-10-11 06:23:24.000000000 +0000
+++ linux/drivers/net/aironet4500.h	2002-07-20 01:08:21.000000000 +0000
@@ -463,7 +463,7 @@
 	spin_unlock_irqrestore(&queue->spinlock,flags);	
 };
 
-extern inline void
+static inline void
 awc_fid_queue_push_tail(	struct awc_fid_queue * 	queue,
 				struct awc_fid *	fid){
 
@@ -488,7 +488,7 @@
 };
 
 
-extern inline void
+static inline void
 awc_fid_queue_push_head(	struct awc_fid_queue * 	queue,
 				struct awc_fid *	fid){
 
@@ -513,7 +513,7 @@
 
 
 
-extern inline void
+static inline void
 awc_fid_queue_rm(		struct awc_fid_queue * 	queue,
 				struct awc_fid *	fid){
 
@@ -541,7 +541,7 @@
 	}		
 };
 
-extern inline void
+static inline void
 awc_fid_queue_remove(		struct awc_fid_queue * 	queue,
 				struct awc_fid *	fid){
 	unsigned long flags;
@@ -555,7 +555,7 @@
 
 
 
-extern inline struct awc_fid * 
+static inline struct awc_fid * 
 awc_fid_queue_pop_head(		struct awc_fid_queue * 	queue){
 
 	unsigned long flags;
@@ -575,7 +575,7 @@
 
 
 
-extern inline struct awc_fid * 
+static inline struct awc_fid * 
 awc_fid_queue_pop_tail(		struct awc_fid_queue * 	queue){
 
 	unsigned long flags;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/am79c961a.c linux/drivers/net/am79c961a.c
--- linux.orig/drivers/net/am79c961a.c	2001-06-27 21:12:04.000000000 +0000
+++ linux/drivers/net/am79c961a.c	2002-07-20 01:08:39.000000000 +0000
@@ -29,6 +29,7 @@
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -308,33 +309,13 @@
 	return &priv->stats;
 }
 
-static inline u32 update_crc(u32 crc, u8 byte)
-{
-	int i;
-
-	for (i = 8; i != 0; i--) {
-		byte ^= crc & 1;
-		crc >>= 1;
-
-		if (byte & 1)
-			crc ^= 0xedb88320;
-
-		byte >>= 1;
-	}
-
-	return crc;
-}
-
 static void am79c961_mc_hash(struct dev_mc_list *dmi, unsigned short *hash)
 {
 	if (dmi->dmi_addrlen == ETH_ALEN && dmi->dmi_addr[0] & 0x01) {
-		int i, idx, bit;
+		int idx, bit;
 		u32 crc;
 
-		crc = 0xffffffff;
-
-		for (i = 0; i < ETH_ALEN; i++)
-			crc = update_crc(crc, dmi->dmi_addr[i]);
+		crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr);
 
 		idx = crc >> 30;
 		bit = (crc >> 26) & 15;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/apne.c linux/drivers/net/apne.c
--- linux.orig/drivers/net/apne.c	2001-04-19 16:34:52.000000000 +0000
+++ linux/drivers/net/apne.c	2002-07-20 01:08:40.000000000 +0000
@@ -54,19 +54,19 @@
 #define NE_BASE	 (dev->base_addr)
 #define NE_CMD	 		0x00
 #define NE_DATAPORT		0x10            /* NatSemi-defined port window offset. */
-#define NE_RESET		0x1f+GAYLE_ODD  /* Issue a read to reset, a write to clear. */
-#define NE_IO_EXTENT	0x20
+#define NE_RESET		0x1f            /* Issue a read to reset, a write to clear. */
+#define NE_IO_EXTENT	        0x20
 
-#define NE_EN0_ISR		0x07+GAYLE_ODD
+#define NE_EN0_ISR		0x07
 #define NE_EN0_DCFG		0x0e
 
-#define NE_EN0_RSARLO	0x08
-#define NE_EN0_RSARHI	0x09+GAYLE_ODD
-#define NE_EN0_RCNTLO	0x0a
+#define NE_EN0_RSARLO	        0x08
+#define NE_EN0_RSARHI	        0x09
+#define NE_EN0_RCNTLO	        0x0a
 #define NE_EN0_RXCR		0x0c
-#define NE_EN0_TXCR		0x0d+GAYLE_ODD
-#define NE_EN0_RCNTHI	0x0b+GAYLE_ODD
-#define NE_EN0_IMR		0x0f+GAYLE_ODD
+#define NE_EN0_TXCR		0x0d
+#define NE_EN0_RCNTHI	        0x0b
+#define NE_EN0_IMR		0x0f
 
 #define NE1SM_START_PG	0x20	/* First page of TX buffer */
 #define NE1SM_STOP_PG 	0x40	/* Last page +1 of RX ring */
@@ -157,7 +157,7 @@
 	printk("ethernet PCMCIA card inserted\n");
 
 	if (init_pcmcia())
-		return apne_probe1(dev, IOBASE+GAYLE_IO);
+		return apne_probe1(dev, IOBASE);
 	else
 		return (-ENODEV);
 
@@ -174,12 +174,7 @@
     int neX000, ctron;
 #endif
     static unsigned version_printed;
-    static u32 pcmcia_offsets[16]={
-                0,   1+GAYLE_ODD,   2,   3+GAYLE_ODD,
-                4,   5+GAYLE_ODD,   6,   7+GAYLE_ODD,
-                8,   9+GAYLE_ODD, 0xa, 0xb+GAYLE_ODD,
-              0xc, 0xd+GAYLE_ODD, 0xe, 0xf+GAYLE_ODD };
-
+ 
     if (ei_debug  &&  version_printed++ == 0)
 	printk(version);
 
@@ -188,15 +183,15 @@
     /* Reset card. Who knows what dain-bramaged state it was left in. */
     {	unsigned long reset_start_time = jiffies;
 
-	writeb(readb(ioaddr + NE_RESET), ioaddr + NE_RESET);
+	outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
 
-	while ((readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
+	while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
 		if (jiffies - reset_start_time > 2*HZ/100) {
 			printk(" not found (no reset ack).\n");
 			return -ENODEV;
 		}
 
-	writeb(0xff, ioaddr + NE_EN0_ISR);		/* Ack all intr. */
+	outb(0xff, ioaddr + NE_EN0_ISR);		/* Ack all intr. */
     }
 
 #ifndef MANUAL_HWADDR0
@@ -222,13 +217,13 @@
 	    {E8390_RREAD+E8390_START, NE_CMD},
 	};
 	for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) {
-	    writeb(program_seq[i].value, ioaddr + program_seq[i].offset);
+	    outb(program_seq[i].value, ioaddr + program_seq[i].offset);
 	}
 
     }
     for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
-	SA_prom[i] = readb(ioaddr + NE_DATAPORT);
-	SA_prom[i+1] = readb(ioaddr + NE_DATAPORT);
+	SA_prom[i] = inb(ioaddr + NE_DATAPORT);
+	SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
 	if (SA_prom[i] != SA_prom[i+1])
 	    wordlength = 1;
     }
@@ -244,7 +239,7 @@
     
     if (wordlength == 2) {
 	/* We must set the 8390 for word mode. */
-	writeb(0x49, ioaddr + NE_EN0_DCFG);
+	outb(0x49, ioaddr + NE_EN0_DCFG);
 	start_page = NESM_START_PG;
 	stop_page = NESM_STOP_PG;
     } else {
@@ -271,7 +266,7 @@
 #else
     wordlength = 2;
     /* We must set the 8390 for word mode. */
-    writeb(0x49, ioaddr + NE_EN0_DCFG);
+    outb(0x49, ioaddr + NE_EN0_DCFG);
     start_page = NESM_START_PG;
     stop_page = NESM_STOP_PG;
 
@@ -314,7 +309,6 @@
     ei_status.block_input = &apne_block_input;
     ei_status.block_output = &apne_block_output;
     ei_status.get_8390_hdr = &apne_get_8390_hdr;
-    ei_status.reg_offset = pcmcia_offsets;
     dev->open = &apne_open;
     dev->stop = &apne_close;
     NS8390_init(dev, 0);
@@ -354,18 +348,18 @@
 
     if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
 
-    writeb(readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
+    outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
 
     ei_status.txing = 0;
     ei_status.dmaing = 0;
 
     /* This check _should_not_ be necessary, omit eventually. */
-    while ((readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
+    while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
 	if (jiffies - reset_start_time > 2*HZ/100) {
 	    printk("%s: ne_reset_8390() did not complete.\n", dev->name);
 	    break;
 	}
-    writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR);	/* Ack intr. */
+    outb(ENISR_RESET, NE_BASE + NE_EN0_ISR);	/* Ack intr. */
 }
 
 /* Grab the 8390 specific header. Similar to the block_input routine, but
@@ -390,25 +384,25 @@
     }
 
     ei_status.dmaing |= 0x01;
-    writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
-    writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
-    writeb(0, nic_base + NE_EN0_RCNTHI);
-    writeb(0, nic_base + NE_EN0_RSARLO);		/* On page boundary */
-    writeb(ring_page, nic_base + NE_EN0_RSARHI);
-    writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+    outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+    outb(ENISR_RDC, nic_base + NE_EN0_ISR);
+    outb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
+    outb(0, nic_base + NE_EN0_RCNTHI);
+    outb(0, nic_base + NE_EN0_RSARLO);		/* On page boundary */
+    outb(ring_page, nic_base + NE_EN0_RSARHI);
+    outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
 
     if (ei_status.word16) {
         ptrs = (short*)hdr;
         for(cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++)
-            *ptrs++ = readw(NE_BASE + NE_DATAPORT);
+            *ptrs++ = inw(NE_BASE + NE_DATAPORT);
     } else {
         ptrc = (char*)hdr;
         for(cnt = 0; cnt < sizeof(struct e8390_pkt_hdr); cnt++)
-            *ptrc++ = readb(NE_BASE + NE_DATAPORT);
+            *ptrc++ = inb(NE_BASE + NE_DATAPORT);
     }
 
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+    outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
 
     hdr->count = WORDSWAP(hdr->count);
 
@@ -418,7 +412,7 @@
 /* Block input and output, similar to the Crynwr packet driver.  If you
    are porting to a new ethercard, look at the packet driver source for hints.
    The NEx000 doesn't share the on-board packet memory -- you have to put
-   the packet out through the "remote DMA" dataport using writeb. */
+   the packet out through the "remote DMA" dataport using outb. */
 
 static void
 apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
@@ -437,27 +431,27 @@
 	return;
     }
     ei_status.dmaing |= 0x01;
-    writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
-    writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
-    writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
-    writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
-    writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
-    writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+    outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+    outb(ENISR_RDC, nic_base + NE_EN0_ISR);
+    outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+    outb(count >> 8, nic_base + NE_EN0_RCNTHI);
+    outb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
+    outb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
+    outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
     if (ei_status.word16) {
       ptrs = (short*)buf;
       for (cnt = 0; cnt < (count>>1); cnt++)
-        *ptrs++ = readw(NE_BASE + NE_DATAPORT);
+        *ptrs++ = inw(NE_BASE + NE_DATAPORT);
       if (count & 0x01) {
-	buf[count-1] = readb(NE_BASE + NE_DATAPORT);
+	buf[count-1] = inb(NE_BASE + NE_DATAPORT);
       }
     } else {
       ptrc = (char*)buf;
       for (cnt = 0; cnt < count; cnt++)
-        *ptrc++ = readb(NE_BASE + NE_DATAPORT);
+        *ptrc++ = inb(NE_BASE + NE_DATAPORT);
     }
 
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+    outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
     ei_status.dmaing &= ~0x01;
 }
 
@@ -486,30 +480,30 @@
     }
     ei_status.dmaing |= 0x01;
     /* We should already be in page 0, but to be safe... */
-    writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+    outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
 
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+    outb(ENISR_RDC, nic_base + NE_EN0_ISR);
 
    /* Now the normal output. */
-    writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
-    writeb(count >> 8,   nic_base + NE_EN0_RCNTHI);
-    writeb(0x00, nic_base + NE_EN0_RSARLO);
-    writeb(start_page, nic_base + NE_EN0_RSARHI);
+    outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+    outb(count >> 8,   nic_base + NE_EN0_RCNTHI);
+    outb(0x00, nic_base + NE_EN0_RSARLO);
+    outb(start_page, nic_base + NE_EN0_RSARHI);
 
-    writeb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+    outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
     if (ei_status.word16) {
         ptrs = (short*)buf;
         for (cnt = 0; cnt < count>>1; cnt++)
-            writew(*ptrs++, NE_BASE+NE_DATAPORT);
+            outw(*ptrs++, NE_BASE+NE_DATAPORT);
     } else {
         ptrc = (char*)buf;
         for (cnt = 0; cnt < count; cnt++)
-	    writeb(*ptrc++, NE_BASE + NE_DATAPORT);
+	    outb(*ptrc++, NE_BASE + NE_DATAPORT);
     }
 
     dma_start = jiffies;
 
-    while ((readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
+    while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
 	if (jiffies - dma_start > 2*HZ/100) {		/* 20ms */
 		printk("%s: timeout waiting for Tx RDC.\n", dev->name);
 		apne_reset_8390(dev);
@@ -517,7 +511,7 @@
 		break;
 	}
 
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+    outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
     ei_status.dmaing &= ~0x01;
     return;
 }
@@ -611,7 +605,9 @@
 	}
 #endif
 
-	writeb(config, GAYLE_ATTRIBUTE+offset);
+	out_8(GAYLE_ATTRIBUTE+offset, config);
 
 	return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/appletalk/Config.in linux/drivers/net/appletalk/Config.in
--- linux.orig/drivers/net/appletalk/Config.in	2001-11-09 22:01:22.000000000 +0000
+++ linux/drivers/net/appletalk/Config.in	2002-07-20 01:08:22.000000000 +0000
@@ -2,22 +2,20 @@
 # Appletalk driver configuration
 #
 
-if [ "$CONFIG_ATALK" != "n" ]; then
-   mainmenu_option next_comment
-   comment 'Appletalk devices'
-   bool 'Appletalk interfaces support' CONFIG_APPLETALK
-   if [ "$CONFIG_ATALK" != "n" ]; then
-      dep_tristate '  Apple/Farallon LocalTalk PC support' CONFIG_LTPC $CONFIG_DEV_APPLETALK
-      dep_tristate '  COPS LocalTalk PC support' CONFIG_COPS $CONFIG_DEV_APPLETALK
-      if [ "$CONFIG_COPS" != "n" ]; then
-	 bool '    Dayna firmware support' CONFIG_COPS_DAYNA
-	 bool '    Tangent firmware support' CONFIG_COPS_TANGENT
-      fi
-      dep_tristate '  Appletalk-IP driver support' CONFIG_IPDDP $CONFIG_DEV_APPLETALK
-      if [ "$CONFIG_IPDDP" != "n" ]; then
-	 bool '    IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP
-	 bool '    Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP
-      fi
+mainmenu_option next_comment
+comment 'Appletalk devices'
+dep_mbool 'Appletalk interfaces support' CONFIG_DEV_APPLETALK $CONFIG_ATALK
+if [ "$CONFIG_DEV_APPLETALK" = "y" ]; then
+   tristate '  Apple/Farallon LocalTalk PC support' CONFIG_LTPC
+   tristate '  COPS LocalTalk PC support' CONFIG_COPS
+   if [ "$CONFIG_COPS" != "n" ]; then
+      bool '    Dayna firmware support' CONFIG_COPS_DAYNA
+      bool '    Tangent firmware support' CONFIG_COPS_TANGENT
+   fi
+   dep_tristate '  Appletalk-IP driver support' CONFIG_IPDDP $CONFIG_ATALK
+   if [ "$CONFIG_IPDDP" != "n" ]; then
+      bool '    IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP
+      bool '    Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP
    fi
-   endmenu
 fi
+endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/arc-rawmode.c linux/drivers/net/arcnet/arc-rawmode.c
--- linux.orig/drivers/net/arcnet/arc-rawmode.c	2001-02-13 21:15:05.000000000 +0000
+++ linux/drivers/net/arcnet/arc-rawmode.c	2002-07-20 01:08:40.000000000 +0000
@@ -83,6 +83,7 @@
 	arcnet_unregister_proto(&rawmode_proto);
 }
 
+MODULE_LICENSE("GPL");
 #endif				/* MODULE */
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/arc-rimi.c linux/drivers/net/arcnet/arc-rimi.c
--- linux.orig/drivers/net/arcnet/arc-rimi.c	2001-11-04 17:31:58.000000000 +0000
+++ linux/drivers/net/arcnet/arc-rimi.c	2002-07-20 01:08:23.000000000 +0000
@@ -297,6 +297,7 @@
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM(device, "s");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/arcnet.c linux/drivers/net/arcnet/arcnet.c
--- linux.orig/drivers/net/arcnet/arcnet.c	2001-11-04 17:31:58.000000000 +0000
+++ linux/drivers/net/arcnet/arcnet.c	2002-07-20 01:08:26.000000000 +0000
@@ -163,6 +163,7 @@
 
 static int debug = ARCNET_DEBUG;
 MODULE_PARM(debug, "i");
+MODULE_LICENSE("GPL");
 
 int __init init_module(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/com20020-isa.c linux/drivers/net/arcnet/com20020-isa.c
--- linux.orig/drivers/net/arcnet/com20020-isa.c	2001-11-04 17:31:58.000000000 +0000
+++ linux/drivers/net/arcnet/com20020-isa.c	2002-07-20 01:08:26.000000000 +0000
@@ -133,6 +133,7 @@
 MODULE_PARM(backplane, "i");
 MODULE_PARM(clockp, "i");
 MODULE_PARM(clockm, "i");
+MODULE_LICENSE("GPL");
 
 static void com20020isa_open_close(struct net_device *dev, bool open)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/com20020-pci.c linux/drivers/net/arcnet/com20020-pci.c
--- linux.orig/drivers/net/arcnet/com20020-pci.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/arcnet/com20020-pci.c	2002-07-20 01:08:27.000000000 +0000
@@ -57,6 +57,7 @@
 MODULE_PARM(backplane, "i");
 MODULE_PARM(clockp, "i");
 MODULE_PARM(clockm, "i");
+MODULE_LICENSE("GPL");
 
 static void com20020pci_open_close(struct net_device *dev, bool open)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/com20020.c linux/drivers/net/arcnet/com20020.c
--- linux.orig/drivers/net/arcnet/com20020.c	2001-11-04 17:31:58.000000000 +0000
+++ linux/drivers/net/arcnet/com20020.c	2002-07-20 01:08:31.000000000 +0000
@@ -356,6 +356,8 @@
 EXPORT_SYMBOL(com20020_found);
 EXPORT_SYMBOL(com20020_remove);
 
+MODULE_LICENSE("GPL");
+
 int init_module(void)
 {
 	BUGLVL(D_NORMAL) printk(VERSION);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/com90io.c linux/drivers/net/arcnet/com90io.c
--- linux.orig/drivers/net/arcnet/com90io.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/arcnet/com90io.c	2002-07-20 01:08:31.000000000 +0000
@@ -383,6 +383,7 @@
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM(device, "s");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/com90xx.c linux/drivers/net/arcnet/com90xx.c
--- linux.orig/drivers/net/arcnet/com90xx.c	2001-11-04 17:31:58.000000000 +0000
+++ linux/drivers/net/arcnet/com90xx.c	2002-07-20 01:08:27.000000000 +0000
@@ -619,6 +619,7 @@
 MODULE_PARM(irq, "i");
 MODULE_PARM(shmem, "i");
 MODULE_PARM(device, "s");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/rfc1051.c linux/drivers/net/arcnet/rfc1051.c
--- linux.orig/drivers/net/arcnet/rfc1051.c	2001-02-13 21:15:05.000000000 +0000
+++ linux/drivers/net/arcnet/rfc1051.c	2002-07-20 01:08:25.000000000 +0000
@@ -68,6 +68,8 @@
 
 #ifdef MODULE
 
+MODULE_LICENSE("GPL");
+
 int __init init_module(void)
 {
 	printk(VERSION);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arcnet/rfc1201.c linux/drivers/net/arcnet/rfc1201.c
--- linux.orig/drivers/net/arcnet/rfc1201.c	2001-02-13 21:15:05.000000000 +0000
+++ linux/drivers/net/arcnet/rfc1201.c	2002-07-20 01:08:36.000000000 +0000
@@ -70,6 +70,8 @@
 
 #ifdef MODULE
 
+MODULE_LICENSE("GPL");
+
 int __init init_module(void)
 {
 	printk(VERSION);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ariadne.c linux/drivers/net/ariadne.c
--- linux.orig/drivers/net/ariadne.c	2001-08-12 17:51:42.000000000 +0000
+++ linux/drivers/net/ariadne.c	2002-07-20 01:08:38.000000000 +0000
@@ -54,7 +54,7 @@
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
 #include <linux/zorro.h>
-#include <asm/io.h>
+
 #include <asm/irq.h>
 
 #include "ariadne.h"
@@ -847,3 +847,5 @@
 
 module_init(ariadne_probe);
 module_exit(ariadne_cleanup);
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ariadne2.c linux/drivers/net/ariadne2.c
--- linux.orig/drivers/net/ariadne2.c	2001-04-12 19:15:25.000000000 +0000
+++ linux/drivers/net/ariadne2.c	2002-07-20 01:08:23.000000000 +0000
@@ -30,7 +30,7 @@
 #include <linux/zorro.h>
 
 #include <asm/system.h>
-#include <asm/io.h>
+
 #include <asm/irq.h>
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
@@ -142,15 +142,15 @@
     {
 	unsigned long reset_start_time = jiffies;
 
-	writeb(readb(ioaddr + NE_RESET), ioaddr + NE_RESET);
+	z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET);
 
-	while ((readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
+	while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
 	    if (jiffies - reset_start_time > 2*HZ/100) {
 		printk(" not found (no reset ack).\n");
 		return -ENODEV;
 	    }
 
-	writeb(0xff, ioaddr + NE_EN0_ISR);		/* Ack all intr. */
+	z_writeb(0xff, ioaddr + NE_EN0_ISR);		/* Ack all intr. */
     }
 
     /* Read the 16 bytes of station address PROM.
@@ -177,16 +177,16 @@
 	    {E8390_RREAD+E8390_START, NE_CMD},
 	};
 	for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) {
-	    writeb(program_seq[i].value, ioaddr + program_seq[i].offset);
+	    z_writeb(program_seq[i].value, ioaddr + program_seq[i].offset);
 	}
     }
     for (i = 0; i < 16; i++) {
-	SA_prom[i] = readb(ioaddr + NE_DATAPORT);
-	(void)readb(ioaddr + NE_DATAPORT);
+	SA_prom[i] = z_readb(ioaddr + NE_DATAPORT);
+	(void)z_readb(ioaddr + NE_DATAPORT);
     }
 
     /* We must set the 8390 for word mode. */
-    writeb(0x49, ioaddr + NE_EN0_DCFG);
+    z_writeb(0x49, ioaddr + NE_EN0_DCFG);
     start_page = NESM_START_PG;
     stop_page = NESM_STOP_PG;
 
@@ -260,18 +260,18 @@
     if (ei_debug > 1)
 	printk("resetting the 8390 t=%ld...", jiffies);
 
-    writeb(readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
+    z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
 
     ei_status.txing = 0;
     ei_status.dmaing = 0;
 
     /* This check _should_not_ be necessary, omit eventually. */
-    while ((readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
+    while ((z_readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
 	if (jiffies - reset_start_time > 2*HZ/100) {
 	    printk("%s: ne_reset_8390() did not complete.\n", dev->name);
 	    break;
 	}
-    writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR);	/* Ack intr. */
+    z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR);	/* Ack intr. */
 }
 
 /* Grab the 8390 specific header. Similar to the block_input routine, but
@@ -294,19 +294,19 @@
     }
 
     ei_status.dmaing |= 0x01;
-    writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
-    writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
-    writeb(0, nic_base + NE_EN0_RCNTHI);
-    writeb(0, nic_base + NE_EN0_RSARLO);		/* On page boundary */
-    writeb(ring_page, nic_base + NE_EN0_RSARHI);
-    writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+    z_writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+    z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+    z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
+    z_writeb(0, nic_base + NE_EN0_RCNTHI);
+    z_writeb(0, nic_base + NE_EN0_RSARLO);		/* On page boundary */
+    z_writeb(ring_page, nic_base + NE_EN0_RSARHI);
+    z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
 
     ptrs = (short*)hdr;
     for (cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++)
-	*ptrs++ = readw(NE_BASE + NE_DATAPORT);
+	*ptrs++ = z_readw(NE_BASE + NE_DATAPORT);
 
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+    z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
 
     hdr->count = WORDSWAP(hdr->count);
 
@@ -316,7 +316,7 @@
 /* Block input and output, similar to the Crynwr packet driver.  If you
    are porting to a new ethercard, look at the packet driver source for hints.
    The NEx000 doesn't share the on-board packet memory -- you have to put
-   the packet out through the "remote DMA" dataport using writeb. */
+   the packet out through the "remote DMA" dataport using z_writeb. */
 
 static void ariadne2_block_input(struct net_device *dev, int count,
 				 struct sk_buff *skb, int ring_offset)
@@ -334,20 +334,20 @@
 	return;
     }
     ei_status.dmaing |= 0x01;
-    writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
-    writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
-    writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
-    writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
-    writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
-    writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+    z_writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+    z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+    z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+    z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
+    z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
+    z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
+    z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
     ptrs = (short*)buf;
     for (cnt = 0; cnt < (count>>1); cnt++)
-	*ptrs++ = readw(NE_BASE + NE_DATAPORT);
+	*ptrs++ = z_readw(NE_BASE + NE_DATAPORT);
     if (count & 0x01)
-	buf[count-1] = readb(NE_BASE + NE_DATAPORT);
+	buf[count-1] = z_readb(NE_BASE + NE_DATAPORT);
 
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+    z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
     ei_status.dmaing &= ~0x01;
 }
 
@@ -375,24 +375,24 @@
     }
     ei_status.dmaing |= 0x01;
     /* We should already be in page 0, but to be safe... */
-    writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+    z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
 
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+    z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
 
    /* Now the normal output. */
-    writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
-    writeb(count >> 8,   nic_base + NE_EN0_RCNTHI);
-    writeb(0x00, nic_base + NE_EN0_RSARLO);
-    writeb(start_page, nic_base + NE_EN0_RSARHI);
+    z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+    z_writeb(count >> 8,   nic_base + NE_EN0_RCNTHI);
+    z_writeb(0x00, nic_base + NE_EN0_RSARLO);
+    z_writeb(start_page, nic_base + NE_EN0_RSARHI);
 
-    writeb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+    z_writeb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
     ptrs = (short*)buf;
     for (cnt = 0; cnt < count>>1; cnt++)
-	writew(*ptrs++, NE_BASE+NE_DATAPORT);
+	z_writew(*ptrs++, NE_BASE+NE_DATAPORT);
 
     dma_start = jiffies;
 
-    while ((readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
+    while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
 	if (jiffies - dma_start > 2*HZ/100) {		/* 20ms */
 		printk("%s: timeout waiting for Tx RDC.\n", dev->name);
 		ariadne2_reset_8390(dev);
@@ -400,7 +400,7 @@
 		break;
 	}
 
-    writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+    z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
     ei_status.dmaing &= ~0x01;
     return;
 }
@@ -423,3 +423,5 @@
 
 module_init(ariadne2_probe);
 module_exit(ariadne2_cleanup);
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/arlan.c linux/drivers/net/arlan.c
--- linux.orig/drivers/net/arlan.c	2001-11-09 21:45:35.000000000 +0000
+++ linux/drivers/net/arlan.c	2002-07-20 01:08:38.000000000 +0000
@@ -128,7 +128,7 @@
 
 EXPORT_SYMBOL(arlan_command);
 
-extern inline long long arlan_time(void)
+static inline long long arlan_time(void)
 {
 	struct timeval timev;
 	do_gettimeofday(&timev);
@@ -186,7 +186,7 @@
 
 
 
-extern inline int arlan_drop_tx(struct net_device *dev)
+static inline int arlan_drop_tx(struct net_device *dev)
 {
 	struct arlan_private *priv = ((struct arlan_private *) dev->priv);
 
@@ -554,7 +554,7 @@
 
 };
 
-extern inline void arlan_command_process(struct net_device *dev)
+static inline void arlan_command_process(struct net_device *dev)
 {
 	struct arlan_private *priv = ((struct arlan_private *) dev->priv);
 
@@ -575,7 +575,7 @@
 }
 
 
-extern inline void arlan_retransmit_now(struct net_device *dev)
+static inline void arlan_retransmit_now(struct net_device *dev)
 {
 	struct arlan_private *priv = ((struct arlan_private *) dev->priv);
 
@@ -677,7 +677,7 @@
 		arlan_retransmit_now(dev);
 	}
 	if (!registrationBad(dev) &&
-		priv->tx_done_delayed < jiffies &&
+		time_after(jiffies, priv->tx_done_delayed) &&
 		priv->tx_done_delayed != 0)
 	{
 		TXLAST(dev).offset = 0;
@@ -1405,7 +1405,7 @@
 }
 
 
-extern inline int DoNotReTransmitCrap(struct net_device *dev)
+static inline int DoNotReTransmitCrap(struct net_device *dev)
 {
 	struct arlan_private *priv = ((struct arlan_private *) dev->priv);
 
@@ -1415,7 +1415,7 @@
 
 }
 
-extern inline int DoNotWaitReTransmitCrap(struct net_device *dev)
+static inline int DoNotWaitReTransmitCrap(struct net_device *dev)
 {
 	struct arlan_private *priv = ((struct arlan_private *) dev->priv);
 
@@ -1424,7 +1424,7 @@
 	return 0;
 }
 
-extern inline void arlan_queue_retransmit(struct net_device *dev)
+static inline void arlan_queue_retransmit(struct net_device *dev)
 {
 	struct arlan_private *priv = ((struct arlan_private *) dev->priv);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/at1700.c linux/drivers/net/at1700.c
--- linux.orig/drivers/net/at1700.c	2001-10-11 06:24:09.000000000 +0000
+++ linux/drivers/net/at1700.c	2002-07-20 01:08:33.000000000 +0000
@@ -49,6 +49,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -464,7 +465,7 @@
 #define EE_DATA_READ	0x80	/* EEPROM chip data out, in reg. 17. */
 
 /* Delay between EEPROM clock transitions. */
-#define eeprom_delay()	do {} while (0);
+#define eeprom_delay()	do { } while (0)
 
 /* The EEPROM commands include the alway-set leading bit. */
 #define EE_WRITE_CMD	(5 << 6)
@@ -804,27 +805,6 @@
   Set the multicast/promiscuous mode for this adaptor.
 */
 
-/* The little-endian AUTODIN II ethernet CRC calculation.
-   N.B. Do not use for bulk data, use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-	unsigned int crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-
 static void
 set_rx_mode(struct net_device *dev)
 {
@@ -856,6 +836,7 @@
 			 i++, mclist = mclist->next)
 			set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26,
 					mc_filter);
+		outb(0x02, ioaddr + RX_MODE);	/* Use normal mode. */
 	}
 
 	save_flags(flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/atp.c linux/drivers/net/atp.c
--- linux.orig/drivers/net/atp.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/atp.c	2002-07-20 01:08:36.000000000 +0000
@@ -140,6 +140,7 @@
 #include <asm/dma.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -666,7 +667,7 @@
 			}
 			num_tx_since_rx++;
 		} else if (num_tx_since_rx > 8
-				   && jiffies > dev->last_rx + HZ) {
+				   && time_after(jiffies, dev->last_rx + HZ)) {
 			if (net_debug > 2)
 				printk(KERN_DEBUG "%s: Missed packet? No Rx after %d Tx and "
 					   "%ld jiffies status %02x  CMR1 %02x.\n", dev->name,
@@ -857,26 +858,6 @@
  *	Set or clear the multicast filter for this adapter.
  */
 
-/* The little-endian AUTODIN32 ethernet CRC calculation.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-    unsigned int crc = 0xffffffff;	/* Initial value. */
-    while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-    }
-    return crc;
-}
-
 static void set_rx_mode_8002(struct net_device *dev)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/au1000_eth.c linux/drivers/net/au1000_eth.c
--- linux.orig/drivers/net/au1000_eth.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/au1000_eth.c	2002-07-20 01:08:21.000000000 +0000
@@ -22,15 +22,8 @@
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
  * ########################################################################
- *
- * 
  */
-
-#ifndef __mips__
-#error This driver only works with MIPS architectures!
-#endif
-
-
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -47,6 +40,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
+#include <asm/mipsregs.h>
 #include <asm/irq.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -64,6 +58,7 @@
 static void *dma_alloc(size_t, dma_addr_t *);
 static void dma_free(void *, size_t);
 static void hard_stop(struct net_device *);
+static void enable_rx_tx(struct net_device *dev);
 static int __init au1000_probe1(struct net_device *, long, int, int);
 static int au1000_init(struct net_device *);
 static int au1000_open(struct net_device *);
@@ -78,15 +73,17 @@
 static inline void update_tx_stats(struct net_device *, u32, u32);
 static inline void update_rx_stats(struct net_device *, u32);
 static void au1000_timer(unsigned long);
-static void cleanup_buffers(struct net_device *);
 static int au1000_ioctl(struct net_device *, struct ifreq *, int);
 static int mdio_read(struct net_device *, int, int);
 static void mdio_write(struct net_device *, int, int, u16);
-static inline void sync(void);
+static void dump_mii(struct net_device *dev, int phy_id);
 
+// externs
 extern  void ack_rise_edge_irq(unsigned int);
-
-static int next_dev;
+extern int get_ethernet_addr(char *ethernet_addr);
+extern inline void str2eaddr(unsigned char *ea, unsigned char *str);
+extern inline unsigned char str2hexnum(unsigned char c);
+extern char * __init prom_getcmdline(void);
 
 /*
  * Theory of operation
@@ -105,24 +102,30 @@
 
 
 /*
- * Base address and interupt of the Au1000 ethernet macs
+ * Base address and interupt of the Au1xxx ethernet macs
  */
 static struct {
 	unsigned int port;
 	int irq;
 } au1000_iflist[NUM_INTERFACES] = {
-	{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
-	{AU1000_ETH1_BASE, AU1000_ETH1_IRQ}
-};
+		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
+		{AU1000_ETH1_BASE, AU1000_ETH1_IRQ}
+	},
+  au1500_iflist[NUM_INTERFACES] = {
+		{AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, 
+		{AU1500_ETH1_BASE, AU1000_ETH1_IRQ}
+	};
 
 
 static char version[] __devinitdata =
-    "au1000eth.c:0.1 ppopov@mvista.com\n";
+    "au1000eth.c:1.0 ppopov@mvista.com\n";
 
-// FIX! Need real Ethernet addresses
-static unsigned char au1000_mac_addr[2][6] __devinitdata = { 
-	{0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00},
-	{0x00, 0x50, 0xc2, 0x0c, 0x40, 0x00}
+/* These addresses are only used if yamon doesn't tell us what
+ * the mac address is, and the mac address is not passed on the
+ * command line.
+ */
+static unsigned char au1000_mac_addr[6] __devinitdata = { 
+	0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00
 };
 
 #define nibswap(x) ((((x) >> 4) & 0x0f) | (((x) << 4) & 0xf0))
@@ -132,11 +135,6 @@
 #define cpu_to_dma32 cpu_to_be32
 #define dma32_to_cpu be32_to_cpu
 
-/* CPU pipeline flush */
-static inline void sync(void)
-{
-	asm volatile ("sync");
-}
 
 /* FIXME 
  * All of the PHY code really should be detached from the MAC 
@@ -147,7 +145,8 @@
 	{"unknown", 
 	"10Base2", "10BaseT", 
 	"AUI",
-	"100BaseT", "100BaseTX", "100BaseFX"};
+	"100BaseT", "100BaseTX", "100BaseFX"
+	};
 
 int bcm_5201_init(struct net_device *dev, int phy_addr)
 {
@@ -168,7 +167,8 @@
 	data = mdio_read(dev, phy_addr, MII_CONTROL);
 	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
 	mdio_write(dev, phy_addr, MII_CONTROL, data);
-	//dump_mii(dev, phy_addr);
+
+	if (au1000_debug > 4) dump_mii(dev, phy_addr);
 	return 0;
 }
 
@@ -228,10 +228,91 @@
 	else {
 		*link = 0;
 		*speed = 0;
+		dev->if_port = IF_PORT_UNKNOWN;
 	}
 	return 0;
 }
 
+int lsi_80227_init(struct net_device *dev, int phy_addr)
+{
+	if (au1000_debug > 4)
+		printk("lsi_80227_init\n");
+
+	/* restart auto-negotiation */
+	mdio_write(dev, phy_addr, 0, 0x3200);
+
+	/* set up LEDs to correct display */
+	mdio_write(dev, phy_addr, 17, 0xffc0);
+
+	if (au1000_debug > 4)
+		dump_mii(dev, phy_addr);
+	return 0;
+}
+
+int lsi_80227_reset(struct net_device *dev, int phy_addr)
+{
+	s16 mii_control, timeout;
+	
+	if (au1000_debug > 4) {
+		printk("lsi_80227_reset\n");
+		dump_mii(dev, phy_addr);
+	}
+
+	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
+	mdelay(1);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+		if ((mii_control & MII_CNTL_RESET) == 0)
+			break;
+		mdelay(1);
+	}
+	if (mii_control & MII_CNTL_RESET) {
+		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
+		return -1;
+	}
+	return 0;
+}
+
+int
+lsi_80227_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+{
+	u16 mii_data;
+	struct au1000_private *aup;
+
+	if (!dev) {
+		printk(KERN_ERR "lsi_80227_status error: NULL dev\n");
+		return -1;
+	}
+	aup = (struct au1000_private *) dev->priv;
+
+	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
+	if (mii_data & MII_STAT_LINK) {
+		*link = 1;
+		mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_STAT);
+		if (mii_data & MII_LSI_STAT_SPD) {
+			if (mii_data & MII_LSI_STAT_FDX) {
+				*speed = IF_PORT_100BASEFX;
+				dev->if_port = IF_PORT_100BASEFX;
+			}
+			else {
+				*speed = IF_PORT_100BASETX;
+				dev->if_port = IF_PORT_100BASETX;
+			}
+		}
+		else  {
+			*speed = IF_PORT_10BASET;
+			dev->if_port = IF_PORT_10BASET;
+		}
+
+	}
+	else {
+		*link = 0;
+		*speed = 0;
+		dev->if_port = IF_PORT_UNKNOWN;
+	}
+	return 0;
+}
 
 int am79c901_init(struct net_device *dev, int phy_addr)
 {
@@ -263,6 +344,12 @@
 	am79c901_status,
 };
 
+struct phy_ops lsi_80227_ops = { 
+	lsi_80227_init,
+	lsi_80227_reset,
+	lsi_80227_status,
+};
+
 static struct mii_chip_info {
 	const char * name;
 	u16 phy_id0;
@@ -271,6 +358,7 @@
 } mii_chip_table[] = {
 	{"Broadcom BCM5201 10/100 BaseT PHY",  0x0040, 0x6212, &bcm_5201_ops },
 	{"AMD 79C901 HomePNA PHY",  0x0000, 0x35c8, &am79c901_ops },
+	{"LSI 80227 10/100 BaseT PHY", 0x0016, 0xf840, &lsi_80227_ops },
 	{0,},
 };
 
@@ -283,7 +371,8 @@
 	while (aup->mac->mii_control & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: read_MII busy timeout!!\n", dev->name);
+			printk(KERN_ERR "%s: read_MII busy timeout!!\n", 
+					dev->name);
 			return -1;
 		}
 	}
@@ -297,7 +386,8 @@
 	while (aup->mac->mii_control & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: mdio_read busy timeout!!\n", dev->name);
+			printk(KERN_ERR "%s: mdio_read busy timeout!!\n", 
+					dev->name);
 			return -1;
 		}
 	}
@@ -313,7 +403,8 @@
 	while (aup->mac->mii_control & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: mdio_write busy timeout!!\n", dev->name);
+			printk(KERN_ERR "%s: mdio_write busy timeout!!\n", 
+					dev->name);
 			return;
 		}
 	}
@@ -362,25 +453,34 @@
 		phy_id1 = mdio_read(dev, phy_addr, MII_PHY_ID1);
 
 		/* search our mii table for the current mii */ 
-		for (i = 0; mii_chip_table[i].phy_id1; i++)
+		for (i = 0; mii_chip_table[i].phy_id1; i++) {
 			if (phy_id0 == mii_chip_table[i].phy_id0 &&
 			    phy_id1 == mii_chip_table[i].phy_id1) {
 				struct mii_phy * mii_phy;
 
-				printk(KERN_INFO "%s: %s found at phy address %d\n",
-				       dev->name, mii_chip_table[i].name, phy_addr);
-				if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) != NULL) {
+				printk(KERN_INFO "%s: %s at phy address %d\n",
+				       dev->name, mii_chip_table[i].name, 
+				       phy_addr);
+				mii_phy = kmalloc(sizeof(struct mii_phy), 
+						GFP_KERNEL);
+				if (mii_phy) {
 					mii_phy->chip_info = mii_chip_table+i;
 					mii_phy->phy_addr = phy_addr;
-					//mii_phy->status = mdio_read(dev, phy_addr, MII_STATUS);
 					mii_phy->next = aup->mii;
-					aup->phy_ops = mii_chip_table[i].phy_ops;
+					aup->phy_ops = 
+						mii_chip_table[i].phy_ops;
 					aup->mii = mii_phy;
+					aup->phy_ops->phy_init(dev,phy_addr);
+				} else {
+					printk(KERN_ERR "%s: out of memory\n",
+							dev->name);
+					return -1;
 				}
 				/* the current mii is on our mii_info_table,
 				   try next address */
 				break;
 			}
+		}
 	}
 
 	if (aup->mii == NULL) {
@@ -390,7 +490,8 @@
 
 	/* use last PHY */
 	aup->phy_addr = aup->mii->phy_addr;
-	printk(KERN_INFO "%s: Using %s as default\n", dev->name, aup->mii->chip_info->name);
+	printk(KERN_INFO "%s: Using %s as default\n", 
+			dev->name, aup->mii->chip_info->name);
 
 	return 0;
 }
@@ -437,7 +538,7 @@
 	if (ret != NULL) {
 		memset(ret, 0, size);
 		*dma_handle = virt_to_bus(ret);
-		ret = KSEG0ADDR(ret);
+		ret = (void *)KSEG0ADDR(ret);
 	}
 	return ret;
 }
@@ -445,11 +546,22 @@
 
 static void dma_free(void *vaddr, size_t size)
 {
-	vaddr = KSEG0ADDR(vaddr);
+	vaddr = (void *)KSEG0ADDR(vaddr);
 	free_pages((unsigned long) vaddr, get_order(size));
 }
 
 
+static void enable_rx_tx(struct net_device *dev)
+{
+	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+
+	if (au1000_debug > 4)
+		printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
+
+	aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+	au_sync_delay(10);
+}
+
 static void hard_stop(struct net_device *dev)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
@@ -458,8 +570,7 @@
 		printk(KERN_INFO "%s: hard stop\n", dev->name);
 
 	aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
-	sync();
-	mdelay(10);
+	au_sync_delay(10);
 }
 
 
@@ -468,39 +579,21 @@
 	u32 flags;
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 
-	if (au1000_debug > 4)
-		printk(KERN_INFO "%s: reset mac, aup %x\n", dev->name, (unsigned)aup);
+	if (au1000_debug > 4) 
+		printk(KERN_INFO "%s: reset mac, aup %x\n", 
+				dev->name, (unsigned)aup);
 
 	spin_lock_irqsave(&aup->lock, flags);
 	del_timer(&aup->timer);
 	hard_stop(dev);
-	*aup->enable |= MAC_DMA_RESET;
-	sync();
-	mdelay(10);
+	*aup->enable = MAC_EN_CLOCK_ENABLE;
+	au_sync_delay(2);
+       	*aup->enable = 0;
+	au_sync_delay(2);
 	aup->tx_full = 0;
 	spin_unlock_irqrestore(&aup->lock, flags);
 }
 
-static void cleanup_buffers(struct net_device *dev)
-{
-	int i;
-	struct au1000_private *aup = (struct au1000_private *) dev->priv;
-
-	for (i=0; i<NUM_RX_DMA; i++) {
-		if (aup->rx_db_inuse[i]) {
-			ReleaseDB(aup, aup->rx_db_inuse[i]);
-			aup->rx_db_inuse[i] = 0;
-		}
-	}
-
-	for (i=0; i<NUM_TX_DMA; i++) {
-		if (aup->tx_db_inuse[i]) {
-			ReleaseDB(aup, aup->tx_db_inuse[i]);
-			aup->tx_db_inuse[i] = 0;
-		}
-	}
-}
-
 
 /* 
  * Setup the receive and transmit "rings".  These pointers are the addresses
@@ -513,44 +606,40 @@
 	int i;
 
 	for (i=0; i<NUM_RX_DMA; i++) {
-		aup->rx_dma_ring[i] = (volatile rx_dma_t *) ioremap_nocache((unsigned long)
-					(rx_base + sizeof(rx_dma_t)*i), sizeof(rx_dma_t));
+		aup->rx_dma_ring[i] = 
+			(volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
 	}
 	for (i=0; i<NUM_TX_DMA; i++) {
-		aup->tx_dma_ring[i] = (volatile tx_dma_t *)ioremap_nocache((unsigned long)
-				(tx_base + sizeof(tx_dma_t)*i), sizeof(tx_dma_t));
+		aup->tx_dma_ring[i] = 
+			(volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
 	}
 }
 
-/*
- * Probe for a AU1000 ethernet controller.
- */
-int __init au1000_probe(struct net_device *dev)
+static int __init au1000_init_module(void)
 {
-	int base_addr = au1000_iflist[next_dev].port;
-	int irq = au1000_iflist[next_dev].irq;
-
-#ifndef CONFIG_MIPS_AU1000_ENET
-	return -ENODEV;
-#endif
-
-	if (au1000_debug > 4)
-		printk(KERN_INFO "%s: au1000_probe base_addr %x\n", 
-				dev->name, base_addr);
+	int i;
+	int prid;
+	int base_addr, irq;
 
-	if (next_dev >= NUM_INTERFACES) {
-		return -ENODEV;
-	}
-	if (au1000_probe1(dev, base_addr, irq, next_dev) == 0) {
-		next_dev++;
-		return 0;
+	prid = read_32bit_cp0_register(CP0_PRID);
+	for (i=0; i<NUM_INTERFACES; i++) {
+		if ( (prid & 0xffff0000) == 0x00030000 ) {
+			base_addr = au1000_iflist[i].port;
+			irq = au1000_iflist[i].irq;
+		} else if ( (prid & 0xffff0000) == 0x01030000 ) {
+			base_addr = au1500_iflist[i].port;
+			irq = au1500_iflist[i].irq;
+		} else {
+			printk(KERN_ERR "au1000 eth: unknown Processor ID\n");
+			return -ENODEV;
+		}
+		if (au1000_probe1(NULL, base_addr, irq, i) != 0) {
+			return -ENODEV;
+		}
 	}
-	next_dev++;
-	return -ENODEV;
+	return 0;
 }
 
-
-
 static int __init
 au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
 {
@@ -558,11 +647,8 @@
 	struct au1000_private *aup = NULL;
 	int i, retval = 0;
 	db_dest_t *pDB, *pDBfree;
-	u16 link, speed;
-
-	if ((ioaddr != AU1000_ETH0_BASE) && (ioaddr != AU1000_ETH1_BASE))  {
-		return -ENODEV;
-	}
+	char *pmac, *argptr;
+	char ethaddr[6];
 
 	if (!request_region(ioaddr, MAC_IOSIZE, "Au1000 ENET")) {
 		 return -ENODEV;
@@ -578,13 +664,13 @@
 		 return -ENODEV;
 	}
 
-	printk("%s: Au1000 ethernet found at 0x%lx, irq %d\n",
-	       dev->name, ioaddr, irq);
-
+	printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", 
+			dev->name, ioaddr, irq);
 
 	/* Initialize our private structure */
 	if (dev->priv == NULL) {
-		aup = (struct au1000_private *) kmalloc(sizeof(*aup), GFP_KERNEL);
+		aup = (struct au1000_private *) 
+			kmalloc(sizeof(*aup), GFP_KERNEL);
 		if (aup == NULL) {
 			retval = -ENOMEM;
 			goto free_region;
@@ -597,52 +683,75 @@
 
 
 	/* Allocate the data buffers */
-	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
+	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
+			(NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
 	if (!aup->vaddr) {
 		retval = -ENOMEM;
 		goto free_region;
 	}
 
 	/* aup->mac is the base address of the MAC's registers */
-	aup->mac = (volatile mac_reg_t *)ioremap_nocache((unsigned long)ioaddr, sizeof(*aup->mac));
+	aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
 	/* Setup some variables for quick register address access */
-	if (ioaddr == AU1000_ETH0_BASE) {
-		aup->enable = (volatile u32 *)
-			ioremap_nocache((unsigned long)MAC0_ENABLE, sizeof(*aup->enable)); 
-		memcpy(dev->dev_addr, au1000_mac_addr[0], sizeof(dev->dev_addr));
+	switch (ioaddr) {
+	case AU1000_ETH0_BASE:
+	case AU1500_ETH0_BASE:
+		/* check env variables first */
+		if (!get_ethernet_addr(ethaddr)) { 
+			memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
+		} else {
+			/* Check command line */
+			argptr = prom_getcmdline();
+			if ((pmac = strstr(argptr, "ethaddr=")) == NULL) {
+				printk(KERN_INFO "%s: No mac address found\n", 
+						dev->name);
+				/* use the hard coded mac addresses */
+			} else {
+				str2eaddr(ethaddr, pmac + strlen("ethaddr="));
+				memcpy(au1000_mac_addr, ethaddr, 
+						sizeof(dev->dev_addr));
+			}
+		}
+		if (ioaddr == AU1000_ETH0_BASE)
+			aup->enable = (volatile u32 *) 
+				((unsigned long)AU1000_MAC0_ENABLE);
+		else
+			aup->enable = (volatile u32 *) 
+				((unsigned long)AU1500_MAC0_ENABLE);
+		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
 		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
-	}
-	else if (ioaddr == AU1000_ETH1_BASE) {
-		aup->enable = (volatile u32 *)
-			ioremap_nocache((unsigned long)MAC1_ENABLE, sizeof(*aup->enable)); 
-		memcpy(dev->dev_addr, au1000_mac_addr[1], sizeof(dev->dev_addr));
+			break;
+	case AU1000_ETH1_BASE:
+	case AU1500_ETH1_BASE:
+		if (ioaddr == AU1000_ETH1_BASE)
+			aup->enable = (volatile u32 *) 
+				((unsigned long)AU1000_MAC1_ENABLE);
+		else
+			aup->enable = (volatile u32 *) 
+				((unsigned long)AU1500_MAC1_ENABLE);
+		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
+		dev->dev_addr[4] += 0x10;
 		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
-	}
-	else { /* should never happen */
-		 printk (KERN_ERR "au1000 eth: bad ioaddr %x\n", (unsigned)ioaddr);  
-		 retval = -ENODEV;
-		 goto free_region;
+			break;
+	default:
+		printk(KERN_ERR "%s: bad ioaddr\n", dev->name);
+		break;
+
 	}
 
 	aup->phy_addr = PHY_ADDRESS;
+
 	/* bring the device out of reset, otherwise probing the mii
 	 * will hang */
-	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
-		MAC_EN_CLOCK_ENABLE | MAC_EN_TOSS;
-	sync();
-	mdelay(2);
+	*aup->enable = MAC_EN_CLOCK_ENABLE;
+	au_sync_delay(2);
+	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
+		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
+	au_sync_delay(2);
+
 	if (mii_probe(dev) != 0) {
 		 goto free_region;
 	}
-	aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
-	if (!link) {
-		printk(KERN_INFO "%s: link down resetting...\n", dev->name);
-		aup->phy_ops->phy_reset(dev, aup->phy_addr);
-		aup->phy_ops->phy_init(dev, aup->phy_addr);
-	}
-	else {
-		printk(KERN_INFO "%s: link up (%s)\n", dev->name, phy_link[speed]);
-	}
 
 	pDBfree = NULL;
 	/* setup the data buffer descriptors and attach a buffer to each one */
@@ -688,18 +797,18 @@
 	ether_setup(dev);
 
 	/* 
-	 * The boot code uses the ethernet controller, so reset it to start fresh.
-	 * au1000_init() expects that the device is in reset state.
+	 * The boot code uses the ethernet controller, so reset it to start 
+	 * fresh.  au1000_init() expects that the device is in reset state.
 	 */
 	reset_mac(dev);
-
 	return 0;
 
 free_region:
 	release_region(ioaddr, MAC_IOSIZE);
 	unregister_netdev(dev);
-	if (aup->vaddr)
-		dma_free((void *)aup->vaddr, MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
+	if (aup->vaddr) 
+		dma_free((void *)aup->vaddr, 
+				MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
 	if (dev->priv != NULL)
 		kfree(dev->priv);
 	kfree(dev);
@@ -723,18 +832,19 @@
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 	u32 flags;
 	int i;
-	u32 value, control;
+	u32 control;
+	u16 link, speed;
 
-	if (au1000_debug > 4) printk("%s: au1000_init", dev->name);
+	if (au1000_debug > 4) printk("%s: au1000_init\n", dev->name);
 
 	spin_lock_irqsave(&aup->lock, flags);
 
 	/* bring the device out of reset */
-	value = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
-		MAC_EN_CLOCK_ENABLE | MAC_EN_TOSS;
-	*aup->enable = value;
-	sync();
-	mdelay(200);
+	*aup->enable = MAC_EN_CLOCK_ENABLE;
+        au_sync_delay(2);
+	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
+		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
+	au_sync_delay(20);
 
 	aup->mac->control = 0;
 	aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;
@@ -748,13 +858,18 @@
 	for (i=0; i<NUM_RX_DMA; i++) {
 		aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
 	}
+	au_sync();
 
-	sync();
+	aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
 	control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE;
 #ifndef CONFIG_CPU_LITTLE_ENDIAN
 	control |= MAC_BIG_ENDIAN;
 #endif
+	if (link && (dev->if_port == IF_PORT_100BASEFX)) {
+		control |= MAC_FULL_DUPLEX;
+	}
 	aup->mac->control = control;
+	au_sync();
 
 	spin_unlock_irqrestore(&aup->lock, flags);
 	return 0;
@@ -764,23 +879,22 @@
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
-	u16 mii_data, link, speed;
+	unsigned char if_port;
+	u16 link, speed;
 
 	if (!dev) {
 		/* fatal error, don't restart the timer */
 		printk(KERN_ERR "au1000_timer error: NULL dev\n");
 		return;
 	}
-	if (!(dev->flags & IFF_UP)) {
-		goto set_timer;
-	}
 
+	if_port = dev->if_port;
 	if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
 		if (link) {
 			if (!(dev->flags & IFF_RUNNING)) {
 				netif_carrier_on(dev);
 				dev->flags |= IFF_RUNNING;
-				printk(KERN_DEBUG "%s: link up\n", dev->name);
+				printk(KERN_INFO "%s: link up\n", dev->name);
 			}
 		}
 		else {
@@ -788,12 +902,27 @@
 				netif_carrier_off(dev);
 				dev->flags &= ~IFF_RUNNING;
 				dev->if_port = 0;
-				printk(KERN_DEBUG "%s: link down\n", dev->name);
+				printk(KERN_INFO "%s: link down\n", dev->name);
 			}
 		}
 	}
 
-set_timer:
+	if (link && (dev->if_port != if_port) && 
+			(dev->if_port != IF_PORT_UNKNOWN)) {
+		hard_stop(dev);
+		if (dev->if_port == IF_PORT_100BASEFX) {
+			printk(KERN_INFO "%s: going to full duplex\n", 
+					dev->name);
+			aup->mac->control |= MAC_FULL_DUPLEX;
+			au_sync_delay(1);
+		}
+		else {
+			aup->mac->control &= ~MAC_FULL_DUPLEX;
+			au_sync_delay(1);
+		}
+		enable_rx_tx(dev);
+	}
+
 	aup->timer.expires = RUN_AT((1*HZ)); 
 	aup->timer.data = (unsigned long)dev;
 	aup->timer.function = &au1000_timer; /* timer handler */
@@ -819,8 +948,10 @@
 	}
 	netif_start_queue(dev);
 
-	if ((retval = request_irq(dev->irq, &au1000_interrupt, 0, dev->name, dev))) {
-		printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
+	if ((retval = request_irq(dev->irq, &au1000_interrupt, 0, 
+					dev->name, dev))) {
+		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
+				dev->name, dev->irq);
 		MOD_DEC_USE_COUNT;
 		return retval;
 	}
@@ -860,8 +991,13 @@
 	return 0;
 }
 
+static void __exit au1000_cleanup_module(void)
+{
+}
+
 
-static inline void update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
+static inline void 
+update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 	struct net_device_stats *ps = &aup->stats;
@@ -870,10 +1006,20 @@
 	ps->tx_bytes += pkt_len;
 
 	if (status & TX_FRAME_ABORTED) {
-		ps->tx_errors++;
-		ps->tx_aborted_errors++;
-		if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
-			ps->tx_carrier_errors++;
+		if (dev->if_port == IF_PORT_100BASEFX) {
+			if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
+				/* any other tx errors are only valid
+				 * in half duplex mode */
+				ps->tx_errors++;
+				ps->tx_aborted_errors++;
+			}
+		}
+		else {
+			ps->tx_errors++;
+			ps->tx_aborted_errors++;
+			if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
+				ps->tx_carrier_errors++;
+		}
 	}
 }
 
@@ -894,7 +1040,7 @@
 		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
 		ptxd->buff_stat &= ~TX_T_DONE;
 		ptxd->len = 0;
-		sync();
+		au_sync();
 
 		aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
 		ptxd = aup->tx_dma_ring[aup->tx_tail];
@@ -913,26 +1059,22 @@
 static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
-	//unsigned long flags;
 	volatile tx_dma_t *ptxd;
 	u32 buff_stat;
 	db_dest_t *pDB;
 	int i;
 
 	if (au1000_debug > 4)
-		printk("%s: tx: aup %x len=%d, data=%p, head %d\n",
-		       dev->name, (unsigned)aup, skb->len, skb->data, aup->tx_head);
+		printk("%s: tx: aup %x len=%d, data=%p, head %d\n", 
+				dev->name, (unsigned)aup, skb->len, 
+				skb->data, aup->tx_head);
 
-	/* Prevent interrupts from changing the Tx ring */
-	//spin_lock_irqsave(&aup->lock, flags);
-	
 	ptxd = aup->tx_dma_ring[aup->tx_head];
 	buff_stat = ptxd->buff_stat;
 	if (buff_stat & TX_DMA_ENABLE) {
 		/* We've wrapped around and the transmitter is still busy */
 		netif_stop_queue(dev);
 		aup->tx_full = 1;
-		//spin_unlock_irqrestore(&aup->lock, flags);
 		return 1;
 	}
 	else if (buff_stat & TX_T_DONE) {
@@ -957,11 +1099,10 @@
 		ptxd->len = skb->len;
 
 	ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
-	sync();
+	au_sync();
 	dev_kfree_skb(skb);
 	aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
 	dev->trans_start = jiffies;
-	//spin_unlock_irqrestore(&aup->lock, flags);
 	return 0;
 }
 
@@ -1026,7 +1167,7 @@
 			skb_reserve(skb, 2);	/* 16 byte IP header align */
 			eth_copy_and_sum(skb, (unsigned char *)pDB->vaddr, 
 					status & RX_FRAME_LEN_MASK, 0);
-			skb_put(skb, status & RX_FRAME_LEN_MASK); /* Make room */
+			skb_put(skb, status & RX_FRAME_LEN_MASK);
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);	/* pass the packet to upper layers */
 		}
@@ -1056,7 +1197,7 @@
 		}
 		prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
 		aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
-		sync();
+		au_sync();
 
 		/* next descriptor */
 		prxd = aup->rx_dma_ring[aup->rx_head];
@@ -1078,8 +1219,8 @@
 		printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
 		return;
 	}
-	au1000_rx(dev);
 	au1000_tx_ack(dev);
+	au1000_rx(dev);
 }
 
 
@@ -1105,7 +1246,8 @@
 		int bit;
 		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
 			crc = (crc << 1) ^
-				((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+				((crc < 0) ^ (current_octet & 1) ? 
+				 ethernet_polynomial : 0);
     }
     return crc;
 }
@@ -1114,9 +1256,8 @@
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 
-	/* fixme */
 	if (au1000_debug > 4) 
-		printk("%s: set_multicast: flags=%x\n", dev->name, dev->flags);
+		printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags);
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		aup->mac->control |= MAC_PROMISCUOUS;
@@ -1134,10 +1275,12 @@
 		mc_filter[1] = mc_filter[0] = 0;
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, mc_filter);
+			set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, 
+					mc_filter);
 		}
 		aup->mac->multi_hash_high = mc_filter[1];
 		aup->mac->multi_hash_low = mc_filter[0];
+		aup->mac->control &= ~MAC_PROMISCUOUS;
 		aup->mac->control |= MAC_HASH_MODE;
 	}
 }
@@ -1145,27 +1288,27 @@
 
 static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	//struct au1000_private *aup = (struct au1000_private *) dev->priv;
 	u16 *data = (u16 *)&rq->ifr_data;
 
 	/* fixme */
-	switch(cmd) { 
-		case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
-		case SIOCDEVPRIVATE:		/* binary compat, remove in 2.5 */
+	switch (cmd) { 
+	case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
+	case SIOCDEVPRIVATE:		/* binary compat, remove in 2.5 */
 		data[0] = PHY_ADDRESS;
 
-		case SIOCGMIIREG:		/* Read the specified MII register. */
-		case SIOCDEVPRIVATE+1:		/* binary compat, remove in 2.5 */
+	case SIOCGMIIREG:		/* Read the specified MII register. */
+	case SIOCDEVPRIVATE+1:		/* binary compat, remove in 2.5 */
 		//data[3] = mdio_read(ioaddr, data[0], data[1]); 
 		return 0;
 
-		case SIOCSMIIREG:		/* Write the specified MII register */
-		case SIOCDEVPRIVATE+2:		/* binary compat, remove in 2.5 */
+	case SIOCSMIIREG:		/* Write the specified MII register */
+	case SIOCDEVPRIVATE+2:		/* binary compat, remove in 2.5 */
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 		//mdio_write(ioaddr, data[0], data[1], data[2]);
 		return 0;
-		default:
+
+	default:
 		return -EOPNOTSUPP;
 	}
 }
@@ -1183,7 +1326,8 @@
 
 	switch(map->port){
 		case IF_PORT_UNKNOWN: /* use auto here */   
-			printk("auto\\n");
+			printk(KERN_INFO "%s: config phy for aneg\n", 
+					dev->name);
 			dev->if_port = map->port;
 			/* Link Down: the timer will bring it up */
 			netif_carrier_off(dev);
@@ -1193,13 +1337,15 @@
 			control &= ~(MII_CNTL_FDX | MII_CNTL_F100);
 
 			/* enable auto negotiation and reset the negotiation */
-			mdio_write(dev, aup->phy_addr,
-				   MII_CONTROL, control | MII_CNTL_AUTO | MII_CNTL_RST_AUTO);
+			mdio_write(dev, aup->phy_addr, MII_CONTROL, 
+					control | MII_CNTL_AUTO | 
+					MII_CNTL_RST_AUTO);
 
 			break;
     
 		case IF_PORT_10BASET: /* 10BaseT */         
-			printk("10baseT\n");
+			printk(KERN_INFO "%s: config phy for 10BaseT\n", 
+					dev->name);
 			dev->if_port = map->port;
 	
 			/* Link Down: the timer will bring it up */
@@ -1207,8 +1353,8 @@
 
 			/* set Speed to 10Mbps, Half Duplex */
 			control = mdio_read(dev, aup->phy_addr, MII_CONTROL);
-			printk("read control %x\n", control);
-			control &= ~(MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_FDX);
+			control &= ~(MII_CNTL_F100 | MII_CNTL_AUTO | 
+					MII_CNTL_FDX);
 	
 			/* disable auto negotiation and force 10M/HD mode*/
 			mdio_write(dev, aup->phy_addr, MII_CONTROL, control);
@@ -1216,7 +1362,8 @@
     
 		case IF_PORT_100BASET: /* 100BaseT */
 		case IF_PORT_100BASETX: /* 100BaseTx */ 
-			printk("100 base T/TX\n");
+			printk(KERN_INFO "%s: config phy for 100BaseTX\n", 
+					dev->name);
 			dev->if_port = map->port;
 	
 			/* Link Down: the timer will bring it up */
@@ -1232,7 +1379,8 @@
 			break;
     
 		case IF_PORT_100BASEFX: /* 100BaseFx */
-			printk("100 Base FX\n");
+			printk(KERN_INFO "%s: config phy for 100BaseFX\n", 
+					dev->name);
 			dev->if_port = map->port;
 	
 			/* Link Down: the timer will bring it up */
@@ -1248,12 +1396,14 @@
 		case IF_PORT_10BASE2: /* 10Base2 */
 		case IF_PORT_AUI: /* AUI */
 		/* These Modes are not supported (are they?)*/
-			printk(KERN_INFO "Not supported");
+			printk(KERN_ERR "%s: 10Base2/AUI not supported", 
+					dev->name);
 			return -EOPNOTSUPP;
 			break;
     
 		default:
-			printk("Invalid");
+			printk(KERN_ERR "%s: Invalid media selected", 
+					dev->name);
 			return -EINVAL;
 	}
 	return 0;
@@ -1271,3 +1421,6 @@
 	}
 	return 0;
 }
+
+module_init(au1000_init_module);
+module_exit(au1000_cleanup_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/au1000_eth.h linux/drivers/net/au1000_eth.h
--- linux.orig/drivers/net/au1000_eth.h	2001-07-04 21:41:33.000000000 +0000
+++ linux/drivers/net/au1000_eth.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,13 +1,10 @@
 /*
- *
  * Alchemy Semi Au1000 ethernet driver include file
  *
  * Author: Pete Popov <ppopov@mvista.com>
  *
  * Copyright 2001 MontaVista Software Inc.
  *
- * ########################################################################
- *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
  *  published by the Free Software Foundation.
@@ -20,11 +17,8 @@
  *  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>
 
 
 #define NUM_INTERFACES 2
@@ -39,7 +33,7 @@
 #define ETH_TX_TIMEOUT HZ/4
 #define MAC_MIN_PKT_SIZE 64
 
-#ifdef CONFIG_MIPS_PB1000
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500)
 #define PHY_ADDRESS              0
 #define PHY_CONTROL_DEFAULT 0x3000
 #define PHY_CONTROL_REG_ADDR     0
@@ -60,7 +54,9 @@
 #define MII_ANLPAR  0x0005
 #define MII_AEXP    0x0006
 #define MII_ANEXT   0x0007
-#define MII_AUX_CNTRL 0x18
+#define MII_LSI_CONFIG 0x0011
+#define MII_LSI_STAT   0x0012
+#define MII_AUX_CNTRL  0x0018
 
 /* mii registers specific to AMD 79C901 */
 #define	MII_STATUS_SUMMARY = 0x0018
@@ -124,6 +120,11 @@
 #define	MII_STSSUM_AUTO  0x0002
 #define MII_STSSUM_SPD   0x0001
 
+/* lsi status register */
+
+#define MII_LSI_STAT_FDX	0x0008
+#define MII_LSI_STAT_SPD	0x0010
+
 /* Auxilliary Control/Status Register */
 #define MII_AUX_FDX      0x0001
 #define MII_AUX_100      0x0002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/bmac.c linux/drivers/net/bmac.c
--- linux.orig/drivers/net/bmac.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/bmac.c	2002-07-20 01:08:23.000000000 +0000
@@ -17,6 +17,7 @@
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/prom.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
@@ -24,11 +25,11 @@
 #include <asm/pgtable.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
+#include <asm/irq.h>
 #ifdef CONFIG_PMAC_PBOOK
 #include <linux/adb.h>
 #include <linux/pmu.h>
-#include <asm/irq.h>
-#endif
+#endif /* CONFIG_PMAC_PBOOK */
 #include "bmac.h"
 
 #define trunc_page(x)	((void *)(((unsigned long)(x)) & ~((unsigned long)(PAGE_SIZE - 1))))
@@ -1048,16 +1049,13 @@
 
 /* The version of set_multicast below was lifted from sunhme.c */
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 static void bmac_set_multicast(struct net_device *dev)
 {
 	struct dev_mc_list *dmi = dev->mc_list;
 	char *addrs;
 	int i, j, bit, byte;
 	unsigned short rx_cfg;
-	u32 crc, poly = CRC_POLYNOMIAL_LE;
+	u32 crc;
 
 	if((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
 		bmwrite(dev, BHASH0, 0xffff);
@@ -1084,17 +1082,7 @@
 			if(!(*addrs & 1))
 				continue;
 
-			crc = 0xffffffffU;
-			for(byte = 0; byte < 6; byte++) {
-				for(bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-					int test;
-
-					test = ((bit ^ crc) & 0x01);
-					crc >>= 1;
-					if(test)
-						crc = crc ^ poly;
-				}
-			}
+			crc = ether_crc_le(6, addrs);
 			crc >>= 26;
 			hash_table[crc >> 4] |= 1 << (crc & 0xf);
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/bonding.c linux/drivers/net/bonding.c
--- linux.orig/drivers/net/bonding.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/bonding.c	2002-07-20 01:08:33.000000000 +0000
@@ -161,6 +161,21 @@
  *     - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr 
  *     - Handle hot swap ethernet interface deregistration events to remove
  *       kernel oops following hot swap of enslaved interface
+ *
+ * 2002/1/2 - Chad N. Tindel <ctindel at ieee dot org>
+ *     - Restore original slave flags at release time.
+ *
+ * 2002/02/18 - Erik Habbinga <erik_habbinga at hp dot com>
+ *     - bond_release(): calling kfree on our_slave after call to
+ *       bond_restore_slave_flags, not before
+ *     - bond_enslave(): saving slave flags into original_flags before
+ *       call to netdev_set_master, so the IFF_SLAVE flag doesn't end
+ *       up in original_flags
+ *
+ * 2002/04/05 - Mark Smith <mark.smith at comdev dot cc> and
+ *              Steve Mead <steve.mead at comdev dot cc>
+ *     - Port Gleb Natapov's multicast support patchs from 2.4.12
+ *       to 2.4.18 adding support for multicast.
  */
 
 #include <linux/config.h>
@@ -208,11 +223,8 @@
 #define MII_ENDOF_NWAY	0x20
 
 #undef  MII_LINK_READY
-/*#define MII_LINK_READY	(MII_LINK_UP | MII_ENDOF_NWAY)*/
 #define MII_LINK_READY	(MII_LINK_UP)
 
-#define MAX_BOND_ADDR 256
-
 #ifndef BOND_LINK_ARP_INTERV
 #define BOND_LINK_ARP_INTERV	0
 #endif
@@ -223,7 +235,7 @@
 static u32 my_ip = 0;
 char *arp_target_hw_addr = NULL;
 
-static int max_bonds	= MAX_BONDS;
+static int max_bonds	= BOND_DEFAULT_MAX_BONDS;
 static int miimon	= BOND_LINK_MON_INTERV;
 static int mode		= BOND_MODE_ROUNDROBIN;
 static int updelay	= 0;
@@ -234,7 +246,7 @@
 static struct bonding *these_bonds =  NULL;
 static struct net_device *dev_bonds = NULL;
 
-MODULE_PARM(max_bonds, "1-" __MODULE_STRING(INT_MAX) "i");
+MODULE_PARM(max_bonds, "i");
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
 MODULE_PARM(miimon, "i");
 MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
@@ -260,6 +272,15 @@
 static void bond_mii_monitor(struct net_device *dev);
 static void bond_arp_monitor(struct net_device *dev);
 static int bond_event(struct notifier_block *this, unsigned long event, void *ptr);
+static void bond_restore_slave_flags(slave_t *slave);
+static void bond_mc_list_destroy(struct bonding *bond);
+static void bond_mc_add(bonding_t *bond, void *addr, int alen);
+static void bond_mc_delete(bonding_t *bond, void *addr, int alen);
+static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst, int gpf_flag);
+static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2);
+static void bond_set_promiscuity(bonding_t *bond, int inc);
+static void bond_set_allmulti(bonding_t *bond, int inc);
+static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list);
 static void bond_set_slave_inactive_flags(slave_t *slave);
 static void bond_set_slave_active_flags(slave_t *slave);
 static int bond_enslave(struct net_device *master, struct net_device *slave);
@@ -282,6 +303,11 @@
 #define IS_UP(dev)	((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \
 			(netif_running(dev) && netif_carrier_ok(dev)))
 
+static void bond_restore_slave_flags(slave_t *slave)
+{
+	slave->dev->flags = slave->original_flags;
+}
+
 static void bond_set_slave_inactive_flags(slave_t *slave)
 {
 	slave->state = BOND_STATE_BACKUP;
@@ -431,6 +457,7 @@
 
 	/* Release the bonded slaves */
 	bond_release_all(master);
+	bond_mc_list_destroy (bond);
 
 	write_unlock_irqrestore(&bond->lock, flags);
 
@@ -438,19 +465,180 @@
 	return 0;
 }
 
-static void set_multicast_list(struct net_device *master)
+/* 
+ * flush all members of flush->mc_list from device dev->mc_list
+ */
+static void bond_mc_list_flush(struct net_device *dev, struct net_device *flush)
+{ 
+	struct dev_mc_list *dmi; 
+ 
+	for (dmi = flush->mc_list; dmi != NULL; dmi = dmi->next) 
+		dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+}
+
+/*
+ * Totally destroys the mc_list in bond
+ */
+static void bond_mc_list_destroy(struct bonding *bond)
 {
+	struct dev_mc_list *dmi;
+
+	dmi = bond->mc_list; 
+	while (dmi) { 
+		bond->mc_list = dmi->next; 
+		kfree(dmi); 
+		dmi = bond->mc_list; 
+	}
+}
+
 /*
-	bonding_t *bond = master->priv;
+ * Add a Multicast address to every slave in the bonding group
+ */
+static void bond_mc_add(bonding_t *bond, void *addr, int alen)
+{ 
 	slave_t *slave;
 
-	for (slave = bond->next; slave != (slave_t*)bond; slave = slave->next) {
-		slave->dev->mc_list = master->mc_list;
-		slave->dev->mc_count = master->mc_count;
-		slave->dev->flags = master->flags;
-		slave->dev->set_multicast_list(slave->dev);
+	for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev) {
+		dev_mc_add(slave->dev, addr, alen, 0);
 	}
+} 
+
+/*
+ * Remove a multicast address from every slave in the bonding group
+ */
+static void bond_mc_delete(bonding_t *bond, void *addr, int alen)
+{ 
+	slave_t *slave; 
+
+	for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
+		dev_mc_delete(slave->dev, addr, alen, 0);
+} 
+
+/*
+ * Copy all the Multicast addresses from src to the bonding device dst
  */
+static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst,
+ int gpf_flag)
+{
+	struct dev_mc_list *dmi, *new_dmi;
+
+   	for (dmi = src; dmi != NULL; dmi = dmi->next) { 
+		new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag);
+
+		if (new_dmi == NULL) {
+			return -ENOMEM; 
+		}
+
+		new_dmi->next = dst->mc_list; 
+		dst->mc_list = new_dmi;
+
+		new_dmi->dmi_addrlen = dmi->dmi_addrlen; 
+		memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen); 
+		new_dmi->dmi_users = dmi->dmi_users;
+		new_dmi->dmi_gusers = dmi->dmi_gusers; 
+	} 
+	return 0;
+}
+
+/*
+ * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
+ */
+static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2)
+{ 
+	return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
+	 dmi1->dmi_addrlen == dmi2->dmi_addrlen;
+} 
+
+/*
+ * Push the promiscuity flag down to all slaves
+ */
+static void bond_set_promiscuity(bonding_t *bond, int inc)
+{ 
+	slave_t *slave; 
+ 
+	for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
+		dev_set_promiscuity(slave->dev, inc);
+} 
+
+/*
+ * Push the allmulti flag down to all slaves
+ */
+static void bond_set_allmulti(bonding_t *bond, int inc)
+{ 
+	slave_t *slave; 
+ 
+	for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
+		dev_set_allmulti(slave->dev, inc);
+} 
+
+/* 
+ * returns dmi entry if found, NULL otherwise 
+ */
+static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi,
+ struct dev_mc_list *mc_list)
+{ 
+	struct dev_mc_list *idmi;
+
+	for (idmi = mc_list; idmi != NULL; idmi = idmi->next) {
+		if (dmi_same(dmi, idmi)) {
+			return idmi; 
+		}
+	}
+	return NULL;
+} 
+
+static void set_multicast_list(struct net_device *master)
+{
+	bonding_t *bond = master->priv;
+	struct dev_mc_list *dmi;
+	unsigned long flags = 0;
+
+	/*
+	 * Lock the private data for the master
+	 */
+	write_lock_irqsave(&bond->lock, flags);
+
+	/*
+	 * Lock the master device so that noone trys to transmit
+	 * while we're changing things
+	 */
+	spin_lock_bh(&master->xmit_lock);
+
+	/* set promiscuity flag to slaves */
+	if ( (master->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC) )
+		bond_set_promiscuity(bond, 1); 
+
+	if ( !(master->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC) ) 
+		bond_set_promiscuity(bond, -1); 
+
+	/* set allmulti flag to slaves */ 
+	if ( (master->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI) ) 
+		bond_set_allmulti(bond, 1); 
+
+	if ( !(master->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI) )
+		bond_set_allmulti(bond, -1); 
+
+	bond->flags = master->flags; 
+
+	/* looking for addresses to add to slaves' mc list */ 
+	for (dmi = master->mc_list; dmi != NULL; dmi = dmi->next) { 
+		if (bond_mc_list_find_dmi(dmi, bond->mc_list) == NULL) 
+		 bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen); 
+	} 
+
+	/* looking for addresses to delete from slaves' list */ 
+	for (dmi = bond->mc_list; dmi != NULL; dmi = dmi->next) { 
+		if (bond_mc_list_find_dmi(dmi, master->mc_list) == NULL) 
+		 bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen); 
+	}
+
+
+	/* save master's multicast list */ 
+	bond_mc_list_destroy (bond);
+	bond_mc_list_copy (master->mc_list, bond, GFP_KERNEL);
+
+	spin_unlock_bh(&master->xmit_lock);
+	write_unlock_irqrestore(&bond->lock, flags);
 }
 
 /*
@@ -476,6 +664,7 @@
 	unsigned long flags = 0;
 	int ndx = 0;
 	int err = 0;
+	struct dev_mc_list *dmi;
 
 	if (master_dev == NULL || slave_dev == NULL) {
 		return -ENODEV;
@@ -513,6 +702,8 @@
 	}
 	memset(new_slave, 0, sizeof(slave_t));
 
+	/* save flags before call to netdev_set_master */
+	new_slave->original_flags = slave_dev->flags;
 	err = netdev_set_master(slave_dev, master_dev);
 
 	if (err) {
@@ -526,10 +717,38 @@
 
 	new_slave->dev = slave_dev;
 
+	/* set promiscuity level to new slave */ 
+	if (master_dev->flags & IFF_PROMISC)
+		dev_set_promiscuity(slave_dev, 1); 
+ 
+	/* set allmulti level to new slave */
+	if (master_dev->flags & IFF_ALLMULTI) 
+		dev_set_allmulti(slave_dev, 1); 
+ 
+	/* upload master's mc_list to new slave */ 
+	for (dmi = master_dev->mc_list; dmi != NULL; dmi = dmi->next) 
+		dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+
 	/* 
 	 * queue to the end of the slaves list, make the first element its
 	 * successor, the last one its predecessor, and make it the bond's
 	 * predecessor. 
+	 *
+	 * Just to clarify, so future bonding driver hackers don't go through
+	 * the same confusion stage I did trying to figure this out, the
+	 * slaves are stored in a double linked circular list, sortof.
+	 * In the ->next direction, the last slave points to the first slave,
+	 * bypassing bond; only the slaves are in the ->next direction.
+	 * In the ->prev direction, however, the first slave points to bond
+	 * and bond points to the last slave.
+	 *
+	 * It looks like a circle with a little bubble hanging off one side
+	 * in the ->prev direction only.
+	 *
+	 * When going through the list once, its best to start at bond->prev
+	 * and go in the ->prev direction, testing for bond.  Doing this
+	 * in the ->next direction doesn't work.  Trust me, I know this now.
+	 * :)  -mts 2002.03.14
 	 */
 	new_slave->prev       = bond->prev;
 	new_slave->prev->next = new_slave;
@@ -838,10 +1057,20 @@
 			} else {
 				printk(".\n");
 			}
-			kfree(our_slave);
 
 			/* release the slave from its bond */
-			 
+
+			/* flush master's mc_list from slave */ 
+			bond_mc_list_flush (slave, master); 
+       
+			/* unset promiscuity level from slave */
+			if (master->flags & IFF_PROMISC) 
+				dev_set_promiscuity(slave, -1); 
+       
+			/* unset allmulti level from slave */ 
+			if (master->flags & IFF_ALLMULTI)
+				dev_set_allmulti(slave, -1); 
+
 			netdev_set_master(slave, NULL);
 
 			/* only restore its RUNNING flag if monitoring set it down */
@@ -854,6 +1083,9 @@
 					dev_close(slave);
 			}
 
+			bond_restore_slave_flags(our_slave);
+			kfree(our_slave);
+
 			if (bond->current_slave == NULL) {
 				printk(KERN_INFO
 					"%s: now running without any active interface !\n",
@@ -1121,8 +1353,8 @@
 					master->name, bestslave->dev->name,
 					(updelay - bestslave->delay) * miimon);
 
-				bestslave->delay= 0;
-				bestslave->link = BOND_LINK_UP;
+				bestslave->delay = 0;
+				bestslave->link  = BOND_LINK_UP;
 			}
 
 			if (mode == BOND_MODE_ACTIVEBACKUP) {
@@ -1192,7 +1424,7 @@
 
 		read_lock(&bond->ptrlock);
 	  	if ( (!(slave->link == BOND_LINK_UP))  
-				&& (slave!= bond->current_slave) ) {
+				&& (slave != bond->current_slave) ) {
 
 			read_unlock(&bond->ptrlock);
 
@@ -1207,7 +1439,7 @@
 					slave->state = BOND_STATE_ACTIVE;
 					bond->current_slave = slave;
 				}
-				if (slave!=bond->current_slave) {
+				if (slave != bond->current_slave) {
 					slave->dev->flags |= IFF_NOARP;
 				}
 				write_unlock(&bond->ptrlock);
@@ -1311,7 +1543,7 @@
 #define isdigit(c) (c >= '0' && c <= '9')
 __inline static int atoi( char **s) 
 {
-int i=0;
+int i = 0;
 while (isdigit(**s))
   i = i*20 + *((*s)++) - '0';
 return i;
@@ -1388,7 +1620,7 @@
 		goto ret_0;
 	}
 
-	if (the_addr!= NULL) {
+	if (the_addr != NULL) {
 		*the_addr = res.word | htonl (val);
 	}
 
@@ -1420,7 +1652,7 @@
 	info->miimon = miimon;
 
 	read_lock_irqsave(&bond->lock, flags);
-	for (slave = bond->prev; slave!=(slave_t *)bond; slave = slave->prev) {
+	for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) {
 		info->num_slaves++;
 	}
 	read_unlock_irqrestore(&bond->lock, flags);
@@ -1696,7 +1928,7 @@
 
 	/* if we are sending arp packets, try to at least 
 	   identify our own ip address */
-	if ( (arp_interval > 0) && (my_ip==0) &&
+	if ( (arp_interval > 0) && (my_ip == 0) &&
 		(skb->protocol == __constant_htons(ETH_P_ARP) ) ) {
 		char *the_ip = (((char *)skb->data)) 
 				+ sizeof(struct ethhdr)  
@@ -1708,7 +1940,7 @@
 	/* if we are sending arp packets and don't know 
 	   the target hw address, save it so we don't need 
 	   to use a broadcast address */
-	if ( (arp_interval > 0) && (arp_target_hw_addr==NULL) &&
+	if ( (arp_interval > 0) && (arp_target_hw_addr == NULL) &&
 	     (skb->protocol == __constant_htons(ETH_P_IP) ) ) {
 		struct ethhdr *eth_hdr = 
 			(struct ethhdr *) (((char *)skb->data));
@@ -1751,7 +1983,7 @@
 
 	read_lock_irqsave(&bond->lock, flags);
 
-	for (slave = bond->prev; slave!=(slave_t *)bond; slave = slave->prev) {
+	for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) {
 		sstats = slave->dev->get_stats(slave->dev);
  
 		stats->rx_packets += sstats->rx_packets;
@@ -1861,7 +2093,7 @@
 static int bond_event(struct notifier_block *this, unsigned long event, 
 			void *ptr)
 {
-	struct bonding *this_bond=(struct bonding *)these_bonds;
+	struct bonding *this_bond = (struct bonding *)these_bonds;
 	struct bonding *last_bond;
 	struct net_device *event_dev = (struct net_device *)ptr;
 
@@ -1905,10 +2137,8 @@
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block bond_netdev_notifier={
-	bond_event,
-	NULL,
-	0
+static struct notifier_block bond_netdev_notifier = {
+	notifier_call: bond_event,
 };
 
 static int __init bond_init(struct net_device *dev)
@@ -2038,6 +2268,13 @@
 	/* Find a name for this unit */
 	static struct net_device *dev_bond = NULL;
 
+	if (max_bonds < 1 || max_bonds > INT_MAX) {
+		printk(KERN_WARNING 
+		       "bonding_init(): max_bonds (%d) not in range %d-%d, "
+		       "so it was reset to BOND_DEFAULT_MAX_BONDS (%d)",
+		       max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
+		max_bonds = BOND_DEFAULT_MAX_BONDS;
+	}
 	dev_bond = dev_bonds = kmalloc(max_bonds*sizeof(struct net_device), 
 					GFP_KERNEL);
 	if (dev_bond == NULL) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- linux.orig/drivers/net/cs89x0.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/cs89x0.c	2002-07-20 01:08:39.000000000 +0000
@@ -81,6 +81,9 @@
                     : Make `version[]' __initdata
                     : Uninlined the read/write reg/word functions.
 
+  Oskar Schirmer    : oskar@scara.com
+                    : HiCO.SH4 (superh) support added (irq#1, cs89x0_media=)
+
 */
 
 /* Always include 'config.h' first in case the user wants to turn on
@@ -156,6 +159,10 @@
 static unsigned int netcard_portlist[] __initdata =
    { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
 static unsigned int cs8900_irq_map[] = {12,0,0,0};
+#elif defined(CONFIG_SH_HICOSH4)
+static unsigned int netcard_portlist[] __initdata =
+   { 0x0300, 0};
+static unsigned int cs8900_irq_map[] = {1,0,0,0};
 #else
 static unsigned int netcard_portlist[] __initdata =
    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@@ -247,6 +254,20 @@
 __setup("cs89x0_dma=", dma_fn);
 #endif	/* !defined(MODULE) && (ALLOW_DMA != 0) */
 
+#ifndef MODULE
+static int g_cs89x0_media__force;
+
+static int __init media_fn(char *str)
+{
+	if (!strcmp(str, "rj45")) g_cs89x0_media__force = FORCE_RJ45;
+	else if (!strcmp(str, "aui")) g_cs89x0_media__force = FORCE_AUI;
+	else if (!strcmp(str, "bnc")) g_cs89x0_media__force = FORCE_BNC;
+	return 1;
+}
+
+__setup("cs89x0_media=", media_fn);
+#endif
+
 
 /* Check for a network adaptor of this type, and return '0' iff one exists.
    If dev->base_addr == 0, probe all likely locations.
@@ -383,6 +404,9 @@
 			lp->dmasize = 16;	/* Could make this an option... */
 		}
 #endif
+#ifndef MODULE
+		lp->force = g_cs89x0_media__force;
+#endif
         }
 	lp = (struct net_local *)dev->priv;
 
@@ -394,6 +418,12 @@
 		goto out1;
 	}
 
+#ifdef CONFIG_SH_HICOSH4
+	/* truely reset the chip */
+	outw(0x0114, ioaddr + ADD_PORT);
+	outw(0x0040, ioaddr + DATA_PORT);
+#endif
+
 	/* if they give us an odd I/O address, then do ONE write to
            the address port, to get it back to address zero, where we
            expect to find the EISA signature word. An IO with a base of 0x3
@@ -413,7 +443,7 @@
 	}
 printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT));
 
-        if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) {
+	if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) {
 		printk(KERN_ERR "%s: incorrect signature 0x%x\n",
 			dev->name, inw(ioaddr + DATA_PORT));
   		retval = -ENODEV;
@@ -454,6 +484,39 @@
 	   EEPROM read on reset. So, if the chip says it read the EEPROM
 	   the driver will always do *something* instead of complain that
 	   adapter_cnf is 0. */
+
+#ifdef CONFIG_SH_HICOSH4
+	if (1) {
+		/* For the HiCO.SH4 board, things are different: we don't
+		   have EEPROM, but there is some data in flash, so we go
+		   get it there directly (MAC). */
+		__u16 *confd;
+		short cnt;
+		if (((* (volatile __u32 *) 0xa0013ff0) & 0x00ffffff)
+			== 0x006c3000) {
+			confd = (__u16*) 0xa0013fc0;
+		} else {
+			confd = (__u16*) 0xa001ffc0;
+		}
+		cnt = (*confd++ & 0x00ff) >> 1;
+		while (--cnt > 0) {
+			__u16 j = *confd++;
+			
+			switch (j & 0x0fff) {
+			case PP_IA:
+				for (i = 0; i < ETH_ALEN/2; i++) {
+					dev->dev_addr[i*2] = confd[i] & 0xFF;
+					dev->dev_addr[i*2+1] = confd[i] >> 8;
+				}
+				break;
+			}
+			j = (j >> 12) + 1;
+			confd += j;
+			cnt -= j;
+		}
+	} else
+#endif
+
         if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == 
 	      (EEPROM_OK|EEPROM_PRESENT)) {
 	        /* Load the MAC. */
@@ -507,6 +570,11 @@
         printk("\n");
    
 	/* First check to see if an EEPROM is attached. */
+#ifdef CONFIG_SH_HICOSH4 /* no EEPROM on HiCO, don't hazzle with it here */
+	if (1) {
+		printk(KERN_NOTICE "cs89x0: No EEPROM on HiCO.SH4\n");
+	} else
+#endif
 	if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
 		printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
 	else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) {
@@ -616,10 +684,10 @@
 	}
 
 	/* print the ethernet address. */
-	printk(", MAC ");
+	printk(", MAC");
 	for (i = 0; i < ETH_ALEN; i++)
 	{
-		printk("%s%02x", i ? ":" : "", dev->dev_addr[i]);
+		printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
 	}
 
 	dev->open		= net_open;
@@ -1046,6 +1114,7 @@
 	int i;
 	int ret;
 
+#ifndef CONFIG_SH_HICOSH4 /* uses irq#1, so this wont work */
 	if (dev->irq < 2) {
 		/* Allow interrupts to be generated by the chip */
 /* Cirrus' release had this: */
@@ -1056,7 +1125,7 @@
 		writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
 
 		for (i = 2; i < CS8920_NO_INTS; i++) {
-			if ((1 << dev->irq) & lp->irq_map) {
+			if ((1 << i) & lp->irq_map) {
 				if (request_irq(i, net_interrupt, 0, dev->name, dev) == 0) {
 					dev->irq = i;
 					write_irq(dev, lp->chip_type, i);
@@ -1072,7 +1141,10 @@
 			ret = -EAGAIN;
 			goto bad_out;
 		}
-	} else {
+	}
+	else
+#endif
+	{
 		if (((1 << dev->irq) & lp->irq_map) == 0) {
 			printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
                                dev->name, dev->irq, lp->irq_map);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/cs89x0.h linux/drivers/net/cs89x0.h
--- linux.orig/drivers/net/cs89x0.h	2000-03-03 20:56:13.000000000 +0000
+++ linux/drivers/net/cs89x0.h	2002-07-20 01:08:26.000000000 +0000
@@ -437,7 +437,11 @@
 #define IRQ_MAP_EEPROM_DATA 0x0046 /*  Offset into eeprom for the IRQ map */
 #define IRQ_MAP_LEN 0x0004 /*  No of bytes to read for the IRQ map */
 #define PNP_IRQ_FRMT 0x0022 /*  PNP small item IRQ format */
+#ifdef CONFIG_SH_HICOSH4
+#define CS8900_IRQ_MAP 0x0002 /* HiCO-SH4 board has its IRQ on #1 */
+#else
 #define CS8900_IRQ_MAP 0x1c20 /*  This IRQ map is fixed */
+#endif
 
 #define CS8920_NO_INTS 0x0F   /*  Max CS8920 interrupt select # */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/daynaport.c linux/drivers/net/daynaport.c
--- linux.orig/drivers/net/daynaport.c	2001-04-12 19:15:25.000000000 +0000
+++ linux/drivers/net/daynaport.c	2002-07-20 01:08:38.000000000 +0000
@@ -919,12 +919,4 @@
 #endif	
 }
 
-/*
- * Local variables:
- *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c daynaport.c"
- *  version-control: t
- *  c-basic-offset: 4
- *  tab-width: 4
- *  kept-new-versions: 5
- * End:
- */
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- linux.orig/drivers/net/de4x5.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/de4x5.c	2002-07-20 01:08:23.000000000 +0000
@@ -436,6 +436,7 @@
                            'pb' is now only initialized if a de4x5 chip is
                            present. 
                            <france@handhelds.org>  
+      0.547  08-Nov-01    Use library crc32 functions by <Matt_Domsch@dell.com>
     =========================================================================
 */
 
@@ -457,6 +458,7 @@
 #include <linux/init.h>
 #include <linux/version.h>
 #include <linux/spinlock.h>
+#include <linux/crc32.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -622,9 +624,6 @@
 #define QUEUE_PKT_TIMEOUT (3*HZ)        /* 3 second timeout */
 
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 /*
 ** EISA bus defines
 */
@@ -658,15 +657,15 @@
 ** DESC_ALIGN. ALIGN aligns the start address of the private memory area
 ** and hence the RX descriptor ring's first entry. 
 */
-#define ALIGN4      ((u_long)4 - 1)     /* 1 longword align */
-#define ALIGN8      ((u_long)8 - 1)     /* 2 longword align */
-#define ALIGN16     ((u_long)16 - 1)    /* 4 longword align */
-#define ALIGN32     ((u_long)32 - 1)    /* 8 longword align */
-#define ALIGN64     ((u_long)64 - 1)    /* 16 longword align */
-#define ALIGN128    ((u_long)128 - 1)   /* 32 longword align */
+#define DE4X5_ALIGN4      ((u_long)4 - 1)     /* 1 longword align */
+#define DE4X5_ALIGN8      ((u_long)8 - 1)     /* 2 longword align */
+#define DE4X5_ALIGN16     ((u_long)16 - 1)    /* 4 longword align */
+#define DE4X5_ALIGN32     ((u_long)32 - 1)    /* 8 longword align */
+#define DE4X5_ALIGN64     ((u_long)64 - 1)    /* 16 longword align */
+#define DE4X5_ALIGN128    ((u_long)128 - 1)   /* 32 longword align */
 
-#define ALIGN         ALIGN32           /* Keep the DC21040 happy... */
-#define CACHE_ALIGN   CAL_16LONG
+#define DE4X5_ALIGN         DE4X5_ALIGN32           /* Keep the DC21040 happy... */
+#define DE4X5_CACHE_ALIGN   CAL_16LONG
 #define DESC_SKIP_LEN DSL_0             /* Must agree with DESC_ALIGN */
 /*#define DESC_ALIGN    u32 dummy[4];  / * Must agree with DESC_SKIP_LEN */
 #define DESC_ALIGN
@@ -867,7 +866,7 @@
 ** offsets in the PCI and EISA boards. Also note that the ethernet address
 ** PROM is accessed differently.
 */
-static struct bus_type {
+static struct de4x5_bus_type {
     int bus;
     int bus_num;
     int device;
@@ -968,10 +967,10 @@
 static int     test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec);
 static int     test_tp(struct net_device *dev, s32 msec);
 static int     EISA_signature(char *name, s32 eisa_id);
-static int     PCI_signature(char *name, struct bus_type *lp);
+static int     PCI_signature(char *name, struct de4x5_bus_type *lp);
 static void    DevicePresent(u_long iobase);
 static void    enet_addr_rst(u_long aprom_addr);
-static int     de4x5_bad_srom(struct bus_type *lp);
+static int     de4x5_bad_srom(struct de4x5_bus_type *lp);
 static short   srom_rd(u_long address, u_char offset);
 static void    srom_latch(u_int command, u_long address);
 static void    srom_command(u_int command, u_long address);
@@ -999,7 +998,7 @@
 static int     get_hw_addr(struct net_device *dev);
 static void    srom_repair(struct net_device *dev, int card);
 static int     test_bad_enet(struct net_device *dev, int status);
-static int     an_exception(struct bus_type *lp);
+static int     an_exception(struct de4x5_bus_type *lp);
 #if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
 static void    eisa_probe(struct net_device *dev, u_long iobase);
 #endif
@@ -1144,7 +1143,7 @@
 static int __init 
 de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
 {
-    struct bus_type *lp = &bus;
+    struct de4x5_bus_type *lp = &bus;
     int i, status=0;
     char *tmp;
     
@@ -1203,7 +1202,7 @@
 	** Reserve a section of kernel memory for the adapter
 	** private area and the TX/RX descriptor rings.
 	*/
-	dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + ALIGN, 
+	dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + DE4X5_ALIGN, 
 				     GFP_KERNEL);
 	if (dev->priv == NULL) {
 	    return -ENOMEM;
@@ -1213,7 +1212,7 @@
 	** Align to a longword boundary
 	*/
 	tmp = dev->priv;
-	dev->priv = (void *)(((u_long)dev->priv + ALIGN) & ~ALIGN);
+	dev->priv = (void *)(((u_long)dev->priv + DE4X5_ALIGN) & ~DE4X5_ALIGN);
 	lp = (struct de4x5_private *)dev->priv;
 	memset(dev->priv, 0, sizeof(struct de4x5_private));
 	lp->bus = bus.bus;
@@ -1249,7 +1248,7 @@
 
 	lp->dma_size = (NUM_RX_DESC + NUM_TX_DESC) * sizeof(struct de4x5_desc);
 #if defined(__alpha__) || defined(__powerpc__) || defined(__sparc_v9__) || defined(DE4X5_DO_MEMCPY)
-	lp->dma_size += RX_BUFF_SZ * NUM_RX_DESC + ALIGN;
+	lp->dma_size += RX_BUFF_SZ * NUM_RX_DESC + DE4X5_ALIGN;
 #endif
 	lp->rx_ring = pci_alloc_consistent(pdev, lp->dma_size, &lp->dma_rings);
 	if (lp->rx_ring == NULL) {
@@ -1279,9 +1278,9 @@
 
 		dma_rx_bufs = lp->dma_rings + (NUM_RX_DESC + NUM_TX_DESC)
 		      	* sizeof(struct de4x5_desc);
-		dma_rx_bufs = (dma_rx_bufs + ALIGN) & ~ALIGN;
+		dma_rx_bufs = (dma_rx_bufs + DE4X5_ALIGN) & ~DE4X5_ALIGN;
 		lp->rx_bufs = (char *)(((long)(lp->rx_ring + NUM_RX_DESC
-		      	+ NUM_TX_DESC) + ALIGN) & ~ALIGN);
+		      	+ NUM_TX_DESC) + DE4X5_ALIGN) & ~DE4X5_ALIGN);
 		for (i=0; i<NUM_RX_DESC; i++) {
 	    		lp->rx_ring[i].status = 0;
 	    		lp->rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
@@ -1490,7 +1489,7 @@
     ** Fasternet chips and 4 longwords for all others: DMA errors result
     ** without these values. Cache align 16 long.
     */
-    bmr = (lp->chipset==DC21140 ? PBL_8 : PBL_4) | DESC_SKIP_LEN | CACHE_ALIGN;
+    bmr = (lp->chipset==DC21140 ? PBL_8 : PBL_4) | DESC_SKIP_LEN | DE4X5_CACHE_ALIGN;
     bmr |= ((lp->chipset & ~0x00ff)==DC2114x ? BMR_RML : 0);
     outl(bmr, DE4X5_BMR);
 
@@ -2050,7 +2049,7 @@
     u_long iobase = dev->base_addr;
     int i, j, bit, byte;
     u16 hashcode;
-    u32 omr, crc, poly = CRC_POLYNOMIAL_LE;
+    u32 omr, crc;
     char *pa;
     unsigned char *addrs;
 
@@ -2065,13 +2064,7 @@
 	    addrs=dmi->dmi_addr;
 	    dmi=dmi->next;
 	    if ((*addrs & 0x01) == 1) {      /* multicast address? */ 
-		crc = 0xffffffff;            /* init CRC for each address */
-		for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */
-		                             /* process each address bit */ 
-		    for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
-			crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
-		    }
-		}
+		crc = ether_crc_le(ETH_ALEN, addrs);
 		hashcode = crc & HASH_BITS;  /* hashcode is 9 LSb of CRC */
 		
 		byte = hashcode >> 3;        /* bit[3-8] -> byte in filter */
@@ -2112,7 +2105,7 @@
     u_short vendor;
     u32 cfid;
     u_long iobase;
-    struct bus_type *lp = &bus;
+    struct de4x5_bus_type *lp = &bus;
     char name[DE4X5_STRLEN];
 
     if (lastEISA == MAX_EISA_SLOTS) return;/* No more EISA devices to search */
@@ -2193,7 +2186,7 @@
     u_short vendor, index, status;
     u_int irq = 0, device, class = DE4X5_CLASS_CODE;
     u_long iobase = 0;                     /* Clear upper 32 bits in Alphas */
-    struct bus_type *lp = &bus;
+    struct de4x5_bus_type *lp = &bus;
 
     if (lastPCI == NO_MORE_PCI) return;
 
@@ -2306,7 +2299,7 @@
     u_int irq = 0, device;
     u_long iobase = 0;                     /* Clear upper 32 bits in Alphas */
     int i, j;
-    struct bus_type *lp = &bus;
+    struct de4x5_bus_type *lp = &bus;
     struct list_head *walk = &dev->bus_list;
 
     for (walk = walk->next; walk != &dev->bus_list; walk = walk->next) {
@@ -3645,12 +3638,12 @@
     struct sk_buff *ret;
     u_long i=0, tmp;
 
-    p = dev_alloc_skb(IEEE802_3_SZ + ALIGN + 2);
+    p = dev_alloc_skb(IEEE802_3_SZ + DE4X5_ALIGN + 2);
     if (!p) return NULL;
 
     p->dev = dev;
     tmp = virt_to_bus(p->data);
-    i = ((tmp + ALIGN) & ~ALIGN) - tmp;
+    i = ((tmp + DE4X5_ALIGN) & ~DE4X5_ALIGN) - tmp;
     skb_reserve(p, i);
     lp->rx_ring[index].buf = cpu_to_le32(tmp + i);
 
@@ -3999,7 +3992,7 @@
 ** Look for a particular board name in the PCI configuration space
 */
 static int
-PCI_signature(char *name, struct bus_type *lp)
+PCI_signature(char *name, struct de4x5_bus_type *lp)
 {
     static c_char *de4x5_signatures[] = DE4X5_SIGNATURE;
     int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *);
@@ -4048,7 +4041,7 @@
 DevicePresent(u_long aprom_addr)
 {
     int i, j=0;
-    struct bus_type *lp = &bus;
+    struct de4x5_bus_type *lp = &bus;
     
     if (lp->chipset == DC21040) {
 	if (lp->bus == EISA) {
@@ -4129,7 +4122,7 @@
     u_long iobase = dev->base_addr;
     int broken, i, k, tmp, status = 0;
     u_short j,chksum;
-    struct bus_type *lp = &bus;
+    struct de4x5_bus_type *lp = &bus;
 
     broken = de4x5_bad_srom(lp);
 
@@ -4210,7 +4203,7 @@
 ** didn't seem to work here...?
 */
 static int
-de4x5_bad_srom(struct bus_type *lp)
+de4x5_bad_srom(struct de4x5_bus_type *lp)
 {
     int i, status = 0;
 
@@ -4244,7 +4237,7 @@
 static void
 srom_repair(struct net_device *dev, int card)
 {
-    struct bus_type *lp = &bus;
+    struct de4x5_bus_type *lp = &bus;
 
     switch(card) {
       case SMC:
@@ -4265,7 +4258,7 @@
 static int
 test_bad_enet(struct net_device *dev, int status)
 {
-    struct bus_type *lp = &bus;
+    struct de4x5_bus_type *lp = &bus;
     int i, tmp;
 
     for (tmp=0,i=0; i<ETH_ALEN; i++) tmp += (u_char)dev->dev_addr[i];
@@ -4298,7 +4291,7 @@
 ** List of board exceptions with correctly wired IRQs
 */
 static int
-an_exception(struct bus_type *lp)
+an_exception(struct de4x5_bus_type *lp)
 {
     if ((*(u_short *)lp->srom.sub_vendor_id == 0x00c0) && 
 	(*(u_short *)lp->srom.sub_system_id == 0x95e0)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/de620.c linux/drivers/net/de620.c
--- linux.orig/drivers/net/de620.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/de620.c	2002-07-20 01:08:21.000000000 +0000
@@ -449,11 +449,17 @@
 		return ret;
 	}
 
-	if (adapter_init(dev))
-		return -EIO;
+	if (adapter_init(dev)) {
+		ret = -EIO;
+		goto out_free_irq;
+	}
 
 	netif_start_queue(dev);
 	return 0;
+
+out_free_irq:
+	free_irq(dev->irq, dev);
+	return ret;
 }
 
 /************************************************
@@ -850,7 +856,10 @@
 		return -EBUSY;
 	}
 #endif
-	request_region(dev->base_addr, 3, "de620");
+	if (!request_region(dev->base_addr, 3, "de620")) {
+		printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr);
+		return -EBUSY;
+	}
 
 	/* else, got it! */
 	printk(", Ethernet Address: %2.2X",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/declance.c linux/drivers/net/declance.c
--- linux.orig/drivers/net/declance.c	2001-09-09 17:45:43.000000000 +0000
+++ linux/drivers/net/declance.c	2002-07-20 01:08:23.000000000 +0000
@@ -5,6 +5,8 @@
  *
  *      adopted from sunlance.c by Richard van den Berg
  *
+ *      Copyright (C) 2002  Maciej W. Rozycki
+ *
  *      additional sources:
  *      - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
  *        Revision 1.2
@@ -16,77 +18,68 @@
  *      v0.002: Removed most sparc stuff, left only some module and dma stuff.
  *
  *      v0.003: Enhanced base address calculation from proposals by
- *      Harald Koerfgen and Thomas Riemer.
+ *              Harald Koerfgen and Thomas Riemer.
  *
  *      v0.004: lance-regs is pointing at the right addresses, added prom
- *      check. First start of address mapping and DMA.
+ *              check. First start of address mapping and DMA.
  *
- *      v0.005: started to play around with LANCE-DMA. This driver will not work
- *      for non IOASIC lances. HK
+ *      v0.005: started to play around with LANCE-DMA. This driver will not
+ *              work for non IOASIC lances. HK
  *
- *      v0.006: added pointer arrays to lance_private and setup routine for them
- *      in dec_lance_init. HK
+ *      v0.006: added pointer arrays to lance_private and setup routine for
+ *              them in dec_lance_init. HK
  *
- *      v0.007: Big shit. The LANCE seems to use a different DMA mechanism to access
- *      the init block. This looks like one (short) word at a time, but the smallest
- *      amount the IOASIC can transfer is a (long) word. So we have a 2-2 padding here.
- *      Changed lance_init_block accordingly. The 16-16 padding for the buffers
- *      seems to be correct. HK
+ *      v0.007: Big shit. The LANCE seems to use a different DMA mechanism to
+ *              access the init block. This looks like one (short) word at a
+ *              time, but the smallest amount the IOASIC can transfer is a
+ *              (long) word. So we have a 2-2 padding here. Changed
+ *              lance_init_block accordingly. The 16-16 padding for the buffers
+ *              seems to be correct. HK
  *
- *     v0.008 - mods to make PMAX_LANCE work. 01/09/1999 triemer
- */
-
-#undef DEBUG_DRIVER
-
-static char *version =
-"declance.c: v0.008 by Linux Mips DECstation task force\n";
-
-static char *lancestr = "LANCE";
-
-/*
- * card types
+ *      v0.008: mods to make PMAX_LANCE work. 01/09/1999 triemer
+ *
+ *      v0.009: Module support fixes, multiple interfaces support, various
+ *              bits. macro
  */
-#define ASIC_LANCE 1
-#define PMAD_LANCE 2
-#define PMAX_LANCE 3
 
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
 
+#include <asm/addrspace.h>
 #include <asm/dec/interrupts.h>
-#include <asm/dec/ioasic_ints.h>
+#include <asm/dec/ioasic.h>
 #include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/kn01.h>
 #include <asm/dec/machtype.h>
 #include <asm/dec/tc.h>
-#include <asm/dec/kn01.h>
 #include <asm/wbflush.h>
-#include <asm/addrspace.h>
 
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/hdreg.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/string.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/utsname.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <linux/etherdevice.h>
+static char version[] __devinitdata =
+"declance.c: v0.009 by Linux MIPS DECstation task force\n";
+
+MODULE_AUTHOR("Linux MIPS DECstation task force");
+MODULE_DESCRIPTION("DEC LANCE (DECstation onboard, PMAD-xx) driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * card types
+ */
+#define ASIC_LANCE 1
+#define PMAD_LANCE 2
+#define PMAX_LANCE 3
 
 #ifndef CONFIG_TC
 unsigned long system_base;
 unsigned long dmaptr;
 #endif
-static int type;
 
 #define CRC_POLYNOMIAL_BE 0x04c11db7UL	/* Ethernet CRC, big endian */
 #define CRC_POLYNOMIAL_LE 0xedb88320UL	/* Ethernet CRC, little endian */
@@ -164,8 +157,6 @@
 #define TX_BUFF_SIZE            PKT_BUF_SZ
 
 #undef TEST_HITS
-#define DEBUG_DRIVER 1
-
 #define ZERO 0
 
 /* The DS2000/3000 have a linear 64 KB buffer.
@@ -183,26 +174,26 @@
  */
 
 struct lance_rx_desc {
-	unsigned short rmd0;	/* low address of packet */
+	unsigned short rmd0;		/* low address of packet */
 	short gap0;
 	unsigned char rmd1_hadr;	/* high address of packet */
 	unsigned char rmd1_bits;	/* descriptor bits */
 	short gap1;
-	short length;		/* This length is 2s complement (negative)!
-				   * Buffer length
-				 */
+	short length;			/* 2s complement (negative!)
+					   of buffer length */
 	short gap2;
-	unsigned short mblength;	/* This is the actual number of bytes received */
+	unsigned short mblength;	/* actual number of bytes received */
 	short gap3;
 };
 
 struct lance_tx_desc {
-	unsigned short tmd0;	/* low address of packet */
+	unsigned short tmd0;		/* low address of packet */
 	short gap0;
 	unsigned char tmd1_hadr;	/* high address of packet */
 	unsigned char tmd1_bits;	/* descriptor bits */
 	short gap1;
-	short length;		/* Length is 2s complement (negative)! */
+	short length;			/* 2s complement (negative!)
+					   of buffer length */
 	short gap2;
 	unsigned short misc;
 	short gap3;
@@ -211,28 +202,26 @@
 
 /* First part of the LANCE initialization block, described in databook. */
 struct lance_init_block {
-	unsigned short mode;	/* Pre-set mode (reg. 15) */
+	unsigned short mode;		/* pre-set mode (reg. 15) */
 	short gap0;
 
-	unsigned char phys_addr[12];	/* Physical ethernet address
-					   * only 0, 1, 4, 5, 8, 9 are valid
-					   * 2, 3, 6, 7, 10, 11 are gaps
-					 */
-	unsigned short filter[8];	/* Multicast filter.
-					   * only 0, 2, 4, 6 are valid
-					   * 1, 3, 5, 7 are gaps
-					 */
+	unsigned char phys_addr[12];	/* physical ethernet address
+					   only 0, 1, 4, 5, 8, 9 are valid
+					   2, 3, 6, 7, 10, 11 are gaps */
+	unsigned short filter[8];	/* multicast filter
+					   only 0, 2, 4, 6 are valid
+					   1, 3, 5, 7 are gaps */
 
 	/* Receive and transmit ring base, along with extra bits. */
-	unsigned short rx_ptr;	/* receive descriptor addr */
+	unsigned short rx_ptr;		/* receive descriptor addr */
 	short gap1;
-	unsigned short rx_len;	/* receive len and high addr */
+	unsigned short rx_len;		/* receive len and high addr */
 	short gap2;
-	unsigned short tx_ptr;	/* transmit descriptor addr */
+	unsigned short tx_ptr;		/* transmit descriptor addr */
 	short gap3;
-	unsigned short tx_len;	/* transmit len and high addr */
+	unsigned short tx_len;		/* transmit len and high addr */
 	short gap4;
-	char gap5[16];
+	short gap5[8];
 
 	/* The buffer descriptors */
 	struct lance_rx_desc brx_ring[RX_RING_SIZE];
@@ -251,10 +240,12 @@
 #define LANCE_ADDR(x) (PHYSADDR(x) >> 1)
 
 struct lance_private {
-	char *name;
+	struct net_device *next;
+	int type;
+	int slot;
+	int dma_irq;
 	volatile struct lance_regs *ll;
 	volatile struct lance_init_block *init_block;
-	volatile unsigned long *dma_ptr_reg;
 
 	spinlock_t	lock;
 
@@ -265,8 +256,6 @@
 
 	unsigned short busmaster_regval;
 
-	struct net_device *dev;	/* Backpointer        */
-	struct lance_private *next_module;
 	struct timer_list       multicast_timer;
 
 	/* Pointers to the ring buffers as seen from the CPU */
@@ -296,11 +285,7 @@
 
 int dec_lance_debug = 2;
 
-/*
-   #ifdef MODULE
-   static struct lance_private *root_lance_dev = NULL;
-   #endif
- */
+static struct net_device *root_lance_dev;
 
 static inline void writereg(volatile unsigned short *regptr, short value)
 {
@@ -334,7 +319,7 @@
  * Our specialized copy routines
  *
  */
-void cp_to_buf(void *to, const void *from, __kernel_size_t len)
+void cp_to_buf(const int type, void *to, const void *from, int len)
 {
 	unsigned short *tp, *fp, clen;
 	unsigned char *rtp, *rfp;
@@ -388,7 +373,7 @@
 	wbflush();
 }
 
-void cp_from_buf(void *to, unsigned char *from, int len)
+void cp_from_buf(const int type, void *to, const void *from, int len)
 {
 	unsigned short *tp, *fp, clen;
 	unsigned char *rtp, *rfp;
@@ -555,22 +540,21 @@
 
 #ifdef TEST_HITS
 	{
-	int i;
+		int i;
 
-	printk("[");
-	for (i = 0; i < RX_RING_SIZE; i++) {
-		if (i == lp->rx_new)
-			printk("%s",
-			       ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "_" : "X");
-		else
-			printk("%s",
-			       ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "." : "1");
-	}
-	printk("]");
+		printk("[");
+		for (i = 0; i < RX_RING_SIZE; i++) {
+			if (i == lp->rx_new)
+				printk("%s", ib->brx_ring[i].rmd1_bits &
+					     LE_R1_OWN ? "_" : "X");
+			else
+				printk("%s", ib->brx_ring[i].rmd1_bits &
+					     LE_R1_OWN ? "." : "1");
+		}
+		printk("]");
 	}
 #endif
 
-
 	for (rd = &ib->brx_ring[lp->rx_new];
 	     !((bits = rd->rmd1_bits) & LE_R1_OWN);
 	     rd = &ib->brx_ring[lp->rx_new]) {
@@ -612,8 +596,8 @@
 			skb_reserve(skb, 2);	/* 16 byte align */
 			skb_put(skb, len);	/* make room */
 
-			cp_from_buf(skb->data,
-				 (char *) lp->rx_buf_ptr_cpu[lp->rx_new],
+			cp_from_buf(lp->type, skb->data,
+				    (char *)lp->rx_buf_ptr_cpu[lp->rx_new],
 				    len);
 
 			skb->protocol = eth_type_trans(skb, dev);
@@ -713,6 +697,14 @@
 	spin_unlock(&lp->lock);
 }
 
+static void lance_dma_merr_int(const int irq, void *dev_id,
+				struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+
+	printk("%s: DMA error\n", dev->name);
+}
+
 static void lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
@@ -744,19 +736,8 @@
 		lp->stats.rx_errors++;
 
 	if (csr0 & LE_C0_MERR) {
-		volatile unsigned long int_stat = *(unsigned long *) (system_base + IOCTL + SIR);
-
 		printk("%s: Memory error, status %04x\n", dev->name, csr0);
 
-		if (int_stat & LANCE_DMA_MEMRDERR) {
-			printk("%s: DMA error\n", dev->name);
-			int_stat |= LANCE_DMA_MEMRDERR;
-			/*
-			 * re-enable LANCE DMA
-			 */
-			*(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16);
-			wbflush();
-		}
 		writereg(&ll->rdp, LE_C0_STOP);
 
 		lance_init_ring(dev);
@@ -793,6 +774,8 @@
 	ib->mode = 0;
 	ib->filter [0] = 0;
 	ib->filter [2] = 0;
+	ib->filter [4] = 0;
+	ib->filter [6] = 0;
 
 	lance_init_ring(dev);
 	load_csrs(lp);
@@ -800,10 +783,21 @@
 	netif_start_queue(dev);
 
 	/* Associate IRQ with lance_interrupt */
-	if (request_irq(dev->irq, &lance_interrupt, 0, lp->name, dev)) {
-		printk("Lance: Can't get irq %d\n", dev->irq);
+	if (request_irq(dev->irq, &lance_interrupt, 0, "lance", dev)) {
+		printk("lance: Can't get IRQ %d\n", dev->irq);
 		return -EAGAIN;
 	}
+	if (lp->dma_irq >= 0) {
+		if (request_irq(lp->dma_irq, &lance_dma_merr_int, 0,
+				"lance error", dev)) {
+			free_irq(dev->irq, dev);
+			printk("lance: Can't get DMA IRQ %d\n", lp->dma_irq);
+			return -EAGAIN;
+		}
+		/* Enable I/O ASIC LANCE DMA.  */
+		wbflush();
+		ioasic_write(SSR, ioasic_read(SSR) | LANCE_DMA_EN);
+	}
 
 	status = init_restart_lance(lp);
 
@@ -827,7 +821,13 @@
 	writereg(&ll->rap, LE_CSR0);
 	writereg(&ll->rdp, LE_C0_STOP);
 
-	free_irq(dev->irq, (void *) dev);
+	if (lp->dma_irq >= 0) {
+		/* Disable I/O ASIC LANCE DMA.  */
+		ioasic_write(SSR, ioasic_read(SSR) & ~LANCE_DMA_EN);
+		wbflush();
+		free_irq(lp->dma_irq, dev);
+	}
+	free_irq(dev->irq, dev);
 	/*
 	   MOD_DEC_USE_COUNT;
 	 */
@@ -879,7 +879,8 @@
 	ib->btx_ring[entry].length = (-len);
 	ib->btx_ring[entry].misc = 0;
 
-	cp_to_buf((char *) lp->tx_buf_ptr_cpu[entry], skb->data, skblen);
+	cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data,
+		  skblen);
 
 	/* Clear the slack of the packet, do I need this? */
 	/* For a firewall its a good idea - AC */
@@ -920,7 +921,7 @@
 	struct dev_mc_list *dmi = dev->mc_list;
 	char *addrs;
 	int i, j, bit, byte;
-	u32 crc, poly = CRC_POLYNOMIAL_BE;
+	u32 crc, poly = CRC_POLYNOMIAL_LE;
 
 	/* set all multicast bits */
 	if (dev->flags & IFF_ALLMULTI) {
@@ -959,7 +960,7 @@
 			}
 
 		crc = crc >> 26;
-		mcast_table[crc >> 3] |= 1 << (crc & 0xf);
+		mcast_table[2 * (crc >> 4)] |= 1 << (crc & 0xf);
 	}
 	return;
 }
@@ -1006,7 +1007,7 @@
 	lance_set_multicast(dev);
 }
 
-static int __init dec_lance_init(struct net_device *dev, const int type)
+static int __init dec_lance_init(const int type, const int slot)
 {
 	static unsigned version_printed;
 	struct net_device *dev;
@@ -1018,21 +1019,25 @@
 
 #ifndef CONFIG_TC
 	system_base = KN01_LANCE_BASE;
-#else
-	int slot;
 #endif
 
 	if (dec_lance_debug && version_printed++ == 0)
 		printk(version);
 
-	dev = init_etherdev(0, sizeof(struct lance_private));
+	dev = init_etherdev(NULL, sizeof(struct lance_private));
 	if (!dev)
 		return -ENOMEM;
+	SET_MODULE_OWNER(dev);
 
-	/* init_etherdev ensures the data structures used by the LANCE are aligned. */
+	/*
+	 * init_etherdev ensures the data structures used by the LANCE
+	 * are aligned.
+	 */
 	lp = (struct lance_private *) dev->priv;
 	spin_lock_init(&lp->lock);
 
+	lp->type = type;
+	lp->slot = slot;
 	switch (type) {
 #ifdef CONFIG_TC
 	case ASIC_LANCE:
@@ -1044,78 +1049,100 @@
 		 */
 		dev->mem_start = KSEG1ADDR(0x00020000);
 		dev->mem_end = dev->mem_start + 0x00020000;
-		dev->irq = ETHER;
+		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
 		esar_base = system_base + ESAR;
-	
+
 		/* Workaround crash with booting KN04 2.1k from Disk */
-		memset(dev->mem_start, 0, dev->mem_end - dev->mem_start);
+		memset((void *)dev->mem_start, 0,
+		       dev->mem_end - dev->mem_start);
 
 		/*
 		 * setup the pointer arrays, this sucks [tm] :-(
 		 */
 		for (i = 0; i < RX_RING_SIZE; i++) {
-			lp->rx_buf_ptr_cpu[i] = (char *) (dev->mem_start + BUF_OFFSET_CPU
-						 + 2 * i * RX_BUFF_SIZE);
-			lp->rx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC
-						     + i * RX_BUFF_SIZE);
+			lp->rx_buf_ptr_cpu[i] =
+				(char *)(dev->mem_start + BUF_OFFSET_CPU +
+					 2 * i * RX_BUFF_SIZE);
+			lp->rx_buf_ptr_lnc[i] =
+				(char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
 		}
 		for (i = 0; i < TX_RING_SIZE; i++) {
-			lp->tx_buf_ptr_cpu[i] = (char *) (dev->mem_start + BUF_OFFSET_CPU
-					+ 2 * RX_RING_SIZE * RX_BUFF_SIZE
-						 + 2 * i * TX_BUFF_SIZE);
-			lp->tx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC
-					    + RX_RING_SIZE * RX_BUFF_SIZE
-						     + i * TX_BUFF_SIZE);
+			lp->tx_buf_ptr_cpu[i] =
+				(char *)(dev->mem_start + BUF_OFFSET_CPU +
+					 2 * RX_RING_SIZE * RX_BUFF_SIZE +
+					 2 * i * TX_BUFF_SIZE);
+			lp->tx_buf_ptr_lnc[i] =
+				(char *)(BUF_OFFSET_LNC +
+					 RX_RING_SIZE * RX_BUFF_SIZE +
+					 i * TX_BUFF_SIZE);
 		}
 
-		/*
-		 * setup and enable IOASIC LANCE DMA
-		 */
-		lp->dma_ptr_reg = (unsigned long *) (system_base + IOCTL + LANCE_DMA_P);
-		*(lp->dma_ptr_reg) = PHYSADDR(dev->mem_start) << 3;
-		*(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16);
-		wbflush();
+		/* Setup I/O ASIC LANCE DMA.  */
+		lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR];
+		ioasic_write(LANCE_DMA_P, PHYSADDR(dev->mem_start) << 3);
 
 		break;
+
 	case PMAD_LANCE:
-		slot = search_tc_card("PMAD-AA");
 		claim_tc_card(slot);
 
 		dev->mem_start = get_tc_base_addr(slot);
 		dev->base_addr = dev->mem_start + 0x100000;
 		dev->irq = get_tc_irq_nr(slot);
 		esar_base = dev->mem_start + 0x1c0002;
+		lp->dma_irq = -1;
+
+		for (i = 0; i < RX_RING_SIZE; i++) {
+			lp->rx_buf_ptr_cpu[i] =
+				(char *)(dev->mem_start + BUF_OFFSET_CPU +
+					 i * RX_BUFF_SIZE);
+			lp->rx_buf_ptr_lnc[i] =
+				(char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
+		}
+		for (i = 0; i < TX_RING_SIZE; i++) {
+			lp->tx_buf_ptr_cpu[i] =
+				(char *)(dev->mem_start + BUF_OFFSET_CPU +
+					 RX_RING_SIZE * RX_BUFF_SIZE +
+					 i * TX_BUFF_SIZE);
+			lp->tx_buf_ptr_lnc[i] =
+				(char *)(BUF_OFFSET_LNC +
+					 RX_RING_SIZE * RX_BUFF_SIZE +
+					 i * TX_BUFF_SIZE);
+		}
+
 		break;
 #endif
+
 	case PMAX_LANCE:
-		dev->irq = ETHER;
+		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
 		dev->base_addr = KN01_LANCE_BASE;
 		dev->mem_start = KN01_LANCE_BASE + 0x01000000;
 		esar_base = KN01_RTC_BASE + 1;
+		lp->dma_irq = -1;
+
 		/*
 		 * setup the pointer arrays, this sucks [tm] :-(
 		 */
 		for (i = 0; i < RX_RING_SIZE; i++) {
 			lp->rx_buf_ptr_cpu[i] =
-			    (char *) (dev->mem_start + BUF_OFFSET_CPU
-				      + 2 * i * RX_BUFF_SIZE);
-
+				(char *)(dev->mem_start + BUF_OFFSET_CPU +
+					 2 * i * RX_BUFF_SIZE);
 			lp->rx_buf_ptr_lnc[i] =
-			    (char *) (BUF_OFFSET_LNC
-				      + i * RX_BUFF_SIZE);
-
+				(char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
 		}
 		for (i = 0; i < TX_RING_SIZE; i++) {
 			lp->tx_buf_ptr_cpu[i] =
-			    (char *) (dev->mem_start + BUF_OFFSET_CPU
-				      + 2 * RX_RING_SIZE * RX_BUFF_SIZE
-				      + 2 * i * TX_BUFF_SIZE);
-			lp->tx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC
-					    + RX_RING_SIZE * RX_BUFF_SIZE
-						     + i * TX_BUFF_SIZE);
-
+				(char *)(dev->mem_start + BUF_OFFSET_CPU +
+					 2 * RX_RING_SIZE * RX_BUFF_SIZE +
+					 2 * i * TX_BUFF_SIZE);
+			lp->tx_buf_ptr_lnc[i] =
+				(char *)(BUF_OFFSET_LNC +
+					 RX_RING_SIZE * RX_BUFF_SIZE +
+					 i * TX_BUFF_SIZE);
 		}
+
 		break;
+
 	default:
 		printk("declance_init called with unknown type\n");
 		ret = -ENODEV;
@@ -1145,6 +1172,9 @@
 		}
 	}
 
+	lp->next = root_lance_dev;
+	root_lance_dev = dev;
+
 	/* Copy the ethernet address to the device structure, later to the
 	 * lance initialization block so the lance gets it every time it's
 	 * (re)initialized.
@@ -1167,7 +1197,6 @@
 
 	printk(" irq = %d\n", dev->irq);
 
-	lp->dev = dev;
 	dev->open = &lance_open;
 	dev->stop = &lance_close;
 	dev->hard_start_xmit = &lance_start_xmit;
@@ -1179,8 +1208,6 @@
 	/* lp->ll is the location of the registers for lance card */
 	lp->ll = ll;
 
-	lp->name = lancestr;
-
 	/* busmaster_regval (CSR3) should be zero according to the PMAD-AA
 	 * specification.
 	 */
@@ -1188,8 +1215,6 @@
 
 	dev->dma = 0;
 
-	ether_setup(dev);
-
 	/* We cannot sleep if the chip is busy during a
 	 * multicast list update event, because such events
 	 * can occur from interrupts (ex. IPv6).  So we
@@ -1199,11 +1224,6 @@
 	lp->multicast_timer.data = (unsigned long) dev;
 	lp->multicast_timer.function = &lance_set_multicast_retry;
 
-#ifdef MODULE
-	dev->ifindex = dev_new_index();
-	lp->next_module = root_lance_dev;
-	root_lance_dev = lp;
-#endif
 	return 0;
 
 err_out:
@@ -1216,61 +1236,51 @@
 /* Find all the lance cards on the system and initialize them */
 static int __init dec_lance_probe(void)
 {
-	struct net_device *dev = NULL;
-	static int called;
-
-#ifdef MODULE
-	root_lance_dev = NULL;
-#endif
-
+	int count = 0;
 
+	/* Scan slots for PMAD-AA cards first. */
 #ifdef CONFIG_TC
-	int slot = -1;
-
 	if (TURBOCHANNEL) {
-		if (IOASIC && !called) {
-			called = 1;
-			type = ASIC_LANCE;
-		} else {
-			if ((slot = search_tc_card("PMAD-AA")) >= 0) {
-				type = PMAD_LANCE;
-			} else {
-				return -ENODEV;
-			}
-		}
-	} else {
-		if (!called) {
-			called = 1;
-			type = PMAX_LANCE;
-		} else {
-			return -ENODEV;
+		int slot;
+
+		while ((slot = search_tc_card("PMAD-AA")) >= 0) {
+			if (dec_lance_init(PMAD_LANCE, slot) < 0)
+				break;
+			count++;
 		}
 	}
-#else
-	if (!called && !TURBOCHANNEL) {
-		called = 1;
-		type = PMAX_LANCE;
-	} else {
-		return -ENODEV;
-	}
 #endif
 
-	return dec_lance_init(dev, type);
+	/* Then handle onboard devices. */
+	if (dec_interrupt[DEC_IRQ_LANCE] >= 0) {
+		if (dec_interrupt[DEC_IRQ_LANCE_MERR] >= 0) {
+#ifdef CONFIG_TC
+			if (dec_lance_init(ASIC_LANCE, -1) >= 0)
+				count++;
+#endif
+		} else if (!TURBOCHANNEL) {
+			if (dec_lance_init(PMAX_LANCE, -1) >= 0)
+				count++;
+		}
+	}
+
+	return (count > 0) ? 0 : -ENODEV;
 }
 
 static void __exit dec_lance_cleanup(void)
 {
-#ifdef MODULE
-   struct lance_private *lp;
-
-   while (root_lance_dev) {
-   lp = root_lance_dev->next_module;
+	while (root_lance_dev) {
+		struct net_device *dev = root_lance_dev;
+		struct lance_private *lp = (struct lance_private *)dev->priv;
 
-   unregister_netdev(root_lance_dev->dev);
-   kfree(root_lance_dev->dev);
-   root_lance_dev = lp;
-   }
-#endif /* MODULE */
+#ifdef CONFIG_TC
+		if (lp->slot >= 0)
+			release_tc_card(lp->slot);
+#endif
+		root_lance_dev = lp->next;
+		unregister_netdev(dev);
+		kfree(dev);
+	}
 }
 
 module_init(dec_lance_probe);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/depca.c linux/drivers/net/depca.c
--- linux.orig/drivers/net/depca.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/depca.c	2002-07-20 01:08:37.000000000 +0000
@@ -228,6 +228,8 @@
 			   by <peterd@pnd-pc.demon.co.uk>
       0.53    12-Jan-01	  Release resources on failure, bss tidbits
       			   by acme@conectiva.com.br
+      0.54    08-Nov-01	  use library crc32 functions
+      			   by Matt_Domsch@dell.com
 
     =========================================================================
 */
@@ -245,6 +247,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -296,9 +299,6 @@
 #define RX_BUFF_SZ	1536            /* Buffer size for each Rx buffer */
 #define TX_BUFF_SZ	1536            /* Buffer size for each Tx buffer */
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 /*
 ** EISA bus defines
 */
@@ -1225,7 +1225,7 @@
   char *addrs;
   int i, j, bit, byte;
   u16 hashcode;
-  s32 crc, poly = CRC_POLYNOMIAL_BE;
+  u32 crc;
 
   if (dev->flags & IFF_ALLMULTI) {         /* Set all multicast bits */
     for (i=0; i<(HASH_TABLE_LEN>>3); i++) {
@@ -1240,13 +1240,7 @@
       addrs=dmi->dmi_addr;
       dmi=dmi->next;
       if ((*addrs & 0x01) == 1) {          /* multicast address? */ 
-	crc = 0xffffffff;                  /* init CRC for each address */
-	for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */
-	                                   /* process each address bit */ 
-	  for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
-	    crc = (crc << 1) ^ ((((crc<0?1:0) ^ bit) & 0x01) ? poly : 0);
-	  }
-	}
+        crc = ether_crc(ETH_ALEN, addrs);
 	hashcode = (crc & 1);              /* hashcode is 6 LSb of CRC ... */
 	for (j=0;j<5;j++) {                /* ... in reverse order. */
 	  hashcode = (hashcode << 1) | ((crc>>=1) & 1);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- linux.orig/drivers/net/dgrs.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/dgrs.c	2002-07-20 01:08:24.000000000 +0000
@@ -1153,9 +1153,7 @@
 	 */
 	rc = dgrs_download(dev);
 	if (rc)
-	{
-		return rc;
-	}
+		goto err_out;
 
 	/*
 	 * Get ether address of board
@@ -1169,7 +1167,8 @@
 	if (dev->dev_addr[0] & 1)
 	{
 		printk("%s: Illegal Ethernet Address\n", dev->name);
-		return (-ENXIO);
+		rc = -ENXIO;
+		goto err_out;
 	}
 
 	/*
@@ -1178,9 +1177,10 @@
 	 */
 	if (priv->plxreg)
 		OUTL(dev->base_addr + PLX_LCL2PCI_DOORBELL, 1);
+	
 	rc = request_irq(dev->irq, &dgrs_intr, SA_SHIRQ, "RightSwitch", dev);
 	if (rc)
-		return (rc);
+		goto err_out;
 
 	priv->intrcnt = 0;
 	for (i = jiffies + 2*HZ + HZ/2; time_after(i, jiffies); )
@@ -1191,16 +1191,22 @@
 	}
 	if (priv->intrcnt < 2)
 	{
-		printk("%s: Not interrupting on IRQ %d (%d)\n",
+		printk(KERN_ERR "%s: Not interrupting on IRQ %d (%d)\n",
 				dev->name, dev->irq, priv->intrcnt);
-		return (-ENXIO);
+		rc = -ENXIO;
+		goto err_free_irq;
 	}
 
 	/*
 	 *	Register the /proc/ioports information...
 	 */
-	request_region(dev->base_addr, 256, "RightSwitch");
-
+	if (!request_region(dev->base_addr, 256, "RightSwitch")) {
+		printk(KERN_ERR "%s: io 0x%3lX, which is busy.\n", dev->name,
+				dev->base_addr);
+		rc = -EBUSY;
+		goto err_free_irq;
+	}
+	
 	/*
 	 *	Entry points...
 	 */
@@ -1211,7 +1217,12 @@
 	dev->set_multicast_list = &dgrs_set_multicast_list;
 	dev->do_ioctl = &dgrs_ioctl;
 
-	return (0);
+	return rc;
+
+err_free_irq:
+	free_irq(dev->irq, dev);
+err_out:
+       	return rc;
 }
 
 int __init 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/dl2k.c linux/drivers/net/dl2k.c
--- linux.orig/drivers/net/dl2k.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/dl2k.c	2002-07-20 01:08:34.000000000 +0000
@@ -1,6 +1,6 @@
 /*  D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
 /*
-    Copyright (c) 2001 by D-Link Corporation
+    Copyright (c) 2001,2002 by D-Link Corporation
     Written by Edward Peng.<edward_peng@dlink.com.tw>
     Created 03-May-2001, base on Linux' sundance.c.
 
@@ -27,24 +27,31 @@
 				Added tx_coalesce paramter.
     1.07	2002/01/03	Fixed miscount of RX frame error.
     1.08	2002/01/17	Fixed the multicast bug.
+    1.09	2002/03/07	Move rx-poll-now to re-fill loop.	
+    				Added rio_timer() to watch rx buffers. 
+    1.10	2002/04/16	Fixed miscount of carrier error.
+    1.11	2002/05/23	Added ISR schedule scheme.
+    				Fixed miscount of rx frame error for DGE-550SX.
+    				Fixed VLAN bug.
  */
 
 #include "dl2k.h"
 
 static char version[] __devinitdata =
-    KERN_INFO "D-Link DL2000-based linux driver v1.08 2002/01/17\n";
+    KERN_INFO "D-Link DL2000-based linux driver v1.11 2002/05/23\n";
 
 #define MAX_UNITS 8
 static int mtu[MAX_UNITS];
 static int vlan[MAX_UNITS];
 static int jumbo[MAX_UNITS];
 static char *media[MAX_UNITS];
-static int tx_flow[MAX_UNITS];
-static int rx_flow[MAX_UNITS];
+static int tx_flow=-1;
+static int rx_flow=-1;
 static int copy_thresh;
-static int rx_coalesce = DEFAULT_RXC;
-static int rx_timeout = DEFAULT_RXT;	
-static int tx_coalesce = DEFAULT_TXC;	
+static int rx_coalesce=10;	/* Rx frame count each interrupt */
+static int rx_timeout=200;	/* Rx DMA wait time in 640ns increments */
+static int tx_coalesce=16;	/* HW xmit count each TxDMAComplete */
+
 
 MODULE_AUTHOR ("Edward Peng");
 MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter");
@@ -53,16 +60,16 @@
 MODULE_PARM (media, "1-" __MODULE_STRING (MAX_UNITS) "s");
 MODULE_PARM (vlan, "1-" __MODULE_STRING (MAX_UNITS) "i");
 MODULE_PARM (jumbo, "1-" __MODULE_STRING (MAX_UNITS) "i");
-MODULE_PARM (tx_flow, "1-" __MODULE_STRING (MAX_UNITS) "i");
-MODULE_PARM (rx_flow, "1-" __MODULE_STRING (MAX_UNITS) "i");
+MODULE_PARM (tx_flow, "i");
+MODULE_PARM (rx_flow, "i");
 MODULE_PARM (copy_thresh, "i");
 MODULE_PARM (rx_coalesce, "i");	/* Rx frame count each interrupt */
 MODULE_PARM (rx_timeout, "i");	/* Rx DMA wait time in 64ns increments */
-MODULE_PARM (tx_coalesce, "i"); /* HW xmit count each TxComplete [1-8] */
+MODULE_PARM (tx_coalesce, "i"); /* HW xmit count each TxDMAComplete */
 
 
 /* Enable the default interrupts */
-#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxComplete| \
+#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \
        UpdateStats | LinkEvent)
 #define EnableInt() \
 writew(DEFAULT_INTR, ioaddr + IntEnable)
@@ -71,22 +78,24 @@
 static int multicast_filter_limit = 0x40;
 
 static int rio_open (struct net_device *dev);
-static void tx_timeout (struct net_device *dev);
+static void rio_timer (unsigned long data);
+static void rio_tx_timeout (struct net_device *dev);
 static void alloc_list (struct net_device *dev);
 static int start_xmit (struct sk_buff *skb, struct net_device *dev);
 static void rio_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static void rio_free_tx (struct net_device *dev, int irq);
 static void tx_error (struct net_device *dev, int tx_status);
 static int receive_packet (struct net_device *dev);
 static void rio_error (struct net_device *dev, int int_status);
 static int change_mtu (struct net_device *dev, int new_mtu);
 static void set_multicast (struct net_device *dev);
 static struct net_device_stats *get_stats (struct net_device *dev);
+static int clear_stats (struct net_device *dev);
 static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static int rio_close (struct net_device *dev);
 static int find_miiphy (struct net_device *dev);
 static int parse_eeprom (struct net_device *dev);
 static int read_eeprom (long ioaddr, int eep_addr);
-static unsigned get_crc (unsigned char *p, int len);
 static int mii_wait_link (struct net_device *dev, int wait);
 static int mii_set_media (struct net_device *dev);
 static int mii_get_media (struct net_device *dev);
@@ -95,9 +104,6 @@
 static int mii_read (struct net_device *dev, int phy_addr, int reg_num);
 static int mii_write (struct net_device *dev, int phy_addr, int reg_num,
 		      u16 data);
-#ifdef RIO_DEBUG
-static int rio_ioctl_ext (struct net_device *dev, struct ioctl_data *iodata);
-#endif
 
 static int __devinit
 rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -106,7 +112,7 @@
 	struct netdev_private *np;
 	static int card_idx;
 	int chip_idx = ent->driver_data;
-	int err, irq = pdev->irq;
+	int err, irq;
 	long ioaddr;
 	static int version_printed;
 	void *ring_space;
@@ -119,6 +125,7 @@
 	if (err)
 		return err;
 
+	irq = pdev->irq;
 	err = pci_request_regions (pdev, "dl2k");
 	if (err)
 		goto err_out_disable;
@@ -146,7 +153,8 @@
 	np = dev->priv;
 	np->chip_id = chip_idx;
 	np->pdev = pdev;
-	spin_lock_init (&np->lock);
+	spin_lock_init (&np->tx_lock);
+	spin_lock_init (&np->rx_lock);
 
 	/* Parse manual configuration */
 	np->an_enable = 1;
@@ -195,17 +203,18 @@
 		}
 		np->vlan = (vlan[card_idx] > 0 && vlan[card_idx] < 4096) ?
 		    vlan[card_idx] : 0;
-		if (rx_coalesce != 0 && rx_timeout != 0) {
+		if (rx_coalesce > 0 && rx_timeout > 0) {
 			np->rx_coalesce = rx_coalesce;
 			np->rx_timeout = rx_timeout;
 			np->coalesce = 1;
 		}
-		np->tx_flow = (tx_flow[card_idx]) ? 1 : 0;
-		np->rx_flow = (rx_flow[card_idx]) ? 1 : 0;
+		np->tx_flow = (tx_flow == 0) ? 0 : 1;
+		np->rx_flow = (rx_flow == 0) ? 0 : 1;
+
 		if (tx_coalesce < 1)
 			tx_coalesce = 1;
-		if (tx_coalesce > 8)
-			tx_coalesce = 8;
+		if (tx_coalesce > TX_RING_SIZE-1)
+			tx_coalesce = TX_RING_SIZE - 1;
 	}
 	dev->open = &rio_open;
 	dev->hard_start_xmit = &start_xmit;
@@ -213,7 +222,7 @@
 	dev->get_stats = &get_stats;
 	dev->set_multicast_list = &set_multicast;
 	dev->do_ioctl = &rio_ioctl;
-	dev->tx_timeout = &tx_timeout;
+	dev->tx_timeout = &rio_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->change_mtu = &change_mtu;
 #if 0
@@ -243,6 +252,7 @@
 	
 	/* Fiber device? */
 	np->phy_media = (readw(ioaddr + ASICCtrl) & PhyMedia) ? 1 : 0;
+	np->link_status = 0;
 	/* Set media and reset PHY */
 	if (np->phy_media) {
 		/* default 1000mbps_fd for fiber deivices */
@@ -261,6 +271,7 @@
 			np->an_enable = 1;
 		mii_set_media (dev);
 	}
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &np->pci_rev_id);
 
 	/* Reset all logic functions */
 	writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
@@ -276,6 +287,15 @@
 		dev->name, np->name,
 		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
 		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], irq);
+	if (tx_coalesce > 1)
+		printk(KERN_INFO "tx_coalesce:\t%d packets\n", 
+				tx_coalesce);
+	if (np->coalesce)
+		printk(KERN_INFO "rx_coalesce:\t%d packets\n"
+		       KERN_INFO "rx_timeout: \t%d ns\n", 
+				np->rx_coalesce, np->rx_timeout*640);
+	if (np->vlan)
+		printk(KERN_INFO "vlan(id):\t%d\n", np->vlan);
 	return 0;
 
       err_out_unmap_rx:
@@ -341,7 +361,7 @@
 	}
 
 	/* Check CRC */
-	crc = ~get_crc (sromdata, 256 - 4);
+	crc = ~ether_crc_le(256 - 4, sromdata);
 	if (psrom->crc != crc) {
 		printk (KERN_ERR "%s: EEPROM data CRC error.\n", dev->name);
 		return -1;
@@ -422,10 +442,14 @@
 			ioaddr + RxDMAIntCtrl);
 	}
 	/* Set RIO to poll every N*320nsec. */
-	writeb (0xff, ioaddr + RxDMAPollPeriod);
+	writeb (0x20, ioaddr + RxDMAPollPeriod);
 	writeb (0xff, ioaddr + TxDMAPollPeriod);
-	netif_start_queue (dev);
-	writel (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl);
+	writeb (0x30, ioaddr + RxDMABurstThresh);
+	writeb (0x30, ioaddr + RxDMAUrgentThresh);
+
+	/* clear statistics */
+	clear_stats (dev);
+
 	/* VLAN supported */
 	if (np->vlan) {
 		/* priority field in RxDMAIntCtrl  */
@@ -444,42 +468,76 @@
 	/* Enable default interrupts */
 	EnableInt ();
 
-	/* clear statistics */
-	get_stats (dev);
+	init_timer (&np->timer);
+	np->timer.expires = jiffies + 1*HZ;
+	np->timer.data = (unsigned long) dev;
+	np->timer.function = &rio_timer;
+	add_timer (&np->timer);
+
+	/* Start Tx/Rx */
+	writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable, 
+			ioaddr + MACCtrl);
+
+	netif_start_queue (dev);
 	return 0;
 }
 
-static void
-tx_timeout (struct net_device *dev)
+static void 
+rio_timer (unsigned long data)
 {
+	struct net_device *dev = (struct net_device *)data;
 	struct netdev_private *np = dev->priv;
+	unsigned int entry;
+	int next_tick = 1*HZ;
+	unsigned long flags;
+
+	spin_lock_irqsave(&np->rx_lock, flags);
+	/* Recover rx ring exhausted error */
+	if (np->cur_rx - np->old_rx >= RX_RING_SIZE) {
+		printk(KERN_INFO "Try to recover rx ring exhausted...\n");
+		/* Re-allocate skbuffs to fill the descriptor ring */
+		for (; np->cur_rx - np->old_rx > 0; np->old_rx++) {
+			struct sk_buff *skb;
+			entry = np->old_rx % RX_RING_SIZE;
+			/* Dropped packets don't need to re-allocate */
+			if (np->rx_skbuff[entry] == NULL) {
+				skb = dev_alloc_skb (np->rx_buf_sz);
+				if (skb == NULL) {
+					np->rx_ring[entry].fraginfo = 0;
+					printk (KERN_INFO
+						"%s: Still unable to re-allocate Rx skbuff.#%d\n",
+						dev->name, entry);
+					break;
+				}
+				np->rx_skbuff[entry] = skb;
+				skb->dev = dev;
+				/* 16 byte align the IP header */
+				skb_reserve (skb, 2);
+				np->rx_ring[entry].fraginfo =
+				    cpu_to_le64 (pci_map_single
+					 (np->pdev, skb->tail, np->rx_buf_sz,
+					  PCI_DMA_FROMDEVICE));
+			}
+			np->rx_ring[entry].fraginfo |=
+			    cpu_to_le64 (np->rx_buf_sz) << 48;
+			np->rx_ring[entry].status = 0;
+		} /* end for */
+	} /* end if */
+	spin_unlock_irqrestore (&np->rx_lock, flags);
+	np->timer.expires = jiffies + next_tick;
+	add_timer(&np->timer);
+}
+	
+static void
+rio_tx_timeout (struct net_device *dev)
+{
 	long ioaddr = dev->base_addr;
 
 	printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
 		dev->name, readl (ioaddr + TxStatus));
-	/* Free used tx skbuffs */
-	for (; np->cur_tx - np->old_tx > 0; np->old_tx++) {
-		int entry = np->old_tx % TX_RING_SIZE;
-		struct sk_buff *skb;
-
-		if (!(np->tx_ring[entry].status & TFDDone))
-			break;
-		skb = np->tx_skbuff[entry];
-		pci_unmap_single (np->pdev,
-				  np->tx_ring[entry].fraginfo,
-				  skb->len, PCI_DMA_TODEVICE);
-		dev_kfree_skb_irq (skb);
-		np->tx_skbuff[entry] = 0;
-	}
+	rio_free_tx(dev, 0);
 	dev->if_port = 0;
 	dev->trans_start = jiffies;
-	np->stats.tx_errors++;
-	/* If the ring is no longer full, clear tx_full and 
-	   call netif_wake_queue() */
-	if (np->tx_full && np->cur_tx - np->old_tx < TX_QUEUE_LEN - 1) {
-		np->tx_full = 0;
-		netif_wake_queue (dev);
-	}
 }
 
  /* allocate and initialize Tx and Rx descriptors */
@@ -489,7 +547,6 @@
 	struct netdev_private *np = dev->priv;
 	int i;
 
-	np->tx_full = 0;
 	np->cur_rx = np->cur_tx = 0;
 	np->old_rx = np->old_tx = 0;
 	np->rx_buf_sz = (dev->mtu <= 1500 ? PACKET_SIZE : dev->mtu + 32);
@@ -500,16 +557,14 @@
 		np->tx_ring[i].status = cpu_to_le64 (TFDDone);
 		np->tx_ring[i].next_desc = cpu_to_le64 (np->tx_ring_dma +
 					      ((i+1)%TX_RING_SIZE) *
-					      sizeof (struct
-					      netdev_desc));
+					      sizeof (struct netdev_desc));
 	}
 
 	/* Initialize Rx descriptors */
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		np->rx_ring[i].next_desc = cpu_to_le64 (np->rx_ring_dma +
 						((i + 1) % RX_RING_SIZE) *
-						sizeof (struct
-						netdev_desc));
+						sizeof (struct netdev_desc));
 		np->rx_ring[i].status = 0;
 		np->rx_ring[i].fraginfo = 0;
 		np->rx_skbuff[i] = 0;
@@ -530,8 +585,8 @@
 		skb_reserve (skb, 2);	/* 16 byte align the IP header. */
 		/* Rubicon now supports 40 bits of addressing space. */
 		np->rx_ring[i].fraginfo =
-		    cpu_to_le64 (pci_map_single
-				 (np->pdev, skb->tail, np->rx_buf_sz,
+		    cpu_to_le64 ( pci_map_single (
+			 	  np->pdev, skb->tail, np->rx_buf_sz,
 				  PCI_DMA_FROMDEVICE));
 		np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
 	}
@@ -550,18 +605,17 @@
 	struct netdev_desc *txdesc;
 	unsigned entry;
 	u32 ioaddr;
-	int tx_shift;
-	unsigned long flags;
+	u64 tfc_vlan_tag = 0;
 
+	if (np->link_status == 0) {	/* Link Down */
+		dev_kfree_skb(skb);
+		return 0;
+	}
 	ioaddr = dev->base_addr;
 	entry = np->cur_tx % TX_RING_SIZE;
 	np->tx_skbuff[entry] = skb;
 	txdesc = &np->tx_ring[entry];
 
-	/* Set TFDDone to avoid TxDMA gather this descriptor */
-	txdesc->status = cpu_to_le64 (TFDDone);
-	txdesc->status |=
-	    cpu_to_le64 (entry | WordAlignDisable | (1 << FragCountShift));
 #if 0
 	if (skb->ip_summed == CHECKSUM_HW) {
 		txdesc->status |=
@@ -575,31 +629,33 @@
 		    (cpu_to_le64 (np->vlan) << 32) |
 		    (cpu_to_le64 (skb->priority) << 45);
 	}
-
-	/* Send one packet each time at 10Mbps mode */
-	/* Tx coalescing loop do not exceed 8 */
-	if (entry % tx_coalesce == 0 || np->speed == 10)
-		txdesc->status |= cpu_to_le64 (TxIndicate);
 	txdesc->fraginfo = cpu_to_le64 (pci_map_single (np->pdev, skb->data,
 							skb->len,
 							PCI_DMA_TODEVICE));
 	txdesc->fraginfo |= cpu_to_le64 (skb->len) << 48;
 
-	/* Clear TFDDone, then TxDMA start to send this descriptor */
-	txdesc->status &= ~cpu_to_le64 (TFDDone);
-
-	DEBUG_TFD_DUMP (np);
+	/* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode
+	 * Work around: Always use 1 descriptor in 10Mbps mode */
+	if (entry % tx_coalesce == 0 || np->speed == 10)
+		txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
+					      WordAlignDisable | 
+					      TxDMAIndicate |
+					      (1 << FragCountShift));
+	else
+		txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
+					      WordAlignDisable | 
+					      (1 << FragCountShift));
 
 	/* TxDMAPollNow */
 	writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
-	np->cur_tx++;
-	if (np->cur_tx - np->old_tx < TX_QUEUE_LEN - 1 && np->speed != 10) {
+	/* Schedule ISR */
+	writel(10000, ioaddr + CountDown);
+	np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
+	if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
+			< TX_QUEUE_LEN - 1 && np->speed != 10) {
 		/* do nothing */
-	} else {
-		spin_lock_irqsave(&np->lock, flags);
-		np->tx_full = 1;
+	} else if (!netif_queue_stopped(dev)) {
 		netif_stop_queue (dev);
-		spin_unlock_irqrestore (&np->lock, flags);
 	}
 
 	/* The first TFDListPtr */
@@ -609,14 +665,6 @@
 		writel (0, dev->base_addr + TFDListPtr1);
 	}
 	
-	if (np->old_tx > TX_RING_SIZE) {
-		spin_lock_irqsave (&np->lock, flags);
-		tx_shift = TX_RING_SIZE;
-		np->old_tx -= tx_shift;
-		np->cur_tx -= tx_shift;
-		spin_unlock_irqrestore (&np->lock, flags);
-	}
-	
 	/* NETDEV WATCHDOG timer */
 	dev->trans_start = jiffies;
 	return 0;
@@ -633,61 +681,79 @@
 
 	ioaddr = dev->base_addr;
 	np = dev->priv;
-	spin_lock(&np->lock);
 	while (1) {
 		int_status = readw (ioaddr + IntStatus); 
 		writew (int_status, ioaddr + IntStatus);
 		int_status &= DEFAULT_INTR;
-		if (int_status == 0)
+		if (int_status == 0 || --cnt < 0)
 			break;
 		/* Processing received packets */
 		if (int_status & RxDMAComplete)
 			receive_packet (dev);
-		/* TxComplete interrupt */
-		if ((int_status & TxComplete) || np->tx_full) {
+		/* TxDMAComplete interrupt */
+		if ((int_status & (TxDMAComplete|IntRequested))) {
 			int tx_status;
 			tx_status = readl (ioaddr + TxStatus);
 			if (tx_status & 0x01)
 				tx_error (dev, tx_status);
 			/* Free used tx skbuffs */
-			for (;np->cur_tx - np->old_tx > 0; np->old_tx++) {
-				int entry = np->old_tx % TX_RING_SIZE;
-				struct sk_buff *skb;
-
-				if (!(np->tx_ring[entry].status & TFDDone))
-					break;
-				skb = np->tx_skbuff[entry];
-				pci_unmap_single (np->pdev,
-						  np->tx_ring[entry].fraginfo,
-						  skb->len, PCI_DMA_TODEVICE);
-				dev_kfree_skb_irq (skb);
-				np->tx_skbuff[entry] = 0;
-			}
-		}
-		/* If the ring is no longer full, clear tx_full and 
-		   call netif_wake_queue() */
-		if (np->tx_full && np->cur_tx - np->old_tx < TX_QUEUE_LEN - 1) {
-			if (np->speed != 10 || int_status & TxComplete) {
-				np->tx_full = 0;
-				netif_wake_queue (dev);
-			}
+			rio_free_tx (dev, 1);		
 		}
 
 		/* Handle uncommon events */
 		if (int_status &
-		    (IntRequested | HostError | LinkEvent | UpdateStats))
+		    (HostError | LinkEvent | UpdateStats))
 			rio_error (dev, int_status);
-		/* If too much interrupts here, disable all interrupts except 
-		   IntRequest. When CountDown down to 0, IntRequest will 
-		   be caught by rio_error() to recovery the interrupts */
-		if (--cnt < 0) {
-			get_stats (dev);
-			writel (1, ioaddr + CountDown);
-			writew (IntRequested, ioaddr + IntEnable);
+	}
+	if (np->cur_tx != np->old_tx)
+		writel (100, ioaddr + CountDown);
+}
+
+static void 
+rio_free_tx (struct net_device *dev, int irq) 
+{
+	struct netdev_private *np = (struct netdev_private *) dev->priv;
+	int entry = np->old_tx % TX_RING_SIZE;
+	int tx_use = 0;
+	long flag = 0;
+	
+	if (irq)
+		spin_lock_irqsave(&np->tx_lock, flag);
+	else
+		spin_lock(&np->tx_lock);
+	/* Free used tx skbuffs */
+	while (entry != np->cur_tx) {
+		struct sk_buff *skb;
+
+		if (!(np->tx_ring[entry].status & TFDDone))
 			break;
-		}
+		skb = np->tx_skbuff[entry];
+		pci_unmap_single (np->pdev,
+				  np->tx_ring[entry].fraginfo,
+				  skb->len, PCI_DMA_TODEVICE);
+		if (irq)
+			dev_kfree_skb_irq (skb);
+		else
+			dev_kfree_skb (skb);
+
+		np->tx_skbuff[entry] = 0;
+		entry = (entry + 1) % TX_RING_SIZE;
+		tx_use++;
+	}
+	if (irq)
+		spin_unlock_irqrestore(&np->tx_lock, flag);
+	else
+		spin_unlock(&np->tx_lock);
+	np->old_tx = entry;
+
+	/* If the ring is no longer full, clear tx_full and 
+	   call netif_wake_queue() */
+
+	if (netif_queue_stopped(dev) &&
+	    ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE 
+	    < TX_QUEUE_LEN - 1 || np->speed == 10)) {
+		netif_wake_queue (dev);
 	}
-	spin_unlock(&np->lock);
 }
 
 static void
@@ -700,11 +766,10 @@
 
 	np = dev->priv;
 
-	frame_id = (tx_status & 0xffff0000) >> 16;
+	frame_id = (tx_status & 0xffff0000);
 	printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n",
 		dev->name, tx_status, frame_id);
 	np->stats.tx_errors++;
-	np->stats.tx_dropped++;
 	/* Ttransmit Underrun */
 	if (tx_status & 0x10) {
 		np->stats.tx_fifo_errors++;
@@ -719,20 +784,7 @@
 				break;
 			mdelay (1);
 		}
-		/* Free completed descriptors */
-		for (; np->cur_tx - np->old_tx > 0; np->old_tx++) {
-			int entry = np->old_tx % TX_RING_SIZE;
-			struct sk_buff *skb;
-			if (!(np->tx_ring[entry].status & TFDDone))
-				break;
-
-			skb = np->tx_skbuff[entry];
-			pci_unmap_single (np->pdev, np->tx_ring[entry].fraginfo,
-					  skb->len, PCI_DMA_TODEVICE);
-			dev_kfree_skb_irq (skb);
-			np->tx_skbuff[entry] = 0;
-		}
-
+		rio_free_tx (dev, 1);
 		/* Reset TFDListPtr */
 		writel (np->tx_ring_dma +
 			np->old_tx * sizeof (struct netdev_desc),
@@ -755,14 +807,13 @@
 		/* Let TxStartThresh stay default value */
 	}
 	/* Maximum Collisions */
-#ifdef ETHER_STATS
-	if (tx_status & 0x08)
+#ifdef ETHER_STATS	
+	if (tx_status & 0x08) 
 		np->stats.collisions16++;
 #else
-	if (tx_status & 0x08)
+	if (tx_status & 0x08) 
 		np->stats.collisions++;
 #endif
-
 	/* Restart the Tx */
 	writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
 }
@@ -772,14 +823,8 @@
 {
 	struct netdev_private *np = (struct netdev_private *) dev->priv;
 	int entry = np->cur_rx % RX_RING_SIZE;
-	int cnt = np->old_rx + RX_RING_SIZE - np->cur_rx;
-	int rx_shift;
-	if (np->old_rx > RX_RING_SIZE) {
-		rx_shift = RX_RING_SIZE;
-		np->old_rx -= rx_shift;
-		np->cur_rx -= rx_shift;
-	}
-	DEBUG_RFD_DUMP (np, 1);
+	int cnt = 30;
+
 	/* If RFDDone, FrameStart and FrameEnd set, there is a new packet in. */
 	while (1) {
 		struct netdev_desc *desc = &np->rx_ring[entry];
@@ -795,20 +840,19 @@
 		frame_status = le64_to_cpu (desc->status);
 		if (--cnt < 0)
 			break;
-		DEBUG_PKT_DUMP (np, pkt_len);
 		pci_dma_sync_single (np->pdev, desc->fraginfo, np->rx_buf_sz,
 				     PCI_DMA_FROMDEVICE);
 		/* Update rx error statistics, drop packet. */
-		if (frame_status & 0x003f0000) {
+		if (frame_status & RFS_Errors) {
 			np->stats.rx_errors++;
-			if (frame_status & 0x00300000)
+			if (frame_status & (RxRuntFrame | RxLengthError))
 				np->stats.rx_length_errors++;
-			if (frame_status & 0x00010000)
-	 			np->stats.rx_fifo_errors++;
-			if (frame_status & 0x00060000)
-				np->stats.rx_frame_errors++;
-			if (frame_status & 0x00080000)
+			if (frame_status & RxFCSError)
 				np->stats.rx_crc_errors++;
+			if (frame_status & RxAlignmentError && np->speed != 1000)
+				np->stats.rx_frame_errors++;
+			if (frame_status & RxFIFOOverrun)
+	 			np->stats.rx_fifo_errors++;
 		} else {
 			struct sk_buff *skb;
 
@@ -829,30 +873,33 @@
 				skb_put (skb, pkt_len);
 			}
 			skb->protocol = eth_type_trans (skb, dev);
-#if 0
+#if 0			
 			/* Checksum done by hw, but csum value unavailable. */
-			if (!(frame_status & (TCPError | UDPError | IPError))) {
+			if (np->pci_rev_id >= 0x0c && 
+				!(frame_status & (TCPError | UDPError | IPError))) {
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
-			}
+			} 
 #endif
 			netif_rx (skb);
 			dev->last_rx = jiffies;
 		}
-		entry = (++np->cur_rx) % RX_RING_SIZE;
-
+		entry = (entry + 1) % RX_RING_SIZE;
 	}
+	spin_lock(&np->rx_lock);
+	np->cur_rx = entry;
 	/* Re-allocate skbuffs to fill the descriptor ring */
-	for (; np->cur_rx - np->old_rx > 0; np->old_rx++) {
+	entry = np->old_rx;
+	while (entry != np->cur_rx) {
 		struct sk_buff *skb;
-		entry = np->old_rx % RX_RING_SIZE;
 		/* Dropped packets don't need to re-allocate */
 		if (np->rx_skbuff[entry] == NULL) {
 			skb = dev_alloc_skb (np->rx_buf_sz);
 			if (skb == NULL) {
 				np->rx_ring[entry].fraginfo = 0;
-				printk (KERN_ERR
-					"%s: Allocate Rx buffer error!",
-					dev->name);
+				printk (KERN_INFO
+					"%s: receive_packet: "
+					"Unable to re-allocate Rx skbuff.#%d\n",
+					dev->name, entry);
 				break;
 			}
 			np->rx_skbuff[entry] = skb;
@@ -867,13 +914,10 @@
 		np->rx_ring[entry].fraginfo |=
 		    cpu_to_le64 (np->rx_buf_sz) << 48;
 		np->rx_ring[entry].status = 0;
+		entry = (entry + 1) % RX_RING_SIZE;
 	}
-
-	/* RxDMAPollNow */
-	writel (readl (dev->base_addr + DMACtrl) | 0x00000010,
-		dev->base_addr + DMACtrl);
-
-	DEBUG_RFD_DUMP (np, 2);
+	np->old_rx = entry;
+	spin_unlock(&np->rx_lock);
 	return 0;
 }
 
@@ -884,14 +928,6 @@
 	struct netdev_private *np = dev->priv;
 	u16 macctrl;
 
-	/* Stop the down counter and recovery the interrupt */
-	if (int_status & IntRequested) {
-		writew (0, ioaddr + IntEnable);
-		writel (0, ioaddr + CountDown);
-		/* Enable default interrupts */
-		EnableInt ();
-	}
-
 	/* Link change event */
 	if (int_status & LinkEvent) {
 		if (mii_wait_link (dev, 10) == 0) {
@@ -901,14 +937,19 @@
 			else
 				mii_get_media (dev);
 			macctrl = 0;
+			macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
 			macctrl |= (np->full_duplex) ? DuplexSelect : 0;
 			macctrl |= (np->tx_flow) ? 
 				TxFlowControlEnable : 0;
 			macctrl |= (np->rx_flow) ? 
 				RxFlowControlEnable : 0;
 			writew(macctrl,	ioaddr + MACCtrl);
+			np->link_status = 1;
+			netif_carrier_on(dev);
 		} else {
 			printk (KERN_INFO "%s: Link off\n", dev->name);
+			np->link_status = 0;
+			netif_carrier_off(dev);
 		}
 	}
 
@@ -932,41 +973,100 @@
 {
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
-	u16 temp1;
-	u16 temp2;
 	int i;
+	unsigned int stat_reg;
+
 	/* All statistics registers need to be acknowledged,
 	   else statistic overflow could cause problems */
+	
 	np->stats.rx_packets += readl (ioaddr + FramesRcvOk);
 	np->stats.tx_packets += readl (ioaddr + FramesXmtOk);
 	np->stats.rx_bytes += readl (ioaddr + OctetRcvOk);
 	np->stats.tx_bytes += readl (ioaddr + OctetXmtOk);
-	temp1 = readw (ioaddr + FrameLostRxError);
-	np->stats.rx_errors += temp1;
-	np->stats.rx_missed_errors += temp1;
-	np->stats.tx_dropped += readw (ioaddr + FramesAbortXSColls);
-	temp1 = readl (ioaddr + SingleColFrames) +
-	    readl (ioaddr + MultiColFrames) + readl (ioaddr + LateCollisions);
-	temp2 = readw (ioaddr + CarrierSenseErrors);
-	np->stats.tx_carrier_errors += temp2;
-	np->stats.tx_errors += readw (ioaddr + FramesWEXDeferal) +
-	    readl (ioaddr + FramesWDeferredXmt) + temp2;
-
-	/* detailed rx_error */
-	np->stats.rx_length_errors += readw (ioaddr + FrameTooLongErrors);
-	np->stats.rx_crc_errors += readw (ioaddr + FrameCheckSeqError);
+
+	np->stats.multicast = readl (ioaddr + McstFramesRcvdOk);
+	np->stats.collisions += readl (ioaddr + SingleColFrames) 
+			     +  readl (ioaddr + MultiColFrames); 
+	
+	/* detailed tx errors */
+	stat_reg = readw (ioaddr + FramesAbortXSColls);
+	np->stats.tx_aborted_errors += stat_reg;
+	np->stats.tx_errors += stat_reg;
+
+	stat_reg = readw (ioaddr + CarrierSenseErrors);
+	np->stats.tx_carrier_errors += stat_reg;
+	np->stats.tx_errors += stat_reg;
 
 	/* Clear all other statistic register. */
-	readw (ioaddr + InRangeLengthErrors);
-	readw (ioaddr + MacControlFramesXmtd);
+	readl (ioaddr + McstOctetXmtOk);
 	readw (ioaddr + BcstFramesXmtdOk);
 	readl (ioaddr + McstFramesXmtdOk);
+	readw (ioaddr + BcstFramesRcvdOk);
+	readw (ioaddr + MacControlFramesRcvd);
+	readw (ioaddr + FrameTooLongErrors);
+	readw (ioaddr + InRangeLengthErrors);
+	readw (ioaddr + FramesCheckSeqErrors);
+	readw (ioaddr + FramesLostRxErrors);
+	readl (ioaddr + McstOctetXmtOk);
 	readl (ioaddr + BcstOctetXmtOk);
+	readl (ioaddr + McstFramesXmtdOk);
+	readl (ioaddr + FramesWDeferredXmt);
+	readl (ioaddr + LateCollisions);
+	readw (ioaddr + BcstFramesXmtdOk);
+	readw (ioaddr + MacControlFramesXmtd);
+	readw (ioaddr + FramesWEXDeferal);
+
+
+	for (i = 0x100; i <= 0x150; i += 4)
+		readl (ioaddr + i);
+	readw (ioaddr + TxJumboFrames);
+	readw (ioaddr + RxJumboFrames);
+	readw (ioaddr + TCPCheckSumErrors);
+	readw (ioaddr + UDPCheckSumErrors);
+	readw (ioaddr + IPCheckSumErrors);
+	return &np->stats;
+}
+
+static int
+clear_stats (struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	int i;
+
+	/* All statistics registers need to be acknowledged,
+	   else statistic overflow could cause problems */
+	readl (ioaddr + FramesRcvOk);
+	readl (ioaddr + FramesXmtOk);
+	readl (ioaddr + OctetRcvOk);
+	readl (ioaddr + OctetXmtOk);
+
+	readl (ioaddr + McstFramesRcvdOk);
+	readl (ioaddr + SingleColFrames);
+	readl (ioaddr + MultiColFrames);
+	readl (ioaddr + LateCollisions);
+	/* detailed rx errors */		
+	readw (ioaddr + FrameTooLongErrors);
+	readw (ioaddr + InRangeLengthErrors);
+	readw (ioaddr + FramesCheckSeqErrors);
+	readw (ioaddr + FramesLostRxErrors);
+
+	/* detailed tx errors */
+	readw (ioaddr + FramesAbortXSColls);
+	readw (ioaddr + CarrierSenseErrors);
+
+	/* Clear all other statistic register. */
 	readl (ioaddr + McstOctetXmtOk);
+	readw (ioaddr + BcstFramesXmtdOk);
+	readl (ioaddr + McstFramesXmtdOk);
+	readw (ioaddr + BcstFramesRcvdOk);
 	readw (ioaddr + MacControlFramesRcvd);
-	readw (ioaddr + BcstFramesRcvOk);
-	readl (ioaddr + McstFramesRcvOk);
-	readl (ioaddr + BcstOctetRcvOk);
+	readl (ioaddr + McstOctetXmtOk);
+	readl (ioaddr + BcstOctetXmtOk);
+	readl (ioaddr + McstFramesXmtdOk);
+	readl (ioaddr + FramesWDeferredXmt);
+	readw (ioaddr + BcstFramesXmtdOk);
+	readw (ioaddr + MacControlFramesXmtd);
+	readw (ioaddr + FramesWEXDeferal);
 
 	for (i = 0x100; i <= 0x150; i += 4)
 		readl (ioaddr + i);
@@ -975,9 +1075,10 @@
 	readw (ioaddr + TCPCheckSumErrors);
 	readw (ioaddr + UDPCheckSumErrors);
 	readw (ioaddr + IPCheckSumErrors);
-	return &np->stats;
+	return 0;
 }
 
+
 int
 change_mtu (struct net_device *dev, int new_mtu)
 {
@@ -993,23 +1094,6 @@
 	return 0;
 }
 
-#define CRC_POLY 0xedb88320
-static unsigned
-get_crc (unsigned char *p, int len)
-{
-	int bit;
-	unsigned char byte;
-	unsigned crc = 0xffffffff;
-
-	while (--len >= 0) {
-		byte = *p++;
-		for (bit = 0; bit < 8; bit++, byte >>= 1) {
-			crc = (crc >> 1) ^ (((crc ^ byte) & 1) ? CRC_POLY : 0);
-		}
-	}
-	return crc;
-}
-
 static void
 set_multicast (struct net_device *dev)
 {
@@ -1024,7 +1108,7 @@
 	
 	hash_table[0] = hash_table[1] = 0;
 	/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
-	hash_table[1] |= 0x02000000;
+	hash_table[1] |= cpu_to_le32(0x02000000);
 	if (dev->flags & IFF_PROMISC) {
 		/* Receive all frames promiscuously. */
 		rx_mode = ReceiveAllFrames;
@@ -1038,11 +1122,16 @@
 		rx_mode =
 		    ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
 		for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count; 
-				i++, mclist=mclist->next) {
-			crc = get_crc (mclist->dmi_addr, ETH_ALEN);
-			for (index=0, bit=0; bit<6; bit++, crc<<=1) {
-				if (crc & 0x80000000) index |= 1 << bit;
-			}
+			i++, mclist=mclist->next) {
+
+			crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
+
+			/* The inverted high significant 6 bits of CRC are
+			   used as an index to hashtable */
+			for (index = 0, bit = 0; bit < 6; bit++)
+				if (test_bit(31 - bit, &crc))
+					set_bit(bit, &index);
+
 			hash_table[index / 32] |= (1 << (index % 32));
 		}
 	} else {
@@ -1064,58 +1153,44 @@
 	int phy_addr;
 	struct netdev_private *np = dev->priv;
 	struct mii_data *miidata = (struct mii_data *) &rq->ifr_data;
-#ifdef RIO_DEBUG
-	struct ioctl_data *iodata = (struct ioctl_data *) (rq->ifr_data);
-#endif
-	u16 *data = (u16 *) & rq->ifr_data;
+	
 	struct netdev_desc *desc;
 	int i;
 
 	phy_addr = np->phy_addr;
 	switch (cmd) {
 	case SIOCDEVPRIVATE:
-#ifdef RIO_DEBUG
-		if (rio_ioctl_ext (dev, iodata) != 0)
-			return -EOPNOTSUPP;
 		break;
-#else
-		return -EOPNOTSUPP;
-#endif
+	
 	case SIOCDEVPRIVATE + 1:
 		miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);
 		break;
 	case SIOCDEVPRIVATE + 2:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value);
 		break;
 	case SIOCDEVPRIVATE + 3:
-		np->rx_debug = (data[0] <= 7) ? data[0] : 0;
-		printk ("rx_debug = %d\n", np->rx_debug);
 		break;
 	case SIOCDEVPRIVATE + 4:
-		np->tx_debug = (data[0] <= 7) ? data[0] : 0;
-		printk ("tx_debug = %d\n", np->tx_debug);
 		break;
 	case SIOCDEVPRIVATE + 5:
-		np->tx_full = 1;
 		netif_stop_queue (dev);
 		break;
 	case SIOCDEVPRIVATE + 6:
-		np->tx_full = 0;
 		netif_wake_queue (dev);
 		break;
 	case SIOCDEVPRIVATE + 7:
 		printk
 		    ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",
-		     np->tx_full, np->cur_tx, np->old_tx, np->cur_rx,
+		     netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,
 		     np->old_rx);
 		break;
 	case SIOCDEVPRIVATE + 8:
+		printk("TX ring:\n");
 		for (i = 0; i < TX_RING_SIZE; i++) {
 			desc = &np->tx_ring[i];
 			printk
-			    ("cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
+			    ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
+			     i,
 			     (u32) (np->tx_ring_dma + i * sizeof (*desc)),
 			     (u32) desc->next_desc,
 			     (u32) desc->status, (u32) (desc->fraginfo >> 32),
@@ -1124,106 +1199,13 @@
 		}
 		printk ("\n");
 		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-	return 0;
-}
-
-#ifdef RIO_DEBUG
-int
-rio_ioctl_ext (struct net_device *dev, struct ioctl_data *iodata)
-{
-	struct netdev_private *np = dev->priv;
-	int phy_addr = np->phy_addr;
-	u32 hi, lo;
-	int i;
-	BMCR_t bmcr;
-	BMSR_t bmsr;
-
-	if (iodata == NULL)
-		goto invalid_cmd;
-	if (strcmp (iodata->signature, "rio") != 0)
-		goto invalid_cmd;
-
-	switch (iodata->cmd) {
-	case 0:
-		for (i = 0; i < TX_RING_SIZE; i++) {
-			hi = np->tx_ring[i].status >> 32;
-			lo = np->tx_ring[i].status;
-			printk ("TFC=%08x %08x \n", hi, lo);
-
-		}
-		break;
-	case 1:
-		for (i = 0; i < RX_RING_SIZE; i++) {
-			hi = np->rx_ring[i].status >> 32;
-			lo = np->rx_ring[i].status;
-			printk ("RFS=%08x %08x \n", hi, lo);
-		}
-		break;
-	case 2:
-		break;
-	case 3:
-		if (iodata->data != NULL)
-			np->tx_debug = iodata->data[0];
-		break;
-	case 4:
-		/* Soft reset PHY */
-		mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
-		bmcr.image = 0;
-		bmcr.bits.an_enable = 1;
-		bmcr.bits.reset = 1;
-		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
-		break;
-	case 5:
-		mii_write (dev, phy_addr, MII_BMCR, 0x1940);
-		mdelay (10);
-		mii_write (dev, phy_addr, MII_BMCR, 0x1940);
-		mdelay (100);	/* wait a certain time */
-		break;
-	case 6:
-		/* 5) Set media and Power Up */
-		bmcr.image = 0;
-		bmcr.bits.power_down = 1;
-		if (np->an_enable) {
-			bmcr.bits.an_enable = 1;
-		} else {
-			if (np->speed == 100) {
-				bmcr.bits.speed100 = 1;
-				bmcr.bits.speed1000 = 0;
-				printk ("Manual 100 Mbps, ");
-			} else if (np->speed == 10) {
-				bmcr.bits.speed100 = 0;
-				bmcr.bits.speed1000 = 0;
-				printk ("Manual 10 Mbps, ");
-			}
-			if (np->full_duplex) {
-				bmcr.bits.duplex_mode = 1;
-				printk ("Full duplex. \n");
-			} else {
-				bmcr.bits.duplex_mode = 0;
-				printk ("Half duplex.\n");
-			}
-		}
-		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
-		break;
-	case 7:
-		bmcr.image = mii_read (dev, phy_addr, MII_BMCR);
-		bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
-		printk ("BMCR=%x BMSR=%x LinkUp=%d\n",
-			bmcr.image, bmsr.image, bmsr.bits.link_status);
-		break;
 
 	default:
 		return -EOPNOTSUPP;
 	}
 	return 0;
-
-      invalid_cmd:
-	return -1;
 }
-#endif
+
 #define EEP_READ 0x0200
 #define EEP_BUSY 0x8000
 /* Read the EEPROM word */
@@ -1393,10 +1375,11 @@
 			printk (KERN_INFO "Auto 10 Mbps, Half duplex\n");
 		}
 		if (negotiate.bits.pause) {
-			np->tx_flow = 1;
-			np->rx_flow = 1;
+			np->tx_flow &= 1;
+			np->rx_flow &= 1;
 		} else if (negotiate.bits.asymmetric) {
-			np->rx_flow = 1;
+			np->tx_flow = 0;
+			np->rx_flow &= 1;
 		}
 		/* else tx_flow, rx_flow = user select  */
 	} else {
@@ -1545,10 +1528,11 @@
 			np->full_duplex = 0;
 		}
 		if (negotiate.bits.pause) {
-			np->tx_flow = 1;
-			np->rx_flow = 1;
+			np->tx_flow &= 1;
+			np->rx_flow &= 1;
 		} else if (negotiate.bits.asymmetric) {
-			np->rx_flow = 1;
+			np->tx_flow = 0;
+			np->rx_flow &= 1;
 		}
 		/* else tx_flow, rx_flow = user select  */
 	} else {
@@ -1647,7 +1631,8 @@
 	writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
 	synchronize_irq ();
 	free_irq (dev->irq, dev);
-
+	del_timer_sync (&np->timer);
+	
 	/* Free all the skbuffs in the queue. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		np->rx_ring[i].status = 0;
@@ -1697,10 +1682,10 @@
 }
 
 static struct pci_driver rio_driver = {
-	name:"dl2k",
-	id_table:rio_pci_tbl,
-	probe:rio_probe1,
-	remove:__devexit_p(rio_remove1),
+	name:		"dl2k",
+	id_table:	rio_pci_tbl,
+	probe:		rio_probe1,
+	remove:		__devexit_p(rio_remove1),
 };
 
 static int __init
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/dl2k.h linux/drivers/net/dl2k.h
--- linux.orig/drivers/net/dl2k.h	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/dl2k.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,6 +1,6 @@
 /*  D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
 /*  
-    Copyright (c) 2001 by D-Link Corporation
+    Copyright (c) 2001, 2002 by D-Link Corporation
     Written by Edward Peng.<edward_peng@dlink.com.tw>
     Created 03-May-2001, base on Linux' sundance.c.
 
@@ -26,6 +26,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/processor.h>	/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -118,13 +119,13 @@
 	McstOctetRcvOk = 0xac,
 	BcstOctetRcvOk = 0xb0,
 	FramesRcvOk = 0xb4,
-	McstFramesRcvOk = 0xb8,
-	BcstFramesRcvOk = 0xbe,
+	McstFramesRcvdOk = 0xb8,
+	BcstFramesRcvdOk = 0xbe,
 	MacControlFramesRcvd = 0xc6,
 	FrameTooLongErrors = 0xc8,
 	InRangeLengthErrors = 0xca,
-	FrameCheckSeqError = 0xcc,
-	FrameLostRxError = 0xce,
+	FramesCheckSeqErrors = 0xcc,
+	FramesLostRxErrors = 0xce,
 	OctetXmtOk = 0xd0,
 	McstOctetXmtOk = 0xd4,
 	BcstOctetXmtOk = 0xd8,
@@ -263,6 +264,7 @@
 	FrameEnd = 0x40000000,
 	RFDDone = 0x80000000,
 	TCIShift = 32,
+	RFS_Errors = 0x003f0000,
 };
 
 #define MII_RESET_TIME_OUT		10000
@@ -647,7 +649,8 @@
 	dma_addr_t tx_ring_dma;
 	dma_addr_t rx_ring_dma;
 	struct pci_dev *pdev;
-	spinlock_t lock;
+	spinlock_t tx_lock;
+	spinlock_t rx_lock;
 	struct net_device_stats stats;
 	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
 	unsigned int speed;		/* Operating speed */
@@ -655,7 +658,6 @@
 	unsigned int chip_id;		/* PCI table chip id */
 	unsigned int rx_coalesce; 	/* Maximum frames each RxDMAComplete intr */
 	unsigned int rx_timeout; 	/* Wait time between RxDMAComplete intr */
-	unsigned int tx_full:1;		/* The Tx queue is full. */
 	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
 	unsigned int an_enable:2;	/* Auto-Negotiated Enable */
 	unsigned int jumbo:1;		/* Jumbo frame enable */
@@ -663,9 +665,12 @@
 	unsigned int tx_flow:1;		/* Tx flow control enable */
 	unsigned int rx_flow:1;		/* Rx flow control enable */
 	unsigned int phy_media:1;	/* 1: fiber, 0: copper */
+	unsigned int link_status:1;	/* Current link status */
+	unsigned char pci_rev_id;	/* PCI revision ID */
 	struct netdev_desc *last_tx;	/* Last Tx descriptor used. */
 	unsigned long cur_rx, old_rx;	/* Producer/consumer ring indices */
 	unsigned long cur_tx, old_tx;
+	struct timer_list timer;
 	int wake_polarity;
 	char name[256];		/* net device description */
 	u8 duplex_polarity;
@@ -673,8 +678,6 @@
 	u16 advertising;	/* NWay media advertisement */
 	u16 negotiate;		/* Negotiated media */
 	int phy_addr;		/* PHY addresses. */
-	int tx_debug;
-	int rx_debug;
 };
 
 /* The station address location in the EEPROM. */
@@ -703,113 +706,4 @@
 #define DEFAULT_RXT		750
 #define DEFAULT_TXC		1
 #define MAX_TXC			8
-#ifdef RIO_DEBUG
-#define DEBUG_TFD_DUMP(x) debug_tfd_dump(x)
-#define DEBUG_RFD_DUMP(x,flag) debug_rfd_dump(x,flag)
-#define DEBUG_PKT_DUMP(x,len) debug_pkt_dump(x,len)
-#define DEBUG_PRINT printk
-
-static inline void
-debug_tfd_dump (struct netdev_private *np)
-{
-	int i;
-	struct netdev_desc *desc;
-
-	if (np->tx_debug == 6) {
-		printk ("TFDone Dump: ");
-		for (i = 0; i < TX_RING_SIZE; i++) {
-			desc = &np->tx_ring[i];
-			if ((desc->fraginfo & 0xffffffffff) == 0)
-				printk ("X");
-			else
-				printk ("%d", (desc->status & TFDDone) ? 1 : 0);
-		}
-		printk ("\n");
-	}
-	if (np->tx_debug == 5) {
-		for (i = 0; i < TX_RING_SIZE; i++) {
-			desc = &np->tx_ring[i];
-			printk
-			    ("cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
-			     (u32) np->tx_ring_dma + i * sizeof (*desc),
-			     (u32) desc->next_desc, (u32) desc->status,
-			     (u32) (desc->fraginfo >> 32),
-			     (u32) desc->fraginfo);
-			printk ("\n");
-		}
-		printk ("\n");
-	}
-}
-static inline void
-debug_rfd_dump (struct netdev_private *np, int flag)
-{
-	int i;
-	struct netdev_desc *desc;
-	int entry = np->cur_rx % RX_RING_SIZE;
-
-	if (np->rx_debug == 5) {
-		for (i = 0; i < RX_RING_SIZE; i++) {
-			desc = &np->rx_ring[i];
-			printk
-			    ("cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
-			     (u32) np->rx_ring_dma + i * sizeof (*desc),
-			     (u32) desc->next_desc, (u32) desc->status,
-			     (u32) (desc->fraginfo >> 32),
-			     (u32) desc->fraginfo);
-			printk ("\n");
-		}
-		printk ("\n");
-	}
-
-	if (np->rx_debug == 6) {
-		if (flag == 1)
-			printk ("RFDone Dump: ");
-		else if (flag == 2)
-			printk ("Re-Filling:  ");
-		for (i = 0; i < RX_RING_SIZE; i++) {
-			desc = &np->rx_ring[i];
-			printk ("%d", (desc->status & RFDDone) ? 1 : 0);
-		}
-		printk ("\n");
-	}
-	if (np->rx_debug == 7) {
-		printk (" In rcv_pkt(), entry %d status %4.4x %4.4x.\n",
-			entry, (u32) (np->rx_ring[entry].status >> 32),
-			(u32) np->rx_ring[entry].status);
-	}
-
-}
-
-static inline void
-debug_pkt_dump (struct netdev_private *np, int pkt_len)
-{
-	int entry = np->cur_rx % RX_RING_SIZE;
-	struct netdev_desc *desc = &np->rx_ring[entry];
-	u64 frame_status = le64_to_cpu (desc->status);
-	unsigned char *pchar;
-	unsigned char *phead;
-	int i;
-
-	if (np->rx_debug == 4) {
-		printk ("  rcv_pkt: status was %4.4x %4.4x.\n",
-			(u32) (frame_status >> 32), (u32) frame_status);
-	}
-	if (np->rx_debug == 7) {
-
-		phead =
-		    bus_to_virt (le64_to_cpu (desc->fraginfo & 0xffffffffff));
-		for (pchar = phead, i = 0; i < pkt_len; i++, pchar++) {
-			printk ("%02x ", *pchar);
-			if ((i + 1) % 20 == 0)
-				printk ("\n");
-		}
-	}
-}
-#else
-#define DEBUG_TFD_DUMP(x) {}
-#define DEBUG_RFD_DUMP(x,flag) {}
-#define DEBUG_PKT_DUMP(x,len) {}
-#define DEBUG_PRINT() {}
-#endif
-
 #endif				/* __DL2K_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/dmfe.c linux/drivers/net/dmfe.c
--- linux.orig/drivers/net/dmfe.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/dmfe.c	2002-07-20 01:08:39.000000000 +0000
@@ -84,6 +84,7 @@
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/crc32.h>
 
 #include <asm/processor.h>
 #include <asm/bitops.h>
@@ -287,72 +288,6 @@
 static u8 SF_mode;		/* Special Function: 1:VLAN, 2:RX Flow Control
 				   4: TX pause packet */
 
-unsigned long CrcTable[256] = {
-	0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
-	0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
-	0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
-	0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
-	0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
-	0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
-	0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
-	0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
-	0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
-	0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
-	0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
-	0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
-	0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
-	0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
-	0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
-	0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
-	0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
-	0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
-	0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
-	0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
-	0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
-	0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
-	0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
-	0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
-	0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
-	0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
-	0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
-	0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
-	0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
-	0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
-	0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
-	0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
-	0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
-	0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
-	0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
-	0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
-	0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
-	0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
-	0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
-	0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
-	0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
-	0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
-	0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
-	0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
-	0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
-	0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
-	0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
-	0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
-	0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
-	0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
-	0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
-	0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
-	0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
-	0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
-	0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
-	0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
-	0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
-	0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
-	0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
-	0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
-	0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
-	0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
-	0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
-	0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
-};
 
 /* function declaration ------------------------------------- */
 static int dmfe_open(struct DEVICE *);
@@ -381,7 +316,7 @@
 static void dmfe_dynamic_reset(struct DEVICE *);
 static void dmfe_free_rxbuffer(struct dmfe_board_info *);
 static void dmfe_init_dm910x(struct DEVICE *);
-static unsigned long cal_CRC(unsigned char *, unsigned int, u8);
+static inline u32 cal_CRC(unsigned char *, unsigned int, u8);
 static void dmfe_parse_srom(struct dmfe_board_info *);
 static void dmfe_program_DM9801(struct dmfe_board_info *, int);
 static void dmfe_program_DM9802(struct dmfe_board_info *);
@@ -1850,18 +1785,11 @@
  *		0 : return the normal CRC (for Hash Table index)
  */
 
-unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
+static inline u32 cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
 {
-	unsigned long Crc = 0xffffffff;
-
-	while (Len--) {
-		Crc = CrcTable[(Crc ^ *Data++) & 0xFF] ^ (Crc >> 8);
-	}
-
-	if (flag)
-		return ~Crc;
-	else
-		return Crc;
+	u32 crc = ether_crc_le(Len, Data);
+	if (flag) crc = ~crc;
+	return crc;
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/e2100.c linux/drivers/net/e2100.c
--- linux.orig/drivers/net/e2100.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/e2100.c	2002-07-20 01:08:39.000000000 +0000
@@ -388,10 +388,12 @@
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
 MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
-MODULE_PARM_DESC(io, "E2100 I/O base address(es)");
-MODULE_PARM_DESC(irq, "E2100 IRQ number(s)");
-MODULE_PARM_DESC(mem, " E2100 memory base address(es)");
-MODULE_PARM_DESC(xcvr, "E2100 tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(io, "I/O base address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(mem, " memory base address(es)");
+MODULE_PARM_DESC(xcvr, "tranceiver(s) (0=internal, 1=external)");
+MODULE_DESCRIPTION("Cabletron E2100 ISA ethernet driver");
+MODULE_LICENSE("GPL");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
@@ -440,7 +442,6 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- linux.orig/drivers/net/eepro100.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/eepro100.c	2002-07-20 01:08:38.000000000 +0000
@@ -64,8 +64,8 @@
 
 /* A few values that may be tweaked. */
 /* The ring sizes should be a power of two for efficiency. */
-#define TX_RING_SIZE	32
-#define RX_RING_SIZE	32
+#define TX_RING_SIZE	64
+#define RX_RING_SIZE	64
 /* How much slots multicast filter setup may take.
    Do not descrease without changing set_rx_mode() implementaion. */
 #define TX_MULTICAST_SIZE   2
@@ -114,7 +114,6 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
-#include <linux/delay.h>
 
 MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");
 MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver");
@@ -130,17 +129,17 @@
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(multicast_filter_limit, "i");
-MODULE_PARM_DESC(debug, "eepro100 debug level (0-6)");
-MODULE_PARM_DESC(options, "eepro100: Bits 0-3: tranceiver type, bit 4: full duplex, bit 5: 100Mbps");
-MODULE_PARM_DESC(full_duplex, "eepro100 full duplex setting(s) (1)");
-MODULE_PARM_DESC(congenb, "eepro100  Enable congestion control (1)");
-MODULE_PARM_DESC(txfifo, "eepro100 Tx FIFO threshold in 4 byte units, (0-15)");
-MODULE_PARM_DESC(rxfifo, "eepro100 Rx FIFO threshold in 4 byte units, (0-15)");
-MODULE_PARM_DESC(txdmaccount, "eepro100 Tx DMA burst length; 128 - disable (0-128)");
-MODULE_PARM_DESC(rxdmaccount, "eepro100 Rx DMA burst length; 128 - disable (0-128)");
-MODULE_PARM_DESC(rx_copybreak, "eepro100 copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(max_interrupt_work, "eepro100 maximum events handled per interrupt");
-MODULE_PARM_DESC(multicast_filter_limit, "eepro100 maximum number of filtered multicast addresses");
+MODULE_PARM_DESC(debug, "debug level (0-6)");
+MODULE_PARM_DESC(options, "Bits 0-3: tranceiver type, bit 4: full duplex, bit 5: 100Mbps");
+MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
+MODULE_PARM_DESC(congenb, "Enable congestion control (1)");
+MODULE_PARM_DESC(txfifo, "Tx FIFO threshold in 4 byte units, (0-15)");
+MODULE_PARM_DESC(rxfifo, "Rx FIFO threshold in 4 byte units, (0-15)");
+MODULE_PARM_DESC(txdmaccount, "Tx DMA burst length; 128 - disable (0-128)");
+MODULE_PARM_DESC(rxdmaccount, "Rx DMA burst length; 128 - disable (0-128)");
+MODULE_PARM_DESC(rx_copybreak, "copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
+MODULE_PARM_DESC(multicast_filter_limit, "maximum number of filtered multicast addresses");
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -525,10 +524,8 @@
 static int eepro100_init_one(struct pci_dev *pdev,
 		const struct pci_device_id *ent);
 static void eepro100_remove_one (struct pci_dev *pdev);
-#ifdef CONFIG_PM
 static int eepro100_suspend (struct pci_dev *pdev, u32 state);
 static int eepro100_resume (struct pci_dev *pdev);
-#endif
 
 static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
 static int mdio_read(long ioaddr, int phy_id, int location);
@@ -570,6 +567,19 @@
 	if (speedo_debug > 0  &&  did_version++ == 0)
 		printk(version);
 
+	/* save power state before pci_enable_device overwrites it */
+	pm = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (pm) {
+		u16 pwr_command;
+		pci_read_config_word(pdev, pm + PCI_PM_CTRL, &pwr_command);
+		acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
+	}
+
+	if (pci_enable_device(pdev))
+		goto err_out_free_mmio_region;
+
+	pci_set_master(pdev);
+
 	if (!request_region(pci_resource_start(pdev, 1),
 			pci_resource_len(pdev, 1), "eepro100")) {
 		printk (KERN_ERR "eepro100: cannot reserve I/O ports\n");
@@ -600,18 +610,6 @@
 			   pci_resource_start(pdev, 0), irq);
 #endif
 
-	/* save power state b4 pci_enable_device overwrites it */
-	pm = pci_find_capability(pdev, PCI_CAP_ID_PM);
-	if (pm) {
-		u16 pwr_command;
-		pci_read_config_word(pdev, pm + PCI_PM_CTRL, &pwr_command);
-		acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
-	}
-
-	if (pci_enable_device(pdev))
-		goto err_out_free_mmio_region;
-
-	pci_set_master(pdev);
 
 	if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0)
 		cards_found++;
@@ -632,7 +630,7 @@
 	return -ENODEV;
 }
 
-static int speedo_found1(struct pci_dev *pdev,
+static int __devinit speedo_found1(struct pci_dev *pdev,
 		long ioaddr, int card_idx, int acpi_idle_state)
 {
 	struct net_device *dev;
@@ -826,8 +824,9 @@
 	sp->phy[0] = eeprom[6];
 	sp->phy[1] = eeprom[7];
 	sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1;
-	if (((pdev->device > 0x1030 && (pdev->device < 0x1039))) 
-	    || (pdev->device == 0x2449)) {
+	if (((pdev->device > 0x1030 && (pdev->device < 0x103F))) 
+	    || (pdev->device == 0x2449) || (pdev->device == 0x2459) 
+            || (pdev->device == 0x245D)) {
 	    	sp->chip_id = 1;
 	}
 
@@ -865,7 +864,7 @@
    interval for serial EEPROM.  However, it looks like that there is an
    additional requirement dictating larger udelay's in the code below.
    2000/05/24  SAW */
-static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
+static int __devinit do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
 {
 	unsigned retval = 0;
 	long ee_addr = ioaddr + SCBeeprom;
@@ -1074,6 +1073,51 @@
 	outw(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd);
 }
 
+/*
+ * Sometimes the receiver stops making progress.  This routine knows how to
+ * get it going again, without losing packets or being otherwise nasty like
+ * a chip reset would be.  Previously the driver had a whole sequence
+ * of if RxSuspended, if it's no buffers do one thing, if it's no resources,
+ * do another, etc.  But those things don't really matter.  Separate logic
+ * in the ISR provides for allocating buffers--the other half of operation
+ * is just making sure the receiver is active.  speedo_rx_soft_reset does that.
+ * This problem with the old, more involved algorithm is shown up under
+ * ping floods on the order of 60K packets/second on a 100Mbps fdx network.
+ */
+static void
+speedo_rx_soft_reset(struct net_device *dev)
+{
+	struct speedo_private *sp = dev->priv;
+	struct RxFD *rfd;
+	long ioaddr;
+
+	ioaddr = dev->base_addr;
+	wait_for_cmd_done(ioaddr + SCBCmd);
+	if (inb(ioaddr + SCBCmd) != 0) {
+		printk("%s: previous command stalled\n", dev->name);
+		return;
+	}
+	/*
+	* Put the hardware into a known state.
+	*/
+	outb(RxAbort, ioaddr + SCBCmd);
+
+	rfd = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
+
+	rfd->rx_buf_addr = 0xffffffff;
+
+	wait_for_cmd_done(ioaddr + SCBCmd);
+
+	if (inb(ioaddr + SCBCmd) != 0) {
+		printk("%s: RxAbort command stalled\n", dev->name);
+		return;
+	}
+	outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
+		ioaddr + SCBPointer);
+	outb(RxStart, ioaddr + SCBCmd);
+}
+
+
 /* Media monitoring and control. */
 static void speedo_timer(unsigned long data)
 {
@@ -1377,9 +1421,10 @@
 
 	/* workaround for hardware bug on 10 mbit half duplex */
 
-	if ((sp->partner == 0) || (sp->chip_id == 1)) {
+	if ((sp->partner == 0) && (sp->chip_id == 1)) {
 		wait_for_cmd_done(ioaddr + SCBCmd);
 		outb(0 , ioaddr + SCBCmd);
+		udelay(1);
 	}
 
 	/* Trigger the command unit resume. */
@@ -1507,82 +1552,39 @@
 		if ((status & 0xfc00) == 0)
 			break;
 
-		/* Always check if all rx buffers are allocated.  --SAW */
-		speedo_refill_rx_buffers(dev, 0);
 
 		if ((status & 0x5000) ||	/* Packet received, or Rx error. */
 			(sp->rx_ring_state&(RrNoMem|RrPostponed)) == RrPostponed)
 									/* Need to gather the postponed packet. */
 			speedo_rx(dev);
 
-		if (status & 0x1000) {
-			spin_lock(&sp->lock);
-			if ((status & 0x003c) == 0x0028) {		/* No more Rx buffers. */
-				struct RxFD *rxf;
-				printk(KERN_WARNING "%s: card reports no RX buffers.\n",
-						dev->name);
-				rxf = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
-				if (rxf == NULL) {
-					if (speedo_debug > 2)
-						printk(KERN_DEBUG
-								"%s: NULL cur_rx in speedo_interrupt().\n",
-								dev->name);
-					sp->rx_ring_state |= RrNoMem|RrNoResources;
-				} else if (rxf == sp->last_rxf) {
-					if (speedo_debug > 2)
-						printk(KERN_DEBUG
-								"%s: cur_rx is last in speedo_interrupt().\n",
-								dev->name);
-					sp->rx_ring_state |= RrNoMem|RrNoResources;
-				} else
-					outb(RxResumeNoResources, ioaddr + SCBCmd);
-			} else if ((status & 0x003c) == 0x0008) { /* No resources. */
-				struct RxFD *rxf;
-				printk(KERN_WARNING "%s: card reports no resources.\n",
-						dev->name);
-				rxf = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
-				if (rxf == NULL) {
-					if (speedo_debug > 2)
-						printk(KERN_DEBUG
-								"%s: NULL cur_rx in speedo_interrupt().\n",
-								dev->name);
-					sp->rx_ring_state |= RrNoMem|RrNoResources;
-				} else if (rxf == sp->last_rxf) {
-					if (speedo_debug > 2)
-						printk(KERN_DEBUG
-								"%s: cur_rx is last in speedo_interrupt().\n",
-								dev->name);
-					sp->rx_ring_state |= RrNoMem|RrNoResources;
-				} else {
-					/* Restart the receiver. */
-					outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
-						 ioaddr + SCBPointer);
-					outb(RxStart, ioaddr + SCBCmd);
-				}
-			}
-			sp->stats.rx_errors++;
-			spin_unlock(&sp->lock);
-		}
-
-		if ((sp->rx_ring_state&(RrNoMem|RrNoResources)) == RrNoResources) {
-			printk(KERN_WARNING
-					"%s: restart the receiver after a possible hang.\n",
-					dev->name);
-			spin_lock(&sp->lock);
-			/* Restart the receiver.
-			   I'm not sure if it's always right to restart the receiver
-			   here but I don't know another way to prevent receiver hangs.
-			   1999/12/25 SAW */
-			outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
-				 ioaddr + SCBPointer);
-			outb(RxStart, ioaddr + SCBCmd);
-			sp->rx_ring_state &= ~RrNoResources;
-			spin_unlock(&sp->lock);
+		/* Always check if all rx buffers are allocated.  --SAW */
+		speedo_refill_rx_buffers(dev, 0);
+		
+		spin_lock(&sp->lock);
+		/*
+		 * The chip may have suspended reception for various reasons.
+		 * Check for that, and re-prime it should this be the case.
+		 */
+		switch ((status >> 2) & 0xf) {
+		case 0: /* Idle */
+			break;
+		case 1:	/* Suspended */
+		case 2:	/* No resources (RxFDs) */
+		case 9:	/* Suspended with no more RBDs */
+		case 10: /* No resources due to no RBDs */
+		case 12: /* Ready with no RBDs */
+			speedo_rx_soft_reset(dev);
+			break;
+		case 3:  case 5:  case 6:  case 7:  case 8:
+		case 11:  case 13:  case 14:  case 15:
+			/* these are all reserved values */
+			break;
 		}
-
+		
+		
 		/* User interrupt, Command/Tx unit interrupt or CU not active. */
 		if (status & 0xA400) {
-			spin_lock(&sp->lock);
 			speedo_tx_buffer_gc(dev);
 			if (sp->tx_full
 				&& (int)(sp->cur_tx - sp->dirty_tx) < TX_QUEUE_UNFULL) {
@@ -1590,8 +1592,9 @@
 				sp->tx_full = 0;
 				netif_wake_queue(dev); /* Attention: under a spinlock.  --SAW */
 			}
-			spin_unlock(&sp->lock);
 		}
+		
+		spin_unlock(&sp->lock);
 
 		if (--boguscnt < 0) {
 			printk(KERN_ERR "%s: Too much work at interrupt, status=0x%4.4x.\n",
@@ -2205,6 +2208,8 @@
 
 	if (!netif_running(dev))
 		return 0;
+		
+	del_timer_sync(&sp->timer);
 
 	netif_device_detach(dev);
 	outl(PortPartialReset, ioaddr + SCBPort);
@@ -2237,6 +2242,8 @@
 	sp->rx_mode = -1;
 	sp->flow_ctrl = sp->partner = 0;
 	set_rx_mode(dev);
+	sp->timer.expires = RUN_AT(2*HZ);
+	add_timer(&sp->timer);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -2279,8 +2286,17 @@
 	{ PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x1228, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0,}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/epic100.c linux/drivers/net/epic100.c
--- linux.orig/drivers/net/epic100.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/epic100.c	2002-07-20 01:08:35.000000000 +0000
@@ -60,11 +60,14 @@
 	LK1.1.12:
 	* fix power-up sequence
 
+	LK1.1.13:
+	* revert version 1.1.12, power-up sequence "fix"
+
 */
 
 #define DRV_NAME	"epic100"
-#define DRV_VERSION	"1.11+LK1.1.12"
-#define DRV_RELDATE	"Jan 18, 2002"
+#define DRV_VERSION	"1.11+LK1.1.13"
+#define DRV_RELDATE	"Mar 20, 2002"
 
 
 /* The user-configurable values.
@@ -131,6 +134,7 @@
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/crc32.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -578,7 +582,7 @@
 #define EE_READ256_CMD	(6 << 8)
 #define EE_ERASE_CMD	(7 << 6)
 
-static int read_eeprom(long ioaddr, int location)
+static int __devinit read_eeprom(long ioaddr, int location)
 {
 	int i;
 	int retval = 0;
@@ -677,8 +681,9 @@
 	   required by the details of which bits are reset and the transceiver
 	   wiring on the Ositech CardBus card.
 	*/
-
-	outl(0x12, ioaddr + MIICfg);
+#if 0
+	outl(dev->if_port == 1 ? 0x13 : 0x12, ioaddr + MIICfg);
+#endif
 	if (ep->chip_flags & MII_PWRDWN)
 		outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
 
@@ -1302,27 +1307,6 @@
    new frame, not around filling ep->setup_frame.  This is non-deterministic
    when re-entered but still correct. */
 
-/* The little-endian AUTODIN II ethernet CRC calculation.
-   N.B. Do not use for bulk data, use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-	unsigned int crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-
 static void set_rx_mode(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/es3210.c linux/drivers/net/es3210.c
--- linux.orig/drivers/net/es3210.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/es3210.c	2002-07-20 01:08:29.000000000 +0000
@@ -383,9 +383,11 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
-MODULE_PARM_DESC(io, "ES3210 I/O base address(es)");
-MODULE_PARM_DESC(irq, "ES3210 IRQ number(s)");
-MODULE_PARM_DESC(mem, "ES3210 memory base address(es)");
+MODULE_PARM_DESC(io, "I/O base address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(mem, "memory base address(es)");
+MODULE_DESCRIPTION("Racal-Interlan ES3210 EISA ethernet driver");
+MODULE_LICENSE("GPL");
 
 int
 init_module(void)
@@ -429,5 +431,4 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- linux.orig/drivers/net/ewrk3.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/ewrk3.c	2002-07-20 01:08:35.000000000 +0000
@@ -132,6 +132,7 @@
    <kenneth@bbs.sas.ntu.ac.sg>.
    0.42    22-Apr-96      Fix alloc_device() bug <jari@markkus2.fimr.fi>
    0.43    16-Aug-96      Update alloc_device() to conform to de4x5.c
+   0.44    08-Nov-01      use library crc32 functions <Matt_Domsch@dell.com>
 
    =========================================================================
  */
@@ -148,6 +149,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -207,9 +209,6 @@
 #define EISA_SLOT_INC 0x1000
 #endif
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL	/* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL	/* Ethernet CRC, little endian */
-
 #define QUEUE_PKT_TIMEOUT (1*HZ)	/* Jiffies */
 
 /*
@@ -1174,10 +1173,10 @@
 	struct dev_mc_list *dmi = dev->mc_list;
 	u_long iobase = dev->base_addr;
 	int i;
-	char *addrs, j, bit, byte;
+	char *addrs, bit, byte;
 	short *p = (short *) lp->mctbl;
 	u16 hashcode;
-	s32 crc, poly = CRC_POLYNOMIAL_LE;
+	u32 crc;
 
 	spin_lock_irq(&lp->hw_lock);
 
@@ -1219,13 +1218,7 @@
 			addrs = dmi->dmi_addr;
 			dmi = dmi->next;
 			if ((*addrs & 0x01) == 1) {	/* multicast address? */
-				crc = 0xffffffff;	/* init CRC for each address */
-				for (byte = 0; byte < ETH_ALEN; byte++) {	/* for each address byte */
-					/* process each address bit */
-					for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-						crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
-					}
-				}
+				crc = ether_crc_le(ETH_ALEN, addrs);
 				hashcode = crc & ((1 << 9) - 1);	/* hashcode is 9 LSb of CRC */
 
 				byte = hashcode >> 3;	/* bit[3-8] -> byte in filter */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/fc/iph5526.c linux/drivers/net/fc/iph5526.c
--- linux.orig/drivers/net/fc/iph5526.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/net/fc/iph5526.c	2002-07-20 01:08:28.000000000 +0000
@@ -2984,8 +2984,7 @@
 	 */
 	if ((type == ETH_P_ARP) || (status == 0))
 		dev_kfree_skb(skb);
-	else
-		netif_wake_queue(dev);
+	netif_wake_queue(dev);
 	LEAVE("iph5526_send_packet");
 	return 0;
 }
@@ -3871,8 +3870,11 @@
 		/* Wait for the Link to come up and the login process 
 		 * to complete. 
 		 */
-		for(timeout = jiffies + 10*HZ; (timeout > jiffies) && ((fi->g.link_up == FALSE) || (fi->g.port_discovery == TRUE) || (fi->g.explore_fabric == TRUE) || (fi->g.perform_adisc == TRUE));)
+		for(timeout = jiffies + 10*HZ; time_before(jiffies, timeout) && ((fi->g.link_up == FALSE) || (fi->g.port_discovery == TRUE) || (fi->g.explore_fabric == TRUE) || (fi->g.perform_adisc == TRUE));)
+		{
+			cpu_relax();
 			barrier();
+		}
 		
 		count++;
 		no_of_hosts++;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/fealnx.c linux/drivers/net/fealnx.c
--- linux.orig/drivers/net/fealnx.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/fealnx.c	2002-07-20 01:08:27.000000000 +0000
@@ -84,6 +84,7 @@
 #include <linux/init.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/crc32.h>
 #include <asm/processor.h>	/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -439,7 +440,6 @@
 static int start_tx(struct sk_buff *skb, struct net_device *dev);
 static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
 static int netdev_rx(struct net_device *dev);
-static inline unsigned ether_crc(int length, unsigned char *data);
 static void set_rx_mode(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
 static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -1726,26 +1726,6 @@
 	return &np->stats;
 }
 
-
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
-	int crc = -1;
-
-	while (--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
-			crc = (crc << 1) ^
-			    ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
-		}
-	}
-
-	return crc;
-}
-
-
 static void set_rx_mode(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/gmac.c linux/drivers/net/gmac.c
--- linux.orig/drivers/net/gmac.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/gmac.c	2002-07-20 01:08:30.000000000 +0000
@@ -16,6 +16,8 @@
  *  - PHY updates
  * BenH <benh@kernel.crashing.org> - 08/08/2001
  * - Add more PHYs, fixes to sleep code
+ * Matt Domsch <Matt_Domsch@dell.com> - 11/12/2001
+ * - use library crc32 functions
  */
 
 #include <linux/module.h>
@@ -33,6 +35,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/crc32.h>
 #include <asm/prom.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -1000,14 +1003,13 @@
  * Configure promisc mode and setup multicast hash table
  * filter
  */
-#define CRC_POLY	0xedb88320
 static void
 gmac_set_multicast(struct net_device *dev)
 {
 	struct gmac *gm = (struct gmac *) dev->priv;
 	struct dev_mc_list *dmi = dev->mc_list;
 	int i,j,k,b;
-	unsigned long crc;
+	u32 crc;
 	int multicast_hash = 0;
 	int multicast_all = 0;
 	int promisc = 0;
@@ -1030,17 +1032,7 @@
 			hash_table[i] = 0;
 
 	    	for (i = 0; i < dev->mc_count; i++) {
-			crc = ~0;
-			for (j = 0; j < 6; ++j) {
-			    b = dmi->dmi_addr[j];
-			    for (k = 0; k < 8; ++k) {
-				if ((crc ^ b) & 1)
-				    crc = (crc >> 1) ^ CRC_POLY;
-				else
-				    crc >>= 1;
-				b >>= 1;
-			    }
-			}
+			crc = ether_crc_le(6, dmi->dmi_addr);
 			j = crc >> 24;	/* bit number in multicast_filter */
 			hash_table[j >> 4] |= 1 << (15 - (j & 0xf));
 			dmi = dmi->next;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/gt96100eth.c linux/drivers/net/gt96100eth.c
--- linux.orig/drivers/net/gt96100eth.c	2001-10-17 04:56:29.000000000 +0000
+++ linux/drivers/net/gt96100eth.c	2002-07-20 01:08:39.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000 MontaVista Software Inc.
+ * Copyright 2000, 2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
  *         	stevel@mvista.com or source@mvista.com
  *
@@ -22,13 +22,17 @@
  *
  * Ethernet driver for the MIPS GT96100 Advanced Communication Controller.
  * 
+ *  Revision history
+ *    
+ *    11.11.2001  Moved to 2.4.14, ppopov@mvista.com.  Modified driver to add
+ *                proper gt96100A support.
+ *    12.05.2001  Moved eth port 0 to irq 3 (mapped to GT_SERINT0 on EV96100A)
+ *                in order for both ports to work. Also cleaned up boot
+ *                option support (mac address string parsing), fleshed out
+ *                gt96100_cleanup_module(), and other general code cleanups
+ *                <stevel@mvista.com>.
  */
-
-#ifndef __mips__
-#error This driver only works with MIPS architectures!
-#endif
-
-
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -45,34 +49,49 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
+#include <linux/ctype.h>
 #include <asm/irq.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 
-#include "gt96100eth.h"
+#define DESC_BE 1
+#define DESC_DATA_BE 1
 
-#ifdef GT96100_DEBUG
-static int gt96100_debug = GT96100_DEBUG;
-#else
-static int gt96100_debug = 3;
-#endif
+#define GT96100_DEBUG 2
+
+#include "gt96100eth.h"
 
 // prototypes
-static void *dmaalloc(size_t size, dma_addr_t * dma_handle);
+static void* dmaalloc(size_t size, dma_addr_t *dma_handle);
 static void dmafree(size_t size, void *vaddr);
+static void gt96100_delay(int msec);
 static int gt96100_add_hash_entry(struct net_device *dev,
-				  unsigned char *addr);
+				  unsigned char* addr);
 static void read_mib_counters(struct gt96100_private *gp);
-static int read_MII(struct net_device *dev, u32 reg);
-static int write_MII(struct net_device *dev, u32 reg, u16 data);
-static void dump_MII(struct net_device *dev);
+static int read_MII(int phy_addr, u32 reg);
+static int write_MII(int phy_addr, u32 reg, u16 data);
+#if 0
+static void dump_tx_ring(struct net_device *dev);
+static void dump_rx_ring(struct net_device *dev);
+#endif
+static int gt96100_init_module(void);
+static void gt96100_cleanup_module(void);
+static void dump_MII(int dbg_lvl, struct net_device *dev);
+static void dump_tx_desc(int dbg_lvl, struct net_device *dev, int i);
+static void dump_rx_desc(int dbg_lvl, struct net_device *dev, int i);
+static void dump_skb(int dbg_lvl, struct net_device *dev,
+		     struct sk_buff *skb);
+static void dump_hw_addr(int dbg_lvl, struct net_device *dev,
+			 const char* pfx, unsigned char* addr_str);
 static void update_stats(struct gt96100_private *gp);
 static void abort(struct net_device *dev, u32 abort_bits);
 static void hard_stop(struct net_device *dev);
 static void enable_ether_irq(struct net_device *dev);
 static void disable_ether_irq(struct net_device *dev);
-static int __init gt96100_probe1(struct net_device *dev, long ioaddr,
-				 int irq, int port_num);
+static int gt96100_probe1(int port_num);
+static void reset_tx(struct net_device *dev);
+static void reset_rx(struct net_device *dev);
+static int gt96100_check_tx_consistent(struct gt96100_private *gp);
 static int gt96100_init(struct net_device *dev);
 static int gt96100_open(struct net_device *dev);
 static int gt96100_close(struct net_device *dev);
@@ -81,134 +100,229 @@
 static void gt96100_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void gt96100_tx_timeout(struct net_device *dev);
 static void gt96100_set_rx_mode(struct net_device *dev);
-static struct net_device_stats *gt96100_get_stats(struct net_device *dev);
+static struct net_device_stats* gt96100_get_stats(struct net_device *dev);
 
-static char version[] __devinitdata =
-    "gt96100eth.c:0.1 stevel@mvista.com\n";
+extern char * __init prom_getcmdline(void);
 
-// FIX! Need real Ethernet addresses
-static unsigned char gt96100_station_addr[2][6] __devinitdata =
-    { {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
-{0x01, 0x02, 0x03, 0x04, 0x05, 0x07}
-};
+static int max_interrupt_work = 32;
 
 #define nibswap(x) ((((x) >> 4) & 0x0f) | (((x) << 4) & 0xf0))
 
 #define RUN_AT(x) (jiffies + (x))
 
-// For reading/writing 32-bit words from/to DMA memory
+// For reading/writing 32-bit words and half-words from/to DMA memory
+#ifdef DESC_BE
 #define cpu_to_dma32 cpu_to_be32
 #define dma32_to_cpu be32_to_cpu
+#define cpu_to_dma16 cpu_to_be16
+#define dma16_to_cpu be16_to_cpu
+#else
+#define cpu_to_dma32 cpu_to_le32
+#define dma32_to_cpu le32_to_cpu
+#define cpu_to_dma16 cpu_to_le16
+#define dma16_to_cpu le16_to_cpu
+#endif
+
+static char mac0[18] = "00.02.03.04.05.06";
+static char mac1[18] = "00.01.02.03.04.05";
+MODULE_PARM(mac0, "c18");
+MODULE_PARM(mac1, "c18");
+MODULE_PARM_DESC(mac0, "MAC address for GT96100 ethernet port 0");
+MODULE_PARM_DESC(mac1, "MAC address for GT96100 ethernet port 1");
 
 /*
- * Base address and interupt of the GT96100 ethernet controllers
+ * Info for the GT96100 ethernet controller's ports.
  */
-static struct {
-	unsigned int port;
-	int irq;
+static struct gt96100_if_t {
+	struct net_device *dev;
+	unsigned int  iobase;   // IO Base address of this port
+	int           irq;      // IRQ number of this port
+	char         *mac_str;
 } gt96100_iflist[NUM_INTERFACES] = {
 	{
-	GT96100_ETH0_BASE, GT96100_ETHER0_IRQ}, {
-	GT96100_ETH1_BASE, GT96100_ETHER1_IRQ}
+		NULL,
+		GT96100_ETH0_BASE, GT96100_ETHER0_IRQ,
+		mac0
+	},
+	{
+		NULL,
+		GT96100_ETH1_BASE, GT96100_ETHER1_IRQ,
+		mac1
+	}
 };
 
+static inline const char*
+chip_name(int chip_rev)
+{
+	switch (chip_rev) {
+	case REV_GT96100:
+		return "GT96100";
+	case REV_GT96100A_1:
+	case REV_GT96100A:
+		return "GT96100A";
+	default:
+		return "Unknown GT96100";
+	}
+}
+
 /*
   DMA memory allocation, derived from pci_alloc_consistent.
 */
-static void *dmaalloc(size_t size, dma_addr_t * dma_handle)
+static void *
+dmaalloc(size_t size, dma_addr_t *dma_handle)
 {
 	void *ret;
-
-	ret =
-	    (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA,
-				      get_order(size));
-
+	
+	ret = (void *)__get_free_pages(GFP_ATOMIC | GFP_DMA,
+				       get_order(size));
+	
 	if (ret != NULL) {
-		dma_cache_inv((unsigned long) ret, size);
+		dma_cache_inv((unsigned long)ret, size);
 		if (dma_handle != NULL)
 			*dma_handle = virt_to_phys(ret);
 
 		/* bump virtual address up to non-cached area */
-		ret = KSEG1ADDR(ret);
+		ret = (void*)KSEG1ADDR(ret);
 	}
 
 	return ret;
 }
 
-static void dmafree(size_t size, void *vaddr)
+static void
+dmafree(size_t size, void *vaddr)
 {
-	vaddr = KSEG0ADDR(vaddr);
-	free_pages((unsigned long) vaddr, get_order(size));
+	vaddr = (void*)KSEG0ADDR(vaddr);
+	free_pages((unsigned long)vaddr, get_order(size));
 }
 
 
-static int read_MII(struct net_device *dev, u32 reg)
+
+static void
+gt96100_delay(int ms)
+{
+	if (in_interrupt())
+		return;
+	else {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(ms*HZ/1000);
+	}
+}
+
+static int
+parse_mac_addr(struct net_device *dev, char* macstr)
+{
+	int i, j;
+	unsigned char result, value;
+	
+	for (i=0; i<6; i++) {
+		result = 0;
+		if (i != 5 && *(macstr+2) != '.') {
+			err(__FILE__ "invalid mac address format: %d %c\n",
+			    i, *(macstr+2));
+			return -EINVAL;
+		}
+		
+		for (j=0; j<2; j++) {
+			if (isxdigit(*macstr) &&
+			    (value = isdigit(*macstr) ? *macstr-'0' : 
+			     toupper(*macstr)-'A'+10) < 16) {
+				result = result*16 + value;
+				macstr++;
+			} else {
+				err(__FILE__ "invalid mac address "
+				    "character: %c\n", *macstr);
+				return -EINVAL;
+			}
+		}
+
+		macstr++; // step over '.'
+		dev->dev_addr[i] = result;
+	}
+
+	return 0;
+}
+
+
+static int
+read_MII(int phy_addr, u32 reg)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
 	int timedout = 20;
-	u32 smir = smirOpCode | (gp->phy_addr << smirPhyAdBit) |
-	    (reg << smirRegAdBit);
+	u32 smir = smirOpCode | (phy_addr << smirPhyAdBit) |
+		(reg << smirRegAdBit);
 
 	// wait for last operation to complete
 	while (GT96100_READ(GT96100_ETH_SMI_REG) & smirBusy) {
 		// snooze for 1 msec and check again
-#if 0
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(10 * HZ / 10000);
-#else
-		mdelay(1);
-#endif
+		gt96100_delay(1);
 
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: read_MII busy timeout!!\n",
-			       dev->name);
-			return -1;
+			printk(KERN_ERR __FUNCTION__ ": busy timeout!!\n");
+			return -ENODEV;
 		}
 	}
-
+    
 	GT96100_WRITE(GT96100_ETH_SMI_REG, smir);
 
 	timedout = 20;
 	// wait for read to complete
-	while (!(smir = GT96100_READ(GT96100_ETH_SMI_REG) & smirReadValid)) {
+	while (!((smir = GT96100_READ(GT96100_ETH_SMI_REG)) & smirReadValid)) {
 		// snooze for 1 msec and check again
-#if 0
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(10 * HZ / 10000);
-#else
-		mdelay(1);
-#endif
-
+		gt96100_delay(1);
+	
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: read_MII timeout!!\n",
-			       dev->name);
-			return -1;
+			printk(KERN_ERR __FUNCTION__ ": timeout!!\n");
+			return -ENODEV;
 		}
 	}
 
-	return (int) (smir & smirDataMask);
+	return (int)(smir & smirDataMask);
+}
+
+static void
+dump_tx_desc(int dbg_lvl, struct net_device *dev, int i)
+{
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	gt96100_td_t *td = &gp->tx_ring[i];
+
+	dbg(dbg_lvl, "Tx descriptor at 0x%08lx:\n", virt_to_phys(td));
+	dbg(dbg_lvl,
+	    "    cmdstat=%04x, byte_cnt=%04x, buff_ptr=%04x, next=%04x\n",
+	    dma32_to_cpu(td->cmdstat),
+	    dma16_to_cpu(td->byte_cnt),
+	    dma32_to_cpu(td->buff_ptr),
+	    dma32_to_cpu(td->next));
+}
+
+static void
+dump_rx_desc(int dbg_lvl, struct net_device *dev, int i)
+{
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	gt96100_rd_t *rd = &gp->rx_ring[i];
+
+	dbg(dbg_lvl, "Rx descriptor at 0x%08lx:\n", virt_to_phys(rd));
+	dbg(dbg_lvl, "    cmdstat=%04x, buff_sz=%04x, byte_cnt=%04x, "
+	    "buff_ptr=%04x, next=%04x\n",
+	    dma32_to_cpu(rd->cmdstat),
+	    dma16_to_cpu(rd->buff_sz),
+	    dma16_to_cpu(rd->byte_cnt),
+	    dma32_to_cpu(rd->buff_ptr),
+	    dma32_to_cpu(rd->next));
 }
 
-static int write_MII(struct net_device *dev, u32 reg, u16 data)
+static int
+write_MII(int phy_addr, u32 reg, u16 data)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
 	int timedout = 20;
-	u32 smir =
-	    (gp->phy_addr << smirPhyAdBit) | (reg << smirRegAdBit) | data;
+	u32 smir = (phy_addr << smirPhyAdBit) |
+		(reg << smirRegAdBit) | data;
 
 	// wait for last operation to complete
 	while (GT96100_READ(GT96100_ETH_SMI_REG) & smirBusy) {
 		// snooze for 1 msec and check again
-#if 0
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(10 * HZ / 10000);
-#else
-		mdelay(1);
-#endif
-
+		gt96100_delay(1);
+	
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: write_MII busy timeout!!\n",
-			       dev->name);
+			printk(KERN_ERR __FUNCTION__ ": busy timeout!!\n");
 			return -1;
 		}
 	}
@@ -217,109 +331,203 @@
 	return 0;
 }
 
+#if 0
+// These routines work, just disabled to avoid compile warnings
+static void
+dump_tx_ring(struct net_device *dev)
+{
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	int i;
+
+	dbg(0, __FUNCTION__ ": txno/txni/cnt=%d/%d/%d\n",
+	    gp->tx_next_out, gp->tx_next_in, gp->tx_count);
 
-static void dump_MII(struct net_device *dev)
+	for (i=0; i<TX_RING_SIZE; i++)
+		dump_tx_desc(0, dev, i);
+}
+
+static void
+dump_rx_ring(struct net_device *dev)
+{
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	int i;
+
+	dbg(0, __FUNCTION__ ": rxno=%d\n", gp->rx_next_out);
+
+	for (i=0; i<RX_RING_SIZE; i++)
+		dump_rx_desc(0, dev, i);
+}
+#endif
+
+static void
+dump_MII(int dbg_lvl, struct net_device *dev)
 {
 	int i, val;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+    
+	if (dbg_lvl <= GT96100_DEBUG) {
+		for (i=0; i<7; i++) {
+			if ((val = read_MII(gp->phy_addr, i)) >= 0)
+				printk("MII Reg %d=%x\n", i, val);
+		}
+		for (i=16; i<21; i++) {
+			if ((val = read_MII(gp->phy_addr, i)) >= 0)
+				printk("MII Reg %d=%x\n", i, val);
+		}
+	}
+}
 
-	for (i = 0; i < 7; i++) {
-		if ((val = read_MII(dev, i)) >= 0)
-			printk("%s: MII Reg %d=%x\n", dev->name, i, val);
-	}
-	for (i = 16; i < 21; i++) {
-		if ((val = read_MII(dev, i)) >= 0)
-			printk("%s: MII Reg %d=%x\n", dev->name, i, val);
+static void
+dump_hw_addr(int dbg_lvl, struct net_device *dev, const char* pfx,
+	     unsigned char* addr_str)
+{
+	int i;
+	char buf[100], octet[5];
+    
+	if (dbg_lvl <= GT96100_DEBUG) {
+		strcpy(buf, pfx);
+		for (i = 0; i < 6; i++) {
+			sprintf(octet, "%2.2x%s",
+				addr_str[i], i<5 ? ":" : "\n");
+			strcat(buf, octet);
+		}
+		info("%s", buf);
+	}
+}
+
+
+static void
+dump_skb(int dbg_lvl, struct net_device *dev, struct sk_buff *skb)
+{
+	int i;
+	unsigned char* skbdata;
+    
+	if (dbg_lvl <= GT96100_DEBUG) {
+		dbg(dbg_lvl, __FUNCTION__
+		    ": skb=%p, skb->data=%p, skb->len=%d\n",
+		    skb, skb->data, skb->len);
+
+		skbdata = (unsigned char*)KSEG1ADDR(skb->data);
+    
+		for (i=0; i<skb->len; i++) {
+			if (!(i % 16))
+				printk(KERN_DEBUG "\n   %3.3x: %2.2x,",
+				       i, skbdata[i]);
+			else
+				printk(KERN_DEBUG "%2.2x,", skbdata[i]);
+		}
+		printk(KERN_DEBUG "\n");
 	}
 }
 
 
 static int
-gt96100_add_hash_entry(struct net_device *dev, unsigned char *addr)
+gt96100_add_hash_entry(struct net_device *dev, unsigned char* addr)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
-	u16 hashResult, stmp;
-	unsigned char ctmp, hash_ea[6];
-	u32 tblEntry, *tblEntryAddr;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	//u16 hashResult, stmp;
+	//unsigned char ctmp, hash_ea[6];
+	u32 tblEntry1, tblEntry0, *tblEntryAddr;
 	int i;
 
-	for (i = 0; i < 6; i++) {
+	tblEntry1 = hteValid | hteRD;
+	tblEntry1 |= (u32)addr[5] << 3;
+	tblEntry1 |= (u32)addr[4] << 11;
+	tblEntry1 |= (u32)addr[3] << 19;
+	tblEntry1 |= ((u32)addr[2] & 0x1f) << 27;
+	dbg(3, __FUNCTION__ ": tblEntry1=%x\n", tblEntry1);
+	tblEntry0 = ((u32)addr[2] >> 5) & 0x07;
+	tblEntry0 |= (u32)addr[1] << 3;
+	tblEntry0 |= (u32)addr[0] << 11;
+	dbg(3, __FUNCTION__ ": tblEntry0=%x\n", tblEntry0);
+
+#if 0
+
+	for (i=0; i<6; i++) {
 		// nibble swap
 		ctmp = nibswap(addr[i]);
 		// invert every nibble
-		hash_ea[i] = ((ctmp & 1) << 3) | ((ctmp & 8) >> 3) |
-		    ((ctmp & 2) << 1) | ((ctmp & 4) >> 1);
-		hash_ea[i] |= ((ctmp & 0x10) << 3) | ((ctmp & 0x80) >> 3) |
-		    ((ctmp & 0x20) << 1) | ((ctmp & 0x40) >> 1);
+		hash_ea[i] = ((ctmp&1)<<3) | ((ctmp&8)>>3) |
+			((ctmp&2)<<1) | ((ctmp&4)>>1);
+		hash_ea[i] |= ((ctmp&0x10)<<3) | ((ctmp&0x80)>>3) |
+			((ctmp&0x20)<<1) | ((ctmp&0x40)>>1);
 	}
 
+	dump_hw_addr(3, dev, __FUNCTION__ ": nib swap/invt addr=", hash_ea);
+    
 	if (gp->hash_mode == 0) {
-		hashResult = ((u16) hash_ea[0] & 0xfc) << 7;
-		stmp =
-		    ((u16) hash_ea[0] & 0x03) | (((u16) hash_ea[1] & 0x7f)
-						 << 2);
-		stmp ^=
-		    (((u16) hash_ea[1] >> 7) & 0x01) | ((u16) hash_ea[2] <<
-							1);
-		stmp ^= (u16) hash_ea[3] | (((u16) hash_ea[4] & 1) << 8);
+		hashResult = ((u16)hash_ea[0] & 0xfc) << 7;
+		stmp = ((u16)hash_ea[0] & 0x03) |
+			(((u16)hash_ea[1] & 0x7f) << 2);
+		stmp ^= (((u16)hash_ea[1] >> 7) & 0x01) |
+			((u16)hash_ea[2] << 1);
+		stmp ^= (u16)hash_ea[3] | (((u16)hash_ea[4] & 1) << 8);
 		hashResult |= stmp;
 	} else {
-		return -1;	// don't support hash mode 1
+		return -1; // don't support hash mode 1
 	}
 
-	tblEntryAddr =
-	    (u32 *) (&gp->hash_table[((u32) hashResult & 0x7ff) << 3]);
+	dbg(3, __FUNCTION__ ": hashResult=%x\n", hashResult);
 
-	for (i = 0; i < HASH_HOP_NUMBER; i++) {
-		if ((*tblEntryAddr & hteValid)
-		    && !(*tblEntryAddr & hteSkip)) {
+	tblEntryAddr =
+		(u32 *)(&gp->hash_table[((u32)hashResult & 0x7ff) << 3]);
+    
+	dbg(3, __FUNCTION__ ": tblEntryAddr=%p\n", tblEntryAddr);
+
+	for (i=0; i<HASH_HOP_NUMBER; i++) {
+		if ((*tblEntryAddr & hteValid) &&
+		    !(*tblEntryAddr & hteSkip)) {
 			// This entry is already occupied, go to next entry
 			tblEntryAddr += 2;
+			dbg(3, __FUNCTION__ ": skipping to %p\n",
+			    tblEntryAddr);
 		} else {
 			memset(tblEntryAddr, 0, 8);
-			tblEntry = hteValid | hteRD;
-			tblEntry |= (u32) addr[5] << 3;
-			tblEntry |= (u32) addr[4] << 11;
-			tblEntry |= (u32) addr[3] << 19;
-			tblEntry |= ((u32) addr[2] & 0x1f) << 27;
-			*(tblEntryAddr + 1) = cpu_to_dma32(tblEntry);
-			tblEntry = ((u32) addr[2] >> 5) & 0x07;
-			tblEntry |= (u32) addr[1] << 3;
-			tblEntry |= (u32) addr[0] << 11;
-			*tblEntryAddr = cpu_to_dma32(tblEntry);
+			tblEntryAddr[1] = cpu_to_dma32(tblEntry1);
+			tblEntryAddr[0] = cpu_to_dma32(tblEntry0);
 			break;
 		}
 	}
 
 	if (i >= HASH_HOP_NUMBER) {
-		printk(KERN_ERR "%s: gt96100_add_hash_entry expired!\n",
-		       dev->name);
-		return -1;	// Couldn't find an unused entry
+		err(__FUNCTION__ ": expired!\n");
+		return -1; // Couldn't find an unused entry
+	}
+
+#else
+
+	tblEntryAddr = (u32 *)gp->hash_table;
+	for (i=0; i<RX_HASH_TABLE_SIZE/4; i+=2) {
+		tblEntryAddr[i+1] = cpu_to_dma32(tblEntry1);
+		tblEntryAddr[i] = cpu_to_dma32(tblEntry0);
 	}
 
+#endif
+    
 	return 0;
 }
 
 
-static void read_mib_counters(struct gt96100_private *gp)
+static void
+read_mib_counters(struct gt96100_private *gp)
 {
-	u32 *mib_regs = (u32 *) & gp->mib;
+	u32* mib_regs = (u32*)&gp->mib;
 	int i;
-
-	for (i = 0; i < sizeof(mib_counters_t) / sizeof(u32); i++)
-		mib_regs[i] =
-		    GT96100ETH_READ(gp,
-				    GT96100_ETH_MIB_COUNT_BASE +
-				    i * sizeof(u32));
+    
+	for (i=0; i<sizeof(mib_counters_t)/sizeof(u32); i++)
+		mib_regs[i] = GT96100ETH_READ(gp, GT96100_ETH_MIB_COUNT_BASE +
+					      i*sizeof(u32));
 }
 
 
-static void update_stats(struct gt96100_private *gp)
+static void
+update_stats(struct gt96100_private *gp)
 {
 	mib_counters_t *mib = &gp->mib;
 	struct net_device_stats *stats = &gp->stats;
-
+    
 	read_mib_counters(gp);
-
+    
 	stats->rx_packets = mib->totalFramesReceived;
 	stats->tx_packets = mib->framesSent;
 	stats->rx_bytes = mib->totalByteReceived;
@@ -329,8 +537,7 @@
 	//rx_dropped incremented by gt96100_rx
 	//tx_dropped incremented by gt96100_tx
 	stats->multicast = mib->multicastFramesReceived;
-	// Tx collisions incremented by ISR, so add in MIB Rx collisions
-	stats->collisions += mib->collision + mib->lateCollision;
+	// collisions incremented by gt96100_tx_complete
 	stats->rx_length_errors = mib->oversizeFrames + mib->fragments;
 	// The RxError condition means the Rx DMA encountered a
 	// CPU owned descriptor, which, if things are working as
@@ -339,13 +546,13 @@
 	stats->rx_crc_errors = mib->cRCError;
 }
 
-static void abort(struct net_device *dev, u32 abort_bits)
+static void
+abort(struct net_device *dev, u32 abort_bits)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
-	int timedout = 100;	// wait up to 100 msec for hard stop to complete
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	int timedout = 100; // wait up to 100 msec for hard stop to complete
 
-	if (gt96100_debug > 2)
-		printk(KERN_INFO "%s: abort\n", dev->name);
+	dbg(3, __FUNCTION__ "\n");
 
 	// Return if neither Rx or Tx abort bits are set
 	if (!(abort_bits & (sdcmrAR | sdcmrAT)))
@@ -353,48 +560,36 @@
 
 	// make sure only the Rx/Tx abort bits are set
 	abort_bits &= (sdcmrAR | sdcmrAT);
-
+    
 	spin_lock(&gp->lock);
 
 	// abort any Rx/Tx DMA immediately
 	GT96100ETH_WRITE(gp, GT96100_ETH_SDMA_COMM, abort_bits);
 
-	if (gt96100_debug > 2)
-		printk(KERN_INFO "%s: abort: SDMA comm = %x\n",
-		       dev->name, GT96100ETH_READ(gp,
-						  GT96100_ETH_SDMA_COMM));
+	dbg(3, __FUNCTION__ ": SDMA comm = %x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_SDMA_COMM));
 
 	// wait for abort to complete
 	while (GT96100ETH_READ(gp, GT96100_ETH_SDMA_COMM) & abort_bits) {
 		// snooze for 20 msec and check again
-#if 0
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(10 * HZ / 10000);
-#else
-		mdelay(1);
-#endif
-
+		gt96100_delay(1);
+	
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: abort timeout!!\n",
-			       dev->name);
+			err(__FUNCTION__ ": timeout!!\n");
 			break;
 		}
 	}
 
-	if (gt96100_debug > 2)
-		printk(KERN_INFO "%s: abort: timedout=%d\n", dev->name,
-		       timedout);
-
 	spin_unlock(&gp->lock);
 }
 
 
-static void hard_stop(struct net_device *dev)
+static void
+hard_stop(struct net_device *dev)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
 
-	if (gt96100_debug > 2)
-		printk(KERN_INFO "%s: hard stop\n", dev->name);
+	dbg(3, __FUNCTION__ "\n");
 
 	disable_ether_irq(dev);
 
@@ -405,207 +600,236 @@
 }
 
 
-static void enable_ether_irq(struct net_device *dev)
+static void
+enable_ether_irq(struct net_device *dev)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
 	u32 intMask;
-
+	/*
+	 * route ethernet interrupt to GT_SERINT0 for port 0,
+	 * GT_INT0 for port 1.
+	 */
+	int intr_mask_reg = (gp->port_num == 0) ?
+		GT96100_SERINT0_MASK : GT96100_INT0_HIGH_MASK;
+	
+	if (gp->chip_rev >= REV_GT96100A_1) {
+		intMask = icrTxBufferLow | icrTxEndLow |
+			icrTxErrorLow  | icrRxOVR | icrTxUdr |
+			icrRxBufferQ0 | icrRxErrorQ0 |
+			icrMIIPhySTC | icrEtherIntSum;
+	}
+	else {
+		intMask = icrTxBufferLow | icrTxEndLow |
+			icrTxErrorLow  | icrRxOVR | icrTxUdr |
+			icrRxBuffer | icrRxError |
+			icrMIIPhySTC | icrEtherIntSum;
+	}
+	
 	// unmask interrupts
-	GT96100ETH_WRITE(gp, GT96100_ETH_INT_MASK,
-			 icrRxBuffer | icrTxBufferLow | icrTxEndLow |
-			 icrRxError | icrTxErrorLow | icrRxOVR |
-			 icrTxUdr | icrRxBufferQ0 | icrRxErrorQ0 |
-			 icrMIIPhySTC);
-
-	// now route ethernet interrupts to GT Int0 (eth0 and eth1 will be
-	// sharing it).
-	// FIX! The kernel's irq code should do this
-	intMask = GT96100_READ(GT96100_INT0_HIGH_MASK);
-	intMask |= 1 << gp->port_num;
-	GT96100_WRITE(GT96100_INT0_HIGH_MASK, intMask);
+	GT96100ETH_WRITE(gp, GT96100_ETH_INT_MASK, intMask);
+    
+	intMask = GT96100_READ(intr_mask_reg);
+	intMask |= 1<<gp->port_num;
+	GT96100_WRITE(intr_mask_reg, intMask);
 }
 
-static void disable_ether_irq(struct net_device *dev)
+static void
+disable_ether_irq(struct net_device *dev)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
 	u32 intMask;
+	int intr_mask_reg = (gp->port_num == 0) ?
+		GT96100_SERINT0_MASK : GT96100_INT0_HIGH_MASK;
 
-	// FIX! The kernel's irq code should do this
-	intMask = GT96100_READ(GT96100_INT0_HIGH_MASK);
-	intMask &= ~(1 << gp->port_num);
-	GT96100_WRITE(GT96100_INT0_HIGH_MASK, intMask);
-
+	intMask = GT96100_READ(intr_mask_reg);
+	intMask &= ~(1<<gp->port_num);
+	GT96100_WRITE(intr_mask_reg, intMask);
+    
 	GT96100ETH_WRITE(gp, GT96100_ETH_INT_MASK, 0);
 }
 
 
 /*
- * Probe for a GT96100 ethernet controller.
+ * Init GT96100 ethernet controller driver
  */
-int __init gt96100_probe(struct net_device *dev)
+int gt96100_init_module(void)
 {
-	unsigned int base_addr = dev ? dev->base_addr : 0;
-	int i;
+	int i, retval=0;
+	u16 vendor_id, device_id;
+	u32 cpuConfig;
 
 #ifndef CONFIG_MIPS_GT96100ETH
 	return -ENODEV;
 #endif
 
-	if (gt96100_debug > 2)
-		printk(KERN_INFO "%s: gt96100_probe\n", dev->name);
+	// probe for GT96100 by reading PCI0 vendor/device ID register
+	pcibios_read_config_word(0, 0, PCI_VENDOR_ID, &vendor_id);
+	pcibios_read_config_word(0, 0, PCI_DEVICE_ID, &device_id);
+    
+	if (vendor_id != PCI_VENDOR_ID_GALILEO ||
+	    (device_id != PCI_DEVICE_ID_GALILEO_GT96100 &&
+	     device_id != PCI_DEVICE_ID_GALILEO_GT96100A)) {
+		printk(KERN_ERR __FILE__ ": GT96100 not found!\n");
+		return -ENODEV;
+	}
 
-	if (base_addr >= KSEG0)	/* Check a single specified location. */
-		return gt96100_probe1(dev, base_addr, dev->irq, 0);
-	else if (base_addr != 0)	/* Don't probe at all. */
-		return -ENXIO;
-
-//	for (i = 0; i<NUM_INTERFACES; i++) {
-	for (i = NUM_INTERFACES - 1; i >= 0; i--) {
-		int base_addr = gt96100_iflist[i].port;
-#if 0
-		if (check_region(base_addr, GT96100_ETH_IO_SIZE)) {
-			printk(KERN_ERR
-			       "%s: gt96100_probe: ioaddr 0x%lx taken?\n",
-			       dev->name, base_addr);
-			continue;
-		}
-#endif
-		if (gt96100_probe1
-		    (dev, base_addr, gt96100_iflist[i].irq, i) == 0)
-			return 0;
+	cpuConfig = GT96100_READ(GT96100_CPU_INTERF_CONFIG);
+	if (cpuConfig & (1<<12)) {
+		printk(KERN_ERR __FILE__
+		       ": must be in Big Endian mode!\n");
+		return -ENODEV;
 	}
-	return -ENODEV;
+
+	for (i=0; i < NUM_INTERFACES; i++) {
+		retval |= gt96100_probe1(i);
+	}
+
+	return retval;
 }
 
 
 
 static int __init
-gt96100_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
+gt96100_probe1(int port_num)
 {
-	static unsigned version_printed = 0;
 	struct gt96100_private *gp = NULL;
-	int i, retval;
-	u32 cpuConfig;
-
-	// FIX! probe for GT96100 by reading a suitable register
-
-	if (gt96100_debug > 2)
-		printk(KERN_INFO "gt96100_probe1: ioaddr 0x%lx, irq %d\n",
-		       ioaddr, irq);
-
-	request_region(ioaddr, GT96100_ETH_IO_SIZE, "GT96100ETH");
-
-	cpuConfig = GT96100_READ(GT96100_CPU_INTERF_CONFIG);
-	if (cpuConfig & (1 << 12)) {
-		printk(KERN_ERR
-		       "gt96100_probe1: must be in Big Endian mode!\n");
-		retval = -ENODEV;
-		goto free_region;
-	}
-
-	if (gt96100_debug > 2)
-		printk(KERN_INFO
-		       "gt96100_probe1: chip in Big Endian mode - cool\n");
-
-	/* Allocate a new 'dev' if needed. */
-	if (dev == NULL)
-		dev = init_etherdev(0, sizeof(struct gt96100_private));
-
-	if (gt96100_debug && version_printed++ == 0)
-		printk(version);
-
-	if (irq < 0) {
-		printk(KERN_ERR
-		       "gt96100_probe1: irq unknown - probing not supported\n");
-		retval = -ENODEV;
-		goto free_region;
-	}
-
-	printk(KERN_INFO "%s: GT-96100 ethernet found at 0x%lx, irq %d\n",
-	       dev->name, ioaddr, irq);
-
+	struct gt96100_if_t *gtif = &gt96100_iflist[port_num];
+	int phy_addr, phy_id1, phy_id2;
+	u32 phyAD;
+	int retval;
+	unsigned char chip_rev;
+	struct net_device *dev = NULL;
+    
+	if (gtif->irq < 0) {
+		printk(KERN_ERR __FUNCTION__
+		       ": irq unknown - probing not supported\n");
+		return -ENODEV;
+	}
+    
+	pcibios_read_config_byte(0, 0, PCI_REVISION_ID, &chip_rev);
+
+	if (chip_rev >= REV_GT96100A_1) {
+		phyAD = GT96100_READ(GT96100_ETH_PHY_ADDR_REG);
+		phy_addr = (phyAD >> (5*port_num)) & 0x1f;
+	} else {
+		/*
+		 * not sure what's this about -- probably 
+		 * a gt bug
+		 */
+		phy_addr = port_num;
+		phyAD = GT96100_READ(GT96100_ETH_PHY_ADDR_REG);
+		phyAD &= ~(0x1f << (port_num*5));
+		phyAD |= phy_addr << (port_num*5);
+		GT96100_WRITE(GT96100_ETH_PHY_ADDR_REG, phyAD);
+	}
+	
+	// probe for the external PHY
+	if ((phy_id1 = read_MII(phy_addr, 2)) <= 0 ||
+	    (phy_id2 = read_MII(phy_addr, 3)) <= 0) {
+		printk(KERN_ERR __FUNCTION__
+		       ": no PHY found on MII%d\n", port_num);
+		return -ENODEV;
+	}
+	
+	if (!request_region(gtif->iobase, GT96100_ETH_IO_SIZE, "GT96100ETH")) {
+		printk(KERN_ERR __FUNCTION__ ": request_region failed\n");
+		return -EBUSY;
+	}
+
+	dev = init_etherdev(0, sizeof(struct gt96100_private));
+	gtif->dev = dev;
+	
 	/* private struct aligned and zeroed by init_etherdev */
 	/* Fill in the 'dev' fields. */
-	dev->base_addr = ioaddr;
-	dev->irq = irq;
-	memcpy(dev->dev_addr, gt96100_station_addr[port_num],
-	       sizeof(dev->dev_addr));
-
-	printk(KERN_INFO "%s: HW Address ", dev->name);
-	for (i = 0; i < sizeof(dev->dev_addr); i++) {
-		printk("%2.2x", dev->dev_addr[i]);
-		printk(i < 5 ? ":" : "\n");
+	dev->base_addr = gtif->iobase;
+	dev->irq = gtif->irq;
+
+	if ((retval = parse_mac_addr(dev, gtif->mac_str))) {
+		err(__FUNCTION__ ": MAC address parse failed\n");
+		retval = -EINVAL;
+		goto free_region;
 	}
 
 	/* Initialize our private structure. */
 	if (dev->priv == NULL) {
 
-		gp =
-		    (struct gt96100_private *) kmalloc(sizeof(*gp),
+		gp = (struct gt96100_private *)kmalloc(sizeof(*gp),
 						       GFP_KERNEL);
 		if (gp == NULL) {
 			retval = -ENOMEM;
 			goto free_region;
 		}
-
+	
 		dev->priv = gp;
 	}
 
 	gp = dev->priv;
 
-	memset(gp, 0, sizeof(*gp));	// clear it
+	memset(gp, 0, sizeof(*gp)); // clear it
 
 	gp->port_num = port_num;
 	gp->io_size = GT96100_ETH_IO_SIZE;
 	gp->port_offset = port_num * GT96100_ETH_IO_SIZE;
-	gp->phy_addr = port_num + 1;
+	gp->phy_addr = phy_addr;
+	gp->chip_rev = chip_rev;
 
-	if (gt96100_debug > 2)
-		printk(KERN_INFO "%s: gt96100_probe1, port %d\n",
-		       dev->name, gp->port_num);
+	info("%s found at 0x%x, irq %d\n",
+	     chip_name(gp->chip_rev), gtif->iobase, gtif->irq);
+	dump_hw_addr(0, dev, "HW Address ", dev->dev_addr);
+	info("%s chip revision=%d\n", chip_name(gp->chip_rev), gp->chip_rev);
+	info("%s ethernet port %d\n", chip_name(gp->chip_rev), gp->port_num);
+	info("external PHY ID1=0x%04x, ID2=0x%04x\n", phy_id1, phy_id2);
 
 	// Allocate Rx and Tx descriptor rings
 	if (gp->rx_ring == NULL) {
 		// All descriptors in ring must be 16-byte aligned
 		gp->rx_ring = dmaalloc(sizeof(gt96100_rd_t) * RX_RING_SIZE
-				       +
-				       sizeof(gt96100_td_t) * TX_RING_SIZE,
+				       + sizeof(gt96100_td_t) * TX_RING_SIZE,
 				       &gp->rx_ring_dma);
 		if (gp->rx_ring == NULL) {
 			retval = -ENOMEM;
 			goto free_region;
 		}
-
-		gp->tx_ring =
-		    (gt96100_td_t *) (gp->rx_ring + RX_RING_SIZE);
+	
+		gp->tx_ring = (gt96100_td_t *)(gp->rx_ring + RX_RING_SIZE);
 		gp->tx_ring_dma =
-		    gp->rx_ring_dma + sizeof(gt96100_rd_t) * RX_RING_SIZE;
+			gp->rx_ring_dma + sizeof(gt96100_rd_t) * RX_RING_SIZE;
 	}
-
-	if (gt96100_debug > 2)
-		printk(KERN_INFO
-		       "%s: gt96100_probe1, rx_ring=%p, tx_ring=%p\n",
-		       dev->name, gp->rx_ring, gp->tx_ring);
+    
+	// Allocate the Rx Data Buffers
+	if (gp->rx_buff == NULL) {
+		gp->rx_buff = dmaalloc(PKT_BUF_SZ*RX_RING_SIZE,
+				       &gp->rx_buff_dma);
+		if (gp->rx_buff == NULL) {
+			dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
+				+ sizeof(gt96100_td_t) * TX_RING_SIZE,
+				gp->rx_ring);
+			retval = -ENOMEM;
+			goto free_region;
+		}
+	}
+    
+	dbg(3, __FUNCTION__ ": rx_ring=%p, tx_ring=%p\n",
+	    gp->rx_ring, gp->tx_ring);
 
 	// Allocate Rx Hash Table
 	if (gp->hash_table == NULL) {
-		gp->hash_table = (char *) dmaalloc(RX_HASH_TABLE_SIZE,
-						   &gp->hash_table_dma);
+		gp->hash_table = (char*)dmaalloc(RX_HASH_TABLE_SIZE,
+						 &gp->hash_table_dma);
 		if (gp->hash_table == NULL) {
 			dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
 				+ sizeof(gt96100_td_t) * TX_RING_SIZE,
 				gp->rx_ring);
+			dmafree(PKT_BUF_SZ*RX_RING_SIZE, gp->rx_buff);
 			retval = -ENOMEM;
 			goto free_region;
 		}
 	}
-
-	if (gt96100_debug > 2)
-		printk(KERN_INFO "%s: gt96100_probe1, hash=%p\n",
-		       dev->name, gp->hash_table);
+    
+	dbg(3, __FUNCTION__ ": hash=%p\n", gp->hash_table);
 
 	spin_lock_init(&gp->lock);
-
+    
 	dev->open = gt96100_open;
 	dev->hard_start_xmit = gt96100_tx;
 	dev->stop = gt96100_close;
@@ -619,317 +843,358 @@
 	ether_setup(dev);
 	return 0;
 
-      free_region:
-	release_region(ioaddr, gp->io_size);
+ free_region:
+	release_region(gtif->iobase, GT96100_ETH_IO_SIZE);
 	unregister_netdev(dev);
 	if (dev->priv != NULL)
-		kfree(dev->priv);
-	kfree(dev);
-	printk(KERN_ERR "%s: gt96100_probe1 failed.  Returns %d\n",
-	       dev->name, retval);
+		kfree (dev->priv);
+	kfree (dev);
+	err(__FUNCTION__ " failed.  Returns %d\n", retval);
 	return retval;
 }
 
 
-static int gt96100_init(struct net_device *dev)
+static void
+reset_tx(struct net_device *dev)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
-	unsigned long flags;
-	u32 phyAD, ciu;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
 	int i;
 
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: dev=%p\n", dev->name, dev);
-
-	// Stop and disable Port
-	hard_stop(dev);
+	abort(dev, sdcmrAT);
 
-	spin_lock_irqsave(&gp->lock, flags);
+	for (i=0; i<TX_RING_SIZE; i++) {
+		if (gp->tx_skbuff[i]) {
+			if (in_interrupt())
+				dev_kfree_skb_irq(gp->tx_skbuff[i]);
+			else
+				dev_kfree_skb(gp->tx_skbuff[i]);
+			gp->tx_skbuff[i] = NULL;
+		}
 
-	// First things first, set-up hash table
-	memset(gp->hash_table, 0, RX_HASH_TABLE_SIZE);	// clear it
-	gp->hash_mode = 0;
-	// Add a single entry to hash table - our ethernet address
-	gt96100_add_hash_entry(dev, dev->dev_addr);
-	// Set-up DMA ptr to hash table
-	GT96100ETH_WRITE(gp, GT96100_ETH_HASH_TBL_PTR, gp->hash_table_dma);
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: Hash Tbl Ptr=%x\n", dev->name,
-		       GT96100ETH_READ(gp, GT96100_ETH_HASH_TBL_PTR));
-
-	// Setup Tx descriptor ring
-	for (i = 0; i < TX_RING_SIZE; i++) {
-		gp->tx_ring[i].cmdstat = 0;	// CPU owns
+		gp->tx_ring[i].cmdstat = 0; // CPU owns
 		gp->tx_ring[i].byte_cnt = 0;
 		gp->tx_ring[i].buff_ptr = 0;
 		gp->tx_ring[i].next =
-		    cpu_to_dma32(gp->tx_ring_dma +
-				 sizeof(gt96100_td_t) * (i + 1));
+			cpu_to_dma32(gp->tx_ring_dma +
+				     sizeof(gt96100_td_t) * (i+1));
+		dump_tx_desc(4, dev, i);
 	}
 	/* Wrap the ring. */
-	gp->tx_ring[i - 1].next = cpu_to_dma32(gp->tx_ring_dma);
-
+	gp->tx_ring[i-1].next = cpu_to_dma32(gp->tx_ring_dma);
+    
 	// setup only the lowest priority TxCDP reg
-	GT96100ETH_WRITE(gp, GT96100_ETH_CURR_TX_DESC_PTR0,
-			 gp->tx_ring_dma);
+	GT96100ETH_WRITE(gp, GT96100_ETH_CURR_TX_DESC_PTR0, gp->tx_ring_dma);
 	GT96100ETH_WRITE(gp, GT96100_ETH_CURR_TX_DESC_PTR1, 0);
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: Curr Tx Desc Ptr0=%x\n",
-		       dev->name, GT96100ETH_READ(gp,
-						  GT96100_ETH_CURR_TX_DESC_PTR0));
-
-	// Setup Rx descriptor ring 
-	for (i = 0; i < RX_RING_SIZE; i++) {
-		dma_addr_t rx_buff_dma;
+
+	// init Tx indeces and pkt counter
+	gp->tx_next_in = gp->tx_next_out = 0;
+	gp->tx_count = 0;
+
+}
+
+static void
+reset_rx(struct net_device *dev)
+{
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	int i;
+
+	abort(dev, sdcmrAR);
+    
+	for (i=0; i<RX_RING_SIZE; i++) {
 		gp->rx_ring[i].next =
-		    cpu_to_dma32(gp->rx_ring_dma +
-				 sizeof(gt96100_rd_t) * (i + 1));
-		if (gp->rx_buff[i] == NULL)
-			gp->rx_buff[i] =
-			    dmaalloc(PKT_BUF_SZ, &rx_buff_dma);
-		else
-			rx_buff_dma = virt_to_phys(gp->rx_buff[i]);
-		if (gp->rx_buff[i] == NULL)
-			break;
-		gp->rx_ring[i].buff_ptr = cpu_to_dma32(rx_buff_dma);
-		gp->rx_ring[i].buff_cnt_sz =
-		    cpu_to_dma32(PKT_BUF_SZ << rdBuffSzBit);
-		// Give ownership to device, enable interrupt
+			cpu_to_dma32(gp->rx_ring_dma +
+				     sizeof(gt96100_rd_t) * (i+1));
+		gp->rx_ring[i].buff_ptr =
+			cpu_to_dma32(gp->rx_buff_dma + i*PKT_BUF_SZ);
+		gp->rx_ring[i].buff_sz = cpu_to_dma16(PKT_BUF_SZ);
+		// Give ownership to device, set first and last, enable intr
 		gp->rx_ring[i].cmdstat =
-		    cpu_to_dma32((u32) (rxOwn | rxEI));
+			cpu_to_dma32((u32)(rxFirst | rxLast | rxOwn | rxEI));
+		dump_rx_desc(4, dev, i);
 	}
+	/* Wrap the ring. */
+	gp->rx_ring[i-1].next = cpu_to_dma32(gp->rx_ring_dma);
 
-	if (i != RX_RING_SIZE) {
-		int j;
-		for (j = 0; j < RX_RING_SIZE; j++) {
-			if (gp->rx_buff[j]) {
-				dmafree(PKT_BUF_SZ, gp->rx_buff[j]);
-				gp->rx_buff[j] = NULL;
-			}
+	// Setup only the lowest priority RxFDP and RxCDP regs
+	for (i=0; i<4; i++) {
+		if (i == 0) {
+			GT96100ETH_WRITE(gp, GT96100_ETH_1ST_RX_DESC_PTR0,
+					 gp->rx_ring_dma);
+			GT96100ETH_WRITE(gp, GT96100_ETH_CURR_RX_DESC_PTR0,
+					 gp->rx_ring_dma);
+		} else {
+			GT96100ETH_WRITE(gp,
+					 GT96100_ETH_1ST_RX_DESC_PTR0 + i*4,
+					 0);
+			GT96100ETH_WRITE(gp,
+					 GT96100_ETH_CURR_RX_DESC_PTR0 + i*4,
+					 0);
 		}
-		printk(KERN_ERR "%s: Rx ring allocation failed.\n",
-		       dev->name);
-		spin_unlock_irqrestore(&gp->lock, flags);
-		return -ENOMEM;
 	}
 
-	/* Wrap the ring. */
-	gp->rx_ring[i - 1].next = cpu_to_dma32(gp->rx_ring_dma);
+	// init Rx NextOut index
+	gp->rx_next_out = 0;
+}
 
-	// Set our MII PHY device address
-	phyAD = GT96100_READ(GT96100_ETH_PHY_ADDR_REG);
-	phyAD &= ~(0x1f << (gp->port_num * 5));
-	phyAD |= gp->phy_addr << (gp->port_num * 5);
-	GT96100_WRITE(GT96100_ETH_PHY_ADDR_REG, phyAD);
-
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: PhyAD=%x\n", dev->name,
-		       GT96100_READ(GT96100_ETH_PHY_ADDR_REG));
-
-	// Clear all the RxFDP and RXCDP regs...
-	for (i = 0; i < 4; i++) {
-		GT96100ETH_WRITE(gp, GT96100_ETH_1ST_RX_DESC_PTR0 + i * 4,
-				 0);
-		GT96100ETH_WRITE(gp, GT96100_ETH_CURR_RX_DESC_PTR0 + i * 4,
-				 0);
-	}
-	// and setup only the lowest priority RxFDP and RxCDP regs
-	GT96100ETH_WRITE(gp, GT96100_ETH_1ST_RX_DESC_PTR0,
-			 gp->rx_ring_dma);
-	GT96100ETH_WRITE(gp, GT96100_ETH_CURR_RX_DESC_PTR0,
-			 gp->rx_ring_dma);
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: 1st/Curr Rx Desc Ptr0=%x/%x\n",
-		       dev->name, GT96100ETH_READ(gp,
-						  GT96100_ETH_1ST_RX_DESC_PTR0),
-		       GT96100ETH_READ(gp, GT96100_ETH_CURR_RX_DESC_PTR0));
 
-	// init Rx/Tx indeces and pkt counters
-	gp->rx_next_out = gp->tx_next_in = gp->tx_next_out = 0;
-	gp->tx_count = 0;
+// Returns 1 if the Tx counter and indeces don't gel
+static int
+gt96100_check_tx_consistent(struct gt96100_private *gp)
+{
+	int diff = gp->tx_next_in - gp->tx_next_out;
 
-	// setup DMA
+	diff = diff<0 ? TX_RING_SIZE + diff : diff;
+	diff = gp->tx_count == TX_RING_SIZE ? diff + TX_RING_SIZE : diff;
+    
+	return (diff != gp->tx_count);
+}
+
+static int
+gt96100_init(struct net_device *dev)
+{
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	u32 tmp;
+	u16 mii_reg;
+    
+	dbg(3, __FUNCTION__ ": dev=%p\n", dev);
+	dbg(3, __FUNCTION__ ": scs10_lo=%4x, scs10_hi=%4x\n",
+	    GT96100_READ(0x8), GT96100_READ(0x10));
+	dbg(3, __FUNCTION__ ": scs32_lo=%4x, scs32_hi=%4x\n",
+	    GT96100_READ(0x18), GT96100_READ(0x20));
+    
+	// Stop and disable Port
+	hard_stop(dev);
+    
+	// Setup CIU Arbiter
+	tmp = GT96100_READ(GT96100_CIU_ARBITER_CONFIG);
+	tmp |= (0x0c << (gp->port_num*2)); // set Ether DMA req priority to hi
+#ifndef DESC_BE
+	tmp &= ~(1<<31);                   // set desc endianess to little
+#else
+	tmp |= (1<<31);
+#endif
+	GT96100_WRITE(GT96100_CIU_ARBITER_CONFIG, tmp);
+	dbg(3, __FUNCTION__ ": CIU Config=%x/%x\n",
+	    tmp, GT96100_READ(GT96100_CIU_ARBITER_CONFIG));
+
+	// Set routing.
+	tmp = GT96100_READ(GT96100_ROUTE_MAIN) & (0x3f << 18);
+	tmp |= (0x07 << (18 + gp->port_num*3));
+	GT96100_WRITE(GT96100_ROUTE_MAIN, tmp);
+
+	/* set MII as peripheral func */
+	tmp = GT96100_READ(GT96100_GPP_CONFIG2);
+	tmp |= 0x7fff << (gp->port_num*16);
+	GT96100_WRITE(GT96100_GPP_CONFIG2, tmp);
+	
+	/* Set up MII port pin directions */
+	tmp = GT96100_READ(GT96100_GPP_IO2);
+	tmp |= 0x003d << (gp->port_num*16);
+	GT96100_WRITE(GT96100_GPP_IO2, tmp);
+
+	// Set-up hash table
+	memset(gp->hash_table, 0, RX_HASH_TABLE_SIZE); // clear it
+	gp->hash_mode = 0;
+	// Add a single entry to hash table - our ethernet address
+	gt96100_add_hash_entry(dev, dev->dev_addr);
+	// Set-up DMA ptr to hash table
+	GT96100ETH_WRITE(gp, GT96100_ETH_HASH_TBL_PTR, gp->hash_table_dma);
+	dbg(3, __FUNCTION__ ": Hash Tbl Ptr=%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_HASH_TBL_PTR));
+
+	// Setup Tx
+	reset_tx(dev);
+
+	dbg(3, __FUNCTION__ ": Curr Tx Desc Ptr0=%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_CURR_TX_DESC_PTR0));
+
+	// Setup Rx
+	reset_rx(dev);
+
+	dbg(3, __FUNCTION__ ": 1st/Curr Rx Desc Ptr0=%x/%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_1ST_RX_DESC_PTR0),
+	    GT96100ETH_READ(gp, GT96100_ETH_CURR_RX_DESC_PTR0));
+
+	// eth port config register
+	GT96100ETH_WRITE(gp, GT96100_ETH_PORT_CONFIG_EXT,
+			 pcxrFCTL | pcxrFCTLen | pcxrFLP | pcxrDPLXen);
 
-	// FIX! this should be done by Kernel setup code
-	ciu = GT96100_READ(GT96100_CIU_ARBITER_CONFIG);
-	ciu |= (0x0c << (gp->port_num * 2));	// set Ether DMA req priority to high
-	// FIX! setting the following bit causes the EV96100 board to hang!!!
-	//ciu |= (1 << (24+gp->port_num));   // pull Ethernet port out of Reset???
-	// FIX! endian mode???
-	ciu &= ~(1 << 31);	// set desc endianess to Big
-	GT96100_WRITE(GT96100_CIU_ARBITER_CONFIG, ciu);
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: CIU Config=%x/%x\n", dev->name,
-		       ciu, GT96100_READ(GT96100_CIU_ARBITER_CONFIG));
+	mii_reg = read_MII(gp->phy_addr, 0x11); /* int enable register */
+	mii_reg |= 2;  /* enable mii interrupt */
+	write_MII(gp->phy_addr, 0x11, mii_reg);
+	
+	dbg(3, __FUNCTION__ ": PhyAD=%x\n",
+	    GT96100_READ(GT96100_ETH_PHY_ADDR_REG));
+
+	// setup DMA
 
 	// We want the Rx/Tx DMA to write/read data to/from memory in
 	// Big Endian mode. Also set DMA Burst Size to 8 64Bit words.
-	// FIX! endian mode???
+#ifdef DESC_DATA_BE
+	GT96100ETH_WRITE(gp, GT96100_ETH_SDMA_CONFIG,
+			 (0xf<<sdcrRCBit) | sdcrRIFB | (3<<sdcrBSZBit));
+#else
 	GT96100ETH_WRITE(gp, GT96100_ETH_SDMA_CONFIG,
-			 //sdcrBLMR | sdcrBLMT |
-			 (0xf << sdcrRCBit) | sdcrRIFB | (3 << sdcrBSZBit));
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: SDMA Config=%x\n", dev->name,
-		       GT96100ETH_READ(gp, GT96100_ETH_SDMA_CONFIG));
+			 sdcrBLMR | sdcrBLMT |
+			 (0xf<<sdcrRCBit) | sdcrRIFB | (3<<sdcrBSZBit));
+#endif
+	dbg(3, __FUNCTION__ ": SDMA Config=%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_SDMA_CONFIG));
 
 	// start Rx DMA
 	GT96100ETH_WRITE(gp, GT96100_ETH_SDMA_COMM, sdcmrERD);
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: SDMA Comm=%x\n", dev->name,
-		       GT96100ETH_READ(gp, GT96100_ETH_SDMA_COMM));
-
-	// enable interrupts
-	enable_ether_irq(dev);
-
+	dbg(3, __FUNCTION__ ": SDMA Comm=%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_SDMA_COMM));
+    
+	// enable this port (set hash size to 1/2K)
+	GT96100ETH_WRITE(gp, GT96100_ETH_PORT_CONFIG, pcrEN | pcrHS);
+	dbg(3, __FUNCTION__ ": Port Config=%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_PORT_CONFIG));
+    
 	/*
 	 * Disable all Type-of-Service queueing. All Rx packets will be
 	 * treated normally and will be sent to the lowest priority
 	 * queue.
 	 *
-	 * Disable flow-control for now. FIX! support flow control?
+	 * Disable flow-control for now. FIXME: support flow control?
 	 */
+
 	// clear all the MIB ctr regs
-	// Enable reg clear on read. FIX! desc of this bit is inconsistent
-	// in the GT-96100A datasheet.
 	GT96100ETH_WRITE(gp, GT96100_ETH_PORT_CONFIG_EXT,
-			 pcxrFCTL | pcxrFCTLen | pcxrFLP);
+			 pcxrFCTL | pcxrFCTLen | pcxrFLP |
+			 pcxrPRIOrxOverride);
 	read_mib_counters(gp);
 	GT96100ETH_WRITE(gp, GT96100_ETH_PORT_CONFIG_EXT,
-			 pcxrFCTL | pcxrFCTLen | pcxrFLP | pcxrMIBclrMode);
+			 pcxrFCTL | pcxrFCTLen | pcxrFLP |
+			 pcxrPRIOrxOverride | pcxrMIBclrMode);
+    
+	dbg(3, __FUNCTION__ ": Port Config Ext=%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_PORT_CONFIG_EXT));
 
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: Port Config Ext=%x\n", dev->name,
-		       GT96100ETH_READ(gp, GT96100_ETH_PORT_CONFIG_EXT));
+	netif_start_queue(dev);
 
-	// enable this port (set hash size to 1/2K)
-	GT96100ETH_WRITE(gp, GT96100_ETH_PORT_CONFIG, pcrEN | pcrHS);
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_init: Port Config=%x\n", dev->name,
-		       GT96100ETH_READ(gp, GT96100_ETH_PORT_CONFIG));
+	dump_MII(4, dev);
 
-	// we should now be receiving frames
-	if (gt96100_debug > 2)
-		dump_MII(dev);
+	// enable interrupts
+	enable_ether_irq(dev);
 
-	spin_unlock_irqrestore(&gp->lock, flags);
+	// we should now be receiving frames
 	return 0;
 }
 
 
-static int gt96100_open(struct net_device *dev)
+static int
+gt96100_open(struct net_device *dev)
 {
 	int retval;
-
+    
 	MOD_INC_USE_COUNT;
 
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_open: dev=%p\n", dev->name, dev);
+	dbg(2, __FUNCTION__ ": dev=%p\n", dev);
 
-	if ((retval = request_irq(dev->irq, &gt96100_interrupt,
-				  SA_SHIRQ, dev->name, dev))) {
-		printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name,
-		       dev->irq);
-		MOD_DEC_USE_COUNT;
-		return retval;
-	}
 	// Initialize and startup the GT-96100 ethernet port
 	if ((retval = gt96100_init(dev))) {
-		printk(KERN_ERR "%s: error in gt96100_init\n", dev->name);
+		err("error in gt96100_init\n");
 		free_irq(dev->irq, dev);
 		MOD_DEC_USE_COUNT;
 		return retval;
 	}
 
-	netif_start_queue(dev);
-
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_open: Initialization done.\n",
-		       dev->name);
+	if ((retval = request_irq(dev->irq, &gt96100_interrupt,
+				  SA_SHIRQ, dev->name, dev))) {
+		err("unable to get IRQ %d\n", dev->irq);
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	
+	dbg(2, __FUNCTION__ ": Initialization done.\n");
 
 	return 0;
 }
 
-static int gt96100_close(struct net_device *dev)
+static int
+gt96100_close(struct net_device *dev)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
-	int i;
-
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_close: dev=%p\n", dev->name, dev);
+	dbg(3, __FUNCTION__ ": dev=%p\n", dev);
 
 	// stop the device
 	if (netif_device_present(dev)) {
 		netif_stop_queue(dev);
 		hard_stop(dev);
 	}
-	// free the Rx DMA buffers
-	for (i = 0; i < RX_RING_SIZE; i++) {
-		if (gp->rx_buff[i]) {
-			dmafree(PKT_BUF_SZ, gp->rx_buff[i]);
-			gp->rx_buff[i] = NULL;
-		}
-	}
 
 	free_irq(dev->irq, dev);
-
+    
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
 
-static int gt96100_tx(struct sk_buff *skb, struct net_device *dev)
+static int
+gt96100_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
 	unsigned long flags;
 	int nextIn;
 
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_tx: skb->len=%d, skb->data=%p\n",
-		       dev->name, skb->len, skb->data);
-
 	spin_lock_irqsave(&gp->lock, flags);
 
+	nextIn = gp->tx_next_in;
+
+	dbg(3, __FUNCTION__ ": nextIn=%d\n", nextIn);
+    
 	if (gp->tx_count >= TX_RING_SIZE) {
-		printk(KERN_WARNING
-		       "%s: Tx Ring full, refusing to send buffer.\n",
-		       dev->name);
+		warn("Tx Ring full, pkt dropped.\n");
 		gp->stats.tx_dropped++;
 		spin_unlock_irqrestore(&gp->lock, flags);
 		return 1;
 	}
-	// Prepare the Descriptor at tx_next_in
-	nextIn = gp->tx_next_in;
-
+    
+	if (!(gp->last_psr & psrLink)) {
+		err(__FUNCTION__ ": Link down, pkt dropped.\n");
+		gp->stats.tx_dropped++;
+		spin_unlock_irqrestore(&gp->lock, flags);
+		return 1;
+	}
+    
 	if (dma32_to_cpu(gp->tx_ring[nextIn].cmdstat) & txOwn) {
-		printk(KERN_ERR "%s: gt96100_tx: TxOwn bit wrong!!\n",
-		       dev->name);
+		err(__FUNCTION__ ": device owns descriptor, pkt dropped.\n");
+		gp->stats.tx_dropped++;
+		// stop the queue, so Tx timeout can fix it
+		netif_stop_queue(dev);
+		spin_unlock_irqrestore(&gp->lock, flags);
+		return 1;
 	}
-
+    
+	// Prepare the Descriptor at tx_next_in
 	gp->tx_skbuff[nextIn] = skb;
-	gp->tx_ring[nextIn].byte_cnt =
-	    cpu_to_dma32(skb->len << tdByteCntBit);
-	gp->tx_ring[nextIn].buff_ptr =
-	    cpu_to_dma32(virt_to_phys(skb->data));
+	gp->tx_ring[nextIn].byte_cnt = cpu_to_dma16(skb->len);
+	gp->tx_ring[nextIn].buff_ptr = cpu_to_dma32(virt_to_phys(skb->data));
+	// make sure packet gets written back to memory
+	dma_cache_wback_inv((unsigned long)(skb->data), skb->len);
 	// Give ownership to device, set first and last desc, enable interrupt
 	// Setting of ownership bit must be *last*!
 	gp->tx_ring[nextIn].cmdstat =
-	    cpu_to_dma32((u32) (txOwn | txEI | txFirst | txLast));
+		cpu_to_dma32((u32)(txOwn | txGenCRC | txEI |
+				   txPad | txFirst | txLast));
+    
+	dump_tx_desc(4, dev, nextIn);
+	dump_skb(4, dev, skb);
 
 	// increment tx_next_in with wrap
 	gp->tx_next_in = (nextIn + 1) % TX_RING_SIZE;
-	// If count is zero, DMA should be stopped, so restart
-	if (gp->tx_count == 0) {
-		if (GT96100ETH_READ(gp, GT96100_ETH_PORT_STATUS) &
-		    psrTxLow) printk(KERN_WARNING
-				     "%s: Tx count zero but Tx queue running!\n",
-				     dev->name);
+	// If DMA is stopped, restart
+	if (!(GT96100ETH_READ(gp, GT96100_ETH_PORT_STATUS) & psrTxLow))
 		GT96100ETH_WRITE(gp, GT96100_ETH_SDMA_COMM,
 				 sdcmrERD | sdcmrTXDL);
-	}
+
 	// increment count and stop queue if full
-	if (++gp->tx_count == TX_RING_SIZE)
+	if (++gp->tx_count == TX_RING_SIZE) {
+		gp->tx_full = 1;
 		netif_stop_queue(dev);
-
+		dbg(2, "Tx Ring now full, queue stopped.\n");
+	}
+    
 	dev->trans_start = jiffies;
 	spin_unlock_irqrestore(&gp->lock, flags);
 
@@ -937,317 +1202,438 @@
 }
 
 
-static int gt96100_rx(struct net_device *dev, u32 status)
+static int
+gt96100_rx(struct net_device *dev, u32 status)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
 	struct sk_buff *skb;
-	int pkt_len, nextOut;
+	int pkt_len, nextOut, cdp;
 	gt96100_rd_t *rd;
 	u32 cmdstat;
+    
+	dbg(3, __FUNCTION__ ": dev=%p, status=%x\n", dev, status);
 
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_rx: dev=%p, status = %x\n",
-		       dev->name, dev, status);
+	cdp = (GT96100ETH_READ(gp, GT96100_ETH_1ST_RX_DESC_PTR0)
+	       - gp->rx_ring_dma) / sizeof(gt96100_rd_t);
 
-	// Continue until we reach the current descriptor pointer
-	for (nextOut = gp->rx_next_out;
-	     nextOut !=
-	     (GT96100ETH_READ(gp, GT96100_ETH_CURR_RX_DESC_PTR0) -
-	      gp->rx_ring_dma) / sizeof(gt96100_rd_t);
+	// Continue until we reach 1st descriptor pointer
+	for (nextOut = gp->rx_next_out; nextOut != cdp;
 	     nextOut = (nextOut + 1) % RX_RING_SIZE) {
+	
+		if (--gp->intr_work_done == 0)
+			break;
 
 		rd = &gp->rx_ring[nextOut];
 		cmdstat = dma32_to_cpu(rd->cmdstat);
+	
+		dbg(4, __FUNCTION__ ": Rx desc cmdstat=%x, nextOut=%d\n",
+		    cmdstat, nextOut);
+
+		if (cmdstat & (u32)rxOwn) {
+			//err(__FUNCTION__ ": device owns descriptor!\n");
+			// DMA is not finished updating descriptor???
+			// Leave and come back later to pick-up where
+			// we left off.
+			break;
+		}
 
-		if (cmdstat & (u32) rxOwn) {
-			cmdstat &= ~((u32) rxOwn);
+		// Drop this received pkt if there were any errors
+		if (((cmdstat & (u32)(rxErrorSummary)) &&
+		     (cmdstat & (u32)(rxFirst))) || (status & icrRxError)) {
+			// update the detailed rx error counters that
+			// are not covered by the MIB counters.
+			if (cmdstat & (u32)rxOverrun)
+				gp->stats.rx_fifo_errors++;
+			cmdstat |= (u32)rxOwn;
 			rd->cmdstat = cpu_to_dma32(cmdstat);
-			printk(KERN_ERR
-			       "%s: gt96100_rx: ownership bit wrong!\n",
-			       dev->name);
-		}
-		// must be first and last (ie only) buffer of packet
-		if (!(cmdstat & (u32) rxFirst)
-		    || !(cmdstat & (u32) rxLast)) {
-			printk(KERN_ERR
-			       "%s: gt96100_rx: desc not first and last!\n",
-			       dev->name);
 			continue;
 		}
-		// drop this received pkt if there were any errors
-		if ((cmdstat & (u32) rxErrorSummary)
-		    || (status & icrRxErrorQ0)) {
-			// update the detailed rx error counters that are not covered
-			// by the MIB counters.
-			if (cmdstat & (u32) rxOverrun)
-				gp->stats.rx_fifo_errors++;
+
+		/*
+		 * Must be first and last (ie only) descriptor of packet. We
+		 * ignore (drop) any packets that do not fit in one descriptor.
+		 * Every descriptor's receive buffer is large enough to hold
+		 * the maximum 802.3 frame size, so a multi-descriptor packet
+		 * indicates an error. Most if not all corrupted packets will
+		 * have already been dropped by the above check for the
+		 * rxErrorSummary status bit.
+		 */
+		if (!(cmdstat & (u32)rxFirst) || !(cmdstat & (u32)rxLast)) {
+			if (cmdstat & (u32)rxFirst) {
+				/*
+				 * This is the first descriptor of a
+				 * multi-descriptor packet. It isn't corrupted
+				 * because the above check for rxErrorSummary
+				 * would have dropped it already, so what's
+				 * the deal with this packet? Good question,
+				 * let's dump it out.
+				 */
+				err(__FUNCTION__
+				    ": desc not first and last!\n");
+				dump_rx_desc(0, dev, nextOut);
+			}
+			cmdstat |= (u32)rxOwn;
+			rd->cmdstat = cpu_to_dma32(cmdstat);
+			// continue to drop every descriptor of this packet
 			continue;
 		}
-
-		pkt_len = dma32_to_cpu(rd->buff_cnt_sz) & rdByteCntMask;
-
+	
+		pkt_len = dma16_to_cpu(rd->byte_cnt);
+	
 		/* Create new skb. */
-		skb = dev_alloc_skb(pkt_len + 2);
+		skb = dev_alloc_skb(pkt_len+2);
 		if (skb == NULL) {
-			printk(KERN_ERR
-			       "%s: Memory squeeze, dropping packet.\n",
-			       dev->name);
+			err(__FUNCTION__
+			    ": Memory squeeze, dropping packet.\n");
 			gp->stats.rx_dropped++;
+			cmdstat |= (u32)rxOwn;
+			rd->cmdstat = cpu_to_dma32(cmdstat);
 			continue;
 		}
 		skb->dev = dev;
-		skb_reserve(skb, 2);	/* 16 byte IP header align */
-		skb_put(skb, pkt_len);	/* Make room */
-		eth_copy_and_sum(skb, gp->rx_buff[nextOut], pkt_len, 0);
+		skb_reserve(skb, 2);   /* 16 byte IP header align */
+		memcpy(skb_put(skb, pkt_len),
+		       &gp->rx_buff[nextOut*PKT_BUF_SZ], pkt_len);
 		skb->protocol = eth_type_trans(skb, dev);
-		netif_rx(skb);	/* pass the packet to upper layers */
+		dump_skb(4, dev, skb);
+	
+		netif_rx(skb);        /* pass the packet to upper layers */
+		dev->last_rx = jiffies;
 
 		// now we can release ownership of this desc back to device
-		cmdstat |= (u32) rxOwn;
+		cmdstat |= (u32)rxOwn;
 		rd->cmdstat = cpu_to_dma32(cmdstat);
-
-		dev->last_rx = jiffies;
 	}
+    
+	if (nextOut == gp->rx_next_out)
+		dbg(3, __FUNCTION__ ": RxCDP did not increment?\n");
 
 	gp->rx_next_out = nextOut;
 	return 0;
 }
 
 
-static void gt96100_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void
+gt96100_tx_complete(struct net_device *dev, u32 status)
 {
-	struct net_device *dev = (struct net_device *) dev_id;
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
-	u32 status;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	int nextOut, cdp;
+	gt96100_td_t *td;
+	u32 cmdstat;
 
-	if (dev == NULL) {
-		printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
-		return;
+	cdp = (GT96100ETH_READ(gp, GT96100_ETH_CURR_TX_DESC_PTR0)
+	       - gp->tx_ring_dma) / sizeof(gt96100_td_t);
+    
+	// Continue until we reach the current descriptor pointer
+	for (nextOut = gp->tx_next_out; nextOut != cdp;
+	     nextOut = (nextOut + 1) % TX_RING_SIZE) {
+	
+		if (--gp->intr_work_done == 0)
+			break;
+
+		td = &gp->tx_ring[nextOut];
+		cmdstat = dma32_to_cpu(td->cmdstat);
+	
+		dbg(3, __FUNCTION__ ": Tx desc cmdstat=%x, nextOut=%d\n",
+		    cmdstat, nextOut);
+	
+		if (cmdstat & (u32)txOwn) {
+			//dump_tx_ring(dev);
+			// DMA is not finished writing descriptor???
+			// Leave and come back later to pick-up where
+			// we left off.
+			break;
+		}
+	
+		// increment Tx error stats
+		if (cmdstat & (u32)txErrorSummary) {
+			dbg(2, __FUNCTION__ ": Tx error, cmdstat = %x\n",
+			    cmdstat);
+			gp->stats.tx_errors++;
+			if (cmdstat & (u32)txReTxLimit)
+				gp->stats.tx_aborted_errors++;
+			if (cmdstat & (u32)txUnderrun)
+				gp->stats.tx_fifo_errors++;
+			if (cmdstat & (u32)txLateCollision)
+				gp->stats.tx_window_errors++;
+		}
+	
+		if (cmdstat & (u32)txCollision)
+			gp->stats.collisions +=
+				(u32)((cmdstat & txReTxCntMask) >>
+				      txReTxCntBit);
+
+		// Wake the queue if the ring was full
+		if (gp->tx_full) {
+			gp->tx_full = 0;
+			if (gp->last_psr & psrLink) {
+				netif_wake_queue(dev);
+				dbg(2, __FUNCTION__
+				    ": Tx Ring was full, queue waked\n");
+			}
+		}
+	
+		// decrement tx ring buffer count
+		if (gp->tx_count) gp->tx_count--;
+	
+		// free the skb
+		if (gp->tx_skbuff[nextOut]) {
+			dbg(3, __FUNCTION__ ": good Tx, skb=%p\n",
+			    gp->tx_skbuff[nextOut]);
+			dev_kfree_skb_irq(gp->tx_skbuff[nextOut]);
+			gp->tx_skbuff[nextOut] = NULL;
+		} else {
+			err(__FUNCTION__ ": no skb!\n");
+		}
 	}
 
-	status = GT96100ETH_READ(gp, GT96100_ETH_INT_CAUSE);
-	// ACK interrupts
-#if 0
-	GT96100ETH_CLRBIT(gp, GT96100_ETH_INT_CAUSE,
-			  icrEtherIntSum | icrRxBufferQ1 | icrRxBufferQ2 |
-			  icrRxBufferQ3 | icrRxBufferQ0 | icrTxBufferHigh |
-			  icrTxEndHigh | icrTxBufferLow | icrTxEndLow |
-			  icrTxErrorHigh | icrTxErrorLow | icrTxUdr);
-#else
-	GT96100ETH_WRITE(gp, GT96100_ETH_INT_CAUSE, 0);
-#endif
+	gp->tx_next_out = nextOut;
+
+	if (gt96100_check_tx_consistent(gp)) {
+		err(__FUNCTION__ ": Tx queue inconsistent!\n");
+	}
+    
+	if ((status & icrTxEndLow) && gp->tx_count != 0) {
+		// we must restart the DMA
+		dbg(3, __FUNCTION__ ": Restarting Tx DMA\n");
+		GT96100ETH_WRITE(gp, GT96100_ETH_SDMA_COMM,
+				 sdcmrERD | sdcmrTXDL);
+	}
+}
+
 
-	if ((status & icrEtherIntSum) == 0) {
-		// not our interrupt
-		//printk("%s: isr: no ints? icr=%x,cp0_cause=%x\n",
-		//       dev->name, status, read_32bit_cp0_register(CP0_CAUSE));
+static void
+gt96100_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	u32 status;
+    
+	if (dev == NULL) {
+		err(__FUNCTION__ ": null dev ptr\n");
 		return;
 	}
 
-	if (gt96100_debug > 3)
-		printk("%s: isr: entry, icr=%x\n", dev->name, status);
+	dbg(3, __FUNCTION__ ": entry, icr=%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_INT_CAUSE));
 
-	if (status & (icrRxBufferQ1 | icrRxBufferQ2 | icrRxBufferQ3)) {
-		printk(KERN_ERR "%s: isr: Rx intr in unused queues!?\n",
-		       dev->name);
-	}
-
-	if (status & icrRxBufferQ0) {
-		gt96100_rx(dev, status);
-	}
-
-	if (status & (icrTxBufferHigh | icrTxEndHigh)) {
-		printk(KERN_ERR "%s: isr: Tx intr in unused queue!?\n",
-		       dev->name);
-	}
-
-	if (status & icrMIIPhySTC) {
-		u32 psr = GT96100ETH_READ(gp, GT96100_ETH_PORT_STATUS);
-		printk("%s: port status:\n", dev->name);
-		printk
-		    ("%s:     %s MBit/s, %s-duplex, flow-control %s, link is %s,\n",
-		     dev->name, psr & psrSpeed ? "100" : "10",
-		     psr & psrDuplex ? "full" : "half",
-		     psr & psrFctl ? "disabled" : "enabled",
-		     psr & psrLink ? "up" : "down");
-		printk
-		    ("%s:     TxLowQ is %s, TxHighQ is %s, Transmitter is %s\n",
-		     dev->name, psr & psrTxLow ? "running" : "stopped",
-		     psr & psrTxHigh ? "running" : "stopped",
-		     psr & psrTxInProg ? "on" : "off");
-		gp->last_psr = psr;
-	}
-
-	if (status & (icrTxBufferLow | icrTxEndLow)) {
-		int nextOut;
-		gt96100_td_t *td;
-		u32 cmdstat;
-
-		// Continue until we reach the current descriptor pointer
-		for (nextOut = gp->tx_next_out;
-		     nextOut !=
-		     (GT96100ETH_READ(gp, GT96100_ETH_CURR_TX_DESC_PTR0) -
-		      gp->tx_ring_dma) / sizeof(gt96100_td_t);
-		     nextOut = (nextOut + 1) % TX_RING_SIZE) {
-
-			td = &gp->tx_ring[nextOut];
-			cmdstat = dma32_to_cpu(td->cmdstat);
-
-			if (gt96100_debug > 2)
-				printk("%s: isr: Tx desc cmdstat=%x\n",
-				       dev->name, cmdstat);
-
-			if (cmdstat & (u32) txOwn) {
-				cmdstat &= ~((u32) txOwn);
-				td->cmdstat = cpu_to_dma32(cmdstat);
-				printk(KERN_ERR
-				       "%s: isr: Tx ownership bit wrong!\n",
-				       dev->name);
-			}
-			// increment Tx error stats
-			if (cmdstat & (u32) txErrorSummary) {
-				if (gt96100_debug > 2)
-					printk
-					    ("%s: gt96100_interrupt: Tx error, cmdstat = %x\n",
-					     dev->name, cmdstat);
-				gp->stats.tx_errors++;
-				if (cmdstat & (u32) txReTxLimit)
-					gp->stats.collisions++;
-				if (cmdstat & (u32) txUnderrun)
-					gp->stats.tx_fifo_errors++;
-				if (cmdstat & (u32) txLateCollision)
-					gp->stats.tx_window_errors++;
-			}
-			// Wake the queue if the ring was full
-			if (gp->tx_count == TX_RING_SIZE)
-				netif_wake_queue(dev);
+	spin_lock(&gp->lock);
 
-			// decrement tx ring buffer count
-			if (gp->tx_count)
-				gp->tx_count--;
-
-			// free the skb
-			if (gp->tx_skbuff[nextOut]) {
-				if (gt96100_debug > 2)
-					printk
-					    ("%s: isr: good Tx, skb=%p\n",
-					     dev->name,
-					     gp->tx_skbuff[nextOut]);
-				dev_kfree_skb_irq(gp->tx_skbuff[nextOut]);
-				gp->tx_skbuff[nextOut] = NULL;
-			} else {
-				printk(KERN_ERR "%s: isr: no skb!\n",
-				       dev->name);
-			}
-		}
+	gp->intr_work_done = max_interrupt_work;
 
-		if (gp->tx_count == 0 && nextOut != gp->tx_next_in) {
-			// FIX! this should probably be a panic
-			printk(KERN_ERR
-			       "%s: isr: warning! Tx queue inconsistent\n",
-			       dev->name);
-		}
+	while (gp->intr_work_done > 0) {
 
-		gp->tx_next_out = nextOut;
+		status = GT96100ETH_READ(gp, GT96100_ETH_INT_CAUSE);
+		// ACK interrupts
+		GT96100ETH_WRITE(gp, GT96100_ETH_INT_CAUSE, ~status);
 
-		if ((status & icrTxEndLow) && gp->tx_count != 0) {
-			// we must restart the DMA
-			if (gt96100_debug > 2)
-				printk("%s: isr: Restarting Tx DMA\n",
-				       dev->name);
-			GT96100ETH_WRITE(gp, GT96100_ETH_SDMA_COMM,
-					 sdcmrERD | sdcmrTXDL);
-		}
-	}
-	// Now check TX errors (RX errors were handled in gt96100_rx)
+		if ((status & icrEtherIntSum) == 0 &&
+		    !(status & (icrTxBufferLow|icrTxBufferHigh|icrRxBuffer)))
+			break;
+	
+		if (status & icrMIIPhySTC) {
+			u32 psr = GT96100ETH_READ(gp, GT96100_ETH_PORT_STATUS);
+			if (gp->last_psr != psr) {
+				dbg(0, "port status:\n");
+				dbg(0, "    %s MBit/s, %s-duplex, "
+				    "flow-control %s, link is %s,\n",
+				    psr & psrSpeed ? "100":"10",
+				    psr & psrDuplex ? "full":"half",
+				    psr & psrFctl ? "disabled":"enabled",
+				    psr & psrLink ? "up":"down");
+				dbg(0, "    TxLowQ is %s, TxHighQ is %s, "
+				    "Transmitter is %s\n",
+				    psr & psrTxLow ? "running":"stopped",
+				    psr & psrTxHigh ? "running":"stopped",
+				    psr & psrTxInProg ? "on":"off");
+		
+				if ((psr & psrLink) && !gp->tx_full &&
+				    netif_queue_stopped(dev)) {
+					dbg(0, __FUNCTION__
+					    ": Link up, waking queue.\n");
+					netif_wake_queue(dev);
+				} else if (!(psr & psrLink) &&
+					   !netif_queue_stopped(dev)) {
+					dbg(0, __FUNCTION__
+					    "Link down, stopping queue.\n");
+					netif_stop_queue(dev);
+				}
 
-	if (status & icrTxErrorHigh) {
-		printk(KERN_ERR
-		       "%s: isr: Tx resource error in unused queue!?\n",
-		       dev->name);
-	}
+				gp->last_psr = psr;
+			}
 
-	if (status & icrTxErrorLow) {
-		printk(KERN_ERR "%s: isr: Tx resource error\n", dev->name);
-	}
+			if (--gp->intr_work_done == 0)
+				break;
+		}
+	
+		if (status & (icrTxBufferLow | icrTxEndLow))
+			gt96100_tx_complete(dev, status);
 
-	if (status & icrTxUdr) {
-		printk(KERN_ERR "%s: isr: Tx underrun error\n", dev->name);
+		if (status & (icrRxBuffer | icrRxError)) {
+			gt96100_rx(dev, status);
+		}
+	
+		// Now check TX errors (RX errors were handled in gt96100_rx)
+		if (status & icrTxErrorLow) {
+			err(__FUNCTION__ ": Tx resource error\n");
+			if (--gp->intr_work_done == 0)
+				break;
+		}
+	
+		if (status & icrTxUdr) {
+			err(__FUNCTION__ ": Tx underrun error\n");
+			if (--gp->intr_work_done == 0)
+				break;
+		}
 	}
 
-	if (gt96100_debug > 3)
-		printk("%s: isr: exit, icr=%x\n",
-		       dev->name, GT96100ETH_READ(gp,
-						  GT96100_ETH_INT_CAUSE));
+	if (gp->intr_work_done == 0) {
+		// ACK any remaining pending interrupts
+		GT96100ETH_WRITE(gp, GT96100_ETH_INT_CAUSE, 0);
+		dbg(3, __FUNCTION__ ": hit max work\n");
+	}
+    
+	dbg(3, __FUNCTION__ ": exit, icr=%x\n",
+	    GT96100ETH_READ(gp, GT96100_ETH_INT_CAUSE));
+
+	spin_unlock(&gp->lock);
 }
 
 
-/*
- * The Tx ring has been full longer than the watchdog timeout
- * value, meaning that the interrupt routine has not been freeing
- * up space in the Tx ring buffer.
- */
-static void gt96100_tx_timeout(struct net_device *dev)
+static void
+gt96100_tx_timeout(struct net_device *dev)
 {
-//    struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
-
-	printk(KERN_ERR "%s: gt96100_tx_timeout: dev=%p\n", dev->name,
-	       dev);
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
+	unsigned long flags;
+    
+	spin_lock_irqsave(&gp->lock, flags);
+    
+	if (!(gp->last_psr & psrLink)) {
+		err("tx_timeout: link down.\n");
+		spin_unlock_irqrestore(&gp->lock, flags);
+	} else {
+		if (gt96100_check_tx_consistent(gp))
+			err("tx_timeout: Tx ring error.\n");
 
-	// FIX! do something, like reset the device
+		disable_ether_irq(dev);
+		spin_unlock_irqrestore(&gp->lock, flags);
+		reset_tx(dev);
+		enable_ether_irq(dev);
+	
+		netif_wake_queue(dev);
+	}
 }
 
 
-static void gt96100_set_rx_mode(struct net_device *dev)
+static void
+gt96100_set_rx_mode(struct net_device *dev)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
 	unsigned long flags;
-	struct dev_mc_list *mcptr;
-
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_set_rx_mode: dev=%p, flags=%x\n",
-		       dev->name, dev, dev->flags);
+	//struct dev_mc_list *mcptr;
+    
+	dbg(3, __FUNCTION__ ": dev=%p, flags=%x\n", dev, dev->flags);
 
 	// stop the Receiver DMA
 	abort(dev, sdcmrAR);
 
 	spin_lock_irqsave(&gp->lock, flags);
 
-	if (dev->flags & IFF_PROMISC)
+	if (dev->flags & IFF_PROMISC) {
 		GT96100ETH_WRITE(gp, GT96100_ETH_PORT_CONFIG,
 				 pcrEN | pcrHS | pcrPM);
+	}
 
-	memset(gp->hash_table, 0, RX_HASH_TABLE_SIZE);	// clear hash table
-	// Add our ethernet address
-	gt96100_add_hash_entry(dev, dev->dev_addr);
-
+#if 0
+	/*
+	  FIXME: currently multicast doesn't work - need to get hash table
+	  working first.
+	*/
 	if (dev->mc_count) {
+		// clear hash table
+		memset(gp->hash_table, 0, RX_HASH_TABLE_SIZE);
+		// Add our ethernet address
+		gt96100_add_hash_entry(dev, dev->dev_addr);
+
 		for (mcptr = dev->mc_list; mcptr; mcptr = mcptr->next) {
+			dump_hw_addr(2, dev, __FUNCTION__ ": addr=",
+				     mcptr->dmi_addr);
 			gt96100_add_hash_entry(dev, mcptr->dmi_addr);
 		}
 	}
+#endif
+    
 	// restart Rx DMA
 	GT96100ETH_WRITE(gp, GT96100_ETH_SDMA_COMM, sdcmrERD);
 
 	spin_unlock_irqrestore(&gp->lock, flags);
 }
 
-static struct net_device_stats *gt96100_get_stats(struct net_device *dev)
+static struct net_device_stats *
+gt96100_get_stats(struct net_device *dev)
 {
-	struct gt96100_private *gp = (struct gt96100_private *) dev->priv;
+	struct gt96100_private *gp = (struct gt96100_private *)dev->priv;
 	unsigned long flags;
 
-	if (gt96100_debug > 2)
-		printk("%s: gt96100_get_stats: dev=%p\n", dev->name, dev);
+	dbg(3, __FUNCTION__ ": dev=%p\n", dev);
 
 	if (netif_device_present(dev)) {
-		spin_lock_irqsave(&gp->lock, flags);
+		spin_lock_irqsave (&gp->lock, flags);
 		update_stats(gp);
-		spin_unlock_irqrestore(&gp->lock, flags);
+		spin_unlock_irqrestore (&gp->lock, flags);
 	}
 
 	return &gp->stats;
 }
 
-module_init(gt96100_probe);
-MODULE_LICENSE("GPL");
+static void gt96100_cleanup_module(void)
+{
+	int i;
+	for (i=0; i<NUM_INTERFACES; i++) {
+		struct gt96100_if_t *gtif = &gt96100_iflist[i];
+		if (gtif->dev != NULL) {
+			struct gt96100_private *gp =
+				(struct gt96100_private *)gtif->dev->priv;
+			release_region(gtif->iobase, gp->io_size);
+			unregister_netdev(gtif->dev);
+			if (gtif->dev->priv != NULL)
+				kfree (gtif->dev->priv);
+			kfree (gtif->dev);
+		}
+	}
+}
+
+
+#ifndef MODULE
+
+static int __init gt96100_setup(char *options)
+{
+	char *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+        for(this_opt=strtok(options, ",");
+	    this_opt; this_opt=strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "mac0:", 5)) {
+			memcpy(mac0, this_opt+5, 17);
+			mac0[17]= '\0';
+		} else if (!strncmp(this_opt, "mac1:", 5)) {
+			memcpy(mac1, this_opt+5, 17);
+			mac1[17]= '\0';
+		}
+	}
+
+	return 1;
+}
+
+__setup("gt96100eth=", gt96100_setup);
+
+#endif /* !MODULE */
+
+
+module_init(gt96100_init_module);
+module_exit(gt96100_cleanup_module);
+
+MODULE_AUTHOR("Steve Longerbeam <stevel@mvista.com>");
+MODULE_DESCRIPTION("GT96100 Ethernet driver");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/gt96100eth.h linux/drivers/net/gt96100eth.h
--- linux.orig/drivers/net/gt96100eth.h	2001-09-09 17:45:43.000000000 +0000
+++ linux/drivers/net/gt96100eth.h	2002-07-20 01:08:28.000000000 +0000
@@ -27,31 +27,46 @@
 #ifndef _GT96100ETH_H
 #define _GT96100ETH_H
 
+#include <linux/config.h>
 #include <asm/galileo-boards/gt96100.h>
 
+#define dbg(lvl, format, arg...) \
+    if (lvl <= GT96100_DEBUG) \
+        printk(KERN_DEBUG "%s: " format, dev->name , ## arg)
+#define err(format, arg...) \
+    printk(KERN_ERR "%s: " format, dev->name , ## arg)
+#define info(format, arg...) \
+    printk(KERN_INFO "%s: " format, dev->name , ## arg)
+#define warn(format, arg...) \
+    printk(KERN_WARNING "%s: " format, dev->name , ## arg)
+
 /* Keep the ring sizes a power of two for efficiency. */
 #define TX_RING_SIZE	16
 #define RX_RING_SIZE	32
-#define PKT_BUF_SZ	1536	/* Size of each temporary Rx buffer. */
+#define PKT_BUF_SZ	1536	/* Size of each temporary Rx buffer.*/
 
 #define RX_HASH_TABLE_SIZE 16384
 #define HASH_HOP_NUMBER 12
 
 #define NUM_INTERFACES 2
 
-#define GT96100ETH_TX_TIMEOUT HZ
+#define GT96100ETH_TX_TIMEOUT HZ/4
 
 #define GT96100_ETH0_BASE (MIPS_GT96100_BASE + GT96100_ETH_PORT_CONFIG)
 #define GT96100_ETH1_BASE (GT96100_ETH0_BASE + GT96100_ETH_IO_SIZE)
 
 #ifdef CONFIG_MIPS_EV96100
-#define GT96100_ETHER0_IRQ 4
+#define GT96100_ETHER0_IRQ 3
 #define GT96100_ETHER1_IRQ 4
 #else
 #define GT96100_ETHER0_IRQ -1
 #define GT96100_ETHER1_IRQ -1
 #endif
 
+#define REV_GT96100  1
+#define REV_GT96100A_1 2
+#define REV_GT96100A 3
+
 #define GT96100ETH_READ(gp, offset) \
     GT96100_READ((gp->port_offset + offset))
 
@@ -70,13 +85,13 @@
 /* Bit definitions of the SMI Reg */
 enum {
 	smirDataMask = 0xffff,
-	smirPhyAdMask = 0x1f << 16,
+	smirPhyAdMask = 0x1f<<16,
 	smirPhyAdBit = 16,
-	smirRegAdMask = 0x1f << 21,
+	smirRegAdMask = 0x1f<<21,
 	smirRegAdBit = 21,
-	smirOpCode = 1 << 26,
-	smirReadValid = 1 << 27,
-	smirBusy = 1 << 28
+	smirOpCode = 1<<26,
+	smirReadValid = 1<<27,
+	smirBusy = 1<<28
 };
 
 /* Bit definitions of the Port Config Reg */
@@ -84,17 +99,17 @@
 	pcrPM = 1,
 	pcrRBM = 2,
 	pcrPBF = 4,
-	pcrEN = 1 << 7,
-	pcrLPBKMask = 0x3 << 8,
+	pcrEN = 1<<7,
+	pcrLPBKMask = 0x3<<8,
 	pcrLPBKBit = 8,
-	pcrFC = 1 << 10,
-	pcrHS = 1 << 12,
-	pcrHM = 1 << 13,
-	pcrHDM = 1 << 14,
-	pcrHD = 1 << 15,
-	pcrISLMask = 0x7 << 28,
+	pcrFC = 1<<10,
+	pcrHS = 1<<12,
+	pcrHM = 1<<13,
+	pcrHDM = 1<<14,
+	pcrHD = 1<<15,
+	pcrISLMask = 0x7<<28,
 	pcrISLBit = 28,
-	pcrACCS = 1 << 31
+	pcrACCS = 1<<31
 };
 
 /* Bit definitions of the Port Config Extend Reg */
@@ -102,27 +117,27 @@
 	pcxrIGMP = 1,
 	pcxrSPAN = 2,
 	pcxrPAR = 4,
-	pcxrPRIOtxMask = 0x7 << 3,
+	pcxrPRIOtxMask = 0x7<<3,
 	pcxrPRIOtxBit = 3,
-	pcxrPRIOrxMask = 0x3 << 6,
+	pcxrPRIOrxMask = 0x3<<6,
 	pcxrPRIOrxBit = 6,
-	pcxrPRIOrxOverride = 1 << 8,
-	pcxrDPLXen = 1 << 9,
-	pcxrFCTLen = 1 << 10,
-	pcxrFLP = 1 << 11,
-	pcxrFCTL = 1 << 12,
-	pcxrMFLMask = 0x3 << 14,
+	pcxrPRIOrxOverride = 1<<8,
+	pcxrDPLXen = 1<<9,
+	pcxrFCTLen = 1<<10,
+	pcxrFLP = 1<<11,
+	pcxrFCTL = 1<<12,
+	pcxrMFLMask = 0x3<<14,
 	pcxrMFLBit = 14,
-	pcxrMIBclrMode = 1 << 16,
-	pcxrSpeed = 1 << 18,
-	pcxrSpeeden = 1 << 19,
-	pcxrRMIIen = 1 << 20,
-	pcxrDSCPen = 1 << 21
+	pcxrMIBclrMode = 1<<16,
+	pcxrSpeed = 1<<18,
+	pcxrSpeeden = 1<<19,
+	pcxrRMIIen = 1<<20,
+	pcxrDSCPen = 1<<21
 };
 
 /* Bit definitions of the Port Command Reg */
 enum pcmr_bits {
-	pcmrFJ = 1 << 15
+	pcmrFJ = 1<<15
 };
 
 
@@ -132,119 +147,124 @@
 	psrDuplex = 2,
 	psrFctl = 4,
 	psrLink = 8,
-	psrPause = 1 << 4,
-	psrTxLow = 1 << 5,
-	psrTxHigh = 1 << 6,
-	psrTxInProg = 1 << 7
+	psrPause = 1<<4,
+	psrTxLow = 1<<5,
+	psrTxHigh = 1<<6,
+	psrTxInProg = 1<<7
 };
 
 /* Bit definitions of the SDMA Config Reg */
 enum sdcr_bits {
-	sdcrRCMask = 0xf << 2,
+	sdcrRCMask = 0xf<<2,
 	sdcrRCBit = 2,
-	sdcrBLMR = 1 << 6,
-	sdcrBLMT = 1 << 7,
-	sdcrPOVR = 1 << 8,
-	sdcrRIFB = 1 << 9,
-	sdcrBSZMask = 0x3 << 12,
+	sdcrBLMR = 1<<6,
+	sdcrBLMT = 1<<7,
+	sdcrPOVR = 1<<8,
+	sdcrRIFB = 1<<9,
+	sdcrBSZMask = 0x3<<12,
 	sdcrBSZBit = 12
 };
 
 /* Bit definitions of the SDMA Command Reg */
 enum sdcmr_bits {
-	sdcmrERD = 1 << 7,
-	sdcmrAR = 1 << 15,
-	sdcmrSTDH = 1 << 16,
-	sdcmrSTDL = 1 << 17,
-	sdcmrTXDH = 1 << 23,
-	sdcmrTXDL = 1 << 24,
-	sdcmrAT = 1 << 31
+	sdcmrERD = 1<<7,
+	sdcmrAR = 1<<15,
+	sdcmrSTDH = 1<<16,
+	sdcmrSTDL = 1<<17,
+	sdcmrTXDH = 1<<23,
+	sdcmrTXDL = 1<<24,
+	sdcmrAT = 1<<31
 };
 
 /* Bit definitions of the Interrupt Cause Reg */
 enum icr_bits {
 	icrRxBuffer = 1,
-	icrTxBufferHigh = 1 << 2,
-	icrTxBufferLow = 1 << 3,
-	icrTxEndHigh = 1 << 6,
-	icrTxEndLow = 1 << 7,
-	icrRxError = 1 << 8,
-	icrTxErrorHigh = 1 << 10,
-	icrTxErrorLow = 1 << 11,
-	icrRxOVR = 1 << 12,
-	icrTxUdr = 1 << 13,
-	icrRxBufferQ0 = 1 << 16,
-	icrRxBufferQ1 = 1 << 17,
-	icrRxBufferQ2 = 1 << 18,
-	icrRxBufferQ3 = 1 << 19,
-	icrRxErrorQ0 = 1 << 20,
-	icrRxErrorQ1 = 1 << 21,
-	icrRxErrorQ2 = 1 << 22,
-	icrRxErrorQ3 = 1 << 23,
-	icrMIIPhySTC = 1 << 28,
-	icrSMIdone = 1 << 29,
-	icrEtherIntSum = 1 << 31
+	icrTxBufferHigh = 1<<2,
+	icrTxBufferLow = 1<<3,
+	icrTxEndHigh = 1<<6,
+	icrTxEndLow = 1<<7,
+	icrRxError = 1<<8,
+	icrTxErrorHigh = 1<<10,
+	icrTxErrorLow = 1<<11,
+	icrRxOVR = 1<<12,
+	icrTxUdr = 1<<13,
+	icrRxBufferQ0 = 1<<16,
+	icrRxBufferQ1 = 1<<17,
+	icrRxBufferQ2 = 1<<18,
+	icrRxBufferQ3 = 1<<19,
+	icrRxErrorQ0 = 1<<20,
+	icrRxErrorQ1 = 1<<21,
+	icrRxErrorQ2 = 1<<22,
+	icrRxErrorQ3 = 1<<23,
+	icrMIIPhySTC = 1<<28,
+	icrSMIdone = 1<<29,
+	icrEtherIntSum = 1<<31
 };
 
 
 /* The Rx and Tx descriptor lists. */
-
 typedef struct {
+#ifdef DESC_BE
+	u16 byte_cnt;
+	u16 reserved;
+#else
+	u16 reserved;
+	u16 byte_cnt;
+#endif
 	u32 cmdstat;
-	u32 byte_cnt;
-	u32 buff_ptr;
 	u32 next;
-} gt96100_td_t;
-
-#define tdByteCntBit 16
+	u32 buff_ptr;
+} gt96100_td_t __attribute__ ((packed));
 
 typedef struct {
+#ifdef DESC_BE
+	u16 buff_sz;
+	u16 byte_cnt;
+#else
+	u16 byte_cnt;
+	u16 buff_sz;
+#endif
 	u32 cmdstat;
-	u32 buff_cnt_sz;
-	u32 buff_ptr;
 	u32 next;
-} gt96100_rd_t;
-
-#define rdBuffSzBit 16
-#define rdByteCntMask 0xffff
+	u32 buff_ptr;
+} gt96100_rd_t __attribute__ ((packed));
 
 
 /* Values for the Tx command-status descriptor entry. */
 enum td_cmdstat {
-	txOwn = 1 << 31,
-	txAutoMode = 1 << 30,
-	txEI = 1 << 23,
-	txGenCRC = 1 << 22,
-	txPad = 1 << 18,
-	txFirst = 1 << 17,
-	txLast = 1 << 16,
-	txErrorSummary = 1 << 15,
-	txReTxCntMask = 0x0f << 10,
+	txOwn = 1<<31,
+	txAutoMode = 1<<30,
+	txEI = 1<<23,
+	txGenCRC = 1<<22,
+	txPad = 1<<18,
+	txFirst = 1<<17,
+	txLast = 1<<16,
+	txErrorSummary = 1<<15,
+	txReTxCntMask = 0x0f<<10,
 	txReTxCntBit = 10,
-	txCollision = 1 << 9,
-	txReTxLimit = 1 << 8,
-	txUnderrun = 1 << 6,
-	txLateCollision = 1 << 5
+	txCollision = 1<<9,
+	txReTxLimit = 1<<8,
+	txUnderrun = 1<<6,
+	txLateCollision = 1<<5
 };
 
-#define TxReTxCntBit 10
 
 /* Values for the Rx command-status descriptor entry. */
 enum rd_cmdstat {
-	rxOwn = 1 << 31,
-	rxAutoMode = 1 << 30,
-	rxEI = 1 << 23,
-	rxFirst = 1 << 17,
-	rxLast = 1 << 16,
-	rxErrorSummary = 1 << 15,
-	rxIGMP = 1 << 14,
-	rxHashExpired = 1 << 13,
-	rxMissedFrame = 1 << 12,
-	rxFrameType = 1 << 11,
-	rxShortFrame = 1 << 8,
-	rxMaxFrameLen = 1 << 7,
-	rxOverrun = 1 << 6,
-	rxCollision = 1 << 4,
+	rxOwn = 1<<31,
+	rxAutoMode = 1<<30,
+	rxEI = 1<<23,
+	rxFirst = 1<<17,
+	rxLast = 1<<16,
+	rxErrorSummary = 1<<15,
+	rxIGMP = 1<<14,
+	rxHashExpired = 1<<13,
+	rxMissedFrame = 1<<12,
+	rxFrameType = 1<<11,
+	rxShortFrame = 1<<8,
+	rxMaxFrameLen = 1<<7,
+	rxOverrun = 1<<6,
+	rxCollision = 1<<4,
 	rxCRCError = 1
 };
 
@@ -286,40 +306,44 @@
 
 
 struct gt96100_private {
-	gt96100_rd_t *rx_ring;
-	gt96100_td_t *tx_ring;
+	gt96100_rd_t* rx_ring;
+	gt96100_td_t* tx_ring;
 	// The Rx and Tx rings must be 16-byte aligned
 	dma_addr_t rx_ring_dma;
 	dma_addr_t tx_ring_dma;
-	char *hash_table;
+	char* hash_table;
 	// The Hash Table must be 8-byte aligned
 	dma_addr_t hash_table_dma;
 	int hash_mode;
-
+    
 	// The Rx buffers must be 8-byte aligned
-	char *rx_buff[RX_RING_SIZE];
+	char* rx_buff;
+	dma_addr_t rx_buff_dma;
 	// Tx buffers (tx_skbuff[i]->data) with less than 8 bytes
 	// of payload must be 8-byte aligned
-	struct sk_buff *tx_skbuff[TX_RING_SIZE];
-	int rx_next_out;	/* The next free ring entry to receive */
-	int tx_next_in;		/* The next free ring entry to send */
-	int tx_next_out;	/* The last ring entry the ISR processed */
-	int tx_count;		/* current # of pkts waiting to be sent in Tx ring */
-
+	struct sk_buff* tx_skbuff[TX_RING_SIZE];
+	int rx_next_out; /* The next free ring entry to receive */
+	int tx_next_in;	 /* The next free ring entry to send */
+	int tx_next_out; /* The last ring entry the ISR processed */
+	int tx_count;    /* current # of pkts waiting to be sent in Tx ring */
+	int intr_work_done; /* number of Rx and Tx pkts processed in the isr */
+	int tx_full;        /* Tx ring is full */
+    
 	mib_counters_t mib;
 	struct net_device_stats stats;
 
 	int io_size;
-	int port_num;		// 0 or 1
+	int port_num;  // 0 or 1
+	int chip_rev;
 	u32 port_offset;
+    
+	int phy_addr; // PHY address
+	u32 last_psr; // last value of the port status register
 
-	int phy_addr;		// PHY address
-	u32 last_psr;		// last value of the port status register
-
-	int options;		/* User-settable misc. driver options. */
+	int options;     /* User-settable misc. driver options. */
 	int drv_flags;
-	unsigned char phys[2];	/* MII device addresses. */
-	spinlock_t lock;	/* Serialise access to device */
+	struct timer_list timer;
+	spinlock_t lock; /* Serialise access to device */
 };
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/baycom_epp.c linux/drivers/net/hamradio/baycom_epp.c
--- linux.orig/drivers/net/hamradio/baycom_epp.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/hamradio/baycom_epp.c	2002-07-20 01:08:40.000000000 +0000
@@ -302,7 +302,7 @@
 /*---------------------------------------------------------------------------*/
 
 #if 0
-extern inline void append_crc_ccitt(unsigned char *buffer, int len)
+static inline void append_crc_ccitt(unsigned char *buffer, int len)
 {
  	unsigned int crc = 0xffff;
 
@@ -316,7 +316,7 @@
 
 /*---------------------------------------------------------------------------*/
 
-extern inline int check_crc_ccitt(const unsigned char *buf, int cnt)
+static inline int check_crc_ccitt(const unsigned char *buf, int cnt)
 {
 	unsigned int crc = 0xffff;
 
@@ -327,7 +327,7 @@
 
 /*---------------------------------------------------------------------------*/
 
-extern inline int calc_crc_ccitt(const unsigned char *buf, int cnt)
+static inline int calc_crc_ccitt(const unsigned char *buf, int cnt)
 {
 	unsigned int crc = 0xffff;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/baycom_ser_fdx.c linux/drivers/net/hamradio/baycom_ser_fdx.c
--- linux.orig/drivers/net/hamradio/baycom_ser_fdx.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/hamradio/baycom_ser_fdx.c	2002-07-20 01:08:22.000000000 +0000
@@ -201,12 +201,12 @@
 /* --------------------------------------------------------------------- */
 
 #if 0
-extern inline unsigned int hweight16(unsigned int w)
+static inline unsigned int hweight16(unsigned int w)
         __attribute__ ((unused));
-extern inline unsigned int hweight8(unsigned int w)
+static inline unsigned int hweight8(unsigned int w)
         __attribute__ ((unused));
 
-extern inline unsigned int hweight16(unsigned int w)
+static inline unsigned int hweight16(unsigned int w)
 {
         unsigned short res = (w & 0x5555) + ((w >> 1) & 0x5555);
         res = (res & 0x3333) + ((res >> 2) & 0x3333);
@@ -214,7 +214,7 @@
         return (res & 0x00FF) + ((res >> 8) & 0x00FF);
 }
 
-extern inline unsigned int hweight8(unsigned int w)
+static inline unsigned int hweight8(unsigned int w)
 {
         unsigned short res = (w & 0x55) + ((w >> 1) & 0x55);
         res = (res & 0x33) + ((res >> 2) & 0x33);
@@ -417,21 +417,27 @@
 		return -ENXIO;
 	if (bc->baud < 300 || bc->baud > 4800)
 		return -EINVAL;
-	if (check_region(dev->base_addr, SER12_EXTENT))
+	if (!request_region(dev->base_addr, SER12_EXTENT, "baycom_ser_fdx")) {
+		printk(KERN_WARNING "BAYCOM_SER_FSX: I/O port 0x%04lx busy \n", 
+		       dev->base_addr);
 		return -EACCES;
+	}
 	memset(&bc->modem, 0, sizeof(bc->modem));
 	bc->hdrv.par.bitrate = bc->baud;
 	bc->baud_us = 1000000/bc->baud;
 	bc->baud_uartdiv = (115200/8)/bc->baud;
-	if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown)
+	if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown){
+		release_region(dev->base_addr, SER12_EXTENT);
 		return -EIO;
+	}
 	outb(0, FCR(dev->base_addr));  /* disable FIFOs */
 	outb(0x0d, MCR(dev->base_addr));
 	outb(0, IER(dev->base_addr));
 	if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT | SA_SHIRQ,
-			"baycom_ser_fdx", dev))
+			"baycom_ser_fdx", dev)) {
+		release_region(dev->base_addr, SER12_EXTENT);
 		return -EBUSY;
-	request_region(dev->base_addr, SER12_EXTENT, "baycom_ser_fdx");
+	}
 	/*
 	 * set the SIO to 6 Bits/character; during receive,
 	 * the baud rate is set to produce 100 ints/sec
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/mkiss.c linux/drivers/net/hamradio/mkiss.c
--- linux.orig/drivers/net/hamradio/mkiss.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/hamradio/mkiss.c	2002-07-20 01:08:35.000000000 +0000
@@ -347,6 +347,7 @@
 	skb->protocol = htons(ETH_P_AX25);
 	netif_rx(skb);
 	tmp_ax->rx_packets++;
+	tmp_ax->rx_bytes+=count;
 }
 
 /* Encapsulate one AX.25 packet and stuff into a TTY queue. */
@@ -386,6 +387,7 @@
 		ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
 		actual = ax->tty->driver.write(ax->tty, 0, ax->xbuff, count);
 		ax->tx_packets++;
+		ax->tx_bytes+=actual;
 		ax->dev->trans_start = jiffies;
 		ax->xleft = count - actual;
 		ax->xhead = ax->xbuff + actual;
@@ -394,6 +396,7 @@
 		ax->mkiss->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
 		actual = ax->mkiss->tty->driver.write(ax->mkiss->tty, 0, ax->mkiss->xbuff, count);
 		ax->tx_packets++;
+		ax->tx_bytes+=actual;
 		ax->mkiss->dev->trans_start = jiffies;
 		ax->mkiss->xleft = count - actual;
 		ax->mkiss->xhead = ax->mkiss->xbuff + actual;
@@ -709,6 +712,8 @@
 
 	stats.rx_packets     = ax->rx_packets;
 	stats.tx_packets     = ax->tx_packets;
+	stats.rx_bytes	     = ax->rx_bytes;
+	stats.tx_bytes       = ax->tx_bytes;
 	stats.rx_dropped     = ax->rx_dropped;
 	stats.tx_dropped     = ax->tx_dropped;
 	stats.tx_errors      = ax->tx_errors;
@@ -936,7 +941,7 @@
 	memcpy(dev->dev_addr,  ax25_test,  AX25_ADDR_LEN);
 
 	/* New-style flags. */
-	dev->flags      = 0;
+	dev->flags      = IFF_BROADCAST | IFF_MULTICAST;
 
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/mkiss.h linux/drivers/net/hamradio/mkiss.h
--- linux.orig/drivers/net/hamradio/mkiss.h	2000-12-04 01:45:22.000000000 +0000
+++ linux/drivers/net/hamradio/mkiss.h	2002-07-20 01:08:26.000000000 +0000
@@ -31,6 +31,8 @@
 	/* SLIP interface statistics. */
 	unsigned long      rx_packets;		/* inbound frames counter	*/
 	unsigned long      tx_packets;		/* outbound frames counter      */
+        unsigned long      rx_bytes;            /* inbound bytes counter        */
+        unsigned long      tx_bytes;            /* outbound bytes counter       */
 	unsigned long      rx_errors;		/* Parity, etc. errors          */
 	unsigned long      tx_errors;		/* Planned stuff                */
 	unsigned long      rx_dropped;		/* No memory for skb            */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/soundmodem/sm.h linux/drivers/net/hamradio/soundmodem/sm.h
--- linux.orig/drivers/net/hamradio/soundmodem/sm.h	2001-08-15 08:22:15.000000000 +0000
+++ linux/drivers/net/hamradio/soundmodem/sm.h	2002-07-20 01:08:21.000000000 +0000
@@ -158,7 +158,7 @@
  * ===================== diagnostics stuff ===============================
  */
 
-extern inline void diag_trigger(struct sm_state *sm)
+static inline void diag_trigger(struct sm_state *sm)
 {
 	if (sm->diag.ptr < 0)
 		if (!(sm->diag.flags & SM_DIAGFLAG_DCDGATE) || sm->hdrv.hdlcrx.dcd)
@@ -170,7 +170,7 @@
 #define SHRT_MAX ((short)(((unsigned short)(~0U))>>1))
 #define SHRT_MIN (-SHRT_MAX-1)
 
-extern inline void diag_add(struct sm_state *sm, int valinp, int valdemod)
+static inline void diag_add(struct sm_state *sm, int valinp, int valdemod)
 {
 	int val;
 
@@ -189,7 +189,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern inline void diag_add_one(struct sm_state *sm, int val)
+static inline void diag_add_one(struct sm_state *sm, int val)
 {
 	if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
 	     sm->diag.mode != SM_DIAGMODE_DEMOD) ||
@@ -229,14 +229,14 @@
  */
 
 #if 0
-extern inline unsigned int hweight32(unsigned int w)
+static inline unsigned int hweight32(unsigned int w)
 	__attribute__ ((unused));
-extern inline unsigned int hweight16(unsigned short w)
+static inline unsigned int hweight16(unsigned short w)
 	__attribute__ ((unused));
-extern inline unsigned int hweight8(unsigned char w)
+static inline unsigned int hweight8(unsigned char w)
         __attribute__ ((unused));
 
-extern inline unsigned int hweight32(unsigned int w)
+static inline unsigned int hweight32(unsigned int w)
 {
         unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
         res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
@@ -245,7 +245,7 @@
         return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
 }
 
-extern inline unsigned int hweight16(unsigned short w)
+static inline unsigned int hweight16(unsigned short w)
 {
         unsigned short res = (w & 0x5555) + ((w >> 1) & 0x5555);
         res = (res & 0x3333) + ((res >> 2) & 0x3333);
@@ -253,7 +253,7 @@
         return (res & 0x00FF) + ((res >> 8) & 0x00FF);
 }
 
-extern inline unsigned int hweight8(unsigned char w)
+static inline unsigned int hweight8(unsigned char w)
 {
         unsigned short res = (w & 0x55) + ((w >> 1) & 0x55);
         res = (res & 0x33) + ((res >> 2) & 0x33);
@@ -262,12 +262,12 @@
 
 #endif
 
-extern inline unsigned int gcd(unsigned int x, unsigned int y)
+static inline unsigned int gcd(unsigned int x, unsigned int y)
 	__attribute__ ((unused));
-extern inline unsigned int lcm(unsigned int x, unsigned int y)
+static inline unsigned int lcm(unsigned int x, unsigned int y)
 	__attribute__ ((unused));
 
-extern inline unsigned int gcd(unsigned int x, unsigned int y)
+static inline unsigned int gcd(unsigned int x, unsigned int y)
 {
 	for (;;) {
 		if (!x)
@@ -281,7 +281,7 @@
 	}
 }
 
-extern inline unsigned int lcm(unsigned int x, unsigned int y)
+static inline unsigned int lcm(unsigned int x, unsigned int y)
 {
 	return x * y / gcd(x, y);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/soundmodem/sm_afsk1200.c linux/drivers/net/hamradio/soundmodem/sm_afsk1200.c
--- linux.orig/drivers/net/hamradio/soundmodem/sm_afsk1200.c	1997-06-16 23:35:56.000000000 +0000
+++ linux/drivers/net/hamradio/soundmodem/sm_afsk1200.c	2002-07-20 01:08:40.000000000 +0000
@@ -94,7 +94,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern __inline__ int convolution8_u8(const unsigned char *st, const int *coeff, int csum)
+static inline int convolution8_u8(const unsigned char *st, const int *coeff, int csum)
 {
 	int sum = -0x80 * csum;
 	
@@ -111,7 +111,7 @@
 	return sum * sum;
 }
 
-extern __inline__ int convolution8_s16(const short *st, const int *coeff, int csum)
+static inline int convolution8_s16(const short *st, const int *coeff, int csum)
 {
 	int sum = 0;
 	
@@ -128,7 +128,7 @@
 	return sum * sum;
 }
 
-extern __inline__ int do_filter_1200_u8(const unsigned char *buf)
+static inline int do_filter_1200_u8(const unsigned char *buf)
 {
 	int sum = convolution8_u8(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
 	sum += convolution8_u8(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
@@ -137,7 +137,7 @@
 	return sum;
 }
 
-extern __inline__ int do_filter_1200_s16(const short *buf)
+static inline int do_filter_1200_s16(const short *buf)
 {
 	int sum = convolution8_s16(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
 	sum += convolution8_s16(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c linux/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c
--- linux.orig/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c	1997-09-04 20:25:28.000000000 +0000
+++ linux/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c	2002-07-20 01:08:27.000000000 +0000
@@ -104,7 +104,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
+static inline int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
 {
 	int sum = -0x80 * csum;
 	
@@ -127,7 +127,7 @@
 	return sum * sum;
 }
 
-extern __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
+static inline int convolution14_s16(const short *st, const int *coeff, int csum)
 {
 	int sum = 0;
 	
@@ -150,7 +150,7 @@
 	return sum * sum;
 }
 
-extern __inline__ int do_filter_2400_u8(const unsigned char *buf)
+static inline int do_filter_2400_u8(const unsigned char *buf)
 {
 	int sum = convolution14_u8(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
 	sum += convolution14_u8(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
@@ -159,7 +159,7 @@
 	return sum;
 }
 
-extern __inline__ int do_filter_2400_s16(const short *buf)
+static inline int do_filter_2400_s16(const short *buf)
 {
 	int sum = convolution14_s16(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
 	sum += convolution14_s16(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c linux/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c
--- linux.orig/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c	1997-09-04 20:25:28.000000000 +0000
+++ linux/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c	2002-07-20 01:08:29.000000000 +0000
@@ -104,7 +104,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
+static inline int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
 {
 	int sum = -0x80 * csum;
 	
@@ -127,7 +127,7 @@
 	return sum * sum;
 }
 
-extern __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
+static inline int convolution14_s16(const short *st, const int *coeff, int csum)
 {
 	int sum = 0;
 	
@@ -150,7 +150,7 @@
 	return sum * sum;
 }
 
-extern __inline__ int do_filter_2400_u8(const unsigned char *buf)
+static inline int do_filter_2400_u8(const unsigned char *buf)
 {
 	int sum = convolution14_u8(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
 	sum += convolution14_u8(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
@@ -159,7 +159,7 @@
 	return sum;
 }
 
-extern __inline__ int do_filter_2400_s16(const short *buf)
+static inline int do_filter_2400_s16(const short *buf)
 {
 	int sum = convolution14_s16(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
 	sum += convolution14_s16(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/soundmodem/sm_afsk2666.c linux/drivers/net/hamradio/soundmodem/sm_afsk2666.c
--- linux.orig/drivers/net/hamradio/soundmodem/sm_afsk2666.c	1998-06-07 18:13:45.000000000 +0000
+++ linux/drivers/net/hamradio/soundmodem/sm_afsk2666.c	2002-07-20 01:08:39.000000000 +0000
@@ -114,7 +114,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern __inline__ int convolution12_u8(const unsigned char *st, const int *coeff, int csum)
+static inline int convolution12_u8(const unsigned char *st, const int *coeff, int csum)
 {
 	int sum = -0x80 * csum;
 	
@@ -134,7 +134,7 @@
 	return sum;
 }
 
-extern __inline__ int convolution12_s16(const short *st, const int *coeff, int csum)
+static inline int convolution12_s16(const short *st, const int *coeff, int csum)
 {
 	int sum = 0;
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/soundmodem/sm_sbc.c linux/drivers/net/hamradio/soundmodem/sm_sbc.c
--- linux.orig/drivers/net/hamradio/soundmodem/sm_sbc.c	2000-07-18 23:55:19.000000000 +0000
+++ linux/drivers/net/hamradio/soundmodem/sm_sbc.c	2002-07-20 01:08:26.000000000 +0000
@@ -59,7 +59,7 @@
 #define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
 #define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
 
-extern inline int copy_from_user(void *to, const void *from, unsigned long n)
+static inline int copy_from_user(void *to, const void *from, unsigned long n)
 {
         int i = verify_area(VERIFY_READ, from, n);
         if (i)
@@ -68,7 +68,7 @@
         return 0;
 }
 
-extern inline int copy_to_user(void *to, const void *from, unsigned long n)
+static inline int copy_to_user(void *to, const void *from, unsigned long n)
 {
         int i = verify_area(VERIFY_WRITE, to, n);
         if (i)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/soundmodem/sm_wss.c linux/drivers/net/hamradio/soundmodem/sm_wss.c
--- linux.orig/drivers/net/hamradio/soundmodem/sm_wss.c	2001-06-28 00:10:55.000000000 +0000
+++ linux/drivers/net/hamradio/soundmodem/sm_wss.c	2002-07-20 01:08:34.000000000 +0000
@@ -58,7 +58,7 @@
 #define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
 #define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
 
-extern inline int copy_from_user(void *to, const void *from, unsigned long n)
+static inline int copy_from_user(void *to, const void *from, unsigned long n)
 {
         int i = verify_area(VERIFY_READ, from, n);
         if (i)
@@ -67,7 +67,7 @@
         return 0;
 }
 
-extern inline int copy_to_user(void *to, const void *from, unsigned long n)
+static inline int copy_to_user(void *to, const void *from, unsigned long n)
 {
         int i = verify_area(VERIFY_WRITE, to, n);
         if (i)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hamradio/soundmodem/smdma.h linux/drivers/net/hamradio/soundmodem/smdma.h
--- linux.orig/drivers/net/hamradio/soundmodem/smdma.h	2000-12-11 21:22:15.000000000 +0000
+++ linux/drivers/net/hamradio/soundmodem/smdma.h	2002-07-20 01:08:25.000000000 +0000
@@ -52,7 +52,7 @@
 /*
  * returns the number of samples per fragment
  */
-extern __inline__ unsigned int dma_setup(struct sm_state *sm, int send, unsigned int dmanr)
+static inline unsigned int dma_setup(struct sm_state *sm, int send, unsigned int dmanr)
 {
 	if (send) {
 		disable_dma(dmanr);
@@ -79,7 +79,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern __inline__ unsigned int dma_ptr(struct sm_state *sm, int send, unsigned int dmanr,
+static inline unsigned int dma_ptr(struct sm_state *sm, int send, unsigned int dmanr,
 				       unsigned int *curfrag)
 {
 	unsigned int dmaptr, sz, frg, offs;
@@ -120,7 +120,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern __inline__ int dma_end_transmit(struct sm_state *sm, unsigned int curfrag)
+static inline int dma_end_transmit(struct sm_state *sm, unsigned int curfrag)
 {
 	unsigned int diff = (NUM_FRAGMENTS + curfrag - sm->dma.ofragptr) % NUM_FRAGMENTS;
 
@@ -137,7 +137,7 @@
 	return 0;
 }
 
-extern __inline__ void dma_transmit(struct sm_state *sm)
+static inline void dma_transmit(struct sm_state *sm)
 {
 	void *p;
 
@@ -155,13 +155,13 @@
 	}
 }
 
-extern __inline__ void dma_init_transmit(struct sm_state *sm)
+static inline void dma_init_transmit(struct sm_state *sm)
 {
 	sm->dma.ofragptr = 0;
 	sm->dma.ptt_cnt = 0;
 }
 
-extern __inline__ void dma_start_transmit(struct sm_state *sm)
+static inline void dma_start_transmit(struct sm_state *sm)
 {
 	sm->dma.ofragptr = 0;
 	if (sm->dma.o16bit) {
@@ -174,7 +174,7 @@
 	sm->dma.ptt_cnt = 1;
 }
 
-extern __inline__ void dma_clear_transmit(struct sm_state *sm)
+static inline void dma_clear_transmit(struct sm_state *sm)
 {
 	sm->dma.ptt_cnt = 0;
 	memset(sm->dma.obuf, (sm->dma.o16bit) ? 0 : 0x80, sm->dma.ofragsz * NUM_FRAGMENTS);
@@ -182,7 +182,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern __inline__ void dma_receive(struct sm_state *sm, unsigned int curfrag)
+static inline void dma_receive(struct sm_state *sm, unsigned int curfrag)
 {
 	void *p;
 
@@ -205,7 +205,7 @@
 	}
 }
 
-extern __inline__ void dma_init_receive(struct sm_state *sm)
+static inline void dma_init_receive(struct sm_state *sm)
 {
 	sm->dma.ifragptr = 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- linux.orig/drivers/net/hp-plus.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/hp-plus.c	2002-07-20 01:08:24.000000000 +0000
@@ -408,8 +408,10 @@
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
-MODULE_PARM_DESC(io, "HP PC-LAN+ I/O port address(es)");
-MODULE_PARM_DESC(irq, "HP PC-LAN+ IRQ number(s); ignored if properly detected");
+MODULE_PARM_DESC(io, "I/O port address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s); ignored if properly detected");
+MODULE_DESCRIPTION("HP PC-LAN+ ISA ethernet driver");
+MODULE_LICENSE("GPL");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
@@ -457,7 +459,6 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hp.c linux/drivers/net/hp.c
--- linux.orig/drivers/net/hp.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/hp.c	2002-07-20 01:08:28.000000000 +0000
@@ -380,8 +380,10 @@
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
-MODULE_PARM_DESC(io, "HP PC-LAN I/O base address(es)");
-MODULE_PARM_DESC(irq, "HP PC-LAN IRQ number(s) (assigned)");
+MODULE_PARM_DESC(io, "I/O base address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
+MODULE_DESCRIPTION("HP PC-LAN ISA ethernet driver");
+MODULE_LICENSE("GPL");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
@@ -429,7 +431,6 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hp100.c linux/drivers/net/hp100.c
--- linux.orig/drivers/net/hp100.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/net/hp100.c	2002-07-20 01:08:33.000000000 +0000
@@ -210,8 +210,8 @@
 	hp100_ring_t rxring[MAX_RX_PDL];
 	hp100_ring_t txring[MAX_TX_PDL];
 
-	u_int *page_vaddr;	/* Virtual address of allocated page */
 	u_int *page_vaddr_algn;	/* Aligned virtual address of allocated page */
+	u_long whatever_offset;	/* Offset to bus/phys/dma address */
 	int rxrcommit;		/* # Rx PDLs commited to adapter */
 	int txrcommit;		/* # Tx PDLs commited to adapter */
 };
@@ -348,6 +348,18 @@
 static void hp100_RegisterDump(struct net_device *dev);
 #endif
 
+/* Conversion to new PCI API :
+ * Convert an address in a kernel buffer to a bus/phys/dma address.
+ * This work *only* for memory fragments part of lp->page_vaddr,
+ * because it was properly DMA allocated via pci_alloc_consistent(),
+ * so we just need to "retreive" the original mapping to bus/phys/dma
+ * address - Jean II */
+static inline dma_addr_t virt_to_whatever(struct net_device *dev, u32 * ptr)
+{
+  return ((u_long) ptr) +
+    ((struct hp100_private *) (dev->priv))->whatever_offset;
+}
+
 /* TODO: This function should not really be needed in a good design... */
 static void wait(void)
 {
@@ -625,9 +637,20 @@
 			local_mode = 3;
 		} else if (chip == HP100_CHIPID_LASSEN &&
 			   (lsw & (HP100_BM_WRITE | HP100_BM_READ)) == (HP100_BM_WRITE | HP100_BM_READ)) {
+			/* Conversion to new PCI API :
+			 * I don't have the doc, but I assume that the card
+			 * can map the full 32bit address space.
+			 * Also, we can have EISA Busmaster cards (not tested),
+			 * so beware !!! - Jean II */
+			if((bus == HP100_BUS_PCI) &&
+			   (pci_set_dma_mask(pci_dev, 0xffffffff))) {
+				/* Gracefully fallback to shared memory */
+				goto busmasterfail;
+			}
 			printk("hp100: %s: Busmaster mode enabled.\n", dev->name);
 			hp100_outw(HP100_MEM_EN | HP100_IO_EN | HP100_RESET_LB, OPTION_LSW);
 		} else {
+		busmasterfail:
 #ifdef HP100_DEBUG
 			printk("hp100: %s: Card not configured for BM or BM not supported with this card.\n", dev->name);
 			printk("hp100: %s: Trying shared memory mode.\n", dev->name);
@@ -770,11 +793,14 @@
 	 * in the cards shared memory area. But currently, busmaster has been
 	 * implemented/tested only with the lassen chip anyway... */
 	if (lp->mode == 1) {	/* busmaster */
+		dma_addr_t page_baddr;
 		/* Get physically continous memory for TX & RX PDLs    */
-		if ((lp->page_vaddr = kmalloc(MAX_RINGSIZE + 0x0f, GFP_KERNEL)) == NULL)
+		/* Conversion to new PCI API :
+		 * Pages are always aligned and zeroed, no need to it ourself.
+		 * Doc says should be OK for EISA bus as well - Jean II */
+		if ((lp->page_vaddr_algn = pci_alloc_consistent(lp->pci_dev, MAX_RINGSIZE, &page_baddr)) == NULL)
 			return -ENOMEM;
-		lp->page_vaddr_algn = ((u_int *) (((u_int) (lp->page_vaddr) + 0x0f) & ~0x0f));
-		memset(lp->page_vaddr, 0, MAX_RINGSIZE + 0x0f);
+		lp->whatever_offset = ((u_long) page_baddr) - ((u_long) lp->page_vaddr_algn);
 
 #ifdef HP100_DEBUG_BM
 		printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n", dev->name, (u_int) lp->page_vaddr_algn, (u_int) lp->page_vaddr_algn + MAX_RINGSIZE);
@@ -1187,7 +1213,7 @@
 {
 	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 	hp100_ring_t *ringptr;
-	u_int *pageptr;
+	u_int *pageptr;		/* Warning : increment by 4 - Jean II */
 	int i;
 
 #ifdef HP100_DEBUG_B
@@ -1244,7 +1270,7 @@
 		       dev->name, (unsigned) pdlptr);
 
 	ringptr->pdl = pdlptr + 1;
-	ringptr->pdl_paddr = virt_to_bus(pdlptr + 1);
+	ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr + 1);
 	ringptr->skb = (void *) NULL;
 
 	/* 
@@ -1255,7 +1281,7 @@
 	 */
 	/* Note that pdlptr+1 and not pdlptr is the pointer to the PDH */
 
-	*(pdlptr + 2) = (u_int) virt_to_bus(pdlptr);	/* Address Frag 1 */
+	*(pdlptr + 2) = (u_int) virt_to_whatever(dev, pdlptr);	/* Address Frag 1 */
 	*(pdlptr + 3) = 4;	/* Length  Frag 1 */
 
 	return ((((MAX_RX_FRAG * 2 + 2) + 3) / 4) * 4);
@@ -1270,7 +1296,7 @@
 		printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n", dev->name, (unsigned) pdlptr);
 
 	ringptr->pdl = pdlptr;	/* +1; */
-	ringptr->pdl_paddr = virt_to_bus(pdlptr);	/* +1 */
+	ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr);	/* +1 */
 	ringptr->skb = (void *) NULL;
 
 	return ((((MAX_TX_FRAG * 2 + 2) + 3) / 4) * 4);
@@ -1329,8 +1355,10 @@
 				     (unsigned int) ringptr->skb->data);
 #endif
 
+		/* Conversion to new PCI API : map skbuf data to PCI bus.
+		 * Doc says it's OK for EISA as well - Jean II */
 		ringptr->pdl[0] = 0x00020000;	/* Write PDH */
-		ringptr->pdl[3] = ((u_int) virt_to_bus(ringptr->skb->data));
+		ringptr->pdl[3] = ((u_int) pci_map_single(((struct hp100_private *) (dev->priv))->pci_dev, ringptr->skb->data, MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE));
 		ringptr->pdl[4] = MAX_ETHER_SIZE;	/* Length of Data */
 
 #ifdef HP100_DEBUG_BM
@@ -1583,7 +1611,6 @@
 
 	ringptr->skb = skb;
 	ringptr->pdl[0] = ((1 << 16) | i);	/* PDH: 1 Fragment & length */
-	ringptr->pdl[1] = (u32) virt_to_bus(skb->data);	/* 1st Frag: Adr. of data */
 	if (lp->chip == HP100_CHIPID_SHASTA) {
 		/* TODO:Could someone who has the EISA card please check if this works? */
 		ringptr->pdl[2] = i;
@@ -1591,6 +1618,9 @@
 		/* In the PDL, don't use the padded size but the real packet size: */
 		ringptr->pdl[2] = skb->len;	/* 1st Frag: Length of frag */
 	}
+	/* Conversion to new PCI API : map skbuf data to PCI bus.
+	 * Doc says it's OK for EISA as well - Jean II */
+	ringptr->pdl[1] = ((u32) pci_map_single(lp->pci_dev, skb->data, ringptr->pdl[2], PCI_DMA_TODEVICE));	/* 1st Frag: Adr. of data */
 
 	/* Hand this PDL to the card. */
 	hp100_outl(ringptr->pdl_paddr, TX_PDA_L);	/* Low Prio. Queue */
@@ -1639,6 +1669,8 @@
 				dev->name, (u_int) lp->txrhead->skb->data,
 				lp->txrcommit, hp100_inb(TX_PDL), donecount);
 #endif
+		/* Conversion to new PCI API : NOP */
+		pci_unmap_single(lp->pci_dev, (dma_addr_t) lp->txrhead->pdl[1], lp->txrhead->pdl[2], PCI_DMA_TODEVICE);
 		dev_kfree_skb_any(lp->txrhead->skb);
 		lp->txrhead->skb = (void *) NULL;
 		lp->txrhead = lp->txrhead->next;
@@ -1948,6 +1980,9 @@
 		header = *(ptr->pdl - 1);
 		pkt_len = (header & HP100_PKT_LEN_MASK);
 
+		/* Conversion to new PCI API : NOP */
+		pci_unmap_single(lp->pci_dev, (dma_addr_t) ptr->pdl[3], MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE);
+
 #ifdef HP100_DEBUG_BM
 		printk("hp100: %s: rx_bm: header@0x%x=0x%x length=%d, errors=0x%x, dest=0x%x\n",
 				dev->name, (u_int) (ptr->pdl - 1), (u_int) header,
@@ -2908,7 +2943,7 @@
 	release_region(d->base_addr, HP100_REGION_SIZE);
 
 	if (p->mode == 1)	/* busmaster */
-		kfree(p->page_vaddr);
+		pci_free_consistent(p->pci_dev, MAX_RINGSIZE + 0x0f, p->page_vaddr_algn, virt_to_whatever(d, p->page_vaddr_algn));
 	if (p->mem_ptr_virt)
 		iounmap(p->mem_ptr_virt);
 	kfree(d->priv);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/hydra.c linux/drivers/net/hydra.c
--- linux.orig/drivers/net/hydra.c	2001-10-17 04:56:29.000000000 +0000
+++ linux/drivers/net/hydra.c	2002-07-20 01:08:36.000000000 +0000
@@ -121,7 +121,7 @@
 	dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j));
 
     /* We must set the 8390 for word mode. */
-    writeb(0x4b, ioaddr + NE_EN0_DCFG);
+    z_writeb(0x4b, ioaddr + NE_EN0_DCFG);
     start_page = NESM_START_PG;
     stop_page = NESM_STOP_PG;
 
@@ -196,10 +196,10 @@
 			     ((ring_page - NESM_START_PG)<<8);
     ptrs = (short *)hdr;
 
-    *(ptrs++) = readw(hdr_start);
+    *(ptrs++) = z_readw(hdr_start);
     *((short *)hdr) = WORDSWAP(*((short *)hdr));
     hdr_start += 2;
-    *(ptrs++) = readw(hdr_start);
+    *(ptrs++) = z_readw(hdr_start);
     *((short *)hdr+1) = WORDSWAP(*((short *)hdr+1));
 }
 
@@ -216,11 +216,11 @@
     if (xfer_start+count >  mem_base + (NESM_STOP_PG<<8)) {
 	int semi_count = (mem_base + (NESM_STOP_PG<<8)) - xfer_start;
 
-	memcpy_fromio(skb->data,xfer_start,semi_count);
+	z_memcpy_fromio(skb->data,xfer_start,semi_count);
 	count -= semi_count;
-	memcpy_fromio(skb->data+semi_count, mem_base, count);
+	z_memcpy_fromio(skb->data+semi_count, mem_base, count);
     } else
-	memcpy_fromio(skb->data, xfer_start,count);
+	z_memcpy_fromio(skb->data, xfer_start,count);
 
 }
 
@@ -233,7 +233,7 @@
     if (count&1)
 	count++;
 
-    memcpy_toio(mem_base+((start_page - NESM_START_PG)<<8), buf, count);
+    z_memcpy_toio(mem_base+((start_page - NESM_START_PG)<<8), buf, count);
 }
 
 static void __exit hydra_cleanup(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ioc3-eth.c linux/drivers/net/ioc3-eth.c
--- linux.orig/drivers/net/ioc3-eth.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/ioc3-eth.c	2002-07-20 01:08:24.000000000 +0000
@@ -26,6 +26,7 @@
  *    which workarounds are required for them?  Do we ever have Lucent's?
  *  o For the 2.5 branch kill the mii-tool ioctls.
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
@@ -33,6 +34,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/crc32.h>
 
 #ifdef CONFIG_SERIAL
 #include <linux/serial.h>
@@ -340,14 +342,15 @@
 }
 
 /*
- * Read the NIC (Number-In-a-Can) device.
+ * Read the NIC (Number-In-a-Can) device used to store the MAC address on
+ * SN0 / SN00 nodeboards and PCI cards.
  */
-static void ioc3_get_eaddr(struct ioc3_private *ip)
+static void ioc3_get_eaddr_nic(struct ioc3_private *ip)
 {
 	struct ioc3 *ioc3 = ip->regs;
 	u8 nic[14];
-	int i;
 	int tries = 2; /* There may be some problem with the battery?  */
+	int i;
 
 	ioc3_w(gpcr_s, (1 << 21));
 
@@ -370,16 +373,123 @@
 	for (i = 13; i >= 0; i--)
 		nic[i] = nic_read_byte(ioc3);
 
-	printk("Ethernet address is ");
-	for (i = 2; i < 8; i++) {
+	for (i = 2; i < 8; i++)
 		ip->dev->dev_addr[i - 2] = nic[i];
-		printk("%02x", nic[i]);
+}
+
+#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2)
+/*
+ * Get the ether-address on SN1 nodes
+ */
+static void ioc3_get_eaddr_sn(struct ioc3_private *ip)
+{
+	int ibrick_mac_addr_get(nasid_t, char *);
+	struct ioc3 *ioc3 = ip->regs;
+	nasid_t nasid_of_ioc3;
+	char io7eaddr[20];
+	long mac;
+	int err_val;
+
+	/*
+	 * err_val = ibrick_mac_addr_get(get_nasid(), io7eaddr );
+	 * 
+	 * BAD!!  The above call uses get_nasid() and assumes that
+	 * the ioc3 pointed to by struct ioc3 is hooked up to the
+	 * cbrick that we're running on.  The proper way to make this call
+	 * is to figure out which nasid the ioc3 is connected to
+	 * and use that to call ibrick_mac_addr_get.  Below is
+	 * a hack to do just that.
+	 */
+
+	/*
+	 * Get the nasid of the ioc3 from the ioc3's base addr.
+	 * FIXME: the 8 at the end assumes we're in memory mode, 
+	 * not node mode (for that, we'd change it to a 9).
+	 * Is there a call to extract this info from a physical
+	 * addr somewhere in an sn header file already?  If so,
+	 * we should probably use that, or restructure this routine
+	 * to use pci_dev and generic numa nodeid getting stuff.
+	 */
+	nasid_of_ioc3 = (((unsigned long)ioc3 >> 33) & ~(-1 << 8));
+	err_val = ibrick_mac_addr_get(nasid_of_ioc3, io7eaddr );
+
+
+	if (err_val) {
+		/* Couldn't read the eeprom; try OSLoadOptions. */
+		printk("WARNING: ibrick_mac_addr_get failed: %d\n", err_val);
+
+		/* this is where we hardwire the mac address
+ 		 * 1st ibrick had 08:00:69:11:34:75
+ 		 * 2nd ibrick had 08:00:69:11:35:35
+ 		 *
+ 		 * Eagan Machines:
+ 		 *      mankato1 08:00:69:11:BE:95
+ 		 *      warroad  08:00:69:11:bd:60
+ 		 *      duron    08:00:69:11:34:60
+ 		 *
+ 		 * an easy way to get the mac address is to hook
+ 		 * up an ip35, then from L1 do 'cti serial'
+ 		 * and then look for MAC line XXX THIS DOESN"T QUITE WORK!!
+ 		 */
+		printk("ioc3_get_eaddr: setting ethernet address to:\n -----> ");
+		ip->dev->dev_addr[0] = 0x8;
+		ip->dev->dev_addr[1] = 0x0;
+		ip->dev->dev_addr[2] = 0x69;
+		ip->dev->dev_addr[3] = 0x11;
+		ip->dev->dev_addr[4] = 0x34;
+		ip->dev->dev_addr[5] = 0x60;
+	}
+	else {
+		long simple_strtol(const char *,char **,unsigned int);
+
+		mac = simple_strtol(io7eaddr, (char **)0, 16);
+		ip->dev->dev_addr[0] = (mac >> 40) & 0xff;
+		ip->dev->dev_addr[1] = (mac >> 32) & 0xff;
+		ip->dev->dev_addr[2] = (mac >> 24) & 0xff;
+		ip->dev->dev_addr[3] = (mac >> 16) & 0xff;
+		ip->dev->dev_addr[4] = (mac >> 8) & 0xff;
+		ip->dev->dev_addr[5] = mac & 0xff;
+	}
+}
+#endif
+
+/*
+ * Ok, this is hosed by design.  It's necessary to know what machine the
+ * NIC is in in order to know how to read the NIC address.  We also have
+ * to know if it's a PCI card or a NIC in on the node board ...
+ */
+static void ioc3_get_eaddr(struct ioc3_private *ip)
+{
+	void (*do_get_eaddr)(struct ioc3_private *ip) = NULL;
+	int i;
+
+	/*
+	 * We should also use this code for PCI cards, no matter what host
+	 * machine but how to know that we're a PCI card?
+	 */
+#ifdef CONFIG_SGI_IP27
+	do_get_eaddr = ioc3_get_eaddr_nic;
+#endif
+#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2)
+	do_get_eaddr = ioc3_get_eaddr_sn;
+#endif
+
+	if (!do_get_eaddr) {
+		printk(KERN_ERR "Don't know how to read MAC address of this "
+		       "IOC3 NIC\n");
+		return;
+	}
+
+	printk("Ethernet address is ");
+	for (i = 0; i < 6; i++) {
+		printk("%02x", ip->dev->dev_addr[i]);
 		if (i < 7)
 			printk(":");
 	}
 	printk(".\n");
 }
 
+
 /*
  * Caller must hold the ioc3_lock ever for MII readers.  This is also
  * used to protect the transmitter side but it's low contention.
@@ -434,10 +544,10 @@
 
 	skb = ip->rx_skbs[rx_entry];
 	rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
-	w0 = rxb->w0;
+	w0 = be32_to_cpu(rxb->w0);
 
 	while (w0 & ERXBUF_V) {
-		err = rxb->err;				/* It's valid ...  */
+		err = be32_to_cpu(rxb->err);		/* It's valid ...  */
 		if (err & ERXBUF_GOODPKT) {
 			len = ((w0 >> ERXBUF_BYTECNT_SHIFT) & 0x7ff) - 4;
 			skb_trim(skb, len);
@@ -478,8 +588,8 @@
 			ip->stats.rx_frame_errors++;
 next:
 		ip->rx_skbs[n_entry] = new_skb;
-		rxr[n_entry] = (0xa5UL << 56) |
-		                ((unsigned long) rxb & TO_PHYS_MASK);
+		rxr[n_entry] = cpu_to_be32((0xa5UL << 56) |
+		                         ((unsigned long) rxb & TO_PHYS_MASK));
 		rxb->w0 = 0;				/* Clear valid flag */
 		n_entry = (n_entry + 1) & 511;		/* Update erpir */
 
@@ -487,7 +597,7 @@
 		rx_entry = (rx_entry + 1) & 511;
 		skb = ip->rx_skbs[rx_entry];
 		rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
-		w0 = rxb->w0;
+		w0 = be32_to_cpu(rxb->w0);
 	}
 	ioc3->erpir = (n_entry << 3) | ERPIR_ARM;
 	ip->rx_pi = n_entry;
@@ -1189,8 +1299,8 @@
 			/* Because we reserve afterwards. */
 			skb_put(skb, (1664 + RX_OFFSET));
 			rxb = (struct ioc3_erxbuf *) skb->data;
-			rxr[i] = (0xa5UL << 56)
-				| ((unsigned long) rxb & TO_PHYS_MASK);
+			rxr[i] = cpu_to_be64((0xa5UL << 56) |
+			                ((unsigned long) rxb & TO_PHYS_MASK));
 			skb_reserve(skb, RX_OFFSET);
 		}
 		ip->rx_ci = 0;
@@ -1554,8 +1664,8 @@
 			memset(desc->data + len, 0, ETH_ZLEN - len);
 			len = ETH_ZLEN;
 		}
-		desc->cmd    = len | ETXD_INTWHENDONE | ETXD_D0V;
-		desc->bufcnt = len;
+		desc->cmd    = cpu_to_be32(len | ETXD_INTWHENDONE | ETXD_D0V);
+		desc->bufcnt = cpu_to_be32(len);
 	} else if ((data ^ (data + len)) & 0x4000) {
 		unsigned long b2, s1, s2;
 
@@ -1563,16 +1673,20 @@
 		s1 = b2 - data;
 		s2 = data + len - b2;
 
-		desc->cmd    = len | ETXD_INTWHENDONE | ETXD_B1V | ETXD_B2V;
-		desc->bufcnt = (s1 << ETXD_B1CNT_SHIFT) |
-		               (s2 << ETXD_B2CNT_SHIFT);
-		desc->p1     = (0xa5UL << 56) | (data & TO_PHYS_MASK);
-		desc->p2     = (0xa5UL << 56) | (data & TO_PHYS_MASK);
+		desc->cmd    = cpu_to_be32(len | ETXD_INTWHENDONE |
+		                           ETXD_B1V | ETXD_B2V);
+		desc->bufcnt = cpu_to_be32((s1 << ETXD_B1CNT_SHIFT)
+		                           | (s2 << ETXD_B2CNT_SHIFT));
+		desc->p1     = cpu_to_be64((0xa5UL << 56) |
+                                           (data & TO_PHYS_MASK));
+		desc->p2     = cpu_to_be64((0xa5UL << 56) |
+		                           (data & TO_PHYS_MASK));
 	} else {
 		/* Normal sized packet that doesn't cross a page boundary. */
-		desc->cmd    = len | ETXD_INTWHENDONE | ETXD_B1V;
-		desc->bufcnt = len << ETXD_B1CNT_SHIFT;
-		desc->p1     = (0xa5UL << 56) | (data & TO_PHYS_MASK);
+		desc->cmd    = cpu_to_be32(len | ETXD_INTWHENDONE | ETXD_B1V);
+		desc->bufcnt = cpu_to_be32(len << ETXD_B1CNT_SHIFT);
+		desc->p1     = cpu_to_be64((0xa5UL << 56) |
+		                           (data & TO_PHYS_MASK));
 	}
 
 	BARRIER();
@@ -1611,27 +1725,16 @@
  * Given a multicast ethernet address, this routine calculates the
  * address's bit index in the logical address filter mask
  */
-#define CRC_MASK        0xedb88320
 
 static inline unsigned int
 ioc3_hash(const unsigned char *addr)
 {
 	unsigned int temp = 0;
 	unsigned char byte;
-	unsigned int crc;
-	int bits, len;
+	u32 crc;
+	int bits;
 
-	len = ETH_ALEN;
-	for (crc = ~0; --len >= 0; addr++) {
-		byte = *addr;
-		for (bits = 8; --bits >= 0; ) {
-			if ((byte ^ crc) & 1)
-				crc = (crc >> 1) ^ CRC_MASK;
-			else
-				crc >>= 1;
-			byte >>= 1;
-		}
-	}
+	crc = ether_crc_le(ETH_ALEN, addr);
 
 	crc &= 0x3f;    /* bit reverse lowest 6 bits for hash index */
 	for (bits = 6; --bits >= 0; ) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/irda/Config.in linux/drivers/net/irda/Config.in
--- linux.orig/drivers/net/irda/Config.in	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/net/irda/Config.in	2002-07-20 01:08:30.000000000 +0000
@@ -24,6 +24,9 @@
 dep_tristate 'NSC PC87108/PC87338' CONFIG_NSC_FIR  $CONFIG_IRDA
 dep_tristate 'Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
 dep_tristate 'Toshiba Type-O IR Port' CONFIG_TOSHIBA_FIR $CONFIG_IRDA
+if [ "$CONFIG_MIPS" = "y" ]; then
+   dep_tristate 'Alchemy Au1000 SIR/FIR' CONFIG_AU1000_FIR $CONFIG_IRDA
+fi
 if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
 dep_tristate 'SMC IrCC (Experimental)' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA
 dep_tristate 'ALi M5123 FIR (Experimental)' CONFIG_ALI_FIR $CONFIG_IRDA
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/irda/Makefile linux/drivers/net/irda/Makefile
--- linux.orig/drivers/net/irda/Makefile	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/irda/Makefile	2002-07-20 01:08:35.000000000 +0000
@@ -28,5 +28,6 @@
 obj-$(CONFIG_LITELINK_DONGLE)	+= litelink.o
 obj-$(CONFIG_OLD_BELKIN_DONGLE)	+= old_belkin.o
 obj-$(CONFIG_EP7211_IR)		+= ep7211_ir.o
+obj-$(CONFIG_AU1000_FIR)	+= au1k_ir.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/irda/ali-ircc.c linux/drivers/net/irda/ali-ircc.c
--- linux.orig/drivers/net/irda/ali-ircc.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/irda/ali-ircc.c	2002-07-20 01:08:34.000000000 +0000
@@ -291,15 +291,13 @@
         self->io.fifo_size = 16;		/* SIR: 16, FIR: 32 Benjamin 2000/11/1 */
 	
 	/* Reserve the ioports that we need */
-	ret = check_region(self->io.fir_base, self->io.fir_ext);
-	if (ret < 0) { 
+	if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) {
 		WARNING(__FUNCTION__ "(), can't get iobase of 0x%03x\n",
 			self->io.fir_base);
 		dev_self[i] = NULL;
 		kfree(self);
 		return -ENODEV;
 	}
-	request_region(self->io.fir_base, self->io.fir_ext, driver_name);
 
 	/* Initialize QoS for this device */
 	irda_init_max_qos_capabilies(&self->qos);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/irda/au1k_ir.c linux/drivers/net/irda/au1k_ir.c
--- linux.orig/drivers/net/irda/au1k_ir.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/irda/au1k_ir.c	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,867 @@
+/*
+ *
+ * Alchemy Semi Au1000 IrDA driver
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
+ */
+
+#ifndef __mips__
+#error This driver only works with MIPS architectures!
+#endif
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/slab.h>
+#include <linux/rtnetlink.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/au1000.h>
+#include <asm/pb1000.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/irda_device.h>
+#include "net/irda/au1000_ircc.h"
+
+static int au1k_irda_net_init(struct net_device *);
+static int au1k_irda_start(struct net_device *);
+static int au1k_irda_stop(struct net_device *dev);
+static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *);
+static int au1k_irda_rx(struct net_device *);
+static void au1k_irda_interrupt(int, void *, struct pt_regs *);
+static void au1k_tx_timeout(struct net_device *);
+static struct net_device_stats *au1k_irda_stats(struct net_device *);
+static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int);
+static int au1k_irda_set_speed(struct net_device *dev, int speed);
+
+static void *dma_alloc(size_t, dma_addr_t *);
+static void dma_free(void *, size_t);
+
+static int qos_mtt_bits = 0x07;  /* 1 ms or more */
+static struct net_device *ir_devs[NUM_IR_IFF];
+static char version[] __devinitdata =
+    "au1k_ircc:1.0 ppopov@mvista.com\n";
+
+#define RUN_AT(x) (jiffies + (x))
+
+/*
+ * IrDA peripheral bug. You have to read the register
+ * twice to get the right value.
+ */
+u32 read_ir_reg(u32 addr) 
+{ 
+	readl(addr);
+	return readl(addr);
+}
+
+
+/*
+ * Buffer allocation/deallocation routines. The buffer descriptor returned
+ * has the virtual and dma address of a buffer suitable for 
+ * both, receive and transmit operations.
+ */
+static db_dest_t *GetFreeDB(struct au1k_private *aup)
+{
+	db_dest_t *pDB;
+	pDB = aup->pDBfree;
+
+	if (pDB) {
+		aup->pDBfree = pDB->pnext;
+	}
+	return pDB;
+}
+
+static void ReleaseDB(struct au1k_private *aup, db_dest_t *pDB)
+{
+	db_dest_t *pDBfree = aup->pDBfree;
+	if (pDBfree)
+		pDBfree->pnext = pDB;
+	aup->pDBfree = pDB;
+}
+
+
+/*
+  DMA memory allocation, derived from pci_alloc_consistent.
+  However, the Au1000 data cache is coherent (when programmed
+  so), therefore we return KSEG0 address, not KSEG1.
+*/
+static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC | GFP_DMA;
+
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_bus(ret);
+		ret = KSEG0ADDR(ret);
+	}
+	return ret;
+}
+
+
+static void dma_free(void *vaddr, size_t size)
+{
+	vaddr = KSEG0ADDR(vaddr);
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+
+static void 
+setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base)
+{
+	int i;
+	for (i=0; i<NUM_IR_DESC; i++) {
+		aup->rx_ring[i] = (volatile ring_dest_t *) 
+			(rx_base + sizeof(ring_dest_t)*i);
+	}
+	for (i=0; i<NUM_IR_DESC; i++) {
+		aup->tx_ring[i] = (volatile ring_dest_t *) 
+			(tx_base + sizeof(ring_dest_t)*i);
+	}
+}
+
+
+/* 
+ * Device has already been stopped at this point.
+ */
+static void au1k_irda_net_uninit(struct net_device *dev)
+{
+	dev->hard_start_xmit = NULL;
+	dev->open            = NULL;
+	dev->stop            = NULL;
+	dev->do_ioctl        = NULL;
+	dev->get_stats       = NULL;
+	dev->priv            = NULL;
+}
+
+
+static int au1k_irda_init(void)
+{
+	static unsigned version_printed = 0;
+	struct net_device *dev;
+	int err;
+
+	if (version_printed++ == 0) printk(version);
+
+	rtnl_lock();
+	dev = dev_alloc("irda%d", &err);
+	if (dev) {
+		dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */
+		dev->init = au1k_irda_net_init;
+		dev->uninit = au1k_irda_net_uninit;
+		err = register_netdevice(dev);
+
+		if (err)
+			kfree(dev);
+		else
+			ir_devs[0] = dev;
+		printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
+	}
+	rtnl_unlock();
+	return err;
+}
+
+static int au1k_irda_init_iobuf(iobuff_t *io, int size)
+{
+	io->head = kmalloc(size, GFP_KERNEL);
+	if (io->head != NULL) {
+		io->truesize = size;
+		io->in_frame = FALSE;
+		io->state    = OUTSIDE_FRAME;
+		io->data     = io->head;
+	}
+	return io->head ? 0 : -ENOMEM;
+}
+
+static int au1k_irda_net_init(struct net_device *dev)
+{
+	struct au1k_private *aup = NULL;
+	int i, retval = 0, err;
+	db_dest_t *pDB, *pDBfree;
+	unsigned long temp;
+
+	dev->priv = kmalloc(sizeof(struct au1k_private), GFP_KERNEL);
+	if (dev->priv == NULL) {
+		retval = -ENOMEM;
+		goto out;
+	}
+	memset(dev->priv, 0, sizeof(struct au1k_private));
+	aup = dev->priv;
+
+	err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
+	if (err)
+		goto out;
+
+	dev->open = au1k_irda_start;
+	dev->hard_start_xmit = au1k_irda_hard_xmit;
+	dev->stop = au1k_irda_stop;
+	dev->get_stats = au1k_irda_stats;
+	dev->do_ioctl = au1k_irda_ioctl;
+	dev->tx_timeout = au1k_tx_timeout;
+
+	irda_device_setup(dev);
+	irda_init_max_qos_capabilies(&aup->qos);
+
+	/* The only value we must override it the baudrate */
+	aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+		IR_115200|IR_576000 |(IR_4000000 << 8);
+	
+	aup->qos.min_turn_time.bits = qos_mtt_bits;
+	irda_qos_bits_to_value(&aup->qos);
+
+
+	/* Tx ring follows rx ring + 512 bytes */
+	/* we need a 1k aligned buffer */
+	aup->rx_ring[0] = (ring_dest_t *)
+		dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp);
+
+	/* allocate the data buffers */
+	aup->db[0].vaddr = 
+		(void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp);
+	if (!aup->db[0].vaddr || !aup->rx_ring[0]) {
+		retval = -ENOMEM;
+		goto out;
+	}
+
+	setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);
+
+	pDBfree = NULL;
+	pDB = aup->db;
+	for (i=0; i<(2*NUM_IR_DESC); i++) {
+		pDB->pnext = pDBfree;
+		pDBfree = pDB;
+		pDB->vaddr = 
+			(u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i);
+		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+		pDB++;
+	}
+	aup->pDBfree = pDBfree;
+
+	/* attach a data buffer to each descriptor */
+	for (i=0; i<NUM_IR_DESC; i++) {
+		pDB = GetFreeDB(aup);
+		if (!pDB) goto out;
+		aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
+		aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
+		aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
+		aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
+		aup->rx_db_inuse[i] = pDB;
+	}
+	for (i=0; i<NUM_IR_DESC; i++) {
+		pDB = GetFreeDB(aup);
+		if (!pDB) goto out;
+		aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
+		aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
+		aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
+		aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
+		aup->tx_ring[i]->count_0 = 0;
+		aup->tx_ring[i]->count_1 = 0;
+		aup->tx_ring[i]->flags = 0;
+		aup->tx_db_inuse[i] = pDB;
+	}
+	return 0;
+
+out:
+	if (aup->db[0].vaddr) 
+		dma_free((void *)aup->db[0].vaddr, 
+				MAX_BUF_SIZE * 2*NUM_IR_DESC);
+	if (aup->rx_ring[0])
+		kfree((void *)aup->rx_ring[0]);
+	if (aup->rx_buff.head)
+		kfree(aup->rx_buff.head);
+	if (dev->priv != NULL)
+		kfree(dev->priv);
+	unregister_netdevice(dev);
+	printk(KERN_ERR "%s: au1k_init_module failed.  Returns %d\n",
+	       dev->name, retval);
+	return retval;
+}
+
+
+static int au1k_init(struct net_device *dev)
+{
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+	int i;
+	u32 control;
+	u32 ring_address;
+
+	/* bring the device out of reset */
+	control = 0xe; /* coherent, clock enable, one half system clock */
+			  
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
+	control |= 1;
+#endif
+	aup->tx_head = 0;
+	aup->tx_tail = 0;
+	aup->rx_head = 0;
+
+	for (i=0; i<NUM_IR_DESC; i++) {
+		aup->rx_ring[i]->flags = AU_OWN;
+	}
+
+	writel(control, IR_INTERFACE_CONFIG);
+	au_sync_delay(10);
+
+	writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
+	au_sync_delay(1);
+
+	writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN);
+
+	ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
+	writel(ring_address >> 26, IR_RING_BASE_ADDR_H);
+	writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L);
+
+	writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);
+
+	writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
+	writel(0, IR_RING_ADDR_CMPR);
+
+	au1k_irda_set_speed(dev, 9600);
+	return 0;
+}
+
+static int au1k_irda_start(struct net_device *dev)
+{
+	int retval;
+	char hwname[32];
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+
+	MOD_INC_USE_COUNT;
+
+	if ((retval = au1k_init(dev))) {
+		printk(KERN_ERR "%s: error in au1k_init\n", dev->name);
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	if ((retval = request_irq(AU1000_IRDA_TX_INT, &au1k_irda_interrupt, 
+					0, dev->name, dev))) {
+		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
+				dev->name, dev->irq);
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	if ((retval = request_irq(AU1000_IRDA_RX_INT, &au1k_irda_interrupt, 
+					0, dev->name, dev))) {
+		free_irq(AU1000_IRDA_TX_INT, dev);
+		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
+				dev->name, dev->irq);
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	/* Give self a hardware name */
+	sprintf(hwname, "Au1000 SIR/FIR");
+	aup->irlap = irlap_open(dev, &aup->qos, hwname);
+	netif_start_queue(dev);
+
+	writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */
+
+	aup->timer.expires = RUN_AT((3*HZ)); 
+	aup->timer.data = (unsigned long)dev;
+	return 0;
+}
+
+static int au1k_irda_stop(struct net_device *dev)
+{
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+
+	/* disable interrupts */
+	writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2);
+	writel(0, IR_CONFIG_1); 
+	writel(0, IR_INTERFACE_CONFIG); /* disable clock */
+	au_sync();
+
+	if (aup->irlap) {
+		irlap_close(aup->irlap);
+		aup->irlap = NULL;
+	}
+
+	netif_stop_queue(dev);
+	del_timer(&aup->timer);
+
+	/* disable the interrupt */
+	free_irq(AU1000_IRDA_TX_INT, dev);
+	free_irq(AU1000_IRDA_RX_INT, dev);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static void __exit au1k_irda_exit(void)
+{
+	struct net_device *dev = ir_devs[0];
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+
+	if (!dev) {
+		printk(KERN_ERR "au1k_ircc no dev found\n");
+		return;
+	}
+	if (aup->db[0].vaddr)  {
+		dma_free((void *)aup->db[0].vaddr, 
+				MAX_BUF_SIZE * 2*NUM_IR_DESC);
+		aup->db[0].vaddr = 0;
+	}
+	if (aup->rx_ring[0]) {
+		dma_free((void *)aup->rx_ring[0], 
+				2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
+		aup->rx_ring[0] = 0;
+	}
+	rtnl_lock();
+	unregister_netdevice(dev);
+	rtnl_unlock();
+	ir_devs[0] = 0;
+}
+
+
+static inline void 
+update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
+{
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+	struct net_device_stats *ps = &aup->stats;
+
+	ps->tx_packets++;
+	ps->tx_bytes += pkt_len;
+
+	if (status & IR_TX_ERROR) {
+		ps->tx_errors++;
+		ps->tx_aborted_errors++;
+	}
+}
+
+
+static void au1k_tx_ack(struct net_device *dev)
+{
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+	volatile ring_dest_t *ptxd;
+
+	ptxd = aup->tx_ring[aup->tx_tail];
+	while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
+		update_tx_stats(dev, ptxd->flags, 
+				ptxd->count_1<<8 | ptxd->count_0);
+		ptxd->count_0 = 0;
+		ptxd->count_1 = 0;
+		au_sync();
+
+		aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
+		ptxd = aup->tx_ring[aup->tx_tail];
+
+		if (aup->tx_full) {
+			aup->tx_full = 0;
+			netif_wake_queue(dev);
+		}
+	}
+
+	if (aup->tx_tail == aup->tx_head) {
+		if (aup->newspeed) {
+			au1k_irda_set_speed(dev, aup->newspeed);
+			aup->newspeed = 0;
+		}
+		else {
+			writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE, 
+					IR_CONFIG_1); 
+			au_sync();
+			writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE, 
+					IR_CONFIG_1); 
+			writel(0, IR_RING_PROMPT);
+			au_sync();
+		}
+	}
+}
+
+
+/*
+ * Au1000 transmit routine.
+ */
+static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+	int speed = irda_get_next_speed(skb);
+	volatile ring_dest_t *ptxd;
+	u32 len;
+
+	u32 flags;
+	db_dest_t *pDB;
+
+	if (speed != aup->speed && speed != -1) {
+		aup->newspeed = speed;
+	}
+
+	if ((skb->len == 0) && (aup->newspeed)) {
+		if (aup->tx_tail == aup->tx_head) {
+			au1k_irda_set_speed(dev, speed);
+			aup->newspeed = 0;
+		}
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	ptxd = aup->tx_ring[aup->tx_head];
+	flags = ptxd->flags;
+
+	if (flags & AU_OWN) {
+		printk(KERN_INFO "%s: tx_full\n", dev->name);
+		netif_stop_queue(dev);
+		aup->tx_full = 1;
+		return 1;
+	}
+	else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
+		printk(KERN_INFO "%s: tx_full\n", dev->name);
+		netif_stop_queue(dev);
+		aup->tx_full = 1;
+		return 1;
+	}
+
+	pDB = aup->tx_db_inuse[aup->tx_head];
+
+#if 0
+	if (read_ir_reg(IR_RX_BYTE_CNT) != 0) {
+		printk("tx warning: rx byte cnt %x\n", 
+				read_ir_reg(IR_RX_BYTE_CNT));
+	}
+#endif
+	
+	if (aup->speed == 4000000) {
+		/* FIR */
+		memcpy((void *)pDB->vaddr, skb->data, skb->len);
+		ptxd->count_0 = skb->len & 0xff;
+		ptxd->count_1 = (skb->len >> 8) & 0xff;
+	}
+	else {
+		/* SIR */
+		len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE);
+		ptxd->count_0 = len & 0xff;
+		ptxd->count_1 = (len >> 8) & 0xff;
+		ptxd->flags |= IR_DIS_CRC;
+	}
+	ptxd->flags |= AU_OWN;
+	au_sync();
+
+	writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1); 
+	writel(0, IR_RING_PROMPT);
+	au_sync();
+
+	dev_kfree_skb(skb);
+	aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1);
+	dev->trans_start = jiffies;
+	return 0;
+}
+
+
+static inline void 
+update_rx_stats(struct net_device *dev, u32 status, u32 count)
+{
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+	struct net_device_stats *ps = &aup->stats;
+
+	ps->rx_packets++;
+
+	if (status & IR_RX_ERROR) {
+		ps->rx_errors++;
+		if (status & (IR_PHY_ERROR|IR_FIFO_OVER))
+			ps->rx_missed_errors++;
+		if (status & IR_MAX_LEN)
+			ps->rx_length_errors++;
+		if (status & IR_CRC_ERROR)
+			ps->rx_crc_errors++;
+	}
+	else 
+		ps->rx_bytes += count;
+}
+
+/*
+ * Au1000 receive routine.
+ */
+static int au1k_irda_rx(struct net_device *dev)
+{
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+	struct sk_buff *skb;
+	volatile ring_dest_t *prxd;
+	u32 flags, count;
+	db_dest_t *pDB;
+
+	prxd = aup->rx_ring[aup->rx_head];
+	flags = prxd->flags;
+
+	while (!(flags & AU_OWN))  {
+		pDB = aup->rx_db_inuse[aup->rx_head];
+		count = prxd->count_1<<8 | prxd->count_0;
+		if (!(flags & IR_RX_ERROR))  {
+			/* good frame */
+			update_rx_stats(dev, flags, count);
+			skb=alloc_skb(count+1,GFP_ATOMIC);
+			if (skb == NULL) {
+				aup->stats.rx_dropped++;
+				continue;
+			}
+			skb_reserve(skb, 1);
+			if (aup->speed == 4000000)
+				skb_put(skb, count);
+			else
+				skb_put(skb, count-2);
+			memcpy(skb->data, (void *)pDB->vaddr, count-2);
+			skb->dev = dev;
+			skb->mac.raw = skb->data;
+			skb->protocol = htons(ETH_P_IRDA);
+			netif_rx(skb);
+			prxd->count_0 = 0;
+			prxd->count_1 = 0;
+		}
+		prxd->flags |= AU_OWN;
+		aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
+		writel(0, IR_RING_PROMPT);
+		au_sync();
+
+		/* next descriptor */
+		prxd = aup->rx_ring[aup->rx_head];
+		flags = prxd->flags;
+		dev->last_rx = jiffies;
+
+	}
+	return 0;
+}
+
+
+void au1k_irda_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+
+	if (dev == NULL) {
+		printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
+		return;
+	}
+
+	writel(0, IR_INT_CLEAR); /* ack irda interrupts */
+
+	au1k_irda_rx(dev);
+	au1k_tx_ack(dev);
+}
+
+
+/*
+ * The Tx ring has been full longer than the watchdog timeout
+ * value. The transmitter must be hung?
+ */
+static void au1k_tx_timeout(struct net_device *dev)
+{
+	u32 speed;
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+
+	printk(KERN_ERR "%s: tx timeout\n", dev->name);
+	speed = aup->speed;
+	aup->speed = 0;
+	au1k_irda_set_speed(dev, speed);
+	aup->tx_full = 0;
+	netif_wake_queue(dev);
+}
+
+
+/*
+ * Set the IrDA communications speed.
+ */
+static int 
+au1k_irda_set_speed(struct net_device *dev, int speed)
+{
+	unsigned long flags;
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+	u32 control;
+	int ret = 0, timeout = 10, i;
+	volatile ring_dest_t *ptxd;
+
+	if (speed == aup->speed)
+		return ret;
+
+	save_flags(flags);
+	cli();
+
+	/* disable PHY first */
+	writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE);
+
+	/* disable RX/TX */
+	writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE), 
+			IR_CONFIG_1);
+	au_sync_delay(1);
+	while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) {
+		mdelay(1);
+		if (!timeout--) {
+			printk(KERN_ERR "%s: rx/tx disable timeout\n",
+					dev->name);
+			break;
+		}
+	}
+
+	/* disable DMA */
+	writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1);
+	au_sync_delay(1);
+
+	/* 
+	 *  After we disable tx/rx. the index pointers
+ 	 * go back to zero.
+	 */
+	aup->tx_head = aup->tx_tail = aup->rx_head = 0;
+	for (i=0; i<NUM_IR_DESC; i++) {
+		ptxd = aup->tx_ring[i];
+		ptxd->flags = 0;
+		ptxd->count_0 = 0;
+		ptxd->count_1 = 0;
+	}
+
+	for (i=0; i<NUM_IR_DESC; i++) {
+		ptxd = aup->rx_ring[i];
+		ptxd->count_0 = 0;
+		ptxd->count_1 = 0;
+		ptxd->flags = AU_OWN;
+	}
+
+	if (speed == 4000000)
+		writel(1<<13, CPLD_AUX1);
+	else
+		writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
+
+	switch (speed) {
+	case 9600:	
+		writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
+		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		break;
+	case 19200:	
+		writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
+		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		break;
+	case 38400:
+		writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
+		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		break;
+	case 57600:	
+		writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
+		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		break;
+	case 115200: 
+		writel(12<<5, IR_WRITE_PHY_CONFIG); 
+		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		break;
+	case 4000000:
+		writel(0xF, IR_WRITE_PHY_CONFIG);
+		writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1); 
+		break;
+	default:
+		printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
+		ret = -EINVAL;
+		break;
+	}
+
+	aup->speed = speed;
+	writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE);
+	au_sync();
+
+	control = read_ir_reg(IR_ENABLE);
+	writel(0, IR_RING_PROMPT);
+	au_sync();
+
+	if (control & (1<<14)) {
+		printk(KERN_ERR "%s: configuration error\n", dev->name);
+	}
+	else {
+		if (control & (1<<11))
+			printk(KERN_INFO "%s Valid SIR config\n", dev->name);
+		if (control & (1<<12))
+			printk(KERN_INFO "%s Valid MIR config\n", dev->name);
+		if (control & (1<<13))
+			printk(KERN_INFO "%s Valid FIR config\n", dev->name);
+		if (control & (1<<10))
+			printk(KERN_INFO "%s TX enabled\n", dev->name);
+		if (control & (1<<9))
+			printk(KERN_INFO "%s RX enabled\n", dev->name);
+	}
+
+	restore_flags(flags);
+	return ret;
+}
+
+static int 
+au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
+{
+	struct if_irda_req *rq = (struct if_irda_req *)ifreq;
+	struct au1k_private *aup = dev->priv;
+	int ret = -EOPNOTSUPP;
+
+	switch (cmd) {
+	case SIOCSBANDWIDTH:
+		if (capable(CAP_NET_ADMIN)) {
+			/*
+			 * We are unable to set the speed if the
+			 * device is not running.
+			 */
+			if (aup->open)
+				ret = au1k_irda_set_speed(dev,
+						rq->ifr_baudrate);
+			else {
+				printk(KERN_ERR "%s ioctl: !netif_running\n",
+						dev->name);
+				ret = 0;
+			}
+		}
+		break;
+
+	case SIOCSMEDIABUSY:
+		ret = -EPERM;
+		if (capable(CAP_NET_ADMIN)) {
+			irda_device_set_media_busy(dev, TRUE);
+			ret = 0;
+		}
+		break;
+
+	case SIOCGRECEIVING:
+		rq->ifr_receiving = 0;
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+
+static struct net_device_stats *au1k_irda_stats(struct net_device *dev)
+{
+	struct au1k_private *aup = (struct au1k_private *) dev->priv;
+	return &aup->stats;
+}
+
+#ifdef MODULE
+MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
+MODULE_DESCRIPTION("Au1000 IrDA Device Driver");
+
+module_init(au1k_irda_init);
+module_exit(au1k_irda_exit);
+#endif /* MODULE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/irda/irda-usb.c linux/drivers/net/irda/irda-usb.c
--- linux.orig/drivers/net/irda/irda-usb.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/irda/irda-usb.c	2002-07-20 01:08:37.000000000 +0000
@@ -378,10 +378,17 @@
 		return 0;
 	}
 
-	/* Make room for IrDA-USB header (note skb->len += USB_IRDA_HEADER) */
-	if (skb_cow(skb, USB_IRDA_HEADER)) {
-		dev_kfree_skb(skb);
-		return 0;
+	/* Make sure there is room for IrDA-USB header. The actual
+	 * allocation will be done lower in skb_push().
+	 * Also, we don't use directly skb_cow(), because it require
+	 * headroom >= 16, which force unnecessary copies - Jean II */
+	if (skb_headroom(skb) < USB_IRDA_HEADER) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), Insuficient skb headroom.\n");
+		if (skb_cow(skb, USB_IRDA_HEADER)) {
+			WARNING(__FUNCTION__ "(), failed skb_cow() !!!\n");
+			dev_kfree_skb(skb);
+			return 0;
+		}
 	}
 
 	spin_lock_irqsave(&self->lock, flags);
@@ -432,7 +439,7 @@
 #ifdef IU_USB_MIN_RTT
 			/* Factor in USB delays -> Get rid of udelay() that
 			 * would be lost in the noise - Jean II */
-			diff -= IU_USB_MIN_RTT;
+			diff += IU_USB_MIN_RTT;
 #endif /* IU_USB_MIN_RTT */
 			if (diff < 0)
 				diff += 1000000;
@@ -848,8 +855,8 @@
 	/* Submit the idle URB to replace the URB we've just received */
 	irda_usb_submit(self, skb, self->idle_rx_urb);
 	/* Recycle Rx URB : Now, the idle URB is the present one */
-	self->idle_rx_urb = purb;
 	purb->context = NULL;
+	self->idle_rx_urb = purb;
 }
 
 /*------------------------------------------------------------------*/
@@ -952,13 +959,17 @@
 	/* Allow IrLAP to send data to us */
 	netif_start_queue(netdev);
 
+	/* We submit all the Rx URB except for one that we keep idle.
+	 * Need to be initialised before submitting other USBs, because
+	 * in some cases as soon as we submit the URBs the USB layer
+	 * will trigger a dummy receive - Jean II */
+	self->idle_rx_urb = &(self->rx_urb[IU_MAX_ACTIVE_RX_URBS]);
+	self->idle_rx_urb->context = NULL;
+
 	/* Now that we can pass data to IrLAP, allow the USB layer
 	 * to send us some data... */
 	for (i = 0; i < IU_MAX_ACTIVE_RX_URBS; i++)
 		irda_usb_submit(self, NULL, &(self->rx_urb[i]));
-	/* Note : we submit all the Rx URB except for one - Jean II */
-	self->idle_rx_urb = &(self->rx_urb[IU_MAX_ACTIVE_RX_URBS]);
-	self->idle_rx_urb->context = NULL;
 
 	/* Ready to play !!! */
 	MOD_INC_USE_COUNT;
@@ -1582,3 +1593,4 @@
 MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
 MODULE_AUTHOR("Roman Weissgaerber <weissg@vienna.at>, Dag Brattli <dag@brattli.net> and Jean Tourrilhes <jt@hpl.hp.com>");
 MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); 
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/irda/sa1100_ir.c linux/drivers/net/irda/sa1100_ir.c
--- linux.orig/drivers/net/irda/sa1100_ir.c	2001-10-25 20:53:47.000000000 +0000
+++ linux/drivers/net/irda/sa1100_ir.c	2002-07-20 01:08:33.000000000 +0000
@@ -132,7 +132,7 @@
 	Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
 
 	/*
-	 * Enable the DMA, receiver and recieve interrupt.
+	 * Enable the DMA, receiver and receive interrupt.
 	 */
 	sa1100_dma_flush_all(si->rxdma);
 	sa1100_dma_queue_buffer(si->rxdma, NULL, si->rxbuf_dma, HPSIR_MAX_RXLEN);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/lance.c linux/drivers/net/lance.c
--- linux.orig/drivers/net/lance.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/lance.c	2002-07-20 01:08:25.000000000 +0000
@@ -354,7 +354,7 @@
    board probes now that kmalloc() can allocate ISA DMA-able regions.
    This also allows the LANCE driver to be used as a module.
    */
-int lance_probe(struct net_device *dev)
+int __init lance_probe(struct net_device *dev)
 {
 	int *port, result;
 
@@ -383,7 +383,7 @@
 					return 0;
 				}
 			}
-			release_resource(r);
+			release_region(ioaddr, LANCE_TOTAL_SIZE);
 		}
 	}
 	return -ENODEV;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/lne390.c linux/drivers/net/lne390.c
--- linux.orig/drivers/net/lne390.c	2001-09-30 19:26:06.000000000 +0000
+++ linux/drivers/net/lne390.c	2002-07-20 01:08:39.000000000 +0000
@@ -381,9 +381,10 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
-MODULE_PARM_DESC(io, "LNE390 I/O base address(es)");
-MODULE_PARM_DESC(irq, "LNE390 IRQ number(s)");
-MODULE_PARM_DESC(mem, "LNE390 memory base address(es)");
+MODULE_PARM_DESC(io, "I/O base address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(mem, "memory base address(es)");
+MODULE_DESCRIPTION("Mylex LNE390A/B EISA Ethernet driver");
 MODULE_LICENSE("GPL");
 
 int init_module(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/mace.c linux/drivers/net/mace.c
--- linux.orig/drivers/net/mace.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/mace.c	2002-07-20 01:08:30.000000000 +0000
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/prom.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
@@ -549,17 +550,12 @@
     return &p->stats;
 }
 
-/*
- * CRC polynomial - used in working out multicast filter bits.
- */
-#define CRC_POLY	0xedb88320
-
 static void mace_set_multicast(struct net_device *dev)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
     volatile struct mace *mb = mp->mace;
-    int i, j, k, b;
-    unsigned long crc;
+    int i, j;
+    u32 crc;
 
     mp->maccc &= ~PROM;
     if (dev->flags & IFF_PROMISC) {
@@ -575,17 +571,7 @@
 	    for (i = 0; i < 8; i++)
 		multicast_filter[i] = 0;
 	    for (i = 0; i < dev->mc_count; i++) {
-		crc = ~0;
-		for (j = 0; j < 6; ++j) {
-		    b = dmi->dmi_addr[j];
-		    for (k = 0; k < 8; ++k) {
-			if ((crc ^ b) & 1)
-			    crc = (crc >> 1) ^ CRC_POLY;
-			else
-			    crc >>= 1;
-			b >>= 1;
-		    }
-		}
+	        crc = ether_crc_le(6, dmi->dmi_addr);
 		j = crc >> 26;	/* bit number in multicast_filter */
 		multicast_filter[j >> 3] |= 1 << (j & 7);
 		dmi = dmi->next;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/macmace.c linux/drivers/net/macmace.c
--- linux.orig/drivers/net/macmace.c	2001-04-12 19:15:25.000000000 +0000
+++ linux/drivers/net/macmace.c	2002-07-20 01:08:32.000000000 +0000
@@ -10,6 +10,8 @@
  *
  *	Copyright (C) 1996 Paul Mackerras.
  *	Copyright (C) 1998 Alan Cox <alan@redhat.com>
+ *
+ *	Modified heavily by Joshua M. Thompson based on Dave Huang's NetBSD driver
  */
 
 
@@ -18,21 +20,20 @@
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
 #include <linux/string.h>
-#include <linux/timer.h>
+#include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_psc.h>
+#include <asm/page.h>
 #include "mace.h"
 
+#define N_TX_RING	1
 #define N_RX_RING	8
-#define N_TX_RING	2
-#define MAX_TX_ACTIVE	1
-#define NCMDS_TX	1	/* dma commands per element in tx ring */
-#define RX_BUFLEN	(ETH_FRAME_LEN + 8)
-#define TX_TIMEOUT	HZ	/* 1 second */
+#define N_RX_PAGES	((N_RX_RING * 0x0800 + PAGE_SIZE - 1) / PAGE_SIZE)
+#define TX_TIMEOUT	HZ
 
 /* Bits in transmit DMA status */
 #define TX_DMA_ERR	0x80
@@ -42,22 +43,19 @@
 #define MACE_BASE	(void *)(0x50F1C000)
 #define MACE_PROM	(void *)(0x50F08001)
 
-struct mace68k_data
-{
+struct mace_data {
 	volatile struct mace *mace;
 	volatile unsigned char *tx_ring;
+	volatile unsigned char *tx_ring_phys;
 	volatile unsigned char *rx_ring;
+	volatile unsigned char *rx_ring_phys;
 	int dma_intr;
-	unsigned char maccc;
 	struct net_device_stats stats;
-	struct timer_list tx_timeout;
-	int timeout_active;
-	int rx_slot, rx_done;
-	int tx_slot, tx_count;
+	int rx_slot, rx_tail;
+	int tx_slot, tx_sloti, tx_count;
 };
 
-struct mace_frame
-{
+struct mace_frame {
 	u16	len;
 	u16	status;
 	u16	rntpc;
@@ -68,271 +66,227 @@
 	/* And frame continues.. */
 };
 
-#define PRIV_BYTES	sizeof(struct mace68k_data)
+#define PRIV_BYTES	sizeof(struct mace_data)
 
 extern void psc_debug_dump(void);
 
-static int mace68k_open(struct net_device *dev);
-static int mace68k_close(struct net_device *dev);
-static int mace68k_xmit_start(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *mace68k_stats(struct net_device *dev);
-static void mace68k_set_multicast(struct net_device *dev);
-static void mace68k_reset(struct net_device *dev);
-static int mace68k_set_address(struct net_device *dev, void *addr);
-static void mace68k_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void mace68k_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
-static void mace68k_set_timeout(struct net_device *dev);
-static void mace68k_tx_timeout(unsigned long data);
+static int mace_open(struct net_device *dev);
+static int mace_close(struct net_device *dev);
+static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static struct net_device_stats *mace_stats(struct net_device *dev);
+static void mace_set_multicast(struct net_device *dev);
+static int mace_set_address(struct net_device *dev, void *addr);
+static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
+static void mace_tx_timeout(struct net_device *dev);
 
-/*
- *	PSC DMA engine control. As you'd expect on a macintosh its
- *	more like a lawnmower engine supplied without instructions
- *
- *	The basic theory of operation appears to be as follows.
- *
- *	There are two sets of receive DMA registers and two sets
- *	of transmit DMA registers. Instead of the more traditional
- *	"ring buffer" approach the Mac68K DMA engine expects you
- *	to be loading one chain while the other runs, and then
- *	to flip register set. Each entry in the chain is a fixed 
- *	length.
- */
+/* Bit-reverse one byte of an ethernet hardware address. */
+
+static int bitrev(int b)
+{
+	int d = 0, i;
+
+	for (i = 0; i < 8; ++i, b >>= 1) {
+		d = (d << 1) | (b & 1);
+	}
+
+	return d;
+}
 
 /*
- *	Load a receive DMA channel with a base address and ring length
+ * Load a receive DMA channel with a base address and ring length
  */
-  
-static void psc_load_rxdma_base(int set, void *base)
+
+static void mace_load_rxdma_base(struct net_device *dev, int set)
 {
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+
 	psc_write_word(PSC_ENETRD_CMD + set, 0x0100);
-	psc_write_long(PSC_ENETRD_ADDR + set, (u32)base);
+	psc_write_long(PSC_ENETRD_ADDR + set, (u32) mp->rx_ring_phys);
 	psc_write_long(PSC_ENETRD_LEN + set, N_RX_RING);
 	psc_write_word(PSC_ENETRD_CMD + set, 0x9800);
+	mp->rx_tail = 0;
 }
 
 /*
- *	Reset the receive DMA subsystem
+ * Reset the receive DMA subsystem
  */
-  
-static void mace68k_rxdma_reset(struct net_device *dev)
+
+static void mace_rxdma_reset(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mace = mp->mace;
-	u8 mcc = mace->maccc;
+	u8 maccc = mace->maccc;
 	
-	/*
-	 *	Turn off receive
-	 */
-	 
-	mcc&=~ENRCV;
-	mace->maccc=mcc;
-	
-	/*
-	 *	Program the DMA
-	 */
+	mace->maccc = maccc & ~ENRCV;
 	
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
-	psc_load_rxdma_base(0x0, (void *)virt_to_bus(mp->rx_ring));
+	mace_load_rxdma_base(dev, 0x00);
 	psc_write_word(PSC_ENETRD_CTL, 0x0400);
 	
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
-	psc_load_rxdma_base(0x10, (void *)virt_to_bus(mp->rx_ring));
+	mace_load_rxdma_base(dev, 0x10);
 	psc_write_word(PSC_ENETRD_CTL, 0x0400);
 	
-	mace->maccc=mcc|ENRCV;
-	
-#if 0
-	psc_write_word(PSC_ENETRD_CTL, 0x9800);
-	psc_write_word(PSC_ENETRD_CTL+0x10, 0x9800);
-#endif
+	mace->maccc = maccc;
+	mp->rx_slot = 0;
+
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET0, 0x9800);
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET1, 0x9800);
 }
 
 /*
- *	Reset the transmit DMA subsystem
+ * Reset the transmit DMA subsystem
  */
  
-static void mace68k_txdma_reset(struct net_device *dev)
+static void mace_txdma_reset(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mace = mp->mace;
-	u8 mcc = mace->maccc;
+	u8 maccc;
 
-	psc_write_word(PSC_ENETWR_CTL,0x8800);
-	
-	mace->maccc = mcc&~ENXMT;
-	psc_write_word(PSC_ENETWR_CTL,0x0400);
-	mace->maccc = mcc;
+	psc_write_word(PSC_ENETWR_CTL, 0x8800);
+
+	maccc = mace->maccc;
+	mace->maccc = maccc & ~ENXMT;
+
+	mp->tx_slot = mp->tx_sloti = 0;
+	mp->tx_count = N_TX_RING;
+
+	psc_write_word(PSC_ENETWR_CTL, 0x0400);
+	mace->maccc = maccc;
 }
 
 /*
- *	Disable DMA
+ * Disable DMA
  */
  
-static void mace68k_dma_off(struct net_device *dev)
+static void mace_dma_off(struct net_device *dev)
 {
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
 	psc_write_word(PSC_ENETRD_CTL, 0x1000);
-	psc_write_word(PSC_ENETRD_CMD, 0x1100);
-	psc_write_word(PSC_ENETRD_CMD+0x10, 0x1100);
-                                        
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET0, 0x1100);
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET1, 0x1100);
+
 	psc_write_word(PSC_ENETWR_CTL, 0x8800);
 	psc_write_word(PSC_ENETWR_CTL, 0x1000);
-	psc_write_word(PSC_ENETWR_CMD, 0x1100);
-	psc_write_word(PSC_ENETWR_CMD+0x10, 0x1100);
-}
-
-/* Bit-reverse one byte of an ethernet hardware address. */
-
-static int bitrev(int b)
-{
-    int d = 0, i;
-
-    for (i = 0; i < 8; ++i, b >>= 1)
-	d = (d << 1) | (b & 1);
-    return d;
+	psc_write_word(PSC_ENETWR_CMD + PSC_SET0, 0x1100);
+	psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100);
 }
 
 /*
- * 	Not really much of a probe. The hardware table tells us if this
- *	model of Macintrash has a MACE (AV macintoshes)
+ * Not really much of a probe. The hardware table tells us if this
+ * model of Macintrash has a MACE (AV macintoshes)
  */
  
-int mace68k_probe(struct net_device *unused)
+int mace_probe(struct net_device *unused)
 {
 	int j;
 	static int once;
-	struct mace68k_data *mp;
+	struct mace_data *mp;
 	unsigned char *addr;
 	struct net_device *dev;
 	unsigned char checksum = 0;
+	static int found = 0;
 	
-	/*
-	 *	There can be only one...
-	 */
-	 
-	if (once) return -ENODEV;
-	
-	once = 1;
+	if (found || macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV;
 
-	if (macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV;
+	found = 1;	/* prevent 'finding' one on every device probe */
 
-	printk("MACE ethernet should be present ");
-	
 	dev = init_etherdev(0, PRIV_BYTES);
-	if(dev==NULL)
-	{
-		printk("no free memory.\n");
-		return -ENOMEM;
-	}		
-	mp = (struct mace68k_data *) dev->priv;
+	if (!dev) return -ENOMEM;
+
+	mp = (struct mace_data *) dev->priv;
 	dev->base_addr = (u32)MACE_BASE;
 	mp->mace = (volatile struct mace *) MACE_BASE;
 	
-	printk("at 0x%p", mp->mace);
-	
-	/*
-	 *	16K RX ring and 4K TX ring should do nicely
-	 */
-
-	mp->rx_ring=(void *)__get_free_pages(GFP_KERNEL, 2);
-	mp->tx_ring=(void *)__get_free_page(GFP_KERNEL);
-	
-	printk(".");
-	
-	if(mp->tx_ring==NULL || mp->rx_ring==NULL)
-	{
-		if(mp->tx_ring)
-			free_page((u32)mp->tx_ring);
-//		if(mp->rx_ring)
-//			__free_pages(mp->rx_ring,2);
-		printk("\nNo memory for ring buffers.\n");
-		return -ENOMEM;
-	}
-
-	/* We want the receive data to be uncached. We dont care about the
-	   byte reading order */
-
-	printk(".");	
-	kernel_set_cachemode((void *)mp->rx_ring, 16384, IOMAP_NOCACHE_NONSER);	
-	
-	printk(".");	
-	/* The transmit buffer needs to be write through */
-	kernel_set_cachemode((void *)mp->tx_ring, 4096, IOMAP_WRITETHROUGH);
-
-	printk(" Ok\n");	
 	dev->irq = IRQ_MAC_MACE;
-	printk(KERN_INFO "%s: MACE at", dev->name);
+	mp->dma_intr = IRQ_MAC_MACE_DMA;
 
 	/*
-	 *	The PROM contains 8 bytes which total 0xFF when XOR'd
-	 *	together. Due to the usual peculiar apple brain damage
-	 *	the bytes are spaced out in a strange boundary and the
-	 * 	bits are reversed.
+	 * The PROM contains 8 bytes which total 0xFF when XOR'd
+	 * together. Due to the usual peculiar apple brain damage
+	 * the bytes are spaced out in a strange boundary and the
+	 * bits are reversed.
 	 */
 
 	addr = (void *)MACE_PROM;
 		 
-	for (j = 0; j < 6; ++j)
-	{
+	for (j = 0; j < 6; ++j) {
 		u8 v=bitrev(addr[j<<4]);
-		checksum^=v;
+		checksum ^= v;
 		dev->dev_addr[j] = v;
-		printk("%c%.2x", (j ? ':' : ' '), dev->dev_addr[j]);
 	}
-	for (; j < 8; ++j)
-	{
-		checksum^=bitrev(addr[j<<4]);
+	for (; j < 8; ++j) {
+		checksum ^= bitrev(addr[j<<4]);
 	}
 	
-	if(checksum!=0xFF)
-	{
-		printk(" (invalid checksum)\n");
-		return -ENODEV;
-	}		
-	printk("\n");
+	if (checksum != 0xFF) return -ENODEV;
 
 	memset(&mp->stats, 0, sizeof(mp->stats));
-	init_timer(&mp->tx_timeout);
-	mp->timeout_active = 0;
 
-	dev->open = mace68k_open;
-	dev->stop = mace68k_close;
-	dev->hard_start_xmit = mace68k_xmit_start;
-	dev->get_stats = mace68k_stats;
-	dev->set_multicast_list = mace68k_set_multicast;
-	dev->set_mac_address = mace68k_set_address;
+	dev->open		= mace_open;
+	dev->stop		= mace_close;
+	dev->hard_start_xmit	= mace_xmit_start;
+	dev->tx_timeout		= mace_tx_timeout;
+	dev->watchdog_timeo	= TX_TIMEOUT;
+	dev->get_stats		= mace_stats;
+	dev->set_multicast_list	= mace_set_multicast;
+	dev->set_mac_address	= mace_set_address;
 
 	ether_setup(dev);
 
-	mp = (struct mace68k_data *) dev->priv;
-	mp->maccc = ENXMT | ENRCV;
-	mp->dma_intr = IRQ_MAC_MACE_DMA;
+	printk(KERN_INFO "%s: 68K MACE, hardware address %.2X", dev->name, dev->dev_addr[0]);
+	for (j = 1 ; j < 6 ; j++) printk(":%.2X", dev->dev_addr[j]);
+	printk("\n");
 
-	psc_write_word(PSC_ENETWR_CTL, 0x9000);
-	psc_write_word(PSC_ENETRD_CTL, 0x9000);
-	psc_write_word(PSC_ENETWR_CTL, 0x0400);
-	psc_write_word(PSC_ENETRD_CTL, 0x0400);
-                                        	
-	/* apple's driver doesn't seem to do this */
-	/* except at driver shutdown time...      */
-#if 0
-	mace68k_dma_off(dev);
-#endif
+	return 0;
+}
+
+/*
+ * Load the address on a mace controller.
+ */
+
+static int mace_set_address(struct net_device *dev, void *addr)
+{
+	unsigned char *p = addr;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+	volatile struct mace *mb = mp->mace;
+	int i;
+	unsigned long flags;
+	u8 maccc;
+
+	save_flags(flags);
+	cli();
+
+	maccc = mb->maccc;
+
+	/* load up the hardware address */
+	mb->iac = ADDRCHG | PHYADDR;
+	while ((mb->iac & ADDRCHG) != 0);
+	
+	for (i = 0; i < 6; ++i) {
+		mb->padr = dev->dev_addr[i] = p[i];
+	}
+
+	mb->maccc = maccc;
+	restore_flags(flags);
 
 	return 0;
 }
 
 /*
- *	Reset a MACE controller
+ * Open the Macintosh MACE. Most of this is playing with the DMA
+ * engine. The ethernet chip is quite friendly.
  */
  
-static void mace68k_reset(struct net_device *dev)
+static int mace_open(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
+#if 0
 	int i;
 
-	/* soft-reset the chip */
 	i = 200;
 	while (--i) {
 		mb->biucc = SWRST;
@@ -343,18 +297,59 @@
 		break;
 	}
 	if (!i) {
-		printk(KERN_ERR "mace: cannot reset chip!\n");
-		return;
+		printk(KERN_ERR "%s: software reset failed!!\n", dev->name);
+		return -EAGAIN;
 	}
+#endif
 
 	mb->biucc = XMTSP_64;
-	mb->imr = 0xff;		/* disable all intrs for now */
-	i = mb->ir;
-	mb->maccc = 0;		/* turn off tx, rx */
-	mb->utr = RTRD;
-	mb->fifocc = RCVFW_64;
-	mb->xmtfc = AUTO_PAD_XMIT;	/* auto-pad short frames */
+	mb->fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST;
+	mb->xmtfc = AUTO_PAD_XMIT;
+	mb->plscc = PORTSEL_AUI;
+	/* mb->utr = RTRD; */
+
+	if (request_irq(dev->irq, mace_interrupt, 0, dev->name, dev)) {
+		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq);
+		return -EAGAIN;
+	}
+	if (request_irq(mp->dma_intr, mace_dma_intr, 0, dev->name, dev)) {
+		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, mp->dma_intr);
+		free_irq(dev->irq, dev);
+		return -EAGAIN;
+	}
+
+	/* Allocate the DMA ring buffers */
+
+	mp->rx_ring = (void *) __get_free_pages(GFP_DMA, N_RX_PAGES);
+	mp->tx_ring = (void *) __get_free_pages(GFP_DMA, 0);
+	
+	if (mp->tx_ring==NULL || mp->rx_ring==NULL) {
+		if (mp->rx_ring) free_pages((u32) mp->rx_ring, N_RX_PAGES);
+		if (mp->tx_ring) free_pages((u32) mp->tx_ring, 0);
+		free_irq(dev->irq, dev);
+		free_irq(mp->dma_intr, dev);
+		printk(KERN_ERR "%s: unable to allocate DMA buffers\n", dev->name);
+		return -ENOMEM;
+	}
 
+	mp->rx_ring_phys = (unsigned char *) virt_to_bus(mp->rx_ring);
+	mp->tx_ring_phys = (unsigned char *) virt_to_bus(mp->tx_ring);
+
+	/* We want the Rx buffer to be uncached and the Tx buffer to be writethrough */
+
+	kernel_set_cachemode((void *)mp->rx_ring, N_RX_PAGES * PAGE_SIZE, IOMAP_NOCACHE_NONSER);	
+	kernel_set_cachemode((void *)mp->tx_ring, PAGE_SIZE, IOMAP_WRITETHROUGH);
+
+	mace_dma_off(dev);
+
+	/* Not sure what these do */
+
+	psc_write_word(PSC_ENETWR_CTL, 0x9000);
+	psc_write_word(PSC_ENETRD_CTL, 0x9000);
+	psc_write_word(PSC_ENETWR_CTL, 0x0400);
+	psc_write_word(PSC_ENETRD_CTL, 0x0400);
+
+#if 0
 	/* load up the hardware address */
 	
 	mb->iac = ADDRCHG | PHYADDR;
@@ -373,262 +368,158 @@
 		mb->ladrf = 0;
 
 	mb->plscc = PORTSEL_GPSI + ENPLSIO;
-}
 
-/*
- *	Load the address on a mace controller.
- */
- 
-static int mace68k_set_address(struct net_device *dev, void *addr)
-{
-	unsigned char *p = addr;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	volatile struct mace *mb = mp->mace;
-	int i;
-	unsigned long flags;
-
-	save_flags(flags);
-	cli();
+	mb->maccc = ENXMT | ENRCV;
+	mb->imr = RCVINT;
+#endif
 
-	/* load up the hardware address */
-	mb->iac = ADDRCHG | PHYADDR;
-	while ((mb->iac & ADDRCHG) != 0);
+	mace_rxdma_reset(dev);
+	mace_txdma_reset(dev);
 	
-	for (i = 0; i < 6; ++i)
-		mb->padr = dev->dev_addr[i] = p[i];
-	/* note: setting ADDRCHG clears ENRCV */
-	mb->maccc = mp->maccc;
-	restore_flags(flags);
 	return 0;
 }
 
 /*
- *	Open the Macintosh MACE. Most of this is playing with the DMA
- *	engine. The ethernet chip is quite friendly.
+ * Shut down the mace and its interrupt channel
  */
  
-static int mace68k_open(struct net_device *dev)
+static int mace_close(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 
-	/* reset the chip */
-	mace68k_reset(dev);
+	mb->maccc = 0;		/* disable rx and tx	 */
+	mb->imr = 0xFF;		/* disable all irqs	 */
+	mace_dma_off(dev);	/* disable rx and tx dma */
 
-	mp->rx_done = 0;
-	mace68k_rxdma_reset(dev);
-
-	/*
-	 *	The interrupt is fixed and comes off the PSC.
-	 */
-	 
-	if (request_irq(dev->irq, mace68k_interrupt, 0, "68K MACE", dev))
-	{
-		printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);
-		return -EAGAIN;
-	}
-
-	/*
-	 *	Ditto the DMA interrupt.
-	 */
-	 
-	if (request_irq(IRQ_MAC_MACE_DMA, mace68k_dma_intr, 0, "68K MACE DMA",
-			dev))
-	{
-		printk(KERN_ERR "MACE: can't get irq %d\n", IRQ_MAC_MACE_DMA);
-		return -EAGAIN;
-	}
+	free_irq(dev->irq, dev);
+	free_irq(IRQ_MAC_MACE_DMA, dev);
 
-	/* Activate the Mac DMA engine */
+	free_pages((u32) mp->rx_ring, N_RX_PAGES);
+	free_pages((u32) mp->tx_ring, 0);
 
-	mp->tx_slot = 0;		/* Using register set 0 */
-	mp->tx_count = 1;		/* 1 Buffer ready for use */
-	mace68k_txdma_reset(dev);
-	
-	/* turn it on! */
-	mb->maccc = mp->maccc;
-	/* enable all interrupts except receive interrupts */
-	mb->imr = RCVINT;
 	return 0;
 }
 
 /*
- *	Shut down the mace and its interrupt channel
+ * Transmit a frame
  */
  
-static int mace68k_close(struct net_device *dev)
+static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	volatile struct mace *mb = mp->mace;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 
-	/* disable rx and tx */
-	mb->maccc = 0;
-	mb->imr = 0xff;		/* disable all intrs */
+	/* Stop the queue if the buffer is full */
 
-	/* disable rx and tx dma */
+	if (!mp->tx_count) {
+		netif_stop_queue(dev);
+		return 1;
+	}
+	mp->tx_count--;
+	
+	mp->stats.tx_packets++;
+	mp->stats.tx_bytes += skb->len;
 
-	mace68k_dma_off(dev);
+	/* We need to copy into our xmit buffer to take care of alignment and caching issues */
 
-	free_irq(dev->irq, dev);
-	free_irq(IRQ_MAC_MACE_DMA, dev);
-	return 0;
-}
+	memcpy((void *) mp->tx_ring, skb->data, skb->len);
 
-static inline void mace68k_set_timeout(struct net_device *dev)
-{
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	unsigned long flags;
+	/* load the Tx DMA and fire it off */
 
-	save_flags(flags);
-	cli();
-	if (mp->timeout_active)
-		del_timer(&mp->tx_timeout);
-	mp->tx_timeout.expires = jiffies + TX_TIMEOUT;
-	mp->tx_timeout.function = mace68k_tx_timeout;
-	mp->tx_timeout.data = (unsigned long) dev;
-	add_timer(&mp->tx_timeout);
-	mp->timeout_active = 1;
-	restore_flags(flags);
-}
+	psc_write_long(PSC_ENETWR_ADDR + mp->tx_slot, (u32)  mp->tx_ring_phys);
+	psc_write_long(PSC_ENETWR_LEN + mp->tx_slot, skb->len);
+	psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x9800);
 
-/*
- *	Transmit a frame
- */
- 
-static int mace68k_xmit_start(struct sk_buff *skb, struct net_device *dev)
-{
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	/*
-	 *	This may need atomic types ???
-	 */
+	mp->tx_slot ^= 0x10;
+
+	dev_kfree_skb(skb);
 
-	printk("mace68k_xmit_start: mp->tx_count = %d, dev->tbusy = %d, mp->tx_ring = %p (%p)\n",
-		mp->tx_count, dev->tbusy,
-		mp->tx_ring, virt_to_bus(mp->tx_ring));
-	psc_debug_dump();
-
-	if(mp->tx_count == 0)
-	{
-		dev->tbusy=1;
-		mace68k_dma_intr(IRQ_MAC_MACE_DMA, dev, NULL);
-		return 1;
-	}
-	mp->tx_count--;
-	
-	/*
-	 *	FIXME:
-	 *	This is hackish. The memcpy probably isnt needed but
-	 *	the rules for alignment are not known. Ideally we'd like
-	 *	to just blast the skb directly to ethernet. We also don't
-	 *	use the ring properly - just a one frame buffer. That
-	 *	also requires cache pushes ;).
-	 */
-	memcpy((void *)mp->tx_ring, skb, skb->len);
-	psc_write_long(PSC_ENETWR_ADDR + mp->tx_slot, virt_to_bus(mp->tx_ring));
-        psc_write_long(PSC_ENETWR_LEN + mp->tx_slot, skb->len);
-        psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x9800);                       
-	mp->stats.tx_packets++;
-	mp->stats.tx_bytes+=skb->len;
-        dev_kfree_skb(skb);
 	return 0;
 }
 
-static struct net_device_stats *mace68k_stats(struct net_device *dev)
+static struct net_device_stats *mace_stats(struct net_device *dev)
 {
-	struct mace68k_data *p = (struct mace68k_data *) dev->priv;
+	struct mace_data *p = (struct mace_data *) dev->priv;
 	return &p->stats;
 }
 
-/*
- * CRC polynomial - used in working out multicast filter bits.
- */
-#define CRC_POLY	0xedb88320
-
-static void mace68k_set_multicast(struct net_device *dev)
+static void mace_set_multicast(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 	int i, j, k, b;
-	unsigned long crc;
+	u32 crc;
+	u8 maccc;
+
+	maccc = mb->maccc;
+	mb->maccc &= ~PROM;
 
-	mp->maccc &= ~PROM;
-	if (dev->flags & IFF_PROMISC)
-	{
-		mp->maccc |= PROM;
-	} else
-	{
+	if (dev->flags & IFF_PROMISC) {
+		mb->maccc |= PROM;
+	} else {
 		unsigned char multicast_filter[8];
 		struct dev_mc_list *dmi = dev->mc_list;
 
-		if (dev->flags & IFF_ALLMULTI)
-		{
-			for (i = 0; i < 8; i++)
-				multicast_filter[i] = 0xff;
-		} else
-		{
-			for (i = 0; i < 8; i++)
+		if (dev->flags & IFF_ALLMULTI) {
+			for (i = 0; i < 8; i++) {
+				multicast_filter[i] = 0xFF;
+			}
+		} else {
+			for (i = 0; i < 8; i++) {
 				multicast_filter[i] = 0;
-			for (i = 0; i < dev->mc_count; i++)
-			{
-				crc = ~0;
-				for (j = 0; j < 6; ++j)
-				{
-					b = dmi->dmi_addr[j];
-					for (k = 0; k < 8; ++k)
-					{
-						if ((crc ^ b) & 1)
-							crc = (crc >> 1) ^ CRC_POLY;
-						else
-							crc >>= 1;
-						b >>= 1;
-					}
-				}
+			}
+			for (i = 0; i < dev->mc_count; i++) {
+				crc = ether_crc_le(6, dmi->dmi_addr);
 				j = crc >> 26;	/* bit number in multicast_filter */
 				multicast_filter[j >> 3] |= 1 << (j & 7);
 				dmi = dmi->next;
 			}
 		}
-#if 0
-		printk("Multicast filter :");
-		for (i = 0; i < 8; i++)
-			printk("%02x ", multicast_filter[i]);
-		printk("\n");
-#endif
 
 		mb->iac = ADDRCHG | LOGADDR;
-		while ((mb->iac & ADDRCHG) != 0);
+		while (mb->iac & ADDRCHG);
 		
-		for (i = 0; i < 8; ++i)
+		for (i = 0; i < 8; ++i) {
 			mb->ladrf = multicast_filter[i];
+		}
 	}
-	/* reset maccc */
-	mb->maccc = mp->maccc;
+
+	mb->maccc = maccc;
 }
 
 /*
- *	Miscellaneous interrupts are handled here. We may end up 
- *	having to bash the chip on the head for bad errors
+ * Miscellaneous interrupts are handled here. We may end up 
+ * having to bash the chip on the head for bad errors
  */
  
-static void mace68k_handle_misc_intrs(struct mace68k_data *mp, int intr)
+static void mace_handle_misc_intrs(struct mace_data *mp, int intr)
 {
 	volatile struct mace *mb = mp->mace;
-	static int mace68k_babbles, mace68k_jabbers;
+	static int mace_babbles, mace_jabbers;
 
-	if (intr & MPCO)
+	if (intr & MPCO) {
 		mp->stats.rx_missed_errors += 256;
+	}
 	mp->stats.rx_missed_errors += mb->mpc;	/* reading clears it */
-	if (intr & RNTPCO)
+
+	if (intr & RNTPCO) {
 		mp->stats.rx_length_errors += 256;
+	}
 	mp->stats.rx_length_errors += mb->rntpc;	/* reading clears it */
-	if (intr & CERR)
+
+	if (intr & CERR) {
 		++mp->stats.tx_heartbeat_errors;
-	if (intr & BABBLE)
-		if (mace68k_babbles++ < 4)
+	}
+	if (intr & BABBLE) {
+		if (mace_babbles++ < 4) {
 			printk(KERN_DEBUG "mace: babbling transmitter\n");
-	if (intr & JABBER)
-		if (mace68k_jabbers++ < 4)
+		}
+	}
+	if (intr & JABBER) {
+		if (mace_jabbers++ < 4) {
 			printk(KERN_DEBUG "mace: jabbering transceiver\n");
+		}
+	}
 }
 
 /*
@@ -636,191 +527,172 @@
  *	the DMA completion)
  */
  
-static void mace68k_xmit_error(struct net_device *dev)
+static void mace_xmit_error(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 	u8 xmtfs, xmtrc;
 	
 	xmtfs = mb->xmtfs;
 	xmtrc = mb->xmtrc;
 	
-	if(xmtfs & XMTSV)
-	{
-		if(xmtfs & UFLO)
-		{
+	if (xmtfs & XMTSV) {
+		if (xmtfs & UFLO) {
 			printk("%s: DMA underrun.\n", dev->name);
 			mp->stats.tx_errors++;
 			mp->stats.tx_fifo_errors++;
-			mace68k_reset(dev);
+			mace_txdma_reset(dev);
 		}
-		if(xmtfs & RTRY)
+		if (xmtfs & RTRY) {
 			mp->stats.collisions++;
+		}
 	}			
-	mark_bh(NET_BH);
 }
 
 /*
  *	A receive interrupt occurred.
  */
  
-static void mace68k_recv_interrupt(struct net_device *dev)
+static void mace_recv_interrupt(struct net_device *dev)
 {
-//	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+/*	struct mace_data *mp = (struct mace_data *) dev->priv; */
 //	volatile struct mace *mb = mp->mace;
 }
 
 /*
- *	Process the chip interrupt
+ * Process the chip interrupt
  */
  
-static void mace68k_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 	u8 ir;
 	
 	ir = mb->ir;
-	mace68k_handle_misc_intrs(mp, ir);
+	mace_handle_misc_intrs(mp, ir);
 	
-	if(ir&XMTINT)
-		mace68k_xmit_error(dev);
-	if(ir&RCVINT)
-		mace68k_recv_interrupt(dev);
+	if (ir & XMTINT) {
+		mace_xmit_error(dev);
+	}
+	if (ir & RCVINT) {
+		mace_recv_interrupt(dev);
+	}
 }
 
-static void mace68k_tx_timeout(unsigned long data)
+static void mace_tx_timeout(struct net_device *dev)
 {
-//	struct net_device *dev = (struct net_device *) data;
-//	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+/*	struct mace_data *mp = (struct mace_data *) dev->priv; */
 //	volatile struct mace *mb = mp->mace;
 }
 
 /*
- *	Handle a newly arrived frame
+ * Handle a newly arrived frame
  */
  
 static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	struct sk_buff *skb;
 
-	if(mf->status&RS_OFLO)
-	{
+	if (mf->status & RS_OFLO) {
 		printk("%s: fifo overflow.\n", dev->name);
 		mp->stats.rx_errors++;
 		mp->stats.rx_fifo_errors++;
 	}
-	if(mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR))
+	if (mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR))
 		mp->stats.rx_errors++;
 		
-	if(mf->status&RS_CLSN)
+	if (mf->status&RS_CLSN) {
 		mp->stats.collisions++;
-	if(mf->status&RS_FRAMERR)
+	}
+	if (mf->status&RS_FRAMERR) {
 		mp->stats.rx_frame_errors++;
-	if(mf->status&RS_FCSERR)
+	}
+	if (mf->status&RS_FCSERR) {
 		mp->stats.rx_crc_errors++;
+	}
 		
 	skb = dev_alloc_skb(mf->len+2);
-	if(skb==NULL)
-	{
+	if (!skb) {
 		mp->stats.rx_dropped++;
 		return;
 	}
 	skb_reserve(skb,2);
 	memcpy(skb_put(skb, mf->len), mf->data, mf->len);
 	
+	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
 	netif_rx(skb);
 	dev->last_rx = jiffies;
 	mp->stats.rx_packets++;
-	mp->stats.rx_bytes+=mf->len;
+	mp->stats.rx_bytes += mf->len;
 }
 
 /*
- *	The PSC has passed us a DMA interrupt event.
+ * The PSC has passed us a DMA interrupt event.
  */
  
-static void mace68k_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+	int left, head;
+	u16 status;
+	u32 baka;
 
-#if 0
-	u32 psc_status;
-	
-	/* It seems this must be allowed to stabilise ?? */
-	
-	while((psc_status=psc_read_long(0x0804))!=psc_read_long(0x0804));
+	/* Not sure what this does */
+
+	while ((baka = psc_read_long(PSC_MYSTERY)) != psc_read_long(PSC_MYSTERY));
+	if (!(baka & 0x60000000)) return;
 
 	/*
-	 *	Was this an ethernet event ?
+	 * Process the read queue
 	 */
-	 	
-	if(psc_status&0x60000000)
-	{
-#endif
-		/*
-		 *	Process the read queue
-		 */
 		 
-		u16 psc_status = psc_read_word(PSC_ENETRD_CTL);
+	status = psc_read_word(PSC_ENETRD_CTL);
 		
-		printk("mace68k_dma_intr: PSC_ENETRD_CTL = %04X\n", (uint) psc_status);
-
-		if (psc_status & 0x2000) {
-			mace68k_rxdma_reset(dev);
-			mp->rx_done = 0;
-		} else if (psc_status & 0x100) {
-			int left;
-			
-			psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x1100);
-			left=psc_read_long(PSC_ENETRD_LEN + mp->rx_slot);
-			/* read packets */	
-			
-			while(mp->rx_done < left)
-			{
-				struct mace_frame *mf=((struct mace_frame *)
-					mp->rx_ring)+mp->rx_done++;
-				mace_dma_rx_frame(dev, mf);
-			}
+	if (status & 0x2000) {
+		mace_rxdma_reset(dev);
+	} else if (status & 0x0100) {
+		psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x1100);
+
+		left = psc_read_long(PSC_ENETRD_LEN + mp->rx_slot);
+		head = N_RX_RING - left;
+
+		/* Loop through the ring buffer and process new packages */
+
+		while (mp->rx_tail < head) {
+			mace_dma_rx_frame(dev, (struct mace_frame *) (mp->rx_ring + (mp->rx_tail * 0x0800)));
+			mp->rx_tail++;
+		}
 			
-			if(left == 0)	/* Out of DMA room */
-			{
-				psc_load_rxdma_base(mp->rx_slot, 
-					(void *)virt_to_phys(mp->rx_ring));
-				mp->rx_slot^=16;
-				mp->rx_done = 0;
-			}
-			else
-			{
-				psc_write_word(PSC_ENETRD_CMD+mp->rx_slot,
-					0x9800);
-			}
-					
+		/* If we're out of buffers in this ring then switch to */
+		/* the other set, otherwise just reactivate this one.  */
+
+		if (!left) {
+			mace_load_rxdma_base(dev, mp->rx_slot);
+			mp->rx_slot ^= 0x10;
+		} else {
+			psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x9800);
 		}
+	}
 		
-		/*
-		 *	Process the write queue
-		 */
-		 
-		psc_status = psc_read_word(PSC_ENETWR_CTL);
-		printk("mace68k_dma_intr: PSC_ENETWR_CTL = %04X\n", (uint) psc_status);
+	/*
+	 * Process the write queue
+	 */
 
-		/* apple's driver seems to loop over this until neither */
-		/* condition is true.    - jmt                          */
+	status = psc_read_word(PSC_ENETWR_CTL);
 
-		if (psc_status & 0x2000) {
-			mace68k_txdma_reset(dev);
-		} else if (psc_status & 0x0100) {
-			psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x0100);
-			mp->tx_slot ^=16;
-			mp->tx_count++;
-			dev->tbusy = 0;
-			mark_bh(NET_BH);
-		}
-#if 0
+	if (status & 0x2000) {
+		mace_txdma_reset(dev);
+	} else if (status & 0x0100) {
+		psc_write_word(PSC_ENETWR_CMD + mp->tx_sloti, 0x0100);
+		mp->tx_sloti ^= 0x10;
+		mp->tx_count++;
+		netif_wake_queue(dev);
 	}
-#endif
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/macsonic.c linux/drivers/net/macsonic.c
--- linux.orig/drivers/net/macsonic.c	2001-10-17 04:56:29.000000000 +0000
+++ linux/drivers/net/macsonic.c	2002-07-20 01:08:25.000000000 +0000
@@ -20,6 +20,9 @@
  *		  and duplicating packets. Needs more testing.
  *
  * 99/01/03 MSch: upgraded to version 0.92 of the core driver, fixed.
+ * 
+ * 00/10/31 sammy@sammy.net: Updated driver for 2.4 kernels, fixed problems
+ *          on centris.
  */
 
 #include <linux/kernel.h>
@@ -47,6 +50,7 @@
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_via.h>
+#include <asm/pgalloc.h>
 
 #include <linux/errno.h>
 
@@ -126,36 +130,42 @@
 
 int __init macsonic_init(struct net_device* dev)
 {
-	struct sonic_local* lp = (struct sonic_local *)dev->priv;
+	struct sonic_local* lp;
 	int i;
 
 	/* Allocate the entire chunk of memory for the descriptors.
            Note that this cannot cross a 64K boundary. */
 	for (i = 0; i < 20; i++) {
 		unsigned long desc_base, desc_top;
-		if ((lp->sonic_desc = 
-		     kmalloc(SIZEOF_SONIC_DESC
-			     * SONIC_BUS_SCALE(lp->dma_bitmode), GFP_KERNEL | GFP_DMA)) == NULL) {
+		if((lp = kmalloc(sizeof(struct sonic_local), GFP_KERNEL | GFP_DMA)) == NULL) {
 			printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name);
 			return -ENOMEM;
 		}
-		desc_base = (unsigned long) lp->sonic_desc;
-		desc_top = desc_base + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode);
+
+		desc_base = (unsigned long) lp;
+		desc_top = desc_base + sizeof(struct sonic_local);
 		if ((desc_top & 0xffff) >= (desc_base & 0xffff))
 			break;
 		/* Hmm. try again (FIXME: does this actually work?) */
-		kfree(lp->sonic_desc);
+		kfree(lp);
 		printk(KERN_DEBUG
 		       "%s: didn't get continguous chunk [%08lx - %08lx], trying again\n",
 		       dev->name, desc_base, desc_top);
 	}
 
-	if (lp->sonic_desc == NULL) {
+	if (lp == NULL) {
 		printk(KERN_ERR "%s: tried 20 times to allocate descriptor buffers, giving up.\n",
 		       dev->name);
 		return -ENOMEM;
 	}		       
 
+	dev->priv = lp;
+
+#if 0
+	/* this code is only here as a curiousity...   mainly, where the 
+	   fuck did SONIC_BUS_SCALE come from, and what was it supposed
+	   to do?  the normal allocation works great for 32 bit stuffs..  */
+
 	/* Now set up the pointers to point to the appropriate places */
 	lp->cda = lp->sonic_desc;
 	lp->tda = lp->cda + (SIZEOF_SONIC_CDA * SONIC_BUS_SCALE(lp->dma_bitmode));
@@ -164,6 +174,15 @@
 	lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
 			     * SONIC_BUS_SCALE(lp->dma_bitmode));
 
+#endif
+	
+	memset(lp, 0, sizeof(struct sonic_local));
+
+	lp->cda_laddr = (unsigned int)&(lp->cda);
+	lp->tda_laddr = (unsigned int)lp->tda;
+	lp->rra_laddr = (unsigned int)lp->rra;
+	lp->rda_laddr = (unsigned int)lp->rda;
+
 	/* FIXME, maybe we should use skbs */
 	if ((lp->rba = (char *)
 	     kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
@@ -173,15 +192,17 @@
 		return -ENOMEM;
 	}
 
+	lp->rba_laddr = (unsigned int)lp->rba;
+
 	{
 		int rs, ds;
 
 		/* almost always 12*4096, but let's not take chances */
 		rs = ((SONIC_NUM_RRS * SONIC_RBSIZE + 4095) / 4096) * 4096;
 		/* almost always under a page, but let's not take chances */
-		ds = ((SIZEOF_SONIC_DESC + 4095) / 4096) * 4096;
+		ds = ((sizeof(struct sonic_local) + 4095) / 4096) * 4096;
 		kernel_set_cachemode(lp->rba, rs, IOMAP_NOCACHE_SER);
-		kernel_set_cachemode(lp->sonic_desc, ds, IOMAP_NOCACHE_SER);
+		kernel_set_cachemode(lp, ds, IOMAP_NOCACHE_SER);
 	}
 	
 #if 0
@@ -278,6 +299,7 @@
 	static int once_is_more_than_enough;
 	struct sonic_local* lp;
 	int i;
+	int dma_bitmode;
 	
 	if (once_is_more_than_enough)
 		return -ENODEV;
@@ -317,7 +339,7 @@
 
 	printk("yes\n");	
 
-	if (dev) {
+	if (dev) 
 		dev = init_etherdev(dev, sizeof(struct sonic_local));
 		if (!dev)
 			return -ENOMEM;
@@ -329,13 +351,17 @@
 		}
 	} else {
 		dev = init_etherdev(NULL, sizeof(struct sonic_local));
-	}
 
 	if (dev == NULL)
 		return -ENOMEM;
 
-	lp = (struct sonic_local*) dev->priv;
-	memset(lp, 0, sizeof(struct sonic_local));
+	if(dev->priv) {
+		printk("%s: warning! sonic entering with priv already allocated!\n",
+		       dev->name);
+		printk("%s: discarding, will attempt to reallocate\n", dev->name);
+		dev->priv = NULL;
+	}
+
 	/* Danger!  My arms are flailing wildly!  You *must* set this
            before using sonic_read() */
 
@@ -357,8 +383,11 @@
 
 	/* The PowerBook's SONIC is 16 bit always. */
 	if (macintosh_config->ident == MAC_MODEL_PB520) {
-		lp->reg_offset = 0;
-		lp->dma_bitmode = 0;
+		reg_offset = 0;
+		dma_bitmode = 0;
+	} else if (macintosh_config->ident == MAC_MODEL_C610) {
+		reg_offset = 0;
+		dma_bitmode = 1;
 	} else {
 		/* Some of the comm-slot cards are 16 bit.  But some
                    of them are not.  The 32-bit cards use offset 2 and
@@ -369,27 +398,41 @@
 
 		/* Technically this is not necessary since we zeroed
                    it above */
-		lp->reg_offset = 0;
-		lp->dma_bitmode = 0;
+		reg_offset = 0;
+		dma_bitmode = 0;
 		sr = sonic_read(dev, SONIC_SR);
 		if (sr == 0 || sr == 0xffff) {
-			lp->reg_offset = 2;
+			reg_offset = 2;
 			/* 83932 is 0x0004, 83934 is 0x0100 or 0x0101 */
 			sr = sonic_read(dev, SONIC_SR);
-			lp->dma_bitmode = 1;
+			dma_bitmode = 1;
 			
 		}
 		printk(KERN_INFO
 		       "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
-		       dev->name, sr, lp->dma_bitmode?32:16, lp->reg_offset);
+		       dev->name, sr, dma_bitmode?32:16, reg_offset);
 	}
+	
 
-
+	/* this carries my sincere apologies -- by the time I got to updating
+	   the driver, support for "reg_offsets" appeares nowhere in the sonic
+	   code, going back for over a year.  Fortunately, my Mac does't seem
+	   to use whatever this was.
+
+	   If you know how this is supposed to be implemented, either fix it,
+	   or contact me (sammy@sammy.net) to explain what it is. --Sam */
+	   
+	if(reg_offset) {
+		printk("%s: register offset unsupported.  please fix this if you know what it is.\n", dev->name);
+		return -ENODEV;
+	}
+	
 	/* Software reset, then initialize control registers. */
 	sonic_write(dev, SONIC_CMD, SONIC_CR_RST);
 	sonic_write(dev, SONIC_DCR, SONIC_DCR_BMS |
 		    SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_EXBUS |
-		    (lp->dma_bitmode ? SONIC_DCR_DW : 0));
+		    (dma_bitmode ? SONIC_DCR_DW : 0));
+
 	/* This *must* be written back to in order to restore the
            extended programmable output bits */
 	sonic_write(dev, SONIC_DCR2, 0);
@@ -453,7 +496,7 @@
 	u16 sonic_dcr;
 	int id;
 	int i;
-	int reg_offset, dma_bitmode;
+	int dma_bitmode;
 
 	/* Find the first SONIC that hasn't been initialized already */
 	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK,
@@ -539,8 +582,6 @@
 	memset(lp, 0, sizeof(struct sonic_local));
 	/* Danger!  My arms are flailing wildly!  You *must* set this
            before using sonic_read() */
-	lp->reg_offset = reg_offset;
-	lp->dma_bitmode = dma_bitmode;
 	dev->base_addr = base_addr;
 	dev->irq = SLOT2IRQ(ndev->board->slot);
 
@@ -553,6 +594,11 @@
 	printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
 	       dev->name, sonic_read(dev, SONIC_SR), dma_bitmode?32:16, reg_offset);
 
+	if(reg_offset) {
+		printk("%s: register offset unsupported.  please fix this if you know what it is.\n", dev->name);
+		return -ENODEV;
+	}
+
 	/* Software reset, then initialize control registers. */
 	sonic_write(dev, SONIC_CMD, SONIC_CR_RST);
 	sonic_write(dev, SONIC_DCR, sonic_dcr
@@ -618,6 +664,9 @@
 #define sonic_chiptomem(bat) (bat)
 #define PHYSADDR(quux) (quux)
 
+#define sonic_request_irq       request_irq
+#define sonic_free_irq          free_irq
+
 #include "sonic.c"
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/mii.c linux/drivers/net/mii.c
--- linux.orig/drivers/net/mii.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/mii.c	2002-07-20 01:08:31.000000000 +0000
@@ -146,6 +146,8 @@
 
 int mii_link_ok (struct mii_if_info *mii)
 {
+	/* first, a dummy read, needed to latch some MII phys */
+	mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
 	if (mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_LSTATUS)
 		return 1;
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c
--- linux.orig/drivers/net/myri_sbus.c	2001-10-19 15:32:28.000000000 +0000
+++ linux/drivers/net/myri_sbus.c	2002-07-20 01:08:24.000000000 +0000
@@ -800,9 +800,6 @@
 static struct net_device_stats *myri_get_stats(struct net_device *dev)
 { return &(((struct myri_eth *)dev->priv)->enet_stats); }
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 static void myri_set_multicast(struct net_device *dev)
 {
 	/* Do nothing, all MyriCOM nodes transmit multicast frames
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/natsemi.c linux/drivers/net/natsemi.c
--- linux.orig/drivers/net/natsemi.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/natsemi.c	2002-07-20 01:08:24.000000000 +0000
@@ -105,6 +105,9 @@
 	version 1.0.14:
 		* Cleanup some messages and autoneg in ethtool (Tim Hockin)
 
+	version 1.0.13:
+		* crc cleanup (Matt Domsch <Matt_Domsch@dell.com>)
+
 	TODO:
 	* big endian support with CFG:BEM instead of cpu_to_le32
 	* support for an external PHY
@@ -1731,36 +1734,15 @@
 	return &np->stats;
 }
 
-/* The little-endian AUTODIN II ethernet CRC calculations.
-   A big-endian version is also available.
-   This is slow but compact code.  Do not use this routine for bulk data,
-   use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c.
-   Chips may use the upper or lower CRC bits, and may reverse and/or invert
-   them.  Select the endian-ness that results in minimal calculations.
-*/
-#if 0
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-	unsigned int crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-#else
+/**
+ * dp83815_crc - computer CRC for hash table entries
+ *
+ * Note - this is, for some reason, *not* the same function
+ * as ether_crc_le() or ether_crc(), though it uses the
+ * same big-endian polynomial.
+ */
 #define DP_POLYNOMIAL			0x04C11DB7
-/* dp83815_crc - computer CRC for hash table entries */
-static unsigned ether_crc_le(int length, unsigned char *data)
+static unsigned dp83815_crc(int length, unsigned char *data)
 {
     u32 crc;
     u8 cur_byte;
@@ -1784,7 +1766,7 @@
 
     return (crc);
 }
-#endif
+
 
 void set_bit_le(int offset, unsigned char * data)
 {
@@ -1814,7 +1796,7 @@
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit_le(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
+			set_bit_le(dp83815_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
 					mc_filter);
 		}
 		rx_mode = RxFilterEnable | AcceptBroadcast 
@@ -1965,6 +1947,8 @@
 	/* get link status */
 	case ETHTOOL_GLINK: {
 		struct ethtool_value edata = {ETHTOOL_GLINK};
+		/* LSTATUS is latched low until a read - so read twice */
+		mdio_read(dev, 1, MII_BMSR);
 		edata.data = (mdio_read(dev, 1, MII_BMSR)&BMSR_LSTATUS) ? 1:0;
 		if (copy_to_user(useraddr, &edata, sizeof(edata)))
 			return -EFAULT;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ne.c linux/drivers/net/ne.c
--- linux.orig/drivers/net/ne.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/ne.c	2002-07-20 01:08:35.000000000 +0000
@@ -734,9 +734,11 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
 MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
-MODULE_PARM_DESC(io, "NEx000 I/O base address(es),required");
-MODULE_PARM_DESC(irq, "NEx000 IRQ number(s)");
-MODULE_PARM_DESC(bad, "NEx000 accept bad clone(s)");
+MODULE_PARM_DESC(io, "I/O base address(es),required");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
+MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver");
+MODULE_LICENSE("GPL");
 
 /* This is set up so that no ISA autoprobe takes place. We can't guarantee
 that the ne2k probe is the last 8390 based probe to take place (as it
@@ -788,7 +790,6 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
--- linux.orig/drivers/net/ne2k-pci.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/ne2k-pci.c	2002-07-20 01:08:28.000000000 +0000
@@ -82,9 +82,9 @@
 MODULE_PARM(debug, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM_DESC(debug, "PCI NE2000 debug level (1-2)");
-MODULE_PARM_DESC(options, "PCI NE2000: Bit 5: full duplex");
-MODULE_PARM_DESC(full_duplex, "PCI NE2000 full duplex setting(s) (1)");
+MODULE_PARM_DESC(debug, "debug level (1-2)");
+MODULE_PARM_DESC(options, "Bit 5: full duplex");
+MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
 
 /* Some defines that people can play with if so inclined. */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ne3210.c linux/drivers/net/ne3210.c
--- linux.orig/drivers/net/ne3210.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/ne3210.c	2002-07-20 01:08:34.000000000 +0000
@@ -370,9 +370,11 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
-MODULE_PARM_DESC(io, "NE3210 I/O base address(es)");
-MODULE_PARM_DESC(irq, "NE3210 IRQ number(s)");
-MODULE_PARM_DESC(mem, "NE3210 memory base address(es)");
+MODULE_PARM_DESC(io, "I/O base address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(mem, "memory base address(es)");
+MODULE_DESCRIPTION("NE3210 EISA Ethernet driver");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
@@ -415,7 +417,6 @@
 		}
 	}
 }
-MODULE_LICENSE("GPL");
 
 #endif /* MODULE */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ns83820.c linux/drivers/net/ns83820.c
--- linux.orig/drivers/net/ns83820.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/ns83820.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,10 +1,12 @@
-#define _VERSION "0.15"
-/* ns83820.c by Benjamin LaHaise <bcrl@redhat.com> with contributions.
+#define _VERSION "0.18"
+/* ns83820.c by Benjamin LaHaise with contributions.
  *
- * $Revision: 1.34.2.12 $
+ * Questions/comments/discussion to linux-ns83820@kvack.org.
+ *
+ * $Revision: 1.34.2.16 $
  *
  * Copyright 2001 Benjamin LaHaise.
- * Copyright 2001 Red Hat.
+ * Copyright 2001, 2002 Red Hat.
  *
  * Mmmm, chocolate vanilla mocha...
  *
@@ -51,6 +53,10 @@
  *				suppress duplicate link status messages
  *	20011117 	0.14 - ethtool GDRVINFO, GLINK support from jgarzik
  *	20011204 	0.15	get ppc (big endian) working
+ *	20011218	0.16	various cleanups
+ *	20020310	0.17	speedups
+ *	20020610	0.18 -	actually use the pci dma api for highmem
+ *			     -	remove pci latency register fiddling
  *
  * Driver Overview
  * ===============
@@ -93,8 +99,8 @@
 #include <linux/in.h>	/* for IPPROTO_... */
 #include <linux/eeprom.h>
 #include <linux/compiler.h>
+#include <linux/prefetch.h>
 #include <linux/ethtool.h>
-//#include <linux/skbrefill.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -103,61 +109,29 @@
 #undef Dprintk
 #define	Dprintk			dprintk
 
-#ifdef CONFIG_HIGHMEM64G
-#define USE_64BIT_ADDR	"+"
-#elif defined(__ia64__)
+#if defined(CONFIG_HIGHMEM64G) || defined(__ia64__)
 #define USE_64BIT_ADDR	"+"
 #endif
 
-/* Tell davem to fix the pci dma api.  Grrr. */
-/* stolen from acenic.c */
-#if 0 //def CONFIG_HIGHMEM
-#if defined(CONFIG_X86)
-#define DMAADDR_OFFSET  0
-#if defined(CONFIG_HIGHMEM64G)
-typedef u64 dmaaddr_high_t;
-#else
-typedef u32 dmaaddr_high_t;
-#endif
-#elif defined(CONFIG_PPC)
-#define DMAADDR_OFFSET PCI_DRAM_OFFSET
-typedef unsigned long dmaaddr_high_t;
-#endif
-
-static inline dmaaddr_high_t
-pci_map_single_high(struct pci_dev *hwdev, struct page *page,
-		    int offset, size_t size, int dir)
-{
-	u64 phys;
-	phys = page - mem_map;
-	phys <<= PAGE_SHIFT;
-	phys += offset;
-	phys += DMAADDR_OFFSET;
-	return phys;
-}
-#else
-
-typedef unsigned long dmaaddr_high_t;
-
-static inline dmaaddr_high_t
-pci_map_single_high(struct pci_dev *hwdev, struct page *page,
-		    int offset, size_t size, int dir)
-{
-	return pci_map_single(hwdev, page_address(page) + offset, size, dir);
-}
-#endif
-
 #if defined(USE_64BIT_ADDR)
 #define	VERSION	_VERSION USE_64BIT_ADDR
+#define TRY_DAC	1
 #else
 #define	VERSION	_VERSION
+#define TRY_DAC	0
 #endif
 
 /* tunables */
-#define RX_BUF_SIZE	6144	/* 8192 */
-#define NR_RX_DESC	256
+#define RX_BUF_SIZE	1500	/* 8192 */
+
+/* Must not exceed ~65000. */
+#define NR_RX_DESC	64
+#define NR_TX_DESC	64
 
-#define NR_TX_DESC	256
+/* not tunable */
+#define REAL_RX_BUF_SIZE (RX_BUF_SIZE + 14)	/* rx/tx mac addr + type */
+
+#define MIN_TX_DESC_FREE	8
 
 /* register defines */
 #define CFGCS		0x04
@@ -376,13 +350,22 @@
 } while(0)
 
 #ifdef USE_64BIT_ADDR
-typedef u64	hw_addr_t;
+#define HW_ADDR_LEN	8
+#define desc_addr_set(desc, addr)				\
+	do {							\
+		u64 __addr = (addr);				\
+		desc[BUFPTR] = cpu_to_le32(__addr);		\
+		desc[BUFPTR+1] = cpu_to_le32(__addr >> 32);	\
+	} while(0)
+#define desc_addr_get(desc)					\
+		(((u64)le32_to_cpu(desc[BUFPTR+1]) << 32)	\
+		     | le32_to_cpu(desc[BUFPTR]))
 #else
-typedef u32	hw_addr_t;
+#define HW_ADDR_LEN	4
+#define desc_addr_set(desc, addr)	(desc[BUFPTR] = cpu_to_le32(addr))
+#define desc_addr_get(desc)		(le32_to_cpu(desc[BUFPTR]))
 #endif
 
-#define HW_ADDR_LEN	(sizeof(hw_addr_t))
-
 #define LINK		0
 #define BUFPTR		(LINK + HW_ADDR_LEN/4)
 #define CMDSTS		(BUFPTR + HW_ADDR_LEN/4)
@@ -394,6 +377,7 @@
 #define CMDSTS_INTR	0x20000000
 #define CMDSTS_ERR	0x10000000
 #define CMDSTS_OK	0x08000000
+#define CMDSTS_LEN_MASK	0x0000ffff
 
 #define CMDSTS_DEST_MASK	0x01800000
 #define CMDSTS_DEST_SELF	0x00800000
@@ -408,7 +392,8 @@
 
 	struct sk_buff	*skbs[NR_RX_DESC];
 
-	unsigned	next_rx, next_empty;
+	u32		*next_rx_desc;
+	u16		next_rx, next_empty;
 
 	u32		*descs;
 	dma_addr_t	phy_descs;
@@ -423,6 +408,7 @@
 	struct pci_dev		*pci_dev;
 
 	struct rx_info		rx_info;
+	struct tasklet_struct	rx_tasklet;
 
 	unsigned		ihr;
 	struct tq_struct	tq_refill;
@@ -441,10 +427,11 @@
 	spinlock_t	tx_lock;
 
 	long		tx_idle;
-	u32		tx_done_idx;
-	u32		tx_idx;
-	volatile u32	tx_free_idx;	/* idx of free desc chain */
-	u32		tx_intr_idx;
+
+	u16		tx_done_idx;
+	u16		tx_idx;
+	volatile u16	tx_free_idx;	/* idx of free desc chain */
+	u16		tx_intr_idx;
 
 	struct sk_buff	*tx_skbs[NR_TX_DESC];
 
@@ -455,7 +442,7 @@
 
 //free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC
 #define start_tx_okay(dev)	\
-	(((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > NR_TX_DESC/2)
+	(((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > MIN_TX_DESC_FREE)
 
 
 /* Packet Receiver
@@ -504,12 +491,12 @@
 	unsigned next_empty;
 	u32 cmdsts;
 	u32 *sg;
-	hw_addr_t buf;
+	dma_addr_t buf;
 
 	next_empty = dev->rx_info.next_empty;
 
 	/* don't overrun last rx marker */
-	if (nr_rx_empty(dev) <= 2) {
+	if (unlikely(nr_rx_empty(dev) <= 2)) {
 		kfree_skb(skb);
 		return 1;
 	}
@@ -523,34 +510,39 @@
 #endif
 
 	sg = dev->rx_info.descs + (next_empty * DESC_SIZE);
-	if (dev->rx_info.skbs[next_empty])
+	if (unlikely(NULL != dev->rx_info.skbs[next_empty]))
 		BUG();
 	dev->rx_info.skbs[next_empty] = skb;
 
 	dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
-	cmdsts = RX_BUF_SIZE | CMDSTS_INTR;
-	buf = pci_map_single(dev->pci_dev, skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+	cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR;
+	buf = pci_map_single(dev->pci_dev, skb->tail,
+			     REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 	build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
 	/* update link of previous rx */
-	if (next_empty != dev->rx_info.next_rx)
+	if (likely(next_empty != dev->rx_info.next_rx))
 		dev->rx_info.descs[((NR_RX_DESC + next_empty - 1) % NR_RX_DESC) * DESC_SIZE] = cpu_to_le32(dev->rx_info.phy_descs + (next_empty * DESC_SIZE * 4));
 
 	return 0;
 }
 
-static int rx_refill(struct ns83820 *dev, int gfp)
+static inline int rx_refill(struct ns83820 *dev, int gfp)
 {
 	unsigned i;
 	long flags = 0;
 
+	if (unlikely(nr_rx_empty(dev) <= 2))
+		return 0;
+
 	dprintk("rx_refill(%p)\n", dev);
 	if (gfp == GFP_ATOMIC)
 		spin_lock_irqsave(&dev->rx_info.lock, flags);
 	for (i=0; i<NR_RX_DESC; i++) {
 		struct sk_buff *skb;
 		long res;
-		skb = __dev_alloc_skb(RX_BUF_SIZE+16, gfp);
-		if (!skb)
+		/* extra 16 bytes for alignment */
+		skb = __dev_alloc_skb(REAL_RX_BUF_SIZE+16, gfp);
+		if (unlikely(!skb))
 			break;
 
 		res = (long)skb->tail & 0xf;
@@ -575,6 +567,12 @@
 	return i ? 0 : -ENOMEM;
 }
 
+static void FASTCALL(rx_refill_atomic(struct ns83820 *dev));
+static void rx_refill_atomic(struct ns83820 *dev)
+{
+	rx_refill(dev, GFP_ATOMIC);
+}
+
 /* REFILL */
 static inline void queue_refill(void *_dev)
 {
@@ -590,6 +588,7 @@
 	build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
 }
 
+static void FASTCALL(phy_intr(struct ns83820 *dev));
 static void phy_intr(struct ns83820 *dev)
 {
 	static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
@@ -600,7 +599,6 @@
 	cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY;
 
 	if (dev->CFG_cache & CFG_TBI_EN) {
-
 		/* we have an optical transceiver */
 		tbisr = readl(dev->base + TBISR);
 		tanar = readl(dev->base + TANAR);
@@ -646,20 +644,24 @@
 		new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
 
 		if (cfg & CFG_SPDSTS1)
-			new_cfg |= CFG_MODE_1000 | CFG_SB;
+			new_cfg |= CFG_MODE_1000;
 		else
-			new_cfg &= ~CFG_MODE_1000 | CFG_SB;
+			new_cfg &= ~CFG_MODE_1000;
 
-		if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
+		speed = ((cfg / CFG_SPDSTS0) & 3);
+		fullduplex = (cfg & CFG_DUPSTS);
+
+		if (fullduplex)
+			new_cfg |= CFG_SB;
+
+		if ((cfg & CFG_LNKSTS) &&
+		    ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
 			writel(new_cfg, dev->base + CFG);
 			dev->CFG_cache = new_cfg;
 		}
 
 		dev->CFG_cache &= ~CFG_SPDSTS;
 		dev->CFG_cache |= cfg & CFG_SPDSTS;
-
-		speed = ((cfg / CFG_SPDSTS0) & 3);
-		fullduplex = (cfg & CFG_DUPSTS);
 	}
 
 	newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN;
@@ -690,6 +692,7 @@
 
 	dev->rx_info.idle = 1;
 	dev->rx_info.next_rx = 0;
+	dev->rx_info.next_rx_desc = dev->rx_info.descs;
 	dev->rx_info.next_empty = 0;
 
 	for (i=0; i<NR_RX_DESC; i++)
@@ -724,7 +727,7 @@
 		dev->IMR_cache |= ISR_RXDESC;
 		dev->IMR_cache |= ISR_RXIDLE;
 		dev->IMR_cache |= ISR_TXDESC;
-		//dev->IMR_cache |= ISR_TXIDLE;
+		dev->IMR_cache |= ISR_TXIDLE;
 
 		writel(dev->IMR_cache, dev->base + IMR);
 		writel(1, dev->base + IER);
@@ -770,6 +773,24 @@
 	}
 }
 
+static void FASTCALL(ns83820_rx_kick(struct ns83820 *dev));
+static void ns83820_rx_kick(struct ns83820 *dev)
+{
+	/*if (nr_rx_empty(dev) >= NR_RX_DESC/4)*/ {
+		if (dev->rx_info.up) {
+			rx_refill_atomic(dev);
+			kick_rx(dev);
+		}
+	}
+
+	if (dev->rx_info.up && nr_rx_empty(dev) > NR_RX_DESC*3/4)
+		schedule_task(&dev->tq_refill);
+	else
+		kick_rx(dev);
+	if (dev->rx_info.idle)
+		Dprintk("BAD\n");
+}
+
 /* rx_irq
  *	
  */
@@ -785,10 +806,10 @@
 	dprintk("rx_irq(%p)\n", dev);
 	dprintk("rxdp: %08x, descs: %08lx next_rx[%d]: %p next_empty[%d]: %p\n",
 		readl(dev->base + RXDP),
-		(dev->rx_info.phy_descs),
-		dev->rx_info.next_rx,
+		(long)(dev->rx_info.phy_descs),
+		(int)dev->rx_info.next_rx,
 		(dev->rx_info.descs + (DESC_SIZE * dev->rx_info.next_rx)),
-		dev->rx_info.next_empty,
+		(int)dev->rx_info.next_empty,
 		(dev->rx_info.descs + (DESC_SIZE * dev->rx_info.next_empty))
 		);
 
@@ -798,12 +819,12 @@
 
 	dprintk("walking descs\n");
 	next_rx = info->next_rx;
-	desc = info->descs + (DESC_SIZE * next_rx);
+	desc = info->next_rx_desc;
 	while ((CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[CMDSTS]))) &&
 	       (cmdsts != CMDSTS_OWN)) {
 		struct sk_buff *skb;
 		u32 extsts = le32_to_cpu(desc[EXTSTS]);
-		dmaaddr_high_t bufptr = le32_to_cpu(desc[BUFPTR]);
+		dma_addr_t bufptr = desc_addr_get(desc);
 
 		dprintk("cmdsts: %08x\n", cmdsts);
 		dprintk("link: %08x\n", cpu_to_le32(desc[LINK]));
@@ -813,29 +834,16 @@
 		info->skbs[next_rx] = NULL;
 		info->next_rx = (next_rx + 1) % NR_RX_DESC;
 
-		barrier();
+		mb();
 		clear_rx_desc(dev, next_rx);
 
 		pci_unmap_single(dev->pci_dev, bufptr,
 				 RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
-		if (CMDSTS_OK & cmdsts) {
-#if 0 //ndef __i386__
-			struct sk_buff *tmp;
-#endif
+		if (likely(CMDSTS_OK & cmdsts)) {
 			int len = cmdsts & 0xffff;
-			if (!skb)
-				BUG();
 			skb_put(skb, len);
-#if 0 //ndef __i386__	/* I hate the network stack sometimes */
-			tmp = __dev_alloc_skb(RX_BUF_SIZE+16, GFP_ATOMIC);
-			if (!tmp)
-				goto done;
-			tmp->dev = &dev->net_dev;
-			skb_reserve(tmp, 2);
-			memcpy(skb_put(tmp, len), skb->data, len);
-			kfree_skb(skb);
-			skb = tmp;
-#endif
+			if (unlikely(!skb))
+				goto netdev_mangle_me_harder_failed;
 			if (cmdsts & CMDSTS_DEST_MULTI)
 				dev->stats.multicast ++;
 			dev->stats.rx_packets ++;
@@ -846,11 +854,10 @@
 				skb->ip_summed = CHECKSUM_NONE;
 			}
 			skb->protocol = eth_type_trans(skb, &dev->net_dev);
-			if (NET_RX_DROP == netif_rx(skb))
+			if (NET_RX_DROP == netif_rx(skb)) {
+netdev_mangle_me_harder_failed:
 				dev->stats.rx_dropped ++;
-#if 0 //ndef __i386__
-		done:;
-#endif
+			}
 		} else {
 			kfree_skb(skb);
 		}
@@ -860,6 +867,7 @@
 		desc = info->descs + (DESC_SIZE * next_rx);
 	}
 	info->next_rx = next_rx;
+	info->next_rx_desc = info->descs + (DESC_SIZE * next_rx);
 
 out:
 	if (0 && !nr) {
@@ -869,6 +877,15 @@
 	spin_unlock_irqrestore(&info->lock, flags);
 }
 
+static void rx_action(unsigned long _dev)
+{
+	struct ns83820 *dev = (void *)_dev;
+	rx_irq(dev);
+	writel(0x002, dev->base + IHR);
+	writel(dev->IMR_cache | ISR_RXDESC, dev->base + IMR);
+	rx_irq(dev);
+	ns83820_rx_kick(dev);
+}
 
 /* Packet Transmit code
  */
@@ -879,7 +896,9 @@
 	writel(CR_TXE, dev->base + CR);
 }
 
-/* no spinlock needed on the transmit irq path as the interrupt handler is serialized */
+/* No spinlock needed on the transmit irq path as the interrupt handler is
+ * serialized.
+ */
 static void do_tx_done(struct ns83820 *dev)
 {
 	u32 cmdsts, tx_done_idx, *desc;
@@ -893,6 +912,8 @@
 	while ((tx_done_idx != dev->tx_free_idx) &&
 	       !(CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[CMDSTS]))) ) {
 		struct sk_buff *skb;
+		unsigned len;
+		dma_addr_t addr;
 
 		if (cmdsts & CMDSTS_ERR)
 			dev->stats.tx_errors ++;
@@ -906,18 +927,25 @@
 		skb = dev->tx_skbs[tx_done_idx];
 		dev->tx_skbs[tx_done_idx] = NULL;
 		dprintk("done(%p)\n", skb);
+
+		len = cmdsts & CMDSTS_LEN_MASK;
+		addr = desc_addr_get(desc);
 		if (skb) {
 			pci_unmap_single(dev->pci_dev,
-					le32_to_cpu(desc[BUFPTR]),
-					skb->len,
+					addr,
+					len,
 					PCI_DMA_TODEVICE);
 			dev_kfree_skb_irq(skb);
-		}
+		} else
+			pci_unmap_page(dev->pci_dev, 
+					addr,
+					len,
+					PCI_DMA_TODEVICE);
 
 		tx_done_idx = (tx_done_idx + 1) % NR_TX_DESC;
 		dev->tx_done_idx = tx_done_idx;
 		desc[CMDSTS] = cpu_to_le32(0);
-		barrier();
+		mb();
 		desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
 	}
 
@@ -952,14 +980,13 @@
  * while trying to track down a bug in either the zero copy code or
  * the tx fifo (hence the MAX_FRAG_LEN).
  */
-#define MAX_FRAG_LEN	8192	/* disabled for now */
 static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
 {
 	struct ns83820 *dev = (struct ns83820 *)_dev;
 	u32 free_idx, cmdsts, extsts;
 	int nr_free, nr_frags;
 	unsigned tx_done_idx;
-	dmaaddr_high_t buf;
+	dma_addr_t buf;
 	unsigned len;
 	skb_frag_t *frag;
 	int stopped = 0;
@@ -970,9 +997,9 @@
 
 	nr_frags =  skb_shinfo(skb)->nr_frags;
 again:
-	if (__builtin_expect(dev->CFG_cache & CFG_LNKSTS, 0)) {
+	if (unlikely(dev->CFG_cache & CFG_LNKSTS)) {
 		netif_stop_queue(&dev->net_dev);
-		if (__builtin_expect(dev->CFG_cache & CFG_LNKSTS, 0))
+		if (unlikely(dev->CFG_cache & CFG_LNKSTS))
 			return 1;
 		netif_start_queue(&dev->net_dev);
 	}
@@ -981,7 +1008,7 @@
 	tx_done_idx = dev->tx_done_idx;
 	nr_free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC;
 	nr_free -= 1;
-	if ((nr_free <= nr_frags) || (nr_free <= 8192 / MAX_FRAG_LEN)) {
+	if (nr_free <= nr_frags) {
 		dprintk("stop_queue - not enough(%p)\n", dev);
 		netif_stop_queue(&dev->net_dev);
 
@@ -996,11 +1023,11 @@
 
 	if (free_idx == dev->tx_intr_idx) {
 		do_intr = 1;
-		dev->tx_intr_idx = (dev->tx_intr_idx + NR_TX_DESC/2) % NR_TX_DESC;
+		dev->tx_intr_idx = (dev->tx_intr_idx + NR_TX_DESC/4) % NR_TX_DESC;
 	}
 
 	nr_free -= nr_frags;
-	if (nr_free < 1) {
+	if (nr_free < MIN_TX_DESC_FREE) {
 		dprintk("stop_queue - last entry(%p)\n", dev);
 		netif_stop_queue(&dev->net_dev);
 		stopped = 1;
@@ -1028,20 +1055,12 @@
 	for (;;) {
 		volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
 		u32 residue = 0;
-#if 0
-		if (len > MAX_FRAG_LEN) {
-			residue = len;
-			/* align the start address of the next fragment */
-			len = MAX_FRAG_LEN;
-			residue -= len;
-		}
-#endif
 
 		dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len,
 			(unsigned long long)buf);
 		free_idx = (free_idx + 1) % NR_TX_DESC;
 		desc[LINK] = cpu_to_le32(dev->tx_phy_descs + (free_idx * DESC_SIZE * 4));
-		desc[BUFPTR] = cpu_to_le32(buf);
+		desc_addr_set(desc, buf);
 		desc[EXTSTS] = cpu_to_le32(extsts);
 
 		cmdsts = ((nr_frags|residue) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0);
@@ -1058,11 +1077,12 @@
 		if (!nr_frags)
 			break;
 
-		buf = pci_map_single_high(dev->pci_dev, frag->page,
-					  frag->page_offset,
-					  frag->size, PCI_DMA_TODEVICE);
-		dprintk("frag: buf=%08Lx  page=%08lx\n",
-			(long long)buf, (long)(frag->page - mem_map));
+		buf = pci_map_page(dev->pci_dev, frag->page,
+				   frag->page_offset,
+				   frag->size, PCI_DMA_TODEVICE);
+		dprintk("frag: buf=%08Lx  page=%08lx offset=%08lx\n",
+			(long long)buf, (long)(frag->page - mem_map),
+			frag->page_offset);
 		len = frag->size;
 		frag++;
 		nr_frags--;
@@ -1084,6 +1104,7 @@
 {
 	u8 *base = dev->base;
 
+	/* the DP83820 will freeze counters, so we need to read all of them */
 	dev->stats.rx_errors		+= readl(base + 0x60) & 0xffff;
 	dev->stats.rx_crc_errors	+= readl(base + 0x64) & 0xffff;
 	dev->stats.rx_missed_errors	+= readl(base + 0x68) & 0xffff;
@@ -1162,54 +1183,54 @@
 	}
 }
 
+static void ns83820_mib_isr(struct ns83820 *dev)
+{
+	spin_lock(&dev->misc_lock);
+	ns83820_update_stats(dev);
+	spin_unlock(&dev->misc_lock);
+}
+
 static void ns83820_irq(int foo, void *data, struct pt_regs *regs)
 {
 	struct ns83820 *dev = data;
-	int count = 0;
 	u32 isr;
 	dprintk("ns83820_irq(%p)\n", dev);
 
 	dev->ihr = 0;
 
-	while (count++ < 32 && (isr = readl(dev->base + ISR))) {
-		dprintk("irq: %08x\n", isr);
-
-		if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC))
-			Dprintk("odd isr? 0x%08x\n", isr);
-
-	if ((ISR_RXEARLY | ISR_RXIDLE | ISR_RXORN | ISR_RXDESC | ISR_RXOK | ISR_RXERR) & isr) {
- 		if (ISR_RXIDLE & isr) {
-			dev->rx_info.idle = 1;
-			Dprintk("oh dear, we are idle\n");
-		}
+	isr = readl(dev->base + ISR);
+	dprintk("irq: %08x\n", isr);
 
-		if ((ISR_RXDESC) & isr) {
-			rx_irq(dev);
-			writel(4, dev->base + IHR);
-		}
-
-		if (nr_rx_empty(dev) >= NR_RX_DESC/4) {
-			if (dev->rx_info.up) {
-				rx_refill(dev, GFP_ATOMIC);
-				kick_rx(dev);
-			}
-		}
+#ifdef DEBUG
+	if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC))
+		Dprintk("odd isr? 0x%08x\n", isr);
+#endif
 
-		if (dev->rx_info.up && nr_rx_empty(dev) > NR_RX_DESC*3/4)
-			schedule_task(&dev->tq_refill);
-		else
-			kick_rx(dev);
-		if (dev->rx_info.idle)
-			Dprintk("BAD\n");
+	if (ISR_RXIDLE & isr) {
+		dev->rx_info.idle = 1;
+		Dprintk("oh dear, we are idle\n");
+		ns83820_rx_kick(dev);
+	}
+
+	if ((ISR_RXDESC | ISR_RXOK) & isr) {
+		prefetch(dev->rx_info.next_rx_desc);
+		writel(dev->IMR_cache & ~(ISR_RXDESC | ISR_RXOK), dev->base + IMR);
+		tasklet_schedule(&dev->rx_tasklet);
+		//rx_irq(dev);
+		//writel(4, dev->base + IHR);
 	}
 
+	if ((ISR_RXIDLE | ISR_RXORN | ISR_RXDESC | ISR_RXOK | ISR_RXERR) & isr)
+		ns83820_rx_kick(dev);
+
 	if (unlikely(ISR_RXSOVR & isr)) {
-		Dprintk("overrun: rxsovr\n");
-		dev->stats.rx_over_errors ++;
+		//printk("overrun: rxsovr\n");
+		dev->stats.rx_fifo_errors ++;
 	}
+
 	if (unlikely(ISR_RXORN & isr)) {
-		Dprintk("overrun: rxorn\n");
-		dev->stats.rx_over_errors ++;
+		//printk("overrun: rxorn\n");
+		dev->stats.rx_fifo_errors ++;
 	}
 
 	if ((ISR_RXRCMP & isr) && dev->rx_info.up)
@@ -1241,15 +1262,11 @@
 	if ((ISR_TXDESC | ISR_TXIDLE) & isr)
 		do_tx_done(dev);
 
-	if (ISR_MIB & isr) {
-		spin_lock(&dev->misc_lock);
-		ns83820_update_stats(dev);
-		spin_unlock(&dev->misc_lock);
-	}
+	if (unlikely(ISR_MIB & isr))
+		ns83820_mib_isr(dev);
 
-	if (ISR_PHY & isr)
+	if (unlikely(ISR_PHY & isr))
 		phy_intr(dev);
-	}
 
 #if 0	/* Still working on the interrupt mitigation strategy */
 	if (dev->ihr)
@@ -1396,6 +1413,16 @@
 	struct ns83820 *dev;
 	long addr;
 	int err;
+	int using_dac = 0;
+
+	if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffff)) {
+		using_dac = 1;
+	} else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) {
+		using_dac = 0;
+	} else {
+		printk(KERN_WARNING "ns83820.c: pci_set_dma_mask failed!\n");
+		return -ENODEV;
+	}
 
 	dev = (struct ns83820 *)alloc_etherdev((sizeof *dev) - (sizeof dev->net_dev));
 	err = -ENOMEM;
@@ -1412,6 +1439,7 @@
 	dev->net_dev.owner = THIS_MODULE;
 
 	PREPARE_TQUEUE(&dev->tq_refill, queue_refill, dev);
+	tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)dev);
 
 	err = pci_enable_device(pci_dev);
 	if (err) {
@@ -1430,8 +1458,9 @@
 	if (!dev->base || !dev->tx_descs || !dev->rx_info.descs)
 		goto out_disable;
 
-	dprintk("%p: %08lx  %p: %08lx\n", dev->tx_descs, dev->tx_phy_descs,
-		dev->rx_info.descs, dev->rx_info.phy_descs);
+	dprintk("%p: %08lx  %p: %08lx\n",
+		dev->tx_descs, (long)dev->tx_phy_descs,
+		dev->rx_info.descs, (long)dev->rx_info.phy_descs);
 	/* disable interrupts */
 	writel(0, dev->base + IMR);
 	writel(0, dev->base + IER);
@@ -1484,14 +1513,14 @@
 	dev->CFG_cache = readl(dev->base + CFG);
 
 	if ((dev->CFG_cache & CFG_PCI64_DET)) {
-		printk("%s: enabling 64 bit PCI addressing.\n",
+		printk("%s: detected 64 bit PCI data bus.\n",
 			dev->net_dev.name);
-		dev->CFG_cache |= CFG_T64ADDR | CFG_DATA64_EN;
-#if defined(USE_64BIT_ADDR)
-		dev->net_dev.features |= NETIF_F_HIGHDMA;
-#endif
+		/*dev->CFG_cache |= CFG_DATA64_EN;*/
+		if (!(dev->CFG_cache & CFG_DATA64_EN))
+			printk("%s: EEPROM did not enable 64 bit bus.  Disabled.\n",
+				dev->net_dev.name);
 	} else
-		dev->CFG_cache &= ~(CFG_T64ADDR | CFG_DATA64_EN);
+		dev->CFG_cache &= ~(CFG_DATA64_EN);
 
 	dev->CFG_cache &= (CFG_TBI_EN  | CFG_MRM_DIS   | CFG_MWI_DIS |
 			   CFG_T64ADDR | CFG_DATA64_EN | CFG_EXT_125 |
@@ -1503,6 +1532,9 @@
 #ifdef USE_64BIT_ADDR
 	dev->CFG_cache |= CFG_M64ADDR;
 #endif
+	if (using_dac)
+		dev->CFG_cache |= CFG_T64ADDR;
+
 	/* Big endian mode does not seem to do what the docs suggest */
 	dev->CFG_cache &= ~CFG_BEM;
 
@@ -1528,8 +1560,12 @@
 	writel(dev->CFG_cache, dev->base + CFG);
 	dprintk("CFG: %08x\n", dev->CFG_cache);
 
+#if 0	/* Huh?  This sets the PCI latency register.  Should be done via 
+	 * the PCI layer.  FIXME.
+	 */
 	if (readl(dev->base + SRR))
 		writel(readl(dev->base+0x20c) | 0xfe00, dev->base + 0x20c);
+#endif
 
 	/* Note!  The DMA burst size interacts with packet
 	 * transmission, such that the largest packet that
@@ -1543,13 +1579,15 @@
 	/* Flush the interrupt holdoff timer */
 	writel(0x000, dev->base + IHR);
 	writel(0x100, dev->base + IHR);
+	writel(0x000, dev->base + IHR);
 
 	/* Set Rx to full duplex, don't accept runt, errored, long or length
-	 * range errored packets.  Set MXDMA to 7 => 512 word burst
+	 * range errored packets.  Set MXDMA to 0 => 1024 word burst
 	 */
 	writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD
+		| RXCFG_STRIPCRC
 		| RXCFG_ALP
-		| RXCFG_MXDMA | 0, dev->base + RXCFG);
+		| (RXCFG_MXDMA0 * 0) | 0, dev->base + RXCFG);
 
 	/* Disable priority queueing */
 	writel(0, dev->base + PQCR);
@@ -1575,9 +1613,12 @@
 	/* Yes, we support dumb IP checksum on transmit */
 	dev->net_dev.features |= NETIF_F_SG;
 	dev->net_dev.features |= NETIF_F_IP_CSUM;
-#if defined(USE_64BIT_ADDR) || defined(CONFIG_HIGHMEM4G)
-	dev->net_dev.features |= NETIF_F_HIGHDMA;
-#endif
+
+	if (using_dac) {
+		printk(KERN_INFO "%s: using 64 bit addressing.\n",
+			dev->net_dev.name);
+		dev->net_dev.features |= NETIF_F_HIGHDMA;
+	}
 
 	printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %02x:%02x:%02x:%02x:%02x:%02x io=0x%08lx irq=%d f=%s\n",
 		dev->net_dev.name,
@@ -1587,7 +1628,7 @@
 		dev->net_dev.dev_addr[2], dev->net_dev.dev_addr[3],
 		dev->net_dev.dev_addr[4], dev->net_dev.dev_addr[5],
 		addr, pci_dev->irq,
-		(dev->net_dev.features & NETIF_F_HIGHDMA) ? "sg" : "h,sg"
+		(dev->net_dev.features & NETIF_F_HIGHDMA) ? "h,sg" : "sg"
 		);
 
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pci-skeleton.c linux/drivers/net/pci-skeleton.c
--- linux.orig/drivers/net/pci-skeleton.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/pci-skeleton.c	2002-07-20 01:08:23.000000000 +0000
@@ -96,6 +96,7 @@
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/crc32.h>
 #include <asm/io.h>
 
 #define NETDRV_VERSION		"1.0.0"
@@ -509,7 +510,6 @@
 static int netdrv_close (struct net_device *dev);
 static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static struct net_device_stats *netdrv_get_stats (struct net_device *dev);
-static inline u32 ether_crc (int length, unsigned char *data);
 static void netdrv_set_rx_mode (struct net_device *dev);
 static void netdrv_hw_start (struct net_device *dev);
 
@@ -1853,27 +1853,6 @@
 /* Set or clear the multicast filter for this adaptor.
    This routine is not state sensitive and need not be SMP locked. */
 
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc (int length, unsigned char *data)
-{
-	int crc = -1;
-
-	DPRINTK ("ENTER\n");
-
-	while (--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
-			crc = (crc << 1) ^
-			    ((crc < 0) ^ (current_octet & 1) ?
-			     ethernet_polynomial : 0);
-	}
-
-	DPRINTK ("EXIT\n");
-	return crc;
-}
-
-
 static void netdrv_set_rx_mode (struct net_device *dev)
 {
 	struct netdrv_private *tp = dev->priv;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pcmcia/com20020_cs.c linux/drivers/net/pcmcia/com20020_cs.c
--- linux.orig/drivers/net/pcmcia/com20020_cs.c	2001-04-18 21:40:05.000000000 +0000
+++ linux/drivers/net/pcmcia/com20020_cs.c	2002-07-20 01:08:36.000000000 +0000
@@ -122,6 +122,7 @@
 
 MODULE_PARM(irq_mask, "i");
 MODULE_PARM(irq_list, "1-4i");
+MODULE_LICENSE("GPL");
 
 /*====================================================================*/
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pcmcia/fmvj18x_cs.c linux/drivers/net/pcmcia/fmvj18x_cs.c
--- linux.orig/drivers/net/pcmcia/fmvj18x_cs.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/pcmcia/fmvj18x_cs.c	2002-07-20 01:08:26.000000000 +0000
@@ -53,6 +53,7 @@
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
+#include <linux/crc32.h>
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
@@ -1248,27 +1249,6 @@
   Set the multicast/promiscuous mode for this adaptor.
 */
 
-/* The little-endian AUTODIN II ethernet CRC calculation.
-   N.B. Do not use for bulk data, use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-    unsigned int crc = 0xffffffff;	/* Initial value. */
-    while(--length >= 0) {
-	unsigned char current_octet = *data++;
-	int bit;
-	for (bit = 8; --bit >= 0; current_octet >>= 1) {
-	    if ((crc ^ current_octet) & 1) {
-		crc >>= 1;
-		crc ^= ethernet_polynomial_le;
-	    } else
-		crc >>= 1;
-	}
-    }
-    return crc;
-}
-
 static void set_rx_mode(struct net_device *dev)
 {
     ioaddr_t ioaddr = dev->base_addr;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c
--- linux.orig/drivers/net/pcmcia/ray_cs.c	2001-10-12 21:21:18.000000000 +0000
+++ linux/drivers/net/pcmcia/ray_cs.c	2002-07-20 01:08:33.000000000 +0000
@@ -999,7 +999,9 @@
 /*===========================================================================*/
 int ray_dev_init(struct net_device *dev)
 {
+#ifdef RAY_IMMEDIATE_INIT
     int i;
+#endif	/* RAY_IMMEDIATE_INIT */
     ray_dev_t *local = dev->priv;
     dev_link_t *link = local->finder;
 
@@ -1008,6 +1010,7 @@
         DEBUG(2,"ray_dev_init - device not present\n");
         return -1;
     }
+#ifdef RAY_IMMEDIATE_INIT
     /* Download startup parameters */
     if ( (i = dl_startup_params(dev)) < 0)
     {
@@ -1015,7 +1018,14 @@
            "returns 0x%x\n",i);
         return -1;
     }
-    
+#else	/* RAY_IMMEDIATE_INIT */
+    /* Postpone the card init so that we can still configure the card,
+     * for example using the Wireless Extensions. The init will happen
+     * in ray_open() - Jean II */
+    DEBUG(1,"ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
+	  local->card_status);
+#endif	/* RAY_IMMEDIATE_INIT */
+
     /* copy mac and broadcast addresses to linux device */
     memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
     memset(dev->broadcast, 0xff, ETH_ALEN);
@@ -1245,6 +1255,22 @@
       wrq->u.freq.e = 0;
       break;
 
+      /* Set frequency/channel */
+    case SIOCSIWFREQ:
+      /* Reject if card is already initialised */
+      if(local->card_status != CARD_AWAITING_PARAM)
+	{
+	  err = -EBUSY;
+	  break;
+	}
+
+      /* Setting by channel number */
+      if ((wrq->u.freq.m > USA_HOP_MOD) || (wrq->u.freq.e > 0))
+	err = -EOPNOTSUPP;
+      else
+	  local->sparm.b5.a_hop_pattern = wrq->u.freq.m;
+      break;
+
       /* Get current network name (ESSID) */
     case SIOCGIWESSID:
       if (wrq->u.data.pointer)
@@ -1262,6 +1288,46 @@
 	}
       break;
 
+      /* Set desired network name (ESSID) */
+    case SIOCSIWESSID:
+      /* Reject if card is already initialised */
+      if(local->card_status != CARD_AWAITING_PARAM)
+	{
+	  err = -EBUSY;
+	  break;
+	}
+
+	if (wrq->u.data.pointer)
+	{
+	    char	card_essid[IW_ESSID_MAX_SIZE + 1];
+	    
+	    /* Check if we asked for `any' */
+	    if(wrq->u.data.flags == 0)
+	    {
+		/* Corey : can you do that ? */
+		err = -EOPNOTSUPP;
+	    }
+	    else
+	    {
+		/* Check the size of the string */
+		if(wrq->u.data.length >
+		   IW_ESSID_MAX_SIZE + 1)
+		{
+		    err = -E2BIG;
+		    break;
+		}
+		copy_from_user(card_essid,
+			       wrq->u.data.pointer,
+			       wrq->u.data.length);
+		card_essid[IW_ESSID_MAX_SIZE] = '\0';
+
+		/* Set the ESSID in the card */
+		memcpy(local->sparm.b5.a_current_ess_id, card_essid,
+		       IW_ESSID_MAX_SIZE);
+	    }
+	}
+	break;
+
       /* Get current Access Point (BSSID in our case) */
     case SIOCGIWAP:
       memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN);
@@ -1304,6 +1370,34 @@
       wrq->u.rts.fixed = 1;
       break;
 
+      /* Set the desired RTS threshold */
+    case SIOCSIWRTS:
+    {
+	int rthr = wrq->u.rts.value;
+
+      /* Reject if card is already initialised */
+      if(local->card_status != CARD_AWAITING_PARAM)
+	{
+	  err = -EBUSY;
+	  break;
+	}
+
+	/* if(wrq->u.rts.fixed == 0) we should complain */
+#if WIRELESS_EXT > 8
+	if(wrq->u.rts.disabled)
+	    rthr = 32767;
+	else
+#endif /* WIRELESS_EXT > 8 */
+	    if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
+	    {
+		err = -EINVAL;
+		break;
+	    }
+	local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
+	local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
+    }
+    break;
+
       /* Get the current fragmentation threshold */
     case SIOCGIWFRAG:
       wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
@@ -1313,6 +1407,35 @@
 #endif /* WIRELESS_EXT > 8 */
       wrq->u.frag.fixed = 1;
       break;
+
+      /* Set the desired fragmentation threshold */
+    case SIOCSIWFRAG:
+    {
+	int fthr = wrq->u.frag.value;
+
+      /* Reject if card is already initialised */
+      if(local->card_status != CARD_AWAITING_PARAM)
+	{
+	  err = -EBUSY;
+	  break;
+	}
+
+	/* if(wrq->u.frag.fixed == 0) should complain */
+#if WIRELESS_EXT > 8
+	if(wrq->u.frag.disabled)
+	    fthr = 32767;
+	else
+#endif /* WIRELESS_EXT > 8 */
+	    if((fthr < 256) || (fthr > 2347)) /* To check out ! */
+	    {
+		err = -EINVAL;
+		break;
+	    }
+	local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
+	local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
+    }
+    break;
+
 #endif	/* WIRELESS_EXT > 7 */
 #if WIRELESS_EXT > 8
 
@@ -1323,6 +1446,33 @@
       else
 	wrq->u.mode = IW_MODE_ADHOC;
       break;
+
+      /* Set the current mode of operation */
+    case SIOCSIWMODE:
+    {
+	char card_mode = 1;
+	
+      /* Reject if card is already initialised */
+      if(local->card_status != CARD_AWAITING_PARAM)
+	{
+	  err = -EBUSY;
+	  break;
+	}
+
+	switch (wrq->u.mode)
+	{
+	case IW_MODE_ADHOC:
+	    card_mode = 0;
+	    // Fall through
+	case IW_MODE_INFRA:
+	    local->sparm.b5.a_network_type = card_mode;
+	    break;
+	default:
+	    err = -EINVAL;
+	}
+    }
+    break;
+
 #endif /* WIRELESS_EXT > 8 */
 #if WIRELESS_EXT > 7
       /* ------------------ IWSPY SUPPORT ------------------ */
@@ -1549,6 +1699,21 @@
     if (link->open == 0) local->num_multi = 0;
     link->open++;
 
+    /* If the card is not started, time to start it ! - Jean II */
+    if(local->card_status == CARD_AWAITING_PARAM) {
+	int i;
+
+	DEBUG(1,"ray_open: doing init now !\n");
+
+	/* Download startup parameters */
+	if ( (i = dl_startup_params(dev)) < 0)
+	  {
+	    printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
+		   "returns 0x%x\n",i);
+	    return -1;
+	  }
+     }
+
     if (sniffer) netif_stop_queue(dev);
     else         netif_start_queue(dev);
 
@@ -1572,6 +1737,11 @@
     if (link->state & DEV_STALE_CONFIG)
 	mod_timer(&link->release, jiffies + HZ/20);
 
+    /* In here, we should stop the hardware (stop card from beeing active)
+     * and set local->card_status to CARD_AWAITING_PARAM, so that while the
+     * card is closed we can chage its configuration.
+     * Probably also need a COR reset to get sane state - Jean II */
+
     MOD_DEC_USE_COUNT;
 
     return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pcmcia/smc91c92_cs.c linux/drivers/net/pcmcia/smc91c92_cs.c
--- linux.orig/drivers/net/pcmcia/smc91c92_cs.c	2001-11-13 17:02:30.000000000 +0000
+++ linux/drivers/net/pcmcia/smc91c92_cs.c	2002-07-20 01:08:26.000000000 +0000
@@ -34,6 +34,7 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -1740,31 +1741,6 @@
     return &smc->stats;
 }
 
-/*======================================================================
-
-    Compute the AUTODIN polynomial "CRC32" for ethernet packets.
-
-======================================================================*/
-
-static const u_int ethernet_polynomial = 0x04c11db7U;
-
-static u_int ether_crc(int length, u_char *data)
-{
-    int crc = 0xffffffff;	/* Initial value. */
-    
-    while (--length >= 0) {
-	u_char current_octet = *data++;
-	int bit;
-	for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
-	    crc = (crc << 1) ^
-		((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
-	}
-    }
-    /* The hash index is the either the upper or lower bits of the CRC, so
-     * we return the entire CRC.
-     */
-    return crc;
-}
 
 /*======================================================================
   
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pcmcia/wavelan_cs.c linux/drivers/net/pcmcia/wavelan_cs.c
--- linux.orig/drivers/net/pcmcia/wavelan_cs.c	2001-11-09 23:22:54.000000000 +0000
+++ linux/drivers/net/pcmcia/wavelan_cs.c	2002-07-20 01:08:22.000000000 +0000
@@ -22,7 +22,7 @@
 #ifdef WAVELAN_ROAMING	
  * Roaming support added 07/22/98 by Justin Seger (jseger@media.mit.edu)
  * based on patch by Joe Finney from Lancaster University.
-#endif :-)
+#endif
  *
  * Lucent (formerly AT&T GIS, formerly NCR) WaveLAN PCMCIA card: An
  * Ethernet-like radio transceiver controlled by an Intel 82593 coprocessor.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pcmcia/xircom_cb.c linux/drivers/net/pcmcia/xircom_cb.c
--- linux.orig/drivers/net/pcmcia/xircom_cb.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/pcmcia/xircom_cb.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,37 +1,45 @@
 /*
  * xircom_cb: A driver for the (tulip-like) Xircom Cardbus ethernet cards 
  *
- * This software is Copyright 2001 by the respective authors, and licensed under the GPL
+ * This software is (C) by the respective authors, and licensed under the GPL
  * License.
  *
  * Written by Arjan van de Ven for Red Hat, Inc.
- * Based on work by Jeff Garzik, Doug Ledford, Donald Becker and Ion Badulescu
+ * Based on work by Jeff Garzik, Doug Ledford and Donald Becker 
  *
  *  	This software may be used and distributed according to the terms
  *      of the GNU General Public License, incorporated herein by reference.
  *
  *
- * 	$Id: xircom_cb.c,v 1.11 2001/06/05 09:50:57 fenrus Exp $
+ * 	$Id: xircom_cb.c,v 1.33 2001/03/19 14:02:07 arjanv Exp $
  */
 
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/skbuff.h>
 #include <linux/delay.h>
+#include <linux/init.h>
+#include <asm/bitops.h>
 #include <asm/io.h>
 
 
 
 #ifdef DEBUG
-#define enter()   printk("Enter: %s, %s line %i\n",__FUNCTION__,__FILE__,__LINE__)
-#define leave()   printk("Leave: %s, %s line %i\n",__FUNCTION__,__FILE__,__LINE__)
+#define enter(x)   printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__)
+#define leave(x)   printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__)
 #else
-#define enter()   do {} while (0)
-#define leave()   do {} while (0)
+#define enter(x)   do {} while (0)
+#define leave(x)   do {} while (0)
 #endif
 
 
@@ -66,52 +74,27 @@
 /* Offsets of the buffers within the descriptor pages, in bytes */
 
 #define NUMDESCRIPTORS 4
-#define RXTXBUFSIZE 8192
-#define MAX_PACKETSIZE 1536
 
-
-#define DescOwnedCard	0x80000000
-#define DescOwnedDriver	0x00000000
-
-#define PromiscBit		(1<<6)
-#define CollisionBit 		(1<<8)
-#define TxActiveBit		(1<<13)
-#define RxActiveBit		(1<<1)
-#define LastDescBit	 	(1<<25)
-#define LinkStatusBit 		(1<<27)
-
-#define PowerMgmtBits		( (1<<31)|(1<<30) )
-
-static const unsigned int bufferoffsets[NUMDESCRIPTORS] = {128,2048,4096,6144};
-
-/* note: this struct is assumed to be packed as this is the "hardware" layout */
-struct descriptor {
-	u32	status;
-	u32	control;
-	u32	address1;
-	u32	address2;
-};
+static int bufferoffsets[NUMDESCRIPTORS] = {128,2048,4096,6144};
 
 
 struct xircom_private {
 	/* Send and receive buffers, kernel-addressable and dma addressable forms */
 
-	unsigned char *rx_buffer;
-	unsigned char *tx_buffer;
-	
-	struct descriptor *rx_desc;
-	struct descriptor *tx_desc;
+	unsigned int *rx_buffer;
+	unsigned int *tx_buffer;
 
 	dma_addr_t rx_dma_handle;
 	dma_addr_t tx_dma_handle;
 
-	struct sk_buff *tx_skb[NUMDESCRIPTORS];
+	struct sk_buff *tx_skb[4];
 
 	unsigned long io_port;
+	int open;
 	
 	/* transmit_used is the rotating counter that indicates which transmit
 	   descriptor has to be used next */
-	unsigned int transmit_used;
+	int transmit_used;
 
 	/* Spinlock to serialize register operations.
 	   It must be helt while manipulating the following registers:
@@ -136,16 +119,16 @@
 static void xircom_up(struct xircom_private *card);
 static struct net_device_stats *xircom_get_stats(struct net_device *dev);
 
-static void investigate_rx_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset);
-static unsigned int investigate_tx_descriptor(struct net_device *dev, struct xircom_private *card, unsigned int descnr, unsigned int bufferoffset);
+static void investigate_read_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset);
+static void investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsigned int bufferoffset);
 static void read_mac_address(struct xircom_private *card);
 static void tranceiver_voodoo(struct xircom_private *card);
 static void initialize_card(struct xircom_private *card);
-static inline void trigger_transmit(struct xircom_private *card);
-static inline void trigger_receive(struct xircom_private *card);
+static void trigger_transmit(struct xircom_private *card);
+static void trigger_receive(struct xircom_private *card);
 static void setup_descriptors(struct xircom_private *card);
-static inline void remove_descriptors(struct xircom_private *card);
-static inline unsigned int link_status_changed(struct xircom_private *card);
+static void remove_descriptors(struct xircom_private *card);
+static int link_status_changed(struct xircom_private *card);
 static void activate_receiver(struct xircom_private *card);
 static void deactivate_receiver(struct xircom_private *card);
 static void activate_transmitter(struct xircom_private *card);
@@ -154,9 +137,7 @@
 static void enable_receive_interrupt(struct xircom_private *card);
 static void enable_link_interrupt(struct xircom_private *card);
 static void disable_all_interrupts(struct xircom_private *card);
-static inline unsigned int link_status(struct xircom_private *card);
-static int mdio_read(struct xircom_private *card, int phy_id, int location);
-static void mdio_write(struct xircom_private *card, int phy_id, int location, int value);
+static int link_status(struct xircom_private *card);
 
 
 
@@ -170,7 +151,7 @@
 	name:		"xircom_cb", 
 	id_table:	xircom_pci_table, 
 	probe:		xircom_probe, 
-	remove:		__devexit_p(xircom_remove), 
+	remove:		__devexit_p(xircom_remove),
 };
 
 
@@ -204,25 +185,20 @@
 {
 	struct net_device *dev = NULL;
 	struct xircom_private *private;
-	u8 chip_rev;
+	unsigned char chip_rev;
 	unsigned long flags;
-	u32 tmp32;
-	u16 tmp16;
-	int ret;
-	enter();
+	unsigned short tmp16;
+	enter("xircom_probe");
 	
 	/* First do the PCI initialisation */
 
-	ret = pci_enable_device(pdev);
-	if (ret)
-		return ret;
+	if (pci_enable_device(pdev))
+		return -ENODEV;
 
 	/* disable all powermanagement */
-	pci_read_config_dword(pdev, PCI_POWERMGMT,&tmp32);
-	tmp32 &= ~PowerMgmtBits; 
-	pci_write_config_dword(pdev, PCI_POWERMGMT, tmp32);
+	pci_write_config_dword(pdev, PCI_POWERMGMT, 0x0000);
 	
-	pci_set_master(pdev); 
+	pci_set_master(pdev); /* Why isn't this done by pci_enable_device ?*/
 
 	/* clear PCI status, if any */ 
 	pci_read_config_word (pdev,PCI_STATUS, &tmp16); 
@@ -236,39 +212,38 @@
 	}
 
 	
-	dev = init_etherdev(dev, sizeof(*private));
-	if (dev == NULL) {
-		printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n");
-		return -ENODEV;
-	}
-	SET_MODULE_OWNER(dev);
-	private = dev->priv;
-	if (private==NULL) {
-		printk(KERN_ERR "xircom_probe: failed to allocate private device struct\n");
-		return -ENODEV;
-	}
-		
+	/* 
+	   Before changing the hardware, allocate the memory.
+	   This way, we can fail gracefully if not enough memory
+	   is available. 
+	 */
+	private = kmalloc(sizeof(*private),GFP_KERNEL);
+	memset(private, 0, sizeof(struct xircom_private));
+	
 	/* Allocate the send/receive buffers */
-	private->rx_buffer = pci_alloc_consistent(pdev,RXTXBUFSIZE,&private->rx_dma_handle);
+	private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle);
+	
 	if (private->rx_buffer == NULL) {
  		printk(KERN_ERR "xircom_probe: no memory for rx buffer \n");
  		kfree(private);
 		return -ENODEV;
 	}	
-	/* the descriptors are stored in the first bytes of the rx_buffer, hence the ugly cast */
-	private->rx_desc = (struct descriptor *)private->rx_buffer;
-
-	private->tx_buffer = pci_alloc_consistent(pdev,RXTXBUFSIZE,&private->tx_dma_handle);
+	private->tx_buffer = pci_alloc_consistent(pdev,8192,&private->tx_dma_handle);
 	if (private->tx_buffer == NULL) {
 		printk(KERN_ERR "xircom_probe: no memory for tx buffer \n");
 		kfree(private->rx_buffer);
 		kfree(private);
 		return -ENODEV;
 	}
-	/* the descriptors are stored in the first bytes of the tx_buffer, hence the ugly cast */
-	private->tx_desc = (struct descriptor *)private->tx_buffer;
-	
-	
+	dev = init_etherdev(dev, 0);
+	if (dev == NULL) {
+		printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n");
+		kfree(private->rx_buffer);
+		kfree(private->tx_buffer);
+		kfree(private);
+		return -ENODEV;
+	}
+	SET_MODULE_OWNER(dev);
 	printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq);
 
 	private->dev = dev;
@@ -288,25 +263,21 @@
 	dev->stop = &xircom_close;
 	dev->get_stats = &xircom_get_stats;
 	dev->priv = private;
-	pci_set_drvdata(pdev,dev);
+	pdev->driver_data = dev;
 
 	
-	/* start the transmitter to get a heartbeat; don't do
-	   that when there already is one though; Cisco's 
-	   really don't like that. */
-	if (!link_status(private))
-		tranceiver_voodoo(private);
+	/* start the transmitter to get a heartbeat */
+	/* TODO: send 2 dummy packets here */
+	tranceiver_voodoo(private);
 	
 	spin_lock_irqsave(&private->lock,flags);
 	  activate_transmitter(private);
 	  activate_receiver(private);
 	spin_unlock_irqrestore(&private->lock,flags);
-
-	/* TODO: send 2 dummy packets here */
 	
 	trigger_receive(private);
 	
-	leave();
+	leave("xircom_probe");
 	return 0;
 }
 
@@ -319,138 +290,131 @@
  */
 static void __devexit xircom_remove(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
+	struct net_device *dev = pdev->driver_data;
 	struct xircom_private *card;
-	enter();
-	
-	card=dev->priv;
-
-	if (card->rx_buffer!=NULL)
-		pci_free_consistent(pdev,RXTXBUFSIZE,card->rx_buffer,card->rx_dma_handle);
-	card->rx_buffer = NULL;
-	card->rx_desc = NULL;
-	if (card->tx_buffer!=NULL)
-		pci_free_consistent(pdev,RXTXBUFSIZE,card->tx_buffer,card->tx_dma_handle);
-	card->tx_buffer = NULL;			
-	card->tx_desc = NULL;
-
+	enter("xircom_remove");
+	if (dev!=NULL) {
+		card=dev->priv;
+		if (card!=NULL) {	
+			if (card->rx_buffer!=NULL)
+				pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
+			card->rx_buffer = NULL;
+			if (card->tx_buffer!=NULL)
+				pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
+			card->tx_buffer = NULL;			
+		}
+		kfree(card);
+	}
 	release_region(dev->base_addr, 128);
 	unregister_netdev(dev);
 	kfree(dev);
-	pci_set_drvdata(pdev,NULL);
-	leave();
+	leave("xircom_remove");
 } 
 
 static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
-	struct net_device *dev = dev_instance;
-	struct xircom_private *card = dev->priv;
-	u32 status;
-	unsigned int xmit_free_count;
-	unsigned int i;
-
-	enter();
+	struct net_device *dev = (struct net_device *) dev_instance;
+	struct xircom_private *card = (struct xircom_private *) dev->priv;
+	unsigned int status;
+	int i;
 
+	enter("xircom_interrupt\n");
 
 	spin_lock(&card->lock);
 	status = inl(card->io_port+CSR5);
-	if (status==0xffffffff) {/* card has been ejected / powered down */
-		spin_unlock(&card->lock);
-		return;
-	}
 
-	/* Todo: check if there were any events at all; to speed up
-	   returning if we're on a shared interrupt */	
+#if DEBUG	
+	print_binary(status);
+	printk("tx status 0x%08x 0x%08x \n",card->tx_buffer[0],card->tx_buffer[4]);
+	printk("rx status 0x%08x 0x%08x \n",card->rx_buffer[0],card->rx_buffer[4]);
+#endif	
 
 	if (link_status_changed(card)) {
 		int newlink;
 		printk(KERN_DEBUG "xircom_cb: Link status has changed \n");
 		newlink = link_status(card);
-		if (newlink) {
-			printk(KERN_INFO  "xircom_cb: Link is %i mbit \n",newlink);
+		printk(KERN_INFO  "xircom_cb: Link is %i mbit \n",newlink);
+		if (newlink)
 			netif_carrier_on(dev);
-		} else {
-			printk(KERN_INFO  "xircom_cb: Link is absent \n");
+		else
 			netif_carrier_off(dev);
-		}
+		
 	}
 
-	/* Clear all remaining interrupt events */	
+	/* Clear all remaining interrupts */	
 	status |= 0xffffffff; /* FIXME: make this clear only the
 				        real existing bits */
 	outl(status,card->io_port+CSR5);
 	
-	xmit_free_count = 0;
 
 	for (i=0;i<NUMDESCRIPTORS;i++) 
-		xmit_free_count += investigate_tx_descriptor(dev,card,i,bufferoffsets[i]);
+		investigate_write_descriptor(dev,card,i,bufferoffsets[i]);
 	for (i=0;i<NUMDESCRIPTORS;i++) 
-		investigate_rx_descriptor(dev,card,i,bufferoffsets[i]);
+		investigate_read_descriptor(dev,card,i,bufferoffsets[i]);
 
 	
-	if (xmit_free_count)
-		netif_start_queue(dev);
-		
 	spin_unlock(&card->lock);
-	leave();
+	leave("xircom_interrupt");
 }
 
 static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct xircom_private *card;
 	unsigned long flags;
-	unsigned int nextdescriptor;
-	unsigned int desc;
-	enter();
+	int nextdescriptor;
+	int desc;
+	enter("xircom_start_xmit");
 	
 	card = (struct xircom_private*)dev->priv;
-
 	spin_lock_irqsave(&card->lock,flags);
 	
+	/* First see if we can free some descriptors */
+	for (desc=0;desc<NUMDESCRIPTORS;desc++) 
+		investigate_write_descriptor(dev,card,desc,bufferoffsets[desc]);
+	
+	
 	nextdescriptor = (card->transmit_used +1) % (NUMDESCRIPTORS);
 	desc = card->transmit_used;
 	
 	/* only send the packet if the descriptor is free */
-	if (card->tx_desc[desc].status==0) {
+	if (card->tx_buffer[4*desc]==0) {
 			/* Copy the packet data; zero the memory first as the card
 			   sometimes sends more than you ask it to. */
 			
-			memset(&card->tx_buffer[bufferoffsets[desc]],0,MAX_PACKETSIZE);
-			memcpy(&(card->tx_buffer[bufferoffsets[desc]]),skb->data,skb->len);
+			memset(&card->tx_buffer[bufferoffsets[desc]/4],0,1536);
+			memcpy(&(card->tx_buffer[bufferoffsets[desc]/4]),skb->data,skb->len);
 	
 	
 			/* FIXME: The specification tells us that the length we send HAS to be a multiple of
 			   4 bytes. */
 			   
-			card->tx_desc[desc].control = skb->len;
+			card->tx_buffer[4*desc+1] = skb->len;
 			if (desc == NUMDESCRIPTORS-1)
-				card->tx_desc[desc].control |= LastDescBit;  /* bit 25: last descriptor of the ring */
+				card->tx_buffer[4*desc+1] |= (1<<25);  /* bit 25: last descriptor of the ring */
 
-			card->tx_desc[desc].control |= 0xF0000000;
+			card->tx_buffer[4*desc+1] |= 0xF0000000;
 						 /* 0xF0... means want interrupts*/ 
 			card->tx_skb[desc] = skb;
 			
 			wmb();
 			/* This gives the descriptor to the card */
-			card->tx_desc[desc].status = DescOwnedCard;
+			card->tx_buffer[4*desc] = 0x80000000;
 			trigger_transmit(card);
-			if (((int)card->tx_desc[nextdescriptor].status)<0) {	/* next descriptor is occupied... */
+			if (((int)card->tx_buffer[nextdescriptor*4])<0) {	/* next descriptor is occupied... */
 				netif_stop_queue(dev);
 			}
 			card->transmit_used = nextdescriptor;
+			leave("xircom-start_xmit - sent");	
 			spin_unlock_irqrestore(&card->lock,flags);
-			leave();
 			return 0;
 	}
 	
 
 
 	/* Uh oh... no free descriptor... drop the packet */
-	/* This should not happen in theory...*/
 	netif_stop_queue(dev);
 	spin_unlock_irqrestore(&card->lock,flags);
 	trigger_transmit(card);
-	leave();
 	
 	return -EIO;
 }
@@ -462,17 +426,17 @@
 {
 	struct xircom_private *xp = (struct xircom_private *) dev->priv;
 	int retval;
-	enter();
-	printk(KERN_INFO "Xircom cardbus adaptor found, registering as %s, using irq %i \n",dev->name,dev->irq);
+	enter("xircom_open");
+	printk(KERN_INFO "xircom cardbus adaptor found, registering as %s, using irq %i \n",dev->name,dev->irq);
 	retval = request_irq(dev->irq, &xircom_interrupt, SA_SHIRQ, dev->name, dev);
 	if (retval) {
-		printk(KERN_ERR "xircom_cb: Unable to aquire IRQ %i, aborting.\n",dev->irq);
-		leave();
+		leave("xircom_open - No IRQ");
 		return retval;
 	}
 	
 	xircom_up(xp);
-	leave();
+	xp->open = 1;
+	leave("xircom_open");
 	return 0;
 }
 
@@ -481,9 +445,9 @@
 	struct xircom_private *card;
 	unsigned long flags;
 	
-	enter();
+	enter("xircom_close");
 	card = dev->priv;
-	netif_stop_queue(dev); /* we don't want to send new packets */
+	netif_stop_queue(dev); /* we don't want new packets */
 
 	
 	spin_lock_irqsave(&card->lock,flags);
@@ -498,10 +462,11 @@
 	
 	spin_unlock_irqrestore(&card->lock,flags);
 	
+	card->open = 0;
 	free_irq(dev->irq,dev);
 	
-	leave();
-		
+	leave("xircom_close");
+	
 	return 0;
 	
 }
@@ -521,7 +486,7 @@
 {
 	unsigned int val;
 	unsigned long flags;
-	enter();
+	enter("initialize_card");
 
 
 	spin_lock_irqsave(&card->lock, flags);
@@ -549,7 +514,7 @@
 
 	spin_unlock_irqrestore(&card->lock, flags);
 
-	leave();
+	leave("initialize_card");
 }
 
 /*
@@ -558,11 +523,15 @@
 claims that the act of writing is sufficient and that the value is
 ignored; I chose zero.
 */
-static inline void trigger_transmit(struct xircom_private *card)
+static void trigger_transmit(struct xircom_private *card)
 {
-	enter();
-	outl(0, card->io_port + CSR1);
-	leave();
+	unsigned int val;
+	enter("trigger_transmit");
+
+	val = 0;
+	outl(val, card->io_port + CSR1);
+
+	leave("trigger_transmit");
 }
 
 /*
@@ -572,11 +541,15 @@
 claims that the act of writing is sufficient and that the value is
 ignored; I chose zero.
 */
-static inline void trigger_receive(struct xircom_private *card)
+static void trigger_receive(struct xircom_private *card)
 {
-	enter();
-	outl(0, card->io_port + CSR2);
-	leave();
+	unsigned int val;
+	enter("trigger_receive");
+
+	val = 0;
+	outl(val, card->io_port + CSR2);
+
+	leave("trigger_receive");
 }
 
 /*
@@ -586,9 +559,9 @@
 static void setup_descriptors(struct xircom_private *card)
 {
 	unsigned int val;
-	u32 address;
-	unsigned int i;
-	enter();
+	unsigned int address;
+	int i;
+	enter("setup_descriptors");
 
 
 	if (card->rx_buffer == NULL)
@@ -597,75 +570,74 @@
 		BUG();
 
 	/* Receive descriptors */
-	memset(card->rx_desc, 0, 128);	/* clear the descriptors */
+	memset(card->rx_buffer, 0, 128);	/* clear the descriptors */
 	for (i=0;i<NUMDESCRIPTORS;i++ ) {
 
 		/* Rx Descr0: It's empty, let the card own it, no errors -> 0x80000000 */
-		card->rx_desc[i].status = DescOwnedCard;
+		card->rx_buffer[i*4 + 0] = 0x80000000;
 		/* Rx Descr1: buffer 1 is 1536 bytes, buffer 2 is 0 bytes */
-		card->rx_desc[i].control = MAX_PACKETSIZE;
+		card->rx_buffer[i*4 + 1] = 1536;
 		if (i==NUMDESCRIPTORS-1)
-			card->rx_desc[i].control |= LastDescBit; /* bit 25 is "last descriptor" */
+			card->rx_buffer[i*4 + 1] |= (1 << 25); /* bit 25 is "last descriptor" */
 
 		/* Rx Descr2: address of the buffer
 		   we store the buffer at the 2nd half of the page */
 	
-		address = card->rx_dma_handle;
-		
-		card->rx_desc[i].address1 = cpu_to_le32(address + bufferoffsets[i]);
+		address = (unsigned long) card->rx_dma_handle;
+		card->rx_buffer[i*4 + 2] = cpu_to_le32(address + bufferoffsets[i]);
 		/* Rx Desc3: address of 2nd buffer -> 0 */
-		card->rx_desc[i].address2 = 0;
+		card->rx_buffer[i*4 + 3] = 0;
 	}
 	
 	wmb();
 	/* Write the receive descriptor ring address to the card */
-	address = card->rx_dma_handle;
+	address = (unsigned long) card->rx_dma_handle;
 	val = cpu_to_le32(address); 
 	outl(val, card->io_port + CSR3);	/* Receive descr list address */
 
 
 	/* transmit descriptors */
-	memset(card->tx_desc, 0, 128);	/* clear the descriptors */
+	memset(card->tx_buffer, 0, 128);	/* clear the descriptors */
 	
 	for (i=0;i<NUMDESCRIPTORS;i++ ) {
 		/* Tx Descr0: Empty, we own it, no errors -> 0x00000000 */
-		card->tx_desc[i].status = DescOwnedDriver;
+		card->tx_buffer[i*4 + 0] = 0x00000000;
 		/* Tx Descr1: buffer 1 is 1536 bytes, buffer 2 is 0 bytes */
-		card->tx_desc[i].control = MAX_PACKETSIZE;
+		card->tx_buffer[i*4 + 1] = 1536;
 		if (i==NUMDESCRIPTORS-1)
-			card->tx_desc[i].control |= LastDescBit; /* bit 25 is "last descriptor" */
+			card->tx_buffer[i*4 + 1] |= (1 << 25); /* bit 25 is "last descriptor" */
 		
 		/* Tx Descr2: address of the buffer
 		   we store the buffer at the 2nd half of the page */
-		address = card->tx_dma_handle;
-		card->tx_desc[i].address1 = cpu_to_le32(address + bufferoffsets[i]);
+		address = (unsigned long) card->tx_dma_handle;
+		card->tx_buffer[i*4 + 2] = cpu_to_le32(address + bufferoffsets[i]);
 		/* Tx Desc3: address of 2nd buffer -> 0 */
-		card->tx_desc[i].address2 = 0;
+		card->tx_buffer[i*4 + 3] = 0;
 	}
 
 	wmb();
 	/* wite the transmit descriptor ring to the card */
-	address = card->tx_dma_handle;
+	address = (unsigned long) card->tx_dma_handle;
 	val =cpu_to_le32(address);
 	outl(val, card->io_port + CSR4);	/* xmit descr list address */
 
-	leave();
+	leave("setup_descriptors");
 }
 
 /*
 remove_descriptors informs the card the descriptors are no longer
 valid by setting the address in the card to 0x00.
 */
-static inline void remove_descriptors(struct xircom_private *card)
+static void remove_descriptors(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("remove_descriptors");
 
 	val = 0;
 	outl(val, card->io_port + CSR3);	/* Receive descriptor address */
 	outl(val, card->io_port + CSR4);	/* Send descriptor address */
 
-	leave();
+	leave("remove_descriptors");
 }
 
 /*
@@ -674,24 +646,24 @@
 
 This function also clears the status-bit.
 */
-static inline unsigned int link_status_changed(struct xircom_private *card)
+static int link_status_changed(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("link_status_changed");
 
 	val = inl(card->io_port + CSR5);	/* Status register */
 
-	if ((val & LinkStatusBit) == 0) {	/* no change */
-		leave();
+	if ((val & (1 << 27)) == 0) {	/* no change */
+		leave("link_status_changed - nochange");
 		return 0;
 	}
 
 	/* clear the event by writing a 1 to the bit in the
 	   status register. */
-	val = LinkStatusBit;
+	val = (1 << 27);
 	outl(val, card->io_port + CSR5);
 
-	leave();
+	leave("link_status_changed - changed");
 	return 1;
 }
 
@@ -700,19 +672,19 @@
 transmit_active returns 1 if the transmitter on the card is
 in a non-stopped state.
 */
-static inline int transmit_active(struct xircom_private *card)
+static int transmit_active(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("transmit_active");
 
 	val = inl(card->io_port + CSR5);	/* Status register */
 
 	if ((val & (7 << 20)) == 0) {	/* transmitter disabled */
-		leave();
+		leave("transmit_active - inactive");
 		return 0;
 	}
 
-	leave();
+	leave("transmit_active - active");
 	return 1;
 }
 
@@ -720,20 +692,20 @@
 receive_active returns 1 if the receiver on the card is
 in a non-stopped state.
 */
-static inline unsigned int receive_active(struct xircom_private *card)
+static int receive_active(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("receive_active");
 
 
 	val = inl(card->io_port + CSR5);	/* Status register */
 
 	if ((val & (7 << 17)) == 0) {	/* receiver disabled */
-		leave();
+		leave("receive_active - inactive");
 		return 0;
 	}
 
-	leave();
+	leave("receive_active - active");
 	return 1;
 }
 
@@ -751,18 +723,18 @@
 {
 	unsigned int val;
 	int counter;
-	enter();
+	enter("activate_receiver");
 
 
 	val = inl(card->io_port + CSR6);	/* Operation mode */
 	
-	/* If the "active" bit (1) is set and the receiver is already
+	/* If the "active" bit is set and the receiver is already
 	   active, no need to do the expensive thing */
-	if ((val& RxActiveBit) && (receive_active(card)))
+	if ((val&2) && (receive_active(card)))
 		return;
 	
 	
-	val = val & ~RxActiveBit;		/* disable the receiver */
+	val = val & ~2;		/* disable the receiver */
 	outl(val, card->io_port + CSR6);
 
 	counter = 10;
@@ -778,7 +750,7 @@
 
 	/* enable the receiver */
 	val = inl(card->io_port + CSR6);	/* Operation mode */
-	val = val | RxActiveBit;		/* enable the receiver */
+	val = val | 2;				/* enable the receiver */
 	outl(val, card->io_port + CSR6);
 
 	/* now wait for the card to activate again */
@@ -793,7 +765,7 @@
 			printk(KERN_ERR "xircom_cb: Receiver failed to re-activate\n");
 	}
 
-	leave();
+	leave("activate_receiver");
 }
 
 /*
@@ -807,10 +779,10 @@
 {
 	unsigned int val;
 	int counter;
-	enter();
+	enter("deactivate_receiver");
 
 	val = inl(card->io_port + CSR6);	/* Operation mode */
-	val = val & ~RxActiveBit;		/* disable the receiver */
+	val = val & ~2;				/* disable the receiver */
 	outl(val, card->io_port + CSR6);
 
 	counter = 10;
@@ -825,7 +797,7 @@
 	}
 
 
-	leave();
+	leave("deactivate_receiver");
 }
 
 
@@ -843,17 +815,17 @@
 {
 	unsigned int val;
 	int counter;
-	enter();
+	enter("activate_transmitter");
 
 
 	val = inl(card->io_port + CSR6);	/* Operation mode */
 
-	/* If the "active" bit (13) is set and the receiver is already
+	/* If the "active" bit is set and the receiver is already
 	   active, no need to do the expensive thing */	 
-	if ((val & TxActiveBit) && (transmit_active(card)))
+	if ((val&(1<<13)) && (transmit_active(card)))
 		return;
 
-	val = val & ~TxActiveBit;	/* disable the transmitter */
+	val = val & ~(1 << 13);	/* disable the transmitter */
 	outl(val, card->io_port + CSR6);
 
 	counter = 10;
@@ -869,7 +841,7 @@
 
 	/* enable the transmitter */
 	val = inl(card->io_port + CSR6);	/* Operation mode */
-	val = val | TxActiveBit;	/* enable the transmitter */
+	val = val | (1 << 13);	/* enable the transmitter */
 	outl(val, card->io_port + CSR6);
 
 	/* now wait for the card to activate again */
@@ -884,7 +856,7 @@
 			printk(KERN_ERR "xircom_cb: Transmitter failed to re-activate\n");
 	}
 
-	leave();
+	leave("activate_transmitter");
 }
 
 /*
@@ -898,10 +870,10 @@
 {
 	unsigned int val;
 	int counter;
-	enter();
+	enter("deactivate_transmitter");
 
 	val = inl(card->io_port + CSR6);	/* Operation mode */
-	val = val & ~TxActiveBit;		/* disable the transmitter */
+	val = val & ~2;		/* disable the transmitter */
 	outl(val, card->io_port + CSR6);
 
 	counter = 20;
@@ -916,7 +888,7 @@
 	}
 
 
-	leave();
+	leave("deactivate_transmitter");
 }
 
 
@@ -928,13 +900,13 @@
 static void enable_transmit_interrupt(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("enable_transmit_interrupt");
 
 	val = inl(card->io_port + CSR7);	/* Interrupt enable register */
 	val |= 1;				/* enable the transmit interrupt */
 	outl(val, card->io_port + CSR7);
 
-	leave();
+	leave("enable_transmit_interrupt");
 }
 
 
@@ -946,13 +918,13 @@
 static void enable_receive_interrupt(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("enable_receive_interrupt");
 
 	val = inl(card->io_port + CSR7);	/* Interrupt enable register */
 	val = val | (1 << 6);			/* enable the receive interrupt */
 	outl(val, card->io_port + CSR7);
 
-	leave();
+	leave("enable_receive_interrupt");
 }
 
 /*
@@ -963,13 +935,13 @@
 static void enable_link_interrupt(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("enable_link_interrupt");
 
 	val = inl(card->io_port + CSR7);	/* Interrupt enable register */
-	val = val | LinkStatusBit;			/* enable the link status chage interrupt */
+	val = val | (1 << 27);			/* enable the link status chage interrupt */
 	outl(val, card->io_port + CSR7);
 
-	leave();
+	leave("enable_link_interrupt");
 }
 
 
@@ -982,12 +954,12 @@
 static void disable_all_interrupts(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("enable_all_interrupts");
 	
 	val = 0;				/* disable all interrupts */
 	outl(val, card->io_port + CSR7);
 
-	leave();
+	leave("disable_all_interrupts");
 }
 
 /*
@@ -998,7 +970,7 @@
 static void enable_common_interrupts(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("enable_link_interrupt");
 
 	val = inl(card->io_port + CSR7);	/* Interrupt enable register */
 	val |= (1<<16); /* Normal Interrupt Summary */
@@ -1011,7 +983,7 @@
 	val |= (1<<1);  /* Transmit Process Stopped */
 	outl(val, card->io_port + CSR7);
 
-	leave();
+	leave("enable_link_interrupt");
 }
 
 /*
@@ -1019,32 +991,31 @@
 
 must be called with the lock held and interrupts disabled.
 */
-static inline void enable_promisc(struct xircom_private *card)
+static int enable_promisc(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("enable_promisc");
 
 	val = inl(card->io_port + CSR6);	
-	val = val | PromiscBit;	 /* Bit 6 */
+	val = val | (1 << 6);	
 	outl(val, card->io_port + CSR6);
 
-	printk(KERN_INFO "xircom_cb: enabling promiscuous mode \n");
-	leave();
+	leave("enable_promisc");
+	return 1;
 }
 
 
 
 
 /* 
-link_status() checks the the links status and will return 0 for no link, 
-10 for 10mbit link and 100 for.. guess what.
+link_status() checks the the links status and will return 0 for no link, 10 for 10mbit link and 100 for.. guess what.
 
 Must be called in locked state with interrupts disabled
 */
-static inline unsigned int link_status(struct xircom_private *card)
+static int link_status(struct xircom_private *card)
 {
 	unsigned int val;
-	enter();
+	enter("link_status");
 	
 	val = inb(card->io_port + CSR12);
 	
@@ -1055,59 +1026,12 @@
 		
 	/* If we get here -> no link at all */	
 
-	leave();
+	leave("link_status");
 	return 0;
 }
 
 
 
-/* 
-
-set_half_duplex() sets the card to half duplex mode. In order to do this,
-set_half_duplex() has to deactivate the transmitter and receiver first. It
-will re-enable the transmitter and receiver if those were active from the
-beginning.
-
-Update: the above is not enough. It doesn't touch the MII, in fact it ensures
-the main chipset and the MII are never in sync if a full-duplex connection
-is negotiated. The proper fix is to tell the MII to force a half-duplex
-connection. -Ion
-
-Must be called in locked state
-*/
-static void set_half_duplex(struct xircom_private *card)
-{
-	unsigned int val;
-	int rx,tx,tmp;
-	enter();
-	
-	rx=receive_active(card);
-	tx=transmit_active(card);
-	
-	deactivate_transmitter(card);
-	deactivate_receiver(card);
-	
-	val = inb(card->io_port + CSR6);
-	val &= ~(1<<9);
-	outb(val,card->io_port + CSR6);
-
-	/* tell the MII not to advertise 10/100FDX */
-	tmp = mdio_read(card, 0, 4);
-	printk("xircom_cb: capabilities changed from %#x to %#x\n",
-	       tmp, tmp & ~0x140);
-	tmp &= ~0x140;
-	mdio_write(card, 0, 4, tmp);
-	/* restart autonegotiation */
-	tmp = mdio_read(card, 0, 0);
-	mdio_write(card, 0, 0, tmp | 0x1200);
-
-	if (rx)
-		activate_receiver(card);
-	if (tx)
-		activate_transmitter(card);	
-
-	leave();
-}
 
 
 /*
@@ -1121,7 +1045,7 @@
 	unsigned long flags;
 	int i;
 
-	enter();
+	enter("read_mac_address");
 		
 	spin_lock_irqsave(&card->lock, flags);
 
@@ -1154,92 +1078,7 @@
 		printk("%c%2.2X", i ? ':' : ' ', card->dev->dev_addr[i]);
 	printk("\n");
 #endif
-	leave();
-}
-
-
-/* MII transceiver control section.
-   Read and write the MII registers using software-generated serial
-   MDIO protocol.  See the MII specifications or DP83840A data sheet
-   for details. */
-
-/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
-   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
-   "overclocking" issues or future 66Mhz PCI. */
-#define mdio_delay() inl(mdio_addr)
-
-/* Read and write the MII registers using software-generated serial
-   MDIO protocol.  It is just different enough from the EEPROM protocol
-   to not share code.  The maxium data clock rate is 2.5 Mhz. */
-#define MDIO_SHIFT_CLK	0x10000
-#define MDIO_DATA_WRITE0 0x00000
-#define MDIO_DATA_WRITE1 0x20000
-#define MDIO_ENB	0x00000		/* Ignore the 0x02000 databook setting. */
-#define MDIO_ENB_IN	0x40000
-#define MDIO_DATA_READ	0x80000
-
-static int mdio_read(struct xircom_private *card, int phy_id, int location)
-{
-	int i;
-	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
-	int retval = 0;
-	long mdio_addr = card->io_port + CSR9;
-
-	/* Establish sync by sending at least 32 logic ones. */
-	for (i = 32; i >= 0; i--) {
-		outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	/* Shift the read command bits out. */
-	for (i = 15; i >= 0; i--) {
-		int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
-
-		outl(MDIO_ENB | dataval, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	/* Read the two transition, 16 data, and wire-idle bits. */
-	for (i = 19; i > 0; i--) {
-		outl(MDIO_ENB_IN, mdio_addr);
-		mdio_delay();
-		retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
-		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	return (retval>>1) & 0xffff;
-}
-
-static void mdio_write(struct xircom_private *card, int phy_id, int location, int value)
-{
-	int i;
-	int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
-	long mdio_addr = card->io_port + CSR9;
-
-	/* Establish sync by sending 32 logic ones. */
-	for (i = 32; i >= 0; i--) {
-		outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	/* Shift the command bits out. */
-	for (i = 31; i >= 0; i--) {
-		int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
-		outl(MDIO_ENB | dataval, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
-	/* Clear out extra bits. */
-	for (i = 2; i > 0; i--) {
-		outl(MDIO_ENB_IN, mdio_addr);
-		mdio_delay();
-		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
+	leave("read_mac_address");
 }
 
 
@@ -1251,14 +1090,11 @@
 static void tranceiver_voodoo(struct xircom_private *card)
 {
 	unsigned long flags;
-	u32 tmp32;
 
-	enter();
+	enter("tranceiver_voodoo");
 
 	/* disable all powermanagement */
-	pci_read_config_dword(card->pdev, PCI_POWERMGMT,&tmp32);
-	tmp32 &= ~PowerMgmtBits; 
-	pci_write_config_dword(card->pdev, PCI_POWERMGMT, tmp32);
+	pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);
 
 	setup_descriptors(card);
 
@@ -1274,7 +1110,7 @@
         spin_unlock_irqrestore(&card->lock, flags);
 
 	netif_start_queue(card->dev);
-	leave();
+	leave("tranceiver_voodoo");
 }
 
 
@@ -1282,14 +1118,11 @@
 {
 	unsigned long flags;
 	int i;
-	u32 tmp32;
 
-	enter();
+	enter("xircom_up");
 
 	/* disable all powermanagement */
-	pci_read_config_dword(card->pdev, PCI_POWERMGMT,&tmp32);
-	tmp32 &= ~PowerMgmtBits; 
-	pci_write_config_dword(card->pdev, PCI_POWERMGMT, tmp32);
+	pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);
 
 	setup_descriptors(card);
 
@@ -1304,23 +1137,23 @@
 	
 	/* The card can have received packets already, read them away now */
 	for (i=0;i<NUMDESCRIPTORS;i++) 
-		investigate_rx_descriptor(card->dev,card,i,bufferoffsets[i]);
+		investigate_read_descriptor(card->dev,card,i,bufferoffsets[i]);
 
 
-	set_half_duplex(card);
 	spin_unlock_irqrestore(&card->lock, flags);
 	trigger_receive(card);
 	trigger_transmit(card);
 	netif_start_queue(card->dev);
-	leave();
+	leave("xircom_up");
 }
 
-static void investigate_rx_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset)
+/* Bufferoffset is in BYTES */
+static void investigate_read_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset)
 {
 		int status;		
 		
-		enter();
-		status = card->rx_desc[descnr].status;
+		enter("investigate_read_descriptor");
+		status = card->rx_buffer[4*descnr];
 		
 		if ((status > 0)) {	/* packet received */
 		
@@ -1341,7 +1174,7 @@
 			}
 			skb->dev = dev;
 			skb_reserve(skb, 2);
-			eth_copy_and_sum(skb, &card->rx_buffer[bufferoffset], pkt_len, 0);
+			eth_copy_and_sum(skb, (unsigned char*)&card->rx_buffer[bufferoffset / 4], pkt_len, 0);
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);
@@ -1351,48 +1184,46 @@
 			
 		      out:
 			/* give the buffer back to the card */
-			card->rx_desc[descnr].status = DescOwnedCard;
+			card->rx_buffer[4*descnr] =  0x80000000;
 			trigger_receive(card);
 		}
 
-		leave();
+		leave("investigate_read_descriptor");
 
 }
 
 
-/* Returns 1 if the descriptor is free or became free */
-static unsigned int investigate_tx_descriptor(struct net_device *dev, struct xircom_private *card, unsigned int descnr, unsigned int bufferoffset)
+/* Bufferoffset is in BYTES */
+static void investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsigned int bufferoffset)
 {
-		int status,retval = 0;
-		enter();
-		
-		status = card->tx_desc[descnr].status;
+		int status;
+
+		enter("investigate_write_descriptor");
 		
-		if (status == DescOwnedDriver)
-			return 1;
+		status = card->tx_buffer[4*descnr];
 #if 0		
 		if (status & 0x8000) {	/* Major error */
 			printk(KERN_ERR "Major transmit error status %x \n", status);
-			card->tx_desc[descnr].status = 0;
+			card->tx_buffer[4*descnr] = 0;
 			netif_wake_queue (dev);
 		}
 #endif
 		if (status > 0) {	/* bit 31 is 0 when done */
-			card->stats.tx_packets++;
 			if (card->tx_skb[descnr]!=NULL) {
 				card->stats.tx_bytes += card->tx_skb[descnr]->len;
 				dev_kfree_skb_irq(card->tx_skb[descnr]);
 			}
 			card->tx_skb[descnr] = NULL;
 			/* Bit 8 in the status field is 1 if there was a collision */
-			if (status & CollisionBit)
+			if (status&(1<<8))
 				card->stats.collisions++;
-			card->tx_desc[descnr].status = DescOwnedDriver; /* descriptor is free again */
-			retval = 1;
+			card->tx_buffer[4*descnr] = 0; /* descriptor is free again */
+			netif_wake_queue (dev);
+			card->stats.tx_packets++;
 		}
 
-		leave();
-		return retval;		
+		leave("investigate_write_descriptor");
+		
 }
 
 
@@ -1409,3 +1240,4 @@
 
 module_init(xircom_init) 
 module_exit(xircom_exit)
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pcmcia/xircom_tulip_cb.c linux/drivers/net/pcmcia/xircom_tulip_cb.c
--- linux.orig/drivers/net/pcmcia/xircom_tulip_cb.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/pcmcia/xircom_tulip_cb.c	2002-07-20 01:08:26.000000000 +0000
@@ -101,6 +101,7 @@
 #include <linux/init.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/crc32.h>
 
 #include <asm/io.h>
 #include <asm/processor.h>	/* Processor type for cache alignment. */
@@ -1518,43 +1519,6 @@
 	return -EOPNOTSUPP;
 }
 
-
-/* The little-endian AUTODIN32 ethernet CRC calculation.
-   N.B. Do not use for bulk data, use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline u32 ether_crc_le(int length, unsigned char *data)
-{
-	u32 crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
-    int crc = -1;
-
-    while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
-			crc = (crc << 1) ^
-				((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
-    }
-    return crc;
-}
-
-
 /* Set or clear the multicast filter for this adaptor.
    Note that we only use exclusion around actually queueing the
    new frame, not around filling tp->setup_frame.  This is non-deterministic
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
--- linux.orig/drivers/net/pcnet32.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/pcnet32.c	2002-07-20 01:08:30.000000000 +0000
@@ -22,8 +22,9 @@
  *************************************************************************/
 
 #define DRV_NAME	"pcnet32"
-#define DRV_VERSION	"1.25kf"
-#define DRV_RELDATE	"17.11.2001"
+#define DRV_VERSION	"1.27a"
+#define DRV_RELDATE	"10.02.2002"
+#define PFX		DRV_NAME ": "
 
 static const char *version =
 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " tsbogend@alpha.franken.de\n";
@@ -43,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/crc32.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -53,8 +55,6 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 
-static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0};
-
 /*
  * PCI device identifiers for "new style" Linux PCI Device Drivers
  */
@@ -64,13 +64,26 @@
     { 0, }
 };
 
+MODULE_DEVICE_TABLE (pci, pcnet32_pci_tbl);
+
+int cards_found __initdata;
+
+/* 
+ * VLB I/O addresses 
+ */
+static unsigned int pcnet32_portlist[] __initdata = 
+	{ 0x300, 0x320, 0x340, 0x360, 0 };
+
+
+
 static int pcnet32_debug = 1;
 static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */
+static int pcnet32vlb;	 /* check for VLB cards ? */
 
 static struct net_device *pcnet32_dev;
 
-static const int max_interrupt_work = 80;
-static const int rx_copybreak = 200;
+static int max_interrupt_work = 80;
+static int rx_copybreak = 200;
 
 #define PCNET32_PORT_AUI      0x00
 #define PCNET32_PORT_10BT     0x01
@@ -93,21 +106,21 @@
     PCNET32_PORT_AUI,			   /*  1 BNC/AUI	  */
     PCNET32_PORT_AUI,			   /*  2 AUI/BNC	  */ 
     PCNET32_PORT_ASEL,			   /*  3 not supported	  */
-    PCNET32_PORT_10BT | PCNET32_PORT_FD,	   /*  4 10baseT-FD	  */
+    PCNET32_PORT_10BT | PCNET32_PORT_FD,   /*  4 10baseT-FD	  */
     PCNET32_PORT_ASEL,			   /*  5 not supported	  */
     PCNET32_PORT_ASEL,			   /*  6 not supported	  */
     PCNET32_PORT_ASEL,			   /*  7 not supported	  */
     PCNET32_PORT_ASEL,			   /*  8 not supported	  */
     PCNET32_PORT_MII,			   /*  9 MII 10baseT	  */
-    PCNET32_PORT_MII | PCNET32_PORT_FD,		   /* 10 MII 10baseT-FD	  */
+    PCNET32_PORT_MII | PCNET32_PORT_FD,	   /* 10 MII 10baseT-FD	  */
     PCNET32_PORT_MII,			   /* 11 MII (autosel)	  */
     PCNET32_PORT_10BT,			   /* 12 10BaseT	  */
-    PCNET32_PORT_MII | PCNET32_PORT_100,	   /* 13 MII 100BaseTx	  */
+    PCNET32_PORT_MII | PCNET32_PORT_100,   /* 13 MII 100BaseTx	  */
     PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD, /* 14 MII 100BaseTx-FD */
     PCNET32_PORT_ASEL			   /* 15 not supported	  */
 };
 
-#define MAX_UNITS 8
+#define MAX_UNITS 8	/* More are supported, limit only on options */
 static int options[MAX_UNITS];
 static int full_duplex[MAX_UNITS];
 
@@ -186,7 +199,19 @@
  * v1.25kf Added No Interrupt on successful Tx for some Tx's <kaf@fc.hp.com>
  * v1.26   Converted to pci_alloc_consistent, Jamey Hicks / George France
  *                                           <jamey@crl.dec.com>
- * v1.26p Fix oops on rmmod+insmod; plug i/o resource leak - Paul Gortmaker
+ * -	   Fixed a few bugs, related to running the controller in 32bit mode.
+ *	   23 Oct, 2000.  Carsten Langgaard, carstenl@mips.com
+ *	   Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * v1.26p  Fix oops on rmmod+insmod; plug i/o resource leak - Paul Gortmaker
+ * v1.27   improved CSR/PROM address detection, lots of cleanups,
+ * 	   new pcnet32vlb module option, HP-PARISC support,
+ * 	   added module parameter descriptions, 
+ * 	   initial ethtool support - Helge Deller <deller@gmx.de>
+ * v1.27a  Sun Feb 10 2002 Go Taniguchi <go@turbolinux.co.jp>
+ *	   use alloc_etherdev and register_netdev
+ *	   fix pci probe not increment cards_found
+ *	   FD auto negotiate error workaround for xSeries250
+ *	   clean up and using new mii module
  */
 
 
@@ -200,13 +225,13 @@
 #define PCNET32_LOG_RX_BUFFERS 5
 #endif
 
-#define TX_RING_SIZE			(1 << (PCNET32_LOG_TX_BUFFERS))
-#define TX_RING_MOD_MASK		(TX_RING_SIZE - 1)
-#define TX_RING_LEN_BITS		((PCNET32_LOG_TX_BUFFERS) << 12)
-
-#define RX_RING_SIZE			(1 << (PCNET32_LOG_RX_BUFFERS))
-#define RX_RING_MOD_MASK		(RX_RING_SIZE - 1)
-#define RX_RING_LEN_BITS		((PCNET32_LOG_RX_BUFFERS) << 4)
+#define TX_RING_SIZE		(1 << (PCNET32_LOG_TX_BUFFERS))
+#define TX_RING_MOD_MASK	(TX_RING_SIZE - 1)
+#define TX_RING_LEN_BITS	((PCNET32_LOG_TX_BUFFERS) << 12)
+
+#define RX_RING_SIZE		(1 << (PCNET32_LOG_RX_BUFFERS))
+#define RX_RING_MOD_MASK	(RX_RING_SIZE - 1)
+#define RX_RING_LEN_BITS	((PCNET32_LOG_RX_BUFFERS) << 4)
 
 #define PKT_BUF_SZ		1544
 
@@ -221,9 +246,7 @@
 #define PCNET32_DWIO_RESET	0x18
 #define PCNET32_DWIO_BDP	0x1C
 
-#define PCNET32_TOTAL_SIZE 0x20
-
-#define CRC_POLYNOMIAL_LE 0xedb88320UL	/* Ethernet CRC, little endian */
+#define PCNET32_TOTAL_SIZE	0x20
 
 /* The PCNET32 Rx and Tx ring descriptors. */
 struct pcnet32_rx_head {
@@ -271,37 +294,36 @@
  */
 struct pcnet32_private {
     /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
-    struct pcnet32_rx_head   rx_ring[RX_RING_SIZE];
-    struct pcnet32_tx_head   tx_ring[TX_RING_SIZE];
-    struct pcnet32_init_block	init_block;
-    dma_addr_t dma_addr;		/* DMA address of beginning of this object, returned by pci_alloc_consistent */
-    struct pci_dev *pci_dev;		/* Pointer to the associated pci device structure */
-    const char *name;
+    struct pcnet32_rx_head    rx_ring[RX_RING_SIZE];
+    struct pcnet32_tx_head    tx_ring[TX_RING_SIZE];
+    struct pcnet32_init_block init_block;
+    dma_addr_t 		dma_addr;	/* DMA address of beginning of this object, 
+					   returned by pci_alloc_consistent */
+    struct pci_dev	*pci_dev;	/* Pointer to the associated pci device structure */
+    const char		*name;
     /* The saved address of a sent-in-place packet/buffer, for skfree(). */
-    struct sk_buff *tx_skbuff[TX_RING_SIZE];
-    struct sk_buff *rx_skbuff[RX_RING_SIZE];
-    dma_addr_t tx_dma_addr[TX_RING_SIZE];
-    dma_addr_t rx_dma_addr[RX_RING_SIZE];
+    struct sk_buff	*tx_skbuff[TX_RING_SIZE];
+    struct sk_buff	*rx_skbuff[RX_RING_SIZE];
+    dma_addr_t		tx_dma_addr[TX_RING_SIZE];
+    dma_addr_t		rx_dma_addr[RX_RING_SIZE];
     struct pcnet32_access a;
-    spinlock_t lock;					/* Guard lock */
-    unsigned int cur_rx, cur_tx;		/* The next free ring entry */
-    unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
+    spinlock_t		lock;		/* Guard lock */
+    unsigned int	cur_rx, cur_tx;	/* The next free ring entry */
+    unsigned int	dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
     struct net_device_stats stats;
-    char tx_full;
-    int	 options;
-    int	 shared_irq:1,			/* shared irq possible */
-	ltint:1,
-#ifdef DO_DXSUFLO
-      dxsuflo:1,			    /* disable transmit stop on uflo */
-#endif
-	mii:1;					/* mii port available */
-    struct net_device *next;
+    char		tx_full;
+    int			options;
+    int	shared_irq:1,			/* shared irq possible */
+	ltint:1,			/* enable TxDone-intr inhibitor */
+	dxsuflo:1,			/* disable transmit stop on uflo */
+	mii:1;				/* mii port available */
+    struct net_device	*next;
     struct mii_if_info mii_if;
 };
 
-static int  pcnet32_probe_vlbus(int cards_found);
+static void pcnet32_probe_vlbus(void);
 static int  pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
-static int  pcnet32_probe1(unsigned long, unsigned char, int, int, struct pci_dev *);
+static int  pcnet32_probe1(unsigned long, unsigned int, int, struct pci_dev *);
 static int  pcnet32_open(struct net_device *);
 static int  pcnet32_init_ring(struct net_device *);
 static int  pcnet32_start_xmit(struct sk_buff *, struct net_device *);
@@ -320,15 +342,6 @@
     PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
 };
 
-struct pcnet32_pci_id_info {
-    const char *name;
-    u16 vendor_id, device_id, svid, sdid, flags;
-    int io_size;
-    int (*probe1) (unsigned long, unsigned char, int, int, struct pci_dev *);
-};
-
-
-MODULE_DEVICE_TABLE (pci, pcnet32_pci_tbl);
 
 static u16 pcnet32_wio_read_csr (unsigned long addr, int index)
 {
@@ -376,13 +389,13 @@
 }
 
 static struct pcnet32_access pcnet32_wio = {
-    pcnet32_wio_read_csr,
-    pcnet32_wio_write_csr,
-    pcnet32_wio_read_bcr,
-    pcnet32_wio_write_bcr,
-    pcnet32_wio_read_rap,
-    pcnet32_wio_write_rap,
-    pcnet32_wio_reset
+    read_csr:	pcnet32_wio_read_csr,
+    write_csr:	pcnet32_wio_write_csr,
+    read_bcr:	pcnet32_wio_read_bcr,
+    write_bcr:	pcnet32_wio_write_bcr,
+    read_rap:	pcnet32_wio_read_rap,
+    write_rap:	pcnet32_wio_write_rap,
+    reset:	pcnet32_wio_reset
 };
 
 static u16 pcnet32_dwio_read_csr (unsigned long addr, int index)
@@ -431,82 +444,61 @@
 }
 
 static struct pcnet32_access pcnet32_dwio = {
-    pcnet32_dwio_read_csr,
-    pcnet32_dwio_write_csr,
-    pcnet32_dwio_read_bcr,
-    pcnet32_dwio_write_bcr,
-    pcnet32_dwio_read_rap,
-    pcnet32_dwio_write_rap,
-    pcnet32_dwio_reset
-
+    read_csr:	pcnet32_dwio_read_csr,
+    write_csr:	pcnet32_dwio_write_csr,
+    read_bcr:	pcnet32_dwio_read_bcr,
+    write_bcr:	pcnet32_dwio_write_bcr,
+    read_rap:	pcnet32_dwio_read_rap,
+    write_rap:	pcnet32_dwio_write_rap,
+    reset:	pcnet32_dwio_reset
 };
 
-
 
-/* only probes for non-PCI devices, the rest are handled by pci_register_driver via pcnet32_probe_pci*/
-static int __init pcnet32_probe_vlbus(int cards_found)
+
+/* only probes for non-PCI devices, the rest are handled by 
+ * pci_register_driver via pcnet32_probe_pci */
+
+static void __devinit
+pcnet32_probe_vlbus(void)
 {
-    unsigned long ioaddr = 0; // FIXME dev ? dev->base_addr: 0;
-    unsigned int  irq_line = 0; // FIXME dev ? dev->irq : 0;
-    int *port;
-    
-    printk(KERN_INFO "pcnet32_probe_vlbus: cards_found=%d\n", cards_found);
-#ifndef __powerpc__
-    if (ioaddr > 0x1ff) {
-	if (check_region(ioaddr, PCNET32_TOTAL_SIZE) == 0)
-	    return pcnet32_probe1(ioaddr, irq_line, 0, 0, NULL);
-	else
-	    return -ENODEV;
-    } else
-#endif
-	if (ioaddr != 0)
-	    return -ENXIO;
+    unsigned int *port, ioaddr;
     
-    /* now look for PCnet32 VLB cards */
-    for (port = pcnet32_portlist; *port; port++) {
-	unsigned long ioaddr = *port;
-	
-	if ( check_region(ioaddr, PCNET32_TOTAL_SIZE) == 0) {
+    /* search for PCnet32 VLB cards at known addresses */
+    for (port = pcnet32_portlist; (ioaddr = *port); port++) {
+	if (!check_region(ioaddr, PCNET32_TOTAL_SIZE)) {
 	    /* check if there is really a pcnet chip on that ioaddr */
-	    if ((inb(ioaddr + 14) == 0x57) &&
-		(inb(ioaddr + 15) == 0x57) &&
-		(pcnet32_probe1(ioaddr, 0, 0, 0, NULL) == 0))
-		cards_found++;
+	    if ((inb(ioaddr + 14) == 0x57) && (inb(ioaddr + 15) == 0x57))
+		pcnet32_probe1(ioaddr, 0, 0, NULL);
 	}
     }
-    return cards_found ? 0: -ENODEV;
 }
 
 
-
 static int __devinit
 pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-    static int card_idx;
-    long ioaddr;
-    int err = 0;
-
-    printk(KERN_INFO "pcnet32_probe_pci: found device %#08x.%#08x\n", ent->vendor, ent->device);
+    unsigned long ioaddr;
+    int err;
 
-    if ((err = pci_enable_device(pdev)) < 0) {
-	printk(KERN_ERR "pcnet32.c: failed to enable device -- err=%d\n", err);
+    err = pci_enable_device(pdev);
+    if (err < 0) {
+	printk(KERN_ERR PFX "failed to enable device -- err=%d\n", err);
 	return err;
     }
     pci_set_master(pdev);
 
     ioaddr = pci_resource_start (pdev, 0);
-    printk(KERN_INFO "    ioaddr=%#08lx  resource_flags=%#08lx\n", ioaddr, pci_resource_flags (pdev, 0));
     if (!ioaddr) {
-        printk (KERN_ERR "no PCI IO resources, aborting\n");
+        printk (KERN_ERR PFX "card has no PCI IO resources, aborting\n");
         return -ENODEV;
     }
-	
+    
     if (!pci_dma_supported(pdev, PCNET32_DMA_MASK)) {
-	printk(KERN_ERR "pcnet32.c: architecture does not support 32bit PCI busmaster DMA\n");
+	printk(KERN_ERR PFX "architecture does not support 32bit PCI busmaster DMA\n");
 	return -ENODEV;
     }
 
-    return pcnet32_probe1(ioaddr, pdev->irq, 1, card_idx, pdev);
+    return pcnet32_probe1(ioaddr, pdev->irq, 1, pdev);
 }
 
 
@@ -515,41 +507,43 @@
  *  pdev will be NULL when called from pcnet32_probe_vlbus.
  */
 static int __devinit
-pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx, struct pci_dev *pdev)
+pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
+		struct pci_dev *pdev)
 {
     struct pcnet32_private *lp;
-    struct resource *res;
     dma_addr_t lp_dma_addr;
-    int i,media,fdx = 0, mii = 0, fset = 0;
-#ifdef DO_DXSUFLO
-    int dxsuflo = 0;
-#endif
-    int ltint = 0;
+    int i, media;
+    int fdx, mii, fset, dxsuflo, ltint;
     int chip_version;
     char *chipname;
     struct net_device *dev;
     struct pcnet32_access *a = NULL;
+    u8 promaddr[6];
 
     /* reset the chip */
-    pcnet32_dwio_reset(ioaddr);
     pcnet32_wio_reset(ioaddr);
 
     /* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */
-    if (pcnet32_wio_read_csr (ioaddr, 0) == 4 && pcnet32_wio_check (ioaddr)) {
+    if (pcnet32_wio_read_csr(ioaddr, 0) == 4 && pcnet32_wio_check(ioaddr)) {
 	a = &pcnet32_wio;
     } else {
-	if (pcnet32_dwio_read_csr (ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) {
+	pcnet32_dwio_reset(ioaddr);
+	if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) {
 	    a = &pcnet32_dwio;
 	} else
 	    return -ENODEV;
     }
 
-    chip_version = a->read_csr (ioaddr, 88) | (a->read_csr (ioaddr,89) << 16);
+    chip_version = a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr,89) << 16);
     if (pcnet32_debug > 2)
 	printk(KERN_INFO "  PCnet chip version is %#x.\n", chip_version);
     if ((chip_version & 0xfff) != 0x003)
 	return -ENODEV;
+    
+    /* initialize variables */
+    fdx = mii = fset = dxsuflo = ltint = 0;
     chip_version = (chip_version >> 12) & 0xffff;
+
     switch (chip_version) {
     case 0x2420:
 	chipname = "PCnet/PCI 79C970"; /* PCI */
@@ -588,23 +582,24 @@
 	 * mode by which the card should operate
 	 */
 	/* switch to home wiring mode */
-	media = a->read_bcr (ioaddr, 49);
+	media = a->read_bcr(ioaddr, 49);
 #if 0
 	if (pcnet32_debug > 2)
-	    printk(KERN_DEBUG "pcnet32: pcnet32 media value %#x.\n",  media);
+	    printk(KERN_DEBUG PFX "media value %#x.\n",  media);
 	media &= ~3;
 	media |= 1;
 #endif
 	if (pcnet32_debug > 2)
-	    printk(KERN_DEBUG "pcnet32: pcnet32 media reset to %#x.\n",  media);
-	a->write_bcr (ioaddr, 49, media);
+	    printk(KERN_DEBUG PFX "media reset to %#x.\n",  media);
+	a->write_bcr(ioaddr, 49, media);
 	break;
     case 0x2627:
 	chipname = "PCnet/FAST III 79C975"; /* PCI */
 	fdx = 1; mii = 1;
 	break;
     default:
-	printk(KERN_INFO "pcnet32: PCnet version %#x, no PCnet32 chip.\n",chip_version);
+	printk(KERN_INFO PFX "PCnet version %#x, no PCnet32 chip.\n",
+			chip_version);
 	return -ENODEV;
     }
 
@@ -619,17 +614,15 @@
     {
 	a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800));
 	a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00);
-#ifdef DO_DXSUFLO
 	dxsuflo = 1;
-#endif
 	ltint = 1;
     }
     
-    dev = init_etherdev(NULL, 0);
-    if(dev==NULL)
+    dev = alloc_etherdev(0);
+    if(!dev)
 	return -ENOMEM;
 
-    printk(KERN_INFO "%s: %s at %#3lx,", dev->name, chipname, ioaddr);
+    printk(KERN_INFO PFX "%s at %#3lx,", chipname, ioaddr);
 
     /* In most chips, after a chip reset, the ethernet address is read from the
      * station address PROM at the base address and programmed into the
@@ -645,31 +638,28 @@
 	dev->dev_addr[2*i] = val & 0x0ff;
 	dev->dev_addr[2*i+1] = (val >> 8) & 0x0ff;
     }
-    {
-	u8 promaddr[6];
-	for (i = 0; i < 6; i++) {
-	    promaddr[i] = inb(ioaddr + i);
-	}
-	if( memcmp( promaddr, dev->dev_addr, 6) )
-	{
-	    printk(" warning PROM address does not match CSR address\n");
-#if defined(__i386__)
-	    printk(KERN_WARNING "%s: Probably a Compaq, using the PROM address of", dev->name);
-	    memcpy(dev->dev_addr, promaddr, 6);
-#elif defined(__powerpc__)
-	    if (!is_valid_ether_addr(dev->dev_addr)
-		&& is_valid_ether_addr(promaddr)) {
-		    printk("\n" KERN_WARNING "%s: using PROM address:",
-			   dev->name);
-		    memcpy(dev->dev_addr, promaddr, 6);
-	    }
+
+    /* read PROM address and compare with CSR address */
+    for (i = 0; i < 6; i++)
+	promaddr[i] = inb(ioaddr + i);
+    
+    if( memcmp( promaddr, dev->dev_addr, 6)
+	|| !is_valid_ether_addr(dev->dev_addr) ) {
+#ifndef __powerpc__
+	if( is_valid_ether_addr(promaddr) ){
+#else
+	if( !is_valid_ether_addr(dev->dev_addr)
+	    && is_valid_ether_addr(promaddr)) {
 #endif
-	}	    	    
+	    printk(" warning: CSR address invalid,\n");
+	    printk(KERN_INFO "    using instead PROM address of");
+	    memcpy(dev->dev_addr, promaddr, 6);
+	}
     }
+
     /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
     if( !is_valid_ether_addr(dev->dev_addr) )
-	for (i = 0; i < 6; i++)
-	    dev->dev_addr[i]=0;
+	memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
 
     for (i = 0; i < 6; i++)
 	printk(" %2.2x", dev->dev_addr[i] );
@@ -698,20 +688,18 @@
     }
 
     dev->base_addr = ioaddr;
-    res = request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname);
-    if (res == NULL)
+    if (request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname) == NULL)
 	return -EBUSY;
     
     /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
     if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) {
-	release_resource(res);
+	release_region(ioaddr, PCNET32_TOTAL_SIZE);
 	return -ENOMEM;
     }
 
     memset(lp, 0, sizeof(*lp));
     lp->dma_addr = lp_dma_addr;
     lp->pci_dev = pdev;
-    printk("\n" KERN_INFO "pcnet32: pcnet32_private lp=%p lp_dma_addr=%#08x", lp, lp_dma_addr);
 
     spin_lock_init(&lp->lock);
     
@@ -719,26 +707,25 @@
     lp->name = chipname;
     lp->shared_irq = shared;
     lp->mii_if.full_duplex = fdx;
-#ifdef DO_DXSUFLO
     lp->dxsuflo = dxsuflo;
-#endif
     lp->ltint = ltint;
     lp->mii = mii;
-    if (options[card_idx] > sizeof (options_mapping))
+    if ((cards_found >= MAX_UNITS) || (options[cards_found] > sizeof(options_mapping)))
 	lp->options = PCNET32_PORT_ASEL;
     else
-	lp->options = options_mapping[options[card_idx]];
+	lp->options = options_mapping[options[cards_found]];
     lp->mii_if.dev = dev;
     lp->mii_if.mdio_read = mdio_read;
     lp->mii_if.mdio_write = mdio_write;
     
-    if (fdx && !(lp->options & PCNET32_PORT_ASEL) && full_duplex[card_idx])
+    if (fdx && !(lp->options & PCNET32_PORT_ASEL) && 
+		((cards_found>=MAX_UNITS) || full_duplex[cards_found]))
 	lp->options |= PCNET32_PORT_FD;
     
-    if (a == NULL) {
-      printk(KERN_ERR "pcnet32: No access methods\n");
+    if (!a) {
+      printk(KERN_ERR PFX "No access methods\n");
       pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
-      release_resource(res);
+      release_region(ioaddr, PCNET32_TOTAL_SIZE);
       return -ENODEV;
     }
     lp->a = *a;
@@ -786,13 +773,11 @@
 	else {
 	    printk(", failed to detect IRQ line.\n");
 	    pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
-	    release_resource(res);
+	    release_region(ioaddr, PCNET32_TOTAL_SIZE);
 	    return -ENODEV;
 	}
     }
 
-    if (pcnet32_debug > 0)
-	printk(KERN_INFO "%s", version);
     
     /* The PCNET32-specific entries in the device structure. */
     dev->open = &pcnet32_open;
@@ -802,17 +787,19 @@
     dev->set_multicast_list = &pcnet32_set_multicast_list;
     dev->do_ioctl = &pcnet32_ioctl;
     dev->tx_timeout = pcnet32_tx_timeout;
-    dev->watchdog_timeo = (HZ >> 1);
+    dev->watchdog_timeo = (5*HZ);
 
     lp->next = pcnet32_dev;
     pcnet32_dev = dev;
 
     /* Fill in the generic fields of the device structure. */
-    ether_setup(dev);
+    register_netdev(dev);
+    printk(KERN_INFO "%s: registered as %s\n",dev->name, lp->name);
+    cards_found++;
     return 0;
 }
 
-
+
 static int
 pcnet32_open(struct net_device *dev)
 {
@@ -857,6 +844,10 @@
 	    val |= 1;
 	    if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI))
 		val |= 2;
+	} else if (lp->options & PCNET32_PORT_ASEL) {
+	/* workaround of xSeries250, turn on for 79C975 only */
+	    i = ((lp->a.read_csr(ioaddr, 88) | (lp->a.read_csr(ioaddr,89) << 16)) >> 12) & 0xffff;
+	    if (i == 0x2627) val |= 3;
 	}
 	lp->a.write_bcr (ioaddr, 9, val);
     }
@@ -889,6 +880,7 @@
 	lp->a.write_csr (ioaddr, 3, val);
     }
 #endif
+
     if (lp->ltint) { /* Enable TxDone-intr inhibitor */
 	val = lp->a.read_csr (ioaddr, 5);
 	val |= (1<<14);
@@ -923,7 +915,7 @@
     if (pcnet32_debug > 2)
 	printk(KERN_DEBUG "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n",
 	       dev->name, i, (u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)),
-	       lp->a.read_csr (ioaddr, 0));
+	       lp->a.read_csr(ioaddr, 0));
 
 
     MOD_INC_USE_COUNT;
@@ -953,7 +945,7 @@
     for (i = 0; i < TX_RING_SIZE; i++) {
 	if (lp->tx_skbuff[i]) {
             pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], lp->tx_skbuff[i]->len, PCI_DMA_TODEVICE);
-	    dev_kfree_skb(lp->tx_skbuff[i]); 
+	    dev_kfree_skb_any(lp->tx_skbuff[i]); 
 	    lp->tx_skbuff[i] = NULL;
             lp->tx_dma_addr[i] = 0;
 	}
@@ -1029,11 +1021,12 @@
 pcnet32_tx_timeout (struct net_device *dev)
 {
     struct pcnet32_private *lp = dev->priv;
-    unsigned int ioaddr = dev->base_addr;
+    unsigned long ioaddr = dev->base_addr, flags;
 
+    spin_lock_irqsave(&lp->lock, flags);
     /* Transmitter timeout, serious problems. */
 	printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n",
-	       dev->name, lp->a.read_csr (ioaddr, 0));
+	       dev->name, lp->a.read_csr(ioaddr, 0));
 	lp->a.write_csr (ioaddr, 0, 0x0004);
 	lp->stats.tx_errors++;
 	if (pcnet32_debug > 2) {
@@ -1055,6 +1048,8 @@
 
 	dev->trans_start = jiffies;
 	netif_start_queue(dev);
+
+	spin_unlock_irqrestore(&lp->lock, flags);
 }
 
 
@@ -1062,14 +1057,14 @@
 pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     struct pcnet32_private *lp = dev->priv;
-    unsigned int ioaddr = dev->base_addr;
+    unsigned long ioaddr = dev->base_addr;
     u16 status;
     int entry;
     unsigned long flags;
 
     if (pcnet32_debug > 3) {
 	printk(KERN_DEBUG "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n",
-	       dev->name, lp->a.read_csr (ioaddr, 0));
+	       dev->name, lp->a.read_csr(ioaddr, 0));
     }
 
     spin_lock_irqsave(&lp->lock, flags);
@@ -1136,8 +1131,9 @@
     int boguscnt =  max_interrupt_work;
     int must_restart;
 
-    if (dev == NULL) {
-	printk (KERN_DEBUG "pcnet32_interrupt(): irq %d for unknown device.\n", irq);
+    if (!dev) {
+	printk (KERN_DEBUG "%s(): irq %d for unknown device\n",
+		__FUNCTION__, irq);
 	return;
     }
 
@@ -1208,7 +1204,8 @@
 
 		/* We must free the original skb */
 		if (lp->tx_skbuff[entry]) {
-                    pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[entry], lp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);
+                    pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[entry],
+			lp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);
 		    dev_kfree_skb_irq(lp->tx_skbuff[entry]);
 		    lp->tx_skbuff[entry] = 0;
                     lp->tx_dma_addr[entry] = 0;
@@ -1216,13 +1213,12 @@
 		dirty_tx++;
 	    }
 
-#ifndef final_version
 	    if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
-		printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
-		       dirty_tx, lp->cur_tx, lp->tx_full);
+		printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
+			dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
 		dirty_tx += TX_RING_SIZE;
 	    }
-#endif
+
 	    if (lp->tx_full &&
 		netif_queue_stopped(dev) &&
 		dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
@@ -1263,7 +1259,7 @@
 
     /* Clear any other interrupt, and set interrupt enable. */
     lp->a.write_csr (ioaddr, 0, 0x7940);
-    lp->a.write_rap(ioaddr,rap);
+    lp->a.write_rap (ioaddr,rap);
     
     if (pcnet32_debug > 4)
 	printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",
@@ -1313,10 +1309,13 @@
 		    if ((newskb = dev_alloc_skb (PKT_BUF_SZ))) {
 			skb_reserve (newskb, 2);
 			skb = lp->rx_skbuff[entry];
+			pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[entry], skb->len, PCI_DMA_FROMDEVICE);
 			skb_put (skb, pkt_len);
 			lp->rx_skbuff[entry] = newskb;
 			newskb->dev = dev;
-                        lp->rx_dma_addr[entry] = pci_map_single(lp->pci_dev, newskb->tail, newskb->len, PCI_DMA_FROMDEVICE);
+                        lp->rx_dma_addr[entry] = 
+				pci_map_single(lp->pci_dev, newskb->tail,
+					newskb->len, PCI_DMA_FROMDEVICE);
 			lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]);
 			rx_in_place = 1;
 		    } else
@@ -1350,6 +1349,7 @@
 		lp->stats.rx_bytes += skb->len;
 		skb->protocol=eth_type_trans(skb,dev);
 		netif_rx(skb);
+		dev->last_rx = jiffies;
 		lp->stats.rx_packets++;
 	    }
 	}
@@ -1441,18 +1441,18 @@
     volatile u16 *mcast_table = (u16 *)&ib->filter;
     struct dev_mc_list *dmi=dev->mc_list;
     char *addrs;
-    int i, j, bit, byte;
-    u32 crc, poly = CRC_POLYNOMIAL_LE;
+    int i;
+    u32 crc;
 	
     /* set all multicast bits */
     if (dev->flags & IFF_ALLMULTI){ 
-	ib->filter [0] = 0xffffffff;
-	ib->filter [1] = 0xffffffff;
+	ib->filter[0] = 0xffffffff;
+	ib->filter[1] = 0xffffffff;
 	return;
     }
     /* clear the multicast filter */
-    ib->filter [0] = 0;
-    ib->filter [1] = 0;
+    ib->filter[0] = 0;
+    ib->filter[1] = 0;
 
     /* Add addresses */
     for (i = 0; i < dev->mc_count; i++){
@@ -1463,19 +1463,7 @@
 	if (!(*addrs & 1))
 	    continue;
 	
-	crc = 0xffffffff;
-	for (byte = 0; byte < 6; byte++)
-	    for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-		int test;
-		
-		test = ((bit ^ crc) & 0x01);
-		crc >>= 1;
-		
-		if (test) {
-		    crc = crc ^ poly;
-		}
-	    }
-	
+	crc = ether_crc_le(6, addrs);
 	crc = crc >> 26;
 	mcast_table [crc >> 4] |= 1 << (crc & 0xf);
     }
@@ -1488,9 +1476,10 @@
  */
 static void pcnet32_set_multicast_list(struct net_device *dev)
 {
-    unsigned long ioaddr = dev->base_addr;
+    unsigned long ioaddr = dev->base_addr, flags;
     struct pcnet32_private *lp = dev->priv;	 
 
+    spin_lock_irqsave(&lp->lock, flags);
     if (dev->flags&IFF_PROMISC) {
 	/* Log any net taps. */
 	printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
@@ -1503,6 +1492,7 @@
     lp->a.write_csr (ioaddr, 0, 0x0004); /* Temporarily stop the lance. */
 
     pcnet32_restart(dev, 0x0042); /*  Resume normal operation */
+    spin_unlock_irqrestore(&lp->lock, flags);
 }
 
 static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
@@ -1641,17 +1631,14 @@
     if (lp->mii) {
 	switch(cmd) {
 	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
-	case SIOCDEVPRIVATE:		/* for binary compat, remove in 2.5 */
 	    data->phy_id = (phyaddr >> 5) & 0x1f;
 	    /* Fall Through */
 	case SIOCGMIIREG:		/* Read MII PHY register. */
-	case SIOCDEVPRIVATE+1:		/* for binary compat, remove in 2.5 */
 	    lp->a.write_bcr (ioaddr, 33, ((data->phy_id & 0x1f) << 5) | (data->reg_num & 0x1f));
 	    data->val_out = lp->a.read_bcr (ioaddr, 34);
 	    lp->a.write_bcr (ioaddr, 33, phyaddr);
 	    return 0;
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-	case SIOCDEVPRIVATE+2:		/* for binary compat, remove in 2.5 */
 	    if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 	    lp->a.write_bcr (ioaddr, 33, ((data->phy_id & 0x1f) << 5) | (data->reg_num & 0x1f));
@@ -1664,20 +1651,28 @@
     }
     return -EOPNOTSUPP;
 }
-					    
+
 static struct pci_driver pcnet32_driver = {
-	name:		DRV_NAME,
-	probe:		pcnet32_probe_pci,
-	remove:		NULL,
-	id_table:	pcnet32_pci_tbl,
+    name:	DRV_NAME,
+    probe:	pcnet32_probe_pci,
+    id_table:	pcnet32_pci_tbl,
 };
 
 MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, DRV_NAME " debug level (0-6)");
 MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM_DESC(max_interrupt_work, DRV_NAME " maximum events handled per interrupt");  
 MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM_DESC(rx_copybreak, DRV_NAME " copy breakpoint for copy-only-tiny-frames"); 
 MODULE_PARM(tx_start_pt, "i");
+MODULE_PARM_DESC(tx_start_pt, DRV_NAME " transmit start point (0-3)"); 
+MODULE_PARM(pcnet32vlb, "i");
+MODULE_PARM_DESC(pcnet32vlb, DRV_NAME " Vesa local bus (VLB) support (0/1)"); 
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(options, DRV_NAME " initial option setting(s) (0-15)"); 
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(full_duplex, DRV_NAME " full duplex setting(s) (1)");
+
 MODULE_AUTHOR("Thomas Bogendoerfer");
 MODULE_DESCRIPTION("Driver for PCnet32 and PCnetPCI based ethercards");
 MODULE_LICENSE("GPL");
@@ -1688,36 +1683,25 @@
 
 static int __init pcnet32_init_module(void)
 {
-    int cards_found = 0;
-    int err;
+    printk(KERN_INFO "%s", version);
 
     if (debug > 0)
 	pcnet32_debug = debug;
+
     if ((tx_start_pt >= 0) && (tx_start_pt <= 3))
 	tx_start = tx_start_pt;
-    
-    pcnet32_dev = NULL;
+
     /* find the PCI devices */
-#define USE_PCI_REGISTER_DRIVER
-#ifdef USE_PCI_REGISTER_DRIVER
-    if ((err = pci_module_init(&pcnet32_driver)) < 0 )
-       return err;
-#else
-    {
-        struct pci_device_id *devid = pcnet32_pci_tbl;
-        for (devid = pcnet32_pci_tbl; devid != NULL && devid->vendor != 0; devid++) {
-            struct pci_dev *pdev = pci_find_subsys(devid->vendor, devid->device, devid->subvendor, devid->subdevice, NULL);
-            if (pdev != NULL) {
-                if (pcnet32_probe_pci(pdev, devid) >= 0) {
-                    cards_found++;
-                }
-            }
-        }
-    }
-#endif
-    return 0;
-    /* find any remaining VLbus devices */
-    return pcnet32_probe_vlbus(cards_found);
+    pci_module_init(&pcnet32_driver);
+
+    /* should we find any remaining VLbus devices ? */
+    if (pcnet32vlb)
+	pcnet32_probe_vlbus();
+
+    if (cards_found)
+	printk(KERN_INFO PFX "%d cards_found.\n", cards_found);
+    
+    return cards_found ? 0 : -ENODEV;
 }
 
 static void __exit pcnet32_cleanup_module(void)
@@ -1726,13 +1710,13 @@
 
     /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
     while (pcnet32_dev) {
-        struct pcnet32_private *lp = pcnet32_dev->priv;
+	struct pcnet32_private *lp = pcnet32_dev->priv;
 	next_dev = lp->next;
 	unregister_netdev(pcnet32_dev);
 	release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
-	if (lp->pci_dev != NULL)
+	if (lp->pci_dev)
 	    pci_unregister_driver(&pcnet32_driver);
-        pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
+	pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
 	kfree(pcnet32_dev);
 	pcnet32_dev = next_dev;
     }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ppp_async.c linux/drivers/net/ppp_async.c
--- linux.orig/drivers/net/ppp_async.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/ppp_async.c	2002-07-20 01:08:39.000000000 +0000
@@ -17,7 +17,7 @@
  * PPP driver, written by Michael Callahan and Al Longyear, and
  * subsequently hacked by Paul Mackerras.
  *
- * ==FILEVERSION 20000227==
+ * ==FILEVERSION 20020125==
  */
 
 #include <linux/module.h>
@@ -33,7 +33,7 @@
 #include <linux/init.h>
 #include <asm/uaccess.h>
 
-#define PPP_VERSION	"2.4.1"
+#define PPP_VERSION	"2.4.2"
 
 #define OBUFSIZE	256
 
@@ -62,6 +62,8 @@
 	struct sk_buff	*rpkt;
 	int		lcp_fcs;
 
+	atomic_t	refcnt;
+	struct semaphore dead_sem;
 	struct ppp_channel chan;	/* interface to generic ppp layer */
 	unsigned char	obuf[OBUFSIZE];
 };
@@ -108,6 +110,35 @@
  */
 
 /*
+ * We have a potential race on dereferencing tty->disc_data,
+ * because the tty layer provides no locking at all - thus one
+ * cpu could be running ppp_asynctty_receive while another
+ * calls ppp_asynctty_close, which zeroes tty->disc_data and
+ * frees the memory that ppp_asynctty_receive is using.  The best
+ * way to fix this is to use a rwlock in the tty struct, but for now
+ * we use a single global rwlock for all ttys in ppp line discipline.
+ */
+static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
+
+static struct asyncppp *ap_get(struct tty_struct *tty)
+{
+	struct asyncppp *ap;
+
+	read_lock(&disc_data_lock);
+	ap = tty->disc_data;
+	if (ap != NULL)
+		atomic_inc(&ap->refcnt);
+	read_unlock(&disc_data_lock);
+	return ap;
+}
+
+static void ap_put(struct asyncppp *ap)
+{
+	if (atomic_dec_and_test(&ap->refcnt))
+		up(&ap->dead_sem);
+}
+
+/*
  * Called when a tty is put into PPP line discipline.
  */
 static int
@@ -135,6 +166,9 @@
 	ap->olim = ap->obuf;
 	ap->lcp_fcs = -1;
 
+	atomic_set(&ap->refcnt, 1);
+	init_MUTEX_LOCKED(&ap->dead_sem);
+
 	ap->chan.private = ap;
 	ap->chan.ops = &async_ops;
 	ap->chan.mtu = PPP_MRU;
@@ -155,19 +189,34 @@
 
 /*
  * Called when the tty is put into another line discipline
- * or it hangs up.
- * We assume that while we are in this routine, the tty layer
- * won't call any of the other line discipline entries for the
- * same tty.
+ * or it hangs up.  We have to wait for any cpu currently
+ * executing in any of the other ppp_asynctty_* routines to
+ * finish before we can call ppp_unregister_channel and free
+ * the asyncppp struct.  This routine must be called from
+ * process context, not interrupt or softirq context.
  */
 static void
 ppp_asynctty_close(struct tty_struct *tty)
 {
-	struct asyncppp *ap = tty->disc_data;
+	struct asyncppp *ap;
 
+	write_lock(&disc_data_lock);
+	ap = tty->disc_data;
+	tty->disc_data = 0;
+	write_unlock(&disc_data_lock);
 	if (ap == 0)
 		return;
-	tty->disc_data = 0;
+
+	/*
+	 * We have now ensured that nobody can start using ap from now
+	 * on, but we have to wait for all existing users to finish.
+	 * Note that ppp_unregister_channel ensures that no calls to
+	 * our channel ops (i.e. ppp_async_send/ioctl) are in progress
+	 * by the time it returns.
+	 */
+	if (!atomic_dec_and_test(&ap->refcnt))
+		down(&ap->dead_sem);
+
 	ppp_unregister_channel(&ap->chan);
 	if (ap->rpkt != 0)
 		kfree_skb(ap->rpkt);
@@ -203,9 +252,11 @@
 ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
 		   unsigned int cmd, unsigned long arg)
 {
-	struct asyncppp *ap = tty->disc_data;
+	struct asyncppp *ap = ap_get(tty);
 	int err, val;
 
+	if (ap == 0)
+		return -ENXIO;
 	err = -EFAULT;
 	switch (cmd) {
 	case PPPIOCGCHAN:
@@ -251,6 +302,7 @@
 		err = -ENOIOCTLCMD;
 	}
 
+	ap_put(ap);
 	return err;
 }
 
@@ -271,13 +323,14 @@
 ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
 		  char *flags, int count)
 {
-	struct asyncppp *ap = tty->disc_data;
+	struct asyncppp *ap = ap_get(tty);
 
 	if (ap == 0)
 		return;
 	spin_lock_bh(&ap->recv_lock);
 	ppp_async_input(ap, buf, flags, count);
 	spin_unlock_bh(&ap->recv_lock);
+	ap_put(ap);
 	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
 	    && tty->driver.unthrottle)
 		tty->driver.unthrottle(tty);
@@ -286,13 +339,14 @@
 static void
 ppp_asynctty_wakeup(struct tty_struct *tty)
 {
-	struct asyncppp *ap = tty->disc_data;
+	struct asyncppp *ap = ap_get(tty);
 
 	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 	if (ap == 0)
 		return;
 	if (ppp_async_push(ap))
 		ppp_output_wakeup(&ap->chan);
+	ap_put(ap);
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ppp_deflate.c linux/drivers/net/ppp_deflate.c
--- linux.orig/drivers/net/ppp_deflate.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/ppp_deflate.c	2002-07-20 01:08:32.000000000 +0000
@@ -657,4 +657,4 @@
 
 module_init(deflate_init);
 module_exit(deflate_cleanup);
-MODULE_LICENSE("BSD without advertisement clause");
+MODULE_LICENSE("Dual BSD/GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
--- linux.orig/drivers/net/ppp_generic.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/ppp_generic.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Generic PPP layer for Linux.
  *
- * Copyright 1999-2000 Paul Mackerras.
+ * Copyright 1999-2002 Paul Mackerras.
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
@@ -19,7 +19,7 @@
  * PPP driver, written by Michael Callahan and Al Longyear, and
  * subsequently hacked by Paul Mackerras.
  *
- * ==FILEVERSION 20000902==
+ * ==FILEVERSION 20020217==
  */
 
 #include <linux/config.h>
@@ -43,10 +43,12 @@
 #include <linux/tcp.h>
 #include <linux/spinlock.h>
 #include <linux/smp_lock.h>
+#include <linux/rwsem.h>
+#include <linux/stddef.h>
 #include <net/slhc_vj.h>
 #include <asm/atomic.h>
 
-#define PPP_VERSION	"2.4.1"
+#define PPP_VERSION	"2.4.2"
 
 /*
  * Network protocols we support.
@@ -75,11 +77,11 @@
 	wait_queue_head_t rwait;	/* for poll on reading /dev/ppp */
 	atomic_t	refcnt;		/* # refs (incl /dev/ppp attached) */
 	int		hdrlen;		/* space to leave for headers */
-	struct list_head list;		/* link in all_* list */
 	int		index;		/* interface unit / channel number */
+	int		dead;		/* unit/channel has been shut down */
 };
 
-#define PF_TO_X(pf, X)	((X *)((char *)(pf)-(unsigned long)(&((X *)0)->file)))
+#define PF_TO_X(pf, X)		((X *)((char *)(pf) - offsetof(X, file)))
 
 #define PF_TO_PPP(pf)		PF_TO_X(pf, struct ppp)
 #define PF_TO_CHANNEL(pf)	PF_TO_X(pf, struct channel)
@@ -93,26 +95,27 @@
  * It can have 0 or more ppp channels connected to it.
  */
 struct ppp {
-	struct ppp_file	file;		/* stuff for read/write/poll */
-	struct list_head channels;	/* list of attached channels */
-	int		n_channels;	/* how many channels are attached */
-	spinlock_t	rlock;		/* lock for receive side */
-	spinlock_t	wlock;		/* lock for transmit side */
-	int		mru;		/* max receive unit */
-	unsigned int	flags;		/* control bits */
-	unsigned int	xstate;		/* transmit state bits */
-	unsigned int	rstate;		/* receive state bits */
-	int		debug;		/* debug flags */
+	struct ppp_file	file;		/* stuff for read/write/poll 0 */
+	struct file	*owner;		/* file that owns this unit 48 */
+	struct list_head channels;	/* list of attached channels 4c */
+	int		n_channels;	/* how many channels are attached 54 */
+	spinlock_t	rlock;		/* lock for receive side 58 */
+	spinlock_t	wlock;		/* lock for transmit side 5c */
+	int		mru;		/* max receive unit 60 */
+	unsigned int	flags;		/* control bits 64 */
+	unsigned int	xstate;		/* transmit state bits 68 */
+	unsigned int	rstate;		/* receive state bits 6c */
+	int		debug;		/* debug flags 70 */
 	struct slcompress *vj;		/* state for VJ header compression */
-	enum NPmode	npmode[NUM_NP];	/* what to do with each net proto */
-	struct sk_buff	*xmit_pending;	/* a packet ready to go out */
-	struct compressor *xcomp;	/* transmit packet compressor */
-	void		*xc_state;	/* its internal state */
-	struct compressor *rcomp;	/* receive decompressor */
-	void		*rc_state;	/* its internal state */
-	unsigned long	last_xmit;	/* jiffies when last pkt sent */
-	unsigned long	last_recv;	/* jiffies when last pkt rcvd */
-	struct net_device *dev;		/* network interface device */
+	enum NPmode	npmode[NUM_NP];	/* what to do with each net proto 78 */
+	struct sk_buff	*xmit_pending;	/* a packet ready to go out 88 */
+	struct compressor *xcomp;	/* transmit packet compressor 8c */
+	void		*xc_state;	/* its internal state 90 */
+	struct compressor *rcomp;	/* receive decompressor 94 */
+	void		*rc_state;	/* its internal state 98 */
+	unsigned long	last_xmit;	/* jiffies when last pkt sent 9c */
+	unsigned long	last_recv;	/* jiffies when last pkt rcvd a0 */
+	struct net_device *dev;		/* network interface device a4 */
 #ifdef CONFIG_PPP_MULTILINK
 	int		nxchan;		/* next channel to send something on */
 	u32		nxseq;		/* next sequence number to send */
@@ -144,11 +147,13 @@
  */
 struct channel {
 	struct ppp_file	file;		/* stuff for read/write/poll */
+	struct list_head list;		/* link in all/new_channels list */
 	struct ppp_channel *chan;	/* public channel data structure */
+	struct rw_semaphore chan_sem;	/* protects `chan' during chan ioctl */
 	spinlock_t	downl;		/* protects `chan', file.xq dequeue */
 	struct ppp	*ppp;		/* ppp unit we're connected to */
 	struct list_head clist;		/* link in list of channels per unit */
-	rwlock_t	upl;		/* protects `ppp' and `ulist' */
+	rwlock_t	upl;		/* protects `ppp' */
 #ifdef CONFIG_PPP_MULTILINK
 	u8		avail;		/* flag used in multilink stuff */
 	u8		had_frag;	/* >= 1 fragments have been sent */
@@ -166,12 +171,35 @@
  */
 
 /*
- * all_ppp_sem protects the all_ppp_units.
- * It also ensures that finding a ppp unit in the all_ppp_units list
+ * A cardmap represents a mapping from unsigned integers to pointers,
+ * and provides a fast "find lowest unused number" operation.
+ * It uses a broad (32-way) tree with a bitmap at each level.
+ * It is designed to be space-efficient for small numbers of entries
+ * and time-efficient for large numbers of entries.
+ */
+#define CARDMAP_ORDER	5
+#define CARDMAP_WIDTH	(1U << CARDMAP_ORDER)
+#define CARDMAP_MASK	(CARDMAP_WIDTH - 1)
+
+struct cardmap {
+	int shift;
+	unsigned long inuse;
+	struct cardmap *parent;
+	void *ptr[CARDMAP_WIDTH];
+};
+static void *cardmap_get(struct cardmap *map, unsigned int nr);
+static void cardmap_set(struct cardmap **map, unsigned int nr, void *ptr);
+static unsigned int cardmap_find_first_free(struct cardmap *map);
+static void cardmap_destroy(struct cardmap **map);
+
+/*
+ * all_ppp_sem protects the all_ppp_units mapping.
+ * It also ensures that finding a ppp unit in the all_ppp_units map
  * and updating its file.refcnt field is atomic.
  */
 static DECLARE_MUTEX(all_ppp_sem);
-static LIST_HEAD(all_ppp_units);
+static struct cardmap *all_ppp_units;
+static atomic_t ppp_unit_count = ATOMIC_INIT(0);
 
 /*
  * all_channels_lock protects all_channels and last_channel_index,
@@ -180,7 +208,9 @@
  */
 static spinlock_t all_channels_lock = SPIN_LOCK_UNLOCKED;
 static LIST_HEAD(all_channels);
+static LIST_HEAD(new_channels);
 static int last_channel_index;
+static atomic_t channel_count = ATOMIC_INIT(0);
 
 /* Get the PPP protocol number from a skb */
 #define PPP_PROTO(skb)	(((skb)->data[0] << 8) + (skb)->data[1])
@@ -205,10 +235,6 @@
 #define seq_after(a, b)		((s32)((a) - (b)) > 0)
 
 /* Prototypes. */
-static ssize_t ppp_file_read(struct ppp_file *pf, struct file *file,
-			     char *buf, size_t count);
-static ssize_t ppp_file_write(struct ppp_file *pf, const char *buf,
-			      size_t count);
 static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
 				unsigned int cmd, unsigned long arg);
 static void ppp_xmit_process(struct ppp *ppp);
@@ -235,6 +261,7 @@
 static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st);
 static struct ppp *ppp_create_interface(int unit, int *retp);
 static void init_ppp_file(struct ppp_file *pf, int kind);
+static void ppp_shutdown_interface(struct ppp *ppp);
 static void ppp_destroy_interface(struct ppp *ppp);
 static struct ppp *ppp_find_unit(int unit);
 static struct channel *ppp_find_channel(int unit);
@@ -303,7 +330,6 @@
 #define ppp_unlock(ppp)		do { ppp_recv_unlock(ppp); \
 				     ppp_xmit_unlock(ppp); } while (0)
 
-
 /*
  * /dev/ppp device routines.
  * The /dev/ppp device is used by pppd to control the ppp unit.
@@ -323,11 +349,16 @@
 
 static int ppp_release(struct inode *inode, struct file *file)
 {
-	struct ppp_file *pf = (struct ppp_file *) file->private_data;
+	struct ppp_file *pf = file->private_data;
+	struct ppp *ppp;
 
-	lock_kernel();
 	if (pf != 0) {
 		file->private_data = 0;
+		if (pf->kind == INTERFACE) {
+			ppp = PF_TO_PPP(pf);
+			if (file == ppp->owner)
+				ppp_shutdown_interface(ppp);
+		}
 		if (atomic_dec_and_test(&pf->refcnt)) {
 			switch (pf->kind) {
 			case INTERFACE:
@@ -339,37 +370,27 @@
 			}
 		}
 	}
-	unlock_kernel();
 	return 0;
 }
 
 static ssize_t ppp_read(struct file *file, char *buf,
 			size_t count, loff_t *ppos)
 {
-	struct ppp_file *pf = (struct ppp_file *) file->private_data;
-
-	return ppp_file_read(pf, file, buf, count);
-}
-
-static ssize_t ppp_file_read(struct ppp_file *pf, struct file *file,
-			     char *buf, size_t count)
-{
+	struct ppp_file *pf = file->private_data;
 	DECLARE_WAITQUEUE(wait, current);
 	ssize_t ret;
 	struct sk_buff *skb = 0;
 
-	ret = -ENXIO;
 	if (pf == 0)
-		goto out;		/* not currently attached */
-
+		return -ENXIO;
 	add_wait_queue(&pf->rwait, &wait);
-	current->state = TASK_INTERRUPTIBLE;
 	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
 		skb = skb_dequeue(&pf->rq);
 		if (skb)
 			break;
 		ret = 0;
-		if (pf->kind == CHANNEL && PF_TO_CHANNEL(pf)->chan == 0)
+		if (pf->dead)
 			break;
 		ret = -EAGAIN;
 		if (file->f_flags & O_NONBLOCK)
@@ -379,7 +400,7 @@
 			break;
 		schedule();
 	}
-	current->state = TASK_RUNNING;
+	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&pf->rwait, &wait);
 
 	if (skb == 0)
@@ -402,21 +423,12 @@
 static ssize_t ppp_write(struct file *file, const char *buf,
 			 size_t count, loff_t *ppos)
 {
-	struct ppp_file *pf = (struct ppp_file *) file->private_data;
-
-	return ppp_file_write(pf, buf, count);
-}
-
-static ssize_t ppp_file_write(struct ppp_file *pf, const char *buf,
-			      size_t count)
-{
+	struct ppp_file *pf = file->private_data;
 	struct sk_buff *skb;
 	ssize_t ret;
 
-	ret = -ENXIO;
 	if (pf == 0)
-		goto out;
-
+		return -ENXIO;
 	ret = -ENOMEM;
 	skb = alloc_skb(count + pf->hdrlen, GFP_KERNEL);
 	if (skb == 0)
@@ -448,7 +460,7 @@
 /* No kernel lock - fine */
 static unsigned int ppp_poll(struct file *file, poll_table *wait)
 {
-	struct ppp_file *pf = (struct ppp_file *) file->private_data;
+	struct ppp_file *pf = file->private_data;
 	unsigned int mask;
 
 	if (pf == 0)
@@ -457,28 +469,52 @@
 	mask = POLLOUT | POLLWRNORM;
 	if (skb_peek(&pf->rq) != 0)
 		mask |= POLLIN | POLLRDNORM;
-	if (pf->kind == CHANNEL) {
-		struct channel *pch = PF_TO_CHANNEL(pf);
-		if (pch->chan == 0)
-			mask |= POLLHUP;
-	}
+	if (pf->dead)
+		mask |= POLLHUP;
 	return mask;
 }
 
 static int ppp_ioctl(struct inode *inode, struct file *file,
 		     unsigned int cmd, unsigned long arg)
 {
-	struct ppp_file *pf = (struct ppp_file *) file->private_data;
+	struct ppp_file *pf = file->private_data;
 	struct ppp *ppp;
 	int err = -EFAULT, val, val2, i;
 	struct ppp_idle idle;
 	struct npioctl npi;
-	int unit;
+	int unit, cflags;
 	struct slcompress *vj;
 
 	if (pf == 0)
 		return ppp_unattached_ioctl(pf, file, cmd, arg);
 
+	if (cmd == PPPIOCDETACH) {
+		/*
+		 * We have to be careful here... if the file descriptor
+		 * has been dup'd, we could have another process in the
+		 * middle of a poll using the same file *, so we had
+		 * better not free the interface data structures -
+		 * instead we fail the ioctl.  Even in this case, we
+		 * shut down the interface if we are the owner of it.
+		 * Actually, we should get rid of PPPIOCDETACH, userland
+		 * (i.e. pppd) could achieve the same effect by closing
+		 * this fd and reopening /dev/ppp.
+		 */
+		err = -EINVAL;
+		if (pf->kind == INTERFACE) {
+			ppp = PF_TO_PPP(pf);
+			if (file == ppp->owner)
+				ppp_shutdown_interface(ppp);
+		}
+		if (atomic_read(&file->f_count) <= 2) {
+			ppp_release(inode, file);
+			err = 0;
+		} else
+			printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%d\n",
+			       atomic_read(&file->f_count));
+		return err;
+	}
+
 	if (pf->kind == CHANNEL) {
 		struct channel *pch = PF_TO_CHANNEL(pf);
 		struct ppp_channel *chan;
@@ -494,20 +530,13 @@
 			err = ppp_disconnect_channel(pch);
 			break;
 
-		case PPPIOCDETACH:
-			file->private_data = 0;
-			if (atomic_dec_and_test(&pf->refcnt))
-				ppp_destroy_channel(pch);
-			err = 0;
-			break;
-
 		default:
-			spin_lock_bh(&pch->downl);
+			down_read(&pch->chan_sem);
 			chan = pch->chan;
 			err = -ENOTTY;
 			if (chan && chan->ops->ioctl)
 				err = chan->ops->ioctl(chan, cmd, arg);
-			spin_unlock_bh(&pch->downl);
+			up_read(&pch->chan_sem);
 		}
 		return err;
 	}
@@ -520,13 +549,6 @@
 
 	ppp = PF_TO_PPP(pf);
 	switch (cmd) {
-	case PPPIOCDETACH:
-		file->private_data = 0;
-		if (atomic_dec_and_test(&pf->refcnt))
-			ppp_destroy_interface(ppp);
-		err = 0;
-		break;
-
 	case PPPIOCSMRU:
 		if (get_user(val, (int *) arg))
 			break;
@@ -538,10 +560,11 @@
 		if (get_user(val, (int *) arg))
 			break;
 		ppp_lock(ppp);
-		if (ppp->flags & ~val & SC_CCP_OPEN)
-			ppp_ccp_closed(ppp);
+		cflags = ppp->flags & ~val;
 		ppp->flags = val & SC_FLAG_BITS;
 		ppp_unlock(ppp);
+		if (cflags & SC_CCP_OPEN)
+			ppp_ccp_closed(ppp);
 		err = 0;
 		break;
 
@@ -677,6 +700,7 @@
 	default:
 		err = -ENOTTY;
 	}
+
 	return err;
 }
 
@@ -696,6 +720,7 @@
 		if (ppp == 0)
 			break;
 		file->private_data = &ppp->file;
+		ppp->owner = file;
 		err = -EFAULT;
 		if (put_user(ppp->file.index, (int *) arg))
 			break;
@@ -707,30 +732,28 @@
 		if (get_user(unit, (int *) arg))
 			break;
 		down(&all_ppp_sem);
+		err = -ENXIO;
 		ppp = ppp_find_unit(unit);
-		if (ppp != 0)
+		if (ppp != 0) {
 			atomic_inc(&ppp->file.refcnt);
+			file->private_data = &ppp->file;
+			err = 0;
+		}
 		up(&all_ppp_sem);
-		err = -ENXIO;
-		if (ppp == 0)
-			break;
-		file->private_data = &ppp->file;
-		err = 0;
 		break;
 
 	case PPPIOCATTCHAN:
 		if (get_user(unit, (int *) arg))
 			break;
 		spin_lock_bh(&all_channels_lock);
+		err = -ENXIO;
 		chan = ppp_find_channel(unit);
-		if (chan != 0)
+		if (chan != 0) {
 			atomic_inc(&chan->file.refcnt);
+			file->private_data = &chan->file;
+			err = 0;
+		}
 		spin_unlock_bh(&all_channels_lock);
-		err = -ENXIO;
-		if (chan == 0)
-			break;
-		file->private_data = &chan->file;
-		err = 0;
 		break;
 
 	default:
@@ -907,15 +930,16 @@
 	struct sk_buff *skb;
 
 	ppp_xmit_lock(ppp);
-	ppp_push(ppp);
-	while (ppp->xmit_pending == 0
-	       && (skb = skb_dequeue(&ppp->file.xq)) != 0)
-		ppp_send_frame(ppp, skb);
-	/* If there's no work left to do, tell the core net
-	   code that we can accept some more. */
-	if (ppp->xmit_pending == 0 && skb_peek(&ppp->file.xq) == 0
-	    && ppp->dev != 0)
-		netif_wake_queue(ppp->dev);
+	if (ppp->dev != 0) {
+		ppp_push(ppp);
+		while (ppp->xmit_pending == 0
+		       && (skb = skb_dequeue(&ppp->file.xq)) != 0)
+			ppp_send_frame(ppp, skb);
+		/* If there's no work left to do, tell the core net
+		   code that we can accept some more. */
+		if (ppp->xmit_pending == 0 && skb_peek(&ppp->file.xq) == 0)
+			netif_wake_queue(ppp->dev);
+	}
 	ppp_xmit_unlock(ppp);
 }
 
@@ -1800,7 +1824,7 @@
 {
 	struct channel *pch;
 
-	pch = kmalloc(sizeof(struct channel), GFP_ATOMIC);
+	pch = kmalloc(sizeof(struct channel), GFP_KERNEL);
 	if (pch == 0)
 		return -ENOMEM;
 	memset(pch, 0, sizeof(struct channel));
@@ -1812,11 +1836,13 @@
 #ifdef CONFIG_PPP_MULTILINK
 	pch->lastseq = -1;
 #endif /* CONFIG_PPP_MULTILINK */
+	init_rwsem(&pch->chan_sem);
 	spin_lock_init(&pch->downl);
 	pch->upl = RW_LOCK_UNLOCKED;
 	spin_lock_bh(&all_channels_lock);
 	pch->file.index = ++last_channel_index;
-	list_add(&pch->file.list, &all_channels);
+	list_add(&pch->list, &new_channels);
+	atomic_inc(&channel_count);
 	spin_unlock_bh(&all_channels_lock);
 	MOD_INC_USE_COUNT;
 	return 0;
@@ -1829,7 +1855,9 @@
 {
 	struct channel *pch = chan->ppp;
 
-	return pch->file.index;
+	if (pch != 0)
+		return pch->file.index;
+	return -1;
 }
 
 /*
@@ -1851,7 +1879,7 @@
 
 /*
  * Disconnect a channel from the generic layer.
- * This can be called from mainline or BH/softirq level.
+ * This must be called in process context.
  */
 void
 ppp_unregister_channel(struct ppp_channel *chan)
@@ -1866,14 +1894,17 @@
 	 * This ensures that we have returned from any calls into the
 	 * the channel's start_xmit or ioctl routine before we proceed.
 	 */
+	down_write(&pch->chan_sem);
 	spin_lock_bh(&pch->downl);
 	pch->chan = 0;
 	spin_unlock_bh(&pch->downl);
+	up_write(&pch->chan_sem);
 	ppp_disconnect_channel(pch);
-	wake_up_interruptible(&pch->file.rwait);
 	spin_lock_bh(&all_channels_lock);
-	list_del(&pch->file.list);
+	list_del(&pch->list);
 	spin_unlock_bh(&all_channels_lock);
+	pch->file.dead = 1;
+	wake_up_interruptible(&pch->file.rwait);
 	if (atomic_dec_and_test(&pch->file.refcnt))
 		ppp_destroy_channel(pch);
 	MOD_DEC_USE_COUNT;
@@ -1902,9 +1933,9 @@
 ppp_set_compress(struct ppp *ppp, unsigned long arg)
 {
 	int err;
-	struct compressor *cp;
+	struct compressor *cp, *ocomp;
 	struct ppp_option_data data;
-	void *state;
+	void *state, *ostate;
 	unsigned char ccp_option[CCP_MAX_OPTION_LENGTH];
 #ifdef CONFIG_KMOD
 	char modname[32];
@@ -1930,41 +1961,39 @@
 #endif /* CONFIG_KMOD */
 	if (cp == 0)
 		goto out;
+	/*
+	 * XXX race: the compressor module could get unloaded between
+	 * here and when we do the comp_alloc or decomp_alloc call below.
+	 */
 
 	err = -ENOBUFS;
 	if (data.transmit) {
-		ppp_xmit_lock(ppp);
-		ppp->xstate &= ~SC_COMP_RUN;
-		if (ppp->xc_state != 0) {
-			ppp->xcomp->comp_free(ppp->xc_state);
-			ppp->xc_state = 0;
-		}
-		ppp_xmit_unlock(ppp);
-
 		state = cp->comp_alloc(ccp_option, data.length);
 		if (state != 0) {
 			ppp_xmit_lock(ppp);
+			ppp->xstate &= ~SC_COMP_RUN;
+			ocomp = ppp->xcomp;
+			ostate = ppp->xc_state;
 			ppp->xcomp = cp;
 			ppp->xc_state = state;
 			ppp_xmit_unlock(ppp);
+			if (ostate != 0)
+				ocomp->comp_free(ostate);
 			err = 0;
 		}
 
 	} else {
-		ppp_recv_lock(ppp);
-		ppp->rstate &= ~SC_DECOMP_RUN;
-		if (ppp->rc_state != 0) {
-			ppp->rcomp->decomp_free(ppp->rc_state);
-			ppp->rc_state = 0;
-		}
-		ppp_recv_unlock(ppp);
-
 		state = cp->decomp_alloc(ccp_option, data.length);
 		if (state != 0) {
 			ppp_recv_lock(ppp);
+			ppp->rstate &= ~SC_DECOMP_RUN;
+			ocomp = ppp->rcomp;
+			ostate = ppp->rc_state;
 			ppp->rcomp = cp;
 			ppp->rc_state = state;
 			ppp_recv_unlock(ppp);
+			if (ostate != 0)
+				ocomp->decomp_free(ostate);
 			err = 0;
 		}
 	}
@@ -2062,19 +2091,25 @@
 static void
 ppp_ccp_closed(struct ppp *ppp)
 {
-	ppp->flags &= ~(SC_CCP_OPEN | SC_CCP_UP);
+	void *xstate, *rstate;
+	struct compressor *xcomp, *rcomp;
 
-	ppp->xstate &= ~SC_COMP_RUN;
-	if (ppp->xc_state) {
-		ppp->xcomp->comp_free(ppp->xc_state);
-		ppp->xc_state = 0;
-	}
+	ppp_lock(ppp);
+	ppp->flags &= ~(SC_CCP_OPEN | SC_CCP_UP);
+	ppp->xstate = 0;
+	xcomp = ppp->xcomp;
+	xstate = ppp->xc_state;
+	ppp->xc_state = 0;
+	ppp->rstate = 0;
+	rcomp = ppp->rcomp;
+	rstate = ppp->rc_state;
+	ppp->rc_state = 0;
+	ppp_unlock(ppp);
 
-	ppp->xstate &= ~SC_DECOMP_RUN;
-	if (ppp->rc_state) {
-		ppp->rcomp->decomp_free(ppp->rc_state);
-		ppp->rc_state = 0;
-	}
+	if (xstate)
+		xcomp->comp_free(xstate);
+	if (rstate)
+		rcomp->decomp_free(rstate);
 }
 
 /* List of compressors. */
@@ -2194,39 +2229,27 @@
 ppp_create_interface(int unit, int *retp)
 {
 	struct ppp *ppp;
-	struct net_device *dev;
-	struct list_head *list;
-	int last_unit = -1;
-	int ret = -EEXIST;
+	struct net_device *dev = NULL;
+	int ret = -ENOMEM;
 	int i;
 
-	down(&all_ppp_sem);
-	list = &all_ppp_units;
-	while ((list = list->next) != &all_ppp_units) {
-		ppp = list_entry(list, struct ppp, file.list);
-		if ((unit < 0 && ppp->file.index > last_unit + 1)
-		    || (unit >= 0 && unit < ppp->file.index))
-			break;
-		if (unit == ppp->file.index)
-			goto out;	/* unit already exists */
-		last_unit = ppp->file.index;
-	}
-	if (unit < 0)
-		unit = last_unit + 1;
-
-	/* Create a new ppp structure and link it before `list'. */
-	ret = -ENOMEM;
 	ppp = kmalloc(sizeof(struct ppp), GFP_KERNEL);
 	if (ppp == 0)
-		goto out;
-	memset(ppp, 0, sizeof(struct ppp));
+		goto err;
 	dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-	if (dev == 0) {
-		kfree(ppp);
-		goto out;
-	}
+	if (dev == 0)
+		goto err;
+	memset(ppp, 0, sizeof(struct ppp));
 	memset(dev, 0, sizeof(struct net_device));
 
+	ret = -EEXIST;
+	down(&all_ppp_sem);
+	if (unit < 0)
+		unit = cardmap_find_first_free(all_ppp_units);
+	else if (cardmap_get(all_ppp_units, unit) != NULL)
+		goto err_unlock;	/* unit already exists */
+
+	/* Initialize the new ppp unit */
 	ppp->file.index = unit;
 	ppp->mru = PPP_MRU;
 	init_ppp_file(&ppp->file, INTERFACE);
@@ -2251,19 +2274,26 @@
 	ret = register_netdevice(dev);
 	rtnl_unlock();
 	if (ret != 0) {
-		printk(KERN_ERR "PPP: couldn't register device (%d)\n", ret);
-		kfree(dev);
-		kfree(ppp);
-		goto out;
+		printk(KERN_ERR "PPP: couldn't register device %s (%d)\n",
+		       dev->name, ret);
+		goto err_unlock;
 	}
 
-	list_add(&ppp->file.list, list->prev);
- out:
- 	up(&all_ppp_sem);
-	*retp = ret;
-	if (ret != 0)
-		ppp = 0;
+	atomic_inc(&ppp_unit_count);
+	cardmap_set(&all_ppp_units, unit, ppp);
+	up(&all_ppp_sem);
+	*retp = 0;
 	return ppp;
+
+ err_unlock:
+	up(&all_ppp_sem);
+ err:
+	*retp = ret;
+	if (ppp)
+		kfree(ppp);
+	if (dev)
+		kfree(dev);
+	return NULL;
 }
 
 /*
@@ -2280,19 +2310,48 @@
 }
 
 /*
- * Free up all the resources used by a ppp interface unit.
+ * Take down a ppp interface unit - called when the owning file
+ * (the one that created the unit) is closed or detached.
  */
-static void ppp_destroy_interface(struct ppp *ppp)
+static void ppp_shutdown_interface(struct ppp *ppp)
 {
 	struct net_device *dev;
-	int n_channels ;
 
 	down(&all_ppp_sem);
-	list_del(&ppp->file.list);
-
-	/* Last fd open to this ppp unit is being closed or detached:
-	   mark the interface down, free the ppp unit */
 	ppp_lock(ppp);
+	dev = ppp->dev;
+	ppp->dev = 0;
+	ppp_unlock(ppp);
+	if (dev) {
+		rtnl_lock();
+		dev_close(dev);
+		unregister_netdevice(dev);
+		rtnl_unlock();
+	}
+	cardmap_set(&all_ppp_units, ppp->file.index, NULL);
+	ppp->file.dead = 1;
+	ppp->owner = NULL;
+	wake_up_interruptible(&ppp->file.rwait);
+	up(&all_ppp_sem);
+}
+
+/*
+ * Free the memory used by a ppp unit.  This is only called once
+ * there are no channels connected to the unit and no file structs
+ * that reference the unit.
+ */
+static void ppp_destroy_interface(struct ppp *ppp)
+{
+	atomic_dec(&ppp_unit_count);
+
+	if (!ppp->file.dead || ppp->n_channels) {
+		/* "can't happen" */
+		printk(KERN_ERR "ppp: destroying ppp struct %p but dead=%d "
+		       "n_channels=%d !\n", ppp, ppp->file.dead,
+		       ppp->n_channels);
+		return;
+	}
+
 	ppp_ccp_closed(ppp);
 	if (ppp->vj) {
 		slhc_free(ppp->vj);
@@ -2313,52 +2372,27 @@
 		ppp->active_filter.filter = 0;
 	}
 #endif /* CONFIG_PPP_FILTER */
-	dev = ppp->dev;
-	ppp->dev = 0;
-	n_channels = ppp->n_channels ;
-	ppp_unlock(ppp);
 
-	if (dev) {
-		rtnl_lock();
-		dev_close(dev);
-		unregister_netdevice(dev);
-		rtnl_unlock();
-	}
-
-	/*
-	 * We can't acquire any new channels (since we have the
-	 * all_ppp_sem) so if n_channels is 0, we can free the
-	 * ppp structure.  Otherwise we leave it around until the
-	 * last channel disconnects from it.
-	 */
-	if (n_channels == 0) 
-		kfree(ppp);
-
-	up(&all_ppp_sem);
+	kfree(ppp);
 }
 
 /*
  * Locate an existing ppp unit.
- * The caller must have locked the all_ppp_sem.
+ * The caller should have locked the all_ppp_sem.
  */
 static struct ppp *
 ppp_find_unit(int unit)
 {
-	struct ppp *ppp;
-	struct list_head *list;
-
-	list = &all_ppp_units;
-	while ((list = list->next) != &all_ppp_units) {
-		ppp = list_entry(list, struct ppp, file.list);
-		if (ppp->file.index == unit)
-			return ppp;
-	}
-	return 0;
+	return cardmap_get(all_ppp_units, unit);
 }
 
 /*
  * Locate an existing ppp channel.
  * The caller should have locked the all_channels_lock.
+ * First we look in the new_channels list, then in the
+ * all_channels list.  If found in the new_channels list,
+ * we move it to the all_channels list.  This is for speed
+ * when we have a lot of channels in use.
  */
 static struct channel *
 ppp_find_channel(int unit)
@@ -2366,9 +2400,18 @@
 	struct channel *pch;
 	struct list_head *list;
 
+	list = &new_channels;
+	while ((list = list->next) != &new_channels) {
+		pch = list_entry(list, struct channel, list);
+		if (pch->file.index == unit) {
+			list_del(&pch->list);
+			list_add(&pch->list, &all_channels);
+			return pch;
+		}
+	}
 	list = &all_channels;
 	while ((list = list->next) != &all_channels) {
-		pch = list_entry(list, struct channel, file.list);
+		pch = list_entry(list, struct channel, list);
 		if (pch->file.index == unit)
 			return pch;
 	}
@@ -2392,12 +2435,9 @@
 	write_lock_bh(&pch->upl);
 	ret = -EINVAL;
 	if (pch->ppp != 0)
-		goto outwl;
-	ppp_lock(ppp);
-	spin_lock_bh(&pch->downl);
-	if (pch->chan == 0)		/* need to check this?? */
-		goto outr;
+		goto outl;
 
+	ppp_lock(ppp);
 	if (pch->file.hdrlen > ppp->file.hdrlen)
 		ppp->file.hdrlen = pch->file.hdrlen;
 	hdrlen = pch->file.hdrlen + 2;	/* for protocol bytes */
@@ -2406,15 +2446,14 @@
 	list_add_tail(&pch->clist, &ppp->channels);
 	++ppp->n_channels;
 	pch->ppp = ppp;
+	atomic_inc(&ppp->file.refcnt);
+	ppp_unlock(ppp);
 	ret = 0;
 
- outr:
-	spin_unlock_bh(&pch->downl);
-	ppp_unlock(ppp);
- outwl:
+ outl:
 	write_unlock_bh(&pch->upl);
  out:
- 	up(&all_ppp_sem);
+	up(&all_ppp_sem);
 	return ret;
 }
 
@@ -2426,25 +2465,21 @@
 {
 	struct ppp *ppp;
 	int err = -EINVAL;
-	int dead;
 
 	write_lock_bh(&pch->upl);
 	ppp = pch->ppp;
+	pch->ppp = NULL;
+	write_unlock_bh(&pch->upl);
 	if (ppp != 0) {
 		/* remove it from the ppp unit's list */
-		pch->ppp = NULL;
 		ppp_lock(ppp);
 		list_del(&pch->clist);
 		--ppp->n_channels;
-		dead = ppp->dev == 0 && ppp->n_channels == 0;
 		ppp_unlock(ppp);
-		if (dead)
-			/* Last disconnect from a ppp unit
-			   that is already dead: free it. */
-			kfree(ppp);
+		if (atomic_dec_and_test(&ppp->file.refcnt))
+			ppp_destroy_interface(ppp);
 		err = 0;
 	}
-	write_unlock_bh(&pch->upl);
 	return err;
 }
 
@@ -2453,6 +2488,14 @@
  */
 static void ppp_destroy_channel(struct channel *pch)
 {
+	atomic_dec(&channel_count);
+
+	if (!pch->file.dead) {
+		/* "can't happen" */
+		printk(KERN_ERR "ppp: destroying undead channel %p !\n",
+		       pch);
+		return;
+	}
 	skb_queue_purge(&pch->file.xq);
 	skb_queue_purge(&pch->file.rq);
 	kfree(pch);
@@ -2461,13 +2504,124 @@
 static void __exit ppp_cleanup(void)
 {
 	/* should never happen */
-	if (!list_empty(&all_ppp_units) || !list_empty(&all_channels))
+	if (atomic_read(&ppp_unit_count) || atomic_read(&channel_count))
 		printk(KERN_ERR "PPP: removing module but units remain!\n");
+	cardmap_destroy(&all_ppp_units);
 	if (devfs_unregister_chrdev(PPP_MAJOR, "ppp") != 0)
 		printk(KERN_ERR "PPP: failed to unregister PPP device\n");
 	devfs_unregister(devfs_handle);
 }
 
+/*
+ * Cardmap implementation.
+ */
+static void *cardmap_get(struct cardmap *map, unsigned int nr)
+{
+	struct cardmap *p;
+	int i;
+
+	for (p = map; p != NULL; ) {
+		if ((i = nr >> p->shift) >= CARDMAP_WIDTH)
+			return NULL;
+		if (p->shift == 0)
+			return p->ptr[i];
+		nr &= ~(CARDMAP_MASK << p->shift);
+		p = p->ptr[i];
+	}
+	return NULL;
+}
+
+static void cardmap_set(struct cardmap **pmap, unsigned int nr, void *ptr)
+{
+	struct cardmap *p;
+	int i;
+
+	p = *pmap;
+	if (p == NULL || (nr >> p->shift) >= CARDMAP_WIDTH) {
+		do {
+			/* need a new top level */
+			struct cardmap *np = kmalloc(sizeof(*np), GFP_KERNEL);
+			memset(np, 0, sizeof(*np));
+			np->ptr[0] = p;
+			if (p != NULL) {
+				np->shift = p->shift + CARDMAP_ORDER;
+				p->parent = np;
+			} else
+				np->shift = 0;
+			p = np;
+		} while ((nr >> p->shift) >= CARDMAP_WIDTH);
+		*pmap = p;
+	}
+	while (p->shift > 0) {
+		i = (nr >> p->shift) & CARDMAP_MASK;
+		if (p->ptr[i] == NULL) {
+			struct cardmap *np = kmalloc(sizeof(*np), GFP_KERNEL);
+			memset(np, 0, sizeof(*np));
+			np->shift = p->shift - CARDMAP_ORDER;
+			np->parent = p;
+			p->ptr[i] = np;
+		}
+		if (ptr == NULL)
+			clear_bit(i, &p->inuse);
+		p = p->ptr[i];
+	}
+	i = nr & CARDMAP_MASK;
+	p->ptr[i] = ptr;
+	if (ptr != NULL)
+		set_bit(i, &p->inuse);
+	else
+		clear_bit(i, &p->inuse);
+}
+
+static unsigned int cardmap_find_first_free(struct cardmap *map)
+{
+	struct cardmap *p;
+	unsigned int nr = 0;
+	int i;
+
+	if ((p = map) == NULL)
+		return 0;
+	for (;;) {
+		i = find_first_zero_bit(&p->inuse, CARDMAP_WIDTH);
+		if (i >= CARDMAP_WIDTH) {
+			if (p->parent == NULL)
+				return CARDMAP_WIDTH << p->shift;
+			p = p->parent;
+			i = (nr >> p->shift) & CARDMAP_MASK;
+			set_bit(i, &p->inuse);
+			continue;
+		}
+		nr = (nr & (~CARDMAP_MASK << p->shift)) | (i << p->shift);
+		if (p->shift == 0 || p->ptr[i] == NULL)
+			return nr;
+		p = p->ptr[i];
+	}
+}
+
+static void cardmap_destroy(struct cardmap **pmap)
+{
+	struct cardmap *p, *np;
+	int i;
+
+	for (p = *pmap; p != NULL; p = np) {
+		if (p->shift != 0) {
+			for (i = 0; i < CARDMAP_WIDTH; ++i)
+				if (p->ptr[i] != NULL)
+					break;
+			if (i < CARDMAP_WIDTH) {
+				np = p->ptr[i];
+				p->ptr[i] = NULL;
+				continue;
+			}
+		}
+		np = p->parent;
+		kfree(p);
+	}
+	*pmap = NULL;
+}
+
+/* Module/initialization stuff */
+
 module_init(ppp_init);
 module_exit(ppp_cleanup);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/ppp_synctty.c linux/drivers/net/ppp_synctty.c
--- linux.orig/drivers/net/ppp_synctty.c	2001-10-11 18:17:22.000000000 +0000
+++ linux/drivers/net/ppp_synctty.c	2002-07-20 01:08:34.000000000 +0000
@@ -25,11 +25,11 @@
  * the generic PPP layer to give it frames to send and to process
  * received frames.  It implements the PPP line discipline.
  *
- * Part of the code in this driver was inspired by the old sync-only
+ * Part of the code in this driver was inspired by the old async-only
  * PPP driver, written by Michael Callahan and Al Longyear, and
  * subsequently hacked by Paul Mackerras.
  *
- * ==FILEVERSION 20000322==
+ * ==FILEVERSION 20020125==
  */
 
 #include <linux/module.h>
@@ -41,10 +41,12 @@
 #include <linux/ppp_defs.h>
 #include <linux/if_ppp.h>
 #include <linux/ppp_channel.h>
+#include <linux/spinlock.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
+#include <asm/semaphore.h>
 
-#define PPP_VERSION	"2.4.1"
+#define PPP_VERSION	"2.4.2"
 
 /* Structure for storing local state. */
 struct syncppp {
@@ -65,6 +67,8 @@
 
 	struct sk_buff	*rpkt;
 
+	atomic_t	refcnt;
+	struct semaphore dead_sem;
 	struct ppp_channel chan;	/* interface to generic ppp layer */
 };
 
@@ -161,7 +165,36 @@
  */
 
 /*
- * Called when a tty is put into line discipline.
+ * We have a potential race on dereferencing tty->disc_data,
+ * because the tty layer provides no locking at all - thus one
+ * cpu could be running ppp_synctty_receive while another
+ * calls ppp_synctty_close, which zeroes tty->disc_data and
+ * frees the memory that ppp_synctty_receive is using.  The best
+ * way to fix this is to use a rwlock in the tty struct, but for now
+ * we use a single global rwlock for all ttys in ppp line discipline.
+ */
+static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
+
+static struct syncppp *sp_get(struct tty_struct *tty)
+{
+	struct syncppp *ap;
+
+	read_lock(&disc_data_lock);
+	ap = tty->disc_data;
+	if (ap != NULL)
+		atomic_inc(&ap->refcnt);
+	read_unlock(&disc_data_lock);
+	return ap;
+}
+
+static void sp_put(struct syncppp *ap)
+{
+	if (atomic_dec_and_test(&ap->refcnt))
+		up(&ap->dead_sem);
+}
+
+/*
+ * Called when a tty is put into sync-PPP line discipline.
  */
 static int
 ppp_sync_open(struct tty_struct *tty)
@@ -185,6 +218,9 @@
 	ap->xaccm[3] = 0x60000000U;
 	ap->raccm = ~0U;
 
+	atomic_set(&ap->refcnt, 1);
+	init_MUTEX_LOCKED(&ap->dead_sem);
+
 	ap->chan.private = ap;
 	ap->chan.ops = &sync_ops;
 	ap->chan.mtu = PPP_MRU;
@@ -206,16 +242,34 @@
 
 /*
  * Called when the tty is put into another line discipline
- * (or it hangs up).
+ * or it hangs up.  We have to wait for any cpu currently
+ * executing in any of the other ppp_synctty_* routines to
+ * finish before we can call ppp_unregister_channel and free
+ * the syncppp struct.  This routine must be called from
+ * process context, not interrupt or softirq context.
  */
 static void
 ppp_sync_close(struct tty_struct *tty)
 {
-	struct syncppp *ap = tty->disc_data;
+	struct syncppp *ap;
 
+	write_lock(&disc_data_lock);
+	ap = tty->disc_data;
+	tty->disc_data = 0;
+	write_unlock(&disc_data_lock);
 	if (ap == 0)
 		return;
-	tty->disc_data = 0;
+
+	/*
+	 * We have now ensured that nobody can start using ap from now
+	 * on, but we have to wait for all existing users to finish.
+	 * Note that ppp_unregister_channel ensures that no calls to
+	 * our channel ops (i.e. ppp_sync_send/ioctl) are in progress
+	 * by the time it returns.
+	 */
+	if (!atomic_dec_and_test(&ap->refcnt))
+		down(&ap->dead_sem);
+
 	ppp_unregister_channel(&ap->chan);
 	if (ap->rpkt != 0)
 		kfree_skb(ap->rpkt);
@@ -251,9 +305,11 @@
 ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
 		  unsigned int cmd, unsigned long arg)
 {
-	struct syncppp *ap = tty->disc_data;
+	struct syncppp *ap = sp_get(tty);
 	int err, val;
 
+	if (ap == 0)
+		return -ENXIO;
 	err = -EFAULT;
 	switch (cmd) {
 	case PPPIOCGCHAN:
@@ -299,6 +355,7 @@
 		err = -ENOIOCTLCMD;
 	}
 
+	sp_put(ap);
 	return err;
 }
 
@@ -319,13 +376,14 @@
 ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
 		  char *flags, int count)
 {
-	struct syncppp *ap = tty->disc_data;
+	struct syncppp *ap = sp_get(tty);
 
 	if (ap == 0)
 		return;
 	spin_lock_bh(&ap->recv_lock);
 	ppp_sync_input(ap, buf, flags, count);
 	spin_unlock_bh(&ap->recv_lock);
+	sp_put(ap);
 	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
 	    && tty->driver.unthrottle)
 		tty->driver.unthrottle(tty);
@@ -334,13 +392,14 @@
 static void
 ppp_sync_wakeup(struct tty_struct *tty)
 {
-	struct syncppp *ap = tty->disc_data;
+	struct syncppp *ap = sp_get(tty);
 
 	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 	if (ap == 0)
 		return;
 	if (ppp_sync_push(ap))
 		ppp_output_wakeup(&ap->chan);
+	sp_put(ap);
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pppoe.c linux/drivers/net/pppoe.c
--- linux.orig/drivers/net/pppoe.c	2001-11-09 22:02:24.000000000 +0000
+++ linux/drivers/net/pppoe.c	2002-07-20 01:08:24.000000000 +0000
@@ -5,7 +5,7 @@
  * PPPoE --- PPP over Ethernet (RFC 2516)
  *
  *
- * Version:    0.6.9
+ * Version:    0.6.11
  *
  * 030700 :     Fixed connect logic to allow for disconnect.
  * 270700 :	Fixed potential SMP problems; we must protect against
@@ -31,6 +31,12 @@
  *		a memory leak.
  * 081001 :     Misc. cleanup (licence string, non-blocking, prevent
  *              reference of device on close).
+ * 121301 :     New ppp channels interface; cannot unregister a channel
+ *              from interrupts.  Thus, we mark the socket as a ZOMBIE
+ *              and do the unregistration later.
+ * 071502 :     When a connection is being torn down, we must remember that
+ *              ZOMBIE state connections are still connected and thus
+ *              pppox_unbind_sock must unbind them (in pppoe_release).
  *
  * Author:	Michal Ostrowski <mostrows@speakeasy.net>
  * Contributors:
@@ -86,11 +92,11 @@
 
 
 #if 0
-#define CHECKPTR(x,y) { if (!(x) && pppoe_debug &7 ){ printk(KERN_CRIT "PPPoE Invalid pointer : %s , %p\n",#x,(x)); error=-EINVAL; goto y; }}
-#define DEBUG(s,args...) if( pppoe_debug & (s) ) printk(KERN_CRIT args );
+#define CHECKPTR(x,y) do { if (!(x) && pppoe_debug &7 ){ printk(KERN_CRIT "PPPoE Invalid pointer : %s , %p\n",#x,(x)); error=-EINVAL; goto y; }} while (0)
+#define DEBUG(s,args...) do { if( pppoe_debug & (s) ) printk(KERN_CRIT args ); } while (0)
 #else
-#define CHECKPTR(x,y) do {} while (0);
-#define DEBUG(s,args...) do { } while (0);
+#define CHECKPTR(x,y) do { } while (0)
+#define DEBUG(s,args...) do { } while (0)
 #endif
 
 
@@ -273,10 +279,10 @@
 
 				lock_sock(sk);
 
-				if (sk->state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+				if (sk->state & (PPPOX_CONNECTED|PPPOX_BOUND)){
 					pppox_unbind_sock(sk);
 					dev_put(dev);
-					sk->state = PPPOX_DEAD;
+					sk->state = PPPOX_ZOMBIE;
 					sk->state_change(sk);
 				}
 
@@ -439,8 +445,12 @@
 		 * one socket family type, we cannot (easily) distinguish
 		 * what kind of SKB it is during backlog rcv.
 		 */
-		if (sk->lock.users == 0)
-			pppox_unbind_sock(sk);
+		if (sk->lock.users == 0) {
+			/* We're no longer connect at the PPPOE layer,
+			 * and must wait for ppp channel to disconnect us.
+			 */
+			sk->state = PPPOX_ZOMBIE;
+		}
 
 		bh_unlock_sock(sk);
 		sock_put(sk);
@@ -722,7 +732,7 @@
 		struct pppox_opt *relay_po;
 
 		err = -EBUSY;
-		if (sk->state & PPPOX_BOUND)
+		if (sk->state & (PPPOX_BOUND|PPPOX_ZOMBIE|PPPOX_DEAD))
 			break;
 
 		err = -ENOTCONN;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/pppox.c linux/drivers/net/pppox.c
--- linux.orig/drivers/net/pppox.c	2001-11-09 22:02:24.000000000 +0000
+++ linux/drivers/net/pppox.c	2002-07-20 01:08:32.000000000 +0000
@@ -5,9 +5,9 @@
  * PPPoE --- PPP over Ethernet (RFC 2516)
  *
  *
- * Version:	0.5.1
+ * Version:	0.5.2
  *
- * Author:	Michal Ostrowski <mostrows@styx.uwaterloo.ca>
+ * Author:	Michal Ostrowski <mostrows@speakeasy.net>
  *
  * 051000 :	Initialization cleanup
  *
@@ -67,9 +67,9 @@
 {
 	/* Clear connection to ppp device, if attached. */
 
-	if (sk->state & PPPOX_BOUND) {
+	if (sk->state & (PPPOX_BOUND|PPPOX_ZOMBIE)) {
 		ppp_unregister_channel(&sk->protinfo.pppox->chan);
-		sk->state &= ~PPPOX_BOUND;
+		sk->state = PPPOX_DEAD;
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/rrunner.c linux/drivers/net/rrunner.c
--- linux.orig/drivers/net/rrunner.c	2001-11-09 21:45:35.000000000 +0000
+++ linux/drivers/net/rrunner.c	2002-07-20 01:08:29.000000000 +0000
@@ -73,13 +73,13 @@
 #define rr_mark_net_bh(foo) mark_bh(foo)
 #define rr_if_busy(dev)     dev->tbusy
 #define rr_if_running(dev)  dev->start /* Currently unused. */
-#define rr_if_down(dev)     {do{dev->start = 0;}while (0);}
+#define rr_if_down(dev)     do { dev->start = 0; } while (0)
 #else
 #define NET_BH              0
-#define rr_mark_net_bh(foo) {do{} while(0);}
+#define rr_mark_net_bh(foo) do { } while(0)
 #define rr_if_busy(dev)     netif_queue_stopped(dev)
 #define rr_if_running(dev)  netif_running(dev)
-#define rr_if_down(dev)     {do{} while(0);}
+#define rr_if_down(dev)     do { } while(0)
 #endif
 
 #include "rrunner.h"
@@ -269,6 +269,7 @@
 #if LINUX_VERSION_CODE > 0x20118
 MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@cern.ch>");
 MODULE_DESCRIPTION("Essential RoadRunner HIPPI driver");
+MODULE_LICENSE("GPL");
 #endif
 
 int init_module(void)
@@ -770,7 +771,7 @@
 	 * Give the FirmWare time to chew on the `get running' command.
 	 */
 	myjif = jiffies + 5 * HZ;
-	while ((jiffies < myjif) && !rrpriv->fw_running);
+	while (time_before(jiffies, myjif) && !rrpriv->fw_running);
 
 	netif_start_queue(dev);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sb1000.c linux/drivers/net/sb1000.c
--- linux.orig/drivers/net/sb1000.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/sb1000.c	2002-07-20 01:08:24.000000000 +0000
@@ -204,7 +204,12 @@
 		/*
 		 *	Ok set it up.
 		 */
-		 
+		if (!request_region(ioaddr[0], 16, dev->name))
+			continue;
+		if (!request_region(ioaddr[1], 16, dev->name)) {
+			release_region(ioaddr[0], 16);
+			continue;
+		}
 		 
 		dev->base_addr = ioaddr[0];
 		/* rmem_end holds the second I/O address - fv */
@@ -262,9 +267,6 @@
 
 		/* Lock resources */
 
-		request_region(ioaddr[0], 16, dev->name);
-		request_region(ioaddr[1], 16, dev->name);
-
 		return 0;
 	}
 }
@@ -403,7 +405,7 @@
 	}
 	timeout = jiffies + Sb1000TimeOutJiffies;
 	while (!(inb(ioaddr[1] + 6) & 0x40)) {
-		if (jiffies >= timeout) {
+		if (time_after_eq(jiffies, timeout)) {
 			printk(KERN_WARNING "%s: sb1000_wait_for_ready timeout\n",
 				name);
 			return -ETIME;
@@ -421,7 +423,7 @@
 
 	timeout = jiffies + Sb1000TimeOutJiffies;
 	while (inb(ioaddr[1] + 6) & 0x80) {
-		if (jiffies >= timeout) {
+		if (time_after_eq(jiffies, timeout)) {
 			printk(KERN_WARNING "%s: sb1000_wait_for_ready_clear timeout\n",
 				name);
 			return -ETIME;
@@ -429,7 +431,7 @@
 	}
 	timeout = jiffies + Sb1000TimeOutJiffies;
 	while (inb(ioaddr[1] + 6) & 0x40) {
-		if (jiffies >= timeout) {
+		if (time_after_eq(jiffies, timeout)) {
 			printk(KERN_WARNING "%s: sb1000_wait_for_ready_clear timeout\n",
 				name);
 			return -ETIME;
@@ -962,8 +964,6 @@
 	/* rmem_end holds the second I/O address - fv */
 	ioaddr[1] = dev->rmem_end;
 	name = dev->name;
-	request_region(ioaddr[0], SB1000_IO_EXTENT, "sb1000");
-	request_region(ioaddr[1], SB1000_IO_EXTENT, "sb1000");
 
 	/* initialize sb1000 */
 	if ((status = sb1000_reset(ioaddr, name)))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sb1250-mac.c linux/drivers/net/sb1250-mac.c
--- linux.orig/drivers/net/sb1250-mac.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/sb1250-mac.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,2541 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+/*
+  This driver is designed for the Broadcom BCM12500 SOC chip's built-in
+  Ethernet controllers.
+  
+  The author may be reached as mpl@broadcom.com
+*/
+
+
+/* A few user-configurable values.
+   These may be modified when a driver module is loaded. */
+
+static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
+
+/* Used to pass the media type, etc.
+   Both 'options[]' and 'full_duplex[]' should exist for driver
+   interoperability.
+   The media type is usually passed in 'options[]'.
+*/
+
+#define MAX_UNITS 3		/* More are supported, limit only on options */
+#ifdef MODULE
+static int options[MAX_UNITS] = {-1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1};
+#endif
+
+
+/* Operational parameters that usually are not changed. */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (2*HZ)
+
+#if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
+#warning  You must compile this file with the correct options!
+#warning  See the last lines of the source file.
+#error  You must compile this driver with "-O".
+#endif
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/compiler.h>
+#include <asm/processor.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/64bit.h>
+
+/* This is only here until the firmware is ready.  In that case,
+   the firmware leaves the ethernet address in the register for us. */
+#ifdef CONFIG_SWARM_STANDALONE
+#define SBMAC_ETH0_HWADDR "40:00:00:00:01:00"
+#define SBMAC_ETH1_HWADDR "40:00:00:00:01:01"
+#define SBMAC_ETH2_HWADDR "40:00:00:00:01:02"
+#endif
+
+
+/* These identify the driver base version and may not be removed. */
+#if 0
+static char version1[] __devinitdata =
+"sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg (mpl@broadcom.com)\n";
+#endif
+
+
+
+MODULE_AUTHOR("Mitch Lichtenberg (mpl@broadcom.com)");
+MODULE_DESCRIPTION("Broadcom BCM12500 SOC GB Ethernet driver");
+MODULE_PARM(debug, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+
+
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_mac.h>
+#include <asm/sibyte/sb1250_dma.h>
+#include <asm/sibyte/sb1250_int.h>
+
+
+/**********************************************************************
+ *  Simple types
+ ********************************************************************* */
+
+
+typedef unsigned long sbmac_port_t;
+typedef uint64_t sbmac_physaddr_t;
+typedef uint64_t sbmac_enetaddr_t;
+
+typedef enum { sbmac_speed_auto, sbmac_speed_10,
+	       sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t;
+
+typedef enum { sbmac_duplex_auto, sbmac_duplex_half,
+	       sbmac_duplex_full } sbmac_duplex_t;
+
+typedef enum { sbmac_fc_auto, sbmac_fc_disabled, sbmac_fc_frame,
+	       sbmac_fc_collision, sbmac_fc_carrier } sbmac_fc_t;
+
+typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on, 
+	       sbmac_state_broken } sbmac_state_t;
+
+
+/**********************************************************************
+ *  Macros
+ ********************************************************************* */
+
+
+#define SBDMA_NEXTBUF(d,f) ((((d)->f+1) == (d)->sbdma_dscrtable_end) ? \
+			  (d)->sbdma_dscrtable : (d)->f+1)
+
+
+#define CACHELINESIZE 32
+#define NUMCACHEBLKS(x) (((x)+CACHELINESIZE-1)/CACHELINESIZE)
+#define KMALLOC(x) kmalloc((x),GFP_KERNEL)
+#define KFREE(x) kfree(x)
+#define KVTOPHYS(x) virt_to_bus((void *)(x))
+
+ 
+#define SBMAC_READCSR(t)    (in64((unsigned long)(t)))
+#define SBMAC_WRITECSR(t,v) (out64(v, (unsigned long)(t)))
+
+#define PKSEG1(x) ((sbmac_port_t) KSEG1ADDR(x))
+
+#define SBMAC_MAX_TXDESCR	32
+#define SBMAC_MAX_RXDESCR	32
+
+#define ETHER_ALIGN	2
+#define ETHER_ADDR_LEN	6
+#define ENET_PACKET_SIZE	1518
+
+/**********************************************************************
+ *  DMA Descriptor structure
+ ********************************************************************* */
+
+typedef struct sbdmadscr_s {
+	uint64_t  dscr_a;
+	uint64_t  dscr_b;
+} sbdmadscr_t;
+
+typedef unsigned long paddr_t;
+typedef unsigned long vaddr_t;
+
+/**********************************************************************
+ *  DMA Controller structure
+ ********************************************************************* */
+
+typedef struct sbmacdma_s {
+	
+	/* 
+	 * This stuff is used to identify the channel and the registers
+	 * associated with it.
+	 */
+	
+	struct sbmac_softc *sbdma_eth;	        /* back pointer to associated MAC */
+	int              sbdma_channel;	/* channel number */
+	int		     sbdma_txdir;       /* direction (1=transmit) */
+	int		     sbdma_maxdescr;	/* total # of descriptors in ring */
+	sbmac_port_t     sbdma_config0;	/* DMA config register 0 */
+	sbmac_port_t     sbdma_config1;	/* DMA config register 1 */
+	sbmac_port_t     sbdma_dscrbase;	/* Descriptor base address */
+	sbmac_port_t     sbdma_dscrcnt;     /* Descriptor count register */
+	sbmac_port_t     sbdma_curdscr;	/* current descriptor address */
+	
+	/*
+	 * This stuff is for maintenance of the ring
+	 */
+	
+	sbdmadscr_t     *sbdma_dscrtable;	/* base of descriptor table */
+	sbdmadscr_t     *sbdma_dscrtable_end; /* end of descriptor table */
+	
+	struct sk_buff **sbdma_ctxtable;    /* context table, one per descr */
+	
+	paddr_t          sbdma_dscrtable_phys; /* and also the phys addr */
+	sbdmadscr_t     *sbdma_addptr;	/* next dscr for sw to add */
+	sbdmadscr_t     *sbdma_remptr;	/* next dscr for sw to remove */
+	
+} sbmacdma_t;
+
+
+/**********************************************************************
+ *  Ethernet softc structure
+ ********************************************************************* */
+
+struct sbmac_softc {
+	/*
+	 * Linux-specific things
+	 */
+	struct net_device *sbm_dev;
+	spinlock_t sbm_lock;
+	struct timer_list sbm_timer;     	/* for monitoring MII */
+	struct net_device_stats sbm_stats; 
+	int sbm_devflags;			/* current device flags */
+
+        int	     sbm_phy_oldbmsr;
+        int	     sbm_phy_oldanlpar;
+        int	     sbm_phy_oldk1stsr;
+        int          sbm_phy_oldlinkstat;
+	int sbm_buffersize;
+
+	unsigned char sbm_phys[2];
+
+	/*
+	 * Controller-specific things
+	 */
+	sbmac_port_t     sbm_base;          /* MAC's base address */
+	sbmac_state_t    sbm_state;         /* current state */
+
+	sbmac_port_t     sbm_macenable;	/* MAC Enable Register */
+	sbmac_port_t     sbm_maccfg;	/* MAC Configuration Register */
+	sbmac_port_t     sbm_fifocfg;	/* FIFO configuration register */
+	sbmac_port_t     sbm_framecfg;	/* Frame configuration register */
+	sbmac_port_t     sbm_rxfilter;	/* receive filter register */
+	sbmac_port_t     sbm_isr;		/* Interrupt status register */
+	sbmac_port_t     sbm_imr;		/* Interrupt mask register */
+	sbmac_port_t     sbm_mdio;		/* MDIO register */
+
+	sbmac_speed_t    sbm_speed;		/* current speed */
+	sbmac_duplex_t   sbm_duplex;	/* current duplex */
+	sbmac_fc_t       sbm_fc;		/* current flow control setting */
+	
+	u_char           sbm_hwaddr[ETHER_ADDR_LEN];
+
+	sbmacdma_t       sbm_txdma;		/* for now, only use channel 0 */
+	sbmacdma_t       sbm_rxdma;
+};
+
+
+/**********************************************************************
+ *  Externs
+ ********************************************************************* */
+
+/**********************************************************************
+ *  Prototypes
+ ********************************************************************* */
+
+static void sbdma_initctx(sbmacdma_t *d,
+			  struct sbmac_softc *s,
+			  int chan,
+			  int txrx,
+			  int maxdescr);
+static void sbdma_channel_start(sbmacdma_t *d);
+static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *m);
+static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *m);
+static void sbdma_emptyring(sbmacdma_t *d);
+static void sbdma_fillring(sbmacdma_t *d);
+static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d);
+static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d);
+static int sbmac_initctx(struct sbmac_softc *s);
+static void sbmac_channel_start(struct sbmac_softc *s);
+static void sbmac_channel_stop(struct sbmac_softc *s);
+static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *,sbmac_state_t);
+static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff);
+/*static void sbmac_init_and_start(struct sbmac_softc *sc);*/
+static uint64_t sbmac_addr2reg(unsigned char *ptr);
+static void sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs);
+static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev);
+static void sbmac_setmulti(struct sbmac_softc *sc);
+static int sbmac_init(struct net_device *dev);
+static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed);
+static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc);
+
+static int sbmac_open(struct net_device *dev);
+static void sbmac_timer(unsigned long data);
+static void sbmac_tx_timeout (struct net_device *dev);
+static struct net_device_stats *sbmac_get_stats(struct net_device *dev);
+static void sbmac_set_rx_mode(struct net_device *dev);
+static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int sbmac_close(struct net_device *dev);
+static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
+
+static void sbmac_mii_sync(struct sbmac_softc *s);
+static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitcnt);
+static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx);
+static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
+			    unsigned int regval);
+
+
+/**********************************************************************
+ *  Globals
+ ********************************************************************* */
+
+
+/**********************************************************************
+ *  MDIO constants
+ ********************************************************************* */
+
+#define	MII_COMMAND_START	0x01
+#define	MII_COMMAND_READ	0x02
+#define	MII_COMMAND_WRITE	0x01
+#define	MII_COMMAND_ACK		0x02
+
+#define BMCR_RESET     0x8000
+#define BMCR_LOOPBACK  0x4000
+#define BMCR_SPEED0    0x2000
+#define BMCR_ANENABLE  0x1000
+#define BMCR_POWERDOWN 0x0800
+#define BMCR_ISOLATE   0x0400
+#define BMCR_RESTARTAN 0x0200
+#define BMCR_DUPLEX    0x0100
+#define BMCR_COLTEST   0x0080
+#define BMCR_SPEED1    0x0040
+#define BMCR_SPEED1000 (BMCR_SPEED1|BMCR_SPEED0)
+#define BMCR_SPEED100  (BMCR_SPEED0)
+#define BMCR_SPEED10 	0
+
+#define BMSR_100BT4	0x8000
+#define BMSR_100BT_FDX	0x4000
+#define BMSR_100BT_HDX  0x2000
+#define BMSR_10BT_FDX   0x1000
+#define BMSR_10BT_HDX   0x0800
+#define BMSR_100BT2_FDX 0x0400
+#define BMSR_100BT2_HDX 0x0200
+#define BMSR_1000BT_XSR	0x0100
+#define BMSR_PRESUP	0x0040
+#define BMSR_ANCOMPLT	0x0020
+#define BMSR_REMFAULT	0x0010
+#define BMSR_AUTONEG	0x0008
+#define BMSR_LINKSTAT	0x0004
+#define BMSR_JABDETECT	0x0002
+#define BMSR_EXTCAPAB	0x0001
+
+#define PHYIDR1 	0x2000
+#define PHYIDR2		0x5C60
+
+#define ANAR_NP		0x8000
+#define ANAR_RF		0x2000
+#define ANAR_ASYPAUSE	0x0800
+#define ANAR_PAUSE	0x0400
+#define ANAR_T4		0x0200
+#define ANAR_TXFD	0x0100
+#define ANAR_TXHD	0x0080
+#define ANAR_10FD	0x0040
+#define ANAR_10HD	0x0020
+#define ANAR_PSB	0x0001
+
+#define ANLPAR_NP	0x8000
+#define ANLPAR_ACK	0x4000
+#define ANLPAR_RF	0x2000
+#define ANLPAR_ASYPAUSE	0x0800
+#define ANLPAR_PAUSE	0x0400
+#define ANLPAR_T4	0x0200
+#define ANLPAR_TXFD	0x0100
+#define ANLPAR_TXHD	0x0080
+#define ANLPAR_10FD	0x0040
+#define ANLPAR_10HD	0x0020
+#define ANLPAR_PSB	0x0001	/* 802.3 */
+
+#define ANER_PDF	0x0010
+#define ANER_LPNPABLE	0x0008
+#define ANER_NPABLE	0x0004
+#define ANER_PAGERX	0x0002
+#define ANER_LPANABLE	0x0001
+
+#define ANNPTR_NP	0x8000
+#define ANNPTR_MP	0x2000
+#define ANNPTR_ACK2	0x1000
+#define ANNPTR_TOGTX	0x0800
+#define ANNPTR_CODE	0x0008
+
+#define ANNPRR_NP	0x8000
+#define ANNPRR_MP	0x2000
+#define ANNPRR_ACK3	0x1000
+#define ANNPRR_TOGTX	0x0800
+#define ANNPRR_CODE	0x0008
+
+#define K1TCR_TESTMODE	0x0000
+#define K1TCR_MSMCE	0x1000
+#define K1TCR_MSCV	0x0800
+#define K1TCR_RPTR	0x0400
+#define K1TCR_1000BT_FDX 0x200
+#define K1TCR_1000BT_HDX 0x100
+
+#define K1STSR_MSMCFLT	0x8000
+#define K1STSR_MSCFGRES	0x4000
+#define K1STSR_LRSTAT	0x2000
+#define K1STSR_RRSTAT	0x1000
+#define K1STSR_LP1KFD	0x0800
+#define K1STSR_LP1KHD   0x0400
+#define K1STSR_LPASMDIR	0x0200
+
+#define K1SCR_1KX_FDX	0x8000
+#define K1SCR_1KX_HDX	0x4000
+#define K1SCR_1KT_FDX	0x2000
+#define K1SCR_1KT_HDX	0x1000
+
+#define STRAP_PHY1	0x0800
+#define STRAP_NCMODE	0x0400
+#define STRAP_MANMSCFG	0x0200
+#define STRAP_ANENABLE	0x0100
+#define STRAP_MSVAL	0x0080
+#define STRAP_1KHDXADV	0x0010
+#define STRAP_1KFDXADV	0x0008
+#define STRAP_100ADV	0x0004
+#define STRAP_SPEEDSEL	0x0000
+#define STRAP_SPEED100	0x0001
+
+#define PHYSUP_SPEED1000 0x10
+#define PHYSUP_SPEED100  0x08
+#define PHYSUP_SPEED10   0x00
+#define PHYSUP_LINKUP	 0x04
+#define PHYSUP_FDX       0x02
+
+#define	MII_BMCR	0x00 	/* Basic mode control register (rw) */
+#define	MII_BMSR	0x01	/* Basic mode status register (ro) */
+#define MII_K1STSR	0x0A	/* 1K Status Register (ro) */
+#define	MII_ANLPAR	0x05	/* Autonegotiation lnk partner abilities (rw) */
+
+
+#define M_MAC_MDIO_DIR_OUTPUT	0		/* for clarity */
+
+
+/*
+ *  SBMAC_MII_SYNC(s)
+ *  
+ *  Synchronize with the MII - send a pattern of bits to the MII
+ *  that will guarantee that it is ready to accept a command.
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac structure
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbmac_mii_sync(struct sbmac_softc *s)
+{
+	int cnt;
+	uint64_t bits;
+	
+	bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT;
+	
+	SBMAC_WRITECSR(s->sbm_mdio,bits);
+	
+	for (cnt = 0; cnt < 32; cnt++) {
+		SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC);
+		SBMAC_WRITECSR(s->sbm_mdio,bits);
+	}
+}
+
+/*
+ *  SBMAC_MII_SENDDATA(s,data,bitcnt)
+ *  
+ *  Send some bits to the MII.  The bits to be sent are right-
+ *  justified in the 'data' parameter.
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac structure
+ *  	   data - data to send
+ *  	   bitcnt - number of bits to send
+ */
+static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitcnt)
+{
+	int i;
+	uint64_t bits;
+	unsigned int curmask;
+	
+	bits = M_MAC_MDIO_DIR_OUTPUT;
+	SBMAC_WRITECSR(s->sbm_mdio,bits);
+	
+	curmask = 1 << (bitcnt - 1);
+	
+	for (i = 0; i < bitcnt; i++) {
+		if (data & curmask) bits |= M_MAC_MDIO_OUT;
+		else bits &= ~M_MAC_MDIO_OUT;
+		SBMAC_WRITECSR(s->sbm_mdio,bits);
+		SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC);
+		SBMAC_WRITECSR(s->sbm_mdio,bits);
+		curmask >>= 1;
+	}
+}
+
+/*
+ *  SBMAC_MII_READ(s,phyaddr,regidx)
+ *  
+ *  Read a PHY register.
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac structure
+ *  	   phyaddr - PHY's address
+ *  	   regidx = index of register to read
+ *  	   
+ *  Return value:
+ *  	   value read, or 0 if an error occured.
+ */
+static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
+{
+	int idx;
+	int error;
+	int regval;
+	
+	/*
+	 * Synchronize ourselves so that the PHY knows the next
+	 * thing coming down is a command
+	 */
+	
+	sbmac_mii_sync(s);
+	
+	/*
+	 * Send the data to the PHY.  The sequence is
+	 * a "start" command (2 bits)
+	 * a "read" command (2 bits)
+	 * the PHY addr (5 bits)
+	 * the register index (5 bits)
+	 */
+	
+	sbmac_mii_senddata(s,MII_COMMAND_START, 2);
+	sbmac_mii_senddata(s,MII_COMMAND_READ, 2);
+	sbmac_mii_senddata(s,phyaddr, 5);
+	sbmac_mii_senddata(s,regidx, 5);
+	
+	/* 
+	 * Switch the port around without a clock transition.
+	 */
+	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT);
+	
+	/*
+	 * Send out a clock pulse to signal we want the status
+	 */
+	
+	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | M_MAC_MDC);
+	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT);
+	
+	/* 
+	 * If an error occured, the PHY will signal '1' back
+	 */
+	error = SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN;
+	
+	/* 
+	 * Issue an 'idle' clock pulse, but keep the direction
+	 * the same.
+	 */
+	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | M_MAC_MDC);
+	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT);
+	
+	regval = 0;
+	
+	for (idx = 0; idx < 16; idx++) {
+		regval <<= 1;
+		
+		if (error == 0) {
+			if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN) regval |= 1;
+		}
+		
+		SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | M_MAC_MDC);
+		SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT);
+	}
+	
+	/* Switch back to output */
+	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT);
+	
+	if (error == 0) return regval;
+	return 0;
+}
+
+
+/*
+ *  SBMAC_MII_WRITE(s,phyaddr,regidx,regval)
+ *  
+ *  Write a value to a PHY register.
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac structure
+ *  	   phyaddr - PHY to use
+ *  	   regidx - register within the PHY
+ *  	   regval - data to write to register
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
+			    unsigned int regval)
+{
+	
+	sbmac_mii_sync(s);
+	
+	sbmac_mii_senddata(s,MII_COMMAND_START,2);
+	sbmac_mii_senddata(s,MII_COMMAND_WRITE,2);
+	sbmac_mii_senddata(s,phyaddr, 5);
+	sbmac_mii_senddata(s,regidx, 5);
+	sbmac_mii_senddata(s,MII_COMMAND_ACK,2);
+	sbmac_mii_senddata(s,regval,16);
+	
+	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT);
+}
+
+
+
+/*
+ *  SBDMA_INITCTX(d,s,chan,txrx,maxdescr)
+ *  
+ *  Initialize a DMA channel context.  Since there are potentially
+ *  eight DMA channels per MAC, it's nice to do this in a standard
+ *  way.  
+ *  
+ *  Input parameters: 
+ *  	   d - sbmacdma_t structure (DMA channel context)
+ *  	   s - sbmac_softc structure (pointer to a MAC)
+ *  	   chan - channel number (0..1 right now)
+ *  	   txrx - Identifies DMA_TX or DMA_RX for channel direction
+ *      maxdescr - number of descriptors
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbdma_initctx(sbmacdma_t *d,
+			  struct sbmac_softc *s,
+			  int chan,
+			  int txrx,
+			  int maxdescr)
+{
+	/* 
+	 * Save away interesting stuff in the structure 
+	 */
+	
+	d->sbdma_eth       = s;
+	d->sbdma_channel   = chan;
+	d->sbdma_txdir     = txrx;
+	
+	/* 
+	 * initialize register pointers 
+	 */
+	
+	d->sbdma_config0 = 
+		PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0));
+	d->sbdma_config1 = 
+		PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0));
+	d->sbdma_dscrbase = 
+		PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE));
+	d->sbdma_dscrcnt = 
+		PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT));
+	d->sbdma_curdscr = 	
+		PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR));
+	
+	/*
+	 * Allocate memory for the ring
+	 */
+	
+	d->sbdma_maxdescr = maxdescr;
+	
+	d->sbdma_dscrtable = (sbdmadscr_t *) 
+		KMALLOC(d->sbdma_maxdescr*sizeof(sbdmadscr_t));
+	
+	memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t));
+	
+	d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr;
+	
+	d->sbdma_dscrtable_phys = KVTOPHYS(d->sbdma_dscrtable);
+	
+	/*
+	 * And context table
+	 */
+	
+	d->sbdma_ctxtable = (struct sk_buff **) 
+		KMALLOC(d->sbdma_maxdescr*sizeof(struct sk_buff *));
+	
+	memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *));
+	
+}
+
+/*
+ *  SBDMA_CHANNEL_START(d)
+ *  
+ *  Initialize the hardware registers for a DMA channel.
+ *  
+ *  Input parameters: 
+ *  	   d - DMA channel to init (context must be previously init'd
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbdma_channel_start(sbmacdma_t *d)
+{
+	/*
+	 * Turn on the DMA channel
+	 */
+	
+	SBMAC_WRITECSR(d->sbdma_config1,0);
+	
+	SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys);
+	
+	SBMAC_WRITECSR(d->sbdma_config0,
+		       V_DMA_RINGSZ(d->sbdma_maxdescr) |
+		       0);
+	
+	/*
+	 * Initialize ring pointers
+	 */
+	
+	d->sbdma_addptr = d->sbdma_dscrtable;
+	d->sbdma_remptr = d->sbdma_dscrtable;
+}
+
+
+static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset)
+{
+	unsigned long addr;
+	unsigned long newaddr;
+	
+	addr = (unsigned long) skb->data;
+	
+	newaddr = (addr + power2 - 1) & ~(power2 - 1);
+	
+	skb_reserve(skb,newaddr-addr+offset);
+}
+
+/*
+ *  SBDMA_ADD_RCVBUFFER(d,sb)
+ *  
+ *  Add a buffer to the specified DMA channel.   For receive channels,
+ *  this queues a buffer for inbound packets.
+ *  
+ *  Input parameters: 
+ *  	   d - DMA channel descriptor
+ * 	   sb - sk_buff to add, or NULL if we should allocate one
+ *  	   
+ *  Return value:
+ *  	   0 if buffer could not be added (ring is full)
+ *  	   1 if buffer added successfully
+ */
+static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
+{
+	sbdmadscr_t *dsc;
+	sbdmadscr_t *nextdsc;
+	struct sk_buff *sb_new = NULL;
+	int pktsize = ENET_PACKET_SIZE;
+	
+	/* get pointer to our current place in the ring */
+	
+	dsc = d->sbdma_addptr;
+	nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
+	
+	/*
+	 * figure out if the ring is full - if the next descriptor
+	 * is the same as the one that we're going to remove from
+	 * the ring, the ring is full
+	 */
+	
+	if (nextdsc == d->sbdma_remptr) {
+		return -ENOSPC;
+	}
+	
+	/* 
+	 * Allocate a sk_buff if we don't already have one.  
+	 * If we do have an sk_buff, reset it so that it's empty.
+	 *
+	 * Note: sk_buffs don't seem to be guaranteed to have any sort
+	 * of alignment when they are allocated.  Therefore, allocate enough
+	 * extra space to make sure that:
+	 *
+	 *    1. the data does not start in the middle of a cache line.
+	 *    2. The data does not end in the middle of a cache line
+	 * 	  3. The buffer can be aligned such that the IP addresses are 
+	 *       naturally aligned.
+	 *
+	 *  Remember, the SB1250's MAC writes whole cache lines at a time,
+	 *  without reading the old contents first.  So, if the sk_buff's
+	 *  data portion starts in the middle of a cache line, the SB1250
+	 *  DMA will trash the beginning (and ending) portions.
+	 */
+	
+	if (sb == NULL) {
+		sb_new = dev_alloc_skb(ENET_PACKET_SIZE + CACHELINESIZE*2 + ETHER_ALIGN);
+		if (sb_new == NULL) {
+			printk(KERN_INFO "%s: sk_buff allocation failed\n",
+			       d->sbdma_eth->sbm_dev->name);
+			return -ENOBUFS;
+		}
+		
+		sbdma_align_skb(sb_new,CACHELINESIZE,ETHER_ALIGN);
+		
+		/* mark skbuff owned by our device */
+		sb_new->dev = d->sbdma_eth->sbm_dev;
+	}
+	else {
+		sb_new = sb;
+		/* 
+		 * nothing special to reinit buffer, it's already aligned
+		 * and sb->tail already points to a good place.
+		 */
+	}
+	
+	/*
+	 * fill in the descriptor 
+	 */
+	
+	dsc->dscr_a = KVTOPHYS(sb_new->tail) |
+		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
+		M_DMA_DSCRA_INTERRUPT;
+	
+	/* receiving: no options */
+	dsc->dscr_b = 0;
+	
+	/*
+	 * fill in the context 
+	 */
+	
+	d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb_new;
+	
+	/* 
+	 * point at next packet 
+	 */
+	
+	d->sbdma_addptr = nextdsc;
+	
+	/* 
+	 * Give the buffer to the DMA engine.
+	 */
+	
+	SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
+	
+	return 0;					/* we did it */
+}
+
+/*
+ *  SBDMA_ADD_TXBUFFER(d,sb)
+ *  
+ *  Add a transmit buffer to the specified DMA channel, causing a
+ *  transmit to start.
+ *  
+ *  Input parameters: 
+ *  	   d - DMA channel descriptor
+ * 	   sb - sk_buff to add
+ *  	   
+ *  Return value:
+ *  	   0 transmit queued successfully
+ *  	   otherwise error code
+ */
+static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *sb)
+{
+	sbdmadscr_t *dsc;
+	sbdmadscr_t *nextdsc;
+	uint64_t phys;
+	uint64_t ncb;
+	int length;
+	
+	/* get pointer to our current place in the ring */
+	
+	dsc = d->sbdma_addptr;
+	nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
+	
+	/*
+	 * figure out if the ring is full - if the next descriptor
+	 * is the same as the one that we're going to remove from
+	 * the ring, the ring is full
+	 */
+	
+	if (nextdsc == d->sbdma_remptr) {
+		return -ENOSPC;
+	}
+	
+	/*
+	 * Under Linux, it's not necessary to copy/coalesce buffers
+	 * like it is on NetBSD.  We think they're all contiguous,
+	 * but that may not be true for GBE.
+	 */
+	
+	length = sb->len;
+	
+	/*
+	 * fill in the descriptor.  Note that the number of cache
+	 * blocks in the descriptor is the number of blocks
+	 * *spanned*, so we need to add in the offset (if any)
+	 * while doing the calculation.
+	 */
+	
+	phys = KVTOPHYS(sb->data);
+	ncb = NUMCACHEBLKS(length+(phys & (CACHELINESIZE-1)));
+	
+	dsc->dscr_a = phys | 
+		V_DMA_DSCRA_A_SIZE(ncb) |
+		M_DMA_DSCRA_INTERRUPT |
+		M_DMA_ETHTX_SOP;
+	
+	/* transmitting: set outbound options and length */
+
+	dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
+		V_DMA_DSCRB_PKT_SIZE(length);
+	
+	/*
+	 * fill in the context 
+	 */
+	
+	d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb;
+	
+	/* 
+	 * point at next packet 
+	 */
+	
+	d->sbdma_addptr = nextdsc;
+	
+	/* 
+	 * Give the buffer to the DMA engine.
+	 */
+	
+	SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
+	
+	return 0;					/* we did it */
+}
+
+/**********************************************************************
+ *  SBDMA_EMPTYRING(d)
+ *  
+ *  Free all allocated sk_buffs on the specified DMA channel;
+ *  
+ *  Input parameters: 
+ *  	   d  - DMA channel
+ *  	   
+ *  Return value:
+ *  	   nothing
+ ********************************************************************* */
+
+static void sbdma_emptyring(sbmacdma_t *d)
+{
+	int idx;
+	struct sk_buff *sb;
+	
+	for (idx = 0; idx < d->sbdma_maxdescr; idx++) {
+		sb = d->sbdma_ctxtable[idx];
+		if (sb) {
+			dev_kfree_skb(sb);
+			d->sbdma_ctxtable[idx] = NULL;
+		}
+	}
+}
+
+
+/**********************************************************************
+ *  SBDMA_FILLRING(d)
+ *  
+ *  Fill the specified DMA channel (must be receive channel)
+ *  with sk_buffs
+ *  
+ *  Input parameters: 
+ *  	   d - DMA channel
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbdma_fillring(sbmacdma_t *d)
+{
+	int idx;
+	
+	for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++)
+		if (sbdma_add_rcvbuffer(d, NULL) != 0)
+			break;
+}
+
+/*
+ *  SBDMA_RX_PROCESS(sc,d)
+ *  
+ *  Process "completed" receive buffers on the specified DMA channel.  
+ *  Note that this isn't really ideal for priority channels, since
+ *  it processes all of the packets on a given channel before 
+ *  returning. 
+ *
+ *  Input parameters: 
+ *	   sc - softc structure
+ *  	   d - DMA channel context
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
+{
+	int curidx;
+	int hwidx;
+	sbdmadscr_t *dsc;
+	struct sk_buff *sb;
+	int len;
+	
+	for (;;) {
+		/* 
+		 * figure out where we are (as an index) and where
+		 * the hardware is (also as an index)
+		 *
+		 * This could be done faster if (for example) the 
+		 * descriptor table was page-aligned and contiguous in
+		 * both virtual and physical memory -- you could then
+		 * just compare the low-order bits of the virtual address
+		 * (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
+		 */
+		curidx = d->sbdma_remptr - d->sbdma_dscrtable;
+		hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+				d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
+
+		/*
+		 * If they're the same, that means we've processed all
+		 * of the descriptors up to (but not including) the one that
+		 * the hardware is working on right now.
+		 */
+		if (curidx == hwidx)
+			break;
+
+		/*
+		 * Otherwise, get the packet's sk_buff ptr back
+		 */
+		dsc = d->sbdma_dscrtable + curidx;
+		sb = d->sbdma_ctxtable[curidx];
+		d->sbdma_ctxtable[curidx] = NULL;
+
+		len = (int)G_DMA_DSCRB_PKT_SIZE(dsc->dscr_b) - 4;
+
+		/*
+		 * Check packet status.  If good, process it.
+		 * If not, silently drop it and put it back on the
+		 * receive ring.
+		 */
+		if (!(dsc->dscr_a & M_DMA_ETHRX_BAD)) {
+			/*
+			 * Set length into the packet
+			 */
+			skb_put(sb,len);
+
+       			/*
+			 * Add a new buffer to replace the old one.  If we fail
+			 * to allocate a buffer, we're going to drop this
+			 * packet and put it right back on the receive ring.
+			 */
+			if (sbdma_add_rcvbuffer(d, NULL) == -ENOBUFS) {
+				sbdma_add_rcvbuffer(d,sb);	/* re-add old buffer */
+			} else {
+				/*
+				 * Buffer has been replaced on the receive ring.
+				 * Pass the buffer to the kernel
+				 */
+				sc->sbm_stats.rx_bytes += len;
+				sc->sbm_stats.rx_packets++;
+				sb->protocol = eth_type_trans(sb,
+							d->sbdma_eth->sbm_dev);
+				netif_rx(sb);
+			}
+		} else {
+			/*
+			 * Packet was mangled somehow.  Just drop it and
+			 * put it back on the receive ring.
+			 */
+			sbdma_add_rcvbuffer(d,sb);
+		}
+
+		/* 
+		 * .. and advance to the next buffer.
+		 */
+		d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
+	}
+}
+
+/*
+ *  SBDMA_TX_PROCESS(sc,d)
+ *  
+ *  Process "completed" transmit buffers on the specified DMA channel.  
+ *  This is normally called within the interrupt service routine.
+ *  Note that this isn't really ideal for priority channels, since
+ *  it processes all of the packets on a given channel before 
+ *  returning. 
+ *
+ *  Input parameters: 
+ *      sc - softc structure
+ *  	   d - DMA channel context
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
+{
+	int curidx;
+	int hwidx;
+	sbdmadscr_t *dsc;
+	struct sk_buff *sb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->sbm_lock, flags);
+
+	for (;;) {
+		/* 
+		 * figure out where we are (as an index) and where
+		 * the hardware is (also as an index)
+		 *
+		 * This could be done faster if (for example) the 
+		 * descriptor table was page-aligned and contiguous in
+		 * both virtual and physical memory -- you could then
+		 * just compare the low-order bits of the virtual address
+		 * (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
+		 */
+		
+		curidx = d->sbdma_remptr - d->sbdma_dscrtable;
+		{
+			/* XXX This is gross, ugly, and only here because justin hacked it
+			   in to fix a problem without really understanding it. 
+			   
+			   It seems that, for whatever reason, this routine is invoked immediately upon the enabling of interrupts.
+			   So then the Read below returns zero, making hwidx a negative number, and anti-hilarity
+			   ensues.
+			   
+			   I'm guessing there's a proper fix involving clearing out interrupt state from old packets
+			   before enabling interrupts, but I'm not sure.  
+
+			   Anyways, this hack seems to work, and is Good Enough for 11 PM.  :)
+			   
+			   -Justin
+			*/
+			  
+			uint64_t tmp = SBMAC_READCSR(d->sbdma_curdscr);
+			if (!tmp)
+				break;
+
+			hwidx = (int) (((tmp & M_DMA_CURDSCR_ADDR) -
+					d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
+		}
+
+		/*
+		 * If they're the same, that means we've processed all
+		 * of the descriptors up to (but not including) the one that
+		 * the hardware is working on right now.
+		 */
+		if (curidx == hwidx)
+			break;
+		
+		/*
+		 * Otherwise, get the packet's sk_buff ptr back
+		 */
+		dsc = d->sbdma_dscrtable + curidx;
+		sb = d->sbdma_ctxtable[curidx];
+		d->sbdma_ctxtable[curidx] = NULL;
+
+		/*
+		 * Stats
+		 */
+		sc->sbm_stats.tx_bytes += sb->len;
+		sc->sbm_stats.tx_packets++;
+
+		/*
+		 * for transmits, we just free buffers.
+		 */
+		dev_kfree_skb_irq(sb);
+
+		/* 
+		 * .. and advance to the next buffer.
+		 */
+		d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
+		
+	}
+
+	/*
+	 * Decide if we should wake up the protocol or not.
+	 * Other drivers seem to do this when we reach a low
+	 * watermark on the transmit queue.
+	 */
+	netif_wake_queue(d->sbdma_eth->sbm_dev);
+
+	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+}
+
+
+
+/*
+ *  SBMAC_INITCTX(s)
+ *  
+ *  Initialize an Ethernet context structure - this is called
+ *  once per MAC on the 1250.  Memory is allocated here, so don't
+ *  call it again from inside the ioctl routines that bring the
+ *  interface up/down
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac context structure
+ *  	   
+ *  Return value:
+ *  	   0
+ */
+static int sbmac_initctx(struct sbmac_softc *s)
+{
+	
+	/* 
+	 * figure out the addresses of some ports 
+	 */
+	
+	s->sbm_macenable = PKSEG1(s->sbm_base + R_MAC_ENABLE);
+	s->sbm_maccfg    = PKSEG1(s->sbm_base + R_MAC_CFG);
+	s->sbm_fifocfg   = PKSEG1(s->sbm_base + R_MAC_THRSH_CFG);
+	s->sbm_framecfg  = PKSEG1(s->sbm_base + R_MAC_FRAMECFG);
+	s->sbm_rxfilter  = PKSEG1(s->sbm_base + R_MAC_ADFILTER_CFG);
+	s->sbm_isr       = PKSEG1(s->sbm_base + R_MAC_STATUS);
+	s->sbm_imr       = PKSEG1(s->sbm_base + R_MAC_INT_MASK);
+	s->sbm_mdio      = PKSEG1(s->sbm_base + R_MAC_MDIO);
+
+	s->sbm_phys[0]   = 1;
+	s->sbm_phys[1]   = 0;
+
+	s->sbm_phy_oldbmsr = 0;
+	s->sbm_phy_oldanlpar = 0;
+	s->sbm_phy_oldk1stsr = 0;
+	s->sbm_phy_oldlinkstat = 0;
+	
+	/*
+	 * Initialize the DMA channels.  Right now, only one per MAC is used
+	 * Note: Only do this _once_, as it allocates memory from the kernel!
+	 */
+	
+	sbdma_initctx(&s->sbm_txdma, s, 0, DMA_TX,SBMAC_MAX_TXDESCR);
+	sbdma_initctx(&s->sbm_rxdma, s, 0, DMA_RX,SBMAC_MAX_RXDESCR);
+	
+	/*
+	 * initial state is OFF
+	 */
+	
+	s->sbm_state = sbmac_state_off;
+	
+	/*
+	 * Initial speed is (XXX TEMP) 10MBit/s HDX no FC
+	 */
+	
+	s->sbm_speed = sbmac_speed_10;
+	s->sbm_duplex = sbmac_duplex_half;
+	s->sbm_fc = sbmac_fc_disabled;
+	
+	return 0;
+}
+
+static void sbdma_uninitctx(struct sbmacdma_s *d)
+{
+	if (d->sbdma_dscrtable) {
+		KFREE(d->sbdma_dscrtable);
+		d->sbdma_dscrtable = NULL;
+	}
+	
+	if (d->sbdma_ctxtable) {
+		KFREE(d->sbdma_ctxtable);
+		d->sbdma_ctxtable = NULL;
+	}
+}
+
+
+static void sbmac_uninitctx(struct sbmac_softc *sc)
+{
+	sbdma_uninitctx(&sc->sbm_txdma);
+	sbdma_uninitctx(&sc->sbm_rxdma);
+}
+
+/*
+ *  SBMAC_CHANNEL_START(s)
+ *  
+ *  Start packet processing on this MAC.
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac structure
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbmac_channel_start(struct sbmac_softc *s)
+{
+	uint64_t reg;
+	sbmac_port_t port;
+	uint64_t cfg,fifo,framecfg;
+	int idx;
+	
+	/*
+	 * Don't do this if running
+	 */
+
+	if (s->sbm_state == sbmac_state_on) return;
+	
+	/*
+	 * Bring the controller out of reset, but leave it off.
+	 */
+	
+	SBMAC_WRITECSR(s->sbm_macenable,0);
+	
+	/*
+	 * Ignore all received packets
+	 */
+	
+	SBMAC_WRITECSR(s->sbm_rxfilter,0);
+	
+	/* 
+	 * Calculate values for various control registers.
+	 */
+	
+	cfg = M_MAC_RETRY_EN |
+		M_MAC_TX_HOLD_SOP_EN | 
+		V_MAC_TX_PAUSE_CNT_16K |
+		M_MAC_AP_STAT_EN |
+		M_MAC_FAST_SYNC |
+		M_MAC_SS_EN |
+		0;
+	
+	fifo = V_MAC_TX_WR_THRSH(4) |	/* Must be '4' or '8' */
+		V_MAC_TX_RD_THRSH(4) |
+		V_MAC_TX_RL_THRSH(4) |
+		V_MAC_RX_PL_THRSH(4) |
+		V_MAC_RX_RD_THRSH(4) |	/* Must be '4' */
+		V_MAC_RX_PL_THRSH(4) |
+		V_MAC_RX_RL_THRSH(8) |
+		0;
+	
+	framecfg = V_MAC_MIN_FRAMESZ_DEFAULT |
+		V_MAC_MAX_FRAMESZ_DEFAULT |
+		V_MAC_BACKOFF_SEL(1);
+	
+	
+	/*
+	 * Clear out the hash address map 
+	 */
+	
+	port = PKSEG1(s->sbm_base + R_MAC_HASH_BASE);
+        for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
+		SBMAC_WRITECSR(port,0);
+		port += sizeof(uint64_t);
+	}
+	
+	/*
+	 * Clear out the exact-match table
+	 */
+	
+	port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE);
+	for (idx = 0; idx < MAC_ADDR_COUNT; idx++) {
+		SBMAC_WRITECSR(port,0);
+		port += sizeof(uint64_t);
+	}
+	
+	/*
+	 * Clear out the DMA Channel mapping table registers
+	 */
+	
+	port = PKSEG1(s->sbm_base + R_MAC_CHUP0_BASE);
+	for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
+		SBMAC_WRITECSR(port,0);
+		port += sizeof(uint64_t);
+	}
+
+
+	port = PKSEG1(s->sbm_base + R_MAC_CHLO0_BASE);
+	for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
+		SBMAC_WRITECSR(port,0);
+		port += sizeof(uint64_t);
+	}
+	
+	/*
+	 * Program the hardware address.  It goes into the hardware-address
+	 * register as well as the first filter register.
+	 */
+	
+	reg = sbmac_addr2reg(s->sbm_hwaddr);
+	
+	port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE);
+	SBMAC_WRITECSR(port,reg);
+	port = PKSEG1(s->sbm_base + R_MAC_ETHERNET_ADDR);
+
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	/*
+	 * Pass1 SB1250s do not receive packets addressed to the
+	 * destination address in the R_MAC_ETHERNET_ADDR register.
+	 * Set the value to zero.
+	 */
+	SBMAC_WRITECSR(port,0);
+#else
+	SBMAC_WRITECSR(port,reg);
+#endif
+	
+	/*
+	 * Set the receive filter for no packets, and write values
+	 * to the various config registers
+	 */
+	
+	SBMAC_WRITECSR(s->sbm_rxfilter,0);
+	SBMAC_WRITECSR(s->sbm_imr,0);
+	SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
+	SBMAC_WRITECSR(s->sbm_fifocfg,fifo);
+	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+	
+	/*
+	 * Initialize DMA channels (rings should be ok now)
+	 */
+	sbdma_channel_start(&s->sbm_rxdma);
+	sbdma_channel_start(&s->sbm_txdma);
+
+	/*
+	 * Configure the speed, duplex, and flow control
+	 */
+	sbmac_set_speed(s,s->sbm_speed);
+	sbmac_set_duplex(s,s->sbm_duplex,s->sbm_fc);
+	
+	/*
+	 * Fill the receive ring
+	 */
+	sbdma_fillring(&s->sbm_rxdma);
+
+	/* 
+	 * Turn on the rest of the bits in the enable register
+	 */      
+	SBMAC_WRITECSR(s->sbm_macenable,
+		       M_MAC_RXDMA_EN0 |
+		       M_MAC_TXDMA_EN0 |
+		       M_MAC_RX_ENABLE |
+		       M_MAC_TX_ENABLE);
+
+	/*
+	 * Accept any kind of interrupt on TX and RX DMA channel 0
+	 */
+	SBMAC_WRITECSR(s->sbm_imr,
+		       (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
+		       (M_MAC_INT_CHANNEL << S_MAC_RX_CH0));
+
+	/* 
+	 * Enable receiving unicasts and broadcasts 
+	 */
+	SBMAC_WRITECSR(s->sbm_rxfilter,M_MAC_UCAST_EN | M_MAC_BCAST_EN);
+
+	/*
+	 * we're running now. 
+	 */
+	s->sbm_state = sbmac_state_on;
+
+	/* 
+	 * Program multicast addresses 
+	 */
+	sbmac_setmulti(s);
+
+	/* 
+	 * If channel was in promiscuous mode before, turn that on 
+	 */
+	if (s->sbm_devflags & IFF_PROMISC)
+		sbmac_promiscuous_mode(s,1);
+}
+
+/*
+ *  SBMAC_CHANNEL_STOP(s)
+ *  
+ *  Stop packet processing on this MAC.
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac structure
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbmac_channel_stop(struct sbmac_softc *s)
+{
+	uint64_t ctl;
+	
+	/* don't do this if already stopped */
+	
+	if (s->sbm_state == sbmac_state_off) return;
+	
+	/* don't accept any packets, disable all interrupts */
+	
+	SBMAC_WRITECSR(s->sbm_rxfilter,0);
+	SBMAC_WRITECSR(s->sbm_imr,0);
+	
+	/* Turn off ticker */
+	
+	/* XXX */
+	
+	/* turn off receiver and transmitter */
+	
+	ctl = SBMAC_READCSR(s->sbm_macenable);
+	ctl &= ~(M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0);
+	SBMAC_WRITECSR(s->sbm_macenable,ctl);
+	
+	/* We're stopped now. */
+	
+	s->sbm_state = sbmac_state_off;
+	
+	
+	/* Empty the receive and transmit rings */
+	
+	sbdma_emptyring(&s->sbm_rxdma);
+	sbdma_emptyring(&s->sbm_txdma);
+}
+
+/*
+ *  SBMAC_SET_CHANNEL_STATE(state)
+ *  
+ *  Set the channel's state ON or OFF
+ *  
+ *  Input parameters: 
+ *  	   state - new state
+ *  	   
+ *  Return value:
+ *  	   old state
+ */
+static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *sc,
+					     sbmac_state_t state)
+{
+	sbmac_state_t oldstate = sc->sbm_state;
+	
+	/*
+	 * If same as previous state, return
+	 */
+	
+	if (state == oldstate) {
+		return oldstate;
+	}
+	
+	/*
+	 * If new state is ON, turn channel on 
+	 */
+	
+	if (state == sbmac_state_on) {
+		sbmac_channel_start(sc);
+	}
+	else {
+		sbmac_channel_stop(sc);
+	}
+	
+	/*
+	 * Return previous state
+	 */
+	
+	return oldstate;
+}
+
+
+/*
+ *  SBMAC_PROMISCUOUS_MODE(sc,onoff)
+ *  
+ *  Turn on or off promiscuous mode
+ *  
+ *  Input parameters: 
+ *  	   sc - softc
+ *      onoff - 1 to turn on, 0 to turn off
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff)
+{
+	uint64_t reg;
+	
+	if (sc->sbm_state != sbmac_state_on) return;
+	
+	if (onoff) {
+		reg = SBMAC_READCSR(sc->sbm_rxfilter);
+		reg |= M_MAC_ALLPKT_EN;
+		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+	}	
+	else {
+		reg = SBMAC_READCSR(sc->sbm_rxfilter);
+		reg &= ~M_MAC_ALLPKT_EN;
+		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+	}
+}
+
+
+
+#if 0
+/**********************************************************************
+ *  SBMAC_INIT_AND_START(sc)
+ *  
+ *  Stop the channel and restart it.  This is generally used
+ *  when we have to do something to the channel that requires
+ *  a swift kick.
+ *  
+ *  Input parameters: 
+ *  	   sc - softc
+ ********************************************************************* */
+
+static void sbmac_init_and_start(struct sbmac_softc *sc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->sbm_lock, flags);
+	sbmac_set_channel_state(sc, sbmac_state_on);
+	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+}
+#endif
+
+
+/*
+ *  SBMAC_ADDR2REG(ptr)
+ *  
+ *  Convert six bytes into the 64-bit register value that
+ *  we typically write into the SBMAC's address/mcast registers
+ *  
+ *  Input parameters: 
+ *  	   ptr - pointer to 6 bytes
+ *  	   
+ *  Return value:
+ *  	   register value
+ */
+static uint64_t sbmac_addr2reg(unsigned char *ptr)
+{
+	uint64_t reg = 0;
+
+	ptr += 6;
+
+	reg |= (uint64_t) *(--ptr); 
+	reg <<= 8;
+	reg |= (uint64_t) *(--ptr); 
+	reg <<= 8;
+	reg |= (uint64_t) *(--ptr); 
+	reg <<= 8;
+	reg |= (uint64_t) *(--ptr); 
+	reg <<= 8;
+	reg |= (uint64_t) *(--ptr); 
+	reg <<= 8;
+	reg |= (uint64_t) *(--ptr); 
+
+	return reg;
+}
+
+
+/*
+ *  SBMAC_SET_SPEED(s,speed)
+ *  
+ *  Configure LAN speed for the specified MAC.
+ *  Warning: must be called when MAC is off!
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac structure
+ *  	   speed - speed to set MAC to (see sbmac_speed_t enum)
+ *  	   
+ *  Return value:
+ *  	   1 if successful
+ *      0 indicates invalid parameters
+ */
+static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
+{
+	uint64_t cfg;
+	uint64_t framecfg;
+
+	/*
+	 * Save new current values
+	 */
+	
+	s->sbm_speed = speed;
+	
+	if (s->sbm_state == sbmac_state_on) return 0;	/* save for next restart */
+
+	/*
+	 * Read current register values 
+	 */
+	
+	cfg = SBMAC_READCSR(s->sbm_maccfg);
+	framecfg = SBMAC_READCSR(s->sbm_framecfg);
+	
+	/*
+	 * Mask out the stuff we want to change
+	 */
+	
+	cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL);
+	framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH |
+		      M_MAC_SLOT_SIZE);
+	
+	/*
+	 * Now add in the new bits
+	 */
+	
+	switch (speed) {
+	case sbmac_speed_10:
+		framecfg |= V_MAC_IFG_RX_10 |
+			V_MAC_IFG_TX_10 |
+			K_MAC_IFG_THRSH_10 |
+			V_MAC_SLOT_SIZE_10;
+		cfg |= V_MAC_SPEED_SEL_10MBPS;
+		break;
+		
+	case sbmac_speed_100:
+		framecfg |= V_MAC_IFG_RX_100 |
+			V_MAC_IFG_TX_100 |
+			V_MAC_IFG_THRSH_100 |
+			V_MAC_SLOT_SIZE_100;
+		cfg |= V_MAC_SPEED_SEL_100MBPS ;
+		break;
+		
+	case sbmac_speed_1000:
+		framecfg |= V_MAC_IFG_RX_1000 |
+			V_MAC_IFG_TX_1000 |
+			V_MAC_IFG_THRSH_1000 |
+			V_MAC_SLOT_SIZE_1000;
+		cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN;
+		break;
+		
+	case sbmac_speed_auto:		/* XXX not implemented */
+		/* fall through */
+	default:
+		return 0;
+	}
+	
+	/*
+	 * Send the bits back to the hardware 
+	 */
+	
+	SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
+	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+	
+	return 1;
+	
+}
+
+/**********************************************************************
+ *  SBMAC_SET_DUPLEX(s,duplex,fc)
+ *  
+ *  Set Ethernet duplex and flow control options for this MAC
+ *  Warning: must be called when MAC is off!
+ *  
+ *  Input parameters: 
+ *  	   s - sbmac structure
+ *  	   duplex - duplex setting (see sbmac_duplex_t)
+ *  	   fc - flow control setting (see sbmac_fc_t)
+ *  	   
+ *  Return value:
+ *  	   1 if ok
+ *  	   0 if an invalid parameter combination was specified
+ ********************************************************************* */
+
+static int sbmac_set_duplex(struct sbmac_softc *s, sbmac_duplex_t duplex,
+                            sbmac_fc_t fc)
+{
+	uint64_t cfg;
+	
+	/*
+	 * Save new current values
+	 */
+	
+	s->sbm_duplex = duplex;
+	s->sbm_fc = fc;
+	
+	if (s->sbm_state == sbmac_state_on) return 0;	/* save for next restart */
+	
+	/*
+	 * Read current register values 
+	 */
+	
+	cfg = SBMAC_READCSR(s->sbm_maccfg);
+	
+	/*
+	 * Mask off the stuff we're about to change
+	 */
+	
+	cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN);
+	
+	
+	switch (duplex) {
+	case sbmac_duplex_half:
+		switch (fc) {
+		case sbmac_fc_disabled:
+			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED;
+			break;
+			
+		case sbmac_fc_collision:
+			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED;
+			break;
+			
+		case sbmac_fc_carrier:
+			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR;
+			break;
+			
+		case sbmac_fc_auto:		/* XXX not implemented */
+			/* fall through */					   
+		case sbmac_fc_frame:		/* not valid in half duplex */
+		default:			/* invalid selection */
+			return 0;
+		}
+		break;
+		
+	case sbmac_duplex_full:
+		switch (fc) {
+		case sbmac_fc_disabled:
+			cfg |= V_MAC_FC_CMD_DISABLED;
+			break;
+			
+		case sbmac_fc_frame:
+			cfg |= V_MAC_FC_CMD_ENABLED;
+			break;
+			
+		case sbmac_fc_collision:	/* not valid in full duplex */
+		case sbmac_fc_carrier:		/* not valid in full duplex */
+		case sbmac_fc_auto:		/* XXX not implemented */
+			/* fall through */					   
+		default:
+			return 0;
+		}
+		break;
+	case sbmac_duplex_auto:
+		/* XXX not implemented */
+		break;
+	}
+	
+	/*
+	 * Send the bits back to the hardware 
+	 */
+	
+	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+	
+	return 1;
+}
+
+static void sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs)
+{
+	struct net_device *dev = (struct net_device *) dev_instance;
+	struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv;
+	uint64_t isr;
+
+	for (;;) {
+		/*
+		 * Read the ISR (this clears the bits in the real register)
+		 */
+		isr = SBMAC_READCSR(sc->sbm_isr);
+
+		if (isr == 0)
+			break;
+
+		/*
+		 * Transmits on channel 0
+		 */
+		if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0))
+			sbdma_tx_process(sc, &sc->sbm_txdma);
+
+		/*
+		 * Receives on channel 0
+		 */
+		if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0))
+			sbdma_rx_process(sc, &sc->sbm_rxdma);
+	}
+}
+
+
+/*
+ *  SBMAC_START_TX(skb,dev)
+ *  
+ *  Start output on the specified interface.  Basically, we 
+ *  queue as many buffers as we can until the ring fills up, or
+ *  we run off the end of the queue, whichever comes first.
+ *  
+ *  Input parameters: 
+ *  	   
+ *  	   
+ *  Return value:
+ *  	   nothing
+ */
+static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv;
+
+	/* lock eth irq */
+	spin_lock_irq(&sc->sbm_lock);
+
+	/*
+	 * Put the buffer on the transmit ring.  If we 
+	 * don't have room, stop the queue.
+	 */
+	if (unlikely(sbdma_add_txbuffer(&sc->sbm_txdma, skb))) {
+		netif_stop_queue(dev);
+		spin_unlock_irq(&sc->sbm_lock);
+
+		return 1;
+	}
+
+	dev->trans_start = jiffies;
+
+	spin_unlock_irq(&sc->sbm_lock);
+
+	return 0;
+}
+
+/**********************************************************************
+ *  SBMAC_SETMULTI(sc)
+ *  
+ *  Reprogram the multicast table into the hardware, given
+ *  the list of multicasts associated with the interface
+ *  structure.
+ *  
+ *  Input parameters: 
+ *  	   sc - softc
+ *  	   
+ *  Return value:
+ *  	   nothing
+ ********************************************************************* */
+
+static void sbmac_setmulti(struct sbmac_softc *sc)
+{
+	uint64_t reg;
+	sbmac_port_t port;
+	int idx;
+	struct dev_mc_list *mclist;
+	struct net_device *dev = sc->sbm_dev;
+	
+	/* 
+	 * Clear out entire multicast table.  We do this by nuking
+	 * the entire hash table and all the direct matches except
+	 * the first one, which is used for our station address 
+	 */
+	
+	for (idx = 1; idx < MAC_ADDR_COUNT; idx++) {
+		port = PKSEG1(sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)));
+		SBMAC_WRITECSR(port,0);	
+	}
+	
+	for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
+		port = PKSEG1(sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t)));
+		SBMAC_WRITECSR(port,0);	
+	}
+	
+	/*
+	 * Clear the filter to say we don't want any multicasts.
+	 */
+	
+	reg = SBMAC_READCSR(sc->sbm_rxfilter);
+	reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN);
+	SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+	
+	if (dev->flags & IFF_ALLMULTI) {
+		/* 
+		 * Enable ALL multicasts.  Do this by inverting the 
+		 * multicast enable bit. 
+		 */
+		reg = SBMAC_READCSR(sc->sbm_rxfilter);
+		reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN);
+		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+		return;
+	}
+	
+
+	/* 
+	 * Progam new multicast entries.  For now, only use the
+	 * perfect filter.  In the future we'll need to use the
+	 * hash filter if the perfect filter overflows
+	 */
+	
+	/* XXX only using perfect filter for now, need to use hash
+	 * XXX if the table overflows */
+	
+	idx = 1;		/* skip station address */
+	mclist = dev->mc_list;
+	while (mclist && (idx < MAC_ADDR_COUNT)) {
+		reg = sbmac_addr2reg(mclist->dmi_addr);
+		port = PKSEG1(sc->sbm_base + 
+			      R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)));
+		SBMAC_WRITECSR(port,reg);
+		idx++;
+		mclist = mclist->next;
+	}
+	
+	/*	
+	 * Enable the "accept multicast bits" if we programmed at least one
+	 * multicast. 
+	 */
+	
+	if (idx > 1) {
+		reg = SBMAC_READCSR(sc->sbm_rxfilter);
+		reg |= M_MAC_MCAST_EN;
+		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+	}
+}
+
+#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR)
+/**********************************************************************
+ *  SBMAC_PARSE_XDIGIT(str)
+ *  
+ *  Parse a hex digit, returning its value
+ *  
+ *  Input parameters: 
+ *  	   str - character
+ *  	   
+ *  Return value:
+ *  	   hex value, or -1 if invalid
+ ********************************************************************* */
+
+static int sbmac_parse_xdigit(char str)
+{
+	int digit;
+	
+	if ((str >= '0') && (str <= '9')) digit = str - '0';
+	else if ((str >= 'a') && (str <= 'f')) digit = str - 'a' + 10;
+	else if ((str >= 'A') && (str <= 'F')) digit = str - 'A' + 10;
+	else return -1;
+	
+	return digit;
+}
+
+static int sbmac_parse_hwaddr(char *str,u_char *hwaddr)
+{
+	int digit1,digit2;
+	int idx = 6;
+	
+	while (*str && (idx > 0)) {
+		digit1 = sbmac_parse_xdigit(*str);
+		if (digit1 < 0) return -1;
+		str++;
+		if (!*str) return -1;
+		
+		if ((*str == ':') || (*str == '-')) {
+			digit2 = digit1;
+			digit1 = 0;
+		}
+		else {
+			digit2 = sbmac_parse_xdigit(*str);
+			if (digit2 < 0) return -1;
+			str++;
+		}
+		
+		*hwaddr++ = (digit1 << 4) | digit2;
+		idx--;
+		
+		if (*str == '-') str++;
+		if (*str == ':') str++;
+	}
+	return 0;
+}
+#endif
+
+static int sbmac_init(struct net_device *dev)
+{
+	struct sbmac_softc *sc;
+	u_char *eaddr;
+	uint64_t ea_reg;
+	int idx;
+	
+	sc = (struct sbmac_softc *)dev->priv;
+	
+	/* Determine controller base address */
+	
+	sc->sbm_base = (sbmac_port_t) dev->base_addr;
+	sc->sbm_dev = dev;
+	
+	eaddr = sc->sbm_hwaddr;
+	
+	/* 
+	 * Read the ethernet address.  The firwmare left this programmed
+	 * for us in the ethernet address register for each mac.
+	 */
+	
+	ea_reg = SBMAC_READCSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR));
+	SBMAC_WRITECSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR), 0);
+	for (idx = 0; idx < 6; idx++) {
+		eaddr[idx] = (uint8_t) (ea_reg & 0xFF);
+		ea_reg >>= 8;
+	}
+	
+	
+	for (idx = 0; idx < 6; idx++) {
+		dev->dev_addr[idx] = eaddr[idx];
+	}
+	
+	
+	/*
+	 * Init packet size 
+	 */
+	
+	sc->sbm_buffersize = ENET_PACKET_SIZE + CACHELINESIZE*2 + ETHER_ALIGN;
+	
+	/* 
+	 * Initialize context (get pointers to registers and stuff), then
+	 * allocate the memory for the descriptor tables.
+	 */
+	
+	sbmac_initctx(sc);
+	
+	
+	/*
+	 * Display Ethernet address (this is called during the config process
+	 * so we need to finish off the config message that was being displayed)
+	 */
+	printk(KERN_INFO
+	       "%s: SB1250 Ethernet at 0x%08lX, address: %02X-%02X-%02X-%02X-%02X-%02X\n", 
+	       dev->name,
+	       (unsigned long) sc->sbm_base,
+	       eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]);
+	
+	/*
+	 * Set up Linux device callins
+	 */
+	
+	spin_lock_init(&sc->sbm_lock);
+	
+	ether_setup(dev);
+	dev->open               = sbmac_open;
+	dev->hard_start_xmit    = sbmac_start_tx;
+	dev->stop               = sbmac_close;
+	dev->get_stats          = sbmac_get_stats;
+	dev->set_multicast_list = sbmac_set_rx_mode;
+	dev->do_ioctl           = sbmac_mii_ioctl;
+	dev->tx_timeout         = sbmac_tx_timeout;
+	dev->watchdog_timeo     = TX_TIMEOUT;
+	
+	return 0;
+	
+}
+
+static int sbmac_open(struct net_device *dev)
+{
+	struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv;
+	
+	MOD_INC_USE_COUNT;
+
+	if (debug > 1) {
+		printk(KERN_DEBUG "%s: sbmac_open() irq %d.\n", dev->name, dev->irq);
+	}
+	
+	/* 
+	 * map/route interrupt 
+	 */
+	
+	if (request_irq(dev->irq, &sbmac_intr, SA_SHIRQ, dev->name, dev)) {
+		MOD_DEC_USE_COUNT;
+		return -EBUSY;
+	}
+	
+	/*
+	 * Configure default speed 
+	 */
+
+	sbmac_mii_poll(sc,1);
+	
+	/*
+	 * Turn on the channel
+	 */
+
+	sbmac_set_channel_state(sc,sbmac_state_on);
+	
+	/*
+	 * XXX Station address is in dev->dev_addr
+	 */
+	
+	if (dev->if_port == 0)
+		dev->if_port = 0; 
+	
+	netif_start_queue(dev);
+	
+	sbmac_set_rx_mode(dev);
+	
+	/* Set the timer to check for link beat. */
+	init_timer(&sc->sbm_timer);
+	sc->sbm_timer.expires = jiffies + 2;
+	sc->sbm_timer.data = (unsigned long)dev;
+	sc->sbm_timer.function = &sbmac_timer;
+	add_timer(&sc->sbm_timer);
+	
+	return 0;
+}
+
+static int sbmac_mii_poll(struct sbmac_softc *s,int noisy)
+{
+	int bmsr,bmcr,k1stsr,anlpar;
+	int chg;
+	char buffer[100];
+	char *p = buffer;
+
+	/* Read the mode status and mode control registers. */
+	bmsr = sbmac_mii_read(s,s->sbm_phys[0],MII_BMSR);
+	bmcr = sbmac_mii_read(s,s->sbm_phys[0],MII_BMCR);
+
+	/* get the link partner status */
+	anlpar = sbmac_mii_read(s,s->sbm_phys[0],MII_ANLPAR);
+
+	/* if supported, read the 1000baseT register */
+	if (bmsr & BMSR_1000BT_XSR) {
+		k1stsr = sbmac_mii_read(s,s->sbm_phys[0],MII_K1STSR);
+	} else {
+		k1stsr = 0;
+	}
+
+	chg = 0;
+
+	if ((bmsr & BMSR_LINKSTAT) == 0) {
+		/*
+		 * If link status is down, clear out old info so that when
+		 * it comes back up it will force us to reconfigure speed
+		 */
+		s->sbm_phy_oldbmsr = 0;
+		s->sbm_phy_oldanlpar = 0;
+		s->sbm_phy_oldk1stsr = 0;
+		return 0;
+	}
+
+	if ((s->sbm_phy_oldbmsr != bmsr) ||
+	    (s->sbm_phy_oldanlpar != anlpar) ||
+	    (s->sbm_phy_oldk1stsr != k1stsr)) {
+		if (debug > 1)
+			printk(KERN_DEBUG
+			       "%s: bmsr:%x/%x anlpar:%x/%x  k1stsr:%x/%x\n",
+			       s->sbm_dev->name,
+			       s->sbm_phy_oldbmsr,bmsr,
+			       s->sbm_phy_oldanlpar,anlpar,
+			       s->sbm_phy_oldk1stsr,k1stsr);
+		s->sbm_phy_oldbmsr = bmsr;
+		s->sbm_phy_oldanlpar = anlpar;
+		s->sbm_phy_oldk1stsr = k1stsr;
+		chg = 1;
+	}
+
+	if (chg == 0)
+		return 0;
+
+	p += sprintf(p,"Link speed: ");
+
+	if (k1stsr & K1STSR_LP1KFD) {
+		s->sbm_speed = sbmac_speed_1000;
+		s->sbm_duplex = sbmac_duplex_full;
+		s->sbm_fc = sbmac_fc_frame;
+		p += sprintf(p,"1000BaseT FDX");
+	} else if (k1stsr & K1STSR_LP1KHD) {
+		s->sbm_speed = sbmac_speed_1000;
+		s->sbm_duplex = sbmac_duplex_half;
+		s->sbm_fc = sbmac_fc_disabled;
+		p += sprintf(p,"1000BaseT HDX");
+	} else if (anlpar & ANLPAR_TXFD) {
+		s->sbm_speed = sbmac_speed_100;
+		s->sbm_duplex = sbmac_duplex_full;
+		s->sbm_fc = (anlpar & ANLPAR_PAUSE) ? sbmac_fc_frame
+		                                    : sbmac_fc_disabled;
+		p += sprintf(p,"100BaseT FDX");
+	} else if (anlpar & ANLPAR_TXHD) {
+		s->sbm_speed = sbmac_speed_100;
+		s->sbm_duplex = sbmac_duplex_half;
+		s->sbm_fc = sbmac_fc_disabled;
+		p += sprintf(p,"100BaseT HDX");
+	} else if (anlpar & ANLPAR_10FD) {
+		s->sbm_speed = sbmac_speed_10;
+		s->sbm_duplex = sbmac_duplex_full;
+		s->sbm_fc = sbmac_fc_frame;
+		p += sprintf(p,"10BaseT FDX");
+	} else if (anlpar & ANLPAR_10HD) {
+		s->sbm_speed = sbmac_speed_10;
+		s->sbm_duplex = sbmac_duplex_half;
+		s->sbm_fc = sbmac_fc_collision;
+		p += sprintf(p,"10BaseT HDX");
+	} else
+		p += sprintf(p,"Unknown");
+
+	if (noisy)
+		printk(KERN_INFO "%s: %s\n",s->sbm_dev->name,buffer);
+
+		return 1;
+}
+
+static void sbmac_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv;
+	int next_tick = HZ;
+	int mii_status;
+
+	spin_lock_irq (&sc->sbm_lock);
+	
+	/* make IFF_RUNNING follow the MII status bit "Link established" */
+	mii_status = sbmac_mii_read(sc, sc->sbm_phys[0], MII_BMSR);
+	
+	if ( (mii_status & BMSR_LINKSTAT) != (sc->sbm_phy_oldlinkstat) ) {
+    	        sc->sbm_phy_oldlinkstat = mii_status & BMSR_LINKSTAT;
+		if (mii_status & BMSR_LINKSTAT) {
+			netif_carrier_on(dev);
+		}
+		else {
+			netif_carrier_off(dev);	
+		}
+	}
+	
+	/*
+	 * Poll the PHY to see what speed we should be running at
+	 */
+
+	if (sbmac_mii_poll(sc,1)) {
+	    if (sc->sbm_state != sbmac_state_off) {
+		/*
+		 * something changed, restart the channel
+		 */
+		if (debug > 1) {
+		    printk("%s: restarting channel because speed changed\n",
+			   sc->sbm_dev->name);
+		    }
+		sbmac_channel_stop(sc);
+		sbmac_channel_start(sc);
+		}
+	    }
+	
+	spin_unlock_irq (&sc->sbm_lock);
+	
+	sc->sbm_timer.expires = jiffies + next_tick;
+	add_timer(&sc->sbm_timer);
+}
+
+static void sbmac_tx_timeout (struct net_device *dev)
+{
+	struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv;
+	
+	spin_lock_irq (&sc->sbm_lock);
+	
+	
+	dev->trans_start = jiffies;
+	sc->sbm_stats.tx_errors++;
+	
+	spin_unlock_irq (&sc->sbm_lock);
+
+	printk (KERN_WARNING "%s: Transmit timed out\n",dev->name);
+}
+
+static struct net_device_stats *sbmac_get_stats(struct net_device *dev)
+{
+	struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv;
+	unsigned long flags;
+	
+	spin_lock_irqsave(&sc->sbm_lock, flags);
+	
+	/* XXX update other stats here */
+	
+	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+	
+	return &sc->sbm_stats;
+}
+
+static void sbmac_set_rx_mode(struct net_device *dev)
+{
+	unsigned long flags;
+	int msg_flag = 0;
+	struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv;
+
+	spin_lock_irqsave(&sc->sbm_lock, flags);
+	if ((dev->flags ^ sc->sbm_devflags) & IFF_PROMISC) {
+		/*
+		 * Promiscuous changed.
+		 */
+		
+		if (dev->flags & IFF_PROMISC) {	
+			/* Unconditionally log net taps. */
+			msg_flag = 1;
+			sbmac_promiscuous_mode(sc,1);
+		}
+		else {
+			msg_flag = 2;
+			sbmac_promiscuous_mode(sc,0);
+		}
+	}
+	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+	
+	if (msg_flag) {
+		printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n", dev->name,(msg_flag==1)?"en":"dis");
+	}
+	
+	/*
+	 * Program the multicasts.  Do this every time.
+	 */
+	sbmac_setmulti(sc);
+	
+}
+
+static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv;
+	u16 *data = (u16 *)&rq->ifr_data;
+	unsigned long flags;
+	int retval;
+	
+	spin_lock_irqsave(&sc->sbm_lock, flags);
+	retval = 0;
+	
+	switch(cmd) {
+	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
+		data[0] = sc->sbm_phys[0] & 0x1f;
+		/* Fall Through */
+	case SIOCDEVPRIVATE+1:		/* Read the specified MII register. */
+		data[3] = sbmac_mii_read(sc, data[0] & 0x1f, data[1] & 0x1f);
+		break;
+	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
+		if (!capable(CAP_NET_ADMIN)) {
+			retval = -EPERM;
+			break;
+		}
+		if (debug > 1) {
+		    printk(KERN_DEBUG "%s: sbmac_mii_ioctl: write %02X %02X %02X\n",dev->name,
+		       data[0],data[1],data[2]);
+		    }
+		sbmac_mii_write(sc, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+		break;
+	default:
+		retval = -EOPNOTSUPP;
+	}
+	
+	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+	return retval;
+}
+
+static int sbmac_close(struct net_device *dev)
+{
+	struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv;
+	unsigned long flags;
+
+	sbmac_set_channel_state(sc,sbmac_state_off);
+
+	del_timer_sync(&sc->sbm_timer);
+
+	spin_lock_irqsave(&sc->sbm_lock, flags);
+
+	netif_stop_queue(dev);
+
+	if (debug > 1)
+		printk(KERN_DEBUG "%s: Shutting down ethercard\n",dev->name);
+
+	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+
+	/* Make sure there is no irq-handler running on a different CPU. */
+	synchronize_irq();
+
+	free_irq(dev->irq, dev);
+
+	sbdma_emptyring(&sc->sbm_txdma);
+	sbdma_emptyring(&sc->sbm_rxdma);
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR)
+static void
+sbmac_setup_hwaddr(int chan,char *addr)
+{
+	uint8_t eaddr[6];
+	uint64_t val;
+	sbmac_port_t port;
+
+	port = A_MAC_CHANNEL_BASE(chan);
+	sbmac_parse_hwaddr(addr,eaddr);
+	val = sbmac_addr2reg(eaddr);
+	SBMAC_WRITECSR(PKSEG1(port+R_MAC_ETHERNET_ADDR),val);
+	val = SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR));
+}
+#endif
+
+static struct net_device *dev_sbmac[MAX_UNITS] = {0,0,0};
+
+static int __init
+sbmac_init_module(void)
+{
+	int idx;
+	int macidx = 0;
+	struct net_device *dev;
+	sbmac_port_t port;
+	
+	/*
+	 * For bringup when not using the firmware, we can pre-fill
+	 * the MAC addresses using the environment variables
+	 * specified in this file (or maybe from the config file?)
+	 */
+#ifdef SBMAC_ETH0_HWADDR
+	sbmac_setup_hwaddr(0,SBMAC_ETH0_HWADDR);
+#endif
+#ifdef SBMAC_ETH1_HWADDR
+	sbmac_setup_hwaddr(1,SBMAC_ETH1_HWADDR);
+#endif
+#ifdef SBMAC_ETH2_HWADDR
+	sbmac_setup_hwaddr(2,SBMAC_ETH2_HWADDR);
+#endif
+
+	/*
+	 * Walk through the Ethernet controllers and find
+	 * those who have their MAC addresses set.
+	 */
+	
+	for (idx = 0; idx < MAX_UNITS; idx++) {
+
+	        /*
+	         * This is the base address of the MAC.
+		 */
+
+	        port = A_MAC_CHANNEL_BASE(idx);
+
+		/*	
+		 * The R_MAC_ETHERNET_ADDR register will be set to some nonzero
+		 * value for us by the firmware if we're going to use this MAC.
+		 * If we find a zero, skip this MAC.
+		 */
+
+		if (SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR)) == 0) {
+		    continue;
+		    }
+
+		/*
+		 * Okay, cool.  Initialize this MAC.
+		 */
+
+		dev = init_etherdev(NULL,sizeof(struct sbmac_softc));
+		if (!dev) break;			/* problems, get out now. */
+		dev->irq = K_INT_MAC_0 + idx;
+		dev->base_addr = port;
+		dev->mem_end = 0;
+		/*dev->init = sbmac_init;*/
+		sbmac_init(dev);
+
+		dev_sbmac[macidx] = dev;
+		macidx++;
+
+	}
+
+	/*
+	 * Should we care, 'macidx' is the total number of enabled MACs.
+	 */
+	
+	return 0;
+}
+
+
+static void __exit
+sbmac_cleanup_module(void)
+{
+	int idx;
+	struct net_device *dev;
+	for (idx = 0; idx < MAX_UNITS; idx++) {
+		dev = dev_sbmac[idx];
+		if (dev == NULL) continue;
+		if (dev->priv != NULL) {
+			struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv;
+			
+			unregister_netdev(dev);
+			
+			sbmac_uninitctx(sc);
+			
+			KFREE(sc);
+		}
+		KFREE(dev);
+		dev_sbmac[idx] = NULL;
+	}
+}
+
+module_init(sbmac_init_module);
+module_exit(sbmac_cleanup_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sgiseeq.c linux/drivers/net/sgiseeq.c
--- linux.orig/drivers/net/sgiseeq.c	2001-04-12 19:15:25.000000000 +0000
+++ linux/drivers/net/sgiseeq.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,10 +1,10 @@
-/* $Id: sgiseeq.c,v 1.17 2000/03/27 23:02:57 ralf Exp $
- *
+/*
  * sgiseeq.c: Seeq8003 ethernet driver for SGI machines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -451,20 +451,22 @@
 	unsigned long flags;
 	int err;
 
-	save_flags(flags); cli();
-	if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, (void *) dev)) {
+	__save_and_cli(flags);
+
+	err = -EAGAIN;
+	if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) {
 		printk("Seeq8003: Can't get irq %d\n", dev->irq);
-		restore_flags(flags);
-		return -EAGAIN;
+		goto out;
 	}
-
 	err = init_seeq(dev, sp, sregs);
 	if (err)
-		return err;
+		goto out;
 
 	netif_start_queue(dev);
-	restore_flags(flags);
-	return 0;
+
+out:
+	__restore_flags(flags);
+	return err;
 }
 
 static int sgiseeq_close(struct net_device *dev)
@@ -721,3 +723,5 @@
 			    (struct sgiseeq_regs *) (KSEG1ADDR(0x1fbd4000)),
 			    &hpc3c0->ethregs, SGI_ENET_IRQ);
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sis900.c linux/drivers/net/sis900.c
--- linux.orig/drivers/net/sis900.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/sis900.c	2002-07-20 01:08:34.000000000 +0000
@@ -1,6 +1,6 @@
 /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
    Copyright 1999 Silicon Integrated System Corporation 
-   Revision:	1.08.02	Nov. 30 2001
+   Revision:	1.08.04	Apr. 25 2002
    
    Modified from the driver which is originally written by Donald Becker.
    
@@ -18,6 +18,8 @@
    preliminary Rev. 1.0 Jan. 18, 1998
    http://www.sis.com.tw/support/databook.htm
 
+   Rev 1.08.04 Apr. 25 2002 Mufasa Yang <mufasa@sis.com.tw> added SiS962 support
+   Rev 1.08.03 Feb. 1 2002 Matt Domsch <Matt_Domsch@dell.com> update to use library crc32 function
    Rev 1.08.02 Nov. 30 2001 Hui-Fen Hsu workaround for EDB & bug fix for dhcp problem
    Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY
    Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix
@@ -60,6 +62,7 @@
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
+#include <linux/crc32.h>
 
 #include <asm/processor.h>      /* Processor type for cache alignment. */
 #include <asm/bitops.h>
@@ -69,7 +72,7 @@
 #include "sis900.h"
 
 #define SIS900_MODULE_NAME "sis900"
-#define SIS900_DRV_VERSION "v1.08.02 11/30/2001"
+#define SIS900_DRV_VERSION "v1.08.04 4/25/2002"
 
 static char version[] __devinitdata =
 KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
@@ -305,6 +308,40 @@
 	return 1;
 }
 
+/**
+ *	sis962_get_mac_addr: - Get MAC address for SiS962 model
+ *	@pci_dev: the sis900 pci device
+ *	@net_dev: the net device to get address for 
+ *
+ *	SiS962 model, use EEPROM to store MAC address. And EEPROM is shared by
+ *	LAN and 1394. When access EEPROM, send EEREQ signal to hardware first 
+ *	and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access 
+ *	by LAN, otherwise is not. After MAC address is read from EEPROM, send
+ *	EEDONE signal to refuse EEPROM access by LAN. 
+ *	MAC address is read into @net_dev->dev_addr.
+ */
+
+static int __devinit sis962_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
+{
+	long ioaddr = net_dev->base_addr;
+	long ee_addr = ioaddr + mear;
+	u32 waittime = 0;
+	int ret = 0;
+	
+	outl(EEREQ, ee_addr);
+	while(waittime < 2000) {
+		if(inl(ee_addr) & EEGNT) {
+			ret = sis900_get_mac_addr(pci_dev, net_dev);
+			outl(EEDONE, ee_addr);
+			return(ret);
+		} else {
+			udelay(1);	
+			waittime ++;
+		}
+	}
+	outl(EEDONE, ee_addr);
+	return 0;
+}
 
 /**
  *	sis900_probe: - Probe for sis900 device
@@ -406,6 +443,8 @@
 		ret = sis630e_get_mac_addr(pci_dev, net_dev);
 	else if ((revision > 0x81) && (revision <= 0x90) )
 		ret = sis635_get_mac_addr(pci_dev, net_dev);
+	else if (revision == SIS962_900_REV)
+		ret = sis962_get_mac_addr(pci_dev, net_dev);
 	else
 		ret = sis900_get_mac_addr(pci_dev, net_dev);
 
@@ -654,7 +693,7 @@
  *	Note that location is in word (16 bits) unit
  */
 
-static u16 read_eeprom(long ioaddr, int location)
+static u16 __devinit read_eeprom(long ioaddr, int location)
 {
 	int i;
 	u16 retval = 0;
@@ -1981,29 +2020,10 @@
 static u16 sis900_compute_hashtable_index(u8 *addr, u8 revision)
 {
 
-/* what is the correct value of the POLYNOMIAL ??
-   Donald Becker use 0x04C11DB7U
-   Joseph Zbiciak im14u2c@primenet.com gives me the
-   correct answer, thank you Joe !! */
-#define POLYNOMIAL 0x04C11DB7L
-	u32 crc = 0xffffffff, msb;
-	int  i, j;
-	u32  byte;
-
-	for (i = 0; i < 6; i++) {
-		byte = *addr++;
-		for (j = 0; j < 8; j++) {
-			msb = crc >> 31;
-			crc <<= 1;
-			if (msb ^ (byte & 1)) {
-				crc ^= POLYNOMIAL;
-			}
-			byte >>= 1;
-		}
-	}
+	u32 crc = ether_crc(6, addr);
 
 	/* leave 8 or 7 most siginifant bits */
-	if ((revision == SIS635A_900_REV) || (revision == SIS900B_900_REV))
+	if ((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
 		return ((int)(crc >> 24));
 	else
 		return ((int)(crc >> 25));
@@ -2029,7 +2049,7 @@
 
 	/* 635 Hash Table entires = 256(2^16) */
 	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
-	if((revision == SIS635A_900_REV) || (revision == SIS900B_900_REV))
+	if((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
 		table_entries = 16;
 	else
 		table_entries = 8;
@@ -2110,7 +2130,7 @@
 	}
 
 	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
-	if( (revision == SIS635A_900_REV) || (revision == SIS900B_900_REV) )
+	if( (revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV) )
 		outl(PESEL | RND_CNT, ioaddr + cfg);
 	else
 		outl(PESEL, ioaddr + cfg);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sis900.h linux/drivers/net/sis900.h
--- linux.orig/drivers/net/sis900.h	2001-10-09 22:13:03.000000000 +0000
+++ linux/drivers/net/sis900.h	2002-07-20 01:08:26.000000000 +0000
@@ -135,6 +135,11 @@
 	EEaddrMask = 0x013F, EEcmdShift = 16
 };
 
+/* For SiS962, request the eeprom software access */
+enum sis962_eeprom_command {
+	EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100
+};
+
 /* Manamgement Data I/O (mdio) frame */
 #define MIIread         0x6000
 #define MIIwrite        0x5002
@@ -240,7 +245,7 @@
 	SIS630A_900_REV = 0x80,		SIS630E_900_REV = 0x81,
 	SIS630S_900_REV = 0x82,		SIS630EA1_900_REV = 0x83,
 	SIS630ET_900_REV = 0x84,	SIS635A_900_REV = 0x90,
-	SIS900B_900_REV = 0x03
+	SIS962_900_REV = 0X91,		SIS900B_900_REV = 0x03
 };
 
 enum sis630_revision_id {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sk98lin/h/skdrv1st.h linux/drivers/net/sk98lin/h/skdrv1st.h
--- linux.orig/drivers/net/sk98lin/h/skdrv1st.h	2001-09-09 17:45:43.000000000 +0000
+++ linux/drivers/net/sk98lin/h/skdrv1st.h	2002-07-20 01:08:22.000000000 +0000
@@ -116,6 +116,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/crc32.h>
 #include <asm/byteorder.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sk98lin/skaddr.c linux/drivers/net/sk98lin/skaddr.c
--- linux.orig/drivers/net/sk98lin/skaddr.c	2001-07-04 18:50:39.000000000 +0000
+++ linux/drivers/net/sk98lin/skaddr.c	2002-07-20 01:08:23.000000000 +0000
@@ -199,7 +199,6 @@
 /* defines ********************************************************************/
 
 
-#define CRC32_POLY	0xEDB88320UL	/* CRC32-Poly - XMAC: Little Endian */
 #define HASH_BITS	6				/* #bits in hash */
 #define	SK_MC_BIT	0x01
 
@@ -534,18 +533,9 @@
 unsigned SkCrc32McHash(
 unsigned char *pMc)	/* Multicast address */
 {
-	unsigned Idx;
-	unsigned Bit;
-	unsigned Data;
-	unsigned Crc;
-
-	Crc = 0xFFFFFFFFUL;
-	for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
-		Data = *pMc++;
-		for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
-			Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? CRC32_POLY : 0);
-		}
-	}
+	u32 Crc;
+
+	Crc = ether_crc_le(SK_MAC_ADDR_LEN, pMc);
 
 	return (Crc & ((1 << HASH_BITS) - 1));
 }	/* SkCrc32McHash */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- linux.orig/drivers/net/sk98lin/skge.c	2001-10-12 22:35:53.000000000 +0000
+++ linux/drivers/net/sk98lin/skge.c	2002-07-20 01:08:26.000000000 +0000
@@ -541,6 +541,48 @@
 
 		boards_found++;
 
+		/* More then one port found */
+		if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+			if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) {
+				printk(KERN_ERR "Unable to allocate etherdev "
+					"structure!\n");
+				break;
+			}
+
+			pAC->dev[1] = dev;
+			pNet = dev->priv;
+			pNet->PortNr = 1;
+			pNet->NetNr = 1;
+			pNet->pAC = pAC;
+			pNet->Mtu = 1500;
+			pNet->Up = 0;
+
+			dev->open =		&SkGeOpen;
+			dev->stop =		&SkGeClose;
+			dev->hard_start_xmit =	&SkGeXmit;
+			dev->get_stats =	&SkGeStats;
+			dev->set_multicast_list = &SkGeSetRxMode;
+			dev->set_mac_address =	&SkGeSetMacAddr;
+			dev->do_ioctl =		&SkGeIoctl;
+			dev->change_mtu =	&SkGeChangeMtu;
+
+			pProcFile = create_proc_entry(dev->name, 
+				S_IFREG | 0444, pSkRootDir);
+			pProcFile->read_proc = proc_read;
+			pProcFile->write_proc = NULL;
+			pProcFile->nlink = 1;
+			pProcFile->size = sizeof(dev->name+1);
+			pProcFile->data = (void*)pProcFile;
+
+			memcpy((caddr_t) &dev->dev_addr,
+			(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
+	
+			printk("%s: %s\n", dev->name, pAC->DeviceStr);
+			printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
+		
+		}
+
+
 		/*
 		 * This is bollocks, but we need to tell the net-init
 		 * code that it shall go for the next device.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/skfp/h/fplustm.h linux/drivers/net/skfp/h/fplustm.h
--- linux.orig/drivers/net/skfp/h/fplustm.h	2000-05-12 18:43:26.000000000 +0000
+++ linux/drivers/net/skfp/h/fplustm.h	2002-07-20 01:08:24.000000000 +0000
@@ -50,38 +50,82 @@
 	u_long err_tkerr ;		/* token error */
 } ;
 
+#define SK_XD_ALIGN     (size_t) 32
+
 /*
  *	Transmit Descriptor struct
  */
+struct s_dummy_txd {
+        u_int txd_tbctrl ;              /* transmit buffer control */
+        u_int txd_txdscr ;              /* transmit frame status word */
+        u_int txd_tbadr ;               /* physical tx buffer address */
+        u_int txd_ntdadr ;              /* physical pointer to the next TxD */
+#ifdef  ENA_64BIT_SUP
+        u_int txd_tbadr_hi ;            /* physical tx buffer addr(high dword)*/
+#endif 
+        caddr_t txd_virt ;              /* virtual pointer to the data frag */
+                                        /* virt pointer to the next TxD */
+        struct s_smt_fp_txd volatile far *txd_next ;
+        struct s_txd_os txd_os ;        /* OS - specific struct */ 
+	/* No padding here! */
+} ;
+
+#define SK_DUMMY_TXD	sizeof(struct s_dummy_txd)
+#define SK_TXD_PAD	(((SK_DUMMY_TXD+SK_XD_ALIGN-1) \
+				& ~(SK_XD_ALIGN-1))-SK_DUMMY_TXD)
 struct s_smt_fp_txd {
 	u_int txd_tbctrl ;		/* transmit buffer control */
 	u_int txd_txdscr ;		/* transmit frame status word */
 	u_int txd_tbadr ;		/* physical tx buffer address */
 	u_int txd_ntdadr ;		/* physical pointer to the next TxD */
 #ifdef	ENA_64BIT_SUP
-	u_int txd_tbadr_hi ;		/* physical tx buffer addr (high dword)*/
+	u_int txd_tbadr_hi ;		/* physical tx buffer addr(high dword)*/
 #endif
-	char far *txd_virt ;		/* virtual pointer to the data frag */
+	caddr_t txd_virt ;		/* virtual pointer to the data frag */
 					/* virt pointer to the next TxD */
 	struct s_smt_fp_txd volatile far *txd_next ;
 	struct s_txd_os txd_os ;	/* OS - specific struct */
+	char padding[SK_TXD_PAD];	/* padding */
 } ;
 
+
+
 /*
  *	Receive Descriptor struct
  */
+
+struct s_dummy_rxd {
+        u_int rxd_rbctrl ;              /* receive buffer control */
+        u_int rxd_rfsw ;                /* receive frame status word */
+        u_int rxd_rbadr ;               /* physical rx buffer address */
+        u_int rxd_nrdadr ;              /* physical pointer to the next RxD */
+#ifdef  ENA_64BIT_SUP
+        u_int rxd_rbadr_hi ;            /* physical tx buffer addr(high dword)*/
+#endif
+        caddr_t rxd_virt ;              /* virtual pointer to the data frag */
+                                        /* virt pointer to the next RxD */
+        struct s_smt_fp_rxd volatile far *rxd_next ;
+        struct s_rxd_os rxd_os ;        /* OS - specific struct */
+        /* No padding here! */
+} ;
+
+#define SK_DUMMY_RXD	sizeof(struct s_dummy_rxd)
+#define SK_RXD_PAD	(((SK_DUMMY_RXD+SK_XD_ALIGN-1) \
+				& ~(SK_XD_ALIGN-1))-SK_DUMMY_RXD)
+
 struct s_smt_fp_rxd {
 	u_int rxd_rbctrl ;		/* receive buffer control */
 	u_int rxd_rfsw ;		/* receive frame status word */
 	u_int rxd_rbadr ;		/* physical rx buffer address */
 	u_int rxd_nrdadr ;		/* physical pointer to the next RxD */
 #ifdef	ENA_64BIT_SUP
-	u_int rxd_rbadr_hi ;		/* physical tx buffer addr (high dword)*/
+	u_int rxd_rbadr_hi ;		/* physical tx buffer addr(high dword)*/
 #endif
-	char far *rxd_virt ;		/* virtual pointer to the data frag */
+	caddr_t rxd_virt ;		/* virtual pointer to the data frag */
 					/* virt pointer to the next RxD */
 	struct s_smt_fp_rxd volatile far *rxd_next ;
 	struct s_rxd_os rxd_os ;	/* OS - specific struct */
+	char padding[SK_RXD_PAD] ;
 } ;
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/skfp/h/smt.h linux/drivers/net/skfp/h/smt.h
--- linux.orig/drivers/net/skfp/h/smt.h	2000-05-12 18:43:26.000000000 +0000
+++ linux/drivers/net/skfp/h/smt.h	2002-07-20 01:08:39.000000000 +0000
@@ -543,7 +543,7 @@
 
 struct smt_p_001d {
 	struct smt_para	para ;		/* generic parameter header */
-	u_int		allocatable ;	/* total sync bw availabel for alloc */
+	u_int		allocatable ;	/* total sync bw available for alloc */
 } ;
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/skfp/skfddi.c linux/drivers/net/skfp/skfddi.c
--- linux.orig/drivers/net/skfp/skfddi.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/skfp/skfddi.c	2002-07-20 01:08:24.000000000 +0000
@@ -56,6 +56,7 @@
  *		12-Nov-99	CG	Source code release
  *		22-Nov-99	CG	Included in kernel source.
  *		07-May-00	DM	64 bit fixes, new dma interface
+ *		06-May-02	ML	Structure fixes
  *
  * Compilation options (-Dxxx):
  *              DRIVERDEBUG     print lots of messages to log file
@@ -68,7 +69,7 @@
 
 /* Version information string - should be updated prior to */
 /* each new release!!! */
-#define VERSION		"2.06"
+#define VERSION		"2.07"
 
 static const char *boot_msg = 
 	"SysKonnect FDDI PCI Adapter driver v" VERSION " for\n"
@@ -188,6 +189,7 @@
 };
 MODULE_DEVICE_TABLE(pci, skfddi_pci_tbl);
 MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
 
 // Define module-wide (static) variables
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- linux.orig/drivers/net/smc-ultra.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/smc-ultra.c	2002-07-20 01:08:26.000000000 +0000
@@ -501,8 +501,10 @@
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
-MODULE_PARM_DESC(io, "SMC Ultra I/O base address(es)");
-MODULE_PARM_DESC(irq, "SMC Ultra IRQ number(s) (assigned)");
+MODULE_PARM_DESC(io, "I/O base address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
+MODULE_DESCRIPTION("SMC Ultra/EtherEZ ISA/PnP Ethernet driver");
+MODULE_LICENSE("GPL");
 
 EXPORT_NO_SYMBOLS;
 
@@ -557,7 +559,6 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/smc-ultra32.c linux/drivers/net/smc-ultra32.c
--- linux.orig/drivers/net/smc-ultra32.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/smc-ultra32.c	2002-07-20 01:08:31.000000000 +0000
@@ -379,6 +379,9 @@
 #define MAX_ULTRA32_CARDS   4	/* Max number of Ultra cards per module */
 static struct net_device dev_ultra[MAX_ULTRA32_CARDS];
 
+MODULE_DESCRIPTION("SMC Ultra32 EISA ethernet driver");
+MODULE_LICENSE("GPL");
+
 int init_module(void)
 {
 	int this_dev, found = 0;
@@ -415,5 +418,4 @@
 	}
 }
 #endif /* MODULE */
-MODULE_LICENSE("GPL");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/smc9194.c linux/drivers/net/smc9194.c
--- linux.orig/drivers/net/smc9194.c	2001-10-17 04:56:29.000000000 +0000
+++ linux/drivers/net/smc9194.c	2002-07-20 01:08:39.000000000 +0000
@@ -51,6 +51,7 @@
  .				 allocation
  .      08/20/00  Arnaldo Melo   fix kfree(skb) in smc_hardware_send_packet
  .      12/15/00  Christian Jullien fix "Warning: kfree_skb on hard IRQ"
+ .      11/08/01 Matt Domsch     Use common crc32 function
  ----------------------------------------------------------------------------*/
 
 static const char version[] =
@@ -69,6 +70,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <linux/errno.h>
@@ -223,10 +225,6 @@
 */
 static void smc_set_multicast_list(struct net_device *dev);
 
-/*
- . CRC compute
- */
-static int crc32( char * s, int length );
 
 /*---------------------------------------------------------------
  .
@@ -436,7 +434,7 @@
 			continue;
 
 		/* only use the low order bits */
-		position = crc32( cur_addr->dmi_addr, 6 ) & 0x3f;
+		position = ether_crc_le(6, cur_addr->dmi_addr) & 0x3f;
 
 		/* do some messy swapping to put the bit in the right spot */
 		multicast_table[invert3[position&7]] |=
@@ -452,33 +450,6 @@
 }
 
 /*
-  Finds the CRC32 of a set of bytes.
-  Again, from Peter Cammaert's code.
-*/
-static int crc32( char * s, int length ) {
-	/* indices */
-	int perByte;
-	int perBit;
-	/* crc polynomial for Ethernet */
-	const unsigned long poly = 0xedb88320;
-	/* crc value - preinitialized to all 1's */
-	unsigned long crc_value = 0xffffffff;
-
-	for ( perByte = 0; perByte < length; perByte ++ ) {
-		unsigned char	c;
-
-		c = *(s++);
-		for ( perBit = 0; perBit < 8; perBit++ ) {
-			crc_value = (crc_value>>1)^
-				(((crc_value^c)&0x01)?poly:0);
-			c >>= 1;
-		}
-	}
-	return	crc_value;
-}
-
-
-/*
  . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * )
  . Purpose:
  .    Attempt to allocate memory for a packet, if chip-memory is not
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sonic.c linux/drivers/net/sonic.c
--- linux.orig/drivers/net/sonic.c	2001-10-11 06:23:24.000000000 +0000
+++ linux/drivers/net/sonic.c	2002-07-20 01:08:40.000000000 +0000
@@ -620,3 +620,5 @@
 
 	return 0;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sonic.h linux/drivers/net/sonic.h
--- linux.orig/drivers/net/sonic.h	2001-10-11 06:23:24.000000000 +0000
+++ linux/drivers/net/sonic.h	2002-07-20 01:08:22.000000000 +0000
@@ -87,6 +87,7 @@
 #define SONIC_FAET              0x2d
 #define SONIC_MPT               0x2e
 
+#define SONIC_DCR2              0x3f
 
 /*
  * SONIC command bits
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/starfire.c linux/drivers/net/starfire.c
--- linux.orig/drivers/net/starfire.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/starfire.c	2002-07-20 01:08:29.000000000 +0000
@@ -96,13 +96,19 @@
 	LK1.3.5 (jgarzik)
 	- ethtool NWAY_RST, GLINK, [GS]MSGLVL support
 
+	LK1.3.6:
+	- Sparc64 support and fixes (Ion Badulescu)
+	- Better stats and error handling (Ion Badulescu)
+	- Use new pci_set_mwi() PCI API function (jgarzik)
+
 TODO:
 	- implement tx_timeout() properly
+	- VLAN support
 */
 
 #define DRV_NAME	"starfire"
-#define DRV_VERSION	"1.03+LK1.3.5"
-#define DRV_RELDATE	"November 17, 2001"
+#define DRV_VERSION	"1.03+LK1.3.6"
+#define DRV_RELDATE	"March 7, 2002"
 
 #include <linux/version.h>
 #include <linux/module.h>
@@ -112,6 +118,7 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/crc32.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -121,14 +128,14 @@
  * firmware files) does not allow one to redistribute them. Thus, we can't
  * include the firmware with this driver.
  *
- * However, an end-user is allowed to download and use it, after
- * converting it to C header files using starfire_firmware.pl.
+ * However, should a legal-to-use firmware become available,
+ * the driver developer would need only to obtain the firmware in the
+ * form of a C header file.
  * Once that's done, the #undef below must be changed into a #define
  * for this driver to really use the firmware. Note that Rx/Tx
  * hardware TCP checksumming is not possible without the firmware.
  *
- * I'm currently [Feb 2001] talking to Adaptec about this redistribution
- * issue. Stay tuned...
+ * WANTED: legal firmware to include with this GPL'd driver.
  */
 #undef HAS_FIRMWARE
 /*
@@ -608,7 +615,10 @@
 	long ioaddr;
 	int drv_flags, io_size;
 	int boguscnt;
+#ifndef HAVE_PCI_SET_MWI
+	u16 cmd;
 	u8 cache;
+#endif
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -643,14 +653,25 @@
 		goto err_out_free_netdev;
 	}
 
-	ioaddr = (long) ioremap (ioaddr, io_size);
+	/* ioremap is borken in Linux-2.2.x/sparc64 */
+#if !defined(CONFIG_SPARC64) || LINUX_VERSION_CODE > 0x20300
+	ioaddr = (long) ioremap(ioaddr, io_size);
 	if (!ioaddr) {
 		printk (KERN_ERR DRV_NAME " %d: cannot remap 0x%x @ 0x%lx, aborting\n",
 			card_idx, io_size, ioaddr);
 		goto err_out_free_res;
 	}
+#endif /* !CONFIG_SPARC64 || Linux 2.3.0+ */
 
-	pci_set_master (pdev);
+	pci_set_master(pdev);
+
+#ifdef HAVE_PCI_SET_MWI
+	pci_set_mwi(pdev);
+#else
+	/* enable MWI -- it vastly improves Rx performance on sparc64 */
+	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_INVALIDATE;
+	pci_write_config_word(pdev, PCI_COMMAND, cmd);
 
 	/* set PCI cache size */
 	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
@@ -661,6 +682,7 @@
 		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
 				      SMP_CACHE_BYTES >> 2);
 	}
+#endif
 
 #ifdef ZEROCOPY
 	/* Starfire can do SG and TCP/UDP checksumming */
@@ -669,7 +691,7 @@
 
 	/* Serial EEPROM reads are hidden by the hardware. */
 	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i);
+		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20 - i);
 
 #if ! defined(final_version) /* Dump the EEPROM contents during development. */
 	if (debug > 4)
@@ -931,7 +953,7 @@
 
 	/* Fill both the unused Tx SA register and the Rx perfect filter. */
 	for (i = 0; i < 6; i++)
-		writeb(dev->dev_addr[i], ioaddr + StationAddr + 5-i);
+		writeb(dev->dev_addr[i], ioaddr + StationAddr + 5 - i);
 	for (i = 0; i < 16; i++) {
 		u16 *eaddrs = (u16 *)dev->dev_addr;
 		long setup_frm = ioaddr + PerfFilterTable + i * 16;
@@ -978,9 +1000,9 @@
 #ifdef HAS_FIRMWARE
 	/* Load Rx/Tx firmware into the frame processors */
 	for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
-		writel(cpu_to_le32(firmware_rx[i]), ioaddr + RxGfpMem + i * 4);
+		writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
 	for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
-		writel(cpu_to_le32(firmware_tx[i]), ioaddr + TxGfpMem + i * 4);
+		writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
 	/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
 	writel(0x003F, ioaddr + GenCtrl);
 #else  /* not HAS_FIRMWARE */
@@ -1155,8 +1177,8 @@
 
 	np->tx_ring[entry].first_addr = cpu_to_le32(np->tx_info[entry].first_mapping);
 #ifdef ZEROCOPY
-	np->tx_ring[entry].first_len = cpu_to_le32(skb_first_frag_len(skb));
-	np->tx_ring[entry].total_len = cpu_to_le32(skb->len);
+	np->tx_ring[entry].first_len = cpu_to_le16(skb_first_frag_len(skb));
+	np->tx_ring[entry].total_len = cpu_to_le16(skb->len);
 	/* Add "| TxDescIntr" to generate Tx-done interrupts. */
 	np->tx_ring[entry].status = cpu_to_le32(TxDescID | TxCRCEn);
 	np->tx_ring[entry].nbufs = cpu_to_le32(skb_shinfo(skb)->nr_frags + 1);
@@ -1169,8 +1191,10 @@
 		np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr);
 
 #ifdef ZEROCOPY
-	if (skb->ip_summed == CHECKSUM_HW)
+	if (skb->ip_summed == CHECKSUM_HW) {
 		np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP);
+		np->stats.tx_compressed++;
+	}
 #endif /* ZEROCOPY */
 
 	if (debug > 5) {
@@ -1448,6 +1472,7 @@
 #if defined(full_rx_status) || defined(csum_rx_status)
 		if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
+			np->stats.rx_compressed++;
 		}
 		/*
 		 * This feature doesn't seem to be working, at least
@@ -1579,12 +1604,17 @@
 		printk(KERN_NOTICE "%s: Increasing Tx FIFO threshold to %d bytes\n",
 		       dev->name, np->tx_threshold * 16);
 	}
-	if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrPCIPad)) && debug)
+	if (intr_status & IntrRxGFPDead) {
+		np->stats.rx_fifo_errors++;
+		np->stats.rx_errors++;
+	}
+	if (intr_status & (IntrNoTxCsum | IntrDMAErr)) {
+		np->stats.tx_fifo_errors++;
+		np->stats.tx_errors++;
+	}
+	if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrRxGFPDead | IntrNoTxCsum | IntrPCIPad)) && debug)
 		printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
 		       dev->name, intr_status);
-	/* Hmmmmm, it's not clear how to recover from DMA faults. */
-	if (intr_status & IntrDMAErr)
-		np->stats.tx_fifo_errors++;
 }
 
 
@@ -1615,32 +1645,9 @@
 }
 
 
-/* The little-endian AUTODIN II ethernet CRC calculations.
-   A big-endian version is also available.
-   This is slow but compact code.  Do not use this routine for bulk data,
-   use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c.
-   Chips may use the upper or lower CRC bits, and may reverse and/or invert
+/* Chips may use the upper or lower CRC bits, and may reverse and/or invert
    them.  Select the endian-ness that results in minimal calculations.
 */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-	unsigned int crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-
 
 static void set_rx_mode(struct net_device *dev)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/starfire_firmware.pl linux/drivers/net/starfire_firmware.pl
--- linux.orig/drivers/net/starfire_firmware.pl	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/net/starfire_firmware.pl	1970-01-01 00:00:00.000000000 +0000
@@ -1,31 +0,0 @@
-#!/usr/bin/perl
-
-# This script can be used to generate a new starfire_firmware.h
-# from GFP_RX.DAT and GFP_TX.DAT, files included with the DDK
-# and also with the Novell drivers.
-
-open FW, "GFP_RX.DAT" || die;
-open FWH, ">starfire_firmware.h" || die;
-
-printf(FWH "static u32 firmware_rx[] = {\n");
-$counter = 0;
-while ($foo = <FW>) {
-  chomp;
-  printf(FWH "  0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4));
-  $counter++;
-}
-
-close FW;
-open FW, "GFP_TX.DAT" || die;
-
-printf(FWH "};\t/* %d Rx instructions */\n#define FIRMWARE_RX_SIZE %d\n\nstatic u32 firmware_tx[] = {\n", $counter, $counter);
-$counter = 0;
-while ($foo = <FW>) {
-  chomp;
-  printf(FWH "  0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4));
-  $counter++;
-}
-
-close FW;
-printf(FWH "};\t/* %d Tx instructions */\n#define FIRMWARE_TX_SIZE %d\n", $counter, $counter);
-close(FWH);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sun3_82586.c linux/drivers/net/sun3_82586.c
--- linux.orig/drivers/net/sun3_82586.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/sun3_82586.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,1206 @@
+/*
+ * Sun3 i82586 Ethernet driver
+ *
+ * Cloned from ni52.c for the Sun3 by Sam Creasey (sammy@sammy.net)
+ *
+ * Original copyright follows:
+ * --------------------------
+ *
+ * net-3-driver for the NI5210 card (i82586 Ethernet chip)
+ *
+ * This is an extension to the Linux operating system, and is covered by the
+ * same Gnu Public License that covers that work.
+ *
+ * Alphacode 0.82 (96/09/29) for Linux 2.0.0 (or later)
+ * Copyrights (c) 1994,1995,1996 by M.Hipp (hippm@informatik.uni-tuebingen.de)
+ * --------------------------
+ * 
+ * Consult ni52.c for further notes from the original driver.
+ *
+ * This incarnation currently supports the OBIO version of the i82586 chip 
+ * used in certain sun3 models.  It should be fairly doable to expand this
+ * to support VME if I should every acquire such a board.
+ *
+ */
+
+static int debuglevel = 0; /* debug-printk 0: off 1: a few 2: more */
+static int automatic_resume = 0; /* experimental .. better should be zero */
+static int rfdadd = 0; /* rfdadd=1 may be better for 8K MEM cards */
+static int fifo=0x8;	/* don't change */
+
+/* #define REALLY_SLOW_IO */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/idprom.h>
+#include <asm/machines.h>
+#include <asm/sun3mmu.h>
+#include <asm/dvma.h>
+#include <asm/byteorder.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include "sun3_82586.h"
+
+#define DEBUG       /* debug on */
+#define SYSBUSVAL 0 /* 16 Bit */
+
+#define sun3_attn586()  {*(volatile unsigned char *)(dev->base_addr) |= IEOB_ATTEN; *(volatile unsigned char *)(dev->base_addr) &= ~IEOB_ATTEN;}
+#define sun3_reset586() {*(volatile unsigned char *)(dev->base_addr) = 0; udelay(100); *(volatile unsigned char *)(dev->base_addr) = IEOB_NORSET;}
+#define sun3_disint()   {*(volatile unsigned char *)(dev->base_addr) &= ~IEOB_IENAB;}
+#define sun3_enaint()   {*(volatile unsigned char *)(dev->base_addr) |= IEOB_IENAB;}
+#define sun3_active()   {*(volatile unsigned char *)(dev->base_addr) |= (IEOB_IENAB|IEOB_ONAIR|IEOB_NORSET);}
+
+#define make32(ptr16) (p->memtop + (swab16((unsigned short) (ptr16))) )
+#define make24(ptr32) (char *)swab32(( ((unsigned long) (ptr32)) - p->base))
+#define make16(ptr32) (swab16((unsigned short) ((unsigned long)(ptr32) - (unsigned long) p->memtop )))
+
+/******************* how to calculate the buffers *****************************
+
+  * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
+  * --------------- in a different (more stable?) mode. Only in this mode it's
+  *                 possible to configure the driver with 'NO_NOPCOMMANDS'
+
+sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
+sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
+sizeof(rfd) = 24; sizeof(rbd) = 12;
+sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
+sizeof(nop_cmd) = 8;
+
+  * if you don't know the driver, better do not change these values: */
+
+#define RECV_BUFF_SIZE 1536 /* slightly oversized */
+#define XMIT_BUFF_SIZE 1536 /* slightly oversized */
+#define NUM_XMIT_BUFFS 1    /* config for 32K shmem */
+#define NUM_RECV_BUFFS_8 4 /* config for 32K shared mem */
+#define NUM_RECV_BUFFS_16 9 /* config for 32K shared mem */
+#define NUM_RECV_BUFFS_32 16 /* config for 32K shared mem */
+#define NO_NOPCOMMANDS      /* only possible with NUM_XMIT_BUFFS=1 */
+
+/**************************************************************************/
+
+/* different DELAYs */
+#define DELAY(x) mdelay(32 * x);
+#define DELAY_16(); { udelay(16); }
+#define DELAY_18(); { udelay(4); }
+
+/* wait for command with timeout: */
+#define WAIT_4_SCB_CMD() \
+{ int i; \
+  for(i=0;i<16384;i++) { \
+    if(!p->scb->cmd_cuc) break; \
+    DELAY_18(); \
+    if(i == 16383) { \
+      printk("%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_cuc,p->scb->cus); \
+       if(!p->reseted) { p->reseted = 1; sun3_reset586(); } } } }
+
+#define WAIT_4_SCB_CMD_RUC() { int i; \
+  for(i=0;i<16384;i++) { \
+    if(!p->scb->cmd_ruc) break; \
+    DELAY_18(); \
+    if(i == 16383) { \
+      printk("%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_ruc,p->scb->rus); \
+       if(!p->reseted) { p->reseted = 1; sun3_reset586(); } } } }
+
+#define WAIT_4_STAT_COMPL(addr) { int i; \
+   for(i=0;i<32767;i++) { \
+     if(swab16((addr)->cmd_status) & STAT_COMPL) break; \
+     DELAY_16(); DELAY_16(); } }
+
+static int     sun3_82586_probe1(struct net_device *dev,int ioaddr);
+static void    sun3_82586_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr);
+static int     sun3_82586_open(struct net_device *dev);
+static int     sun3_82586_close(struct net_device *dev);
+static int     sun3_82586_send_packet(struct sk_buff *,struct net_device *);
+static struct  net_device_stats *sun3_82586_get_stats(struct net_device *dev);
+static void    set_multicast_list(struct net_device *dev);
+static void    sun3_82586_timeout(struct net_device *dev);
+#if 0
+static void    sun3_82586_dump(struct net_device *,void *);
+#endif
+
+/* helper-functions */
+static int     init586(struct net_device *dev);
+static int     check586(struct net_device *dev,char *where,unsigned size);
+static void    alloc586(struct net_device *dev);
+static void    startrecv586(struct net_device *dev);
+static void   *alloc_rfa(struct net_device *dev,void *ptr);
+static void    sun3_82586_rcv_int(struct net_device *dev);
+static void    sun3_82586_xmt_int(struct net_device *dev);
+static void    sun3_82586_rnr_int(struct net_device *dev);
+
+struct priv
+{
+	struct net_device_stats stats;
+	unsigned long base;
+	char *memtop;
+	long int lock;
+	int reseted;
+	volatile struct rfd_struct	*rfd_last,*rfd_top,*rfd_first;
+	volatile struct scp_struct	*scp;	/* volatile is important */
+	volatile struct iscp_struct	*iscp;	/* volatile is important */
+	volatile struct scb_struct	*scb;	/* volatile is important */
+	volatile struct tbd_struct	*xmit_buffs[NUM_XMIT_BUFFS];
+	volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
+#if (NUM_XMIT_BUFFS == 1)
+	volatile struct nop_cmd_struct *nop_cmds[2];
+#else
+	volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
+#endif
+	volatile int		nop_point,num_recv_buffs;
+	volatile char		*xmit_cbuffs[NUM_XMIT_BUFFS];
+	volatile int		xmit_count,xmit_last;
+};
+
+/**********************************************
+ * close device
+ */
+static int sun3_82586_close(struct net_device *dev)
+{
+	free_irq(dev->irq, dev);
+
+	sun3_reset586(); /* the hard way to stop the receiver */
+
+	netif_stop_queue(dev);
+
+	return 0;
+}
+
+/**********************************************
+ * open device
+ */
+static int sun3_82586_open(struct net_device *dev)
+{
+	int ret;
+
+	sun3_disint();
+	alloc586(dev);
+	init586(dev);
+	startrecv586(dev);
+	sun3_enaint();
+
+	ret = request_irq(dev->irq, &sun3_82586_interrupt,0,dev->name,dev);
+	if (ret)
+	{
+		sun3_reset586();
+		return ret;
+	}
+
+	netif_start_queue(dev);
+
+	return 0; /* most done by init */
+}
+
+/**********************************************
+ * Check to see if there's an 82586 out there.
+ */
+static int check586(struct net_device *dev,char *where,unsigned size)
+{
+	struct priv pb;
+	struct priv *p = /* (struct priv *) dev->priv*/ &pb;
+	char *iscp_addr;
+	int i;
+
+	p->base = (unsigned long) dvma_btov(0);
+	p->memtop = (char *)dvma_btov((unsigned long)where);
+	p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
+	memset((char *)p->scp,0, sizeof(struct scp_struct));
+	for(i=0;i<sizeof(struct scp_struct);i++) /* memory was writeable? */
+		if(((char *)p->scp)[i])
+			return 0;
+	p->scp->sysbus = SYSBUSVAL;				/* 1 = 8Bit-Bus, 0 = 16 Bit */
+	if(p->scp->sysbus != SYSBUSVAL)
+		return 0;
+
+	iscp_addr = (char *)dvma_btov((unsigned long)where);
+	
+	p->iscp = (struct iscp_struct *) iscp_addr;
+	memset((char *)p->iscp,0, sizeof(struct iscp_struct));
+
+	p->scp->iscp = make24(p->iscp);
+	p->iscp->busy = 1;
+
+	sun3_reset586();
+	sun3_attn586();
+	DELAY(1);	/* wait a while... */
+	
+	if(p->iscp->busy) /* i82586 clears 'busy' after successful init */
+		return 0;
+
+	return 1;
+}
+
+/******************************************************************
+ * set iscp at the right place, called by sun3_82586_probe1 and open586.
+ */
+static void alloc586(struct net_device *dev)
+{
+	struct priv *p =	(struct priv *) dev->priv;
+
+	sun3_reset586();
+	DELAY(1);
+
+	p->scp	= (struct scp_struct *)	(p->base + SCP_DEFAULT_ADDRESS);
+	p->iscp	= (struct iscp_struct *) dvma_btov(dev->mem_start);
+	p->scb  = (struct scb_struct *)  ((char *)p->iscp + sizeof(struct iscp_struct));
+
+	memset((char *) p->iscp,0,sizeof(struct iscp_struct));
+	memset((char *) p->scp ,0,sizeof(struct scp_struct));
+
+	p->scp->iscp = make24(p->iscp);
+	p->scp->sysbus = SYSBUSVAL;
+	p->iscp->scb_offset = make16(p->scb);
+	p->iscp->scb_base = make24(dvma_btov(dev->mem_start));
+
+	p->iscp->busy = 1;
+	sun3_reset586();
+	sun3_attn586();
+
+	DELAY(1);
+
+	if(p->iscp->busy)
+		printk("%s: Init-Problems (alloc).\n",dev->name);
+
+	p->reseted = 0;
+
+	memset((char *)p->scb,0,sizeof(struct scb_struct));
+}
+
+int __init sun3_82586_probe(struct net_device *dev)
+{
+	unsigned long ioaddr, iopte;
+	static int found = 0;
+	
+	/* check that this machine has an onboard 82586 */
+	switch(idprom->id_machtype) {
+	case SM_SUN3|SM_3_160:
+	case SM_SUN3|SM_3_260:
+		/* these machines have 82586 */
+		break;
+
+	default:
+		return(-ENODEV);
+	}
+
+	if(found)
+		return -ENODEV;
+	
+	for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 +
+	    SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) {
+
+		iopte = sun3_get_pte(ioaddr);
+		if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */
+			continue;
+
+		if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) ==
+		   IE_OBIO) {
+			found = 1;
+			break;
+		}
+	}
+	
+	if(!found)
+		return 0;
+	
+	SET_MODULE_OWNER(dev);
+
+	dev->irq = IE_IRQ;
+	dev->base_addr = ioaddr;
+	if(sun3_82586_probe1(dev, ioaddr) == 0)
+		return 0;
+
+	return -ENODEV;
+}
+
+static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
+{
+	int i, size, retval;
+
+//	if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name))
+//		return -EBUSY;
+
+	/* copy in the ethernet address from the prom */
+	for(i = 0; i < 6 ; i++)
+	     dev->dev_addr[i] = idprom->id_ethaddr[i];
+
+	printk("%s: SUN3 Intel 82586 found at %lx, ",dev->name,dev->base_addr);
+
+	/*
+	 * check (or search) IO-Memory, 32K
+	 */
+	size = 0x8000;
+
+	dev->mem_start = (unsigned long)dvma_malloc_align(0x8000, 0x1000);
+	dev->mem_end = dev->mem_start + size;
+
+	if(size != 0x2000 && size != 0x4000 && size != 0x8000) {
+		printk("\n%s: Illegal memory size %d. Allowed is 0x2000 or 0x4000 or 0x8000 bytes.\n",dev->name,size);
+		retval = -ENODEV;
+		goto out;
+	}
+	if(!check586(dev,(char *) dev->mem_start,size)) {
+		printk("?memcheck, Can't find memory at 0x%lx with size %d!\n",dev->mem_start,size);
+		retval = -ENODEV;
+		goto out;
+	}
+
+	dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
+	if(dev->priv == NULL) {
+		printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name);
+		retval = -ENOMEM;
+		goto out;
+	}
+
+	/* warning: we don't free it on errors */
+	memset((char *) dev->priv,0,sizeof(struct priv));
+
+	((struct priv *) (dev->priv))->memtop = (char *)dvma_btov(dev->mem_start);
+	((struct priv *) (dev->priv))->base = (unsigned long) dvma_btov(0);
+	alloc586(dev);
+
+	/* set number of receive-buffs according to memsize */
+	if(size == 0x2000)
+		((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8;
+	else if(size == 0x4000)
+		((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
+	else
+		((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_32;
+
+	printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq);
+	
+	dev->open		= sun3_82586_open;
+	dev->stop		= sun3_82586_close;
+	dev->get_stats		= sun3_82586_get_stats;
+	dev->tx_timeout 	= sun3_82586_timeout;
+	dev->watchdog_timeo	= HZ/20;
+	dev->hard_start_xmit 	= sun3_82586_send_packet;
+	dev->set_multicast_list = set_multicast_list;
+
+	dev->if_port 		= 0;
+
+	ether_setup(dev);
+
+	return 0;
+out:
+	return retval;
+}
+
+
+static int init586(struct net_device *dev)
+{
+	void *ptr;
+	int i,result=0;
+	struct priv *p = (struct priv *) dev->priv;
+	volatile struct configure_cmd_struct	*cfg_cmd;
+	volatile struct iasetup_cmd_struct *ias_cmd;
+	volatile struct tdr_cmd_struct *tdr_cmd;
+	volatile struct mcsetup_cmd_struct *mc_cmd;
+	struct dev_mc_list *dmi=dev->mc_list;
+	int num_addrs=dev->mc_count;
+
+	ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
+
+	cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */
+	cfg_cmd->cmd_status	= 0;
+	cfg_cmd->cmd_cmd	= swab16(CMD_CONFIGURE | CMD_LAST);
+	cfg_cmd->cmd_link	= 0xffff;
+
+	cfg_cmd->byte_cnt	= 0x0a; /* number of cfg bytes */
+	cfg_cmd->fifo		= fifo; /* fifo-limit (8=tx:32/rx:64) */
+	cfg_cmd->sav_bf		= 0x40; /* hold or discard bad recv frames (bit 7) */
+	cfg_cmd->adr_len	= 0x2e; /* addr_len |!src_insert |pre-len |loopback */
+	cfg_cmd->priority	= 0x00;
+	cfg_cmd->ifs		= 0x60;
+	cfg_cmd->time_low	= 0x00;
+	cfg_cmd->time_high	= 0xf2;
+	cfg_cmd->promisc	= 0;
+	if(dev->flags & IFF_ALLMULTI) {
+		int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
+		if(num_addrs > len)	{
+			printk("%s: switching to promisc. mode\n",dev->name);
+			dev->flags|=IFF_PROMISC;
+		}
+	}
+	if(dev->flags&IFF_PROMISC)
+	{
+			 cfg_cmd->promisc=1;
+			 dev->flags|=IFF_PROMISC;
+	}
+	cfg_cmd->carr_coll	= 0x00;
+
+	p->scb->cbl_offset	= make16(cfg_cmd);
+	p->scb->cmd_ruc		= 0;
+
+	p->scb->cmd_cuc		= CUC_START; /* cmd.-unit start */
+	sun3_attn586();
+
+	WAIT_4_STAT_COMPL(cfg_cmd);
+
+	if((swab16(cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
+	{
+		printk("%s: configure command failed: %x\n",dev->name,swab16(cfg_cmd->cmd_status));
+		return 1;
+	}
+
+	/*
+	 * individual address setup
+	 */
+
+	ias_cmd = (struct iasetup_cmd_struct *)ptr;
+
+	ias_cmd->cmd_status	= 0;
+	ias_cmd->cmd_cmd	= swab16(CMD_IASETUP | CMD_LAST);
+	ias_cmd->cmd_link	= 0xffff;
+
+	memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN);
+
+	p->scb->cbl_offset = make16(ias_cmd);
+
+	p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
+	sun3_attn586();
+
+	WAIT_4_STAT_COMPL(ias_cmd);
+
+	if((swab16(ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
+		printk("%s (82586): individual address setup command failed: %04x\n",dev->name,swab16(ias_cmd->cmd_status));
+		return 1;
+	}
+
+	/*
+	 * TDR, wire check .. e.g. no resistor e.t.c
+	 */
+	 
+	tdr_cmd = (struct tdr_cmd_struct *)ptr;
+
+	tdr_cmd->cmd_status	= 0;
+	tdr_cmd->cmd_cmd	= swab16(CMD_TDR | CMD_LAST);
+	tdr_cmd->cmd_link	= 0xffff;
+	tdr_cmd->status		= 0;
+
+	p->scb->cbl_offset = make16(tdr_cmd);
+	p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
+	sun3_attn586();
+
+	WAIT_4_STAT_COMPL(tdr_cmd);
+
+	if(!(swab16(tdr_cmd->cmd_status) & STAT_COMPL))
+	{
+		printk("%s: Problems while running the TDR.\n",dev->name);
+	}
+	else
+	{
+		DELAY_16(); /* wait for result */
+		result = swab16(tdr_cmd->status);
+
+		p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
+		sun3_attn586(); /* ack the interrupts */
+
+		if(result & TDR_LNK_OK)
+			;
+		else if(result & TDR_XCVR_PRB)
+			printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name);
+		else if(result & TDR_ET_OPN)
+			printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
+		else if(result & TDR_ET_SRT)
+		{
+			if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
+				printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
+		}
+		else
+			printk("%s: TDR: Unknown status %04x\n",dev->name,result);
+	}
+
+	/*
+	 * Multicast setup
+	 */
+	if(num_addrs && !(dev->flags & IFF_PROMISC) )
+	{
+		mc_cmd = (struct mcsetup_cmd_struct *) ptr;
+		mc_cmd->cmd_status = 0;
+		mc_cmd->cmd_cmd = swab16(CMD_MCSETUP | CMD_LAST);
+		mc_cmd->cmd_link = 0xffff;
+		mc_cmd->mc_cnt = swab16(num_addrs * 6);
+
+		for(i=0;i<num_addrs;i++,dmi=dmi->next)
+			memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6);
+
+		p->scb->cbl_offset = make16(mc_cmd);
+		p->scb->cmd_cuc = CUC_START;
+		sun3_attn586();
+
+		WAIT_4_STAT_COMPL(mc_cmd);
+
+		if( (swab16(mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
+			printk("%s: Can't apply multicast-address-list.\n",dev->name);
+	}
+
+	/*
+	 * alloc nop/xmit-cmds
+	 */
+#if (NUM_XMIT_BUFFS == 1)
+	for(i=0;i<2;i++)
+	{
+		p->nop_cmds[i] 			= (struct nop_cmd_struct *)ptr;
+		p->nop_cmds[i]->cmd_cmd		= swab16(CMD_NOP);
+		p->nop_cmds[i]->cmd_status 	= 0;
+		p->nop_cmds[i]->cmd_link	= make16((p->nop_cmds[i]));
+		ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
+	}
+#else
+	for(i=0;i<NUM_XMIT_BUFFS;i++)
+	{
+		p->nop_cmds[i]			= (struct nop_cmd_struct *)ptr;
+		p->nop_cmds[i]->cmd_cmd		= swab16(CMD_NOP);
+		p->nop_cmds[i]->cmd_status	= 0;
+		p->nop_cmds[i]->cmd_link	= make16((p->nop_cmds[i]));
+		ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
+	}
+#endif
+
+	ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
+
+	/*
+	 * alloc xmit-buffs / init xmit_cmds
+	 */
+	for(i=0;i<NUM_XMIT_BUFFS;i++)
+	{
+		p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/
+		ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
+		p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */
+		ptr = (char *) ptr + XMIT_BUFF_SIZE;
+		p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
+		ptr = (char *) ptr + sizeof(struct tbd_struct);
+		if((void *)ptr > (void *)dev->mem_end)
+		{
+			printk("%s: not enough shared-mem for your configuration!\n",dev->name);
+			return 1;
+		}
+		memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
+		memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
+		p->xmit_cmds[i]->cmd_link = make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]);
+		p->xmit_cmds[i]->cmd_status = swab16(STAT_COMPL);
+		p->xmit_cmds[i]->cmd_cmd = swab16(CMD_XMIT | CMD_INT);
+		p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
+		p->xmit_buffs[i]->next = 0xffff;
+		p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
+	}
+
+	p->xmit_count = 0;
+	p->xmit_last	= 0;
+#ifndef NO_NOPCOMMANDS
+	p->nop_point	= 0;
+#endif
+
+	 /*
+		* 'start transmitter'
+		*/
+#ifndef NO_NOPCOMMANDS
+	p->scb->cbl_offset = make16(p->nop_cmds[0]);
+	p->scb->cmd_cuc = CUC_START;
+	sun3_attn586();
+	WAIT_4_SCB_CMD();
+#else
+	p->xmit_cmds[0]->cmd_link = make16(p->xmit_cmds[0]);
+	p->xmit_cmds[0]->cmd_cmd	= swab16(CMD_XMIT | CMD_SUSPEND | CMD_INT);
+#endif
+
+	/*
+	 * ack. interrupts
+	 */
+	p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
+	sun3_attn586();
+	DELAY_16();
+
+	sun3_enaint();
+	sun3_active();
+
+	return 0;
+}
+
+/******************************************************
+ * This is a helper routine for sun3_82586_rnr_int() and init586().
+ * It sets up the Receive Frame Area (RFA).
+ */
+
+static void *alloc_rfa(struct net_device *dev,void *ptr)
+{
+	volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
+	volatile struct rbd_struct *rbd;
+	int i;
+	struct priv *p = (struct priv *) dev->priv;
+
+	memset((char *) rfd,0,sizeof(struct rfd_struct)*(p->num_recv_buffs+rfdadd));
+	p->rfd_first = rfd;
+
+	for(i = 0; i < (p->num_recv_buffs+rfdadd); i++) {
+		rfd[i].next = make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd) );
+		rfd[i].rbd_offset = 0xffff;
+	}
+	rfd[p->num_recv_buffs-1+rfdadd].last = RFD_SUSP;	 /* RU suspend */
+
+	ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd) );
+
+	rbd = (struct rbd_struct *) ptr;
+	ptr = (void *) (rbd + p->num_recv_buffs);
+
+	 /* clr descriptors */
+	memset((char *) rbd,0,sizeof(struct rbd_struct)*(p->num_recv_buffs));
+
+	for(i=0;i<p->num_recv_buffs;i++)
+	{
+		rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs));
+		rbd[i].size = swab16(RECV_BUFF_SIZE);
+		rbd[i].buffer = make24(ptr);
+		ptr = (char *) ptr + RECV_BUFF_SIZE;
+	}
+
+	p->rfd_top	= p->rfd_first;
+	p->rfd_last = p->rfd_first + (p->num_recv_buffs - 1 + rfdadd);
+
+	p->scb->rfa_offset		= make16(p->rfd_first);
+	p->rfd_first->rbd_offset	= make16(rbd);
+
+	return ptr;
+}
+
+
+/**************************************************
+ * Interrupt Handler ...
+ */
+
+static void sun3_82586_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr)
+{
+	struct net_device *dev = dev_id;
+	unsigned short stat;
+	int cnt=0;
+	struct priv *p;
+
+	if (!dev) {
+		printk ("sun3_82586-interrupt: irq %d for unknown device.\n",irq);
+		return;
+	}
+	p = (struct priv *) dev->priv;
+
+	if(debuglevel > 1)
+		printk("I");
+
+	WAIT_4_SCB_CMD(); /* wait for last command	*/
+
+	while((stat=p->scb->cus & STAT_MASK))
+	{
+		p->scb->cmd_cuc = stat;
+		sun3_attn586();
+
+		if(stat & STAT_FR)	 /* received a frame */
+			sun3_82586_rcv_int(dev);
+
+		if(stat & STAT_RNR) /* RU went 'not ready' */
+		{
+			printk("(R)");
+			if(p->scb->rus & RU_SUSPEND) /* special case: RU_SUSPEND */
+			{
+				WAIT_4_SCB_CMD();
+				p->scb->cmd_ruc = RUC_RESUME;
+				sun3_attn586();
+				WAIT_4_SCB_CMD_RUC();
+			}
+			else
+			{
+				printk("%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->rus);
+				sun3_82586_rnr_int(dev);
+			}
+		}
+
+		if(stat & STAT_CX)		/* command with I-bit set complete */
+			 sun3_82586_xmt_int(dev);
+
+#ifndef NO_NOPCOMMANDS
+		if(stat & STAT_CNA)	/* CU went 'not ready' */
+		{
+			if(netif_running(dev))
+				printk("%s: oops! CU has left active state. stat: %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->cus);
+		}
+#endif
+
+		if(debuglevel > 1)
+			printk("%d",cnt++);
+
+		WAIT_4_SCB_CMD(); /* wait for ack. (sun3_82586_xmt_int can be faster than ack!!) */
+		if(p->scb->cmd_cuc)	 /* timed out? */
+		{
+			printk("%s: Acknowledge timed out.\n",dev->name);
+			sun3_disint();
+			break;
+		}
+	}
+
+	if(debuglevel > 1)
+		printk("i");
+}
+
+/*******************************************************
+ * receive-interrupt
+ */
+
+static void sun3_82586_rcv_int(struct net_device *dev)
+{
+	int status,cnt=0;
+	unsigned short totlen;
+	struct sk_buff *skb;
+	struct rbd_struct *rbd;
+	struct priv *p = (struct priv *) dev->priv;
+
+	if(debuglevel > 0)
+		printk("R");
+
+	for(;(status = p->rfd_top->stat_high) & RFD_COMPL;)
+	{
+			rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
+
+			if(status & RFD_OK) /* frame received without error? */
+			{
+				if( (totlen = swab16(rbd->status)) & RBD_LAST) /* the first and the last buffer? */
+				{
+					totlen &= RBD_MASK; /* length of this frame */
+					rbd->status = 0;
+					skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
+					if(skb != NULL)
+					{
+						skb->dev = dev;
+						skb_reserve(skb,2);
+						skb_put(skb,totlen);
+						eth_copy_and_sum(skb,(char *) p->base+swab32((unsigned long) rbd->buffer),totlen,0);
+						skb->protocol=eth_type_trans(skb,dev);
+						netif_rx(skb);
+						p->stats.rx_packets++;
+					}
+					else
+						p->stats.rx_dropped++;
+				}
+				else
+				{
+					int rstat;
+						 /* free all RBD's until RBD_LAST is set */
+					totlen = 0;
+					while(!((rstat=swab16(rbd->status)) & RBD_LAST))
+					{
+						totlen += rstat & RBD_MASK;
+						if(!rstat)
+						{
+							printk("%s: Whoops .. no end mark in RBD list\n",dev->name);
+							break;
+						}
+						rbd->status = 0;
+						rbd = (struct rbd_struct *) make32(rbd->next);
+					}
+					totlen += rstat & RBD_MASK;
+					rbd->status = 0;
+					printk("%s: received oversized frame! length: %d\n",dev->name,totlen);
+					p->stats.rx_dropped++;
+			 }
+		}
+		else /* frame !(ok), only with 'save-bad-frames' */
+		{
+			printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
+			p->stats.rx_errors++;
+		}
+		p->rfd_top->stat_high = 0;
+		p->rfd_top->last = RFD_SUSP; /* maybe exchange by RFD_LAST */
+		p->rfd_top->rbd_offset = 0xffff;
+		p->rfd_last->last = 0;				/* delete RFD_SUSP	*/
+		p->rfd_last = p->rfd_top;
+		p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
+		p->scb->rfa_offset = make16(p->rfd_top);
+
+		if(debuglevel > 0)
+			printk("%d",cnt++);
+	}
+
+	if(automatic_resume)
+	{
+		WAIT_4_SCB_CMD();
+		p->scb->cmd_ruc = RUC_RESUME;
+		sun3_attn586();
+		WAIT_4_SCB_CMD_RUC();
+	}
+
+#ifdef WAIT_4_BUSY
+	{
+		int i;
+		for(i=0;i<1024;i++)
+		{
+			if(p->rfd_top->status)
+				break;
+			DELAY_16();
+			if(i == 1023)
+				printk("%s: RU hasn't fetched next RFD (not busy/complete)\n",dev->name);
+		}
+	}
+#endif
+
+#if 0
+	if(!at_least_one)
+	{
+		int i;
+		volatile struct rfd_struct *rfds=p->rfd_top;
+		volatile struct rbd_struct *rbds;
+		printk("%s: received a FC intr. without having a frame: %04x %d\n",dev->name,status,old_at_least);
+		for(i=0;i< (p->num_recv_buffs+4);i++)
+		{
+			rbds = (struct rbd_struct *) make32(rfds->rbd_offset);
+			printk("%04x:%04x ",rfds->status,rbds->status);
+			rfds = (struct rfd_struct *) make32(rfds->next);
+		}
+		printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);
+		printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);
+	}
+	old_at_least = at_least_one;
+#endif
+
+	if(debuglevel > 0)
+		printk("r");
+}
+
+/**********************************************************
+ * handle 'Receiver went not ready'.
+ */
+
+static void sun3_82586_rnr_int(struct net_device *dev)
+{
+	struct priv *p = (struct priv *) dev->priv;
+
+	p->stats.rx_errors++;
+
+	WAIT_4_SCB_CMD();		/* wait for the last cmd, WAIT_4_FULLSTAT?? */
+	p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
+	sun3_attn586();
+	WAIT_4_SCB_CMD_RUC();		/* wait for accept cmd. */
+
+	alloc_rfa(dev,(char *)p->rfd_first);
+/* maybe add a check here, before restarting the RU */
+	startrecv586(dev); /* restart RU */
+
+	printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->rus);
+
+}
+
+/**********************************************************
+ * handle xmit - interrupt
+ */
+
+static void sun3_82586_xmt_int(struct net_device *dev)
+{
+	int status;
+	struct priv *p = (struct priv *) dev->priv;
+
+	if(debuglevel > 0)
+		printk("X");
+
+	status = swab16(p->xmit_cmds[p->xmit_last]->cmd_status);
+	if(!(status & STAT_COMPL))
+		printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
+
+	if(status & STAT_OK)
+	{
+		p->stats.tx_packets++;
+		p->stats.collisions += (status & TCMD_MAXCOLLMASK);
+	}
+	else
+	{
+		p->stats.tx_errors++;
+		if(status & TCMD_LATECOLL) {
+			printk("%s: late collision detected.\n",dev->name);
+			p->stats.collisions++;
+		}
+		else if(status & TCMD_NOCARRIER) {
+			p->stats.tx_carrier_errors++;
+			printk("%s: no carrier detected.\n",dev->name);
+		}
+		else if(status & TCMD_LOSTCTS)
+			printk("%s: loss of CTS detected.\n",dev->name);
+		else if(status & TCMD_UNDERRUN) {
+			p->stats.tx_fifo_errors++;
+			printk("%s: DMA underrun detected.\n",dev->name);
+		}
+		else if(status & TCMD_MAXCOLL) {
+			printk("%s: Max. collisions exceeded.\n",dev->name);
+			p->stats.collisions += 16;
+		}
+	}
+
+#if (NUM_XMIT_BUFFS > 1)
+	if( (++p->xmit_last) == NUM_XMIT_BUFFS)
+		p->xmit_last = 0;
+#endif
+	netif_wake_queue(dev);
+}
+
+/***********************************************************
+ * (re)start the receiver
+ */
+
+static void startrecv586(struct net_device *dev)
+{
+	struct priv *p = (struct priv *) dev->priv;
+
+	WAIT_4_SCB_CMD();
+	WAIT_4_SCB_CMD_RUC();
+	p->scb->rfa_offset = make16(p->rfd_first);
+	p->scb->cmd_ruc = RUC_START;
+	sun3_attn586();		/* start cmd. */
+	WAIT_4_SCB_CMD_RUC();	/* wait for accept cmd. (no timeout!!) */
+}
+
+static void sun3_82586_timeout(struct net_device *dev)
+{
+	struct priv *p = (struct priv *) dev->priv;
+#ifndef NO_NOPCOMMANDS
+	if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */
+	{
+		netif_wake_queue(dev);
+#ifdef DEBUG
+		printk("%s: strange ... timeout with CU active?!?\n",dev->name);
+		printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)swab16(p->xmit_cmds[0]->cmd_status),(int)swab16(p->nop_cmds[0]->cmd_status),(int)swab16(p->nop_cmds[1]->cmd_status),(int)p->nop_point);
+#endif
+		p->scb->cmd_cuc = CUC_ABORT;
+		sun3_attn586();
+		WAIT_4_SCB_CMD();
+		p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
+		p->scb->cmd_cuc = CUC_START;
+		sun3_attn586();
+		WAIT_4_SCB_CMD();
+		dev->trans_start = jiffies;
+		return 0;
+	}
+#endif
+	{
+#ifdef DEBUG
+		printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus);
+		printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status));
+		printk("%s: check, whether you set the right interrupt number!\n",dev->name);
+#endif
+		sun3_82586_close(dev);
+		sun3_82586_open(dev);
+	}
+	dev->trans_start = jiffies;
+}
+
+/******************************************************
+ * send frame
+ */
+
+static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	int len,i;
+#ifndef NO_NOPCOMMANDS
+	int next_nop;
+#endif
+	struct priv *p = (struct priv *) dev->priv;
+
+	if(skb->len > XMIT_BUFF_SIZE)
+	{
+		printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
+		return 0;
+	}
+
+	netif_stop_queue(dev);
+
+#if(NUM_XMIT_BUFFS > 1)
+	if(test_and_set_bit(0,(void *) &p->lock)) {
+		printk("%s: Queue was locked\n",dev->name);
+		return 1;
+	}
+	else
+#endif
+	{
+		memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);
+		len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
+
+#if (NUM_XMIT_BUFFS == 1)
+#	ifdef NO_NOPCOMMANDS
+
+#ifdef DEBUG
+		if(p->scb->cus & CU_ACTIVE)
+		{
+			printk("%s: Hmmm .. CU is still running and we wanna send a new packet.\n",dev->name);
+			printk("%s: stat: %04x %04x\n",dev->name,p->scb->cus,swab16(p->xmit_cmds[0]->cmd_status));
+		}
+#endif
+
+		p->xmit_buffs[0]->size = swab16(TBD_LAST | len);
+		for(i=0;i<16;i++)
+		{
+			p->xmit_cmds[0]->cmd_status = 0;
+			WAIT_4_SCB_CMD();
+			if( (p->scb->cus & CU_STATUS) == CU_SUSPEND)
+				p->scb->cmd_cuc = CUC_RESUME;
+			else
+			{
+				p->scb->cbl_offset = make16(p->xmit_cmds[0]);
+				p->scb->cmd_cuc = CUC_START;
+			}
+
+			sun3_attn586();
+			dev->trans_start = jiffies;
+			if(!i)
+				dev_kfree_skb(skb);
+			WAIT_4_SCB_CMD();
+			if( (p->scb->cus & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */
+				break;
+			if(p->xmit_cmds[0]->cmd_status)
+				break;
+			if(i==15)
+				printk("%s: Can't start transmit-command.\n",dev->name);
+		}
+#	else
+		next_nop = (p->nop_point + 1) & 0x1;
+		p->xmit_buffs[0]->size = swab16(TBD_LAST | len);
+
+		p->xmit_cmds[0]->cmd_link	 = p->nop_cmds[next_nop]->cmd_link
+			= make16((p->nop_cmds[next_nop]));
+		p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
+
+		p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
+		dev->trans_start = jiffies;
+		p->nop_point = next_nop;
+		dev_kfree_skb(skb);
+#	endif
+#else
+		p->xmit_buffs[p->xmit_count]->size = swab16(TBD_LAST | len);
+		if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
+			next_nop = 0;
+
+		p->xmit_cmds[p->xmit_count]->cmd_status	= 0;
+		/* linkpointer of xmit-command already points to next nop cmd */
+		p->nop_cmds[next_nop]->cmd_link = make16((p->nop_cmds[next_nop]));
+		p->nop_cmds[next_nop]->cmd_status = 0;
+
+		p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
+		dev->trans_start = jiffies;
+		p->xmit_count = next_nop;
+
+		{
+			unsigned long flags;
+			save_flags(flags);
+			cli();
+			if(p->xmit_count != p->xmit_last)
+				netif_wake_queue(dev);
+			p->lock = 0;
+			restore_flags(flags);
+		}
+		dev_kfree_skb(skb);
+#endif
+	}
+	return 0;
+}
+
+/*******************************************
+ * Someone wanna have the statistics
+ */
+
+static struct net_device_stats *sun3_82586_get_stats(struct net_device *dev)
+{
+	struct priv *p = (struct priv *) dev->priv;
+	unsigned short crc,aln,rsc,ovrn;
+
+	crc = swab16(p->scb->crc_errs); /* get error-statistic from the ni82586 */
+	p->scb->crc_errs = 0;
+	aln = swab16(p->scb->aln_errs);
+	p->scb->aln_errs = 0;
+	rsc = swab16(p->scb->rsc_errs);
+	p->scb->rsc_errs = 0;
+	ovrn = swab16(p->scb->ovrn_errs);
+	p->scb->ovrn_errs = 0;
+
+	p->stats.rx_crc_errors += crc;
+	p->stats.rx_fifo_errors += ovrn;
+	p->stats.rx_frame_errors += aln;
+	p->stats.rx_dropped += rsc;
+
+	return &p->stats;
+}
+
+/********************************************************
+ * Set MC list ..
+ */
+
+static void set_multicast_list(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+	sun3_disint();
+	alloc586(dev);
+	init586(dev);
+	startrecv586(dev);
+	sun3_enaint();
+	netif_wake_queue(dev);
+}
+
+#ifdef MODULE
+#error This code is not currently supported as a module
+static struct net_device dev_sun3_82586;
+
+int init_module(void)
+{
+	dev_sun3_82586.init = sun3_82586_probe;
+	if (register_netdev(&dev_sun3_82586) != 0)
+		return -EIO;
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	unregister_netdev(&dev_sun3_82586);
+	kfree(dev_sun3_82586.priv);
+	dev_sun3_82586.priv = NULL;
+}
+#endif /* MODULE */
+
+#if 0
+/*
+ * DUMP .. we expect a not running CMD unit and enough space
+ */
+void sun3_82586_dump(struct net_device *dev,void *ptr)
+{
+	struct priv *p = (struct priv *) dev->priv;
+	struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr;
+	int i;
+
+	p->scb->cmd_cuc = CUC_ABORT;
+	sun3_attn586();
+	WAIT_4_SCB_CMD();
+	WAIT_4_SCB_CMD_RUC();
+
+	dump_cmd->cmd_status = 0;
+	dump_cmd->cmd_cmd = CMD_DUMP | CMD_LAST;
+	dump_cmd->dump_offset = make16((dump_cmd + 1));
+	dump_cmd->cmd_link = 0xffff;
+
+	p->scb->cbl_offset = make16(dump_cmd);
+	p->scb->cmd_cuc = CUC_START;
+	sun3_attn586();
+	WAIT_4_STAT_COMPL(dump_cmd);
+
+	if( (dump_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
+				printk("%s: Can't get dump information.\n",dev->name);
+
+	for(i=0;i<170;i++) {
+		printk("%02x ",(int) ((unsigned char *) (dump_cmd + 1))[i]);
+		if(i % 24 == 23)
+			printk("\n");
+	}
+	printk("\n");
+}
+#endif
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sun3_82586.h linux/drivers/net/sun3_82586.h
--- linux.orig/drivers/net/sun3_82586.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/sun3_82586.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,318 @@
+/*
+ * Intel i82586 Ethernet definitions
+ *
+ * This is an extension to the Linux operating system, and is covered by the
+ * same Gnu Public License that covers that work.
+ *
+ * copyrights (c) 1994 by Michael Hipp (hippm@informatik.uni-tuebingen.de)
+ *
+ * I have done a look in the following sources:
+ *   crynwr-packet-driver by Russ Nelson
+ *   Garret A. Wollman's i82586-driver for BSD
+ */
+
+/*
+ * Cloned from ni52.h, copyright as above.  
+ *
+ * Modified for Sun3 OBIO i82586 by Sam Creasey (sammy@sammy.net)
+ */
+
+
+/* defines for the obio chip (not vme) */ 
+#define IEOB_NORSET 0x80        /* don't reset the board */
+#define IEOB_ONAIR  0x40        /* put us on the air */
+#define IEOB_ATTEN  0x20        /* attention! */
+#define IEOB_IENAB  0x10        /* interrupt enable */
+#define IEOB_XXXXX  0x08        /* free bit */
+#define IEOB_XCVRL2 0x04        /* level 2 transceiver? */
+#define IEOB_BUSERR 0x02        /* bus error */
+#define IEOB_INT    0x01        /* interrupt */
+
+/* where the obio one lives */
+#define IE_OBIO 0xc0000
+#define IE_IRQ 3
+
+/*
+ * where to find the System Configuration Pointer (SCP)
+ */
+#define SCP_DEFAULT_ADDRESS 0xfffff4
+
+
+/*
+ * System Configuration Pointer Struct
+ */
+
+struct scp_struct
+{
+  unsigned short zero_dum0;	/* has to be zero */
+  unsigned char  sysbus;	/* 0=16Bit,1=8Bit */
+  unsigned char  zero_dum1;	/* has to be zero for 586 */
+  unsigned short zero_dum2;
+  unsigned short zero_dum3;
+  char          *iscp;		/* pointer to the iscp-block */
+};
+
+
+/*
+ * Intermediate System Configuration Pointer (ISCP)
+ */
+struct iscp_struct
+{
+  unsigned char  busy;          /* 586 clears after successful init */
+  unsigned char  zero_dummy;    /* has to be zero */
+  unsigned short scb_offset;    /* pointeroffset to the scb_base */
+  char          *scb_base;      /* base-address of all 16-bit offsets */
+};
+
+/*
+ * System Control Block (SCB)
+ */
+struct scb_struct
+{
+  unsigned char rus;
+  unsigned char cus;
+  unsigned char cmd_ruc;           /* command word: RU part */
+  unsigned char cmd_cuc;           /* command word: CU part & ACK */
+  unsigned short cbl_offset;    /* pointeroffset, command block list */
+  unsigned short rfa_offset;    /* pointeroffset, receive frame area */
+  unsigned short crc_errs;      /* CRC-Error counter */
+  unsigned short aln_errs;      /* allignmenterror counter */
+  unsigned short rsc_errs;      /* Resourceerror counter */
+  unsigned short ovrn_errs;     /* OVerrunerror counter */
+};
+
+/*
+ * possible command values for the command word
+ */
+#define RUC_MASK	0x0070	/* mask for RU commands */
+#define RUC_NOP		0x0000	/* NOP-command */
+#define RUC_START	0x0010	/* start RU */
+#define RUC_RESUME	0x0020	/* resume RU after suspend */
+#define RUC_SUSPEND	0x0030	/* suspend RU */
+#define RUC_ABORT	0x0040	/* abort receiver operation immediately */
+
+#define CUC_MASK        0x07  /* mask for CU command */
+#define CUC_NOP         0x00  /* NOP-command */
+#define CUC_START       0x01  /* start execution of 1. cmd on the CBL */
+#define CUC_RESUME      0x02  /* resume after suspend */
+#define CUC_SUSPEND     0x03  /* Suspend CU */
+#define CUC_ABORT       0x04  /* abort command operation immediately */
+
+#define ACK_MASK        0xf0  /* mask for ACK command */
+#define ACK_CX          0x80  /* acknowledges STAT_CX */
+#define ACK_FR          0x40  /* ack. STAT_FR */
+#define ACK_CNA         0x20  /* ack. STAT_CNA */
+#define ACK_RNR         0x10  /* ack. STAT_RNR */
+
+/*
+ * possible status values for the status word
+ */
+#define STAT_MASK       0xf0  /* mask for cause of interrupt */
+#define STAT_CX         0x80  /* CU finished cmd with its I bit set */
+#define STAT_FR         0x40  /* RU finished receiving a frame */
+#define STAT_CNA        0x20  /* CU left active state */
+#define STAT_RNR        0x10  /* RU left ready state */
+
+#define CU_STATUS       0x7   /* CU status, 0=idle */
+#define CU_SUSPEND      0x1   /* CU is suspended */
+#define CU_ACTIVE       0x2   /* CU is active */
+
+#define RU_STATUS	0x70	/* RU status, 0=idle */
+#define RU_SUSPEND	0x10	/* RU suspended */
+#define RU_NOSPACE	0x20	/* RU no resources */
+#define RU_READY	0x40	/* RU is ready */
+
+/*
+ * Receive Frame Descriptor (RFD)
+ */
+struct rfd_struct
+{
+  unsigned char  stat_low;	/* status word */
+  unsigned char  stat_high;	/* status word */
+  unsigned char  rfd_sf;	/* 82596 mode only */
+  unsigned char  last;		/* Bit15,Last Frame on List / Bit14,suspend */
+  unsigned short next;		/* linkoffset to next RFD */
+  unsigned short rbd_offset;	/* pointeroffset to RBD-buffer */
+  unsigned char  dest[6];	/* ethernet-address, destination */
+  unsigned char  source[6];	/* ethernet-address, source */
+  unsigned short length;	/* 802.3 frame-length */
+  unsigned short zero_dummy;	/* dummy */
+};
+
+#define RFD_LAST     0x80	/* last: last rfd in the list */
+#define RFD_SUSP     0x40	/* last: suspend RU after  */
+#define RFD_COMPL    0x80
+#define RFD_OK       0x20
+#define RFD_BUSY     0x40
+#define RFD_ERR_LEN  0x10     /* Length error (if enabled length-checking */
+#define RFD_ERR_CRC  0x08     /* CRC error */
+#define RFD_ERR_ALGN 0x04     /* Alignment error */
+#define RFD_ERR_RNR  0x02     /* status: receiver out of resources */
+#define RFD_ERR_OVR  0x01     /* DMA Overrun! */
+
+#define RFD_ERR_FTS  0x0080	/* Frame to short */
+#define RFD_ERR_NEOP 0x0040	/* No EOP flag (for bitstuffing only) */
+#define RFD_ERR_TRUN 0x0020	/* (82596 only/SF mode) indicates truncated frame */
+#define RFD_MATCHADD 0x0002     /* status: Destinationaddress !matches IA (only 82596) */
+#define RFD_COLLDET  0x0001	/* Detected collision during reception */
+
+/*
+ * Receive Buffer Descriptor (RBD)
+ */
+struct rbd_struct 
+{
+  unsigned short status;	/* status word,number of used bytes in buff */
+  unsigned short next;		/* pointeroffset to next RBD */
+  char          *buffer;	/* receive buffer address pointer */
+  unsigned short size;		/* size of this buffer */
+  unsigned short zero_dummy;    /* dummy */
+};
+
+#define RBD_LAST	0x8000	/* last buffer */
+#define RBD_USED	0x4000	/* this buffer has data */
+#define RBD_MASK	0x3fff	/* size-mask for length */
+
+/*
+ * Statusvalues for Commands/RFD
+ */
+#define STAT_COMPL   0x8000	/* status: frame/command is complete */
+#define STAT_BUSY    0x4000	/* status: frame/command is busy */
+#define STAT_OK      0x2000	/* status: frame/command is ok */
+
+/*
+ * Action-Commands
+ */
+#define CMD_NOP		0x0000	/* NOP */
+#define CMD_IASETUP	0x0001	/* initial address setup command */
+#define CMD_CONFIGURE	0x0002	/* configure command */
+#define CMD_MCSETUP	0x0003	/* MC setup command */
+#define CMD_XMIT	0x0004	/* transmit command */
+#define CMD_TDR		0x0005	/* time domain reflectometer (TDR) command */
+#define CMD_DUMP	0x0006	/* dump command */
+#define CMD_DIAGNOSE	0x0007	/* diagnose command */
+
+/*
+ * Action command bits
+ */
+#define CMD_LAST	0x8000	/* indicates last command in the CBL */
+#define CMD_SUSPEND	0x4000	/* suspend CU after this CB */
+#define CMD_INT		0x2000	/* generate interrupt after execution */
+
+/*
+ * NOP - command
+ */
+struct nop_cmd_struct
+{
+  unsigned short cmd_status;	/* status of this command */
+  unsigned short cmd_cmd;       /* the command itself (+bits) */
+  unsigned short cmd_link;      /* offsetpointer to next command */
+};
+
+/*
+ * IA Setup command
+ */
+struct iasetup_cmd_struct 
+{
+  unsigned short cmd_status;
+  unsigned short cmd_cmd;
+  unsigned short cmd_link;
+  unsigned char  iaddr[6];
+};
+
+/*
+ * Configure command 
+ */
+struct configure_cmd_struct
+{
+  unsigned short cmd_status;
+  unsigned short cmd_cmd;
+  unsigned short cmd_link;
+  unsigned char  byte_cnt;   /* size of the config-cmd */
+  unsigned char  fifo;       /* fifo/recv monitor */
+  unsigned char  sav_bf;     /* save bad frames (bit7=1)*/
+  unsigned char  adr_len;    /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
+  unsigned char  priority;   /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
+  unsigned char  ifs;        /* inter frame spacing */
+  unsigned char  time_low;   /* slot time low */
+  unsigned char  time_high;  /* slot time high(0-2) and max. retries(4-7) */
+  unsigned char  promisc;    /* promisc-mode(0) , et al (1-7) */
+  unsigned char  carr_coll;  /* carrier(0-3)/collision(4-7) stuff */
+  unsigned char  fram_len;   /* minimal frame len */
+  unsigned char  dummy;	     /* dummy */
+};
+
+/*
+ * Multicast Setup command 
+ */
+struct mcsetup_cmd_struct 
+{
+  unsigned short cmd_status;
+  unsigned short cmd_cmd;
+  unsigned short cmd_link;
+  unsigned short mc_cnt;		/* number of bytes in the MC-List */
+  unsigned char  mc_list[0][6];  	/* pointer to 6 bytes entries */
+};
+
+/*
+ * DUMP command
+ */
+struct dump_cmd_struct
+{
+  unsigned short cmd_status;
+  unsigned short cmd_cmd;
+  unsigned short cmd_link;
+  unsigned short dump_offset;    /* pointeroffset to DUMP space */
+};
+
+/*
+ * transmit command 
+ */
+struct transmit_cmd_struct 
+{
+  unsigned short cmd_status;
+  unsigned short cmd_cmd;
+  unsigned short cmd_link;
+  unsigned short tbd_offset;	/* pointeroffset to TBD */
+  unsigned char  dest[6];       /* destination address of the frame */
+  unsigned short length;	/* user defined: 802.3 length / Ether type */
+};
+
+#define TCMD_ERRMASK     0x0fa0
+#define TCMD_MAXCOLLMASK 0x000f
+#define TCMD_MAXCOLL     0x0020
+#define TCMD_HEARTBEAT   0x0040
+#define TCMD_DEFERRED    0x0080
+#define TCMD_UNDERRUN    0x0100
+#define TCMD_LOSTCTS     0x0200
+#define TCMD_NOCARRIER   0x0400
+#define TCMD_LATECOLL    0x0800
+
+struct tdr_cmd_struct
+{
+  unsigned short cmd_status;
+  unsigned short cmd_cmd;
+  unsigned short cmd_link;
+  unsigned short status;
+};
+
+#define TDR_LNK_OK	0x8000	/* No link problem identified */
+#define TDR_XCVR_PRB	0x4000	/* indicates a transceiver problem */
+#define TDR_ET_OPN	0x2000	/* open, no correct termination */
+#define TDR_ET_SRT	0x1000	/* TDR detected a short circuit */
+#define TDR_TIMEMASK	0x07ff	/* mask for the time field */
+
+/*
+ * Transmit Buffer Descriptor (TBD)
+ */
+struct tbd_struct
+{
+  unsigned short size;		/* size + EOF-Flag(15) */
+  unsigned short next;          /* pointeroffset to next TBD */
+  char          *buffer;        /* pointer to buffer */
+};
+
+#define TBD_LAST 0x8000         /* EOF-Flag, indicates last buffer in list */
+
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sun3lance.c linux/drivers/net/sun3lance.c
--- linux.orig/drivers/net/sun3lance.c	2001-10-17 04:56:29.000000000 +0000
+++ linux/drivers/net/sun3lance.c	2002-07-20 01:08:31.000000000 +0000
@@ -21,7 +21,7 @@
   
 */
 
-static char *version = "sun3lance.c: v1.1 11/17/1999  Sam Creasey (sammy@oh.verio.com)\n";
+static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.net)\n";
 
 #include <linux/module.h>
 
@@ -35,16 +35,24 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/delay.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
-#include <asm/idprom.h>
 #include <asm/pgtable.h>
-#include <asm/sun3mmu.h>
+#include <asm/pgalloc.h>
 #include <asm/dvma.h>
+#include <asm/idprom.h>
+#include <asm/machines.h>
+
+#ifdef CONFIG_SUN3
+#include <asm/sun3mmu.h>
+#else
+#include <asm/sun3xprom.h>
+#endif
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -62,7 +70,7 @@
  *  3 = debug, print even more debug infos (packet data)
  */
 
-#define	LANCE_DEBUG	1
+#define	LANCE_DEBUG	0
 
 #ifdef LANCE_DEBUG
 static int lance_debug = LANCE_DEBUG;
@@ -139,7 +147,7 @@
 	struct lance_tx_head	tx_head[TX_RING_SIZE];
 	struct lance_rx_head	rx_head[RX_RING_SIZE];
 	char   rx_data[RX_RING_SIZE][PKT_BUF_SZ];
-	char   tx_data[RX_RING_SIZE][PKT_BUF_SZ];
+	char   tx_data[TX_RING_SIZE][PKT_BUF_SZ];
 };
 
 /* The driver's private device structure */
@@ -151,8 +159,8 @@
 	int old_tx, old_rx;     /* ring entry to be processed */
 	struct net_device_stats stats;
 /* These two must be longs for set_bit() */
-	long					tx_full;
-	long					lock;
+	long	    tx_full;
+	long	    lock;
 };
 
 /* I/O register access macros */
@@ -247,15 +255,27 @@
 {	
 	static int found;
 
+	/* check that this machine has an onboard lance */
+	switch(idprom->id_machtype) {
+	case SM_SUN3|SM_3_50:
+	case SM_SUN3|SM_3_60:
+	case SM_SUN3X|SM_3_80:
+		/* these machines have lance */
+		break;
+
+	default:
+		return(-ENODEV);
+	}
+
 	if(found)
-		return(ENODEV);
+		return(-ENODEV);
 
 	if (lance_probe(dev)) {
 			found = 1;
 			return( 0 );
 	}
 
-	return( ENODEV );
+	return( -ENODEV );
 }
 
 static int __init lance_probe( struct net_device *dev)
@@ -269,6 +289,7 @@
 	volatile unsigned short *ioaddr_probe;
 	unsigned short tmp1, tmp2;
 
+#ifdef CONFIG_SUN3
 	/* LANCE_OBIO can be found within the IO pmeg with some effort */
 	for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 +
 	    SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) {
@@ -286,6 +307,9 @@
 	
 	if(!found)
 		return 0;
+#else
+	ioaddr = SUN3X_LANCE;
+#endif
 
 	/* test to see if there's really a lance here */
 	/* (CSRO_INIT shouldn't be readable) */
@@ -311,8 +335,9 @@
 			return 0;
 	}
 	lp = (struct lance_private *)dev->priv;
-	MEM = (struct lance_memory *)sun3_dvma_malloc(sizeof(struct
-							     lance_memory)); 
+
+	MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
+
 	lp->iobase = (volatile unsigned short *)ioaddr;
 	dev->base_addr = (unsigned long)ioaddr; /* informational only */
 
@@ -331,7 +356,7 @@
 	/* copy in the ethernet address from the prom */
 	for(i = 0; i < 6 ; i++)
 	     dev->dev_addr[i] = idprom->id_ethaddr[i];
-	
+
 	/* tell the card it's ether address, bytes swapped */
 	MEM->init.hwaddr[0] = dev->dev_addr[1];
 	MEM->init.hwaddr[1] = dev->dev_addr[0];
@@ -346,20 +371,19 @@
 	MEM->init.mode = 0x0000;
 	MEM->init.filter[0] = 0x00000000;
 	MEM->init.filter[1] = 0x00000000;
-	MEM->init.rdra = sun3_dvma_vtop(MEM->rx_head);
+	MEM->init.rdra = dvma_vtob(MEM->rx_head);
 	MEM->init.rlen    = (RX_LOG_RING_SIZE << 13) |
-		(sun3_dvma_vtop(MEM->rx_head) >> 16);
-	MEM->init.tdra = sun3_dvma_vtop(MEM->tx_head);
+		(dvma_vtob(MEM->rx_head) >> 16);
+	MEM->init.tdra = dvma_vtob(MEM->tx_head);
 	MEM->init.tlen    = (TX_LOG_RING_SIZE << 13) |
-		(sun3_dvma_vtop(MEM->tx_head) >> 16);
+		(dvma_vtob(MEM->tx_head) >> 16);
 
 	DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n",
-	       sun3_dvma_vtop(&(MEM->init)), sun3_dvma_vtop(MEM->rx_head),
-	       (sun3_dvma_vtop(MEM->tx_head))));  
-
+	       dvma_vtob(&(MEM->init)), dvma_vtob(MEM->rx_head),
+	       (dvma_vtob(MEM->tx_head))));  
 
 	if (did_version++ == 0)
-		DPRINTK( 1, ( version ));
+		printk( version );
 
 	/* The LANCE-specific entries in the device structure. */
 	dev->open = &lance_open;
@@ -386,16 +410,8 @@
 
 	REGA(CSR0) = CSR0_STOP;
 
-	/* tell the lance the address of its init block */
-	REGA(CSR1) = sun3_dvma_vtop(&(MEM->init));
-	REGA(CSR2) = sun3_dvma_vtop(&(MEM->init)) >> 16;
-
 	lance_init_ring(dev);
 
-	/* Re-initialize the LANCE, and start it when done. */
-
-	REGA(CSR3) = CSR3_BSWP;
-
 	/* From now on, AREG is kept to point to CSR0 */
 	REGA(CSR0) = CSR0_INIT;
 
@@ -434,23 +450,52 @@
 	lp->old_rx = lp->old_tx = 0;
 
 	for( i = 0; i < TX_RING_SIZE; i++ ) {
-		MEM->tx_head[i].base = sun3_dvma_vtop(MEM->tx_data[i]);
+		MEM->tx_head[i].base = dvma_vtob(MEM->tx_data[i]);
 		MEM->tx_head[i].flag = 0;
  		MEM->tx_head[i].base_hi = 
-			(sun3_dvma_vtop(MEM->tx_data[i])) >>16;
+			(dvma_vtob(MEM->tx_data[i])) >>16;
 		MEM->tx_head[i].length = 0;
 		MEM->tx_head[i].misc = 0;
 	}
 
 	for( i = 0; i < RX_RING_SIZE; i++ ) {
-		MEM->rx_head[i].base = sun3_dvma_vtop(MEM->rx_data[i]);
-		MEM->rx_head[i].flag = TMD1_OWN_CHIP;
+		MEM->rx_head[i].base = dvma_vtob(MEM->rx_data[i]);
+		MEM->rx_head[i].flag = RMD1_OWN_CHIP;
 		MEM->rx_head[i].base_hi = 
-			(sun3_dvma_vtop(MEM->rx_data[i])) >> 16;
+			(dvma_vtob(MEM->rx_data[i])) >> 16;
 		MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000;
 		MEM->rx_head[i].msg_length = 0;
 	}
 
+	/* tell the card it's ether address, bytes swapped */
+	MEM->init.hwaddr[0] = dev->dev_addr[1];
+	MEM->init.hwaddr[1] = dev->dev_addr[0];
+	MEM->init.hwaddr[2] = dev->dev_addr[3];
+	MEM->init.hwaddr[3] = dev->dev_addr[2];
+	MEM->init.hwaddr[4] = dev->dev_addr[5];
+	MEM->init.hwaddr[5] = dev->dev_addr[4];
+
+	MEM->init.mode = 0x0000;
+	MEM->init.filter[0] = 0x00000000;
+	MEM->init.filter[1] = 0x00000000;
+	MEM->init.rdra = dvma_vtob(MEM->rx_head);
+	MEM->init.rlen    = (RX_LOG_RING_SIZE << 13) |
+		(dvma_vtob(MEM->rx_head) >> 16);
+	MEM->init.tdra = dvma_vtob(MEM->tx_head);
+	MEM->init.tlen    = (TX_LOG_RING_SIZE << 13) |
+		(dvma_vtob(MEM->tx_head) >> 16);
+
+
+	/* tell the lance the address of its init block */
+	REGA(CSR1) = dvma_vtob(&(MEM->init));
+	REGA(CSR2) = dvma_vtob(&(MEM->init)) >> 16;
+
+#ifdef CONFIG_SUN3X
+	REGA(CSR3) = CSR3_BSWP | CSR3_ACON | CSR3_BCON;
+#else
+	REGA(CSR3) = CSR3_BSWP;
+#endif
+
 }
 
 
@@ -512,7 +557,7 @@
 	   stopping the queue for a bit... */
      
 	netif_stop_queue(dev);
-
+	
 	if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
 		printk( "%s: tx queue lock!.\n", dev->name);
 		/* don't clear dev->tbusy flag. */
@@ -520,13 +565,22 @@
 	}
 
 	AREG = CSR0;
-//	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
-//				  dev->name, DREG ));
-	
+  	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
+  				  dev->name, DREG ));
+
+#ifdef CONFIG_SUN3X
+	/* this weirdness doesn't appear on sun3... */
+	if(!(DREG & CSR0_INIT)) {
+		DPRINTK( 1, ("INIT not set, reinitializing...\n"));
+		REGA( CSR0 ) = CSR0_STOP;
+		lance_init_ring(dev);
+		REGA( CSR0 ) = CSR0_INIT | CSR0_STRT;
+	}
+#endif
 
 	/* Fill in a Tx ring entry */
 #if 0
-	if (lance_debug >= 3) {
+	if (lance_debug >= 2) {
 		u_char *p;
 		int i;
 		printk( "%s: TX pkt %d type 0x%04x from ", dev->name,
@@ -566,7 +620,10 @@
 	lp->stats.tx_bytes += skb->len;
 
 	/* Trigger an immediate send poll. */
-	REGA(CSR0) = CSR0_INEA | CSR0_TDMD;
+	REGA(CSR0) = CSR0_INEA | CSR0_TDMD | CSR0_STRT;
+	AREG = CSR0;
+  	DPRINTK( 2, ( "%s: lance_start_xmit() exiting, csr0 %4.4x.\n",
+  				  dev->name, DREG ));
 	dev->trans_start = jiffies;
 	dev_kfree_skb( skb );
 
@@ -597,14 +654,15 @@
 	if (in_interrupt)
 		DPRINTK( 2, ( "%s: Re-entering the interrupt handler.\n", dev->name ));
 	in_interrupt = 1;
-
+	
  still_more:
-
+	flush_cache_all();
+	
 	AREG = CSR0;
 	csr0 = DREG;
 
 	/* ack interrupts */
-	DREG = csr0 & (CSR0_TINT | CSR0_RINT);
+	DREG = csr0 & (CSR0_TINT | CSR0_RINT | CSR0_IDON);
 
 	/* clear errors */
 	if(csr0 & CSR0_ERR)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sunbmac.c linux/drivers/net/sunbmac.c
--- linux.orig/drivers/net/sunbmac.c	2001-10-30 23:08:11.000000000 +0000
+++ linux/drivers/net/sunbmac.c	2002-07-20 01:08:21.000000000 +0000
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -979,17 +980,14 @@
 	return &bp->enet_stats;
 }
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 static void bigmac_set_multicast(struct net_device *dev)
 {
 	struct bigmac *bp = (struct bigmac *) dev->priv;
 	unsigned long bregs = bp->bregs;
 	struct dev_mc_list *dmi = dev->mc_list;
 	char *addrs;
-	int i, j, bit, byte;
-	u32 tmp, crc, poly = CRC_POLYNOMIAL_LE;
+	int i;
+	u32 tmp, crc;
 
 	/* Disable the receiver.  The bit self-clears when
 	 * the operation is complete.
@@ -1022,17 +1020,7 @@
 			if (!(*addrs & 1))
 				continue;
 
-			crc = 0xffffffffU;
-			for (byte = 0; byte < 6; byte++) {
-				for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-					int test;
-
-					test = ((bit ^ crc) & 0x01);
-					crc >>= 1;
-					if (test)
-						crc = crc ^ poly;
-				}
-			}
+			crc = ether_crc_le(6, addrs);
 			crc >>= 26;
 			hash_table[crc >> 4] |= 1 << (crc & 0xf);
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sundance.c linux/drivers/net/sundance.c
--- linux.orig/drivers/net/sundance.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/sundance.c	2002-07-20 01:08:23.000000000 +0000
@@ -107,6 +107,7 @@
 #include <linux/init.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/crc32.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
@@ -636,7 +637,7 @@
 
 
 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
-static int eeprom_read(long ioaddr, int location)
+static int __devinit eeprom_read(long ioaddr, int location)
 {
 	int boguscnt = 1000;		/* Typical 190 ticks. */
 	writew(0x0200 | (location & 0xff), ioaddr + EECtrl);
@@ -1274,32 +1275,6 @@
 	return &np->stats;
 }
 
-/* The little-endian AUTODIN II ethernet CRC calculations.
-   A big-endian version is also available.
-   This is slow but compact code.  Do not use this routine for bulk data,
-   use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c.
-   Chips may use the upper or lower CRC bits, and may reverse and/or invert
-   them.  Select the endian-ness that results in minimal calculations.
-*/
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-	unsigned int crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-
 static void set_rx_mode(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sungem.c linux/drivers/net/sungem.c
--- linux.orig/drivers/net/sungem.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/sungem.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,7 +1,7 @@
-/* $Id: sungem.c,v 1.44.2.5 2002/02/01 21:45:52 davem Exp $
+/* $Id: sungem.c,v 1.44.2.22 2002/03/13 01:18:12 davem Exp $
  * sungem.c: Sun GEM ethernet driver.
  *
- * Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2000, 2001, 2002 David S. Miller (davem@redhat.com)
  * 
  * Support for Apple GMAC and assorted PHYs by
  * Benjamin Herrenscmidt (benh@kernel.crashing.org)
@@ -16,6 +16,8 @@
  *    I can at least detect gigabit with autoneg.
  */
 
+#include <linux/config.h>
+
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -37,6 +39,8 @@
 #include <linux/skbuff.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/random.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -66,8 +70,8 @@
 			 NETIF_MSG_LINK)
 
 #define DRV_NAME	"sungem"
-#define DRV_VERSION	"0.96"
-#define DRV_RELDATE	"11/17/01"
+#define DRV_VERSION	"0.97"
+#define DRV_RELDATE	"3/20/02"
 #define DRV_AUTHOR	"David S. Miller (davem@redhat.com)"
 
 static char version[] __devinitdata =
@@ -287,6 +291,105 @@
 	return 0;
 }
 
+/* When we get a RX fifo overflow, the RX unit in GEM is probably hung
+ * so we do the following.
+ *
+ * If any part of the reset goes wrong, we return 1 and that causes the
+ * whole chip to be reset.
+ */
+static int gem_rxmac_reset(struct gem *gp)
+{
+	struct net_device *dev = gp->dev;
+	int limit, i;
+	u64 desc_dma;
+	u32 val;
+
+	/* First, reset MAC RX. */
+	writel(gp->mac_rx_cfg & ~MAC_RXCFG_ENAB,
+	       gp->regs + MAC_RXCFG);
+	for (limit = 0; limit < 5000; limit++) {
+		if (!(readl(gp->regs + MAC_RXCFG) & MAC_RXCFG_ENAB))
+			break;
+		udelay(10);
+	}
+	if (limit == 5000) {
+		printk(KERN_ERR "%s: RX MAC will not disable, resetting whole "
+		       "chip.\n", dev->name);
+		return 1;
+	}
+
+	/* Second, disable RX DMA. */
+	writel(0, gp->regs + RXDMA_CFG);
+	for (limit = 0; limit < 5000; limit++) {
+		if (!(readl(gp->regs + RXDMA_CFG) & RXDMA_CFG_ENABLE))
+			break;
+		udelay(10);
+	}
+	if (limit == 5000) {
+		printk(KERN_ERR "%s: RX DMA will not disable, resetting whole "
+		       "chip.\n", dev->name);
+		return 1;
+	}
+
+	udelay(5000);
+
+	/* Execute RX reset command. */
+	writel(gp->swrst_base | GREG_SWRST_RXRST,
+	       gp->regs + GREG_SWRST);
+	for (limit = 0; limit < 5000; limit++) {
+		if (!(readl(gp->regs + GREG_SWRST) & GREG_SWRST_RXRST))
+			break;
+		udelay(10);
+	}
+	if (limit == 5000) {
+		printk(KERN_ERR "%s: RX reset command will not execute, resetting "
+		       "whole chip.\n", dev->name);
+		return 1;
+	}
+
+	/* Refresh the RX ring. */
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		struct gem_rxd *rxd = &gp->init_block->rxd[i];
+
+		if (gp->rx_skbs[i] == NULL) {
+			printk(KERN_ERR "%s: Parts of RX ring empty, resetting "
+			       "whole chip.\n", dev->name);
+			return 1;
+		}
+
+		rxd->status_word = cpu_to_le64(RXDCTRL_FRESH(gp));
+	}
+	gp->rx_new = gp->rx_old = 0;
+
+	/* Now we must reprogram the rest of RX unit. */
+	desc_dma = (u64) gp->gblock_dvma;
+	desc_dma += (INIT_BLOCK_TX_RING_SIZE * sizeof(struct gem_txd));
+	writel(desc_dma >> 32, gp->regs + RXDMA_DBHI);
+	writel(desc_dma & 0xffffffff, gp->regs + RXDMA_DBLOW);
+	writel(RX_RING_SIZE - 4, gp->regs + RXDMA_KICK);
+	val = (RXDMA_CFG_BASE | (RX_OFFSET << 10) |
+	       ((14 / 2) << 13) | RXDMA_CFG_FTHRESH_128);
+	writel(val, gp->regs + RXDMA_CFG);
+	if (readl(gp->regs + GREG_BIFCFG) & GREG_BIFCFG_M66EN)
+		writel(((5 & RXDMA_BLANK_IPKTS) |
+			((8 << 12) & RXDMA_BLANK_ITIME)),
+		       gp->regs + RXDMA_BLANK);
+	else
+		writel(((5 & RXDMA_BLANK_IPKTS) |
+			((4 << 12) & RXDMA_BLANK_ITIME)),
+		       gp->regs + RXDMA_BLANK);
+	val  = (((gp->rx_pause_off / 64) << 0) & RXDMA_PTHRESH_OFF);
+	val |= (((gp->rx_pause_on / 64) << 12) & RXDMA_PTHRESH_ON);
+	writel(val, gp->regs + RXDMA_PTHRESH);
+	val = readl(gp->regs + RXDMA_CFG);
+	writel(val | RXDMA_CFG_ENABLE, gp->regs + RXDMA_CFG);
+	writel(MAC_RXSTAT_RCV, gp->regs + MAC_RXMASK);
+	val = readl(gp->regs + MAC_RXCFG);
+	writel(val | MAC_RXCFG_ENAB, gp->regs + MAC_RXCFG);
+
+	return 0;
+}
+
 static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_status)
 {
 	u32 rxmac_stat = readl(gp->regs + MAC_RXSTAT);
@@ -297,19 +400,10 @@
 			gp->dev->name, rxmac_stat);
 
 	if (rxmac_stat & MAC_RXSTAT_OFLW) {
-		u32 smac = readl(gp->regs + MAC_SMACHINE);
-
-		printk(KERN_ERR "%s: RX MAC fifo overflow smac[%08x].\n",
-		       dev->name, smac);
 		gp->net_stats.rx_over_errors++;
 		gp->net_stats.rx_fifo_errors++;
 
-		if (((smac >> 24) & 0x7) == 0x7) {
-			/* Due to a bug, the chip is hung in this case
-			 * and a full reset is necessary.
-			 */
-			ret = 1;
-		}
+		ret = gem_rxmac_reset(gp);
 	}
 
 	if (rxmac_stat & MAC_RXSTAT_ACE)
@@ -546,7 +640,7 @@
 	gp->tx_old = entry;
 
 	if (netif_queue_stopped(dev) &&
-	    TX_BUFFS_AVAIL(gp) > 0)
+	    TX_BUFFS_AVAIL(gp) > (MAX_SKB_FRAGS + 1))
 		netif_wake_queue(dev);
 }
 
@@ -721,7 +815,7 @@
 
 	spin_lock_irq(&gp->lock);
 
-	gp->reset_task_pending = 1;
+	gp->reset_task_pending = 2;
 	schedule_task(&gp->reset_task);
 
 	spin_unlock_irq(&gp->lock);
@@ -756,9 +850,12 @@
 
 	spin_lock_irq(&gp->lock);
 
+	/* This is a hard error, log it. */
 	if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) {
 		netif_stop_queue(dev);
 		spin_unlock_irq(&gp->lock);
+		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+		       dev->name);
 		return 1;
 	}
 
@@ -833,7 +930,7 @@
 	}
 
 	gp->tx_new = entry;
-	if (TX_BUFFS_AVAIL(gp) <= 0)
+	if (TX_BUFFS_AVAIL(gp) <= (MAX_SKB_FRAGS + 1))
 		netif_stop_queue(dev);
 
 	if (netif_msg_tx_queued(gp))
@@ -848,19 +945,28 @@
 }
 
 /* Jumbo-grams don't seem to work :-( */
+#define GEM_MIN_MTU	68
 #if 1
-#define MAX_MTU		1500
+#define GEM_MAX_MTU	1500
 #else
-#define MAX_MTU		9000
+#define GEM_MAX_MTU	9000
 #endif
 
 static int gem_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct gem *gp = dev->priv;
 
-	if (new_mtu < 0 || new_mtu > MAX_MTU)
+	if (new_mtu < GEM_MIN_MTU || new_mtu > GEM_MAX_MTU)
 		return -EINVAL;
 
+	if (!netif_running(dev) || !netif_device_present(dev)) {
+		/* We'll just catch it later when the
+		 * device is up'd or resumed.
+		 */
+		dev->mtu = new_mtu;
+		return 0;
+	}
+
 	spin_lock_irq(&gp->lock);
 	dev->mtu = new_mtu;
 	gp->reset_task_pending = 1;
@@ -874,6 +980,7 @@
 
 #define STOP_TRIES 32
 
+/* Must be invoked under gp->lock. */
 static void gem_stop(struct gem *gp)
 {
 	int limit;
@@ -883,7 +990,8 @@
 	writel(0xffffffff, gp->regs + GREG_IMASK);
 
 	/* Reset the chip */
-	writel(GREG_SWRST_TXRST | GREG_SWRST_RXRST, gp->regs + GREG_SWRST);
+	writel(gp->swrst_base | GREG_SWRST_TXRST | GREG_SWRST_RXRST,
+	       gp->regs + GREG_SWRST);
 
 	limit = STOP_TRIES;
 
@@ -898,6 +1006,7 @@
 		printk(KERN_ERR "gem: SW reset is ghetto.\n");
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_start_dma(struct gem *gp)
 {
 	unsigned long val;
@@ -933,6 +1042,7 @@
 	{ 1, 0, 1 },	/* 1000BT */
 };
 
+/* Must be invoked under gp->lock. */
 static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
 {
 	u16 ctl;
@@ -958,11 +1068,8 @@
 	}
 
 start_aneg:
-	spin_lock_irq(&gp->lock);
-	if (!gp->hw_running) {
-		spin_unlock_irq(&gp->lock);
+	if (!gp->hw_running)
 		return;
-	}
 
 	/* Configure PHY & start aneg */
 	ctl = phy_read(gp, MII_BMCR);
@@ -977,11 +1084,10 @@
 	phy_write(gp, MII_BMCR, ctl);
 
 	gp->timer_ticks = 0;
-	gp->link_timer.expires = jiffies + ((12 * HZ) / 10);
-	add_timer(&gp->link_timer);
-	spin_unlock_irq(&gp->lock);
+	mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10));
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_read_mii_link_mode(struct gem *gp, int *fd, int *spd, int *pause)
 {
 	u32 val;
@@ -1025,6 +1131,8 @@
 
 /* A link-up condition has occurred, initialize and enable the
  * rest of the chip.
+ *
+ * Must be invoked under gp->lock.
  */
 static void gem_set_link_modes(struct gem *gp)
 {
@@ -1105,6 +1213,20 @@
 			pause = 1;
 	}
 
+	if (netif_msg_link(gp)) {
+		if (pause) {
+			printk(KERN_INFO "%s: Pause is enabled "
+			       "(rxfifo: %d off: %d on: %d)\n",
+			       gp->dev->name,
+			       gp->rx_fifo_sz,
+			       gp->rx_pause_off,
+			       gp->rx_pause_on);
+		} else {
+			printk(KERN_INFO "%s: Pause is disabled\n",
+			       gp->dev->name);
+		}
+	}
+
 	if (!full_duplex)
 		writel(512, gp->regs + MAC_STIME);
 	else
@@ -1119,6 +1241,7 @@
 	gem_start_dma(gp);
 }
 
+/* Must be invoked under gp->lock. */
 static int gem_mdio_link_not_up(struct gem *gp)
 {
 	u16 val;
@@ -1162,7 +1285,7 @@
 	return 0;
 }
 
-static void gem_init_rings(struct gem *, int);
+static void gem_init_rings(struct gem *);
 static void gem_init_hw(struct gem *, int);
 
 static void gem_reset_task(void *data)
@@ -1173,25 +1296,27 @@
 	 * DMA stopped. Todo: Use this function for reset
 	 * on error as well.
 	 */
+
+	spin_lock_irq(&gp->lock);
+
 	if (gp->hw_running && gp->opened) {
 		/* Make sure we don't get interrupts or tx packets */
-		spin_lock_irq(&gp->lock);
-
 		netif_stop_queue(gp->dev);
 
 		writel(0xffffffff, gp->regs + GREG_IMASK);
 
-		spin_unlock_irq(&gp->lock);
-
 		/* Reset the chip & rings */
 		gem_stop(gp);
-		gem_init_rings(gp, 0);
+		gem_init_rings(gp);
+
 		gem_init_hw(gp,
 			    (gp->reset_task_pending == 2));
 
 		netif_wake_queue(gp->dev);
 	}
 	gp->reset_task_pending = 0;
+
+	spin_unlock_irq(&gp->lock);
 }
 
 static void gem_link_timer(unsigned long data)
@@ -1201,13 +1326,14 @@
 	if (!gp->hw_running)
 		return;
 
+	spin_lock_irq(&gp->lock);
+
 	/* If the link of task is still pending, we just
 	 * reschedule the link timer
 	 */
 	if (gp->reset_task_pending)
 		goto restart;
 	    	
-	spin_lock_irq(&gp->lock);
 	if (gp->phy_type == phy_mii_mdio0 ||
 	    gp->phy_type == phy_mii_mdio1) {
 		u16 val = phy_read(gp, MII_BMSR);
@@ -1252,16 +1378,15 @@
 				if (netif_msg_link(gp))
 					printk(KERN_INFO "%s: Link down\n",
 						gp->dev->name);
-				gp->reset_task_pending = 1;
+				gp->reset_task_pending = 2;
 				schedule_task(&gp->reset_task);
 				restart = 1;
 			} else if (++gp->timer_ticks > 10)
 				restart = gem_mdio_link_not_up(gp);
 
 			if (restart) {
-				spin_unlock_irq(&gp->lock);
 				gem_begin_auto_negotiation(gp, NULL);
-				return;
+				goto out_unlock;
 			}
 		}
 	} else {
@@ -1278,11 +1403,12 @@
 	}
 
 restart:
-	gp->link_timer.expires = jiffies + ((12 * HZ) / 10);
-	add_timer(&gp->link_timer);
+	mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10));
+out_unlock:
 	spin_unlock_irq(&gp->lock);
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_clean_rings(struct gem *gp)
 {
 	struct gem_init_block *gb = gp->init_block;
@@ -1316,7 +1442,9 @@
 			gp->tx_skbs[i] = NULL;
 
 			for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
-				txd = &gb->txd[i];
+				int ent = i & (TX_RING_SIZE - 1);
+
+				txd = &gb->txd[ent];
 				dma_addr = le64_to_cpu(txd->buffer);
 				pci_unmap_page(gp->pdev, dma_addr,
 					       le64_to_cpu(txd->control_word) &
@@ -1330,16 +1458,14 @@
 	}
 }
 
-static void gem_init_rings(struct gem *gp, int from_irq)
+/* Must be invoked under gp->lock. */
+static void gem_init_rings(struct gem *gp)
 {
 	struct gem_init_block *gb = gp->init_block;
 	struct net_device *dev = gp->dev;
-	int i, gfp_flags = GFP_KERNEL;
+	int i;
 	dma_addr_t dma_addr;
 
-	if (from_irq)
-		gfp_flags = GFP_ATOMIC;
-
 	gp->rx_new = gp->rx_old = gp->tx_new = gp->tx_old = 0;
 
 	gem_clean_rings(gp);
@@ -1348,7 +1474,7 @@
 		struct sk_buff *skb;
 		struct gem_rxd *rxd = &gb->rxd[i];
 
-		skb = gem_alloc_skb(RX_BUF_ALLOC_SIZE(gp), gfp_flags);
+		skb = gem_alloc_skb(RX_BUF_ALLOC_SIZE(gp), GFP_ATOMIC);
 		if (!skb) {
 			rxd->buffer = 0;
 			rxd->status_word = 0;
@@ -1377,6 +1503,7 @@
 	}
 }
 
+/* Must be invoked under gp->lock. */
 static int gem_reset_one_mii_phy(struct gem *gp, int phy_addr)
 {
 	u16 val;
@@ -1401,6 +1528,7 @@
 	return (limit <= 0);
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_bcm5201_phy(struct gem *gp)
 {
 	u16 data;
@@ -1410,6 +1538,7 @@
 	phy_write(gp, MII_BCM5201_MULTIPHY, data);
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_bcm5400_phy(struct gem *gp)
 {
 	u16 data;
@@ -1437,6 +1566,7 @@
 	phy_write(gp, MII_BCM5400_AUXCONTROL, data);
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_bcm5401_phy(struct gem *gp)
 {
 	u16 data;
@@ -1451,6 +1581,9 @@
 		 * WARNING ! OF and Darwin don't agree on the
 		 * register addresses. OF seem to interpret the
 		 * register numbers below as decimal
+		 *
+		 * Note: This should (and does) match tg3_init_5401phy_dsp
+		 *       in the tg3.c driver. -DaveM
 		 */
 		phy_write(gp, 0x18, 0x0c20);
 		phy_write(gp, 0x17, 0x0012);
@@ -1480,6 +1613,7 @@
 	__phy_write(gp, MII_BCM5201_MULTIPHY, data, 0x1f);
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_bcm5411_phy(struct gem *gp)
 {
 	u16 data;
@@ -1506,6 +1640,7 @@
 	phy_write(gp, MII_BCM5400_GB_CONTROL, data);
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_phy(struct gem *gp)
 {
 	u32 mifcfg;
@@ -1654,7 +1789,9 @@
 		val &= ~(PCS_CFG_ENABLE | PCS_CFG_TO);
 		writel(val, gp->regs + PCS_CFG);
 
-		/* Advertise all capabilities. */
+		/* Advertise all capabilities except assymetric
+		 * pause.
+		 */
 		val = readl(gp->regs + PCS_MIIADV);
 		val |= (PCS_MIIADV_FD | PCS_MIIADV_HD |
 			PCS_MIIADV_SP | PCS_MIIADV_AP);
@@ -1689,9 +1826,9 @@
 	if (gp->phy_mod != phymod_bcm5400 && gp->phy_mod != phymod_bcm5401 &&
 	    gp->phy_mod != phymod_bcm5411)
 	    	gp->link_cntl &= ~BMCR_SPD2;
-	    
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_dma(struct gem *gp)
 {
 	u64 desc_dma = (u64) gp->gblock_dvma;
@@ -1707,7 +1844,7 @@
 	writel(0, gp->regs + TXDMA_KICK);
 
 	val = (RXDMA_CFG_BASE | (RX_OFFSET << 10) |
-	       ((14 / 2) << 13) | RXDMA_CFG_FTHRESH_512);
+	       ((14 / 2) << 13) | RXDMA_CFG_FTHRESH_128);
 	writel(val, gp->regs + RXDMA_CFG);
 
 	writel(desc_dma >> 32, gp->regs + RXDMA_DBHI);
@@ -1729,8 +1866,7 @@
 		       gp->regs + RXDMA_BLANK);
 }
 
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
+/* Must be invoked under gp->lock. */
 static u32
 gem_setup_multicast(struct gem *gp)
 {
@@ -1746,9 +1882,9 @@
 		rxcfg |= MAC_RXCFG_PROM;
 	} else {
 		u16 hash_table[16];
-		u32 crc, poly = CRC_POLYNOMIAL_LE;
+		u32 crc;
 		struct dev_mc_list *dmi = gp->dev->mc_list;
-		int i, j, bit, byte;
+		int i;
 
 		for (i = 0; i < 16; i++)
 			hash_table[i] = 0;
@@ -1761,17 +1897,7 @@
 			if (!(*addrs & 1))
 				continue;
 
-			crc = 0xffffffffU;
-			for (byte = 0; byte < 6; byte++) {
-				for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-					int test;
-
-					test = ((bit ^ crc) & 0x01);
-					crc >>= 1;
-					if (test)
-						crc = crc ^ poly;
-				}
-			}
+ 			crc = ether_crc_le(6, addrs);
 			crc >>= 24;
 			hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
 		}
@@ -1783,10 +1909,10 @@
 	return rxcfg;
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_mac(struct gem *gp)
 {
 	unsigned char *e = &gp->dev->dev_addr[0];
-	u32 rxcfg;
 
 	if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
 	    gp->pdev->device == PCI_DEVICE_ID_SUN_GEM)
@@ -1797,7 +1923,10 @@
 	writel(0x04, gp->regs + MAC_IPG2);
 	writel(0x40, gp->regs + MAC_STIME);
 	writel(0x40, gp->regs + MAC_MINFSZ);
-	writel(0x20000000 | (gp->dev->mtu + 18), gp->regs + MAC_MAXFSZ);
+
+	/* Ethernet payload + header + FCS + optional VLAN tag. */
+	writel(0x20000000 | (gp->dev->mtu + ETH_HLEN + 4 + 4), gp->regs + MAC_MAXFSZ);
+
 	writel(0x07, gp->regs + MAC_PASIZE);
 	writel(0x04, gp->regs + MAC_JAMSIZE);
 	writel(0x10, gp->regs + MAC_ATTLIM);
@@ -1823,7 +1952,7 @@
 	writel(0, gp->regs + MAC_AF21MSK);
 	writel(0, gp->regs + MAC_AF0MSK);
 
-	rxcfg = gem_setup_multicast(gp);
+	gp->mac_rx_cfg = gem_setup_multicast(gp);
 
 	writel(0, gp->regs + MAC_NCOLL);
 	writel(0, gp->regs + MAC_FASUCC);
@@ -1841,7 +1970,7 @@
 	 * them once a link is established.
 	 */
 	writel(0, gp->regs + MAC_TXCFG);
-	writel(rxcfg, gp->regs + MAC_RXCFG);
+	writel(gp->mac_rx_cfg, gp->regs + MAC_RXCFG);
 	writel(0, gp->regs + MAC_MCCFG);
 	writel(0, gp->regs + MAC_XIFCFG);
 
@@ -1858,6 +1987,7 @@
 	writel(0xffffffff, gp->regs + MAC_MCMASK);
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_pause_thresholds(struct gem *gp)
 {
 	/* Calculate pause thresholds.  Setting the OFF threshold to the
@@ -1868,8 +1998,9 @@
 	if (gp->rx_fifo_sz <= (2 * 1024)) {
 		gp->rx_pause_off = gp->rx_pause_on = gp->rx_fifo_sz;
 	} else {
-		int off = (gp->rx_fifo_sz - (5 * 1024));
-		int on = off - 1024;
+		int max_frame = (gp->dev->mtu + ETH_HLEN + 4 + 4 + 64) & ~63;
+		int off = (gp->rx_fifo_sz - (max_frame * 2));
+		int on = off - max_frame;
 
 		gp->rx_pause_off = off;
 		gp->rx_pause_on = on;
@@ -1878,7 +2009,10 @@
 	{
 		u32 cfg;
 
-		cfg  = GREG_CFG_IBURST;
+		cfg  = 0;
+#if !defined(CONFIG_SPARC64) && !defined(CONFIG_ALPHA)
+		cfg |= GREG_CFG_IBURST;
+#endif
 		cfg |= ((31 << 1) & GREG_CFG_TXDMALIM);
 		cfg |= ((31 << 6) & GREG_CFG_RXDMALIM);
 		writel(cfg, gp->regs + GREG_CFG);
@@ -1898,6 +2032,7 @@
 		gp->phy_type = phy_mii_mdio0;
 		gp->tx_fifo_sz = readl(gp->regs + TXDMA_FSZ) * 64;
 		gp->rx_fifo_sz = readl(gp->regs + RXDMA_FSZ) * 64;
+		gp->swrst_base = 0;
 		return 0;
 	}
 
@@ -1960,6 +2095,7 @@
 				       gp->tx_fifo_sz, gp->rx_fifo_sz);
 				return -1;
 			}
+			gp->swrst_base = 0;
 		} else {
 			if (gp->tx_fifo_sz != (2 * 1024) ||
 			    gp->rx_fifo_sz != (2 * 1024)) {
@@ -1967,12 +2103,14 @@
 				       gp->tx_fifo_sz, gp->rx_fifo_sz);
 				return -1;
 			}
+			gp->swrst_base = (64 / 4) << GREG_SWRST_CACHE_SHIFT;
 		}
 	}
 
 	return 0;
 }
 
+/* Must be invoked under gp->lock. */
 static void gem_init_hw(struct gem *gp, int restart_link)
 {
 	/* On Apple's gmac, I initialize the PHY only after
@@ -1983,25 +2121,20 @@
 	 */
 	if (restart_link)
 		gem_init_phy(gp);
+	gem_init_pause_thresholds(gp);
 	gem_init_dma(gp);
 	gem_init_mac(gp);
-	gem_init_pause_thresholds(gp);
 
-	spin_lock_irq(&gp->lock);
 	if (restart_link) {
 		/* Default aneg parameters */
 		gp->timer_ticks = 0;
 		gp->lstate = link_down;
 
-		spin_unlock_irq(&gp->lock);
-
 		/* Can I advertise gigabit here ? I'd need BCM PHY docs... */
 		gem_begin_auto_negotiation(gp, NULL);
 	} else {
 		if (gp->lstate == link_up)
 			gem_set_link_modes(gp);
-
-		spin_unlock_irq(&gp->lock);
 	}
 }
 
@@ -2046,6 +2179,7 @@
 
 #endif /* CONFIG_ALL_PPC */
 
+/* Must be invoked under gp->lock. */
 static void gem_stop_phy(struct gem *gp)
 {
 	u32 mifcfg;
@@ -2117,14 +2251,21 @@
 		schedule();
 	
 	/* Actually stop the chip */
+	spin_lock_irq(&gp->lock);
 	if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
 		gem_stop_phy(gp);
+
+		spin_unlock_irq(&gp->lock);
+
 #ifdef CONFIG_ALL_PPC
 		/* Power down the chip */
 		gem_apple_powerdown(gp);
 #endif /* CONFIG_ALL_PPC */
-	} else
+	} else {
 		gem_stop(gp);
+
+		spin_unlock_irq(&gp->lock);
+	}
 }
 
 static void gem_pm_task(void *data)
@@ -2159,14 +2300,19 @@
 static int gem_open(struct net_device *dev)
 {
 	struct gem *gp = dev->priv;
-	int hw_was_up = gp->hw_running;
+	int hw_was_up;
 
 	down(&gp->pm_sem);
 
+	hw_was_up = gp->hw_running;
+
 	/* Stop the PM timer/task */
 	del_timer(&gp->pm_timer);
 	flush_scheduled_tasks();
 
+	/* The power-management semaphore protects the hw_running
+	 * etc. state so it is safe to do this bit without gp->lock
+	 */
 	if (!gp->hw_running) {
 #ifdef CONFIG_ALL_PPC
 		/* First, we need to bring up the chip */
@@ -2175,18 +2321,26 @@
 			gem_check_invariants(gp);
 		}
 #endif /* CONFIG_ALL_PPC */
+
 		/* Reset the chip */
+		spin_lock_irq(&gp->lock);
 		gem_stop(gp);
+		spin_unlock_irq(&gp->lock);
 
 		gp->hw_running = 1;
 	}
 
+	spin_lock_irq(&gp->lock);
+
 	/* We can now request the interrupt as we know it's masked
 	 * on the controller
 	 */
 	if (request_irq(gp->pdev->irq, gem_interrupt,
 			SA_SHIRQ, dev->name, (void *)dev)) {
+		spin_unlock_irq(&gp->lock);
+
 		printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
+
 #ifdef CONFIG_ALL_PPC
 		if (!hw_was_up && gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
 			gem_apple_powerdown(gp);
@@ -2200,13 +2354,15 @@
 	}
 
 	/* Allocate & setup ring buffers */
-	gem_init_rings(gp, 0);
+	gem_init_rings(gp);
 
 	/* Init & setup chip hardware */
 	gem_init_hw(gp, !hw_was_up);
 
 	gp->opened = 1;
 
+	spin_unlock_irq(&gp->lock);
+
 	up(&gp->pm_sem);
 
 	return 0;
@@ -2226,8 +2382,6 @@
 	writel(0xffffffff, gp->regs + GREG_IMASK);
 	netif_stop_queue(dev);
 
-	spin_unlock_irq(&gp->lock);
-
 	/* Stop chip */
 	gem_stop(gp);
 
@@ -2237,6 +2391,8 @@
 	/* Bye, the pm timer will finish the job */
 	free_irq(gp->pdev->irq, (void *) dev);
 
+	spin_unlock_irq(&gp->lock);
+
 	/* Fire the PM timer that will shut us down in about 10 seconds */
 	gp->pm_timer.expires = jiffies + 10*HZ;
 	add_timer(&gp->pm_timer);
@@ -2262,21 +2418,21 @@
 	
 	/* If the driver is opened, we stop the DMA */
 	if (gp->opened) {
+		spin_lock_irq(&gp->lock);
+
 		/* Stop traffic, mark us closed */
 		netif_device_detach(dev);
 
-		spin_lock_irq(&gp->lock);
-
 		writel(0xffffffff, gp->regs + GREG_IMASK);
 
-		spin_unlock_irq(&gp->lock);
-
 		/* Stop chip */
 		gem_stop(gp);
 
 		/* Get rid of ring buffers */
 		gem_clean_rings(gp);
 
+		spin_unlock_irq(&gp->lock);
+
 		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
 			disable_irq(gp->pdev->irq);
 	}
@@ -2307,10 +2463,15 @@
 			gem_check_invariants(gp);
 		}
 #endif /* CONFIG_ALL_PPC */
+		spin_lock_irq(&gp->lock);
+
 		gem_stop(gp);
 		gp->hw_running = 1;
-		gem_init_rings(gp, 0);
+		gem_init_rings(gp);
 		gem_init_hw(gp, 1);
+
+		spin_unlock_irq(&gp->lock);
+
 		netif_device_attach(dev);
 		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
 			enable_irq(gp->pdev->irq);
@@ -2326,6 +2487,8 @@
 	struct gem *gp = dev->priv;
 	struct net_device_stats *stats = &gp->net_stats;
 
+	spin_lock_irq(&gp->lock);
+
 	if (gp->hw_running) {
 		stats->rx_crc_errors += readl(gp->regs + MAC_FCSERR);
 		writel(0, gp->regs + MAC_FCSERR);
@@ -2343,6 +2506,9 @@
 		writel(0, gp->regs + MAC_ECOLL);
 		writel(0, gp->regs + MAC_LCOLL);
 	}
+
+	spin_unlock_irq(&gp->lock);
+
 	return &gp->net_stats;
 }
 
@@ -2355,10 +2521,12 @@
 	if (!gp->hw_running)
 		return;
 		
+	spin_lock_irq(&gp->lock);
+
 	netif_stop_queue(dev);
 
 	rxcfg = readl(gp->regs + MAC_RXCFG);
-	rxcfg_new = gem_setup_multicast(gp);
+	gp->mac_rx_cfg = rxcfg_new = gem_setup_multicast(gp);
 	
 	writel(rxcfg & ~MAC_RXCFG_ENAB, gp->regs + MAC_RXCFG);
 	while (readl(gp->regs + MAC_RXCFG) & MAC_RXCFG_ENAB) {
@@ -2372,8 +2540,9 @@
 
 	writel(rxcfg, gp->regs + MAC_RXCFG);
 
-	/* Hrm... we may walk on the reset task here... */
 	netif_wake_queue(dev);
+
+	spin_unlock_irq(&gp->lock);
 }
 
 /* Eventually add support for changing the advertisement
@@ -2422,11 +2591,13 @@
 		ecmd.phy_address = 0; /* XXX fixed PHYAD */
 
 		/* Record PHY settings if HW is on. */
+		spin_lock_irq(&gp->lock);
 		if (gp->hw_running) {
 			bmcr = phy_read(gp, MII_BMCR);
 			gem_read_mii_link_mode(gp, &full_duplex, &speed, &pause);
 		} else
 			bmcr = 0;
+		spin_unlock_irq(&gp->lock);
 		if (bmcr & BMCR_ANENABLE) {
 			ecmd.autoneg = AUTONEG_ENABLE;
 			ecmd.speed = speed == 10 ? SPEED_10 : (speed == 1000 ? SPEED_1000 : SPEED_100);
@@ -2460,18 +2631,22 @@
 		      ecmd.duplex != DUPLEX_FULL)))
 			return -EINVAL;
 
-		/* Apply settings and restart link process */
-		if (gp->hw_running)
-			del_timer(&gp->link_timer);
+		/* Apply settings and restart link process. */
+		spin_lock_irq(&gp->lock);
 		gem_begin_auto_negotiation(gp, &ecmd);
+		spin_unlock_irq(&gp->lock);
+
 		return 0;
 
 	case ETHTOOL_NWAY_RST:
 		if ((gp->link_cntl & BMCR_ANENABLE) == 0)
 			return -EINVAL;
-		if (gp->hw_running)
-			del_timer(&gp->link_timer);
+
+		/* Restart link process. */
+		spin_lock_irq(&gp->lock);
 		gem_begin_auto_negotiation(gp, NULL);
+		spin_unlock_irq(&gp->lock);
+
 		return 0;
 
 	case ETHTOOL_GWOL:
@@ -2587,13 +2762,74 @@
 	return rc;
 }
 
+#if (!defined(__sparc__) && !defined(CONFIG_ALL_PPC))
+/* Fetch MAC address from vital product data of PCI ROM. */
+static void find_eth_addr_in_vpd(void *rom_base, int len, unsigned char *dev_addr)
+{
+	int this_offset;
+
+	for (this_offset = 0x20; this_offset < len; this_offset++) {
+		void *p = rom_base + this_offset;
+		int i;
+
+		if (readb(p + 0) != 0x90 ||
+		    readb(p + 1) != 0x00 ||
+		    readb(p + 2) != 0x09 ||
+		    readb(p + 3) != 0x4e ||
+		    readb(p + 4) != 0x41 ||
+		    readb(p + 5) != 0x06)
+			continue;
+
+		this_offset += 6;
+		p += 6;
+
+		for (i = 0; i < 6; i++)
+			dev_addr[i] = readb(p + i);
+		break;
+	}
+}
+
+static void get_gem_mac_nonobp(struct pci_dev *pdev, unsigned char *dev_addr)
+{
+	u32 rom_reg_orig;
+	void *p;
+
+	if (pdev->resource[PCI_ROM_RESOURCE].parent == NULL) {
+		if (pci_assign_resource(pdev, PCI_ROM_RESOURCE) < 0)
+			goto use_random;
+	}
+
+	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_reg_orig);
+	pci_write_config_dword(pdev, pdev->rom_base_reg,
+			       rom_reg_orig | PCI_ROM_ADDRESS_ENABLE);
+
+	p = ioremap(pci_resource_start(pdev, PCI_ROM_RESOURCE), (64 * 1024));
+	if (p != NULL && readb(p) == 0x55 && readb(p + 1) == 0xaa)
+		find_eth_addr_in_vpd(p, (64 * 1024), dev_addr);
+
+	if (p != NULL)
+		iounmap(p);
+
+	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_reg_orig);
+	return;
+
+use_random:
+	/* Sun MAC prefix then 3 random bytes. */
+	dev_addr[0] = 0x08;
+	dev_addr[1] = 0x00;
+	dev_addr[2] = 0x20;
+	get_random_bytes(dev_addr + 3, 3);
+	return;
+}
+#endif /* not Sparc and not PPC */
+
 static int __devinit gem_get_device_address(struct gem *gp)
 {
 #if defined(__sparc__) || defined(CONFIG_ALL_PPC)
 	struct net_device *dev = gp->dev;
 #endif
 
-#ifdef __sparc__
+#if defined(__sparc__)
 	struct pci_dev *pdev = gp->pdev;
 	struct pcidev_cookie *pcp = pdev->sysdata;
 	int node = -1;
@@ -2608,8 +2844,7 @@
 	}
 	if (node == -1)
 		memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
-#endif
-#ifdef CONFIG_ALL_PPC
+#elif defined(CONFIG_ALL_PPC)
 	unsigned char *addr;
 
 	addr = get_property(gp->of_node, "local-mac-address", NULL);
@@ -2619,6 +2854,8 @@
 		return -1;
 	}
 	memcpy(dev->dev_addr, addr, MAX_ADDR_LEN);
+#else
+	get_gem_mac_nonobp(gp->pdev, gp->dev->dev_addr);
 #endif
 	return 0;
 }
@@ -2681,21 +2918,21 @@
 		return -ENODEV;
 	}
 
-	dev = init_etherdev(NULL, sizeof(*gp));
+	dev = alloc_etherdev(sizeof(*gp));
 	if (!dev) {
-		printk(KERN_ERR PFX "Etherdev init failed, aborting.\n");
+		printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
 		return -ENOMEM;
 	}
 	SET_MODULE_OWNER(dev);
 
-	if (!request_mem_region(gemreg_base, gemreg_len, dev->name)) {
-		printk(KERN_ERR PFX "MMIO resource (0x%lx@0x%lx) unavailable, "
-		       "aborting.\n", gemreg_base, gemreg_len);
+	gp = dev->priv;
+
+	if (pci_request_regions(pdev, dev->name)) {
+		printk(KERN_ERR PFX "Cannot obtain PCI resources, "
+		       "aborting.\n");
 		goto err_out_free_netdev;
 	}
 
-	gp = dev->priv;
-
 	gp->pdev = pdev;
 	dev->base_addr = (long) pdev;
 	gp->dev = dev;
@@ -2728,7 +2965,7 @@
 	if (gp->regs == 0UL) {
 		printk(KERN_ERR PFX "Cannot map device registers, "
 		       "aborting.\n");
-		goto err_out_free_mmio_res;
+		goto err_out_free_res;
 	}
 
 	/* On Apple, we power the chip up now in order for check
@@ -2739,12 +2976,18 @@
 	if (pdev->vendor == PCI_VENDOR_ID_APPLE)
 		gem_apple_powerup(gp);
 #endif
+	spin_lock_irq(&gp->lock);
 	gem_stop(gp);
+	spin_unlock_irq(&gp->lock);
+
 	if (gem_check_invariants(gp))
 		goto err_out_iounmap;
+
+	spin_lock_irq(&gp->lock);
 	gp->hw_running = 1;
 	gem_init_phy(gp);
 	gem_begin_auto_negotiation(gp, NULL);
+	spin_unlock_irq(&gp->lock);
 
 	/* It is guarenteed that the returned buffer will be at least
 	 * PAGE_SIZE aligned.
@@ -2758,22 +3001,28 @@
 		goto err_out_iounmap;
 	}
 
-	pci_set_drvdata(pdev, dev);
-
-	printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet ",
-	       dev->name);
-
 #ifdef CONFIG_ALL_PPC
 	gp->of_node = pci_device_to_OF_node(pdev);
 #endif	
 	if (gem_get_device_address(gp))
-		goto err_out_iounmap;
+		goto err_out_free_consistent;
+
+	if (register_netdev(dev)) {
+		printk(KERN_ERR PFX "Cannot register net device, "
+		       "aborting.\n");
+		goto err_out_free_consistent;
+	}
+
+	printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet ",
+	       dev->name);
 
 	for (i = 0; i < 6; i++)
 		printk("%2.2x%c", dev->dev_addr[i],
 		       i == 5 ? ' ' : ':');
 	printk("\n");
 
+	pci_set_drvdata(pdev, dev);
+
 	dev->open = gem_open;
 	dev->stop = gem_close;
 	dev->hard_start_xmit = gem_start_xmit;
@@ -2797,6 +3046,12 @@
 
 	return 0;
 
+err_out_free_consistent:
+	pci_free_consistent(pdev,
+			    sizeof(struct gem_init_block),
+			    gp->init_block,
+			    gp->gblock_dvma);
+
 err_out_iounmap:
 	down(&gp->pm_sem);
 	/* Stop the PM timer & task */
@@ -2805,13 +3060,13 @@
 	if (gp->hw_running)
 		gem_shutdown(gp);
 	up(&gp->pm_sem);
+
 	iounmap((void *) gp->regs);
 
-err_out_free_mmio_res:
-	release_mem_region(gemreg_base, gemreg_len);
+err_out_free_res:
+	pci_release_regions(pdev);
 
 err_out_free_netdev:
-	unregister_netdev(dev);
 	kfree(dev);
 
 	return -ENODEV;
@@ -2840,8 +3095,7 @@
 				    gp->init_block,
 				    gp->gblock_dvma);
 		iounmap((void *) gp->regs);
-		release_mem_region(pci_resource_start(pdev, 0),
-				   pci_resource_len(pdev, 0));
+		pci_release_regions(pdev);
 		kfree(dev);
 
 		pci_set_drvdata(pdev, NULL);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sungem.h linux/drivers/net/sungem.h
--- linux.orig/drivers/net/sungem.h	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/sungem.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: sungem.h,v 1.10.2.2 2002/01/23 15:40:02 davem Exp $
+/* $Id: sungem.h,v 1.10.2.4 2002/03/11 08:54:48 davem Exp $
  * sungem.h: Definitions for Sun GEM ethernet driver.
  *
  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
@@ -94,6 +94,8 @@
 #define GREG_SWRST_TXRST	0x00000001	/* TX Software Reset		*/
 #define GREG_SWRST_RXRST	0x00000002	/* RX Software Reset		*/
 #define GREG_SWRST_RSTOUT	0x00000004	/* Force RST# pin active	*/
+#define GREG_SWRST_CACHESIZE	0x00ff0000	/* RIO only: cache line size	*/
+#define GREG_SWRST_CACHE_SHIFT	16
 
 /* TX DMA Registers */
 #define TXDMA_KICK	0x2000UL	/* TX Kick Register		*/
@@ -986,6 +988,9 @@
 	int			mii_phy_addr;
 	int			gigabit_capable;
 
+	u32			mac_rx_cfg;
+	u32			swrst_base;
+
 	/* Autoneg & PHY control */
 	int			link_cntl;
 	int			link_advertise;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sunhme.c linux/drivers/net/sunhme.c
--- linux.orig/drivers/net/sunhme.c	2001-10-12 22:35:53.000000000 +0000
+++ linux/drivers/net/sunhme.c	2002-07-20 01:08:32.000000000 +0000
@@ -3,7 +3,7 @@
  *           auto carrier detecting ethernet driver.  Also known as the
  *           "Happy Meal Ethernet" found on SunSwift SBUS cards.
  *
- * Copyright (C) 1996, 1998, 1999 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996, 1998, 1999, 2002 David S. Miller (davem@redhat.com)
  *
  * Changes :
  * 2000/11/11 Willy Tarreau <willy AT meta-x.org>
@@ -14,7 +14,7 @@
  */
 
 static char version[] =
-        "sunhme.c:v1.99 12/Sep/99 David S. Miller (davem@redhat.com)\n";
+        "sunhme.c:v2.01 26/Mar/2002 David S. Miller (davem@redhat.com)\n";
 
 #include <linux/module.h>
 
@@ -33,6 +33,8 @@
 #include <linux/init.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/crc32.h>
+#include <linux/random.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -695,7 +697,7 @@
 	return 1;
 }
 
-static int happy_meal_init(struct happy_meal *hp, int from_irq);
+static int happy_meal_init(struct happy_meal *hp);
 
 static int is_lucent_phy(struct happy_meal *hp)
 {
@@ -706,12 +708,8 @@
 	mr2 = happy_meal_tcvr_read(hp, tregs, 2);
 	mr3 = happy_meal_tcvr_read(hp, tregs, 3);
 	if ((mr2 & 0xffff) == 0x0180 &&
-	    ((mr3 & 0xffff) >> 10) == 0x1d) {
-#if 0
-		printk("HMEDEBUG: Lucent PHY detected.\n");
-#endif
+	    ((mr3 & 0xffff) >> 10) == 0x1d)
 		ret = 1;
-	}
 
 	return ret;
 }
@@ -722,6 +720,8 @@
 	unsigned long tregs = hp->tcvregs;
 	int restart_timer = 0;
 
+	spin_lock_irq(&hp->happy_lock);
+
 	hp->timer_ticks++;
 	switch(hp->timer_state) {
 	case arbwait:
@@ -851,13 +851,13 @@
 					printk(KERN_NOTICE "%s: Link down, cable problem?\n",
 					       hp->dev->name);
 
-					ret = happy_meal_init(hp, 0);
+					ret = happy_meal_init(hp);
 					if (ret) {
 						/* ho hum... */
 						printk(KERN_ERR "%s: Error, cannot re-init the "
 						       "Happy Meal.\n", hp->dev->name);
 					}
-					return;
+					goto out;
 				}
 				if (!is_lucent_phy(hp)) {
 					hp->sw_csconfig = happy_meal_tcvr_read(hp, tregs,
@@ -889,11 +889,15 @@
 		hp->happy_timer.expires = jiffies + ((12 * HZ)/10); /* 1.2 sec. */
 		add_timer(&hp->happy_timer);
 	}
+
+out:
+	spin_unlock_irq(&hp->happy_lock);
 }
 
 #define TX_RESET_TRIES     32
 #define RX_RESET_TRIES     32
 
+/* hp->happy_lock must be held */
 static void happy_meal_tx_reset(struct happy_meal *hp, unsigned long bregs)
 {
 	int tries = TX_RESET_TRIES;
@@ -913,6 +917,7 @@
 	HMD(("done\n"));
 }
 
+/* hp->happy_lock must be held */
 static void happy_meal_rx_reset(struct happy_meal *hp, unsigned long bregs)
 {
 	int tries = RX_RESET_TRIES;
@@ -934,6 +939,7 @@
 
 #define STOP_TRIES         16
 
+/* hp->happy_lock must be held */
 static void happy_meal_stop(struct happy_meal *hp, unsigned long gregs)
 {
 	int tries = STOP_TRIES;
@@ -953,6 +959,7 @@
 	HMD(("done\n"));
 }
 
+/* hp->happy_lock must be held */
 static void happy_meal_get_counters(struct happy_meal *hp, unsigned long bregs)
 {
 	struct net_device_stats *stats = &hp->net_stats;
@@ -975,53 +982,7 @@
 	hme_write32(hp, bregs + BMAC_LTCTR, 0);
 }
 
-#if 0
-static void happy_meal_poll_start(struct happy_meal *hp, unsigned long tregs)
-{
-	u32 tmp;
-	int speed;
-
-	ASD(("happy_meal_poll_start: "));
-	if (!(hp->happy_flags & HFLAG_POLLENABLE)) {
-		HMD(("polling disabled, return\n"));
-		return;
-	}
-
-	/* Start the MIF polling on the external transceiver. */
-	ASD(("polling on, "));
-	tmp = hme_read32(hp, tregs + TCVR_CFG);
-	tmp &= ~(TCV_CFG_PDADDR | TCV_CFG_PREGADDR);
-	tmp |= ((hp->paddr & 0x1f) << 10);
-	tmp |= (TCV_PADDR_ETX << 3);
-	tmp |= TCV_CFG_PENABLE;
-	hme_write32(hp, tregs + TCVR_CFG, tmp);
-
-	/* Let the bits set. */
-	udelay(200);
-
-	/* We are polling now. */
-	ASD(("now polling, "));
-	hp->happy_flags |= HFLAG_POLL;
-
-	/* Clear the poll flags, get the basic status as of now. */
-	hp->poll_flag = 0;
-	hp->poll_data = hme_read32(hp, tregs + TCVR_STATUS) >> 16;
-
-	if (hp->happy_flags & HFLAG_AUTO)
-		speed = hp->auto_speed;
-	else
-		speed = hp->forced_speed;
-
-	/* Listen only for the MIF interrupts we want to hear. */
-	ASD(("mif ints on, "));
-	if (speed == 100)
-		hme_write32(hp, tregs + TCVR_IMASK, 0xfffb);
-	else
-		hme_write32(hp, tregs + TCVR_IMASK, 0xfff9);
-	ASD(("done\n"));
-}
-#endif
-
+/* hp->happy_lock must be held */
 static void happy_meal_poll_stop(struct happy_meal *hp, unsigned long tregs)
 {
 	ASD(("happy_meal_poll_stop: "));
@@ -1056,6 +1017,7 @@
 #define TCVR_RESET_TRIES       16 /* It should reset quickly        */
 #define TCVR_UNISOLATE_TRIES   32 /* Dis-isolation can take longer. */
 
+/* hp->happy_lock must be held */
 static int happy_meal_tcvr_reset(struct happy_meal *hp, unsigned long tregs)
 {
 	u32 tconfig;
@@ -1150,7 +1112,10 @@
 	return 0;
 }
 
-/* Figure out whether we have an internal or external transceiver. */
+/* Figure out whether we have an internal or external transceiver.
+ *
+ * hp->happy_lock must be held
+ */
 static void happy_meal_transceiver_check(struct happy_meal *hp, unsigned long tregs)
 {
 	unsigned long tconfig = hme_read32(hp, tregs + TCVR_CFG);
@@ -1302,14 +1267,12 @@
 	}
 }
 
-static void happy_meal_init_rings(struct happy_meal *hp, int from_irq)
+/* hp->happy_lock must be held */
+static void happy_meal_init_rings(struct happy_meal *hp)
 {
 	struct hmeal_init_block *hb = hp->happy_block;
 	struct net_device *dev = hp->dev;
-	int i, gfp_flags = GFP_KERNEL;
-
-	if (from_irq || in_interrupt())
-		gfp_flags = GFP_ATOMIC;
+	int i;
 
 	HMD(("happy_meal_init_rings: counters to zero, "));
 	hp->rx_new = hp->rx_old = hp->tx_new = hp->tx_old = 0;
@@ -1323,7 +1286,7 @@
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		struct sk_buff *skb;
 
-		skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, gfp_flags);
+		skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
 		if (!skb) {
 			hme_write_rxd(hp, &hb->happy_meal_rxd[i], 0, 0);
 			continue;
@@ -1346,6 +1309,7 @@
 	HMD(("done\n"));
 }
 
+/* hp->happy_lock must be held */
 static void happy_meal_begin_auto_negotiation(struct happy_meal *hp,
 					      unsigned long tregs,
 					      struct ethtool_cmd *ep)
@@ -1469,10 +1433,8 @@
 	add_timer(&hp->happy_timer);
 }
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
-static int happy_meal_init(struct happy_meal *hp, int from_irq)
+/* hp->happy_lock must be held */
+static int happy_meal_init(struct happy_meal *hp)
 {
 	unsigned long gregs        = hp->gregs;
 	unsigned long etxregs      = hp->etxregs;
@@ -1503,7 +1465,7 @@
 
 	/* Alloc and reset the tx/rx descriptor chains. */
 	HMD(("happy_meal_init: to happy_meal_init_rings\n"));
-	happy_meal_init_rings(hp, from_irq);
+	happy_meal_init_rings(hp);
 
 	/* Shut up the MIF. */
 	HMD(("happy_meal_init: Disable all MIF irqs (old[%08x]), ",
@@ -1583,8 +1545,8 @@
 		u16 hash_table[4];
 		struct dev_mc_list *dmi = hp->dev->mc_list;
 		char *addrs;
-		int i, j, bit, byte;
-		u32 crc, poly = CRC_POLYNOMIAL_LE;
+		int i;
+		u32 crc;
 
 		for (i = 0; i < 4; i++)
 			hash_table[i] = 0;
@@ -1596,17 +1558,7 @@
 			if (!(*addrs & 1))
 				continue;
 
-			crc = 0xffffffffU;
-			for (byte = 0; byte < 6; byte++) {
-				for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-					int test;
-
-					test = ((bit ^ crc) & 0x01);
-					crc >>= 1;
-					if (test)
-						crc = crc ^ poly;
-				}
-			}
+			crc = ether_crc_le(6, addrs);
 			crc >>= 26;
 			hash_table[crc >> 4] |= 1 << (crc & 0xf);
 		}
@@ -1623,12 +1575,23 @@
 
 	/* Set the RX and TX ring ptrs. */
 	HMD(("ring ptrs rxr[%08x] txr[%08x]\n",
-	     (hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)),
-	     (hp->hblock_dvma + hblock_offset(happy_meal_txd, 0))));
+	     ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)),
+	     ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_txd, 0))));
 	hme_write32(hp, erxregs + ERX_RING,
-		    (hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)));
+		    ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)));
 	hme_write32(hp, etxregs + ETX_RING,
-		    (hp->hblock_dvma + hblock_offset(happy_meal_txd, 0)));
+		    ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_txd, 0)));
+
+	/* Parity issues in the ERX unit of some HME revisions can cause some
+	 * registers to not be written unless their parity is even.  Detect such
+	 * lost writes and simply rewrite with a low bit set (which will be ignored
+	 * since the rxring needs to be 2K aligned).
+	 */
+	if (hme_read32(hp, erxregs + ERX_RING) !=
+	    ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)))
+		hme_write32(hp, erxregs + ERX_RING,
+			    ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0))
+			    | 0x4);
 
 	/* Set the supported burst sizes. */
 	HMD(("happy_meal_init: old[%08x] bursts<",
@@ -1710,7 +1673,7 @@
 	/* Enable Big Mac hash table filter. */
 	HMD(("happy_meal_init: enable hash rx_cfg_old[%08x], ",
 	     hme_read32(hp, bregs + BMAC_RXCFG)));
-	rxcfg = BIGMAC_RXCFG_HENABLE;
+	rxcfg = BIGMAC_RXCFG_HENABLE | BIGMAC_RXCFG_REJME;
 	if (hp->dev->flags & IFF_PROMISC)
 		rxcfg |= BIGMAC_RXCFG_PMISC;
 	hme_write32(hp, bregs + BMAC_RXCFG, rxcfg);
@@ -1723,7 +1686,14 @@
 	regtmp = 0;
 	if (hp->happy_flags & HFLAG_FULL)
 		regtmp |= BIGMAC_TXCFG_FULLDPLX;
-	hme_write32(hp, bregs + BMAC_TXCFG, regtmp | BIGMAC_TXCFG_DGIVEUP);
+
+	/* Don't turn on the "don't give up" bit for now.  It could cause hme
+	 * to deadlock with the PHY if a Jabber occurs.
+	 */
+	hme_write32(hp, bregs + BMAC_TXCFG, regtmp /*| BIGMAC_TXCFG_DGIVEUP*/);
+
+	/* Give up after 16 TX attempts. */
+	hme_write32(hp, bregs + BMAC_ALIMIT, 16);
 
 	/* Enable the output drivers no matter what. */
 	regtmp = BIGMAC_XCFG_ODENABLE;
@@ -1756,6 +1726,7 @@
 	return 0;
 }
 
+/* hp->happy_lock must be held */
 static void happy_meal_set_initial_advertisement(struct happy_meal *hp)
 {
 	unsigned long tregs	= hp->tcvregs;
@@ -1813,6 +1784,8 @@
 
 /* Once status is latched (by happy_meal_interrupt) it is cleared by
  * the hardware, so we cannot re-read it and get a correct value.
+ *
+ * hp->happy_lock must be held
  */
 static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status)
 {
@@ -1921,12 +1894,13 @@
 
 	if (reset) {
 		printk(KERN_NOTICE "%s: Resetting...\n", hp->dev->name);
-		happy_meal_init(hp, 1);
+		happy_meal_init(hp);
 		return 1;
 	}
 	return 0;
 }
 
+/* hp->happy_lock must be held */
 static void happy_meal_mif_interrupt(struct happy_meal *hp)
 {
 	unsigned long tregs = hp->tcvregs;
@@ -1960,6 +1934,7 @@
 #define TXD(x)
 #endif
 
+/* hp->happy_lock must be held */
 static void happy_meal_tx(struct happy_meal *hp)
 {
 	struct happy_meal_txd *txbase = &hp->happy_block->happy_meal_txd[0];
@@ -1967,8 +1942,6 @@
 	struct net_device *dev = hp->dev;
 	int elem;
 
-	spin_lock(&hp->happy_lock);
-
 	elem = hp->tx_old;
 	TXD(("TX<"));
 	while (elem != hp->tx_new) {
@@ -2012,10 +1985,8 @@
 	TXD((">"));
 
 	if (netif_queue_stopped(dev) &&
-	    TX_BUFFS_AVAIL(hp) > 0)
+	    TX_BUFFS_AVAIL(hp) > (MAX_SKB_FRAGS + 1))
 		netif_wake_queue(dev);
-
-	spin_unlock(&hp->happy_lock);
 }
 
 #ifdef RXDEBUG
@@ -2030,6 +2001,8 @@
  * with all of the packets it has DMA'd in.  So now I just drop the entire
  * ring when we cannot get a new skb and give them all back to the happy meal,
  * maybe things will be "happier" now.
+ *
+ * hp->happy_lock must be held
  */
 static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
 {
@@ -2139,10 +2112,12 @@
 
 	HMD(("happy_meal_interrupt: status=%08x ", happy_status));
 
+	spin_lock(&hp->happy_lock);
+
 	if (happy_status & GREG_STAT_ERRORS) {
 		HMD(("ERRORS "));
 		if (happy_meal_is_not_so_happy(hp, /* un- */ happy_status))
-			return;
+			goto out;
 	}
 
 	if (happy_status & GREG_STAT_MIFIRQ) {
@@ -2161,6 +2136,8 @@
 	}
 
 	HMD(("done\n"));
+out:
+	spin_unlock(&hp->happy_lock);
 }
 
 #ifdef CONFIG_SBUS
@@ -2182,10 +2159,12 @@
 				      GREG_STAT_RXTOHOST)))
 			continue;
 
+		spin_lock(&hp->happy_lock);
+
 		if (happy_status & GREG_STAT_ERRORS) {
 			HMD(("ERRORS "));
 			if (happy_meal_is_not_so_happy(hp, happy_status))
-				break;
+				goto next;
 		}
 
 		if (happy_status & GREG_STAT_MIFIRQ) {
@@ -2202,6 +2181,9 @@
 			HMD(("RXTOHOST "));
 			happy_meal_rx(hp, dev);
 		}
+
+	next:
+		spin_unlock(&hp->happy_lock);
 	}
 	HMD(("done\n"));
 }
@@ -2234,7 +2216,11 @@
 	}
 
 	HMD(("to happy_meal_init\n"));
-	res = happy_meal_init(hp, 0);
+
+	spin_lock_irq(&hp->happy_lock);
+	res = happy_meal_init(hp);
+	spin_unlock_irq(&hp->happy_lock);
+
 	if (res && ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO))
 		free_irq(dev->irq, dev);
 	return res;
@@ -2244,12 +2230,15 @@
 {
 	struct happy_meal *hp = dev->priv;
 
+	spin_lock_irq(&hp->happy_lock);
 	happy_meal_stop(hp, hp->gregs);
 	happy_meal_clean_rings(hp);
 
 	/* If auto-negotiation timer is running, kill it. */
 	del_timer(&hp->happy_timer);
 
+	spin_unlock_irq(&hp->happy_lock);
+
 	/* On Quattro QFE cards, all hme interrupts are concentrated
 	 * into a single source which we register handling at probe
 	 * time and never unregister.
@@ -2266,7 +2255,6 @@
 #define SXD(x)
 #endif
 
-#ifdef CONFIG_SBUS
 static void happy_meal_tx_timeout(struct net_device *dev)
 {
 	struct happy_meal *hp = dev->priv;
@@ -2277,10 +2265,13 @@
 		hme_read32(hp, hp->gregs + GREG_STAT),
 		hme_read32(hp, hp->etxregs + ETX_CFG),
 		hme_read32(hp, hp->bigmacregs + BMAC_TXCFG));
-	happy_meal_init(hp, 0);
+
+	spin_lock_irq(&hp->happy_lock);
+	happy_meal_init(hp);
+	spin_unlock_irq(&hp->happy_lock);
+
 	netif_wake_queue(dev);
 }
-#endif
 
 static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
@@ -2305,6 +2296,8 @@
  	if (TX_BUFFS_AVAIL(hp) <= (skb_shinfo(skb)->nr_frags + 1)) {
 		netif_stop_queue(dev);
 		spin_unlock_irq(&hp->happy_lock);
+		printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
+		       dev->name);
 		return 1;
 	}
 
@@ -2357,7 +2350,7 @@
 
 	hp->tx_new = entry;
 
-	if (TX_BUFFS_AVAIL(hp) <= 0)
+	if (TX_BUFFS_AVAIL(hp) <= (MAX_SKB_FRAGS + 1))
 		netif_stop_queue(dev);
 
 	/* Get it going. */
@@ -2375,7 +2368,10 @@
 {
 	struct happy_meal *hp = dev->priv;
 
+	spin_lock_irq(&hp->happy_lock);
 	happy_meal_get_counters(hp, hp->bigmacregs);
+	spin_unlock_irq(&hp->happy_lock);
+
 	return &hp->net_stats;
 }
 
@@ -2385,10 +2381,11 @@
 	unsigned long bregs = hp->bigmacregs;
 	struct dev_mc_list *dmi = dev->mc_list;
 	char *addrs;
-	int i, j, bit, byte;
-	u32 crc, poly = CRC_POLYNOMIAL_LE;
+	int i;
+	u32 crc;
+
+	spin_lock_irq(&hp->happy_lock);
 
-	/* Lock out others. */
 	netif_stop_queue(dev);
 
 	if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
@@ -2412,17 +2409,7 @@
 			if (!(*addrs & 1))
 				continue;
 
-			crc = 0xffffffffU;
-			for (byte = 0; byte < 6; byte++) {
-				for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-					int test;
-
-					test = ((bit ^ crc) & 0x01);
-					crc >>= 1;
-					if (test)
-						crc = crc ^ poly;
-				}
-			}
+			crc = ether_crc_le(6, addrs);
 			crc >>= 26;
 			hash_table[crc >> 4] |= 1 << (crc & 0xf);
 		}
@@ -2432,8 +2419,9 @@
 		hme_write32(hp, bregs + BMAC_HTABLE3, hash_table[3]);
 	}
 
-	/* Let us get going again. */
 	netif_wake_queue(dev);
+
+	spin_unlock_irq(&hp->happy_lock);
 }
 
 /* Ethtool support... */
@@ -2461,8 +2449,11 @@
 		ecmd.phy_address = 0; /* XXX fixed PHYAD */
 
 		/* Record PHY settings. */
+		spin_lock_irq(&hp->happy_lock);
 		hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR);
 		hp->sw_lpa = happy_meal_tcvr_read(hp, hp->tcvregs, MII_LPA);
+		spin_unlock_irq(&hp->happy_lock);
+
 		if (hp->sw_bmcr & BMCR_ANENABLE) {
 			ecmd.autoneg = AUTONEG_ENABLE;
 			ecmd.speed =
@@ -2504,10 +2495,12 @@
 			return -EINVAL;
 
 		/* Ok, do it to it. */
+		spin_lock_irq(&hp->happy_lock);
 		del_timer(&hp->happy_timer);
 		happy_meal_begin_auto_negotiation(hp,
 						  hp->tcvregs,
 						  &ecmd);
+		spin_unlock_irq(&hp->happy_lock);
 
 		return 0;
 	} else
@@ -2665,33 +2658,28 @@
 	struct happy_meal *hp;
 	struct net_device *dev;
 	int i, qfe_slot = -1;
+	int err = -ENODEV;
 
 	if (is_qfe) {
 		qp = quattro_sbus_find(sdev);
 		if (qp == NULL)
-			return -ENODEV;
+			goto err_out;
 		for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
 			if (qp->happy_meals[qfe_slot] == NULL)
 				break;
 		if (qfe_slot == 4)
-			return -ENODEV;
+			goto err_out;
 	}
 
-	dev = init_etherdev(NULL, sizeof(struct happy_meal));
+	err = -ENOMEM;
+	dev = alloc_etherdev(sizeof(struct happy_meal));
 	if (!dev)
-		return -ENOMEM;
+		goto err_out;
 	SET_MODULE_OWNER(dev);
 
 	if (hme_version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
 
-	if (qfe_slot != -1)
-		printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
-		       dev->name, qfe_slot);
-	else
-		printk(KERN_INFO "%s: HAPPY MEAL (SBUS) 10/100baseT Ethernet ",
-		       dev->name);
-
 	/* If user did not specify a MAC address specifically, use
 	 * the Quattro local-mac-address property...
 	 */
@@ -2702,6 +2690,7 @@
 	if (i < 6) { /* a mac address was given */
 		for (i = 0; i < 6; i++)
 			dev->dev_addr[i] = macaddr[i];
+		macaddr[5]++;
 	} else if (qfe_slot != -1 &&
 		   prom_getproplen(sdev->prom_node,
 				   "local-mac-address") == 6) {
@@ -2711,11 +2700,6 @@
 		memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
 	}
 
-	for (i = 0; i < 6; i++)
-		printk("%2.2x%c",
-		       dev->dev_addr[i], i == 5 ? ' ' : ':');
-	printk("\n");
-
 	hp = dev->priv;
 	memset(hp, 0, sizeof(*hp));
 
@@ -2723,11 +2707,12 @@
 
 	spin_lock_init(&hp->happy_lock);
 
+	err = -ENODEV;
 	if (sdev->num_registers != 5) {
 		printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n",
 		       sdev->num_registers);
 		printk(KERN_ERR "happymeal: Would you like that for here or to go?\n");
-		return -ENODEV;
+		goto err_out_free_netdev;
 	}
 
 	if (qp != NULL) {
@@ -2741,35 +2726,35 @@
 				 GREG_REG_SIZE, "HME Global Regs");
 	if (!hp->gregs) {
 		printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n");
-		return -ENODEV;
+		goto err_out_free_netdev;
 	}
 
 	hp->etxregs = sbus_ioremap(&sdev->resource[1], 0,
 				   ETX_REG_SIZE, "HME TX Regs");
 	if (!hp->etxregs) {
 		printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n");
-		return -ENODEV;
+		goto err_out_iounmap;
 	}
 
 	hp->erxregs = sbus_ioremap(&sdev->resource[2], 0,
 				   ERX_REG_SIZE, "HME RX Regs");
 	if (!hp->erxregs) {
 		printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n");
-		return -ENODEV;
+		goto err_out_iounmap;
 	}
 
 	hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0,
 				      BMAC_REG_SIZE, "HME BIGMAC Regs");
 	if (!hp->bigmacregs) {
 		printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n");
-		return -ENODEV;
+		goto err_out_iounmap;
 	}
 
 	hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0,
 				   TCVR_REG_SIZE, "HME Tranceiver Regs");
 	if (!hp->tcvregs) {
 		printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n");
-		return -ENODEV;
+		goto err_out_iounmap;
 	}
 
 	hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff);
@@ -2792,6 +2777,11 @@
 	hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
 						PAGE_SIZE,
 						&hp->hblock_dvma);
+	err = -ENOMEM;
+	if (!hp->happy_block) {
+		printk(KERN_ERR "happymeal: Cannot allocate descriptors.\n");
+		goto err_out_iounmap;
+	}
 
 	/* Force check of the link first time we are brought up. */
 	hp->linkcheck = 0;
@@ -2832,22 +2822,161 @@
 	/* Grrr, Happy Meal comes up by default not advertising
 	 * full duplex 100baseT capabilities, fix this.
 	 */
+	spin_lock_irq(&hp->happy_lock);
 	happy_meal_set_initial_advertisement(hp);
+	spin_unlock_irq(&hp->happy_lock);
+
+	if (register_netdev(hp->dev)) {
+		printk(KERN_ERR "happymeal: Cannot register net device, "
+		       "aborting.\n");
+		goto err_out_free_consistent;
+	}
+
+	if (qfe_slot != -1)
+		printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
+		       dev->name, qfe_slot);
+	else
+		printk(KERN_INFO "%s: HAPPY MEAL (SBUS) 10/100baseT Ethernet ",
+		       dev->name);
 
-	ether_setup(dev);
+	for (i = 0; i < 6; i++)
+		printk("%2.2x%c",
+		       dev->dev_addr[i], i == 5 ? ' ' : ':');
+	printk("\n");
 
 	/* We are home free at this point, link us in to the happy
 	 * device list.
 	 */
-	dev->ifindex = dev_new_index();
 	hp->next_module = root_happy_dev;
 	root_happy_dev = hp;
 
 	return 0;
+
+err_out_free_consistent:
+	sbus_free_consistent(hp->happy_dev,
+			     PAGE_SIZE,
+			     hp->happy_block,
+			     hp->hblock_dvma);
+
+err_out_iounmap:
+	if (hp->gregs)
+		sbus_iounmap(hp->gregs, GREG_REG_SIZE);
+	if (hp->etxregs)
+		sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
+	if (hp->erxregs)
+		sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
+	if (hp->bigmacregs)
+		sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
+	if (hp->tcvregs)
+		sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
+
+err_out_free_netdev:
+	kfree(dev);
+
+err_out:
+	return err;
 }
 #endif
 
 #ifdef CONFIG_PCI
+#ifndef __sparc__
+static int is_quattro_p(struct pci_dev *pdev)
+{
+	struct pci_dev *busdev = pdev->bus->self;
+	struct list_head *tmp;
+	int n_hmes;
+
+	if (busdev->vendor != PCI_VENDOR_ID_DEC ||
+	    busdev->device != PCI_DEVICE_ID_DEC_21153)
+		return 0;
+
+	n_hmes = 0;
+	tmp = pdev->bus->devices.next;
+	while (tmp != &pdev->bus->devices) {
+		struct pci_dev *this_pdev = pci_dev_b(tmp);
+
+		if (this_pdev->vendor == PCI_VENDOR_ID_SUN &&
+		    this_pdev->device == PCI_DEVICE_ID_SUN_HAPPYMEAL)
+			n_hmes++;
+
+		tmp = tmp->next;
+	}
+
+	if (n_hmes != 4)
+		return 0;
+
+	return 1;
+}
+
+/* Fetch MAC address from vital product data of PCI ROM. */
+static void find_eth_addr_in_vpd(void *rom_base, int len, int index, unsigned char *dev_addr)
+{
+	int this_offset;
+
+	for (this_offset = 0x20; this_offset < len; this_offset++) {
+		void *p = rom_base + this_offset;
+
+		if (readb(p + 0) != 0x90 ||
+		    readb(p + 1) != 0x00 ||
+		    readb(p + 2) != 0x09 ||
+		    readb(p + 3) != 0x4e ||
+		    readb(p + 4) != 0x41 ||
+		    readb(p + 5) != 0x06)
+			continue;
+
+		this_offset += 6;
+		p += 6;
+
+		if (index == 0) {
+			int i;
+
+			for (i = 0; i < 6; i++)
+				dev_addr[i] = readb(p + i);
+			break;
+		}
+		index--;
+	}
+}
+
+static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
+{
+	u32 rom_reg_orig;
+	void *p;
+	int index;
+
+	index = 0;
+	if (is_quattro_p(pdev))
+		index = PCI_SLOT(pdev->devfn);
+
+	if (pdev->resource[PCI_ROM_RESOURCE].parent == NULL) {
+		if (pci_assign_resource(pdev, PCI_ROM_RESOURCE) < 0)
+			goto use_random;
+	}
+
+	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_reg_orig);
+	pci_write_config_dword(pdev, pdev->rom_base_reg,
+			       rom_reg_orig | PCI_ROM_ADDRESS_ENABLE);
+
+	p = ioremap(pci_resource_start(pdev, PCI_ROM_RESOURCE), (64 * 1024));
+	if (p != NULL && readb(p) == 0x55 && readb(p + 1) == 0xaa)
+		find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
+
+	if (p != NULL)
+		iounmap(p);
+
+	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_reg_orig);
+	return;
+
+use_random:
+	/* Sun MAC prefix then 3 random bytes. */
+	dev_addr[0] = 0x08;
+	dev_addr[1] = 0x00;
+	dev_addr[2] = 0x20;
+	get_random_bytes(dev_addr, 3);
+	return;
+}
+#endif /* !(__sparc__) */
+
 static int __init happy_meal_pci_init(struct pci_dev *pdev)
 {
 	struct quattro *qp = NULL;
@@ -2860,6 +2989,7 @@
 	unsigned long hpreg_base;
 	int i, qfe_slot = -1;
 	char prom_name[64];
+	int err;
 
 	/* Now make sure pci_dev cookie is there. */
 #ifdef __sparc__
@@ -2872,52 +3002,33 @@
 	
 	prom_getstring(node, "name", prom_name, sizeof(prom_name));
 #else
-/* This needs to be corrected... -DaveM */
-	strcpy(prom_name, "qfe");
+	if (is_quattro_p(pdev))
+		strcpy(prom_name, "SUNW,qfe");
+	else
+		strcpy(prom_name, "SUNW,hme");
 #endif
 
+	err = -ENODEV;
 	if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
 		qp = quattro_pci_find(pdev);
 		if (qp == NULL)
-			return -ENODEV;
+			goto err_out;
 		for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
 			if (qp->happy_meals[qfe_slot] == NULL)
 				break;
 		if (qfe_slot == 4)
-			return -ENODEV;
+			goto err_out;
 	}
 
-	dev = init_etherdev(NULL, sizeof(struct happy_meal));
+	dev = alloc_etherdev(sizeof(struct happy_meal));
+	err = -ENOMEM;
 	if (!dev)
-		return -ENOMEM;
+		goto err_out;
 	SET_MODULE_OWNER(dev);
 
 	if (hme_version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
 
-	if (!qfe_slot) {
-		struct pci_dev *qpdev = qp->quattro_dev;
-
-		prom_name[0] = 0;
-		if (!strncmp(dev->name, "eth", 3)) {
-			int i = simple_strtoul(dev->name + 3, NULL, 10);
-			sprintf(prom_name, "-%d", i + 3);
-		}
-		printk(KERN_INFO "%s%s: Quattro HME (PCI/CheerIO) 10/100baseT Ethernet ", dev->name, prom_name);
-		if (qpdev->vendor == PCI_VENDOR_ID_DEC &&
-		    qpdev->device == PCI_DEVICE_ID_DEC_21153)
-			printk("DEC 21153 PCI Bridge\n");
-		else
-			printk("unknown bridge %04x.%04x\n", 
-				qpdev->vendor, qpdev->device);
-	}
-	if (qfe_slot != -1)
-		printk(KERN_INFO "%s: Quattro HME slot %d (PCI/CheerIO) 10/100baseT Ethernet ",
-		       dev->name, qfe_slot);
-	else
-		printk(KERN_INFO "%s: HAPPY MEAL (PCI/CheerIO) 10/100BaseT Ethernet ",
-		       dev->name);
-
 	dev->base_addr = (long) pdev;
 
 	hp = (struct happy_meal *)dev->priv;
@@ -2934,13 +3045,20 @@
 	}		
 
 	hpreg_base = pci_resource_start(pdev, 0);
+	err = -ENODEV;
 	if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
 		printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n");
-		return -ENODEV;
+		goto err_out_clear_quattro;
 	}
+	if (pci_request_regions(pdev, dev->name)) {
+		printk(KERN_ERR "happymeal(PCI): Cannot obtain PCI resources, "
+		       "aborting.\n");
+		goto err_out_clear_quattro;
+	}
+
 	if ((hpreg_base = (unsigned long) ioremap(hpreg_base, 0x8000)) == 0) {
 		printk(KERN_ERR "happymeal(PCI): Unable to remap card memory.\n");
-		return -ENODEV;
+		goto err_out_free_res;
 	}
 
 	for (i = 0; i < 6; i++) {
@@ -2950,6 +3068,7 @@
 	if (i < 6) { /* a mac address was given */
 		for (i = 0; i < 6; i++)
 			dev->dev_addr[i] = macaddr[i];
+		macaddr[5]++;
 	} else {
 #ifdef __sparc__
 		if (qfe_slot != -1 &&
@@ -2960,15 +3079,10 @@
 			memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
 		}
 #else
-		memset(dev->dev_addr, 0, 6);
+		get_hme_mac_nonsparc(pdev, &dev->dev_addr[0]);
 #endif
 	}
 	
-	for (i = 0; i < 6; i++)
-		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? ' ' : ':');
-
-	printk("\n");
-
 	/* Layout registers. */
 	hp->gregs      = (hpreg_base + 0x0000UL);
 	hp->etxregs    = (hpreg_base + 0x2000UL);
@@ -3005,9 +3119,10 @@
 	hp->happy_block = (struct hmeal_init_block *)
 		pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma);
 
+	err = -ENODEV;
 	if (!hp->happy_block) {
 		printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n");
-		return -ENODEV;
+		goto err_out_iounmap;
 	}
 
 	hp->linkcheck = 0;
@@ -3022,6 +3137,8 @@
 	dev->hard_start_xmit = &happy_meal_start_xmit;
 	dev->get_stats = &happy_meal_get_stats;
 	dev->set_multicast_list = &happy_meal_set_multicast;
+	dev->tx_timeout = &happy_meal_tx_timeout;
+	dev->watchdog_timeo = 5*HZ;
 	dev->do_ioctl = &happy_meal_ioctl;
 	dev->irq = pdev->irq;
 	dev->dma = 0;
@@ -3044,18 +3161,67 @@
 	/* Grrr, Happy Meal comes up by default not advertising
 	 * full duplex 100baseT capabilities, fix this.
 	 */
+	spin_lock_irq(&hp->happy_lock);
 	happy_meal_set_initial_advertisement(hp);
+	spin_unlock_irq(&hp->happy_lock);
+
+	if (register_netdev(hp->dev)) {
+		printk(KERN_ERR "happymeal(PCI): Cannot register net device, "
+		       "aborting.\n");
+		goto err_out_iounmap;
+	}
+
+	if (!qfe_slot) {
+		struct pci_dev *qpdev = qp->quattro_dev;
+
+		prom_name[0] = 0;
+		if (!strncmp(dev->name, "eth", 3)) {
+			int i = simple_strtoul(dev->name + 3, NULL, 10);
+			sprintf(prom_name, "-%d", i + 3);
+		}
+		printk(KERN_INFO "%s%s: Quattro HME (PCI/CheerIO) 10/100baseT Ethernet ", dev->name, prom_name);
+		if (qpdev->vendor == PCI_VENDOR_ID_DEC &&
+		    qpdev->device == PCI_DEVICE_ID_DEC_21153)
+			printk("DEC 21153 PCI Bridge\n");
+		else
+			printk("unknown bridge %04x.%04x\n", 
+				qpdev->vendor, qpdev->device);
+	}
+
+	if (qfe_slot != -1)
+		printk(KERN_INFO "%s: Quattro HME slot %d (PCI/CheerIO) 10/100baseT Ethernet ",
+		       dev->name, qfe_slot);
+	else
+		printk(KERN_INFO "%s: HAPPY MEAL (PCI/CheerIO) 10/100BaseT Ethernet ",
+		       dev->name);
 
-	ether_setup(dev);
+	for (i = 0; i < 6; i++)
+		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? ' ' : ':');
+
+	printk("\n");
 
 	/* We are home free at this point, link us in to the happy
 	 * device list.
 	 */
-	dev->ifindex = dev_new_index();
 	hp->next_module = root_happy_dev;
 	root_happy_dev = hp;
 
 	return 0;
+
+err_out_iounmap:
+	iounmap((void *)hp->gregs);
+
+err_out_free_res:
+	pci_release_regions(pdev);
+
+err_out_clear_quattro:
+	if (qp != NULL)
+		qp->happy_meals[qfe_slot] = NULL;
+
+	kfree(dev);
+
+err_out:
+	return err;
 }
 #endif
 
@@ -3102,6 +3268,7 @@
 				       PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) {
 		if (pci_enable_device(pdev))
 			continue;
+		pci_set_master(pdev);
 		cards++;
 		happy_meal_pci_init(pdev);
 	}
@@ -3142,12 +3309,18 @@
 	while (root_happy_dev) {
 		struct happy_meal *hp = root_happy_dev;
 		struct happy_meal *next = root_happy_dev->next_module;
+		struct net_device *dev = hp->dev;
+
+		/* Unregister netdev before unmapping registers as this
+		 * call can end up trying to access those registers.
+		 */
+		unregister_netdev(dev);
 
 #ifdef CONFIG_SBUS
 		if (!(hp->happy_flags & HFLAG_PCI)) {
 			if (hp->happy_flags & HFLAG_QUATTRO) {
 				if (hp->qfe_parent != last_seen_qfe) {
-					free_irq(hp->dev->irq, hp->qfe_parent);
+					free_irq(dev->irq, hp->qfe_parent);
 					last_seen_qfe = hp->qfe_parent;
 				}
 			}
@@ -3170,12 +3343,35 @@
 					    hp->happy_block,
 					    hp->hblock_dvma);
 			iounmap((void *)hp->gregs);
+			pci_release_regions(hp->happy_dev);
 		}
 #endif
-		unregister_netdev(hp->dev);
-		kfree(hp->dev);
+		kfree(dev);
+
 		root_happy_dev = next;
 	}
+
+	/* Now cleanup the quattro lists. */
+#ifdef CONFIG_SBUS
+	while (qfe_sbus_list) {
+		struct quattro *qfe = qfe_sbus_list;
+		struct quattro *next = qfe->next;
+
+		kfree(qfe);
+
+		qfe_sbus_list = next;
+	}
+#endif
+#ifdef CONFIG_PCI
+	while (qfe_pci_list) {
+		struct quattro *qfe = qfe_pci_list;
+		struct quattro *next = qfe->next;
+
+		kfree(qfe);
+
+		qfe_pci_list = next;
+	}
+#endif
 }
 
 module_init(happy_meal_probe);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sunhme.h linux/drivers/net/sunhme.h
--- linux.orig/drivers/net/sunhme.h	2001-08-07 15:30:50.000000000 +0000
+++ linux/drivers/net/sunhme.h	2002-07-20 01:08:35.000000000 +0000
@@ -227,7 +227,7 @@
 #define BIGMAC_RXCFG_PMISC    0x00000040 /* Enable promiscous mode          */
 #define BIGMAC_RXCFG_DERR     0x00000080 /* Disable error checking          */
 #define BIGMAC_RXCFG_DCRCS    0x00000100 /* Disable CRC stripping           */
-#define BIGMAC_RXCFG_ME       0x00000200 /* Receive packets addressed to me */
+#define BIGMAC_RXCFG_REJME    0x00000200 /* Reject packets addressed to me  */
 #define BIGMAC_RXCFG_PGRP     0x00000400 /* Enable promisc group mode       */
 #define BIGMAC_RXCFG_HENABLE  0x00000800 /* Enable the hash filter          */
 #define BIGMAC_RXCFG_AENABLE  0x00001000 /* Enable the address filter       */
@@ -431,7 +431,7 @@
 	unsigned long	bigmacregs;     /* BIGMAC core regs		     */
 	unsigned long	tcvregs;        /* MIF transceiver regs              */
 
-	__u32                     hblock_dvma;    /* DVMA visible address happy block  */
+	dma_addr_t                hblock_dvma;    /* DVMA visible address happy block  */
 	unsigned int              happy_flags;    /* Driver state flags                */
 	enum happy_transceiver    tcvr_type;      /* Kind of transceiver in use        */
 	unsigned int              happy_bursts;   /* Get your mind out of the gutter   */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sunlance.c linux/drivers/net/sunlance.c
--- linux.orig/drivers/net/sunlance.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/sunlance.c	2002-07-20 01:08:30.000000000 +0000
@@ -62,12 +62,15 @@
  * 	          Anton Blanchard (anton@progsoc.uts.edu.au)
  * 2.00: 11/9/99: Massive overhaul and port to new SBUS driver interfaces.
  *		  David S. Miller (davem@redhat.com)
+ * 2.01:
+ *      11/08/01: Use library crc32 functions (Matt_Domsch@dell.com)
+ *		  
  */
 
 #undef DEBUG_DRIVER
 
 static char version[] =
-	"sunlance.c:v2.00 11/Sep/99 Miguel de Icaza (miguel@nuclecu.unam.mx)\n";
+	"sunlance.c:v2.01 08/Nov/01 Miguel de Icaza (miguel@nuclecu.unam.mx)\n";
 
 static char lancestr[] = "LANCE";
 
@@ -86,6 +89,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -115,9 +119,6 @@
 #define LANCE_LOG_RX_BUFFERS 4
 #endif
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 #define LE_CSR0 0
 #define LE_CSR1 1
 #define LE_CSR2 2
@@ -257,7 +258,7 @@
 	void (*tx)(struct net_device *);
 
 	char	       	       *name;
-	__u32			init_block_dvma;
+	dma_addr_t		init_block_dvma;
 	struct net_device      *dev;		  /* Backpointer	*/
 	struct lance_private   *next_module;
 	struct sbus_dev	       *sdev;
@@ -319,7 +320,7 @@
 {
 	struct lance_private *lp = (struct lance_private *) dev->priv;
 	volatile struct lance_init_block *ib = lp->init_block;
-	__u32 aib = lp->init_block_dvma;
+	dma_addr_t aib = lp->init_block_dvma;
 	__u32 leptr;
 	int i;
     
@@ -1180,8 +1181,8 @@
 	volatile u16 *mcast_table = (u16 *) &ib->filter;
 	struct dev_mc_list *dmi = dev->mc_list;
 	char *addrs;
-	int i, j, bit, byte;
-	u32 crc, poly = CRC_POLYNOMIAL_LE;
+	int i;
+	u32 crc;
 	
 	/* set all multicast bits */
 	if (dev->flags & IFF_ALLMULTI) {
@@ -1211,19 +1212,7 @@
 		/* multicast address? */
 		if (!(*addrs & 1))
 			continue;
-
-		crc = 0xffffffff;
-		for (byte = 0; byte < 6; byte++) {
-			for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-				int test;
-
-				test = ((bit ^ crc) & 0x01);
-				crc >>= 1;
-
-				if (test)
-					crc = crc ^ poly;
-			}
-		}
+		crc = ether_crc_le(6, addrs);
 		crc = crc >> 26;
 		if (lp->pio_buffer) {
 			u16 tmp = sbus_readw(&mcast_table[crc>>4]);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/sunqe.c linux/drivers/net/sunqe.c
--- linux.orig/drivers/net/sunqe.c	2002-02-25 19:37:59.000000000 +0000
+++ linux/drivers/net/sunqe.c	2002-07-20 01:08:33.000000000 +0000
@@ -24,6 +24,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -622,17 +623,14 @@
 	return &qep->net_stats;
 }
 
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
-
 static void qe_set_multicast(struct net_device *dev)
 {
 	struct sunqe *qep = (struct sunqe *) dev->priv;
 	struct dev_mc_list *dmi = dev->mc_list;
 	u8 new_mconfig = qep->mconfig;
 	char *addrs;
-	int i, j, bit, byte;
-	u32 crc, poly = CRC_POLYNOMIAL_LE;
+	int i;
+	u32 crc;
 
 	/* Lock out others. */
 	netif_stop_queue(dev);
@@ -660,18 +658,7 @@
 
 			if (!(*addrs & 1))
 				continue;
-
-			crc = 0xffffffffU;
-			for (byte = 0; byte < 6; byte++) {
-				for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
-					int test;
-
-					test = ((bit ^ crc) & 0x01);
-					crc >>= 1;
-					if (test)
-						crc = crc ^ poly;
-				}
-			}
+			crc = ether_crc_le(6, addrs);
 			crc >>= 26;
 			hash_table[crc >> 4] |= 1 << (crc & 0xf);
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tc35815.c linux/drivers/net/tc35815.c
--- linux.orig/drivers/net/tc35815.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/tc35815.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,1765 @@
+/* tc35815.c: A TOSHIBA TC35815CF PCI 10/100Mbps ethernet driver for linux.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. 
+ *                ahennessy@mvista.com
+ *
+ * Based on skelton.c by Donald Becker.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * Cleaned up various non portable stuff (save_and_cli etc) and made it
+ * build on x86 platforms -- Alan Cox <alan@redhat.com> 20020302
+ *
+ * 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * TODO:
+ *	Switch to spin_lock not lock_kernel for scalability.
+ */
+
+static const char *version =
+	"tc35815.c:v0.00-ac 26/07/2000 by Toshiba Corporation\n";
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <asm/byteorder.h>
+
+
+/*
+ * The name of the card. Is used for messages and in the requests for
+ * io regions, irqs and dma channels
+ */
+static const char* cardname = "TC35815CF";
+#define TC35815_PROC_ENTRY "net/tc35815"
+
+#define TC35815_MODULE_NAME "TC35815CF"
+#define TX_TIMEOUT (4*HZ)
+
+/* First, a few definitions that the brave might change. */
+
+/* use 0 for production, 1 for verification, >2 for debug */
+#ifndef TC35815_DEBUG
+#define TC35815_DEBUG 1
+#endif
+static unsigned int tc35815_debug = TC35815_DEBUG;
+
+#define GATHER_TXINT	/* On-Demand Tx Interrupt */
+
+#define vtonocache(p)	KSEG1ADDR(virt_to_phys(p))
+
+/*
+ * Registers
+ */
+struct tc35815_regs {
+	volatile __u32 DMA_Ctl;		/* 0x00 */
+	volatile __u32 TxFrmPtr;
+	volatile __u32 TxThrsh;
+	volatile __u32 TxPollCtr;
+	volatile __u32 BLFrmPtr;
+	volatile __u32 RxFragSize;
+	volatile __u32 Int_En;
+	volatile __u32 FDA_Bas;
+	volatile __u32 FDA_Lim;		/* 0x20 */
+	volatile __u32 Int_Src;
+	volatile __u32 unused0[2];
+	volatile __u32 PauseCnt;
+	volatile __u32 RemPauCnt;
+	volatile __u32 TxCtlFrmStat;
+	volatile __u32 unused1;
+	volatile __u32 MAC_Ctl;		/* 0x40 */
+	volatile __u32 CAM_Ctl;
+	volatile __u32 Tx_Ctl;
+	volatile __u32 Tx_Stat;
+	volatile __u32 Rx_Ctl;
+	volatile __u32 Rx_Stat;
+	volatile __u32 MD_Data;
+	volatile __u32 MD_CA;
+	volatile __u32 CAM_Adr;		/* 0x60 */
+	volatile __u32 CAM_Data;
+	volatile __u32 CAM_Ena;
+	volatile __u32 PROM_Ctl;
+	volatile __u32 PROM_Data;
+	volatile __u32 Algn_Cnt;
+	volatile __u32 CRC_Cnt;
+	volatile __u32 Miss_Cnt;
+};
+
+/*
+ * Bit assignments
+ */
+/* DMA_Ctl bit asign ------------------------------------------------------- */
+#define DMA_IntMask            0x00040000 /* 1:Interupt mask                 */
+#define DMA_SWIntReq           0x00020000 /* 1:Software Interrupt request    */
+#define DMA_TxWakeUp           0x00010000 /* 1:Transmit Wake Up              */
+#define DMA_RxBigE             0x00008000 /* 1:Receive Big Endian            */
+#define DMA_TxBigE             0x00004000 /* 1:Transmit Big Endian           */
+#define DMA_TestMode           0x00002000 /* 1:Test Mode                     */
+#define DMA_PowrMgmnt          0x00001000 /* 1:Power Management              */
+#define DMA_DmBurst_Mask       0x000001fc /* DMA Burst size                  */
+
+/* RxFragSize bit asign ---------------------------------------------------- */
+#define RxFrag_EnPack          0x00008000 /* 1:Enable Packing                */
+#define RxFrag_MinFragMask     0x00000ffc /* Minimum Fragment                */
+
+/* MAC_Ctl bit asign ------------------------------------------------------- */
+#define MAC_Link10             0x00008000 /* 1:Link Status 10Mbits           */
+#define MAC_EnMissRoll         0x00002000 /* 1:Enable Missed Roll            */
+#define MAC_MissRoll           0x00000400 /* 1:Missed Roll                   */
+#define MAC_Loop10             0x00000080 /* 1:Loop 10 Mbps                  */
+#define MAC_Conn_Auto          0x00000000 /*00:Connection mode (Automatic)   */
+#define MAC_Conn_10M           0x00000020 /*01:                (10Mbps endec)*/
+#define MAC_Conn_Mll           0x00000040 /*10:                (Mll clock)   */
+#define MAC_MacLoop            0x00000010 /* 1:MAC Loopback                  */
+#define MAC_FullDup            0x00000008 /* 1:Full Duplex 0:Half Duplex     */
+#define MAC_Reset              0x00000004 /* 1:Software Reset                */
+#define MAC_HaltImm            0x00000002 /* 1:Halt Immediate                */
+#define MAC_HaltReq            0x00000001 /* 1:Halt request                  */
+
+/* PROM_Ctl bit asign ------------------------------------------------------ */
+#define PROM_Busy              0x00008000 /* 1:Busy (Start Operation)        */
+#define PROM_Read              0x00004000 /*10:Read operation                */
+#define PROM_Write             0x00002000 /*01:Write operation               */
+#define PROM_Erase             0x00006000 /*11:Erase operation               */
+                                          /*00:Enable or Disable Writting,   */
+                                          /*      as specified in PROM_Addr. */
+#define PROM_Addr_Ena          0x00000030 /*11xxxx:PROM Write enable         */
+                                          /*00xxxx:           disable        */
+
+/* CAM_Ctl bit asign ------------------------------------------------------- */
+#define CAM_CompEn             0x00000010 /* 1:CAM Compare Enable            */
+#define CAM_NegCAM             0x00000008 /* 1:Reject packets CAM recognizes,*/
+                                          /*                    accept other */
+#define CAM_BroadAcc           0x00000004 /* 1:Broadcast assept              */
+#define CAM_GroupAcc           0x00000002 /* 1:Multicast assept              */
+#define CAM_StationAcc         0x00000001 /* 1:unicast accept                */
+
+/* CAM_Ena bit asign ------------------------------------------------------- */
+#define CAM_ENTRY_MAX                  21   /* CAM Data entry max count      */
+#define CAM_Ena_Mask ((1<<CAM_ENTRY_MAX)-1) /* CAM Enable bits (Max 21bits)  */
+#define CAM_Ena_Bit(index)         (1<<(index))
+#define CAM_ENTRY_DESTINATION	0
+#define CAM_ENTRY_SOURCE	1
+#define CAM_ENTRY_MACCTL	20
+
+/* Tx_Ctl bit asign -------------------------------------------------------- */
+#define Tx_En                  0x00000001 /* 1:Transmit enable               */
+#define Tx_TxHalt              0x00000002 /* 1:Transmit Halt Request         */
+#define Tx_NoPad               0x00000004 /* 1:Suppress Padding              */
+#define Tx_NoCRC               0x00000008 /* 1:Suppress Padding              */
+#define Tx_FBack               0x00000010 /* 1:Fast Back-off                 */
+#define Tx_EnUnder             0x00000100 /* 1:Enable Underrun               */
+#define Tx_EnExDefer           0x00000200 /* 1:Enable Excessive Deferral     */
+#define Tx_EnLCarr             0x00000400 /* 1:Enable Lost Carrier           */
+#define Tx_EnExColl            0x00000800 /* 1:Enable Excessive Collision    */
+#define Tx_EnLateColl          0x00001000 /* 1:Enable Late Collision         */
+#define Tx_EnTxPar             0x00002000 /* 1:Enable Transmit Parity        */
+#define Tx_EnComp              0x00004000 /* 1:Enable Completion             */
+
+/* Tx_Stat bit asign ------------------------------------------------------- */
+#define Tx_TxColl_MASK         0x0000000F /* Tx Collision Count              */
+#define Tx_ExColl              0x00000010 /* Excessive Collision             */
+#define Tx_TXDefer             0x00000020 /* Transmit Defered                */
+#define Tx_Paused              0x00000040 /* Transmit Paused                 */
+#define Tx_IntTx               0x00000080 /* Interrupt on Tx                 */
+#define Tx_Under               0x00000100 /* Underrun                        */
+#define Tx_Defer               0x00000200 /* Deferral                        */
+#define Tx_NCarr               0x00000400 /* No Carrier                      */
+#define Tx_10Stat              0x00000800 /* 10Mbps Status                   */
+#define Tx_LateColl            0x00001000 /* Late Collision                  */
+#define Tx_TxPar               0x00002000 /* Tx Parity Error                 */
+#define Tx_Comp                0x00004000 /* Completion                      */
+#define Tx_Halted              0x00008000 /* Tx Halted                       */
+#define Tx_SQErr               0x00010000 /* Signal Quality Error(SQE)       */
+
+/* Rx_Ctl bit asign -------------------------------------------------------- */
+#define Rx_EnGood              0x00004000 /* 1:Enable Good                   */
+#define Rx_EnRxPar             0x00002000 /* 1:Enable Receive Parity         */
+#define Rx_EnLongErr           0x00000800 /* 1:Enable Long Error             */
+#define Rx_EnOver              0x00000400 /* 1:Enable OverFlow               */
+#define Rx_EnCRCErr            0x00000200 /* 1:Enable CRC Error              */
+#define Rx_EnAlign             0x00000100 /* 1:Enable Alignment              */
+#define Rx_IgnoreCRC           0x00000040 /* 1:Ignore CRC Value              */
+#define Rx_StripCRC            0x00000010 /* 1:Strip CRC Value               */
+#define Rx_ShortEn             0x00000008 /* 1:Short Enable                  */
+#define Rx_LongEn              0x00000004 /* 1:Long Enable                   */
+#define Rx_RxHalt              0x00000002 /* 1:Receive Halt Request          */
+#define Rx_RxEn                0x00000001 /* 1:Receive Intrrupt Enable       */
+
+/* Rx_Stat bit asign ------------------------------------------------------- */
+#define Rx_Halted              0x00008000 /* Rx Halted                       */
+#define Rx_Good                0x00004000 /* Rx Good                         */
+#define Rx_RxPar               0x00002000 /* Rx Parity Error                 */
+                            /* 0x00001000    not use                         */
+#define Rx_LongErr             0x00000800 /* Rx Long Error                   */
+#define Rx_Over                0x00000400 /* Rx Overflow                     */
+#define Rx_CRCErr              0x00000200 /* Rx CRC Error                    */
+#define Rx_Align               0x00000100 /* Rx Alignment Error              */
+#define Rx_10Stat              0x00000080 /* Rx 10Mbps Status                */
+#define Rx_IntRx               0x00000040 /* Rx Interrupt                    */
+#define Rx_CtlRecd             0x00000020 /* Rx Control Receive              */
+
+#define Rx_Stat_Mask           0x0000EFC0 /* Rx All Status Mask              */
+
+/* Int_En bit asign -------------------------------------------------------- */
+#define Int_NRAbtEn            0x00000800 /* 1:Non-recoverable Abort Enable  */
+#define Int_TxCtlCmpEn         0x00000400 /* 1:Transmit Control Complete Enable */
+#define Int_DmParErrEn         0x00000200 /* 1:DMA Parity Error Enable       */
+#define Int_DParDEn            0x00000100 /* 1:Data Parity Error Enable      */
+#define Int_EarNotEn           0x00000080 /* 1:Early Notify Enable           */
+#define Int_DParErrEn          0x00000040 /* 1:Detected Parity Error Enable  */
+#define Int_SSysErrEn          0x00000020 /* 1:Signalled System Error Enable */
+#define Int_RMasAbtEn          0x00000010 /* 1:Received Master Abort Enable  */
+#define Int_RTargAbtEn         0x00000008 /* 1:Received Target Abort Enable  */
+#define Int_STargAbtEn         0x00000004 /* 1:Signalled Target Abort Enable */
+#define Int_BLExEn             0x00000002 /* 1:Buffer List Exhausted Enable  */
+#define Int_FDAExEn            0x00000001 /* 1:Free Descriptor Area          */
+                                          /*               Exhausted Enable  */
+
+/* Int_Src bit asign ------------------------------------------------------- */
+#define Int_NRabt              0x00004000 /* 1:Non Recoverable error         */
+#define Int_DmParErrStat       0x00002000 /* 1:DMA Parity Error & Clear      */
+#define Int_BLEx               0x00001000 /* 1:Buffer List Empty & Clear     */
+#define Int_FDAEx              0x00000800 /* 1:FDA Empty & Clear             */
+#define Int_IntNRAbt           0x00000400 /* 1:Non Recoverable Abort         */
+#define	Int_IntCmp             0x00000200 /* 1:MAC control packet complete   */
+#define Int_IntExBD            0x00000100 /* 1:Interrupt Extra BD & Clear    */
+#define Int_DmParErr           0x00000080 /* 1:DMA Parity Error & Clear      */
+#define Int_IntEarNot          0x00000040 /* 1:Receive Data write & Clear    */
+#define Int_SWInt              0x00000020 /* 1:Software request & Clear      */
+#define Int_IntBLEx            0x00000010 /* 1:Buffer List Empty & Clear     */
+#define Int_IntFDAEx           0x00000008 /* 1:FDA Empty & Clear             */
+#define Int_IntPCI             0x00000004 /* 1:PCI controller & Clear        */
+#define Int_IntMacRx           0x00000002 /* 1:Rx controller & Clear         */
+#define Int_IntMacTx           0x00000001 /* 1:Tx controller & Clear         */
+
+/* MD_CA bit asign --------------------------------------------------------- */
+#define MD_CA_PreSup           0x00001000 /* 1:Preamble Supress              */
+#define MD_CA_Busy             0x00000800 /* 1:Busy (Start Operation)        */
+#define MD_CA_Wr               0x00000400 /* 1:Write 0:Read                  */
+
+
+/* MII register offsets */
+#define MII_CONTROL             0x0000
+#define MII_STATUS              0x0001
+#define MII_PHY_ID0             0x0002
+#define MII_PHY_ID1             0x0003
+#define MII_ANAR                0x0004
+#define MII_ANLPAR              0x0005
+#define MII_ANER                0x0006
+/* MII Control register bit definitions. */
+#define MIICNTL_FDX             0x0100
+#define MIICNTL_RST_AUTO        0x0200
+#define MIICNTL_ISOLATE         0x0400
+#define MIICNTL_PWRDWN          0x0800
+#define MIICNTL_AUTO            0x1000
+#define MIICNTL_SPEED           0x2000
+#define MIICNTL_LPBK            0x4000
+#define MIICNTL_RESET           0x8000
+/* MII Status register bit significance. */
+#define MIISTAT_EXT             0x0001
+#define MIISTAT_JAB             0x0002
+#define MIISTAT_LINK            0x0004
+#define MIISTAT_CAN_AUTO        0x0008
+#define MIISTAT_FAULT           0x0010
+#define MIISTAT_AUTO_DONE       0x0020
+#define MIISTAT_CAN_T           0x0800
+#define MIISTAT_CAN_T_FDX       0x1000
+#define MIISTAT_CAN_TX          0x2000
+#define MIISTAT_CAN_TX_FDX      0x4000
+#define MIISTAT_CAN_T4          0x8000
+/* MII Auto-Negotiation Expansion/RemoteEnd Register Bits */
+#define MII_AN_TX_FDX           0x0100
+#define MII_AN_TX_HDX           0x0080
+#define MII_AN_10_FDX           0x0040
+#define MII_AN_10_HDX           0x0020
+
+
+/*
+ * Descriptors
+ */
+
+/* Frame descripter */
+struct FDesc {
+	volatile __u32 FDNext;
+	volatile __u32 FDSystem;
+	volatile __u32 FDStat;
+	volatile __u32 FDCtl;
+};
+
+/* Buffer descripter */
+struct BDesc {
+	volatile __u32 BuffData;
+	volatile __u32 BDCtl;
+};
+
+#define FD_ALIGN	16
+
+/* Frame Descripter bit asign ---------------------------------------------- */
+#define FD_FDLength_MASK       0x0000FFFF /* Length MASK                     */
+#define FD_BDCnt_MASK          0x001F0000 /* BD count MASK in FD             */
+#define FD_FrmOpt_MASK         0x7C000000 /* Frame option MASK               */
+#define FD_FrmOpt_BigEndian    0x40000000 /* Tx/Rx */
+#define FD_FrmOpt_IntTx        0x20000000 /* Tx only */
+#define FD_FrmOpt_NoCRC        0x10000000 /* Tx only */
+#define FD_FrmOpt_NoPadding    0x08000000 /* Tx only */
+#define FD_FrmOpt_Packing      0x04000000 /* Rx only */
+#define FD_CownsFD             0x80000000 /* FD Controller owner bit         */
+#define FD_Next_EOL            0x00000001 /* FD EOL indicator                */
+#define FD_BDCnt_SHIFT         16
+
+/* Buffer Descripter bit asign --------------------------------------------- */
+#define BD_BuffLength_MASK     0x0000FFFF /* Recieve Data Size               */
+#define BD_RxBDID_MASK         0x00FF0000 /* BD ID Number MASK               */
+#define BD_RxBDSeqN_MASK       0x7F000000 /* Rx BD Sequence Number           */
+#define BD_CownsBD             0x80000000 /* BD Controller owner bit         */
+#define BD_RxBDID_SHIFT        16
+#define BD_RxBDSeqN_SHIFT      24
+
+
+/* Some useful constants. */
+#undef NO_CHECK_CARRIER	/* Does not check No-Carrier with TP */
+
+#ifdef NO_CHECK_CARRIER
+#define TX_CTL_CMD	(Tx_EnComp | Tx_EnTxPar | Tx_EnLateColl | \
+	Tx_EnExColl | Tx_EnLCarr | Tx_EnExDefer | Tx_EnUnder | \
+	Tx_En)	/* maybe  0x7d01 */
+#else
+#define TX_CTL_CMD	(Tx_EnComp | Tx_EnTxPar | Tx_EnLateColl | \
+	Tx_EnExColl | Tx_EnExDefer | Tx_EnUnder | \
+	Tx_En)	/* maybe  0x7f01 */
+#endif
+#define RX_CTL_CMD	(Rx_EnGood | Rx_EnRxPar | Rx_EnLongErr | Rx_EnOver \
+	| Rx_EnCRCErr | Rx_EnAlign | Rx_RxEn)	/* maybe 0x6f01 */
+
+#define INT_EN_CMD  (Int_NRAbtEn | \
+	 Int_DParDEn | Int_DParErrEn | \
+	Int_SSysErrEn  | Int_RMasAbtEn | Int_RTargAbtEn | \
+	Int_STargAbtEn | \
+	Int_BLExEn  | Int_FDAExEn) /* maybe 0xb7f*/
+
+/* Tuning parameters */
+#define DMA_BURST_SIZE	32
+#define TX_THRESHOLD	1024
+
+#define FD_PAGE_NUM 2
+#define FD_PAGE_ORDER 1
+/* 16 + RX_BUF_PAGES * 8 + RX_FD_NUM * 16 + TX_FD_NUM * 32 <= PAGE_SIZE*2 */
+#define RX_BUF_PAGES	8	/* >= 2 */
+#define RX_FD_NUM	250	/* >= 32 */
+#define TX_FD_NUM	128
+
+struct TxFD {
+	struct FDesc fd;
+	struct BDesc bd;
+	struct BDesc unused;
+};
+
+struct RxFD {
+	struct FDesc fd;
+	struct BDesc bd[0];	/* variable length */
+};
+
+struct FrFD {
+	struct FDesc fd;
+	struct BDesc bd[RX_BUF_PAGES];
+};
+
+
+#if defined(__mips__)
+/* MIPS weirdness */
+extern unsigned long tc_readl(volatile __u32 *addr);
+extern void tc_writel(unsigned long data, volatile __u32 *addr);
+#else
+#define tc_readl	readl
+#define tc_writel	writel
+#endif
+
+dma_addr_t priv_dma_handle;
+
+/* Information that need to be kept for each board. */
+struct tc35815_local {
+	struct net_device *next_module;
+
+	/* statistics */
+	struct net_device_stats stats;
+	struct {
+		int max_tx_qlen;
+		int tx_ints;
+		int rx_ints;
+	} lstats;
+
+	int tbusy;
+	int option;
+#define TC35815_OPT_AUTO	0x00
+#define TC35815_OPT_10M	0x01
+#define TC35815_OPT_100M	0x02
+#define TC35815_OPT_FULLDUP	0x04
+	int linkspeed;	/* 10 or 100 */
+	int fullduplex;
+
+	/*
+	 * Transmitting: Batch Mode.
+	 *	1 BD in 1 TxFD.
+	 * Receiving: Packing Mode.
+	 *	1 circular FD for Free Buffer List.
+	 *	RX_BUG_PAGES BD in Free Buffer FD.
+	 *	One Free Buffer BD has PAGE_SIZE data buffer.
+	 */
+        struct pci_dev *pdev;
+	dma_addr_t fd_buf_dma_handle;
+	void * fd_buf;	/* for TxFD, TxFD, FrFD */
+	struct TxFD *tfd_base;
+	int tfd_start;
+	int tfd_end;
+	struct RxFD *rfd_base;
+	struct RxFD *rfd_limit;
+	struct RxFD *rfd_cur;
+	struct FrFD *fbl_ptr;
+	unsigned char fbl_curid;
+	dma_addr_t data_buf_dma_handle[RX_BUF_PAGES];
+	void * data_buf[RX_BUF_PAGES];		/* packing */
+};
+
+/* Index to functions, as function prototypes. */
+
+static int __init tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq);
+
+static int	tc35815_open(struct net_device *dev);
+static int	tc35815_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void     tc35815_tx_timeout(struct net_device *dev);
+static void	tc35815_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void	tc35815_rx(struct net_device *dev);
+static void	tc35815_txdone(struct net_device *dev);
+static int	tc35815_close(struct net_device *dev);
+static struct	net_device_stats *tc35815_get_stats(struct net_device *dev);
+static void	tc35815_set_multicast_list(struct net_device *dev);
+
+static void 	tc35815_chip_reset(struct net_device *dev);
+static void 	tc35815_chip_init(struct net_device *dev);
+static void 	tc35815_phy_chip_init(struct net_device *dev);
+
+/* A list of all installed tc35815 devices. */
+static struct net_device *root_tc35815_dev = NULL;
+
+/*
+ * PCI device identifiers for "new style" Linux PCI Device Drivers
+ */
+static struct pci_device_id tc35815_pci_tbl[] __devinitdata = {
+    { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815CF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+    { 0, }
+};
+
+MODULE_DEVICE_TABLE (pci, tc35815_pci_tbl);
+
+int
+tc35815_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
+{
+	static int called = 0;
+	int err = 0;
+	int ret;
+
+	if (called)
+		return -ENODEV;
+	called++;
+
+	if (!pci_present())
+		return -ENODEV;
+
+	if (pdev) {
+		unsigned long pci_memaddr;
+		unsigned int pci_irq_line;
+
+		printk(KERN_INFO "tc35815_probe: found device %#08x.%#08x\n", ent->vendor, ent->device);
+
+	        pci_memaddr = pci_resource_start (pdev, 1);
+
+	        printk(KERN_INFO "    pci_memaddr=%#08lx  resource_flags=%#08lx\n", pci_memaddr, pci_resource_flags (pdev, 0));
+
+		if (!pci_memaddr) {
+			printk(KERN_WARNING "no PCI MEM resources, aborting\n");
+			return -ENODEV;
+		}
+		pci_irq_line = pdev->irq;
+		/* irq disabled. */
+		if (pci_irq_line == 0) {
+			printk(KERN_WARNING "no PCI irq, aborting\n");
+			return -ENODEV;
+		}
+
+		ret =  tc35815_probe1(pdev, pci_memaddr, pci_irq_line);
+
+		if (!ret) {
+			if ((err = pci_enable_device(pdev)) < 0) {
+			    printk(KERN_ERR "tc35815_probe: failed to enable device -- err=%d\n", err);
+			    return err;
+			}
+			pci_set_master(pdev);
+		}
+
+		return ret;
+	}
+	return -ENODEV;
+}
+
+static int __init tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq)
+{
+	static unsigned version_printed = 0;
+	int i;
+	struct tc35815_local *lp;
+	struct tc35815_regs *tr;
+	struct net_device *dev;
+
+	/* Allocate a new 'dev' if needed. */
+	dev = init_etherdev(NULL, 0);
+	if (dev == NULL)
+		return -ENOMEM;
+
+	if (tc35815_debug  &&  version_printed++ == 0)
+		printk(KERN_DEBUG "%s", version);
+
+	printk(KERN_INFO "%s: %s found at %#x, irq %d\n",
+	       dev->name, cardname, base_addr, irq);
+
+	/* Fill in the 'dev' fields. */
+	dev->irq = irq;
+	dev->base_addr = (unsigned long)ioremap(base_addr,
+						sizeof(struct tc35815_regs));
+	tr = (struct tc35815_regs*)dev->base_addr;
+
+	tc35815_chip_reset(dev);
+
+	/* Retrieve and print the ethernet address. */
+	while (tc_readl(&tr->PROM_Ctl) & PROM_Busy)
+		cpu_relax();
+	for (i = 0; i < 6; i += 2) {
+		unsigned short data;
+		tc_writel(PROM_Busy | PROM_Read | (i / 2 + 2), &tr->PROM_Ctl);
+		while (tc_readl(&tr->PROM_Ctl) & PROM_Busy)
+			cpu_relax();
+		data = tc_readl(&tr->PROM_Data);
+		dev->dev_addr[i] = data & 0xff;
+		dev->dev_addr[i+1] = data >> 8;
+	}
+	for (i = 0; i < 6; i++)
+		printk(" %2.2x", dev->dev_addr[i]);
+	printk("\n");
+
+	/* Initialize the device structure. */
+	if (dev->priv == NULL) {
+		dev->priv = kmalloc(sizeof(struct tc35815_local), GFP_KERNEL);
+		if (dev->priv == NULL)
+			return -ENODEV;
+	}
+	lp = dev->priv;
+
+	lp->pdev = pdev;
+
+	memset(lp, 0, sizeof(struct tc35815_local));
+
+	lp->next_module = root_tc35815_dev;
+	root_tc35815_dev = dev;
+
+	if (dev->mem_start > 0) {
+		lp->option = dev->mem_start;
+		if ((lp->option & TC35815_OPT_10M) &&
+		    (lp->option & TC35815_OPT_100M)) {
+			/* if both speed speficied, auto select. */
+			lp->option &= ~(TC35815_OPT_10M | TC35815_OPT_100M);
+		}
+	}
+	//XXX fixme
+        lp->option |= TC35815_OPT_10M;
+
+	/* do auto negotiation */
+	tc35815_phy_chip_init(dev);
+	printk(KERN_INFO "%s: linkspeed %dMbps, %s Duplex\n",
+	       dev->name, lp->linkspeed, lp->fullduplex ? "Full" : "Half");
+
+	dev->open		= tc35815_open;
+	dev->stop		= tc35815_close;
+	dev->tx_timeout         = tc35815_tx_timeout;
+	dev->watchdog_timeo     = TX_TIMEOUT;
+	dev->hard_start_xmit	= tc35815_send_packet;
+	dev->get_stats		= tc35815_get_stats;
+	dev->set_multicast_list = tc35815_set_multicast_list;
+
+#if 0	/* XXX called in init_etherdev */
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+#endif
+
+	return 0;
+}
+
+
+static int
+tc35815_init_queues(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	int i;
+	unsigned long fd_addr;
+
+	if (!lp->fd_buf) {
+		if (sizeof(struct FDesc) +
+		    sizeof(struct BDesc) * RX_BUF_PAGES +
+		    sizeof(struct FDesc) * RX_FD_NUM +
+		    sizeof(struct TxFD) * TX_FD_NUM > PAGE_SIZE * FD_PAGE_NUM) {
+			printk(KERN_WARNING "%s: Invalid Queue Size.\n", dev->name);
+			return -ENOMEM;
+		}
+
+		if ((lp->fd_buf = (void *)__get_free_pages(GFP_KERNEL, FD_PAGE_ORDER)) == 0)
+			return -ENOMEM;
+		for (i = 0; i < RX_BUF_PAGES; i++) {
+			if ((lp->data_buf[i] = (void *)get_free_page(GFP_KERNEL)) == 0) {
+				while (--i >= 0) {
+					free_page((unsigned long)lp->data_buf[i]);
+					lp->data_buf[i] = 0;
+				}
+				free_page((unsigned long)lp->fd_buf);
+				lp->fd_buf = 0;
+				return -ENOMEM;
+			}
+#ifdef __mips__
+			dma_cache_wback_inv((unsigned long)lp->data_buf[i], PAGE_SIZE * FD_PAGE_NUM);
+#endif
+		}
+#ifdef __mips__
+		dma_cache_wback_inv((unsigned long)lp->fd_buf, PAGE_SIZE * FD_PAGE_NUM);
+#endif
+	} else {
+		clear_page(lp->fd_buf);
+#ifdef __mips__
+		dma_cache_wback_inv((unsigned long)lp->fd_buf, PAGE_SIZE * FD_PAGE_NUM);
+#endif
+	}
+#ifdef __mips__
+	fd_addr = (unsigned long)vtonocache(lp->fd_buf);  
+#else
+	fd_addr = (unsigned long)lp->fd_buf;
+#endif
+
+	/* Free Descriptors (for Receive) */
+	lp->rfd_base = (struct RxFD *)fd_addr;
+	fd_addr += sizeof(struct RxFD) * RX_FD_NUM;
+	for (i = 0; i < RX_FD_NUM; i++) {
+		lp->rfd_base[i].fd.FDCtl = cpu_to_le32(FD_CownsFD);
+	}
+	lp->rfd_cur = lp->rfd_base;
+	lp->rfd_limit = (struct RxFD *)(fd_addr -
+					sizeof(struct FDesc) -
+					sizeof(struct BDesc) * 30);
+
+	/* Transmit Descriptors */
+	lp->tfd_base = (struct TxFD *)fd_addr;
+	fd_addr += sizeof(struct TxFD) * TX_FD_NUM;
+	for (i = 0; i < TX_FD_NUM; i++) {
+		lp->tfd_base[i].fd.FDNext = cpu_to_le32(virt_to_bus(&lp->tfd_base[i+1]));
+		lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0);
+		lp->tfd_base[i].fd.FDCtl = cpu_to_le32(0);
+	}
+	lp->tfd_base[TX_FD_NUM-1].fd.FDNext = cpu_to_le32(virt_to_bus(&lp->tfd_base[0]));
+	lp->tfd_start = 0;
+	lp->tfd_end = 0;
+
+	/* Buffer List (for Receive) */
+	lp->fbl_ptr = (struct FrFD *)fd_addr;
+	lp->fbl_ptr->fd.FDNext = cpu_to_le32(virt_to_bus(lp->fbl_ptr));
+	lp->fbl_ptr->fd.FDCtl = cpu_to_le32(RX_BUF_PAGES | FD_CownsFD);
+	for (i = 0; i < RX_BUF_PAGES; i++) {
+		lp->fbl_ptr->bd[i].BuffData = cpu_to_le32(virt_to_bus(lp->data_buf[i]));
+		/* BDID is index of FrFD.bd[] */
+		lp->fbl_ptr->bd[i].BDCtl =
+			cpu_to_le32(BD_CownsBD | (i << BD_RxBDID_SHIFT) | PAGE_SIZE);
+	}
+	lp->fbl_curid = 0;
+
+	return 0;
+}
+
+static void
+tc35815_clear_queues(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	int i;
+
+	for (i = 0; i < TX_FD_NUM; i++) {
+		struct sk_buff *skb = (struct sk_buff *)
+			le32_to_cpu(lp->tfd_base[i].fd.FDSystem);
+		if (skb)
+			dev_kfree_skb_any(skb);
+		lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0);
+	}
+
+	tc35815_init_queues(dev);
+}
+
+static void
+tc35815_free_queues(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	int i;
+
+	if (lp->tfd_base) {
+		for (i = 0; i < TX_FD_NUM; i++) {
+			struct sk_buff *skb = (struct sk_buff *)
+				le32_to_cpu(lp->tfd_base[i].fd.FDSystem);
+			if (skb)
+				dev_kfree_skb_any(skb);
+			lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0);
+		}
+	}
+
+	lp->rfd_base = NULL;
+	lp->rfd_base = NULL;
+	lp->rfd_limit = NULL;
+	lp->rfd_cur = NULL;
+	lp->fbl_ptr = NULL;
+
+	for (i = 0; i < RX_BUF_PAGES; i++) {
+		if (lp->data_buf[i])
+			free_page((unsigned long)lp->data_buf[i]);
+		lp->data_buf[i] = 0;
+	}
+	if (lp->fd_buf)
+		__free_pages(lp->fd_buf, FD_PAGE_ORDER);
+	lp->fd_buf = NULL;
+}
+
+static void
+dump_txfd(struct TxFD *fd)
+{
+	printk("TxFD(%p): %08x %08x %08x %08x\n", fd,
+	       le32_to_cpu(fd->fd.FDNext),
+	       le32_to_cpu(fd->fd.FDSystem),
+	       le32_to_cpu(fd->fd.FDStat),
+	       le32_to_cpu(fd->fd.FDCtl));
+	printk("BD: ");
+	printk(" %08x %08x",
+	       le32_to_cpu(fd->bd.BuffData),
+	       le32_to_cpu(fd->bd.BDCtl));
+	printk("\n");
+}
+
+static int
+dump_rxfd(struct RxFD *fd)
+{
+	int i, bd_count = (le32_to_cpu(fd->fd.FDCtl) & FD_BDCnt_MASK) >> FD_BDCnt_SHIFT;
+	if (bd_count > 8)
+		bd_count = 8;
+	printk("RxFD(%p): %08x %08x %08x %08x\n", fd,
+	       le32_to_cpu(fd->fd.FDNext),
+	       le32_to_cpu(fd->fd.FDSystem),
+	       le32_to_cpu(fd->fd.FDStat),
+	       le32_to_cpu(fd->fd.FDCtl));
+	if (le32_to_cpu(fd->fd.FDCtl) & FD_CownsFD)
+	    return 0;
+	printk("BD: ");
+	for (i = 0; i < bd_count; i++)
+		printk(" %08x %08x",
+		       le32_to_cpu(fd->bd[i].BuffData),
+		       le32_to_cpu(fd->bd[i].BDCtl));
+	printk("\n");
+	return bd_count;
+}
+
+static void
+dump_frfd(struct FrFD *fd)
+{
+	int i;
+	printk("FrFD(%p): %08x %08x %08x %08x\n", fd,
+	       le32_to_cpu(fd->fd.FDNext),
+	       le32_to_cpu(fd->fd.FDSystem),
+	       le32_to_cpu(fd->fd.FDStat),
+	       le32_to_cpu(fd->fd.FDCtl));
+	printk("BD: ");
+	for (i = 0; i < RX_BUF_PAGES; i++)
+		printk(" %08x %08x",
+		       le32_to_cpu(fd->bd[i].BuffData),
+		       le32_to_cpu(fd->bd[i].BDCtl));
+	printk("\n");
+}
+
+static void
+panic_queues(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	int i;
+
+	printk("TxFD base %p, start %d, end %d\n",
+	       lp->tfd_base, lp->tfd_start, lp->tfd_end);
+	printk("RxFD base %p limit %p cur %p\n",
+	       lp->rfd_base, lp->rfd_limit, lp->rfd_cur);
+	printk("FrFD %p\n", lp->fbl_ptr);
+	for (i = 0; i < TX_FD_NUM; i++)
+		dump_txfd(&lp->tfd_base[i]);
+	for (i = 0; i < RX_FD_NUM; i++) {
+		int bd_count = dump_rxfd(&lp->rfd_base[i]);
+		i += (bd_count + 1) / 2;	/* skip BDs */
+	}
+	dump_frfd(lp->fbl_ptr);
+	panic("%s: Illegal queue state.", dev->name);
+}
+
+#if 0
+static void print_buf(char *add, int length)
+{
+	int i;
+	int len = length;
+
+	printk("print_buf(%08x)(%x)\n", (unsigned int) add,length);
+
+	if (len > 100)
+		len = 100;
+	for (i = 0; i < len; i++) {
+		printk(" %2.2X", (unsigned char) add[i]);
+		if (!(i % 16))
+			printk("\n");
+	}
+	printk("\n");
+}
+#endif
+
+static void print_eth(char *add)
+{
+	int i;
+
+	printk("print_eth(%08x)\n", (unsigned int) add);
+	for (i = 0; i < 6; i++)
+		printk(" %2.2X", (unsigned char) add[i + 6]);
+	printk(" =>");
+	for (i = 0; i < 6; i++)
+		printk(" %2.2X", (unsigned char) add[i]);
+	printk(" : %2.2X%2.2X\n", (unsigned char) add[12], (unsigned char) add[13]);
+}
+
+/*
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ */
+static int
+tc35815_open(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	/*
+	 * This is used if the interrupt line can turned off (shared).
+	 * See 3c503.c for an example of selecting the IRQ at config-time.
+	 */
+
+	if (dev->irq == 0  ||
+	    request_irq(dev->irq, &tc35815_interrupt, SA_SHIRQ, cardname, dev)) {
+		return -EAGAIN;
+	}
+
+	tc35815_chip_reset(dev);
+
+	if (tc35815_init_queues(dev) != 0) {
+		free_irq(dev->irq, dev);
+		return -EAGAIN;
+	}
+
+	/* Reset the hardware here. Don't forget to set the station address. */
+	tc35815_chip_init(dev);
+
+	lp->tbusy = 0;
+	netif_start_queue(dev);
+
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+static void tc35815_tx_timeout(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr;
+	int flags;
+
+	save_flags(flags);
+	cli();
+	printk(KERN_WARNING "%s: transmit timed out, status %#x\n",
+	       dev->name, tc_readl(&tr->Tx_Stat));
+	/* Try to restart the adaptor. */
+	tc35815_chip_reset(dev);
+	tc35815_clear_queues(dev);
+	tc35815_chip_init(dev);
+	lp->tbusy=0;
+	restore_flags(flags);
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+}
+
+static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr;
+
+	if (netif_queue_stopped(dev)) {
+		/*
+		 * If we get here, some higher level has decided we are broken.
+		 * There should really be a "kick me" function call instead.
+		 */
+		int tickssofar = jiffies - dev->trans_start;
+		if (tickssofar < 5)
+			return 1;
+		printk(KERN_WARNING "%s: transmit timed out, status %#x\n",
+		       dev->name, tc_readl(&tr->Tx_Stat));
+		/* Try to restart the adaptor. */
+		tc35815_chip_reset(dev);
+		tc35815_clear_queues(dev);
+		tc35815_chip_init(dev);
+		lp->tbusy=0;
+		dev->trans_start = jiffies;
+		netif_wake_queue(dev);
+	}
+
+	/*
+	 * Block a timer-based transmit from overlapping. This could better be
+	 * done with atomic_swap(1, lp->tbusy), but set_bit() works as well.
+	 */
+	if (test_and_set_bit(0, (void*)&lp->tbusy) != 0) {
+		printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
+		dev_kfree_skb_any(skb);
+	} else {
+		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+		unsigned char *buf = skb->data;
+		struct TxFD *txfd = &lp->tfd_base[lp->tfd_start];
+		int flags;
+		lp->stats.tx_bytes += skb->len;
+
+
+#ifdef __mips__
+		dma_cache_wback_inv((unsigned long)buf, length);
+#endif
+
+		save_flags(flags);
+		cli();
+
+		/* failsafe... */
+		if (lp->tfd_start != lp->tfd_end)
+			tc35815_txdone(dev);
+
+
+		txfd->bd.BuffData = cpu_to_le32(virt_to_bus(buf));
+
+		txfd->bd.BDCtl = cpu_to_le32(length);
+		txfd->fd.FDSystem = cpu_to_le32((__u32)skb);
+		txfd->fd.FDCtl = cpu_to_le32(FD_CownsFD | (1 << FD_BDCnt_SHIFT));
+
+		if (lp->tfd_start == lp->tfd_end) {
+			/* Start DMA Transmitter. */
+			txfd->fd.FDNext |= cpu_to_le32(FD_Next_EOL);
+#ifdef GATHER_TXINT
+			txfd->fd.FDCtl |= cpu_to_le32(FD_FrmOpt_IntTx);
+#endif
+			if (tc35815_debug > 2) {
+				printk("%s: starting TxFD.\n", dev->name);
+				dump_txfd(txfd);
+				if (tc35815_debug > 3)
+					print_eth(buf);
+			}
+			tc_writel(virt_to_bus(txfd), &tr->TxFrmPtr);
+		} else {
+			txfd->fd.FDNext &= cpu_to_le32(~FD_Next_EOL);
+			if (tc35815_debug > 2) {
+				printk("%s: queueing TxFD.\n", dev->name);
+				dump_txfd(txfd);
+				if (tc35815_debug > 3)
+					print_eth(buf);
+			}
+		}
+		lp->tfd_start = (lp->tfd_start + 1) % TX_FD_NUM;
+
+		dev->trans_start = jiffies;
+
+		if ((lp->tfd_start + 1) % TX_FD_NUM != lp->tfd_end) {
+			/* we can send another packet */
+			lp->tbusy = 0;
+			netif_start_queue(dev);
+		} else {
+			netif_stop_queue(dev);
+			if (tc35815_debug > 1)
+				printk(KERN_WARNING "%s: TxFD Exhausted.\n", dev->name);
+		}
+		restore_flags(flags);
+	}
+
+	return 0;
+}
+
+#define FATAL_ERROR_INT \
+	(Int_IntPCI | Int_DmParErr | Int_IntNRAbt)
+static void tc35815_fatal_error_interrupt(struct net_device *dev, int status)
+{
+	static int count;
+	printk(KERN_WARNING "%s: Fatal Error Intterrupt (%#x):",
+	       dev->name, status);
+
+	if (status & Int_IntPCI)
+		printk(" IntPCI");
+	if (status & Int_DmParErr)
+		printk(" DmParErr");
+	if (status & Int_IntNRAbt)
+		printk(" IntNRAbt");
+	printk("\n");
+	if (count++ > 100)
+		panic("%s: Too many fatal errors.", dev->name);
+	printk(KERN_WARNING "%s: Resetting %s...\n", dev->name, cardname);
+	/* Try to restart the adaptor. */
+	tc35815_chip_reset(dev);
+	tc35815_clear_queues(dev);
+	tc35815_chip_init(dev);
+}
+
+/*
+ * The typical workload of the driver:
+ *   Handle the network interface interrupts.
+ */
+static void tc35815_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = dev_id;
+	struct tc35815_regs *tr;
+	struct tc35815_local *lp;
+	int status, boguscount = 0;
+
+	if (dev == NULL) {
+		printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
+		return;
+	}
+
+	tr = (struct tc35815_regs*)dev->base_addr;
+	lp = (struct tc35815_local *)dev->priv;
+
+	do {
+		status = tc_readl(&tr->Int_Src);
+		if (status == 0)
+			break;
+		tc_writel(status, &tr->Int_Src);	/* write to clear */
+
+		/* Fatal errors... */
+		if (status & FATAL_ERROR_INT) {
+			tc35815_fatal_error_interrupt(dev, status);
+			break;
+		}
+		/* recoverable errors */
+		if (status & Int_IntFDAEx) {
+			/* disable FDAEx int. (until we make rooms...) */
+			tc_writel(tc_readl(&tr->Int_En) & ~Int_FDAExEn, &tr->Int_En);
+			printk(KERN_WARNING
+			       "%s: Free Descriptor Area Exhausted (%#x).\n",
+			       dev->name, status);
+			lp->stats.rx_dropped++;
+		}
+		if (status & Int_IntBLEx) {
+			/* disable BLEx int. (until we make rooms...) */
+			tc_writel(tc_readl(&tr->Int_En) & ~Int_BLExEn, &tr->Int_En);
+			printk(KERN_WARNING
+			       "%s: Buffer List Exhausted (%#x).\n",
+			       dev->name, status);
+			lp->stats.rx_dropped++;
+		}
+		if (status & Int_IntExBD) {
+			printk(KERN_WARNING
+			       "%s: Excessive Buffer Descriptiors (%#x).\n",
+			       dev->name, status);
+			lp->stats.rx_length_errors++;
+		}
+		/* normal notification */
+		if (status & Int_IntMacRx) {
+			/* Got a packet(s). */
+			lp->lstats.rx_ints++;
+			tc35815_rx(dev);
+		}
+		if (status & Int_IntMacTx) {
+			lp->lstats.tx_ints++;
+			tc35815_txdone(dev);
+		}
+	} while (++boguscount < 20) ;
+
+	return;
+}
+
+/* We have a good packet(s), get it/them out of the buffers. */
+static void
+tc35815_rx(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+	unsigned int fdctl;
+	int i;
+	int buf_free_count = 0;
+	int fd_free_count = 0;
+
+	while (!((fdctl = le32_to_cpu(lp->rfd_cur->fd.FDCtl)) & FD_CownsFD)) {
+		int status = le32_to_cpu(lp->rfd_cur->fd.FDStat);
+		int pkt_len = fdctl & FD_FDLength_MASK;
+		struct RxFD *next_rfd;
+		int bd_count = (fdctl & FD_BDCnt_MASK) >> FD_BDCnt_SHIFT;
+
+		if (tc35815_debug > 2)
+			dump_rxfd(lp->rfd_cur);
+		if (status & Rx_Good) {
+			/* Malloc up new buffer. */
+			struct sk_buff *skb;
+			unsigned char *data;
+			int cur_bd, offset;
+
+			lp->stats.rx_bytes += pkt_len;
+			
+			skb = dev_alloc_skb(pkt_len + 2); /* +2: for reserve */
+			if (skb == NULL) {
+				printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
+				       dev->name);
+				lp->stats.rx_dropped++;
+				break;
+			}
+			skb_reserve(skb, 2);   /* 16 bit alignment */
+			skb->dev = dev;
+
+			data = skb_put(skb, pkt_len);
+
+			/* copy from receive buffer */
+			cur_bd = 0;
+			offset = 0;
+			while (offset < pkt_len && cur_bd < bd_count) {
+				int len = le32_to_cpu(lp->rfd_cur->bd[cur_bd].BDCtl) &
+					BD_BuffLength_MASK;
+				void *rxbuf =
+					bus_to_virt(le32_to_cpu(lp->rfd_cur->bd[cur_bd].BuffData));
+#ifdef __mips__
+				dma_cache_inv((unsigned long)rxbuf, len);
+#endif
+				memcpy(data + offset, rxbuf, len);
+				offset += len;
+				cur_bd++;
+			}
+	//		print_buf(data,pkt_len);
+			if (tc35815_debug > 3)
+				print_eth(data);
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+			lp->stats.rx_packets++;
+		} else {
+			lp->stats.rx_errors++;
+			/* WORKAROUND: LongErr and CRCErr means Overflow. */
+			if ((status & Rx_LongErr) && (status & Rx_CRCErr)) {
+				status &= ~(Rx_LongErr|Rx_CRCErr);
+				status |= Rx_Over;
+			}
+			if (status & Rx_LongErr) lp->stats.rx_length_errors++;
+			if (status & Rx_Over) lp->stats.rx_fifo_errors++;
+			if (status & Rx_CRCErr) lp->stats.rx_crc_errors++;
+			if (status & Rx_Align) lp->stats.rx_frame_errors++;
+		}
+
+		if (bd_count > 0) {
+			/* put Free Buffer back to controller */
+			int bdctl = le32_to_cpu(lp->rfd_cur->bd[bd_count - 1].BDCtl);
+			unsigned char id =
+				(bdctl & BD_RxBDID_MASK) >> BD_RxBDID_SHIFT;
+			if (id >= RX_BUF_PAGES) {
+				printk("%s: invalid BDID.\n", dev->name);
+				panic_queues(dev);
+			}
+			/* free old buffers */
+			while (lp->fbl_curid != id) {
+				bdctl = le32_to_cpu(lp->fbl_ptr->bd[lp->fbl_curid].BDCtl);
+				if (bdctl & BD_CownsBD) {
+					printk("%s: Freeing invalid BD.\n",
+					       dev->name);
+					panic_queues(dev);
+				}
+				/* pass BD to controler */
+				/* Note: BDLength was modified by chip. */
+				lp->fbl_ptr->bd[lp->fbl_curid].BDCtl =
+					cpu_to_le32(BD_CownsBD |
+						    (lp->fbl_curid << BD_RxBDID_SHIFT) |
+						    PAGE_SIZE);
+				lp->fbl_curid =
+					(lp->fbl_curid + 1) % RX_BUF_PAGES;
+				if (tc35815_debug > 2) {
+					printk("%s: Entering new FBD %d\n",
+					       dev->name, lp->fbl_curid);
+					dump_frfd(lp->fbl_ptr);
+				}
+				buf_free_count++;
+			}
+		}
+
+		/* put RxFD back to controller */
+		next_rfd = bus_to_virt(le32_to_cpu(lp->rfd_cur->fd.FDNext));
+#ifdef __mips__
+		next_rfd = (struct RxFD *)vtonocache(next_rfd);
+#endif
+		if (next_rfd < lp->rfd_base || next_rfd > lp->rfd_limit) {
+			printk("%s: RxFD FDNext invalid.\n", dev->name);
+			panic_queues(dev);
+		}
+		for (i = 0; i < (bd_count + 1) / 2 + 1; i++) {
+			/* pass FD to controler */
+			lp->rfd_cur->fd.FDNext = cpu_to_le32(0xdeaddead);	/* for debug */
+			lp->rfd_cur->fd.FDCtl = cpu_to_le32(FD_CownsFD);
+			lp->rfd_cur++;
+			fd_free_count++;
+		}
+
+		lp->rfd_cur = next_rfd;
+	}
+
+	/* re-enable BL/FDA Exhaust interupts. */
+	if (fd_free_count) {
+		tc_writel(tc_readl(&tr->Int_En) | Int_FDAExEn, &tr->Int_En);
+		if (buf_free_count)
+			tc_writel(tc_readl(&tr->Int_En) | Int_BLExEn, &tr->Int_En);
+	}
+}
+
+#ifdef NO_CHECK_CARRIER
+#define TX_STA_ERR	(Tx_ExColl|Tx_Under|Tx_Defer|Tx_LateColl|Tx_TxPar|Tx_SQErr)
+#else
+#define TX_STA_ERR	(Tx_ExColl|Tx_Under|Tx_Defer|Tx_NCarr|Tx_LateColl|Tx_TxPar|Tx_SQErr)
+#endif
+
+static void
+tc35815_check_tx_stat(struct net_device *dev, int status)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	const char *msg = NULL;
+
+	/* count collisions */
+	if (status & Tx_ExColl)
+		lp->stats.collisions += 16;
+	if (status & Tx_TxColl_MASK)
+		lp->stats.collisions += status & Tx_TxColl_MASK;
+
+	/* WORKAROUND: ignore LostCrS in full duplex operation */
+	if (lp->fullduplex)
+		status &= ~Tx_NCarr;
+
+	if (!(status & TX_STA_ERR)) {
+		/* no error. */
+		lp->stats.tx_packets++;
+		return;
+	}
+
+	lp->stats.tx_errors++;
+	if (status & Tx_ExColl) {
+		lp->stats.tx_aborted_errors++;
+		msg = "Excessive Collision.";
+	}
+	if (status & Tx_Under) {
+		lp->stats.tx_fifo_errors++;
+		msg = "Tx FIFO Underrun.";
+	}
+	if (status & Tx_Defer) {
+		lp->stats.tx_fifo_errors++;
+		msg = "Excessive Deferral.";
+	}
+#ifndef NO_CHECK_CARRIER
+	if (status & Tx_NCarr) {
+		lp->stats.tx_carrier_errors++;
+		msg = "Lost Carrier Sense.";
+	}
+#endif
+	if (status & Tx_LateColl) {
+		lp->stats.tx_aborted_errors++;
+		msg = "Late Collision.";
+	}
+	if (status & Tx_TxPar) {
+		lp->stats.tx_fifo_errors++;
+		msg = "Transmit Parity Error.";
+	}
+	if (status & Tx_SQErr) {
+		lp->stats.tx_heartbeat_errors++;
+		msg = "Signal Quality Error.";
+	}
+	if (msg)
+		printk(KERN_WARNING "%s: %s (%#x)\n", dev->name, msg, status);
+}
+
+static void
+tc35815_txdone(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+	struct TxFD *txfd;
+	unsigned int fdctl;
+	int num_done = 0;
+
+	txfd = &lp->tfd_base[lp->tfd_end];
+	while (lp->tfd_start != lp->tfd_end &&
+	       !((fdctl = le32_to_cpu(txfd->fd.FDCtl)) & FD_CownsFD)) {
+		int status = le32_to_cpu(txfd->fd.FDStat);
+		struct sk_buff *skb;
+		unsigned long fdnext = le32_to_cpu(txfd->fd.FDNext);
+
+		if (tc35815_debug > 2) {
+			printk("%s: complete TxFD.\n", dev->name);
+			dump_txfd(txfd);
+		}
+		tc35815_check_tx_stat(dev, status);
+
+		skb = (struct sk_buff *)le32_to_cpu(txfd->fd.FDSystem);
+		if (skb) {
+			dev_kfree_skb_any(skb);
+		}
+		txfd->fd.FDSystem = cpu_to_le32(0);
+
+		num_done++;
+		lp->tfd_end = (lp->tfd_end + 1) % TX_FD_NUM;
+		txfd = &lp->tfd_base[lp->tfd_end];
+		if ((fdnext & ~FD_Next_EOL) != virt_to_bus(txfd)) {
+			printk("%s: TxFD FDNext invalid.\n", dev->name);
+			panic_queues(dev);
+		}
+		if (fdnext & FD_Next_EOL) {
+			/* DMA Transmitter has been stopping... */
+			if (lp->tfd_end != lp->tfd_start) {
+				int head = (lp->tfd_start + TX_FD_NUM - 1) % TX_FD_NUM;
+				struct TxFD* txhead = &lp->tfd_base[head];
+				int qlen = (lp->tfd_start + TX_FD_NUM
+					    - lp->tfd_end) % TX_FD_NUM;
+
+				if (!(le32_to_cpu(txfd->fd.FDCtl) & FD_CownsFD)) {
+					printk("%s: TxFD FDCtl invalid.\n", dev->name);
+					panic_queues(dev);
+				}
+				/* log max queue length */
+				if (lp->lstats.max_tx_qlen < qlen)
+					lp->lstats.max_tx_qlen = qlen;
+
+
+				/* start DMA Transmitter again */
+				txhead->fd.FDNext |= cpu_to_le32(FD_Next_EOL);
+#ifdef GATHER_TXINT
+				txhead->fd.FDCtl |= cpu_to_le32(FD_FrmOpt_IntTx);
+#endif
+				if (tc35815_debug > 2) {
+					printk("%s: start TxFD on queue.\n",
+					       dev->name);
+					dump_txfd(txfd);
+				}
+				tc_writel(virt_to_bus(txfd), &tr->TxFrmPtr);
+			}
+			break;
+		}
+	}
+
+	if (num_done > 0 && lp->tbusy) {
+		lp->tbusy = 0;
+		netif_start_queue(dev);
+	}
+}
+
+/* The inverse routine to tc35815_open(). */
+static int
+tc35815_close(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+
+	lp->tbusy = 1;
+	netif_stop_queue(dev);
+
+	/* Flush the Tx and disable Rx here. */
+
+	tc35815_chip_reset(dev);
+	free_irq(dev->irq, dev);
+
+	tc35815_free_queues(dev);
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *tc35815_get_stats(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+	unsigned long flags;
+
+	if (netif_running(dev)) {
+		save_flags(flags);
+		cli();
+		/* Update the statistics from the device registers. */
+		lp->stats.rx_missed_errors = tc_readl(&tr->Miss_Cnt);
+		restore_flags(flags);
+	}
+
+	return &lp->stats;
+}
+
+static void tc35815_set_cam_entry(struct tc35815_regs *tr, int index, unsigned char *addr)
+{
+	int cam_index = index * 6;
+	unsigned long cam_data;
+	unsigned long saved_addr;
+	saved_addr = tc_readl(&tr->CAM_Adr);
+
+	if (tc35815_debug > 1) {
+		int i;
+		printk(KERN_DEBUG "%s: CAM %d:", cardname, index);
+		for (i = 0; i < 6; i++)
+			printk(" %02x", addr[i]);
+		printk("\n");
+	}
+	if (index & 1) {
+		/* read modify write */
+		tc_writel(cam_index - 2, &tr->CAM_Adr);
+		cam_data = tc_readl(&tr->CAM_Data) & 0xffff0000;
+		cam_data |= addr[0] << 8 | addr[1];
+		tc_writel(cam_data, &tr->CAM_Data);
+		/* write whole word */
+		tc_writel(cam_index + 2, &tr->CAM_Adr);
+		cam_data = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
+		tc_writel(cam_data, &tr->CAM_Data);
+	} else {
+		/* write whole word */
+		tc_writel(cam_index, &tr->CAM_Adr);
+		cam_data = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
+		tc_writel(cam_data, &tr->CAM_Data);
+		/* read modify write */
+		tc_writel(cam_index + 4, &tr->CAM_Adr);
+		cam_data = tc_readl(&tr->CAM_Data) & 0x0000ffff;
+		cam_data |= addr[4] << 24 | (addr[5] << 16);
+		tc_writel(cam_data, &tr->CAM_Data);
+	}
+
+	if (tc35815_debug > 2) {
+		int i;
+		for (i = cam_index / 4; i < cam_index / 4 + 2; i++) {
+			tc_writel(i * 4, &tr->CAM_Adr);
+			printk("CAM 0x%x: %08x",
+			       i * 4, tc_readl(&tr->CAM_Data));
+		}
+	}
+	tc_writel(saved_addr, &tr->CAM_Adr);
+}
+
+
+/*
+ * Set or clear the multicast filter for this adaptor.
+ * num_addrs == -1	Promiscuous mode, receive all packets
+ * num_addrs == 0	Normal mode, clear multicast list
+ * num_addrs > 0	Multicast mode, receive normal and MC packets,
+ *			and do best-effort filtering.
+ */
+static void
+tc35815_set_multicast_list(struct net_device *dev)
+{
+	struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+
+	if (dev->flags&IFF_PROMISC)
+	{
+		/* Enable promiscuous mode */
+		tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc | CAM_StationAcc, &tr->CAM_Ctl);
+	}
+	else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > CAM_ENTRY_MAX - 3)
+	{
+		/* CAM 0, 1, 20 are reserved. */
+		/* Disable promiscuous mode, use normal mode. */
+		tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc, &tr->CAM_Ctl);
+	}
+	else if(dev->mc_count)
+	{
+		struct dev_mc_list* cur_addr = dev->mc_list;
+		int i;
+		int ena_bits = CAM_Ena_Bit(CAM_ENTRY_SOURCE);
+
+		tc_writel(0, &tr->CAM_Ctl);
+		/* Walk the address list, and load the filter */
+		for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
+			if (!cur_addr)
+				break;
+			/* entry 0,1 is reserved. */
+			tc35815_set_cam_entry(tr, i + 2, cur_addr->dmi_addr);
+			ena_bits |= CAM_Ena_Bit(i + 2);
+		}
+		tc_writel(ena_bits, &tr->CAM_Ena);
+		tc_writel(CAM_CompEn | CAM_BroadAcc, &tr->CAM_Ctl);
+	}
+	else {
+		tc_writel(CAM_Ena_Bit(CAM_ENTRY_SOURCE), &tr->CAM_Ena);
+		tc_writel(CAM_CompEn | CAM_BroadAcc, &tr->CAM_Ctl);
+	}
+}
+
+static unsigned long tc_phy_read(struct tc35815_regs *tr, int phy, int phy_reg)
+{
+	unsigned long data;
+	int flags;
+	save_flags(flags);
+	cli();
+	tc_writel(MD_CA_Busy | (phy << 5) | phy_reg, &tr->MD_CA);
+	while (tc_readl(&tr->MD_CA) & MD_CA_Busy)
+		cpu_relax();
+	data = tc_readl(&tr->MD_Data);
+	restore_flags(flags);
+	return data;
+}
+
+static void tc_phy_write(unsigned long d, struct tc35815_regs *tr, int phy, int phy_reg)
+{
+	int flags;
+	save_flags(flags);
+	cli();
+	tc_writel(d, &tr->MD_Data);
+	tc_writel(MD_CA_Busy | MD_CA_Wr | (phy << 5) | phy_reg, &tr->MD_CA);
+	while (tc_readl(&tr->MD_CA) & MD_CA_Busy)
+		cpu_relax();
+	restore_flags(flags);
+}
+
+static void tc35815_phy_chip_init(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+	static int first = 1;
+	unsigned short ctl;
+
+	if (first) {
+		unsigned short id0, id1;
+		int count;
+		first = 0;
+
+		/* first data written to the PHY will be an ID number */
+		tc_phy_write(0, tr, 0, MII_CONTROL);	/* ID:0 */
+#if 0
+		tc_phy_write(MIICNTL_RESET, tr, 0, MII_CONTROL);
+		printk(KERN_INFO "%s: Resetting PHY...", dev->name);
+		while (tc_phy_read(tr, 0, MII_CONTROL) & MIICNTL_RESET)
+			;
+		printk("\n");
+		tc_phy_write(MIICNTL_AUTO|MIICNTL_SPEED|MIICNTL_FDX, tr, 0,
+			     MII_CONTROL);
+#endif
+		id0 = tc_phy_read(tr, 0, MII_PHY_ID0);
+		id1 = tc_phy_read(tr, 0, MII_PHY_ID1);
+		printk(KERN_DEBUG "%s: PHY ID %04x %04x\n", dev->name,
+		       id0, id1);
+		if (lp->option & TC35815_OPT_10M) {
+			lp->linkspeed = 10;
+			lp->fullduplex = (lp->option & TC35815_OPT_FULLDUP) != 0;
+		} else if (lp->option & TC35815_OPT_100M) {
+			lp->linkspeed = 100;
+			lp->fullduplex = (lp->option & TC35815_OPT_FULLDUP) != 0;
+		} else {
+			/* auto negotiation */
+			unsigned long neg_result;
+			tc_phy_write(MIICNTL_AUTO | MIICNTL_RST_AUTO, tr, 0, MII_CONTROL);
+			printk(KERN_INFO "%s: Auto Negotiation...", dev->name);
+			count = 0;
+			while (!(tc_phy_read(tr, 0, MII_STATUS) & MIISTAT_AUTO_DONE)) {
+				if (count++ > 5000) {
+					printk(" failed. Assume 10Mbps\n");
+					lp->linkspeed = 10;
+					lp->fullduplex = 0;
+					goto done;
+				}
+				if (count % 512 == 0)
+					printk(".");
+				mdelay(1);
+			}
+			printk(" done.\n");
+			neg_result = tc_phy_read(tr, 0, MII_ANLPAR);
+			if (neg_result & (MII_AN_TX_FDX | MII_AN_TX_HDX))
+				lp->linkspeed = 100;
+			else
+				lp->linkspeed = 10;
+			if (neg_result & (MII_AN_TX_FDX | MII_AN_10_FDX))
+				lp->fullduplex = 1;
+			else
+				lp->fullduplex = 0;
+		done:
+			;
+		}
+	}
+
+	ctl = 0;
+	if (lp->linkspeed == 100)
+		ctl |= MIICNTL_SPEED;
+	if (lp->fullduplex)
+		ctl |= MIICNTL_FDX;
+	tc_phy_write(ctl, tr, 0, MII_CONTROL);
+
+	if (lp->fullduplex) {
+		tc_writel(tc_readl(&tr->MAC_Ctl) | MAC_FullDup, &tr->MAC_Ctl);
+	}
+}
+
+static void tc35815_chip_reset(struct net_device *dev)
+{
+	struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+
+	/* reset the controller */
+	tc_writel(MAC_Reset, &tr->MAC_Ctl);
+	while (tc_readl(&tr->MAC_Ctl) & MAC_Reset)
+		cpu_relax();
+
+	tc_writel(0, &tr->MAC_Ctl);
+
+	/* initialize registers to default value */
+	tc_writel(0, &tr->DMA_Ctl);
+	tc_writel(0, &tr->TxThrsh);
+	tc_writel(0, &tr->TxPollCtr);
+	tc_writel(0, &tr->RxFragSize);
+	tc_writel(0, &tr->Int_En);
+	tc_writel(0, &tr->FDA_Bas);
+	tc_writel(0, &tr->FDA_Lim);
+	tc_writel(0xffffffff, &tr->Int_Src);	/* Write 1 to clear */
+	tc_writel(0, &tr->CAM_Ctl);
+	tc_writel(0, &tr->Tx_Ctl);
+	tc_writel(0, &tr->Rx_Ctl);
+	tc_writel(0, &tr->CAM_Ena);
+	(void)tc_readl(&tr->Miss_Cnt);	/* Read to clear */
+
+}
+
+static void tc35815_chip_init(struct net_device *dev)
+{
+	struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+	struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+	int flags;
+	unsigned long txctl = TX_CTL_CMD;
+
+	tc35815_phy_chip_init(dev);
+
+	/* load station address to CAM */
+	tc35815_set_cam_entry(tr, CAM_ENTRY_SOURCE, dev->dev_addr);
+
+	/* Enable CAM (broadcast and unicast) */
+	tc_writel(CAM_Ena_Bit(CAM_ENTRY_SOURCE), &tr->CAM_Ena);
+	tc_writel(CAM_CompEn | CAM_BroadAcc, &tr->CAM_Ctl);
+
+	save_flags(flags);
+	cli();
+
+	tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl);
+
+	tc_writel(RxFrag_EnPack | ETH_ZLEN, &tr->RxFragSize);	/* Packing */
+	tc_writel(0, &tr->TxPollCtr);	/* Batch mode */
+	tc_writel(TX_THRESHOLD, &tr->TxThrsh);
+	tc_writel(INT_EN_CMD, &tr->Int_En);
+
+	/* set queues */
+	tc_writel(virt_to_bus(lp->rfd_base), &tr->FDA_Bas);
+	tc_writel((unsigned long)lp->rfd_limit - (unsigned long)lp->rfd_base,
+		  &tr->FDA_Lim);
+	/*
+	 * Activation method:
+	 * First, enable eht MAC Transmitter and the DMA Receive circuits.
+	 * Then enable the DMA Transmitter and the MAC Receive circuits.
+	 */
+	tc_writel(virt_to_bus(lp->fbl_ptr), &tr->BLFrmPtr);	/* start DMA receiver */
+	tc_writel(RX_CTL_CMD, &tr->Rx_Ctl);	/* start MAC receiver */
+	/* start MAC transmitter */
+	/* WORKAROUND: ignore LostCrS in full duplex operation */
+	if (lp->fullduplex)
+		txctl = TX_CTL_CMD & ~Tx_EnLCarr;
+#ifdef GATHER_TXINT
+	txctl &= ~Tx_EnComp;	/* disable global tx completion int. */
+#endif
+	tc_writel(txctl, &tr->Tx_Ctl);
+#if 0	/* No need to polling */
+	tc_writel(virt_to_bus(lp->tfd_base), &tr->TxFrmPtr);	/* start DMA transmitter */
+#endif
+	restore_flags(flags);
+}
+
+
+/* XXX */
+void
+tc35815_killall(void)
+{
+	struct net_device *dev;
+
+	for (dev = root_tc35815_dev; dev; dev = ((struct tc35815_local *)dev->priv)->next_module) {
+		if (dev->flags&IFF_UP){
+			dev->stop(dev);
+		}
+	}
+}
+
+static struct pci_driver tc35815_driver = {
+	name:  TC35815_MODULE_NAME,
+	probe: tc35815_probe,
+	remove: NULL,
+	id_table: tc35815_pci_tbl,
+};
+
+static int __init tc35815_init_module(void)
+{
+	int err;
+
+	if ((err = pci_module_init(&tc35815_driver)) < 0 )
+		       return err;      
+	else
+		return 0;
+}
+
+static void __exit tc35815_cleanup_module(void)
+{
+	struct net_device *next_dev;
+
+	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+	while (root_tc35815_dev) {
+		struct net_device *dev = root_tc35815_dev;
+		next_dev = ((struct tc35815_local *)dev->priv)->next_module;
+		kfree(dev->priv);
+		iounmap((void *)(dev->base_addr));
+		unregister_netdev(dev);
+		kfree(dev);
+		root_tc35815_dev = next_dev;
+	}
+}
+module_init(tc35815_init_module);
+module_exit(tc35815_cleanup_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tg3.c linux/drivers/net/tg3.c
--- linux.orig/drivers/net/tg3.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/tg3.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,6529 @@
+/* $Id: tg3.c,v 1.43.2.80 2002/03/14 00:10:04 davem Exp $
+ * tg3.c: Broadcom Tigon3 ethernet driver.
+ *
+ * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2001, 2002 Jeff Garzik (jgarzik@mandrakesoft.com)
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/if_vlan.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#ifndef PCI_DMA_BUS_IS_PHYS
+#define PCI_DMA_BUS_IS_PHYS 1
+#endif
+
+/* Either I can't figure out how they secretly implemented it (ie. RXD flags
+ * for mini ring, where it should go in NIC sram, and how many entries the NIC
+ * firmware expects) or it isn't really fully implemented.  Perhaps Broadcom
+ * wants people to pay for a "performance enhanced" version of their firmware +
+ * binary-only driver that has the mini ring actually implemented.
+ * These kids today... -DaveM
+ */
+#define TG3_MINI_RING_WORKS 0
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define TG3_VLAN_TAG_USED 1
+#else
+#define TG3_VLAN_TAG_USED 0
+#endif
+
+#include "tg3.h"
+
+#define DRV_MODULE_NAME		"tg3"
+#define PFX DRV_MODULE_NAME	": "
+#define DRV_MODULE_VERSION	"0.99"
+#define DRV_MODULE_RELDATE	"Jun 11, 2002"
+
+#define TG3_DEF_MAC_MODE	0
+#define TG3_DEF_RX_MODE		0
+#define TG3_DEF_TX_MODE		0
+#define TG3_DEF_MSG_ENABLE	  \
+	(NETIF_MSG_DRV		| \
+	 NETIF_MSG_PROBE	| \
+	 NETIF_MSG_LINK		| \
+	 NETIF_MSG_TIMER	| \
+	 NETIF_MSG_IFDOWN	| \
+	 NETIF_MSG_IFUP		| \
+	 NETIF_MSG_RX_ERR	| \
+	 NETIF_MSG_TX_ERR)
+
+/* length of time before we decide the hardware is borked,
+ * and dev->tx_timeout() should be called to fix the problem
+ */
+#define TG3_TX_TIMEOUT			(5 * HZ)
+
+/* hardware minimum and maximum for a single frame's data payload */
+#define TG3_MIN_MTU			60
+#define TG3_MAX_MTU			9000
+
+/* These numbers seem to be hard coded in the NIC firmware somehow.
+ * You can't change the ring sizes, but you can change where you place
+ * them in the NIC onboard memory.
+ */
+#define TG3_RX_RING_SIZE		512
+#define TG3_DEF_RX_RING_PENDING		200
+#if TG3_MINI_RING_WORKS
+#define TG3_RX_MINI_RING_SIZE		256 /* ??? */
+#define TG3_DEF_RX_MINI_RING_PENDING	100
+#endif
+#define TG3_RX_JUMBO_RING_SIZE		256
+#define TG3_DEF_RX_JUMBO_RING_PENDING	100
+#define TG3_RX_RCB_RING_SIZE		1024
+#define TG3_TX_RING_SIZE		512
+#define TG3_DEF_TX_RING_PENDING		(TG3_TX_RING_SIZE - 1)
+
+#define TG3_RX_RING_BYTES	(sizeof(struct tg3_rx_buffer_desc) * \
+				 TG3_RX_RING_SIZE)
+#if TG3_MINI_RING_WORKS
+#define TG3_RX_MINI_RING_BYTES	(sizeof(struct tg3_rx_buffer_desc) * \
+				 TG3_RX_MINI_RING_SIZE)
+#endif
+#define TG3_RX_JUMBO_RING_BYTES	(sizeof(struct tg3_rx_buffer_desc) * \
+			         TG3_RX_JUMBO_RING_SIZE)
+#define TG3_RX_RCB_RING_BYTES	(sizeof(struct tg3_rx_buffer_desc) * \
+			         TG3_RX_RCB_RING_SIZE)
+#define TG3_TX_RING_BYTES	(sizeof(struct tg3_tx_buffer_desc) * \
+				 TG3_TX_RING_SIZE)
+#define TX_RING_GAP(TP)	\
+	(TG3_TX_RING_SIZE - (TP)->tx_pending)
+#define TX_BUFFS_AVAIL(TP)						\
+	(((TP)->tx_cons <= (TP)->tx_prod) ?				\
+	  (TP)->tx_cons + (TP)->tx_pending - (TP)->tx_prod :		\
+	  (TP)->tx_cons - (TP)->tx_prod - TX_RING_GAP(TP))
+#define NEXT_TX(N)		(((N) + 1) & (TG3_TX_RING_SIZE - 1))
+
+#define RX_PKT_BUF_SZ		(1536 + tp->rx_offset + 64)
+#if TG3_MINI_RING_WORKS
+#define RX_MINI_PKT_BUF_SZ	(256 + tp->rx_offset + 64)
+#endif
+#define RX_JUMBO_PKT_BUF_SZ	(9046 + tp->rx_offset + 64)
+
+/* minimum number of free TX descriptors required to wake up TX process */
+#define TG3_TX_WAKEUP_THRESH		(TG3_TX_RING_SIZE / 4)
+
+static char version[] __devinitdata =
+	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@mandrakesoft.com)");
+MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM(tg3_debug, "i");
+MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value");
+
+static int tg3_debug = -1;	/* -1 == use TG3_DEF_MSG_ENABLE as value */
+
+static struct pci_device_id tg3_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5701,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_SYSKONNECT, 0x4400,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, tg3_pci_tbl);
+
+static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
+{
+	if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&tp->indirect_lock, flags);
+		pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
+		pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
+		spin_unlock_irqrestore(&tp->indirect_lock, flags);
+	} else {
+		writel(val, tp->regs + off);
+	}
+}
+
+#define tw32(reg,val)		tg3_write_indirect_reg32(tp,(reg),(val))
+#define tw32_mailbox(reg, val)	writel(((val) & 0xffffffff), tp->regs + (reg))
+#define tw16(reg,val)		writew(((val) & 0xffff), tp->regs + (reg))
+#define tw8(reg,val)		writeb(((val) & 0xff), tp->regs + (reg))
+#define tr32(reg)		readl(tp->regs + (reg))
+#define tr16(reg)		readw(tp->regs + (reg))
+#define tr8(reg)		readb(tp->regs + (reg))
+
+static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&tp->indirect_lock, flags);
+	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
+	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
+
+	/* Always leave this as zero. */
+	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+	spin_unlock_irqrestore(&tp->indirect_lock, flags);
+}
+
+static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&tp->indirect_lock, flags);
+	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
+	pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
+
+	/* Always leave this as zero. */
+	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+	spin_unlock_irqrestore(&tp->indirect_lock, flags);
+}
+
+static void tg3_disable_ints(struct tg3 *tp)
+{
+	tw32(TG3PCI_MISC_HOST_CTRL,
+	     (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
+	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+}
+
+static void tg3_enable_ints(struct tg3 *tp)
+{
+	tw32(TG3PCI_MISC_HOST_CTRL,
+	     (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
+	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000);
+
+	if (tp->hw_status->status & SD_STATUS_UPDATED)
+		tw32(GRC_LOCAL_CTRL,
+		     tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+}
+
+#define PHY_BUSY_LOOPS	5000
+
+static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
+{
+	u32 frame_val;
+	int loops, ret;
+
+	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
+		tw32(MAC_MI_MODE,
+		     (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
+		udelay(40);
+	}
+
+	*val = 0xffffffff;
+
+	frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+		      MI_COM_PHY_ADDR_MASK);
+	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
+		      MI_COM_REG_ADDR_MASK);
+	frame_val |= (MI_COM_CMD_READ | MI_COM_START);
+	
+	tw32(MAC_MI_COM, frame_val);
+
+	loops = PHY_BUSY_LOOPS;
+	while (loops-- > 0) {
+		frame_val = tr32(MAC_MI_COM);
+
+		if ((frame_val & MI_COM_BUSY) == 0) {
+			udelay(5);
+			frame_val = tr32(MAC_MI_COM);
+			break;
+		}
+		udelay(10);
+	}
+
+	ret = -EBUSY;
+	if (loops > 0) {
+		*val = frame_val & MI_COM_DATA_MASK;
+		ret = 0;
+	}
+
+	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
+		tw32(MAC_MI_MODE, tp->mi_mode);
+		udelay(40);
+	}
+
+	return ret;
+}
+
+static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
+{
+	u32 frame_val;
+	int loops, ret;
+
+	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
+		tw32(MAC_MI_MODE,
+		     (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
+		udelay(40);
+	}
+
+	frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+		      MI_COM_PHY_ADDR_MASK);
+	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
+		      MI_COM_REG_ADDR_MASK);
+	frame_val |= (val & MI_COM_DATA_MASK);
+	frame_val |= (MI_COM_CMD_WRITE | MI_COM_START);
+	
+	tw32(MAC_MI_COM, frame_val);
+
+	loops = PHY_BUSY_LOOPS;
+	while (loops-- > 0) {
+		frame_val = tr32(MAC_MI_COM);
+		if ((frame_val & MI_COM_BUSY) == 0) {
+			udelay(5);
+			frame_val = tr32(MAC_MI_COM);
+			break;
+		}
+		udelay(10);
+	}
+
+	ret = -EBUSY;
+	if (loops > 0)
+		ret = 0;
+
+	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
+		tw32(MAC_MI_MODE, tp->mi_mode);
+		udelay(40);
+	}
+
+	return ret;
+}
+
+/* This will reset the tigon3 PHY if there is no valid
+ * link unless the FORCE argument is non-zero.
+ */
+static int tg3_phy_reset(struct tg3 *tp, int force)
+{
+	u32 phy_status, phy_control;
+	int err, limit;
+
+	err  = tg3_readphy(tp, MII_BMSR, &phy_status);
+	err |= tg3_readphy(tp, MII_BMSR, &phy_status);
+	if (err != 0)
+		return -EBUSY;
+
+	/* If we have link, and not forcing a reset, then nothing
+	 * to do.
+	 */
+	if ((phy_status & BMSR_LSTATUS) != 0 && (force == 0))
+		return 0;
+
+	/* OK, reset it, and poll the BMCR_RESET bit until it
+	 * clears or we time out.
+	 */
+	phy_control = BMCR_RESET;
+	err = tg3_writephy(tp, MII_BMCR, phy_control);
+	if (err != 0)
+		return -EBUSY;
+
+	limit = 5000;
+	while (limit--) {
+		err = tg3_readphy(tp, MII_BMCR, &phy_control);
+		if (err != 0)
+			return -EBUSY;
+
+		if ((phy_control & BMCR_RESET) == 0) {
+			udelay(40);
+			return 0;
+		}
+		udelay(10);
+	}
+
+	return -EBUSY;
+}
+
+static int tg3_setup_phy(struct tg3 *);
+static int tg3_halt(struct tg3 *);
+
+static int tg3_set_power_state(struct tg3 *tp, int state)
+{
+	u32 misc_host_ctrl;
+	u16 power_control, power_caps;
+	int pm = tp->pm_cap;
+
+	/* Make sure register accesses (indirect or otherwise)
+	 * will function correctly.
+	 */
+	pci_write_config_dword(tp->pdev,
+			       TG3PCI_MISC_HOST_CTRL,
+			       tp->misc_host_ctrl);
+
+	pci_read_config_word(tp->pdev,
+			     pm + PCI_PM_CTRL,
+			     &power_control);
+	power_control |= PCI_PM_CTRL_PME_STATUS;
+	power_control &= ~(PCI_PM_CTRL_STATE_MASK);
+	switch (state) {
+	case 0:
+		power_control |= 0;
+		pci_write_config_word(tp->pdev,
+				      pm + PCI_PM_CTRL,
+				      power_control);
+		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
+		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
+		return 0;
+
+	case 1:
+		power_control |= 1;
+		break;
+
+	case 2:
+		power_control |= 2;
+		break;
+
+	case 3:
+		power_control |= 3;
+		break;
+
+	default:
+		printk(KERN_WARNING "%s: Invalid power state (%d) requested.\n",
+		       tp->dev->name, state);
+		return -EINVAL;
+	};
+
+	power_control |= PCI_PM_CTRL_PME_ENABLE;
+
+	misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
+	tw32(TG3PCI_MISC_HOST_CTRL,
+	     misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
+
+	if (tp->link_config.phy_is_low_power == 0) {
+		tp->link_config.phy_is_low_power = 1;
+		tp->link_config.orig_speed = tp->link_config.speed;
+		tp->link_config.orig_duplex = tp->link_config.duplex;
+		tp->link_config.orig_autoneg = tp->link_config.autoneg;
+	}
+
+	tp->link_config.speed = SPEED_10;
+	tp->link_config.autoneg = AUTONEG_ENABLE;
+	tg3_setup_phy(tp);
+
+	tg3_halt(tp);
+
+	pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps);
+
+	if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
+		u32 mac_mode;
+
+		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
+
+		mac_mode = MAC_MODE_PORT_MODE_MII |
+			MAC_MODE_LINK_POLARITY;
+
+		if (((power_caps & PCI_PM_CAP_PME_D3cold) &&
+		     (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)))
+			mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
+
+		tw32(MAC_MODE, mac_mode);
+		tw32(MAC_RX_MODE, RX_MODE_ENABLE);
+	}
+
+	if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) {
+		tw32(TG3PCI_CLOCK_CTRL,
+		     (CLOCK_CTRL_RXCLK_DISABLE |
+		      CLOCK_CTRL_TXCLK_DISABLE |
+		      CLOCK_CTRL_ALTCLK));
+		tw32(TG3PCI_CLOCK_CTRL,
+		     (CLOCK_CTRL_RXCLK_DISABLE |
+		      CLOCK_CTRL_TXCLK_DISABLE |
+		      CLOCK_CTRL_44MHZ_CORE));
+		tw32(TG3PCI_CLOCK_CTRL,
+		     (CLOCK_CTRL_RXCLK_DISABLE |
+		      CLOCK_CTRL_TXCLK_DISABLE |
+		      CLOCK_CTRL_ALTCLK |
+		      CLOCK_CTRL_44MHZ_CORE));
+	} else {
+		tw32(TG3PCI_CLOCK_CTRL,
+		     (CLOCK_CTRL_RXCLK_DISABLE |
+		      CLOCK_CTRL_TXCLK_DISABLE |
+		      CLOCK_CTRL_ALTCLK |
+		      CLOCK_CTRL_PWRDOWN_PLL133));
+	}
+
+	udelay(40);
+
+	if ((power_caps & PCI_PM_CAP_PME_D3cold) &&
+	    (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
+		/* Move to auxilliary power. */
+		tw32(GRC_LOCAL_CTRL,
+		     (GRC_LCLCTRL_GPIO_OE0 |
+		      GRC_LCLCTRL_GPIO_OE1 |
+		      GRC_LCLCTRL_GPIO_OE2 |
+		      GRC_LCLCTRL_GPIO_OUTPUT0 |
+		      GRC_LCLCTRL_GPIO_OUTPUT1));
+	}
+
+	/* Finally, set the new power state. */
+	pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
+
+	return 0;
+}
+
+static void tg3_link_report(struct tg3 *tp)
+{
+	if (!netif_carrier_ok(tp->dev)) {
+		printk("%s: Link is down.\n", tp->dev->name);
+	} else {
+		printk("%s: Link is up at %d Mbps, %s duplex.\n",
+		       tp->dev->name,
+		       (tp->link_config.active_speed == SPEED_1000 ?
+			1000 :
+			(tp->link_config.active_speed == SPEED_100 ?
+			 100 : 10)),
+		       (tp->link_config.active_duplex == DUPLEX_FULL ?
+			"full" : "half"));
+
+		printk("%s: Flow control is %s for TX and %s for RX.\n",
+		       tp->dev->name,
+		       (tp->tg3_flags & TG3_FLAG_TX_PAUSE) ? "on" : "off",
+		       (tp->tg3_flags & TG3_FLAG_RX_PAUSE) ? "on" : "off");
+	}
+}
+
+static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv)
+{
+	u32 new_tg3_flags = 0;
+
+	if (local_adv & ADVERTISE_PAUSE_CAP) {
+		if (local_adv & ADVERTISE_PAUSE_ASYM) {
+			if (remote_adv & LPA_PAUSE_CAP)
+				new_tg3_flags |=
+					(TG3_FLAG_RX_PAUSE |
+					 TG3_FLAG_TX_PAUSE);
+			else if (remote_adv & LPA_PAUSE_ASYM)
+				new_tg3_flags |=
+					(TG3_FLAG_RX_PAUSE);
+		} else {
+			if (remote_adv & LPA_PAUSE_CAP)
+				new_tg3_flags |=
+					(TG3_FLAG_RX_PAUSE |
+					 TG3_FLAG_TX_PAUSE);
+		}
+	} else if (local_adv & ADVERTISE_PAUSE_ASYM) {
+		if ((remote_adv & LPA_PAUSE_CAP) &&
+		    (remote_adv & LPA_PAUSE_ASYM))
+			new_tg3_flags |= TG3_FLAG_TX_PAUSE;
+	}
+
+	tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE);
+	tp->tg3_flags |= new_tg3_flags;
+
+	if (new_tg3_flags & TG3_FLAG_RX_PAUSE)
+		tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
+	else
+		tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
+
+	if (new_tg3_flags & TG3_FLAG_TX_PAUSE)
+		tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
+	else
+		tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
+}
+
+static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
+{
+	switch (val & MII_TG3_AUX_STAT_SPDMASK) {
+	case MII_TG3_AUX_STAT_10HALF:
+		*speed = SPEED_10;
+		*duplex = DUPLEX_HALF;
+		break;
+
+	case MII_TG3_AUX_STAT_10FULL:
+		*speed = SPEED_10;
+		*duplex = DUPLEX_FULL;
+		break;
+
+	case MII_TG3_AUX_STAT_100HALF:
+		*speed = SPEED_100;
+		*duplex = DUPLEX_HALF;
+		break;
+
+	case MII_TG3_AUX_STAT_100FULL:
+		*speed = SPEED_100;
+		*duplex = DUPLEX_FULL;
+		break;
+
+	case MII_TG3_AUX_STAT_1000HALF:
+		*speed = SPEED_1000;
+		*duplex = DUPLEX_HALF;
+		break;
+
+	case MII_TG3_AUX_STAT_1000FULL:
+		*speed = SPEED_1000;
+		*duplex = DUPLEX_FULL;
+		break;
+
+	default:
+		*speed = SPEED_INVALID;
+		*duplex = DUPLEX_INVALID;
+		break;
+	};
+}
+
+static int tg3_phy_copper_begin(struct tg3 *tp, int wait_for_link)
+{
+	u32 new_adv;
+	int i;
+
+	if (tp->link_config.phy_is_low_power) {
+		/* Entering low power mode.  Disable gigabit and
+		 * 100baseT advertisements.
+		 */
+		tg3_writephy(tp, MII_TG3_CTRL, 0);
+
+		new_adv = (ADVERTISE_10HALF | ADVERTISE_10FULL |
+			   ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+		if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
+			new_adv |= (ADVERTISE_100HALF | ADVERTISE_100FULL);
+
+		tg3_writephy(tp, MII_ADVERTISE, new_adv);
+	} else if (tp->link_config.speed == SPEED_INVALID) {
+		tp->link_config.advertising =
+			(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+			 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+			 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
+			 ADVERTISED_Autoneg | ADVERTISED_MII);
+
+		if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+			tp->link_config.advertising &=
+				~(ADVERTISED_1000baseT_Half |
+				  ADVERTISED_1000baseT_Full);
+
+		new_adv = (ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+		if (tp->link_config.advertising & ADVERTISED_10baseT_Half)
+			new_adv |= ADVERTISE_10HALF;
+		if (tp->link_config.advertising & ADVERTISED_10baseT_Full)
+			new_adv |= ADVERTISE_10FULL;
+		if (tp->link_config.advertising & ADVERTISED_100baseT_Half)
+			new_adv |= ADVERTISE_100HALF;
+		if (tp->link_config.advertising & ADVERTISED_100baseT_Full)
+			new_adv |= ADVERTISE_100FULL;
+		tg3_writephy(tp, MII_ADVERTISE, new_adv);
+
+		if (tp->link_config.advertising &
+		    (ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full)) {
+			new_adv = 0;
+			if (tp->link_config.advertising & ADVERTISED_1000baseT_Half)
+				new_adv |= MII_TG3_CTRL_ADV_1000_HALF;
+			if (tp->link_config.advertising & ADVERTISED_1000baseT_Full)
+				new_adv |= MII_TG3_CTRL_ADV_1000_FULL;
+			if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+			    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
+				new_adv |= (MII_TG3_CTRL_AS_MASTER |
+					    MII_TG3_CTRL_ENABLE_AS_MASTER);
+			tg3_writephy(tp, MII_TG3_CTRL, new_adv);
+		} else {
+			tg3_writephy(tp, MII_TG3_CTRL, 0);
+		}
+	} else {
+		/* Asking for a specific link mode. */
+		if (tp->link_config.speed == SPEED_1000) {
+			new_adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
+			tg3_writephy(tp, MII_ADVERTISE, new_adv);
+
+			if (tp->link_config.duplex == DUPLEX_FULL)
+				new_adv = MII_TG3_CTRL_ADV_1000_FULL;
+			else
+				new_adv = MII_TG3_CTRL_ADV_1000_HALF;
+			if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+			    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
+				new_adv |= (MII_TG3_CTRL_AS_MASTER |
+					    MII_TG3_CTRL_ENABLE_AS_MASTER);
+			tg3_writephy(tp, MII_TG3_CTRL, new_adv);
+		} else {
+			tg3_writephy(tp, MII_TG3_CTRL, 0);
+
+			new_adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
+			if (tp->link_config.speed == SPEED_100) {
+				if (tp->link_config.duplex == DUPLEX_FULL)
+					new_adv |= ADVERTISE_100FULL;
+				else
+					new_adv |= ADVERTISE_100HALF;
+			} else {
+				if (tp->link_config.duplex == DUPLEX_FULL)
+					new_adv |= ADVERTISE_10FULL;
+				else
+					new_adv |= ADVERTISE_10HALF;
+			}
+			tg3_writephy(tp, MII_ADVERTISE, new_adv);
+		}
+	}
+
+	if (tp->link_config.autoneg == AUTONEG_DISABLE &&
+	    tp->link_config.speed != SPEED_INVALID) {
+		u32 bmcr, orig_bmcr;
+
+		tp->link_config.active_speed = tp->link_config.speed;
+		tp->link_config.active_duplex = tp->link_config.duplex;
+
+		bmcr = 0;
+		switch (tp->link_config.speed) {
+		default:
+		case SPEED_10:
+			break;
+
+		case SPEED_100:
+			bmcr |= BMCR_SPEED100;
+			break;
+
+		case SPEED_1000:
+			bmcr |= TG3_BMCR_SPEED1000;
+			break;
+		};
+
+		if (tp->link_config.duplex == DUPLEX_FULL)
+			bmcr |= BMCR_FULLDPLX;
+
+		tg3_readphy(tp, MII_BMCR, &orig_bmcr);
+		if (bmcr != orig_bmcr) {
+			tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK);
+			for (i = 0; i < 15000; i++) {
+				u32 tmp;
+
+				udelay(10);
+				tg3_readphy(tp, MII_BMSR, &tmp);
+				tg3_readphy(tp, MII_BMSR, &tmp);
+				if (!(tmp & BMSR_LSTATUS)) {
+					udelay(40);
+					break;
+				}
+			}
+			tg3_writephy(tp, MII_BMCR, bmcr);
+			udelay(40);
+		}
+	} else {
+		tg3_writephy(tp, MII_BMCR,
+			     BMCR_ANENABLE | BMCR_ANRESTART);
+	}
+
+	if (wait_for_link) {
+		tp->link_config.active_speed = SPEED_INVALID;
+		tp->link_config.active_duplex = DUPLEX_INVALID;
+		for (i = 0; i < 300000; i++) {
+			u32 tmp;
+
+			udelay(10);
+			tg3_readphy(tp, MII_BMSR, &tmp);
+			tg3_readphy(tp, MII_BMSR, &tmp);
+			if (!(tmp & BMSR_LSTATUS))
+				continue;
+
+			tg3_readphy(tp, MII_TG3_AUX_STAT, &tmp);
+			tg3_aux_stat_to_speed_duplex(tp, tmp,
+						     &tp->link_config.active_speed,
+						     &tp->link_config.active_duplex);
+		}
+		if (tp->link_config.active_speed == SPEED_INVALID)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int tg3_init_5401phy_dsp(struct tg3 *tp)
+{
+	int err;
+
+	/* Turn off tap power management. */
+	err  = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c20);
+
+	err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0012);
+	err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1804);
+
+	err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0013);
+	err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1204);
+
+	err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8006);
+	err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0132);
+
+	err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8006);
+	err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0232);
+
+	err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
+	err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0a20);
+
+	udelay(40);
+
+	return err;
+}
+
+static int tg3_setup_copper_phy(struct tg3 *tp)
+{
+	int current_link_up;
+	u32 bmsr, dummy;
+	u16 current_speed;
+	u8 current_duplex;
+	int i, err;
+
+	tw32(MAC_STATUS,
+	     (MAC_STATUS_SYNC_CHANGED |
+	      MAC_STATUS_CFG_CHANGED));
+
+	tp->mi_mode = MAC_MI_MODE_BASE;
+	tw32(MAC_MI_MODE, tp->mi_mode);
+	udelay(40);
+
+	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+
+		if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE))
+			bmsr = 0;
+
+		if (!(bmsr & BMSR_LSTATUS)) {
+			err = tg3_init_5401phy_dsp(tp);
+			if (err)
+				return err;
+
+			tg3_readphy(tp, MII_BMSR, &bmsr);
+			for (i = 0; i < 1000; i++) {
+				udelay(10);
+				tg3_readphy(tp, MII_BMSR, &bmsr);
+				if (bmsr & BMSR_LSTATUS) {
+					udelay(40);
+					break;
+				}
+			}
+
+			if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 &&
+			    !(bmsr & BMSR_LSTATUS) &&
+			    tp->link_config.active_speed == SPEED_1000) {
+				err = tg3_phy_reset(tp, 1);
+				if (!err)
+					err = tg3_init_5401phy_dsp(tp);
+				if (err)
+					return err;
+			}
+		}
+	} else if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+		   tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
+		/* 5701 {A0,B0} CRC bug workaround */
+		tg3_writephy(tp, 0x15, 0x0a75);
+		tg3_writephy(tp, 0x1c, 0x8c68);
+		tg3_writephy(tp, 0x1c, 0x8d68);
+		tg3_writephy(tp, 0x1c, 0x8c68);
+	}
+
+	/* Clear pending interrupts... */
+	tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
+	tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
+
+	if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT)
+		tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
+	else
+		tg3_writephy(tp, MII_TG3_IMASK, ~0);
+
+	if (tp->led_mode == led_mode_three_link)
+		tg3_writephy(tp, MII_TG3_EXT_CTRL,
+			     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
+	else
+		tg3_writephy(tp, MII_TG3_EXT_CTRL, 0);
+
+	current_link_up = 0;
+	current_speed = SPEED_INVALID;
+	current_duplex = DUPLEX_INVALID;
+
+	tg3_readphy(tp, MII_BMSR, &bmsr);
+	tg3_readphy(tp, MII_BMSR, &bmsr);
+
+	if (bmsr & BMSR_LSTATUS) {
+		u32 aux_stat, bmcr;
+
+		tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
+		for (i = 0; i < 2000; i++) {
+			udelay(10);
+			tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
+			if (aux_stat)
+				break;
+		}
+
+		tg3_aux_stat_to_speed_duplex(tp, aux_stat,
+					     &current_speed,
+					     &current_duplex);
+		tg3_readphy(tp, MII_BMCR, &bmcr);
+		tg3_readphy(tp, MII_BMCR, &bmcr);
+		if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+			if (bmcr & BMCR_ANENABLE) {
+				u32 gig_ctrl;
+
+				current_link_up = 1;
+
+				/* Force autoneg restart if we are exiting
+				 * low power mode.
+				 */
+				tg3_readphy(tp, MII_TG3_CTRL, &gig_ctrl);
+				if (!(gig_ctrl & (MII_TG3_CTRL_ADV_1000_HALF |
+						  MII_TG3_CTRL_ADV_1000_FULL))) {
+					current_link_up = 0;
+				}
+			} else {
+				current_link_up = 0;
+			}
+		} else {
+			if (!(bmcr & BMCR_ANENABLE) &&
+			    tp->link_config.speed == current_speed &&
+			    tp->link_config.duplex == current_duplex) {
+				current_link_up = 1;
+			} else {
+				current_link_up = 0;
+			}
+		}
+
+		tp->link_config.active_speed = current_speed;
+		tp->link_config.active_duplex = current_duplex;
+	}
+
+	if (current_link_up == 1 &&
+	    (tp->link_config.active_duplex == DUPLEX_FULL) &&
+	    (tp->link_config.autoneg == AUTONEG_ENABLE)) {
+		u32 local_adv, remote_adv;
+
+		tg3_readphy(tp, MII_ADVERTISE, &local_adv);
+		local_adv &= (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
+
+		tg3_readphy(tp, MII_LPA, &remote_adv);
+		remote_adv &= (LPA_PAUSE_CAP | LPA_PAUSE_ASYM);
+
+		/* If we are not advertising full pause capability,
+		 * something is wrong.  Bring the link down and reconfigure.
+		 */
+		if (local_adv != ADVERTISE_PAUSE_CAP) {
+			current_link_up = 0;
+		} else {
+			tg3_setup_flow_control(tp, local_adv, remote_adv);
+		}
+	}
+
+	if (current_link_up == 0) {
+		u32 tmp;
+
+		tg3_phy_copper_begin(tp, 0);
+
+		tg3_readphy(tp, MII_BMSR, &tmp);
+		tg3_readphy(tp, MII_BMSR, &tmp);
+		if (tmp & BMSR_LSTATUS)
+			current_link_up = 1;
+	}
+
+	tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK;
+	if (current_link_up == 1) {
+		if (tp->link_config.active_speed == SPEED_100 ||
+		    tp->link_config.active_speed == SPEED_10)
+			tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
+		else
+			tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	} else
+		tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+
+	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
+	if (tp->link_config.active_duplex == DUPLEX_HALF)
+		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
+
+	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
+		if (current_link_up == 1)
+			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+		tw32(MAC_LED_CTRL, LED_CTRL_PHY_MODE_1);
+	} else {
+		if ((tp->led_mode == led_mode_link10) ||
+		    (current_link_up == 1 &&
+		     tp->link_config.active_speed == SPEED_10))
+			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+	}
+
+	/* ??? Without this setting Netgear GA302T PHY does not
+	 * ??? send/receive packets...
+	 */
+	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411 &&
+	    tp->pci_chip_rev_id == CHIPREV_ID_5700_ALTIMA) {
+		tp->mi_mode |= MAC_MI_MODE_AUTO_POLL;
+		tw32(MAC_MI_MODE, tp->mi_mode);
+		udelay(40);
+	}
+
+	tw32(MAC_MODE, tp->mac_mode);
+
+	if (tp->tg3_flags &
+	    (TG3_FLAG_USE_LINKCHG_REG |
+	     TG3_FLAG_POLL_SERDES)) {
+		/* Polled via timer. */
+		tw32(MAC_EVENT, 0);
+	} else {
+		tw32(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+	}
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&
+	    current_link_up == 1 &&
+	    tp->link_config.active_speed == SPEED_1000 &&
+	    ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ||
+	     (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED))) {
+		udelay(120);
+		tw32(MAC_STATUS,
+		     (MAC_STATUS_SYNC_CHANGED |
+		      MAC_STATUS_CFG_CHANGED));
+		tg3_write_mem(tp,
+			      NIC_SRAM_FIRMWARE_MBOX,
+			      NIC_SRAM_FIRMWARE_MBOX_MAGIC2);
+	}
+
+	if (current_link_up != netif_carrier_ok(tp->dev)) {
+		if (current_link_up)
+			netif_carrier_on(tp->dev);
+		else
+			netif_carrier_off(tp->dev);
+		tg3_link_report(tp);
+	}
+
+	return 0;
+}
+
+struct tg3_fiber_aneginfo {
+	int state;
+#define ANEG_STATE_UNKNOWN		0
+#define ANEG_STATE_AN_ENABLE		1
+#define ANEG_STATE_RESTART_INIT		2
+#define ANEG_STATE_RESTART		3
+#define ANEG_STATE_DISABLE_LINK_OK	4
+#define ANEG_STATE_ABILITY_DETECT_INIT	5
+#define ANEG_STATE_ABILITY_DETECT	6
+#define ANEG_STATE_ACK_DETECT_INIT	7
+#define ANEG_STATE_ACK_DETECT		8
+#define ANEG_STATE_COMPLETE_ACK_INIT	9
+#define ANEG_STATE_COMPLETE_ACK		10
+#define ANEG_STATE_IDLE_DETECT_INIT	11
+#define ANEG_STATE_IDLE_DETECT		12
+#define ANEG_STATE_LINK_OK		13
+#define ANEG_STATE_NEXT_PAGE_WAIT_INIT	14
+#define ANEG_STATE_NEXT_PAGE_WAIT	15
+
+	u32 flags;
+#define MR_AN_ENABLE		0x00000001
+#define MR_RESTART_AN		0x00000002
+#define MR_AN_COMPLETE		0x00000004
+#define MR_PAGE_RX		0x00000008
+#define MR_NP_LOADED		0x00000010
+#define MR_TOGGLE_TX		0x00000020
+#define MR_LP_ADV_FULL_DUPLEX	0x00000040
+#define MR_LP_ADV_HALF_DUPLEX	0x00000080
+#define MR_LP_ADV_SYM_PAUSE	0x00000100
+#define MR_LP_ADV_ASYM_PAUSE	0x00000200
+#define MR_LP_ADV_REMOTE_FAULT1	0x00000400
+#define MR_LP_ADV_REMOTE_FAULT2	0x00000800
+#define MR_LP_ADV_NEXT_PAGE	0x00001000
+#define MR_TOGGLE_RX		0x00002000
+#define MR_NP_RX		0x00004000
+
+#define MR_LINK_OK		0x80000000
+
+	unsigned long link_time, cur_time;
+
+	u32 ability_match_cfg;
+	int ability_match_count;
+
+	char ability_match, idle_match, ack_match;
+
+	u32 txconfig, rxconfig;
+#define ANEG_CFG_NP		0x00000080
+#define ANEG_CFG_ACK		0x00000040
+#define ANEG_CFG_RF2		0x00000020
+#define ANEG_CFG_RF1		0x00000010
+#define ANEG_CFG_PS2		0x00000001
+#define ANEG_CFG_PS1		0x00008000
+#define ANEG_CFG_HD		0x00004000
+#define ANEG_CFG_FD		0x00002000
+#define ANEG_CFG_INVAL		0x00001f06
+
+};
+#define ANEG_OK		0
+#define ANEG_DONE	1
+#define ANEG_TIMER_ENAB	2
+#define ANEG_FAILED	-1
+
+#define ANEG_STATE_SETTLE_TIME	10000
+
+static int tg3_fiber_aneg_smachine(struct tg3 *tp,
+				   struct tg3_fiber_aneginfo *ap)
+{
+	unsigned long delta;
+	u32 rx_cfg_reg;
+	int ret;
+
+	if (ap->state == ANEG_STATE_UNKNOWN) {
+		ap->rxconfig = 0;
+		ap->link_time = 0;
+		ap->cur_time = 0;
+		ap->ability_match_cfg = 0;
+		ap->ability_match_count = 0;
+		ap->ability_match = 0;
+		ap->idle_match = 0;
+		ap->ack_match = 0;
+	}
+	ap->cur_time++;
+
+	if (tr32(MAC_STATUS) & MAC_STATUS_RCVD_CFG) {
+		rx_cfg_reg = tr32(MAC_RX_AUTO_NEG);
+
+		if (rx_cfg_reg != ap->ability_match_cfg) {
+			ap->ability_match_cfg = rx_cfg_reg;
+			ap->ability_match = 0;
+			ap->ability_match_count = 0;
+		} else {
+			if (++ap->ability_match_count > 1) {
+				ap->ability_match = 1;
+				ap->ability_match_cfg = rx_cfg_reg;
+			}
+		}
+		if (rx_cfg_reg & ANEG_CFG_ACK)
+			ap->ack_match = 1;
+		else
+			ap->ack_match = 0;
+
+		ap->idle_match = 0;
+	} else {
+		ap->idle_match = 1;
+		ap->ability_match_cfg = 0;
+		ap->ability_match_count = 0;
+		ap->ability_match = 0;
+		ap->ack_match = 0;
+
+		rx_cfg_reg = 0;
+	}
+
+	ap->rxconfig = rx_cfg_reg;
+	ret = ANEG_OK;
+
+	switch(ap->state) {
+	case ANEG_STATE_UNKNOWN:
+		if (ap->flags & (MR_AN_ENABLE | MR_RESTART_AN))
+			ap->state = ANEG_STATE_AN_ENABLE;
+
+		/* fallthru */
+	case ANEG_STATE_AN_ENABLE:
+		ap->flags &= ~(MR_AN_COMPLETE | MR_PAGE_RX);
+		if (ap->flags & MR_AN_ENABLE) {
+			ap->link_time = 0;
+			ap->cur_time = 0;
+			ap->ability_match_cfg = 0;
+			ap->ability_match_count = 0;
+			ap->ability_match = 0;
+			ap->idle_match = 0;
+			ap->ack_match = 0;
+
+			ap->state = ANEG_STATE_RESTART_INIT;
+		} else {
+			ap->state = ANEG_STATE_DISABLE_LINK_OK;
+		}
+		break;
+
+	case ANEG_STATE_RESTART_INIT:
+		ap->link_time = ap->cur_time;
+		ap->flags &= ~(MR_NP_LOADED);
+		ap->txconfig = 0;
+		tw32(MAC_TX_AUTO_NEG, 0);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
+		tw32(MAC_MODE, tp->mac_mode);
+		ret = ANEG_TIMER_ENAB;
+		ap->state = ANEG_STATE_RESTART;
+
+		/* fallthru */
+	case ANEG_STATE_RESTART:
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME) {
+			ap->state = ANEG_STATE_ABILITY_DETECT_INIT;
+		} else {
+			ret = ANEG_TIMER_ENAB;
+		}
+		break;
+
+	case ANEG_STATE_DISABLE_LINK_OK:
+		ret = ANEG_DONE;
+		break;
+
+	case ANEG_STATE_ABILITY_DETECT_INIT:
+		ap->flags &= ~(MR_TOGGLE_TX);
+		ap->txconfig = (ANEG_CFG_FD | ANEG_CFG_PS1);
+		tw32(MAC_TX_AUTO_NEG, ap->txconfig);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
+		tw32(MAC_MODE, tp->mac_mode);
+
+		ap->state = ANEG_STATE_ABILITY_DETECT;
+		break;
+
+	case ANEG_STATE_ABILITY_DETECT:
+		if (ap->ability_match != 0 && ap->rxconfig != 0) {
+			ap->state = ANEG_STATE_ACK_DETECT_INIT;
+		}
+		break;
+
+	case ANEG_STATE_ACK_DETECT_INIT:
+		ap->txconfig |= ANEG_CFG_ACK;
+		tw32(MAC_TX_AUTO_NEG, ap->txconfig);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
+		tw32(MAC_MODE, tp->mac_mode);
+
+		ap->state = ANEG_STATE_ACK_DETECT;
+
+		/* fallthru */
+	case ANEG_STATE_ACK_DETECT:
+		if (ap->ack_match != 0) {
+			if ((ap->rxconfig & ~ANEG_CFG_ACK) ==
+			    (ap->ability_match_cfg & ~ANEG_CFG_ACK)) {
+				ap->state = ANEG_STATE_COMPLETE_ACK_INIT;
+			} else {
+				ap->state = ANEG_STATE_AN_ENABLE;
+			}
+		} else if (ap->ability_match != 0 &&
+			   ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
+		}
+		break;
+
+	case ANEG_STATE_COMPLETE_ACK_INIT:
+		if (ap->rxconfig & ANEG_CFG_INVAL) {
+			ret = ANEG_FAILED;
+			break;
+		}
+		ap->flags &= ~(MR_LP_ADV_FULL_DUPLEX |
+			       MR_LP_ADV_HALF_DUPLEX |
+			       MR_LP_ADV_SYM_PAUSE |
+			       MR_LP_ADV_ASYM_PAUSE |
+			       MR_LP_ADV_REMOTE_FAULT1 |
+			       MR_LP_ADV_REMOTE_FAULT2 |
+			       MR_LP_ADV_NEXT_PAGE |
+			       MR_TOGGLE_RX |
+			       MR_NP_RX);
+		if (ap->rxconfig & ANEG_CFG_FD)
+			ap->flags |= MR_LP_ADV_FULL_DUPLEX;
+		if (ap->rxconfig & ANEG_CFG_HD)
+			ap->flags |= MR_LP_ADV_HALF_DUPLEX;
+		if (ap->rxconfig & ANEG_CFG_PS1)
+			ap->flags |= MR_LP_ADV_SYM_PAUSE;
+		if (ap->rxconfig & ANEG_CFG_PS2)
+			ap->flags |= MR_LP_ADV_ASYM_PAUSE;
+		if (ap->rxconfig & ANEG_CFG_RF1)
+			ap->flags |= MR_LP_ADV_REMOTE_FAULT1;
+		if (ap->rxconfig & ANEG_CFG_RF2)
+			ap->flags |= MR_LP_ADV_REMOTE_FAULT2;
+		if (ap->rxconfig & ANEG_CFG_NP)
+			ap->flags |= MR_LP_ADV_NEXT_PAGE;
+
+		ap->link_time = ap->cur_time;
+
+		ap->flags ^= (MR_TOGGLE_TX);
+		if (ap->rxconfig & 0x0008)
+			ap->flags |= MR_TOGGLE_RX;
+		if (ap->rxconfig & ANEG_CFG_NP)
+			ap->flags |= MR_NP_RX;
+		ap->flags |= MR_PAGE_RX;
+
+		ap->state = ANEG_STATE_COMPLETE_ACK;
+		ret = ANEG_TIMER_ENAB;
+		break;
+
+	case ANEG_STATE_COMPLETE_ACK:
+		if (ap->ability_match != 0 &&
+		    ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
+			break;
+		}
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME) {
+			if (!(ap->flags & (MR_LP_ADV_NEXT_PAGE))) {
+				ap->state = ANEG_STATE_IDLE_DETECT_INIT;
+			} else {
+				if ((ap->txconfig & ANEG_CFG_NP) == 0 &&
+				    !(ap->flags & MR_NP_RX)) {
+					ap->state = ANEG_STATE_IDLE_DETECT_INIT;
+				} else {
+					ret = ANEG_FAILED;
+				}
+			}
+		}
+		break;
+
+	case ANEG_STATE_IDLE_DETECT_INIT:
+		ap->link_time = ap->cur_time;
+		tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
+		tw32(MAC_MODE, tp->mac_mode);
+
+		ap->state = ANEG_STATE_IDLE_DETECT;
+		ret = ANEG_TIMER_ENAB;
+		break;
+
+	case ANEG_STATE_IDLE_DETECT:
+		if (ap->ability_match != 0 &&
+		    ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
+			break;
+		}
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME) {
+			/* XXX another gem from the Broadcom driver :( */
+			ap->state = ANEG_STATE_LINK_OK;
+		}
+		break;
+
+	case ANEG_STATE_LINK_OK:
+		ap->flags |= (MR_AN_COMPLETE | MR_LINK_OK);
+		ret = ANEG_DONE;
+		break;
+
+	case ANEG_STATE_NEXT_PAGE_WAIT_INIT:
+		/* ??? unimplemented */
+		break;
+
+	case ANEG_STATE_NEXT_PAGE_WAIT:
+		/* ??? unimplemented */
+		break;
+
+	default:
+		ret = ANEG_FAILED;
+		break;
+	};
+
+	return ret;
+}
+
+static int tg3_setup_fiber_phy(struct tg3 *tp)
+{
+	u32 orig_pause_cfg;
+	u16 orig_active_speed;
+	u8 orig_active_duplex;
+	int current_link_up;
+	int i;
+
+	orig_pause_cfg =
+		(tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
+				  TG3_FLAG_TX_PAUSE));
+	orig_active_speed = tp->link_config.active_speed;
+	orig_active_duplex = tp->link_config.active_duplex;
+
+	tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
+	tp->mac_mode |= MAC_MODE_PORT_MODE_TBI;
+	tw32(MAC_MODE, tp->mac_mode);
+	udelay(40);
+
+	/* Reset when initting first time or we have a link. */
+	if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) ||
+	    (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) {
+		/* Set PLL lock range. */
+		tg3_writephy(tp, 0x16, 0x8007);
+
+		/* SW reset */
+		tg3_writephy(tp, MII_BMCR, BMCR_RESET);
+
+		/* Wait for reset to complete. */
+		/* XXX schedule_timeout() ... */
+		for (i = 0; i < 500; i++)
+			udelay(10);
+
+		/* Config mode; select PMA/Ch 1 regs. */
+		tg3_writephy(tp, 0x10, 0x8411);
+
+		/* Enable auto-lock and comdet, select txclk for tx. */
+		tg3_writephy(tp, 0x11, 0x0a10);
+
+		tg3_writephy(tp, 0x18, 0x00a0);
+		tg3_writephy(tp, 0x16, 0x41ff);
+
+		/* Assert and deassert POR. */
+		tg3_writephy(tp, 0x13, 0x0400);
+		udelay(40);
+		tg3_writephy(tp, 0x13, 0x0000);
+
+		tg3_writephy(tp, 0x11, 0x0a50);
+		udelay(40);
+		tg3_writephy(tp, 0x11, 0x0a10);
+
+		/* Wait for signal to stabilize */
+		/* XXX schedule_timeout() ... */
+		for (i = 0; i < 15000; i++)
+			udelay(10);
+
+		/* Deselect the channel register so we can read the PHYID
+		 * later.
+		 */
+		tg3_writephy(tp, 0x10, 0x8011);
+	}
+
+	/* Enable link change interrupt unless serdes polling.  */
+	if (!(tp->tg3_flags & TG3_FLAG_POLL_SERDES))
+		tw32(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+	else
+		tw32(MAC_EVENT, 0);
+
+	current_link_up = 0;
+	if (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) {
+		if (tp->link_config.autoneg == AUTONEG_ENABLE &&
+		    !(tp->tg3_flags & TG3_FLAG_GOT_SERDES_FLOWCTL)) {
+			struct tg3_fiber_aneginfo aninfo;
+			int status = ANEG_FAILED;
+			unsigned int tick;
+			u32 tmp;
+
+			memset(&aninfo, 0, sizeof(aninfo));
+			aninfo.flags |= (MR_AN_ENABLE);
+
+			tw32(MAC_TX_AUTO_NEG, 0);
+
+			tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
+			tw32(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
+			udelay(20);
+
+			tw32(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
+
+			aninfo.state = ANEG_STATE_UNKNOWN;
+			aninfo.cur_time = 0;
+			tick = 0;
+			while (++tick < 195000) {
+				status = tg3_fiber_aneg_smachine(tp, &aninfo);
+				if (status == ANEG_DONE ||
+				    status == ANEG_FAILED)
+					break;
+
+				udelay(1);
+			}
+
+			tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
+			tw32(MAC_MODE, tp->mac_mode);
+
+			if (status == ANEG_DONE &&
+			    (aninfo.flags &
+			     (MR_AN_COMPLETE | MR_LINK_OK |
+			      MR_LP_ADV_FULL_DUPLEX))) {
+				u32 local_adv, remote_adv;
+
+				local_adv = ADVERTISE_PAUSE_CAP;
+				remote_adv = 0;
+				if (aninfo.flags & MR_LP_ADV_SYM_PAUSE)
+					remote_adv |= LPA_PAUSE_CAP;
+				if (aninfo.flags & MR_LP_ADV_ASYM_PAUSE)
+					remote_adv |= LPA_PAUSE_ASYM;
+
+				tg3_setup_flow_control(tp, local_adv, remote_adv);
+
+				tp->tg3_flags |=
+					TG3_FLAG_GOT_SERDES_FLOWCTL;
+				current_link_up = 1;
+			}
+			for (i = 0; i < 60; i++) {
+				udelay(20);
+				tw32(MAC_STATUS,
+				     (MAC_STATUS_SYNC_CHANGED |
+				      MAC_STATUS_CFG_CHANGED));
+
+				udelay(20);
+				if ((tr32(MAC_STATUS) &
+				     (MAC_STATUS_SYNC_CHANGED |
+				      MAC_STATUS_CFG_CHANGED)) == 0)
+					break;
+			}
+			if (current_link_up == 0 &&
+			    (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) {
+				current_link_up = 1;
+			}
+		} else {
+			/* Forcing 1000FD link up. */
+			current_link_up = 1;
+		}
+	}
+
+	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
+	tw32(MAC_MODE, tp->mac_mode);
+
+	tp->hw_status->status =
+		(SD_STATUS_UPDATED |
+		 (tp->hw_status->status & ~SD_STATUS_LINK_CHG));
+
+	for (i = 0; i < 100; i++) {
+		udelay(20);
+		tw32(MAC_STATUS,
+		     (MAC_STATUS_SYNC_CHANGED |
+		      MAC_STATUS_CFG_CHANGED));
+
+		udelay(20);
+		if ((tr32(MAC_STATUS) &
+		     (MAC_STATUS_SYNC_CHANGED |
+		      MAC_STATUS_CFG_CHANGED)) == 0)
+			break;
+	}
+
+	if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0)
+		current_link_up = 0;
+
+	if (current_link_up == 1) {
+		tp->link_config.active_speed = SPEED_1000;
+		tp->link_config.active_duplex = DUPLEX_FULL;
+	} else {
+		tp->link_config.active_speed = SPEED_INVALID;
+		tp->link_config.active_duplex = DUPLEX_INVALID;
+	}
+
+	if (current_link_up != netif_carrier_ok(tp->dev)) {
+		if (current_link_up)
+			netif_carrier_on(tp->dev);
+		else
+			netif_carrier_off(tp->dev);
+		tg3_link_report(tp);
+	} else {
+		u32 now_pause_cfg =
+			tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
+					 TG3_FLAG_TX_PAUSE);
+		if (orig_pause_cfg != now_pause_cfg ||
+		    orig_active_speed != tp->link_config.active_speed ||
+		    orig_active_duplex != tp->link_config.active_duplex)
+			tg3_link_report(tp);
+	}
+
+	if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0) {
+		tw32(MAC_MODE, tp->mac_mode | MAC_MODE_LINK_POLARITY);
+		if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) {
+			udelay(1);
+			tw32(MAC_MODE, tp->mac_mode);
+		}
+	}
+
+	return 0;
+}
+
+static int tg3_setup_phy(struct tg3 *tp)
+{
+	int err;
+
+	if (tp->phy_id == PHY_ID_SERDES) {
+		err = tg3_setup_fiber_phy(tp);
+	} else {
+		err = tg3_setup_copper_phy(tp);
+	}
+
+	if (tp->link_config.active_speed == SPEED_1000 &&
+	    tp->link_config.active_duplex == DUPLEX_HALF)
+		tw32(MAC_TX_LENGTHS,
+		     ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+		      (6 << TX_LENGTHS_IPG_SHIFT) |
+		      (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
+	else
+		tw32(MAC_TX_LENGTHS,
+		     ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+		      (6 << TX_LENGTHS_IPG_SHIFT) |
+		      (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
+
+	return err;
+}
+
+/* Tigon3 never reports partial packet sends.  So we do not
+ * need special logic to handle SKBs that have not had all
+ * of their frags sent yet, like SunGEM does.
+ */
+static void tg3_tx(struct tg3 *tp)
+{
+	u32 hw_idx = tp->hw_status->idx[0].tx_consumer;
+	u32 sw_idx = tp->tx_cons;
+
+	while (sw_idx != hw_idx) {
+		struct ring_info *ri = &tp->tx_buffers[sw_idx];
+		struct sk_buff *skb = ri->skb;
+		int i;
+
+		if (unlikely(skb == NULL))
+			BUG();
+
+		pci_unmap_single(tp->pdev,
+				 pci_unmap_addr(ri, mapping),
+				 (skb->len - skb->data_len),
+				 PCI_DMA_TODEVICE);
+
+		ri->skb = NULL;
+
+		sw_idx = NEXT_TX(sw_idx);
+
+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			if (unlikely(sw_idx == hw_idx))
+				BUG();
+
+			ri = &tp->tx_buffers[sw_idx];
+			if (unlikely(ri->skb != NULL))
+				BUG();
+
+			pci_unmap_page(tp->pdev,
+				       pci_unmap_addr(ri, mapping),
+				       skb_shinfo(skb)->frags[i].size,
+				       PCI_DMA_TODEVICE);
+
+			sw_idx = NEXT_TX(sw_idx);
+		}
+
+		dev_kfree_skb_irq(skb);
+	}
+
+	tp->tx_cons = sw_idx;
+
+	if (netif_queue_stopped(tp->dev) &&
+	    (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH))
+		netif_wake_queue(tp->dev);
+}
+
+/* Returns size of skb allocated or < 0 on error.
+ *
+ * We only need to fill in the address because the other members
+ * of the RX descriptor are invariant, see tg3_init_rings.
+ *
+ * Note the purposeful assymetry of cpu vs. chip accesses.  For
+ * posting buffers we only dirty the first cache line of the RX
+ * descriptor (containing the address).  Whereas for the RX status
+ * buffers the cpu only reads the last cacheline of the RX descriptor
+ * (to fetch the error flags, vlan tag, checksum, and opaque cookie).
+ */
+static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
+			    int src_idx, u32 dest_idx_unmasked)
+{
+	struct tg3_rx_buffer_desc *desc;
+	struct ring_info *map, *src_map;
+	struct sk_buff *skb;
+	dma_addr_t mapping;
+	int skb_size, dest_idx;
+
+	src_map = NULL;
+	switch (opaque_key) {
+	case RXD_OPAQUE_RING_STD:
+		dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
+		desc = &tp->rx_std[dest_idx];
+		map = &tp->rx_std_buffers[dest_idx];
+		if (src_idx >= 0)
+			src_map = &tp->rx_std_buffers[src_idx];
+		skb_size = RX_PKT_BUF_SZ;
+		break;
+
+	case RXD_OPAQUE_RING_JUMBO:
+		dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
+		desc = &tp->rx_jumbo[dest_idx];
+		map = &tp->rx_jumbo_buffers[dest_idx];
+		if (src_idx >= 0)
+			src_map = &tp->rx_jumbo_buffers[src_idx];
+		skb_size = RX_JUMBO_PKT_BUF_SZ;
+		break;
+#if TG3_MINI_RING_WORKS
+	case RXD_OPAQUE_RING_MINI:
+		dest_idx = dest_idx_unmasked % TG3_RX_MINI_RING_SIZE;
+		desc = &tp->rx_mini[dest_idx];
+		map = &tp->rx_mini_buffers[dest_idx];
+		if (src_idx >= 0)
+			src_map = &tp->rx_mini_buffers[src_idx];
+		skb_size = RX_MINI_PKT_BUF_SZ;
+		break;
+#endif
+	default:
+		return -EINVAL;
+	};
+
+	/* Do not overwrite any of the map or rp information
+	 * until we are sure we can commit to a new buffer.
+	 *
+	 * Callers depend upon this behavior and assume that
+	 * we leave everything unchanged if we fail.
+	 */
+	skb = dev_alloc_skb(skb_size);
+	if (skb == NULL)
+		return -ENOMEM;
+
+	skb->dev = tp->dev;
+	skb_reserve(skb, tp->rx_offset);
+
+	mapping = pci_map_single(tp->pdev, skb->data,
+				 skb_size - tp->rx_offset,
+				 PCI_DMA_FROMDEVICE);
+
+	map->skb = skb;
+	pci_unmap_addr_set(map, mapping, mapping);
+
+	if (src_map != NULL)
+		src_map->skb = NULL;
+
+	desc->addr_hi = ((u64)mapping >> 32);
+	desc->addr_lo = ((u64)mapping & 0xffffffff);
+
+	return skb_size;
+}
+
+/* We only need to move over in the address because the other
+ * members of the RX descriptor are invariant.  See notes above
+ * tg3_alloc_rx_skb for full details.
+ */
+static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
+			   int src_idx, u32 dest_idx_unmasked)
+{
+	struct tg3_rx_buffer_desc *src_desc, *dest_desc;
+	struct ring_info *src_map, *dest_map;
+	int dest_idx;
+
+	switch (opaque_key) {
+	case RXD_OPAQUE_RING_STD:
+		dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
+		dest_desc = &tp->rx_std[dest_idx];
+		dest_map = &tp->rx_std_buffers[dest_idx];
+		src_desc = &tp->rx_std[src_idx];
+		src_map = &tp->rx_std_buffers[src_idx];
+		break;
+
+	case RXD_OPAQUE_RING_JUMBO:
+		dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
+		dest_desc = &tp->rx_jumbo[dest_idx];
+		dest_map = &tp->rx_jumbo_buffers[dest_idx];
+		src_desc = &tp->rx_jumbo[src_idx];
+		src_map = &tp->rx_jumbo_buffers[src_idx];
+		break;
+#if TG3_MINI_RING_WORKS
+	case RXD_OPAQUE_RING_MINI:
+		dest_idx = dest_idx_unmasked % TG3_RX_MINI_RING_SIZE;
+		dest_desc = &tp->rx_mini[dest_idx];
+		dest_map = &tp->rx_mini_buffers[dest_idx];
+		src_desc = &tp->rx_mini[src_idx];
+		src_map = &tp->rx_mini_buffers[src_idx];
+		break;
+#endif
+	default:
+		return;
+	};
+
+	dest_map->skb = src_map->skb;
+	pci_unmap_addr_set(dest_map, mapping,
+			   pci_unmap_addr(src_map, mapping));
+	dest_desc->addr_hi = src_desc->addr_hi;
+	dest_desc->addr_lo = src_desc->addr_lo;
+
+	src_map->skb = NULL;
+}
+
+#if TG3_VLAN_TAG_USED
+static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag)
+{
+	return vlan_hwaccel_rx(skb, tp->vlgrp, vlan_tag);
+}
+#endif
+
+/* The RX ring scheme is composed of multiple rings which post fresh
+ * buffers to the chip, and one special ring the chip uses to report
+ * status back to the host.
+ *
+ * The special ring reports the status of received packets to the
+ * host.  The chip does not write into the original descriptor the
+ * RX buffer was obtained from.  The chip simply takes the original
+ * descriptor as provided by the host, updates the status and length
+ * field, then writes this into the next status ring entry.
+ *
+ * Each ring the host uses to post buffers to the chip is described
+ * by a TG3_BDINFO entry in the chips SRAM area.  When a packet arrives,
+ * it is first placed into the on-chip ram.  When the packet's length
+ * is known, it walks down the TG3_BDINFO entries to select the ring.
+ * Each TG3_BDINFO specifies a MAXLEN field and the first TG3_BDINFO
+ * which is within the range of the new packet's length is chosen.
+ *
+ * The "seperate ring for rx status" scheme may sound queer, but it makes
+ * sense from a cache coherency perspective.  If only the host writes
+ * to the buffer post rings, and only the chip writes to the rx status
+ * rings, then cache lines never move beyond shared-modified state.
+ * If both the host and chip were to write into the same ring, cache line
+ * eviction could occur since both entities want it in an exclusive state.
+ */
+static void tg3_rx(struct tg3 *tp)
+{
+	u32 work_mask;
+	u32 rx_rcb_ptr = tp->rx_rcb_ptr;
+	u16 hw_idx, sw_idx;
+
+	hw_idx = tp->hw_status->idx[0].rx_producer;
+	sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE;
+	work_mask = 0;
+	while (sw_idx != hw_idx) {
+		struct tg3_rx_buffer_desc *desc = &tp->rx_rcb[sw_idx];
+		unsigned int len;
+		struct sk_buff *skb;
+		dma_addr_t dma_addr;
+		u32 opaque_key, desc_idx, *post_ptr;
+
+		desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
+		opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
+		if (opaque_key == RXD_OPAQUE_RING_STD) {
+			dma_addr = pci_unmap_addr(&tp->rx_std_buffers[desc_idx],
+						  mapping);
+			skb = tp->rx_std_buffers[desc_idx].skb;
+			post_ptr = &tp->rx_std_ptr;
+		} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
+			dma_addr = pci_unmap_addr(&tp->rx_jumbo_buffers[desc_idx],
+						  mapping);
+			skb = tp->rx_jumbo_buffers[desc_idx].skb;
+			post_ptr = &tp->rx_jumbo_ptr;
+		}
+#if TG3_MINI_RING_WORKS
+		else if (opaque_key == RXD_OPAQUE_RING_MINI) {
+			dma_addr = pci_unmap_addr(&tp->rx_mini_buffers[desc_idx],
+						  mapping);
+			skb = tp->rx_mini_buffers[desc_idx].skb;
+			post_ptr = &tp->rx_mini_ptr;
+		}
+#endif
+		else {
+			goto next_pkt_nopost;
+		}
+
+		work_mask |= opaque_key;
+
+		if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
+		    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) {
+		drop_it:
+			tg3_recycle_rx(tp, opaque_key,
+				       desc_idx, *post_ptr);
+		drop_it_no_recycle:
+			/* Other statistics kept track of by card. */
+			tp->net_stats.rx_dropped++;
+			goto next_pkt;
+		}
+
+		len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */
+
+		/* Kill the copy case if we ever get the mini ring working. */
+		if (len > RX_COPY_THRESHOLD) {
+			int skb_size;
+
+			skb_size = tg3_alloc_rx_skb(tp, opaque_key,
+						    desc_idx, *post_ptr);
+			if (skb_size < 0)
+				goto drop_it;
+
+			pci_unmap_single(tp->pdev, dma_addr,
+					 skb_size - tp->rx_offset,
+					 PCI_DMA_FROMDEVICE);
+
+			skb_put(skb, len);
+		} else {
+			struct sk_buff *copy_skb;
+
+			tg3_recycle_rx(tp, opaque_key,
+				       desc_idx, *post_ptr);
+
+			copy_skb = dev_alloc_skb(len + 2);
+			if (copy_skb == NULL)
+				goto drop_it_no_recycle;
+
+			copy_skb->dev = tp->dev;
+			skb_reserve(copy_skb, 2);
+			skb_put(copy_skb, len);
+			pci_dma_sync_single(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
+			memcpy(copy_skb->data, skb->data, len);
+
+			/* We'll reuse the original ring buffer. */
+			skb = copy_skb;
+		}
+
+		if ((tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) &&
+		    (desc->type_flags & RXD_FLAG_TCPUDP_CSUM)) {
+			skb->csum = htons((desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
+					  >> RXD_TCPCSUM_SHIFT);
+			skb->ip_summed = CHECKSUM_HW;
+		} else {
+			skb->ip_summed = CHECKSUM_NONE;
+		}
+
+		skb->protocol = eth_type_trans(skb, tp->dev);
+#if TG3_VLAN_TAG_USED
+		if (tp->vlgrp != NULL &&
+		    desc->type_flags & RXD_FLAG_VLAN) {
+			tg3_vlan_rx(tp, skb,
+				    desc->err_vlan & RXD_VLAN_MASK);
+		} else
+#endif
+			netif_rx(skb);
+
+		tp->dev->last_rx = jiffies;
+
+next_pkt:
+		(*post_ptr)++;
+next_pkt_nopost:
+		rx_rcb_ptr++;
+		sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE;
+	}
+
+	/* ACK the status ring. */
+	tp->rx_rcb_ptr = rx_rcb_ptr;
+	tw32_mailbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW,
+		     (rx_rcb_ptr % TG3_RX_RCB_RING_SIZE));
+
+	/* Refill RX ring(s). */
+	if (work_mask & RXD_OPAQUE_RING_STD) {
+		sw_idx = tp->rx_std_ptr % TG3_RX_RING_SIZE;
+		tw32_mailbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
+			     sw_idx);
+	}
+	if (work_mask & RXD_OPAQUE_RING_JUMBO) {
+		sw_idx = tp->rx_jumbo_ptr % TG3_RX_JUMBO_RING_SIZE;
+		tw32_mailbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
+			     sw_idx);
+	}
+#if TG3_MINI_RING_WORKS
+	if (work_mask & RXD_OPAQUE_RING_MINI) {
+		sw_idx = tp->rx_mini_ptr % TG3_RX_MINI_RING_SIZE;
+		tw32_mailbox(MAILBOX_RCV_MINI_PROD_IDX + TG3_64BIT_REG_LOW,
+			     sw_idx);
+	}
+#endif
+}
+
+#define PKT_RATE_LOW		22000
+#define PKT_RATE_HIGH		61000
+
+static void tg3_rate_sample(struct tg3 *tp, unsigned long ticks)
+{
+	u32 delta, rx_now, tx_now;
+	int new_vals, do_tx, do_rx;
+
+	rx_now = tp->hw_stats->rx_ucast_packets.low;
+	tx_now = tp->hw_stats->COS_out_packets[0].low;
+
+	delta  = (rx_now - tp->last_rx_count);
+	delta += (tx_now - tp->last_tx_count);
+	delta /= (ticks / tp->coalesce_config.rate_sample_jiffies);
+
+	tp->last_rx_count = rx_now;
+	tp->last_tx_count = tx_now;
+
+	new_vals = 0;
+	do_tx = (tp->tg3_flags & TG3_FLAG_ADAPTIVE_TX) != 0;
+	do_rx = (tp->tg3_flags & TG3_FLAG_ADAPTIVE_RX) != 0;
+	if (delta < tp->coalesce_config.pkt_rate_low) {
+		if (do_rx &&
+		    tp->coalesce_config.rx_max_coalesced_frames !=
+		    tp->coalesce_config.rx_max_coalesced_frames_low) {
+			tp->coalesce_config.rx_max_coalesced_frames =
+				LOW_RXMAX_FRAMES;
+			tp->coalesce_config.rx_coalesce_ticks =
+				LOW_RXCOL_TICKS;
+			new_vals = 1;
+		}
+		if (do_tx &&
+		    tp->coalesce_config.tx_max_coalesced_frames !=
+		    tp->coalesce_config.tx_max_coalesced_frames_low) {
+			tp->coalesce_config.tx_max_coalesced_frames =
+				tp->coalesce_config.tx_max_coalesced_frames_low;
+			tp->coalesce_config.tx_coalesce_ticks =
+				tp->coalesce_config.tx_coalesce_ticks_low;
+			new_vals = 1;
+		}
+	} else if (delta < tp->coalesce_config.pkt_rate_high) {
+		if (do_rx &&
+		    tp->coalesce_config.rx_max_coalesced_frames !=
+		    tp->coalesce_config.rx_max_coalesced_frames_def) {
+			tp->coalesce_config.rx_max_coalesced_frames =
+				tp->coalesce_config.rx_max_coalesced_frames_def;
+			tp->coalesce_config.rx_coalesce_ticks =
+				tp->coalesce_config.rx_coalesce_ticks_def;
+			new_vals = 1;
+		}
+		if (do_tx &&
+		    tp->coalesce_config.tx_max_coalesced_frames !=
+		    tp->coalesce_config.tx_max_coalesced_frames_def) {
+			tp->coalesce_config.tx_max_coalesced_frames =
+				tp->coalesce_config.tx_max_coalesced_frames_def;
+			tp->coalesce_config.tx_coalesce_ticks =
+				tp->coalesce_config.tx_coalesce_ticks_def;
+			new_vals = 1;
+		}
+	} else {
+		if (do_rx &&
+		    tp->coalesce_config.rx_max_coalesced_frames !=
+		    tp->coalesce_config.rx_max_coalesced_frames_high) {
+			tp->coalesce_config.rx_max_coalesced_frames =
+				tp->coalesce_config.rx_max_coalesced_frames_high;
+			tp->coalesce_config.rx_coalesce_ticks =
+				tp->coalesce_config.rx_coalesce_ticks_high;
+			new_vals = 1;
+		}
+		if (do_tx &&
+		    tp->coalesce_config.tx_max_coalesced_frames !=
+		    tp->coalesce_config.tx_max_coalesced_frames_high) {
+			tp->coalesce_config.tx_max_coalesced_frames =
+				tp->coalesce_config.tx_max_coalesced_frames_high;
+			tp->coalesce_config.tx_coalesce_ticks =
+				tp->coalesce_config.tx_coalesce_ticks_high;
+			new_vals = 1;
+		}
+	}
+
+	if (new_vals) {
+		if (do_rx) {
+			tw32(HOSTCC_RXCOL_TICKS,
+			     tp->coalesce_config.rx_coalesce_ticks);
+			tw32(HOSTCC_RXMAX_FRAMES,
+			     tp->coalesce_config.rx_max_coalesced_frames);
+		}
+		if (do_tx) {
+			tw32(HOSTCC_TXCOL_TICKS,
+			     tp->coalesce_config.tx_coalesce_ticks);
+			tw32(HOSTCC_TXMAX_FRAMES,
+			     tp->coalesce_config.tx_max_coalesced_frames);
+		}
+	}
+
+	tp->last_rate_sample = jiffies;
+}
+
+static void tg3_interrupt_main_work(struct tg3 *tp)
+{
+	struct tg3_hw_status *sblk = tp->hw_status;
+	int did_pkts;
+
+	if (!(tp->tg3_flags &
+	      (TG3_FLAG_USE_LINKCHG_REG |
+	       TG3_FLAG_POLL_SERDES))) {
+		if (sblk->status & SD_STATUS_LINK_CHG) {
+			sblk->status = SD_STATUS_UPDATED |
+				(sblk->status & ~SD_STATUS_LINK_CHG);
+			tg3_setup_phy(tp);
+		}
+	}
+
+	did_pkts = 0;
+	if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) {
+		tg3_rx(tp);
+		did_pkts = 1;
+	}
+
+	if (sblk->idx[0].tx_consumer != tp->tx_cons) {
+		tg3_tx(tp);
+		did_pkts = 1;
+	}
+
+	if (did_pkts &&
+	    (tp->tg3_flags & (TG3_FLAG_ADAPTIVE_RX | TG3_FLAG_ADAPTIVE_TX))) {
+		unsigned long ticks = jiffies - tp->last_rate_sample;
+
+		if (ticks >= tp->coalesce_config.rate_sample_jiffies)
+			tg3_rate_sample(tp, ticks);
+	}
+}
+
+static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = dev_id;
+	struct tg3 *tp = dev->priv;
+	struct tg3_hw_status *sblk = tp->hw_status;
+
+	spin_lock(&tp->lock);
+
+	while (sblk->status & SD_STATUS_UPDATED) {
+		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+			     0x00000001);
+		sblk->status &= ~SD_STATUS_UPDATED;
+
+		tg3_interrupt_main_work(tp);
+
+		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+			     0x00000000);
+		tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+	}
+
+	spin_unlock(&tp->lock);
+}
+
+static void tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = dev_id;
+	struct tg3 *tp = dev->priv;
+	struct tg3_hw_status *sblk = tp->hw_status;
+
+	spin_lock(&tp->lock);
+
+	if (sblk->status & SD_STATUS_UPDATED) {
+		u32 oldtag;
+
+		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+			     0x00000001);
+		oldtag = sblk->status_tag;
+
+		while (1) {
+			u32 newtag;
+
+			sblk->status &= ~SD_STATUS_UPDATED;
+			barrier();
+
+			tg3_interrupt_main_work(tp);
+
+			newtag = sblk->status_tag;
+			if (newtag == oldtag) {
+				tw32_mailbox(MAILBOX_INTERRUPT_0 +
+					     TG3_64BIT_REG_LOW,
+					     newtag << 24);
+				break;
+			}
+			oldtag = newtag;
+		}
+	}
+
+	spin_unlock(&tp->lock);
+}
+
+static void tg3_init_rings(struct tg3 *);
+static int tg3_init_hw(struct tg3 *);
+
+static void tg3_tx_timeout(struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+
+	printk(KERN_ERR "%s: transmit timed out, resetting\n",
+	       dev->name);
+
+	spin_lock_irq(&tp->lock);
+
+	tg3_halt(tp);
+	tg3_init_rings(tp);
+	tg3_init_hw(tp);
+
+	spin_unlock_irq(&tp->lock);
+
+	netif_wake_queue(dev);
+}
+
+#if !PCI_DMA_BUS_IS_PHYS
+static void tg3_set_txd_addr(struct tg3 *tp, int entry, dma_addr_t mapping)
+{
+	if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) {
+		struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry];
+
+		txd->addr_hi = ((u64) mapping >> 32);
+		txd->addr_lo = ((u64) mapping & 0xffffffff);
+	} else {
+		unsigned long txd;
+
+		txd = (tp->regs +
+		       NIC_SRAM_WIN_BASE +
+		       NIC_SRAM_TX_BUFFER_DESC);
+		txd += (entry * TXD_SIZE);
+
+		if (sizeof(dma_addr_t) != sizeof(u32))
+			writel(((u64) mapping >> 32),
+			       txd + TXD_ADDR + TG3_64BIT_REG_HIGH);
+
+		writel(((u64) mapping & 0xffffffff),
+		       txd + TXD_ADDR + TG3_64BIT_REG_LOW);
+	}
+}
+#endif
+
+static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, int);
+
+static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
+				       u32 guilty_entry, int guilty_len,
+				       u32 last_plus_one, u32 *start)
+{
+	dma_addr_t new_addr;
+	u32 entry = *start;
+	int i;
+
+#if !PCI_DMA_BUS_IS_PHYS
+	/* IOMMU, just map the guilty area again which is guarenteed to
+	 * use different addresses.
+	 */
+
+	i = 0;
+	while (entry != guilty_entry) {
+		entry = NEXT_TX(entry);
+		i++;
+	}
+	if (i == 0) {
+		new_addr = pci_map_single(tp->pdev, skb->data, guilty_len,
+					  PCI_DMA_TODEVICE);
+	} else {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
+
+		new_addr = pci_map_page(tp->pdev,
+					frag->page, frag->page_offset,
+					guilty_len, PCI_DMA_TODEVICE);
+	}
+	pci_unmap_single(tp->pdev, pci_unmap_addr(&tp->tx_buffers[guilty_entry],
+						  mapping),
+			 guilty_len, PCI_DMA_TODEVICE);
+	tg3_set_txd_addr(tp, guilty_entry, new_addr);
+	pci_unmap_addr_set(&tp->tx_buffers[guilty_entry], mapping,
+			   new_addr);
+	*start = last_plus_one;
+#else
+	/* Oh well, no IOMMU, have to allocate a whole new SKB. */
+	struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC);
+
+	if (!new_skb) {
+		dev_kfree_skb(skb);
+		return -1;
+	}
+
+	/* NOTE: Broadcom's driver botches this case up really bad.
+	 *       This is especially true if any of the frag pages
+	 *       are in highmem.  It will instantly oops in that case.
+	 */
+
+	/* New SKB is guarenteed to be linear. */
+	entry = *start;
+	new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
+				  PCI_DMA_TODEVICE);
+	tg3_set_txd(tp, entry, new_addr, new_skb->len,
+		    (skb->ip_summed == CHECKSUM_HW) ?
+		    TXD_FLAG_TCPUDP_CSUM : 0, 1);
+	*start = NEXT_TX(entry);
+
+	/* Now clean up the sw ring entries. */
+	i = 0;
+	while (entry != last_plus_one) {
+		int len;
+
+		if (i == 0)
+			len = skb->len - skb->data_len;
+		else
+			len = skb_shinfo(skb)->frags[i-1].size;
+		pci_unmap_single(tp->pdev,
+				 pci_unmap_addr(&tp->tx_buffers[entry], mapping),
+				 len, PCI_DMA_TODEVICE);
+		if (i == 0) {
+			tp->tx_buffers[entry].skb = new_skb;
+			pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, new_addr);
+		} else {
+			tp->tx_buffers[entry].skb = NULL;
+		}
+		entry = NEXT_TX(entry);
+	}
+
+	dev_kfree_skb(skb);
+#endif
+
+	return 0;
+}
+
+static void tg3_set_txd(struct tg3 *tp, int entry,
+			dma_addr_t mapping, int len, u32 flags,
+			int is_end)
+{
+#if TG3_VLAN_TAG_USED
+	u16 vlan_tag = 0;
+#endif
+
+	if (is_end)
+		flags |= TXD_FLAG_END;
+#if TG3_VLAN_TAG_USED
+	if (flags & TXD_FLAG_VLAN) {
+		vlan_tag = flags >> 16;
+		flags &= 0xffff;
+	}
+#endif
+	if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) {
+		struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry];
+
+		txd->addr_hi = ((u64) mapping >> 32);
+		txd->addr_lo = ((u64) mapping & 0xffffffff);
+		txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
+#if TG3_VLAN_TAG_USED
+		txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
+#endif
+	} else {
+		unsigned long txd;
+
+		txd = (tp->regs +
+		       NIC_SRAM_WIN_BASE +
+		       NIC_SRAM_TX_BUFFER_DESC);
+		txd += (entry * TXD_SIZE);
+
+		/* Save some PIOs */
+		if (sizeof(dma_addr_t) != sizeof(u32))
+			writel(((u64) mapping >> 32),
+			       txd + TXD_ADDR + TG3_64BIT_REG_HIGH);
+
+		writel(((u64) mapping & 0xffffffff),
+		       txd + TXD_ADDR + TG3_64BIT_REG_LOW);
+		writel(len << TXD_LEN_SHIFT | flags, txd + TXD_LEN_FLAGS);
+#if TG3_VLAN_TAG_USED
+		writel(vlan_tag << TXD_VLAN_TAG_SHIFT, txd + TXD_VLAN_TAG);
+#endif
+	}
+}
+
+static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
+{
+	u32 base = (u32) mapping & 0xffffffff;
+
+	return ((base > 0xffffdcc0) &&
+		((u64) mapping >> 32) == 0 &&
+		(base + len + 8 < base));
+}
+
+static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+	dma_addr_t mapping;
+	unsigned int i;
+	u32 len, entry, base_flags;
+	int would_hit_hwbug;
+
+	len = (skb->len - skb->data_len);
+
+	spin_lock_irq(&tp->lock);
+
+	/* This is a hard error, log it. */
+	if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
+		netif_stop_queue(dev);
+		spin_unlock_irq(&tp->lock);
+		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+		       dev->name);
+		return 1;
+	}
+
+	entry = tp->tx_prod;
+	base_flags = 0;
+	if (skb->ip_summed == CHECKSUM_HW)
+		base_flags |= TXD_FLAG_TCPUDP_CSUM;
+#if TG3_VLAN_TAG_USED
+	if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+		base_flags |= (TXD_FLAG_VLAN |
+			       (vlan_tx_tag_get(skb) << 16));
+#endif
+
+	/* Queue skb data, a.k.a. the main skb fragment. */
+	mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+
+	tp->tx_buffers[entry].skb = skb;
+	pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);
+
+	would_hit_hwbug = 0;
+
+	if (tg3_4g_overflow_test(mapping, len))
+		would_hit_hwbug = entry + 1;
+
+	tg3_set_txd(tp, entry, mapping, len, base_flags,
+		    (skb_shinfo(skb)->nr_frags == 0));
+
+	entry = NEXT_TX(entry);
+
+	/* Now loop through additional data fragments, and queue them. */
+	if (skb_shinfo(skb)->nr_frags > 0) {
+		unsigned int i, last;
+
+		last = skb_shinfo(skb)->nr_frags - 1;
+		for (i = 0; i <= last; i++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+			len = frag->size;
+			mapping = pci_map_page(tp->pdev,
+					       frag->page,
+					       frag->page_offset,
+					       len, PCI_DMA_TODEVICE);
+
+			tp->tx_buffers[entry].skb = NULL;
+			pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);
+
+			if (tg3_4g_overflow_test(mapping, len)) {
+				/* Only one should match. */
+				if (would_hit_hwbug)
+					BUG();
+				would_hit_hwbug = entry + 1;
+			}
+
+			tg3_set_txd(tp, entry, mapping, len,
+				    base_flags, (i == last));
+
+			entry = NEXT_TX(entry);
+		}
+	}
+
+	if (would_hit_hwbug) {
+		u32 last_plus_one = entry;
+		u32 start;
+		unsigned int len = 0;
+
+		would_hit_hwbug -= 1;
+		entry = entry - 1 - skb_shinfo(skb)->nr_frags;
+		entry &= (TG3_TX_RING_SIZE - 1);
+		start = entry;
+		i = 0;
+		while (entry != last_plus_one) {
+			if (i == 0)
+				len = skb->len - skb->data_len;
+			else
+				len = skb_shinfo(skb)->frags[i-1].size;
+
+			if (entry == would_hit_hwbug)
+				break;
+
+			i++;
+			entry = NEXT_TX(entry);
+
+		}
+
+		/* If the workaround fails due to memory/mapping
+		 * failure, silently drop this packet.
+		 */
+		if (tigon3_4gb_hwbug_workaround(tp, skb,
+						entry, len,
+						last_plus_one,
+						&start))
+			goto out_unlock;
+
+		entry = start;
+	}
+
+	/* Packets are ready, update Tx producer idx local and on card. */
+	if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) {
+		tw32_mailbox((MAILBOX_SNDHOST_PROD_IDX_0 +
+			      TG3_64BIT_REG_LOW), entry);
+		if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG)
+			tw32_mailbox((MAILBOX_SNDHOST_PROD_IDX_0 +
+				      TG3_64BIT_REG_LOW), entry);
+	} else {
+		tw32_mailbox((MAILBOX_SNDNIC_PROD_IDX_0 +
+			      TG3_64BIT_REG_LOW), entry);
+		if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG)
+			tw32_mailbox((MAILBOX_SNDNIC_PROD_IDX_0 +
+				      TG3_64BIT_REG_LOW), entry);
+	}
+
+	tp->tx_prod = entry;
+	if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))
+		netif_stop_queue(dev);
+
+out_unlock:
+	spin_unlock_irq(&tp->lock);
+
+	dev->trans_start = jiffies;
+
+	return 0;
+}
+
+static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+	dma_addr_t mapping;
+	u32 len, entry, base_flags;
+
+	len = (skb->len - skb->data_len);
+
+	spin_lock_irq(&tp->lock);
+
+	/* This is a hard error, log it. */
+	if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
+		netif_stop_queue(dev);
+		spin_unlock_irq(&tp->lock);
+		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+		       dev->name);
+		return 1;
+	}
+
+	entry = tp->tx_prod;
+	base_flags = 0;
+	if (skb->ip_summed == CHECKSUM_HW)
+		base_flags |= TXD_FLAG_TCPUDP_CSUM;
+#if TG3_VLAN_TAG_USED
+	if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+		base_flags |= (TXD_FLAG_VLAN |
+			       (vlan_tx_tag_get(skb) << 16));
+#endif
+
+	/* Queue skb data, a.k.a. the main skb fragment. */
+	mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+
+	tp->tx_buffers[entry].skb = skb;
+	pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);
+
+	tg3_set_txd(tp, entry, mapping, len, base_flags,
+		    (skb_shinfo(skb)->nr_frags == 0));
+
+	entry = NEXT_TX(entry);
+
+	/* Now loop through additional data fragments, and queue them. */
+	if (skb_shinfo(skb)->nr_frags > 0) {
+		unsigned int i, last;
+
+		last = skb_shinfo(skb)->nr_frags - 1;
+		for (i = 0; i <= last; i++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+
+			len = frag->size;
+			mapping = pci_map_page(tp->pdev,
+					       frag->page,
+					       frag->page_offset,
+					       len, PCI_DMA_TODEVICE);
+
+			tp->tx_buffers[entry].skb = NULL;
+			pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);
+
+			tg3_set_txd(tp, entry, mapping, len,
+				    base_flags, (i == last));
+
+			entry = NEXT_TX(entry);
+		}
+	}
+
+	/* Packets are ready, update Tx producer idx local and on card.
+	 * We know this is not a 5700 (by virtue of not being a chip
+	 * requiring the 4GB overflow workaround) so we can safely omit
+	 * the double-write bug tests.
+	 */
+	if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) {
+		tw32_mailbox((MAILBOX_SNDHOST_PROD_IDX_0 +
+			      TG3_64BIT_REG_LOW), entry);
+	} else {
+		tw32_mailbox((MAILBOX_SNDNIC_PROD_IDX_0 +
+			      TG3_64BIT_REG_LOW), entry);
+	}
+
+	tp->tx_prod = entry;
+	if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))
+		netif_stop_queue(dev);
+
+	spin_unlock_irq(&tp->lock);
+
+	dev->trans_start = jiffies;
+
+	return 0;
+}
+
+static int tg3_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct tg3 *tp = dev->priv;
+
+	if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU)
+		return -EINVAL;
+
+	if (!netif_running(dev)) {
+		/* We'll just catch it later when the
+		 * device is up'd.
+		 */
+		dev->mtu = new_mtu;
+		return 0;
+	}
+
+	spin_lock_irq(&tp->lock);
+
+	tg3_halt(tp);
+
+	dev->mtu = new_mtu;
+
+	if (new_mtu > ETH_DATA_LEN)
+		tp->tg3_flags |= TG3_FLAG_JUMBO_ENABLE;
+	else
+		tp->tg3_flags &= ~TG3_FLAG_JUMBO_ENABLE;
+
+	tg3_init_rings(tp);
+	tg3_init_hw(tp);
+
+	spin_unlock_irq(&tp->lock);
+
+	return 0;
+}
+
+/* Free up pending packets in all rx/tx rings.
+ *
+ * The chip has been shut down and the driver detached from
+ * the networking, so no interrupts or new tx packets will
+ * end up in the driver.  tp->lock is not held and we are not
+ * in an interrupt context and thus may sleep.
+ */
+static void tg3_free_rings(struct tg3 *tp)
+{
+	struct ring_info *rxp;
+	int i;
+
+	for (i = 0; i < TG3_RX_RING_SIZE; i++) {
+		rxp = &tp->rx_std_buffers[i];
+
+		if (rxp->skb == NULL)
+			continue;
+		pci_unmap_single(tp->pdev,
+				 pci_unmap_addr(rxp, mapping),
+				 RX_PKT_BUF_SZ - tp->rx_offset,
+				 PCI_DMA_FROMDEVICE);
+		dev_kfree_skb(rxp->skb);
+		rxp->skb = NULL;
+	}
+#if TG3_MINI_RING_WORKS
+	for (i = 0; i < TG3_RX_MINI_RING_SIZE; i++) {
+		rxp = &tp->rx_mini_buffers[i];
+
+		if (rxp->skb == NULL)
+			continue;
+		pci_unmap_single(tp->pdev,
+				 pci_unmap_addr(rxp, mapping),
+				 RX_MINI_PKT_BUF_SZ - tp->rx_offset,
+				 PCI_DMA_FROMDEVICE);
+		dev_kfree_skb(rxp->skb);
+		rxp->skb = NULL;
+	}
+#endif
+	for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+		rxp = &tp->rx_jumbo_buffers[i];
+
+		if (rxp->skb == NULL)
+			continue;
+		pci_unmap_single(tp->pdev,
+				 pci_unmap_addr(rxp, mapping),
+				 RX_JUMBO_PKT_BUF_SZ - tp->rx_offset,
+				 PCI_DMA_FROMDEVICE);
+		dev_kfree_skb(rxp->skb);
+		rxp->skb = NULL;
+	}
+
+	for (i = 0; i < TG3_TX_RING_SIZE; ) {
+		struct ring_info *txp;
+		struct sk_buff *skb;
+		int j;
+
+		txp = &tp->tx_buffers[i];
+		skb = txp->skb;
+
+		if (skb == NULL) {
+			i++;
+			continue;
+		}
+
+		pci_unmap_single(tp->pdev,
+				 pci_unmap_addr(txp, mapping),
+				 (skb->len - skb->data_len),
+				 PCI_DMA_TODEVICE);
+		txp->skb = NULL;
+
+		i++;
+
+		for (j = 0; j < skb_shinfo(skb)->nr_frags; j++) {
+			txp = &tp->tx_buffers[i & (TG3_TX_RING_SIZE - 1)];
+			pci_unmap_page(tp->pdev,
+				       pci_unmap_addr(txp, mapping),
+				       skb_shinfo(skb)->frags[j].size,
+				       PCI_DMA_TODEVICE);
+			i++;
+		}
+
+		dev_kfree_skb_any(skb);
+	}
+}
+
+/* Initialize tx/rx rings for packet processing.
+ *
+ * The chip has been shut down and the driver detached from
+ * the networking, so no interrupts or new tx packets will
+ * end up in the driver.  tp->lock is not held and we are not
+ * in an interrupt context and thus may sleep.
+ */
+static void tg3_init_rings(struct tg3 *tp)
+{
+	unsigned long start, end;
+	u32 i;
+
+	/* Free up all the SKBs. */
+	tg3_free_rings(tp);
+
+	/* Zero out all descriptors. */
+	memset(tp->rx_std, 0, TG3_RX_RING_BYTES);
+#if TG3_MINI_RING_WORKS
+	memset(tp->rx_mini, 0, TG3_RX_MINI_RING_BYTES);
+#endif
+	memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES);
+	memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES);
+
+	if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) {
+		memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
+	} else {
+		start = (tp->regs +
+			 NIC_SRAM_WIN_BASE +
+			 NIC_SRAM_TX_BUFFER_DESC);
+		end = start + TG3_TX_RING_BYTES;
+		while (start < end) {
+			writel(0, start);
+			start += 4;
+		}
+	}
+
+	/* Initialize invariants of the rings, we only set this
+	 * stuff once.  This works because the card does not
+	 * write into the rx buffer posting rings.
+	 */
+	for (i = 0; i < TG3_RX_RING_SIZE; i++) {
+		struct tg3_rx_buffer_desc *rxd;
+
+		rxd = &tp->rx_std[i];
+		rxd->idx_len = (RX_PKT_BUF_SZ - tp->rx_offset - 64)
+			<< RXD_LEN_SHIFT;
+		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
+		rxd->opaque = (RXD_OPAQUE_RING_STD |
+			       (i << RXD_OPAQUE_INDEX_SHIFT));
+	}
+#if TG3_MINI_RING_WORKS
+	for (i = 0; i < TG3_RX_MINI_RING_SIZE; i++) {
+		struct tg3_rx_buffer_desc *rxd;
+
+		rxd = &tp->rx_mini[i];
+		rxd->idx_len = (RX_MINI_PKT_BUF_SZ - tp->rx_offset - 64)
+			<< RXD_LEN_SHIFT;
+		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
+			RXD_FLAG_MINI;
+		rxd->opaque = (RXD_OPAQUE_RING_MINI |
+			       (i << RXD_OPAQUE_INDEX_SHIFT));
+	}
+#endif
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) {
+		for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+			struct tg3_rx_buffer_desc *rxd;
+
+			rxd = &tp->rx_jumbo[i];
+			rxd->idx_len = (RX_JUMBO_PKT_BUF_SZ - tp->rx_offset - 64)
+				<< RXD_LEN_SHIFT;
+			rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
+				RXD_FLAG_JUMBO;
+			rxd->opaque = (RXD_OPAQUE_RING_JUMBO |
+			       (i << RXD_OPAQUE_INDEX_SHIFT));
+		}
+	}
+
+	/* Now allocate fresh SKBs for each rx ring. */
+	for (i = 0; i < tp->rx_pending; i++) {
+		if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD,
+				     -1, i) < 0)
+			break;
+	}
+
+#if TG3_MINI_RING_WORKS
+	for (i = 0; i < tp->rx_mini_pending; i++) {
+		if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_MINI,
+				     -1, i) < 0)
+			break;
+	}
+#endif
+
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) {
+		for (i = 0; i < tp->rx_jumbo_pending; i++) {
+			if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
+					     -1, i) < 0)
+				break;
+		}
+	}
+}
+
+/*
+ * Must not be invoked with interrupt sources disabled and
+ * the hardware shutdown down.
+ */
+static void tg3_free_consistent(struct tg3 *tp)
+{
+	if (tp->rx_std_buffers) {
+		kfree(tp->rx_std_buffers);
+		tp->rx_std_buffers = NULL;
+	}
+	if (tp->rx_std) {
+		pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
+				    tp->rx_std, tp->rx_std_mapping);
+		tp->rx_std = NULL;
+	}
+#if TG3_MINI_RING_WORKS
+	if (tp->rx_mini) {
+		pci_free_consistent(tp->pdev, TG3_RX_MINI_RING_BYTES,
+				    tp->rx_mini, tp->rx_mini_mapping);
+		tp->rx_mini = NULL;
+	}
+#endif
+	if (tp->rx_jumbo) {
+		pci_free_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES,
+				    tp->rx_jumbo, tp->rx_jumbo_mapping);
+		tp->rx_jumbo = NULL;
+	}
+	if (tp->rx_rcb) {
+		pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES,
+				    tp->rx_rcb, tp->rx_rcb_mapping);
+		tp->rx_rcb = NULL;
+	}
+	if (tp->tx_ring) {
+		pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
+			tp->tx_ring, tp->tx_desc_mapping);
+		tp->tx_ring = NULL;
+	}
+	if (tp->hw_status) {
+		pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
+				    tp->hw_status, tp->status_mapping);
+		tp->hw_status = NULL;
+	}
+	if (tp->hw_stats) {
+		pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats),
+				    tp->hw_stats, tp->stats_mapping);
+		tp->hw_stats = NULL;
+	}
+}
+
+/*
+ * Must not be invoked with interrupt sources disabled and
+ * the hardware shutdown down.  Can sleep.
+ */
+static int tg3_alloc_consistent(struct tg3 *tp)
+{
+	tp->rx_std_buffers = kmalloc(sizeof(struct ring_info) *
+				     (TG3_RX_RING_SIZE +
+#if TG3_MINI_RING_WORKS
+				      TG3_RX_MINI_RING_SIZE +
+#endif
+				      TG3_RX_JUMBO_RING_SIZE +
+				      TG3_TX_RING_SIZE),
+				     GFP_KERNEL);
+	if (!tp->rx_std_buffers)
+		return -ENOMEM;
+
+#if TG3_MINI_RING_WORKS
+	memset(tp->rx_std_buffers, 0,
+	       (sizeof(struct ring_info) *
+		(TG3_RX_RING_SIZE +
+		 TG3_RX_MINI_RING_SIZE +
+		 TG3_RX_JUMBO_RING_SIZE +
+		 TG3_TX_RING_SIZE)));
+#else
+	memset(tp->rx_std_buffers, 0,
+	       (sizeof(struct ring_info) *
+		(TG3_RX_RING_SIZE +
+		 TG3_RX_JUMBO_RING_SIZE +
+		 TG3_TX_RING_SIZE)));
+#endif
+
+#if TG3_MINI_RING_WORKS
+	tp->rx_mini_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
+	tp->rx_jumbo_buffers = &tp->rx_mini_buffers[TG3_RX_MINI_RING_SIZE];
+#else
+	tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
+#endif
+	tp->tx_buffers = &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
+
+	tp->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
+					  &tp->rx_std_mapping);
+	if (!tp->rx_std)
+		goto err_out;
+
+#if TG3_MINI_RING_WORKS
+	tp->rx_mini = pci_alloc_consistent(tp->pdev, TG3_RX_MINI_RING_BYTES,
+					   &tp->rx_mini_mapping);
+
+	if (!tp->rx_mini)
+		goto err_out;
+#endif
+
+	tp->rx_jumbo = pci_alloc_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES,
+					    &tp->rx_jumbo_mapping);
+
+	if (!tp->rx_jumbo)
+		goto err_out;
+
+	tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES,
+					  &tp->rx_rcb_mapping);
+	if (!tp->rx_rcb)
+		goto err_out;
+
+	if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) {
+		tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES,
+						   &tp->tx_desc_mapping);
+		if (!tp->tx_ring)
+			goto err_out;
+	} else {
+		tp->tx_ring = NULL;
+		tp->tx_desc_mapping = 0;
+	}
+
+	tp->hw_status = pci_alloc_consistent(tp->pdev,
+					     TG3_HW_STATUS_SIZE,
+					     &tp->status_mapping);
+	if (!tp->hw_status)
+		goto err_out;
+
+	tp->hw_stats = pci_alloc_consistent(tp->pdev,
+					    sizeof(struct tg3_hw_stats),
+					    &tp->stats_mapping);
+	if (!tp->hw_stats)
+		goto err_out;
+
+	memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+	memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
+
+	return 0;
+
+err_out:
+	tg3_free_consistent(tp);
+	return -ENOMEM;
+}
+
+#define MAX_WAIT_CNT 10000
+
+/* To stop a block, clear the enable bit and poll till it
+ * clears.  tp->lock is held.
+ */
+static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit)
+{
+	unsigned int i;
+	u32 val;
+
+	val = tr32(ofs);
+	val &= ~enable_bit;
+	tw32(ofs, val);
+
+	for (i = 0; i < MAX_WAIT_CNT; i++) {
+		val = tr32(ofs);
+
+		if ((val & enable_bit) == 0)
+			break;
+		udelay(100);
+	}
+
+	if (i == MAX_WAIT_CNT) {
+		printk(KERN_ERR PFX "tg3_stop_block timed out, "
+		       "ofs=%lx enable_bit=%x\n",
+		       ofs, enable_bit);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/* tp->lock is held. */
+static int tg3_abort_hw(struct tg3 *tp)
+{
+	int i, err;
+
+	tg3_disable_ints(tp);
+
+	tp->rx_mode &= ~RX_MODE_ENABLE;
+	tw32(MAC_RX_MODE, tp->rx_mode);
+
+	err  = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE);
+
+	err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE);
+	err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE);
+	err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE);
+	if (err)
+		goto out;
+
+	tp->mac_mode &= ~MAC_MODE_TDE_ENABLE;
+	tw32(MAC_MODE, tp->mac_mode);
+
+	tp->tx_mode &= ~TX_MODE_ENABLE;
+	tw32(MAC_TX_MODE, tp->tx_mode);
+	for (i = 0; i < MAX_WAIT_CNT; i++) {
+		udelay(100);
+		if (!(tr32(MAC_TX_MODE) & TX_MODE_ENABLE))
+			break;
+	}
+	if (i >= MAX_WAIT_CNT) {
+		printk(KERN_ERR PFX "tg3_abort_hw timed out for %s, "
+		       "TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n",
+		       tp->dev->name, tr32(MAC_TX_MODE));
+		return -ENODEV;
+	}
+
+	err  = tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE);
+
+	tw32(FTQ_RESET, 0xffffffff);
+	tw32(FTQ_RESET, 0x00000000);
+
+	err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE);
+	err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE);
+	if (err)
+		goto out;
+
+	memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+out:
+	return err;
+}
+
+/* tp->lock is held. */
+static void tg3_chip_reset(struct tg3 *tp)
+{
+	u32 val;
+
+	/* Force NVRAM to settle.
+	 * This deals with a chip bug which can result in EEPROM
+	 * corruption.
+	 */
+	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+		int i;
+
+		tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+		for (i = 0; i < 100000; i++) {
+			if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+				break;
+			udelay(10);
+		}
+	}
+
+	tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET);
+	udelay(40);
+	udelay(40);
+	udelay(40);
+
+	/* Re-enable indirect register accesses. */
+	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+			       tp->misc_host_ctrl);
+
+	/* Set MAX PCI retry to zero. */
+	pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE,
+			       (PCISTATE_ROM_ENABLE |
+				PCISTATE_ROM_RETRY_ENABLE));
+
+	pci_restore_state(tp->pdev, tp->pci_cfg_state);
+
+	/* Make sure PCI-X relaxed ordering bit is clear. */
+	pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
+	val &= ~PCIX_CAPS_RELAXED_ORDERING;
+	pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val);
+
+	tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
+
+	tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
+}
+
+/* tp->lock is held. */
+static int tg3_halt(struct tg3 *tp)
+{
+	u32 val;
+	int i;
+
+	tg3_abort_hw(tp);
+	tg3_chip_reset(tp);
+	tg3_write_mem(tp,
+		      NIC_SRAM_FIRMWARE_MBOX,
+		      NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
+	for (i = 0; i < 100000; i++) {
+		tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
+		if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+			break;
+		udelay(10);
+	}
+
+	if (i >= 100000) {
+		printk(KERN_ERR PFX "tg3_halt timed out for %s, "
+		       "firmware will not restart magic=%08x\n",
+		       tp->dev->name, val);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+#define TG3_FW_RELEASE_MAJOR	0x0
+#define TG3_FW_RELASE_MINOR	0x0
+#define TG3_FW_RELEASE_FIX	0x0
+#define TG3_FW_START_ADDR	0x08000000
+#define TG3_FW_TEXT_ADDR	0x08000000
+#define TG3_FW_TEXT_LEN		0x9c0
+#define TG3_FW_RODATA_ADDR	0x080009c0
+#define TG3_FW_RODATA_LEN	0x60
+#define TG3_FW_DATA_ADDR	0x08000a40
+#define TG3_FW_DATA_LEN		0x20
+#define TG3_FW_SBSS_ADDR	0x08000a60
+#define TG3_FW_SBSS_LEN		0xc
+#define TG3_FW_BSS_ADDR		0x08000a70
+#define TG3_FW_BSS_LEN		0x10
+
+static u32 t3FwText[(TG3_FW_TEXT_LEN / sizeof(u32)) + 1] = {
+	0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800,
+	0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000018, 0x00000000,
+	0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100034,
+	0x0e00021c, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, 0x00000000,
+	0x27bdffe0, 0x3c1cc000, 0xafbf0018, 0xaf80680c, 0x0e00004c, 0x241b2105,
+	0x97850000, 0x97870002, 0x9782002c, 0x9783002e, 0x3c040800, 0x248409c0,
+	0xafa00014, 0x00021400, 0x00621825, 0x00052c00, 0xafa30010, 0x8f860010,
+	0x00e52825, 0x0e000060, 0x24070102, 0x3c02ac00, 0x34420100, 0x3c03ac01,
+	0x34630100, 0xaf820490, 0x3c02ffff, 0xaf820494, 0xaf830498, 0xaf82049c,
+	0x24020001, 0xaf825ce0, 0x0e00003f, 0xaf825d00, 0x0e000140, 0x00000000,
+	0x8fbf0018, 0x03e00008, 0x27bd0020, 0x2402ffff, 0xaf825404, 0x8f835400,
+	0x34630400, 0xaf835400, 0xaf825404, 0x3c020800, 0x24420034, 0xaf82541c,
+	0x03e00008, 0xaf805400, 0x00000000, 0x00000000, 0x3c020800, 0x34423000,
+	0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac220a64,
+	0x24020040, 0x3c010800, 0xac220a68, 0x3c010800, 0xac200a60, 0xac600000,
+	0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000,
+	0x00804821, 0x8faa0010, 0x3c020800, 0x8c420a60, 0x3c040800, 0x8c840a68,
+	0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac230a60, 0x14400003,
+	0x00004021, 0x3c010800, 0xac200a60, 0x3c020800, 0x8c420a60, 0x3c030800,
+	0x8c630a64, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001,
+	0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c420a60,
+	0x3c030800, 0x8c630a64, 0x8f84680c, 0x00021140, 0x00431021, 0xac440008,
+	0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0,
+	0x02000008, 0x00000000, 0x0a0001e3, 0x3c0a0001, 0x0a0001e3, 0x3c0a0002,
+	0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
+	0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
+	0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
+	0x0a0001e3, 0x3c0a0007, 0x0a0001e3, 0x3c0a0008, 0x0a0001e3, 0x3c0a0009,
+	0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a000b,
+	0x0a0001e3, 0x3c0a000c, 0x0a0001e3, 0x3c0a000d, 0x0a0001e3, 0x00000000,
+	0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a000e, 0x0a0001e3, 0x00000000,
+	0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
+	0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
+	0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a0013, 0x0a0001e3, 0x3c0a0014,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0x27bdffe0, 0x00001821, 0x00001021, 0xafbf0018, 0xafb10014, 0xafb00010,
+	0x3c010800, 0x00220821, 0xac200a70, 0x3c010800, 0x00220821, 0xac200a74,
+	0x3c010800, 0x00220821, 0xac200a78, 0x24630001, 0x1860fff5, 0x2442000c,
+	0x24110001, 0x8f906810, 0x32020004, 0x14400005, 0x24040001, 0x3c020800,
+	0x8c420a78, 0x18400003, 0x00002021, 0x0e000182, 0x00000000, 0x32020001,
+	0x10400003, 0x00000000, 0x0e000169, 0x00000000, 0x0a000153, 0xaf915028,
+	0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c050800,
+	0x8ca50a70, 0x3c060800, 0x8cc60a80, 0x3c070800, 0x8ce70a78, 0x27bdffe0,
+	0x3c040800, 0x248409d0, 0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014,
+	0x0e00017b, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001,
+	0x8f836810, 0x00821004, 0x00021027, 0x00621824, 0x03e00008, 0xaf836810,
+	0x27bdffd8, 0xafbf0024, 0x1080002e, 0xafb00020, 0x8f825cec, 0xafa20018,
+	0x8f825cec, 0x3c100800, 0x26100a78, 0xafa2001c, 0x34028000, 0xaf825cec,
+	0x8e020000, 0x18400016, 0x00000000, 0x3c020800, 0x94420a74, 0x8fa3001c,
+	0x000221c0, 0xac830004, 0x8fa2001c, 0x3c010800, 0x0e000201, 0xac220a74,
+	0x10400005, 0x00000000, 0x8e020000, 0x24420001, 0x0a0001df, 0xae020000,
+	0x3c020800, 0x8c420a70, 0x00021c02, 0x000321c0, 0x0a0001c5, 0xafa2001c,
+	0x0e000201, 0x00000000, 0x1040001f, 0x00000000, 0x8e020000, 0x8fa3001c,
+	0x24420001, 0x3c010800, 0xac230a70, 0x3c010800, 0xac230a74, 0x0a0001df,
+	0xae020000, 0x3c100800, 0x26100a78, 0x8e020000, 0x18400028, 0x00000000,
+	0x0e000201, 0x00000000, 0x14400024, 0x00000000, 0x8e020000, 0x3c030800,
+	0x8c630a70, 0x2442ffff, 0xafa3001c, 0x18400006, 0xae020000, 0x00031402,
+	0x000221c0, 0x8c820004, 0x3c010800, 0xac220a70, 0x97a2001e, 0x2442ff00,
+	0x2c420300, 0x1440000b, 0x24024000, 0x3c040800, 0x248409dc, 0xafa00010,
+	0xafa00014, 0x8fa6001c, 0x24050008, 0x0e000060, 0x00003821, 0x0a0001df,
+	0x00000000, 0xaf825cf8, 0x3c020800, 0x8c420a40, 0x8fa3001c, 0x24420001,
+	0xaf835cf8, 0x3c010800, 0xac220a40, 0x8fbf0024, 0x8fb00020, 0x03e00008,
+	0x27bd0028, 0x27bdffe0, 0x3c040800, 0x248409e8, 0x00002821, 0x00003021,
+	0x00003821, 0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014, 0x8fbf0018,
+	0x03e00008, 0x27bd0020, 0x8f82680c, 0x8f85680c, 0x00021827, 0x0003182b,
+	0x00031823, 0x00431024, 0x00441021, 0x00a2282b, 0x10a00006, 0x00000000,
+	0x00401821, 0x8f82680c, 0x0043102b, 0x1440fffd, 0x00000000, 0x03e00008,
+	0x00000000, 0x3c040800, 0x8c840000, 0x3c030800, 0x8c630a40, 0x0064102b,
+	0x54400002, 0x00831023, 0x00641023, 0x2c420008, 0x03e00008, 0x38420001,
+	0x27bdffe0, 0x00802821, 0x3c040800, 0x24840a00, 0x00003021, 0x00003821,
+	0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014, 0x0a000216, 0x00000000,
+	0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, 0x27bdffe0, 0x3c1cc000,
+	0xafbf0018, 0x0e00004c, 0xaf80680c, 0x3c040800, 0x24840a10, 0x03802821,
+	0x00003021, 0x00003821, 0xafa00010, 0x0e000060, 0xafa00014, 0x2402ffff,
+	0xaf825404, 0x3c0200aa, 0x0e000234, 0xaf825434, 0x8fbf0018, 0x03e00008,
+	0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe8, 0xafb00010,
+	0x24100001, 0xafbf0014, 0x3c01c003, 0xac200000, 0x8f826810, 0x30422000,
+	0x10400003, 0x00000000, 0x0e000246, 0x00000000, 0x0a00023a, 0xaf905428,
+	0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdfff8, 0x8f845d0c,
+	0x3c0200ff, 0x3c030800, 0x8c630a50, 0x3442fff8, 0x00821024, 0x1043001e,
+	0x3c0500ff, 0x34a5fff8, 0x3c06c003, 0x3c074000, 0x00851824, 0x8c620010,
+	0x3c010800, 0xac230a50, 0x30420008, 0x10400005, 0x00871025, 0x8cc20000,
+	0x24420001, 0xacc20000, 0x00871025, 0xaf825d0c, 0x8fa20000, 0x24420001,
+	0xafa20000, 0x8fa20000, 0x8fa20000, 0x24420001, 0xafa20000, 0x8fa20000,
+	0x8f845d0c, 0x3c030800, 0x8c630a50, 0x00851024, 0x1443ffe8, 0x00851824,
+	0x27bd0008, 0x03e00008, 0x00000000, 0x00000000, 0x00000000
+};
+
+static u32 t3FwRodata[(TG3_FW_RODATA_LEN / sizeof(u32)) + 1] = {
+	0x35373031, 0x726c7341, 0x00000000, 0x00000000, 0x53774576, 0x656e7430,
+	0x00000000, 0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e, 0x45766e74,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66617461, 0x6c457272,
+	0x00000000, 0x00000000, 0x4d61696e, 0x43707542, 0x00000000, 0x00000000,
+	0x00000000
+};
+
+#if 0 /* All zeros, dont eat up space with it. */
+u32 t3FwData[(TG3_FW_DATA_LEN / sizeof(u32)) + 1] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+#endif
+
+#define RX_CPU_SCRATCH_BASE	0x30000
+#define RX_CPU_SCRATCH_SIZE	0x04000
+#define TX_CPU_SCRATCH_BASE	0x34000
+#define TX_CPU_SCRATCH_SIZE	0x04000
+
+/* tp->lock is held. */
+static int tg3_reset_cpu(struct tg3 *tp, u32 offset)
+{
+	int i;
+
+	tw32(offset + CPU_STATE, 0xffffffff);
+	tw32(offset + CPU_MODE,  CPU_MODE_RESET);
+	if (offset == RX_CPU_BASE) {
+		for (i = 0; i < 10000; i++)
+			if (!(tr32(offset + CPU_MODE) & CPU_MODE_RESET))
+				break;
+		tw32(offset + CPU_STATE, 0xffffffff);
+		tw32(offset + CPU_MODE,  CPU_MODE_RESET);
+		udelay(10);
+	} else {
+		for (i = 0; i < 10000; i++) {
+			if (!(tr32(offset + CPU_MODE) & CPU_MODE_RESET))
+				break;
+			tw32(offset + CPU_STATE, 0xffffffff);
+			tw32(offset + CPU_MODE,  CPU_MODE_RESET);
+			udelay(10);
+		}
+	}
+
+	if (i >= 10000) {
+		printk(KERN_ERR PFX "tg3_reset_cpu timed out for %s, "
+		       "and %s CPU\n",
+		       tp->dev->name,
+		       (offset == RX_CPU_BASE ? "RX" : "TX"));
+		return -ENODEV;
+	}
+	return 0;
+}
+
+/* tp->lock is held. */
+static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base,
+				 int cpu_scratch_size)
+{
+	int err, i;
+
+	err = tg3_reset_cpu(tp, cpu_base);
+	if (err)
+		return err;
+
+	for (i = 0; i < cpu_scratch_size; i += sizeof(u32))
+		tg3_write_indirect_reg32(tp, cpu_scratch_base + i, 0);
+	tw32(cpu_base + CPU_STATE, 0xffffffff);
+	tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT);
+	for (i = 0; i < (TG3_FW_TEXT_LEN / sizeof(u32)); i++)
+		tg3_write_indirect_reg32(tp, (cpu_scratch_base +
+					      (TG3_FW_TEXT_ADDR & 0xffff) +
+					      (i * sizeof(u32))),
+					 t3FwText[i]);
+	for (i = 0; i < (TG3_FW_RODATA_LEN / sizeof(u32)); i++)
+		tg3_write_indirect_reg32(tp, (cpu_scratch_base +
+					      (TG3_FW_RODATA_ADDR & 0xffff) +
+					      (i * sizeof(u32))),
+					 t3FwRodata[i]);
+	for (i = 0; i < (TG3_FW_DATA_LEN / sizeof(u32)); i++)
+		tg3_write_indirect_reg32(tp, (cpu_scratch_base +
+					      (TG3_FW_DATA_ADDR & 0xffff) +
+					      (i * sizeof(u32))),
+					 0);
+
+	return 0;
+}
+
+/* tp->lock is held. */
+static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
+{
+	int err, i;
+
+	err = tg3_load_firmware_cpu(tp, RX_CPU_BASE,
+				    RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE);
+	if (err)
+		return err;
+
+	err = tg3_load_firmware_cpu(tp, TX_CPU_BASE,
+				    TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE);
+	if (err)
+		return err;
+
+	/* Now startup only the RX cpu. */
+	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
+	tw32(RX_CPU_BASE + CPU_PC,    TG3_FW_TEXT_ADDR);
+
+	/* Flush posted writes. */
+	tr32(RX_CPU_BASE + CPU_PC);
+	for (i = 0; i < 5; i++) {
+		if (tr32(RX_CPU_BASE + CPU_PC) == TG3_FW_TEXT_ADDR)
+			break;
+		tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
+		tw32(RX_CPU_BASE + CPU_MODE,  CPU_MODE_HALT);
+		tw32(RX_CPU_BASE + CPU_PC,    TG3_FW_TEXT_ADDR);
+
+		/* Flush posted writes. */
+		tr32(RX_CPU_BASE + CPU_PC);
+
+		udelay(1000);
+	}
+	if (i >= 5) {
+		printk(KERN_ERR PFX "tg3_load_firmware fails for %s "
+		       "to set RX CPU PC, is %08x should be %08x\n",
+		       tp->dev->name, tr32(RX_CPU_BASE + CPU_PC),
+		       TG3_FW_TEXT_ADDR);
+		return -ENODEV;
+	}
+	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
+	tw32(RX_CPU_BASE + CPU_MODE,  0x00000000);
+
+	/* Flush posted writes. */
+	tr32(RX_CPU_BASE + CPU_MODE);
+
+	return 0;
+}
+
+/* tp->lock is held. */
+static void __tg3_set_mac_addr(struct tg3 *tp)
+{
+	u32 addr_high, addr_low;
+	int i;
+
+	addr_high = ((tp->dev->dev_addr[0] << 8) |
+		     tp->dev->dev_addr[1]);
+	addr_low = ((tp->dev->dev_addr[2] << 24) |
+		    (tp->dev->dev_addr[3] << 16) |
+		    (tp->dev->dev_addr[4] <<  8) |
+		    (tp->dev->dev_addr[5] <<  0));
+	for (i = 0; i < 4; i++) {
+		tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
+		tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
+	}
+
+	addr_high = (tp->dev->dev_addr[0] +
+		     tp->dev->dev_addr[1] +
+		     tp->dev->dev_addr[2] +
+		     tp->dev->dev_addr[3] +
+		     tp->dev->dev_addr[4] +
+		     tp->dev->dev_addr[5]) &
+		TX_BACKOFF_SEED_MASK;
+	tw32(MAC_TX_BACKOFF_SEED, addr_high);
+}
+
+static int tg3_set_mac_addr(struct net_device *dev, void *p)
+{
+	struct tg3 *tp = dev->priv;
+	struct sockaddr *addr = p;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	spin_lock_irq(&tp->lock);
+	__tg3_set_mac_addr(tp);
+	spin_unlock_irq(&tp->lock);
+
+	return 0;
+}
+
+/* tp->lock is held. */
+static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr,
+			   dma_addr_t mapping, u32 maxlen_flags,
+			   u32 nic_addr)
+{
+	tg3_write_mem(tp,
+		      (bdinfo_addr +
+		       TG3_BDINFO_HOST_ADDR +
+		       TG3_64BIT_REG_HIGH),
+		      ((u64) mapping >> 32));
+	tg3_write_mem(tp,
+		      (bdinfo_addr +
+		       TG3_BDINFO_HOST_ADDR +
+		       TG3_64BIT_REG_LOW),
+		      ((u64) mapping & 0xffffffff));
+	tg3_write_mem(tp,
+		      (bdinfo_addr +
+		       TG3_BDINFO_MAXLEN_FLAGS),
+		       maxlen_flags);
+	tg3_write_mem(tp,
+		      (bdinfo_addr +
+		       TG3_BDINFO_NIC_ADDR),
+		      nic_addr);
+}
+
+static void __tg3_set_rx_mode(struct net_device *);
+
+/* tp->lock is held. */
+static int tg3_reset_hw(struct tg3 *tp)
+{
+	u32 val;
+	int i, err;
+
+	tg3_disable_ints(tp);
+
+	if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) {
+		err = tg3_abort_hw(tp);
+		if (err)
+			return err;
+	}
+
+	tg3_chip_reset(tp);
+
+	tw32(GRC_MODE, tp->grc_mode);
+	tg3_write_mem(tp,
+		      NIC_SRAM_FIRMWARE_MBOX,
+		      NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
+	if (tp->phy_id == PHY_ID_SERDES) {
+		tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
+		tw32(MAC_MODE, tp->mac_mode);
+	} else
+		tw32(MAC_MODE, 0);
+
+	/* Wait for firmware initialization to complete. */
+	for (i = 0; i < 100000; i++) {
+		tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
+		if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+			break;
+		udelay(10);
+	}
+	if (i >= 100000) {
+		printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, "
+		       "firmware will not restart magic=%08x\n",
+		       tp->dev->name, val);
+		return -ENODEV;
+	}
+
+	/* This works around an issue with Athlon chipsets on
+	 * B3 tigon3 silicon.  This bit has no effect on any
+	 * other revision.
+	 */
+	val = tr32(TG3PCI_CLOCK_CTRL);
+	val |= CLOCK_CTRL_DELAY_PCI_GRANT;
+	tw32(TG3PCI_CLOCK_CTRL, val);
+
+	/* Clear statistics/status block in chip, and status block in ram. */
+	for (i = NIC_SRAM_STATS_BLK;
+	     i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
+	     i += sizeof(u32))
+		tg3_write_mem(tp, i, 0);
+	memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+	/* This value is determined during the probe time DMA
+	 * engine test, tg3_test_dma.
+	 */
+	tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
+
+	tp->grc_mode &= ~(GRC_MODE_HOST_SENDBDS |
+			  GRC_MODE_4X_NIC_SEND_RINGS |
+			  GRC_MODE_NO_TX_PHDR_CSUM |
+			  GRC_MODE_NO_RX_PHDR_CSUM);
+	if (tp->tg3_flags & TG3_FLAG_HOST_TXDS)
+		tp->grc_mode |= GRC_MODE_HOST_SENDBDS;
+	else
+		tp->grc_mode |= GRC_MODE_4X_NIC_SEND_RINGS;
+	if (tp->tg3_flags & TG3_FLAG_NO_TX_PSEUDO_CSUM)
+		tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM;
+	if (tp->tg3_flags & TG3_FLAG_NO_RX_PSEUDO_CSUM)
+		tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM;
+
+	tw32(GRC_MODE,
+	     tp->grc_mode |
+	     (GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP));
+
+	/* Setup the timer prescalar register.  Clock is always 66Mhz. */
+	tw32(GRC_MISC_CFG,
+	     (65 << GRC_MISC_CFG_PRESCALAR_SHIFT));
+
+	/* Initialize MBUF/DESC pool. */
+	tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
+	tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE);
+	tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
+	tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
+
+	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)) {
+		tw32(BUFMGR_MB_RDMA_LOW_WATER,
+		     tp->bufmgr_config.mbuf_read_dma_low_water);
+		tw32(BUFMGR_MB_MACRX_LOW_WATER,
+		     tp->bufmgr_config.mbuf_mac_rx_low_water);
+		tw32(BUFMGR_MB_HIGH_WATER,
+		     tp->bufmgr_config.mbuf_high_water);
+	} else {
+		tw32(BUFMGR_MB_RDMA_LOW_WATER,
+		     tp->bufmgr_config.mbuf_read_dma_low_water_jumbo);
+		tw32(BUFMGR_MB_MACRX_LOW_WATER,
+		     tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo);
+		tw32(BUFMGR_MB_HIGH_WATER,
+		     tp->bufmgr_config.mbuf_high_water_jumbo);
+	}
+	tw32(BUFMGR_DMA_LOW_WATER,
+	     tp->bufmgr_config.dma_low_water);
+	tw32(BUFMGR_DMA_HIGH_WATER,
+	     tp->bufmgr_config.dma_high_water);
+
+	tw32(BUFMGR_MODE, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
+	for (i = 0; i < 2000; i++) {
+		if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
+			break;
+		udelay(10);
+	}
+	if (i >= 2000) {
+		printk(KERN_ERR PFX "tg3_reset_hw cannot enable BUFMGR for %s.\n",
+		       tp->dev->name);
+		return -ENODEV;
+	}
+
+	tw32(FTQ_RESET, 0xffffffff);
+	tw32(FTQ_RESET, 0x00000000);
+	for (i = 0; i < 2000; i++) {
+		if (tr32(FTQ_RESET) == 0x00000000)
+			break;
+		udelay(10);
+	}
+	if (i >= 2000) {
+		printk(KERN_ERR PFX "tg3_reset_hw cannot reset FTQ for %s.\n",
+		       tp->dev->name);
+		return -ENODEV;
+	}
+
+	/* Initialize TG3_BDINFO's at:
+	 *  RCVDBDI_STD_BD:	standard eth size rx ring
+	 *  RCVDBDI_JUMBO_BD:	jumbo frame rx ring
+	 *  RCVDBDI_MINI_BD:	small frame rx ring (??? does not work)
+	 *
+	 * like so:
+	 *  TG3_BDINFO_HOST_ADDR:	high/low parts of DMA address of ring
+	 *  TG3_BDINFO_MAXLEN_FLAGS:	(rx max buffer size << 16) |
+	 *                              ring attribute flags
+	 *  TG3_BDINFO_NIC_ADDR:	location of descriptors in nic SRAM
+	 *
+	 * Standard receive ring @ NIC_SRAM_RX_BUFFER_DESC, 512 entries.
+	 * Jumbo receive ring @ NIC_SRAM_RX_JUMBO_BUFFER_DESC, 256 entries.
+	 *
+	 * ??? No space allocated for mini receive ring? :(
+	 *
+	 * The size of each ring is fixed in the firmware, but the location is
+	 * configurable.
+	 */
+	tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
+	     ((u64) tp->rx_std_mapping >> 32));
+	tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
+	     ((u64) tp->rx_std_mapping & 0xffffffff));
+	tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
+	     RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
+	tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
+	     NIC_SRAM_RX_BUFFER_DESC);
+
+#if TG3_MINI_RING_WORKS
+	tw32(RCVDBDI_MINI_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
+	     ((u64) tp->rx_mini_mapping >> 32));
+	tw32(RCVDBDI_MINI_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
+	     ((u64) tp->rx_mini_mapping & 0xffffffff));
+	tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,
+	     RX_MINI_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
+	tw32(RCVDBDI_MINI_BD + TG3_BDINFO_NIC_ADDR,
+	     NIC_SRAM_RX_MINI_BUFFER_DESC);
+#else
+	tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,
+	     BDINFO_FLAGS_DISABLED);
+#endif
+
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) {
+		tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
+		     ((u64) tp->rx_jumbo_mapping >> 32));
+		tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
+		     ((u64) tp->rx_jumbo_mapping & 0xffffffff));
+		tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
+		     RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
+		tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
+		     NIC_SRAM_RX_JUMBO_BUFFER_DESC);
+	} else {
+		tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
+		     BDINFO_FLAGS_DISABLED);
+	}
+
+	/* Setup replenish thresholds. */
+	tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8);
+#if TG3_MINI_RING_WORKS
+	tw32(RCVBDI_MINI_THRESH, tp->rx_mini_pending / 8);
+#endif
+	tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
+
+	/* Clear out send RCB ring in SRAM. */
+	for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE)
+		tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED);
+
+	tp->tx_prod = 0;
+	tp->tx_cons = 0;
+	tw32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
+	tw32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
+
+	if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) {
+		tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB,
+			       tp->tx_desc_mapping,
+			       (TG3_TX_RING_SIZE <<
+				BDINFO_FLAGS_MAXLEN_SHIFT),
+			       NIC_SRAM_TX_BUFFER_DESC);
+	} else {
+		tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB,
+			       0,
+			       BDINFO_FLAGS_DISABLED,
+			       NIC_SRAM_TX_BUFFER_DESC);
+	}
+
+	for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK; i += TG3_BDINFO_SIZE) {
+		tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS,
+			      BDINFO_FLAGS_DISABLED);
+	}
+
+	tp->rx_rcb_ptr = 0;
+	tw32_mailbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, 0);
+
+	tg3_set_bdinfo(tp, NIC_SRAM_RCV_RET_RCB,
+		       tp->rx_rcb_mapping,
+		       (TG3_RX_RCB_RING_SIZE <<
+			BDINFO_FLAGS_MAXLEN_SHIFT),
+		       0);
+
+	tp->rx_std_ptr = tp->rx_pending;
+	tw32_mailbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
+		     tp->rx_std_ptr);
+#if TG3_MINI_RING_WORKS
+	tp->rx_mini_ptr = tp->rx_mini_pending;
+	tw32_mailbox(MAILBOX_RCV_MINI_PROD_IDX + TG3_64BIT_REG_LOW,
+		     tp->rx_mini_ptr);
+#endif
+
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)
+		tp->rx_jumbo_ptr = tp->rx_jumbo_pending;
+	else
+		tp->rx_jumbo_ptr = 0;
+	tw32_mailbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
+		     tp->rx_jumbo_ptr);
+
+	/* Initialize MAC address and backoff seed. */
+	__tg3_set_mac_addr(tp);
+
+	/* MTU + ethernet header + FCS + optional VLAN tag */
+	tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8);
+
+	/* The slot time is changed by tg3_setup_phy if we
+	 * run at gigabit with half duplex.
+	 */
+	tw32(MAC_TX_LENGTHS,
+	     (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+	     (6 << TX_LENGTHS_IPG_SHIFT) |
+	     (32 << TX_LENGTHS_SLOT_TIME_SHIFT));
+
+	/* Receive rules. */
+	tw32(MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS);
+	tw32(RCVLPC_CONFIG, 0x0181);
+
+	/* Receive/send statistics. */
+	tw32(RCVLPC_STATS_ENABLE, 0xffffff);
+	tw32(RCVLPC_STATSCTRL, RCVLPC_STATSCTRL_ENABLE);
+	tw32(SNDDATAI_STATSENAB, 0xffffff);
+	tw32(SNDDATAI_STATSCTRL,
+	     (SNDDATAI_SCTRL_ENABLE |
+	      SNDDATAI_SCTRL_FASTUPD));
+
+	/* Setup host coalescing engine. */
+	tw32(HOSTCC_MODE, 0);
+	for (i = 0; i < 2000; i++) {
+		if (!(tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE))
+			break;
+		udelay(10);
+	}
+
+	tw32(HOSTCC_RXCOL_TICKS,
+	     tp->coalesce_config.rx_coalesce_ticks);
+	tw32(HOSTCC_RXMAX_FRAMES,
+	     tp->coalesce_config.rx_max_coalesced_frames);
+	tw32(HOSTCC_RXCOAL_TICK_INT,
+	     tp->coalesce_config.rx_coalesce_ticks_during_int);
+	tw32(HOSTCC_RXCOAL_MAXF_INT,
+	     tp->coalesce_config.rx_max_coalesced_frames_during_int);
+	tw32(HOSTCC_TXCOL_TICKS,
+	     tp->coalesce_config.tx_coalesce_ticks);
+	tw32(HOSTCC_TXMAX_FRAMES,
+	     tp->coalesce_config.tx_max_coalesced_frames);
+	tw32(HOSTCC_TXCOAL_TICK_INT,
+	     tp->coalesce_config.tx_coalesce_ticks_during_int);
+	tw32(HOSTCC_TXCOAL_MAXF_INT,
+	     tp->coalesce_config.tx_max_coalesced_frames_during_int);
+	tw32(HOSTCC_STAT_COAL_TICKS,
+	     tp->coalesce_config.stats_coalesce_ticks);
+
+	/* Status/statistics block address. */
+	tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
+	     ((u64) tp->stats_mapping >> 32));
+	tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
+	     ((u64) tp->stats_mapping & 0xffffffff));
+	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
+	     ((u64) tp->status_mapping >> 32));
+	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
+	     ((u64) tp->status_mapping & 0xffffffff));
+	tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK);
+	tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK);
+
+	tw32(HOSTCC_MODE, HOSTCC_MODE_ENABLE | tp->coalesce_mode);
+
+	tw32(RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE);
+	tw32(RCVLPC_MODE, RCVLPC_MODE_ENABLE);
+	tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE);
+
+	tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
+		MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
+	tw32(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
+
+	tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_GPIO_OE1 |
+		GRC_LCLCTRL_GPIO_OUTPUT1 | GRC_LCLCTRL_AUTO_SEEPROM;
+	tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
+
+	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
+
+	tw32(DMAC_MODE, DMAC_MODE_ENABLE);
+
+	tw32(WDMAC_MODE, (WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB |
+			  WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB |
+			  WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB |
+			  WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB |
+			  WDMAC_MODE_LNGREAD_ENAB));
+	tw32(RDMAC_MODE, (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB |
+			  RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB |
+			  RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
+			  RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
+			  RDMAC_MODE_LNGREAD_ENAB));
+
+	tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE);
+	tw32(MBFREE_MODE, MBFREE_MODE_ENABLE);
+	tw32(SNDDATAC_MODE, SNDDATAC_MODE_ENABLE);
+	tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE);
+	tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB);
+	tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ);
+	tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
+	tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE);
+	tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE);
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
+		err = tg3_load_5701_a0_firmware_fix(tp);
+		if (err)
+			return err;
+	}
+
+	tp->tx_mode = TX_MODE_ENABLE;
+	tw32(MAC_TX_MODE, tp->tx_mode);
+	tp->rx_mode = RX_MODE_ENABLE;
+	tw32(MAC_RX_MODE, tp->rx_mode);
+
+	if (tp->link_config.phy_is_low_power) {
+		tp->link_config.phy_is_low_power = 0;
+		tp->link_config.speed = tp->link_config.orig_speed;
+		tp->link_config.duplex = tp->link_config.orig_duplex;
+		tp->link_config.autoneg = tp->link_config.orig_autoneg;
+	}
+
+	tp->mi_mode = MAC_MI_MODE_BASE;
+	tw32(MAC_MI_MODE, tp->mi_mode);
+	tw32(MAC_LED_CTRL, 0);
+	tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
+	tw32(MAC_RX_MODE, RX_MODE_RESET);
+	udelay(10);
+	tw32(MAC_RX_MODE, tp->rx_mode);
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
+		tw32(MAC_SERDES_CFG, 0x616000);
+
+	err = tg3_setup_phy(tp);
+	if (err)
+		return err;
+
+	if (tp->phy_id != PHY_ID_SERDES) {
+		u32 tmp;
+
+		/* Clear CRC stats. */
+		tg3_readphy(tp, 0x1e, &tmp);
+		tg3_writephy(tp, 0x1e, tmp | 0x8000);
+		tg3_readphy(tp, 0x14, &tmp);
+	}
+
+	__tg3_set_rx_mode(tp->dev);
+
+	/* Initialize receive rules. */
+	tw32(MAC_RCV_RULE_0,  0xc2000000 & RCV_RULE_DISABLE_MASK);
+	tw32(MAC_RCV_VALUE_0, 0xffffffff & RCV_RULE_DISABLE_MASK);
+	tw32(MAC_RCV_RULE_1,  0x86000004 & RCV_RULE_DISABLE_MASK);
+	tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
+#if 0
+	tw32(MAC_RCV_RULE_2,  0); tw32(MAC_RCV_VALUE_2,  0);
+	tw32(MAC_RCV_RULE_3,  0); tw32(MAC_RCV_VALUE_3,  0);
+#endif
+	tw32(MAC_RCV_RULE_4,  0); tw32(MAC_RCV_VALUE_4,  0);
+	tw32(MAC_RCV_RULE_5,  0); tw32(MAC_RCV_VALUE_5,  0);
+	tw32(MAC_RCV_RULE_6,  0); tw32(MAC_RCV_VALUE_6,  0);
+	tw32(MAC_RCV_RULE_7,  0); tw32(MAC_RCV_VALUE_7,  0);
+	tw32(MAC_RCV_RULE_8,  0); tw32(MAC_RCV_VALUE_8,  0);
+	tw32(MAC_RCV_RULE_9,  0); tw32(MAC_RCV_VALUE_9,  0);
+	tw32(MAC_RCV_RULE_10,  0); tw32(MAC_RCV_VALUE_10,  0);
+	tw32(MAC_RCV_RULE_11,  0); tw32(MAC_RCV_VALUE_11,  0);
+	tw32(MAC_RCV_RULE_12,  0); tw32(MAC_RCV_VALUE_12,  0);
+	tw32(MAC_RCV_RULE_13,  0); tw32(MAC_RCV_VALUE_13,  0);
+	tw32(MAC_RCV_RULE_14,  0); tw32(MAC_RCV_VALUE_14,  0);
+	tw32(MAC_RCV_RULE_15,  0); tw32(MAC_RCV_VALUE_15,  0);
+
+	if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
+		tg3_enable_ints(tp);
+
+	return 0;
+}
+
+/* Called at device open time to get the chip ready for
+ * packet processing.  Invoked with tp->lock held.
+ */
+static int tg3_init_hw(struct tg3 *tp)
+{
+	int err;
+
+	/* Force the chip into D0. */
+	err = tg3_set_power_state(tp, 0);
+	if (err)
+		goto out;
+
+	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
+
+	err = tg3_reset_hw(tp);
+
+out:
+	return err;
+}
+
+static void tg3_timer(unsigned long __opaque)
+{
+	struct tg3 *tp = (struct tg3 *) __opaque;
+
+	spin_lock_irq(&tp->lock);
+
+	if (!(tp->tg3_flags & TG3_FLAG_TAGGED_IRQ_STATUS)) {
+		/* All of this garbage is because on the 5700 the
+		 * mailbox/status_block protocol the chip uses with
+		 * the cpu is race prone.
+		 */
+		if (tp->hw_status->status & SD_STATUS_UPDATED) {
+			tw32(GRC_LOCAL_CTRL,
+			     tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+		} else {
+			tw32(HOSTCC_MODE,
+			     (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
+		}
+
+		if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
+			tg3_halt(tp);
+			tg3_init_rings(tp);
+			tg3_init_hw(tp);
+		}
+	}
+
+	/* This part only runs once per second. */
+	if (!--tp->timer_counter) {
+		if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
+			u32 mac_stat;
+			int phy_event;
+
+			mac_stat = tr32(MAC_STATUS);
+
+			phy_event = 0;
+			if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) {
+				if (mac_stat & MAC_STATUS_MI_INTERRUPT)
+					phy_event = 1;
+			} else if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)
+				phy_event = 1;
+
+			if (phy_event)
+				tg3_setup_phy(tp);
+		} else if (tp->tg3_flags & TG3_FLAG_POLL_SERDES) {
+			u32 mac_stat = tr32(MAC_STATUS);
+			int need_setup = 0;
+
+			if (netif_carrier_ok(tp->dev) &&
+			    (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)) {
+				need_setup = 1;
+			}
+			if (! netif_carrier_ok(tp->dev) &&
+			    (mac_stat & MAC_STATUS_PCS_SYNCED)) {
+				need_setup = 1;
+			}
+			if (need_setup) {
+				tw32(MAC_MODE,
+				     (tp->mac_mode &
+				      ~MAC_MODE_PORT_MODE_MASK));
+				udelay(40);
+				tw32(MAC_MODE, tp->mac_mode);
+				tg3_setup_phy(tp);
+			}
+		}
+
+		tp->timer_counter = tp->timer_multiplier;
+	}
+
+	spin_unlock_irq(&tp->lock);
+
+	tp->timer.expires = jiffies + tp->timer_offset;
+	add_timer(&tp->timer);
+}
+
+static int tg3_open(struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+	int err;
+
+	spin_lock_irq(&tp->lock);
+
+	tg3_disable_ints(tp);
+	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+
+	spin_unlock_irq(&tp->lock);
+
+	/* If you move this call, make sure TG3_FLAG_HOST_TXDS in
+	 * tp->tg3_flags is accurate at that new place.
+	 */
+	err = tg3_alloc_consistent(tp);
+	if (err)
+		return err;
+
+	if (tp->tg3_flags & TG3_FLAG_TAGGED_IRQ_STATUS)
+		err = request_irq(dev->irq, tg3_interrupt_tagged,
+				  SA_SHIRQ, dev->name, dev);
+	else
+		err = request_irq(dev->irq, tg3_interrupt,
+				  SA_SHIRQ, dev->name, dev);
+
+	if (err) {
+		tg3_free_consistent(tp);
+		return err;
+	}
+
+	spin_lock_irq(&tp->lock);
+
+	tg3_init_rings(tp);
+
+	err = tg3_init_hw(tp);
+	if (err) {
+		tg3_halt(tp);
+		tg3_free_rings(tp);
+	} else {
+		if (tp->tg3_flags & TG3_FLAG_TAGGED_IRQ_STATUS) {
+			tp->timer_offset = HZ;
+			tp->timer_counter = tp->timer_multiplier = 1;
+		} else {
+			tp->timer_offset = HZ / 10;
+			tp->timer_counter = tp->timer_multiplier = 10;
+		}
+
+		init_timer(&tp->timer);
+		tp->timer.expires = jiffies + tp->timer_offset;
+		tp->timer.data = (unsigned long) tp;
+		tp->timer.function = tg3_timer;
+		add_timer(&tp->timer);
+
+		tp->last_rate_sample = jiffies;
+		tp->last_rx_count = 0;
+		tp->last_tx_count = 0;
+
+		tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+	}
+
+	spin_unlock_irq(&tp->lock);
+
+	if (err) {
+		free_irq(dev->irq, dev);
+		tg3_free_consistent(tp);
+		return err;
+	}
+
+	netif_start_queue(dev);
+
+	spin_lock_irq(&tp->lock);
+
+	tg3_enable_ints(tp);
+
+	spin_unlock_irq(&tp->lock);
+
+	return 0;
+}
+
+#if 0
+/*static*/ void tg3_dump_state(struct tg3 *tp)
+{
+	u32 val32, val32_2, val32_3, val32_4, val32_5;
+	u16 val16;
+	int i;
+
+	pci_read_config_word(tp->pdev, PCI_STATUS, &val16);
+	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, &val32);
+	printk("DEBUG: PCI status [%04x] TG3PCI state[%08x]\n",
+	       val16, val32);
+
+	/* MAC block */
+	printk("DEBUG: MAC_MODE[%08x] MAC_STATUS[%08x]\n",
+	       tr32(MAC_MODE), tr32(MAC_STATUS));
+	printk("       MAC_EVENT[%08x] MAC_LED_CTRL[%08x]\n",
+	       tr32(MAC_EVENT), tr32(MAC_LED_CTRL));
+	printk("DEBUG: MAC_TX_MODE[%08x] MAC_TX_STATUS[%08x]\n",
+	       tr32(MAC_TX_MODE), tr32(MAC_TX_STATUS));
+	printk("       MAC_RX_MODE[%08x] MAC_RX_STATUS[%08x]\n",
+	       tr32(MAC_RX_MODE), tr32(MAC_RX_STATUS));
+
+	/* Send data initiator control block */
+	printk("DEBUG: SNDDATAI_MODE[%08x] SNDDATAI_STATUS[%08x]\n",
+	       tr32(SNDDATAI_MODE), tr32(SNDDATAI_STATUS));
+	printk("       SNDDATAI_STATSCTRL[%08x]\n",
+	       tr32(SNDDATAI_STATSCTRL));
+
+	/* Send data completion control block */
+	printk("DEBUG: SNDDATAC_MODE[%08x]\n", tr32(SNDDATAC_MODE));
+
+	/* Send BD ring selector block */
+	printk("DEBUG: SNDBDS_MODE[%08x] SNDBDS_STATUS[%08x]\n",
+	       tr32(SNDBDS_MODE), tr32(SNDBDS_STATUS));
+
+	/* Send BD initiator control block */
+	printk("DEBUG: SNDBDI_MODE[%08x] SNDBDI_STATUS[%08x]\n",
+	       tr32(SNDBDI_MODE), tr32(SNDBDI_STATUS));
+
+	/* Send BD completion control block */
+	printk("DEBUG: SNDBDC_MODE[%08x]\n", tr32(SNDBDC_MODE));
+
+	/* Receive list placement control block */
+	printk("DEBUG: RCVLPC_MODE[%08x] RCVLPC_STATUS[%08x]\n",
+	       tr32(RCVLPC_MODE), tr32(RCVLPC_STATUS));
+	printk("       RCVLPC_STATSCTRL[%08x]\n",
+	       tr32(RCVLPC_STATSCTRL));
+
+	/* Receive data and receive BD initiator control block */
+	printk("DEBUG: RCVDBDI_MODE[%08x] RCVDBDI_STATUS[%08x]\n",
+	       tr32(RCVDBDI_MODE), tr32(RCVDBDI_STATUS));
+
+	/* Receive data completion control block */
+	printk("DEBUG: RCVDCC_MODE[%08x]\n",
+	       tr32(RCVDCC_MODE));
+
+	/* Receive BD initiator control block */
+	printk("DEBUG: RCVBDI_MODE[%08x] RCVBDI_STATUS[%08x]\n",
+	       tr32(RCVBDI_MODE), tr32(RCVBDI_STATUS));
+
+	/* Receive BD completion control block */
+	printk("DEBUG: RCVCC_MODE[%08x] RCVCC_STATUS[%08x]\n",
+	       tr32(RCVCC_MODE), tr32(RCVCC_STATUS));
+
+	/* Receive list selector control block */
+	printk("DEBUG: RCVLSC_MODE[%08x] RCVLSC_STATUS[%08x]\n",
+	       tr32(RCVLSC_MODE), tr32(RCVLSC_STATUS));
+
+	/* Mbuf cluster free block */
+	printk("DEBUG: MBFREE_MODE[%08x] MBFREE_STATUS[%08x]\n",
+	       tr32(MBFREE_MODE), tr32(MBFREE_STATUS));
+
+	/* Host coalescing control block */
+	printk("DEBUG: HOSTCC_MODE[%08x] HOSTCC_STATUS[%08x]\n",
+	       tr32(HOSTCC_MODE), tr32(HOSTCC_STATUS));
+	printk("DEBUG: HOSTCC_STATS_BLK_HOST_ADDR[%08x%08x]\n",
+	       tr32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH),
+	       tr32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW));
+	printk("DEBUG: HOSTCC_STATUS_BLK_HOST_ADDR[%08x%08x]\n",
+	       tr32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH),
+	       tr32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW));
+	printk("DEBUG: HOSTCC_STATS_BLK_NIC_ADDR[%08x]\n",
+	       tr32(HOSTCC_STATS_BLK_NIC_ADDR));
+	printk("DEBUG: HOSTCC_STATUS_BLK_NIC_ADDR[%08x]\n",
+	       tr32(HOSTCC_STATUS_BLK_NIC_ADDR));
+
+	/* Memory arbiter control block */
+	printk("DEBUG: MEMARB_MODE[%08x] MEMARB_STATUS[%08x]\n",
+	       tr32(MEMARB_MODE), tr32(MEMARB_STATUS));
+
+	/* Buffer manager control block */
+	printk("DEBUG: BUFMGR_MODE[%08x] BUFMGR_STATUS[%08x]\n",
+	       tr32(BUFMGR_MODE), tr32(BUFMGR_STATUS));
+	printk("DEBUG: BUFMGR_MB_POOL_ADDR[%08x] BUFMGR_MB_POOL_SIZE[%08x]\n",
+	       tr32(BUFMGR_MB_POOL_ADDR), tr32(BUFMGR_MB_POOL_SIZE));
+	printk("DEBUG: BUFMGR_DMA_DESC_POOL_ADDR[%08x] "
+	       "BUFMGR_DMA_DESC_POOL_SIZE[%08x]\n",
+	       tr32(BUFMGR_DMA_DESC_POOL_ADDR),
+	       tr32(BUFMGR_DMA_DESC_POOL_SIZE));
+
+	/* Read DMA control block */
+	printk("DEBUG: RDMAC_MODE[%08x] RDMAC_STATUS[%08x]\n",
+	       tr32(RDMAC_MODE), tr32(RDMAC_STATUS));
+
+	/* Write DMA control block */
+	printk("DEBUG: WDMAC_MODE[%08x] WDMAC_STATUS[%08x]\n",
+	       tr32(WDMAC_MODE), tr32(WDMAC_STATUS));
+
+	/* DMA completion block */
+	printk("DEBUG: DMAC_MODE[%08x]\n",
+	       tr32(DMAC_MODE));
+
+	/* GRC block */
+	printk("DEBUG: GRC_MODE[%08x] GRC_MISC_CFG[%08x]\n",
+	       tr32(GRC_MODE), tr32(GRC_MISC_CFG));
+	printk("DEBUG: GRC_LOCAL_CTRL[%08x]\n",
+	       tr32(GRC_LOCAL_CTRL));
+
+	/* TG3_BDINFOs */
+	printk("DEBUG: RCVDBDI_JUMBO_BD[%08x%08x:%08x:%08x]\n",
+	       tr32(RCVDBDI_JUMBO_BD + 0x0),
+	       tr32(RCVDBDI_JUMBO_BD + 0x4),
+	       tr32(RCVDBDI_JUMBO_BD + 0x8),
+	       tr32(RCVDBDI_JUMBO_BD + 0xc));
+	printk("DEBUG: RCVDBDI_STD_BD[%08x%08x:%08x:%08x]\n",
+	       tr32(RCVDBDI_STD_BD + 0x0),
+	       tr32(RCVDBDI_STD_BD + 0x4),
+	       tr32(RCVDBDI_STD_BD + 0x8),
+	       tr32(RCVDBDI_STD_BD + 0xc));
+	printk("DEBUG: RCVDBDI_MINI_BD[%08x%08x:%08x:%08x]\n",
+	       tr32(RCVDBDI_MINI_BD + 0x0),
+	       tr32(RCVDBDI_MINI_BD + 0x4),
+	       tr32(RCVDBDI_MINI_BD + 0x8),
+	       tr32(RCVDBDI_MINI_BD + 0xc));
+
+	tg3_read_mem(tp, NIC_SRAM_SEND_RCB + 0x0, &val32);
+	tg3_read_mem(tp, NIC_SRAM_SEND_RCB + 0x4, &val32_2);
+	tg3_read_mem(tp, NIC_SRAM_SEND_RCB + 0x8, &val32_3);
+	tg3_read_mem(tp, NIC_SRAM_SEND_RCB + 0xc, &val32_4);
+	printk("DEBUG: SRAM_SEND_RCB_0[%08x%08x:%08x:%08x]\n",
+	       val32, val32_2, val32_3, val32_4);
+
+	tg3_read_mem(tp, NIC_SRAM_RCV_RET_RCB + 0x0, &val32);
+	tg3_read_mem(tp, NIC_SRAM_RCV_RET_RCB + 0x4, &val32_2);
+	tg3_read_mem(tp, NIC_SRAM_RCV_RET_RCB + 0x8, &val32_3);
+	tg3_read_mem(tp, NIC_SRAM_RCV_RET_RCB + 0xc, &val32_4);
+	printk("DEBUG: SRAM_RCV_RET_RCB_0[%08x%08x:%08x:%08x]\n",
+	       val32, val32_2, val32_3, val32_4);
+
+	tg3_read_mem(tp, NIC_SRAM_STATUS_BLK + 0x0, &val32);
+	tg3_read_mem(tp, NIC_SRAM_STATUS_BLK + 0x4, &val32_2);
+	tg3_read_mem(tp, NIC_SRAM_STATUS_BLK + 0x8, &val32_3);
+	tg3_read_mem(tp, NIC_SRAM_STATUS_BLK + 0xc, &val32_4);
+	tg3_read_mem(tp, NIC_SRAM_STATUS_BLK + 0x10, &val32_5);
+	printk("DEBUG: SRAM_STATUS_BLK[%08x:%08x:%08x:%08x:%08x]\n",
+	       val32, val32_2, val32_3, val32_4, val32_5);
+
+	/* SW status block */
+	printk("DEBUG: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
+	       tp->hw_status->status,
+	       tp->hw_status->status_tag,
+	       tp->hw_status->rx_jumbo_consumer,
+	       tp->hw_status->rx_consumer,
+	       tp->hw_status->rx_mini_consumer,
+	       tp->hw_status->idx[0].rx_producer,
+	       tp->hw_status->idx[0].tx_consumer);
+
+	/* SW statistics block */
+	printk("DEBUG: Host statistics block [%08x:%08x:%08x:%08x]\n",
+	       ((u32 *)tp->hw_stats)[0],
+	       ((u32 *)tp->hw_stats)[1],
+	       ((u32 *)tp->hw_stats)[2],
+	       ((u32 *)tp->hw_stats)[3]);
+
+	/* Mailboxes */
+	printk("DEBUG: SNDHOST_PROD[%08x%08x] SNDNIC_PROD[%08x%08x]\n",
+	       tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0),
+	       tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4),
+	       tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0),
+	       tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4));
+
+	/* NIC side send descriptors. */
+	for (i = 0; i < 6; i++) {
+		unsigned long txd;
+
+		txd = tp->regs + NIC_SRAM_WIN_BASE + NIC_SRAM_TX_BUFFER_DESC
+			+ (i * sizeof(struct tg3_tx_buffer_desc));
+		printk("DEBUG: NIC TXD(%d)[%08x:%08x:%08x:%08x]\n",
+		       i,
+		       readl(txd + 0x0), readl(txd + 0x4),
+		       readl(txd + 0x8), readl(txd + 0xc));
+	}
+
+	/* NIC side RX descriptors. */
+	for (i = 0; i < 6; i++) {
+		unsigned long rxd;
+
+		rxd = tp->regs + NIC_SRAM_WIN_BASE + NIC_SRAM_RX_BUFFER_DESC
+			+ (i * sizeof(struct tg3_rx_buffer_desc));
+		printk("DEBUG: NIC RXD_STD(%d)[0][%08x:%08x:%08x:%08x]\n",
+		       i,
+		       readl(rxd + 0x0), readl(rxd + 0x4),
+		       readl(rxd + 0x8), readl(rxd + 0xc));
+		rxd += (4 * sizeof(u32));
+		printk("DEBUG: NIC RXD_STD(%d)[1][%08x:%08x:%08x:%08x]\n",
+		       i,
+		       readl(rxd + 0x0), readl(rxd + 0x4),
+		       readl(rxd + 0x8), readl(rxd + 0xc));
+	}
+#if TG3_MINI_RING_WORKS
+	for (i = 0; i < 6; i++) {
+		unsigned long rxd;
+
+		rxd = tp->regs + NIC_SRAM_WIN_BASE + NIC_SRAM_RX_MINI_BUFFER_DESC
+			+ (i * sizeof(struct tg3_rx_buffer_desc));
+		printk("DEBUG: NIC RXD_MINI(%d)[0][%08x:%08x:%08x:%08x]\n",
+		       i,
+		       readl(rxd + 0x0), readl(rxd + 0x4),
+		       readl(rxd + 0x8), readl(rxd + 0xc));
+		rxd += (4 * sizeof(u32));
+		printk("DEBUG: NIC RXD_MINI(%d)[1][%08x:%08x:%08x:%08x]\n",
+		       i,
+		       readl(rxd + 0x0), readl(rxd + 0x4),
+		       readl(rxd + 0x8), readl(rxd + 0xc));
+	}
+#endif
+
+	for (i = 0; i < 6; i++) {
+		unsigned long rxd;
+
+		rxd = tp->regs + NIC_SRAM_WIN_BASE + NIC_SRAM_RX_JUMBO_BUFFER_DESC
+			+ (i * sizeof(struct tg3_rx_buffer_desc));
+		printk("DEBUG: NIC RXD_JUMBO(%d)[0][%08x:%08x:%08x:%08x]\n",
+		       i,
+		       readl(rxd + 0x0), readl(rxd + 0x4),
+		       readl(rxd + 0x8), readl(rxd + 0xc));
+		rxd += (4 * sizeof(u32));
+		printk("DEBUG: NIC RXD_JUMBO(%d)[1][%08x:%08x:%08x:%08x]\n",
+		       i,
+		       readl(rxd + 0x0), readl(rxd + 0x4),
+		       readl(rxd + 0x8), readl(rxd + 0xc));
+	}
+}
+#endif
+
+static struct net_device_stats *tg3_get_stats(struct net_device *);
+
+static int tg3_close(struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+
+	netif_stop_queue(dev);
+
+	del_timer_sync(&tp->timer);
+
+	spin_lock_irq(&tp->lock);
+#if 0
+	tg3_dump_state(tp);
+#endif
+
+	tg3_disable_ints(tp);
+
+	tg3_halt(tp);
+	tg3_free_rings(tp);
+	tp->tg3_flags &=
+		~(TG3_FLAG_INIT_COMPLETE |
+		  TG3_FLAG_GOT_SERDES_FLOWCTL);
+	netif_carrier_off(tp->dev);
+
+	spin_unlock_irq(&tp->lock);
+
+	free_irq(dev->irq, dev);
+
+	memcpy(&tp->net_stats_prev, tg3_get_stats(tp->dev),
+	       sizeof(tp->net_stats_prev));
+
+	tg3_free_consistent(tp);
+
+	return 0;
+}
+
+static inline unsigned long get_stat64(tg3_stat64_t *val)
+{
+	unsigned long ret;
+
+#if (BITS_PER_LONG == 32)
+	if (val->high != 0)
+		ret = ~0UL;
+	else
+		ret = val->low;
+#else
+	ret = ((u64)val->high << 32) | ((u64)val->low);
+#endif
+	return ret;
+}
+
+static unsigned long calc_crc_errors(struct tg3 *tp)
+{
+	struct tg3_hw_stats *hw_stats = tp->hw_stats;
+
+	if (tp->phy_id != PHY_ID_SERDES &&
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
+		unsigned long flags;
+		u32 val;
+
+		spin_lock_irqsave(&tp->lock, flags);
+		tg3_readphy(tp, 0x1e, &val);
+		tg3_writephy(tp, 0x1e, val | 0x8000);
+		tg3_readphy(tp, 0x14, &val);
+		spin_unlock_irqrestore(&tp->lock, flags);
+
+		tp->phy_crc_errors += val;
+
+		return tp->phy_crc_errors;
+	}
+
+	return get_stat64(&hw_stats->rx_fcs_errors);
+}
+
+static struct net_device_stats *tg3_get_stats(struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+	struct net_device_stats *stats = &tp->net_stats;
+	struct net_device_stats *old_stats = &tp->net_stats_prev;
+	struct tg3_hw_stats *hw_stats = tp->hw_stats;
+
+	if (!hw_stats)
+		return old_stats;
+
+	stats->rx_packets = old_stats->rx_packets +
+		get_stat64(&hw_stats->rx_ucast_packets) +
+		get_stat64(&hw_stats->rx_mcast_packets) +
+		get_stat64(&hw_stats->rx_bcast_packets);
+		
+	stats->tx_packets = old_stats->tx_packets +
+		get_stat64(&hw_stats->COS_out_packets[0]);
+
+	stats->rx_bytes = old_stats->rx_bytes +
+		get_stat64(&hw_stats->rx_octets);
+	stats->tx_bytes = old_stats->tx_bytes +
+		get_stat64(&hw_stats->tx_octets);
+
+	stats->rx_errors = old_stats->rx_errors +
+		get_stat64(&hw_stats->rx_errors);
+	stats->tx_errors = old_stats->tx_errors +
+		get_stat64(&hw_stats->tx_errors) +
+		get_stat64(&hw_stats->tx_mac_errors) +
+		get_stat64(&hw_stats->tx_carrier_sense_errors) +
+		get_stat64(&hw_stats->tx_discards);
+
+	stats->multicast = old_stats->multicast +
+		get_stat64(&hw_stats->rx_mcast_packets);
+	stats->collisions = old_stats->collisions +
+		get_stat64(&hw_stats->tx_collisions);
+
+	stats->rx_length_errors = old_stats->rx_length_errors +
+		get_stat64(&hw_stats->rx_frame_too_long_errors) +
+		get_stat64(&hw_stats->rx_undersize_packets);
+
+	stats->rx_over_errors = old_stats->rx_over_errors +
+		get_stat64(&hw_stats->rxbds_empty);
+	stats->rx_frame_errors = old_stats->rx_frame_errors +
+		get_stat64(&hw_stats->rx_align_errors);
+	stats->tx_aborted_errors = old_stats->tx_aborted_errors +
+		get_stat64(&hw_stats->tx_discards);
+	stats->tx_carrier_errors = old_stats->tx_carrier_errors +
+		get_stat64(&hw_stats->tx_carrier_sense_errors);
+
+	stats->rx_crc_errors = old_stats->rx_crc_errors +
+		calc_crc_errors(tp);
+
+	return stats;
+}
+
+static inline u32 calc_crc(unsigned char *buf, int len)
+{
+	u32 reg;
+	u32 tmp;
+	int j, k;
+
+	reg = 0xffffffff;
+
+	for (j = 0; j < len; j++) {
+		reg ^= buf[j];
+
+		for (k = 0; k < 8; k++) {
+			tmp = reg & 0x01;
+
+			reg >>= 1;
+
+			if (tmp) {
+				reg ^= 0xedb88320;
+			}
+		}
+	}
+
+	return ~reg;
+}
+
+static void tg3_set_multi(struct tg3 *tp, unsigned int accept_all)
+{
+	/* accept or reject all multicast frames */
+	tw32 (MAC_HASH_REG_0, accept_all ? 0xffffffff : 0);
+	tw32 (MAC_HASH_REG_1, accept_all ? 0xffffffff : 0);
+	tw32 (MAC_HASH_REG_2, accept_all ? 0xffffffff : 0);
+	tw32 (MAC_HASH_REG_3, accept_all ? 0xffffffff : 0);
+}
+
+static void __tg3_set_rx_mode(struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+	u32 rx_mode;
+
+	rx_mode = tp->rx_mode & ~RX_MODE_PROMISC;
+
+	if (dev->flags & IFF_PROMISC) {
+		/* Promiscuous mode. */
+		rx_mode |= RX_MODE_PROMISC;
+	} else if (dev->flags & IFF_ALLMULTI) {
+		/* Accept all multicast. */
+		tg3_set_multi (tp, 1);
+	} else if (dev->mc_count < 1) {
+		/* Reject all multicast. */
+		tg3_set_multi (tp, 0);
+	} else {
+		/* Accept one or more multicast(s). */
+		struct dev_mc_list *mclist;
+		unsigned int i;
+		u32 mc_filter[4] = { 0, };
+		u32 regidx;
+		u32 bit;
+		u32 crc;
+
+		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+		     i++, mclist = mclist->next) {
+
+			crc = calc_crc (mclist->dmi_addr, ETH_ALEN);
+			bit = ~crc & 0x7f;
+			regidx = (bit & 0x60) >> 5;
+			bit &= 0x1f;
+			mc_filter[regidx] |= (1 << bit);
+		}
+
+		tw32 (MAC_HASH_REG_0, mc_filter[0]);
+		tw32 (MAC_HASH_REG_1, mc_filter[1]);
+		tw32 (MAC_HASH_REG_2, mc_filter[2]);
+		tw32 (MAC_HASH_REG_3, mc_filter[3]);
+	}
+
+	if (rx_mode != tp->rx_mode) {
+		tp->rx_mode = rx_mode;
+		tw32 (MAC_RX_MODE, rx_mode);
+	}
+}
+
+static void tg3_set_rx_mode(struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+
+	spin_lock_irq(&tp->lock);
+	__tg3_set_rx_mode(dev);
+	spin_unlock_irq(&tp->lock);
+}
+
+#define TG3_REGDUMP_LEN		(32 * 1024)
+
+static u8 *tg3_get_regs(struct tg3 *tp)
+{
+	u8 *orig_p = kmalloc(TG3_REGDUMP_LEN, GFP_KERNEL);
+	u8 *p;
+	int i;
+
+	if (orig_p == NULL)
+		return NULL;
+
+	memset(orig_p, 0, TG3_REGDUMP_LEN);
+
+	spin_lock_irq(&tp->lock);
+
+#define __GET_REG32(reg)	(*((u32 *)(p))++ = tr32(reg))
+#define GET_REG32_LOOP(base,len)		\
+do {	p = orig_p + (base);			\
+	for (i = 0; i < len; i += 4)		\
+		__GET_REG32((base) + i);	\
+} while (0)
+#define GET_REG32_1(reg)	\
+do {	p = orig_p + (reg);	\
+	__GET_REG32((reg));	\
+} while (0)
+
+	GET_REG32_LOOP(TG3PCI_VENDOR, 0xb0);
+	GET_REG32_LOOP(MAILBOX_INTERRUPT_0, 0x200);
+	GET_REG32_LOOP(MAC_MODE, 0x4f0);
+	GET_REG32_LOOP(SNDDATAI_MODE, 0xe0);
+	GET_REG32_1(SNDDATAC_MODE);
+	GET_REG32_LOOP(SNDBDS_MODE, 0x80);
+	GET_REG32_LOOP(SNDBDI_MODE, 0x48);
+	GET_REG32_1(SNDBDC_MODE);
+	GET_REG32_LOOP(RCVLPC_MODE, 0x20);
+	GET_REG32_LOOP(RCVLPC_SELLST_BASE, 0x15c);
+	GET_REG32_LOOP(RCVDBDI_MODE, 0x0c);
+	GET_REG32_LOOP(RCVDBDI_JUMBO_BD, 0x3c);
+	GET_REG32_LOOP(RCVDBDI_BD_PROD_IDX_0, 0x44);
+	GET_REG32_1(RCVDCC_MODE);
+	GET_REG32_LOOP(RCVBDI_MODE, 0x20);
+	GET_REG32_LOOP(RCVCC_MODE, 0x14);
+	GET_REG32_LOOP(RCVLSC_MODE, 0x08);
+	GET_REG32_1(MBFREE_MODE);
+	GET_REG32_LOOP(HOSTCC_MODE, 0x100);
+	GET_REG32_LOOP(MEMARB_MODE, 0x10);
+	GET_REG32_LOOP(BUFMGR_MODE, 0x58);
+	GET_REG32_LOOP(RDMAC_MODE, 0x08);
+	GET_REG32_LOOP(WDMAC_MODE, 0x08);
+	GET_REG32_LOOP(RX_CPU_BASE, 0x280);
+	GET_REG32_LOOP(TX_CPU_BASE, 0x280);
+	GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110);
+	GET_REG32_LOOP(FTQ_RESET, 0x120);
+	GET_REG32_LOOP(MSGINT_MODE, 0x0c);
+	GET_REG32_1(DMAC_MODE);
+	GET_REG32_LOOP(GRC_MODE, 0x4c);
+	GET_REG32_LOOP(NVRAM_CMD, 0x24);
+
+#undef __GET_REG32
+#undef GET_REG32_LOOP
+#undef GET_REG32_1
+
+	spin_unlock_irq(&tp->lock);
+
+	return orig_p;
+}
+
+static void tg3_to_ethtool_coal(struct tg3 *tp,
+				struct ethtool_coalesce *ecoal)
+{
+	ecoal->rx_coalesce_usecs =
+		tp->coalesce_config.rx_coalesce_ticks_def;
+	ecoal->rx_max_coalesced_frames =
+		tp->coalesce_config.rx_max_coalesced_frames_def;
+	ecoal->rx_coalesce_usecs_irq =
+		tp->coalesce_config.rx_coalesce_ticks_during_int_def;
+	ecoal->rx_max_coalesced_frames_irq =
+		tp->coalesce_config.rx_max_coalesced_frames_during_int_def;
+
+	ecoal->tx_coalesce_usecs =
+		tp->coalesce_config.tx_coalesce_ticks_def;
+	ecoal->tx_max_coalesced_frames =
+		tp->coalesce_config.tx_max_coalesced_frames_def;
+	ecoal->tx_coalesce_usecs_irq =
+		tp->coalesce_config.tx_coalesce_ticks_during_int_def;
+	ecoal->tx_max_coalesced_frames_irq =
+		tp->coalesce_config.tx_max_coalesced_frames_during_int_def;
+
+	ecoal->stats_block_coalesce_usecs =
+		tp->coalesce_config.stats_coalesce_ticks_def;
+
+	ecoal->use_adaptive_rx_coalesce =
+		(tp->tg3_flags & TG3_FLAG_ADAPTIVE_RX) != 0;
+	ecoal->use_adaptive_tx_coalesce =
+		(tp->tg3_flags & TG3_FLAG_ADAPTIVE_TX) != 0;
+
+	ecoal->pkt_rate_low =
+		tp->coalesce_config.pkt_rate_low;
+	ecoal->rx_coalesce_usecs_low =
+		tp->coalesce_config.rx_coalesce_ticks_low;
+	ecoal->rx_max_coalesced_frames_low =
+		tp->coalesce_config.rx_max_coalesced_frames_low;
+	ecoal->tx_coalesce_usecs_low =
+		tp->coalesce_config.tx_coalesce_ticks_low;
+	ecoal->tx_max_coalesced_frames_low =
+		tp->coalesce_config.tx_max_coalesced_frames_low;
+
+	ecoal->pkt_rate_high =
+		tp->coalesce_config.pkt_rate_high;
+	ecoal->rx_coalesce_usecs_high =
+		tp->coalesce_config.rx_coalesce_ticks_high;
+	ecoal->rx_max_coalesced_frames_high =
+		tp->coalesce_config.rx_max_coalesced_frames_high;
+	ecoal->tx_coalesce_usecs_high =
+		tp->coalesce_config.tx_coalesce_ticks_high;
+	ecoal->tx_max_coalesced_frames_high =
+		tp->coalesce_config.tx_max_coalesced_frames_high;
+
+	ecoal->rate_sample_interval =
+		tp->coalesce_config.rate_sample_jiffies / HZ;
+}
+
+static int tg3_from_ethtool_coal(struct tg3 *tp,
+				 struct ethtool_coalesce *ecoal)
+{
+	/* Make sure we are not getting garbage. */
+	if ((ecoal->rx_coalesce_usecs == 0 &&
+	     ecoal->rx_max_coalesced_frames == 0) ||
+	    (ecoal->tx_coalesce_usecs == 0 &&
+	     ecoal->tx_max_coalesced_frames == 0) ||
+	    ecoal->stats_block_coalesce_usecs == 0)
+		return -EINVAL;
+	if (ecoal->use_adaptive_rx_coalesce ||
+	    ecoal->use_adaptive_tx_coalesce) {
+		if (ecoal->pkt_rate_low > ecoal->pkt_rate_high)
+			return -EINVAL;
+		if (ecoal->rate_sample_interval == 0)
+			return -EINVAL;
+		if (ecoal->use_adaptive_rx_coalesce &&
+		    ((ecoal->rx_coalesce_usecs_low == 0 &&
+		      ecoal->rx_max_coalesced_frames_low == 0) ||
+		     (ecoal->rx_coalesce_usecs_high == 0 &&
+		      ecoal->rx_max_coalesced_frames_high == 0)))
+			return -EINVAL;
+		if (ecoal->use_adaptive_tx_coalesce &&
+		    ((ecoal->tx_coalesce_usecs_low == 0 &&
+		      ecoal->tx_max_coalesced_frames_low == 0) ||
+		     (ecoal->tx_coalesce_usecs_high == 0 &&
+		      ecoal->tx_max_coalesced_frames_high == 0)))
+			return -EINVAL;
+	}
+
+	/* Looks good, let it rip. */
+	spin_lock_irq(&tp->lock);
+	tp->coalesce_config.rx_coalesce_ticks =
+		tp->coalesce_config.rx_coalesce_ticks_def =
+		ecoal->rx_coalesce_usecs;
+	tp->coalesce_config.rx_max_coalesced_frames =
+		tp->coalesce_config.rx_max_coalesced_frames_def =
+		ecoal->rx_max_coalesced_frames;
+	tp->coalesce_config.rx_coalesce_ticks_during_int =
+		tp->coalesce_config.rx_coalesce_ticks_during_int_def =
+		ecoal->rx_coalesce_usecs_irq;
+	tp->coalesce_config.rx_max_coalesced_frames_during_int =
+		tp->coalesce_config.rx_max_coalesced_frames_during_int_def =
+		ecoal->rx_max_coalesced_frames_irq;
+	tp->coalesce_config.tx_coalesce_ticks =
+		tp->coalesce_config.tx_coalesce_ticks_def =
+		ecoal->tx_coalesce_usecs;
+	tp->coalesce_config.tx_max_coalesced_frames =
+		tp->coalesce_config.tx_max_coalesced_frames_def =
+		ecoal->tx_max_coalesced_frames;
+	tp->coalesce_config.tx_coalesce_ticks_during_int =
+		tp->coalesce_config.tx_coalesce_ticks_during_int_def =
+		ecoal->tx_coalesce_usecs_irq;
+	tp->coalesce_config.tx_max_coalesced_frames_during_int =
+		tp->coalesce_config.tx_max_coalesced_frames_during_int_def =
+		ecoal->tx_max_coalesced_frames_irq;
+	tp->coalesce_config.stats_coalesce_ticks =
+		tp->coalesce_config.stats_coalesce_ticks_def =
+		ecoal->stats_block_coalesce_usecs;
+
+	if (ecoal->use_adaptive_rx_coalesce)
+		tp->tg3_flags |= TG3_FLAG_ADAPTIVE_RX;
+	else
+		tp->tg3_flags &= ~TG3_FLAG_ADAPTIVE_RX;
+	if (ecoal->use_adaptive_tx_coalesce)
+		tp->tg3_flags |= TG3_FLAG_ADAPTIVE_TX;
+	else
+		tp->tg3_flags &= ~TG3_FLAG_ADAPTIVE_TX;
+
+	tp->coalesce_config.pkt_rate_low = ecoal->pkt_rate_low;
+	tp->coalesce_config.pkt_rate_high = ecoal->pkt_rate_high;
+	tp->coalesce_config.rate_sample_jiffies =
+		ecoal->rate_sample_interval * HZ;
+
+	tp->coalesce_config.rx_coalesce_ticks_low =
+		ecoal->rx_coalesce_usecs_low;
+	tp->coalesce_config.rx_max_coalesced_frames_low =
+		ecoal->rx_max_coalesced_frames_low;
+	tp->coalesce_config.tx_coalesce_ticks_low =
+		ecoal->tx_coalesce_usecs_low;
+	tp->coalesce_config.tx_max_coalesced_frames_low =
+		ecoal->tx_max_coalesced_frames_low;
+
+	tp->coalesce_config.rx_coalesce_ticks_high =
+		ecoal->rx_coalesce_usecs_high;
+	tp->coalesce_config.rx_max_coalesced_frames_high =
+		ecoal->rx_max_coalesced_frames_high;
+	tp->coalesce_config.tx_coalesce_ticks_high =
+		ecoal->tx_coalesce_usecs_high;
+	tp->coalesce_config.tx_max_coalesced_frames_high =
+		ecoal->tx_max_coalesced_frames_high;
+
+	tw32(HOSTCC_RXCOL_TICKS,
+	     tp->coalesce_config.rx_coalesce_ticks_def);
+	tw32(HOSTCC_RXMAX_FRAMES,
+	     tp->coalesce_config.rx_max_coalesced_frames_def);
+	tw32(HOSTCC_RXCOAL_TICK_INT,
+	     tp->coalesce_config.rx_coalesce_ticks_during_int_def);
+	tw32(HOSTCC_RXCOAL_MAXF_INT,
+	     tp->coalesce_config.rx_max_coalesced_frames_during_int_def);
+	tw32(HOSTCC_TXCOL_TICKS,
+	     tp->coalesce_config.tx_coalesce_ticks_def);
+	tw32(HOSTCC_TXMAX_FRAMES,
+	     tp->coalesce_config.tx_max_coalesced_frames_def);
+	tw32(HOSTCC_TXCOAL_TICK_INT,
+	     tp->coalesce_config.tx_coalesce_ticks_during_int_def);
+	tw32(HOSTCC_TXCOAL_MAXF_INT,
+	     tp->coalesce_config.tx_max_coalesced_frames_during_int_def);
+	tw32(HOSTCC_STAT_COAL_TICKS,
+	     tp->coalesce_config.stats_coalesce_ticks_def);
+
+	spin_unlock_irq(&tp->lock);
+
+	return 0;
+}
+
+static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
+{
+	struct tg3 *tp = dev->priv;
+	struct pci_dev *pci_dev = tp->pdev;
+	u32 ethcmd;
+
+	if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
+		return -EFAULT;
+
+	switch (ethcmd) {
+	case ETHTOOL_GDRVINFO:{
+		struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+		strcpy (info.driver, DRV_MODULE_NAME);
+		strcpy (info.version, DRV_MODULE_VERSION);
+		memset(&info.fw_version, 0, sizeof(info.fw_version));
+		strcpy (info.bus_info, pci_dev->slot_name);
+		info.eedump_len = 0;
+		info.regdump_len = TG3_REGDUMP_LEN;
+		if (copy_to_user (useraddr, &info, sizeof (info)))
+			return -EFAULT;
+		return 0;
+	}
+
+	case ETHTOOL_GSET: {
+		struct ethtool_cmd cmd = { ETHTOOL_GSET };
+
+		if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) ||
+		    tp->link_config.phy_is_low_power)
+			return -EAGAIN;
+		cmd.supported = (SUPPORTED_Autoneg);
+
+		if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+			cmd.supported |= (SUPPORTED_1000baseT_Half |
+					  SUPPORTED_1000baseT_Full);
+
+		if (tp->phy_id != PHY_ID_SERDES)
+			cmd.supported |= (SUPPORTED_100baseT_Half |
+					  SUPPORTED_100baseT_Full |
+					  SUPPORTED_10baseT_Half |
+					  SUPPORTED_10baseT_Full |
+					  SUPPORTED_MII);
+		else
+			cmd.supported |= SUPPORTED_FIBRE;
+
+		cmd.advertising = tp->link_config.advertising;
+		cmd.speed = tp->link_config.active_speed;
+		cmd.duplex = tp->link_config.active_duplex;
+		cmd.port = 0;
+		cmd.phy_address = PHY_ADDR;
+		cmd.transceiver = 0;
+		cmd.autoneg = tp->link_config.autoneg;
+		cmd.maxtxpkt = tp->coalesce_config.tx_max_coalesced_frames_def;
+		cmd.maxrxpkt = tp->coalesce_config.rx_max_coalesced_frames_def;
+		if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SSET: {
+		struct ethtool_cmd cmd;
+
+		if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) ||
+		    tp->link_config.phy_is_low_power)
+			return -EAGAIN;
+
+		if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
+			return -EFAULT;
+
+		/* Fiber PHY only supports 1000 full/half */
+		if (cmd.autoneg == AUTONEG_ENABLE) {
+			if (tp->phy_id == PHY_ID_SERDES &&
+			    (cmd.advertising &
+			     (ADVERTISED_10baseT_Half |
+			      ADVERTISED_10baseT_Full |
+			      ADVERTISED_100baseT_Half |
+			      ADVERTISED_100baseT_Full)))
+				return -EINVAL;
+			if ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) &&
+			    (cmd.advertising &
+			     (ADVERTISED_1000baseT_Half |
+			      ADVERTISED_1000baseT_Full)))
+				return -EINVAL;
+		} else {
+			if (tp->phy_id == PHY_ID_SERDES &&
+			    (cmd.speed == SPEED_10 ||
+			     cmd.speed == SPEED_100))
+				return -EINVAL;
+			if ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) &&
+			    (cmd.speed == SPEED_10 ||
+			     cmd.speed == SPEED_100))
+				return -EINVAL;
+		}
+
+		spin_lock_irq(&tp->lock);
+
+		tp->link_config.autoneg = cmd.autoneg;
+		if (cmd.autoneg == AUTONEG_ENABLE) {
+			tp->link_config.advertising = cmd.advertising;
+			tp->link_config.speed = SPEED_INVALID;
+			tp->link_config.duplex = DUPLEX_INVALID;
+		} else {
+			tp->link_config.speed = cmd.speed;
+			tp->link_config.duplex = cmd.duplex;
+		}
+
+		if (cmd.maxtxpkt || cmd.maxrxpkt) {
+			tp->coalesce_config.tx_max_coalesced_frames_def =
+				tp->coalesce_config.tx_max_coalesced_frames =
+				cmd.maxtxpkt;
+			tp->coalesce_config.rx_max_coalesced_frames_def =
+				tp->coalesce_config.rx_max_coalesced_frames =
+				cmd.maxrxpkt;
+
+			/* Coalescing config bits can be updated without
+			 * a full chip reset.
+			 */
+			tw32(HOSTCC_TXMAX_FRAMES,
+			     tp->coalesce_config.tx_max_coalesced_frames);
+			tw32(HOSTCC_RXMAX_FRAMES,
+			     tp->coalesce_config.rx_max_coalesced_frames);
+		}
+		tg3_setup_phy(tp);
+		spin_unlock_irq(&tp->lock);
+
+		return 0;
+	}
+
+	case ETHTOOL_GREGS: {
+		struct ethtool_regs regs;
+		u8 *regbuf;
+		int ret;
+
+		if (copy_from_user(&regs, useraddr, sizeof(regs)))
+			return -EFAULT;
+		if (regs.len > TG3_REGDUMP_LEN)
+			regs.len = TG3_REGDUMP_LEN;
+		regs.version = 0;
+		if (copy_to_user(useraddr, &regs, sizeof(regs)))
+			return -EFAULT;
+
+		regbuf = tg3_get_regs(tp);
+		if (!regbuf)
+			return -ENOMEM;
+
+		useraddr += offsetof(struct ethtool_regs, data);
+		ret = 0;
+		if (copy_to_user(useraddr, regbuf, regs.len))
+			ret = -EFAULT;
+		kfree(regbuf);
+		return ret;
+	}
+	case ETHTOOL_GWOL: {
+		struct ethtool_wolinfo wol = { ETHTOOL_GWOL };
+
+		wol.supported = WAKE_MAGIC;
+		wol.wolopts = 0;
+		if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
+			wol.wolopts = WAKE_MAGIC;
+		memset(&wol.sopass, 0, sizeof(wol.sopass));
+		if (copy_to_user(useraddr, &wol, sizeof(wol)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SWOL: {
+		struct ethtool_wolinfo wol;
+
+		if (copy_from_user(&wol, useraddr, sizeof(wol)))
+			return -EFAULT;
+		if (wol.wolopts & ~WAKE_MAGIC)
+			return -EINVAL;
+		spin_lock_irq(&tp->lock);
+		if (wol.wolopts & WAKE_MAGIC)
+			tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
+		else
+			tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
+		spin_unlock_irq(&tp->lock);
+
+		return 0;
+	}
+	case ETHTOOL_GMSGLVL: {
+		struct ethtool_value edata = { ETHTOOL_GMSGLVL };
+		edata.data = tp->msg_enable;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SMSGLVL: {
+		struct ethtool_value edata;
+		if (copy_from_user(&edata, useraddr, sizeof(edata)))
+			return -EFAULT;
+		tp->msg_enable = edata.data;
+		return 0;
+	}
+	case ETHTOOL_NWAY_RST: {
+		u32 bmcr;
+		int r;
+
+		spin_lock_irq(&tp->lock);
+		tg3_readphy(tp, MII_BMCR, &bmcr);
+		tg3_readphy(tp, MII_BMCR, &bmcr);
+		r = -EINVAL;
+		if (bmcr & BMCR_ANENABLE) {
+			tg3_writephy(tp, MII_BMCR,
+				     bmcr | BMCR_ANRESTART);
+			r = 0;
+		}
+		spin_unlock_irq(&tp->lock);
+
+		return r;
+	}
+	case ETHTOOL_GLINK: {
+		struct ethtool_value edata = { ETHTOOL_GLINK };
+		edata.data = netif_carrier_ok(tp->dev) ? 1 : 0;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_GCOALESCE: {
+		struct ethtool_coalesce ecoal = { ETHTOOL_GCOALESCE };
+
+		tg3_to_ethtool_coal(tp, &ecoal);
+		if (copy_to_user(useraddr, &ecoal, sizeof(ecoal)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SCOALESCE: {
+		struct ethtool_coalesce ecoal;
+
+		if (copy_from_user(&ecoal, useraddr, sizeof(ecoal)))
+			return -EINVAL;
+
+		return tg3_from_ethtool_coal(tp, &ecoal);
+	}
+	case ETHTOOL_GRINGPARAM: {
+		struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM };
+
+		ering.rx_max_pending = TG3_RX_RING_SIZE - 1;
+#if TG3_MINI_RING_WORKS
+		ering.rx_mini_max_pending = TG3_RX_MINI_RING_SIZE - 1;
+#else
+		ering.rx_mini_max_pending = 0;
+#endif
+		ering.rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1;
+
+		ering.rx_pending = tp->rx_pending;
+#if TG3_MINI_RING_WORKS
+		ering.rx_mini_pending = tp->rx_mini_pending;
+#else
+		ering.rx_mini_pending = 0;
+#endif
+		ering.rx_jumbo_pending = tp->rx_jumbo_pending;
+		ering.tx_pending = tp->tx_pending;
+
+		if (copy_to_user(useraddr, &ering, sizeof(ering)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SRINGPARAM: {
+		struct ethtool_ringparam ering;
+
+		if (copy_from_user(&ering, useraddr, sizeof(ering)))
+			return -EFAULT;
+
+		if ((ering.rx_pending > TG3_RX_RING_SIZE - 1) ||
+#if TG3_MINI_RING_WORKS
+		    (ering.rx_mini_pending > TG3_RX_MINI_RING_SIZE - 1) ||
+#endif
+		    (ering.rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
+		    (ering.tx_pending > TG3_TX_RING_SIZE - 1))
+			return -EINVAL;
+
+		spin_lock_irq(&tp->lock);
+
+		tp->rx_pending = ering.rx_pending;
+#if TG3_MINI_RING_WORKS
+		tp->rx_mini_pending = ering.rx_mini_pending;
+#endif
+		tp->rx_jumbo_pending = ering.rx_jumbo_pending;
+		tp->tx_pending = ering.tx_pending;
+
+		tg3_halt(tp);
+		tg3_init_rings(tp);
+		tg3_init_hw(tp);
+		netif_wake_queue(tp->dev);
+		spin_unlock_irq(&tp->lock);
+
+		return 0;
+	}
+	case ETHTOOL_GPAUSEPARAM: {
+		struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
+
+		epause.autoneg =
+			(tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0;
+		epause.rx_pause =
+			(tp->tg3_flags & TG3_FLAG_PAUSE_RX) != 0;
+		epause.tx_pause =
+			(tp->tg3_flags & TG3_FLAG_PAUSE_TX) != 0;
+		if (copy_to_user(useraddr, &epause, sizeof(epause)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SPAUSEPARAM: {
+		struct ethtool_pauseparam epause;
+
+		if (copy_from_user(&epause, useraddr, sizeof(epause)))
+			return -EFAULT;
+
+		spin_lock_irq(&tp->lock);
+		if (epause.autoneg)
+			tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+		else
+			tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+		if (epause.rx_pause)
+			tp->tg3_flags |= TG3_FLAG_PAUSE_RX;
+		else
+			tp->tg3_flags &= ~TG3_FLAG_PAUSE_RX;
+		if (epause.tx_pause)
+			tp->tg3_flags |= TG3_FLAG_PAUSE_TX;
+		else
+			tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX;
+		tg3_halt(tp);
+		tg3_init_rings(tp);
+		tg3_init_hw(tp);
+		spin_unlock_irq(&tp->lock);
+
+		return 0;
+	}
+	case ETHTOOL_GRXCSUM: {
+		struct ethtool_value edata = { ETHTOOL_GRXCSUM };
+
+		edata.data =
+			(tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SRXCSUM: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, useraddr, sizeof(edata)))
+			return -EFAULT;
+
+		if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) {
+			if (edata.data != 0)
+				return -EINVAL;
+			return 0;
+		}
+
+		spin_lock_irq(&tp->lock);
+		if (edata.data)
+			tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
+		else
+			tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
+		spin_unlock_irq(&tp->lock);
+
+		return 0;
+	}
+	case ETHTOOL_GTXCSUM: {
+		struct ethtool_value edata = { ETHTOOL_GTXCSUM };
+
+		edata.data =
+			(tp->dev->features & NETIF_F_IP_CSUM) != 0;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_STXCSUM: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, useraddr, sizeof(edata)))
+			return -EFAULT;
+
+		if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) {
+			if (edata.data != 0)
+				return -EINVAL;
+			return 0;
+		}
+
+		if (edata.data)
+			tp->dev->features |= NETIF_F_IP_CSUM;
+		else
+			tp->dev->features &= ~NETIF_F_IP_CSUM;
+
+		return 0;
+	}
+	case ETHTOOL_GSG: {
+		struct ethtool_value edata = { ETHTOOL_GSG };
+
+		edata.data =
+			(tp->dev->features & NETIF_F_SG) != 0;
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SSG: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, useraddr, sizeof(edata)))
+			return -EFAULT;
+
+		if (edata.data)
+			tp->dev->features |= NETIF_F_SG;
+		else
+			tp->dev->features &= ~NETIF_F_SG;
+
+		return 0;
+	}
+	};
+
+	return -EOPNOTSUPP;
+}
+
+static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+	struct tg3 *tp = dev->priv;
+	int err;
+
+	switch(cmd) {
+	case SIOCETHTOOL:
+		return tg3_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+	case SIOCGMIIPHY:
+		data->phy_id = PHY_ADDR;
+
+		/* fallthru */
+	case SIOCGMIIREG: {
+		u32 mii_regval;
+
+		spin_lock_irq(&tp->lock);
+		err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
+		spin_unlock_irq(&tp->lock);
+
+		data->val_out = mii_regval;
+
+		return err;
+	}
+
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		spin_lock_irq(&tp->lock);
+		err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
+		spin_unlock_irq(&tp->lock);
+
+		return err;
+
+	default:
+		/* do nothing */
+		break;
+	}
+	return -EOPNOTSUPP;
+}
+
+#if TG3_VLAN_TAG_USED
+static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct tg3 *tp = dev->priv;
+
+	spin_lock_irq(&tp->lock);
+	tp->vlgrp = grp;
+	spin_unlock_irq(&tp->lock);
+}
+
+static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct tg3 *tp = dev->priv;
+
+	spin_lock_irq(&tp->lock);
+	if (tp->vlgrp)
+		tp->vlgrp->vlan_devices[vid] = NULL;
+	spin_unlock_irq(&tp->lock);
+}
+#endif
+
+/* Chips other than 5700/5701 use the NVRAM for fetching info. */
+static void __devinit tg3_nvram_init(struct tg3 *tp)
+{
+	int j;
+
+	tw32(GRC_EEPROM_ADDR,
+	     (EEPROM_ADDR_FSM_RESET |
+	      (EEPROM_DEFAULT_CLOCK_PERIOD <<
+	       EEPROM_ADDR_CLKPERD_SHIFT)));
+
+	/* XXX schedule_timeout() ... */
+	for (j = 0; j < 100; j++)
+		udelay(10);
+
+	/* Enable seeprom accesses. */
+	tw32(GRC_LOCAL_CTRL,
+	     tr32(GRC_LOCAL_CTRL) | GRC_LCLCTRL_AUTO_SEEPROM);
+	udelay(100);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
+		u32 nvcfg1 = tr32(NVRAM_CFG1);
+
+		tp->tg3_flags |= TG3_FLAG_NVRAM;
+		if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
+			if (nvcfg1 & NVRAM_CFG1_BUFFERED_MODE)
+				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		} else {
+			nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+			tw32(NVRAM_CFG1, nvcfg1);
+		}
+
+	} else {
+		tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
+	}
+}
+
+static int __devinit tg3_nvram_read_using_eeprom(struct tg3 *tp,
+						 u32 offset, u32 *val)
+{
+	u32 tmp;
+	int i;
+
+	if (offset > EEPROM_ADDR_ADDR_MASK ||
+	    (offset % 4) != 0)
+		return -EINVAL;
+
+	tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
+					EEPROM_ADDR_DEVID_MASK |
+					EEPROM_ADDR_READ);
+	tw32(GRC_EEPROM_ADDR,
+	     tmp |
+	     (0 << EEPROM_ADDR_DEVID_SHIFT) |
+	     ((offset << EEPROM_ADDR_ADDR_SHIFT) &
+	      EEPROM_ADDR_ADDR_MASK) |
+	     EEPROM_ADDR_READ | EEPROM_ADDR_START);
+
+	for (i = 0; i < 10000; i++) {
+		tmp = tr32(GRC_EEPROM_ADDR);
+
+		if (tmp & EEPROM_ADDR_COMPLETE)
+			break;
+		udelay(100);
+	}
+	if (!(tmp & EEPROM_ADDR_COMPLETE))
+		return -EBUSY;
+
+	*val = tr32(GRC_EEPROM_DATA);
+	return 0;
+}
+
+static int __devinit tg3_nvram_read(struct tg3 *tp,
+				    u32 offset, u32 *val)
+{
+	int i, saw_done_clear;
+
+	if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
+		return tg3_nvram_read_using_eeprom(tp, offset, val);
+
+	if (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED)
+		offset = ((offset / NVRAM_BUFFERED_PAGE_SIZE) <<
+			  NVRAM_BUFFERED_PAGE_POS) +
+			(offset % NVRAM_BUFFERED_PAGE_SIZE);
+
+	if (offset > NVRAM_ADDR_MSK)
+		return -EINVAL;
+
+	tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+	for (i = 0; i < 1000; i++) {
+		if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+			break;
+		udelay(20);
+	}
+
+	tw32(NVRAM_ADDR, offset);
+	tw32(NVRAM_CMD,
+	     NVRAM_CMD_RD | NVRAM_CMD_GO |
+	     NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+	/* Wait for done bit to clear then set again. */
+	saw_done_clear = 0;
+	for (i = 0; i < 1000; i++) {
+		udelay(10);
+		if (!saw_done_clear &&
+		    !(tr32(NVRAM_CMD) & NVRAM_CMD_DONE))
+			saw_done_clear = 1;
+		else if (saw_done_clear &&
+			 (tr32(NVRAM_CMD) & NVRAM_CMD_DONE))
+			break;
+	}
+	if (i >= 1000) {
+		tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
+		return -EBUSY;
+	}
+
+	*val = swab32(tr32(NVRAM_RDDATA));
+	tw32(NVRAM_SWARB, 0x20);
+
+	return 0;
+}
+
+struct subsys_tbl_ent {
+	u16 subsys_vendor, subsys_devid;
+	u32 phy_id;
+};
+
+static struct subsys_tbl_ent subsys_id_to_phy_id[] = {
+	/* Broadcom boards. */
+	{ 0x14e4, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */
+	{ 0x14e4, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */
+	{ 0x14e4, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */
+	{ 0x14e4, 0x0003, PHY_ID_SERDES  }, /* BCM95700A9 */
+	{ 0x14e4, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */
+	{ 0x14e4, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */
+	{ 0x14e4, 0x0007, PHY_ID_SERDES  }, /* BCM95701A7 */
+	{ 0x14e4, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */
+	{ 0x14e4, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */
+	{ 0x14e4, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */
+	{ 0x14e4, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */
+
+	/* 3com boards. */
+	{ PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */
+	{ PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */
+	/* { PCI_VENDOR_ID_3COM, 0x1002, PHY_ID_XXX },     3C996CT */
+	/* { PCI_VENDOR_ID_3COM, 0x1003, PHY_ID_XXX },     3C997T */
+	{ PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES  }, /* 3C996SX */
+	/* { PCI_VENDOR_ID_3COM, 0x1005, PHY_ID_XXX },     3C997SZ */
+	{ PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */
+	{ PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */
+
+	/* DELL boards. */
+	{ PCI_VENDOR_ID_DELL, 0x00d1, PHY_ID_BCM5401 }, /* VIPER */
+	{ PCI_VENDOR_ID_DELL, 0x0106, PHY_ID_BCM5401 }, /* JAGUAR */
+	{ PCI_VENDOR_ID_DELL, 0x0109, PHY_ID_BCM5411 }, /* MERLOT */
+	{ PCI_VENDOR_ID_DELL, 0x010a, PHY_ID_BCM5411 }, /* SLIM_MERLOT */
+
+	/* Compaq boards. */
+	{ PCI_VENDOR_ID_COMPAQ, 0x007c, PHY_ID_BCM5701 }, /* BANSHEE */
+	{ PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */
+	{ PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES  }, /* CHANGELING */
+	{ PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */
+	{ PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }  /* NC7780_2 */
+};
+
+static int __devinit tg3_phy_probe(struct tg3 *tp)
+{
+	u32 eeprom_phy_id, hw_phy_id_1, hw_phy_id_2;
+	u32 hw_phy_id, hw_phy_id_masked;
+	enum phy_led_mode eeprom_led_mode;
+	u32 val;
+	int i, eeprom_signature_found, err;
+
+	tp->phy_id = PHY_ID_INVALID;
+	for (i = 0; i < ARRAY_SIZE(subsys_id_to_phy_id); i++) {
+		if ((subsys_id_to_phy_id[i].subsys_vendor ==
+		     tp->pdev->subsystem_vendor) &&
+		    (subsys_id_to_phy_id[i].subsys_devid ==
+		     tp->pdev->subsystem_device)) {
+			tp->phy_id = subsys_id_to_phy_id[i].phy_id;
+			break;
+		}
+	}
+
+	eeprom_phy_id = PHY_ID_INVALID;
+	eeprom_led_mode = led_mode_auto;
+	eeprom_signature_found = 0;
+	tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
+	if (val == NIC_SRAM_DATA_SIG_MAGIC) {
+		u32 nic_cfg;
+
+		tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
+
+		eeprom_signature_found = 1;
+
+		if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
+		    NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) {
+			eeprom_phy_id = PHY_ID_SERDES;
+		} else {
+			u32 nic_phy_id;
+
+			tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &nic_phy_id);
+			if (nic_phy_id != 0) {
+				u32 id1 = nic_phy_id & NIC_SRAM_DATA_PHY_ID1_MASK;
+				u32 id2 = nic_phy_id & NIC_SRAM_DATA_PHY_ID2_MASK;
+
+				eeprom_phy_id  = (id1 >> 16) << 10;
+				eeprom_phy_id |= (id2 & 0xfc00) << 16;
+				eeprom_phy_id |= (id2 & 0x03ff) <<  0;
+			}
+		}
+
+		switch (nic_cfg & NIC_SRAM_DATA_CFG_LED_MODE_MASK) {
+		case NIC_SRAM_DATA_CFG_LED_TRIPLE_SPD:
+			eeprom_led_mode = led_mode_three_link;
+			break;
+
+		case NIC_SRAM_DATA_CFG_LED_LINK_SPD:
+			eeprom_led_mode = led_mode_link10;
+			break;
+
+		default:
+			eeprom_led_mode = led_mode_auto;
+			break;
+		};
+	}
+
+	err = tg3_phy_reset(tp, 0);
+	if (err)
+		return err;
+
+	/* Now read the physical PHY_ID from the chip and verify
+	 * that it is sane.  If it doesn't look good, we fall back
+	 * to either the hard-coded table based PHY_ID and failing
+	 * that the value found in the eeprom area.
+	 */
+	err  = tg3_readphy(tp, MII_PHYSID1, &hw_phy_id_1);
+	err |= tg3_readphy(tp, MII_PHYSID2, &hw_phy_id_2);
+
+	hw_phy_id  = (hw_phy_id_1 & 0xffff) << 10;
+	hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16;
+	hw_phy_id |= (hw_phy_id_2 & 0x03ff) <<  0;
+
+	hw_phy_id_masked = hw_phy_id & PHY_ID_MASK;
+
+	if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) {
+		tp->phy_id = hw_phy_id;
+	} else {
+		/* phy_id currently holds the value found in the
+		 * subsys_id_to_phy_id[] table or PHY_ID_INVALID
+		 * if a match was not found there.
+		 */
+		if (tp->phy_id == PHY_ID_INVALID) {
+			if (!eeprom_signature_found ||
+			    !KNOWN_PHY_ID(eeprom_phy_id & PHY_ID_MASK))
+				return -ENODEV;
+			tp->phy_id = eeprom_phy_id;
+		}
+	}
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
+		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+		tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
+		tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
+	}
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
+		tp->tg3_flags |= TG3_FLAG_PHY_RESET_ON_INIT;
+
+	if (tp->tg3_flags & TG3_FLAG_PHY_RESET_ON_INIT) {
+		u32 mii_tg3_ctrl;
+
+		err = tg3_phy_reset(tp, 1);
+		if (err)
+			return err;
+
+		/* These chips, when reset, only advertise 10Mb capabilities.
+		 * Fix that.
+		 */
+		err  = tg3_writephy(tp, MII_ADVERTISE,
+				    (ADVERTISE_CSMA |
+				     ADVERTISE_10HALF | ADVERTISE_10FULL |
+				     ADVERTISE_100HALF | ADVERTISE_100FULL));
+		mii_tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
+				MII_TG3_CTRL_ADV_1000_FULL |
+				MII_TG3_CTRL_AS_MASTER |
+				MII_TG3_CTRL_ENABLE_AS_MASTER);
+		if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+			mii_tg3_ctrl = 0;
+
+		err |= tg3_writephy(tp, MII_TG3_CTRL, mii_tg3_ctrl);
+		err |= tg3_writephy(tp, MII_BMCR,
+				    (BMCR_ANRESTART | BMCR_ANENABLE));
+	}
+
+	if (!err && ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)) {
+		err = tg3_init_5401phy_dsp(tp);
+	}
+
+	/* Determine the PHY led mode. */
+	if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) {
+		tp->led_mode = led_mode_link10;
+	} else {
+		tp->led_mode = led_mode_three_link;
+		if (eeprom_signature_found &&
+		    eeprom_led_mode != led_mode_auto)
+			tp->led_mode = eeprom_led_mode;
+	}
+
+	if (tp->phy_id == PHY_ID_SERDES)
+		tp->link_config.advertising =
+			(ADVERTISED_1000baseT_Half |
+			 ADVERTISED_1000baseT_Full |
+			 ADVERTISED_Autoneg |
+			 ADVERTISED_FIBRE);
+	if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+		tp->link_config.advertising &=
+			~(ADVERTISED_1000baseT_Half |
+			  ADVERTISED_1000baseT_Full);
+
+	return err;
+}
+
+static void __devinit tg3_read_partno(struct tg3 *tp)
+{
+	unsigned char vpd_data[256];
+	int i;
+
+	for (i = 0; i < 256; i += 4) {
+		u32 tmp;
+
+		if (tg3_nvram_read(tp, 0x100 + i, &tmp))
+			goto out_not_found;
+
+		vpd_data[i + 0] = ((tmp >>  0) & 0xff);
+		vpd_data[i + 1] = ((tmp >>  8) & 0xff);
+		vpd_data[i + 2] = ((tmp >> 16) & 0xff);
+		vpd_data[i + 3] = ((tmp >> 24) & 0xff);
+	}
+
+	/* Now parse and find the part number. */
+	for (i = 0; i < 256; ) {
+		unsigned char val = vpd_data[i];
+		int block_end;
+
+		if (val == 0x82 || val == 0x91) {
+			i = (i + 3 +
+			     (vpd_data[i + 1] +
+			      (vpd_data[i + 2] << 8)));
+			continue;
+		}
+
+		if (val != 0x90)
+			goto out_not_found;
+
+		block_end = (i + 3 +
+			     (vpd_data[i + 1] +
+			      (vpd_data[i + 2] << 8)));
+		i += 3;
+		while (i < block_end) {
+			if (vpd_data[i + 0] == 'P' &&
+			    vpd_data[i + 1] == 'N') {
+				int partno_len = vpd_data[i + 2];
+
+				if (partno_len > 24)
+					goto out_not_found;
+
+				memcpy(tp->board_part_number,
+				       &vpd_data[i + 3],
+				       partno_len);
+
+				/* Success. */
+				return;
+			}
+		}
+
+		/* Part number not found. */
+		goto out_not_found;
+	}
+
+out_not_found:
+	strcpy(tp->board_part_number, "none");
+}
+
+static int __devinit tg3_get_invariants(struct tg3 *tp)
+{
+	u32 misc_ctrl_reg;
+	u32 cacheline_sz_reg;
+	u32 pci_state_reg, grc_misc_cfg;
+	u16 pci_cmd;
+	int err;
+
+	/* Force memory write invalidate off.  If we leave it on,
+	 * then on 5700_BX chips we have to enable a workaround.
+	 * The workaround is to set the TG3PCI_DMA_RW_CTRL boundry
+	 * to match the cacheline size.  The Broadcom driver have this
+	 * workaround but turns MWI off all the times so never uses
+	 * it.  This seems to suggest that the workaround is insufficient.
+	 */
+	pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
+	pci_cmd &= ~PCI_COMMAND_INVALIDATE;
+	pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
+
+	pci_read_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+			      &misc_ctrl_reg);
+
+	tp->pci_chip_rev_id = (misc_ctrl_reg >>
+			       MISC_HOST_CTRL_CHIPREV_SHIFT);
+
+	pci_read_config_dword(tp->pdev, TG3PCI_CACHELINESZ,
+			      &cacheline_sz_reg);
+
+	tp->pci_cacheline_sz = (cacheline_sz_reg >>  0) & 0xff;
+	tp->pci_lat_timer    = (cacheline_sz_reg >>  8) & 0xff;
+	tp->pci_hdr_type     = (cacheline_sz_reg >> 16) & 0xff;
+	tp->pci_bist         = (cacheline_sz_reg >> 24) & 0xff;
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
+	    tp->pci_lat_timer < 64) {
+		tp->pci_lat_timer = 64;
+
+		cacheline_sz_reg  = ((tp->pci_cacheline_sz & 0xff) <<  0);
+		cacheline_sz_reg |= ((tp->pci_lat_timer    & 0xff) <<  8);
+		cacheline_sz_reg |= ((tp->pci_hdr_type     & 0xff) << 16);
+		cacheline_sz_reg |= ((tp->pci_bist         & 0xff) << 24);
+
+		pci_write_config_dword(tp->pdev, TG3PCI_CACHELINESZ,
+				       cacheline_sz_reg);
+	}
+
+	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
+			      &pci_state_reg);
+
+	if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0) {
+		tp->tg3_flags |= TG3_FLAG_PCIX_MODE;
+
+		/* If this is a 5700 BX chipset, and we are in PCI-X
+		 * mode, enable register write workaround.
+		 *
+		 * The workaround is to use indirect register accesses
+		 * for all chip writes not to mailbox registers.
+		 */
+		if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) {
+			u32 pm_reg;
+			u16 pci_cmd;
+
+			tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
+
+			/* The chip can have it's power management PCI config
+			 * space registers clobbered due to this bug.
+			 * So explicitly force the chip into D0 here.
+			 */
+			pci_read_config_dword(tp->pdev, TG3PCI_PM_CTRL_STAT,
+					      &pm_reg);
+			pm_reg &= ~PCI_PM_CTRL_STATE_MASK;
+			pm_reg |= PCI_PM_CTRL_PME_ENABLE | 0 /* D0 */;
+			pci_write_config_dword(tp->pdev, TG3PCI_PM_CTRL_STAT,
+					       pm_reg);
+
+			/* Also, force SERR#/PERR# in PCI command. */
+			pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
+			pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+			pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
+		}
+	}
+	if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0)
+		tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
+	if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
+		tp->tg3_flags |= TG3_FLAG_PCI_32BIT;
+
+	/* Force the chip into D0. */
+	err = tg3_set_power_state(tp, 0);
+	if (err)
+		return err;
+
+	/* 5700 B0 chips do not support checksumming correctly due
+	 * to hardware bugs.
+	 */
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
+		tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
+
+	/* Regardless of whether checksums work or not, we configure
+	 * the StrongARM chips to not compute the pseudo header checksums
+	 * in either direction.  Because of the way Linux checksum support
+	 * works we do not need the chips to do this, and taking the load
+	 * off of the TX/RX onboard StrongARM cpus means that they will not be
+	 * the bottleneck.  Whoever wrote Broadcom's driver did not
+	 * understand the situation at all.  He could have bothered
+	 * to read Jes's Acenic driver because the logic (and this part of
+	 * the Tigon2 hardware/firmware) is pretty much identical.
+	 */
+	tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM;
+	tp->tg3_flags |= TG3_FLAG_NO_RX_PSEUDO_CSUM;
+
+	/* Derive initial jumbo mode from MTU assigned in
+	 * ether_setup() via the alloc_etherdev() call
+	 */
+	if (tp->dev->mtu > ETH_DATA_LEN)
+		tp->tg3_flags |= TG3_FLAG_JUMBO_ENABLE;
+
+	/* Determine WakeOnLan speed to use. */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5701_B2) {
+		tp->tg3_flags &= ~(TG3_FLAG_WOL_SPEED_100MB);
+	} else {
+		tp->tg3_flags |= TG3_FLAG_WOL_SPEED_100MB;
+	}
+
+	/* Only 5701 and later support tagged irq status mode. */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) {
+		tp->tg3_flags |= TG3_FLAG_TAGGED_IRQ_STATUS;
+		tp->misc_host_ctrl |= MISC_HOST_CTRL_TAGGED_STATUS;
+
+		/* ??? Due to a glitch Broadcom's driver ALWAYS sets
+		 * ??? these bits in coalesce_mode.  Because MM_GetConfig
+		 * ??? always sets pDevice->UseTaggedStatus correctly
+		 * ??? the following test at tigon3.c:LM_GetAdapterInfo()
+		 * ???
+		 * ???   pDevice->UseTaggedStatus &&
+		 * ???   (pDevice->ChipRevId == T3_CHIP_ID_5700_C0 ||
+		 * ???    T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_AX ||
+		 * ???    T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
+		 * ???
+		 * ??? will never pass and thus pDevice->CoalesceMode will never
+		 * ??? get set to zero.  For now I'll mirror what I believe is
+		 * ??? the intention of their driver.
+		 * ???
+		 * ??? Update: This is fixed in Broadcom's 2.2.3 and later
+		 * ???         drivers.  All the current 2.0.x drivers still
+		 * ???         have the bug.
+		 */
+		tp->coalesce_mode = (HOSTCC_MODE_CLRTICK_RXBD |
+				     HOSTCC_MODE_CLRTICK_TXBD);
+	} else {
+		tp->coalesce_mode = 0;
+
+		/* If not using tagged status, set the *_during_int
+		 * coalesce default config values to zero.
+		 */
+		tp->coalesce_config.rx_coalesce_ticks_during_int_def = 0;
+		tp->coalesce_config.rx_max_coalesced_frames_during_int_def = 0;
+		tp->coalesce_config.tx_coalesce_ticks_during_int_def = 0;
+		tp->coalesce_config.tx_max_coalesced_frames_during_int_def = 0;
+	}
+
+	if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX &&
+	    GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
+		tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
+
+	/* Initialize misc host control in PCI block. */
+	tp->misc_host_ctrl |= (misc_ctrl_reg &
+			       MISC_HOST_CTRL_CHIPREV);
+	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+			       tp->misc_host_ctrl);
+
+	/* Initialize MAC MI mode, polling disabled. */
+	tw32(MAC_MI_MODE, tp->mi_mode);
+	udelay(40);
+
+	/* Initialize data/descriptor byte/word swapping. */
+	tw32(GRC_MODE, tp->grc_mode);
+
+	/* Clear these out for sanity. */
+	tw32(TG3PCI_CLOCK_CTRL, 0);
+	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
+
+	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
+			      &pci_state_reg);
+	if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 &&
+	    (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) == 0) {
+		u32 chiprevid = GET_CHIP_REV_ID(tp->misc_host_ctrl);
+
+		if (chiprevid == CHIPREV_ID_5701_A0 ||
+		    chiprevid == CHIPREV_ID_5701_B0 ||
+		    chiprevid == CHIPREV_ID_5701_B2 ||
+		    chiprevid == CHIPREV_ID_5701_B5) {
+			unsigned long sram_base;
+
+			/* Write some dummy words into the SRAM status block
+			 * area, see if it reads back correctly.  If the return
+			 * value is bad, force enable the PCIX workaround.
+			 */
+			sram_base = tp->regs + NIC_SRAM_WIN_BASE + NIC_SRAM_STATS_BLK;
+
+			writel(0x00000000, sram_base);
+			writel(0x00000000, sram_base + 4);
+			writel(0xffffffff, sram_base + 4);
+			if (readl(sram_base) != 0x00000000)
+				tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
+		}
+	}
+
+	udelay(50);
+	tg3_nvram_init(tp);
+
+	/* Determine if TX descriptors will reside in
+	 * main memory or in the chip SRAM.
+	 */
+	if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG)
+		tp->tg3_flags |= TG3_FLAG_HOST_TXDS;
+
+	/* Quick sanity check.  Make sure we see an expected
+	 * value here.
+	 */
+	grc_misc_cfg = tr32(GRC_MISC_CFG);
+	grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
+	if (grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5700 &&
+	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5701 &&
+	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5702FE &&
+	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703 &&
+	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703S &&
+	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_AC91002A1)
+		return -ENODEV;
+
+	/* ROFL, you should see Broadcom's driver code implementing
+	 * this, stuff like "if (a || b)" where a and b are always
+	 * mutually exclusive.  DaveM finds like 6 bugs today, hello!
+	 */
+	if (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5702FE)
+		tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
+
+	err = tg3_phy_probe(tp);
+
+	tg3_read_partno(tp);
+
+	if (tp->phy_id == PHY_ID_SERDES) {
+		tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT;
+
+		/* And override led_mode in case Dell ever makes
+		 * a fibre board.
+		 */
+		tp->led_mode = led_mode_three_link;
+	} else {
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
+			tp->tg3_flags |= TG3_FLAG_USE_MI_INTERRUPT;
+		else
+			tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT;
+	}
+
+	/* 5700 {AX,BX} chips have a broken status block link
+	 * change bit implementation, so we must use the
+	 * status register in those cases.
+	 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
+		tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG;
+	else
+		tp->tg3_flags &= ~TG3_FLAG_USE_LINKCHG_REG;
+
+	/* The led_mode is set during tg3_phy_probe, here we might
+	 * have to force the link status polling mechanism based
+	 * upon subsystem IDs.
+	 */
+	if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
+	    tp->phy_id != PHY_ID_SERDES) {
+		tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT |
+				  TG3_FLAG_USE_LINKCHG_REG);
+	}
+
+	/* For all SERDES we poll the MAC status register. */
+	if (tp->phy_id == PHY_ID_SERDES)
+		tp->tg3_flags |= TG3_FLAG_POLL_SERDES;
+	else
+		tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
+
+	/* 5700 BX chips need to have their TX producer index mailboxes
+	 * written twice to workaround a bug.
+	 */
+	if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX)
+		tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
+	else
+		tp->tg3_flags &= ~TG3_FLAG_TXD_MBOX_HWBUG;
+
+	/* 5700 chips can get confused if TX buffers straddle the
+	 * 4GB address boundary in some cases.
+	 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
+		/* ROFL!  Latest Broadcom driver disables NETIF_F_HIGHDMA
+		 * in this case instead of fixing their workaround code.
+		 *
+		 * Like, hey, there is this skb_copy() thing guys,
+		 * use it.  Oh I can't stop laughing...
+		 */
+		tp->dev->hard_start_xmit = tg3_start_xmit_4gbug;
+	} else {
+		tp->dev->hard_start_xmit = tg3_start_xmit;
+	}
+
+	tp->rx_offset = 2;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
+	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0)
+		tp->rx_offset = 0;
+
+	return err;
+}
+
+static int __devinit tg3_get_device_address(struct tg3 *tp)
+{
+	struct net_device *dev = tp->dev;
+	u32 hi, lo;
+
+	/* First try to get it from MAC address mailbox. */
+	tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
+	if ((hi >> 16) == 0x484b) {
+		dev->dev_addr[0] = (hi >>  8) & 0xff;
+		dev->dev_addr[1] = (hi >>  0) & 0xff;
+
+		tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_LOW_MBOX, &lo);
+		dev->dev_addr[2] = (lo >> 24) & 0xff;
+		dev->dev_addr[3] = (lo >> 16) & 0xff;
+		dev->dev_addr[4] = (lo >>  8) & 0xff;
+		dev->dev_addr[5] = (lo >>  0) & 0xff;
+	}
+	/* Next, try NVRAM. */
+	else if (!tg3_nvram_read(tp, 0x7c, &hi) &&
+		 !tg3_nvram_read(tp, 0x80, &lo)) {
+		dev->dev_addr[0] = ((hi >> 16) & 0xff);
+		dev->dev_addr[1] = ((hi >> 24) & 0xff);
+		dev->dev_addr[2] = ((lo >>  0) & 0xff);
+		dev->dev_addr[3] = ((lo >>  8) & 0xff);
+		dev->dev_addr[4] = ((lo >> 16) & 0xff);
+		dev->dev_addr[5] = ((lo >> 24) & 0xff);
+	}
+	/* Finally just fetch it out of the MAC control regs. */
+	else {
+		hi = tr32(MAC_ADDR_0_HIGH);
+		lo = tr32(MAC_ADDR_0_LOW);
+
+		dev->dev_addr[5] = lo & 0xff;
+		dev->dev_addr[4] = (lo >> 8) & 0xff;
+		dev->dev_addr[3] = (lo >> 16) & 0xff;
+		dev->dev_addr[2] = (lo >> 24) & 0xff;
+		dev->dev_addr[1] = hi & 0xff;
+		dev->dev_addr[0] = (hi >> 8) & 0xff;
+	}
+
+	if (!is_valid_ether_addr(&dev->dev_addr[0]))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dma, int size, int to_device)
+{
+	struct tg3_internal_buffer_desc test_desc;
+	u32 sram_dma_descs;
+	int i, ret;
+
+	sram_dma_descs = NIC_SRAM_DMA_DESC_POOL_BASE;
+
+	tw32(FTQ_RCVBD_COMP_FIFO_ENQDEQ, 0);
+	tw32(FTQ_RCVDATA_COMP_FIFO_ENQDEQ, 0);
+	tw32(RDMAC_STATUS, 0);
+	tw32(WDMAC_STATUS, 0);
+
+	tw32(BUFMGR_MODE, 0);
+	tw32(FTQ_RESET, 0);
+
+	/* pci_alloc_consistent gives only non-DAC addresses */
+	test_desc.addr_hi = 0;
+	test_desc.addr_lo = buf_dma & 0xffffffff;
+	test_desc.nic_mbuf = 0x00002100;
+	test_desc.len = size;
+	if (to_device) {
+		test_desc.cqid_sqid = (13 << 8) | 2;
+		tw32(RDMAC_MODE, RDMAC_MODE_RESET);
+		tw32(RDMAC_MODE, RDMAC_MODE_ENABLE);
+	} else {
+		test_desc.cqid_sqid = (16 << 8) | 7;
+		tw32(WDMAC_MODE, WDMAC_MODE_RESET);
+		tw32(WDMAC_MODE, WDMAC_MODE_ENABLE);
+	}
+	test_desc.flags = 0x00000004;
+
+	for (i = 0; i < (sizeof(test_desc) / sizeof(u32)); i++) {
+		u32 val;
+
+		val = *(((u32 *)&test_desc) + i);
+		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR,
+				       sram_dma_descs + (i * sizeof(u32)));
+		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
+	}
+	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+
+	if (to_device) {
+		tw32(FTQ_DMA_HIGH_READ_FIFO_ENQDEQ, sram_dma_descs);
+	} else {
+		tw32(FTQ_DMA_HIGH_WRITE_FIFO_ENQDEQ, sram_dma_descs);
+	}
+
+	ret = -ENODEV;
+	for (i = 0; i < 40; i++) {
+		u32 val;
+
+		if (to_device)
+			val = tr32(FTQ_RCVBD_COMP_FIFO_ENQDEQ);
+		else
+			val = tr32(FTQ_RCVDATA_COMP_FIFO_ENQDEQ);
+		if ((val & 0xffff) == sram_dma_descs) {
+			ret = 0;
+			break;
+		}
+
+		udelay(100);
+	}
+
+	return ret;
+}
+
+#define TEST_BUFFER_SIZE	0x400
+
+static int __devinit tg3_test_dma(struct tg3 *tp)
+{
+	dma_addr_t buf_dma;
+	u32 *buf;
+	int ret;
+
+	buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto out_nofree;
+	}
+
+	tw32(TG3PCI_CLOCK_CTRL, 0);
+
+	if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) == 0) {
+		tp->dma_rwctrl =
+			(0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+			(0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+			(0x7 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+			(0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
+			(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
+	} else {
+		tp->dma_rwctrl =
+			(0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+			(0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+			(0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+			(0x3 << DMA_RWCTRL_READ_WATER_SHIFT) |
+			(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
+
+		/* Wheee, some more chip bugs... */
+		if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1 ||
+		    tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)
+			tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
+	}
+
+	/* We don't do this on x86 because it seems to hurt performace.
+	 * It does help things on other platforms though.
+	 */
+#ifndef CONFIG_X86
+	{
+		u8 byte;
+		int cacheline_size;
+		pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, &byte);
+
+		if (byte == 0)
+			cacheline_size = 1024;
+		else
+			cacheline_size = (int) byte * 4;
+
+		tp->dma_rwctrl &= ~(DMA_RWCTRL_READ_BNDRY_MASK |
+				    DMA_RWCTRL_WRITE_BNDRY_MASK);
+
+		switch (cacheline_size) {
+		case 16:
+			tp->dma_rwctrl |=
+				(DMA_RWCTRL_READ_BNDRY_16 |
+				 DMA_RWCTRL_WRITE_BNDRY_16);
+			break;
+
+		case 32:
+			tp->dma_rwctrl |=
+				(DMA_RWCTRL_READ_BNDRY_32 |
+				 DMA_RWCTRL_WRITE_BNDRY_32);
+			break;
+
+		case 64:
+			tp->dma_rwctrl |=
+				(DMA_RWCTRL_READ_BNDRY_64 |
+				 DMA_RWCTRL_WRITE_BNDRY_64);
+			break;
+
+		case 128:
+			tp->dma_rwctrl |=
+				(DMA_RWCTRL_READ_BNDRY_128 |
+				 DMA_RWCTRL_WRITE_BNDRY_128);
+			break;
+
+		case 256:
+			tp->dma_rwctrl |=
+				(DMA_RWCTRL_READ_BNDRY_256 |
+				 DMA_RWCTRL_WRITE_BNDRY_256);
+			break;
+
+		case 512:
+			tp->dma_rwctrl |=
+				(DMA_RWCTRL_READ_BNDRY_512 |
+				 DMA_RWCTRL_WRITE_BNDRY_512);
+			break;
+
+		case 1024:
+			tp->dma_rwctrl |=
+				(DMA_RWCTRL_READ_BNDRY_1024 |
+				 DMA_RWCTRL_WRITE_BNDRY_1024);
+			break;
+		};
+	}
+#endif
+
+	/* Remove this if it causes problems for some boards. */
+	tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT;
+
+	tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
+		return 0;
+
+	ret = 0;
+	while (1) {
+		u32 *p, i;
+
+		p = buf;
+		for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++)
+			p[i] = i;
+
+		/* Send the buffer to the chip. */
+		ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 1);
+		if (ret)
+			break;
+
+		p = buf;
+		for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++)
+			p[i] = 0;
+
+		/* Now read it back. */
+		ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 0);
+		if (ret)
+			break;
+
+		/* Verify it. */
+		p = buf;
+		for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) {
+			if (p[i] == i)
+				continue;
+
+			if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) ==
+			    DMA_RWCTRL_WRITE_BNDRY_DISAB) {
+				tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16;
+				tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
+				break;
+			} else {
+				ret = -ENODEV;
+				goto out;
+			}
+		}
+
+		if (i == (TEST_BUFFER_SIZE / sizeof(u32))) {
+			/* Success. */
+			ret = 0;
+			break;
+		}
+	}
+
+out:
+	pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma);
+out_nofree:
+	return ret;
+}
+
+static void __devinit tg3_init_link_config(struct tg3 *tp)
+{
+	tp->link_config.advertising =
+		(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+		 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+		 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
+		 ADVERTISED_Autoneg | ADVERTISED_MII);
+	tp->link_config.speed = SPEED_INVALID;
+	tp->link_config.duplex = DUPLEX_INVALID;
+	tp->link_config.autoneg = AUTONEG_ENABLE;
+	netif_carrier_off(tp->dev);
+	tp->link_config.active_speed = SPEED_INVALID;
+	tp->link_config.active_duplex = DUPLEX_INVALID;
+	tp->link_config.phy_is_low_power = 0;
+	tp->link_config.orig_speed = SPEED_INVALID;
+	tp->link_config.orig_duplex = DUPLEX_INVALID;
+	tp->link_config.orig_autoneg = AUTONEG_INVALID;
+}
+
+static void __devinit tg3_init_coalesce_config(struct tg3 *tp)
+{
+	tp->coalesce_config.rx_coalesce_ticks_def = DEFAULT_RXCOL_TICKS;
+	tp->coalesce_config.rx_max_coalesced_frames_def = DEFAULT_RXMAX_FRAMES;
+	tp->coalesce_config.rx_coalesce_ticks_during_int_def =
+		DEFAULT_RXCOAL_TICK_INT;
+	tp->coalesce_config.rx_max_coalesced_frames_during_int_def =
+		DEFAULT_RXCOAL_MAXF_INT;
+	tp->coalesce_config.tx_coalesce_ticks_def = DEFAULT_TXCOL_TICKS;
+	tp->coalesce_config.tx_max_coalesced_frames_def = DEFAULT_TXMAX_FRAMES;
+	tp->coalesce_config.tx_coalesce_ticks_during_int_def =
+		DEFAULT_TXCOAL_TICK_INT;
+	tp->coalesce_config.tx_max_coalesced_frames_during_int_def =
+		DEFAULT_TXCOAL_MAXF_INT;
+	tp->coalesce_config.stats_coalesce_ticks_def =
+		DEFAULT_STAT_COAL_TICKS;
+
+	tp->coalesce_config.rx_coalesce_ticks_low =
+		LOW_RXCOL_TICKS;
+	tp->coalesce_config.rx_max_coalesced_frames_low =
+		LOW_RXMAX_FRAMES;
+	tp->coalesce_config.tx_coalesce_ticks_low =
+		LOW_TXCOL_TICKS;
+	tp->coalesce_config.tx_max_coalesced_frames_low =
+		LOW_TXMAX_FRAMES;
+
+	tp->coalesce_config.rx_coalesce_ticks_high =
+		HIGH_RXCOL_TICKS;
+	tp->coalesce_config.rx_max_coalesced_frames_high =
+		HIGH_RXMAX_FRAMES;
+	tp->coalesce_config.tx_coalesce_ticks_high =
+		HIGH_TXCOL_TICKS;
+	tp->coalesce_config.tx_max_coalesced_frames_high =
+		HIGH_TXMAX_FRAMES;
+
+	/* Active == default */
+	tp->coalesce_config.rx_coalesce_ticks =
+		tp->coalesce_config.rx_coalesce_ticks_def;
+	tp->coalesce_config.rx_max_coalesced_frames =
+		tp->coalesce_config.rx_max_coalesced_frames_def;
+	tp->coalesce_config.tx_coalesce_ticks =
+		tp->coalesce_config.tx_coalesce_ticks_def;
+	tp->coalesce_config.tx_max_coalesced_frames =
+		tp->coalesce_config.tx_max_coalesced_frames_def;
+	tp->coalesce_config.stats_coalesce_ticks =
+		tp->coalesce_config.stats_coalesce_ticks_def;
+
+	tp->coalesce_config.rate_sample_jiffies = (1 * HZ);
+	tp->coalesce_config.pkt_rate_low = 22000;
+	tp->coalesce_config.pkt_rate_high = 61000;
+
+	tp->tg3_flags |= TG3_FLAG_ADAPTIVE_RX;
+	tp->tg3_flags &= ~(TG3_FLAG_ADAPTIVE_TX);
+}
+
+static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
+{
+	tp->bufmgr_config.mbuf_read_dma_low_water =
+		DEFAULT_MB_RDMA_LOW_WATER;
+	tp->bufmgr_config.mbuf_mac_rx_low_water =
+		DEFAULT_MB_MACRX_LOW_WATER;
+	tp->bufmgr_config.mbuf_high_water =
+		DEFAULT_MB_HIGH_WATER;
+
+	tp->bufmgr_config.mbuf_read_dma_low_water_jumbo =
+		DEFAULT_MB_RDMA_LOW_WATER_JUMBO;
+	tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo =
+		DEFAULT_MB_MACRX_LOW_WATER_JUMBO;
+	tp->bufmgr_config.mbuf_high_water_jumbo =
+		DEFAULT_MB_HIGH_WATER_JUMBO;
+
+	tp->bufmgr_config.dma_low_water = DEFAULT_DMA_LOW_WATER;
+	tp->bufmgr_config.dma_high_water = DEFAULT_DMA_HIGH_WATER;
+}
+
+static char * __devinit tg3_phy_string(struct tg3 *tp)
+{
+	switch (tp->phy_id & PHY_ID_MASK) {
+	case PHY_ID_BCM5400:	return "5400";
+	case PHY_ID_BCM5401:	return "5401";
+	case PHY_ID_BCM5411:	return "5411";
+	case PHY_ID_BCM5701:	return "5701";
+	case PHY_ID_BCM5703:	return "5703";
+	case PHY_ID_BCM8002:	return "8002";
+	case PHY_ID_SERDES:	return "serdes";
+	default:		return "unknown";
+	};
+}
+
+static int __devinit tg3_init_one(struct pci_dev *pdev,
+				  const struct pci_device_id *ent)
+{
+	static int tg3_version_printed = 0;
+	unsigned long tg3reg_base, tg3reg_len;
+	struct net_device *dev;
+	struct tg3 *tp;
+	int i, err, pci_using_dac, pm_cap;
+
+	if (tg3_version_printed++ == 0)
+		printk(KERN_INFO "%s", version);
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot enable PCI device, "
+		       "aborting.\n");
+		return err;
+	}
+
+	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+		printk(KERN_ERR PFX "Cannot find proper PCI device "
+		       "base address, aborting.\n");
+		err = -ENODEV;
+		goto err_out_disable_pdev;
+	}
+
+	err = pci_request_regions(pdev, DRV_MODULE_NAME);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot obtain PCI resources, "
+		       "aborting.\n");
+		goto err_out_disable_pdev;
+	}
+
+	pci_set_master(pdev);
+
+	/* Find power-management capability. */
+	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (pm_cap == 0) {
+		printk(KERN_ERR PFX "Cannot find PowerManagement capability, "
+		       "aborting.\n");
+		goto err_out_free_res;
+	}
+
+	/* Configure DMA attributes. */
+	if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) {
+		pci_using_dac = 1;
+	} else {
+		err = pci_set_dma_mask(pdev, (u64) 0xffffffff);
+		if (err) {
+			printk(KERN_ERR PFX "No usable DMA configuration, "
+			       "aborting.\n");
+			goto err_out_free_res;
+		}
+		pci_using_dac = 0;
+	}
+
+	tg3reg_base = pci_resource_start(pdev, 0);
+	tg3reg_len = pci_resource_len(pdev, 0);
+
+	dev = alloc_etherdev(sizeof(*tp));
+	if (!dev) {
+		printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+		err = -ENOMEM;
+		goto err_out_free_res;
+	}
+
+	SET_MODULE_OWNER(dev);
+
+	if (pci_using_dac)
+		dev->features |= NETIF_F_HIGHDMA;
+#if TG3_VLAN_TAG_USED
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->vlan_rx_register = tg3_vlan_rx_register;
+	dev->vlan_rx_kill_vid = tg3_vlan_rx_kill_vid;
+#endif
+
+	tp = dev->priv;
+	tp->pdev = pdev;
+	tp->dev = dev;
+	tp->pm_cap = pm_cap;
+	tp->mac_mode = TG3_DEF_MAC_MODE;
+	tp->rx_mode = TG3_DEF_RX_MODE;
+	tp->tx_mode = TG3_DEF_TX_MODE;
+	tp->mi_mode = MAC_MI_MODE_BASE;
+	if (tg3_debug > 0)
+		tp->msg_enable = tg3_debug;
+	else
+		tp->msg_enable = TG3_DEF_MSG_ENABLE;
+
+	/* The word/byte swap controls here control register access byte
+	 * swapping.  DMA data byte swapping is controlled in the GRC_MODE
+	 * setting below.
+	 */
+	tp->misc_host_ctrl =
+		MISC_HOST_CTRL_MASK_PCI_INT |
+		MISC_HOST_CTRL_WORD_SWAP |
+		MISC_HOST_CTRL_INDIR_ACCESS |
+		MISC_HOST_CTRL_PCISTATE_RW;
+
+	/* The NONFRM (non-frame) byte/word swap controls take effect
+	 * on descriptor entries, anything which isn't packet data.
+	 *
+	 * The StrongARM chips on the board (one for tx, one for rx)
+	 * are running in big-endian mode.
+	 */
+	tp->grc_mode = (GRC_MODE_WSWAP_DATA | GRC_MODE_BSWAP_DATA |
+			GRC_MODE_WSWAP_NONFRM_DATA);
+#ifdef __BIG_ENDIAN
+	tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA;
+#endif
+	spin_lock_init(&tp->lock);
+	spin_lock_init(&tp->indirect_lock);
+
+	tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
+	if (tp->regs == 0UL) {
+		printk(KERN_ERR PFX "Cannot map device registers, "
+		       "aborting.\n");
+		err = -ENOMEM;
+		goto err_out_free_dev;
+	}
+
+	tg3_init_link_config(tp);
+
+	tg3_init_coalesce_config(tp);
+
+	tg3_init_bufmgr_config(tp);
+
+	tp->rx_pending = TG3_DEF_RX_RING_PENDING;
+#if TG3_MINI_RING_WORKS
+	tp->rx_mini_pending = TG3_DEF_RX_MINI_RING_PENDING;
+#endif
+	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
+	tp->tx_pending = TG3_DEF_TX_RING_PENDING;
+
+	dev->open = tg3_open;
+	dev->stop = tg3_close;
+	dev->get_stats = tg3_get_stats;
+	dev->set_multicast_list = tg3_set_rx_mode;
+	dev->set_mac_address = tg3_set_mac_addr;
+	dev->do_ioctl = tg3_ioctl;
+	dev->tx_timeout = tg3_tx_timeout;
+	dev->watchdog_timeo = TG3_TX_TIMEOUT;
+	dev->change_mtu = tg3_change_mtu;
+	dev->irq = pdev->irq;
+
+	err = tg3_get_invariants(tp);
+	if (err) {
+		printk(KERN_ERR PFX "Problem fetching invariants of chip, "
+		       "aborting.\n");
+		goto err_out_iounmap;
+	}
+
+	err = tg3_get_device_address(tp);
+	if (err) {
+		printk(KERN_ERR PFX "Could not obtain valid ethernet address, "
+		       "aborting.\n");
+		goto err_out_iounmap;
+	}
+
+	err = tg3_test_dma(tp);
+	if (err) {
+		printk(KERN_ERR PFX "DMA engine test failed, aborting.\n");
+		goto err_out_iounmap;
+	}
+
+	/* Tigon3 can do ipv4 only... and some chips have buggy
+	 * checksumming.
+	 */
+	if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
+		dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+		tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
+	} else
+		tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
+
+	err = register_netdev(dev);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot register net device, "
+		       "aborting.\n");
+		goto err_out_iounmap;
+	}
+
+	pci_set_drvdata(pdev, dev);
+
+	/* Now that we have fully setup the chip, save away a snapshot
+	 * of the PCI config space.  We need to restore this after
+	 * GRC_MISC_CFG core clock resets and some resume events.
+	 */
+	pci_save_state(tp->pdev, tp->pci_cfg_state);
+
+	printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ",
+	       dev->name,
+	       tp->board_part_number,
+	       tp->pci_chip_rev_id,
+	       tg3_phy_string(tp),
+	       ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "X" : ""),
+	       ((tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) ?
+		((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "133MHz" : "66MHz") :
+		((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "100MHz" : "33MHz")),
+	       ((tp->tg3_flags & TG3_FLAG_PCI_32BIT) ? "32-bit" : "64-bit"),
+	       (tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000");
+
+	for (i = 0; i < 6; i++)
+		printk("%2.2x%c", dev->dev_addr[i],
+		       i == 5 ? '\n' : ':');
+
+	return 0;
+
+err_out_iounmap:
+	iounmap((void *) tp->regs);
+
+err_out_free_dev:
+	kfree(dev);
+
+err_out_free_res:
+	pci_release_regions(pdev);
+
+err_out_disable_pdev:
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+	return err;
+}
+
+static void __devexit tg3_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+
+	if (dev) {
+		unregister_netdev(dev);
+		iounmap((void *) ((struct tg3 *)(dev->priv))->regs);
+		kfree(dev);
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		pci_set_drvdata(pdev, NULL);
+	}
+}
+
+static int tg3_suspend(struct pci_dev *pdev, u32 state)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct tg3 *tp = dev->priv;
+	int err;
+
+	if (!netif_running(dev))
+		return 0;
+
+	spin_lock_irq(&tp->lock);
+	tg3_disable_ints(tp);
+	spin_unlock_irq(&tp->lock);
+
+	netif_device_detach(dev);
+
+	spin_lock_irq(&tp->lock);
+	tg3_halt(tp);
+	spin_unlock_irq(&tp->lock);
+
+	err = tg3_set_power_state(tp, state);
+	if (err) {
+		spin_lock_irq(&tp->lock);
+
+		tg3_init_rings(tp);
+		tg3_init_hw(tp);
+
+		spin_unlock_irq(&tp->lock);
+
+		netif_device_attach(dev);
+	}
+
+	return err;
+}
+
+static int tg3_resume(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct tg3 *tp = dev->priv;
+	int err;
+
+	if (!netif_running(dev))
+		return 0;
+
+	err = tg3_set_power_state(tp, 0);
+	if (err)
+		return err;
+
+	netif_device_attach(dev);
+
+	spin_lock_irq(&tp->lock);
+
+	tg3_init_rings(tp);
+	tg3_init_hw(tp);
+	tg3_enable_ints(tp);
+
+	spin_unlock_irq(&tp->lock);
+
+	return 0;
+}
+
+static struct pci_driver tg3_driver = {
+	name:		DRV_MODULE_NAME,
+	id_table:	tg3_pci_tbl,
+	probe:		tg3_init_one,
+	remove:		__devexit_p(tg3_remove_one),
+	suspend:	tg3_suspend,
+	resume:		tg3_resume
+};
+
+static int __init tg3_init(void)
+{
+	return pci_module_init(&tg3_driver);
+}
+
+static void __exit tg3_cleanup(void)
+{
+	pci_unregister_driver(&tg3_driver);
+}
+
+module_init(tg3_init);
+module_exit(tg3_cleanup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tg3.h linux/drivers/net/tg3.h
--- linux.orig/drivers/net/tg3.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/tg3.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,1900 @@
+/* $Id: tg3.h,v 1.37.2.32 2002/03/11 12:18:18 davem Exp $
+ * tg3.h: Definitions for Broadcom Tigon3 ethernet driver.
+ *
+ * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2001 Jeff Garzik (jgarzik@mandrakesoft.com)
+ */
+
+#ifndef _T3_H
+#define _T3_H
+
+#define TG3_64BIT_REG_HIGH		0x00UL
+#define TG3_64BIT_REG_LOW		0x04UL
+
+/* Descriptor block info. */
+#define TG3_BDINFO_HOST_ADDR		0x0UL /* 64-bit */
+#define TG3_BDINFO_MAXLEN_FLAGS		0x8UL /* 32-bit */
+#define  BDINFO_FLAGS_USE_EXT_RECV	 0x00000001 /* ext rx_buffer_desc */
+#define  BDINFO_FLAGS_DISABLED		 0x00000002
+#define  BDINFO_FLAGS_MAXLEN_MASK	 0xffff0000
+#define  BDINFO_FLAGS_MAXLEN_SHIFT	 16
+#define TG3_BDINFO_NIC_ADDR		0xcUL /* 32-bit */
+#define TG3_BDINFO_SIZE			0x10UL
+
+#define RX_COPY_THRESHOLD  		256
+
+#define RX_STD_MAX_SIZE			1536
+#define RX_JUMBO_MAX_SIZE		0xdeadbeef /* XXX */
+#if TG3_MINI_RING_WORKS
+#define RX_MINI_MAX_SIZE		256
+#endif
+
+/* First 256 bytes are a mirror of PCI config space. */
+#define TG3PCI_VENDOR			0x00000000
+#define  TG3PCI_VENDOR_BROADCOM		 0x14e4
+#define TG3PCI_DEVICE			0x00000002
+#define  TG3PCI_DEVICE_TIGON3_1		 0x1644 /* BCM5700 */
+#define  TG3PCI_DEVICE_TIGON3_2		 0x1645 /* BCM5701 */
+#define  TG3PCI_DEVICE_TIGON3_3		 0x1646 /* BCM5702 */
+#define  TG3PCI_DEVICE_TIGON3_4		 0x1647 /* BCM5703 */
+#define TG3PCI_COMMAND			0x00000004
+#define TG3PCI_STATUS			0x00000006
+#define TG3PCI_CCREVID			0x00000008
+#define TG3PCI_CACHELINESZ		0x0000000c
+#define TG3PCI_LATTIMER			0x0000000d
+#define TG3PCI_HEADERTYPE		0x0000000e
+#define TG3PCI_BIST			0x0000000f
+#define TG3PCI_BASE0_LOW		0x00000010
+#define TG3PCI_BASE0_HIGH		0x00000014
+/* 0x18 --> 0x2c unused */
+#define TG3PCI_SUBSYSVENID		0x0000002c
+#define TG3PCI_SUBSYSID			0x0000002e
+#define TG3PCI_ROMADDR			0x00000030
+#define TG3PCI_CAPLIST			0x00000034
+/* 0x35 --> 0x3c unused */
+#define TG3PCI_IRQ_LINE			0x0000003c
+#define TG3PCI_IRQ_PIN			0x0000003d
+#define TG3PCI_MIN_GNT			0x0000003e
+#define TG3PCI_MAX_LAT			0x0000003f
+#define TG3PCI_X_CAPS			0x00000040
+#define  PCIX_CAPS_RELAXED_ORDERING	 0x00020000
+#define TG3PCI_PM_CAP_PTR		0x00000041
+#define TG3PCI_X_COMMAND		0x00000042
+#define TG3PCI_X_STATUS			0x00000044
+#define TG3PCI_PM_CAP_ID		0x00000048
+#define TG3PCI_VPD_CAP_PTR		0x00000049
+#define TG3PCI_PM_CAPS			0x0000004a
+#define TG3PCI_PM_CTRL_STAT		0x0000004c
+#define TG3PCI_BR_SUPP_EXT		0x0000004e
+#define TG3PCI_PM_DATA			0x0000004f
+#define TG3PCI_VPD_CAP_ID		0x00000050
+#define TG3PCI_MSI_CAP_PTR		0x00000051
+#define TG3PCI_VPD_ADDR_FLAG		0x00000052
+#define  VPD_ADDR_FLAG_WRITE		0x00008000
+#define TG3PCI_VPD_DATA			0x00000054
+#define TG3PCI_MSI_CAP_ID		0x00000058
+#define TG3PCI_NXT_CAP_PTR		0x00000059
+#define TG3PCI_MSI_CTRL			0x0000005a
+#define TG3PCI_MSI_ADDR_LOW		0x0000005c
+#define TG3PCI_MSI_ADDR_HIGH		0x00000060
+#define TG3PCI_MSI_DATA			0x00000064
+/* 0x66 --> 0x68 unused */
+#define TG3PCI_MISC_HOST_CTRL		0x00000068
+#define  MISC_HOST_CTRL_CLEAR_INT	 0x00000001
+#define  MISC_HOST_CTRL_MASK_PCI_INT	 0x00000002
+#define  MISC_HOST_CTRL_BYTE_SWAP	 0x00000004
+#define  MISC_HOST_CTRL_WORD_SWAP	 0x00000008
+#define  MISC_HOST_CTRL_PCISTATE_RW	 0x00000010
+#define  MISC_HOST_CTRL_CLKREG_RW	 0x00000020
+#define  MISC_HOST_CTRL_REGWORD_SWAP	 0x00000040
+#define  MISC_HOST_CTRL_INDIR_ACCESS	 0x00000080
+#define  MISC_HOST_CTRL_IRQ_MASK_MODE	 0x00000100
+#define  MISC_HOST_CTRL_TAGGED_STATUS	 0x00000200
+#define  MISC_HOST_CTRL_CHIPREV		 0xffff0000
+#define  MISC_HOST_CTRL_CHIPREV_SHIFT	 16
+#define  GET_CHIP_REV_ID(MISC_HOST_CTRL) \
+	 (((MISC_HOST_CTRL) & MISC_HOST_CTRL_CHIPREV) >> \
+	  MISC_HOST_CTRL_CHIPREV_SHIFT)
+#define  CHIPREV_ID_5700_A0		 0x7000
+#define  CHIPREV_ID_5700_A1		 0x7001
+#define  CHIPREV_ID_5700_B0		 0x7100
+#define  CHIPREV_ID_5700_B1		 0x7101
+#define  CHIPREV_ID_5700_B3		 0x7102
+#define  CHIPREV_ID_5700_ALTIMA		 0x7104
+#define  CHIPREV_ID_5700_C0		 0x7200
+#define  CHIPREV_ID_5701_A0		 0x0000
+#define  CHIPREV_ID_5701_B0		 0x0100
+#define  CHIPREV_ID_5701_B2		 0x0102
+#define  CHIPREV_ID_5701_B5		 0x0105
+#define  CHIPREV_ID_5703_A0		 0x1000
+#define  CHIPREV_ID_5703_A1		 0x1001
+#define  CHIPREV_ID_5703_A2		 0x1002
+#define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
+#define   ASIC_REV_5700			 0x07
+#define   ASIC_REV_5701			 0x00
+#define   ASIC_REV_5703			 0x01
+#define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
+#define   CHIPREV_5700_AX		 0x70
+#define   CHIPREV_5700_BX		 0x71
+#define   CHIPREV_5700_CX		 0x72
+#define   CHIPREV_5701_AX		 0x00
+#define  GET_METAL_REV(CHIP_REV_ID)	((CHIP_REV_ID) & 0xff)
+#define   METAL_REV_A0			 0x00
+#define   METAL_REV_A1			 0x01
+#define   METAL_REV_B0			 0x00
+#define   METAL_REV_B1			 0x01
+#define   METAL_REV_B2			 0x02
+#define TG3PCI_DMA_RW_CTRL		0x0000006c
+#define  DMA_RWCTRL_MIN_DMA		 0x000000ff
+#define  DMA_RWCTRL_MIN_DMA_SHIFT	 0
+#define  DMA_RWCTRL_READ_BNDRY_MASK	 0x00000700
+#define  DMA_RWCTRL_READ_BNDRY_DISAB	 0x00000000
+#define  DMA_RWCTRL_READ_BNDRY_16	 0x00000100
+#define  DMA_RWCTRL_READ_BNDRY_32	 0x00000200
+#define  DMA_RWCTRL_READ_BNDRY_64	 0x00000300
+#define  DMA_RWCTRL_READ_BNDRY_128	 0x00000400
+#define  DMA_RWCTRL_READ_BNDRY_256	 0x00000500
+#define  DMA_RWCTRL_READ_BNDRY_512	 0x00000600
+#define  DMA_RWCTRL_READ_BNDRY_1024	 0x00000700
+#define  DMA_RWCTRL_WRITE_BNDRY_MASK	 0x00003800
+#define  DMA_RWCTRL_WRITE_BNDRY_DISAB	 0x00000000
+#define  DMA_RWCTRL_WRITE_BNDRY_16	 0x00000800
+#define  DMA_RWCTRL_WRITE_BNDRY_32	 0x00001000
+#define  DMA_RWCTRL_WRITE_BNDRY_64	 0x00001800
+#define  DMA_RWCTRL_WRITE_BNDRY_128	 0x00002000
+#define  DMA_RWCTRL_WRITE_BNDRY_256	 0x00002800
+#define  DMA_RWCTRL_WRITE_BNDRY_512	 0x00003000
+#define  DMA_RWCTRL_WRITE_BNDRY_1024	 0x00003800
+#define  DMA_RWCTRL_ONE_DMA		 0x00004000
+#define  DMA_RWCTRL_READ_WATER		 0x00070000
+#define  DMA_RWCTRL_READ_WATER_SHIFT	 16
+#define  DMA_RWCTRL_WRITE_WATER		 0x00380000
+#define  DMA_RWCTRL_WRITE_WATER_SHIFT	 19
+#define  DMA_RWCTRL_USE_MEM_READ_MULT	 0x00400000
+#define  DMA_RWCTRL_ASSERT_ALL_BE	 0x00800000
+#define  DMA_RWCTRL_PCI_READ_CMD	 0x0f000000
+#define  DMA_RWCTRL_PCI_READ_CMD_SHIFT	 24
+#define  DMA_RWCTRL_PCI_WRITE_CMD	 0xf0000000
+#define  DMA_RWCTRL_PCI_WRITE_CMD_SHIFT	 28
+#define TG3PCI_PCISTATE			0x00000070
+#define  PCISTATE_FORCE_RESET		 0x00000001
+#define  PCISTATE_INT_NOT_ACTIVE	 0x00000002
+#define  PCISTATE_CONV_PCI_MODE		 0x00000004
+#define  PCISTATE_BUS_SPEED_HIGH	 0x00000008
+#define  PCISTATE_BUS_32BIT		 0x00000010
+#define  PCISTATE_ROM_ENABLE		 0x00000020
+#define  PCISTATE_ROM_RETRY_ENABLE	 0x00000040
+#define  PCISTATE_FLAT_VIEW		 0x00000100
+#define TG3PCI_CLOCK_CTRL		0x00000074
+#define  CLOCK_CTRL_CORECLK_DISABLE	 0x00000200
+#define  CLOCK_CTRL_RXCLK_DISABLE	 0x00000400
+#define  CLOCK_CTRL_TXCLK_DISABLE	 0x00000800
+#define  CLOCK_CTRL_ALTCLK		 0x00001000
+#define  CLOCK_CTRL_PWRDOWN_PLL133	 0x00008000
+#define  CLOCK_CTRL_44MHZ_CORE		 0x00040000
+#define  CLOCK_CTRL_DELAY_PCI_GRANT	 0x80000000
+#define TG3PCI_REG_BASE_ADDR		0x00000078
+#define TG3PCI_MEM_WIN_BASE_ADDR	0x0000007c
+#define TG3PCI_REG_DATA			0x00000080
+#define TG3PCI_MEM_WIN_DATA		0x00000084
+#define TG3PCI_MODE_CTRL		0x00000088
+#define TG3PCI_MISC_CFG			0x0000008c
+#define TG3PCI_MISC_LOCAL_CTRL		0x00000090
+/* 0x94 --> 0x98 unused */
+#define TG3PCI_STD_RING_PROD_IDX	0x00000098 /* 64-bit */
+#define TG3PCI_RCV_RET_RING_CON_IDX	0x000000a0 /* 64-bit */
+#define TG3PCI_SND_PROD_IDX		0x000000a8 /* 64-bit */
+/* 0xb0 --> 0x100 unused */
+
+/* 0x100 --> 0x200 unused */
+
+/* Mailbox registers */
+#define MAILBOX_INTERRUPT_0		0x00000200 /* 64-bit */
+#define MAILBOX_INTERRUPT_1		0x00000208 /* 64-bit */
+#define MAILBOX_INTERRUPT_2		0x00000210 /* 64-bit */
+#define MAILBOX_INTERRUPT_3		0x00000218 /* 64-bit */
+#define MAILBOX_GENERAL_0		0x00000220 /* 64-bit */
+#define MAILBOX_GENERAL_1		0x00000228 /* 64-bit */
+#define MAILBOX_GENERAL_2		0x00000230 /* 64-bit */
+#define MAILBOX_GENERAL_3		0x00000238 /* 64-bit */
+#define MAILBOX_GENERAL_4		0x00000240 /* 64-bit */
+#define MAILBOX_GENERAL_5		0x00000248 /* 64-bit */
+#define MAILBOX_GENERAL_6		0x00000250 /* 64-bit */
+#define MAILBOX_GENERAL_7		0x00000258 /* 64-bit */
+#define MAILBOX_RELOAD_STAT		0x00000260 /* 64-bit */
+#define MAILBOX_RCV_STD_PROD_IDX	0x00000268 /* 64-bit */
+#define MAILBOX_RCV_JUMBO_PROD_IDX	0x00000270 /* 64-bit */
+#define MAILBOX_RCV_MINI_PROD_IDX	0x00000278 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_0	0x00000280 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_1	0x00000288 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_2	0x00000290 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_3	0x00000298 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_4	0x000002a0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_5	0x000002a8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_6	0x000002b0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_7	0x000002b8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_8	0x000002c0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_9	0x000002c8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_10	0x000002d0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_11	0x000002d8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_12	0x000002e0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_13	0x000002e8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_14	0x000002f0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_15	0x000002f8 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_0	0x00000300 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_1	0x00000308 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_2	0x00000310 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_3	0x00000318 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_4	0x00000320 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_5	0x00000328 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_6	0x00000330 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_7	0x00000338 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_8	0x00000340 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_9	0x00000348 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_10	0x00000350 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_11	0x00000358 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_12	0x00000360 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_13	0x00000368 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_14	0x00000370 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_15	0x00000378 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_0	0x00000380 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_1	0x00000388 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_2	0x00000390 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_3	0x00000398 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_4	0x000003a0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_5	0x000003a8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_6	0x000003b0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_7	0x000003b8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_8	0x000003c0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_9	0x000003c8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_10	0x000003d0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_11	0x000003d8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_12	0x000003e0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_13	0x000003e8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_14	0x000003f0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_15	0x000003f8 /* 64-bit */
+
+/* MAC control registers */
+#define MAC_MODE			0x00000400
+#define  MAC_MODE_RESET			 0x00000001
+#define  MAC_MODE_HALF_DUPLEX		 0x00000002
+#define  MAC_MODE_PORT_MODE_MASK	 0x0000000c
+#define  MAC_MODE_PORT_MODE_TBI		 0x0000000c
+#define  MAC_MODE_PORT_MODE_GMII	 0x00000008
+#define  MAC_MODE_PORT_MODE_MII		 0x00000004
+#define  MAC_MODE_PORT_MODE_NONE	 0x00000000
+#define  MAC_MODE_PORT_INT_LPBACK	 0x00000010
+#define  MAC_MODE_TAGGED_MAC_CTRL	 0x00000080
+#define  MAC_MODE_TX_BURSTING		 0x00000100
+#define  MAC_MODE_MAX_DEFER		 0x00000200
+#define  MAC_MODE_LINK_POLARITY		 0x00000400
+#define  MAC_MODE_RXSTAT_ENABLE		 0x00000800
+#define  MAC_MODE_RXSTAT_CLEAR		 0x00001000
+#define  MAC_MODE_RXSTAT_FLUSH		 0x00002000
+#define  MAC_MODE_TXSTAT_ENABLE		 0x00004000
+#define  MAC_MODE_TXSTAT_CLEAR		 0x00008000
+#define  MAC_MODE_TXSTAT_FLUSH		 0x00010000
+#define  MAC_MODE_SEND_CONFIGS		 0x00020000
+#define  MAC_MODE_MAGIC_PKT_ENABLE	 0x00040000
+#define  MAC_MODE_ACPI_ENABLE		 0x00080000
+#define  MAC_MODE_MIP_ENABLE		 0x00100000
+#define  MAC_MODE_TDE_ENABLE		 0x00200000
+#define  MAC_MODE_RDE_ENABLE		 0x00400000
+#define  MAC_MODE_FHDE_ENABLE		 0x00800000
+#define MAC_STATUS			0x00000404
+#define  MAC_STATUS_PCS_SYNCED		 0x00000001
+#define  MAC_STATUS_SIGNAL_DET		 0x00000002
+#define  MAC_STATUS_RCVD_CFG		 0x00000004
+#define  MAC_STATUS_CFG_CHANGED		 0x00000008
+#define  MAC_STATUS_SYNC_CHANGED	 0x00000010
+#define  MAC_STATUS_PORT_DEC_ERR	 0x00000400
+#define  MAC_STATUS_LNKSTATE_CHANGED	 0x00001000
+#define  MAC_STATUS_MI_COMPLETION	 0x00400000
+#define  MAC_STATUS_MI_INTERRUPT	 0x00800000
+#define  MAC_STATUS_AP_ERROR		 0x01000000
+#define  MAC_STATUS_ODI_ERROR		 0x02000000
+#define  MAC_STATUS_RXSTAT_OVERRUN	 0x04000000
+#define  MAC_STATUS_TXSTAT_OVERRUN	 0x08000000
+#define MAC_EVENT			0x00000408
+#define  MAC_EVENT_PORT_DECODE_ERR	 0x00000400
+#define  MAC_EVENT_LNKSTATE_CHANGED	 0x00001000
+#define  MAC_EVENT_MI_COMPLETION	 0x00400000
+#define  MAC_EVENT_MI_INTERRUPT		 0x00800000
+#define  MAC_EVENT_AP_ERROR		 0x01000000
+#define  MAC_EVENT_ODI_ERROR		 0x02000000
+#define  MAC_EVENT_RXSTAT_OVERRUN	 0x04000000
+#define  MAC_EVENT_TXSTAT_OVERRUN	 0x08000000
+#define MAC_LED_CTRL			0x0000040c
+#define  LED_CTRL_LNKLED_OVERRIDE	 0x00000001
+#define  LED_CTRL_1000MBPS_ON		 0x00000002
+#define  LED_CTRL_100MBPS_ON		 0x00000004
+#define  LED_CTRL_10MBPS_ON		 0x00000008
+#define  LED_CTRL_TRAFFIC_OVERRIDE	 0x00000010
+#define  LED_CTRL_TRAFFIC_BLINK		 0x00000020
+#define  LED_CTRL_TRAFFIC_LED		 0x00000040
+#define  LED_CTRL_1000MBPS_STATUS	 0x00000080
+#define  LED_CTRL_100MBPS_STATUS	 0x00000100
+#define  LED_CTRL_10MBPS_STATUS		 0x00000200
+#define  LED_CTRL_TRAFFIC_STATUS	 0x00000400
+#define  LED_CTRL_MAC_MODE		 0x00000000
+#define  LED_CTRL_PHY_MODE_1		 0x00000800
+#define  LED_CTRL_PHY_MODE_2		 0x00001000
+#define  LED_CTRL_BLINK_RATE_MASK	 0x7ff80000
+#define  LED_CTRL_BLINK_RATE_SHIFT	 19
+#define  LED_CTRL_BLINK_PER_OVERRIDE	 0x00080000
+#define  LED_CTRL_BLINK_RATE_OVERRIDE	 0x80000000
+#define MAC_ADDR_0_HIGH			0x00000410 /* upper 2 bytes */
+#define MAC_ADDR_0_LOW			0x00000414 /* lower 4 bytes */
+#define MAC_ADDR_1_HIGH			0x00000418 /* upper 2 bytes */
+#define MAC_ADDR_1_LOW			0x0000041c /* lower 4 bytes */
+#define MAC_ADDR_2_HIGH			0x00000420 /* upper 2 bytes */
+#define MAC_ADDR_2_LOW			0x00000424 /* lower 4 bytes */
+#define MAC_ADDR_3_HIGH			0x00000428 /* upper 2 bytes */
+#define MAC_ADDR_3_LOW			0x0000042c /* lower 4 bytes */
+#define MAC_ACPI_MBUF_PTR		0x00000430
+#define MAC_ACPI_LEN_OFFSET		0x00000434
+#define  ACPI_LENOFF_LEN_MASK		 0x0000ffff
+#define  ACPI_LENOFF_LEN_SHIFT		 0
+#define  ACPI_LENOFF_OFF_MASK		 0x0fff0000
+#define  ACPI_LENOFF_OFF_SHIFT		 16
+#define MAC_TX_BACKOFF_SEED		0x00000438
+#define  TX_BACKOFF_SEED_MASK		 0x000003ff
+#define MAC_RX_MTU_SIZE			0x0000043c
+#define  RX_MTU_SIZE_MASK		 0x0000ffff
+#define MAC_PCS_TEST			0x00000440
+#define  PCS_TEST_PATTERN_MASK		 0x000fffff
+#define  PCS_TEST_PATTERN_SHIFT		 0
+#define  PCS_TEST_ENABLE		 0x00100000
+#define MAC_TX_AUTO_NEG			0x00000444
+#define  TX_AUTO_NEG_MASK		 0x0000ffff
+#define  TX_AUTO_NEG_SHIFT		 0
+#define MAC_RX_AUTO_NEG			0x00000448
+#define  RX_AUTO_NEG_MASK		 0x0000ffff
+#define  RX_AUTO_NEG_SHIFT		 0
+#define MAC_MI_COM			0x0000044c
+#define  MI_COM_CMD_MASK		 0x0c000000
+#define  MI_COM_CMD_WRITE		 0x04000000
+#define  MI_COM_CMD_READ		 0x08000000
+#define  MI_COM_READ_FAILED		 0x10000000
+#define  MI_COM_START			 0x20000000
+#define  MI_COM_BUSY			 0x20000000
+#define  MI_COM_PHY_ADDR_MASK		 0x03e00000
+#define  MI_COM_PHY_ADDR_SHIFT		 21
+#define  MI_COM_REG_ADDR_MASK		 0x001f0000
+#define  MI_COM_REG_ADDR_SHIFT		 16
+#define  MI_COM_DATA_MASK		 0x0000ffff
+#define MAC_MI_STAT			0x00000450
+#define  MAC_MI_STAT_LNKSTAT_ATTN_ENAB	 0x00000001
+#define MAC_MI_MODE			0x00000454
+#define  MAC_MI_MODE_CLK_10MHZ		 0x00000001
+#define  MAC_MI_MODE_SHORT_PREAMBLE	 0x00000002
+#define  MAC_MI_MODE_AUTO_POLL		 0x00000010
+#define  MAC_MI_MODE_CORE_CLK_62MHZ	 0x00008000
+#define  MAC_MI_MODE_BASE		 0x000c0000 /* XXX magic values XXX */
+#define MAC_AUTO_POLL_STATUS		0x00000458
+#define  MAC_AUTO_POLL_ERROR		 0x00000001
+#define MAC_TX_MODE			0x0000045c
+#define  TX_MODE_RESET			 0x00000001
+#define  TX_MODE_ENABLE			 0x00000002
+#define  TX_MODE_FLOW_CTRL_ENABLE	 0x00000010
+#define  TX_MODE_BIG_BCKOFF_ENABLE	 0x00000020
+#define  TX_MODE_LONG_PAUSE_ENABLE	 0x00000040
+#define MAC_TX_STATUS			0x00000460
+#define  TX_STATUS_XOFFED		 0x00000001
+#define  TX_STATUS_SENT_XOFF		 0x00000002
+#define  TX_STATUS_SENT_XON		 0x00000004
+#define  TX_STATUS_LINK_UP		 0x00000008
+#define  TX_STATUS_ODI_UNDERRUN		 0x00000010
+#define  TX_STATUS_ODI_OVERRUN		 0x00000020
+#define MAC_TX_LENGTHS			0x00000464
+#define  TX_LENGTHS_SLOT_TIME_MASK	 0x000000ff
+#define  TX_LENGTHS_SLOT_TIME_SHIFT	 0
+#define  TX_LENGTHS_IPG_MASK		 0x00000f00
+#define  TX_LENGTHS_IPG_SHIFT		 8
+#define  TX_LENGTHS_IPG_CRS_MASK	 0x00003000
+#define  TX_LENGTHS_IPG_CRS_SHIFT	 12
+#define MAC_RX_MODE			0x00000468
+#define  RX_MODE_RESET			 0x00000001
+#define  RX_MODE_ENABLE			 0x00000002
+#define  RX_MODE_FLOW_CTRL_ENABLE	 0x00000004
+#define  RX_MODE_KEEP_MAC_CTRL		 0x00000008
+#define  RX_MODE_KEEP_PAUSE		 0x00000010
+#define  RX_MODE_ACCEPT_OVERSIZED	 0x00000020
+#define  RX_MODE_ACCEPT_RUNTS		 0x00000040
+#define  RX_MODE_LEN_CHECK		 0x00000080
+#define  RX_MODE_PROMISC		 0x00000100
+#define  RX_MODE_NO_CRC_CHECK		 0x00000200
+#define  RX_MODE_KEEP_VLAN_TAG		 0x00000400
+#define MAC_RX_STATUS			0x0000046c
+#define  RX_STATUS_REMOTE_TX_XOFFED	 0x00000001
+#define  RX_STATUS_XOFF_RCVD		 0x00000002
+#define  RX_STATUS_XON_RCVD		 0x00000004
+#define MAC_HASH_REG_0			0x00000470
+#define MAC_HASH_REG_1			0x00000474
+#define MAC_HASH_REG_2			0x00000478
+#define MAC_HASH_REG_3			0x0000047c
+#define MAC_RCV_RULE_0			0x00000480
+#define MAC_RCV_VALUE_0			0x00000484
+#define MAC_RCV_RULE_1			0x00000488
+#define MAC_RCV_VALUE_1			0x0000048c
+#define MAC_RCV_RULE_2			0x00000490
+#define MAC_RCV_VALUE_2			0x00000494
+#define MAC_RCV_RULE_3			0x00000498
+#define MAC_RCV_VALUE_3			0x0000049c
+#define MAC_RCV_RULE_4			0x000004a0
+#define MAC_RCV_VALUE_4			0x000004a4
+#define MAC_RCV_RULE_5			0x000004a8
+#define MAC_RCV_VALUE_5			0x000004ac
+#define MAC_RCV_RULE_6			0x000004b0
+#define MAC_RCV_VALUE_6			0x000004b4
+#define MAC_RCV_RULE_7			0x000004b8
+#define MAC_RCV_VALUE_7			0x000004bc
+#define MAC_RCV_RULE_8			0x000004c0
+#define MAC_RCV_VALUE_8			0x000004c4
+#define MAC_RCV_RULE_9			0x000004c8
+#define MAC_RCV_VALUE_9			0x000004cc
+#define MAC_RCV_RULE_10			0x000004d0
+#define MAC_RCV_VALUE_10		0x000004d4
+#define MAC_RCV_RULE_11			0x000004d8
+#define MAC_RCV_VALUE_11		0x000004dc
+#define MAC_RCV_RULE_12			0x000004e0
+#define MAC_RCV_VALUE_12		0x000004e4
+#define MAC_RCV_RULE_13			0x000004e8
+#define MAC_RCV_VALUE_13		0x000004ec
+#define MAC_RCV_RULE_14			0x000004f0
+#define MAC_RCV_VALUE_14		0x000004f4
+#define MAC_RCV_RULE_15			0x000004f8
+#define MAC_RCV_VALUE_15		0x000004fc
+#define  RCV_RULE_DISABLE_MASK		 0x7fffffff
+#define MAC_RCV_RULE_CFG		0x00000500
+#define  RCV_RULE_CFG_DEFAULT_CLASS	0x00000008
+/* 0x504 --> 0x590 unused */
+#define MAC_SERDES_CFG			0x00000590
+#define MAC_SERDES_STAT			0x00000594
+/* 0x598 --> 0x600 unused */
+#define MAC_TX_MAC_STATE_BASE		0x00000600 /* 16 bytes */
+#define MAC_RX_MAC_STATE_BASE		0x00000610 /* 20 bytes */
+/* 0x624 --> 0x800 unused */
+#define MAC_RX_STATS_BASE		0x00000800 /* 26 32-bit words */
+/* 0x868 --> 0x880 unused */
+#define MAC_TX_STATS_BASE		0x00000880 /* 28 32-bit words */
+/* 0x8f0 --> 0xc00 unused */
+
+/* Send data initiator control registers */
+#define SNDDATAI_MODE			0x00000c00
+#define  SNDDATAI_MODE_RESET		 0x00000001
+#define  SNDDATAI_MODE_ENABLE		 0x00000002
+#define  SNDDATAI_MODE_STAT_OFLOW_ENAB	 0x00000004
+#define SNDDATAI_STATUS			0x00000c04
+#define  SNDDATAI_STATUS_STAT_OFLOW	 0x00000004
+#define SNDDATAI_STATSCTRL		0x00000c08
+#define  SNDDATAI_SCTRL_ENABLE		 0x00000001
+#define  SNDDATAI_SCTRL_FASTUPD		 0x00000002
+#define  SNDDATAI_SCTRL_CLEAR		 0x00000004
+#define  SNDDATAI_SCTRL_FLUSH		 0x00000008
+#define  SNDDATAI_SCTRL_FORCE_ZERO	 0x00000010
+#define SNDDATAI_STATSENAB		0x00000c0c
+#define SNDDATAI_STATSINCMASK		0x00000c10
+/* 0xc14 --> 0xc80 unused */
+#define SNDDATAI_COS_CNT_0		0x00000c80
+#define SNDDATAI_COS_CNT_1		0x00000c84
+#define SNDDATAI_COS_CNT_2		0x00000c88
+#define SNDDATAI_COS_CNT_3		0x00000c8c
+#define SNDDATAI_COS_CNT_4		0x00000c90
+#define SNDDATAI_COS_CNT_5		0x00000c94
+#define SNDDATAI_COS_CNT_6		0x00000c98
+#define SNDDATAI_COS_CNT_7		0x00000c9c
+#define SNDDATAI_COS_CNT_8		0x00000ca0
+#define SNDDATAI_COS_CNT_9		0x00000ca4
+#define SNDDATAI_COS_CNT_10		0x00000ca8
+#define SNDDATAI_COS_CNT_11		0x00000cac
+#define SNDDATAI_COS_CNT_12		0x00000cb0
+#define SNDDATAI_COS_CNT_13		0x00000cb4
+#define SNDDATAI_COS_CNT_14		0x00000cb8
+#define SNDDATAI_COS_CNT_15		0x00000cbc
+#define SNDDATAI_DMA_RDQ_FULL_CNT	0x00000cc0
+#define SNDDATAI_DMA_PRIO_RDQ_FULL_CNT	0x00000cc4
+#define SNDDATAI_SDCQ_FULL_CNT		0x00000cc8
+#define SNDDATAI_NICRNG_SSND_PIDX_CNT	0x00000ccc
+#define SNDDATAI_STATS_UPDATED_CNT	0x00000cd0
+#define SNDDATAI_INTERRUPTS_CNT		0x00000cd4
+#define SNDDATAI_AVOID_INTERRUPTS_CNT	0x00000cd8
+#define SNDDATAI_SND_THRESH_HIT_CNT	0x00000cdc
+/* 0xce0 --> 0x1000 unused */
+
+/* Send data completion control registers */
+#define SNDDATAC_MODE			0x00001000
+#define  SNDDATAC_MODE_RESET		 0x00000001
+#define  SNDDATAC_MODE_ENABLE		 0x00000002
+/* 0x1004 --> 0x1400 unused */
+
+/* Send BD ring selector */
+#define SNDBDS_MODE			0x00001400
+#define  SNDBDS_MODE_RESET		 0x00000001
+#define  SNDBDS_MODE_ENABLE		 0x00000002
+#define  SNDBDS_MODE_ATTN_ENABLE	 0x00000004
+#define SNDBDS_STATUS			0x00001404
+#define  SNDBDS_STATUS_ERROR_ATTN	 0x00000004
+#define SNDBDS_HWDIAG			0x00001408
+/* 0x140c --> 0x1440 */
+#define SNDBDS_SEL_CON_IDX_0		0x00001440
+#define SNDBDS_SEL_CON_IDX_1		0x00001444
+#define SNDBDS_SEL_CON_IDX_2		0x00001448
+#define SNDBDS_SEL_CON_IDX_3		0x0000144c
+#define SNDBDS_SEL_CON_IDX_4		0x00001450
+#define SNDBDS_SEL_CON_IDX_5		0x00001454
+#define SNDBDS_SEL_CON_IDX_6		0x00001458
+#define SNDBDS_SEL_CON_IDX_7		0x0000145c
+#define SNDBDS_SEL_CON_IDX_8		0x00001460
+#define SNDBDS_SEL_CON_IDX_9		0x00001464
+#define SNDBDS_SEL_CON_IDX_10		0x00001468
+#define SNDBDS_SEL_CON_IDX_11		0x0000146c
+#define SNDBDS_SEL_CON_IDX_12		0x00001470
+#define SNDBDS_SEL_CON_IDX_13		0x00001474
+#define SNDBDS_SEL_CON_IDX_14		0x00001478
+#define SNDBDS_SEL_CON_IDX_15		0x0000147c
+/* 0x1480 --> 0x1800 unused */
+
+/* Send BD initiator control registers */
+#define SNDBDI_MODE			0x00001800
+#define  SNDBDI_MODE_RESET		 0x00000001
+#define  SNDBDI_MODE_ENABLE		 0x00000002
+#define  SNDBDI_MODE_ATTN_ENABLE	 0x00000004
+#define SNDBDI_STATUS			0x00001804
+#define  SNDBDI_STATUS_ERROR_ATTN	 0x00000004
+#define SNDBDI_IN_PROD_IDX_0		0x00001808
+#define SNDBDI_IN_PROD_IDX_1		0x0000180c
+#define SNDBDI_IN_PROD_IDX_2		0x00001810
+#define SNDBDI_IN_PROD_IDX_3		0x00001814
+#define SNDBDI_IN_PROD_IDX_4		0x00001818
+#define SNDBDI_IN_PROD_IDX_5		0x0000181c
+#define SNDBDI_IN_PROD_IDX_6		0x00001820
+#define SNDBDI_IN_PROD_IDX_7		0x00001824
+#define SNDBDI_IN_PROD_IDX_8		0x00001828
+#define SNDBDI_IN_PROD_IDX_9		0x0000182c
+#define SNDBDI_IN_PROD_IDX_10		0x00001830
+#define SNDBDI_IN_PROD_IDX_11		0x00001834
+#define SNDBDI_IN_PROD_IDX_12		0x00001838
+#define SNDBDI_IN_PROD_IDX_13		0x0000183c
+#define SNDBDI_IN_PROD_IDX_14		0x00001840
+#define SNDBDI_IN_PROD_IDX_15		0x00001844
+/* 0x1848 --> 0x1c00 unused */
+
+/* Send BD completion control registers */
+#define SNDBDC_MODE			0x00001c00
+#define SNDBDC_MODE_RESET		 0x00000001
+#define SNDBDC_MODE_ENABLE		 0x00000002
+#define SNDBDC_MODE_ATTN_ENABLE		 0x00000004
+/* 0x1c04 --> 0x2000 unused */
+
+/* Receive list placement control registers */
+#define RCVLPC_MODE			0x00002000
+#define  RCVLPC_MODE_RESET		 0x00000001
+#define  RCVLPC_MODE_ENABLE		 0x00000002
+#define  RCVLPC_MODE_CLASS0_ATTN_ENAB	 0x00000004
+#define  RCVLPC_MODE_MAPOOR_AATTN_ENAB	 0x00000008
+#define  RCVLPC_MODE_STAT_OFLOW_ENAB	 0x00000010
+#define RCVLPC_STATUS			0x00002004
+#define  RCVLPC_STATUS_CLASS0		 0x00000004
+#define  RCVLPC_STATUS_MAPOOR		 0x00000008
+#define  RCVLPC_STATUS_STAT_OFLOW	 0x00000010
+#define RCVLPC_LOCK			0x00002008
+#define  RCVLPC_LOCK_REQ_MASK		 0x0000ffff
+#define  RCVLPC_LOCK_REQ_SHIFT		 0
+#define  RCVLPC_LOCK_GRANT_MASK		 0xffff0000
+#define  RCVLPC_LOCK_GRANT_SHIFT	 16
+#define RCVLPC_NON_EMPTY_BITS		0x0000200c
+#define  RCVLPC_NON_EMPTY_BITS_MASK	 0x0000ffff
+#define RCVLPC_CONFIG			0x00002010
+#define RCVLPC_STATSCTRL		0x00002014
+#define  RCVLPC_STATSCTRL_ENABLE	 0x00000001
+#define  RCVLPC_STATSCTRL_FASTUPD	 0x00000002
+#define RCVLPC_STATS_ENABLE		0x00002018
+#define RCVLPC_STATS_INCMASK		0x0000201c
+/* 0x2020 --> 0x2100 unused */
+#define RCVLPC_SELLST_BASE		0x00002100 /* 16 16-byte entries */
+#define  SELLST_TAIL			0x00000004
+#define  SELLST_CONT			0x00000008
+#define  SELLST_UNUSED			0x0000000c
+#define RCVLPC_COS_CNTL_BASE		0x00002200 /* 16 4-byte entries */
+#define RCVLPC_DROP_FILTER_CNT		0x00002240
+#define RCVLPC_DMA_WQ_FULL_CNT		0x00002244
+#define RCVLPC_DMA_HIPRIO_WQ_FULL_CNT	0x00002248
+#define RCVLPC_NO_RCV_BD_CNT		0x0000224c
+#define RCVLPC_IN_DISCARDS_CNT		0x00002250
+#define RCVLPC_IN_ERRORS_CNT		0x00002254
+#define RCVLPC_RCV_THRESH_HIT_CNT	0x00002258
+/* 0x225c --> 0x2400 unused */
+
+/* Receive Data and Receive BD Initiator Control */
+#define RCVDBDI_MODE			0x00002400
+#define  RCVDBDI_MODE_RESET		 0x00000001
+#define  RCVDBDI_MODE_ENABLE		 0x00000002
+#define  RCVDBDI_MODE_JUMBOBD_NEEDED	 0x00000004
+#define  RCVDBDI_MODE_FRM_TOO_BIG	 0x00000008
+#define  RCVDBDI_MODE_INV_RING_SZ	 0x00000010
+#define RCVDBDI_STATUS			0x00002404
+#define  RCVDBDI_STATUS_JUMBOBD_NEEDED	 0x00000004
+#define  RCVDBDI_STATUS_FRM_TOO_BIG	 0x00000008
+#define  RCVDBDI_STATUS_INV_RING_SZ	 0x00000010
+#define RCVDBDI_SPLIT_FRAME_MINSZ	0x00002408
+/* 0x240c --> 0x2440 unused */
+#define RCVDBDI_JUMBO_BD		0x00002440 /* TG3_BDINFO_... */
+#define RCVDBDI_STD_BD			0x00002450 /* TG3_BDINFO_... */
+#define RCVDBDI_MINI_BD			0x00002460 /* TG3_BDINFO_... */
+#define RCVDBDI_JUMBO_CON_IDX		0x00002470
+#define RCVDBDI_STD_CON_IDX		0x00002474
+#define RCVDBDI_MINI_CON_IDX		0x00002478
+/* 0x247c --> 0x2480 unused */
+#define RCVDBDI_BD_PROD_IDX_0		0x00002480
+#define RCVDBDI_BD_PROD_IDX_1		0x00002484
+#define RCVDBDI_BD_PROD_IDX_2		0x00002488
+#define RCVDBDI_BD_PROD_IDX_3		0x0000248c
+#define RCVDBDI_BD_PROD_IDX_4		0x00002490
+#define RCVDBDI_BD_PROD_IDX_5		0x00002494
+#define RCVDBDI_BD_PROD_IDX_6		0x00002498
+#define RCVDBDI_BD_PROD_IDX_7		0x0000249c
+#define RCVDBDI_BD_PROD_IDX_8		0x000024a0
+#define RCVDBDI_BD_PROD_IDX_9		0x000024a4
+#define RCVDBDI_BD_PROD_IDX_10		0x000024a8
+#define RCVDBDI_BD_PROD_IDX_11		0x000024ac
+#define RCVDBDI_BD_PROD_IDX_12		0x000024b0
+#define RCVDBDI_BD_PROD_IDX_13		0x000024b4
+#define RCVDBDI_BD_PROD_IDX_14		0x000024b8
+#define RCVDBDI_BD_PROD_IDX_15		0x000024bc
+#define RCVDBDI_HWDIAG			0x000024c0
+/* 0x24c4 --> 0x2800 unused */
+
+/* Receive Data Completion Control */
+#define RCVDCC_MODE			0x00002800
+#define  RCVDCC_MODE_RESET		 0x00000001
+#define  RCVDCC_MODE_ENABLE		 0x00000002
+#define  RCVDCC_MODE_ATTN_ENABLE	 0x00000004
+/* 0x2804 --> 0x2c00 unused */
+
+/* Receive BD Initiator Control Registers */
+#define RCVBDI_MODE			0x00002c00
+#define  RCVBDI_MODE_RESET		 0x00000001
+#define  RCVBDI_MODE_ENABLE		 0x00000002
+#define  RCVBDI_MODE_RCB_ATTN_ENAB	 0x00000004
+#define RCVBDI_STATUS			0x00002c04
+#define  RCVBDI_STATUS_RCB_ATTN		 0x00000004
+#define RCVBDI_JUMBO_PROD_IDX		0x00002c08
+#define RCVBDI_STD_PROD_IDX		0x00002c0c
+#define RCVBDI_MINI_PROD_IDX		0x00002c10
+#define RCVBDI_MINI_THRESH		0x00002c14
+#define RCVBDI_STD_THRESH		0x00002c18
+#define RCVBDI_JUMBO_THRESH		0x00002c1c
+/* 0x2c20 --> 0x3000 unused */
+
+/* Receive BD Completion Control Registers */
+#define RCVCC_MODE			0x00003000
+#define  RCVCC_MODE_RESET		 0x00000001
+#define  RCVCC_MODE_ENABLE		 0x00000002
+#define  RCVCC_MODE_ATTN_ENABLE		 0x00000004
+#define RCVCC_STATUS			0x00003004
+#define  RCVCC_STATUS_ERROR_ATTN	 0x00000004
+#define RCVCC_JUMP_PROD_IDX		0x00003008
+#define RCVCC_STD_PROD_IDX		0x0000300c
+#define RCVCC_MINI_PROD_IDX		0x00003010
+/* 0x3014 --> 0x3400 unused */
+
+/* Receive list selector control registers */
+#define RCVLSC_MODE			0x00003400
+#define  RCVLSC_MODE_RESET		 0x00000001
+#define  RCVLSC_MODE_ENABLE		 0x00000002
+#define  RCVLSC_MODE_ATTN_ENABLE	 0x00000004
+#define RCVLSC_STATUS			0x00003404
+#define  RCVLSC_STATUS_ERROR_ATTN	 0x00000004
+/* 0x3408 --> 0x3800 unused */
+
+/* Mbuf cluster free registers */
+#define MBFREE_MODE			0x00003800
+#define  MBFREE_MODE_RESET		 0x00000001
+#define  MBFREE_MODE_ENABLE		 0x00000002
+#define MBFREE_STATUS			0x00003804
+/* 0x3808 --> 0x3c00 unused */
+
+/* Host coalescing control registers */
+#define HOSTCC_MODE			0x00003c00
+#define  HOSTCC_MODE_RESET		 0x00000001
+#define  HOSTCC_MODE_ENABLE		 0x00000002
+#define  HOSTCC_MODE_ATTN		 0x00000004
+#define  HOSTCC_MODE_NOW		 0x00000008
+#define  HOSTCC_MODE_FULL_STATUS	 0x00000000
+#define  HOSTCC_MODE_64BYTE		 0x00000080
+#define  HOSTCC_MODE_32BYTE		 0x00000100
+#define  HOSTCC_MODE_CLRTICK_RXBD	 0x00000200
+#define  HOSTCC_MODE_CLRTICK_TXBD	 0x00000400
+#define  HOSTCC_MODE_NOINT_ON_NOW	 0x00000800
+#define  HOSTCC_MODE_NOINT_ON_FORCE	 0x00001000
+#define HOSTCC_STATUS			0x00003c04
+#define  HOSTCC_STATUS_ERROR_ATTN	 0x00000004
+#define HOSTCC_RXCOL_TICKS		0x00003c08
+#define  LOW_RXCOL_TICKS		 0x00000032
+#define  DEFAULT_RXCOL_TICKS		 0x00000048
+#define  HIGH_RXCOL_TICKS		 0x00000096
+#define HOSTCC_TXCOL_TICKS		0x00003c0c
+#define  LOW_TXCOL_TICKS		 0x00000096
+#define  DEFAULT_TXCOL_TICKS		 0x0000012c
+#define  HIGH_TXCOL_TICKS		 0x00000145
+#define HOSTCC_RXMAX_FRAMES		0x00003c10
+#define  LOW_RXMAX_FRAMES		 0x00000005
+#define  DEFAULT_RXMAX_FRAMES		 0x00000008
+#define  HIGH_RXMAX_FRAMES		 0x00000012
+#define HOSTCC_TXMAX_FRAMES		0x00003c14
+#define  LOW_TXMAX_FRAMES		 0x00000035
+#define  DEFAULT_TXMAX_FRAMES		 0x0000004b
+#define  HIGH_TXMAX_FRAMES		 0x00000052
+#define HOSTCC_RXCOAL_TICK_INT		0x00003c18
+#define  DEFAULT_RXCOAL_TICK_INT	 0x00000019
+#define HOSTCC_TXCOAL_TICK_INT		0x00003c1c
+#define  DEFAULT_TXCOAL_TICK_INT	 0x00000019
+#define HOSTCC_RXCOAL_MAXF_INT		0x00003c20
+#define  DEFAULT_RXCOAL_MAXF_INT	 0x00000005
+#define HOSTCC_TXCOAL_MAXF_INT		0x00003c24
+#define  DEFAULT_TXCOAL_MAXF_INT	 0x00000005
+#define HOSTCC_STAT_COAL_TICKS		0x00003c28
+#define  DEFAULT_STAT_COAL_TICKS	 0x000f4240
+/* 0x3c2c --> 0x3c30 unused */
+#define HOSTCC_STATS_BLK_HOST_ADDR	0x00003c30 /* 64-bit */
+#define HOSTCC_STATUS_BLK_HOST_ADDR	0x00003c38 /* 64-bit */
+#define HOSTCC_STATS_BLK_NIC_ADDR	0x00003c40
+#define HOSTCC_STATUS_BLK_NIC_ADDR	0x00003c44
+#define HOSTCC_FLOW_ATTN		0x00003c48
+/* 0x3c4c --> 0x3c50 unused */
+#define HOSTCC_JUMBO_CON_IDX		0x00003c50
+#define HOSTCC_STD_CON_IDX		0x00003c54
+#define HOSTCC_MINI_CON_IDX		0x00003c58
+/* 0x3c5c --> 0x3c80 unused */
+#define HOSTCC_RET_PROD_IDX_0		0x00003c80
+#define HOSTCC_RET_PROD_IDX_1		0x00003c84
+#define HOSTCC_RET_PROD_IDX_2		0x00003c88
+#define HOSTCC_RET_PROD_IDX_3		0x00003c8c
+#define HOSTCC_RET_PROD_IDX_4		0x00003c90
+#define HOSTCC_RET_PROD_IDX_5		0x00003c94
+#define HOSTCC_RET_PROD_IDX_6		0x00003c98
+#define HOSTCC_RET_PROD_IDX_7		0x00003c9c
+#define HOSTCC_RET_PROD_IDX_8		0x00003ca0
+#define HOSTCC_RET_PROD_IDX_9		0x00003ca4
+#define HOSTCC_RET_PROD_IDX_10		0x00003ca8
+#define HOSTCC_RET_PROD_IDX_11		0x00003cac
+#define HOSTCC_RET_PROD_IDX_12		0x00003cb0
+#define HOSTCC_RET_PROD_IDX_13		0x00003cb4
+#define HOSTCC_RET_PROD_IDX_14		0x00003cb8
+#define HOSTCC_RET_PROD_IDX_15		0x00003cbc
+#define HOSTCC_SND_CON_IDX_0		0x00003cc0
+#define HOSTCC_SND_CON_IDX_1		0x00003cc4
+#define HOSTCC_SND_CON_IDX_2		0x00003cc8
+#define HOSTCC_SND_CON_IDX_3		0x00003ccc
+#define HOSTCC_SND_CON_IDX_4		0x00003cd0
+#define HOSTCC_SND_CON_IDX_5		0x00003cd4
+#define HOSTCC_SND_CON_IDX_6		0x00003cd8
+#define HOSTCC_SND_CON_IDX_7		0x00003cdc
+#define HOSTCC_SND_CON_IDX_8		0x00003ce0
+#define HOSTCC_SND_CON_IDX_9		0x00003ce4
+#define HOSTCC_SND_CON_IDX_10		0x00003ce8
+#define HOSTCC_SND_CON_IDX_11		0x00003cec
+#define HOSTCC_SND_CON_IDX_12		0x00003cf0
+#define HOSTCC_SND_CON_IDX_13		0x00003cf4
+#define HOSTCC_SND_CON_IDX_14		0x00003cf8
+#define HOSTCC_SND_CON_IDX_15		0x00003cfc
+/* 0x3d00 --> 0x4000 unused */
+
+/* Memory arbiter control registers */
+#define MEMARB_MODE			0x00004000
+#define  MEMARB_MODE_RESET		 0x00000001
+#define  MEMARB_MODE_ENABLE		 0x00000002
+#define MEMARB_STATUS			0x00004004
+#define MEMARB_TRAP_ADDR_LOW		0x00004008
+#define MEMARB_TRAP_ADDR_HIGH		0x0000400c
+/* 0x4010 --> 0x4400 unused */
+
+/* Buffer manager control registers */
+#define BUFMGR_MODE			0x00004400
+#define  BUFMGR_MODE_RESET		 0x00000001
+#define  BUFMGR_MODE_ENABLE		 0x00000002
+#define  BUFMGR_MODE_ATTN_ENABLE	 0x00000004
+#define  BUFMGR_MODE_BM_TEST		 0x00000008
+#define  BUFMGR_MODE_MBLOW_ATTN_ENAB	 0x00000010
+#define BUFMGR_STATUS			0x00004404
+#define  BUFMGR_STATUS_ERROR		 0x00000004
+#define  BUFMGR_STATUS_MBLOW		 0x00000010
+#define BUFMGR_MB_POOL_ADDR		0x00004408
+#define BUFMGR_MB_POOL_SIZE		0x0000440c
+#define BUFMGR_MB_RDMA_LOW_WATER	0x00004410
+#define  DEFAULT_MB_RDMA_LOW_WATER	 0x00000040
+#define  DEFAULT_MB_RDMA_LOW_WATER_JUMBO 0x00000130
+#define BUFMGR_MB_MACRX_LOW_WATER	0x00004414
+#define  DEFAULT_MB_MACRX_LOW_WATER	  0x00000020
+#define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098
+#define BUFMGR_MB_HIGH_WATER		0x00004418
+#define  DEFAULT_MB_HIGH_WATER		 0x00000060
+#define  DEFAULT_MB_HIGH_WATER_JUMBO	 0x0000017c
+#define BUFMGR_RX_MB_ALLOC_REQ		0x0000441c
+#define  BUFMGR_MB_ALLOC_BIT		 0x10000000
+#define BUFMGR_RX_MB_ALLOC_RESP		0x00004420
+#define BUFMGR_TX_MB_ALLOC_REQ		0x00004424
+#define BUFMGR_TX_MB_ALLOC_RESP		0x00004428
+#define BUFMGR_DMA_DESC_POOL_ADDR	0x0000442c
+#define BUFMGR_DMA_DESC_POOL_SIZE	0x00004430
+#define BUFMGR_DMA_LOW_WATER		0x00004434
+#define  DEFAULT_DMA_LOW_WATER		 0x00000005
+#define BUFMGR_DMA_HIGH_WATER		0x00004438
+#define  DEFAULT_DMA_HIGH_WATER		 0x0000000a
+#define BUFMGR_RX_DMA_ALLOC_REQ		0x0000443c
+#define BUFMGR_RX_DMA_ALLOC_RESP	0x00004440
+#define BUFMGR_TX_DMA_ALLOC_REQ		0x00004444
+#define BUFMGR_TX_DMA_ALLOC_RESP	0x00004448
+#define BUFMGR_HWDIAG_0			0x0000444c
+#define BUFMGR_HWDIAG_1			0x00004450
+#define BUFMGR_HWDIAG_2			0x00004454
+/* 0x4458 --> 0x4800 unused */
+
+/* Read DMA control registers */
+#define RDMAC_MODE			0x00004800
+#define  RDMAC_MODE_RESET		 0x00000001
+#define  RDMAC_MODE_ENABLE		 0x00000002
+#define  RDMAC_MODE_TGTABORT_ENAB	 0x00000004
+#define  RDMAC_MODE_MSTABORT_ENAB	 0x00000008
+#define  RDMAC_MODE_PARITYERR_ENAB	 0x00000010
+#define  RDMAC_MODE_ADDROFLOW_ENAB	 0x00000020
+#define  RDMAC_MODE_FIFOOFLOW_ENAB	 0x00000040
+#define  RDMAC_MODE_FIFOURUN_ENAB	 0x00000080
+#define  RDMAC_MODE_FIFOOREAD_ENAB	 0x00000100
+#define  RDMAC_MODE_LNGREAD_ENAB	 0x00000200
+#define RDMAC_STATUS			0x00004804
+#define  RDMAC_STATUS_TGTABORT		 0x00000004
+#define  RDMAC_STATUS_MSTABORT		 0x00000008
+#define  RDMAC_STATUS_PARITYERR		 0x00000010
+#define  RDMAC_STATUS_ADDROFLOW		 0x00000020
+#define  RDMAC_STATUS_FIFOOFLOW		 0x00000040
+#define  RDMAC_STATUS_FIFOURUN		 0x00000080
+#define  RDMAC_STATUS_FIFOOREAD		 0x00000100
+#define  RDMAC_STATUS_LNGREAD		 0x00000200
+/* 0x4808 --> 0x4c00 unused */
+
+/* Write DMA control registers */
+#define WDMAC_MODE			0x00004c00
+#define  WDMAC_MODE_RESET		 0x00000001
+#define  WDMAC_MODE_ENABLE		 0x00000002
+#define  WDMAC_MODE_TGTABORT_ENAB	 0x00000004
+#define  WDMAC_MODE_MSTABORT_ENAB	 0x00000008
+#define  WDMAC_MODE_PARITYERR_ENAB	 0x00000010
+#define  WDMAC_MODE_ADDROFLOW_ENAB	 0x00000020
+#define  WDMAC_MODE_FIFOOFLOW_ENAB	 0x00000040
+#define  WDMAC_MODE_FIFOURUN_ENAB	 0x00000080
+#define  WDMAC_MODE_FIFOOREAD_ENAB	 0x00000100
+#define  WDMAC_MODE_LNGREAD_ENAB	 0x00000200
+#define WDMAC_STATUS			0x00004c04
+#define  WDMAC_STATUS_TGTABORT		 0x00000004
+#define  WDMAC_STATUS_MSTABORT		 0x00000008
+#define  WDMAC_STATUS_PARITYERR		 0x00000010
+#define  WDMAC_STATUS_ADDROFLOW		 0x00000020
+#define  WDMAC_STATUS_FIFOOFLOW		 0x00000040
+#define  WDMAC_STATUS_FIFOURUN		 0x00000080
+#define  WDMAC_STATUS_FIFOOREAD		 0x00000100
+#define  WDMAC_STATUS_LNGREAD		 0x00000200
+/* 0x4c08 --> 0x5000 unused */
+
+/* Per-cpu register offsets (arm9) */
+#define CPU_MODE			0x00000000
+#define  CPU_MODE_RESET			 0x00000001
+#define  CPU_MODE_HALT			 0x00000400
+#define CPU_STATE			0x00000004
+#define CPU_EVTMASK			0x00000008
+/* 0xc --> 0x1c reserved */
+#define CPU_PC				0x0000001c
+#define CPU_INSN			0x00000020
+#define CPU_SPAD_UFLOW			0x00000024
+#define CPU_WDOG_CLEAR			0x00000028
+#define CPU_WDOG_VECTOR			0x0000002c
+#define CPU_WDOG_PC			0x00000030
+#define CPU_HW_BP			0x00000034
+/* 0x38 --> 0x44 unused */
+#define CPU_WDOG_SAVED_STATE		0x00000044
+#define CPU_LAST_BRANCH_ADDR		0x00000048
+#define CPU_SPAD_UFLOW_SET		0x0000004c
+/* 0x50 --> 0x200 unused */
+#define CPU_R0				0x00000200
+#define CPU_R1				0x00000204
+#define CPU_R2				0x00000208
+#define CPU_R3				0x0000020c
+#define CPU_R4				0x00000210
+#define CPU_R5				0x00000214
+#define CPU_R6				0x00000218
+#define CPU_R7				0x0000021c
+#define CPU_R8				0x00000220
+#define CPU_R9				0x00000224
+#define CPU_R10				0x00000228
+#define CPU_R11				0x0000022c
+#define CPU_R12				0x00000230
+#define CPU_R13				0x00000234
+#define CPU_R14				0x00000238
+#define CPU_R15				0x0000023c
+#define CPU_R16				0x00000240
+#define CPU_R17				0x00000244
+#define CPU_R18				0x00000248
+#define CPU_R19				0x0000024c
+#define CPU_R20				0x00000250
+#define CPU_R21				0x00000254
+#define CPU_R22				0x00000258
+#define CPU_R23				0x0000025c
+#define CPU_R24				0x00000260
+#define CPU_R25				0x00000264
+#define CPU_R26				0x00000268
+#define CPU_R27				0x0000026c
+#define CPU_R28				0x00000270
+#define CPU_R29				0x00000274
+#define CPU_R30				0x00000278
+#define CPU_R31				0x0000027c
+/* 0x280 --> 0x400 unused */
+
+#define RX_CPU_BASE			0x00005000
+#define TX_CPU_BASE			0x00005400
+
+/* Mailboxes */
+#define GRCMBOX_INTERRUPT_0		0x00005800 /* 64-bit */
+#define GRCMBOX_INTERRUPT_1		0x00005808 /* 64-bit */
+#define GRCMBOX_INTERRUPT_2		0x00005810 /* 64-bit */
+#define GRCMBOX_INTERRUPT_3		0x00005818 /* 64-bit */
+#define GRCMBOX_GENERAL_0		0x00005820 /* 64-bit */
+#define GRCMBOX_GENERAL_1		0x00005828 /* 64-bit */
+#define GRCMBOX_GENERAL_2		0x00005830 /* 64-bit */
+#define GRCMBOX_GENERAL_3		0x00005838 /* 64-bit */
+#define GRCMBOX_GENERAL_4		0x00005840 /* 64-bit */
+#define GRCMBOX_GENERAL_5		0x00005848 /* 64-bit */
+#define GRCMBOX_GENERAL_6		0x00005850 /* 64-bit */
+#define GRCMBOX_GENERAL_7		0x00005858 /* 64-bit */
+#define GRCMBOX_RELOAD_STAT		0x00005860 /* 64-bit */
+#define GRCMBOX_RCVSTD_PROD_IDX		0x00005868 /* 64-bit */
+#define GRCMBOX_RCVJUMBO_PROD_IDX	0x00005870 /* 64-bit */
+#define GRCMBOX_RCVMINI_PROD_IDX	0x00005878 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_0	0x00005880 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_1	0x00005888 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_2	0x00005890 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_3	0x00005898 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_4	0x000058a0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_5	0x000058a8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_6	0x000058b0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_7	0x000058b8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_8	0x000058c0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_9	0x000058c8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_10	0x000058d0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_11	0x000058d8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_12	0x000058e0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_13	0x000058e8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_14	0x000058f0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_15	0x000058f8 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_0	0x00005900 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_1	0x00005908 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_2	0x00005910 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_3	0x00005918 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_4	0x00005920 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_5	0x00005928 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_6	0x00005930 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_7	0x00005938 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_8	0x00005940 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_9	0x00005948 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_10	0x00005950 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_11	0x00005958 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_12	0x00005960 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_13	0x00005968 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_14	0x00005970 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_15	0x00005978 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_0	0x00005980 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_1	0x00005988 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_2	0x00005990 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_3	0x00005998 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_4	0x000059a0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_5	0x000059a8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_6	0x000059b0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_7	0x000059b8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_8	0x000059c0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_9	0x000059c8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_10	0x000059d0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_11	0x000059d8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_12	0x000059e0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_13	0x000059e8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_14	0x000059f0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_15	0x000059f8 /* 64-bit */
+#define GRCMBOX_HIGH_PRIO_EV_VECTOR	0x00005a00
+#define GRCMBOX_HIGH_PRIO_EV_MASK	0x00005a04
+#define GRCMBOX_LOW_PRIO_EV_VEC		0x00005a08
+#define GRCMBOX_LOW_PRIO_EV_MASK	0x00005a0c
+/* 0x5a10 --> 0x5c00 */
+
+/* Flow Through queues */
+#define FTQ_RESET			0x00005c00
+/* 0x5c04 --> 0x5c10 unused */
+#define FTQ_DMA_NORM_READ_CTL		0x00005c10
+#define FTQ_DMA_NORM_READ_FULL_CNT	0x00005c14
+#define FTQ_DMA_NORM_READ_FIFO_ENQDEQ	0x00005c18
+#define FTQ_DMA_NORM_READ_WRITE_PEEK	0x00005c1c
+#define FTQ_DMA_HIGH_READ_CTL		0x00005c20
+#define FTQ_DMA_HIGH_READ_FULL_CNT	0x00005c24
+#define FTQ_DMA_HIGH_READ_FIFO_ENQDEQ	0x00005c28
+#define FTQ_DMA_HIGH_READ_WRITE_PEEK	0x00005c2c
+#define FTQ_DMA_COMP_DISC_CTL		0x00005c30
+#define FTQ_DMA_COMP_DISC_FULL_CNT	0x00005c34
+#define FTQ_DMA_COMP_DISC_FIFO_ENQDEQ	0x00005c38
+#define FTQ_DMA_COMP_DISC_WRITE_PEEK	0x00005c3c
+#define FTQ_SEND_BD_COMP_CTL		0x00005c40
+#define FTQ_SEND_BD_COMP_FULL_CNT	0x00005c44
+#define FTQ_SEND_BD_COMP_FIFO_ENQDEQ	0x00005c48
+#define FTQ_SEND_BD_COMP_WRITE_PEEK	0x00005c4c
+#define FTQ_SEND_DATA_INIT_CTL		0x00005c50
+#define FTQ_SEND_DATA_INIT_FULL_CNT	0x00005c54
+#define FTQ_SEND_DATA_INIT_FIFO_ENQDEQ	0x00005c58
+#define FTQ_SEND_DATA_INIT_WRITE_PEEK	0x00005c5c
+#define FTQ_DMA_NORM_WRITE_CTL		0x00005c60
+#define FTQ_DMA_NORM_WRITE_FULL_CNT	0x00005c64
+#define FTQ_DMA_NORM_WRITE_FIFO_ENQDEQ	0x00005c68
+#define FTQ_DMA_NORM_WRITE_WRITE_PEEK	0x00005c6c
+#define FTQ_DMA_HIGH_WRITE_CTL		0x00005c70
+#define FTQ_DMA_HIGH_WRITE_FULL_CNT	0x00005c74
+#define FTQ_DMA_HIGH_WRITE_FIFO_ENQDEQ	0x00005c78
+#define FTQ_DMA_HIGH_WRITE_WRITE_PEEK	0x00005c7c
+#define FTQ_SWTYPE1_CTL			0x00005c80
+#define FTQ_SWTYPE1_FULL_CNT		0x00005c84
+#define FTQ_SWTYPE1_FIFO_ENQDEQ		0x00005c88
+#define FTQ_SWTYPE1_WRITE_PEEK		0x00005c8c
+#define FTQ_SEND_DATA_COMP_CTL		0x00005c90
+#define FTQ_SEND_DATA_COMP_FULL_CNT	0x00005c94
+#define FTQ_SEND_DATA_COMP_FIFO_ENQDEQ	0x00005c98
+#define FTQ_SEND_DATA_COMP_WRITE_PEEK	0x00005c9c
+#define FTQ_HOST_COAL_CTL		0x00005ca0
+#define FTQ_HOST_COAL_FULL_CNT		0x00005ca4
+#define FTQ_HOST_COAL_FIFO_ENQDEQ	0x00005ca8
+#define FTQ_HOST_COAL_WRITE_PEEK	0x00005cac
+#define FTQ_MAC_TX_CTL			0x00005cb0
+#define FTQ_MAC_TX_FULL_CNT		0x00005cb4
+#define FTQ_MAC_TX_FIFO_ENQDEQ		0x00005cb8
+#define FTQ_MAC_TX_WRITE_PEEK		0x00005cbc
+#define FTQ_MB_FREE_CTL			0x00005cc0
+#define FTQ_MB_FREE_FULL_CNT		0x00005cc4
+#define FTQ_MB_FREE_FIFO_ENQDEQ		0x00005cc8
+#define FTQ_MB_FREE_WRITE_PEEK		0x00005ccc
+#define FTQ_RCVBD_COMP_CTL		0x00005cd0
+#define FTQ_RCVBD_COMP_FULL_CNT		0x00005cd4
+#define FTQ_RCVBD_COMP_FIFO_ENQDEQ	0x00005cd8
+#define FTQ_RCVBD_COMP_WRITE_PEEK	0x00005cdc
+#define FTQ_RCVLST_PLMT_CTL		0x00005ce0
+#define FTQ_RCVLST_PLMT_FULL_CNT	0x00005ce4
+#define FTQ_RCVLST_PLMT_FIFO_ENQDEQ	0x00005ce8
+#define FTQ_RCVLST_PLMT_WRITE_PEEK	0x00005cec
+#define FTQ_RCVDATA_INI_CTL		0x00005cf0
+#define FTQ_RCVDATA_INI_FULL_CNT	0x00005cf4
+#define FTQ_RCVDATA_INI_FIFO_ENQDEQ	0x00005cf8
+#define FTQ_RCVDATA_INI_WRITE_PEEK	0x00005cfc
+#define FTQ_RCVDATA_COMP_CTL		0x00005d00
+#define FTQ_RCVDATA_COMP_FULL_CNT	0x00005d04
+#define FTQ_RCVDATA_COMP_FIFO_ENQDEQ	0x00005d08
+#define FTQ_RCVDATA_COMP_WRITE_PEEK	0x00005d0c
+#define FTQ_SWTYPE2_CTL			0x00005d10
+#define FTQ_SWTYPE2_FULL_CNT		0x00005d14
+#define FTQ_SWTYPE2_FIFO_ENQDEQ		0x00005d18
+#define FTQ_SWTYPE2_WRITE_PEEK		0x00005d1c
+/* 0x5d20 --> 0x6000 unused */
+
+/* Message signaled interrupt registers */
+#define MSGINT_MODE			0x00006000
+#define  MSGINT_MODE_RESET		 0x00000001
+#define  MSGINT_MODE_ENABLE		 0x00000002
+#define MSGINT_STATUS			0x00006004
+#define MSGINT_FIFO			0x00006008
+/* 0x600c --> 0x6400 unused */
+
+/* DMA completion registers */
+#define DMAC_MODE			0x00006400
+#define  DMAC_MODE_RESET		 0x00000001
+#define  DMAC_MODE_ENABLE		 0x00000002
+/* 0x6404 --> 0x6800 unused */
+
+/* GRC registers */
+#define GRC_MODE			0x00006800
+#define  GRC_MODE_UPD_ON_COAL		0x00000001
+#define  GRC_MODE_BSWAP_NONFRM_DATA	0x00000002
+#define  GRC_MODE_WSWAP_NONFRM_DATA	0x00000004
+#define  GRC_MODE_BSWAP_DATA		0x00000010
+#define  GRC_MODE_WSWAP_DATA		0x00000020
+#define  GRC_MODE_SPLITHDR		0x00000100
+#define  GRC_MODE_NOFRM_CRACKING	0x00000200
+#define  GRC_MODE_INCL_CRC		0x00000400
+#define  GRC_MODE_ALLOW_BAD_FRMS	0x00000800
+#define  GRC_MODE_NOIRQ_ON_SENDS	0x00002000
+#define  GRC_MODE_NOIRQ_ON_RCV		0x00004000
+#define  GRC_MODE_FORCE_PCI32BIT	0x00008000
+#define  GRC_MODE_HOST_STACKUP		0x00010000
+#define  GRC_MODE_HOST_SENDBDS		0x00020000
+#define  GRC_MODE_NO_TX_PHDR_CSUM	0x00100000
+#define  GRC_MODE_NO_RX_PHDR_CSUM	0x00800000
+#define  GRC_MODE_IRQ_ON_TX_CPU_ATTN	0x01000000
+#define  GRC_MODE_IRQ_ON_RX_CPU_ATTN	0x02000000
+#define  GRC_MODE_IRQ_ON_MAC_ATTN	0x04000000
+#define  GRC_MODE_IRQ_ON_DMA_ATTN	0x08000000
+#define  GRC_MODE_IRQ_ON_FLOW_ATTN	0x10000000
+#define  GRC_MODE_4X_NIC_SEND_RINGS	0x20000000
+#define  GRC_MODE_MCAST_FRM_ENABLE	0x40000000
+#define GRC_MISC_CFG			0x00006804
+#define  GRC_MISC_CFG_CORECLK_RESET	0x00000001
+#define  GRC_MISC_CFG_PRESCALAR_MASK	0x000000fe
+#define  GRC_MISC_CFG_PRESCALAR_SHIFT	1
+#define  GRC_MISC_CFG_BOARD_ID_MASK	0x0001e000
+#define  GRC_MISC_CFG_BOARD_ID_5700	0x0001e000
+#define  GRC_MISC_CFG_BOARD_ID_5701	0x00000000
+#define  GRC_MISC_CFG_BOARD_ID_5702FE	0x00004000
+#define  GRC_MISC_CFG_BOARD_ID_5703	0x00000000
+#define  GRC_MISC_CFG_BOARD_ID_5703S	0x00002000
+#define  GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
+#define GRC_LOCAL_CTRL			0x00006808
+#define  GRC_LCLCTRL_INT_ACTIVE		0x00000001
+#define  GRC_LCLCTRL_CLEARINT		0x00000002
+#define  GRC_LCLCTRL_SETINT		0x00000004
+#define  GRC_LCLCTRL_INT_ON_ATTN	0x00000008
+#define  GRC_LCLCTRL_GPIO_INPUT0	0x00000100
+#define  GRC_LCLCTRL_GPIO_INPUT1	0x00000200
+#define  GRC_LCLCTRL_GPIO_INPUT2	0x00000400
+#define  GRC_LCLCTRL_GPIO_OE0		0x00000800
+#define  GRC_LCLCTRL_GPIO_OE1		0x00001000
+#define  GRC_LCLCTRL_GPIO_OE2		0x00002000
+#define  GRC_LCLCTRL_GPIO_OUTPUT0	0x00004000
+#define  GRC_LCLCTRL_GPIO_OUTPUT1	0x00008000
+#define  GRC_LCLCTRL_GPIO_OUTPUT2	0x00010000
+#define  GRC_LCLCTRL_EXTMEM_ENABLE	0x00020000
+#define  GRC_LCLCTRL_MEMSZ_MASK		0x001c0000
+#define  GRC_LCLCTRL_MEMSZ_256K		0x00000000
+#define  GRC_LCLCTRL_MEMSZ_512K		0x00040000
+#define  GRC_LCLCTRL_MEMSZ_1M		0x00080000
+#define  GRC_LCLCTRL_MEMSZ_2M		0x000c0000
+#define  GRC_LCLCTRL_MEMSZ_4M		0x00100000
+#define  GRC_LCLCTRL_MEMSZ_8M		0x00140000
+#define  GRC_LCLCTRL_MEMSZ_16M		0x00180000
+#define  GRC_LCLCTRL_BANK_SELECT	0x00200000
+#define  GRC_LCLCTRL_SSRAM_TYPE		0x00400000
+#define  GRC_LCLCTRL_AUTO_SEEPROM	0x01000000
+#define GRC_TIMER			0x0000680c
+#define GRC_RX_CPU_EVENT		0x00006810
+#define GRC_RX_TIMER_REF		0x00006814
+#define GRC_RX_CPU_SEM			0x00006818
+#define GRC_REMOTE_RX_CPU_ATTN		0x0000681c
+#define GRC_TX_CPU_EVENT		0x00006820
+#define GRC_TX_TIMER_REF		0x00006824
+#define GRC_TX_CPU_SEM			0x00006828
+#define GRC_REMOTE_TX_CPU_ATTN		0x0000682c
+#define GRC_MEM_POWER_UP		0x00006830 /* 64-bit */
+#define GRC_EEPROM_ADDR			0x00006838
+#define  EEPROM_ADDR_WRITE		0x00000000
+#define  EEPROM_ADDR_READ		0x80000000
+#define  EEPROM_ADDR_COMPLETE		0x40000000
+#define  EEPROM_ADDR_FSM_RESET		0x20000000
+#define  EEPROM_ADDR_DEVID_MASK		0x1c000000
+#define  EEPROM_ADDR_DEVID_SHIFT	26
+#define  EEPROM_ADDR_START		0x02000000
+#define  EEPROM_ADDR_CLKPERD_SHIFT	16
+#define  EEPROM_ADDR_ADDR_MASK		0x0000ffff
+#define  EEPROM_ADDR_ADDR_SHIFT		0
+#define  EEPROM_DEFAULT_CLOCK_PERIOD	0x60
+#define  EEPROM_CHIP_SIZE		(64 * 1024)
+#define GRC_EEPROM_DATA			0x0000683c
+#define GRC_EEPROM_CTRL			0x00006840
+#define GRC_MDI_CTRL			0x00006844
+#define GRC_SEEPROM_DELAY		0x00006848
+/* 0x684c --> 0x6c00 unused */
+
+/* 0x6c00 --> 0x7000 unused */
+
+/* NVRAM Control registers */
+#define NVRAM_CMD			0x00007000
+#define  NVRAM_CMD_RESET		 0x00000001
+#define  NVRAM_CMD_DONE			 0x00000008
+#define  NVRAM_CMD_GO			 0x00000010
+#define  NVRAM_CMD_WR			 0x00000020
+#define  NVRAM_CMD_RD			 0x00000000
+#define  NVRAM_CMD_ERASE		 0x00000040
+#define  NVRAM_CMD_FIRST		 0x00000080
+#define  NVRAM_CMD_LAST			 0x00000100
+#define NVRAM_STAT			0x00007004
+#define NVRAM_WRDATA			0x00007008
+#define NVRAM_ADDR			0x0000700c
+#define  NVRAM_ADDR_MSK			0x00ffffff
+#define NVRAM_RDDATA			0x00007010
+#define NVRAM_CFG1			0x00007014
+#define  NVRAM_CFG1_FLASHIF_ENAB	 0x00000001
+#define  NVRAM_CFG1_BUFFERED_MODE	 0x00000002
+#define  NVRAM_CFG1_PASS_THRU		 0x00000004
+#define  NVRAM_CFG1_BIT_BANG		 0x00000008
+#define  NVRAM_CFG1_COMPAT_BYPASS	 0x80000000
+#define NVRAM_CFG2			0x00007018
+#define NVRAM_CFG3			0x0000701c
+#define NVRAM_SWARB			0x00007020
+#define  SWARB_REQ_SET0			 0x00000001
+#define  SWARB_REQ_SET1			 0x00000002
+#define  SWARB_REQ_SET2			 0x00000004
+#define  SWARB_REQ_SET3			 0x00000008
+#define  SWARB_REQ_CLR0			 0x00000010
+#define  SWARB_REQ_CLR1			 0x00000020
+#define  SWARB_REQ_CLR2			 0x00000040
+#define  SWARB_REQ_CLR3			 0x00000080
+#define  SWARB_GNT0			 0x00000100
+#define  SWARB_GNT1			 0x00000200
+#define  SWARB_GNT2			 0x00000400
+#define  SWARB_GNT3			 0x00000800
+#define  SWARB_REQ0			 0x00001000
+#define  SWARB_REQ1			 0x00002000
+#define  SWARB_REQ2			 0x00004000
+#define  SWARB_REQ3			 0x00008000
+#define    NVRAM_BUFFERED_PAGE_SIZE	   264
+#define    NVRAM_BUFFERED_PAGE_POS	   9
+/* 0x7024 --> 0x7400 unused */
+
+/* 0x7400 --> 0x8000 unused */
+
+/* 32K Window into NIC internal memory */
+#define NIC_SRAM_WIN_BASE		0x00008000
+
+/* Offsets into first 32k of NIC internal memory. */
+#define NIC_SRAM_PAGE_ZERO		0x00000000
+#define NIC_SRAM_SEND_RCB		0x00000100 /* 16 * TG3_BDINFO_... */
+#define NIC_SRAM_RCV_RET_RCB		0x00000200 /* 16 * TG3_BDINFO_... */
+#define NIC_SRAM_STATS_BLK		0x00000300
+#define NIC_SRAM_STATUS_BLK		0x00000b00
+
+#define NIC_SRAM_FIRMWARE_MBOX		0x00000b50
+#define  NIC_SRAM_FIRMWARE_MBOX_MAGIC1	 0x4B657654
+#define  NIC_SRAM_FIRMWARE_MBOX_MAGIC2	 0x4861764b /* !dma on linkchg */
+
+#define NIC_SRAM_DATA_SIG		0x00000b54
+#define  NIC_SRAM_DATA_SIG_MAGIC	 0x4b657654 /* ascii for 'KevT' */
+
+#define NIC_SRAM_DATA_CFG			0x00000b58
+#define  NIC_SRAM_DATA_CFG_PHY_TYPE_MASK	 0x0000000c
+#define  NIC_SRAM_DATA_CFG_PHY_TYPE_UNKNOWN	 0x00000000
+#define  NIC_SRAM_DATA_CFG_PHY_TYPE_COPPER	 0x00000004
+#define  NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER	 0x00000008
+#define  NIC_SRAM_DATA_CFG_LED_MODE_MASK	 0x00000030
+#define  NIC_SRAM_DATA_CFG_LED_MODE_UNKNOWN	 0x00000000
+#define  NIC_SRAM_DATA_CFG_LED_TRIPLE_SPD	 0x00000010
+#define  NIC_SRAM_DATA_CFG_LED_LINK_SPD		 0x00000020
+
+#define NIC_SRAM_DATA_PHY_ID		0x00000b74
+#define  NIC_SRAM_DATA_PHY_ID1_MASK	 0xffff0000
+#define  NIC_SRAM_DATA_PHY_ID2_MASK	 0x0000ffff
+
+#define NIC_SRAM_FW_CMD_MBOX		0x00000b78
+#define  FWCMD_NICDRV_ALIVE		 0x00000001
+#define  FWCMD_NICDRV_PAUSE_FW		 0x00000002
+#define  FWCMD_NICDRV_IPV4ADDR_CHG	 0x00000003
+#define  FWCMD_NICDRV_IPV6ADDR_CHG	 0x00000004
+#define  FWCMD_NICDRV_FIX_DMAR		 0x00000005
+#define  FWCMD_NICDRV_FIX_DMAW		 0x00000006
+#define NIC_SRAM_FW_CMD_LEN_MBOX	0x00000b7c
+#define NIC_SRAM_FW_CMD_DATA_MBOX	0x00000b80
+#define NIC_SRAM_FW_ASF_STATUS_MBOX	0x00000c00
+#define NIC_SRAM_FW_DRV_STATE_MBOX	0x00000c04
+#define  DRV_STATE_START		 0x00000001
+#define  DRV_STATE_UNLOAD		 0x00000002
+#define  DRV_STATE_WOL			 0x00000003
+#define  DRV_STATE_SUSPEND		 0x00000004
+
+#define NIC_SRAM_FW_RESET_TYPE_MBOX	0x00000c08
+
+#define NIC_SRAM_MAC_ADDR_HIGH_MBOX	0x00000c14
+#define NIC_SRAM_MAC_ADDR_LOW_MBOX	0x00000c18
+
+#if TG3_MINI_RING_WORKS
+#define NIC_SRAM_RX_MINI_BUFFER_DESC	0x00001000
+#endif
+
+#define NIC_SRAM_DMA_DESC_POOL_BASE	0x00002000
+#define  NIC_SRAM_DMA_DESC_POOL_SIZE	 0x00002000
+#define NIC_SRAM_TX_BUFFER_DESC		0x00004000 /* 512 entries */
+#define NIC_SRAM_RX_BUFFER_DESC		0x00006000 /* 256 entries */
+#define NIC_SRAM_RX_JUMBO_BUFFER_DESC	0x00007000 /* 256 entries */
+#define NIC_SRAM_MBUF_POOL_BASE		0x00008000
+#define  NIC_SRAM_MBUF_POOL_SIZE	 0x00018000
+
+/* Currently this is fixed. */
+#define PHY_ADDR		0x01
+
+/* Tigon3 specific PHY MII registers. */
+#define  TG3_BMCR_SPEED1000		0x0040
+
+#define MII_TG3_CTRL			0x09 /* 1000-baseT control register */
+#define  MII_TG3_CTRL_ADV_1000_HALF	0x0100
+#define  MII_TG3_CTRL_ADV_1000_FULL	0x0200
+#define  MII_TG3_CTRL_AS_MASTER		0x0800
+#define  MII_TG3_CTRL_ENABLE_AS_MASTER	0x1000
+
+#define MII_TG3_EXT_CTRL		0x10 /* Extended control register */
+#define  MII_TG3_EXT_CTRL_LNK3_LED_MODE	0x0002
+#define  MII_TG3_EXT_CTRL_TBI		0x8000
+
+#define MII_TG3_EXT_STAT		0x11 /* Extended status register */
+#define  MII_TG3_EXT_STAT_LPASS		0x0100
+
+#define MII_TG3_DSP_RW_PORT		0x15 /* DSP coefficient read/write port */
+
+#define MII_TG3_DSP_ADDRESS		0x17 /* DSP address register */
+
+#define MII_TG3_AUX_CTRL		0x18 /* auxilliary control register */
+
+#define MII_TG3_AUX_STAT		0x19 /* auxilliary status register */
+#define MII_TG3_AUX_STAT_LPASS		0x0004
+#define MII_TG3_AUX_STAT_SPDMASK	0x0700
+#define MII_TG3_AUX_STAT_10HALF		0x0100
+#define MII_TG3_AUX_STAT_10FULL		0x0200
+#define MII_TG3_AUX_STAT_100HALF	0x0300
+#define MII_TG3_AUX_STAT_100_4		0x0400
+#define MII_TG3_AUX_STAT_100FULL	0x0500
+#define MII_TG3_AUX_STAT_1000HALF	0x0600
+#define MII_TG3_AUX_STAT_1000FULL	0x0700
+
+#define MII_TG3_ISTAT			0x1a /* IRQ status register */
+#define MII_TG3_IMASK			0x1b /* IRQ mask register */
+
+/* ISTAT/IMASK event bits */
+#define MII_TG3_INT_LINKCHG		0x0002
+#define MII_TG3_INT_SPEEDCHG		0x0004
+#define MII_TG3_INT_DUPLEXCHG		0x0008
+#define MII_TG3_INT_ANEG_PAGE_RX	0x0400
+
+/* XXX Add this to mii.h */
+#ifndef ADVERTISE_PAUSE
+#define ADVERTISE_PAUSE_CAP		0x0400
+#endif
+#ifndef ADVERTISE_PAUSE_ASYM
+#define ADVERTISE_PAUSE_ASYM		0x0800
+#endif
+#ifndef LPA_PAUSE
+#define LPA_PAUSE_CAP			0x0400
+#endif
+#ifndef LPA_PAUSE_ASYM
+#define LPA_PAUSE_ASYM			0x0800
+#endif
+
+/* There are two ways to manage the TX descriptors on the tigon3.
+ * Either the descriptors are in host DMA'able memory, or they
+ * exist only in the cards on-chip SRAM.  All 16 send bds are under
+ * the same mode, they may not be configured individually.
+ *
+ * The mode we use is controlled by TG3_FLAG_HOST_TXDS in tp->tg3_flags.
+ *
+ * To use host memory TX descriptors:
+ *	1) Set GRC_MODE_HOST_SENDBDS in GRC_MODE register.
+ *	   Make sure GRC_MODE_4X_NIC_SEND_RINGS is clear.
+ *	2) Allocate DMA'able memory.
+ *	3) In NIC_SRAM_SEND_RCB (of desired index) of on-chip SRAM:
+ *	   a) Set TG3_BDINFO_HOST_ADDR to DMA address of memory
+ *	      obtained in step 2
+ *	   b) Set TG3_BDINFO_NIC_ADDR to NIC_SRAM_TX_BUFFER_DESC.
+ *	   c) Set len field of TG3_BDINFO_MAXLEN_FLAGS to number
+ *            of TX descriptors.  Leave flags field clear.
+ *	4) Access TX descriptors via host memory.  The chip
+ *	   will refetch into local SRAM as needed when producer
+ *	   index mailboxes are updated.
+ *
+ * To use on-chip TX descriptors:
+ *	1) Set GRC_MODE_4X_NIC_SEND_RINGS in GRC_MODE register.
+ *	   Make sure GRC_MODE_HOST_SENDBDS is clear.
+ *	2) In NIC_SRAM_SEND_RCB (of desired index) of on-chip SRAM:
+ *	   a) Set TG3_BDINFO_HOST_ADDR to zero.
+ *	   b) Set TG3_BDINFO_NIC_ADDR to NIC_SRAM_TX_BUFFER_DESC
+ *	   c) TG3_BDINFO_MAXLEN_FLAGS is don't care.
+ *	3) Access TX descriptors directly in on-chip SRAM
+ *	   using normal {read,write}l().  (and not using
+ *         pointer dereferencing of ioremap()'d memory like
+ *	   the broken Broadcom driver does)
+ *
+ * Note that BDINFO_FLAGS_DISABLED should be set in the flags field of
+ * TG3_BDINFO_MAXLEN_FLAGS of all unused SEND_RCB indices.
+ */
+struct tg3_tx_buffer_desc {
+	u32				addr_hi;
+	u32				addr_lo;
+
+	u32				len_flags;
+#define TXD_FLAG_TCPUDP_CSUM		0x0001
+#define TXD_FLAG_IP_CSUM		0x0002
+#define TXD_FLAG_END			0x0004
+#define TXD_FLAG_IP_FRAG		0x0008
+#define TXD_FLAG_IP_FRAG_END		0x0010
+#define TXD_FLAG_VLAN			0x0040
+#define TXD_FLAG_COAL_NOW		0x0080
+#define TXD_FLAG_CPU_PRE_DMA		0x0100
+#define TXD_FLAG_CPU_POST_DMA		0x0200
+#define TXD_FLAG_ADD_SRC_ADDR		0x1000
+#define TXD_FLAG_CHOOSE_SRC_ADDR	0x6000
+#define TXD_FLAG_NO_CRC			0x8000
+#define TXD_LEN_SHIFT			16
+
+	u32				vlan_tag;
+#define TXD_VLAN_TAG_SHIFT		0
+};
+
+#define TXD_ADDR			0x00UL /* 64-bit */
+#define TXD_LEN_FLAGS			0x08UL /* 32-bit (upper 16-bits are len) */
+#define TXD_VLAN_TAG			0x0cUL /* 32-bit (upper 16-bits are tag) */
+#define TXD_SIZE			0x10UL
+
+struct tg3_rx_buffer_desc {
+	u32				addr_hi;
+	u32				addr_lo;
+
+	u32				idx_len;
+#define RXD_IDX_MASK	0xffff0000
+#define RXD_IDX_SHIFT	16
+#define RXD_LEN_MASK	0x0000ffff
+#define RXD_LEN_SHIFT	0
+
+	u32				type_flags;
+#define RXD_TYPE_SHIFT	16
+#define RXD_FLAGS_SHIFT	0
+
+#define RXD_FLAG_END			0x0004
+#if TG3_MINI_RING_WORKS
+#define RXD_FLAG_MINI			0x0800
+#endif
+#define RXD_FLAG_JUMBO			0x0020
+#define RXD_FLAG_VLAN			0x0040
+#define RXD_FLAG_ERROR			0x0400
+#define RXD_FLAG_IP_CSUM		0x1000
+#define RXD_FLAG_TCPUDP_CSUM		0x2000
+#define RXD_FLAG_IS_TCP			0x4000
+
+	u32				ip_tcp_csum;
+#define RXD_IPCSUM_MASK		0xffff0000
+#define RXD_IPCSUM_SHIFT	16
+#define RXD_TCPCSUM_MASK	0x0000ffff
+#define RXD_TCPCSUM_SHIFT	0
+
+	u32				err_vlan;
+
+#define RXD_VLAN_MASK			0x0000ffff
+
+#define RXD_ERR_BAD_CRC			0x00010000
+#define RXD_ERR_COLLISION		0x00020000
+#define RXD_ERR_LINK_LOST		0x00040000
+#define RXD_ERR_PHY_DECODE		0x00080000
+#define RXD_ERR_ODD_NIBBLE_RCVD_MII	0x00100000
+#define RXD_ERR_MAC_ABRT		0x00200000
+#define RXD_ERR_TOO_SMALL		0x00400000
+#define RXD_ERR_NO_RESOURCES		0x00800000
+#define RXD_ERR_HUGE_FRAME		0x01000000
+#define RXD_ERR_MASK			0xffff0000
+
+	u32				reserved;
+	u32				opaque;
+#define RXD_OPAQUE_INDEX_MASK		0x0000ffff
+#define RXD_OPAQUE_INDEX_SHIFT		0
+#define RXD_OPAQUE_RING_STD		0x00010000
+#define RXD_OPAQUE_RING_JUMBO		0x00020000
+#if TG3_MINI_RING_WORKS
+#define RXD_OPAQUE_RING_MINI		0x00040000
+#endif
+#define RXD_OPAQUE_RING_MASK		0x00070000
+};
+
+struct tg3_ext_rx_buffer_desc {
+	struct {
+		u32			addr_hi;
+		u32			addr_lo;
+	}				addrlist[3];
+	u32				len2_len1;
+	u32				resv_len3;
+	struct tg3_rx_buffer_desc	std;
+};
+
+/* We only use this when testing out the DMA engine
+ * at probe time.  This is the internal format of buffer
+ * descriptors used by the chip at NIC_SRAM_DMA_DESCS.
+ */
+struct tg3_internal_buffer_desc {
+	u32				addr_hi;
+	u32				addr_lo;
+	u32				nic_mbuf;
+	/* XXX FIX THIS */
+#ifdef __BIG_ENDIAN
+	u16				cqid_sqid;
+	u16				len;
+#else
+	u16				len;
+	u16				cqid_sqid;
+#endif
+	u32				flags;
+	u32				__cookie1;
+	u32				__cookie2;
+	u32				__cookie3;
+};
+
+#define TG3_HW_STATUS_SIZE		0x80
+struct tg3_hw_status {
+	u32				status;
+#define SD_STATUS_UPDATED		0x00000001
+#define SD_STATUS_LINK_CHG		0x00000002
+#define SD_STATUS_ERROR			0x00000004
+
+	u32				status_tag;
+
+#ifdef __BIG_ENDIAN
+	u16				rx_consumer;
+	u16				rx_jumbo_consumer;
+#else
+	u16				rx_jumbo_consumer;
+	u16				rx_consumer;
+#endif
+
+#ifdef __BIG_ENDIAN
+	u16				reserved;
+	u16				rx_mini_consumer;
+#else
+	u16				rx_mini_consumer;
+	u16				reserved;
+#endif
+	struct {
+#ifdef __BIG_ENDIAN
+		u16			tx_consumer;
+		u16			rx_producer;
+#else
+		u16			rx_producer;
+		u16			tx_consumer;
+#endif
+	}				idx[16];
+};
+
+typedef struct {
+	u32 high, low;
+} tg3_stat64_t;
+
+struct tg3_hw_stats {
+	u8				__reserved0[0x400-0x300];
+
+	/* Statistics maintained by Receive MAC. */
+	tg3_stat64_t			rx_octets;
+	u64				__reserved1;
+	tg3_stat64_t			rx_fragments;
+	tg3_stat64_t			rx_ucast_packets;
+	tg3_stat64_t			rx_mcast_packets;
+	tg3_stat64_t			rx_bcast_packets;
+	tg3_stat64_t			rx_fcs_errors;
+	tg3_stat64_t			rx_align_errors;
+	tg3_stat64_t			rx_xon_pause_rcvd;
+	tg3_stat64_t			rx_xoff_pause_rcvd;
+	tg3_stat64_t			rx_mac_ctrl_rcvd;
+	tg3_stat64_t			rx_xoff_entered;
+	tg3_stat64_t			rx_frame_too_long_errors;
+	tg3_stat64_t			rx_jabbers;
+	tg3_stat64_t			rx_undersize_packets;
+	tg3_stat64_t			rx_in_length_errors;
+	tg3_stat64_t			rx_out_length_errors;
+	tg3_stat64_t			rx_64_or_less_octet_packets;
+	tg3_stat64_t			rx_65_to_127_octet_packets;
+	tg3_stat64_t			rx_128_to_255_octet_packets;
+	tg3_stat64_t			rx_256_to_511_octet_packets;
+	tg3_stat64_t			rx_512_to_1023_octet_packets;
+	tg3_stat64_t			rx_1024_to_1522_octet_packets;
+	tg3_stat64_t			rx_1523_to_2047_octet_packets;
+	tg3_stat64_t			rx_2048_to_4095_octet_packets;
+	tg3_stat64_t			rx_4096_to_8191_octet_packets;
+	tg3_stat64_t			rx_8192_to_9022_octet_packets;
+
+	u64				__unused0[37];
+
+	/* Statistics maintained by Transmit MAC. */
+	tg3_stat64_t			tx_octets;
+	u64				__reserved2;
+	tg3_stat64_t			tx_collisions;
+	tg3_stat64_t			tx_xon_sent;
+	tg3_stat64_t			tx_xoff_sent;
+	tg3_stat64_t			tx_flow_control;
+	tg3_stat64_t			tx_mac_errors;
+	tg3_stat64_t			tx_single_collisions;
+	tg3_stat64_t			tx_mult_collisions;
+	tg3_stat64_t			tx_deferred;
+	u64				__reserved3;
+	tg3_stat64_t			tx_excessive_collisions;
+	tg3_stat64_t			tx_late_collisions;
+	tg3_stat64_t			tx_collide_2times;
+	tg3_stat64_t			tx_collide_3times;
+	tg3_stat64_t			tx_collide_4times;
+	tg3_stat64_t			tx_collide_5times;
+	tg3_stat64_t			tx_collide_6times;
+	tg3_stat64_t			tx_collide_7times;
+	tg3_stat64_t			tx_collide_8times;
+	tg3_stat64_t			tx_collide_9times;
+	tg3_stat64_t			tx_collide_10times;
+	tg3_stat64_t			tx_collide_11times;
+	tg3_stat64_t			tx_collide_12times;
+	tg3_stat64_t			tx_collide_13times;
+	tg3_stat64_t			tx_collide_14times;
+	tg3_stat64_t			tx_collide_15times;
+	tg3_stat64_t			tx_ucast_packets;
+	tg3_stat64_t			tx_mcast_packets;
+	tg3_stat64_t			tx_bcast_packets;
+	tg3_stat64_t			tx_carrier_sense_errors;
+	tg3_stat64_t			tx_discards;
+	tg3_stat64_t			tx_errors;
+
+	u64				__unused1[31];
+
+	/* Statistics maintained by Receive List Placement. */
+	tg3_stat64_t			COS_rx_packets[16];
+	tg3_stat64_t			COS_rx_filter_dropped;
+	tg3_stat64_t			dma_writeq_full;
+	tg3_stat64_t			dma_write_prioq_full;
+	tg3_stat64_t			rxbds_empty;
+	tg3_stat64_t			rx_discards;
+	tg3_stat64_t			rx_errors;
+	tg3_stat64_t			rx_threshold_hit;
+
+	u64				__unused2[9];
+
+	/* Statistics maintained by Send Data Initiator. */
+	tg3_stat64_t			COS_out_packets[16];
+	tg3_stat64_t			dma_readq_full;
+	tg3_stat64_t			dma_read_prioq_full;
+	tg3_stat64_t			tx_comp_queue_full;
+
+	/* Statistics maintained by Host Coalescing. */
+	tg3_stat64_t			ring_set_send_prod_index;
+	tg3_stat64_t			ring_status_update;
+	tg3_stat64_t			nic_irqs;
+	tg3_stat64_t			nic_avoided_irqs;
+	tg3_stat64_t			nic_tx_threshold_hit;
+
+	u8				__reserved4[0xb00-0x9c0];
+};
+
+enum phy_led_mode {
+	led_mode_auto,
+	led_mode_three_link,
+	led_mode_link10
+};
+
+/* 'mapping' is superfluous as the chip does not write into
+ * the tx/rx post rings so we could just fetch it from there.
+ * But the cache behavior is better how we are doing it now.
+ */
+struct ring_info {
+	struct sk_buff			*skb;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+struct tg3_config_info {
+	u32				flags;
+};
+
+struct tg3_link_config {
+	/* Describes what we're trying to get. */
+	u32				advertising;
+	u16				speed;
+	u8				duplex;
+	u8				autoneg;
+
+	/* Describes what we actually have. */
+	u16				active_speed;
+	u8				active_duplex;
+#define SPEED_INVALID		0xffff
+#define DUPLEX_INVALID		0xff
+#define AUTONEG_INVALID		0xff
+
+	/* When we go in and out of low power mode we need
+	 * to swap with this state.
+	 */
+	int				phy_is_low_power;
+	u16				orig_speed;
+	u8				orig_duplex;
+	u8				orig_autoneg;
+};
+
+struct tg3_coalesce_config {
+	/* Current settings. */
+	u32		rx_coalesce_ticks;
+	u32		rx_max_coalesced_frames;
+	u32		rx_coalesce_ticks_during_int;
+	u32		rx_max_coalesced_frames_during_int;
+	u32		tx_coalesce_ticks;
+	u32		tx_max_coalesced_frames;
+	u32		tx_coalesce_ticks_during_int;
+	u32		tx_max_coalesced_frames_during_int;
+	u32		stats_coalesce_ticks;
+
+	/* Default settings. */
+	u32		rx_coalesce_ticks_def;
+	u32		rx_max_coalesced_frames_def;
+	u32		rx_coalesce_ticks_during_int_def;
+	u32		rx_max_coalesced_frames_during_int_def;
+	u32		tx_coalesce_ticks_def;
+	u32		tx_max_coalesced_frames_def;
+	u32		tx_coalesce_ticks_during_int_def;
+	u32		tx_max_coalesced_frames_during_int_def;
+	u32		stats_coalesce_ticks_def;
+
+	/* Adaptive RX/TX coalescing parameters. */
+	u32		rate_sample_jiffies;
+	u32		pkt_rate_low;
+	u32		pkt_rate_high;
+
+	u32		rx_coalesce_ticks_low;
+	u32		rx_max_coalesced_frames_low;
+	u32		tx_coalesce_ticks_low;
+	u32		tx_max_coalesced_frames_low;
+
+	u32		rx_coalesce_ticks_high;
+	u32		rx_max_coalesced_frames_high;
+	u32		tx_coalesce_ticks_high;
+	u32		tx_max_coalesced_frames_high;
+};
+
+struct tg3_bufmgr_config {
+	u32		mbuf_read_dma_low_water;
+	u32		mbuf_mac_rx_low_water;
+	u32		mbuf_high_water;
+
+	u32		mbuf_read_dma_low_water_jumbo;
+	u32		mbuf_mac_rx_low_water_jumbo;
+	u32		mbuf_high_water_jumbo;
+
+	u32		dma_low_water;
+	u32		dma_high_water;
+};
+
+struct tg3 {
+	spinlock_t			lock;
+	u32				tx_prod;
+	u32				tx_cons;
+	u32				rx_rcb_ptr;
+	u32				rx_std_ptr;
+	u32				rx_jumbo_ptr;
+#if TG3_MINI_RING_WORKS
+	u32				rx_mini_ptr;
+#endif
+	spinlock_t			indirect_lock;
+
+	struct net_device_stats		net_stats;
+	struct net_device_stats		net_stats_prev;
+	unsigned long			phy_crc_errors;
+
+	/* Adaptive coalescing engine. */
+	unsigned long			last_rate_sample;
+	u32				last_rx_count;
+	u32				last_tx_count;
+
+	u32				rx_offset;
+	u32				tg3_flags;
+#define TG3_FLAG_HOST_TXDS		0x00000001
+#define TG3_FLAG_TXD_MBOX_HWBUG		0x00000002
+#define TG3_FLAG_RX_CHECKSUMS		0x00000004
+#define TG3_FLAG_USE_LINKCHG_REG	0x00000008
+#define TG3_FLAG_USE_MI_INTERRUPT	0x00000010
+#define TG3_FLAG_ADAPTIVE_RX		0x00000020
+#define TG3_FLAG_ADAPTIVE_TX		0x00000040
+#define TG3_FLAG_POLL_SERDES		0x00000080
+#define TG3_FLAG_PHY_RESET_ON_INIT	0x00000100
+#define TG3_FLAG_PCIX_TARGET_HWBUG	0x00000200
+#define TG3_FLAG_TAGGED_IRQ_STATUS	0x00000400
+#define TG3_FLAG_WOL_SPEED_100MB	0x00000800
+#define TG3_FLAG_WOL_ENABLE		0x00001000
+#define TG3_FLAG_NVRAM			0x00002000
+#define TG3_FLAG_NVRAM_BUFFERED		0x00004000
+#define TG3_FLAG_RX_PAUSE		0x00008000
+#define TG3_FLAG_TX_PAUSE		0x00010000
+#define TG3_FLAG_PCIX_MODE		0x00020000
+#define TG3_FLAG_PCI_HIGH_SPEED		0x00040000
+#define TG3_FLAG_PCI_32BIT		0x00080000
+#define TG3_FLAG_NO_TX_PSEUDO_CSUM	0x00100000
+#define TG3_FLAG_NO_RX_PSEUDO_CSUM	0x00200000
+#define TG3_FLAG_AUTONEG_DISABLE	0x00400000
+#define TG3_FLAG_JUMBO_ENABLE		0x00800000
+#define TG3_FLAG_10_100_ONLY		0x01000000
+#define TG3_FLAG_PAUSE_AUTONEG		0x02000000
+#define TG3_FLAG_PAUSE_RX		0x04000000
+#define TG3_FLAG_PAUSE_TX		0x08000000
+#define TG3_FLAG_BROKEN_CHECKSUMS	0x10000000
+#define TG3_FLAG_GOT_SERDES_FLOWCTL	0x20000000
+#define TG3_FLAG_INIT_COMPLETE		0x80000000
+
+	u32				msg_enable;
+
+	struct timer_list		timer;
+	u16				timer_counter;
+	u16				timer_multiplier;
+	u32				timer_offset;
+
+	struct tg3_link_config		link_config;
+	struct tg3_coalesce_config	coalesce_config;
+	struct tg3_bufmgr_config	bufmgr_config;
+
+	u32				rx_pending;
+#if TG3_MINI_RING_WORKS
+	u32				rx_mini_pending;
+#endif
+	u32				rx_jumbo_pending;
+	u32				tx_pending;
+
+	/* cache h/w values, often passed straight to h/w */
+	u32				rx_mode;
+	u32				tx_mode;
+	u32				mac_mode;
+	u32				mi_mode;
+	u32				misc_host_ctrl;
+	u32				grc_mode;
+	u32				grc_local_ctrl;
+	u32				dma_rwctrl;
+	u32				coalesce_mode;
+
+	/* PCI block */
+	u16				pci_chip_rev_id;
+	u8				pci_cacheline_sz;
+	u8				pci_lat_timer;
+	u8				pci_hdr_type;
+	u8				pci_bist;
+	u32				pci_cfg_state[64 / sizeof(u32)];
+
+	int				pm_cap;
+
+	/* PHY info */
+	u32				phy_id;
+#define PHY_ID_MASK			0xfffffff0
+#define PHY_ID_BCM5400			0x60008040
+#define PHY_ID_BCM5401			0x60008050
+#define PHY_ID_BCM5411			0x60008070
+#define PHY_ID_BCM5701			0x60008110
+#define PHY_ID_BCM5703			0x60008160
+#define PHY_ID_BCM8002			0x60010140
+#define PHY_ID_SERDES			0xfeedbee0
+#define PHY_ID_INVALID			0xffffffff
+#define PHY_ID_REV_MASK			0x0000000f
+#define PHY_REV_BCM5401_B0		0x1
+#define PHY_REV_BCM5401_B2		0x3
+#define PHY_REV_BCM5401_C0		0x6
+#define PHY_REV_BCM5411_X0		0x1 /* Found on Netgear GA302T */
+
+	enum phy_led_mode		led_mode;
+
+	char				board_part_number[24];
+
+	/* This macro assumes the passed PHY ID is already masked
+	 * with PHY_ID_MASK.
+	 */
+#define KNOWN_PHY_ID(X)		\
+	((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \
+	 (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
+	 (X) == PHY_ID_BCM5703 ||			   \
+	 (X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES)
+
+	unsigned long			regs;
+	struct pci_dev			*pdev;
+	struct net_device		*dev;
+#if TG3_VLAN_TAG_USED
+	struct vlan_group		*vlgrp;
+#endif
+
+	struct tg3_rx_buffer_desc	*rx_std;
+	struct ring_info		*rx_std_buffers;
+	dma_addr_t			rx_std_mapping;
+#if TG3_MINI_RING_WORKS
+	struct tg3_rx_buffer_desc	*rx_mini;
+	struct ring_info		*rx_mini_buffers;
+	dma_addr_t			rx_mini_mapping;
+#endif
+	struct tg3_rx_buffer_desc	*rx_jumbo;
+	struct ring_info		*rx_jumbo_buffers;
+	dma_addr_t			rx_jumbo_mapping;
+
+	struct tg3_rx_buffer_desc	*rx_rcb;
+	dma_addr_t			rx_rcb_mapping;
+
+	/* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */
+	struct tg3_tx_buffer_desc	*tx_ring;
+	struct ring_info		*tx_buffers;
+	dma_addr_t			tx_desc_mapping;
+
+	struct tg3_hw_status		*hw_status;
+	dma_addr_t			status_mapping;
+
+	struct tg3_hw_stats		*hw_stats;
+	dma_addr_t			stats_mapping;
+};
+
+#endif /* !(_T3_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tlan.c linux/drivers/net/tlan.c
--- linux.orig/drivers/net/tlan.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/tlan.c	2002-07-20 01:08:26.000000000 +0000
@@ -8,6 +8,7 @@
  *  (C) 1997-1998 Caldera, Inc.
  *  (C) 1998 James Banks
  *  (C) 1999-2001 Torben Mathiasen
+ *  (C) 2002 Samuel Chessman
  *
  *  This software may be used and distributed according to the terms
  *  of the GNU General Public License, incorporated herein by reference.
@@ -158,6 +159,11 @@
  *
  * 	v1.14a Jan 6, 2001   - Minor adjustments (spinlocks, etc.)
  *
+ *	Samuel Chessman <chessman@tux.org> New Maintainer!
+ *
+ *	v1.15 Apr 4, 2002    - Correct operation when aui=1 to be
+ *	                       10T half duplex no loopback
+ *	                       Thanks to Gunnar Eikman
  *******************************************************************************/
 
                                                                                 
@@ -188,7 +194,7 @@
 static  int speed[MAX_TLAN_BOARDS];
 static  int boards_found;
 
-MODULE_AUTHOR("Maintainer: Torben Mathiasen <torben.mathiasen@compaq.com>");
+MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
 MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
 MODULE_LICENSE("GPL");
 
@@ -213,7 +219,7 @@
 static	int		bbuf;
 static	u8		*TLanPadBuffer;
 static	char		TLanSignature[] = "TLAN";
-static const char tlan_banner[] = "ThunderLAN driver v1.14a\n";
+static const char tlan_banner[] = "ThunderLAN driver v1.15\n";
 static int tlan_have_pci;
 static int tlan_have_eisa;
 
@@ -2603,12 +2609,12 @@
 		TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN );
 		return;
 	}  else if ( priv->phyNum == 0 ) {
+		control = 0;
         	TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl );
 		if ( priv->aui ) {
                 	tctl |= TLAN_TC_AUISEL;
 		} else { 
                 	tctl &= ~TLAN_TC_AUISEL;
-			control = 0;
 			if ( priv->duplex == TLAN_DUPLEX_FULL ) {
 				control |= MII_GC_DUPLEX;
 				priv->tlanFullDuplex = TRUE;
@@ -2616,8 +2622,8 @@
 			if ( priv->speed == TLAN_SPEED_100 ) {
 				control |= MII_GC_SPEEDSEL;
 			}
-       			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );
 		}
+		TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );
         	TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/3c359.c linux/drivers/net/tokenring/3c359.c
--- linux.orig/drivers/net/tokenring/3c359.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/tokenring/3c359.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,1816 @@
+/*
+ *   3c359.c (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved
+ *
+ *  Linux driver for 3Com 3c359 Tokenlink Velocity XL PCI NIC
+ *
+ *  Base Driver Olympic:
+ *	Written 1999 Peter De Schrijver & Mike Phillips
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License, incorporated herein by reference.
+ * 
+ *  7/17/00 - Clean up, version number 0.9.0. Ready to release to the world.
+ *
+ *  2/16/01 - Port up to kernel 2.4.2 ready for submission into the kernel.
+ *  3/05/01 - Last clean up stuff before submission.
+ *  2/15/01 - Finally, update to new pci api. 
+ *
+ *  To Do:
+ */
+
+/* 
+ *	Technical Card Details
+ *
+ *  All access to data is done with 16/8 bit transfers.  The transfer
+ *  method really sucks. You can only read or write one location at a time.
+ *
+ *  Also, the microcode for the card must be uploaded if the card does not have
+ *  the flashrom on board.  This is a 28K bloat in the driver when compiled
+ *  as a module.
+ *
+ *  Rx is very simple, status into a ring of descriptors, dma data transfer,
+ *  interrupts to tell us when a packet is received.
+ *
+ *  Tx is a little more interesting. Similar scenario, descriptor and dma data
+ *  transfers, but we don't have to interrupt the card to tell it another packet
+ *  is ready for transmission, we are just doing simple memory writes, not io or mmio
+ *  writes.  The card can be set up to simply poll on the next
+ *  descriptor pointer and when this value is non-zero will automatically download
+ *  the next packet.  The card then interrupts us when the packet is done.
+ *
+ */
+
+#define XL_DEBUG 0
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <linux/in.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/ptrace.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/trdevice.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <net/checksum.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include "3c359.h"
+
+static char version[] __devinitdata  = 
+"3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ; 
+
+MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ; 
+MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver \n") ;
+
+/* Module paramters */
+
+/* Ring Speed 0,4,16 
+ * 0 = Autosense   
+ * 4,16 = Selected speed only, no autosense
+ * This allows the card to be the first on the ring
+ * and become the active monitor.
+ *
+ * WARNING: Some hubs will allow you to insert
+ * at the wrong speed.
+ * 
+ * The adapter will _not_ fail to open if there are no
+ * active monitors on the ring, it will simply open up in 
+ * its last known ringspeed if no ringspeed is specified.
+ */
+
+static int ringspeed[XL_MAX_ADAPTERS] = {0,} ;
+
+MODULE_PARM(ringspeed, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i");
+MODULE_PARM_DESC(ringspeed,"3c359: Ringspeed selection - 4,16 or 0") ; 
+
+/* Packet buffer size */
+
+static int pkt_buf_sz[XL_MAX_ADAPTERS] = {0,} ;
+ 
+MODULE_PARM(pkt_buf_sz, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i") ; 
+MODULE_PARM_DESC(pkt_buf_sz,"3c359: Initial buffer size") ; 
+/* Message Level */
+
+static int message_level[XL_MAX_ADAPTERS] = {0,} ; 
+
+MODULE_PARM(message_level, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i") ; 
+MODULE_PARM_DESC(message_level, "3c359: Level of reported messages \n") ; 
+/* 
+ *	This is a real nasty way of doing this, but otherwise you
+ *	will be stuck with 1555 lines of hex #'s in the code.
+ */
+
+#include "3c359_microcode.h" 
+
+static struct pci_device_id xl_pci_tbl[] __devinitdata =
+{
+	{PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, },
+	{ }			/* terminate list */
+};
+MODULE_DEVICE_TABLE(pci,xl_pci_tbl) ; 
+
+static int xl_init(struct net_device *dev);
+static int xl_open(struct net_device *dev);
+static int xl_open_hw(struct net_device *dev) ;  
+static int xl_hw_reset(struct net_device *dev); 
+static int xl_xmit(struct sk_buff *skb, struct net_device *dev);
+static void xl_dn_comp(struct net_device *dev); 
+static int xl_close(struct net_device *dev);
+static void xl_set_rx_mode(struct net_device *dev);
+static void xl_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static struct net_device_stats * xl_get_stats(struct net_device *dev);
+static int xl_set_mac_address(struct net_device *dev, void *addr) ; 
+static void xl_arb_cmd(struct net_device *dev);
+static void xl_asb_cmd(struct net_device *dev) ; 
+static void xl_srb_cmd(struct net_device *dev, int srb_cmd) ; 
+static void xl_wait_misr_flags(struct net_device *dev) ; 
+static int xl_change_mtu(struct net_device *dev, int mtu);
+static void xl_srb_bh(struct net_device *dev) ; 
+static void xl_asb_bh(struct net_device *dev) ; 
+static void xl_reset(struct net_device *dev) ;  
+static void xl_freemem(struct net_device *dev) ;  
+
+
+/* EEProm Access Functions */
+static u16  xl_ee_read(struct net_device *dev, int ee_addr) ; 
+static void  xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) ; 
+
+/* Debugging functions */
+#if XL_DEBUG
+static void print_tx_state(struct net_device *dev) ; 
+static void print_rx_state(struct net_device *dev) ; 
+
+static void print_tx_state(struct net_device *dev)
+{
+
+	struct xl_private *xl_priv = (struct xl_private *)dev->priv ; 
+	struct xl_tx_desc *txd ; 
+	u8 *xl_mmio = xl_priv->xl_mmio ; 
+	int i ; 
+
+	printk("tx_ring_head: %d, tx_ring_tail: %d, free_ent: %d \n",xl_priv->tx_ring_head, 
+		xl_priv->tx_ring_tail, xl_priv->free_ring_entries) ; 
+	printk("Ring    , Address ,   FSH  , DnNextPtr, Buffer, Buffer_Len \n"); 
+	for (i = 0; i < 16; i++) {
+		txd = &(xl_priv->xl_tx_ring[i]) ; 
+		printk("%d, %08lx, %08x, %08x, %08x, %08x \n", i, virt_to_bus(txd), 
+			txd->framestartheader, txd->dnnextptr, txd->buffer, txd->buffer_length ) ; 
+	}
+
+	printk("DNLISTPTR = %04x \n", readl(xl_mmio + MMIO_DNLISTPTR) ); 
+	
+	printk("DmaCtl = %04x \n", readl(xl_mmio + MMIO_DMA_CTRL) ); 
+	printk("Queue status = %0x \n",netif_running(dev) ) ; 
+}
+
+static void print_rx_state(struct net_device *dev)
+{
+
+	struct xl_private *xl_priv = (struct xl_private *)dev->priv ; 
+	struct xl_rx_desc *rxd ; 
+	u8 *xl_mmio = xl_priv->xl_mmio ; 
+	int i ; 
+
+	printk("rx_ring_tail: %d \n", xl_priv->rx_ring_tail) ; 
+	printk("Ring    , Address ,   FrameState  , UPNextPtr, FragAddr, Frag_Len \n"); 
+	for (i = 0; i < 16; i++) { 
+		/* rxd = (struct xl_rx_desc *)xl_priv->rx_ring_dma_addr + (i * sizeof(struct xl_rx_desc)) ; */
+		rxd = &(xl_priv->xl_rx_ring[i]) ; 
+		printk("%d, %08lx, %08x, %08x, %08x, %08x \n", i, virt_to_bus(rxd), 
+			rxd->framestatus, rxd->upnextptr, rxd->upfragaddr, rxd->upfraglen ) ; 
+	}
+
+	printk("UPLISTPTR = %04x \n", readl(xl_mmio + MMIO_UPLISTPTR) ); 
+	
+	printk("DmaCtl = %04x \n", readl(xl_mmio + MMIO_DMA_CTRL) ); 
+	printk("Queue status = %0x \n",netif_running(dev) ) ;
+} 
+#endif
+
+/*
+ *	Read values from the on-board EEProm.  This looks very strange
+ *	but you have to wait for the EEProm to get/set the value before 
+ *	passing/getting the next value from the nic. As with all requests
+ *	on this nic it has to be done in two stages, a) tell the nic which
+ *	memory address you want to access and b) pass/get the value from the nic.
+ *	With the EEProm, you have to wait before and inbetween access a) and b).
+ *	As this is only read at initialization time and the wait period is very 
+ *	small we shouldn't have to worry about scheduling issues.
+ */
+
+static u16 xl_ee_read(struct net_device *dev, int ee_addr)
+{ 
+    	struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+	u8 *xl_mmio = xl_priv->xl_mmio ; 
+
+	/* Wait for EEProm to not be busy */
+	writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+
+	/* Tell EEProm what we want to do and where */
+	writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ; 
+
+	/* Wait for EEProm to not be busy */
+	writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; 
+	
+	/* Tell EEProm what we want to do and where */
+	writel(IO_WORD_WRITE | EECONTROL , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ; 
+
+	/* Finally read the value from the EEProm */
+	writel(IO_WORD_READ | EEDATA , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	return readw(xl_mmio + MMIO_MACDATA) ; 
+}
+
+/* 
+ *	Write values to the onboard eeprom. As with eeprom read you need to 
+ *	set which location to write, wait, value to write, wait, with the 
+ *	added twist of having to enable eeprom writes as well.
+ */
+
+static void  xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) 
+{
+    	struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+	u8 *xl_mmio = xl_priv->xl_mmio ; 
+
+	/* Wait for EEProm to not be busy */
+	writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+	
+	/* Enable write/erase */
+	writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writew(EE_ENABLE_WRITE, xl_mmio + MMIO_MACDATA) ; 
+
+	/* Wait for EEProm to not be busy */
+	writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+
+	/* Put the value we want to write into EEDATA */ 
+	writel(IO_WORD_WRITE | EEDATA, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writew(ee_value, xl_mmio + MMIO_MACDATA) ;
+
+	/* Tell EEProm to write eevalue into ee_addr */
+	writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writew(EEWRITE + ee_addr, xl_mmio + MMIO_MACDATA) ; 
+
+	/* Wait for EEProm to not be busy, to ensure write gets done */
+	writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+	
+	return ; 
+}
+ 
+int __devinit xl_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 
+{
+	struct net_device *dev ; 
+	struct xl_private *xl_priv ; 
+	static int card_no = -1 ;
+	int i ; 
+
+	card_no++ ; 
+
+	if (pci_enable_device(pdev)) { 
+		return -ENODEV ; 
+	} 
+
+	pci_set_master(pdev);
+
+	if ((i = pci_request_regions(pdev,"3c359"))) { 
+		return i ; 
+	} ; 
+
+	/* 
+	 * Allowing init_trdev to allocate the dev->priv structure will align xl_private
+   	 * on a 32 bytes boundary which we need for the rx/tx descriptors
+	 */
+
+	dev = alloc_trdev(sizeof(struct xl_private)) ; 
+	if (!dev) { 
+		pci_release_regions(pdev) ; 
+		return -ENOMEM ; 
+	} 
+	xl_priv = dev->priv ; 
+
+#if XL_DEBUG  
+	printk("pci_device: %p, dev:%p, dev->priv: %p, ba[0]: %10x, ba[1]:%10x\n", 
+		pdev, dev, dev->priv, (unsigned int)pdev->resource[0].start, (unsigned int)pdev->resource[1].start) ;  
+#endif 
+
+	dev->irq=pdev->irq;
+	dev->base_addr=pci_resource_start(pdev,0) ; 
+	dev->init=NULL ; /* Must be null with new api, otherwise get called twice */
+	xl_priv->xl_card_name = (char *)pdev->name ; 
+	xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE);
+	xl_priv->pdev = pdev ; 
+		
+	if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
+		xl_priv->pkt_buf_sz = PKT_BUF_SZ ; 
+	else
+		xl_priv->pkt_buf_sz = pkt_buf_sz[card_no] ; 
+
+	dev->mtu = xl_priv->pkt_buf_sz - TR_HLEN ; 
+	xl_priv->xl_ring_speed = ringspeed[card_no] ; 
+	xl_priv->xl_message_level = message_level[card_no] ; 
+	xl_priv->xl_functional_addr[0] = xl_priv->xl_functional_addr[1] = xl_priv->xl_functional_addr[2] = xl_priv->xl_functional_addr[3] = 0 ; 
+	xl_priv->xl_copy_all_options = 0 ; 
+		
+	if((i = xl_init(dev))) {
+		iounmap(xl_priv->xl_mmio) ; 
+		kfree(dev) ; 
+		pci_release_regions(pdev) ; 
+		return i ; 
+	}				
+
+	dev->open=&xl_open;
+	dev->hard_start_xmit=&xl_xmit;
+	dev->change_mtu=&xl_change_mtu;
+	dev->stop=&xl_close;
+	dev->do_ioctl=NULL;
+	dev->set_multicast_list=&xl_set_rx_mode;
+	dev->get_stats=&xl_get_stats ;
+	dev->set_mac_address=&xl_set_mac_address ; 
+	SET_MODULE_OWNER(dev); 
+
+	pci_set_drvdata(pdev,dev) ; 
+	if ((i = register_netdev(dev))) { 
+		printk(KERN_ERR "3C359, register netdev failed\n") ;  
+		pci_set_drvdata(pdev,NULL) ; 
+		iounmap(xl_priv->xl_mmio) ; 
+		kfree(dev) ; 
+		pci_release_regions(pdev) ; 
+		return i ; 
+	}
+   
+	printk(KERN_INFO "3C359: %s registered as: %s\n",xl_priv->xl_card_name,dev->name) ; 
+
+	return 0; 
+}
+
+
+static int __init xl_init(struct net_device *dev) 
+{
+    	struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+
+	printk(KERN_INFO "%s \n", version);
+	printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n",
+		xl_priv->xl_card_name, (unsigned int)dev->base_addr ,xl_priv->xl_mmio, dev->irq);
+
+	spin_lock_init(&xl_priv->xl_lock) ; 
+
+	return xl_hw_reset(dev) ; 
+
+}
+
+
+/* 
+ *	Hardware reset.  This needs to be a separate entity as we need to reset the card
+ *	when we change the EEProm settings.
+ */
+
+static int xl_hw_reset(struct net_device *dev) 
+{ 
+    	struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+	u8 *xl_mmio = xl_priv->xl_mmio ; 
+	unsigned long t ; 
+	u16 i ; 
+    	u16 result_16 ; 
+	u8 result_8 ;
+	u16 start ; 
+	int j ;
+
+	/*
+	 *  Reset the card.  If the card has got the microcode on board, we have 
+         *  missed the initialization interrupt, so we must always do this.
+	 */
+
+	writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; 
+
+	/* 
+	 * Must wait for cmdInProgress bit (12) to clear before continuing with
+	 * card configuration.
+	 */
+
+	t=jiffies;
+	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
+		schedule();		
+		if(jiffies-t > 40*HZ) {
+			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL  card not responding to global reset.\n", dev->name);
+			return -ENODEV;
+		}
+	}
+
+	/*
+	 *  Enable pmbar by setting bit in CPAttention
+	 */
+
+	writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+	result_8 = readb(xl_mmio + MMIO_MACDATA) ; 
+	result_8 = result_8 | CPA_PMBARVIS ; 
+	writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(result_8, xl_mmio + MMIO_MACDATA) ; 
+	
+	/*
+	 * Read cpHold bit in pmbar, if cleared we have got Flashrom on board.
+ 	 * If not, we need to upload the microcode to the card
+	 */
+
+	writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);  
+
+#if XL_DEBUG
+	printk(KERN_INFO "Read from PMBAR = %04x \n", readw(xl_mmio + MMIO_MACDATA)) ; 
+#endif
+
+	if ( readw( (xl_mmio + MMIO_MACDATA))  & PMB_CPHOLD ) { 
+
+		/* Set PmBar, privateMemoryBase bits (8:2) to 0 */
+
+		writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);  
+		result_16 = readw(xl_mmio + MMIO_MACDATA) ; 
+		result_16 = result_16 & ~((0x7F) << 2) ; 
+		writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writew(result_16,xl_mmio + MMIO_MACDATA) ; 
+	
+		/* Set CPAttention, memWrEn bit */
+
+		writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		result_8 = readb(xl_mmio + MMIO_MACDATA) ; 
+		result_8 = result_8 | CPA_MEMWREN  ; 
+		writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(result_8, xl_mmio + MMIO_MACDATA) ; 
+
+		/* 
+		 * Now to write the microcode into the shared ram 
+	 	 * The microcode must finish at position 0xFFFF, so we must subtract
+		 * to get the start position for the code
+		 */
+
+		start = (0xFFFF - (mc_size) + 1 ) ; /* Looks strange but ensures compiler only uses 16 bit unsigned int for this */ 
+		
+		printk(KERN_INFO "3C359: Uploading Microcode: "); 
+		
+		for (i = start,j=0; (j < mc_size && i <= 0xffff) ; i++,j++) { 
+			writel(MEM_BYTE_WRITE | 0XD0000 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+			writeb(microcode[j],xl_mmio + MMIO_MACDATA) ; 
+			if (j % 1024 == 0)
+				printk(".");
+		}
+		printk("\n") ; 
+
+		for (i=0;i < 16; i++) { 
+			writel( (MEM_BYTE_WRITE | 0xDFFF0) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+			writeb(microcode[mc_size - 16 + i], xl_mmio + MMIO_MACDATA) ; 
+		}
+
+		/*
+		 * Have to write the start address of the upload to FFF4, but
+                 * the address must be >> 4. You do not want to know how long
+                 * it took me to discover this.
+		 */
+
+		writel(MEM_WORD_WRITE | 0xDFFF4, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writew(start >> 4, xl_mmio + MMIO_MACDATA);
+
+		/* Clear the CPAttention, memWrEn Bit */
+	
+		writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		result_8 = readb(xl_mmio + MMIO_MACDATA) ; 
+		result_8 = result_8 & ~CPA_MEMWREN ; 
+		writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(result_8, xl_mmio + MMIO_MACDATA) ; 
+
+		/* Clear the cpHold bit in pmbar */
+
+		writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);  
+		result_16 = readw(xl_mmio + MMIO_MACDATA) ; 
+		result_16 = result_16 & ~PMB_CPHOLD ; 
+		writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writew(result_16,xl_mmio + MMIO_MACDATA) ; 
+
+
+	} /* If microcode upload required */
+
+	/* 
+	 * The card should now go though a self test procedure and get itself ready
+         * to be opened, we must wait for an srb response with the initialization
+         * information. 
+	 */
+
+#if XL_DEBUG
+	printk(KERN_INFO "%s: Microcode uploaded, must wait for the self test to complete\n", dev->name);
+#endif
+
+	writew(SETINDENABLE | 0xFFF, xl_mmio + MMIO_COMMAND) ; 
+
+	t=jiffies;
+	while ( !(readw(xl_mmio + MMIO_INTSTATUS_AUTO) & INTSTAT_SRB) ) { 
+		schedule();		
+		if(jiffies-t > 15*HZ) {
+			printk(KERN_ERR "3COM 3C359 Velocity XL  card not responding.\n");
+			return -ENODEV; 
+		}
+	}
+
+	/*
+	 * Write the RxBufArea with D000, RxEarlyThresh, TxStartThresh, 
+ 	 * DnPriReqThresh, read the tech docs if you want to know what
+	 * values they need to be.
+	 */
+
+	writel(MMIO_WORD_WRITE | RXBUFAREA, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writew(0xD000, xl_mmio + MMIO_MACDATA) ; 
+	
+	writel(MMIO_WORD_WRITE | RXEARLYTHRESH, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writew(0X0020, xl_mmio + MMIO_MACDATA) ; 
+	
+	writew( SETTXSTARTTHRESH | 0x40 , xl_mmio + MMIO_COMMAND) ; 
+
+	writeb(0x04, xl_mmio + MMIO_DNBURSTTHRESH) ; 
+	writeb(0x04, xl_mmio + DNPRIREQTHRESH) ;
+
+	/*
+	 * Read WRBR to provide the location of the srb block, have to use byte reads not word reads. 
+	 * Tech docs have this wrong !!!!
+	 */
+
+	writel(MMIO_BYTE_READ | WRBR, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	xl_priv->srb = readb(xl_mmio + MMIO_MACDATA) << 8 ; 
+	writel( (MMIO_BYTE_READ | WRBR) + 1, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	xl_priv->srb = xl_priv->srb | readb(xl_mmio + MMIO_MACDATA) ;
+
+#if XL_DEBUG
+	writel(IO_WORD_READ | SWITCHSETTINGS, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	if ( readw(xl_mmio + MMIO_MACDATA) & 2) { 
+		printk(KERN_INFO "Default ring speed 4 mbps \n") ;
+	} else {
+		printk(KERN_INFO "Default ring speed 16 mbps \n") ; 
+	} 
+	printk(KERN_INFO "%s: xl_priv->srb = %04x\n",xl_priv->xl_card_name, xl_priv->srb);
+#endif
+
+	return 0;
+}
+
+static int xl_open(struct net_device *dev) 
+{
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 i ; 
+	u16 hwaddr[3] ; /* Should be u8[6] but we get word return values */
+	int open_err ;
+
+	u16 switchsettings, switchsettings_eeprom  ;
+ 
+	if(request_irq(dev->irq, &xl_interrupt, SA_SHIRQ , "3c359", dev)) {
+		return -EAGAIN;
+	}
+
+	/* 
+	 * Read the information from the EEPROM that we need. I know we
+ 	 * should use ntohs, but the word gets stored reversed in the 16
+	 * bit field anyway and it all works its self out when we memcpy
+	 * it into dev->dev_addr. 
+	 */
+	
+	hwaddr[0] = xl_ee_read(dev,0x10) ; 
+	hwaddr[1] = xl_ee_read(dev,0x11) ; 
+	hwaddr[2] = xl_ee_read(dev,0x12) ; 
+
+	/* Ring speed */
+
+	switchsettings_eeprom = xl_ee_read(dev,0x08) ;
+	switchsettings = switchsettings_eeprom ;  
+
+	if (xl_priv->xl_ring_speed != 0) { 
+		if (xl_priv->xl_ring_speed == 4)  
+			switchsettings = switchsettings | 0x02 ; 
+		else 
+			switchsettings = switchsettings & ~0x02 ; 
+	}
+
+	/* Only write EEProm if there has been a change */
+	if (switchsettings != switchsettings_eeprom) { 
+		xl_ee_write(dev,0x08,switchsettings) ; 
+		/* Hardware reset after changing EEProm */
+		xl_hw_reset(dev) ; 
+	}
+
+	memcpy(dev->dev_addr,hwaddr,dev->addr_len) ; 
+	
+	open_err = xl_open_hw(dev) ; 
+
+	/* 
+	 * This really needs to be cleaned up with better error reporting.
+	 */
+
+	if (open_err != 0) { /* Something went wrong with the open command */
+		if (open_err & 0x07) { /* Wrong speed, retry at different speed */
+			printk(KERN_WARNING "%s: Open Error, retrying at different ringspeed \n", dev->name) ; 
+			switchsettings = switchsettings ^ 2 ; 
+			xl_ee_write(dev,0x08,switchsettings) ; 
+			xl_hw_reset(dev) ; 
+			open_err = xl_open_hw(dev) ; 
+			if (open_err != 0) { 
+				printk(KERN_WARNING "%s: Open error returned a second time, we're bombing out now\n", dev->name); 
+				free_irq(dev->irq,dev) ; 						
+				return -ENODEV ;
+			}  
+		} else { 
+			printk(KERN_WARNING "%s: Open Error = %04x\n", dev->name, open_err) ; 
+			free_irq(dev->irq,dev) ; 
+			return -ENODEV ; 
+		}
+	}
+
+	/*
+	 * Now to set up the Rx and Tx buffer structures
+	 */
+	/* These MUST be on 8 byte boundaries */
+	xl_priv->xl_tx_ring = kmalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL) ; 
+	xl_priv->xl_rx_ring = kmalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL) ; 
+	memset(xl_priv->xl_tx_ring,0,sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) ; 
+	memset(xl_priv->xl_rx_ring,0,sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) ; 
+
+	 /* Setup Rx Ring */
+	 for (i=0 ; i < XL_RX_RING_SIZE ; i++) { 
+		struct sk_buff *skb ; 
+
+		skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ; 
+		if (skb==NULL) 
+			break ; 
+
+		skb->dev = dev ; 
+		xl_priv->xl_rx_ring[i].upfragaddr = pci_map_single(xl_priv->pdev, skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ; 
+		xl_priv->xl_rx_ring[i].upfraglen = xl_priv->pkt_buf_sz | RXUPLASTFRAG;
+		xl_priv->rx_ring_skb[i] = skb ; 	
+	}
+
+	if (i==0) { 
+		printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled \n",dev->name) ; 
+		free_irq(dev->irq,dev) ; 
+		return -EIO ; 
+	} 
+
+	xl_priv->rx_ring_no = i ; 
+	xl_priv->rx_ring_tail = 0 ; 
+	xl_priv->rx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_rx_ring, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_TODEVICE) ; 
+	for (i=0;i<(xl_priv->rx_ring_no-1);i++) { 
+		xl_priv->xl_rx_ring[i].upnextptr = xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * (i+1)) ; 
+	} 
+	xl_priv->xl_rx_ring[i].upnextptr = 0 ; 
+
+	writel(xl_priv->rx_ring_dma_addr, xl_mmio + MMIO_UPLISTPTR) ; 
+	
+	/* Setup Tx Ring */
+	
+	xl_priv->tx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_tx_ring, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,PCI_DMA_TODEVICE) ; 
+	
+	xl_priv->tx_ring_head = 1 ; 
+	xl_priv->tx_ring_tail = 255 ; /* Special marker for first packet */
+	xl_priv->free_ring_entries = XL_TX_RING_SIZE ; 
+
+	/*
+ 	 * Setup the first dummy DPD entry for polling to start working.
+	 */
+
+	xl_priv->xl_tx_ring[0].framestartheader = TXDPDEMPTY ; 
+	xl_priv->xl_tx_ring[0].buffer = 0 ; 
+	xl_priv->xl_tx_ring[0].buffer_length = 0 ; 
+	xl_priv->xl_tx_ring[0].dnnextptr = 0 ; 
+
+	writel(xl_priv->tx_ring_dma_addr, xl_mmio + MMIO_DNLISTPTR) ; 
+	writel(DNUNSTALL, xl_mmio + MMIO_COMMAND) ; 
+	writel(UPUNSTALL, xl_mmio + MMIO_COMMAND) ; 
+	writel(DNENABLE, xl_mmio + MMIO_COMMAND) ; 
+	writeb(0x40, xl_mmio + MMIO_DNPOLL) ;	
+
+	/*
+	 * Enable interrupts on the card
+	 */
+
+	writel(SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; 
+	writel(SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; 
+
+	netif_start_queue(dev) ; 	
+	return 0;
+	
+}	
+
+static int xl_open_hw(struct net_device *dev) 
+{ 
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u16 vsoff ;
+	char ver_str[33];  
+	int open_err ; 
+	int i ; 
+	unsigned long t ; 
+
+	/*
+	 * Okay, let's build up the Open.NIC srb command
+	 *
+	 */
+		
+	writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(OPEN_NIC, xl_mmio + MMIO_MACDATA) ; 
+	
+	/*
+	 * Use this as a test byte, if it comes back with the same value, the command didn't work
+	 */
+
+	writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb)+ 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(0xff,xl_mmio + MMIO_MACDATA) ; 
+
+	/* Open options */
+	writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(0x00, xl_mmio + MMIO_MACDATA) ; 
+	writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 9, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(0x00, xl_mmio + MMIO_MACDATA) ; 
+
+	/* 
+	 * Node address, be careful here, the docs say you can just put zeros here and it will use
+	 * the hardware address, it doesn't, you must include the node address in the open command.
+	 */
+
+	if (xl_priv->xl_laa[0]) {  /* If using a LAA address */
+		for (i=10;i<16;i++) { 
+			writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+			writeb(xl_priv->xl_laa[i],xl_mmio + MMIO_MACDATA) ; 
+		}
+		memcpy(dev->dev_addr,xl_priv->xl_laa,dev->addr_len) ; 
+	} else { /* Regular hardware address */ 
+		for (i=10;i<16;i++) { 
+			writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+			writeb(dev->dev_addr[i-10], xl_mmio + MMIO_MACDATA) ; 
+		}
+	}
+
+	/* Default everything else to 0 */
+	for (i = 16; i < 34; i++) {
+		writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(0x00,xl_mmio + MMIO_MACDATA) ; 
+	}
+	
+	/*
+	 *  Set the csrb bit in the MISR register
+	 */
+
+	xl_wait_misr_flags(dev) ; 
+	writel(MEM_BYTE_WRITE | MF_CSRB, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(0xFF, xl_mmio + MMIO_MACDATA) ; 
+	writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(MISR_CSRB , xl_mmio + MMIO_MACDATA) ; 
+
+	/*
+	 * Now wait for the command to run
+	 */
+
+	t=jiffies;
+	while (! (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) { 
+		schedule();		
+		if(jiffies-t > 40*HZ) {
+			printk(KERN_ERR "3COM 3C359 Velocity XL  card not responding.\n");
+			break ; 
+		}
+	}
+
+	/*
+	 * Let's interpret the open response
+	 */
+
+	writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb)+2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	if (readb(xl_mmio + MMIO_MACDATA)!=0) {
+		open_err = readb(xl_mmio + MMIO_MACDATA) << 8 ; 
+		writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb) + 7, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		open_err |= readb(xl_mmio + MMIO_MACDATA) ; 
+		return open_err ; 
+	} else { 
+		writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		xl_priv->asb = ntohs(readw(xl_mmio + MMIO_MACDATA)) ; 
+		printk(KERN_INFO "%s: Adapter Opened Details: ",dev->name) ; 
+		printk("ASB: %04x",xl_priv->asb ) ; 
+		writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 10, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		printk(", SRB: %04x",ntohs(readw(xl_mmio + MMIO_MACDATA)) ) ; 
+ 
+		writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 12, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		xl_priv->arb = ntohs(readw(xl_mmio + MMIO_MACDATA)) ; 
+		printk(", ARB: %04x \n",xl_priv->arb ) ; 
+		writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 14, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		vsoff = ntohs(readw(xl_mmio + MMIO_MACDATA)) ; 
+
+		/* 
+		 * Interesting, sending the individual characters directly to printk was causing klogd to use
+		 * use 100% of processor time, so we build up the string and print that instead.
+	   	 */
+
+		for (i=0;i<0x20;i++) { 
+			writel( (MEM_BYTE_READ | 0xD0000 | vsoff) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+			ver_str[i] = readb(xl_mmio + MMIO_MACDATA) ; 
+		}
+		ver_str[i] = '\0' ; 
+		printk(KERN_INFO "%s: Microcode version String: %s \n",dev->name,ver_str); 
+	} 	
+	
+	/*
+	 * Issue the AckInterrupt
+	 */
+	writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 
+
+	return 0 ; 
+}
+
+/*
+ *	There are two ways of implementing rx on the 359 NIC, either
+ * 	interrupt driven or polling.  We are going to uses interrupts,
+ *	it is the easier way of doing things.
+ *	
+ *	The Rx works with a ring of Rx descriptors.  At initialise time the ring
+ *	entries point to the next entry except for the last entry in the ring 
+ *	which points to 0.  The card is programmed with the location of the first
+ *	available descriptor and keeps reading the next_ptr until next_ptr is set
+ *	to 0.  Hopefully with a ring size of 16 the card will never get to read a next_ptr
+ *	of 0.  As the Rx interrupt is received we copy the frame up to the protocol layers
+ *	and then point the end of the ring to our current position and point our current
+ *	position to 0, therefore making the current position the last position on the ring.
+ *	The last position on the ring therefore loops continually loops around the rx ring.
+ *	
+ *	rx_ring_tail is the position on the ring to process next. (Think of a snake, the head 
+ *	expands as the card adds new packets and we go around eating the tail processing the
+ *	packets.)
+ *
+ *	Undoubtably it could be streamlined and improved upon, but at the moment it works 
+ *	and the fast path through the routine is fine. 
+ *	
+ *	adv_rx_ring could be inlined to increase performance, but its called a *lot* of times
+ *	in xl_rx so would increase the size of the function significantly. 
+ */
+
+static void adv_rx_ring(struct net_device *dev) /* Advance rx_ring, cut down on bloat in xl_rx */ 
+{
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+	int prev_ring_loc ; 
+
+	prev_ring_loc = (xl_priv->rx_ring_tail + XL_RX_RING_SIZE - 1) & (XL_RX_RING_SIZE - 1);
+	xl_priv->xl_rx_ring[prev_ring_loc].upnextptr = xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * xl_priv->rx_ring_tail) ; 
+	xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus = 0 ; 
+	xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upnextptr = 0 ; 	
+	xl_priv->rx_ring_tail++ ; 
+	xl_priv->rx_ring_tail &= (XL_RX_RING_SIZE-1) ; 
+
+	return ; 
+}
+
+static void xl_rx(struct net_device *dev)
+{
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	struct sk_buff *skb, *skb2 ; 
+	int frame_length = 0, copy_len = 0  ; 	
+	int temp_ring_loc ;  
+
+	/*
+	 * Receive the next frame, loop around the ring until all frames
+  	 * have been received.
+	 */ 	 
+	
+	while (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & (RXUPDCOMPLETE | RXUPDFULL) ) { /* Descriptor to process */
+
+		if (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & RXUPDFULL ) { /* UpdFull, Multiple Descriptors used for the frame */
+
+			/* 
+			 * This is a pain, you need to go through all the descriptors until the last one 
+			 * for this frame to find the framelength
+			 */
+
+			temp_ring_loc = xl_priv->rx_ring_tail ; 
+
+			while (xl_priv->xl_rx_ring[temp_ring_loc].framestatus & RXUPDFULL ) {
+				temp_ring_loc++ ; 
+				temp_ring_loc &= (XL_RX_RING_SIZE-1) ; 
+			}
+
+			frame_length = xl_priv->xl_rx_ring[temp_ring_loc].framestatus & 0x7FFF ; 
+
+			skb = dev_alloc_skb(frame_length) ;
+ 
+			if (skb==NULL) { /* No memory for frame, still need to roll forward the rx ring */
+				printk(KERN_WARNING "%s: dev_alloc_skb failed - multi buffer !\n", dev->name) ; 
+				while (xl_priv->rx_ring_tail != temp_ring_loc)  
+					adv_rx_ring(dev) ; 
+				
+				adv_rx_ring(dev) ; /* One more time just for luck :) */ 
+				xl_priv->xl_stats.rx_dropped++ ; 
+
+				writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; 
+				return ; 				
+			}
+	
+			skb->dev = dev ; 
+
+			while (xl_priv->rx_ring_tail != temp_ring_loc) { 
+				copy_len = xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen & 0x7FFF ; 
+				frame_length -= copy_len ;  
+				pci_dma_sync_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; 
+				memcpy(skb_put(skb,copy_len), xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]->data, copy_len) ; 
+				adv_rx_ring(dev) ; 
+			} 
+
+			/* Now we have found the last fragment */
+			pci_dma_sync_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; 
+			memcpy(skb_put(skb,copy_len), xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]->data, frame_length) ; 
+/*			memcpy(skb_put(skb,frame_length), bus_to_virt(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), frame_length) ; */
+			adv_rx_ring(dev) ; 
+			skb->protocol = tr_type_trans(skb,dev) ; 
+			netif_rx(skb) ; 
+
+		} else { /* Single Descriptor Used, simply swap buffers over, fast path  */
+
+			frame_length = xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & 0x7FFF ; 
+			
+			skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ; 
+
+			if (skb==NULL) { /* Still need to fix the rx ring */
+				printk(KERN_WARNING "%s: dev_alloc_skb failed in rx, single buffer \n",dev->name) ; 
+				adv_rx_ring(dev) ; 
+				xl_priv->xl_stats.rx_dropped++ ; 
+				writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; 
+				return ; 
+			}
+
+			skb->dev = dev ; 
+
+			skb2 = xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] ; 
+			pci_unmap_single(xl_priv->pdev, xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr, xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; 
+			skb_put(skb2, frame_length) ; 
+			skb2->protocol = tr_type_trans(skb2,dev) ; 
+
+			xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] = skb ; 	
+			xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr = pci_map_single(xl_priv->pdev,skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ; 
+			xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen = xl_priv->pkt_buf_sz | RXUPLASTFRAG ; 
+			adv_rx_ring(dev) ; 
+			xl_priv->xl_stats.rx_packets++ ; 
+			xl_priv->xl_stats.rx_bytes += frame_length ; 	
+
+			netif_rx(skb2) ; 		
+		 } /* if multiple buffers */
+		dev->last_rx = jiffies ; 	
+	} /* while packet to do */
+
+	/* Clear the updComplete interrupt */
+	writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; 
+	return ; 	
+}
+
+/*
+ * This is ruthless, it doesn't care what state the card is in it will 
+ * completely reset the adapter.
+ */
+
+static void xl_reset(struct net_device *dev) 
+{
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	unsigned long t; 
+
+	writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; 
+
+	/* 
+	 * Must wait for cmdInProgress bit (12) to clear before continuing with
+	 * card configuration.
+	 */
+
+	t=jiffies;
+	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
+		if(jiffies-t > 40*HZ) {
+			printk(KERN_ERR "3COM 3C359 Velocity XL  card not responding.\n");
+			break ; 
+		}
+	}
+	
+}
+
+static void xl_freemem(struct net_device *dev) 
+{
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv ; 
+	int i ; 
+
+	for (i=0;i<XL_RX_RING_SIZE;i++) {
+		dev_kfree_skb_irq(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]) ; 
+		pci_unmap_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ; 
+		xl_priv->rx_ring_tail++ ; 
+		xl_priv->rx_ring_tail &= XL_RX_RING_SIZE-1; 
+	} 
+
+	/* unmap ring */
+	pci_unmap_single(xl_priv->pdev,xl_priv->rx_ring_dma_addr, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_FROMDEVICE) ; 
+	
+	pci_unmap_single(xl_priv->pdev,xl_priv->tx_ring_dma_addr, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, PCI_DMA_TODEVICE) ; 
+
+	kfree(xl_priv->xl_rx_ring) ; 
+	kfree(xl_priv->xl_tx_ring) ; 
+
+	return  ; 
+}
+
+static void xl_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+ 	struct xl_private *xl_priv =(struct xl_private *)dev->priv;
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u16 intstatus, macstatus  ;
+
+	if (!dev) { 
+		printk(KERN_WARNING "Device structure dead, aaahhhh !\n") ;
+		return ; 
+	}
+
+	intstatus = readw(xl_mmio + MMIO_INTSTATUS) ;  
+
+	if (!(intstatus & 1)) /* We didn't generate the interrupt */
+		return ; 
+
+	spin_lock(&xl_priv->xl_lock) ; 
+
+	/*
+	 * Process the interrupt
+	 */
+	/*
+	 * Something fishy going on here, we shouldn't get 0001 ints, not fatal though.
+	 */
+	if (intstatus == 0x0001) {  
+		writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+		printk(KERN_INFO "%s: 00001 int received \n",dev->name) ;  
+	} else {  
+		if (intstatus &	(HOSTERRINT | SRBRINT | ARBCINT | UPCOMPINT | DNCOMPINT | HARDERRINT | (1<<8) | TXUNDERRUN | ASBFINT)) { 
+			
+			/* 
+			 * Host Error.
+			 * It may be possible to recover from this, but usually it means something
+			 * is seriously fubar, so we just close the adapter.
+			 */
+
+			if (intstatus & HOSTERRINT) {
+				printk(KERN_WARNING "%s: Host Error, performing global reset, intstatus = %04x \n",dev->name,intstatus) ; 
+				writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ;
+				printk(KERN_WARNING "%s: Resetting hardware: \n", dev->name); 
+				netif_stop_queue(dev) ;
+				xl_freemem(dev) ; 
+				free_irq(dev->irq,dev); 	
+				xl_reset(dev) ; 
+				writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 
+				spin_unlock(&xl_priv->xl_lock) ; 
+				return ; 
+			} /* Host Error */
+
+			if (intstatus & SRBRINT ) {  /* Srbc interrupt */
+				writel(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+				if (xl_priv->srb_queued)
+					xl_srb_bh(dev) ; 
+			} /* SRBR Interrupt */
+
+			if (intstatus & TXUNDERRUN) { /* Issue DnReset command */
+				writel(DNRESET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+				while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { /* Wait for command to run */
+					/* !!! FIX-ME !!!! 
+					Must put a timeout check here ! */
+					/* Empty Loop */
+				} 
+				printk(KERN_WARNING "%s: TX Underrun received \n",dev->name) ;
+				writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 
+			} /* TxUnderRun */
+	
+			if (intstatus & ARBCINT ) { /* Arbc interrupt */
+				xl_arb_cmd(dev) ; 
+			} /* Arbc */
+
+			if (intstatus & ASBFINT) { 
+				if (xl_priv->asb_queued == 1) {
+					xl_asb_cmd(dev) ; 
+				} else if (xl_priv->asb_queued == 2) {
+					xl_asb_bh(dev) ; 
+				} else { 
+					writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; 
+				}  
+			} /* Asbf */
+
+			if (intstatus & UPCOMPINT ) /* UpComplete */
+				xl_rx(dev) ; 
+
+			if (intstatus & DNCOMPINT )  /* DnComplete */
+				xl_dn_comp(dev) ; 
+
+			if (intstatus & HARDERRINT ) { /* Hardware error */
+				writel(MMIO_WORD_READ | MACSTATUS, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+				macstatus = readw(xl_mmio + MMIO_MACDATA) ; 
+				printk(KERN_WARNING "%s: MacStatusError, details: ", dev->name);
+				if (macstatus & (1<<14)) 
+					printk(KERN_WARNING "tchk error: Unrecoverable error \n") ; 
+				if (macstatus & (1<<3))
+					printk(KERN_WARNING "eint error: Internal watchdog timer expired \n") ;
+				if (macstatus & (1<<2))
+					printk(KERN_WARNING "aint error: Host tried to perform illegal operation \n") ; 
+				printk(KERN_WARNING "Instatus = %02x, macstatus = %02x\n",intstatus,macstatus) ; 
+				printk(KERN_WARNING "%s: Resetting hardware: \n", dev->name); 
+				netif_stop_queue(dev) ;
+				xl_freemem(dev) ; 
+				free_irq(dev->irq,dev); 
+				unregister_trdev(dev) ; 
+				kfree(dev) ;  
+				xl_reset(dev) ; 
+				writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 
+				spin_unlock(&xl_priv->xl_lock) ; 
+				return ; 
+			}
+		} else { 
+			printk(KERN_WARNING "%s: Received Unknown interrupt : %04x \n", dev->name, intstatus) ;
+			writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 	
+		}
+	} 
+
+	/* Turn interrupts back on */
+
+	writel( SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; 
+	writel( SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; 
+
+	spin_unlock(&xl_priv->xl_lock) ; 
+}	
+
+/*
+ *	Tx - Polling configuration
+ */
+	
+static int xl_xmit(struct sk_buff *skb, struct net_device *dev) 
+{
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+	struct xl_tx_desc *txd ; 
+	int tx_head, tx_tail, tx_prev ; 
+	unsigned long flags ; 	
+
+	spin_lock_irqsave(&xl_priv->xl_lock,flags) ; 
+
+	netif_stop_queue(dev) ; 
+
+	if (xl_priv->free_ring_entries > 1 ) { 	
+		/*
+		 * Set up the descriptor for the packet 
+		 */
+		tx_head = xl_priv->tx_ring_head ; 
+		tx_tail = xl_priv->tx_ring_tail ; 
+
+		txd = &(xl_priv->xl_tx_ring[tx_head]) ; 
+		txd->dnnextptr = 0 ; 
+		txd->framestartheader = skb->len | TXDNINDICATE ; 
+		txd->buffer = pci_map_single(xl_priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE) ; 
+		txd->buffer_length = skb->len | TXDNFRAGLAST  ; 
+		xl_priv->tx_ring_skb[tx_head] = skb ; 
+		xl_priv->xl_stats.tx_packets++ ; 
+		xl_priv->xl_stats.tx_bytes += skb->len ;
+
+		/* 
+		 * Set the nextptr of the previous descriptor equal to this descriptor, add XL_TX_RING_SIZE -1 
+		 * to ensure no negative numbers in unsigned locations.
+		 */ 
+	
+		tx_prev = (xl_priv->tx_ring_head + XL_TX_RING_SIZE - 1) & (XL_TX_RING_SIZE - 1) ; 
+
+		xl_priv->tx_ring_head++ ; 
+		xl_priv->tx_ring_head &= (XL_TX_RING_SIZE - 1) ;
+		xl_priv->free_ring_entries-- ; 
+
+		xl_priv->xl_tx_ring[tx_prev].dnnextptr = xl_priv->tx_ring_dma_addr + (sizeof (struct xl_tx_desc) * tx_head) ; 
+
+		/* Sneaky, by doing a read on DnListPtr we can force the card to poll on the DnNextPtr */
+		/* readl(xl_mmio + MMIO_DNLISTPTR) ; */
+
+		netif_wake_queue(dev) ; 
+
+		spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; 
+ 
+		return 0;
+	} else {
+		spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; 
+		return 1;
+	}
+
+}
+	
+/* 
+ * The NIC has told us that a packet has been downloaded onto the card, we must
+ * find out which packet it has done, clear the skb and information for the packet
+ * then advance around the ring for all tranmitted packets
+ */
+
+static void xl_dn_comp(struct net_device *dev) 
+{
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	struct xl_tx_desc *txd ; 
+
+
+	if (xl_priv->tx_ring_tail == 255) {/* First time */
+		xl_priv->xl_tx_ring[0].framestartheader = 0 ; 
+		xl_priv->xl_tx_ring[0].dnnextptr = 0 ;  
+		xl_priv->tx_ring_tail = 1 ; 
+	}
+
+	while (xl_priv->xl_tx_ring[xl_priv->tx_ring_tail].framestartheader & TXDNCOMPLETE ) { 
+		txd = &(xl_priv->xl_tx_ring[xl_priv->tx_ring_tail]) ;
+		pci_unmap_single(xl_priv->pdev,txd->buffer, xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]->len, PCI_DMA_TODEVICE) ; 
+		txd->framestartheader = 0 ; 
+		txd->buffer = 0xdeadbeef  ; 
+		txd->buffer_length  = 0 ;  
+		dev_kfree_skb_irq(xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]) ;
+		xl_priv->tx_ring_tail++ ; 
+		xl_priv->tx_ring_tail &= (XL_TX_RING_SIZE - 1) ; 
+		xl_priv->free_ring_entries++ ; 
+	}
+
+	netif_wake_queue(dev) ; 
+
+	writel(ACK_INTERRUPT | DNCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; 
+}
+
+/*
+ * Close the adapter properly.
+ * This srb reply cannot be handled from interrupt context as we have
+ * to free the interrupt from the driver. 
+ */
+
+static int xl_close(struct net_device *dev) 
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	unsigned long t ; 
+
+	netif_stop_queue(dev) ; 
+
+	/*
+	 * Close the adapter, need to stall the rx and tx queues.
+	 */
+
+    	writew(DNSTALL, xl_mmio + MMIO_COMMAND) ; 
+	t=jiffies;
+	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
+		schedule();		
+		if(jiffies-t > 10*HZ) {
+			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNSTALL not responding.\n", dev->name);
+			break ; 
+		}
+	}
+    	writew(DNDISABLE, xl_mmio + MMIO_COMMAND) ; 
+	t=jiffies;
+	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
+		schedule();		
+		if(jiffies-t > 10*HZ) {
+			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNDISABLE not responding.\n", dev->name);
+			break ;
+		}
+	}
+    	writew(UPSTALL, xl_mmio + MMIO_COMMAND) ; 
+	t=jiffies;
+	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
+		schedule();		
+		if(jiffies-t > 10*HZ) {
+			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPSTALL not responding.\n", dev->name);
+			break ; 
+		}
+	}
+
+	/* Turn off interrupts, we will still get the indication though
+ 	 * so we can trap it
+	 */
+
+	writel(SETINTENABLE, xl_mmio + MMIO_COMMAND) ; 
+
+	xl_srb_cmd(dev,CLOSE_NIC) ; 
+
+	t=jiffies;
+	while (!(readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) { 
+		schedule();		
+		if(jiffies-t > 10*HZ) {
+			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-CLOSENIC not responding.\n", dev->name);
+			break ; 
+		}
+	}
+	/* Read the srb response from the adapter */
+
+	writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD);
+	if (readb(xl_mmio + MMIO_MACDATA) != CLOSE_NIC) { 
+		printk(KERN_INFO "%s: CLOSE_NIC did not get a CLOSE_NIC response \n",dev->name) ; 
+	} else { 
+		writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+		if (readb(xl_mmio + MMIO_MACDATA)==0) { 
+			printk(KERN_INFO "%s: Adapter has been closed \n",dev->name) ;
+			writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 
+
+			xl_freemem(dev) ; 
+			free_irq(dev->irq,dev) ; 
+		} else { 
+			printk(KERN_INFO "%s: Close nic command returned error code %02x\n",dev->name, readb(xl_mmio + MMIO_MACDATA)) ;
+		} 
+	}
+
+	/* Reset the upload and download logic */
+ 
+    	writew(UPRESET, xl_mmio + MMIO_COMMAND) ; 
+	t=jiffies;
+	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
+		schedule();		
+		if(jiffies-t > 10*HZ) {
+			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPRESET not responding.\n", dev->name);
+			break ; 
+		}
+	}
+    	writew(DNRESET, xl_mmio + MMIO_COMMAND) ; 
+	t=jiffies;
+	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
+		schedule();		
+		if(jiffies-t > 10*HZ) {
+			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNRESET not responding.\n", dev->name);
+			break ; 
+		}
+	}
+	xl_hw_reset(dev) ; 
+	return 0 ;
+}
+
+static void xl_set_rx_mode(struct net_device *dev) 
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
+	struct dev_mc_list *dmi ; 
+	unsigned char dev_mc_address[4] ; 
+	u16 options ; 
+	int i ; 
+
+	if (dev->flags & IFF_PROMISC)
+		options = 0x0004 ; 
+	else
+		options = 0x0000 ; 
+
+	if (options ^ xl_priv->xl_copy_all_options) { /* Changed, must send command */
+		xl_priv->xl_copy_all_options = options ; 
+		xl_srb_cmd(dev, SET_RECEIVE_MODE) ;
+		return ;  
+	}
+
+	dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;
+
+        for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) {
+                dev_mc_address[0] |= dmi->dmi_addr[2] ;
+                dev_mc_address[1] |= dmi->dmi_addr[3] ;
+                dev_mc_address[2] |= dmi->dmi_addr[4] ;
+                dev_mc_address[3] |= dmi->dmi_addr[5] ;
+        }
+
+	if (memcmp(xl_priv->xl_functional_addr,dev_mc_address,4) != 0) { /* Options have changed, run the command */
+		memcpy(xl_priv->xl_functional_addr, dev_mc_address,4) ; 
+		xl_srb_cmd(dev, SET_FUNC_ADDRESS) ; 
+	}
+	return ; 
+}
+
+
+/*
+ *	We issued an srb command and now we must read
+ *	the response from the completed command.
+ */
+
+static void xl_srb_bh(struct net_device *dev) 
+{ 
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 srb_cmd, ret_code ; 
+	int i ; 
+
+	writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+	srb_cmd = readb(xl_mmio + MMIO_MACDATA) ; 
+	writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+	ret_code = readb(xl_mmio + MMIO_MACDATA) ; 
+
+	/* Ret_code is standard across all commands */
+
+	switch (ret_code) { 
+	case 1:
+		printk(KERN_INFO "%s: Command: %d - Invalid Command code\n",dev->name,srb_cmd) ; 
+		break ; 
+	case 4:
+		printk(KERN_INFO "%s: Command: %d - Adapter is closed, must be open for this command \n",dev->name,srb_cmd) ; 
+		break ;
+	
+	case 6:
+		printk(KERN_INFO "%s: Command: %d - Options Invalid for command \n",dev->name,srb_cmd) ;
+		break ;
+
+	case 0: /* Successful command execution */ 
+		switch (srb_cmd) { 
+		case READ_LOG: /* Returns 14 bytes of data from the NIC */
+			if(xl_priv->xl_message_level)
+				printk(KERN_INFO "%s: READ.LOG 14 bytes of data ",dev->name) ; 
+			/* 
+			 * We still have to read the log even if message_level = 0 and we don't want
+			 * to see it
+			 */
+			for (i=0;i<14;i++) { 
+				writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+				if(xl_priv->xl_message_level) 
+					printk("%02x:",readb(xl_mmio + MMIO_MACDATA)) ; 	
+			} 
+			printk("\n") ; 
+			break ; 
+		case SET_FUNC_ADDRESS:
+			if(xl_priv->xl_message_level) 
+				printk(KERN_INFO "%s: Functional Address Set \n",dev->name) ;  
+			break ; 
+		case CLOSE_NIC:
+			if(xl_priv->xl_message_level)
+				printk(KERN_INFO "%s: Received CLOSE_NIC interrupt in interrupt handler \n",dev->name) ; 	
+			break ; 
+		case SET_MULTICAST_MODE:
+			if(xl_priv->xl_message_level)
+				printk(KERN_INFO "%s: Multicast options successfully changed\n",dev->name) ; 
+			break ;
+		case SET_RECEIVE_MODE:
+			if(xl_priv->xl_message_level) {  
+				if (xl_priv->xl_copy_all_options == 0x0004) 
+					printk(KERN_INFO "%s: Entering promiscuous mode \n", dev->name) ; 
+				else
+					printk(KERN_INFO "%s: Entering normal receive mode \n",dev->name) ; 
+			}
+			break ; 
+ 
+		} /* switch */
+		break ; 
+	} /* switch */
+	return ; 	
+} 
+
+static struct net_device_stats * xl_get_stats(struct net_device *dev)
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+	return (struct net_device_stats *) &xl_priv->xl_stats; 
+}
+
+static int xl_set_mac_address (struct net_device *dev, void *addr) 
+{
+	struct sockaddr *saddr = addr ; 
+	struct xl_private *xl_priv = (struct xl_private *)dev->priv ; 
+
+	if (netif_running(dev)) { 
+		printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ; 
+		return -EIO ; 
+	}
+
+	memcpy(xl_priv->xl_laa, saddr->sa_data,dev->addr_len) ; 
+	
+	if (xl_priv->xl_message_level) { 
+ 		printk(KERN_INFO "%s: MAC/LAA Set to  = %x.%x.%x.%x.%x.%x\n",dev->name, xl_priv->xl_laa[0],
+		xl_priv->xl_laa[1], xl_priv->xl_laa[2],
+		xl_priv->xl_laa[3], xl_priv->xl_laa[4],
+		xl_priv->xl_laa[5]);
+	} 
+
+	return 0 ; 
+}
+
+static void xl_arb_cmd(struct net_device *dev)
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv;
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 arb_cmd ; 
+	u16 lan_status, lan_status_diff ; 
+
+	writel( ( MEM_BYTE_READ | 0xD0000 | xl_priv->arb), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	arb_cmd = readb(xl_mmio + MMIO_MACDATA) ; 
+	
+	if (arb_cmd == RING_STATUS_CHANGE) { /* Ring.Status.Change */
+		writel( ( (MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+		 
+		printk(KERN_INFO "%s: Ring Status Change: New Status = %04x\n", dev->name, ntohs(readw(xl_mmio + MMIO_MACDATA) )) ; 
+
+		lan_status = ntohs(readw(xl_mmio + MMIO_MACDATA));
+	
+		/* Acknowledge interrupt, this tells nic we are done with the arb */
+		writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 
+			
+		lan_status_diff = xl_priv->xl_lan_status ^ lan_status ; 
+
+		if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) { 
+			if (lan_status_diff & LSC_LWF) 
+				printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name);
+			if (lan_status_diff & LSC_ARW) 
+				printk(KERN_WARNING "%s: Auto removal error\n",dev->name);
+			if (lan_status_diff & LSC_FPE)
+				printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name);
+			if (lan_status_diff & LSC_RR) 
+				printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name);
+		
+			/* Adapter has been closed by the hardware */
+
+			netif_stop_queue(dev);
+			xl_freemem(dev) ; 
+			free_irq(dev->irq,dev);
+			
+			printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ; 
+		} /* If serious error */
+		
+		if (xl_priv->xl_message_level) { 
+			if (lan_status_diff & LSC_SIG_LOSS) 
+					printk(KERN_WARNING "%s: No receive signal detected \n", dev->name) ; 
+			if (lan_status_diff & LSC_HARD_ERR)
+					printk(KERN_INFO "%s: Beaconing \n",dev->name);
+			if (lan_status_diff & LSC_SOFT_ERR)
+					printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame \n",dev->name);
+			if (lan_status_diff & LSC_TRAN_BCN) 
+					printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n",dev->name);
+			if (lan_status_diff & LSC_SS) 
+					printk(KERN_INFO "%s: Single Station on the ring \n", dev->name);
+			if (lan_status_diff & LSC_RING_REC)
+					printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name);
+			if (lan_status_diff & LSC_FDX_MODE)
+					printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name);
+		} 	
+		
+		if (lan_status_diff & LSC_CO) { 
+				if (xl_priv->xl_message_level) 
+					printk(KERN_INFO "%s: Counter Overflow \n", dev->name);
+				/* Issue READ.LOG command */
+				xl_srb_cmd(dev, READ_LOG) ; 	
+		}
+
+		/* There is no command in the tech docs to issue the read_sr_counters */
+		if (lan_status_diff & LSC_SR_CO) { 
+			if (xl_priv->xl_message_level)
+				printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name);
+		}
+
+		xl_priv->xl_lan_status = lan_status ; 
+	
+	}  /* Lan.change.status */
+	else if ( arb_cmd == RECEIVE_DATA) { /* Received.Data */
+#if XL_DEBUG
+		printk(KERN_INFO "Received.Data \n") ; 
+#endif 		
+		writel( ((MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+		xl_priv->mac_buffer = ntohs(readw(xl_mmio + MMIO_MACDATA)) ;
+		
+		/* Now we are going to be really basic here and not do anything
+		 * with the data at all. The tech docs do not give me enough
+		 * information to calculate the buffers properly so we're
+		 * just going to tell the nic that we've dealt with the frame
+		 * anyway.
+		 */
+
+		dev->last_rx = jiffies ; 
+		/* Acknowledge interrupt, this tells nic we are done with the arb */
+		writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 
+
+		/* Is the ASB free ? */ 	
+			
+		xl_priv->asb_queued = 0 ; 			
+		writel( ((MEM_BYTE_READ | 0xD0000 | xl_priv->asb) + 2), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+		if (readb(xl_mmio + MMIO_MACDATA) != 0xff) { 
+			xl_priv->asb_queued = 1 ;
+
+			xl_wait_misr_flags(dev) ;  
+
+			writel(MEM_BYTE_WRITE | MF_ASBFR, xl_mmio + MMIO_MAC_ACCESS_CMD); 
+			writeb(0xff, xl_mmio + MMIO_MACDATA) ;
+			writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+			writeb(MISR_ASBFR, xl_mmio + MMIO_MACDATA) ; 
+			return ; 	
+			/* Drop out and wait for the bottom half to be run */
+		}
+	
+		xl_asb_cmd(dev) ; 
+		
+	} else {
+		printk(KERN_WARNING "%s: Received unknown arb (xl_priv) command: %02x \n",dev->name,arb_cmd) ; 
+	}
+
+	/* Acknowledge the arb interrupt */
+
+	writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; 
+
+	return ; 
+}
+
+
+/*
+ *	There is only one asb command, but we can get called from different
+ *	places.
+ */
+
+static void xl_asb_cmd(struct net_device *dev)
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+
+	if (xl_priv->asb_queued == 1) 
+		writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; 
+		
+	writel(MEM_BYTE_WRITE | 0xd0000 | xl_priv->asb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(0x81, xl_mmio + MMIO_MACDATA) ; 
+
+	writel(MEM_WORD_WRITE | 0xd0000 | xl_priv->asb | 6, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writew(ntohs(xl_priv->mac_buffer), xl_mmio + MMIO_MACDATA) ; 
+
+	xl_wait_misr_flags(dev) ; 	
+
+	writel(MEM_BYTE_WRITE | MF_RASB, xl_mmio + MMIO_MAC_ACCESS_CMD); 
+	writeb(0xff, xl_mmio + MMIO_MACDATA) ;
+
+	writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(MISR_RASB, xl_mmio + MMIO_MACDATA) ; 
+
+	xl_priv->asb_queued = 2 ; 
+
+	return ; 
+}
+
+/*
+ * 	This will only get called if there was an error
+ *	from the asb cmd.
+ */
+static void xl_asb_bh(struct net_device *dev) 
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 ret_code ; 
+
+	writel(MMIO_BYTE_READ | 0xd0000 | xl_priv->asb | 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	ret_code = readb(xl_mmio + MMIO_MACDATA) ; 
+	switch (ret_code) { 
+		case 0x01:
+			printk(KERN_INFO "%s: ASB Command, unrecognized command code \n",dev->name) ;
+			break ;
+		case 0x26:
+			printk(KERN_INFO "%s: ASB Command, unexpected receive buffer \n", dev->name) ; 
+			break ; 
+		case 0x40:
+			printk(KERN_INFO "%s: ASB Command, Invalid Station ID \n", dev->name) ; 
+			break ;  
+	}
+	xl_priv->asb_queued = 0 ; 
+	writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ;
+	return ;  
+}
+
+/* 	
+ *	Issue srb commands to the nic 
+ */
+
+static void xl_srb_cmd(struct net_device *dev, int srb_cmd) 
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+
+	switch (srb_cmd) { 
+	case READ_LOG:
+		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(READ_LOG, xl_mmio + MMIO_MACDATA) ; 
+		break; 
+
+	case CLOSE_NIC:
+		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(CLOSE_NIC, xl_mmio + MMIO_MACDATA) ; 
+		break ;
+
+	case SET_RECEIVE_MODE:
+		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(SET_RECEIVE_MODE, xl_mmio + MMIO_MACDATA) ; 
+		writel(MEM_WORD_WRITE | 0xD0000 | xl_priv->srb | 4, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writew(xl_priv->xl_copy_all_options, xl_mmio + MMIO_MACDATA) ; 
+		break ;
+
+	case SET_FUNC_ADDRESS:
+		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(SET_FUNC_ADDRESS, xl_mmio + MMIO_MACDATA) ; 
+		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 6 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(xl_priv->xl_functional_addr[0], xl_mmio + MMIO_MACDATA) ; 
+		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 7 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(xl_priv->xl_functional_addr[1], xl_mmio + MMIO_MACDATA) ; 
+		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 8 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(xl_priv->xl_functional_addr[2], xl_mmio + MMIO_MACDATA) ; 
+		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 9 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+		writeb(xl_priv->xl_functional_addr[3], xl_mmio + MMIO_MACDATA) ;
+		break ;  
+	} /* switch */
+
+
+	xl_wait_misr_flags(dev)  ; 
+
+	/* Write 0xff to the CSRB flag */
+	writel(MEM_BYTE_WRITE | MF_CSRB , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(0xFF, xl_mmio + MMIO_MACDATA) ; 
+	/* Set csrb bit in MISR register to process command */
+	writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(MISR_CSRB, xl_mmio + MMIO_MACDATA) ; 
+	xl_priv->srb_queued = 1 ; 
+
+	return ; 
+}
+
+/*
+ * This is nasty, to use the MISR command you have to wait for 6 memory locations
+ * to be zero. This is the way the driver does on other OS'es so we should be ok with 
+ * the empty loop.
+ */
+
+static void xl_wait_misr_flags(struct net_device *dev) 
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
+	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	
+	int i  ; 
+	
+	writel(MMIO_BYTE_READ | MISR_RW, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	if (readb(xl_mmio + MMIO_MACDATA) != 0) {  /* Misr not clear */
+		for (i=0; i<6; i++) { 
+			writel(MEM_BYTE_READ | 0xDFFE0 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+			while (readb(xl_mmio + MMIO_MACDATA) != 0 ) {} ; /* Empty Loop */
+		} 
+	}
+
+	writel(MMIO_BYTE_WRITE | MISR_AND, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
+	writeb(0x80, xl_mmio + MMIO_MACDATA) ; 
+
+	return ; 
+} 
+
+/*
+ *	Change mtu size, this should work the same as olympic
+ */
+
+static int xl_change_mtu(struct net_device *dev, int mtu) 
+{
+	struct xl_private *xl_priv = (struct xl_private *) dev->priv;
+	u16 max_mtu ; 
+
+	if (xl_priv->xl_ring_speed == 4)
+		max_mtu = 4500 ; 
+	else
+		max_mtu = 18000 ; 
+	
+	if (mtu > max_mtu)
+		return -EINVAL ; 
+	if (mtu < 100) 
+		return -EINVAL ; 
+
+	dev->mtu = mtu ; 
+	xl_priv->pkt_buf_sz = mtu + TR_HLEN ; 
+
+	return 0 ; 
+}
+
+static void __devexit xl_remove_one (struct pci_dev *pdev)
+{
+	struct net_device *dev = pdev->driver_data;
+	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+	
+	unregister_trdev(dev);
+	iounmap(xl_priv->xl_mmio) ; 
+	pci_release_regions(pdev) ; 
+	pci_set_drvdata(pdev,NULL) ; 
+	kfree(dev);
+	return ; 
+}
+
+static struct pci_driver xl_3c359_driver = {
+	name:		"3c359",
+	id_table:	xl_pci_tbl,
+	probe:		xl_probe,
+	remove:		__devexit_p(xl_remove_one),
+};
+
+static int __init xl_pci_init (void)
+{
+	return pci_module_init (&xl_3c359_driver);
+}
+
+
+static void __exit xl_pci_cleanup (void)
+{
+	pci_unregister_driver (&xl_3c359_driver);
+}
+
+module_init(xl_pci_init);
+module_exit(xl_pci_cleanup);
+
+MODULE_LICENSE("GPL") ; 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/3c359.h linux/drivers/net/tokenring/3c359.h
--- linux.orig/drivers/net/tokenring/3c359.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/tokenring/3c359.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,294 @@
+/*
+ *  3c359.h (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved
+ *
+ *  Linux driver for 3Com 3C359 Token Link PCI XL cards.
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License Version 2 or (at your option) 
+ *  any later verion, incorporated herein by reference.
+ */
+
+#ifndef PCI_DEVICE_ID_3COM_3C359
+#define PCI_DEVICE_ID_3COM_3C359 0x3590
+#endif
+
+/* Memory Access Commands */
+#define IO_BYTE_READ 0x28 << 24
+#define IO_BYTE_WRITE 0x18 << 24 
+#define IO_WORD_READ 0x20 << 24
+#define IO_WORD_WRITE 0x10 << 24
+#define MMIO_BYTE_READ 0x88 << 24
+#define MMIO_BYTE_WRITE 0x48 << 24
+#define MMIO_WORD_READ 0x80 << 24
+#define MMIO_WORD_WRITE 0x40 << 24
+#define MEM_BYTE_READ 0x8C << 24
+#define MEM_BYTE_WRITE 0x4C << 24
+#define MEM_WORD_READ 0x84 << 24
+#define MEM_WORD_WRITE 0x44 << 24
+
+#define PMBAR 0x1C80
+#define PMB_CPHOLD (1<<10)
+
+#define CPATTENTION 0x180D
+#define CPA_PMBARVIS (1<<7)
+#define CPA_MEMWREN (1<<6)
+
+#define SWITCHSETTINGS 0x1C88
+#define EECONTROL 0x1C8A
+#define EEDATA 0x1C8C
+#define EEREAD 0x0080 
+#define EEWRITE 0x0040
+#define EEERASE 0x0060
+#define EE_ENABLE_WRITE 0x0030
+#define EEBUSY (1<<15)
+
+#define WRBR 0xCDE02
+#define WWOR 0xCDE04
+#define WWCR 0xCDE06
+#define MACSTATUS 0xCDE08 
+#define MISR_RW 0xCDE0B
+#define MISR_AND 0xCDE2B
+#define MISR_SET 0xCDE4B
+#define RXBUFAREA 0xCDE10
+#define RXEARLYTHRESH 0xCDE12
+#define TXSTARTTHRESH 0x58
+#define DNPRIREQTHRESH 0x2C
+
+#define MISR_CSRB (1<<5)
+#define MISR_RASB (1<<4)
+#define MISR_SRBFR (1<<3)
+#define MISR_ASBFR (1<<2)
+#define MISR_ARBF (1<<1) 
+
+/* MISR Flags memory locations */
+#define MF_SSBF 0xDFFE0 
+#define MF_ARBF 0xDFFE1
+#define MF_ASBFR 0xDFFE2
+#define MF_SRBFR 0xDFFE3
+#define MF_RASB 0xDFFE4
+#define MF_CSRB 0xDFFE5
+
+#define MMIO_MACDATA 0x10 
+#define MMIO_MAC_ACCESS_CMD 0x14
+#define MMIO_TIMER 0x1A
+#define MMIO_DMA_CTRL 0x20
+#define MMIO_DNLISTPTR 0x24
+#define MMIO_HASHFILTER 0x28
+#define MMIO_CONFIG 0x29
+#define MMIO_DNPRIREQTHRESH 0x2C
+#define MMIO_DNPOLL 0x2D
+#define MMIO_UPPKTSTATUS 0x30
+#define MMIO_FREETIMER 0x34
+#define MMIO_COUNTDOWN 0x36
+#define MMIO_UPLISTPTR 0x38
+#define MMIO_UPPOLL 0x3C
+#define MMIO_UPBURSTTHRESH 0x40
+#define MMIO_DNBURSTTHRESH 0x41
+#define MMIO_INTSTATUS_AUTO 0x56
+#define MMIO_TXSTARTTHRESH 0x58
+#define MMIO_INTERRUPTENABLE 0x5A
+#define MMIO_INDICATIONENABLE 0x5C
+#define MMIO_COMMAND 0x5E  /* These two are meant to be the same */
+#define MMIO_INTSTATUS 0x5E /* Makes the code more readable this way */
+#define INTSTAT_CMD_IN_PROGRESS (1<<12) 
+#define INTSTAT_SRB (1<<14)
+#define INTSTAT_INTLATCH (1<<0)
+
+/* Indication / Interrupt Mask 
+ * Annoyingly the bits to be set in the indication and interrupt enable
+ * do not match with the actual bits received in the interrupt, although
+ * they are in the same order. 
+ * The mapping for the indication / interrupt are:
+ * Bit	Indication / Interrupt
+ *   0	HostError
+ *   1	txcomplete
+ *   2	updneeded
+ *   3	rxcomplete
+ *   4	intrequested
+ *   5	macerror
+ *   6  dncomplete
+ *   7	upcomplete
+ *   8	txunderrun
+ *   9	asbf
+ *  10	srbr
+ *  11	arbc
+ *
+ *  The only ones we don't want to receive are txcomplete and rxcomplete
+ *  we use dncomplete and upcomplete instead.
+ */
+
+#define INT_MASK 0xFF5
+
+/* Note the subtle difference here, IND and INT */
+
+#define SETINDENABLE (8<<12)
+#define SETINTENABLE (7<<12)
+#define SRBBIT (1<<10)
+#define ASBBIT (1<<9)
+#define ARBBIT (1<<11)
+
+#define SRB 0xDFE90
+#define ASB 0xDFED0
+#define ARB 0xD0000
+#define SCRATCH 0xDFEF0
+
+#define INT_REQUEST 0x6000 /* (6 << 12) */
+#define ACK_INTERRUPT 0x6800 /* (13 <<11) */
+#define GLOBAL_RESET 0x00 
+#define DNDISABLE 0x5000 
+#define DNENABLE 0x4800 
+#define DNSTALL 0x3002
+#define DNRESET 0x5800
+#define DNUNSTALL 0x3003
+#define UPRESET 0x2800
+#define UPSTALL 0x3000
+#define UPUNSTALL 0x3001
+#define SETCONFIG 0x4000
+#define SETTXSTARTTHRESH 0x9800 
+
+/* Received Interrupts */
+#define ASBFINT (1<<13)
+#define SRBRINT (1<<14)
+#define ARBCINT (1<<15)
+#define TXUNDERRUN (1<<11)
+
+#define UPCOMPINT (1<<10)
+#define DNCOMPINT (1<<9)
+#define HARDERRINT (1<<7)
+#define RXCOMPLETE (1<<4)
+#define TXCOMPINT (1<<2)
+#define HOSTERRINT (1<<1)
+
+/* Receive descriptor bits */
+#define RXOVERRUN (1<<19)
+#define RXFC (1<<21)
+#define RXAR (1<<22)
+#define RXUPDCOMPLETE (1<<23)
+#define RXUPDFULL (1<<24)
+#define RXUPLASTFRAG (1<<31)
+
+/* Transmit descriptor bits */
+#define TXDNCOMPLETE (1<<16)
+#define TXTXINDICATE (1<<27)
+#define TXDPDEMPTY (1<<29)
+#define TXDNINDICATE (1<<31)
+#define TXDNFRAGLAST (1<<31)
+
+/* Interrupts to Acknowledge */
+#define LATCH_ACK 1 
+#define TXCOMPACK (1<<1)
+#define INTREQACK (1<<2)
+#define DNCOMPACK (1<<3)
+#define UPCOMPACK (1<<4)
+#define ASBFACK (1<<5)
+#define SRBRACK (1<<6)
+#define ARBCACK (1<<7)
+
+#define XL_IO_SPACE 128
+#define SRB_COMMAND_SIZE 50
+
+/* Adapter Commands */
+#define REQUEST_INT 0x00
+#define MODIFY_OPEN_PARMS 0x01
+#define RESTORE_OPEN_PARMS 0x02
+#define OPEN_NIC 0x03
+#define CLOSE_NIC 0x04
+#define SET_SLEEP_MODE 0x05
+#define SET_GROUP_ADDRESS 0x06
+#define SET_FUNC_ADDRESS 0x07
+#define READ_LOG 0x08
+#define SET_MULTICAST_MODE 0x0C
+#define CHANGE_WAKEUP_PATTERN 0x0D
+#define GET_STATISTICS 0x13
+#define SET_RECEIVE_MODE 0x1F
+
+/* ARB Commands */
+#define RECEIVE_DATA 0x81
+#define RING_STATUS_CHANGE 0x84
+
+/* ASB Commands */
+#define ASB_RECEIVE_DATE 0x81 
+
+/* Defines for LAN STATUS CHANGE reports */
+#define LSC_SIG_LOSS 0x8000
+#define LSC_HARD_ERR 0x4000
+#define LSC_SOFT_ERR 0x2000
+#define LSC_TRAN_BCN 0x1000
+#define LSC_LWF      0x0800
+#define LSC_ARW      0x0400
+#define LSC_FPE      0x0200
+#define LSC_RR       0x0100
+#define LSC_CO       0x0080
+#define LSC_SS       0x0040
+#define LSC_RING_REC 0x0020
+#define LSC_SR_CO    0x0010
+#define LSC_FDX_MODE 0x0004
+
+#define XL_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */
+
+/* 3c359 defaults for buffers */
+ 
+#define XL_RX_RING_SIZE 16 /* must be a power of 2 */
+#define XL_TX_RING_SIZE 16 /* must be a power of 2 */
+
+#define PKT_BUF_SZ 4096 /* Default packet size */
+
+/* 3c359 data structures */
+
+struct xl_tx_desc {
+	u32 dnnextptr ; 
+	u32 framestartheader ; 
+	u32 buffer ;
+	u32 buffer_length ;
+};
+
+struct xl_rx_desc {
+	u32 upnextptr ; 
+	u32 framestatus ; 
+	u32 upfragaddr ; 
+	u32 upfraglen ; 
+};
+
+struct xl_private {
+	
+
+	/* These two structures must be aligned on 8 byte boundaries */
+
+	/* struct xl_rx_desc xl_rx_ring[XL_RX_RING_SIZE]; */
+	/* struct xl_tx_desc xl_tx_ring[XL_TX_RING_SIZE]; */
+	struct xl_rx_desc *xl_rx_ring ; 
+	struct xl_tx_desc *xl_tx_ring ; 
+	struct sk_buff *tx_ring_skb[XL_TX_RING_SIZE], *rx_ring_skb[XL_RX_RING_SIZE];	
+	int tx_ring_head, tx_ring_tail ;  
+	int rx_ring_tail, rx_ring_no ; 
+	int free_ring_entries ; 
+
+	u16 srb;
+	u16 arb;
+	u16 asb;
+
+	u8 *xl_mmio;
+	char *xl_card_name;
+	struct pci_dev *pdev ; 
+	
+	spinlock_t xl_lock ; 
+
+	volatile int srb_queued;    
+	struct wait_queue *srb_wait;
+	volatile int asb_queued;   
+
+	struct net_device_stats xl_stats ;
+
+	u16 mac_buffer ; 	
+	u16 xl_lan_status ;
+	u8 xl_ring_speed ;
+	u16 pkt_buf_sz ; 
+	u8 xl_message_level; 
+	u16 xl_copy_all_options ;  
+	unsigned char xl_functional_addr[4] ; 
+	u16 xl_addr_table_addr, xl_parms_addr ; 
+	u8 xl_laa[6] ; 
+	u32 rx_ring_dma_addr ; 
+	u32 tx_ring_dma_addr ; 
+};
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/3c359_microcode.h linux/drivers/net/tokenring/3c359_microcode.h
--- linux.orig/drivers/net/tokenring/3c359_microcode.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/tokenring/3c359_microcode.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,1585 @@
+
+/*
+ * The firmware this driver downloads into the tokenring card is a
+ * separate program and is not GPL'd source code, even though the Linux
+ * side driver and the routine that loads this data into the card are.
+ *
+ * This firmware is licensed to you strictly for use in conjunction
+ * with the use of 3Com 3C359 TokenRing adapters. There is no
+ * waranty expressed or implied about its fitness for any purpose.
+ */
+
+/* 3c359_microcode.mac: 3Com 3C359 Tokenring microcode.
+ *
+ * Notes:
+ *  - Loaded from xl_init upon adapter initialization.
+ *
+ * Available from 3Com as part of their standard 3C359 driver. 
+ *
+ * mc_size *must* must match the microcode being used, each version is a 
+ * different length.
+ */
+
+
+#if defined(CONFIG_3C359) || defined(CONFIG_3C359_MODULE) 
+
+static int mc_size = 24880 ; 
+
+u8 microcode[] = { 
+ 0xfe,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x33,0x2f,0x30,0x32,0x2f,0x39,0x39,0x20,0x31
+,0x37,0x3a,0x31,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46
+,0x00,0x00,0x07,0xff,0x02,0x00,0xfe,0x9f,0x06,0x00,0x00,0x7c,0x48,0x00,0x00,0x70
+,0x82,0x00,0xff,0xff,0x86,0x00,0xff,0xff,0x88,0x00,0xff,0xff,0x9a,0x00,0xff,0xff
+,0xff,0xff,0x11,0x00,0xc0,0x00,0xff,0xff,0xff,0xff,0x11,0x22,0x33,0x44,0x55,0x66
+,0x33,0x43,0x4f,0x4d,0x20,0x42,0x41,0x42,0x45,0x11,0x40,0xc0,0x00,0xff,0xff,0xff
+,0xff,0x11,0x22,0x33,0x44,0x55,0x66,0x53,0x74,0x61,0x72,0x74,0x20,0x6f,0x66,0x20
+,0x4c,0x4c,0x43,0x20,0x66,0x72,0x61,0x6d,0x65,0x2e,0x20,0x20,0x54,0x6f,0x74,0x61
+,0x6c,0x20,0x64,0x61,0x74,0x61,0x20,0x73,0x69,0x7a,0x65,0x20,0x69,0x73,0x20,0x78
+,0x78,0x78,0x20,0x20,0x20,0x42,0x41,0x42,0x45,0xe8,0xd2,0x01,0x83,0x3e,0xf7,0x34
+,0x00,0x75,0x21,0xe8,0x41,0x00,0x83,0x3e,0xf7,0x34,0x00,0x75,0x17,0xe8,0x82,0x00
+,0x83,0x3e,0xf7,0x34,0x00,0x75,0x0d,0xe8,0xbf,0x00,0x83,0x3e,0xf7,0x34,0x00,0x75
+,0x03,0xe8,0x41,0x02,0xc3,0x1e,0xb8,0x00,0xf0,0x8e,0xd8,0x33,0xf6,0xb9,0x00,0x80
+,0x33,0xdb,0xad,0x03,0xd8,0xe2,0xfb,0x1f,0xb8,0x00,0x00,0x83,0xfb,0x00,0x74,0x03
+,0xb8,0x22,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0xba,0x56,0x00,0xb0,0xff,0xee,0x33,0xc0
+,0x8e,0xc0,0x33,0xf6,0xb9,0xff,0x7f,0x83,0x3e,0xff,0x34,0x00,0x74,0x08,0x8d,0x3e
+,0x30,0x61,0xd1,0xef,0x2b,0xcf,0x26,0x8b,0x1c,0x26,0xc7,0x04,0xff,0xff,0x26,0x83
+,0x3c,0xff,0x75,0x17,0x26,0xc7,0x04,0x00,0x00,0x26,0x83,0x3c,0x00,0x75,0x0c,0x26
+,0x89,0x1c,0x46,0x46,0xe2,0xe0,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x24,0x00,0xa3,0xf7
+,0x34,0xc3,0xfa,0xb4,0xd7,0x9e,0x73,0x3a,0x75,0x38,0x79,0x36,0x7b,0x34,0x9f,0xb1
+,0x05,0xd2,0xec,0x73,0x2d,0xb0,0x40,0xd0,0xe0,0x71,0x27,0x79,0x25,0xd0,0xe0,0x73
+,0x21,0x7b,0x1f,0x32,0xc0,0x75,0x1b,0x32,0xe4,0x9e,0x72,0x16,0x74,0x14,0x78,0x12
+,0x7a,0x10,0x9f,0xd2,0xec,0x72,0x0b,0xd0,0xe4,0x70,0x07,0x75,0x05,0xb8,0x00,0x00
+,0xeb,0x03,0xb8,0x26,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0xba,0x5a,0x00,0x33,0xc0,0xef
+,0xef,0xef,0xef,0xb0,0x00,0xe6,0x56,0xb0,0x00,0xe6,0x54,0xba,0x52,0x00,0xb8,0x01
+,0x01,0xef,0xe8,0xca,0x00,0x3c,0x01,0x75,0x7f,0xe8,0x83,0x00,0xba,0x52,0x00,0xb8
+,0x02,0x02,0xef,0xe8,0xb9,0x00,0x3c,0x02,0x75,0x6e,0xe8,0x7a,0x00,0xba,0x52,0x00
+,0xb8,0x04,0x04,0xef,0xe8,0xa8,0x00,0x3c,0x04,0x75,0x5d,0xe8,0x71,0x00,0xba,0x52
+,0x00,0xb8,0x08,0x08,0xef,0xe8,0x97,0x00,0x3c,0x08,0x75,0x4c,0xe8,0x68,0x00,0xba
+,0x52,0x00,0xb8,0x10,0x10,0xef,0xe8,0x86,0x00,0x3c,0x10,0x75,0x3b,0xe8,0x5f,0x00
+,0xba,0x52,0x00,0xb8,0x20,0x20,0xef,0xe8,0x75,0x00,0x3c,0x20,0x75,0x2a,0xe8,0x56
+,0x00,0xba,0x52,0x00,0xb8,0x40,0x40,0xef,0xe8,0x64,0x00,0x3c,0x40,0x75,0x19,0xe8
+,0x4d,0x00,0xba,0x52,0x00,0xb8,0x80,0x80,0xef,0xe8,0x53,0x00,0x3c,0x80,0x75,0x08
+,0xe8,0x44,0x00,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x28,0x00,0xa3,0xf7,0x34,0xc3,0xba
+,0x5a,0x00,0xb8,0x00,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x01,0x80,0xef,0xc3,0xba
+,0x5a,0x00,0xb8,0x02,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x03,0x80,0xef,0xc3,0xba
+,0x5a,0x00,0xb8,0x04,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x05,0x80,0xef,0xc3,0xba
+,0x5a,0x00,0xb8,0x06,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x07,0x80,0xef,0xc3,0xb9
+,0xff,0xff,0xe4,0x58,0xe4,0x54,0x3c,0x00,0x75,0x03,0x49,0x75,0xf7,0xc3,0xfa,0x32
+,0xc0,0xe6,0x56,0xe4,0x56,0x3c,0x00,0x74,0x03,0xe9,0x82,0x00,0xb0,0xff,0xe6,0x56
+,0xe4,0x56,0x3c,0xff,0x75,0x78,0xba,0x52,0x00,0xb8,0xff,0xff,0xef,0xed,0x3c,0xff
+,0x75,0x6c,0xb8,0x00,0xff,0xef,0xed,0x3c,0x00,0x75,0x63,0xb0,0xff,0xe6,0x54,0xe4
+,0x54,0x3c,0xff,0x75,0x59,0x32,0xc0,0xe6,0x54,0xe4,0x54,0x3c,0x00,0x75,0x4f,0xb0
+,0x0f,0xe6,0x50,0xe4,0x50,0x24,0x0f,0x3c,0x0f,0x75,0x43,0xb0,0x00,0xe6,0x50,0xe4
+,0x50,0x24,0x0f,0x3c,0x00,0x75,0x37,0x8c,0xc8,0x8e,0xc0,0xbe,0x70,0x00,0x26,0x8b
+,0x14,0x26,0x8b,0x5c,0x02,0xb8,0x00,0x00,0xef,0xed,0x23,0xc3,0x3d,0x00,0x00,0x75
+,0x1d,0xb8,0xff,0xff,0x23,0xc3,0xef,0x8b,0xc8,0xed,0x23,0xc3,0x3b,0xc1,0x75,0x0e
+,0x83,0xc6,0x04,0x26,0x83,0x3c,0xff,0x75,0xd5,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x2a
+,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0x33,0xc0,0xbf,0x00,0x20,0xb9,0x17,0x00,0xf3,0xab
+,0xbf,0x00,0x30,0xb9,0x17,0x00,0xf3,0xab,0xbf,0x00,0x22,0xb9,0x40,0x00,0xf3,0xab
+,0xbf,0x00,0x32,0xb9,0x40,0x00,0xf3,0xab,0xfc,0x1e,0x8c,0xc8,0x8e,0xd8,0x33,0xc0
+,0x8e,0xc0,0xbe,0x92,0x00,0xbf,0x00,0x20,0xb9,0x17,0x00,0xf3,0xa4,0xbe,0xa9,0x00
+,0xbf,0x00,0x22,0xb9,0x40,0x00,0xf3,0xa4,0x1f,0xc7,0x06,0xfb,0x34,0x64,0x00,0xba
+,0x08,0x00,0xb8,0x0f,0x00,0xef,0xe8,0x82,0x01,0xe8,0x9b,0x01,0x72,0x0d,0xc7,0x06
+,0xf7,0x34,0x2c,0x00,0xc7,0x06,0xf9,0x34,0x04,0x00,0xc3,0xba,0x0a,0x00,0x33,0xc0
+,0xef,0xe8,0x98,0x01,0xe8,0xb5,0x01,0xb8,0x17,0x00,0xba,0x9c,0x00,0xef,0xb8,0x00
+,0x10,0xba,0x9a,0x00,0xef,0xb8,0x17,0x00,0xa9,0x01,0x00,0x74,0x01,0x40,0xba,0x8c
+,0x00,0xef,0xb8,0x00,0x18,0xba,0x86,0x00,0xef,0xb8,0x0c,0x00,0xba,0x82,0x00,0xef
+,0xba,0x02,0x00,0xed,0x25,0xf9,0xff,0x0d,0x02,0x00,0xef,0xba,0x06,0x00,0x33,0xc0
+,0xef,0xba,0x04,0x00,0xb8,0x60,0x00,0xef,0xba,0x00,0x00,0xb8,0x18,0x00,0xef,0xba
+,0x80,0x00,0xb9,0xff,0xff,0xed,0xa9,0x01,0x00,0x75,0x04,0xe2,0xf8,0xeb,0x3e,0xba
+,0x0a,0x00,0xed,0xa9,0x00,0x40,0x74,0x35,0xa9,0x00,0x20,0x74,0x30,0x33,0xc0,0xef
+,0x51,0xb9,0xc8,0x00,0xe2,0xfe,0x59,0x1e,0x06,0x1f,0x26,0x8b,0x0e,0x02,0x30,0x83
+,0xf9,0x17,0x75,0x18,0x49,0x49,0xbe,0x02,0x20,0xbf,0x06,0x30,0xf3,0xa6,0x1f,0x23
+,0xc9,0x75,0x0a,0xff,0x0e,0xfb,0x34,0x74,0x12,0xe9,0x4d,0xff,0x1f,0xb8,0x2c,0x00
+,0xbb,0x00,0x00,0xa3,0xf7,0x34,0x89,0x1e,0xf9,0x34,0xc3,0xc7,0x06,0xfb,0x34,0x64
+,0x00,0xe8,0xd3,0x00,0x72,0x0d,0xc7,0x06,0xf7,0x34,0x2c,0x00,0xc7,0x06,0xf9,0x34
+,0x04,0x00,0xc3,0xe8,0xd6,0x00,0xe8,0xf3,0x00,0xb8,0x03,0x00,0xba,0x82,0x00,0xef
+,0xb8,0x40,0x80,0xba,0x98,0x00,0xef,0xb8,0x00,0x11,0xba,0x96,0x00,0xef,0xb8,0x40
+,0x00,0xa9,0x01,0x00,0x74,0x01,0x40,0xba,0x92,0x00,0xef,0xb8,0x00,0x19,0xba,0x8e
+,0x00,0xef,0xba,0x02,0x00,0xed,0x25,0xf9,0xff,0x0d,0x06,0x00,0xef,0xba,0x06,0x00
+,0x33,0xc0,0xef,0xba,0x00,0x00,0xb8,0x18,0x00,0xef,0xba,0x80,0x00,0xb9,0xff,0xff
+,0xed,0xa9,0x20,0x00,0x75,0x04,0xe2,0xf8,0xeb,0x43,0xba,0x0a,0x00,0xed,0xa9,0x00
+,0x40,0x74,0x3a,0xa9,0x00,0x20,0x74,0x35,0x33,0xc0,0xef,0x51,0xb9,0xc8,0x00,0xe2
+,0xfe,0x59,0x1e,0x06,0x1f,0x26,0x8b,0x0e,0x02,0x32,0x83,0xf9,0x40,0x75,0x1d,0x49
+,0x49,0xbe,0x02,0x22,0xbf,0x06,0x32,0xf3,0xa6,0x1f,0x23,0xc9,0x75,0x0f,0xff,0x0e
+,0xfb,0x34,0x74,0x03,0xe9,0x5a,0xff,0xb8,0x00,0x00,0xeb,0x0b,0x1f,0xb8,0x2c,0x00
+,0xbb,0x02,0x00,0x89,0x1e,0xf9,0x34,0xa3,0xf7,0x34,0xc3,0xba,0x02,0x00,0xb8,0x00
+,0x9c,0xef,0xba,0x00,0x00,0xb8,0x00,0x84,0xef,0x33,0xc0,0xef,0xba,0x0a,0x00,0xef
+,0xba,0x0e,0x00,0x33,0xc0,0xef,0xc3,0xba,0x0a,0x00,0xb9,0xff,0xff,0xed,0x25,0x00
+,0x60,0x3d,0x00,0x60,0x74,0x04,0xe2,0xf5,0xf8,0xc3,0xf9,0xc3,0xb0,0x00,0xe6,0x56
+,0xb8,0x00,0xff,0xba,0x52,0x00,0xef,0xb9,0xff,0xff,0xba,0x58,0x00,0xed,0x25,0xef
+,0x00,0x74,0x08,0xba,0x5a,0x00,0x33,0xc0,0xef,0xe2,0xef,0xc3,0xba,0x80,0x00,0xed
+,0xba,0x84,0x00,0xef,0xba,0x80,0x00,0xed,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xc6,0x06,0xec,0x34,0x15,0x33,0xc0,0x8e,0xd8,0x8e,0xc0,0x1e,0x8c,0xc8,0xbe,0x40
+,0x54,0xbf,0x60,0xfe,0x8e,0xd8,0xb9,0x10,0x00,0xf3,0xa4,0x1f,0xc7,0x06,0x80,0x36
+,0x10,0x35,0xc7,0x06,0x8c,0x36,0x30,0x35,0x8d,0x06,0x38,0x35,0xa3,0x30,0x35,0xa3
+,0x32,0x35,0x05,0x33,0x01,0xa3,0x34,0x35,0xc7,0x06,0x36,0x35,0x50,0x01,0xc7,0x06
+,0x84,0x36,0x80,0xfe,0xc7,0x06,0x88,0x36,0xc0,0xfe,0xc6,0x06,0xc2,0xfe,0xff,0xc6
+,0x06,0x93,0x36,0x80,0xc6,0x06,0x92,0x36,0x00,0xc6,0x06,0x80,0xfe,0x80,0xc7,0x06
+,0x82,0xfe,0x54,0x50,0xc7,0x06,0x84,0xfe,0x2b,0x4d,0xe5,0xce,0xa9,0x02,0x00,0x75
+,0x08,0xc6,0x06,0x81,0xfe,0x23,0xe9,0x05,0x00,0xc6,0x06,0x81,0xfe,0x22,0xa1,0xf7
+,0x34,0xa3,0x86,0xfe,0xb8,0x48,0x34,0x86,0xe0,0xa3,0x88,0xfe,0x8d,0x06,0x4e,0x34
+,0x86,0xe0,0xa3,0x8a,0xfe,0xb8,0x58,0x34,0x86,0xe0,0xa3,0x8c,0xfe,0xb8,0x9c,0x34
+,0x86,0xe0,0xa3,0x8e,0xfe,0x8d,0x06,0x20,0x03,0x86,0xe0,0xa3,0x90,0xfe,0x33,0xc0
+,0xba,0x72,0x00,0xef,0x33,0xc0,0xba,0x74,0x00,0xef,0xba,0x76,0x00,0xef,0xb8,0x80
+,0xfe,0x86,0xe0,0xba,0x72,0x00,0xef,0xe8,0xbf,0x07,0xba,0x0c,0x01,0xb8,0x40,0x40
+,0xef,0xed,0xba,0x6a,0x00,0xb8,0x03,0x00,0xc1,0xe0,0x08,0x0d,0x03,0x00,0xef,0xb9
+,0x0a,0x00,0xe8,0x94,0x00,0xba,0x6a,0x00,0xb8,0x03,0x00,0xc1,0xe0,0x08,0xef,0xa1
+,0x32,0x34,0xa3,0xa2,0x33,0xc7,0x06,0xa6,0x33,0x04,0x00,0x8d,0x06,0xa0,0x33,0xc1
+,0xe8,0x04,0xcd,0x39,0xc7,0x06,0x90,0x36,0xff,0xff,0xe9,0xe3,0x00,0x63,0x0d,0x66
+,0x0d,0x66,0x0d,0x8a,0x0d,0xe6,0x0e,0x75,0x12,0x2e,0x0f,0x03,0x0f,0x50,0x0f,0x60
+,0x0d,0x60,0x0d,0x60,0x0d,0xed,0x0f,0xe9,0x12,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
+,0x0d,0x60,0x0d,0x22,0x10,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0xfe,0x10,0x60
+,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0xaf,0x0f,0x32,0x10,0x37
+,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
+,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
+,0x0d,0x64,0x0e,0x00,0x0f,0x95,0x09,0x60,0x0a,0x49,0xbb,0xff,0xff,0xba,0x6a,0x00
+,0xed,0xa9,0x00,0x20,0x74,0x38,0x80,0x3e,0x80,0xfe,0x12,0x75,0x31,0xe8,0x4a,0x00
+,0xa1,0x32,0x34,0xa3,0xa2,0x33,0xc7,0x06,0xa6,0x33,0x04,0x00,0x8d,0x06,0xa0,0x33
+,0xc1,0xe8,0x04,0xcd,0x39,0xe8,0x22,0x00,0xc7,0x06,0xf3,0x34,0x46,0x00,0xc7,0x06
+,0xf5,0x34,0xff,0xff,0xc7,0x06,0x90,0x36,0xff,0xff,0x58,0xe9,0x32,0x00,0x4b,0x83
+,0xfb,0x00,0x75,0xb9,0x83,0xf9,0x00,0x75,0xb0,0xc3,0x52,0xba,0x6a,0x00,0xb8,0x03
+,0x00,0xc1,0xe0,0x08,0x0d,0x03,0x00,0xef,0x5a,0xc3,0x52,0xba,0x6a,0x00,0xb8,0x03
+,0x00,0xc1,0xe0,0x08,0xef,0x5a,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x68,0x80,0x07,0xa1,0x90,0x36,0xcd,0x35,0x8b,0x36,0x24,0x02,0x2e,0xff,0xa4,0x35
+,0x0a,0xfa,0x8a,0x26,0x94,0x36,0x88,0x26,0xe8,0x34,0xc6,0x06,0x94,0x36,0x00,0xfb
+,0x22,0xe4,0x75,0x01,0xc3,0xf6,0xc4,0x20,0x74,0x7d,0xf6,0xc4,0x08,0x74,0x05,0x80
+,0x0e,0x92,0x36,0x04,0x80,0x26,0xe8,0x34,0xd7,0xc4,0x1e,0x84,0x36,0x26,0x8b,0x37
+,0x81,0xe6,0xff,0x00,0x83,0xfe,0x20,0x76,0x05,0xb0,0x01,0xe9,0x28,0x00,0x53,0x06
+,0xd1,0xe6,0x2e,0xff,0x94,0x9d,0x06,0x07,0x5b,0x26,0x88,0x47,0x02,0x3c,0xff,0x74
+,0x07,0x3c,0xfe,0x75,0x11,0xe9,0x3b,0x00,0xf6,0x06,0x92,0x36,0x08,0x75,0x34,0xf6
+,0x06,0x92,0x36,0x04,0x74,0x2d,0x80,0x26,0x92,0x36,0xf3,0x80,0x3e,0x95,0x36,0x00
+,0x75,0x21,0x26,0x80,0x3f,0x05,0x75,0x13,0xc6,0x06,0x95,0x36,0x00,0x26,0x80,0x7f
+,0x06,0x00,0x74,0x07,0x26,0x8b,0x47,0x04,0xa2,0x95,0x36,0xba,0x0c,0x01,0xb8,0x40
+,0x40,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x10,0x75,0x03,0xe9,0x5b,0x00,0xf6
+,0xc4,0x04,0x74,0x05,0x80,0x0e,0x92,0x36,0x01,0x80,0x26,0xe8,0x34,0xeb,0xc4,0x3e
+,0x88,0x36,0x26,0x8b,0x35,0x83,0xe6,0x7f,0x83,0xfe,0x12,0x72,0x08,0x26,0xc6,0x45
+,0x02,0x01,0xe9,0x24,0x00,0x83,0xc6,0x20,0xd1,0xe6,0x2e,0xff,0x94,0x9d,0x06,0xc4
+,0x3e,0x88,0x36,0x26,0x88,0x45,0x02,0x3c,0xff,0x75,0x0e,0xf6,0x06,0x92,0x36,0x01
+,0x74,0x14,0xf6,0x06,0x92,0x36,0x02,0x75,0x0d,0x80,0x26,0x92,0x36,0xfc,0xba,0x0c
+,0x01,0xb8,0x20,0x20,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x08,0x74,0x22,0x80
+,0x26,0xe8,0x34,0xf7,0x80,0x0e,0x92,0x36,0x04,0xf6,0x06,0x92,0x36,0x08,0x74,0x11
+,0x80,0x26,0x92,0x36,0xf3,0xba,0x0c,0x01,0xb8,0x40,0x40,0xef,0xed,0x8a,0x26,0xe8
+,0x34,0xf6,0xc4,0x04,0x74,0x22,0x80,0x26,0xe8,0x34,0xfb,0x80,0x0e,0x92,0x36,0x01
+,0xf6,0x06,0x92,0x36,0x02,0x75,0x11,0x80,0x26,0x92,0x36,0xfe,0xba,0x0c,0x01,0xb8
+,0x20,0x20,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x01,0x74,0x67,0x80,0x26,0xe8
+,0x34,0xfe,0x80,0x3e,0xe8,0xff,0x00,0x74,0x39,0x80,0x3e,0xe8,0xff,0x04,0x74,0x32
+,0x80,0x3e,0xe8,0xff,0x01,0x75,0x21,0xe5,0x80,0xa9,0x00,0x07,0x74,0x0a,0xba,0x9e
+,0x00,0xb8,0x00,0x02,0xef,0xe9,0xef,0xff,0xc6,0x06,0xe8,0xff,0x03,0xba,0x0c,0x01
+,0xb8,0x08,0x08,0xef,0xed,0xe9,0x28,0x00,0x80,0x3e,0xe8,0xff,0x03,0x74,0x06,0xe9
+,0x1e,0x00,0xe9,0x00,0x00,0xba,0x10,0x01,0xb8,0x02,0x02,0xef,0xed,0xe5,0x00,0x0d
+,0x18,0x00,0xe7,0x00,0xe5,0x82,0x0d,0x02,0x00,0xe7,0x82,0xc6,0x06,0xe8,0xff,0x04
+,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x02,0x74,0x0d,0x80,0x26,0xe8,0x34,0xfd,0x80,0x26
+,0x92,0x36,0xbf,0xe8,0x4f,0x0b,0xfa,0xa0,0xe8,0x34,0x08,0x06,0x94,0x36,0xc6,0x06
+,0xe8,0x34,0x00,0xfb,0xc3,0xe8,0xe7,0x0f,0xc4,0x1e,0x84,0x36,0x2e,0xff,0x16,0x01
+,0x07,0x26,0x88,0x47,0x02,0xe9,0x7e,0xfe,0xe8,0x2d,0x10,0xc4,0x1e,0x84,0x36,0x2e
+,0xff,0x16,0x03,0x07,0x26,0x88,0x47,0x02,0xe9,0x6b,0xfe,0x8e,0x06,0x26,0x02,0x2e
+,0xff,0x16,0x07,0x07,0xc3,0xc3,0x83,0x3e,0xf5,0x34,0x00,0x74,0x0f,0xff,0x0e,0xf3
+,0x34,0x75,0x09,0xe8,0xc4,0xfd,0xc7,0x06,0xf5,0x34,0x00,0x00,0xf6,0x06,0x93,0x36
+,0x20,0x74,0x30,0xa1,0xc2,0x34,0x3b,0x06,0xe9,0x34,0xa3,0xe9,0x34,0x74,0x24,0x80
+,0x3e,0x95,0x36,0x00,0x75,0x1d,0xf7,0x06,0xe6,0x34,0x20,0x00,0x74,0x12,0xa9,0x20
+,0x00,0x74,0x0d,0x83,0x26,0xc2,0x34,0xdf,0x83,0x26,0xe9,0x34,0xdf,0xe9,0x03,0x00
+,0xe8,0xdd,0x09,0xba,0x06,0x01,0xed,0x8b,0xd0,0x81,0xe2,0x00,0xc0,0xc1,0xea,0x0e
+,0x03,0x16,0x74,0x34,0xc1,0xe0,0x02,0x11,0x06,0x72,0x34,0x73,0x04,0xff,0x06,0x74
+,0x34,0xba,0x02,0x01,0xed,0x8b,0xd0,0x81,0xe2,0x00,0xc0,0xc1,0xea,0x0e,0x03,0x16
+,0x70,0x34,0xc1,0xe0,0x02,0x11,0x06,0x6e,0x34,0x73,0x04,0xff,0x06,0x70,0x34,0xc7
+,0x06,0xa6,0x33,0x04,0x00,0xc7,0x06,0xaa,0x33,0x00,0x00,0x8d,0x06,0xa0,0x33,0xc1
+,0xe8,0x04,0xcd,0x39,0xc3,0x95,0x09,0x95,0x09,0x65,0x09,0x78,0x09,0x95,0x09,0x95
+,0x09,0x91,0x07,0x95,0x09,0x96,0x09,0x8b,0x09,0x95,0x09,0x95,0x09,0x95,0x09,0x95
+,0x09,0x95,0x09,0x95,0x09,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x90
+,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xe9,0xcc,0x00,0x8c,0xc0,0x40,0x8e,0xc0,0x26
+,0x8b,0x0e,0x06,0x00,0x86,0xe9,0x26,0x89,0x0e,0x06,0x00,0x8c,0xc2,0xc1,0xe2,0x04
+,0xbe,0x0e,0x00,0x26,0xa1,0x04,0x00,0xd0,0xe0,0x24,0xc0,0x8a,0xe0,0xc0,0xec,0x04
+,0x0a,0xc4,0x26,0xa2,0x05,0x00,0x26,0xa1,0x08,0x00,0xa9,0x00,0xc0,0x74,0x03,0xe9
+,0x9e,0x00,0x26,0xf6,0x06,0x10,0x00,0x80,0x75,0x03,0xe9,0x0a,0x00,0x26,0xa0,0x16
+,0x00,0x24,0x1f,0x32,0xe4,0x03,0xf0,0x80,0x3e,0xec,0x34,0x06,0x72,0x5c,0x80,0x3e
+,0x95,0x36,0x00,0x75,0x66,0x8b,0xfa,0x33,0xdb,0x8e,0xc3,0x26,0x89,0x1d,0x26,0x88
+,0x5d,0x04,0x51,0x50,0xc4,0x1e,0x8c,0x36,0xb9,0x0f,0x00,0x33,0xc0,0xe8,0x21,0x09
+,0x58,0x59,0x0b,0xdb,0x74,0x34,0xfe,0x0e,0xe6,0x3a,0x26,0xc6,0x07,0x81,0x26,0xc6
+,0x47,0x01,0x00,0x26,0xc6,0x47,0x02,0xff,0x26,0xc7,0x47,0x04,0x00,0x00,0x26,0x89
+,0x4f,0x0a,0x86,0xf2,0x26,0x89,0x57,0x06,0x26,0x89,0x77,0x08,0x26,0xc6,0x47,0x09
+,0x00,0x26,0xc6,0x47,0x0c,0x02,0xe8,0x8c,0x09,0xc3,0xff,0x06,0xec,0x33,0x8c,0xc0
+,0x48,0x8e,0xc0,0xfa,0xe8,0x97,0x10,0xfb,0xe9,0xeb,0xff,0x8c,0xc0,0x48,0x8e,0xc0
+,0xfa,0xe8,0x8a,0x10,0xfb,0xc3,0x8c,0xc0,0x8e,0xc0,0xfa,0xe8,0x80,0x10,0xfb,0xc3
+,0x80,0x3e,0x95,0x36,0x00,0x75,0x03,0xe9,0xc2,0x00,0xbf,0x08,0x00,0x26,0xf6,0x06
+,0x10,0x00,0x80,0x75,0x05,0x03,0xfe,0xe9,0x0c,0x00,0x26,0xa0,0x16,0x00,0x24,0x1f
+,0x32,0xe4,0x03,0xf0,0x03,0xfe,0xa0,0x95,0x36,0x3c,0x00,0x75,0x03,0xe9,0x9c,0x00
+,0x3c,0x01,0x74,0x0b,0x3c,0x02,0x74,0x14,0x3c,0x03,0x74,0x1d,0xe9,0x8d,0x00,0xc6
+,0x06,0x96,0x36,0x01,0xe8,0x3c,0x01,0x72,0x27,0xe9,0x80,0x00,0xc6,0x06,0x96,0x36
+,0x02,0xe8,0x83,0x00,0x72,0x1a,0xe9,0x73,0x00,0xc6,0x06,0x96,0x36,0x01,0xe8,0x22
+,0x01,0x72,0x0d,0xc6,0x06,0x96,0x36,0x02,0xe8,0x6c,0x00,0x72,0x03,0xe9,0x5c,0x00
+,0x53,0x06,0x50,0xc4,0x1e,0x8c,0x36,0xb9,0x0b,0x00,0x33,0xc0,0xe8,0x42,0x08,0x58
+,0x26,0xc6,0x07,0x82,0x26,0xc6,0x47,0x02,0xff,0x8d,0x06,0xe0,0xfe,0x86,0xc4,0x26
+,0x89,0x47,0x06,0xa0,0x96,0x36,0x26,0x88,0x47,0x08,0xe8,0xc8,0x08,0x07,0x5b,0x83
+,0x26,0xad,0x36,0xfe,0xa1,0xad,0x36,0xe7,0x04,0xba,0x10,0x01,0xb8,0x80,0x80,0xef
+,0xed,0xba,0x10,0x01,0xb8,0x02,0x02,0xef,0xed,0x52,0xba,0xe0,0x00,0xb8,0x41,0x10
+,0xef,0x5a,0xb8,0x9c,0x03,0xcd,0x39,0xc6,0x06,0x95,0x36,0x00,0x8c,0xc0,0x48,0x8e
+,0xc0,0xfa,0xe8,0xa9,0x0f,0xfb,0xc3,0x1e,0x06,0x1f,0x06,0x33,0xc0,0x8e,0xc0,0x8b
+,0xf0,0x8d,0x3e,0x20,0xf3,0x51,0xb1,0x0a,0x26,0x83,0x7d,0x0c,0x01,0x75,0x2a,0x57
+,0x26,0x83,0x7d,0x0e,0x00,0x74,0x06,0xe8,0x2f,0x00,0xe9,0x03,0x00,0xe8,0x66,0x07
+,0x5f,0x73,0x16,0x33,0xc0,0x8e,0xd8,0x26,0x8b,0x4d,0x12,0x8d,0x75,0x20,0x8d,0x3e
+,0xe0,0xfe,0xf3,0xa4,0x59,0x07,0x1f,0xf9,0xc3,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20
+,0x01,0xe9,0xc4,0xff,0x59,0x07,0x1f,0xf8,0xc3,0x51,0x50,0x53,0x56,0x52,0x57,0x33
+,0xdb,0x26,0x8a,0x5d,0x0e,0x26,0x8b,0x4d,0x12,0x8d,0x7d,0x20,0x5a,0x87,0xd7,0x26
+,0x8a,0x45,0x14,0x87,0xd7,0x42,0x32,0xff,0x80,0xff,0x08,0x75,0x08,0xfe,0xcb,0x22
+,0xdb,0x75,0xea,0x33,0xdb,0x23,0xdb,0x74,0x06,0xfe,0xc7,0xd0,0xc8,0x73,0x0c,0x50
+,0x26,0x8a,0x05,0x38,0x04,0x58,0x74,0x03,0xe9,0x0a,0x00,0x49,0x46,0x47,0x23,0xc9
+,0x74,0x0a,0xe9,0xd3,0xff,0x5a,0x5e,0x5b,0x58,0x59,0xf8,0xc3,0x5a,0x5e,0x5b,0x58
+,0x59,0xf9,0xc3,0x1e,0x06,0x1f,0x06,0x33,0xc0,0x8e,0xc0,0x86,0xcd,0x2b,0xce,0x8b
+,0xf7,0x8b,0xc1,0x33,0xc9,0x80,0x3c,0xff,0x74,0x16,0x80,0xf9,0x06,0x73,0x09,0x32
+,0xc9,0x46,0x48,0x74,0x2e,0xe9,0xed,0xff,0x3d,0x60,0x00,0x73,0x0c,0xe9,0x23,0x00
+,0xfe,0xc1,0x46,0x48,0x74,0x1d,0xe9,0xdc,0xff,0xb8,0x10,0x00,0x8d,0x3e,0x18,0x34
+,0x32,0xed,0xb1,0x06,0xf3,0xa6,0x74,0x03,0xe9,0x08,0x00,0x48,0x23,0xc0,0x74,0x07
+,0xe9,0xe9,0xff,0x07,0x1f,0xf8,0xc3,0x8d,0x36,0x18,0x34,0x33,0xc0,0x8e,0xd8,0x8d
+,0x3e,0xe0,0xfe,0xb8,0x10,0x00,0xb9,0x06,0x00,0x56,0xf3,0xa4,0x5e,0x48,0x3d,0x00
+,0x00,0x75,0xf3,0x07,0x1f,0xf9,0xc3,0xff,0x06,0xe4,0x33,0xc6,0x06,0xeb,0x34,0x00
+,0x26,0x8b,0x45,0x06,0x86,0xe0,0xc1,0xe8,0x04,0x48,0x06,0x8e,0xc0,0xfe,0x06,0xe6
+,0x3a,0xfa,0xe8,0x69,0x0e,0xfb,0x07,0xb0,0xff,0xc3,0x00,0x00,0x00,0x00,0x00,0x00
+,0xb0,0x01,0xc3,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3
+,0x8b,0x0e,0x97,0x36,0x81,0xe1,0x80,0x30,0x26,0x8b,0x47,0x04,0x25,0x7f,0xcf,0x0b
+,0xc1,0xa3,0x97,0x36,0xa3,0xe6,0x34,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x74
+,0x03,0xb0,0x03,0xc3,0x26,0x8b,0x47,0x08,0xa3,0x97,0x36,0xa3,0xe6,0x34,0x26,0x8a
+,0x47,0x20,0xa2,0xfd,0x34,0x3c,0x01,0x75,0x06,0xc7,0x06,0xa1,0x36,0x00,0x00,0x26
+,0x8a,0x47,0x21,0xa2,0xfe,0x34,0x26,0x8b,0x47,0x0a,0xa3,0x18,0x34,0xa3,0x58,0x34
+,0x26,0x8b,0x47,0x0c,0xa3,0x1a,0x34,0xa3,0x5a,0x34,0x26,0x8b,0x47,0x0e,0xa3,0x1c
+,0x34,0xa3,0x5c,0x34,0xc6,0x06,0x2a,0x34,0xc0,0x26,0x8b,0x47,0x14,0x25,0x7f,0xff
+,0x09,0x06,0x2c,0x34,0x26,0x8b,0x47,0x16,0x25,0xff,0xfe,0x25,0xff,0xfc,0x09,0x06
+,0x2e,0x34,0xc6,0x06,0x00,0x34,0xc0,0x26,0x8b,0x47,0x10,0xa3,0x02,0x34,0x26,0x8b
+,0x47,0x12,0xa3,0x04,0x34,0x06,0x53,0xe8,0x84,0x0a,0x5b,0x07,0x3d,0x00,0x00,0x75
+,0x07,0x80,0x0e,0x92,0x36,0x08,0xb0,0xfe,0xc3,0xb9,0x00,0x01,0xa1,0xac,0x33,0x33
+,0xd2,0xf7,0xf9,0xa3,0xae,0x33,0x91,0x49,0x33,0xd2,0xf7,0xe9,0x05,0x00,0x3b,0xa3
+,0x46,0x34,0xbf,0x00,0x3b,0x89,0x3e,0x44,0x34,0xba,0x68,0x00,0xb8,0xe0,0xe0,0xef
+,0xa1,0xae,0x33,0xe7,0x62,0xa1,0xae,0x33,0xba,0x08,0x01,0xef,0xa1,0x44,0x34,0xe7
+,0x64,0xa1,0x44,0x34,0xba,0x0a,0x01,0xef,0xb8,0x00,0x01,0x2d,0x04,0x00,0x0d,0x00
+,0x10,0xe7,0x92,0xc3,0x3d,0x00,0x00,0x74,0x0a,0x26,0x89,0x47,0x07,0xe8,0x83,0x3a
+,0xb0,0x07,0xc3,0xa1,0xae,0x33,0x26,0x89,0x47,0x2b,0xa1,0x44,0x34,0x26,0x89,0x47
+,0x2d,0xa1,0x46,0x34,0x26,0x89,0x47,0x2f,0x80,0x0e,0x93,0x36,0x20,0xa1,0x88,0x36
+,0x86,0xe0,0x26,0x89,0x47,0x08,0xa1,0x84,0x36,0x86,0xe0,0x26,0x89,0x47,0x0a,0xa1
+,0x80,0x36,0x86,0xe0,0x26,0x89,0x47,0x0c,0xb8,0x60,0xfe,0x86,0xe0,0x26,0x89,0x47
+,0x0e,0xa0,0xa1,0x36,0x26,0x88,0x47,0x10,0x8b,0x36,0x88,0x36,0x26,0xc6,0x44,0x02
+,0xff,0xe5,0x9e,0xa9,0x00,0x08,0x74,0x0c,0xba,0x84,0x00,0xed,0x0d,0x08,0x00,0xef
+,0xba,0x8e,0x00,0xef,0xe5,0x02,0x25,0xf9,0xff,0xe7,0x02,0xba,0x10,0x01,0xb8,0x02
+,0x02,0xef,0xed,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x01,0xc3
+,0x80,0x26,0x93,0x36,0x9f,0xe8,0x8d,0x0a,0x80,0x0e,0x92,0x36,0x08,0xb0,0xfe,0xc3
+,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xc6,0x06,0x2a
+,0x34,0xc0,0x26,0x8b,0x47,0x06,0x25,0x7f,0xff,0xa3,0x2c,0x34,0x26,0x8b,0x47,0x08
+,0x25,0xff,0xfe,0x25,0xff,0xfc,0xa3,0x2e,0x34,0xcd,0x52,0xb0,0x00,0xc3,0xf6,0x06
+,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xc6,0x06,0x00,0x34,0xc0,0x26,0x8b,0x47
+,0x06,0xa3,0x02,0x34,0x26,0x8b,0x47,0x08,0xa3,0x04,0x34,0xcd,0x52,0xb0,0x00,0xc3
+,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x57,0x8d,0x7f,0x06,0x51,0xb9
+,0x07,0x00,0x33,0xc0,0xf3,0xab,0x59,0x8d,0x7f,0x06,0xa1,0x7a,0x34,0x03,0x06,0x39
+,0x37,0x26,0x88,0x05,0xa1,0x95,0x37,0x26,0x88,0x45,0x02,0xa1,0x80,0x34,0x03,0x06
+,0x76,0x34,0x26,0x88,0x45,0x07,0xa1,0xc6,0x34,0x26,0x88,0x45,0x09,0xa1,0xd8,0x33
+,0x26,0x88,0x45,0x0a,0x33,0xc0,0xa3,0x7a,0x34,0xa3,0x39,0x37,0xa3,0x95,0x37,0xa3
+,0x80,0x34,0xa3,0x76,0x34,0xa3,0xc6,0x34,0xa3,0xd8,0x33,0x5f,0xb0,0x00,0xc3,0xf6
+,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x26,0x8b,0x4f,0x04,0x83,0xf9,0x06
+,0x74,0x12,0x83,0xf9,0x04,0x74,0x0d,0x83,0xf9,0x00,0x74,0x08,0x83,0xf9,0x02,0x74
+,0x03,0xb0,0x01,0xc3,0x89,0x0e,0xe8,0x3a,0x83,0x26,0xab,0x36,0xf9,0x09,0x0e,0xab
+,0x36,0xe5,0x02,0x25,0xf9,0xff,0x0b,0xc1,0xe7,0x02,0xb0,0x00,0xc3,0xf6,0x06,0x93
+,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x26,0x8b,0x4f,0x04,0x80,0xf9,0xff,0x74,0x08
+,0x80,0xf9,0x00,0x74,0x10,0xb0,0x01,0xc3,0x83,0x0e,0xad,0x36,0x02,0xa1,0xad,0x36
+,0xe7,0x04,0xe9,0x0a,0x00,0x83,0x26,0xad,0x36,0xfd,0xa1,0xad,0x36,0xe7,0x04,0xb0
+,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xe8,0xd5,0x04,0xb0
+,0x00,0xc3,0xf6,0x06,0x93,0x36,0x80,0x75,0x03,0xb0,0x01,0xc3,0x26,0x83,0x7f,0x06
+,0x05,0x75,0x03,0xe9,0x9d,0x00,0x26,0x8b,0x57,0x04,0x26,0x8b,0x47,0x08,0x26,0x81
+,0x7f,0x06,0x00,0x80,0x75,0x08,0xed,0x26,0x89,0x47,0x0a,0xe9,0x9d,0x00,0x26,0x83
+,0x7f,0x06,0x01,0x75,0x04,0xef,0xe9,0x92,0x00,0x26,0x81,0x7f,0x06,0x01,0x80,0x75
+,0x09,0xef,0xed,0x26,0x89,0x47,0x0a,0xe9,0x81,0x00,0x26,0x83,0x7f,0x06,0x02,0x75
+,0x07,0x26,0x21,0x47,0x04,0xe9,0x73,0x00,0x26,0x81,0x7f,0x06,0x02,0x80,0x75,0x0c
+,0x26,0x21,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x5f,0x00,0x26,0x83,0x7f,0x06
+,0x03,0x75,0x07,0x26,0x09,0x47,0x04,0xe9,0x51,0x00,0x26,0x81,0x7f,0x06,0x03,0x80
+,0x75,0x0c,0x26,0x09,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x3d,0x00,0x26,0x83
+,0x7f,0x06,0x04,0x75,0x07,0x26,0x31,0x47,0x04,0xe9,0x2f,0x00,0x26,0x81,0x7f,0x06
+,0x04,0x80,0x75,0x0c,0x26,0x31,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x1b,0x00
+,0xb0,0x01,0xc3,0xfa,0x53,0x26,0x8b,0x4f,0x08,0x0b,0xc9,0x74,0x0c,0x8d,0x1e,0xe0
+,0xfe,0xe8,0x52,0xff,0x83,0xc3,0x08,0xe2,0xf8,0x5b,0xfb,0xb0,0x00,0xc3,0xf6,0x06
+,0x93,0x36,0x80,0x75,0x0a,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x01,0xc3,0x8d
+,0x3e,0xe0,0xfe,0xe5,0x00,0x26,0x89,0x05,0xe5,0x02,0x26,0x89,0x45,0x02,0xa1,0xad
+,0x36,0x26,0x89,0x45,0x04,0xe5,0x06,0x26,0x89,0x45,0x06,0xe5,0x08,0x26,0x89,0x45
+,0x08,0xe5,0x0a,0x26,0x89,0x45,0x0a,0xe5,0x0e,0x26,0x89,0x45,0x0c,0xe5,0x48,0x26
+,0x89,0x45,0x0e,0xe5,0x4a,0x26,0x89,0x45,0x10,0xe5,0x4c,0x26,0x89,0x45,0x12,0xa1
+,0xb7,0x36,0x26,0x89,0x45,0x14,0xe5,0x50,0x26,0x89,0x45,0x16,0xe5,0x52,0x26,0x89
+,0x45,0x18,0xe5,0x54,0x26,0x89,0x45,0x1a,0xe5,0x56,0x26,0x89,0x45,0x1c,0xe5,0x58
+,0x26,0x89,0x45,0x1e,0xe5,0x62,0x26,0x89,0x45,0x20,0xe5,0x64,0x26,0x89,0x45,0x22
+,0xe5,0x66,0x26,0x89,0x45,0x24,0xe5,0x68,0x26,0x89,0x45,0x26,0xe5,0x6a,0x26,0x89
+,0x45,0x28,0xe5,0x6c,0x26,0x89,0x45,0x2a,0xe5,0x70,0x26,0x89,0x45,0x2c,0xe5,0x72
+,0x26,0x89,0x45,0x2e,0xe5,0x74,0x26,0x89,0x45,0x30,0xe5,0x76,0x26,0x89,0x45,0x32
+,0xe5,0x7c,0x26,0x89,0x45,0x34,0xe5,0x7e,0x26,0x89,0x45,0x36,0xe5,0x80,0x26,0x89
+,0x45,0x38,0xe5,0x82,0x26,0x89,0x45,0x3a,0xe5,0x86,0x26,0x89,0x45,0x3c,0xe5,0x88
+,0x26,0x89,0x45,0x3e,0xe5,0x9a,0x26,0x89,0x45,0x40,0xe5,0x9e,0x26,0x89,0x45,0x42
+,0xe5,0xcc,0x26,0x89,0x45,0x44,0xe5,0xce,0x26,0x89,0x45,0x46,0xe5,0xd0,0x26,0x89
+,0x45,0x48,0xe5,0xd2,0x26,0x89,0x45,0x4a,0xba,0x00,0x01,0xed,0x11,0x06,0x66,0x34
+,0x73,0x04,0xff,0x06,0x68,0x34,0x26,0x89,0x45,0x4c,0xba,0x02,0x01,0xed,0xc1,0xe0
+,0x02,0x11,0x06,0x6e,0x34,0x73,0x04,0xff,0x06,0x70,0x34,0x26,0x89,0x45,0x4e,0xba
+,0x04,0x01,0xed,0x11,0x06,0x6a,0x34,0x73,0x04,0xff,0x06,0x6c,0x34,0x26,0x89,0x45
+,0x50,0xba,0x06,0x01,0xed,0xc1,0xe0,0x02,0x11,0x06,0x72,0x34,0x73,0x04,0xff,0x06
+,0x74,0x34,0x26,0x89,0x45,0x52,0xba,0x08,0x01,0xed,0x26,0x89,0x45,0x54,0xba,0x0a
+,0x01,0xed,0x26,0x89,0x45,0x56,0xba,0x0c,0x01,0xed,0x26,0x89,0x45,0x58,0xba,0x0e
+,0x01,0xed,0x01,0x06,0x7a,0x34,0x26,0x89,0x45,0x5e,0xba,0x10,0x01,0xed,0x26,0x89
+,0x45,0x5c,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x80,0x74,0x07,0xf6,0x06,0x93,0x36
+,0x20,0x75,0x03,0xb0,0x01,0xc3,0x26,0x80,0x7f,0x06,0x00,0x75,0x30,0x80,0x3e,0x95
+,0x36,0x00,0x74,0x52,0xc6,0x06,0x95,0x36,0x00,0x83,0x26,0xad,0x36,0xfe,0xa1,0xad
+,0x36,0xe7,0x04,0xba,0x10,0x01,0xb8,0x80,0x80,0xef,0xed,0xba,0x10,0x01,0xb8,0x02
+,0x02,0xef,0xed,0xba,0xe0,0x00,0xb8,0x00,0x10,0xef,0xb0,0x00,0xc3,0x26,0x8b,0x47
+,0x04,0x3d,0x00,0x00,0x74,0x20,0x3d,0x03,0x00,0x77,0x1b,0xba,0x10,0x01,0xb8,0x02
+,0x00,0xef,0xba,0xe0,0x00,0xb8,0x01,0x10,0xef,0x83,0x0e,0xad,0x36,0x01,0xa1,0xad
+,0x36,0xe7,0x04,0xb0,0x00,0xc3,0xb0,0x06,0xc3,0xf6,0x06,0x93,0x36,0x80,0x75,0x03
+,0xb0,0x01,0xc3,0x26,0x83,0x7f,0x04,0x01,0x74,0x0a,0x26,0x83,0x7f,0x04,0x02,0x74
+,0x19,0xb0,0x06,0xc3,0x26,0x83,0x7f,0x06,0x0c,0x77,0xf6,0x26,0x83,0x7f,0x0a,0x60
+,0x77,0xef,0xe8,0x10,0x00,0x72,0x0b,0xb0,0x46,0xc3,0xe8,0x4e,0x00,0x72,0x03,0xb0
+,0x46,0xc3,0xb0,0x00,0xc3,0x51,0xb1,0x0a,0x8b,0x3e,0x20,0xf3,0x26,0x83,0x7d,0x0c
+,0x02,0x75,0x03,0xe9,0x0e,0x00,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20,0x01,0xe9,0xeb
+,0xff,0x59,0xf8,0xc3,0x57,0x8d,0x7d,0x0e,0x8d,0x77,0x06,0xb9,0x12,0x00,0xf3,0xa4
+,0x8d,0x7d,0x20,0x8d,0x36,0xe0,0xfe,0x26,0x8b,0x4d,0x12,0xf3,0xa4,0xff,0x06,0x01
+,0x35,0x5f,0x26,0xc7,0x45,0x0c,0x01,0x00,0x59,0xf9,0xc3,0x51,0xb1,0x0a,0x8d,0x3e
+,0x20,0xf3,0x8d,0x36,0xe0,0xfe,0x26,0x83,0x7d,0x0c,0x01,0x75,0x1b,0x57,0xe8,0x25
+,0x00,0x5f,0x73,0x14,0x33,0xc0,0xb9,0x20,0x01,0xf3,0xaa,0x26,0xc7,0x45,0x0c,0x02
+,0x00,0xff,0x0e,0x01,0x35,0x59,0xf9,0xc3,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20,0x01
+,0xe9,0xd3,0xff,0x59,0xf8,0xc3,0x51,0x26,0x8b,0x4d,0x12,0x8d,0x7d,0x20,0xf3,0xa6
+,0x74,0x03,0x59,0xf8,0xc3,0x59,0xf9,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x80,0x3e,0xec,0x34,0x06,0x72,0x33,0xff,0x06,0xf0,0x33,0x50,0xc4,0x1e,0x8c,0x36
+,0xb9,0x0f,0x00,0x33,0xc0,0xe8,0x29,0x00,0x58,0x81,0x26,0xc2,0x34,0xdf,0x7f,0x81
+,0x26,0xe9,0x34,0xdf,0x7f,0x0b,0xdb,0x74,0x11,0x26,0xc6,0x07,0x84,0x26,0xc6,0x47
+,0x02,0xff,0x26,0x89,0x47,0x06,0xe8,0xac,0x00,0xc3,0xff,0x06,0xea,0x33,0xe9,0xf5
+,0xff,0x57,0x26,0x8b,0x3f,0x03,0xf9,0x26,0x3b,0x7f,0x02,0x74,0x16,0x26,0x3b,0x7f
+,0x04,0x7c,0x2a,0x3d,0x00,0x00,0x75,0x13,0x8d,0x7f,0x08,0x03,0xf9,0x26,0x3b,0x7f
+,0x02,0x7c,0x14,0xff,0x06,0xde,0x33,0x33,0xdb,0x5f,0xc3,0x26,0x8b,0x7f,0x02,0x26
+,0x89,0x3f,0x03,0xf9,0xe9,0x06,0x00,0x26,0x89,0x3f,0x26,0x29,0x0f,0x26,0xc7,0x05
+,0xff,0xff,0x26,0x87,0x3f,0x26,0x89,0x0d,0x8d,0x5d,0x02,0x50,0x8b,0xfb,0x83,0xe9
+,0x02,0x33,0xc0,0xf3,0xaa,0x58,0xfe,0x0e,0xec,0x34,0x5f,0xc3,0x8b,0x7c,0x02,0x3b
+,0x3c,0x74,0x2f,0x83,0x3d,0xff,0x75,0x0b,0x8d,0x7c,0x08,0x89,0x7c,0x02,0x83,0x3d
+,0xff,0x74,0x1e,0x8a,0x45,0x02,0x3c,0x81,0x75,0x0c,0x80,0x3e,0xeb,0x34,0x00,0x74
+,0x05,0x33,0xc0,0xe9,0x0b,0x00,0x8b,0x0d,0x01,0x4c,0x02,0x8d,0x75,0x02,0x83,0xe9
+,0x02,0xc3,0x80,0x3e,0xec,0x34,0x06,0x72,0x05,0x33,0xc0,0xe9,0xf3,0xff,0xff,0x06
+,0xee,0x33,0xe9,0xbe,0xff,0xf6,0x06,0x92,0x36,0x40,0x74,0x01,0xc3,0x57,0x56,0x51
+,0x52,0x8b,0x36,0x8c,0x36,0xe8,0xa4,0xff,0x75,0x03,0xe9,0x1a,0x00,0xe9,0x1c,0x00
+,0xfe,0x06,0xec,0x34,0xc4,0x3e,0x80,0x36,0xf3,0xa4,0x80,0x0e,0x92,0x36,0x40,0xba
+,0x0c,0x01,0xb8,0x80,0x80,0xef,0xed,0x5a,0x59,0x5e,0x5f,0xc3,0xff,0x06,0xe0,0x33
+,0x80,0x3c,0x81,0x75,0x0c,0xff,0x06,0xe2,0x33,0xc6,0x06,0xeb,0x34,0x01,0xe9,0xcf
+,0xff,0x80,0x3c,0x84,0x75,0x07,0xff,0x06,0xe6,0x33,0xe9,0xc3,0xff,0xff,0x06,0xe8
+,0x33,0xe9,0xbc,0xff,0x8d,0x3e,0xe0,0xfe,0xa1,0x72,0x34,0xc7,0x06,0x72,0x34,0x00
+,0x00,0x89,0x05,0xa1,0x74,0x34,0xc7,0x06,0x74,0x34,0x00,0x00,0x89,0x45,0x02,0xba
+,0x04,0x01,0xed,0x89,0x45,0x04,0xc7,0x45,0x06,0x00,0x00,0xa1,0x6e,0x34,0xc7,0x06
+,0x6e,0x34,0x00,0x00,0x89,0x45,0x08,0xa1,0x70,0x34,0xc7,0x06,0x70,0x34,0x00,0x00
+,0x89,0x45,0x0a,0xba,0x00,0x01,0xed,0x89,0x45,0x0c,0xc7,0x45,0x0e,0x00,0x00,0x32
+,0xe4,0xba,0x0e,0x01,0xec,0x89,0x45,0x10,0xa1,0x7e,0x34,0xc7,0x06,0x7e,0x34,0x00
+,0x00,0x89,0x45,0x12,0xa1,0x8c,0x34,0xc7,0x06,0x8c,0x34,0x00,0x00,0x89,0x45,0x14
+,0xa1,0x8a,0x34,0xc7,0x06,0x8a,0x34,0x00,0x00,0x89,0x45,0x16,0xa1,0x7c,0x34,0xc7
+,0x06,0x7c,0x34,0x00,0x00,0x89,0x45,0x18,0xa1,0x88,0x34,0xc7,0x06,0x88,0x34,0x00
+,0x00,0x89,0x45,0x1a,0xa1,0xca,0x33,0xc7,0x06,0xca,0x33,0x00,0x00,0x89,0x45,0x1c
+,0xa1,0x78,0x34,0xc7,0x06,0x78,0x34,0x00,0x00,0x89,0x45,0x1e,0xa1,0xc6,0x34,0xc7
+,0x06,0xc6,0x34,0x00,0x00,0x89,0x45,0x20,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xfa,0x33,0xc0,0x8e,0xd8,0x8e,0xc0,0xb8,0xa0,0x01,0xc1,0xe8,0x04,0x8e,0xd0,0x8d
+,0x26,0x80,0x00,0xe8,0x00,0x01,0xe8,0x10,0xeb,0x8b,0x1e,0xf7,0x34,0x8b,0x16,0xf9
+,0x34,0x8b,0x36,0xff,0x34,0x33,0xc0,0xb9,0xef,0xff,0x8d,0x3e,0x14,0x00,0x2b,0xcf
+,0x2b,0xce,0xd1,0xe9,0xf3,0xab,0x89,0x1e,0xf7,0x34,0x89,0x16,0xf9,0x34,0x83,0xfe
+,0x00,0x74,0x0c,0xb9,0xef,0xff,0xbf,0x80,0xfe,0x2b,0xcf,0xd1,0xe9,0xf3,0xab,0xb9
+,0xff,0xff,0x81,0xe9,0x00,0x3b,0x83,0xfe,0x00,0x74,0x03,0xe9,0x1b,0x00,0x51,0x1e
+,0xb8,0x00,0xe0,0x8e,0xd8,0x33,0xf6,0x8d,0x3e,0x00,0xd8,0xb9,0x00,0x0c,0xf3,0xa5
+,0x1f,0x59,0xbe,0xff,0xff,0x81,0xee,0x00,0xd8,0x2b,0xce,0x81,0xe1,0x00,0xff,0x89
+,0x0e,0xac,0x33,0x8d,0x06,0x20,0x02,0xc1,0xe8,0x04,0xa3,0x32,0x34,0x8e,0xd0,0x36
+,0xc7,0x06,0x1e,0x00,0x80,0x18,0x36,0xc7,0x06,0x22,0x00,0xff,0x7f,0x36,0xc7,0x06
+,0x0a,0x00,0xff,0xff,0x36,0xc7,0x06,0x1c,0x00,0x80,0x00,0x8d,0x06,0xa0,0x02,0xc1
+,0xe8,0x04,0xa3,0x30,0x34,0x8e,0xd0,0x36,0xc7,0x06,0x1e,0x00,0x50,0x28,0x36,0xc7
+,0x06,0x0a,0x00,0xff,0xff,0x36,0xc7,0x06,0x1c,0x00,0x80,0x00,0xb8,0xa0,0x01,0xc1
+,0xe8,0x04,0xa3,0x34,0x34,0xa3,0xf2,0x33,0x8e,0xd0,0x8d,0x26,0x80,0x00,0xb8,0x00
+,0x90,0xe7,0x02,0x8d,0x3e,0x70,0x01,0x8b,0xc7,0xc1,0xe8,0x04,0xb9,0x03,0x00,0x89
+,0x45,0x0e,0x89,0x45,0x02,0xc7,0x05,0xff,0xff,0x83,0xc7,0x10,0x05,0x01,0x00,0xe2
+,0xee,0xe8,0x5b,0x01,0xe5,0xce,0xa3,0xb5,0x36,0xe8,0x21,0x00,0xe8,0x45,0x01,0xa1
+,0x32,0x34,0x8c,0xcb,0xcd,0x37,0x0e,0x58,0xa9,0x00,0xf0,0x74,0x07,0x33,0xf6,0x89
+,0x36,0xff,0x34,0xc3,0x8d,0x36,0x30,0x61,0x89,0x36,0xff,0x34,0xc3,0x33,0xc0,0x8b
+,0xd0,0x8b,0xf2,0xb9,0x68,0x00,0x2e,0x80,0xbc,0xac,0x17,0x80,0x75,0x01,0xef,0x83
+,0xc2,0x02,0x46,0xe2,0xf1,0xb8,0x02,0x00,0xe7,0x50,0xb9,0x5a,0x00,0x33,0xff,0xc7
+,0x05,0x65,0x18,0x8c,0x4d,0x02,0x83,0xc7,0x04,0xe2,0xf4,0x33,0xc0,0x8e,0xc0,0x8c
+,0xc8,0x8e,0xd8,0x8d,0x3e,0x80,0x00,0x8d,0x36,0x9c,0x17,0xb9,0x08,0x00,0xe8,0x37
+,0x00,0x8d,0x36,0x20,0x21,0x8d,0x3e,0xc0,0x00,0xb9,0x0d,0x00,0xe8,0x29,0x00,0x8d
+,0x3e,0x40,0x01,0xb9,0x0a,0x00,0xe8,0x1f,0x00,0xe8,0x4b,0x0e,0x33,0xc0,0x8e,0xd8
+,0xc7,0x06,0x4e,0x37,0x6f,0x17,0xe7,0x48,0xe7,0x4c,0xb8,0x40,0x9c,0xe7,0x4a,0xe5
+,0x48,0x90,0xb8,0x00,0x70,0xe7,0x48,0xc3,0xa5,0x83,0xc7,0x02,0xe2,0xfa,0xc3,0xe5
+,0x4c,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe5,0x58,0xd1
+,0xe0,0x73,0x11,0x8b,0xf0,0xd1,0xe6,0x33,0xc0,0x8e,0xd8,0x8b,0xb4,0x80,0x00,0x83
+,0xc6,0x0b,0xff,0xe6,0x1f,0x07,0x5a,0x5f,0x5e,0x59,0x58,0xcf,0x58,0x1c,0xe4,0x1c
+,0x6c,0x1c,0x8e,0x1a,0xc0,0x1f,0x40,0x1a,0x44,0x1c,0x65,0x18,0x80,0x80,0x80,0xff
+,0x80,0x03,0x02,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+,0x80,0x03,0x03,0x43,0x80,0x80,0x02,0x80,0x42,0x03,0x02,0xff,0x03,0x01,0x03,0x01
+,0x01,0x03,0x02,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x03,0x01,0x03
+,0x03,0xff,0x01,0x01,0xff,0x01,0xff,0x01,0x01,0x03,0x03,0x03,0xff,0xff,0xff,0xff
+,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+,0xff,0xff,0xff,0x02,0xb8,0x0f,0x00,0xe7,0x84,0xb8,0x0f,0xf8,0xe7,0x82,0xc3,0xb9
+,0x08,0x00,0x89,0x0e,0xe6,0x3a,0x8d,0x06,0x20,0x03,0x8b,0xd0,0xc1,0xe8,0x04,0xa3
+,0x90,0x01,0x8b,0xc2,0x8b,0xd8,0xc1,0xe8,0x04,0x8e,0xc0,0x05,0x61,0x00,0x26,0xa3
+,0x00,0x00,0xa1,0x30,0x34,0x26,0xa3,0x02,0x00,0x83,0xc3,0x14,0xd1,0xeb,0x26,0x89
+,0x1e,0x08,0x00,0x81,0xc2,0x10,0x06,0xe2,0xd9,0x26,0xc7,0x06,0x00,0x00,0xff,0xff
+,0x8c,0x06,0x92,0x01,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8
+,0xe7,0x5a,0xff,0x06,0xbe,0x33,0xba,0xd2,0x00,0xed,0xcf,0x00,0x00,0x00,0x00,0x00
+,0x8c,0xcb,0xa1,0x30,0x34,0xcd,0x37,0xe9,0x06,0xed,0xb8,0x32,0x00,0xc3,0xe8,0x8c
+,0x01,0xfe,0x06,0xe2,0x34,0xe8,0x21,0x01,0x75,0xf0,0xe8,0x53,0x0e,0x81,0x0e,0xaf
+,0x36,0x00,0xc0,0xc7,0x06,0xad,0x36,0x60,0x00,0xf7,0x06,0xe6,0x34,0x80,0x00,0x75
+,0x1a,0xf7,0x06,0xe6,0x34,0x00,0x08,0x74,0x09,0xc7,0x06,0xab,0x36,0x0b,0x00,0xe9
+,0x0f,0x00,0xc7,0x06,0xab,0x36,0x03,0x00,0xe9,0x06,0x00,0xc7,0x06,0xab,0x36,0x11
+,0x9c,0xc7,0x06,0xa9,0x36,0x18,0x00,0xf7,0x06,0xe6,0x34,0x80,0x00,0x75,0x0d,0xf7
+,0x06,0xb5,0x36,0x02,0x00,0x74,0x05,0x83,0x0e,0xa9,0x36,0x20,0xa1,0xa9,0x36,0xe7
+,0x00,0xa1,0xab,0x36,0xe7,0x02,0xf7,0x06,0xe6,0x34,0x80,0x00,0x74,0x2e,0xe8,0xf2
+,0x2f,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56,0xa1,0xb1,0x36,0x0d,0x00,0x10,0xe7,0x08
+,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xb8,0x40,0x00,0xe7,0x4e,0x33
+,0xc0,0xe7,0x0e,0xc7,0x06,0x26,0x02,0x00,0x00,0xe9,0x23,0x00,0xc7,0x06,0x4e,0x37
+,0x3f,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x80,0x74,0x07,0x26
+,0x81,0x0e,0x08,0x00,0x00,0x80,0xc6,0x06,0xe0,0x34,0x01,0xb8,0x00,0x00,0xc3,0xfe
+,0x06,0xe1,0x34,0xc6,0x06,0xe0,0x34,0x00,0xa1,0x26,0x02,0x0b,0xc0,0x74,0x01,0xc3
+,0xe8,0x04,0x00,0xb8,0x00,0x00,0xc3,0xa1,0xa9,0x36,0xe7,0x00,0x8b,0x1e,0xab,0x36
+,0x83,0xe3,0x06,0xe5,0x02,0x25,0xf9,0xff,0x0b,0xc3,0x0d,0x10,0x00,0xe7,0x02,0xa1
+,0xad,0x36,0xe7,0x04,0xc3,0xb8,0x0a,0x00,0xe7,0x84,0xfe,0x06,0xe5,0x34,0xc6,0x06
+,0xe3,0x34,0x01,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x40,0x74,0x07
+,0x26,0x81,0x0e,0x08,0x00,0x00,0x40,0xc3,0xc7,0x06,0x4e,0x37,0x6f,0x17,0xfe,0x06
+,0xe4,0x34,0xc6,0x06,0xe3,0x34,0x00,0xc3,0xc3,0xf6,0x06,0x18,0x34,0x80,0x75,0x0d
+,0xa1,0x18,0x34,0x0b,0x06,0x1a,0x34,0x0b,0x06,0x1c,0x34,0x75,0x01,0xc3,0xa1,0x2e
+,0x34,0x25,0xff,0xfe,0x8b,0x16,0xe7,0x36,0x81,0xe2,0x00,0x01,0x0b,0xc2,0xa3,0x2e
+,0x34,0x8d,0x16,0x10,0x00,0xbf,0x00,0x00,0xb9,0x08,0x00,0x8b,0x85,0x00,0x34,0xef
+,0x83,0xc2,0x10,0x8b,0x85,0x02,0x34,0xef,0x83,0xc2,0x10,0x8b,0x85,0x04,0x34,0xef
+,0x83,0xc2,0xe2,0x83,0xc7,0x06,0x49,0x75,0xe2,0xb8,0x00,0x00,0x8e,0xc0,0xbe,0x00
+,0x34,0xbf,0xb9,0x36,0xb9,0x18,0x00,0xf3,0xa5,0xb8,0x00,0x00,0xc3,0x33,0xc0,0x8e
+,0xc0,0x8d,0x3e,0xb0,0x33,0xb9,0x08,0x00,0xf3,0xab,0x8d,0x3e,0x3e,0x34,0xb9,0x03
+,0x00,0xf3,0xab,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xba
+,0x33,0xe5,0x56,0x0d,0x20,0x00,0xe7,0x56,0xba,0x7a,0x00,0xed,0x08,0x26,0x94,0x36
+,0x33,0xc0,0xb1,0x08,0x32,0xed,0x06,0x8e,0xc0,0x8d,0x3e,0xe0,0xff,0xf3,0xaa,0x8e
+,0x06,0x32,0x34,0x26,0x81,0x0e,0x08,0x00,0x00,0x02,0x07,0xe5,0x56,0x25,0xdf,0xff
+,0xe7,0x56,0xe9,0xf8,0xfc,0x00,0xbd,0x1b,0x10,0x1b,0xd9,0x1a,0xf3,0x1a,0x50,0x51
+,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb6,0x33,0x53
+,0x06,0x51,0xe5,0x80,0xa3,0xb4,0x33,0x8b,0xd8,0x8b,0xc8,0x25,0x10,0x00,0xa3,0xed
+,0x34,0x0b,0xc0,0x74,0x14,0xff,0x06,0x80,0x34,0x80,0x3e,0xfe,0x34,0x00,0x74,0x03
+,0xe9,0x06,0x00,0xb8,0x80,0x00,0xe8,0x9d,0x04,0x83,0xe3,0x03,0xd1,0xe3,0x2e,0xff
+,0x97,0x86,0x1a,0x59,0x07,0x5b,0xe9,0xa4,0xfc,0xba,0x20,0x00,0x8e,0x06,0x3c,0x34
+,0x83,0x3e,0x3c,0x34,0x00,0x75,0x03,0xe9,0xf0,0x00,0xc7,0x06,0x3c,0x34,0x00,0x00
+,0xe9,0x2a,0x00,0xba,0x10,0x00,0x8e,0x06,0x3a,0x34,0x83,0x3e,0x3a,0x34,0x00,0x75
+,0x03,0xe9,0xd5,0xff,0xc7,0x06,0x3a,0x34,0x00,0x00,0xe8,0x10,0x00,0xe9,0xc9,0xff
+,0xba,0x10,0x00,0x8e,0x06,0x3a,0x34,0xc7,0x06,0x3a,0x34,0x00,0x00,0x26,0xa1,0x14
+,0x00,0x26,0xa3,0x0c,0x00,0x26,0xa1,0x16,0x00,0x26,0xa3,0x0e,0x00,0x26,0xc6,0x06
+,0x0a,0x00,0x00,0xc1,0xea,0x02,0x23,0xd1,0x74,0x1c,0xba,0x20,0x00,0x26,0xc7,0x06
+,0x0e,0x00,0xea,0x05,0x26,0x0b,0x16,0x0c,0x00,0x26,0x89,0x16,0x0c,0x00,0xff,0x06
+,0x86,0x34,0xff,0x06,0xdc,0x33,0x26,0xa1,0x0c,0x00,0xa9,0x00,0x37,0x74,0x16,0x26
+,0xc6,0x06,0x0a,0x00,0x02,0xa9,0x00,0x30,0x74,0x04,0xff,0x06,0x7a,0x34,0xff,0x06
+,0xda,0x33,0xe9,0x49,0x00,0xc0,0xec,0x07,0x83,0x16,0x8a,0x34,0x00,0x24,0x07,0x3c
+,0x07,0x75,0x04,0xff,0x06,0x8c,0x34,0xff,0x06,0x7e,0x34,0xa1,0x30,0x34,0x8c,0xc3
+,0x8e,0xc0,0x8e,0xdb,0x26,0x83,0x0e,0x08,0x00,0x40,0x8c,0xd8,0x26,0x87,0x06,0x16
+,0x00,0x26,0x83,0x3e,0x14,0x00,0xff,0x74,0x0a,0x8e,0xc0,0x26,0x8c,0x1e,0x00,0x00
+,0xe9,0x05,0x00,0x26,0x8c,0x1e,0x14,0x00,0x33,0xc0,0x8e,0xd8,0xc3,0xc3,0x8c,0xc0
+,0x87,0x06,0x92,0x01,0x3d,0xff,0xff,0x74,0x0d,0x8e,0xd8,0x8c,0x06,0x00,0x00,0x33
+,0xc0,0x8e,0xd8,0xe9,0x04,0x00,0x8c,0x06,0x90,0x01,0xe8,0x01,0x00,0xc3,0x06,0x83
+,0x3e,0x90,0x01,0xff,0x74,0x29,0x83,0x3e,0x3a,0x34,0x00,0x75,0x11,0xba,0x86,0x00
+,0xe8,0x1e,0x00,0x8c,0x06,0x3a,0x34,0x83,0x3e,0x90,0x01,0xff,0x74,0x11,0x83,0x3e
+,0x3c,0x34,0x00,0x75,0x0a,0xba,0x88,0x00,0xe8,0x06,0x00,0x8c,0x06,0x3c,0x34,0x07
+,0xc3,0xa1,0x90,0x01,0x8e,0xc0,0x26,0xa1,0x08,0x00,0xef,0x26,0xa1,0x00,0x00,0x26
+,0xc7,0x06,0x00,0x00,0xff,0xff,0xa3,0x90,0x01,0x3d,0xff,0xff,0x75,0x03,0xa3,0x92
+,0x01,0x83,0x3e,0xed,0x34,0x00,0x74,0x0b,0xb8,0x10,0x00,0xe7,0x84,0xc7,0x06,0xed
+,0x34,0x00,0x00,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7
+,0x5a,0xff,0x06,0xbc,0x33,0xe9,0x25,0xfb,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33
+,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb0,0x33,0xe9,0x11,0xfb,0x50,0x51,0x56,0x57
+,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb4,0x33,0x06,0xff,0x06
+,0x76,0x34,0x80,0x3e,0xfe,0x34,0x00,0x74,0x04,0x07,0xe9,0xf0,0xfa,0xb8,0x80,0x00
+,0xe8,0xd3,0x02,0x07,0xe9,0xe6,0xfa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xc6,0x1d,0x08,0x1d,0x91,0x1e,0x5d,0x1e,0x73,0x1e,0x89,0x1e,0x91,0x1e,0xa8,0x1d
+,0x91,0x1e,0x91,0x1e,0xaf,0x1e,0xaf,0x1e,0x15,0x1d,0x15,0x1d,0x91,0x1e,0x99,0x1f
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00
+,0x00,0x01,0x00,0x10,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00
+,0x07,0xe9,0x99,0xfa,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7
+,0x5a,0xff,0x06,0xb2,0x33,0x06,0x68,0xf6,0x1c,0xe5,0x06,0xa3,0xb2,0x33,0x8b,0xf0
+,0x83,0xe6,0x1e,0x2e,0xff,0xa4,0xa0,0x1c,0xe5,0x0c,0xa9,0x80,0x00,0x74,0x06,0xe8
+,0xa4,0x01,0xe5,0x06,0xc3,0x53,0xe5,0x0c,0x8b,0xd8,0xa9,0x01,0x00,0x74,0x14,0x83
+,0x3e,0xe0,0x3a,0x00,0x74,0x0d,0x8e,0x06,0x38,0x34,0xe8,0xbf,0x06,0xc7,0x06,0xe0
+,0x3a,0x00,0x00,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7
+,0x02,0x8b,0xc3,0x5b,0xa9,0x01,0x00,0x74,0x01,0xc3,0x8b,0xd0,0xb8,0x00,0x08,0xe7
+,0x84,0x8b,0xc2,0x8e,0x06,0x38,0x34,0x26,0xa3,0x0c,0x00,0x8b,0xd0,0xc1,0xe0,0x03
+,0x83,0x16,0x88,0x34,0x00,0xff,0x06,0x7c,0x34,0x26,0x83,0x3e,0x06,0x00,0x0a,0x75
+,0x21,0x8b,0xc2,0x25,0x40,0x18,0x3d,0x40,0x00,0x74,0x0c,0x3d,0x00,0x10,0x75,0x12
+,0x26,0xfe,0x0e,0x0a,0x00,0x74,0x0b,0xf7,0x06,0xef,0x34,0x20,0x00,0x75,0x03,0xe9
+,0x5a,0x06,0x8c,0xc0,0x26,0x8e,0x06,0x02,0x00,0x26,0x83,0x0e,0x08,0x00,0x20,0x26
+,0xa3,0x12,0x00,0x26,0xa3,0x10,0x00,0xc3,0xff,0x06,0xc4,0x33,0xe5,0x0c,0xa9,0x01
+,0x00,0x75,0x01,0xc3,0xa9,0xf0,0x07,0x74,0x01,0xc3,0xff,0x06,0xd4,0x33,0xe5,0x00
+,0x0d,0x18,0x00,0xe7,0x00,0xc3,0xff,0x06,0xca,0x33,0x80,0x3e,0xa0,0x36,0x08,0x75
+,0x14,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x08,0x74,0x07,0x26,0x81
+,0x0e,0x08,0x00,0x00,0x08,0xe5,0x82,0x25,0xfd,0xff,0xe7,0x82,0xe5,0x0c,0x50,0xe5
+,0x80,0x25,0x00,0x07,0xa3,0xe4,0x3a,0xe5,0x8c,0x25,0x00,0x80,0xa3,0xe2,0x3a,0x58
+,0xa9,0x02,0x00,0x75,0x25,0x83,0x3e,0xe2,0x3a,0x00,0x75,0x1e,0x83,0x3e,0xe4,0x3a
+,0x00,0x75,0x17,0xe5,0x08,0x0d,0x00,0x04,0x25,0xff,0x04,0xe7,0x08,0xe8,0x6a,0x01
+,0xe5,0x82,0x0d,0x02,0x00,0xe7,0x82,0xe9,0x21,0x00,0xe8,0x1a,0x06,0x80,0x3e,0xe8
+,0xff,0x00,0x74,0x0a,0x80,0x3e,0xe8,0xff,0x04,0x74,0x03,0xe9,0x0d,0x00,0xc6,0x06
+,0xe8,0xff,0x01,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0x80,0x3e,0x9f,0x36,0x06
+,0x75,0x05,0x83,0x0e,0x99,0x36,0x40,0xb8,0x00,0x01,0xe9,0x09,0x01,0xff,0x06,0xcc
+,0x33,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36,0xe7,0x06,0xff,0x06,0xc6,0x34
+,0xe9,0x1e,0x00,0xff,0x06,0xce,0x33,0xff,0x06,0x95,0x37,0x81,0x26,0xaf,0x36,0xff
+,0xef,0xa1,0xaf,0x36,0xe7,0x06,0xe9,0x08,0x00,0xff,0x06,0xd0,0x33,0xff,0x06,0x7a
+,0x34,0xff,0x06,0xd2,0x33,0xd1,0xe6,0x8e,0x06,0x30,0x34,0x2e,0x8b,0x84,0xc0,0x1c
+,0x26,0x09,0x06,0x08,0x00,0x2e,0x8b,0x84,0xc2,0x1c,0x09,0x06,0x66,0x37,0xc3,0xe5
+,0x0c,0xa9,0x80,0x00,0x74,0x56,0x50,0xe8,0xf0,0x00,0x58,0xa9,0x00,0x01,0x75,0x07
+,0xff,0x06,0xc6,0x33,0xe9,0x08,0x00,0xff,0x06,0x78,0x34,0xff,0x06,0xc8,0x33,0xe5
+,0x82,0x25,0xfd,0xff,0xe7,0x82,0xe8,0x6e,0x05,0xba,0x10,0x01,0xed,0x80,0x3e,0xe8
+,0xff,0x00,0x74,0x0a,0x80,0x3e,0xe8,0xff,0x04,0x74,0x03,0xe9,0x1d,0x00,0xc6,0x06
+,0xe8,0xff,0x01,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0xe9,0x0d,0x00,0xc6,0x06
+,0xe8,0xff,0x03,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0xc3,0xa9,0x01,0x00,0x74
+,0x1c,0xe8,0x2c,0x00,0x83,0x3e,0xe0,0x3a,0x00,0x74,0x0f,0x06,0x8e,0x06,0x38,0x34
+,0xe8,0xc9,0x04,0xc7,0x06,0xe0,0x3a,0x00,0x00,0x07,0xe9,0x5d,0x00,0x8b,0xd0,0x8e
+,0x06,0x38,0x34,0x26,0xa3,0x0c,0x00,0xe8,0x06,0x00,0x68,0x69,0x1d,0xe9,0x4a,0x00
+,0xa9,0x00,0x04,0x74,0x0a,0xb8,0x00,0x04,0xff,0x06,0xd8,0x33,0xe9,0x17,0x00,0xa9
+,0x00,0x01,0x74,0x0a,0xff,0x06,0x39,0x37,0xb8,0x00,0x01,0xe9,0x08,0x00,0xa9,0x10
+,0x00,0xb8,0x10,0x00,0x74,0x1d,0x09,0x06,0x66,0x37,0x8c,0xc0,0x8e,0x06,0x30,0x34
+,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x01
+,0x8e,0xc0,0xc3,0xff,0x06,0xc2,0x33,0xe9,0xf8,0xff,0xe5,0x00,0x0d,0x18,0x00,0xe7
+,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7,0x02,0xc3,0x58,0xe9,0x43,0xfd,0xe5,0x08,0x0d
+,0x00,0x04,0x25,0xff,0x04,0xe7,0x08,0xe9,0xe0,0xff,0xe5,0x0e,0xa9,0x00,0x08,0x75
+,0x01,0xc3,0xe9,0xf5,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb8
+,0x33,0xe5,0x48,0x06,0x53,0x57,0xff,0x16,0x4e,0x37,0x5f,0x5b,0x83,0x3e,0x80,0x01
+,0xff,0x74,0x58,0x8e,0x06,0x80,0x01,0x26,0xff,0x0e,0x08,0x00,0x75,0x4d,0x26,0xa1
+,0x00,0x00,0xa3,0x80,0x01,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x8c,0xc0,0x26,0x8e
+,0x06,0x02,0x00,0x26,0x81,0x0e,0x08,0x00,0x80,0x00,0x8b,0xd0,0x26,0x87,0x06,0x1a
+,0x00,0x26,0x83,0x3e,0x18,0x00,0xff,0x74,0x0a,0x8e,0xc0,0x26,0x89,0x16,0x00,0x00
+,0xe9,0x05,0x00,0x26,0x89,0x16,0x18,0x00,0x83,0x3e,0x80,0x01,0xff,0x74,0x0c,0x8e
+,0x06,0x80,0x01,0x26,0x83,0x3e,0x08,0x00,0x00,0x74,0xb3,0x07,0xe9,0x3e,0xf7,0xe5
+,0x4c,0x90,0xe5,0x02,0xa9,0x00,0x20,0x74,0x0d,0x25,0xff,0xdf,0x0d,0x01,0x00,0xe7
+,0x02,0x0d,0x00,0x20,0xe7,0x02,0xe5,0x0a,0x8b,0xd8,0xa3,0xf4,0x33,0x25,0xc3,0x57
+,0x0d,0x00,0x10,0xe7,0x0a,0xf7,0x06,0x9b,0x36,0x00,0x80,0x74,0x37,0xf7,0xc3,0x00
+,0x80,0x74,0x06,0xf7,0xc3,0x00,0x08,0x74,0x5d,0x81,0x26,0xc2,0x34,0x7f,0xff,0xc7
+,0x06,0x35,0x37,0x05,0x00,0xb8,0x80,0x03,0xcd,0x39,0x81,0x26,0x9b,0x36,0xff,0x7f
+,0xc7,0x06,0x0f,0x37,0x04,0x00,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06
+,0x0f,0x37,0x03,0x00,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x2a,0xf7,0xc3,0x00,0x08
+,0x74,0x24,0x80,0x3e,0x9d,0x36,0x06,0x7c,0x1d,0xff,0x06,0x94,0x34,0x83,0x0e,0x66
+,0x37,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26
+,0x81,0x0e,0x08,0x00,0x00,0x01,0xf7,0xc3,0x00,0x20,0x75,0x3b,0xf7,0x06,0x9a,0x37
+,0x80,0x00,0x74,0x0b,0xff,0x06,0x89,0x37,0x33,0xc0,0xe7,0x0e,0xe9,0x04,0x00,0xff
+,0x06,0x3b,0x37,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x1c,0x80,0x26,0x9e,0x36,0xff
+,0x75,0x15,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x08,0x74,0x07,0x26
+,0x81,0x0e,0x08,0x00,0x00,0x08,0xc3,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x02,0x23,0x02,0x23,0x02,0x23,0x02,0x23,0x03,0x23,0xdd,0x22,0x02,0x23,0xfd,0x21
+,0x02,0x23,0xa4,0x24,0xf3,0x24,0x02,0x23,0x8d,0x22,0x7a,0x23,0x02,0x23,0x97,0x24
+,0x1b,0x24,0x75,0x24,0x02,0x23,0x02,0x23,0x8e,0x25,0xfb,0x8e,0x06,0x7e,0x01,0xfb
+,0x26,0x83,0x3e,0x00,0x00,0xff,0x74,0xf2,0x26,0x8e,0x06,0x00,0x00,0xfa,0x26,0x8b
+,0x1e,0x08,0x00,0x26,0x23,0x1e,0x0a,0x00,0x74,0xe5,0x8c,0xc0,0x8e,0xd0,0x26,0x8b
+,0x26,0x02,0x00,0x8c,0x16,0xf2,0x33,0x22,0xff,0x75,0x6a,0x26,0xa1,0x1c,0x00,0x8a
+,0xe3,0x8a,0xdc,0x22,0xd8,0x75,0x0d,0xd0,0xe8,0x24,0xf8,0x0a,0xc0,0x75,0xf2,0xb0
+,0x80,0xe9,0xed,0xff,0xd0,0xe8,0x24,0xf8,0x0a,0xc0,0x75,0x02,0xb0,0x80,0x32,0xe4
+,0x26,0xa3,0x1c,0x00,0xf7,0xc3,0x08,0x00,0x75,0x47,0x2e,0x8a,0x9f,0xc5,0x25,0x2e
+,0x8b,0xbf,0xc5,0x26,0x80,0xc3,0x10,0x26,0x8e,0x1d,0x26,0x8c,0x1e,0x06,0x00,0x8b
+,0x16,0x00,0x00,0xc7,0x06,0x00,0x00,0xff,0xff,0x26,0x89,0x15,0x83,0xfa,0xff,0x75
+,0x0a,0x2e,0x8b,0x97,0xcd,0x26,0x26,0x21,0x16,0x08,0x00,0x33,0xc0,0x8e,0xd8,0x26
+,0x89,0x1e,0x04,0x00,0xc3,0x8a,0xdf,0xb7,0x00,0x2e,0x8a,0x9f,0xc5,0x25,0xe9,0xe0
+,0xff,0x26,0x83,0x26,0x08,0x00,0xf7,0x83,0xc3,0x10,0xe9,0xde,0xff,0x60,0x06,0x1e
+,0x68,0x87,0x25,0x6a,0x00,0x1f,0x8e,0x06,0xf2,0x33,0x8b,0x0e,0x34,0x34,0x39,0x0e
+,0xf2,0x33,0x74,0x0e,0x26,0x81,0x0e,0x0a,0x00,0x00,0x02,0x26,0x81,0x0e,0x08,0x00
+,0x00,0x02,0x26,0x89,0x26,0x02,0x00,0xa3,0xf2,0x33,0x8e,0xd0,0x8d,0x26,0x80,0x00
+,0x36,0x89,0x26,0x02,0x00,0x36,0x89,0x1e,0x20,0x00,0x36,0xc7,0x06,0x08,0x00,0x00
+,0x00,0xb9,0x04,0x00,0xbe,0x00,0x00,0x2e,0x8b,0xbc,0xc5,0x26,0x36,0xc7,0x05,0xff
+,0xff,0x36,0xc7,0x45,0x02,0xff,0xff,0x83,0xc6,0x02,0xe2,0xeb,0x8e,0x06,0x7e,0x01
+,0x36,0x8b,0x0e,0x22,0x00,0x8c,0xc0,0x26,0x83,0x3e,0x00,0x00,0xff,0x26,0x8e,0x06
+,0x00,0x00,0x74,0x07,0x26,0x3b,0x0e,0x22,0x00,0x7d,0xea,0x36,0x8c,0x06,0x00,0x00
+,0x8e,0xc0,0x26,0x8c,0x16,0x00,0x00,0xfb,0x36,0xff,0x2e,0x1e,0x00,0x06,0x1e,0x68
+,0x8b,0x25,0x6a,0x00,0x1f,0x26,0x09,0x36,0x08,0x00,0xf7,0xc6,0x00,0xff,0x74,0x01
+,0xc3,0x56,0x52,0x2e,0x8b,0xb4,0xc5,0x25,0x81,0xe6,0xff,0x00,0x2e,0x8b,0xb4,0xc5
+,0x26,0x8c,0xc2,0x8e,0xc0,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x8e,0xc2,0x26,0x83
+,0x3c,0xff,0x74,0x0f,0x8b,0xd0,0x26,0x87,0x54,0x02,0x8e,0xc2,0x26,0xa3,0x00,0x00
+,0xe9,0x07,0x00,0x26,0x89,0x44,0x02,0x26,0x89,0x04,0x5a,0x5e,0xc3,0x06,0x1e,0x68
+,0x8b,0x25,0x6a,0x00,0x1f,0x8e,0x06,0xf2,0x33,0x26,0xa3,0x0a,0x00,0x26,0x89,0x26
+,0x02,0x00,0xa1,0x34,0x34,0x8e,0xd0,0x8d,0x26,0x80,0x00,0x8c,0x16,0xf2,0x33,0xe9
+,0x4d,0xfe,0xcf,0x50,0x1e,0x52,0x53,0x33,0xc0,0x8e,0xd8,0x26,0x83,0x3e,0x04,0x00
+,0xff,0x26,0xc7,0x06,0x04,0x00,0x00,0x00,0x74,0x03,0xe9,0x1a,0x00,0x83,0x3e,0xe6
+,0x3a,0x02,0x76,0x13,0xff,0x06,0xd6,0x33,0x8c,0xc0,0x8e,0x06,0x32,0x34,0xbe,0x40
+,0x00,0x68,0x3a,0x23,0xe9,0x5e,0xff,0xe8,0x84,0xf8,0x5b,0x5a,0x1f,0x58,0xcf,0xe8
+,0xe1,0x00,0x26,0xc6,0x06,0x18,0x00,0x10,0x26,0x8a,0x1e,0x29,0x00,0x88,0x1e,0x1b
+,0x37,0x26,0xc7,0x06,0x0c,0x00,0xff,0x7f,0x26,0xa1,0x0e,0x00,0xe7,0x9c,0x26,0xa1
+,0x08,0x00,0xe7,0x9a,0xe5,0x00,0x80,0xfb,0x08,0x74,0x09,0x0d,0x18,0xac,0xe7,0x00
+,0x07,0x1f,0x58,0xcf,0x0d,0x18,0x00,0xe9,0xf4,0xff,0x50,0x1e,0x06,0x33,0xc0,0x8e
+,0xd8,0x83,0x3e,0xa1,0x36,0x00,0x75,0xb7,0x26,0x8b,0x36,0x06,0x00,0x2e,0xff,0x94
+,0xdc,0x23,0x07,0x1f,0x58,0xcf,0xe8,0x8a,0x00,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00
+,0xe8,0x49,0x00,0xc3,0x53,0xf7,0x06,0xef,0x34,0x20,0x00,0x75,0x2d,0xe5,0x8c,0x25
+,0x00,0x70,0x8b,0xd8,0xe5,0x8c,0x25,0x00,0x70,0x3b,0xc3,0x74,0x05,0x8b,0xd8,0xe9
+,0xf2,0xff,0x3d,0x00,0x30,0x75,0x10,0xe5,0x02,0x25,0xef,0xff,0xe7,0x02,0xc7,0x06
+,0xe0,0x3a,0xff,0xff,0xe9,0x03,0x00,0xe8,0x12,0x00,0x5b,0xc3,0xa3,0x23,0x96,0x23
+,0xa4,0x23,0xa4,0x23,0x96,0x23,0xa4,0x23,0x96,0x23,0x96,0x23,0x26,0xa0,0x29,0x00
+,0xa2,0x1b,0x37,0x26,0xc7,0x06,0x0c,0x00,0xff,0x7f,0x26,0xa1,0x0e,0x00,0xe7,0x9c
+,0x26,0xa1,0x08,0x00,0xe7,0x9a,0xe5,0x00,0x25,0xff,0x53,0x26,0x8b,0x36,0x06,0x00
+,0x83,0xe6,0x0e,0x2e,0x0b,0x84,0xad,0x25,0xe7,0x00,0xc3,0x06,0x1e,0x68,0x8b,0x25
+,0x6a,0x00,0x1f,0x83,0x0e,0xef,0x34,0x20,0x83,0x0e,0x9b,0x36,0x08,0xe5,0x00,0x25
+,0xef,0xff,0x0d,0x08,0x00,0xe7,0x00,0xe5,0x00,0xa9,0x10,0x00,0x75,0x01,0xc3,0xe5
+,0x00,0xa9,0x10,0x00,0x75,0xf9,0xc3,0x50,0x53,0x51,0x56,0x06,0x1e,0x33,0xc0,0x8e
+,0xd8,0xb8,0x05,0x00,0xe7,0x84,0xe5,0x08,0x0d,0x00,0x04,0x25,0xff,0x04,0xe7,0x08
+,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7,0x02,0x1f,0x07
+,0x5e,0x59,0x5b,0x58,0xc3,0x50,0x1e,0x33,0xc0,0x8e,0xd8,0xc7,0x06,0xef,0x34,0x00
+,0x00,0x83,0x26,0x9b,0x36,0xf7,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d
+,0x11,0x00,0xe7,0x02,0x1f,0x58,0xcf,0x60,0x06,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f
+,0xe8,0x16,0xf5,0xc3,0x06,0x1e,0x68,0x8b,0x25,0x6a,0x00,0x1f,0x8e,0xc0,0x26,0x83
+,0x3e,0x0a,0x00,0x00,0x74,0x03,0xe8,0x43,0x00,0x26,0xc7,0x06,0x0a,0x00,0xff,0xff
+,0x26,0x8b,0x16,0x06,0x00,0x8e,0x1e,0x8e,0x01,0x8c,0xd8,0x8b,0xca,0x83,0x3e,0x00
+,0x00,0xff,0x8e,0x1e,0x00,0x00,0x74,0x0a,0x2b,0x16,0x08,0x00,0x73,0xeb,0x29,0x0e
+,0x08,0x00,0x26,0x89,0x0e,0x08,0x00,0x26,0x8c,0x1e,0x00,0x00,0x8e,0xd8,0x8c,0x06
+,0x00,0x00,0xc3,0x60,0x06,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f,0x8e,0xc0,0x8b,0xc8
+,0x8e,0x1e,0x8e,0x01,0x26,0xc7,0x06,0x0a,0x00,0x00,0x00,0x8c,0xd8,0x83,0x3e,0x00
+,0x00,0xff,0x74,0x25,0x3b,0x0e,0x00,0x00,0x8e,0x1e,0x00,0x00,0x75,0xed,0x8e,0xd8
+,0x26,0xa1,0x00,0x00,0xa3,0x00,0x00,0x3d,0xff,0xff,0x74,0x56,0x8e,0xd8,0x26,0xa1
+,0x08,0x00,0x01,0x06,0x08,0x00,0xe9,0x49,0x00,0x26,0x8e,0x1e,0x02,0x00,0xbe,0x18
+,0x00,0x83,0x3c,0xff,0x74,0x3c,0x39,0x0c,0x74,0x19,0x8e,0x1c,0xbe,0x00,0x00,0x83
+,0x3e,0x00,0x00,0xff,0x74,0x2c,0x39,0x0e,0x00,0x00,0x74,0x07,0x8e,0x1e,0x00,0x00
+,0xe9,0xec,0xff,0x26,0xa1,0x00,0x00,0x89,0x04,0x33,0xc9,0x8e,0xd9,0x3d,0xff,0xff
+,0x75,0x10,0x83,0xfe,0x18,0x75,0x0b,0x26,0x8e,0x1e,0x02,0x00,0x81,0x26,0x08,0x00
+,0x7f,0xff,0x33,0xc0,0x8e,0xd8,0xc3,0x1f,0x07,0x61,0xcf,0x1f,0x07,0xcf,0x60,0x06
+,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f,0xe5,0x06,0x25,0x1e,0x00,0x3d,0x1e,0x00,0x75
+,0xf6,0xb9,0x08,0x00,0xe5,0x58,0xe7,0x5a,0x23,0xc0,0xe0,0xf8,0xc3,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x00,0x00,0x00,0xa8,0x00,0x8c,0x02,0x04,0x00
+,0x00,0x08,0x10,0x20,0x00,0xff,0x0e,0x0c,0x0c,0x0a,0x0a,0x0a,0x0a,0x08,0x08,0x08
+,0x08,0x08,0x08,0x08,0x08,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06
+,0x06,0x06,0x06,0x06,0x06,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
+,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
+,0x04,0x04,0x04,0x04,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
+,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
+,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
+,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
+,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x14,0x00,0x10,0x00,0x0c,0x00,0xff,0x7f,0xff
+,0xbf,0xff,0xdf,0xff,0xef,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,0xfe,0x7f,0xff,0xbf
+,0xff,0xdf,0xff,0xef,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,0xfe,0xff,0x00,0x00,0x00
+,0x80,0x3e,0xe2,0x34,0x01,0x76,0x03,0xe9,0xa5,0x00,0xb8,0x00,0x00,0xe7,0x4e,0xb9
+,0x28,0x00,0xe2,0xfe,0xc6,0x06,0x45,0x37,0x02,0xbf,0x3f,0x28,0x2e,0x8b,0x45,0x08
+,0xe7,0x4e,0xb9,0x28,0x00,0xe2,0xfe,0x2e,0x8b,0x1d,0xc7,0x06,0xb3,0x36,0x40,0x11
+,0xc7,0x06,0xb1,0x36,0x27,0x00,0xc7,0x06,0x46,0x37,0x02,0x00,0xc7,0x06,0x48,0x37
+,0x64,0x00,0xf7,0x06,0xb5,0x36,0x02,0x00,0x75,0x1c,0x2e,0x0b,0x5d,0x02,0x81,0x26
+,0xb3,0x36,0xff,0xfe,0xc7,0x06,0xb1,0x36,0x9c,0x00,0xc7,0x06,0x46,0x37,0x08,0x00
+,0xc7,0x06,0x48,0x37,0x90,0x01,0x89,0x1e,0xb7,0x36,0x89,0x1e,0xfe,0x33,0xbe,0x20
+,0x00,0x8b,0xc3,0xe7,0x4e,0xb9,0x28,0x00,0xe2,0xfe,0x2e,0x8b,0x45,0x04,0xe7,0x4e
+,0xb9,0x28,0x00,0xe2,0xfe,0xe5,0x4e,0x8b,0xcb,0x2e,0x23,0x45,0x06,0x2e,0x23,0x4d
+,0x06,0x3a,0xc1,0x74,0x36,0x4e,0x75,0xd9,0x80,0x3e,0x45,0x37,0x00,0x74,0x0b,0xc6
+,0x06,0x45,0x37,0x00,0xbf,0x2f,0x28,0xe9,0x72,0xff,0xc6,0x06,0x45,0x37,0x01,0xf7
+,0x06,0xb5,0x36,0x02,0x00,0x74,0x14,0xe5,0xce,0x25,0xfd,0xff,0xe7,0xce,0xe8,0x43
+,0x00,0xe5,0xce,0x0d,0x02,0x00,0xe7,0xce,0xe8,0x39,0x00,0x80,0x3e,0xe2,0x34,0x01
+,0x76,0x01,0xc3,0xb8,0xea,0x05,0xe7,0x8c,0xfa,0xe8,0x12,0xf4,0xfb,0x8d,0x06,0xd0
+,0x39,0x8b,0xd8,0xc1,0xe8,0x04,0xa3,0x38,0x34,0x8e,0xc0,0xa1,0x30,0x34,0x26,0xa3
+,0x02,0x00,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x83,0xc3,0x18,0xd1,0xeb,0x26,0x89
+,0x1e,0x08,0x00,0xc3,0xe5,0x02,0x0d,0x00,0x40,0xe7,0x02,0xe5,0x00,0x0d,0x04,0x00
+,0xe7,0x00,0xb8,0x00,0x00,0xe7,0x0a,0xe5,0x0a,0xa9,0x00,0x80,0x75,0x14,0xe5,0x08
+,0x0d,0x00,0x10,0xe7,0x08,0xe5,0x0a,0x0d,0x00,0x08,0xb9,0x05,0x00,0xe7,0x0a,0xe2
+,0xfc,0xc3,0xe5,0x08,0x0d,0x00,0x10,0xb9,0x05,0x00,0xe7,0x08,0xe2,0xfc,0xc3,0x04
+,0x0c,0x20,0x00,0x01,0x0c,0x7e,0xff,0x00,0x0c,0x02,0x00,0x10,0x00,0x40,0x00,0x0c
+,0xc6,0x01,0x00,0x00,0xc0,0xf7,0xff,0x00,0xc0,0x02,0x00,0x10,0x00,0x40,0x00,0x00
+,0x33,0xc0,0x8e,0xd8,0x8d,0x3e,0x72,0x49,0x8d,0x36,0xb0,0x37,0xb9,0x14,0x00,0x8b
+,0x1e,0x30,0x34,0x89,0x5c,0x02,0x2e,0x8b,0x45,0x02,0x89,0x44,0x06,0x2e,0x8b,0x05
+,0x89,0x44,0x04,0x83,0xc7,0x04,0x83,0xc6,0x10,0xe2,0xe8,0xc6,0x06,0x9e,0x36,0x0e
+,0xe8,0xfd,0x26,0x68,0x83,0x28,0xa1,0xaa,0x02,0xcd,0x35,0x83,0x3e,0xa1,0x36,0x00
+,0x74,0x03,0xe9,0x3b,0x27,0x33,0xff,0x8e,0x06,0xa6,0x02,0x8b,0x36,0xa4,0x02,0x2e
+,0xff,0xa4,0x2e,0x30,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37,0x37,0x01,0x00,0xc6
+,0x06,0xca,0x34,0x01,0xe9,0x7d,0x19,0x80,0x3e,0xa0,0x36,0x08,0x74,0xe6,0x80,0x26
+,0x9e,0x36,0xff,0x75,0x1a,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x12,0xf7,0x06,0x9b
+,0x36,0x03,0x00,0x75,0x0a,0x83,0x0e,0x66,0x37,0x10,0xc6,0x06,0xa0,0x36,0x08,0xe9
+,0xfb,0x01,0x80,0x3e,0x9e,0x36,0x02,0x75,0xce,0xc6,0x06,0xa0,0x36,0x06,0xe9,0xec
+,0x01,0xc3,0xe9,0xe8,0x01,0x26,0xc7,0x06,0x0a,0x00,0x00,0x00,0x26,0xff,0x26,0x04
+,0x00,0xa1,0xd1,0x36,0x26,0x39,0x06,0x1a,0x00,0x75,0x22,0xa1,0xd3,0x36,0x26,0x39
+,0x06,0x1c,0x00,0x75,0x18,0xa1,0xd5,0x36,0x26,0x39,0x06,0x1e,0x00,0x75,0x0e,0x26
+,0xf7,0x06,0x0c,0x00,0x40,0x00,0x74,0x05,0x83,0x0e,0x66,0x37,0x40,0x81,0x0e,0xaf
+,0x36,0x00,0x10,0xa1,0xaf,0x36,0xe7,0x06,0x80,0x3e,0x9d,0x36,0x02,0x75,0x06,0xcd
+,0x34,0xe9,0xa2,0x1a,0xc3,0xf7,0x06,0x9b,0x36,0x10,0x00,0x75,0x54,0x26,0xf6,0x06
+,0x0a,0x00,0xff,0x75,0x4c,0x26,0xa0,0x19,0x00,0x24,0xc0,0x3c,0x40,0x75,0x11,0x80
+,0x3e,0x95,0x36,0x00,0x74,0x3b,0x26,0xc7,0x06,0x04,0x00,0xff,0xff,0xe9,0x31,0x00
+,0xe8,0xf1,0x04,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74,0x2f,0x8b,0xd8,0xb8,0x7d,0x03
+,0xcd,0x3a,0x8b,0xc3,0xc6,0x06,0xa0,0x36,0x06,0xf7,0x06,0x9b,0x36,0x02,0x00,0x75
+,0x05,0xc6,0x06,0xa0,0x36,0x04,0x81,0x0e,0x9b,0x36,0x80,0x00,0x83,0x26,0x9b,0x36
+,0xfc,0xe9,0x23,0x01,0xe8,0x87,0x1d,0xe9,0x33,0x01,0x50,0x26,0xa1,0x0c,0x00,0x25
+,0x07,0x00,0x3d,0x07,0x00,0x75,0x03,0xe9,0x84,0x00,0x3d,0x05,0x00,0x75,0x03,0xe9
+,0x7c,0x00,0x83,0x3e,0xe8,0x3a,0x04,0x74,0x75,0x83,0x3e,0xe8,0x3a,0x02,0x74,0x6e
+,0xf7,0x06,0xe6,0x34,0x18,0x80,0x75,0x03,0xe9,0x6a,0x00,0xf7,0x06,0xe6,0x34,0x00
+,0x80,0x74,0x35,0x26,0x80,0x3e,0x29,0x00,0x02,0x75,0x2d,0x51,0x56,0x57,0x8d,0x36
+,0x3e,0x34,0x8d,0x3e,0x20,0x00,0xb9,0x06,0x00,0xf3,0xa6,0x5f,0x5e,0x59,0x74,0x45
+,0x26,0xa1,0x20,0x00,0xa3,0x3e,0x34,0x26,0xa1,0x22,0x00,0xa3,0x40,0x34,0x26,0xa1
+,0x24,0x00,0xa3,0x42,0x34,0xe9,0x26,0x00,0xf7,0x06,0xe6,0x34,0x08,0x00,0x74,0x0b
+,0x26,0x80,0x3e,0x19,0x00,0x00,0x74,0x03,0xe9,0x13,0x00,0xf7,0x06,0xe6,0x34,0x10
+,0x00,0x74,0x12,0x26,0xa0,0x28,0x00,0xc0,0xe8,0x04,0x22,0xc0,0x74,0x07,0x26,0xc7
+,0x06,0x04,0x00,0xff,0xff,0x58,0x23,0xc0,0x74,0x03,0xe9,0x57,0xff,0x81,0x26,0x9b
+,0x36,0xff,0xfe,0x83,0xfe,0x06,0x7f,0x24,0x26,0xa1,0x20,0x00,0x3b,0x06,0xd1,0x36
+,0x75,0x1a,0x26,0xa1,0x22,0x00,0x3b,0x06,0xd3,0x36,0x75,0x10,0x26,0xa1,0x24,0x00
+,0x3b,0x06,0xd5,0x36,0x75,0x06,0x81,0x0e,0x9b,0x36,0x00,0x01,0x26,0xa1,0x20,0x00
+,0x25,0x7f,0xff,0xa3,0xb8,0x34,0x26,0xa1,0x22,0x00,0xa3,0xba,0x34,0x26,0xa1,0x24
+,0x00,0xa3,0xbc,0x34,0x8b,0xc6,0x86,0xc4,0xa3,0xc0,0x34,0xd1,0xe6,0x80,0xfc,0x09
+,0x74,0x03,0xe8,0xaa,0x1c,0x8b,0xc6,0x2e,0xff,0xa4,0x30,0x49,0x26,0xa1,0x0c,0x00
+,0x3d,0xff,0x7f,0x74,0x0f,0x26,0xff,0x26,0x04,0x00,0x8e,0x06,0x38,0x34,0xe8,0x36
+,0x06,0xcd,0x50,0xc3,0xe9,0x16,0x00,0xcd,0x34,0xe9,0x11,0x00,0xcd,0x34,0x89,0x36
+,0x3d,0x37,0xa1,0x9d,0x36,0xa3,0x3f,0x37,0xc6,0x06,0xa0,0x36,0x0c,0xe8,0x8e,0x00
+,0xa1,0x9f,0x36,0x22,0xe4,0x75,0x32,0xf7,0x06,0x4c,0x37,0x01,0x00,0x75,0x2a,0xf6
+,0x06,0x9d,0x36,0x80,0x74,0x07,0x88,0x26,0x9e,0x36,0xe9,0x31,0x00,0x3a,0x06,0x9d
+,0x36,0xa3,0x9d,0x36,0x74,0x28,0x8b,0xf0,0x2e,0xff,0xa4,0x0d,0x2b,0x44,0x29,0xee
+,0x42,0x19,0x44,0xcd,0x44,0x2f,0x45,0x5a,0x45,0x3a,0x26,0x9e,0x36,0x75,0x01,0xc3
+,0x32,0xc0,0x86,0xc4,0x8b,0xf0,0xa2,0x9e,0x36,0x2e,0xff,0xa4,0x20,0x49,0x8b,0x2e
+,0x99,0x36,0x23,0xed,0x75,0x01,0xc3,0xbf,0x01,0x00,0xbe,0x00,0x00,0x85,0xfd,0x75
+,0x1a,0x46,0xd1,0xe7,0xe9,0xf6,0xff,0x2a,0x00,0x29,0x00,0x28,0x00,0x27,0x00,0x25
+,0x00,0x05,0x00,0x07,0x00,0x26,0x00,0x06,0x00,0x20,0x00,0xf7,0xd7,0x21,0x3e,0x99
+,0x36,0xd1,0xe6,0x2e,0x8b,0xb4,0x47,0x2b,0xe9,0x4f,0xff,0xe9,0x56,0xff,0x80,0x26
+,0x9e,0x36,0xff,0x75,0x17,0xf7,0x06,0x4c,0x37,0x01,0x00,0x75,0x0f,0xf6,0x06,0x9d
+,0x36,0x80,0x74,0x08,0xf7,0x06,0x66,0x37,0xff,0xff,0x75,0x07,0xc7,0x06,0x66,0x37
+,0x00,0x00,0xc3,0xf7,0x06,0x41,0x37,0x01,0x00,0x75,0x0b,0xb8,0x7f,0x03,0xcd,0x39
+,0xc7,0x06,0x41,0x37,0x01,0x00,0x33,0xf6,0xb8,0x00,0x40,0x85,0x06,0x66,0x37,0x74
+,0x21,0x80,0xbc,0x54,0x37,0xff,0x74,0x04,0xfe,0x84,0x54,0x37,0x80,0xbc,0x96,0x34
+,0xff,0x74,0x04,0xfe,0x84,0x96,0x34,0x31,0x06,0x66,0x37,0x83,0x3e,0x66,0x37,0x00
+,0x74,0x05,0x46,0xd1,0xe8,0x73,0xd4,0xc3,0xa1,0xf4,0x33,0xa9,0x00,0x88,0x74,0x0b
+,0xa9,0x00,0x10,0x75,0x09,0x8b,0x1e,0x43,0x37,0xff,0xe3,0xe9,0xd7,0x00,0xc7,0x06
+,0x35,0x37,0x05,0x00,0xc7,0x06,0x43,0x37,0x1e,0x2c,0xf7,0x06,0xf4,0x33,0x00,0x08
+,0x74,0x06,0xc7,0x06,0x43,0x37,0x10,0x2c,0xb8,0x80,0x03,0xcd,0x39,0xe9,0xcd,0xfe
+,0xa9,0x00,0x08,0x74,0xd9,0xff,0x0e,0x35,0x37,0x75,0xed,0xe9,0x66,0x00,0xa9,0x00
+,0x08,0x75,0xcb,0xff,0x0e,0x35,0x37,0x75,0xdf,0x81,0x0e,0xc2,0x34,0xc0,0x00,0xf6
+,0x06,0x9d,0x36,0x80,0x74,0x48,0x81,0x0e,0x9b,0x36,0x00,0x80,0xf7,0x06,0x9b,0x36
+,0x01,0x00,0x74,0x1e,0xb8,0x7d,0x03,0xcd,0x3a,0x81,0x0e,0x9b,0x36,0x80,0x00,0x83
+,0x26,0x9b,0x36,0xfe,0xc7,0x06,0x0f,0x37,0x02,0x00,0xc6,0x06,0xa0,0x36,0x04,0xe9
+,0x7b,0xfe,0x80,0x3e,0xa0,0x36,0x04,0x75,0x07,0x83,0x3e,0x0f,0x37,0x01,0x75,0x05
+,0xc6,0x06,0xa0,0x36,0x06,0xc7,0x06,0x0f,0x37,0x02,0x00,0xe9,0x5f,0xfe,0xbe,0x02
+,0x00,0xe9,0x4a,0xfe,0x80,0x26,0x9e,0x36,0xff,0x75,0x3a,0xf6,0x06,0x9d,0x36,0x80
+,0x74,0x2d,0xf7,0x06,0x9b,0x36,0x00,0x20,0x75,0x2b,0xc6,0x06,0xa0,0x36,0x06,0xff
+,0x06,0x94,0x34,0x83,0x0e,0x66,0x37,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a
+,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x01,0xe9,0x06,0x00,0xbe
+,0x04,0x00,0xe9,0x09,0xfe,0x81,0x0e,0xaf,0x36,0x00,0x08,0xa1,0xaf,0x36,0xe7,0x06
+,0xe5,0x0a,0xa9,0x00,0x80,0x74,0x0e,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36
+,0xe7,0x06,0xe9,0x09,0xff,0xe9,0xf5,0xfd,0xc7,0x06,0x41,0x37,0x00,0x00,0x83,0x0e
+,0x99,0x36,0x02,0xe9,0xe7,0xfd,0x80,0x26,0x9e,0x36,0xff,0x75,0x1d,0xf7,0x06,0x9b
+,0x36,0x00,0x40,0x75,0x05,0x83,0x0e,0x99,0x36,0x08,0x83,0x0e,0x99,0x36,0x20,0x81
+,0x26,0x9b,0x36,0xff,0xbf,0xb8,0x85,0x03,0xcd,0x39,0xe9,0xc0,0xfd,0x80,0x3e,0x9e
+,0x36,0x06,0x74,0x07,0x80,0x3e,0x9e,0x36,0x0a,0x75,0x34,0xf6,0x06,0x9d,0x36,0x80
+,0x75,0x06,0xbe,0x07,0x00,0xe9,0x96,0xfd,0xc6,0x06,0xa0,0x36,0x04,0x83,0x3e,0x0f
+,0x37,0x02,0x74,0x1b,0xc7,0x06,0x0f,0x37,0x04,0x00,0x80,0x3e,0x9e,0x36,0x06,0x75
+,0x0e,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06,0x0f,0x37,0x03,0x00,0xe9
+,0x7b,0xfd,0x80,0x3e,0x9d,0x36,0x04,0x75,0x12,0x81,0x0e,0xc2,0x34,0x00,0x40,0xff
+,0x06,0x92,0x34,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x62,0xfd,0xbe,0x05,0x00,0xe9,0x4d
+,0xfd,0xf6,0x06,0x9d,0x36,0x80,0x75,0x19,0x83,0x0e,0xc2,0x34,0x04,0xbe,0x06,0x00
+,0xe9,0x3b,0xfd,0x80,0x26,0x9e,0x36,0xff,0x75,0xc5,0xff,0x06,0x31,0x37,0xe9,0x00
+,0x00,0x83,0x26,0xc2,0x34,0xbf,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x2f,0xfd,0xe5,0x0a
+,0x50,0x25,0xc3,0xbf,0xe7,0x0a,0x58,0x80,0x26,0x9e,0x36,0xff,0x75,0x0d,0xa9,0x00
+,0x40,0x75,0x08,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x12,0xfd,0xb8,0x83,0x03,0xcd,0x39
+,0xc3,0xb8,0x7c,0x03,0xcd,0x39,0xf7,0x06,0xf4,0x33,0x00,0x10,0x75,0x09,0xc7,0x06
+,0x33,0x37,0x02,0x00,0xe9,0xf6,0xfc,0xff,0x0e,0x33,0x37,0x74,0x03,0xe9,0xed,0xfc
+,0xff,0x06,0x8e,0x34,0xe8,0xf7,0x19,0x83,0x0e,0xc2,0x34,0x08,0xbe,0x03,0x00,0xe9
+,0xcc,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x04,0x05
+,0x04,0x04,0x04,0x00,0x03,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x04,0x00,0x08,0x08,0x05,0x08,0x08,0x08,0x00,0x03,0x00,0x03,0x03,0x00,0x00
+,0x02,0x04,0x04,0x04,0x04,0x00,0x00,0x08,0x00,0x00,0x0a,0x14,0x00,0x00,0x1a,0x00
+,0x1c,0x00,0x1e,0x20,0x00,0x00,0x04,0x41,0x06,0x0b,0x08,0xc2,0xff,0xe7,0x04,0x03
+,0x06,0x04,0x04,0x05,0x04,0x06,0x04,0x87,0x04,0x03,0x06,0x04,0x04,0x85,0x4e,0xa2
+,0x04,0xcf,0x04,0xcd,0xc7,0x06,0xa2,0x37,0x00,0x00,0xc7,0x06,0xa6,0x37,0x00,0x00
+,0x26,0xa1,0x20,0x00,0x25,0x7f,0xff,0xa3,0xf5,0x36,0x26,0xa1,0x22,0x00,0xa3,0xf7
+,0x36,0x26,0xa1,0x24,0x00,0xa3,0xf9,0x36,0xe8,0x3b,0x19,0x8b,0xf0,0x26,0x8b,0x0e
+,0x0e,0x00,0x2b,0xc8,0x83,0xe9,0x0e,0xb8,0x01,0x80,0x83,0xf9,0x04,0x7c,0x51,0x26
+,0x8a,0x54,0x28,0x88,0x16,0x1c,0x37,0x40,0x26,0x8b,0x6c,0x26,0x86,0xcd,0x3b,0xcd
+,0x86,0xcd,0x89,0x0e,0xa4,0x37,0x75,0x38,0x40,0x32,0xff,0x26,0x8a,0x5c,0x29,0x80
+,0xfb,0x15,0x77,0x25,0x80,0xfb,0x0a,0x74,0x20,0x80,0xfb,0x01,0x74,0x1b,0xb8,0x04
+,0x80,0x2e,0x3a,0x97,0x02,0x2e,0x74,0x07,0x2e,0x3a,0x97,0x18,0x2e,0x75,0x11,0x33
+,0xc0,0x80,0xfb,0x09,0x75,0x4f,0x8b,0xf3,0xc3,0x26,0xc7,0x06,0x04,0x00,0xff,0xff
+,0x50,0x52,0xa1,0xa4,0x37,0x86,0xc4,0x26,0x3b,0x06,0x26,0x00,0x7c,0x32,0x26,0x81
+,0x3e,0x26,0x00,0x00,0x04,0x7e,0x29,0x8d,0x74,0x2a,0x26,0x8b,0x14,0x22,0xd2,0x74
+,0x1f,0x80,0xe6,0xbf,0x80,0xfe,0x09,0x75,0x17,0xc7,0x06,0xa2,0x37,0x01,0x00,0x80
+,0xfa,0x04,0x75,0x0c,0x26,0x8b,0x44,0x02,0xa3,0x03,0x37,0x86,0xc4,0xa3,0xd0,0x34
+,0x5a,0x58,0xe9,0xb1,0xff,0xbd,0x72,0x37,0x2e,0x8a,0x87,0x2e,0x2e,0x22,0xc0,0x74
+,0x16,0x05,0x44,0x2e,0x8b,0xf8,0x2e,0x8b,0x05,0x3e,0x89,0x46,0x00,0x83,0xc5,0x02
+,0x83,0xc7,0x02,0x22,0xe4,0x7d,0xef,0x8d,0x74,0x2a,0x83,0xe9,0x04,0x75,0x03,0xe9
+,0xa1,0x00,0x26,0x8b,0x14,0x22,0xd2,0x75,0x03,0xe9,0x7c,0x00,0xc7,0x06,0xa6,0x37
+,0x01,0x00,0xbf,0x72,0x37,0x8b,0x05,0x83,0xc7,0x02,0x80,0xe6,0xbf,0x80,0xe4,0x3f
+,0x80,0xfe,0x09,0x75,0x22,0x80,0xfa,0x04,0x75,0x5e,0xc7,0x06,0xa2,0x37,0x01,0x00
+,0x26,0x8b,0x44,0x02,0xa3,0x03,0x37,0x86,0xc4,0xa3,0xd0,0x34,0x86,0xc4,0xc7,0x06
+,0xa6,0x37,0x00,0x00,0xe9,0x47,0x00,0x3b,0xfd,0x7e,0x15,0x26,0x8b,0x04,0xa8,0x40
+,0x74,0x06,0xb8,0x07,0x80,0xe9,0x38,0xff,0x32,0xc0,0x26,0x8b,0x04,0xe9,0x2e,0x00
+,0x3a,0xf4,0x75,0xb1,0xc7,0x45,0xfe,0x00,0x00,0x80,0xfe,0x22,0x75,0x0d,0x3a,0xd0
+,0x77,0x16,0xc7,0x06,0xa6,0x37,0x00,0x00,0xe9,0x13,0x00,0x3a,0xd0,0x75,0x09,0xc7
+,0x06,0xa6,0x37,0x00,0x00,0xe9,0x06,0x00,0xb8,0x05,0x80,0xe9,0x02,0xff,0x32,0xf6
+,0x03,0xf2,0x2b,0xca,0xb8,0x05,0x80,0x23,0xc9,0x76,0x03,0xe9,0x64,0xff,0x74,0x03
+,0xe9,0xed,0xfe,0x33,0xc0,0xbf,0x72,0x37,0x8b,0x15,0x47,0x47,0x3b,0xfd,0x7f,0x1b
+,0xf6,0xc6,0x80,0x74,0x16,0xf7,0x06,0xa6,0x37,0x01,0x00,0x74,0x06,0xb8,0x08,0x80
+,0xe9,0xc3,0xfe,0xf6,0xc6,0x40,0x74,0xe0,0xb8,0x07,0x80,0xe9,0xb8,0xfe,0x7d,0x42
+,0xa3,0x45,0x44,0x29,0x44,0x29,0xb7,0x28,0xe2,0x28,0xee,0x2b,0xf2,0x28,0xf5,0x28
+,0x01,0x29,0xac,0x2a,0x44,0x29,0x44,0x29,0x44,0x29,0x44,0x29,0x44,0x29,0x00,0x00
+,0x73,0x36,0x00,0x00,0x03,0x36,0xc5,0x35,0x83,0x35,0x45,0x35,0x07,0x35,0xd2,0x34
+,0x45,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0xa6,0x38,0x00,0x00,0xe0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xf2,0x33,0x00,0x00,0xa6,0x33,0x60,0x33,0xfd,0x32,0xbc,0x32,0x77,0x32,0x3c,0x32
+,0xfb,0x31,0x6a,0x31,0x0a,0x31,0xe0,0xe0,0x10,0x10,0x10,0xe0,0xe0,0xe0,0xe0,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0
+,0xe0,0x33,0xff,0x26,0xf6,0x06,0x1a,0x00,0x80,0x74,0x1b,0x26,0x80,0x26,0x1a,0x00
+,0x7f,0x26,0x8b,0x3e,0x26,0x00,0x83,0xe7,0x1f,0x74,0x0b,0x26,0x80,0x0e,0x20,0x00
+,0x80,0x26,0x01,0x3e,0x0e,0x00,0xc3,0x60,0x2e,0x8b,0x84,0xa6,0x30,0x26,0xa3,0x18
+,0x00,0xd1,0xe6,0x2e,0xff,0x94,0x50,0x30,0x61,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4
+,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x16,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26
+,0xc6,0x06,0x19,0x00,0x00,0xe8,0xbf,0x05,0xe8,0x98,0x05,0x26,0xc7,0x06,0x26,0x00
+,0x00,0x08,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29,0x00,0x2a,0xbf,0x2a
+,0x00,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x2a,0xa1,0x93,0x37,0x33,0xdb,0xa9
+,0x40,0x00,0x75,0x02,0xb3,0x01,0xa9,0x00,0x10,0x74,0x02,0xb7,0x88,0xa9,0x00,0x08
+,0x74,0x03,0x80,0xcf,0x44,0x26,0x89,0x5d,0x02,0xc3,0x83,0x0e,0xc2,0x34,0x20,0x26
+,0xc7,0x06,0x04,0x00,0x6b,0x2b,0x26,0xc7,0x06,0x0e,0x00,0x30,0x00,0x26,0xc7,0x06
+,0x06,0x00,0x0a,0x00,0x26,0xc7,0x06,0x0a,0x00,0x04,0x00,0x26,0xc6,0x06,0x19,0x00
+,0x00,0xe8,0x69,0x05,0xe8,0x2c,0x05,0x26,0xc7,0x06,0x26,0x00,0x00,0x22,0x26,0xc6
+,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x29,0xbf,0x2a,0x00,0x26,0xc6,0x05
+,0x08,0x26,0xc6,0x45,0x01,0x2d,0x8d,0x7d,0x02,0xbe,0x54,0x37,0xb9,0x03,0x00,0xf3
+,0xa5,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x2e,0x8d,0x7d,0x02,0xbe,0x5a,0x37
+,0xb9,0x03,0x00,0xf3,0xa5,0xe8,0xd4,0x05,0xe8,0x64,0x05,0xb9,0x06,0x00,0xbe,0x54
+,0x37,0x8d,0x2e,0x2c,0x00,0x26,0x8b,0x46,0x00,0x29,0x04,0x83,0xc6,0x02,0x83,0xc5
+,0x02,0x83,0xf9,0x04,0x75,0x02,0x45,0x45,0xe2,0xeb,0xc3,0x26,0xc7,0x06,0x04,0x00
+,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x24,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00
+,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0xe4,0x04,0xe8,0xa7,0x04,0x26,0xc7,0x06,0x26
+,0x00,0x00,0x16,0x26,0xc6,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x28,0xbf
+,0x2a,0x00,0xe8,0x5b,0x06,0xe8,0x74,0x05,0xe8,0x04,0x05,0xc3,0x26,0xc7,0x06,0x04
+,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x1a,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
+,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0xa3,0x04,0xe8,0x66,0x04,0x26,0xc7,0x06
+,0x26,0x00,0x00,0x0c,0x26,0xc6,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x27
+,0xbf,0x2a,0x00,0xe8,0x21,0x05,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7
+,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x0a,0x00,0x26,0xc7,0x06,0x0a
+,0x00,0x04,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x4b,0x04,0xe8,0x24,0x04,0x26
+,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29
+,0x00,0x26,0xbf,0x2a,0x00,0xe8,0xf4,0x04,0xe8,0x84,0x04,0xc3,0x26,0xc7,0x06,0x04
+,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
+,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x0d,0x04,0xe8,0xe6,0x03,0x26,0xc7,0x06
+,0x26,0x00,0x00,0x26,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29,0x00,0x25
+,0xbf,0x2a,0x00,0xe8,0xb6,0x04,0xe8,0x46,0x04,0xe8,0xfa,0x04,0xc3,0x26,0xc7,0x06
+,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x38,0x00,0xa1,0xa2,0x37,0x50,0x0b
+,0xc0,0x75,0x07,0x26,0xc7,0x06,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
+,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x99,0x03,0xe8,0xa4,0xfd,0x26,0xc7,0x45
+,0x26,0x00,0x2a,0x58,0x0b,0xc0,0x75,0x06,0x26,0xc7,0x45,0x26,0x00,0x26,0xa1,0x1c
+,0x37,0xc1,0xe0,0x04,0x26,0x88,0x45,0x28,0x26,0xc6,0x45,0x29,0x24,0x83,0xc7,0x2a
+,0xe8,0x29,0x04,0xe8,0xa0,0x04,0xe8,0x22,0x05,0xe8,0xf8,0x03,0xe8,0x09,0x04,0xc3
+,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x32,0x00,0x26,0xc7
+,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x45,0x03,0xe8,0x50
+,0xfd,0x26,0xc7,0x45,0x26,0x00,0x24,0xa1,0x1c,0x37,0xc1,0xe0,0x04,0x26,0x88,0x45
+,0x28,0x26,0xc6,0x45,0x29,0x23,0x83,0xc7,0x2a,0xe8,0xe0,0x03,0xe8,0x6c,0x04,0xe8
+,0x8a,0x04,0xe8,0x9c,0x04,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06
+,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00
+,0x00,0xe8,0xff,0x02,0xe8,0x0a,0xfd,0x26,0xc7,0x45,0x26,0x00,0x26,0xa1,0x1c,0x37
+,0xc1,0xe0,0x04,0x26,0x88,0x45,0x28,0x26,0xc6,0x45,0x29,0x22,0x83,0xc7,0x2a,0xe8
+,0x9a,0x03,0xe8,0xc7,0x03,0xe8,0x57,0x03,0xe8,0xf8,0x03,0xe8,0x78,0x04,0xe8,0x8a
+,0x04,0xc3,0x26,0xc7,0x06,0x04,0x00,0x74,0x45,0x26,0xc7,0x06,0x0e,0x00,0x3e,0x00
+,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc7,0x06,0x0a,0x00,0x04,0x00,0x26,0xc6
+,0x06,0x19,0x00,0x00,0xe8,0xfc,0x02,0xe8,0xa9,0x02,0x83,0x3e,0x8d,0x37,0x03,0x75
+,0x01,0x90,0x26,0xc7,0x06,0x26,0x00,0x00,0x30,0x26,0xc6,0x06,0x28,0x00,0x50,0x26
+,0xc6,0x06,0x29,0x00,0x20,0xbf,0x2a,0x00,0xe8,0xd0,0x03,0xe8,0x01,0x03,0xe8,0xb5
+,0x03,0xe8,0x9f,0x03,0xc3,0x26,0xc7,0x06,0x04,0x00,0x61,0x43,0xb9,0xf0,0x00,0x83
+,0xe9,0x02,0x26,0x89,0x0e,0x0e,0x00,0x26,0xc7,0x06,0x06,0x00,0x02,0x00,0x26,0xc6
+,0x06,0x19,0x00,0x00,0x26,0xc7,0x06,0x1a,0x00,0x00,0x00,0x26,0xc7,0x06,0x1c,0x00
+,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x00,0xe8,0x47,0x02,0x83,0xe9,0x0e,0x86
+,0xcd,0x26,0x89,0x0e,0x26,0x00,0x86,0xcd,0x26,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6
+,0x06,0x29,0x00,0x08,0xbf,0x2a,0x00,0x83,0xe9,0x04,0x26,0x89,0x0d,0x26,0xc6,0x45
+,0x01,0x26,0x8d,0x7d,0x02,0x83,0xe9,0x02,0xbb,0x01,0x00,0xb8,0x30,0x30,0x4b,0x75
+,0x17,0xbb,0x0a,0x00,0x8a,0xc4,0x26,0x88,0x05,0xb0,0x31,0x80,0xc4,0x01,0x80,0xfc
+,0x3a,0x75,0x0a,0xb4,0x61,0xe9,0x05,0x00,0x26,0x88,0x05,0x04,0x01,0x47,0x49,0x75
+,0xdd,0xc3,0x26,0xc7,0x06,0x04,0x00,0x04,0x45,0x26,0xc7,0x06,0x0e,0x00,0x12,0x00
+,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x01,0xe8,0xe5,0x01
+,0xe8,0xd0,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x04,0x26,0xc6,0x06,0x28,0x00,0x00
+,0x26,0xc6,0x06,0x29,0x00,0x07,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7
+,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19
+,0x00,0x06,0xe8,0x04,0x02,0xe8,0x9b,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26
+,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x06,0xbf,0x2a,0x00,0xe8,0x6b
+,0x02,0xe8,0xfb,0x01,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e
+,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x05
+,0xe8,0xc6,0x01,0xe8,0x5d,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06
+,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x05,0xbf,0x2a,0x00,0xe8,0x2d,0x02,0xe8
+,0xbd,0x01,0xc3,0xff,0x06,0x82,0x34,0x26,0xc7,0x06,0x04,0x00,0x3d,0x41,0x26,0xc7
+,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x0e,0x00,0x26,0xc6,0x06,0x19
+,0x00,0x04,0xe8,0x84,0x01,0xe8,0x1b,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26
+,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x04,0xbf,0x2a,0x00,0xe8,0xeb
+,0x01,0xe8,0x7b,0x01,0xc3,0x26,0xc7,0x06,0x04,0x00,0x67,0x42,0x26,0xc7,0x06,0x0e
+,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x08,0x00,0x26,0xc6,0x06,0x19,0x00,0x03
+,0xe8,0x46,0x01,0xe8,0xdd,0x00,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06
+,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x03,0xbf,0x2a,0x00,0xe8,0xad,0x01,0xe8
+,0x3d,0x01,0xc3,0xff,0x06,0x84,0x34,0x26,0xc7,0x06,0x04,0x00,0x67,0x42,0x26,0xc7
+,0x06,0x0e,0x00,0x24,0x00,0x26,0xc7,0x06,0x06,0x00,0x08,0x00,0x26,0xc6,0x06,0x19
+,0x00,0x02,0xe8,0x04,0x01,0xe8,0x9b,0x00,0x26,0xc7,0x06,0x26,0x00,0x00,0x16,0x26
+,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x02,0xbf,0x2a,0x00,0x26,0xc6
+,0x05,0x04,0x26,0xc6,0x45,0x01,0x01,0xa1,0x0f,0x37,0x86,0xe0,0xf6,0x06,0x6f,0x37
+,0x01,0x75,0x0f,0x39,0x06,0xcc,0x34,0x74,0x09,0x8b,0xd8,0xb8,0x89,0x03,0xcd,0x39
+,0x8b,0xc3,0xa3,0xcc,0x34,0x26,0x89,0x45,0x02,0x8d,0x7d,0x04,0xe8,0x3d,0x01,0xe8
+,0xcd,0x00,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x1c
+,0x00,0xa1,0xa2,0x37,0x50,0x0b,0xc0,0x75,0x07,0x26,0xc7,0x06,0x0e,0x00,0x18,0x00
+,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x23,0x00
+,0xe8,0x2e,0xfa,0x26,0xc7,0x45,0x26,0x00,0x0e,0x58,0x0b,0xc0,0x75,0x06,0x26,0xc7
+,0x45,0x26,0x00,0x0a,0x26,0xc6,0x45,0x29,0x00,0x83,0xc7,0x2a,0xe8,0xbd,0x00,0xe8
+,0xff,0x00,0xc3,0x56,0x57,0x51,0xb9,0x03,0x00,0xbe,0xd1,0x36,0xbf,0x20,0x00,0xf3
+,0xa5,0x59,0x5f,0x5e,0xc3,0x56,0x57,0x51,0xb9,0x03,0x00,0xbe,0xd1,0x36,0xbf,0x1a
+,0x00,0xf3,0xa5,0x59,0x5f,0x5e,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00,0x26,0xc7
+,0x06,0x1c,0x00,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x10,0xc3,0x26,0xc7,0x06
+,0x1a,0x00,0xc0,0x00,0x26,0xc7,0x06,0x1c,0x00,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00
+,0x00,0x08,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00,0x26,0xc7,0x06,0x1c,0x00,0x00
+,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x02,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00
+,0x26,0xc7,0x06,0x1c,0x00,0xff,0xff,0x26,0xc7,0x06,0x1e,0x00,0xff,0xff,0xc3,0x26
+,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x02,0x8d,0x7d,0x02,0xbe,0x05,0x37,0xb9,0x03
+,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x06,0xa1,0x0d,0x37
+,0x26,0x89,0x45,0x02,0x8d,0x7d,0x04,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01
+,0x07,0xa1,0x0b,0x37,0x26,0x89,0x45,0x02,0x83,0xc7,0x04,0xc3,0xa1,0xa2,0x37,0x0b
+,0xc0,0x74,0x13,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x09,0xa1,0x03,0x37,0x26
+,0x89,0x45,0x02,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x02
+,0x8d,0x7d,0x02,0xbe,0x05,0x37,0xb9,0x03,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x06
+,0x26,0xc6,0x45,0x01,0x0b,0x8d,0x7d,0x02,0xbe,0xef,0x36,0xb9,0x02,0x00,0xf3,0xa5
+,0xc3,0x26,0xc6,0x05,0x06,0x26,0xc6,0x45,0x01,0x20,0xa1,0x68,0x37,0x26,0x89,0x45
+,0x02,0xa1,0x6a,0x37,0x26,0x88,0x65,0x05,0xc1,0xe0,0x04,0x26,0x88,0x45,0x04,0x83
+,0xc7,0x06,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x21,0x26,0xc7,0x45,0x02
+,0x00,0x00,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x14,0x26,0xc6,0x45,0x01,0x22,0x8d
+,0x7d,0x02,0xbe,0x1f,0x37,0xb9,0x09,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x0c,0x26
+,0xc6,0x45,0x01,0x23,0x8d,0x7d,0x02,0x1e,0x0e,0x1f,0x8d,0x36,0x40,0x54,0xb9,0x03
+,0x00,0xf3,0xa5,0x33,0xc0,0xb9,0x02,0x00,0xf3,0xab,0x1f,0xc3,0x26,0xc6,0x05,0x08
+,0x26,0xc6,0x45,0x01,0x28,0x8d,0x7d,0x02,0xbe,0xd1,0x36,0xb9,0x03,0x00,0xf3,0xa5
+,0xc3,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x29,0xa1,0xc2,0x34,0x86,0xe0,0x26
+,0x89,0x45,0x02,0xa1,0x9b,0x36,0x26,0x89,0x45,0x04,0x26,0x88,0x45,0x06,0x26,0x88
+,0x45,0x07,0x8d,0x7d,0x08,0xc3,0x26,0xc6,0x05,0x06,0x26,0xc6,0x45,0x01,0x2b,0x8d
+,0x7d,0x02,0xbe,0xbb,0x36,0xb9,0x02,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x06,0x26
+,0xc6,0x45,0x01,0x2c,0x8d,0x7d,0x02,0xbe,0xe5,0x36,0xb9,0x02,0x00,0xf3,0xa5,0xc3
+,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x30,0xa1,0x37,0x37,0x86,0xe0,0x26,0x89
+,0x45,0x02,0x8d,0x7d,0x04,0xc3,0x26,0xc7,0x06,0x0e,0x00,0x1e,0x00,0x26,0xc7,0x06
+,0x06,0x00,0x02,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x6c,0xfe,0xe8,0x03,0xfe
+,0x26,0xc7,0x06,0x26,0x00,0x00,0x10,0x26,0xc6,0x06,0x28,0x00,0x30,0x26,0xc6,0x06
+,0x29,0x00,0x11,0xbf,0x2a,0x00,0xe8,0x35,0x00,0xe8,0x45,0x00,0xe8,0x55,0x00,0xc3
+,0x26,0xc7,0x06,0x0e,0x00,0x12,0x00,0x26,0xc7,0x06,0x06,0x00,0x02,0x00,0x26,0xc6
+,0x06,0x19,0x00,0x00,0xe8,0x32,0xfe,0xe8,0xc9,0xfd,0x26,0xc7,0x06,0x26,0x00,0x00
+,0x04,0x26,0xc6,0x06,0x28,0x00,0x30,0x26,0xc6,0x06,0x29,0x00,0x13,0xc3,0x26,0xc6
+,0x05,0x04,0x26,0xc6,0x45,0x01,0x0c,0x26,0xc7,0x45,0x02,0x00,0x01,0x83,0xc7,0x04
+,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x0e,0x26,0xc7,0x45,0x02,0x00,0x02
+,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x21,0x26,0xc7,0x45
+,0x02,0x00,0x00,0x83,0xc7,0x04,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xb3,0x39,0xc9,0x39,0x83,0x3a,0xb3,0x39,0xb3,0x39,0xb3,0x39,0x1c,0x3a,0x1c,0x3a
+,0xa3,0xb6,0x34,0xa1,0xe9,0x36,0xa3,0x11,0x37,0xa3,0xd2,0x34,0xa1,0xeb,0x36,0xa3
+,0x13,0x37,0xa3,0xd4,0x34,0xa1,0xed,0x36,0xa3,0x15,0x37,0xa3,0xd6,0x34,0xa1,0x01
+,0x37,0xa3,0xce,0x34,0xa1,0xf7,0x36,0xa3,0x17,0x37,0xa3,0xdc,0x34,0xa1,0xf9,0x36
+,0xa3,0x19,0x37,0xa3,0xde,0x34,0xf7,0x06,0x9b,0x36,0x02,0x00,0x75,0x0c,0x33,0xc0
+,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0x50,0x39,0xe9,0x0f,0x01,0xbe,0x07,0x00
+,0xe9,0x19,0xf1,0xf6,0x06,0x9d,0x36,0x80,0x74,0xf3,0xc6,0x06,0xa0,0x36,0x02,0xc6
+,0x06,0x6e,0x37,0x08,0xc6,0x06,0x70,0x37,0x02,0xb8,0x88,0x03,0xcd,0x39,0xf6,0x06
+,0x6f,0x37,0x01,0x75,0x4a,0xa1,0xd1,0x36,0x3a,0x06,0xe9,0x36,0x75,0x41,0x3a,0x26
+,0xea,0x36,0x75,0x3b,0xa1,0xd3,0x36,0x3a,0x06,0xeb,0x36,0x75,0x32,0x3a,0x26,0xec
+,0x36,0x75,0x2c,0xa1,0xd5,0x36,0x3a,0x06,0xed,0x36,0x75,0x23,0x3a,0x26,0xee,0x36
+,0x75,0x1d,0xc6,0x06,0x70,0x37,0x02,0xfe,0x0e,0x6e,0x37,0x75,0x0f,0xb8,0x88,0x03
+,0xcd,0x3a,0x83,0x0e,0x9b,0x36,0x12,0xc6,0x06,0xa0,0x36,0x0c,0xe9,0xa8,0xf0,0xa1
+,0x05,0x37,0x26,0x3b,0x06,0x20,0x00,0x75,0x40,0xa1,0x07,0x37,0x26,0x3b,0x06,0x22
+,0x00,0x75,0x36,0xa1,0x09,0x37,0x26,0x3b,0x06,0x24,0x00,0x75,0x2c,0xa0,0x9e,0x36
+,0x3c,0x02,0x75,0x08,0x26,0xf6,0x06,0x18,0x00,0x08,0x75,0x47,0xc6,0x06,0x6e,0x37
+,0x08,0xfe,0x0e,0x70,0x37,0x75,0x1c,0xc6,0x06,0x70,0x37,0x02,0xe5,0x02,0x0d,0x01
+,0x04,0x25,0xef,0xff,0xe7,0x02,0xe9,0x5e,0xf0,0xc6,0x06,0x70,0x37,0x02,0xc6,0x06
+,0x6e,0x37,0x08,0xe5,0x02,0x25,0xff,0xfb,0x0d,0x01,0x00,0x25,0xef,0xff,0xe7,0x02
+,0xe9,0x44,0xf0,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x25,0x26,0xf6,0x06,0x18,0x00
+,0x08,0x75,0xed,0x81,0x26,0x9b,0x36,0x7f,0xff,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x84
+,0x03,0xcd,0x3a,0xc6,0x06,0xa0,0x36,0x06,0x83,0x26,0xc2,0x34,0xaf,0xe9,0x17,0xf0
+,0xa1,0x01,0x37,0x3a,0x26,0x0f,0x37,0x7f,0xc7,0xe9,0xf7,0xfe,0x83,0x26,0x9b,0x36
+,0xec,0xe8,0x2a,0x0d,0x81,0x0e,0x9b,0x36,0x80,0x00,0xbb,0xff,0x7f,0xcd,0x53,0xc6
+,0x06,0xa0,0x36,0x02,0xe9,0xf0,0xef,0x83,0x0e,0x9b,0x36,0x11,0xc6,0x06,0xa0,0x36
+,0x0c,0xe9,0xf9,0xef,0x44,0x3b,0x2c,0x3b,0xc7,0x2a,0x6b,0x3b,0x44,0x3b,0xc7,0x2a
+,0xc7,0x2a,0xc7,0x2a,0xa3,0xb6,0x34,0x81,0x0e,0xc2,0x34,0x00,0x20,0xf7,0x06,0x41
+,0x37,0x01,0x00,0x74,0x1b,0x8c,0xc3,0xc7,0x06,0x41,0x37,0x00,0x00,0xb8,0x7f,0x03
+,0xcd,0x3a,0x33,0xc0,0x8e,0xc0,0xbf,0x54,0x37,0xb9,0x06,0x00,0xf3,0xab,0x8e,0xc3
+,0x33,0xc0,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0xe4,0x3a,0xf7,0x06,0x9b,0x36
+,0x00,0x01,0x75,0x21,0x83,0x26,0xc2,0x34,0xbf,0xa1,0xa9,0x36,0xe7,0x00,0xa1,0x9b
+,0x36,0xe9,0x09,0x00,0xa1,0x9b,0x36,0x81,0x26,0x9b,0x36,0xff,0xdf,0xa9,0x00,0x20
+,0x75,0x06,0xe9,0x6e,0x00,0xe9,0x6f,0xef,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37
+,0x37,0x01,0x00,0xc6,0x06,0xca,0x34,0x01,0xe9,0x58,0x00,0x83,0x0e,0x9b,0x36,0x40
+,0xe8,0x58,0x00,0xa1,0x05,0x37,0x3b,0x06,0xe9,0x36,0x75,0x37,0xa1,0x07,0x37,0x3b
+,0x06,0xeb,0x36,0x75,0x2e,0xa1,0x09,0x37,0x3b,0x06,0xed,0x36,0x75,0x25,0xfe,0x0e
+,0x71,0x37,0x75,0x1c,0xb8,0x87,0x03,0xcd,0x3a,0x83,0x0e,0x99,0x36,0x10,0xa1,0x50
+,0x37,0xc7,0x06,0x50,0x37,0x00,0x00,0x09,0x06,0x99,0x36,0xc6,0x06,0xa0,0x36,0x08
+,0xe9,0x14,0xef,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37,0x37,0x03,0x00,0xc6,0x06
+,0xca,0x34,0x03,0xc6,0x06,0xa0,0x36,0x0a,0xe9,0xfc,0xee,0xa1,0xd1,0x36,0x26,0x3b
+,0x06,0x20,0x00,0x75,0x15,0xa1,0xd3,0x36,0x26,0x3b,0x06,0x22,0x00,0x75,0x12,0xa1
+,0xd5,0x36,0x26,0x3b,0x06,0x24,0x00,0x75,0x0f,0xc3,0x8d,0x36,0x20,0x00,0xe9,0x0b
+,0x00,0x8d,0x36,0x22,0x00,0xe9,0x04,0x00,0x8d,0x36,0x24,0x00,0x83,0xc4,0x02,0xf7
+,0x06,0xe6,0x34,0x01,0x00,0x74,0x15,0x26,0x3a,0x04,0x77,0x08,0x72,0x0e,0x26,0x3a
+,0x64,0x01,0x72,0x08,0xc6,0x06,0xa0,0x36,0x06,0xe9,0xab,0xee,0xe8,0x7c,0x0a,0x8c
+,0xc0,0x3d,0xff,0xff,0x74,0x1b,0x26,0xc6,0x06,0x18,0x00,0x10,0x26,0xc7,0x06,0x04
+,0x00,0x49,0x3c,0x26,0xc7,0x06,0x06,0x00,0x0c,0x00,0xcd,0x50,0xb9,0x4e,0x00,0xe2
+,0xfe,0xc6,0x06,0xa0,0x36,0x0a,0xe9,0x94,0xee,0xe9,0x7b,0xee,0x8f,0x3c,0x06,0x3d
+,0x06,0x3d,0x06,0x3d,0xd2,0x3c,0xea,0x3c,0x06,0x3d,0x06,0x3d,0xa3,0xb6,0x34,0x81
+,0x26,0xc2,0x34,0xaf,0xdf,0xc7,0x06,0x4c,0x37,0x00,0x00,0xb8,0x8a,0x03,0xcd,0x3a
+,0x80,0x3e,0x9d,0x36,0x04,0x75,0x0c,0x80,0x3e,0x9e,0x36,0x06,0x74,0x05,0xc6,0x06
+,0x9f,0x36,0x06,0x33,0xc0,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0x4c,0x3c,0xf7
+,0x06,0x9b,0x36,0x00,0x20,0x75,0x0e,0x81,0x26,0x9b,0x36,0xff,0xbf,0xb8,0x8b,0x03
+,0xcd,0x3a,0xe9,0x54,0x00,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x03,0xe9,0x17,0xee
+,0xc7,0x06,0x37,0x37,0x02,0x00,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04
+,0x83,0x0e,0x50,0x37,0x04,0xf6,0x06,0x9d,0x36,0x80,0x75,0x2a,0xe8,0x1f,0x0b,0xe9
+,0x27,0x00,0xf7,0x06,0x9b,0x36,0x00,0x01,0x75,0xd3,0xc7,0x06,0x37,0x37,0x02,0x00
+,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04,0xc6,0x06,0xa0,0x36,0x00,0xf6
+,0x06,0x9d,0x36,0x80,0x74,0x03,0xe8,0xde,0x0a,0x81,0x26,0x9b,0x36,0x7c,0xff,0xbb
+,0xff,0xff,0xcd,0x53,0xcd,0x54,0xe9,0xbe,0xed,0xa3,0xb6,0x34,0xe8,0xad,0x01,0xb8
+,0x86,0x03,0xcd,0x39,0xc7,0x06,0x4c,0x37,0x00,0x00,0x81,0x26,0xc2,0x34,0xaf,0xdf
+,0xf6,0x06,0x9d,0x36,0x80,0x74,0x34,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x56,0xf7
+,0x06,0x9b,0x36,0x00,0x01,0x74,0x27,0xe8,0x35,0x01,0x72,0x1c,0xbe,0x00,0x40,0x85
+,0x36,0xc2,0x34,0x75,0x08,0x09,0x36,0xc2,0x34,0xff,0x06,0x92,0x34,0xe8,0x8b,0x01
+,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00,0xe9,0x6c,0xed,0xe9,0xb5,0x00,0xc7,0x06
+,0x37,0x37,0x02,0x00,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04,0x83,0x0e
+,0x50,0x37,0x04,0x80,0x3e,0x9e,0x36,0x08,0x74,0x03,0xe8,0x5a,0x0a,0xe8,0xef,0x00
+,0x72,0xd6,0xe9,0xc8,0xff,0x80,0x3e,0x9e,0x36,0x0a,0x75,0x12,0xc6,0x06,0xa0,0x36
+,0x00,0xf7,0x06,0x9b,0x36,0x08,0x00,0x74,0x02,0xcd,0x54,0xe8,0x39,0x0a,0x81,0x26
+,0x9b,0x36,0xff,0xbf,0xe8,0xc8,0x00,0x72,0xaf,0xb8,0x8b,0x03,0xcd,0x39,0xe9,0x9c
+,0xff,0xf6,0x06,0x9e,0x36,0xff,0x75,0x58,0xa3,0xb6,0x34,0xe8,0xfe,0x00,0x81,0x26
+,0xc2,0x34,0xff,0xbf,0xf6,0x06,0x9d,0x36,0x80,0x74,0x48,0xf7,0x06,0x9b,0x36,0x00
+,0x20,0x74,0x22,0xf7,0x06,0x9b,0x36,0x00,0x40,0x75,0x08,0xe8,0x91,0x00,0x72,0x30
+,0xe9,0x22,0x00,0x26,0xa1,0x0c,0x00,0xa9,0x60,0x00,0x75,0x24,0x81,0x0e,0x66,0x37
+,0x00,0x08,0xe9,0xd2,0xec,0xc7,0x06,0x4c,0x37,0x00,0x00,0xe8,0x71,0x00,0x72,0x10
+,0xb8,0x8b,0x03,0xcd,0x39,0xe8,0xd3,0x00,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00
+,0xe9,0xb4,0xec,0x80,0x3e,0x9d,0x36,0x04,0x75,0x0c,0x80,0x3e,0x9e,0x36,0x06,0x74
+,0x46,0xc6,0x06,0x9f,0x36,0x06,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x0c,0x80,0x3e
+,0x9d,0x36,0x08,0x75,0x05,0xc6,0x06,0x9f,0x36,0x0a,0xe8,0x32,0x00,0x72,0xd1,0xe8
+,0x99,0x00,0x80,0x3e,0x9d,0x36,0x08,0x75,0x13,0x81,0x0e,0x99,0x36,0x80,0x00,0xf7
+,0x06,0x9b,0x36,0x00,0x20,0x75,0x08,0xb8,0x8b,0x03,0xcd,0x39,0xe9,0x68,0xec,0xc6
+,0x06,0x9f,0x36,0x0a,0xe9,0x60,0xec,0xb8,0x86,0x03,0xcd,0x3a,0xe9,0x58,0xec,0x26
+,0xa1,0x0c,0x00,0xa9,0x60,0x00,0x74,0x08,0x81,0x26,0xc2,0x34,0xff,0xbf,0xf9,0xc3
+,0xf7,0x06,0x9b,0x36,0x00,0x40,0x74,0x13,0x81,0x0e,0x66,0x37,0x00,0x08,0xe8,0x4a
+,0x00,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00,0xf9,0xc3,0x81,0x0e,0x9b,0x36,0x00
+,0x40,0x80,0x26,0x6f,0x37,0xfe,0x81,0x26,0x9b,0x36,0x7f,0xff,0xc6,0x06,0xa0,0x36
+,0x00,0xf8,0xc3,0x81,0x0e,0x99,0x36,0x00,0x01,0xe9,0x21,0xec,0x26,0xa1,0x20,0x00
+,0xa3,0xfb,0x36,0xa3,0xaa,0x34,0x26,0xa1,0x22,0x00,0xa3,0xfd,0x36,0xa3,0xac,0x34
+,0x26,0xa1,0x24,0x00,0xa3,0xff,0x36,0xa3,0xae,0x34,0xc3,0xa1,0x05,0x37,0x26,0x3b
+,0x06,0x20,0x00,0x75,0x19,0xa1,0x07,0x37,0x26,0x3b,0x06,0x22,0x00,0x75,0x0f,0xa1
+,0x09,0x37,0x26,0x3b,0x06,0x24,0x00,0x75,0x05,0xe8,0x02,0x00,0xf8,0xc3,0x51,0x1e
+,0x06,0x8b,0xc7,0x8d,0x36,0x20,0x00,0xbf,0x05,0x37,0xb9,0x03,0x00,0x1e,0x06,0x1f
+,0x07,0xf3,0xa5,0x8b,0xf8,0x8d,0x36,0x20,0x00,0xbf,0xa0,0x34,0xb9,0x03,0x00,0xf3
+,0xa5,0x07,0x1f,0x59,0x8b,0xf8,0xa1,0x07,0x37,0xa3,0xa6,0x34,0xa1,0x09,0x37,0xa3
+,0xa8,0x34,0xf9,0xc3,0xc6,0x06,0xb6,0x34,0x01,0xe9,0x8b,0xeb,0xe8,0x87,0x08,0x8b
+,0xf0,0x05,0x12,0x00,0x26,0x29,0x06,0x0e,0x00,0x26,0x8b,0x44,0x2a,0x26,0x3a,0x06
+,0x0e,0x00,0x75,0x5b,0x26,0x83,0x2e,0x0e,0x00,0x02,0x80,0xfc,0x27,0x75,0x50,0x26
+,0x8b,0x44,0x2c,0xa9,0xff,0xff,0x75,0x47,0x8b,0xfe,0x33,0xc0,0x26,0xf6,0x45,0x3c
+,0x80,0x74,0x06,0x26,0x8a,0x45,0x3a,0x24,0x1f,0x03,0xf8,0x26,0x80,0x7d,0x45,0x09
+,0x75,0x2d,0x8c,0xc2,0x8e,0x06,0x38,0x34,0x8e,0xda,0x8b,0x0e,0x0e,0x00,0x26,0x89
+,0x0e,0x0e,0x00,0x8d,0x74,0x2c,0xbf,0x18,0x00,0xf3,0xa4,0x33,0xc0,0x8e,0xd8,0x26
+,0xc7,0x06,0x04,0x00,0xb5,0x3f,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0xcd,0x50,0xb8
+,0x06,0x80,0xe9,0xef,0xe9,0x26,0xa1,0x0c,0x00,0xa3,0x93,0x37,0x83,0x0e,0x99,0x36
+,0x01,0xe9,0x00,0xeb,0x26,0x80,0x3e,0x1c,0x00,0xff,0x75,0x2f,0x26,0x80,0x3e,0x1e
+,0x00,0xff,0x75,0x27,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00,0x75,0x1b,0xa1,0xd1,0x36
+,0x26,0xa3,0x1a,0x00,0xa1,0xd3,0x36,0x26,0xa3,0x1c,0x00,0xa1,0xd5,0x36,0x26,0xa3
+,0x1e,0x00,0xb8,0x0a,0x80,0xe8,0x36,0x07,0xe9,0xe2,0xea,0xff,0x06,0x90,0x34,0xbe
+,0x0a,0x00,0xc6,0x06,0xb6,0x34,0x01,0xf6,0x06,0x9d,0x36,0x80,0x75,0x05,0x83,0x0e
+,0xc2,0x34,0x01,0xe9,0xb6,0xea,0x80,0x3e,0x9d,0x36,0x0a,0x75,0x0f,0x26,0xa1,0x0c
+,0x00,0x25,0x07,0x00,0x3d,0x04,0x00,0x75,0x03,0xe8,0x79,0x00,0xa1,0xf3,0x36,0x86
+,0xe0,0xe7,0x1e,0xa3,0xe3,0x36,0x81,0x26,0x0b,0x37,0x00,0x03,0x81,0x26,0x0d,0x37
+,0x7b,0x7f,0x83,0x0e,0x0d,0x37,0x48,0xe8,0x1e,0x00,0x26,0xa1,0x0c,0x00,0x25,0x07
+,0x00,0x3d,0x04,0x00,0x74,0x09,0x26,0xf7,0x06,0x0c,0x00,0x20,0x00,0x75,0x06,0xb8
+,0x01,0x00,0xe9,0x3f,0xe9,0xe9,0x5f,0xea,0xc7,0x06,0x41,0x37,0x00,0x00,0xb8,0x7f
+,0x03,0xcd,0x3a,0xa1,0x1d,0x37,0xa3,0xc4,0x34,0x86,0xe0,0x68,0x7f,0x03,0x1f,0xa3
+,0x06,0x00,0x33,0xc0,0x8e,0xd8,0xa1,0x0b,0x37,0xa3,0xb2,0x34,0xa1,0x0d,0x37,0xa3
+,0xb4,0x34,0xa1,0xf3,0x36,0xa3,0xc8,0x34,0xa1,0xef,0x36,0xa3,0x9c,0x34,0xa1,0xf1
+,0x36,0xa3,0x9e,0x34,0xc3,0x80,0x0e,0x9d,0x36,0x80,0xbe,0x00,0x00,0xe8,0xb4,0x07
+,0xb8,0x7b,0x03,0xcd,0x3a,0xb8,0x7c,0x03,0xcd,0x39,0xc7,0x06,0x33,0x37,0x02,0x00
+,0xa1,0xe5,0x36,0xe7,0x2e,0xa1,0xe7,0x36,0xe7,0x3e,0xb8,0x82,0x03,0xcd,0x3a,0xf7
+,0x06,0x9b,0x36,0x00,0x20,0x75,0x03,0xe8,0xfd,0x06,0xa1,0xd3,0x36,0xa3,0xef,0x36
+,0xa3,0x9c,0x34,0xa1,0xd5,0x36,0xa3,0xf1,0x36,0xa3,0x9e,0x34,0xc3,0xf6,0x06,0x9d
+,0x36,0x80,0x74,0x31,0xbe,0x22,0x00,0xe9,0x17,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74
+,0x24,0xbe,0x23,0x00,0xe9,0x0a,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74,0x17,0xbe,0x24
+,0x00,0x56,0xe8,0xa8,0x05,0x8c,0xc0,0x3d,0xff,0xff,0x5e,0x74,0x05,0xe8,0xd7,0xef
+,0xcd,0x50,0xe9,0x1f,0xe8,0xe9,0x9f,0xe9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xb8,0x84,0x03,0xcd,0x3a,0xb8,0x8a,0x03,0xcd,0x39,0xe9,0xf7,0x00,0x80,0x3e,0xa0
+,0x36,0x08,0x75,0x2e,0xa9,0xd0,0x07,0x75,0x2c,0xa1,0xb1,0x36,0x0d,0x00,0x04,0xe7
+,0x08,0xe5,0x00,0x25,0xff,0x73,0xe7,0x00,0xb8,0x8a,0x03,0xcd,0x3a,0xe8,0xc3,0x06
+,0x33,0xc0,0xe7,0x0e,0xe5,0x0a,0x25,0xc3,0x17,0xe7,0x0a,0xcd,0x54,0xc6,0x06,0xa0
+,0x36,0x00,0xe9,0x68,0xe9,0xbe,0x04,0x00,0xe9,0x3f,0xe9,0x83,0x26,0x9b,0x36,0xbf
+,0xc6,0x06,0x71,0x37,0x03,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x88,0x03,0xcd,0x3a,0xb8
+,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x39,0x81,0x0e,0xc2,0x34,0x00,0x20,0xe9
+,0x92,0x00,0xe8,0x49,0x06,0xb8,0x87,0x03,0xcd,0x39,0xbb,0xff,0x7f,0xcd,0x53,0xb8
+,0x84,0x03,0xcd,0x3a,0xb8,0x88,0x03,0xcd,0x3a,0xb8,0x8b,0x03,0xcd,0x3a,0xb8,0x83
+,0x03,0xcd,0x3a,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd,0x3a,0xc3,0xe5,0x00
+,0x25,0xff,0x53,0xe7,0x00,0x83,0x0e,0xc2,0x34,0x40,0x83,0x26,0xc2,0x34,0xef,0xe8
+,0x0c,0x06,0xbb,0xff,0x7f,0xcd,0x53,0xb8,0x8a,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd
+,0x3a,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x3a
+,0xb8,0x8b,0x03,0xcd,0x3a,0xb8,0x84,0x03,0xcd,0x3a,0xb8,0x89,0x03,0xcd,0x3a,0xc3
+,0x83,0x0e,0xc2,0x34,0x50,0xe8,0x18,0x04,0xe8,0xd3,0x05,0xf6,0x06,0x6f,0x37,0x01
+,0x75,0x12,0xb8,0x89,0x03,0xcd,0x39,0x83,0x3e,0x0f,0x37,0x00,0x75,0x06,0xc7,0x06
+,0x0f,0x37,0x04,0x00,0xa1,0x9d,0x36,0x80,0xfc,0x08,0x74,0x05,0xb8,0x84,0x03,0xcd
+,0x39,0xe5,0x02,0x0d,0x01,0x08,0x25,0xef,0xff,0xe7,0x02,0xa1,0x9d,0x36,0x86,0xe0
+,0x32,0xe4,0x8b,0xf0,0xd1,0xee,0x33,0xc0,0x0d,0x20,0x00,0x09,0x06,0xad,0x36,0xa1
+,0xad,0x36,0xe7,0x04,0xe9,0x53,0xe8,0xe9,0x5a,0xe8,0x33,0xc0,0xa0,0x1b,0x37,0xd1
+,0xe0,0x3a,0x06,0xa0,0x36,0x75,0x03,0xe9,0xba,0xff,0xe9,0x60,0xe8,0xc7,0x06,0x41
+,0x37,0x00,0x00,0xe8,0xc1,0xe1,0xe8,0x6a,0x06,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56
+,0xa1,0xb1,0x36,0x0d,0x00,0x10,0xe7,0x08,0xe5,0x02,0x25,0xf9,0xff,0x0d,0x03,0x00
+,0xe7,0x02,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xa1,0xad,0x36,0xe7
+,0x04,0xe8,0x7c,0x03,0xe8,0x9f,0x03,0xc7,0x06,0x1d,0x37,0x00,0xc8,0xc7,0x06,0x0b
+,0x37,0x00,0x03,0xc7,0x06,0x0d,0x37,0x7b,0x7f,0x33,0xc0,0xa3,0x99,0x36,0xa3,0x9b
+,0x36,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xa3,0x4c,0x37,0xa3,0xf3,0x36,0xa3,0xef,0x36
+,0xa3,0xf1,0x36,0xe8,0x82,0xfd,0xc6,0x06,0x9f,0x36,0x02,0xe9,0xef,0xe7,0xe5,0x02
+,0x0d,0x01,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02,0xe8,0xf2
+,0x05,0xe5,0x0a,0x0d,0x40,0x00,0xe7,0x0a,0x33,0xc0,0xa3,0x81,0x37,0xa3,0x85,0x37
+,0xa3,0x83,0x37,0xa3,0x87,0x37,0xa3,0x89,0x37,0xe5,0x00,0x0d,0x00,0x84,0xe7,0x00
+,0xb8,0x8c,0x03,0xcd,0x39,0xb8,0x80,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff
+,0xe5,0x00,0x25,0xff,0x7b,0xe7,0x00,0x81,0x0e,0x9a,0x37,0x80,0x00,0xb8,0x7e,0x03
+,0xcd,0x39,0x33,0xc0,0xe7,0x0e,0xbe,0x08,0x00,0x8e,0x06,0x38,0x34,0xe8,0xa7,0xed
+,0x83,0x26,0xef,0x34,0xdf,0xff,0x06,0x81,0x37,0xcd,0x50,0x83,0x0e,0xef,0x34,0x20
+,0xc3,0xf7,0x06,0x9a,0x37,0x80,0x00,0x74,0x3d,0xa9,0xd0,0x07,0x74,0x10,0xa9,0x00
+,0x04,0x74,0x12,0x33,0xc0,0xe7,0x0e,0xff,0x06,0x87,0x37,0xe9,0xd2,0xff,0xff,0x06
+,0x85,0x37,0xe9,0xcb,0xff,0xff,0x06,0x83,0x37,0xe9,0xc4,0xff,0x83,0x26,0x9a,0x37
+,0x7f,0xa1,0x89,0x37,0x03,0x06,0x87,0x37,0x3d,0x05,0x00,0x7f,0x01,0xc3,0xbb,0xff
+,0x7f,0xcd,0x53,0xe9,0x00,0x00,0xe5,0x02,0x25,0xff,0xfb,0x25,0xef,0xff,0x0d,0x01
+,0x00,0xe7,0x02,0xa1,0x83,0x37,0x3b,0x06,0x46,0x37,0x7f,0x2a,0xa1,0x85,0x37,0x3b
+,0x06,0x48,0x37,0x7c,0x21,0xa1,0x89,0x37,0x03,0x06,0x87,0x37,0x3d,0x05,0x00,0x7f
+,0x15,0xc6,0x06,0x9f,0x36,0x04,0xe5,0x02,0x25,0xff,0xf7,0x0d,0x01,0x00,0x25,0xef
+,0xff,0xe7,0x02,0xe9,0xf7,0xe6,0xbe,0x01,0x00,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74
+,0x0a,0x83,0x26,0x9b,0x36,0xfc,0x83,0x0e,0xc2,0x34,0x04,0xe9,0xd0,0xe6,0xb8,0x7b
+,0x03,0xcd,0x39,0xe5,0x02,0x0d,0x01,0x60,0x25,0xef,0xff,0xe7,0x02,0xc7,0x06,0xf1
+,0x34,0x20,0x03,0xb8,0x8e,0x03,0xcd,0x39,0xc3,0x81,0x26,0xc2,0x34,0x7f,0xff,0x80
+,0x0e,0x6f,0x37,0x01,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74,0xd2,0xb8,0x7b,0x03,0xcd
+,0x3a,0xb8,0x7d,0x03,0xcd,0x39,0x83,0x26,0x9b,0x36,0xef,0x33,0xc0,0xb0,0x8a,0xa2
+,0x9f,0x36,0xa2,0x9d,0x36,0xc7,0x06,0x4c,0x37,0x01,0x00,0xc7,0x06,0x0f,0x37,0x04
+,0x00,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06,0x0f,0x37,0x03,0x00,0xb8
+,0x8d,0x03,0xcd,0x39,0xe8,0x00,0xd5,0xe5,0x02,0x0d,0x01,0x40,0x25,0xef,0xff,0x8b
+,0xd8,0xb8,0x7c,0x03,0xcd,0x39,0xc7,0x06,0x33,0x37,0x02,0x00,0x8b,0xc3,0x0d,0x00
+,0x20,0x25,0xf9,0xff,0x0b,0x06,0xe8,0x3a,0xe7,0x02,0xc3,0xff,0x0e,0xf1,0x34,0x75
+,0x01,0xc3,0xe5,0x4e,0xa9,0x01,0x00,0x75,0x12,0xe5,0x00,0xa9,0x00,0x04,0x75,0x05
+,0x0d,0x00,0x04,0xe7,0x00,0xb8,0x8e,0x03,0xcd,0x39,0xc3,0xe5,0x00,0xa9,0x00,0x04
+,0x74,0xf3,0x25,0xff,0xfb,0xe7,0x00,0xe9,0xeb,0xff,0xc6,0x06,0xa0,0x36,0x04,0x83
+,0x26,0x9b,0x36,0xfc,0x81,0x0e,0x9b,0x36,0x80,0x00,0xe9,0x10,0xe6,0xb8,0x8e,0x03
+,0xcd,0x3a,0xcd,0x54,0x81,0x0e,0xaf,0x36,0x00,0x18,0xa1,0xaf,0x36,0xe7,0x06,0xb8
+,0x7b,0x03,0xcd,0x39,0xa1,0xd3,0x36,0xa3,0x8f,0x37,0xa1,0xd5,0x36,0xa3,0x91,0x37
+,0xc7,0x06,0x8b,0x37,0x02,0x00,0xc7,0x06,0x8d,0x37,0x02,0x00,0x83,0x0e,0x99,0x36
+,0x40,0xe9,0xd9,0xe5,0x80,0x3e,0x9f,0x36,0x06,0x75,0x15,0xa9,0xd0,0x07,0x75,0xec
+,0x25,0x00,0x18,0x75,0x0e,0xff,0x0e,0x8b,0x37,0x75,0xe1,0xc6,0x06,0x9f,0x36,0x08
+,0xe9,0xba,0xe5,0xff,0x0e,0x8d,0x37,0x75,0xd3,0xbe,0x08,0x00,0xe9,0x9f,0xe5,0xb8
+,0x7b,0x03,0xcd,0x39,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x08,0xc6,0x06,0x9f,0x36
+,0x0a,0xe9,0x0d,0x00,0xf7,0x06,0x9b,0x36,0x00,0x40,0x74,0x0b,0xb8,0x8b,0x03,0xcd
+,0x39,0x81,0x0e,0x99,0x36,0x80,0x00,0xe9,0x83,0xe5,0xb8,0x7b,0x03,0xcd,0x39,0xc7
+,0x06,0x8b,0x37,0x04,0x00,0xc7,0x06,0x8d,0x37,0x04,0x00,0x81,0x0e,0x99,0x36,0x00
+,0x02,0xe9,0x69,0xe5,0xf6,0x06,0x9d,0x36,0x80,0x75,0x1b,0xa9,0xd0,0x07,0x75,0xeb
+,0xa9,0x00,0x18,0x75,0x0c,0xff,0x0e,0x8d,0x37,0x75,0xe0,0xe8,0x17,0xfb,0xe9,0x4c
+,0xe5,0xb8,0x82,0x03,0xcd,0x39,0xc3,0xff,0x0e,0x8b,0x37,0x75,0xce,0xbe,0x09,0x00
+,0xe9,0x2b,0xe5,0xc7,0x06,0x3d,0x37,0x00,0x00,0xc7,0x06,0x9b,0x36,0x00,0x00,0xe8
+,0x3c,0x02,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0x81,0x26,0x9b
+,0x36,0xff,0x7f,0xe5,0x02,0x0d,0x01,0x00,0x25,0xef,0xff,0x25,0xff,0xdf,0xe7,0x02
+,0xbb,0xff,0x7f,0xcd,0x53,0x33,0xc0,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xe8,0x50,0x00
+,0xe8,0x73,0x00,0xb8,0x81,0x03,0xcd,0x39,0xc3,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74
+,0x0d,0xc6,0x06,0x9f,0x36,0x02,0xc6,0x06,0xa0,0x36,0x00,0xe9,0xdf,0xe4,0x83,0x0e
+,0x9b,0x36,0x10,0xc7,0x06,0x99,0x36,0x00,0x00,0xe8,0xe7,0x02,0xe5,0x56,0x0d,0x02
+,0x00,0xe7,0x56,0xc7,0x06,0xa8,0x02,0x00,0x00,0x8b,0x36,0x3d,0x37,0xe8,0x44,0x02
+,0xc6,0x06,0xa0,0x36,0x0e,0xe9,0xb5,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x06,0xb8,0x8a,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd,0x3a,0xb8,0x86,0x03,0xcd,0x3a
+,0xb8,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x3a,0xb8,0x8b,0x03,0xcd,0x3a,0xb8
+,0x88,0x03,0xcd,0x3a,0x07,0xc3,0x06,0xb8,0x88,0x03,0xcd,0x3a,0xb8,0x7b,0x03,0xcd
+,0x3a,0xb8,0x82,0x03,0xcd,0x3a,0xb8,0x7f,0x03,0xcd,0x3a,0xb8,0x7c,0x03,0xcd,0x3a
+,0xb8,0x7e,0x03,0xcd,0x3a,0xb8,0x80,0x03,0xcd,0x3a,0xb8,0x81,0x03,0xcd,0x3a,0xb8
+,0x84,0x03,0xcd,0x3a,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x7d,0x03,0xcd,0x3a,0xb8,0x8d
+,0x03,0xcd,0x3a,0xc7,0x06,0x41,0x37,0x00,0x00,0x07,0xc3,0x06,0x8e,0x06,0x38,0x34
+,0x1f,0x8b,0x0e,0x0e,0x00,0x26,0x89,0x0e,0x0e,0x00,0xbe,0x18,0x00,0xbf,0x18,0x00
+,0xf3,0xa4,0x06,0x1e,0x07,0xcd,0x34,0x07,0x33,0xc0,0x8e,0xd8,0xc3,0x26,0xf6,0x06
+,0x20,0x00,0x80,0x74,0x44,0x33,0xc0,0x26,0xa0,0x26,0x00,0x24,0x1f,0x8b,0xf0,0x26
+,0x8b,0x5c,0x28,0x89,0x1e,0x6a,0x37,0x06,0x8e,0x06,0x38,0x34,0x1f,0xc0,0xe3,0x04
+,0x26,0x88,0x5c,0x28,0x8b,0xc6,0xb9,0x06,0x00,0xbe,0x20,0x00,0xbf,0x1a,0x00,0xf3
+,0xa4,0x8b,0xc8,0x83,0xc7,0x06,0xf3,0xa4,0x26,0x81,0x26,0x26,0x00,0x1f,0x80,0x26
+,0x81,0x36,0x26,0x00,0x00,0x80,0xe9,0xa9,0xff,0x26,0x8b,0x1e,0x28,0x00,0x89,0x1e
+,0x6a,0x37,0x06,0x8e,0x06,0x38,0x34,0x1f,0xc0,0xe3,0x04,0x26,0x88,0x1e,0x28,0x00
+,0xb9,0x06,0x00,0xbe,0x20,0x00,0xbf,0x1a,0x00,0xf3,0xa4,0xe9,0x84,0xff,0x86,0xc4
+,0xa3,0x68,0x37,0xe8,0x87,0xff,0xf7,0x06,0x6a,0x37,0x0f,0x00,0x74,0x10,0x80,0x3e
+,0x9e,0x36,0x00,0x75,0x09,0xbe,0x00,0x00,0xe8,0xac,0xe9,0xcd,0x50,0xc3,0xc3,0x50
+,0x56,0x06,0x33,0xc0,0x26,0xf6,0x06,0x20,0x00,0x80,0x74,0x06,0x26,0xa0,0x26,0x00
+,0x24,0x1f,0x8b,0xf0,0x26,0x8b,0x5c,0x26,0x86,0xfb,0x83,0xeb,0x04,0x74,0x4f,0x83
+,0xc6,0x2a,0x8c,0xc0,0x8e,0xd8,0xb9,0x07,0x00,0x33,0xc0,0x8e,0xc0,0xbf,0x72,0x37
+,0xf3,0xab,0x33,0xc9,0x8a,0x0c,0x80,0xf9,0x00,0x75,0x03,0xe9,0x30,0x00,0x3b,0xd9
+,0x73,0x03,0xe9,0x29,0x00,0x2b,0xd9,0x8a,0x44,0x01,0x25,0x3f,0x00,0x74,0x19,0x3d
+,0x0b,0x00,0x7d,0x14,0xd1,0xe0,0x8b,0xf8,0x2e,0x8b,0xbd,0x5c,0x49,0x8d,0x74,0x02
+,0x83,0xe9,0x02,0xf3,0xa4,0xe9,0x02,0x00,0x03,0xf1,0x23,0xdb,0x75,0xc4,0x33,0xc0
+,0x8e,0xd8,0x07,0x5e,0x58,0xc3,0x33,0xc0,0x26,0xf6,0x06,0x20,0x00,0x80,0x74,0x06
+,0x26,0xa0,0x26,0x00,0x24,0x1f,0xc3,0xe5,0x0a,0x25,0xc3,0xbf,0xe7,0x0a,0xb8,0x86
+,0x03,0xcd,0x39,0xb8,0x83,0x03,0xcd,0x39,0x81,0x26,0x9b,0x36,0x7c,0xdf,0xb8,0x85
+,0x03,0xcd,0x3a,0xe5,0x02,0x25,0xff,0xf3,0x0d,0x01,0x00,0x25,0xef,0xff,0xe7,0x02
+,0xe5,0x00,0x25,0xff,0x53,0xe7,0x00,0xa1,0xe7,0x36,0x25,0xff,0xfe,0xa3,0xe7,0x36
+,0xe7,0x3e,0x83,0x26,0x99,0x36,0xcf,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1,0xaf,0x36
+,0xe7,0x06,0xc3,0xe5,0x02,0x0d,0x01,0x0c,0x25,0xef,0xff,0xe7,0x02,0xa1,0xe7,0x36
+,0x0d,0x00,0x01,0xe7,0x3e,0xa3,0xe7,0x36,0x81,0x0e,0x9b,0x36,0x00,0x20,0x83,0x0e
+,0x99,0x36,0x20,0x81,0x26,0x9b,0x36,0x7c,0xbf,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1
+,0xaf,0x36,0xe7,0x06,0xb8,0x86,0x03,0xcd,0x39,0xb8,0x85,0x03,0xcd,0x39,0xb8,0x83
+,0x03,0xcd,0x3a,0xc3,0x0b,0xf6,0x75,0x49,0x06,0x8e,0x06,0x32,0x34,0x80,0x3e,0xe0
+,0x34,0x01,0x75,0x1b,0x26,0x89,0x36,0x06,0x00,0x8e,0x06,0x32,0x34,0x26,0xf7,0x06
+,0x0a,0x00,0x00,0x20,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x20,0x07,0xc3,0x80
+,0x3e,0xe3,0x34,0x01,0x75,0x19,0x26,0x89,0x36,0x06,0x00,0x8e,0x06,0x32,0x34,0x26
+,0xf7,0x06,0x0a,0x00,0x00,0x10,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x10,0x07
+,0xc3,0xe9,0xb4,0xff,0x50,0x51,0x57,0x33,0xc0,0xb9,0x06,0x00,0x8e,0xc0,0xbf,0xd1
+,0x36,0xf3,0xae,0x5f,0x74,0x0c,0x26,0xf6,0x06,0x00,0x00,0xc0,0x75,0x04,0xf8,0x59
+,0x58,0xc3,0xf9,0xe9,0xf9,0xff,0x8b,0x05,0x0b,0x45,0x02,0x0b,0x45,0x04,0xc3,0x52
+,0x50,0xe5,0x06,0x25,0x1e,0x00,0x3d,0x1e,0x00,0x75,0xf6,0xb8,0x01,0x80,0xe7,0x5a
+,0x58,0x5a,0xc3,0xe8,0xe9,0xff,0x50,0xe5,0x02,0x25,0xff,0x7f,0x0d,0x01,0x00,0x25
+,0xef,0xff,0xe7,0x02,0x0d,0x00,0x80,0xe7,0x02,0xa1,0xad,0x36,0xe7,0x04,0xa1,0xaf
+,0x36,0xe7,0x06,0x58,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x2e,0x2b,0xce,0x41,0x10,0x42,0x7b,0x41,0x30,0x41,0xa2,0x41,0xaf,0x45,0x44,0x29
+,0xc7,0x2a,0xc7,0x2a,0x60,0x39,0xf4,0x3a,0x5c,0x3c,0x09,0x3d,0xb1,0x3d,0x34,0x3f
+,0xc7,0x2a,0x3c,0x3f,0xc7,0x2a,0xc4,0x3f,0x16,0x40,0x16,0x40,0xed,0x40,0xfa,0x40
+,0x07,0x41,0xc7,0x2a,0xc7,0x2a,0xc7,0x2a,0xc7,0x2a,0xd6,0x52,0x00,0x00,0x01,0x37
+,0xe9,0x36,0xf3,0x36,0xef,0x36,0x1d,0x37,0x0d,0x37,0x0b,0x37,0x9c,0x37,0x03,0x37
+,0xfb,0x36,0x62,0x2d,0x40,0x06,0xd1,0x2d,0xf4,0x01,0xba,0x44,0x40,0x06,0x8c,0x43
+,0x64,0x00,0xe8,0x2c,0xc8,0x00,0xd8,0x2b,0x05,0x00,0xe9,0x45,0x50,0x00,0x97,0x45
+,0xfa,0x00,0xae,0x2d,0x04,0x01,0x6a,0x42,0x02,0x00,0xf6,0x2c,0xbc,0x02,0x93,0x2d
+,0xdc,0x05,0x1d,0x2d,0x64,0x00,0xa1,0x2d,0x14,0x00,0xd7,0x3a,0x08,0x07,0x81,0x2d
+,0x64,0x00,0xb3,0x3e,0x02,0x00,0x30,0x43,0x64,0x00,0xc5,0x2c,0xf4,0x01,0x8b,0x44
+,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x80,0x3e,0xfd,0x34,0x02,0x74,0x0c,0xe8,0x20,0x05,0xc7,0x06,0xa1,0x36,0x00,0x00
+,0xe9,0x9a,0xf8,0xff,0x06,0xc0,0x33,0xe8,0x10,0x05,0x8b,0x36,0x3d,0x37,0xe8,0x73
+,0xfe,0xc3,0xcd,0x34,0xe9,0xe8,0x05,0xc7,0x06,0xa3,0x36,0x00,0x00,0xc7,0x06,0x41
+,0x37,0x00,0x00,0xe8,0xed,0xfe,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56,0xa1,0xb1,0x36
+,0x0d,0x00,0x10,0xe7,0x08,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xa1
+,0xad,0x36,0xe7,0x04,0xe8,0x2b,0x09,0xc7,0x06,0x1d,0x37,0x00,0xc8,0xc7,0x06,0x0b
+,0x37,0x00,0x03,0xc7,0x06,0x0d,0x37,0x7b,0x7f,0x33,0xc0,0xa3,0x9b,0x36,0xa3,0x9d
+,0x36,0xc7,0x06,0x4c,0x37,0x01,0x00,0xc6,0x06,0x9e,0x36,0xff,0xc7,0x06,0x05,0x37
+,0x00,0x00,0xc7,0x06,0x07,0x37,0x00,0x00,0xc7,0x06,0x09,0x37,0x00,0x00,0xa3,0xf3
+,0x36,0xa3,0xef,0x36,0xa3,0xf1,0x36,0xe8,0xfe,0xf5,0xe5,0x02,0x25,0xf9,0xff,0x0d
+,0x03,0x00,0x0d,0x00,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02
+,0xb8,0x8f,0x03,0xcd,0x39,0xb8,0x80,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff
+,0xa1,0xa9,0x36,0xa3,0xa7,0x36,0x0d,0x00,0xa4,0x0d,0x00,0x08,0xe7,0x00,0xa3,0xa9
+,0x36,0xc7,0x06,0xa3,0x36,0x01,0x00,0xc7,0x06,0xa5,0x36,0x0c,0x00,0x83,0x3e,0xa5
+,0x36,0x00,0x75,0x09,0xc7,0x06,0x3d,0x37,0x05,0x00,0xe9,0x13,0xff,0xff,0x0e,0xa5
+,0x36,0xbe,0x11,0x00,0xe8,0x22,0x05,0xb8,0x90,0x03,0xcd,0x39,0xc3,0x83,0x3e,0xa3
+,0x36,0x01,0x74,0xd9,0xc3,0xb8,0x90,0x03,0xcd,0x3a,0x26,0xa0,0x2b,0x00,0x26,0x8b
+,0x1e,0x2c,0x00,0xcd,0x34,0x83,0x3e,0xa3,0x36,0x01,0x74,0x03,0xe9,0xf0,0x04,0x3c
+,0x0f,0x75,0x1e,0x81,0xfb,0x00,0x02,0x75,0x18,0x26,0xa1,0x20,0x00,0xa3,0x05,0x37
+,0x26,0xa1,0x22,0x00,0xa3,0x07,0x37,0x26,0xa1,0x24,0x00,0xa3,0x09,0x37,0xe9,0x09
+,0x00,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xb6,0xfe,0xc7,0x06,0xa3,0x36,0x02,0x00
+,0xc6,0x06,0x9e,0x36,0xff,0xe8,0xcb,0xfd,0xe8,0x1c,0xd9,0x33,0xc0,0xa3,0x85,0x37
+,0xa3,0x83,0x37,0xa3,0x87,0x37,0xa3,0x89,0x37,0xb8,0x91,0x03,0xcd,0x39,0xb8,0x80
+,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff,0xe5,0x00,0x25,0xff,0x53,0xe7,0x00
+,0x81,0x0e,0x9a,0x37,0x80,0x00,0xb8,0x92,0x03,0xcd,0x39,0x33,0xc0,0xe7,0x0e,0xbe
+,0x08,0x00,0x8e,0x06,0x38,0x34,0xe8,0x8e,0xe5,0x26,0xc7,0x06,0x04,0x00,0x7d,0x4b
+,0x83,0x26,0xef,0x34,0xdf,0xcd,0x50,0x83,0x0e,0xef,0x34,0x20,0xc3,0xf7,0x06,0x9a
+,0x37,0x80,0x00,0x74,0x32,0xa9,0xd0,0x07,0x74,0x0c,0xa9,0x00,0x04,0x74,0x0e,0x33
+,0xc0,0xe7,0x0e,0xe9,0xda,0xff,0xff,0x06,0x85,0x37,0xe9,0xd3,0xff,0xff,0x06,0x83
+,0x37,0xe9,0xcc,0xff,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0x36,0xfe,0x83,0x26,0x9a
+,0x37,0x7f,0xbb,0xff,0x7f,0xcd,0x53,0xe5,0x00,0x0d,0x00,0xac,0xe7,0x00,0xe5,0x02
+,0x25,0xff,0xfb,0x25,0xef,0xff,0x25,0xff,0xf7,0x0d,0x01,0x00,0xe7,0x02,0xa1,0x83
+,0x37,0x3b,0x06,0x46,0x37,0x7f,0xcd,0xa1,0x85,0x37,0x3b,0x06,0x48,0x37,0x7c,0xc4
+,0xc7,0x06,0xa3,0x36,0x03,0x00,0xbe,0x13,0x00,0xe8,0xfd,0x03,0xb8,0x93,0x03,0xcd
+,0x39,0xb8,0x94,0x03,0xcd,0x39,0xb8,0x96,0x03,0xcd,0x39,0xb8,0x95,0x03,0xcd,0x39
+,0xbe,0x06,0x00,0xe8,0xe3,0x03,0xe9,0xd6,0x03,0x83,0x3e,0xa3,0x36,0x03,0x74,0x01
+,0xc3,0xbe,0x13,0x00,0xe8,0xd2,0x03,0xb8,0x94,0x03,0xcd,0x39,0xc3,0xb8,0x94,0x03
+,0xcd,0x3a,0x26,0xa0,0x2b,0x00,0x26,0x8b,0x1e,0x2c,0x00,0xcd,0x34,0x83,0x3e,0xa3
+,0x36,0x03,0x74,0x03,0xe9,0xa8,0x03,0x3c,0x0d,0x75,0x3e,0x83,0xfb,0x00,0x75,0x39
+,0xe5,0x02,0x0d,0x00,0x20,0xe7,0x02,0xb8,0x93,0x03,0xcd,0x3a,0xc7,0x06,0xa3,0x36
+,0x04,0x00,0xbe,0x00,0x00,0xe8,0x0c,0xfc,0xc6,0x06,0x9d,0x36,0x80,0xc6,0x06,0x9e
+,0x36,0x00,0xc7,0x06,0x33,0x37,0x02,0x00,0xb8,0x9a,0x03,0xcd,0x39,0xe8,0xfc,0x00
+,0xc7,0x06,0x4c,0x37,0x00,0x00,0xe9,0x66,0x03,0xc7,0x06,0x3d,0x37,0x08,0x00,0xe9
+,0x61,0xfd,0x83,0x3e,0xa3,0x36,0x03,0x75,0x09,0xc7,0x06,0x3d,0x37,0x05,0x00,0xe9
+,0x51,0xfd,0xe9,0x4a,0x03,0x83,0x3e,0xa3,0x36,0x04,0x74,0x12,0x83,0x3e,0xa3,0x36
+,0x05,0x74,0x0b,0xcd,0x34,0xc7,0x06,0x3d,0x37,0x07,0x00,0xe9,0x35,0xfd,0xc7,0x06
+,0xa3,0x36,0x06,0x00,0xc6,0x06,0x9e,0x36,0xff,0xb8,0x9a,0x03,0xcd,0x3a,0xb8,0x99
+,0x03,0xcd,0x3a,0xb8,0x96,0x03,0xcd,0x3a,0xb8,0x97,0x03,0xcd,0x39,0xb8,0x98,0x03
+,0xcd,0x39,0xb8,0x9b,0x03,0xcd,0x39,0xe9,0x18,0xfd,0xcd,0x34,0x83,0x3e,0xa3,0x36
+,0x04,0x77,0x18,0x83,0x3e,0xa3,0x36,0x03,0x75,0x08,0xf7,0x06,0x9b,0x36,0x00,0x01
+,0x75,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xe8,0xfc,0xe9,0xe1,0x02,0xcd,0x34
+,0x83,0x3e,0xa3,0x36,0x02,0x77,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xd3,0xfc
+,0x83,0x3e,0xa3,0x36,0x04,0x77,0x05,0xb8,0x96,0x03,0xcd,0x39,0xe9,0xc0,0x02,0x83
+,0x3e,0xa3,0x36,0x03,0x75,0x10,0x26,0xa1,0x0c,0x00,0x25,0x07,0x00,0x50,0x3d,0x04
+,0x00,0x75,0x03,0xe8,0x36,0x00,0xa1,0xf3,0x36,0x86,0xe0,0xe7,0x1e,0xa3,0xe3,0x36
+,0x81,0x26,0x0b,0x37,0x00,0x03,0x81,0x26,0x0d,0x37,0x7b,0x7f,0x83,0x0e,0x0d,0x37
+,0x48,0xe8,0x14,0xf3,0x58,0x3d,0x04,0x00,0x74,0x09,0x26,0xf7,0x06,0x0c,0x00,0x20
+,0x00,0x75,0x06,0xb8,0x01,0x00,0xe9,0x7a,0x02,0xe9,0x86,0xfc,0xa1,0xe5,0x36,0xe7
+,0x2e,0xa1,0xe7,0x36,0xe7,0x3e,0xa1,0xd3,0x36,0xa3,0x9c,0x34,0xa1,0xd5,0x36,0xa3
+,0x9e,0x34,0xc3,0x26,0x80,0x3e,0x1c,0x00,0xff,0x75,0x2f,0x26,0x80,0x3e,0x1e,0x00
+,0xff,0x75,0x27,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00,0x75,0x1b,0xa1,0xd1,0x36,0x26
+,0xa3,0x1a,0x00,0xa1,0xd3,0x36,0x26,0xa3,0x1c,0x00,0xa1,0xd5,0x36,0x26,0xa3,0x1e
+,0x00,0xb8,0x0a,0x80,0xe9,0x2c,0x02,0xe9,0x38,0xfc,0xff,0x06,0x90,0x34,0xbe,0x0a
+,0x00,0xc6,0x06,0xb6,0x34,0x01,0xf6,0x06,0x9d,0x36,0x80,0x75,0x05,0x83,0x0e,0xc2
+,0x34,0x01,0xcd,0x34,0xe9,0x0c,0xfc,0x83,0x3e,0xa3,0x36,0x03,0x75,0x09,0xc7,0x06
+,0x3d,0x37,0x05,0x00,0xe9,0xfc,0xfb,0xe5,0x02,0x0d,0x03,0x00,0x0d,0x00,0x88,0x0d
+,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02,0xc7,0x06,0xa3,0x36,0x05,0x00,0xc6,0x06,0x9e
+,0x36,0xff,0xbe,0x02,0x00,0xe8,0xe1,0x01,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x9a,0x03
+,0xcd,0x3a,0xb8,0x99,0x03,0xcd,0x39,0xb8,0x97,0x03,0xcd,0x39,0xb8,0x98,0x03,0xcd
+,0x39,0xe9,0xbb,0x01,0x83,0x3e,0xa3,0x36,0x03,0x74,0x0a,0x83,0x3e,0xa3,0x36,0x04
+,0x74,0x03,0xe9,0xaa,0x01,0xbe,0x06,0x00,0xe8,0xae,0x01,0xb8,0x95,0x03,0xcd,0x39
+,0xe9,0x9c,0x01,0x83,0x3e,0xa3,0x36,0x05,0x74,0x03,0xe9,0x92,0x01,0xbe,0x02,0x00
+,0xe8,0x96,0x01,0xb8,0x99,0x03,0xcd,0x39,0xe9,0x84,0x01,0xc7,0x06,0x0f,0x37,0x05
+,0x00,0xe9,0x7b,0x01,0xe5,0x02,0x25,0xff,0xdf,0xe7,0x02,0xc7,0x06,0xa3,0x36,0x07
+,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xe9,0x65,0x01,0xe8,0xd5,0x04,0xc6,0x06,0x9d
+,0x36,0x00,0xc7,0x06,0x9b,0x36,0x00,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xc7,0x06
+,0xa8,0x02,0x00,0x00,0xc7,0x06,0x4c,0x37,0x01,0x00,0xe5,0x02,0x25,0xf9,0xff,0x0d
+,0x03,0x00,0x0d,0x00,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02
+,0xe9,0x67,0xfc,0xb8,0x9a,0x03,0xcd,0x39,0xf7,0x06,0xf4,0x33,0x00,0x10,0x75,0x09
+,0xc7,0x06,0x33,0x37,0x02,0x00,0xe9,0x16,0x01,0xff,0x0e,0x33,0x37,0x74,0x03,0xe9
+,0x0d,0x01,0xff,0x06,0x8e,0x34,0x83,0x0e,0xc2,0x34,0x08,0xc7,0x06,0x3d,0x37,0x03
+,0x00,0xe9,0xff,0xfa,0xc3,0x52,0x50,0xba,0xe0,0x00,0xb8,0x00,0x10,0xef,0x58,0x5a
+,0xc3,0xc7,0x06,0x3d,0x37,0x00,0x00,0xe9,0xe9,0xfa,0xfa,0xe8,0x54,0x04,0xb8,0x80
+,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04,0x00,0xd8,0x2b,0xb8,0x7f,0x03,0x8e,0xc0,0x26
+,0xc7,0x06,0x04,0x00,0xe8,0x2c,0x33,0xc0,0x8e,0xc0,0xa1,0xa7,0x36,0xa3,0xa9,0x36
+,0xa1,0xa9,0x36,0xe7,0x00,0xa1,0xab,0x36,0xe7,0x02,0xc7,0x06,0x05,0x37,0x00,0x00
+,0xc7,0x06,0x07,0x37,0x00,0x00,0xc7,0x06,0x09,0x37,0x00,0x00,0xc6,0x06,0x9d,0x36
+,0x00,0xc6,0x06,0x9e,0x36,0xff,0xc7,0x06,0x9b,0x36,0x00,0x00,0xc7,0x06,0xa3,0x36
+,0x00,0x00,0xc7,0x06,0x0f,0x37,0x00,0x00,0xc7,0x06,0xa8,0x02,0x00,0x00,0xc7,0x06
+,0x4c,0x37,0x01,0x00,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0xbb
+,0xff,0x7f,0xcd,0x53,0xe8,0x7c,0xf9,0xe5,0x56,0x0d,0x02,0x00,0xe7,0x56,0xfb,0xc3
+,0x8d,0x3e,0xc0,0x53,0x8d,0x36,0xf0,0x38,0xb9,0x0e,0x00,0x8b,0x1e,0x30,0x34,0x89
+,0x5c,0x02,0x2e,0x8b,0x45,0x02,0x89,0x44,0x06,0x2e,0x8b,0x05,0x89,0x44,0x04,0x83
+,0xc7,0x04,0x83,0xc6,0x10,0xe2,0xe8,0xb8,0x80,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04
+,0x00,0xe2,0x51,0xb8,0x7f,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04,0x00,0xb2,0x52,0x33
+,0xc0,0x8e,0xc0,0xc7,0x06,0xa1,0x36,0x01,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xc3
+,0x33,0xff,0x8e,0x06,0xa6,0x02,0x8b,0x36,0xa4,0x02,0x2e,0xff,0xa4,0xa0,0x53,0xe8
+,0x8c,0xdb,0xc3,0xe8,0x48,0xf7,0xe9,0xf6,0xff,0x8e,0x06,0x38,0x34,0xe8,0x07,0xe1
+,0x26,0xc7,0x06,0x04,0x00,0xdf,0x4f,0xcd,0x50,0xc3,0x26,0xc7,0x06,0x0a,0x00,0x00
+,0x00,0x26,0xff,0x26,0x04,0x00,0xcd,0x34,0xe9,0xd4,0xff,0xa1,0xd1,0x36,0x26,0x39
+,0x06,0x1a,0x00,0x75,0x22,0xa1,0xd3,0x36,0x26,0x39,0x06,0x1c,0x00,0x75,0x18,0xa1
+,0xd5,0x36,0x26,0x39,0x06,0x1e,0x00,0x75,0x0e,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00
+,0x74,0x05,0x83,0x0e,0x66,0x37,0x40,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1,0xaf,0x36
+,0xe7,0x06,0x83,0x3e,0xa3,0x36,0x02,0x75,0x05,0xcd,0x34,0xe9,0x56,0xfb,0x83,0x3e
+,0xa3,0x36,0x00,0x74,0xb1,0x83,0x3e,0xa3,0x36,0x05,0x77,0xaa,0x26,0xf6,0x06,0x0a
+,0x00,0xff,0x75,0xa2,0xe8,0xfd,0xdd,0x50,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xe9
+,0x8c,0x00,0x26,0xa1,0x0c,0x00,0x25,0x07,0x00,0x3d,0x07,0x00,0x75,0x03,0xe9,0x76
+,0x00,0x3d,0x05,0x00,0x75,0x03,0xe9,0x6e,0x00,0xf7,0x06,0xe6,0x34,0x18,0x80,0x75
+,0x03,0xe9,0x6a,0x00,0xf7,0x06,0xe6,0x34,0x00,0x80,0x74,0x35,0x26,0x80,0x3e,0x29
+,0x00,0x02,0x75,0x2d,0x51,0x56,0x57,0x8d,0x36,0x3e,0x34,0x8d,0x3e,0x20,0x00,0xb9
+,0x06,0x00,0xf3,0xa6,0x5f,0x5e,0x59,0x75,0x45,0x26,0xa1,0x20,0x00,0xa3,0x3e,0x34
+,0x26,0xa1,0x22,0x00,0xa3,0x40,0x34,0x26,0xa1,0x24,0x00,0xa3,0x42,0x34,0xe9,0x26
+,0x00,0xf7,0x06,0xe6,0x34,0x08,0x00,0x74,0x0b,0x26,0x80,0x3e,0x19,0x00,0x00,0x74
+,0x03,0xe9,0x13,0x00,0xf7,0x06,0xe6,0x34,0x10,0x00,0x74,0x12,0x26,0xa0,0x28,0x00
+,0xc0,0xe8,0x04,0x22,0xc0,0x74,0x07,0x26,0xc7,0x06,0x04,0x00,0xff,0xff,0x58,0x23
+,0xc0,0x74,0x03,0xe9,0xdd,0xfe,0x81,0x26,0x9b,0x36,0xff,0xfe,0x26,0xa1,0x20,0x00
+,0x3b,0x06,0xd1,0x36,0x75,0x1a,0x26,0xa1,0x22,0x00,0x3b,0x06,0xd3,0x36,0x75,0x10
+,0x26,0xa1,0x24,0x00,0x3b,0x06,0xd5,0x36,0x75,0x06,0x81,0x0e,0x9b,0x36,0x00,0x01
+,0x26,0xa1,0x20,0x00,0x25,0x7f,0xff,0xa3,0xb8,0x34,0x26,0xa1,0x22,0x00,0xa3,0xba
+,0x34,0x26,0xa1,0x24,0x00,0xa3,0xbc,0x34,0x8b,0xc6,0x86,0xc4,0xa3,0xc0,0x34,0xd1
+,0xe6,0x80,0xfc,0x09,0x74,0x03,0xe8,0xf6,0xf5,0xa1,0x05,0x37,0x0b,0x06,0x07,0x37
+,0x0b,0x06,0x09,0x37,0x74,0x3e,0x26,0xa1,0x20,0x00,0x3b,0x06,0x05,0x37,0x75,0x17
+,0x26,0xa1,0x22,0x00,0x3b,0x06,0x07,0x37,0x75,0x0d,0x26,0xa1,0x24,0x00,0x3b,0x06
+,0x09,0x37,0x75,0x03,0xe9,0x1d,0x00,0x26,0xa0,0x28,0x00,0x24,0x0f,0x3c,0x03,0x74
+,0x1b,0x3c,0x00,0x75,0x0f,0x83,0x3e,0xa3,0x36,0x04,0x74,0x10,0xf7,0x06,0x9b,0x36
+,0x00,0x01,0x74,0x08,0x2e,0xff,0x94,0xf8,0x53,0xe9,0x33,0xfe,0xcd,0x34,0xc7,0x06
+,0x3d,0x37,0x01,0x00,0xe9,0x2c,0xf8,0x83,0x3e,0xa3,0x36,0x05,0x74,0x10,0x83,0x3e
+,0xa3,0x36,0x01,0x7e,0x09,0x83,0xee,0x16,0x2e,0xff,0x94,0x24,0x54,0xc3,0xcd,0x34
+,0xc3,0x26,0xa1,0x0c,0x00,0x3d,0xff,0x7f,0x74,0x05,0x26,0xff,0x26,0x04,0x00,0xe9
+,0xfd,0xfd,0xa1,0xf4,0x33,0xa9,0x00,0x88,0x74,0x0b,0xa9,0x00,0x10,0x75,0x09,0x8b
+,0x1e,0x43,0x37,0xff,0xe3,0xe9,0x97,0x00,0xc7,0x06,0x35,0x37,0x05,0x00,0xc7,0x06
+,0x43,0x37,0x28,0x52,0xf7,0x06,0xf4,0x33,0x00,0x08,0x74,0x06,0xc7,0x06,0x43,0x37
+,0x1a,0x52,0xb8,0x80,0x03,0xcd,0x39,0xe9,0xc5,0xfd,0xa9,0x00,0x08,0x74,0xd9,0xff
+,0x0e,0x35,0x37,0x75,0xed,0xe9,0x30,0x00,0xa9,0x00,0x08,0x75,0xcb,0xff,0x0e,0x35
+,0x37,0x75,0xdf,0x81,0x0e,0xc2,0x34,0xc0,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74,0x0f
+,0x81,0x0e,0x9b,0x36,0x00,0x80,0xc7,0x06,0x0f,0x37,0x02,0x00,0xe9,0x90,0xfd,0xc7
+,0x06,0x3d,0x37,0x02,0x00,0xe9,0x8b,0xf7,0x80,0x26,0x9e,0x36,0xff,0x75,0x30,0xf6
+,0x06,0x9d,0x36,0x80,0x74,0x20,0xff,0x06,0x94,0x34,0x83,0x0e,0x66,0x37,0x20,0x8e
+,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08
+,0x00,0x00,0x01,0xe9,0x09,0x00,0xc7,0x06,0x3d,0x37,0x04,0x00,0xe9,0x54,0xf7,0x81
+,0x0e,0xaf,0x36,0x00,0x08,0xa1,0xaf,0x36,0xe7,0x06,0xe5,0x0a,0xa9,0x00,0x80,0x74
+,0x0e,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36,0xe7,0x06,0xe9,0x49,0xff,0xe9
+,0x2d,0xfd,0xc7,0x06,0x41,0x37,0x00,0x00,0xbe,0x29,0x00,0xe8,0x2b,0xfd,0xe9,0x1e
+,0xfd,0xcd,0x34,0x83,0x3e,0xa3,0x36,0x04,0x77,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00
+,0xe9,0x10,0xf7,0xe9,0x09,0xfd,0xcd,0x34,0xc3,0xc7,0x06,0x9b,0x36,0x00,0x00,0xe8
+,0x0c,0xf5,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0x81,0x26,0x9b
+,0x36,0xff,0x7f,0xe5,0x02,0x0d,0x01,0x00,0x25,0xef,0xff,0x25,0xff,0xdf,0xe7,0x02
+,0xbb,0xff,0x7f,0xcd,0x53,0x33,0xc0,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xe8,0x20,0xf3
+,0xe8,0x43,0xf3,0x83,0x0e,0x9b,0x36,0x10,0xc7,0x06,0x99,0x36,0x00,0x00,0xe8,0xd2
+,0xf5,0xe5,0x56,0x0d,0x02,0x00,0xe7,0x56,0xc7,0x06,0xa8,0x02,0x00,0x00,0xbe,0x00
+,0x00,0xe8,0x30,0xf5,0xc6,0x06,0xa0,0x36,0x0e,0xb8,0x9c,0x03,0xcd,0x39,0xb8,0x80
+,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff,0xc7,0x06,0xa1,0x36,0x01,0x00,0xe9
+,0xa5,0xf6,0x06,0xb8,0x8f,0x03,0xcd,0x3a,0xb8,0x90,0x03,0xcd,0x3a,0xb8,0x91,0x03
+,0xcd,0x3a,0xb8,0x92,0x03,0xcd,0x3a,0xb8,0x93,0x03,0xcd,0x3a,0xb8,0x94,0x03,0xcd
+,0x3a,0xb8,0x95,0x03,0xcd,0x3a,0xb8,0x96,0x03,0xcd,0x3a,0xb8,0x97,0x03,0xcd,0x3a
+,0xb8,0x98,0x03,0xcd,0x3a,0xb8,0x99,0x03,0xcd,0x3a,0xb8,0x9a,0x03,0xcd,0x3a,0xb8
+,0x9b,0x03,0xcd,0x3a,0xb8,0x7f,0x03,0xcd,0x3a,0xb8,0x80,0x03,0xcd,0x3a,0x07,0xc3
+,0xf7,0x49,0xf1,0x4e,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xf8,0x51,0xdf,0x4f
+,0xfa,0x4f,0x0b,0x50,0xd1,0x51,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f
+,0xe4,0x4e,0x06,0x00,0xcd,0x4a,0x04,0x00,0xe4,0x4e,0x19,0x00,0xad,0x4b,0xfa,0x00
+,0x82,0x4c,0x08,0x07,0x09,0x4c,0x14,0x00,0x24,0x4e,0x64,0x00,0xd7,0x4d,0xf4,0x01
+,0x64,0x4e,0xbc,0x02,0x7a,0x4e,0xe8,0x03,0x43,0x4e,0x02,0x00,0xb3,0x4e,0xf4,0x01
+,0x5b,0x4e,0xf4,0x01,0xe5,0x4e,0x14,0x00,0x06,0x50,0x06,0x50,0x95,0x4c,0xc1,0x52
+,0xc1,0x52,0xfe,0x4c,0xda,0x4c,0x06,0x50,0x06,0x50,0x06,0x50,0x06,0x50,0xb7,0x51
+,0xb7,0x51,0xb7,0x51,0xb7,0x51,0xb7,0x51,0xb7,0x51,0x06,0x50,0xd5,0x4a,0x06,0x50
+,0x1d,0x4c,0x06,0x50,0x83,0x4d,0x1f,0x4d,0x1f,0x4d,0xed,0x40,0xfa,0x40,0x07,0x41
+,0x37,0x37,0x2e,0x37,0x37,0x20,0x20,0x79,0x79,0x2f,0x79,0x79,0x2f,0x79,0x79,0x20
+,0x30,0x31,0x2e,0x39,0x30,0x20,0x20,0x30,0x32,0x2f,0x31,0x37,0x2f,0x39,0x39,0x20
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x90,0xea,0xc0,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x06
+} ;  
+#endif 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/Config.in linux/drivers/net/tokenring/Config.in
--- linux.orig/drivers/net/tokenring/Config.in	2001-03-07 03:28:35.000000000 +0000
+++ linux/drivers/net/tokenring/Config.in	2002-07-20 01:08:28.000000000 +0000
@@ -18,6 +18,7 @@
    fi
    dep_tristate '  IBM Olympic chipset PCI adapter support' CONFIG_IBMOL $CONFIG_TR $CONFIG_PCI
    dep_tristate '  IBM Lanstreamer chipset PCI adapter support' CONFIG_IBMLS $CONFIG_TR $CONFIG_PCI
+   dep_tristate '  3Com 3C359 Token Link Velocity XL adapter support' CONFIG_3C359 $CONFIG_TR $CONFIG_PCI
    tristate '  Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR
    if [ "$CONFIG_TMS380TR" != "n" ]; then
       dep_tristate '    Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_PCI
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/Makefile linux/drivers/net/tokenring/Makefile
--- linux.orig/drivers/net/tokenring/Makefile	2001-02-17 00:02:36.000000000 +0000
+++ linux/drivers/net/tokenring/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -21,6 +21,7 @@
 obj-$(CONFIG_TMSPCI) 	+= tmspci.o
 obj-$(CONFIG_TMSISA) 	+= tmsisa.o
 obj-$(CONFIG_SMCTR) 	+= smctr.o
+obj-$(CONFIG_3C359)	+= 3c359.o
 
 O_TARGET := tr.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/lanstreamer.c linux/drivers/net/tokenring/lanstreamer.c
--- linux.orig/drivers/net/tokenring/lanstreamer.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/tokenring/lanstreamer.c	2002-07-20 01:08:35.000000000 +0000
@@ -60,6 +60,11 @@
  *		malloc free checks, reviewed code. <alan@redhat.com>
  *  03/13/00 - Added spinlocks for smp
  *  03/08/01 - Added support for module_init() and module_exit()
+ *  08/15/01 - Added ioctl() functionality for debugging, changed netif_*_queue
+ *             calls and other incorrectness - Kent Yoder <yoder1@us.ibm.com>
+ *  11/05/01 - Restructured the interrupt function, added delays, reduced the 
+ *             the number of TX descriptors to 1, which together can prevent 
+ *             the card from locking up the box - <yoder1@us.ibm.com>
  *  
  *  To Do:
  *
@@ -84,6 +89,14 @@
 
 #define STREAMER_NETWORK_MONITOR 0
 
+/* #define CONFIG_PROC_FS */
+
+/*
+ *  Allow or disallow ioctl's for debugging
+ */
+
+#define STREAMER_IOCTL 0
+
 #include <linux/config.h>
 #include <linux/module.h>
 
@@ -105,6 +118,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
+#include <linux/version.h>
 #include <net/checksum.h>
 
 #include <asm/io.h>
@@ -121,7 +135,8 @@
  * Official releases will only have an a.b.c version number format.
  */
 
-static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan";
+static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n"
+                        "              v0.5.1 03/04/02 - Kent Yoder";
 
 static struct pci_device_id streamer_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,},
@@ -175,6 +190,10 @@
 MODULE_PARM(message_level,
 	    "1-" __MODULE_STRING(STREAMER_MAX_ADAPTERS) "i");
 
+#if STREAMER_IOCTL
+static int streamer_ioctl(struct net_device *, struct ifreq *, int);
+#endif
+
 static int streamer_reset(struct net_device *dev);
 static int streamer_open(struct net_device *dev);
 static int streamer_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -206,6 +225,8 @@
   __u32 mmio_start, mmio_end, mmio_flags, mmio_len;
   int rc=0;
   static int card_no=-1;
+  u16 pcr;
+  u8 cls = 0;
 
 #if STREAMER_DEBUG
   printk("lanstreamer::streamer_init_one, entry pdev %p\n",pdev);
@@ -281,7 +302,11 @@
 			dev->hard_start_xmit = &streamer_xmit;
 			dev->change_mtu = &streamer_change_mtu;
 			dev->stop = &streamer_close;
+#if STREAMER_IOCTL
+			dev->do_ioctl = &streamer_ioctl;
+#else
 			dev->do_ioctl = NULL;
+#endif
 			dev->set_multicast_list = &streamer_set_rx_mode;
 			dev->get_stats = &streamer_get_stats;
 			dev->set_mac_address = &streamer_set_mac_address;
@@ -303,6 +328,27 @@
 
   spin_lock_init(&streamer_priv->streamer_lock);
   
+  pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cls);
+  cls <<= 2;
+  if (cls != SMP_CACHE_BYTES) {
+         printk(KERN_INFO "  PCI cache line size set incorrectly "
+                "(%i bytes) by BIOS/FW, ", cls);
+         if (cls > SMP_CACHE_BYTES)
+                printk("expecting %i\n", SMP_CACHE_BYTES);
+         else {
+                printk("correcting to %i\n", SMP_CACHE_BYTES);
+                pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+                                      SMP_CACHE_BYTES >> 2);
+         }
+  }
+
+  pci_read_config_word (pdev, PCI_COMMAND, &pcr);
+
+  pcr |= (PCI_COMMAND_INVALIDATE | PCI_COMMAND_SERR);
+
+  pci_write_config_word (pdev, PCI_COMMAND, pcr);
+  pci_read_config_word (pdev, PCI_COMMAND, &pcr);
+
   printk("%s \n", version);
   printk("%s: %s. I/O at %hx, MMIO at %p, using irq %d\n",dev->name,
 	 streamer_priv->streamer_card_name,
@@ -403,6 +449,7 @@
 	printk("GPR: %x\n", readw(streamer_mmio + GPR));
 	printk("SISRMASK: %x\n", readw(streamer_mmio + SISR_MASK));
 #endif
+	writew(readw(streamer_mmio + BCTL) | (BCTL_RX_FIFO_8 | BCTL_TX_FIFO_8), streamer_mmio + BCTL );
 
 	if (streamer_priv->streamer_ring_speed == 0) {	/* Autosense */
 		writew(readw(streamer_mmio + GPR) | GPR_AUTOSENSE,
@@ -558,8 +605,6 @@
 	do {
 		int i;
 
-		save_flags(flags);
-		cli();
 		for (i = 0; i < SRB_COMMAND_SIZE; i += 2) {
 			writew(0, streamer_mmio + LAPDINC);
 		}
@@ -599,11 +644,12 @@
 		}
 		printk("\n");
 #endif
-
+		spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
 		streamer_priv->srb_queued = 1;
 
 		/* signal solo that SRB command has been issued */
 		writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
+		spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags);
 
 		while (streamer_priv->srb_queued) {
 			interruptible_sleep_on_timeout(&streamer_priv->srb_wait, 5 * HZ);
@@ -617,7 +663,6 @@
 				break;
 			}
 		}
-		restore_flags(flags);
 
 #if STREAMER_DEBUG
 		printk("SISR_MASK: %x\n", readw(streamer_mmio + SISR_MASK));
@@ -767,9 +812,12 @@
 		streamer_priv->streamer_tx_ring[i].bufcnt_framelen = 0;
 		streamer_priv->streamer_tx_ring[i].buffer = 0;
 		streamer_priv->streamer_tx_ring[i].buflen = 0;
+		streamer_priv->streamer_tx_ring[i].rsvd1 = 0;
+		streamer_priv->streamer_tx_ring[i].rsvd2 = 0;
+		streamer_priv->streamer_tx_ring[i].rsvd3 = 0;
 	}
 	streamer_priv->streamer_tx_ring[STREAMER_TX_RING_SIZE - 1].forward =
-					virt_to_bus(&streamer_priv->streamer_tx_ring[0]);;
+					virt_to_bus(&streamer_priv->streamer_tx_ring[0]);
 
 	streamer_priv->free_tx_ring_entries = STREAMER_TX_RING_SIZE;
 	streamer_priv->tx_ring_free = 0;	/* next entry in tx ring to use */
@@ -941,37 +989,30 @@
 	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
 	__u16 sisr;
 	__u16 misr;
-	__u16 sisrmask;
+	u8 max_intr = MAX_INTR;
 
-	sisrmask = SISR_MI;
-	writew(~sisrmask, streamer_mmio + SISR_MASK_RUM);
+	spin_lock(&streamer_priv->streamer_lock);
 	sisr = readw(streamer_mmio + SISR);
-	writew(~sisr, streamer_mmio + SISR_RUM);
-	misr = readw(streamer_mmio + MISR_RUM);
-	writew(~misr, streamer_mmio + MISR_RUM);
 
-	if (!sisr) 
-	{		/* Interrupt isn't for us */
-  	        writew(~misr,streamer_mmio+MISR_RUM);
-		return;
-	}
+	while((sisr & (SISR_MI | SISR_SRB_REPLY | SISR_ADAPTER_CHECK | SISR_ASB_FREE | 
+		       SISR_ARB_CMD | SISR_TRB_REPLY | SISR_PAR_ERR | SISR_SERR_ERR))
+               && (max_intr > 0)) {
 
-	spin_lock(&streamer_priv->streamer_lock);
+		if(sisr & SISR_PAR_ERR) {
+			writew(~SISR_PAR_ERR, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
+		}
 
-	if ((sisr & (SISR_SRB_REPLY | SISR_ADAPTER_CHECK | SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY))
-	    || (misr & (MISR_TX2_EOF | MISR_RX_NOBUF | MISR_RX_EOF))) {
-		if (sisr & SISR_SRB_REPLY) {
-			if (streamer_priv->srb_queued == 1) {
-				wake_up_interruptible(&streamer_priv->srb_wait);
-			} else if (streamer_priv->srb_queued == 2) {
-				streamer_srb_bh(dev);
-			}
-			streamer_priv->srb_queued = 0;
+		else if(sisr & SISR_SERR_ERR) {
+			writew(~SISR_SERR_ERR, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
 		}
-		/* SISR_SRB_REPLY */
+
+		else if(sisr & SISR_MI) {
+			misr = readw(streamer_mmio + MISR_RUM);
+
 		if (misr & MISR_TX2_EOF) {
-			while (streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) 
-			{
+				while(streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) {
 				streamer_priv->tx_ring_last_status = (streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1);
 				streamer_priv->free_tx_ring_entries++;
 				streamer_priv->streamer_stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
@@ -981,6 +1022,9 @@
 				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].status = 0;
 				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].bufcnt_framelen = 0;
 				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buflen = 0;
+				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd1 = 0;
+				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd2 = 0;
+				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd3 = 0;
 			}
 			netif_wake_queue(dev);
 		}
@@ -989,7 +1033,30 @@
 			streamer_rx(dev);
 		}
 		/* MISR_RX_EOF */
-		if (sisr & SISR_ADAPTER_CHECK) {
+
+			if (misr & MISR_RX_NOBUF) {
+				/* According to the documentation, we don't have to do anything,  
+                                 * but trapping it keeps it out of /var/log/messages.  
+                                 */
+			}		/* SISR_RX_NOBUF */
+
+			writew(~misr, streamer_mmio + MISR_RUM);
+			(void)readw(streamer_mmio + MISR_RUM);
+		}
+
+		else if (sisr & SISR_SRB_REPLY) {
+			if (streamer_priv->srb_queued == 1) {
+				wake_up_interruptible(&streamer_priv->srb_wait);
+			} else if (streamer_priv->srb_queued == 2) {
+				streamer_srb_bh(dev);
+			}
+			streamer_priv->srb_queued = 0;
+
+			writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
+		}
+
+		else if (sisr & SISR_ADAPTER_CHECK) {
 			printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
 			writel(readl(streamer_mmio + LAPWWO), streamer_mmio + LAPA);
 			printk(KERN_WARNING "%s: Words %x:%x:%x:%x:\n",
@@ -1001,38 +1068,37 @@
 		}
 
 		/* SISR_ADAPTER_CHECK */
-		if (sisr & SISR_ASB_FREE) {
+		else if (sisr & SISR_ASB_FREE) {
 			/* Wake up anything that is waiting for the asb response */
 			if (streamer_priv->asb_queued) {
 				streamer_asb_bh(dev);
 			}
+			writew(~SISR_ASB_FREE, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
 		}
 		/* SISR_ASB_FREE */
-		if (sisr & SISR_ARB_CMD) {
+		else if (sisr & SISR_ARB_CMD) {
 			streamer_arb_cmd(dev);
+			writew(~SISR_ARB_CMD, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
 		}
 		/* SISR_ARB_CMD */
-		if (sisr & SISR_TRB_REPLY) {
+		else if (sisr & SISR_TRB_REPLY) {
 			/* Wake up anything that is waiting for the trb response */
 			if (streamer_priv->trb_queued) {
 				wake_up_interruptible(&streamer_priv->
 						      trb_wait);
 			}
 			streamer_priv->trb_queued = 0;
+			writew(~SISR_TRB_REPLY, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
 		}
 		/* SISR_TRB_REPLY */
-		if (misr & MISR_RX_NOBUF) {
-			/* According to the documentation, we don't have to do anything, but trapping it keeps it out of
-			   /var/log/messages.  */
-		}		/* SISR_RX_NOBUF */
-	} else {
-		printk(KERN_WARNING "%s: Unexpected interrupt: %x\n",
-		       dev->name, sisr);
-		printk(KERN_WARNING "%s: SISR_MASK: %x\n", dev->name,
-		       readw(streamer_mmio + SISR_MASK));
-	}			/* One if the interrupts we want */
 
-	writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
+		sisr = readw(streamer_mmio + SISR);
+		max_intr--;
+	} /* while() */		
+
 	spin_unlock(&streamer_priv->streamer_lock) ; 
 }
 
@@ -1044,13 +1110,16 @@
 	unsigned long flags ;
 
 	spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
-	netif_stop_queue(dev);
 
 	if (streamer_priv->free_tx_ring_entries) {
 		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0;
-		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00010000 | skb->len;
+		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len;
 		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer = virt_to_bus(skb->data);
+		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len;
+		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0;
+		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0;
 		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buflen = skb->len;
+
 		streamer_priv->tx_ring_skb[streamer_priv->tx_ring_free] = skb;
 		streamer_priv->free_tx_ring_entries--;
 #if STREAMER_DEBUG_PACKETS
@@ -1067,12 +1136,13 @@
 #endif
 
 		writel(virt_to_bus (&streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free]),streamer_mmio + TX2LFDA);
+		(void)readl(streamer_mmio + TX2LFDA);
 
 		streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1);
-		netif_wake_queue(dev);
 		spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
 		return 0;
 	} else {
+	        netif_stop_queue(dev);
 	        spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
 		return 1;
 	}
@@ -1092,12 +1162,13 @@
 	writew(htons(SRB_CLOSE_ADAPTER << 8),streamer_mmio+LAPDINC);
 	writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
 
 	streamer_priv->srb_queued = 1;
 	writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
 
+	spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags);
+
 	while (streamer_priv->srb_queued) 
 	{
 		interruptible_sleep_on_timeout(&streamer_priv->srb_wait,
@@ -1114,7 +1185,6 @@
 		}
 	}
 
-	restore_flags(flags);
 	streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1);
 
 	for (i = 0; i < STREAMER_RX_RING_SIZE; i++) {
@@ -1808,6 +1878,64 @@
 #endif
 #endif
 
+#if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static int streamer_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+        int i;
+	struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv;
+	u8 *streamer_mmio = streamer_priv->streamer_mmio;
+
+	switch(cmd) {
+	case IOCTL_SISR_MASK:
+		writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
+		break;
+	case IOCTL_SPIN_LOCK_TEST:
+	        printk(KERN_INFO "spin_lock() called.\n");
+		spin_lock(&streamer_priv->streamer_lock);
+		spin_unlock(&streamer_priv->streamer_lock);
+		printk(KERN_INFO "spin_unlock() finished.\n");
+		break;
+	case IOCTL_PRINT_BDAS:
+	        printk(KERN_INFO "bdas: RXBDA: %x RXLBDA: %x TX2FDA: %x TX2LFDA: %x\n",
+		       readw(streamer_mmio + RXBDA),
+		       readw(streamer_mmio + RXLBDA),
+		       readw(streamer_mmio + TX2FDA),
+		       readw(streamer_mmio + TX2LFDA));
+		break;
+	case IOCTL_PRINT_REGISTERS:
+	        printk(KERN_INFO "registers:\n");
+		printk(KERN_INFO "SISR: %04x MISR: %04x LISR: %04x BCTL: %04x BMCTL: %04x\nmask  %04x mask  %04x\n", 
+		       readw(streamer_mmio + SISR),
+		       readw(streamer_mmio + MISR_RUM),
+		       readw(streamer_mmio + LISR),
+		       readw(streamer_mmio + BCTL),
+		       readw(streamer_mmio + BMCTL_SUM),
+		       readw(streamer_mmio + SISR_MASK),
+		       readw(streamer_mmio + MISR_MASK));
+		break;
+	case IOCTL_PRINT_RX_BUFS:
+	        printk(KERN_INFO "Print rx bufs:\n");
+		for(i=0; i<STREAMER_RX_RING_SIZE; i++)
+		        printk(KERN_INFO "rx_ring %d status: 0x%x\n", i, 
+			       streamer_priv->streamer_rx_ring[i].status);
+		break;
+	case IOCTL_PRINT_TX_BUFS:
+	        printk(KERN_INFO "Print tx bufs:\n");
+		for(i=0; i<STREAMER_TX_RING_SIZE; i++)
+		        printk(KERN_INFO "tx_ring %d status: 0x%x\n", i, 
+			       streamer_priv->streamer_tx_ring[i].status);
+		break;
+	case IOCTL_RX_CMD:
+	        streamer_rx(dev);
+		printk(KERN_INFO "Sent rx command.\n");
+		break;
+	default:
+	        printk(KERN_INFO "Bad ioctl!\n");
+	}
+	return 0;
+}
+#endif
+
 static struct pci_driver streamer_pci_driver = {
   name:       "lanstreamer",
   id_table:   streamer_pci_tbl,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/lanstreamer.h linux/drivers/net/tokenring/lanstreamer.h
--- linux.orig/drivers/net/tokenring/lanstreamer.h	2001-03-20 20:04:59.000000000 +0000
+++ linux/drivers/net/tokenring/lanstreamer.h	2002-07-20 01:08:30.000000000 +0000
@@ -56,11 +56,36 @@
  * 
  *  12/10/99 - Alpha Release 0.1.0
  *            First release to the public
+ *  08/15/01 - Added ioctl() definitions and others - Kent Yoder <yoder1@us.ibm.com>
  *
  */
 
+#if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include <asm/ioctl.h>
+#define IOCTL_PRINT_RX_BUFS   SIOCDEVPRIVATE
+#define IOCTL_PRINT_TX_BUFS   SIOCDEVPRIVATE+1
+#define IOCTL_RX_CMD          SIOCDEVPRIVATE+2
+#define IOCTL_TX_CMD          SIOCDEVPRIVATE+3
+#define IOCTL_PRINT_REGISTERS SIOCDEVPRIVATE+4
+#define IOCTL_PRINT_BDAS      SIOCDEVPRIVATE+5
+#define IOCTL_SPIN_LOCK_TEST  SIOCDEVPRIVATE+6
+#define IOCTL_SISR_MASK       SIOCDEVPRIVATE+7
+#endif
+
+/* MAX_INTR - the maximum number of times we can loop
+ * inside the interrupt function before returning
+ * control to the OS (maximum value is 256)
+ */
+#define MAX_INTR 5
+
+#define CLS 0x0C
+#define MLR 0x86
+#define LTR 0x0D
+
 #define BCTL 0x60
 #define BCTL_SOFTRESET (1<<15)
+#define BCTL_RX_FIFO_8 (1<<1)
+#define BCTL_TX_FIFO_8 (1<<3)
 
 #define GPR 0x4a
 #define GPR_AUTOSENSE (1<<2)
@@ -89,6 +114,7 @@
 #define SISR_MASK_RUM 0x58
 
 #define SISR_MI (1<<15)
+#define SISR_SERR_ERR (1<<14)
 #define SISR_TIMER (1<<11)
 #define SISR_LAP_PAR_ERR (1<<10)
 #define SISR_LAP_ACC_ERR (1<<9)
@@ -218,7 +244,13 @@
 /* Streamer defaults for buffers */
 
 #define STREAMER_RX_RING_SIZE 16	/* should be a power of 2 */
-#define STREAMER_TX_RING_SIZE 8	/* should be a power of 2 */
+/* Setting the number of TX descriptors to 1 is a workaround for an
+ * undocumented hardware problem with the lanstreamer board. Setting
+ * this to something higher may slightly increase the throughput you
+ * can get from the card, but at the risk of locking up the box. - 
+ * <yoder1@us.ibm.com>
+ */
+#define STREAMER_TX_RING_SIZE 1	/* should be a power of 2 */
 
 #define PKT_BUF_SZ 4096		/* Default packet size */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/olympic.c linux/drivers/net/tokenring/olympic.c
--- linux.orig/drivers/net/tokenring/olympic.c	2001-12-21 17:41:54.000000000 +0000
+++ linux/drivers/net/tokenring/olympic.c	2002-07-20 01:08:29.000000000 +0000
@@ -50,10 +50,16 @@
  *	      adapter when live does not take the system down with it.
  * 
  * 06/02/01 - Clean up, copy skb for small packets
+ * 
+ * 06/22/01 - Add EISR error handling routines 
+ *
+ * 07/19/01 - Improve bad LAA reporting, strip out freemem
+ *	      into a separate function, its called from 3 
+ *	      different places now. 
+ * 02/09/01 - Replaced sleep_on. 
  *
  *  To Do:
  *
- *	     Complete full Cardbus / hot-swap support.
  *	     Wake on lan	
  * 
  *  If Problems do Occur
@@ -105,7 +111,7 @@
  */
 
 static char version[] __devinitdata = 
-"Olympic.c v0.9.7 6/02/01 - Peter De Schrijver & Mike Phillips" ; 
+"Olympic.c v1.0.0 2/9/02  - Peter De Schrijver & Mike Phillips" ; 
 
 static char *open_maj_error[]  = {"No error", "Lobe Media Test", "Physical Insertion",
 				   "Address Verification", "Neighbor Notification (Ring Poll)",
@@ -172,6 +178,7 @@
 static int olympic_xmit(struct sk_buff *skb, struct net_device *dev);
 static int olympic_close(struct net_device *dev);
 static void olympic_set_rx_mode(struct net_device *dev);
+static void olympic_freemem(struct net_device *dev) ;  
 static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static struct net_device_stats * olympic_get_stats(struct net_device *dev);
 static int olympic_set_mac_address(struct net_device *dev, void *addr) ; 
@@ -396,6 +403,8 @@
 	char open_error[255] ; 
 	int i, open_finished = 1 ;
 
+	DECLARE_WAITQUEUE(wait,current) ; 
+
 	if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) {
 		return -EAGAIN;
 	}
@@ -424,8 +433,6 @@
 	do {
 		int i;
 
-		save_flags(flags);
-		cli();
 		for(i=0;i<SRB_COMMAND_SIZE;i+=4)
 			writel(0,init_srb+i);
 		if(SRB_COMMAND_SIZE & 2)
@@ -441,8 +448,12 @@
 			writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8);
 		else
 			writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8);
+	
+		/* Test OR of first 3 bytes as its totally possible for 
+		 * someone to set the first 2 bytes to be zero, although this 
+		 * is an error, the first byte must have bit 6 set to 1  */
 
-		if (olympic_priv->olympic_laa[0]) {
+		if (olympic_priv->olympic_laa[0] | olympic_priv->olympic_laa[1] | olympic_priv->olympic_laa[2]) {
 			writeb(olympic_priv->olympic_laa[0],init_srb+12);
 			writeb(olympic_priv->olympic_laa[1],init_srb+13);
 			writeb(olympic_priv->olympic_laa[2],init_srb+14);
@@ -452,14 +463,20 @@
 			memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ;  
 		} 	
 		writeb(1,init_srb+30);
-	
+
+		spin_lock_irqsave(&olympic_priv->olympic_lock,flags);	
 		olympic_priv->srb_queued=1;
 
 		writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
+		spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
 
 		t = jiffies ; 
+	
+		add_wait_queue(&olympic_priv->srb_wait,&wait) ;
+		set_current_state(TASK_INTERRUPTIBLE) ; 
+ 
  		while(olympic_priv->srb_queued) {        
-        		interruptible_sleep_on_timeout(&olympic_priv->srb_wait, 60*HZ);
+			schedule() ; 
         		if(signal_pending(current))	{            
 				printk(KERN_WARNING "%s: Signal received in open.\n",
                 			dev->name);
@@ -474,8 +491,11 @@
 				olympic_priv->srb_queued=0;
 				break ; 
 			} 
+			set_current_state(TASK_INTERRUPTIBLE) ; 
     		}
-		restore_flags(flags);
+		remove_wait_queue(&olympic_priv->srb_wait,&wait) ; 
+		set_current_state(TASK_RUNNING) ; 
+
 #if OLYMPIC_DEBUG
 		printk("init_srb(%p): ",init_srb);
 		for(i=0;i<20;i++)
@@ -515,6 +535,17 @@
 					return -EIO ; 
  
 				}	/* if autosense && open_finished */
+			} else if (init_srb[2] == 0x32) {
+				printk(KERN_WARNING "%s: Invalid LAA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+					dev->name, 
+					olympic_priv->olympic_laa[0],
+					olympic_priv->olympic_laa[1],
+					olympic_priv->olympic_laa[2],
+					olympic_priv->olympic_laa[3],
+					olympic_priv->olympic_laa[4],
+					olympic_priv->olympic_laa[5]) ; 
+				free_irq(dev->irq,dev) ; 
+				return -EIO ; 
 			} else {  
 				printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name,init_srb[2]);
 				free_irq(dev->irq, dev);
@@ -598,8 +629,7 @@
 	printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7])  );
 
 	printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
-	printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr =
-%08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; 
+	printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; 
 #endif
 
 	writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
@@ -634,7 +664,10 @@
 	olympic_priv->tx_ring_free=0; /* next entry in tx ring to use */
 	olympic_priv->tx_ring_last_status=OLYMPIC_TX_RING_SIZE-1; /* last processed tx status */
 
-	writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE,olympic_mmio+SISR_MASK_SUM);
+	writel(0xffffffff, olympic_mmio+EISR_RWM) ; /* clean the eisr */
+	writel(0,olympic_mmio+EISR) ; 
+	writel(EISR_MASK_OPTIONS,olympic_mmio+EISR_MASK) ; /* enables most of the TX error interrupts */
+	writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE | SISR_ERR,olympic_mmio+SISR_MASK_SUM);
 
 #if OLYMPIC_DEBUG 
 	printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
@@ -822,6 +855,35 @@
 
 }
 
+static void olympic_freemem(struct net_device *dev) 
+{ 
+	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
+	int i;
+			
+	for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
+		dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
+		if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
+			pci_unmap_single(olympic_priv->pdev, 
+			le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
+			olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
+		}
+		olympic_priv->rx_status_last_received++;
+		olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
+	}
+	/* unmap rings */
+	pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, 
+		sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
+	pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
+		sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
+
+	pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, 
+		sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
+	pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, 
+		sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
+
+	return ; 
+}
+ 
 static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
 {
 	struct net_device *dev= (struct net_device *)dev_id;
@@ -842,9 +904,33 @@
 
 	spin_lock(&olympic_priv->olympic_lock);
 
+	/* Hotswap gives us this on removal */
+	if (sisr == 0xffffffff) { 
+		printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ; 
+		olympic_freemem(dev) ; 
+		free_irq(dev->irq, dev) ;
+		dev->stop = NULL ;  
+		spin_unlock(&olympic_priv->olympic_lock) ; 
+		return ;
+	} 
+		
 	if (sisr & (SISR_SRB_REPLY | SISR_TX1_EOF | SISR_RX_STATUS | SISR_ADAPTER_CHECK |  
-			SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF)) {  
+			SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF | SISR_ERR)) {  
 	
+		/* If we ever get this the adapter is seriously dead. Only a reset is going to 
+		 * bring it back to life. We're talking pci bus errors and such like :( */ 
+		if((sisr & SISR_ERR) && (readl(olympic_mmio+EISR) & EISR_MASK_OPTIONS)) {
+			printk(KERN_ERR "Olympic: EISR Error, EISR=%08x\n",readl(olympic_mmio+EISR)) ; 
+			printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ; 
+			printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ; 
+			printk(KERN_ERR "or the linux-tr mailing list.\n") ; 
+			olympic_freemem(dev) ; 
+			free_irq(dev->irq, dev) ;
+			dev->stop = NULL ;  
+			spin_unlock(&olympic_priv->olympic_lock) ; 
+			return ;
+		} /* SISR_ERR */
+
 		if(sisr & SISR_SRB_REPLY) {
 			if(olympic_priv->srb_queued==1) {
 				wake_up_interruptible(&olympic_priv->srb_wait);
@@ -878,34 +964,12 @@
 		} /* SISR_RX_STATUS */
 	
 		if (sisr & SISR_ADAPTER_CHECK) {
-			int i ; 
 			netif_stop_queue(dev);
 			printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
-			writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
-			adapter_check_area = (u8 *)(olympic_mmio+LAPWWO) ; 
+			writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA);
+			adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ;
 			printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ; 
-			/* The adapter is effectively dead, clean up and exit */
-			for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
-				dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
-				if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
-					pci_unmap_single(olympic_priv->pdev, 
-						le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
-						olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
-				}
-				olympic_priv->rx_status_last_received++;
-				olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
-			}
-			/* unmap rings */
-			pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, 
-				sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
-			pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
-				sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
-
-			pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, 
-				sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
-			pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, 
-				sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
-
+			olympic_freemem(dev) ;
 			free_irq(dev->irq, dev) ;
 			dev->stop = NULL ;  
 			spin_unlock(&olympic_priv->olympic_lock) ; 
@@ -980,7 +1044,8 @@
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
     	u8 *olympic_mmio=olympic_priv->olympic_mmio,*srb;
 	unsigned long t,flags;
-	int i;
+
+	DECLARE_WAITQUEUE(wait,current) ; 
 
 	netif_stop_queue(dev);
 	
@@ -991,16 +1056,19 @@
 	writeb(0,srb+1);
 	writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
 
-	save_flags(flags);
-	cli();	
-
+	spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
 	olympic_priv->srb_queued=1;
 
 	writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
+	spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
 	
 	t = jiffies ; 
+
+	add_wait_queue(&olympic_priv->srb_wait,&wait) ;
+	set_current_state(TASK_INTERRUPTIBLE) ; 
+
 	while(olympic_priv->srb_queued) {
-	        interruptible_sleep_on_timeout(&olympic_priv->srb_wait, jiffies+60*HZ);
+		schedule() ; 
         	if(signal_pending(current))	{            
 			printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
             		printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR));
@@ -1012,32 +1080,15 @@
 			olympic_priv->srb_queued=0;
 			break ; 
 		} 
+		set_current_state(TASK_INTERRUPTIBLE) ; 
     	}
+	remove_wait_queue(&olympic_priv->srb_wait,&wait) ; 
+	set_current_state(TASK_RUNNING) ; 
 
-	restore_flags(flags) ; 
 	olympic_priv->rx_status_last_received++;
 	olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
-	
-	for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
-		dev_kfree_skb(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
-		if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
-			pci_unmap_single(olympic_priv->pdev, 
-				le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
-				olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
-		}
-		olympic_priv->rx_status_last_received++;
-		olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
-	}
-	/* unmap rings */
-	pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, 
-		sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
-	pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
-		sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
 
-	pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, 
-		sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
-	pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, 
-		sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
+	olympic_freemem(dev) ; 	
 
 	/* reset tx/rx fifo's and busmaster logic */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tokenring/olympic.h linux/drivers/net/tokenring/olympic.h
--- linux.orig/drivers/net/tokenring/olympic.h	2001-06-20 18:13:18.000000000 +0000
+++ linux/drivers/net/tokenring/olympic.h	2002-07-20 01:08:35.000000000 +0000
@@ -79,6 +79,7 @@
 #define EISR 0x34
 #define EISR_RWM 0x38
 #define EISR_MASK 0x3c
+#define EISR_MASK_OPTIONS 0x001FFF7F
 
 #define LAPA 0x60
 #define LAPWWO 0x64
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tulip/21142.c linux/drivers/net/tulip/21142.c
--- linux.orig/drivers/net/tulip/21142.c	2001-11-09 21:45:35.000000000 +0000
+++ linux/drivers/net/tulip/21142.c	2002-07-20 01:08:28.000000000 +0000
@@ -167,8 +167,9 @@
 			int i;
 			for (i = 0; i < tp->mtable->leafcount; i++)
 				if (tp->mtable->mleaf[i].media == dev->if_port) {
+					int startup = ! ((tp->chip_id == DC21143 && tp->revision == 65));
 					tp->cur_index = i;
-					tulip_select_media(dev, 1);
+					tulip_select_media(dev, startup);
 					setup_done = 1;
 					break;
 				}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tulip/ChangeLog linux/drivers/net/tulip/ChangeLog
--- linux.orig/drivers/net/tulip/ChangeLog	2002-02-25 19:38:00.000000000 +0000
+++ linux/drivers/net/tulip/ChangeLog	2002-07-20 01:08:27.000000000 +0000
@@ -1,3 +1,20 @@
+2002-05-11  Juan Quintela  <quintela@mandrakesoft.com>
+
+	* 21142.c (t21142_lnk_change): Revert earlier patch
+	to always reset phy; only conditionally do so now.
+
+2002-05-03  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip_core (tulip_pci_tbl): Add new "comet"
+	pci id.  Contributed by Ohta Kyuma.
+
+2002-03-07  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip_core (tulip_mwi_config): Use new PCI API functions
+	for enabling and disabled Memory-Write-Invalidate
+	PCI transaction.
+	Fix bugs in tulip MWI config also.
+
 2002-02-07  Uwe Bonnes  <bon@elektron.ikp.physik.tu-darmstadt.de>
 
 	* tulip_core (tulip_pci_tbl[]):
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tulip/media.c linux/drivers/net/tulip/media.c
--- linux.orig/drivers/net/tulip/media.c	2001-07-18 01:53:55.000000000 +0000
+++ linux/drivers/net/tulip/media.c	2002-07-20 01:08:29.000000000 +0000
@@ -389,9 +389,9 @@
 		if (tulip_media_cap[dev->if_port] & MediaIsMII) {
 			new_csr6 = 0x020E0000;
 		} else if (tulip_media_cap[dev->if_port] & MediaIsFx) {
-			new_csr6 = 0x028600000;
+			new_csr6 = 0x02860000;
 		} else
-			new_csr6 = 0x038600000;
+			new_csr6 = 0x03860000;
 		if (tulip_debug > 1)
 			printk(KERN_DEBUG "%s: No media description table, assuming "
 				   "%s transceiver, CSR12 %2.2x.\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- linux.orig/drivers/net/tulip/tulip_core.c	2002-02-25 19:38:00.000000000 +0000
+++ linux/drivers/net/tulip/tulip_core.c	2002-07-20 01:08:38.000000000 +0000
@@ -2,7 +2,7 @@
 
 /*
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
-	Copyright 2000,2001  The Linux Kernel Team
+	Copyright 2000-2002  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
@@ -15,8 +15,8 @@
 */
 
 #define DRV_NAME	"tulip"
-#define DRV_VERSION	"0.9.15-pre9"
-#define DRV_RELDATE	"Nov 6, 2001"
+#define DRV_VERSION	"0.9.15-pre11"
+#define DRV_RELDATE	"May 11, 2002"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/crc32.h>
 #include <asm/unaligned.h>
 #include <asm/uaccess.h>
 
@@ -93,6 +94,8 @@
 static int csr0 = 0x01A00000 | 0x9000;
 #elif defined(__arm__) || defined(__sh__)
 static int csr0 = 0x01A00000 | 0x4800;
+#elif defined(__mips__)
+static int csr0 = 0x00200000 | 0x4000;
 #else
 #warning Processor architecture undefined!
 static int csr0 = 0x00A00000 | 0x4800;
@@ -205,6 +208,7 @@
 	{ 0x1317, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1317, 0x0985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1317, 0x1985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x1317, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x13D1, 0xAB02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x13D1, 0xAB03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x13D1, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
@@ -1036,41 +1040,6 @@
    new frame, not around filling tp->setup_frame.  This is non-deterministic
    when re-entered but still correct. */
 
-/* The little-endian AUTODIN32 ethernet CRC calculation.
-   N.B. Do not use for bulk data, use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline u32 ether_crc_le(int length, unsigned char *data)
-{
-	u32 crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
-    int crc = -1;
-
-    while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
-			crc = (crc << 1) ^
-				((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
-    }
-    return crc;
-}
-
 #undef set_bit_le
 #define set_bit_le(i,p) do { ((char *)(p))[(i)/8] |= (1<<((i)%8)); } while(0)
 
@@ -1263,7 +1232,7 @@
 {
 	struct tulip_private *tp = dev->priv;
 	u8 cache;
-	u16 pci_command, new_command;
+	u16 pci_command;
 	u32 csr0;
 
 	if (tulip_debug > 3)
@@ -1271,24 +1240,6 @@
 
 	tp->csr0 = csr0 = 0;
 
-	/* check for sane cache line size. from acenic.c. */
-	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
-	if ((cache << 2) != SMP_CACHE_BYTES) {
-		printk(KERN_WARNING "%s: PCI cache line size set incorrectly "
-		       "(%i bytes) by BIOS/FW, correcting to %i\n",
-		       pdev->slot_name, (cache << 2), SMP_CACHE_BYTES);
-		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
-				      SMP_CACHE_BYTES >> 2);
-		udelay(5);
-	}
-
-	/* read cache line size again, hardware may not have accepted
-	 * our cache line size change
-	 */
-	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
-	if (!cache)
-		goto out;
-
 	/* if we have any cache line size at all, we can do MRM */
 	csr0 |= MRM;
 
@@ -1299,15 +1250,19 @@
 	/* set or disable MWI in the standard PCI command bit.
 	 * Check for the case where  mwi is desired but not available
 	 */
+	if (csr0 & MWI)	pci_set_mwi(pdev);
+	else		pci_clear_mwi(pdev);
+
+	/* read result from hardware (in case bit refused to enable) */
 	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-	if (csr0 & MWI)	new_command = pci_command | PCI_COMMAND_INVALIDATE;
-	else		new_command = pci_command & ~PCI_COMMAND_INVALIDATE;
-	if (new_command != pci_command) {
-		pci_write_config_word(pdev, PCI_COMMAND, new_command);
-		udelay(5);
-		pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-		if ((csr0 & MWI) && (!(pci_command & PCI_COMMAND_INVALIDATE)))
-			csr0 &= ~MWI;
+	if ((csr0 & MWI) && (!(pci_command & PCI_COMMAND_INVALIDATE)))
+		csr0 &= ~MWI;
+
+	/* if cache line size hardwired to zero, no MWI */
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
+	if ((csr0 & MWI) && (cache == 0)) {
+		csr0 &= ~MWI;
+		pci_clear_mwi(pdev);
 	}
 
 	/* assign per-cacheline-size cache alignment and
@@ -1324,20 +1279,29 @@
 		csr0 |= MRL | (3 << CALShift) | (32 << BurstLenShift);
 		break;
 	default:
-		goto out;
+		cache = 0;
+		break;
 	}
 
-	tp->csr0 = csr0;
-	goto out;
+	/* if we have a good cache line size, we by now have a good
+	 * csr0, so save it and exit
+	 */
+	if (cache)
+		goto out;
 
+	/* we don't have a good csr0 or cache line size, disable MWI */
 	if (csr0 & MWI) {
-		pci_command &= ~PCI_COMMAND_INVALIDATE;
-		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+		pci_clear_mwi(pdev);
 		csr0 &= ~MWI;
 	}
-	tp->csr0 = csr0 | (8 << BurstLenShift) | (1 << CALShift);
+
+	/* sane defaults for burst length and cache alignment
+	 * originally from de4x5 driver
+	 */
+	csr0 |= (8 << BurstLenShift) | (1 << CALShift);
 
 out:
+	tp->csr0 = csr0;
 	if (tulip_debug > 2)
 		printk(KERN_DEBUG "%s: MWI config cacheline=%d, csr0=%08x\n",
 		       pdev->slot_name, cache, csr0);
@@ -1604,6 +1568,16 @@
                        tp->flags &= ~HAS_MEDIA_TABLE;
                }
 #endif
+#ifdef CONFIG_MIPS_COBALT
+               if ((pdev->bus->number == 0) && 
+                   ((PCI_SLOT(pdev->devfn) == 7) ||
+                    (PCI_SLOT(pdev->devfn) == 12))) {
+                       /* Cobalt MAC address in first EEPROM locations. */
+                       sa_offset = 0;
+                       /* No media table either */
+                       tp->flags &= ~HAS_MEDIA_TABLE;
+               }
+#endif
 		for (i = 0; i < 6; i ++) {
 			dev->dev_addr[i] = ee_data[i + sa_offset];
 			sum += ee_data[i + sa_offset];
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/tun.c linux/drivers/net/tun.c
--- linux.orig/drivers/net/tun.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/tun.c	2002-07-20 01:08:35.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *  TUN - Universal TUN/TAP device driver.
- *  Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
+ *  Copyright (C) 1999-2002 Maxim Krasnyansky <maxk@qualcomm.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
@@ -12,7 +12,7 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *  GNU General Public License for more details.
  *
- *  $Id: tun.c,v 1.12 2001/03/08 03:29:27 maxk Exp $
+ *  $Id: tun.c,v 1.15 2002/03/01 02:44:24 maxk Exp $
  */
 
 /*
@@ -20,7 +20,7 @@
  *    Modifications for 2.3.99-pre5 kernel.
  */
 
-#define TUN_VER "1.4"
+#define TUN_VER "1.5"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -181,19 +181,17 @@
 }
 
 /* Get packet from user space buffer(already verified) */
-static __inline__ ssize_t tun_get_user(struct tun_struct *tun, const char *buf, size_t count)
+static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
 {
 	struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
-	register const char *ptr = buf; 
-	register int len = count;
 	struct sk_buff *skb;
+	size_t len = count;
 
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) < 0)
 			return -EINVAL;
 
-		copy_from_user(&pi, ptr, sizeof(pi));
-		ptr += sizeof(pi);
+		memcpy_fromiovec((void *)&pi, iv, sizeof(pi));
 	}
  
 	if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
@@ -202,7 +200,7 @@
 	}
 
 	skb_reserve(skb, 2);
-	copy_from_user(skb_put(skb, len), ptr, len); 
+	memcpy_fromiovec(skb_put(skb, len), iv, len);
 
 	skb->dev = &tun->dev;
 	switch (tun->flags & TUN_TYPE_MASK) {
@@ -226,31 +224,43 @@
 	return count;
 } 
 
-/* Write */
-static ssize_t tun_chr_write(struct file * file, const char * buf, 
-			     size_t count, loff_t *pos)
+/* Writev */
+static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv, 
+			      unsigned long count, loff_t *pos)
 {
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
+	unsigned long i;
+	size_t len;
 
 	if (!tun)
 		return -EBADFD;
 
 	DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count);
 
-	if (verify_area(VERIFY_READ, buf, count))
-		return -EFAULT;
+	for (i = 0, len = 0; i < count; i++) {
+		if (verify_area(VERIFY_READ, iv[i].iov_base, iv[i].iov_len))
+			return -EFAULT;
+		len += iv[i].iov_len;
+	}
 
-	return tun_get_user(tun, buf, count);
+	return tun_get_user(tun, (struct iovec *) iv, len);
 }
 
-/* Put packet to user space buffer(already verified) */
+/* Write */
+static ssize_t tun_chr_write(struct file * file, const char * buf, 
+			     size_t count, loff_t *pos)
+{
+	struct iovec iv = { (void *) buf, count };
+	return tun_chr_writev(file, &iv, 1, pos);
+}
+
+/* Put packet to the user space buffer (already verified) */
 static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
 				       struct sk_buff *skb,
-				       char *buf, int count)
+				       struct iovec *iv, int len)
 {
 	struct tun_pi pi = { 0, skb->protocol };
-	int len = count, total = 0;
-	char *ptr = buf;
+	ssize_t total = 0;
 
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) < 0)
@@ -261,14 +271,13 @@
 			pi.flags |= TUN_PKT_STRIP;
 		}
  
-		copy_to_user(ptr, &pi, sizeof(pi));
-
+		memcpy_toiovec(iv, (void *) &pi, sizeof(pi));
 		total += sizeof(pi);
-		ptr += sizeof(pi);
 	}       
 
-	len = MIN(skb->len, len); 
-	copy_to_user(ptr, skb->data, len); 
+	len = MIN(skb->len, len);
+
+	skb_copy_datagram_iovec(skb, 0, iv, len);
 	total += len;
 
 	tun->stats.tx_packets++;
@@ -277,22 +286,29 @@
 	return total;
 }
 
-/* Read */
-static ssize_t tun_chr_read(struct file * file, char * buf, 
-			    size_t count, loff_t *pos)
+/* Readv */
+static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
+			    unsigned long count, loff_t *pos)
 {
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
 	DECLARE_WAITQUEUE(wait, current);
 	struct sk_buff *skb;
-	ssize_t ret = 0;
+	ssize_t len, ret = 0;
+	unsigned long i;
 
 	if (!tun)
 		return -EBADFD;
 
 	DBG(KERN_INFO "%s: tun_chr_read\n", tun->name);
 
+	for (i = 0, len = 0; i < count; i++) {
+		if (verify_area(VERIFY_WRITE, iv[i].iov_base, iv[i].iov_len))
+			return -EFAULT;
+		len += iv[i].iov_len;
+	}
+
 	add_wait_queue(&tun->read_wait, &wait);
-	while (count) {
+	while (len) {
 		current->state = TASK_INTERRUPTIBLE;
 
 		/* Read frames from the queue */
@@ -312,10 +328,7 @@
 		}
 		netif_start_queue(&tun->dev);
 
-		if (!verify_area(VERIFY_WRITE, buf, count))
-			ret = tun_put_user(tun, skb, buf, count);
-		else
-			ret = -EFAULT;
+		ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
 
 		kfree_skb(skb);
 		break;
@@ -327,6 +340,14 @@
 	return ret;
 }
 
+/* Read */
+static ssize_t tun_chr_read(struct file * file, char * buf, 
+			    size_t count, loff_t *pos)
+{
+	struct iovec iv = { buf, count };
+	return tun_chr_readv(file, &iv, 1, pos);
+}
+
 static int tun_set_iff(struct file *file, struct ifreq *ifr)
 {
 	struct tun_struct *tun;
@@ -546,7 +567,9 @@
 	owner:	THIS_MODULE,	
 	llseek:	no_llseek,
 	read:	tun_chr_read,
+	readv:	tun_chr_readv,
 	write:	tun_chr_write,
+	writev:	tun_chr_writev,
 	poll:	tun_chr_poll,
 	ioctl:	tun_chr_ioctl,
 	open:	tun_chr_open,
@@ -564,7 +587,7 @@
 int __init tun_init(void)
 {
 	printk(KERN_INFO "Universal TUN/TAP device driver %s " 
-	       "(C)1999-2001 Maxim Krasnyansky\n", TUN_VER);
+	       "(C)1999-2002 Maxim Krasnyansky\n", TUN_VER);
 
 	if (misc_register(&tun_miscdev)) {
 		printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- linux.orig/drivers/net/via-rhine.c	2002-02-25 19:38:00.000000000 +0000
+++ linux/drivers/net/via-rhine.c	2002-07-20 01:08:35.000000000 +0000
@@ -9,8 +9,8 @@
 	a complete program and may only be used when the entire operating
 	system is licensed under the GPL.
 
-	This driver is designed for the VIA VT86c100A Rhine-II PCI Fast Ethernet
-	controller.  It also works with the older 3043 Rhine-I chip.
+	This driver is designed for the VIA VT86C100A Rhine-I. 
+	It also works with the 6102 Rhine-II, and 6105/6105M Rhine-III.   
 
 	The author may be reached as becker@scyld.com, or C/O
 	Scyld Computing Corporation
@@ -81,11 +81,24 @@
 	- Add ethtool support
 	- Replace some MII-related magic numbers with constants
 	
+	LK1.1.14 (Ivan G.):
+ 	- fixes comments for Rhine-III
+	- removes W_MAX_TIMEOUT (unused)
+	- adds HasDavicomPhy for Rhine-I (basis: linuxfet driver; my card
+	  is R-I and has Davicom chip, flag is referenced in kernel driver)
+	- sends chip_id as a parameter to wait_for_reset since np is not
+	  initialized on first call
+	- changes mmio "else if (chip_id==VT6102)" to "else" so it will work
+	  for Rhine-III's (documentation says same bit is correct)		
+	- transmit frame queue message is off by one - fixed
+	- adds IntrNormalSummary to "Something Wicked" exclusion list
+	  so normal interrupts will not trigger the message (src: Donald Becker)
+
 */
 
 #define DRV_NAME	"via-rhine"
-#define DRV_VERSION	"1.1.13"
-#define DRV_RELDATE	"Nov-17-2001"
+#define DRV_VERSION	"1.1.14"
+#define DRV_RELDATE	"May-3-2002"
 
 
 /* A few user-configurable values.
@@ -136,9 +149,6 @@
 
 #define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
 
-/* max time out delay time */
-#define W_MAX_TIMEOUT	0x0FFFU
-
 #if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
 #warning  You must compile this file with the correct options!
 #warning  See the last lines of the source file.
@@ -161,6 +171,7 @@
 #include <linux/delay.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/crc32.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -316,7 +327,8 @@
 enum via_rhine_chips {
 	VT86C100A = 0,
 	VT6102,
-	VT3043,
+	VT6105,
+	VT6105M
 };
 
 struct via_rhine_chip_info {
@@ -341,18 +353,21 @@
 static struct via_rhine_chip_info via_rhine_chip_info[] __devinitdata =
 {
 	{ "VIA VT86C100A Rhine", RHINE_IOTYPE, 128,
-	  CanHaveMII | ReqTxAlign },
+	  CanHaveMII | ReqTxAlign | HasDavicomPhy },
 	{ "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256,
 	  CanHaveMII | HasWOL },
-	{ "VIA VT3043 Rhine",    RHINE_IOTYPE, 128,
-	  CanHaveMII | ReqTxAlign }
+	{ "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256,
+	  CanHaveMII | HasWOL },	  
+	{ "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256,
+	  CanHaveMII | HasWOL },	  	  	 
 };
 
 static struct pci_device_id via_rhine_pci_tbl[] __devinitdata =
 {
-	{0x1106, 0x6100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
+	{0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
 	{0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102},
-	{0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT3043},
+	{0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105},
+	{0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M},	
 	{0,}			/* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, via_rhine_pci_tbl);
@@ -371,6 +386,11 @@
 	StickyHW=0x83, WOLcrClr=0xA4, WOLcgClr=0xA7, PwrcsrClr=0xAC,
 };
 
+/* Bits in ConfigD (select backoff algorithm (Ethernet capture effect)) */
+enum backoff_bits {
+	BackOpt=0x01, BackAMD=0x02, BackDEC=0x04, BackRandom=0x08
+};
+
 #ifdef USE_MEM
 /* Registers we check that mmio and reg are the same. */
 int mmio_verify_registers[] = {
@@ -419,11 +439,11 @@
 	u32 next_desc;
 };
 
-/* Bits in *_desc.status */
 enum rx_status_bits {
 	RxOK=0x8000, RxWholePkt=0x0300, RxErr=0x008F
 };
 
+/* Bits in *_desc.status */
 enum desc_status_bits {
 	DescOwn=0x80000000, DescEndPacket=0x4000, DescIntr=0x1000,
 };
@@ -471,13 +491,10 @@
 	u16 chip_cmd;						/* Current setting for ChipCmd */
 
 	/* These values are keep track of the transceiver/media in use. */
-	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
-	unsigned int duplex_lock:1;
 	unsigned int default_port:4;		/* Last dev->if_port value. */
 	u8 tx_thresh, rx_thresh;
 
 	/* MII transceiver section. */
-	u16 advertising;					/* NWay media advertisement */
 	unsigned char phys[MAX_MII_CNT];			/* MII device addresses. */
 	unsigned int mii_cnt;			/* number of MIIs found, but only the first one is used */
 	u16 mii_status;						/* last read MII status */
@@ -501,15 +518,13 @@
 static int  via_rhine_close(struct net_device *dev);
 static inline void clear_tally_counters(long ioaddr);
 
-static void wait_for_reset(struct net_device *dev, char *name)
+static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
 {
-	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
-	int chip_id = np->chip_id;
 	int i;
 
-	/* 3043 may need long delay after reset (dlink) */
-	if (chip_id == VT3043 || chip_id == VT86C100A)
+	/* VT86C100A may need long delay after reset (dlink) */
+	if (chip_id == VT86C100A)
 		udelay(100);
 
 	i = 0;
@@ -530,11 +545,11 @@
 static void __devinit enable_mmio(long ioaddr, int chip_id)
 {
 	int n;
-	if (chip_id == VT3043 || chip_id == VT86C100A) {
+	if (chip_id == VT86C100A) {
 		/* More recent docs say that this bit is reserved ... */
 		n = inb(ioaddr + ConfigA) | 0x20;
 		outb(n, ioaddr + ConfigA);
-	} else if (chip_id == VT6102) {
+	} else {
 		n = inb(ioaddr + ConfigD) | 0x80;
 		outb(n, ioaddr + ConfigD);
 	}
@@ -658,7 +673,7 @@
 	writew(CmdReset, ioaddr + ChipCmd);
 
 	dev->base_addr = ioaddr;
-	wait_for_reset(dev, shortname);
+	wait_for_reset(dev, chip_id, shortname);
 
 	/* Reload the station address from the EEPROM. */
 #ifdef USE_IO
@@ -779,7 +794,7 @@
 				   (option & 0x300 ? 100 : 10),
 				   (option & 0x220 ? "full" : "half"));
 			if (np->mii_cnt)
-				mdio_write(dev, np->phys[0], 0,
+				mdio_write(dev, np->phys[0], MII_BMCR,
 						   ((option & 0x300) ? 0x2000 : 0) |  /* 100mbps? */
 						   ((option & 0x220) ? 0x0100 : 0));  /* Full duplex? */
 		}
@@ -963,9 +978,9 @@
 		writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
 
 	/* Initialize other registers. */
-	writew(0x0006, ioaddr + PCIBusConfig);	/* Tune configuration??? */
-	/* Configure the FIFO thresholds. */
-	writeb(0x20, ioaddr + TxConfig);	/* Initial threshold 32 bytes */
+	writew(0x0006, ioaddr + PCIBusConfig);	/* Store & forward */
+	/* Configure initial FIFO thresholds. */
+	writeb(0x20, ioaddr + TxConfig);
 	np->tx_thresh = 0x20;
 	np->rx_thresh = 0x60;			/* Written in via_rhine_set_rx_mode(). */
 
@@ -1024,13 +1039,13 @@
 
 	if (phy_id == np->phys[0]) {
 		switch (regnum) {
-		case 0:							/* Is user forcing speed/duplex? */
+		case MII_BMCR:					/* Is user forcing speed/duplex? */
 			if (value & 0x9000)			/* Autonegotiation. */
 				np->mii_if.duplex_lock = 0;
 			else
 				np->mii_if.full_duplex = (value & 0x0100) ? 1 : 0;
 			break;
-		case 4:
+		case MII_ADVERTISE:
 			np->mii_if.advertising = value;
 			break;
 		}
@@ -1069,7 +1084,7 @@
 		return i;
 	alloc_rbufs(dev);
 	alloc_tbufs(dev);
-	wait_for_reset(dev, dev->name);
+	wait_for_reset(dev, np->chip_id, dev->name);
 	init_registers(dev);
 	if (debug > 2)
 		printk(KERN_DEBUG "%s: Done via_rhine_open(), status %4.4x "
@@ -1176,7 +1191,7 @@
 	alloc_rbufs(dev);
 
 	/* Reinitialize the hardware. */
-	wait_for_reset(dev, dev->name);
+	wait_for_reset(dev, np->chip_id, dev->name);
 	init_registers(dev);
 	
 	spin_unlock(&np->lock);
@@ -1246,7 +1261,7 @@
 
 	if (debug > 4) {
 		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
-			   dev->name, np->cur_tx, entry);
+			   dev->name, np->cur_tx-1, entry);
 	}
 	return 0;
 }
@@ -1497,8 +1512,8 @@
 			printk(KERN_INFO "%s: Transmitter underrun, increasing Tx "
 				   "threshold setting to %2.2x.\n", dev->name, np->tx_thresh);
 	}
-	if ((intr_status & ~( IntrLinkChange | IntrStatsMax |
-						  IntrTxAbort | IntrTxAborted))) {
+	if (intr_status & ~( IntrLinkChange | IntrStatsMax |
+ 						 IntrTxAbort | IntrTxAborted | IntrNormalSummary)) {
 		if (debug > 1)
 			printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
 			   dev->name, intr_status);
@@ -1535,26 +1550,6 @@
 	readw(ioaddr + RxMissed);
 }
 
-
-/* The big-endian AUTODIN II ethernet CRC calculation.
-   N.B. Do not use for bulk data, use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
-    int crc = -1;
-
-    while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
-			crc = (crc << 1) ^
-				((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
-		}
-    }
-    return crc;
-}
-
 static void via_rhine_set_rx_mode(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253x.h linux/drivers/net/wan/8253x/8253x.h
--- linux.orig/drivers/net/wan/8253x/8253x.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253x.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,986 @@
+/* -*- linux-c -*- */
+/* $Id: 8253x.h,v 1.14 2002/02/10 22:17:25 martillo Exp $
+ * sab82532.h: Register Definitions for the Siemens SAB82532 DUSCC
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * Modified Aug 1, 2000 Francois Wautier  
+ * Modified for complete driver Joachim Martillo
+ */
+
+/* Modifications:
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+#ifndef _SAB82532_H
+#define _SAB82532_H
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/serial.h>	/* need struct async_icount for ioctl */
+#include <linux/netdevice.h>
+
+#include "8253xioc.h"
+#include "ring.h"
+
+#define SAB8253X_MAX_TEC_DELAY	200000 /* 1 character time (at 50 baud) */
+#define SAB8253X_MAX_CEC_DELAY	 50000 /* 2.5 TX CLKs (at 50 baud) */
+
+#define SERIAL_TYPE_SYNCTTY 3	/* check tty driver to make sure okay */
+				/* SERIAL_TYPE_NORMAL and SERIAL_TYPE_CALLOUT */
+				/* seem to be used by the tty driver */
+				/* only to print out a warning not to */
+				/* use callout devices - next version of */
+				/* the code, for now want to be able to */
+				/* maintain some of the structure of */
+				/* a 2.2.* driver for those that are */
+				/* running old kernels. */
+
+#define READB(port, rreg) (*port->readbyte)(port,\
+	(unsigned char *)&(port->regs->async_read.rreg))
+#define WRITEB(port, rreg, val) (*port->writebyte)(port,\
+	(unsigned char *)&(port->regs->async_write.rreg), val)
+#ifdef DEFINE_VARIABLE
+static unsigned char tmpval; 
+#endif
+	/* Used in the macro below -- don't create a variable called tmpval*/
+#define SET_REG_BIT(port,rreg,bit)\
+	tmpval=(*port->readbyte)(port,\
+		(unsigned char *)&(port->regs->async_read.rreg));\
+	tmpval |= bit;\
+	(*port->writebyte)(port,\
+		(unsigned char *)&(port->regs->async_write.rreg), tmpval);
+#define CLEAR_REG_BIT(port,rreg,bit)\
+	tmpval=(*port->readbyte)(port,\
+		(unsigned char *)&(port->regs->async_read.rreg));\
+	tmpval &= ~(bit);\
+	(*port->writebyte)(port,\
+		(unsigned char *)&(port->regs->async_write.rreg), tmpval);
+#define MASK_REG_BIT(port,rreg,bit)\
+	tmpval=(*port->readbyte)(port,\
+		(unsigned char *)&(port->regs->async_read.rreg));\
+	tmpval &= bit;\
+	(*port->writebyte)(port,\
+		(unsigned char *)&(port->regs->async_write.rreg), tmpval);
+#define READ_X_WRITEB(port,rreg,op,val)\
+	tmpval=(*port->readbyte)(port,\
+		(unsigned char *)&(port->regs->async_read.rreg));\
+	tmpval op= val;\
+	(*port->writebyte)(port,\
+		(unsigned char *)&(port->regs->async_write.rreg), tmpval);
+
+
+struct sab82532_async_rd_regs 
+{
+	volatile unsigned char	rfifo[0x20];	/* Receive FIFO				*/
+	volatile unsigned char	star;		/* Status Register			*/
+	volatile unsigned char	rsta;		/* actually an HDLC register */
+	volatile unsigned char	mode;		/* Mode Register			*/
+	volatile unsigned char	timr;		/* Timer Register			*/
+	volatile unsigned char	xon;		/* XON Character			*/
+	volatile unsigned char	xoff;		/* XOFF Character			*/
+	volatile unsigned char	tcr;		/* Termination Character Register	*/
+	volatile unsigned char	dafo;		/* Data Format				*/
+	volatile unsigned char	rfc;		/* RFIFO Control Register		*/
+	volatile unsigned char	__pad2;
+	volatile unsigned char	rbcl;		/* Receive Byte Count Low		*/
+	volatile unsigned char	rbch;		/* Receive Byte Count High		*/
+	volatile unsigned char	ccr0;		/* Channel Configuration Register 0	*/
+	volatile unsigned char	ccr1;		/* Channel Configuration Register 1	*/
+	volatile unsigned char	ccr2;		/* Channel Configuration Register 2	*/
+	volatile unsigned char	ccr3;		/* Channel Configuration Register 3	*/
+	volatile unsigned char	__pad3[4];
+	volatile unsigned char	vstr;		/* Version Status Register		*/
+	volatile unsigned char	__pad4[3];
+	volatile unsigned char	gis;		/* Global Interrupt Status		*/
+	volatile unsigned char	ipc;		/* Interrupt Port Configuration		*/
+	volatile unsigned char	isr0;		/* Interrupt Status 0			*/
+	volatile unsigned char	isr1;		/* Interrupt Status 1			*/
+	volatile unsigned char	pvr;		/* Port Value Register			*/
+	volatile unsigned char	pis;		/* Port Interrupt Status		*/
+	volatile unsigned char	pcr;		/* Port Configuration Register		*/
+	volatile unsigned char	ccr4;		/* Channel Configuration Register 4	*/
+};
+
+struct sab82532_async_wr_regs 
+{
+	unsigned char	xfifo[0x20];	/* Transmit FIFO			*/
+	unsigned char	cmdr;		/* Command Register			*/
+	unsigned char	__pad1;
+	unsigned char	mode;
+	unsigned char	timr;
+	unsigned char	xon;
+	unsigned char	xoff;
+	unsigned char	tcr;
+	unsigned char	dafo;
+	unsigned char	rfc;
+	unsigned char	__pad2;
+	unsigned char	xbcl;		/* Transmit Byte Count Low		*/
+	unsigned char	xbch;		/* Transmit Byte Count High		*/
+	unsigned char	ccr0;
+	unsigned char	ccr1;
+	unsigned char	ccr2;
+	unsigned char	ccr3;
+	unsigned char	tsax;		/* Time-Slot Assignment Reg. Transmit	*/
+	unsigned char	tsar;		/* Time-Slot Assignment Reg. Receive	*/
+	unsigned char	xccr;		/* Transmit Channel Capacity Register	*/
+	unsigned char	rccr;		/* Receive Channel Capacity Register	*/
+	unsigned char	bgr;		/* Baud Rate Generator Register		*/
+	unsigned char	tic;		/* Transmit Immediate Character		*/
+	unsigned char	mxn;		/* Mask XON Character			*/
+	unsigned char	mxf;		/* Mask XOFF Character			*/
+	unsigned char	iva;		/* Interrupt Vector Address		*/
+	unsigned char	ipc;
+	unsigned char	imr0;		/* Interrupt Mask Register 0		*/
+	unsigned char	imr1;		/* Interrupt Mask Register 1		*/
+	unsigned char	pvr;
+	unsigned char	pim;		/* Port Interrupt Mask			*/
+	unsigned char	pcr;
+	unsigned char	ccr4;
+};
+
+struct sab82532_async_rw_regs 
+{	/* Read/Write registers			*/
+	volatile unsigned char	__pad1[0x20];
+	volatile unsigned char	__pad2;
+	volatile unsigned char	__pad3;
+	volatile unsigned char	mode;
+	volatile unsigned char	timr;
+	volatile unsigned char	xon;
+	volatile unsigned char	xoff;
+	volatile unsigned char	tcr;
+	volatile unsigned char	dafo;
+	volatile unsigned char	rfc;
+	volatile unsigned char	__pad4;
+	volatile unsigned char	__pad5;
+	volatile unsigned char	__pad6;
+	volatile unsigned char	ccr0;
+	volatile unsigned char	ccr1;
+	volatile unsigned char	ccr2;
+	volatile unsigned char	ccr3;
+	volatile unsigned char	__pad7;
+	volatile unsigned char	__pad8;
+	volatile unsigned char	__pad9;
+	volatile unsigned char	__pad10;
+	volatile unsigned char	__pad11;
+	volatile unsigned char	__pad12;
+	volatile unsigned char	__pad13;
+	volatile unsigned char	__pad14;
+	volatile unsigned char	__pad15;
+	volatile unsigned char	ipc;
+	volatile unsigned char	__pad16;
+	volatile unsigned char	__pad17;
+	volatile unsigned char	pvr;
+	volatile unsigned char	__pad18;
+	volatile unsigned char	pcr;
+	volatile unsigned char	ccr4;
+};
+
+union sab82532_async_regs 
+{
+	__volatile__ struct sab82532_async_rd_regs	r;
+	__volatile__ struct sab82532_async_wr_regs	w;
+	__volatile__ struct sab82532_async_rw_regs	rw;
+};
+
+/* not really used yet */
+struct sab82532_hdlc_rd_regs 
+{
+	volatile unsigned char	rfifo[0x20];	/* Receive FIFO				*/
+	volatile unsigned char	star;		/* Status Register			*/
+	volatile unsigned char	rsta;
+	volatile unsigned char	mode;		/* Mode Register			*/
+	volatile unsigned char	timr;		/* Timer Register			*/
+	volatile unsigned char	xad1;		/* Tx Address High 1	 		*/
+	volatile unsigned char	xad2;		/* Tx Address High 2			*/
+	volatile unsigned char	__pad1[2];
+	volatile unsigned char	ral1;		/* Rx Address Low 1			*/
+	volatile unsigned char	rhcr;		/* Received HDLC Control		*/
+	volatile unsigned char	rbcl;		/* Receive Byte Count Low		*/
+	volatile unsigned char	rbch;		/* Receive Byte Count High		*/
+	volatile unsigned char	ccr0;		/* Channel Configuration Register 0	*/
+	volatile unsigned char	ccr1;		/* Channel Configuration Register 1	*/
+	volatile unsigned char	ccr2;		/* Channel Configuration Register 2	*/
+	volatile unsigned char	ccr3;		/* Channel Configuration Register 3	*/
+	volatile unsigned char	__pad2[4];
+	volatile unsigned char	vstr;		/* Version Status Register		*/
+	volatile unsigned char	__pad3[3];
+	volatile unsigned char	gis;		/* Global Interrupt Status		*/
+	volatile unsigned char	ipc;		/* Interrupt Port Configuration		*/
+	volatile unsigned char	isr0;		/* Interrupt Status 0			*/
+	volatile unsigned char	isr1;		/* Interrupt Status 1			*/
+	volatile unsigned char	pvr;		/* Port Value Register			*/
+	volatile unsigned char	pis;		/* Port Interrupt Status		*/
+	volatile unsigned char	pcr;		/* Port Configuration Register		*/
+	volatile unsigned char	ccr4;		/* Channel Configuration Register 4	*/
+};
+
+struct sab82532_hdlc_wr_regs 
+{
+	unsigned char	xfifo[0x20];	/* Transmit FIFO			*/
+	unsigned char	cmdr;		/* Command Register			*/
+	unsigned char	pre;		/* Preamble                             */
+	unsigned char	mode;
+	unsigned char	timr;
+	unsigned char	xad1;		/* Tx Address High 1	 		*/
+	unsigned char	xad2;		/* Tx Address High 2	 		*/
+	unsigned char	rah1;		/* Rx Address High 1	 		*/
+	unsigned char	rah2;		/* Rx Address High 2	 		*/
+	unsigned char	ral1;		/* Rx Address Low 1			*/
+	unsigned char	ral2;		/* Rx Address Low 2			*/
+	unsigned char	xbcl;		/* Transmit Byte Count Low		*/
+	unsigned char	xbch;		/* Transmit Byte Count High		*/
+	unsigned char	ccr0;
+	unsigned char	ccr1;
+	unsigned char	ccr2;
+	unsigned char	ccr3;
+	unsigned char	tsax;		/* Time-Slot Assignment Reg. Transmit	*/
+	unsigned char	tsar;		/* Time-Slot Assignment Reg. Receive	*/
+	unsigned char	xccr;		/* Transmit Channel Capacity Register	*/
+	unsigned char	rccr;		/* Receive Channel Capacity Register	*/
+	unsigned char	bgr;		/* Baud Rate Generator Register		*/
+	unsigned char	rlcr;		/* Rx Frame Length Check		*/
+	unsigned char	aml;		/* Address Mask Low			*/
+	unsigned char	amh;		/* Address Mask High			*/
+	unsigned char	iva;		/* Interrupt Vector Address		*/
+	unsigned char	ipc;
+	unsigned char	imr0;		/* Interrupt Mask Register 0		*/
+	unsigned char	imr1;		/* Interrupt Mask Register 1		*/
+	unsigned char	pvr;
+	unsigned char	pim;		/* Port Interrupt Mask			*/
+	unsigned char	pcr;
+	unsigned char	ccr4;
+};
+
+union sab82532_regs 
+{
+	__volatile__ struct sab82532_async_rd_regs	async_read;
+	__volatile__ struct sab82532_async_wr_regs	async_write;
+	__volatile__ struct sab82532_hdlc_rd_regs	hdlc_read;
+	__volatile__ struct sab82532_hdlc_wr_regs	hdlc_write;
+};
+
+/*
+ * Modem signal definition
+ */
+
+typedef struct mctlsig 
+{
+	unsigned char *reg;	/* chip register offset */
+	unsigned char inverted;	/* interpret the results as inverted */
+	unsigned char mask;	/* bit within that register */
+	unsigned char val;	/* cached value */
+	unsigned int irq;	/* address of correct isr register */
+	unsigned char irqmask;	/*  */
+	unsigned char cnst;	/* A value that should always be set for
+				 * this signal register */ 
+} mctlsig_t, MCTLSIG;
+
+union sab8253x_irq_status 
+{
+	unsigned int stat;
+	unsigned char images[4];
+	struct
+	{
+		unsigned char isr0;
+		unsigned char isr1;
+		unsigned char pis;
+	} sreg;
+};
+				/* the following are deprecated */
+				/* older version of structure above */
+				/* used array*/
+#define      ISR0_IDX 0
+#define      ISR1_IDX 1
+#define       PIS_IDX 2
+
+/*
+ * Each port has a structure like this associated to it.
+ * All the port are linked with the  next fields
+ * All the port of one chip are linked with the  next_by_chip
+ */
+
+#define	FUNCTION_NR	0
+#define	FUNCTION_AO	1
+#define	FUNCTION_NA	2
+#define FUNCTION_UN	3
+
+typedef struct sab_port 
+{
+	int				magic;
+	union sab82532_regs		*regs;
+	struct sab_chip			*chip;
+	struct sab_board		*board;
+	struct tty_struct		*tty;
+	unsigned char			*xmit_buf;
+	int				 xmit_head; /* put characters on write */
+	int				 xmit_tail; /* read from here -- in writeb or writefifo */
+	int				 xmit_cnt;
+	
+	/*
+	 * Various linked list pertinent to this link 
+	 */
+	struct sab_port * next;
+	struct sab_port * next_by_chip;
+	struct sab_port * next_by_board;
+	struct sab_port * next_by_cim;
+	
+	struct net_device *dev;
+	struct net_device *next_dev;
+	
+	struct fasync_struct * async_queue;
+	struct sk_buff_head *sab8253xbuflist; /* need to keep */
+				/* a list of all */
+				/* skbuffs so that */
+				/* we can guarantee */
+				/* freeing all when */
+				/* the PPC is stopped */
+				/* on close*/
+	struct sk_buff_head *sab8253xc_rcvbuflist; /* used for passing */
+				/* buffers from interrupt */
+				/* receive process*/
+	
+	
+	DCONTROL2 dcontrol2;
+	DCONTROL2 active2;
+	DCONTROL2 sabnext2;
+
+	int			DoingInterrupt;
+	int			irq;
+	int			flags;	       /* suggested by serial.h
+						* but this driver is
+						* more general */
+	int			syncflags;
+	int			type;	       /* SAB82532/8 version */
+	unsigned int		function;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			recv_fifo_size;
+	int			custom_divisor;
+	unsigned long		baud;
+	unsigned int		ebrg;
+	unsigned int		cec_timeout;
+	unsigned int		tec_timeout;
+
+	int			x_char;
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	int			all_sent;
+	int			is_console;
+#define OPEN_NOT 0
+#define OPEN_ASYNC 1
+#define OPEN_SYNC 2
+#define OPEN_BSC 3
+#define OPEN_RAW 4
+#define OPEN_SYNC_NET 5
+#define OPEN_SYNC_CHAR 6
+	unsigned int		open_type; /* Sync? Async?, int better for hw bps */
+	unsigned char	        interrupt_mask0;
+	unsigned char		interrupt_mask1;
+				/* Modem signals */
+	mctlsig_t		dtr;
+	mctlsig_t		dsr;
+	mctlsig_t		dcd;
+	mctlsig_t		cts;
+	mctlsig_t		rts;
+	mctlsig_t		txclkdir; /* Direction of TxClk */
+	unsigned long           custspeed; /* Custom speed */
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;
+	int			blocked_open;
+	long			session;
+	long			pgrp;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct async_icount	icount;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	delta_msr_wait;
+	wait_queue_head_t	read_wait;
+	wait_queue_head_t	write_wait;
+  
+  /*
+   * Pointer to FIFO access routines.  These are individualized
+   *  by hardware because different hardware may have different
+   *  ways to get to the FIFOs.
+   */
+  
+	void			(*readfifo)(struct sab_port *port, 
+					    unsigned char *buf,
+					    u32 nbytes);
+	void			(*writefifo)(struct sab_port *port);
+  
+  /*
+   * Pointer to register access routines.  These are individualized
+   *  by hardware because different hardware may have different
+   *  ways to get to the register.
+   */
+	unsigned char		(*readbyte)(struct sab_port *port, 
+					    unsigned char *reg);
+	void	        	(*writebyte)(struct sab_port *port, 
+					     unsigned char *reg,
+					     unsigned char val);
+	u16			(*readword)(struct sab_port *port, 
+					    u16 *reg);
+	void	        	(*writeword)(struct sab_port *port, 
+					     u16 *reg,
+					     u16 val);
+  
+  /*
+   * Pointer to protocol functions
+   *
+   */
+  
+	unsigned int portno;
+	void (*receive_chars)(struct sab_port *port, 
+			      union sab8253x_irq_status *stat);
+	void (*transmit_chars)(struct sab_port *port,
+			       union sab8253x_irq_status *stat);
+	void (*check_status)(struct sab_port *port,
+			     union sab8253x_irq_status *stat);
+	unsigned int receive_test;
+	unsigned int transmit_test;
+	unsigned int check_status_test;
+	struct channelcontrol ccontrol;
+	
+	unsigned int tx_full;
+	unsigned int rx_empty;
+	struct counters Counters;
+	struct net_device_stats stats;
+	
+				/* collect statistics for netstat */
+				/* etc.  those programs don't know */
+				/* about priorities*/
+
+	int			msgbufindex;
+	char			msgbuf[RXSIZE];
+	unsigned int		buffergreedy;
+	unsigned int		sigmode;
+} sab_port_t, SAB_PORT;
+
+/*
+ * per-parallel port structure
+ */
+
+/* SAB82538 4 8-bits parallel ports
+ * To summarize the use of the parallel port:
+ *                    RS-232
+ * Parallel port A -- TxClkdir control	(output) ports 0 - 7
+ * Parallel port B -- DTR		(output) ports 0 - 7
+ * Parallel port C -- DSR		(input)  ports 0 - 7
+ * Parallel port D -- driver power down	(output) drivers 0 - 3
+ *
+ * SAB82532 (Aurora) 1 8-bit parallel port
+ * To summarize the use of the parallel port:
+ *                    RS-232
+ *  A       B        I/O     descr
+ * P0      P4      output  TxClk ctrl
+ * P1      P5      output  DTR
+ * P2      P6      input   DSR
+ * P3      P7      output  485 control
+ *
+ * Note that this new version of the driver
+ * does not support the SPARC motherboard ESCC2
+ *
+ * SAB82532 (Sun) 1 8-bit parallel port
+ * To summarize the use of the parallel port:
+ *                    RS-232
+ *  A       B        I/O     descr
+ * P0      P3      input    DSR
+ * P1      P2      output    DTR
+ * P5      P6      input     ?
+ * P4      P7      output    ?
+ *
+ */
+				/* not sure how usefule */
+typedef struct sabparport 
+{
+  /* cached values: */
+	unsigned char	 pp_pcr;
+	unsigned char	 pp_pim;
+	unsigned char	 pp_pvr;
+	
+	/* register offsets: */
+	unsigned int	 pp_pcrreg;
+	unsigned int	 pp_pimreg;
+	unsigned int	 pp_pisreg;
+	unsigned int	 pp_pvrreg;
+} sabparport_t, SABPARPORT;
+
+#define ESCC2	2
+#define ESCC8	8
+
+/*
+ * Per-chip structure
+ */
+
+
+typedef struct sab_chip 
+{
+	unsigned int		chip_type;
+	struct sab_board	*c_board;	/* Parent board */
+	struct aura_cim		*c_cim;		/* if present */
+	unsigned char		c_chipno;	/* chip number */
+	unsigned char	 	c_revision;	/* the revision code from the VSTR */
+	unsigned char         	c_nports;	/* number of ports per chip */
+	void 			*c_regs;	/* base address for chip registers */
+	struct sab_port		*c_portbase;
+	struct sab_chip       	*next;          /* the next chip in the chip chain */
+	struct sab_chip       	*next_by_board;    /* the next chip on the board */
+	struct sab_chip		*next_by_cim;
+	void 			(*int_disable)(struct sab_chip* chip);
+} sab_chip_t, SAB_CHIP;
+
+
+/* Some useful facts */
+#define SAB82532_REG_SIZE               0x40
+#define SAB82538_REG_SIZE               0x40
+
+/* RFIFO Status Byte */
+#define SAB82532_RSTAT_PE		0x80
+#define SAB82532_RSTAT_FE		0x40
+#define SAB82532_RSTAT_PARITY		0x01
+
+/* Status Register (STAR) */
+#define SAB82532_STAR_XDOV		0x80
+#define SAB82532_STAR_XFW		0x40
+#define SAB82532_STAR_RFNE		0x20
+#define SAB82532_STAR_FCS		0x10
+#define SAB82532_STAR_TEC		0x08
+#define SAB82532_STAR_RLI		0x08
+#define SAB82532_STAR_CEC		0x04
+#define SAB82532_STAR_CTS		0x02
+
+/* Command Register (CMDR) */
+#define SAB82532_CMDR_RMC		0x80
+#define SAB82532_CMDR_RRES		0x40
+#define SAB82532_CMDR_RHR		0x40
+#define SAB82532_CMDR_RFRD		0x20
+#define SAB82532_CMDR_STI		0x10
+#define SAB82532_CMDR_XF		0x08
+#define SAB82532_CMDR_XTF		0x08
+#define SAB82532_CMDR_XME		0x02
+#define SAB82532_CMDR_XRES		0x01
+
+				/* leaving them for reference */
+				/* they are now defined in 8253xioc.h*/
+#if 0
+/* Mode Register (MODE) */
+#define SAB82532_MODE_TM0		0x80
+#define SAB82532_MODE_FRTS		0x40
+#define SAB82532_MODE_FCTS		0x20
+#define SAB82532_MODE_FLON		0x10
+#define SAB82532_MODE_TCPU		0x10
+#define SAB82532_MODE_RAC		0x08
+#define SAB82532_MODE_RTS		0x04
+#define SAB82532_MODE_TRS		0x02
+#define SAB82532_MODE_TLP		0x01
+#endif
+
+/* Receive Status Register (READ)  */
+#define SAB82532_RSTA_VFR		0x80
+#define SAB82532_RSTA_RDO		0x40
+#define SAB82532_RSTA_CRC		0x20
+#define SAB82532_RSTA_RAB		0x10
+
+/* Timer Register (TIMR) */
+#define SAB82532_TIMR_CNT_MASK		0xe0
+#define SAB82532_TIMR_VALUE_MASK	0x1f
+
+/* Data Format (DAFO) */
+#define SAB82532_DAFO_XBRK		0x40
+#define SAB82532_DAFO_STOP		0x20
+#define SAB82532_DAFO_PAR_SPACE		0x00
+#define SAB82532_DAFO_PAR_ODD		0x08
+#define SAB82532_DAFO_PAR_EVEN		0x10
+#define SAB82532_DAFO_PAR_MARK		0x18
+#define SAB82532_DAFO_PARE		0x04
+#define SAB82532_DAFO_CHL8		0x00
+#define SAB82532_DAFO_CHL7		0x01
+#define SAB82532_DAFO_CHL6		0x02
+#define SAB82532_DAFO_CHL5		0x03
+
+/* RFIFO Control Register (RFC) */
+#define SAB82532_RFC_DPS		0x40
+#define SAB82532_RFC_DXS		0x20
+#define SAB82532_RFC_RFDF		0x10
+#define SAB82532_RFC_RFTH_1		0x00
+#define SAB82532_RFC_RFTH_4		0x04
+#define SAB82532_RFC_RFTH_16		0x08
+#define SAB82532_RFC_RFTH_32		0x0c
+#define SAB82532_RFC_TCDE		0x01
+
+/* Received Byte Count High (RBCH) */
+#define SAB82532_RBCH_DMA		0x80
+#define SAB82532_RBCH_CAS		0x20
+#define SAB82532_RBCH_OV		0x10
+#define SAB82532_RBCH_HMSK		0x0F
+
+/* Transmit Byte Count High (XBCH) */
+#define SAB82532_XBCH_DMA		0x80
+#define SAB82532_XBCH_CAS		0x20
+#define SAB82532_XBCH_XC		0x10
+
+				/* leaving them for reference */
+				/* they are now defined in 8253xioc.h*/
+#if 0
+/* Channel Configuration Register 0 (CCR0) */
+#define SAB82532_CCR0_PU		0x80
+#define SAB82532_CCR0_MCE		0x40
+#define SAB82532_CCR0_SC_NRZ		0x00
+#define SAB82532_CCR0_SC_NRZI		0x08
+#define SAB82532_CCR0_SC_FM0		0x10
+#define SAB82532_CCR0_SC_FM1		0x14
+#define SAB82532_CCR0_SC_MANCH		0x18
+#define SAB82532_CCR0_SM_HDLC		0x00
+#define SAB82532_CCR0_SM_SDLC_LOOP	0x01
+#define SAB82532_CCR0_SM_BISYNC		0x02
+#define SAB82532_CCR0_SM_ASYNC		0x03
+
+/* Channel Configuration Register 1 (CCR1) */
+#define SAB82532_CCR1_SFLG		0x80
+#define SAB82532_CCR1_ODS		0x10
+#define SAB82532_CCR1_BCR		0x08
+#define SAB82532_CCR1_IFF		0x08
+#define SAB82532_CCR1_ITF		0x00
+#define SAB82532_CCR1_CM_MASK		0x07
+
+/* Channel Configuration Register 2 (CCR2) */
+#define SAB82532_CCR2_SOC1		0x80
+#define SAB82532_CCR2_SOC0		0x40
+#define SAB82532_CCR2_BR9		0x80
+#define SAB82532_CCR2_BR8		0x40
+#define SAB82532_CCR2_BDF		0x20
+#define SAB82532_CCR2_SSEL		0x10
+#define SAB82532_CCR2_XCS0		0x20
+#define SAB82532_CCR2_RCS0		0x10
+#define SAB82532_CCR2_TOE		0x08
+#define SAB82532_CCR2_RWX		0x04
+#define SAB82532_CCR2_C32		0x02
+#define SAB82532_CCR2_DIV		0x01
+
+/* Channel Configuration Register 3 (CCR3) */
+#define SAB82532_CCR3_PSD		0x01
+#define SAB82532_CCR3_RCRC		0x04
+#endif
+
+/* Time Slot Assignment Register Transmit (TSAX) */
+#define SAB82532_TSAX_TSNX_MASK		0xfc
+#define SAB82532_TSAX_XCS2		0x02	/* see also CCR2 */
+#define SAB82532_TSAX_XCS1		0x01
+
+/* Time Slot Assignment Register Receive (TSAR) */
+#define SAB82532_TSAR_TSNR_MASK		0xfc
+#define SAB82532_TSAR_RCS2		0x02	/* see also CCR2 */
+#define SAB82532_TSAR_RCS1		0x01
+
+/* Version Status Register (VSTR) */
+#define SAB85232_REG_VSTR               0x34
+#define SAB82532_VSTR_CD		0x80
+#define SAB82532_VSTR_DPLA		0x40
+#define SAB82532_VSTR_VN_MASK		0x0f
+#define SAB82532_VSTR_VN_1		0x00
+#define SAB82532_VSTR_VN_2		0x01
+#define SAB82532_VSTR_VN_3_2		0x02
+
+/* Global Interrupt Status Register (GIS) */
+#define SAB82532_GIS_PI			0x80
+#define SAB82532_GIS_ISA1		0x08
+#define SAB82532_GIS_ISA0		0x04
+#define SAB82532_GIS_ISB1		0x02
+#define SAB82532_GIS_ISB0		0x01
+#define SAB82532_GIS_MASK		0x8f 
+#define SAB82538_GIS_PIA		0x80
+#define SAB82538_GIS_PIB		0x40
+#define SAB82538_GIS_PIC		0x20
+#define SAB82538_GIS_PID		0x10
+#define SAB82538_GIS_CII		0x08
+#define SAB82538_GIS_CHNL_MASK          0x07
+#define SAB82538_GIS_MASK		0x28  /* Port C and CII ! */ 
+
+/* Interrupt Vector Address (IVA) */
+#define SAB82532_REG_IVA                0x38
+#define SAB82532_IVA_MASK		0xf1
+#define SAB82538_IVA_ROT                0x02
+
+/* Interrupt Port Configuration (IPC) */
+#define SAB82532_REG_IPC                0x39
+#define SAB82532_IPC_VIS		0x80
+#define SAB82532_IPC_SLA1		0x10
+#define SAB82532_IPC_SLA0		0x08
+#define SAB82532_IPC_CASM		0x04
+#define SAB82532_IPC_IC_OPEN_DRAIN	0x00
+#define SAB82532_IPC_IC_ACT_LOW		0x01
+#define SAB82532_IPC_IC_ACT_HIGH	0x03
+
+/* Interrupt Status Register 0 (ISR0) */
+#define SAB82532_ISR0_TCD		0x80
+#define SAB82532_ISR0_RME		0x80
+#define SAB82532_ISR0_TIME		0x40
+#define SAB82532_ISR0_RFS		0x40
+#define SAB82532_ISR0_PERR		0x20
+#define SAB82532_ISR0_FERR		0x10
+#define SAB82532_ISR0_PLLA		0x08
+#define SAB82532_ISR0_CDSC		0x04
+#define SAB82532_ISR0_RFO		0x02
+#define SAB82532_ISR0_RPF		0x01
+
+/* Interrupt Status Register 1 (ISR1) */
+#define SAB82532_ISR1_BRK		0x80
+#define SAB82532_ISR1_BRKT		0x40
+#define SAB82532_ISR1_RDO		0x40
+#define SAB82532_ISR1_ALLS		0x20
+#define SAB82532_ISR1_XOFF		0x10
+#define SAB82532_ISR1_XDU		0x10
+#define SAB82532_ISR1_TIN		0x08
+#define SAB82532_ISR1_CSC		0x04
+#define SAB82532_ISR1_XON		0x02
+#define SAB82532_ISR1_XPR		0x01
+
+/* Interrupt Mask Register 0 (IMR0) */
+#define SAB82532_IMR0_TCD		0x80
+#define SAB82532_IMR0_RME		0x80
+#define SAB82532_IMR0_TIME		0x40
+#define SAB82532_IMR0_RFS		0x40
+#define SAB82532_IMR0_PERR		0x20
+#define SAB82532_IMR0_RSC		0x20
+#define SAB82532_IMR0_FERR		0x10
+#define SAB82532_IMR0_PCE		0x10
+#define SAB82532_IMR0_PLLA		0x08
+#define SAB82532_IMR0_CDSC		0x04
+#define SAB82532_IMR0_RFO		0x02
+#define SAB82532_IMR0_RPF		0x01
+
+/* Interrupt Mask Register 1 (IMR1) */
+#define SAB82532_IMR1_BRK		0x80
+#define SAB82532_IMR1_EOP		0x80
+#define SAB82532_IMR1_BRKT		0x40
+#define SAB82532_IMR1_RDO		0x40
+#define SAB82532_IMR1_ALLS		0x20
+#define SAB82532_IMR1_XOFF		0x10
+#define SAB82532_IMR1_EXE		0x10
+#define SAB82532_IMR1_TIN		0x08
+#define SAB82532_IMR1_CSC		0x04
+#define SAB82532_IMR1_XON		0x02
+#define SAB82532_IMR1_XMR		0x02
+#define SAB82532_IMR1_XPR		0x01
+
+/* Port Value Register (PVR) */
+#define SAB82532_REG_PVR                 0x3c
+#define SAB82538_REG_PVR_A               0x3c
+#define SAB82538_REG_PVR_B               0xbc
+#define SAB82538_REG_PVR_C               0x13c
+#define SAB82538_REG_PVR_D               0x1bc
+
+/* Port Value Register (PIM) */
+#define SAB82532_REG_PIM                 0x3d
+#define SAB82538_REG_PIM_A               0x3d
+#define SAB82538_REG_PIM_B               0xbd
+#define SAB82538_REG_PIM_C               0x13d
+#define SAB82538_REG_PIM_D               0x1bd
+/* Port Value Register (PIS) */
+#define SAB82532_REG_PIS                 0x3d
+#define SAB82538_REG_PIS_A               0x3d
+#define SAB82538_REG_PIS_B               0xbd
+#define SAB82538_REG_PIS_C               0x13d
+#define SAB82538_REG_PIS_D               0x1bd
+
+/* Port Value Register (PCR) */
+#define SAB82532_REG_PCR                 0x3e
+#define SAB82538_REG_PCR_A               0x3e
+#define SAB82538_REG_PCR_B               0xbe
+#define SAB82538_REG_PCR_C               0x13e
+#define SAB82538_REG_PCR_D               0x1be
+
+				/* leaving them for reference */
+				/* they are now defined in 8253xioc.h*/
+
+#if 0
+/* Channel Configuration Register 4 (CCR4) */
+#define SAB82532_CCR4_MCK4		0x80/* needs to be set when board clock */
+					    /* over 10 Mhz (?)*/
+#define SAB82532_CCR4_EBRG		0x40
+#define SAB82532_CCR4_TST1		0x20
+#define SAB82532_CCR4_ICD		0x10
+#endif
+
+
+/* Port Interrupt Status Register (PIS) */
+#define SAB82532_PIS_SYNC_B		0x08
+#define SAB82532_PIS_DTR_B		0x04
+#define SAB82532_PIS_DTR_A		0x02
+#define SAB82532_PIS_SYNC_A		0x01
+
+
+/* More things useful */
+#define SAB_MAGIC 5977
+
+/* When computing the baudrate, we "encode" it by multiplying
+ * the actual baudrate by 2. This way we can use 134.5
+ */
+#define ENCODEBR(x)  ((x)<<1)
+
+/*
+ * Raise a modem signal y on port x, tmpval must exist! */
+#define RAISE(xx,y) \
+{ \
+	  unsigned char __tmpval__; \
+	  __tmpval__= (xx)->readbyte((xx),(xx)->y.reg);\
+	  if((xx)->y.inverted)\
+	    __tmpval__ &= ~((xx)->y.mask);\
+	  else\
+	    __tmpval__ |= (xx)->y.mask;\
+	  __tmpval__ |= (xx)->y.cnst;\
+	  (xx)->y.val=1;\
+	  (xx)->writebyte((xx),(xx)->y.reg,__tmpval__);\
+}
+/*
+ * Lower a modem signal y on port x, __tmpval__ must exist! */
+#define LOWER(xx,y) \
+{\
+	  unsigned char __tmpval__; \
+	  __tmpval__= (xx)->readbyte((xx),(xx)->y.reg);\
+	  if((xx)->y.inverted)\
+	    __tmpval__ |= (xx)->y.mask;\
+	  else\
+	    __tmpval__ &= ~((xx)->y.mask);\
+	  __tmpval__ |= (xx)->y.cnst;\
+	  (xx)->y.val=0;\
+	  (xx)->writebyte((xx),(xx)->y.reg,__tmpval__);\
+}
+
+#define ISON(xx,y) \
+          ((xx)->y.inverted != (((xx)->readbyte((xx),(xx)->y.reg)&(xx)->y.mask) ==(xx)->y.mask) )
+/*
+ * Now let's define all those functions we need else where.
+ *
+ * This should probably be reorganized
+ */
+extern void sab8253x_setup_ttydriver(void);
+extern int finish_sab8253x_setup_ttydriver(void);
+extern void sab8253x_setup_ttyport(struct sab_port *port);
+extern void sab8253x_cleanup_ttydriver(void);
+extern void sab8253x_start_txS(struct sab_port *port);
+
+static int inline sab8253x_serial_paranoia_check(struct sab_port *port,
+						 kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null sab8253x for (%s) in %s\n";
+	
+	if (!port) 
+	{
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (port->magic != SAB_MAGIC) 
+	{
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+static void inline sab8253x_cec_wait(struct sab_port *port)
+{
+	int timeout = port->cec_timeout;
+
+#if 1				/* seems to work for 82532s */
+	while ((READB(port, star) & SAB82532_STAR_CEC) && --timeout)
+	{
+		udelay(1);
+	}
+#else
+	if (READB(port,star) & SAB82532_STAR_CEC)
+	{
+		udelay(1);
+	}
+#endif
+}
+
+extern void sab8253x_transmit_charsS(struct sab_port *port, union sab8253x_irq_status *stat);
+extern void sab8253x_flush_charsS(struct tty_struct *tty);
+extern void sab8253x_set_termiosS(struct tty_struct *tty, struct termios *old_termios);
+extern void sab8253x_stopS(struct tty_struct *tty);
+extern void sab8253x_startS(struct tty_struct *tty);
+extern void sab8253x_send_xcharS(struct tty_struct *tty, char ch);
+extern void sab8253x_transmit_charsN(struct sab_port *port,
+				     union sab8253x_irq_status *stat);
+extern SAB_PORT  *AuraPortRoot;
+
+#define MAX_SAB8253X_RCV_QUEUE_LEN 50
+
+struct ebrg_struct 
+{
+	int	baud;
+	int	n;
+	int	m;
+};
+
+extern task_queue tq_8253x_serial;
+
+extern int sab8253x_openS(struct tty_struct *tty, struct file * filp);
+extern void sab8253x_closeS(struct tty_struct *tty, struct file * filp);
+extern int sab8253x_writeS(struct tty_struct * tty, int from_user,
+			   const unsigned char *buf, int count);
+extern void sab8253x_throttleS(struct tty_struct * tty);
+extern void sab8253x_unthrottleS(struct tty_struct * tty);
+extern void sab8253x_hangupS(struct tty_struct *tty);
+extern void sab8253x_breakS(struct tty_struct *tty, int break_state);
+extern void Sab8253xCleanUpTransceiveN(SAB_PORT* priv);
+
+				/* used for running routines in the */
+				/* soft int part of the driver */
+				/* at one time the flip buffer routines */
+				/* seem to have been too time consuming */
+				/* to invoke in the hardware interrupt */
+				/* routing -- I am not so sure there is */
+				/* a problem with modern processor and */
+				/* memory speeds, but maybe there is a */
+				/* requirement that certain tty routines */
+				/* not be executed with ints turned off.*/
+
+static void inline sab8253x_sched_event(struct sab_port *port, int event)
+{
+	port->event |= 1 << event;
+	queue_task(&port->tqueue, &tq_8253x_serial);
+	mark_bh(AURORA_BH);
+}
+
+extern unsigned int 
+sab8253x_baud(sab_port_t *port, unsigned long encbaud,
+	      unsigned char *bgr, unsigned char *ccr2,
+	      unsigned char *ccr4, unsigned long *truebaudp);
+extern void Sab8253xFreeAllReceiveListSKBUFFS(SAB_PORT* priv);
+extern int Sab8253xSetUpLists(SAB_PORT *priv);
+extern int Sab8253xCountTransmitDescriptors(SAB_PORT *port);
+extern int Sab8253xCountTransmit(SAB_PORT *port);
+extern void sab8253x_init_lineS(struct sab_port *port);
+extern void sab8253x_init_lineS(struct sab_port *port);
+extern int getccr2configS(struct sab_port *port);
+extern void sab8253x_change_speedN(struct sab_port *port);
+extern void sab8253x_shutdownN(struct sab_port *port);
+extern int sab8253x_startupN(struct sab_port *port);
+extern int sab8253x_block_til_ready(struct tty_struct *tty, struct file * filp,
+				    struct sab_port *port);
+extern void sab8253x_wait_until_sent(struct tty_struct *tty, int timeout);
+extern void sab8253x_flush_buffer(struct tty_struct *tty);
+extern void aura_sp502_program(SAB_PORT *port, unsigned int index);
+#endif 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xchr.c linux/drivers/net/wan/8253x/8253xchr.c
--- linux.orig/drivers/net/wan/8253x/8253xchr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xchr.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,760 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include <linux/poll.h>
+#include "Reg9050.h"
+#include "8253xctl.h"
+#include "ring.h"
+#include "8253x.h"
+#include "crc32dcl.h"
+
+/* a raw character driver  -- theoretically for implementing custom protocols,
+ * async interrupts can be used for getting indication that a packet has
+ * been successfully transmitted.
+ */
+
+
+				/* the application read routine, can block according */
+				/* to flag, returns one packet at a time */
+int sab8253xc_read(struct file *filep, char *cptr, size_t cnt, loff_t *loffp)
+{
+	unsigned int length;
+	unsigned long flags;
+	SAB_PORT *port = filep->private_data;
+	struct sk_buff *skb;
+	
+	DEBUGPRINT((KERN_ALERT "Attempting to read %i bytes.\n", cnt));
+	
+	
+	if(port->sab8253xc_rcvbuflist == NULL)
+	{
+		return -ENOMEM;
+	}
+	
+	save_flags(flags); cli();  
+	if(skb_queue_len(port->sab8253xc_rcvbuflist) == 0)
+	{
+		port->rx_empty = 1;
+		if(filep->f_flags & O_NONBLOCK)
+		{
+			restore_flags(flags);
+			return -EAGAIN;
+		}
+		restore_flags(flags);
+		interruptible_sleep_on(&port->read_wait);
+	}
+	else
+	{
+		restore_flags(flags);
+	}
+	
+	skb = skb_peek(port->sab8253xc_rcvbuflist);
+	length = skb->tail - skb->data;
+	if(cnt < length)
+	{
+		return -ENOMEM;
+	}
+	
+	skb = skb_dequeue(port->sab8253xc_rcvbuflist);
+	
+	save_flags(flags); cli();  
+	if(skb_queue_len(port->sab8253xc_rcvbuflist) <= 0)
+	{
+		port->rx_empty = 1;
+	}
+	restore_flags(flags);
+	
+	DEBUGPRINT((KERN_ALERT "Copying to user space %s.\n", skb->data));
+	copy_to_user(cptr, skb->data, length);
+	dev_kfree_skb_any(skb);
+	return length;
+}
+
+/* application write */
+
+int sab8253xc_write(struct file *filep, const char *cptr, size_t cnt, loff_t *loffp)
+{
+	struct sk_buff *skb;
+	unsigned long flags;
+	SAB_PORT *port = filep->private_data;
+	
+	if(cnt > sab8253xc_rbufsize)	/* should not send bigger than can be received */
+	{
+		return -ENOMEM;
+	}
+	
+	if(port->active2.transmit == NULL)
+	{
+		return -ENOMEM;
+	}
+	
+	save_flags(flags); cli();	/* can block on write when */
+	/* no space in transmit circular */
+	/* array. */
+	if((port->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		++(port->Counters.tx_drops);
+		port->tx_full = 1;
+		restore_flags(flags);
+		if(filep->f_flags & O_NONBLOCK)
+		{
+			return -EAGAIN;
+		}
+		interruptible_sleep_on(&port->write_wait);
+	}
+	else
+	{
+		restore_flags(flags);
+	}
+	
+#ifndef FREEINTERRUPT
+	if((port->active2.transmit->HostVaddr != NULL) || /* not OWN_SAB from above */
+	   (port->active2.transmit->crcindex != 0))
+	{
+		register RING_DESCRIPTOR *freeme;
+		
+		freeme = port->active2.transmit;
+		do
+		{
+			if((freeme->crcindex == 0) && (freeme->HostVaddr == NULL))
+			{
+				break;
+			}
+			if(freeme->HostVaddr)
+			{
+				skb_unlink((struct sk_buff*)freeme->HostVaddr);
+				dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+				freeme->HostVaddr = NULL;
+			}
+			freeme->sendcrc = 0;
+			freeme->crcindex = 0;
+			freeme = (RING_DESCRIPTOR*) freeme->VNext;
+		}
+		while((freeme->Count & OWNER) != OWN_SAB);
+	}
+#endif
+	
+	skb = alloc_skb(cnt, GFP_KERNEL); /* not called from int as with tty */
+	if(skb == NULL)
+	{
+		return -ENOMEM;
+	}
+	copy_from_user(skb->data, cptr, cnt);
+	skb->tail = (skb->data + cnt);
+	skb->len = cnt;
+	skb->data_len = cnt;
+	
+	skb_queue_head(port->sab8253xbuflist, skb);
+	port->active2.transmit->HostVaddr = skb;
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+	port->active2.transmit->Count = (OWN_SAB|cnt); /* must be this order */
+	port->active2.transmit = 
+		(RING_DESCRIPTOR*) port->active2.transmit->VNext;
+	port->Counters.transmitbytes += cnt;
+	sab8253x_start_txS(port);
+	return cnt;
+}
+
+static void sab8253x_receive_charsC(struct sab_port *port,
+				    union sab8253x_irq_status *stat)
+{
+	unsigned char buf[32];
+	int free_fifo = 0;
+	int reset_fifo = 0;
+	int msg_done = 0;
+	int msg_bad = 0;
+	int count = 0;
+	int total_size = 0;
+	int rstatus = 0;
+	struct sk_buff *skb;
+	
+	/* Read number of BYTES (Character + Status) available. */
+	
+	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
+	{
+		++msg_bad;
+		++free_fifo;
+		++reset_fifo;
+	}
+	else
+	{
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
+		{
+			count = port->recv_fifo_size;
+			++free_fifo;
+		}
+		
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 
+		{
+			count = READB(port, rbcl);
+			count &= (port->recv_fifo_size - 1);
+			++msg_done;
+			++free_fifo;
+			
+			total_size = READB(port, rbch);
+			if(total_size & SAB82532_RBCH_OV) /* need to revisit for 4096 byte frames */
+			{
+				msg_bad++;
+			}
+			
+			rstatus = READB(port, rsta);
+			if((rstatus & SAB82532_RSTA_VFR) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RDO)
+			{
+				msg_bad++;
+			}
+			if((rstatus & SAB82532_RSTA_CRC) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RAB)
+			{
+				msg_bad++;
+			}
+		}
+	}
+	
+	/* Read the FIFO. */
+	
+	(*port->readfifo)(port, buf, count);
+	
+	
+	/* Issue Receive Message Complete command. */
+	
+	if (free_fifo) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
+	}
+	
+	if(reset_fifo)
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
+	}
+	
+	if(msg_bad)
+	{
+		port->msgbufindex = 0;
+		return;
+	}
+	
+	memcpy(&port->msgbuf[port->msgbufindex], buf, count);
+	port->msgbufindex += count;
+	
+	if(msg_done)
+	{
+		
+		if(port->msgbufindex <= 3) /* min is 1 char + 2 CRC + status byte */
+		{
+			port->msgbufindex = 0;
+			return;
+		}
+		
+		total_size = port->msgbufindex - 3; /* strip off the crc16 and the status byte */
+		port->msgbufindex = 0;
+		
+		/* ignore the receive buffer waiting -- we know the correct size here */
+		
+		if(skb = dev_alloc_skb(total_size), skb)
+		{
+			memcpy(skb->data, &port->msgbuf[0], total_size);
+			skb->tail = (skb->data + total_size);
+			skb->data_len = total_size;
+			skb->len = total_size;
+			skb_queue_tail(port->sab8253xc_rcvbuflist, skb);
+			if(port->rx_empty)
+			{
+				port->rx_empty = 0;
+				wake_up_interruptible(&port->read_wait);
+			}
+			if(port->async_queue)
+			{
+				kill_fasync(&port->async_queue, SIGIO, POLL_IN);
+			}
+		}
+	}
+}
+
+static void sab8253x_check_statusC(struct sab_port *port,
+				   union sab8253x_irq_status *stat)
+{
+	int modem_change = 0;
+	mctlsig_t         *sig;
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 
+	{
+		port->icount.buf_overrun++;
+	}
+	
+	/* Checking DCD */
+	sig = &port->dcd;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dcd);
+		port->icount.dcd++;
+		modem_change++;
+	}
+	/* Checking CTS */
+	sig = &port->cts;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,cts);
+		port->icount.cts++;
+		modem_change++;
+	}
+	/* Checking DSR */
+	sig = &port->dsr;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dsr);
+		port->icount.dsr++;
+		modem_change++;
+	}
+	if (modem_change)
+	{
+		wake_up_interruptible(&port->delta_msr_wait);
+	}
+	
+	sig = &port->dcd;
+	if ((port->flags & FLAG8253X_CHECK_CD) &&
+	    (stat->images[sig->irq] & sig->irqmask)) 
+	{
+		
+		if (sig->val)
+		{
+			wake_up_interruptible(&port->open_wait); /* in case waiting in block_til_ready */
+		}
+		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+			   (port->flags & FLAG8253X_CALLOUT_NOHUP))) 
+		{
+			/* I think the code needs to walk through all the proces that have opened this
+			 * port and send a SIGHUP to them -- need to investigate somewhat more*/
+		}
+	}
+}
+
+static int sab8253x_startupC(struct sab_port *port)
+{
+	unsigned long flags;
+	int retval = 0;
+	
+	save_flags(flags); cli();
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		goto errout;
+	}
+	
+	if (!port->regs) 
+	{
+		retval = -ENODEV;
+		goto errout;
+	}
+	/*
+	 * Initialize the Hardware
+	 */
+	sab8253x_init_lineS(port);	/* nothing in this function
+					 * refers to tty structure */
+	
+	/* Activate RTS */
+	RAISE(port,rts);
+	
+	/* Activate DTR */
+	RAISE(port,dtr);
+	
+	
+	/*
+	 * Initialize the modem signals values
+	 */
+	port->dcd.val=ISON(port,dcd);
+	port->cts.val=ISON(port,cts);
+	port->dsr.val=ISON(port,dsr);
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	
+	port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE |
+		SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC;
+#if 0
+	((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); /* the weird way the cards work
+									       * when clocking CD seems to
+									       *  monitor txclk*/
+#endif
+	WRITEB(port,imr0,port->interrupt_mask0);
+	port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR |
+		SAB82532_IMR1_TIN | SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	port->all_sent = 1;
+	
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	sab8253x_change_speedN(port);
+	
+	port->flags |= FLAG8253X_INITIALIZED; /* bad name for indicating to other functionalities status */
+	port->receive_chars = sab8253x_receive_charsC;
+	port->transmit_chars = sab8253x_transmit_charsS;
+	port->check_status = sab8253x_check_statusC;
+	port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR |
+			       SAB82532_ISR1_XDU | SAB82532_ISR1_CSC);
+	port->check_status_test = SAB82532_ISR1_CSC;
+	
+	restore_flags(flags);
+	return 0;
+	
+ errout:
+	restore_flags(flags);
+	return retval;
+}
+
+static int sab8253x_block_til_readyC(struct file* filp, struct sab_port *port)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 1;		/* cheating -- I need to understand how
+					   signals behave synchronously better*/
+	unsigned long flags;
+	
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (port->flags & FLAG8253X_CLOSING)
+	{
+		interruptible_sleep_on(&port->close_wait); /* finish up previous close */
+		
+#ifdef SERIAL_DO_RESTART
+		if (port->flags & FLAG8253X_HUP_NOTIFY)
+		{
+			return -EAGAIN;
+		}
+		else
+		{
+			return -ERESTARTSYS;
+		}
+#else
+		return -EAGAIN;
+#endif
+	}
+	
+	/* sort out async vs sync tty, not call out */
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	
+	if (filp->f_flags & O_NONBLOCK) 
+	{
+		if (port->flags & FLAG8253X_CALLOUT_ACTIVE)
+		{
+			return -EBUSY;
+		}
+		port->flags |= FLAG8253X_NORMAL_ACTIVE;
+		return 0;
+	}
+	
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE) 
+	{
+		if (port->normal_termios.c_cflag & CLOCAL)
+		{
+			do_clocal = 1;
+		}
+	} 
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, port->count is dropped by one, so that
+	 * sab8253x_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	
+	/* The port decrement logic is probably */
+	/* broken -- hence if def'd out -- it does*/
+	retval = 0;
+	add_wait_queue(&port->open_wait, &wait); /* starts the wait but does not block here */
+	port->blocked_open++;
+	while (1)			/* on some devices when providing clock have to just assume connection */
+	{
+		save_flags(flags);
+		cli();
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE))
+		{
+			RAISE(port, dtr);
+			RAISE(port, rts);	/* maybe not correct for sync */
+			/*
+			 * ??? Why changing the mode here? 
+			 *  port->regs->rw.mode |= SAB82532_MODE_FRTS;
+			 *  port->regs->rw.mode &= ~(SAB82532_MODE_RTS);
+			 */
+		}
+		restore_flags(flags);;
+		current->state = TASK_INTERRUPTIBLE;
+		if (!(port->flags & FLAG8253X_INITIALIZED)) 
+		{
+#ifdef SERIAL_DO_RESTART
+			if (port->flags & FLAG8253X_HUP_NOTIFY)
+			{
+				retval = -EAGAIN;
+			}
+			else
+			{
+				retval = -ERESTARTSYS;	
+			}
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    !(port->flags & FLAG8253X_CLOSING) &&
+		    (do_clocal || ISON(port,dcd))) 
+		{
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("sab8253x_block_til_ready:2 flags = 0x%x\n",port->flags);
+#endif
+		if (signal_pending(current)) 
+		{
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("sab8253x_block_til_readyC blocking: ttyS%d, count = %d, flags = %x, clocal = %d, vstr = %02x\n",
+		       port->line, port->count, port->flags, do_clocal, READB(port,vstr));
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&port->open_wait, &wait);
+	port->blocked_open--;
+	
+#ifdef DEBUG_OPEN
+	printk("sab8253x_block_til_ready after blockingC: ttys%d, count = %d\n",
+	       port->line, port->count);
+#endif
+	
+	if (retval)
+	{
+		return retval;
+	}
+	port->flags |= FLAG8253X_NORMAL_ACTIVE;
+	return 0;
+}
+
+
+int sab8253xc_open(struct inode *inodep, struct file *filep)
+{
+	unsigned int line;
+	unsigned int retval;
+	unsigned int counter;
+	SAB_PORT *port;
+	
+	line = MINOR(inodep->i_rdev);	/* let's find which physical device to use */
+	/* minor dev number indexes through the port */
+	/* list */
+	
+	for(counter = 0, port = AuraPortRoot; 
+	    (counter < line) && (port != NULL); 
+	    ++counter)
+	{
+		port = port->next;
+	}
+	
+	
+	if (!port) 
+	{
+		printk(KERN_ALERT "sab8253xc_open: can't find structure for line %d\n",
+		       line);
+		return -ENODEV;
+	}
+	
+	if(port->function == FUNCTION_NA)
+	{				/* port 2 on 1020s and 1520s */
+		return -ENODEV;
+	}
+	
+	switch(port->open_type)
+	{
+	case OPEN_ASYNC:
+		if(!(port->flags & FLAG8253X_CALLOUT_ACTIVE))
+		{
+			return -EBUSY;
+		}
+		break;
+		
+	case OPEN_SYNC_CHAR:
+	case OPEN_NOT:
+		port->tty = NULL;
+		port->open_type = OPEN_SYNC_CHAR;
+		break;
+		
+	default:
+		return -EBUSY;
+	}
+	
+	/*
+	 * Maybe start up serial port -- may already be running in callout mode
+	 */
+	
+	if(Sab8253xSetUpLists(port))
+	{
+		if(port->open_type == OPEN_SYNC_CHAR)
+		{
+			port->open_type = OPEN_NOT;
+		}
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xc_listsize, sab8253xc_rbufsize))
+	{
+		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */
+		/* is the crc32 that is appended */
+		if(port->open_type == OPEN_SYNC_CHAR)
+		{
+			port->open_type = OPEN_NOT;
+		}
+		return -ENODEV;
+	}
+	retval = sab8253x_startupC(port); /* does not do anything if call out active */
+	if (retval)
+	{
+		if(port->open_type == OPEN_SYNC_CHAR)
+		{
+			port->open_type = OPEN_NOT;
+		}
+		return retval;		
+	}
+	
+	MOD_INC_USE_COUNT;		/* might block */
+	/* note logic different from tty
+	   open failure does not call the
+	   close routine */
+	retval = sab8253x_block_til_readyC(filep, port);	/* need to wait for completion of callout */
+	if(retval)
+	{
+		if(port->open_type == OPEN_SYNC_CHAR)
+		{
+			port->open_type = OPEN_NOT;
+		}
+		MOD_DEC_USE_COUNT;	/* something went wrong */
+		return retval;
+	}
+	
+	port->tty = NULL;
+	port->open_type = OPEN_SYNC_CHAR;
+	if(Sab8253xSetUpLists(port))
+	{
+		port->open_type = OPEN_NOT;
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xc_listsize, sab8253xc_rbufsize))
+	{
+		port->open_type = OPEN_NOT;
+		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */
+		/* is the crc32 that is appended */
+		return -ENODEV;
+	}
+	retval = sab8253x_startupC(port); /* ditto */
+	if (retval)
+	{
+		port->open_type = OPEN_NOT;
+		Sab8253xCleanUpTransceiveN(port);
+		return retval;		
+	}
+	port->tx_full = 0;
+	port->rx_empty = 1;
+	port->count++;
+	port->session = current->session;
+	port->pgrp = current->pgrp;
+	filep->private_data = port;
+	MOD_INC_USE_COUNT;
+	return 0;			/* success */
+}
+
+int sab8253xc_release(struct inode *inodep, struct file *filep)
+{
+	SAB_PORT *port = (SAB_PORT*) filep->private_data;
+	unsigned long flags;
+	
+	save_flags(flags); cli();
+	
+	--(port->count);
+	if(port->count <= 0)
+	{
+		sab8253x_shutdownN(port);
+		Sab8253xCleanUpTransceiveN(port);
+		port->count = 0;
+		port->open_type = OPEN_NOT;
+	}
+	sab8253xc_fasync(-1, filep, 0);
+	MOD_DEC_USE_COUNT;
+	restore_flags(flags);
+	return 0;
+}
+
+unsigned int sab8253xc_poll(struct file *fileobj, struct poll_table_struct *polltab)
+{
+	SAB_PORT *port = fileobj->private_data;
+	unsigned int mask = 0;
+	
+	poll_wait(fileobj, &port->write_wait, polltab);
+	poll_wait(fileobj, &port->read_wait, polltab);
+	if(port->rx_empty == 0)
+	{
+		mask |= POLLIN | POLLRDNORM;
+	}
+	if(port->tx_full == 0)
+	{
+		mask |= POLLOUT | POLLWRNORM;
+	}
+	return mask;
+}
+
+int sab8253xc_ioctl(struct inode *iobj, struct file *fileobj, unsigned int cmd, unsigned long length)
+{
+	return 0;
+}
+
+int sab8253xc_fasync(int fd, struct file * fileobj, int mode)
+{
+	SAB_PORT *port = fileobj->private_data;
+	
+	return fasync_helper(fd, fileobj, mode, &port->async_queue); /* I am a little baffled -- does async_helper */
+				/* work on the basis of a port or on an open */
+				/* basis*/
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xctl.h linux/drivers/net/wan/8253x/8253xctl.h
--- linux.orig/drivers/net/wan/8253x/8253xctl.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xctl.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,337 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+/* These structures and symbols are less related to the ESCC2s and ESCC8s per se and more to */
+/* the architecture of Aurora cards or to the logic of the driver */
+
+#ifndef _ATICNTRL_H_
+#define _ATICNTRL_H_
+
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/autoconf.h>
+#include <asm/page.h>
+#include "Reg9050.h"
+#include "8253x.h"
+
+#define FALSE	0
+#define TRUE	1
+
+#define NUMINTS 32
+
+/* The following are suggested by serial.h -- all not currently used */
+#define FLAG8253X_HUP_NOTIFY	0x0001 /* Notify getty on hangups and closes 
+					  on the callout port */ 
+#define FLAG8253X_FOURPORT	0x0002 /* Set OU1, OUT2 per AST Fourport settings */
+#define FLAG8253X_SAK		0x0004 /* Secure Attention Key (Orange book) */
+#define FLAG8253X_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+#define FLAG8253X_SPD_MASK	0x1030
+#define FLAG8253X_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+#define FLAG8253X_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define FLAG8253X_SPD_CUST	0x0030  /* Use user-specified divisor */
+#define FLAG8253X_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+#define FLAG8253X_AUTO_IRQ	0x0080 /* Do automatic IRQ during autoconfiguration */
+
+#define FLAG8253X_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define FLAG8253X_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define FLAG8253X_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define FLAG8253X_HARDPPS_CD	0x0800	/* Call hardpps when CD goes high  */
+#define FLAG8253X_SPD_SHI	0x1000	/* Use 230400 instead of 38400 bps */
+#define FLAG8253X_SPD_WARP	0x1010	/* Use 460800 instead of 38400 bps */
+
+#define FLAG8253X_LOW_LATENCY	0x2000 /* Request low latency behaviour */
+
+#define FLAG8253X_BUGGY_UART	0x4000 /* This is a buggy UART, skip some safety
+					* checks.  Note: can be dangerous! */
+
+#define FLAG8253X_AUTOPROBE	0x8000 /* Port was autoprobed by PCI or PNP code */
+
+#define FLAG8253X_FLAGS		0x7FFF	/* Possible legal async flags */
+#define FLAG8253X_USR_MASK	0x3430	/* Legal flags that non-privileged
+					 * users can set or reset */
+
+/* Internal flags used only by the 8253x driver */
+#define FLAG8253X_INITIALIZED	0x80000000 /* Serial port was initialized */
+#define FLAG8253X_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */
+#define FLAG8253X_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+#define FLAG8253X_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+#define FLAG8253X_CLOSING	0x08000000 /* Serial port is closing */
+#define FLAG8253X_CTS_FLOW	0x04000000 /* Do CTS flow control */
+#define FLAG8253X_CHECK_CD	0x02000000 /* i.e., CLOCAL */
+#define FLAG8253X_NETWORK	0x01000000 /* the logic of callout
+					    * and reconnect works differently
+					    * for network ports*/
+
+#define FLAG8253X_CONS_FLOW	0x00800000 /* flow control for console  */
+
+#define FLAG8253X_INTERNAL_FLAGS 0xFF800000 /* Internal flags */
+
+#define SAB8253X_CLOSING_WAIT_INF	0
+#define SAB8253X_CLOSING_WAIT_NONE	65535
+
+#define SAB8253X_EVENT_WRITE_WAKEUP 0
+
+typedef struct AuraXX20params
+{
+	unsigned debug;		/* lots of kernel warnings */
+	unsigned listsize;		/* size of descriptor list */
+} AURAXX20PARAMS;
+
+/* initialization functions */
+extern unsigned int
+plx9050_eprom_read(unsigned int* eprom_ctl, unsigned short *ptr, unsigned char addr, unsigned short len);
+extern unsigned int 
+plx9050_eprom_cmd(unsigned int* eprom_ctl, unsigned char cmd, unsigned char addr, unsigned short data);
+extern void dump_ati_adapter_registers(unsigned int *addr, int len);
+
+/* common routine */
+extern void sab8253x_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/* net device functions */
+extern int Sab8253xInitDescriptors2(SAB_PORT *priv, int listsize, int rbufsize);
+extern int sab8253xn_init(struct net_device *dev); /* called by registration */
+extern int sab8253xn_write2(struct sk_buff *skb, struct net_device *dev); 
+				/* hard_start_xmit */
+extern int sab8253xn_ioctl(struct net_device *dev, struct ifreq *ifr,
+			   int cmd); 
+				/* interrupt handler */
+extern void sab8253xn_handler2(int irq, void *devidp, struct pt_regs* ptregsp);
+extern int sab8253xn_open(struct net_device *dev);
+extern int sab8253xn_release(struct net_device *dev);	/* stop */
+extern struct net_device_stats *sab8253xn_stats(struct net_device *dev);
+
+extern struct net_device *Sab8253xRoot;
+extern struct net_device auraXX20n_prototype;
+extern SAB_PORT *current_sab_port;
+extern int sab8253xn_listsize;
+extern int sab8253xn_rbufsize;
+extern int sab8253xt_listsize;
+extern int sab8253xt_rbufsize;
+extern int sab8253xs_listsize;
+extern int sab8253xs_rbufsize;
+extern int sab8253xc_listsize;
+extern int sab8253xc_rbufsize;
+
+/* character device functions */
+
+extern int 
+sab8253xc_read(struct file *filep, char *cptr, size_t cnt, loff_t *loffp);
+extern int sab8253xc_write(struct file *filep, const char *cptr, size_t cnt, loff_t *loffp);
+extern int sab8253xc_open(struct inode *inodep, struct file *filep);
+extern int sab8253xc_release(struct inode *inodep, struct file *filep);
+extern unsigned int sab8253xc_poll(struct file *, struct poll_table_struct *);
+extern int sab8253xc_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+extern int sab8253xc_fasync(int, struct file *, int);
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+#define SERIAL_PARANOIA_CHECK
+#define SERIAL_DO_RESTART
+
+/* sync tty functions */
+
+/* general macros */
+#define DEBUGPRINT(arg) if(DRIVER_DEBUG()) printk arg
+#define	MIN(a,b) (((a)<(b))?(a):(b))
+#define	MAX(a,b) (((a)>(b))?(a):(b))
+
+extern AURAXX20PARAMS AuraXX20DriverParams;
+#define DRIVER_DEBUG() (AuraXX20DriverParams.debug)
+#define DRIVER_LISTSIZE() (AuraXX20DriverParams.listsize)
+#define XSETDRIVER_LISTSIZE(arg) (AuraXX20DriverParams.listsize = (arg))
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+#define	net_device_stats enet_statistics
+#define net_device device
+#define pci_base_address(p, n)  (p)->base_address[n]
+#define dev_kfree_skb_irq(s) dev_kfree_skb((s))
+#define dev_kfree_skb_any(s) dev_kfree_skb((s))
+#else  /* LINUX_VERSION_CODE */
+#define NETSTATS_VER2
+#define pci_base_address(p, n) pci_resource_start((p), (n))
+#endif /* LINUX_VERSION_CODE */
+
+				/* The sample LINUX driver */
+				/* uses these no reason not */
+				/* to be more dynamic.*/
+
+/* Below are things that should be placed in <linux/pci_ids.h> */
+#ifndef PCI_VENDOR_ID_AURORATECH
+#define PCI_VENDOR_ID_AURORATECH 0x125c
+                                  /* Saturn and Apollo boards */ 
+#define PCI_DEVICE_ID_AURORATECH_MULTI   0x0101 
+                                  /* WAN/LAN Multiservers */
+#define PCI_DEVICE_ID_AURORATECH_WANMS   0x0102  
+                                  /* Comnpact PCI boards */
+#define PCI_DEVICE_ID_AURORATECH_CPCI    0x0103  
+#endif /* PCI_VENDOR_ID_AURORATECH */
+
+extern int sab8253x_vendor_id;
+extern int sab8253x_cpci_device_id;
+extern int sab8253x_wmcs_device_id;
+extern int sab8253x_mpac_device_id;
+
+#define PCIMEMVALIDMULTI	((sab8253x_vendor_id << 16) | sab8253x_mpac_device_id)
+#define PCIMEMVALIDCPCI		((sab8253x_vendor_id << 16) | sab8253x_cpci_device_id)
+#define PCIMEMVALIDWMCS		(sab8253x_vendor_id | (sab8253x_wmcs_device_id << 16))
+
+/* 
+ * Some values defining boards
+ *
+ * First 1, 2, 4 and 8 ports Multiports
+ */
+
+#define AURORA_8X20_CHIP_NPORTS      8
+#define AURORA_4X20_CHIP_NPORTS      2 /* uses two ESCC2s */
+#define AURORA_2X20_CHIP_NPORTS      2
+#define AURORA_1X20_CHIP_NPORTS      1
+
+				/* sizes of PLX9050 address space */
+#define AURORA_4X20_SIZE		0x800 
+#define AURORA_4X20_CHIP_OFFSET           0x400
+#define AURORA_8X20_SIZE		0x200
+#define AURORA_8X20_CHIP_OFFSET           0x0
+#define AURORA_2X20_SIZE		0x80 /* This looks wrong probably las0 size */
+#define AURORA_2X20_CHIP_OFFSET           0x0
+
+#define AURORA_MULTI_1PORTBIT		PLX_CTRL_USERIO3DATA
+#define AURORA_MULTI_SYNCBIT		PLX_CTRL_USERIO3DIR
+
+#define AURORA_MULTI_CLKSPEED	((unsigned long) 29491200) /* 29.4912 MHz */
+#define SUN_SE_CLKSPEED	        ((unsigned long) 29491200) /* 29.4912 MHz */
+
+/*
+ * Per-CIM structure
+ */
+
+#define CIM_SEPLEN	128	/* serial EPROM length on a CIM */
+#define CIM_REVLEN	17
+#define CIM_SNLEN	17
+#define CIM_MFGLOCLEN	17
+#define CIM_MFGDATELEN	33
+
+/* CIM types: */
+#define CIM_UNKNOWN	0
+#define CIM_RS232	1	/* RS-232 only CIM */
+#define CIM_SP502	2	/* SP502 multi-mode CIM */
+
+/* CIM flags: */
+#define CIM_SYNC	0x0000001	/* sync allowed */
+#define CIM_PROTOTYPE	0x0000002	/* prototype */
+#define CIM_LAST	0x0000100	/* the last CIM */
+
+typedef struct aura_cim 
+{
+	int			ci_type;	/* CIM type */
+	unsigned long	 	ci_flags;	/* CIM flags */
+	int			ci_num;	/* the canonical number of this CIM */
+	int			ci_port0lbl;	/* what's the label on port 0 */
+	unsigned int	 	ci_nports;	/* the number of ports on this CIM */
+	struct sab_board	*ci_board;	/* pointer back to the board */
+	struct sab_chip		*ci_chipbase;	/* first chip */
+	struct sab_port		*ci_portbase;	/* first port */
+	unsigned long	 	ci_clkspeed;	/* the clock speed */
+	unsigned int		ci_clkspdsrc;
+	int			ci_spdgrd;	/* chip speed grade */
+	unsigned int		ci_spdgrdsrc;
+	unsigned char	 	ci_sep[CIM_SEPLEN];
+	unsigned char	 	ci_rev[CIM_REVLEN];	/* revision information */
+	unsigned char	 	ci_sn[CIM_SNLEN];	/* serial number */
+	unsigned char	 	ci_mfgdate[CIM_MFGDATELEN];
+	unsigned char	 	ci_mfgloc[CIM_MFGLOCLEN];
+	struct aura_cim		*next;
+	struct aura_cim		*next_by_mcs;
+} aura_cim_t, AURA_CIM;
+
+/*
+ * Board structure
+ */
+
+typedef struct sab_board 
+{
+	struct sab_board 	*nextboard;
+	struct sab_board	*next_on_interrupt;
+	
+	struct sab_chip		*board_chipbase;	/* chip list for this board */
+	struct sab_port		*board_portbase;	/* port list for this board */
+	unsigned int		board_number;
+	
+#define BD_1020P	1
+#define BD_1520P	2
+#define BD_2020P	3
+#define BD_2520P	4
+#define BD_4020P	5
+#define BD_4520P	6
+#define BD_8020P	7
+#define BD_8520P	8
+#define BD_SUNSE	9	/* Sun's built-in 82532 -- not supported by this driver*/
+#define BD_WANMCS	10	
+#define BD_1020CP	11	/* CPCI start here */
+#define BD_1520CP	12
+#define BD_2020CP	13
+#define BD_2520CP	14
+#define BD_4020CP	15
+#define BD_4520CP	16
+#define BD_8020CP	17
+#define BD_8520CP	18
+#define BD_ISCPCI(x)	((x) == BD_1020CP || (x) == BD_1520CP		\
+			 || (x) == BD_2020CP || (x) == BD_2520CP	\
+			 || (x) == BD_4020CP || (x) == BD_4520CP	\
+			 || (x) == BD_8020CP || (x) == BD_8520CP)
+
+	unsigned char		b_type;
+	unsigned char		b_nchips;	/* num chips for this board */
+	unsigned char		b_nports;	/* num ports for this board */
+	unsigned char		b_flags;	/* flags: */
+#define BD_SYNC		0x01	/* sync is allowed on this board */
+#define BD_INTRHI	0x02	/* intr is hi level (SPARC only) */
+	struct pci_dev      	b_dev;         /* what does PCI knows about us */
+	int                  	b_irq;           /* For faster access */
+	unsigned char		*b_chipregbase;	/* chip register io */
+	long		 	b_clkspeed;	/* the clock speed */
+	int			b_spdgrd;	/* chip speed grade */
+	unsigned short		b_intrmask;	/* wanmcs interrupt mask */
+	unsigned char*		virtbaseaddress0;
+	unsigned int		length0;
+	unsigned char*		virtbaseaddress1;
+	unsigned int		length1;
+	unsigned char*		virtbaseaddress2;
+	unsigned int		length2;
+	unsigned char*		virtbaseaddress3;
+	unsigned int		length3;
+  
+  /*
+   * Pointer to hardware-specific electrical interface code.  This
+   *  routine will set the electrical interface to whatever is in
+   *  the given interface/txena pair.
+   * Returns 0 if it could not set the value, non-zero otherwise.
+   */
+	int			(*b_setif)(struct sab_port *line,
+					   int interface, int txena);
+	/*
+	 * hardware mapping
+	 */
+	unsigned int	 	b_eprom[64];	/* serial EPROM contents */
+	AURA_CIM		*b_cimbase;	/* CIM information */
+	PLX9050		*b_bridge;	/* PCI bridge ctlr. regs. */
+} sab_board_t, SAB_BOARD;	/* really hate the _t convention */
+
+#define SEPROM 1		/* driver got clock speed from SEPROM */
+
+#define SAB8253X_XMIT_SIZE PAGE_SIZE
+
+extern char *aura_functionality[];
+
+#endif /* _ATICNTRL_H_ */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xdbg.c linux/drivers/net/wan/8253x/8253xdbg.c
--- linux.orig/drivers/net/wan/8253x/8253xdbg.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xdbg.c	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,64 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include "8253xctl.h"
+#include "Reg9050.h"
+#if 0 				/* only during debugging */
+#undef DEBUGPRINT
+#define DEBUGPRINT(arg) printk arg
+#endif
+
+void dump_ati_adapter_registers(unsigned int *addr, int len)
+{
+	int index;
+	int flag = 1;
+	
+	for(index = 0; index < (len/(sizeof(unsigned int*))); ++index)
+	{
+		if(flag)
+		{
+			DEBUGPRINT((KERN_ALERT "bridge: %4.4x:%8.8x", (4*index), *addr++));
+		}
+		else
+		{
+			DEBUGPRINT(("%8.8x", *addr++));
+		}
+		if(((index + 1) % 8) == 0)
+		{
+			DEBUGPRINT(("\n"));
+			flag = 1;
+		}
+		else
+		{
+			DEBUGPRINT((" "));
+			flag = 0;
+		}
+	}
+	if(flag == 0)
+	{
+		DEBUGPRINT(("\n"));
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xini.c linux/drivers/net/wan/8253x/8253xini.c
--- linux.orig/drivers/net/wan/8253x/8253xini.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xini.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,3043 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include "Reg9050.h"
+#include "8253xctl.h"
+#include "ring.h"
+#include "8253x.h"
+#include "crc32dcl.h"
+#include "8253xmcs.h"
+#include "sp502.h"
+
+/* card names */
+
+char *aura_functionality[] =
+{
+	"NR",
+	"AO",
+	"NA",
+	"UN"
+};
+
+char *board_type[] =
+{
+	"unknown",
+	"1020P",
+	"1520P",
+	"2020P",
+	"2520P",
+	"4020P",
+	"4520P",
+	"8020P",
+	"8520P",
+	"SUNSE",
+	"WANMS",
+	"1020C",
+	"1520C",
+	"2020C",
+	"2520C",
+	"4020C",
+	"4520C",
+	"8020C",
+	"8520C",
+};
+
+unsigned int sab8253x_rebootflag = 0;
+
+AURAXX20PARAMS AuraXX20DriverParams; /* loaded at startup */
+				/* from variables below */
+SAB_BOARD *AuraBoardRoot = NULL; /* The order of this list is not important */
+SAB_CHIP  *AuraChipRoot = NULL;	/* chips grouped by board chip0 before chip1 */
+SAB_PORT  *AuraPortRoot = NULL;	/* ports grouped by board and by chip, chip0, chip1, etc */
+AURA_CIM  *AuraCimRoot = NULL;	/* only used for deallocating the cim structures, etc */
+/* CIM stands for Communications Interface Module -- the G.Link logic provided by the Altera parts. */
+
+/* Arrays of lists of boards of each type on a given interrupt */
+SAB_BOARD *AuraBoardESCC2IrqRoot[NUMINTS]; 
+SAB_BOARD *AuraBoardESCC8IrqRoot[NUMINTS];
+SAB_BOARD *AuraBoardMCSIrqRoot[NUMINTS];
+
+unsigned int NumSab8253xPorts = 0;
+
+unsigned BD1020Pcounter = 0;	/* keep count of each board */
+unsigned BD1520Pcounter = 0;	/* may change to just keeping count */
+unsigned BD2020Pcounter = 0;	/* of the total number of boards */
+unsigned BD2520Pcounter = 0;
+unsigned BD4020Pcounter = 0;
+unsigned BD4520Pcounter = 0;
+unsigned BD8020Pcounter = 0;
+unsigned BD8520Pcounter = 0;
+
+unsigned BD1020CPcounter = 0;	/* keep count of each board */
+unsigned BD1520CPcounter = 0;	/* may change to just keeping count */
+unsigned BD2020CPcounter = 0;	/* of the total number of boards */
+unsigned BD2520CPcounter = 0;
+unsigned BD4020CPcounter = 0;
+unsigned BD4520CPcounter = 0;
+unsigned BD8020CPcounter = 0;
+unsigned BD8520CPcounter = 0;
+
+unsigned BDMCScounter = 0;
+
+
+static int auraXX20n_debug = 0;	/* turns on lots of */
+				/* debugging messages*/
+static char* auraXX20n_name = 0;/* set net dev name on command line */
+static char *sab8253xc_name = "sab8253xc";
+static int sab8253xc_major = 0;
+int sab8253xn_listsize = 32; /* recommend descriptor list size */
+int sab8253xn_rbufsize = RXSIZE; /* recommend rbuf list size */
+int sab8253xt_listsize = 256; /* recommend descriptor list size */
+int sab8253xt_rbufsize = 32; /* recommend rbuf list size for tty */
+int sab8253xs_listsize = 64; /* recommend descriptor list size */
+int sab8253xs_rbufsize = RXSIZE; /* recommend rbuf list size */
+int sab8253xc_listsize = 64; /* recommend descriptor list size */
+int sab8253xc_rbufsize = RXSIZE; /* recommend rbuf list size for tty */
+int xx20_minorstart = 128;
+int sab8253x_vendor_id = PCI_VENDOR_ID_AURORATECH;
+int sab8253x_cpci_device_id = PCI_DEVICE_ID_AURORATECH_CPCI;
+int sab8253x_wmcs_device_id = PCI_DEVICE_ID_AURORATECH_WANMS;
+int sab8253x_mpac_device_id = PCI_DEVICE_ID_AURORATECH_MULTI;
+int sab8253x_default_sp502_mode = SP502_RS232_MODE;
+
+MODULE_PARM(sab8253x_vendor_id, "i");
+MODULE_PARM(sab8253x_cpci_device_id, "i");
+MODULE_PARM(sab8253x_wmcs_device_id, "i");
+MODULE_PARM(sab8253x_mpac_device_id, "i");
+MODULE_PARM(sab8253x_default_sp502_mode, "i");
+
+MODULE_PARM(xx20_minorstart, "i");
+MODULE_PARM(sab8253xc_major, "i");
+MODULE_PARM(auraXX20n_debug, "i");
+MODULE_PARM(auraXX20n_name, "s"); /* this and the following for sync */
+MODULE_PARM(sab8253xn_listsize, "i"); /* network driver */
+MODULE_PARM(sab8253xn_rbufsize, "i"); /* network driver */
+MODULE_PARM(sab8253xt_listsize, "i"); /* tty driver */
+MODULE_PARM(sab8253xt_rbufsize, "i"); /* tty driver */
+MODULE_PARM(sab8253xc_listsize, "i"); /* network driver */
+MODULE_PARM(sab8253xc_rbufsize, "i"); /* network driver */
+MODULE_PARM(sab8253xs_listsize, "i"); /* tty driver */
+MODULE_PARM(sab8253xs_rbufsize, "i"); /* tty driver */
+MODULE_PARM(sab8253xc_name, "s"); 
+
+struct pci_dev   *XX20lastpdev = NULL; /* just used for finding all PCI devices */
+static SAB_BOARD *find_ati_multiport_card(void); /* actually implemented */
+static SAB_BOARD *find_ati_cpci_card(void); /* to be done */
+static SAB_BOARD *find_ati_wanms_card(void); /* to be done */
+
+#if (!defined(MODULE)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+				/* unpleasantness for 2.2 kernels
+				 * and probe illogic */
+
+				/* The LRP project is still working on
+				   2.2.* kernels but I suspect
+				   that initially we will see more
+				   purchases for complete Linux
+				   machines using 2.4.*, LRP
+				   machines tend to be underpowered
+				   and have a paucity of PCI slots
+				*/
+
+unsigned int do_probe = 1;
+#endif
+
+				/* One could argue that these could be in  */
+				/* the 8253xnet.c file but they are fairly */
+				/* intimately involved with initialization.*/
+struct net_device *Sab8253xRoot = NULL;
+
+struct net_device auraXX20n_prototype = /* used for the network device */
+{
+	"8253x0",			
+	0, 0, 0, 0,
+	0x000,
+	-1, /* bad irq */
+	0, 0, 0,
+	NULL,
+	sab8253xn_init /* network driver initialization */
+};
+
+struct file_operations sab8253xc_fops =
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0))
+	NULL,
+#endif
+	NULL,			/* llseek */
+	sab8253xc_read,		/* read */
+	sab8253xc_write,	/* write */
+	NULL,			/* readdir */
+	sab8253xc_poll,		/* poll */
+	sab8253xc_ioctl,	/* ioctl */
+	NULL,			/* mmap */
+	sab8253xc_open,		/* open */
+	NULL,			/* flush */
+	sab8253xc_release,	/* release */
+	NULL,			/* fsync */
+	sab8253xc_fasync,	/* fasync */
+	NULL,			/* check_media_change */
+	NULL,			/* revalidate */
+	NULL			/* lock */
+};
+
+
+/* A few function defined in this file */
+/* These functions are basically functionality */
+/* independent -- they are used with asynchronous ttys */
+/* synchronous ttys, the network device and the */
+/* raw character device */
+
+				/* used for reading and writing ports
+				   readw and writew require some reprogramming
+				   of the PLX9050
+				*/
+static unsigned char aura_readb(struct sab_port *port, unsigned char *reg);
+static unsigned char wmsaura_readb(struct sab_port *port, unsigned char *reg);
+static unsigned short aura_readw(struct sab_port *port, unsigned short *reg);
+static unsigned short wmsaura_readw(struct sab_port *port, unsigned short *reg);
+static void aura_writeb(struct sab_port *port, unsigned char *reg,unsigned char val);
+static void wmsaura_writeb(struct sab_port *port, unsigned char *reg,unsigned char val);
+static void aura_writew(struct sab_port *port, unsigned short *reg,unsigned short val);
+static void wmsaura_writew(struct sab_port *port, unsigned short *reg,unsigned short val);
+
+static void aura_readfifo(struct sab_port *port, unsigned char *buf, unsigned int nbytes);
+static void aura_writefifo(struct sab_port *port);
+
+static void wmsaura_readfifo(struct sab_port *port, unsigned char *buf, unsigned int nbytes);
+static void wmsaura_writefifo(struct sab_port *port);
+
+/* function definitions */
+
+/* [124]X20 type cards */
+static void DisableESCC2Interrupts(SAB_CHIP *chipptr) /* in processing ports may have to disable ints */
+{
+	struct sab82532_async_wr_regs *regs;
+	
+	regs = chipptr->c_regs;
+	writeb(0xff,&regs->pim);	/* All interrupts off */
+				/* Note that regs/->c_regs
+				   is set to base reg
+				   address, thus taking
+				   address or regs->pim
+				   gets the address of
+				   the PIM register/int mask */
+}
+
+static SAB_CHIP* CreateESCC2(SAB_BOARD *bptr, unsigned int offset)
+{
+	SAB_CHIP *cptr;
+	struct sab82532_async_wr_regs *regs;
+	
+	printk(KERN_ALERT 
+	       "auraXX20n: creating ESCC2 structure on board %p at offset %x.\n",
+	       bptr, offset);
+	
+	cptr = (SAB_CHIP*) kmalloc(sizeof(SAB_CHIP), GFP_KERNEL);
+	if(cptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC2 structure on board %p at offset %x.\n",
+		       bptr, offset);
+		return NULL;
+	}
+	memset(cptr, 0, sizeof(SAB_CHIP));
+	cptr->chip_type = ESCC2;
+	cptr->c_board = bptr;
+	cptr->c_cim = NULL;
+	cptr->c_chipno = (offset ? 1 : 0); /* first or second chip on board */
+	cptr->c_revision = 
+		(readb(((char *)bptr->virtbaseaddress2) + offset + SAB85232_REG_VSTR) &
+		 SAB82532_VSTR_VN_MASK);
+	cptr->c_nports = 2;
+	cptr->c_portbase = NULL;
+	cptr->next = AuraChipRoot;	/* chips are added to chiplist in reverse order */
+	AuraChipRoot = cptr;
+	cptr->next_by_board = bptr->board_chipbase; /* likewise for the local board chiplist */
+	bptr->board_chipbase = cptr;
+	printk(KERN_ALERT "auraXX20n: chip %d on board %p is revision %d.\n",
+	       cptr->c_chipno, bptr, cptr->c_revision);
+	
+	/* lets set up the generic parallel
+	 * port register which is used to
+	 * control signaling and other stuff*/
+	/*
+	 * SAB82532 (Aurora) 1 8-bit parallel port
+	 * To summarize the use of the parallel port:
+	 *                    RS-232
+	 *  A       B        I/O     descr
+	 * P0      P4      output  TxClk ctrl
+	 * P1      P5      output  DTR
+	 * P2      P6      input   DSR
+	 * P3      P7      output  485 control
+	 *
+	 */
+	/*
+	 * Configuring the parallel port 
+	 */
+	
+	regs = (struct sab82532_async_wr_regs *)(((char *)bptr->virtbaseaddress2) + offset);
+	
+	DEBUGPRINT((KERN_ALERT "Writing 0x44 to 0x%p + 0x%x for chip %d\n",
+		    regs, SAB82532_REG_PCR, cptr->c_chipno));
+	
+	writeb(0x44,&regs->pcr);  /* 2 input bits */
+	writeb(0xff,&regs->pim);/* All interrupts off */
+	writeb(0x33,&regs->pvr); /* Txclk and DTR low  */
+	
+	cptr->c_regs = (void*) regs;
+	cptr->int_disable = DisableESCC2Interrupts;
+	return cptr;
+}
+
+static void CreateESCC2Port(SAB_CHIP *cptr, unsigned int portno, unsigned int function)
+{
+	SAB_BOARD *bptr;
+	SAB_PORT  *pptr;
+	extern void sab8253x_setup_ttyport(struct sab_port *p_port) ;
+	
+	++NumSab8253xPorts;
+	bptr = cptr->c_board;
+	pptr = (SAB_PORT*) kmalloc(sizeof(SAB_PORT), GFP_KERNEL);
+	if(pptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC2 port structure on chip %p on board %p.\n",
+		       cptr, bptr);
+		return;
+	}
+	memset(pptr, 0, sizeof(SAB_PORT));
+	DEBUGPRINT
+		((KERN_ALERT "Setting up port %d, chipno %d for %s type board number %d.\n", 
+		  portno, cptr->c_chipno, board_type[bptr->b_type],bptr->board_number));
+	pptr->portno = portno;
+	pptr->chip=cptr;
+	pptr->board=bptr;
+	pptr->open_type=OPEN_NOT;
+	pptr->is_console=0;
+	pptr->regs=
+		(union sab82532_regs *)
+		(((unsigned int)cptr->c_regs) +
+		 (portno * SAB82532_REG_SIZE));
+	pptr->type = cptr->c_revision;
+	pptr->function = function;
+	
+	/* Simpify reading */
+#define PVR  pptr->regs->async_write.pvr
+#define PCR  pptr->regs->async_write.pcr
+#define PIM  pptr->regs->async_write.pim
+#define ISR0 pptr->regs->async_read.isr0
+#define IMR0 pptr->regs->async_write.imr0
+#define IMR1 pptr->regs->async_write.imr1
+#define PIS  pptr->regs->async_read.pis
+#define VSTR pptr->regs->async_read.vstr
+#define STAR pptr->regs->async_read.star
+#define MODE pptr->regs->async_read.mode
+	
+	pptr->irq = bptr->b_irq;
+	if(portno == 0) 
+	{ /* Port A .... */
+		pptr->dsr.reg=(unsigned char *)&(PVR);
+		pptr->dsr.mask=0x04;
+		pptr->dsr.irq=PIS_IDX;
+		pptr->dsr.irqmask=0x04;
+		
+		pptr->dtr.reg=(unsigned char *)&(PVR);
+		pptr->dtr.mask=0x02;
+		
+		pptr->txclkdir.reg=(unsigned char *)&(PVR);
+		pptr->txclkdir.mask=0x01;
+	} 
+	else 
+	{ /* Port B */
+		pptr->dsr.reg=(unsigned char *)&(PVR);
+		pptr->dsr.mask=0x40;
+		pptr->dsr.irq=PIS_IDX;
+		pptr->dsr.irqmask=0x40;
+		
+		pptr->dtr.reg=(unsigned char *)&(PVR);
+		pptr->dtr.mask=0x20;
+		
+		pptr->txclkdir.reg=(unsigned char *)&(PVR);
+		pptr->txclkdir.mask=0x10;
+	}
+	pptr->dsr.inverted=1;
+	pptr->dsr.cnst = 0;
+	pptr->dtr.inverted=1;
+	pptr->dtr.cnst = 0;
+	pptr->txclkdir.inverted=1;
+	
+	pptr ->dcd.reg =(unsigned char *) &(VSTR);
+	
+	DEBUGPRINT((KERN_ALERT "cd register set to 0x%p\n", pptr ->dcd.reg));
+	
+	pptr->dcd.mask = SAB82532_VSTR_CD;
+	pptr->dcd.inverted = 1;
+	pptr->dcd.irq=ISR0_IDX;
+	pptr->dcd.irqmask=SAB82532_ISR0_CDSC;
+	pptr->dcd.cnst = 0;
+	
+	pptr->cts.reg = (unsigned char *)&(STAR);
+	pptr->cts.mask = SAB82532_STAR_CTS;
+	pptr->cts.inverted = 0;
+	pptr->cts.irq=ISR1_IDX;
+	pptr->cts.irqmask=SAB82532_ISR1_CSC;
+	pptr->cts.cnst = 0;
+	
+	pptr->rts.reg = (unsigned char *)&(MODE);
+	pptr->rts.mask = SAB82532_MODE_FRTS;
+	pptr->rts.inverted = 1;
+	pptr->rts.cnst = SAB82532_MODE_RTS;
+	
+	
+	/* Set the read and write function */
+	pptr->readbyte=aura_readb;
+	pptr->readword=aura_readw;
+	pptr->writebyte=aura_writeb;
+	pptr->writeword=aura_writew;
+	pptr->readfifo=aura_readfifo;
+	pptr->writefifo=aura_writefifo;
+	
+	sab8253x_setup_ttyport(pptr);	/* asynchronous */
+	/* ttys are default, basic */
+	/* initialization, everything */
+	/* else works as a modification */
+	/* thereof */
+	
+	pptr->next = AuraPortRoot;
+	AuraPortRoot = pptr;
+	pptr->next_by_chip = cptr->c_portbase;
+	cptr->c_portbase = pptr;
+	pptr->next_by_board = bptr->board_portbase;
+	bptr->board_portbase = pptr;
+}
+
+/* 8x20 type functions */
+
+static void DisableESCC8Interrupts(SAB_CHIP *chipptr)
+{
+	unsigned int regbase;		/* a lot more to do for ESCC8 */
+	
+	regbase = (unsigned int) chipptr->c_regs;
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_A); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_B); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_C); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_D); /* All interrupts off */
+}
+
+static SAB_CHIP* CreateESCC8(SAB_BOARD *bptr, unsigned int offset)
+{
+	SAB_CHIP *cptr;
+	unsigned int regbase;
+	
+	printk(KERN_ALERT 
+	       "auraXX20n: creating ESCC8 structure on board %p at offset %x.\n",
+	       bptr, offset);
+	
+	cptr = (SAB_CHIP*) kmalloc(sizeof(SAB_CHIP), GFP_KERNEL);
+	if(cptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC8 structure on board %p at offset %x.\n",
+		       bptr, offset);
+		return NULL;
+	}
+	memset(cptr, 0, sizeof(SAB_CHIP));
+	cptr->chip_type = ESCC8;
+	cptr->c_board = bptr;
+	cptr->c_cim = NULL;
+	cptr->c_chipno = (offset ? 1 : 0); /* no card actually has 2 ESCC8s on it */
+	cptr->c_revision = 
+		(readb(((char *)bptr->virtbaseaddress2) + offset + SAB85232_REG_VSTR) & 
+		 SAB82532_VSTR_VN_MASK);
+	cptr->c_nports = 8;
+	cptr->c_portbase = NULL;	/* used for the list of ports associated
+					   with this chip
+					*/
+	cptr->next = AuraChipRoot;
+	AuraChipRoot = cptr;
+	cptr->next_by_board = bptr->board_chipbase;
+	bptr->board_chipbase = cptr;
+	printk(KERN_ALERT "auraXX20n: chip %d on board %p is revision %d.\n",
+	       cptr->c_chipno, bptr, cptr->c_revision);
+	
+	/* lets set up the generic parallel
+	 * port register which is used to
+	 * control signaling and other stuff*/
+	
+	/* SAB82538 4 8-bits parallel ports
+	 * To summarize the use of the parallel port:
+	 *                    RS-232
+	 * Parallel port A -- TxClkdir control	(output) ports 0 - 7
+	 * Parallel port B -- DTR		(output) ports 0 - 7
+	 * Parallel port C -- DSR		(input)  ports 0 - 7
+	 * Parallel port D -- driver power down 	(output) drivers 0 - 3
+	 *
+	 * Note port D is not used on recent boards
+	 */
+	
+	regbase = (unsigned int)(((char *)bptr->virtbaseaddress2) + offset);
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port A (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_A, SAB82538_REG_PIM_A, SAB82538_REG_PVR_A));
+	
+	/* Configuring Parallel Port A  (Clkdir)*/
+	writeb(0x0,((unsigned char *)regbase) + SAB82538_REG_PCR_A);  /* All output bits */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_A); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PVR_A);  /* All low */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port B (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_B,SAB82538_REG_PIM_B,SAB82538_REG_PVR_B));
+	
+	writeb(0x0,((unsigned char *)regbase) + SAB82538_REG_PCR_B);  /* All output bits */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_B); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PVR_B);  /* All low */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port C (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_C, SAB82538_REG_PIM_C, SAB82538_REG_PVR_C));
+	
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PCR_C);  /* All intput bits */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_C); /* All interrupts off */
+	/* don't set port value register on input register */
+	
+	/* Configuring Parallel Port D */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port D (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_D, SAB82538_REG_PIM_D, SAB82538_REG_PVR_D));
+	writeb(0x0f,((unsigned char *)regbase) + SAB82538_REG_PCR_D);  /* 4 input  bits */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_D); /* All interrupts off */
+	/* don't set port value register on input register */
+	
+	/* The priority rotation thing */
+	
+	DEBUGPRINT((KERN_ALERT "Setting IVA (0x%x +  0x%x = 0x%x\n", regbase,
+		    SAB82532_REG_IVA, regbase + SAB82532_REG_IVA));
+	
+	writeb(SAB82538_IVA_ROT, ((unsigned char *)regbase) + SAB82532_REG_IVA); 
+	
+	cptr->c_regs = (void*) regbase;
+	cptr->int_disable = DisableESCC8Interrupts;
+	return cptr;
+}
+
+static void DisableESCC8InterruptsFromCIM(SAB_CHIP *chipptr)
+{
+	unsigned int regbase;		/* a lot more to do for ESCC8 */
+	
+	regbase = (unsigned int) chipptr->c_regs;
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_A)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_B)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_C)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_D)); /* All interrupts off */
+}
+
+static void CreateESCC8Port(SAB_CHIP *cptr, unsigned int portno, unsigned int function)
+{
+	SAB_BOARD *bptr;
+	SAB_PORT  *pptr;
+	extern void sab8253x_setup_ttyport(struct sab_port *p_port) ;
+	
+	++NumSab8253xPorts;
+	bptr = cptr->c_board;
+	pptr = (SAB_PORT*) kmalloc(sizeof(SAB_PORT), GFP_KERNEL);
+	if(pptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC2 port structure on chip %p on board %p.\n",
+		       cptr, bptr);
+		return;
+	}
+	memset(pptr, 0, sizeof(SAB_PORT));
+	DEBUGPRINT
+		((KERN_ALERT "Setting up port %d, chipno %d for %s type board number %d.\n", 
+		  portno, cptr->c_chipno, board_type[bptr->b_type],bptr->board_number));
+	pptr->portno = portno;
+	pptr->chip=cptr;
+	pptr->board=bptr;
+	pptr->open_type=OPEN_NOT;
+	pptr->is_console=0;
+	pptr->regs=
+		(union sab82532_regs *)
+		(((unsigned int)cptr->c_regs) +
+		 (portno * SAB82538_REG_SIZE));
+	pptr->type = cptr->c_revision;
+	pptr->function = function;
+	
+	pptr->irq = bptr->b_irq;
+	
+	pptr->dsr.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_C; 
+	pptr->dsr.mask = 0x1 << portno;
+	pptr->dsr.inverted = 1;
+	pptr->dsr.irq=PIS_IDX;	/* need to check this constant */
+	pptr->dsr.irqmask=0x1 << portno;
+	pptr->dsr.cnst = 0;
+	
+	pptr->txclkdir.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_A;
+	pptr->txclkdir.mask = 0x1 << portno;
+	/* NOTE: Early 8 ports  boards had different tx clkdir sense */
+	pptr->txclkdir.inverted = 1;
+	
+	pptr->dtr.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_B;
+	pptr->dtr.mask = 0x1 << portno;
+	pptr->dtr.inverted = 1;
+	pptr->dtr.cnst = 0;
+	
+	pptr ->dcd.reg = (unsigned char *)&(VSTR);
+	
+	DEBUGPRINT((KERN_ALERT "cd register set to 0x%p\n", pptr ->dcd.reg));
+	
+	pptr->dcd.mask = SAB82532_VSTR_CD;
+	pptr->dcd.inverted = 1;
+	pptr->dcd.irq=ISR0_IDX;
+	pptr->dcd.irqmask=SAB82532_ISR0_CDSC;
+	pptr->dcd.cnst = 0;
+	
+	pptr->cts.reg = (unsigned char *)&(STAR);
+	pptr->cts.mask = SAB82532_STAR_CTS;
+	pptr->cts.inverted = 0;
+	pptr->cts.irq=ISR1_IDX;
+	pptr->cts.irqmask=SAB82532_ISR1_CSC;
+	pptr->cts.cnst = 0;
+	
+	pptr->rts.reg = (unsigned char *)&(MODE);
+	pptr->rts.mask = SAB82532_MODE_FRTS;
+	pptr->rts.inverted = 1;
+	pptr->rts.cnst = SAB82532_MODE_RTS;
+	
+	
+	/* Set the read and write function */
+	pptr->readbyte=aura_readb;
+	pptr->readword=aura_readw;
+	pptr->writebyte=aura_writeb;
+	pptr->writeword=aura_writew;
+	pptr->readfifo=aura_readfifo;
+	pptr->writefifo=aura_writefifo;
+	
+	sab8253x_setup_ttyport(pptr);	/* asynchronous */
+	/* ttys are default, basic */
+	/* initialization, everything */
+	/* else works as a modification */
+	/* thereof */
+	
+	pptr->next = AuraPortRoot;
+	AuraPortRoot = pptr;
+	pptr->next_by_chip = cptr->c_portbase;
+	cptr->c_portbase = pptr;
+	pptr->next_by_board = bptr->board_portbase;
+	bptr->board_portbase = pptr;
+}
+
+/* Multichannel server functions */
+
+static SAB_CHIP* CreateESCC8fromCIM(SAB_BOARD *bptr, AURA_CIM *cim, unsigned int chipno)
+{
+	SAB_CHIP *cptr;
+	unsigned int regbase;
+	
+	printk(KERN_ALERT 
+	       "auraXX20n: creating ESCC8 %d structure on board %p from cim %p.\n",
+	       chipno, bptr, cim);
+	
+	cptr = (SAB_CHIP*) kmalloc(sizeof(SAB_CHIP), GFP_KERNEL);
+	if(cptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC8 structure %d on board %p at from cim %p.\n",
+		       chipno, bptr, cim);
+		return NULL;
+	}
+	
+	memset(cptr, 0, sizeof(SAB_CHIP));
+	cptr->chip_type = ESCC8;
+	cptr->c_board = bptr;
+	cptr->c_cim = cim;
+	cptr->c_chipno = chipno;
+	cptr->c_revision = 
+		(readb((unsigned char *) (bptr->CIMCMD_REG +
+					  (CIMCMD_RDREGB | (((chipno*8) << 6) | SAB85232_REG_VSTR))))
+		 & SAB82532_VSTR_VN_MASK);
+	cptr->c_nports = 8;
+	cptr->c_portbase = NULL;	/* used for the list of ports associated
+					   with this chip
+					*/
+	cptr->next = AuraChipRoot;
+	AuraChipRoot = cptr;
+	cptr->next_by_board = bptr->board_chipbase;
+	bptr->board_chipbase = cptr;
+	
+	cptr->next_by_cim = cim->ci_chipbase;
+	cim->ci_chipbase = cptr;
+	
+	printk(KERN_ALERT "auraXX20n: chip %d on board %p is revision %d.\n",
+	       cptr->c_chipno, bptr, cptr->c_revision);
+	
+	/* lets set up the generic parallel
+	 * port register which is used to
+	 * control signaling and other stuff*/
+	
+	/* SAB82538 4 8-bits parallel ports
+	 * To summarize the use of the parallel port:
+	 *                    RS-232
+	 * Parallel port A -- TxClkdir control	(output) ports 0 - 7
+	 * Parallel port B -- DTR		(output) ports 0 - 7
+	 * Parallel port C -- DSR		(input)  ports 0 - 7
+	 * Parallel port D -- driver power down 	(output) drivers 0 - 3
+	 *
+	 * Note port D is not used on recent boards
+	 */
+	
+	regbase = (unsigned int)
+		(bptr->CIMCMD_REG + (0 | (((chipno*8) << 6) | 0)));	/* need to add in RDB/WRB cmd bits
+									 * and reg offset (> 32) */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port A (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_A, SAB82538_REG_PIM_A, SAB82538_REG_PVR_A));
+	
+	/* Configuring Parallel Port A  (Clkdir)*/
+	writeb(0x00,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PCR_A));  /* All output bits */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_A)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PVR_A));  /* All low */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port B (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_B,SAB82538_REG_PIM_B,SAB82538_REG_PVR_B));
+	
+	writeb(0x00,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PCR_B));  /* All output bits */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_B)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PVR_B));  /* All low */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port C (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_C, SAB82538_REG_PIM_C, SAB82538_REG_PVR_C));
+	
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PCR_C));  /* All intput bits */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_C)); /* All interrupts off */
+	/* don't set port value register on input register */
+	
+	/* Configuring Parallel Port D */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port D (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_D, SAB82538_REG_PIM_D, SAB82538_REG_PVR_D));
+	writeb(0x0f,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PCR_D));  /* 4 input  bits */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_D)); /* All interrupts off */
+	/* don't set port value register on input register */
+	
+	/* The priority rotation thing */
+	
+	DEBUGPRINT((KERN_ALERT "Setting IVA (0x%x +  0x%x = 0x%x\n", regbase,
+		    SAB82532_REG_IVA, regbase + SAB82532_REG_IVA));
+	
+	writeb(SAB82538_IVA_ROT, ((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82532_REG_IVA)); 
+	writeb(0, ((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82532_REG_IPC)); 
+	
+	cptr->c_regs = (void*) regbase;
+	cptr->int_disable = DisableESCC8InterruptsFromCIM;
+	return cptr;
+}
+
+static void CreateESCC8PortWithCIM(SAB_CHIP *cptr, unsigned int portno, 
+				   AURA_CIM *cim, unsigned flag)
+{
+	SAB_BOARD *bptr;
+	SAB_PORT  *pptr;
+	extern void sab8253x_setup_ttyport(struct sab_port *p_port) ;
+	
+	++NumSab8253xPorts;
+	bptr = cptr->c_board;
+	pptr = (SAB_PORT*) kmalloc(sizeof(SAB_PORT), GFP_KERNEL);
+	if(pptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC2 port structure on chip %p on board %p.\n",
+		       cptr, bptr);
+		return;
+	}
+	memset(pptr, 0, sizeof(SAB_PORT));
+	DEBUGPRINT
+		((KERN_ALERT "Setting up port %d, chipno %d for %s type board number %d.\n", 
+		  portno, cptr->c_chipno, board_type[bptr->b_type],bptr->board_number));
+	pptr->portno = portno;
+	pptr->chip=cptr;
+	pptr->board=bptr;
+	pptr->open_type=OPEN_NOT;
+	pptr->is_console=0;
+	pptr->regs=
+		(union sab82532_regs *)
+		(((unsigned int)cptr->c_regs) +
+		 (portno << 6));		/* addressing is different when there is a cim */
+	pptr->type = cptr->c_revision;
+	pptr->function = (((cim->ci_flags & CIM_SYNC) || flag) ? FUNCTION_NR : 
+			  FUNCTION_AO);
+	
+	pptr->irq = bptr->b_irq;
+	
+	pptr->dsr.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_C; 
+	pptr->dsr.mask = 0x1 << portno;
+	pptr->dsr.inverted = 1;
+	pptr->dsr.irq=PIS_IDX;	/* need to check this constant */
+	pptr->dsr.irqmask=0x1 << portno;
+	pptr->dsr.cnst = 0;
+	
+	pptr->txclkdir.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_A;
+	pptr->txclkdir.mask = 0x1 << portno;
+	/* NOTE: Early 8 ports  boards had different tx clkdir sense */
+	pptr->txclkdir.inverted = 1;
+	
+	pptr->dtr.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_B;
+	pptr->dtr.mask = 0x1 << portno;
+	pptr->dtr.inverted = 1;
+	pptr->dtr.cnst = 0;
+	
+	pptr->dcd.reg = ((unsigned char *)pptr->regs) + SAB85232_REG_VSTR;
+	
+	DEBUGPRINT((KERN_ALERT "cd register set to 0x%p\n", pptr->dcd.reg));
+	
+	pptr->dcd.mask = SAB82532_VSTR_CD;
+	pptr->dcd.inverted = 1;
+	pptr->dcd.irq=ISR0_IDX;
+	pptr->dcd.irqmask=SAB82532_ISR0_CDSC;
+	pptr->dcd.cnst = 0;
+	
+	pptr->cts.reg = (unsigned char *)&(STAR);
+	pptr->cts.mask = SAB82532_STAR_CTS;
+	pptr->cts.inverted = 0;
+	pptr->cts.irq=ISR1_IDX;
+	pptr->cts.irqmask=SAB82532_ISR1_CSC;
+	pptr->cts.cnst = 0;
+	
+	pptr->rts.reg = (unsigned char *)&(MODE);
+	pptr->rts.mask = SAB82532_MODE_FRTS;
+	pptr->rts.inverted = 1;
+	pptr->rts.cnst = SAB82532_MODE_RTS;
+	
+	
+	/* Set the read and write function */
+	pptr->readbyte=wmsaura_readb;
+	pptr->readword=wmsaura_readw;
+	pptr->writebyte=wmsaura_writeb;
+	pptr->writeword=wmsaura_writew;
+	pptr->readfifo=wmsaura_readfifo;
+	pptr->writefifo=wmsaura_writefifo;
+	
+	sab8253x_setup_ttyport(pptr);	/* asynchronous */
+	/* ttys are default, basic */
+	/* initialization, everything */
+	/* else works as a modification */
+	/* thereof */
+	
+	pptr->next = AuraPortRoot;
+	AuraPortRoot = pptr;
+	
+	pptr->next_by_chip = cptr->c_portbase;
+	cptr->c_portbase = pptr;
+	
+	pptr->next_by_board = bptr->board_portbase;
+	bptr->board_portbase = pptr;
+	
+	pptr->next_by_cim = cim->ci_portbase;
+	cim->ci_portbase = pptr;
+}
+
+static void CreateCIMs(SAB_BOARD *bptr)
+{
+	unsigned int cimnum;
+	unsigned char *wrcsr;
+	unsigned char *rdcsr;
+	unsigned char tmp;
+	AURA_CIM *cim;
+	unsigned short intrmask;
+	
+	for(intrmask = 0, cimnum = 0; cimnum < MAX_NCIMS; ++cimnum)
+	{
+		intrmask >>= 2;
+		
+		/*
+		 * The hardware is mapped.  Try writing to CIM CSR.
+		 */
+		wrcsr = bptr->CIMCMD_REG +
+			(CIMCMD_WRCIMCSR | (cimnum << CIMCMD_CIMSHIFT));
+		rdcsr = bptr->CIMCMD_REG +
+			(CIMCMD_RDCIMCSR | (cimnum << CIMCMD_CIMSHIFT));
+		
+		/* Try to write an 0xff */
+		writeb((unsigned char) 0xff, (unsigned char *) wrcsr);
+		/* and read it back */
+		tmp = (unsigned char) readb((unsigned char *) rdcsr);
+		DEBUGPRINT((KERN_ALERT 
+			    "aura wan mcs: wrcsr %p rdcsr %p cim %d 0xff readback: 0x%x.\n",
+			    (void*) wrcsr, (void*) rdcsr, cimnum, tmp));
+		
+		/* make sure it's really all ones. */
+		if ((tmp & CIMCMD_CIMCSR_TESTMASK) != CIMCMD_CIMCSR_TESTMASK) 
+		{
+			printk(KERN_ALERT 
+			       "aura wan mcs: not found -- wrcsr %p rdcsr %p cim %d 0xff readback: 0x%x.\n",
+			       (void*) wrcsr, (void*) rdcsr, cimnum, tmp);
+			continue;
+		}
+		
+		/* Try to write a zero */
+		writeb((unsigned char) 0, (unsigned char*) wrcsr);
+		/* and read it back */
+		tmp = (unsigned char) readb((unsigned char *) rdcsr);
+		DEBUGPRINT((KERN_ALERT 
+			    "aura wan mcs: wrcsr %p rdcsr %p cim %d 0x0 readback: 0x%x.\n",
+			    (void*) wrcsr, (void*) rdcsr, cimnum, tmp));
+		
+		/* make sure it's really zero. */
+		if ((tmp & CIMCMD_CIMCSR_TESTMASK) != 0) 
+		{
+			printk(KERN_ALERT 
+			       "aura wan mcs: not found -- wrcsr %p rdcsr %p cim %d 0x0 readback: 0x%x.\n",
+			       (void*) wrcsr, (void*) rdcsr, cimnum, tmp);
+			continue;
+		}
+		cim = (AURA_CIM*) kmalloc(sizeof(AURA_CIM), GFP_KERNEL);
+		if(cim == NULL)
+		{
+			printk(KERN_ALERT 
+			       "aura wan mcs: unable to allocate memory, board %p, cim %d.\n", 
+			       bptr, cimnum); 
+			continue;
+		}
+		cim->ci_num = cimnum;
+		cim->ci_board = bptr;
+		cim->ci_chipbase = NULL;
+		cim->ci_portbase = NULL;
+		cim->ci_nports = CIM_NPORTS;
+		cim->ci_port0lbl = cimnum * CIM_NPORTS;
+		if (mcs_ciminit(bptr, cim) == FALSE) 
+		{
+			kfree(cim);
+			continue;
+		}
+		intrmask |= 0xc0;	/* turn on the high two bits
+					 * a little obscure, borrowed
+					 * from solaris driver 0th cim
+					 * gets lowest two bits*/
+		cim->next = AuraCimRoot;
+		AuraCimRoot = cim;
+		cim->next_by_mcs = bptr->b_cimbase;
+		bptr->b_cimbase = cim;
+		printk(KERN_ALERT 
+		       "aura wan mcs: Created cim %d type %d on board %p.\n",
+		       cim->ci_num, cim->ci_type, bptr);
+	}
+	bptr->b_intrmask = intrmask;
+}
+
+/* put the chips on the boards */
+
+static void SetupAllChips(SAB_BOARD *bptr)
+{				/* note that port ordering */
+				/* is important in chip setup */
+				/* the open routine walks the */
+				/* port list for sync and async */
+				/* ttys */
+	SAB_CHIP *chip;
+	AURA_CIM *cim;
+	unsigned int chipno;
+	
+	switch(bptr->b_type)
+	{
+	case BD_1020P:
+	case BD_1020CP:
+		/* setup 1 ESCC2 */
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NA);
+			CreateESCC2Port(chip, 0, FUNCTION_AO);
+		}
+		
+		break;
+	case BD_1520P:
+	case BD_1520CP:
+		/* setup 1 ESCC2 */
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NA);
+			CreateESCC2Port(chip, 0, FUNCTION_NR);
+		}      
+		break;
+	case BD_2020P:
+	case BD_2020CP:
+		/* setup 1 ESCC2 */
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_AO);
+			CreateESCC2Port(chip, 0, FUNCTION_AO);
+		}      
+		break;
+	case BD_2520P:
+	case BD_2520CP:
+		/* setup 1 ESCC2 */
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NR);
+			CreateESCC2Port(chip, 0, FUNCTION_NR);
+		}      
+		break;
+	case BD_4020P:		
+	case BD_4020CP:		/* do chips in reverCse
+				   order so that they
+				   are on lists in forward
+				   order
+				*/
+				/* setup 2 ESCC2 */
+		chip = CreateESCC2(bptr, AURORA_4X20_CHIP_OFFSET);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_AO);
+			CreateESCC2Port(chip, 0, FUNCTION_AO);
+		}
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_AO);
+			CreateESCC2Port(chip, 0, FUNCTION_AO);
+		}
+		break;
+	case BD_4520P:
+	case BD_4520CP:
+		/* setup 2 ESCC2 */
+		chip = CreateESCC2(bptr, AURORA_4X20_CHIP_OFFSET);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NR);
+			CreateESCC2Port(chip, 0, FUNCTION_NR);
+		}
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NR);
+			CreateESCC2Port(chip, 0, FUNCTION_NR);
+		}
+		break;
+	case BD_8020P:
+	case BD_8020CP:
+		/* setup 1 ESCC8 */
+		chip = CreateESCC8(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC8Port(chip, 7, FUNCTION_AO);
+			CreateESCC8Port(chip, 6, FUNCTION_AO);
+			CreateESCC8Port(chip, 5, FUNCTION_AO);
+			CreateESCC8Port(chip, 4, FUNCTION_AO);
+			CreateESCC8Port(chip, 3, FUNCTION_AO);
+			CreateESCC8Port(chip, 2, FUNCTION_AO);
+			CreateESCC8Port(chip, 1, FUNCTION_AO);
+			CreateESCC8Port(chip, 0, FUNCTION_AO);
+		}
+		break;
+	case BD_8520P:
+	case BD_8520CP:
+		/* setup 1 ESCC8 */
+		chip = CreateESCC8(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC8Port(chip, 7, FUNCTION_NR);
+			CreateESCC8Port(chip, 6, FUNCTION_NR);
+			CreateESCC8Port(chip, 5, FUNCTION_NR);
+			CreateESCC8Port(chip, 4, FUNCTION_NR);
+			CreateESCC8Port(chip, 3, FUNCTION_NR);
+			CreateESCC8Port(chip, 2, FUNCTION_NR);
+			CreateESCC8Port(chip, 1, FUNCTION_NR);
+			CreateESCC8Port(chip, 0, FUNCTION_NR);
+		}
+		break;
+		
+	case BD_WANMCS:
+		CreateCIMs(bptr);
+		for(chipno = 7, cim = bptr->b_cimbase; 
+		    cim != NULL; cim = cim->next_by_mcs)
+		{
+			chip = CreateESCC8fromCIM(bptr, cim, chipno--);
+			if(chip != NULL)
+			{
+				CreateESCC8PortWithCIM(chip, 7, cim, 0);
+				CreateESCC8PortWithCIM(chip, 6, cim, 0);
+				CreateESCC8PortWithCIM(chip, 5, cim, 0);
+				CreateESCC8PortWithCIM(chip, 4, cim, 0);
+				CreateESCC8PortWithCIM(chip, 3, cim, 0);
+				CreateESCC8PortWithCIM(chip, 2, cim, 0);
+				CreateESCC8PortWithCIM(chip, 1, cim, 0);
+				CreateESCC8PortWithCIM(chip, 0, cim, 0);
+			}
+			chip = CreateESCC8fromCIM(bptr, cim, chipno--);
+			if(chip != NULL)
+			{
+				CreateESCC8PortWithCIM(chip, 7, cim, 0);
+				CreateESCC8PortWithCIM(chip, 6, cim, 0);
+				CreateESCC8PortWithCIM(chip, 5, cim, 0);
+				CreateESCC8PortWithCIM(chip, 4, cim, 0);
+				CreateESCC8PortWithCIM(chip, 3, cim, 0);
+				CreateESCC8PortWithCIM(chip, 2, cim, 0);
+				CreateESCC8PortWithCIM(chip, 1, cim, 0);
+				CreateESCC8PortWithCIM(chip, 0, cim, 1);
+			}
+		}
+		break;
+		
+	default:
+		printk(KERN_ALERT "auraXX20n: unable to set up chip for board %p.\n", bptr);
+		break;
+	}
+}
+
+/* finding the cards by PCI device type */
+
+static SAB_BOARD* find_ati_cpci_card(void)
+{
+	struct pci_dev *pdev;
+	unsigned char bus;
+	unsigned char devfn;
+	unsigned char pci_latency;
+	unsigned short pci_command;
+	SAB_BOARD *bptr;
+	unsigned control;
+	unsigned does_sync;
+	unsigned use_1port;
+	
+	printk(KERN_ALERT "auraXX20n: finding ati cpci cards.\n");
+	
+	bptr = (SAB_BOARD*)kmalloc(sizeof(SAB_BOARD), GFP_KERNEL);
+	if(bptr == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not allocate board memory!\n");
+		return 0;
+	}
+	memset(bptr, 0, sizeof(SAB_BOARD));
+	
+	if(!pcibios_present())
+	{
+		printk(KERN_ALERT "auraXX20n: system does not support PCI bus.\n");
+		kfree(bptr);
+		return 0;
+	}
+	DEBUGPRINT((KERN_ALERT "auraXX20n: System supports PCI bus.\n"));
+	
+ CPCIRESTART:
+	if(pdev = pci_find_device(sab8253x_vendor_id, sab8253x_cpci_device_id, XX20lastpdev),
+	   pdev == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not find cpci card.\n");
+		kfree(bptr);
+		return 0;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found multiport CPCI serial card.\n"));
+	
+	XX20lastpdev = pdev;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found ATI PLX 9050, %p.\n", pdev));
+	bptr->b_dev = *pdev;
+	
+	/* the Solaris and model linux drivers
+	 * comment that there are problems with
+	 * getting the length via PCI operations
+	 * seems to work for 2.4
+	 */
+	bptr->length0 = (unsigned int) pci_resource_len(pdev, 0);
+	bptr->length1 = (unsigned int) pci_resource_len(pdev, 1);
+	bptr->length2 = (unsigned int) pci_resource_len(pdev, 2);
+	bptr->b_irq = pdev->irq;
+	
+	
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 0 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 0), bptr->length0));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 1 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 1), bptr->length1));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 2 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 2),
+		    bptr->length2));
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: interrupt is %i.\n", pdev->irq));
+	bus = pdev->bus->number;
+	devfn = pdev->devfn;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: bus is %x, slot is %x.\n", bus, PCI_SLOT(devfn)));
+	pcibios_read_config_word(bus, devfn, PCI_COMMAND, &pci_command);
+#if 0
+	/* The Aurora card does not act as a PCI master
+	 * ugh!!
+	 */
+	new_command = pci_command | PCI_COMMAND_MASTER;
+	if(pci_command != new_command)
+	{
+		DEBUGPRINT((KERN_ALERT 
+			    "auraXX20n: the PCI BIOS has not enabled this device!"
+			    " Updating PCI command %4.4x->%4.4x.\n", 
+			    pci_command,
+			    new_command));
+		pcibios_write_config_word(bus, devfn, PCI_COMMAND, 
+					  new_command);
+	}
+	else
+	{
+		DEBUGPRINT
+			((KERN_ALERT 
+			  "auraXX20n: the PCI BIOS has enabled this device as master!\n"));
+	}
+#endif
+	if((pci_command & PCI_COMMAND_MASTER) != PCI_COMMAND_MASTER)
+	{
+		DEBUGPRINT((KERN_ALERT "auraXX20n: Aurora card is not a bus master.\n"));
+	}
+	
+	pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
+				 &pci_latency);
+	if (pci_latency < 32) 
+	{
+		DEBUGPRINT
+			((KERN_ALERT
+			  "auraXX20n: PCI latency timer (CFLT) is low at %i.\n", pci_latency));
+		/* may need to change the latency */
+#if 0
+		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 32);
+#endif
+	} 
+	else 
+	{
+		DEBUGPRINT((KERN_ALERT
+			    "auraXX20n: PCI latency timer (CFLT) is %#x.\n", 
+			    pci_latency));
+	}
+	bptr->virtbaseaddress0 = ioremap_nocache(pci_base_address(pdev, 0), 
+						 bptr->length0);
+	if(bptr->virtbaseaddress0 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 0));
+		
+		goto CPCIRESTART;
+	}
+	
+	bptr->b_bridge = (PLX9050*) bptr->virtbaseaddress0; /* MAKE SURE INTS ARE OFF */
+	writel(PLX_INT_OFF, &(bptr->b_bridge->intr));
+	
+	printk
+		(KERN_ALERT
+		 "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		 (void*) pci_base_address(pdev, 0), (void*) bptr->virtbaseaddress0);
+	
+	dump_ati_adapter_registers((unsigned int*) bptr->virtbaseaddress0, bptr->length0);
+	
+	if(*(unsigned int*)bptr->virtbaseaddress0 == -1) /* XP7 problem? */
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to access PLX 9050 registers at %p.\n", 
+		       (void*)bptr->virtbaseaddress0);
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	bptr->virtbaseaddress2 = ioremap_nocache(pci_base_address(pdev, 2),
+						 bptr->length2);
+	if(bptr->virtbaseaddress2 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 2));
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	DEBUGPRINT
+		((KERN_ALERT
+		  "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		  (void*) pci_base_address(pdev, 2), (void*) bptr->virtbaseaddress2));
+	
+	/* we get clockrate from serial eeprom */
+	if (!plx9050_eprom_read(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				(unsigned short*) bptr->b_eprom,
+				(unsigned char) 0, EPROM9050_SIZE))
+	{
+		printk(KERN_ALERT "auraXX20n: Could not read serial eprom.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	printk(KERN_ALERT "auraXX20n: dumping serial eprom.\n");
+	dump_ati_adapter_registers((unsigned int*) bptr->b_eprom, 2 * EPROM9050_SIZE);  
+	
+	if(*(unsigned int*)bptr->b_eprom != PCIMEMVALIDCPCI) /* bridge problem? */
+	{
+		printk(KERN_ALERT "auraXX20n: unable to access valid serial eprom data.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	if(((unsigned short*) bptr->b_eprom)[EPROMPREFETCHOFFSET] & PREFETCHBIT)
+	{
+		++sab8253x_rebootflag;
+		printk(KERN_ALERT "8253x: eeprom programmed for prefetchable memory resources; must reprogram!!\n");
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  9,
+				  (((unsigned short*) bptr->b_eprom)[EPROMPREFETCHOFFSET] & (~PREFETCHBIT)));
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+	}
+	/* get SYNC and ONEPORT values */
+	
+	control = readl(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl);	
+	/* note we use the actual address
+	 * of the control register in
+	 * memory
+	 */
+	
+	if(control & AURORA_MULTI_SYNCBIT)
+	{
+		does_sync = 0;
+	}
+	else
+	{
+		does_sync = 1;
+	}
+	
+	if(control & AURORA_MULTI_1PORTBIT)
+	{
+		use_1port = 1;
+	}
+	else
+	{
+		use_1port = 0;
+	}
+	
+	
+	/* Figure out the board */
+	switch(bptr->length2) 
+	{
+	case AURORA_4X20_SIZE:
+		if(does_sync) 
+		{
+			bptr->b_type = BD_4520CP;
+			bptr->b_nchips = 2;
+			bptr->b_nports = 4;
+			bptr->b_flags = BD_SYNC;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD4520CPcounter; /* keep track of boardnumber for naming devices */
+			++BD4520CPcounter;
+			printk(KERN_ALERT "auraXX20n: Found Saturn 4520CP.\n");
+		} 
+		else 
+		{
+			bptr->b_type = BD_4020CP;
+			bptr->b_nchips = 2;
+			bptr->b_nports = 4;
+			bptr->b_flags = 0x0;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD4020CPcounter;
+			++BD4020CPcounter;
+			printk(KERN_ALERT "auraXX20n: Found Apollo 4020CP.\n");
+		}
+		break;
+	case AURORA_8X20_SIZE:
+		if(does_sync) 
+		{ 
+			bptr->b_type = BD_8520CP;
+			bptr->b_nchips = 1;
+			bptr->b_nports = 8;
+			bptr->b_flags = BD_SYNC;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD8520CPcounter;
+			++BD8520CPcounter;
+			printk(KERN_ALERT "auraXX20n: Found Saturn 8520CP.\n");
+		} 
+		else 
+		{
+			bptr->b_type = BD_8020CP;
+			bptr->b_nchips = 1;
+			bptr->b_nports = 8;
+			bptr->b_flags = 0x0;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD8020CPcounter;
+			++BD8020CPcounter;
+			printk(KERN_ALERT "auraXX20n: Found Apollo 8020CP.\n");
+		}
+		break;
+	case AURORA_2X20_SIZE:
+		if(does_sync) 
+		{
+			if(use_1port) 
+			{
+				bptr->b_type = BD_1520CP;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 1520CP.\n");
+				bptr->b_nchips = 1;
+				bptr->b_nports = 1;
+				bptr->b_flags = BD_SYNC;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD1520CPcounter;
+				++BD1520CPcounter;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 1520CP.\n");
+			} 
+			else 
+			{
+				bptr->b_type = BD_2520CP;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 2;
+				bptr->b_flags = BD_SYNC;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD2520CPcounter;
+				++BD2520CPcounter;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 2520CP.\n");
+			}
+		}
+		else
+		{
+			if(use_1port) 
+			{
+				bptr->b_type = BD_1020CP;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 1;
+				bptr->b_flags = 0x0;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD1020CPcounter;
+				++BD1020CPcounter;
+				printk(KERN_ALERT "auraXX20n: Found Apollo 1020CP.\n");
+			} 
+			else 
+			{
+				bptr->b_type = BD_2020CP;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 2;
+				bptr->b_flags = 0x0;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD2020CPcounter;
+				++BD2020CPcounter;
+				printk(KERN_ALERT "auraXX20n: Found Apollo 2020CP.\n");
+			}
+		}
+		break;
+	default:
+		printk(KERN_ALERT "Error: Board could not be identified\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	/* Let's get the clockrate right -- ugh!*/
+	
+	bptr->b_clkspeed = bptr->b_eprom[AURORA_MULTI_EPROM_CLKLSW/2];
+	
+	if(bptr->b_clkspeed == -1)	/* misprogrammed -- ugh. */
+	{
+		switch(bptr->b_type)
+		{
+		case BD_8520CP:
+		case BD_8020CP:
+			bptr->b_clkspeed = AURORA_MULTI_CLKSPEED/4;
+			break;
+		default:
+			bptr->b_clkspeed = AURORA_MULTI_CLKSPEED;
+			break;
+			
+		}
+		printk(KERN_ALERT "auraXX20n:  UNKNOWN CLOCKSPEED -- ASSUMING %ld.\n", bptr->b_clkspeed);
+		
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  54, (unsigned short) bptr->b_clkspeed);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  55, (unsigned short) (bptr->b_clkspeed >> 16));
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+	}
+	
+	return bptr;
+}
+
+static SAB_BOARD* find_ati_wanms_card(void)   /* wan multichanner server == mcs [ multichannel server] */
+{
+	struct pci_dev *pdev;
+	unsigned char bus;
+	unsigned char devfn;
+	unsigned char pci_latency;
+	unsigned short pci_command;
+	SAB_BOARD *bptr;
+	int resetresult;
+	
+	printk(KERN_ALERT "auraXX20n: finding ati mcs cards.\n");
+	
+	bptr = (SAB_BOARD*)kmalloc(sizeof(SAB_BOARD), GFP_KERNEL);
+	if(bptr == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not allocate board memory!\n");
+		return 0;
+	}
+	memset(bptr, 0, sizeof(SAB_BOARD));
+	
+	if(!pcibios_present())
+	{
+		printk(KERN_ALERT "auraXX20n: system does not support PCI bus.\n");
+		kfree(bptr);
+		return 0;
+	}
+	DEBUGPRINT((KERN_ALERT "auraXX20n: System supports PCI bus.\n"));
+	
+ MCSRESTART:
+	if(pdev = pci_find_device(sab8253x_vendor_id, sab8253x_wmcs_device_id, XX20lastpdev),
+	   pdev == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not find mcs card.\n");
+		kfree(bptr);
+		return 0;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found mcs card.\n"));
+	
+	XX20lastpdev = pdev;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found ATI S5920, %p.\n", pdev));
+	bptr->b_dev = *pdev;
+	
+	/* the Solaris and model linux drivers
+	 * comment that there are problems with
+	 * getting the length via PCI operations
+	 * seems to work for 2.4
+	 */
+	bptr->length0 = (unsigned int) pci_resource_len(pdev, 0); /* AMCC 5920 operation registers
+								     includes access to serial eprom */
+	bptr->length1 = (unsigned int) pci_resource_len(pdev, 1); /* commands to remote cards */
+	bptr->length2 = (unsigned int) pci_resource_len(pdev, 2); /* command to host card */
+	bptr->length3 = (unsigned int) pci_resource_len(pdev, 3); /* RFIFO cache */
+	bptr->b_irq = pdev->irq;
+	
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 0 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 0), bptr->length0));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 1 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 1), bptr->length1));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 2 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 2),
+		    bptr->length2));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 3 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 3),
+		    bptr->length3));
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: interrupt is %i.\n", pdev->irq));
+	bus = pdev->bus->number;
+	devfn = pdev->devfn;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: bus is %x, slot is %x.\n", bus, PCI_SLOT(devfn)));
+	pcibios_read_config_word(bus, devfn, PCI_COMMAND, &pci_command);
+	
+#if 0
+	/* The Aurora card does not act as a PCI master
+	 * ugh!!
+	 */
+	new_command = pci_command | PCI_COMMAND_MASTER;
+	if(pci_command != new_command)
+	{
+		DEBUGPRINT((KERN_ALERT 
+			    "auraXX20n: the PCI BIOS has not enabled this device!"
+			    " Updating PCI command %4.4x->%4.4x.\n", 
+			    pci_command,
+			    new_command));
+		pcibios_write_config_word(bus, devfn, PCI_COMMAND, 
+					  new_command);
+	}
+	else
+	{
+		DEBUGPRINT
+			((KERN_ALERT 
+			  "auraXX20n: the PCI BIOS has enabled this device as master!\n"));
+	}
+#endif
+	
+	if((pci_command & PCI_COMMAND_MASTER) != PCI_COMMAND_MASTER)
+	{
+		DEBUGPRINT((KERN_ALERT "auraXX20n: Aurora card is not a bus master.\n"));
+	}
+	
+	pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
+				 &pci_latency);
+	if (pci_latency < 32) 
+	{
+		DEBUGPRINT
+			((KERN_ALERT
+			  "auraXX20n: PCI latency timer (CFLT) is low at %i.\n", pci_latency));
+		/* may need to change the latency */
+#if 0
+		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 32);
+#endif
+	} 
+	else 
+	{
+		DEBUGPRINT((KERN_ALERT
+			    "auraXX20n: PCI latency timer (CFLT) is %#x.\n", 
+			    pci_latency));
+	}
+	
+	bptr->virtbaseaddress0 = ioremap_nocache(pci_base_address(pdev, 0), 
+						 bptr->length0);
+	if(bptr->virtbaseaddress0 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 0));
+		goto MCSRESTART;
+	}
+	
+	bptr->b_bridge = (void*) bptr->virtbaseaddress0; /* b_bridge is not supposed
+							    to be used by the AMCC based
+							    products -- it is set just
+							    in case */
+	
+	printk(KERN_ALERT
+	       "auraXX20n: remapped physical address %p to virtual address %p.\n",
+	       (void*) pci_base_address(pdev, 0), (void*) bptr->virtbaseaddress0);
+	
+	/* unfortunate name -- works for any bridge */
+	dump_ati_adapter_registers((unsigned int*) bptr->virtbaseaddress0, bptr->length0);
+	
+	if(*(unsigned int*)bptr->virtbaseaddress0 == -1) /* XP7 problem? */
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to access AMCC registers at %p.\n", 
+		       (void*)bptr->virtbaseaddress0);
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		goto MCSRESTART;		       /* try the next one if any */
+	}
+	
+	writel(AMCC_INT_OFF, (unsigned int*)(bptr->AMCC_REG + AMCC_INTCSR));
+	
+	bptr->virtbaseaddress1 = ioremap_nocache(pci_base_address(pdev, 1),
+						 bptr->length1);
+	if(bptr->virtbaseaddress1 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 1));
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		goto MCSRESTART;
+	}
+	
+	DEBUGPRINT
+		((KERN_ALERT
+		  "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		  (void*) pci_base_address(pdev, 1), (void*) bptr->virtbaseaddress1));
+	
+	/* next address space */
+	bptr->virtbaseaddress2 = ioremap_nocache(pci_base_address(pdev, 2),
+						 bptr->length2);
+	if(bptr->virtbaseaddress2 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 2));
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress1);
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		goto MCSRESTART;
+	}
+	
+	DEBUGPRINT
+		((KERN_ALERT
+		  "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		  (void*) pci_base_address(pdev, 2), (void*) bptr->virtbaseaddress2));
+	
+	bptr->virtbaseaddress3 = ioremap_nocache(pci_base_address(pdev, 3),
+						 bptr->length3);
+	if(bptr->virtbaseaddress3 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 3));
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress1);
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress2);
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto MCSRESTART;
+	}
+	
+	DEBUGPRINT
+		((KERN_ALERT
+		  "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		  (void*) pci_base_address(pdev, 3), (void*) bptr->virtbaseaddress3));
+	
+	bptr->b_type = BD_WANMCS;
+	
+	resetresult = wanmcs_reset(bptr);
+	writel(AMCC_INT_OFF, (unsigned int*)(bptr->AMCC_REG + AMCC_INTCSR));
+	
+	if(resetresult == FALSE)
+	{
+		printk(KERN_ALERT "auraXX20n: unable to reset wan mcs %p.\n", bptr);
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress1);
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress2);
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress3);
+		iounmap((void*)bptr->virtbaseaddress3);
+		bptr->virtbaseaddress3 = 0;
+		
+		goto MCSRESTART;
+	}
+	
+	/* we get clockrate from serial eeprom */
+	if (amcc_read_nvram((unsigned char*) bptr->b_eprom,
+			    AMCC_NVRAM_SIZE, bptr->AMCC_REG) == FALSE)
+	{
+		printk(KERN_ALERT "auraXX20n: Could not read serial eprom.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		iounmap((void*)bptr->virtbaseaddress3);
+		bptr->virtbaseaddress3 = 0;
+		goto MCSRESTART;
+	}
+	printk(KERN_ALERT "auraXX20n: dumping serial eprom.\n");
+	dump_ati_adapter_registers((unsigned int*) bptr->b_eprom, 2 * AMCC_NVRAM_SIZE);  
+	if(bptr->b_eprom[AMCC_NVR_VENDEVID] != PCIMEMVALIDWMCS)
+	{
+		printk(KERN_ALERT "auraXX20: bad serial eprom, board %p.\n", bptr);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		iounmap((void*)bptr->virtbaseaddress3);
+		bptr->virtbaseaddress3 = 0;
+		goto MCSRESTART;
+	}
+	return bptr;
+}
+
+/* initialize the auraXX20 */
+static SAB_BOARD* find_ati_multiport_card(void)
+{
+	struct pci_dev *pdev;
+	unsigned char bus;
+	unsigned char devfn;
+	unsigned char pci_latency;
+	unsigned short pci_command;
+	SAB_BOARD *bptr;
+	unsigned control;
+	unsigned does_sync;
+	unsigned use_1port;
+	
+	printk(KERN_ALERT "auraXX20n: finding ati cards.\n");
+	
+	bptr = (SAB_BOARD*)kmalloc(sizeof(SAB_BOARD), GFP_KERNEL);
+	if(bptr == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not allocate board memory!\n");
+		return 0;
+	}
+	memset(bptr, 0, sizeof(SAB_BOARD));
+	
+	if(!pcibios_present())
+	{
+		printk(KERN_ALERT "auraXX20n: system does not support PCI bus.\n");
+		kfree(bptr);
+		return 0;
+	}
+	DEBUGPRINT((KERN_ALERT "auraXX20n: System supports PCI bus.\n"));
+	
+ MULTIPORTRESTART:
+	if(pdev = pci_find_device(sab8253x_vendor_id, sab8253x_mpac_device_id, XX20lastpdev),
+	   pdev == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not find multiport card.\n");
+		kfree(bptr);
+		return 0;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found multiport PCI serial card.\n"));
+	
+	XX20lastpdev = pdev;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found ATI PLX 9050, %p.\n", pdev));
+	bptr->b_dev = *pdev;
+	
+	/* the Solaris and model linux drivers
+	 * comment that there are problems with
+	 * getting the length via PCI operations
+	 * seems to work for 2.4
+	 */
+	bptr->length0 = (unsigned int) pci_resource_len(pdev, 0);
+	bptr->length1 = (unsigned int) pci_resource_len(pdev, 1);
+	bptr->length2 = (unsigned int) pci_resource_len(pdev, 2);
+	bptr->b_irq = pdev->irq;
+	
+	
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 0 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 0), bptr->length0));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 1 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 1), bptr->length1));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 2 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 2),
+		    bptr->length2));
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: interrupt is %i.\n", pdev->irq));
+	bus = pdev->bus->number;
+	devfn = pdev->devfn;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: bus is %x, slot is %x.\n", bus, PCI_SLOT(devfn)));
+	pcibios_read_config_word(bus, devfn, PCI_COMMAND, &pci_command);
+#if 0
+	/* The Aurora card does not act as a PCI master
+	 * ugh!!
+	 */
+	new_command = pci_command | PCI_COMMAND_MASTER;
+	if(pci_command != new_command)
+	{
+		DEBUGPRINT((KERN_ALERT 
+			    "auraXX20n: the PCI BIOS has not enabled this device!"
+			    " Updating PCI command %4.4x->%4.4x.\n", 
+			    pci_command,
+			    new_command));
+		pcibios_write_config_word(bus, devfn, PCI_COMMAND, 
+					  new_command);
+	}
+	else
+	{
+		DEBUGPRINT
+			((KERN_ALERT 
+			  "auraXX20n: the PCI BIOS has enabled this device as master!\n"));
+	}
+#endif
+	if((pci_command & PCI_COMMAND_MASTER) != PCI_COMMAND_MASTER)
+	{
+		DEBUGPRINT((KERN_ALERT "auraXX20n: Aurora card is not a bus master.\n"));
+	}
+	
+	pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
+				 &pci_latency);
+	if (pci_latency < 32) 
+	{
+		DEBUGPRINT
+			((KERN_ALERT
+			  "auraXX20n: PCI latency timer (CFLT) is low at %i.\n", pci_latency));
+		/* may need to change the latency */
+#if 0
+		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 32);
+#endif
+	} 
+	else 
+	{
+		DEBUGPRINT((KERN_ALERT
+			    "auraXX20n: PCI latency timer (CFLT) is %#x.\n", 
+			    pci_latency));
+	}
+	bptr->virtbaseaddress0 = ioremap_nocache(pci_base_address(pdev, 0), 
+						 bptr->length0);
+	if(bptr->virtbaseaddress0 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 0));
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	bptr->b_bridge = (PLX9050*) bptr->virtbaseaddress0; /* MAKE SURE INTS ARE OFF */
+	writel(PLX_INT_OFF, &(bptr->b_bridge->intr));
+	
+	printk(KERN_ALERT
+	       "auraXX20n: remapped physical address %p to virtual address %p.\n",
+	       (void*) pci_base_address(pdev, 0), (void*) bptr->virtbaseaddress0);
+	
+	dump_ati_adapter_registers((unsigned int*) bptr->virtbaseaddress0, bptr->length0);
+	
+	if(*(unsigned int*)bptr->virtbaseaddress0 == -1) /* XP7 problem? */
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to access PLX 9050 registers at %p.\n", 
+		       (void*)bptr->virtbaseaddress0);
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	bptr->virtbaseaddress2 = ioremap_nocache(pci_base_address(pdev, 2),
+						 bptr->length2);
+	if(bptr->virtbaseaddress2 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 2));
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	DEBUGPRINT((KERN_ALERT
+		    "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		    (void*) pci_base_address(pdev, 2), (void*) bptr->virtbaseaddress2));
+	
+	if (!plx9050_eprom_read(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				(unsigned short*) bptr->b_eprom,
+				(unsigned char) 0, EPROM9050_SIZE))
+	{
+		printk(KERN_ALERT "auraXX20n: Could not read serial eprom.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	printk(KERN_ALERT "auraXX20n: dumping serial eprom.\n");
+	dump_ati_adapter_registers((unsigned int*) bptr->b_eprom, 2 * EPROM9050_SIZE);  
+	
+	if(*(unsigned int*)bptr->b_eprom != PCIMEMVALIDMULTI) /* bridge problem? */
+	{
+		printk(KERN_ALERT "auraXX20n: unable to access valid serial eprom data.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	if(((unsigned short*) bptr->b_eprom)[EPROMPREFETCHOFFSET] & PREFETCHBIT)
+	{
+		++sab8253x_rebootflag;
+		printk(KERN_ALERT "8253x: eeprom programmed for prefetchable memory resources; must reprogram!!\n");
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  9,
+				  (((unsigned short*) bptr->b_eprom)[EPROMPREFETCHOFFSET] & (~PREFETCHBIT)));
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+	}
+	
+	/* get SYNC and ONEPORT values */
+	
+	control = readl(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl);	
+	/* note we use the actual address
+	 * of the control register in
+	 * memory
+	 */
+	
+	if(control & AURORA_MULTI_SYNCBIT)
+	{
+		does_sync = 0;
+	}
+	else
+	{
+		does_sync = 1;
+	}
+	
+	if(control & AURORA_MULTI_1PORTBIT)
+	{
+		use_1port = 1;
+	}
+	else
+	{
+		use_1port = 0;
+	}
+	
+	
+	/* Figure out the board */
+	switch(bptr->length2) 
+	{
+	case AURORA_4X20_SIZE:
+		if(does_sync) 
+		{
+			bptr->b_type = BD_4520P;
+			bptr->b_nchips = 2;
+			bptr->b_nports = 4;
+			bptr->b_flags = BD_SYNC;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD4520Pcounter; /* keep track of boardnumber for naming devices */
+			++BD4520Pcounter;
+			printk(KERN_ALERT "auraXX20n: Found Saturn 4520P.\n");
+		} 
+		else 
+		{
+			bptr->b_type = BD_4020P;
+			bptr->b_nchips = 2;
+			bptr->b_nports = 4;
+			bptr->b_flags = 0x0;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD4020Pcounter;
+			++BD4020Pcounter;
+			printk(KERN_ALERT "auraXX20n: Found Apollo 4020P.\n");
+		}
+		break;
+	case AURORA_8X20_SIZE:
+		if(does_sync) 
+		{ 
+			bptr->b_type = BD_8520P;
+			bptr->b_nchips = 1;
+			bptr->b_nports = 8;
+			bptr->b_flags = BD_SYNC;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD8520Pcounter;
+			++BD8520Pcounter;
+			printk(KERN_ALERT "auraXX20n: Found Saturn 8520P.\n");
+		} 
+		else 
+		{
+			bptr->b_type = BD_8020P;
+			bptr->b_nchips = 1;
+			bptr->b_nports = 8;
+			bptr->b_flags = 0x0;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD8020Pcounter;
+			++BD8020Pcounter;
+			printk(KERN_ALERT "auraXX20n: Found Apollo 8020P.\n");
+		}
+		break;
+	case AURORA_2X20_SIZE:
+		if(does_sync) 
+		{
+			if(use_1port) 
+			{
+				bptr->b_type = BD_1520P;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 1520P.\n");
+				bptr->b_nchips = 1;
+				bptr->b_nports = 1;
+				bptr->b_flags = BD_SYNC;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD1520Pcounter;
+				++BD1520Pcounter;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 1520P.\n");
+			} 
+			else 
+			{
+				bptr->b_type = BD_2520P;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 2;
+				bptr->b_flags = BD_SYNC;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD2520Pcounter;
+				++BD2520Pcounter;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 2520P.\n");
+			}
+		}
+		else
+		{
+			if(use_1port) 
+			{
+				bptr->b_type = BD_1020P;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 1;
+				bptr->b_flags = 0x0;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD1020Pcounter;
+				++BD1020Pcounter;
+				printk(KERN_ALERT "auraXX20n: Found Apollo 1020P.\n");
+			} 
+			else 
+			{
+				bptr->b_type = BD_2020P;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 2;
+				bptr->b_flags = 0x0;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD2020Pcounter;
+				++BD2020Pcounter;
+				printk(KERN_ALERT "auraXX20n: Found Apollo 2020P.\n");
+			}
+		}
+		break;
+	default:
+		printk(KERN_ALERT "Error: Board could not be identified\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	/* Let's get the clockrate right -- ugh!*/
+	
+	bptr->b_clkspeed = bptr->b_eprom[AURORA_MULTI_EPROM_CLKLSW/2];
+	
+	if(bptr->b_clkspeed == -1)	/* misprogrammed -- ugh. */
+	{
+		switch(bptr->b_type)
+		{
+		case BD_8520P:
+		case BD_8020P:
+			bptr->b_clkspeed = AURORA_MULTI_CLKSPEED/4;
+			break;
+		default:
+			bptr->b_clkspeed = AURORA_MULTI_CLKSPEED;
+			break;
+			
+		}
+		printk(KERN_ALERT "auraXX20n:  UNKNOWN CLOCKSPEED -- ASSUMING %ld.\n", bptr->b_clkspeed);
+		
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  54, (unsigned short) bptr->b_clkspeed);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  55, (bptr->b_clkspeed >> 16));
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+	}
+	
+	return bptr;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+#ifdef MODULE
+int init_module(void)		/* all OS */
+#else
+int auraXX20_probe(struct net_device *devp) /* passed default device structure */
+#endif
+#else
+static int __init auraXX20_probe(void)	/* legacy device initialization 2.4.* */
+#endif
+{
+	SAB_BOARD *boardptr;
+	SAB_PORT *portptr;
+	struct net_device *dev;
+	unsigned int result;
+	unsigned int namelength;
+	unsigned int portno;
+	int intr_val;
+	
+	int mp_probe_count = 0;	/* multiport count */
+	int cp_probe_count = 0;	/* compact pci count */
+	int wm_probe_count = 0;	/* wan multiserver count */
+	
+	printk(KERN_ALERT "aurora interea miseris mortalibus almam extulerat lucem\n");
+	printk(KERN_ALERT "        referens opera atque labores\n"); 
+	
+	memset(AuraBoardESCC8IrqRoot, 0, sizeof(AuraBoardESCC8IrqRoot));
+	memset(AuraBoardESCC2IrqRoot, 0, sizeof(AuraBoardESCC2IrqRoot));
+	memset(AuraBoardMCSIrqRoot, 0, sizeof(AuraBoardMCSIrqRoot));
+	
+#if !defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+	if(do_probe == 0)
+		return -1;			/* only allow to be called one 2.2.* */
+	do_probe = 0;
+#endif
+	
+	fn_init_crc_table();		/* used in faking ethernet packets for */
+	/* the network driver -- crcs are currently */
+	/* not being checked by this software */
+	/* but is good to have them in case a frame */
+	/* passes through a WAN LAN bridge */
+	
+	sab8253x_setup_ttydriver();	/* add synchronous tty and synchronous network
+					   driver initialization */
+	
+	AuraBoardRoot = NULL;		/* basic lists */
+	AuraChipRoot = NULL;
+	AuraPortRoot = NULL;
+	NumSab8253xPorts = 0;
+	
+	AuraXX20DriverParams.debug = auraXX20n_debug;
+	AuraXX20DriverParams.listsize = sab8253xn_listsize;
+	
+	if(auraXX20n_name != 0)
+	{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+		auraXX20n_prototype.name = auraXX20n_name;
+#else
+		strcpy(auraXX20n_prototype.name, auraXX20n_name);
+#endif
+	}
+	
+	/* find all multiport cards */
+	XX20lastpdev = NULL;
+	while(1)
+	{
+		boardptr = find_ati_multiport_card();
+		if(boardptr == NULL)
+		{
+			printk(KERN_ALERT 
+			       "auraXX20n: found %d AURAXX20 multiport device%s.\n", 
+			       mp_probe_count, ((mp_probe_count == 1) ? "" : "s"));
+			break;
+		}
+		boardptr->nextboard = AuraBoardRoot;
+		AuraBoardRoot = boardptr;
+		printk(KERN_ALERT "auraXX20n: found AURAXX20 multiport device #%d.\n",
+		       mp_probe_count);
+		++mp_probe_count;
+	}
+	
+	/* find all cpci cards */
+	XX20lastpdev = NULL;
+	while(1)
+	{
+		boardptr = find_ati_cpci_card();
+		if(boardptr == NULL)
+		{
+			printk(KERN_ALERT 
+			       "auraXX20n: found %d AURAXX20 CPCI device%s.\n", 
+			       cp_probe_count, ((cp_probe_count == 1) ? "" : "s"));
+			break;
+		}
+		boardptr->nextboard = AuraBoardRoot;
+		AuraBoardRoot = boardptr;
+		printk(KERN_ALERT "auraXX20n: found AURAXX20 CPCI device #%d.\n",
+		       cp_probe_count);
+		++cp_probe_count;
+	}
+	/* find all WAN MS cards */
+	XX20lastpdev = NULL;
+	while(1)
+	{
+		boardptr = find_ati_wanms_card();
+		if(boardptr == NULL)
+		{
+			printk(KERN_ALERT 
+			       "auraXX20n: found %d AURAXX20 WANMS device%s.\n", 
+			       wm_probe_count, ((wm_probe_count == 1) ? "" : "s"));
+			break;
+		}
+		boardptr->nextboard = AuraBoardRoot;
+		AuraBoardRoot = boardptr;
+		printk(KERN_ALERT "auraXX20n: found AURAXX20 WANMS device #%d.\n",
+		       wm_probe_count);
+		++wm_probe_count;
+	}
+	
+	/* Now do the chips! */
+	
+	for(boardptr = AuraBoardRoot; boardptr != NULL; boardptr = boardptr->nextboard)
+	{
+		SetupAllChips(boardptr);	/* sets up the ports on the chips */
+	}
+	
+				/* set up global driver structures
+				 * for async tty, call out device
+				 * for sync tty and for network device
+				 */
+
+				/* NOW TURN ON THE PLX INTS */
+				/* note all port ints (only receive right now)
+				 * are off */
+
+				/* interrupts cannot be turned on by port
+				   this seems to be the only sensible place
+				   to do it*/
+
+				/* only at this point is the number of
+				 * ttys to be created known. */
+
+	if(finish_sab8253x_setup_ttydriver() ==  -1) /* only as many termios are allocated */
+		/* as needed */
+	{
+		return 0;
+	}
+	for(portno = 0, portptr = AuraPortRoot; portptr != NULL; ++portno, portptr = portptr->next)
+	{
+		portptr->line = portno;	/* set up the line number == minor dev associated with port */
+		portptr->sigmode = sab8253x_default_sp502_mode; 
+				/* if we have SP502s let getty work with RS232 by default */
+				/* unless overridden in module setup. */
+	}
+	/* Now lets set up the network devices */
+	for(portno = 0, portptr = AuraPortRoot; portptr != NULL; ++portno, portptr = portptr->next)
+	{
+		
+		dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+		if(!dev)
+		{
+			break;
+		}
+		memset(dev, 0, sizeof(struct net_device));
+		*dev = auraXX20n_prototype;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+		dev->name = kmalloc(IFNAMSIZ+1, GFP_KERNEL);
+		if(!dev->name)
+		{
+			kfree(dev);
+			break;
+		}
+#endif
+		namelength = MIN(strlen(auraXX20n_prototype.name), IFNAMSIZ);
+		strcpy(dev->name, auraXX20n_prototype.name);
+		sprintf(&dev->name[namelength-1], "%3.3d", portno);
+		
+#if 1
+		current_sab_port = portptr;
+#else
+		dev->priv = portptr;
+#endif
+		result = register_netdev(dev);
+		if(result)
+		{			/* if we run into some internal kernel limit */
+			break;
+		}
+		printk(KERN_ALERT "sab8253xn: found sab8253x network device #%d.\n",
+		       portno);
+	}
+	printk(KERN_ALERT 
+	       "sab8253xn: found %d sab8253x network device%s.\n", 
+	       portno, ((portno == 1) ? "" : "s"));
+	
+	/* Now lets set up the character device */
+	
+	if(sab8253xc_name)
+	{
+		result = register_chrdev(sab8253xc_major, sab8253xc_name, &sab8253xc_fops);
+		if(result < 0)
+		{
+			sab8253xc_major = result;
+			printk(KERN_ALERT "Could not install sab8253xc device.\n");
+		}
+		else if(result > 0)
+		{
+			sab8253xc_major = result;
+		}
+	}
+	
+	for(boardptr = AuraBoardRoot; boardptr != NULL; boardptr = boardptr->nextboard)
+	{				/* let's set up port interrupt lists */
+		intr_val = boardptr->b_irq;
+		if((intr_val < 0) || (intr_val >= NUMINTS))
+		{
+			printk(KERN_ALERT "sab8253xn:  bad interrupt %i board %p.\n", intr_val, boardptr);
+			continue;
+		}
+		switch(boardptr->b_type)
+		{
+		case BD_WANMCS:
+			boardptr->next_on_interrupt = AuraBoardMCSIrqRoot[intr_val];
+			AuraBoardMCSIrqRoot[intr_val] = boardptr;
+			break;
+		case BD_8520P:
+		case BD_8520CP:
+			boardptr->next_on_interrupt = AuraBoardESCC8IrqRoot[intr_val];
+			AuraBoardESCC8IrqRoot[intr_val] = boardptr;
+			break;
+		default:
+			boardptr->next_on_interrupt = AuraBoardESCC2IrqRoot[intr_val];
+			AuraBoardESCC2IrqRoot[intr_val] = boardptr;
+			break;
+		}
+	}
+	
+	for(intr_val = 0; intr_val < NUMINTS; ++intr_val) /* trying to install as few int handlers as possible */
+	{				/* one for each group of boards on a given irq */
+		if((AuraBoardESCC2IrqRoot[intr_val] != NULL) || (AuraBoardESCC8IrqRoot[intr_val] != NULL) ||
+		   (AuraBoardMCSIrqRoot[intr_val] != NULL))
+		{
+			if (request_irq(intr_val, sab8253x_interrupt, SA_SHIRQ,
+					"sab8253x", &AuraBoardESCC2IrqRoot[intr_val]) == 0) 
+				/* interrupts on perboard basis
+				 * cycle through chips and then
+				 * ports */
+				/* NOTE PLX INTS ARE OFF -- so turn them on */
+			{
+				for(boardptr = AuraBoardESCC2IrqRoot[intr_val]; boardptr != NULL; 
+				    boardptr = boardptr->next_on_interrupt)
+				{
+					writel(PLX_INT_ON, &(boardptr->b_bridge->intr));
+				}
+				for(boardptr = AuraBoardESCC8IrqRoot[intr_val]; boardptr != NULL; 
+				    boardptr = boardptr->next_on_interrupt)
+				{
+					writel(PLX_INT_ON, &(boardptr->b_bridge->intr));
+				}
+				for(boardptr = AuraBoardMCSIrqRoot[intr_val]; boardptr != NULL; 
+				    boardptr = boardptr->next_on_interrupt)
+				{
+					/* write to the MIC csr to reset the PCI interrupt */
+					writeb(0, (unsigned char*)(boardptr->MICCMD_REG +  MICCMD_MICCSR));
+					
+					/* now, write to the CIM interrupt ena to re-enable interrupt generation */
+					writeb(0, (unsigned char*)(boardptr->CIMCMD_REG + CIMCMD_WRINTENA));
+					
+					/* now, activate PCI interrupts */
+					writel(AMCC_AOINTPINENA, (unsigned int*)(boardptr->AMCC_REG + AMCC_INTCSR));
+				}
+			}
+			else
+			{
+				printk(KERN_ALERT "Unable to get interrupt, board set up not complete %i.\n", intr_val);
+			}
+		}
+	}
+	
+	/* all done!  a lot of work */
+	
+#if !defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+	return -1;			/* otherwise 2.2 probe uses up
+					 * a default device structure*/
+#else
+	return 0;
+#endif
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+#ifdef MODULE
+/* cleanup module/free up virtual memory */
+/* space*/
+void cleanup_module(void)
+#endif
+#else
+void auraXX20_cleanup(void)
+#endif
+{
+	SAB_BOARD *boardptr;
+	SAB_CHIP *chipptr;
+	SAB_PORT *portptr;
+	AURA_CIM *cimptr;
+	int intr_val;
+	extern void sab8253x_cleanup_ttydriver(void);
+	
+	printk(KERN_ALERT "auraXX20n: unloading AURAXX20 driver.\n");
+	
+	sab8253x_cleanup_ttydriver();	/* clean up tty */
+	
+	/* unallocate and turn off ints */
+	for(intr_val = 0; intr_val < NUMINTS; ++intr_val)
+	{
+		if((AuraBoardESCC2IrqRoot[intr_val] != NULL) || (AuraBoardESCC8IrqRoot[intr_val] != NULL) ||
+		   (AuraBoardMCSIrqRoot[intr_val] != NULL))
+		{
+			for(boardptr = AuraBoardESCC2IrqRoot[intr_val]; boardptr != NULL; 
+			    boardptr = boardptr->next_on_interrupt)
+			{
+				writel(PLX_INT_OFF, &(boardptr->b_bridge->intr));
+			}
+			for(boardptr = AuraBoardESCC8IrqRoot[intr_val]; boardptr != NULL; 
+			    boardptr = boardptr->next_on_interrupt)
+			{
+				writel(PLX_INT_OFF, &(boardptr->b_bridge->intr));
+			}
+			for(boardptr = AuraBoardMCSIrqRoot[intr_val]; boardptr != NULL; 
+			    boardptr = boardptr->next_on_interrupt)
+			{
+				writel(AMCC_INT_OFF, (unsigned int*)(boardptr->AMCC_REG + AMCC_INTCSR));
+				(void) wanmcs_reset(boardptr);
+				writel(AMCC_INT_OFF, (unsigned int*)(boardptr->AMCC_REG + AMCC_INTCSR));
+			}
+			
+			free_irq(intr_val, &AuraBoardESCC2IrqRoot[intr_val]); /* free up board int
+									       * note that if two boards
+									       * share an int, two int
+									       * handlers were registered
+									       * 
+									       */
+		}
+	}
+	
+	/* disable chips and free board memory*/
+	while(AuraBoardRoot)
+	{
+		boardptr = AuraBoardRoot;
+		for(chipptr = boardptr->board_chipbase; chipptr != NULL; chipptr = chipptr->next_by_board)
+		{
+			(*chipptr->int_disable)(chipptr); /* make sure no ints can come int */
+		}
+		AuraBoardRoot = boardptr->nextboard;
+		if(boardptr->b_type == BD_WANMCS)
+		{
+			if(boardptr->virtbaseaddress0 != 0)
+			{
+				DEBUGPRINT((KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+					    (void*)boardptr->virtbaseaddress0));
+				iounmap((void*)boardptr->virtbaseaddress0);
+				boardptr->virtbaseaddress0 = 0;
+			}
+			
+			if(boardptr->virtbaseaddress1 != 0)
+			{
+				DEBUGPRINT((KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+					    (void*)boardptr->virtbaseaddress1));
+				iounmap((void*)boardptr->virtbaseaddress1);
+				boardptr->virtbaseaddress1 = 0;
+			}
+			
+			if(boardptr->virtbaseaddress2 != 0)
+			{
+				DEBUGPRINT((KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+					    (void*)boardptr->virtbaseaddress2));
+				iounmap((void*)boardptr->virtbaseaddress2);
+				boardptr->virtbaseaddress2 = 0;
+			}
+			
+			if(boardptr->virtbaseaddress3 != 0)
+			{
+				DEBUGPRINT((KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+					    (void*)boardptr->virtbaseaddress3));
+				iounmap((void*)boardptr->virtbaseaddress3);
+				boardptr->virtbaseaddress3 = 0;
+			}
+			
+		}
+		else			/* everything but wan multichannel servers */
+		{
+			if(boardptr->virtbaseaddress0)
+			{
+				DEBUGPRINT((KERN_ALERT
+					    "auraXX20n: unmapping virtual address %p.\n", 
+					    (void*)boardptr->virtbaseaddress0));
+				iounmap((void*)boardptr->virtbaseaddress0);
+				boardptr->virtbaseaddress0 = 0;
+			}
+			if(boardptr->virtbaseaddress2)
+			{
+				DEBUGPRINT((KERN_ALERT
+					    "auraXX20n: unmapping virtual address %p.\n", 
+					    (void*)boardptr->virtbaseaddress2));
+				iounmap((void*)boardptr->virtbaseaddress2);
+				boardptr->virtbaseaddress2 = 0;
+			}
+		}
+		kfree(boardptr);
+	}
+	
+	while(AuraCimRoot)
+	{
+		cimptr = AuraCimRoot;
+		AuraCimRoot = cimptr->next;
+		kfree(cimptr);
+	}
+	
+	
+	while(AuraChipRoot)		/* free chip memory */
+	{
+		chipptr = AuraChipRoot;
+		AuraChipRoot = chipptr->next;
+		kfree(chipptr);
+	}
+	
+	if(sab8253xc_name && (sab8253xc_major > 0)) /* unregister the chr device */
+	{
+		unregister_chrdev(sab8253xc_major, sab8253xc_name);
+	}
+	
+	while(Sab8253xRoot)		/* free up network stuff */
+	{
+		SAB_PORT *priv;
+		priv = (SAB_PORT *)Sab8253xRoot->priv;
+		unregister_netdev(Sab8253xRoot);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+		kfree(Sab8253xRoot.name);
+#endif
+		kfree(Sab8253xRoot);
+		Sab8253xRoot = priv->next_dev;
+	}
+	
+	while(AuraPortRoot)		/* free up port memory */
+	{
+		portptr = AuraPortRoot;
+		AuraPortRoot = portptr->next;
+		if(portptr->dcontrol2.receive)
+		{
+			kfree(portptr->dcontrol2.receive);
+		}
+		if(portptr->dcontrol2.transmit)
+		{
+			kfree(portptr->dcontrol2.transmit);
+		}
+		kfree(portptr);
+	}
+}
+
+/*
+ * Hardware dependent read and write functions.
+ * We have functions to write/read a byte, write/read
+ * a word and read and write the FIFO
+ */
+
+
+/***************************************************************************
+ * aura_readb:    Function to read a byte on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg: The address of the register
+ *
+ *     Return value : The value of the register. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static unsigned char aura_readb(struct sab_port *port, unsigned char *reg) 
+{
+	return readb(reg);
+}
+
+/***************************************************************************
+ * aura_writeb:    Function to write a byte on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg:  The address of the register
+ *                   val:  The value to put into the register
+ *
+ *     Return value : None
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static void aura_writeb(struct sab_port *port, unsigned char *reg,unsigned char val) 
+{
+	writeb(val,reg);
+}
+
+/***************************************************************************
+ * aura_readw:    Function to read a word on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg: The address of the hw memory to access
+ *
+ *     Return value : The value of the memory area. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+static unsigned short aura_readw(struct sab_port *port, unsigned short *reg) 
+{
+	return readw(reg);
+}
+
+/***************************************************************************
+ * aura_writew:    Function to write a word on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg:  The address of the hw memory to access
+ *                   val:  The value to put into the register
+ *
+ *     Return value : The value of the memory area. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static void aura_writew(struct sab_port *port, unsigned short *reg,unsigned short val) 
+{
+	writew(val,reg);
+}
+
+/***************************************************************************
+ * aura_readfifo:    Function to read the FIFO on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port:  The port being accessed
+ *                   buf:   The address of a buffer where we should put
+ *                          what we read
+ *                  nbytes: How many chars to read.
+ *
+ *     Return value : none
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 13 2000, creation
+ ***************************************************************************/
+static void aura_readfifo(struct sab_port *port, unsigned char *buf, unsigned int nbytes) 
+{
+	int i;
+	unsigned short *wptr = (unsigned short*) buf;
+	int nwords = ((nbytes+1)/2);
+	for(i = 0; i < nwords; i ++) 
+	{
+		wptr[i] = readw(((unsigned short *)port->regs));
+	}
+}
+
+/***************************************************************************
+ * aura_writefifo:    Function to write the FIFO on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port:  The port being accessed
+ *
+ *     Return value : none
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 13 2000, creation
+ ***************************************************************************/
+static void aura_writefifo(struct sab_port *port) 
+{
+	int i,max,maxw;
+	unsigned short *wptr;
+	unsigned char buffer[32];
+	
+	if(port->xmit_cnt <= 0)
+	{
+		return; 
+	}
+	max= (port->xmit_fifo_size < port->xmit_cnt) ? port->xmit_fifo_size : port->xmit_cnt;
+	
+	for (i = 0; i < max; i++) 
+	{
+		buffer[i] = port->xmit_buf[port->xmit_tail++];
+		port->xmit_tail &= (SAB8253X_XMIT_SIZE - 1);
+		port->icount.tx++;
+		port->xmit_cnt--;
+	}
+	
+	maxw = max/2;
+	wptr = (unsigned short*) buffer;
+	
+	for(i = 0; i < maxw; ++i)
+	{
+		writew(wptr[i], (unsigned short *)port->regs);
+	}
+	
+	if(max & 1)
+	{
+		writeb(buffer[max-1], (unsigned char*)port->regs);
+	}
+}
+
+/***************************************************************************
+ * wmsaura_readb:    Function to read a byte on a LMS, WMS
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg: The address of the register
+ *
+ *     Return value : The value of the register. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : TO BE IMPLEMENTED 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static unsigned char wmsaura_readb(struct sab_port *port, unsigned char *reg) 
+{
+	return readb((unsigned char*) (((unsigned int) reg) + CIMCMD_RDREGB));
+}
+
+/***************************************************************************
+ * wmsaura_writeb:    Function to write a byte on a LMS, WMS
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg:  The address of the register
+ *                   val:  The value to put into the register
+ *
+ *     Return value : None
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : TO BE IMPLEMENTED
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static void wmsaura_writeb(struct sab_port *port, unsigned char *reg,unsigned char val) 
+{
+	writeb(val, (unsigned char*) (((unsigned int) reg) + CIMCMD_WRREGB));
+}
+
+/***************************************************************************
+ * wmsaura_readw:    Function to read a word on a LMS, WMS
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg: The address of the hw memory to access
+ *
+ *     Return value : The value of the memory area. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : TO BE IMPLEMENTED
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+static unsigned short wmsaura_readw(struct sab_port *port, unsigned short *reg) 
+{
+	unsigned short readval;
+	unsigned int address;
+	address = (unsigned int) reg;
+	
+	readval =  readb((unsigned char*) (address + CIMCMD_RDREGB));
+	++address;
+	return (readval | (readb((unsigned char*) (address + CIMCMD_RDREGB)) << 8));
+}
+
+/***************************************************************************
+ * wmsaura_writew:    Function to write a word on a LMS, WMS
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg:  The address of the hw memory to access
+ *                   val:  The value to put into the register
+ *
+ *     Return value : The value of the memory area. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : TO BE IMPLEMENTED
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static void wmsaura_writew(struct sab_port *port, unsigned short *reg, unsigned short val) 
+{
+	unsigned char vallow;
+	unsigned char valhigh;
+	unsigned int address;
+	
+	address = (unsigned int) reg;
+	
+	vallow = (unsigned char) val;
+	valhigh = (unsigned char) (val >> 8);
+	
+	writeb(vallow, (unsigned char*) (address + CIMCMD_WRREGB));
+	++address;
+	writeb(valhigh, (unsigned char*) (address + CIMCMD_WRREGB));
+}
+
+static void wmsaura_readfifo(struct sab_port *port, unsigned char *buf, unsigned int nbytes) 
+{
+#ifdef FIFO_DIRECT
+	unsigned short fifo[32/2];	/* this array is word aligned
+					 * buf may not be word aligned*/
+	unsigned int nwords;
+	int i;
+	int wcount;
+	unsigned int address;
+	
+	if (nbytes == 0) 
+	{
+		return;
+	}
+	
+	wcount = ((nbytes + 1) >> 1);
+	/* Read the thing into the local FIFO and copy it out. */
+	address = (unsigned int) port->regs;
+	
+	for(i = 0; i < wcount; ++i)
+	{
+		fifo[i] = readw((unsigned short*)(address + CIMCMD_RDFIFOW));
+	}
+	
+	memcpy((unsigned char*) buf, (unsigned char*) &(fifo[0]), (unsigned int) nbytes);
+	
+#else		/* FIFO_DIRECT */
+	unsigned short fifo[32/2];
+	int i;
+	int wcount;
+	SAB_BOARD *bptr;
+	unsigned int channel;
+	
+	if (nbytes == 0) 
+	{
+		return;
+	}
+	
+	bptr = port->board;
+	wcount = ((nbytes + 1) >> 1);
+	channel = (((unsigned char*) port->regs) - bptr->CIMCMD_REG); /* should be properly shifted */
+	
+	/*
+	 * Trigger a cache read by writing the nwords - 1 to the
+	 *  magic place.
+	 */
+	
+	writeb((unsigned char) wcount, bptr->MICCMD_REG + (MICCMD_CACHETRIG + channel));
+	
+	/*
+	 * Now, read out the contents.
+	 */
+	
+	channel >>= 1;
+	
+	for(i = 0; i < wcount; ++i)
+	{
+		fifo[i] = readw((unsigned short*)(bptr->FIFOCACHE_REG + (channel + (i << 1))));
+	}
+	
+	memcpy((unsigned char*) buf, (unsigned char*) &(fifo[0]), (unsigned int) nbytes);
+#endif		/* !FIFO_DIRECT */
+}
+
+static void wmsaura_writefifo(struct sab_port *port)
+{
+	unsigned short fifo[32/2];
+	unsigned char* fifob = (unsigned char*) fifo;
+	int i,max;
+	int wcount;
+	unsigned int address;
+	
+	if(port->xmit_cnt <= 0) 
+	{
+		return; 
+	}
+	max = (port->xmit_fifo_size < port->xmit_cnt) ? port->xmit_fifo_size:port->xmit_cnt;
+	for (i = 0; i < max; i++) 
+	{
+		fifob[i] = port->xmit_buf[port->xmit_tail++];
+		port->xmit_tail &= (SAB8253X_XMIT_SIZE - 1);
+		port->icount.tx++;
+		port->xmit_cnt--;
+	}
+	
+	wcount = (max >> 1);
+	/* Copy from the linear local FIFO into the hardware fifo. */
+	address = (unsigned int) port->regs;
+	
+	for(i = 0; i < wcount; ++i)
+	{
+		writew(fifo[i], (unsigned short*)(address + CIMCMD_WRFIFOW));
+	}
+	if(max & 1)			/* odd byte */
+	{
+		--max;
+		writeb(fifob[max], (unsigned short*)(address + CIMCMD_WRFIFOB));
+	}
+}
+
+module_init(auraXX20_probe);
+module_exit(auraXX20_cleanup);
+MODULE_DESCRIPTION("Aurora Multiport Multiprotocol Serial Driver");
+MODULE_AUTHOR("Joachim Martillo <martillo@telfordtools.com>");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xint.c linux/drivers/net/wan/8253x/8253xint.c
--- linux.orig/drivers/net/wan/8253x/8253xint.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xint.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,458 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+/* Standard in kernel modules */
+#include <linux/module.h>   /* Specifically, a module */
+
+#include <asm/io.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include <linux/pci.h>
+#include "8253xctl.h"
+#include "8253xmcs.h"
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * sab8253x_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: sab8253x_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * sab8253x_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/* Note:  the inline interrupt routines constitute the smallest hardware
+   unit that must be examined when an interrupt comes up.  On the 4520
+   type cards, two ESCC2s must be examined.  Because the ESCC2s are in
+   a null terminated list the sab82532_interrupt also works for 2 port/1 port
+   single ESCC2 cards.
+   
+   On an 8520 type card there is but one ESCC8 thus the sab82538_interrupt
+   routine does not walk through a list.  But this requires some contortion
+   in dealing with the multichannel server.  The multichannel server has
+   at most 4 channel interface modules (CIM) 1/EB.  Each CIM has at most
+   two ESCC8s, thus the host card can have a list of 8 ESCC8s.  But by
+   walking the CIMs the exact ESCC8 that is interrupting can be identified.
+   Thus despite the complexity, really the MCS is a collection of 8520 type
+   cards multiplexed on one interrupt.  Thus after making some temporary
+   modifications of the board structure, the generic interrupt handler invokes
+   sab82538_interrupt handler just as for an 8520 type card.
+*/
+
+/* static forces inline compilation */
+static void inline sab82532_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct sab_port *port;
+	struct sab_chip *chip=NULL;
+	struct sab_board *bptr = (struct sab_board*) dev_id;
+	union sab8253x_irq_status status;
+	unsigned char gis;
+	
+	for(chip = bptr->board_chipbase; chip != NULL; chip = chip->next_by_board) 
+	{
+		port= chip->c_portbase;
+		gis = READB(port, gis); /* Global! */
+		status.stat=0;
+		
+		/* Since the PORT interrupt are global, 
+		 * we do check all the ports for this chip
+		 */
+		
+		/* A 2 ports chip */
+		
+		if(!(gis & SAB82532_GIS_MASK)) 
+		{
+			continue; /* no interrupt on this chip */
+		}
+		
+		if (gis & SAB82532_GIS_ISA0)
+		{
+			status.sreg.isr0 = READB(port, isr0);
+		}
+		else 
+		{
+			status.sreg.isr0 = 0;
+		}
+		if (gis & SAB82532_GIS_ISA1)
+		{
+			status.sreg.isr1 = READB(port, isr1);
+		}
+		else
+		{
+			status.sreg.isr1 = 0;
+		}
+		
+		if (gis & SAB82532_GIS_PI)
+		{
+			status.sreg.pis = READB(port, pis);
+		}
+		else
+		{
+			status.sreg.pis = 0;
+		}
+		
+		if (status.stat) 
+		{
+			if (status.images[ISR0_IDX] & port->receive_test)
+			{
+				(*port->receive_chars)(port, &status);	/* when the fifo is full */
+				/* no time to schedule thread*/
+			}
+			
+			if ((status.images[port->dcd.irq] & port->dcd.irqmask) || 
+			    (status.images[port->cts.irq] & port->cts.irqmask) ||
+			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+			    (status.images[ISR1_IDX] & port->check_status_test))
+			{
+				(*port->check_status)(port, &status); /* this stuff should be */
+				/* be moveable to scheduler */
+				/* thread*/
+			}
+			
+			if (status.images[ISR1_IDX] & port->transmit_test)
+			{
+				(*port->transmit_chars)(port, &status); /* needs to be moved to task */
+			}
+		}
+		
+		/* Get to next port on chip */
+		port = port->next_by_chip;
+		/* Port B */
+		if (gis & SAB82532_GIS_ISB0)
+		{
+			status.images[ISR0_IDX] = READB(port, isr0);
+		}
+		else 
+		{
+			status.images[ISR0_IDX] = 0;
+		}
+		if (gis & SAB82532_GIS_ISB1)
+		{
+			status.images[ISR1_IDX] = READB(port,isr1);
+		}
+		else
+		{
+			status.images[ISR1_IDX] = 0;
+		}
+		/* DO NOT SET PIS. IT was reset! */
+		
+		
+		if (status.stat) 
+		{
+			if (status.images[ISR0_IDX] & port->receive_test)
+			{
+				(*port->receive_chars)(port, &status);
+			}
+			if ((status.images[port->dcd.irq] & port->dcd.irqmask) || 
+			    (status.images[port->cts.irq] & port->cts.irqmask) ||
+			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+			    (status.images[ISR1_IDX] & port->check_status_test))
+			{
+				(*port->check_status)(port, &status);
+			}
+			if (status.images[ISR1_IDX] & port->transmit_test)
+			{
+				(*port->transmit_chars)(port, &status);
+			}
+		}
+	}
+}
+
+static void inline sab82538_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct sab_port *port;
+	struct sab_chip *chip=NULL;
+	struct sab_board *bptr = (struct sab_board*) dev_id;
+	union sab8253x_irq_status status;
+	unsigned char gis,i;
+	
+	chip = bptr->board_chipbase;
+	port = chip->c_portbase;
+	
+	gis = READB(port, gis); /* Global! */
+	status.stat=0;
+	
+	/* Since the PORT interrupt are global, 
+	 * we do check all the ports for this chip
+	 */
+	
+	/* 8 ports chip */
+	if(!(gis & SAB82538_GIS_MASK)) 
+	{
+		return;
+	}
+	
+	if(gis & SAB82538_GIS_CII) 
+	{ /* A port interrupt! */
+		/* Get the port */
+		int portindex;
+		
+		portindex = (gis & SAB82538_GIS_CHNL_MASK);
+		
+		port = chip->c_portbase;
+		
+		while(portindex)
+		{
+			port = port->next_by_chip;
+			--portindex;
+		}
+		
+		status.images[ISR0_IDX] = READB(port,isr0);
+		status.images[ISR1_IDX] = READB(port,isr1);
+		if (gis & SAB82538_GIS_PIC)
+		{
+			status.images[PIS_IDX] = 
+				(*port->readbyte)(port,
+						  ((unsigned char *)(port->regs)) +
+						  SAB82538_REG_PIS_C);
+		}
+		else
+		{
+			status.images[PIS_IDX] = 0;
+		}
+		
+		if (status.stat) 
+		{
+			if (status.images[ISR0_IDX] & port->receive_test)
+			{
+				(*port->receive_chars)(port, &status);
+			}
+			if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
+			    (status.images[port->cts.irq] & port->cts.irqmask) ||
+			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+			    (status.images[ISR1_IDX] & port->check_status_test))
+			{
+				(*port->check_status)(port, &status);
+			}
+			/*
+			 * We know that with 8 ports chip, the bit corresponding to channel 
+			 * number is used in the parallel port... So we clear it
+			 * Not too elegant!
+			 */
+			status.images[PIS_IDX] &= ~(1 << (gis&SAB82538_GIS_CHNL_MASK));
+			if (status.images[ISR1_IDX] & port->transmit_test)
+			{
+				(*port->transmit_chars)(port, &status);
+			}
+		}
+	}
+	
+	/* 
+	 * Now we handle the "channel interrupt" case. The chip manual for the
+	 * 8 ports chip states that "channel" and "port" interrupt are set
+	 * independently so we still must check the parrallel port
+	 *
+	 * We should probably redesign the whole thing to be less AD HOC that we 
+	 * are now... We know that port C is used for DSR so we only check that one.
+	 * PIS for port C was already recorded in  status.images[PIS_IDX], so we
+	 * check the ports that are set
+	 */
+	
+	if (status.images[PIS_IDX]) 
+	{
+		for(i=0, port = chip->c_portbase;
+		    i < chip->c_nports;
+		    i++, port=port->next_by_chip) 
+		{
+			if(status.images[PIS_IDX] & (0x1 << i)) 
+			{ /* Match */
+				/* Checking DSR */
+				if(port->dsr.inverted)
+				{
+					port->dsr.val = (((*port->readbyte)
+							  (port, port->dsr.reg) & 
+							  port->dsr.mask) ? 0 : 1);
+				}
+				else
+				{
+					port->dsr.val = ((*port->readbyte)(port, port->dsr.reg) & 
+							 port->dsr.mask);
+				}
+				
+				port->icount.dsr++;
+				wake_up_interruptible(&port->delta_msr_wait); /* in case waiting on modem change */
+			}
+		}
+	}
+}
+
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+
+void sab8253x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	extern SAB_BOARD *AuraBoardESCC2IrqRoot[];
+	extern SAB_BOARD *AuraBoardESCC8IrqRoot[];
+	extern SAB_BOARD *AuraBoardMCSIrqRoot[];
+	AURA_CIM *cim;
+	SAB_CHIP *chip;
+	SAB_PORT *port;
+	register SAB_BOARD *boardptr;
+	register unsigned char intrmask;
+	unsigned char stat;
+	SAB_CHIP *save_chiplist;
+	SAB_PORT *save_portlist;
+	
+	if((irq < 0) || (irq >= NUMINTS))
+	{
+		printk(KERN_ALERT "sab8253x: bad interrupt value %i.\n", irq);
+		return;
+	}
+	/* walk through all the cards on the interrupt that occurred. */
+	for(boardptr = AuraBoardESCC2IrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
+	{
+		sab82532_interrupt(irq, boardptr, regs);
+	}
+	
+	for(boardptr = AuraBoardESCC8IrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
+	{
+		sab82538_interrupt(irq, boardptr, regs);
+	}  
+	
+	for(boardptr = AuraBoardMCSIrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
+	{
+		
+		while(1)
+		{
+			writeb(0, (unsigned char*)(boardptr->CIMCMD_REG + CIMCMD_WRINTDIS)); /* prevent EBs from raising
+											      * any more ints through the
+											      * host card */
+			stat = ~(unsigned char) /* active low !!!!! */
+				readw((unsigned short*) 
+				      (((unsigned char*)boardptr->CIMCMD_REG) + CIMCMD_RDINT)); /* read out the ints */
+				/* write to the MIC csr to reset the PCI interrupt */
+			writeb(0, (unsigned char*)(boardptr->MICCMD_REG + MICCMD_MICCSR)); 
+				/* reset the interrupt generation
+				 * hardware on the host card*/
+			/* now, write to the CIM interrupt ena to re-enable interrupt generation */
+			writeb(0, (unsigned char*)(boardptr->CIMCMD_REG + CIMCMD_WRINTENA)); /* allow EBs to request ints
+											      * through the host card */
+			if(!stat)
+			{
+				break;
+			}
+			cim = boardptr->b_cimbase; /* cims in reverse order */
+			for(intrmask = boardptr->b_intrmask;
+			    intrmask != 0; 
+			    intrmask <<= 2, stat <<=2)
+			{
+				if(cim == NULL)
+				{
+					break;	/* no cim no ports */
+				}
+				if((intrmask & 0xc0) == 0) /* means no cim for these ints */
+				{		/* cim not on list do not go to next */
+					continue;
+				}
+				save_portlist = boardptr->board_portbase;
+				save_chiplist = boardptr->board_chipbase;
+				/* the goal is temporarily to make the structures
+				 * look like 8x20 structures -- thus if I find
+				 * a bug related to escc8s I need fix it in
+				 * only one place. */
+				switch(stat & 0xc0) /* possible ints */
+				{
+				default:
+					break;
+					
+				case 0x80:	/* esccB */
+					chip = cim->ci_chipbase;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing cim.\n");
+						break;
+					}
+					chip = chip->next_by_cim;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
+						break;
+					}
+					port = chip->c_portbase;
+					boardptr->board_portbase = port;
+					boardptr->board_chipbase = chip;
+					sab82538_interrupt(irq, boardptr, regs);		  
+					break;
+					
+				case 0x40:	/* esccA */
+					chip = cim->ci_chipbase;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing cim.\n");
+						break;
+					}
+					port = chip->c_portbase;
+					boardptr->board_portbase = port;
+					boardptr->board_chipbase = chip;
+					sab82538_interrupt(irq, boardptr, regs);		  
+					break;
+					
+				case 0xc0:	/* esccB and esccA */
+					chip = cim->ci_chipbase;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing cim.\n");
+						break;
+					}
+					port = chip->c_portbase;
+					boardptr->board_portbase = port;
+					boardptr->board_chipbase = chip;
+					sab82538_interrupt(irq, boardptr, regs);		  
+					
+					chip = cim->ci_chipbase;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing cim.\n");
+						break;
+					}
+					chip = chip->next_by_cim;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
+						break;
+					}
+					port = chip->c_portbase;
+					boardptr->board_portbase = port;
+					boardptr->board_chipbase = chip;
+					sab82538_interrupt(irq, boardptr, regs);		  
+					break;
+				}
+				boardptr->board_portbase = save_portlist;
+				boardptr->board_chipbase = save_chiplist;
+				cim = cim->next_by_mcs;
+			}
+		}
+	}
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xioc.h linux/drivers/net/wan/8253x/8253xioc.h
--- linux.orig/drivers/net/wan/8253x/8253xioc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xioc.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,143 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+#ifndef _SABIOCTL_H_
+#define _SABIOCTL_H_
+
+#include <linux/tty.h>
+#include <asm/ioctl.h>
+#include <linux/sockios.h>
+#include "ring.h"
+#include "Reg9050.h"
+
+/* Channel Configuration Register 0 (CCR0) */
+#define SAB82532_CCR0_PU		0x80
+#define SAB82532_CCR0_MCE		0x40
+#define SAB82532_CCR0_SC_NRZ		0x00
+#define SAB82532_CCR0_SC_NRZI		0x08
+#define SAB82532_CCR0_SC_FM0		0x10
+#define SAB82532_CCR0_SC_FM1		0x14
+#define SAB82532_CCR0_SC_MANCH		0x18
+#define SAB82532_CCR0_SM_HDLC		0x00
+#define SAB82532_CCR0_SM_SDLC_LOOP	0x01
+#define SAB82532_CCR0_SM_BISYNC		0x02
+#define SAB82532_CCR0_SM_ASYNC		0x03
+
+/* Channel Configuration Register 1 (CCR1) */
+#define SAB82532_CCR1_SFLG		0x80
+#define SAB82532_CCR1_ODS		0x10
+#define SAB82532_CCR1_BCR		0x08
+#define SAB82532_CCR1_IFF		0x08
+#define SAB82532_CCR1_ITF		0x00
+#define SAB82532_CCR1_CM_MASK		0x07
+
+/* Channel Configuration Register 2 (CCR2) */
+#define SAB82532_CCR2_SOC1		0x80
+#define SAB82532_CCR2_SOC0		0x40
+#define SAB82532_CCR2_BR9		0x80
+#define SAB82532_CCR2_BR8		0x40
+#define SAB82532_CCR2_BDF		0x20
+#define SAB82532_CCR2_SSEL		0x10
+#define SAB82532_CCR2_XCS0		0x20
+#define SAB82532_CCR2_RCS0		0x10
+#define SAB82532_CCR2_TOE		0x08
+#define SAB82532_CCR2_RWX		0x04
+#define SAB82532_CCR2_C32		0x02
+#define SAB82532_CCR2_DIV		0x01
+
+/* Channel Configuration Register 3 (CCR3) */
+#define SAB82532_CCR3_PSD		0x01
+#define SAB82532_CCR3_RCRC		0x04
+
+/* Channel Configuration Register 4 (CCR4) */
+#define SAB82532_CCR4_MCK4		0x80
+#define SAB82532_CCR4_EBRG		0x40
+#define SAB82532_CCR4_TST1		0x20
+#define SAB82532_CCR4_ICD		0x10
+#define SAB82532_CCR4_RF32		0x00
+#define SAB82532_CCR4_RF16		0x01
+#define SAB82532_CCR4_RF04		0x02
+#define SAB82532_CCR4_RF02		0x03
+
+/* Mode Register (MODE) */
+#define SAB82532_MODE_TM0		0x80
+#define SAB82532_MODE_FRTS		0x40
+#define SAB82532_MODE_FCTS		0x20
+#define SAB82532_MODE_FLON		0x10
+#define SAB82532_MODE_TCPU		0x10
+#define SAB82532_MODE_RAC		0x08
+#define SAB82532_MODE_RTS		0x04
+#define SAB82532_MODE_TRS		0x02
+#define SAB82532_MODE_TLP		0x01
+
+struct channelcontrol
+{
+	unsigned char ccr0;
+	unsigned char ccr1;
+	unsigned char ccr2;
+	unsigned char ccr3;
+	unsigned char ccr4;
+	unsigned char mode;
+	unsigned char rlcr;
+};
+
+struct sep9050
+{
+	unsigned short values[EPROM9050_SIZE];
+};
+
+				/* EXTERNAL-CLOCKING */
+#define DEFAULT_CCR0 (SAB82532_CCR0_MCE | SAB82532_CCR0_SC_NRZ | SAB82532_CCR0_SM_HDLC)
+#define DEFAULT_CCR1 (SAB82532_CCR1_SFLG | SAB82532_CCR1_ODS | SAB82532_CCR1_IFF) /* clock mode 0 */
+#define DEFAULT_CCR2 0 /*SAB82532_CCR2_SOC1*/		/* 0a -- RTS high*/
+#define DEFAULT_CCR3 SAB82532_CCR3_RCRC
+#define DEFAULT_CCR4 0
+#define DEFAULT_MODE (SAB82532_MODE_TM0 | SAB82532_MODE_RTS | SAB82532_MODE_RAC)
+#define DEFAULT_RLCR ((RXSIZE/32) - 1)
+
+#define DEFAULT_RLCR_NET ((RXSIZE/32) - 1)
+
+				/* Internal-Clocking */
+
+#define DCE_CCR0 (SAB82532_CCR0_MCE | SAB82532_CCR0_SC_NRZ | SAB82532_CCR0_SM_HDLC)
+#define DCE_CCR1 (SAB82532_CCR1_SFLG | SAB82532_CCR1_ODS | SAB82532_CCR1_IFF | 6) /* clock mode 6 */
+#define DCE_CCR2 (SAB82532_CCR2_BDF | SAB82532_CCR2_SSEL | SAB82532_CCR2_TOE) /* 6b */
+#define DCE_CCR3 (SAB82532_CCR3_RCRC)
+#define DCE_CCR4 (SAB82532_CCR4_MCK4|SAB82532_CCR4_EBRG)
+#define DCE_MODE SAB82532_MODE_TM0 | SAB82532_MODE_RTS | SAB82532_MODE_RAC
+#define DCE_RLCR ((RXSIZE/32) - 1)
+
+#define ATIS_MAGIC_IOC	'A'
+#define ATIS_IOCSPARAMS		_IOW(ATIS_MAGIC_IOC,0,struct channelcontrol)
+#define ATIS_IOCGPARAMS		_IOR(ATIS_MAGIC_IOC,1,struct channelcontrol)
+#define ATIS_IOCSSPEED		_IOW(ATIS_MAGIC_IOC,2,unsigned long)
+#define ATIS_IOCGSPEED		_IOR(ATIS_MAGIC_IOC,3,unsigned long)
+#define ATIS_IOCSSEP9050	_IOW(ATIS_MAGIC_IOC,4,struct sep9050)
+#define ATIS_IOCGSEP9050	_IOR(ATIS_MAGIC_IOC,5,struct sep9050)
+#define ATIS_IOCSSIGMODE	_IOW(ATIS_MAGIC_IOC,6,unsigned int)
+#define ATIS_IOCGSIGMODE	_IOW(ATIS_MAGIC_IOC,7,unsigned int)
+
+/* same order as the bytes in sp502.h and as the names in 8253xtty.c */
+
+#define SP502_OFF_MODE		0
+#define SP502_RS232_MODE	1
+#define SP502_V28_MODE		SP502_RS232_MODE
+#define SP502_RS422_MODE	2
+#define SP502_V11_MODE		SP502_RS422_MODE
+#define SP502_X27_MODE		SP502_RS422_MODE
+#define SP502_RS485_MODE	3
+#define SP502_RS449_MODE	4
+#define SP502_EIA530_MODE	5
+#define SP502_V35_MODE		6
+
+#define SAB8253XCLEARCOUNTERS 	(SIOCDEVPRIVATE + 5 + 1)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xmcs.c linux/drivers/net/wan/8253x/8253xmcs.c
--- linux.orig/drivers/net/wan/8253x/8253xmcs.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xmcs.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,637 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include "Reg9050.h"
+#include "8253xctl.h"
+#include "ring.h"
+#include "8253x.h"
+#include "crc32dcl.h"
+#include "8253xmcs.h"
+#include "sp502.h"
+
+/* Just to guarantee that strings are null terminated */
+#define MEMCPY(dest, src, cnt) \
+{ \
+	memcpy((dest), (src), (cnt)); \
+	(dest)[cnt] = 0; \
+}
+
+static unsigned char sp502progbyte[] =
+{
+	SP502_OFF,
+	SP502_RS232,
+	SP502_RS422,
+	SP502_RS485,
+	SP502_RS449,
+	SP502_EIA530,
+	SP502_V35
+};	
+
+/*
+ * The following routines are the multichannel server I2C serial EPROM routines.
+ */
+
+/*
+ * Set the clock and the data lines of the SEP.
+ */
+static void
+mcs_sep_set(mcs_sep_t *msp, unsigned sdavalid, unsigned sda,
+	    unsigned sclvalid, unsigned scl)
+{
+#ifdef MAX
+#undef MAX
+#endif		/* MAX */
+	
+#define MAX(x, y)	((x) > (y) ? (x) : (y))
+	
+	unsigned char csr;
+	unsigned int sleeptime;
+	
+	/*
+	 * Ensure sufficient clock
+	 */
+	
+	sleeptime = 0;
+	
+	if (sclvalid) 
+	{
+		if (msp->s_scl && !scl) 
+		{   /* do we have a downgoing transition? */
+			sleeptime = MAX(1, sleeptime);
+		}
+		else if (!msp->s_scl && scl) 
+		{	/* upgoing */
+			sleeptime = MAX(2, sleeptime);
+		}
+		msp->s_scl = scl;
+	}
+	
+	if (sdavalid) 
+	{
+		if ((msp->s_sda && !sda) || (!msp->s_sda && sda)) 
+		{
+			sleeptime = MAX(1, sleeptime);
+		}
+		
+		msp->s_sda = sda;
+	}
+	
+	if (sleeptime > 0) 
+	{
+		udelay(sleeptime);
+	}
+	
+	/*
+	 * Construct the CSR byte.
+	 */
+	csr = 0;
+	if (msp->s_sda) 
+	{
+		csr |= CIMCMD_CIMCSR_SDA;
+	}
+	
+	if (msp->s_scl) 
+	{
+		csr |= CIMCMD_CIMCSR_SCL;
+	}
+	
+	writeb((unsigned char) csr, msp->s_wrptr);
+}
+
+static void
+mcs_sep_start(mcs_sep_t *msp)
+{
+	/*
+	 * Generate a START condition
+	 */
+	mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
+	mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
+}
+
+static void
+mcs_sep_stop(mcs_sep_t *msp)
+{
+	/*
+	 * Generate a STOP condition
+	 */
+	mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
+	mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
+}
+
+/*
+ * Send out a single byte.
+ */
+static void
+mcs_sep_byte(mcs_sep_t *msp, unsigned char val)
+{
+	register int	 bitcount;
+	
+	/* Clock may be high ... lower the clock */
+	mcs_sep_set(msp, TRUE, FALSE, TRUE, FALSE);
+	
+	bitcount = 8;
+	
+	while (TRUE) 
+	{
+		mcs_sep_set(msp, TRUE, (val & 0x80) != 0, TRUE, FALSE);
+		mcs_sep_set(msp, TRUE, (val & 0x80) != 0, TRUE, TRUE);
+		
+		bitcount--;
+		if (bitcount == 0) 
+		{
+			break;
+		}
+		val <<= 1;
+	}
+	
+	/* Clock is high ... lower the clock */
+	mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+}
+
+/*
+ * Wait for an acknowledge cycle.  Expects the clock to be low.
+ */
+static unsigned
+mcs_sep_waitsep(mcs_sep_t *msp)
+{
+	int loopcount;
+	unsigned char cimcsr;
+  
+	/* Stop driving SDA */
+	mcs_sep_set(msp, TRUE, TRUE, FALSE, FALSE);
+	/* Raise the clock */
+	mcs_sep_set(msp, FALSE, FALSE, TRUE, TRUE);
+	
+	loopcount = 1000;
+	while (loopcount != 0) 
+	{
+		cimcsr = readb(msp->s_rdptr);
+		
+		if ((cimcsr & CIMCMD_CIMCSR_SDA) == 0) 
+		{
+			break;
+		}
+		loopcount--;
+	}
+	
+	/* Lower the clock */
+	mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+	
+	if (loopcount == 0) 
+	{
+		return FALSE;
+	}
+	else 
+	{
+		return TRUE;
+	}
+}
+
+/*
+ * Read the given CIM's SEP, starting at the given address, into
+ *  the given buffer, for the given length.
+ *
+ * Returns -1 if there was a failure, otherwise the byte count.
+ */
+
+static int
+mcs_sep_read(mcs_sep_t *msp, unsigned short addr, 
+	     unsigned char *buf, unsigned int nbytes)
+{
+	unsigned char cmdaddr, val, cimcsr;
+	unsigned int bytecount, bitcount;
+	
+	mcs_sep_start(msp);
+	
+	/*
+	 * First, send out a dummy WRITE command with no data.
+	 */
+	
+	cmdaddr = 0xa0 | (((addr >> 8) & 0x7) << 1) | 0x0;
+	
+	mcs_sep_byte(msp, cmdaddr);
+	
+	if (!mcs_sep_waitsep(msp)) 
+	{
+		return -1;
+	}
+	
+	/*
+	 * Now, send the reset of the address.
+	 */
+	
+	mcs_sep_byte(msp, (unsigned char) addr);
+	
+	if (!mcs_sep_waitsep(msp)) 
+	{
+		return -1;
+	}
+	
+	/*
+	 * Now, restart with a read command.
+	 */
+	
+	mcs_sep_start(msp);
+	
+	cmdaddr = 0xa0 | (((addr >> 8) & 0x7) << 1) | 0x1;
+	
+	mcs_sep_byte(msp, cmdaddr);
+	
+	if (!mcs_sep_waitsep(msp)) 
+	{
+		return -1;
+	}
+	
+	/*
+	 * Now, start reading the bytes.
+	 */
+	bytecount = 0;
+	while (TRUE) 
+	{
+		bitcount = 8;
+		val = 0;
+		while (TRUE) 
+		{
+			mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
+			
+			cimcsr = readb(msp->s_rdptr);
+			
+			if ((cimcsr & CIMCMD_CIMCSR_SDA) != 0) 
+			{
+				val |= 0x01;
+			}
+			
+			mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+			bitcount--;
+			
+			if (bitcount == 0) 
+			{
+				break;
+			}
+			val <<= 1;
+		}
+		
+		*buf++ = val;
+		bytecount++;
+		nbytes--;
+		
+		if (nbytes == 0) 
+		{
+			break;
+		}
+		
+		/*
+		 * Send the acknowledge.
+		 */
+		
+		mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+		mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
+		mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+	}
+	
+	mcs_sep_stop(msp);
+	
+	return (int) bytecount;
+}
+
+
+unsigned int mcs_ciminit(SAB_BOARD *bptr, AURA_CIM *cim)
+{
+	mcs_sep_t		 ms;
+	
+	ms.s_rdptr = (unsigned char *) 
+		(bptr->CIMCMD_REG + (CIMCMD_RDCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT)));
+	ms.s_wrptr = (unsigned char *) 
+		(bptr->CIMCMD_REG + (CIMCMD_WRCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT)));
+	ms.s_scl = ms.s_sda = FALSE;
+	
+	if (mcs_sep_read(&ms, (unsigned short) 0, &(cim->ci_sep[0]),
+			 sizeof(cim->ci_sep)) != sizeof(cim->ci_sep)
+	    || cim->ci_sep[MCS_SEP_MAGIC] != MCS_SEP_MAGICVAL) 
+	{
+		
+		if (cim->ci_sep[MCS_SEP_MAGIC] != MCS_SEP_MAGICVAL) 
+		{
+			DEBUGPRINT((KERN_ALERT
+				    "auraXX20: invalid CIM %d serial EPROM on board %d",
+				    cim->ci_num, bptr->board_number));
+		}
+		else 
+		{
+			DEBUGPRINT((KERN_ALERT
+				    "auraXX20: error reading CIM %d serial EPROM on board %d",
+				    cim->ci_num, bptr->board_number));
+		}
+		
+		cim->ci_clkspeed = WANMCS_CLKSPEED;
+		cim->ci_clkspdsrc = -1;
+		cim->ci_spdgrd = 10;
+		cim->ci_spdgrdsrc = -1;
+		cim->ci_flags = 0;
+		cim->ci_rev[0] = '\0';
+		cim->ci_sn[0] = '\0';
+		cim->ci_mfgdate[0] = '\0';
+		cim->ci_mfgloc[0] = '\0';
+		
+		/*
+		 * Diddle the port setup registers to determine if this
+		 *  CIM was built up for RS232 or SP502.
+		 */
+		
+		writew((unsigned short) 0xffff, (unsigned short *) 
+		       (bptr->CIMCMD_REG +
+			(CIMCMD_WRSETUP | (cim->ci_num << CIMCMD_CIMSHIFT))));
+		
+#ifdef RICHARD_DELAY
+		udelay(1);
+#endif		/* RICHARD_DELAY */
+		
+		if (readw((unsigned short *) 
+			  (bptr->CIMCMD_REG +
+			   (CIMCMD_RDSETUP | (cim->ci_num << CIMCMD_CIMSHIFT)))) == 0xffff) 
+		{
+			
+			writew(0, (unsigned short *) 
+			       (bptr->CIMCMD_REG +
+				(CIMCMD_WRSETUP | (cim->ci_num << CIMCMD_CIMSHIFT))));
+			
+#ifdef RICHARD_DELAY
+			udelay(1);
+#endif		/* RICHARD_DELAY */
+			
+			if (readw((unsigned short *) 
+				  (bptr->CIMCMD_REG +
+				   (CIMCMD_RDSETUP | (cim->ci_num << CIMCMD_CIMSHIFT)))) == 0) 
+			{
+				
+				cim->ci_type = CIM_SP502;
+			}
+			else 
+			{
+				cim->ci_type = CIM_RS232;
+			}
+		}
+		else 
+		{
+			cim->ci_type = CIM_RS232;
+		}
+		
+		if (cim->ci_type == CIM_SP502) 
+		{
+			cim->ci_flags |= CIM_SYNC;
+		}
+	}
+	else 
+	{
+		/*
+		 * Pick through the serial EPROM contents and derive
+		 *  the values we need.
+		 */
+		MEMCPY(&(cim->ci_rev[0]), &(cim->ci_sep[MCS_SEP_REV]),
+		       MCS_SEP_REVLEN);
+		MEMCPY(&(cim->ci_sn[0]), &(cim->ci_sep[MCS_SEP_SN]),
+		       MCS_SEP_SNLEN);
+		MEMCPY(&(cim->ci_mfgdate[0]), &(cim->ci_sep[MCS_SEP_MFGDATE]),
+		       MCS_SEP_MFGDATELEN);
+		MEMCPY(&(cim->ci_mfgloc[0]), &(cim->ci_sep[MCS_SEP_MFGLOC]),
+		       MCS_SEP_MFGLOCLEN);
+		
+		cim->ci_clkspeed = (unsigned long) cim->ci_sep[MCS_SEP_CLKSPD]
+			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 1] << 8)
+			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 2] << 16)
+			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 3] << 24);
+		
+		cim->ci_clkspdsrc = SEPROM;
+		
+		cim->ci_spdgrd = (int) cim->ci_sep[MCS_SEP_SPDGRD];
+		cim->ci_spdgrdsrc = SEPROM;
+		
+		cim->ci_flags = (unsigned long) cim->ci_sep[MCS_SEP_FLAGS];
+		
+		cim->ci_type = (int) cim->ci_sep[MCS_SEP_TYPE];
+	}
+	
+	/*
+	 * Possibly initialize the port setup registers.
+	 */
+	
+	if (cim->ci_type == CIM_SP502) 
+	{
+		unsigned short alloff;
+#ifdef DEBUG_VERBOSE
+		unsigned short readback;
+#endif
+		int offset;
+		
+		/*
+		 * Turn off all of the electrical interfaces.  The
+		 *  hardware *should* initialize to this state, but the
+		 *  prototype, at least, does not.  Note that this setting
+		 *  is reflected in the SIF_OFF setting of l_interface in
+		 *  mustard_lineinit, above.
+		 */
+		
+		alloff = (unsigned short) SP502_OFF
+			| ((unsigned short) SP502_OFF << 4)
+			| ((unsigned short) SP502_OFF << 8)
+			| ((unsigned short) SP502_OFF << 12);
+		for (offset = 0; offset < 8; offset++) 
+		{
+#ifdef DEBUG_VERBOSE
+			DEBUGPRINT((KERN_ALERT "cim %d setup reg #%d: writing 0x%x to 0x%x",
+				    cim->ci_num, offset, (unsigned) alloff,
+				    (CIMCMD_WRSETUP | (offset << 1) |
+				     (cim->ci_num << CIMCMD_CIMSHIFT))));
+#endif		 /* DEBUG_VERBOSE */
+			
+			writew((unsigned short) alloff, (unsigned short *)
+			       (bptr->CIMCMD_REG +
+				(CIMCMD_WRSETUP | (offset << 1) |
+				 (cim->ci_num << CIMCMD_CIMSHIFT))));
+#ifdef RICHARD_DELAY
+			udelay(1);
+#endif		/* RICHARD_DELAY */
+#ifdef DEBUG_VERBOSE
+			readback = readw((unsigned short *)
+					 (bptr->CIMCMD_REG +
+					  (CIMCMD_RDSETUP | (offset << 1) |
+					   (cim->ci_num << CIMCMD_CIMSHIFT))));
+			if (readback != alloff) 
+			{
+				DEBUGPRINT((KERN_ALERT "cim %d setup reg #%d: readback (0x%x) should be 0x%x",
+					    cim->ci_num, offset, readback, alloff));
+			}
+#endif		/* DEBUG_VERBOSE */
+		}
+	}
+	
+	/*
+	 * Clear out the CIM CSR with the exception of the LED.
+	 */
+	
+	writeb((unsigned char) 0, 
+	       (unsigned char *) (bptr->CIMCMD_REG +
+				  (CIMCMD_WRCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT))));
+	
+	return TRUE;
+}
+
+
+int wanmcs_reset(SAB_BOARD* bptr) /* note the board is the host card not the
+				   * individual extension boards
+				   */
+{
+	int		 counter;
+	
+#if 0				/* from the ASE driver */
+	/*
+	 * Program the AMCC to deactivate the write FIFO.
+	 */
+	
+	ASE_PUT32(cboard->b_bridgehandle,
+		  (aseuint32_t *) (cboard->b_bridge + AMCC_PTCR),
+		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 24) |
+		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 16) |
+		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 8) |
+		  (aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS));
+#endif		/* 0 */
+	
+	/*
+	 * First thing: do a reset of the local bus on the MIC 
+	 *  by diddling the Add-On Reset bit in the RCR.
+	 */
+	
+	writel((unsigned int) AMCC_AORESET, 
+	       (unsigned int *)(bptr->AMCC_REG + AMCC_RCR));
+	
+	udelay(10);		/* wait for 10 us. */
+	
+	writel((unsigned int) 0, 
+	       (unsigned int *)(bptr->AMCC_REG + AMCC_RCR));
+	
+	udelay(10);		/* wait for 10 us. */
+	
+	/*
+	 * Now the PCI bridge is reset.  Try to establish
+	 *  a link through the Glink chipset.
+	 */
+	
+	for (counter = 1000; counter != 0; counter--) 
+	{
+		writeb(0, (unsigned char*) (bptr->MICCMD_REG + MICCMD_MICCSR));
+		
+		udelay(5);
+		
+		if((readb((unsigned char*) 
+			  (bptr->MICCMD_REG + MICCMD_MICCSR)) & MICCMD_MICCSR_GLE) == 0)
+		{
+			break;
+		}
+	}
+	
+	/*
+	 * Did we run out of time?
+	 */
+	
+	if (counter == 0) 
+	{
+		printk(KERN_ALERT 
+		       "AMCC5920: board %p: GLink did not reset -- is the MEB on?",
+		       bptr);
+		
+		return FALSE;
+	}
+	
+	/*
+	 * Now, hit the reset in the MEB.
+	 */
+	
+	writeb(0, (unsigned int *) (bptr->CIMCMD_REG + CIMCMD_RESETENA));
+	
+	udelay(5);
+	
+	writeb(0, (unsigned int *) (bptr->CIMCMD_REG + CIMCMD_RESETDIS));
+	
+	/*
+	 * And we're done!
+	 */
+	
+	return TRUE;
+}
+
+void aura_sp502_program(SAB_PORT *port, register unsigned int sigindex)
+{
+	register unsigned char prognibble;
+	SAB_BOARD *bptr;
+	unsigned int cimnum;
+	unsigned int chipno;
+	unsigned int portno;
+	unsigned int rdaddressreceiver;
+	unsigned int rdaddresstransmitter;
+	unsigned int wraddressreceiver;
+	unsigned int wraddresstransmitter;
+	unsigned short datareceiver;
+	unsigned short datatransmitter;
+
+	bptr = port->board;
+	cimnum = port->chip->c_cim->ci_num;
+	chipno = (port->chip->c_chipno & 1); /* chip number relative to EB not MCS */
+	portno = (port->portno + (8 * chipno)); /* portno on a per EB basis */
+
+	prognibble = (sp502progbyte[sigindex] & 0x0F);
+
+				/* first 4 shorts contain receiver control bits */
+	rdaddressreceiver = 
+		(((unsigned int)bptr->CIMCMD_REG) + 
+		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_RDSETUP | ((portno/4) << CIMCMD_CTRLSHIFT)));
+				/* second 4 shorts contain transmitter control bits */
+	rdaddresstransmitter = 
+		(((unsigned int)bptr->CIMCMD_REG) + 
+		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_RDSETUP | ((4+(portno/4)) << CIMCMD_CTRLSHIFT)));
+
+	wraddressreceiver = 
+		(((unsigned int)bptr->CIMCMD_REG) + 
+		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_WRSETUP | ((portno/4) << CIMCMD_CTRLSHIFT)));
+	wraddresstransmitter = 
+		(((unsigned int)bptr->CIMCMD_REG) + 
+		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_WRSETUP | ((4+(portno/4)) << CIMCMD_CTRLSHIFT)));
+
+				/* read out the current receiver status */
+	datareceiver = readw((unsigned short*) rdaddressreceiver);
+				/* clear out nibble that corresponds to current port */
+	datareceiver &= (unsigned short) ~(0x0F << ((3 - (portno % 4)) * 4));
+				/* or in new receiver control field */
+	datareceiver |= (prognibble << ((3 - (portno % 4)) * 4));
+				/* write back the short that corresponds to 4 ports */
+	writew(datareceiver, (unsigned short*) wraddressreceiver);
+
+				/* just as above except that next 4 shorts correspond to transmitters */
+	datatransmitter = readw((unsigned short*) rdaddresstransmitter);
+	datatransmitter &= (unsigned short) ~(0x0F << ((3 - (portno % 4)) * 4)); 
+	datatransmitter |= (prognibble << ((3 - (portno % 4)) * 4));
+	writew(datatransmitter, (unsigned short*) wraddresstransmitter);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xmcs.h linux/drivers/net/wan/8253x/8253xmcs.h
--- linux.orig/drivers/net/wan/8253x/8253xmcs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xmcs.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,313 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+#ifndef _8253XMCS_H_
+#define _8253XMCS_H_
+
+#include "8253xctl.h"
+
+/* structures for the multi channel server, the host card, GLINK and
+ * extensions cards.  This system uses the AMCC S5920 instead of the
+ * PLX 9050 */
+
+/* ------------------------------------------------------------------------- */
+/* Useful macros */
+
+/*
+ * NOTICE: pciat_identify: pci125c,102 unit 1
+ * NOTICE: pciat_probe: pci125c,102 unit 1
+ * NOTICE: pciat_attach: pci125c,102 instance 1
+ * NOTICE: Reg End Size     Pointer  AccHandle
+ * NOTICE:   0 --  00000000 5093a000 5033f160
+ * NOTICE:   0 be  00000000 5093c000 5033f128
+ * NOTICE:   0 le  00000000 50940000 5033f0f0
+ * NOTICE:   1 --  00000080 50942000 5033f0b8
+ * NOTICE:   1 be  00000080 50944000 5033f080
+ * NOTICE:   1 le  00000080 50946000 5033f048
+ * NOTICE:   2 --  00004000 50948000 5033f010
+ * NOTICE:   2 be  00004000 5094c000 5033efd8
+ * NOTICE:   2 le  00004000 50950000 5033efa0
+ * NOTICE:   3 --  00008000 50954000 5033ef68
+ * NOTICE:   3 be  00008000 5095c000 5033ef30
+ * NOTICE:   3 le  00008000 50964000 5033eef8
+ * NOTICE:   4 --  00000800 5096c000 5033eec0
+ * NOTICE:   4 be  00000800 5096e000 5033ee88
+ * NOTICE:   4 le  00000800 50970000 5033ee50
+ * NOTICE: pciat_attach: pci125c,102 1: PCI reg property
+ * NOTICE: Idx Bus Dev Fun Reg Spc        Addr              Size
+ * NOTICE:   0 000 004 000 000 CFG 00000000 00000000 00000000 00000000
+ * NOTICE:   1 000 004 000 010 MEM 00000000 00000000 00000000 00000080
+ * NOTICE:   2 000 004 000 014 MEM 00000000 00000000 00000000 00004000
+ * NOTICE:   3 000 004 000 018 MEM 00000000 00000000 00000000 00008000
+ * NOTICE:   4 000 004 000 01c MEM 00000000 00000000 00000000 00000800
+ * PCI-device: pci125c,102@4, pciat #1
+ */
+
+/*
+ * Serial EPROM information:
+ *
+ *  + chip speed grade		[ one byte ]
+ *  + chip oscillator speed	[ 4 bytes ]
+ *  + board revision		[ ascii string ]
+ *  + date of manufacture	[ ascii string ]
+ *  + location of manufacture	[ ascii string ]
+ *  + serial number		[ ascii string ]
+ *  + prototype/production flag	[ one bit ]
+ *  + sync/async license	[ one bit ]
+ *  + CIM type			[ one byte ]
+ *  + assembly house		[ ascii string ]
+ */
+
+/*
+ * Serial EPROM map.
+ */
+
+#define MCS_SEP_TYPE		0x00
+#define MCS_SEP_FLAGS		0x01
+#define MCS_SEP_SPDGRD		0x02
+#define MCS_SEP_MAGIC		0x03
+#define MCS_SEP_CLKSPD		0x04
+#define MCS_SEP_SN		0x10
+#define MCS_SEP_SNLEN		0x10
+#define MCS_SEP_REV		0x20
+#define MCS_SEP_REVLEN		0x10
+#define MCS_SEP_MFGLOC		0x30
+#define MCS_SEP_MFGLOCLEN	0x10
+#define MCS_SEP_MFGDATE		0x40
+#define MCS_SEP_MFGDATELEN	0x20
+
+#define MCS_SEP_MAGICVAL	0x65
+
+/* Host NVRAM DEFINES */
+
+#define AMCC_NVR_VENDEVID	0x10 /* offset in 32bit quantities */
+
+/*
+ * PCI spaces on the CIM.
+ */
+#if 0				/* Solaris driver stuff */
+#define AMCC_REG		1
+#define CIMCMD_REG		2
+#define MICCMD_REG		3
+#define FIFOCACHE_REG		4
+#else
+#define AMCC_REG		virtbaseaddress0 /* bridge */
+#define CIMCMD_REG		virtbaseaddress1
+#define MICCMD_REG		virtbaseaddress2
+#define FIFOCACHE_REG		virtbaseaddress3
+#endif
+
+/*
+ * AMCC registers:
+ */
+
+#define AMCC_OMB		0x0c	/* 4 bytes */
+#define AMCC_IMB		0x1c	/* 4 bytes */
+#define AMCC_MBEF		0x34	/* 4 bytes */
+#define AMCC_INTCSR		0x38	/* 4 bytes */
+#define	AMCC_INTASSERT		0x00800000	/* RO */
+#define	AMCC_AOINTPIN		0x00400000	/* RO */
+#define	AMCC_IMINT		0x00020000	/* R/WC */
+#define	AMCC_OMINT		0x00010000	/* R/WC */
+#define	AMCC_AOINTPINENA	0x00002000	/* R/W */
+#define AMCC_RCR		0x3c	/* 4 bytes */
+#define	AMCC_NVRACCCTRLMASK	0xe0000000	/* nvRAM Acc. Ctrl */
+#define	AMCC_NVRACCFAIL		0x10000000	/* RO */
+#define AMCC_NVRBUSY		0x80000000
+#define AMCC_NVRWRLA		0x80000000
+#define AMCC_NVRWRHA		0xa0000000
+#define AMCC_NVRRDDB		0xe0000000
+#define	AMCC_NVROPPMASK		0x000f0000	/* R/W */
+#define	AMCC_MBXFLGRESET	0x08000000	/* WO */
+#define	AMCC_RDFIFORESET	0x02000000	/* WO */
+#define	AMCC_AORESET		0x01000000	/* R/W */
+#define AMCC_PTCR		0x60	/* 4 bytes */
+#define	AMCC_AMWTSTATEMASK	0x07
+#define	AMCC_PREFETCHMASK	0x18
+#define	AMCC_WRFIFODIS		0x20
+#define	AMCC_ENDCONV		0x40
+#define	AMCC_PTMODE		0x80
+
+#define AMCC_SIZE		0x80	/* space size, in bytes */
+#define AMCC_NVRAM_SIZE	        0x40 /* in shorts just to be consistent with
+				      * other eprom and nvram sizes*/
+
+/*
+ * CIM Command space	0x0000 - 0x3fff
+ */
+
+#define CIMCMD_CHANSHIFT	6	/* shift channel# to the left */
+#define CIMCMD_CHANMASK		0x3f	/* 6 bits of mask */
+#define CIMCMD_CIMSHIFT		10	/* shift cim# to the left */
+#define CIMCMD_CIMMASK		0x3	/* 2 bits of mask */
+#define CIMCMD_CTRLSHIFT	1	/* shift control address to the left */
+#define CIMCMD_CTRLMASK		0x7	/* 3 bits of mask */
+#define CIMCMD_CHIPSHIFT	9
+
+#define CIMCMD_RESET		0x0000
+#define CIMCMD_RDINT		0x0002
+#define CIMCMD_RDINT_ESCCMASK	0x00ff
+#define CIMCMD_WRINT		0x0003
+#define CIMCMD_WRINTENA		0x0004
+#define CIMCMD_WRINTDIS		0x0006
+#define CIMCMD_RESETENA		0x0007	/* assert reset */
+#define CIMCMD_RESETDIS		0x0000	/* deassert the reset */
+#define CIMCMD_RDFIFOW		0x1000	/* add channel# */
+#define CIMCMD_WRFIFOB		0x2002	/* add channel# */
+#define CIMCMD_WRFIFOW		0x2000	/* add channel# */
+#define CIMCMD_RDREGB		0x1000	/* add channel# and reg# (>= 0x20) */
+#define CIMCMD_WRREGB		0x2000	/* add channel# and reg# (>= 0x20) */
+#define CIMCMD_RDSETUP		0x3200	/* add cim# and address (word acc) */
+#define CIMCMD_WRSETUP		0x3220	/* add cim# and address (word acc) */
+#define CIMCMD_RDCIMCSR		0x3000	/* add cim# */
+#define CIMCMD_CIMCSR_LED	0x01
+#define CIMCMD_CIMCSR_SWI	0x02
+#define CIMCMD_CIMCSR_SDA	0x04
+#define CIMCMD_CIMCSR_SCL	0x08
+#define CIMCMD_CIMCSR_TESTMASK	0xc0
+#define CIMCMD_WRCIMCSR		0x3020	/* add cim# */
+
+#define CIMCMD_SIZE		0x4000	/* space size, in bytes */
+
+/*
+ * MIC Command space	0x0000 - 0x5fc0
+ */
+
+#define MICCMD_CHANSHIFT	6	/* shift channel# to the left */
+#define MICCMD_CHANMASK		0x3f	/* 6 bits of mask */
+
+#define MICCMD_MICCSR		0x0000	/* R/W (byte) */
+#define MICCMD_MICCSR_END	0x80
+#define MICCMD_MICCSR_ENL	0x40
+#define MICCMD_MICCSR_LPN	0x20
+#define MICCMD_MICCSR_DGM	0x10
+#define MICCMD_MICCSR_CPY	0x08
+#define MICCMD_MICCSR_GLE	0x04
+#define MICCMD_MICCSR_RXE	0x02
+#define MICCMD_MICCSR_IRQ	0x01
+#define MICCMD_REV		0x0001	/* RO (byte) */
+#define MICCMD_CACHETRIG	0x5000	/* WO (byte: #words-1) add channel# */
+
+#define MICCMD_SIZE		0x8000	/* space size, in bytes */
+
+/*
+ * FIFO Cache space	0x000 - 0x7ff
+ */
+
+#define FIFOCACHE_CHANSHIFT	5	/* shift channel# to the left */
+#define FIFOCACHE_CHANMASK	0x3f	/* 6 bits of mask */
+
+#define FIFOCACHE_FIFOCACHE	0x000	/* add channel# and word offset */
+
+#define FIFOCACHE_SIZE		0x800	/* space size, in bytes */
+
+/*
+ * Other miscellaneous constants
+ */
+
+#define MAX_NCIMS		4	/* maximum of 4 CIMS */
+#define CIM_NPORTS		16	/* 16 ports per CIM */
+#define CIM_NCHIPS		2	/* 2 ESCC8s/CIM */
+#define CHIP_NPORTS		8	/* 8 ports per chip */
+
+#define WANMCS_CLKSPEED	7372800	/* 7.3728 MHz */
+
+
+/* PCR/PVR (Universal Port) */
+
+/*
+ * To summarize the use of the parallel port:
+ *                    RS-232
+ * Parallel port A -- TxClkdir control	(output) ports 0 - 7
+ * Parallel port B -- DTR		(output) ports 0 - 7
+ * Parallel port C -- DSR		(input)  ports 0 - 7
+ * Parallel port D -- unused
+ */
+
+#define WANMCS_PCRAVAL		0x00	/* all output bits */
+#define WANMCS_PCRBVAL		0x00	/* all output bits */
+#define WANMCS_PCRCVAL		0xff	/* all input bits */
+#define WANMCS_PCRDVAL		0x0f	/* 4 input bits */
+
+#define WANMCS_PIMAVAL		0xff	/* all interrupts off */
+#define WANMCS_PIMBVAL		0xff	/* all interrupts off */
+#define WANMCS_PIMCVAL		0xff	/* all interrupts off */
+#define WANMCS_PIMDVAL		0x0f	/* all interrupts off */
+
+#define WANMCS_PVRAVAL		0xff	/* all high */
+#define WANMCS_PVRBVAL		0xff	/* all high */
+
+#define ANY_BITS_ARE_ON(x, b)	(((x) & (b)) != 0)
+#define ANY_BITS_ARE_OFF(x, b)	((((x) & (b)) ^ (b)) != 0)
+#define ALL_BITS_ARE_ON(x, b)	((((x) & (b)) ^ (b)) == 0)
+
+/* ------------------------------------------------------------------------- */
+/* New types and type specific macros */
+
+typedef struct _mcs_sep 
+{
+#if 0
+	ddi_acc_handle_t	 s_handle; /* something from Solaris */
+#endif
+	unsigned char		*s_rdptr;
+	unsigned char		*s_wrptr;
+	unsigned int		 s_scl;
+	unsigned int		 s_sda;
+} mcs_sep_t;
+
+/*
+ * Per-line private information for wanmcs.
+ */
+
+typedef struct _wanmcspriv 
+{
+	unsigned char		 r_chipunit;	/* [0, 1] or [0, 7] */
+	
+	/* these items are for accessing the ESCCx registers as bytes */
+#if 0
+	ddi_acc_handle_t	 r_reghandle;	/* handle for access to ESCCx regs */
+#endif
+	unsigned char		*r_rdregbase;	/* base for reading ESCCx registers */
+	unsigned char		*r_wrregbase;	/* base for writing ESCCx registers */
+	
+	/* these items are for accessing the ESCCx FIFOs as bytes and words */
+#if 0
+	ddi_acc_handle_t	 r_fifohandle;
+#endif
+	unsigned short	*r_rdfifow;	/* read FIFO word */
+	unsigned char		*r_wrfifob;	/* write FIFO byte */
+	unsigned short	*r_wrfifow;	/* write FIFO word */
+	
+	/* these items are for accessing the MIC command space */
+#if 0
+	ddi_acc_handle_t	 r_miccmdhandle;
+#endif
+	unsigned char		*r_wrcachetrig;	/* the FIFO cache trigger */
+	
+	/* these itmes are for accessing the FIFO cache space */
+#if 0
+	ddi_acc_handle_t r_fifocachehandle;
+#endif
+	unsigned short *r_fifocachebase;    
+} wanmcspriv_t;
+
+#define AMCC_INT_OFF 0
+
+extern unsigned int 
+amcc_read_nvram(unsigned char* buffer, 
+		unsigned length, 
+		unsigned char *bridge_space);
+
+extern unsigned int mcs_ciminit(SAB_BOARD *bptr, AURA_CIM *cim);
+
+extern int wanmcs_reset(SAB_BOARD* bptr);
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xnet.c linux/drivers/net/wan/8253x/8253xnet.c
--- linux.orig/drivers/net/wan/8253x/8253xnet.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xnet.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,702 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ **/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include "Reg9050.h"
+#include "8253xctl.h"
+#include "ring.h"
+#include "8253x.h"
+#include "crc32dcl.h"
+
+				/* turns network packet into a pseudoethernet */
+				/* frame -- does ethernet stuff that 8253x does */
+				/* not do -- makes minimum  64 bytes add crc, etc*/
+int 
+sab8253xn_write2(struct sk_buff *skb, struct net_device *dev)
+{
+	size_t cnt;
+	unsigned int flags;
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	struct sk_buff *substitute;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+	if(dev->tbusy != 0)		/* something of an error */
+	{
+		++(priv->Counters.tx_drops);
+		dev_kfree_skb_any(skb);
+		return -EBUSY;		/* only during release */
+	}
+#endif
+
+	if(priv->active2.transmit == NULL)
+	{
+		return -ENOMEM;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "sab8253x: sending IP packet(bytes):\n"));
+
+	DEBUGPRINT((KERN_ALERT "sab8253x: start address is %p.\n", skb->data));
+	
+	cnt = skb->tail - skb->data;
+	cnt = MIN(cnt, sab8253xn_rbufsize);
+	if(cnt < ETH_ZLEN)
+	{
+		if((skb->end - skb->data) >= ETH_ZLEN)
+		{
+			skb->tail = (skb->data + ETH_ZLEN);
+			cnt = ETH_ZLEN;
+		}
+		else
+		{
+			substitute = dev_alloc_skb(ETH_ZLEN);
+			if(substitute == NULL)
+			{
+				dev_kfree_skb_any(skb);
+				return 0;
+			}
+			substitute->tail = (substitute->data + ETH_ZLEN);
+			memcpy(substitute->data, skb->data, cnt);
+			cnt = ETH_ZLEN;
+			dev_kfree_skb_any(skb);
+			skb = substitute;
+		}
+	}
+	
+	save_flags(flags); cli();
+	if((priv->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		++(priv->Counters.tx_drops);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+		dev->tbusy = 1;
+#else
+		netif_stop_queue (dev);
+#endif
+		priv->tx_full = 1;
+		restore_flags(flags);
+		return 1;
+	}
+	restore_flags(flags);
+#ifndef FREEINTERRUPT
+	if(priv->active2.transmit->HostVaddr != NULL)
+	{
+		register RING_DESCRIPTOR *freeme;
+		
+		freeme = priv->active2.transmit;
+		do
+		{
+			skb_unlink((struct sk_buff*)freeme->HostVaddr);
+			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+			freeme->HostVaddr = NULL;
+			freeme = (RING_DESCRIPTOR*) freeme->VNext;
+		}
+		while(((freeme->Count & OWNER) != OWN_SAB) &&
+		      (freeme->HostVaddr != NULL));
+	}
+#endif
+	dev->trans_start = jiffies;
+	skb_queue_head(priv->sab8253xbuflist, skb);
+	priv->active2.transmit->HostVaddr = skb;
+	priv->active2.transmit->sendcrc = 1;
+	priv->active2.transmit->crcindex = 0;
+	priv->active2.transmit->crc = fn_calc_memory_crc32(skb->data, cnt);
+	priv->active2.transmit->Count = (OWN_SAB|cnt); /* must be this order */
+	priv->active2.transmit = 
+		(RING_DESCRIPTOR*) priv->active2.transmit->VNext;
+	priv->Counters.transmitbytes += cnt;
+	sab8253x_start_txS(priv);
+	return 0;
+}
+
+	/* packetizes the received character */
+	/* stream */
+static void sab8253x_receive_charsN(struct sab_port *port,
+				    union sab8253x_irq_status *stat)
+{
+	unsigned char buf[32];
+	int free_fifo = 0;
+	int reset_fifo = 0;
+	int msg_done = 0;
+	int msg_bad = 0;
+	int count = 0;
+	int total_size = 0;
+	int rstatus = 0;
+	struct sk_buff *skb;
+	
+	/* Read number of BYTES (Character + Status) available. */
+	
+	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
+	{
+		++msg_bad;
+		++free_fifo;
+		++reset_fifo;
+	}
+	else
+	{
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
+		{
+			count = port->recv_fifo_size;
+			++free_fifo;
+		}
+		
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 
+		{
+			count = READB(port,rbcl);
+			count &= (port->recv_fifo_size - 1);
+			++msg_done;
+			++free_fifo;
+			
+			total_size = READB(port, rbch);
+			if(total_size & SAB82532_RBCH_OV)
+			{
+				msg_bad++;
+			}
+			
+			rstatus = READB(port, rsta);
+			if((rstatus & SAB82532_RSTA_VFR) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RDO)
+			{
+				msg_bad++;
+			}
+			if((rstatus & SAB82532_RSTA_CRC) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RAB)
+			{
+				msg_bad++;
+			}
+		}
+	}
+	
+	/* Read the FIFO. */
+	(*port->readfifo)(port, buf, count);
+	
+	/* Issue Receive Message Complete command. */
+	
+	if (free_fifo) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
+	}
+	
+	if(reset_fifo)
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
+	}
+	
+	if(port->active2.receive == NULL)
+	{
+		return;
+	}
+	
+	if(msg_bad)
+	{
+		++(port->Counters.rx_drops);
+		port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; /* clear the buffer */
+		port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
+		return;
+	}
+	
+	memcpy(port->active2.receive->HostVaddr->tail, buf, count);
+	port->active2.receive->HostVaddr->tail += count;
+	
+	if(msg_done)
+	{
+		port->active2.receive->Count = 
+			(port->active2.receive->HostVaddr->tail - port->active2.receive->HostVaddr->data);
+		if((port->active2.receive->Count < (ETH_ZLEN+4+3)) || /* 4 is the CRC32 size 3 bytes from the SAB part */
+		   (skb = dev_alloc_skb(sab8253xn_rbufsize), skb == NULL))
+		{
+			++(port->Counters.rx_drops);
+			port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; 
+				/* clear the buffer */
+			port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
+		}
+		else
+		{
+			port->active2.receive->Count -= 3;
+			port->active2.receive->HostVaddr->len = port->active2.receive->Count;
+			port->active2.receive->HostVaddr->pkt_type = PACKET_HOST;
+			port->active2.receive->HostVaddr->dev = port->dev;
+			port->active2.receive->HostVaddr->protocol = 
+				eth_type_trans(port->active2.receive->HostVaddr, port->dev);
+			port->active2.receive->HostVaddr->tail -= 3;
+			++(port->Counters.receivepacket);
+			port->Counters.receivebytes += port->active2.receive->Count;
+			skb_unlink(port->active2.receive->HostVaddr);
+			
+			netif_rx(port->active2.receive->HostVaddr);
+			
+			skb_queue_head(port->sab8253xbuflist, skb);
+			port->active2.receive->HostVaddr = skb;
+			port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
+		}
+	}
+}
+
+static void sab8253x_check_statusN(struct sab_port *port,
+				   union sab8253x_irq_status *stat)
+{
+	int modem_change = 0;
+	mctlsig_t         *sig;
+	
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 
+	{
+		port->icount.buf_overrun++;
+	}
+	
+	/* Checking DCD */
+	sig = &port->dcd;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dcd);
+		port->icount.dcd++;
+		modem_change++;
+	}
+	/* Checking CTS */
+	sig = &port->cts;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,cts);
+		port->icount.cts++;
+		modem_change++;
+	}
+	/* Checking DSR */
+	sig = &port->dsr;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dsr);
+		port->icount.dsr++;
+		modem_change++;
+	}
+	if (modem_change)
+	{
+		wake_up_interruptible(&port->delta_msr_wait);
+	}
+	
+	sig = &port->dcd;
+	if ((port->flags & FLAG8253X_CHECK_CD) &&
+	    (stat->images[sig->irq] & sig->irqmask)) 
+	{
+		
+		if (sig->val)
+		{
+			netif_carrier_on(port->dev);
+		}
+		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+			   (port->flags & FLAG8253X_CALLOUT_NOHUP))) 
+		{
+			netif_carrier_off(port->dev);
+		}
+	}
+#if 0				/* need to think about CTS/RTS stuff for a network driver */
+	sig = &port->cts;
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{				/* not setting this yet */
+		if (port->tty->hw_stopped) 
+		{
+			if (sig->val) 
+			{
+				
+				port->tty->hw_stopped = 0;
+				sab8253x_sched_event(port, RS_EVENT_WRITE_WAKEUP);
+				port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
+				WRITEB(port, imr1, port->interrupt_mask1);
+				sab8253x_start_txS(port);
+			}
+		} 
+		else 
+		{
+			if (!(sig->val)) 
+			{
+				port->tty->hw_stopped = 1;
+			}
+		}
+	}
+#endif
+}
+
+static void Sab8253xCollectStats(struct net_device *dev)
+{
+	
+	struct net_device_stats *statsp = 
+		&((SAB_PORT*) dev->priv)->stats;
+	
+	memset(statsp, 0, sizeof(struct net_device_stats));
+	
+	statsp->rx_packets +=
+		((SAB_PORT*)dev->priv)->Counters.receivepacket;
+	statsp->tx_packets +=
+		((SAB_PORT*)dev->priv)->Counters.transmitpacket;
+	statsp->tx_dropped += 
+		((SAB_PORT*)dev->priv)->Counters.tx_drops;
+	statsp->rx_dropped += 
+		((SAB_PORT*)dev->priv)->Counters.rx_drops;
+}
+
+struct net_device_stats *sab8253xn_stats(struct net_device *dev)
+{
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	
+	Sab8253xCollectStats(dev);
+	return &priv->stats;
+}
+
+/* minimal ioctls -- more to be added later */
+int sab8253xn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	
+	switch(cmd)
+	{
+	case SAB8253XCLEARCOUNTERS:
+		memset(&priv->Counters, 0, sizeof(struct counters));
+		break;
+		
+	default:
+		break;
+	}
+	return 0;
+}
+
+#if 0
+static int sab8253x_block_til_readyN(SAB_PORT *port)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+	unsigned long	flags;
+	
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (port->flags & FLAG8253X_CLOSING)
+	{
+		if (port->flags & FLAG8253X_CLOSING)
+		{
+			interruptible_sleep_on(&port->close_wait);
+		}
+#ifdef SERIAL_DO_RESTART
+		if (port->flags & FLAG8253X_HUP_NOTIFY)
+		{
+			return -EAGAIN;
+		}
+		else
+		{
+			return -ERESTARTSYS;
+		}
+#else
+		return -EAGAIN;
+#endif
+	}
+	
+	/*
+	 * this is not a callout device
+	 */
+	
+	/* suppose callout active */
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE) 
+	{
+		if (port->normal_termios.c_cflag & CLOCAL)
+		{
+			do_clocal = 1;
+		}
+	} 
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, port->count is dropped by one, so that
+	 * sab8253x_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&port->open_wait, &wait);
+	port->blocked_open++;
+	while (1) 
+	{
+		save_flags(flags); cli();
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE))
+		{
+			RAISE(port,dtr);
+			RAISE(port,rts);	/* maybe not correct for sync */
+			/*
+			 * ??? Why changing the mode here? 
+			 *  port->regs->rw.mode |= SAB82532_MODE_FRTS;
+			 *  port->regs->rw.mode &= ~(SAB82532_MODE_RTS);
+			 */
+		}
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (!(port->flags & FLAG8253X_INITIALIZED)) 
+		{
+#ifdef SERIAL_DO_RESTART
+			if (port->flags & FLAG8253X_HUP_NOTIFY)
+			{
+				retval = -EAGAIN;
+			}
+			else
+			{
+				retval = -ERESTARTSYS;	
+			}
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    !(port->flags & FLAG8253X_CLOSING) &&
+		    (do_clocal || ISON(port,dcd))) 
+		{
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("block_til_readyN:2 flags = 0x%x\n",port->flags);
+#endif
+		if (signal_pending(current)) 
+		{
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&port->open_wait, &wait);
+	port->blocked_open--;
+	if (retval)
+	{
+		return retval;
+	}
+	port->flags |= FLAG8253X_NORMAL_ACTIVE; /* is this a good flag? */
+	return 0;
+}
+#endif
+
+int sab8253x_startupN(struct sab_port *port)
+{
+	unsigned long flags;
+	int retval = 0;
+	
+	save_flags(flags); cli();
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		goto errout;
+	}
+	
+	if (!port->regs) 
+	{
+		retval = -ENODEV;
+		goto errout;
+	}
+	/*
+	 * Initialize the Hardware
+	 */
+	sab8253x_init_lineS(port);	/* nothing in this function
+					 * refers to tty structure */
+	
+	/* Activate RTS */
+	RAISE(port,rts);
+	/* Activate DTR */
+	RAISE(port,dtr);
+	/*
+	 * Initialize the modem signals values
+	 */
+	port->dcd.val=ISON(port,dcd);
+	port->cts.val=ISON(port,cts);
+	port->dsr.val=ISON(port,dsr);
+	/*
+	 * Finally, enable interrupts
+	 */
+	
+	port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE |
+		SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC;
+	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); */
+	
+	WRITEB(port,imr0,port->interrupt_mask0);
+	port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR |
+		SAB82532_IMR1_TIN | SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	port->all_sent = 1;
+	
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	sab8253x_change_speedN(port);
+	
+	port->flags |= FLAG8253X_INITIALIZED; /* bad name for indicating to other functionalities status */
+	port->receive_chars = sab8253x_receive_charsN;
+	port->transmit_chars = sab8253x_transmit_charsS;
+	port->check_status = sab8253x_check_statusN;
+	port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR |
+			       SAB82532_ISR1_XDU | SAB82532_ISR1_CSC);
+	port->check_status_test = (SAB82532_ISR1_CSC);
+	
+	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? 0 : SAB82532_ISR0_CDSC));*/
+	
+	restore_flags(flags);
+	return 0;
+	
+ errout:
+	restore_flags(flags);
+	return retval;
+}
+
+int sab8253xn_open(struct net_device *dev)
+{
+	unsigned int retval;
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	
+	if(priv->function != FUNCTION_NR)
+	{
+		return -ENODEV;		/* only allowed if there are no restrictions on the port */
+	}
+	
+	
+	if(priv->flags & FLAG8253X_CLOSING) /* try again after the TTY close finishes */
+	{	
+#ifdef SERIAL_DO_RESTART
+		return ((priv->flags & FLAG8253X_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS); /* The ifconfig UP will just fail */
+#else
+		return -EAGAIN;
+#endif
+	}
+	
+	/*
+	 * Maybe start up serial port -- may already be running a TTY
+	 */
+	if(priv->flags & FLAG8253X_NORMAL_ACTIVE) /* probably should be a test open at all */
+	{
+		return -EBUSY;	/* can't reopen in NET */
+	}
+	
+	if(Sab8253xSetUpLists(priv))
+	{
+		return -ENODEV;
+	}
+	
+	if(Sab8253xInitDescriptors2(priv, sab8253xn_listsize, sab8253xn_rbufsize))
+	{
+		Sab8253xCleanUpTransceiveN(priv);
+		return -ENODEV;
+	}
+	netif_carrier_off(dev);
+	
+	priv->open_type = OPEN_SYNC_NET;
+	priv->tty = 0;
+	
+	retval = sab8253x_startupN(priv);
+	if (retval)
+	{
+		Sab8253xCleanUpTransceiveN(priv);
+		return retval;		
+	}
+	
+	priv->flags |= FLAG8253X_NETWORK; /* flag the call out driver that it has to reinitialize the port */
+	priv->tx_full = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+	dev->start = 1;
+	dev->tbusy = 0;
+#else
+	netif_start_queue(dev);
+#endif
+
+	priv->flags |= FLAG8253X_NORMAL_ACTIVE; /* is this a good flag? */
+	MOD_INC_USE_COUNT;
+	return 0;			/* success */
+}
+/* stop the PPC, free all skbuffers */
+int sab8253xn_release(struct net_device *dev)	/* stop */
+{
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	unsigned long flags;
+	
+	printk(KERN_ALERT "sab8253xn: network interface going down.\n");
+	save_flags(flags); cli();
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+	dev->start = 0;
+	dev->tbusy = 1;
+#else
+	netif_stop_queue (dev);
+#endif
+	
+	sab8253x_shutdownN(priv);
+	Sab8253xCleanUpTransceiveN(priv);
+	netif_carrier_off(dev);
+	priv->flags &= ~FLAG8253X_NETWORK; 
+	priv->flags &= ~(FLAG8253X_NORMAL_ACTIVE|/*FLAG8253X_CALLOUT_ACTIVE|*/
+			 FLAG8253X_CLOSING);
+	priv->open_type = OPEN_NOT;
+	MOD_DEC_USE_COUNT;
+	restore_flags(flags);
+	return 0;
+}
+
+SAB_PORT *current_sab_port = NULL;
+
+int sab8253xn_init(struct net_device *dev)
+{
+	
+	SAB_PORT *priv;
+	
+	printk(KERN_ALERT "sab8253xn: initializing SAB8253X network driver instance.\n");
+	
+	priv = current_sab_port;
+	dev->priv = priv;
+	
+	if(dev->priv == NULL)
+	{
+		printk(KERN_ALERT "sab8253xn: could not find active port!\n");
+		return -ENOMEM;
+	}
+	priv->dev = dev;
+	
+	ether_setup(dev);
+	
+	dev->irq = priv->irq;
+	dev->hard_start_xmit = sab8253xn_write2;
+	dev->do_ioctl = sab8253xn_ioctl;
+	dev->open = sab8253xn_open;
+	dev->stop = sab8253xn_release;
+	dev->get_stats = sab8253xn_stats;
+	dev->base_addr = (unsigned) priv->regs;
+	/* should I do a request region here */
+	priv->next_dev = Sab8253xRoot;
+	Sab8253xRoot = dev;
+	return 0;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xplx.c linux/drivers/net/wan/8253x/8253xplx.c
--- linux.orig/drivers/net/wan/8253x/8253xplx.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xplx.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,299 @@
+/* -*- linux-c -*- */
+
+/* plx9050.c 
+ * Copyright (C) 2000 by Francois Wautier
+ * based on code from Bjorn Davis
+ * 
+ * Read and write command for the eprom attached to
+ * the PLX9050 
+ */
+
+/* Modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ **/
+
+/* We handle PCI devices */
+#include <linux/pci.h>      
+
+/* We need to use ioremap */ 
+#include <asm/io.h>
+
+#include <linux/delay.h>
+
+				/* Joachim Martillo modified this file */
+				/* so that it had no dependencies on specific */
+				/* Aurora adapter card or ESSC* structures*/
+				/* The original file use TRUE for 1 and */
+				/* FALSE for 0.  This convention conflicted */
+				/* with other conventions throughout LINUX */
+				/* also TRUE was used for setting an eprom */
+				/* bit which is a slight semantic confusion. */
+				/* I just used 0 and 1 */
+#include "Reg9050.h"
+
+/*
+ * Write a single bit to the serial EPROM interface.
+ */
+
+				/* eprom_ctl is the */
+				/* address of the 9050 */
+				/* eprom control register */
+				/* The original & operation */
+				/* looks wrong.  I am surprised */
+				/* the code worked */ 
+				/* but I left the parentheses */
+				/* because readl, writel etc */
+				/* are macros*/
+
+				/* The following function */
+				/* assumes the proper bit */
+				/* in the serial eprom */
+				/* has already been selected*/
+
+				/* The 9050 registers are 32 bits */
+				/* hence the readl and writel */
+				/* macros are invoked*/
+
+				/* eprom_ctl must be a virtual */
+				/* address*/
+
+static void plx9050_eprom_wbit(unsigned int* eprom_ctl, unsigned int val)
+{
+	unsigned int	 ctrl;
+	
+	/* get the initial value of the CTRL register */
+	ctrl = readl((eprom_ctl));
+	
+	/* set or clear the data bit */
+	if (val) 
+	{
+		ctrl |= PLX_CTRL_SEPWD;
+	}
+	else 
+	{
+		ctrl &= ~PLX_CTRL_SEPWD;
+	}
+	
+	writel(ctrl, (eprom_ctl));
+	
+	udelay(1);
+	
+	/* Toggle the clock line */
+	/* gets to the next bit */
+	/* in the serial eprom */
+	ctrl |= PLX_CTRL_SEPCLK;
+	writel(ctrl, (eprom_ctl));
+	
+	udelay(1);
+	
+	/* Toggle the clock line */
+	ctrl &= ~PLX_CTRL_SEPCLK;
+	writel(ctrl, (eprom_ctl));
+	udelay(1);
+}
+
+/*
+ * Run a serial EPROM command.  Returns 1 on success,
+ *  0 otherwise.
+ */
+
+/* This routine does the write of data but only sets up */
+/* for a read*/
+/* the write goes from most significant to least significant */
+unsigned int plx9050_eprom_cmd(unsigned int* eprom_ctl, unsigned char cmd, unsigned char addr, unsigned short data)
+{
+	unsigned int ctrl;
+	unsigned char shiftb;
+	unsigned short shiftw;
+	unsigned int l, v;
+	unsigned char ret;
+	int i;
+	
+	ret = 1;
+	shiftb = addr << (NM93_BITS_PER_BYTE - NM93_ADDRBITS); /* looks a bizarre way to mask out unused bits */
+	
+	ctrl = readl((eprom_ctl));
+	
+	ctrl &= ~(PLX_CTRL_SEPCLK | PLX_CTRL_SEPWD);
+	writel(ctrl, (eprom_ctl));
+	udelay(1);
+	
+	ctrl |= PLX_CTRL_SEPCS;
+	writel(ctrl, (eprom_ctl));
+	
+	plx9050_eprom_wbit(eprom_ctl, 1);
+	
+	/*
+	 * Clock out the command
+	 */
+	
+	plx9050_eprom_wbit(eprom_ctl, (cmd & 0x02) != 0);
+	plx9050_eprom_wbit(eprom_ctl, (cmd & 0x01) != 0);
+	
+	/*
+	 * Clock out the address
+	 */
+	
+	i = NM93_ADDRBITS;
+	while (i != 0)		/* here we get to the correct */
+				/* short in the serial eprom*/
+	{
+		/* printf("Loop #1\n"); */
+		plx9050_eprom_wbit(eprom_ctl, (shiftb & 0x80) != 0);
+		
+		shiftb <<= 1;
+		i--;
+	}
+	
+	if (cmd == NM93_WRITECMD)	/* now do the write if */
+		/* a write is to be done*/
+	{	
+		/* write data? */
+		/*
+		 * Clock out the data
+		 */
+		
+		shiftw = data;
+		
+		i = NM93_BITS_PER_WORD;
+		while (i != 0) {
+			/* printf("Loop #2\n"); */
+			plx9050_eprom_wbit(eprom_ctl, (shiftw & 0x8000) != 0);
+			
+			shiftw <<= 1;
+			i--;
+		}
+		
+		/*
+		 * De-assert chip select for a short period of time
+		 */
+		ctrl = readl((eprom_ctl));
+		
+		ctrl &= ~PLX_CTRL_SEPCS;
+		writel(ctrl, (eprom_ctl));
+		udelay(2);
+		
+		/*
+		 * Re-assert chip select
+		 */
+		ctrl |= PLX_CTRL_SEPCS;
+		writel(ctrl, (eprom_ctl));
+		
+		/*
+		 * Wait for a low to high transition of DO
+		 */
+		
+		i = 20000;
+		ctrl = readl((eprom_ctl));
+		l = (ctrl & PLX_CTRL_SEPRD);
+		
+		while (i != 0) 
+		{
+			/* printf("Loop #3\n"); */
+			ctrl = readl((eprom_ctl));
+			v = (ctrl & PLX_CTRL_SEPRD);
+			if (v != 0 && l == 0) 
+			{
+				break;
+			}
+			l = v;
+			udelay(1);
+			i--;
+		}
+		
+		if (i == 0) 
+		{
+			printk("plx9050: eprom didn't go low to high");
+			ret = 0;
+		}
+	}
+	
+	if (cmd != NM93_READCMD)	/* not a read -- terminate */
+	{
+		/*
+		 * De-assert the chip select.
+		 */
+		
+		ctrl = readl((eprom_ctl));
+		ctrl &= ~PLX_CTRL_SEPCS;
+		writel(ctrl,(eprom_ctl));
+	}
+	/* otherwise left in read state */
+	return ret;
+}
+
+/*
+ * Read the serial EPROM.  Returns 1 on success, 0 on failure.
+ * reads in shorts (i.e., 16 bits at a time.)
+ *
+ */
+
+unsigned int
+plx9050_eprom_read(unsigned int* eprom_ctl, unsigned short *ptr, unsigned char addr, unsigned short len)
+{
+	unsigned short shiftw;
+	int i;
+	unsigned int ctrl;
+	
+	if (!plx9050_eprom_cmd(eprom_ctl, NM93_READCMD, addr, (unsigned short) 0x0)) /* set up read */
+	{
+		return 0;
+	}
+	
+	ctrl = readl((eprom_ctl));	/* synchronize */
+	
+	while (len-- > 0)		/* now read one word at a time */
+	{
+		shiftw = 0;
+		
+		ctrl &= ~PLX_CTRL_SEPCLK;
+		writel(ctrl, (eprom_ctl));
+		
+		udelay(1);
+		
+		i = NM93_BITS_PER_WORD;
+		while (1)			/* now read one bit at a time, */
+			/* left shifting each bit */
+		{
+			ctrl |= PLX_CTRL_SEPCLK;
+			writel(ctrl, (eprom_ctl));
+			
+			udelay(1);
+			
+			ctrl = readl((eprom_ctl));
+			
+			
+			if ((ctrl & PLX_CTRL_SEPRD) != 0) 
+			{
+				shiftw |= 0x1;
+			}
+			
+			i--;
+			if (i == 0) 
+			{
+				break;
+			}
+			shiftw <<= 1;
+			
+			ctrl &= ~PLX_CTRL_SEPCLK;
+			writel(ctrl, (eprom_ctl));
+			udelay(1);
+		}
+		
+		*ptr++ = shiftw;
+	}
+	
+	ctrl &= ~PLX_CTRL_SEPCS;
+	writel(ctrl, (eprom_ctl));
+	
+	udelay(1);
+	ctrl &= ~PLX_CTRL_SEPCLK;
+	writel(ctrl, (eprom_ctl));
+	
+	return 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xsyn.c linux/drivers/net/wan/8253x/8253xsyn.c
--- linux.orig/drivers/net/wan/8253x/8253xsyn.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xsyn.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,1339 @@
+/* -*- linux-c -*- */
+/* $Id: 8253xsyn.c,v 1.17 2002/02/10 22:17:25 martillo Exp $
+ * 8253xsyn.c: SYNC TTY Driver for the SIEMENS SAB8253X DUSCC.
+ *
+ * Implementation, modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/* Standard in kernel modules */
+#define DEFINE_VARIABLE
+#include <linux/module.h>   /* Specifically, a module */
+#include <asm/io.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include "8253xctl.h"
+#include "8253x.h"
+#include <linux/pci.h>
+#include <linux/fs.h>
+
+#ifdef MODULE
+#undef XCONFIG_SERIAL_CONSOLE
+#endif
+
+
+static void sab8253x_flush_to_ldiscS(void *private_) /* need a separate version for sync
+						 there are no flags associated with
+						 received sync TTY data*/
+{
+	struct tty_struct *tty = (struct tty_struct *) private_;
+	unsigned char	*cp;
+	int		count;
+	struct sab_port *port;
+	struct sk_buff *skb;  
+	
+	if(tty)
+	{
+		port = (struct sab_port *)tty->driver_data;
+	}
+	else
+	{
+		return;
+	}
+	if(port == NULL)
+	{
+		return;
+	}
+	
+	if (test_bit(TTY_DONT_FLIP, &tty->flags)) 
+	{
+		queue_task(&tty->flip.tqueue, &tq_timer);
+		return;
+	}
+	/* note that a hangup may have occurred -- perhaps should check for that */
+	port->DoingInterrupt = 1;
+	while(port->sab8253xc_rcvbuflist && (skb_queue_len(port->sab8253xc_rcvbuflist) > 0))
+	{
+		skb = skb_dequeue(port->sab8253xc_rcvbuflist);
+		count = skb->data_len;
+		cp = skb->data;
+		(*tty->ldisc.receive_buf)(tty, cp, 0, count);
+		dev_kfree_skb_any(skb);
+	}
+	port->DoingInterrupt = 0;
+}
+
+void sab8253x_flush_charsS(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_flush_chars"))
+	{
+		return;
+	}
+	
+	if ((Sab8253xCountTransmit(port) <= 0) || tty->stopped || tty->hw_stopped)
+	{				/* can't flush */
+		return;
+	}
+	
+	sab8253x_start_txS(port);
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_stopS() and sab8253x_startS()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+
+void sab8253x_stopS(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	/* can't do anything here */
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_stop"))
+	{
+		return;
+	}
+	/*  interrupt handles it all*/
+	/* turning off XPR is not an option in sync mode */
+}
+
+void sab8253x_startS(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_start"))
+	{
+		return;
+	}
+	sab8253x_start_txS(port);
+}
+
+
+static void sab8253x_receive_charsS(struct sab_port *port,
+			     union sab8253x_irq_status *stat)
+{
+	struct tty_struct *tty = port->tty;
+	unsigned char buf[32];
+	int free_fifo = 0;
+	int reset_fifo = 0;
+	int msg_done = 0;
+	int msg_bad = 0;
+	int count = 0;
+	int total_size = 0;
+	int rstatus = 0;
+	struct sk_buff *skb;
+	
+	/* Read number of BYTES (Character + Status) available. */
+	
+	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
+	{
+		++msg_bad;
+		++free_fifo;
+		++reset_fifo;
+	}
+	else
+	{
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
+		{
+			count = port->recv_fifo_size;
+			++free_fifo;
+		}
+		
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 
+		{
+			count = READB(port, rbcl);
+			count &= (port->recv_fifo_size - 1);
+			++msg_done;
+			++free_fifo;
+			
+			total_size = READB(port, rbch);
+			if(total_size & SAB82532_RBCH_OV) /* need to revisit for 4096 byte frames */
+			{
+				msg_bad++;
+			}
+			
+			rstatus = READB(port, rsta);
+			if((rstatus & SAB82532_RSTA_VFR) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RDO)
+			{
+				msg_bad++;
+			}
+			if((rstatus & SAB82532_RSTA_CRC) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RAB)
+			{
+				msg_bad++;
+			}
+		}
+	}
+	
+	/* Read the FIFO. */
+	
+	(*port->readfifo)(port, buf, count);
+	
+	
+	/* Issue Receive Message Complete command. */
+	
+	if (free_fifo) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
+	}
+	
+	if(reset_fifo)
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
+	}
+	
+	if(msg_bad)
+	{
+		port->msgbufindex = 0;
+		return;
+	}
+	
+	memcpy(&port->msgbuf[port->msgbufindex], buf, count);
+	port->msgbufindex += count;
+	
+#ifdef CONSOLE_SUPPORT
+	if (port->is_console)
+	{
+		wake_up(&keypress_wait);
+	}
+#endif
+	
+	if(msg_done)
+	{
+		
+		if(port->msgbufindex <= 3) /* min is 1 char + 2 CRC + status byte */
+		{
+			port->msgbufindex = 0;
+			return;
+		}
+		
+		total_size = port->msgbufindex - 3; /* strip off the crc16 and the status byte */
+		port->msgbufindex = 0;
+		
+		/* ignore the receive buffer waiting -- we know the correct size here */
+		
+		if (!tty)
+		{
+			return;
+		}
+		if(skb = dev_alloc_skb(total_size), skb)
+		{
+			memcpy(skb->data, &port->msgbuf[0], total_size);
+			skb->tail = (skb->data + total_size);
+			skb->data_len = total_size;
+			skb->len = total_size;
+			skb_queue_tail(port->sab8253xc_rcvbuflist, skb);
+		}
+		queue_task(&tty->flip.tqueue, &tq_timer); /* clear out flip buffer as fast as possible
+							   * maybe should not be done unconditionally hear
+							   * but should be within the above consequence
+							   * clause */
+	}
+}
+
+
+static void sab8253x_check_statusS(struct sab_port *port,
+			    union sab8253x_irq_status *stat)
+{
+	struct tty_struct *tty = port->tty;
+	int modem_change = 0;
+	mctlsig_t         *sig;
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	/* check_modem:*/
+	/* Checking DCD */
+	sig = &port->dcd;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dcd);
+		port->icount.dcd++;
+		modem_change++;
+	}
+	/* Checking CTS */
+	sig = &port->cts;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,cts);
+		port->icount.cts++;
+		modem_change++;
+	}
+	/* Checking DSR */
+	sig = &port->dsr;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dsr);
+		port->icount.dsr++;
+		modem_change++;
+	}
+	if (modem_change)
+	{
+		wake_up_interruptible(&port->delta_msr_wait);
+	}
+	
+	sig = &port->dcd;
+	if ((port->flags & FLAG8253X_CHECK_CD) &&
+	    (stat->images[sig->irq] & sig->irqmask)) 
+	{
+		
+		if (sig->val)
+		{
+			wake_up_interruptible(&port->open_wait);
+		}
+		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+			   (port->flags & FLAG8253X_CALLOUT_NOHUP))) 
+		{
+#if 0				/* requires more investigation */
+			MOD_INC_USE_COUNT;
+			if (schedule_task(&port->tqueue_hangup) == 0)
+			{
+				MOD_DEC_USE_COUNT;
+			}
+#endif
+		}
+	}
+	
+	sig = &port->cts;
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{				/* not setting this yet */
+		if (port->tty->hw_stopped) 
+		{
+			if (sig->val) 
+			{
+				port->tty->hw_stopped = 0;
+				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
+				sab8253x_start_txS(port);
+			}
+		} 
+		
+		else 
+		{
+			if(!(getccr2configS(port) & SAB82532_CCR2_TOE))
+			{
+				if (!(sig->val)) 
+				{
+					port->tty->hw_stopped = 1;
+				}
+			}
+		}
+	}
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void sab8253x_change_speedS(struct sab_port *port)
+{
+	unsigned long	flags,baud;
+	tcflag_t	cflag;
+	u8	        ccr2=0,ccr4=0,ebrg=0;
+	int		i, bits;
+#ifdef DEBUGGING
+	printk("Change speed!  ");
+#endif
+	if (!port->tty || !port->tty->termios) 
+	{
+#ifdef DEBUGGING
+		printk("NOT!\n");
+#endif
+		return;
+	}
+	
+#ifdef DEBUGGING
+	printk(" for real.\n");
+#endif
+	
+	cflag = port->tty->termios->c_cflag;
+	
+	/* Byte size and parity */
+	switch (cflag & CSIZE) 
+	{
+	case CS5: 
+		bits = 7; 
+		break;
+	case CS6: 
+		bits = 8; 
+		break;
+	case CS7: 
+		bits = 9; 
+		break;
+	default:
+	case CS8: 
+		bits = 10; 
+		break;
+	}
+	
+	if (cflag & CSTOPB) 
+	{
+		bits++;
+	}
+	
+	if (cflag & PARENB) 
+	{
+		bits++;
+	}
+	
+	/* Determine EBRG values based on the "encoded"baud rate */
+	i = cflag & CBAUD;
+	switch(i)
+	{
+	case B0:
+		baud=0;
+		break;
+	case  B50:
+		baud=100;
+		break;
+	case  B75:
+		baud=150;
+		break;
+	case  B110:
+		baud=220;
+		break;
+	case  B134:
+		baud=269;
+		break;
+	case  B150:
+		baud=300;
+		break;
+	case  B200:
+		baud=400;
+		break;
+	case B300:
+		baud=600;
+		break;
+	case B600:
+		baud=1200;
+		break;
+	case B1200:
+		baud=2400;
+		break;
+	case B1800:
+		baud=3600;
+		break;
+	case B2400:
+		baud=4800;
+		break;
+	case B4800:
+		baud=9600;
+		break;
+	case B9600:
+		baud=19200;
+		break;
+	case B19200:
+		baud=38400;
+		break;
+	case  B38400:
+		if(port->custspeed)
+		{
+			baud=port->custspeed<<1;
+		}
+		else
+		{
+			baud=76800;
+		}
+		break;
+	case B57600:
+		baud=115200;
+		break;
+#ifdef SKIPTHIS
+	case B76800:
+		baud=153600;
+		break;
+	case B153600:
+		baud=307200;
+		break;
+#endif
+	case B230400:
+		baud=460800;
+		break;
+	case  B460800:
+		baud=921600;
+		break;
+	case B115200:
+	default:
+		baud=230400;
+		break;
+	}
+	
+	if(!sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud))) 
+	{
+		printk("Aurora Warning. baudrate %ld could not be set! Using 115200",baud);
+		baud=230400;
+		sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud));
+	}
+	
+	if (port->baud)
+		port->timeout = (port->xmit_fifo_size * HZ * bits) / port->baud;
+	else
+		port->timeout = 0;
+	port->timeout += HZ / 50;		/* Add .02 seconds of slop */
+	
+	/* CTS flow control flags */
+	if (cflag & CRTSCTS)
+		port->flags |= FLAG8253X_CTS_FLOW;
+	else
+		port->flags &= ~(FLAG8253X_CTS_FLOW);
+	
+	if (cflag & CLOCAL)
+		port->flags &= ~(FLAG8253X_CHECK_CD);
+	else
+		port->flags |= FLAG8253X_CHECK_CD;
+	if (port->tty)
+		port->tty->hw_stopped = 0;
+	
+	/*
+	 * Set up parity check flag
+	 * XXX: not implemented, yet.
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+	
+	/*
+	 * Characters to ignore
+	 * XXX: not implemented, yet.
+	 */
+	
+	/*
+	 * !!! ignore all characters if CREAD is not set
+	 * XXX: not implemented, yet.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= SAB82532_ISR0_RPF;
+	
+	save_flags(flags); 
+	cli();
+	sab8253x_cec_wait(port);
+	
+	WRITEB(port, bgr, ebrg);
+	WRITEB(port, ccr2, READB(port, ccr2) & ~(0xc0)); /* clear out current baud rage */
+	WRITEB(port, ccr2, READB(port, ccr2) | ccr2);
+	WRITEB(port, ccr4, (READB(port,ccr4) & ~SAB82532_CCR4_EBRG) | ccr4);
+	
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{
+		WRITEB(port, mode, READB(port,mode) & ~(SAB82532_MODE_RTS));
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_CSC);
+		WRITEB(port, imr1, port->interrupt_mask1);
+	} 
+	else 
+	{
+		WRITEB(port, mode, READB(port,mode) | SAB82532_MODE_RTS);
+		port->interrupt_mask1 |= SAB82532_IMR1_CSC;
+		WRITEB(port, imr1, port->interrupt_mask1);
+	}
+	WRITEB(port, mode, READB(port, mode) | SAB82532_MODE_RAC);
+	restore_flags(flags);
+}
+
+void sab8253x_set_termiosS(struct tty_struct *tty,
+			   struct termios *old_termios)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if((tty->termios->c_cflag == old_termios->c_cflag) && 
+	   (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag)))
+	{
+		return;
+	}
+	if(!port)
+	{
+		return;
+	}
+	sab8253x_change_speedS(port);
+	
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(tty->termios->c_cflag & CBAUD)) 
+	{
+		LOWER(port,rts);
+		LOWER(port,dtr);
+	}
+	
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (tty->termios->c_cflag & CBAUD)) 
+	{
+		RAISE(port,dtr);
+		if (!tty->hw_stopped ||
+		    !(tty->termios->c_cflag & CRTSCTS)) 
+		{
+			RAISE(port,rts);
+		}
+	}
+	
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) 
+	{
+		tty->hw_stopped = 0;
+		sab8253x_startS(tty);
+	}
+}
+
+static int sab8253x_startupS(struct sab_port *port)
+{
+	unsigned long flags;
+	int retval = 0;
+	
+	save_flags(flags); cli();
+	
+	port->msgbufindex = 0;
+	port->xmit_buf = NULL;
+	port->buffergreedy = 0;
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		goto errout;
+	}
+	
+	if (!port->regs) 
+	{
+		if (port->tty)
+		{
+			set_bit(TTY_IO_ERROR, &port->tty->flags);
+		}
+		retval = -ENODEV;
+		goto errout;
+	}
+	/*
+	 * Initialize the Hardware
+	 */
+	sab8253x_init_lineS(port);
+	
+#if 0				/* maybe should be conditional */
+	if (port->tty->termios->c_cflag & CBAUD) 
+	{
+#endif
+		/* Activate RTS */
+		RAISE(port,rts);
+		/* Activate DTR */
+		RAISE(port,dtr);
+#if 0
+	}
+#endif
+	
+	/*
+	 * Initialize the modem signals values
+	 */
+	port->dcd.val=ISON(port,dcd);
+	port->cts.val=ISON(port,cts);
+	port->dsr.val=ISON(port,dsr);
+	/*
+	 * Finally, enable interrupts
+	 */
+	
+	port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE |
+		SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC;
+	
+	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); */
+	
+	WRITEB(port,imr0,port->interrupt_mask0);
+	port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR |
+		SAB82532_IMR1_TIN | SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	port->all_sent = 1;
+	
+	if (port->tty)
+	{
+		clear_bit(TTY_IO_ERROR, &port->tty->flags);
+	}
+	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	sab8253x_change_speedS(port);
+	
+	port->flags |= FLAG8253X_INITIALIZED;
+	port->receive_chars = sab8253x_receive_charsS;
+	port->transmit_chars = sab8253x_transmit_charsS;
+	port->check_status = sab8253x_check_statusS;
+	port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR |
+			       SAB82532_ISR1_XDU | SAB82532_ISR1_CSC);
+	port->check_status_test = (SAB82532_ISR1_CSC);
+	
+	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? 0 : SAB82532_ISR0_CDSC));*/
+	
+	
+	restore_flags(flags);
+	return 0;
+	
+ errout:
+	restore_flags(flags);
+	return retval;
+}
+
+static void sab8253x_shutdownS(struct sab_port *port)
+{
+	unsigned long flags;
+	
+	if (!(port->flags & FLAG8253X_INITIALIZED))
+	{
+		return;
+	}
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+	
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&port->delta_msr_wait);
+	
+	if (port->xmit_buf) 
+	{
+		port->xmit_buf = 0;
+	}
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (port->is_console) 
+	{
+		port->interrupt_mask0 = 
+			SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+			/*SAB82532_IMR0_TIME |*/
+			SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;
+		WRITEB(port,imr0,port->interrupt_mask0);
+		port->interrupt_mask1 = 
+			SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+			SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+			SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+			SAB82532_IMR1_XPR;
+		WRITEB(port,imr1,port->interrupt_mask1);
+		if (port->tty)
+		{
+			set_bit(TTY_IO_ERROR, &port->tty->flags);
+		}
+		port->flags &= ~FLAG8253X_INITIALIZED;
+		restore_flags(flags);
+		return;
+	}
+#endif
+	
+	/* Disable Interrupts */
+	
+	port->interrupt_mask0 = 0xff;
+	WRITEB(port, imr0, port->interrupt_mask0);
+	port->interrupt_mask1 = 0xff;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	
+	if (!port->tty || (port->tty->termios->c_cflag & HUPCL)) 
+	{
+		LOWER(port,rts);
+		LOWER(port,dtr);
+	}
+	
+	/* Disable Receiver */	
+	CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC);
+	
+	/* Power Down */	
+	CLEAR_REG_BIT(port,ccr0,SAB82532_CCR0_PU);
+	
+	if (port->tty)
+	{
+		set_bit(TTY_IO_ERROR, &port->tty->flags);
+	}
+	
+	port->flags &= ~FLAG8253X_INITIALIZED;
+	restore_flags(flags);
+}
+
+int sab8253x_writeS(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	struct sk_buff *skb;
+	int truelength = 0;
+	int do_queue = 1;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_write"))
+	{
+		return 0;
+	}
+	
+	if(count == 0)
+	{
+		return 0;
+	}
+	
+	if(port->active2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	if((port->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		sab8253x_start_txS(port);	/* no descriptor slot */
+		return 0;
+	}
+	
+#ifndef FREEININTERRUPT
+	skb = port->active2.transmit->HostVaddr; /* current slot value */
+	
+	if(port->buffergreedy == 0)	/* are we avoiding buffer free's */
+	{				/* no */
+		if((skb != NULL) || /* not OWN_SAB from above */
+		   (port->active2.transmit->crcindex != 0)) 
+		{
+			register RING_DESCRIPTOR *freeme;
+			
+			freeme = port->active2.transmit;
+			do
+			{
+				if((freeme->crcindex == 0) && (freeme->HostVaddr == NULL))
+				{
+					break;
+				}
+				if(freeme->HostVaddr)
+				{
+					skb_unlink((struct sk_buff*)freeme->HostVaddr);
+					dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+					freeme->HostVaddr = NULL;
+				}
+				freeme->sendcrc = 0;
+				freeme->crcindex = 0;
+				freeme = (RING_DESCRIPTOR*) freeme->VNext;
+			}
+			while((freeme->Count & OWNER) != OWN_SAB);
+		}
+		skb = NULL;		/* buffer was freed */
+	}
+	
+	if(skb != NULL)		/* potentially useful */
+	{
+		truelength = (skb->end - skb->head);
+		if(truelength >= count)
+		{
+			skb->data = skb->head; /* this buffer is already queued */
+			skb->tail = skb->head;
+			do_queue = 0;
+		}
+		else
+		{
+			skb_unlink(skb);
+			dev_kfree_skb_any(skb);
+			skb = NULL;
+			port->active2.transmit->HostVaddr = NULL;
+		}
+	}
+	/* in all cases the following is allowed */
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+#endif
+	
+	if(skb == NULL)
+	{
+		if(port->DoingInterrupt)
+		{
+			skb = alloc_skb(count, GFP_ATOMIC);
+		}
+		else
+		{
+			skb = alloc_skb(count, GFP_KERNEL);
+		}
+	}
+	
+	if(skb == NULL)
+	{
+		printk(KERN_ALERT "sab8253xs: no skbuffs available.\n");
+		return 0;
+	}
+	if(from_user)
+	{
+		copy_from_user(skb->data, buf, count);
+	}
+	else
+	{
+		memcpy(skb->data, buf, count);
+	}
+	skb->tail = (skb->data + count);
+	skb->data_len = count;
+	skb->len = count;
+	
+	if(do_queue)
+	{
+		skb_queue_head(port->sab8253xbuflist, skb);
+	}
+	
+	port->active2.transmit->HostVaddr = skb;
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+	port->active2.transmit->Count = (OWN_SAB|count);
+	port->active2.transmit = port->active2.transmit->VNext;
+	
+	sab8253x_start_txS(port);
+	return count;
+}
+
+void sab8253x_throttleS(struct tty_struct * tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_throttleS"))
+	{
+		return;
+	}
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	if (I_IXOFF(tty))
+	{
+		sab8253x_send_xcharS(tty, STOP_CHAR(tty));
+	}
+}
+
+void sab8253x_unthrottleS(struct tty_struct * tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_unthrottle"))
+	{
+		return;
+	}
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	if (I_IXOFF(tty)) 
+	{
+		sab8253x_send_xcharS(tty, START_CHAR(tty));
+	}
+}
+
+void sab8253x_send_xcharS(struct tty_struct *tty, char ch)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	int stopped;
+	int hw_stopped;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_send_xcharS"))
+	{
+		return;
+	}
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return;
+	}
+	
+	save_flags(flags); cli();
+	
+	if((port->sabnext2.transmit->Count & OWNER) == OWN_SAB) /* may overwrite a character
+								 * -- but putting subsequent
+								 * XONs or XOFFs later in the
+								 * stream could cause problems
+								 * with the XON and XOFF protocol */
+	{
+		port->sabnext2.transmit->sendcrc = 1;
+		port->sabnext2.transmit->crcindex = 3;
+		port->sabnext2.transmit->crc = (ch << 24); /* LITTLE ENDIAN */
+		restore_flags(flags);
+	}
+	else
+	{
+		restore_flags(flags);
+		sab8253x_writeS(tty, 0, &ch, 1);
+	}
+	
+	stopped = tty->stopped;
+	hw_stopped = tty->hw_stopped;
+	tty->stopped = 0;
+	tty->hw_stopped = 0;
+	
+	sab8253x_start_txS(port);
+	
+	tty->stopped = stopped;
+	tty->hw_stopped = hw_stopped;
+}
+
+
+void sab8253x_breakS(struct tty_struct *tty, int break_state)
+{
+	struct sab_port *port = (struct sab_port *) tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_breakS"))
+	{
+		return;
+	} /* can't break in sync mode */
+}
+
+void sab8253x_closeS(struct tty_struct *tty, struct file * filp)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	MOD_DEC_USE_COUNT;	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_closeS"))
+	{
+		return;
+	}
+
+	if(port->open_type == OPEN_SYNC_NET)
+	{				/* port->tty field should already be NULL */
+		return;
+	}
+	
+	save_flags(flags); cli();
+	--(port->count);
+	if (tty_hung_up_p(filp)) 
+	{
+		if(port->count == 0)	/* I think the reason for the weirdness
+					   relates to freeing of structures in
+					   the tty driver */
+		{
+			port->open_type = OPEN_NOT;
+		}
+		else if(port->count < 0)
+		{
+			printk(KERN_ALERT "XX20: port->count went negative.\n");
+			port->count = 0;
+			port->open_type = OPEN_NOT;
+		}
+		restore_flags(flags);
+		return;
+	}
+	
+#if 0
+	if ((tty->count == 1) && (port->count != 0)) 
+	{
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  port->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("sab8253x_close: bad serial port count; tty->count is 1,"
+		       " port->count is %d\n", port->count);
+		port->count = 0;
+	}
+#endif
+	
+	if (port->count < 0) 
+	{
+		printk(KERN_ALERT "sab8253x_close: bad serial port count for ttys%d: %d\n",
+		       port->line, port->count);
+		port->count = 0;
+	}
+	if (port->count) 
+	{
+		restore_flags(flags);
+		return;
+	}
+	port->flags |= FLAG8253X_CLOSING;
+	
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (port->flags & FLAG8253X_NORMAL_ACTIVE)
+	{
+		port->normal_termios = *tty->termios;
+	}
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE)
+	{
+		port->callout_termios = *tty->termios;
+	}
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (port->closing_wait != SAB8253X_CLOSING_WAIT_NONE) 
+	{
+		tty_wait_until_sent(tty, port->closing_wait);
+	}
+	
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and turn off
+	 * the receiver.
+	 */
+	
+#if 0
+	port->interrupt_mask0 |= SAB82532_IMR0_TCD; /* not needed for sync */
+#endif
+	WRITEB(port,imr0,port->interrupt_mask0);
+	
+	CLEAR_REG_BIT(port, mode, SAB82532_MODE_RAC); /* turn off receiver */
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		sab8253x_wait_until_sent(tty, port->timeout);
+	}
+	sab8253x_shutdownS(port);
+	Sab8253xCleanUpTransceiveN(port);
+	if (tty->driver.flush_buffer)
+	{
+		tty->driver.flush_buffer(tty);
+	}
+	if (tty->ldisc.flush_buffer)
+	{
+		tty->ldisc.flush_buffer(tty);
+	}
+	tty->closing = 0;
+	port->event = 0;
+	port->tty = 0;
+	if (port->blocked_open) 
+	{
+		if (port->close_delay) 
+		{
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(port->close_delay);
+		}
+		wake_up_interruptible(&port->open_wait);
+	}
+	port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE|
+			 FLAG8253X_CLOSING);
+	wake_up_interruptible(&port->close_wait);
+	port->open_type = OPEN_NOT;
+	restore_flags(flags);
+}
+
+
+void sab8253x_hangupS(struct tty_struct *tty)
+{
+	struct sab_port * port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_hangupS"))
+	{
+		return;
+	}
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (port->is_console)
+	{
+		return;
+	}
+#endif
+	
+	sab8253x_flush_buffer(tty);
+	if(port)
+	{
+		sab8253x_shutdownS(port);
+		Sab8253xCleanUpTransceiveN(port);
+		port->event = 0;
+		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE);
+		port->tty = 0;
+		wake_up_interruptible(&port->open_wait);
+	}
+}
+
+int sab8253x_openS(struct tty_struct *tty, struct file * filp)
+{
+	struct sab_port	*port;
+	int retval, line;
+	int counter;
+	unsigned long flags;
+	
+	MOD_INC_USE_COUNT;  
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	
+	for(counter = 0, port = AuraPortRoot; 
+	    (counter < line) && (port != NULL); 
+	    ++counter)
+	{
+		port = port->next;
+	}
+	
+	if (!port) 
+	{
+		printk(KERN_ALERT "sab8253x_openS: can't find structure for line %d\n",
+		       line);
+		return -ENODEV;
+	}
+	
+	save_flags(flags);		/* Need to protect port->tty element */
+	cli();
+	
+	if(port->tty == 0)
+	{
+		port->tty = tty;
+		tty->flip.tqueue.routine = sab8253x_flush_to_ldiscS;
+	}
+	tty->driver_data = port;
+	
+	if(port->function != FUNCTION_NR)
+	{
+		++(port->count);
+		restore_flags(flags);
+		return -ENODEV;		/* only allowed if there are no restrictions on the port */
+	}
+	
+	if(port->open_type == OPEN_SYNC_NET)
+	{
+		port->tty = NULL;	/* Don't bother with open counting here
+					   but make sure the tty field is NULL*/
+		restore_flags(flags);
+		return -EBUSY;
+	}
+	
+	restore_flags(flags);
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_openS"))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	
+#ifdef DEBUG_OPEN
+	printk("sab8253x_open %s%d, count = %d\n", tty->driver.name, port->line,
+	       port->count);
+#endif
+	
+	/*
+	 * If the port is in the middle of closing, bail out now.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (port->flags & FLAG8253X_CLOSING)) 
+	{
+		
+		if (port->flags & FLAG8253X_CLOSING)
+		{
+			interruptible_sleep_on(&port->close_wait);
+		}
+#ifdef SERIAL_DO_RESTART
+		++(port->count);
+		return ((port->flags & FLAG8253X_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		++(port->count);
+		return -EAGAIN;
+#endif
+	}
+	
+	if(port->flags & FLAG8253X_NORMAL_ACTIVE)
+	{
+		if(port->open_type == OPEN_ASYNC)
+		{
+			++(port->count);
+			return -EBUSY;	/* can't reopen in sync mode */
+		}
+	}
+	if(port->open_type > OPEN_SYNC) /* can reopen a SYNC_TTY */
+	{
+		return -EBUSY;
+	}
+	if(Sab8253xSetUpLists(port))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xs_listsize, sab8253xs_rbufsize))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	
+	retval = sab8253x_startupS(port);
+	if (retval)
+	{
+		++(port->count);
+		return retval;		/* does not check channel mode */
+	}
+	
+	retval = sab8253x_block_til_ready(tty, filp, port); /* checks channel mode */
+	++(port->count);
+	if (retval) 
+	{
+		return retval;
+	}
+	
+	port->tty = tty;		/* may change here once through the block */
+	/* because now the port belongs to an new tty */
+	tty->flip.tqueue.routine = sab8253x_flush_to_ldiscS;
+	if(Sab8253xSetUpLists(port))
+	{
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xs_listsize, sab8253xs_rbufsize))
+	{
+		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */
+		/* is the crc32 that is appended */
+		return -ENODEV;
+	}
+	
+	/*
+	 * Start up serial port
+	 */
+	retval = sab8253x_startupS(port); /* in case cu was running the first time
+					   * the function was called*/
+	if (retval)
+	{
+		return retval;		/* does not check channel mode */
+	}
+	
+	if ((port->count == 1) &&
+	    (port->flags & FLAG8253X_SPLIT_TERMIOS)) 
+	{
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+		{
+			*tty->termios = port->normal_termios;
+		}
+		else 
+		{
+			*tty->termios = port->callout_termios;
+		}
+		sab8253x_change_speedS(port);
+	}
+	
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (sab8253x_console.cflag && sab8253x_console.index == line) 
+	{
+		tty->termios->c_cflag = sab8253x_console.cflag;
+		sab8253x_console.cflag = 0;
+		change_speed(port);
+	}
+#endif
+	
+	port->session = current->session;
+	port->pgrp = current->pgrp;
+	port->open_type = OPEN_SYNC;
+	return 0;
+}
+
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xtty.c linux/drivers/net/wan/8253x/8253xtty.c
--- linux.orig/drivers/net/wan/8253x/8253xtty.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xtty.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,2925 @@
+/* -*- linux-c -*- */
+/* $Id: 8253xtty.c,v 1.23 2002/02/10 22:17:25 martillo Exp $
+ * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * Modified by Francois Wautier 2000 (fw@auroratech.com)
+ *
+ * Extended extensively by Joachim Martillo 2001 (Telford002@aol.com)
+ * 	to provide synchronous/asynchronous TTY/Callout/character/network device
+ * 	capabilities.
+ *
+ * Modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+/* Standard in kernel modules */
+#define DEFINE_VARIABLE
+#include <linux/module.h>   /* Specifically, a module */
+#include <asm/io.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include <linux/pci.h>
+#include "8253xctl.h"
+#include "sp502.h"
+
+DECLARE_TASK_QUEUE(tq_8253x_serial); /* this just initializes a list head called */
+				     /* tq_8253x_serial*/
+
+struct tty_driver sab8253x_serial_driver, sab8253x_callout_driver, sync_sab8253x_serial_driver;
+int sab8253x_refcount;
+
+/* Trace things on serial device, useful for console debugging: */
+#undef SERIAL_LOG_DEVICE
+
+#ifdef SERIAL_LOG_DEVICE
+static void dprint_init(int tty);
+#endif
+
+static void sab8253x_change_speed(struct sab_port *port);
+
+static struct tty_struct **sab8253x_tableASY = 0;	/* make dynamic */
+static struct tty_struct **sab8253x_tableCUA = 0;	/* make dynamic */
+static struct tty_struct **sab8253x_tableSYN = 0;	/* make dynamic */
+static struct termios **sab8253x_termios = 0 ;
+static struct termios **sab8253x_termios_locked = 0;
+
+#ifdef MODULE
+#undef XCONFIG_SERIAL_CONSOLE	/* leaving out CONFIG_SERIAL_CONSOLE for now */
+#endif
+
+#ifdef XCONFIG_SERIAL_CONSOLE	/* not really implemented yet */
+extern int serial_console;
+struct console sab8253x_console;
+int sab8253x_console_init(void);
+#endif
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+char sab8253x_serial_version[16];
+
+static void sab8253x_flush_to_ldisc(void *private_)
+{
+	struct tty_struct *tty = (struct tty_struct *) private_;
+	unsigned char	*cp;
+	char		*fp;
+	int		count;
+	struct sab_port *port;
+	struct sk_buff *skb;  
+	
+	if(tty)
+	{
+		port = (struct sab_port *)tty->driver_data; /* probably a silly check */
+	}
+	else
+	{
+		return;
+	}
+	
+	if(!port)
+	{
+		return;
+	}
+	
+	if (test_bit(TTY_DONT_FLIP, &tty->flags)) 
+	{
+		queue_task(&tty->flip.tqueue, &tq_timer);
+		return;
+	}
+	/* note that a hangup may have occurred -- perhaps should check for that */
+	port->DoingInterrupt = 1;
+	while(port->sab8253xc_rcvbuflist && (skb_queue_len(port->sab8253xc_rcvbuflist) > 0))
+	{
+		skb = skb_dequeue(port->sab8253xc_rcvbuflist);
+		count = skb->data_len;
+		cp = skb->data;
+		fp = skb->data + (count/2);
+		(*tty->ldisc.receive_buf)(tty, cp, fp, count/2);
+		dev_kfree_skb_any(skb);
+	}
+	port->DoingInterrupt = 0;
+}
+
+/* only used asynchronously */
+static void inline sab8253x_tec_wait(struct sab_port *port)
+{
+	int count = port->tec_timeout;
+	
+	while((READB(port, star) & SAB82532_STAR_TEC) && --count)
+	{
+		udelay(1);
+	}
+}
+
+void sab8253x_start_tx(struct sab_port *port)
+{
+	unsigned long flags;
+	register int count;
+	register int total;
+	register int offset;
+	char temporary[32];
+	register unsigned int slopspace;
+	register int sendsize;
+	unsigned int totaltransmit;
+	unsigned fifospace;
+	unsigned loadedcount;
+	struct tty_struct *tty = port->tty;
+	
+	fifospace = port->xmit_fifo_size;
+	loadedcount = 0;
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();			
+	
+	
+	while(count = port->sabnext2.transmit->Count, (count & OWNER) == OWN_SAB)
+	{
+		count &= ~OWN_SAB; /* OWN_SAB is really 0 but cannot guarantee in the future */
+		
+		if(port->sabnext2.transmit->HostVaddr)
+		{
+			total = (port->sabnext2.transmit->HostVaddr->tail - 
+				 port->sabnext2.transmit->HostVaddr->data); /* packet size */
+		}
+		else
+		{
+			total = 0;		/* the data is only in the crc/trailer */
+		}
+		
+		if(tty && (tty->stopped || tty->hw_stopped))
+		{			/* works for frame that only has a trailer (crc) */
+			port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+			WRITEB(port, imr1, port->interrupt_mask1);
+			restore_flags(flags);	/* can't send */
+			return;
+		}
+		
+		offset = (total - count);	/* offset to data still to send */
+		
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
+		WRITEB(port, imr1, port->interrupt_mask1);
+		port->all_sent = 0;
+		
+		
+		if(READB(port,star) & SAB82532_STAR_XFW)
+		{
+			if(count <= fifospace)
+			{
+				port->xmit_cnt = count;
+				slopspace = 0;
+				sendsize = 0;
+				if(port->sabnext2.transmit->sendcrc) 
+				/* obviously should not happen for async but might use for
+				   priority transmission */
+				{
+					slopspace = fifospace - count;
+				}
+				if(slopspace)
+				{
+					if(count)
+					{
+						memcpy(temporary, &port->sabnext2.transmit->HostVaddr->data[offset], 
+						       count);
+					}
+					sendsize = MIN(slopspace, (4 - port->sabnext2.transmit->crcindex)); 
+				/* how many bytes to send */
+					memcpy(&temporary[count], 
+					       &((unsigned char*)(&port->sabnext2.transmit->crc))
+					       [port->sabnext2.transmit->crcindex], 
+					       sendsize);
+					port->sabnext2.transmit->crcindex += sendsize;
+					if(port->sabnext2.transmit->crcindex >= 4)
+					{
+						port->sabnext2.transmit->sendcrc = 0;
+					}
+					port->xmit_buf = temporary;
+				}
+				else
+				{
+					port->xmit_buf =	/* set up wrifefifo variables */
+						&port->sabnext2.transmit->HostVaddr->data[offset];
+				}
+				port->xmit_cnt += sendsize;
+				count = 0;
+			}
+			else
+			{
+				count -= fifospace;
+				port->xmit_cnt = fifospace;
+				port->xmit_buf =	/* set up wrifefifo variables */
+					&port->sabnext2.transmit->HostVaddr->data[offset];
+				
+			}
+			port->xmit_tail= 0;
+			loadedcount = port->xmit_cnt;
+			(*port->writefifo)(port);
+			totaltransmit = Sab8253xCountTransmitDescriptors(port);
+			if((sab8253xt_listsize - totaltransmit) > 2) 
+			{
+				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
+			}
+			
+			if((sab8253xt_listsize - totaltransmit) > (sab8253xt_listsize/2))
+			{
+				port->buffergreedy = 0;
+			}
+			else
+			{
+				port->buffergreedy = 1;
+			}
+			
+			port->xmit_buf = NULL; /* this var is used to indicate whether to call kfree */
+			
+			fifospace -= loadedcount;
+			
+			if ((count <= 0) && (port->sabnext2.transmit->sendcrc == 0))
+			{
+				port->sabnext2.transmit->Count = OWN_DRIVER;
+#ifdef FREEININTERRUPT		/* treat this routine as if taking place in interrupt */
+				if(port->sabnext2.transmit->HostVaddr)
+				{
+					skb_unlink(port->sabnext2.transmit->HostVaddr);
+					dev_kfree_skb_any(port->sabnext2.transmit->HostVaddr);
+					port->sabnext2.transmit->HostVaddr = 0; /* no skb */
+				}
+				port->sabnext2.transmit->crcindex = 0; /* no single byte */
+#endif
+				port->sabnext2.transmit = port->sabnext2.transmit->VNext;
+				if((port->sabnext2.transmit->Count & OWNER) == OWN_SAB)
+				{
+					if(fifospace > 0)
+					{
+						continue;	/* the only place where this code really loops */
+					}
+					if(fifospace < 0)
+					{
+						printk(KERN_ALERT "sab8253x:  bad math in interrupt handler.\n");
+					}
+					port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
+					WRITEB(port, imr1, port->interrupt_mask1);
+				}
+				else
+				{
+					port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+					WRITEB(port, imr1, port->interrupt_mask1);
+				}
+				sab8253x_cec_wait(port);
+				/* Issue a Transmit Frame command. */
+				WRITEB(port, cmdr, SAB82532_CMDR_XF); 
+				/* This could be optimized to load from next skbuff */
+				/* SAB82532_CMDR_XF is the same as SAB82532_CMDR_XTF */
+				restore_flags(flags);
+				return;
+			}
+			sab8253x_cec_wait(port);
+			/* Issue a Transmit Frame command. */
+			WRITEB(port, cmdr, SAB82532_CMDR_XF);	/* same as SAB82532_CMDR_XTF */
+			port->sabnext2.transmit->Count = (count|OWN_SAB);
+		}
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
+		WRITEB(port, imr1, port->interrupt_mask1);
+		restore_flags(flags);
+		return;
+	}
+	/*  The While loop only exits via return*/
+	/* we get here by skipping the loop  */
+	port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	restore_flags(flags);
+	return;
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_stop() and sab8253x_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+
+static void sab8253x_stop(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_stop"))
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();	/* maybe should turn off ALLS as well
+		   but the stop flags are checked
+		   so ALLS is probably harmless
+		   and I have seen too much evil
+		   associated with that interrupt*/
+	port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	restore_flags(flags);
+}
+
+static void sab8253x_start(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_start"))
+	{
+		return;
+	}
+	
+	sab8253x_start_tx(port);
+}
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+/* no obvious changes for sync tty */
+
+static void sab8253x_receive_chars(struct sab_port *port,
+			    union sab8253x_irq_status *stat)
+{
+	struct tty_struct *tty = port->tty;
+	unsigned char buf[32];
+	unsigned char reordered[32];
+	unsigned char status;
+	int free_fifo = 0;
+	int i, count = 0;
+	struct sk_buff *skb;
+	
+	/* Read number of BYTES (Character + Status) available. */
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
+	{
+		count = port->recv_fifo_size;
+		free_fifo++;
+	}
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_TCD) 
+	{
+		count = READB(port,rbcl) & (port->recv_fifo_size - 1);
+		free_fifo++;
+	}
+	
+	/* Issue a FIFO read command in case we where idle. */
+	if (stat->sreg.isr0 & SAB82532_ISR0_TIME) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RFRD);
+	}
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 
+	{				/* FIFO overflow */
+		free_fifo++;
+	}
+	
+	/* Read the FIFO. */
+	(*port->readfifo)(port, buf, count);
+	
+	/* Issue Receive Message Complete command. */
+	if (free_fifo) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
+	}
+	
+#ifdef CONSOLE_SUPPORT
+	if (port->is_console)
+	{
+		wake_up(&keypress_wait);
+	}
+#endif
+	if (!tty)
+	{
+		return;
+	}
+	
+	if(!count)
+	{
+		return;
+	}
+	
+	for(i = 0; i < count; i += 2)
+	{
+		reordered[i/2] = buf[i];
+		status = buf[i+1];
+		if (status & SAB82532_RSTAT_PE) 
+		{
+			status = TTY_PARITY;
+			port->icount.parity++;
+		} 
+		else if (status & SAB82532_RSTAT_FE) 
+		{
+			status = TTY_FRAME;
+			port->icount.frame++;
+		}
+		else
+		{
+			status = TTY_NORMAL;
+		}
+		reordered[(count+i)/2] = status;
+	}
+	
+	if(port->active2.receive == NULL)
+	{
+		return;
+	}
+	
+	memcpy(port->active2.receive->HostVaddr->tail, reordered, count);
+	port->active2.receive->HostVaddr->tail += count;
+	port->active2.receive->HostVaddr->data_len = count;
+	port->active2.receive->HostVaddr->len = count;
+	if(skb = dev_alloc_skb(port->recv_fifo_size), skb == NULL) /* use dev_alloc_skb because at int
+								      there is header space but so what*/
+	{
+		port->icount.buf_overrun++;
+		port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; /* clear the buffer */
+		port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+		port->active2.receive->HostVaddr->data_len = 0;
+		port->active2.receive->HostVaddr->len = 0;
+	}
+	else
+	{
+		skb_unlink(port->active2.receive->HostVaddr);
+		skb_queue_tail(port->sab8253xc_rcvbuflist, port->active2.receive->HostVaddr);
+		skb_queue_head(port->sab8253xbuflist, skb);
+		port->active2.receive->HostVaddr = skb;
+		port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+	}
+	queue_task(&tty->flip.tqueue, &tq_timer);
+}
+
+static void sab8253x_transmit_chars(struct sab_port *port,
+				    union sab8253x_irq_status *stat)
+{
+	
+	if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) /* got an all sent int? */
+	{
+		port->interrupt_mask1 |= SAB82532_IMR1_ALLS;
+		WRITEB(port, imr1, port->interrupt_mask1);
+		port->all_sent = 1;	/* not much else to do */
+	} /* a very weird chip -- this int only indicates this int */
+	
+	sab8253x_start_tx(port);
+}
+
+static void sab8253x_check_status(struct sab_port *port,
+			   union sab8253x_irq_status *stat)
+{
+	struct tty_struct *tty = port->tty;
+	int modem_change = 0;
+	mctlsig_t         *sig;
+	struct sk_buff *skb;
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	if(port->active2.receive == NULL)
+	{
+		goto check_modem;
+	}
+	
+	if (stat->images[ISR1_IDX] & SAB82532_ISR1_BRK) 
+	{
+#ifdef XCONFIG_SERIAL_CONSOLE
+		if (port->is_console) 
+		{
+			batten_down_hatches(info); /* need to add this function */
+			return;
+		}
+#endif 
+		
+		port->active2.receive->HostVaddr->tail[0] = 0;
+		port->active2.receive->HostVaddr->tail[1] = TTY_PARITY;
+		port->active2.receive->HostVaddr->tail += 2;
+		port->active2.receive->HostVaddr->data_len = 2;
+		port->active2.receive->HostVaddr->len = 2;
+		
+		if(skb = dev_alloc_skb(port->recv_fifo_size), skb == NULL)
+		{
+			port->icount.buf_overrun++;
+			port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; 
+				/* clear the buffer */
+			port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+			port->active2.receive->HostVaddr->data_len = 0;
+			port->active2.receive->HostVaddr->len = 0;
+		}
+		else
+		{
+			skb_unlink(port->active2.receive->HostVaddr);
+			skb_queue_tail(port->sab8253xc_rcvbuflist, port->active2.receive->HostVaddr);
+			skb_queue_head(port->sab8253xbuflist, skb);
+			port->active2.receive->HostVaddr = skb;
+			port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+		}
+		queue_task(&tty->flip.tqueue, &tq_timer);
+		port->icount.brk++;
+	}
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 
+	{
+		port->active2.receive->HostVaddr->tail[0] = 0;
+		port->active2.receive->HostVaddr->tail[1] = TTY_PARITY;
+		port->active2.receive->HostVaddr->tail += 2;
+		port->active2.receive->HostVaddr->data_len = 2;
+		port->active2.receive->HostVaddr->len = 2;
+		if(skb = dev_alloc_skb(port->recv_fifo_size), skb == NULL)
+		{
+			port->icount.buf_overrun++;
+			port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; 
+				/* clear the buffer */
+			port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+			port->active2.receive->HostVaddr->data_len = 0;
+			port->active2.receive->HostVaddr->len = 0;
+		}
+		else
+		{
+			skb_unlink(port->active2.receive->HostVaddr);
+			skb_queue_tail(port->sab8253xc_rcvbuflist, port->active2.receive->HostVaddr);
+			skb_queue_head(port->sab8253xbuflist, skb);
+			port->active2.receive->HostVaddr = skb;
+			port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+		}
+		queue_task(&tty->flip.tqueue, &tq_timer);
+		port->icount.overrun++;
+	}
+	
+ check_modem:
+	/* Checking DCD */
+	sig = &port->dcd;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dcd);
+		port->icount.dcd++;
+		modem_change++;
+	}
+	/* Checking CTS */
+	sig = &port->cts;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,cts);
+		port->icount.cts++;
+		modem_change++;
+	}
+	/* Checking DSR */
+	sig = &port->dsr;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dsr);
+		port->icount.dsr++;
+		modem_change++;
+	}
+	if (modem_change)
+	{
+		wake_up_interruptible(&port->delta_msr_wait); /* incase kernel proc level was waiting on modem change */
+	}
+	
+	sig = &port->dcd;
+	if ((port->flags & FLAG8253X_CHECK_CD) &&
+	    (stat->images[sig->irq] & sig->irqmask)) 
+	{
+		
+		if (sig->val)
+		{
+			wake_up_interruptible(&port->open_wait); /* in case waiting in block_til_ready */
+		}
+		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+			   (port->flags & FLAG8253X_CALLOUT_NOHUP))) 
+		{
+			
+			MOD_INC_USE_COUNT;	/* in case a close is already in progress
+						   don't want structures to vanish during
+						   late processing of hangup */
+			if (schedule_task(&port->tqueue_hangup) == 0)
+			{
+				MOD_DEC_USE_COUNT; /* task schedule failed */
+			}
+		}
+	}
+	
+	sig = &port->cts;
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{
+		if (port->tty->hw_stopped) 
+		{
+			if (sig->val) 
+			{
+				
+				port->tty->hw_stopped = 0;
+				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
+				sab8253x_start_tx(port);
+			}
+		} 
+		else 
+		{
+			if (!(sig->val)) 
+			{
+				port->tty->hw_stopped = 1;
+			}
+		}
+	}
+}
+
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * sab8253x_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using sab8253x_sched_event(), and they get done here.
+ */
+				/* The following routine is installed */
+				/* in the bottom half -- just search */
+				/* for the init_bh() call */
+				/* The logic: sab8253x_sched_event() */
+				/* enqueues the tqueue port entry on */
+				/* the tq_8253x_serial task list -- */
+				/* whenever the bottom half is run */
+				/* sab8253x_do_softint is invoked for */
+				/* every port that has invoked the bottom */
+				/* half via sab8253x_sched_event(). */
+				/* currently only a write wakeevent */
+				/* wakeup is scheduled -- to tell the */
+				/* tty driver to send more chars */
+				/* down to the serial driver.*/
+
+static void sab8253x_do_serial_bh(void)
+{
+	run_task_queue(&tq_8253x_serial);
+}
+
+				/* I believe the reason for the */
+				/* bottom half processing below is */
+				/* the length of time needed to transfer */
+				/* characters to the TTY driver. */
+
+static void sab8253x_do_softint(void *private_)
+{
+	struct sab_port	*port = (struct sab_port *)private_;
+	struct tty_struct *tty;
+	
+	tty = port->tty;
+	if (!tty)
+	{
+		return;
+	}
+	
+	port->DoingInterrupt = 1;
+	if (test_and_clear_bit(SAB8253X_EVENT_WRITE_WAKEUP, &port->event)) 
+	{
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait); /* in case tty driver waiting on write */
+	}
+	port->DoingInterrupt = 0;
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> sab8253x_hangup()
+ * 
+ */
+/* This logic takes place at kernel */
+/* process context through the scheduler*/
+/* schedule_task(tqueue_hangup) */
+/* takes place in the interrupt handler*/
+static void sab8253x_do_serial_hangup(void *private_)
+{
+	struct sab_port *port = (struct sab_port *) private_;
+	struct tty_struct *tty;
+	
+	tty = port->tty;
+	if (tty)
+	{
+		tty_hangup(tty);
+	}
+	MOD_DEC_USE_COUNT;		/* in case busy waiting to unload module */
+}
+
+static void
+sab8253x_init_line(struct sab_port *port)
+{
+	unsigned char stat;
+
+	if(port->chip->c_cim)
+	{
+		if(port->chip->c_cim->ci_type == CIM_SP502)
+		{
+			aura_sp502_program(port, SP502_OFF_MODE);
+		}
+	}
+	
+	/*
+	 * Wait for any commands or immediate characters
+	 */
+	sab8253x_cec_wait(port);
+	sab8253x_tec_wait(port);
+	
+	/*
+	 * Clear the FIFO buffers.
+	 */
+	
+	WRITEB(port, cmdr, SAB82532_CMDR_RRES);
+	sab8253x_cec_wait(port);
+	WRITEB(port, cmdr, SAB82532_CMDR_XRES);
+	
+	
+	/*
+	 * Clear the interrupt registers.
+	 */
+	stat = READB(port, isr0);
+	stat = READB(port, isr1);
+	
+	/*
+	 * Now, initialize the UART 
+	 */
+	WRITEB(port, ccr0, 0);	  /* power-down */
+	WRITEB(port, ccr0,
+	       SAB82532_CCR0_MCE | SAB82532_CCR0_SC_NRZ | SAB82532_CCR0_SM_ASYNC);
+	WRITEB(port, ccr1,
+	       SAB82532_CCR1_ODS | SAB82532_CCR1_BCR | 7);
+	WRITEB(port, ccr2,
+	       SAB82532_CCR2_BDF | SAB82532_CCR2_SSEL | SAB82532_CCR2_TOE);
+	WRITEB(port, ccr3, 0);
+	WRITEB(port, ccr4,
+	       SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG);
+	WRITEB(port, mode,
+	       SAB82532_MODE_RTS | SAB82532_MODE_FCTS | SAB82532_MODE_RAC);
+	WRITEB(port, rfc,
+	       SAB82532_RFC_DPS | SAB82532_RFC_RFDF);
+	switch (port->recv_fifo_size) 
+	{
+	case 1:
+		SET_REG_BIT(port,rfc,SAB82532_RFC_RFTH_1);
+		break;
+	case 4:
+		SET_REG_BIT(port,rfc,SAB82532_RFC_RFTH_4);
+		break;
+	case 16:
+		SET_REG_BIT(port,rfc,SAB82532_RFC_RFTH_16);
+		break;
+	default:
+		port->recv_fifo_size = 32;
+	case 32:
+		SET_REG_BIT(port,rfc,SAB82532_RFC_RFTH_32);
+		break;
+	}
+	/* power-up */
+	SET_REG_BIT(port, ccr0, SAB82532_CCR0_PU);
+	if(port->chip->c_cim)
+	{
+		if(port->chip->c_cim->ci_type == CIM_SP502)
+		{
+			aura_sp502_program(port, port->sigmode);
+		}
+	}
+}
+
+
+static int sab8253x_startup(struct sab_port *port)
+{
+	unsigned long flags;
+	
+	int retval = 0;
+	
+	save_flags(flags); cli();
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		goto errout;
+	}
+	
+	port->msgbufindex = 0;
+	port->xmit_buf = NULL;
+	port->buffergreedy = 0;
+	
+	if (!port->regs) 
+	{
+		if (port->tty)
+		{
+			set_bit(TTY_IO_ERROR, &port->tty->flags);
+		}
+		retval = -ENODEV;
+		goto errout;
+	}
+	
+	/*
+	 * Initialize the Hardware
+	 */
+	sab8253x_init_line(port);
+	
+	if (port->tty->termios->c_cflag & CBAUD) 
+	{
+		/* Activate RTS */
+		RAISE(port,rts);
+		
+		/* Activate DTR */
+		RAISE(port,dtr);
+	}
+	
+	/*
+	 * Initialize the modem signals values
+	 */
+	port->dcd.val=ISON(port,dcd);
+	port->cts.val=ISON(port,cts);
+	port->dsr.val=ISON(port,dsr);
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	
+	port->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+		SAB82532_IMR0_PLLA;
+	WRITEB(port, imr0, port->interrupt_mask0);
+	port->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_XOFF |
+		SAB82532_IMR1_TIN | SAB82532_IMR1_XON |
+		SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	port->all_sent = 1;
+	
+	if (port->tty)
+	{
+		clear_bit(TTY_IO_ERROR, &port->tty->flags);
+	}
+	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	sab8253x_change_speed(port);
+	
+	port->flags |= FLAG8253X_INITIALIZED;
+	port->receive_chars = sab8253x_receive_chars;
+	port->transmit_chars = sab8253x_transmit_chars;
+	port->check_status = sab8253x_check_status;
+	port->receive_test = (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
+			      SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR);
+	port->check_status_test = SAB82532_ISR1_BRK;
+	
+	restore_flags(flags);
+	return 0;
+	
+ errout:
+	restore_flags(flags);
+	return retval;
+}
+
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void sab8253x_shutdown(struct sab_port *port)
+{
+	unsigned long flags;
+	
+	if (!(port->flags & FLAG8253X_INITIALIZED))
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli(); /* Disable interrupts */
+	
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&port->delta_msr_wait);	/* shutting down port modem status is pointless */
+	
+	if (port->xmit_buf) 
+	{
+		port->xmit_buf = NULL;
+	}
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (port->is_console) 
+	{
+		port->interrupt_mask0 = 
+			SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+			/*SAB82532_IMR0_TIME |*/
+			SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;
+		WRITEB(port,imr0,port->interrupt_mask0);
+		port->interrupt_mask1 = 
+			SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+			SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+			SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+			SAB82532_IMR1_XPR;
+		WRITEB(port,imr1,port->interrupt_mask1);
+		if (port->tty)
+		{
+			set_bit(TTY_IO_ERROR, &port->tty->flags);
+		}
+		port->flags &= ~FLAG8253X_INITIALIZED;
+		restore_flags(flags);
+		return;
+	}
+#endif
+	
+	/* Disable Interrupts */
+	
+	port->interrupt_mask0 = 0xff;
+	WRITEB(port, imr0, port->interrupt_mask0);
+	port->interrupt_mask1 = 0xff;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	
+	if (!port->tty || (port->tty->termios->c_cflag & HUPCL)) 
+	{
+		LOWER(port,rts);
+		LOWER(port,dtr);
+	}
+	
+	/* Disable break condition */
+	CLEAR_REG_BIT(port,dafo,SAB82532_DAFO_XBRK);
+	
+	/* Disable Receiver */	
+	CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC);
+	
+	/* Power Down */	
+	CLEAR_REG_BIT(port,ccr0,SAB82532_CCR0_PU);
+	
+	if (port->tty)
+	{
+		set_bit(TTY_IO_ERROR, &port->tty->flags);
+	}
+	
+	port->flags &= ~FLAG8253X_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void sab8253x_change_speed(struct sab_port *port)
+{
+	unsigned long	flags,baud;
+	tcflag_t	cflag;
+	u8	        dafo,ccr2=0,ccr4=0,ebrg=0,mode;
+	int		i, bits;
+#ifdef DEBUGGING
+	printk("Change speed!  ");
+#endif
+	if (!port->tty || !port->tty->termios) 
+	{
+#ifdef DEBUGGING
+		printk("NOT!\n");
+#endif
+		return;
+	}
+	
+#ifdef DEBUGGING
+	printk(" for real.\n");
+#endif
+	
+	cflag = port->tty->termios->c_cflag;
+	
+	/* Byte size and parity */
+	switch (cflag & CSIZE) 
+	{
+	case CS5: 
+		dafo = SAB82532_DAFO_CHL5; 
+		bits = 7; 
+		break;
+	case CS6: 
+		dafo = SAB82532_DAFO_CHL6; 
+		bits = 8; 
+		break;
+	case CS7: 
+		dafo = SAB82532_DAFO_CHL7; 
+		bits = 9; 
+		break;
+	default:
+	case CS8: 
+		dafo = SAB82532_DAFO_CHL8; 
+		bits = 10; 
+		break;
+	}
+	
+	if (cflag & CSTOPB) 
+	{
+		dafo |= SAB82532_DAFO_STOP;
+		bits++;
+	}
+	
+	if (cflag & PARENB) 
+	{
+		dafo |= SAB82532_DAFO_PARE;
+		bits++;
+	}
+	
+	if (cflag & PARODD) 
+	{
+#ifdef CMSPAR
+		if (cflag & CMSPAR)
+			dafo |= SAB82532_DAFO_PAR_MARK;
+		else
+#endif
+			dafo |= SAB82532_DAFO_PAR_ODD;
+	} 
+	else 
+	{
+#ifdef CMSPAR
+		if (cflag & CMSPAR)
+			dafo |= SAB82532_DAFO_PAR_SPACE;
+		else
+#endif
+			dafo |= SAB82532_DAFO_PAR_EVEN;
+	}
+	
+	/* Determine EBRG values based on the "encoded"baud rate */
+	i = cflag & CBAUD;
+	switch(i)
+	{
+	case B0:
+		baud=0;
+		break;
+	case  B50:
+		baud=100;
+		break;
+	case  B75:
+		baud=150;
+		break;
+	case  B110:
+		baud=220;
+		break;
+	case  B134:
+		baud=269;
+		break;
+	case  B150:
+		baud=300;
+		break;
+	case  B200:
+		baud=400;
+		break;
+	case B300:
+		baud=600;
+		break;
+	case B600:
+		baud=1200;
+		break;
+	case B1200:
+		baud=2400;
+		break;
+	case B1800:
+		baud=3600;
+		break;
+	case B2400:
+		baud=4800;
+		break;
+	case B4800:
+		baud=9600;
+		break;
+	case B9600:
+		baud=19200;
+		break;
+	case B19200:
+		baud=38400;
+		break;
+	case  B38400:
+		if(port->custspeed)
+		{
+			baud=port->custspeed<<1;
+		}
+		else
+		{
+			baud=76800;
+		}
+		break;
+	case B57600:
+		baud=115200;
+		break;
+#ifdef SKIPTHIS
+	case B76800:
+		baud=153600;
+		break;
+	case B153600:
+		baud=307200;
+		break;
+#endif
+	case B230400:
+		baud=460800;
+		break;
+	case  B460800:
+		baud=921600;
+		break;
+	case B115200:
+	default:
+		baud=230400;
+		break;
+	}
+	
+	if(!sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud))) 
+	{
+		printk("Aurora Warning. baudrate %ld could not be set! Using 115200",baud);
+		baud=230400;
+		sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud));
+	}
+	
+	if (port->baud)
+		port->timeout = (port->xmit_fifo_size * HZ * bits) / port->baud;
+	else
+		port->timeout = 0;
+	port->timeout += HZ / 50;		/* Add .02 seconds of slop */
+	
+	/* CTS flow control flags */
+	if (cflag & CRTSCTS)
+		port->flags |= FLAG8253X_CTS_FLOW;
+	else
+		port->flags &= ~(FLAG8253X_CTS_FLOW);
+	
+	if (cflag & CLOCAL)
+		port->flags &= ~(FLAG8253X_CHECK_CD);
+	else
+		port->flags |= FLAG8253X_CHECK_CD;
+	if (port->tty)
+		port->tty->hw_stopped = 0;
+	
+	/*
+	 * Set up parity check flag
+	 * XXX: not implemented, yet.
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+	
+	/*
+	 * Characters to ignore
+	 * XXX: not implemented, yet.
+	 */
+	
+	/*
+	 * !!! ignore all characters if CREAD is not set
+	 * XXX: not implemented, yet.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= SAB82532_ISR0_RPF |
+			/* SAB82532_ISR0_TIME |*/
+			SAB82532_ISR0_TCD ;
+	
+	save_flags(flags); 
+	cli();
+	sab8253x_cec_wait(port);
+	sab8253x_tec_wait(port);
+	WRITEB(port,dafo,dafo);
+	WRITEB(port,bgr,ebrg);
+	ccr2 |= READB(port,ccr2) & ~(0xc0);
+	WRITEB(port,ccr2,ccr2);
+	ccr4 |= READB(port,ccr4) & ~(SAB82532_CCR4_EBRG);
+	WRITEB(port,ccr4,ccr4);
+	
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{
+		mode = READB(port,mode) & ~(SAB82532_MODE_RTS);
+		mode |= SAB82532_MODE_FRTS;
+		mode  &= ~(SAB82532_MODE_FCTS);
+	} 
+	else 
+	{
+		mode = READB(port,mode) & ~(SAB82532_MODE_FRTS);
+		mode |= SAB82532_MODE_RTS;
+		mode |= SAB82532_MODE_FCTS;
+	}
+	WRITEB(port,mode,mode);
+	mode |= SAB82532_MODE_RAC;
+	WRITEB(port,mode,mode);
+	restore_flags(flags);
+}
+
+static void sab8253x_flush_chars(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_flush_chars"))
+	{
+		return;
+	}
+	
+	if ((Sab8253xCountTransmit(port) <= 0) || tty->stopped || tty->hw_stopped)
+	{
+		return;
+	}
+	
+	sab8253x_start_tx(port);
+}
+
+static int sab8253x_write(struct tty_struct * tty, int from_user,
+		   const unsigned char *buf, int count)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	struct sk_buff *skb = NULL;
+	int truelength = 0;
+	int do_queue = 1;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_write"))
+	{
+		return 0;
+	}
+	
+	if(count == 0)
+	{
+		return 0;
+	}
+	
+	if(port->active2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	if((port->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		sab8253x_start_tx(port);
+		return 0;
+	}
+	
+#ifndef FREEININTERRUPT
+	skb = port->active2.transmit->HostVaddr; /* current slot value */
+	
+	if(port->buffergreedy == 0)	/* are we avoiding buffer free's */
+	{				/* no */
+		if((skb != NULL) || /* not OWN_SAB from above */
+		   (port->active2.transmit->crcindex != 0)) 
+		{
+			register RING_DESCRIPTOR *freeme;
+			
+			freeme = port->active2.transmit;
+			do
+			{
+				if((freeme->crcindex == 0) && (freeme->HostVaddr == NULL))
+				{
+					break;
+				}
+				if(freeme->HostVaddr)
+				{
+					skb_unlink((struct sk_buff*)freeme->HostVaddr);
+					dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+					freeme->HostVaddr = NULL;
+				}
+				freeme->sendcrc = 0;
+				freeme->crcindex = 0;
+				freeme = (RING_DESCRIPTOR*) freeme->VNext;
+			}
+			while((freeme->Count & OWNER) != OWN_SAB);
+		}
+		skb = NULL;		/* buffer was freed */
+	}
+	
+	if(skb != NULL)		/* potentially useful */
+	{
+		truelength = (skb->end - skb->head);
+		if(truelength >= count)
+		{
+			skb->data = skb->head; /* this buffer is already queued */
+			skb->tail = skb->head;
+			do_queue = 0;
+		}
+		else
+		{
+			skb_unlink(skb);
+			dev_kfree_skb_any(skb);
+			skb = NULL;
+			port->active2.transmit->HostVaddr = NULL;
+		}
+	}
+	/* in all cases the following is allowed */
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+#endif
+	
+	if(skb == NULL)
+	{
+		if(port->DoingInterrupt)
+		{
+			skb = alloc_skb(count, GFP_ATOMIC);
+		}
+		else
+		{
+			skb = alloc_skb(count, GFP_KERNEL);
+		}
+	}
+	
+	if(skb == NULL)
+	{
+		printk(KERN_ALERT "sab8253xt: no skbuffs available.\n");
+		return 0;
+	}
+	if(from_user)
+	{
+		copy_from_user(skb->data, buf, count);
+	}
+	else
+	{
+		memcpy(skb->data, buf, count);
+	}
+	skb->tail = (skb->data + count);
+	skb->data_len = count;
+	skb->len = count;
+	
+	if(do_queue)
+	{
+		skb_queue_head(port->sab8253xbuflist, skb);
+	}
+	
+	port->active2.transmit->HostVaddr = skb;
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+	port->active2.transmit->Count = (OWN_SAB|count);
+	port->active2.transmit = port->active2.transmit->VNext;
+	
+	sab8253x_start_tx(port);
+	return count;
+}
+
+static int sab8253x_write_room(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if(sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_write_room"))
+	{
+		return 0;
+	}
+	
+	if(port->active2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	if((port->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		return 0;
+	}
+	return ((sab8253xt_rbufsize) * /* really should not send buffs bigger than 32 I guess */
+		(sab8253xt_listsize - 
+		 Sab8253xCountTransmitDescriptors(port)));
+}
+
+static int sab8253x_chars_in_buffer(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_chars_in_bufferS"))
+	{
+		return 0;
+	}
+	
+	return Sab8253xCountTransmit(port);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void sab8253x_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_send_xchar"))
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();
+	sab8253x_tec_wait(port);
+	WRITEB(port, tic, ch);
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void sab8253x_throttle(struct tty_struct * tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_throttle"))
+	{
+		return;
+	}
+	
+	if (I_IXOFF(tty))
+	{
+		sab8253x_send_xchar(tty, STOP_CHAR(tty));
+	}
+}
+
+static void sab8253x_unthrottle(struct tty_struct * tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_unthrottle"))
+	{
+		return;
+	}
+	
+	if (I_IXOFF(tty)) 
+	{
+		if (port->x_char)
+		{
+			port->x_char = 0;
+		}
+		else
+		{
+			sab8253x_send_xchar(tty, START_CHAR(tty));
+		}
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int sab8253x_get_serial_info(struct sab_port *port,
+			     struct serial_struct *retinfo)
+{
+	struct serial_struct tmp;
+	
+	if (!retinfo)
+	{
+		return -EFAULT;
+	}
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = port->type;
+	tmp.line = port->line;
+	tmp.port = (unsigned long)port->regs;
+	tmp.irq = port->irq;
+	tmp.flags = port->flags;
+	tmp.xmit_fifo_size = port->xmit_fifo_size;
+	tmp.baud_base = 0;
+	tmp.close_delay = port->close_delay;
+	tmp.closing_wait = port->closing_wait;
+	tmp.custom_divisor = port->custom_divisor;
+	tmp.hub6 = 0;
+	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+	{
+		return -EFAULT;
+	}
+	return 0;
+}
+
+static int sab8253x_set_serial_info(struct sab_port *port,
+			     struct serial_struct *new_info)
+{
+	return 0;
+}
+
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int sab8253x_get_lsr_info(struct sab_port * port, unsigned int *value)
+{
+	unsigned int result;
+	
+	result = (((Sab8253xCountTransmit(port) <= 0) && port->all_sent) ? TIOCSER_TEMT : 0);
+	return put_user(result, value);
+}
+
+
+static int sab8253x_get_modem_info(struct sab_port * port, unsigned int *value)
+{
+	unsigned int result;
+	
+	/* Using the cached values !! After all when changed int occurs
+	   and the cache is updated */
+	result=  
+		((port->dtr.val) ? TIOCM_DTR : 0)
+		| ((port->rts.val) ? TIOCM_RTS : 0)
+		| ((port->cts.val) ? TIOCM_CTS : 0)
+		| ((port->dsr.val) ? TIOCM_DSR : 0)
+		| ((port->dcd.val) ? TIOCM_CAR : 0);
+	
+	return put_user(result,value);
+}
+
+static int sab8253x_set_modem_info(struct sab_port * port, unsigned int cmd,
+				   unsigned int *value)
+{
+	int error;
+	unsigned int arg;
+	unsigned long flags;
+	
+	error = get_user(arg, value);
+	if (error)
+	{
+		return error;
+	}
+	
+	save_flags(flags);
+	cli();
+	switch (cmd) 
+	{
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS) 
+		{
+			RAISE(port, rts);
+		}
+		if (arg & TIOCM_DTR) 
+		{
+			RAISE(port, dtr);
+		}
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS) 
+		{
+			LOWER(port,rts);
+		}
+		if (arg & TIOCM_DTR) 
+		{
+			LOWER(port,dtr);
+		}
+		break;
+	case TIOCMSET:
+		if (arg & TIOCM_RTS) 
+		{
+			RAISE(port, rts);
+		} 
+		else 
+		{
+			LOWER(port,rts);
+		}
+		if (arg & TIOCM_DTR) 
+		{
+			RAISE(port, dtr);
+		} 
+		else 
+		{
+			LOWER(port,dtr);
+		}
+		break;
+	default:
+		restore_flags(flags);
+		return -EINVAL;
+	}
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void sab8253x_break(struct tty_struct *tty, int break_state)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_break"))
+	{
+		return;
+	}
+	
+	if (!port->regs)
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();
+	if (break_state == -1) 
+	{
+		SET_REG_BIT(port,dafo,SAB82532_DAFO_XBRK);
+	} 
+	else 
+	{
+		CLEAR_REG_BIT(port,dafo,SAB82532_DAFO_XBRK);
+	}
+	restore_flags(flags);
+}
+
+static int sab8253x_ioctl(struct tty_struct *tty, struct file * file,
+			  unsigned int cmd, unsigned long arg)
+{
+	int error;
+	unsigned int wordindex;
+	unsigned short *wordptr;
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	struct async_icount cprev, cnow;	/* kernel counter temps */
+	struct serial_icounter_struct *p_cuser;	/* user space */
+	SAB_BOARD *bptr;
+	unsigned long flags;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_ioctl"))
+	{
+		return -ENODEV;
+	}
+	
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) 
+	{
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		{
+			return -EIO;
+		}
+	}
+	
+	switch (cmd) 
+	{
+	case ATIS_IOCSPARAMS:
+		copy_from_user(&port->ccontrol, (struct channelcontrol*)arg , sizeof(struct channelcontrol));
+		break;
+	case ATIS_IOCGPARAMS:
+		copy_to_user((struct channelcontrol*) arg, &port->ccontrol, sizeof(struct channelcontrol));
+		break;
+		
+	case ATIS_IOCSSPEED:
+		copy_from_user(&port->custspeed, (unsigned long*)arg , sizeof(unsigned long));
+		break;
+	case ATIS_IOCGSPEED:
+		copy_to_user((unsigned long*) arg, &port->custspeed, sizeof(unsigned long));
+		break;
+		
+	case ATIS_IOCSSEP9050:
+		bptr = port->board;
+		if(bptr->b_type == BD_WANMCS)
+		{
+			return -EINVAL;
+		}
+		copy_from_user((unsigned char*) bptr->b_eprom, (unsigned char*) arg , sizeof(struct sep9050));
+		
+		wordptr = (unsigned short*) bptr->b_eprom;
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		for(wordindex = 0; wordindex < EPROM9050_SIZE; ++wordindex)
+		{
+			plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+					  NM93_WRITECMD, 
+					  wordindex, wordptr[wordindex]);
+		}
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+		break;
+	case ATIS_IOCGSEP9050:
+		bptr = port->board;
+		if(bptr->b_type == BD_WANMCS)
+		{
+			return -EINVAL;
+		}
+		if (!plx9050_eprom_read(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+					(unsigned short*) bptr->b_eprom,
+					(unsigned char) 0, EPROM9050_SIZE))
+		{
+			printk(KERN_ALERT "auraXX20n: Could not read serial eprom.\n");
+			return -EIO;
+		}
+		copy_to_user((unsigned char*) arg, (unsigned char*) bptr->b_eprom, sizeof(struct sep9050));
+		break;
+		
+	case TIOCGSOFTCAR:
+		return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
+		
+	case TIOCSSOFTCAR:
+		error = get_user(arg, (unsigned int *) arg);
+		if (error)
+		{
+			return error;
+		}
+		tty->termios->c_cflag =
+			((tty->termios->c_cflag & ~CLOCAL) |
+			 (arg ? CLOCAL : 0));
+		return 0;
+	case TIOCMGET:
+		return sab8253x_get_modem_info(port, (unsigned int *) arg);
+	case TIOCMBIS:
+	case TIOCMBIC:
+	case TIOCMSET:
+		return sab8253x_set_modem_info(port, cmd, (unsigned int *) arg);
+	case TIOCGSERIAL:
+		return sab8253x_get_serial_info(port,
+						(struct serial_struct *) arg);
+	case TIOCSSERIAL:
+		return sab8253x_set_serial_info(port,
+						(struct serial_struct *) arg);
+		
+	case TIOCSERGETLSR: /* Get line status register */
+		return sab8253x_get_lsr_info(port, (unsigned int *) arg);
+		
+	case TIOCSERGSTRUCT:
+		if (copy_to_user((struct sab_port *) arg,
+				 port, sizeof(struct sab_port)))
+			return -EFAULT;
+		return 0;
+		
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+	case TIOCMIWAIT:
+		save_flags(flags);
+		cli();
+		/* note the counters on entry */
+		cprev = port->icount;
+		restore_flags(flags);
+		while (1) 
+		{
+			interruptible_sleep_on(&port->delta_msr_wait); /* waits for a modem signal change */
+			/* see if a signal did it */
+			if (signal_pending(current))
+			{
+				return -ERESTARTSYS;
+			}
+			save_flags(flags);
+			cli();
+			cnow = port->icount; /* atomic copy */
+			restore_flags(flags);
+			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+			{
+				return -EIO; /* no change => error */
+			}
+			if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+			     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+			     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+			     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+				{
+					return 0;
+				}
+			}
+			cprev = cnow;
+		}
+		/* NOTREACHED */
+		break;
+		
+		/* 
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+	case TIOCGICOUNT:
+		save_flags(flags);
+		cli();
+		cnow = port->icount;
+		restore_flags(flags);
+		p_cuser = (struct serial_icounter_struct *) arg;
+		error = put_user(cnow.cts, &p_cuser->cts);
+		if (error) 
+		{
+			return error;
+		}
+		error = put_user(cnow.dsr, &p_cuser->dsr);
+		if (error) 
+		{
+			return error;
+		}
+		error = put_user(cnow.rng, &p_cuser->rng);
+		if (error) 
+		{
+			return error;
+		}
+		error = put_user(cnow.dcd, &p_cuser->dcd);
+		if (error) 
+		{
+			return error;
+		}
+		return 0;
+		
+	case ATIS_IOCSSIGMODE:
+		if(port->chip->c_cim)
+		{
+			if(port->chip->c_cim->ci_type == CIM_SP502)
+			{
+				copy_from_user(&port->sigmode, (unsigned int*)arg , sizeof(unsigned int));
+				return 0;
+			}
+		}
+		return -EINVAL;
+
+	case ATIS_IOCGSIGMODE:
+		if(port->chip->c_cim)
+		{
+			if(port->chip->c_cim->ci_type == CIM_SP502)
+			{
+				copy_to_user((unsigned int*) arg, &port->sigmode, sizeof(unsigned int));
+				return 0;
+			}
+		}
+		return -EINVAL;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void sab8253x_set_termios(struct tty_struct *tty,
+				 struct termios *old_termios)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if((tty->termios->c_cflag == old_termios->c_cflag) && 
+	   (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag)))
+	{
+		return;
+	}
+	if(!port)
+	{
+		return;
+	}
+	sab8253x_change_speed(port);
+	
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(tty->termios->c_cflag & CBAUD)) 
+	{
+		LOWER(port,rts);
+		LOWER(port,dtr);
+	}
+	
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (tty->termios->c_cflag & CBAUD)) 
+	{
+		RAISE(port, dtr);
+		if (!tty->hw_stopped ||
+		    !(tty->termios->c_cflag & CRTSCTS)) 
+		{
+			RAISE(port, rts);
+		}
+	}
+	
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) 
+	{
+		tty->hw_stopped = 0;
+		sab8253x_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void sab8253x_close(struct tty_struct *tty, struct file * filp)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	MOD_DEC_USE_COUNT;	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_close"))
+	{
+		return;
+	}
+	if(port->open_type == OPEN_SYNC_NET)
+	{				/* port->tty field should already be NULL */
+		/* port count was not incremented */
+		return;
+	}
+	
+	--(port->count);		/* have a valid port */
+	if (tty_hung_up_p(filp)) 
+	{
+		
+		if(port->count == 0)	/* shutdown took place in hangup context */
+		{
+			port->open_type = OPEN_NOT;
+		}
+		else if(port->count < 0)
+		{
+			printk(KERN_ALERT "XX20: port->count went negative.\n");
+			port->count = 0;
+			port->open_type = OPEN_NOT;
+		}
+		return;
+	}
+	
+	if (port->count < 0) 
+	{
+		printk(KERN_ALERT "sab8253x_close: bad serial port count for ttys%d: %d\n",
+		       port->line, port->count);
+		port->count = 0;
+	}
+	
+	if (port->count) 
+	{
+		return;
+	}
+	
+	port->flags |= FLAG8253X_CLOSING;
+	
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (port->flags & FLAG8253X_NORMAL_ACTIVE)
+	{
+		port->normal_termios = *tty->termios;
+	}
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE)
+	{
+		port->callout_termios = *tty->termios;
+	}
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (port->closing_wait != SAB8253X_CLOSING_WAIT_NONE) 
+	{
+		tty_wait_until_sent(tty, port->closing_wait); /* wait for drain */
+	}
+	
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and turn off
+	 * the receiver.
+	 */
+	
+	save_flags(flags); 
+	cli();
+	port->interrupt_mask0 |= SAB82532_IMR0_TCD;
+	WRITEB(port,imr0,port->interrupt_mask0);
+	
+	CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC); /* ??????? */
+	restore_flags(flags);
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		sab8253x_wait_until_sent(tty, port->timeout);
+	}
+	sab8253x_shutdown(port);	/* no more ints on port */
+	Sab8253xCleanUpTransceiveN(port); /* should be okay */
+	if (tty->driver.flush_buffer)
+	{
+		tty->driver.flush_buffer(tty);
+	}
+	if (tty->ldisc.flush_buffer)
+	{
+		tty->ldisc.flush_buffer(tty);
+	}
+	tty->closing = 0;
+	port->event = 0;
+	port->tty = 0;
+	if (port->blocked_open) 
+	{
+		if (port->close_delay) 
+		{
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(port->close_delay);
+		}
+		wake_up_interruptible(&port->open_wait); /* deal with open blocks */
+	}
+	
+	if((port->flags & (FLAG8253X_CALLOUT_ACTIVE | FLAG8253X_NETWORK)) ==
+	   (FLAG8253X_CALLOUT_ACTIVE | FLAG8253X_NETWORK) &&
+	   port->dev)
+	{
+		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE|
+				 FLAG8253X_CLOSING); /* leave network set */
+		netif_carrier_off(port->dev);
+		port->open_type = OPEN_SYNC_NET;
+		sab8253x_startupN(port);
+	}
+	else
+	{
+		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE|
+				 FLAG8253X_CLOSING);
+		wake_up_interruptible(&port->close_wait);
+		port->open_type = OPEN_NOT;
+	}
+}
+
+/*
+ * sab8253x_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void sab8253x_hangup(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_hangup"))
+	{
+		return;
+	}
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (port->is_console)
+	{
+		return;
+	}
+#endif
+	
+	sab8253x_flush_buffer(tty);
+	if(port)
+	{
+		sab8253x_shutdown(port);
+		Sab8253xCleanUpTransceiveN(port); /* this logic is a bit contorted
+						     Are we cleaning up the lists
+						     because we are waking up a
+						     blocked open?  There is possibly
+						     an order problem here perhaps the
+						     open count should have increased in the
+						     int handler so that it could decrease here*/
+		port->event = 0;
+		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE);
+		port->tty = 0;
+		wake_up_interruptible(&port->open_wait); /* deal with blocking open */
+	}
+}
+/*
+ * ------------------------------------------------------------
+ * sab8253x_open() and friends
+ * ------------------------------------------------------------
+ */
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+
+static int sab8253x_open(struct tty_struct *tty, struct file * filp)
+{
+	struct sab_port	*port;
+	int retval, line;
+	int counter;
+	unsigned long flags;
+	
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	
+	for(counter = 0, port = AuraPortRoot; 
+	    (counter < line) && (port != NULL); 
+	    ++counter)
+	{
+		port = port->next;
+	}
+	
+	if (!port) 
+	{
+		printk(KERN_ALERT "sab8253x_open: can't find structure for line %d\n",
+		       line);
+		return -ENODEV;
+	}
+	
+	save_flags(flags);		/* Need to protect the port->tty field */
+	cli();
+	
+	if(port->tty == NULL)
+	{
+		port->tty = tty;		/* may be a standard tty waiting on a call out device */
+		tty->flip.tqueue.routine = sab8253x_flush_to_ldisc;
+	}
+	
+	tty->driver_data = port;	/* but the tty devices are unique for each type of open */
+	
+	if(port->function == FUNCTION_NA)
+	{				/* port 2 on 1020s and 1520s */
+		++(port->count);
+		restore_flags(flags);
+		return -ENODEV;
+	}
+	
+	/* Check whether or not the port is open in SYNC mode */
+	if(port->open_type == OPEN_SYNC_NET)
+	{
+		if(port->dev && netif_carrier_ok(port->dev));
+		{
+			port->tty= NULL;	/* Don't bother with open counting here
+						   but make sure the tty field is NULL*/
+			restore_flags(flags);
+			return -EBUSY;
+		}
+		sab8253x_flush_buffer(tty); /* don't restore flags here */
+		sab8253x_shutdownN(port);
+	}
+	else if (port->open_type > OPEN_ASYNC) /* can't have a callout or async line
+						* if already open in some sync mode */
+	{
+		++(port->count);
+		restore_flags(flags);
+		return -EBUSY;
+	}
+	restore_flags(flags);
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_open"))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	
+#ifdef DEBUG_OPEN
+	printk("sab8253x_open %s%d, count = %d\n", tty->driver.name, port->line,
+	       port->count);
+#endif
+	
+	/*
+	 * If the port is in the middle of closing, bail out now.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (port->flags & FLAG8253X_CLOSING)) 
+	{
+		
+		if (port->flags & FLAG8253X_CLOSING)
+		{
+			interruptible_sleep_on(&port->close_wait);
+		}
+#ifdef SERIAL_DO_RESTART
+		++(port->count);
+		return ((port->flags & FLAG8253X_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		++(port->count);
+		return -EAGAIN;
+#endif
+	}
+	
+	if(Sab8253xSetUpLists(port))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xt_listsize, sab8253xt_rbufsize))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	
+	retval = sab8253x_startup(port);
+	if (retval)
+	{
+		++(port->count);
+		return retval;
+	}
+	
+	retval = sab8253x_block_til_ready(tty, filp, port);
+	++(port->count);  
+	if (retval) 
+	{
+		return retval;
+	}
+	
+	port->tty = tty;		/* may change here once through the block */
+	/* because now the port belongs to an new tty */
+	tty->flip.tqueue.routine = sab8253x_flush_to_ldisc; /* in case it was changed */
+	
+	if(Sab8253xSetUpLists(port))
+	{
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xt_listsize, sab8253xt_rbufsize))
+	{
+		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */
+		/* is the crc32 that is appended */
+		return -ENODEV;
+	}
+	
+	/*
+	 * Start up serial port
+	 */
+	retval = sab8253x_startup(port); /* just in case closing the cu dev
+					  * shutdown the port (but left CD) */
+	if (retval)
+	{
+		return retval;
+	}
+	
+	if ((port->count == 1) &&	/* first open */
+	    (port->flags & FLAG8253X_SPLIT_TERMIOS)) 
+	{
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+		{
+			*tty->termios = port->normal_termios;
+		}
+		else 
+		{
+			*tty->termios = port->callout_termios;
+		}
+		sab8253x_change_speed(port);
+	}
+	
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (sab8253x_console.cflag && sab8253x_console.index == line) 
+	{
+		tty->termios->c_cflag = sab8253x_console.cflag;
+		sab8253x_console.cflag = 0;
+		sab8253x_change_speed(port);
+	}
+#endif
+	
+	port->session = current->session;
+	port->pgrp = current->pgrp;
+	port->open_type = OPEN_ASYNC;
+	return 0;
+}
+
+static char *signaling[] =
+{
+	"OFF  ",
+	"RS232",
+	"RS422",
+	"RS485",
+	"RS449",
+	"RS530",
+	"V.35 "
+};
+
+static int sab8253x_read_proc(char *page, char **start, off_t off, int count,
+			      int *eof, void *data)
+{
+	extern struct sab_port * AuraPortRoot;
+	struct sab_port *port = AuraPortRoot;
+	extern char *board_type[];
+	off_t begin = 0;
+	int len = 0;
+	int portno;
+	unsigned int typeno;
+	extern int sab8253x_rebootflag;
+	
+#ifdef FREEININTERRUPT
+	len += sprintf(page, "serinfo:2.01I driver:%s\n", sab8253x_serial_version);
+#else
+	len += sprintf(page, "serinfo:2.01N driver:%s\n", sab8253x_serial_version);
+#endif
+	if(sab8253x_rebootflag)
+	{
+		len += sprintf(page+len, 
+			       "WARNING:  Found %d cards that required reprogramming.  Reboot machine!.\n", 
+			       sab8253x_rebootflag);
+	}
+	len += sprintf(page+len, "TTY MAJOR = %d, CUA MAJOR = %d, STTY MAJOR = %d.\n", 
+		       sab8253x_serial_driver.major, sab8253x_callout_driver.major, 
+		       sync_sab8253x_serial_driver.major);
+	for (portno = 0; port != NULL; port = port->next, ++portno) 
+	{
+		typeno = port->board->b_type;
+		if(typeno > BD_8520P)
+		{
+			typeno = 0;
+		}
+		len += sprintf(page+len, 
+			       "%d: port %d: %s: v%d: chip %d: ATI %s: bus %d: slot %d: %s: ", 
+			       sab8253x_serial_driver.minor_start + portno,
+			       port->portno,
+			       (port->chip->chip_type == ESCC2) ? "sab82532" : "sab82538",
+			       port->type,
+			       port->chip->c_chipno,
+			       board_type[port->board->b_type],
+			       port->board->b_dev.bus->number,
+			       PCI_SLOT(port->board->b_dev.devfn),
+			       aura_functionality[((port->function > FUNCTION_UN) ? FUNCTION_UN : port->function)]);
+		switch(port->open_type)
+		{
+		case OPEN_ASYNC:
+			len += sprintf(page+len, "openA");
+			break;
+		case OPEN_SYNC:
+			len += sprintf(page+len, "openS");
+			break;
+		case OPEN_SYNC_NET:
+			len += sprintf(page+len, "openN");
+			break;	  
+		case OPEN_SYNC_CHAR:
+			len += sprintf(page+len, "openC");
+			break;
+		case OPEN_NOT:
+			len += sprintf(page+len, "close");
+			break;
+		default:
+			len += sprintf(page+len, "open?");
+			break;
+		}
+		if(port->chip->c_cim)
+		{
+			if(port->chip->c_cim->ci_type == CIM_SP502)
+			{
+				len += sprintf(page+len, ": %s\n", signaling[port->sigmode]);
+			}
+			else
+			{
+				len += sprintf(page+len, ": NOPRG\n");
+			}
+		}
+		else
+		{
+			len += sprintf(page+len, ": NOPRG\n");
+		}
+
+		if (len+begin > off+count)
+		{
+			goto done;
+		}
+		if (len+begin < off) 
+		{
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+ done:
+	if (off >= len+begin)
+	{
+		return 0;
+	}
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * sab8253x_init() and friends
+ *
+ * sab8253x_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+static void inline show_aurora_version(void)
+{
+	char *revision = "$Revision: 1.23 $";
+	char *version, *p;
+	
+	version = strchr(revision, ' ');
+	strcpy(sab8253x_serial_version, ++version);
+	p = strchr(sab8253x_serial_version, ' ');
+	*p = '\0';
+	printk("Aurora serial driver version %s\n", sab8253x_serial_version);
+}
+
+#ifndef MODULE
+static int GetMinorStart(void)
+{
+	struct tty_driver *ttydriver;
+	int minor_start = 0;
+	kdev_t device;
+	
+	device = MKDEV(TTY_MAJOR, minor_start);
+	while(ttydriver = get_tty_driver(device), ttydriver != NULL)
+	{
+		minor_start += ttydriver->num;
+		device = MKDEV(TTY_MAJOR, minor_start);
+	}
+	return minor_start;
+	
+}
+#endif
+
+int finish_sab8253x_setup_ttydriver(void) 
+{
+	extern unsigned int NumSab8253xPorts;
+	
+	sab8253x_tableASY = (struct tty_struct **) kmalloc(NumSab8253xPorts*sizeof(struct tty_struct *), GFP_KERNEL);
+	if(sab8253x_tableASY == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_tableASY.\n");
+		return -1;
+	}
+	memset(sab8253x_tableASY, 0, NumSab8253xPorts*sizeof(struct tty_struct *));
+	sab8253x_tableCUA = (struct tty_struct **) kmalloc(NumSab8253xPorts*sizeof(struct tty_struct *), GFP_KERNEL);
+	if(sab8253x_tableCUA == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_tableCUA.\n");
+		return -1;
+	}
+	memset(sab8253x_tableCUA, 0, NumSab8253xPorts*sizeof(struct tty_struct *));
+	sab8253x_tableSYN = (struct tty_struct **) kmalloc(NumSab8253xPorts*sizeof(struct tty_struct *), GFP_KERNEL);
+	if(sab8253x_tableSYN == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_tableSYN.\n");
+		return -1;
+	}
+	memset(sab8253x_tableSYN, 0, NumSab8253xPorts*sizeof(struct tty_struct *));
+	
+	sab8253x_termios = (struct termios **) kmalloc(NumSab8253xPorts*sizeof(struct termios *), GFP_KERNEL);
+	if(sab8253x_termios == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_termios.\n");
+		return -1;
+	}
+	memset(sab8253x_termios, 0, NumSab8253xPorts*sizeof(struct termios *));
+	sab8253x_termios_locked = (struct termios **) kmalloc(NumSab8253xPorts*sizeof(struct termios *), GFP_KERNEL);
+	if(sab8253x_termios_locked == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_termios_locked.\n");
+		return -1;
+	}
+	memset(sab8253x_termios_locked, 0, NumSab8253xPorts*sizeof(struct termios *));
+	sync_sab8253x_serial_driver.num = sab8253x_callout_driver.num = sab8253x_serial_driver.num = NumSab8253xPorts;
+	sab8253x_serial_driver.table = sab8253x_tableASY;
+	sab8253x_callout_driver.table = sab8253x_tableCUA;
+	sync_sab8253x_serial_driver.table = sab8253x_tableSYN;
+	sync_sab8253x_serial_driver.termios = sab8253x_callout_driver.termios = sab8253x_serial_driver.termios = 
+		sab8253x_termios;
+	sync_sab8253x_serial_driver.termios_locked = sab8253x_callout_driver.termios_locked = 
+		sab8253x_serial_driver.termios_locked = sab8253x_termios_locked;
+	
+	if (tty_register_driver(&sab8253x_serial_driver) < 0)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not register serial driver.\n");
+		return -1;
+	}
+	if (tty_register_driver(&sab8253x_callout_driver) < 0)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not register call out device.\n");
+		return -1;
+	}
+	if (tty_register_driver(&sync_sab8253x_serial_driver) < 0)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not register sync serial device.\n");
+		return -1;
+	}
+	return 0;
+	
+}
+
+void sab8253x_setup_ttydriver(void) 
+{
+#ifdef MODULE
+	extern int xx20_minorstart;
+#endif
+	init_bh(AURORA_BH, sab8253x_do_serial_bh);
+	
+	show_aurora_version();
+	
+	/* Initialize the tty_driver structure */
+	
+	memset(&sab8253x_serial_driver, 0, sizeof(struct tty_driver));
+	sab8253x_serial_driver.magic = TTY_DRIVER_MAGIC;
+	sab8253x_serial_driver.driver_name = "auraserial";
+	sab8253x_serial_driver.name = "ttyS";
+	sab8253x_serial_driver.major = TTY_MAJOR;
+#ifdef MODULE
+	sab8253x_serial_driver.minor_start = xx20_minorstart;
+#else
+	sab8253x_serial_driver.minor_start = GetMinorStart();
+#endif
+	sab8253x_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	sab8253x_serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	sab8253x_serial_driver.init_termios = tty_std_termios;
+	sab8253x_serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	sab8253x_serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	sab8253x_serial_driver.refcount = &sab8253x_refcount;
+	
+	sab8253x_serial_driver.open = sab8253x_open;
+	sab8253x_serial_driver.close = sab8253x_close;
+	sab8253x_serial_driver.write = sab8253x_write;
+	sab8253x_serial_driver.put_char = NULL; /*sab8253x_put_char is evil.*/
+	sab8253x_serial_driver.flush_chars = sab8253x_flush_chars;
+	sab8253x_serial_driver.write_room = sab8253x_write_room;
+	sab8253x_serial_driver.chars_in_buffer = sab8253x_chars_in_buffer;
+	sab8253x_serial_driver.flush_buffer = sab8253x_flush_buffer;
+	sab8253x_serial_driver.ioctl = sab8253x_ioctl;
+	sab8253x_serial_driver.throttle = sab8253x_throttle;
+	sab8253x_serial_driver.unthrottle = sab8253x_unthrottle;
+	sab8253x_serial_driver.send_xchar = sab8253x_send_xchar;
+	sab8253x_serial_driver.set_termios = sab8253x_set_termios;
+	sab8253x_serial_driver.stop = sab8253x_stop;
+	sab8253x_serial_driver.start = sab8253x_start;
+	sab8253x_serial_driver.hangup = sab8253x_hangup;
+	sab8253x_serial_driver.break_ctl = sab8253x_break;
+	sab8253x_serial_driver.wait_until_sent = sab8253x_wait_until_sent;
+	sab8253x_serial_driver.read_proc = sab8253x_read_proc;
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	sab8253x_callout_driver = sab8253x_serial_driver;
+	sab8253x_callout_driver.name = "cua";
+	sab8253x_callout_driver.major = TTYAUX_MAJOR;
+	sab8253x_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	sab8253x_callout_driver.read_proc = 0;
+	sab8253x_callout_driver.proc_entry = 0;
+	
+	sync_sab8253x_serial_driver = sab8253x_serial_driver;
+	sync_sab8253x_serial_driver.name = "sttyS";
+	sync_sab8253x_serial_driver.major = 0;
+	sync_sab8253x_serial_driver.subtype = SERIAL_TYPE_SYNCTTY;
+	
+	sync_sab8253x_serial_driver.open = sab8253x_openS;
+	sync_sab8253x_serial_driver.close = sab8253x_closeS;
+	sync_sab8253x_serial_driver.write = sab8253x_writeS;
+	sync_sab8253x_serial_driver.put_char = NULL; /*sab8253x_put_char logic is evil*/
+	sync_sab8253x_serial_driver.flush_chars = sab8253x_flush_charsS;
+	sync_sab8253x_serial_driver.write_room = sab8253x_write_room;
+	sync_sab8253x_serial_driver.chars_in_buffer = sab8253x_chars_in_buffer;
+	sync_sab8253x_serial_driver.flush_buffer = sab8253x_flush_buffer;
+	sync_sab8253x_serial_driver.ioctl = sab8253x_ioctl;
+	sync_sab8253x_serial_driver.throttle = sab8253x_throttleS;
+	sync_sab8253x_serial_driver.unthrottle = sab8253x_unthrottleS;
+	sync_sab8253x_serial_driver.send_xchar = sab8253x_send_xcharS;
+	sync_sab8253x_serial_driver.set_termios = sab8253x_set_termiosS;
+	sync_sab8253x_serial_driver.stop = sab8253x_stopS;
+	sync_sab8253x_serial_driver.start = sab8253x_startS;
+	sync_sab8253x_serial_driver.hangup = sab8253x_hangupS;
+	sync_sab8253x_serial_driver.break_ctl = sab8253x_breakS;
+	sync_sab8253x_serial_driver.wait_until_sent = sab8253x_wait_until_sent;
+	sync_sab8253x_serial_driver.read_proc = 0;
+	sync_sab8253x_serial_driver.proc_entry = 0;
+}
+
+void sab8253x_setup_ttyport(struct sab_port *p_port) 
+{
+	p_port->magic = SAB_MAGIC;
+	p_port->custom_divisor = 16;
+	p_port->close_delay = 5*HZ/10;
+	p_port->closing_wait = 30*HZ;
+	p_port->tec_timeout = SAB8253X_MAX_TEC_DELAY;
+	p_port->cec_timeout = SAB8253X_MAX_CEC_DELAY;
+	p_port->x_char = 0;
+	p_port->event = 0;	
+	p_port->flags= FLAG8253X_BOOT_AUTOCONF | FLAG8253X_SKIP_TEST;
+	p_port->blocked_open = 0;
+	
+	p_port->all_sent = 1;	/* probably not needed */
+	
+	p_port->tqueue.sync = 0;	/* for later */
+	p_port->tqueue.routine = sab8253x_do_softint;
+	p_port->tqueue.data = p_port;
+	p_port->tqueue_hangup.sync = 0; /* for later */
+	p_port->tqueue_hangup.routine = sab8253x_do_serial_hangup;
+	p_port->tqueue_hangup.data = p_port;
+	p_port->callout_termios = sab8253x_callout_driver.init_termios;
+	p_port->normal_termios = sab8253x_serial_driver.init_termios; /* these are being shared */
+	/* between asynchronous and */
+	/* asynchronous ttys */
+	init_waitqueue_head(&p_port->open_wait);
+	init_waitqueue_head(&p_port->close_wait);
+	init_waitqueue_head(&p_port->delta_msr_wait);
+	init_waitqueue_head(&p_port->write_wait);
+	init_waitqueue_head(&p_port->read_wait);
+	
+	p_port->count = 0;		/* maybe not needed */
+	p_port->icount.cts = p_port->icount.dsr = 
+		p_port->icount.rng = p_port->icount.dcd = 0;
+	p_port->cts.val = p_port->dsr.val = 
+		p_port->dcd.val = 0;
+	p_port->icount.rx = p_port->icount.tx = 0;
+	p_port->icount.frame = p_port->icount.parity = 0;
+	p_port->icount.overrun = p_port->icount.brk = 0;
+	
+	p_port->xmit_fifo_size = 32;
+	p_port->recv_fifo_size = 32;
+	p_port->xmit_buf = NULL;
+	p_port->receive_chars = sab8253x_receive_chars;
+	p_port->transmit_chars = sab8253x_transmit_chars;
+	p_port->check_status = sab8253x_check_status;
+	p_port->receive_test = (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
+				SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	p_port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR);
+	p_port->check_status_test = SAB82532_ISR1_BRK;
+	
+	/* put in default sync control channel values
+	 * not needed for async -- I think these work
+	 * for bisync*/
+	p_port->ccontrol.ccr0 = DEFAULT_CCR0;
+	p_port->ccontrol.ccr1 = DEFAULT_CCR1;
+	p_port->ccontrol.ccr2 = DEFAULT_CCR2;
+	p_port->ccontrol.ccr3 = DEFAULT_CCR3;
+	p_port->ccontrol.ccr4 = DEFAULT_CCR4;
+	p_port->ccontrol.mode = DEFAULT_MODE;
+	p_port->ccontrol.rlcr = DEFAULT_RLCR;
+}
+
+void sab8253x_cleanup_ttydriver(void)
+{
+	unsigned long flags;
+	int e1, e2;
+	
+	save_flags(flags);
+	cli();
+	
+	if(sab8253x_tableASY) 
+		kfree(sab8253x_tableASY);
+	if(sab8253x_tableCUA) 
+		kfree(sab8253x_tableCUA);
+	if(sab8253x_tableSYN) 
+		kfree(sab8253x_tableSYN);
+	if(sab8253x_termios) 
+		kfree(sab8253x_termios);
+	if(sab8253x_termios_locked) 
+		kfree(sab8253x_termios_locked);
+	
+	remove_bh(AURORA_BH);
+	if ((e1 = tty_unregister_driver(&sab8253x_serial_driver)))
+	{
+		printk("SERIAL: failed to unregister serial driver (%d)\n",
+		       e1);
+	}
+	if ((e2 = tty_unregister_driver(&sab8253x_callout_driver)))
+	{
+		printk("SERIAL: failed to unregister callout driver (%d)\n", 
+		       e2);
+	}
+	if ((e2 = tty_unregister_driver(&sync_sab8253x_serial_driver)))
+	{
+		printk("SERIAL: failed to unregister callout driver (%d)\n", 
+		       e2);
+	}
+	restore_flags(flags);  
+}
+
+/* THE CODE BELOW HAS NOT YET BEEN MODIFIED!!!! FW */
+#ifdef XCONFIG_SERIAL_CONSOLE
+
+static inline void
+sab8253x_console_putchar(struct sab8253x *info, char c)
+{
+	unsigned long flags;
+	
+	save_flags(flags); cli();
+	sab8253x_tec_wait(info);
+	WRITEB(port,tic,c);
+	restore_flags(flags);
+}
+
+static void
+sab8253x_console_write(struct console *con, const char *s, unsigned n)
+{
+	struct sab8253x *info;
+	int i;
+	
+	info = sab8253x_chain;
+	for (i = con->index; i; i--) {
+		info = info->next;
+		if (!info)
+			return;
+	}
+	
+	for (i = 0; i < n; i++) {
+		if (*s == '\n')
+			sab8253x_console_putchar(info, '\r');
+		sab8253x_console_putchar(info, *s++);
+	}
+	sab8253x_tec_wait(info);
+}
+
+static int
+sab8253x_console_wait_key(struct console *con)
+{
+	sleep_on(&keypress_wait);
+	return 0;
+}
+
+static kdev_t
+sab8253x_console_device(struct console *con)
+{
+	return MKDEV(TTY_MAJOR, 64 + con->index);
+}
+
+static int
+sab8253x_console_setup(struct console *con, char *options)
+{
+	struct sab8253x *info;
+	unsigned int	ebrg;
+	tcflag_t	cflag;
+	unsigned char	dafo;
+	int		i, bits;
+	unsigned long	flags;
+	
+	info = sab8253x_chain;
+	for (i = con->index; i; i--) 
+	{
+		info = info->next;
+		if (!info)
+			return -ENODEV;
+	}
+	info->is_console = 1;
+	
+	/*
+	 * Initialize the hardware
+	 */
+	sab8253x_init_line(info);
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	info->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+		/*SAB82532_IMR0_TIME*/ | SAB82532_IMR0_PLLA/*| SAB82532_IMR0_CDSC*/;
+	WRITEB(port,imr0,info->interrupt_mask0);
+	info->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+		SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+		SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+		SAB82532_IMR1_XPR;
+	WRITEB(port,imr1,info->interrupt_mask1);
+	
+	printk("Console: ttyS%d (SAB82532)\n", info->line);
+	
+	sunserial_console_termios(con);
+	cflag = con->cflag;
+	
+	/* Byte size and parity */
+	switch (cflag & CSIZE) 
+	{
+	case CS5: dafo = SAB82532_DAFO_CHL5; bits = 7; break;
+	case CS6: dafo = SAB82532_DAFO_CHL6; bits = 8; break;
+	case CS7: dafo = SAB82532_DAFO_CHL7; bits = 9; break;
+	case CS8: dafo = SAB82532_DAFO_CHL8; bits = 10; break;
+		/* Never happens, but GCC is too dumb to figure it out */
+	default:  dafo = SAB82532_DAFO_CHL5; bits = 7; break;
+	}
+	
+	if (cflag & CSTOPB) 
+	{
+		dafo |= SAB82532_DAFO_STOP;
+		bits++;
+	}
+	
+	if (cflag & PARENB) 
+	{
+		dafo |= SAB82532_DAFO_PARE;
+		bits++;
+	}
+	
+	if (cflag & PARODD) 
+	{
+#ifdef CMSPAR
+		if (cflag & CMSPAR)
+			dafo |= SAB82532_DAFO_PAR_MARK;
+		else
+#endif
+			dafo |= SAB82532_DAFO_PAR_ODD;
+	} 
+	else 
+	{
+#ifdef CMSPAR
+		if (cflag & CMSPAR)
+			dafo |= SAB82532_DAFO_PAR_SPACE;
+		else
+#endif
+			dafo |= SAB82532_DAFO_PAR_EVEN;
+	}
+	
+	/* Determine EBRG values based on baud rate */
+	i = cflag & CBAUD;
+	if (i & CBAUDEX) 
+	{
+		i &= ~(CBAUDEX);
+		if ((i < 1) || ((i + 15) >= NR_EBRG_VALUES))
+			cflag &= ~CBAUDEX;
+		else
+			i += 15;
+	}
+	ebrg = ebrg_tabl[i].n;
+	ebrg |= (ebrg_table[i].m << 6);
+	
+	info->baud = ebrg_table[i].baud;
+	if (info->baud)
+		info->timeout = (info->xmit_fifo_size * HZ * bits) / info->baud;
+	else
+		info->timeout = 0;
+	info->timeout += HZ / 50;		/* Add .02 seconds of slop */
+	
+	/* CTS flow control flags */
+	if (cflag & CRTSCTS)
+		info->flags |= FLAG8253X_CTS_FLOW;
+	else
+		info->flags &= ~(FLAG8253X_CTS_FLOW);
+	
+	if (cflag & CLOCAL)
+		info->flags &= ~(FLAG8253X_CHECK_CD);
+	else
+		info->flags |= FLAG8253X_CHECK_CD;
+	
+	save_flags(flags); cli();
+	sab8253x_cec_wait(info);
+	sab8253x_tec_wait(info);
+	WRITEB(port,dafo,dafo);
+	WRITEB(port,bgr,ebrg & 0xff);
+	info->regs->rw.ccr2 &= ~(0xc0);
+	info->regs->rw.ccr2 |= (ebrg >> 2) & 0xc0;
+	if (info->flags & FLAG8253X_CTS_FLOW) 
+	{
+		info->regs->rw.mode &= ~(SAB82532_MODE_RTS);
+		info->regs->rw.mode |= SAB82532_MODE_FRTS;
+		info->regs->rw.mode &= ~(SAB82532_MODE_FCTS);
+	} 
+	else 
+	{
+		info->regs->rw.mode |= SAB82532_MODE_RTS;
+		info->regs->rw.mode &= ~(SAB82532_MODE_FRTS);
+		info->regs->rw.mode |= SAB82532_MODE_FCTS;
+	}
+	info->regs->rw.pvr &= ~(info->pvr_dtr_bit);
+	info->regs->rw.mode |= SAB82532_MODE_RAC;
+	restore_flags(flags);
+	
+	return 0;
+}
+
+static struct console sab8253x_console = 
+{
+	"ttyS",
+	sab8253x_console_write,
+	NULL,
+	sab8253x_console_device,
+	sab8253x_console_wait_key,
+	NULL,
+	sab8253x_console_setup,
+	CON_PRINTBUFFER,
+	-1,
+	0,
+	NULL
+};
+
+int sab8253x_console_init(void)
+{
+	extern int con_is_present(void);
+	extern int su_console_registered;
+	
+	if (con_is_present() || su_console_registered)
+		return 0;
+	
+	if (!sab8253x_chain) 
+	{
+		prom_printf("sab8253x_console_setup: can't get SAB8253X chain");
+		prom_halt();
+	}
+	
+	sab8253x_console.index = serial_console - 1;
+	register_console(&sab8253x_console);
+	return 0;
+}
+
+#ifdef SERIAL_LOG_DEVICE
+
+static int serial_log_device = 0;
+
+static void
+dprint_init(int tty)
+{
+	serial_console = tty + 1;
+	sab8253x_console.index = tty;
+	sab8253x_console_setup(&sab8253x_console, "");
+	serial_console = 0;
+	serial_log_device = tty + 1;
+}
+
+int
+dprintf(const char *fmt, ...)
+{
+	static char buffer[4096];
+	va_list args;
+	int i;
+	
+	if (!serial_log_device)
+		return 0;
+	
+	va_start(args, fmt);
+	i = vsprintf(buffer, fmt, args);
+	va_end(args);
+	sab8253x_console.write(&sab8253x_console, buffer, i);
+	return i;
+}
+
+#endif /* SERIAL_LOG_DEVICE */
+#endif /* XCONFIG_SERIAL_CONSOLE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/8253xutl.c linux/drivers/net/wan/8253x/8253xutl.c
--- linux.orig/drivers/net/wan/8253x/8253xutl.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/8253xutl.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,1422 @@
+/* -*- linux-c -*- */
+/* $Id: 8253xutl.c,v 1.3 2002/02/10 22:17:26 martillo Exp $
+ * 8253xutl.c: SYNC TTY Driver for the SIEMENS SAB8253X DUSCC.
+ *
+ * Implementation, modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/* Standard in kernel modules */
+#define DEFINE_VARIABLE
+#include <linux/module.h>   /* Specifically, a module */
+#include <asm/io.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include "8253xctl.h"
+#include "8253x.h"
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include "sp502.h"
+
+#ifdef MODULE
+#undef XCONFIG_SERIAL_CONSOLE
+#endif
+
+void sab8253x_start_txS(struct sab_port *port)
+{
+	unsigned long flags;
+	register int count;
+	register int total;
+	register int offset;
+	char temporary[32];
+	register unsigned int slopspace;
+	register int sendsize;
+	unsigned int totaltransmit;
+	unsigned fifospace;
+	unsigned loadedcount;
+	struct tty_struct *tty = port->tty; /* a little gross tty flags whether
+					       invoked from a tty or the network */
+	
+	fifospace = port->xmit_fifo_size; /* This code can handle fragmented frames
+					     although currently none are generated*/
+	loadedcount = 0;
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();			
+	
+	
+	if(count = port->sabnext2.transmit->Count, (count & OWNER) == OWN_SAB)
+	{
+		count &= ~OWN_SAB; /* OWN_SAB is really 0 but cannot guarantee in the future */
+		
+		if(port->sabnext2.transmit->HostVaddr)
+		{
+			total = (port->sabnext2.transmit->HostVaddr->tail - 
+				 port->sabnext2.transmit->HostVaddr->data); /* packet size */
+		}
+		else
+		{
+			total = 0;		/* the data is only the crc/trailer */
+		}
+		
+		if(tty && (tty->stopped || tty->hw_stopped) && (count == total))
+		{			/* works for frame that only has a trailer (crc) */
+			port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+			WRITEB(port, imr1, port->interrupt_mask1);
+			restore_flags(flags);	/* can't send */
+			return;
+		}
+		
+		offset = (total - count);	/* offset to data still to send */
+		
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
+		WRITEB(port, imr1, port->interrupt_mask1);
+		port->all_sent = 0;
+		
+		if(READB(port,star) & SAB82532_STAR_XFW)
+		{
+			if(count <= fifospace)
+			{
+				port->xmit_cnt = count;
+				slopspace = 0;
+				sendsize = 0;
+				if(port->sabnext2.transmit->sendcrc) 
+				/* obviously should not happen for async but might use for
+				   priority transmission */
+				{
+					slopspace = fifospace - count;
+				}
+				if(slopspace)
+				{
+					if(count)
+					{
+						memcpy(temporary, &port->sabnext2.transmit->HostVaddr->data[offset], 
+						       count);
+					}
+					sendsize = MIN(slopspace, (4 - port->sabnext2.transmit->crcindex)); 
+				/* how many bytes to send */
+					memcpy(&temporary[count], 
+					       &((unsigned char*)(&port->sabnext2.transmit->crc))
+					       [port->sabnext2.transmit->crcindex], 
+					       sendsize);
+					port->sabnext2.transmit->crcindex += sendsize;
+					if(port->sabnext2.transmit->crcindex >= 4)
+					{
+						port->sabnext2.transmit->sendcrc = 0;
+					}
+					port->xmit_buf = temporary;
+				}
+				else
+				{
+					port->xmit_buf =	/* set up wrifefifo variables */
+						&port->sabnext2.transmit->HostVaddr->data[offset];
+				}
+				port->xmit_cnt += sendsize;
+				count = 0;
+			}
+			else
+			{
+				count -= fifospace;
+				port->xmit_cnt = fifospace;
+				port->xmit_buf =	/* set up wrifefifo variables */
+					&port->sabnext2.transmit->HostVaddr->data[offset];
+				
+			}
+			port->xmit_tail= 0;
+			loadedcount = port->xmit_cnt;
+			(*port->writefifo)(port);
+			totaltransmit = Sab8253xCountTransmitDescriptors(port);
+			if(tty && (totaltransmit < (sab8253xs_listsize/2))) /* only makes sense on a TTY */
+			{
+				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
+			}
+			
+			if((sab8253xt_listsize - totaltransmit) > (sab8253xt_listsize/2))
+			{
+				port->buffergreedy = 0;
+			}
+			else
+			{
+				port->buffergreedy = 1;
+			}
+			
+			port->xmit_buf = NULL; /* this var is used to indicate whether to call kfree */
+			
+			/* fifospace -= loadedcount;*/
+			/* Here to make mods to handle arbitrarily fragmented frames look to 8253xtty.c for help */
+			
+			if ((count <= 0) && (port->sabnext2.transmit->sendcrc == 0))
+			{
+				port->sabnext2.transmit->Count = OWN_DRIVER;
+				if(!tty)
+				{		/* called by network driver */
+					++(port->Counters.transmitpacket);
+				}
+#ifdef FREEININTERRUPT		/* treat this routine as if taking place in interrupt */
+				if(port->sabnext2.transmit->HostVaddr)
+				{
+					skb_unlink(port->sabnext2.transmit->HostVaddr);
+					dev_kfree_skb_any(port->sabnext2.transmit->HostVaddr);
+					port->sabnext2.transmit->HostVaddr = 0; /* no skb */
+				}
+				port->sabnext2.transmit->crcindex = 0; /* no single byte */
+#endif
+				sab8253x_cec_wait(port);
+				WRITEB(port, cmdr, SAB82532_CMDR_XME|SAB82532_CMDR_XTF); /* Terminate the frame */
+				
+				port->sabnext2.transmit = port->sabnext2.transmit->VNext;
+				
+				if(!tty && port->tx_full)	/* invoked from the network driver */
+				{
+					port->tx_full = 0; /* there is a free slot */
+					switch(port->open_type)
+					{
+					case OPEN_SYNC_NET:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+						port->dev->start = 1;
+						port->dev->tbusy = 0;	/* maybe need mark_bh here */
+#else
+						netif_start_queue(port->dev);
+#endif
+						break;
+						
+					case OPEN_SYNC_CHAR:
+						wake_up_interruptible(&port->write_wait);
+						break;
+						
+					default:
+						break;
+					}
+				}
+				
+				if((port->sabnext2.transmit->Count & OWNER) == OWN_SAB)
+				{		/* new frame to send */
+					port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
+					WRITEB(port, imr1, port->interrupt_mask1);
+				}
+				else
+				{
+					port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+					WRITEB(port, imr1, port->interrupt_mask1);
+					if((port->open_type == OPEN_SYNC_CHAR) && port->async_queue)
+					{		/* if indication of transmission is needed by the */
+						/* application on a per-frame basis kill_fasync */
+						/* can provide it */
+						kill_fasync(&port->async_queue, SIGIO, POLL_OUT);
+					}
+				}
+				restore_flags(flags);
+				return;
+			}
+			/* Issue a Transmit FIFO command. */
+			sab8253x_cec_wait(port);
+			WRITEB(port, cmdr, SAB82532_CMDR_XTF);	
+			port->sabnext2.transmit->Count = (count|OWN_SAB);
+		}
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR); /* more to send */
+		WRITEB(port, imr1, port->interrupt_mask1);
+	}
+	else
+	{				/* nothing to send */
+		port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+		WRITEB(port, imr1, port->interrupt_mask1);
+	}
+	restore_flags(flags);
+	return;
+}
+
+void sab8253x_transmit_charsS(struct sab_port *port,
+			      union sab8253x_irq_status *stat)
+{
+	if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) 
+	{
+		port->interrupt_mask1 |= SAB82532_IMR1_ALLS;
+		WRITEB(port, imr1, port->interrupt_mask1);
+		port->all_sent = 1;
+	}
+	sab8253x_start_txS(port);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+
+/***************************************************************************
+ * sab_baudenh:      Function to compute the "enhanced" baudrate.
+ *                
+ *
+ *     Parameters   : 
+ *                  encbaud  2* the baudrate. We use the
+ *                           double value so as to support 134.5 (in only)
+ *                  clkspeed The board clock speed in Hz.
+ *                  bgr      Value of reg BGR for baudrate(output)
+ *                  ccr2     Value of reg // CCR2 for baudrate (output)
+ *                  ccr4     Value of reg CCR4 for baudrate (output)
+ *                  truebaud The actual baudrate achieved (output).
+ *
+ *
+ *     Return value : Return FALSE the parameters could not be computed, 
+ *
+ *     Prerequisite : The various ports must have been initialized
+ *
+ *     Remark       : Stolen from the Aurora ase driver.
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 9 2000, creation
+ ***************************************************************************/
+/*
+ * Macro to check to see if the high n bits of the given unsigned long
+ *  are zero.
+ */               
+#define HIZERO(x, n)        ( ((unsigned long) ((x) << (n)) >> (n)) == (x))
+/* form an n-bit bitmask */
+#define NBM(n)                  (~(((~(unsigned long) 0) >> (n)) << (n)))
+/* shift x by y bits to right, rounded */
+#define ROUND_SHIFT(x, y)       (((unsigned long) (x) + (NBM(y - 1) + 1)) >> (y))
+/* perform rounded division */
+#define ROUND_DIV(x, y) (((x) + ((y) >> 1)) / (y))
+#define ABSDIF(x, y)    ((x) > (y) ? ((x) - (y)) : ((y) - (x))) 
+static unsigned int
+sab8253x_baudenh(unsigned long encbaud, unsigned long clk_speed,
+		 unsigned char *bgr, unsigned char *ccr2,
+		 unsigned long *truebaudp)
+{
+	register unsigned short	 tmp;
+	register unsigned char	 ccr2tmp;
+	unsigned long		 power2, mant;
+	unsigned int			 fastclock;
+	
+	if (encbaud == 0) {
+		return FALSE;
+	}
+	
+	/*
+	 * Keep dividing quotien by two until it is between the value of 1 and 64,
+	 *  inclusive.
+	 */
+	
+	fastclock = (clk_speed >= 10000000);	/* >= 10 MHz */
+	
+	for (power2 = 0; power2 < 16; power2++) 
+	{
+		/* divisor = baud * 2^M * 16 */
+		if (!HIZERO(encbaud, power2 + 3)) 
+		{
+			if (!HIZERO(encbaud, power2)) 
+			{	/* baud rate still too big? */
+				mant = ROUND_DIV(ROUND_SHIFT(clk_speed, power2 + 3), encbaud);
+				
+				/* mant = (clk_speed / (8 * 2^M)) / (baud * 2) */
+				/*	= clk_speed / (baud * 16 * 2^M) */
+			}
+			else 
+			{
+				mant = ROUND_DIV(ROUND_SHIFT(clk_speed, 3), encbaud << power2);
+				/* mant = (clk_speed / 8) / (baud * 2 * 2^M) */
+				/*	= clk_speed / (baud * 16 * 2^M) */
+			}
+		}
+		else 
+		{
+			mant = ROUND_DIV(clk_speed, encbaud << (power2 + 3));
+			/* mant = clk_speed / (baud * 2 * 8 * 2^M) */
+			/*	    = clk_speed / (baud * 16 * 2^M) */
+		}
+		
+		/* mant = clk_speed / (baud * 2^M * 16) */
+		
+		if (mant < 2
+		    || (mant <= 64 && (!fastclock || power2 != 0))) 
+		{
+			break;
+		}
+	}
+	
+	/*
+	 * Did we not succeed?  (Baud rate is too small)
+	 */
+	if (mant > 64) 
+	{
+		return FALSE;
+	}
+	
+	/*
+	 * Now, calculate the true baud rate.
+	 */
+	
+	if (mant < 1 || (mant == 1 && power2 == 0)) 
+	{
+		/* bgr and ccr2 should be initialized to 0 */
+		*truebaudp = ROUND_SHIFT(clk_speed, 4);
+	}
+	else 
+	{
+		*truebaudp = ROUND_DIV(clk_speed, mant << (4 + power2));
+		/* divisor is not zero because mant is [1, 64] */
+		mant--; /* now [0, 63] */
+		
+		/*
+		 * Encode the N and M values into the bgr and ccr2 registers.
+		 */
+		
+		tmp = ((unsigned short) mant) | ((unsigned short) power2 << 6);
+		
+		ccr2tmp = SAB82532_CCR2_BDF;
+		if ((tmp & 0x200) != 0) 
+		{
+			ccr2tmp |= SAB82532_CCR2_BR9;
+		}
+		if ((tmp & 0x100) != 0) 
+		{
+			ccr2tmp |= SAB82532_CCR2_BR8;
+		}
+		
+		*ccr2 = ccr2tmp | (*ccr2 & ~(SAB82532_CCR2_BDF|SAB82532_CCR2_BR8|SAB82532_CCR2_BR9));
+		*bgr = (unsigned char) tmp;
+	}
+	
+	return TRUE;
+}
+
+/*
+ * Calculate the standard mode baud divisor using an integral algorithm.
+ */
+/***************************************************************************
+ * sab_baudstd:      Function to compute the "standard " baudrate.
+ *                
+ *
+ *     Parameters   : 
+ *                  encbaud  2* the baudrate. We use the
+ *                           double value so as to support 134.5 (in only)
+ *                  clkspeed The board clock speed in Hz.
+ *                  bgr      Value of reg BGR for baudrate(output)
+ *                  ccr2     Value of reg CCR2 for baudrate (output)
+ *                  ccr4     Value of reg CCR4 for baudrate (output)
+ *                  truebaud The actual baudrate achieved (output).
+ *
+ *
+ *     Return value : Return FALSE the parameters could not be computed, 
+ *
+ *     Prerequisite : The various ports must have been initialized
+ *
+ *     Remark       : Stolen from the Aurora ase driver.
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 9 2000, creation
+ ***************************************************************************/
+static unsigned int
+sab8253x_baudstd(unsigned long encbaud, unsigned long clk_speed,
+		 unsigned char *bgr, unsigned char *ccr2,
+		 unsigned long *truebaudp)
+{
+  register unsigned short	 quot;
+  register unsigned char	 ccr2tmp;
+  
+  if (encbaud == 0) 
+  {
+	  return FALSE;
+  }
+  
+  /*
+   * This divisor algorithm is a little strange.  The
+   *  divisors are all multiples of 2, except for the
+   *  magic value of 1.
+   *
+   * What we do is do most of the algorithm for multiples
+   *  of 1, and then switch at the last minute to multiples
+   *  of 2.
+   */
+  
+  /*
+   * Will we lose any information by left shifting encbaud?
+   *  If so, then right shift clk_speed instead.
+   */
+  if (!HIZERO(encbaud, 3)) 
+  {
+	  quot = (unsigned short) ROUND_DIV(ROUND_SHIFT(clk_speed, 3),
+					    encbaud);
+	  /* quot = (clk_speed / 8) / (baud * 2) = clk_speed / (16 * baud) */
+  }
+  else 
+  {
+	  /* encbaud isn't a multiple of 2^29 (baud not mult. of 2^28) */
+	  quot = (unsigned short) ROUND_DIV(clk_speed, encbaud << 3);
+  }
+  
+  /* quot = clk_speed / (baud * 16) */
+  if (quot < 2) 
+  {
+	  /* bgr and ccr2 should be initialized to 0 */
+	  *truebaudp = ROUND_SHIFT(clk_speed, 4);
+	  return TRUE;
+  }
+  
+  /*
+   * Divide the quotient by two.
+   */
+  quot = ROUND_SHIFT(quot, 1);
+  
+  if (quot <= 0x400) 
+  {
+	  /* quot = [1, 0x400]  -> (quot << 5) != 0 */
+	  *truebaudp = ROUND_DIV(clk_speed, ((unsigned long) quot << 5));
+	  quot--;
+	  
+	  ccr2tmp = SAB82532_CCR2_BDF;
+	  if ((quot & 0x200) != 0) 
+	  {
+		  ccr2tmp |= SAB82532_CCR2_BR9;
+	  }
+	  if ((quot & 0x100) != 0) 
+	  {
+		  ccr2tmp |=SAB82532_CCR2_BR8;
+	  }
+	  
+	  *ccr2 = ccr2tmp | (*ccr2 & ~(SAB82532_CCR2_BDF|SAB82532_CCR2_BR8|SAB82532_CCR2_BR9));
+	  *bgr = (unsigned char) quot;
+  }
+  else 
+  {			/* the baud rate is too small. */
+	  return FALSE;
+  }
+  
+  return TRUE;
+}
+
+/***************************************************************************
+ * sab_baud:      Function to compute the best register value to achieve
+ *                a given baudrate.
+ *                
+ *
+ *     Parameters   : 
+ *                  port:    The port being used  (in only)
+ *                  encbaud: 2* the baudrate. We use the
+ *                           double value so as to support 134.5 (in only)
+ *                  bgr      Value of reg BGR for baudrate(output)
+ *                  ccr2     Value of reg CCR2 for baudrate (output)
+ *                  ccr4     Value of reg CCR4 for baudrate (output)
+ *                  truebaud The actual baudrate achieved (output).
+ *
+ *
+ *     Return value : Return TRUE if the vaudrate can be set, FALSE otherwise 
+ *
+ *     Prerequisite : The various ports must have been initialized
+ *
+ *     Remark       : Stolen from the Aurora ase driver.
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 9 2000, creation
+ ***************************************************************************/
+unsigned int 
+sab8253x_baud(sab_port_t *port, unsigned long encbaud,
+	      unsigned char *bgr, unsigned char *ccr2,
+	      unsigned char *ccr4, unsigned long *truebaudp)
+{
+	unsigned char	 bgr_std, bgr_enh, ccr2_std, ccr2_enh, ccr4_enh;
+	unsigned int		 ok_std, ok_enh;
+	unsigned long	 truebaud_std, truebaud_enh, truebaud,clkspeed;
+	
+	bgr_std = bgr_enh = 0;
+	ccr2_std = ccr2_enh = 0;
+	ccr4_enh = 0;
+	
+	/*
+	 * the port/chip/board structure will tell us:
+	 *  1) clock speed
+	 *  2) chip revision (to figure out if the enhanced method is
+	 *     available.
+	 */
+	
+	clkspeed = port->chip->c_cim ? port->chip->c_cim->ci_clkspeed :  port->board->b_clkspeed;
+	
+#ifdef NODEBUGGING
+	printk("With clk speed %ld, baud rate = %ld\n",clkspeed, encbaud);
+#endif
+	
+	ok_std = sab8253x_baudstd(encbaud, clkspeed, &bgr_std,
+				  &ccr2_std, &truebaud_std);
+#ifdef NODEBUGGING
+	printk("Std gives bgr = 0x%x, ccr2=0x%x for speed %ld\n",bgr_std,ccr2_std,truebaud_std);
+#endif
+	if(port->chip->c_revision >= SAB82532_VSTR_VN_3_2) 
+	{
+		ok_enh = sab8253x_baudenh(encbaud, clkspeed,
+					  &bgr_enh, &ccr2_enh, &truebaud_enh);
+#ifdef NODEBUGGING
+		printk("Enh gives bgr = 0x%x, ccr2=0x%x for speed %ld\n",bgr_enh,ccr2_enh,truebaud_enh);
+#endif
+	} 
+	else 
+		ok_enh = FALSE;
+	
+	/*
+	 * Did both methods return values?
+	 */
+	if (ok_std && ok_enh) 
+	{
+		/*
+		 * Find the closest of the two.
+		 */
+		if (ABSDIF((truebaud_enh<<1), encbaud) <
+		    ABSDIF((truebaud_std<<1), encbaud)) 
+		{
+			ok_std = FALSE;
+		}
+		else 
+		{
+			ok_enh = FALSE;
+		}
+	}
+	
+	/*
+	 * Now return the values.
+	 */
+	
+	if (ok_std || ok_enh) 
+	{
+		truebaud = ok_std ? truebaud_std : truebaud_enh;
+		
+		/*
+		 * If the true baud rate is off by more than 5%, then
+		 *  we don't support it.
+		 */
+		if (ROUND_DIV(ABSDIF((truebaud<<1), encbaud), encbaud) != 0) 
+		{
+			/*
+			 * We're not even in the right ballpark.  This
+			 *  test is here to deal with overflow conditions.
+			 */
+			return FALSE;
+		}
+		else if (ROUND_DIV(ABSDIF((truebaud<<1), encbaud) * 100,
+				   encbaud) >= 5) 
+		{
+			return FALSE;
+		}
+		
+		*truebaudp = truebaud;
+		
+		if (ok_enh) 
+		{
+			*ccr4 |= SAB82532_CCR4_EBRG;
+			*ccr2 = ccr2_enh;
+			*bgr = bgr_enh;
+#ifdef DEBUGGING
+			printk("Enhanced Baud at %ld, ccr4 = 0x%x, ccr2 = 9x%x, bgr = 0x%x\n",
+			       truebaud,*ccr4,*ccr2,*bgr);
+#endif
+		} 
+		else 
+		{
+			*ccr4 &= ~SAB82532_CCR4_EBRG;
+			*ccr2 = ccr2_std;
+			*bgr = bgr_std;
+#ifdef DEBUGGING
+			printk("Standard Baud at %ld, ccr4 = 0x%x, ccr2 = 9x%x, bgr = 0x%x\n",
+			       truebaud,*ccr4,*ccr2,*bgr);
+#endif
+		}
+		
+		return TRUE;
+	}
+	else 
+	{
+		return FALSE;
+	}
+}
+
+int Sab8253xCountTransmit(SAB_PORT *port)
+{
+	register RING_DESCRIPTOR *rd;
+	register int total;
+	register int count;
+	unsigned long flags;
+	RING_DESCRIPTOR *start;
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	save_flags(flags);
+	cli();
+	rd = port->sabnext2.transmit;
+	start = rd;
+	total = 0;
+	while(1)
+	{
+		count = rd->Count;
+		if((count & OWNER) == OWN_DRIVER)
+		{
+			break;
+		}
+		total += (count & ~OWNER);
+		if(rd->sendcrc)
+		{
+			total += (4 - rd->crcindex);
+		}
+		rd = rd->VNext;
+		if(rd == start)
+		{
+			break;
+		}
+	}
+	restore_flags(flags);
+	return total;
+}
+
+int Sab8253xCountTransmitDescriptors(SAB_PORT *port)
+{
+	register RING_DESCRIPTOR *rd;
+	register int total;
+	register int count;
+	unsigned long flags;
+	RING_DESCRIPTOR *start;
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	save_flags(flags);
+	cli();
+	rd = port->sabnext2.transmit;
+	start = rd;
+	total = 0;
+	while(1)
+	{
+		count = rd->Count;
+		if((count & OWNER) == OWN_DRIVER)
+		{
+			break;
+		}
+		++total;
+		rd = rd->VNext;
+		if(rd == start)
+		{
+			break;
+		}
+	}
+	restore_flags(flags);
+	return total;
+}
+
+int getccr0configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr0;
+}
+
+int getccr1configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr1;
+}
+
+int getccr2configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr2;
+}
+
+int getccr3configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr3;
+}
+
+int getccr4configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr4;
+}
+
+int getrlcrconfigS(struct sab_port *port)
+{
+	return port->ccontrol.rlcr;
+}
+
+int getmodeS(struct sab_port *port)
+{
+	return port->ccontrol.mode;
+}
+
+void sab8253x_init_lineS(struct sab_port *port)
+{
+	unsigned char stat;
+	
+	if(port->chip->c_cim)
+	{
+		if(port->chip->c_cim->ci_type == CIM_SP502)
+		{
+			aura_sp502_program(port, SP502_OFF_MODE);
+		}
+	}
+
+	/*
+	 * Wait for any commands or immediate characters
+	 */
+	sab8253x_cec_wait(port);
+#if 0
+	sab8253x_tec_wait(port);	/* I have to think about this one
+					 * should I assume the line was
+					 * previously in async mode*/
+#endif
+	
+	/*
+	 * Clear the FIFO buffers.
+	 */
+	
+	WRITEB(port, cmdr, SAB82532_CMDR_RHR);
+	sab8253x_cec_wait(port);
+	WRITEB(port,cmdr,SAB82532_CMDR_XRES);
+	
+	
+	/*
+	 * Clear the interrupt registers.
+	 */
+	stat = READB(port, isr0);	/* acks ints */
+	stat = READB(port, isr1);
+	
+	/*
+	 * Now, initialize the UART 
+	 */
+	WRITEB(port, ccr0, 0);	  /* power-down */
+	WRITEB(port, ccr0, getccr0configS(port));
+	WRITEB(port, ccr1, getccr1configS(port));
+	WRITEB(port, ccr2, getccr2configS(port));
+	WRITEB(port, ccr3, getccr3configS(port));
+	WRITEB(port, ccr4, getccr4configS(port));	/* 32 byte receive fifo */
+	WRITEB(port, mode, getmodeS(port));
+	WRITEB(port, tic /* really rlcr */, getrlcrconfigS(port));
+	/* power-up */
+	
+	switch(port->ccontrol.ccr4 & SAB82532_CCR4_RF02)
+	{
+	case SAB82532_CCR4_RF32:
+		port->recv_fifo_size = 32;
+		break;
+	case SAB82532_CCR4_RF16:
+		port->recv_fifo_size = 16;
+		break;
+	case SAB82532_CCR4_RF04:
+		port->recv_fifo_size = 4;
+		break;
+	case SAB82532_CCR4_RF02:
+		port->recv_fifo_size = 2;
+		break;
+	default:
+		port->recv_fifo_size = 32;
+		port->ccontrol.ccr4 &= ~SAB82532_CCR4_RF02;
+		break;
+	}
+	
+	if(port->ccontrol.ccr2 & SAB82532_CCR2_TOE)
+	{
+		RAISE(port, txclkdir);
+	}
+	else
+	{
+		LOWER(port, txclkdir);
+	}
+	
+	SET_REG_BIT(port,ccr0,SAB82532_CCR0_PU);
+
+	if(port->chip->c_cim)
+	{
+		if(port->chip->c_cim->ci_type == CIM_SP502)
+		{
+			aura_sp502_program(port, port->sigmode);
+		}
+	}
+}
+
+/* frees up all skbuffs currently */
+/* held by driver */
+void Sab8253xFreeAllFreeListSKBUFFS(SAB_PORT* priv) /* empty the skbuffer list */
+/* either on failed open */
+/* or on close*/
+{
+	struct sk_buff* skb;
+	
+	if(priv->sab8253xbuflist == NULL)
+	{
+		return;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "sab8253x: freeing %i skbuffs.\n", 
+		    skb_queue_len(priv->sab8253xbuflist)));
+	
+	while(skb_queue_len(priv->sab8253xbuflist) > 0)
+	{
+		skb = skb_dequeue(priv->sab8253xbuflist);
+		dev_kfree_skb_any(skb);
+	}
+	kfree(priv->sab8253xbuflist);
+	priv->sab8253xbuflist = NULL;
+}
+
+int Sab8253xSetUpLists(SAB_PORT *priv)
+{
+	if(priv->sab8253xbuflist)
+	{
+		if(priv->sab8253xc_rcvbuflist)
+		{
+			return 0;
+		}
+		else
+		{
+			return -1;
+		}
+		return 0;
+	}
+	else if(priv->sab8253xc_rcvbuflist)
+	{
+		return -1;
+	}
+	
+	priv->sab8253xbuflist = (struct sk_buff_head*) kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
+	if(priv->sab8253xbuflist == NULL)
+	{
+		return -1;
+	}
+	priv->sab8253xc_rcvbuflist = (struct sk_buff_head*) kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);  
+	if(priv->sab8253xc_rcvbuflist == NULL)
+	{
+		kfree(priv->sab8253xbuflist);
+		return -1;
+	}
+	skb_queue_head_init(priv->sab8253xbuflist);
+	skb_queue_head_init(priv->sab8253xc_rcvbuflist);
+	return 0;
+}
+
+/* sets up transmit ring and one receive sk_buff */
+
+/* set up transmit and receive
+   sk_buff control structures */
+int Sab8253xInitDescriptors2(SAB_PORT *priv, int listsize, int rbufsize)
+{
+	RING_DESCRIPTOR *desc;
+	RING_DESCRIPTOR *xdesc;
+	
+	if(priv->dcontrol2.transmit != NULL)
+		
+	{
+		if(priv->dcontrol2.receive != NULL)
+		{
+			return 0;
+		}
+		return -1;
+	}
+	else if(priv->dcontrol2.receive != NULL)
+	{
+		return -1;
+	}
+	
+	priv->dcontrol2.transmit = (RING_DESCRIPTOR*) 
+		kmalloc(sizeof(RING_DESCRIPTOR) * listsize, GFP_KERNEL);
+	/* dcontrol2 is an historical
+	   artifact from when the code
+	   talked to an intelligent controller */
+	if(priv->dcontrol2.transmit == NULL)
+	{
+		return -1;
+	}
+	
+	priv->dcontrol2.receive = (RING_DESCRIPTOR*)
+		kmalloc(sizeof(RING_DESCRIPTOR), GFP_KERNEL); /* only one receive sk_buffer */
+	if(priv->dcontrol2.receive == NULL)
+	{
+		kfree(priv->dcontrol2.transmit);
+		priv->dcontrol2.transmit = NULL;
+		return -1;
+	}
+	
+	for(xdesc = priv->dcontrol2.transmit; 
+	    xdesc < &priv->dcontrol2.transmit[listsize - 1];
+	    xdesc = &xdesc[1])	/* set up transmit descriptors */
+	{
+		xdesc->HostVaddr = NULL;
+		xdesc->VNext = &xdesc[1];
+		xdesc->Count = 0 | OWN_DRIVER;
+		xdesc->crc = 0;
+		xdesc->sendcrc = 0;
+		xdesc->crcindex = 0;
+	}
+	xdesc->HostVaddr = NULL;
+	xdesc->VNext = priv->dcontrol2.transmit; /* circular list */
+	xdesc->Count = 0 | OWN_DRIVER;
+	xdesc->crc = 0;
+	xdesc->sendcrc = 0;
+	xdesc->crcindex = 0;
+	
+	desc = priv->dcontrol2.receive; /* only need one descriptor for receive */
+	desc->HostVaddr = NULL;
+	desc->VNext = &desc[0];
+	
+	desc = priv->dcontrol2.receive;
+	desc->HostVaddr = dev_alloc_skb(rbufsize);
+	if(desc->HostVaddr == NULL)
+	{
+		printk(KERN_ALERT "Unable to allocate skb_buffers (rx 0).\n");
+		printk(KERN_ALERT "Driver initialization failed.\n");
+		kfree(priv->dcontrol2.transmit);
+		kfree(priv->dcontrol2.receive);
+		priv->dcontrol2.transmit = NULL; /* get rid of descriptor ring */
+		priv->dcontrol2.receive = NULL; /* get rid of descriptor */
+		/* probably should do some deallocation of sk_buffs*/
+		/* but will take place in the open */
+		return -1;
+	}
+	skb_queue_head(priv->sab8253xbuflist, (struct sk_buff*) desc->HostVaddr);
+	desc->Count = rbufsize|OWN_SAB;	/* belongs to int handler */
+	desc->crc = 0;
+	desc->sendcrc = 0;
+	desc->crcindex = 0;
+	
+	/* setup the various pointers */
+	priv->active2 = priv->dcontrol2; /* insert new skbuff */
+	priv->sabnext2 = priv->dcontrol2; /* transmit from here */
+	
+	return 0;
+}
+
+/* loads program, waits for PPC */
+/* and completes initialization*/
+
+void Sab8253xCleanUpTransceiveN(SAB_PORT* priv)
+{
+	Sab8253xFreeAllFreeListSKBUFFS(priv);	
+	Sab8253xFreeAllReceiveListSKBUFFS(priv);
+	
+	/* these are also cleaned up in the module cleanup routine */
+	/* should probably only be done here */
+	if(priv->dcontrol2.receive)
+	{
+		kfree(priv->dcontrol2.receive);
+		priv->dcontrol2.receive = NULL;
+	}
+	if(priv->dcontrol2.transmit)
+	{
+		kfree(priv->dcontrol2.transmit);
+		priv->dcontrol2.transmit = NULL;
+	}
+	priv->active2 = priv->dcontrol2;
+	priv->sabnext2 = priv->dcontrol2; 
+}
+
+void Sab8253xFreeAllReceiveListSKBUFFS(SAB_PORT* priv) /* empty the skbuffer list */
+/* either on failed open */
+/* or on close*/
+{
+	struct sk_buff* skb;
+	
+	if(priv->sab8253xc_rcvbuflist == NULL)
+	{
+		return;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "sab8253x: freeing %i skbuffs.\n", 
+		    skb_queue_len(priv->sab8253xc_rcvbuflist)));
+	
+	while(skb_queue_len(priv->sab8253xc_rcvbuflist) > 0)
+	{
+		skb = skb_dequeue(priv->sab8253xc_rcvbuflist);
+		dev_kfree_skb_any(skb);
+	}
+	kfree(priv->sab8253xc_rcvbuflist);
+	priv->sab8253xc_rcvbuflist = NULL;
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+
+void sab8253x_change_speedN(struct sab_port *port)
+{
+	unsigned long	flags;
+	unsigned char ccr2=0, ccr4=0, ebrg=0;
+	int bits = 8;
+	
+#ifdef DEBUGGING
+	printk("Change speed!  ");
+#endif
+	
+	if(!sab8253x_baud(port, (port->baud)*2, &ebrg, &ccr2, &ccr4, &(port->baud))) 
+	{
+		printk("Aurora Warning. baudrate %ld could not be set! Using 115200", port->baud);
+		port->baud = 115200;
+		sab8253x_baud(port, (port->baud*2), &ebrg, &ccr2, &ccr4, &(port->baud));
+	}
+	
+	if (port->baud)
+	{
+		port->timeout = (port->xmit_fifo_size * HZ * bits) / port->baud;
+		port->cec_timeout = port->tec_timeout >> 2;
+	}
+	else
+	{
+		port->timeout = 0;
+		port->cec_timeout = SAB8253X_MAX_CEC_DELAY;
+	}
+	port->timeout += HZ / 50;		/* Add .02 seconds of slop */
+	
+	save_flags(flags); 
+	cli();
+	sab8253x_cec_wait(port);
+	
+	WRITEB(port, bgr, ebrg);
+	WRITEB(port, ccr2, READB(port, ccr2) & ~(0xc0)); /* clear out current baud rage */
+	WRITEB(port, ccr2, READB(port, ccr2) | ccr2);
+	WRITEB(port, ccr4, (READB(port,ccr4) & ~SAB82532_CCR4_EBRG) | ccr4);
+	
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{
+		WRITEB(port, mode, READB(port,mode) & ~(SAB82532_MODE_RTS));
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_CSC);
+		WRITEB(port, imr1, port->interrupt_mask1);
+	} 
+	else 
+	{
+		WRITEB(port, mode, READB(port,mode) | SAB82532_MODE_RTS);
+		port->interrupt_mask1 |= SAB82532_IMR1_CSC;
+		WRITEB(port, imr1, port->interrupt_mask1);
+	}
+	WRITEB(port, mode, READB(port, mode) | SAB82532_MODE_RAC);
+	restore_flags(flags);
+}
+
+void sab8253x_shutdownN(struct sab_port *port)
+{
+	unsigned long flags;
+	
+	if (!(port->flags & FLAG8253X_INITIALIZED))
+	{
+		return;
+	}
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+	
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&port->delta_msr_wait);
+	
+	/* Disable Interrupts */
+	
+	port->interrupt_mask0 = 0xff;
+	WRITEB(port, imr0, port->interrupt_mask0);
+	port->interrupt_mask1 = 0xff;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	
+	LOWER(port,rts);
+	LOWER(port,dtr);
+	
+	/* Disable Receiver */	
+	CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC);
+	
+	/* Power Down */	
+	CLEAR_REG_BIT(port,ccr0,SAB82532_CCR0_PU);
+	
+	port->flags &= ~FLAG8253X_INITIALIZED;
+	restore_flags(flags);
+}
+
+int sab8253x_block_til_ready(struct tty_struct *tty, struct file * filp,
+			     struct sab_port *port)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+	unsigned long flags;
+	
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (port->flags & FLAG8253X_CLOSING)) 
+	{
+		if (port->flags & FLAG8253X_CLOSING)
+		{
+			interruptible_sleep_on(&port->close_wait); /* finish up previous close */
+		}
+#ifdef SERIAL_DO_RESTART
+		if (port->flags & FLAG8253X_HUP_NOTIFY)
+		{
+			return -EAGAIN;
+		}
+		else
+		{
+			return -ERESTARTSYS;
+		}
+#else
+		return -EAGAIN;
+#endif
+	}
+	
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) 
+	{
+		if (port->flags & FLAG8253X_NORMAL_ACTIVE) 
+		{
+			return -EBUSY;	/* async, sync tty or network driver active */
+		}
+		if ((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    (port->flags & FLAG8253X_SESSION_LOCKOUT) &&
+		    (port->session != current->session))
+		{
+			return -EBUSY;
+		}
+		if ((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    (port->flags & FLAG8253X_PGRP_LOCKOUT) &&
+		    (port->pgrp != current->pgrp))
+		{
+			return -EBUSY;
+		}
+		port->flags |= FLAG8253X_CALLOUT_ACTIVE; /* doing a callout */
+		return 0;
+	}
+	
+	/* sort out async vs sync tty, not call out */
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) 
+	{
+		if (port->flags & FLAG8253X_CALLOUT_ACTIVE)
+		{
+			return -EBUSY;
+		}
+		port->flags |= FLAG8253X_NORMAL_ACTIVE;
+		return 0;
+	}
+	
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE) 
+	{
+		if (port->normal_termios.c_cflag & CLOCAL)
+		{
+			do_clocal = 1;
+		}
+	} 
+	else if (tty->termios->c_cflag & CLOCAL)
+	{
+		do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, port->count is dropped by one, so that
+	 * sab8253x_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	
+	/* The port decrement logic is probably */
+	/* broken -- hence if def'd out -- it does*/
+	retval = 0;
+	add_wait_queue(&port->open_wait, &wait); /* starts the wait but does not block here */
+	port->blocked_open++;
+	while (1) 
+	{
+		save_flags(flags);
+		cli();
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    (tty->termios->c_cflag & CBAUD)) 
+		{
+			RAISE(port, dtr);
+			RAISE(port, rts);	/* maybe not correct for sync */
+			/*
+			 * ??? Why changing the mode here? 
+			 *  port->regs->rw.mode |= SAB82532_MODE_FRTS;
+			 *  port->regs->rw.mode &= ~(SAB82532_MODE_RTS);
+			 */
+		}
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(port->flags & FLAG8253X_INITIALIZED)) 
+		{
+#ifdef SERIAL_DO_RESTART
+			if (port->flags & FLAG8253X_HUP_NOTIFY)
+			{
+				retval = -EAGAIN;
+			}
+			else
+			{
+				retval = -ERESTARTSYS;	
+			}
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    !(port->flags & FLAG8253X_CLOSING) &&
+		    (do_clocal || ISON(port,dcd))) 
+		{
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("sab8253x_block_til_ready:2 flags = 0x%x\n",port->flags);
+#endif
+		if (signal_pending(current)) 
+		{
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("sab8253x_block_til_ready blocking: ttyS%d, count = %d, flags = %x, clocal = %d, vstr = %02x\n",
+		       port->line, port->count, port->flags, do_clocal, READB(port,vstr));
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&port->open_wait, &wait);
+	port->blocked_open--;
+#ifdef DEBUG_OPEN
+	printk("sab8253x_block_til_ready after blocking: ttys%d, count = %d\n",
+	       port->line, port->count);
+#endif
+	if (retval)
+	{
+		return retval;
+	}
+	port->flags |= FLAG8253X_NORMAL_ACTIVE;
+	return 0;
+}
+
+/*
+ * sab8253x_wait_until_sent() --- wait until the transmitter is empty
+ */
+void sab8253x_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	
+	if (sab8253x_serial_paranoia_check(port,tty->device,"sab8253x_wait_until_sent"))
+	{
+		return;
+	}
+	
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 * 
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (port->timeout - HZ/50) / port->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+	{
+		char_time = 1;
+	}
+	if (timeout)
+	{
+		char_time = MIN(char_time, timeout);
+	}
+	while ((Sab8253xCountTransmit(port) > 0) || !port->all_sent) 
+	{
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+		{
+			break;
+		}
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+		{
+			break;
+		}
+	}
+}
+
+void sab8253x_flush_buffer(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	register RING_DESCRIPTOR *freeme;
+	
+	if(sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_flush_buffer"))
+	{
+		return;
+	}
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();			/* need to turn off ints because mucking
+				   with sabnext2 */
+#ifndef FREEININTERRUPT
+	freeme = port->active2.transmit;
+	do				/* just go all around */
+	{
+		if(freeme->HostVaddr)
+		{
+			skb_unlink((struct sk_buff*)freeme->HostVaddr);
+			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+			freeme->HostVaddr = NULL;
+		}
+		freeme->sendcrc = 0;
+		freeme->crcindex = 0;
+		freeme->Count = OWN_DRIVER;
+		freeme = (RING_DESCRIPTOR*) freeme->VNext;
+	}
+	while(freeme != port->active2.transmit);
+#else  /* buffers only from sabnext2.transmit to active2.transmit */
+	while((port->sabnext2.transmit->Count & OWNER) == OWN_SAB) /* clear out stuff waiting to be transmitted */
+	{
+		freeme = port->sabnext2.transmit;
+		if(freeme->HostVaddr)
+		{
+			skb_unlink((struct sk_buff*)freeme->HostVaddr);
+			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+			freeme->HostVaddr = NULL;
+		}
+		freeme->sendcrc = 0;
+		freeme->crcindex = 0;
+		freeme->Count = OWN_DRIVER;
+		port->sabnext2.transmit = freeme->VNext;
+	}
+#endif
+	port->sabnext2.transmit = port->active2.transmit; /* should already be equal to be sure */
+	sab8253x_cec_wait(port);
+	WRITEB(port,cmdr,SAB82532_CMDR_XRES);
+	restore_flags(flags);
+	
+	wake_up_interruptible(&tty->write_wait); /* wake up tty driver */
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+	{
+		(*tty->ldisc.write_wakeup)(tty);
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/Makefile linux/drivers/net/wan/8253x/Makefile
--- linux.orig/drivers/net/wan/8253x/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,21 @@
+# Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+
+# File: drivers/net/WAN/atiXX50/Makefile
+#
+# Makefile for the Aurora ESSC based cards
+# Specifically the 2520, 4020, 4520, 8520
+#
+
+O_TARGET := ASLX.o
+
+obj-y := 8253xini.o 8253xnet.o 8253xsyn.o crc32.o 8253xdbg.o 8253xplx.o 8253xtty.o 8253xchr.o 8253xint.o amcc5920.o 8253xmcs.o 8253xutl.o
+obj-m := ASLX.o
+
+#EXTRA_CFLAGS += -DFREEININTERRUPT 
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/PciRegs.h linux/drivers/net/wan/8253x/PciRegs.h
--- linux.orig/drivers/net/wan/8253x/PciRegs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/PciRegs.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,68 @@
+/* -*- linux-c -*- */
+#ifndef __PCIREGS_H
+#define __PCIREGS_H
+
+#include <linux/pci.h>
+
+/*******************************************************************************
+ * Copyright (c) 1997 - 1999 PLX Technology, Inc.
+ * 
+ * PLX Technology Inc. licenses this software under specific terms and
+ * conditions.  Use of any of the software or derviatives thereof in any
+ * product without a PLX Technology chip is strictly prohibited. 
+ * 
+ * PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
+ * EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  PLX makes no guarantee
+ * or representations regarding the use of, or the results of the use of,
+ * the software and documentation in terms of correctness, accuracy,
+ * reliability, currentness, or otherwise; and you rely on the software,
+ * documentation and results solely at your own risk.
+ * 
+ * IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
+ * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
+ * OF ANY KIND.  IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
+ * PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
+ * 
+ ******************************************************************************/
+
+/* Modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ **/
+
+/******************************************************************************
+ *
+ * File Name:   PciRegs.h
+ *
+ * Module Name: IOP API and PCI API
+ *
+ * Description: This file defines the generic PCI Configuration Registers
+ *
+ * Revision:
+ *     09-03-99 : PCI SDK v3.00 Release
+ *
+ ******************************************************************************/
+
+#define CFG_VENDOR_ID           PCI_VENDOR_ID
+#define CFG_COMMAND             PCI_COMMAND
+#define CFG_REV_ID              PCI_REVISION_ID
+#define CFG_CACHE_SIZE          PCI_CACHE_LINE_SIZE
+#define CFG_BAR0                PCI_BASE_ADDRESS_0
+#define CFG_BAR1                PCI_BASE_ADDRESS_1
+#define CFG_BAR2                PCI_BASE_ADDRESS_2
+#define CFG_BAR3                PCI_BASE_ADDRESS_3
+#define CFG_BAR4                PCI_BASE_ADDRESS_4
+#define CFG_BAR5                PCI_BASE_ADDRESS_5
+#define CFG_CIS_PTR             PCI_CARDBUS_CIS
+#define CFG_SUB_VENDOR_ID       PCI_SUBSYSTEM_VENDOR_ID
+#define CFG_EXP_ROM_BASE        PCI_ROM_ADDRESS
+#define CFG_RESERVED1           PCI_CAPABILITY_LIST
+#define CFG_RESERVED2           (PCI_CAPABILITY_LIST + 4)
+#define CFG_INT_LINE            PCI_INTERRUPT_LINE
+
+#endif  /* __PCIREGS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/Reg9050.h linux/drivers/net/wan/8253x/Reg9050.h
--- linux.orig/drivers/net/wan/8253x/Reg9050.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/Reg9050.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,244 @@
+/* -*- linux-c -*- */
+#ifndef __REG9050_H
+#define __REG9050_H
+
+/*******************************************************************************
+ * Copyright (c) 2001 PLX Technology, Inc.
+ * 
+ * PLX Technology Inc. licenses this software under specific terms and
+ * conditions.  Use of any of the software or derviatives thereof in any
+ * product without a PLX Technology chip is strictly prohibited. 
+ * 
+ * PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
+ * EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  PLX makes no guarantee
+ * or representations regarding the use of, or the results of the use of,
+ * the software and documentation in terms of correctness, accuracy,
+ * reliability, currentness, or otherwise; and you rely on the software,
+ * documentation and results solely at your own risk.
+ * 
+ * IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
+ * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
+ * OF ANY KIND.  IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
+ * PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
+ * 
+ ******************************************************************************/
+
+/* Modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ **/
+
+
+/******************************************************************************
+ * 
+ * File Name:
+ *
+ *      Reg9050.h
+ *
+ * Description:
+ *
+ *      This file defines all the PLX 9050 chip Registers.
+ *
+ * Revision:
+ *
+ *      01-30-01 : PCI SDK v3.20
+ *
+ ******************************************************************************/
+
+
+#include "PciRegs.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* PCI Configuration Registers */
+#define PCI9050_VENDOR_ID            CFG_VENDOR_ID
+#define PCI9050_COMMAND              CFG_COMMAND
+#define PCI9050_REV_ID               CFG_REV_ID
+#define PCI9050_CACHE_SIZE           CFG_CACHE_SIZE
+#define PCI9050_PCI_BASE_0           CFG_BAR0
+#define PCI9050_PCI_BASE_1           CFG_BAR1
+#define PCI9050_PCI_BASE_2           CFG_BAR2
+#define PCI9050_PCI_BASE_3           CFG_BAR3
+#define PCI9050_PCI_BASE_4           CFG_BAR4
+#define PCI9050_PCI_BASE_5           CFG_BAR5
+#define PCI9050_CIS_PTR              CFG_CIS_PTR
+#define PCI9050_SUB_ID               CFG_SUB_VENDOR_ID
+#define PCI9050_PCI_BASE_EXP_ROM     CFG_EXP_ROM_BASE
+#define PCI9050_CAP_PTR              CFG_CAP_PTR
+#define PCI9050_PCI_RESERVED         CFG_RESERVED2
+#define PCI9050_INT_LINE             CFG_INT_LINE
+
+
+#if 0				/* from PLX header file */
+/* Local Configuration Registers */
+#define PCI9050_RANGE_SPACE0         0x000
+#define PCI9050_RANGE_SPACE1         0x004
+#define PCI9050_RANGE_SPACE2         0x008
+#define PCI9050_RANGE_SPACE3         0x00C
+#define PCI9050_RANGE_EXP_ROM        0x010
+#define PCI9050_REMAP_SPACE0         0x014
+#define PCI9050_REMAP_SPACE1         0x018
+#define PCI9050_REMAP_SPACE2         0x01C
+#define PCI9050_REMAP_SPACE3         0x020
+#define PCI9050_REMAP_EXP_ROM        0x024
+#define PCI9050_DESC_SPACE0          0x028
+#define PCI9050_DESC_SPACE1          0x02C
+#define PCI9050_DESC_SPACE2          0x030
+#define PCI9050_DESC_SPACE3          0x034
+#define PCI9050_DESC_EXP_ROM         0x038
+#define PCI9050_BASE_CS0             0x03C
+#define PCI9050_BASE_CS1             0x040
+#define PCI9050_BASE_CS2             0x044
+#define PCI9050_BASE_CS3             0x048
+#define PCI9050_INT_CTRL_STAT        0x04C
+#define PCI9050_EEPROM_CTRL          0x050
+
+#endif
+
+
+/* Additional register defintions */
+#define MAX_PCI9050_REG_OFFSET       0x054
+
+#define PCI9050_EEPROM_SIZE          0x064
+
+/*
+ * PLX 9050 registers:
+ */
+
+typedef struct plx9050_s 
+{
+	/* Local Address Space */
+	unsigned int	las0;		/* 0x00 */
+	unsigned int	las1;		/* 0x04 */
+	unsigned int	las2;		/* 0x08 */
+	unsigned int	las3;		/* 0x0c */
+	/* Expansion ROM range */
+	unsigned int	e_rom;		/* 0x10 */
+	/* Local Base Adresses */
+	unsigned int   lba0;		/* 0x14 */
+	unsigned int   lba1;		/* 0x18 */
+	unsigned int   lba2;		/* 0x1c */
+	unsigned int   lba3;		/* 0x20 */
+	unsigned int	e_rom_lba;	/* 0x24 */
+	/* Bus region description */
+	unsigned int	brd0;		/* 0x28 */
+	unsigned int	brd1;		/* 0x2c */
+	unsigned int	brd2;		/* 0x30 */
+	unsigned int	brd3;		/* 0x34 */
+	unsigned int	e_rom_brd;	/* 0x38 */
+	/* Chip Select X Base address */
+	unsigned int	csba0;		/* 0x3c */
+	unsigned int	csba1;		/* 0x40 */
+	unsigned int	csba2;		/* 0x44 */
+	unsigned int	csba3;		/* 0x48 */
+	/* Interupt Control/Status */
+	unsigned int   intr;		/* 0x4c */
+	/* Control */
+	unsigned int	ctrl;		/* 0x50 */
+} plx9050_t, PLX9050;
+
+#define PLX_REG_LAS0RR	0x0
+#define PLX_REG_LAS1RR	0x4
+#define PLX_REG_LAS2RR	0x8
+#define PLX_REG_LAS3RR	0x0c
+#define PLX_REG_EROMRR	0x10
+#define PLX_REG_LAS0BA	0x14
+#define PLX_REG_LAS1BA	0x18
+#define PLX_REG_LAS2BA	0x1c
+#define PLX_REG_LAS3BA	0x20
+#define PLX_REG_EROMBA	0x24
+#define PLX_REG_LAS0BRD	0x28
+#define PLX_REG_LAS1BRD	0x2c
+#define PLX_REG_LAS2BRD	0x30
+#define PLX_REG_LAS3BRD	0x34
+#define PLX_REG_EROMBRD	0x38
+#define PLX_REG_CS0BASE	0x3c
+#define PLX_REG_CS1BASE	0x40
+#define PLX_REG_CS2BASE	0x44
+#define PLX_REG_CS3BASE	0x48
+#define PLX_REG_INTCSR	0x4c
+#define PLX_REG_CTRL	0x50 
+
+/*
+ * Bits within those registers:
+ */
+/* LAS0    */
+#define PLX_LAS0_MEM_MASK	0x0ffffff0
+
+/* INTCSR: */
+#define PLX_INT_INTR1ENA	0x00000001   /* Local interrupt 1 enable */
+#define PLX_INT_INTR1POL	0x00000002   /* Local interrupt 1 polarity */
+#define PLX_INT_INTR1STS	0x00000004   /* Local interrupt 1 status */
+#define PLX_INT_INTR2ENA	0x00000008   /* Local interrupt 2 enable */
+#define PLX_INT_INTR2POL	0x00000010   /* Local interrupt 2 polarity */
+#define PLX_INT_INTR2STS	0x00000020   /* Local interrupt 2 status */
+#define PLX_INT_PCIINTRENA	0x00000040   /* PCI interrupt enable */
+#define PLX_INT_SOFTINTR	0x00000080   /* Software interrupt */
+#if 0
+#define PLX_INT_ON	        (PLX_INT_INTR1ENA | PLX_INT_PCIINTRENA | PLX_INT_INTR2POL)
+#define PLX_INT_OFF	        PLX_INT_INTR2POL
+#elif 0
+#define PLX_INT_ON	        PLX_INT_PCIINTRENA
+#define PLX_INT_OFF	        0
+#else
+#define PLX_INT_ON	(PLX_INT_INTR1ENA | PLX_INT_PCIINTRENA)
+#define PLX_INT_OFF	0x0000
+#endif
+
+/* BRD */
+#define PLX_BRD_BIGEND          0x01000000
+#define PLX_BRD_BIGEND_LANE     0x02000000
+
+
+     /* CTRL: */	      /*  87654321 */
+#define PLX_CTRL_RESET		0x40000000
+#define PLX_CTRL_USERIO3DIR	0x00000400
+#define PLX_CTRL_USERIO3DATA	0x00000800
+#define PLX_CTRL_SEPCLK		0x01000000
+#define PLX_CTRL_SEPCS		0x02000000
+#define PLX_CTRL_SEPWD		0x04000000
+#define PLX_CTRL_SEPRD		0x08000000
+
+/* Definition for the EPROM */
+	/* # of addressing bits for NM93CS06, NM93CS46 */
+#define NM93_ADDRBITS	6
+#define NM93_WENCMD	((u8) 0x00)
+#define NM93_WRITECMD	((u8) 0x01)
+#define NM93_READCMD	((u8) 0x02)
+#define NM93_WRALLCMD	((u8) 0x00) /* same as WEN */
+#define NM93_WDSCMD	((u8) 0x00) /* ditto */
+
+#define NM93_WDSADDR	((u8) 0x00)
+#define NM93_WRALLADDR	((u8) 0x10)
+#define NM93_WENADDR	((u8) 0x30)
+
+#define NM93_BITS_PER_BYTE	8
+#define NM93_BITS_PER_WORD	16
+
+#define EPROMPREFETCHOFFSET 	9
+#define PREFETCHBIT		0x0008
+
+#define EPROM9050_SIZE			0x40 /* for loading the 9050 */
+
+#define AURORA_MULTI_EPROM_SIZE		0x40	/* serial EPROM size */
+/* serial EPROM offsets */
+#define AURORA_MULTI_EPROM_CLKLSW	0x36	/* clock speed LSW */
+#define AURORA_MULTI_EPROM_CLKMSW	0x37	/* clock speed MSW */
+#define AURORA_MULTI_EPROM_REV		0x38	/* revision begins here */
+#define AURORA_MULTI_EPROM_REVLEN	0x0f	/* length (in bytes) */
+#define AURORA_MULTI_EPROM_SPDGRD	0x3f	/* speed grade is here */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/amcc5920.c linux/drivers/net/wan/8253x/amcc5920.c
--- linux.orig/drivers/net/wan/8253x/amcc5920.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/amcc5920.c	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,92 @@
+/* -*- linux-c -*- */
+/*
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+				/* This file is linked in, but I am
+				   not sure there is ever any
+				   reason directly to read the
+				   serial eprom on the multichannel
+				   server host card. */
+
+/* We handle PCI devices */
+#include <linux/pci.h>      
+
+/* We need to use ioremap */ 
+#include <asm/io.h>
+
+#include <linux/delay.h>
+
+#include "8253xmcs.h"
+#include "8253xctl.h"
+
+/* read a byte out of the serial eeprom/nvram by means of
+ * 16 short commands */
+
+static unsigned int amcc_nvram_breadw(unsigned char *bridge_space, 
+				      unsigned short address,
+				      unsigned char *value)
+{
+	unsigned int count;
+	unsigned rhr;
+	
+	for(count = 0; count < 20000; ++count)
+	{
+		rhr = readl(bridge_space + AMCC_RCR);
+		if((rhr & AMCC_NVRBUSY) == 0)
+		{
+			break;
+		}
+		udelay(1);
+	}
+	if(count >= 20000)
+	{
+		return FALSE;
+	}
+	rhr = AMCC_NVRWRLA | ((address & 0x00FF) << 16);
+	writel(rhr, bridge_space + AMCC_RCR);
+	rhr = AMCC_NVRWRHA | ((address & 0xFF00) << 8);
+	writel(rhr, bridge_space + AMCC_RCR);
+	writel(AMCC_NVRRDDB, bridge_space + AMCC_RCR);
+	for(count = 0; count < 20000; ++count)
+	{
+		rhr = readl(bridge_space + AMCC_RCR);
+		if((rhr & AMCC_NVRBUSY) == 0)
+		{
+			break;
+		}
+		udelay(1);
+	}
+	if(count >= 20000)
+	{
+		return FALSE;
+	}
+	if(rhr & AMCC_NVRACCFAIL)
+	{
+		return FALSE;
+	}
+	*value = (unsigned char) (rhr >> 16);
+	return TRUE;
+}
+
+/* read the whole serial eeprom from the host card */
+
+unsigned int amcc_read_nvram(unsigned char* buffer, unsigned length, unsigned char *bridge_space)
+{
+	unsigned int count;
+	length <<= 1;			/* covert words to bytes */
+	
+	for(count = 0; count < length; ++count)
+	{
+		if(amcc_nvram_breadw(bridge_space, count, &buffer[count]) == FALSE)
+		{
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/crc32.c linux/drivers/net/wan/8253x/crc32.c
--- linux.orig/drivers/net/wan/8253x/crc32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/crc32.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,148 @@
+/* -*- linux-c -*- */
+/******************************************************************************
+ *  FILE:      crc32.c
+ *
+ *  Copyright: Telford Tools, Inc.
+ *             1996
+ *
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ ******************************************************************************
+ */
+/******************************************************************************
+ *  REVISION HISTORY: (Most Recent First)
+ *  -------------------------------------
+ *  2-Apr-91    ALEX    Introduced "fn_calc_novram_crc32()".
+ ******************************************************************************
+ */
+
+/****************************************************/
+/*		    header files		    */
+/****************************************************/
+
+#include "crc32dcl.h"
+#include "endian.h"
+
+/****************************************************/
+/*		    constants			    */
+/****************************************************/
+
+#define k_poly		    ((unsigned int)(0xedb88320))
+#define k_crc_table_size    (256)
+
+#if defined (AMD29K)
+pragma Code ("rkernel");
+pragma Off(cross_jump);
+#endif
+
+/****************************************************/
+/*			static data		    */
+/****************************************************/
+
+#if defined(AMD29K)
+pragma Data (Export,"fastbss");
+#endif defined(AMD29K)
+
+unsigned int gg_a_crc_table[k_crc_table_size];
+
+#if defined(AMD29K)
+pragma Data;
+#endif defined(AMD29K)
+
+
+/****************************************************/
+/*		    global procedures		    */
+/****************************************************/
+
+void
+fn_init_crc_table()
+{
+	short	i_table;
+	
+	for (i_table = 0; i_table < k_crc_table_size; i_table++)
+	{
+		unsigned int	result = 0;
+		short	i_bit;
+		
+		for (i_bit = 0; i_bit < 8; i_bit++)
+		{
+			unsigned int    bit = ((i_table  & (1 << i_bit)) != 0);
+			
+			if ((bit ^ (result & 1)) != 0)
+				result = (result >> 1) ^ k_poly;
+			else
+				result >>= 1;
+		}
+		
+		gg_a_crc_table[i_table] = result;
+	}
+	
+} /* end of fn_init_crc_table */
+
+/****************************************************/
+
+static unsigned int
+fn_calc_memory_chunk_crc32(void *p, unsigned int n_bytes, unsigned int crc)
+{
+	unsigned char    *p_uc   = (unsigned char*)p;
+	unsigned int   result  = ~crc;
+	
+	while (n_bytes-- > 0)
+	{
+		result = (result >> 8) ^ gg_a_crc_table[(result ^ *p_uc++) & 0xff];
+	}
+	
+	return(~result);
+	
+} /* end of fn_calc_memory_chunk_crc32 */
+
+/****************************************************/
+
+unsigned int
+fn_calc_memory_crc32(void *p, unsigned int n_bytes)
+{
+	fnm_assert_stmt(n_bytes > 4);
+	
+	return(fn_calc_memory_chunk_crc32(p, n_bytes, k_initial_crc_value));
+	
+} /* end of fn_calc_memory_crc32 */
+
+/****************************************************/
+
+unsigned int
+fn_check_memory_crc32(void *p, unsigned int n_bytes, unsigned int crc)
+{
+	return(fn_calc_memory_crc32(p, n_bytes) == crc);
+	
+} /* end of fn_check_memory_crc32 */
+
+
+/****************************************************/
+/* Adds current longword to the crc value and       */
+/* returns that value.                              */
+unsigned int
+fn_update_crc(char *val, unsigned int crcval)
+{
+	long i;
+	
+	/* ----< break long into bytes >---- */
+	/* ----< put bytes into crc >---- */
+	for (i = 0; i < 4; i++)
+	{
+		crcval = gg_a_crc_table[(crcval ^ val[i]) & 0xff] ^
+			((crcval >> 8) & 0x00ffffff);
+	}
+	return(crcval);
+}					/* endfunc--fn_update_crc */
+
+
+/****************************************************/
+/****************************************************/
+/*	    End source file "crc32.c"		    */
+/****************************************************/
+/****************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/crc32.h linux/drivers/net/wan/8253x/crc32.h
--- linux.orig/drivers/net/wan/8253x/crc32.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/crc32.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,27 @@
+/* -*- linux-c -*- */
+/****************************************************/
+/****************************************************/
+/*	    Begin source file "crc32.h"		    */
+/****************************************************/
+/****************************************************/
+
+#if !defined(_CRC32_H_)
+#define _CRC32_H_
+
+/****************************************************/
+/*		    header files		    */
+/****************************************************/
+
+/****************************************************/
+/*		    constants			    */
+/****************************************************/
+
+#define k_initial_crc_value	((unsigned int) 0)
+
+#endif
+
+/****************************************************/
+/****************************************************/
+/*	    End source file "crc32.h"		    */
+/****************************************************/
+/****************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/crc32dcl.h linux/drivers/net/wan/8253x/crc32dcl.h
--- linux.orig/drivers/net/wan/8253x/crc32dcl.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/crc32dcl.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,45 @@
+/* -*- linux-c -*- */
+/*
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+/****************************************************/
+/****************************************************/
+/*	    Begin source file "crc32dcl.h"	    */
+/****************************************************/
+/****************************************************/
+
+#if !defined(_CRC32_HP_)
+#define _CRC32_HP_
+
+/****************************************************/
+/*		    header files		    */
+/****************************************************/
+
+#include "crc32.h"
+
+/****************************************************/
+/*	    global procedure prototypes		    */
+/****************************************************/
+
+extern void	fn_init_crc_table(void);
+extern unsigned int	fn_calc_memory_chunk_crc32(void *p, unsigned int n_bytes, unsigned int crc);
+extern unsigned int	fn_calc_memory_crc32(void *p, unsigned int n_bytes);
+extern unsigned int	fn_check_memory_crc32(void *p, unsigned int n_bytes, unsigned int crc);
+
+extern unsigned int gg_a_crc_table[];
+
+
+#endif
+
+/****************************************************/
+/****************************************************/
+/*	    End source file "crc32dcl.h"		    */
+/****************************************************/
+/****************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/endian.h linux/drivers/net/wan/8253x/endian.h
--- linux.orig/drivers/net/wan/8253x/endian.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/endian.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,341 @@
+/* -*- linux-c -*- */
+/*
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+/****************************************************/
+/****************************************************/
+/*	    Begin header file "endian.h"	    */
+/****************************************************/
+/****************************************************/
+
+#if !defined(_ENDIAN_HP_)
+#define _ENDIAN_HP_
+
+/****************************************************/
+/*		    header files		    */
+/****************************************************/
+
+
+/****************************************************/
+/*  let's see if we know this is a big endian	    */
+/****************************************************/
+#ifndef INLINE
+#define INLINE inline
+#endif
+
+#define fnm_assert_stmt(a)
+
+#ifndef BYTE_ORDER
+#if defined(AMD29K) || defined(mc68000)
+
+#define BIG_ENDIAN     4321
+
+#endif
+
+/****************************************************/
+/*  global macro functions handling endian issues   */
+/****************************************************/
+
+#if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
+#define LITTLE_ENDIAN 1234
+#endif
+#endif
+
+#define fnm_get_i_big_endian(p_uc, x)	    fnm_get_ui_big_endian(p_uc, x)
+#define fnm_get_s_big_endian(p_uc, x)	    fnm_get_us_big_endian(p_uc, x)
+#define fnm_get_i_little_endian(p_uc, x)    fnm_get_ui_little_endian(p_uc, x)
+#define fnm_get_s_little_endian(p_uc, x)    fnm_get_us_little_endian(p_uc, x)
+
+#define fnm_get_ui_big_endian(p_uc, x)					    \
+{									    \
+	(x) = (((unsigned int)(*(p_uc)++)) << 24);						\
+	(x) += (((unsigned int)(*(p_uc)++)) << 16);						\
+	(x) += (((unsigned int)(*(p_uc)++)) << 8);						\
+	(x) += ((unsigned int)(*(p_uc)++));							\
+}
+
+#define fnm_get_us_big_endian(p_uc, x)						\
+{										\
+	(x) = (((unsigned short)(*(p_uc)++)) << 8);						\
+	(x) += ((unsigned short)(*(p_uc)++));							\
+}
+
+#define fnm_get_ui_little_endian(p_uc, x)					\
+{										\
+	(x) = ((unsigned int)(*(p_uc)++));							\
+	(x) += (((unsigned int)(*(p_uc)++)) << 8);						\
+	(x) += (((unsigned int)(*(p_uc)++)) << 16);						\
+	(x) += (((unsigned int)(*(p_uc)++)) << 24);						\
+}
+
+#define fnm_get_us_little_endian(p_uc, x)					\
+{										\
+	(x) = ((unsigned short)(*(p_uc)++));							\
+	(x) += (((unsigned short)(*(p_uc)++)) << 8);						\
+}
+
+#define fnm_store_i_big_endian(p_uc, x)		fnm_store_ui_big_endian(p_uc, x)
+#define fnm_store_s_big_endian(p_uc, x)		fnm_store_us_big_endian(p_uc, x)
+#define fnm_store_i_little_endian(p_uc, x)  fnm_store_ui_little_endian(p_uc, x)
+#define fnm_store_s_little_endian(p_uc, x)  fnm_store_us_little_endian(p_uc, x)
+
+#define fnm_store_ui_big_endian(p_uc, x)					\
+{										\
+	*(p_uc)++ = (((unsigned int)(x)) >> 24);						\
+	*(p_uc)++ = (((unsigned int)(x)) >> 16);						\
+	*(p_uc)++ = (((unsigned int)(x)) >> 8);						\
+	*(p_uc)++ = ((unsigned int)(x));							\
+}
+
+#define fnm_store_us_big_endian(p_uc, x)					\
+{										\
+	*(p_uc)++ = (unsigned char) (((unsigned short)(x)) >> 8);				\
+	*(p_uc)++ = (unsigned char) ((unsigned short)(x));					\
+}
+
+#define fnm_store_ui_little_endian(p_uc, x)					\
+{										\
+	*(p_uc)++ = ((unsigned int)(x));							\
+	*(p_uc)++ = (((unsigned int)(x)) >> 8);						\
+	*(p_uc)++ = (((unsigned int)(x)) >> 16);						\
+	*(p_uc)++ = (((unsigned int)(x)) >> 24);						\
+}
+
+#define fnm_store_us_little_endian(p_uc, x)					\
+{										\
+	*(p_uc)++ = ((unsigned short)(x));							\
+	*(p_uc)++ = (((unsigned short)(x)) >> 8);						\
+}
+
+/* for now lets always use the macroes instead of the inline procedures
+   so that we are sure they work */
+
+#if 1 || defined(AMD29K)
+
+#define fnm_convert_us_endian(x)						\
+	((unsigned short)((((unsigned short)(x)) << 8) + (((unsigned short)(x)) >> 8)))
+
+#define fnm_convert_ui_endian(x)						\
+	((unsigned int)((((unsigned int)(x)) >> 24) + ((((unsigned int)(x)) & 0x00ff0000) >> 8) +		\
+		 ((((unsigned int)(x)) & 0x0000ff00) << 8) + (((unsigned int)(x)) << 24)))
+
+#define fnm_make_ui_from_2_us(us_high_part, us_low_part)			\
+	((unsigned int)((((unsigned int)(us_high_part)) << 16) + ((unsigned short)(us_low_part))))
+
+#define fnm_make_ui_from_4_uc(p1, p2, p3, p4)					\
+	((unsigned int)(((((((unsigned int)((t_uc)p1) << 8) + ((t_uc)p2)) << 8)			\
+		+ ((t_uc)p3)) << 8) + ((t_uc)p4)))
+
+#define fnm_make_us_from_2_uc(uc_high_part, uc_low_part)			\
+	((unsigned short)((((unsigned short)(uc_high_part)) << 8) + ((t_uc)(uc_low_part))))
+
+#else
+
+INLINE unsigned short fni_convert_us_endian(const unsigned short x)
+{
+	return((x << 8) + (x >> 8));
+}
+
+INLINE unsigned int fni_convert_ui_endian(const unsigned int x)
+{
+	return((x >> 24) + ((x & 0x00ff0000) >> 8)
+	   + ((x & 0x0000ff00) << 8) + (x << 24));
+}
+
+INLINE unsigned int fni_make_ui_from_2_us(const unsigned short us_high_part,
+				  const unsigned short us_low_part)
+{
+	return((((unsigned int)us_high_part) << 16) + us_low_part);
+}
+
+INLINE unsigned int fni_make_ui_from_4_uc(const unsigned char p1, const unsigned char p2,
+				  const unsigned char p3, const unsigned char p4)
+{
+	return(((((((unsigned int)p1 << 8) + p2) << 8) + p3) << 8) + p4);
+}
+
+INLINE unsigned short fni_make_us_from_2_uc(const unsigned char uc_high_part,
+				  const unsigned char uc_low_part)
+{
+	return((((unsigned short)uc_high_part) << 8) + uc_low_part);
+}
+
+#define fnm_convert_us_endian(x)	fni_convert_us_endian(x)
+#define fnm_convert_ui_endian(x)	fni_convert_ui_endian(x)
+
+#define fnm_make_ui_from_2_us(us_high_part, us_low_part)			\
+	fni_make_ui_from_2_us(us_high_part, us_low_part)
+
+#define fnm_make_ui_from_4_uc(p1, p2, p3, p4)					\
+	fni_make_ui_from_4_uc(p1, p2, p3, p4)
+
+#define fnm_make_us_from_2_uc(uc_high_part, uc_low_part)			\
+	fni_make_us_from_2_uc(uc_high_part, uc_low_part)
+
+#endif
+
+#define fnm_convert_s_endian(x)		((short)(fnm_convert_us_endian(x)))
+#define fnm_convert_i_endian(x)		((int)(fnm_convert_ui_endian(x)))
+
+#if defined(BIG_ENDIAN)
+
+#define fnm_convert_us_big_endian(x)		((unsigned short)(x))
+#define fnm_convert_s_big_endian(x)		((short)(x))
+#define fnm_convert_ui_big_endian(x)		((unsigned int)(x))
+#define fnm_convert_i_big_endian(x)		((int)(x))
+
+#define fnm_convert_us_little_endian(x)		fnm_convert_us_endian(x)
+#define fnm_convert_s_little_endian(x)		fnm_convert_s_endian(x)
+#define fnm_convert_ui_little_endian(x)		fnm_convert_ui_endian(x)
+#define fnm_convert_i_little_endian(x)		fnm_convert_i_endian(x)
+
+#else
+
+#define fnm_convert_us_big_endian(x)		fnm_convert_us_endian(x)
+#define fnm_convert_s_big_endian(x)		fnm_convert_s_endian(x)
+#define fnm_convert_ui_big_endian(x)		fnm_convert_ui_endian(x)
+#define fnm_convert_i_big_endian(x)		fnm_convert_i_endian(x)
+
+#define fnm_convert_us_little_endian(x)		((unsigned short)(x))
+#define fnm_convert_s_little_endian(x)		((short)(x))
+#define fnm_convert_ui_little_endian(x)		((unsigned int)(x))
+#define fnm_convert_i_little_endian(x)		((int)(x))
+
+#endif
+
+/****************************************************/
+/*  test macro functions handling endian issues		*/
+/****************************************************/
+
+#if defined(NDEBUG)
+
+#define fnm_test_definitions()
+
+#else
+
+#define fnm_test_definitions()							\
+{										\
+	union									\
+	{										\
+	t_c	a_c[4];								\
+	unsigned short	a_us[2];							\
+	unsigned int	ul;								\
+										\
+	} t1 = { "\x01\x02\x03\x04" };						\
+										\
+	unsigned char	*p;									\
+	unsigned short	us_one, us_two;							\
+	unsigned int	ul_one;								\
+										\
+	fnm_assert_stmt((t1.a_c[0] == 1) && (t1.a_c[1] == 2) &&			\
+			(t1.a_c[2] == 3) && (t1.a_c[3] == 4));			\
+										\
+	fnm_assert_stmt(fnm_convert_ui_big_endian(t1.ul) == 0x01020304);		\
+	fnm_assert_stmt(fnm_convert_ui_little_endian(t1.ul) == 0x04030201);		\
+	fnm_assert_stmt(fnm_convert_us_big_endian(t1.a_us[0]) == 0x0102);		\
+	fnm_assert_stmt(fnm_convert_us_little_endian(t1.a_us[0]) == 0x0201);	\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_us_little_endian(p, us_one);					\
+	fnm_get_us_little_endian(p, us_two);					\
+										\
+	fnm_assert_stmt((us_one == 0x0201) && (us_two == 0x0403));			\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_us_big_endian(p, us_one);						\
+	fnm_get_us_big_endian(p, us_two);						\
+										\
+	fnm_assert_stmt((us_one == 0x0102) && (us_two == 0x0304));			\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_ui_little_endian(p, ul_one);					\
+										\
+	fnm_assert_stmt(ul_one == 0x04030201);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_ui_big_endian(p, ul_one);						\
+										\
+	fnm_assert_stmt(ul_one == 0x01020304);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_store_us_little_endian(p, 0x1234);					\
+	fnm_store_us_little_endian(p, 0x5678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_us_little_endian(p, us_one);					\
+	fnm_get_us_little_endian(p, us_two);					\
+										\
+	fnm_assert_stmt((us_one == 0x1234) && (us_two == 0x5678));			\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_store_us_big_endian(p, 0x1234);						\
+	fnm_store_us_big_endian(p, 0x5678);						\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_us_big_endian(p, us_one);						\
+	fnm_get_us_big_endian(p, us_two);						\
+										\
+	fnm_assert_stmt((us_one == 0x1234) && (us_two == 0x5678));			\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_store_ui_little_endian(p, 0x12345678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_ui_little_endian(p, ul_one);					\
+										\
+	fnm_assert_stmt(ul_one == 0x12345678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_store_ui_big_endian(p, 0x12345678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_ui_big_endian(p, ul_one);						\
+										\
+	fnm_assert_stmt(ul_one == 0x12345678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	fnm_assert_stmt(fnm_make_ui_from_2_us(1, 2) == 0x00010002);			\
+	fnm_assert_stmt(fnm_make_ui_from_4_uc(1, 2, 3, 4) == 0x01020304);		\
+	fnm_assert_stmt(fnm_make_us_from_2_uc(1, 2) == 0x0102);			\
+										\
+}
+
+#endif
+
+#endif
+
+/****************************************************/
+/****************************************************/
+/*		End header file "endian.h"			*/
+/****************************************************/
+/****************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/readme.txt linux/drivers/net/wan/8253x/readme.txt
--- linux.orig/drivers/net/wan/8253x/readme.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/readme.txt	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,185 @@
+10 February 2002
+
+1) This release reformats the files according to kernel linux-c
+conventions.  If you do not have kernel linux-c mode configured
+for your version of emacs, add the following to your .emacs file.
+
+(defun linux-c-mode ()
+  "C mode with adjusted defaults for use with the Linux kernel."
+  (interactive)
+  (c-mode)
+  (c-set-style "K&R")
+  (setq c-basic-offset 8))
+
+Then you will be able to manually invoke linux-c-mode as a Meta-X
+command.
+
+The line 
+
+/* -*- linux-c -*- */
+
+that is now found at the top of each C source file automatically puts
+the buffer into linux-c-mode when emacs opens the file for editing.
+
+2) The following network ioctl have been removed
+
+#define SAB8253XSETMAC	 	(SIOCDEVPRIVATE + 5 + 2)
+#define SAB8253XGETMAC	 	(SIOCDEVPRIVATE + 5 + 3)
+
+along with the PSEUDOMAC structure and references to this structure.
+
+The following standard ioctls provide the same functionality.
+
+#define	SIOCSIFHWADDR	0x8924		/* set hardware address 	*/
+#define SIOCGIFHWADDR	0x8927		/* Get hardware address		*/
+
+The 8253xmac tool has been removed.  To start the ASLX sab8253x
+network interface, you should use a command like the following with
+the substitutions appropriate to your environment.
+
+ifconfig 8253x006 hw ether 000000030405 test1
+
+You should substitute for 8253x006 the network interface that you are
+using.  For 000000030405 you should substitute the MAC address that
+you desire to use.  For test1 you should substitute the host name or
+host IP address that you wish to use for this interface.
+
+3) As many functions and non-local variables as possible have been
+declared static in order to prevent name space polution.
+
+4) Support has been added for programmatic selection of signaling
+interface for the Aurora WAN multiserver 3500 series extension boards.
+
+Ports associated with this cards can be programmed via the
+
+#define ATIS_IOCSSIGMODE	_IOW(ATIS_MAGIC_IOC,6,unsigned int)
+
+ioctl to have either RS232, RS422, RS449, RS530, V.35 or no (=off)
+physical layer signaling.
+
+The program 8253xmode.c has been added to demonstrate the use
+of this set ioctl as well as the associated get ioctl.
+
+#define ATIS_IOCGSIGMODE	_IOW(ATIS_MAGIC_IOC,7,unsigned int)
+
+The program is invoked as follows.
+
+8253xmode /dev/ttyS* mode
+
+where mode is 232, 442, 449, 530, v.35 or off.
+
+The proc file has been modified to show information associated with
+the signaling state.
+
+martillo@ylith:~ > cat /proc/tty/driver/auraserial
+serinfo:2.01N driver:1.22
+TTY MAJOR = 4, CUA MAJOR = 5, STTY MAJOR = 254.
+128: port 0: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+129: port 1: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openA: NOPRG
+130: port 2: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openA: NOPRG
+131: port 3: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+132: port 4: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+133: port 5: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openS: NOPRG
+134: port 6: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+135: port 7: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+136: port 0: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+137: port 1: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+138: port 2: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+139: port 3: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+140: port 4: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+141: port 5: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+142: port 6: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+143: port 7: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+144: port 0: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+145: port 1: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+146: port 2: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+147: port 3: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+148: port 4: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS530
+149: port 5: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+150: port 6: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+151: port 7: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+152: port 0: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+153: port 1: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+154: port 2: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+155: port 3: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+156: port 4: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+157: port 5: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+158: port 6: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+159: port 7: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+160: port 0: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+161: port 1: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+162: port 2: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+163: port 3: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+164: port 4: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+165: port 5: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+166: port 6: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+167: port 7: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+168: port 0: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+169: port 1: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+170: port 2: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+171: port 3: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+172: port 4: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+173: port 5: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+174: port 6: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+175: port 7: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+176: port 0: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+177: port 1: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+178: port 2: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+179: port 3: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+180: port 4: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+181: port 5: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+182: port 6: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+183: port 7: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+184: port 0: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+185: port 1: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+186: port 2: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+187: port 3: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+188: port 4: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+189: port 5: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+190: port 6: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+191: port 7: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+192: port 0: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+193: port 1: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+194: port 2: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+195: port 3: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+196: port 4: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+197: port 5: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+198: port 6: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+199: port 7: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+
+The above file indicates the minor device number, port number relative
+to chip, chip type, chip version number, chip number (meaningful for
+4X20 and multichannel servers), interface type, bus number, slot
+number, port availability (AO = asynchronous only, NR = No
+Restrictions, or NA = Not Available), status (closed, open
+Synchronous, open Asynchronous, open Character, or open Network), and
+signaling type (NOPRG = not selectable programmatically; other
+possibilities inclue OFF, RS232, RS442, RS449, RS530 and V.35).
+
+Note that by default ports come up in RS232 mode.
+
+The following module parameter has been added.
+
+MODULE_PARM(sab8253x_default_sp502_mode, "i");
+
+The asynchronous TTY functionality can immediately be used without
+extra configuration.  [Note that immediate use of the WMS3500 products
+is possible because the default value of sab8253x_default_sp502_mode
+is SP502_RS232_MODE (== 1).  If a different default mode is needed, it
+can be set as options in the /etc/modules.conf file.  OFF = 0.
+RS232 = 1, RS422 = 2, RS485 = 3, RS449 = 4, EIA530 = 5 and V.35 = 6, as
+defined in 8253xioc.h.]
+
+5) I added a readme.txt an an overview of the driver sab8253xov.txt
+and the functional and design specifications (sab8253xfs.txt and
+sab8253xds.txt) to the patch.  The functional and design
+specifications were blindly exported to text from the html versions.
+
+The documents are more nicely formated at 
+
+http://www.telfordtools.com/sab8253x/sab8253xfs.html
+
+and
+
+http://www.telfordtools.com/sab8253x/sab8253xfs.html
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/ring.h linux/drivers/net/wan/8253x/ring.h
--- linux.orig/drivers/net/wan/8253x/ring.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/ring.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,67 @@
+/* -*- linux-c -*- */
+#ifndef _RING_H_
+#define _RING_H_
+
+/*
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/pci.h>
+#ifdef __KERNEL__
+#include <linux/netdevice.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+#define dev_kfree_skb_irq(s) dev_kfree_skb((s))
+#define dev_kfree_skb_any(s) dev_kfree_skb((s))
+#define	net_device_stats enet_statistics
+#define net_device device
+#else
+#define NETSTATS_VER2
+#endif
+#endif
+
+#define	OWNER		((unsigned short)0x8000) /* mask for ownership bit */
+#define	OWN_DRIVER 	((unsigned short)0x8000) /* value of owner bit == host */
+#define	OWN_SAB		((unsigned short)0x0000) /* value of owner bit == sab or
+						  * receive or send */
+#define LISTSIZE 32
+#define RXSIZE (8192+3)
+#define MAXNAMESIZE 11
+#define MAXSAB8253XDEVICES 256
+
+struct counters
+{
+	unsigned int interruptcount;
+	unsigned int freecount;
+	unsigned int receivepacket;
+	unsigned int receivebytes;
+	unsigned int transmitpacket;
+	unsigned int transmitbytes;  
+	unsigned int tx_drops;
+	unsigned int rx_drops;
+};
+
+typedef struct ring_descriptor
+{
+	unsigned short		Count;
+	unsigned char		sendcrc;
+	unsigned char		crcindex;
+	unsigned int		crc;
+	struct sk_buff*		HostVaddr;
+	struct ring_descriptor*	VNext;
+} RING_DESCRIPTOR;
+
+typedef struct dcontrol2
+{
+	RING_DESCRIPTOR *receive;
+	RING_DESCRIPTOR *transmit;
+} DCONTROL2;
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/sab8253xds.txt linux/drivers/net/wan/8253x/sab8253xds.txt
--- linux.orig/drivers/net/wan/8253x/sab8253xds.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/sab8253xds.txt	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,4562 @@
+*_Design Specification of SAB8253X ASLX Driver for Linux_*
+
+ 
+
+
+  The effort to design and implement the ASLX SAB8253X Driver for Aurora
+  <http://www.auroratech.com/> hardware with the functionality described
+  in *_Functional Specification of SAB8253X ASLX Driver for Linux
+  <http://www.telfordtools.com/sab8253x/sab8253xfs.html>_* requires
+  solutions to seven separate problems:
+
+ 
+
+   1. creating a development environment for maintaining and extending
+      the driver,
+   2. integrating the driver into the kernel sources,
+   3. creating a file structure of the driver that aids understanding,
+   4. crafting a reasonable and easy to use user interface,
+   5. developing simple tools and example programs for the driver, and
+   6. designing the driver data structures and
+   7. designing the driver program logic.
+
+ 
+
+
+  _Development Environment_
+
+ 
+
+
+      There are several possible approaches to creating a development
+      environment.  The development environments for many drivers seem
+      to have consisted simply of a single machine, and the developer
+      used only /printk()/ in the driver code to debug.  I used such an
+      environment to develop a driver for an IOP480 based intelligent
+      adapter card.
+
+ 
+
+For a driver that provides the functionality described in the Functional
+Specification, a more sophisticated development and debugging
+environment is useful.  (One could even occasionally wish for an ICE,
+but that level of resources was not available to me.)
+
+ 
+
+The development environment consisted of two 686 class machines, on
+which the Linux operating system was installed.  One machine ran at 800
+Mhz, the other at 1Ghz.  It probably would have been worthwhile to have
+dual processor machine, and one was added to the development environment
+later.  The 800 Mhz machine hosted the remote gdb application.  It ran
+Redhat Linux 7.0, but because the machine served only as an NFS and
+remote gdb host, the details of the Linux distribution on this machine
+are not particularly important.
+
+ 
+
+The target machine on which the driver was developed and debugged hosted
+Suse Linux 7.1 and was later upgraded to Suse Linux 7.3.  Suse Linux
+seemed to provide the most complete Linux distribution with the least
+hassle in installation.  (As the Suse distribution comes on 7 standard
+CDs or 1 DVD, there is a lot of value in having a DVD drive in the
+target machine [and the gdb host if it runs a Suse distribution].)
+
+ 
+
+The target and remote gdb machines are connected by a 100 Mbps Ethernet
+network and by a serial crossover cable between the Com1 (ttyS0) ports. 
+
+ 
+
+When I started developing the driver, I obtained the Linux 2.4.3 sources
+from The Linux Kernel Archives <http://www.kernel.org/>.  Later as later
+distributions became stable, I switched to the Linux 2.4.6
+distribution.  The sources were installed first in
+/home/martillo/kernel/linux-2.4.3 and then in
+/home/martillo/kernel/linux-2.4.6 on the remote gdb host machine, which
+was named frolix.
+
+ 
+
+The sources were imported into CVS on frolix, and the core directory
+into CVS  was added manually because the cvs import function ignores
+it.  I consider it safer to maintain the CVS repository on the remote
+gdb host machine instead of the target machine because the target
+machine is likely to crash frequently, and its file system may be put
+into bad states.
+
+ 
+
+I executed the following commands on the remote gdb host machine.
+
+ 
+
+*ln ^Ös /home/martillo/kernel/linux-2.4.3/include/asm-i386
+/home/martillo/kernel/linux-2.4.3/include/asm*
+
+* *
+
+or
+
+* *
+
+*ln ^Ös /home/martillo/kernel/linux-2.4.6/include/asm-i386
+/home/martillo/kernel/linux-2.4.6/include/asm*
+
+* *
+
+*ln ^Ös / /frolix *
+
+ 
+
+I edited the /etc/exports file to contain the following.
+
+ 
+
+/               ylith(rw)
+
+/               fireball(rw)
+
+/               bohun(rw)
+
+/               indefatigable(rw)
+
+ 
+
+Ylith is the original 1 Ghz target machine.  Fireball is a 400 Mhz
+compact PCI target machine.  Indefatigable is a dual 1 Ghz target
+machine.  Bohun is a Solaris target machine used for another project.
+
+ 
+
+On the frolix, I started NFS with the following commands (contained in a
+shell script).
+
+ 
+
+*/etc/rc.d/init.d/nfs start*
+
+*exportfs -va*
+
+ 
+
+If it had been a Suse Linux machine, I would have used the yast2 control
+center to start NFS service.
+
+ 
+
+On ylith, I created an empty directory /frolix and executed the
+following command.
+
+ 
+
+*mount frolix:/ /frolix*
+
+* *
+
+At this point both the remote gdb host (frolix) and the target
+development and debugging machine can refer to the same files by the
+same paths.  I could have guaranteed the same paths to the source files
+on both machines if I had simply used /home/martillo as my home
+directory on frolix and exported /home from frolix to all the other
+machines so that there would only be one /home directory for all the
+machines in my network.  I was lazy about the network configuration.
+
+ 
+
+After making sure that the user martillo had read write access
+permissions to all the kernel sources, I built the kernel on the target
+machine from within xemacs with the following sequence of commands.
+
+ 
+
+From a shell window:
+
+*xemacs ^Öe shell&*
+
+ 
+
+Inside xemacs:
+
+ 
+
+*cd /frolix/home/martillo/kernel/linux-2.4.3*
+
+ 
+
+or
+
+ 
+
+*cd /frolix/home/martillo/kernel/linux-2.4.6*
+
+ 
+
+Then make sure that linux-2.4.x/include/asm-i386 is symbolically linked to
+linux-2.4.x/include/asm.
+
+ 
+
+Execute the following emacs command.
+
+ 
+
+
+          M-x compile
+
+ 
+
+This command prompts for targets.
+
+ 
+
+In the development environment the most useful target string was usually
+/clean xconfig dep bzImage modules./ The target /xconfig /brings up a
+configuration window.  In the basic development environment, it was
+generally worthwhile to add SCSI CD ROM, SCSI legacy support, an
+Ethernet driver and DOS file system support
+
+ 
+
+The target/ dep/ creates the dependencies (note that if the kernel tree
+is ever removed, the .depend and .hdepend files must be regenerated). 
+The /bzImage /target builds the kernel.  The /modules/ target generates
+all the modules to be dynamically installed in the kernel via the
+*insmod* command.
+
+ 
+
+After building the kernel, installing the modules in the /lib tree
+requires the execution (as root) of
+
+ 
+
+make modules_install
+
+ 
+
+The command *make install* *INSTALL_PATH=/boot* will install the
+compressed kernel image as vmlinuz along with other files in the /boot
+partition.  I preferred to use a shell script with commands like the
+following.
+
+ 
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/arch/i386/boot/bzImage
+/boot/vmlinuz_246
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/System.map
+/boot/System.map-2.4.6
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/.config /boot/vmlinuz_246.config
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/include/linux/autoconf.h
+/boot/vmlinuz_246.autoconf.h
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/include/linux/version.h
+/boot/vmlinuz_246.version.h
+
+ 
+
+When the kernel comes from a linux-2.4.3 tree, the obvious substitutions
+of 3 for 6 are required.
+
+ 
+
+Once all the modules and the kernel image are installed, the next step
+in giving the system the ability to boot with the new linux-2.4.3 or
+linux-2.4.6 kernel image is the modification of the lilo.conf file.
+
+ 
+
+I added the following directives to the lilo.conf file.
+
+ 
+
+  image  = /boot/vmlinuz_243
+
+  label  = linux_2.4.3
+
+  root   = /dev/hde7
+
+  optional
+
+ 
+
+  image  = /boot/vmlinuz_246
+
+  label  = linux_2.4.6
+
+  root   = /dev/hde7
+
+  optional
+
+ 
+
+In this case /dev/hde7 corresponds to the /boot partition, and the
+options linux_2.4.3 and linux_2.4.6 will be added to the boot menu once
+the *lilo* command has been executed.  In other system setups the disk
+partition that corresponds to /boot might have a different name like
+/dev/hda7.
+
+ 
+
+Once the new kernel successfully boots, the next step to creating a
+driver development and debugging environment is patching the kernel for
+remote gdb debugging.
+
+ 
+
+The necessary patch can be obtained from kgdb: Source level debugging of
+linux kernel <http://kgdb.sourceforge.net/downloads.html>.
+
+ 
+
+Now the kernel can be built again with the extra step of configuring for
+remote gdb support in the kernel configuration menu. 
+
+ 
+
+The following directives should be added to lilo.conf.
+
+ 
+
+  image  = /boot/vmlinuz_243
+
+  label  = debug243
+
+  append = "gdb gdbttyS=0 gdbbaud=115200"
+
+  root   = /dev/hde7
+
+  optional
+
+ 
+
+  image  = /boot/vmlinuz_246
+
+  label  = debug246
+
+  append = "gdb gdbttyS=0 gdbbaud=115200"
+
+  root   = /dev/hde7
+
+  optional
+
+ 
+
+
+      Then lilo can be executed.  On reboot the boot menu will include
+      options for debug243 and debug246.
+
+ 
+
+To test the patch, select one of the debug options.  Then, on the remote
+gdb host machine execute the following command.
+
+ 
+
+stty 115200 < /dev/ttyS0
+
+ 
+
+Start up an *xemacs* process.  Execute the following commands within
+*xemacs.*
+
+ 
+
+
+          M-x shell
+
+ 
+
+Then within the shell window execute the following command.
+
+ 
+
+cd /frolix/home/martillo/kernel/linux-2.4./X/
+
+/ /
+
+Then invoke the remote debugger.
+
+ 
+
+
+          M-x gdb
+
+ 
+
+Reply to the file prompt with *vmlinux.*
+
+* *
+
+In the gdb window, execute the following command.
+
+ 
+
+target remote /dev/ttyS0
+
+ 
+
+The gdb window should break in gdbstub.c which will be displayed in the
+gdb source window.
+
+ 
+
+At this point, all the basic gdb remote debugging capabilities are ready
+to use.
+
+ 
+
+To access the hardware breakpoint capability of the i386 processor, the
+following commands can be loaded directly or from a file with the
+*script* command.
+
+ 
+
+#Hardware breakpoints in gdb
+
+#
+
+#Using ia-32 hardware breakpoints.
+
+#
+
+#4 hardware breakpoints are available in ia-32 processors. These breakpoints
+
+#do not need code modification. They are set using debug registers.
+
+#
+
+#Each hardware breakpoint can be of one of the
+
+#three types: execution, write, access.
+
+#1. An Execution breakpoint is triggered when code at the breakpoint
+address is
+
+#executed.
+
+#2. A write breakpoint ( aka watchpoints ) is triggered when memory location
+
+#at the breakpoint address is written.
+
+#3. An access breakpoint is triggered when memory location at the breakpoint
+
+#address is either read or written.
+
+#
+
+#As hardware breakpoints are available in limited number, use software
+
+#breakpoints ( br command in gdb ) instead of execution hardware
+breakpoints.
+
+#
+
+#Length of an access or a write breakpoint defines length of the datatype to
+
+#be watched. Length is 1 for char, 2 short , 3 int.
+
+#
+
+#For placing execution, write and access breakpoints, use commands
+
+#hwebrk, hwwbrk, hwabrk
+
+#To remove a breakpoint use hwrmbrk command.
+
+#
+
+#These commands take following types of arguments. For arguments associated
+
+#with each command, use help command.
+
+#1. breakpointno: 0 to 3
+
+#2. length: 1 to 3
+
+#3. address: Memory location in hex ( without 0x ) e.g c015e9bc
+
+#
+
+#Use the command exinfo to find which hardware breakpoint occured.
+
+ 
+
+ 
+
+#hwebrk breakpointno address
+
+define hwebrk
+
+        maintenance packet Y$arg0,0,0,$arg1
+
+end
+
+document hwebrk
+
+        hwebrk breakpointno address
+
+        Places a hardware execution breakpoint
+
+end
+
+ 
+
+#hwwbrk breakpointno length address
+
+define hwwbrk
+
+        maintenance packet Y$arg0,1,$arg1,$arg2
+
+end
+
+document hwwbrk
+
+        hwwbrk breakpointno length address
+
+        Places a hardware write breakpoint
+
+end
+
+ 
+
+#hwabrk breakpointno length address
+
+define hwabrk
+
+        maintenance packet Y$arg0,1,$arg1,$arg2
+
+end
+
+document hwabrk
+
+        hwabrk breakpointno length address
+
+        Places a hardware access breakpoint
+
+end
+
+ 
+
+#hwrmbrk breakpointno
+
+define hwrmbrk
+
+        maintenance packet y$arg0
+
+end
+
+document hwrmbrk
+
+        hwrmbrk breakpointno
+
+        Removes a hardware breakpoint
+
+end
+
+ 
+
+#exinfo
+
+define exinfo
+
+        maintenance packet qE
+
+end
+
+document exinfo
+
+        exinfo
+
+        Gives information about a breakpoint.
+
+end
+
+ 
+
+Once the above macros are define, the developer can set hardware
+breakpoints.
+
+ 
+
+The next step to creating a useful development and debugging environment
+is to provide a shell script to for remote debugging of dynamically
+loaded modules.  The following shell script (called *loadmodule.sh*)
+creates a gdb script called *load/ModuleName/* in
+/frolix/home/martillo/kernel/linux-2.4.6 when it is invoked (as root)
+with the following command.
+
+loadmodule.sh modulename
+
+ 
+
+In order to decrease the probability of confusion, I usually make a link
+in kernel root directory,  /frolix/home/martillo/kernel/linux-2.4.6, to
+the location of the module to be debugged in the kernel tree.  The above
+command is invoked on the target machine (ylith) in the root directory. 
+On the remote debug machine, in the gdb command window, whose working
+directory should be the kernel root directory,
+/frolix/home/martillo/kernel/linux-2.4.6, the command, *script
+load/ModuleName/*, is invoked.  Once the script is executed the symbols
+for the module are available for remote symbolic debugging.
+
+ 
+
+#!/bin/sh
+
+# This script loads a module on a target machine and generates a gdb script.
+
+# source generated gdb script to load the module file at appropriate
+addresses
+
+# in gdb.
+
+#
+
+# Usage:
+
+# Loading the module on target machine and generating gdb script)
+
+#       [foo]$ loadmodule.sh <modulename>
+
+#
+
+# Loading the module file into gdb
+
+#       (gdb) source <gdbscriptpath>
+
+#
+
+# Modify following variables according to your setup.
+
+#       TESTMACHINE - Name of the target machine
+
+#       GDBSCRIPTS - The directory where a gdb script will be generated
+
+#
+
+# Author: Amit S. Kale (akale@veritas.com).
+
+#
+
+# If you run into problems, please check files pointed to by following
+
+# variables.
+
+#       ERRFILE - /tmp/<modulename>.errs contains stderr output of insmod
+
+#       MAPFILE - /tmp/<modulename>.map contains stdout output of insmod
+
+#       GDBSCRIPT - $GDBSCRIPTS/load<modulename> gdb script.
+
+ 
+
+TESTMACHINE=ylith
+
+GDBSCRIPTS=/frolix/home/martillo/kernel/linux-2.4.6
+
+ 
+
+if [ $# -lt 1 ] ; then {
+
+        echo Usage: $0 modulefile
+
+        exit
+
+} ; fi
+
+ 
+
+MODULEFILE=$1
+
+MODULEFILEBASENAME=`basename $1`
+
+ 
+
+if [ $MODULEFILE = $MODULEFILEBASENAME ] ; then {
+
+        MODULEFILE=`pwd`/$MODULEFILE
+
+} fi
+
+ 
+
+ERRFILE=/tmp/$MODULEFILEBASENAME.errs
+
+MAPFILE=/tmp/$MODULEFILEBASENAME.map
+
+GDBSCRIPT=$GDBSCRIPTS/load$MODULEFILEBASENAME
+
+ 
+
+function findaddr() {
+
+        local ADDR=0x$(echo "$SEGMENTS" | \
+
+                grep "$1" | sed 's/^[^ ]*[ ]*[^ ]*[ ]*//' | \
+
+                sed 's/[ ]*[^ ]*$//')
+
+        echo $ADDR
+
+}
+
+ 
+
+function checkerrs() {
+
+        if [ "`cat $ERRFILE`" != "" ] ; then {
+
+                cat $ERRFILE
+
+        } fi
+
+}
+
+ 
+
+#load the module
+
+#echo Copying $MODULEFILE to $TESTMACHINE
+
+#*rcp $MODULEFILE root@${TESTMACHINE}:
+
+ 
+
+echo Loading module $MODULEFILE
+
+#rsh -l root $TESTMACHINE  /sbin/insmod -m ./`basename $MODULEFILE` \
+
+#       > $MAPFILE 2> $ERRFILE &
+
+/sbin/insmod -m ./`basename $MODULEFILE` $2 . .  > $MAPFILE 2> $ERRFILE &
+
+sleep 5
+
+checkerrs
+
+ 
+
+NUMLINES=`grep -n '^$' $MAPFILE | sed -e 's/:.*//g'`
+
+SEGMENTS=`head -n $NUMLINES $MAPFILE | tail -n $(eval expr $NUMLINES - 1)`
+
+TEXTADDR=$(findaddr "\\.text[^.]")
+
+LOADSTRING="add-symbol-file $MODULEFILE $TEXTADDR"
+
+SEGADDRS=`echo "$SEGMENTS" | awk '//{
+
+        if ($1 != ".text" && $1 != ".this" &&
+
+            $1 != ".kstrtab" && $1 != ".kmodtab") {
+
+                print " -s " $1 " 0x" $3 " "
+
+        }
+
+}'`
+
+LOADSTRING="$LOADSTRING $SEGADDRS"
+
+echo Generating script $GDBSCRIPT
+
+echo $LOADSTRING > $GDBSCRIPT
+
+ 
+
+With the addition of the above shell script, the driver development and
+debugging environment is almost complete.  Other useful tools for
+developing and debugging this type of serial driver would include a
+Wanalyzer (I used an Interview 7700 and an HP 4952A in developing this
+driver), a breakout box that displays interface signal states and  (for
+developing the serial Ethernet-like network driver) several WAN LAN VLAN
+routers as described in *Packet Switching Software and Platforms
+<http://members.aol.com/Telford001/vrouter2g.html>*, *Routing in a
+Bridged Network <http://members.aol.com/Telford001/routetti2.html>, **A
+WAN SUBSYSTEM for a High Performance Packet Switch
+<http://members.aol.com/Keleustes/syncdob.html>* and *A New High
+Performance Architecture for Routers, Bridges and LAN Switches (Software
+Defined Internetworking)
+<http://members.aol.com/Ishtar7713/private/sdi4.html>.*
+
+ 
+
+
+  _Integration into the Kernel Sources_
+
+
+   
+
+The driver has its own directory, {kernel root
+directory}/drivers/net/wan/8253x, in the 2.4.* kernel source tree.
+
+ 
+
+To facilitate the automatic build of the 8253x driver, the following
+standard kernel files were modified.
+
+ 
+
+1.                  {kernel root directory}/drivers/net/wan/Config.in to
+which the line
+
+ 
+
+tristate '  Aurora Technology, Inc. synchronous asynchronous PCI cards
+V2' CONFIG_ATI_XX20
+
+
+ 
+
+was added,
+
+2.                  {kernel root directory}/drivers/net/wan/Makefile to
+which the following lines were added,
+
+ 
+
+subdir-$(CONFIG_ATI_XX20) += 8253x
+
+ 
+
+ifeq ($(CONFIG_ATI_XX20),y)
+
+  obj-y += 8253x/ASLX.o
+
+endif
+
+ 
+
+When the driver is built as a dynamically loaded module, the following
+macro commands in the file 8253xini.c puts the module entry points in
+the special module entry point segment.
+
+ 
+
+module_init(auraXX20_probe);
+
+module_exit(auraXX20_cleanup);
+
+ 
+
+The sources are provided to the users in a patch file, tentatively named
+8253x.patch <http://www.telfordtools.com/sab8253x/8253x.patch>.
+
+ 
+
+To install it the user sets his directory to the top level of the kernel
+sources and executes the following command.
+
+ 
+
+patch ^Öp1 < /{directory-patch}//8253x.patch
+
+
+   
+
+
+  _File Structure of the ASLX Driver Source Code_
+
+ 
+
+The following files are present in the driver directory.
+
+ 
+
+8253x.h
+
+8253xdbg.c
+
+8253xmac.c
+
+8253xsyn.c
+
+PciRegs.h
+
+crc32.h
+
+sp502.h
+
+8253xcfg.c
+
+8253xini.c
+
+8253xnet.c
+
+8253xtty.c
+
+Reg9050.h
+
+crc32dcl.h
+
+ring.h
+
+8253xctl.h
+
+8253xioc.h
+
+8253xplx.c
+
+8253xint.c
+
+crc32.c
+
+endian.h
+
+Makefile
+
+Amcc5920.c
+
+8253xmcs.h
+
+8253xmcs.c
+
+8253xchr.c
+
+8253xutl.c
+
+ 
+
+ 
+
+ 
+
+The source code is divided functionally among the files of the ASLX driver.
+
+ 
+
+8253xcfg.c is the source for a user application that configures 8253x
+control registers to provide clocking.  8253xmac.c is the source for a
+user application that sets a pseudo-MAC address for the network driver.
+
+ 
+
+8253xini.c contains the initialization/probe logic.
+
+ 
+
+8253xint.c contains the common interrupt logic.
+
+ 
+
+8253xtty.c contains the asynchronous TTY logic.
+
+ 
+
+8253xsyn.c contains the synchronous TTY logic.
+
+ 
+
+8253xnet.c contains the network driver logic.
+
+ 
+
+8253xchr.c contains the character driver logic.
+
+
+ 
+
+8253xdbg.c contains some debugging functions.
+
+ 
+
+8253xutl.c contains most of the functions that are common among the
+different driver functional subunits.
+
+ 
+
+8253xplx.c contains some functions specific to the PLX9050 (a PCI bridge
+chip) and specifically to reading and reprogramming the associated
+serial EEPROM.
+
+ 
+
+amcc5920.c contains some functions specific to the AMCC5920 (a PCI
+bridge chip) and specifically to reading and reprogramming the
+associated serial EEPROM.
+
+ 
+
+8253xmcs.c contains functions specific to programming the multichannel
+server (mostly G-LINK related logic, programming the sp502 driver chip
+and reading or programming the serial EEPROM associated with the
+interface cards contained within the MCS unit).
+
+ 
+
+crc32.c contains logic to append a CRC32 to a pseudo MAC frame that is
+generated by the network driver.
+
+ 
+
+8253x.h contains symbols, structures and macros that relate mostly to
+the 8253x chips and ports.
+
+ 
+
+8253xctl.h contains symbols, structures and macros that relate mostly to
+the adapter cards.
+
+ 
+
+8253xmcs.h contains symbols and structures that relate mostly to the
+multichannel server.  A lot of this file relates to G-LINK.
+
+ 
+
+sp502.h contains symbols and structures that relate to the programming
+of the hardware interface line drivers of the 3500 adapter cards of the
+multichannel server.
+
+ 
+
+8253xioc.h contains symbols and structures that relate to private ioctls.
+
+ 
+
+PciRegs.h contains symbols and structures that relate to PCI
+configuration space.
+
+ 
+
+Reg9050.h contains symbols and structures that relate to the PLX9050 PCI
+interface chip and its serial eprom
+
+ 
+
+crc32.h, crc32dcl.h and .endian.h contain symbols, structures and macros
+that relate to generating a correct CRC32.
+
+ 
+
+ring.h contains symbols and structures that relate to the network driver
+frame transmission ring and frame reception.
+
+ 
+
+The Makefile is a standard Linux kernel Makefile whose structure is
+dictated by the current Linux build formalism.
+
+ 
+
+
+  _Using the ASLX Driver _
+
+
+   
+
+
+  The ASLX driver is designed to be a ^Óplug-and-play^Ô driver as far as
+  possible.  If it is built as a dynamically loadable module, the user
+  (or relevant system configuration file) invokes /insmod /to load the
+  ASLX.o file. 
+
+ 
+
+The following parameters can be set on the /insmod/ command line.
+
+ 
+
+MODULE_PARM(xx20_minorstart, "i");/*when statically linked autodected
+otherwise 128 by default*/
+
+MODULE_PARM(sab8253xc_major, "i");/*major dev for character device, by
+default dynamic */
+
+MODULE_PARM(auraXX20n_debug, "i");/*turns on debugging messages, default
+off*/
+
+MODULE_PARM(auraXX20n_name, "s"); /*base network driver name = 8253x000*/
+
+MODULE_PARM(sab8253xn_listsize, "i"); /*transmit ring size default 32*/
+
+MODULE_PARM(sab8253xc_name, "s");/*registered name for char driver =
+sab8253xc*/
+
+MODULE_PARM(sab8253x_default_sp502_mode, "i");
+
+ 
+
+
+  The asynchronous TTY functionality can immediately be used without
+  extra configuration.  [Note that immediate use of the WMS3500 products
+  is possible because the default value of sab8253x_default_sp502_mode
+  is SP502_RS232_MODE (== 1).  If a different default mode is needed, it
+  can be set as options in the /etc/modules.conf file.  OFF = 0.
+
+RS232 = 1, RS422 = 2, RS485 = 3, RS449 = 4, EIA530 = 5 and V.35 = 6, as
+defined in 8253xioc.h.]
+
+ 
+
+The MAKETERMS script below parses the /proc/tty/driver/auraserial file
+to make the asynchronous TTY device files in the /dev directory.
+
+ 
+
+TTYDEV=$1
+
+MDEVS=`cat /proc/tty/driver/auraserial | gawk '{print $1}' | sed -e
+'/[a-zA-Z]/d' | sed -e 's/://'`
+
+ 
+
+for i in $MDEVS
+
+do
+
+        TTYNAME=/dev/ttyS${TTYDEV}
+
+        mknod $TTYNAME c 4 $i
+
+        TTYDEV=$((${TTYDEV}+1))
+
+done
+
+ 
+
+The MAKEPROTO script below provides a prototype to modify the
+/etc/inittab file so that an agetty process can be spawned on every
+other /dev/ttyS* at 9600 bps
+
+ 
+
+TTYDEV=$1
+
+MDEVS=`cat /proc/tty/driver/auraserial | gawk '{print $1}' | sed -e
+'/[a-zA-Z]/d' | sed -e 's/://'`
+
+LEADCHAR=""
+
+ 
+
+for i in $MDEVS
+
+do
+
+        NAME=S${TTYDEV}
+
+        TTYNAME=ttyS${TTYDEV}
+
+        echo ${LEADCHAR}${NAME}:35:respawn:/sbin/agetty 9600 ${TTYNAME}
+
+        TTYDEV=$((${TTYDEV}+1))
+
+        if [ -z "$LEADCHAR" ]
+
+        then
+
+                LEADCHAR="#"
+
+        else
+
+                LEADCHAR=""
+
+        fi
+
+done
+
+ 
+
+
+  If loopback cables are connected between successive TTY ports on each
+  Aurora adapter card or unit, the command
+
+ 
+
+cu ^Öl /dev/ttyS{n} ^Ös 9600
+
+ 
+
+would connect to the login that was spawned on /dev/ttyS{n-1}.
+
+ 
+
+The script MAKESTERMS (viz below) creates synchronous TTY dev files for
+all the Aurora serial ports.
+
+ 
+
+TTYDEV=$1
+
+MDEVS=`cat /proc/tty/driver/auraserial | gawk '{print $1}' | sed -e
+'/[a-zA-Z]/d' | sed -e 's/://'`
+
+ 
+
+for i in $MDEVS
+
+do
+
+        TTYNAME=/dev/sttyS${TTYDEV}
+
+        mknod $TTYNAME c 5 $i
+
+        TTYDEV=$((${TTYDEV}+1))
+
+done
+
+ 
+
+The MAKESPROTO script below creates a prototype with which to modify the
+/etc/inittab file to spawn an agetty process on every other
+/dev/sttyS{N} device.
+
+ 
+
+TTYDEV=$1
+
+MDEVS=`cat /proc/tty/driver/auraserial | gawk '{print $1}' | sed -e
+'/[a-zA-Z]/d' | sed -e 's/://'`
+
+LEADCHAR=""
+
+ 
+
+for i in $MDEVS
+
+do
+
+        NAME=sS${TTYDEV}
+
+        TTYNAME=sttyS${TTYDEV}
+
+        echo ${LEADCHAR}${NAME}:35:respawn:/sbin/agetty 9600 ${TTYNAME}
+
+        TTYDEV=$((${TTYDEV}+1))
+
+        if [ -z "$LEADCHAR" ]
+
+        then
+
+                LEADCHAR="#"
+
+        else
+
+                LEADCHAR=""
+
+        fi
+
+done
+
+ 
+
+
+  The simplest way to use these terminals with the agetty process that
+  comes with the Linux distribution is to leave externally clocked (the
+  default) the terminals on which agetty has been spawned.
+
+ 
+
+The loopback cable can be connected to a port on which agetty is not
+being run.  The clockside of the cable is connected to this port.  The
+user can run the MAKECLOCKING script below.
+
+ 
+
+echo 8253xcfg $1 -n 64 158 56 4 192 140 15
+
+8253xcfg $1 -n 64 158 56 4 192 140 15
+
+ 
+
+The numbers on the 8253xcfg command line are new (decimal) values for
+the channel control, mode and baud rate registers.  The file 8253xioc.h
+and sab8253x manuals from Siemens/Infineon can assist in explaining the
+reasoning behind these values. The 8253xcfg sets the mode, channel
+control and baudrate generator registers of the port specified by
+/dev/sttyS{N-1} which is the argument $1 of this script file.  8253xcfg
+is a simple example program that is included with the driver sources. 
+It is described in the next section of this document.
+
+ 
+
+At this point, the user could execute the following command to connect
+synchronously to the peer synchronous TTY port.
+
+ 
+
+cu ^Öl /dev/sttyS{n} ^Ös 9600
+
+ 
+
+To turn off internal clocking use the following command.
+
+ 
+
+8253xcfg /dev/sttyS? ^Ön 64 152 0 4 0 140 15
+
+ 
+
+To use an ASLX network device the following commands would be used.
+
+ 
+
+*MAKECLOCKING /dev/sttyS*/{N} [if the interface is to provide clock]/
+
+*stty */{speed} /*< /dev/sttyS*/{N} [if the interface is to provide clock]/
+
+ 
+
+To set the MAC address, which defaults to 00:00:00:00:00:00 and which
+consequently must be changed, use the following command.
+
+ 
+
+*ifconfig 8253x*/{mdev} /*hw ether*/ {mac address} [as root]/
+
+ 
+
+[Note that the 8253x{mdev} interface must not be running when the above
+command is executed.]
+
+ 
+
+To set the IP address, use the command.
+
+/ /
+
+*ifconfig 8253x*/{mdev} {ipadress} [as root]/
+
+ 
+
+[Note that the two ifconfig commands can be combined on one line.  If
+they are executed separately the MAC address command must be executed
+before the IP address command.]
+
+ 
+
+After the completion of the above commands, assuming there is an active
+network peer that uses the same serial Ethernet frame structure, it
+should be possible to ping or telnet to the peer networking device.
+
+ 
+
+{mdev} is the minor device number (in decimal, 3 digits including
+leading 0s required) associated with /dev/sttyS{N}.//
+
+* *
+
+To disable the network interface use the following command.
+
+ 
+
+*ifconfig 8253x*/{mdev} /*down*/ [as root]/
+
+ 
+
+If there is a need to disable clocking on a serial port, the
+MAKENONCLOCKING shell script is invoked with the TTY device as an
+argument as follows.
+
+ 
+
+MAKENONCLOCKING /dev/ttyS{N}
+
+ 
+
+The shell script contains the following commands.
+
+ 
+
+echo 8253xcfg $1 -n 64 152 0 4 192 140 255
+
+8253xcfg $1 -n 64 152 0 4 192 140 255
+
+ 
+
+The numbers on the 8253xcfg command line are new (decimal) values for
+the channel control, mode and baud rate registers.  The file 8253xioc.h
+and sab8253x manuals from Siemens/Infineon can assist in explaining the
+reasoning behind these values. The 8253xcfg sets the mode, channel
+control and baudrate generator registers of the port specified by
+/dev/sttyS{N-1} which is the argument $1 of this script file.  8253xcfg
+is a simple example program that is included with the driver sources. 
+It is described in the next section of this document.
+
+
+         
+
+
+  _Simple Tools and Example Programs_
+
+ 
+
+The tools and example programs supplied with the SAB8253X ASLX driver
+are the following.
+
+1.      eprom9050
+
+2.      8253xcfg
+
+3.      8253xspeed
+
+4.      8253xpeer
+
+5.      8253xmode
+
+
+    eprom9050
+
+ 
+
+This program performs the bit-banging necessary to read and to program
+the serial eprom of the PLX9050. 
+
+ 
+
+To access the serial eprom on an adapter card the program opens up a TTY
+device on   the adapter card, whose serial eprom is to be modified. 
+This TTY device can either be synchronous, asynchronous or callout.  The
+TTY device is passed as an argument when the program is invoked.
+
+ 
+
+The program uses the ATIS_IOCGSEP9050 IOCTL to get the current serial
+eprom values and the ATIS_IOCSSEP9050 IOCTL to set the new serial eprom
+values.
+
+ 
+
+Here is the source code of the program.
+
+ 
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+
+ *
+
+ * This program is free software; you can redistribute it and/or
+
+ * modify it under the terms of the GNU General Public License
+
+ * as published by the Free Software Foundation; either version
+
+ * 2 of the License, or (at your option) any later version.
+
+ *
+
+ **/
+
+ 
+
+#include <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+#include "Reg9050.h"
+
+ 
+
+ 
+
+                                /* This application shows how to load the */
+
+                                /* channel control, mode and rx frame
+length */
+
+                                /* check registers via an ioctl.*/
+
+ 
+
+int main(int argc, char **argv)
+
+{
+
+  int fd;
+
+  unsigned short oldeeprom[EPROM9050_SIZE], neweeprom[EPROM9050_SIZE];
+
+  char buffer[200];
+
+  int count;
+
+  int value;
+
+  unsigned short *pointer;
+
+  unsigned short *pointerold;
+
+  int noprompt = 0;
+
+  int epromindex;
+
+ 
+
+  if(argc < 2)
+
+    {
+
+      fprintf(stderr, "Syntax: %s {portname} [-n] {prom values}.\n", *argv);
+
+      exit(-1);
+
+    }
+
+  fd = open(argv[1], O_RDWR);
+
+  if(fd < 0)
+
+    {
+
+      perror("open failed.");
+
+      exit(-2);
+
+    }
+
+ 
+
+  if((argc > 2) && !strcmp("-n", argv[2]))
+
+    {
+
+      noprompt = 1;
+
+    }
+
+ 
+
+                                /* get the current values */
+
+  if(ioctl(fd, ATIS_IOCGSEP9050, &oldeeprom) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+                                /* set up the existing values as defaults */
+
+  memcpy(neweeprom, oldeeprom, sizeof(oldeeprom));
+
+                                /* gather all new values from the
+command line */
+
+                                /* or via tty input.*/
+
+  for(count = (2+noprompt), pointer = neweeprom; count < argc; ++count,
+++pointer)
+
+    {
+
+      *pointer = atoi(argv[count]);
+
+    }
+
+  pointer = neweeprom;
+
+  pointerold = oldeeprom;
+
+  for(epromindex = 0; epromindex < EPROM9050_SIZE; ++epromindex)
+
+    {
+
+      fprintf(stderr, "LOCATION %i [%4.4x/%4.4x]: ", epromindex,
+*pointerold, *pointer);
+
+ 
+
+      if(!noprompt)
+
+        {
+
+          if(count = read(0, buffer, 150), count <= 0)
+
+            {
+
+              exit(0);
+
+            }
+
+          buffer[count] = '\0';
+
+          if(buffer[0] != '\n')
+
+            {
+
+              sscanf(buffer, "%x", &value);
+
+              *pointer = (unsigned short) value;
+
+            }
+
+        }
+
+      else
+
+        {
+
+          fprintf(stderr, "\n");
+
+        }
+
+      ++pointerold;
+
+      ++pointer;
+
+    }
+
+                                /* This ioctl does the actual register
+load. */
+
+  if(ioctl(fd, ATIS_IOCSSEP9050, neweeprom) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+ 
+
+  fflush(stdout);
+
+}
+
+ 
+
+With the above program it is possible to change PCI vendor and device ID
+values of the adapter card.  At that point the card would no longer be
+visible to the driver.  To correct the vendor and device IDs use the
+*lspci* Linux command to find out what new values are and recompile the
+driver code after modifying the symbols that correspond to the correct
+vendor and device Ids of the card to the new values.  (I should make the
+vendor and device IDs module parameters that can be set from the
+*insmod* command line.)  The eprom9050 can be invoked to write the
+device and vendor IDs to the correct values.  Of course, then the card
+will no longer be visible to the new version of the driver, and the
+original version of the driver must be used to communicate with this card.
+
+ 
+
+
+    8253xcfg
+
+ 
+
+The 8253xcfg command provides access to images of the channel control,
+mode and baud rate generator registers of the serial port that is
+specified by the minor device number (port number = minor device number
+^Ö minor_start) of the TTY device (either synchronous, asynchronous or
+callout) specified on the command line by which 8253xcfg is invoked. 
+The next time the port is initialized (usually on the first open after
+every process that currently has the port open has closed it) these
+registers are set with the values of their images.  The 8253xcfg command
+can make a synchronous port clocking or non-clocking.  Note that even
+though 8253xcfg operates on a TTY device, the open that finally sets the
+registers with the values from the images can be either a synchronous
+TTY, a network device or a synchronous character device open.  The
+program uses the ATIS_IOCGPARAMS IOCTL to get the current values of the
+images of the registers and employs the ATIS_IOCSPARAMS IOCTL to set the
+current values of the images of the registers.  Here is the source of
+the 8253xcfg program.
+
+ 
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+
+ *
+
+ * This program is free software; you can redistribute it and/or
+
+ * modify it under the terms of the GNU General Public License
+
+ * as published by the Free Software Foundation; either version
+
+ * 2 of the License, or (at your option) any later version.
+
+ *
+
+ **/
+
+ 
+
+#include <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+ 
+
+char *prompts[] =
+
+  {
+
+    "ccr0",
+
+    "ccr1",
+
+    "ccr2",
+
+    "ccr3",
+
+    "ccr4",
+
+    "mode",
+
+    "rlcr",
+
+    0
+
+  };
+
+ 
+
+                                /* This application shows how to load the */
+
+                                /* channel control, mode and rx frame
+length */
+
+                                /* check registers via an ioctl.*/
+
+ 
+
+int main(int argc, char **argv)
+
+{
+
+  int fd;
+
+  struct channelcontrol ccontrolold, ccontrolnew;
+
+  char buffer[200];
+
+  int count;
+
+  int value;
+
+  unsigned char *pointer;
+
+  unsigned char *pointerold;
+
+  char **promptpointer = prompts;
+
+  int noprompt = 0;
+
+ 
+
+  if(argc < 2)
+
+    {
+
+      fprintf(stderr, "Syntax: %s {portname} [-n] [ccr0 [ccr1 [ccr2
+[ccr3 [ccr4 [mode [rlcr]]]]]]].\n", *argv);
+
+      exit(-1);
+
+    }
+
+  fd = open(argv[1], O_RDWR);
+
+  if(fd < 0)
+
+    {
+
+      perror("open failed.");
+
+      exit(-2);
+
+    }
+
+ 
+
+  if((argc > 2) && !strcmp("-n", argv[2]))
+
+    {
+
+      noprompt = 1;
+
+    }
+
+ 
+
+                                /* get the current values */
+
+  if(ioctl(fd, ATIS_IOCGPARAMS, &ccontrolold) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+                                /* set up the existing values as defaults */
+
+  ccontrolnew = ccontrolold;
+
+ 
+
+                                /* gather all new values from the
+command line */
+
+                                /* or via tty input.*/
+
+  for(count = (2+noprompt), pointer = (unsigned char*) &ccontrolnew;
+count < argc; ++count, ++pointer)
+
+    {
+
+      *pointer = atoi(argv[count]);
+
+    }
+
+  pointer = (unsigned char*) &ccontrolnew;
+
+  pointerold = (unsigned char*) &ccontrolold;
+
+  while(*promptpointer)
+
+    {
+
+      fprintf(stderr, "%s [%2.2x/%2.2x]: ",*promptpointer, *pointerold,
+*pointer);
+
+ 
+
+      if(!noprompt)
+
+        {
+
+          if(count = read(0, buffer, 150), count <= 0)
+
+            {
+
+              exit(0);
+
+            }
+
+          buffer[count] = '\0';
+
+          if(buffer[0] != '\n')
+
+            {
+
+              sscanf(buffer, "%x", &value);
+
+              *pointer = (unsigned char) value;
+
+            }
+
+        }
+
+      else
+
+        {
+
+          fprintf(stderr, "\n");
+
+        }
+
+      ++pointerold;
+
+      ++pointer;
+
+      ++promptpointer;
+
+    }
+
+                                /* This ioctl does the actual register
+load. */
+
+  if(ioctl(fd, ATIS_IOCSPARAMS, &ccontrolnew) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+ 
+
+  fflush(stdout);
+
+}
+
+ 
+
+ 
+
+
+    8253xspeed
+
+ 
+
+This program sets the custom baud rate of a serial port.  If the custom
+baud rate of a serial port is non-zero, and if the standard baud rate
+has been set to 38,400 bps, the next time the port is initialized, the
+port will run at the custom baud rate.  If the custom baud rate were 0,
+the port would run at the standard baud rate.   The 8352xpeed program is
+invoked with a TTY device (either asynchronous, synchronous or callout),
+but the effect also applies to the network device and the synchronous
+character device that correspond to the same physical serial port.
+
+ 
+
+Here is the source code for the 8253xspeed.
+
+ 
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+
+ *
+
+ * This program is free software; you can redistribute it and/or
+
+ * modify it under the terms of the GNU General Public License
+
+ * as published by the Free Software Foundation; either version
+
+ * 2 of the License, or (at your option) any later version.
+
+ *
+
+ **/
+
+ 
+
+#include <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+ 
+
+ 
+
+int main(int argc, char **argv)
+
+{
+
+  int fd;
+
+  unsigned long oldspeed, newspeed;
+
+  char buffer[200];
+
+  int count;
+
+  long value;
+
+  int noprompt = 0;
+
+  int epromindex;
+
+ 
+
+  if(argc < 2)
+
+    {
+
+      fprintf(stderr, "Syntax: %s {portname} [-n] {new speed}.\n", *argv);
+
+      exit(-1);
+
+    }
+
+  fd = open(argv[1], O_RDWR);
+
+  if(fd < 0)
+
+    {
+
+      perror("open failed.");
+
+      exit(-2);
+
+    }
+
+ 
+
+  if((argc > 2) && !strcmp("-n", argv[2]))
+
+    {
+
+      noprompt = 1;
+
+    }
+
+ 
+
+                                                                                                       
+/* get the current values */
+
+  if(ioctl(fd, ATIS_IOCGSPEED, &oldspeed) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+                                                                                                       
+/* set up the existing values as defaults */
+
+  newspeed = oldspeed;
+
+                                                                                                       
+/* gather all new values from the command line */
+
+                                                                                                       
+/* or via tty input.*/
+
+  if(argc == (noprompt + 3))
+
+    {
+
+      newspeed = atoi(argv[count]);
+
+    }
+
+ 
+
+  fprintf(stderr, "speed [%ld/%ld]: ", oldspeed, newspeed);
+
+ 
+
+  if(!noprompt)
+
+    {
+
+      if(count = read(0, buffer, 150), count <= 0)
+
+                                                                                    
+{
+
+                                                                                    
+  exit(0);
+
+                                                                                    
+}
+
+      buffer[count] = '\0';
+
+      if(buffer[0] != '\n')
+
+                                                                                    
+{
+
+                                                                                    
+  sscanf(buffer, "%ld", &newspeed);
+
+                                                                                    
+}
+
+    }
+
+  else
+
+    {
+
+      fprintf(stderr, "\n");
+
+    }
+
+ 
+
+                                                                                                       
+/* This ioctl does the actual register load. */
+
+  if(ioctl(fd, ATIS_IOCSSPEED, &newspeed) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+ 
+
+  fflush(stdout);
+
+}
+
+ 
+
+The ATIS_IOCGSPEED gets the value the custom baud rate for a serial port
+while ATIS_IOCSSPEED sets the value of the custom baud rate for a serial
+port.
+
+ 
+
+ 
+
+
+    8253xpeer
+
+ 
+
+The 8253xpeer example program reads and writes packets to the serial
+port in synchronous mode.  The synchronous character driver to some
+extent emulates the getmsg/putmsg functionality found in Solaris.  This
+driver returns only one packet at a time to read and returns ENOMEM if
+the receive buffer is not large enough to receive the current packet. 
+The driver assumes that the data from a write is to be packetized into a
+single packet.  The driver can provide asynchronous notification that
+there is no more data queued to be transmitted at the serial port.  This
+asynchronous notification informs the application program that a low
+priority packet can now be written to the driver.  Such functionality is
+useful to protocols like LAPB that distinguish low priority information
+frames from high priority control frames.
+
+ 
+
+To try out this program find the major device number associated with the
+8253xc device in the /proc/devices file.  Select two ports to loop
+together.  Connect them with a synchronous loopback cable.  Then execute
+the following command for each of the ports.
+
+ 
+
+mknod /dev//DevName1/ c /major-dev-num minor-dev-num-1/
+
+/ /
+
+mknod /dev//DevName2/ c /major-dev-num minor-dev-num-2/
+
+ 
+
+Minor-dev-num-[1/2] correspond to the selected ports.
+
+ 
+
+Select one of the ports to be clocking (the clocking end of the loopback
+cable should connect to this port) and apply MAKECLOCKING to the
+corresponding TTY.  Use stty or 8253xspeed and stty to set the speed on
+the corresponding TTY port.
+
+ 
+
+Then in one window run *8253xpeer /dev//DevName1/* and in another window
+execute *8253xpeer /dev//DevName2./*  It should now be possible to send
+and receive data in each of the windows.
+
+ 
+
+Here is the program source.
+
+ 
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+
+ *
+
+ * This program is free software; you can redistribute it and/or
+
+ * modify it under the terms of the GNU General Public License
+
+ * as published by the Free Software Foundation; either version
+
+ * 2 of the License, or (at your option) any later version.
+
+ *
+
+ **/
+
+ 
+
+#include <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+#include <sys/poll.h>
+
+ 
+
+struct pollfd pollarray[2];
+
+ 
+
+ 
+
+char buffer[8192];
+
+ 
+
+int main(int argc, char **argv)
+
+{
+
+  int fd;
+
+  int status;
+
+  int prompt = 1;
+
+  int count;
+
+ 
+
+  if(argc != 2)
+
+    {
+
+      fprintf(stderr, "Syntax: %s {portname}\n", *argv);
+
+      exit(-1);
+
+    }
+
+  fd = open(argv[1], O_RDWR);
+
+  if(fd < 0)
+
+    {
+
+      perror("open failed.");
+
+      exit(-2);
+
+    }
+
+  do
+
+    {
+
+      if(prompt)
+
+        {
+
+          printf("Enter data: ");
+
+          fflush(stdout);
+
+          prompt = 0;
+
+        }
+
+      pollarray[0].fd = 0;
+
+      pollarray[0].events = POLLIN;
+
+      pollarray[0].revents = 0;
+
+      pollarray[1].fd = fd;
+
+      pollarray[1].events = POLLIN|POLLOUT;
+
+      pollarray[1].revents = 0;
+
+      status = poll(pollarray, 2, 10);
+
+      switch(status)
+
+        {
+
+        case 0:
+
+          break;
+
+ 
+
+        case 1:
+
+        case 2:
+
+          if(pollarray[0].revents == POLLIN)
+
+            {
+
+              if(count = read(0, buffer, 150), count <= 0)
+
+                {
+
+                  perror("unable to read stdio.\n");
+
+                  exit(0);
+
+                }
+
+              buffer[count] = '\0';
+
+              if(count)
+
+                {
+
+                  if(pollarray[1].revents & POLLOUT)
+
+                    {
+
+                      if(write(pollarray[1].fd, buffer, count) <= 0)
+
+                        {
+
+                          perror("unable to write protodevice.\n");
+
+                          exit(-1);
+
+                        }
+
+                    }
+
+                  else
+
+                    {
+
+                      printf("Write of protodevice would block.\n");
+
+                      fflush(stdout);
+
+                    }
+
+                }
+
+              prompt = 1;
+
+            }
+
+          if(pollarray[1].revents & POLLIN)
+
+            {
+
+              if(count = read(pollarray[1].fd, buffer, 8192), count <= 0)
+
+                {
+
+                  perror("unable to read protodevice.\n");
+
+                  exit(0);
+
+                }
+
+              buffer[count] = '\0';
+
+              printf("\nRead: %s", buffer);
+
+              fflush(stdout);
+
+              prompt = 1;
+
+            }
+
+          break;
+
+ 
+
+        default:
+
+          break;
+
+        }
+
+    }
+
+  while(status >= 0);
+
+}
+
+ 
+
+ 
+
+
+    8253xmode
+
+ 
+
+The 8253xmode program sets the signaling mode of port on a multichannel
+server 3500 extension board which has a programmable Sipex sp502
+physical driver chip for each port.
+
+ 
+
+The command syntax is the following
+
+ 
+
+*8253xmode* /dev//{dev name} {mode}/
+
+ 
+
+where mode is one of the following.
+
+    * off
+    * 232
+    * 422
+    * 485
+    * 530
+    * v.35
+
+ 
+
+Note the minor devices associated with a multiserver increase
+monotonically starting from the first connector on the upper left corner
+if you are facing the connector side of the multiserver.  The numbering
+goes from left to right and top to bottom without gaps  Thus, the
+numbers on the multiserver itself may not map to the minor device number
+as port number + minor device number of first port if the multiserver is
+not fully populated.
+
+ 
+
+Here is the source for the 8253xmode program.
+
+ 
+
+/* -*- linux-c -*- */
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+
+ *
+
+ * This program is free software; you can redistribute it and/or
+
+ * modify it under the terms of the GNU General Public License
+
+ * as published by the Free Software Foundation; either version
+
+ * 2 of the License, or (at your option) any later version.
+
+ *
+
+ **/
+
+ 
+
+#include <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+ 
+
+static char *signaling[] =
+
+{
+
+        "OFF",
+
+        "RS232",
+
+        "RS422",
+
+        "RS485",
+
+        "RS449",
+
+        "RS530",
+
+        "V.35"
+
+};
+
+ 
+
+                                /* This application shows how to set sigmode
+
+                                 * on those devices that support software
+
+                                 * programmable signaling. */
+
+int main(int argc, char **argv)
+
+{
+
+        int fd;
+
+        unsigned int oldmode, newmode;
+
+       
+
+        if(argc != 3)
+
+        {
+
+                fprintf(stderr, "Syntax: %s {portname} {new mode}.\n",
+*argv);
+
+                fprintf(stderr, "{new mode} = off | 232 | 422 | 485 |
+449 | 530 | v.35\n");
+
+                exit(-1);
+
+        }
+
+        fd = open(argv[1], O_RDWR);
+
+        if(fd < 0)
+
+        {
+
+                perror("open failed.");
+
+                exit(-2);
+
+        }
+
+        if(!strcmp("off", argv[2]))
+
+        {
+
+                newmode = SP502_OFF_MODE;
+
+        }
+
+        else if(!strcmp("232", argv[2]))
+
+        {
+
+                newmode = SP502_RS232_MODE;
+
+        }
+
+        else if(!strcmp("422", argv[2]))
+
+        {
+
+                newmode = SP502_RS422_MODE;
+
+        }
+
+        else if(!strcmp("485", argv[2]))
+
+        {
+
+                newmode = SP502_RS485_MODE;
+
+        }
+
+        else if(!strcmp("449", argv[2]))
+
+        {
+
+                newmode = SP502_RS449_MODE;
+
+        }
+
+        else if(!strcmp("530", argv[2]))
+
+        {
+
+                newmode = SP502_EIA530_MODE;
+
+        }
+
+        else if(!strcmp("v.35", argv[2]))
+
+        {
+
+                newmode = SP502_V35_MODE;
+
+        }
+
+        else
+
+        {
+
+                fprintf(stderr, "Unknown mode %s.\n", argv[2]);
+
+                fprintf(stderr, "Syntax: %s {portname} {new mode}.\n",
+*argv);
+
+                fprintf(stderr, "{new mode} = off | 232 | 422 | 485 |
+449 | 530 | v.35\n");
+
+                exit(-1);
+
+        }
+
+       
+
+        /* get the current values */
+
+        if(ioctl(fd, ATIS_IOCGSIGMODE, &oldmode) < 0)
+
+        {
+
+                perror("ATIS_IOCGSIGMODE ioctl failed.");
+
+                exit(-3);
+
+        }
+
+        fprintf(stderr, "old mode = %s.\n", signaling[oldmode]);
+
+       
+
+        if(ioctl(fd, ATIS_IOCSSIGMODE, &newmode) < 0)
+
+        {
+
+                perror("ATIS_IOCSSIGMODE ioctl failed.");
+
+                exit(-3);
+
+        }
+
+ 
+
+        /* get the current values */
+
+        if(ioctl(fd, ATIS_IOCGSIGMODE, &oldmode) < 0)
+
+        {
+
+                perror("ATIS_IOCGSIGMODE ioctl failed.");
+
+                exit(-3);
+
+        }      
+
+        fprintf(stderr, "new mode = %s.\n", signaling[oldmode]);
+
+        fflush(stdout);
+
+}
+
+ 
+
+The 8253xmode program uses the ATIS_IOCSSIGMODE ioctl to set the new
+physical signaling mode and employs the ATIS_IOCGSIGMODE ioctl to get
+the original value and to verify the new mode.
+
+ 
+
+
+  _Logic Structure of the ASLX Driver_
+
+ 
+
+
+  /Data Structure Summary/
+
+ 
+
+The key data structures that enable the driver logic are:
+
+ 
+
+1.      SAB_BOARD structure ^Ö driver specific
+
+2.      SAB_CHIP structure ^Ö driver specific
+
+3.      SAB_PORT structure ^Ö driver specific
+
+4.      AURA_CIM structure ^Ö driver specific (actually specific to the
+multichannel server)
+
+5.      RING_DESCRIPTOR ^Ö used by all the driver functionalities in the
+transmission of data.
+
+6.      DCONTROL2 ^Ö used by all the driver functionalities in managing
+the transmission of data.
+
+7.      struct sk_buff_head ^Ö two buffer lists are associated with the
+SAB_PORT structure are used to track all the sk_buffs that are currently
+in use at each port.
+
+8.      struct tty_struct ^Ö one per port, standard structure by which
+the TTY driver access low level routines for either asynchronous TTY,
+synchronous TTY and callout functionality.  The SAB_PORT serves as the
+private data structure associated with each 8253x TTY, which on a given
+open can instantiate itself as a synchronous TTY, an asynchronous TTY or
+as a call out device.
+
+9.      struct net_device ^Ö one per port, standard network device
+structure.  The SAB_PORT serves as the private data structure associated
+with each 8253x network interface.
+
+10. struct file_operations ^Ö one per port, standard character device
+structure.  The SAB_PORT serves as the private data structure associated
+with each 8253x character interface.
+
+ 
+
+Thus the fundamental driver functionalities, the TTY device, the network
+interface and the character device, share the port structure; and the
+port structure contains the data is used to arbitrate driver
+functionality access to a given physical port.  All the above driver
+specific structures are dynamically allocated at driver initialization. 
+They are maintained on lists (in come cases several lists, e.g., global,
+per board, by interrupt+by board type and per chip lists).  The global
+port list is used to map minor device numbers sequentially to ports. 
+The per chip port list is used in interrupt processing.  Likewise the by
+interrupt+by board type board lists are also used in interrupt processing.
+
+ 
+
+The use and definition of the tty_struct (TTY and callout drivers),
+net_device (network drivers) and file_operations (character drivers)
+structures are found in the Linux. 
+
+
+     
+
+
+    Quick Overview of Standard Linux TTY, Network and Character Devices
+    and Interaction with the ASLX Driver Design
+
+ 
+
+The basic design of TTY/callout drivers, network drivers and character
+drivers is specified by the Linux interface. 
+
+ 
+
+The TTY driver uses the standard circular transmit buffer as found in
+serial.c, which handles the PC com ports) while received characters pass
+into a line disciple via the standard flip buffer logic found in serial.c
+
+ 
+
+The network and character driver parts just follow the design described
+in /Linux Device Drivers/ by Alessandro Rubini.
+
+All the driver functionalities use a circular transmit buffer descriptor
+ring and sk_buffers for receiving and transmitting data.  This uniform
+approach to transception simplifies the driver logic immensely.
+
+ 
+
+There is no use of a transmit done interrupt equivalent (unnecessary for
+a non-dma design).  The driver can be compiled to free up transmitted
+sk_buffs in the interrupt handler or in write routines. Investigation
+shows that the driver performs better when transmitted buffers are freed
+outside of the interrupt handlers.  The sk_* routines are in general
+fairly performance costly.  As a further optimization, when sk_buffs are
+freed in the write routines, if system write gets ahead of the
+transmitter, the program logic will try to avoid releasing transmitted
+buffers (in the TTY driver) but will try to reuse them if possible.
+
+ 
+
+When data is received, chains of receive buffers are passed back to the
+character device read routine or to a flush-to-line-discipline function
+(defined in the ASLX driver to override the default flush_to_ldisc
+routine defined in tty_io.c) in the case of the TTY driver
+functionalities. The network driver just invokes the /netif_rx()/ 
+routine at interrupt level to receive packets. Currently, the network
+driver pre-allocates a receive buffer, but such pre-allocation is not
+necessary, and no other driver functionalities make use of
+pre-allocation of buffers.
+
+
+    From Standard Driver Architectures to the ASLX Driver
+
+ 
+
+The main difficulties to be overcome in the ASLX design fit into two
+categories.
+
+ 
+
+1.      No other Linux driver attempts to combine multiple TTY
+functionalities with network and character driver functionalities.
+
+2.      Even though the members of this Aurora product line all use
+basically the same Siemens/Infineon interface chip, the details of
+accessing this chip differ radically over the product line.  The adapter
+cards use the PLX 9050 PCI bridge chip while the multichannel servers
+use the AMCC 5920 PCI bridge chip.  In the latter case there is a
+somewhat complex G-Link hardware protocol used for communication between
+the host adapter card and the expansion chassis that hosts the extension
+boards where the serial interface chips are located.  The adapter cards
+differ in detecting and causing modem signal changes.
+
+ 
+
+
+  /Creating a Uniform Device Programming Interface/
+
+ 
+
+The most painful aspect of  of creating a multifunction driver for the
+Aurora hardware is the difference of each Aurora adapter card or unit
+from every other Aurora adapter card or unit. 
+
+ 
+
+Signals are handled differently on ESCC2 (SAB82532) versus ESCC8
+(SAB82538) based devices.  Interrupt processing is different on ESCC2,
+ESCC8 and multichannel server devices.  The multichannel servers use an
+AMCC bridge chip while the other devices use a PLX bridge chip.  
+Multichannel servers and all other Aurora adapter cards access device
+registers completely differently.
+
+ 
+
+There are a set of data structures and macros that simplify access to
+control registers for serial ports and that try to provide uniformity in
+line control signal handling, which is complex because some signals are
+defined in the serial port interface of the 8253X serial interface chip
+while other signals are handled through the general parallel ports of
+the 8253X chip. 
+
+ 
+
+The bitwise definition of the line control signals differ on the
+parallel ports of the 82532 and the 82538 based cards (including
+multichannel server units). 
+
+ 
+
+The macros (courtesy Francois Wautier) below provide a common interface
+for raising and lowering control signals as well as for querying them.
+
+
+   
+
+/*
+
+ * Raise a modem signal y on port x, tmpval must exist! */
+
+#define RAISE(xx,y) \
+
+{ \
+
+          unsigned char __tmpval__; \
+
+          __tmpval__= (xx)->readbyte((xx),(xx)->y.reg);\
+
+          if((xx)->y.inverted)\
+
+            __tmpval__ &= ~((xx)->y.mask);\
+
+          else\
+
+            __tmpval__ |= (xx)->y.mask;\
+
+          __tmpval__ |= (xx)->y.cnst;\
+
+          (xx)->y.val=1;\
+
+          (xx)->writebyte((xx),(xx)->y.reg,__tmpval__);\
+
+}
+
+/*
+
+ * Lower a modem signal y on port x, __tmpval__ must exist! */
+
+#define LOWER(xx,y) \
+
+{\
+
+          unsigned char __tmpval__; \
+
+          __tmpval__= (xx)->readbyte((xx),(xx)->y.reg);\
+
+          if((xx)->y.inverted)\
+
+            __tmpval__ |= (xx)->y.mask;\
+
+          else\
+
+            __tmpval__ &= ~((xx)->y.mask);\
+
+          __tmpval__ |= (xx)->y.cnst;\
+
+          (xx)->y.val=0;\
+
+          (xx)->writebyte((xx),(xx)->y.reg,__tmpval__);\
+
+}
+
+ 
+
+#define ISON(xx,y) \
+
+          ((xx)->y.inverted !=
+(((xx)->readbyte((xx),(xx)->y.reg)&(xx)->y.mask)==(xx)->y.mask))
+
+ 
+
+The inverted, cnst, and mask fields of the modem signal structure (y)
+are specific to the type of serial communications controller.  The
+readbyte and writebyte functions are specific to the different types of
+Aurora hardware.
+
+ 
+
+To hide the details of accessing control and data registers, the
+SAB_PORT structure has a fields whose values are the functions to read a
+device register, to write a device register,to  read a device FIFO and
+to write a device FIFO (as well as to read and to write short words,
+functions that could be used in implementing the readfifo and writefifo
+routines).
+
+ 
+
+Here is readfifo for non-multichannel server hardware.
+
+ 
+
+/***************************************************************************
+
+ * aura_readfifo:    Function to read the FIFO on a 4X20P, 8X20P or Sun
+serial
+
+ *               
+
+ *
+
+ *     Parameters   :
+
+ *                   port:  The port being accessed
+
+ *                   buf:   The address of a buffer where we should put
+
+ *                          what we read
+
+ *                  nbytes: How many chars to read.
+
+ *
+
+ *     Return value : none
+
+ *
+
+ *     Prerequisite : The port must have been opened
+
+ *
+
+ *     Remark       :
+
+ *
+
+ *     Author       : fw
+
+ *
+
+ *     Revision     : Oct 13 2000, creation
+
+ ***************************************************************************/
+
+void aura_readfifo(struct sab_port *port, unsigned char *buf, unsigned
+int nbytes)
+
+{
+
+  int i;
+
+  unsigned short *wptr = (unsigned short*) buf;
+
+  int nwords = ((nbytes+1)/2);
+
+  for(i = 0; i < nwords; i ++)
+
+    {
+
+      wptr[i] = readw(((unsigned short *)port->regs));
+
+    }
+
+}
+
+ 
+
+Here is the readfifo function for multichannel servers.
+
+ 
+
+void wmsaura_readfifo(struct sab_port *port, unsigned char *buf,
+unsigned int nbytes)
+
+{
+
+#ifdef FIFO_DIRECT
+
+  unsigned short fifo[32/2];    /* this array is word aligned
+
+                                 * buf may not be word aligned*/
+
+  unsigned int nwords;
+
+  int i;
+
+  int wcount;
+
+  unsigned int address;
+
+ 
+
+  if (nbytes == 0)
+
+    {
+
+      return;
+
+    }
+
+ 
+
+  wcount = ((nbytes + 1) >> 1);
+
+  /* Read the thing into the local FIFO and copy it out. */
+
+  address = (unsigned int) port->regs;
+
+ 
+
+  for(i = 0; i < wcount; ++i)
+
+    {
+
+      fifo[i] = readw((unsigned short*)(address + CIMCMD_RDFIFOW));
+
+    }
+
+ 
+
+  memcpy((unsigned char*) buf, (unsigned char*) &(fifo[0]), (unsigned
+int) nbytes);
+
+ 
+
+#else           /* FIFO_DIRECT */
+
+  unsigned short fifo[32/2];
+
+  int i;
+
+  int wcount;
+
+  SAB_BOARD *bptr;
+
+  unsigned int channel;
+
+ 
+
+  if (nbytes == 0)
+
+    {
+
+      return;
+
+    }
+
+ 
+
+  bptr = port->board;
+
+  wcount = ((nbytes + 1) >> 1);
+
+  channel = (((unsigned char*) port->regs) - bptr->CIMCMD_REG); /*
+should be properly shifted */
+
+ 
+
+  /*
+
+   * Trigger a cache read by writing the nwords - 1 to the
+
+   *  magic place.
+
+   */
+
+ 
+
+  writeb((unsigned char) wcount, bptr->MICCMD_REG + (MICCMD_CACHETRIG +
+channel));
+
+ 
+
+  /*
+
+   * Now, read out the contents.
+
+   */
+
+ 
+
+  channel >>= 1;
+
+ 
+
+  for(i = 0; i < wcount; ++i)
+
+    {
+
+      fifo[i] = readw((unsigned short*)(bptr->FIFOCACHE_REG + (channel +
+(i << 1))));
+
+    }
+
+ 
+
+  memcpy((unsigned char*) buf, (unsigned char*) &(fifo[0]), (unsigned
+int) nbytes);
+
+#endif          /* !FIFO_DIRECT */
+
+}
+
+
+   
+
+Except at initialization time the driver code accesses serial
+communications controller device registers only through fields in the
+port structure.  The details of accessing the different types of
+hardware are almost completely hidden from the driver program logic.
+
+ 
+
+The only exception is the interrupt handler, which must understand some
+of the details of the multichannel server.  Nevertheless, as is made
+clear in the following section, from the standpoint of processing
+interrupts there are really only two types of Aurora hardware, that
+which is ESCC2 based and that which is ESCC8 based.  The details of the
+difference of the two types of hardware is contained solely within the
+8253xint.c file which also contains the logic by which an interrupt from
+a multichannel server can be processed almost exactly like an interrupt
+from an 8520P adapter card.
+
+ 
+
+
+  /Code Structure Summary/
+
+
+   
+
+
+  The SAB8253X driver code has the following logic components
+
+ 
+
+1.      a probe/initialization logic,
+
+a.      bridge initialization/EEPROM parsing logic,
+
+b.      structure allocation logic,
+
+c.      interrupt request logic,
+
+2.      the core logic, which handles all the non-interrupt processing
+of the driver functionality,
+
+a.      per port startup/shutdown logic,
+
+b.      driver arbitration logic,
+
+c.      skbuffer management logic,
+
+3.      the interrupt handler logic,
+
+a.      common interrupt port polling logic,
+
+b.      skbuffer management logic,
+
+4.      the termination/driver unload logic,
+
+a.      interrupt shutdown logic,
+
+b.      device shutdown logic,
+
+c.      structure deallocation logic.
+
+ 
+
+ 
+
+/Probe/Initialization Logic/
+
+ 
+
+The probe/initialization logic sets up the CRC structures for the
+network driver and then the tty_struct for the synchronous and
+asynchronous TTY drivers.  Initializing the tty_struct involves setting
+up pointers to the standard functions that the Linux TTY driver invokes
+as well as some standard data and the /proc/tty/driver/auraserial
+function and data.
+
+ 
+
+
+The probe/initialization logic identifies all the multiport serial
+adapters, compact PCI adapters and multiserver adapters in the system
+and puts them on a list of board structures.  After identifying all the
+boards, initializing the bridge chips and analyzing (possibly rewriting)
+the serial EEPROM, the logic sets up all the chips on the boards and all
+the ports on the chips. 
+
+ 
+
+All chips are linked together in a list.  All ports are linked together
+in a list.  The port list is linked together so that minor device N
+corresponds to the Nth element of the port list.  A board structure
+points to a list of chips on the board as well as a list of all ports on
+the board.  Likewise a chip structure points to a list of all ports on
+the chip.  Chip structures point back to the board structure associated
+with the board on which the chip resides.  Likewise port structures
+point back to the board and to the chip on which they reside.  This
+interconnected list structure facilitates access to one type of
+structure when a routine has been passed a pointer to another type of
+structure.  All these structures are dynamically allocated via
+/kmalloc()/.  When the driver is unloaded, memory is released by walking
+the list. 
+
+ 
+
+After setting up the board, chip and port structures, initialization of
+the tty_struct is completed at this point because the maximum possible
+number of serial TTYs is now known.  The, the standard network device
+structure that is associated with each port is allocated and
+initialized.  The network devices point to the associated port
+structure.  The network devices are chained via a pointer in the
+associated port structure.  This chaining facilitates release of the
+network device structure memory when the driver is unloaded.
+
+ 
+
+Each network device is registered after its network device structure is
+initialized.  Network device initialization invokes the network device
+initialization, which installs the standard network functions in the
+network device structure and which sets up the sk_buff transmit ring as
+well as the receive sk_buf.  Unlike the Solaris driver, when a complete
+frame is received with no errors, it is immediately passed into the
+network layer.  Thus, there is no receive ring of sk_buffs as one might
+find in the driver of a device that could carry out chained DMA (e.g. a
+DEC Tulip or an Hitachi SCA).
+
+ 
+
+All sk_buffs associated with a network device that are currently in use
+by the network driver are linked together in an sk_buff list (viz core
+logic).   This list facilitates release of all sk_buff associated with a
+network device when that network device is shut down.  This list may be
+a problem if it becomes possible for a single sk_buff to be used
+simultaneously by multiple network devices.  Currently, sk_buff headers
+are not shared among network devices although sk_buff data can be
+shared.  Thus, for the nonce this logic works correctly.
+
+ 
+
+After completing of network device initialization, the
+probe/initialization logic register the character driver.  Next, the
+probe/initialization creates three lists of boards for each interrupt
+(0-31).  One list contains 82532 based boards at that interrupt level. 
+The next list contains 82538 based adapter cards at that interrupt
+level.  The third list contains all multichannel server units at that
+interrupt level.
+
+ 
+
+Next the probe/initialization logic checks the lists associated with
+each interrupt level.  If either list is non-null, the
+probe/initialization logic requests that the general interrupt handler
+be installed at this interrupt level and then it turns on PLX9050 or
+AMCC5920 interrupts (as needed) into the Linux host for each card
+associated with that interrupt level.  Thus, the interrupt handler polls
+all boards/ports at a given interrupt level when the interrupt occurs. 
+This approach is more efficient that installing one interrupt per board
+and avoids some internal Linux limits on the number of interrupt
+handlers that can be installed per interrupt.
+
+ 
+
+At this point probe/intialization is complete and any serial port may be
+used for asynchronous TTY, synchronous TTY, call out, network device
+service or synchronous character device service.
+
+ 
+
+
+/Core Logic/
+
+ 
+
+The main problem of the core logic is arbitration of access to the
+serial port, when and by which part of the driver a port is started and
+when the port is shut down.
+
+ 
+
+The asynchronous callout, asynchronous TTY, synchronous TTY devices,
+synchronous character device and network device follow the following rules.
+
+ 
+
+1.                  If there is an established point-to-point
+connection, only the current process or process group that owns the
+serial port may open the device.
+
+2.                  If the asynchronous callout is open, opens of a
+single TTY or character device type block until the connection completes.
+
+3.                  Network device opens never block, and the network
+layer opens a network device only once.
+
+4.                  If a connection that belongs to a TTY device or
+character device hangs up, eventually all opens of that device will close.
+
+5.                  Hangup of on a network device does not guarantee a
+close of the device, but a flag bit is set that permits a call out open
+to restore the connection (note that a one-to-one map of TTY devices,
+callout devices, character devices and network devices is implied.)
+
+ 
+
+The network device open and block_til_ready* functions invoked from TTY
+opens enforce this arbitration.
+
+ 
+
+The logic works as follows:
+
+ 
+
+    * The cua device associated with a port may only be opened one.
+    * If a TTY or character device is open, the cua device may not be
+      opened.
+    * If the cua device is open, the network device cannot be opened and
+      the TTY or character device block (multiple opens from the same
+      process or process group are allowed).
+    * If the network device is open, the TTY or character devices cannot
+      be opened while the cua device blocks.
+    * A hangup sends an interrupt to the TTY or character device while
+      the network device shuts down its port and a (network blocked) cua
+      device proceeds.
+    * On the close of the cua device, blocked TTY and character devices
+      proceed and the network device restarts its port.
+
+ 
+
+When an open completes, the transmit_chars, receive_chars,  check_status
+functions and associated data fields are set in the port structure,
+these are used in the interrupt handler that never changes until the
+driver is unloaded.
+
+ 
+
+When a port is not in use, the asynchronous version of these fields and
+functions are set in the port structure.  Some values must be present,
+and the asynchronous ones are probably the least dangerous.
+
+ 
+
+Besides the arbitration problem, the core logic addresses buffer
+management for the network and character drivers.
+
+ 
+
+The network layer passes a transmit sk_buff to the network driver.   The
+buffer is inserted in the transmit ring or sets a transmit congestion
+flag.  In either case, transmit is initialized if not already in
+progress.  If the sk_buff is successfully inserted, it is also linked
+into the driver sk_buff list which tracks all sk_buffs used by the
+network driver.  On network device close all sk_buffs on the per port
+sk_buff list are released.  This sk_buff list mechanism is used to avoid
+memory leaks.
+
+ 
+
+The TTY and character drivers packetize write data in an sk_buff (each
+write creates a single sk_buff) and inserts it in the transmit ring if
+possible or blocks (returns a failure in the case of TTY drivers). 
+Transmit sk_buffs are also linked into the driver sk_buff list.  This
+list is a convenience to assist deallocation during driver close.
+
+ 
+
+The TTY and character drivers also maintains a receive sk_buff list. 
+When the user application invokes the read system call, the data from
+one sk_buff is passed up to the user application (or an error if the
+read were not invoked with sufficient buffer space). 
+
+ 
+
+The character driver can be configured via IOCTL to send asynchronous
+user notification when the transmit ring empties (a design choice for
+the standard driver fasync functionality).  This character driver design
+emulates the Solaris putmsg/getmsg interface as far as possible and
+makes it possible to implement in a user application protocols like
+LAPB, which require that low priority packets only be queued to the
+driver when the driver currently has no frames in the process of
+transmission or queued for transmission.
+
+ 
+
+On character device close all sk_buffs on the per port sk_buff and per
+port receive sk_buff list are released.  This double sk_buff list
+mechanism is used to avoid memory leaks.
+
+ 
+
+/Interrupt Handler Logic/
+
+ 
+
+
+      The following code comprises the combined interrupt and board/port
+      polling logic.  The actual handler is /sab8253x_interrupt()/.  It
+      walks through the 82532, adapter 82538 adapter and multichannel
+      server lists at the interrupt level that is being processed and
+      invokes inline /sab82532_interrupt()/ and /sab82538_interrupt()/. 
+      Note that it temporary modifies multichannel server lists so that
+      it like an 8520P adapter card to the /sab8253x_interrupt()/.  This
+      logic works because the granularity of the PCI interrupt
+      associated with the Aurora hardware is basically either a list of
+      ESCC2s (the 4520P and 4520CP adapter cards) or a single ESCC8 (an
+      8520P or one ESCC8 on a multichannel server remote card after the
+      interrupt status has been queried).
+
+
+       
+
+
+      The current interrupt sources are identified and processed.  If
+      any characters are available to be received, they are received one
+      fifo at a time into the TTY flip buffer (a structure that is
+      supposed to decrease TTY latency) or into an sk_buf (something
+      like a Solaris mblk/dblk structure( in the case of the network or
+      character driver.  Then if there are characters in the TTY
+      circular transmit buffer or in the network or character driver
+      sk_buff, they are loaded into the transmit fifo, one fifo at a
+      time.  Finally, modem control status is checked.  If a hang up is
+      detected, the serial driver hang up is scheduled at kernel
+      scheduler priority (a slight difference from the standard serial
+      driver which processes hang-ups at interrupt level) in order to
+      avoid certain race conditions in the TTY driver that can occur on
+      fast machines with many serial ports.  /do_serial_hangup()/
+      invokes the TTY hangup routines in the case of TTY driver.  For a
+      network connection in the event of a line disconnection, carrier
+      is marked as off on the interface and the blocked cua device is
+      woken so that it can proceed after the network port has shut down.
+
+ 
+
+static void __inline__ sab82532_interrupt(int irq, void *dev_id, struct
+pt_regs *regs)
+
+{
+
+  struct sab_port *port;
+
+  struct sab_chip *chip=NULL;
+
+  struct sab_board *bptr = (struct sab_board*) dev_id;
+
+  union sab8253x_irq_status status;
+
+  unsigned char gis;
+
+ 
+
+  for(chip = bptr->board_chipbase; chip != NULL; chip =
+chip->next_by_board)
+
+    {
+
+      port= chip->c_portbase;
+
+      gis = READB(port, gis); /* Global! */
+
+      status.stat=0;
+
+     
+
+            /* Since the PORT interrupt are global,
+
+             * we do check all the ports for this chip
+
+             */
+
+           
+
+                                /* A 2 ports chip */
+
+         
+
+      if(!(gis & SAB82532_GIS_MASK))
+
+        {
+
+          continue; /* no interrupt on this chip */
+
+        }
+
+         
+
+      if (gis & SAB82532_GIS_ISA0)
+
+        {
+
+          status.sreg.isr0 = READB(port, isr0);
+
+        }
+
+      else
+
+        {
+
+          status.sreg.isr0 = 0;
+
+        }
+
+      if (gis & SAB82532_GIS_ISA1)
+
+        {
+
+          status.sreg.isr1 = READB(port, isr1);
+
+        }
+
+      else
+
+        {
+
+          status.sreg.isr1 = 0;
+
+        }
+
+         
+
+      if (gis & SAB82532_GIS_PI)
+
+        {
+
+          status.sreg.pis = READB(port, pis);
+
+        }
+
+      else
+
+        {
+
+          status.sreg.pis = 0;
+
+        }
+
+               
+
+      if (status.stat)
+
+        {
+
+          if (status.images[ISR0_IDX] & port->receive_test)
+
+            {
+
+              (*port->receive_chars)(port, &status);    /* when the fifo
+is full */
+
+                                                /* no time to schedule
+thread*/
+
+            }
+
+         
+
+          if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
+
+              (status.images[port->cts.irq] & port->cts.irqmask) ||
+
+              (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+
+              (status.images[ISR1_IDX] & port->check_status_test))
+
+            {
+
+              (*port->check_status)(port, &status); /* this stuff should
+be */
+
+              /* be moveable to scheduler */
+
+              /* thread*/
+
+            }
+
+         
+
+          if (status.images[ISR1_IDX] & port->transmit_test)
+
+            {
+
+              (*port->transmit_chars)(port, &status); /* needs to be
+moved to task */
+
+            }
+
+        }
+
+     
+
+                                /* Get to next port on chip */
+
+      port = port->next_by_chip;
+
+      /* Port B */
+
+      if (gis & SAB82532_GIS_ISB0)
+
+        {
+
+          status.images[ISR0_IDX] = READB(port, isr0);
+
+        }
+
+      else
+
+        {
+
+          status.images[ISR0_IDX] = 0;
+
+        }
+
+      if (gis & SAB82532_GIS_ISB1)
+
+        {
+
+          status.images[ISR1_IDX] = READB(port,isr1);
+
+        }
+
+      else
+
+        {
+
+          status.images[ISR1_IDX] = 0;
+
+        }
+
+      /* DO NOT SET PIS. IT was reset! */
+
+     
+
+     
+
+      if (status.stat)
+
+        {
+
+          if (status.images[ISR0_IDX] & port->receive_test)
+
+            {
+
+              (*port->receive_chars)(port, &status);
+
+            }
+
+          if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
+
+              (status.images[port->cts.irq] & port->cts.irqmask) ||
+
+              (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+
+              (status.images[ISR1_IDX] & port->check_status_test))
+
+            {
+
+              (*port->check_status)(port, &status);
+
+            }
+
+          if (status.images[ISR1_IDX] & port->transmit_test)
+
+            {
+
+              (*port->transmit_chars)(port, &status);
+
+            }
+
+        }
+
+    }
+
+}
+
+ 
+
+static void __inline__ sab82538_interrupt(int irq, void *dev_id, struct
+pt_regs *regs)
+
+{
+
+  struct sab_port *port;
+
+  struct sab_chip *chip=NULL;
+
+  struct sab_board *bptr = (struct sab_board*) dev_id;
+
+  union sab8253x_irq_status status;
+
+  unsigned char gis,i;
+
+ 
+
+  chip = bptr->board_chipbase;
+
+  port= chip->c_portbase;
+
+ 
+
+  gis = READB(port, gis); /* Global! */
+
+  status.stat=0;
+
+     
+
+            /* Since the PORT interrupt are global,
+
+             * we do check all the ports for this chip
+
+             */
+
+           
+
+  /* 8 ports chip */
+
+  if(!(gis & SAB82538_GIS_MASK))
+
+    {
+
+      return;
+
+    }
+
+             
+
+  if(gis & SAB82538_GIS_CII)
+
+    { /* A port interrupt! */
+
+      /* Get the port */
+
+      int portindex;
+
+     
+
+      portindex = (gis & SAB82538_GIS_CHNL_MASK);
+
+     
+
+      port = chip->c_portbase;
+
+     
+
+      while(portindex)
+
+        {
+
+          port = port->next_by_chip;
+
+          --portindex;
+
+        }
+
+     
+
+      status.images[ISR0_IDX] = READB(port,isr0);
+
+      status.images[ISR1_IDX] = READB(port,isr1);
+
+      if (gis & SAB82538_GIS_PIC)
+
+        {
+
+          status.images[PIS_IDX] =
+
+            (*port->readbyte)(port,
+
+                              ((unsigned char *)(port->regs)) +
+
+                              SAB82538_REG_PIS_C);
+
+        }
+
+      else
+
+        {
+
+          status.images[PIS_IDX] = 0;
+
+        }
+
+     
+
+      if (status.stat)
+
+        {
+
+          if (status.images[ISR0_IDX] & port->receive_test)
+
+            {
+
+              (*port->receive_chars)(port, &status);
+
+            }
+
+          if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
+
+              (status.images[port->cts.irq] & port->cts.irqmask) ||
+
+              (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+
+              (status.images[ISR1_IDX] & port->check_status_test))
+
+            {
+
+              (*port->check_status)(port, &status);
+
+            }
+
+          /*
+
+           * We know that with 8 ports chip, the bit corresponding to
+channel
+
+           * number is used in the parallel port... So we clear it
+
+           * Not too elegant!
+
+           */
+
+          status.images[PIS_IDX] &= ~(1 << (gis&SAB82538_GIS_CHNL_MASK));
+
+          if (status.images[ISR1_IDX] & port->transmit_test)
+
+            {
+
+              (*port->transmit_chars)(port, &status);
+
+            }
+
+        }
+
+    }
+
+ 
+
+  /*
+
+   * Now we handle the "channel interrupt" case. The chip manual for the
+
+   * 8 ports chip states that "channel" and "port" interrupt are set
+
+   * independently so we still must check the parrallel port
+
+   *
+
+   * We should probably redesign the whole thing to be less AD HOC that we
+
+   * are now... We know that port C is used for DSR so we only check
+that one.
+
+   * PIS for port C was already recorded in  status.images[PIS_IDX], so we
+
+   * check the ports that are set
+
+   */
+
+ 
+
+  if (status.images[PIS_IDX])
+
+    {
+
+      for(i=0, port = chip->c_portbase;
+
+          i < chip->c_nports;
+
+          i++, port=port->next_by_chip)
+
+        {
+
+          if(status.images[PIS_IDX] & (0x1 << i))
+
+            { /* Match */
+
+              /* Checking DSR */
+
+              if(port->dsr.inverted)
+
+                {
+
+                  port->dsr.val = (((*port->readbyte)
+
+                                    (port, port->dsr.reg) &
+
+                                    port->dsr.mask) ? 0 : 1);
+
+                }
+
+              else
+
+                {
+
+                  port->dsr.val = ((*port->readbyte)(port, port->dsr.reg) &
+
+                                   port->dsr.mask);
+
+                }
+
+             
+
+              port->icount.dsr++;
+
+              wake_up_interruptible(&port->delta_msr_wait);
+
+            }
+
+        }
+
+    }
+
+}
+
+ 
+
+/*
+
+ * This is the serial driver's generic interrupt routine
+
+ */
+
+ 
+
+void sab8253x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+
+{
+
+  extern SAB_BOARD *AuraBoardESCC2IrqRoot[];
+
+  extern SAB_BOARD *AuraBoardESCC8IrqRoot[];
+
+  extern SAB_BOARD *AuraBoardMCSIrqRoot[];
+
+  AURA_CIM *cim;
+
+  SAB_CHIP *chip;
+
+  SAB_PORT *port;
+
+  register SAB_BOARD *boardptr;
+
+  register unsigned char intrmask;
+
+  unsigned char stat;
+
+  SAB_CHIP *save_chiplist;
+
+  SAB_PORT *save_portlist;
+
+ 
+
+  if((irq < 0) || (irq >= NUMINTS))
+
+    {
+
+      printk(KERN_ALERT "sab8253x: bad interrupt value %i.\n", irq);
+
+      return;
+
+    }
+
+  /* walk through all the cards on the interrupt that occurred. */
+
+  for(boardptr = AuraBoardESCC2IrqRoot[irq]; boardptr != NULL; boardptr
+= boardptr->next_on_interrupt)
+
+    {
+
+      sab82532_interrupt(irq, boardptr, regs);
+
+    }
+
+ 
+
+  for(boardptr = AuraBoardESCC8IrqRoot[irq]; boardptr != NULL; boardptr
+= boardptr->next_on_interrupt)
+
+    {
+
+      sab82538_interrupt(irq, boardptr, regs);
+
+    } 
+
+ 
+
+  for(boardptr = AuraBoardMCSIrqRoot[irq]; boardptr != NULL; boardptr =
+boardptr->next_on_interrupt)
+
+    {
+
+ 
+
+      while(1)
+
+        {
+
+          writeb(0, (unsigned char*)(boardptr->CIMCMD_REG +
+CIMCMD_WRINTDIS)); /* prevent EBs from raising
+
+                                                                               
+* any more ints through the
+
+                                                                               
+* host card */
+
+          stat = ~(unsigned char) /* active low !!!!! */
+
+            readw((unsigned short*)
+
+                  (((unsigned char*)boardptr->CIMCMD_REG) +
+CIMCMD_RDINT)); /* read out the ints */
+
+                                /* write to the MIC csr to reset the PCI
+interrupt */
+
+          writeb(0, (unsigned char*)(boardptr->MICCMD_REG +
+MICCMD_MICCSR)); /* reset the interrupt generation
+
+                                                                       
+      * hardware on the host card*/
+
+                                /* now, write to the CIM interrupt ena
+to re-enable interrupt generation */
+
+          writeb(0, (unsigned char*)(boardptr->CIMCMD_REG +
+CIMCMD_WRINTENA)); /* allow EBs to request ints
+
+                                                                               
+* through the host card */
+
+          if(!stat)
+
+            {
+
+              break;
+
+            }
+
+          cim = boardptr->b_cimbase; /* cims in reverse order */
+
+          for(intrmask = boardptr->b_intrmask;
+
+              intrmask != 0;
+
+              intrmask <<= 2, stat <<=2)
+
+            {
+
+              if(cim == NULL)
+
+                {
+
+                  break;        /* no cim no ports */
+
+                }
+
+              if((intrmask & 0xc0) == 0) /* means no cim for these ints */
+
+                {               /* cim not on list do not go to next */
+
+                  continue;
+
+                }
+
+              save_portlist = boardptr->board_portbase;
+
+              save_chiplist = boardptr->board_chipbase;
+
+                                /* the goal is temporarily to make the
+structures
+
+                                 * look like 8x20 structures -- thus if
+I find
+
+                                 * a bug related to escc8s I need fix it in
+
+                                 * only one place. */
+
+              switch(stat & 0xc0) /* possible ints */
+
+                {
+
+                default:
+
+                  break;
+
+                 
+
+                case 0x80:      /* esccB */
+
+                  chip = cim->ci_chipbase;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing cim.\n");
+
+                      break;
+
+                    }
+
+                  chip = chip->next_by_cim;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
+
+                      break;
+
+                    }
+
+                  port = chip->c_portbase;
+
+                  boardptr->board_portbase = port;
+
+                  boardptr->board_chipbase = chip;
+
+                  sab82538_interrupt(irq, boardptr, regs);               
+
+                  break;
+
+                 
+
+                case 0x40:      /* esccA */
+
+                  chip = cim->ci_chipbase;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing cim.\n");
+
+                      break;
+
+                    }
+
+                  port = chip->c_portbase;
+
+                  boardptr->board_portbase = port;
+
+                  boardptr->board_chipbase = chip;
+
+                  sab82538_interrupt(irq, boardptr, regs);               
+
+                  break;
+
+                 
+
+                case 0xc0:      /* esccB and esccA */
+
+                  chip = cim->ci_chipbase;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing cim.\n");
+
+                      break;
+
+                    }
+
+                  port = chip->c_portbase;
+
+                  boardptr->board_portbase = port;
+
+                  boardptr->board_chipbase = chip;
+
+                  sab82538_interrupt(irq, boardptr, regs);               
+
+ 
+
+                  chip = cim->ci_chipbase;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing cim.\n");
+
+                      break;
+
+                    }
+
+                  chip = chip->next_by_cim;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
+
+                      break;
+
+                    }
+
+                  port = chip->c_portbase;
+
+                  boardptr->board_portbase = port;
+
+                  boardptr->board_chipbase = chip;
+
+                  sab82538_interrupt(irq, boardptr, regs);               
+
+                  break;
+
+                }
+
+              boardptr->board_portbase = save_portlist;
+
+              boardptr->board_chipbase = save_chiplist;
+
+              cim = cim->next_by_mcs;
+
+            }
+
+        }
+
+    }
+
+}
+
+ 
+
+Note that if there is no transmit in process when the
+write/hard_start_transmit routine is invoked,  transmit is intitiated
+from the core logic as if it took place in the interrupt handler.  This
+approach differs from the ASE driver, which used to force an interrupt,
+and then start the transmission.  Francois Wautier may have fixed that
+logic to start the transmission either in the STREAMS put or service
+routine.
+
+ 
+
+/Driver Unload Logic/
+
+ 
+
+The driver unload logic inverts the probe intialization logic.
+
+ 
+
+At this point no ports should be in use and in fact every port should
+have been put in the 8253x powered down state when each port underwent
+its last close (or hangup which can actually complete after a close).
+
+ 
+
+The tty driver is cleaned up, some dynamic TTY data structures are
+deallocated, the bottom half associated with this driver is removed and
+all TTY ports are deregistered.
+
+ 
+
+The PLX or AMCC interrupts to the Linux host are disabled on each board,
+and all interrupt handlers are freed.
+
+ 
+
+Next all board and chip structures are deallocated (including physical
+memory to virtual memory mappings associated with PLX9050 or AMCC 5920
+and chip registers).  Then all network device structures are
+deallocated.  (Note that all lingering sk_buffs were freed during the
+close of the network device, which must have completed before the unload
+of the driver module.)  And finally the port structures are
+deallocated.  In deallocating the port structures, network driver
+transmit rings and the receive sk_buff descriptor are deallocated if
+they are present.  (They were only allocated if the port had ever been
+used for a network device.)  At this point the driver has been
+gracefully unloaded.
+
+ 
+
+                                /* cleanup module/free up virtual memory */
+
+                                /* space*/
+
+void cleanup_module(void)
+
+{
+
+  SAB_BOARD *boardptr;
+
+  SAB_CHIP *chipptr;
+
+  SAB_PORT *portptr;
+
+  int intr_val;
+
+  extern void sab8253x_cleanup_ttydriver(void);
+
+ 
+
+  printk(KERN_ALERT "auraXX50n: unloading AURAXX50 driver.\n");
+
+ 
+
+  sab8253x_cleanup_ttydriver(); /* clean up tty */
+
+ 
+
+                                /* unallocate and turn off ints */
+
+  for(intr_val = 0; intr_val < NUMINTS; ++intr_val)
+
+    {
+
+      if((AuraBoardESCC2IrqRoot[intr_val] != NULL) ||
+(AuraBoardESCC8IrqRoot[intr_val] != NULL))
+
+        {
+
+          for(boardptr = AuraBoardESCC2IrqRoot[intr_val]; boardptr !=
+NULL; boardptr = boardptr->next_on_interrupt)
+
+            {
+
+              writel(PLX_INT_OFF, &(boardptr->b_bridge->intr));
+
+            }
+
+          for(boardptr = AuraBoardESCC8IrqRoot[intr_val]; boardptr !=
+NULL; boardptr = boardptr->next_on_interrupt)
+
+            {
+
+              writel(PLX_INT_OFF, &(boardptr->b_bridge->intr));
+
+            }
+
+ 
+
+          free_irq(intr_val, &AuraBoardESCC2IrqRoot[intr_val]); /* free
+up board int
+
+                                                                 * note
+that if two boards
+
+                                                                 * share
+an int, two int
+
+                                                                 *
+handlers were registered
+
+                                                                 *
+
+                                                                 */
+
+        }
+
+    }
+
+ 
+
+                                /* disable chips and free board memory*/
+
+  while(AuraBoardRoot)
+
+    {
+
+      boardptr = AuraBoardRoot;
+
+      for(chipptr = boardptr->board_chipbase; chipptr != NULL; chipptr =
+chipptr->next_by_board)
+
+        {
+
+          (*chipptr->int_disable)(chipptr); /* make sure no ints can
+come int */
+
+        }
+
+      AuraBoardRoot = boardptr->nextboard;
+
+      if(boardptr->virtbaseaddress0)
+
+        {
+
+          DEBUGPRINT((KERN_ALERT
+
+                      "auraXX50n: unmapping virtual address %p.\n",
+
+                      (void*)boardptr->virtbaseaddress0));
+
+          iounmap((void*)boardptr->virtbaseaddress0);
+
+          boardptr->virtbaseaddress0 = 0;
+
+        }
+
+      if(boardptr->virtbaseaddress2)
+
+        {
+
+          DEBUGPRINT((KERN_ALERT
+
+                      "auraXX50n: unmapping virtual address %p.\n",
+
+                      (void*)boardptr->virtbaseaddress2));
+
+          iounmap((void*)boardptr->virtbaseaddress2);
+
+          boardptr->virtbaseaddress2 = 0;
+
+        }
+
+      kfree(boardptr);
+
+    }
+
+ 
+
+  while(AuraChipRoot)           /* free chip memory */
+
+    {
+
+      chipptr = AuraChipRoot;
+
+      AuraChipRoot = chipptr->next;
+
+      kfree(chipptr);
+
+    }
+
+ 
+
+  while(Sab8253xRoot)           /* free up network stuff */
+
+    {
+
+      SAB_PORT *priv;
+
+      priv = (SAB_PORT *)Sab8253xRoot->priv;
+
+      unregister_netdev(Sab8253xRoot);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+
+      kfree(Sab8253xRoot.name);
+
+#endif
+
+      kfree(Sab8253xRoot);
+
+      Sab8253xRoot = priv->next_dev;
+
+    }
+
+ 
+
+  while(AuraPortRoot)           /* free up port memory */
+
+    {
+
+      portptr = AuraPortRoot;
+
+      AuraPortRoot = portptr->next;
+
+      if(portptr->dcontrol2.receive)
+
+        {
+
+          kfree(portptr->dcontrol2.receive);
+
+        }
+
+      if(portptr->dcontrol2.transmit)
+
+        {
+
+          kfree(portptr->dcontrol2.transmit);
+
+        }
+
+      kfree(portptr);
+
+    }
+
+}
+
+ 
+
+_Design Summary_
+
+ 
+
+The 10 key data structures are shared by all the logic of the system. 
+The logic enforces both exclusive and cooperative access to the physical
+hardware on the basis of certain rules established by the core logic at
+device/port open time. While the driver is mostly self-configuring, the
+data structure sharing simplifies the user interface because an ioctl to
+one driver functionality (e.g., the TTY functionality) configures the
+rest of the driver functionality (e.g., the network and character device
+functionality).   In other words, a single serial port acts virtually as
+three arbitrated devices:  a TTY device, which may be asynchronous,
+synchronous or call out, a network device or a character device.  Yet,
+except at the time of initialization, time of driver unload and very
+early in interrupt processing all hardware details are concealed and the
+driver logic is applied to an abstract, simplified port entity.  Thus,
+the user application interfaces to three abstract virtual devices, which
+have a single configuration interface (otherwise it might be possible to
+have an inconsistent configuration) and not to a complex real single
+port in the context of an equally complex adapter card or unit. This
+simplification makes it possible to provide a high degree of serial
+functionality across the family of Aurora synchronous/asynchronous PCI
+hardware through a straightforward uniform application interface.
+
+ 
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/sab8253xfs.txt linux/drivers/net/wan/8253x/sab8253xfs.txt
--- linux.orig/drivers/net/wan/8253x/sab8253xfs.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/sab8253xfs.txt	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,1303 @@
+*_Functional Specification of SAB8253X ASLX Driver for Linux_*
+
+ 
+
+
+The SAB8253X serial interface chip is very flexible.  It supports most
+of the standard asynchronous serial transmission modes as well as
+synchronous Bit Oriented Protocols (BOPs) and character oriented
+protocols.  The Linux ASLX Driver system provides an extremely flexible
+Linux interface to the SAB8253X serial interface chips that are used on
+the Aurora <http://www.auroratech.com/> XX20 adapter cards and
+Multichannel server units whether they are inserted directly into a host
+bus or whether they are connected via a PCI extension system such as the
+Aurora XP7.
+
+ 
+
+
+  Supported Hardware
+
+ 
+
+The Linux ASLX Driver supports Aurora SAB8253X communications adapter
+cards and systems for PCI bus systems.  Possible adapter card
+configurations are identified as MN20 where M is 1, 2, 4, 8 and N is 0
+or 5.  M is the number of ports.  N = 0 means that the adapter card does
+not support synchronous modes.  N = 5 means the adapter card modes are
+unrestricted.  The multichannel server system consists of an host
+adapter card that attaches to an expansion box via the G-Link connection
+cable.  The expansion box can host 2000, 2500 and 3500 type Expansion
+Boards (EBs).  The 2000 EB provides 15 asynchronous-only RS-232 ports
+and 1 unrestricted RS-232 port.  The 2500 EB provides 16 unrestricted
+RS-232 ports.  The 3500 EB provides 16 unrestricted serial ports, whose
+physical signaling is under software control.  The XP7 is a PCI
+expansion chassis. 
+
+ 
+
+The ASLX correctly identifies the Aurora adapter card or Multichannel
+server and EBs, determines capabilities and provides a software
+interface to configurable capabilities (e.g., a choice of RS-232 [= the
+default], RS 422/423, RS 449, EIA 530, V.35, X.21, RS-485 and none
+[=off] signaling for 3500 EBs).  The use of an XP7 should be transparent
+to the driver.  The ASLX driver will automatically correct incorrectly
+programmed adapter card or Multichannel server serial EEPROMs. 
+Moreover, in addition to the primary serial communications interface,
+the ASLX driver provides a ^Ómaintenance^Ô interface to the serial EEPROMs
+so that user intervention can correct an incorrectly programmed EEPROM.
+
+ 
+
+
+  Serial Communications Interface
+
+ 
+
+The ASLX driver conforms to the standard Linux driver formalism for TTY
+devices, network devices and character devices.
+
+ 
+
+The ASLX Linux driver can like all standard Linux drivers either be
+linked into the kernel or be built as a downloadable module that can
+also be cleanly deloaded.
+
+ 
+
+The ASLX Linux driver functionality provides more than the usual serial
+device driver functionality because it provides the TTY device, network
+device and character device functionality in one package.  Moreover, the
+ASLX Linux driver TTY functionality supports asynchronous TTY devices,
+asynchronous CUA devices and synchronous TTY devices.  The CUA devices
+can also be used in conjunction with the network device and synchronous
+character device functionalities for the purpose of dynamically setting
+up a dialed link via a modem device.
+
+ 
+
+The ASLX Linux driver has been developed for Linux on i386 hardware, but
+it has no specific i386 dependence and after recompilation should be
+able to run with Linux that has been compiled for other hardware.
+
+ 
+
+The driver is structured to minimize Linux 2.4.*-isms.  While it has not
+been built as a Linux 2.2.* driver, rebuilding it to work under Linux
+2.2.* should not be too difficult.
+
+ 
+
+
+  Driver Initialization
+
+ 
+
+Drivers for physical devices usually must provide device detection and
+device initialization.
+
+ 
+
+The initialization or probe routines of the driver detect all the Aurora
+SAB8253X devices in the system (i.e., these routines look for PCI
+devices that have Aurora device and manufacturer IDs) and carry out any
+necessary low-level PCI initialization of the PLX9050 (XX20 adapter
+cards) or AMCC5920 bridge device (Multichannel server host card). 
+
+ 
+
+The initialization routines of the ASLX driver dynamically allocate all
+structures.  The number of Aurora adapter cards in a given system is
+solely limited by the amount of dynamically allocatable kernel memory.
+
+ 
+
+Note that the performance of a system will be dependent on the number of
+active SAB8253X ports, port modes and speeds, the speed of the CPU, the
+number of CPUs, memory design and similar hardware related considerations.
+
+ 
+
+This driver currently does not initialize serial adapter cards of
+similar design but with different device or manufacturer IDs, but users
+will be able to access all the functionality described in this document
+for serial ports on SAB8253X based Aurora adapter cards. 
+
+ 
+
+Extending the initialization to the intrinsic SAB8253X ports of SPARC
+hardware or to similar adapter cards of other manufacturers would not be
+difficult.
+
+ 
+
+Note that the intrinsic SAB8253X ports of the SPARC hardware can serve
+as boot serial consoles because they do not depend on PCI initialization
+as the Aurora adapter cards and multichannel units do.  Currently, the
+Aurora ASLX driver does not support boot console or serial console
+functionality, but extending the driver to provide such functionality
+would not be difficult.
+
+ 
+
+Note further the ASLX driver is designed (viz the Design Specification
+of SAB8253X ASLX Driver for Linux) for hardware that utilizes none of
+the DMA capabilities of SAB8253X extended serial interface controllers. 
+Because the ASLX driver transmits data from sk_buffs and receives data
+into sk_buffs extending the driver to support SAB8253X based adapter
+cards that support DMA would not be particularly difficult..
+
+ 
+
+In addition, the Zilog 85X30, Intel 8X530 and the AMD 85X30 serial
+communication controllers are character oriented devices that could
+easily be supported within the logic of the ASLX driver.  These devices
+do not have the same sort of visible FIFO that the SAB8253X devices
+have, but a FIFO operation looks like a sequence of operations to an
+output or an input register on a device that does not have a visible FIFO. 
+
+ 
+
+
+  The Communications Port
+
+ 
+
+From the standpoint of the Linux operating system, after initialization,
+the device that the operating system accesses is neither the Aurora
+adapter card or Multichannel server nor the SAB8253X chip but is the
+individual communications port of a SAB8253X chip.  Thus a SAB82532 is
+logically two devices, a SAB82538 is logically 8 devices, an Aurora 4520
+logically provides 4 devices, and an Aurora Multichannel server can
+logically provide up to 64 serial communications devices.
+
+ 
+
+Each communications port according to board capabilities and device
+configuration can provide asynchronous communications or synchronous
+communications as well as access to modem signal status.  On a given
+port synchronous communications can either be bit-oriented or
+character-oriented.  Currently, the driver only supports bit-oriented
+HDLC flag-framing and bit-stuffing, but the driver source can be easily
+modified to support BSC character-oriented synchronous communications. 
+
+ 
+
+There are two obvious possible ways to extend the driver to support BSC
+communications.  Either a configuration flag could be added to indicate
+that the synchronous TTY, network and character devices were running in
+BSC mode and not in BOP mode, or new BSC specific TTY, network and
+character devices could be created.  The latter approach would probably
+minimize potential user confusion and errors of connecting BSC ports to
+BOP configured lines and vice-versa.
+
+ 
+
+/Asynchronous Serial Communications Initialization for a Specific Port/
+
+ 
+
+After probing for the hardware, the driver registers the asynchronous
+device dependent routines, whose addresses are values of elements of
+/struct tty_driver/ variables with the device independent TTY driver by
+means of the /tty_register_driver()/ function. 
+
+ 
+
+These functions handle the device dependent aspects of opening a TTY
+port (i.e., completing initialization in asynchronous mode), closing a
+physical TTY port, writing an array of characters to a physical TTY
+port, putting a single character to a physical TTY port, flushing the
+characters in the process of being written to a single TTY port,
+determining how much buffer space is currently available to a single
+physical TTY port, determining how many characters are in the buffer
+space associated with a single physical TTY port, carrying out the
+device dependent aspects of IOCTLs invoked by a user application,
+carrying out flow control at the physical port, carrying out the device
+dependent aspects of setting TERMIOs, handling asynchronous break, and
+waiting for a physical TTY port to transmit all characters associated
+with the port.  Other elements of the /struct_tty_driver/ are
+initialized with information used for proc files and other TTY driver
+functionality. 
+
+ 
+
+/Asynchronous Serial Communications Functionality/
+
+ 
+
+The driver supports the standard Linux asynchronous TTY and call out
+functionality, which includes all standard STTY and TERMIO IOCTLs, all
+the standard speeds, all the standard flow control formalisms, etc.,
+that can be found in the Linux STTY and TERMIO manual pages. 
+
+ 
+
+Note that custom IOCTLs have been added to support the configuration of
+signaling on the WAN multichannel server 3500 cards.
+
+ 
+
+In addition, customized IOCTLs have been added to support reading and
+programming the serial EEPROM associated with the various Aurora adapter
+cards and units.  These are of limited use for users but are helpful in
+debugging cards.  Changing the manufacturer or device IDs can render an
+adapter card or unit unusable.
+
+ 
+
+The asynchronous TTY and call out functionality obey the standard Linux
+block_til_ready logic than enforces arbitration between call out and
+asynchronous TTY access.  Current Linux design documents deprecate the
+separate asynchronous call out functionality, but it is not particularly
+obvious how to provide asynchronous call out functionality to set up
+synchronous point-to-point links dynamically without the separate call
+out devices. 
+
+ 
+
+To wit, ckermit does not use the cua devices.  The ckermit user sets a
+tty line, turns off carrier watch, executes the connect command, dials
+out and then continues with his terminal session using the same tty
+device on which he dialed out after the modems connect.  This procedure
+would not work if the point-to-point connection were to be synchronous
+(or in fact if the point-to-point session were to carry X.25 traffic for
+a PAD session).  The cua devices are useful to deal with such /mixed
+mode/ dynamically connected sessions.
+
+ 
+
+Note that in the past Linux has required that TTY devices be named
+/dev/ttyS* and that call out devices be named /dev/cua*.  The devices
+can still be so named, but this naming convention is not obligatory.
+
+ 
+
+The asynchronous TTY devices use major device 4 and the call out device
+uses major device 5.  This assignment is a convention and can be changed
+if necessary.
+
+ 
+
+Ports are selected by the minor device number.  Port minor device
+numbers increase strictly monotonically in accord with the numbering
+convention of the adapter card or adapter unit.[1] <#_ftn1> 
+
+ 
+
+The file /proc/tty/driver/auraserial that is created by the ASLX driver
+helps in mapping port to minor device number.  The call out device and
+TTY device of a single port have the same minor device number.  To
+calculate the port number of an asynchronous TTY device or of a call out
+device, subtract the minor device number of the first ASLX port from the
+minor device number of the TTY or CUA device of interest.
+
+ 
+
+/Synchronous Serial TTY Communications Initialization for a Specific Port/
+
+ 
+
+After probing for the hardware, the driver registers the synchronous
+device dependent routines, whose addresses are values of elements of
+/struct_tty_driver/ variables with the device independent TTY driver by
+means of the /tty_register_driver()/ function. 
+
+ 
+
+Just as in the case of asynchronous TTYs, these functions handle the
+device dependent aspects of opening a TTY port (i.e., completing
+initialization in synchronous mode), closing a physical TTY port,
+writing an array of characters to a physical TTY port, putting a single
+character to a physical TTY port, flushing the characters in the process
+of being written to a single TTY port, determining how much buffer space
+is currently available to a single physical TTY port, determining how
+many characters are in the buffer space associated with a single
+physical TTY port, carrying out the device dependent aspects of IOCTLs
+invoked by a user application, carrying out flow control at the physical
+port, carrying out the device dependent aspects of setting TERMIOs, and
+waiting for a physical TTY port to transmit all characters associated
+with the port.  Other elements of the /struct tty_driver/ are
+initialized with information used for proc files and other TTY driver
+functionality. 
+
+
+   
+
+
+  Synchronous Serial TTY Communications Functionality
+
+ 
+
+By default synchronous serial TTY communications takes place on devices
+named /dev/sttyS*, but such names are not required.  The major device
+number associated with these ports is dynamically allocated and can be
+found in the /proc/tty/driver/auraserial file.
+
+ 
+
+Synchronous TTYs act just like asynchronous TTYs (e.g., getty^Òs may be
+associated with them, and a user may invoke cu on them) in so far as
+possible (to wit, break processing is not possible on a synchronous TTY).
+
+ 
+
+As one cannot generally purchase synchronous TTY hardware, synchronous
+TTYs are probably most useful in porting a synchronous TTY application
+from another type of Unix that made use of line disciplines in some
+legacy application.
+
+ 
+
+Note that the synchronous TTY driver logic obeys the block_til_ready
+arbitration logic so that asynchronous call out devices can be used to
+set up point-to-point synchronous TTY links.
+
+ 
+
+The synchronous TTY devices support all the standard STTY and TERMIO
+IOCTLs as well as the custom IOCTLs that are described in the previous
+section.  Because these IOCTLs do not deal with the issue of synchronous
+clock mode, IOCTLs for setting custom bit rates as well as for
+programming and reading synchronous clock modes are provided.  These
+IOCTLs are also accessible through the asynchronous TTY and call out
+devices.  Configuring a port to provide clock only affects the port when
+it is used as a synchronous device.
+
+ 
+
+The minor device number associated with a specific port is the same
+whether it is used as a synchronous TTY, an asynchronous TTY or a call
+out device.  To calculate the port number of a synchronous TTY device,
+subtract the minor device number of the first ASLX port from the minor
+device number of the TTY device of interest.
+
+ 
+
+
+  Synchronous Serial Network Device Initialization
+
+
+   
+
+The synchronous network device functionality is to some extent an
+extension of the synchronous TTY functionality.
+
+ 
+
+After probing for the SAB8253X hardware, the software in addition to
+invoking /tty_register_driver()/ also invokes /register_netdev()/ for
+each SAB8253X port.  This registration makes it possible to connect
+SAB8253X ports into the Linux network layer via ifconfig commands like
+the following, which opens the device.
+
+ 
+
+*ifconfig 8253x001 */{network address or host name}/
+
+*ifconfig 8253x001* *hw ether* /{MAC address}/
+
+ 
+
+Note that by default the number part of the network device name
+corresponds to the serial port number (i.e., the minor device number of
+the associated serial port minus the value of an internal kernel
+variable called sab8253x_minor_start [equal to the minor device number
+of the first TTY device listed in the /proc/tty/driver/auraserial
+file]).  The module parameter, sab8253x_minor_start, identifies the
+minor device number at which Aurora asynchronous TTY, synchronous TTY
+and call out devices start. 
+
+ 
+
+The network driver dynamically allocates memory specifically for its use
+as needed on network device open and frees up network device driver
+memory on network device close.
+
+ 
+
+
+  Synchronous Serial Network Devices
+
+ 
+
+The network devices like all standard Linux network devices are not
+visible in the /dev directory. 
+
+ 
+
+If an 8 port adapter card is installed in a Linux system that has an
+Ethernet port, the new SAB8253X Linux driver makes it possible to use
+the system as an 8 WAN x 1 LAN port router.
+
+ 
+
+The SAB8253X network device functionality emulates an Ethernet device. 
+The network device functionality requires the implementation of the
+following functions.  As a consequence, the network portion of the ASLX
+driver implements the standard Ethernet functionality as far as
+possible.  In addition, the network driver requires a special IOCTL to
+set a pseudomac address.
+
+ 
+
+In addition, the network driver needs some functionality that goes
+beyond the standard Ethernet functionality, for it must be possible
+dynamically to establish or reestablish synchronous links by means of
+the asynchronous call out device logic.
+
+ 
+
+Using the call out device logic in conjunction with the network device
+requires an extension of the call out device arbitration logic.
+
+ 
+
+The standard call out device arbitration logic requires that the call
+out device start first and be invoked from the same process or process
+group that opens the TTY device while the TTY device blocks until the
+call out succeeds.  Such logic is inapplicable to the network device. 
+The call out device must be opened while the corresponding network
+device is open.  The corresponding network device never blocks but
+informs the network layer of outgoing network congestion.
+
+ 
+
+ 
+
+
+  Synchronous Serial Character Device Initialization
+
+
+   
+
+The synchronous character device functionality is to some extent an
+extension of the synchronous network functionality.
+
+ 
+
+After probing for the SAB8253X hardware, the software besides invoking
+/tty_register_driver()/ also invokes /register_chardev()/ in addition to
+/register_netdev()/ for each SAB8253X port.  This registration makes it
+possible to access SAB8253X port packet functionality independently of
+the Linux network layer via function calls associated with a standard
+character device.
+
+ 
+
+The major device number of the synchronous serial character device can
+be found in the /proc/devices file.  Note that by default the minor
+device number of each synchronous serial character device file (e.g.,
+/dev/sab8253xC* if mknod is invoked as below) corresponds to the minor
+device number of the associated serial port minus the value of an
+internal kernel variable/module parameter called sab8253x_minor_start
+(equal to the minor device number of the first TTY device indentified in
+the /proc/tty/driver/auraserial file).  The variable
+sab8253x_minor_start identifies the minor device number at which Aurora
+asynchronous TTY, synchronous TTY and call out devices start. 
+
+ 
+
+*mknod /dev/sab8253xC*{number} *c* {major dev number} {minor dev number}
+
+ 
+
+The character driver dynamically allocates memory specifically for its
+use as needed on network device open and frees up network device driver
+memory on network device close.
+
+ 
+
+/Synchronous Serial Character Device/
+
+/
+/
+
+/ /
+
+ 
+
+The SAB8253X synchronous character device functionality implements
+essentially the same functions as the SAB8253X synchronous network
+device functionality with the addition of a read/receive function that
+will pass received data packets to a user application and with the
+addition of an fasync helper function if the driver is to support
+asynchronous notification to the user application.  This functionality
+is provided so that users that wish to implement their own bit oriented
+synchronous protocols may directly access the serial data stream without
+having to work around the TTY driver or the Linux network layer. 
+
+ 
+
+Note that while the network device is only opened once by the Linux
+network layer, the character device may be opened multiple times by a
+process or defined process group just like the TTY driver.
+
+ 
+
+In a sense, the synchronous character device implements an emulation of
+Solaris putmsg/getmsg functionality for Aurora^Òs synchronous serial
+device.  The availability of such emulation should help the portation of
+applications from Solaris to a Linux platform that uses Aurora hardware
+and software.
+
+ 
+
+The asynchronous functionality is useful for those protocols like LAPB,
+which do not work well if the physical driver buffers up low priority
+packets while other packets are being transmitted.  The asynchronous
+notification can provide notification that there are no packets of any
+sort in the process of being transmitted and that there are no high
+priority packets buffered within the driver.  On receiving this
+notification, the user application could transmit the next low priority
+packet.
+
+ 
+
+Note that the synchronous serial character device interacts with the
+call out device almost exactly like the TTY devices.
+
+ 
+
+In the interest of keeping the interfaces simple and not introducing
+extra foci for bugs, there are no IOCTLs implemented for this device. 
+If it is necessary to set a clocking mode or baud rate etc., the IOCTL
+call is made via the STTY, TERMIO or extended IOCTLs associated with the
+TTY driver functionalities. 
+
+ 
+
+
+  Common Interrupt Handling Functionality
+
+ 
+
+All the above functionality shares a common interrupt handler that
+invokes indirectly functionality-specific receive_chars, transmit_chars
+and check_status functions to receive character data, to transmit
+character data and to check signal status.
+
+ 
+
+In other words, the interrupt handler must support all possible
+functionalities simultaneously on a group of ports associated with a
+single interrupt simultaneously. 
+
+ 
+
+Linux is not capable of registering an interrupt handler for each port
+separately (when there are many ports ^Ö the specialty of Aurora
+hardware), and such an approach would have lower performance than having
+a single interrupt handler that polled the ports.  In any case,
+interrupt status registers associated with the Aurora hardware often
+indicate interrupt status on several ports simultaneous.  It is
+preferable to read such registers once especially with the Multichannel
+server hardware.
+
+ 
+
+
+  Proc Files
+
+ 
+
+The following traces show how the driver interacts with (or creates)
+various /proc status files.
+
+ 
+
+
+martillo@ylith:~ > cat /proc/tty/driver/auraserial
+
+serinfo:2.01N driver:1.22
+
+TTY MAJOR = 4, CUA MAJOR = 5, STTY MAJOR = 254.
+
+128: port 0: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+129: port 1: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openA:
+NOPRG
+
+130: port 2: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openA:
+NOPRG
+
+131: port 3: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+132: port 4: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+133: port 5: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openS:
+NOPRG
+
+134: port 6: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+135: port 7: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+136: port 0: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+137: port 1: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+138: port 2: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+139: port 3: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+140: port 4: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+141: port 5: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+142: port 6: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+143: port 7: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+144: port 0: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+145: port 1: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+146: port 2: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+147: port 3: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+148: port 4: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS530
+
+149: port 5: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+150: port 6: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+151: port 7: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+152: port 0: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+153: port 1: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+154: port 2: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+155: port 3: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+156: port 4: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+157: port 5: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+158: port 6: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+159: port 7: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+160: port 0: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+161: port 1: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+162: port 2: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+163: port 3: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+164: port 4: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+165: port 5: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+166: port 6: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+167: port 7: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+168: port 0: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+169: port 1: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+170: port 2: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+171: port 3: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+172: port 4: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+173: port 5: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+174: port 6: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+175: port 7: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+176: port 0: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+177: port 1: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+178: port 2: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+179: port 3: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+180: port 4: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+181: port 5: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+182: port 6: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+183: port 7: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+184: port 0: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+185: port 1: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+186: port 2: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+187: port 3: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+188: port 4: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+189: port 5: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+190: port 6: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+191: port 7: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+192: port 0: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+193: port 1: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+194: port 2: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+195: port 3: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+196: port 4: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+197: port 5: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+198: port 6: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+199: port 7: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+ 
+
+The above file indicates the minor device number, port number relative
+to chip, chip type, chip version number, chip number (meaningful for
+4X20 and multichannel servers), interface type, bus number, slot number,
+port availability (AO = asynchronous only, NR = No Restrictions, or NA =
+Not Available),  status (closed, open Synchronous, open Asynchronous,
+open Character, or open Network), and signaling type (NOPRG = not
+selectable programmatically; other possibilities inclue OFF, RS232,
+RS442, RS449, RS530 and V.35).
+
+ 
+
+
+martillo@ylith:/proc > cat /proc/pci
+
+PCI devices found:
+
+  Bus  0, device   0, function  0:
+
+    Host bridge: Intel Corporation 82820 820 (Camino) Chipset Host
+Bridge (MCH) (rev 4).
+
+      Prefetchable 32 bit memory at 0xf8000000 [0xfbffffff].
+
+  Bus  0, device   1, function  0:
+
+    PCI bridge: Intel Corporation 82820 820 (Camino) Chipset PCI to AGP
+Bridge (rev 4).
+
+      Master Capable.  Latency=64.  Min Gnt=8.
+
+  Bus  0, device  30, function  0:
+
+    PCI bridge: Intel Corporation 82801AA PCI Bridge (rev 2).
+
+      Master Capable.  No bursts.  Min Gnt=2.
+
+  Bus  0, device  31, function  0:
+
+    ISA bridge: Intel Corporation 82801AA ISA Bridge (LPC) (rev 2).
+
+  Bus  0, device  31, function  1:
+
+    IDE interface: Intel Corporation 82801AA IDE (rev 2).
+
+      I/O at 0xffa0 [0xffaf].
+
+  Bus  0, device  31, function  2:
+
+    USB Controller: Intel Corporation 82801AA USB (rev 2).
+
+      IRQ 10.
+
+      I/O at 0xef80 [0xef9f].
+
+  Bus  0, device  31, function  3:
+
+    SMBus: Intel Corporation 82801AA SMBus (rev 2).
+
+      IRQ 9.
+
+      I/O at 0xefa0 [0xefaf].
+
+  Bus  1, device   0, function  0:
+
+    VGA compatible controller: nVidia Corporation NV15 (Geforce2 GTS)
+(rev 164).
+
+      IRQ 11.
+
+      Master Capable.  Latency=64.  Min Gnt=5.Max Lat=1.
+
+      Non-prefetchable 32 bit memory at 0xfd000000 [0xfdffffff].
+
+      Prefetchable 32 bit memory at 0xe8000000 [0xefffffff].
+
+  Bus  2, device   8, function  0:
+
+    Ethernet controller: 3Com Corporation 3c905C-TX [Fast Etherlink]
+(rev 120).
+
+      IRQ 11.
+
+      Master Capable.  Latency=64.  Min Gnt=10.Max Lat=10.
+
+      I/O at 0xdc00 [0xdc7f].
+
+      Non-prefetchable 32 bit memory at 0xfeacfc00 [0xfeacfc7f].
+
+  Bus  2, device   9, function  0:
+
+    Unknown mass storage controller: Promise Technology, Inc. 20267 (rev 2).
+
+      IRQ 9.
+
+      Master Capable.  Latency=64. 
+
+      I/O at 0xdff0 [0xdff7].
+
+      I/O at 0xdfe4 [0xdfe7].
+
+      I/O at 0xdfa8 [0xdfaf].
+
+      I/O at 0xdfe0 [0xdfe3].
+
+      I/O at 0xdf00 [0xdf3f].
+
+      Non-prefetchable 32 bit memory at 0xfeae0000 [0xfeafffff].
+
+  Bus  2, device  10, function  0:
+
+    Communication controller: PCI device 125c:0101 (Aurora Technologies,
+Inc.) (rev 1).
+
+      IRQ 3.
+
+      Non-prefetchable 32 bit memory at 0xfeacf800 [0xfeacf87f].
+
+      Non-prefetchable 32 bit memory at 0xfeacf400 [0xfeacf5ff].
+
+      Non-prefetchable 32 bit memory at 0xfeacf000 [0xfeacf1ff].
+
+  Bus  2, device  11, function  0:
+
+    Communication controller: PCI device 125c:0101 (Aurora Technologies,
+Inc.) (rev 1).
+
+      IRQ 10.
+
+      Non-prefetchable 32 bit memory at 0xfeacec00 [0xfeacec7f].
+
+      Non-prefetchable 32 bit memory at 0xfeace000 [0xfeace7ff].
+
+      Non-prefetchable 32 bit memory at 0xfeacd800 [0xfeacdfff].
+
+ 
+
+The above file indications PCI resources that the Aurora adapter card or
+unit uses.
+
+ 
+
+
+martillo@ylith:/proc > cat /proc/devices
+
+Character devices:
+
+  1 mem
+
+  2 pty
+
+  3 ttyp
+
+  4 ttyS
+
+  5 cua
+
+  7 vcs
+
+ 10 misc
+
+ 14 sound
+
+128 ptm
+
+136 pts
+
+162 raw
+
+180 usb
+
+253 sab8253xc
+
+254 sttyS
+
+ 
+
+Block devices:
+
+  2 fd
+
+ 22 ide1
+
+ 33 ide2
+
+ 
+
+The above file provides the major device number associated with the
+synchronous serial character device.
+
+ 
+
+martillo@ylith:/proc > cat /proc/modules
+
+ASLX                   84336   5 (autoclean)
+
+ 
+
+The above file indicates that the ASLX module has been dynamically
+linked into the kernel.  If the ASLX is statically linked into the
+kernel, it will not appear in this file.
+
+ 
+
+martillo@ylith:/proc > cat /proc/interrupts
+
+           CPU0      
+
+  0:      25311          XT-PIC  timer
+
+  1:        401          XT-PIC  keyboard
+
+  2:          0          XT-PIC  cascade
+
+  3:         22          XT-PIC  sab8253x
+
+  9:      20055          XT-PIC  ide2
+
+ 10:         27          XT-PIC  usb-uhci, sab8253x
+
+ 11:         38          XT-PIC  eth0
+
+ 12:       2720          XT-PIC  PS/2 Mouse
+
+ 15:          7          XT-PIC  ide1
+
+NMI:          0
+
+LOC:          0
+
+ERR:          0
+
+MIS:          0
+
+ 
+
+The above file indicates the interrupts that are being used by Aurora
+adapter cards.
+
+
+martillo@ylith:/proc/net > cat /proc/net/dev
+
+Inter-|   Receive                                                |  Transmit
+
+ face |bytes    packets errs drop fifo frame compressed
+multicast|bytes    packets errs drop fifo colls carrier compressed
+
+    lo:    1080      16    0    0    0     0          0         0    
+1080      16    0    0    0     0       0          0
+
+  eth0:    2316      19    0    0    0     0          0         0 
+   1836      19    0    0    0     1       0          0
+
+8253x000:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x001:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x002:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x003:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x004:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x005:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x006:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x007:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x008:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x009:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x010:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x011:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+ 
+
+The above file provides statistics on ASLX network interfaces.
+
+ 
+
+martillo@ylith:/proc > cat /proc/iomem
+
+00000000-0009fbff : System RAM
+
+0009fc00-0009ffff : reserved
+
+000a0000-000bffff : Video RAM area
+
+000c0000-000c7fff : Video ROM
+
+000cc000-000cdfff : Extension ROM
+
+000ce000-000ce7ff : Extension ROM
+
+000f0000-000fffff : System ROM
+
+00100000-0ffbffff : System RAM
+
+  00100000-00260dfe : Kernel code
+
+  00260dff-002f325f : Kernel data
+
+0ffc0000-0fff7fff : ACPI Tables
+
+0fff8000-0fffffff : ACPI Non-volatile Storage
+
+e4600000-f46fffff : PCI Bus #01
+
+  e8000000-efffffff : nVidia Corporation NV15 (Geforce2 GTS)
+
+f4700000-f47fffff : PCI Bus #02
+
+f8000000-fbffffff : Intel Corporation 82820 820 (Camino) Chipset Host
+Bridge (MCH)
+
+fc900000-fe9fffff : PCI Bus #01
+
+  fd000000-fdffffff : nVidia Corporation NV15 (Geforce2 GTS)
+
+fea00000-feafffff : PCI Bus #02
+
+  feacd800-feacdfff : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feace000-feace7ff : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacec00-feacec7f : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacf000-feacf1ff : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacf400-feacf5ff : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacf800-feacf87f : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacfc00-feacfc7f : 3Com Corporation 3c905C-TX [Fast Etherlink]
+
+  feae0000-feafffff : Promise Technology, Inc. 20267
+
+ffb80000-ffbfffff : reserved
+
+fff00000-ffffffff : reserved
+
+ 
+
+The above file indicate the I/O memory mapping of the Aurora devices.
+
+ 
+
+
+  ASLX IOCTL Summary
+
+ 
+
+The ASLX driver supports the standard TTY and Ethernet driver IOCTLs. 
+In addition, the following TTY driver IOCTLs are supported (on
+asynchronous/synchronous TTY devices and on asynchronous CUA devices):
+
+ 
+
+/1.     /set custom baud rate,//
+
+/2.     /get baud rate,//
+
+/3.     /read EEPROM,//
+
+/4.     /set EEPROM,//
+
+/5.     /get clocking mode,//
+
+/6.     /set clocking mode//
+
+/7.     /get WAN MCS signaling configuration,//
+
+/8.     /set WAN MCS signaling configuration,//
+
+/9.     /clear network driver statistics.//
+
+ 
+
+In addition, the ASLX driver supports a network IOCTL to clear interface
+statistics.
+
+ 
+
+/Source Code Functionality/
+
+ 
+
+To facilitate user modification and extension of the ASLX driver, the
+code has been written as clearly as possible, and the various
+functionalities (asynchronous TTY, synchronous TTY, network device and
+character devices, initialization, interrupt, bridge initialization,
+etc) have their own files to discourage massive unsupportable changes to
+driver logic.
+
+ 
+
+/Summary/
+
+ 
+
+The driver attempts to provide as much as possible of the functionality
+of the SAB8253X communication controller and the Aurora hardware in a
+form that is both useful and friendly to the Linux user with as much
+self-configuration as possible and by means of the standard Linux
+interfaces.  The custom portion of the interface has been minimized as
+much as possible, and duplication of this interface across the TTY,
+network, and synchronous serial character interface has been eschewed. 
+
+ 
+
+In this version of the driver for each type of custom configuration,
+there is only one IOCTL, and this custom configuration is shared among
+all the functionalities that share a given physical port. 
+
+ 
+
+In most applications of this driver, the user will generally not have to
+use any of the custom IOCTLs unless he is using a serial port as a
+synchronous device that is providing clock, in which case he would have
+to use an IOCTL to make the port provide clock and he might have to use
+another IOCTL to set a custom baud rate.  In all cases, if the network
+driver is used on a given port, that port would have to be assigned a
+pseudomac address by means of the standard ifconfig command.
+
+ 
+
+Altogether the driver provides the functionality needed for massive
+asynchronous and synchronous TTY connectivity, for shake-and-bake WAN
+networking and for synchronous legacy interconnect by means of a custom
+application.  Linux systems that host Aurora communications cards that
+interface to the OS via the ASLX driver can replace a massive
+point-of-sales servers, expensive WAN networking systems or custom
+synchronous legacy protocol-to-standard protocol interconnect hardware.
+
+ 
+
+
+------------------------------------------------------------------------
+
+[1] <#_ftnref1> In the ASLX driver internal device lists, adapter cards
+and adapter units are ordered in reverse order to the ordering on the
+kernel PCI device list by type.  Multiport adapter cards are ordered
+last.  Compact multiport adapter cards are ordered next.  And
+Multichannel units are ordered next, i.e., first.   The ordering of
+adapter cards and interface chips on internal driver lists currently
+does not affect external functionality with one possible exception. 
+Adapter cards are also listed on per type per interrupt lists.   If
+there are many cards associated with a given interrupt, it is possible
+that list order might cause maximum delay in loading and emptying port
+FIFOs to be exceeded.  As every card on the interrupt list must be
+interrogated when an interrupt is received, avoiding the problem might
+require moving to a faster processor based system.  Multi-CPU hardware
+would not help.
+
+ 
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/sab8253xov.txt linux/drivers/net/wan/8253x/sab8253xov.txt
--- linux.orig/drivers/net/wan/8253x/sab8253xov.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/sab8253xov.txt	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,47 @@
+The Aurora Linux 2.4.* software package for the Siemens/Infineon 8253X
+based PCI adapter card product line (2520, 4520, 4020, 8520, WMS and LMS
+communications controllers) provides the following benefits to the user.
+
+ 
+
+1.        A Linux Asynchronous TTY driver that supports serial
+connections to asynchronous TTYs with the standard Linux/Unix terminal
+capabilities as well as custom baud rates.  The asynchronous TTY driver
+can also support connections to computers that support standard
+asynchronous terminal emulation programs, such as cu, tip, kermit or
+hyperterm.  The asynchronous TTY driver can also support file transfer
+via standard asynchronous file transfer programs like kermit.  In
+addition, the asynchronous TTY driver can be used by asynchronous SLIP
+or PPP to provide network connectivity.
+
+2.        A Linux Synchronous TTY driver that supports all of the above
+for synchronous TTY connections.  Because one cannot generally purchase
+synchronous TTYs, this functionality is most useful with software
+terminal emulators and with synchronous PPP implementations that assume
+an underlying synchronous terminal driver.
+
+3.        A Linux Synchronous Network driver that provides a synchronous
+serial ethernet interface.  This interface provides a simple
+straightforward method of synchronous wide-area interconnection that
+works via the standard Linux Ethernet network and bridging interfaces. 
+Some routers and bridges support this interface.
+
+4.        A Linux Synchronous Character driver that provides a standard
+read/write interface to the network driver functionality (i.e., packet
+read and packet write capability) and that can emulate the Solaris
+putmsg/getmsg interface.  This driver is useful for users that wish to
+implement their own protocol software within user applications.
+
+5.        The Aurora Linux software provides the capability of dial-up
+connection set-up for any of the previous drivers.  This dial-up
+capability follows the /dev/cua convention of Linux 2.2* and Linux 2.4.*
+kernels.
+
+6.        Source is provided so that users may make custom modifications
+to drivers.  Adding BISYNC or cHDLC support would be fairly
+straightforward and may become available in later releases.  This source
+could provide a starting point for implementing drivers for other
+operating systems.  The source is partitioned by functionality and comes
+with functional and design specifications as well as other documentation
+useful to users and implementers.
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/8253x/sp502.h linux/drivers/net/wan/8253x/sp502.h
--- linux.orig/drivers/net/wan/8253x/sp502.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/8253x/sp502.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,48 @@
+/* -*- linux-c -*- */
+/*
+ * sp502.h - chip definitions for the
+ *	Sipex SP502 Multi-Mode Serial Transceiver
+ *
+ * Bjoren Davis, Aurora Technologies, 21. January, 1995.
+ *
+ * COPYRIGHT (c) 1995-1999 BY AURORA TECHNOLOGIES, INC., WALTHAM, MA.
+ *
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ *	file: sp502.h
+ *	author: bkd
+ *	created: 1/21/95
+ *	revision info: $Id: sp502.h,v 1.3 2002/02/10 22:17:26 martillo Exp $
+ *	ripped off from: Header: /vol/sources.cvs/dev/acs/include/sp502.h,v 1.4 1996/11/07 21:35:10 bkd Exp 
+ *	Used without modification in the multichannel server portion of the Linux driver by Joachim Martillo
+ */
+
+#ifndef _SP502_H
+#define _SP502_H
+
+#ifdef sun
+#   pragma ident "@(#)$Header: /usr/local/cvs/linux-2.4.6/drivers/net/wan/8253x/sp502.h,v 1.3 2002/02/10 22:17:26 martillo Exp $"
+#endif
+
+/*
+ * These following nibble values are from the SP502 Data Sheet, which
+ *  is in the Sipex Interface Products Catalog, 1994 Edition, pages
+ *  168 and 170.
+ */
+
+/* same order as the modes in 8253xioc.h and as the names in 8253xtty.c and as the progbytes in 8253xmcs.c*/
+
+#define SP502_OFF	((unsigned char) 0x00)
+#define SP502_RS232	((unsigned char) 0x02)
+#define SP502_RS422	((unsigned char) 0x04)
+#define SP502_RS485	((unsigned char) 0x05)
+#define SP502_RS449	((unsigned char) 0x0c)
+#define SP502_EIA530	((unsigned char) 0x0d)
+#define SP502_V35	((unsigned char) 0x0e)
+
+#endif		/* !_SP502_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/Config.in linux/drivers/net/wan/Config.in
--- linux.orig/drivers/net/wan/Config.in	2001-08-12 17:38:48.000000000 +0000
+++ linux/drivers/net/wan/Config.in	2002-07-20 01:08:25.000000000 +0000
@@ -24,6 +24,7 @@
       dep_tristate '    Support for COMX/CMX/HiCOMX boards' CONFIG_COMX_HW_COMX $CONFIG_COMX
       dep_tristate '    Support for LoCOMX board' CONFIG_COMX_HW_LOCOMX $CONFIG_COMX
       dep_tristate '    Support for MixCOM board' CONFIG_COMX_HW_MIXCOM $CONFIG_COMX
+      dep_tristate '    Support for MUNICH based boards: SliceCOM, PCICOM (WelCOM)' CONFIG_COMX_HW_MUNICH $CONFIG_COMX
       dep_tristate '    Support for HDLC and syncPPP protocols on MultiGate boards' CONFIG_COMX_PROTO_PPP $CONFIG_COMX
       if [ "$CONFIG_LAPB" = "y" ]; then
 	 dep_tristate '    Support for LAPB protocol on MultiGate boards' CONFIG_COMX_PROTO_LAPB $CONFIG_COMX
@@ -49,6 +50,12 @@
 
    tristate '  LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards' CONFIG_LANMEDIA
 
+#
+# ATI's sync/async boards. Currently 2520, 4020, 4520, 8520 -- 0 in second digit means async only
+#
+
+   tristate '  Aurora Technology, Inc. synchronous asynchronous PCI cards V2' CONFIG_ATI_XX20
+
 # There is no way to detect a Sealevel board. Force it modular
 
    dep_tristate '  Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/Makefile linux/drivers/net/wan/Makefile
--- linux.orig/drivers/net/wan/Makefile	2002-02-25 19:38:01.000000000 +0000
+++ linux/drivers/net/wan/Makefile	2002-07-20 01:08:23.000000000 +0000
@@ -29,6 +29,7 @@
 obj-$(CONFIG_COMX_HW_COMX)	+= 				comx-hw-comx.o
 obj-$(CONFIG_COMX_HW_LOCOMX)	+= z85230.o	syncppp.o	comx-hw-locomx.o
 obj-$(CONFIG_COMX_HW_MIXCOM)	+=				comx-hw-mixcom.o
+obj-$(CONFIG_COMX_HW_MUNICH)	+=				comx-hw-munich.o
 obj-$(CONFIG_COMX_PROTO_PPP)	+=		syncppp.o	comx-proto-ppp.o
 obj-$(CONFIG_COMX_PROTO_LAPB)	+=				comx-proto-lapb.o
 obj-$(CONFIG_COMX_PROTO_FR)	+=				comx-proto-fr.o
@@ -44,6 +45,13 @@
 ifeq ($(CONFIG_LANMEDIA),y)
   obj-y += lmc/lmc.o
 endif
+
+subdir-$(CONFIG_ATI_XX20) += 8253x
+
+ifeq ($(CONFIG_ATI_XX20),y)
+  obj-y += 8253x/ASLX.o
+endif
+
  
 obj-$(CONFIG_DLCI)		+= dlci.o 
 obj-$(CONFIG_SDLA)		+= sdla.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/comx-hw-locomx.c linux/drivers/net/wan/comx-hw-locomx.c
--- linux.orig/drivers/net/wan/comx-hw-locomx.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/net/wan/comx-hw-locomx.c	2002-07-20 01:08:25.000000000 +0000
@@ -154,12 +154,10 @@
 		return -ENODEV;
 	}
 
-	if (check_region(dev->base_addr, hw->io_extent)) {
+	if (!request_region(dev->base_addr, hw->io_extent, dev->name)) {
 		return -EAGAIN;
 	}
 
-	request_region(dev->base_addr, hw->io_extent, dev->name);
-
 	hw->board.chanA.ctrlio=dev->base_addr + 5;
 	hw->board.chanA.dataio=dev->base_addr + 7;
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/comx-hw-munich.c linux/drivers/net/wan/comx-hw-munich.c
--- linux.orig/drivers/net/wan/comx-hw-munich.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/comx-hw-munich.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,2860 @@
+/*
+ * Hardware-level driver for the SliceCOM board for Linux kernels 2.4.X
+ *
+ * Current maintainer / latest changes: Pasztor Szilard <don@itc.hu>
+ *
+ * Original author: Bartok Istvan <bartoki@itc.hu>
+ * Based on skeleton by Tivadar Szemethy <tiv@itc.hu>
+ *
+ * 0.51:
+ *      - port for 2.4.x
+ *	- clean up some code, make it more portable
+ *	- busted direct hardware access through mapped memory
+ *	- fix a possible race
+ *	- prevent procfs buffer overflow
+ *
+ * 0.50:
+ *	- support for the pcicom board, lots of rearrangements
+ *	- handle modem status lines
+ *
+ * 0.50a:
+ *	- fix for falc version 1.0
+ *
+ * 0.50b: T&t
+ *	- fix for bad localbus
+ */
+
+#define VERSION		"0.51"
+#define VERSIONSTR	"SliceCOM v" VERSION ", 2002/01/07\n"
+
+#include <linux/config.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/netdevice.h>
+#include <linux/proc_fs.h>
+#include <asm/delay.h>
+#include <asm/types.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+
+#define COMX_NEW
+
+#ifndef COMX_NEW
+#include "../include/comx.h"
+#include "../include/munich32x.h"
+#include "../include/falc-lh.h"
+#else
+#include "comx.h"
+#include "munich32x.h"
+#include "falc-lh.h"
+#endif
+
+MODULE_AUTHOR
+    ("Bartok Istvan <bartoki@itc.hu>, Gergely Madarasz <gorgo@itc.hu>, Szilard Pasztor <don@itc.hu>");
+MODULE_DESCRIPTION
+    ("Hardware-level driver for the SliceCOM and PciCOM (WelCOM) adapters");
+
+/*
+ *	TODO: az ilyenek a comxhw.h -ban szoktak lenni, idovel menjenek majd oda:
+ */
+
+#define FILENAME_BOARDNUM	"boardnum"	/* /proc/comx/comx0.1/boardnum          */
+#define FILENAME_TIMESLOTS	"timeslots"	/* /proc/comx/comx0.1/timeslots         */
+#define FILENAME_FRAMING	"framing"	/* /proc/comx/comx0.1/framing           */
+#define FILENAME_LINECODE	"linecode"	/* /proc/comx/comx0.1/linecode          */
+#define FILENAME_CLOCK_SOURCE	"clock_source"	/* /proc/comx/comx0.1/clock_source      */
+#define FILENAME_LOOPBACK	"loopback"	/* /proc/comx/comx0.1/loopback          */
+#define FILENAME_REG		"reg"		/* /proc/comx/comx0.1/reg               */
+#define FILENAME_LBIREG		"lbireg"	/* /proc/comx/comx0.1/lbireg            */
+
+#define SLICECOM_BOARDNUM_DEFAULT	0
+
+#define SLICECOM_FRAMING_CRC4		1
+#define SLICECOM_FRAMING_NO_CRC4	2
+#define SLICECOM_FRAMING_DEFAULT	SLICECOM_FRAMING_CRC4
+
+#define SLICECOM_LINECODE_HDB3		1
+#define SLICECOM_LINECODE_AMI		2
+#define SLICECOM_LINECODE_DEFAULT	SLICECOM_LINECODE_HDB3
+
+#define SLICECOM_CLOCK_SOURCE_LINE	1
+#define SLICECOM_CLOCK_SOURCE_INTERNAL	2
+#define SLICECOM_CLOCK_SOURCE_DEFAULT	SLICECOM_CLOCK_SOURCE_LINE
+
+#define SLICECOM_LOOPBACK_NONE		1
+#define SLICECOM_LOOPBACK_LOCAL		2
+#define SLICECOM_LOOPBACK_REMOTE	3
+#define SLICECOM_LOOPBACK_DEFAULT	SLICECOM_LOOPBACK_NONE
+
+#define MUNICH_VIRT(addr) (void *)(&bar1[addr])
+
+struct slicecom_stringtable
+{
+    char *name;
+    int value;
+};
+
+/* A convention: keep "default" the last not NULL when reading from /proc,
+   "error" is an indication that something went wrong, we have an undefined value */
+
+struct slicecom_stringtable slicecom_framings[] =
+{
+    {"crc4", SLICECOM_FRAMING_CRC4},
+    {"no-crc4", SLICECOM_FRAMING_NO_CRC4},
+    {"default", SLICECOM_FRAMING_DEFAULT},
+    {"error", 0}
+};
+
+struct slicecom_stringtable slicecom_linecodes[] =
+{
+    {"hdb3", SLICECOM_LINECODE_HDB3},
+    {"ami", SLICECOM_LINECODE_AMI},
+    {"default", SLICECOM_LINECODE_DEFAULT},
+    {"error", 0}
+};
+
+struct slicecom_stringtable slicecom_clock_sources[] =
+{
+    {"line", SLICECOM_CLOCK_SOURCE_LINE},
+    {"internal", SLICECOM_CLOCK_SOURCE_INTERNAL},
+    {"default", SLICECOM_CLOCK_SOURCE_DEFAULT},
+    {"error", 0}
+};
+
+struct slicecom_stringtable slicecom_loopbacks[] =
+{
+    {"none", SLICECOM_LOOPBACK_NONE},
+    {"local", SLICECOM_LOOPBACK_LOCAL},
+    {"remote", SLICECOM_LOOPBACK_REMOTE},
+    {"default", SLICECOM_LOOPBACK_DEFAULT},
+    {"error", 0}
+};
+
+/*
+ *	Some tunable values...
+ *
+ *	Note: when tuning values which change the length of text in
+ *	/proc/comx/comx[n]/status, keep in mind that it must be shorter then
+ *	PAGESIZE !
+ */
+
+#define MAX_BOARDS	4	/* ezzel 4 kartya lehet a gepben: 0..3          */
+#define RX_DESC_MAX	8	/* Rx ring size, must be >= 4                   */
+#define TX_DESC_MAX	4	/* Tx ring size, must be >= 2                   */
+				/* a sokkal hosszabb Tx ring mar ronthatja a nem-FIFO packet    */
+				/* schedulerek (fair queueing, stb.) hatekonysagat.             */
+#define MAX_WORK	10	/* TOD: update the info max. ennyi-1 esemenyt dolgoz fel egy interrupt hivasnal */
+
+/*
+ *	These are tunable too, but don't touch them without fully understanding what is happening
+ */
+
+#define UDELAY		20	/* We wait UDELAY usecs with disabled interrupts before and     */
+				/* after each command to avoid writing into each other's        */
+				/* ccb->action_spec. A _send_packet nem var, mert azt az        */
+				/* _interrupt()-bol is meghivhatja a LINE_tx()                  */
+
+/*
+ *	Just to avoid warnings about implicit declarations:
+ */
+
+static int MUNICH_close(struct net_device *dev);
+static struct comx_hardware slicecomhw;
+static struct comx_hardware pcicomhw;
+
+static unsigned long flags;
+static spinlock_t mister_lock = SPIN_LOCK_UNLOCKED;
+
+typedef volatile struct		/* Time Slot Assignment */
+{
+    u32 rxfillmask:8,		// ----------------------------+------+
+				//                             |      |
+      rxchannel:5,		// ----------------------+---+ |      |
+      rti:1,			// ---------------------+|   | |      |
+      res2:2,			// -------------------++||   | |      |
+				//                    ||||   | |      |
+      txfillmask:8,		// ----------+------+ ||||   | |      |
+				//           |      | ||||   | |      |
+      txchannel:5,		// ----+---+ |      | ||||   | |      |
+      tti:1,			// ---+|   | |      | ||||   | |      |
+      res1:2;			// -++||   | |      | ||||   | |      |
+				//   3          2          1
+    				//  10987654 32109876 54321098 76543210
+} timeslot_spec_t;
+
+typedef volatile struct		/* Receive Descriptor */
+{
+    u32 zero1:16, no:13, hi:1, hold:1, zero2:1;
+
+    u32 next;
+    u32 data;
+
+    u32 zero3:8, status:8, bno:13, zero4:1, c:1, fe:1;
+} rx_desc_t;
+
+typedef volatile struct		/* Transmit Descriptor */
+{
+    u32 fnum:11, csm:1, no13:1, zero1:2, v110:1, no:13, hi:1, hold:1, fe:1;
+
+    u32 next;
+    u32 data;
+
+} tx_desc_t;
+
+typedef volatile struct		/* Channel Specification */
+{
+    u32 iftf:1, mode:2, fa:1, trv:2, crc:1, inv:1, cs:1, tflag:7, ra:1, ro:1,
+	th:1, ta:1, to:1, ti:1, ri:1, nitbs:1, fit:1, fir:1, re:1, te:1, ch:1,
+	ifc:1, sfe:1, fe2:1;
+
+    u32 frda;
+    u32 ftda;
+
+    u32 itbs:6, zero1:26;
+
+} channel_spec_t;
+
+typedef volatile struct		/* Configuration Control Block */
+{
+    u32 action_spec;
+    u32 reserved1;
+    u32 reserved2;
+    timeslot_spec_t timeslot_spec[32];
+    channel_spec_t channel_spec[32];
+    u32 current_rx_desc[32];
+    u32 current_tx_desc[32];
+    u32 csa;			/* Control Start Address. CSA = *CCBA; CCB = *CSA */
+				/* MUNICH does it like: CCB = *( *CCBA )          */
+} munich_ccb_t;
+
+typedef volatile struct		/* Entry in the interrupt queue */
+{
+    u32 all;
+} munich_intq_t;
+
+#define MUNICH_INTQLEN	63	/* Rx/Tx Interrupt Queue Length
+				   (not the real len, but the TIQL/RIQL value)  */
+#define MUNICH_INTQMAX	( 16*(MUNICH_INTQLEN+1) )	/* Rx/Tx/Periph Interrupt Queue size in munich_intq_t's */
+#define MUNICH_INTQSIZE	( 4*MUNICH_INTQMAX )	/* Rx/Tx/Periph Interrupt Queue size in bytes           */
+
+#define MUNICH_PIQLEN	4	/* Peripheral Interrupt Queue Length. Unlike the RIQL/TIQL, */
+#define MUNICH_PIQMAX	( 4*MUNICH_PIQLEN )	/* PIQL register needs it like this                     */
+#define MUNICH_PIQSIZE	( 4*MUNICH_PIQMAX )
+
+typedef volatile u32 vol_u32;	/* TOD: ezek megszunnek ha atirom readw()/writew()-re - kész */
+typedef volatile u8 vol_u8;
+
+typedef volatile struct		/* counters of E1-errors and errored seconds, see rfc2495 */
+{
+    /* use here only unsigned ints, we depend on it when calculating the sum for the last N intervals */
+
+    unsigned line_code_violations,	/* AMI: bipolar violations, HDB3: hdb3 violations                       */
+      path_code_violations,	/* FAS errors and CRC4 errors                                                   */
+      e_bit_errors,		/* E-Bit Errors (the remote side received from us with CRC4-error) */
+      slip_secs,		/* number of seconds with (receive) Controlled Slip(s)          */
+      fr_loss_secs,		/* number of seconds an Out Of Frame defect was detected                */
+      line_err_secs,		/* number of seconds with one or more Line Code Violations              */
+      degraded_mins,		/* Degraded Minute - the estimated error rate is >1E-6, but <1E-3       */
+      errored_secs,		/* Errored Second - at least one of these happened:
+				   - Path Code Violation
+				   - Out Of Frame defect
+				   - Slip
+				   - receiving AIS
+				   - not incremented during an Unavailable Second                       */
+      bursty_err_secs,		/* Bursty Errored Second: (rfc2495 says it does not apply to E1)
+				   - Path Code Violations >1, but <320
+				   - not a Severely Errored Second
+				   - no AIS
+				   - not incremented during an Unavailabla Second                       */
+      severely_err_secs,	/* Severely Errored Second:
+				   - CRC4: >=832 Path COde Violations || >0 Out Of Frame defects
+				   - noCRC4: >=2048 Line Code Violations
+				   - not incremented during an Unavailable Second                       */
+      unavail_secs;		/* number of Unavailable Seconds. Unavailable state is said after:
+				   - 10 contiguous Severely Errored Seconds
+				   - or RAI || AIS || LOF || LOS 
+				   - (any) loopback has been set                                                */
+
+    /*
+     * we do not strictly comply to the rfc: we do not retroactively reduce errored_secs,
+     * bursty_err_secs, severely_err_secs when 'unavailable state' is reached
+     */
+
+} e1_stats_t;
+
+typedef volatile struct		/* ezek board-adatok, nem lehetnek a slicecom_privdata -ban     */
+{
+    int use_count;		/* num. of interfaces using the board                           */
+    int irq;			/* a kartya irq-ja. belemasoljuk a dev->irq -kba is, de csak hogy       */
+    /* szebb legyen az ifconfig outputja                            */
+    /* ha != 0, az azt jelenti hogy az az irq most nekunk sikeresen */
+    /* le van foglalva                                              */
+    struct pci_dev *pci;	/* a kartya PCI strukturaja. NULL, ha nincs kartya              */
+    u32 *bar1;			/* pci->base_address[0] ioremap()-ed by munich_probe(),         */
+    /* on x86 can be used both as a bus or virtual address.         */
+    /* These are the Munich's registers                             */
+    u8 *lbi;			/* pci->base_address[1] ioremap()-ed by munich_probe(),         */
+    /* this is a 256-byte range, the start of the LBI on the board  */
+    munich_ccb_t *ccb;		/* virtual address of CCB                                       */
+    munich_intq_t *tiq;		/* Tx Interrupt Queue                                           */
+    munich_intq_t *riq;		/* Rx Interrupt Queue                                           */
+    munich_intq_t *piq;		/* Peripheral Interrupt Queue (FALC interrupts arrive here)     */
+    int tiq_ptr,		/* A 'current' helyek a tiq/riq/piq -ban.                       */
+      riq_ptr,			/* amikor feldolgoztam az interruptokat, a legelso ures         */
+      piq_ptr;			/* interrupt_information szora mutatnak.                        */
+    struct net_device *twins[32];	/* MUNICH channel -> network interface assignment       */
+
+    unsigned long lastcheck;	/* When were the Rx rings last checked. Time in jiffies         */
+
+    struct timer_list modemline_timer;
+    char isx21;
+    char lineup;
+    char framing;		/* a beallitasok tarolasa                               */
+    char linecode;
+    char clock_source;
+    char loopback;
+
+    char devname[30];		/* what to show in /proc/interrupts                     */
+    unsigned histogram[MAX_WORK];	/* number of processed events in the interrupt loop     */
+    unsigned stat_pri_races;	/* number of special events, we try to handle them      */
+    unsigned stat_pti_races;
+    unsigned stat_pri_races_missed;	/* when it can not be handled, because of MAX_WORK      */
+    unsigned stat_pti_races_missed;
+
+#define SLICECOM_BOARD_INTERVALS_SIZE	97
+    e1_stats_t intervals[SLICECOM_BOARD_INTERVALS_SIZE];	/* E1 line statistics           */
+    unsigned current_interval;	/* pointer to the current interval                      */
+    unsigned elapsed_seconds;	/* elapsed seconds from the start of the current interval */
+    unsigned ses_seconds;	/* counter of contiguous Severely Errored Seconds       */
+    unsigned is_unavailable;	/* set to 1 after 10 contiguous Severely Errored Seconds */
+    unsigned no_ses_seconds;	/* contiguous Severely Error -free seconds in unavail state */
+
+    unsigned deg_elapsed_seconds;	/* for counting the 'Degraded Mins'                     */
+    unsigned deg_cumulated_errors;
+
+    struct module *owner;	/* pointer to our module to avoid module load races */
+} munich_board_t;
+
+struct slicecom_privdata
+{
+    int busy;			/* transmitter busy - number of packets in the Tx ring  */
+    int channel;		/* Munich logical channel ('channel-group' in Cisco)    */
+    unsigned boardnum;
+    u32 timeslots;		/* i-th bit means i-th timeslot is our                  */
+
+    int tx_ring_hist[TX_DESC_MAX];	/* histogram: number of packets in Tx ring when _send_packet is called  */
+
+    tx_desc_t tx_desc[TX_DESC_MAX];	/* the ring of Tx descriptors                           */
+    u8 tx_data[TX_DESC_MAX][TXBUFFER_SIZE];	/* buffers for data to transmit                 */
+    int tx_desc_ptr;		/* hanyadik descriptornal tartunk a beirassal   */
+    /* ahol ez all, oda irtunk utoljara                     */
+
+    rx_desc_t rx_desc[RX_DESC_MAX];	/* the ring of Rx descriptors                           */
+    u8 rx_data[RX_DESC_MAX][RXBUFFER_SIZE];	/* buffers for received data                            */
+    int rx_desc_ptr;		/* hanyadik descriptornal tartunk az olvasassal */
+
+    int rafutott;
+};
+
+static u32 reg, reg_ertek;	/* why static: don't write stack trash into regs if strtoul() fails */
+static u32 lbireg;
+static u8 lbireg_ertek;		/* why static: don't write stack trash into regs if strtoul() fails */
+
+static munich_board_t slicecom_boards[MAX_BOARDS];
+static munich_board_t pcicom_boards[MAX_BOARDS];
+
+/*
+ * Reprogram Idle Channel Registers in the FALC - send special code in not used channels
+ * Should be called from the open and close, when the timeslot assignment changes
+ */
+
+void rework_idle_channels(struct net_device *dev)
+{
+    struct comx_channel *ch = dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+    munich_board_t *board = slicecom_boards + hw->boardnum;
+    munich_ccb_t *ccb = board->ccb;
+
+    u8 *lbi = board->lbi;
+    int i, j, tmp;
+
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    for (i = 0; i < 4; i++)
+    {
+	tmp = 0xFF;
+	for (j = 0; j < 8; j++)
+	    if (ccb->timeslot_spec[8 * i + j].tti == 0) tmp ^= (0x80 >> j);
+	writeb(tmp, lbi + 0x30 + i);
+    }
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+}
+
+/*
+ * Set PCM framing - /proc/comx/comx0/framing
+ */
+
+void slicecom_set_framing(int boardnum, int value)
+{
+    u8 *lbi = slicecom_boards[boardnum].lbi;
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    slicecom_boards[boardnum].framing = value;
+    switch (value)
+    {
+	case SLICECOM_FRAMING_CRC4:
+	    writeb(readb(lbi + FMR1) | 8, lbi + FMR1);
+	    writeb((readb(lbi + FMR2) & 0x3f) | 0x80, lbi + FMR2);
+	    break;
+	case SLICECOM_FRAMING_NO_CRC4:
+	    writeb(readb(lbi + FMR1) & 0xf7, lbi + FMR1);
+	    writeb(readb(lbi + FMR2) & 0x3f, lbi + FMR2);
+	    break;
+	default:
+	    printk("slicecom: board %d: unhandled " FILENAME_FRAMING
+		   " value %d\n", boardnum, value);
+    }
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+}
+
+/*
+ * Set PCM linecode - /proc/comx/comx0/linecode
+ */
+
+void slicecom_set_linecode(int boardnum, int value)
+{
+    u8 *lbi = slicecom_boards[boardnum].lbi;
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    slicecom_boards[boardnum].linecode = value;
+    switch (value)
+    {
+	case SLICECOM_LINECODE_HDB3:
+	    writeb(readb(lbi + FMR0) | 0xf0, lbi + FMR0);
+	    break;
+	case SLICECOM_LINECODE_AMI:
+	    writeb((readb(lbi + FMR0) & 0x0f) | 0xa0, lbi + FMR0);
+	    break;
+	default:
+	    printk("slicecom: board %d: unhandled " FILENAME_LINECODE
+		   " value %d\n", boardnum, value);
+    }
+    spin_unlock_irqrestore(&mister_lock, flags);
+}
+
+/*
+ * Set PCM clock source - /proc/comx/comx0/clock_source
+ */
+
+void slicecom_set_clock_source(int boardnum, int value)
+{
+    u8 *lbi = slicecom_boards[boardnum].lbi;
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    slicecom_boards[boardnum].clock_source = value;
+    switch (value)
+    {
+	case SLICECOM_CLOCK_SOURCE_LINE:
+	    writeb(readb(lbi + LIM0) & ~1, lbi + LIM0);
+	    break;
+	case SLICECOM_CLOCK_SOURCE_INTERNAL:
+	    writeb(readb(lbi + LIM0) | 1, lbi + LIM0);
+	    break;
+	default:
+	    printk("slicecom: board %d: unhandled " FILENAME_CLOCK_SOURCE
+		   " value %d\n", boardnum, value);
+    }
+    spin_unlock_irqrestore(&mister_lock, flags);
+}
+
+/*
+ * Set loopbacks - /proc/comx/comx0/loopback
+ */
+
+void slicecom_set_loopback(int boardnum, int value)
+{
+    u8 *lbi = slicecom_boards[boardnum].lbi;
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    slicecom_boards[boardnum].loopback = value;
+    switch (value)
+    {
+	case SLICECOM_LOOPBACK_NONE:
+	    writeb(readb(lbi + LIM0) & ~2, lbi + LIM0);	/* Local Loop OFF  */
+	    writeb(readb(lbi + LIM1) & ~2, lbi + LIM1);	/* Remote Loop OFF */
+	    break;
+	case SLICECOM_LOOPBACK_LOCAL:
+	    writeb(readb(lbi + LIM1) & ~2, lbi + LIM1);	/* Remote Loop OFF */
+	    writeb(readb(lbi + LIM0) | 2, lbi + LIM0);	/* Local Loop ON   */
+	    break;
+	case SLICECOM_LOOPBACK_REMOTE:
+	    writeb(readb(lbi + LIM0) & ~2, lbi + LIM0);	/* Local Loop OFF  */
+	    writeb(readb(lbi + LIM1) | 2, lbi + LIM1);	/* Remote Loop ON  */
+	    break;
+	default:
+	    printk("slicecom: board %d: unhandled " FILENAME_LOOPBACK
+		   " value %d\n", boardnum, value);
+    }
+    spin_unlock_irqrestore(&mister_lock, flags);
+}
+
+/*
+ * Update E1 line status LEDs on the adapter
+ */
+
+void slicecom_update_leds(munich_board_t * board)
+{
+    u32 *bar1 = board->bar1;
+    u8 *lbi = board->lbi;
+    u8 frs0;
+    u32 leds;
+    int i;
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    leds = 0;
+    frs0 = readb(lbi + FRS0);	/* FRS0 bits described on page 137 */
+
+    if (!(frs0 & 0xa0))
+    {
+	leds |= 0x2000;		/* Green LED: Input signal seems to be OK, no LOS, no LFA       */
+	if (frs0 & 0x10)
+	    leds |= 0x8000;	/* Red LED: Receiving Remote Alarm                                      */
+    }
+    writel(leds, MUNICH_VIRT(GPDATA));
+
+    if (leds == 0x2000 && !board->lineup)
+    {				/* line up */
+	board->lineup = 1;
+	for (i = 0; i < 32; i++)
+	{
+	    if (board->twins[i] && (board->twins[i]->flags & IFF_RUNNING))
+	    {
+		struct comx_channel *ch = board->twins[i]->priv;
+
+		if (!test_and_set_bit(0, &ch->lineup_pending))
+		{
+		    ch->lineup_timer.function = comx_lineup_func;
+		    ch->lineup_timer.data = (unsigned long)board->twins[i];
+		    ch->lineup_timer.expires = jiffies + HZ * ch->lineup_delay;
+		    add_timer(&ch->lineup_timer);
+		}
+	    }
+	}
+    }
+    else if (leds != 0x2000 && board->lineup)
+    {				/* line down */
+	board->lineup = 0;
+	for (i = 0; i < 32; i++)
+	    if (board->twins[i] && (board->twins[i]->flags & IFF_RUNNING))
+	    {
+		struct comx_channel *ch = board->twins[i]->priv;
+
+		if (test_and_clear_bit(0, &ch->lineup_pending))
+		    del_timer(&ch->lineup_timer);
+		else if (ch->line_status & LINE_UP)
+		{
+		    ch->line_status &= ~LINE_UP;
+		    if (ch->LINE_status)
+			ch->LINE_status(board->twins[i], ch->line_status);
+		}
+	    }
+    }
+    spin_unlock_irqrestore(&mister_lock, flags);
+}
+
+/*
+ * This function gets called every second when the FALC issues the interrupt.
+ * Hardware counters contain error counts for last 1-second time interval.
+ * We add them to the global counters here.
+ * Read rfc2495 to understand this.
+ */
+
+void slicecom_update_line_counters(munich_board_t * board)
+{
+    e1_stats_t *curr_int = &board->intervals[board->current_interval];
+
+    u8 *lbi = board->lbi;
+
+    unsigned framing_errors, code_violations, path_code_violations, crc4_errors,
+	e_bit_errors;
+    unsigned slip_detected,	/* this one has logical value, not the number of slips! */
+      out_of_frame_defect,	/* logical value        */
+      ais_defect,		/* logical value        */
+      errored_sec, bursty_err_sec, severely_err_sec = 0, failure_sec;
+    u8 isr2, isr3, isr5, frs0;
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    isr2 = readb(lbi + ISR2);	/* ISR0-5 described on page 156     */
+    isr3 = readb(lbi + ISR3);
+    isr5 = readb(lbi + ISR5);
+    frs0 = readb(lbi + FRS0);	/* FRS0 described on page 137       */
+
+    /* Error Events: */
+
+    code_violations = readb(lbi + CVCL) + (readb(lbi + CVCH) << 8);
+    framing_errors = readb(lbi + FECL) + (readb(lbi + FECH) << 8);
+    crc4_errors = readb(lbi + CEC1L) + (readb(lbi + CEC1H) << 8);
+    e_bit_errors = readb(lbi + EBCL) + (readb(lbi + EBCH) << 8);
+    slip_detected = isr3 & (ISR3_RSN | ISR3_RSP);
+
+    path_code_violations = framing_errors + crc4_errors;
+
+    curr_int->line_code_violations += code_violations;
+    curr_int->path_code_violations += path_code_violations;
+    curr_int->e_bit_errors += e_bit_errors;
+
+    /* Performance Defects: */
+
+    /* there was an LFA in the last second, but maybe disappeared: */
+    out_of_frame_defect = (isr2 & ISR2_LFA) || (frs0 & FRS0_LFA);
+
+    /* there was an AIS in the last second, but maybe disappeared: */
+    ais_defect = (isr2 & ISR2_AIS) || (frs0 & FRS0_AIS);
+
+    /* Performance Parameters: */
+
+    if (out_of_frame_defect)
+	curr_int->fr_loss_secs++;
+    if (code_violations)
+	curr_int->line_err_secs++;
+
+    errored_sec = ((board->framing == SLICECOM_FRAMING_NO_CRC4) &&
+		   (code_violations)) || path_code_violations ||
+	out_of_frame_defect || slip_detected || ais_defect;
+
+    bursty_err_sec = !out_of_frame_defect && !ais_defect &&
+	(path_code_violations > 1) && (path_code_violations < 320);
+
+    switch (board->framing)
+    {
+	case SLICECOM_FRAMING_CRC4:
+	    severely_err_sec = out_of_frame_defect ||
+		(path_code_violations >= 832);
+	    break;
+	case SLICECOM_FRAMING_NO_CRC4:
+	    severely_err_sec = (code_violations >= 2048);
+	    break;
+    }
+
+    /*
+     * failure_sec: true if there was a condition leading to a failure
+     * (and leading to unavailable state) in this second:
+     */
+
+    failure_sec = (isr2 & ISR2_RA) || (frs0 & FRS0_RRA)	/* Remote/Far End/Distant Alarm Failure */
+	|| ais_defect || out_of_frame_defect	/* AIS or LOF Failure                           */
+	|| (isr2 & ISR2_LOS) || (frs0 & FRS0_LOS)	/* Loss Of Signal Failure                       */
+	|| (board->loopback != SLICECOM_LOOPBACK_NONE);	/* Loopback has been set                        */
+
+    if (board->is_unavailable)
+    {
+	if (severely_err_sec)
+	    board->no_ses_seconds = 0;
+	else
+	    board->no_ses_seconds++;
+
+	if ((board->no_ses_seconds >= 10) && !failure_sec)
+	{
+	    board->is_unavailable = 0;
+	    board->ses_seconds = 0;
+	    board->no_ses_seconds = 0;
+	}
+    }
+    else
+    {
+	if (severely_err_sec)
+	    board->ses_seconds++;
+	else
+	    board->ses_seconds = 0;
+
+	if ((board->ses_seconds >= 10) || failure_sec)
+	{
+	    board->is_unavailable = 1;
+	    board->ses_seconds = 0;
+	    board->no_ses_seconds = 0;
+	}
+    }
+
+    if (board->is_unavailable)
+	curr_int->unavail_secs++;
+    else
+    {
+	if (slip_detected)
+	    curr_int->slip_secs++;
+	curr_int->errored_secs += errored_sec;
+	curr_int->bursty_err_secs += bursty_err_sec;
+	curr_int->severely_err_secs += severely_err_sec;
+    }
+
+    /* the RFC does not say clearly which errors to count here, we try to count bit errors */
+
+    if (!board->is_unavailable && !severely_err_sec)
+    {
+	board->deg_cumulated_errors += code_violations;
+	board->deg_elapsed_seconds++;
+	if (board->deg_elapsed_seconds >= 60)
+	{
+	    if (board->deg_cumulated_errors >= 123)
+		curr_int->degraded_mins++;
+	    board->deg_cumulated_errors = 0;
+	    board->deg_elapsed_seconds = 0;
+	}
+
+    }
+
+    board->elapsed_seconds++;
+    if (board->elapsed_seconds >= 900)
+    {
+	board->current_interval =
+	    (board->current_interval + 1) % SLICECOM_BOARD_INTERVALS_SIZE;
+	memset((void *)&board->intervals[board->current_interval], 0,
+	       sizeof(e1_stats_t));
+	board->elapsed_seconds = 0;
+    }
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+}
+
+static void pcicom_modemline(unsigned long b)
+{
+    munich_board_t *board = (munich_board_t *) b;
+    struct net_device *dev = board->twins[0];
+    struct comx_channel *ch = dev->priv;
+    unsigned long regs;
+
+    regs = readl((void *)(&board->bar1[GPDATA]));
+    if ((ch->line_status & LINE_UP) && (regs & 0x0800))
+    {
+	ch->line_status &= ~LINE_UP;
+	board->lineup = 0;
+	if (ch->LINE_status)
+	{
+	    ch->LINE_status(dev, ch->line_status);
+	}
+    }
+
+    if (!(ch->line_status & LINE_UP) && !(regs & 0x0800))
+    {
+	ch->line_status |= LINE_UP;
+	board->lineup = 1;
+	if (ch->LINE_status)
+	{
+	    ch->LINE_status(dev, ch->line_status);
+	}
+    }
+
+    mod_timer((struct timer_list *)&board->modemline_timer, jiffies + HZ);
+}
+
+/* 
+ * Is it possible to transmit ?
+ * Called (may be called) by the protocol layer 
+ */
+
+static int MUNICH_txe(struct net_device *dev)
+{
+    struct comx_channel *ch = dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+
+    return (hw->busy < TX_DESC_MAX - 1);
+}
+
+/* 
+ * Hw probe function. Detects all the boards in the system,
+ * and fills up slicecom_boards[] and pcicom_boards[]
+ * Returns 0 on success.
+ * We do not disable interrupts!
+ */
+static int munich_probe(void)
+{
+    struct pci_dev *pci;
+    int boardnum;
+    int slicecom_boardnum;
+    int pcicom_boardnum;
+    u32 *bar1;
+    u8 *lbi;
+    munich_board_t *board;
+
+    for (boardnum = 0; boardnum < MAX_BOARDS; boardnum++)
+    {
+	pcicom_boards[boardnum].pci = 0;
+	pcicom_boards[boardnum].bar1 = 0;
+	pcicom_boards[boardnum].lbi = 0;
+	slicecom_boards[boardnum].pci = 0;
+	slicecom_boards[boardnum].bar1 = 0;
+	slicecom_boards[boardnum].lbi = 0;
+    }
+
+    pci = NULL;
+    board = NULL;
+    slicecom_boardnum = 0;
+    pcicom_boardnum = 0;
+
+    for (boardnum = 0;
+	boardnum < MAX_BOARDS && (pci = pci_find_device(PCI_VENDOR_ID_SIEMENS,
+	PCI_DEVICE_ID_SIEMENS_MUNICH32X, pci)); boardnum++)
+    {
+	if (pci_enable_device(pci))
+	    continue;
+
+	printk("munich_probe: munich chip found, IRQ %d\n", pci->irq);
+
+#if (LINUX_VERSION_CODE < 0x02030d)
+	bar1 = ioremap_nocache(pci->base_address[0], 0x100);
+	lbi = ioremap_nocache(pci->base_address[1], 0x100);
+#else
+	bar1 = ioremap_nocache(pci->resource[0].start, 0x100);
+	lbi = ioremap_nocache(pci->resource[1].start, 0x100);
+#endif
+
+	if (bar1 && lbi)
+	{
+	    pci_write_config_dword(pci, MUNICH_PCI_PCIRES, 0xe0000);
+	    set_current_state(TASK_UNINTERRUPTIBLE);
+	    schedule_timeout(1);
+	    pci_write_config_dword(pci, MUNICH_PCI_PCIRES, 0);
+	    set_current_state(TASK_UNINTERRUPTIBLE);
+	    schedule_timeout(1);
+	    /* check the type of the card */
+	    writel(LREG0_MAGIC, MUNICH_VIRT(LREG0));
+	    writel(LREG1_MAGIC, MUNICH_VIRT(LREG1));
+	    writel(LREG2_MAGIC, MUNICH_VIRT(LREG2));
+	    writel(LREG3_MAGIC, MUNICH_VIRT(LREG3));
+	    writel(LREG4_MAGIC, MUNICH_VIRT(LREG4));
+	    writel(LREG5_MAGIC, MUNICH_VIRT(LREG5));
+	    writel(LCONF_MAGIC2,MUNICH_VIRT(LCONF));	/* enable the DMSM */
+
+	    if ((readb(lbi + VSTR) == 0x13) || (readb(lbi + VSTR) == 0x10))
+	    {
+		board = slicecom_boards + slicecom_boardnum;
+		sprintf((char *)board->devname, "slicecom%d",
+			slicecom_boardnum);
+		board->isx21 = 0;
+		slicecom_boardnum++;
+	    }
+	    else if ((readb(lbi + VSTR) == 0x6) || (readb(lbi + GIS) == 0x6))
+	    {
+		board = pcicom_boards + pcicom_boardnum;
+		sprintf((char *)board->devname, "pcicom%d", pcicom_boardnum);
+		board->isx21 = 1;
+		pcicom_boardnum++;
+	    }
+	    if (board)
+	    {
+		printk("munich_probe: %s board found\n", board->devname);
+		writel(LCONF_MAGIC1, MUNICH_VIRT(LCONF));	/* reset the DMSM */
+		board->pci = pci;
+		board->bar1 = bar1;
+		board->lbi = lbi;
+		board->framing = SLICECOM_FRAMING_DEFAULT;
+		board->linecode = SLICECOM_LINECODE_DEFAULT;
+		board->clock_source = SLICECOM_CLOCK_SOURCE_DEFAULT;
+		board->loopback = SLICECOM_LOOPBACK_DEFAULT;
+		SET_MODULE_OWNER(board);
+	    }
+	    else
+	    {
+		printk("munich_probe: Board error, VSTR: %02X\n",
+		       readb(lbi + VSTR));
+		iounmap((void *)bar1);
+		iounmap((void *)lbi);
+	    }
+	}
+	else
+	{
+	    printk("munich_probe: ioremap() failed, not enabling this board!\n");
+	    /* .pci = NULL, so the MUNICH_open will not try to open it            */
+	    if (bar1) iounmap((void *)bar1);
+	    if (lbi) iounmap((void *)lbi);
+	}
+    }
+
+    if (!pci && !boardnum)
+    {
+	printk("munich_probe: no PCI present!\n");
+	return -ENODEV;
+    }
+
+    if (pcicom_boardnum + slicecom_boardnum == 0)
+    {
+	printk
+	    ("munich_probe: Couldn't find any munich board: vendor:device %x:%x not found\n",
+	     PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_SIEMENS_MUNICH32X);
+	return -ENODEV;
+    }
+
+    /* Found some */
+    if (pcicom_boardnum)
+	printk("%d pcicom board(s) found.\n", pcicom_boardnum);
+    if (slicecom_boardnum)
+	printk("%d slicecom board(s) found.\n", slicecom_boardnum);
+
+    return 0;
+}
+
+/* 
+ * Reset the hardware. Get called only from within this module if needed.
+ */
+#if 0
+static int slicecom_reset(struct net_device *dev)
+{
+    struct comx_channel *ch = dev->priv;
+
+    printk("slicecom_reset: resetting the hardware\n");
+
+    /* Begin to reset the hardware */
+
+    if (ch->HW_set_clock)
+	ch->HW_set_clock(dev);
+
+    /* And finish it */
+
+    return 0;
+}
+#endif
+
+/* 
+ * Transmit a packet. 
+ * Called by the protocol layer
+ * Return values:	
+ *	FRAME_ACCEPTED:	frame is being transmited, transmitter is busy
+ *	FRAME_QUEUED:	frame is being transmitted, there's more room in
+ *				the transmitter for additional packet(s)
+ *	FRAME_ERROR:
+ *	FRAME_DROPPED:	there was some error
+ */
+
+static int MUNICH_send_packet(struct net_device *dev, struct sk_buff *skb)
+{
+    struct comx_channel *ch = (struct comx_channel *)dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+
+    /* Send it to the debug facility too if needed: */
+
+    if (ch->debug_flags & DEBUG_HW_TX)
+	comx_debug_bytes(dev, skb->data, skb->len, "MUNICH_send_packet");
+
+    /* If the line is inactive, don't accept: */
+
+    /* TODO: atgondolni hogy mi is legyen itt */
+    /* if (!(ch->line_status & LINE_UP)) return FRAME_DROPPED; */
+
+    /* More check, to be sure: */
+
+    if (skb->len > TXBUFFER_SIZE)
+    {
+	ch->stats.tx_errors++;
+	kfree_skb(skb);
+	return FRAME_ERROR;
+    }
+
+    /* Maybe you have to disable irq's while programming the hw: */
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    /* And more check: */
+
+    if (hw->busy >= TX_DESC_MAX - 1)
+    {
+	printk(KERN_ERR
+	       "%s: Transmitter called while busy... dropping frame, busy = %d\n",
+	       dev->name, hw->busy);
+	spin_unlock_irqrestore(&mister_lock, flags);
+	kfree_skb(skb);
+	return FRAME_DROPPED;
+    }
+
+    if (hw->busy >= 0)
+	hw->tx_ring_hist[hw->busy]++;
+    /* DELL: */
+    else
+	printk("slicecom: %s: FATAL: busy = %d\n", dev->name, hw->busy);
+
+//              /* DEL: */
+//      printk("slicecom: %s: _send_packet called, busy = %d\n", dev->name, hw->busy );
+
+    /* Packet can go, update stats: */
+
+    ch->stats.tx_packets++;
+    ch->stats.tx_bytes += skb->len;
+
+    /* Pass the packet to the HW:                   */
+    /* Step forward with the transmit descriptors:  */
+
+    hw->tx_desc_ptr = (hw->tx_desc_ptr + 1) % TX_DESC_MAX;
+
+    memcpy(&(hw->tx_data[hw->tx_desc_ptr][0]), skb->data, skb->len);
+    hw->tx_desc[hw->tx_desc_ptr].no = skb->len;
+
+    /* We don't issue any command, just step with the HOLD bit      */
+
+    hw->tx_desc[hw->tx_desc_ptr].hold = 1;
+    hw->tx_desc[(hw->tx_desc_ptr + TX_DESC_MAX - 1) % TX_DESC_MAX].hold = 0;
+
+#ifdef COMX_NEW
+    dev_kfree_skb(skb);
+#endif
+    /* csomag kerult a Tx ringbe: */
+
+    hw->busy++;
+
+    /* Report it: */
+
+    if (ch->debug_flags & DEBUG_HW_TX)
+	comx_debug(dev, "%s: MUNICH_send_packet was successful\n\n", dev->name);
+
+    if (hw->busy >= TX_DESC_MAX - 1)
+    {
+	spin_unlock_irqrestore(&mister_lock, flags);
+	return FRAME_ACCEPTED;
+    }
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+
+    /* All done */
+
+    return FRAME_QUEUED;
+}
+
+/*
+ * Interrupt handler routine.
+ * Called by the Linux kernel.
+ * BEWARE! The interrupts are enabled on the call!
+ */
+static void MUNICH_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    struct sk_buff *skb;
+    int length;
+    int rx_status;
+    int work;			/* hany esemenyt kezeltem mar le                                */
+    u32 *bar1;
+    u8 *lbi;
+    u32 stat,			/* az esemenyek, amiket a ebben a loop korben le kell meg kezelni       */
+      race_stat = 0,		/* race eseten ebben uzenek magamnak hogy mit kell meg lekezelni        */
+      ack;			/* ezt fogom a vegen a STAT-ba irni, kiveszek belole 1-1 bitet ha       */
+
+    /* az adott dolgot nem kell ack-olni mert volt vele munkam, es  */
+    /* legjobb ha visszaterek ide megegyszer                        */
+    munich_intq_t int_info;
+
+    struct net_device *dev;
+    struct comx_channel *ch;
+    struct slicecom_privdata *hw;
+    munich_board_t *board = (munich_board_t *) dev_id;
+    int channel;
+
+    //      , boardnum = (int)dev_id;
+
+    // board = munich_boards + boardnum;
+    bar1 = board->bar1;
+    lbi = board->lbi;
+
+    //      Do not uncomment this under heavy load! :->
+    //      printk("MUNICH_interrupt: masked STAT=0x%08x, tiq=0x%08x, riq=0x%08x, piq=0x%08x\n", stat, board->tiq[0].all, board->riq[0].all, board->piq[0].all );
+
+    for (work = 0; (stat = (race_stat | (readl(MUNICH_VIRT(STAT)) & ~STAT_NOT_HANDLED_BY_INTERRUPT))) && (work < MAX_WORK - 1); work++)
+    {
+	ack = stat & (STAT_PRI | STAT_PTI | STAT_LBII);
+
+	/* Handle the interrupt information in the Rx queue. We don't really trust      */
+	/* info from this queue, because it can be overflowed, so later check           */
+	/* every Rx ring for received packets. But there are some errors which can't    */
+	/* be counted from the Rx rings, so we parse it.                                        */
+
+	int_info = board->riq[board->riq_ptr];
+	if (int_info.all & 0xF0000000)	/* ha ez nem 0, akkor itt interrupt_info van                    */
+	{
+	    ack &= ~STAT_PRI;	/* don't ack the interrupt, we had some work to do              */
+
+	    channel = PCM_INT_CHANNEL(int_info.all);
+	    dev = board->twins[channel];
+
+	    if (dev == NULL)
+	    {
+		printk
+		    ("MUNICH_interrupt: got an Rx interrupt info for NULL device "
+		     "%s.twins[%d], int_info = 0x%08x\n", board->devname,
+		     channel, int_info.all);
+		goto go_for_next_interrupt;
+	    }
+
+	    ch = (struct comx_channel *)dev->priv;
+	    hw = (struct slicecom_privdata *)ch->HW_privdata;
+
+	    //      printk("Rx STAT=0x%08x int_info=0x%08x rx_desc_ptr=%d rx_desc.status=0x%01x\n",
+	    //              stat, int_info.all, hw->rx_desc_ptr, hw->rx_desc[ hw->rx_desc_ptr ].status );
+
+	    if (int_info.all & PCM_INT_HI)
+		printk("SliceCOM: %s: Host Initiated interrupt\n", dev->name);
+	    if (int_info.all & PCM_INT_IFC)
+		printk("SliceCOM: %s: Idle/Flag Change\n", dev->name);
+	    /* TOD: jo ez az Idle/Flag Change valamire? - azonnal latszik belole hogy mikor ad a masik oldal */
+	    /* TOD: ilyen IT most nem is jon, mert ki van maszkolva az interrupt, biztosan kell ez? */
+
+	    if (int_info.all & PCM_INT_FO)
+		/* Internal buffer (RB) overrun */
+		ch->stats.rx_over_errors++;	/* TOD: Ez azt jelenti hogy a belso RB nem volt hozzaferheto, es ezert kihagyott valamit. De nem csak csomag lehetett, hanem esemeny, stb. is. lasd page 247. Ezzel a 'cat status'-hoz igazodok, de a netdevice.h szerint nem egyertelmu hogy ide ez kellene. Nem lehet hogy rx_missed ? */
+		/* DE: nem gotozok sehova, elvileg jo igy */
+		/* kesobb meg visszaterek az FO-ra, ha packet-FO volt. Keresd a "packet-FO"-t. */
+	    if (int_info.all & PCM_INT_FI)	/* frame received, but we do not trust the int_info queue       */
+		if (int_info.all & PCM_INT_SF)
+		{		/* Short Frame: rovidebb mint a CRC */
+		    /* "rovidebb mint CRC+2byte" vizsgalat a "CRC+2"-nel */
+		    ch->stats.rx_length_errors++;	/* TOD: noveljem? ne noveljem? */
+		    goto go_for_next_interrupt;
+		}
+
+	    go_for_next_interrupt:	/* One step in the interrupt queue */
+	    board->riq[board->riq_ptr].all = 0;	/* megjelolom hogy itt meg nem jart a hw */
+	    board->riq_ptr = (board->riq_ptr + 1) % MUNICH_INTQMAX;
+
+	}
+
+	/* Check every Rx ring for incomed packets: */
+
+	for (channel = 0; channel < 32; channel++)
+	{
+	    dev = board->twins[channel];
+
+	    if (dev != NULL)
+	    {
+		ch = (struct comx_channel *)dev->priv;
+		hw = (struct slicecom_privdata *)ch->HW_privdata;
+
+		rx_status = hw->rx_desc[hw->rx_desc_ptr].status;
+
+		if (!(rx_status & 0x80))	/* mar jart itt a hardver */
+		{
+		    ack &= ~STAT_PRI;	/* Don't ack, we had some work          */
+
+		    /* Ez most egy kicsit zuros, mert itt mar nem latom az int_infot        */
+		    if (rx_status & RX_STATUS_ROF)
+			ch->stats.rx_over_errors++;	/* TOD: 'cat status'-hoz igazodok */
+
+		    if (rx_status & RX_STATUS_RA)
+			/* Abort received or issued on channel  */
+			ch->stats.rx_frame_errors++;	/* or HOLD bit in the descriptor                */
+			/* TOD: 'cat status'-hoz igazodok */
+
+		    if (rx_status & RX_STATUS_LFD)
+		    {		/* Long Frame (longer then MFL in the MODE1) */
+			ch->stats.rx_length_errors++;
+			goto go_for_next_frame;
+		    }
+
+		    if (rx_status & RX_STATUS_NOB)
+		    {		/* Not n*8 bits long frame - frame alignment */
+			ch->stats.rx_frame_errors++;	/* ez viszont nem igazodik a 'cat status'-hoz */
+			goto go_for_next_frame;
+		    }
+
+		    if (rx_status & RX_STATUS_CRCO)
+		    {		/* CRC error */
+			ch->stats.rx_crc_errors++;
+			goto go_for_next_frame;
+		    }
+
+		    if (rx_status & RX_STATUS_SF)
+		    {		/* Short Frame: rovidebb mint CRC+2byte */
+			ch->stats.rx_errors++;	/* The HW does not set PCI_INT_ERR bit for this one, see page 246 */
+			ch->stats.rx_length_errors++;
+			goto go_for_next_frame;
+		    }
+
+		    if (rx_status != 0)
+		    {
+			printk("SliceCOM: %s: unhandled rx_status: 0x%02x\n",
+			       dev->name, rx_status);
+			goto go_for_next_frame;
+		    }
+
+		    /* frame received without errors: */
+
+		    length = hw->rx_desc[hw->rx_desc_ptr].bno;
+		    ch->stats.rx_packets++;	/* Count only 'good' packets */
+		    ch->stats.rx_bytes += length;
+
+		    /* Allocate a larger skb and reserve the heading for efficiency: */
+
+		    if ((skb = dev_alloc_skb(length + 16)) == NULL)
+		    {
+			ch->stats.rx_dropped++;
+			goto go_for_next_frame;
+		    }
+
+		    /* Do bookkeeping: */
+
+		    skb_reserve(skb, 16);
+		    skb_put(skb, length);
+		    skb->dev = dev;
+
+		    /* Now copy the data into the buffer: */
+
+		    memcpy(skb->data, &(hw->rx_data[hw->rx_desc_ptr][0]), length);
+
+		    /* DEL: UGLY HACK!!!! */
+		    if (*((int *)skb->data) == 0x02000000 &&
+			*(((int *)skb->data) + 1) == 0x3580008f)
+		    {
+			printk("%s: swapping hack\n", dev->name);
+			*((int *)skb->data) = 0x3580008f;
+			*(((int *)skb->data) + 1) = 0x02000000;
+		    }
+
+		    if (ch->debug_flags & DEBUG_HW_RX)
+			comx_debug_skb(dev, skb, "MUNICH_interrupt receiving");
+
+		    /* Pass it to the protocol entity: */
+
+		    ch->LINE_rx(dev, skb);
+
+		    go_for_next_frame:
+		    /* DEL: rafutott-e a HOLD bitre -detektalas */
+		    {
+			if( ((rx_desc_t*)phys_to_virt(board->ccb->current_rx_desc[channel]))->hold
+			    && ((rx_desc_t*)phys_to_virt(board->ccb->current_rx_desc[channel]))->status != 0xff)
+			    hw->rafutott++;	/* rafutott: hanyszor volt olyan hogy a current descriptoron HOLD bit volt, es a hw mar befejezte az irast (azaz a hw rafutott a HOLD bitre) */
+		    }
+
+		    //      if( jiffies % 2 )               /* DELL: okozzunk egy kis Rx ring slipet :) */
+		    //      {
+		    /* Step forward with the receive descriptors: */
+		    /* if you change this, change the copy of it below too! Search for: "RxSlip" */
+		    hw->rx_desc[(hw->rx_desc_ptr + RX_DESC_MAX - 1) % RX_DESC_MAX].hold = 1;
+		    hw->rx_desc[hw->rx_desc_ptr].status = 0xFF;	/* megjelolom hogy itt meg nem jart a hw */
+		    hw->rx_desc[(hw->rx_desc_ptr + RX_DESC_MAX - 2) % RX_DESC_MAX].hold = 0;
+		    hw->rx_desc_ptr = (hw->rx_desc_ptr + 1) % RX_DESC_MAX;
+		    //      }
+		}
+	    }
+	}
+
+	stat &= ~STAT_PRI;
+
+//      }
+
+//      if( stat & STAT_PTI )   /* TOD: primko megvalositas: mindig csak egy esemenyt dolgozok fel, */
+	/* es nem torlom a STAT-ot, ezert ujra visszajon ide a rendszer. Amikor */
+	/* jon interrupt, de nincs mit feldolgozni, akkor torlom a STAT-ot.     */
+	/* 'needs a rewrite', de elso megoldasnak jo lesz                       */
+//              {
+
+udelay(10000);
+	int_info = board->tiq[board->tiq_ptr];
+	if (int_info.all & 0xF0000000)	/* ha ez nem 0, akkor itt interrupt_info van    */
+	{
+	    ack &= ~STAT_PTI;	/* don't ack the interrupt, we had some work to do      */
+
+	    channel = PCM_INT_CHANNEL(int_info.all);
+	    dev = board->twins[channel];
+
+	    if (dev == NULL)
+	    {
+		printk("MUNICH_interrupt: got a Tx interrupt for NULL device "
+		       "%s.twins[%d], int_info = 0x%08x\n",
+		       board->isx21 ? "pcicom" : "slicecom", channel, int_info.all);
+		goto go_for_next_tx_interrupt;
+	    }
+
+	    ch = (struct comx_channel *)dev->priv;
+	    hw = (struct slicecom_privdata *)ch->HW_privdata;
+
+	    //      printk("Tx STAT=0x%08x int_info=0x%08x tiq_ptr=%d\n", stat, int_info.all, board->tiq_ptr );
+
+	    if (int_info.all & PCM_INT_FE2)
+	    {			/* "Tx available"                               */
+		/* do nothing */
+	    }
+	    else if (int_info.all & PCM_INT_FO)
+	    {			/* Internal buffer (RB) overrun */
+		ch->stats.rx_over_errors++;
+	    }
+	    else
+	    {
+		printk("slicecom: %s: unhandled Tx int_info: 0x%08x\n",
+		       dev->name, int_info.all);
+	    }
+
+	    go_for_next_tx_interrupt:
+	    board->tiq[board->tiq_ptr].all = 0;
+	    board->tiq_ptr = (board->tiq_ptr + 1) % MUNICH_INTQMAX;
+	}
+
+	/* Check every Tx ring for incoming packets: */
+
+	for (channel = 0; channel < 32; channel++)
+	{
+	    dev = board->twins[channel];
+
+	    if (dev != NULL)
+	    {
+		int newbusy;
+
+		ch = (struct comx_channel *)dev->priv;
+		hw = (struct slicecom_privdata *)ch->HW_privdata;
+
+		/* We dont trust the "Tx available" info from the TIQ, but check        */
+		/* every ring if there is some free room                                        */
+
+		if (ch->init_status && netif_running(dev))
+		{
+		    newbusy = ( TX_DESC_MAX + (& hw->tx_desc[ hw->tx_desc_ptr ]) -
+			(tx_desc_t*)phys_to_virt(board->ccb->current_tx_desc[ hw->channel ]) ) % TX_DESC_MAX;
+
+		    if(newbusy < 0)
+		    {
+			printk("slicecom: %s: FATAL: fresly computed busy = %d, HW: 0x%p, SW: 0x%p\n",
+			dev->name, newbusy,
+			phys_to_virt(board->ccb->current_tx_desc[hw->channel]),
+			& hw->tx_desc[hw->tx_desc_ptr]);
+		    }
+
+		    /* Fogyott valami a Tx ringbol? */
+
+		    if (newbusy < hw->busy)
+		    {
+			// ack &= ~STAT_PTI;                            /* Don't ack, we had some work  */
+			hw->busy = newbusy;
+			if (ch->LINE_tx)
+			    ch->LINE_tx(dev);	/* Report it to protocol driver */
+		    }
+		    else if (newbusy > hw->busy)
+			printk("slicecom: %s: newbusy > hw->busy, this should not happen!\n", dev->name);
+		}
+	    }
+	}
+	stat &= ~STAT_PTI;
+
+	int_info = board->piq[board->piq_ptr];
+	if (int_info.all & 0xF0000000)	/* ha ez nem 0, akkor itt interrupt_info van            */
+	{
+	    ack &= ~STAT_LBII;	/* don't ack the interrupt, we had some work to do      */
+
+	    /* We do not really use (yet) the interrupt info from this queue, */
+
+	    // printk("slicecom: %s: LBI Interrupt event: %08x\n", board->devname, int_info.all);
+
+	    if (!board->isx21)
+	    {
+		slicecom_update_leds(board);
+		slicecom_update_line_counters(board);
+	    }
+
+	    goto go_for_next_lbi_interrupt;	/* To avoid warning about unused label  */
+
+	    go_for_next_lbi_interrupt:	/* One step in the interrupt queue */
+	    board->piq[board->piq_ptr].all = 0;	/* megjelolom hogy itt meg nem jart a hw        */
+	    board->piq_ptr = (board->piq_ptr + 1) % MUNICH_PIQMAX;
+	}
+	stat &= ~STAT_LBII;
+
+	writel(ack, MUNICH_VIRT(STAT));
+
+	if (stat & STAT_TSPA)
+	{
+	    //      printk("slicecom: %s: PCM TSP Asynchronous\n", board->devname);
+	    writel(STAT_TSPA, MUNICH_VIRT(STAT));
+	    stat &= ~STAT_TSPA;
+	}
+
+	if (stat & STAT_RSPA)
+	{
+	    //      printk("slicecom: %s: PCM RSP Asynchronous\n", board->devname);
+	    writel(STAT_RSPA, MUNICH_VIRT(STAT));
+	    stat &= ~STAT_RSPA;
+	}
+	if (stat)
+	{
+	    printk("MUNICH_interrupt: unhandled interrupt, STAT=0x%08x\n",
+		   stat);
+	    writel(stat, MUNICH_VIRT(STAT));	/* ha valamit megsem kezeltunk le, azert ack-ot kuldunk neki */
+	}
+
+    }
+    board->histogram[work]++;
+
+    /* We can miss these if we reach the MAX_WORK   */
+    /* Count it to see how often it happens         */
+
+    if (race_stat & STAT_PRI)
+	board->stat_pri_races_missed++;
+    if (race_stat & STAT_PTI)
+	board->stat_pti_races_missed++;
+    return;
+}
+
+/* 
+ * Hardware open routine.
+ * Called by comx (upper) layer when the user wants to bring up the interface
+ * with ifconfig.
+ * Initializes hardware, allocates resources etc.
+ * Returns 0 on OK, or standard error value on error.
+ */
+
+static int MUNICH_open(struct net_device *dev)
+{
+    struct comx_channel *ch = dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+    struct proc_dir_entry *procfile = ch->procdir->subdir;
+    munich_board_t *board;
+    munich_ccb_t *ccb;
+
+    u32 *bar1;
+    u8 *lbi;
+    u32 stat;
+    unsigned long flags, jiffs;
+
+    int i, channel;
+    u32 timeslots = hw->timeslots;
+
+    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
+
+    bar1 = board->bar1;
+    lbi = board->lbi;
+
+    /* TODO: a timeslotok ellenorzese kell majd ide .. hat, biztos? mar a write_proc-ban is
+       ellenorzom valamennyire.
+       if (!dev->io || !dev->irq) return -ENODEV;
+     */
+
+    if (!board->pci)
+    {
+	printk("MUNICH_open: no %s board with boardnum = %d\n",
+	       ch->hardware->name, hw->boardnum);
+	return -ENODEV;
+    }
+
+    spin_lock_irqsave(&mister_lock, flags);
+    /* lock the section to avoid race with multiple opens and make sure
+       that no interrupts get called while this lock is active */
+
+    if (board->use_count == 0)	/* bring up the board if it was unused                  */
+	/* if fails, frees allocated resources and returns.     */
+	/* TOD: is it safe? nem kellene resetelni a kartyat?    */
+    {
+	printk("MUNICH_open: %s: bringing up board\n", board->devname);
+
+	/* Clean up the board's static struct if messed: */
+
+	for (i = 0; i < 32; i++)
+	    board->twins[i] = NULL;
+	for (i = 0; i < MAX_WORK; i++)
+	    board->histogram[i] = 0;
+
+	board->lineup = 0;
+
+	/* Allocate CCB: */
+        board->ccb = kmalloc(sizeof(munich_ccb_t), GFP_KERNEL);
+	if (board->ccb == NULL)
+	{
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -ENOMEM;
+	}
+	memset((void *)board->ccb, 0, sizeof(munich_ccb_t));
+	board->ccb->csa = virt_to_phys(board->ccb);
+	ccb = board->ccb;
+	for (i = 0; i < 32; i++)
+	{
+	    ccb->timeslot_spec[i].tti = 1;
+	    ccb->timeslot_spec[i].rti = 1;
+	}
+
+	/* Interrupt queues: */
+
+	board->tiq = kmalloc(MUNICH_INTQSIZE, GFP_KERNEL);
+	if (board->tiq == NULL)
+	{
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -ENOMEM;
+	}
+	memset((void *)board->tiq, 0, MUNICH_INTQSIZE);
+
+	board->riq = kmalloc(MUNICH_INTQSIZE, GFP_KERNEL);
+	if (board->riq == NULL)
+	{
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -ENOMEM;
+	}
+	memset((void *)board->riq, 0, MUNICH_INTQSIZE);
+
+	board->piq = kmalloc(MUNICH_PIQSIZE, GFP_KERNEL);
+	if (board->piq == NULL)
+	{
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -ENOMEM;
+	}
+	memset((void *)board->piq, 0, MUNICH_PIQSIZE);
+
+	board->tiq_ptr = 0;
+	board->riq_ptr = 0;
+	board->piq_ptr = 0;
+
+	/* Request irq: */
+
+	board->irq = 0;
+
+	/* (char*) cast to avoid warning about discarding volatile:             */
+	if (request_irq(board->pci->irq, MUNICH_interrupt, 0,
+	    (char *)board->devname, (void *)board))
+	{
+	    printk("MUNICH_open: %s: unable to obtain irq %d\n", board->devname,
+		   board->pci->irq);
+	    /* TOD: free other resources (a sok malloc feljebb)                     */
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -EAGAIN;
+	}
+	board->irq = board->pci->irq;	/* csak akkor legyen != 0, ha tenyleg le van foglalva nekunk */
+
+	/* Programming device: */
+
+	/* Reset the board like a power-on: */
+	/* TOD:
+	   - It is not a real power-on: if a DMA transaction fails with master abort, the board
+	   stays in half-dead state.
+	   - It doesn't reset the FALC line driver */
+
+	pci_write_config_dword(board->pci, MUNICH_PCI_PCIRES, 0xe0000);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(1);
+	pci_write_config_dword(board->pci, MUNICH_PCI_PCIRES, 0);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(1);
+
+        writel(virt_to_phys(&ccb->csa), MUNICH_VIRT(CCBA));
+        writel(virt_to_phys( board->tiq ), MUNICH_VIRT(TIQBA));
+        writel(MUNICH_INTQLEN, MUNICH_VIRT(TIQL));
+        writel(virt_to_phys( board->riq ), MUNICH_VIRT(RIQBA));
+        writel(MUNICH_INTQLEN, MUNICH_VIRT(RIQL));
+        writel(virt_to_phys( board->piq ), MUNICH_VIRT(PIQBA));
+        writel(MUNICH_PIQLEN, MUNICH_VIRT(PIQL));
+        
+	/* Put the magic values into the registers: */
+
+	writel(MODE1_MAGIC, MUNICH_VIRT(MODE1));
+	writel(MODE2_MAGIC, MUNICH_VIRT(MODE2));
+
+	writel(LREG0_MAGIC, MUNICH_VIRT(LREG0));
+	writel(LREG1_MAGIC, MUNICH_VIRT(LREG1));
+	writel(LREG2_MAGIC, MUNICH_VIRT(LREG2));
+	writel(LREG3_MAGIC, MUNICH_VIRT(LREG3));
+	writel(LREG4_MAGIC, MUNICH_VIRT(LREG4));
+	writel(LREG5_MAGIC, MUNICH_VIRT(LREG5));
+
+	writel(LCONF_MAGIC1, MUNICH_VIRT(LCONF));	/* reset the DMSM */
+	writel(LCONF_MAGIC2, MUNICH_VIRT(LCONF));	/* enable the DMSM */
+
+	writel(~0, MUNICH_VIRT(TXPOLL));
+	writel(board->isx21 ? 0x1400 : 0xa000, MUNICH_VIRT(GPDIR));
+
+	if (readl(MUNICH_VIRT(STAT))) writel(readl(MUNICH_VIRT(STAT)), MUNICH_VIRT(STAT));
+
+	ccb->action_spec = CCB_ACTIONSPEC_RES | CCB_ACTIONSPEC_IA;
+	writel(CMD_ARPCM, MUNICH_VIRT(CMD));	/* Start the PCM core reset */
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(1);
+
+	stat = 0;		/* Wait for the action to complete max. 1 second */
+	jiffs = jiffies;
+	while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))
+	{
+	    set_current_state(TASK_UNINTERRUPTIBLE);
+	    schedule_timeout(1);
+	}
+
+	if (stat & STAT_PCMF)
+	{
+	    printk(KERN_ERR
+		   "MUNICH_open: %s: Initial ARPCM failed. STAT=0x%08x\n",
+		   board->devname, stat);
+	    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));
+	    free_irq(board->irq, (void *)board);	/* TOD: free other resources too *//* maybe shut down hw? */
+	    board->irq = 0;
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -EAGAIN;
+	}
+	else if (!(stat & STAT_PCMA))
+	{
+	    printk(KERN_ERR
+		   "MUNICH_open: %s: Initial ARPCM timeout. STAT=0x%08x\n",
+		   board->devname, stat);
+	    free_irq(board->irq, (void *)board);	/* TOD: free other resources too *//* maybe shut off the hw? */
+	    board->irq = 0;
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -EIO;
+	}
+
+	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));	/* Acknowledge */
+
+	if (board->isx21) writel(0, MUNICH_VIRT(GPDATA));
+
+	printk("MUNICH_open: %s: succesful HW-open took %ld jiffies\n",
+	       board->devname, jiffies - jiffs);
+
+	/* Set up the FALC hanging on the Local Bus: */
+
+	if (!board->isx21)
+	{
+	    writeb(0x0e, lbi + FMR1);
+	    writeb(0, lbi + LIM0);
+	    writeb(0xb0, lbi + LIM1);	/* TODO: input threshold */
+	    writeb(0xf7, lbi + XPM0);
+	    writeb(0x02, lbi + XPM1);
+	    writeb(0x00, lbi + XPM2);
+	    writeb(0xf0, lbi + FMR0);
+	    writeb(0x80, lbi + PCD);
+	    writeb(0x80, lbi + PCR);
+	    writeb(0x00, lbi + LIM2);
+	    writeb(0x07, lbi + XC0);
+	    writeb(0x3d, lbi + XC1);
+	    writeb(0x05, lbi + RC0);
+	    writeb(0x00, lbi + RC1);
+	    writeb(0x83, lbi + FMR2);
+	    writeb(0x9f, lbi + XSW);
+	    writeb(0x0f, lbi + XSP);
+	    writeb(0x00, lbi + TSWM);
+	    writeb(0xe0, lbi + MODE);
+	    writeb(0xff, lbi + IDLE);	/* Idle Code to send in unused timeslots        */
+	    writeb(0x83, lbi + IPC);	/* interrupt query line mode: Push/pull output, active high     */
+	    writeb(0xbf, lbi + IMR3);	/* send an interrupt every second               */
+
+	    slicecom_set_framing(hw->boardnum, board->framing);
+	    slicecom_set_linecode(hw->boardnum, board->linecode);
+	    slicecom_set_clock_source(hw->boardnum, board->clock_source);
+	    slicecom_set_loopback(hw->boardnum, board->loopback);
+
+	    memset((void *)board->intervals, 0, sizeof(board->intervals));
+	    board->current_interval = 0;
+	    board->elapsed_seconds = 0;
+	    board->ses_seconds = 0;
+	    board->is_unavailable = 0;
+	    board->no_ses_seconds = 0;
+	    board->deg_elapsed_seconds = 0;
+	    board->deg_cumulated_errors = 0;
+	}
+
+	/* Enable the interrupts last                                                   */
+	/* These interrupts will be enabled. We do not need the others. */
+
+	writel(readl(MUNICH_VIRT(IMASK)) & ~(STAT_PTI | STAT_PRI | STAT_LBII | STAT_TSPA | STAT_RSPA), MUNICH_VIRT(IMASK));
+    }
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+
+    dev->irq = board->irq;	/* hogy szep legyen az ifconfig outputja */
+    ccb = board->ccb;		/* TODO: ez igy csunya egy kicsit hogy benn is meg kinn is beletoltom :( */
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout(1);
+
+    /* Check if the selected timeslots aren't used already */
+
+    for (i = 0; i < 32; i++)
+	if (((1 << i) & timeslots) && !ccb->timeslot_spec[i].tti)
+	{
+	    printk("MUNICH_open: %s: timeslot %d already used by %s\n",
+		   dev->name, i, board->twins[ccb->timeslot_spec[i].txchannel]->name);
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -EBUSY;	/* TODO: lehet hogy valami mas errno kellene? */
+	}
+
+    /* find a free channel: */
+    /* TODO: ugly, rewrite it  */
+
+    for (channel = 0; channel <= 32; channel++)
+    {
+	if (channel == 32)
+	{			/* not found a free one */
+	    printk
+		("MUNICH_open: %s: FATAL: can not find a free channel - this should not happen!\n",
+		 dev->name);
+	    spin_unlock_irqrestore(&mister_lock, flags);
+	    return -ENODEV;
+	}
+	if (board->twins[channel] == NULL)
+	    break;		/* found the first free one */
+    }
+
+    board->lastcheck = jiffies;	/* avoid checking uninitialized hardware channel */
+
+    /* Open the channel. If fails, calls MUNICH_close() to properly free resources and stop the HW */
+
+    hw->channel = channel;
+    board->twins[channel] = dev;
+
+    board->use_count++;		/* meg nem nyitottuk meg a csatornat, de a twins-ben
+				   mar elfoglaltunk egyet, es ha a _close-t akarjuk hivni, akkor ez kell. */
+    for (i = 0; i < 32; i++)
+	if ((1 << i) & timeslots)
+	{
+	    ccb->timeslot_spec[i].tti = 0;
+	    ccb->timeslot_spec[i].txchannel = channel;
+	    ccb->timeslot_spec[i].txfillmask = ~0;
+
+	    ccb->timeslot_spec[i].rti = 0;
+	    ccb->timeslot_spec[i].rxchannel = channel;
+	    ccb->timeslot_spec[i].rxfillmask = ~0;
+	}
+
+    if (!board->isx21) rework_idle_channels(dev);
+
+    memset((void *)&(hw->tx_desc), 0, TX_DESC_MAX * sizeof(tx_desc_t));
+    memset((void *)&(hw->rx_desc), 0, RX_DESC_MAX * sizeof(rx_desc_t));
+
+    for (i = 0; i < TX_DESC_MAX; i++)
+    {
+	hw->tx_desc[i].fe = 1;
+	hw->tx_desc[i].fnum = 2;
+                hw->tx_desc[i].data     = virt_to_phys( & (hw->tx_data[i][0]) );
+                hw->tx_desc[i].next     = virt_to_phys( & (hw->tx_desc[ (i+1) % TX_DESC_MAX ]) );
+
+    }
+    hw->tx_desc_ptr = 0;	/* we will send an initial packet so it is correct: "oda irtunk utoljara" */
+    hw->busy = 0;
+    hw->tx_desc[hw->tx_desc_ptr].hold = 1;
+    hw->tx_desc[hw->tx_desc_ptr].no = 1;	/* TOD: inkabb csak 0 hosszut kuldjunk ki az initkor? */
+
+    for (i = 0; i < RX_DESC_MAX; i++)
+    {
+	hw->rx_desc[i].no = RXBUFFER_SIZE;
+	hw->rx_desc[i].data = virt_to_phys(&(hw->rx_data[i][0]));
+	hw->rx_desc[i].next = virt_to_phys(&(hw->rx_desc[(i+1) % RX_DESC_MAX]));
+	hw->rx_desc[i].status = 0xFF;
+    }
+    hw->rx_desc_ptr = 0;
+
+    hw->rx_desc[(hw->rx_desc_ptr + RX_DESC_MAX - 2) % RX_DESC_MAX].hold = 1;
+
+    memset((void *)&ccb->channel_spec[channel], 0, sizeof(channel_spec_t));
+
+    ccb->channel_spec[channel].ti = 0;	/* Transmit off */
+    ccb->channel_spec[channel].to = 1;
+    ccb->channel_spec[channel].ta = 0;
+
+    ccb->channel_spec[channel].th = 1;	/* Transmit hold        */
+
+    ccb->channel_spec[channel].ri = 0;	/* Receive off  */
+    ccb->channel_spec[channel].ro = 1;
+    ccb->channel_spec[channel].ra = 0;
+
+    ccb->channel_spec[channel].mode = 3;	/* HDLC */
+
+    ccb->action_spec = CCB_ACTIONSPEC_IN | (channel << 8);
+    writel(CMD_ARPCM, MUNICH_VIRT(CMD));
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout(1);
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+
+    stat = 0;
+    jiffs = jiffies;
+    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))
+    {
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(1);
+    }
+
+    if (stat & STAT_PCMF)
+    {
+	printk(KERN_ERR "MUNICH_open: %s: %s channel %d off failed\n",
+	       dev->name, board->devname, channel);
+	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));
+	MUNICH_close(dev);
+	return -EAGAIN;
+    }
+    else if (!(stat & STAT_PCMA))
+    {
+	printk(KERN_ERR "MUNICH_open: %s: %s channel %d off timeout\n",
+	       dev->name, board->devname, channel);
+	MUNICH_close(dev);
+	return -EIO;
+    }
+
+    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));
+    //      printk("MUNICH_open: %s: succesful channel off took %ld jiffies\n", board->devname, jiffies-jiffs);
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout(1);
+
+    ccb->channel_spec[channel].ifc = 1;	/* 1 .. 'Idle/Flag change' interrupt letiltva   */
+    ccb->channel_spec[channel].fit = 1;
+    ccb->channel_spec[channel].nitbs = 1;
+    ccb->channel_spec[channel].itbs = 2;
+
+    /* TODOO: lehet hogy jo lenne igy, de utana kellene nezni hogy nem okoz-e fragmentaciot */
+    //      ccb->channel_spec[channel].itbs = 2 * number_of_timeslots;
+    //      printk("open: %s: number_of_timeslots: %d\n", dev->name, number_of_timeslots);
+
+    ccb->channel_spec[channel].mode = 3;	/* HDLC */
+    ccb->channel_spec[channel].ftda = virt_to_phys(&(hw->tx_desc));
+    ccb->channel_spec[channel].frda = virt_to_phys(&(hw->rx_desc[0]));
+
+    ccb->channel_spec[channel].ti = 1;	/* Transmit init        */
+    ccb->channel_spec[channel].to = 0;
+    ccb->channel_spec[channel].ta = 1;
+
+    ccb->channel_spec[channel].th = 0;
+
+    ccb->channel_spec[channel].ri = 1;	/* Receive init */
+    ccb->channel_spec[channel].ro = 0;
+    ccb->channel_spec[channel].ra = 1;
+
+    ccb->action_spec = CCB_ACTIONSPEC_ICO | (channel << 8);
+    writel(CMD_ARPCM, MUNICH_VIRT(CMD));	/* Start the channel init */
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout(1);
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+
+    stat = 0;			/* Wait for the action to complete max. 1 second */
+    jiffs = jiffies;
+    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))
+    {
+	set_current_state(TASK_UNINTERRUPTIBLE);
+        schedule_timeout(1);
+    }
+
+    if (stat & STAT_PCMF)
+    {
+	printk(KERN_ERR "MUNICH_open: %s: channel open ARPCM failed\n",
+	       board->devname);
+	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));
+	MUNICH_close(dev);
+	return -EAGAIN;
+    }
+    else if (!(stat & STAT_PCMA))
+    {
+	printk(KERN_ERR "MUNICH_open: %s: channel open ARPCM timeout\n",
+	       board->devname);
+	MUNICH_close(dev);
+	return -EIO;
+    }
+
+    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));
+    //      printk("MUNICH_open: %s: succesful channel open took %ld jiffies\n", board->devname, jiffies-jiffs);
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    ccb->channel_spec[channel].nitbs = 0;	/* once ITBS defined, these must be 0   */
+    ccb->channel_spec[channel].itbs = 0;
+
+    if (board->isx21)
+    {
+	board->modemline_timer.data = (unsigned int)board;
+	board->modemline_timer.function = pcicom_modemline;
+	board->modemline_timer.expires = jiffies + HZ;
+	add_timer((struct timer_list *)&board->modemline_timer);
+    }
+
+    /* It is done. Declare that we're open: */
+    hw->busy = 0;		/* It may be 1 if the frame at Tx init already ended, but it is not     */
+    /* a real problem: we compute hw->busy on every interrupt                       */
+    hw->rafutott = 0;
+    ch->init_status |= HW_OPEN;
+
+    /* Initialize line state: */
+    if (board->lineup)
+	ch->line_status |= LINE_UP;
+    else
+	ch->line_status &= ~LINE_UP;
+
+    /* Remove w attribute from /proc files associated to hw parameters:
+       no write when the device is open */
+
+    for (; procfile; procfile = procfile->next)
+	if (strcmp(procfile->name, FILENAME_BOARDNUM) == 0 ||
+	    strcmp(procfile->name, FILENAME_TIMESLOTS) == 0)
+	    procfile->mode = S_IFREG | 0444;
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+
+    return 0;
+}
+
+/*
+ * Hardware close routine.
+ * Called by comx (upper) layer when the user wants to bring down the interface
+ * with ifconfig.
+ * We also call it from MUNICH_open, if the open fails.
+ * Brings down hardware, frees resources, stops receiver
+ * Returns 0 on OK, or standard error value on error.
+ */
+
+static int MUNICH_close(struct net_device *dev)
+{
+    struct comx_channel *ch = dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+    struct proc_dir_entry *procfile = ch->procdir->subdir;
+    munich_board_t *board;
+    munich_ccb_t *ccb;
+
+    u32 *bar1;
+    u32 timeslots = hw->timeslots;
+    int stat, i, channel = hw->channel;
+    unsigned long jiffs;
+
+    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
+
+    ccb = board->ccb;
+    bar1 = board->bar1;
+
+    if (board->isx21)
+	del_timer((struct timer_list *)&board->modemline_timer);
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout(1);
+
+    /* Disable receiver for the channel: */
+
+    for (i = 0; i < 32; i++)
+	if ((1 << i) & timeslots)
+	{
+	    ccb->timeslot_spec[i].tti = 1;
+	    ccb->timeslot_spec[i].txfillmask = 0;	/* just to be double-sure :) */
+
+	    ccb->timeslot_spec[i].rti = 1;
+	    ccb->timeslot_spec[i].rxfillmask = 0;
+	}
+
+    if (!board->isx21) rework_idle_channels(dev);
+
+    ccb->channel_spec[channel].ti = 0;	/* Receive off, Transmit off */
+    ccb->channel_spec[channel].to = 1;
+    ccb->channel_spec[channel].ta = 0;
+    ccb->channel_spec[channel].th = 1;
+
+    ccb->channel_spec[channel].ri = 0;
+    ccb->channel_spec[channel].ro = 1;
+    ccb->channel_spec[channel].ra = 0;
+
+    board->twins[channel] = NULL;
+
+    ccb->action_spec = CCB_ACTIONSPEC_IN | (channel << 8);
+    writel(CMD_ARPCM, MUNICH_VIRT(CMD));
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout(1);
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+
+    stat = 0;
+    jiffs = jiffies;
+    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))
+    {
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(1);
+    }
+
+    if (stat & STAT_PCMF)
+    {
+	printk(KERN_ERR
+	       "MUNICH_close: %s: FATAL: channel off ARPCM failed, not closing!\n",
+	       dev->name);
+	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));
+	/* If we return success, the privdata (and the descriptor list) will be freed */
+	return -EIO;
+    }
+    else if (!(stat & STAT_PCMA))
+	printk(KERN_ERR "MUNICH_close: %s: channel off ARPCM timeout\n",
+	       board->devname);
+
+    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));
+    //      printk("MUNICH_close: %s: channel off took %ld jiffies\n", board->devname, jiffies-jiffs);
+
+    spin_lock_irqsave(&mister_lock, flags);
+
+    if (board->use_count) board->use_count--;
+
+    if (!board->use_count)	/* we were the last user of the board */
+    {
+	printk("MUNICH_close: bringing down board %s\n", board->devname);
+
+	/* program down the board: */
+
+	writel(0x0000FF7F, MUNICH_VIRT(IMASK));	/* do not send any interrupts */
+	writel(0, MUNICH_VIRT(CMD));	/* stop the timer if someone started it */
+	writel(~0U, MUNICH_VIRT(STAT));	/* if an interrupt came between the cli()-sti(), quiet it */
+	if (ch->hardware == &pcicomhw)
+	    writel(0x1400, MUNICH_VIRT(GPDATA));
+
+	/* Put the board into 'reset' state: */
+	pci_write_config_dword(board->pci, MUNICH_PCI_PCIRES, 0xe0000);
+
+	/* Free irq and other resources: */
+	if (board->irq)
+	    free_irq(board->irq, (void *)board);	/* Ha nem inicializalta magat, akkor meg nincs irq */
+	board->irq = 0;
+
+	/* Free CCB and the interrupt queues */
+	if (board->ccb) kfree((void *)board->ccb);
+	if (board->tiq) kfree((void *)board->tiq);
+	if (board->riq) kfree((void *)board->riq);
+	if (board->piq) kfree((void *)board->piq);
+	board->ccb = board->tiq = board->riq = board->piq = NULL;
+    }
+
+    /* Enable setting of hw parameters */
+    for (; procfile; procfile = procfile->next)
+	if (strcmp(procfile->name, FILENAME_BOARDNUM) == 0 ||
+	    strcmp(procfile->name, FILENAME_TIMESLOTS) == 0)
+	    procfile->mode = S_IFREG | 0644;
+
+    /* We're not open anymore */
+    ch->init_status &= ~HW_OPEN;
+
+    spin_unlock_irqrestore(&mister_lock, flags);
+
+    return 0;
+}
+
+/* 
+ * Give (textual) status information.
+ * The text it returns will be a part of what appears when the user does a
+ * cat /proc/comx/comx[n]/status 
+ * Don't write more than PAGESIZE.
+ * Return value: number of bytes written (length of the string, incl. 0)
+ */
+
+static int MUNICH_minden(struct net_device *dev, char *page)
+{
+    struct comx_channel *ch = dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+    munich_board_t *board;
+    struct net_device *devp;
+
+    u8 *lbi;
+    e1_stats_t *curr_int, *prev_int;
+    e1_stats_t last4, last96;	/* sum of last 4, resp. last 96 intervals               */
+    unsigned *sump,		/* running pointer for the sum data                     */
+     *p;			/* running pointer for the interval data                */
+
+    int len = 0;
+    u8 frs0, frs1;
+    u8 fmr2;
+    int i, j;
+    u32 timeslots;
+
+    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
+
+    lbi = board->lbi;
+    curr_int = &board->intervals[board->current_interval];
+    prev_int =
+	&board->
+	intervals[(board->current_interval + SLICECOM_BOARD_INTERVALS_SIZE -
+		   1) % SLICECOM_BOARD_INTERVALS_SIZE];
+
+    if (!board->isx21)
+    {
+	frs0 = readb(lbi + FRS0);
+	fmr2 = readb(lbi + FMR2);
+	len += snprintf(page + len, PAGE_SIZE - len, "Controller status:\n");
+	if (frs0 == 0)
+	    len += snprintf(page + len, PAGE_SIZE - len, "\tNo alarms\n");
+	else
+	{
+	    if (frs0 & FRS0_LOS)
+	            len += snprintf(page + len, PAGE_SIZE - len, "\tLoss Of Signal\n");
+	    else
+	    {
+		if (frs0 & FRS0_AIS)
+		    len += snprintf(page + len, PAGE_SIZE - len,
+				 "\tAlarm Indication Signal\n");
+		else
+		{
+		    if (frs0 & FRS0_AUXP)
+			len += snprintf(page + len, PAGE_SIZE - len,
+				     "\tAuxiliary Pattern Indication\n");
+		    if (frs0 & FRS0_LFA)
+			len += snprintf(page + len, PAGE_SIZE - len,
+				     "\tLoss of Frame Alignment\n");
+		    else
+		    {
+			if (frs0 & FRS0_RRA)
+			    len += snprintf(page + len, PAGE_SIZE - len,
+					 "\tReceive Remote Alarm\n");
+
+			/* You can't set this framing with the /proc interface, but it  */
+			/* may be good to have here this alarm if you set it by hand:   */
+
+			if ((board->framing == SLICECOM_FRAMING_CRC4) &&
+			    (frs0 & FRS0_LMFA))
+			    len += snprintf(page + len, PAGE_SIZE - len,
+					 "\tLoss of CRC4 Multiframe Alignment\n");
+
+			if (((fmr2 & 0xc0) == 0xc0) && (frs0 & FRS0_NMF))
+			    len += snprintf(page + len, PAGE_SIZE - len,
+				 "\tNo CRC4 Multiframe alignment Found after 400 msec\n");
+		    }
+		}
+	    }
+	}
+
+	frs1 = readb(lbi + FRS1);
+	if (FRS1_XLS & frs1)
+	    len += snprintf(page + len, PAGE_SIZE - len,
+		 "\tTransmit Line Short\n");
+
+	/* debug Rx ring: DEL: - vagy meghagyni, de akkor legyen kicsit altalanosabb */
+    }
+
+    len += snprintf(page + len, PAGE_SIZE - len, "Rx ring:\n");
+    len += snprintf(page + len, PAGE_SIZE - len, "\trafutott: %d\n", hw->rafutott);
+    len += snprintf(page + len, PAGE_SIZE - len,
+		 "\tlastcheck: %ld, jiffies: %ld\n", board->lastcheck, jiffies);
+    len += snprintf(page + len, PAGE_SIZE - len, "\tbase: %08x\n",
+	(u32) virt_to_phys(&hw->rx_desc[0]));
+    len += snprintf(page + len, PAGE_SIZE - len, "\trx_desc_ptr: %d\n",
+		 hw->rx_desc_ptr);
+    len += snprintf(page + len, PAGE_SIZE - len, "\trx_desc_ptr: %08x\n",
+	(u32) virt_to_phys(&hw->rx_desc[hw->rx_desc_ptr]));
+    len += snprintf(page + len, PAGE_SIZE - len, "\thw_curr_ptr: %08x\n",
+		 board->ccb->current_rx_desc[hw->channel]);
+
+    for (i = 0; i < RX_DESC_MAX; i++)
+	len += snprintf(page + len, PAGE_SIZE - len, "\t%08x %08x %08x %08x\n",
+		     *((u32 *) & hw->rx_desc[i] + 0),
+		     *((u32 *) & hw->rx_desc[i] + 1),
+		     *((u32 *) & hw->rx_desc[i] + 2),
+		     *((u32 *) & hw->rx_desc[i] + 3));
+
+    if (!board->isx21)
+    {
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "Interfaces using this board: (channel-group, interface, timeslots)\n");
+	for (i = 0; i < 32; i++)
+	{
+	    devp = board->twins[i];
+	    if (devp != NULL)
+	    {
+		timeslots =
+		    ((struct slicecom_privdata *)((struct comx_channel *)devp->
+						  priv)->HW_privdata)->
+		    timeslots;
+		len += snprintf(page + len, PAGE_SIZE - len, "\t%2d %s: ", i,
+			     devp->name);
+		for (j = 0; j < 32; j++)
+		    if ((1 << j) & timeslots)
+			len += snprintf(page + len, PAGE_SIZE - len, "%d ", j);
+		len += snprintf(page + len, PAGE_SIZE - len, "\n");
+	    }
+	}
+    }
+
+    len += snprintf(page + len, PAGE_SIZE - len, "Interrupt work histogram:\n");
+    for (i = 0; i < MAX_WORK; i++)
+	len += snprintf(page + len, PAGE_SIZE - len, "hist[%2d]: %8u%c", i,
+		     board->histogram[i], (i &&
+					   ((i + 1) % 4 == 0 ||
+					    i == MAX_WORK - 1)) ? '\n' : ' ');
+
+    len += snprintf(page + len, PAGE_SIZE - len, "Tx ring histogram:\n");
+    for (i = 0; i < TX_DESC_MAX; i++)
+	len += snprintf(page + len, PAGE_SIZE - len, "hist[%2d]: %8u%c", i,
+		     hw->tx_ring_hist[i], (i &&
+					   ((i + 1) % 4 == 0 ||
+					    i ==
+					    TX_DESC_MAX - 1)) ? '\n' : ' ');
+
+    if (!board->isx21)
+    {
+
+	memset((void *)&last4, 0, sizeof(last4));
+	memset((void *)&last96, 0, sizeof(last96));
+
+	/* Calculate the sum of last 4 intervals: */
+
+	for (i = 1; i <= 4; i++)
+	{
+	    p = (unsigned *)&board->intervals[(board->current_interval +
+			   SLICECOM_BOARD_INTERVALS_SIZE -
+			   i) % SLICECOM_BOARD_INTERVALS_SIZE];
+	    sump = (unsigned *)&last4;
+	    for (j = 0; j < (sizeof(e1_stats_t) / sizeof(unsigned)); j++)
+		sump[j] += p[j];
+	}
+
+	/* Calculate the sum of last 96 intervals: */
+
+	for (i = 1; i <= 96; i++)
+	{
+	    p = (unsigned *)&board->intervals[(board->current_interval +
+			   SLICECOM_BOARD_INTERVALS_SIZE -
+			   i) % SLICECOM_BOARD_INTERVALS_SIZE];
+	    sump = (unsigned *)&last96;
+	    for (j = 0; j < (sizeof(e1_stats_t) / sizeof(unsigned)); j++)
+		sump[j] += p[j];
+	}
+
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "Data in current interval (%d seconds elapsed):\n",
+		     board->elapsed_seconds);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Line Code Violations, %d Path Code Violations, %d E-Bit Errors\n",
+		     curr_int->line_code_violations,
+		     curr_int->path_code_violations, curr_int->e_bit_errors);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Slip Secs, %d Fr Loss Secs, %d Line Err Secs, %d Degraded Mins\n",
+		     curr_int->slip_secs, curr_int->fr_loss_secs,
+		     curr_int->line_err_secs, curr_int->degraded_mins);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Errored Secs, %d Bursty Err Secs, %d Severely Err Secs, %d Unavail Secs\n",
+		     curr_int->errored_secs, curr_int->bursty_err_secs,
+		     curr_int->severely_err_secs, curr_int->unavail_secs);
+
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "Data in Interval 1 (15 minutes):\n");
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Line Code Violations, %d Path Code Violations, %d E-Bit Errors\n",
+		     prev_int->line_code_violations,
+		     prev_int->path_code_violations, prev_int->e_bit_errors);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Slip Secs, %d Fr Loss Secs, %d Line Err Secs, %d Degraded Mins\n",
+		     prev_int->slip_secs, prev_int->fr_loss_secs,
+		     prev_int->line_err_secs, prev_int->degraded_mins);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Errored Secs, %d Bursty Err Secs, %d Severely Err Secs, %d Unavail Secs\n",
+		     prev_int->errored_secs, prev_int->bursty_err_secs,
+		     prev_int->severely_err_secs, prev_int->unavail_secs);
+
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "Data in last 4 intervals (1 hour):\n");
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Line Code Violations, %d Path Code Violations, %d E-Bit Errors\n",
+		     last4.line_code_violations, last4.path_code_violations,
+		     last4.e_bit_errors);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Slip Secs, %d Fr Loss Secs, %d Line Err Secs, %d Degraded Mins\n",
+		     last4.slip_secs, last4.fr_loss_secs, last4.line_err_secs,
+		     last4.degraded_mins);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Errored Secs, %d Bursty Err Secs, %d Severely Err Secs, %d Unavail Secs\n",
+		     last4.errored_secs, last4.bursty_err_secs,
+		     last4.severely_err_secs, last4.unavail_secs);
+
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "Data in last 96 intervals (24 hours):\n");
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Line Code Violations, %d Path Code Violations, %d E-Bit Errors\n",
+		     last96.line_code_violations, last96.path_code_violations,
+		     last96.e_bit_errors);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Slip Secs, %d Fr Loss Secs, %d Line Err Secs, %d Degraded Mins\n",
+		     last96.slip_secs, last96.fr_loss_secs,
+		     last96.line_err_secs, last96.degraded_mins);
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "   %d Errored Secs, %d Bursty Err Secs, %d Severely Err Secs, %d Unavail Secs\n",
+		     last96.errored_secs, last96.bursty_err_secs,
+		     last96.severely_err_secs, last96.unavail_secs);
+
+    }
+
+//      len +=snprintf( page + len, PAGE_SIZE - len, "Special events:\n" );
+//      len +=snprintf( page + len, PAGE_SIZE - len, "\tstat_pri/missed: %u / %u\n", board->stat_pri_races, board->stat_pri_races_missed );
+//      len +=snprintf( page + len, PAGE_SIZE - len, "\tstat_pti/missed: %u / %u\n", board->stat_pti_races, board->stat_pti_races_missed );
+    return len;
+}
+
+/*
+ * Memory dump function. Not used currently.
+ */
+static int BOARD_dump(struct net_device *dev)
+{
+    printk
+	("BOARD_dump() requested. It is unimplemented, it should not be called\n");
+    return (-1);
+}
+
+/* 
+ * /proc file read function for the files registered by this module.
+ * This function is called by the procfs implementation when a user
+ * wants to read from a file registered by this module.
+ * page is the workspace, start should point to the real start of data,
+ * off is the file offset, data points to the file's proc_dir_entry
+ * structure.
+ * Returns the number of bytes copied to the request buffer.
+ */
+
+static int munich_read_proc(char *page, char **start, off_t off, int count,
+			    int *eof, void *data)
+{
+    struct proc_dir_entry *file = (struct proc_dir_entry *)data;
+    struct net_device *dev = file->parent->data;
+    struct comx_channel *ch = dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+    munich_board_t *board;
+
+    int len = 0, i;
+    u32 timeslots = hw->timeslots;
+
+    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
+
+    if (!strcmp(file->name, FILENAME_BOARDNUM))
+	len = sprintf(page, "%d\n", hw->boardnum);
+    else if (!strcmp(file->name, FILENAME_TIMESLOTS))
+    {
+	for (i = 0; i < 32; i++)
+	    if ((1 << i) & timeslots)
+		len += snprintf(page + len, PAGE_SIZE - len, "%d ", i);
+	len += snprintf(page + len, PAGE_SIZE - len, "\n");
+    }
+    else if (!strcmp(file->name, FILENAME_FRAMING))
+    {
+	i = 0;
+	while (slicecom_framings[i].value &&
+	       slicecom_framings[i].value != board->framing)
+	    i++;
+	len += snprintf(page + len, PAGE_SIZE - len, "%s\n",
+		     slicecom_framings[i].name);
+    }
+    else if (!strcmp(file->name, FILENAME_LINECODE))
+    {
+	i = 0;
+	while (slicecom_linecodes[i].value &&
+	       slicecom_linecodes[i].value != board->linecode)
+	    i++;
+	len += snprintf(page + len, PAGE_SIZE - len, "%s\n",
+		     slicecom_linecodes[i].name);
+    }
+    else if (!strcmp(file->name, FILENAME_CLOCK_SOURCE))
+    {
+	i = 0;
+	while (slicecom_clock_sources[i].value &&
+	       slicecom_clock_sources[i].value != board->clock_source)
+	    i++;
+	len +=
+	    snprintf(page + len, PAGE_SIZE - len, "%s\n",
+		     slicecom_clock_sources[i].name);
+    }
+    else if (!strcmp(file->name, FILENAME_LOOPBACK))
+    {
+	i = 0;
+	while (slicecom_loopbacks[i].value &&
+	       slicecom_loopbacks[i].value != board->loopback)
+	    i++;
+	len += snprintf(page + len, PAGE_SIZE - len, "%s\n",
+		     slicecom_loopbacks[i].name);
+    }
+    /* We set permissions to write-only for REG and LBIREG, but root can read them anyway: */
+    else if (!strcmp(file->name, FILENAME_REG))
+    {
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "%s: " FILENAME_REG ": write-only file\n", dev->name);
+    }
+    else if (!strcmp(file->name, FILENAME_LBIREG))
+    {
+	len += snprintf(page + len, PAGE_SIZE - len,
+		     "%s: " FILENAME_LBIREG ": write-only file\n", dev->name);
+    }
+    else
+    {
+	printk("slicecom_read_proc: internal error, filename %s\n", file->name);
+	return -EBADF;
+    }
+    /* file handling administration: count eof status, offset, start address
+       and count: */
+
+    if (off >= len)
+    {
+	*eof = 1;
+	return 0;
+    }
+
+    *start = page + off;
+    if (count >= len - off)
+	*eof = 1;
+    return min((off_t) count, (off_t) len - off);
+}
+
+/* 
+ * Write function for /proc files registered by us.
+ * See the comment on read function above.
+ * Beware! buffer is in userspace!!!
+ * Returns the number of bytes written
+ */
+
+static int munich_write_proc(struct file *file, const char *buffer,
+			     u_long count, void *data)
+{
+    struct proc_dir_entry *entry = (struct proc_dir_entry *)data;
+    struct net_device *dev = (struct net_device *)entry->parent->data;
+    struct comx_channel *ch = dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+    munich_board_t *board;
+
+    unsigned long ts, tmp_boardnum;
+
+    u32 tmp_timeslots = 0;
+    char *page, *p;
+    int i;
+
+    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
+
+    /* Paranoia checking: */
+
+    if (file->f_dentry->d_inode->i_ino != entry->low_ino)
+    {
+	printk(KERN_ERR "munich_write_proc: file <-> data internal error\n");
+	return -EIO;
+    }
+
+    /* Request tmp buffer */
+    if (!(page = (char *)__get_free_page(GFP_KERNEL)))
+	return -ENOMEM;
+
+    /* Copy user data and cut trailing \n */
+    copy_from_user(page, buffer, count = min(count, PAGE_SIZE));
+    if (*(page + count - 1) == '\n')
+	*(page + count - 1) = 0;
+    *(page + PAGE_SIZE - 1) = 0;
+
+    if (!strcmp(entry->name, FILENAME_BOARDNUM))
+    {
+	tmp_boardnum = simple_strtoul(page, NULL, 0);
+	if (0 <= tmp_boardnum && tmp_boardnum < MAX_BOARDS)
+	    hw->boardnum = tmp_boardnum;
+	else
+	{
+	    printk("%s: " FILENAME_BOARDNUM " range is 0...%d\n", dev->name,
+		   MAX_BOARDS - 1);
+	    free_page((unsigned long)page);
+	    return -EINVAL;
+	}
+    }
+    else if (!strcmp(entry->name, FILENAME_TIMESLOTS))
+    {
+	p = page;
+	while (*p)
+	{
+	    if (isspace(*p))
+		p++;
+	    else
+	    {
+		ts = simple_strtoul(p, &p, 10);	/* base = 10: Don't read 09 as an octal number */
+		/* ts = 0 ha nem tudta beolvasni a stringet, erre egy kicsit epitek itt: */
+		if (0 <= ts && ts < 32)
+		{
+		    tmp_timeslots |= (1 << ts);
+		}
+		else
+		{
+		    printk("%s: " FILENAME_TIMESLOTS " range is 1...31\n",
+			   dev->name);
+		    free_page((unsigned long)page);
+		    return -EINVAL;
+		}
+	    }
+	}
+	hw->timeslots = tmp_timeslots;
+    }
+    else if (!strcmp(entry->name, FILENAME_FRAMING))
+    {
+	i = 0;
+	while (slicecom_framings[i].value &&
+	       strncmp(slicecom_framings[i].name, page,
+		       strlen(slicecom_framings[i].name)))
+	    i++;
+	if (!slicecom_framings[i].value)
+	{
+	    printk("slicecom: %s: Invalid " FILENAME_FRAMING " '%s'\n",
+		   dev->name, page);
+	    free_page((unsigned long)page);
+	    return -EINVAL;
+	}
+	else
+	{			/*
+				 * If somebody says:
+				 *      echo >boardnum  0
+				 *      echo >framing   no-crc4
+				 *      echo >boardnum  1
+				 * - when the framing was set, hw->boardnum was 0, so it would set the framing for board 0
+				 * Workaround: allow to set it only if interface is administrative UP
+				 */
+	    if (netif_running(dev))
+		slicecom_set_framing(hw->boardnum, slicecom_framings[i].value);
+	    else
+	    {
+		printk("%s: " FILENAME_FRAMING
+		       " can not be set while the interface is DOWN\n",
+		       dev->name);
+		free_page((unsigned long)page);
+		return -EINVAL;
+	    }
+	}
+    }
+    else if (!strcmp(entry->name, FILENAME_LINECODE))
+    {
+	i = 0;
+	while (slicecom_linecodes[i].value &&
+	       strncmp(slicecom_linecodes[i].name, page,
+		       strlen(slicecom_linecodes[i].name)))
+	    i++;
+	if (!slicecom_linecodes[i].value)
+	{
+	    printk("slicecom: %s: Invalid " FILENAME_LINECODE " '%s'\n",
+		   dev->name, page);
+	    free_page((unsigned long)page);
+	    return -EINVAL;
+	}
+	else
+	{			/*
+				 * Allow to set it only if interface is administrative UP,
+				 * for the same reason as FILENAME_FRAMING
+				 */
+	    if (netif_running(dev))
+		slicecom_set_linecode(hw->boardnum,
+				      slicecom_linecodes[i].value);
+	    else
+	    {
+		printk("%s: " FILENAME_LINECODE
+		       " can not be set while the interface is DOWN\n",
+		       dev->name);
+		free_page((unsigned long)page);
+		return -EINVAL;
+	    }
+	}
+    }
+    else if (!strcmp(entry->name, FILENAME_CLOCK_SOURCE))
+    {
+	i = 0;
+	while (slicecom_clock_sources[i].value &&
+	       strncmp(slicecom_clock_sources[i].name, page,
+		       strlen(slicecom_clock_sources[i].name)))
+	    i++;
+	if (!slicecom_clock_sources[i].value)
+	{
+	    printk("%s: Invalid " FILENAME_CLOCK_SOURCE " '%s'\n", dev->name,
+		   page);
+	    free_page((unsigned long)page);
+	    return -EINVAL;
+	}
+	else
+	{			/*
+				 * Allow to set it only if interface is administrative UP,
+				 * for the same reason as FILENAME_FRAMING
+				 */
+	    if (netif_running(dev))
+		slicecom_set_clock_source(hw->boardnum,
+					  slicecom_clock_sources[i].value);
+	    else
+	    {
+		printk("%s: " FILENAME_CLOCK_SOURCE
+		       " can not be set while the interface is DOWN\n",
+		       dev->name);
+		free_page((unsigned long)page);
+		return -EINVAL;
+	    }
+	}
+    }
+    else if (!strcmp(entry->name, FILENAME_LOOPBACK))
+    {
+	i = 0;
+	while (slicecom_loopbacks[i].value &&
+	       strncmp(slicecom_loopbacks[i].name, page,
+		       strlen(slicecom_loopbacks[i].name)))
+	    i++;
+	if (!slicecom_loopbacks[i].value)
+	{
+	    printk("%s: Invalid " FILENAME_LOOPBACK " '%s'\n", dev->name, page);
+	    free_page((unsigned long)page);
+	    return -EINVAL;
+	}
+	else
+	{			/*
+				 * Allow to set it only if interface is administrative UP,
+				 * for the same reason as FILENAME_FRAMING
+				 */
+	    if (netif_running(dev))
+		slicecom_set_loopback(hw->boardnum,
+				      slicecom_loopbacks[i].value);
+	    else
+	    {
+		printk("%s: " FILENAME_LOOPBACK
+		       " can not be set while the interface is DOWN\n",
+		       dev->name);
+		free_page((unsigned long)page);
+		return -EINVAL;
+	    }
+	}
+    }
+    else if (!strcmp(entry->name, FILENAME_REG))
+    {				/* DEL: 'reg' csak tmp */
+	char *p;
+	u32 *bar1 = board->bar1;
+
+	reg = simple_strtoul(page, &p, 0);
+	reg_ertek = simple_strtoul(p + 1, NULL, 0);
+
+	if (reg < 0x100)
+	{
+	    printk("reg(0x%02x) := 0x%08x  jiff: %lu\n", reg, reg_ertek, jiffies);
+	    writel(reg_ertek, MUNICH_VIRT(reg >> 2));
+	}
+	else
+	{
+	    printk("reg(0x%02x) is 0x%08x  jiff: %lu\n", reg - 0x100,
+		   readl(MUNICH_VIRT((reg - 0x100) >> 2)), jiffies);
+	}
+    }
+    else if (!strcmp(entry->name, FILENAME_LBIREG))
+    {				/* DEL: 'lbireg' csak tmp */
+	char *p;
+	u8 *lbi = board->lbi;
+
+	lbireg = simple_strtoul(page, &p, 0);
+	lbireg_ertek = simple_strtoul(p + 1, NULL, 0);
+
+	if (lbireg < 0x100)
+	{
+	    printk("lbireg(0x%02x) := 0x%02x  jiff: %lu\n", lbireg,
+		   lbireg_ertek, jiffies);
+	    writeb(lbireg_ertek, lbi + lbireg);
+	}
+	else
+	    printk("lbireg(0x%02x) is 0x%02x  jiff: %lu\n", lbireg - 0x100,
+		   readb(lbi + lbireg - 0x100), jiffies);
+    }
+    else
+    {
+	printk(KERN_ERR "munich_write_proc: internal error, filename %s\n",
+	       entry->name);
+	free_page((unsigned long)page);
+	return -EBADF;
+    }
+
+    /* Don't forget to free the workspace */
+    free_page((unsigned long)page);
+    return count;
+}
+
+/* 
+ * Boardtype init function.
+ * Called by the comx (upper) layer, when you set boardtype.
+ * Allocates resources associated to using munich board for this device,
+ * initializes ch_struct pointers etc.
+ * Returns 0 on success and standard error codes on error.
+ */
+
+static int init_escape(struct comx_channel *ch)
+{
+    kfree(ch->HW_privdata);
+    return -EIO;
+}
+
+static int BOARD_init(struct net_device *dev)
+{
+    struct comx_channel *ch = (struct comx_channel *)dev->priv;
+    struct slicecom_privdata *hw;
+    struct proc_dir_entry *new_file;
+
+    /* Alloc data for private structure */
+    if ((ch->HW_privdata =
+	kmalloc(sizeof(struct slicecom_privdata), GFP_KERNEL)) == NULL)
+        return -ENOMEM;
+        
+    memset(hw = ch->HW_privdata, 0, sizeof(struct slicecom_privdata));
+
+    /* Register /proc files */
+    if ((new_file = create_proc_entry(FILENAME_BOARDNUM, S_IFREG | 0644,
+			   ch->procdir)) == NULL)
+	return init_escape(ch);
+    new_file->data = (void *)new_file;
+    new_file->read_proc = &munich_read_proc;
+    new_file->write_proc = &munich_write_proc;
+//      new_file->proc_iops = &comx_normal_inode_ops;
+    new_file->nlink = 1;
+
+    if (ch->hardware == &slicecomhw)
+    {
+	if ((new_file = create_proc_entry(FILENAME_TIMESLOTS, S_IFREG | 0644,
+			       ch->procdir)) == NULL)
+	    return init_escape(ch);
+	new_file->data = (void *)new_file;
+	new_file->read_proc = &munich_read_proc;
+	new_file->write_proc = &munich_write_proc;
+//              new_file->proc_iops = &comx_normal_inode_ops;
+	new_file->nlink = 1;
+
+	if ((new_file = create_proc_entry(FILENAME_FRAMING, S_IFREG | 0644,
+			       ch->procdir)) == NULL)
+	    return init_escape(ch);
+	new_file->data = (void *)new_file;
+	new_file->read_proc = &munich_read_proc;
+	new_file->write_proc = &munich_write_proc;
+//              new_file->proc_iops = &comx_normal_inode_ops;
+	new_file->nlink = 1;
+
+	if ((new_file = create_proc_entry(FILENAME_LINECODE, S_IFREG | 0644,
+			       ch->procdir)) == NULL)
+	    return init_escape(ch);
+	new_file->data = (void *)new_file;
+	new_file->read_proc = &munich_read_proc;
+	new_file->write_proc = &munich_write_proc;
+//              new_file->proc_iops = &comx_normal_inode_ops;
+	new_file->nlink = 1;
+
+	if ((new_file = create_proc_entry(FILENAME_CLOCK_SOURCE, S_IFREG | 0644,
+			       ch->procdir)) == NULL)
+	    return init_escape(ch);
+	new_file->data = (void *)new_file;
+	new_file->read_proc = &munich_read_proc;
+	new_file->write_proc = &munich_write_proc;
+//              new_file->proc_iops = &comx_normal_inode_ops;
+	new_file->nlink = 1;
+
+	if ((new_file = create_proc_entry(FILENAME_LOOPBACK, S_IFREG | 0644,
+			       ch->procdir)) == NULL)
+	    return init_escape(ch);
+	new_file->data = (void *)new_file;
+	new_file->read_proc = &munich_read_proc;
+	new_file->write_proc = &munich_write_proc;
+//              new_file->proc_iops = &comx_normal_inode_ops;
+	new_file->nlink = 1;
+    }
+
+    /* DEL: ez itt csak fejlesztesi celokra!! */
+    if ((new_file = create_proc_entry(FILENAME_REG, S_IFREG | 0200, ch->procdir)) == NULL)
+	return init_escape(ch);
+    new_file->data = (void *)new_file;
+    new_file->read_proc = &munich_read_proc;
+    new_file->write_proc = &munich_write_proc;
+//      new_file->proc_iops = &comx_normal_inode_ops;
+    new_file->nlink = 1;
+
+    /* DEL: ez itt csak fejlesztesi celokra!! */
+    if ((new_file = create_proc_entry(FILENAME_LBIREG, S_IFREG | 0200,
+			   ch->procdir)) == NULL)
+	return init_escape(ch);
+    new_file->data = (void *)new_file;
+    new_file->read_proc = &munich_read_proc;
+    new_file->write_proc = &munich_write_proc;
+//      new_file->proc_iops = &comx_normal_inode_ops;
+    new_file->nlink = 1;
+
+    /* Fill in ch_struct hw specific pointers: */
+
+    ch->HW_txe = MUNICH_txe;
+    ch->HW_open = MUNICH_open;
+    ch->HW_close = MUNICH_close;
+    ch->HW_send_packet = MUNICH_send_packet;
+#ifndef COMX_NEW
+    ch->HW_minden = MUNICH_minden;
+#else
+    ch->HW_statistics = MUNICH_minden;
+#endif
+
+    hw->boardnum = SLICECOM_BOARDNUM_DEFAULT;
+    hw->timeslots = ch->hardware == &pcicomhw ?  0xffffffff : 2;
+
+    /* O.K. Count one more user on this module */
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+/* 
+ * Boardtype exit function.
+ * Called by the comx (upper) layer, when you clear boardtype from munich.
+ * Frees resources associated to using munich board for this device,
+ * resets ch_struct pointers etc.
+ */
+static int BOARD_exit(struct net_device *dev)
+{
+    struct comx_channel *ch = (struct comx_channel *)dev->priv;
+    struct slicecom_privdata *hw = ch->HW_privdata;
+//    munich_board_t *board;
+
+    /* Free private data area */
+//    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
+
+    kfree(ch->HW_privdata);
+    /* Remove /proc files */
+    remove_proc_entry(FILENAME_BOARDNUM, ch->procdir);
+    if (ch->hardware == &slicecomhw)
+    {
+	remove_proc_entry(FILENAME_TIMESLOTS, ch->procdir);
+	remove_proc_entry(FILENAME_FRAMING, ch->procdir);
+	remove_proc_entry(FILENAME_LINECODE, ch->procdir);
+	remove_proc_entry(FILENAME_CLOCK_SOURCE, ch->procdir);
+	remove_proc_entry(FILENAME_LOOPBACK, ch->procdir);
+    }
+    remove_proc_entry(FILENAME_REG, ch->procdir);
+    remove_proc_entry(FILENAME_LBIREG, ch->procdir);
+
+    /* Minus one user for the module accounting */
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+static struct comx_hardware slicecomhw =
+{
+    "slicecom",
+#ifdef COMX_NEW
+    VERSION,
+#endif
+    BOARD_init,
+    BOARD_exit,
+    BOARD_dump,
+    NULL
+};
+
+static struct comx_hardware pcicomhw =
+{
+    "pcicom",
+#ifdef COMX_NEW
+    VERSION,
+#endif
+    BOARD_init,
+    BOARD_exit,
+    BOARD_dump,
+    NULL
+};
+
+/* Module management */
+
+int __init init_mister(void)
+{
+    printk(VERSIONSTR);
+    comx_register_hardware(&slicecomhw);
+    comx_register_hardware(&pcicomhw);
+    return munich_probe();
+}
+
+static void __exit cleanup_mister(void)
+{
+    int i;
+
+    comx_unregister_hardware("slicecom");
+    comx_unregister_hardware("pcicom");
+
+    for (i = 0; i < MAX_BOARDS; i++)
+    {
+	if (slicecom_boards[i].bar1)
+	    iounmap((void *)slicecom_boards[i].bar1);
+	if (slicecom_boards[i].lbi)
+	    iounmap((void *)slicecom_boards[i].lbi);
+	if (pcicom_boards[i].bar1)
+	    iounmap((void *)pcicom_boards[i].bar1);
+	if (pcicom_boards[i].lbi)
+	    iounmap((void *)pcicom_boards[i].lbi);
+    }
+}
+
+module_init(init_mister);
+module_exit(cleanup_mister);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/comx.c linux/drivers/net/wan/comx.c
--- linux.orig/drivers/net/wan/comx.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/net/wan/comx.c	2002-07-20 01:08:35.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Device driver framework for the COMX line of synchronous serial boards
  * 
- * for Linux kernel 2.2.X
+ * for Linux kernel 2.2.X / 2.4.X
  *
  * Original authors:  Arpad Bakay <bakay.arpad@synergon.hu>,
  *                    Peter Bajan <bajan.peter@synergon.hu>,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/falc-lh.h linux/drivers/net/wan/falc-lh.h
--- linux.orig/drivers/net/wan/falc-lh.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/falc-lh.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,102 @@
+/*
+ *	Defines for comx-hw-slicecom.c - FALC-LH specific
+ *
+ *	Author:		Bartok Istvan <bartoki@itc.hu>
+ *	Last modified:	Mon Feb  7 20:00:38 CET 2000
+ *
+ *	:set tabstop=6
+ */
+
+/*
+ *	Control register offsets on the LBI (page 90)
+ *	use it like:
+ *	lbi[ MODE ] = 0x34;
+ */
+
+#define MODE	0x03
+#define IPC		0x08
+#define IMR0	0x14	/* Interrupt Mask Register 0	*/
+#define IMR1	0x15
+#define IMR2	0x16
+#define IMR3	0x17
+#define IMR4	0x18
+#define IMR5	0x19
+#define FMR0	0x1a	/* Framer Mode Register 0	*/
+#define FMR1	0x1b
+#define FMR2	0x1c
+#define XSW		0x1e
+#define XSP		0x1f
+#define XC0		0x20
+#define XC1		0x21
+#define RC0		0x22
+#define RC1		0x23
+#define XPM0	0x24
+#define XPM1	0x25
+#define XPM2	0x26
+#define TSWM	0x27
+#define IDLE	0x29	/* Idle Code	*/
+#define LIM0	0x34
+#define LIM1	0x35
+#define PCD		0x36
+#define PCR		0x37
+#define LIM2	0x38
+
+/*
+ *	Status registers on the LBI (page 134)
+ *	these are read-only, use it like:
+ *	if( lbi[ FRS0 ] ) ...
+ */
+
+#define FRS0	0x4c	/* Framer Receive Status register 0	*/
+#define FRS1	0x4d	/* Framer Receive Status register 1	*/
+#define FECL	0x50	/* Framing Error Counter low byte	*/ /* Counts FAS word receive errors		*/
+#define FECH	0x51	/*                       high byte	*/
+#define CVCL	0x52	/* Code Violation Counter low byte	*/ /* Counts bipolar and HDB3 code violations	*/
+#define CVCH	0x53	/*                        high byte	*/
+#define CEC1L	0x54	/* CRC4 Error Counter 1 low byte	*/ /* Counts CRC4 errors in the incoming stream	*/
+#define CEC1H	0x55	/*                      high byte	*/
+#define EBCL	0x56	/* E Bit error Counter low byte	*/ /* E-bits: the remote end sends them, when	*/
+#define EBCH	0x57	/*                     high byte	*/ /* it detected a CRC4-error			*/
+#define ISR0	0x68	/* Interrupt Status Register 0	*/
+#define ISR1	0x69	/* Interrupt Status Register 1	*/
+#define ISR2	0x6a	/* Interrupt Status Register 2	*/
+#define ISR3	0x6b	/* Interrupt Status Register 3	*/
+#define ISR5	0x6c	/* Interrupt Status Register 5	*/
+#define GIS	0x6e	/* Global Interrupt Status Register	*/
+#define VSTR	0x6f	/* version information */
+
+/*
+ *	Bit fields
+ */
+
+#define FRS0_LOS		(1 << 7)
+#define FRS0_AIS		(1 << 6)
+#define FRS0_LFA		(1 << 5)
+#define FRS0_RRA		(1 << 4)
+#define FRS0_AUXP		(1 << 3)
+#define FRS0_NMF		(1 << 2)
+#define FRS0_LMFA		(1 << 1)
+
+#define FRS1_XLS		(1 << 1)
+#define FRS1_XLO		(1)
+
+#define ISR2_FAR		(1 << 7)
+#define ISR2_LFA		(1 << 6)
+#define ISR2_MFAR		(1 << 5)
+#define ISR2_T400MS	(1 << 4)
+#define ISR2_AIS		(1 << 3)
+#define ISR2_LOS		(1 << 2)
+#define ISR2_RAR		(1 << 1)
+#define ISR2_RA		(1)
+
+#define ISR3_ES		(1 << 7)
+#define ISR3_SEC		(1 << 6)
+#define ISR3_LMFA16	(1 << 5)
+#define ISR3_AIS16	(1 << 4)
+#define ISR3_RA16		(1 << 3)
+#define ISR3_API		(1 << 2)
+#define ISR3_RSN		(1 << 1)
+#define ISR3_RSP		(1)
+
+#define ISR5_XSP		(1 << 7)
+#define ISR5_XSN		(1 << 6)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/lmc/lmc_debug.c linux/drivers/net/wan/lmc/lmc_debug.c
--- linux.orig/drivers/net/wan/lmc/lmc_debug.c	2000-04-21 23:08:45.000000000 +0000
+++ linux/drivers/net/wan/lmc/lmc_debug.c	2002-07-20 01:08:31.000000000 +0000
@@ -72,12 +72,12 @@
 
     if(in_interrupt()){
         printk("%s: * %s\n", dev->name, msg);
-//        while(jiffies < j+10)
+//        while(time_before(jiffies, j+10))
 //            ;
     }
     else {
         printk("%s: %s\n", dev->name, msg);
-        while(jiffies < j)
+        while(time_before(jiffies, j))
             schedule();
     }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/lmc/lmc_var.h linux/drivers/net/wan/lmc/lmc_var.h
--- linux.orig/drivers/net/wan/lmc/lmc_var.h	2001-03-07 03:44:36.000000000 +0000
+++ linux/drivers/net/wan/lmc/lmc_var.h	2002-07-20 01:08:35.000000000 +0000
@@ -87,7 +87,7 @@
 		lmc_delay(); \
 		LMC_CSR_WRITE((sc), csr_9, 0x30000); \
                 lmc_delay(); \
-		n--; }} while(0);
+		n--; }} while(0)
 
 struct lmc_regfile_t {
     lmc_csrptr_t csr_busmode;                  /* CSR0 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/munich32x.h linux/drivers/net/wan/munich32x.h
--- linux.orig/drivers/net/wan/munich32x.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wan/munich32x.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,191 @@
+/*
+ *	Defines for comx-hw-slicecom.c - MUNICH32X specific
+ *
+ *	Author:        Bartok Istvan <bartoki@itc.hu>
+ *	Last modified: Tue Jan 11 14:27:36 CET 2000
+ *
+ *	:set tabstop=6
+ */
+
+#define TXBUFFER_SIZE	1536			/* Max mennyit tud a kartya hardver atvenni				*/
+#define RXBUFFER_SIZE	(TXBUFFER_SIZE+4)	/* For Rx reasons it must be a multiple of 4, and =>4 (page 265)	*/
+							/* +4 .. see page 265, bit FE							*/
+							/* TOD: a MODE1-be nem is ezt teszem, hanem a TXBUFFER-t, lehet hogy nem is kell? */
+
+//#define PCI_VENDOR_ID_SIEMENS			0x110a
+#define PCI_DEVICE_ID_SIEMENS_MUNICH32X	0x2101
+
+/*
+ *	PCI config space registers (page 120)
+ */
+
+#define MUNICH_PCI_PCIRES	0x4c		/* 0xe0000 resets	the chip	*/
+
+
+/*
+ *	MUNICH slave register offsets relative to base_address[0] (PCI BAR1) (page 181):
+ *	offsets are in bytes, registers are u32's, so we need a >>2 for indexing
+ *	the int[] by byte offsets. Use it like:
+ *
+ *	bar1[ STAT ] = ~0L;  or
+ *	x = bar1[ STAT ];
+ */
+
+#define CONF	(0x00 >> 2)
+#define CMD		(0x04 >> 2)
+#define STAT	(0x08 >> 2)
+#define STACK	(0x08 >> 2)
+#define IMASK	(0x0c >> 2)
+#define PIQBA	(0x14 >> 2)
+#define PIQL	(0x18 >> 2)
+#define MODE1	(0x20 >> 2)
+#define MODE2	(0x24 >> 2)
+#define CCBA	(0x28 >> 2)
+#define TXPOLL	(0x2c >> 2)
+#define TIQBA	(0x30 >> 2)
+#define TIQL	(0x34 >> 2)
+#define RIQBA	(0x38 >> 2)
+#define RIQL	(0x3c >> 2)
+#define LCONF	(0x40 >> 2)		/* LBI Configuration Register		*/
+#define LCCBA	(0x44 >> 2)		/* LBI Configuration Control Block	*/	/* DE: lehet hogy nem is kell? */
+#define LTIQBA	(0x50 >> 2)		/* DE: lehet hogy nem is kell? page 210: LBI DMA Controller intq - nem hasznalunk DMA-t.. */
+#define LTIQL	(0x54 >> 2)		/* DE: lehet hogy nem is kell? */
+#define LRIQBA	(0x58 >> 2)		/* DE: lehet hogy nem is kell? */
+#define LRIQL	(0x5c >> 2)		/* DE: lehet hogy nem is kell? */
+#define LREG0	(0x60 >> 2)		/* LBI Indirect External Configuration register 0	*/
+#define LREG1	(0x64 >> 2)
+#define LREG2	(0x68 >> 2)
+#define LREG3	(0x6c >> 2)
+#define LREG4	(0x70 >> 2)
+#define LREG5	(0x74 >> 2)
+#define LREG6	(0x78 >> 2)		/* LBI Indirect External Configuration register 6		*/
+#define LSTAT	(0x7c >> 2)		/* LBI Status Register							*/
+#define GPDIR	(0x80 >> 2)		/* General Purpose Bus DIRection - 0..input, 1..output	*/
+#define GPDATA	(0x84 >> 2)		/* General Purpose Bus DATA						*/
+
+
+/*
+ *	MUNICH commands: (they go into register CMD)
+ */
+
+#define CMD_ARPCM	0x01			/* Action Request Serial PCM Core	*/
+#define CMD_ARLBI	0x02			/* Action Request LBI			*/
+
+
+/*
+ *	MUNICH event bits in the STAT, STACK, IMASK registers (page 188,189)
+ */
+
+#define STAT_PTI	(1 << 15)
+#define STAT_PRI	(1 << 14)
+#define STAT_LTI	(1 << 13)
+#define STAT_LRI	(1 << 12)
+#define STAT_IOMI	(1 << 11)
+#define STAT_SSCI	(1 << 10)
+#define STAT_LBII	(1 << 9)
+#define STAT_MBI	(1 << 8)
+
+#define STAT_TI	(1 << 6)
+#define STAT_TSPA	(1 << 5)
+#define STAT_RSPA	(1 << 4)
+#define STAT_LBIF	(1 << 3)
+#define STAT_LBIA	(1 << 2)
+#define STAT_PCMF	(1 << 1)
+#define STAT_PCMA	(1) 
+
+/*
+ *	We do not handle these (and do not touch their STAT bits) in the interrupt loop
+ */
+
+#define STAT_NOT_HANDLED_BY_INTERRUPT	(STAT_PCMF | STAT_PCMA)
+
+
+/*
+ *	MUNICH MODE1/MODE2 slave register fields (page 193,196)
+ *	these are not all masks, MODE1_XX_YY are my magic values!
+ */
+
+#define MODE1_PCM_E1	(1 << 31)		/* E1, 2.048 Mbit/sec		*/
+#define MODE1_TBS_4	(1 << 24)		/* TBS = 4 .. no Tx bit shift	*/
+#define MODE1_RBS_4	(1 << 18)		/* RBS = 4 .. no Rx bit shift	*/
+#define MODE1_REN		(1 << 15)		/* Rx Enable			*/
+#define MODE1_MFL_MY	TXBUFFER_SIZE	/* Maximum Frame Length		*/
+#define MODE1_MAGIC	(MODE1_PCM_E1 | MODE1_TBS_4 | MODE1_RBS_4 | MODE1_REN | MODE1_MFL_MY)
+
+#define MODE2_HPOLL	(1 << 8)		/* Hold Poll			*/
+#define MODE2_SPOLL	(1 << 7)		/* Slow Poll			*/
+#define MODE2_TSF		(1)			/* real magic - discovered by probing :)	*/
+// #define MODE2_MAGIC	(MODE2_TSF)
+#define MODE2_MAGIC	(MODE2_SPOLL | MODE2_TSF)
+
+
+/*
+ *	LCONF bits (page 205)
+ *	these are not all masks, LCONF_XX_YY are my magic values!
+ */
+
+#define LCONF_IPA			(1 << 31)	/* Interrupt Pass. Use 1 for FALC54							*/
+#define LCONF_DCA			(1 << 30)	/* Disregard the int's for Channel A - DMSM does not try to handle them	*/
+#define LCONF_DCB			(1 << 29)	/* Disregard the int's for Channel B						*/
+#define LCONF_EBCRES		(1 << 22)	/* Reset LBI External Bus Controller, 0..reset, 1..normal operation	*/
+#define LCONF_LBIRES		(1 << 21)	/* Reset LBI DMSM, 0..reset, 1..normal operation				*/
+#define LCONF_BTYP_16DEMUX	(1 << 7)	/* 16-bit demultiplexed bus	*/
+#define LCONF_ABM			(1 << 4)	/* Arbitration Master		*/
+
+/* writing LCONF_MAGIC1 followed by a LCONF_MAGIC2 into LCONF resets the EBC and DMSM: */
+
+#define LCONF_MAGIC1		(LCONF_BTYP_16DEMUX | LCONF_ABM | LCONF_IPA | LCONF_DCA | LCONF_DCB)
+#define LCONF_MAGIC2		(LCONF_MAGIC1 | LCONF_EBCRES | LCONF_LBIRES)
+
+
+/*
+ *	LREGx magic values if a FALC54 is on the LBI (page 217)
+ */
+
+#define LREG0_MAGIC	0x00000264
+#define LREG1_MAGIC	0x6e6a6b66
+#define LREG2_MAGIC	0x00000264
+#define LREG3_MAGIC	0x6e686966
+#define LREG4_MAGIC	0x00000000
+#define LREG5_MAGIC	( (7<<27) | (3<<24) | (1<<21) | (7<<3) | (2<<9) )
+
+
+/*
+ *	PCM Action Specification fields (munich_ccb_t.action_spec)
+ */
+
+#define CCB_ACTIONSPEC_IN			(1 << 15)	/* init				*/
+#define CCB_ACTIONSPEC_ICO			(1 << 14)	/* init only this channel	*/
+#define CCB_ACTIONSPEC_RES			(1 << 6)	/* reset all channels		*/
+#define CCB_ACTIONSPEC_LOC			(1 << 5)
+#define CCB_ACTIONSPEC_LOOP			(1 << 4)
+#define CCB_ACTIONSPEC_LOOPI			(1 << 3)
+#define CCB_ACTIONSPEC_IA			(1 << 2)
+
+
+/*
+ *	Interrupt Information bits in the TIQ, RIQ
+ */
+
+#define PCM_INT_HI	(1 << 12)
+#define PCM_INT_FI	(1 << 11)
+#define PCM_INT_IFC	(1 << 10)
+#define PCM_INT_SF	(1 << 9)
+#define PCM_INT_ERR	(1 << 8)
+#define PCM_INT_FO	(1 << 7)
+#define PCM_INT_FE2	(1 << 6)
+
+#define PCM_INT_CHANNEL( info )	(info & 0x1F)
+
+
+/*
+ *	Rx status info in the rx_desc_t.status
+ */
+
+#define RX_STATUS_SF	(1 << 6)
+#define RX_STATUS_LOSS	(1 << 5)
+#define RX_STATUS_CRCO	(1 << 4)
+#define RX_STATUS_NOB	(1 << 3)
+#define RX_STATUS_LFD	(1 << 2)
+#define RX_STATUS_RA	(1 << 1)
+#define RX_STATUS_ROF	1 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/sdla.c linux/drivers/net/wan/sdla.c
--- linux.orig/drivers/net/wan/sdla.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/net/wan/sdla.c	2002-07-20 01:08:36.000000000 +0000
@@ -1348,8 +1348,10 @@
 		return(-EINVAL);
 
 	dev->base_addr = map->base_addr;
-	request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name);
-
+	if (!request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name)){
+		printk(KERN_WARNING "SDLA: io-port 0x%04lx in use \n", dev->base_addr);
+		return(-EINVAL);
+	}
 	/* test for card types, S502A, S502E, S507, S508                 */
 	/* these tests shut down the card completely, so clear the state */
 	flp->type = SDLA_UNKNOWN;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/sdla_chdlc.c linux/drivers/net/wan/sdla_chdlc.c
--- linux.orig/drivers/net/wan/sdla_chdlc.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/net/wan/sdla_chdlc.c	2002-07-20 01:08:36.000000000 +0000
@@ -2680,18 +2680,20 @@
 		printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname);
 
                 if(card->u.c.slarp_timer) {
+			u32 addr_net = htonl(chdlc_priv_area->IP_address);
 
-			printk(KERN_INFO "%s: Bad IP address %s received\n",
+			printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u received\n",
 				card->devname,
-				in_ntoa(ntohl(chdlc_priv_area->IP_address)));
+			       NIPQUAD(addr_net));
                         printk(KERN_INFO "%s: from remote station.\n",
 				card->devname);
 
                 }else{ 
+			u32 addr_net = htonl(chdlc_priv_area->IP_address);
 
-                        printk(KERN_INFO "%s: Bad IP address %s issued\n",
-				card->devname,
-				in_ntoa(ntohl(chdlc_priv_area->IP_address)));
+                        printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u issued\n",
+			       card->devname,
+			       NIPQUAD(addr_net));
                         printk(KERN_INFO "%s: to remote station. Local\n",
 				card->devname);
 			printk(KERN_INFO "%s: IP address must be A.B.C.1\n",
@@ -2810,16 +2812,16 @@
 		}
 
                if(err) {
-			printk(KERN_INFO "%s: Add route %s failed (%d)\n", 
-				card->devname, in_ntoa(remote_IP_addr), err);
+			printk(KERN_INFO "%s: Add route %u.%u.%u.%u failed (%d)\n", 
+				card->devname, NIPQUAD(remote_IP_addr), err);
 		} else {
 			((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED;
 			printk(KERN_INFO "%s: Dynamic route added.\n",
 				card->devname);
-			printk(KERN_INFO "%s:    Local IP addr : %s\n",
-				card->devname, in_ntoa(local_IP_addr));
-			printk(KERN_INFO "%s:    Remote IP addr: %s\n",
-				card->devname, in_ntoa(remote_IP_addr));
+			printk(KERN_INFO "%s:    Local IP addr : %u.%u.%u.%u\n",
+				card->devname, NIPQUAD(local_IP_addr));
+			printk(KERN_INFO "%s:    Remote IP addr: %u.%u.%u.%u\n",
+				card->devname, NIPQUAD(remote_IP_addr));
 			chdlc_priv_area->route_removed = 0;
 		}
 		break;
@@ -2851,13 +2853,13 @@
 		if(err) {
 			printk(KERN_INFO
 				"%s: Remove route %s failed, (err %d)\n",
-					card->devname, in_ntoa(remote_IP_addr),
+					card->devname, NIPQUAD(remote_IP_addr),
 					err);
 		} else {
 			((chdlc_private_area_t *)dev->priv)->route_status =
 				NO_ROUTE;
-                        printk(KERN_INFO "%s: Dynamic route removed: %s\n",
-                                        card->devname, in_ntoa(local_IP_addr)); 
+                        printk(KERN_INFO "%s: Dynamic route removed: %u.%u.%u.%u\n",
+                                        card->devname, NIPQUAD(local_IP_addr)); 
 			chdlc_priv_area->route_removed = 1;
 		}
 		break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/sdla_fr.c linux/drivers/net/wan/sdla_fr.c
--- linux.orig/drivers/net/wan/sdla_fr.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/net/wan/sdla_fr.c	2002-07-20 01:08:40.000000000 +0000
@@ -152,7 +152,6 @@
 #include <asm/io.h>		/* for inb(), outb(), etc. */
 #include <linux/time.h>	 	/* for do_gettimeofday */	
 #include <linux/in.h>		/* sockaddr_in */
-#include <linux/inet.h>		/* in_ntoa(), etc... */
 #include <asm/errno.h>
 
 #include <linux/ip.h>
@@ -2809,16 +2808,15 @@
 		set_fs(fs);           /* restore old block */
 
 		if (err) {
-
 			printk(KERN_INFO 
 				"%s: Route Add failed.  Error: %d\n", 
 					card->devname,err);
-			printk(KERN_INFO "%s: Address: %s\n",
-				chan->name, in_ntoa(chan->ip_remote));
+			printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
+				chan->name, NIPQUAD(chan->ip_remote));
 
 		}else {
-			printk(KERN_INFO "%s: Route Added Successfully: %s\n",
-				card->devname,in_ntoa(chan->ip_remote));
+			printk(KERN_INFO "%s: Route Added Successfully: %u.%u.%u.%u\n",
+				card->devname,NIPQUAD(chan->ip_remote));
 			chan->route_flag = ROUTE_ADDED;
 		}
 		break;
@@ -2841,17 +2839,15 @@
 		set_fs(fs);    
 		
 		if (err) {
-
 			printk(KERN_INFO 
 				"%s: Deleting of route failed.  Error: %d\n", 
 					card->devname,err);
-			printk(KERN_INFO "%s: Address: %s\n",
-				dev->name,in_ntoa(chan->ip_remote) );
+			printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
+				dev->name,NIPQUAD(chan->ip_remote) );
 
 		} else {
-
-			printk(KERN_INFO "%s: Route Removed Sucessfuly: %s\n", 
-				card->devname,in_ntoa(ip_tmp));
+			printk(KERN_INFO "%s: Route Removed Sucessfuly: %u.%u.%u.%u\n", 
+				card->devname,NIPQUAD(ip_tmp));
 			chan->route_flag = NO_ROUTE;
 		}
 		break;
@@ -2887,8 +2883,8 @@
 		if (err) {
 			printk(KERN_INFO "%s: Adding of route failed.  Error: %d\n", 
 						card->devname,err);
-			printk(KERN_INFO "%s: Address: %s\n",
-				chan->name, in_ntoa(dev->pa_dstaddr) );
+			printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
+				chan->name, NIPQUAD(dev->pa_dstaddr) );
 			}
 		else {
 			chan->route_flag = ROUTE_ADDED;
@@ -2902,11 +2898,10 @@
 		set_fs(fs);           /* restore old block */
 
 		if (err) {
-
 		     printk(KERN_INFO "%s: Deleting of route failed.  Error: %d\n", 
 				card->devname,err);
-		     printk(KERN_INFO "%s: Address: %s\n",
-				dev->name,in_ntoa(dev->pa_dstaddr) );
+		     printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
+				dev->name,NIPQUAD(dev->pa_dstaddr) );
 		} else {
 
 		     printk(KERN_INFO "%s: Removed route.\n",
@@ -4337,8 +4332,8 @@
 	case 0x08:  // Inverse ARP request  -- Send Reply, add route.
 			
 		/* Check for valid Address */
-		printk(KERN_INFO "%s: Recvd PtP addr -InArp Req: %s\n", 
-			card->devname, in_ntoa(arphdr->ar_sip));
+		printk(KERN_INFO "%s: Recvd PtP addr -InArp Req: %u.%u.%u.%u\n", 
+			card->devname, NIPQUAD(arphdr->ar_sip));
 
 
 		/* Check that the network address is the same as ours, only
@@ -4348,15 +4343,14 @@
 		if (in_dev->ifa_list->ifa_mask != 0xFFFFFFFF && 
 		    (in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != 
 		    (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)){
-
 			printk(KERN_INFO 
-				"%s: Invalid PtP address. %s  InARP ignored.\n", 
-					card->devname,in_ntoa(arphdr->ar_sip));
+				"%s: Invalid PtP address. %u.%u.%u.%u  InARP ignored.\n", 
+					card->devname,NIPQUAD(arphdr->ar_sip));
 
-			printk(KERN_INFO "%s: mask %s\n", 
-				card->devname, in_ntoa(in_dev->ifa_list->ifa_mask));
-				printk(KERN_INFO "%s: local %s\n", 
-				card->devname,in_ntoa(in_dev->ifa_list->ifa_local));
+			printk(KERN_INFO "%s: mask %u.%u.%u.%u\n", 
+				card->devname, NIPQUAD(in_dev->ifa_list->ifa_mask));
+				printk(KERN_INFO "%s: local %u.%u.%u.%u\n", 
+				card->devname,NIPQUAD(in_dev->ifa_list->ifa_local));
 			return -1;
 		}
 
@@ -4401,8 +4395,8 @@
 	case 0x09:  // Inverse ARP reply
 
 		/* Check for valid Address */
-		printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Reply\n", 
-				card->devname, in_ntoa(arphdr->ar_sip));
+		printk(KERN_INFO "%s: Recvd PtP addr %u.%u.%u.%u -InArp Reply\n", 
+				card->devname, NIPQUAD(arphdr->ar_sip));
 
 
 		/* Compare network addresses, only if network mask
@@ -4450,8 +4444,8 @@
                 case 0x08:  // Inverse ARP request  -- Send Reply, add route.
 
                         /* Check for valid Address */
-                        printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Req\n", 
-				((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip));
+                        printk(KERN_INFO "%s: Recvd PtP addr %u.%u.%u.%u -InArp Req\n", 
+				((fr_channel_t *)dev->priv)->name, NIPQUAD(arphdr->ar_sip));
 
 
 			if (dev->pa_mask != 0xFFFFFFFF){
@@ -4492,8 +4486,8 @@
                 case 0x09:  // Inverse ARP reply
 
                         /* Check for valid Address */
-                        printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Reply\n", 
-				((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip));
+                        printk(KERN_INFO "%s: Recvd PtP addr %u.%u.%u.%u -InArp Reply\n", 
+				((fr_channel_t *)dev->priv)->name, NIPQUAD(arphdr->ar_sip));
 
                         if ((dev->pa_mask & arphdr->ar_sip) != (dev->pa_mask & dev->pa_addr)) {
                                 printk(KERN_INFO "%s: Invalid PtP address.  InARP ignored.\n", 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/sdla_ppp.c linux/drivers/net/wan/sdla_ppp.c
--- linux.orig/drivers/net/wan/sdla_ppp.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wan/sdla_ppp.c	2002-07-20 01:08:28.000000000 +0000
@@ -102,7 +102,6 @@
 #include <linux/if_arp.h>	/* ARPHRD_* defines */
 #include <asm/byteorder.h>	/* htons(), etc. */
 #include <linux/in.h>		/* sockaddr_in */
-#include <linux/inet.h>		/* in_aton(), in_ntoa() prototypes */
 
 
 /* ---- 2.4.X KERNEL SUPPORT -----------------------*/
@@ -2269,10 +2268,11 @@
 			struct in_device *in_dev = dev->ip_ptr;
 			if (in_dev != NULL ) {
 				struct in_ifaddr *ifa = in_dev->ifa_list;
-				printk(KERN_INFO "%s: Assigned Lcl. Addr: %s\n", 
-					card->devname, in_ntoa(ifa->ifa_local));
-				printk(KERN_INFO "%s: Assigned Rmt. Addr: %s\n", 
-						card->devname, in_ntoa(ifa->ifa_address));
+
+				printk(KERN_INFO "%s: Assigned Lcl. Addr: %u.%u.%u.%u\n", 
+					card->devname, NIPQUAD(ifa->ifa_local));
+				printk(KERN_INFO "%s: Assigned Rmt. Addr: %u.%u.%u.%u\n", 
+						card->devname, NIPQUAD(ifa->ifa_address));
 			}else{
 				printk(KERN_INFO 
 				"%s: Error: Failed to add a route for PPP interface %s\n",
@@ -2294,10 +2294,10 @@
 				"%s: An error occurred in IP assignment.\n", 
 				card->devname);
 		} else {
-			printk(KERN_INFO "%s: Assigned Lcl. Addr: %s\n", 
-					card->devname, in_ntoa(dev->pa_addr));
-			printk(KERN_INFO "%s: Assigned Rmt. Addr: %s\n", 
-					card->devname, in_ntoa(dev->pa_dstaddr));
+			printk(KERN_INFO "%s: Assigned Lcl. Addr: %u.%u.%u.%u\n", 
+					card->devname, NIPQUAD(dev->pa_addr));
+			printk(KERN_INFO "%s: Assigned Rmt. Addr: %u.%u.%u.%U\n", 
+					card->devname, NIPQUAD(dev->pa_dstaddr));
 		}
 	}
 
@@ -2408,16 +2408,8 @@
 			/* Debugging code used to check that IP addresses
                          * obtained from the kernel are correct */
 
-			{
-			char laddr[20];
-			char raddr[20];
-			strcpy(laddr,in_ntoa(cfg.ip_local));
-			strcpy(raddr,in_ntoa(cfg.ip_remote));
-
-                        NEX_PRINTK(KERN_INFO "Local %s Remote %s Name %s\n",
-					laddr,raddr, dev->name);
-			
-			}	
+                        NEX_PRINTK(KERN_INFO "Local %u.%u.%u.%u Remote %u.%u.%u.%u Name %s\n",
+					NIPQUAD(ip_local),NIPQUAD(ip_remote), dev->name);
 			break;
 
 		case WANOPT_PPP_HOST:
@@ -2436,18 +2428,9 @@
 
 			/* Debugging code used to check that IP addresses
                          * obtained from the kernel are correct */
-			{
-			char laddr[20];
-			char raddr[20];
-			strcpy(laddr,in_ntoa(cfg.ip_local));
-			strcpy(raddr,in_ntoa(cfg.ip_remote));
-
-                        NEX_PRINTK (KERN_INFO "Local %s Remote %s Name %s\n",
-					laddr,raddr, dev->name);
+                        NEX_PRINTK (KERN_INFO "Local %u.%u.%u.%u Remote %u.%u.%u.%u Name %s\n",
+					NIPQUAD(ip_local),NIPQUAD(ip_remote), dev->name);
 			
-			}	
-
-
 			break;
 	
 		case WANOPT_PPP_PEER:
@@ -3130,10 +3113,10 @@
 	if (err) {
 		printk (KERN_INFO "%s: Adding of route failed: %i\n",
 			card->devname,err);
-		printk (KERN_INFO "%s:	Local : %s\n",
-			card->devname,in_ntoa(ppp_priv_area->ip_local));
-		printk (KERN_INFO "%s:	Remote: %s\n",
-			card->devname,in_ntoa(ppp_priv_area->ip_remote));
+		printk (KERN_INFO "%s:	Local : %u.%u.%u.%u\n",
+			card->devname,NIPQUAD(ppp_priv_area->ip_local));
+		printk (KERN_INFO "%s:	Remote: %u.%u.%u.%u\n",
+			card->devname,NIPQUAD(ppp_priv_area->ip_remote));
 	}
 	return err;
 }
@@ -3212,8 +3195,8 @@
 			 card->devname, err);
 		return;
 	}else{
-		printk (KERN_INFO "%s: PPP Deleting dynamic route %s successfuly\n",
-			card->devname, in_ntoa(ip_addr));
+		printk (KERN_INFO "%s: PPP Deleting dynamic route %u.%u.%u.%u successfuly\n",
+			card->devname, NIPQUAD(ip_addr));
 	}
 	return;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/sdla_x25.c linux/drivers/net/wan/sdla_x25.c
--- linux.orig/drivers/net/wan/sdla_x25.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/net/wan/sdla_x25.c	2002-07-20 01:08:26.000000000 +0000
@@ -1272,7 +1272,7 @@
 			add_timer(&card->u.x.x25_timer);
 		}
 	}
-	/* Device is not up untill the we are in connected state */
+	/* Device is not up until the we are in connected state */
 	do_gettimeofday( &tv );
 	chan->router_start_time = tv.tv_sec;
 
@@ -4756,7 +4756,7 @@
  * send_delayed_cmd_result
  *
  *	Wait commands like PLEACE CALL or CLEAR CALL must wait
- *      untill the result arrivers. This function passes
+ *      until the result arrives. This function passes
  *      the result to a waiting sock. 
  *
  *===============================================================*/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wan/sealevel.c linux/drivers/net/wan/sealevel.c
--- linux.orig/drivers/net/wan/sealevel.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/net/wan/sealevel.c	2002-07-20 01:08:38.000000000 +0000
@@ -219,12 +219,11 @@
 	 *	Get the needed I/O space
 	 */
 	 
-	if(check_region(iobase, 8))
+	if(!request_region(iobase, 8, "Sealevel 4021"))
 	{	
 		printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n", iobase);
 		return NULL;
 	}
-	request_region(iobase, 8, "Sealevel 4021");
 	
 	b=(struct slvl_board *)kmalloc(sizeof(struct slvl_board), GFP_KERNEL);
 	if(!b)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wd.c linux/drivers/net/wd.c
--- linux.orig/drivers/net/wd.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/net/wd.c	2002-07-20 01:08:24.000000000 +0000
@@ -97,7 +97,7 @@
 			return -EBUSY;
 		i = wd_probe1(dev, base_addr);
 		if (i != 0)  
-			release_resource(r);
+			release_region(base_addr, WD_IO_EXTENT);
 		else
 			r->name = dev->name;
 		return i;
@@ -114,7 +114,7 @@
 			r->name = dev->name;
 			return 0;
 		}
-		release_resource(r);
+		release_region(ioaddr, WD_IO_EXTENT);
 	}
 
 	return -ENODEV;
@@ -450,10 +450,11 @@
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
 MODULE_PARM(mem_end, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
-MODULE_PARM_DESC(io, "WD80x3 I/O base address(es)");
-MODULE_PARM_DESC(irq, "WD80x3 IRQ number(s) (ignored for PureData boards)");
-MODULE_PARM_DESC(mem, "WD80x3 memory base address(es)(ignored for PureData boards)");
-MODULE_PARM_DESC(mem_end, "WD80x3 memory end address(es)");
+MODULE_PARM_DESC(io, "I/O base address(es)");
+MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)");
+MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)");
+MODULE_PARM_DESC(mem_end, "memory end address(es)");
+MODULE_DESCRIPTION("ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver");
 MODULE_LICENSE("GPL");
 
 /* This is set up so that only a single autoprobe takes place per call.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
--- linux.orig/drivers/net/winbond-840.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/winbond-840.c	2002-07-20 01:08:28.000000000 +0000
@@ -138,6 +138,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/rtnetlink.h>
+#include <linux/crc32.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
@@ -388,7 +389,6 @@
 static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
 static void netdev_error(struct net_device *dev, int intr_status);
 static int  netdev_rx(struct net_device *dev);
-static inline unsigned ether_crc(int length, unsigned char *data);
 static u32 __set_rx_mode(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
@@ -1410,21 +1410,6 @@
 	return &np->stats;
 }
 
-static unsigned const ethernet_polynomial = 0x04c11db7U;
-static inline u32 ether_crc(int length, unsigned char *data)
-{
-    int crc = -1;
-
-    while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
-			crc = (crc << 1) ^
-				((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
-		}
-    }
-    return crc;
-}
 
 static u32 __set_rx_mode(struct net_device *dev)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/Config.in linux/drivers/net/wireless/Config.in
--- linux.orig/drivers/net/wireless/Config.in	2001-10-09 22:13:03.000000000 +0000
+++ linux/drivers/net/wireless/Config.in	2002-07-20 01:08:30.000000000 +0000
@@ -14,6 +14,7 @@
 
 if [ "$CONFIG_PCI" = "y" ]; then
    dep_tristate '    Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
+   dep_tristate '    Prism 2.5 PCI 802.11b adaptor support' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
 fi
 
 # If Pcmcia is compiled in, offer Pcmcia cards...
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/Makefile linux/drivers/net/wireless/Makefile
--- linux.orig/drivers/net/wireless/Makefile	2001-10-09 22:13:03.000000000 +0000
+++ linux/drivers/net/wireless/Makefile	2002-07-20 01:08:37.000000000 +0000
@@ -18,6 +18,7 @@
 obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o
 obj-$(CONFIG_APPLE_AIRPORT)	+= airport.o
 obj-$(CONFIG_PLX_HERMES)	+= orinoco_plx.o
+obj-$(CONFIG_PCI_HERMES)	+= orinoco_pci.o
 
 obj-$(CONFIG_AIRO)		+= airo.o
 obj-$(CONFIG_AIRO_CS)		+= airo_cs.o airo.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/airport.c linux/drivers/net/wireless/airport.c
--- linux.orig/drivers/net/wireless/airport.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wireless/airport.c	2002-07-20 01:08:34.000000000 +0000
@@ -1,4 +1,4 @@
-/* airport.c 0.09b
+/* airport.c 0.11b
  *
  * A driver for "Hermes" chipset based Apple Airport wireless
  * card.
@@ -42,19 +42,20 @@
 #include "hermes.h"
 #include "orinoco.h"
 
-static char version[] __initdata = "airport.c 0.09b (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
+static char version[] __initdata = "airport.c 0.11b (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
 MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
 MODULE_LICENSE("Dual MPL/GPL");
 EXPORT_NO_SYMBOLS;
 
+#define AIRPORT_IO_LEN	(0x1000)	/* one page */
+
 struct airport {
 	struct device_node* node;
+	void *vaddr;
 	int irq_requested;
 	int ndev_registered;
 	int open;
-	/* Common structure (fully included), see orinoco.h */
-	struct orinoco_private priv;
 };
 
 #ifdef CONFIG_PMAC_PBOOK
@@ -68,8 +69,8 @@
  * Function prototypes
  */
 
-static struct orinoco_private* airport_attach(struct device_node *of_node);
-static void airport_detach(struct orinoco_private* priv);
+static struct net_device *airport_attach(struct device_node *of_node);
+static void airport_detach(struct net_device *dev);
 static int airport_open(struct net_device *dev);
 static int airport_stop(struct net_device *dev);
 
@@ -83,7 +84,7 @@
    device numbers are used to derive the corresponding array index.
 */
 
-static struct orinoco_private *airport_dev;
+static struct net_device *airport_dev;
 
 static int
 airport_open(struct net_device *dev)
@@ -92,6 +93,8 @@
 	struct airport* card = (struct airport *)priv->card;
 	int rc;
 
+	TRACE_ENTER(dev->name);
+
 	netif_device_attach(dev);
 
 	rc = orinoco_reset(priv);
@@ -102,6 +105,8 @@
 		netif_start_queue(dev);
 	}
 
+	TRACE_EXIT(dev->name);
+
 	return rc;
 }
 
@@ -111,13 +116,13 @@
 	struct orinoco_private *priv = dev->priv;
 	struct airport* card = (struct airport *)priv->card;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(dev->name);
 
 	netif_stop_queue(dev);
 	orinoco_shutdown(priv);
 	card->open = 0;
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(dev->name);
 
 	return 0;
 }
@@ -126,9 +131,9 @@
 static int
 airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
-	struct orinoco_private *priv = airport_dev;
+	struct net_device *dev = airport_dev;
+	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
 	struct hermes *hw = &priv->hw;
-	struct net_device *dev = &priv->ndev;
 	struct airport* card = (struct airport *)priv->card;
 	int rc;
 	
@@ -167,12 +172,13 @@
 }
 #endif /* CONFIG_PMAC_PBOOK */
 
-static struct orinoco_private*
+static struct net_device *
 airport_attach(struct device_node* of_node)
 {
 	struct orinoco_private *priv;
-	struct net_device *ndev;
-	struct airport* card;
+	struct net_device *dev;
+	struct airport *card;
+	unsigned long phys_addr;
 	hermes_t *hw;
 
 	TRACE_ENTER("orinoco");
@@ -183,45 +189,42 @@
 	}
 
 	/* Allocate space for private device-specific data */
-	card = kmalloc(sizeof(*card), GFP_KERNEL);
-	if (!card) {
+	dev = alloc_orinocodev(sizeof(*card));
+	if (! dev) {
 		printk(KERN_ERR "airport: can't allocate device datas\n");
 		return NULL;
 	}
-	memset(card, 0, sizeof(*card));
+	priv = dev->priv;
+	card = priv->card;
 
-	priv = &(card->priv);
-	priv->card = card;
-	ndev = &priv->ndev;
 	hw = &priv->hw;
 	card->node = of_node;
 
-	if (!request_OF_resource(of_node, 0, " (airport)")) {
+	if (! request_OF_resource(of_node, 0, " (airport)")) {
 		printk(KERN_ERR "airport: can't request IO resource !\n");
-		kfree(card);
+		kfree(dev);
 		return NULL;
 	}
 	
-	/* Setup the common part */
-	if (orinoco_setup(priv) < 0) {
-		release_OF_resource(of_node, 0);
-		kfree(card);
-		return NULL;
-	}
-
-
-	ndev->name[0] = '\0';	/* register_netdev will give us an ethX name */
-	SET_MODULE_OWNER(ndev);
+	dev->name[0] = '\0';	/* register_netdev will give us an ethX name */
+	SET_MODULE_OWNER(dev);
 
 	/* Overrides */
-	ndev->open = airport_open;
-	ndev->stop = airport_stop;
+	dev->open = airport_open;
+	dev->stop = airport_stop;
 
 	/* Setup interrupts & base address */
-	ndev->irq = of_node->intrs[0].line;
-	ndev->base_addr = (unsigned long)ioremap(of_node->addrs[0].address, 0x1000) - _IO_BASE;
+	dev->irq = of_node->intrs[0].line;
+	phys_addr = of_node->addrs[0].address; /* Physical address */
+	dev->base_addr = phys_addr;
+	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
+	if (! card->vaddr) {
+		printk("airport: ioremap() failed\n");
+		goto failed;
+	}
 
-	hermes_struct_init(hw, ndev->base_addr);
+	hermes_struct_init(hw, (ulong)card->vaddr,
+			HERMES_MEM, HERMES_16BIT_REGSPACING);
 		
 	/* Power up card */
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1);
@@ -231,32 +234,32 @@
 	/* Reset it before we get the interrupt */
 	hermes_reset(hw);
 
-	if (request_irq(ndev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
-		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", ndev->irq);
+	if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
+		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq);
 		goto failed;
 	}
 	card->irq_requested = 1;
 	
 	/* Tell the stack we exist */
-	if (register_netdev(ndev) != 0) {
+	if (register_netdev(dev) != 0) {
 		printk(KERN_ERR "airport: register_netdev() failed\n");
 		goto failed;
 	}
-	printk(KERN_DEBUG "airport: card registered for interface %s\n", ndev->name);
+	printk(KERN_DEBUG "airport: card registered for interface %s\n", dev->name);
 	card->ndev_registered = 1;
 
 	/* And give us the proc nodes for debugging */
 	if (orinoco_proc_dev_init(priv) != 0)
 		printk(KERN_ERR "airport: Failed to create /proc node for %s\n",
-		       ndev->name);
+		       dev->name);
 
 #ifdef CONFIG_PMAC_PBOOK
 	pmu_register_sleep_notifier(&airport_sleep_notifier);
 #endif
-	return priv;
+	return dev;
 	
 failed:
-	airport_detach(priv);
+	airport_detach(dev);
 	return NULL;
 }				/* airport_attach */
 
@@ -265,9 +268,10 @@
   ======================================================================*/
 
 static void
-airport_detach(struct orinoco_private *priv)
+airport_detach(struct net_device *dev)
 {
-	struct airport* card = (struct airport *)priv->card;
+	struct orinoco_private *priv = dev->priv;
+	struct airport *card = priv->card;
 
 	/* Unregister proc entry */
 	orinoco_proc_dev_cleanup(priv);
@@ -276,16 +280,18 @@
 	pmu_unregister_sleep_notifier(&airport_sleep_notifier);
 #endif
 	if (card->ndev_registered)
-		unregister_netdev(&priv->ndev);
+		unregister_netdev(dev);
 	card->ndev_registered = 0;
 	
 	if (card->irq_requested)
-		free_irq(priv->ndev.irq, priv);
+		free_irq(dev->irq, priv);
 	card->irq_requested = 0;
 
-	if (priv->ndev.base_addr)
-		iounmap((void *)(priv->ndev.base_addr + (unsigned long)_IO_BASE));
-	priv->ndev.base_addr = 0;
+	if (card->vaddr)
+		iounmap(card->vaddr);
+	card->vaddr = 0;
+	
+	dev->base_addr = 0;
 
 	release_OF_resource(card->node, 0);
 	
@@ -293,7 +299,7 @@
 	current->state = TASK_UNINTERRUPTIBLE;
 	schedule_timeout(HZ);
 	
-	kfree(card);
+	kfree(dev);
 }				/* airport_detach */
 
 static int __init
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/hermes.c linux/drivers/net/wireless/hermes.c
--- linux.orig/drivers/net/wireless/hermes.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wireless/hermes.c	2002-07-20 01:08:27.000000000 +0000
@@ -53,7 +53,7 @@
 
 #include "hermes.h"
 
-static char version[] __initdata = "hermes.c: 16 Jan 2002 David Gibson <hermes@gibson.dropbear.id.au>";
+static char version[] __initdata = "hermes.c: 5 Apr 2002 David Gibson <hermes@gibson.dropbear.id.au>";
 MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 #ifdef MODULE_LICENSE
@@ -65,7 +65,6 @@
 #define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
 #define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
 #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
-#define BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
 
 /*
  * Debugging helpers
@@ -87,6 +86,8 @@
 
 #endif /* ! HERMES_DEBUG */
 
+#define IO_TYPE(hw)	((hw)->io_space ? "IO " : "MEM ")
+
 /*
  * Internal functions
  */
@@ -127,10 +128,19 @@
  * Function definitions
  */
 
-void hermes_struct_init(hermes_t *hw, uint io)
+void hermes_struct_init(hermes_t *hw, ulong address,
+			int io_space, int reg_spacing)
 {
-	hw->iobase = io;
+	hw->iobase = address;
+	hw->io_space = io_space;
+	hw->reg_spacing = reg_spacing;
 	hw->inten = 0x0;
+
+#ifdef HERMES_DEBUG_BUFFER
+	hw->dbufp = 0;
+	memset(&hw->dbuf, 0xff, sizeof(hw->dbuf));
+	memset(&hw->profile, 0, sizeof(hw->profile));
+#endif
 }
 
 int hermes_reset(hermes_t *hw)
@@ -197,8 +207,9 @@
 	}
 		
 	if (! (reg & HERMES_EV_CMD)) {
-		printk(KERN_ERR "hermes @ 0x%x: Timeout waiting for card to reset (reg=0x%04x)!\n",
-		       hw->iobase, reg);
+		printk(KERN_ERR "hermes @ %s0x%lx: " 
+		       "Timeout waiting for card to reset (reg=0x%04x)!\n",
+		       IO_TYPE(hw), hw->iobase, reg);
 		err = -ETIMEDOUT;
 		goto out;
 	}
@@ -207,7 +218,8 @@
 
 	hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
 
-	err = status & HERMES_STATUS_RESULT;
+	if (status & HERMES_STATUS_RESULT)
+		err = -EIO;
 
  out:
 	return err;
@@ -224,16 +236,18 @@
 	int err;
 	int k;
 	u16 reg;
+	u16 status;
 
 	err = hermes_issue_cmd(hw, cmd, parm0);
 	if (err) {
 		if (! hermes_present(hw)) {
-			printk(KERN_WARNING "hermes @ 0x%x: Card removed while issuing command.\n",
-			       hw->iobase);
+			printk(KERN_WARNING "hermes @ %s0x%lx: "
+			       "Card removed while issuing command.\n",
+			       IO_TYPE(hw), hw->iobase);
 			err = -ENODEV;
 		} else 
-			printk(KERN_ERR "hermes @ 0x%x: Error %d issuing command.\n",
-			       hw->iobase, err);
+			printk(KERN_ERR "hermes @ %s0x%lx: Error %d issuing command.\n",
+			       IO_TYPE(hw), hw->iobase, err);
 		goto out;
 	}
 
@@ -246,27 +260,33 @@
 	}
 
 	if (! hermes_present(hw)) {
-		printk(KERN_WARNING "hermes @ 0x%x: Card removed while waiting for command completion.\n",
-		       hw->iobase);
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "Card removed while waiting for command completion.\n",
+		       IO_TYPE(hw), hw->iobase);
 		err = -ENODEV;
 		goto out;
 	}
 		
 	if (! (reg & HERMES_EV_CMD)) {
-		printk(KERN_ERR "hermes @ 0x%x: Timeout waiting for command completion.\n",
-		       hw->iobase);
+		printk(KERN_ERR "hermes @ %s0x%lx: "
+		       "Timeout waiting for command completion.\n",
+		       IO_TYPE(hw), hw->iobase);
 		err = -ETIMEDOUT;
 		goto out;
 	}
 
-	resp->status = hermes_read_regn(hw, STATUS);
-	resp->resp0 = hermes_read_regn(hw, RESP0);
-	resp->resp1 = hermes_read_regn(hw, RESP1);
-	resp->resp2 = hermes_read_regn(hw, RESP2);
+	status = hermes_read_regn(hw, STATUS);
+	if (resp) {
+		resp->status = status;
+		resp->resp0 = hermes_read_regn(hw, RESP0);
+		resp->resp1 = hermes_read_regn(hw, RESP1);
+		resp->resp2 = hermes_read_regn(hw, RESP2);
+	}
 
 	hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
 
-	err = resp->status & HERMES_STATUS_RESULT;
+	if (status & HERMES_STATUS_RESULT)
+		err = -EIO;
 
  out:
 	return err;
@@ -275,17 +295,17 @@
 int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
 {
 	int err = 0;
-	hermes_response_t resp;
 	int k;
 	u16 reg;
 	
 	if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
 		return -EINVAL;
 
-	err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, &resp);
+	err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
 	if (err) {
-		printk(KERN_WARNING "hermes @ 0x%x: Frame allocation command failed (0x%X).\n",
-		       hw->iobase, err);
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "Frame allocation command failed (0x%X).\n",
+		       IO_TYPE(hw), hw->iobase, err);
 		return err;
 	}
 
@@ -298,14 +318,16 @@
 	}
 	
 	if (! hermes_present(hw)) {
-		printk(KERN_WARNING "hermes @ 0x%x: Card removed waiting for frame allocation.\n",
-		       hw->iobase);
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "Card removed waiting for frame allocation.\n",
+		       IO_TYPE(hw), hw->iobase);
 		return -ENODEV;
 	}
 		
 	if (! (reg & HERMES_EV_ALLOC)) {
-		printk(KERN_ERR "hermes @ 0x%x: Timeout waiting for frame allocation\n",
-		       hw->iobase);
+		printk(KERN_ERR "hermes @ %s0x%lx: "
+		       "Timeout waiting for frame allocation\n",
+		       IO_TYPE(hw), hw->iobase);
 		return -ETIMEDOUT;
 	}
 
@@ -315,13 +337,14 @@
 	return 0;
 }
 
+
 /* Set up a BAP to read a particular chunk of data from card's internal buffer.
  *
  * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
  * from firmware
  *
  * Callable from any context */
-int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
+static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
 {
 	int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
 	int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
@@ -332,7 +355,7 @@
 	if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
 		return -EINVAL;
 
-	k = BAP_BUSY_TIMEOUT;
+	k = HERMES_BAP_BUSY_TIMEOUT;
 	reg = hermes_read_reg(hw, oreg);
 	while ((reg & HERMES_OFFSET_BUSY) && k) {
 		k--;
@@ -340,6 +363,19 @@
 		reg = hermes_read_reg(hw, oreg);
 	}
 
+#ifdef HERMES_DEBUG_BUFFER
+	hw->profile[HERMES_BAP_BUSY_TIMEOUT - k]++;
+
+	if (k < HERMES_BAP_BUSY_TIMEOUT) {
+		struct hermes_debug_entry *e = 
+			&hw->dbuf[(hw->dbufp++) % HERMES_DEBUG_BUFSIZE];
+		e->bap = bap;
+		e->id = id;
+		e->offset = offset;
+		e->cycles = HERMES_BAP_BUSY_TIMEOUT - k;
+	}
+#endif
+
 	if (reg & HERMES_OFFSET_BUSY)
 		return -ETIMEDOUT;
 
@@ -348,7 +384,7 @@
 	hermes_write_reg(hw, oreg, offset);
 
 	/* Wait for the BAP to be ready */
-	k = BAP_BUSY_TIMEOUT;
+	k = HERMES_BAP_BUSY_TIMEOUT;
 	reg = hermes_read_reg(hw, oreg);
 	while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
 		k--;
@@ -382,7 +418,7 @@
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
 
-	if (len % 2)
+	if ( (len < 0) || (len % 2) )
 		return -EINVAL;
 
 	err = hermes_bap_seek(hw, bap, id, offset);
@@ -408,7 +444,7 @@
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
 
-	if (len % 2)
+	if ( (len < 0) || (len % 2) )
 		return -EINVAL;
 
 	err = hermes_bap_seek(hw, bap, id, offset);
@@ -436,12 +472,11 @@
 	int err = 0;
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	u16 rlength, rtype;
-	hermes_response_t resp;
 
-	if (bufsize % 2)
+	if ( (bufsize < 0) || (bufsize % 2) )
 		return -EINVAL;
 
-	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, &resp);
+	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
 	if (err)
 		goto out;
 
@@ -456,11 +491,14 @@
 		*length = rlength;
 
 	if (rtype != rid)
-		printk(KERN_WARNING "hermes_read_ltv(): rid  (0x%04x) does "
-		       "not match type (0x%04x)\n", rid, rtype);
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "hermes_read_ltv(): rid  (0x%04x) does not match type (0x%04x)\n",
+		       IO_TYPE(hw), hw->iobase, rid, rtype);
 	if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
-		printk(KERN_WARNING "hermes @ 0x%x: Truncating LTV record from %d to %d bytes. "
-		       "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "Truncating LTV record from %d to %d bytes. "
+		       "(rid=0x%04x, len=0x%04x)\n",
+		       IO_TYPE(hw), hw->iobase,
 		       HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
 	
 	/* FIXME: we should read the min of the requested length and
@@ -476,7 +514,6 @@
 {
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
-	hermes_response_t resp;
 	int count;
 	
 	DEBUG(3, "write_ltv(): bap=%d rid=0x%04x length=%d (value=0x%04x)\n",
@@ -494,7 +531,7 @@
 	hermes_write_words(hw, dreg, value, count);
 
 	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, 
-				rid, &resp);
+				rid, NULL);
 
  out:
 	return err;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/hermes.h linux/drivers/net/wireless/hermes.h
--- linux.orig/drivers/net/wireless/hermes.h	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wireless/hermes.h	2002-07-20 01:08:24.000000000 +0000
@@ -48,7 +48,6 @@
 #define		HERMES_PDA_LEN_MAX		(1024)	/* in bytes, from EK */
 #define		HERMES_SCANRESULT_MAX		(35)
 #define		HERMES_CHINFORESULT_MAX		(8)
-#define		HERMES_FRAME_LEN_MAX		(2304)
 #define		HERMES_MAX_MULTICAST		(16)
 #define		HERMES_MAGIC			(0x7d1f)
 
@@ -251,13 +250,36 @@
 	struct hermes_scan_apinfo aps[35];        /* Scan result */
 } __attribute__ ((packed));
 
+// #define HERMES_DEBUG_BUFFER 1
+#define HERMES_DEBUG_BUFSIZE 4096
+struct hermes_debug_entry {
+	int bap;
+	u16 id, offset;
+	int cycles;
+};
+
 #ifdef __KERNEL__
 
+/* Timeouts */
+#define HERMES_BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
+
 /* Basic control structure */
 typedef struct hermes {
-	uint iobase;
+	ulong iobase;
+	int io_space; /* 1 if we IO-mapped IO, 0 for memory-mapped IO? */
+#define HERMES_IO	1
+#define HERMES_MEM	0
+	int reg_spacing;
+#define HERMES_16BIT_REGSPACING	0
+#define HERMES_32BIT_REGSPACING	1
 
 	u16 inten; /* Which interrupts should be enabled? */
+
+#ifdef HERMES_DEBUG_BUFFER
+	struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
+	unsigned long dbufp;
+	unsigned long profile[HERMES_BAP_BUSY_TIMEOUT+1];
+#endif
 } hermes_t;
 
 typedef struct hermes_response {
@@ -265,19 +287,22 @@
 } hermes_response_t;
 
 /* Register access convenience macros */
-#define hermes_read_reg(hw, off) (inw((hw)->iobase + (off)))
-#define hermes_write_reg(hw, off, val) (outw_p((val), (hw)->iobase + (off)))
+#define hermes_read_reg(hw, off) ((hw)->io_space ? \
+	inw((hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
+	readw((hw)->iobase + ( (off) << (hw)->reg_spacing )))
+#define hermes_write_reg(hw, off, val) ((hw)->io_space ? \
+	outw_p((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
+	writew((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )))
 
 #define hermes_read_regn(hw, name) (hermes_read_reg((hw), HERMES_##name))
 #define hermes_write_regn(hw, name, val) (hermes_write_reg((hw), HERMES_##name, (val)))
 
 /* Function prototypes */
-void hermes_struct_init(hermes_t *hw, uint io);
+void hermes_struct_init(hermes_t *hw, ulong address, int io_space, int reg_spacing);
 int hermes_reset(hermes_t *hw);
 int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp);
 int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
 
-int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset);
 int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
 		       u16 id, u16 offset);
 int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
@@ -308,35 +333,62 @@
 
 static inline int hermes_enable_port(hermes_t *hw, int port)
 {
-	hermes_response_t resp;
-
 	return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
-				 0, &resp);
+				 0, NULL);
 }
 
 static inline int hermes_disable_port(hermes_t *hw, int port)
 {
-	hermes_response_t resp;
-
 	return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 
-				 0, &resp);
+				 0, NULL);
 }
 
 /* Initiate an INQUIRE command (tallies or scan).  The result will come as an
- * information frame in __dldwd_ev_info() */
+ * information frame in __orinoco_ev_info() */
 static inline int hermes_inquire(hermes_t *hw, u16 rid)
 {
-	hermes_response_t resp;
-
-	return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, &resp);
+	return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
 }
 
 #define HERMES_BYTES_TO_RECLEN(n) ( ((n) % 2) ? (((n)+1)/2)+1 : ((n)/2)+1 )
 #define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
 
 /* Note that for the next two, the count is in 16-bit words, not bytes */
-#define hermes_read_words(hw, off, buf, count) (insw((hw)->iobase + (off), (buf), (count)))
-#define hermes_write_words(hw, off, buf, count) (outsw((hw)->iobase + (off), (buf), (count)))
+static inline void hermes_read_words(struct hermes *hw, int off, void *buf, int count)
+{
+	off = off << hw->reg_spacing;;
+
+	if (hw->io_space) {
+		insw(hw->iobase + off, buf, count);
+	} else {
+		int i;
+		u16 *p;
+
+		/* This need to *not* byteswap (like insw()) but
+		 * readw() does byteswap hence the conversion */
+		for (i = 0, p = buf; i < count; i++) {
+			*p++ = cpu_to_le16(readw(hw->iobase + off));
+		}
+	}
+}
+
+static inline void hermes_write_words(struct hermes *hw, int off, const void *buf, int count)
+{
+	off = off << hw->reg_spacing;;
+
+	if (hw->io_space) {
+		outsw(hw->iobase + off, buf, count);
+	} else {
+		int i;
+		const u16 *p;
+
+		/* This need to *not* byteswap (like outsw()) but
+		 * writew() does byteswap hence the conversion */
+		for (i = 0, p = buf; i < count; i++) {
+			writew(le16_to_cpu(*p++), hw->iobase + off);
+		}
+	}
+}
 
 #define HERMES_READ_RECORD(hw, bap, rid, buf) \
 	(hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/ieee802_11.h linux/drivers/net/wireless/ieee802_11.h
--- linux.orig/drivers/net/wireless/ieee802_11.h	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wireless/ieee802_11.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,6 +1,13 @@
 #ifndef _IEEE802_11_H
 #define _IEEE802_11_H
 
+#define IEEE802_11_DATA_LEN		2304
+/* Actually, the standard seems to be inconsistent about what the
+   maximum frame size really is.  S6.2.1.1.2 says 2304 octets, but the
+   figure in section 7.1.2 says 2312 octects. */
+#define IEEE802_11_HLEN			30
+#define IEEE802_11_FRAME_LEN		(IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
+
 struct ieee802_11_hdr {
 	u16 frame_ctl;
 	u16 duration_id;
@@ -9,7 +16,6 @@
 	u8 addr3[ETH_ALEN];
 	u16 seq_ctl;
 	u8 addr4[ETH_ALEN];
-	u16 data_len;
 } __attribute__ ((packed));
 
 /* Frame control field constants */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/orinoco.c linux/drivers/net/wireless/orinoco.c
--- linux.orig/drivers/net/wireless/orinoco.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wireless/orinoco.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,11 +1,7 @@
-/* orinoco.c 0.09b	- (formerly known as dldwd_cs.c and orinoco_cs.c)
+/* orinoco.c 0.11b	- (formerly known as dldwd_cs.c and orinoco_cs.c)
  *
- * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
- * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
- * EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and others).
- * It should also be usable on various Prism II based cards such as the
- * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
- * cards such as the 3Com AirConnect and Ericsson WLAN.
+ * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
+ * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
  *
  * Copyright (C) 2000 David Gibson, Linuxcare Australia <hermes@gibson.dropbear.id.au>
  *	With some help from :
@@ -41,12 +37,9 @@
  * deleting the provisions above and replace them with the notice and
  * other provisions required by the GPL.  If you do not delete the
  * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
+ * under either the MPL or the GPL.  */
 
 /*
- * Tentative changelog...
- *
  * v0.01 -> v0.02 - 21/3/2001 - Jean II
  *	o Allow to use regular ethX device name instead of dldwdX
  *	o Warning on IBSS with ESSID=any for firmware 6.06
@@ -229,7 +222,7 @@
  * v0.09a -> v0.09b - 16/1/2002 - David Gibson
  *	o Fixed even stupider mistake in new interrupt handling, which
  *	  seriously broke things on big-endian machines.
- *	o Removed a bunch of redundand includes and exports.
+ *	o Removed a bunch of redundant includes and exports.
  *	o Removed a redundant MOD_{INC,DEC}_USE_COUNT pair in airport.c
  *	o Don't attempt to do hardware level multicast reception on
  *	  Intersil firmware, just go promisc instead.
@@ -239,24 +232,69 @@
  *	o Moved netif_wake_queue() from ALLOC interrupts to TX and TXEXC
  *	  interrupts, which should fix the timeouts we're seeing.
  *
+ * v0.09b -> v0.10 - 25 Feb 2002 - David Gibson
+ *	o Removed nested structures used for header parsing, so the
+ *	  driver should now work without hackery on ARM
+ *	o Fix for WEP handling on Intersil (Hawk Newton)
+ *	o Eliminated the /proc/hermes/ethXX/regs debugging file.  It
+ *	  was never very useful.
+ *	o Make Rx errors less noisy.
+ *
+ * v0.10 -> v0.11 - 5 Apr Mar 2002 - David Gibson
+ *	o Laid the groundwork in hermes.[ch] for devices which map
+ *	  into PCI memory space rather than IO space.
+ *	o Fixed bug in multicast handling (cleared multicast list when
+ *	  leaving promiscuous mode).
+ *	o Relegated Tx error messages to debug.
+ *	o Cleaned up / corrected handling of allocation lengths.
+ *	o Set OWNSSID in IBSS mode for WinXP interoperability (jimc).
+ *	o Change to using alloc_etherdev() for structure allocations. 
+ *	o Check for and drop undersized packets.
+ *	o Fixed a race in stopping/waking the queue.  This should fix
+ *	  the timeout problems (Pavel Roskin)
+ *	o Reverted to netif_wake_queue() on the ALLOC event.
+ *	o Fixes for recent Symbol firmwares which lack AP density
+ *	  (Pavel Roskin).
+ *
+ * v0.11 -> v0.11b - 29 Apr 2002 - David Gibson
+ *	o Handle different register spacing, necessary for Prism 2.5
+ *	  PCI adaptors (Steve Hill).
+ *	o Cleaned up initialization of card structures in orinoco_cs
+ *	  and airport.  Removed card->priv field.
+ *	o Make response structure optional for hermes_docmd_wait()
+ *	  Pavel Roskin)
+ *	o Added PCI id for Nortel emobility to orinoco_plx.c.
+ *	o Cleanup to handling of Symbol's allocation bug. (Pavel Roskin)
+ *	o Cleanups to firmware capability detection.
+ *	o Arrange for orinoco_pci.c to override firmware detection.
+ *	  We should be able to support the PCI Intersil cards now.
+ *	o Cleanup handling of reset_cor and hard_reset (Pavel Roskin).
+ *	o Remove erroneous use of USER_BAP in the TxExc handler (Jouni
+ *	  Malinen).
+ *	o Makefile changes for better integration into David Hinds
+ *	  pcmcia-cs package.
+ *
+ * v0.11a -> v0.11b - 1 May 2002 - David Gibson
+ *	o Better error reporting in orinoco_plx_init_one()
+ *	o Fixed multiple bad kfree() bugs introduced by the
+ *	  alloc_orinocodev() changes.
+ *
  * TODO
- *	o Find and kill remaining Tx timeout problems
- *	o Fix WEP / order of iwconfig wierdness on Intersil firmware
- *	o Convert /proc debugging stuff to seqfile
- *	o Re-assess our encapsulation detection strategy
- *	o Handle de-encapsulation within NET framework, provide 802.11
+ *	o New wireless extensions API
+ *	o Handle de-encapsulation within network layer, provide 802.11
  *	  headers
  *	o Fix possible races in SPY handling.
- *	o Take the xmit lock when calling orinoco_reset from an
- *	  ioctl(), because that protects the multicast list.
- *	o Fix allocation lengths.
+ *	o Disconnect wireless extensions from fundamental configuration.
+ *
+ *	o Convert /proc debugging stuff to seqfile
+ *	o Use multiple Tx buffers
  */
 /* Notes on locking:
  *
  * The basic principle of operation is that everything except the
  * interrupt handler is serialized through a single spinlock in the
- * struct orinoco_private structure, using dldwd_lock() and
- * dldwd_unlock() (which in turn use spin_lock_bh() and
+ * struct orinoco_private structure, using orinoco_lock() and
+ * orinoco_unlock() (which in turn use spin_lock_bh() and
  * spin_unlock_bh()).
  *
  * The kernel's IRQ handling stuff ensures that the interrupt handler
@@ -275,7 +313,7 @@
  * running when we actually reset or shut down the card, because
  * strange things might happen (probably the worst would be one packet
  * of garbage, but you can't be too careful). For this we use
- * __dldwd_stop_irqs() which will set a flag to disable the interrupt
+ * __orinoco_stop_irqs() which will set a flag to disable the interrupt
  * handler, and wait for any outstanding instances of the handler to
  * complete. THIS WILL LOSE INTERRUPTS! so it shouldn't be used except
  * for resets, where losing a few interrupts is acceptable. */
@@ -295,6 +333,7 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
@@ -306,7 +345,7 @@
 #include "orinoco.h"
 #include "ieee802_11.h"
 
-/* Wireless extensions backwares compatibility */
+/* Wireless extensions backwards compatibility */
 #ifndef SIOCIWFIRSTPRIV
 #define SIOCIWFIRSTPRIV		SIOCDEVPRIVATE
 #endif /* SIOCIWFIRSTPRIV */
@@ -318,7 +357,7 @@
 #define SPY_NUMBER(priv)	0
 #endif /* WIRELESS_SPY */
 
-static char version[] __initdata = "orinoco.c 0.09b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco.c 0.11b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
 #ifdef MODULE_LICENSE
@@ -329,40 +368,37 @@
 #ifdef ORINOCO_DEBUG
 int orinoco_debug = ORINOCO_DEBUG;
 MODULE_PARM(orinoco_debug, "i");
+EXPORT_SYMBOL(orinoco_debug);
 #endif
 
 #define ORINOCO_MIN_MTU		256
-#define ORINOCO_MAX_MTU		(HERMES_FRAME_LEN_MAX - ENCAPS_OVERHEAD)
+#define ORINOCO_MAX_MTU		(IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
 
 #define SYMBOL_MAX_VER_LEN	(14)
-#define LTV_BUF_SIZE		128
 #define USER_BAP		0
 #define IRQ_BAP			1
-#define ORINOCO_MACPORT		0
 #define MAX_IRQLOOPS_PER_IRQ	10
 #define MAX_IRQLOOPS_PER_JIFFY	(20000/HZ)	/* Based on a guestimate of how many events the
 						   device can legitimately generate */
-#define TX_NICBUF_SIZE		2048
-#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
-#define LARGE_KEY_SIZE		13
 #define SMALL_KEY_SIZE		5
-#define MAX_FRAME_SIZE		2304
+#define LARGE_KEY_SIZE		13
+#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
 
 #define DUMMY_FID		0xFFFF
 
-#define MAX_MULTICAST(priv)	(priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
-				 HERMES_MAX_MULTICAST : 0)
-
-/*
- * Data tables
- */
+/*#define MAX_MULTICAST(priv)	(priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
+  HERMES_MAX_MULTICAST : 0)*/
+#define MAX_MULTICAST(priv)	(HERMES_MAX_MULTICAST)
+
+/********************************************************************/
+/* Data tables                                                      */
+/********************************************************************/
 
 /* The frequency of each channel in MHz */
 const long channel_frequency[] = {
 	2412, 2417, 2422, 2427, 2432, 2437, 2442,
 	2447, 2452, 2457, 2462, 2467, 2472, 2484
 };
-
 #define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )
 
 /* This tables gives the actual meanings of the bitrate IDs returned by the firmware. */
@@ -381,44 +417,26 @@
 	{55, 1,  7,  7},
 	{110, 0,  5,  8},
 };
-
 #define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0]))
 
-struct p8022_hdr {
+struct header_struct {
+	/* 802.3 */
+	u8 dest[ETH_ALEN];
+	u8 src[ETH_ALEN];
+	u16 len;
+	/* 802.2 */
 	u8 dsap;
 	u8 ssap;
 	u8 ctrl;
+	/* SNAP */
 	u8 oui[3];
-} __attribute__ ((packed));
-
-struct orinoco_rxframe_hdr {
-	struct hermes_rx_descriptor desc;
-	struct ieee802_11_hdr p80211;
-	struct ethhdr p8023;
-	struct p8022_hdr p8022;
 	u16 ethertype;
 } __attribute__ ((packed));
 
-struct orinoco_txframe_hdr {
-	struct hermes_tx_descriptor desc;
-	struct ieee802_11_hdr p80211;
-	struct ethhdr p8023;
-	struct p8022_hdr p8022;
-	u16 ethertype;
-} __attribute__ ((packed));
+/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
+u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
 
-#define P8023_OFFSET		(sizeof(struct hermes_rx_descriptor) + \
-				sizeof(struct ieee802_11_hdr))
-#define ENCAPS_OVERHEAD		(sizeof(struct p8022_hdr) + 2)
-
-/* 802.2 LLL header SNAP used for SNAP encapsulation over 802.11 */
-struct p8022_hdr encaps_hdr = {
-	0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}
-};
-
-typedef struct orinoco_commsqual {
-	u16 qual, signal, noise;
-} __attribute__ ((packed)) orinoco_commsqual_t;
+#define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
 
 /*
  * Function prototypes
@@ -426,14 +444,13 @@
 
 static void orinoco_stat_gather(struct net_device *dev,
 			      struct sk_buff *skb,
-			      struct orinoco_rxframe_hdr *hdr);
+			      struct hermes_rx_descriptor *desc);
 
 static struct net_device_stats *orinoco_get_stats(struct net_device *dev);
 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev);
 
 /* Hardware control routines */
 
-static int __orinoco_hw_reset(struct orinoco_private *priv);
 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
 static int __orinoco_hw_setup_wep(struct orinoco_private *priv);
 static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN]);
@@ -441,7 +458,8 @@
 			      char buf[IW_ESSID_MAX_SIZE+1]);
 static long orinoco_hw_get_freq(struct orinoco_private *priv);
 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,
-				    int32_t *rates, int max);
+				    s32 *rates, int max);
+static void __orinoco_set_multicast_list(struct net_device *dev);
 
 /* Interrupt handling routines */
 static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw);
@@ -472,7 +490,6 @@
 static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq);
 static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq);
 static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq);
-static void __orinoco_set_multicast_list(struct net_device *dev);
 
 /* /proc debugging stuff */
 static int orinoco_proc_init(void);
@@ -515,14 +532,14 @@
 {
 	hermes_t *hw = &priv->hw;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
-	__cli();
+	__cli(); /* FIXME: is this necessary? */
 	set_bit(ORINOCO_STATE_DOIRQ, &priv->state);
 	hermes_set_irqmask(hw, irqmask);
 	__sti();
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 }
 
 static inline void
@@ -544,11 +561,17 @@
 		break;
 	default:
 		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
-		       priv->ndev.name);
+		       priv->ndev->name);
 	}
 }
 
-extern void
+static inline int
+is_snap(struct header_struct *hdr)
+{
+	return (hdr->dsap == 0xAA) && (hdr->ssap == 0xAA) && (hdr->ctrl == 0x3);
+}
+
+static void
 orinoco_set_multicast_list(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
@@ -562,66 +585,56 @@
  * Hardware control routines
  */
 
-static int
-__orinoco_hw_reset(struct orinoco_private *priv)
-{
-	hermes_t *hw = &priv->hw;
-
-	return hermes_reset(hw);
-}
-
 void
 orinoco_shutdown(struct orinoco_private *priv)
 {
-/* 	hermes_t *hw = &priv->hw; */
 	int err = 0;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	orinoco_lock(priv);
 	__orinoco_stop_irqs(priv);
 
-	err = __orinoco_hw_reset(priv);
+	err = hermes_reset(&priv->hw);
 	if (err && err != -ENODEV) /* If the card is gone, we don't care about shutting it down */
-		printk(KERN_ERR "%s: Error %d shutting down Hermes chipset\n", priv->ndev.name, err);
+		printk(KERN_ERR "%s: Error %d shutting down Hermes chipset\n", priv->ndev->name, err);
 
 	orinoco_unlock(priv);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 }
 
 int
 orinoco_reset(struct orinoco_private *priv)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	struct hermes_idstring idbuf;
-	int frame_size;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	/* Stop other people bothering us */
 	orinoco_lock(priv);
 	__orinoco_stop_irqs(priv);
 
 	/* Check if we need a card reset */
-	if((priv->need_card_reset) && (priv->card_reset_handler != NULL))
-		priv->card_reset_handler(priv);
+	if (priv->hard_reset)
+		priv->hard_reset(priv);
 
 	/* Do standard firmware reset if we can */
-	err = __orinoco_hw_reset(priv);
+	err = hermes_reset(hw);
 	if (err)
 		goto out;
 
-	frame_size = TX_NICBUF_SIZE;
-	/* This stupid bug is present in Intel firmware 1.10, and
-	 * may be fixed in later firmwares - Jean II */
-	if(priv->broken_allocate)
-		frame_size = TX_NICBUF_SIZE_BUG;
-	err = hermes_allocate(hw, frame_size, &priv->txfid);
-	if (err)
-		goto out;
+	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+	if (err == -EIO) {
+		/* Try workaround for old Symbol firmware bug */
+		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+		if (err)
+			goto out;
+	}
 
 	/* Now set up all the parameters on the card */
 	
@@ -645,21 +658,16 @@
 		}
 	}
 
-	/* Set up encryption */
-	if (priv->has_wep) {
-		err = __orinoco_hw_setup_wep(priv);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d activating WEP.\n",
-			       dev->name, err);
-			goto out;
-		}
-	}
-
 	/* Set the desired ESSID */
 	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
 	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
-	err = hermes_write_ltv(hw, USER_BAP, (priv->port_type == 3) ?
-			       HERMES_RID_CNFOWNSSID : HERMES_RID_CNFDESIREDSSID,
+	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
+			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+			       &idbuf);
+	if (err)
+		goto out;
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
 			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
 			       &idbuf);
 	if (err)
@@ -680,9 +688,12 @@
 		goto out;
 
 	/* Set AP density */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, priv->ap_density);
-	if (err)
-		goto out;
+	if (priv->has_sensitivity) {
+		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+					   priv->ap_density);
+		if (err)
+			priv->has_sensitivity = 0;
+	}
 
 	/* Set RTS threshold */
 	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, priv->rts_thresh);
@@ -740,6 +751,16 @@
 		}
 	}
 
+	/* Set up encryption */
+	if (priv->has_wep) {
+		err = __orinoco_hw_setup_wep(priv);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d activating WEP.\n",
+			       dev->name, err);
+			goto out;
+		}
+	}
+
 	/* Set promiscuity / multicast*/
 	priv->promiscuous = 0;
 	priv->mc_count = 0;
@@ -750,14 +771,14 @@
 			   HERMES_EV_WTERR | HERMES_EV_INFO |
 			   HERMES_EV_INFDROP);
 
-	err = hermes_enable_port(hw, ORINOCO_MACPORT);
+	err = hermes_enable_port(hw, 0);
 	if (err)
 		goto out;
 
  out:
 	orinoco_unlock(priv);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return err;
 }
@@ -767,11 +788,11 @@
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
 		printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
-		       priv->ndev.name, priv->bitratemode);
+		       priv->ndev->name, priv->bitratemode);
 		return -EINVAL;
 	}
 
@@ -791,7 +812,7 @@
 		BUG();
 	}
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return err;
 }
@@ -804,7 +825,7 @@
 	int	master_wep_flag;
 	int	auth_flag;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
@@ -837,19 +858,17 @@
 
 			/* Fudge around firmware weirdness */
 			keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
-
+			
 			/* Write all 4 keys */
 			for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
 /*  				int keylen = le16_to_cpu(priv->keys[i].len); */
-
+				
 				if (keylen > LARGE_KEY_SIZE) {
 					printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
-					       priv->ndev.name, i, keylen);
+					       priv->ndev->name, i, keylen);
 					return -E2BIG;
 				}
 
-				printk("About to write key %d, keylen=%d\n",
-				       i, keylen);				     
 				err = hermes_write_ltv(hw, USER_BAP,
 						       HERMES_RID_CNFDEFAULTKEY0 + i,
 						       HERMES_BYTES_TO_RECLEN(keylen),
@@ -863,32 +882,25 @@
 						   priv->tx_key);
 			if (err)
 				return err;
-
-			/* Authentication is where Intersil and Symbol
-			 * firmware differ... */
-			if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) {
-				/* Symbol cards : set the authentication :
-				 * 0 -> no encryption, 1 -> open,
-				 * 2 -> shared key
-				 * 3 -> shared key 128 -> AP only */
-				if(priv->wep_restrict)
-					auth_flag = 2;
-				else
-					auth_flag = 1;
-				err = hermes_write_wordrec(hw, USER_BAP,
-							   HERMES_RID_CNFAUTHENTICATION, auth_flag);
-				if (err)
-					return err;
-				/* Master WEP setting is always 3 */
+			
+			if (priv->wep_restrict) {
+				auth_flag = 2;
 				master_wep_flag = 3;
 			} else {
-				/* Prism2 card : we need to modify master
-				 * WEP setting */
-				if(priv->wep_restrict)
-					master_wep_flag = 3;
-				else
-					master_wep_flag = 1;
+				/* Authentication is where Intersil and Symbol
+				 * firmware differ... */
+				auth_flag = 1;
+				if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+					master_wep_flag = 3; /* Symbol */ 
+				else 
+					master_wep_flag = 1; /* Intersil */
 			}
+
+
+			err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFAUTHENTICATION, auth_flag);
+			if (err)
+				return err;
 		}
 		
 		/* Master WEP setting : on/off */
@@ -903,12 +915,12 @@
 	default:
 		if (priv->wep_on) {
 			printk(KERN_ERR "%s: WEP enabled, although not supported!\n",
-			       priv->ndev.name);
+			       priv->ndev->name);
 			return -EINVAL;
 		}
 	}
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return 0;
 }
@@ -937,7 +949,7 @@
 	char *p = (char *)(&essidbuf.val);
 	int len;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	orinoco_lock(priv);
 
@@ -971,14 +983,14 @@
 
 	len = le16_to_cpu(essidbuf.len);
 
-	memset(buf, 0, sizeof(buf));
+	memset(buf, 0, IW_ESSID_MAX_SIZE+1);
 	memcpy(buf, p, len);
 	buf[len] = '\0';
 
  fail_unlock:
 	orinoco_unlock(priv);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return err;       
 }
@@ -998,7 +1010,7 @@
 		goto out;
 
 	if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
-		struct net_device *dev = &priv->ndev;
+		struct net_device *dev = priv->ndev;
 
 		printk(KERN_WARNING "%s: Channel out of range (%d)!\n", dev->name, channel);
 		err = -EBUSY;
@@ -1016,7 +1028,7 @@
 }
 
 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,
-				    int32_t *rates, int max)
+				    s32 *rates, int max)
 {
 	hermes_t *hw = &priv->hw;
 	struct hermes_idstring list;
@@ -1114,7 +1126,7 @@
 {
 	struct orinoco_private *priv = (struct orinoco_private *) dev_id;
 	hermes_t *hw = &priv->hw;
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	int count = MAX_IRQLOOPS_PER_IRQ;
 	u16 evstat, events;
 	/* These are used to detect a runaway interrupt situation */
@@ -1131,23 +1143,21 @@
 		return;
 	}
 
-	DEBUG(3, "%s: orinoco_interrupt()\n", priv->ndev.name);
+	DEBUG(3, "%s: orinoco_interrupt()\n", priv->ndev->name);
 
 	evstat = hermes_read_regn(hw, EVSTAT);
 	events = evstat & hw->inten;
 	
-	if (! events) { /* Sometimes the card generates Tx interrupts without setting EVSTAT,
-			   or so I've heard - FIXME does it really happen? */
-		printk(KERN_WARNING "%s: Null event in orinoco_interrupt!\n", priv->ndev.name);
-		__orinoco_ev_alloc(priv, hw);
-	}
+/*  	if (! events) { */
+/*  		printk(KERN_WARNING "%s: Null event\n", dev->name); */
+/*  	} */
 
 	if (jiffies != last_irq_jiffy)
 		loops_this_jiffy = 0;
 	last_irq_jiffy = jiffies;
 
 	while (events && count--) {
-		DEBUG(4, "__orinoco_interrupt(): count=%d EVSTAT=0x%04x\n",
+		DEBUG(3, "__orinoco_interrupt(): count=%d EVSTAT=0x%04x\n",
 		      count, evstat);
 		
 		if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
@@ -1194,7 +1204,7 @@
 
 static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw)
 {
-	printk(KERN_DEBUG "%s: TICK\n", priv->ndev.name);
+	printk(KERN_DEBUG "%s: TICK\n", priv->ndev->name);
 }
 
 static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw)
@@ -1202,17 +1212,17 @@
 	/* This seems to happen a fair bit under load, but ignoring it
 	   seems to work fine...*/
 	DEBUG(1, "%s: MAC controller error (WTERR). Ignoring.\n",
-	      priv->ndev.name);
+	      priv->ndev->name);
 }
 
 static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw)
 {
-	printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev.name);
+	printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev->name);
 }
 
 static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	u16 infofid;
 	struct {
 		u16 len;
@@ -1225,7 +1235,7 @@
 	 * The controller return to us a pseudo frame containing
 	 * the information in question - Jean II */
 	infofid = hermes_read_regn(hw, INFOFID);
-	DEBUG(3, "%s: __dldwd_ev_info(): INFOFID=0x%04x\n", dev->name,
+	DEBUG(3, "%s: __orinoco_ev_info(): INFOFID=0x%04x\n", dev->name,
 	      infofid);
 
 	/* Read the info frame header - don't try too hard */
@@ -1277,7 +1287,7 @@
 	break;
 	default:
 		DEBUG(1, "%s: Unknown information frame received (type %04x).\n",
-		      priv->ndev.name, le16_to_cpu(info.type));
+		      priv->ndev->name, le16_to_cpu(info.type));
 		/* We don't actually do anything about it */
 		break;
 	}
@@ -1285,62 +1295,68 @@
 
 static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	struct net_device_stats *stats = &priv->stats;
 	struct iw_statistics *wstats = &priv->wstats;
 	struct sk_buff *skb = NULL;
 	u16 rxfid, status;
 	int length, data_len, data_off;
 	char *p;
-	struct orinoco_rxframe_hdr hdr;
+	struct hermes_rx_descriptor desc;
+	struct header_struct hdr;
 	struct ethhdr *eh;
 	int err;
 
 	rxfid = hermes_read_regn(hw, RXFID);
 	DEBUG(3, "__orinoco_ev_rx(): RXFID=0x%04x\n", rxfid);
 
-	/* We read in the entire frame header here. This isn't really
-	   necessary, since we ignore most of it, but it's
-	   conceptually simpler. We can tune this later if
-	   necessary. */
-	err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr), rxfid, 0);
+	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
+			       rxfid, 0);
 	if (err) {
-		printk(KERN_ERR "%s: error %d reading frame header. "
+		printk(KERN_ERR "%s: error %d reading Rx descriptor. "
 		       "Frame dropped.\n", dev->name, err);
 		stats->rx_errors++;
 		goto drop;
 	}
 
-	status = le16_to_cpu(hdr.desc.status);
+	status = le16_to_cpu(desc.status);
 	
 	if (status & HERMES_RXSTAT_ERR) {
-		if ((status & HERMES_RXSTAT_ERR) == HERMES_RXSTAT_BADCRC) {
-			stats->rx_crc_errors++;
-			DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
-		} else if ((status & HERMES_RXSTAT_ERR)
-			   == HERMES_RXSTAT_UNDECRYPTABLE) {
+		if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
 			wstats->discard.code++;
-			printk(KERN_WARNING "%s: Undecryptable frame on Rx. Frame dropped.\n",
+			DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
 			       dev->name);
 		} else {
-			wstats->discard.misc++;
-			printk("%s: Unknown Rx error (0x%x). Frame dropped.\n",
-			       dev->name, status & HERMES_RXSTAT_ERR);
+			stats->rx_crc_errors++;
+			DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
 		}
 		stats->rx_errors++;
 		goto drop;
 	}
 
-	length = le16_to_cpu(hdr.p80211.data_len);
-	/* Yes, you heard right, that's le16. 802.2 and 802.3 are
-	   big-endian, but 802.11 is little-endian believe it or
-	   not. */
-	/* Correct. 802.3 is big-endian byte order and little endian bit
-	 * order, whereas 802.11 is little endian for both byte and bit
-	 * order. That's specified in the 802.11 spec. - Jean II */
+	/* For now we ignore the 802.11 header completely, assuming
+           that the card's firmware has handled anything vital */
+
+	err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
+			       rxfid, HERMES_802_3_OFFSET);
+	if (err) {
+		printk(KERN_ERR "%s: error %d reading frame header. "
+		       "Frame dropped.\n", dev->name, err);
+		stats->rx_errors++;
+		goto drop;
+	}
+
+	length = ntohs(hdr.len);
 	
-	/* Sanity check */
-	if (length > MAX_FRAME_SIZE) {
+	/* Sanity checks */
+	if (length < sizeof(struct header_struct)) {
+		printk(KERN_WARNING "%s: Undersized frame received (%d bytes)\n",
+		       dev->name, length);
+		stats->rx_length_errors++;
+		stats->rx_errors++;
+		goto drop;
+	}
+	if (length > IEEE802_11_DATA_LEN) {
 		printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
 		       dev->name, length);
 		stats->rx_length_errors++;
@@ -1371,39 +1387,41 @@
 	 */
 	if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
 	   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
-	   (!memcmp(&hdr.p8022, &encaps_hdr, 3))) {
+	   is_snap(&hdr)) {
 		/* These indicate a SNAP within 802.2 LLC within
 		   802.11 frame which we'll need to de-encapsulate to
 		   the original EthernetII frame. */
 
+		if (length < ENCAPS_OVERHEAD) {
+			stats->rx_length_errors++;
+			stats->rx_dropped++;
+			goto drop;
+		}
+
 		/* Remove SNAP header, reconstruct EthernetII frame */
 		data_len = length - ENCAPS_OVERHEAD;
-		data_off = sizeof(hdr);
+		data_off = HERMES_802_3_OFFSET + sizeof(hdr);
 
 		eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
 
-		memcpy(eh, &hdr.p8023, sizeof(hdr.p8023));
+		memcpy(eh, &hdr, 2 * ETH_ALEN);
 		eh->h_proto = hdr.ethertype;
 	} else {
-		/* All other cases indicate a genuine 802.3 frame.
-		 * No decapsulation needed */
-
-		/* Otherwise, we just throw the whole thing in,
-		 * and hope the protocol layer can deal with it
-		 * as 802.3 */
+		/* All other cases indicate a genuine 802.3 frame.  No
+		   decapsulation needed.  We just throw the whole
+		   thing in, and hope the protocol layer can deal with
+		   it as 802.3 */
 		data_len = length;
-		data_off = P8023_OFFSET;
+		data_off = HERMES_802_3_OFFSET;
+		/* FIXME: we re-read from the card data we already read here */
 	}
 
 	p = skb_put(skb, data_len);
 	err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
 			       rxfid, data_off);
 	if (err) {
-		if (err == -EIO)
-			DEBUG(1, "%s: EIO reading frame header.\n", dev->name);
-		else
-			printk(KERN_ERR "%s: error %d reading frame header. "
-			       "Frame dropped.\n", dev->name, err);
+		printk(KERN_ERR "%s: error %d reading frame header. "
+		       "Frame dropped.\n", dev->name, err);
 		stats->rx_errors++;
 		goto drop;
 	}
@@ -1414,7 +1432,7 @@
 	skb->ip_summed = CHECKSUM_NONE;
 	
 	/* Process the wireless stats if needed */
-	orinoco_stat_gather(dev, skb, &hdr);
+	orinoco_stat_gather(dev, skb, &desc);
 
 	/* Pass the packet to the networking stack */
 	netif_rx(skb);
@@ -1431,7 +1449,7 @@
 
 static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	struct net_device_stats *stats = &priv->stats;
 	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
 	struct hermes_tx_descriptor desc;
@@ -1440,72 +1458,78 @@
 	if (fid == DUMMY_FID)
 		return; /* Nothing's really happened */
 
-	err = hermes_bap_pread(hw, USER_BAP, &desc, sizeof(desc), fid, 0);
+	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0);
 	if (err) {
 		printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
 		       "(FID=%04X error %d)\n",
 		       dev->name, fid, err);
 	} else {
-		printk(KERN_INFO "%s: Tx error, status %d (FID=%04X)\n",
-		       dev->name, le16_to_cpu(desc.status), fid);
+		DEBUG(1, "%s: Tx error, status %d\n",
+		      dev->name, le16_to_cpu(desc.status));
 	}
 	
 	stats->tx_errors++;
-	netif_wake_queue(dev);
 
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
 static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+/*  	struct net_device *dev = priv->ndev; */
 	struct net_device_stats *stats = &priv->stats;
 /*  	u16 fid = hermes_read_regn(hw, TXCOMPLFID); */
 
-	/* We don't generally use the Tx event (to cut down on
-	   interrupts) - we do the transmit complet processing once
-	   the transmit buffer is reclaimed in __orinoco_ev_alloc() ,
-	   hence nothing here */
-
-/*  	DEBUG(2, "%s: Transmit completed (FID=%04X)\n", priv->ndev.name, fid); */
+/*  	DEBUG(2, "%s: Transmit completed (FID=%04X)\n", priv->ndev->name, fid); */
 
 	stats->tx_packets++;
-	netif_wake_queue(dev);
 
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
 static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	u16 fid = hermes_read_regn(hw, ALLOCFID);
 
-	DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev.name, fid);
-
-	/* We don't generally request Tx complete events to cut down
-	   on the number of interrupts, so we do trasmit complete
-	   processing here, which happens once the firmware is done
-	   with the transmit buffer */
+	DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev->name, fid);
 
 	if (fid != priv->txfid) {
 		if (fid != DUMMY_FID)
 			printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
 			       dev->name, fid);
 		return;
+	} else {
+		netif_wake_queue(dev);
 	}
 
 	hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
 }
 
+struct sta_id {
+	u16 id, vendor, major, minor;
+} __attribute__ ((packed));
+
+static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id)
+{
+	u32 firmver = ((u32)sta_id->major << 16) | sta_id->minor;
+	
+	if (sta_id->vendor == 1)
+		return FIRMWARE_TYPE_AGERE;
+	else if ((sta_id->vendor == 2) &&
+		   ((firmver == 0x10001) || (firmver == 0x20001)))
+		return FIRMWARE_TYPE_SYMBOL;
+	else
+		return FIRMWARE_TYPE_INTERSIL;
+}
+
 static void determine_firmware(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
 	int err;
-	struct sta_id {
-		u16 id, vendor, major, minor;
-	} __attribute__ ((packed)) sta_id;
+	struct sta_id sta_id;
 	u32 firmver;
+	char tmp[SYMBOL_MAX_VER_LEN+1];
 
 	/* Get the firmware version */
 	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
@@ -1525,19 +1549,29 @@
 	       dev->name, sta_id.id, sta_id.vendor,
 	       sta_id.major, sta_id.minor);
 
-	/* Determine capabilities from the firmware version */
+	if (! priv->firmware_type)
+		priv->firmware_type = determine_firmware_type(dev, &sta_id);
+
+	/* Default capabilities */
+	priv->has_sensitivity = 1;
+	priv->has_mwo = 0;
+	priv->has_preamble = 0;
+	priv->has_port3 = 1;
+	priv->has_ibss = 1;
+	priv->has_ibss_any = 0;
+	priv->has_wep = 0;
+	priv->has_big_wep = 0;
+	priv->broken_cor_reset = 0;
 
-	if (sta_id.vendor == 1) {
+	/* Determine capabilities from the firmware version */
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
 		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
 		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
 		printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
 		       "version %d.%02d\n", dev->name,
 		       sta_id.major, sta_id.minor);
 
-		priv->firmware_type = FIRMWARE_TYPE_AGERE;
-		priv->need_card_reset = 0;
-		priv->broken_allocate = 0;
-		priv->has_port3 = 1;		/* Still works in 7.28 */
 		priv->has_ibss = (firmver >= 0x60006);
 		priv->has_ibss_any = (firmver >= 0x60010);
 		priv->has_wep = (firmver >= 0x40020);
@@ -1545,18 +1579,18 @@
 					  Gold cards from the others? */
 		priv->has_mwo = (firmver >= 0x60000);
 		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
-		priv->has_preamble = 0;
 		priv->ibss_port = 1;
+
+		/* FIXME: Which firmware really do have a broken reset */
+		priv->broken_cor_reset = (firmver < 0x60000);
 		/* Tested with Agere firmware :
 		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
 		 * Tested CableTron firmware : 4.32 => Anton */
-	} else if ((sta_id.vendor == 2) &&
-		   ((firmver == 0x10001) || (firmver == 0x20001))) {
+		break;
+	case FIRMWARE_TYPE_SYMBOL:
 		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
 		/* Intel MAC : 00:02:B3:* */
 		/* 3Com MAC : 00:50:DA:* */
-		char tmp[SYMBOL_MAX_VER_LEN+1];
-
 		memset(tmp, 0, sizeof(tmp));
 		/* Get the Symbol firmware version */
 		err = hermes_read_ltv(hw, USER_BAP,
@@ -1584,20 +1618,16 @@
 		       "version [%s] (parsing to %X)\n", dev->name,
 		       tmp, firmver);
 
-		priv->firmware_type = FIRMWARE_TYPE_SYMBOL;
-		priv->need_card_reset = 1;
-		priv->broken_allocate = 1;
-		priv->has_port3 = 1;
 		priv->has_ibss = (firmver >= 0x20000);
 		priv->has_wep = (firmver >= 0x15012);
 		priv->has_big_wep = (firmver >= 0x20000);
-		priv->has_mwo = 0;
 		priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);
 		priv->has_preamble = (firmver >= 0x20000);
 		priv->ibss_port = 4;
 		/* Tested with Intel firmware : 0x20015 => Jean II */
 		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
-	} else {
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
 		/* D-Link, Linksys, Adtron, ZoomAir, and many others...
 		 * Samsung, Compaq 100/200 and Proxim are slightly
 		 * different and less well tested */
@@ -1607,16 +1637,9 @@
 		       "version %d.%02d\n", dev->name,
 		       sta_id.major, sta_id.minor);
 
-		priv->firmware_type = FIRMWARE_TYPE_INTERSIL;
-		priv->need_card_reset = 0;
-		priv->broken_allocate = 0;
-		priv->has_port3 = 1;
 		priv->has_ibss = (firmver >= 0x00007); /* FIXME */
-		priv->has_wep = (firmver >= 0x00008);
-		priv->has_big_wep = priv->has_wep;
-		priv->has_mwo = 0;
+		priv->has_big_wep = priv->has_wep = (firmver >= 0x00008);
 		priv->has_pm = (firmver >= 0x00007);
-		priv->has_preamble = 0;
 
 		if (firmver >= 0x00008)
 			priv->ibss_port = 0;
@@ -1626,6 +1649,9 @@
 			       dev->name);
 			priv->ibss_port = 1;
 		}
+		break;
+	default:
+		break;
 	}
 }
 
@@ -1633,7 +1659,7 @@
  * struct net_device methods
  */
 
-int
+static int
 orinoco_init(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
@@ -1647,6 +1673,8 @@
 
 	orinoco_lock(priv);
 
+	priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
+
 	/* Do standard firmware reset */
 	err = hermes_reset(hw);
 	if (err != 0) {
@@ -1711,10 +1739,10 @@
 	}
 
 	/* Get initial AP density */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, &priv->ap_density);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read AP density!\n", dev->name);
-		goto out;
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+				  &priv->ap_density);
+	if (err || priv->ap_density < 1 || priv->ap_density > 3) {
+		priv->has_sensitivity = 0;
 	}
 
 	/* Get initial RTS threshold */
@@ -1773,6 +1801,7 @@
 	/* By default use IEEE/IBSS ad-hoc mode if we have it */
 	priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
 	set_port_type(priv);
+	priv->channel = 10; /* default channel, more-or-less arbitrary */
 
 	priv->promiscuous = 0;
 	priv->wep_on = 0;
@@ -1820,7 +1849,9 @@
 			wstats->qual.updated = priv->spy_stat[0].updated;
 		}
 	} else {
-		orinoco_commsqual_t cq;
+		struct {
+			u16 qual, signal, noise;
+		} __attribute__ ((packed)) cq;
 
 		err = HERMES_READ_RECORD(hw, USER_BAP,
 					 HERMES_RID_COMMSQUALITY, &cq);
@@ -1861,15 +1892,15 @@
 		if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
 			priv->spy_stat[i].level = level - 0x95;
 			priv->spy_stat[i].noise = noise - 0x95;
-			priv->spy_stat[i].qual = level - noise;
+			priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
 			priv->spy_stat[i].updated = 7;
 		}
 }
 
 void
-orinoco_stat_gather( struct net_device *dev,
-		   struct sk_buff *skb,
-		   struct orinoco_rxframe_hdr *hdr)
+orinoco_stat_gather(struct net_device *dev,
+		    struct sk_buff *skb,
+		    struct hermes_rx_descriptor *desc)
 {
 	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
 
@@ -1885,11 +1916,11 @@
 	 * WIRELESS_SPY is not defined... - Jean II */
 	if (SPY_NUMBER(priv)) {
 		orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,
-				   hdr->desc.signal, hdr->desc.silence);
+				   desc->signal, desc->silence);
 	}
 }
 
-int
+static int
 orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
@@ -1900,8 +1931,7 @@
 	char *p;
 	struct ethhdr *eh;
 	int len, data_len, data_off;
-	struct orinoco_txframe_hdr hdr;
-	hermes_response_t resp;
+	struct hermes_tx_descriptor desc;
 
 	if (! netif_running(dev)) {
 		printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -1924,83 +1954,69 @@
 
 	eh = (struct ethhdr *)skb->data;
 
-	/* Build the IEEE 802.11 header */
-	memset(&hdr, 0, sizeof(hdr));
-	memcpy(hdr.p80211.addr1, eh->h_dest, ETH_ALEN);
-	memcpy(hdr.p80211.addr2, eh->h_source, ETH_ALEN);
-	hdr.p80211.frame_ctl = IEEE802_11_FTYPE_DATA;
-
-	/* Request an interrupt on Tx failures, but not sucesses (we
-           use the buffer reclaim allocation event instead */
-	hdr.desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_EX | HERMES_TXCTRL_TX_OK);
+	memset(&desc, 0, sizeof(desc));
+ 	desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
+	err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d writing Tx descriptor to BAP\n",
+		       dev->name, err);
+		stats->tx_errors++;
+		goto fail;
+	}
 
 	/* Encapsulate Ethernet-II frames */
 	if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */
+		struct header_struct hdr;
 		data_len = len;
-		data_off = sizeof(hdr);
+		data_off = HERMES_802_3_OFFSET + sizeof(hdr);
 		p = skb->data + ETH_HLEN;
 
-		/* 802.11 header */
-		hdr.p80211.data_len = cpu_to_le16(data_len + ENCAPS_OVERHEAD);
-
 		/* 802.3 header */
-		memcpy(hdr.p8023.h_dest, eh->h_dest, ETH_ALEN);
-		memcpy(hdr.p8023.h_source, eh->h_source, ETH_ALEN);
-		hdr.p8023.h_proto = htons(data_len + ENCAPS_OVERHEAD);
+		memcpy(hdr.dest, eh->h_dest, ETH_ALEN);
+		memcpy(hdr.src, eh->h_source, ETH_ALEN);
+		hdr.len = htons(data_len + ENCAPS_OVERHEAD);
 		
 		/* 802.2 header */
-		memcpy(&hdr.p8022, &encaps_hdr, sizeof(encaps_hdr));
+		memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr));
 			
 		hdr.ethertype = eh->h_proto;
 		err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
-					 txfid, 0);
+					 txfid, HERMES_802_3_OFFSET);
 		if (err) {
-				printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
-				       dev->name, err);
+			printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
+			       dev->name, err);
 			stats->tx_errors++;
 			goto fail;
 		}
 	} else { /* IEEE 802.3 frame */
 		data_len = len + ETH_HLEN;
-		data_off = P8023_OFFSET;
+		data_off = HERMES_802_3_OFFSET;
 		p = skb->data;
-		
-		/* 802.11 header */
-		hdr.p80211.data_len = cpu_to_le16(len);
-		err = hermes_bap_pwrite(hw, USER_BAP, &hdr, P8023_OFFSET,
-					txfid, 0);
-		if (err) {
-			printk(KERN_ERR
-			       "%s: Error %d writing packet header to BAP\n",
-			       dev->name, err);
-			stats->tx_errors++;
-			goto fail;
-		}
 	}
 
 	/* Round up for odd length packets */
 	err = hermes_bap_pwrite(hw, USER_BAP, p, RUP_EVEN(data_len), txfid, data_off);
 	if (err) {
-		printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
+		printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
 		       dev->name, err);
 		stats->tx_errors++;
 		goto fail;
 	}
 
 	/* Finally, we actually initiate the send */
-	err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, &resp);
+	netif_stop_queue(dev);
+
+	err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, NULL);
 	if (err) {
+		netif_start_queue(dev);
 		printk(KERN_ERR "%s: Error %d transmitting packet\n", dev->name, err);
 		stats->tx_errors++;
 		goto fail;
 	}
 
-	atomic_inc(&priv->queue_length);
 	dev->trans_start = jiffies;
 	stats->tx_bytes += data_off + data_len;
 
-	netif_stop_queue(dev);
-
 	orinoco_unlock(priv);
 
 	dev_kfree_skb(skb);
@@ -2012,14 +2028,15 @@
 	return err;
 }
 
-void
+static void
 orinoco_tx_timeout(struct net_device *dev)
 {
 	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
 	struct net_device_stats *stats = &priv->stats;
+	struct hermes *hw = &priv->hw;
 	int err = 0;
 
-	printk(KERN_WARNING "%s: Tx timeout! Resetting card.\n", dev->name);
+	printk(KERN_WARNING "%s: Tx timeout! Resetting card. ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n", dev->name, hermes_read_regn(hw, ALLOCFID), hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
 
 	stats->tx_errors++;
 
@@ -2033,6 +2050,110 @@
 	}
 }
 
+static int
+orinoco_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct orinoco_private *priv = dev->priv;
+	TRACE_ENTER(dev->name);
+
+	if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
+		return -EINVAL;
+
+	if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) >
+	     (priv->nicbuf_size - ETH_HLEN) )
+		return -EINVAL;
+
+	dev->mtu = new_mtu;
+
+	TRACE_EXIT(dev->name);
+
+	return 0;
+}
+
+static void
+__orinoco_set_multicast_list(struct net_device *dev)
+{
+	struct orinoco_private *priv = dev->priv;
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	int promisc, mc_count;
+
+	/* We'll wait until it's ready. Anyway, the network doesn't call us
+	 * here until we are open - Jean II */
+	/* FIXME: do we need this test at all? */
+	if (! netif_device_present(dev)) {
+		printk(KERN_WARNING "%s: __orinoco_set_multicast_list() called while device "
+		       "not present.\n", dev->name);
+		return;
+	}
+
+	TRACE_ENTER(dev->name);
+
+	/* The Hermes doesn't seem to have an allmulti mode, so we go
+	 * into promiscuous mode and let the upper levels deal. */
+	if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
+	     (dev->mc_count > MAX_MULTICAST(priv)) ) {
+		promisc = 1;
+		mc_count = 0;
+	} else {
+		promisc = 0;
+		mc_count = dev->mc_count;
+	}
+
+	if (promisc != priv->promiscuous) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPROMISCUOUSMODE,
+					   promisc);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
+			       dev->name, err);
+		} else 
+			priv->promiscuous = promisc;
+	}
+
+	if (! promisc && (mc_count || priv->mc_count) ) {
+		struct dev_mc_list *p = dev->mc_list;
+		hermes_multicast_t mclist;
+		int i;
+
+		for (i = 0; i < mc_count; i++) {
+			/* Paranoia: */
+			if (! p)
+				BUG(); /* Multicast list shorter than mc_count */
+			if (p->dmi_addrlen != ETH_ALEN)
+				BUG(); /* Bad address size in multicast list */
+			
+			memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
+			p = p->next;
+		}
+		
+		if (p)
+			printk(KERN_WARNING "Multicast list is longer than mc_count\n");
+
+		err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
+				       HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
+				       &mclist);
+		if (err)
+			printk(KERN_ERR "%s: Error %d setting multicast list.\n",
+			       dev->name, err);
+		else
+			priv->mc_count = mc_count;
+	}
+
+	/* Since we can set the promiscuous flag when it wasn't asked
+	   for, make sure the net_device knows about it. */
+	if (priv->promiscuous)
+		dev->flags |= IFF_PROMISC;
+	else
+		dev->flags &= ~IFF_PROMISC;
+
+	TRACE_EXIT(dev->name);
+}
+
+/********************************************************************/
+/* Wireless extensions support                                      */
+/********************************************************************/
+
 static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq)
 {
 	struct orinoco_private *priv = dev->priv;
@@ -2345,9 +2466,15 @@
 
 	TRACE_ENTER(dev->name);
 
-	err = orinoco_hw_get_essid(priv, &active, essidbuf);
-	if (err)
-		return err;
+	if (netif_running(dev)) {
+		err = orinoco_hw_get_essid(priv, &active, essidbuf);
+		if (err)
+			return err;
+	} else {
+		orinoco_lock(priv);
+		memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
+		orinoco_unlock(priv);
+	}
 
 	erq->flags = 1;
 	erq->length = strlen(essidbuf) + 1;
@@ -2446,6 +2573,9 @@
 	u16 val;
 	int err;
 
+	if (!priv->has_sensitivity)
+		return -EOPNOTSUPP;
+
 	orinoco_lock(priv);
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, &val);
 	orinoco_unlock(priv);
@@ -2464,6 +2594,9 @@
 	struct orinoco_private *priv = dev->priv;
 	int val = srq->value;
 
+	if (!priv->has_sensitivity)
+		return -EOPNOTSUPP;
+
 	if ((val < 1) || (val > 3))
 		return -EINVAL;
 	
@@ -2988,7 +3121,7 @@
 	return 0;
 }
 
-int
+static int
 orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct orinoco_private *priv = dev->priv;
@@ -3253,6 +3386,7 @@
 		break;
 	       
 	case SIOCIWFIRSTPRIV + 0x0: /* force_reset */
+	case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
 		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x0 (force_reset)\n",
 		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
@@ -3261,21 +3395,12 @@
 		}
 		
 		printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
-		orinoco_reset(priv);
-		break;
 
-	case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x1 (card_reset)\n",
-		      dev->name);
-		if (! capable(CAP_NET_ADMIN)) {
-			err = -EPERM;
-			break;
-		}
-		
-		printk(KERN_DEBUG "%s: Forcing card reset!\n", dev->name);
-		if(priv->card_reset_handler != NULL)
-			priv->card_reset_handler(priv);
+		/* We need the xmit lock because it protects the
+		   multicast list which orinoco_reset() reads */
+		spin_lock_bh(&dev->xmit_lock);
 		orinoco_reset(priv);
+		spin_unlock_bh(&dev->xmit_lock);
 		break;
 
 	case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
@@ -3361,7 +3486,11 @@
 	}
 	
 	if (! err && changed && netif_running(dev)) {
+		/* We need the xmit lock because it protects the
+		   multicast list which orinoco_reset() reads */
+		spin_lock_bh(&dev->xmit_lock);
 		err = orinoco_reset(priv);
+		spin_unlock_bh(&dev->xmit_lock);
 		if (err) {
 			/* Ouch ! What are we supposed to do ? */
 			printk(KERN_ERR "orinoco_cs: Failed to set parameters on %s\n",
@@ -3376,106 +3505,14 @@
 	return err;
 }
 
-int
-orinoco_change_mtu(struct net_device *dev, int new_mtu)
-{
-	TRACE_ENTER(dev->name);
-
-	if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
-		return -EINVAL;
-
-	dev->mtu = new_mtu;
-
-	TRACE_EXIT(dev->name);
-
-	return 0;
-}
-
-static void
-__orinoco_set_multicast_list(struct net_device *dev)
-{
-	struct orinoco_private *priv = dev->priv;
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	int promisc, mc_count;
-
-	/* We'll wait until it's ready. Anyway, the network doesn't call us
-	 * here until we are open - Jean II */
-	/* FIXME: do we need this test at all? */
-	if (! netif_device_present(dev))
-		return;
-
-	TRACE_ENTER(dev->name);
-
-	/* The Hermes doesn't seem to have an allmulti mode, so we go
-	 * into promiscuous mode and let the upper levels deal. */
-	if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
-	     (dev->mc_count > MAX_MULTICAST(priv)) ) {
-		promisc = 1;
-		mc_count = 0;
-	} else {
-		promisc = 0;
-		mc_count = dev->mc_count;
-	}
-
-	if (promisc != priv->promiscuous) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPROMISCUOUSMODE,
-					   promisc);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
-			       dev->name, err);
-		} else 
-			priv->promiscuous = promisc;
-
-		mc_count = 0;
-	}
-
-	if (mc_count || priv->mc_count) {
-		struct dev_mc_list *p = dev->mc_list;
-		hermes_multicast_t mclist;
-		int i;
-
-		for (i = 0; i < mc_count; i++) {
-			/* Paranoia: */
-			if (! p)
-				BUG(); /* Multicast list shorter than mc_count */
-			if (p->dmi_addrlen != ETH_ALEN)
-				BUG(); /* Bad address size in multicast list */
-			
-			memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
-			p = p->next;
-		}
-		
-		if (p)
-			printk(KERN_WARNING "Multicast list is longer than mc_count\n");
-
-		err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
-				       HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
-				       &mclist);
-		if (err)
-			printk(KERN_ERR "%s: Error %d setting multicast list.\n",
-			       dev->name, err);
-		else
-			priv->mc_count = mc_count;
-	}
-
-	/* Since we can set the promiscuous flag when it wasn't asked
-	   for, make sure the net_device knows about it. */
-	if (priv->promiscuous)
-		dev->flags |= IFF_PROMISC;
-	else
-		dev->flags &= ~IFF_PROMISC;
-
-	TRACE_EXIT(dev->name);
-}
-
-/*
- * procfs stuff
- */
+/********************************************************************/
+/* procfs stuff                                                     */
+/********************************************************************/
 
 static struct proc_dir_entry *dir_base = NULL;
 
+#define PROC_LTV_SIZE		128
+
 /*
  * This function updates the total amount of data printed so far. It then
  * determines if the amount of data printed into a buffer  has reached the
@@ -3485,7 +3522,6 @@
  * function returns 1, otherwise 0.
  */
 static int 
-
 shift_buffer(char *buffer, int requested_offset, int requested_len,
 	     int *total, int *slop, char **buf)
 {
@@ -3544,180 +3580,116 @@
 	return return_len;
 }
 
-static int
-orinoco_proc_get_hermes_regs(char *page, char **start, off_t requested_offset,
-			   int requested_len, int *eof, void *data)
-{
-	struct orinoco_private *priv = (struct orinoco_private *)data;
-	struct net_device *dev = &priv->ndev;
-	hermes_t *hw = &priv->hw;
-	char *buf;
-	int total = 0, slop = 0;
-
-	/* Hum, in this case hardware register are probably not readable... */
-	if (! netif_device_present(dev))
-		return -ENODEV;
-
-	buf = page;
-
-#define DHERMESREG(name) buf += sprintf(buf, "%-16s: %04x\n", #name, hermes_read_regn(hw, name))
-
-	DHERMESREG(CMD);
-	DHERMESREG(PARAM0);
-	DHERMESREG(PARAM1);
-	DHERMESREG(PARAM2);
-	DHERMESREG(STATUS);
-	DHERMESREG(RESP0);
-	DHERMESREG(RESP1);
-	DHERMESREG(RESP2);
-	DHERMESREG(INFOFID);
-	DHERMESREG(RXFID);
-	DHERMESREG(ALLOCFID);
-	DHERMESREG(TXCOMPLFID);
-	DHERMESREG(SELECT0);
-	DHERMESREG(OFFSET0);
-	DHERMESREG(SELECT1);
-	DHERMESREG(OFFSET1);
-	DHERMESREG(EVSTAT);
-	DHERMESREG(INTEN);
-	DHERMESREG(EVACK);
-	DHERMESREG(CONTROL);
-	DHERMESREG(SWSUPPORT0);
-	DHERMESREG(SWSUPPORT1);
-	DHERMESREG(SWSUPPORT2);
-	DHERMESREG(AUXPAGE);
-	DHERMESREG(AUXOFFSET);
-	DHERMESREG(AUXDATA);
-#undef DHERMESREG
-
-	shift_buffer(page, requested_offset, requested_len, &total,
-		     &slop, &buf);
-	return calc_start_len(page, start, requested_offset, requested_len,
-			      total, buf);
-}
-
 struct {
 	u16 rid;
 	char *name;
-	int minlen, maxlen;
 	int displaytype;
 #define DISPLAY_WORDS	0
 #define DISPLAY_BYTES	1
 #define DISPLAY_STRING	2
 #define DISPLAY_XSTRING	3
 } record_table[] = {
-#define CNF_WORDS(name) { HERMES_RID_CNF##name, #name, 0, LTV_BUF_SIZE, DISPLAY_WORDS }
-#define CNF_BYTES(name) { HERMES_RID_CNF##name, #name, 0, LTV_BUF_SIZE, DISPLAY_BYTES }
-#define CNF_STRING(name) { HERMES_RID_CNF##name, #name, 0, LTV_BUF_SIZE, DISPLAY_STRING }
-	CNF_WORDS(PORTTYPE),
-	CNF_BYTES(OWNMACADDR),
-	CNF_STRING(DESIREDSSID),
-	CNF_WORDS(OWNCHANNEL),
-	CNF_STRING(OWNSSID),
-	CNF_WORDS(OWNATIMWINDOW),
-	CNF_WORDS(SYSTEMSCALE),
-	CNF_WORDS(MAXDATALEN),
-	CNF_WORDS(PMENABLED),
-	CNF_WORDS(PMEPS),
-	CNF_WORDS(MULTICASTRECEIVE),
-	CNF_WORDS(MAXSLEEPDURATION),
-	CNF_WORDS(PMHOLDOVERDURATION),
-	CNF_STRING(OWNNAME),
-	CNF_WORDS(OWNDTIMPERIOD),
-	CNF_WORDS(MULTICASTPMBUFFERING),
-	CNF_WORDS(WEPENABLED_AGERE),
-	CNF_WORDS(MANDATORYBSSID_SYMBOL),
-	CNF_WORDS(WEPDEFAULTKEYID),
-	CNF_BYTES(DEFAULTKEY0),
-	CNF_BYTES(DEFAULTKEY1),
-	CNF_WORDS(MWOROBUST_AGERE),
-	CNF_BYTES(DEFAULTKEY2),
-	CNF_BYTES(DEFAULTKEY3),
-	CNF_WORDS(WEPFLAGS_INTERSIL),
-	CNF_WORDS(WEPKEYMAPPINGTABLE),
-	CNF_WORDS(AUTHENTICATION),
-	CNF_WORDS(MAXASSOCSTA),
-	CNF_WORDS(KEYLENGTH_SYMBOL),
-	CNF_WORDS(TXCONTROL),
-	CNF_WORDS(ROAMINGMODE),
-	CNF_WORDS(HOSTAUTHENTICATION),
-	CNF_WORDS(RCVCRCERROR),
-	CNF_WORDS(MMLIFE),
-	CNF_WORDS(ALTRETRYCOUNT),
-	CNF_WORDS(BEACONINT),
-	CNF_WORDS(APPCFINFO),
-	CNF_WORDS(STAPCFINFO),
-	CNF_WORDS(PRIORITYQUSAGE),
-	CNF_WORDS(TIMCTRL),
-	CNF_WORDS(THIRTY2TALLY),
-	CNF_WORDS(ENHSECURITY),
-	CNF_BYTES(GROUPADDRESSES),
-	CNF_WORDS(CREATEIBSS),
-	CNF_WORDS(FRAGMENTATIONTHRESHOLD),
-	CNF_WORDS(RTSTHRESHOLD),
-	CNF_WORDS(TXRATECONTROL),
-	CNF_WORDS(PROMISCUOUSMODE),
-	CNF_WORDS(BASICRATES_SYMBOL),
-	CNF_WORDS(PREAMBLE_SYMBOL),
-	CNF_WORDS(SHORTPREAMBLE),
-	CNF_BYTES(WEPKEYS_AGERE),
-	CNF_WORDS(EXCLUDELONGPREAMBLE),
-	CNF_WORDS(TXKEY_AGERE),
-	CNF_WORDS(AUTHENTICATIONRSPTO),
-	CNF_WORDS(BASICRATES),
-	CNF_WORDS(SUPPORTEDRATES),
-	CNF_WORDS(TICKTIME),
-	CNF_WORDS(SCANREQUEST),
-	CNF_WORDS(JOINREQUEST),
-	CNF_WORDS(AUTHENTICATESTATION),
-	CNF_WORDS(CHANNELINFOREQUEST),
-#undef CNF_WORDS
-#undef CNF_BYTES
-#undef CNF_STRING
-#define INF_WORDS(name) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, DISPLAY_WORDS }
-#define INF_BYTES(name) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, DISPLAY_BYTES }
-#define INF_STRING(name) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, DISPLAY_STRING }
-#define INF_XSTRING(name) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, DISPLAY_XSTRING }
-	INF_WORDS(MAXLOADTIME),
-	INF_WORDS(DOWNLOADBUFFER),
-	INF_WORDS(PRIID),
-	INF_WORDS(PRISUPRANGE),
-	INF_WORDS(CFIACTRANGES),
-	INF_WORDS(NICSERNUM),
-	INF_WORDS(NICID),
-	INF_WORDS(MFISUPRANGE),
-	INF_WORDS(CFISUPRANGE),
-	INF_WORDS(CHANNELLIST),
-	INF_WORDS(REGULATORYDOMAINS),
-	INF_WORDS(TEMPTYPE),
-/*  	INF_BYTES(CIS), */
-	INF_WORDS(STAID),
-	INF_STRING(CURRENTSSID),
-	INF_BYTES(CURRENTBSSID),
-	INF_WORDS(COMMSQUALITY),
-	INF_WORDS(CURRENTTXRATE),
-	INF_WORDS(CURRENTBEACONINTERVAL),
-	INF_WORDS(CURRENTSCALETHRESHOLDS),
-	INF_WORDS(PROTOCOLRSPTIME),
-	INF_WORDS(SHORTRETRYLIMIT),
-	INF_WORDS(LONGRETRYLIMIT),
-	INF_WORDS(MAXTRANSMITLIFETIME),
-	INF_WORDS(MAXRECEIVELIFETIME),
-	INF_WORDS(CFPOLLABLE),
-	INF_WORDS(AUTHENTICATIONALGORITHMS),
-	INF_WORDS(PRIVACYOPTIONIMPLEMENTED),
-	INF_BYTES(OWNMACADDR),
-	INF_WORDS(SCANRESULTSTABLE),
-	INF_WORDS(PHYTYPE),
-	INF_WORDS(CURRENTCHANNEL),
-	INF_WORDS(CURRENTPOWERSTATE),
-	INF_WORDS(CCAMODE),
-	INF_WORDS(SUPPORTEDDATARATES),
-	INF_BYTES(BUILDSEQ),
-	INF_XSTRING(FWID)
-#undef INF_WORDS
-#undef INF_BYTES
-#undef INF_STRING
+#define PROC_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
+	PROC_REC(CNFPORTTYPE,WORDS),
+	PROC_REC(CNFOWNMACADDR,BYTES),
+	PROC_REC(CNFDESIREDSSID,STRING),
+	PROC_REC(CNFOWNCHANNEL,WORDS),
+	PROC_REC(CNFOWNSSID,STRING),
+	PROC_REC(CNFOWNATIMWINDOW,WORDS),
+	PROC_REC(CNFSYSTEMSCALE,WORDS),
+	PROC_REC(CNFMAXDATALEN,WORDS),
+	PROC_REC(CNFPMENABLED,WORDS),
+	PROC_REC(CNFPMEPS,WORDS),
+	PROC_REC(CNFMULTICASTRECEIVE,WORDS),
+	PROC_REC(CNFMAXSLEEPDURATION,WORDS),
+	PROC_REC(CNFPMHOLDOVERDURATION,WORDS),
+	PROC_REC(CNFOWNNAME,STRING),
+	PROC_REC(CNFOWNDTIMPERIOD,WORDS),
+	PROC_REC(CNFMULTICASTPMBUFFERING,WORDS),
+	PROC_REC(CNFWEPENABLED_AGERE,WORDS),
+	PROC_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
+	PROC_REC(CNFWEPDEFAULTKEYID,WORDS),
+	PROC_REC(CNFDEFAULTKEY0,BYTES),
+	PROC_REC(CNFDEFAULTKEY1,BYTES),
+	PROC_REC(CNFMWOROBUST_AGERE,WORDS),
+	PROC_REC(CNFDEFAULTKEY2,BYTES),
+	PROC_REC(CNFDEFAULTKEY3,BYTES),
+	PROC_REC(CNFWEPFLAGS_INTERSIL,WORDS),
+	PROC_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
+	PROC_REC(CNFAUTHENTICATION,WORDS),
+	PROC_REC(CNFMAXASSOCSTA,WORDS),
+	PROC_REC(CNFKEYLENGTH_SYMBOL,WORDS),
+	PROC_REC(CNFTXCONTROL,WORDS),
+	PROC_REC(CNFROAMINGMODE,WORDS),
+	PROC_REC(CNFHOSTAUTHENTICATION,WORDS),
+	PROC_REC(CNFRCVCRCERROR,WORDS),
+	PROC_REC(CNFMMLIFE,WORDS),
+	PROC_REC(CNFALTRETRYCOUNT,WORDS),
+	PROC_REC(CNFBEACONINT,WORDS),
+	PROC_REC(CNFAPPCFINFO,WORDS),
+	PROC_REC(CNFSTAPCFINFO,WORDS),
+	PROC_REC(CNFPRIORITYQUSAGE,WORDS),
+	PROC_REC(CNFTIMCTRL,WORDS),
+	PROC_REC(CNFTHIRTY2TALLY,WORDS),
+	PROC_REC(CNFENHSECURITY,WORDS),
+	PROC_REC(CNFGROUPADDRESSES,BYTES),
+	PROC_REC(CNFCREATEIBSS,WORDS),
+	PROC_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
+	PROC_REC(CNFRTSTHRESHOLD,WORDS),
+	PROC_REC(CNFTXRATECONTROL,WORDS),
+	PROC_REC(CNFPROMISCUOUSMODE,WORDS),
+	PROC_REC(CNFBASICRATES_SYMBOL,WORDS),
+	PROC_REC(CNFPREAMBLE_SYMBOL,WORDS),
+	PROC_REC(CNFSHORTPREAMBLE,WORDS),
+	PROC_REC(CNFWEPKEYS_AGERE,BYTES),
+	PROC_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
+	PROC_REC(CNFTXKEY_AGERE,WORDS),
+	PROC_REC(CNFAUTHENTICATIONRSPTO,WORDS),
+	PROC_REC(CNFBASICRATES,WORDS),
+	PROC_REC(CNFSUPPORTEDRATES,WORDS),
+	PROC_REC(CNFTICKTIME,WORDS),
+	PROC_REC(CNFSCANREQUEST,WORDS),
+	PROC_REC(CNFJOINREQUEST,WORDS),
+	PROC_REC(CNFAUTHENTICATESTATION,WORDS),
+	PROC_REC(CNFCHANNELINFOREQUEST,WORDS),
+	PROC_REC(MAXLOADTIME,WORDS),
+	PROC_REC(DOWNLOADBUFFER,WORDS),
+	PROC_REC(PRIID,WORDS),
+	PROC_REC(PRISUPRANGE,WORDS),
+	PROC_REC(CFIACTRANGES,WORDS),
+	PROC_REC(NICSERNUM,WORDS),
+	PROC_REC(NICID,WORDS),
+	PROC_REC(MFISUPRANGE,WORDS),
+	PROC_REC(CFISUPRANGE,WORDS),
+	PROC_REC(CHANNELLIST,WORDS),
+	PROC_REC(REGULATORYDOMAINS,WORDS),
+	PROC_REC(TEMPTYPE,WORDS),
+/*  	PROC_REC(CIS,BYTES), */
+	PROC_REC(STAID,WORDS),
+	PROC_REC(CURRENTSSID,STRING),
+	PROC_REC(CURRENTBSSID,BYTES),
+	PROC_REC(COMMSQUALITY,WORDS),
+	PROC_REC(CURRENTTXRATE,WORDS),
+	PROC_REC(CURRENTBEACONINTERVAL,WORDS),
+	PROC_REC(CURRENTSCALETHRESHOLDS,WORDS),
+	PROC_REC(PROTOCOLRSPTIME,WORDS),
+	PROC_REC(SHORTRETRYLIMIT,WORDS),
+	PROC_REC(LONGRETRYLIMIT,WORDS),
+	PROC_REC(MAXTRANSMITLIFETIME,WORDS),
+	PROC_REC(MAXRECEIVELIFETIME,WORDS),
+	PROC_REC(CFPOLLABLE,WORDS),
+	PROC_REC(AUTHENTICATIONALGORITHMS,WORDS),
+	PROC_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
+	PROC_REC(OWNMACADDR,BYTES),
+	PROC_REC(SCANRESULTSTABLE,WORDS),
+	PROC_REC(PHYTYPE,WORDS),
+	PROC_REC(CURRENTCHANNEL,WORDS),
+	PROC_REC(CURRENTPOWERSTATE,WORDS),
+	PROC_REC(CCAMODE,WORDS),
+	PROC_REC(SUPPORTEDDATARATES,WORDS),
+	PROC_REC(BUILDSEQ,BYTES),
+	PROC_REC(FWID,XSTRING)
+#undef PROC_REC
 };
 #define NUM_RIDS ( sizeof(record_table) / sizeof(record_table[0]) )
 
@@ -3726,36 +3698,31 @@
 			   int requested_len, int *eof, void *data)
 {
 	struct orinoco_private *priv = (struct orinoco_private *)data;
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
-	char *buf;
+	char *buf = page;
 	int total = 0, slop = 0;
-	int i;
+	u8 *val8;
+	u16 *val16;
+	int i,j;
 	u16 length;
 	int err;
 
-	/* Hum, in this case hardware register are probably not readable... */
 	if (! netif_device_present(dev))
 		return -ENODEV;
-		
-	buf = page;
 
-	/* print out all the config RIDs */
+	val8 = kmalloc(PROC_LTV_SIZE + 2, GFP_KERNEL);
+	if (! val8)
+		return -ENOMEM;
+	val16 = (u16 *)val8;
+
 	for (i = 0; i < NUM_RIDS; i++) {
 		u16 rid = record_table[i].rid;
-		int minlen = record_table[i].minlen;
-		int maxlen = record_table[i].maxlen;
 		int len;
-		u8 *val8;
-		u16 *val16;
-		int j;
-
-		val8 = kmalloc(maxlen + 2, GFP_KERNEL);
-		if (! val8)
-			return -ENOMEM;
-		memset(val8, 0, maxlen + 2);
 
-		err = hermes_read_ltv(hw, USER_BAP, rid, maxlen,
+		memset(val8, 0, PROC_LTV_SIZE + 2);
+
+		err = hermes_read_ltv(hw, USER_BAP, rid, PROC_LTV_SIZE,
 				      &length, val8);
 		if (err) {
 			DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
@@ -3767,7 +3734,7 @@
 
 		buf += sprintf(buf, "%-15s (0x%04x): length=%d (%d bytes)\tvalue=", record_table[i].name,
 			       rid, length, (length-1)*2);
-		len = min( (int)max(minlen, ((int)length-1)*2), maxlen);
+		len = min(((int)length-1)*2, PROC_LTV_SIZE);
 
 		switch (record_table[i].displaytype) {
 		case DISPLAY_WORDS:
@@ -3790,14 +3757,67 @@
 			val8[len] = '\0';
 			buf += sprintf(buf, "\"%s\"", (char *)&val16[1]);
 			break;
+
 		case DISPLAY_XSTRING:
-			
 			buf += sprintf(buf, "'%s'", (char *)val8);
 		}
 
 		buf += sprintf(buf, "\n");
 
-		kfree(val8);
+		if (shift_buffer(page, requested_offset, requested_len,
+				 &total, &slop, &buf))
+			break;
+
+		if ( (buf - page) > PROC_SAFE_SIZE )
+			break;
+	}
+
+	kfree(val8);
+
+	return calc_start_len(page, start, requested_offset, requested_len,
+			      total, buf);
+}
+
+#ifdef HERMES_DEBUG_BUFFER
+static int
+orinoco_proc_get_hermes_buf(char *page, char **start, off_t requested_offset,
+			    int requested_len, int *eof, void *data)
+{
+	struct orinoco_private *priv = (struct orinoco_private *)data;
+	hermes_t *hw = &priv->hw;
+	char *buf = page;
+	int total = 0, slop = 0;
+	int i;
+
+	for (i = 0; i < min_t(int,hw->dbufp, HERMES_DEBUG_BUFSIZE); i++) {
+		memcpy(buf, &hw->dbuf[i], sizeof(hw->dbuf[i]));
+		buf += sizeof(hw->dbuf[i]);
+
+		if (shift_buffer(page, requested_offset, requested_len,
+				 &total, &slop, &buf))
+			break;
+
+		if ( (buf - page) > PROC_SAFE_SIZE )
+			break;
+	}
+
+	return calc_start_len(page, start, requested_offset, requested_len,
+			      total, buf);
+}
+
+static int
+orinoco_proc_get_hermes_prof(char *page, char **start, off_t requested_offset,
+			    int requested_len, int *eof, void *data)
+{
+	struct orinoco_private *priv = (struct orinoco_private *)data;
+	hermes_t *hw = &priv->hw;
+	char *buf = page;
+	int total = 0, slop = 0;
+	int i;
+
+	for (i = 0; i < (HERMES_BAP_BUSY_TIMEOUT+1); i++) {
+		memcpy(buf, &hw->profile[i], sizeof(hw->profile[i]));
+		buf += sizeof(hw->profile[i]);
 
 		if (shift_buffer(page, requested_offset, requested_len,
 				 &total, &slop, &buf))
@@ -3810,6 +3830,7 @@
 	return calc_start_len(page, start, requested_offset, requested_len,
 			      total, buf);
 }
+#endif /* HERMES_DEBUG_BUFFER */
 
 /* initialise the /proc subsystem for the hermes driver, creating the
  * separate entries */
@@ -3836,32 +3857,41 @@
 int
 orinoco_proc_dev_init(struct orinoco_private *priv)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
+	struct proc_dir_entry *e;
 
 	priv->dir_dev = NULL;
+
 	/* create the directory for it to sit in */
 	priv->dir_dev = create_proc_entry(dev->name, S_IFDIR | S_IRUGO | S_IXUGO,
 					  dir_base);
-	if (priv->dir_dev == NULL) {
-		printk(KERN_ERR "Unable to initialise /proc/hermes/%s.\n",  dev->name);
+	if (! priv->dir_dev) {
+		printk(KERN_ERR "Unable to initialize /proc/hermes/%s\n",  dev->name);
+		goto fail;
+	}
+
+	e = create_proc_read_entry("recs", S_IFREG | S_IRUGO,
+			       priv->dir_dev, orinoco_proc_get_hermes_recs, priv);
+	if (! e) {
+		printk(KERN_ERR "Unable to initialize /proc/hermes/%s/recs\n",  dev->name);
 		goto fail;
 	}
 
-	priv->dir_regs = NULL;
-	priv->dir_regs = create_proc_read_entry("regs", S_IFREG | S_IRUGO,
-						priv->dir_dev, orinoco_proc_get_hermes_regs, priv);
-	if (priv->dir_regs == NULL) {
-		printk(KERN_ERR "Unable to initialise /proc/hermes/%s/regs.\n",  dev->name);
+#ifdef HERMES_DEBUG_BUFFER
+	e = create_proc_read_entry("buf", S_IFREG | S_IRUGO,
+					       priv->dir_dev, orinoco_proc_get_hermes_buf, priv);
+	if (! e) {
+		printk(KERN_ERR "Unable to intialize /proc/hermes/%s/buf\n", dev->name);
 		goto fail;
 	}
 
-	priv->dir_recs = NULL;
-	priv->dir_recs = create_proc_read_entry("recs", S_IFREG | S_IRUGO,
-						priv->dir_dev, orinoco_proc_get_hermes_recs, priv);
-	if (priv->dir_recs == NULL) {
-		printk(KERN_ERR "Unable to initialise /proc/hermes/%s/recs.\n",  dev->name);
+	e = create_proc_read_entry("prof", S_IFREG | S_IRUGO,
+					       priv->dir_dev, orinoco_proc_get_hermes_prof, priv);
+	if (! e) {
+		printk(KERN_ERR "Unable to intialize /proc/hermes/%s/prof\n", dev->name);
 		goto fail;
 	}
+#endif /* HERMES_DEBUG_BUFFER */
 
 	return 0;
  fail:
@@ -3872,24 +3902,19 @@
 void
 orinoco_proc_dev_cleanup(struct orinoco_private *priv)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
-	if (priv->dir_regs) {
-		remove_proc_entry("regs", priv->dir_dev);
-		priv->dir_regs = NULL;
-	}		
-	if (priv->dir_recs) {
-		remove_proc_entry("recs", priv->dir_dev);
-		priv->dir_recs = NULL;
-	}		
 	if (priv->dir_dev) {
+		remove_proc_entry("prof", priv->dir_dev);
+		remove_proc_entry("buf", priv->dir_dev);
+		remove_proc_entry("recs", priv->dir_dev);
 		remove_proc_entry(dev->name, dir_base);
 		priv->dir_dev = NULL;
 	}
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 }
 
 static void
@@ -3905,45 +3930,51 @@
 	TRACE_EXIT("orinoco");
 }
 
-int
-orinoco_setup(struct orinoco_private* priv)
+struct net_device *alloc_orinocodev(int sizeof_card)
 {
-	struct net_device *dev = &priv->ndev;;
-
-	spin_lock_init(&priv->lock);
+	struct net_device *dev;
+	struct orinoco_private *priv;
 
-	/* Set up the net_device */
-	ether_setup(dev);
-	dev->priv = priv;
+	TRACE_ENTER("orinoco");
+	dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
+	priv = (struct orinoco_private *)dev->priv;
+	priv->ndev = dev;
+	if (sizeof_card)
+		priv->card = (void *)((unsigned long)dev->priv + sizeof(struct orinoco_private));
+	else
+		priv->card = NULL;
 
-	/* Setup up default routines */
-	priv->card_reset_handler = NULL;	/* Caller may override */
+	/* Setup / override net_device fields */
 	dev->init = orinoco_init;
-	dev->open = NULL;		/* Caller *must* override */
-	dev->stop = NULL;
 	dev->hard_start_xmit = orinoco_xmit;
 	dev->tx_timeout = orinoco_tx_timeout;
 	dev->watchdog_timeo = HZ; /* 1 second timeout */
-
 	dev->get_stats = orinoco_get_stats;
 	dev->get_wireless_stats = orinoco_get_wireless_stats;
-
 	dev->do_ioctl = orinoco_ioctl;
-
 	dev->change_mtu = orinoco_change_mtu;
 	dev->set_multicast_list = orinoco_set_multicast_list;
 
-	netif_stop_queue(dev);
+	dev->open = NULL;		/* Caller *must* override  these */
+	dev->stop = NULL;
+
+	/* Setup the private structure */
+
+	spin_lock_init(&priv->lock);
+	priv->hard_reset = NULL;	/* Caller may override */
+	
+	TRACE_EXIT("orinoco");
+	return dev;
 
-	return 0;
 }
 
-#ifdef ORINOCO_DEBUG
-EXPORT_SYMBOL(orinoco_debug);
-#endif
+/********************************************************************/
+/* module bookkeeping                                               */
+/********************************************************************/
+
+EXPORT_SYMBOL(alloc_orinocodev);
 EXPORT_SYMBOL(orinoco_shutdown);
 EXPORT_SYMBOL(orinoco_reset);
-EXPORT_SYMBOL(orinoco_setup);
 EXPORT_SYMBOL(orinoco_proc_dev_init);
 EXPORT_SYMBOL(orinoco_proc_dev_cleanup);
 EXPORT_SYMBOL(orinoco_interrupt);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/orinoco.h linux/drivers/net/wireless/orinoco.h
--- linux.orig/drivers/net/wireless/orinoco.h	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wireless/orinoco.h	2002-07-20 01:08:31.000000000 +0000
@@ -28,18 +28,17 @@
 /*====================================================================*/
 
 struct orinoco_private {
-	void* card;	/* Pointer to card dependant structure */
+	void *card;	/* Pointer to card dependant structure */
 	/* card dependant extra reset code (i.e. bus/interface specific */
-	int (*card_reset_handler)(struct orinoco_private *);
+	int (*hard_reset)(struct orinoco_private *);
 
 	spinlock_t lock;
 	long state;
 #define ORINOCO_STATE_INIRQ 0
 #define ORINOCO_STATE_DOIRQ 1
-	atomic_t queue_length;
 
 	/* Net device stuff */
-	struct net_device ndev;
+	struct net_device *ndev;
 	struct net_device_stats stats;
 	struct iw_statistics wstats;
 
@@ -52,23 +51,22 @@
 #define FIRMWARE_TYPE_AGERE 1
 #define FIRMWARE_TYPE_INTERSIL 2
 #define FIRMWARE_TYPE_SYMBOL 3
-	int has_ibss, has_port3, prefer_port3, has_ibss_any, ibss_port;
+	int has_ibss, has_port3, has_ibss_any, ibss_port;
 	int has_wep, has_big_wep;
 	int has_mwo;
 	int has_pm;
 	int has_preamble;
-	int need_card_reset, broken_reset, broken_allocate;
+	int has_sensitivity;
+	int nicbuf_size;
+	int broken_cor_reset;
 	u16 channel_mask;
 
-	/* Current configuration */
+	/* Configuration paramaters */
 	u32 iw_mode;
-	int port_type, allow_ibss;
-
+	int prefer_port3;
 	u16 wep_on, wep_restrict, tx_key;
 	orinoco_keys_t keys;
-
 	int bitratemode;
-
  	char nick[IW_ESSID_MAX_SIZE+1];
 	char desired_essid[IW_ESSID_MAX_SIZE+1];
 	u16 frag_thresh, mwo_robust;
@@ -76,19 +74,19 @@
 	u16 ap_density, rts_thresh;
 	u16 pm_on, pm_mcast, pm_period, pm_timeout;
 	u16 preamble;
-
-	int promiscuous, mc_count;
-
 #ifdef WIRELESS_SPY
 	int			spy_number;
 	u_char			spy_address[IW_MAX_SPY][ETH_ALEN];
 	struct iw_quality	spy_stat[IW_MAX_SPY];
 #endif
 
+	/* Configuration dependent variables */
+	int port_type, allow_ibss;
+	int promiscuous, mc_count;
+
+
 	/* /proc based debugging stuff */
 	struct proc_dir_entry *dir_dev;
-	struct proc_dir_entry *dir_regs;
-	struct proc_dir_entry *dir_recs;
 };
 
 /*====================================================================*/
@@ -109,19 +107,10 @@
 
 #define RUP_EVEN(a) ( (a) % 2 ? (a) + 1 : (a) )
 
-/* struct net_device methods */
-extern int orinoco_init(struct net_device *dev);
-extern int orinoco_xmit(struct sk_buff *skb, struct net_device *dev);
-extern void orinoco_tx_timeout(struct net_device *dev);
-
-extern int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-extern int orinoco_change_mtu(struct net_device *dev, int new_mtu);
-extern void orinoco_set_multicast_list(struct net_device *dev);
-
 /* utility routines */
+struct net_device *alloc_orinocodev(int sizeof_card);
 extern void orinoco_shutdown(struct orinoco_private *dev);
 extern int orinoco_reset(struct orinoco_private *dev);
-extern int orinoco_setup(struct orinoco_private* priv);
 extern int orinoco_proc_dev_init(struct orinoco_private *dev);
 extern void orinoco_proc_dev_cleanup(struct orinoco_private *priv);
 extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/orinoco_cs.c linux/drivers/net/wireless/orinoco_cs.c
--- linux.orig/drivers/net/wireless/orinoco_cs.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wireless/orinoco_cs.c	2002-07-20 01:08:39.000000000 +0000
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.09b	- (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.11b	- (formerly known as dldwd_cs.c)
  *
  * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
  * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -11,6 +11,9 @@
  */
 
 #include <linux/config.h>
+#ifdef  __IN_PCMCIA_PACKAGE__
+#include <pcmcia/k_compat.h>
+#endif /* __IN_PCMCIA_PACKAGE__ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -44,7 +47,7 @@
 
 /*====================================================================*/
 
-static char version[] __initdata = "orinoco_cs.c 0.09b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco_cs.c 0.11b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
@@ -60,7 +63,7 @@
 /* Newer, simpler way of listing specific interrupts */
 static int irq_list[4] = { -1 };
 /* Do a Pcmcia soft reset (may help some cards) */
-static int reset_cor = 0;
+static int reset_cor = -1;
 /* Some D-Link cards have buggy CIS. They do work at 5v properly, but
  * don't have any CIS entry for it. This workaround it... */
 static int ignore_cis_vcc; /* = 0 */
@@ -74,9 +77,6 @@
 struct orinoco_pccard {
 	dev_link_t link;
 	dev_node_t node;
-
-	/* Common structure (fully included), see orinoco.h */
-	struct orinoco_private  priv;
 };
 
 /*
@@ -101,7 +101,6 @@
    device driver with appropriate cards, through the card configuration
    database.
 */
-
 static dev_info_t dev_info = "orinoco_cs";
 
 /*
@@ -133,7 +132,7 @@
 	dev_link_t *link = &card->link;
 	int err;
 	
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(dev->name);
 
 	link->open++;
 	netif_device_attach(dev);
@@ -144,7 +143,7 @@
 	else
 		netif_start_queue(dev);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(dev->name);
 
 	return err;
 }
@@ -156,7 +155,7 @@
 	struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
 	dev_link_t *link = &card->link;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(dev->name);
 
 	netif_stop_queue(dev);
 
@@ -167,7 +166,7 @@
 	if (link->state & DEV_STALE_CONFIG)
 		mod_timer(&link->release, jiffies + HZ/20);
 	
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(dev->name);
 	
 	return 0;
 }
@@ -185,7 +184,7 @@
 	conf_reg_t reg;
 	u_int default_cor; 
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	/* Doing it if hardware is gone is guaranteed crash */
 	if(! (link->state & DEV_CONFIG) )
@@ -211,7 +210,23 @@
 	/* FIXME: mdelay() is deprecated -dgibson */
 	mdelay(1);
 
+#if 0 /* This seems to help on Symbol cards, but we're not sure why,
+       and we don't know what it will do to other cards */
+	reg.Action = CS_READ;
+	reg.Offset = CISREG_CCSR;
+	CardServices(AccessConfigurationRegister, link->handle, &reg);
+
+	/* Write 7 (RUN) to CCSR, but preserve the original bit 4 */
+	reg.Action = CS_WRITE;
+	reg.Offset = CISREG_CCSR;
+	reg.Value = 7 | (reg.Value & 0x10);
+	CardServices(AccessConfigurationRegister, link->handle, &reg);
+	mdelay(1);
+#endif
+
 	/* Restore original COR configuration index */
+	reg.Action = CS_WRITE;
+	reg.Offset = CISREG_COR;
 	reg.Value = (default_cor & ~COR_SOFT_RESET);
 	CardServices(AccessConfigurationRegister, link->handle, &reg);
 
@@ -219,11 +234,32 @@
 	/* FIXME: mdelay() is deprecated -dgibson */
 	mdelay(1);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return 0;
 }
 
+static int
+orinoco_cs_hard_reset(struct orinoco_private *priv)
+{
+	if (! priv->broken_cor_reset)
+		return orinoco_cs_cor_reset(priv);
+	else
+		return 0;
+
+#if 0 /* We'd like to use ResetCard, but we can't for the moment - it sleeps */
+	/* Not sure what the second parameter is supposed to be - the 
+	   PCMCIA code doesn't actually use it */
+	if (in_interrupt()) {
+		printk("Not resetting card, in_interrupt() is true\n");
+		return 0;
+	} else {
+		printk("Doing ResetCard\n");
+		return CardServices(ResetCard, link->handle, NULL);
+	}
+#endif
+}
+
 /* Remove zombie instances (card removed, detach pending) */
 static void
 flush_stale_links(void)
@@ -251,10 +287,10 @@
 static dev_link_t *
 orinoco_cs_attach(void)
 {
-	struct orinoco_pccard *card;
+	struct net_device *dev;
 	struct orinoco_private *priv;
+	struct orinoco_pccard *card;
 	dev_link_t *link;
-	struct net_device *ndev;
 	client_reg_t client_reg;
 	int ret, i;
 
@@ -262,19 +298,18 @@
 	/* A bit of cleanup */
 	flush_stale_links();
 
-	/* Allocate space for private device-specific data */
-	card = kmalloc(sizeof(*card), GFP_KERNEL);
-	if (! card) {
-		link = NULL;
-		goto out;
-	}
-	memset(card, 0, sizeof(*card));
+	dev = alloc_orinocodev(sizeof(*card));
+	if (! dev)
+		return NULL;
+	priv = dev->priv;
+	card = priv->card;
+	/* Overrides */
+	dev->open = orinoco_cs_open;
+	dev->stop = orinoco_cs_stop;
+	priv->hard_reset = orinoco_cs_hard_reset;
 
-	/* Link both structure together */
-	priv = &(card->priv);
-	priv->card = card;
+	/* Link both structures together */
 	link = &card->link;
-	ndev = &priv->ndev;
 	link->priv = priv;
 
 	/* Initialize the dev_link_t structure */
@@ -301,17 +336,6 @@
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Setup the common part */
-	if(orinoco_setup(priv) < 0) {
-		kfree(card);
-		return NULL;
-	}
-
-	/* Overrides */
-	ndev->open = orinoco_cs_open;
-	ndev->stop = orinoco_cs_stop;
-	priv->card_reset_handler = orinoco_cs_cor_reset;
-
 	/* Register with Card Services */
 	link->next = dev_list;
 	dev_list = link;
@@ -349,6 +373,7 @@
 {
 	dev_link_t **linkp;
 	struct orinoco_private *priv = link->priv;
+	struct net_device *dev = priv->ndev;
 
 	TRACE_ENTER("orinoco");
 
@@ -383,10 +408,10 @@
 	DEBUG(0, "orinoco_cs: detach: link=%p link->dev=%p\n", link, link->dev);
 	if (link->dev) {
 		DEBUG(0, "orinoco_cs: About to unregister net device %p\n",
-		      &priv->ndev);
-		unregister_netdev(&priv->ndev);
+		      priv->ndev);
+		unregister_netdev(dev);
 	}
-	kfree(priv->card);
+	kfree(dev);
 
  out:
 	TRACE_EXIT("orinoco");
@@ -411,7 +436,7 @@
 	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = (struct orinoco_pccard *)priv->card;
 	hermes_t *hw = &priv->hw;
-	struct net_device *ndev = &priv->ndev;
+	struct net_device *ndev = priv->ndev;
 	tuple_t tuple;
 	cisparse_t parse;
 	int last_fn, last_ret;
@@ -486,15 +511,13 @@
 		/* Use power settings for Vcc and Vpp if present */
 		/*  Note that the CIS values need to be rescaled */
 		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-			if (conf.Vcc !=
-			    cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
 				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
-				if(!ignore_cis_vcc)
+				if (!ignore_cis_vcc)
 					goto next_entry;
 			}
 		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
-			if (conf.Vcc !=
-			    dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
+			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
 				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
 				if(!ignore_cis_vcc)
 					goto next_entry;
@@ -549,7 +572,12 @@
 	next_entry:
 		if (link->io.NumPorts1)
 			CardServices(ReleaseIO, link->handle, &link->io);
-		CS_CHECK(GetNextTuple, handle, &tuple);
+		last_ret = CardServices(GetNextTuple, handle, &tuple);
+		if (last_ret  == CS_NO_MORE_ITEMS) {
+			printk(KERN_ERR "GetNextTuple().  No matching CIS configuration, "
+			       "maybe you need the ignore_cis_vcc=1 parameter.\n");
+			goto cs_failed;
+		}
 	}
 
 	/*
@@ -577,7 +605,8 @@
 	/* We initialize the hermes structure before completing PCMCIA
 	   configuration just in case the interrupt handler gets
 	   called. */
-	hermes_struct_init(hw, link->io.BasePort1);
+	hermes_struct_init(hw, link->io.BasePort1,
+				HERMES_IO, HERMES_16BIT_REGSPACING);
 
 	/*
 	   This actually configures the PCMCIA socket -- setting up
@@ -589,12 +618,6 @@
 	ndev->base_addr = link->io.BasePort1;
 	ndev->irq = link->irq.AssignedIRQ;
 
-	/* Now do a PCMCIA soft reset on the card, to make sure its in
-	   a sane state */
-	/* Optional because it really mess up old Lucent firmwares - Jean II */
-	if (reset_cor)
-		orinoco_cs_cor_reset(priv);
-
 	/* register_netdev will give us an ethX name */
 	ndev->name[0] = '\0';
 	/* Tell the stack we exist */
@@ -631,9 +654,9 @@
 	/* Note to myself : this replace MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT */
 	SET_MODULE_OWNER(ndev);
 	
-	/* Do a Pcmcia soft reset of the card (optional) */
-	if (reset_cor)
-		orinoco_cs_cor_reset(priv);
+	/* Let reset_cor parameter override determine_firmware()'s guess */
+	if (reset_cor != -1)
+		priv->broken_cor_reset = ! reset_cor;
 
 	/*
 	   At this point, the dev_node_t structure(s) need to be
@@ -711,7 +734,7 @@
 {
 	dev_link_t *link = args->client_data;
 	struct orinoco_private *priv = (struct orinoco_private *)link->priv;
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 
 	TRACE_ENTER("orinoco");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/orinoco_pci.c linux/drivers/net/wireless/orinoco_pci.c
--- linux.orig/drivers/net/wireless/orinoco_pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/net/wireless/orinoco_pci.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,391 @@
+/* orinoco_pci.c 0.01
+ * 
+ * Driver for Prism II devices that have a direct PCI interface
+ * (i.e., not in a Pcmcia or PLX bridge)
+ *
+ * Specifically here we're talking about the Linksys WMP11
+ *
+ * Some of this code is borrowed from orinoco_plx.c
+ *	Copyright (C) 2001 Daniel Barlow <dan@telent.net>
+ * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
+ * has been copied from it. linux-wlan-ng-0.1.10 is originally :
+ *	Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+ * The rest is :
+ *	Copyright (C) 2001 Jean Tourrilhes <jt@hpl.hp.com>
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+/*
+ * Theory of operation...
+ * -------------------
+ * Maybe you had a look in orinoco_plx. Well, this is totally different...
+ *
+ * The card contains only one PCI region, which contains all the usual
+ * hermes registers.
+ *
+ * The driver will memory map this region in normal memory. Because
+ * the hermes registers are mapped in normal memory and not in ISA I/O
+ * post space, we can't use the usual inw/outw macros and we need to
+ * use readw/writew.
+ * This slight difference force us to compile our own version of
+ * hermes.c with the register access macro changed. That's a bit
+ * hackish but works fine.
+ *
+ * Note that the PCI region is pretty big (4K). That's much more than
+ * the usual set of hermes register (0x0 -> 0x3E). I've got a strong
+ * suspicion that the whole memory space of the adapter is in fact in
+ * this region. Accessing directly the adapter memory instead of going
+ * through the usual register would speed up significantely the
+ * operations...
+ *
+ * Finally, the card looks like this :
+-----------------------
+  Bus  0, device  14, function  0:
+    Network controller: PCI device 1260:3873 (Harris Semiconductor) (rev 1).
+      IRQ 11.
+      Master Capable.  Latency=248.  
+      Prefetchable 32 bit memory at 0xffbcc000 [0xffbccfff].
+-----------------------
+00:0e.0 Network controller: Harris Semiconductor: Unknown device 3873 (rev 01)
+        Subsystem: Unknown device 1737:3874
+        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
+        Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
+        Latency: 248 set, cache line size 08
+        Interrupt: pin A routed to IRQ 11
+        Region 0: Memory at ffbcc000 (32-bit, prefetchable) [size=4K]
+        Capabilities: [dc] Power Management version 2
+                Flags: PMEClk- AuxPwr- DSI- D1+ D2+ PME+
+                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
+-----------------------
+ *
+ * That's all..
+ *
+ * Jean II
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <linux/proc_fs.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/wireless.h>
+#include <linux/fcntl.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+/* All the magic there is from wlan-ng */
+/* Magic offset of the reset register of the PCI card */
+#define HERMES_PCI_COR		(0x26)
+/* Magic bitmask to reset the card */
+#define HERMES_PCI_COR_MASK	(0x0080)
+/* Magic timeouts for doing the reset.
+ * Those times are straight from wlan-ng, and it is claimed that they
+ * are necessary. Alan will kill me. Take your time and grab a coffee. */
+#define HERMES_PCI_COR_ONT	(250)		/* ms */
+#define HERMES_PCI_COR_OFFT	(500)		/* ms */
+#define HERMES_PCI_COR_BUSYT	(500)		/* ms */
+
+MODULE_AUTHOR("Jean Tourrilhes <jt@hpl.hp.com>");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int orinoco_pci_open(struct net_device *dev)
+{
+	struct orinoco_private *priv = (struct orinoco_private *) dev->priv;
+	int err;
+
+	netif_device_attach(dev);
+
+	err = orinoco_reset(priv);
+	if (err)
+		printk(KERN_ERR "%s: orinoco_reset failed in orinoco_pci_open()",
+		       dev->name);
+	else
+		netif_start_queue(dev);
+
+	return err;
+}
+
+static int orinoco_pci_stop(struct net_device *dev)
+{
+	struct orinoco_private *priv = (struct orinoco_private *) dev->priv;
+	netif_stop_queue(dev);
+	orinoco_shutdown(priv);
+	return 0;
+}
+
+static void
+orinoco_pci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	orinoco_interrupt(irq, (struct orinoco_private *)dev_id, regs);
+}
+
+/*
+ * Do a soft reset of the PCI card using the Configuration Option Register
+ * We need this to get going...
+ * This is the part of the code that is strongly inspired from wlan-ng
+ *
+ * Note : This code is done with irq enabled. This mean that many
+ * interrupts will occur while we are there. This is why we use the
+ * jiffies to regulate time instead of a straight mdelay(). Usually we
+ * need only around 245 iteration of the loop to do 250 ms delay.
+ *
+ * Note bis : Don't try to access HERMES_CMD during the reset phase.
+ * It just won't work !
+ */
+static int
+orinoco_pci_cor_reset(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	unsigned long	timeout;
+	u16	reg;
+
+	TRACE_ENTER(priv->ndev->name);
+
+
+	/* Assert the reset until the card notice */
+	hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
+	printk(KERN_NOTICE "Reset done");
+	timeout = jiffies + (HERMES_PCI_COR_ONT * HZ / 1000);
+	while(time_before(jiffies, timeout)) {
+		printk(".");
+		mdelay(1);
+	}
+	printk(";\n");
+	//mdelay(HERMES_PCI_COR_ONT);
+
+	/* Give time for the card to recover from this hard effort */
+	hermes_write_regn(hw, PCI_COR, 0x0000);
+	printk(KERN_NOTICE "Clear Reset");
+	timeout = jiffies + (HERMES_PCI_COR_OFFT * HZ / 1000);
+	while(time_before(jiffies, timeout)) {
+		printk(".");
+		mdelay(1);
+	}
+	printk(";\n");
+	//mdelay(HERMES_PCI_COR_OFFT);
+
+	/* The card is ready when it's no longer busy */
+	timeout = jiffies + (HERMES_PCI_COR_BUSYT * HZ / 1000);
+	reg = hermes_read_regn(hw, CMD);
+	while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+		mdelay(1);
+		reg = hermes_read_regn(hw, CMD);
+	}
+	/* Did we timeout ? */
+	if(time_after_eq(jiffies, timeout)) {
+		printk(KERN_ERR "orinoco_pci: Busy timeout\n");
+		return -ETIMEDOUT;
+	}
+	printk(KERN_NOTICE "pci_cor : reg = 0x%X - %lX - %lX\n", reg, timeout, jiffies);
+
+	TRACE_EXIT(priv->ndev->name);
+
+	return 0;
+}
+
+/*
+ * Initialise a card. Mostly similar to PLX code.
+ */
+static int orinoco_pci_init_one(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	int err = 0;
+	unsigned long pci_iorange;
+	u16 *pci_ioaddr = NULL;
+	unsigned long pci_iolen;
+	struct orinoco_private *priv = NULL;
+	struct net_device *dev = NULL;
+	int netdev_registered = 0;
+
+	TRACE_ENTER("orinoco_pci");
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return -EIO;
+
+	/* Resource 0 is mapped to the hermes registers */
+	pci_iorange = pci_resource_start(pdev, 0);
+	pci_iolen = pci_resource_len(pdev, 0);
+	pci_ioaddr = ioremap(pci_iorange, pci_iolen);
+	if (! pci_iorange)
+		goto fail;
+
+	/* Usual setup of structures */
+	dev = alloc_orinocodev(0);
+	if (! dev) {
+		err = -ENOMEM;
+		goto fail;
+	}
+	priv = dev->priv;
+
+	dev->base_addr = (int) pci_ioaddr;
+        dev->mem_start = (unsigned long) pci_iorange;
+        dev->mem_end = ((unsigned long) pci_iorange) + pci_iolen - 1;
+	dev->open = orinoco_pci_open;
+	dev->stop = orinoco_pci_stop;
+/*  	priv->card_reset_handler = orinoco_pci_cor_reset; */
+
+	SET_MODULE_OWNER(dev);
+
+	printk(KERN_DEBUG
+	       "Detected Orinoco/Prism2 PCI device at %s, mem:0x%lX to 0x%lX -> 0x%p, irq:%d\n",
+	       pdev->slot_name, dev->mem_start, dev->mem_end, pci_ioaddr, pdev->irq);
+
+	hermes_struct_init(&(priv->hw), dev->base_addr, HERMES_MEM, HERMES_32BIT_REGSPACING);
+	pci_set_drvdata(pdev, dev);
+
+	err = request_irq(pdev->irq, orinoco_pci_interrupt, SA_SHIRQ, dev->name, priv);
+	if (err) {
+		printk(KERN_ERR "orinoco_pci: Error allocating IRQ %d.\n", pdev->irq);
+		err = -EBUSY;
+		goto fail;
+	}
+	dev->irq = pdev->irq;
+	/* Perform a COR reset to start the card */
+	if(orinoco_pci_cor_reset(priv) != 0) {
+		printk(KERN_ERR "%s: Failed to start the card\n", dev->name);
+		err = -ETIMEDOUT;
+		goto fail;
+	}
+
+	/* Override the normal firmware detection - the Prism 2.5 PCI
+	 * cards look like Lucent firmware but are actually Intersil */
+	priv->firmware_type = FIRMWARE_TYPE_INTERSIL;
+
+	err = register_netdev(dev);
+	if (err)
+		goto fail;
+	netdev_registered = 1;
+
+	err = orinoco_proc_dev_init(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Failed to create /proc node\n", dev->name);
+		err = -EIO;
+		goto fail;
+	}
+
+	TRACE_EXIT("orinoco_pci");
+
+        return 0;               /* succeeded */
+ fail:
+	printk(KERN_DEBUG "orinoco_pci: init_one(), FAIL!\n");
+
+	if (dev) {
+		orinoco_proc_dev_cleanup(priv);
+		if (netdev_registered)
+			unregister_netdev(dev);
+
+		if (dev->irq)
+			free_irq(dev->irq, priv);
+
+		kfree(dev);
+	}
+
+	if (pci_ioaddr)
+		iounmap(pci_ioaddr);
+
+	return err;
+}
+
+static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = dev->priv;
+
+	TRACE_ENTER("orinoco_pci");
+
+	if (! dev)
+		BUG();
+
+	orinoco_proc_dev_cleanup(priv);
+
+	unregister_netdev(dev);
+
+        if (dev->irq)
+		free_irq(dev->irq, priv);
+
+	if (priv->hw.iobase)
+		iounmap((unsigned char *) priv->hw.iobase);
+
+	kfree(dev);
+
+	pci_disable_device(pdev);
+
+	TRACE_EXIT("orinoco_pci");
+}
+
+
+static struct pci_device_id orinoco_pci_pci_id_table[] __devinitdata = {
+	{0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID,},
+	{0,},
+};
+
+MODULE_DEVICE_TABLE(pci, orinoco_pci_pci_id_table);
+
+static struct pci_driver orinoco_pci_driver = {
+	name:"orinoco_pci",
+	id_table:orinoco_pci_pci_id_table,
+	probe:orinoco_pci_init_one,
+	remove:__devexit_p(orinoco_pci_remove_one),
+	suspend:0,
+	resume:0
+};
+
+static int __init orinoco_pci_init(void)
+{
+	return pci_module_init(&orinoco_pci_driver);
+}
+
+extern void __exit orinoco_pci_exit(void)
+{
+	pci_unregister_driver(&orinoco_pci_driver);
+}
+
+module_init(orinoco_pci_init);
+module_exit(orinoco_pci_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/orinoco_plx.c linux/drivers/net/wireless/orinoco_plx.c
--- linux.orig/drivers/net/wireless/orinoco_plx.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/net/wireless/orinoco_plx.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,4 +1,4 @@
-/* orinoco_plx.c 0.09b
+/* orinoco_plx.c 0.11b
  * 
  * Driver for Prism II devices which would usually be driven by orinoco_cs,
  * but are connected to the PCI bus by a PLX9052. 
@@ -129,25 +129,19 @@
 #include <linux/wireless.h>
 #include <linux/fcntl.h>
 
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/bus_ops.h>
 
 #include "hermes.h"
 #include "orinoco.h"
 
-static char version[] __initdata = "orinoco_plx.c 0.09b (Daniel Barlow <dan@telent.net>)";
+static char version[] __initdata = "orinoco_plx.c 0.11b (Daniel Barlow <dan@telent.net>)";
 MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
 MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
 #ifdef MODULE_LICENSE
 MODULE_LICENSE("Dual MPL/GPL");
 #endif
 
-static dev_info_t dev_info = "orinoco_plx";
+static char dev_info[] = "orinoco_plx";
 
 #define COR_OFFSET    (0x3e0 / 2)	/* COR attribute offset of Prism2 PC card */
 #define COR_VALUE     (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
@@ -272,30 +266,25 @@
 		goto fail;
 	}
 
-	priv = kmalloc(sizeof(*priv), GFP_KERNEL);
-	if (! priv) {
+	dev = alloc_orinocodev(0);
+	if (! dev) {
 		err = -ENOMEM;
 		goto fail;
 	}
-	memset(priv, 0, sizeof(*priv));
 
-	dev = &priv->ndev;
-
-	err = orinoco_setup(priv);
-	if (err)
-		goto fail;
+	priv = dev->priv;
 	dev->base_addr = pccard_ioaddr;
 	dev->open = orinoco_plx_open;
 	dev->stop = orinoco_plx_stop;
-	priv->card_reset_handler = NULL; /* We have no reset handler */
 	SET_MODULE_OWNER(dev);
 
 	printk(KERN_DEBUG
 	       "Detected Orinoco/Prism2 PLX device at %s irq:%d, io addr:0x%lx\n",
 	       pdev->slot_name, pdev->irq, pccard_ioaddr);
 
-	hermes_struct_init(&(priv->hw), dev->base_addr);
-	pci_set_drvdata(pdev, priv);
+	hermes_struct_init(&(priv->hw), dev->base_addr,
+			HERMES_IO, HERMES_16BIT_REGSPACING);
+	pci_set_drvdata(pdev, dev);
 
 	err = request_irq(pdev->irq, orinoco_plx_interrupt, SA_SHIRQ, dev->name, priv);
 	if (err) {
@@ -348,12 +337,12 @@
 
 static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
 {
-	struct orinoco_private *priv = pci_get_drvdata(pdev);
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = dev->priv;
 
 	TRACE_ENTER("orinoco_plx");
 
-	if (!priv)
+	if (! dev)
 		BUG();
 
 	orinoco_proc_dev_cleanup(priv);
@@ -363,7 +352,7 @@
 	if (dev->irq)
 		free_irq(dev->irq, priv);
 		
-	kfree(priv);
+	kfree(dev);
 
 	release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
 
@@ -374,10 +363,9 @@
 
 
 static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = {
+	{0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,},	/* Siemens SpeedStream SS1023 */
 	{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},	/* Netgear MA301 */
-#if 0
-	{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},	/* Correga */
-#endif
+	{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},	/* Correga  - does this work? */
 	{0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},	/* SMC EZConnect SMC2602W,
 							   Eumitcom PCI WL11000,
 							   Addtron AWA-100*/
@@ -385,6 +373,9 @@
 	{0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,},	/* Reported working, but unknown */
 	{0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,},	/* Linksys WDT11 */
 	{0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,},	/* USR 2415 */
+	{0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,},	/* Belkin F5D6000 tested by
+							   Brendan W. McAdams <rit@jacked-in.org> */
+	{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},	/* Nortel emobility */
 	{0,},
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c
--- linux.orig/drivers/net/yellowfin.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/net/yellowfin.c	2002-07-20 01:08:33.000000000 +0000
@@ -125,6 +125,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
+#include <linux/crc32.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/unaligned.h>
@@ -1339,29 +1340,6 @@
 
 /* Set or clear the multicast filter for this adaptor. */
 
-/* The little-endian AUTODIN32 ethernet CRC calculation.
-   N.B. Do not use for bulk data, use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-	unsigned int crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-
-
 static void set_rx_mode(struct net_device *dev)
 {
 	struct yellowfin_private *yp = dev->priv;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/zlib.c linux/drivers/net/zlib.c
--- linux.orig/drivers/net/zlib.c	2001-04-18 21:40:04.000000000 +0000
+++ linux/drivers/net/zlib.c	2002-07-20 01:08:24.000000000 +0000
@@ -14,7 +14,7 @@
  */
 
 /* 
- *  ==FILEVERSION 971210==
+ *  ==FILEVERSION 20020318==
  *
  * This marker is used by the Linux installation script to determine
  * whether an up-to-date version of this file is already installed.
@@ -772,7 +772,7 @@
         windowBits = -windowBits;
     }
     if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
-        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
 	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
         return Z_STREAM_ERROR;
     }
@@ -3860,10 +3860,12 @@
                              &s->sub.trees.tb, z);
       if (t != Z_OK)
       {
-        ZFREE(z, s->sub.trees.blens);
         r = t;
         if (r == Z_DATA_ERROR)
+	{
+	  ZFREE(z, s->sub.trees.blens);
           s->mode = BADB;
+	}
         LEAVE
       }
       s->sub.trees.index = 0;
@@ -3928,11 +3930,13 @@
 #endif
         t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
                                   s->sub.trees.blens, &bl, &bd, &tl, &td, z);
-        ZFREE(z, s->sub.trees.blens);
         if (t != Z_OK)
         {
           if (t == (uInt)Z_DATA_ERROR)
+	  {
+	    ZFREE(z, s->sub.trees.blens);
             s->mode = BADB;
+	  }
           r = t;
           LEAVE
         }
@@ -3945,6 +3949,7 @@
           r = Z_MEM_ERROR;
           LEAVE
         }
+        ZFREE(z, s->sub.trees.blens);
         s->sub.decode.codes = c;
         s->sub.decode.tl = tl;
         s->sub.decode.td = td;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog
--- linux.orig/drivers/parport/ChangeLog	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/parport/ChangeLog	2002-07-20 01:08:38.000000000 +0000
@@ -1,3 +1,31 @@
+2002-04-25  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_serial.c, parport_pc.c: Move some SIIG cards around.
+	Patch from Andrey Panin.
+
+2001-12-07  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_pc.c (parport_pc_pci_probe): Hooks for PCI cards before
+	and after probing for ports.
+	* parport_serial.c (parport_register): Likewise.
+
+2002-01-20  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_pc.c (parport_pc_compat_write_block_pio,
+	parport_pc_ecp_write_block_pio, parport_pc_ecp_read_block_pio):
+	Use the default implementations if the caller wants to use
+	O_NONBLOCK.
+
+2002-01-21  Tim Waugh  <twaugh@redhat.com>
+
+	* daisy.c: Apply patch from Max Vorobiev to make parport_daisy_select
+	work for ECP/EPP modes.
+
+2002-02-25  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_pc.c: Make sure that priv->ctr_writable includes IntEn
+	even if IRQ is given as a parameter.
+
 2002-01-13  Niels Kristian Bech Jensen  <nkbj@image.dk>
 
 	* parport_pc.c: Change some occurrences of frob_set_mode to
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/parport/daisy.c linux/drivers/parport/daisy.c
--- linux.orig/drivers/parport/daisy.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/parport/daisy.c	2002-07-20 01:08:30.000000000 +0000
@@ -406,8 +406,33 @@
 
 int parport_daisy_select (struct parport *port, int daisy, int mode)
 {
-	/* mode is currently ignored. FIXME? */
-	return cpp_daisy (port, 0xe0 + daisy) & PARPORT_STATUS_ERROR;
+	switch (mode)
+	{
+		// For these modes we should switch to EPP mode:
+		case IEEE1284_MODE_EPP:
+		case IEEE1284_MODE_EPPSL:
+		case IEEE1284_MODE_EPPSWE:
+			return (cpp_daisy (port, 0x20 + daisy) &
+				PARPORT_STATUS_ERROR);
+
+		// For these modes we should switch to ECP mode:
+		case IEEE1284_MODE_ECP:
+		case IEEE1284_MODE_ECPRLE:
+		case IEEE1284_MODE_ECPSWE: 
+			return (cpp_daisy (port, 0xd0 + daisy) &
+				PARPORT_STATUS_ERROR);
+
+		// Nothing was told for BECP in Daisy chain specification.
+		// May be it's wise to use ECP?
+		case IEEE1284_MODE_BECP:
+		// Others use compat mode
+		case IEEE1284_MODE_NIBBLE:
+		case IEEE1284_MODE_BYTE:
+		case IEEE1284_MODE_COMPAT:
+		default:
+			return (cpp_daisy (port, 0xe0 + daisy) &
+				PARPORT_STATUS_ERROR);
+	}
 }
 
 static int mux_present (struct parport *port)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/parport/parport_mfc3.c linux/drivers/parport/parport_mfc3.c
--- linux.orig/drivers/parport/parport_mfc3.c	2001-05-23 02:54:04.000000000 +0000
+++ linux/drivers/parport/parport_mfc3.c	2002-07-20 01:08:32.000000000 +0000
@@ -408,6 +408,7 @@
 MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
 MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Paralllel Port");
 MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port");
+MODULE_LICENSE("GPL");
 
 module_init(parport_mfc3_init)
 module_exit(parport_mfc3_exit)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- linux.orig/drivers/parport/parport_pc.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/parport/parport_pc.c	2002-07-20 01:08:34.000000000 +0000
@@ -821,8 +821,9 @@
 	long int expire;
 	const struct parport_pc_private *priv = port->physport->private_data;
 
-	/* Special case: a timeout of zero means we cannot call schedule(). */
-	if (!port->physport->cad->timeout)
+	/* Special case: a timeout of zero means we cannot call schedule().
+	 * Also if O_NONBLOCK is set then use the default implementation. */
+	if (port->physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK)
 		return parport_ieee1284_write_compat (port, buf,
 						      length, flags);
 
@@ -897,8 +898,9 @@
 	long int expire;
 	const struct parport_pc_private *priv = port->physport->private_data;
 
-	/* Special case: a timeout of zero means we cannot call schedule(). */
-	if (!port->physport->cad->timeout)
+	/* Special case: a timeout of zero means we cannot call schedule().
+	 * Also if O_NONBLOCK is set then use the default implementation. */
+	if (port->physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK)
 		return parport_ieee1284_ecp_write_data (port, buf,
 							length, flags);
 
@@ -1017,8 +1019,9 @@
 DPRINTK (KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n");
 dump_parport_state ("enter fcn", port);
 
-	/* Special case: a timeout of zero means we cannot call schedule(). */
-	if (!port->cad->timeout)
+	/* Special case: a timeout of zero means we cannot call schedule().
+	 * Also if O_NONBLOCK is set then use the default implementation. */
+	if (port->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK)
 		return parport_ieee1284_ecp_read_data (port, buf,
 						       length, flags);
 
@@ -2139,8 +2142,6 @@
 {
 	struct parport_pc_private *priv = pb->private_data;
 
-	priv->ctr_writable |= 0x10;
-
 	if (priv->ecr) {
 		pb->irq = programmable_irq_support(pb);
 
@@ -2165,9 +2166,6 @@
 	if (pb->irq == PARPORT_IRQ_NONE)
 		pb->irq = get_superio_irq(pb);
 
-	if (pb->irq == PARPORT_IRQ_NONE)
-		priv->ctr_writable &= ~0x10;
-
 	return pb->irq;
 }
 
@@ -2296,6 +2294,7 @@
 	}
 	if (p->irq != PARPORT_IRQ_NONE) {
 		printk(", irq %d", p->irq);
+		priv->ctr_writable |= 0x10;
 
 		if (p->dma == PARPORT_DMA_AUTO) {
 			p->dma = PARPORT_DMA_NONE;
@@ -2654,25 +2653,10 @@
 
 
 enum parport_pc_pci_cards {
-	siig_1s1p_10x_550 = last_sio,
-	siig_1s1p_10x_650,
-	siig_1s1p_10x_850,
-	siig_1p_10x,
+	siig_1p_10x = last_sio,
 	siig_2p_10x,
-	siig_2s1p_10x_550,
-	siig_2s1p_10x_650,
-	siig_2s1p_10x_850,
 	siig_1p_20x,
 	siig_2p_20x,
-	siig_2p1s_20x_550,
-	siig_2p1s_20x_650,
-	siig_2p1s_20x_850,
-	siig_1s1p_20x_550,
-	siig_1s1p_20x_650,
-	siig_1s1p_20x_850,
-	siig_2s1p_20x_550,
-	siig_2s1p_20x_650,
-	siig_2s1p_20x_850,
 	lava_parallel,
 	lava_parallel_dual_a,
 	lava_parallel_dual_b,
@@ -2710,6 +2694,7 @@
 	oxsemi_954,
 	oxsemi_840,
 	aks_0100,
+	mobility_pp,
 };
 
 
@@ -2723,26 +2708,20 @@
 		int hi; /* -1 if not there, >6 for offset-method (max
                            BAR is 6) */
 	} addr[4];
+
+	/* If set, this is called immediately after pci_enable_device.
+	 * If it returns non-zero, no probing will take place and the
+	 * ports will not be used. */
+	int (*preinit_hook) (struct pci_dev *pdev, int autoirq, int autodma);
+
+	/* If set, this is called after probing for ports.  If 'failed'
+	 * is non-zero we couldn't use any of the ports. */
+	void (*postinit_hook) (struct pci_dev *pdev, int failed);
 } cards[] __devinitdata = {
-	/* siig_1s1p_10x_550 */		{ 1, { { 3, 4 }, } },
-	/* siig_1s1p_10x_650 */		{ 1, { { 3, 4 }, } },
-	/* siig_1s1p_10x_850 */		{ 1, { { 3, 4 }, } },
 	/* siig_1p_10x */		{ 1, { { 2, 3 }, } },
 	/* siig_2p_10x */		{ 2, { { 2, 3 }, { 4, 5 }, } },
-	/* siig_2s1p_10x_550 */		{ 1, { { 4, 5 }, } },
-	/* siig_2s1p_10x_650 */		{ 1, { { 4, 5 }, } },
-	/* siig_2s1p_10x_850 */		{ 1, { { 4, 5 }, } },
 	/* siig_1p_20x */		{ 1, { { 0, 1 }, } },
 	/* siig_2p_20x */		{ 2, { { 0, 1 }, { 2, 3 }, } },
-	/* siig_2p1s_20x_550 */		{ 2, { { 1, 2 }, { 3, 4 }, } },
-	/* siig_2p1s_20x_650 */		{ 2, { { 1, 2 }, { 3, 4 }, } },
-	/* siig_2p1s_20x_850 */		{ 2, { { 1, 2 }, { 3, 4 }, } },
-	/* siig_1s1p_20x_550 */		{ 1, { { 1, 2 }, } },
-	/* siig_1s1p_20x_650 */		{ 1, { { 1, 2 }, } },
-	/* siig_1s1p_20x_850 */		{ 1, { { 1, 2 }, } },
-	/* siig_2s1p_20x_550 */		{ 1, { { 2, 3 }, } },
-	/* siig_2s1p_20x_650 */		{ 1, { { 2, 3 }, } },
-	/* siig_2s1p_20x_850 */		{ 1, { { 2, 3 }, } },
 	/* lava_parallel */		{ 1, { { 0, -1 }, } },
 	/* lava_parallel_dual_a */	{ 1, { { 0, -1 }, } },
 	/* lava_parallel_dual_b */	{ 1, { { 0, -1 }, } },
@@ -2784,6 +2763,7 @@
 	/* oxsemi_954 */		{ 1, { { 0, -1 }, } },
 	/* oxsemi_840 */		{ 1, { { 0, -1 }, } },
 	/* aks_0100 */			{ 1, { { 0, 1 }, } },
+	/* mobility_pp */		{ 1, { { 0, 1 }, } },
 };
 
 static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
@@ -2793,44 +2773,14 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_ite_8872 },
 
 	/* PCI cards */
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x_850 },
 	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_10x,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1p_10x },
 	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_10x,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p_10x },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x_850 },
 	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_20x,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1p_20x },
 	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_20x,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p_20x },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x_850 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x_850 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x_850 },
 	{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PARALLEL,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, lava_parallel },
 	{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_A,
@@ -2865,6 +2815,7 @@
 	{ 0x1409, 0x7268, 0x1409, 0x0103, 0, 0, timedia_4008a },
 	{ 0x1409, 0x7268, 0x1409, 0x0104, 0, 0, timedia_4018 },
 	{ 0x1409, 0x7268, 0x1409, 0x9018, 0, 0, timedia_9018a },
+	{ 0x14f2, 0x0121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, mobility_pp },
 	{ PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_2P_EPP,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_2p_epp },
 	{ PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_1P_ECP,
@@ -2899,6 +2850,10 @@
 	if ((err = pci_enable_device (dev)) != 0)
 		return err;
 
+	if (cards[i].preinit_hook &&
+	    cards[i].preinit_hook (dev, PARPORT_IRQ_NONE, PARPORT_DMA_NONE))
+		return -ENODEV;
+
 	for (n = 0; n < cards[i].numports; n++) {
 		int lo = cards[i].addr[n].lo;
 		int hi = cards[i].addr[n].hi;
@@ -2921,6 +2876,9 @@
 			count++;
 	}
 
+	if (cards[i].postinit_hook)
+		cards[i].postinit_hook (dev, count == 0);
+
 	return count == 0 ? -ENODEV : 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/parport/parport_serial.c linux/drivers/parport/parport_serial.c
--- linux.orig/drivers/parport/parport_serial.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/parport/parport_serial.c	2002-07-20 01:08:39.000000000 +0000
@@ -41,6 +41,11 @@
 	avlab_2s1p,
 	avlab_2s1p_650,
 	avlab_2s1p_850,
+	siig_1s1p_10x,
+	siig_2s1p_10x,
+	siig_2p1s_20x,
+	siig_1s1p_20x,
+	siig_2s1p_20x,
 };
 
 
@@ -53,6 +58,15 @@
 		int hi; /* -1 if not there, >6 for offset-method (max
                            BAR is 6) */
 	} addr[4];
+
+	/* If set, this is called immediately after pci_enable_device.
+	 * If it returns non-zero, no probing will take place and the
+	 * ports will not be used. */
+	int (*preinit_hook) (struct pci_dev *pdev, int autoirq, int autodma);
+
+	/* If set, this is called after probing for ports.  If 'failed'
+	 * is non-zero we couldn't use any of the ports. */
+	void (*postinit_hook) (struct pci_dev *pdev, int failed);
 } cards[] __devinitdata = {
 	/* titan_110l */		{ 1, { { 3, -1 }, } },
 	/* titan_210l */		{ 1, { { 3, -1 }, } },
@@ -65,6 +79,11 @@
 	/* avlab_2s1p     */		{ 1, { { 2, 3}, } },
 	/* avlab_2s1p_650 */		{ 1, { { 2, 3}, } },
 	/* avlab_2s1p_850 */		{ 1, { { 2, 3}, } },
+	/* siig_1s1p_10x */		{ 1, { { 3, 4 }, } },
+	/* siig_2s1p_10x */		{ 1, { { 4, 5 }, } },
+	/* siig_2p1s_20x */		{ 2, { { 1, 2 }, { 3, 4 }, } },
+	/* siig_1s1p_20x */		{ 1, { { 1, 2 }, } },
+	/* siig_2s1p_20x */		{ 1, { { 2, 3 }, } },
 };
 
 static struct pci_device_id parport_serial_pci_tbl[] __devinitdata = {
@@ -83,6 +102,37 @@
 	{ 0x14db, 0x2160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p},
 	{ 0x14db, 0x2161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p_650},
 	{ 0x14db, 0x2162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p_850},
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
+
 	{ 0, } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
@@ -98,6 +148,16 @@
 	int first_uart_offset;
 };
 
+static int __devinit siig10x_init_fn(struct pci_dev *dev, struct pci_board_no_ids *board, int enable)
+{
+	return pci_siig10x_fn(dev, NULL, enable);
+}
+
+static int __devinit siig20x_init_fn(struct pci_dev *dev, struct pci_board_no_ids *board, int enable)
+{
+	return pci_siig20x_fn(dev, NULL, enable);
+}
+
 static struct pci_board_no_ids pci_boards[] __devinitdata = {
 	/*
 	 * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
@@ -120,6 +180,11 @@
 /* avlab_2s1p (n/t) */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
 /* avlab_2s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
 /* avlab_2s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
+/* siig_1s1p_10x */	{ SPCI_FL_BASE2, 1, 460800, 0, 0, siig10x_init_fn },
+/* siig_2s1p_10x */	{ SPCI_FL_BASE2, 1, 921600, 0, 0, siig10x_init_fn },
+/* siig_2p1s_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
+/* siig_1s1p_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
+/* siig_2s1p_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
 };
 
 struct parport_serial_private {
@@ -239,6 +304,10 @@
 	int i = id->driver_data, n;
 	int success = 0;
 
+	if (cards[i].preinit_hook &&
+	    cards[i].preinit_hook (dev, PARPORT_IRQ_NONE, PARPORT_DMA_NONE))
+		return -ENODEV;
+
 	for (n = 0; n < cards[i].numports; n++) {
 		struct parport *port;
 		int lo = cards[i].addr[n].lo;
@@ -265,6 +334,9 @@
 		}
 	}
 
+	if (cards[i].postinit_hook)
+		cards[i].postinit_hook (dev, !success);
+
 	return success ? 0 : 1;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pci/Makefile linux/drivers/pci/Makefile
--- linux.orig/drivers/pci/Makefile	2001-09-09 17:50:48.000000000 +0000
+++ linux/drivers/pci/Makefile	2002-07-20 01:08:39.000000000 +0000
@@ -28,8 +28,8 @@
 obj-$(CONFIG_PARISC) += setup-bus.o
 obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o
 obj-$(CONFIG_ALL_PPC) += setup-bus.o
-obj-$(CONFIG_DDB5476) += setup-bus.o
 obj-$(CONFIG_SGI_IP27) += setup-irq.o
+obj-$(CONFIG_SGI_IP32) += setup-irq.o
 
 ifndef CONFIG_X86
 obj-y += syscall.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pci/gen-devlist.c linux/drivers/pci/gen-devlist.c
--- linux.orig/drivers/pci/gen-devlist.c	2001-11-04 17:31:58.000000000 +0000
+++ linux/drivers/pci/gen-devlist.c	2002-07-20 01:08:36.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *	Generate devlist.h and classlist.h from the PCI ID file.
  *
- *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
+ *	(c) 1999--2002 Martin Mares <mj@ucw.cz>
  */
 
 #include <stdio.h>
@@ -15,8 +15,13 @@
 	while (*c) {
 		if (*c == '"')
 			fprintf(f, "\\\"");
-		else
+		else {
 			fputc(*c, f);
+			if (*c == '?' && c[1] == '?') {
+				/* Avoid trigraphs */
+				fprintf(f, "\" \"");
+			}
+		}
 		c++;
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pci/names.c linux/drivers/pci/names.c
--- linux.orig/drivers/pci/names.c	2001-11-09 22:03:11.000000000 +0000
+++ linux/drivers/pci/names.c	2002-07-20 01:08:25.000000000 +0000
@@ -32,18 +32,18 @@
  * real memory.. Parse the same file multiple times
  * to get all the info.
  */
-#define VENDOR( vendor, name )		static char __vendorstr_##vendor[] __initdata = name;
+#define VENDOR( vendor, name )		static char __vendorstr_##vendor[] __devinitdata = name;
 #define ENDVENDOR()
-#define DEVICE( vendor, device, name ) 	static char __devicestr_##vendor##device[] __initdata = name;
+#define DEVICE( vendor, device, name ) 	static char __devicestr_##vendor##device[] __devinitdata = name;
 #include "devlist.h"
 
 
-#define VENDOR( vendor, name )		static struct pci_device_info __devices_##vendor[] __initdata = {
+#define VENDOR( vendor, name )		static struct pci_device_info __devices_##vendor[] __devinitdata = {
 #define ENDVENDOR()			};
 #define DEVICE( vendor, device, name )	{ 0x##device, 0, __devicestr_##vendor##device },
 #include "devlist.h"
 
-static struct pci_vendor_info __initdata pci_vendor_list[] = {
+static struct pci_vendor_info __devinitdata pci_vendor_list[] = {
 #define VENDOR( vendor, name )		{ 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor },
 #define ENDVENDOR()
 #define DEVICE( vendor, device, name )
@@ -121,7 +121,7 @@
 
 #else
 
-void __init pci_name_device(struct pci_dev *dev)
+void __devinit pci_name_device(struct pci_dev *dev)
 {
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pci/pci.c linux/drivers/pci/pci.c
--- linux.orig/drivers/pci/pci.c	2001-11-21 05:53:29.000000000 +0000
+++ linux/drivers/pci/pci.c	2002-07-20 01:08:30.000000000 +0000
@@ -23,6 +23,7 @@
 #include <linux/kmod.h>		/* for hotplug_path */
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/cache.h>
 
 #include <asm/page.h>
 #include <asm/dma.h>	/* isa_dma_bridge_buggy */
@@ -846,6 +847,100 @@
 	pcibios_set_master(dev);
 }
 
+/**
+ * pdev_set_mwi - arch helper function for pcibios_set_mwi
+ * @dev: the PCI device for which MWI is enabled
+ *
+ * Helper function for implementation the arch-specific pcibios_set_mwi
+ * function.  Originally copied from drivers/net/acenic.c.
+ * Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>.
+ *
+ * RETURNS: An appriopriate -ERRNO error value on eror, or zero for success.
+ */
+int
+pdev_set_mwi(struct pci_dev *dev)
+{
+	int rc = 0;
+	u8 cache_size;
+
+	/*
+	 * Looks like this is necessary to deal with on all architectures,
+	 * even this %$#%$# N440BX Intel based thing doesn't get it right.
+	 * Ie. having two NICs in the machine, one will have the cache
+	 * line set at boot time, the other will not.
+	 */
+	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cache_size);
+	cache_size <<= 2;
+	if (cache_size != SMP_CACHE_BYTES) {
+		printk(KERN_WARNING "PCI: %s PCI cache line size set incorrectly "
+		       "(%i bytes) by BIOS/FW, ",
+		       dev->slot_name, cache_size);
+		if (cache_size > SMP_CACHE_BYTES) {
+			printk("expecting %i\n", SMP_CACHE_BYTES);
+			rc = -EINVAL;
+		} else {
+			printk("correcting to %i\n", SMP_CACHE_BYTES);
+			pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+					      SMP_CACHE_BYTES >> 2);
+		}
+	}
+
+	return rc;
+}
+
+/**
+ * pci_set_mwi - enables memory-write-invalidate PCI transaction
+ * @dev: the PCI device for which MWI is enabled
+ *
+ * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND,
+ * and then calls @pcibios_set_mwi to do the needed arch specific
+ * operations or a generic mwi-prep function.
+ *
+ * RETURNS: An appriopriate -ERRNO error value on eror, or zero for success.
+ */
+int
+pci_set_mwi(struct pci_dev *dev)
+{
+	int rc;
+	u16 cmd;
+
+#ifdef HAVE_ARCH_PCI_MWI
+	rc = pcibios_set_mwi(dev);
+#else
+	rc = pdev_set_mwi(dev);
+#endif
+
+	if (rc)
+		return rc;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	if (! (cmd & PCI_COMMAND_INVALIDATE)) {
+		DBG("PCI: Enabling Mem-Wr-Inval for device %s\n", dev->slot_name);
+		cmd |= PCI_COMMAND_INVALIDATE;
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	
+	return 0;
+}
+
+/**
+ * pci_clear_mwi - disables Memory-Write-Invalidate for device dev
+ * @dev: the PCI device to disable
+ *
+ * Disables PCI Memory-Write-Invalidate transaction on the device
+ */
+void
+pci_clear_mwi(struct pci_dev *dev)
+{
+	u16 cmd;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	if (cmd & PCI_COMMAND_INVALIDATE) {
+		cmd &= ~PCI_COMMAND_INVALIDATE;
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+}
+
 int
 pci_set_dma_mask(struct pci_dev *dev, u64 mask)
 {
@@ -914,13 +1009,15 @@
 			l = 0;
 		if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
 			res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
+			res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
 			sz = pci_size(sz, PCI_BASE_ADDRESS_MEM_MASK);
 		} else {
 			res->start = l & PCI_BASE_ADDRESS_IO_MASK;
+			res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
 			sz = pci_size(sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
 		}
 		res->end = res->start + (unsigned long) sz;
-		res->flags |= (l & 0xf) | pci_calc_resource_flags(l);
+		res->flags |= pci_calc_resource_flags(l);
 		if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
 		    == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
 			pci_read_config_dword(dev, reg+4, &l);
@@ -964,7 +1061,7 @@
 	}
 }
 
-void __devinit  pci_read_bridge_bases(struct pci_bus *child)
+void __devinit pci_read_bridge_bases(struct pci_bus *child)
 {
 	struct pci_dev *dev = child->self;
 	u8 io_base_lo, io_limit_lo;
@@ -1055,7 +1152,7 @@
 	}
 }
 
-static struct pci_bus * __devinit  pci_alloc_bus(void)
+static struct pci_bus * __devinit pci_alloc_bus(void)
 {
 	struct pci_bus *b;
 
@@ -1380,7 +1477,7 @@
 	return max;
 }
 
-int __devinit  pci_bus_exists(const struct list_head *list, int nr)
+int __devinit pci_bus_exists(const struct list_head *list, int nr)
 {
 	const struct list_head *l;
 
@@ -1392,7 +1489,7 @@
 	return 0;
 }
 
-struct pci_bus * __devinit  pci_alloc_primary_bus(int bus)
+struct pci_bus * __devinit pci_alloc_primary_bus(int bus)
 {
 	struct pci_bus *b;
 
@@ -1411,7 +1508,7 @@
 	return b;
 }
 
-struct pci_bus * __devinit  pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
+struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
 {
 	struct pci_bus *b = pci_alloc_primary_bus(bus);
 	if (b) {
@@ -1944,7 +2041,7 @@
 #endif
 }
 
-static int __devinit  pci_setup(char *str)
+static int __devinit pci_setup(char *str)
 {
 	while (str) {
 		char *k = strchr(str, ',');
@@ -1979,6 +2076,9 @@
 EXPORT_SYMBOL(pci_find_slot);
 EXPORT_SYMBOL(pci_find_subsys);
 EXPORT_SYMBOL(pci_set_master);
+EXPORT_SYMBOL(pci_set_mwi);
+EXPORT_SYMBOL(pci_clear_mwi);
+EXPORT_SYMBOL(pdev_set_mwi);
 EXPORT_SYMBOL(pci_set_dma_mask);
 EXPORT_SYMBOL(pci_dac_set_dma_mask);
 EXPORT_SYMBOL(pci_assign_resource);
@@ -1996,11 +2096,13 @@
 EXPORT_SYMBOL(pci_add_new_bus);
 EXPORT_SYMBOL(pci_do_scan_bus);
 EXPORT_SYMBOL(pci_scan_slot);
+#ifdef CONFIG_PROC_FS
 EXPORT_SYMBOL(pci_proc_attach_device);
 EXPORT_SYMBOL(pci_proc_detach_device);
 EXPORT_SYMBOL(pci_proc_attach_bus);
 EXPORT_SYMBOL(pci_proc_detach_bus);
 #endif
+#endif
 
 EXPORT_SYMBOL(pci_set_power_state);
 EXPORT_SYMBOL(pci_save_state);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- linux.orig/drivers/pci/pci.ids	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/pci/pci.ids	2002-07-20 01:08:21.000000000 +0000
@@ -7,7 +7,7 @@
 #	so if you have anything to contribute, please visit the home page or
 #	send a diff -u against the most recent pci.ids to pci-ids@ucw.cz.
 #
-#	$Id: pci.ids,v 1.24 2001/10/28 21:55:26 mares Exp $
+#	$Id: pci.ids,v 1.39 2002/03/23 14:58:55 mares Exp $
 #
 
 # Vendors, devices and subsystems. Please keep sorted.
@@ -26,6 +26,10 @@
 0675  Dynalink
 	1700  IS64PH ISDN Adapter
 	1702  IS64PH ISDN Adapter
+# Wrong ID used in subsystem ID of VIA USB controllers.
+0925  VIA Technologies, Inc. (Wrong ID)
+09c1  Arris
+	0704  CM 200E Cable Modem
 0a89  BREA Technologies Inc
 0e11  Compaq Computer Corporation
 	0001  PCI to EISA Bridge
@@ -47,7 +51,7 @@
 	a0f7  PCI Hotplug Controller
 		8086 002a  PCI Hotplug Controller A
 		8086 002b  PCI Hotplug Controller B
-	a0f8  USB Open Host Controller
+	a0f8  ZFMicro Chipset USB
 	a0fc  Fibre Channel Host Controller
 	ae10  Smart-2/P RAID Controller
 		0e11 4030  Smart-2/P Array Controller
@@ -69,28 +73,10 @@
 	ae6d  NorthStar CPU to PCI Bridge
 	b011  Integrated Netelligent 10/100
 	b012  Netelligent 10 T/2
-	b01e  NC3120 Fast Ethernet NIC
-	b01f  NC3122 Fast Ethernet NIC
 	b02f  NC1120 Ethernet NIC
 	b030  Netelligent WS 5100
-	b04a  10/100 TX PCI Intel WOL UTP Controller
 	b060  Smart Array 5300 Controller
-	b0c6  NC3161 Fast Ethernet NIC
-	b0c7  NC3160 Fast Ethernet NIC
-	b0d7  NC3121 Fast Ethernet NIC
-	b0dd  NC3131 Fast Ethernet NIC
-	b0de  NC3132 Fast Ethernet Module
-	b0df  NC6132 Gigabit Module
-	b0e0  NC6133 Gigabit Module
-	b0e1  NC3133 Fast Ethernet Module
-	b123  NC6134 Gigabit NIC
-	b134  NC3163 Fast Ethernet NIC
-	b13c  NC3162 Fast Ethernet NIC
-	b144  NC3123 Fast Ethernet NIC
-	b163  NC3134 Fast Ethernet NIC
-	b164  NC3135 Fast Ethernet Upgrade Module
 	b178  Smart Array 5i/532
-	b1a4  NC7131 Gigabit Server Adapter
 	f130  NetFlex-3/P ThunderLAN 1.0
 	f150  NetFlex-3/P ThunderLAN 2.3
 1000  LSI Logic / Symbios Logic (formerly NCR)
@@ -109,6 +95,9 @@
 		0e11 7004  Embedded Ultra Wide SCSI Controller
 		1092 8760  FirePort 40 Dual SCSI Controller
 		1de1 3904  DC390F Ultra Wide SCSI Controller
+	0010  53c895
+		0e11 4040  Integrated Array Controller
+		0e11 4048  Integrated Array Controller
 	0012  53c895a
 	0020  53c1010 Ultra3 SCSI Adapter
 	0021  53c1010 66MHz  Ultra3 SCSI Adapter
@@ -122,7 +111,11 @@
 	0623  FC929 LAN
 	0624  FC919
 	0625  FC919 LAN
-	0701  83C885
+	0626  FC929X
+	0627  FC929X LAN
+	0628  FC919X
+	0629  FC919X LAN
+	0701  83C885 NT50 DigitalScape Fast Ethernet
 	0702  Yellowfin G-NIC gigabit ethernet
 		1318 0000  PEI100X
 	0901  61C102
@@ -139,28 +132,65 @@
 	9100  INI-9100/9100W SCSI Host
 1002  ATI Technologies Inc
 	4158  68800AX [Mach32]
+	4242  Radeon 8500 DV
+		1002 02aa  Radeon 8500 AIW DV Edition
 	4354  215CT [Mach64 CT]
 	4358  210888CX [Mach64 CX]
 	4554  210888ET [Mach64 ET]
 	4654  Mach64 VT
 	4742  3D Rage Pro AGP 1X/2X
+		1002 0040  Rage Pro Turbo AGP 2X
+		1002 0044  Rage Pro Turbo AGP 2X
+		1002 0061  Rage Pro AIW AGP 2X
+		1002 0062  Rage Pro AIW AGP 2X
+		1002 0063  Rage Pro AIW AGP 2X
+		1002 0080  Rage Pro Turbo AGP 2X
+		1002 0084  Rage Pro Turbo AGP 2X
+		1002 4742  Rage Pro Turbo AGP 2X
+		1002 8001  Rage Pro Turbo AGP 2X
+		1028 0082  Rage Pro Turbo AGP 2X
 		1028 4082  Optiplex GX1 Onboard Display Adapter
-		8086 4152  Rage 3D Pro AGP
+		1028 8082  Rage Pro Turbo AGP 2X
+		1028 c082  Rage Pro Turbo AGP 2X
+		8086 4152  Xpert 98D AGP 2X
+		8086 464a  Rage Pro Turbo AGP 2X
 	4744  3D Rage Pro AGP 1X
+		1002 4744  Rage Pro Turbo AGP
 	4747  3D Rage Pro
 	4749  3D Rage Pro
+		1002 0061  Rage Pro AIW
+		1002 0062  Rage Pro AIW
 	474c  Rage XC
-	474d  Rage XL AGP
+	474d  Rage XL AGP 2X
+		1002 0004  Xpert 98 RXL AGP 2X
+		1002 0008  Xpert 98 RXL AGP 2X
+		1002 0080  Rage XL AGP 2X
+		1002 0084  Xpert 98 AGP 2X
+		1002 474d  Rage XL AGP
+		1033 806a  Rage XL AGP
 	474e  Rage XC AGP
+		1002 474e  Rage XC AGP
 	474f  Rage XL
+		1002 0008  Rage XL
+		1002 474f  Rage XL
 	4750  3D Rage Pro 215GP
+		1002 0040  Rage Pro Turbo
+		1002 0044  Rage Pro Turbo
+		1002 0080  Rage Pro Turbo
+		1002 0084  Rage Pro Turbo
+		1002 4750  Rage Pro Turbo
 	4751  3D Rage Pro 215GQ
 	4752  Rage XL
+		1002 0008  Rage XL
+		1002 4752  Rage XL
 	4753  Rage XC
+		1002 4753  Rage XC
 	4754  3D Rage I/II 215GT [Mach64 GT]
 	4755  3D Rage II+ 215GTB [Mach64 GTB]
 	4756  3D Rage IIC 215IIC [Mach64 GT IIC]
+		1002 4756  Rage IIC
 	4757  3D Rage IIC AGP
+		1002 4757  Rage IIC AGP
 		1028 0089  Rage 3D IIC
 		1028 4082  Rage 3D IIC
 		1028 8082  Rage 3D IIC
@@ -169,77 +199,159 @@
 	4759  3D Rage IIC
 	475a  3D Rage IIC AGP
 		1002 0087  Rage 3D IIC
+		1002 475a  Rage IIC AGP
 	4c42  3D Rage LT Pro AGP-133
 		0e11 b0e8  Rage 3D LT Pro
 		0e11 b10e  3D Rage LT Pro (Compaq Armada 1750)
+		1002 0040  Rage LT Pro AGP 2X
+		1002 0044  Rage LT Pro AGP 2X
+		1002 4c42  Rage LT Pro AGP 2X
+		1002 8001  Rage LT Pro AGP 2X
 		1028 0085  Rage 3D LT Pro
 	4c44  3D Rage LT Pro AGP-66
 	4c45  Rage Mobility M3 AGP
 	4c46  Rage Mobility M3 AGP 2x
 	4c47  3D Rage LT-G 215LG
 	4c49  3D Rage LT Pro
+		1002 0004  Rage LT Pro
+		1002 0040  Rage LT Pro
+		1002 0044  Rage LT Pro
+		1002 4c49  Rage LT Pro
 	4c4d  Rage Mobility P/M AGP 2x
+		1002 0084  Xpert 98 AGP 2X (Mobility)
 	4c4e  Rage Mobility L AGP 2x
 	4c50  3D Rage LT Pro
+		1002 4c50  Rage LT Pro
 	4c51  3D Rage LT Pro
 	4c52  Rage Mobility P/M
 	4c53  Rage Mobility L
 	4c54  264LT [Mach64 LT]
-	4c57  Radeon Mobility M6 LW
+	4c57  Radeon Mobility M7 LW
+		1028 00e6  Radeon Mobility M7 LW (Dell Inspiron 8100)
+	4c58  Radeon Mobility M6 LX
 	4c59  Radeon Mobility M6 LY
+		104d 80e7  Vaio PCG Series video card
 	4c5a  Radeon Mobility M6 LZ
 	4d46  Rage Mobility M4 AGP
 	4d4c  Rage Mobility M4 AGP
-	5041  Rage 128 PA
-	5042  Rage 128 PB
-	5043  Rage 128 PC
-	5044  Rage 128 PD
-	5045  Rage 128 PE
-	5046  Rage 128 PF
+	5041  Rage 128 PA/PRO
+	5042  Rage 128 PB/PRO AGP 2x
+	5043  Rage 128 PC/PRO AGP 4x
+	5044  Rage 128 PD/PRO TMDS
+		1002 0028  Rage 128 AIW
+		1002 0029  Rage 128 AIW
+	5045  Rage 128 PE/PRO AGP 2x TMDS
+	5046  Rage 128 PF/PRO AGP 4x TMDS
+		1002 0004  Rage Fury Pro
+		1002 0008  Rage Fury Pro/Xpert 2000 Pro
+		1002 0014  Rage Fury Pro
+		1002 0018  Rage Fury Pro/Xpert 2000 Pro
+		1002 0028  Rage 128 Pro AIW AGP
+		1002 002a  Rage 128 Pro AIW AGP
+		1002 0048  Rage Fury Pro
 		1002 2000  Rage Fury MAXX AGP 4x (TMDS) (VGA device)
 		1002 2001  Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)
-	5047  Rage 128 PG
-	5048  Rage 128 PH
-	5049  Rage 128 PI
-	504a  Rage 128 PJ
-	504b  Rage 128 PK
-	504c  Rage 128 PL
-	504d  Rage 128 PM
-	504e  Rage 128 PN
-	504f  Rage 128 PO
-	5050  Rage 128 PP
-	5051  Rage 128 PQ
-	5052  Rage 128 PR
-	5053  Rage 128 PS
-	5054  Rage 128 PT
-	5055  Rage 128 PU
-	5056  Rage 128 PV
-	5057  Rage 128 PW
-	5058  Rage 128 PX
+	5047  Rage 128 PG/PRO
+	5048  Rage 128 PH/PRO AGP 2x
+	5049  Rage 128 PI/PRO AGP 4x
+	504a  Rage 128 PJ/PRO TMDS
+	504b  Rage 128 PK/PRO AGP 2x TMDS
+	504c  Rage 128 PL/PRO AGP 4x TMDS
+	504d  Rage 128 PM/PRO
+	504e  Rage 128 PN/PRO AGP 2x
+	504f  Rage 128 PO/PRO AGP 4x
+	5050  Rage 128 PP/PRO TMDS
+		1002 0008  Xpert 128
+	5051  Rage 128 PQ/PRO AGP 2x TMDS
+	5052  Rage 128 PR/PRO AGP 4x TMDS
+	5053  Rage 128 PS/PRO
+	5054  Rage 128 PT/PRO AGP 2x
+	5055  Rage 128 PU/PRO AGP 4x
+	5056  Rage 128 PV/PRO TMDS
+	5057  Rage 128 PW/PRO AGP 2x TMDS
+	5058  Rage 128 PX/PRO AGP 4x TMDS
 	5144  Radeon QD
+		1002 0008  Radeon 7000/Radeon VE
+		1002 0009  Radeon 7000/Radeon
+		1002 000a  Radeon 7000/Radeon
+		1002 001a  Radeon 7000/Radeon
+		1002 0029  Radeon AIW
+		1002 0038  Radeon 7000/Radeon
+		1002 0039  Radeon 7000/Radeon
+		1002 008a  Radeon 7000/Radeon
+		1002 00ba  Radeon 7000/Radeon
+		1002 0139  Radeon 7000/Radeon
+		1002 028a  Radeon 7000/Radeon
+		1002 02aa  Radeon AIW
+		1002 053a  Radeon 7000/Radeon
 	5145  Radeon QE
 	5146  Radeon QF
 	5147  Radeon QG
+	5148  Radeon R200 QH
+	5149  Radeon R200 QI
+	514a  Radeon R200 QJ
+	514b  Radeon R200 QK
+	514c  Radeon QL
+		1002 013a  Radeon 8500
+	5157  Radeon 7500 QW
+		1002 013a  Radeon 7500
+	5158  Radeon 7500 QX
 	5159  Radeon VE QY
+		1002 000a  Radeon 7000/Radeon VE
+		1002 0038  Radeon 7000/Radeon VE
+		1002 003a  Radeon 7000/Radeon VE
+		1002 00ba  Radeon 7000/Radeon VE
+		1002 013a  Radeon 7000/Radeon VE
 	515a  Radeon VE QZ
-	5245  Rage 128 RE
-	5246  Rage 128 RF
+	5168  Radeon R200 Qh
+	5169  Radeon R200 Qi
+	516a  Radeon R200 Qj
+	516b  Radeon R200 Qk
+	5245  Rage 128 RE/SG
+		1002 0008  Xpert 128
+		1002 0028  Rage 128 AIW
+		1002 0029  Rage 128 AIW
+		1002 0068  Rage 128 AIW
+	5246  Rage 128 RF/SG AGP
+		1002 0004  Magnum/Xpert 128/Xpert 99
+		1002 0008  Magnum/Xpert128/X99/Xpert2000
+		1002 0028  Rage 128 AIW AGP
+		1002 0044  Rage Fury/Xpert 128/Xpert 2000
+		1002 0068  Rage 128 AIW AGP
+		1002 0448  Rage Fury
 	5247  Rage 128 RG
-	524b  Rage 128 RK
-	524c  Rage 128 RL
-	5345  Rage 128 SE
-	5346  Rage 128 SF
-	5347  Rage 128 SG
-	5348  Rage 128 4x
-	534b  Rage 128 SK
-	534c  Rage 128 SL
-	534d  Rage 128 SM
-	534e  Rage 128 SN
+	524b  Rage 128 RK/VR
+	524c  Rage 128 RL/VR AGP
+		1002 0008  Xpert 99/Xpert 2000
+		1002 0088  Xpert 99
+	5345  Rage 128 SE/4x
+	5346  Rage 128 SF/4x AGP 2x
+	5347  Rage 128 SG/4x AGP 4x
+	5348  Rage 128 SH
+	534b  Rage 128 SK/4x
+	534c  Rage 128 SL/4x AGP 2x
+	534d  Rage 128 SM/4x AGP 4x
+		1002 0008  Xpert 99/Xpert 2000
+		1002 0018  Xpert 2000
+	534e  Rage 128 4x
 	5354  Mach 64 VT
 		1002 5654  Mach 64 reference
-	5446  Rage 128 Pro TF
-	544c  Rage 128 Pro TL
-	5452  Rage 128 Pro TR
+	5446  Rage 128 Pro Ultra TF
+		1002 0004  Rage Fury Pro
+		1002 0008  Rage Fury Pro/Xpert 2000 Pro
+		1002 0018  Rage Fury Pro/Xpert 2000 Pro
+		1002 0028  Rage 128 AIW Pro AGP
+		1002 0029  Rage 128 AIW
+		1002 002a  Rage 128 AIW Pro AGP
+		1002 002b  Rage 128 AIW
+		1002 0048  Xpert 2000 Pro
+	544c  Rage 128 Pro Ultra TL
+	5452  Rage 128 Pro Ultra TR
+		1002 001c  Rage 128 Pro 4XL
+		103c 1279  Rage 128 Pro 4XL
+	5453  Rage 128 Pro Ultra TS
+	5454  Rage 128 Pro Ultra TT
+	5455  Rage 128 Pro Ultra TU
 	5654  264VT [Mach64 VT]
 		1002 5654  Mach64VT Reference
 	5655  264VT3 [Mach64 VT3]
@@ -255,7 +367,7 @@
 	000c  82C541 [Lynx]
 	000d  82C543 [Lynx]
 	0101  82C532
-	0102  82C534
+	0102  82C534 [Eagle]
 	0103  82C538
 	0104  82C535
 	0105  82C147
@@ -290,11 +402,17 @@
 	0001  DP83810
 	0002  87415/87560 IDE
 	000e  87560 Legacy I/O
-	000f  OHCI Compliant FireWire Controller
-	0011  National PCI System I/O
+	000f  FireWire Controller
+	0011  NS87560 National PCI System I/O
 	0012  USB Controller
 	0020  DP83815 (MacPhyter) Ethernet Controller
 	0022  DP83820 10/100/1000 Ethernet Controller
+	0500  SCx200 Bridge
+	0501  SCx200 SMI
+	0502  SCx200 IDE
+	0503  SCx200 Audio
+	0504  SCx200 Video
+	0505  SCx200 XBus
 	d001  87410 IDE
 100c  Tseng Labs Inc
 	3202  ET4000/W32p rev A
@@ -305,9 +423,10 @@
 	4702  ET6300
 100d  AST Research Inc
 100e  Weitek
-	9000  P9000
-	9001  P9000
-	9100  P9100
+	9000  P9000 Viper
+	9001  P9000 Viper
+	9002  P9000 Viper
+	9100  P9100 Viper Pro/SE
 1010  Video Logic, Ltd.
 1011  Digital Equipment Corporation
 	0001  DECchip 21050
@@ -360,6 +479,7 @@
 		1374 0001  Cardbus Ethernet Card 10/100
 		1395 0001  10/100 Ethernet CardBus PC Card
 		8086 0001  EtherExpress PRO/100 Mobile CardBus 32
+	001a  Farallon PN9000SX
 	0021  DECchip 21052
 	0022  DECchip 21150
 	0023  DECchip 21150
@@ -368,7 +488,11 @@
 	0026  DECchip 21154
 	0045  DECchip 21553
 	0046  DECchip 21554
+		0e11 4050  Integrated Smart Array
+		0e11 4051  Integrated Smart Array
+		0e11 4058  Integrated Smart Array
 		103c 10c2  Hewlett-Packard NetRAID-4M
+		12d9 000a  VoIP PCI Gateway
 		9005 0365  Adaptec 5400S
 		9005 1364  Dell PowerEdge RAID Controller 2
 		9005 1365  Dell PowerEdge RAID Controller 2
@@ -394,7 +518,7 @@
 	00d6  GD 5465 [Laguna]
 	00e8  GD 5436U
 	1100  CL 6729
-	1110  PD 6832
+	1110  PD 6832 PCMCIA/CardBus Ctrlr
 	1112  PD 6834 PCMCIA/CardBus Ctrlr
 	1113  PD 6833 PCMCIA/CardBus Ctrlr
 	1200  GD 7542 [Nordic]
@@ -405,6 +529,8 @@
 		1014 1010  CS4610 SoundFusion Audio Accelerator
 	6003  CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
 		1013 4280  Crystal SoundFusion PCI Audio Accelerator
+		1681 0050  Hercules Game Theater XP
+	6004  CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
 	6005  Crystal CS4281 PCI Audio
 		1013 4281  Crystal CS4281 PCI Audio
 		10cf 10a8  Crystal CS4281 PCI Audio
@@ -424,6 +550,7 @@
 	0017  CPU to PCI Bridge
 	0018  TR Auto LANstreamer
 	001b  GXT-150P
+	001c  Carrera
 	001d  82G2675
 	0020  MCA
 	0022  IBM27-82351
@@ -469,6 +596,7 @@
 	0144  Yotta Video Compositor Output
 		1014 0145  Yotta Output Controller (ytout)
 	0156  405GP PLB to PCI Bridge
+	01a7  PCI-X to PCI-X Bridge
 	01bd  Netfinity ServeRAID controller
 	01be  ServeRAID-4M
 	01bf  ServeRAID-4L
@@ -497,20 +625,25 @@
 	c24a  90C
 101e  American Megatrends Inc.
 	1960  MegaRAID
+		101e 0471  MegaRAID 471 Enterprise 1600 RAID Controller
+		101e 0475  MegaRAID 475 Express 500 RAID Controller
+		101e 0493  MegaRAID 493 Elite 1600 RAID Controller
 		1028 0471  PowerEdge RAID Controller 3/QC
 		1028 0493  PowerEdge RAID Controller 3/DC
-	9010  MegaRAID
+	9010  MegaRAID 428 Ultra RAID Controller
 	9030  EIDE Controller
 	9031  EIDE Controller
 	9032  EIDE & SCSI Controller
 	9033  SCSI Controller
 	9040  Multimedia card
-	9060  MegaRAID
+	9060  MegaRAID 434 Ultra GT RAID Controller
+	9063  MegaRAC
 101f  PictureTel
 1020  Hitachi Computer Products
 1021  OKI Electric Industry Co. Ltd.
 1022  Advanced Micro Devices [AMD]
 	2000  79c970 [PCnet LANCE]
+		1014 2000  NetFinity 10/100 Fast Ethernet
 		103c 104c  Ethernet with LAN remote power Adapter
 		103c 1064  Ethernet with LAN remote power Adapter
 		103c 1065  Ethernet with LAN remote power Adapter
@@ -519,15 +652,20 @@
 		103c 10ea  Ethernet with LAN remote power Adapter
 		1113 1220  EN1220 10/100 Fast Ethernet
 		1259 2450  AT-2450 10/100 Fast Ethernet
+		1259 2454  AT-2450v4 10Mb Ethernet Adapter
 		1259 2700  AT-2700TX 10/100 Fast Ethernet
 		1259 2701  AT-2700FX 100Mb Ethernet
 	2001  79c978 [HomePNA]
+		1092 0a78  Multimedia Home Network Adapter
+		1668 0299  ActionLink Home Network Adapter
 	2020  53c974 [PCscsi]
 	2040  79c974
 	7006  AMD-751 [Irongate] System Controller
 	7007  AMD-751 [Irongate] AGP Bridge
-	700e  AMD-760 [Irongate] System Controller
-	700f  AMD-760 [Irongate] AGP Bridge
+	700c  AMD-760 MP [IGD4-2P] System Controller
+	700d  AMD-760 MP [IGD4-2P] AGP Bridge
+	700e  AMD-760 [IGD4-1P] System Controller
+	700f  AMD-760 [IGD4-1P] AGP Bridge
 	7400  AMD-755 [Cobra] ISA
 	7401  AMD-755 [Cobra] IDE
 	7403  AMD-755 [Cobra] ACPI
@@ -536,15 +674,28 @@
 	7409  AMD-756 [Viper] IDE
 	740b  AMD-756 [Viper] ACPI
 	740c  AMD-756 [Viper] USB
-	7410  AMD-765 [Viper] ISA
-	7411  AMD-765 [Viper] IDE
-	7413  AMD-765 [Viper] ACPI
-	7414  AMD-765 [Viper] USB
-	7440  AMD-768 [??] ISA
-	7441  AMD-768 [??] IDE
-	7443  AMD-768 [??] ACPI
-	7448  AMD-768 [??] PCI
-	7449  AMD-768 [??] USB
+	7410  AMD-766 [ViperPlus] ISA
+	7411  AMD-766 [ViperPlus] IDE
+	7413  AMD-766 [ViperPlus] ACPI
+	7414  AMD-766 [ViperPlus] USB
+	7440  AMD-768 [Opus] ISA
+		1043 8044  Asus A7M-D motherboard ISA bridge
+	7441  AMD-768 [Opus] IDE
+	7443  AMD-768 [Opus] ACPI
+		1043 8044  Asus A7M-D motherboard
+	7448  AMD-768 [Opus] PCI
+	7449  AMD-768 [Opus] USB
+	7454  AMD-8151 System Controller
+	7455  AMD-8151 AGP Bridge
+	7460  AMD-8111 PCI
+	7461  AMD-8111 USB
+	7462  AMD-8111 Ethernet
+	7468  AMD-8111 LPC
+	7469  AMD-8111 IDE
+	746a  AMD-8111 SMBus 2.0
+	746b  AMD-8111 ACPI
+	746d  AMD-8111 AC97 Audio
+	756b  AMD-8111 ACPI
 1023  Trident Microsystems
 	0194  82C194
 	2000  4DWave DX
@@ -557,6 +708,7 @@
 	8520  CyberBlade i1
 		0e11 b16e  CyberBlade i1 AGP
 		1023 8520  CyberBlade i1 AGP
+	8820  CyberBlade XPAi1
 	9320  TGUI 9320
 	9350  GUI Accelerator
 	9360  Flat panel GUI Accelerator
@@ -580,7 +732,7 @@
 	9682  TGUI 9682
 	9683  TGUI 9683
 	9685  ProVIDIA 9685
-	9750  3DIm`age 975
+	9750  3DImage 9750
 		1014 9750  3DImage 9750
 		1023 9750  3DImage 9750
 	9753  TGUI 9753
@@ -620,6 +772,7 @@
 	1621  M1621 Northbridge [Aladdin-Pro II]
 	1631  M1631 Northbridge+3D Graphics [Aladdin TNT2]
 	1641  M1641 Northbridge [Aladdin-Pro IV]
+	1647  M1647 [MaGiK1] PCI North Bridge
 	3141  M3141
 	3143  M3143
 	3145  M3145
@@ -629,26 +782,26 @@
 	3307  M3307 MPEG-I Video Controller
 	3309  M3309 MPEG-II Video w/ Software Audio Decoder
 	3321  M3321 MPEG-II Audio/Video Decoder
-	5212  ALI M4803
+	5212  M4803
 	5215  ALI PCI EIDE Controller
 	5217  M5217H
 	5219  M5219
 	5225  M5225
 	5229  M5229
 	5235  M5235
-	5237  ALI M5237 PCI USB Host Controller
+	5237  M5237 PCI USB Host Controller
 	5240  EIDE Controller
 	5241  PCMCIA Bridge
 	5242  General Purpose Controller
 	5243  PCI to PCI Bridge Controller
 	5244  Floppy Disk Controller
-	5247  ALI M1541 PCI to PCI Bridge
-	5251  M5251 P1394 OHCI Controller
-	5427  ALI PCI to AGP Bridge
-	5451  ALI M5451 PCI AC-Link Controller Audio Device
-	5453  ALI M5453 PCI AC-Link Controller Modem Device
-	7101  ALI M7101 PCI PMU Power Management Controller
-		10b9 7101  ALI M7101 PCI PMU Power Management Controller
+	5247  M1541 PCI to PCI Bridge
+	5251  M5251 P1394 Controller
+	5427  PCI to AGP Bridge
+	5451  M5451 PCI AC-Link Controller Audio Device
+	5453  M5453 PCI AC-Link Controller Modem Device
+	7101  M7101 PCI PMU Power Management Controller
+		10b9 7101  M7101 PCI PMU Power Management Controller
 1028  Dell Computer Corporation
 	0001  PowerEdge Expandable RAID Controller 2/Si
 	0002  PowerEdge Expandable RAID Controller 3/Di
@@ -656,8 +809,10 @@
 	0004  PowerEdge Expandable RAID Controller 3/Si
 	0005  PowerEdge Expandable RAID Controller 3/Di
 	0006  PowerEdge Expandable RAID Controller 3/Di
+	0007  Remote Assitant Card 3
 	0008  PowerEdge Expandable RAID Controller 3/Di
 	000a  PowerEdge Expandable RAID Controller 3/Di
+	000c  Embedded Systems Management Device 4
 1029  Siemens Nixdorf IS
 102a  LSI Logic
 	0000  HYDRA
@@ -698,9 +853,23 @@
 		102b ca6c  Millennium G250 AGP
 		102b dbbc  Millennium G200 AGP
 		102b dbc2  Millennium G200 MMS (Dual G200)
+		102b dbc3  G200 Multi-Monitor
 		102b dbc8  Millennium G200 MMS (Dual G200)
+		102b dbd2  G200 Multi-Monitor
+		102b dbd3  G200 Multi-Monitor
+		102b dbd4  G200 Multi-Monitor
+		102b dbd5  G200 Multi-Monitor
+		102b dbd8  G200 Multi-Monitor
+		102b dbd9  G200 Multi-Monitor
 		102b dbe2  Millennium G200 MMS (Quad G200)
+		102b dbe3  G200 Multi-Monitor
 		102b dbe8  Millennium G200 MMS (Quad G200)
+		102b dbf2  G200 Multi-Monitor
+		102b dbf3  G200 Multi-Monitor
+		102b dbf4  G200 Multi-Monitor
+		102b dbf5  G200 Multi-Monitor
+		102b dbf8  G200 Multi-Monitor
+		102b dbf9  G200 Multi-Monitor
 		102b f806  Mystique G200 Video AGP
 		102b ff00  MGA-G200 AGP
 		102b ff02  Mystique G200 AGP
@@ -708,16 +877,18 @@
 		102b ff04  Marvel G200 AGP
 		110a 0032  MGA-G200 AGP
 	0525  MGA G400 AGP
-		0e11 b16f  Matrox MGA-G400 AGP
+		0e11 b16f  MGA-G400 AGP
 		102b 0328  Millennium G400 16Mb SDRAM
 		102b 0338  Millennium G400 16Mb SDRAM
 		102b 0378  Millennium G400 32Mb SDRAM
 		102b 0541  Millennium G450 Dual Head
 		102b 0542  Millennium G450 Dual Head LX
-		102b 0641  Millennium G450 32Mb SDRAM
+		102b 0543  Millennium G450 Single Head LX
+		102b 0641  Millennium G450 32Mb SDRAM Dual Head
 		102b 0642  Millennium G450 32Mb SDRAM Dual Head LX
+		102b 0643  Millennium G450 32Mb SDRAM Single Head LX
 		102b 07c0  Millennium G450 Dual Head LE
-		102b 07c1  Millennium G450 SDR Dual Head
+		102b 07c1  Millennium G450 SDR Dual Head LE
 		102b 0d41  Millennium G450 Dual Head PCI
 		102b 0d42  Millennium G450 Dual Head LX PCI
 		102b 0e00  Marvel G450 eTV
@@ -733,11 +904,24 @@
 		102b 2159  Millennium G400 Dual Head 16Mb
 		102b 2179  Millennium G400 MAX/Dual Head 32Mb
 		102b 217d  Millennium G400 Dual Head Max
+		102b 23c0  Millennium G450
+		102b 23c1  Millennium G450
+		102b 23c2  Millennium G450 DVI
+		102b 23c3  Millennium G450 DVI
 		102b 2f58  Millennium G400
 		102b 2f78  Millennium G400
 		102b 3693  Marvel G400 AGP
-		1705 0001  Millennium G450 32MB SGRAM
-		b16f 0e11  Matrox MGA-G400 AGP
+		102b 5dd0  4Sight II
+		102b 5f50  4Sight II
+		102b 5f51  4Sight II
+		102b 5f52  4Sight II
+		102b 9010  Millennium G400 Dual Head
+		1458 0400  GA-G400
+		1705 0001  Digital First Millennium G450 32MB SGRAM
+		1705 0002  Digital First Millennium G450 16MB SGRAM
+		1705 0003  Digital First Millennium G450 32MB
+		1705 0004  Digital First Millennium G450 16MB
+		b16f 0e11  MGA-G400 AGP
 	0d10  MGA Ultima/Impression
 	1000  MGA G100 [Productiva]
 		102b ff01  Productiva G100
@@ -752,12 +936,15 @@
 		110a 001e  MGA-G100 AGP
 	2007  MGA Mistral
 	2527  MGA G550 AGP
+		102b 0f83  Millennium G550
 		102b 0f84  Millennium G550 Dual Head DDR 32Mb
+		102b 1e41  Millennium G550
 	4536  VIA Framegrabber
 	6573  Shark 10/100 Multiport SwitchNIC
 102c  Chips and Technologies
 	00b8  F64310
 	00c0  F69000 HiQVideo
+		102c 00c0  F69000 HiQVideo
 	00d0  F65545
 	00d8  F65545
 	00dc  F65548
@@ -796,6 +983,7 @@
 	0029  PowerVR PCX1
 	002a  PowerVR 3D
 	0035  USB
+		12ee 7000  Root Hub
 	003e  NAPCCARD Cardbus Controller
 	0046  PowerVR PCX2 [midas]
 	005a  Vrc5074 [Nile 4]
@@ -812,6 +1000,11 @@
 	0074  56k Voice Modem
 		1033 8014  RCV56ACF 56k Voice Modem
 	009b  Vrc5476
+	00a6  VRC5477 AC97
+	00cd  IEEE 1394 [OrangeLink] Host Controller
+		12ee 8011  Root hub
+	00e0  USB 2.0
+		12ee 7001  Root hub
 1034  Framatome Connectors USA Inc.
 1035  Comp. & Comm. Research Lab
 1036  Future Domain Corp.
@@ -870,8 +1063,9 @@
 		1092 4920  SpeedStar A70
 		1569 6326  SiS6326 GUI Accelerator
 	7001  7001
-	7007  OHCI Compliant FireWire Controller
+	7007  FireWire Controller
 	7012  SiS7012 PCI Audio Accelerator
+	7013  56k Winmodem (Smart Link HAMR5600 compatible)
 	7016  SiS7016 10/100 Ethernet Adapter
 		1039 7016  SiS7016 10/100 Ethernet Adapter
 	7018  SiS PCI Audio Accelerator
@@ -901,8 +1095,17 @@
 103b  Tatung Co. of America
 103c  Hewlett-Packard Company
 	1005  A4977A Visualize EG
-	1030  J2585A
-	1031  J2585B
+	1028  Tach TL Fibre Channel Host Adapter
+	1029  Tach XL2 Fibre Channel Host Adapter
+		107e 000f  Interphase 5560 Fibre Channel Adapter
+		9004 9210  1Gb/2Gb Family Fibre Channel Controller
+		9004 9211  1Gb/2Gb Family Fibre Channel Controller
+	102a  Tach TS Fibre Channel Host Adapter
+		107e 000e  Interphase 5540/5541 Fibre Channel Adapter
+		9004 9110  1Gb/2Gb Family Fibre Channel Controller
+		9004 9111  1Gb/2Gb Family Fibre Channel Controller
+	1030  J2585A DeskDirect 10/100VG NIC
+	1031  J2585B HP 10/100VG PCI LAN Adapter
 		103c 1040  J2973A DeskDirect 10BaseT NIC
 		103c 1041  J2585B DeskDirect 10/100VG NIC
 		103c 1042  J2970A DeskDirect 10BaseT/2 NIC
@@ -917,8 +1120,11 @@
 	121a  NetServer SMIC Controller
 	121b  NetServer Legacy COM Port Decoder
 	121c  NetServer PCI COM Port Decoder
-	2910  E2910A
-	2925  E2925A
+	1229  zx1 System Bus Adapter
+	122a  zx1 I/O Controller
+	122e  zx1 Local Bus Adapter
+	2910  E2910A PCIBus Exerciser
+	2925  E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer
 103e  Solliday Engineering
 103f  Synopsys/Logic Modeling Group
 1040  Accelgraphics Inc.
@@ -930,11 +1136,49 @@
 	3010  Samurai_1
 	3020  Samurai_IDE
 1043  Asustek Computer, Inc.
+	0675  ISDNLink P-IN100-ST-D
+	4057  V8200 GeForce 3
 1044  Distributed Processing Technology
 	1012  Domino RAID Engine
 	a400  SmartCache/Raid I-IV Controller
 	a500  PCI Bridge
 	a501  SmartRAID V Controller
+		1044 c001  PM1554U2 Ultra2 Single Channel
+		1044 c002  PM1654U2 Ultra2 Single Channel
+		1044 c003  PM1564U3 Ultra3 Single Channel
+		1044 c004  PM1564U3 Ultra3 Dual Channel
+		1044 c005  PM1554U2 Ultra2 Single Channel (NON ACPI)
+		1044 c00a  PM2554U2 Ultra2 Single Channel
+		1044 c00b  PM2654U2 Ultra2 Single Channel
+		1044 c00c  PM2664U3 Ultra3 Single Channel
+		1044 c00d  PM2664U3 Ultra3 Dual Channel
+		1044 c00e  PM2554U2 Ultra2 Single Channel (NON ACPI)
+		1044 c00f  PM2654U2 Ultra2 Single Channel (NON ACPI)
+		1044 c014  PM3754U2 Ultra2 Single Channel (NON ACPI)
+		1044 c015  PM3755U2B Ultra2 Single Channel (NON ACPI)
+		1044 c016  PM3755F Fibre Channel (NON ACPI)
+		1044 c01e  PM3757U2 Ultra2 Single Channel
+		1044 c01f  PM3757U2 Ultra2 Dual Channel
+		1044 c020  PM3767U3 Ultra3 Dual Channel
+		1044 c021  PM3767U3 Ultra3 Quad Channel
+		1044 c028  PM2865U3 Ultra3 Single Channel
+		1044 c029  PM2865U3 Ultra3 Dual Channel
+		1044 c02a  PM2865F Fibre Channel
+		1044 c03c  2000S Ultra3 Single Channel
+		1044 c03d  2000S Ultra3 Dual Channel
+		1044 c03e  2000F Fibre Channel
+		1044 c046  3000S Ultra3 Single Channel
+		1044 c047  3000S Ultra3 Dual Channel
+		1044 c048  3000F Fibre Channel
+		1044 c050  5000S Ultra3 Single Channel
+		1044 c051  5000S Ultra3 Dual Channel
+		1044 c052  5000F Fibre Channel
+		1044 c05a  2400A UDMA Four Channel
+		1044 c05b  2400A UDMA Four Channel DAC
+		1044 c064  3010S Ultra3 Dual Channel
+		1044 c065  3010S Ultra3 Four Channel
+		1044 c066  3010S Fibre Channel
+	a511  SmartRAID V Controller
 1045  OPTi Inc.
 	a0f8  82C750 [Vendetta] USB Controller
 	c101  92C264
@@ -966,7 +1210,9 @@
 104a  SGS Thomson Microelectronics
 	0008  STG 2000X
 	0009  STG 1764X
+	0981  DEC-Tulip compatible 10/100 Ethernet
 	1746  STG 1764X
+	2774  DEC-Tulip compatible 10/100 Ethernet
 	3520  MPEG-II decoder card
 104b  BusLogic
 	0140  BT-946C (old) [multimaster  01]
@@ -978,6 +1224,13 @@
 	1000  Eagle i/f AS
 	3d04  TVP4010 [Permedia]
 	3d07  TVP4020 [Permedia 2]
+		1011 4d10  Comet
+		1040 000f  AccelStar II
+		1040 0011  AccelStar II
+		1048 0a31  WINNER 2000
+		1048 0a32  GLoria Synergy
+		1048 0a35  GLoria Synergy
+		107d 2633  WinFast 3D L2300
 		1092 0127  FIRE GL 1000 PRO
 		1092 0136  FIRE GL 1000 PRO
 		1092 0141  FIRE GL 1000 PRO
@@ -990,15 +1243,26 @@
 		1092 0156  FIRE GL 1000 PRO
 		1092 0157  FIRE GL 1000 PRO
 		1097 3d01  Jeronimo Pro
+		1102 100f  Graphics Blaster Extreme
 		3d3d 0100  Reference Permedia 2 3D
 	8000  PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
 		e4bf 1010  CF1-1-SNARE
 		e4bf 1020  CF1-2-SNARE
-	8009  OHCI Compliant FireWire Controller
-	8019  TSB12LV23 OHCI Compliant IEEE-1394 Controller
+	8009  FireWire Controller
+		104d 8032  8032 OHCI i.LINK (IEEE 1394) Controller
+	8017  PCI4410 FireWire Controller
+	8019  TSB12LV23 IEEE-1394 Controller
 		11bd 000a  Studio DV500-1394
 		11bd 000e  Studio DV
 		e4bf 1010  CF2-1-CYMBAL
+	8020  TSB12LV26 IEEE-1394 Controller (Link)
+	8021  TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated)
+		104d 80e7  Notebook Computer Vaio PCG Series
+	8022  TSB43AB22 IEEE-1394 Controller (PHY/Link) 1394a-2000
+	8024  TSB43AB23 IEEE-1394 Controller (PHY/Link) 1394a-2000
+	8026  TSB43AB21 IEEE-1394 Controller (PHY/Link) 1394a-2000
+	8027  PCI4451 IEEE-1394 Controller
+		1028 00e6  PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
 	a001  TDC1570
 	a100  TDC1561
 	ac10  PCI1050
@@ -1017,10 +1281,12 @@
 	ac1e  PCI1211
 	ac1f  PCI1251B
 	ac20  TI 2030
+	ac21  PCI2031
 	ac30  PCI1260 PC card Cardbus Controller
 	ac40  PCI4450 PC card Cardbus Controller
 	ac41  PCI4410 PC card Cardbus Controller
 	ac42  PCI4451 PC card Cardbus Controller
+		1028 00e6  PCI4451 PC card CardBus Controller (Dell Inspiron 8100)
 	ac50  PCI1410 PC card Cardbus Controller
 	ac51  PCI1420
 	ac52  PCI1451 PC card Cardbus Controller
@@ -1032,6 +1298,7 @@
 	8039  CXD3222 i.LINK Controller
 	8056  Rockwell HCF 56K modem
 	808a  Memory Stick Controller
+	80e7  Vaio PCG-GR114MK
 104e  Oak Technology, Inc
 	0017  OTI-64017
 	0107  OTI-107 [Spitfire]
@@ -1057,7 +1324,7 @@
 1055  EFAR Microsystems
 	9130  EIDE Controller
 	9460  PCI to ISA Bridge
-	9462  USB Universal Host Controller [OHCI]
+	9462  USB Universal Host Controller
 	9463  Power Management Controller [Bridge]
 1056  ICL
 # Motorola made a mistake and used 1507 instead of 1057 in some chips. Please look at the 1507 entry as well when updating this.
@@ -1095,13 +1362,24 @@
 1059  Teknor Industrial Computers Inc
 105a  Promise Technology, Inc.
 	0d30  20265
+		105a 4d33  Ultra100
+	0d38  20263
+		105a 4d39  Fasttrak66
 	4d30  20267
+		105a 4d33  Ultra100
+		105a 4d39  Fasttrak100
 	4d33  20246
 	4d38  20262
+		105a 4d30  Ultra Device on SuperTrak
+		105a 4d33  Ultra66
+		105a 4d39  Fasttrak66
 	4d68  20268
-	6268  20268R
+		105a 4d68  Ultra100TX2
 	4d69  20269
+	5275  PDC20276 IDE
+		105a 0275  SuperTrak SX6000 IDE
 	5300  DC5300
+	6268  20268R
 105b  Foxconn International, Inc.
 105c  Wipro Infotech Limited
 105d  Number 9 Computer Company
@@ -1166,7 +1444,9 @@
 	0001  DAC960P
 	0002  DAC960PD
 	0010  DAC960PX
-	ba55  eXtremeRAID support Device
+	0050  AcceleRAID 352/170/160 support Device
+	ba55  eXtremeRAID 1100 support Device
+	ba56  eXtremeRAID 2000/3000 support Device
 106a  Aten Research Inc
 106b  Apple Computer Inc.
 	0001  Bandit PowerPC host bridge
@@ -1237,19 +1517,21 @@
 1075  Advanced Integrations Research
 1076  Chaintech Computer Co. Ltd
 1077  QLogic Corp.
-	1016  QLA10160
-	1020  ISP1020
-	1022  ISP1022
-	1080  QLA1080
-	1216  QLA12160
+	1016  ISP10160 Single Channel Ultra3 SCSI Processor
+	1020  ISP1020 Fast-wide SCSI
+	1022  ISP1022 Fast-wide SCSI
+	1080  ISP1080 SCSI Host Adapter
+	1216  ISP12160 Dual Channel Ultra3 SCSI Processor
 		101e 8471  QLA12160 on AMI MegaRAID
 		101e 8493  QLA12160 on AMI MegaRAID
-	1240  QLA1240
-	1280  QLA1280
-	2020  ISP2020A
-	2100  QLA2100
+	1240  ISP1240 SCSI Host Adapter
+	1280  ISP1280
+	2020  ISP2020A Fast!SCSI Basic Adapter
+	2100  QLA2100 64-bit Fibre Channel Adapter
+		1077 0001  QLA2100 64-bit Fibre Channel Adapter
 	2200  QLA2200
-	2300  QLA2300
+	2300  QLA2300 64-bit FC-AL Adapter
+	2312  QLA2312 Fibre Channel Adapter
 1078  Cyrix Corporation
 	0000  5510 [Grappa]
 	0001  PCI Master
@@ -1259,6 +1541,10 @@
 	0102  5530 IDE [Kahlua]
 	0103  5530 Audio [Kahlua]
 	0104  5530 Video [Kahlua]
+	0400  ZFMicro PCI Bridge
+	0401  ZFMicro Chipset SMI
+	0402  ZFMicro Chipset IDE
+	0403  ZFMicro Expansion Bus
 1079  I-Bus
 107a  NetWorth
 107b  Gateway 2000
@@ -1266,9 +1552,22 @@
 107d  LeadTek Research Inc.
 	0000  P86C850
 107e  Interphase Corporation
-	0001  ATM Interface Card
+	0001  5515 ATM Adapter [Flipper]
 	0002  100 VG AnyLan Controller
-	0008  155 Mbit ATM Controller
+	0004  5526 Fibre Channel Host Adapter
+	0005  x526 Fibre Channel Host Adapter
+	0008  5525/5575 ATM Adapter (155 Mbit) [Atlantic]
+	9003  5535-4P-BRI-ST
+	9007  5535-4P-BRI-U
+	9008  5535-1P-SR
+	900c  5535-1P-SR-ST
+	900e  5535-1P-SR-U
+	9011  5535-1P-PRI
+	9013  5535-2P-PRI
+	9023  5536-4P-BRI-ST
+	9027  5536-4P-BRI-U
+	9031  5536-1P-PRI
+	9033  5536-2P-PRI
 107f  Data Technology Corporation
 	0802  SL82C105
 1080  Contaq Microsystems
@@ -1341,6 +1640,7 @@
 	00a8  Speedstar 64
 	0550  Viper V550
 	08d4  Supra 2260 Modem
+	094c  SupraExpress 56i Pro
 	1092  Viper V330
 	6120  Maximum DVD
 	8810  Stealth SE
@@ -1384,6 +1684,9 @@
 	0647  PCI0647
 	0648  PCI0648
 	0649  PCI0649
+		0e11 005d  Integrated Ultra ATA-100 Dual Channel Controller
+		0e11 007e  Integrated Ultra ATA-100 IDE RAID Controller
+		101e 0649  AMI MegaRAID IDE 100 Controller
 	0650  PBC0650A
 	0670  USB0670
 	0673  USB0673
@@ -1405,6 +1708,7 @@
 		13e9 0070  Win/TV (Video Section)
 	036e  Bt878
 		0070 13eb  WinTV/GO
+		0070 ff01  Viewcast Osprey 200
 		127a 0001  Bt878 Mediastream Controller NTSC
 		127a 0002  Bt878 Mediastream Controller PAL BG
 		127a 0003  Bt878a Mediastream Controller PAL BG
@@ -1453,6 +1757,7 @@
 		1852 1852  FlyVideo'98 (with FM Tuner)
 	0878  Bt878
 		0070 13eb  WinTV/GO
+		0070 ff01  Viewcast Osprey 200
 		127a 0001  Bt878 Video Capture (Audio Section)
 		127a 0002  Bt878 Video Capture (Audio Section)
 		127a 0003  Bt878 Video Capture (Audio Section)
@@ -1560,9 +1865,25 @@
 	0001  i960 PCI bus interface
 	1076  VScom 800 8 port serial adaptor
 	1077  VScom 400 4 port serial adaptor
+	1078  VScom 210 2 port serial and 1 port parallel adaptor
+	1103  VScom 200 2 port serial adaptor
+	1146  VScom 010 1 port parallel adaptor
+	1147  VScom 020 2 port parallel adaptor
+	9030  PCI <-> IOBus Bridge Hot Swap
+		15ed 1002  MCCS 8-port Serial Hot Swap
+		15ed 1003  MCCS 16-port Serial Hot Swap
 	9036  9036
 	9050  PCI <-> IOBus Bridge
 		10b5 2273  SH-ARC SoHard ARCnet card
+		1522 0001  RockForce 4 Port V.90 Data/Fax/Voice Modem
+		1522 0002  RockForce 2 Port V.90 Data/Fax/Voice Modem
+		1522 0010  RockForce2000 4 Port V.90 Data/Fax/Voice Modem
+		1522 0020  RockForce2000 2 Port V.90 Data/Fax/Voice Modem
+		15ed 1000  Macrolink MCCS 8-port Serial
+		15ed 1001  Macrolink MCCS 16-port Serial
+		15ed 1002  Macrolink MCCS 8-port Serial Hot Swap
+		15ed 1003  Macrolink MCCS 16-port Serial Hot Swap
+		d531 c002  PCIntelliCAN 2xSJA1000 CAN bus
 		d84d 4006  EX-4006 1P
 		d84d 4008  EX-4008 1P EPP/ECP
 		d84d 4014  EX-4014 2P
@@ -1586,6 +1907,7 @@
 	906e  9060ES
 	9080  9080
 		10b5 9080  9080 [real subsystem ID not set]
+		129d 0002  Aculab PCI Prosidy card
 	a001  GTEK Jetport II 2 port serial adaptor
 	c001  GTEK Cyclone 16/32 port serial adaptor
 10b6  Madge Networks
@@ -1607,14 +1929,19 @@
 	000a  Smart 100/16/4 PCI Ringnode
 		10b6 000a  Smart 100/16/4 PCI Ringnode
 	000b  16/4 CardBus Adapter Mk2
+		10b6 0008  16/4 CardBus Adapter Mk2
 		10b6 000b  16/4 Cardbus Adapter Mk2
-	1000  Collage 25 ATM Adapter
+	000c  RapidFire 3140V2 16/4 TR Adapter
+		10b6 000c  RapidFire 3140V2 16/4 TR Adapter
+	1000  Collage 25/155 ATM Client Adapter
 	1001  Collage 155 ATM Server Adapter
 10b7  3Com Corporation
-	0001  3c985 1000BaseSX
-	3390  Token Link Velocity
+	0001  3c985 1000BaseSX (SX/TX)
+	1007  Mini PCI 56k Winmodem
+		10b7 615c  Mini PCI 56K Modem
+	3390  3c339 TokenLink Velocity
 	3590  3c359 TokenLink Velocity XL
-		10b7 3590  TokenLink Velocity XL Adapter
+		10b7 3590  TokenLink Velocity XL Adapter (3C359/359B)
 	4500  3c450 Cyclone/unknown
 	5055  3c555 Laptop Hurricane
 	5057  3c575 [Megahertz] 10/100 LAN CardBus
@@ -1622,6 +1949,7 @@
 	5157  3c575 [Megahertz] 10/100 LAN CardBus
 		10b7 5b57  3C575 Megahertz 10/100 LAN Cardbus PC Card
 	5257  3CCFE575CT Cyclone CardBus
+		10b7 5c57  FE575C-3Com 10/100 LAN CardBus-Fast Ethernet
 	5900  3c590 10BaseT [Vortex]
 	5920  3c592 EISA 10mbps Demon/Vortex
 	5950  3c595 100BaseTX [Vortex]
@@ -1632,10 +1960,20 @@
 		10b7 5b57  3C575 Megahertz 10/100 LAN Cardbus PC Card
 	6055  3c556 Hurricane CardBus
 	6056  3c556B Hurricane CardBus
+		10b7 6556  10/100 Mini PCI Ethernet Adapter
 	6560  3CCFE656 Cyclone CardBus
+		10b7 656a  3CCFEM656 10/100 LAN 56K Modem CardBus
+	6561  3CCFEM656 10/100 LAN 56K Modem CardBus
+		10b7 656b  3CCFEM656 10/100 LAN 56K Modem CardBus
 	6562  3CCFEM656 [id 6562] Cyclone CardBus
+		10b7 656b  3CCFEM656B 10/100 LAN 56K Modem CardBus
+	6563  3CCFEM656B 10/100 LAN 56K Modem CardBus
+		10b7 656b  3CCFEM656 10/100 LAN 56K Modem CardBus
 	6564  3CCFEM656 [id 6564] Cyclone CardBus
 	7646  3cSOHO100-TX Hurricane
+	7940  3c803 FDDILink UTP Controller
+	7980  3c804 FDDILink SAS Controller
+	7990  3c805 FDDILink DAS Controller
 	8811  Token ring
 	9000  3c900 10BaseT [Boomerang]
 	9001  3c900 Combo [Boomerang]
@@ -1646,7 +1984,7 @@
 	9006  3c900B-TPC [Etherlink XL TPC]
 	900a  3c900B-FL [Etherlink XL FL]
 	9050  3c905 100BaseTX [Boomerang]
-	9051  3c905 100BaseT4
+	9051  3c905 100BaseT4 [Boomerang]
 	9055  3c905B 100BaseTX [Cyclone]
 		1028 0080  3C905B Fast Etherlink XL 10/100
 		1028 0081  3C905B Fast Etherlink XL 10/100
@@ -1669,19 +2007,26 @@
 		1028 0098  3C905B Fast Etherlink XL 10/100
 		1028 0099  3C905B Fast Etherlink XL 10/100
 		10b7 9055  3C905B Fast Etherlink XL 10/100
-	9056  3c905B-T4
+	9056  3c905B-T4 [Fast EtherLink XL 10/100]
 	9058  3c905B-Combo [Deluxe Etherlink XL 10/100]
 	905a  3c905B-FX [Fast Etherlink XL FX 10/100]
-	9200  3c905C-TX [Fast Etherlink]
+	9200  3c905C-TX/TX-M [Tornado]
 		10b7 1000  3C905C-TX Fast Etherlink for PC Management NIC
+		10b7 7000  10/100 Mini PCI Ethernet Adapter
 	9800  3c980-TX [Fast Etherlink XL Server Adapter]
 		10b7 9800  3c980-TX Fast Etherlink XL Server Adapter
 	9805  3c980-TX 10/100baseTX NIC [Python-T]
+		10b7 1201  3c982-TXM 10/100baseTX Dual Port A [Hydra]
+		10b7 1202  3c982-TXM 10/100baseTX Dual Port B [Hydra]
 		10b7 9805  3c980 10/100baseTX NIC [Python-T]
+	9902  3CR990-TX-95 56-bit Typhoon Client
+	9903  3CR990-TX-97 168-bit Typhoon Client
+	9908  3CR990SVR95 56-bit Typhoon Server
+	9909  3CR990SVR97 Typhoon Server
 10b8  Standard Microsystems Corp [SMC]
 	0005  83C170QF
-		1055 e000  LANEPIC
-		1055 e002  LANEPIC
+		1055 e000  LANEPIC 10/100 [EVB171Q-PCI]
+		1055 e002  LANEPIC 10/100 [EVB171G-PCI]
 		10b8 a011  EtherPower II 10/100
 		10b8 a014  EtherPower II 10/100
 		10b8 a015  EtherPower II 10/100
@@ -1723,7 +2068,13 @@
 	1543  M1543
 	1621  M1621
 	1631  ALI M1631 PCI North Bridge Aladdin Pro III
+	1632  M1632M Northbridge+Trident
 	1641  ALI M1641 PCI North Bridge Aladdin Pro IV
+	1644  M1644/M1644T Northbridge+Trident
+	1646  M1646 Northbridge+Trident
+	1647  M1647 Northbridge [MAGiK 1 / MobileMAGiK 1]
+	1651  M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM]
+	1671  M1671 Northbridge [Aladdin-P4]
 	3141  M3141
 	3143  M3143
 	3145  M3145
@@ -1738,11 +2089,21 @@
 	5219  M5219
 	5225  M5225
 	5229  M5229 IDE
+		1043 8053  A7A66 Motherboard IDE
 	5235  M5225
-	5237  M5237 USB
-	5243  M5243
-	5247  M5247
-	5451  M5451 PCI South Bridge Audio
+	5237  USB 1.1 Controller
+	5239  USB 2.0 Controller
+	5243  M1541 PCI to AGP Controller
+	5247  PCI to AGP Controller
+	5251  M5251 P1394 OHCI 1.0 Controller
+	5253  M5253 P1394 OHCI 1.1 Controller
+	5261  M5261 Ethernet Controller
+	5451  M5451 PCI AC-Link Controller Audio Device
+	5453  M5453 PCI AC-Link Controller Modem Device
+	5455  M5455 PCI AC-Link Controller Audio Device
+	5457  M5457 AC-Link Modem Interface Controller
+	5471  M5471 Memory Stick Controller
+	5473  M5473 SD-MMC Controller
 	7101  M7101 PMU
 		10b9 7101  ALI M7101 Power Management Controller
 10ba  Mitsubishi Electric Corp.
@@ -1804,6 +2165,7 @@
 		110a 8005  MagicMedia 256AV Audio Device
 		14c0 0004  MagicMedia 256AV Audio Device
 	8006  NM2360 [MagicMedia 256ZX Audio]
+	8016  NM2360 [MagicMedia 256ZX Audio]
 10c9  Dataexpert Corporation
 10ca  Fujitsu Microelectr., Inc.
 10cb  Omron Corporation
@@ -1830,6 +2192,7 @@
 10d9  Macronix, Inc. [MXIC]
 	0512  MX98713
 	0531  MX987x5
+		1186 1200  DFE-540TX ProFAST 10/100 Adapter
 	8625  MX86250
 	8888  MX86200
 10da  Compaq IPG-Austin
@@ -1907,12 +2270,13 @@
 	002f  Vanta [NV6]
 	00a0  Riva TNT2
 		14af 5810  Maxi Gamer Xentor
-	0100  GeForce 256
+	0100  NV10 (GeForce 256)
 		1043 0200  AGP-V6600 SGRAM
 		1043 0201  AGP-V6600 SDRAM
 		1043 4008  AGP-V6600 SGRAM
 		1043 4009  AGP-V6600 SDRAM
 		1102 102d  CT6941 GeForce 256
+		14af 5022  3D Prophet SE
 	0101  GeForce 256 DDR
 		1043 0202  AGP-V6800 DDR
 		1043 400a  AGP-V6800 DDR SGRAM
@@ -1921,16 +2285,43 @@
 		14af 5021  3D Prophet DDR-DVI
 	0103  Quadro (GeForce 256 GL)
 	0110  NV11 (GeForce2 MX)
+		1043 4015  AGP-7100 Pro with TV output
+		1043 4031  V7100 Pro with TV output
 	0111  NV11 (GeForce2 MX DDR)
 	0112  GeForce2 Go
 	0113  NV11 (GeForce2 MXR)
 	0150  NV15 (GeForce2 Pro)
+		1043 4016  V7700 AGP Video Card
 		107d 2840  WinFast GeForce2 GTS with TV output
+		1462 8831  Creative GeForce2 Pro
 	0151  NV15 DDR (GeForce2 GTS)
 	0152  NV15 Bladerunner (GeForce2 Ultra)
 	0153  NV15 GL (Quadro2 Pro)
+	0170  NV1x
+	0171  NV1x
+	0172  NV1x
+	0173  NV1x
+	0174  NV1x
+	0175  NV1x
+	0176  GeForce4 420 Go 32M
+	0178  NV1x
+	0179  GeForce4 440 Go 64M
+	017a  NV1x
+	017b  NV1x
+	017c  NV1x
+	01a0  GeForce2 Integrated GPU
+	01bc  nForce IDE
 	0200  NV20 (GeForce3)
+		1043 402f  AGP-V8200 DDR
+	0201  GeForce3 Ti200
+	0202  GeForce3 Ti500
+		1043 405b  V8200 T5
 	0203  Quadro DCC
+	0250  NV25 (GeForce 4)
+	0251  GeForce4 Ti 4400
+	0253  GeForce4 Ti 4200
+	0258  NV25 (GeForce 4)
+	025b  NV25 (GeForce 4)
 10df  Emulex Corporation
 	10df  Light Pulse Fibre Channel Adapter
 	1ae5  LP6000 Fibre Channel Host Adapter
@@ -1962,14 +2353,15 @@
 	8043  LANai4.x [Myrinet LANai interface chip]
 	8062  S5933_PARASTATION
 	807d  S5933 [Matchmaker]
-	8088  Kingsberg Spacetec Format Synchronizer
-	8089  Kingsberg Spacetec Serial Output Board
+	8088  Kongsberg Spacetec Format Synchronizer
+	8089  Kongsberg Spacetec Serial Output Board
 	809c  S5933_HEPC3
 	80d7  PCI-9112
 	80d9  PCI-9118
 	80da  PCI-9812
 	811a  PCI-IEEE1355-DS-DE Interface
 	8170  S5933 [Matchmaker] (Chipset Development Tool)
+	82db  AJA HDNTV HD SDI Framestore
 10e9  Alps Electric Co., Ltd.
 10ea  Intergraphics Systems
 	1680  IGA-1680
@@ -1993,7 +2385,7 @@
 		10ec 8129  RT8129 Fast Ethernet Adapter
 	8138  RT8139 (B/C) Cardbus Fast Ethernet Adapter
 		10ec 8138  RT8139 (B/C) Fast Ethernet Adapter
-	8139  RTL-8139
+	8139  RTL-8139/8139C
 		1025 8920  ALN-325
 		1025 8921  ALN-325
 		10bd 0320  EP-320X-R
@@ -2037,6 +2429,8 @@
 	000c  TARGA 1000
 10fb  Thesys Gesellschaft für Mikroelektronik mbH
 10fc  I-O Data Device, Inc.
+# What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives
+	0003  Cardbus IDE Controller
 10fd  Soyo Computer, Inc
 10fe  Fast Multimedia AG
 10ff  NCube
@@ -2062,18 +2456,26 @@
 		1102 8031  CT4831 SBLive! Value
 		1102 8040  CT4760 SBLive!
 		1102 8051  CT4850 SBLive! Value
-	7002  SB Live!
+	0004  SB Audigy
+	4001  SB Audigy FireWire Port
+	7002  SB Live! MIDI/Game Port
 		1102 0020  Gameport Joystick
+	7003  SB Audigy MIDI/Game port
 	8938  ES1371
 1103  Triones Technologies, Inc.
 	0003  HPT343
 	0004  HPT366 / HPT370
 		1103 0005  HPT370 UDMA100
+# Not HPT370A, It's HPT370. I don't know what ID HPT370A has.
+	0005  HPT370
 1104  RasterOps Corp.
 1105  Sigma Designs, Inc.
 	8300  REALmagic Hollywood Plus DVD Decoder
+	8400  EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder
 1106  VIA Technologies, Inc.
 	0305  VT8363/8365 [KT133/KM133]
+		1043 8042  A7V133/A7V133-C
+		147b a401  KT7/KT7-RAID/KT7A/KT7A-RAID
 	0391  VT8371 [KX133]
 	0501  VT8501 [Apollo MVP4]
 	0505  VT82C505
@@ -2093,6 +2495,7 @@
 	0605  VT8605 [ProSavage PM133]
 	0680  VT82C680 [Apollo P6]
 	0686  VT82C686 [Apollo Super South]
+		1043 8042  ATV133/A7V133-C
 		1106 0000  VT82C686/A PCI to ISA Bridge
 		1106 0686  VT82C686/A PCI to ISA Bridge
 	0691  VT82C693A/694x [Apollo PRO133x]
@@ -2105,25 +2508,30 @@
 	1571  VT82C416MV
 	1595  VT82C595/97 [Apollo VP2/97]
 	3038  UHCI USB
-		1234 0925  MVP3 USB Controller
 	3040  VT82C586B ACPI
-	3043  VT86C100A [Rhine 10/100]
+	3043  VT3043 [Rhine]
 		10bd 0000  VT86C100A Fast Ethernet Adapter
 		1106 0100  VT86C100A Fast Ethernet Adapter
-		1186 1400  DFE-530TX
-	3044  OHCI Compliant IEEE 1394 Host Controller
+		1186 1400  DFE-530TX rev A
+	3044  IEEE 1394 Host Controller
 	3050  VT82C596 Power Management
 	3051  VT82C596 Power Management
 	3057  VT82C686 [Apollo Super ACPI]
-	3058  AC97 Audio Controller
+		1043 8042  ATV133/A7V133-C
+	3058  VT82C686 AC97 Audio Controller
+		1458 7600  Onboard Audio
 		1462 3091  MS-6309 Onboard Audio
-	3059  AC97 Audio Controller
-	3065  Ethernet Controller
+	3059  VT8233 AC97 Audio Controller
+	3065  VT6102 [Rhine-II]
+		1186 1400  DFE-530TX rev A
+		1186 1401  DFE-530TX rev B
 	3068  AC97 Modem Controller
 	3074  VT8233 PCI to ISA Bridge
 	3091  VT8633 [Apollo Pro266]
 	3099  VT8367 [KT266]
+	3104  USB 2.0
 	3109  VT8233C PCI to ISA Bridge
+	3128  VT8753 [P4X266 AGP]
 	5030  VT82C596 ACPI [Apollo PRO]
 	6100  VT85C100A [Rhine II]
 	8231  VT8231 [PCI-to-ISA Bridge]
@@ -2160,6 +2568,7 @@
 	6120  SZB6120
 110b  Chromatic Research Inc.
 	0001  Mpact Media Processor
+	0004  Mpact 2
 110c  Mini-Max Technology, Inc.
 110d  Znyx Advanced Systems
 110e  CPU Technology
@@ -2183,6 +2592,7 @@
 	5105  10Mbps Network card
 	9211  EN-1207D Fast Ethernet Adapter
 		1113 9211  EN-1207D Fast Ethernet Adapter
+	9511  Fast Ethernet Adapter
 1114  Atmel Corporation
 1115  3D Labs
 1116  Data Translation
@@ -2287,6 +2697,7 @@
 	0001  Powerbis Bridge
 111d  Integrated Device Tech
 	0001  IDT77211 ATM Adapter
+	0003  IDT77252 ATM network controller
 111e  Eldec
 111f  Precision Digital Images
 	4a47  Precision MX Video engine interface
@@ -2329,8 +2740,11 @@
 	7912  EiconCard S91
 	7941  EiconCard S94
 	7942  EiconCard S94
+	7943  EiconCard S94
+	7944  EiconCard S94
 	b921  EiconCard P92
 	b922  EiconCard P92
+	b923  EiconCard P92
 	e001  DIVA 20PRO
 		1133 e001  DIVA Pro 2.0 S/T
 	e002  DIVA 20
@@ -2339,8 +2753,12 @@
 		1133 e003  DIVA Pro 2.0 U
 	e004  DIVA 20_U
 		1133 e004  DIVA 2.0 U
+	e005  DIVA LOW
+		1133 e005  DIVA 2.01 S/T
 	e010  DIVA Server BRI-2M
 		1133 e010  DIVA Server BRI-2M
+	e012  DIVA Server BRI-8M
+		1133 e012  DIVA Server BRI-8M
 	e014  DIVA Server PRI-30M
 		1133 e014  DIVA Server PRI-30M
 1134  Mercury Computer Systems
@@ -2367,8 +2785,8 @@
 113f  Equinox Systems, Inc.
 	0808  SST-64P Adapter
 	1010  SST-128P Adapter
-	80c0  SST-16P Adapter
-	80c4  SST-16P Adapter
+	80c0  SST-16P DB Adapter
+	80c4  SST-16P RJ Adapter
 	80c8  SST-16P Adapter
 	8888  SST-4P Adapter
 	9090  SST-8P Adapter
@@ -2415,6 +2833,7 @@
 		1148 9862  SK-9862 (1000Base-SX VF45 dual link)
 1149  Win System Corporation
 114a  VMIC
+	5579  VMIPCI-5579 (Reflective Memory Card)
 	7587  VMIVME-7587
 114b  Canopus Co., Ltd
 114c  Annabooks
@@ -2440,12 +2859,24 @@
 	001a  DataFirePRIme E1 (1-port)
 	001b  AccelePort C/X (IBM)
 	001d  DataFire RAS T1/E1/PRI
+		114f 0050  DataFire RAS E1 Adapter
+		114f 0051  DataFire RAS Dual E1 Adapter
+		114f 0052  DataFire RAS T1 Adapter
+		114f 0053  DataFire RAS Dual T1 Adapter
 	0023  AccelePort RAS
 	0024  DataFire RAS B4 ST/U
+		114f 0030  DataFire RAS BRI U Adapter
+		114f 0031  DataFire RAS BRI S/T Adapter
 	0026  AccelePort 4r 920
 	0027  AccelePort Xr 920
 	0034  AccelePort 2r 920
 	0035  DataFire DSP T1/E1/PRI cPCI
+	0040  AccelePort Xp
+	0042  AccelePort 2p PCI
+	0070  Datafire Micro V IOM2 (Europe)
+	0071  Datafire Micro V (Europe)
+	0072  Datafire Micro V IOM2 (North America)
+	0073  Datafire Micro V (North America)
 	6001  Avanstar
 1150  Thinking Machines Corp
 1151  JAE Electronics Inc.
@@ -2468,6 +2899,8 @@
 	0003  Cardbus Ethernet 10/100
 		1014 0181  10/100 EtherJet Cardbus Adapter
 		1014 1181  10/100 EtherJet Cardbus Adapter
+		1014 8181  10/100 EtherJet Cardbus Adapter
+		1014 9181  10/100 EtherJet Cardbus Adapter
 		115d 0181  Cardbus Ethernet 10/100
 		115d 1181  Cardbus Ethernet 10/100
 		8086 8181  EtherExpress PRO/100 Mobile CardBus 32 Adapter
@@ -2485,6 +2918,7 @@
 	000b  Cardbus Ethernet 10/100
 		1014 0183  10/100 EtherJet Cardbus Adapter
 		115d 0183  Cardbus Ethernet 10/100
+	000c  Mini-PCI V.90 56k Modem
 	000f  Cardbus Ethernet 10/100
 		1014 0183  10/100 EtherJet Cardbus Adapter
 		115d 0183  Cardbus Ethernet 10/100
@@ -2515,7 +2949,7 @@
 	0201  CSB5 South Bridge
 	0211  OSB4 IDE Controller
 	0212  CSB5 IDE Controller
-	0220  OSB4/CSB5 OHCI USB Controller
+	0220  OSB4/CSB5 USB Controller
 1167  Mutoh Industries Inc
 1168  Thine Electronics Inc
 1169  Centre for Development of Advanced Computing
@@ -2566,6 +3000,7 @@
 	0476  RL5c476 II
 	0477  RL5c477
 	0478  RL5c478
+	0552  R5C552 IEEE 1394 Controller
 1181  Telmatics International
 1183  Fujikura Ltd
 1184  Forks Inc
@@ -2574,6 +3009,8 @@
 	0100  DC21041
 	1002  Sundance Ethernet
 	1300  RTL8139 Ethernet
+	1340  DFE-690TXD CardBus PC Card
+	1561  DRP-32TXD Cardbus PC Card
 	4000  DL2K Ethernet
 1187  Advanced Technology Laboratories, Inc.
 1188  Shima Seiki Manufacturing Ltd.
@@ -2693,6 +3130,7 @@
 	0440  56k WinModem
 		0001 0440  LT WinModem 56k Data+Fax+Voice+Dsvd
 		1033 8015  LT WinModem 56k Data+Fax+Voice+Dsvd
+		1033 8047  LT WinModem 56k Data+Fax+Voice+Dsvd
 		1033 804f  LT WinModem 56k Data+Fax+Voice+Dsvd
 		10cf 102c  LB LT Modem V.90 56k
 		10cf 104a  BIBLO LT Modem 56k
@@ -2700,15 +3138,18 @@
 		1179 0001  Internal V.90 Modem
 		11c1 0440  LT WinModem 56k Data+Fax+Voice+Dsvd
 		122d 4101  MDP7800-U Modem
+		122d 4102  MDP7800SP-U Modem
 		13e0 0040  LT WinModem 56k Data+Fax+Voice+Dsvd
 		13e0 0440  LT WinModem 56k Data+Fax+Voice+Dsvd
 		13e0 0441  LT WinModem 56k Data+Fax+Voice+Dsvd
+		13e0 0450  LT WinModem 56k Data+Fax+Voice+Dsvd
 		13e0 f100  LT WinModem 56k Data+Fax+Voice+Dsvd
 		13e0 f101  LT WinModem 56k Data+Fax+Voice+Dsvd
 		144d 2101  LT56PV Modem
 		149f 0440  LT WinModem 56k Data+Fax+Voice+Dsvd
 	0441  56k WinModem
 		1033 804d  LT WinModem 56k Data+Fax
+		1033 8065  LT WinModem 56k Data+Fax
 		1092 0440  Supra 56i
 		1179 0001  Internal V.90 Modem
 		11c1 0440  LT WinModem 56k Data+Fax
@@ -2718,11 +3159,16 @@
 		13e0 0100  LT WinModem 56k Data+Fax
 		13e0 0410  LT WinModem 56k Data+Fax
 		13e0 0420  TelePath Internet 56k WinModem
+		13e0 0440  LT WinModem 56k Data+Fax
 		13e0 0443  LT WinModem 56k Data+Fax
+		13e0 f102  LT WinModem 56k Data+Fax
 		1416 9804  CommWave 56k Modem
 		141d 0440  LT WinModem 56k Data+Fax
 		144f 0441  Lucent 56k V.90 DF Modem
+		144f 0449  Lucent 56k V.90 DF Modem
+		144f 110d  Lucent Win Modem
 		1468 0441  Presario 56k V.90 DF Modem
+		1668 0440  Lucent Win Modem
 	0442  56k WinModem
 		0001 0440  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
 		11c1 0440  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
@@ -2731,6 +3177,7 @@
 		13e0 0442  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
 		13fc 2471  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
 		144d 2104  LT56PT Modem
+		144f 1104  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
 		149f 0440  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
 		1668 0440  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
 	0443  LT WinModem
@@ -2739,14 +3186,22 @@
 	0446  LT WinModem
 	0447  LT WinModem
 	0448  WinModem 56k
+		1014 0131  Lucent Win Modem
+		1033 8066  LT WinModem 56k Data+Fax+Voice+Dsvd
+		13e0 0030  56k Voice Modem
 		13e0 0040  LT WinModem 56k Data+Fax+Voice+Dsvd
+# Actiontech eth+modem card as used by Dell &c.
+		1668 2400  LT WinModem 56k (MiniPCI Ethernet+Modem)
 	0449  WinModem 56k
 		0e11 b14d  56k V.90 Modem
 		13e0 0020  LT WinModem 56k Data+Fax
 		13e0 0041  TelePath Internet 56k WinModem
+		1436 0440  Lucent Win Modem
 		144f 0449  Lucent 56k V.90 DFi Modem
+		1468 0440  Lucent Win Modem
 		1468 0449  Presario 56k V.90 DFi Modem
 	044a  F-1156IV WinModem (V90, 56KFlex)
+		10cf 1072  LB Global LT Modem
 		13e0 0012  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
 		13e0 0042  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
 		144f 1005  LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
@@ -2754,6 +3209,7 @@
 	044c  LT WinModem
 	044d  LT WinModem
 	044e  LT WinModem
+	044f  V90 WildWire Modem
 	0450  LT WinModem
 	0451  LT WinModem
 	0452  LT WinModem
@@ -2765,7 +3221,11 @@
 	0458  LT WinModem
 	0459  LT WinModem
 	045a  LT WinModem
+	0461  V90 WildWire Modem
+	0462  V90 WildWire Modem
 	0480  Venus Modem (V90, 56KFlex)
+	5811  FW323
+		dead 0800  FireWire Host Bus Adapter
 11c2  Sand Microelectronics
 11c3  NEC Corp
 11c4  Document Technologies, Inc
@@ -2796,6 +3256,7 @@
 11d2  Intercom Inc.
 11d3  Trancell Systems Inc
 11d4  Analog Devices
+	1805  SM56 PCI modem
 	1889  AD1889 sound chip
 11d5  Ikon Corporation
 	0115  10115
@@ -2932,7 +3393,7 @@
 		1092 8030  Monster Fusion
 		1092 8035  Monster Fusion AGP
 		10b0 0001  Dragon 4000
-		1102 1017  CT6760 3D Blaster Banshee
+		1102 1018  3D Blaster Banshee VE
 		121a 0001  Voodoo Banshee AGP
 		121a 0003  Voodoo Banshee AGP SGRAM
 		121a 0004  Voodoo Banshee
@@ -2962,6 +3423,7 @@
 		121a 0062  Voodoo3 3500 TV (SECAM)
 	0009  Voodoo 4 / Voodoo 5
 		121a 0009  Voodoo5 AGP 5500/6000
+	0057  Voodoo 3/3000 [Avenger]
 121b  Advanced Telecommunications Modules
 121c  Nippon Texaco., Ltd
 121d  Lippert Automationstechnik GmbH
@@ -3034,8 +3496,12 @@
 1243  Delphax
 1244  AVM Audiovisuelles MKTG & Computer System GmbH
 	0700  B1 ISDN
+	0800  C4 ISDN
 	0a00  A1 ISDN [Fritz]
 		1244 0a00  FRITZ!Card ISDN Controller
+	0e00  Fritz!PCI v2.0 ISDN
+	1100  C2 ISDN
+	1200  T1 ISDN
 1245  A.P.D., S.A.
 1246  Dipix Technologies, Inc.
 1247  Xylon Research, Inc.
@@ -3043,11 +3509,14 @@
 1249  Samsung Electronics Co., Ltd.
 124a  AEG Electrocom GmbH
 124b  SBS/Greenspring Modular I/O
+	0040  cPCI-200 Four Slot IndustryPack carrier
+		124b 9080  PCI9080 Bridge
 124c  Solitron Technologies, Inc.
 124d  Stallion Technologies, Inc.
 	0000  EasyConnection 8/32
 	0002  EasyConnection 8/64
 	0003  EasyIO
+	0004  EasyConnection/RA
 124e  Cylink
 124f  Infotrend Technology, Inc.
 	0041  IFT-2000 Series RAID Controller
@@ -3094,10 +3563,22 @@
 	1989  ESS Modem
 		125d 1989  ESS Modem
 	1998  ES1983S Maestro-3i PCI Audio Accelerator
+		1028 00e6  ES1983S Maestro-3i (Dell Inspiron 8100)
 	1999  ES1983S Maestro-3i PCI Modem Accelerator
+	199a  ES1983S Maestro-3i PCI Audio Accelerator
+	199b  ES1983S Maestro-3i PCI Modem Accelerator
 	2808  ES336H Fax Modem (Later Model)
 	2838  ES2838/2839 SuperLink Modem
 	2898  ES2898 Modem
+		125d 0424  ES56-PI Data Fax Modem
+		125d 0425  ES56T-PI Data Fax Modem
+		125d 0426  ES56V-PI Data Fax Modem
+		125d 0427  VW-PI Data Fax Modem
+		125d 0428  ES56ST-PI Data Fax Modem
+		125d 0429  ES56SV-PI Data Fax Modem
+		147a c001  ES56-PI Data Fax Modem
+		14fe 0428  ES56-PI Data Fax Modem
+		14fe 0429  ES56-PI Data Fax Modem
 125e  Specialvideo Engineering SRL
 125f  Concurrent Technologies, Inc.
 1260  Harris Semiconductor
@@ -3193,7 +3674,9 @@
 		4942 4c4c  Creative Sound Blaster AudioPCI128
 	5880  5880 AudioPCI
 		1274 2000  Creative Sound Blaster AudioPCI128
+		1274 2003  Creative SoundBlaster AudioPCI 128
 		1274 5880  Creative Sound Blaster AudioPCI128
+		1458 a000  5880 AudioPCI On Motherboard 6OXET
 		1462 6880  5880 AudioPCI On Motherboard MS-6188 1.00
 		270f 2001  5880 AudioPCI On Motherboard 6CTR
 		270f 2200  5880 AudioPCI On Motherboard 6WTX
@@ -3202,6 +3685,7 @@
 1276  Switched Network Technologies, Inc.
 1277  Comstream
 1278  Transtech Parallel Systems Ltd.
+	0701  TPE3/TM3 PowerPC Node
 1279  Transmeta Corporation
 	0295  Northbridge
 	0395  LongRun Northbridge
@@ -3209,26 +3693,29 @@
 	0397  BIOS scratchpad
 127a  Rockwell International
 	1002  HCF 56k Data/Fax Modem
+		1092 094c  SupraExpress 56i PRO [Diamond SUP2380]
 		122d 4002  HPG / MDP3858-U # Aztech
 		122d 4005  MDP3858-E # Aztech
 		122d 4007  MDP3858-A/-NZ # Aztech
 		122d 4012  MDP3858-SA # Aztech
 		122d 4017  MDP3858-W # Aztech
 		122d 4018  MDP3858-W # Aztech
+		127a 1002  Rockwell 56K D/F HCF Modem
 	1003  HCF 56k Data/Fax Modem
 		0e11 b0bc  229-DF Zephyr # Compaq
 		0e11 b114  229-DF Cheetah # Compaq
 		1033 802b  229-DF # NEC
 		13df 1003  PCI56RX Modem # E-Tech Inc
 		13e0 0117  IBM # GVC
-		13e0 0147  IBM # GVC
+		13e0 0147  IBM # GVC F-1156IV /R3 Spain V.90 Modem
 		13e0 0197  IBM # GVC
-		13e0 01c7  IBM # GVC
+		13e0 01c7  IBM # GVC F-1156IV /R3 WW V.90 Modem
 		13e0 01f7  IBM # GVC
 		1436 1003  IBM # CIS
-		1436 1103  IBM # CIS
+		1436 1103  IBM # CIS 5614PM3G V.90 Modem
 		1436 1602  Compaq 229-DF Ducati
 	1004  HCF 56k Data/Fax/Voice Modem
+		1048 1500  MicroLink 56k Modem
 		10cf 1059  Fujitsu 229-DFRT
 	1005  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
 		1033 8029  229-DFSV # NEC
@@ -3249,16 +3736,19 @@
 		13df 1005  PCI56RVP Modem  # E-Tech Inc
 		13e0 0187  IBM # GVC
 		13e0 01a7  IBM # GVC
-		13e0 01b7  IBM # GVC
-		13e0 01d7  IBM # GVC
+		13e0 01b7  IBM # GVC DF-1156IV /R3 Spain V.90 Modem
+		13e0 01d7  IBM # GVC DF-1156IV /R3 WW V.90 Modem
 		1436 1005  IBM # CIS
 		1436 1105  IBM # CIS
+		1437 1105  IBM # CIS 5614PS3G V.90 Modem
+	1022  HCF 56k Modem
+		1436 1303  M3-5614PM3G V.90 Modem
 	1023  HCF 56k Data/Fax Modem
 		122d 4020  Packard Bell MDP3858-WE # Aztech
 		122d 4023  MDP3858-UE # Aztech
-		13e0 0247  IBM # GVC
+		13e0 0247  IBM # GVC F-1156IV /R6 Spain V.90 Modem
 		13e0 0297  IBM # GVC
-		13e0 02c7  IBM # GVC
+		13e0 02c7  IBM # GVC F-1156IV /R6 WW V.90 Modem
 		1436 1203  IBM # CIS
 		1436 1303  IBM # CIS
 	1024  HCF 56k Data/Fax/Voice Modem
@@ -3269,7 +3759,11 @@
 		122d 4024  MDP3858V-UE # Aztech
 		122d 4025  MDP3858SP-UE # Aztech
 	1026  HCF 56k PCI Speakerphone Modem
+	1032  HCF 56k Modem
+	1033  HCF 56k Modem
+	1034  HCF 56k Modem
 	1035  HCF 56k PCI Speakerphone Modem
+	1036  HCF 56k Modem
 	1085  HCF 56k Volcano PCI Modem
 	2005  HCF 56k Data/Fax Modem
 		104d 8044  229-DFSV # Sony
@@ -3309,6 +3803,7 @@
 	4322  Riptide PCI Game Controller
 		1235 4322  Riptide PCI Game Controller
 	8234  RapidFire 616X ATM155 Adapter
+		108d 0022  RapidFire 616X ATM155 Adapter
 		108d 0027  RapidFire 616X ATM155 Adapter
 127b  Pixera Corporation
 127c  Crosspoint Solutions, Inc.
@@ -3360,6 +3855,7 @@
 1298  Spellcaster Telecommunications Inc.
 1299  Knowledge Technology Lab.
 129a  VMetro, inc.
+	0615  PBT-615 PCI-X Bus Analyzer
 129b  Image Access
 129c  Jaycor
 129d  Compcore Multimedia, Inc.
@@ -3382,8 +3878,10 @@
 12ad  Multidata GmbH
 12ae  Alteon Networks Inc.
 	0001  AceNIC Gigabit Ethernet (Fibre)
-		1410 0104  Gigabit Ethernet-SX PCI Adapter (14100401)
+		12ae 0001  Gigabit Ethernet-SX (Universal)
+		1410 0104  Gigabit Ethernet-SX PCI Adapter
 	0002  AceNIC Gigabit Ethernet (Copper)
+		12ae 0002  Gigabit Ethernet-T (3C986-T)
 12af  TDK USA Corp
 12b0  Jorge Scientific Corp
 12b1  GammaLink
@@ -3449,19 +3947,24 @@
 	0008  NV1
 	0009  DAC64
 	0018  Riva128
+		1048 0c10  VICTORY Erazor
 		107b 8030  STB Velocity 128
 		1092 0350  Viper V330
 		1092 1092  Viper V330
 		10b4 1b1b  STB Velocity 128
-		10b4 1b20  STB Velocity 128
+		10b4 1b1d  STB Velocity 128
+		10b4 1b1e  STB Velocity 128, PAL TV-Out
+		10b4 1b20  STB Velocity 128 Sapphire
 		10b4 1b21  STB Velocity 128
 		10b4 1b22  STB Velocity 128 AGP, NTSC TV-Out
 		10b4 1b23  STB Velocity 128 AGP, PAL TV-Out
 		10b4 1b27  STB Velocity 128 DVD
+		10b4 1b88  MVP Pro 128
 		10b4 222a  STB Velocity 128 AGP
 		10b4 2230  STB Velocity 128
+		10b4 2232  STB Velocity 128
 		10b4 2235  STB Velocity 128 AGP
-		2a15 54a3  3DVision-SAGP
+		2a15 54a3  3DVision-SAGP / 3DexPlorer 3000
 	0019  Riva128ZX
 	0020  TNT
 	0028  TNT2
@@ -3469,7 +3972,7 @@
 	002c  VTNT2
 	00a0  ITNT2
 12d3  Vingmed Sound A/S
-12d4  DGM&S
+12d4  Ulticom (Formerly DGM&S)
 12d5  Equator Technologies
 12d6  Analogic Corp
 12d7  Biotronic SRL
@@ -3768,6 +4271,7 @@
 1383  Controlnet Inc
 1384  Reality Simulation Systems Inc
 1385  Netgear
+	4100  802.11b Wireless Adapter (MA301)
 	620a  GA620
 	622a  GA622
 	630a  GA630
@@ -3793,6 +4297,7 @@
 	2180  Intellio C218 Turbo PCI
 	3200  Intellio C320 Turbo PCI
 1394  Level One Communications
+	0001  LXT1001 Gigabit Ethernet
 1395  Ambicom Inc
 1396  Cipher Systems Inc
 1397  Cologne Chip Designs GmbH
@@ -3810,12 +4315,17 @@
 13a0  Crystal Group Inc
 13a1  Kawasaki Heavy Industries Ltd
 13a2  Ositech Communications Inc
-13a3  Hi-Fn
+13a3  Hifn Inc.
+	0005  7751 Security Processor
+	0006  6500 Public Key Processor
+	0007  7811 Security Processor
+	0012  7951 Security Processor
 13a4  Rascom Inc
 13a5  Audio Digital Imaging Inc
 13a6  Videonics Inc
 13a7  Teles AG
 13a8  Exar Corp.
+	0158  XR17C158 Octal UART
 13a9  Siemens Medical Systems, Ultrasound Group
 13aa  Broadband Networks Inc
 13ab  Arcom Control Systems Ltd
@@ -3860,6 +4370,7 @@
 13cf  Studio Audio & Video Ltd
 13d0  Techsan Electronics Co Ltd
 13d1  Abocom Systems Inc
+	ab06  RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter
 13d2  Shark Multimedia Inc
 13d3  IMC Networks
 13d4  Graphics Microsystems Inc
@@ -3897,7 +4408,8 @@
 13f1  Oce' - Technologies B.V.
 13f2  Ford Microelectronics Inc
 13f3  Mcdata Corporation
-13f4  Troika Design Inc
+13f4  Troika Networks, Inc.
+	1401  Zentai Fibre Channel Adapter
 13f5  Kansai Electric Co. Ltd
 13f6  C-Media Electronics Inc
 	0100  CM8338A
@@ -3905,6 +4417,7 @@
 	0101  CM8338B
 		13f6 0101  CMI8338-031 PCI Audio Device
 	0111  CM8738
+		1043 8077  CMI8738 6-channel audio controller
 		13f6 0111  CMI8738/C3DX PCI Audio Device
 	0211  CM8738
 13f7  Wildfire Communications
@@ -3939,6 +4452,7 @@
 	8800  BOCA Research IOPPAR
 1408  Aloka Co. Ltd
 1409  Timedia Technology Co Ltd
+	7168  PCI2S550 (Dual 16550 UART)
 140a  DSP Research Inc
 140b  Ramix Inc
 140c  Elmic Systems Inc
@@ -3952,6 +4466,14 @@
 1413  Addonics
 1414  Microsoft Corporation
 1415  Oxford Semiconductor Ltd
+	8403  VScom 011H-EP1 1 port parallel adaptor
+	9501  Quad 16950 UART
+		15ed 2000  MCCR Serial p0-3 of 8
+		15ed 2001  MCCR Serial p0-3 of 16
+	9511  OX16PCI954 (Quad 16950 UART) function 1
+		15ed 2000  MCCR Serial p4-7 of 8
+		15ed 2001  MCCR Serial p4-15 of 16
+	9521  OX16PCI952 (Dual 16950 UART)
 1416  Multiwave Innovation pte Ltd
 1417  Convergenet Technologies Inc
 1418  Kyushu electronics systems Inc
@@ -4128,6 +4650,10 @@
 14b8  Techsoft Technology Co Ltd
 14b9  AIRONET Wireless Communications
 	0001  PC4800
+	0340  PC4800
+	0350  PC4800
+	4500  PC4500
+	4800  PC4800
 14ba  INTERNIX Inc.
 14bb  SEMTECH Corporation
 14bc  Globespan Semiconductor Inc.
@@ -4153,6 +4679,22 @@
 14d0  Ericsson Axe R & D
 14d1  Computer Hi-Tech Co Ltd
 14d2  Titan Electronics Inc
+	8001  VScom 010L 1 port parallel adaptor
+	8002  VScom 020L 2 port parallel adaptor
+	8010  VScom 100L 1 port serial adaptor
+	8011  VScom 110L 1 port serial and 1 port parallel adaptor
+	8020  VScom 200L 1 port serial adaptor
+	8021  VScom 210L 2 port serial and 1 port parallel adaptor
+	8040  VScom 400L 4 port serial adaptor
+	8080  VScom 800L 8 port serial adaptor
+	a000  VScom 010H 1 port parallel adaptor
+	a001  VScom 100H 1 port serial adaptor
+	a003  VScom 400H 4 port serial adaptor
+	a004  VScom 400HF1 4 port serial adaptor
+	a005  VScom 200H 2 port serial adaptor
+	e001  VScom 010HV2 1 port parallel adaptor
+	e010  VScom 100HV2 1 port serial adaptor
+	e020  VScom 200HV2 2 port serial adaptor
 14d3  CIRTECH (UK) Ltd
 14d4  Panacom Technology Corp
 14d5  Nitsuko Corporation
@@ -4182,20 +4724,29 @@
 14e3  AMTELCO
 14e4  BROADCOM Corporation
 	1644  NetXtreme BCM5700 Gigabit Ethernet
+		1014 0277  Vigil B5700 1000BaseTX
+		1028 00d1  NetXtreme 1000BaseTX
+		1028 0106  NetXtreme 1000BaseTX
+		1028 0109  NetXtreme 1000BaseTX
 		10b7 1000  3C996-T 1000BaseTX
 		10b7 1001  3C996B-T 1000BaseTX
 		10b7 1002  3C996C-T 1000BaseTX
-		10b7 1003  3C997-T 1000BaseTX
+		10b7 1003  3C997-T 1000BaseTX Dual Port
 		10b7 1004  3C996-SX 1000BaseSX
-		10b7 1005  3C997-SX 1000BaseSX
+		10b7 1005  3C997-SX 1000BaseSX Dual Port
+		10b7 1008  3C942 Gigabit LOM (31X31)
 		14e4 0002  NetXtreme 1000BaseSX
 		14e4 0003  NetXtreme 1000BaseSX
 		14e4 0004  NetXtreme 1000BaseTX
+		14e4 1028  NetXtreme 1000BaseTX
 		14e4 1644  NetXtreme BCM5700 1000BaseTX
 	1645  NetXtreme BCM5701 Gigabit Ethernet
-		0e11 007c  NC7770 1000BaseTX
-		0e11 007d  NC6770 1000BaseSX
-		0e11 0085  NC7780 1000BaseTX
+		0e11 007c  NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+		0e11 007d  NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
+		0e11 0085  NC7780 Gigabit Server Adapter (embedded, WOL)
+		0e11 0099  NC7780 Gigabit Server Adapter (embedded, WOL)
+		0e11 009a  NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+		1028 0121  NetXtreme BCM5701 1000BaseTX
 		10b7 1004  3C996-SX 1000BaseSX
 		10b7 1006  3C996B-T 1000BaseTX
 		10b7 1007  3C1000-T 1000BaseTX
@@ -4206,7 +4757,22 @@
 		14e4 0007  NetXtreme BCM5701 1000BaseSX
 		14e4 0008  NetXtreme BCM5701 1000BaseTX
 		14e4 8008  NetXtreme BCM5701 1000BaseTX
+	1646  NetXtreme BCM5702 Gigabit Ethernet
+		0e11 00bb  NC7760 1000BaseTX
+		1028 0126  NetXtreme BCM5702 1000BaseTX
+		14e4 8009  NetXtreme BCM5702 1000BaseTX
 	1647  NetXtreme BCM5703 Gigabit Ethernet
+		0e11 0099  NC7780 1000BaseTX
+		0e11 009a  NC7770 1000BaseTX
+		14e4 0009  NetXtreme BCM5703 1000BaseTX
+		14e4 000a  NetXtreme BCM5703 1000BaseSX
+		14e4 000b  NetXtreme BCM5703 1000BaseTX
+		14e4 8009  NetXtreme BCM5703 1000BaseTX
+		14e4 800a  NetXtreme BCM5703 1000BaseTX
+	164d  NetXtreme BCM5702FE Gigabit Ethernet
+	16a6  NetXtreme BCM5702X Gigabit Ethernet
+	16a7  NetXtreme BCM5703X Gigabit Ethernet
+	4212  BCM v.90 56k modem
 	5820  BCM5820 Crypto Accelerator
 14e5  Pixelfusion Ltd
 14e6  SHINING Technology Inc
@@ -4221,14 +4787,30 @@
 14ef  CARRY Computer ENG. CO Ltd
 14f0  CANON RESEACH CENTRE FRANCE
 14f1  Conexant
+	1002  HCF 56k Modem
+	1003  HCF 56k Modem
+	1004  HCF 56k Modem
+	1005  HCF 56k Modem
+	1006  HCF 56k Modem
+	1022  HCF 56k Modem
+	1023  HCF 56k Modem
+	1024  HCF 56k Modem
+	1025  HCF 56k Modem
+	1026  HCF 56k Modem
+	1032  HCF 56k Modem
 	1033  HCF 56k Data/Fax Modem
+		1033 8077  NEC
 		122d 4027  Dell Zeus - MDP3880-W(B) Data Fax Modem
 		122d 4030  Dell Mercury - MDP3880-U(B) Data Fax Modem
 		122d 4034  Dell Thor - MDP3880-W(U) Data Fax Modem
 		13e0 020d  Dell Copper
 		13e0 020e  Dell Silver
+		13e0 0261  IBM # GVC
 		13e0 0290  Compaq Goldwing
+		13e0 02a0  IBM # GVC
+		13e0 02b0  IBM # GVC
 		13e0 02c0  Compaq Scooter
+		13e0 02d0  IBM # GVC
 		144f 1500  IBM P85-DF (1)
 		144f 1501  IBM P85-DF (2)
 		144f 150a  IBM P85-DF (3)
@@ -4238,6 +4820,7 @@
 	1035  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
 		10cf 1098  Fujitsu P85-DFSV
 	1036  HCF 56k Data/Fax/Voice/Spkp Modem
+		104d 8067  HCF 56k Modem
 		122d 4029  MDP3880SP-W
 		122d 4031  MDP3880SP-U
 		13e0 0209  Dell Titanium
@@ -4261,6 +4844,8 @@
 	1435  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
 	1436  HCF 56k Data/Fax Modem
 	1453  HCF 56k Data/Fax Modem
+		13e0 0240  IBM # GVC
+		13e0 0250  IBM # GVC
 		144f 1502  IBM P95-DF (1)
 		144f 1503  IBM P95-DF (2)
 	1454  HCF 56k Data/Fax/Voice Modem
@@ -4282,6 +4867,9 @@
 		0e11 b195  Bear
 		0e11 b196  Seminole 1
 		0e11 b1be  Seminole 2
+		1025 8013  Acer
+		1033 809d  NEC
+		1033 80bc  NEC
 		155d 6793  HP
 		155d 8850  E Machines
 	2014  HSF 56k Data/Fax/Voice Modem
@@ -4314,6 +4902,9 @@
 	2365  HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
 	2366  HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA)
 	2443  HSF 56k Data/Fax Modem (Mob WorldW SmartDAA)
+		104d 8075  Modem # Sony
+		104d 8083  Modem # Sony
+		104d 8097  Modem # Sony
 	2444  HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA)
 	2445  HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA)
 	2446  HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA)
@@ -4383,9 +4974,16 @@
 151d  Fujitsu Computer Products Of America
 151e  MATRIX Corp
 151f  TOPIC SEMICONDUCTOR Corp
+	0000  TP560 Data/Fax/Voice 56k modem
 1520  CHAPLET System Inc
 1521  BELL Corp
 1522  MainPine Ltd
+	0100  PCI <-> IOBus Bridge
+		1522 0200  RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem
+		1522 0300  RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
+		1522 0400  RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
+		1522 0500  RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
+		1522 0600  RockForce+ 2 Port V.90 Data/Fax/Voice Modem
 1523  MUSIC Semiconductors
 1524  ENE Technology Inc
 1525  IMPACT Technologies
@@ -4540,6 +5138,7 @@
 15a0  Compumaster SRL
 15a1  Geocast Network Systems
 15a2  Catalyst Enterprises Inc
+	0001  TA700 PCI Bus Analyzer/Exerciser
 15a3  Italtel
 15a4  X-Net OY
 15a5  Toyota Macs Inc
@@ -4556,6 +5155,7 @@
 15b1  Source Technology Inc
 15b2  Mosaid Technologies Inc
 15b3  Mellanox Technology
+	5274  MT21108 InfiniBridge
 15b4  CCI/TRIAD
 15b5  Cimetrics Inc
 15b6  Texas Memory Systems Inc
@@ -4565,6 +5165,7 @@
 15ba  Impacct Technology Corp
 15bb  Portwell Inc
 15bc  Agilent Technologies
+	2929  E2929A PCI/PCI-X Bus Analyzer
 15bd  DFI Inc
 15be  Sola Electronics
 15bf  High Tech Computer Corp (HTC)
@@ -4645,7 +5246,19 @@
 1619  FarSite Communications Ltd
 	0400  FarSync T2P (2 port X.21/V.35/V.24)
 	0440  FarSync T4P (4 port X.21/V.35/V.24)
+1629  Kongsberg Spacetec AS
+	1003  Format synchronizer v3.0
+	2002  Fast Universal Data Output
+1657  Brocade Communications Systems, Inc.
 1668  Action Tec Electronics Inc
+16f6  VideoTele.com, Inc.
+170b  NetOctave Inc
+170c  YottaYotta Inc.
+173b  Altima (nee BroadCom)
+	03e8  AC1000 Gigabit Ethernet
+	03ea  AC9100 Gigabit Ethernet
+1743  Peppercon AG
+	8139  ROL/F-100 Fast Ethernet Adapter with ROL
 1813  Ambient Technologies Inc
 1a08  Sierra semiconductor
 	0000  SC15064
@@ -4671,6 +5284,7 @@
 3000  Hansol Electronics Inc.
 3142  Post Impression Systems.
 3388  Hint Corp
+	0021  HB1-SE33 PCI-PCI Bridge
 	8011  VXPro II Chipset
 		3388 8011  VXPro II Chipset CPU to PCI Bridge
 	8012  VXPro II Chipset
@@ -4690,6 +5304,7 @@
 	0007  3D Extreme
 	0008  GLINT Gamma G1
 	0009  Permedia II 2D+3D
+		1040 0011  AccelStar II
 		3d3d 0100  AccelStar II 3D Accelerator
 		3d3d 0111  Permedia 3:16
 		3d3d 0114  Santa Ana
@@ -4719,6 +5334,7 @@
 	2501  ALG-2564A/25128A
 	4000  ALS4000 Audio Chipset
 		4005 4000  ALS4000 Audio Chipset
+	4710  ALC200/200P
 4033  Addtron Technology Co, Inc.
 	1360  RTL8139 Ethernet
 4143  Digital Equipment Corp
@@ -4745,6 +5361,8 @@
 	0200  MQ-200
 4d54  Microtechnica Co Ltd
 4ddc  ILC Data Device Corp
+5046  GemTek Technology Corporation
+	1001  PCI Radio
 5053  Voyetra Technologies
 	2010  Daytona Audio Adapter
 5136  S S Technologies
@@ -4788,7 +5406,7 @@
 	88f3  86c968 [Vision 968 VRAM] rev 3
 	8900  86c755 [Trio 64V2/DX]
 		5333 8900  86C775 Trio64V2/DX
-	8901  Trio 64V2/DX or /GX
+	8901  86c775/86c785 [Trio 64V2/DX or /GX]
 		5333 8901  86C775 Trio64V2/DX, 86C785 Trio64V2/GX
 	8902  Plato/PX
 	8903  Trio 3D business multimedia
@@ -4817,9 +5435,11 @@
 		5333 8a13  Trio3D/2X
 	8a20  86c794 [Savage 3D]
 		5333 8a20  86C391 Savage3D
-	8a21  86c795 [Savage 3D/MV]
+	8a21  86c390 [Savage 3D/MV]
 		5333 8a21  86C390 Savage3D/MV
 	8a22  Savage 4
+		1033 8068  Savage 4
+		1033 8069  Savage 4
 		105d 0018  SR9 8Mb SDRAM
 		105d 002a  SR9 Pro 16Mb SDRAM
 		105d 003a  SR9 Pro 32Mb SDRAM
@@ -4901,21 +5521,51 @@
 	04d0  82437FX [Triton FX]
 	0600  RAID Controller
 	0960  80960RP [i960 RP Microprocessor/Bridge]
+	0962  80960RM [i960RM Bridge]
 	0964  80960RP [i960 RP Microprocessor/Bridge]
 	1000  82542 Gigabit Ethernet Controller
-		0e11 b0df  NC1632 Gigabit Ethernet Adapter
-		0e11 b0e0  NC1633 Gigabit Ethernet Adapter
-		0e11 b123  NC1634 Gigabit Ethernet Adapter
+		0e11 b0df  NC1632 Gigabit Ethernet Adapter (1000-SX)
+		0e11 b0e0  NC1633 Gigabit Ethernet Adapter (1000-LX)
+		0e11 b123  NC1634 Gigabit Ethernet Adapter (1000-SX)
 		1014 0119  Netfinity Gigabit Ethernet SX Adapter
+		8086 1000  PRO/1000 Gigabit Server Adapter
 	1001  82543GC Gigabit Ethernet Controller
+		0e11 004a  NC6136 Gigabit Server Adapter
+		1014 01ea  Netfinity Gigabit Ethernet SX Adapter
+		8086 1003  PRO/1000 F Server Adapter
+	1002  Pro 100 LAN Modem 56 Cardbus II
+		8086 200e  Pro 100 LAN Modem 56 Cardbus II
+		8086 2013  Pro 100 SR Mobile Combo Adapter
+		8086 2017  Pro 100 S Combo Mobile Adapter
 	1004  82543GC Gigabit Ethernet Controller
+		0e11 0049  NC7132 Gigabit Upgrade Module
+		0e11 b1a4  NC7131 Gigabit Server Adapter
+		1014 10f2  Gigabit Ethernet Server Adapter
+		8086 1004  PRO/1000 T Server Adapter
+		8086 2004  PRO/1000 T Server Adapter
 	1008  82544EI Gigabit Ethernet Controller
+		8086 1107  PRO/1000 XT Server Adapter
+		8086 2107  PRO/1000 XT Server Adapter
+		8086 2110  PRO/1000 XT Server Adapter
 	1009  82544EI Gigabit Ethernet Controller
+		8086 1109  PRO/1000 XF Server Adapter
+		8086 2109  PRO/1000 XF Server Adapter
 	100c  82544GC Gigabit Ethernet Controller
+		8086 1109  PRO/1000 T Desktop Adapter
+		8086 1112  PRO/1000 T Desktop Adapter
+		8086 2109  PRO/1000 T Desktop Adapter
+		8086 2112  PRO/1000 T Desktop Adapter
 	100d  82544GC Gigabit Ethernet Controller
 	1029  82559 Ethernet Controller
 	1030  82559 InBusiness 10/100
 	1031  82801CAM (ICH3) Chipset Ethernet Controller
+		1014 0209  EtherExpress PRO/100 VE
+		104d 80e7  Vaio PCG Series
+		107b 5350  EtherExpress PRO/100 VE
+		1179 0001  EtherExpress PRO/100 VE
+		144d c000  EtherExpress PRO/100 VE
+		144d c001  EtherExpress PRO/100 VE
+		144d c003  EtherExpress PRO/100 VE
 	1032  82801CAM (ICH3) Chipset Ethernet Controller
 	1033  82801CAM (ICH3) Chipset Ethernet Controller
 	1034  82801CAM (ICH3) Chipset Ethernet Controller
@@ -4924,8 +5574,12 @@
 	1037  82801CAM (ICH3) Chipset Ethernet Controller
 	1038  82801CAM (ICH3) Chipset Ethernet Controller
 	1130  82815 815 Chipset Host Bridge and Memory Controller Hub
+	1131  82815 815 Chipset AGP Bridge
 	1132  82815 CGC [Chipset Graphics Controller]
 	1161  82806AA PCI64 Hub Advanced Programmable Interrupt Controller
+		8086 1161  82806AA PCI64 Hub APIC
+	1200  Unknown device
+		172a 0000  AEP SSL Accelerator
 	1209  82559ER
 	1221  82092AA_0
 	1222  82092AA_1
@@ -4934,31 +5588,61 @@
 	1226  82596 PRO/10 PCI
 	1227  82865 EtherExpress PRO/100A
 	1228  82556 EtherExpress PRO/100 Smart
-	1229  82557 [Ethernet Pro 100]
-		0e11 b01e  NC3120
-		0e11 b01f  NC3122
-		0e11 b02f  NC1120
+# the revision field differentiates between them (1-3 is 82557, 4-5 is 82558, 6-8 is 82559, 9 is 82559ER)
+	1229  82557/8/9 [Ethernet Pro 100]
+		0e11 3001  82559 Fast Ethernet LOM with Alert on LAN*
+		0e11 3002  82559 Fast Ethernet LOM with Alert on LAN*
+		0e11 3003  82559 Fast Ethernet LOM with Alert on LAN*
+		0e11 3004  82559 Fast Ethernet LOM with Alert on LAN*
+		0e11 3005  82559 Fast Ethernet LOM with Alert on LAN*
+		0e11 3006  82559 Fast Ethernet LOM with Alert on LAN*
+		0e11 3007  82559 Fast Ethernet LOM with Alert on LAN*
+		0e11 b01e  NC3120 Fast Ethernet NIC
+		0e11 b01f  NC3122 Fast Ethernet NIC (dual port)
+		0e11 b02f  NC1120 Ethernet NIC
 		0e11 b04a  Netelligent 10/100TX NIC with Wake on LAN
-		0e11 b0c6  Embedded NC3120 with Wake on LAN
-		0e11 b0c7  Embedded NC3121
-		0e11 b0d7  NC3121 with Wake on LAN
-		0e11 b0dd  NC3131 (82558B)
-		0e11 b0de  NC3132
-		0e11 b0e1  NC3133
-		0e11 b144  NC3123 (82559)
+		0e11 b0c6  NC3161 Fast Ethernet NIC (embedded, WOL)
+		0e11 b0c7  NC3160 Fast Ethernet NIC (embedded)
+		0e11 b0d7  NC3121 Fast Ethernet NIC (WOL)
+		0e11 b0dd  NC3131 Fast Ethernet NIC (dual port)
+		0e11 b0de  NC3132 Fast Ethernet Module (dual port)
+		0e11 b0e1  NC3133 Fast Ethernet Module (100-FX)
+		0e11 b134  NC3163 Fast Ethernet NIC (embedded, WOL)
+		0e11 b13c  NC3162 Fast Ethernet NIC (embedded)
+		0e11 b144  NC3123 Fast Ethernet NIC (WOL)
+		0e11 b163  NC3134 Fast Ethernet NIC (dual port)
+		0e11 b164  NC3135 Fast Ethernet Upgrade Module (dual port)
+		0e11 b1a4  NC7131 Gigabit Server Adapter
 		1014 005c  82558B Ethernet Pro 10/100
+		1014 01f1  10/100 Ethernet Server Adapter
+		1014 01f2  10/100 Ethernet Server Adapter
+		1014 0207  Ethernet Pro/100 S
+		1014 0232  10/100 Dual Port Server Adapter
 		1014 105c  Netfinity 10/100
+		1014 305c  10/100 EtherJet Management Adapter
+		1014 405c  10/100 EtherJet Adapter with Alert on LAN
+		1014 505c  10/100 EtherJet Secure Management Adapter
+		1014 605c  10/100 EtherJet Secure Management Adapter
+		1014 705c  10/100 Netfinity 10/100 Ethernet Security Adapter
+		1014 805c  10/100 Netfinity 10/100 Ethernet Security Adapter
 		1033 8000  PC-9821X-B06
 		1033 8016  PK-UG-X006
 		1033 801f  PK-UG-X006
-		103c 10c0  Ethernet Pro 10/100TX
-		103c 10c3  Ethernet Pro 10/100TX
-		103c 1200  Ethernet Pro 10/100TX
+		103c 10c0  NetServer 10/100TX
+		103c 10c3  NetServer 10/100TX
+		103c 10ca  NetServer 10/100TX
+		103c 10cb  NetServer 10/100TX
+		103c 10e3  NetServer 10/100TX
+		103c 10e4  NetServer 10/100TX
+		103c 1200  NetServer 10/100TX
 		10c3 1100  SmartEther100 SC1100
 		1179 0002  PCI FastEther LAN on Docker
 		1259 2560  AT-2560 100
 		1259 2561  AT-2560 100 FX Ethernet Adapter
 		1266 0001  NE10/100 Adapter
+		144d 2501  SEM-2000 MiniPCI LAN Adapter
+		144d 2502  SEM-2100IL MiniPCI LAN Adapter
+		1668 1100  EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem)
 		8086 0001  EtherExpress PRO/100B (TX)
 		8086 0002  EtherExpress PRO/100B (T4)
 		8086 0003  EtherExpress PRO/10+
@@ -4973,14 +5657,76 @@
 		8086 000c  EtherExpress PRO/100+ Management Adapter
 		8086 000d  EtherExpress PRO/100+ Alert On LAN II* Adapter
 		8086 000e  EtherExpress PRO/100+ Management Adapter with Alert On LAN*
+		8086 000f  EtherExpress PRO/100 Desktop Adapter
+		8086 0010  EtherExpress PRO/100 S Management Adapter
+		8086 0011  EtherExpress PRO/100 S Management Adapter
+		8086 0012  EtherExpress PRO/100 S Advanced Management Adapter (D)
+		8086 0013  EtherExpress PRO/100 S Advanced Management Adapter (E)
+		8086 0030  EtherExpress PRO/100  Management Adapter with Alert On LAN* GC
+		8086 0031  EtherExpress PRO/100 Desktop Adapter
+		8086 0040  EtherExpress PRO/100 S Desktop Adapter
+		8086 0041  EtherExpress PRO/100 S Desktop Adapter
+		8086 0042  EtherExpress PRO/100 Desktop Adapter
+		8086 0050  EtherExpress PRO/100 S Desktop Adapter
 		8086 1009  EtherExpress PRO/100+ Server Adapter
 		8086 100c  EtherExpress PRO/100+ Server Adapter (PILA8470B)
+		8086 1012  EtherExpress PRO/100 S Server Adapter (D)
+		8086 1013  EtherExpress PRO/100 S Server Adapter (E)
+		8086 1015  EtherExpress PRO/100 S Dual Port Server Adapter
+		8086 1017  EtherExpress PRO/100+ Dual Port Server Adapter
+		8086 1030  EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server
+		8086 1040  EtherExpress PRO/100 S Server Adapter
+		8086 1041  EtherExpress PRO/100 S Server Adapter
+		8086 1042  EtherExpress PRO/100 Server Adapter
+		8086 1050  EtherExpress PRO/100 S Server Adapter
+		8086 1051  EtherExpress PRO/100 Server Adapter
+		8086 1052  EtherExpress PRO/100 Server Adapter
 		8086 10f0  EtherExpress PRO/100+ Dual Port Adapter
+		8086 2009  EtherExpress PRO/100 S Mobile Adapter
 		8086 200d  EtherExpress PRO/100 Cardbus
 		8086 200e  EtherExpress PRO/100 LAN+V90 Cardbus Modem
+		8086 200f  EtherExpress PRO/100 SR Mobile Adapter
+		8086 2010  EtherExpress PRO/100 S Mobile Combo Adapter
+		8086 2013  EtherExpress PRO/100 SR Mobile Combo Adapter
+		8086 2016  EtherExpress PRO/100 S Mobile Adapter
+		8086 2017  EtherExpress PRO/100 S Combo Mobile Adapter
+		8086 2018  EtherExpress PRO/100 SR Mobile Adapter
+		8086 2019  EtherExpress PRO/100 SR Combo Mobile Adapter
+		8086 2101  EtherExpress PRO/100 P Mobile Adapter
+		8086 2102  EtherExpress PRO/100 SP Mobile Adapter
+		8086 2103  EtherExpress PRO/100 SP Mobile Adapter
+		8086 2104  EtherExpress PRO/100 SP Mobile Adapter
+		8086 2105  EtherExpress PRO/100 SP Mobile Adapter
+		8086 2106  EtherExpress PRO/100 P Mobile Adapter
+		8086 2107  EtherExpress PRO/100 Network Connection
+		8086 2108  EtherExpress PRO/100 Network Connection
+		8086 2200  EtherExpress PRO/100 P Mobile Combo Adapter
+		8086 2201  EtherExpress PRO/100 P Mobile Combo Adapter
+		8086 2202  EtherExpress PRO/100 SP Mobile Combo Adapter
+		8086 2203  EtherExpress PRO/100+ MiniPCI
+		8086 2204  EtherExpress PRO/100+ MiniPCI
+		8086 2205  EtherExpress PRO/100 SP Mobile Combo Adapter
+		8086 2206  EtherExpress PRO/100 SP Mobile Combo Adapter
+		8086 2207  EtherExpress PRO/100 SP Mobile Combo Adapter
+		8086 2208  EtherExpress PRO/100 P Mobile Combo Adapter
+		8086 2402  EtherExpress PRO/100+ MiniPCI
+		8086 2407  EtherExpress PRO/100+ MiniPCI
+		8086 2408  EtherExpress PRO/100+ MiniPCI
+		8086 2409  EtherExpress PRO/100+ MiniPCI
+		8086 240f  EtherExpress PRO/100+ MiniPCI
+		8086 2410  EtherExpress PRO/100+ MiniPCI
+		8086 2411  EtherExpress PRO/100+ MiniPCI
+		8086 2412  EtherExpress PRO/100+ MiniPCI
+		8086 2413  EtherExpress PRO/100+ MiniPCI
 		8086 3000  82559 Fast Ethernet LAN on Motherboard
 		8086 3001  82559 Fast Ethernet LOM with Basic Alert on LAN*
 		8086 3002  82559 Fast Ethernet LOM with Alert on LAN II*
+		8086 3006  EtherExpress PRO/100 S Network Connection
+		8086 3007  EtherExpress PRO/100 S Network Connection
+		8086 3008  EtherExpress PRO/100 Network Connection
+		8086 3010  EtherExpress PRO/100 S Network Connection
+		8086 3011  EtherExpress PRO/100 S Network Connection
+		8086 3012  EtherExpress PRO/100 Network Connection
 	122d  430FX - 82437FX TSC [Triton I]
 	122e  82371FB PIIX ISA [Triton I]
 	1230  82371FB PIIX IDE [Triton I]
@@ -4992,24 +5738,38 @@
 	123b  82380PB
 	123c  82380AB
 	123d  683053 Programmable Interrupt Device
+	123f  82466GX Integrated Hot-Plug Controller (IHPC)
 	1240  752 AGP
 	124b  82380FB
 	1250  430HX - 82439HX TXC [Triton II]
 	1360  82806AA PCI64 Hub PCI Bridge
 	1361  82806AA PCI64 Hub Controller (HRes)
+	1460  82870P2 P64H2 Hub PCI Bridge
+	1461  82870P2 P64H2 I/OxAPIC
+	1462  82870P2 P64H2 Hot Plug Controller
 	1960  80960RP [i960RP Microprocessor]
-		101e 0438  MegaRaid 438
-		101e 0466  MegaRaid 466
-		101e 0467  MegaRaid 467
+		101e 0431  MegaRAID 431 RAID Controller
+		101e 0438  MegaRAID 438 Ultra2 LVD RAID Controller
+		101e 0466  MegaRAID 466 Express Plus RAID Controller
+		101e 0467  MegaRAID 467 Enterprise 1500 RAID Controller
+		101e 0490  MegaRAID 490 Express 300 RAID Controller
+		101e 0762  MegaRAID 762 Express RAID Controller
 		101e 09a0  PowerEdge Expandable RAID Controller 2/SC
 		1028 0467  PowerEdge Expandable RAID Controller 2/DC
 		1028 1111  PowerEdge Expandable RAID Controller 2/SC
-		103c 03a2  MegaRaid
-		103c 10c6  MegaRaid 438
-		103c 10c7  MegaRaid T5
-		103c 10cc  MegaRaid
-		1111 1111  MegaRaid 466
-		113c 03a2  MegaRaid
+		103c 03a2  MegaRAID
+		103c 10c6  MegaRAID 438, HP NetRAID-3Si
+		103c 10c7  MegaRAID T5, Integrated HP NetRAID
+		103c 10cc  MegaRAID, Integrated HP NetRAID
+		103c 10cd  HP NetRAID-1Si
+		105a 0000  SuperTrak
+		105a 2168  SuperTrak Pro
+		105a 5168  SuperTrak66/100
+		1111 1111  MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC
+		1111 1112  PowerEdge Expandable RAID Controller 2/SC
+		113c 03a2  MegaRAID
+	1962  80960RM [i960RM Microprocessor]
+		105a 0000  SuperTrak SX6000 I2O CPU
 	1a21  82840 840 (Carmel) Chipset Host Bridge (Hub A)
 	1a23  82840 840 (Carmel) Chipset AGP Bridge
 	1a24  82840 840 (Carmel) Chipset PCI Bridge (Hub B)
@@ -5034,32 +5794,70 @@
 		11d4 0048  SoundMAX Integrated Digital Audio
 	2426  82801AB AC'97 Modem
 	2428  82801AB PCI Bridge
-	2440  82820 820 (Camino 2) Chipset ISA Bridge (ICH2)
-	2442  82820 820 (Camino 2) Chipset USB (Hub A)
-	2443  82820 820 (Camino 2) Chipset SMBus
-	2444  82820 820 (Camino 2) Chipset USB (Hub B)
-	2445  82820 820 (Camino 2) Chipset AC'97 Audio Controller
-	2446  82820 820 (Camino 2) Chipset AC'97 Modem Controller
-	2448  82820 820 (Camino 2) Chipset PCI (-M)
-	2449  82820 (ICH2) Chipset Ethernet Controller
-	244a  82820 820 (Camino 2) Chipset IDE U100 (-M)
-	244b  82820 820 (Camino 2) Chipset IDE U100
-	244c  82820 820 (Camino 2) Chipset ISA Bridge (ICH2-M)
-	244e  82820 820 (Camino 2) Chipset PCI
-	2485  AC'97 Audio Controller
+	2440  82801BA ISA Bridge (LPC)
+	2442  82801BA/BAM USB (Hub #1)
+	2443  82801BA/BAM SMBus
+	2444  82801BA/BAM USB (Hub #2)
+	2445  82801BA/BAM AC'97 Audio
+	2446  82801BA/BAM AC'97 Modem
+	2448  82801BAM/CAM PCI Bridge
+	2449  82801BA/BAM/CA/CAM Ethernet Controller
+	244a  82801BAM IDE U100
+	244b  82801BA IDE U100
+	244c  82801BAM ISA Bridge (LPC)
+	244e  82801BA/CA/DB PCI Bridge
+	2450  82801E ISA Bridge (LPC)
+	2452  82801E USB
+	2453  82801E SMBus
+	2459  82801E Ethernet Controller 0
+	245b  82801E IDE U100
+	245d  82801E Ethernet Controller 1
+	245e  82801E PCI Bridge
+	2480  82801CA ISA Bridge (LPC)
+	2482  82801CA/CAM USB (Hub #1)
+	2483  82801CA/CAM SMBus
+	2484  82801CA/CAM USB (Hub #2)
+	2485  82801CA/CAM AC'97 Audio
+	2486  82801CA/CAM AC'97 Modem
+	2487  82801CA/CAM USB (Hub #3)
+	248a  82801CAM IDE U100
+	248b  82801CA IDE U100
+	248c  82801CAM ISA Bridge (LPC)
+	24c0  82801DB ISA Bridge (LPC)
+	24c2  82801DB USB (Hub #1)
+	24c3  82801DB SMBus
+	24c4  82801DB USB (Hub #2)
+	24c5  82801DB AC'97 Audio
+	24c6  82801DB AC'97 Modem
+	24c7  82801DB USB (Hub #3)
+	24cb  82801DB IDE U100
+	24cd  82801DB USB EHCI Controller
 	2500  82820 820 (Camino) Chipset Host Bridge (MCH)
 		1043 801c  P3C-2000 system chipset
 	2501  82820 820 (Camino) Chipset Host Bridge (MCH)
 		1043 801c  P3C-2000 system chipset
 	250b  82820 820 (Camino) Chipset Host Bridge
-	250f  82820 820 (Camino) Chipset PCI to AGP Bridge
+	250f  82820 820 (Camino) Chipset AGP Bridge
 	2520  82805AA MTH Memory Translator Hub
 	2521  82804AA MRH-S Memory Repeater Hub for SDRAM
 	2530  82850 850 (Tehama) Chipset Host Bridge (MCH)
 	2531  82850 860 (Wombat) Chipset Host Bridge (MCH)
 	2532  82850 850 (Tehama) Chipset AGP Bridge
 	2533  82860 860 (Wombat) Chipset AGP Bridge
+	2534  82860 860 (Wombat) Chipset PCI Bridge
+	2540  e7500 (Plumas) DRAM Controller
+	2541  e7500 (Plumas) DRAM Controller Error Reporting
+	2543  e7500 (Plumas) HI_B Virtual PCI-to-PCI Bridge (F0)
+	2544  e7500 (Plumas) HI_B Virtual PCI-to-PCI Bridge (F1)
+	2545  e7500 (Plumas) HI_C Virtual PCI-to-PCI Bridge (F0)
+	2546  e7500 (Plumas) HI_C Virtual PCI-to-PCI Bridge (F1)
+	2547  e7500 (Plumas) HI_D Virtual PCI-to-PCI Bridge (F0)
+	2548  e7500 (Plumas) HI_D Virtual PCI-to-PCI Bridge (F1)
 	3092  Integrated RAID
+	3575  82830 830 Chipset Host Bridge
+	3576  82830 830 Chipset AGP Bridge
+	3577  82830 CGC [Chipset Graphics Controller]
+	3578  82830 830 Chipset Host Bridge
 	5200  EtherExpress PRO/100 Intelligent Server
 	5201  EtherExpress PRO/100 Intelligent Server
 		8086 0001  EtherExpress PRO/100 Server Ethernet Adapter
@@ -5069,30 +5867,34 @@
 	7020  82371SB PIIX3 USB [Natoma/Triton II]
 	7030  430VX - 82437VX TVX [Triton VX]
 	7100  430TX - 82439TX MTXC
-	7110  82371AB PIIX4 ISA
-	7111  82371AB PIIX4 IDE
-	7112  82371AB PIIX4 USB
-	7113  82371AB PIIX4 ACPI
+	7110  82371AB/EB/MB PIIX4 ISA
+	7111  82371AB/EB/MB PIIX4 IDE
+	7112  82371AB/EB/MB PIIX4 USB
+	7113  82371AB/EB/MB PIIX4 ACPI
 	7120  82810 GMCH [Graphics Memory Controller Hub]
 	7121  82810 CGC [Chipset Graphics Controller]
-	7122  82810-DC100 GMCH [Graphics Memory Controller Hub]
-	7123  82810-DC100 CGC [Chipset Graphics Controller]
-	7124  82810E GMCH [Graphics Memory Controller Hub]
-	7125  82810E CGC [Chipset Graphics Controller]
-	7126  82810 810 Chipset Host Bridge and Memory Controller Hub
+	7122  82810 DC-100 GMCH [Graphics Memory Controller Hub]
+	7123  82810 DC-100 CGC [Chipset Graphics Controller]
+	7124  82810E DC-133 GMCH [Graphics Memory Controller Hub]
+	7125  82810E DC-133 CGC [Chipset Graphics Controller]
+	7126  82810 DC-133 System and Graphics Controller
+	7128  82810-M DC-100 System and Graphics Controller
+	712a  82810-M DC-133 System and Graphics Controller
 	7180  440LX/EX - 82443LX/EX Host bridge
 	7181  440LX/EX - 82443LX/EX AGP bridge
-	7190  440BX/ZX - 82443BX/ZX Host bridge
+	7190  440BX/ZX/DX - 82443BX/ZX/DX Host bridge
 		0e11 0500  Armada 1750 Laptop System Chipset
-	7191  440BX/ZX - 82443BX/ZX AGP bridge
-	7192  440BX/ZX - 82443BX/ZX Host bridge (AGP disabled)
+		1179 0001  Toshiba Tecra 8100 Laptop System Chipset
+	7191  440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
+	7192  440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
 		0e11 0460  Armada 1700 Laptop System Chipset
-	7194  82440MX I/O Controller
+	7194  82440MX Host Bridge
 	7195  82440MX AC'97 Audio Controller
 		10cf 1099  QSound_SigmaTel Stac97 PCI Audio
 		11d4 0040  SoundMAX Integrated Digital Audio
 		11d4 0048  SoundMAX Integrated Digital Audio
-	7198  82440MX PCI to ISA Bridge
+	7196  82440MX AC'97 Modem Controller
+	7198  82440MX ISA Bridge
 	7199  82440MX EIDE Controller
 	719a  82440MX USB Universal Host Controller
 	719b  82440MX Power Management Controller
@@ -5104,7 +5906,12 @@
 	7602  82372FB [PCI-to-USB UHCI]
 	7603  82372FB System Management Bus Controller
 	7800  i740
+		003d 0008  Starfighter AGP
+		003d 000b  Starfighter AGP
 		1092 0100  Stealth II G460
+		10b4 201a  Lightspeed 740
+		10b4 202f  Lightspeed 740
+		8086 0000  Terminator 2x/i
 		8086 0100  Intel740 Graphics Accelerator
 	84c4  450KX/GX [Orion] - 82454KX/GX PCI bridge
 	84c5  450KX/GX [Orion] - 82453KX/GX Memory controller
@@ -5115,6 +5922,7 @@
 	84e2  460GX - 84460GX AGP Bridge (GXB)
 	84e3  460GX - 84460GX Memory Address Controller (MAC)
 	84e4  460GX - 84460GX Memory Data Controller (MDC)
+	84e6  460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB)
 	9621  Integrated RAID
 	9622  Integrated RAID
 	9641  Integrated RAID
@@ -5142,12 +5950,12 @@
 	5278  AIC-7852
 	5375  AIC-755x
 	5378  AIC-7850
-	5475  AIC-2930
+	5475  AIC-755x
 	5478  AIC-7850
 	5575  AVA-2930
 	5578  AIC-7855
 	5675  AIC-755x
-	5678  AIC-7850
+	5678  AIC-7856
 	5775  AIC-755x
 	5778  AIC-7850
 	5800  AIC-5800
@@ -5155,37 +5963,38 @@
 	5905  ANA-5910A/5930A/5940A ATM Adapter
 	6038  AIC-3860
 	6075  AIC-1480 / APA-1480
+		9004 7560  AIC-1480 / APA-1480 Cardbus
 	6078  AIC-7860
 	6178  AIC-7861
 		9004 7861  AHA-2940AU Single
 	6278  AIC-7860
 	6378  AIC-7860
-	6478  AIC-786
+	6478  AIC-786x
 	6578  AIC-786x
-	6678  AIC-786
+	6678  AIC-786x
 	6778  AIC-786x
 	6915  ANA620xx/ANA69011A
 		9004 0008  ANA69011A/TX 10/100
 		9004 0009  ANA69011A/TX 10/100
 		9004 0010  ANA62022 2-port 10/100
 		9004 0018  ANA62044 4-port 10/100
+		9004 0019  ANA62044 4-port 10/100
 		9004 0020  ANA62022 2-port 10/100
 		9004 0028  ANA69011A/TX 10/100
 		9004 8008  ANA69011A/TX 64 bit 10/100
 		9004 8009  ANA69011A/TX 64 bit 10/100
 		9004 8010  ANA62022 2-port 64 bit 10/100
 		9004 8018  ANA62044 4-port 64 bit 10/100
+		9004 8019  ANA62044 4-port 64 bit 10/100
 		9004 8020  ANA62022 2-port 64 bit 10/100
 		9004 8028  ANA69011A/TX 64 bit 10/100
 	7078  AHA-294x / AIC-7870
-	7178  AHA-294x / AIC-7871
-	7278  AHA-3940 / AIC-7872
+	7178  AHA-2940/2940W / AIC-7871
+	7278  AHA-3940/3940W / AIC-7872
 	7378  AHA-3985 / AIC-7873
-	7478  AHA-2944 / AIC-7874
-# DJ: Where did the 3rd number come from?
-	7578  AHA-3944 / AHA-3944W / 7875
-# DJ: Where did the 3rd number come from?
-	7678  AHA-4944W/UW / 7876
+	7478  AHA-2944/2944W / AIC-7874
+	7578  AHA-3944/3944W / AIC-7875
+	7678  AHA-4944W/UW / AIC-7876
 	7778  AIC-787x
 	7810  AIC-7810
 	7815  AIC-7815 RAID+Memory Controller IC
@@ -5206,49 +6015,69 @@
 	7893  AIC-789x
 	7894  AIC-789x
 	7895  AHA-2940U/UW / AHA-39xx / AIC-7895
+		9004 7890  AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+		9004 7891  AHA-2940U/2940UW Dual
+		9004 7892  AHA-3940AU/AUW/AUWD/UWD
+		9004 7894  AHA-3944AUWD
 		9004 7895  AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+		9004 7896  AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+		9004 7897  AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
 	7896  AIC-789x
 	7897  AIC-789x
 	8078  AIC-7880U
 		9004 7880  AIC-7880P Ultra/Ultra Wide SCSI Chipset
-	8178  AIC-7881U
+	8178  AHA-2940U/UW/D / AIC-7881U
 		9004 7881  AHA-2940UW SCSI Host Adapter
-	8278  AHA-3940U/UW / AIC-7882U
+	8278  AHA-3940U/UW/UWD / AIC-7882U
 	8378  AHA-3940U/UW / AIC-7883U
-	8478  AHA-294x / AIC-7884U
-	8578  AHA-3944U / AHA-3944UWD / 7885
-	8678  AHA-4944UW / 7886
-	8778  AIC-788x
+	8478  AHA-2944UW / AIC-7884U
+	8578  AHA-3944U/UWD / AIC-7885
+	8678  AHA-4944UW / AIC-7886
+	8778  AHA-2940UW Pro / AIC-788x
 		9004 7887  2940UW Pro Ultra-Wide SCSI Controller
-	8878  7888
+	8878  AHA-2930UW / AIC-7888
+		9004 7888  AHA-2930UW SCSI Controller
 	8b78  ABA-1030
 	ec78  AHA-4944W/UW
 9005  Adaptec
-	0010  AHA-2940U2/W
-	0011  2930U2
+	0010  AHA-2940U2/U2W
+		9005 2180  AHA-2940U2 SCSI Controller
+		9005 8100  AHA-2940U2B SCSI Controller
+		9005 a180  AHA-2940U2W SCSI Controller
+		9005 e100  AHA-2950U2B SCSI Controller
+	0011  AHA-2930U2
 	0013  78902
 		9005 0003  AAA-131U2 Array1000 1 Channel RAID Controller
-	001f  AHA-2940U2/W / 7890
+	001f  AHA-2940U2/U2W / 7890/7891
 		9005 000f  2940U2W SCSI Controller
 		9005 a180  2940U2W SCSI Controller
 	0020  AIC-7890
 	002f  AIC-7890
 	0030  AIC-7890
 	003f  AIC-7890
-	0050  3940U2
-	0051  3950U2D
+	0050  AHA-3940U2x/395U2x
+		9005 f500  AHA-3950U2B
+	0051  AHA-3950U2D
+		9005 b500  AHA-3950U2D
 	0053  AIC-7896 SCSI Controller
 		9005 ffff  AIC-7896 SCSI Controller mainboard implementation
-	005f  7896
-	0080  7892A
-	0081  7892B
-	0083  7892D
-	008f  7892P
-	00c0  7899A
-	00c1  7899B
-	00c3  7899D
+	005f  AIC-7896U2/7897U2
+	0080  AIC-7892A U160/m
+		0e11 e2a0  Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter
+		9005 62a0  29160N Ultra160 SCSI Controller
+		9005 e220  29160LP Low Profile Ultra160 SCSI Controller
+		9005 e2a0  29160 Ultra160 SCSI Controller
+	0081  AIC-7892B U160/m
+		9005 62a1  19160 Ultra160 SCSI Controller
+	0083  AIC-7892D U160/m
+	008f  AIC-7892P U160/m
+	00c0  AHA-3960D / AIC-7899A U160/m
+		0e11 f620  Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
+		9005 f620  AHA-3960D U160/m
+	00c1  AIC-7899B U160/m
+	00c3  AIC-7899D U160/m
 	00c5  RAID subsystem HBA
-	00cf  7899P
+	00cf  AIC-7899P U160/m
 907f  Atronics
 	2015  IDE-2015PL
 919a  Gigapixel Corp
@@ -5256,6 +6085,9 @@
 	6565  6565
 9699  Omni Media Technology Inc
 	6565  6565
+9710  NetMos Technology
+	9815  VScom 021H-EP2 2 port parallel adaptor
+	9835  2xserial 1xparallel port adapter
 a0a0  AOPEN Inc.
 a0f1  UNISYS Corporation
 a200  NEC Corporation
@@ -5275,7 +6107,9 @@
 cccc  Catapult Communications
 d4d4  Dy4 Systems Inc
 	0601  PCI Mezzanine Card
+d531  I+ME ACTIA GmbH
 d84d  Exsys
+dead  Indigita Corporation
 e000  Winbond
 	e000  W89C940
 e159  Tiger Jet Network Inc.
@@ -5285,6 +6119,7 @@
 e4bf  EKF Elektronik GmbH
 ea01  Eagle Technology
 eabb  Aashima Technology B.V.
+eace  Endace Measurement Systems, Ltd
 ecc0  Echo Corporation
 edd8  ARK Logic Inc
 	a091  1000PV [Stingray]
@@ -5292,6 +6127,7 @@
 	a0a1  2000MT
 	a0a9  2000MI
 fa57  Fast Search & Transfer ASA
+febd  Ultraview Corp.
 feda  Epigram Inc
 fffe  VMWare Inc
 	0710  Virtual SVGA
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pci/quirks.c linux/drivers/pci/quirks.c
--- linux.orig/drivers/pci/quirks.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/pci/quirks.c	2002-07-20 01:08:23.000000000 +0000
@@ -90,8 +90,8 @@
  *	VIA Apollo KT133 needs PCI latency patch
  *	Made according to a windows driver based patch by George E. Breese
  *	see PCI Latency Adjust on http://www.viahardware.com/download/viatweak.shtm
- *      Also see http://home.tiscalinet.de/au-ja/review-kt133a-1-en.html for
- *      the info on which Mr Breese based his work.
+ *      Also see http://www.au-ja.org/review-kt133a-1-en.phtml for the info on which 
+ *	Mr Breese based his work.
  *
  *	Updated based on further information from the site and also on
  *	information provided by VIA 
@@ -457,10 +457,26 @@
 }
 
 /*
+ *	DreamWorks provided workaround for Dunord I-3000 problem
+ *
+ *	This card decodes and responds to addresses not apparently
+ *	assigned to it. We force a larger allocation to ensure that
+ *	nothing gets put too close to it.
+ */
+
+static void __init quirk_dunord ( struct pci_dev * dev )
+{
+	struct resource * r = & dev -> resource [ 1 ];
+	r -> start = 0;
+	r -> end = 0xffffff;
+}
+
+/*
  *  The main table of quirks.
  */
 
 static struct pci_fixup pci_fixups[] __initdata = {
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_DUNORD,	PCI_DEVICE_ID_DUNORD_I3000,	quirk_dunord },
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82441,	quirk_passive_release },
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82441,	quirk_passive_release },
 	/*
@@ -486,7 +502,7 @@
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_496,		quirk_nopcipci },
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	quirk_vialatency },
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8371_1,	quirk_vialatency },
-	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	0x3112	/* Not out yet ? */,	quirk_vialatency },
+	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8361,	quirk_vialatency },
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C576,	quirk_vsfx },
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C597_0,	quirk_viaetbf },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C597_0,	quirk_vt82c598_id },
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pci/setup-bus.c linux/drivers/pci/setup-bus.c
--- linux.orig/drivers/pci/setup-bus.c	2001-10-05 01:47:08.000000000 +0000
+++ linux/drivers/pci/setup-bus.c	2002-07-20 01:08:35.000000000 +0000
@@ -201,6 +201,16 @@
 		b->resource[0]->end = ranges->io_end - 1;
 		b->resource[1]->end = ranges->mem_end - 1;
 
+		/* Add bridge resources to the resource tree. */
+		if (b->resource[0]->end > b->resource[0]->start &&
+		    request_resource(bus->resource[0], b->resource[0]) < 0)
+			printk(KERN_ERR "PCI: failed to reserve IO "
+					"for bus %d\n",	b->number);
+		if (b->resource[1]->end > b->resource[1]->start &&
+		    request_resource(bus->resource[1], b->resource[1]) < 0)
+			printk(KERN_ERR "PCI: failed to reserve MEM "
+					"for bus %d\n", b->number);
+
 		pci_setup_bridge(b);
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/Config.in linux/drivers/pcmcia/Config.in
--- linux.orig/drivers/pcmcia/Config.in	2001-11-09 22:03:11.000000000 +0000
+++ linux/drivers/pcmcia/Config.in	2002-07-20 01:08:36.000000000 +0000
@@ -17,12 +17,17 @@
    if [ "$CONFIG_PCI" != "n" ]; then
       bool '  CardBus support' CONFIG_CARDBUS
    fi
-   dep_bool '  i82092 compatible bridge support' CONFIG_I82092 $CONFIG_PCI
-   bool '  i82365 compatible bridge support' CONFIG_I82365
    bool '  Databook TCIC host bridge support' CONFIG_TCIC
    if [ "$CONFIG_HD64465" = "y" ]; then
       dep_tristate '  HD64465 host bridge support' CONFIG_HD64465_PCMCIA $CONFIG_PCMCIA
    fi
+   dep_bool '  i82092 compatible bridge support' CONFIG_I82092 $CONFIG_PCI
+   bool '  i82365 compatible bridge support' CONFIG_I82365
+   if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+      dep_tristate '  SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_PCMCIA
+   fi
+   if [ "$CONFIG_8xx" = "y" ]; then
+      dep_tristate '  M8xx support' CONFIG_PCMCIA_M8XX $CONFIG_PCMCIA
+   fi
 fi
-
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/Makefile linux/drivers/pcmcia/Makefile
--- linux.orig/drivers/pcmcia/Makefile	2001-11-12 17:39:01.000000000 +0000
+++ linux/drivers/pcmcia/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -60,24 +60,27 @@
 endif
 
 obj-$(CONFIG_PCMCIA_SA1100)	+= sa1100_cs.o
+obj-$(CONFIG_PCMCIA_M8XX)	+= m8xx_pcmcia.o
 
 sa1100_cs-objs-y				:= sa1100_generic.o
+sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY)	+= sa1100_adsbitsy.o sa1111_generic.o
 sa1100_cs-objs-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.o
-sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET)	+= sa1100_neponset.o
-sa1100_cs-objs-$(CONFIG_SA1100_H3600)		+= sa1100_h3600.o
+sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET)	+= sa1100_neponset.o sa1111_generic.o
+sa1100_cs-objs-$(CONFIG_SA1100_BADGE4)		+= sa1100_badge4.o sa1111_generic.o
 sa1100_cs-objs-$(CONFIG_SA1100_CERF)		+= sa1100_cerf.o
+sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET)	+= sa1100_flexanet.o
+sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD)	+= sa1100_freebird.o
+sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER)	+= sa1100_graphicsmaster.o sa1111_generic.o
 sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT)	+= sa1100_graphicsclient.o
-sa1100_cs-objs-$(CONFIG_SA1100_XP860)		+= sa1100_xp860.o
+sa1100_cs-objs-$(CONFIG_SA1100_H3600)		+= sa1100_h3600.o
+sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720)	+= sa1100_jornada720.o sa1111_generic.o
 sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN)	+= sa1100_pangolin.o
-sa1100_cs-objs-$(CONFIG_SA1100_YOPY)		+= sa1100_yopy.o
-sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD)	+= sa1100_freebird.o
-sa1100_cs-objs-$(CONFIG_SA1100_PFS168)		+= sa1100_pfs168.o
-sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720)	+= sa1100_jornada720.o
-sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET)	+= sa1100_flexanet.o
+sa1100_cs-objs-$(CONFIG_SA1100_PFS168)		+= sa1100_pfs168.o sa1111_generic.o
+sa1100_cs-objs-$(CONFIG_SA1100_SHANNON)		+= sa1100_shannon.o
 sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD)		+= sa1100_simpad.o
-sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER)	+= sa1100_graphicsmaster.o
-sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY)	+= sa1100_adsbitsy.o
 sa1100_cs-objs-$(CONFIG_SA1100_STORK)		+= sa1100_stork.o
+sa1100_cs-objs-$(CONFIG_SA1100_XP860)		+= sa1100_xp860.o sa1111_generic.o
+sa1100_cs-objs-$(CONFIG_SA1100_YOPY)		+= sa1100_yopy.o
 
 include $(TOPDIR)/Rules.make
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/au1000_generic.c linux/drivers/pcmcia/au1000_generic.c
--- linux.orig/drivers/pcmcia/au1000_generic.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/pcmcia/au1000_generic.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,696 @@
+/*
+ *
+ * Alchemy Semi Au1000 pcmcia driver
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/bus_ops.h>
+#include "cs_internal.h"
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <asm/au1000.h>
+#include <asm/au1000_pcmcia.h>
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug;
+#endif
+
+MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov@mvista.com>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller");
+
+#define MAP_SIZE 0x1000000
+
+/* This structure maintains housekeeping state for each socket, such
+ * as the last known values of the card detect pins, or the Card Services
+ * callback value associated with the socket:
+ */
+static struct au1000_pcmcia_socket *pcmcia_socket;
+static int socket_count;
+
+
+/* Returned by the low-level PCMCIA interface: */
+static struct pcmcia_low_level *pcmcia_low_level;
+
+/* Event poll timer structure */
+static struct timer_list poll_timer;
+
+
+/* Prototypes for routines which are used internally: */
+
+static int  au1000_pcmcia_driver_init(void);
+static void au1000_pcmcia_driver_shutdown(void);
+static void au1000_pcmcia_task_handler(void *data);
+static void au1000_pcmcia_poll_event(u32 data);
+static void au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
+static struct tq_struct au1000_pcmcia_task;
+
+#ifdef CONFIG_PROC_FS
+static int au1000_pcmcia_proc_status(char *buf, char **start, 
+		off_t pos, int count, int *eof, void *data);
+#endif
+
+
+/* Prototypes for operations which are exported to the
+ * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
+ */
+
+static int au1000_pcmcia_init(u32 sock);
+static int au1000_pcmcia_suspend(u32 sock);
+static int au1000_pcmcia_register_callback(u32 sock, 
+		void (*handler)(void *, u32), void *info);
+static int au1000_pcmcia_inquire_socket(u32 sock, socket_cap_t *cap);
+static int au1000_pcmcia_get_status(u32 sock, u_int *value);
+static int au1000_pcmcia_get_socket(u32 sock, socket_state_t *state);
+static int au1000_pcmcia_set_socket(u32 sock, socket_state_t *state);
+static int au1000_pcmcia_get_io_map(u32 sock, struct pccard_io_map *io);
+static int au1000_pcmcia_set_io_map(u32 sock, struct pccard_io_map *io);
+static int au1000_pcmcia_get_mem_map(u32 sock, struct pccard_mem_map *mem);
+static int au1000_pcmcia_set_mem_map(u32 sock, struct pccard_mem_map *mem);
+#ifdef CONFIG_PROC_FS
+static void au1000_pcmcia_proc_setup(u32 sock, struct proc_dir_entry *base);
+#endif
+
+static struct pccard_operations au1000_pcmcia_operations = {
+	au1000_pcmcia_init,
+	au1000_pcmcia_suspend,
+	au1000_pcmcia_register_callback,
+	au1000_pcmcia_inquire_socket,
+	au1000_pcmcia_get_status,
+	au1000_pcmcia_get_socket,
+	au1000_pcmcia_set_socket,
+	au1000_pcmcia_get_io_map,
+	au1000_pcmcia_set_io_map,
+	au1000_pcmcia_get_mem_map,
+	au1000_pcmcia_set_mem_map,
+#ifdef CONFIG_PROC_FS
+	au1000_pcmcia_proc_setup
+#endif
+};
+
+static int __init au1000_pcmcia_driver_init(void)
+{
+	servinfo_t info;
+	struct pcmcia_init pcmcia_init;
+	struct pcmcia_state state;
+	unsigned int i;
+	unsigned long timing3;
+
+	printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE);
+
+	CardServices(GetCardServicesInfo, &info);
+
+	if(info.Revision!=CS_RELEASE_CODE){
+		printk(KERN_ERR "Card Services release codes do not match\n");
+		return -1;
+	}
+
+#ifdef CONFIG_MIPS_PB1000
+	pcmcia_low_level=&pb1000_pcmcia_ops;
+#elif defined(CONFIG_MIPS_PB1500)
+	pcmcia_low_level=&pb1500_pcmcia_ops;
+#else
+#error Unsupported AU1000 board.
+#endif
+
+	pcmcia_init.handler=au1000_pcmcia_interrupt;
+	if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
+		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
+		return -EIO;
+	}
+
+	/* setup the static bus controller */
+	timing3 = 0x100e3a07;
+	writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+	writel(timing3, MEM_STTIME3); 
+	writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+	au_sync_delay(1);
+
+	pcmcia_socket = 
+		kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, 
+				GFP_KERNEL);
+	if (!pcmcia_socket) {
+		printk(KERN_ERR "Card Services can't get memory \n");
+		return -1;
+	}
+	memset(pcmcia_socket, 0,
+			sizeof(struct au1000_pcmcia_socket) * socket_count);
+			
+	for(i=0; i < socket_count; i++) {
+
+		if(pcmcia_low_level->socket_state(i, &state)<0){
+			printk(KERN_ERR "Unable to get PCMCIA status\n");
+			return -EIO;
+		}
+		pcmcia_socket[i].k_state=state;
+		pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
+		
+		if (i == 0) {
+			pcmcia_socket[i].virt_io = 
+				(u32)ioremap(0xC0000000, 0x1000);
+			pcmcia_socket[i].phys_attr = 0xC4000000;
+			pcmcia_socket[i].phys_mem = 0xC8000000;
+		}
+		else  {
+			printk(KERN_ERR "au1000: socket 1 not supported\n");
+			return 1;
+		}
+	}
+
+	/* Only advertise as many sockets as we can detect: */
+	if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
+		printk(KERN_ERR "Unable to register socket service routine\n");
+		return -ENXIO;
+	}
+
+	/* Start the event poll timer.  
+	 * It will reschedule by itself afterwards. 
+	 */
+	au1000_pcmcia_poll_event(0);
+
+	DEBUG(1, "au1000: initialization complete\n");
+	return 0;
+
+}  /* au1000_pcmcia_driver_init() */
+
+module_init(au1000_pcmcia_driver_init);
+
+static void __exit au1000_pcmcia_driver_shutdown(void)
+{
+	int i;
+
+	del_timer_sync(&poll_timer);
+	unregister_ss_entry(&au1000_pcmcia_operations);
+	pcmcia_low_level->shutdown();
+	flush_scheduled_tasks();
+	for(i=0; i < socket_count; i++) {
+		if (pcmcia_socket[i].virt_io) 
+			iounmap((void *)pcmcia_socket[i].virt_io);
+	}
+	DEBUG(1, "au1000: shutdown complete\n");
+}
+
+module_exit(au1000_pcmcia_driver_shutdown);
+
+static int au1000_pcmcia_init(unsigned int sock) { return 0; }
+
+static int au1000_pcmcia_suspend(unsigned int sock)
+{
+	return 0;
+}
+
+
+static inline unsigned 
+au1000_pcmcia_events(struct pcmcia_state *state, 
+		struct pcmcia_state *prev_state, 
+		unsigned int mask, unsigned int flags)
+{
+	unsigned int events=0;
+
+	if(state->detect!=prev_state->detect){
+		DEBUG(2, "%s(): card detect value %u\n", 
+				__FUNCTION__, state->detect);
+		events |= mask&SS_DETECT;
+	}
+
+
+	if(state->ready!=prev_state->ready){
+		DEBUG(2, "%s(): card ready value %u\n", 
+				__FUNCTION__, state->ready);
+		events |= mask&((flags&SS_IOCARD)?0:SS_READY);
+	}
+
+	*prev_state=*state;
+	return events;
+
+}  /* au1000_pcmcia_events() */
+
+
+/* 
+ * Au1000_pcmcia_task_handler()
+ * Processes socket events.
+ */
+static void au1000_pcmcia_task_handler(void *data) 
+{
+	struct pcmcia_state state;
+	int i, events, irq_status;
+
+	for(i=0; i<socket_count; i++)  {
+		if((irq_status = pcmcia_low_level->socket_state(i, &state))<0)
+			printk(KERN_ERR "low-level PCMCIA error\n");
+
+		events = au1000_pcmcia_events(&state, 
+				&pcmcia_socket[i].k_state, 
+				pcmcia_socket[i].cs_state.csc_mask, 
+				pcmcia_socket[i].cs_state.flags);
+		if(pcmcia_socket[i].handler!=NULL) {
+			pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
+					events);
+		}
+	}
+
+}  /* au1000_pcmcia_task_handler() */
+
+static struct tq_struct au1000_pcmcia_task = {
+	routine: au1000_pcmcia_task_handler
+};
+
+
+static void au1000_pcmcia_poll_event(u32 dummy)
+{
+	poll_timer.function = au1000_pcmcia_poll_event;
+	poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
+	add_timer(&poll_timer);
+	schedule_task(&au1000_pcmcia_task);
+}
+
+
+/* 
+ * au1000_pcmcia_interrupt()
+ * The actual interrupt work is performed by au1000_pcmcia_task(), 
+ * because the Card Services event handling code performs scheduling 
+ * operations which cannot be executed from within an interrupt context.
+ */
+static void 
+au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
+	schedule_task(&au1000_pcmcia_task);
+}
+
+
+static int 
+au1000_pcmcia_register_callback(unsigned int sock, 
+		void (*handler)(void *, unsigned int), void *info)
+{
+	if(handler==NULL){
+		pcmcia_socket[sock].handler=NULL;
+		MOD_DEC_USE_COUNT;
+	} else {
+		MOD_INC_USE_COUNT;
+		pcmcia_socket[sock].handler=handler;
+		pcmcia_socket[sock].handler_info=info;
+	}
+	return 0;
+}
+
+
+/* au1000_pcmcia_inquire_socket()
+ *
+ * From the sa1100 socket driver : 
+ *
+ * Implements the inquire_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_InquireSocket in Card Services).  We set 
+ * SS_CAP_STATIC_MAP, which disables the memory resource database check. 
+ * (Mapped memory is set up within the socket driver itself.)
+ *
+ * In conjunction with the STATIC_MAP capability is a new field,
+ * `io_offset', recommended by David Hinds. Rather than go through
+ * the SetIOMap interface (which is not quite suited for communicating
+ * window locations up from the socket driver), we just pass up 
+ * an offset which is applied to client-requested base I/O addresses
+ * in alloc_io_space().
+ *
+ * Returns: 0 on success, -1 if no pin has been configured for `sock'
+ */
+static int au1000_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
+{
+	struct pcmcia_irq_info irq_info;
+
+	if(sock > socket_count){
+		printk(KERN_ERR "au1000: socket %u not configured\n", sock);
+		return -1;
+	}
+
+	/* from the sa1100_generic driver: */
+
+	/* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
+	*   force_low argument to validate_mem() in rsrc_mgr.c -- since in
+	*   general, the mapped * addresses of the PCMCIA memory regions
+	*   will not be within 0xffff, setting force_low would be
+	*   undesirable.
+	*
+	* SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
+	*   resource database; we instead pass up physical address ranges
+	*   and allow other parts of Card Services to deal with remapping.
+	*
+	* SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
+	*   not 32-bit CardBus devices.
+	*/
+	cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
+
+	irq_info.sock=sock;
+	irq_info.irq=-1;
+
+	if(pcmcia_low_level->get_irq_info(&irq_info)<0){
+		printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
+		return -1;
+	}
+
+	cap->irq_mask=0;
+	cap->map_size=MAP_SIZE;
+	cap->pci_irq=irq_info.irq;
+	cap->io_offset=pcmcia_socket[sock].virt_io;
+
+	return 0;
+
+}  /* au1000_pcmcia_inquire_socket() */
+
+
+static int 
+au1000_pcmcia_get_status(unsigned int sock, unsigned int *status)
+{
+	struct pcmcia_state state;
+
+
+	if((pcmcia_low_level->socket_state(sock, &state))<0){
+		printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+		return -1;
+	}
+
+	pcmcia_socket[sock].k_state = state;
+
+	*status = state.detect?SS_DETECT:0;
+
+	*status |= state.ready?SS_READY:0;
+
+	*status |= pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
+
+	if(pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
+		*status |= state.bvd1?SS_STSCHG:0;
+	else {
+		if(state.bvd1==0)
+			*status |= SS_BATDEAD;
+		else if(state.bvd2 == 0)
+			*status |= SS_BATWARN;
+	}
+
+	*status|=state.vs_3v?SS_3VCARD:0;
+
+	*status|=state.vs_Xv?SS_XVCARD:0;
+
+	DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
+	(*status&SS_DETECT)?"DETECT ":"",
+	(*status&SS_READY)?"READY ":"", 
+	(*status&SS_BATDEAD)?"BATDEAD ":"",
+	(*status&SS_BATWARN)?"BATWARN ":"",
+	(*status&SS_POWERON)?"POWERON ":"",
+	(*status&SS_STSCHG)?"STSCHG ":"",
+	(*status&SS_3VCARD)?"3VCARD ":"",
+	(*status&SS_XVCARD)?"XVCARD ":"");
+
+	return 0;
+
+}  /* au1000_pcmcia_get_status() */
+
+
+static int 
+au1000_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
+{
+	*state = pcmcia_socket[sock].cs_state;
+	return 0;
+}
+
+
+static int 
+au1000_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
+{
+	struct pcmcia_configure configure;
+
+	DEBUG(2, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
+	"\tVcc %d  Vpp %d  irq %d\n",
+	(state->csc_mask==0)?"<NONE>":"",
+	(state->csc_mask&SS_DETECT)?"DETECT ":"",
+	(state->csc_mask&SS_READY)?"READY ":"",
+	(state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
+	(state->csc_mask&SS_BATWARN)?"BATWARN ":"",
+	(state->csc_mask&SS_STSCHG)?"STSCHG ":"",
+	(state->flags==0)?"<NONE>":"",
+	(state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
+	(state->flags&SS_IOCARD)?"IOCARD ":"",
+	(state->flags&SS_RESET)?"RESET ":"",
+	(state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
+	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
+	state->Vcc, state->Vpp, state->io_irq);
+
+	configure.sock=sock;
+	configure.vcc=state->Vcc;
+	configure.vpp=state->Vpp;
+	configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
+	configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
+	configure.reset=(state->flags&SS_RESET)?1:0;
+
+	if(pcmcia_low_level->configure_socket(&configure)<0){
+		printk(KERN_ERR "Unable to configure socket %u\n", sock);
+		return -1;
+	}
+
+	pcmcia_socket[sock].cs_state = *state;
+	return 0;
+
+}  /* au1000_pcmcia_set_socket() */
+
+
+static int 
+au1000_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
+{
+	DEBUG(1, "au1000_pcmcia_get_io_map: sock %d\n", sock);
+	if(map->map>=MAX_IO_WIN){
+		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+				__FUNCTION__, map->map);
+		return -1;
+	}
+	*map=pcmcia_socket[sock].io_map[map->map];
+	return 0;
+}
+
+
+int 
+au1000_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
+{
+	unsigned int speed;
+	unsigned long start;
+
+	if(map->map>=MAX_IO_WIN){
+		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+				__FUNCTION__, map->map);
+		return -1;
+	}
+
+	if(map->flags&MAP_ACTIVE){
+		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED;
+		pcmcia_socket[sock].speed_io=speed;
+	}
+
+	start=map->start;
+
+	if(map->stop==1) {
+		map->stop=PAGE_SIZE-1;
+	}
+
+	map->start=pcmcia_socket[sock].virt_io;
+	map->stop=map->start+(map->stop-start);
+	pcmcia_socket[sock].io_map[map->map]=*map;
+	DEBUG(3, "set_io_map %d start %x stop %x\n", 
+			map->map, map->start, map->stop);
+	return 0;
+
+}  /* au1000_pcmcia_set_io_map() */
+
+
+static int 
+au1000_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
+{
+
+	if(map->map>=MAX_WIN) {
+		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+				__FUNCTION__, map->map);
+		return -1;
+	}
+	*map=pcmcia_socket[sock].mem_map[map->map];
+	return 0;
+}
+
+
+static int 
+au1000_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
+{
+	unsigned int speed;
+	unsigned long start;
+	u_long flags;
+
+	if(map->map>=MAX_WIN){
+		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+				__FUNCTION__, map->map);
+		return -1;
+	}
+
+	if(map->flags&MAP_ACTIVE){
+		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_MEM_SPEED;
+
+		/* TBD */
+		if(map->flags&MAP_ATTRIB){
+			pcmcia_socket[sock].speed_attr=speed;
+		} 
+		else {
+			pcmcia_socket[sock].speed_mem=speed;
+		}
+	}
+
+	save_flags(flags);
+	cli();
+	start=map->sys_start;
+
+	if(map->sys_stop==0)
+		map->sys_stop=MAP_SIZE-1;
+
+	if (map->flags & MAP_ATTRIB) {
+		map->sys_start = pcmcia_socket[sock].phys_attr + 
+			map->card_start;
+	}
+	else {
+		map->sys_start = pcmcia_socket[sock].phys_mem + 
+			map->card_start;
+	}
+
+	map->sys_stop=map->sys_start+(map->sys_stop-start);
+	pcmcia_socket[sock].mem_map[map->map]=*map;
+	restore_flags(flags);
+	DEBUG(3, "set_mem_map %d start %x stop %x card_start %x\n", 
+			map->map, map->sys_start, map->sys_stop, 
+			map->card_start);
+	return 0;
+
+}  /* au1000_pcmcia_set_mem_map() */
+
+
+#if defined(CONFIG_PROC_FS)
+
+static void 
+au1000_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+{
+	struct proc_dir_entry *entry;
+
+	if((entry=create_proc_entry("status", 0, base))==NULL){
+		printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
+		return;
+	}
+
+	entry->read_proc=au1000_pcmcia_proc_status;
+	entry->data=(void *)sock;
+}
+
+
+/* au1000_pcmcia_proc_status()
+ * Implements the /proc/bus/pccard/??/status file.
+ *
+ * Returns: the number of characters added to the buffer
+ */
+static int 
+au1000_pcmcia_proc_status(char *buf, char **start, off_t pos, 
+		int count, int *eof, void *data)
+{
+	char *p=buf;
+	unsigned int sock=(unsigned int)data;
+
+	p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 
+	     pcmcia_socket[sock].k_state.detect?"detect ":"",
+	     pcmcia_socket[sock].k_state.ready?"ready ":"",
+	     pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
+	     pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
+	     pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
+	     pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
+	     pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
+
+	p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
+	     pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
+	     pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
+	     pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
+	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+	     "SS_IOCARD ":"",
+	     (pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
+	      pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
+	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+	      (pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
+	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+	      (pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
+	     pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
+	     pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
+
+	p+=sprintf(p, "mask     : %s%s%s%s%s\n",
+	     pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
+	     "SS_DETECT ":"",
+	     pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
+	     "SS_READY ":"",
+	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
+	     "SS_BATDEAD ":"",
+	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
+	     "SS_BATWARN ":"",
+	     pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
+	     "SS_STSCHG ":"");
+
+	p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
+	     pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
+	     "SS_PWR_AUTO ":"",
+	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+	     "SS_IOCARD ":"",
+	     pcmcia_socket[sock].cs_state.flags&SS_RESET?\
+	     "SS_RESET ":"",
+	     pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
+	     "SS_SPKR_ENA ":"",
+	     pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
+	     "SS_OUTPUT_ENA ":"");
+
+	p+=sprintf(p, "Vcc      : %d\n", pcmcia_socket[sock].cs_state.Vcc);
+	p+=sprintf(p, "Vpp      : %d\n", pcmcia_socket[sock].cs_state.Vpp);
+	p+=sprintf(p, "irq      : %d\n", pcmcia_socket[sock].cs_state.io_irq);
+	p+=sprintf(p, "I/O      : %u\n", pcmcia_socket[sock].speed_io);
+	p+=sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
+	p+=sprintf(p, "common   : %u\n", pcmcia_socket[sock].speed_mem);
+	return p-buf;
+}
+
+
+#endif  /* defined(CONFIG_PROC_FS) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/au1000_pb1000.c linux/drivers/pcmcia/au1000_pb1000.c
--- linux.orig/drivers/pcmcia/au1000_pb1000.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/pcmcia/au1000_pb1000.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,307 @@
+/*
+ *
+ * Alchemy Semi PB1000 board specific pcmcia routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+#include <linux/types.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/bus_ops.h>
+#include "cs_internal.h"
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <asm/au1000.h>
+#include <asm/au1000_pcmcia.h>
+#include <asm/pb1000.h>
+
+
+extern struct pcmcia_x_table x_table;
+
+static int pb1000_pcmcia_init(struct pcmcia_init *init)
+{
+	u32 pcr;
+	pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
+
+	writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */
+	au_sync_delay(100);
+	writel(0x4000, PB1000_MDR); /* enable pcmcia interrupt */
+	au_sync();
+
+	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
+	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1);
+	writew(pcr, PB1000_PCR);
+	au_sync_delay(20);
+	  
+	/* There's two sockets, but only the first one, 0, is used and tested */
+	return 1;
+}
+
+static int pb1000_pcmcia_shutdown(void)
+{
+	u16 pcr;
+	pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
+	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
+	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1);
+	writew(pcr, PB1000_PCR);
+	au_sync_delay(20);
+	return 0;
+}
+
+static int 
+pb1000_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
+{
+	u16 levels, pcr;
+	unsigned char vs;
+
+	levels = readw(PB1000_ACR1);
+	pcr = readw(PB1000_PCR);
+
+	state->ready = 0;
+	state->vs_Xv = 0;
+	state->vs_3v = 0;
+	state->detect = 0;
+
+	/* 
+	 * This is tricky. The READY pin is also the #IRQ pin.  We'll treat
+	 * READY as #IRQ and set state->ready to 1 whenever state->detect 
+	 * is true.
+	 */
+
+	/* 
+	 * CD1/2 are active low; so are the VSS pins; Ready is active high
+	 */
+	if (sock == 0) {
+		if (!(levels & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2))) {
+			state->detect = 1;
+			vs =  (levels >> 4) & 0x3;
+			switch (vs) {
+				case 0:
+				case 1:
+				case 2:
+					state->vs_3v=1;
+					break;
+				case 3:
+				default:
+					break;
+			}
+		}
+	}
+	else if (sock == 1) {
+		if (!(levels & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2))) {
+			state->detect = 1;
+			vs =  (levels >> 12) & 0x3;
+			switch (vs) {
+				case 0:
+				case 1:
+				case 2:
+					state->vs_3v=1;
+					break;
+				case 3:
+				default:
+					break;
+			}
+		}
+	}
+	else  {
+		printk(KERN_ERR "pb1000 socket_state bad sock %d\n", sock);
+	}
+
+	if (state->detect)
+		state->ready = 1;
+
+	state->bvd1=1;
+	state->bvd2=1;
+	state->wrprot=0; 
+	return 1;
+}
+
+
+static int pb1000_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+	if(info->sock > PCMCIA_MAX_SOCK) return -1;
+
+	if(info->sock == 0)
+		info->irq = AU1000_GPIO_15;
+	else 
+		info->irq = -1;
+
+	return 0;
+}
+
+
+static int 
+pb1000_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+	u16 pcr;
+
+	if(configure->sock > PCMCIA_MAX_SOCK) return -1;
+
+	pcr = readw(PB1000_PCR);
+
+	if (configure->sock == 0) {
+		pcr &= ~(PCR_SLOT_0_VCC0 | PCR_SLOT_0_VCC1 | 
+				PCR_SLOT_0_VPP0 | PCR_SLOT_0_VPP1);
+	}
+	else  {
+		pcr &= ~(PCR_SLOT_1_VCC0 | PCR_SLOT_1_VCC1 | 
+				PCR_SLOT_1_VPP0 | PCR_SLOT_1_VPP1);
+	}
+
+	pcr &= ~PCR_SLOT_0_RST;
+	/*
+	writew(pcr, PB1000_PCR);
+	au_sync_delay(200);
+	*/
+	DEBUG(KERN_INFO "Vcc %dV Vpp %dV, pcr %x\n", 
+			configure->vcc, configure->vpp, pcr);
+	switch(configure->vcc){
+		case 0:  /* Vcc 0 */
+			switch(configure->vpp) {
+				case 0:
+					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_GND,
+							configure->sock);
+					break;
+				case 12:
+					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_12V,
+							configure->sock);
+					break;
+				case 50:
+					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_5V,
+							configure->sock);
+					break;
+				case 33:
+					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_3V,
+							configure->sock);
+					break;
+				default:
+					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
+							configure->sock);
+					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
+							__FUNCTION__, 
+							configure->vcc, 
+							configure->vpp);
+					break;
+			}
+			break;
+		case 50: /* Vcc 5V */
+			switch(configure->vpp) {
+				case 0:
+					pcr |= SET_VCC_VPP(VCC_5V,VPP_GND,
+							configure->sock);
+					break;
+				case 50:
+					pcr |= SET_VCC_VPP(VCC_5V,VPP_5V,
+							configure->sock);
+					break;
+				case 12:
+					pcr |= SET_VCC_VPP(VCC_5V,VPP_12V,
+							configure->sock);
+					break;
+				case 33:
+					pcr |= SET_VCC_VPP(VCC_5V,VPP_3V,
+							configure->sock);
+					break;
+				default:
+					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
+							configure->sock);
+					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
+							__FUNCTION__, 
+							configure->vcc, 
+							configure->vpp);
+					break;
+			}
+			break;
+		case 33: /* Vcc 3.3V */
+			switch(configure->vpp) {
+				case 0:
+					pcr |= SET_VCC_VPP(VCC_3V,VPP_GND,
+							configure->sock);
+					break;
+				case 50:
+					pcr |= SET_VCC_VPP(VCC_3V,VPP_5V,
+							configure->sock);
+					break;
+				case 12:
+					pcr |= SET_VCC_VPP(VCC_3V,VPP_12V,
+							configure->sock);
+					break;
+				case 33:
+					pcr |= SET_VCC_VPP(VCC_3V,VPP_3V,
+							configure->sock);
+					break;
+				default:
+					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
+							configure->sock);
+					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
+							__FUNCTION__, 
+							configure->vcc, 
+							configure->vpp);
+					break;
+			}
+			break;
+		default: /* what's this ? */
+			pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock);
+			printk(KERN_ERR "%s: bad Vcc %d\n", 
+					__FUNCTION__, configure->vcc);
+			break;
+	}
+
+	pcr &= ~(PCR_SLOT_0_RST);
+	if (configure->reset) {
+		pcr |= PCR_SLOT_0_RST;
+	}
+	writew(pcr, PB1000_PCR);
+	au_sync_delay(300);
+	return 0;
+}
+
+struct pcmcia_low_level pb1000_pcmcia_ops = { 
+	pb1000_pcmcia_init,
+	pb1000_pcmcia_shutdown,
+	pb1000_pcmcia_socket_state,
+	pb1000_pcmcia_get_irq_info,
+	pb1000_pcmcia_configure_socket
+};
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- linux.orig/drivers/pcmcia/cs.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/pcmcia/cs.c	2002-07-20 01:08:29.000000000 +0000
@@ -1268,7 +1268,7 @@
     } else
 	c = CONFIG(handle);
     if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
-	(c->IntType & INT_MEMORY_AND_IO)) {
+	(c->IntType & (INT_MEMORY_AND_IO|INT_ZOOMED_VIDEO))) {
 	u_char reg;
 	if (c->Present & PRESENT_PIN_REPLACE) {
 	    read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
@@ -1696,6 +1696,8 @@
     c->Attributes = req->Attributes;
     if (req->IntType & INT_MEMORY_AND_IO)
 	s->socket.flags |= SS_IOCARD;
+    if (req->IntType & INT_ZOOMED_VIDEO)
+	s->socket.flags |= SS_ZVCARD|SS_IOCARD;
     if (req->Attributes & CONF_ENABLE_DMA)
 	s->socket.flags |= SS_DMA_MODE;
     if (req->Attributes & CONF_ENABLE_SPKR)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/m8xx_pcmcia.c linux/drivers/pcmcia/m8xx_pcmcia.c
--- linux.orig/drivers/pcmcia/m8xx_pcmcia.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/pcmcia/m8xx_pcmcia.c	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,1236 @@
+/* 
+ * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
+ *
+ * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
+ * (C) 2001-2002 Montavista Software, Inc.
+ *     <mlocke@mvista.com>
+ *
+ * "The ExCA standard specifies that socket controllers should provide 
+ * two IO and five memory windows per socket, which can be independently 
+ * configured and positioned in the host address space and mapped to 
+ * arbitrary segments of card address space. " - David A Hinds. 1999
+ *
+ * This controller does _not_ meet the ExCA standard.
+ * 
+ * m8xx pcmcia controller brief info:
+ * + 8 windows (attrib, mem, i/o)
+ * + up to two slots (SLOT_A and SLOT_B)
+ * + inputpins, outputpins, event and mask registers.
+ * - no offset register. sigh.
+ *
+ * Because of the lacking offset register we must map the whole card.
+ * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
+ * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO 
+ * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
+ * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
+ * They are maximum 64KByte each...
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include <asm/mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include <asm/irq.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+#define DEBUG(n, args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
+#else
+#define DEBUG(n, args...)
+#endif
+
+#define PCMCIA_INFO(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
+#define PCMCIA_ERROR(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
+
+static const char *version = "Version 0.05, 14-Apr-2002";
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* The RPX series use SLOT_B */
+
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+#define CONFIG_PCMCIA_SLOT_B
+#endif
+
+/* The MBX board use SLOT_A */
+
+#ifdef CONFIG_MBX
+#define CONFIG_PCMCIA_SLOT_A
+#endif
+
+/* The FADS860T board use SLOT_A */
+
+#ifdef CONFIG_FADS
+#define CONFIG_PCMCIA_SLOT_A
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0   */
+#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte     */
+#define PCMCIA_IO_WIN_BASE  _IO_BASE   /* base address for io window 0       */
+
+#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level      */
+
+/* ------------------------------------------------------------------------- */
+
+#define PCMCIA_SOCKETS_NO 1
+
+#define PCMCIA_MEM_WIN_NO 5
+#define PCMCIA_IO_WIN_NO  2
+
+/* define _slot_ to be able to optimize macros */
+
+#ifdef CONFIG_PCMCIA_SLOT_A
+#define _slot_ 0
+#define PCMCIA_SLOT_MSG "SLOT_A"
+#else
+#define _slot_ 1
+#define PCMCIA_SLOT_MSG "SLOT_B"
+#endif
+
+#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
+
+static int pcmcia_schlvl = PCMCIA_SCHLVL;
+
+/* ------------------------------------------------------------------------- */
+
+#define PCMCIA_SOCKET_KEY_5V 1
+#define PCMCIA_SOCKET_KEY_LV 2
+
+
+/* look up table for pgcrx registers */
+
+static u_int *m8xx_pgcrx[2] = {
+	&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
+	&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
+}; 
+
+/*
+ * This structure is used to address each window in the PCMCIA controller. 
+ * 
+ * Keep in mind that we assume that pcmcia_win_t[n+1] is mapped directly
+ * after pcmcia_win_t[n]... 
+ */
+
+typedef struct {             
+	uint	br;           
+	uint	or;
+} pcmcia_win_t;
+
+/* 
+ * For some reason the hardware guys decided to make both slots share
+ * some registers.
+ *
+ * Could someone invent object oriented hardware ?
+ *
+ * The macros are used to get the right bit from the registers.
+ * SLOT_A : slot = 0
+ * SLOT_B : slot = 1
+ */
+
+#define M8XX_PCMCIA_VS1(slot)      (0x80000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS2(slot)      (0x40000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS_MASK(slot)  (0xc0000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
+
+#define M8XX_PCMCIA_WP(slot)       (0x20000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
+#define M8XX_PCMCIA_BVD2(slot)     (0x04000000 >> (slot << 4))
+#define M8XX_PCMCIA_BVD1(slot)     (0x02000000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY(slot)      (0x01000000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_L(slot)    (0x00800000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_H(slot)    (0x00400000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_R(slot)    (0x00200000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_F(slot)    (0x00100000 >> (slot << 4))
+#define M8XX_PCMCIA_MASK(slot)     (0xFFFF0000 >> (slot << 4))
+
+#define M8XX_PGCRX(slot)  (*m8xx_pgcrx[slot])
+
+#define M8XX_PGCRX_CXOE    0x00000080
+#define M8XX_PGCRX_CXRESET 0x00000040
+
+/* we keep one lookup table per socket to check flags */ 
+
+#define PCMCIA_EVENTS_MAX 5  /* 4 max at a time + termination */
+
+typedef struct  {
+	u_int regbit;
+	u_int eventbit;
+} event_table_t;
+
+typedef struct socket_info_t {
+    void	(*handler)(void *info, u_int events);
+    void	*info;
+
+    u_int  slot;
+
+    socket_state_t state;
+    struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
+    struct pccard_io_map  io_win[PCMCIA_IO_WIN_NO];
+    event_table_t events[PCMCIA_EVENTS_MAX]; 
+} socket_info_t;
+
+static socket_info_t socket[PCMCIA_SOCKETS_NO];
+
+static socket_cap_t capabilities = {
+    SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP, /* features - 
+							     only 16-bit cards, 
+							     memory windows must be
+							     size-aligned */
+    0x000,		/* irq_mask - SIU_LEVEL 7 -> 0          */
+    0x1000,		/* map_size - 4K minimum window size    */
+    0,			/* io_offset -			*/
+    9,			/* pci_irq */
+    0		/* No PCI or CardBus support */
+};
+
+/* 
+ * Search this table to see if the windowsize is
+ * supported...
+ */
+
+#define M8XX_SIZES_NO 32
+
+static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] = 
+{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
+  0x00000080, 0x00000040, 0x00000010, 0x00000020,
+  0x00008000, 0x00004000, 0x00001000, 0x00002000,
+  0x00000100, 0x00000200, 0x00000800, 0x00000400,
+
+  0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x01000000, 0x02000000, 0xffffffff, 0x04000000,
+  0x00010000, 0x00020000, 0x00080000, 0x00040000,
+  0x00800000, 0x00400000, 0x00100000, 0x00200000 };
+
+
+/* ------------------------------------------------------------------------- */
+
+static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
+
+#define PCMCIA_BMT_LIMIT (15*4)  /* Bus Monitor Timeout value */
+
+/* ------------------------------------------------------------------------- */
+/* board specific stuff:                                                     */
+/* voltage_set(), hardware_enable() and hardware_disable()                   */
+/* ------------------------------------------------------------------------- */
+/* RPX Boards from Embedded Planet                                           */
+
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+
+/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
+ * SYPCR is write once only, therefore must the slowest memory be faster 
+ * than the bus monitor or we will get a machine check due to the bus timeout.
+ */
+
+#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
+
+#undef PCMCIA_BMT_LIMIT
+#define PCMCIA_BMT_LIMIT (6*8) 
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	u_int reg = 0;
+
+	switch(vcc) {
+	case 0: break;
+	case 33: reg |= BCSR1_PCVCTL4; break;
+	case 50: reg |= BCSR1_PCVCTL5; break;
+	default: return 1;
+	}
+
+	switch(vpp) {
+	case 0: break;
+	case 33: 
+	case 50:
+		if(vcc == vpp)
+			reg |= BCSR1_PCVCTL6;
+		else
+			return 1;
+		break;
+	case 120: 
+		reg |= BCSR1_PCVCTL7;
+	default: return 1;
+	}
+
+	if(!((vcc == 50) || (vcc == 0)))
+	   return 1;
+
+	/* first, turn off all power */
+
+	*((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
+				     | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
+
+	/* enable new powersettings */
+
+	*((uint *)RPX_CSR_ADDR) |= reg;
+
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+#define hardware_enable(_slot_)  /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_RPXCLASSIC */
+
+/* ------------------------------------------------------------------------- */
+/* FADS Boards from Motorola                                               */
+
+#if defined(CONFIG_FADS)
+
+#define PCMCIA_BOARD_MSG "FADS"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	uint reg = 0;
+
+	switch(vcc) {
+		case 0: break;
+		case 33: reg |= BCSR1_PCCVCC0; break;
+		case 50: reg |= BCSR1_PCCVCC1; break;
+		default: return 1;
+	}
+
+	switch(vpp) {
+		case 0: break;
+		case 33:
+		case 50:
+			if(vcc == vpp)
+				reg |= BCSR1_PCCVPP1;
+			else
+				return 1;
+			break;
+		case 120:
+			if ((vcc == 33) || (vcc == 50))
+				reg |= BCSR1_PCCVPP0;
+			else
+				return 1;
+		default: return 1;
+	}
+
+	/* first, turn off all power */
+	*((uint *)BCSR1) &= ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK);
+
+	/* enable new powersettings */
+	*((uint *)BCSR1) |= reg;
+
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static void hardware_enable(int slot)
+{
+	*((uint *)BCSR1) &= ~BCSR1_PCCEN;
+}
+
+static void hardware_disable(int slot)
+{
+	*((uint *)BCSR1) |=  BCSR1_PCCEN;
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Motorola MBX860                                                           */
+
+#if defined(CONFIG_MBX)
+
+#define PCMCIA_BOARD_MSG "MBX"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	unsigned char reg = 0;
+
+	switch(vcc) {
+		case 0: break;
+		case 33: reg |= CSR2_VCC_33; break;
+		case 50: reg |= CSR2_VCC_50; break;
+		default: return 1;
+	}
+
+	switch(vpp) {
+		case 0: break;
+		case 33:
+		case 50:
+			if(vcc == vpp)
+				reg |= CSR2_VPP_VCC;
+			else
+				return 1;
+			break;
+		case 120:
+			if ((vcc == 33) || (vcc == 50))
+				reg |= CSR2_VPP_12;
+			else
+				return 1;
+		default: return 1;
+	}
+
+	/* first, turn off all power */
+	*((unsigned char *)MBX_CSR2_ADDR) &= ~(CSR2_VCC_MASK | CSR2_VPP_MASK);
+
+	/* enable new powersettings */
+	*((unsigned char *)MBX_CSR2_ADDR) |= reg;
+
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+#define hardware_enable(_slot_)  /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_MBX */
+
+/* ------------------------------------------------------------------------- */
+
+static void m8xx_shutdown(void)
+{
+	u_int m;
+	pcmcia_win_t *w;
+
+	
+	w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+
+
+		((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = 
+			M8XX_PCMCIA_MASK(_slot_); 
+		((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
+			&= ~M8XX_PCMCIA_MASK(_slot_);
+ 
+		/* turn off interrupt and disable CxOE */
+
+		M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE;
+
+		/* turn off memory windows */
+
+		for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+			w->or = 0;  /* set to not valid */
+			w++;
+		}
+
+		/* turn off voltage */
+
+		voltage_set(_slot_, 0, 0);
+
+		/* disable external hardware */
+	
+		hardware_disable(_slot_);
+
+	free_irq(pcmcia_schlvl, NULL);
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* ------------------------------------------------------------------------- */
+
+static u_int pending_events[PCMCIA_SOCKETS_NO];
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static void m8xx_pcmcia_bh(void *dummy)
+{
+	u_int events;
+	int i;
+
+	for (i=0; i < PCMCIA_SOCKETS_NO; i++) {
+		spin_lock_irq(&pending_event_lock);
+		events = pending_events[i];
+		pending_events[i] = 0;
+		spin_unlock_irq(&pending_event_lock);
+		/*
+		SS_DETECT events need a small delay here. The reason for this is that
+		the "is there a card" electronics need time to see the card after the
+		"we have a card coming in" electronics have seen it.
+		*/
+		if (events & SS_DETECT)
+			mdelay(4);
+		if (socket[i].handler)
+			socket[i].handler(socket[i].info, events);
+	}
+}
+
+static struct tq_struct m8xx_pcmcia_task = {
+	routine:	m8xx_pcmcia_bh
+};
+
+
+static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
+	socket_info_t *s;
+	event_table_t *e;
+	u_int events, pscr, pipr;
+
+	DEBUG(3,"Interrupt!\n");
+
+	/* get interrupt sources */
+
+	pscr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr;
+	pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
+
+	s = &socket[0];
+
+	    if(s->handler) {
+
+		    e = &s->events[0]; 
+		    events = 0;
+
+		    while(e->regbit) {
+			    if(pscr & e->regbit)
+				    events |= e->eventbit;
+		    
+			    e++;
+		    }
+
+		    /* 
+		     * report only if both card detect signals are the same 
+		     * not too nice done, 
+		     * we depend on that CD2 is the bit to the left of CD1...
+		     */
+
+		    if(events & SS_DETECT)
+			    if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1)
+				    ^ (pipr & M8XX_PCMCIA_CD1(_slot_)))
+				    events &= ~SS_DETECT;
+
+#ifdef PCMCIA_GLITCHY_CD
+		    
+		    /*
+		     * I've experienced CD problems with my ADS board.
+		     * We make an extra check to see if there was a
+		     * real change of Card detection.
+		     */
+
+		    if((events & SS_DETECT) && 
+		       ((pipr &
+			 (M8XX_PCMCIA_CD2(_slot_) | M8XX_PCMCIA_CD1(_slot_)))
+			== 0) && (s->state.Vcc | s->state.Vpp)) {
+			  events &= ~SS_DETECT;
+			  printk( "CD glitch workaround - CD = 0x%08x!\n",
+				(pipr & (M8XX_PCMCIA_CD2(_slot_) 
+					 | M8XX_PCMCIA_CD1(_slot_))));
+		    }
+#endif
+
+		    /* call the handler */
+
+		    DEBUG(3,"slot %u: events = 0x%02x, pscr = 0x%08x, "
+			  "pipr = 0x%08x\n", 
+			  _slot_, events, pscr, pipr);
+
+		    if(events) {
+			    spin_lock(&pending_event_lock);
+			    pending_events[0] |= events;
+			    spin_unlock(&pending_event_lock);
+			    schedule_task(&m8xx_pcmcia_task);
+		    }
+
+	    }
+
+
+    /* clear the interrupt sources */
+
+    ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
+    
+    DEBUG(3,"Interrupt done.\n");
+    
+}
+
+/* ------------------------------------------------------------------------- */
+
+static u_int m8xx_get_graycode(u_int size)
+{
+	u_int k;
+
+	for(k = 0; k < M8XX_SIZES_NO; k++)
+		if(m8xx_size_to_gray[k] == size)
+			break;
+
+	if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
+		k = -1;
+
+	return k;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static u_int m8xx_get_speed(u_int ns, u_int is_io)
+{
+	u_int reg, clocks, psst, psl, psht;
+
+	if(!ns) {
+
+		/*
+		 * We get called with IO maps setup to 0ns
+		 * if not specified by the user.
+		 * They should be 255ns.
+		 */
+
+		if(is_io)
+			ns = 255;
+		else 
+			ns = 100;  /* fast memory if 0 */
+	}
+
+	/* 
+	 * In PSST, PSL, PSHT fields we tell the controller
+	 * timing parameters in CLKOUT clock cycles.
+	 * CLKOUT is the same as GCLK2_50.
+	 */
+
+/* how we want to adjust the timing - in percent */
+
+#define ADJ 180 /* 80 % longer accesstime - to be sure */
+
+
+	clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
+	clocks = (clocks * ADJ) / (100*1000);
+	if(clocks >= PCMCIA_BMT_LIMIT) {
+		printk( "Max access time limit reached\n");
+		clocks = PCMCIA_BMT_LIMIT-1;
+	}
+
+	psst = clocks / 7;          /* setup time */
+	psht = clocks / 7;          /* hold time */
+	psl  = (clocks * 5) / 7;    /* strobe length */
+
+	psst += clocks - (psst + psht + psl);
+
+	reg =  psst << 12;
+	reg |= psl  << 7; 
+	reg |= psht << 16;
+
+	return reg;
+}
+
+/* ------------------------------------------------------------------------- */
+	
+static int m8xx_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
+{
+	socket[sock].handler = handler;
+	socket[sock].info = info;
+	if (handler == NULL) {
+		MOD_DEC_USE_COUNT;
+	} 
+	else {
+		MOD_INC_USE_COUNT;
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_get_status(unsigned int lsock, u_int *value)
+{
+	socket_info_t *s = &socket[lsock];
+	u_int pipr, reg;
+
+
+	pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
+
+	*value  = ((pipr & (M8XX_PCMCIA_CD1(_slot_) 
+			    | M8XX_PCMCIA_CD2(_slot_))) == 0) ? SS_DETECT : 0;
+	*value |= (pipr & M8XX_PCMCIA_WP(_slot_)) ? SS_WRPROT : 0;
+
+	if (s->state.flags & SS_IOCARD)
+		*value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_STSCHG : 0;
+	else {
+		*value |= (pipr & M8XX_PCMCIA_RDY(_slot_)) ? SS_READY : 0;
+		*value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_BATDEAD : 0;
+		*value |= (pipr & M8XX_PCMCIA_BVD2(_slot_)) ? SS_BATWARN : 0;
+	}
+	
+	if (s->state.Vcc | s->state.Vpp)
+		*value |= SS_POWERON;
+	
+	/*
+	 * Voltage detection:
+	 * This driver only supports 16-Bit pc-cards.
+	 * Cardbus is not handled here.
+	 * 
+	 * To determine what voltage to use we must read the VS1 and VS2 pin.
+	 * Depending on what socket type is present,
+	 * different combinations mean different things.
+	 *
+	 * Card Key  Socket Key   VS1   VS2   Card         Vcc for CIS parse
+	 *   
+	 * 5V        5V, LV*      NC    NC    5V only       5V (if available)
+	 *           
+	 * 5V        5V, LV*      GND   NC    5 or 3.3V     as low as possible
+	 *
+	 * 5V        5V, LV*      GND   GND   5, 3.3, x.xV  as low as possible
+	 *
+	 * LV*       5V            -     -    shall not fit into socket
+	 *
+	 * LV*       LV*          GND   NC    3.3V only     3.3V
+	 *
+	 * LV*       LV*          NC    GND   x.xV          x.xV (if avail.)
+	 *
+	 * LV*       LV*          GND   GND   3.3 or x.xV   as low as possible
+	 *
+	 * *LV means Low Voltage
+	 *
+	 *
+	 * That gives us the following table:
+	 *
+	 * Socket    VS1  VS2   Voltage
+	 *
+	 * 5V        NC   NC    5V
+	 * 5V        NC   GND   none (should not be possible)
+	 * 5V        GND  NC    >= 3.3V
+	 * 5V        GND  GND   >= x.xV 
+	 *
+	 * LV        NC   NC    5V   (if available)
+	 * LV        NC   GND   x.xV (if available)
+	 * LV        GND  NC    3.3V 
+	 * LV        GND  GND   >= x.xV 
+	 * 
+	 * So, how do I determine if I have a 5V or a LV
+	 * socket on my board?  Look at the socket!
+	 *
+	 * 
+	 * Socket with 5V key:
+	 * ++--------------------------------------------+
+	 * ||                                            |
+	 * ||                                           ||
+	 * ||                                           ||
+	 * |                                             |
+	 * +---------------------------------------------+
+	 *
+	 * Socket with LV key:
+	 * ++--------------------------------------------+
+	 * ||                                            |
+	 * |                                            ||
+	 * |                                            ||
+	 * |                                             |
+	 * +---------------------------------------------+
+	 *
+	 *
+	 * With other words - LV only cards does not fit
+	 * into the 5V socket!
+	 */
+
+	/* read out VS1 and VS2 */
+
+	reg = (pipr & M8XX_PCMCIA_VS_MASK(_slot_)) 
+		>> M8XX_PCMCIA_VS_SHIFT(_slot_);
+
+	if(socket_get(_slot_) == PCMCIA_SOCKET_KEY_LV) {
+		switch(reg) {
+		case 1: *value |= SS_3VCARD; break; /* GND, NC - 3.3V only */
+		case 2: *value |= SS_XVCARD; break; /* NC. GND - x.xV only */
+		};
+	}
+
+	DEBUG(3,"GetStatus(%d) = %#2.2x\n", lsock, *value);
+	return 0;
+}
+  
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_inquire_socket(unsigned int lsock, socket_cap_t *cap)
+{
+	*cap = capabilities;
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_get_socket(unsigned int lsock, socket_state_t *state)
+{
+	*state = socket[lsock].state; /* copy the whole structure */
+
+	DEBUG(3,"GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
+	      "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
+	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_set_socket(unsigned int lsock, socket_state_t *state)
+{
+	socket_info_t *s = &socket[lsock];
+	event_table_t *e;
+	u_int reg;
+	u_long flags;
+
+	DEBUG(3, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+	      "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
+	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+
+	/* First, set voltage - bail out if invalid */
+    
+	if(voltage_set(_slot_, state->Vcc, state->Vpp))
+		return -EINVAL;
+
+
+	/* Take care of reset... */
+
+	if(state->flags & SS_RESET) 
+		M8XX_PGCRX(_slot_) |=  M8XX_PGCRX_CXRESET; /* active high */
+	else
+		M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXRESET; 
+
+	/* ... and output enable. */
+
+	/* The CxOE signal is connected to a 74541 on the ADS.
+	   I guess most other boards used the ADS as a reference.
+	   I tried to control the CxOE signal with SS_OUTPUT_ENA,
+	   but the reset signal seems connected via the 541. 
+	   If the CxOE is left high are some signals tristated and
+	   no pullups are present -> the cards act wierd.
+	   So right now the buffers are enabled if the power is on. */
+
+	if(state->Vcc || state->Vpp)
+		M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXOE; /* active low */
+	else
+		M8XX_PGCRX(_slot_) |=  M8XX_PGCRX_CXOE;
+	
+	/* 
+	 * We'd better turn off interrupts before 
+	 * we mess with the events-table..
+	 */
+
+	save_flags(flags);
+	cli();
+
+	/*
+	 * Play around with the interrupt mask to be able to
+	 * give the events the generic pcmcia driver wants us to.
+	 */
+
+	e = &s->events[0]; 
+	reg = 0;
+
+	if(state->csc_mask & SS_DETECT) {
+		e->eventbit = SS_DETECT;
+		reg |= e->regbit = (M8XX_PCMCIA_CD2(_slot_) 
+				    | M8XX_PCMCIA_CD1(_slot_));
+		e++;
+	}
+
+	if(state->flags & SS_IOCARD) {
+
+		/* 
+		 * I/O card
+		 */
+
+		if(state->csc_mask & SS_STSCHG) {
+			e->eventbit = SS_STSCHG;
+			reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
+			e++;
+		}
+		
+
+		/*
+		 * If io_irq is non-zero we should enable irq.
+		 */
+
+		if(state->io_irq) {
+			M8XX_PGCRX(_slot_) |= 
+				mk_int_int_mask(state->io_irq) << 24;
+
+			/*
+			 * Strange thing here:
+			 * The manual does not tell us which interrupt
+			 * the sources generate.
+			 * Anyhow, I found out that RDY_L generates IREQLVL.
+			 *
+			 * We use level triggerd interrupts, and they don't
+			 * have to be cleared in PSCR in the interrupt handler.
+			 */
+
+			reg |= M8XX_PCMCIA_RDY_L(_slot_);  
+		}
+		else
+			M8XX_PGCRX(_slot_) &= 0x00ffffff;
+		
+	}
+	else {
+		
+		/*
+		 * Memory card
+		 */
+		
+		if(state->csc_mask & SS_BATDEAD) {
+			e->eventbit = SS_BATDEAD;
+			reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
+			e++;
+		}
+		
+		if(state->csc_mask & SS_BATWARN) {
+			e->eventbit = SS_BATWARN;
+			reg |= e->regbit = M8XX_PCMCIA_BVD2(_slot_);
+			e++;
+		}
+		
+		/* What should I trigger on - low/high,raise,fall? */
+		if(state->csc_mask & SS_READY) {
+			e->eventbit = SS_READY;
+			reg |= e->regbit = 0; //??
+			e++;
+		}
+	}
+	
+	e->regbit = 0;  /* terminate list */
+	
+	/* 
+	 * Clear the status changed .
+	 * Port A and Port B share the same port.
+	 * Writing ones will clear the bits.
+	 */
+	
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = reg;
+	
+	/*
+	 * Write the mask.
+	 * Port A and Port B share the same port.
+	 * Need for read-modify-write. 
+	 * Ones will enable the interrupt.
+	 */
+
+	reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
+		& M8XX_PCMCIA_MASK(_slot_);
+	
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per = reg;
+	
+	restore_flags(flags);
+
+	/* copy the struct and modify the copy */
+	
+	s->state = *state;
+	
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_get_io_map(unsigned int lsock, struct pccard_io_map *io)
+{
+	if(io->map >= PCMCIA_IO_WIN_NO)
+		return -EINVAL;
+
+	*io = socket[lsock].io_win[io->map]; /* copy the struct */
+
+	DEBUG(3,"GetIOMap(%d, %d) = %#2.2x, %d ns, "
+	      "%#4.4x-%#4.4x\n", lsock, io->map, io->flags,
+	      io->speed, io->start, io->stop);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_set_io_map(unsigned int lsock, struct pccard_io_map *io)
+{
+	socket_info_t *s = &socket[lsock];
+	pcmcia_win_t *w;
+	u_int reg, winnr;
+	
+
+#define M8XX_SIZE (io->stop - io->start + 1)   
+#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
+
+	DEBUG(3, "SetIOMap(%d, %d, %#2.2x, %d ns, "
+	      "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
+	      io->speed, io->start, io->stop);
+
+	if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff) 
+	    || (io->stop > 0xffff) || (io->stop < io->start)) 
+		return -EINVAL;
+	
+	if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
+		return -EINVAL;
+
+	if(io->flags & MAP_ACTIVE) {
+
+		winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO) 
+			+ (lsock * PCMCIA_IO_WIN_NO) + io->map;
+	
+		/* setup registers */
+
+		w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+		w += winnr;
+	
+		w->or = 0; /* turn off window first */
+		w->br = M8XX_BASE;
+	
+		reg <<= 27;     
+  		reg |= 0x00018 + (_slot_ << 2);
+
+		reg |= m8xx_get_speed(io->speed, 1);
+
+		if(io->flags & MAP_WRPROT) 
+			reg |= 0x00000002;
+		
+		if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
+			reg |= 0x00000040;
+	
+		if(io->flags & MAP_ACTIVE) 
+			reg |= 0x00000001;
+	
+		w->or = reg;
+
+		DEBUG(3,"Socket %u: Mapped io window %u at %#8.8x, "
+		      "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+	}
+
+
+	/* copy the struct and modify the copy */
+	
+	s->io_win[io->map] = *io; 
+	s->io_win[io->map].flags &= (MAP_WRPROT 
+				     | MAP_16BIT
+				     | MAP_ACTIVE);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
+{
+	if(mem->map >= PCMCIA_MEM_WIN_NO)
+		return -EINVAL;
+	
+	*mem = socket[lsock].mem_win[mem->map]; /* copy the struct */
+	
+	DEBUG(3, "GetMemMap(%d, %d) = %#2.2x, %d ns, "
+	      "%#5.5lx-%#5.5lx, %#5.5x\n", lsock, mem->map, mem->flags,
+	      mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
+{
+	socket_info_t *s = &socket[lsock];
+	pcmcia_win_t *w;
+	struct pccard_mem_map *old;
+	u_int reg, winnr;
+	
+	DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
+	      "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+	      mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
+
+	if ((mem->map >= PCMCIA_MEM_WIN_NO) || (mem->sys_start > mem->sys_stop)
+	    || ((mem->sys_stop - mem->sys_start) >= PCMCIA_MEM_WIN_SIZE)
+	    || (mem->card_start >= 0x04000000) 
+	    || (mem->sys_start & 0xfff)                /* 4KByte resolution */
+	    || (mem->card_start & 0xfff))                   
+		return -EINVAL;
+	
+	if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
+		printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
+		return -EINVAL;
+	}
+
+	winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
+	
+	/* Setup the window in the pcmcia controller */
+	
+	w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+	w += winnr;
+	
+	reg <<= 27;
+	reg |= _slot_ << 2;
+	
+	reg |= m8xx_get_speed(mem->speed, 0);
+
+	if(mem->flags & MAP_ATTRIB) 
+		reg |= 0x00000010;
+	
+	if(mem->flags & MAP_WRPROT) 
+		reg |= 0x00000002;
+	
+	if(mem->flags & MAP_16BIT) 
+		reg |= 0x00000040;
+	
+	if(mem->flags & MAP_ACTIVE) 
+		reg |= 0x00000001;
+	
+	w->or = reg;
+
+	DEBUG(3, "Socket %u: Mapped memory window %u at %#8.8x, "
+	      "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
+
+	if(mem->flags & MAP_ACTIVE) {
+
+		mem->sys_stop -= mem->sys_start;
+
+		/* get the new base address */
+		
+		mem->sys_start = PCMCIA_MEM_WIN_BASE + 
+			(PCMCIA_MEM_WIN_SIZE * winnr)
+			+ mem->card_start; 
+
+		mem->sys_stop += mem->sys_start;
+	}
+
+DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
+	      "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+	      mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
+
+	/* copy the struct and modify the copy */
+	
+	old = &s->mem_win[mem->map];
+	
+	*old = *mem;
+	old->flags &= (MAP_ATTRIB
+		       | MAP_WRPROT 
+		       | MAP_16BIT
+		       | MAP_ACTIVE);
+
+	return 0;
+}
+
+static int m8xx_sock_init(unsigned int s)
+{
+	int i;
+	pccard_io_map io = { 0, 0, 0, 0, 1 };
+	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
+
+	DEBUG(3, "sock_init(%d)\n", s);
+
+	mem.sys_stop = 0x1000;
+	m8xx_set_socket(s, &dead_socket);
+	for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
+		io.map = i;
+		m8xx_set_io_map(s, &io);
+	}
+	for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
+		mem.map = i;
+		m8xx_set_mem_map(s, &mem);
+	}
+
+	return 0;
+		
+}
+
+static int m8xx_suspend(unsigned int s)
+{
+		return(m8xx_set_socket(s, &dead_socket));
+}
+static void m8xx_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+{
+}
+/* ------------------------------------------------------------------------- */
+    
+static struct pccard_operations m8xx_services = {
+	&m8xx_sock_init,	
+	&m8xx_suspend,
+	&m8xx_register_callback,
+	&m8xx_inquire_socket,
+	&m8xx_get_status,
+	&m8xx_get_socket,
+	&m8xx_set_socket,
+	&m8xx_get_io_map,
+	&m8xx_set_io_map,
+	&m8xx_get_mem_map,
+	&m8xx_set_mem_map,
+	&m8xx_proc_setup
+};
+
+static int __init m8xx_init(void)
+{
+	servinfo_t serv;
+	pcmcia_win_t *w;
+	u_int m;
+
+	PCMCIA_INFO("%s\n", version);
+	CardServices(GetCardServicesInfo, &serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		PCMCIA_ERROR("Card Services release does not match!\n");
+		return -1;
+	}
+
+	PCMCIA_INFO(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG 
+		    " with IRQ %u.\n", pcmcia_schlvl); 
+
+	/* Configure Status change interrupt */
+
+	if(request_8xxirq(pcmcia_schlvl, m8xx_interrupt, 0, 
+			   "m8xx_pcmcia", NULL)) {
+		PCMCIA_ERROR("Cannot allocate IRQ %u for SCHLVL!\n", 
+			     pcmcia_schlvl);
+		return -1;
+	}
+
+
+	w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+
+	socket[0].slot = _slot_;
+	    
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = 
+		M8XX_PCMCIA_MASK(_slot_); 
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
+		&= ~M8XX_PCMCIA_MASK(_slot_);
+ 
+/* connect interrupt and disable CxOE */
+
+	M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE |
+		(mk_int_int_mask(pcmcia_schlvl) << 16);
+
+/* intialize the fixed memory windows */
+
+	for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+		w->br = PCMCIA_MEM_WIN_BASE + 
+			(PCMCIA_MEM_WIN_SIZE 
+			 * (m + 0 * PCMCIA_MEM_WIN_NO));
+
+		w->or = 0;  /* set to not valid */
+
+		DEBUG(3,"Socket %u: MemWin %u: Base 0x%08x.\n",
+		      0, m, w->br);
+
+		w++;
+	}
+
+/* turn off voltage */
+	voltage_set(_slot_, 0, 0);
+
+/* Enable external hardware */
+	hardware_enable(_slot_);
+
+	if(register_ss_entry(PCMCIA_SOCKETS_NO, &m8xx_services) != 0) {
+	    PCMCIA_ERROR("register_ss_entry() failed.\n");
+	    m8xx_shutdown();
+	    return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __exit m8xx_exit(void)
+{
+	unregister_ss_entry(&m8xx_services);
+
+	m8xx_shutdown();
+}
+
+module_init(m8xx_init);
+module_exit(m8xx_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/pci_socket.h linux/drivers/pcmcia/pci_socket.h
--- linux.orig/drivers/pcmcia/pci_socket.h	2000-11-17 00:38:16.000000000 +0000
+++ linux/drivers/pcmcia/pci_socket.h	2002-07-20 01:08:28.000000000 +0000
@@ -23,7 +23,9 @@
 	struct socket_info_t *pcmcia_socket;
 	struct tq_struct tq_task;
 	struct timer_list poll_timer;
-
+	/* Zoom video behaviour is so chip specific its not worth adding
+  	   this to _ops */
+	void (*zoom_video)(struct pci_socket *, int);
 	/* A few words of private data for the low-level driver.. */
 	unsigned int private[8];
 } pci_socket_t;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/ricoh.h linux/drivers/pcmcia/ricoh.h
--- linux.orig/drivers/pcmcia/ricoh.h	2001-02-17 00:02:36.000000000 +0000
+++ linux/drivers/pcmcia/ricoh.h	2002-07-20 01:08:35.000000000 +0000
@@ -110,6 +110,8 @@
 #define  RL5C4XX_CMD_SHIFT		4
 #define  RL5C4XX_HOLD_MASK		0x1c00
 #define  RL5C4XX_HOLD_SHIFT		10
+#define  RL5C4XX_MISC_CONTROL           0x2F /* 8 bit */
+#define  RL5C4XX_ZV_ENABLE              0x08
 
 #ifdef __YENTA_H
 
@@ -134,14 +136,45 @@
 	return 0;
 }
 
+static void ricoh_zoom_video(pci_socket_t *socket, int onoff)
+{
+        u8 reg;
+
+        reg = exca_readb(socket, RL5C4XX_MISC_CONTROL);
+        if (onoff)
+                /* Zoom zoom, we will all go together, zoom zoom, zoom zoom */
+                reg |=  RL5C4XX_ZV_ENABLE;
+        else
+                reg &= ~RL5C4XX_ZV_ENABLE;
+	
+        exca_writeb(socket, RL5C4XX_MISC_CONTROL, reg);
+}
+
+static void ricoh_set_zv(pci_socket_t *socket)
+{
+        if(socket->dev->vendor == PCI_VENDOR_ID_RICOH)
+        {
+                switch(socket->dev->device)
+                {
+                        /* There may be more .. */
+		case  PCI_DEVICE_ID_RICOH_RL5C478:
+			socket->zoom_video = ricoh_zoom_video;
+			break;  
+                }
+        }
+}
+
+
 static int ricoh_init(pci_socket_t *socket)
 {
 	yenta_init(socket);
+	ricoh_set_zv(socket);
 
 	config_writew(socket, RL5C4XX_MISC, rl_misc(socket));
 	config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket));
 	config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket));
 	config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket));
+
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100.h linux/drivers/pcmcia/sa1100.h
--- linux.orig/drivers/pcmcia/sa1100.h	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100.h	2002-07-20 01:08:23.000000000 +0000
@@ -38,9 +38,7 @@
 #include <pcmcia/bulkmem.h>
 #include <pcmcia/cistpl.h>
 #include "cs_internal.h"
-
-#include <asm/arch/pcmcia.h>
-
+#include "sa1100_generic.h"
 
 /* MECR: Expansion Memory Configuration Register
  * (SA-1100 Developers Manual, p.10-13; SA-1110 Developers Manual, p.10-24)
@@ -157,15 +155,24 @@
  * use when responding to a Card Services query of some kind.
  */
 struct sa1100_pcmcia_socket {
+  /*
+   * Core PCMCIA state
+   */
   socket_state_t        cs_state;
-  struct pcmcia_state   k_state;
-  unsigned int          irq;
-  void                  (*handler)(void *, unsigned int);
-  void                  *handler_info;
   pccard_io_map         io_map[MAX_IO_WIN];
   pccard_mem_map        mem_map[MAX_WIN];
-  ioaddr_t              virt_io, phys_attr, phys_mem;
+  void                  (*handler)(void *, unsigned int);
+  void                  *handler_info;
+
+  struct pcmcia_state   k_state;
+  ioaddr_t              phys_attr, phys_mem;
+  void			*virt_io;
   unsigned short        speed_io, speed_attr, speed_mem;
+
+  /*
+   * Info from low level handler
+   */
+  unsigned int          irq;
 };
 
 
@@ -189,6 +196,7 @@
 extern struct pcmcia_low_level gcplus_pcmcia_ops;
 extern struct pcmcia_low_level xp860_pcmcia_ops;
 extern struct pcmcia_low_level yopy_pcmcia_ops;
+extern struct pcmcia_low_level shannon_pcmcia_ops;
 extern struct pcmcia_low_level pangolin_pcmcia_ops;
 extern struct pcmcia_low_level freebird_pcmcia_ops;
 extern struct pcmcia_low_level pfs168_pcmcia_ops;
@@ -198,5 +206,6 @@
 extern struct pcmcia_low_level graphicsmaster_pcmcia_ops;
 extern struct pcmcia_low_level adsbitsy_pcmcia_ops;
 extern struct pcmcia_low_level stork_pcmcia_ops;
+extern struct pcmcia_low_level badge4_pcmcia_ops;
 
 #endif  /* !defined(_PCMCIA_SA1100_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_adsbitsy.c linux/drivers/pcmcia/sa1100_adsbitsy.c
--- linux.orig/drivers/pcmcia/sa1100_adsbitsy.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_adsbitsy.c	2002-07-20 01:08:40.000000000 +0000
@@ -12,205 +12,83 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
-#include <asm/delay.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+
+#include "sa1100_generic.h"
+#include "sa1111_generic.h"
 
 static int adsbitsy_pcmcia_init(struct pcmcia_init *init)
 {
-  int return_val=0;
-
   /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
   PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
 
   /* Disable Power 3.3V/5V for PCMCIA/CF */
   PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
 
-  INTPOL1 |= (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
-			 (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
-    		 (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-    		 (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-    		 (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-    		 (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
-
-  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
-			  "GC Master PCMCIA (0) CD", NULL);
-  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
-			  "GC Master CF (1) CD", NULL);
-  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "GC Master PCMCIA (0) BVD1", NULL);
-  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "GC Master CF (1) BVD1", NULL);
-
+  /* Why? */			 
   MECR = 0x09430943;
 
-  return (return_val<0) ? -1 : 2;
-}
-
-static int adsbitsy_pcmcia_shutdown(void)
-{
-
-  free_irq(S0_CD_VALID, NULL);
-  free_irq(S1_CD_VALID, NULL);
-  free_irq(S0_BVD1_STSCHG, NULL);
-  free_irq(S1_BVD1_STSCHG, NULL);
-
-  INTPOL1 &= ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-			   (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-      		   (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-      		   (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
-
-  return 0;
-}
-
-static int adsbitsy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
-{
-  unsigned long status;
-  int return_val=1;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0,
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  status=PCSR;
-
-  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
-
-  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
-
-  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
-
-  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
-
-  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
-
-  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
-
-  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
-
-  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
-
-  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
-
-  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
-
-  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
-
-  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
-
-  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
-
-  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
-
-  return return_val;
-}
-
-static int adsbitsy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-
-  switch(info->sock){
-  case 0:
-    info->irq=S0_READY_NINT;
-    break;
-
-  case 1:
-    info->irq=S1_READY_NINT;
-    break;
-
-  default:
-    return -1;
-  }
-
-  return 0;
+  return sa1111_pcmcia_init(init);
 }
 
-static int adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int
+adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *conf)
 {
-  unsigned long pccr=PCCR, gpio=PA_DWR;
+  unsigned int pa_dwr_mask, pa_dwr_set;
+  int ret;
 
-  switch(configure->sock){
+  switch (conf->sock) {
   case 0:
+    pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
 
-    switch(configure->vcc){
-    case 0:
-      pccr = (pccr & ~PCCR_S0_FLT);
-      gpio |= GPIO_GPIO0 | GPIO_GPIO1;
-      break;
-
-    case 33:
-      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
-      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
-	  gpio &= ~GPIO_GPIO0;
-      break;
-
-    case 50:
-      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
-      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
-	  gpio |= GPIO_GPIO0;
-      break;
-
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
+    case 0:	pa_dwr_set = GPIO_GPIO0 | GPIO_GPIO1;	break;
+    case 33:	pa_dwr_set = GPIO_GPIO1;		break;
+    case 50:	pa_dwr_set = GPIO_GPIO0;		break;
     }
-
-    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
-
     break;
 
   case 1:
-    switch(configure->vcc){
-    case 0:
-      pccr = (pccr & ~PCCR_S1_FLT);
-      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
-      break;
-
-    case 33:
-      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
-      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
-	  gpio |= GPIO_GPIO2;
-      break;
-
-    case 50:
-      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
-      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
-	  gpio |= GPIO_GPIO3;
-      break;
+    pa_dwr_mask = GPIO_GPIO2 | GPIO_GPIO3;
 
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
+    case 0:	pa_dwr_set = 0;				break;
+    case 33:	pa_dwr_set = GPIO_GPIO2;		break;
+    case 50:	pa_dwr_set = GPIO_GPIO3;		break;
     }
 
-    if(configure->vpp!=configure->vcc && configure->vpp!=0){
-      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
-	     configure->vpp);
-      return -1;
-    }
-
-    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
-
-    break;
-
   default:
     return -1;
   }
 
-  PCCR = pccr;
-  PA_DWR = gpio;
+  if (conf->vpp != conf->vcc && conf->vpp != 0) {
+    printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
+		__FUNCTION__, conf->vpp);
+    return -1;
+  }
 
-  return 0;
+  ret = sa1111_pcmcia_configure_socket(conf);
+  if (ret == 0) {
+    unsigned long flags;
+
+    local_irq_save(flags);
+    PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
+    local_irq_restore(flags);
+  }
+
+  return ret;
 }
 
 struct pcmcia_low_level adsbitsy_pcmcia_ops = {
-  adsbitsy_pcmcia_init,
-  adsbitsy_pcmcia_shutdown,
-  adsbitsy_pcmcia_socket_state,
-  adsbitsy_pcmcia_get_irq_info,
-  adsbitsy_pcmcia_configure_socket
+  init:			adsbitsy_pcmcia_init,
+  shutdown:		sa1111_pcmcia_shutdown,
+  socket_state:		sa1111_pcmcia_socket_state,
+  get_irq_info:		sa1111_pcmcia_get_irq_info,
+  configure_socket:	adsbitsy_pcmcia_configure_socket,
+
+  socket_init:		sa1111_pcmcia_socket_init,
+  socket_suspend:	sa1111_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_assabet.c linux/drivers/pcmcia/sa1100_assabet.c
--- linux.orig/drivers/pcmcia/sa1100_assabet.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_assabet.c	2002-07-20 01:08:29.000000000 +0000
@@ -9,141 +9,194 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
 #include <asm/arch/assabet.h>
 
-static int assabet_pcmcia_init(struct pcmcia_init *init){
-  int irq, res;
+#include "sa1100_generic.h"
 
-  /* Enable CF bus: */
-  ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF);
-
-  /* All those are inputs */
-  GPDR &= ~(ASSABET_GPIO_CF_CD | ASSABET_GPIO_CF_BVD2 | ASSABET_GPIO_CF_BVD1 | ASSABET_GPIO_CF_IRQ);
-
-  /* Set transition detect */
-  set_GPIO_IRQ_edge( ASSABET_GPIO_CF_CD|ASSABET_GPIO_CF_BVD2|ASSABET_GPIO_CF_BVD1, GPIO_BOTH_EDGES );
-  set_GPIO_IRQ_edge( ASSABET_GPIO_CF_IRQ, GPIO_FALLING_EDGE );
-
-  /* Register interrupts */
-  irq = ASSABET_IRQ_GPIO_CF_CD;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
-  if( res < 0 ) goto irq_err;
-  irq = ASSABET_IRQ_GPIO_CF_BVD2;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
-  if( res < 0 ) goto irq_err;
-  irq = ASSABET_IRQ_GPIO_CF_BVD1;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
-  if( res < 0 ) goto irq_err;
-
-  /* There's only one slot, but it's "Slot 1": */
-  return 2;
-
-irq_err:
-  printk( KERN_ERR "%s: Request for IRQ %u failed\n", __FUNCTION__, irq );
-  return -1;
-}
+static struct irqs {
+	int irq;
+	unsigned int gpio;
+	const char *str;
+} irqs[] = {
+	{ ASSABET_IRQ_GPIO_CF_CD,   ASSABET_GPIO_CF_CD,   "CF_CD"   },
+	{ ASSABET_IRQ_GPIO_CF_BVD2, ASSABET_GPIO_CF_BVD2, "CF_BVD2" },
+	{ ASSABET_IRQ_GPIO_CF_BVD1, ASSABET_GPIO_CF_BVD1, "CF_BVD1" },
+};
 
-static int assabet_pcmcia_shutdown(void)
+static int assabet_pcmcia_init(struct pcmcia_init *init)
 {
-  /* disable IRQs */
-  free_irq( ASSABET_IRQ_GPIO_CF_CD, NULL );
-  free_irq( ASSABET_IRQ_GPIO_CF_BVD2, NULL );
-  free_irq( ASSABET_IRQ_GPIO_CF_BVD1, NULL );
-  
-  /* Disable CF bus: */
-  ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF);
+	int i, res;
 
-  return 0;
-}
+	/* Set transition detect */
+	set_GPIO_IRQ_edge(ASSABET_GPIO_CF_IRQ, GPIO_FALLING_EDGE);
 
-static int assabet_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
+	/* Register interrupts */
+	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
+		set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
+		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+				  irqs[i].str, NULL);
+		if (res)
+			goto irq_err;
+	}
+
+	/* There's only one slot, but it's "Slot 1": */
+	return 2;
+
+ irq_err:
+	printk(KERN_ERR "%s: request for IRQ%d failed\n",
+		__FUNCTION__, irqs[i].irq);
 
-  if(state_array->size<2) return -1;
+	while (i--)
+		free_irq(irqs[i].irq, NULL);
 
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels=GPLR;
-
-  state_array->state[1].detect=((levels & ASSABET_GPIO_CF_CD)==0)?1:0;
+	return -1;
+}
 
-  state_array->state[1].ready=(levels & ASSABET_GPIO_CF_IRQ)?1:0;
+/*
+ * Release all resources.
+ */
+static int assabet_pcmcia_shutdown(void)
+{
+	int i;
 
-  state_array->state[1].bvd1=(levels & ASSABET_GPIO_CF_BVD1)?1:0;
+	for (i = 0; i < ARRAY_SIZE(irqs); i++)
+		free_irq(irqs[i].irq, NULL);
+  
+	return 0;
+}
 
-  state_array->state[1].bvd2=(levels & ASSABET_GPIO_CF_BVD2)?1:0;
+static int
+assabet_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+	unsigned long levels;
 
-  state_array->state[1].wrprot=0; /* Not available on Assabet. */
+	if (state_array->size < 2)
+		return -1;
 
-  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
+	levels = GPLR;
 
-  state_array->state[1].vs_Xv=0;
+	state_array->state[1].detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
+	state_array->state[1].ready  = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
+	state_array->state[1].bvd1   = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
+	state_array->state[1].bvd2   = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
+	state_array->state[1].wrprot = 0; /* Not available on Assabet. */
+	state_array->state[1].vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
+	state_array->state[1].vs_Xv  = 0;
 
-  return 1;
+	return 1;
 }
 
-static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  if(info->sock>1) return -1;
+static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+	if (info->sock > 1)
+		return -1;
 
-  if(info->sock==1)
-    info->irq=ASSABET_IRQ_GPIO_CF_IRQ;
+	if (info->sock == 1)
+		info->irq = ASSABET_IRQ_GPIO_CF_IRQ;
 
-  return 0;
+	return 0;
 }
 
-static int assabet_pcmcia_configure_socket(const struct pcmcia_configure
-					   *configure)
+static int
+assabet_pcmcia_configure_socket(const struct pcmcia_configure *configure)
 {
-  unsigned long value, flags;
-
-  if(configure->sock>1) return -1;
-
-  if(configure->sock==0) return 0;
+	unsigned int mask;
 
-  save_flags_cli(flags);
+	if (configure->sock > 1)
+		return -1;
 
-  value = BCR_value;
+	if (configure->sock == 0)
+		return 0;
 
-  switch(configure->vcc){
-  case 0:
-    value &= ~ASSABET_BCR_CF_PWR;
-    break;
+	switch (configure->vcc) {
+	case 0:
+		mask = 0;
+		break;
+
+	case 50:
+		printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+			__FUNCTION__);
+
+	case 33:  /* Can only apply 3.3V to the CF slot. */
+		mask = ASSABET_BCR_CF_PWR;
+		break;
+
+	default:
+		printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+			configure->vcc);
+		return -1;
+	}
+
+	/* Silently ignore Vpp, output enable, speaker enable. */
+
+	if (configure->reset)
+		mask |= ASSABET_BCR_CF_RST;
+
+	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask);
+
+	/*
+	 * Handle suspend mode properly.  This prevents a
+	 * flood of IRQs from the CF device.
+	 */
+	if (configure->irq)
+		enable_irq(ASSABET_IRQ_GPIO_CF_IRQ);
+	else
+		disable_irq(ASSABET_IRQ_GPIO_CF_IRQ);
 
-  case 50:
-    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
-	   __FUNCTION__);
-
-  case 33:  /* Can only apply 3.3V to the CF slot. */
-    value |= ASSABET_BCR_CF_PWR;
-    break;
+	return 0;
+}
 
-  default:
-    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	   configure->vcc);
-    restore_flags(flags);
-    return -1;
-  }
+/*
+ * Enable card status IRQs on (re-)initialisation.  This can
+ * be called at initialisation, power management event, or
+ * pcmcia event.
+ */
+static int assabet_pcmcia_socket_init(int sock)
+{
+	int i;
 
-  value = (configure->reset) ? (value | ASSABET_BCR_CF_RST) : (value & ~ASSABET_BCR_CF_RST);
+	if (sock == 1) {
+		/*
+		 * Enable CF bus
+		 */
+		ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF);
+
+		for (i = 0; i < ARRAY_SIZE(irqs); i++)
+			set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
+	}
 
-  /* Silently ignore Vpp, output enable, speaker enable. */
+	return 0;
+}
 
-  ASSABET_BCR = BCR_value = value;
+/*
+ * Disable card status IRQs on suspend.
+ */
+static int assabet_pcmcia_socket_suspend(int sock)
+{
+	int i;
 
-  restore_flags(flags);
+	if (sock == 1) {
+		for (i = 0; i < ARRAY_SIZE(irqs); i++)
+			set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
+
+		/*
+		 * Tristate the CF bus signals.  Also assert CF
+		 * reset as per user guide page 4-11.
+		 */
+		ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST);
+	}
 
-  return 0;
+	return 0;
 }
 
 struct pcmcia_low_level assabet_pcmcia_ops = { 
-  assabet_pcmcia_init,
-  assabet_pcmcia_shutdown,
-  assabet_pcmcia_socket_state,
-  assabet_pcmcia_get_irq_info,
-  assabet_pcmcia_configure_socket
+	init:			assabet_pcmcia_init,
+	shutdown:		assabet_pcmcia_shutdown,
+	socket_state:		assabet_pcmcia_socket_state,
+	get_irq_info:		assabet_pcmcia_get_irq_info,
+	configure_socket:	assabet_pcmcia_configure_socket,
+
+	socket_init:		assabet_pcmcia_socket_init,
+	socket_suspend:		assabet_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_badge4.c linux/drivers/pcmcia/sa1100_badge4.c
--- linux.orig/drivers/pcmcia/sa1100_badge4.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_badge4.c	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,172 @@
+/*
+ * linux/drivers/pcmcia/sa1100_badge4.c
+ *
+ * BadgePAD 4 PCMCIA specific routines
+ *
+ *   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/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/badge4.h>
+#include <asm/hardware/sa1111.h>
+
+#include "sa1100_generic.h"
+#include "sa1111_generic.h"
+
+/*
+ * BadgePAD 4 Details
+ *
+ * PCM Vcc:
+ *
+ *  PCM Vcc on BadgePAD 4 can be jumpered for 3.3V (short pins 1 and 3
+ *  on JP6) or 5V (short pins 3 and 5 on JP6).  N.B., 5V supply rail
+ *  is enabled by the SA-1110's BADGE4_GPIO_PCMEN5V (GPIO 24).
+ *
+ * PCM Vpp:
+ *
+ *  PCM Vpp on BadgePAD 4 can be jumpered for 12V (short pins 2 and 4
+ *  on JP6) or tied to PCM Vcc (short pins 4 and 6 on JP6).  N.B., 12V
+ *  operation requires that the power supply actually supply 12V.
+ *
+ * CF Vcc:
+ *
+ *  CF Vcc on BadgePAD 4 can be jumpered either for 3.3V (short pins 1
+ *  and 2 on JP10) or 5V (short pins 2 and 3 on JP10).  The note above
+ *  about the 5V supply rail applies.
+ *
+ * There's no way programmatically to determine how a given board is
+ * jumpered.  This code assumes a default jumpering: 5V PCM Vcc (pins
+ * 3 and 5 shorted) and PCM Vpp = PCM Vcc (pins 4 and 6 shorted) and
+ * no jumpering for CF Vcc.  If this isn't correct, Override these
+ * defaults with a pcmv setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf
+ * vcc>.  E.g. pcmv=33,120,50 indicates 3.3V PCM Vcc, 12.0V PCM Vpp,
+ * and 5.0V CF Vcc.
+ *
+ */
+
+static int badge4_pcmvcc = 50;
+static int badge4_pcmvpp = 50;
+static int badge4_cfvcc = 0;
+
+static int badge4_pcmcia_init(struct pcmcia_init *init)
+{
+	printk(KERN_INFO __FUNCTION__
+	       ": badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n",
+	       badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
+
+	return sa1111_pcmcia_init(init);
+}
+
+static int badge4_pcmcia_shutdown(void)
+{
+	int rc = sa1111_pcmcia_shutdown();
+
+	/* be sure to disable 5V use */
+	badge4_set_5V(BADGE4_5V_PCMCIA_SOCK0, 0);
+	badge4_set_5V(BADGE4_5V_PCMCIA_SOCK1, 0);
+
+	return rc;
+}
+
+static void complain_about_jumpering(const char *whom,
+				     const char *supply,
+				     int given, int wanted)
+{
+	printk(KERN_ERR
+	 "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation"
+	 "; re-jumper the board and/or use pcmv=xx,xx,xx\n",
+	       whom, supply,
+	       wanted / 10, wanted % 10,
+	       supply,
+	       given / 10, given % 10);
+}
+
+static unsigned badge4_need_5V_bitmap = 0;
+
+static int
+badge4_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+{
+	int ret;
+
+	switch (conf->sock) {
+	case 0:
+		if ((conf->vcc != 0) &&
+		    (conf->vcc != badge4_pcmvcc)) {
+			complain_about_jumpering(__FUNCTION__, "pcmvcc",
+						 badge4_pcmvcc, conf->vcc);
+			return -1;
+		}
+		if ((conf->vpp != 0) &&
+		    (conf->vpp != badge4_pcmvpp)) {
+			complain_about_jumpering(__FUNCTION__, "pcmvpp",
+						 badge4_pcmvpp, conf->vpp);
+			return -1;
+		}
+		break;
+
+	case 1:
+		if ((conf->vcc != 0) &&
+		    (conf->vcc != badge4_cfvcc)) {
+			complain_about_jumpering(__FUNCTION__, "cfvcc",
+						 badge4_cfvcc, conf->vcc);
+			return -1;
+		}
+		break;
+
+	default:
+		return -1;
+	}
+
+	ret = sa1111_pcmcia_configure_socket(conf);
+	if (ret == 0) {
+		unsigned long flags;
+		int need5V;
+
+		local_irq_save(flags);
+
+		need5V = ((conf->vcc == 50) || (conf->vpp == 50));
+
+		badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(conf->sock), need5V);
+
+		local_irq_restore(flags);
+	}
+
+	return 0;
+}
+
+struct pcmcia_low_level badge4_pcmcia_ops = {
+	init:			badge4_pcmcia_init,
+	shutdown:		badge4_pcmcia_shutdown,
+	socket_state:		sa1111_pcmcia_socket_state,
+	get_irq_info:		sa1111_pcmcia_get_irq_info,
+	configure_socket:	badge4_pcmcia_configure_socket,
+
+	socket_init:		sa1111_pcmcia_socket_init,
+	socket_suspend:		sa1111_pcmcia_socket_suspend,
+};
+
+
+static int __init pcmv_setup(char *s)
+{
+	int v[4];
+
+	s = get_options(s, ARRAY_SIZE(v), v);
+
+	if (v[0] >= 1) badge4_pcmvcc = v[1];
+	if (v[0] >= 2) badge4_pcmvpp = v[2];
+	if (v[0] >= 3) badge4_cfvcc = v[3];
+
+	return 1;
+}
+
+__setup("pcmv=", pcmv_setup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_cerf.c linux/drivers/pcmcia/sa1100_cerf.c
--- linux.orig/drivers/pcmcia/sa1100_cerf.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_cerf.c	2002-07-20 01:08:39.000000000 +0000
@@ -10,40 +10,55 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
 
+#ifdef CONFIG_SA1100_CERF_CPLD
+#define CERF_SOCKET	0
+#else
+#define CERF_SOCKET	1
+#endif
 
-static int cerf_pcmcia_init(struct pcmcia_init *init){
-  int irq, res;
+static struct irqs {
+	int irq;
+	unsigned int gpio;
+	const char *str;
+} irqs[] = {
+	{ IRQ_GPIO_CF_CD,   GPIO_CF_CD,   "CF_CD"   },
+	{ IRQ_GPIO_CF_BVD2, GPIO_CF_BVD2, "CF_BVD2" },
+	{ IRQ_GPIO_CF_BVD1, GPIO_CF_BVD1, "CF_BVD1" }
+};
 
-  GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
-  GPDR |= (GPIO_CF_RESET);
+static int cerf_pcmcia_init(struct pcmcia_init *init)
+{
+  int i, res;
 
-  set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
   set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
 
-  irq = IRQ_GPIO_CF_CD;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
-  if( res < 0 ) goto irq_err;
-  irq = IRQ_GPIO_CF_BVD2;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
-  if( res < 0 ) goto irq_err;
-  irq = IRQ_GPIO_CF_BVD1;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
-  if( res < 0 ) goto irq_err;
+  for (i = 0; i < ARRAY_SIZE(irqs); i++) {
+    set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
+    res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+		      irqs[i].str, NULL);
+    if (res)
+      goto irq_err;
+  }
 
   return 2;
 
-irq_err:
-  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+ irq_err:
+  printk(KERN_ERR "%s: Request for IRQ%d failed\n", __FUNCTION__, irqs[i].irq);
+
+  while (i--)
+    free_irq(irqs[i].irq, NULL);
+
   return -1;
 }
 
 static int cerf_pcmcia_shutdown(void)
 {
-  free_irq( IRQ_GPIO_CF_CD, NULL );
-  free_irq( IRQ_GPIO_CF_BVD2, NULL );
-  free_irq( IRQ_GPIO_CF_BVD1, NULL );
+  int i;
+
+  for (i = 0; i < ARRAY_SIZE(irqs); i++)
+    free_irq(irqs[i].irq, NULL);
 
   return 0;
 }
@@ -51,31 +66,18 @@
 static int cerf_pcmcia_socket_state(struct pcmcia_state_array
 				       *state_array){
   unsigned long levels;
-#ifdef CONFIG_SA1100_CERF_CPLD
-  int i = 0;
-#else
-  int i = 1;
-#endif
+  int i = CERF_SOCKET;
 
   if(state_array->size<2) return -1;
 
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
   levels=GPLR;
 
   state_array->state[i].detect=((levels & GPIO_CF_CD)==0)?1:0;
-
   state_array->state[i].ready=(levels & GPIO_CF_IRQ)?1:0;
-
   state_array->state[i].bvd1=(levels & GPIO_CF_BVD1)?1:0;
-
   state_array->state[i].bvd2=(levels & GPIO_CF_BVD2)?1:0;
-
   state_array->state[i].wrprot=0;
-
   state_array->state[i].vs_3v=1;
-
   state_array->state[i].vs_Xv=0;
 
   return 1;
@@ -85,11 +87,7 @@
 
   if(info->sock>1) return -1;
 
-#ifdef CONFIG_SA1100_CERF_CPLD
-  if(info->sock==0)
-#else
-  if(info->sock==1)
-#endif
+  if (info->sock == CERF_SOCKET)
     info->irq=IRQ_GPIO_CF_IRQ;
 
   return 0;
@@ -98,20 +96,12 @@
 static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
 					   *configure)
 {
-  unsigned long flags;
-
   if(configure->sock>1)
     return -1;
 
-#ifdef CONFIG_SA1100_CERF_CPLD
-  if(configure->sock==1)
-#else
-  if(configure->sock==0)
-#endif
+  if (configure->sock != CERF_SOCKET)
     return 0;
 
-  save_flags_cli(flags);
-
   switch(configure->vcc){
   case 0:
     break;
@@ -119,43 +109,62 @@
   case 50:
   case 33:
 #ifdef CONFIG_SA1100_CERF_CPLD
-     GPDR |= GPIO_PWR_SHUTDOWN;
-     GPCR |= GPIO_PWR_SHUTDOWN;
+     GPCR = GPIO_PWR_SHUTDOWN;
 #endif
      break;
 
   default:
     printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
 	   configure->vcc);
-    restore_flags(flags);
     return -1;
   }
 
   if(configure->reset)
   {
 #ifdef CONFIG_SA1100_CERF_CPLD
-    GPDR |= GPIO_CF_RESET;
-    GPSR |= GPIO_CF_RESET;
+    GPSR = GPIO_CF_RESET;
 #endif
   }
   else
   {
 #ifdef CONFIG_SA1100_CERF_CPLD
-    GPDR |= GPIO_CF_RESET;
-    GPCR |= GPIO_CF_RESET;
+    GPCR = GPIO_CF_RESET;
 #endif
   }
 
-  restore_flags(flags);
+  return 0;
+}
+
+static int cerf_pcmcia_socket_init(int sock)
+{
+  int i;
+
+  if (sock == CERF_SOCKET)
+    for (i = 0; i < ARRAY_SIZE(irqs); i++)
+      set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
+
+  return 0;
+}
+
+static int cerf_pcmcia_socket_suspend(int sock)
+{
+  int i;
+
+  if (sock == CERF_SOCKET)
+    for (i = 0; i < ARRAY_SIZE(irqs); i++)
+      set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
 
   return 0;
 }
 
 struct pcmcia_low_level cerf_pcmcia_ops = { 
-  cerf_pcmcia_init,
-  cerf_pcmcia_shutdown,
-  cerf_pcmcia_socket_state,
-  cerf_pcmcia_get_irq_info,
-  cerf_pcmcia_configure_socket
+  init:			cerf_pcmcia_init,
+  shutdown:		cerf_pcmcia_shutdown,
+  socket_state:		cerf_pcmcia_socket_state,
+  get_irq_info:		cerf_pcmcia_get_irq_info,
+  configure_socket:	cerf_pcmcia_configure_socket,
+
+  socket_init:		cerf_pcmcia_socket_init,
+  socket_suspend:	cerf_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_flexanet.c linux/drivers/pcmcia/sa1100_flexanet.c
--- linux.orig/drivers/pcmcia/sa1100_flexanet.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_flexanet.c	2002-07-20 01:08:36.000000000 +0000
@@ -4,7 +4,6 @@
  * PCMCIA implementation routines for Flexanet.
  * by Jordi Colomer, 09/05/2001
  *
- * Yet to be defined.
  */
 
 #include <linux/kernel.h>
@@ -12,8 +11,18 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
 
+static struct {
+  int irq;
+  unsigned int gpio;
+  const char *name;
+} irqs[] = {
+  { IRQ_GPIO_CF1_CD,   GPIO_CF1_NCD,  "CF1_CD"   },
+  { IRQ_GPIO_CF1_BVD1, GPIO_CF1_BVD1, "CF1_BVD1" },
+  { IRQ_GPIO_CF2_CD,   GPIO_CF2_NCD,  "CF2_CD"   },
+  { IRQ_GPIO_CF2_BVD1, GPIO_CF2_BVD1, "CF2_BVD1" }
+};
 
 /*
  * Socket initialization.
@@ -22,9 +31,36 @@
  * Must return the number of slots.
  *
  */
-static int flexanet_pcmcia_init(struct pcmcia_init *init){
+static int flexanet_pcmcia_init(struct pcmcia_init *init)
+{
+  int i, res;
 
-  return 0;
+  /* Configure the GPIOs as inputs (BVD2 is not implemented) */
+  GPDR &= ~(GPIO_CF1_NCD | GPIO_CF1_BVD1 | GPIO_CF1_IRQ |
+            GPIO_CF2_NCD | GPIO_CF2_BVD1 | GPIO_CF2_IRQ );
+
+  /* Set IRQ edge */
+  set_GPIO_IRQ_edge( GPIO_CF1_IRQ | GPIO_CF2_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register the socket interrupts (not the card interrupts) */
+  for (i = 0; i < ARRAY_SIZE(irqs); i++) {
+    set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
+    res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+		      irqs[i].name, NULL);
+    if (res < 0)
+      break;
+  }
+
+  /* If we failed, then free all interrupts requested thus far. */
+  if (res < 0) {
+    printk(KERN_ERR "%s: Request for IRQ%u failed: %d\n", __FUNCTION__,
+           irqs[i].irq, res);
+    while (i--)
+      free_irq(irqs[i].irq, NULL);
+    return -1;
+  }
+
+  return 2;
 }
 
 
@@ -34,6 +70,12 @@
  */
 static int flexanet_pcmcia_shutdown(void)
 {
+  int i;
+
+  /* disable IRQs */
+  for (i = 0; i < ARRAY_SIZE(irqs); i++)
+    free_irq(irqs[i].irq, NULL);
+
   return 0;
 }
 
@@ -46,7 +88,33 @@
  */
 static int flexanet_pcmcia_socket_state(struct pcmcia_state_array
 				       *state_array){
-  return -1;
+  unsigned long levels;
+
+  if (state_array->size < 2)
+    return -1;
+
+  /* Sense the GPIOs, asynchronously */
+  levels = GPLR;
+
+  /* Socket 0 */
+  state_array->state[0].detect = ((levels & GPIO_CF1_NCD)==0)?1:0;
+  state_array->state[0].ready  = (levels & GPIO_CF1_IRQ)?1:0;
+  state_array->state[0].bvd1   = (levels & GPIO_CF1_BVD1)?1:0;
+  state_array->state[0].bvd2   = 1;
+  state_array->state[0].wrprot = 0;
+  state_array->state[0].vs_3v  = 1;
+  state_array->state[0].vs_Xv  = 0;
+
+  /* Socket 1 */
+  state_array->state[1].detect = ((levels & GPIO_CF2_NCD)==0)?1:0;
+  state_array->state[1].ready  = (levels & GPIO_CF2_IRQ)?1:0;
+  state_array->state[1].bvd1   = (levels & GPIO_CF2_BVD1)?1:0;
+  state_array->state[1].bvd2   = 1;
+  state_array->state[1].wrprot = 0;
+  state_array->state[1].vs_3v  = 1;
+  state_array->state[1].vs_Xv  = 0;
+
+  return 1;
 }
 
 
@@ -56,7 +124,16 @@
  */
 static int flexanet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
 
-  return -1;
+  /* check the socket index */
+  if (info->sock > 1)
+    return -1;
+
+  if (info->sock == 0)
+    info->irq = IRQ_GPIO_CF1_IRQ;
+  else if (info->sock == 1)
+    info->irq = IRQ_GPIO_CF2_IRQ;
+
+  return 0;
 }
 
 
@@ -66,19 +143,84 @@
 static int flexanet_pcmcia_configure_socket(const struct pcmcia_configure
 					   *configure)
 {
-  return -1;
+  unsigned long value, flags, mask;
+
+
+  if (configure->sock > 1)
+    return -1;
+
+  /* Ignore the VCC level since it is 3.3V and always on */
+  switch (configure->vcc)
+  {
+    case 0:
+      printk(KERN_WARNING "%s(): CS asked to power off.\n", __FUNCTION__);
+      break;
+
+    case 50:
+      printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+  	   __FUNCTION__);
+
+    case 33:
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+  	   configure->vcc);
+      return -1;
+  }
+
+  /* Reset the slot(s) using the controls in the BCR */
+  mask = 0;
+
+  switch (configure->sock)
+  {
+    case 0 : mask = FHH_BCR_CF1_RST; break;
+    case 1 : mask = FHH_BCR_CF2_RST; break;
+  }
+
+  save_flags_cli(flags);
+
+  value = flexanet_BCR;
+  value = (configure->reset) ? (value | mask) : (value & ~mask);
+  FHH_BCR = flexanet_BCR = value;
+
+  restore_flags(flags);
+
+  return 0;
 }
 
+static int flexanet_pcmcia_socket_init(int sock)
+{
+  if (sock == 0)
+    set_GPIO_IRQ_edge(GPIO_CF1_NCD | GPIO_CF1_BVD1, GPIO_BOTH_EDGES);
+  else if (sock == 1)
+    set_GPIO_IRQ_edge(GPIO_CF2_NCD | GPIO_CF2_BVD1, GPIO_BOTH_EDGES);
+
+  return 0;
+}
+
+static int flexanet_pcmcia_socket_suspend(int sock)
+{
+  if (sock == 0)
+    set_GPIO_IRQ_edge(GPIO_CF1_NCD | GPIO_CF1_BVD1, GPIO_NO_EDGES);
+  else if (sock == 1)
+    set_GPIO_IRQ_edge(GPIO_CF2_NCD | GPIO_CF2_BVD1, GPIO_NO_EDGES);
+
+  return 0;
+}
 
 /*
  * The set of socket operations
  *
  */
 struct pcmcia_low_level flexanet_pcmcia_ops = {
-  flexanet_pcmcia_init,
-  flexanet_pcmcia_shutdown,
-  flexanet_pcmcia_socket_state,
-  flexanet_pcmcia_get_irq_info,
-  flexanet_pcmcia_configure_socket
+  init:			flexanet_pcmcia_init,
+  shutdown:		flexanet_pcmcia_shutdown,
+  socket_state:		flexanet_pcmcia_socket_state,
+  get_irq_info:		flexanet_pcmcia_get_irq_info,
+  configure_socket:	flexanet_pcmcia_configure_socket,
+
+  socket_init:		flexanet_pcmcia_socket_init,
+  socket_suspend:	flexanet_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_freebird.c linux/drivers/pcmcia/sa1100_freebird.c
--- linux.orig/drivers/pcmcia/sa1100_freebird.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_freebird.c	2002-07-20 01:08:22.000000000 +0000
@@ -9,7 +9,7 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
 
 
 static int freebird_pcmcia_init(struct pcmcia_init *init){
@@ -26,14 +26,10 @@
   mdelay(100);
   LINKUP_PRC = 0xc0;
 
-  /* All those are inputs */
-  ////GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
-  GPDR &= ~(GPIO_FREEBIRD_CF_CD | GPIO_FREEBIRD_CF_IRQ | GPIO_FREEBIRD_CF_BVD);
-
   /* Set transition detect */
   //set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
   //set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
-  set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_CD|GPIO_FREEBIRD_CF_BVD,GPIO_BOTH_EDGES);
+  set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_CD|GPIO_FREEBIRD_CF_BVD,GPIO_NO_EDGES);
   set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_IRQ, GPIO_FALLING_EDGE);
 
   /* Register interrupts */
@@ -150,11 +146,26 @@
   return 0;
 }
 
+static int freebird_pcmcia_socket_init(int sock)
+{
+  set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_CD|GPIO_FREEBIRD_CF_BVD, GPIO_BOTH_EDGES);
+  return 0;
+}
+
+static int freebird_pcmcia_socket_suspend(int sock)
+{
+  set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_CD|GPIO_FREEBIRD_CF_BVD, GPIO_NO_EDGES);
+  return 0;
+}
+
 struct pcmcia_low_level freebird_pcmcia_ops = {
-  freebird_pcmcia_init,
-  freebird_pcmcia_shutdown,
-  freebird_pcmcia_socket_state,
-  freebird_pcmcia_get_irq_info,
-  freebird_pcmcia_configure_socket
+  init:			freebird_pcmcia_init,
+  shutdown:		freebird_pcmcia_shutdown,
+  socket_state:		freebird_pcmcia_socket_state,
+  get_irq_info:		freebird_pcmcia_get_irq_info,
+  configure_socket:	freebird_pcmcia_configure_socket,
+
+  socket_init:		freebird_pcmcia_socket_init,
+  socket_suspend:	freebird_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_generic.c linux/drivers/pcmcia/sa1100_generic.c
--- linux.orig/drivers/pcmcia/sa1100_generic.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_generic.c	2002-07-20 01:08:24.000000000 +0000
@@ -29,6 +29,10 @@
     file under either the MPL or the GPL.
     
 ======================================================================*/
+/*
+ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
+ * on the low-level kernel interface.
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -43,6 +47,7 @@
 #include <linux/notifier.h>
 #include <linux/proc_fs.h>
 #include <linux/version.h>
+#include <linux/cpufreq.h>
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
@@ -62,338 +67,94 @@
 static int pc_debug;
 #endif
 
-MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
-MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-1100 Socket Controller");
-
 /* This structure maintains housekeeping state for each socket, such
  * as the last known values of the card detect pins, or the Card Services
  * callback value associated with the socket:
  */
-static struct sa1100_pcmcia_socket 
-sa1100_pcmcia_socket[SA1100_PCMCIA_MAX_SOCK];
-
 static int sa1100_pcmcia_socket_count;
+static struct sa1100_pcmcia_socket sa1100_pcmcia_socket[SA1100_PCMCIA_MAX_SOCK];
 
+#define PCMCIA_SOCKET(x)	(sa1100_pcmcia_socket + (x))
 
 /* Returned by the low-level PCMCIA interface: */
 static struct pcmcia_low_level *pcmcia_low_level;
 
-/* Event poll timer structure */
 static struct timer_list poll_timer;
-
-
-/* Prototypes for routines which are used internally: */
-
-static int  sa1100_pcmcia_driver_init(void);
-static void sa1100_pcmcia_driver_shutdown(void);
-static void sa1100_pcmcia_task_handler(void *data);
-static void sa1100_pcmcia_poll_event(unsigned long data);
-static void sa1100_pcmcia_interrupt(int irq, void *dev,
-				    struct pt_regs *regs);
 static struct tq_struct sa1100_pcmcia_task;
 
-#ifdef CONFIG_PROC_FS
-static int  sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
-				      int count, int *eof, void *data);
-#endif
-
-
-/* Prototypes for operations which are exported to the
- * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
- */
-
-static int sa1100_pcmcia_init(unsigned int sock);
-static int sa1100_pcmcia_suspend(unsigned int sock);
-static int sa1100_pcmcia_register_callback(unsigned int sock,
-					   void (*handler)(void *, 
-							   unsigned int),
-					   void *info);
-static int sa1100_pcmcia_inquire_socket(unsigned int sock, 
-					socket_cap_t *cap);
-static int sa1100_pcmcia_get_status(unsigned int sock, u_int *value);
-static int sa1100_pcmcia_get_socket(unsigned int sock, 
-				    socket_state_t *state);
-static int sa1100_pcmcia_set_socket(unsigned int sock,
-				    socket_state_t *state);
-static int sa1100_pcmcia_get_io_map(unsigned int sock,
-				    struct pccard_io_map *io);
-static int sa1100_pcmcia_set_io_map(unsigned int sock,
-				    struct pccard_io_map *io);
-static int sa1100_pcmcia_get_mem_map(unsigned int sock,
-				     struct pccard_mem_map *mem);
-static int sa1100_pcmcia_set_mem_map(unsigned int sock,
-				     struct pccard_mem_map *mem);
-#ifdef CONFIG_PROC_FS
-static void sa1100_pcmcia_proc_setup(unsigned int sock,
-				     struct proc_dir_entry *base);
-#endif
-
-static struct pccard_operations sa1100_pcmcia_operations = {
-  sa1100_pcmcia_init,
-  sa1100_pcmcia_suspend,
-  sa1100_pcmcia_register_callback,
-  sa1100_pcmcia_inquire_socket,
-  sa1100_pcmcia_get_status,
-  sa1100_pcmcia_get_socket,
-  sa1100_pcmcia_set_socket,
-  sa1100_pcmcia_get_io_map,
-  sa1100_pcmcia_set_io_map,
-  sa1100_pcmcia_get_mem_map,
-  sa1100_pcmcia_set_mem_map,
-#ifdef CONFIG_PROC_FS
-  sa1100_pcmcia_proc_setup
-#endif
-};
-
-#ifdef CONFIG_CPU_FREQ
-/* forward declaration */
-static struct notifier_block sa1100_pcmcia_notifier_block;
-#endif
-
-
-/* sa1100_pcmcia_driver_init()
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- *
- * This routine performs a basic sanity check to ensure that this
- * kernel has been built with the appropriate board-specific low-level
- * PCMCIA support, performs low-level PCMCIA initialization, registers
- * this socket driver with Card Services, and then spawns the daemon
- * thread which is the real workhorse of the socket driver.
+/*
+ * sa1100_pcmcia_state_to_config
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  *
- * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
- * on the low-level kernel interface.
- *
- * Returns: 0 on success, -1 on error
- */
-static int __init sa1100_pcmcia_driver_init(void){
-  servinfo_t info;
-  struct pcmcia_init pcmcia_init;
-  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
-  struct pcmcia_state_array state_array;
-  unsigned int i, clock;
-  unsigned long mecr;
-
-  printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);
-
-  CardServices(GetCardServicesInfo, &info);
-
-  if(info.Revision!=CS_RELEASE_CODE){
-    printk(KERN_ERR "Card Services release codes do not match\n");
-    return -1;
-  }
-
-  if(machine_is_assabet()){
-#ifdef CONFIG_SA1100_ASSABET
-    if(machine_has_neponset()){
-#ifdef CONFIG_ASSABET_NEPONSET
-      pcmcia_low_level=&neponset_pcmcia_ops;
-#else
-      printk(KERN_ERR "Card Services disabled: missing Neponset support\n");
-      return -1;
-#endif
-    }else{
-      pcmcia_low_level=&assabet_pcmcia_ops;
-    }
-#endif
-  } else if (machine_is_freebird()) {
-#ifdef CONFIG_SA1100_FREEBIRD
-    pcmcia_low_level = &freebird_pcmcia_ops;
-#endif
-  } else if (machine_is_h3600()) {
-#ifdef CONFIG_SA1100_H3600
-    pcmcia_low_level = &h3600_pcmcia_ops;
-#endif    
-  } else if (machine_is_cerf()) {
-#ifdef CONFIG_SA1100_CERF
-    pcmcia_low_level = &cerf_pcmcia_ops;
-#endif
-  } else if (machine_is_graphicsclient()) {
-#ifdef CONFIG_SA1100_GRAPHICSCLIENT
-    pcmcia_low_level = &gcplus_pcmcia_ops;
-#endif
-  } else if (machine_is_xp860()) {
-#ifdef CONFIG_SA1100_XP860
-    pcmcia_low_level = &xp860_pcmcia_ops;
-#endif
-  } else if (machine_is_yopy()) {
-#ifdef CONFIG_SA1100_YOPY
-    pcmcia_low_level = &yopy_pcmcia_ops;
-#endif
-  } else if (machine_is_pangolin()) {
-#ifdef CONFIG_SA1100_PANGOLIN
-    pcmcia_low_level = &pangolin_pcmcia_ops;
-#endif
-  } else if (machine_is_jornada720()) {
-#ifdef CONFIG_SA1100_JORNADA720
-    pcmcia_low_level = &jornada720_pcmcia_ops;
-#endif
-  } else if(machine_is_pfs168()){
-#ifdef CONFIG_SA1100_PFS168
-    pcmcia_low_level=&pfs168_pcmcia_ops;
-#endif
-  } else if(machine_is_flexanet()){
-#ifdef CONFIG_SA1100_FLEXANET
-    pcmcia_low_level=&flexanet_pcmcia_ops;
-#endif
- } else if(machine_is_simpad()){
-#ifdef CONFIG_SA1100_SIMPAD
-    pcmcia_low_level=&simpad_pcmcia_ops;
-#endif
-  } else if(machine_is_graphicsmaster()) {
-#ifdef CONFIG_SA1100_GRAPHICSMASTER
-    pcmcia_low_level=&graphicsmaster_pcmcia_ops;
-#endif
-  } else if(machine_is_adsbitsy()) {
-#ifdef CONFIG_SA1100_ADSBITSY
-    pcmcia_low_level=&adsbitsy_pcmcia_ops;
-#endif
-  } else if(machine_is_stork()) {
-#ifdef CONFIG_SA1100_STORK
-    pcmcia_low_level=&stork_pcmcia_ops;
-#endif
-  }
-
-  if (!pcmcia_low_level) {
-    printk(KERN_ERR "This hardware is not supported by the SA1100 Card Service driver\n");
-    return -ENODEV;
-  }
-
-  pcmcia_init.handler=sa1100_pcmcia_interrupt;
-
-  if((sa1100_pcmcia_socket_count=pcmcia_low_level->init(&pcmcia_init))<0){
-    printk(KERN_ERR "Unable to initialize kernel PCMCIA service.\n");
-    return -EIO;
-  }
-
-  state_array.size=sa1100_pcmcia_socket_count;
-  state_array.state=state;
-
-  if(pcmcia_low_level->socket_state(&state_array)<0){
-    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
-    return -EIO;
-  }
-
-  /* We initialize the MECR to default values here, because we are
-   * not guaranteed to see a SetIOMap operation at runtime.
-   */
-  mecr=0;
-
-  clock = get_cclk_frequency() * 100;
-
-  for(i=0; i<sa1100_pcmcia_socket_count; ++i){
-    sa1100_pcmcia_socket[i].k_state=state[i];
-
-    /* This is an interim fix. Apparently, SetSocket is no longer
-     * called to initialize each socket (prior to the first detect
-     * event). For now, we'll just manually set up the mask.
-     */
-    sa1100_pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
-
-    sa1100_pcmcia_socket[i].virt_io=(i==0)?PCMCIA_IO_0_BASE:PCMCIA_IO_1_BASE;
-    sa1100_pcmcia_socket[i].phys_attr=_PCMCIAAttr(i);
-    sa1100_pcmcia_socket[i].phys_mem=_PCMCIAMem(i);
-
-    MECR_FAST_SET(mecr, i, 0);
-    MECR_BSIO_SET(mecr, i,
-		  sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_IO_ACCESS, clock));
-    MECR_BSA_SET(mecr, i,
-		 sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
-    MECR_BSM_SET(mecr, i,
-		 sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
-
-    sa1100_pcmcia_socket[i].speed_io=SA1100_PCMCIA_IO_ACCESS;
-    sa1100_pcmcia_socket[i].speed_attr=SA1100_PCMCIA_5V_MEM_ACCESS;
-    sa1100_pcmcia_socket[i].speed_mem=SA1100_PCMCIA_5V_MEM_ACCESS;
-  }
-
-  MECR=mecr;
-
-#ifdef CONFIG_CPU_FREQ
-  if(cpufreq_register_notifier(&sa1100_pcmcia_notifier_block) < 0){
-    printk(KERN_ERR "Unable to register CPU frequency change notifier\n");
-    return -ENXIO;
-  }
-#endif
-
-  /* Only advertise as many sockets as we can detect: */
-  if(register_ss_entry(sa1100_pcmcia_socket_count, 
-		       &sa1100_pcmcia_operations)<0){
-    printk(KERN_ERR "Unable to register socket service routine\n");
-    return -ENXIO;
-  }
-
-  /* Start the event poll timer.  It will reschedule by itself afterwards. */
-  sa1100_pcmcia_poll_event(0);
-
-  DEBUG(1, "sa1100: initialization complete\n");
-
-  return 0;
-
-}  /* sa1100_pcmcia_driver_init() */
-
-module_init(sa1100_pcmcia_driver_init);
-
-
-/* sa1100_pcmcia_driver_shutdown()
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Invokes the low-level kernel service to free IRQs associated with this
- * socket controller and reset GPIO edge detection.
+ * Convert PCMCIA socket state to our socket configure structure.
  */
-static void __exit sa1100_pcmcia_driver_shutdown(void){
+static struct pcmcia_configure
+sa1100_pcmcia_state_to_config(unsigned int sock, socket_state_t *state)
+{
+  struct pcmcia_configure conf;
 
-  del_timer_sync(&poll_timer);
-  unregister_ss_entry(&sa1100_pcmcia_operations);
-#ifdef CONFIG_CPU_FREQ
-  cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block);
-#endif
-  pcmcia_low_level->shutdown();
-  flush_scheduled_tasks();
+  conf.sock    = sock;
+  conf.vcc     = state->Vcc;
+  conf.vpp     = state->Vpp;
+  conf.output  = state->flags & SS_OUTPUT_ENA ? 1 : 0;
+  conf.speaker = state->flags & SS_SPKR_ENA ? 1 : 0;
+  conf.reset   = state->flags & SS_RESET ? 1 : 0;
+  conf.irq     = state->io_irq != 0;
 
-  DEBUG(1, "sa1100: shutdown complete\n");
+  return conf;
 }
 
-module_exit(sa1100_pcmcia_driver_shutdown);
-
-
 /* sa1100_pcmcia_init()
  * ^^^^^^^^^^^^^^^^^^^^
- * We perform all of the interesting initialization tasks in 
- * sa1100_pcmcia_driver_init().
+ *
+ * (Re-)Initialise the socket, turning on status interrupts
+ * and PCMCIA bus.  This must wait for power to stabilise
+ * so that the card status signals report correctly.
  *
  * Returns: 0
  */
-static int sa1100_pcmcia_init(unsigned int sock){
-  
+static int sa1100_pcmcia_init(unsigned int sock)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+  struct pcmcia_configure conf;
+
   DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, sock);
 
-  return 0;
+  skt->cs_state = dead_socket;
+
+  conf = sa1100_pcmcia_state_to_config(sock, &dead_socket);
+
+  pcmcia_low_level->configure_socket(&conf);
+
+  return pcmcia_low_level->socket_init(sock);
 }
 
 
-/* sa1100_pcmcia_suspend()
+/*
+ * sa1100_pcmcia_suspend()
  * ^^^^^^^^^^^^^^^^^^^^^^^
- * We don't currently perform any actions on a suspend.
+ *
+ * Remove power on the socket, disable IRQs from the card.
+ * Turn off status interrupts, and disable the PCMCIA bus.
  *
  * Returns: 0
  */
 static int sa1100_pcmcia_suspend(unsigned int sock)
 {
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   struct pcmcia_configure conf;
   int ret;
 
   DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, sock);
 
-  conf.sock = sock;
-  conf.vcc = 0;
-  conf.vpp = 0;
-  conf.output = 0;
-  conf.speaker = 0;
-  conf.reset = 1;
+  conf = sa1100_pcmcia_state_to_config(sock, &dead_socket);
 
   ret = pcmcia_low_level->configure_socket(&conf);
 
-  if (ret == 0)
-    sa1100_pcmcia_socket[sock].cs_state = dead_socket;
+  if (ret == 0) {
+    skt->cs_state = dead_socket;
+    ret = pcmcia_low_level->socket_suspend(sock);
+  }
 
   return ret;
 }
@@ -407,52 +168,50 @@
  *
  * Returns: an event mask for the given socket state.
  */
-static inline unsigned sa1100_pcmcia_events(struct pcmcia_state *state,
-					    struct pcmcia_state *prev_state,
-					    unsigned int mask,
-					    unsigned int flags){
-  unsigned int events=0;
-
-  if(state->detect!=prev_state->detect){
+static inline unsigned int
+sa1100_pcmcia_events(struct pcmcia_state *state,
+		     struct pcmcia_state *prev_state,
+		     unsigned int mask, unsigned int flags)
+{
+  unsigned int events = 0;
 
-    DEBUG(2, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
+  if (state->detect != prev_state->detect) {
+    DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
 
-    events|=mask&SS_DETECT;
+    events |= SS_DETECT;
   }
 
-  if(state->ready!=prev_state->ready){
+  if (state->ready != prev_state->ready) {
+    DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
 
-    DEBUG(2, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
-
-    events|=mask&((flags&SS_IOCARD)?0:SS_READY);
+    events |= flags & SS_IOCARD ? 0 : SS_READY;
   }
 
-  if(state->bvd1!=prev_state->bvd1){
-
-    DEBUG(2, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
+  if (state->bvd1 != prev_state->bvd1) {
+    DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
 
-    events|=mask&(flags&SS_IOCARD)?SS_STSCHG:SS_BATDEAD;
+    events |= flags & SS_IOCARD ? SS_STSCHG : SS_BATDEAD;
   }
 
-  if(state->bvd2!=prev_state->bvd2){
+  if (state->bvd2 != prev_state->bvd2) {
+    DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
 
-    DEBUG(2, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
-
-    events|=mask&(flags&SS_IOCARD)?0:SS_BATWARN;
+    events |= flags & SS_IOCARD ? 0 : SS_BATWARN;
   }
 
-  DEBUG(2, "events: %s%s%s%s%s%s\n",
-	(events==0)?"<NONE>":"",
-	(events&SS_DETECT)?"DETECT ":"",
-	(events&SS_READY)?"READY ":"",
-	(events&SS_BATDEAD)?"BATDEAD ":"",
-	(events&SS_BATWARN)?"BATWARN ":"",
-	(events&SS_STSCHG)?"STSCHG ":"");
+  *prev_state = *state;
 
-  *prev_state=*state;
+  events &= mask;
 
-  return events;
+  DEBUG(2, "events: %s%s%s%s%s%s\n",
+	events == 0         ? "<NONE>"   : "",
+	events & SS_DETECT  ? "DETECT "  : "",
+	events & SS_READY   ? "READY "   : "",
+	events & SS_BATDEAD ? "BATDEAD " : "",
+	events & SS_BATWARN ? "BATWARN " : "",
+	events & SS_STSCHG  ? "STSCHG "  : "");
 
+  return events;
 }  /* sa1100_pcmcia_events() */
 
 
@@ -464,38 +223,43 @@
  * callback) occurs in this thread rather than in the actual interrupt
  * handler due to the use of scheduling operations in the PCMCIA core.
  */
-static void sa1100_pcmcia_task_handler(void *data) {
+static void sa1100_pcmcia_task_handler(void *data)
+{
   struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
   struct pcmcia_state_array state_array;
-  int i, events, all_events, irq_status;
+  unsigned int all_events;
 
-  DEBUG(2, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
+  DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
 
-  state_array.size=sa1100_pcmcia_socket_count;
-  state_array.state=state;
+  state_array.size = sa1100_pcmcia_socket_count;
+  state_array.state = state;
 
   do {
+    unsigned int events;
+    int ret, i;
 
-    DEBUG(3, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
+    memset(state, 0, sizeof(state));
 
-    if((irq_status=pcmcia_low_level->socket_state(&state_array))<0)
-      printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
+    DEBUG(4, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
 
-    all_events=0;
+    ret = pcmcia_low_level->socket_state(&state_array);
+    if (ret < 0) {
+      printk(KERN_ERR "sa1100_pcmcia: unable to read socket status\n");
+      break;
+    }
 
-    if(irq_status>0){
+    all_events = 0;
 
-      for(i=0; i<state_array.size; ++i, all_events|=events)
-	if((events=
-	    sa1100_pcmcia_events(&state[i],
-				 &sa1100_pcmcia_socket[i].k_state,
-				 sa1100_pcmcia_socket[i].cs_state.csc_mask,
-				 sa1100_pcmcia_socket[i].cs_state.flags)))
-	  if(sa1100_pcmcia_socket[i].handler!=NULL)
-	    sa1100_pcmcia_socket[i].handler(sa1100_pcmcia_socket[i].handler_info,
-					    events);
-    }
+    for (i = 0; i < state_array.size; i++, all_events |= events) {
+      struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
 
+      events = sa1100_pcmcia_events(&state[i], &skt->k_state,
+				    skt->cs_state.csc_mask,
+				    skt->cs_state.flags);
+
+      if (events && sa1100_pcmcia_socket[i].handler != NULL)
+	skt->handler(skt->handler_info, events);
+    }
   } while(all_events);
 }  /* sa1100_pcmcia_task_handler() */
 
@@ -510,7 +274,7 @@
  */
 static void sa1100_pcmcia_poll_event(unsigned long dummy)
 {
-  DEBUG(3, "%s(): polling for events\n", __FUNCTION__);
+  DEBUG(4, "%s(): polling for events\n", __FUNCTION__);
   poll_timer.function = sa1100_pcmcia_poll_event;
   poll_timer.expires = jiffies + SA1100_PCMCIA_POLL_PERIOD;
   add_timer(&poll_timer);
@@ -527,7 +291,8 @@
  * handling code performs scheduling operations which cannot be
  * executed from within an interrupt context.
  */
-static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs){
+static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
   DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
   schedule_task(&sa1100_pcmcia_task);
 }
@@ -546,17 +311,20 @@
  *
  * Returns: 0
  */
-static int sa1100_pcmcia_register_callback(unsigned int sock,
-					   void (*handler)(void *,
-							   unsigned int),
-					   void *info){
-  if(handler==NULL){
-    sa1100_pcmcia_socket[sock].handler=NULL;
+static int
+sa1100_pcmcia_register_callback(unsigned int sock,
+				void (*handler)(void *, unsigned int),
+				void *info)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+
+  if (handler == NULL) {
+    skt->handler = NULL;
     MOD_DEC_USE_COUNT;
   } else {
     MOD_INC_USE_COUNT;
-    sa1100_pcmcia_socket[sock].handler=handler;
-    sa1100_pcmcia_socket[sock].handler_info=info;
+    skt->handler_info = info;
+    skt->handler = handler;
   }
 
   return 0;
@@ -580,51 +348,41 @@
  * an offset which is applied to client-requested base I/O addresses
  * in alloc_io_space().
  *
- * Returns: 0 on success, -1 if no pin has been configured for `sock'
+ * SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
+ *   force_low argument to validate_mem() in rsrc_mgr.c -- since in
+ *   general, the mapped * addresses of the PCMCIA memory regions
+ *   will not be within 0xffff, setting force_low would be
+ *   undesirable.
+ *
+ * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
+ *   resource database; we instead pass up physical address ranges
+ *   and allow other parts of Card Services to deal with remapping.
+ *
+ * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
+ *   not 32-bit CardBus devices.
+ *
+ * Return value is irrelevant; the pcmcia subsystem ignores it.
  */
-static int sa1100_pcmcia_inquire_socket(unsigned int sock,
-					socket_cap_t *cap){
-  struct pcmcia_irq_info irq_info;
-
-  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
-
-  if(sock>=sa1100_pcmcia_socket_count){
-    printk(KERN_ERR "sa1100: socket %u not configured\n", sock);
-    return -1;
-  }
+static int
+sa1100_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+  int ret = -1;
 
-  /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
-   *   force_low argument to validate_mem() in rsrc_mgr.c -- since in
-   *   general, the mapped * addresses of the PCMCIA memory regions
-   *   will not be within 0xffff, setting force_low would be
-   *   undesirable.
-   *
-   * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
-   *   resource database; we instead pass up physical address ranges
-   *   and allow other parts of Card Services to deal with remapping.
-   *
-   * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
-   *   not 32-bit CardBus devices.
-   */
-  cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
 
-  irq_info.sock=sock;
-  irq_info.irq=-1;
+  if (sock < sa1100_pcmcia_socket_count) {
+    cap->features  = SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
+    cap->irq_mask  = 0;
+    cap->map_size  = PAGE_SIZE;
+    cap->pci_irq   = skt->irq;
+    cap->io_offset = (unsigned long)skt->virt_io;
 
-  if(pcmcia_low_level->get_irq_info(&irq_info)<0){
-    printk(KERN_ERR "Error obtaining IRQ info from kernel for socket %u\n",
-	   sock);
-    return -1;
+    ret = 0;
   }
 
-  cap->irq_mask=0;
-  cap->map_size=PAGE_SIZE;
-  cap->pci_irq=irq_info.irq;
-  cap->io_offset=sa1100_pcmcia_socket[sock].virt_io;
-
-  return 0;
-
-}  /* sa1100_pcmcia_inquire_socket() */
+  return ret;
+}
 
 
 /* sa1100_pcmcia_get_status()
@@ -643,58 +401,61 @@
  *
  * Returns: 0
  */
-static int sa1100_pcmcia_get_status(unsigned int sock,
-				    unsigned int *status){
+static int
+sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
   struct pcmcia_state_array state_array;
+  unsigned int stat;
 
-  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
 
-  state_array.size=sa1100_pcmcia_socket_count;
-  state_array.state=state;
+  state_array.size = sa1100_pcmcia_socket_count;
+  state_array.state = state;
 
-  if((pcmcia_low_level->socket_state(&state_array))<0){
-    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+  memset(state, 0, sizeof(state));
+
+  if ((pcmcia_low_level->socket_state(&state_array)) < 0) {
+    printk(KERN_ERR "sa1100_pcmcia: unable to get socket status\n");
     return -1;
   }
 
-  sa1100_pcmcia_socket[sock].k_state=state[sock];
-
-  *status=state[sock].detect?SS_DETECT:0;
+  skt->k_state = state[sock];
 
-  *status|=state[sock].ready?SS_READY:0;
+  stat = state[sock].detect ? SS_DETECT : 0;
+  stat |= state[sock].ready ? SS_READY  : 0;
+  stat |= state[sock].vs_3v ? SS_3VCARD : 0;
+  stat |= state[sock].vs_Xv ? SS_XVCARD : 0;
 
   /* The power status of individual sockets is not available
    * explicitly from the hardware, so we just remember the state
    * and regurgitate it upon request:
    */
-  *status|=sa1100_pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
+  stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
 
-  if(sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
-    *status|=state[sock].bvd1?SS_STSCHG:0;
+  if (skt->cs_state.flags & SS_IOCARD)
+    stat |= state[sock].bvd1 ? SS_STSCHG : 0;
   else {
-    if(state[sock].bvd1==0)
-      *status|=SS_BATDEAD;
-    else if(state[sock].bvd2==0)
-      *status|=SS_BATWARN;
+    if (state[sock].bvd1 == 0)
+      stat |= SS_BATDEAD;
+    else if (state[sock].bvd2 == 0)
+      stat |= SS_BATWARN;
   }
 
-  *status|=state[sock].vs_3v?SS_3VCARD:0;
-
-  *status|=state[sock].vs_Xv?SS_XVCARD:0;
-
   DEBUG(3, "\tstatus: %s%s%s%s%s%s%s%s\n",
-	(*status&SS_DETECT)?"DETECT ":"",
-	(*status&SS_READY)?"READY ":"", 
-	(*status&SS_BATDEAD)?"BATDEAD ":"",
-	(*status&SS_BATWARN)?"BATWARN ":"",
-	(*status&SS_POWERON)?"POWERON ":"",
-	(*status&SS_STSCHG)?"STSCHG ":"",
-	(*status&SS_3VCARD)?"3VCARD ":"",
-	(*status&SS_XVCARD)?"XVCARD ":"");
+	stat & SS_DETECT  ? "DETECT "  : "",
+	stat & SS_READY   ? "READY "   : "", 
+	stat & SS_BATDEAD ? "BATDEAD " : "",
+	stat & SS_BATWARN ? "BATWARN " : "",
+	stat & SS_POWERON ? "POWERON " : "",
+	stat & SS_STSCHG  ? "STSCHG "  : "",
+	stat & SS_3VCARD  ? "3VCARD "  : "",
+	stat & SS_XVCARD  ? "XVCARD "  : "");
 
-  return 0;
+  *status = stat;
 
+  return 0;
 }  /* sa1100_pcmcia_get_status() */
 
 
@@ -706,20 +467,18 @@
  *
  * Returns: 0
  */
-static int sa1100_pcmcia_get_socket(unsigned int sock,
-				    socket_state_t *state){
+static int
+sa1100_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
 
-  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
 
-  /* This information was given to us in an earlier call to set_socket(),
-   * so we're just regurgitating it here:
-   */
-  *state=sa1100_pcmcia_socket[sock].cs_state;
+  *state = skt->cs_state;
 
   return 0;
 }
 
-
 /* sa1100_pcmcia_set_socket()
  * ^^^^^^^^^^^^^^^^^^^^^^^^^^
  * Implements the set_socket() operation for the in-kernel PCMCIA
@@ -730,14 +489,15 @@
  *
  * Returns: 0
  */
-static int sa1100_pcmcia_set_socket(unsigned int sock,
-				    socket_state_t *state){
-  struct pcmcia_configure configure;
+static int
+sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+  struct pcmcia_configure conf;
 
-  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
 
-  DEBUG(3, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
-	"\tVcc %d  Vpp %d  irq %d\n",
+  DEBUG(3, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n",
 	(state->csc_mask==0)?"<NONE>":"",
 	(state->csc_mask&SS_DETECT)?"DETECT ":"",
 	(state->csc_mask&SS_READY)?"READY ":"",
@@ -749,25 +509,20 @@
 	(state->flags&SS_IOCARD)?"IOCARD ":"",
 	(state->flags&SS_RESET)?"RESET ":"",
 	(state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
-	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
+	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"");
+  DEBUG(3, "\tVcc %d  Vpp %d  irq %d\n",
 	state->Vcc, state->Vpp, state->io_irq);
 
-  configure.sock=sock;
-  configure.vcc=state->Vcc;
-  configure.vpp=state->Vpp;
-  configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
-  configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
-  configure.reset=(state->flags&SS_RESET)?1:0;
+  conf = sa1100_pcmcia_state_to_config(sock, state);
 
-  if(pcmcia_low_level->configure_socket(&configure)<0){
-    printk(KERN_ERR "Unable to configure socket %u\n", sock);
+  if (pcmcia_low_level->configure_socket(&conf) < 0) {
+    printk(KERN_ERR "sa1100_pcmcia: unable to configure socket %d\n", sock);
     return -1;
   }
 
-  sa1100_pcmcia_socket[sock].cs_state=*state;
+  skt->cs_state = *state;
   
   return 0;
-
 }  /* sa1100_pcmcia_set_socket() */
 
 
@@ -779,20 +534,20 @@
  *
  * Returns: 0 on success, -1 if the map index was out of range
  */
-static int sa1100_pcmcia_get_io_map(unsigned int sock,
-				    struct pccard_io_map *map){
+static int
+sa1100_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+  int ret = -1;
 
-  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
 
-  if(map->map>=MAX_IO_WIN){
-    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
-	   map->map);
-    return -1;
+  if (map->map < MAX_IO_WIN) {
+    *map = skt->io_map[map->map];
+    ret = 0;
   }
 
-  *map=sa1100_pcmcia_socket[sock].io_map[map->map];
-
-  return 0;
+  return ret;
 }
 
 
@@ -805,16 +560,16 @@
  *
  * Returns: 0 on success, -1 on error
  */
-static int sa1100_pcmcia_set_io_map(unsigned int sock,
-				    struct pccard_io_map *map){
-  unsigned int clock, speed;
-  unsigned long mecr, start;
+static int
+sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
 
-  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
 
-  DEBUG(4, "\tmap %u  speed %u\n\tstart 0x%08lx  stop 0x%08lx\n"
-	"\tflags: %s%s%s%s%s%s%s%s\n",
-	map->map, map->speed, map->start, map->stop,
+  DEBUG(3, "\tmap %u  speed %u\n\tstart 0x%08x  stop 0x%08x\n",
+	map->map, map->speed, map->start, map->stop);
+  DEBUG(3, "\tflags: %s%s%s%s%s%s%s%s\n",
 	(map->flags==0)?"<NONE>":"",
 	(map->flags&MAP_ACTIVE)?"ACTIVE ":"",
 	(map->flags&MAP_16BIT)?"16BIT ":"",
@@ -824,45 +579,45 @@
 	(map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
 	(map->flags&MAP_PREFETCH)?"PREFETCH ":"");
 
-  if(map->map>=MAX_IO_WIN){
+  if (map->map >= MAX_IO_WIN) {
     printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
 	   map->map);
     return -1;
   }
 
-  if(map->flags&MAP_ACTIVE){
+  if (map->flags & MAP_ACTIVE) {
+    unsigned int clock, speed = map->speed;
+    unsigned long mecr;
 
-    speed=(map->speed>0)?map->speed:SA1100_PCMCIA_IO_ACCESS;
+    if (speed == 0)
+      speed = SA1100_PCMCIA_IO_ACCESS;
 
-    clock = get_cclk_frequency() * 100;
+    clock = cpufreq_get(0);
 
-    mecr=MECR;
+    mecr = MECR;
 
     MECR_BSIO_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
 
-    sa1100_pcmcia_socket[sock].speed_io=speed;
+    skt->speed_io = speed;
 
     DEBUG(4, "%s(): FAST%u %lx  BSM%u %lx  BSA%u %lx  BSIO%u %lx\n",
 	  __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
 	  MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock), 
 	  sock, MECR_BSIO_GET(mecr, sock));
 
-    MECR=mecr;
-
+    MECR = mecr;
   }
 
-  start=map->start;
+  if (map->stop == 1)
+    map->stop = PAGE_SIZE-1;
 
-  if(map->stop==1)
-    map->stop=PAGE_SIZE-1;
+  map->stop -= map->start;
+  map->stop += (unsigned long)skt->virt_io;
+  map->start = (unsigned long)skt->virt_io;
 
-  map->start=sa1100_pcmcia_socket[sock].virt_io;
-  map->stop=map->start+(map->stop-start);
-
-  sa1100_pcmcia_socket[sock].io_map[map->map]=*map;
+  skt->io_map[map->map] = *map;
 
   return 0;
-
 }  /* sa1100_pcmcia_set_io_map() */
 
 
@@ -875,20 +630,20 @@
  *
  * Returns: 0 on success, -1 if the map index was out of range
  */
-static int sa1100_pcmcia_get_mem_map(unsigned int sock,
-				     struct pccard_mem_map *map){
+static int
+sa1100_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+  int ret = -1;
 
-  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
 
-  if(map->map>=MAX_WIN){
-    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
-	   map->map);
-    return -1;
+  if (map->map < MAX_WIN) {
+    *map = skt->mem_map[map->map];
+    ret = 0;
   }
 
-  *map=sa1100_pcmcia_socket[sock].mem_map[map->map];
-
-  return 0;
+  return ret;
 }
 
 
@@ -901,18 +656,18 @@
  *
  * Returns: 0 on success, -1 on error
  */
-static int sa1100_pcmcia_set_mem_map(unsigned int sock,
-				     struct pccard_mem_map *map){
-  unsigned int clock, speed;
-  unsigned long mecr, start;
+static int
+sa1100_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
+{
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+  unsigned long start;
 
-  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
 
-  DEBUG(4, "\tmap %u  speed %u\n\tsys_start  %#lx\n"
-	"\tsys_stop   %#lx\n\tcard_start %#x\n"
-	"\tflags: %s%s%s%s%s%s%s%s\n",
-	map->map, map->speed, map->sys_start, map->sys_stop,
-	map->card_start, (map->flags==0)?"<NONE>":"",
+  DEBUG(3, "\tmap %u speed %u sys_start %08lx sys_stop %08lx card_start %08x\n",
+	map->map, map->speed, map->sys_start, map->sys_stop, map->card_start);
+  DEBUG(3, "\tflags: %s%s%s%s%s%s%s%s\n",
+	(map->flags==0)?"<NONE>":"",
 	(map->flags&MAP_ACTIVE)?"ACTIVE ":"",
 	(map->flags&MAP_16BIT)?"16BIT ":"",
 	(map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
@@ -921,177 +676,175 @@
 	(map->flags&MAP_ATTRIB)?"ATTRIB ":"",
 	(map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
 
-  if(map->map>=MAX_WIN){
+  if (map->map >= MAX_WIN){
     printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
 	   map->map);
     return -1;
   }
 
-  if(map->flags&MAP_ACTIVE){
-
-    /* When clients issue RequestMap, the access speed is not always
-     * properly configured:
+  if (map->flags & MAP_ACTIVE) {
+    unsigned int clock, speed = map->speed;
+    unsigned long mecr;
+
+    /*
+     * When clients issue RequestMap, the access speed is not always
+     * properly configured.  Choose some sensible defaults.
      */
-    if(map->speed > 0)
-      speed = map->speed;
-    else
-      switch(sa1100_pcmcia_socket[sock].cs_state.Vcc){
-      case 33:
+    if (speed == 0) {
+      if (skt->cs_state.Vcc == 33)
 	speed = SA1100_PCMCIA_3V_MEM_ACCESS;
-	break;
-      default:
+      else
 	speed = SA1100_PCMCIA_5V_MEM_ACCESS;
-      }
+    }
 
-    clock = get_cclk_frequency() * 100;
-    
-    mecr=MECR;
-    
-    if(map->flags&MAP_ATTRIB){
+    clock = cpufreq_get(0);
 
-      MECR_BSA_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
-      sa1100_pcmcia_socket[sock].speed_attr=speed;
+    /* Fixme: MECR is not pre-empt safe. */
+    mecr = MECR;
 
+    if (map->flags & MAP_ATTRIB) {
+      MECR_BSA_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+      skt->speed_attr = speed;
     } else {
-
       MECR_BSM_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
-      sa1100_pcmcia_socket[sock].speed_mem=speed;
-
+      skt->speed_mem = speed;
     }
-    
+
     DEBUG(4, "%s(): FAST%u %lx  BSM%u %lx  BSA%u %lx  BSIO%u %lx\n",
 	  __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
 	  MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock), 
 	  sock, MECR_BSIO_GET(mecr, sock));
-    
-    MECR=mecr;
 
+    MECR = mecr;
   }
 
-  start=map->sys_start;
-
-  if(map->sys_stop==0)
-    map->sys_stop=PAGE_SIZE-1;
+  start = (map->flags & MAP_ATTRIB) ? skt->phys_attr : skt->phys_mem;
 
-  map->sys_start=(map->flags & MAP_ATTRIB)?\
-    sa1100_pcmcia_socket[sock].phys_attr:\
-    sa1100_pcmcia_socket[sock].phys_mem;
+  if (map->sys_stop == 0)
+    map->sys_stop = PAGE_SIZE-1;
 
-  map->sys_stop=map->sys_start+(map->sys_stop-start);
+  map->sys_stop -= map->sys_start;
+  map->sys_stop += start;
+  map->sys_start = start;
 
-  sa1100_pcmcia_socket[sock].mem_map[map->map]=*map;
+  skt->mem_map[map->map] = *map;
 
   return 0;
-
 }  /* sa1100_pcmcia_set_mem_map() */
 
 
 #if defined(CONFIG_PROC_FS)
 
-/* sa1100_pcmcia_proc_setup()
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Implements the proc_setup() operation for the in-kernel PCMCIA
- * service (formerly SS_ProcSetup in Card Services).
- *
- * Returns: 0 on success, -1 on error
- */
-static void sa1100_pcmcia_proc_setup(unsigned int sock,
-				     struct proc_dir_entry *base){
-  struct proc_dir_entry *entry;
-
-  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-
-  if((entry=create_proc_entry("status", 0, base))==NULL){
-    printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
-    return;
-  }
-
-  entry->read_proc=sa1100_pcmcia_proc_status;
-  entry->data=(void *)sock;
-}
-
-
 /* sa1100_pcmcia_proc_status()
  * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  * Implements the /proc/bus/pccard/??/status file.
  *
  * Returns: the number of characters added to the buffer
  */
-static int sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
-				     int count, int *eof, void *data){
-  char *p=buf;
-  unsigned int sock=(unsigned int)data;
-  unsigned int clock = get_cclk_frequency() * 100;
+static int
+sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
+			  int count, int *eof, void *data)
+{
+  unsigned int sock = (unsigned int)data;
+  unsigned int clock = cpufreq_get(0);
+  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   unsigned long mecr = MECR;
+  char *p = buf;
 
-  p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 
-	     sa1100_pcmcia_socket[sock].k_state.detect?"detect ":"",
-	     sa1100_pcmcia_socket[sock].k_state.ready?"ready ":"",
-	     sa1100_pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
-	     sa1100_pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
-	     sa1100_pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
-	     sa1100_pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
-	     sa1100_pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
+  p+=sprintf(p, "k_state  : %s%s%s%s%s%s%s\n", 
+	     skt->k_state.detect ? "detect " : "",
+	     skt->k_state.ready  ? "ready "  : "",
+	     skt->k_state.bvd1   ? "bvd1 "   : "",
+	     skt->k_state.bvd2   ? "bvd2 "   : "",
+	     skt->k_state.wrprot ? "wrprot " : "",
+	     skt->k_state.vs_3v  ? "vs_3v "  : "",
+	     skt->k_state.vs_Xv  ? "vs_Xv "  : "");
 
   p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
-	     sa1100_pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
-	     sa1100_pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
-	     "SS_IOCARD ":"",
-	     (sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
-	      sa1100_pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
-	     ((sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
-	      (sa1100_pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
-	     ((sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
-	      (sa1100_pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
-	     sa1100_pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
-	     sa1100_pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
+	     skt->k_state.detect ? "SS_DETECT " : "",
+	     skt->k_state.ready  ? "SS_READY " : "",
+	     skt->cs_state.Vcc   ? "SS_POWERON " : "",
+	     skt->cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "",
+	     (skt->cs_state.flags & SS_IOCARD &&
+	      skt->k_state.bvd1) ? "SS_STSCHG " : "",
+	     ((skt->cs_state.flags & SS_IOCARD)==0 &&
+	      (skt->k_state.bvd1==0)) ? "SS_BATDEAD " : "",
+	     ((skt->cs_state.flags & SS_IOCARD)==0 &&
+	      (skt->k_state.bvd2==0)) ? "SS_BATWARN " : "",
+	     skt->k_state.vs_3v  ? "SS_3VCARD " : "",
+	     skt->k_state.vs_Xv  ? "SS_XVCARD " : "");
 
   p+=sprintf(p, "mask     : %s%s%s%s%s\n",
-	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
-	     "SS_DETECT ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
-	     "SS_READY ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
-	     "SS_BATDEAD ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
-	     "SS_BATWARN ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
-	     "SS_STSCHG ":"");
+	     skt->cs_state.csc_mask & SS_DETECT  ? "SS_DETECT "  : "",
+	     skt->cs_state.csc_mask & SS_READY   ? "SS_READY "   : "",
+	     skt->cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "",
+	     skt->cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "",
+	     skt->cs_state.csc_mask & SS_STSCHG  ? "SS_STSCHG "  : "");
 
   p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
-	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
-	     "SS_PWR_AUTO ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
-	     "SS_IOCARD ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_RESET?\
-	     "SS_RESET ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
-	     "SS_SPKR_ENA ":"",
-	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
-	     "SS_OUTPUT_ENA ":"");
-
-  p+=sprintf(p, "Vcc      : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vcc);
-
-  p+=sprintf(p, "Vpp      : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vpp);
-
-  p+=sprintf(p, "irq      : %d\n", sa1100_pcmcia_socket[sock].cs_state.io_irq);
+	     skt->cs_state.flags & SS_PWR_AUTO   ? "SS_PWR_AUTO "   : "",
+	     skt->cs_state.flags & SS_IOCARD     ? "SS_IOCARD "     : "",
+	     skt->cs_state.flags & SS_RESET      ? "SS_RESET "      : "",
+	     skt->cs_state.flags & SS_SPKR_ENA   ? "SS_SPKR_ENA "   : "",
+	     skt->cs_state.flags & SS_OUTPUT_ENA ? "SS_OUTPUT_ENA " : "");
+
+  p+=sprintf(p, "Vcc      : %d\n", skt->cs_state.Vcc);
+  p+=sprintf(p, "Vpp      : %d\n", skt->cs_state.Vpp);
+  p+=sprintf(p, "IRQ      : %d\n", skt->cs_state.io_irq);
 
-  p+=sprintf(p, "I/O      : %u (%u)\n", sa1100_pcmcia_socket[sock].speed_io,
+  p+=sprintf(p, "I/O      : %u (%u)\n", skt->speed_io,
 	     sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, sock)));
 
-  p+=sprintf(p, "attribute: %u (%u)\n", sa1100_pcmcia_socket[sock].speed_attr,
+  p+=sprintf(p, "attribute: %u (%u)\n", skt->speed_attr,
 	     sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, sock)));
 
-  p+=sprintf(p, "common   : %u (%u)\n", sa1100_pcmcia_socket[sock].speed_mem,
+  p+=sprintf(p, "common   : %u (%u)\n", skt->speed_mem,
 	     sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, sock)));
 
   return p-buf;
 }
 
+/* sa1100_pcmcia_proc_setup()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the proc_setup() operation for the in-kernel PCMCIA
+ * service (formerly SS_ProcSetup in Card Services).
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static void
+sa1100_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+{
+  struct proc_dir_entry *entry;
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if ((entry = create_proc_entry("status", 0, base)) == NULL){
+    printk(KERN_ERR "unable to install \"status\" procfs entry\n");
+    return;
+  }
+
+  entry->read_proc = sa1100_pcmcia_proc_status;
+  entry->data = (void *)sock;
+}
+
 #endif  /* defined(CONFIG_PROC_FS) */
 
+static struct pccard_operations sa1100_pcmcia_operations = {
+  init:			sa1100_pcmcia_init,
+  suspend:		sa1100_pcmcia_suspend,
+  register_callback:	sa1100_pcmcia_register_callback,
+  inquire_socket:	sa1100_pcmcia_inquire_socket,
+  get_status:		sa1100_pcmcia_get_status,
+  get_socket:		sa1100_pcmcia_get_socket,
+  set_socket:		sa1100_pcmcia_set_socket,
+  get_io_map:		sa1100_pcmcia_get_io_map,
+  set_io_map:		sa1100_pcmcia_set_io_map,
+  get_mem_map:		sa1100_pcmcia_get_mem_map,
+  set_mem_map:		sa1100_pcmcia_set_mem_map,
+#ifdef CONFIG_PROC_FS
+  proc_setup:		sa1100_pcmcia_proc_setup
+#endif
+};
 
 #ifdef CONFIG_CPU_FREQ
 
@@ -1101,7 +854,8 @@
  * to a core clock frequency change) is needed, this routine establishes
  * new BS_xx values consistent with the clock speed `clock'.
  */
-static void sa1100_pcmcia_update_mecr(unsigned int clock){
+static void sa1100_pcmcia_update_mecr(unsigned int clock)
+{
   unsigned int sock;
   unsigned long mecr = MECR;
 
@@ -1132,53 +886,293 @@
  *
  * Returns: 0 on success, -1 on error
  */
-static int sa1100_pcmcia_notifier(struct notifier_block *nb,
-				  unsigned long val, void *data){
+static int
+sa1100_pcmcia_notifier(struct notifier_block *nb, unsigned long val,
+		       void *data)
+{
   struct cpufreq_info *ci = data;
 
-  switch(val){
-  case CPUFREQ_MINMAX:
-
-    break;
-
+  switch (val) {
   case CPUFREQ_PRECHANGE:
-
-    if(ci->new_freq > ci->old_freq){
+    if (ci->new_freq > ci->old_freq) {
       DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating\n",
 	    __FUNCTION__,
 	    ci->new_freq / 1000, (ci->new_freq / 100) % 10,
 	    ci->old_freq / 1000, (ci->old_freq / 100) % 10);
       sa1100_pcmcia_update_mecr(ci->new_freq);
     }
-
     break;
 
   case CPUFREQ_POSTCHANGE:
-
-    if(ci->new_freq < ci->old_freq){
+    if (ci->new_freq < ci->old_freq) {
       DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating\n",
 	    __FUNCTION__,
 	    ci->new_freq / 1000, (ci->new_freq / 100) % 10,
 	    ci->old_freq / 1000, (ci->old_freq / 100) % 10);
       sa1100_pcmcia_update_mecr(ci->new_freq);
     }
-
     break;
-
-  default:
-    printk(KERN_ERR "%s(): unknown CPU frequency event %lx\n", __FUNCTION__,
-	   val);
-    return -1;
-
   }
 
   return 0;
-
 }
 
 static struct notifier_block sa1100_pcmcia_notifier_block = {
   notifier_call: sa1100_pcmcia_notifier
 };
+#endif
 
+static int __init sa1100_pcmcia_machine_init(void)
+{
+#ifdef CONFIG_SA1100_ASSABET
+  if(machine_is_assabet()) {
+    if(machine_has_neponset()) {
+#ifdef CONFIG_ASSABET_NEPONSET
+      pcmcia_low_level = &neponset_pcmcia_ops;
+#else
+      printk(KERN_ERR "Card Services disabled: missing Neponset support\n");
+      return -1;
+#endif
+    } else
+      pcmcia_low_level = &assabet_pcmcia_ops;
+  }
+#endif
+#ifdef CONFIG_SA1100_BADGE4
+  if (machine_is_badge4())
+    pcmcia_low_level = &badge4_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_FREEBIRD
+  if (machine_is_freebird())
+    pcmcia_low_level = &freebird_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_H3600
+  if (machine_is_h3600())
+    pcmcia_low_level = &h3600_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_CERF
+  if (machine_is_cerf())
+    pcmcia_low_level = &cerf_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+  if (machine_is_graphicsclient())
+    pcmcia_low_level = &gcplus_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_XP860
+  if (machine_is_xp860())
+    pcmcia_low_level = &xp860_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_YOPY
+  if (machine_is_yopy())
+    pcmcia_low_level = &yopy_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_SHANNON
+  if (machine_is_shannon())
+    pcmcia_low_level = &shannon_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_PANGOLIN
+  if (machine_is_pangolin())
+    pcmcia_low_level = &pangolin_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_JORNADA720
+  if (machine_is_jornada720())
+    pcmcia_low_level = &jornada720_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_PFS168
+  if(machine_is_pfs168())
+    pcmcia_low_level = &pfs168_pcmcia_ops;
 #endif
+#ifdef CONFIG_SA1100_FLEXANET
+  if(machine_is_flexanet())
+    pcmcia_low_level = &flexanet_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_SIMPAD
+  if(machine_is_simpad())
+    pcmcia_low_level = &simpad_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_GRAPHICSMASTER
+  if(machine_is_graphicsmaster())
+    pcmcia_low_level = &graphicsmaster_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_ADSBITSY
+  if(machine_is_adsbitsy())
+    pcmcia_low_level = &adsbitsy_pcmcia_ops;
+#endif
+#ifdef CONFIG_SA1100_STORK
+  if(machine_is_stork())
+    pcmcia_low_level = &stork_pcmcia_ops;
+#endif
+
+  if (!pcmcia_low_level) {
+    printk(KERN_ERR "This hardware is not supported by the SA1100 Card Service driver\n");
+    return -ENODEV;
+  }
+
+  return 0;
+}
+
+/* sa1100_pcmcia_driver_init()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ *
+ * This routine performs a basic sanity check to ensure that this
+ * kernel has been built with the appropriate board-specific low-level
+ * PCMCIA support, performs low-level PCMCIA initialization, registers
+ * this socket driver with Card Services, and then spawns the daemon
+ * thread which is the real workhorse of the socket driver.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int __init sa1100_pcmcia_driver_init(void)
+{
+  servinfo_t info;
+  struct pcmcia_init pcmcia_init;
+  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+  struct pcmcia_state_array state_array;
+  unsigned int i, clock;
+  unsigned long mecr;
+  int ret;
+
+  printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);
+
+  CardServices(GetCardServicesInfo, &info);
+
+  if (info.Revision != CS_RELEASE_CODE) {
+    printk(KERN_ERR "Card Services release codes do not match\n");
+    return -EINVAL;
+  }
+
+  ret = sa1100_pcmcia_machine_init();
+  if (ret)
+    return ret;
+
+  pcmcia_init.handler = sa1100_pcmcia_interrupt;
+
+  ret = pcmcia_low_level->init(&pcmcia_init);
+  if (ret < 0) {
+    printk(KERN_ERR "Unable to initialize kernel PCMCIA service (%d).\n", ret);
+    return ret == -1 ? -EIO : ret;
+  }
+
+  sa1100_pcmcia_socket_count = ret;
+  state_array.size  = sa1100_pcmcia_socket_count;
+  state_array.state = state;
+
+  memset(state, 0, sizeof(state));
+
+  if (pcmcia_low_level->socket_state(&state_array) < 0) {
+    pcmcia_low_level->shutdown();
+    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+    return -EIO;
+  }
+
+  /*
+   * We initialize the MECR to default values here, because we are
+   * not guaranteed to see a SetIOMap operation at runtime.
+   */
+  mecr = 0;
+
+  clock = cpufreq_get(0);
+
+  for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
+    struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+    struct pcmcia_irq_info irq_info;
+
+    if (!request_mem_region(_PCMCIA(i), PCMCIASp, "PCMCIA")) {
+      ret = -EBUSY;
+      goto out_err;
+    }
+
+    irq_info.sock = i;
+    irq_info.irq  = -1;
+    ret = pcmcia_low_level->get_irq_info(&irq_info);
+    if (ret < 0)
+      printk(KERN_ERR "Unable to get IRQ for socket %u (%d)\n", i, ret);
+
+    skt->irq        = irq_info.irq;
+    skt->k_state    = state[i];
+    skt->speed_io   = SA1100_PCMCIA_IO_ACCESS;
+    skt->speed_attr = SA1100_PCMCIA_5V_MEM_ACCESS;
+    skt->speed_mem  = SA1100_PCMCIA_5V_MEM_ACCESS;
+    skt->phys_attr  = _PCMCIAAttr(i);
+    skt->phys_mem   = _PCMCIAMem(i);
+    skt->virt_io    = ioremap(_PCMCIAIO(i), 0x10000);
+
+    if (skt->virt_io == NULL) {
+      ret = -ENOMEM;
+      goto out_err;
+    }
 
+    MECR_FAST_SET(mecr, i, 0);
+    MECR_BSIO_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_io, clock));
+    MECR_BSA_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_attr, clock));
+    MECR_BSM_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_mem, clock));
+  }
+
+  MECR = mecr;
+
+#ifdef CONFIG_CPU_FREQ
+  ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block);
+  if (ret < 0) {
+    printk(KERN_ERR "Unable to register CPU frequency change notifier (%d)\n", ret);
+    goto out_err;
+  }
+#endif
+
+  /* Only advertise as many sockets as we can detect */
+  ret = register_ss_entry(sa1100_pcmcia_socket_count,
+			  &sa1100_pcmcia_operations);
+  if (ret < 0) {
+    printk(KERN_ERR "Unable to register sockets\n");
+    goto out_err;
+  }
+
+  /*
+   * Start the event poll timer.  It will reschedule by itself afterwards.
+   */
+  sa1100_pcmcia_poll_event(0);
+
+  return 0;
+
+ out_err:
+  for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
+    iounmap(sa1100_pcmcia_socket[i].virt_io);
+    release_mem_region(_PCMCIA(i), PCMCIASp);
+  }
+
+  pcmcia_low_level->shutdown();
+
+  return ret;
+}  /* sa1100_pcmcia_driver_init() */
+
+/* sa1100_pcmcia_driver_shutdown()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Invokes the low-level kernel service to free IRQs associated with this
+ * socket controller and reset GPIO edge detection.
+ */
+static void __exit sa1100_pcmcia_driver_shutdown(void)
+{
+  int i;
+
+  del_timer_sync(&poll_timer);
+
+  unregister_ss_entry(&sa1100_pcmcia_operations);
+
+#ifdef CONFIG_CPU_FREQ
+  cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block);
+#endif
+
+  for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
+    iounmap(sa1100_pcmcia_socket[i].virt_io);
+    release_mem_region(_PCMCIA(i), PCMCIASp);
+  }
+
+  pcmcia_low_level->shutdown();
+
+  flush_scheduled_tasks();
+}
+
+MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-1100 Socket Controller");
+MODULE_LICENSE("Dual MPL/GPL");
+
+module_init(sa1100_pcmcia_driver_init);
+module_exit(sa1100_pcmcia_driver_shutdown);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_generic.h linux/drivers/pcmcia/sa1100_generic.h
--- linux.orig/drivers/pcmcia/sa1100_generic.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_generic.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,76 @@
+/*
+ * linux/include/asm/arch/pcmcia.h
+ *
+ * Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
+ *
+ * This file contains definitions for the low-level SA-1100 kernel PCMCIA
+ * interface. Please see linux/Documentation/arm/SA1100/PCMCIA for details.
+ */
+#ifndef _ASM_ARCH_PCMCIA
+#define _ASM_ARCH_PCMCIA
+
+/* Ideally, we'd support up to MAX_SOCK sockets, but the SA-1100 only
+ * has support for two. This shows up in lots of hardwired ways, such
+ * as the fact that MECR only has enough bits to configure two sockets.
+ * Since it's so entrenched in the hardware, limiting the software
+ * in this way doesn't seem too terrible.
+ */
+#define SA1100_PCMCIA_MAX_SOCK   (2)
+
+struct pcmcia_init {
+  void (*handler)(int irq, void *dev, struct pt_regs *regs);
+};
+
+struct pcmcia_state {
+  unsigned detect: 1,
+            ready: 1,
+             bvd1: 1,
+             bvd2: 1,
+           wrprot: 1,
+            vs_3v: 1,
+            vs_Xv: 1;
+};
+
+struct pcmcia_state_array {
+  unsigned int size;
+  struct pcmcia_state *state;
+};
+
+struct pcmcia_configure {
+  unsigned sock: 8,
+            vcc: 8,
+            vpp: 8,
+         output: 1,
+        speaker: 1,
+          reset: 1,
+            irq: 1;
+};
+
+struct pcmcia_irq_info {
+  unsigned int sock;
+  unsigned int irq;
+};
+
+struct pcmcia_low_level {
+  int (*init)(struct pcmcia_init *);
+  int (*shutdown)(void);
+  int (*socket_state)(struct pcmcia_state_array *);
+  int (*get_irq_info)(struct pcmcia_irq_info *);
+  int (*configure_socket)(const struct pcmcia_configure *);
+
+  /*
+   * Enable card status IRQs on (re-)initialisation.  This can
+   * be called at initialisation, power management event, or
+   * pcmcia event.
+   */
+  int (*socket_init)(int sock);
+
+  /*
+   * Disable card status IRQs and PCMCIA bus on suspend.
+   */
+  int (*socket_suspend)(int sock);
+};
+
+extern struct pcmcia_low_level *pcmcia_low_level;
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_graphicsclient.c linux/drivers/pcmcia/sa1100_graphicsclient.c
--- linux.orig/drivers/pcmcia/sa1100_graphicsclient.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_graphicsclient.c	2002-07-20 01:08:22.000000000 +0000
@@ -17,7 +17,9 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
+
+#error This is broken!
 
 #define	S0_CD_IRQ		60				// Socket 0 Card Detect IRQ
 #define	S0_STS_IRQ		55				// Socket 0 PCMCIA IRQ
@@ -144,11 +146,24 @@
   return 0;
 }
 
+static int gcplus_pcmcia_socket_init(int sock)
+{
+  return 0;
+}
+
+static int gcplus_pcmcia_socket_suspend(int sock)
+{
+  return 0;
+}
+
 struct pcmcia_low_level gcplus_pcmcia_ops = { 
-  gcplus_pcmcia_init,
-  gcplus_pcmcia_shutdown,
-  gcplus_pcmcia_socket_state,
-  gcplus_pcmcia_get_irq_info,
-  gcplus_pcmcia_configure_socket
+  init:			gcplus_pcmcia_init,
+  shutdown:		gcplus_pcmcia_shutdown,
+  socket_state:		gcplus_pcmcia_socket_state,
+  get_irq_info:		gcplus_pcmcia_get_irq_info,
+  configure_socket:	gcplus_pcmcia_configure_socket,
+
+  socket_init:		gcplus_pcmcia_socket_init,
+  socket_suspend:	gcplus_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_graphicsmaster.c linux/drivers/pcmcia/sa1100_graphicsmaster.c
--- linux.orig/drivers/pcmcia/sa1100_graphicsmaster.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_graphicsmaster.c	2002-07-20 01:08:27.000000000 +0000
@@ -11,10 +11,10 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
-#include <asm/delay.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+
+#include "sa1100_generic.h"
+#include "sa1111_generic.h"
 
 static int graphicsmaster_pcmcia_init(struct pcmcia_init *init)
 {
@@ -26,190 +26,67 @@
   /* Disable Power 3.3V/5V for PCMCIA/CF */
   PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
 
-  INTPOL1 |= (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
-			 (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
-    		 (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-    		 (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-    		 (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-    		 (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
-
-  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
-			  "GC Master PCMCIA (0) CD", NULL);
-  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
-			  "GC Master CF (1) CD", NULL);
-  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "GC Master PCMCIA (0) BVD1", NULL);
-  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "GC Master CF (1) BVD1", NULL);
-
+  /* why? */
   MECR = 0x09430943;
 
-  return (return_val<0) ? -1 : 2;
-}
-
-static int graphicsmaster_pcmcia_shutdown(void)
-{
-
-  free_irq(S0_CD_VALID, NULL);
-  free_irq(S1_CD_VALID, NULL);
-  free_irq(S0_BVD1_STSCHG, NULL);
-  free_irq(S1_BVD1_STSCHG, NULL);
-
-  INTPOL1 &= ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-			   (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-      		   (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-      		   (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
-
-  return 0;
-}
-
-static int graphicsmaster_pcmcia_socket_state(struct pcmcia_state_array *state_array)
-{
-  unsigned long status;
-  int return_val=1;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0,
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  status=PCSR;
-
-  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
-
-  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
-
-  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
-
-  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
-
-  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
-
-  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
-
-  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
-
-  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
-
-  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
-
-  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
-
-  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
-
-  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
-
-  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
-
-  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
-
-  return return_val;
-}
-
-static int graphicsmaster_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-
-  switch(info->sock){
-  case 0:
-    info->irq=S0_READY_NINT;
-    break;
-
-  case 1:
-    info->irq=S1_READY_NINT;
-    break;
-
-  default:
-    return -1;
-  }
-
-  return 0;
+  return sa1111_pcmcia_init(init);
 }
 
-static int graphicsmaster_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int
+graphicsmaster_pcmcia_configure_socket(const struct pcmcia_configure *conf)
 {
-  unsigned long pccr=PCCR, gpio=PA_DWR;
+  unsigned int pa_dwr_mask, pa_dwr_set;
+  int ret;
 
-  switch(configure->sock){
+  switch (conf->sock) {
   case 0:
+    pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
 
-    switch(configure->vcc){
-    case 0:
-      pccr = (pccr & ~PCCR_S0_FLT);
-      gpio |= GPIO_GPIO0 | GPIO_GPIO1;
-      break;
-
-    case 33:
-      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
-      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
-	  gpio &= ~GPIO_GPIO0;
-      break;
-
-    case 50:
-      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
-      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
-	  gpio |= GPIO_GPIO0;
-      break;
-
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
+    case 0:	pa_dwr_set = GPIO_GPIO0 | GPIO_GPIO1;	break;
+    case 33:	pa_dwr_set = GPIO_GPIO1;		break;
+    case 50:	pa_dwr_set = GPIO_GPIO0;		break;
     }
-
-    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
-
     break;
 
   case 1:
-    switch(configure->vcc){
-    case 0:
-      pccr = (pccr & ~PCCR_S1_FLT);
-      gpio |= GPIO_GPIO2 | GPIO_GPIO3;
-      break;
-
-    case 33:
-      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
-      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
-	  gpio &= ~GPIO_GPIO2;
-      break;
-
-    case 50:
-      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
-      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
-	  gpio |= GPIO_GPIO2;
-      break;
+    pa_dwr_mask = GPIO_GPIO2 | GPIO_GPIO3;
 
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
-    }
-
-    if(configure->vpp!=configure->vcc && configure->vpp!=0){
-      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
-	     configure->vpp);
-      return -1;
+    case 0:	pa_dwr_set = GPIO_GPIO2 | GPIO_GPIO3;	break;
+    case 33:	pa_dwr_set = GPIO_GPIO3;		break;
+    case 50:	pa_dwr_set = GPIO_GPIO2;		break;
     }
+  }
 
-    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
-
-    break;
-
-  default:
+  if (conf->vpp != conf->vcc && conf->vpp != 0) {
+    printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+	   conf->vpp);
     return -1;
   }
 
-  PCCR = pccr;
-  PA_DWR = gpio;
+  ret = sa1111_pcmcia_configure_socket(conf);
+  if (ret == 0) {
+    unsigned long flags;
+
+    local_irq_save(flags);
+    PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
+    local_irq_restore(flags);
+  }
 
-  return 0;
+  return ret;
 }
 
 struct pcmcia_low_level graphicsmaster_pcmcia_ops = {
-  graphicsmaster_pcmcia_init,
-  graphicsmaster_pcmcia_shutdown,
-  graphicsmaster_pcmcia_socket_state,
-  graphicsmaster_pcmcia_get_irq_info,
-  graphicsmaster_pcmcia_configure_socket
+  init:			graphicsmaster_pcmcia_init,
+  shutdown:		sa1111_pcmcia_shutdown,
+  socket_state:		sa1111_pcmcia_socket_state,
+  get_irq_info:		sa1111_pcmcia_get_irq_info,
+  configure_socket:	graphicsmaster_pcmcia_configure_socket,
+
+  socket_init:		sa1111_pcmcia_socket_init,
+  socket_suspend:	sa1111_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_h3600.c linux/drivers/pcmcia/sa1100_h3600.c
--- linux.orig/drivers/pcmcia/sa1100_h3600.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_h3600.c	2002-07-20 01:08:27.000000000 +0000
@@ -9,139 +9,188 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
 
+static struct irqs {
+	int irq;
+	const char *str;
+} irqs[] = {
+	{ IRQ_GPIO_H3600_PCMCIA_CD0, "PCMCIA CD0" },
+	{ IRQ_GPIO_H3600_PCMCIA_CD1, "PCMCIA CD1" }
+};
 
-static int h3600_pcmcia_init(struct pcmcia_init *init){
-  int irq, res;
-
-  /* Enable CF bus: */
-  set_h3600_egpio(EGPIO_H3600_OPT_NVRAM_ON);
-  clr_h3600_egpio(EGPIO_H3600_OPT_RESET);
-
-  /* All those are inputs */
-  GPDR &= ~(GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1 | GPIO_H3600_PCMCIA_IRQ0| GPIO_H3600_PCMCIA_IRQ1);
-
-  /* Set transition detect */
-  set_GPIO_IRQ_edge( GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1, GPIO_BOTH_EDGES );
-  set_GPIO_IRQ_edge( GPIO_H3600_PCMCIA_IRQ0| GPIO_H3600_PCMCIA_IRQ1, GPIO_FALLING_EDGE );
-
-  /* Register interrupts */
-  irq = IRQ_GPIO_H3600_PCMCIA_CD0;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
-  if( res < 0 ) goto irq_err;
-  irq = IRQ_GPIO_H3600_PCMCIA_CD1;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
-  if( res < 0 ) goto irq_err;
+static int h3600_pcmcia_init(struct pcmcia_init *init)
+{
+	int i, res;
 
-  return 2;
+	/*
+	 * Set transition detect
+	 */
+	set_GPIO_IRQ_edge(GPIO_H3600_PCMCIA_IRQ0 | GPIO_H3600_PCMCIA_IRQ1,
+			  GPIO_FALLING_EDGE);
+
+	/*
+	 * Register interrupts
+	 */
+	for (i = res = 0; i < ARRAY_SIZE(irqs); i++) {
+		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+				  irqs[i].str, NULL);
+		if (res)
+			break;
+	}
+
+	if (res) {
+		printk(KERN_ERR "h3600_pcmcia: request for IRQ%d failed: %d\n",
+		       irqs[i].irq, res);
+
+		while (i--)
+			free_irq(irqs[i].irq, NULL);
+	}
 
-irq_err:
-  printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );
-  return -1;
+	return res ? -1 : 2;
 }
 
 static int h3600_pcmcia_shutdown(void)
 {
-  /* disable IRQs */
-  free_irq( IRQ_GPIO_H3600_PCMCIA_CD0, NULL );
-  free_irq( IRQ_GPIO_H3600_PCMCIA_CD1, NULL );
+	int i;
+
+	/*
+	 * disable IRQs
+	 */
+	for (i = 0; i < ARRAY_SIZE(irqs); i++)
+		free_irq(irqs[i].irq, NULL);
   
-  /* Disable CF bus: */
-  clr_h3600_egpio(EGPIO_H3600_OPT_NVRAM_ON|EGPIO_H3600_OPT_ON);
-  set_h3600_egpio(EGPIO_H3600_OPT_RESET);
+	/* Disable CF bus: */
+	clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
+	clr_h3600_egpio(IPAQ_EGPIO_OPT_ON);
+	set_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
 
-  return 0;
+	return 0;
 }
 
-static int h3600_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
+static int
+h3600_pcmcia_socket_state(struct pcmcia_state_array *state)
+{
+	unsigned long levels;
 
-  levels=GPLR;
+	if (state->size < 2)
+		return -1;
 
-  state_array->state[0].detect=((levels & GPIO_H3600_PCMCIA_CD0)==0)?1:0;
-  state_array->state[0].ready=(levels & GPIO_H3600_PCMCIA_IRQ0)?1:0;
-  state_array->state[0].bvd1= 0;
-  state_array->state[0].bvd2= 0;
-  state_array->state[0].wrprot=0; /* Not available on H3600. */
-  state_array->state[0].vs_3v=0;
-  state_array->state[0].vs_Xv=0;
+	levels = GPLR;
 
-  state_array->state[1].detect=((levels & GPIO_H3600_PCMCIA_CD1)==0)?1:0;
-  state_array->state[1].ready=(levels & GPIO_H3600_PCMCIA_IRQ1)?1:0;
-  state_array->state[1].bvd1=0;
-  state_array->state[1].bvd2=0;
-  state_array->state[1].wrprot=0; /* Not available on H3600. */
-  state_array->state[1].vs_3v=0;
-  state_array->state[1].vs_Xv=0;
+	state->state[0].detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
+	state->state[0].ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
+	state->state[0].bvd1 = 0;
+	state->state[0].bvd2 = 0;
+	state->state[0].wrprot = 0; /* Not available on H3600. */
+	state->state[0].vs_3v = 0;
+	state->state[0].vs_Xv = 0;
+
+	state->state[1].detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
+	state->state[1].ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
+	state->state[1].bvd1 = 0;
+	state->state[1].bvd2 = 0;
+	state->state[1].wrprot = 0; /* Not available on H3600. */
+	state->state[1].vs_3v = 0;
+	state->state[1].vs_Xv = 0;
 
-  return 1;
+	return 1;
 }
 
-static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  switch (info->sock) {
-  case 0:
-    info->irq=IRQ_GPIO_H3600_PCMCIA_IRQ0;
-    break;
-  case 1:
-    info->irq=IRQ_GPIO_H3600_PCMCIA_IRQ1;
-    break;
-  default:
-    return -1;
-  }
-  return 0;
+static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+	switch (info->sock) {
+	case 0:
+		info->irq = IRQ_GPIO_H3600_PCMCIA_IRQ0;
+		break;
+	case 1:
+		info->irq = IRQ_GPIO_H3600_PCMCIA_IRQ1;
+		break;
+	default:
+		return -1;
+	}
+	return 0;
 }
 
-static int h3600_pcmcia_configure_socket(const struct pcmcia_configure
-					   *configure)
+static int
+h3600_pcmcia_configure_socket(const struct pcmcia_configure *conf)
 {
-  unsigned long flags;
-
-  if(configure->sock>1) return -1;
+	if (conf->sock > 1)
+		return -1;
 
-  save_flags_cli(flags);
+	if (conf->vcc != 0 && conf->vcc != 33 && conf->vcc != 50) {
+		printk(KERN_ERR "h3600_pcmcia: unrecognized Vcc %u.%uV\n",
+		       conf->vcc / 10, conf->vcc % 10);
+		return -1;
+	}
+
+	if (conf->reset)
+		set_h3600_egpio(IPAQ_EGPIO_CARD_RESET);
+	else
+		clr_h3600_egpio(IPAQ_EGPIO_CARD_RESET);
 
-  switch (configure->vcc) {
-  case 0:
-    clr_h3600_egpio(EGPIO_H3600_OPT_ON);
-    break;
+	/* Silently ignore Vpp, output enable, speaker enable. */
 
-  case 33:
-  case 50:
-    set_h3600_egpio(EGPIO_H3600_OPT_ON);
-    break;
-
-  default:
-    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	   configure->vcc);
-    restore_flags(flags);
-    return -1;
-  }
+	return 0;
+}
 
-  if (configure->reset)
-    set_h3600_egpio(EGPIO_H3600_CARD_RESET);
-  else
-    clr_h3600_egpio(EGPIO_H3600_CARD_RESET);
+static int h3600_pcmcia_socket_init(int sock)
+{
+	/* Enable CF bus: */
+	set_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
+	set_h3600_egpio(IPAQ_EGPIO_OPT_ON);
+	clr_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(10*HZ / 1000);
+
+	switch (sock) {
+	case 0:
+		set_GPIO_IRQ_edge(GPIO_H3600_PCMCIA_CD0, GPIO_BOTH_EDGES);
+		break;
+	case 1:
+		set_GPIO_IRQ_edge(GPIO_H3600_PCMCIA_CD1, GPIO_BOTH_EDGES);
+		break;
+	}
 
-  /* Silently ignore Vpp, output enable, speaker enable. */
+	return 0;
+}
 
-  restore_flags(flags);
+static int h3600_pcmcia_socket_suspend(int sock)
+{
+	switch (sock) {
+	case 0:
+		set_GPIO_IRQ_edge(GPIO_H3600_PCMCIA_CD0, GPIO_NO_EDGES);
+		break;
+	case 1:
+		set_GPIO_IRQ_edge(GPIO_H3600_PCMCIA_CD1, GPIO_NO_EDGES);
+		break;
+	}
+
+	/*
+	 * FIXME:  This doesn't fit well.  We don't have the mechanism in
+	 * the generic PCMCIA layer to deal with the idea of two sockets
+	 * on one bus.  We rely on the cs.c behaviour shutting down
+	 * socket 0 then socket 1.
+	 */
+	if (sock == 1) {
+		clr_h3600_egpio(IPAQ_EGPIO_OPT_ON);
+		clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
+		/* hmm, does this suck power? */
+		set_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+	}
 
-  return 0;
+	return 0;
 }
 
 struct pcmcia_low_level h3600_pcmcia_ops = { 
-  h3600_pcmcia_init,
-  h3600_pcmcia_shutdown,
-  h3600_pcmcia_socket_state,
-  h3600_pcmcia_get_irq_info,
-  h3600_pcmcia_configure_socket
+	init:			h3600_pcmcia_init,
+	shutdown:		h3600_pcmcia_shutdown,
+	socket_state:		h3600_pcmcia_socket_state,
+	get_irq_info:		h3600_pcmcia_get_irq_info,
+	configure_socket:	h3600_pcmcia_configure_socket,
+
+	socket_init:		h3600_pcmcia_socket_init,
+	socket_suspend:		h3600_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_jornada720.c linux/drivers/pcmcia/sa1100_jornada720.c
--- linux.orig/drivers/pcmcia/sa1100_jornada720.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_jornada720.c	2002-07-20 01:08:34.000000000 +0000
@@ -7,20 +7,22 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
-#include <asm/delay.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+
+#include "sa1100_generic.h"
+#include "sa1111_generic.h"
 
 #define SOCKET0_POWER   GPIO_GPIO0
 #define SOCKET0_3V      GPIO_GPIO2
 #define SOCKET1_POWER   (GPIO_GPIO1 | GPIO_GPIO3)
-#define SOCKET1_3V   GPIO_GPIO3
+#warning *** Does SOCKET1_3V actually do anything?
+#define SOCKET1_3V	GPIO_GPIO3
 
 static int jornada720_pcmcia_init(struct pcmcia_init *init)
 {
-  int return_val=0;
-
+  /*
+   * What is all this crap for?
+   */
   GRER |= 0x00000002;
   /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
   PA_DDR = 0;
@@ -38,178 +40,68 @@
   PC_SDR = 0;
   PC_SSR = 0;
 
-  INTPOL1 |=
-    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
-    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
-    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
-
-  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
-			  "Jornada720 PCMCIA (0) CD", NULL);
-  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
-			  "Jornada720 CF (1) CD", NULL);
-  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "Jornada720 PCMCIA (0) BVD1", NULL);
-  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "Jornada720 CF (1) BVD1", NULL);
-
-  return (return_val<0) ? -1 : 2;
+  return sa1111_pcmcia_init(init);
 }
 
-static int jornada720_pcmcia_shutdown(void)
+static int
+jornada720_pcmcia_configure_socket(const struct pcmcia_configure *conf)
 {
-  free_irq(S0_CD_VALID, NULL);
-  free_irq(S1_CD_VALID, NULL);
-  free_irq(S0_BVD1_STSCHG, NULL);
-  free_irq(S1_BVD1_STSCHG, NULL);
-
-  INTPOL1 &=
-    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
-
-  return 0;
-}
-
-static int jornada720_pcmcia_socket_state(struct pcmcia_state_array
-					*state_array)
-{
-  unsigned long status;
-  int return_val=1;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0,
-	 (state_array->size)*sizeof(struct pcmcia_state));
-  status=PCSR;
-  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
-  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
-  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
-  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
-  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
-  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
-  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
-  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
-  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
-  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
-  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
-  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
-  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
-  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
-  return return_val;
-}
-
-static int jornada720_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-  switch(info->sock){
-  case 0:
-    info->irq=S0_READY_NINT;
-    break;
-
-  case 1:
-    info->irq=S1_READY_NINT;
-    break;
-
-  default:
-    return -1;
-  }
-  return 0;
-}
-
-static int jornada720_pcmcia_configure_socket(const struct pcmcia_configure
-					    *configure)
-{
-  unsigned long pccr=PCCR, gpio=PA_DWR;
+  unsigned int pa_dwr_mask, pa_dwr_set;
+  int ret;
 
 printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
-	       configure->sock, configure->vcc, configure->vpp);
-  switch(configure->sock){
+	       conf->sock, conf->vcc, conf->vpp);
+
+  switch (conf->sock) {
   case 0:
-    switch(configure->vcc){
-    case 0:
-      pccr = (pccr & ~PCCR_S0_FLT);
-      gpio&=~(SOCKET0_POWER | SOCKET0_3V);
-      break;
-
-    case 33:
-      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
-      gpio |= SOCKET0_POWER | SOCKET0_3V;
-      break;
-
-    case 50:
-      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
-      gpio = (gpio & ~SOCKET0_3V) | SOCKET0_POWER;
-      break;
+    pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
 
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
-    }
-    switch(configure->vpp){
-    case 0:
-      break;
-    case 50:
-	printk(KERN_ERR "%s(): 5.0 Vpp %u\n", __FUNCTION__,
-	       configure->vpp);
-      break;
-    case 120:
-	printk(KERN_ERR "%s(): 12 Vpp %u\n", __FUNCTION__,
-	       configure->vpp);
-      break;
-    default:
-	printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
-	       configure->vpp);
-	return -1;
+    case 0:	pa_dwr_set = 0;					break;
+    case 33:	pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;	break;
+    case 50:	pa_dwr_set = SOCKET0_POWER;			break;
     }
-    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
     break;
 
   case 1:
-    switch(configure->vcc){
-    case 0:
-      pccr = (pccr & ~PCCR_S1_FLT);
-      gpio &= ~(SOCKET1_POWER);
-      break;
-
-    case 33:
-      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
-      gpio |= SOCKET1_POWER;
-      break;
-
-    case 50:
-      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
-      gpio = (gpio & ~(SOCKET1_POWER)) | SOCKET1_POWER;
-      break;
+    pa_dwr_mask = SOCKET1_POWER;
 
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
-    }
-    if(configure->vpp!=configure->vcc && configure->vpp!=0){
-      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
-	     configure->vpp);
-      return -1;
+    case 0:	pa_dwr_set = 0;					break;
+    case 33:	pa_dwr_set = SOCKET1_POWER;			break;
+    case 50:	pa_dwr_set = SOCKET1_POWER;			break;
     }
-    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
     break;
-  default:
+  }
+
+  if (conf->vpp != conf->vcc && conf->vpp != 0) {
+    printk(KERN_ERR "%s(): slot cannot support VPP %u\n",
+	   __FUNCTION__, conf->vpp);
     return -1;
   }
-  PCCR = pccr;
-  PA_DWR = gpio;
-  return 0;
+
+  ret = sa1111_pcmcia_configure_socket(conf);
+  if (ret == 0) {
+    unsigned long flags;
+
+    local_irq_save(flags);
+    PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
+    locla_irq_restore(flags);
+  }
+
+  return ret;
 }
 
 struct pcmcia_low_level jornada720_pcmcia_ops = {
-  jornada720_pcmcia_init,
-  jornada720_pcmcia_shutdown,
-  jornada720_pcmcia_socket_state,
-  jornada720_pcmcia_get_irq_info,
-  jornada720_pcmcia_configure_socket
+  init:			jornada720_pcmcia_init,
+  shutdown:		sa1111_pcmcia_shutdown,
+  socket_state:		sa1111_pcmcia_socket_state,
+  get_irq_info:		sa1111_pcmcia_get_irq_info,
+  configure_socket:	jornada720_pcmcia_configure_socket,
+
+  socket_init:		sa1111_pcmcia_socket_init,
+  socket_suspend:	sa1111_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_neponset.c linux/drivers/pcmcia/sa1100_neponset.c
--- linux.orig/drivers/pcmcia/sa1100_neponset.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_neponset.c	2002-07-20 01:08:39.000000000 +0000
@@ -1,249 +1,129 @@
 /*
- * drivers/pcmcia/sa1100_neponset.c
+ * linux/drivers/pcmcia/sa1100_neponset.c
  *
  * Neponset PCMCIA specific routines
- *
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
-#include <asm/delay.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
 #include <asm/arch/assabet.h>
+#include <asm/hardware/sa1111.h>
 
-static int neponset_pcmcia_init(struct pcmcia_init *init){
-  int return_val=0;
-
-  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
-  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
-  
-  /* MAX1600 to standby mode: */
-  PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
-  NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
-
-  INTPOL1 |= 
-    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
-    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
-    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
-
-  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
-			  "Neponset PCMCIA (0) CD", NULL);
-  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
-			  "Neponset CF (1) CD", NULL);
-  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "Neponset PCMCIA (0) BVD1", NULL);
-  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "Neponset CF (1) BVD1", NULL);
-
-  return (return_val<0) ? -1 : 2;
-}
-
-static int neponset_pcmcia_shutdown(void){
-
-  free_irq(S0_CD_VALID, NULL);
-  free_irq(S1_CD_VALID, NULL);
-  free_irq(S0_BVD1_STSCHG, NULL);
-  free_irq(S1_BVD1_STSCHG, NULL);
-
-  INTPOL1 &= 
-    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
-
-  return 0;
-}
-
-static int neponset_pcmcia_socket_state(struct pcmcia_state_array
-					*state_array){
-  unsigned long status;
-  int return_val=1;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  status=PCSR;
-
-  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
-
-  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+#include "sa1100_generic.h"
+#include "sa1111_generic.h"
 
-  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+static int neponset_pcmcia_init(struct pcmcia_init *init)
+{
+	/* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+	PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
 
-  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+	/* MAX1600 to standby mode: */
+	PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+	NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
 
-  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
-
-  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
-
-  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
-
-  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
-
-  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
-
-  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
-
-  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
-
-  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
-
-  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
-
-  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
-
-  return return_val;
+	return sa1111_pcmcia_init(init);
 }
 
-static int neponset_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  switch(info->sock){
-  case 0:
-    info->irq=S0_READY_NINT;
-    break;
-
-  case 1:
-    info->irq=S1_READY_NINT;
-    break;
-
-  default:
-    return -1;
-  }
+static int
+neponset_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+{
+	unsigned int ncr_mask, pa_dwr_mask;
+	unsigned int ncr_set, pa_dwr_set;
+	int ret;
+
+	/* Neponset uses the Maxim MAX1600, with the following connections:
+
+	 *   MAX1600      Neponset
+	 *
+	 *    A0VCC        SA-1111 GPIO A<1>
+	 *    A1VCC        SA-1111 GPIO A<0>
+	 *    A0VPP        CPLD NCR A0VPP
+	 *    A1VPP        CPLD NCR A1VPP
+	 *    B0VCC        SA-1111 GPIO A<2>
+	 *    B1VCC        SA-1111 GPIO A<3>
+	 *    B0VPP        ground (slot B is CF)
+	 *    B1VPP        ground (slot B is CF)
+	 *
+	 *     VX          VCC (5V)
+	 *     VY          VCC3_3 (3.3V)
+	 *     12INA       12V
+	 *     12INB       ground (slot B is CF)
+	 *
+	 * The MAX1600 CODE pin is tied to ground, placing the device in 
+	 * "Standard Intel code" mode. Refer to the Maxim data sheet for
+	 * the corresponding truth table.
+	 */
+
+	switch (conf->sock) {
+	case 0:
+		pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
+		ncr_mask = NCR_A0VPP | NCR_A1VPP;
+
+		switch (conf->vcc) {
+		default:
+		case 0:		pa_dwr_set = 0;			break;
+		case 33:	pa_dwr_set = GPIO_GPIO1;	break;
+		case 50:	pa_dwr_set = GPIO_GPIO0;	break;
+		}
+
+		switch (conf->vpp) {
+		case 0:		ncr_set = 0;			break;
+		case 120:	ncr_set = NCR_A1VPP;		break;
+		default:
+			if (conf->vpp == conf->vcc)
+				ncr_set = NCR_A0VPP;
+			else {
+				printk(KERN_ERR "%s(): unrecognized VPP %u\n",
+				       __FUNCTION__, conf->vpp);
+				return -1;
+			}
+		}
+		break;
+
+	case 1:
+		pa_dwr_mask = GPIO_GPIO2 | GPIO_GPIO3;
+		ncr_mask = 0;
+		ncr_set = 0;
+
+		switch (conf->vcc) {
+		default:
+		case 0:		pa_dwr_set = 0;			break;
+		case 33:	pa_dwr_set = GPIO_GPIO2;	break;
+		case 50:	pa_dwr_set = GPIO_GPIO3;	break;
+		}
+
+		if (conf->vpp != conf->vcc && conf->vpp != 0) {
+			printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
+			       __FUNCTION__, conf->vpp);
+			return -1;
+		}
+		break;
+
+	default:
+		return -1;
+	}
+
+	ret = sa1111_pcmcia_configure_socket(conf);
+	if (ret == 0) {
+		unsigned long flags;
+
+		local_irq_save(flags);
+		NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
+		PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
+		local_irq_restore(flags);
+	}
 
-  return 0;
+	return 0;
 }
 
-static int neponset_pcmcia_configure_socket(const struct pcmcia_configure
-					    *configure){
-  unsigned long pccr=PCCR, ncr=NCR_0, gpio=PA_DWR;
-
-  /* Neponset uses the Maxim MAX1600, with the following connections:
-   *
-   *   MAX1600      Neponset
-   *
-   *    A0VCC        SA-1111 GPIO A<1>
-   *    A1VCC        SA-1111 GPIO A<0>
-   *    A0VPP        CPLD NCR A0VPP
-   *    A1VPP        CPLD NCR A1VPP
-   *    B0VCC        SA-1111 GPIO A<2>
-   *    B1VCC        SA-1111 GPIO A<3>
-   *    B0VPP        ground (slot B is CF)
-   *    B1VPP        ground (slot B is CF)
-   *
-   *     VX          VCC (5V)
-   *     VY          VCC3_3 (3.3V)
-   *     12INA       12V
-   *     12INB       ground (slot B is CF)
-   *
-   * The MAX1600 CODE pin is tied to ground, placing the device in 
-   * "Standard Intel code" mode. Refer to the Maxim data sheet for
-   * the corresponding truth table.
-   */
-
-  switch(configure->sock){
-  case 0:
-    
-    switch(configure->vcc){
-    case 0:
-      pccr=(pccr & ~PCCR_S0_FLT);
-      gpio&=~(GPIO_GPIO0 | GPIO_GPIO1);
-      break;
-
-    case 33:
-      pccr=(pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
-      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
-      break;
-
-    case 50:
-      pccr=(pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
-      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
-      break;
-
-    default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
-    }
-
-    switch(configure->vpp){
-    case 0:
-      ncr&=~(NCR_A0VPP | NCR_A1VPP);
-      break;
-
-    case 120:
-      ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A1VPP;
-      break;
-
-    default:
-      if(configure->vpp == configure->vcc)
-	ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A0VPP;
-      else {
-	printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
-	       configure->vpp);
-	return -1;
-      }
-    }
-
-    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
-
-    break;
-
-  case 1:
-    switch(configure->vcc){
-    case 0:
-      pccr=(pccr & ~PCCR_S1_FLT);
-      gpio&=~(GPIO_GPIO2 | GPIO_GPIO3);
-      break;
-
-    case 33:
-      pccr=(pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
-      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2;
-      break;
-
-    case 50:
-      pccr=(pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
-      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
-      break;
-
-    default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
-    }
-
-    if(configure->vpp!=configure->vcc && configure->vpp!=0){
-      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
-	     configure->vpp);
-      return -1;
-    }
-
-    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
-
-    break;
-
-  default:
-    return -1;
-  }
-
-  PCCR = pccr;
-  NCR_0 = ncr;
-  PA_DWR = gpio;
+struct pcmcia_low_level neponset_pcmcia_ops = {
+	init:			neponset_pcmcia_init,
+	shutdown:		sa1111_pcmcia_shutdown,
+	socket_state:		sa1111_pcmcia_socket_state,
+	get_irq_info:		sa1111_pcmcia_get_irq_info,
+	configure_socket:	neponset_pcmcia_configure_socket,
 
-  return 0;
-}
-
-struct pcmcia_low_level neponset_pcmcia_ops = { 
-  neponset_pcmcia_init,
-  neponset_pcmcia_shutdown,
-  neponset_pcmcia_socket_state,
-  neponset_pcmcia_get_irq_info,
-  neponset_pcmcia_configure_socket
+	socket_init:		sa1111_pcmcia_socket_init,
+	socket_suspend:		sa1111_pcmcia_socket_suspend,
 };
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_pangolin.c linux/drivers/pcmcia/sa1100_pangolin.c
--- linux.orig/drivers/pcmcia/sa1100_pangolin.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_pangolin.c	2002-07-20 01:08:24.000000000 +0000
@@ -9,22 +9,16 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
 
 static int pangolin_pcmcia_init(struct pcmcia_init *init){
   int irq, res;
 
-  /* set GPIO_PCMCIA_CD & GPIO_PCMCIA_IRQ as inputs */
-  GPDR &= ~(GPIO_PCMCIA_CD|GPIO_PCMCIA_IRQ);
 #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
-  /* set GPIO pins GPIO_PCMCIA_BUS_ON & GPIO_PCMCIA_RESET as output */
-  GPDR |= (GPIO_PCMCIA_BUS_ON|GPIO_PCMCIA_RESET);
   /* Enable PCMCIA bus: */
   GPCR = GPIO_PCMCIA_BUS_ON;
-#else
-  /* set GPIO pin GPIO_PCMCIA_RESET as output */
-  GPDR |= GPIO_PCMCIA_RESET;
 #endif
+
   /* Set transition detect */
   set_GPIO_IRQ_edge( GPIO_PCMCIA_CD, GPIO_BOTH_EDGES );
   set_GPIO_IRQ_edge( GPIO_PCMCIA_IRQ, GPIO_FALLING_EDGE );
@@ -147,11 +141,26 @@
   return 0;
 }
 
+static int pangolin_pcmcia_socket_init(int sock)
+{
+  /* enable card status IRQs - see sa1100_assabet.c for details  */
+  return -1;
+}
+
+static int pangolin_pcmcia_socket_suspend(int sock)
+{
+  /* disable card status IRQs - see sa1100_assabet.c for details */
+  return -1;
+}
+
 struct pcmcia_low_level pangolin_pcmcia_ops = { 
-  pangolin_pcmcia_init,
-  pangolin_pcmcia_shutdown,
-  pangolin_pcmcia_socket_state,
-  pangolin_pcmcia_get_irq_info,
-  pangolin_pcmcia_configure_socket
+  init:			pangolin_pcmcia_init,
+  shutdown:		pangolin_pcmcia_shutdown,
+  socket_state:		pangolin_pcmcia_socket_state,
+  get_irq_info:		pangolin_pcmcia_get_irq_info,
+  configure_socket:	pangolin_pcmcia_configure_socket,
+
+  socket_init:		pangolin_pcmcia_socket_init,
+  socket_suspend,	pangolin_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_pfs168.c linux/drivers/pcmcia/sa1100_pfs168.c
--- linux.orig/drivers/pcmcia/sa1100_pfs168.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_pfs168.c	2002-07-20 01:08:33.000000000 +0000
@@ -11,117 +11,26 @@
 #include <asm/delay.h>
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
 
-static int pfs168_pcmcia_init(struct pcmcia_init *init){
-  int return_val=0;
+#include "sa1100_generic.h"
+#include "sa1111_generic.h"
 
+static int pfs168_pcmcia_init(struct pcmcia_init *init)
+{
   /* TPS2211 to standby mode: */
   PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
 
   /* Set GPIO_A<3:0> to be outputs for PCMCIA (socket 0) power controller: */
   PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
 
-  INTPOL1 |=
-    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
-    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
-    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
-
-  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
-			  "PFS168 PCMCIA (0) CD", NULL);
-  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
-			  "PFS168 CF (1) CD", NULL);
-  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "PFS168 PCMCIA (0) BVD1", NULL);
-  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "PFS168 CF (1) BVD1", NULL);
-
-  return (return_val<0) ? -1 : 2;
-}
-
-static int pfs168_pcmcia_shutdown(void){
-
-  free_irq(S0_CD_VALID, NULL);
-  free_irq(S1_CD_VALID, NULL);
-  free_irq(S0_BVD1_STSCHG, NULL);
-  free_irq(S1_BVD1_STSCHG, NULL);
-
-  INTPOL1 &=
-    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
-
-  return 0;
-}
-
-static int pfs168_pcmcia_socket_state(struct pcmcia_state_array
-					*state_array){
-  unsigned long status;
-  int return_val=1;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0,
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  status=PCSR;
-
-  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
-
-  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
-
-  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
-
-  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
-
-  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
-
-  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
-
-  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
-
-  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
-
-  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
-
-  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
-
-  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
-
-  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
-
-  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
-
-  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
-
-  return return_val;
-}
-
-static int pfs168_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  switch(info->sock){
-  case 0:
-    info->irq=S0_READY_NINT;
-    break;
-
-  case 1:
-    info->irq=S1_READY_NINT;
-    break;
-
-  default:
-    return -1;
-  }
-
-  return 0;
+  return sa1111_pcmcia_init(init);
 }
 
-static int pfs168_pcmcia_configure_socket(const struct pcmcia_configure
-					    *configure){
-  unsigned long pccr=PCCR, gpio=PA_DWR;
+static int
+pfs168_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+{
+  unsigned int pa_dwr_mask = 0, pa_dwr_set = 0;
+  int ret;
 
   /* PFS168 uses the Texas Instruments TPS2211 for PCMCIA (socket 0) voltage control only,
    * with the following connections:
@@ -135,103 +44,85 @@
    *
    */
 
-  switch(configure->sock){
+  switch (conf->sock) {
   case 0:
+    pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
 
-    switch(configure->vcc){
-    case 0:
-      pccr = (pccr & ~PCCR_S0_FLT);
-      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
-      break;
-
-    case 33:
-      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
-      gpio = (gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
-      break;
-
-    case 50:
-      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
-      gpio = (gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
-      break;
-
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
+    case 0:	pa_dwr_set = 0;			break;
+    case 33:	pa_dwr_set = GPIO_GPIO0;	break;
+    case 50:	pa_dwr_set = GPIO_GPIO1;	break;
     }
 
-    switch(configure->vpp){
+    switch (conf->vpp) {
     case 0:
-      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
       break;
 
     case 120:
-      printk(KERN_ERR "%s(): PFS-168 does not support Vpp %uV\n", __FUNCTION__,
-	     configure->vpp/10);
+      printk(KERN_ERR "%s(): PFS-168 does not support VPP %uV\n",
+	     __FUNCTION__, conf->vpp / 10);
       return -1;
       break;
 
     default:
-      if(configure->vpp == configure->vcc)
-        gpio = (gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+      if (conf->vpp == conf->vcc)
+        pa_dwr_set |= GPIO_GPIO3;
       else {
-	printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
-	       configure->vpp);
+	printk(KERN_ERR "%s(): unrecognized VPP %u\n", __FUNCTION__,
+	       conf->vpp);
 	return -1;
       }
     }
-
-    pccr = (configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
-
-    PA_DWR = gpio;
-
     break;
 
   case 1:
-    switch(configure->vcc){
-    case 0:
-      pccr = (pccr & ~PCCR_S1_FLT);
-      break;
+    pa_dwr_mask = 0;
+    pa_dwr_set = 0;
 
+    switch (conf->vcc) {
+    case 0:
     case 33:
-      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
       break;
 
     case 50:
-      printk(KERN_ERR "%s(): PFS-168 CompactFlash socket does not support Vcc %uV\n", __FUNCTION__,
-	     configure->vcc/10);
+      printk(KERN_ERR "%s(): PFS-168 CompactFlash socket does not support VCC %uV\n",
+	     __FUNCTION__, conf->vcc / 10);
       return -1;
-      break;
 
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
+      printk(KERN_ERR "%s(): unrecognized VCC %u\n", __FUNCTION__,
+	     conf->vcc);
       return -1;
     }
 
-    if(configure->vpp!=configure->vcc && configure->vpp!=0){
-      printk(KERN_ERR "%s(): CompactFlash socket does not support Vpp %uV\n", __FUNCTION__,
-	     configure->vpp/10);
+    if (conf->vpp != conf->vcc && conf->vpp != 0) {
+      printk(KERN_ERR "%s(): CompactFlash socket does not support VPP %uV\n"
+	      __FUNCTION__, conf->vpp/10);
       return -1;
     }
-
-    pccr = (configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
-
     break;
-
-  default:
-    return -1;
   }
 
-  PCCR = pccr;
+  ret = sa1111_pcmcia_configure_socket(conf);
+  if (ret == 0) {
+    unsigned long flags;
+
+    local_irq_save(flags);
+    PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
+    local_irq_restore(flags);
+  }
 
   return 0;
 }
 
 struct pcmcia_low_level pfs168_pcmcia_ops = {
-  pfs168_pcmcia_init,
-  pfs168_pcmcia_shutdown,
-  pfs168_pcmcia_socket_state,
-  pfs168_pcmcia_get_irq_info,
-  pfs168_pcmcia_configure_socket
+  init:			pfs168_pcmcia_init,
+  shutdown:		sa1111_pcmcia_shutdown,
+  socket_state:		sa1111_pcmcia_socket_state,
+  get_irq_info:		sa1111_pcmcia_get_irq_info,
+  configure_socket:	pfs168_pcmcia_configure_socket,
+
+  socket_init:		sa1111_pcmcia_socket_init,
+  socket_suspend:	sa1111_pcmcia_socket_suspend,
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_shannon.c linux/drivers/pcmcia/sa1100_shannon.c
--- linux.orig/drivers/pcmcia/sa1100_shannon.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_shannon.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,144 @@
+/*
+ * drivers/pcmcia/sa1100_shannon.c
+ *
+ * PCMCIA implementation routines for Shannon
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/shannon.h>
+#include <asm/irq.h>
+#include "sa1100_generic.h"
+
+static int shannon_pcmcia_init(struct pcmcia_init *init)
+{
+	int irq, res;
+
+	/* All those are inputs */
+	GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
+		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
+	GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
+		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
+
+	/* Set transition detect */
+	set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1, GPIO_NO_EDGES);
+	set_GPIO_IRQ_edge(SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1, GPIO_FALLING_EDGE);
+
+	/* Register interrupts */
+	irq = SHANNON_IRQ_GPIO_EJECT_0;
+	res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA_CD_0", NULL);
+	if (res < 0) goto irq_err;
+	irq = SHANNON_IRQ_GPIO_EJECT_1;
+	res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA_CD_1", NULL);
+	if (res < 0) goto irq_err;
+
+	return 2;
+irq_err:
+	printk(KERN_ERR "%s: Request for IRQ %d failed\n", __FUNCTION__, irq);
+	return -1;
+}
+
+static int shannon_pcmcia_shutdown(void)
+{
+	/* disable IRQs */
+	free_irq(SHANNON_IRQ_GPIO_EJECT_0, NULL);
+	free_irq(SHANNON_IRQ_GPIO_EJECT_1, NULL);
+
+	return 0;
+}
+
+static int shannon_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+	unsigned long levels;
+
+	memset(state_array->state, 0,
+	       state_array->size * sizeof(struct pcmcia_state));
+
+	levels = GPLR;
+
+	state_array->state[0].detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
+	state_array->state[0].ready  = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
+	state_array->state[0].wrprot = 0; /* Not available on Shannon. */
+	state_array->state[0].bvd1 = 1; 
+	state_array->state[0].bvd2 = 1; 
+	state_array->state[0].vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
+	state_array->state[0].vs_Xv  = 0;
+
+	state_array->state[1].detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
+	state_array->state[1].ready  = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
+	state_array->state[1].wrprot = 0; /* Not available on Shannon. */
+	state_array->state[1].bvd1 = 1; 
+	state_array->state[1].bvd2 = 1; 
+	state_array->state[1].vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
+	state_array->state[1].vs_Xv  = 0;
+
+	return 1;
+}
+
+static int shannon_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+	if (info->sock == 0)
+		info->irq = SHANNON_IRQ_GPIO_RDY_0;
+	else if (info->sock == 1)
+		info->irq = SHANNON_IRQ_GPIO_RDY_1;
+	else return -1;
+	
+	return 0;
+}
+
+static int shannon_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+
+	switch (configure->vcc) {
+	case 0:	/* power off */;
+		printk(KERN_WARNING __FUNCTION__"(): CS asked for 0V, still applying 3.3V..\n");
+		break;
+	case 50:
+		printk(KERN_WARNING __FUNCTION__"(): CS asked for 5V, applying 3.3V..\n");
+	case 33:
+		break;
+	default:
+		printk(KERN_ERR __FUNCTION__"(): unrecognized Vcc %u\n",
+		       configure->vcc);
+		return -1;
+	}
+
+	printk(KERN_WARNING __FUNCTION__"(): Warning, Can't perform reset\n");
+	
+	/* Silently ignore Vpp, output enable, speaker enable. */
+
+	return 0;
+}
+
+static int shannon_pcmcia_socket_init(int sock)
+{
+	if (sock == 0)
+		set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_0, GPIO_BOTH_EDGES);
+	else if (sock == 1)
+		set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_1, GPIO_BOTH_EDGES);
+
+	return 0;
+}
+
+static int shannon_pcmcia_socket_suspend(int sock)
+{
+	if (sock == 0)
+		set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_0, GPIO_NO_EDGES);
+	else if (sock == 1)
+		set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_1, GPIO_NO_EDGES);
+
+	return 0;
+}
+
+struct pcmcia_low_level shannon_pcmcia_ops = {
+	init:			shannon_pcmcia_init,
+	shutdown:		shannon_pcmcia_shutdown,
+	socket_state:		shannon_pcmcia_socket_state,
+	get_irq_info:		shannon_pcmcia_get_irq_info,
+	configure_socket:	shannon_pcmcia_configure_socket,
+
+	socket_init:		shannon_pcmcia_socket_init,
+	socket_suspend:		shannon_pcmcia_socket_suspend,
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_simpad.c linux/drivers/pcmcia/sa1100_simpad.c
--- linux.orig/drivers/pcmcia/sa1100_simpad.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_simpad.c	2002-07-20 01:08:35.000000000 +0000
@@ -9,7 +9,7 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
  
 extern long get_cs3_shadow(void);
 extern void set_cs3_bit(int value); 
@@ -19,9 +19,6 @@
 static int simpad_pcmcia_init(struct pcmcia_init *init){
   int irq, res;
 
-  /* set GPIO_CF_CD & GPIO_CF_IRQ as inputs */
-  GPDR &= ~(GPIO_CF_CD|GPIO_CF_IRQ);
-  
   set_cs3_bit(PCMCIA_RESET);
   clear_cs3_bit(PCMCIA_BUFF_DIS);
   clear_cs3_bit(PCMCIA_RESET);
@@ -29,7 +26,7 @@
   clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
   /* Set transition detect */
-  set_GPIO_IRQ_edge( GPIO_CF_CD, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_CF_CD, GPIO_NO_EDGES );
   set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
 
   /* Register interrupts */
@@ -146,11 +143,26 @@
   return 0;
 }
 
+static int simpad_pcmcia_socket_init(int sock)
+{
+  set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_BOTH_EDGES);
+  return 0;
+}
+
+static int simpad_pcmcia_socket_suspend(int sock)
+{
+  set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_NO_EDGES);
+  return 0;
+}
+
 struct pcmcia_low_level simpad_pcmcia_ops = { 
-  simpad_pcmcia_init,
-  simpad_pcmcia_shutdown,
-  simpad_pcmcia_socket_state,
-  simpad_pcmcia_get_irq_info,
-  simpad_pcmcia_configure_socket
+  init:			simpad_pcmcia_init,
+  shutdown:		simpad_pcmcia_shutdown,
+  socket_state:		simpad_pcmcia_socket_state,
+  get_irq_info:		simpad_pcmcia_get_irq_info,
+  configure_socket:	simpad_pcmcia_configure_socket,
+
+  socket_init:		simpad_pcmcia_socket_init,
+  socket_suspend:	simpad_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_stork.c linux/drivers/pcmcia/sa1100_stork.c
--- linux.orig/drivers/pcmcia/sa1100_stork.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_stork.c	2002-07-20 01:08:37.000000000 +0000
@@ -28,7 +28,7 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
 
 static int debug = 0;
 
@@ -41,14 +41,8 @@
 
         sa1100_stork_pcmcia_init = *init;
 
-        /* Enable CF bus: */
-        storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
-
-        /* All those are inputs */
-	GPDR &= ~(GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT | GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY);
-
 	/* Set transition detect */
-	set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES );
+	set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES );
         set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY, GPIO_FALLING_EDGE );
 
 	/* Register interrupts */
@@ -192,11 +186,41 @@
         return 0;
 }
 
+static int stork_pcmcia_socket_init(int sock)
+{
+        storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+
+        if (sock == 0)
+		set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_BOTH_EDGES);
+        else if (sock == 1)
+		set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES);
+
+	return 0;
+}
+
+static int stork_pcmcia_socket_suspend(int sock)
+{
+        if (sock == 0)
+		set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_NO_EDGES);
+        else if (sock == 1) {
+		set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES);
+
+		/*
+		 * Hack!
+		 */
+	        storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+	}
+
+	return 0;
+}
+
 struct pcmcia_low_level stork_pcmcia_ops = { 
-        stork_pcmcia_init,
-        stork_pcmcia_shutdown,
-        stork_pcmcia_socket_state,
-        stork_pcmcia_get_irq_info,
-        stork_pcmcia_configure_socket
-};
+	init:			stork_pcmcia_init,
+	shutdown:		stork_pcmcia_shutdown,
+	socket_state:		stork_pcmcia_socket_state,
+	get_irq_info:		stork_pcmcia_get_irq_info,
+	configure_socket:	stork_pcmcia_configure_socket,
 
+	socket_init:		stork_pcmcia_socket_init,
+	socket_suspend:		stork_pcmcia_socket_suspend,
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_xp860.c linux/drivers/pcmcia/sa1100_xp860.c
--- linux.orig/drivers/pcmcia/sa1100_xp860.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_xp860.c	2002-07-20 01:08:33.000000000 +0000
@@ -10,125 +10,42 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
 
 #define NCR_A0VPP	(1<<16)
 #define NCR_A1VPP	(1<<17)
 
-static int xp860_pcmcia_init(struct pcmcia_init *init){
-  int return_val=0;
-
+static int xp860_pcmcia_init(struct pcmcia_init *init)
+{
   /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
   PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
   
   /* MAX1600 to standby mode: */
   PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+#error Consider the following comment
+  /*
+   * 1- Please move GPDR initialisation  where it is interrupt or preemption
+   *    safe (like from xp860_map_io).
+   * 2- The GPCR line is bogus i.e. it will simply have absolutely no effect.
+   *    Please see its definition in the SA1110 manual.
+   * 3- Please do not use NCR_* values!
+   */
   GPDR |= (NCR_A0VPP | NCR_A1VPP);
   GPCR &= ~(NCR_A0VPP | NCR_A1VPP);
 
-  INTPOL1 |= 
-    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
-    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
-    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
-
-  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
-			  "XP860 PCMCIA (0) CD", NULL);
-  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
-			  "XP860 CF (1) CD", NULL);
-  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "XP860 PCMCIA (0) BVD1", NULL);
-  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-			  "XP860 CF (1) BVD1", NULL);
-
-  return (return_val<0) ? -1 : 2;
+  return sa1111_pcmcia_init(init);
 }
 
-static int xp860_pcmcia_shutdown(void){
-
-  free_irq(S0_CD_VALID, NULL);
-  free_irq(S1_CD_VALID, NULL);
-  free_irq(S0_BVD1_STSCHG, NULL);
-  free_irq(S1_BVD1_STSCHG, NULL);
-
-  INTPOL1 &= 
-    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
-      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
-      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
-      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
-
-  return 0;
-}
-
-static int xp860_pcmcia_socket_state(struct pcmcia_state_array
-					*state_array){
-  unsigned long status;
-  int return_val=1;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  status=PCSR;
-
-  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
-
-  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
-
-  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
-
-  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
-
-  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
-
-  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
-
-  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
-
-  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
-
-  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
-
-  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
-
-  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
-
-  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
-
-  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
-
-  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
-
-  return return_val;
-}
-
-static int xp860_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  switch(info->sock){
-  case 0:
-    info->irq=S0_READY_NINT;
-    break;
-
-  case 1:
-    info->irq=S1_READY_NINT;
-    break;
-
-  default:
-    return -1;
-  }
-
-  return 0;
-}
-
-static int xp860_pcmcia_configure_socket(const struct pcmcia_configure
-					    *configure){
-  unsigned long pccr=PCCR, ncr=GPLR, gpio=PA_DWR;
-
+static int
+xp860_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+{
+  unsigned int gpio_mask, pa_dwr_mask;
+  unsigned int gpio_set, pa_dwr_set;
+  int ret;
 
   /* Neponset uses the Maxim MAX1600, with the following connections:
+#warning ^^^ This isn't a neponset!
    *
    *   MAX1600      Neponset
    *
@@ -151,105 +68,75 @@
    * the corresponding truth table.
    */
 
-  switch(configure->sock){
+  switch (conf->sock) {
   case 0:
-    
-    switch(configure->vcc){
-    case 0:
-      gpio&=~(GPIO_GPIO0 | GPIO_GPIO1);
-      break;
-
-    case 33:
-      pccr=(pccr & ~PCCR_S0_PSE);
-      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
-      break;
-
-    case 50:
-      pccr=(pccr | PCCR_S0_PSE);
-      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
-      break;
+    pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
+    gpio_mask = NCR_A0VPP | NCR_A1VPP;
 
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
+    case 0:	pa_dwr_set = 0;			break;
+    case 33:	pa_dwr_set = GPIO_GPIO1;	break;
+    case 50:	pa_dwr_set = GPIO_GPIO0;	break;
     }
 
-    switch(configure->vpp){
-    case 0:
-      ncr&=~(NCR_A0VPP | NCR_A1VPP);
-      break;
-
-    case 120:
-      ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A1VPP;
-      break;
+    switch (conf->vpp) {
+    case 0:	gpio_set = 0;			break;
+    case 120:	gpio_set = NCR_A1VPP;		break;
 
     default:
-      if(configure->vpp == configure->vcc)
-	ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A0VPP;
+      if (conf->vpp == conf->vcc)
+	gpio_set = NCR_A0VPP;
       else {
-	printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
-	       configure->vpp);
+	printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
+	       __FUNCTION__, conf->vpp);
 	return -1;
       }
     }
-
-    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
-    pccr=(configure->output)?(pccr | PCCR_S0_FLT):(pccr & ~PCCR_S0_FLT);
-
     break;
 
   case 1:
-    switch(configure->vcc){
-    case 0:
-      gpio&=~(GPIO_GPIO2 | GPIO_GPIO3);
-      break;
-
-    case 33:
-      pccr=(pccr & ~PCCR_S1_PSE);
-      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2;
-      break;
-
-    case 50:
-      pccr=(pccr | PCCR_S1_PSE);
-      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
-      break;
+    pa_dwr_mask = GPIO_GPIO2 | GPIO_GPIO3;
+    gpio_mask = 0;
+    gpio_set = 0;
 
+    switch (conf->vcc) {
     default:
-      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-	     configure->vcc);
-      return -1;
+    case 0:	pa_dwr_set = 0;			break;
+    case 33:	pa_dwr_set = GPIO_GPIO2;	break;
+    case 50:	pa_dwr_set = GPIO_GPIO3;	break;
     }
 
-    if(configure->vpp!=configure->vcc && configure->vpp!=0){
-      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
-	     configure->vpp);
+    if (conf->vpp != conf->vcc && conf->vpp != 0) {
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
+	     __FUNCTION__, conf->vpp);
       return -1;
     }
-
-    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
-    pccr=(configure->output)?(pccr | PCCR_S1_FLT):(pccr & ~PCCR_S1_FLT);
-
     break;
-
-  default:
-    return -1;
   }
 
-  PCCR = pccr;
-  ncr &= NCR_A0VPP|NCR_A1VPP;
-  GPSR = ncr;
-  GPCR = (~ncr)&(NCR_A0VPP|NCR_A1VPP);
-  PA_DWR = gpio;
+  ret = sa1111_pcmcia_configure_socket(conf);
+  if (ret == 0) {
+    unsigned long flags;
+
+    local_irq_save(flags);
+    PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
+    GPSR = gpio_set;
+    GPCR = gpio_set ^ gpio_mask;
+    local_irq_restore(flags);
+  }
 
-  return 0;
+  return ret;
 }
 
 struct pcmcia_low_level xp860_pcmcia_ops = { 
-  xp860_pcmcia_init,
-  xp860_pcmcia_shutdown,
-  xp860_pcmcia_socket_state,
-  xp860_pcmcia_get_irq_info,
-  xp860_pcmcia_configure_socket
+  init:			xp860_pcmcia_init,
+  shutdown:		sa1111_pcmcia_shutdown,
+  socket_state:		sa1111_pcmcia_socket_state,
+  get_irq_info:		sa1111_pcmcia_get_irq_info,
+  configure_socket:	xp860_pcmcia_configure_socket,
+
+  socket_init:		sa1111_pcmcia_socket_init,
+  socket_suspend:	sa1111_pcmcia_socket_suspend,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1100_yopy.c linux/drivers/pcmcia/sa1100_yopy.c
--- linux.orig/drivers/pcmcia/sa1100_yopy.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/pcmcia/sa1100_yopy.c	2002-07-20 01:08:39.000000000 +0000
@@ -9,7 +9,7 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
 
 
 static inline void pcmcia_power(int on) {
@@ -30,13 +30,9 @@
 	pcmcia_power(0);
 	pcmcia_reset(1);
 
-	/* All those are inputs */
-	GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IREQ);
-	GAFR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IREQ);
-
 	/* Set transition detect */
-	set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
-			   GPIO_BOTH_EDGES );
+	set_GPIO_IRQ_edge(GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
+			  GPIO_NO_EDGES);
 	set_GPIO_IRQ_edge( GPIO_CF_IREQ, GPIO_FALLING_EDGE );
 
 	/* Register interrupts */
@@ -130,10 +126,27 @@
 	return 0;
 }
 
+static int yopy_pcmcia_socket_init(int sock)
+{
+	set_GPIO_IRQ_edge(GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
+			  GPIO_BOTH_EDGES);
+	return 0;
+}
+
+static int yopy_pcmcia_socket_suspend(int sock)
+{
+	set_GPIO_IRQ_edge(GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
+			  GPIO_NO_EDGES);
+	return 0;
+}
+
 struct pcmcia_low_level yopy_pcmcia_ops = {
-	yopy_pcmcia_init,
-	yopy_pcmcia_shutdown,
-	yopy_pcmcia_socket_state,
-	yopy_pcmcia_get_irq_info,
-	yopy_pcmcia_configure_socket
+	init:			yopy_pcmcia_init,
+	shutdown:		yopy_pcmcia_shutdown,
+	socket_state:		yopy_pcmcia_socket_state,
+	get_irq_info:		yopy_pcmcia_get_irq_info,
+	configure_socket:	yopy_pcmcia_configure_socket,
+
+	socket_init:		yopy_pcmcia_socket_init,
+	socket_suspend:		yopy_pcmcia_socket_suspend,
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1111_generic.c linux/drivers/pcmcia/sa1111_generic.c
--- linux.orig/drivers/pcmcia/sa1111_generic.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/pcmcia/sa1111_generic.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,189 @@
+/*
+ * linux/drivers/pcmcia/sa1100_sa1111.c
+ *
+ * We implement the generic parts of a SA1111 PCMCIA driver.  This
+ * basically means we handle everything except controlling the
+ * power.  Power is machine specific...
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/irq.h>
+
+#include "sa1100_generic.h"
+#include "sa1111_generic.h"
+
+static struct irqs {
+	int irq;
+	const char *str;
+} irqs[] = {
+	{ S0_CD_VALID,    "SA1111 PCMCIA card detect" },
+	{ S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1"        },
+	{ S1_CD_VALID,    "SA1111 CF card detect"     },
+	{ S1_BVD1_STSCHG, "SA1111 CF BVD1"            },
+};
+
+int sa1111_pcmcia_init(struct pcmcia_init *init)
+{
+	int i, ret;
+
+	if (!request_mem_region(_PCCR, 512, "PCMCIA"))
+		return -1;
+
+	INTPOL1 |= SA1111_IRQMASK_HI(S0_CD_VALID) |
+		   SA1111_IRQMASK_HI(S1_CD_VALID) |
+		   SA1111_IRQMASK_HI(S0_BVD1_STSCHG) |
+		   SA1111_IRQMASK_HI(S1_BVD1_STSCHG);
+
+	for (i = ret = 0; i < ARRAY_SIZE(irqs); i++) {
+		ret = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+				  irqs[i].str, NULL);
+		if (ret)
+			break;
+	}
+
+	if (i < ARRAY_SIZE(irqs)) {
+		printk(KERN_ERR "sa1111_pcmcia: unable to grab IRQ%d (%d)\n",
+			irqs[i].irq, ret);
+		while (i--)
+			free_irq(irqs[i].irq, NULL);
+
+		release_mem_region(_PCCR, 16);
+	}
+
+	return ret ? -1 : 2;
+}
+
+int sa1111_pcmcia_shutdown(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(irqs); i++)
+		free_irq(irqs[i].irq, NULL);
+
+	INTPOL1 &= ~(SA1111_IRQMASK_HI(S0_CD_VALID) |
+		     SA1111_IRQMASK_HI(S1_CD_VALID) |
+		     SA1111_IRQMASK_HI(S0_BVD1_STSCHG) |
+		     SA1111_IRQMASK_HI(S1_BVD1_STSCHG));
+
+	release_mem_region(_PCCR, 512);
+
+	return 0;
+}
+
+int sa1111_pcmcia_socket_state(struct pcmcia_state_array *state)
+{
+	unsigned long status;
+
+	if (state->size < 2)
+		return -1;
+
+	status = PCSR;
+
+	state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
+	state->state[0].ready  = status & PCSR_S0_READY  ? 1 : 0;
+	state->state[0].bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
+	state->state[0].bvd2   = status & PCSR_S0_BVD2   ? 1 : 0;
+	state->state[0].wrprot = status & PCSR_S0_WP     ? 1 : 0;
+	state->state[0].vs_3v  = status & PCSR_S0_VS1    ? 0 : 1;
+	state->state[0].vs_Xv  = status & PCSR_S0_VS2    ? 0 : 1;
+
+	state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1;
+	state->state[1].ready  = status & PCSR_S1_READY  ? 1 : 0;
+	state->state[1].bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
+	state->state[1].bvd2   = status & PCSR_S1_BVD2   ? 1 : 0;
+	state->state[1].wrprot = status & PCSR_S1_WP     ? 1 : 0;
+	state->state[1].vs_3v  = status & PCSR_S1_VS1    ? 0 : 1;
+	state->state[1].vs_Xv  = status & PCSR_S1_VS2    ? 0 : 1;
+
+	return 1;
+}
+
+int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+	int ret = 0;
+
+	switch (info->sock) {
+	case 0:	info->irq = S0_READY_NINT;	break;
+	case 1: info->irq = S1_READY_NINT;	break;
+	default: ret = 1;
+	}
+
+	return ret;
+}
+
+int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+{
+	unsigned int rst, flt, wait, pse, irq, pccr_mask;
+	unsigned long flags;
+
+	switch (conf->sock) {
+	case 0:
+		rst = PCCR_S0_RST;
+		flt = PCCR_S0_FLT;
+		wait = PCCR_S0_PWAITEN;
+		pse = PCCR_S0_PSE;
+		irq = S0_READY_NINT;
+		break;
+
+	case 1:
+		rst = PCCR_S1_RST;
+		flt = PCCR_S1_FLT;
+		wait = PCCR_S1_PWAITEN;
+		pse = PCCR_S1_PSE;
+		irq = S1_READY_NINT;
+		break;
+
+	default:
+		return -1;
+	}
+
+	switch (conf->vcc) {
+	case 0:
+		pccr_mask = 0;
+		break;
+
+	case 33:
+		pccr_mask = wait;
+		break;
+
+	case 50:
+		pccr_mask = pse | wait;
+		break;
+
+	default:
+		printk(KERN_ERR "sa1111_pcmcia: unrecognised VCC %u\n",
+			conf->vcc);
+		return -1;
+	}
+
+	if (conf->reset)
+		pccr_mask |= rst;
+
+	if (conf->output)
+		pccr_mask |= flt;
+
+	local_irq_save(flags);
+	PCCR = (PCCR & ~(pse | flt | wait | rst)) | pccr_mask;
+	local_irq_restore(flags);
+
+	if (conf->irq)
+		enable_irq(irq);
+	else
+		disable_irq(irq);
+
+	return 0;
+}
+
+int sa1111_pcmcia_socket_init(int sock)
+{
+	return 0;
+}
+
+int sa1111_pcmcia_socket_suspend(int sock)
+{
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/sa1111_generic.h linux/drivers/pcmcia/sa1111_generic.h
--- linux.orig/drivers/pcmcia/sa1111_generic.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/pcmcia/sa1111_generic.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,15 @@
+extern int sa1111_pcmcia_init(struct pcmcia_init *);
+extern int sa1111_pcmcia_shutdown(void);
+extern int sa1111_pcmcia_socket_state(struct pcmcia_state_array *);
+extern int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *);
+extern int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *);
+extern int sa1111_pcmcia_socket_init(int);
+extern int sa1111_pcmcia_socket_suspend(int);
+
+/*
+ * I'd really like to move the INTPOL stuff to arch/arm/mach-sa1100/sa1111.c
+ */
+#define SA1111_IRQMASK_LO(x)	(1 << (x - IRQ_SA1111_START))
+#define SA1111_IRQMASK_HI(x)	(1 << (x - IRQ_SA1111_START - 32))
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/ti113x.h linux/drivers/pcmcia/ti113x.h
--- linux.orig/drivers/pcmcia/ti113x.h	2001-11-22 19:48:51.000000000 +0000
+++ linux/drivers/pcmcia/ti113x.h	2002-07-20 01:08:32.000000000 +0000
@@ -170,9 +170,88 @@
 	return 0;
 }
 
+/*
+ *	Zoom video control for TI122x/113x chips
+ */
+
+static void ti_zoom_video(pci_socket_t *socket, int onoff)
+{
+	u8 reg;
+
+	/* If we don't have a Zoom Video switch this is harmless,
+	   we just tristate the unused (ZV) lines */
+	reg = config_readb(socket, TI113X_CARD_CONTROL);
+	if (onoff)
+		/* Zoom zoom, we will all go together, zoom zoom, zoom zoom */
+		reg |= TI113X_CCR_ZVENABLE;
+	else
+		reg &= ~TI113X_CCR_ZVENABLE;
+	config_writeb(socket, TI113X_CARD_CONTROL, reg);
+}
+
+/*
+ *	The 145x series can also use this. They have an additional
+ *	ZV autodetect mode we don't use but don't actually need.
+ *	FIXME: manual says its in func0 and func1 but disagrees with
+ *	itself about this - do we need to force func0, if so we need
+ *	to know a lot more about socket pairings in pci_socket than we
+ *	do now.. uggh.
+ */
+ 
+static void ti1250_zoom_video(pci_socket_t *socket, int onoff)
+{	
+	int shift = 0;
+	u8 reg;
+
+	ti_zoom_video(socket, onoff);
+
+	reg = config_readb(socket, 0x84);
+	reg |= (1<<7);	/* ZV bus enable */
+
+	if(PCI_FUNC(socket->dev->devfn)==1)
+		shift = 1;
+	
+	if(onoff)
+	{
+		reg &= ~(1<<6); 	/* Clear select bit */
+		reg |= shift<<6;	/* Favour our socket */
+		reg |= 1<<shift;	/* Socket zoom video on */
+	}
+	else
+	{
+		reg &= ~(1<<6); 	/* Clear select bit */
+		reg |= (1^shift)<<6;	/* Favour other socket */
+		reg &= ~(1<<shift);	/* Socket zoon video off */
+	}
+
+	config_writeb(socket, 0x84, reg);
+}
+
+static void ti_set_zv(pci_socket_t *socket)
+{
+	if(socket->dev->vendor == PCI_VENDOR_ID_TI)
+	{
+		switch(socket->dev->device)
+		{
+			/* There may be more .. */
+			case PCI_DEVICE_ID_TI_1220:
+			case PCI_DEVICE_ID_TI_1221:
+			case PCI_DEVICE_ID_TI_1225:
+				socket->zoom_video = ti_zoom_video;
+				break;	
+			case PCI_DEVICE_ID_TI_1250:
+			case PCI_DEVICE_ID_TI_1251A:
+			case PCI_DEVICE_ID_TI_1251B:
+			case PCI_DEVICE_ID_TI_1450:
+				socket->zoom_video = ti1250_zoom_video;
+		}
+	}
+}
+
 static int ti_init(pci_socket_t *socket)
 {
 	yenta_init(socket);
+	ti_set_zv(socket);
 	ti_intctl(socket);
 	return 0;
 }
@@ -251,7 +330,7 @@
 static int ti1250_init(pci_socket_t *socket)
 {
 	yenta_init(socket);
-
+	ti_set_zv(socket);
 	config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket));
 	ti_intctl(socket);
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- linux.orig/drivers/pcmcia/yenta.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/pcmcia/yenta.c	2002-07-20 01:08:38.000000000 +0000
@@ -286,6 +286,9 @@
 		}
 		exca_writeb(socket, I365_CSCINT, reg);
 		exca_readb(socket, I365_CSC);
+	
+		if(socket->zoom_video)
+			socket->zoom_video(socket, state->flags & SS_ZVCARD);
 	}
 	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
 	/* Socket event mask: get card insert/remove events.. */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pnp/isapnp.c linux/drivers/pnp/isapnp.c
--- linux.orig/drivers/pnp/isapnp.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/pnp/isapnp.c	2002-07-20 01:08:38.000000000 +0000
@@ -56,10 +56,6 @@
 #define ISAPNP_DEBUG
 #endif
 
-struct resource *pidxr_res;
-struct resource *pnpwrp_res;
-struct resource *isapnp_rdp_res;
-
 int isapnp_disable;			/* Disable ISA PnP */
 int isapnp_rdp;				/* Read Data Port */
 int isapnp_reset = 1;			/* reset all PnP cards (deactivate) */
@@ -2142,19 +2138,13 @@
 	kfree(card);
 }
 
-#endif /* MODULE */
-
 static void isapnp_free_all_resources(void)
 {
 #ifdef ISAPNP_REGION_OK
-	if (pidxr_res)
-		release_resource(pidxr_res);
+	release_region(_PIDXR, 1);
 #endif
-	if (pnpwrp_res)
-		release_resource(pnpwrp_res);
-	if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff && isapnp_rdp_res)
-		release_resource(isapnp_rdp_res);
-#ifdef MODULE
+	release_region(_PNPWRP, 1);
+	release_region(isapnp_rdp, 1);
 #ifdef CONFIG_PROC_FS
 	isapnp_proc_done();
 #endif
@@ -2163,9 +2153,10 @@
 		list_del(list);
 		isapnp_free_card(pci_bus_b(list));
 	}
-#endif
 }
 
+#endif /* MODULE */
+
 static int isapnp_announce_device(struct isapnp_driver *drv, 
 				  struct pci_dev *dev)
 {
@@ -2284,14 +2275,12 @@
 		return 0;
 	}
 #ifdef ISAPNP_REGION_OK
-	pidxr_res=request_region(_PIDXR, 1, "isapnp index");
-	if(!pidxr_res) {
+	if (!request_region(_PIDXR, 1, "isapnp index")) {
 		printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR);
 		return -EBUSY;
 	}
 #endif
-	pnpwrp_res=request_region(_PNPWRP, 1, "isapnp write");
-	if(!pnpwrp_res) {
+	if (!request_region(_PNPWRP, 1, "isapnp write")) {
 		printk(KERN_ERR "isapnp: Write Data Register 0x%x already used\n", _PNPWRP);
 #ifdef ISAPNP_REGION_OK
 		release_region(_PIDXR, 1);
@@ -2307,13 +2296,12 @@
 	printk(KERN_INFO "isapnp: Scanning for PnP cards...\n");
 	if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
 		isapnp_rdp |= 3;
-		isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
-		if(!isapnp_rdp_res) {
+		if (!request_region(isapnp_rdp, 1, "isapnp read")) {
 			printk(KERN_ERR "isapnp: Read Data Register 0x%x already used\n", isapnp_rdp);
 #ifdef ISAPNP_REGION_OK
 			release_region(_PIDXR, 1);
 #endif
-			release_region(isapnp_rdp, 1);
+			release_region(_PNPWRP, 1);
 			return -EBUSY;
 		}
 		isapnp_set_rdp();
@@ -2323,12 +2311,15 @@
 		cards = isapnp_isolate();
 		if (cards < 0 || 
 		    (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
-			isapnp_free_all_resources();
+#ifdef ISAPNP_REGION_OK
+			release_region(_PIDXR, 1);
+#endif
+			release_region(_PNPWRP, 1);
 			isapnp_detected = 0;
 			printk(KERN_INFO "isapnp: No Plug & Play device found\n");
 			return 0;
 		}
-		isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
+		request_region(isapnp_rdp, 1, "isapnp read");
 	}
 	isapnp_build_device_list();
 	cards = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/pnp/quirks.c linux/drivers/pnp/quirks.c
--- linux.orig/drivers/pnp/quirks.c	2001-11-04 17:31:58.000000000 +0000
+++ linux/drivers/pnp/quirks.c	2002-07-20 01:08:31.000000000 +0000
@@ -18,6 +18,10 @@
 #include <linux/isapnp.h>
 #include <linux/string.h>
 
+#if 0
+#define ISAPNP_DEBUG
+#endif
+
 static void __init quirk_awe32_resources(struct pci_dev *dev)
 {
 	struct isapnp_port *port, *port2, *port3;
@@ -139,8 +143,10 @@
 	while (isapnp_fixups[i].vendor != 0) {
 		if ((isapnp_fixups[i].vendor == dev->vendor) &&
 		    (isapnp_fixups[i].device == dev->device)) {
+#ifdef ISAPNP_DEBUG
 			printk(KERN_DEBUG "isapnp: Calling quirk for %02x:%02x\n",
 			       dev->bus->number, dev->devfn);
+#endif
 			isapnp_fixups[i].quirk_function(dev);
 		}
 		i++;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
--- linux.orig/drivers/s390/block/dasd.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/s390/block/dasd.c	2002-07-20 01:08:35.000000000 +0000
@@ -4187,6 +4187,7 @@
 		goto failed;
 	}
 	genhd_dasd_name = dasd_device_name;
+	genhd_dasd_ioctl = dasd_ioctl;
 
 	if (dasd_autodetect) {	/* update device range to all devices */
 		for (irq = get_irq_first (); irq != -ENODEV;
@@ -4309,7 +4310,9 @@
 	printk (KERN_INFO PRINTK_HEADER
 		"De-Registered ECKD discipline successfully\n");
 #endif /* CONFIG_DASD_ECKD_BUILTIN */
-        
+
+	genhd_dasd_name = NULL;
+	genhd_dasd_ioctl = NULL;
 	dasd_proc_cleanup ();
         
 	list_for_each_safe (l, n, &dasd_major_info[0].list) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/block/dasd_int.h linux/drivers/s390/block/dasd_int.h
--- linux.orig/drivers/s390/block/dasd_int.h	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/s390/block/dasd_int.h	2002-07-20 01:08:38.000000000 +0000
@@ -203,14 +203,14 @@
         debug_sprintf_event(d_device->debug_area,d_level,\
                     DASD_DEVICE_FORMAT_STRING d_str "\n",\
                     d_device, d_data);\
-} while(0);
+} while(0)
 #define DASD_DEVICE_DEBUG_EXCEPTION(d_level, d_device, d_str, d_data...)\
 do {\
         if ( d_device->debug_area != NULL )\
         debug_sprintf_exception(d_device->debug_area,d_level,\
                         DASD_DEVICE_FORMAT_STRING d_str "\n",\
                         d_device, d_data);\
-} while(0);
+} while(0)
 
 #define DASD_DRIVER_FORMAT_STRING "Driver: <[%p]>"
 #define DASD_DRIVER_DEBUG_EVENT(d_level, d_fn, d_str, d_data...)\
@@ -219,14 +219,14 @@
         debug_sprintf_event(dasd_debug_area, d_level,\
                     DASD_DRIVER_FORMAT_STRING #d_fn ":" d_str "\n",\
                     d_fn, d_data);\
-} while(0);
+} while(0)
 #define DASD_DRIVER_DEBUG_EXCEPTION(d_level, d_fn, d_str, d_data...)\
 do {\
         if ( dasd_debug_area != NULL )\
         debug_sprintf_exception(dasd_debug_area, d_level,\
                         DASD_DRIVER_FORMAT_STRING #d_fn ":" d_str "\n",\
                         d_fn, d_data);\
-} while(0);
+} while(0)
 
 struct dasd_device_t;
 struct request;
@@ -367,6 +367,8 @@
 
 extern debug_info_t *dasd_debug_area;
 extern int (*genhd_dasd_name) (char *, int, int, struct gendisk *);
+extern int (*genhd_dasd_ioctl) (struct inode *inp, struct file *filp,
+                            unsigned int no, unsigned long data);
 
 #endif /* __KERNEL__ */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/ccwcache.c linux/drivers/s390/ccwcache.c
--- linux.orig/drivers/s390/ccwcache.c	2001-07-25 21:12:02.000000000 +0000
+++ linux/drivers/s390/ccwcache.c	2002-07-20 01:08:24.000000000 +0000
@@ -291,9 +291,11 @@
 	/* Shrink the caches, if available */
 	for ( cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ ) {
 		if ( ccw_cache[cachind] ) {
+#if 0 /* this is useless and could cause an OOPS in the worst case */
 			if ( kmem_cache_shrink(ccw_cache[cachind]) == 0 ) {
 				ccw_cache[cachind] = NULL;
 			}
+#endif
 			kmem_cache_destroy(ccw_cache[cachind]);
 		}
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/char/con3215.c linux/drivers/s390/char/con3215.c
--- linux.orig/drivers/s390/char/con3215.c	2001-07-25 21:12:02.000000000 +0000
+++ linux/drivers/s390/char/con3215.c	2002-07-20 01:08:26.000000000 +0000
@@ -119,7 +119,7 @@
 /*
  * Get a request structure from the free list
  */
-extern inline raw3215_req *raw3215_alloc_req(void) {
+static inline raw3215_req *raw3215_alloc_req(void) {
 	raw3215_req *req;
 	unsigned long flags;
 
@@ -133,7 +133,7 @@
 /*
  * Put a request structure back to the free list
  */
-extern inline void raw3215_free_req(raw3215_req *req) {
+static inline void raw3215_free_req(raw3215_req *req) {
 	unsigned long flags;
 
         if (req->type == RAW3215_FREE)
@@ -312,7 +312,7 @@
  * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not
  * done immediatly a timer is started with a delay of RAW3215_TIMEOUT.
  */
-extern inline void raw3215_try_io(raw3215_info *raw)
+static inline void raw3215_try_io(raw3215_info *raw)
 {
 	if (!(raw->flags & RAW3215_ACTIVE))
 		return;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/char/hwc_con.c linux/drivers/s390/char/hwc_con.c
--- linux.orig/drivers/s390/char/hwc_con.c	2001-07-25 21:12:02.000000000 +0000
+++ linux/drivers/s390/char/hwc_con.c	2002-07-20 01:08:24.000000000 +0000
@@ -31,20 +31,12 @@
 
 #define  HWC_CON_PRINT_HEADER "hwc console driver: "
 
-struct console hwc_console =
-{
-
-	hwc_console_name,
-	hwc_console_write,
-	NULL,
-	hwc_console_device,
-	NULL,
-	hwc_console_unblank,
-	NULL,
-	CON_PRINTBUFFER,
-	0,
-	0,
-	NULL
+struct console hwc_console = {
+	name:	hwc_console_name,
+	write:	hwc_console_write,
+	device:	hwc_console_device,
+	unblank:hwc_console_unblank,
+	flags:	CON_PRINTBUFFER,
 };
 
 void 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/char/tape34xx.c linux/drivers/s390/char/tape34xx.c
--- linux.orig/drivers/s390/char/tape34xx.c	2001-11-09 22:05:02.000000000 +0000
+++ linux/drivers/s390/char/tape34xx.c	2002-07-20 01:08:25.000000000 +0000
@@ -2152,7 +2152,7 @@
       	    tape34xx_error_recovery_HWBUG(ti,21);
 	    return;
 	case 0x3490:
-	    // Resetting event recieved. Since the driver does not support resetting event recovery
+	    // Resetting event received. Since the driver does not support resetting event recovery
 	    // (which has to be handled by the I/O Layer), we'll report and retry our command.
 	    tape34xx_error_recovery_do_retry(ti);
 	    return;
@@ -2219,7 +2219,7 @@
 	    return;
 	case 0x3490:
 	    // Global status intercept. We have to reissue the command.
-	    PRINT_WARN("An global status intercept was recieved, which will be recovered.\n");
+	    PRINT_WARN("An global status intercept was received, which will be recovered.\n");
 	    tape34xx_error_recovery_do_retry(ti);
 	    return;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/char/tuball.c linux/drivers/s390/char/tuball.c
--- linux.orig/drivers/s390/char/tuball.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/s390/char/tuball.c	2002-07-20 01:08:30.000000000 +0000
@@ -84,7 +84,6 @@
 	tub3270_con_write,	/* write */
 	NULL,			/* read */
 	tub3270_con_device,	/* device */
-	NULL,			/* wait_key */
 	tub3270_con_unblank,	/* unblank */
 	NULL,			/* setup */
 	CON_PRINTBUFFER,	/* flags */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/char/tubio.h linux/drivers/s390/char/tubio.h
--- linux.orig/drivers/s390/char/tubio.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/s390/char/tubio.h	2002-07-20 01:08:21.000000000 +0000
@@ -357,7 +357,7 @@
  * Find tub_t * given fullscreen device's inode pointer
  * This algorithm takes into account /dev/3270/tub.
  */
-extern inline tub_t *INODE2TUB(struct inode *ip)
+static inline tub_t *INODE2TUB(struct inode *ip)
 {
 	unsigned int minor = MINOR(ip->i_rdev);
 	tub_t *tubp = NULL;
@@ -381,7 +381,7 @@
 /*
  * Find tub_t * given non-fullscreen (tty) device's tty_struct pointer
  */
-extern inline tub_t *TTY2TUB(struct tty_struct *tty)
+static inline tub_t *TTY2TUB(struct tty_struct *tty)
 {
 	unsigned int minor = MINOR(tty->device);
 	tub_t *tubp = NULL;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/char/tubtty.c linux/drivers/s390/char/tubtty.c
--- linux.orig/drivers/s390/char/tubtty.c	2001-10-11 16:43:29.000000000 +0000
+++ linux/drivers/s390/char/tubtty.c	2002-07-20 01:08:39.000000000 +0000
@@ -603,12 +603,20 @@
 static void
 tty3270_bh(void *data)
 {
-	long flags;
 	tub_t *tubp;
+	ioinfo_t *ioinfop;
+	long flags;
 	struct tty_struct *tty;
 
-	tubp = data;
-	TUBLOCK(tubp->irq, flags);
+	ioinfop = ioinfo[(tubp = data)->irq];
+	while (TUBTRYLOCK(tubp->irq, flags) == 0) {
+		if (ioinfop->ui.flags.unready == 1)
+			return;
+	}
+	if (ioinfop->ui.flags.unready == 1 ||
+	    ioinfop->ui.flags.ready == 0)
+		goto do_unlock;
+
 	tubp->flags &= ~TUB_BHPENDING;
 	tty = tubp->tty;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/misc/chandev.c linux/drivers/s390/misc/chandev.c
--- linux.orig/drivers/s390/misc/chandev.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/s390/misc/chandev.c	2002-07-20 01:08:33.000000000 +0000
@@ -902,25 +902,6 @@
 		       (int)lo_devno,(int)hi_devno);
 		return;
 	}
-	chandev_lock();
-	for_each(parms,chandev_parms_head)
-	{
-		if(chan_type&(parms->chan_type))
-		{
-			u16 lomax=MAX(parms->lo_devno,lo_devno),
-				himin=MIN(parms->hi_devno,lo_devno);
-			if(lomax<=himin)
-			{
-				chandev_unlock();
-				printk("chandev_add_parms detected overlapping "
-				       "parameter definitions for chan_type=0x%02x"
-				       " lo_devno=0x%04x  hi_devno=0x%04x\n,"
-				       " do a del_parms.",chan_type,(int)lo_devno,(int)hi_devno);
-				return;
-			}
-		}
-	}
-	chandev_unlock();
 	if((parms=chandev_allocstr(parmstr,offsetof(chandev_parms,parmstr))))
 	{
 		parms->chan_type=chan_type;
@@ -1727,8 +1708,16 @@
 				   read->sch.devno>=curr_parms->lo_devno&&
 					read->sch.devno<=curr_parms->hi_devno)
 				{
-					probeinfo.parmstr=curr_parms->parmstr;
-					break;
+					if (!probeinfo.parmstr) {
+						probeinfo.parmstr = vmalloc(sizeof(curr_parms->parmstr)+1);
+						strcpy(probeinfo.parmstr, curr_parms->parmstr);
+					} else {
+						char *buf;
+
+						buf = vmalloc(strlen(probeinfo.parmstr)+strlen(curr_parms->parmstr)+2);
+						sprintf(buf, "%s,%s",probeinfo.parmstr, curr_parms->parmstr);
+						probeinfo.parmstr=buf;
+					}
 				}
 			}
 			if(force)
@@ -2024,7 +2013,7 @@
 		/* This is required because the device can go & come back */
                 /* even before we realize it is gone owing to the waits in our kernel threads */
 		/* & the device will be marked as not owned but its status will be good */
-                /* & an attempt to accidently reprobe it may be done. */ 
+                /* & an attempt to accidentally reprobe it may be done. */ 
 		remove:
 		chandev_remove(chandev_get_by_irq(curr_irqinfo->sch.irq));
 		
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/net/Makefile linux/drivers/s390/net/Makefile
--- linux.orig/drivers/s390/net/Makefile	2001-07-25 21:12:02.000000000 +0000
+++ linux/drivers/s390/net/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -9,8 +9,8 @@
 
 ctc-objs := ctcmain.o ctctty.o
 
-obj-y += iucv.o fsm.o
-obj-$(CONFIG_CTC) += ctc.o
+obj-$(CONFIG_IUCV) += iucv.o fsm.o
+obj-$(CONFIG_CTC) += ctc.o fsm.o
 obj-$(CONFIG_IUCV) += netiucv.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/net/ctctty.c linux/drivers/s390/net/ctctty.c
--- linux.orig/drivers/s390/net/ctctty.c	2001-07-25 21:12:02.000000000 +0000
+++ linux/drivers/s390/net/ctctty.c	2002-07-20 01:08:22.000000000 +0000
@@ -286,7 +286,7 @@
 
 	if (!info->netdev) {
 		if (skb)
-			kfree(skb);
+			kfree_skb(skb);
 		return 0;
 	}
 	if (info->flags & CTC_ASYNC_TX_LINESTAT) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/net/fsm.h linux/drivers/s390/net/fsm.h
--- linux.orig/drivers/s390/net/fsm.h	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/s390/net/fsm.h	2002-07-20 01:08:28.000000000 +0000
@@ -140,7 +140,7 @@
  *              1  if current state or event is out of range
  *              !0 if state and event in range, but no action defined.
  */
-extern __inline__ int
+static inline int
 fsm_event(fsm_instance *fi, int event, void *arg)
 {
 	fsm_function_t r;
@@ -188,7 +188,7 @@
  * @param fi    Pointer to FSM
  * @param state The new state for this FSM.
  */
-extern __inline__ void
+static inline void
 fsm_newstate(fsm_instance *fi, int newstate)
 {
 	atomic_set(&fi->state,newstate);
@@ -208,7 +208,7 @@
  *
  * @return The current state of the FSM.
  */
-extern __inline__ int
+static inline int
 fsm_getstate(fsm_instance *fi)
 {
 	return atomic_read(&fi->state);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/net/iucv.c linux/drivers/s390/net/iucv.c
--- linux.orig/drivers/s390/net/iucv.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/s390/net/iucv.c	2002-07-20 01:08:25.000000000 +0000
@@ -1,5 +1,5 @@
 /* 
- * $Id$
+ * $Id: iucv.c,v 1.32 2002/02/12 21:52:20 felfert Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision$
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.32 $
  *
  */
 
@@ -51,7 +51,7 @@
 #include <asm/s390_ext.h>
 #include <asm/ebcdic.h>
 
-#undef DEBUG
+#define DEBUG
 
 /* FLAGS:
  * All flags are defined in the field IPFLAGS1 of each function
@@ -165,6 +165,10 @@
  * declare_flag: is 0 when iucv_declare_buffer has not been called
  */
 static int declare_flag;
+/**
+ * register_flag: is 0 when external interrupt has not been registered
+ */
+static int register_flag;
 
 /****************FIVE 40-BYTE PARAMETER STRUCTURES******************/
 /* Data struct 1: iparml_control
@@ -271,37 +275,56 @@
 
 static iucv_param * iucv_param_pool;
 
+MODULE_AUTHOR("(C) 2001 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
+MODULE_DESCRIPTION("Linux for S/390 IUCV lowlevel driver");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
+MODULE_LICENSE("GPL");
+#endif
+
 /*
  * Debugging stuff
  *******************************************************************************/
 
+
 #ifdef DEBUG
+static int debuglevel = 0;
+
+MODULE_PARM(debuglevel, "i");
+MODULE_PARM_DESC(debuglevel,
+ "Specifies the debug level (0=off ... 3=all)");
 
 static void
-iucv_dumpit(void *buf, int len)
+iucv_dumpit(char *title, void *buf, int len)
 {
 	int i;
 	__u8 *p = (__u8 *)buf;
 
-	printk(KERN_DEBUG "  ");
+	if (debuglevel < 3)
+		return;
+
+	printk(KERN_DEBUG __FUNCTION__ ": %s\n", title);
+	printk("  ");
 	for (i = 0; i < len; i++) {
 		if (!(i % 16) && i != 0)
 			printk ("\n  ");
 		else if (!(i % 4) && i != 0)
-			printk (" ");
-		printk ("%02X", *p++);
+			printk(" ");
+		printk("%02X", *p++);
 	}
 	if (len % 16)
 		printk ("\n");
 	return;
 }
-#define iucv_debug(fmt, args...) \
-printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n" , ## args);
+#define iucv_debug(lvl, fmt, args...) \
+do { \
+	if (debuglevel >= lvl) \
+		printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n" , ## args); \
+} while (0)
 
 #else
 
-#define iucv_debug(fmt, args...)
-#define iucv_dumpit(buf, len)
+#define iucv_debug(lvl, fmt, args...)
+#define iucv_dumpit(title, buf, len)
 
 #endif
 
@@ -310,6 +333,25 @@
  *******************************************************************************/
 
 /**
+ * print start banner
+ */
+static void
+iucv_banner(void)
+{
+	char vbuf[] = "$Revision: 1.32 $";
+	char *version = vbuf;
+
+	if ((version = strchr(version, ':'))) {
+		char *p = strchr(version + 1, '$');
+		if (p)
+			*p = '\0';
+	} else
+		version = " ??? ";
+	printk(KERN_INFO
+	       "IUCV lowlevel driver Version%s initialized\n", version);
+}
+
+/**
  * iucv_init - Initialization
  *
  * Allocates and initializes various data structures.
@@ -354,10 +396,26 @@
 	/* Initialize handler table */
 	INIT_LIST_HEAD(&iucv_handler_table);
 
+	iucv_banner();
 	return 0;
 }
 
 /**
+ * iucv_exit - De-Initialization
+ *
+ * Frees everything allocated from iucv_init.
+ */
+static void
+iucv_exit(void)
+{
+	if (iucv_external_int_buffer)
+		kfree(iucv_external_int_buffer);
+	if (iucv_param_pool)
+		kfree(iucv_param_pool);
+	printk(KERN_INFO "IUCV lowlevel driver unloaded\n");
+}
+
+/**
  * grab_param: - Get a parameter buffer from the pre-allocated pool.
  *
  * This function searches for an unused element in the the pre-allocated pool
@@ -410,8 +468,8 @@
 {
 	ulong flags;
 
-	iucv_debug("entering");
-	iucv_dumpit(new, sizeof(handler));
+	iucv_debug(1, "entering");
+	iucv_dumpit("handler:", new, sizeof(handler));
 
 	spin_lock_irqsave (&iucv_lock, flags);
 	if (!list_empty(&iucv_handler_table)) {
@@ -424,7 +482,7 @@
 		list_for_each(lh, &iucv_handler_table) {
 			handler *h = list_entry(lh, handler, list);
 			if (memcmp(&new->id, &h->id, sizeof(h->id)) == 0) {
-				iucv_debug("ret 1");
+				iucv_debug(1, "ret 1");
 				spin_unlock_irqrestore (&iucv_lock, flags);
 				return 1;
 			}
@@ -437,35 +495,11 @@
 	list_add(&new->list, &iucv_handler_table);
 	spin_unlock_irqrestore (&iucv_lock, flags);
 
-	iucv_debug("exiting");
+	iucv_debug(1, "exiting");
 	return 0;
 }
 
 /**
- * iucv_remove_handler:
- * @users_handler: handler to be removed
- *
- * Remove handler when application unregisters.
- */
-static void
-iucv_remove_handler(handler *handler)
-{
-	unsigned long flags;
-
-	if ((!iucv_pathid_table) || (!handler))
-		return;
-
-	iucv_debug("entering");
-
-	spin_lock_irqsave (&iucv_lock, flags);
-	list_del(&handler->list);
-	spin_unlock_irqrestore (&iucv_lock, flags);
-
-	iucv_debug("exiting");
-	return;
-}
-
-/**
  * b2f0:
  * @code: identifier of IUCV call to CP.
  * @parm: pointer to 40 byte iparml area passed to CP
@@ -477,8 +511,7 @@
 static __inline__ ulong
 b2f0(__u32 code, void *parm)
 {
-	iucv_debug("iparml before b2f0 call:");
-	iucv_dumpit(parm, sizeof(iucv_param));
+	iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param));
 
 	asm volatile (
 		"LRA   1,0(%1)\n\t"
@@ -489,8 +522,7 @@
 		: "0", "1"
 		);
 
-	iucv_debug("iparml after b2f0 call:");
-	iucv_dumpit(parm, sizeof(iucv_param));
+	iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param));
 
 	return (unsigned long)*((__u8 *)(parm + 3));
 }
@@ -511,9 +543,9 @@
 {
 	ulong flags;
 
-	iucv_debug("entering");
+	iucv_debug(1, "entering");
 
-	iucv_debug("handler is pointing to %p", handler);
+	iucv_debug(1, "handler is pointing to %p", handler);
 
 	if (pathid > (max_connections - 1))
 		return -EINVAL;
@@ -521,7 +553,7 @@
 	spin_lock_irqsave (&iucv_lock, flags);
 	if (iucv_pathid_table[pathid]) {
 		spin_unlock_irqrestore (&iucv_lock, flags);
-		iucv_debug("pathid entry is %p", iucv_pathid_table[pathid]);
+		iucv_debug(1, "pathid entry is %p", iucv_pathid_table[pathid]);
 		printk(KERN_WARNING
 		       "%s: Pathid being used, error.\n", __FUNCTION__);
 		return -EINVAL;
@@ -529,7 +561,7 @@
 	iucv_pathid_table[pathid] = handler;
 	spin_unlock_irqrestore (&iucv_lock, flags);
 
-	iucv_debug("exiting");
+	iucv_debug(1, "exiting");
 	return 0;
 }				/* end of add_pathid function */
 
@@ -546,24 +578,63 @@
 	spin_unlock_irqrestore (&iucv_lock, flags);
 }
 
-/*
+/**
+ * iucv_declare_buffer_cpu0
+ * Register at VM for subsequent IUCV operations. This is always
+ * executed on CPU 0. Called from iucv_declare_buffer().
+ */
+static void
+iucv_declare_buffer_cpu0 (void *result)
+{
+	iparml_db *parm;
+
+	if (!(result && (smp_processor_id() == 0)))
+		return;
+	parm = (iparml_db *)grab_param();
+	parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer);
+	if ((*((ulong *)result) = b2f0(DECLARE_BUFFER, parm)) == 1)
+		*((ulong *)result) = parm->iprcode;
+	release_param(parm);
+}
+
+/**
+ * iucv_retrieve_buffer_cpu0:
+ * Unregister IUCV usage at VM. This is always executed on CPU 0.
+ * Called from iucv_retrieve_buffer().
+ */
+void
+iucv_retrieve_buffer_cpu0 (void *result)
+{
+	iparml_control *parm;
+
+	if (smp_processor_id() != 0)
+		return;
+	parm = (iparml_control *)grab_param();
+	b2f0(RETRIEVE_BUFFER, parm);
+	release_param(parm);
+}
+
+/**
  * Name: iucv_declare_buffer
  * Purpose: Specifies the guests real address of an external
  *          interrupt.
  * Input: void
  * Output: iprcode - return code from b2f0 call
-*/
+ */
 int
 iucv_declare_buffer (void)
 {
-	ulong b2f0_result;
-	iparml_db *parm = (iparml_db *)grab_param();
+	ulong b2f0_result = 0x0deadbeef;
 
-	parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer);
-	b2f0_result = b2f0(DECLARE_BUFFER, parm);
-	release_param(parm);
-	iucv_debug("Address of EIB = %p", iucv_external_int_buffer);
-	iucv_debug("exiting");
+	iucv_debug(1, "entering");
+	if (smp_processor_id() == 0)
+		iucv_declare_buffer_cpu0(&b2f0_result);
+	else
+		smp_call_function(iucv_declare_buffer_cpu0, &b2f0_result, 0, 1);
+	iucv_debug(1, "Address of EIB = %p", iucv_external_int_buffer);
+	if (b2f0_result == 0x0deadbeef)
+	    b2f0_result = 0xaa;
+	iucv_debug(1, "exiting");
 	return b2f0_result;
 }
 
@@ -576,20 +647,47 @@
 int
 iucv_retrieve_buffer (void)
 {
-	ulong b2f0_result = 0;
-	iparml_control *parm = (iparml_control *)grab_param();
+	iucv_debug(1, "entering");
+	if (declare_flag) {
+		if (smp_processor_id() == 0)
+			iucv_retrieve_buffer_cpu0(0);
+		else
+			smp_call_function(iucv_retrieve_buffer_cpu0, 0, 0, 1);
+		declare_flag = 0;
+	}
+	iucv_debug(1, "exiting");
+	return 0;
+}
 
-	iucv_debug("entering");
+/**
+ * iucv_remove_handler:
+ * @users_handler: handler to be removed
+ *
+ * Remove handler when application unregisters.
+ */
+static void
+iucv_remove_handler(handler *handler)
+{
+	unsigned long flags;
 
-	b2f0_result = b2f0(RETRIEVE_BUFFER, parm);
-	release_param(parm);
-	if (b2f0_result == 0) {
-		kfree(iucv_pathid_table);
-		iucv_pathid_table = NULL;
-		declare_flag = 0;
+	if ((!iucv_pathid_table) || (!handler))
+		return;
+
+	iucv_debug(1, "entering");
+
+	spin_lock_irqsave (&iucv_lock, flags);
+	list_del(&handler->list);
+	if (list_empty(&iucv_handler_table)) {
+		iucv_retrieve_buffer();
+		if (register_flag) {
+			unregister_external_interrupt(0x4000, iucv_irq_handler);
+			register_flag = 0;
+		}
 	}
-	iucv_debug("exiting");
-	return b2f0_result;
+	spin_unlock_irqrestore (&iucv_lock, flags);
+
+	iucv_debug(1, "exiting");
+	return;
 }
 
 /**
@@ -623,7 +721,7 @@
 	ulong rc = 0;		/* return code from function calls */
 	handler *new_handler;
 
-	iucv_debug("entering");
+	iucv_debug(1, "entering");
 
 	if (ops == NULL) {
 		/* interrupt table is not defined */
@@ -711,17 +809,41 @@
 	if (declare_flag == 0) {
 		rc = iucv_declare_buffer();
 		if (rc) {
+			char *err = "Unknown";
 			iucv_remove_handler(new_handler);
 			kfree(new_handler);
+			switch(rc) {
+				case 0x03:
+					err = "Directory error";
+					break;
+				case 0x0a:
+					err = "Invalid length";
+					break;
+				case 0x13:
+					err = "Buffer already exists";
+					break;
+				case 0x3e:
+					err = "Buffer overlap";
+					break;
+				case 0x5c:
+					err = "Paging or storage error";
+					break;
+				case 0xaa:
+					err = "Function not called";
+					break;
+			}
 			printk(KERN_WARNING "%s: iucv_declare_buffer "
-			       "returned %ld\n", __FUNCTION__, rc);
+			       "returned error 0x%02lx (%s)\n", __FUNCTION__, rc,
+			       err);
 			return NULL;
 		}
+		declare_flag = 1;
+	}
+	if (register_flag == 0) {
 		/* request the 0x4000 external interrupt */
 		rc = register_external_interrupt (0x4000, iucv_irq_handler);
 		if (rc) {
 			iucv_remove_handler(new_handler);
-			iucv_retrieve_buffer();
 			kfree (new_handler);
 			printk(KERN_WARNING "%s: "
 			       "register_external_interrupt returned %ld\n",
@@ -729,9 +851,10 @@
 			return NULL;
 
 		}
-		declare_flag = 1;
+		register_flag = 1;
 	}
-	iucv_debug("exiting");
+	MOD_INC_USE_COUNT;
+	iucv_debug(1, "exiting");
 	return new_handler;
 }				/* end of register function */
 
@@ -741,24 +864,45 @@
  *
  * Unregister application with IUCV.
  * Returns:
- *   Always 0
+ *   0 on success, -EINVAL, if specified handle is invalid.
  */
 
 int
 iucv_unregister_program (iucv_handle_t handle)
 {
-	handler *h = (handler *)handle;
+	handler *h = NULL;
+	struct list_head *lh;
 	int i;
 	ulong flags;
 
-	iucv_debug("entering");
-	iucv_debug("address of handler is %p", h);
+	iucv_debug(1, "entering");
+	iucv_debug(1, "address of handler is %p", h);
+
+	/* Checking if handle is valid  */
+	spin_lock_irqsave (&iucv_lock, flags);
+	list_for_each(lh, &iucv_handler_table) {
+		if ((handler *)handle == list_entry(lh, handler, list)) {
+			h = (handler *)handle;
+			break;
+		}
+	}
+	if (!h) {
+		spin_unlock_irqrestore (&iucv_lock, flags);
+		if (handle)
+			printk(KERN_WARNING
+			       "%s: Handler not found in iucv_handler_table.\n",
+			       __FUNCTION__);
+		else
+			printk(KERN_WARNING
+			       "%s: NULL handle passed by application.\n",
+			       __FUNCTION__);
+		return -EINVAL;
+	}
 
 	/**
 	 * First, walk thru iucv_pathid_table and sever any pathid which is
 	 * still pointing to the handler to be removed.
 	 */
-	spin_lock_irqsave (&iucv_lock, flags);
 	for (i = 0; i < max_connections; i++)
 		if (iucv_pathid_table[i] == h) {
 			spin_unlock_irqrestore (&iucv_lock, flags);
@@ -770,7 +914,8 @@
 	iucv_remove_handler(h);
 	kfree(h);
 
-	iucv_debug("exiting");
+	MOD_DEC_USE_COUNT;
+	iucv_debug(1, "exiting");
 	return 0;
 }
 
@@ -811,8 +956,8 @@
 	handler *h = NULL;
 	iparml_control *parm;
 
-	iucv_debug("entering");
-	iucv_debug("pathid = %d", pathid);
+	iucv_debug(1, "entering");
+	iucv_debug(1, "pathid = %d", pathid);
 
 	/* Checking if handle is valid  */
 	spin_lock_irqsave (&iucv_lock, flags);
@@ -825,9 +970,14 @@
 	spin_unlock_irqrestore (&iucv_lock, flags);
 
 	if (!h) {
-		printk(KERN_WARNING "%s: NULL handle passed by application "
-		       "or handler not found in iucv_handler_table\n",
-		       __FUNCTION__);
+		if (handle)
+			printk(KERN_WARNING
+			       "%s: Handler not found in iucv_handler_table.\n",
+			       __FUNCTION__);
+		else
+			printk(KERN_WARNING
+			       "%s: NULL handle passed by application.\n",
+			       __FUNCTION__);
 		return -EINVAL;
 	}
 
@@ -849,7 +999,7 @@
 	}
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(1, "exiting");
 	return b2f0_result;
 }
 
@@ -904,7 +1054,7 @@
 	handler *h = NULL;
 	__u8 no_memory[16] = "NO MEMORY";
 
-	iucv_debug("entering");
+	iucv_debug(1, "entering");
 
 	/* Checking if handle is valid  */
 	spin_lock_irqsave (&iucv_lock, flags);
@@ -917,9 +1067,14 @@
 	spin_unlock_irqrestore (&iucv_lock, flags);
 
 	if (!h) {
-		printk(KERN_WARNING "%s: NULL handle passed by application "
-		       "or handler not found in iucv_handler_table\n",
-		       __FUNCTION__);
+		if (handle)
+			printk(KERN_WARNING
+			       "%s: Handler not found in iucv_handler_table.\n",
+			       __FUNCTION__);
+		else
+			printk(KERN_WARNING
+			       "%s: NULL handle passed by application.\n",
+			       __FUNCTION__);
 		return -EINVAL;
 	}
 
@@ -971,7 +1126,7 @@
 		return(add_pathid_result);
 	}
 
-	iucv_debug("exiting");
+	iucv_debug(1, "exiting");
 	return b2f0_result;
 }
 
@@ -993,8 +1148,8 @@
 	iparml_purge *parm;
 	ulong b2f0_result = 0;
 
-	iucv_debug("entering");
-	iucv_debug("pathid = %d", pathid);
+	iucv_debug(1, "entering");
+	iucv_debug(1, "pathid = %d", pathid);
 
 	parm = (iparml_purge *)grab_param();
 
@@ -1012,8 +1167,8 @@
 	
 	release_param(parm);
 
-	iucv_debug("b2f0_result = %ld", b2f0_result);
-	iucv_debug("exiting");
+	iucv_debug(1, "b2f0_result = %ld", b2f0_result);
+	iucv_debug(1, "exiting");
 	return b2f0_result;
 }
 
@@ -1099,8 +1254,8 @@
 	iparml_control *parm;
 	ulong b2f0_result = 0;
 
-	iucv_debug("entering");
-	iucv_debug("pathid = %d", pathid);
+	iucv_debug(1, "entering");
+	iucv_debug(1, "pathid = %d", pathid);
 
 	parm = (iparml_control *)grab_param();
 
@@ -1110,8 +1265,8 @@
 	b2f0_result = b2f0(QUIESCE, parm);
 	release_param(parm);
 
-	iucv_debug("b2f0_result = %ld", b2f0_result);
-	iucv_debug("exiting");
+	iucv_debug(1, "b2f0_result = %ld", b2f0_result);
+	iucv_debug(1, "exiting");
 
 	return b2f0_result;
 }
@@ -1152,7 +1307,7 @@
 	ulong b2f0_result;
 	int moved = 0;	/* number of bytes moved from parmlist to buffer */
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!buffer)
 		return -EINVAL;
@@ -1170,9 +1325,9 @@
 
 	if (b2f0_result == 0 || b2f0_result == 5) {
 		if (flags1_out) {
-			iucv_debug("*flags1_out = %d", *flags1_out);
+			iucv_debug(2, "*flags1_out = %d", *flags1_out);
 			*flags1_out = (parm->ipflags1 & (~0x07));
-			iucv_debug("*flags1_out = %d", *flags1_out);
+			iucv_debug(2, "*flags1_out = %d", *flags1_out);
 		}
 
 		if (!(parm->ipflags1 & IPRMDATA)) {	/*msg not in parmlist */
@@ -1199,7 +1354,7 @@
 	}
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 	return b2f0_result;
 }
 
@@ -1242,7 +1397,7 @@
 	ulong b2f0_result;
 	int i = 0, moved = 0, need_to_move = 8, dyn_len;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!buffer)
 		return -EINVAL;
@@ -1261,9 +1416,9 @@
 	if (b2f0_result == 0 || b2f0_result == 5) {
 
 		if (flags1_out) {
-			iucv_debug("*flags1_out = %d", *flags1_out);
+			iucv_debug(2, "*flags1_out = %d", *flags1_out);
 			*flags1_out = (parm->ipflags1 & (~0x07));
-			iucv_debug("*flags1_out = %d", *flags1_out);
+			iucv_debug(2, "*flags1_out = %d", *flags1_out);
 		}
 
 		if (!(parm->ipflags1 & IPRMDATA)) {	/*msg not in parmlist */
@@ -1316,7 +1471,7 @@
 	}
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 	return b2f0_result;
 }
 
@@ -1337,8 +1492,8 @@
 	iparml_db *parm;
 	ulong b2f0_result = 0;
 
-	iucv_debug("entering");
-	iucv_debug("pathid = %d", pathid);
+	iucv_debug(1, "entering");
+	iucv_debug(1, "pathid = %d", pathid);
 
 	parm = (iparml_db *)grab_param();
 
@@ -1350,8 +1505,8 @@
 	b2f0_result = b2f0(REJECT, parm);
 	release_param(parm);
 
-	iucv_debug("b2f0_result = %ld", b2f0_result);
-	iucv_debug("exiting");
+	iucv_debug(1, "b2f0_result = %ld", b2f0_result);
+	iucv_debug(1, "exiting");
 
 	return b2f0_result;
 }
@@ -1391,7 +1546,7 @@
 	iparml_db *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!buffer)
 		return -EINVAL;
@@ -1415,7 +1570,7 @@
 	}
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 
 	return b2f0_result;
 }
@@ -1457,7 +1612,7 @@
 	iparml_db *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!buffer)
 		return -EINVAL;
@@ -1482,7 +1637,7 @@
 	}
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 
 	return b2f0_result;
 }
@@ -1511,7 +1666,7 @@
 	iparml_dpl *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	parm = (iparml_dpl *)grab_param();
 
@@ -1524,7 +1679,7 @@
 	b2f0_result = b2f0(REPLY, parm);
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 
 	return b2f0_result;
 }
@@ -1543,8 +1698,8 @@
 	iparml_control *parm;
 	ulong b2f0_result = 0;
 
-	iucv_debug("entering");
-	iucv_debug("pathid = %d", pathid);
+	iucv_debug(1, "entering");
+	iucv_debug(1, "pathid = %d", pathid);
 
 	parm = (iparml_control *)grab_param();
 
@@ -1554,7 +1709,7 @@
 	b2f0_result = b2f0(RESUME, parm);
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(1, "exiting");
 
 	return b2f0_result;
 }
@@ -1582,7 +1737,7 @@
 	iparml_db *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!buffer)
 		return -EINVAL;
@@ -1603,7 +1758,7 @@
 		*msgid = parm->ipmsgid;
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 
 	return b2f0_result;
 }
@@ -1637,7 +1792,7 @@
 	iparml_db *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!buffer)
 		return -EINVAL;
@@ -1657,7 +1812,7 @@
 		*msgid = parm->ipmsgid;
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 	return b2f0_result;
 }
 
@@ -1686,7 +1841,7 @@
 	iparml_dpl *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	parm = (iparml_dpl *)grab_param();
 
@@ -1703,7 +1858,7 @@
 		*msgid = parm->ipmsgid;
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 
 	return b2f0_result;
 }
@@ -1741,7 +1896,7 @@
 	iparml_db *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!buffer || !ansbuf)
 		return -EINVAL;
@@ -1764,7 +1919,7 @@
 		*msgid = parm->ipmsgid;
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 
 	return b2f0_result;
 }
@@ -1804,7 +1959,7 @@
 	iparml_db *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!buffer || !ansbuf)
 		return -EINVAL;
@@ -1825,7 +1980,7 @@
 		*msgid = parm->ipmsgid;
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 	return b2f0_result;
 }
 
@@ -1861,7 +2016,7 @@
 	iparml_dpl *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!ansbuf)
 		return -EINVAL;
@@ -1883,7 +2038,7 @@
 		*msgid = parm->ipmsgid;
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 
 	return b2f0_result;
 }
@@ -1924,7 +2079,7 @@
 	iparml_dpl *parm;
 	ulong b2f0_result;
 
-	iucv_debug("entering");
+	iucv_debug(2, "entering");
 
 	if (!ansbuf)
 		return -EINVAL;
@@ -1944,7 +2099,7 @@
 		*msgid = parm->ipmsgid;
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(2, "exiting");
 	return b2f0_result;
 }
 
@@ -1967,7 +2122,7 @@
 	iparml_set_mask *parm;
 	ulong b2f0_result = 0;
 
-	iucv_debug("entering");
+	iucv_debug(1, "entering");
 
 	parm = (iparml_set_mask *)grab_param();
 
@@ -1976,8 +2131,8 @@
 	b2f0_result = b2f0(SETMASK, parm);
 	release_param(parm);
 
-	iucv_debug("b2f0_result = %ld", b2f0_result);
-	iucv_debug("exiting");
+	iucv_debug(1, "b2f0_result = %ld", b2f0_result);
+	iucv_debug(1, "exiting");
 
 	return b2f0_result;
 }
@@ -1996,7 +2151,7 @@
 	iparml_control *parm;
 	ulong b2f0_result = 0;
 
-	iucv_debug("entering");
+	iucv_debug(1, "entering");
 	parm = (iparml_control *)grab_param();
 
 	memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));
@@ -2008,7 +2163,7 @@
 		iucv_remove_pathid(pathid);
 	release_param(parm);
 
-	iucv_debug("exiting");
+	iucv_debug(1, "exiting");
 	return b2f0_result;
 }
 
@@ -2073,10 +2228,10 @@
 	int rc = 0, j = 0;
 	__u8 no_listener[16] = "NO LISTENER";
 
-	iucv_debug("entering, pathid %d, type %02X",
+	iucv_debug(2, "entering, pathid %d, type %02X",
 		 int_buf->ippathid, int_buf->iptype);
-	iucv_debug("External Interrupt Buffer:");
-	iucv_dumpit(int_buf, sizeof(iucv_GeneralInterrupt));
+	iucv_dumpit("External Interrupt Buffer:",
+		    int_buf, sizeof(iucv_GeneralInterrupt));
 
 	ASCEBC (no_listener, 16);
 
@@ -2088,9 +2243,7 @@
 		} else {
 			h = iucv_pathid_table[int_buf->ippathid];
 			interrupt = h->interrupt_table;
-
-			iucv_debug("Handler:");
-			iucv_dumpit(h, sizeof(handler));
+			iucv_dumpit("Handler:", h, sizeof(handler));
 		}
 	}
 
@@ -2107,14 +2260,15 @@
 					temp_buff2[j] &= (h->id.mask)[j];
 				}
 				
-				iucv_debug("temp_buff1:");
-				iucv_dumpit(temp_buff1, sizeof(temp_buff1));
-				iucv_debug("temp_buff2");
-				iucv_dumpit(temp_buff2, sizeof(temp_buff2));
+				iucv_dumpit("temp_buff1:",
+					    temp_buff1, sizeof(temp_buff1));
+				iucv_dumpit("temp_buff2",
+					    temp_buff2, sizeof(temp_buff2));
 				
 				if (memcmp (temp_buff1, temp_buff2, 24) == 0) {
 					
-					iucv_debug("found a matching handler");
+					iucv_debug(2,
+						   "found a matching handler");
 					break;
 				}
 			}
@@ -2125,7 +2279,8 @@
 				if (rc) {
 					iucv_sever (int_buf->ippathid,
 						    no_listener);
-					iucv_debug("add_pathid failed, rc = %d",
+					iucv_debug(1,
+						   "add_pathid failed, rc = %d",
 						   rc);
 				} else {
 					interrupt = h->interrupt_table;
@@ -2149,7 +2304,8 @@
 						(iucv_ConnectionComplete *)int_buf,
 						h->pgm_data);
 				else
-					iucv_debug("ConnectionComplete not called");
+					iucv_debug(1,
+						   "ConnectionComplete not called");
 			} else
 				iucv_sever(int_buf->ippathid, no_listener);
 			break;
@@ -2174,7 +2330,8 @@
 						(iucv_ConnectionQuiesced *)int_buf,
 						h->pgm_data);
 				else
-					iucv_debug("ConnectionQuiesced not called");
+					iucv_debug(1,
+						   "ConnectionQuiesced not called");
 			}
 			break;
 			
@@ -2185,7 +2342,8 @@
 						(iucv_ConnectionResumed *)int_buf,
 						h->pgm_data);
 				else
-					iucv_debug("ConnectionResumed not called");
+					iucv_debug(1,
+						   "ConnectionResumed not called");
 			}
 			break;
 			
@@ -2197,7 +2355,8 @@
 						(iucv_MessageComplete *)int_buf,
 						h->pgm_data);
 				else
-					iucv_debug("MessageComplete not called");
+					iucv_debug(2,
+						   "MessageComplete not called");
 			}
 			break;
 			
@@ -2209,7 +2368,8 @@
 						(iucv_MessagePending *) int_buf,
 						h->pgm_data);
 				else
-					iucv_debug("MessagePending not called");
+					iucv_debug(2,
+						   "MessagePending not called");
 			}
 			break;
 		default:		/* unknown iucv type */
@@ -2218,7 +2378,7 @@
 			break;
 	}			/* end switch */
 	
-	iucv_debug("exiting pathid %d, type %02X",
+	iucv_debug(2, "exiting pathid %d, type %02X",
 		 int_buf->ippathid, int_buf->iptype);
 
 	return;
@@ -2256,6 +2416,9 @@
 	return;
 }
 
+module_init(iucv_init);
+module_exit(iucv_exit);
+
 /**
  * Export all public stuff
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/net/netiucv.c linux/drivers/s390/net/netiucv.c
--- linux.orig/drivers/s390/net/netiucv.c	2002-02-25 19:38:03.000000000 +0000
+++ linux/drivers/s390/net/netiucv.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.16 2001/12/03 14:28:45 felfert Exp $
+ * $Id: netiucv.c,v 1.17 2002/02/12 21:52:20 felfert Exp $
  *
  * IUCV network driver
  *
@@ -28,7 +28,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.16 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.17 $
  *
  */
 
@@ -70,7 +70,7 @@
 MODULE_PARM (iucv, "1s");
 MODULE_PARM_DESC (iucv,
 		  "Specify the initial remote userids for iucv0 .. iucvn:\n"
-		  "iucv=userid0:userid1:...:useridN\n");
+		  "iucv=userid0:userid1:...:useridN");
 #endif
 
 static char *iucv = "";
@@ -2005,7 +2005,7 @@
 static void
 netiucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.16 $";
+	char vbuf[] = "$Revision: 1.17 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/s390/s390io.c linux/drivers/s390/s390io.c
--- linux.orig/drivers/s390/s390io.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/s390/s390io.c	2002-07-20 01:08:28.000000000 +0000
@@ -93,7 +93,6 @@
 
 static spinlock_t  adapter_lock = SPIN_LOCK_UNLOCKED;
                                           // adapter interrupt lock
-static psw_t      io_sync_wait;           // wait PSW for sync IO, prot. by sync_isc
 static int        cons_dev          = -1; // identify console device
 static int        init_IRQ_complete = 0;
 static int        cio_show_msg      = 0;
@@ -1413,7 +1412,7 @@
 		 */
 		if ( flag & DOIO_WAIT_FOR_INTERRUPT )
 		{
-			psw_t            io_new_psw;
+			unsigned long    psw_mask;
 			int              ccode;
 			uint64_t         time_start;    	
 			uint64_t         time_curr;    	
@@ -1431,30 +1430,25 @@
 			 *  sync. interrupt arrived we reset the I/O old PSW to
 			 *  its original value.
 			 */
-			memcpy( &io_new_psw, &lc->io_new_psw, sizeof(psw_t));
 
 			ccode = iac();
 
 			switch (ccode) {
 			case 0:  		// primary-space
-				io_sync_wait.mask =   _IO_PSW_MASK
-				                    | _PSW_PRIM_SPACE_MODE
-				                    | _PSW_IO_WAIT;
+				psw_mask = _IO_PSW_MASK
+				    | _PSW_PRIM_SPACE_MODE | _PSW_IO_WAIT;
 				break;
 			case 1:			// secondary-space
-				io_sync_wait.mask =   _IO_PSW_MASK
-				                    | _PSW_SEC_SPACE_MODE
-				                    | _PSW_IO_WAIT;
+				psw_mask = _IO_PSW_MASK
+				    | _PSW_SEC_SPACE_MODE | _PSW_IO_WAIT;
 				break;
 			case 2:			// access-register
-				io_sync_wait.mask =   _IO_PSW_MASK
-				                    | _PSW_ACC_REG_MODE
-				                    | _PSW_IO_WAIT;
+				psw_mask = _IO_PSW_MASK
+				    | _PSW_ACC_REG_MODE | _PSW_IO_WAIT;
 				break;
 			case 3:			// home-space	
-				io_sync_wait.mask =   _IO_PSW_MASK
-				                    | _PSW_HOME_SPACE_MODE
-				                    | _PSW_IO_WAIT;
+				psw_mask = _IO_PSW_MASK
+				    | _PSW_HOME_SPACE_MODE | _PSW_IO_WAIT;
 				break;
 			default:
 				panic( "start_IO() : unexpected "
@@ -1463,8 +1457,6 @@
 				break;
 			} /* endswitch */
 
-			io_sync_wait.addr = FIX_PSW(&&io_wakeup);
-
 			/*
 			 * Martin didn't like modifying the new PSW, now we take
 			 *  a fast exit in do_IRQ() instead
@@ -1502,9 +1494,8 @@
 				}
 				else
 				{
-					__load_psw( io_sync_wait );
+					__load_psw_mask( psw_mask );
 
-io_wakeup:
 					io_sub  = (__u32)*(__u16 *)__LC_SUBCHANNEL_NR;
 
 				} /* endif */
@@ -1984,7 +1975,7 @@
 			{
 				int              io_sub;
 				__u32            io_parm;
-				psw_t            io_new_psw;
+				unsigned long    psw_mask;
 				int              ccode;
   	
 				int              ready = 0;
@@ -1999,32 +1990,29 @@
 				 *  arrived we reset the I/O old PSW to its
 				 *  original value.
 				 */
-				memcpy( &io_new_psw,
-				        &lc->io_new_psw,
-				        sizeof(psw_t));
 
 				ccode = iac();
 
 				switch (ccode) {
 				case 0:  		// primary-space
-					io_sync_wait.mask =   _IO_PSW_MASK
-					                    | _PSW_PRIM_SPACE_MODE
-					                    | _PSW_IO_WAIT;
+					psw_mask = _IO_PSW_MASK
+						| _PSW_PRIM_SPACE_MODE
+						| _PSW_IO_WAIT;
 					break;
 				case 1:			// secondary-space
-					io_sync_wait.mask =   _IO_PSW_MASK
-					                    | _PSW_SEC_SPACE_MODE
-					                    | _PSW_IO_WAIT;
+					psw_mask = _IO_PSW_MASK
+						| _PSW_SEC_SPACE_MODE
+						| _PSW_IO_WAIT;
 					break;
 				case 2:			// access-register
-					io_sync_wait.mask =   _IO_PSW_MASK
-					                    | _PSW_ACC_REG_MODE
-					                    | _PSW_IO_WAIT;
+					psw_mask = _IO_PSW_MASK
+						| _PSW_ACC_REG_MODE
+						| _PSW_IO_WAIT;
 					break;
 				case 3:			// home-space	
-					io_sync_wait.mask =   _IO_PSW_MASK
-					                    | _PSW_HOME_SPACE_MODE
-					                    | _PSW_IO_WAIT;
+					psw_mask = _IO_PSW_MASK
+						| _PSW_HOME_SPACE_MODE
+						| _PSW_IO_WAIT;
 					break;
 				default:
 					panic( "halt_IO() : unexpected "
@@ -2033,8 +2021,6 @@
 					break;
 				} /* endswitch */
 
-				io_sync_wait.addr = FIX_PSW(&&hio_wakeup);
-
 				/*
 				 * Martin didn't like modifying the new PSW, now we take
 				 *  a fast exit in do_IRQ() instead
@@ -2044,8 +2030,8 @@
 				do
 				{
 
-					__load_psw( io_sync_wait );
-hio_wakeup:
+					__load_psw_mask( psw_mask );
+
 				   io_parm = *(__u32 *)__LC_IO_INT_PARM;
 				   io_sub  = (__u32)*(__u16 *)__LC_SUBCHANNEL_NR;
 
@@ -2243,7 +2229,7 @@
 			{
 				int              io_sub;
 				__u32            io_parm;
-				psw_t            io_new_psw;
+				unsigned long    psw_mask;
 				int              ccode;
   	
 				int              ready = 0;
@@ -2258,32 +2244,29 @@
 				 *  arrived we reset the I/O old PSW to its
 				 *  original value.
 				 */
-				memcpy( &io_new_psw,
-				        &lc->io_new_psw,
-				        sizeof(psw_t));
 
 				ccode = iac();
 
 				switch (ccode) {
 				case 0:  		// primary-space
-					io_sync_wait.mask =   _IO_PSW_MASK
-					                    | _PSW_PRIM_SPACE_MODE
-					                    | _PSW_IO_WAIT;
+					psw_mask = _IO_PSW_MASK
+						| _PSW_PRIM_SPACE_MODE
+						| _PSW_IO_WAIT;
 					break;
 				case 1:			// secondary-space
-					io_sync_wait.mask =   _IO_PSW_MASK
-					                    | _PSW_SEC_SPACE_MODE
-					                    | _PSW_IO_WAIT;
+					psw_mask = _IO_PSW_MASK
+						| _PSW_SEC_SPACE_MODE
+						| _PSW_IO_WAIT;
 					break;
 				case 2:			// access-register
-					io_sync_wait.mask =   _IO_PSW_MASK
-					                    | _PSW_ACC_REG_MODE
-					                    | _PSW_IO_WAIT;
+					psw_mask = _IO_PSW_MASK
+						| _PSW_ACC_REG_MODE
+						| _PSW_IO_WAIT;
 					break;
 				case 3:			// home-space	
-					io_sync_wait.mask =   _IO_PSW_MASK
-					                    | _PSW_HOME_SPACE_MODE
-					                    | _PSW_IO_WAIT;
+					psw_mask =   _IO_PSW_MASK
+					        | _PSW_HOME_SPACE_MODE
+					        | _PSW_IO_WAIT;
 					break;
 				default:
 					panic( "clear_IO() : unexpected "
@@ -2292,8 +2275,6 @@
 					break;
 				} /* endswitch */
 
-				io_sync_wait.addr = FIX_PSW(&&cio_wakeup);
-
 				/*
 				 * Martin didn't like modifying the new PSW, now we take
 				 *  a fast exit in do_IRQ() instead
@@ -2302,9 +2283,8 @@
 
 				do
 				{
+					__load_psw_mask( psw_mask );
 
-					__load_psw( io_sync_wait );
-cio_wakeup:
 				   io_parm = *(__u32 *)__LC_IO_INT_PARM;
 				   io_sub  = (__u32)*(__u16 *)__LC_SUBCHANNEL_NR;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/audio/amd7930.c linux/drivers/sbus/audio/amd7930.c
--- linux.orig/drivers/sbus/audio/amd7930.c	2001-10-17 21:16:39.000000000 +0000
+++ linux/drivers/sbus/audio/amd7930.c	2002-07-20 01:08:40.000000000 +0000
@@ -1619,7 +1619,6 @@
 	info->irq = irq.pri;
 	request_irq(info->irq, amd7930_interrupt,
 		    SA_INTERRUPT, "amd7930", drv);
-	enable_irq(info->irq);
 	amd7930_enable_ints(info);
 
 	/* Initalize the local copy of the MAP registers. */
@@ -1644,7 +1643,6 @@
 	err = register_sparcaudio_driver(drv, 1);
 	if (err < 0) {
 		printk(KERN_ERR "amd7930: unable to register\n");
-		disable_irq(info->irq);
 		free_irq(info->irq, drv);
 		sbus_iounmap(info->regs, info->regs_size);
 		kfree(drv->private);
@@ -1666,7 +1664,6 @@
 
 	unregister_sparcaudio_driver(drv, 1);
 	amd7930_idle(info);
-	disable_irq(info->irq);
 	free_irq(info->irq, drv);
 	sbus_iounmap(info->regs, info->regs_size);
 	kfree(drv->private);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/audio/cs4231.c linux/drivers/sbus/audio/cs4231.c
--- linux.orig/drivers/sbus/audio/cs4231.c	2001-10-11 06:42:46.000000000 +0000
+++ linux/drivers/sbus/audio/cs4231.c	2002-07-20 01:08:38.000000000 +0000
@@ -35,7 +35,7 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/sbus.h>
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
 #define EB4231_SUPPORT
 #include <asm/ebus.h>
 #include <asm/pbm.h>
@@ -2210,7 +2210,6 @@
         /* Attach the interrupt handler to the audio interrupt. */
         cs4231_chip->irq = sdev->irqs[0];
         request_irq(cs4231_chip->irq, cs4231_interrupt, SA_SHIRQ, "cs4231", drv);
-        enable_irq(cs4231_chip->irq);
 
         cs4231_chip->nirqs = 1;
         cs4231_enable_interrupts(drv);
@@ -2224,7 +2223,6 @@
         if (err < 0) {
                 printk(KERN_ERR "cs4231: unable to register\n");
                 cs4231_disable_interrupts(drv);
-                disable_irq(cs4231_chip->irq);
                 free_irq(cs4231_chip->irq, drv);
                 sbus_iounmap(cs4231_chip->regs, cs4231_chip->regs_size);
                 kfree(drv->private);
@@ -2312,9 +2310,7 @@
         bail:
                 printk(KERN_ERR "cs4231: unable to register\n");
                 cs4231_disable_interrupts(drv);
-                disable_irq(cs4231_chip->irq);
                 free_irq(cs4231_chip->irq, drv);
-                disable_irq(cs4231_chip->irq2);
                 free_irq(cs4231_chip->irq2, drv);
                 kfree(drv->private);
                 return -EIO;
@@ -2371,7 +2367,6 @@
 
 	cs4231_disable_interrupts(drv);
 	unregister_sparcaudio_driver(drv, 1);
-	disable_irq(cs4231_chip->irq);
 	free_irq(cs4231_chip->irq, drv);
 	if (!(cs4231_chip->status & CS_STATUS_IS_EBUS)) {
 		sbus_iounmap(cs4231_chip->regs, cs4231_chip->regs_size);
@@ -2380,7 +2375,6 @@
 		iounmap(cs4231_chip->regs);
 		iounmap(cs4231_chip->eb2p);
 		iounmap(cs4231_chip->eb2c);
-		disable_irq(cs4231_chip->irq2);
 		free_irq(cs4231_chip->irq2, drv);
 #endif
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c
--- linux.orig/drivers/sbus/char/pcikbd.c	2001-08-28 14:09:44.000000000 +0000
+++ linux/drivers/sbus/char/pcikbd.c	2002-07-20 01:08:38.000000000 +0000
@@ -29,7 +29,7 @@
 #include <linux/init.h>
 
 #include <asm/ebus.h>
-#if defined(CONFIG_USB) && defined(CONFIG_SPARC64)
+#if (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)) && defined(CONFIG_SPARC64)
 #include <asm/isa.h>
 #endif
 #include <asm/oplib.h>
@@ -640,7 +640,7 @@
 	restore_flags(flags);
 }
 
-#if defined(CONFIG_USB) && defined(CONFIG_SPARC64)
+#if (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)) && defined(CONFIG_SPARC64)
 static void isa_kd_nosound(unsigned long __unused)
 {
 	/* disable counter 2 */
@@ -758,7 +758,7 @@
 				}
 			}
 		}
-#ifdef CONFIG_USB
+#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
 		/* We are being called for the sake of USB keyboard
 		 * state initialization.  So we should check for beeper
 		 * device in this case.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c
--- linux.orig/drivers/sbus/char/sab82532.c	2001-10-17 21:16:39.000000000 +0000
+++ linux/drivers/sbus/char/sab82532.c	2002-07-20 01:08:33.000000000 +0000
@@ -361,10 +361,6 @@
 		writeb(SAB82532_CMDR_RMC, &info->regs->w.cmdr);
 	}
 
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (info->is_console)
-		wake_up(&keypress_wait);
-#endif
 	if (!tty)
 		return;
 
@@ -2541,13 +2537,6 @@
 	sab82532_tec_wait(info);
 }
 
-static int
-sab82532_console_wait_key(struct console *con)
-{
-	sleep_on(&keypress_wait);
-	return 0;
-}
-
 static kdev_t
 sab82532_console_device(struct console *con)
 {
@@ -2622,7 +2611,6 @@
 	name:		"ttyS",
 	write:		sab82532_console_write,
 	device:		sab82532_console_device,
-	wait_key:	sab82532_console_wait_key,
 	setup:		sab82532_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/char/su.c linux/drivers/sbus/char/su.c
--- linux.orig/drivers/sbus/char/su.c	2001-11-13 17:16:05.000000000 +0000
+++ linux/drivers/sbus/char/su.c	2002-07-20 01:08:28.000000000 +0000
@@ -2854,40 +2854,6 @@
 	su_outb(info, UART_IER, ier);
 }
 
-/*
- *	Receive character from the serial port
- */
-static int
-serial_console_wait_key(struct console *co)
-{
-	struct su_struct *info;
-	int ier;
-	int lsr;
-	int c;
-
-	info = su_table + co->index;
-
-	/*
-	 *	First save the IER then disable the interrupts so
-	 *	that the real driver for the port does not get the
-	 *	character.
-	 */
-	ier = su_inb(info, UART_IER);
-	su_outb(info, UART_IER, 0x00);
-
-	do {
-		lsr = su_inb(info, UART_LSR);
-	} while (!(lsr & UART_LSR_DR));
-	c = su_inb(info, UART_RX);
-
-	/*
-	 *	Restore the interrupts
-	 */
-	su_outb(info, UART_IER, ier);
-
-	return c;
-}
-
 static kdev_t
 serial_console_device(struct console *c)
 {
@@ -3013,7 +2979,6 @@
 	name:		"ttyS",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c
--- linux.orig/drivers/sbus/char/sunkbd.c	2001-09-17 04:22:50.000000000 +0000
+++ linux/drivers/sbus/char/sunkbd.c	2002-07-20 01:08:38.000000000 +0000
@@ -82,16 +82,6 @@
 
 struct l1a_kbd_state l1a_state;
 
-#ifndef CONFIG_PCI
-DECLARE_WAIT_QUEUE_HEAD(keypress_wait);
-#endif
-
-int keyboard_wait_for_keypress(struct console *co)
-{
-	sleep_on(&keypress_wait);
-	return 0;
-}
-
 static spinlock_t sunkbd_lock = SPIN_LOCK_UNLOCKED;
 
 /*
@@ -629,7 +619,6 @@
 
 static void put_queue(int ch)
 {
-	wake_up(&keypress_wait);
 	if (tty) {
 		tty_insert_flip_char(tty, ch, 0);
 		con_schedule_flip(tty);
@@ -638,7 +627,6 @@
 
 static void puts_queue(char *cp)
 {
-	wake_up(&keypress_wait);
 	if (!tty)
 		return;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/char/sunserial.c linux/drivers/sbus/char/sunserial.c
--- linux.orig/drivers/sbus/char/sunserial.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sbus/char/sunserial.c	2002-07-20 01:08:22.000000000 +0000
@@ -139,7 +139,7 @@
 	nop_getkeycode
 };
 
-#ifdef CONFIG_USB
+#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
 extern void pci_compute_shiftstate(void);
 extern int pci_setkeycode(unsigned int, unsigned int);
 extern int pci_getkeycode(unsigned int);
@@ -158,7 +158,7 @@
 		err = init->init();
 		init = init->next;
 	}
-#ifdef CONFIG_USB
+#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
 	if (!serial_console &&
 	    kbd_ops.compute_shiftstate == nop_compute_shiftstate) {
 		printk("kbd_init: Assuming USB keyboard.\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/char/uctrl.c linux/drivers/sbus/char/uctrl.c
--- linux.orig/drivers/sbus/char/uctrl.c	2001-10-11 06:42:47.000000000 +0000
+++ linux/drivers/sbus/char/uctrl.c	2002-07-20 01:08:40.000000000 +0000
@@ -389,15 +389,11 @@
 	if(!driver->irq) 
 		driver->irq = tmp_irq[0].pri;
 
-	request_irq(driver->irq, uctrl_interrupt, 0, 
-		    "uctrl", driver);
-
-	enable_irq(driver->irq);
+	request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
 
 	if (misc_register(&uctrl_dev)) {
 		printk("%s: unable to get misc minor %d\n",
 		       __FUNCTION__, uctrl_dev.minor);
-		disable_irq(driver->irq);
 		free_irq(driver->irq, driver);
 		return -ENODEV;
 	}
@@ -414,10 +410,8 @@
 	struct uctrl_driver *driver = &drv;
 
 	misc_deregister(&uctrl_dev);
-	if (driver->irq) {
-		disable_irq(driver->irq);
+	if (driver->irq)
 		free_irq(driver->irq, driver);
-	}
 	if (driver->regs)
 		driver->regs = 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/char/zs.c linux/drivers/sbus/char/zs.c
--- linux.orig/drivers/sbus/char/zs.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sbus/char/zs.c	2002-07-20 01:08:40.000000000 +0000
@@ -543,8 +543,6 @@
 				/* Continue execution... */
 				return;
 			}
-			/* It is a 'keyboard interrupt' ;-) */
-			wake_up(&keypress_wait);
 		}
 #ifndef __sparc_v9__
 		/* Look for kgdb 'stop' character, consult the gdb
@@ -2797,13 +2795,6 @@
 #endif
 }
 
-static int
-zs_console_wait_key(struct console *con)
-{
-	sleep_on(&keypress_wait);
-	return 0;
-}
-
 static kdev_t zs_console_device(struct console *con)
 {
 	return MKDEV(TTY_MAJOR, 64 + con->index);
@@ -2881,7 +2872,6 @@
 	name:		"ttyS",
 	write:		zs_console_write,
 	device:		zs_console_device,
-	wait_key:	zs_console_wait_key,
 	setup:		zs_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sbus/sbus.c linux/drivers/sbus/sbus.c
--- linux.orig/drivers/sbus/sbus.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sbus/sbus.c	2002-07-20 01:08:34.000000000 +0000
@@ -391,6 +391,10 @@
 		sbus_bus_ranges_init(iommund, sbus);
 
 		sbus_devs = prom_getchild(this_sbus);
+		if (!sbus_devs) {
+			sbus->devices = NULL;
+			goto next_bus;
+		}
 
 		sbus->devices = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
 
@@ -454,7 +458,7 @@
 		sbus_fixup_all_regs(sbus->devices);
 
 		dvma_init(sbus);
-
+	next_bus:
 		num_sbus++;
 		if(sparc_cpu_model == sun4u) {
 			this_sbus = prom_getsibling(this_sbus);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- linux.orig/drivers/scsi/3w-xxxx.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/3w-xxxx.c	2002-07-20 01:08:33.000000000 +0000
@@ -121,13 +121,39 @@
    1.02.00.015 - Re-write raw command post with data ioctl method.
    1.02.00.016 - Set max_cmd_len for 3dm.
                  Set max sectors to 256 for non raid5 & 6XXX.          
+   1.02.00.017 - Modified pci parity error handling/clearing from config space
+                 during initialization.
+   1.02.00.018 - Better handling of request sense opcode and sense information
+                 for failed commands.  Add tw_decode_sense().
+                 Replace all mdelay()'s with scsi_sleep().
+   1.02.00.019 - Revert mdelay's and scsi_sleep's, this caused problems on
+                 some SMP systems.
+   1.02.00.020 - Bump cmd_per_lun in SHT to 255 for better jbod performance.
+                 Make module license ifdef'd for backward compatibility.
+                 Improve handling of errors in tw_interrupt().
+                 Add handling/clearing of controller queue error.
+                 Better alignment checking in tw_allocate_memory().
+                 Cleanup tw_initialize_device_extension().
+                 Empty stale responses before draining aen queue.
+                 Fix tw_scsi_eh_abort() to not reset on every io abort.
+                 Set can_queue in SHT to 255 to prevent hang from AEN.
+   1.02.00.021 - Fix possible null pointer dereference in tw_scsi_release().
+   1.02.00.022 - Fix bug in tw_aen_drain_queue() where unit # was always zero.
+   1.02.00.023 - Add severity levels to AEN strings.
+   1.02.00.024 - Fix command interrupt spurious error messages.
+                 Fix bug in raw command post with data ioctl method.
+                 Fix bug where rollcall sometimes failed with cable errors.
+   1.02.00.025 - Print unit # on all command timeouts.
 */
 
 #include <linux/module.h>
 
 MODULE_AUTHOR ("3ware Inc.");
+#ifdef __SMP__
+MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver (SMP)");
+#else
 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
-MODULE_LICENSE("GPL");
+#endif
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -156,6 +182,10 @@
 
 #include "3w-xxxx.h"
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)
+MODULE_LICENSE("GPL");
+#endif
+
 static int tw_copy_info(TW_Info *info, char *fmt, ...);
 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
@@ -167,7 +197,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.02.00.016";
+char *tw_driver_version="1.02.00.025";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -191,7 +221,7 @@
 
 	/* Print some useful info when certain aen codes come out */
 	if (aen == 0x0ff) {
-		printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: AEN queue overflow.\n", tw_dev->host->host_no);
+		printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
 	} else {
 		if ((aen & 0x0ff) < TW_AEN_STRING_MAX) {
 			if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
@@ -263,12 +293,15 @@
 	status_reg_addr = tw_dev->registers.status_reg_addr;
 	response_que_addr = tw_dev->registers.response_que_addr;
 
-	if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 30)) {
+	if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
 		dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
 		return 1;
 	}
 	tw_clear_attention_interrupt(tw_dev);
 
+	/* Empty response queue */
+	tw_empty_response_que(tw_dev);
+
 	/* Initialize command packet */
 	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
 		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
@@ -322,7 +355,7 @@
 			status_reg_value = inl(status_reg_addr);
 			if (tw_check_bits(status_reg_value)) {
 				dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n");
-				tw_decode_bits(tw_dev, status_reg_value);
+				tw_decode_bits(tw_dev, status_reg_value, 0);
 				return 1;
 			}
 			if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -338,8 +371,7 @@
 				if (command_packet->status != 0) {
 					if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
 						/* Bad response */
-						dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
-						tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
+						tw_decode_sense(tw_dev, request_id, 0);
 						return 1;
 					} else {
 						/* We know this is a 3w-1x00, and doesn't support aen's */
@@ -371,7 +403,7 @@
 						break;
 					default:
 						if (aen == 0x0ff) {
-							printk(KERN_WARNING "3w-xxxx: AEN: AEN queue overflow.\n");
+							printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
 						} else {
 							if ((aen & 0x0ff) < TW_AEN_STRING_MAX) {
 								if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
@@ -388,7 +420,7 @@
 
 				/* Now put the aen on the aen_queue */
 				if (queue == 1) {
-					tw_dev->aen_queue[tw_dev->aen_tail] = aen_code;
+					tw_dev->aen_queue[tw_dev->aen_tail] = aen;
 					if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
 						tw_dev->aen_tail = TW_Q_START;
 					} else {
@@ -437,7 +469,7 @@
 	status_reg_value = inl(status_reg_addr);
 	if (tw_check_bits(status_reg_value)) {
 		dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
-		tw_decode_bits(tw_dev, status_reg_value);
+		tw_decode_bits(tw_dev, status_reg_value, 1);
 		return 1;
 	}
 	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
@@ -504,9 +536,9 @@
 		return 1;
 	}
 
-	if ((u32)virt_addr % TW_ALIGNMENT) {
+	if ((u32)virt_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
 		kfree(virt_addr);
-		printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n");
+		printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
 		return 1;
 	}
 
@@ -552,12 +584,24 @@
 	status_reg_addr = tw_dev->registers.status_reg_addr;
 	status_reg_value = inl(status_reg_addr);
 
-	if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value))
+	if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
+		tw_decode_bits(tw_dev, status_reg_value, 0);
 		return 1;
+	}
 
 	return 0;
 } /* End tw_check_errors() */
 
+/* This function will clear all interrupts on the controller */
+void tw_clear_all_interrupts(TW_Device_Extension *tw_dev)
+{
+	u32 control_reg_addr, control_reg_value;
+
+	control_reg_addr = tw_dev->registers.control_reg_addr;
+	control_reg_value = TW_STATUS_VALID_INTERRUPT;
+	outl(control_reg_value, control_reg_addr);
+} /* End tw_clear_all_interrupts() */
+
 /* This function will clear the attention interrupt */
 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev)
 {
@@ -613,47 +657,90 @@
 } /* End tw_copy_mem_info() */
 
 /* This function will print readable messages from status register errors */
-void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
+int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
 {
+	char host[16];
+	
 	dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
+
+	if (print_host)
+		sprintf(host, " scsi%d:", tw_dev->host->host_no);
+	else
+		host[0] = '\0';
+
 	switch (status_reg_value & TW_STATUS_UNEXPECTED_BITS) {
 	case TW_STATUS_PCI_PARITY_ERROR:
-		printk(KERN_WARNING "3w-xxxx: PCI Parity Error: Reseat card, move card, or buggy device on the bus.\n");
+		printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
 		outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
-		pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PARITY_ERRORS);
 		break;
 	case TW_STATUS_MICROCONTROLLER_ERROR:
-		printk(KERN_WARNING "3w-xxxx: Microcontroller Error.\n");
-		break;
+		if (tw_dev->reset_print == 0) {
+			printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
+			tw_dev->reset_print = 1;
+		}
+		return 1;
 	case TW_STATUS_PCI_ABORT:
-		printk(KERN_WARNING "3w-xxxx: PCI Abort: clearing.\n");
+		printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
 		outl(TW_CONTROL_CLEAR_PCI_ABORT, tw_dev->registers.control_reg_addr);
 		pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
 		break;
-  }
+	case TW_STATUS_QUEUE_ERROR:
+		printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
+		outl(TW_CONTROL_CLEAR_QUEUE_ERROR, tw_dev->registers.control_reg_addr);
+		break;
+	case TW_STATUS_SBUF_WRITE_ERROR:
+		printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
+		outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, tw_dev->registers.control_reg_addr);
+		break;
+	}
+
+	return 0;
 } /* End tw_decode_bits() */
 
-/* This function will print readable messages from flags and status values */
-void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit)
+/* This function will return valid sense buffer information for failed cmds */
+int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
 {
-	dprintk(KERN_WARNING "3w-xxxx: tw_decode_error()\n");
-	switch (status) {
-	case 0xc7:
-		switch (flags) {
-		case 0x1b: 
-			printk(KERN_WARNING "3w-xxxx: scsi%d: Drive timeout on unit %d, check drive and drive cables.\n", tw_dev->host->host_no, unit);
-			break;
-		case 0x51:
-			printk(KERN_WARNING "3w-xxxx: scsi%d: Unrecoverable drive error on unit %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, unit);
-			break;
-		default:
-			printk(KERN_WARNING "3w-xxxx: scsi%d: Controller error: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, status, flags, unit);
+	int i;
+	TW_Command *command;
+
+	dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
+	command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+
+	printk(KERN_WARNING "3w-xxxx: scsi%d: Command failed: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, command->status, command->flags, command->byte3.unit);
+
+	/* Attempt to return intelligent sense information */
+	if (fill_sense) {
+		if ((command->status == 0xc7) || (command->status == 0xcb)) {
+			for (i=0;i<(sizeof(tw_sense_table)/sizeof(tw_sense_table[0]));i++) {
+				if (command->flags == tw_sense_table[i][0]) {
+
+					/* Valid bit and 'current errors' */
+					tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
+
+					/* Sense key */
+					tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
+
+					/* Additional sense length */
+					tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
+
+					/* Additional sense code */
+					tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
+
+					/* Additional sense code qualifier */
+					tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
+
+					tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
+					return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
+				}
+			}
 		}
-		break;
-	default:
-		printk(KERN_WARNING "3w-xxxx: scsi%d: Controller error: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, status, flags, unit);
+
+		/* If no table match, error so we get a reset */
+		return 1;
 	}
-} /* End tw_decode_error() */
+
+	return 0;
+} /* End tw_decode_sense() */
 
 /* This function will disable interrupts on the controller */  
 void tw_disable_interrupts(TW_Device_Extension *tw_dev) 
@@ -666,7 +753,7 @@
 } /* End tw_disable_interrupts() */
 
 /* This function will empty the response que */
-int tw_empty_response_que(TW_Device_Extension *tw_dev) 
+void tw_empty_response_que(TW_Device_Extension *tw_dev) 
 {
 	u32 status_reg_addr, status_reg_value;
 	u32 response_que_addr, response_que_value;
@@ -676,22 +763,10 @@
   
 	status_reg_value = inl(status_reg_addr);
 
-	if (tw_check_bits(status_reg_value)) {
-		dprintk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n");
-		tw_decode_bits(tw_dev, status_reg_value);
-		return 1;
-	}
-  
 	while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
 		response_que_value = inl(response_que_addr);
 		status_reg_value = inl(status_reg_addr);
-		if (tw_check_bits(status_reg_value)) {
-			dprintk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n");
-			tw_decode_bits(tw_dev, status_reg_value);
-			return 1;
-		}
 	}
-	return 0;
 } /* End tw_empty_response_que() */
 
 /* This function will enable interrupts on the controller */
@@ -744,6 +819,9 @@
 			}
 			memset(tw_dev, 0, sizeof(TW_Device_Extension));
 
+			/* Save pci_dev struct to device extension */
+			tw_dev->tw_pci_dev = tw_pci_dev;
+
 			error = tw_initialize_device_extension(tw_dev);
 			if (error) {
 				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", numcards);
@@ -758,13 +836,11 @@
 			tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4;
 			tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8;
 			tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC;
-			/* Save pci_dev struct to device extension */
-			tw_dev->tw_pci_dev = tw_pci_dev;
 
 			/* Check for errors and clear them */
 			status_reg_value = inl(tw_dev->registers.status_reg_addr);
-			if (TW_STATUS_ERRORS(status_reg_value)) 
-			  tw_decode_bits(tw_dev, status_reg_value);
+			if (TW_STATUS_ERRORS(status_reg_value))
+				tw_decode_bits(tw_dev, status_reg_value, 0);
 			
 			/* Poll status register for 60 secs for 'Controller Ready' flag */
 			if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
@@ -780,7 +856,7 @@
 			while (tries < TW_MAX_RESET_TRIES) {
 				/* Do soft reset */
 				tw_soft_reset(tw_dev);
-			  
+
 				error = tw_aen_drain_queue(tw_dev);
 				if (error) {
 					printk(KERN_WARNING "3w-xxxx: AEN drain failed for card %d.\n", numcards);
@@ -795,14 +871,6 @@
 					continue;
 				}
 
-				/* Empty the response queue */
-				error = tw_empty_response_que(tw_dev);
-				if (error) {
-					printk(KERN_WARNING "3w-xxxx: Couldn't empty response queue, retrying for card %d.\n", numcards);
-					tries++;
-					continue;
-				}
-
 				/* Now the controller is in a good state */
 				break;
 			}
@@ -829,7 +897,7 @@
 			request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME);
 			error = tw_initialize_units(tw_dev);
 			if (error) {
-				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize units for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: No valid units for card %d.\n", numcards);
 				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
@@ -853,7 +921,7 @@
 					tw_dev->free_tail = TW_MAX_BOUNCEBUF - 1;
 					tw_dev->free_wrap = TW_MAX_BOUNCEBUF - 1;
 				} else {
-					tw_host->cmd_per_lun = (TW_Q_LENGTH-1)/tw_dev->num_units;
+					/* Use SHT cmd_per_lun here */
 					tw_dev->free_head = TW_Q_START;
 					tw_dev->free_tail = TW_Q_LENGTH - 1;
 					tw_dev->free_wrap = TW_Q_LENGTH - 1;
@@ -1033,7 +1101,7 @@
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			dprintk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
-			tw_decode_bits(tw_dev, status_reg_value);
+			tw_decode_bits(tw_dev, status_reg_value, 0);
 			return 1;
 		}
 		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1046,8 +1114,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				dprintk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
-				tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
+				tw_decode_sense(tw_dev, request_id, 0);
 				return 1;
 			}
 			break;	/* Response was okay, so we exit */
@@ -1059,12 +1126,11 @@
 /* This function will initialize the fields of a device extension */
 int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
 {
-	int i, imax;
+	int i;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
-	imax = TW_Q_LENGTH;
 
-	for (i=0; i<imax; i++) {
+	for (i=0;i<TW_Q_LENGTH;i++) {
 		/* Initialize command packet buffers */
 		tw_allocate_memory(tw_dev, i, sizeof(TW_Sector), 0);
 		if (tw_dev->command_packet_virtual_address[i] == NULL) {
@@ -1083,34 +1149,12 @@
 
 		tw_dev->free_queue[i] = i;
 		tw_dev->state[i] = TW_S_INITIAL;
-		tw_dev->ioctl_size[i] = 0;
-		tw_dev->aen_queue[i] = 0;
-		tw_dev->ioctl_data[i] = NULL;
-	}
-
-	for (i=0;i<TW_MAX_UNITS;i++) {
-		tw_dev->is_unit_present[i] = 0;
-		tw_dev->is_raid_five[i] = 0;
 	}
 
-	tw_dev->num_units = 0;
-	tw_dev->num_aborts = 0;
-	tw_dev->num_resets = 0;
-	tw_dev->posted_request_count = 0;
-	tw_dev->max_posted_request_count = 0;
-	tw_dev->max_sgl_entries = 0;
-	tw_dev->sgl_entries = 0;
-	tw_dev->host = NULL;
 	tw_dev->pending_head = TW_Q_START;
 	tw_dev->pending_tail = TW_Q_START;
-	tw_dev->aen_head = 0;
-	tw_dev->aen_tail = 0;
-	tw_dev->sector_count = 0;
-	tw_dev->max_sector_count = 0;
-	tw_dev->aen_count = 0;
-	tw_dev->num_raid_five = 0;
 	spin_lock_init(&tw_dev->tw_lock);
-	tw_dev->flags = 0;
+
 	return 0;
 } /* End tw_initialize_device_extension() */
 
@@ -1187,7 +1231,7 @@
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
-			tw_decode_bits(tw_dev, status_reg_value);
+			tw_decode_bits(tw_dev, status_reg_value, 0);
 			return 1;
 		}
 		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1200,8 +1244,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
-				tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
+				tw_decode_sense(tw_dev, request_id, 0);
 				return 1;
 			}
 			found = 1;
@@ -1291,7 +1334,7 @@
 			status_reg_value = inl(status_reg_addr);
 			if (tw_check_bits(status_reg_value)) {
 				dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
-				tw_decode_bits(tw_dev, status_reg_value);
+				tw_decode_bits(tw_dev, status_reg_value, 0);
 				return 1;
 			}
 			if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1304,8 +1347,7 @@
 				}
 				if (command_packet->status != 0) {
 					/* bad response */
-					dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
-					tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
+					tw_decode_sense(tw_dev, request_id, 0);
 					return 1;
 				}
 				found = 1;
@@ -1351,46 +1393,52 @@
 	u32 response_que_addr;
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
 	TW_Response_Queue response_que;
-	int error = 0;
-	int do_response_interrupt=0;
-	int do_attention_interrupt=0;
-	int do_host_interrupt=0;
-	int do_command_interrupt=0;
+	int error = 0, retval = 0;
 	unsigned long flags = 0;
 	TW_Command *command_packet;
+
+	dprintk(KERN_WARNING "3w-xxxx: tw_interrupt()\n");
+
+	/* See if we are already running on another processor */
 	if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags))
 		return;
-	spin_lock_irqsave(&io_request_lock, flags);
 
+	/* Get the block layer lock for io completions */
+	spin_lock_irqsave(&io_request_lock, flags);
+	
+	/* See if the interrupt matches this instance */
 	if (tw_dev->tw_pci_dev->irq == irq) {
+
+		/* Make sure io isn't queueing */
 		spin_lock(&tw_dev->tw_lock);
-		dprintk(KERN_WARNING "3w-xxxx: tw_interrupt()\n");
 
 		/* Read the registers */
 		status_reg_addr = tw_dev->registers.status_reg_addr;
 		response_que_addr = tw_dev->registers.response_que_addr;
 		status_reg_value = inl(status_reg_addr);
 
-		/* Check which interrupt */
-		if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
-			do_host_interrupt=1;
-		if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT)
-			do_attention_interrupt=1;
-		if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT)
-			do_command_interrupt=1;
-		if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT)
-			do_response_interrupt=1;
+		/* Check if this is our interrupt, otherwise bail */
+		if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
+			goto tw_interrupt_bail;
+
+		/* Check controller for errors */
+		if (tw_check_bits(status_reg_value)) {
+			dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+			if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
+				tw_clear_all_interrupts(tw_dev);
+				goto tw_interrupt_bail;
+			}
+		}
 
 		/* Handle host interrupt */
-		if (do_host_interrupt) {
+		if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
 			dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
 			tw_clear_host_interrupt(tw_dev);
 		}
 
 		/* Handle attention interrupt */
-		if (do_attention_interrupt) {
+		if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
 			dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
-			dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Clearing attention interrupt.\n");
 			tw_clear_attention_interrupt(tw_dev);
 			tw_state_request_start(tw_dev, &request_id);
 			error = tw_aen_read_queue(tw_dev, request_id);
@@ -1402,7 +1450,7 @@
 		}
 
 		/* Handle command interrupt */
-		if (do_command_interrupt) {
+		if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
 			/* Drain as many pending commands as we can */
 			while (tw_dev->pending_request_count > 0) {
 				request_id = tw_dev->pending_queue[tw_dev->pending_head];
@@ -1418,6 +1466,7 @@
 					}
 					tw_dev->pending_request_count--;
 				} else {
+					/* If we get here, we will continue re-posting on the next command interrupt */
 					break;
 				}
 			}
@@ -1427,40 +1476,46 @@
 		}
 
 		/* Handle response interrupt */
-		if (do_response_interrupt) {
+		if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
 			/* Drain the response queue from the board */
 			while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+				/* Read response queue register */
 				response_que.value = inl(response_que_addr);
 				request_id = response_que.u.response_id;
 				command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 				error = 0;
+
+				/* Check for bad response */
 				if (command_packet->status != 0) {
-					dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x, unit = 0x%x.\n", command_packet->status, command_packet->flags, command_packet->byte3.unit);
-					tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
-					error = 1;
+					/* If internal command, don't error, don't fill sense */
+					if (tw_dev->srb[request_id] == 0) {
+						tw_decode_sense(tw_dev, request_id, 0);
+					} else {
+						error = tw_decode_sense(tw_dev, request_id, 1);
+					}
 				}
+
+				/* Check for correct state */
 				if (tw_dev->state[request_id] != TW_S_POSTED) {
-					printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", tw_dev->host->host_no, request_id, command_packet->byte0.opcode);
-					error = 1;
-				}
-				if (TW_STATUS_ERRORS(status_reg_value)) {
-				  tw_decode_bits(tw_dev, status_reg_value);
-				  error = 1;
+					/* Handle timed out ioctl's */
+					if (tw_dev->srb[request_id] != 0) {
+						if (tw_dev->srb[request_id]->cmnd[0] != TW_IOCTL) {
+							printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", tw_dev->host->host_no, request_id, command_packet->byte0.opcode);
+							error = 1;
+						}
+					}
 				}
+
 				dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
-				/* Check for internal command */
+
+				/* Check for internal command completion */
 				if (tw_dev->srb[request_id] == 0) {
 					dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
-					error = tw_aen_complete(tw_dev, request_id);
-					if (error) {
+					retval = tw_aen_complete(tw_dev, request_id);
+					if (retval) {
 						printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
 					}
-					status_reg_value = inl(status_reg_addr);
-					if (tw_check_bits(status_reg_value)) {
-						dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
-						tw_decode_bits(tw_dev, status_reg_value);
-					}
-		} else {
+				} else {
 				switch (tw_dev->srb[request_id]->cmnd[0]) {
 					case READ_10:
 					case READ_6:
@@ -1483,35 +1538,45 @@
 						error = tw_ioctl_complete(tw_dev, request_id);
 						break;
 					default:
-						printk(KERN_WARNING "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x.\n", tw_dev->host->host_no, tw_dev->srb[request_id]->cmnd[0]);
-						tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
-						tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
-					}
-					if (error == 1) {
-						/* Tell scsi layer there was an error */
-						dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Scsi Error.\n");
-						tw_dev->srb[request_id]->result = (DID_RESET << 16);
+						printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
+						error = 1;
 					}
+
+					/* If no error command was a success */
 					if (error == 0) {
-						/* Tell scsi layer command was a success */
 						tw_dev->srb[request_id]->result = (DID_OK << 16);
 					}
-					if (error != 2) {
+
+					/* If error, command failed */
+					if (error == 1) {
+						tw_dev->srb[request_id]->result = (DID_RESET << 16);
+					}
+					
+					/* Now complete the io */
+					if ((error != TW_ISR_DONT_COMPLETE)) {
 						tw_dev->state[request_id] = TW_S_COMPLETED;
 						tw_state_request_finish(tw_dev, request_id);
 						tw_dev->posted_request_count--;
 						tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
 					}
-					status_reg_value = inl(status_reg_addr);
-					if (tw_check_bits(status_reg_value)) {
-						dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
-						tw_decode_bits(tw_dev, status_reg_value);
+				}
+
+				/* Check for valid status after each drain */
+				status_reg_value = inl(status_reg_addr);
+				if (tw_check_bits(status_reg_value)) {
+					dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+					if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
+						tw_clear_all_interrupts(tw_dev);
+						goto tw_interrupt_bail;
 					}
 				}
 			}
 		}
+tw_interrupt_bail:
 		spin_unlock(&tw_dev->tw_lock);
-	}
+	} else
+		dprintk(KERN_WARNING "3w-xxxx: tw_interrupt() called for wrong instance.\n");
+
 	spin_unlock_irqrestore(&io_request_lock, flags);
 	clear_bit(TW_IN_INTR, &tw_dev->flags);
 } /* End tw_interrupt() */
@@ -1528,7 +1593,8 @@
 	TW_Passthru *passthru = NULL;
 	int tw_aen_code, i, use_sg;
 	char *data_ptr;
-	int total_bytes = 0;
+	int total_bytes = 0, posted = 0;
+	struct timeval before, timeout;
 
 	ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
 	if (ioctl == NULL) {
@@ -1679,7 +1745,7 @@
 						if ((u32 *)command_packet->byte8.param.sgl[i].address != NULL) {
 							error = copy_from_user(data_ptr, (u32 *)command_packet->byte8.param.sgl[i].address, command_packet->byte8.param.sgl[i].length);
 							if (error) {
-								printk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist from userspace.\n", tw_dev->host->host_no);
+								dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist from userspace.\n", tw_dev->host->host_no);
 								goto tw_ioctl_bail;
 							}
 						} else {
@@ -1709,7 +1775,7 @@
 							if ((u32 *)command_packet->byte8.io.sgl[i].address != NULL) {
 								error = copy_from_user(data_ptr, (u32 *)command_packet->byte8.io.sgl[i].address, command_packet->byte8.io.sgl[i].length);
 								if (error) {
-									printk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist from userspace.\n", tw_dev->host->host_no);
+									dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist from userspace.\n", tw_dev->host->host_no);
 									goto tw_ioctl_bail;
 								}
 							} else {
@@ -1725,15 +1791,31 @@
 					command_packet->byte8.io.sgl[0].length = total_bytes;
 				}
 
+				spin_unlock(&tw_dev->tw_lock);
 				spin_unlock_irq(&io_request_lock);
-				spin_unlock_irq(&tw_dev->tw_lock);
+
+				set_bit(TW_IN_IOCTL, &tw_dev->flags);
 
 				/* Finally post the command packet */
 				tw_post_command_packet(tw_dev, request_id);
+				posted = 1;
+				do_gettimeofday(&before);
 
+			tw_ioctl_retry:
 				mdelay(TW_IOCTL_WAIT_TIME);
-				spin_lock_irq(&tw_dev->tw_lock);
+				if (test_bit(TW_IN_IOCTL, &tw_dev->flags)) {
+					do_gettimeofday(&timeout);
+					if (before.tv_sec + TW_IOCTL_TIMEOUT < timeout.tv_sec) {
+						spin_lock_irq(&io_request_lock);
+						spin_lock(&tw_dev->tw_lock);
+						goto tw_ioctl_bail;
+					} else {
+						goto tw_ioctl_retry;
+					}
+				}
+
 				spin_lock_irq(&io_request_lock);
+				spin_lock(&tw_dev->tw_lock);
 
 				if (signal_pending(current)) {
 					dprintk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Signal pending, aborting ioctl().\n", tw_dev->host->host_no);
@@ -1750,7 +1832,7 @@
 						if ((u32 *)command_save->byte8.param.sgl[i].address != NULL) {
 							error = copy_to_user((u32 *)command_save->byte8.param.sgl[i].address, data_ptr, command_save->byte8.param.sgl[i].length);
 							if (error) {
-								printk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist to userspace.\n", tw_dev->host->host_no);
+								dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist to userspace.\n", tw_dev->host->host_no);
 								goto tw_ioctl_bail;
 							}
 							dprintk(KERN_WARNING "3w-xxxx: scsi%d: Copied %ld bytes to pid %d.\n", tw_dev->host->host_no, command_save->byte8.param.sgl[i].length, current->pid);
@@ -1770,7 +1852,7 @@
 							if ((u32 *)command_save->byte8.io.sgl[i].address != NULL) {
 								error = copy_to_user((u32 *)command_save->byte8.io.sgl[i].address, data_ptr, command_save->byte8.io.sgl[i].length);
 								if (error) {
-									printk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist to userspace.\n", tw_dev->host->host_no);
+									dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist to userspace.\n", tw_dev->host->host_no);
 									goto tw_ioctl_bail;
 								}
 								dprintk(KERN_WARNING "3w-xxxx: scsi%d: Copied %ld bytes to pid %d.\n", tw_dev->host->host_no, command_save->byte8.io.sgl[i].length, current->pid);
@@ -1795,7 +1877,8 @@
 				/* Now complete the io */
 				tw_dev->state[request_id] = TW_S_COMPLETED;
 				tw_state_request_finish(tw_dev, request_id);
-				tw_dev->posted_request_count--;
+				if (posted)
+					tw_dev->posted_request_count--;
 				tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
 				return 0;
 			} else {
@@ -1871,7 +1954,8 @@
 			break;
 		case TW_CMD_PACKET_WITH_DATA:
 			dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n");
-			return 2; /* Special case for isr to not complete io */
+			clear_bit(TW_IN_IOCTL, &tw_dev->flags);
+			return TW_ISR_DONT_COMPLETE; /* Special case for isr to not complete io */
 		default:
 			memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
 			param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
@@ -1905,14 +1989,25 @@
 	do_gettimeofday(&before);
 	status_reg_value = inl(status_reg_addr);
 
+	if (tw_check_bits(status_reg_value)) {
+		dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
+		tw_decode_bits(tw_dev, status_reg_value, 0);
+	}
+
 	while ((status_reg_value & flag) != flag) {
 		status_reg_value = inl(status_reg_addr);
+
+		if (tw_check_bits(status_reg_value)) {
+			dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
+			tw_decode_bits(tw_dev, status_reg_value, 0);
+		}
+
 		do_gettimeofday(&timeout);
 		if (before.tv_sec + seconds < timeout.tv_sec) { 
 			dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag);
 			return 1;
 		}
-		mdelay(1);
+		mdelay(5);
 	}
 	return 0;
 } /* End tw_poll_status() */
@@ -1931,7 +2026,7 @@
 
 	if (tw_check_bits(status_reg_value)) {
 		dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
-		tw_decode_bits(tw_dev, status_reg_value);
+		tw_decode_bits(tw_dev, status_reg_value, 1);
 	}
 
 	if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
@@ -1985,7 +2080,6 @@
 		    (tw_dev->state[i] != TW_S_COMPLETED)) {
 			srb = tw_dev->srb[i];
 			if (srb != NULL) {
-				srb = tw_dev->srb[i];
 				srb->result = (DID_RESET << 16);
 				tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
 			}
@@ -2003,6 +2097,7 @@
 	tw_dev->pending_request_count = 0;
 	tw_dev->pending_head = TW_Q_START;
 	tw_dev->pending_tail = TW_Q_START;
+	tw_dev->reset_print = 0;
 
 	return 0;
 } /* End tw_reset_device_extension() */
@@ -2034,14 +2129,6 @@
 			continue;
 		}
 
-		/* Empty the response queue again */
-		error = tw_empty_response_que(tw_dev);
-		if (error) {
-			printk(KERN_WARNING "3w-xxxx: scsi%d: Couldn't empty response queue, retrying.\n", tw_dev->host->host_no);
-			tries++;
-			continue;
-		}
-
 		/* Now the controller is in a good state */
 		break;
 	}
@@ -2131,11 +2218,6 @@
 		return (FAILED);
 	}
 
-	/* We have to let AEN requests through before the reset */
-	spin_unlock_irq(&io_request_lock);
-	mdelay(TW_AEN_WAIT_TIME);
-	spin_lock_irq(&io_request_lock);
-
 	spin_lock(&tw_dev->tw_lock);
 	tw_dev->num_aborts++;
 
@@ -2143,14 +2225,14 @@
 	for (i=0;i<TW_Q_LENGTH;i++) {
 		if (tw_dev->srb[i] == SCpnt) {
 			if (tw_dev->state[i] == TW_S_STARTED) {
-				printk(KERN_WARNING "3w-xxxx: scsi%d: Command (0x%x) timed out.\n", tw_dev->host->host_no, (u32)SCpnt);
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (0x%x) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, (u32)SCpnt);
 				tw_dev->state[i] = TW_S_COMPLETED;
 				tw_state_request_finish(tw_dev, i);
 				spin_unlock(&tw_dev->tw_lock);
 				return (SUCCESS);
 			}
 			if (tw_dev->state[i] == TW_S_PENDING) {
-				printk(KERN_WARNING "3w-xxxx: scsi%d: Command (0x%x) timed out.\n", tw_dev->host->host_no, (u32)SCpnt);
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (0x%x) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, (u32)SCpnt);
 				if (tw_dev->pending_head == TW_Q_LENGTH-1) {
 					tw_dev->pending_head = TW_Q_START;
 				} else {
@@ -2162,18 +2244,26 @@
 				spin_unlock(&tw_dev->tw_lock);
 				return (SUCCESS);
 			}
+			if (tw_dev->state[i] == TW_S_POSTED) {
+				/* If the command has already been posted, we have to reset the card */
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, (u32)SCpnt);
+				/* We have to let AEN requests through before the reset */
+				spin_unlock(&tw_dev->tw_lock);
+				spin_unlock_irq(&io_request_lock);
+				mdelay(TW_AEN_WAIT_TIME);
+				spin_lock_irq(&io_request_lock);
+				spin_lock(&tw_dev->tw_lock);
+
+				if (tw_reset_device_extension(tw_dev)) {
+					dprintk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
+					spin_unlock(&tw_dev->tw_lock);
+					return (FAILED);
+				}
+			}
 		}
 	}
 
-	/* If the command has already been posted, we have to reset the card */
-	printk(KERN_WARNING "3w-xxxx: scsi%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, (u32)SCpnt);
-	if (tw_reset_device_extension(tw_dev)) {
-		dprintk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
-		spin_unlock(&tw_dev->tw_lock);
-		return (FAILED);
-	}
 	spin_unlock(&tw_dev->tw_lock);
-
 	return (SUCCESS);
 } /* End tw_scsi_eh_abort() */
 
@@ -2374,6 +2464,11 @@
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n");
 
+	/* Fake like we just shut down, so notify the card that
+	 * we "shut down cleanly".
+	 */
+	tw_halt(0, 0, 0);  // parameters aren't actually used
+
 	/* Free up the IO region */
 	release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
 
@@ -2385,11 +2480,6 @@
 
 	/* Tell kernel scsi-layer we are gone */
 	scsi_unregister(tw_host);
-	
-	/* Fake like we just shut down, so notify the card that
-	 * we "shut down cleanly".
-	 */
-	tw_halt(0, 0, 0);  // parameters aren't actually used
 
 	return 0;
 } /* End tw_scsi_release() */
@@ -2638,7 +2728,7 @@
 	}
 
 	command_packet->byte0.sgl_offset = 3;
-	command_packet->size = 5;
+	command_packet->size = 3;
 	command_packet->request_id = request_id;
 	command_packet->byte3.unit = srb->target;
 	command_packet->byte3.host_id = 0;
@@ -2673,6 +2763,7 @@
 			dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
 			command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->srb[request_id]->request_buffer);
 			command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
+			command_packet->size+=2;
 		}
 
 		/* Do this if we have multiple sg list entries */
@@ -2682,8 +2773,6 @@
 				command_packet->byte8.io.sgl[i].length = sglist[i].length;
 				command_packet->size+=2;
 			}
-			if (tw_dev->srb[request_id]->use_sg >= 1)
-				command_packet->size-=2;
 		}
 	} else {
                 /* Do this if there are no sg list entries for raid 5 */
@@ -2692,6 +2781,7 @@
 			memcpy(tw_dev->bounce_buffer[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
 			command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->bounce_buffer[request_id]);
 			command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
+			command_packet->size+=2;
                 }
 
                 /* Do this if we have multiple sg list entries for raid 5 */
@@ -2727,18 +2817,19 @@
 /* This function will handle the request sense scsi command */
 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
 {
-       dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
+	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
   
-       /* For now we just zero the sense buffer */
-       memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
-       tw_dev->state[request_id] = TW_S_COMPLETED;
-       tw_state_request_finish(tw_dev, request_id);
+	/* For now we just zero the request buffer */
+	memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
+       
+	tw_dev->state[request_id] = TW_S_COMPLETED;
+	tw_state_request_finish(tw_dev, request_id);
   
-       /* If we got a request_sense, we probably want a reset, return error */
-       tw_dev->srb[request_id]->result = (DID_ERROR << 16);
-       tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+	/* If we got a request_sense, we probably want a reset, return error */
+	tw_dev->srb[request_id]->result = (DID_ERROR << 16);
+	tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
   
-       return 0;
+	return 0;
 } /* End tw_scsiop_request_sense() */
 
 /* This function will handle test unit ready scsi command */
@@ -2819,7 +2910,7 @@
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			dprintk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
-			tw_decode_bits(tw_dev, status_reg_value);
+			tw_decode_bits(tw_dev, status_reg_value, 1);
 			return 1;
 		}
 		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -2832,8 +2923,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				dprintk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
-				tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
+				tw_decode_sense(tw_dev, request_id, 0);
 				return 1;
 			}
 			break; /* Response was okay, so we exit */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/3w-xxxx.h linux/drivers/scsi/3w-xxxx.h
--- linux.orig/drivers/scsi/3w-xxxx.h	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/3w-xxxx.h	2002-07-20 01:08:29.000000000 +0000
@@ -60,42 +60,68 @@
 
 /* AEN strings */
 static char *tw_aen_string[] = {
-	"AEN queue empty",                      // 0x000
-	"Soft reset occurred",                  // 0x001
-	"Unit degraded: Unit #",                // 0x002
-	"Controller error",                     // 0x003 
-	"Rebuild failed: Unit #",               // 0x004
-	"Rebuild complete: Unit #",             // 0x005
-	"Incomplete unit detected: Unit #",     // 0x006
-	"Initialization complete: Unit #",      // 0x007
-	"Unclean shutdown detected: Unit #",    // 0x008
-	"ATA port timeout: Port #",             // 0x009
-	"Drive error: Port #",                  // 0x00A
-	"Rebuild started: Unit #",              // 0x00B 
-	"Initialization started: Unit #",       // 0x00C
-	"Logical unit deleted: Unit #",         // 0x00D
-	NULL,                                   // 0x00E unused
-	"SMART threshold exceeded: Port #",     // 0x00F
+	"INFO: AEN queue empty",                       // 0x000
+	"INFO: Soft reset occurred",                   // 0x001
+	"ERROR: Unit degraded: Unit #",                // 0x002
+	"ERROR: Controller error",                     // 0x003 
+	"ERROR: Rebuild failed: Unit #",               // 0x004
+	"INFO: Rebuild complete: Unit #",              // 0x005
+	"ERROR: Incomplete unit detected: Unit #",     // 0x006
+	"INFO: Initialization complete: Unit #",       // 0x007
+	"WARNING: Unclean shutdown detected: Unit #",  // 0x008
+	"WARNING: ATA port timeout: Port #",           // 0x009
+	"ERROR: Drive error: Port #",                  // 0x00A
+	"INFO: Rebuild started: Unit #",               // 0x00B 
+	"INFO: Initialization started: Unit #",        // 0x00C
+	"ERROR: Logical unit deleted: Unit #",         // 0x00D
+	NULL,                                          // 0x00E unused
+	"WARNING: SMART threshold exceeded: Port #",   // 0x00F
 	NULL, NULL, NULL, NULL, NULL,
 	NULL, NULL, NULL, NULL, NULL,
 	NULL, NULL, NULL, NULL, NULL,
-	NULL, NULL,                             // 0x010-0x020 unused
-	"ATA UDMA downgrade: Port #",           // 0x021
-	"ATA UDMA upgrade: Port #",             // 0x022
-	"Sector repair occurred: Port #",       // 0x023
-	"SBUF integrity check failure",         // 0x024
-	"Lost cached write: Port #",            // 0x025
-	"Drive ECC error detected: Port #",     // 0x026
-	"DCB checksum error: Port #",           // 0x027
-	"DCB unsupported version: Port #",      // 0x028
-	"Verify started: Unit #",               // 0x029
-	"Verify failed: Port #",                // 0x02A
-	"Verify complete: Unit #",              // 0x02B
-	"Overwrote bad sector during rebuild: Port #",  //0x2C
-	"Encountered bad sector during rebuild: Port #" //0x2D
+	NULL, NULL,                                    // 0x010-0x020 unused
+	"WARNING: ATA UDMA downgrade: Port #",         // 0x021
+	"WARNING: ATA UDMA upgrade: Port #",           // 0x022
+	"WARNING: Sector repair occurred: Port #",     // 0x023
+	"ERROR: SBUF integrity check failure",         // 0x024
+	"ERROR: Lost cached write: Port #",            // 0x025
+	"ERROR: Drive ECC error detected: Port #",     // 0x026
+	"ERROR: DCB checksum error: Port #",           // 0x027
+	"ERROR: DCB unsupported version: Port #",      // 0x028
+	"INFO: Verify started: Unit #",                // 0x029
+	"ERROR: Verify failed: Port #",                // 0x02A
+	"INFO: Verify complete: Unit #",               // 0x02B
+	"ERROR: Overwrote bad sector during rebuild: Port #",   //0x02C
+	"ERROR: Encountered bad sector during rebuild: Port #", //0x02D
+	"INFO: Replacement drive is too small: Port #",         //0x02E
+	"WARNING: Verify error: Unit not previously initialized: Unit #" //0x02F
 };
 
-#define TW_AEN_STRING_MAX                      0x02E
+#define TW_AEN_STRING_MAX                      0x030
+
+/* 
+   Sense key lookup table 
+   Format: ESDC/flags,SenseKey,AdditionalSenseCode,AdditionalSenseCodeQualifier
+*/
+static unsigned char tw_sense_table[][4] =
+{
+  /* Codes for newer firmware */
+                            // ATA Error                    SCSI Error
+  {0x01, 0x03, 0x13, 0x00}, // Address mark not found       Address mark not found for data field
+  {0x04, 0x0b, 0x00, 0x00}, // Aborted command              Aborted command
+  {0x10, 0x0b, 0x14, 0x00}, // ID not found                 Recorded entity not found
+  {0x40, 0x03, 0x11, 0x00}, // Uncorrectable ECC error      Unrecovered read error
+  {0x61, 0x04, 0x00, 0x00}, // Device fault                 Hardware error
+  {0x84, 0x0b, 0x47, 0x00}, // Data CRC error               SCSI parity error
+  {0xd0, 0x0b, 0x00, 0x00}, // Device busy                  Aborted command
+  {0xd1, 0x0b, 0x00, 0x00}, // Device busy                  Aborted command
+
+  /* Codes for older firmware */
+                            // 3ware Error                  SCSI Error
+  {0x09, 0x0b, 0x00, 0x00}, // Unrecovered disk error       Aborted command
+  {0x37, 0x0b, 0x04, 0x00}, // Unit offline                 Logical unit not ready
+  {0x51, 0x0b, 0x00, 0x00}  // Unspecified                  Aborted command
+};
 
 /* Control register bit definitions */
 #define TW_CONTROL_CLEAR_HOST_INTERRUPT	       0x00080000
@@ -110,7 +136,9 @@
 #define TW_CONTROL_DISABLE_INTERRUPTS	       0x00000040
 #define TW_CONTROL_ISSUE_HOST_INTERRUPT	       0x00000020
 #define TW_CONTROL_CLEAR_PARITY_ERROR          0x00800000
+#define TW_CONTROL_CLEAR_QUEUE_ERROR           0x00400000
 #define TW_CONTROL_CLEAR_PCI_ABORT             0x00100000
+#define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR      0x00000008
 
 /* Status register bit definitions */
 #define TW_STATUS_MAJOR_VERSION_MASK	       0xF0000000
@@ -130,7 +158,9 @@
 #define TW_STATUS_ALL_INTERRUPTS	       0x000F0000
 #define TW_STATUS_CLEARABLE_BITS	       0x00D00000
 #define TW_STATUS_EXPECTED_BITS		       0x00002000
-#define TW_STATUS_UNEXPECTED_BITS	       0x00F80000
+#define TW_STATUS_UNEXPECTED_BITS	       0x00F00008
+#define TW_STATUS_SBUF_WRITE_ERROR             0x00000008
+#define TW_STATUS_VALID_INTERRUPT              0x00DF0008
 
 /* RESPONSE QUEUE BIT DEFINITIONS */
 #define TW_RESPONSE_ID_MASK		       0x00000FF0
@@ -174,7 +204,8 @@
 #define TW_AEN_SBUF_FAIL         0x0024
 
 /* Misc defines */
-#define TW_ALIGNMENT			      0x200 /* 16 D-WORDS */
+#define TW_ALIGNMENT_6000                     64 /* 64 bytes */
+#define TW_ALIGNMENT_7000                     4  /* 4 bytes */
 #define TW_MAX_UNITS			      16
 #define TW_COMMAND_ALIGNMENT_MASK	      0x1ff
 #define TW_INIT_MESSAGE_CREDITS		      0x100
@@ -190,17 +221,21 @@
 #define TW_MAX_PCI_BUSES		      255
 #define TW_MAX_RESET_TRIES		      3
 #define TW_UNIT_INFORMATION_TABLE_BASE	      0x300
-#define TW_MAX_CMDS_PER_LUN		      (TW_Q_LENGTH-2)/TW_MAX_UNITS
+#define TW_MAX_CMDS_PER_LUN		      255
 #define TW_BLOCK_SIZE			      0x200 /* 512-byte blocks */
 #define TW_IOCTL                              0x80
 #define TW_MAX_AEN_TRIES                      100
 #define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
+#define TW_IN_IOCTL                           2
 #define TW_MAX_SECTORS                        256
 #define TW_MAX_BOUNCE_SECTORS                 128
 #define TW_AEN_WAIT_TIME                      1000
 #define TW_IOCTL_WAIT_TIME                    (1 * HZ) /* 1 second */
 #define TW_MAX_CDB_LEN                        16
+#define TW_ISR_DONT_COMPLETE                  2
+#define TW_ISR_DONT_RESULT                    3
+#define TW_IOCTL_TIMEOUT                      25 /* 25 seconds */
 
 /* Macros */
 #define TW_STATUS_ERRORS(x) \
@@ -213,7 +248,7 @@
 #ifdef TW_DEBUG
 #define dprintk(msg...) printk(msg)
 #else
-#define dprintk(msg...) do { } while(0);
+#define dprintk(msg...) do { } while(0)
 #endif
 
 /* Scatter Gather List Entry */
@@ -386,8 +421,9 @@
 	unsigned short		aen_queue[TW_Q_LENGTH];
 	unsigned char		aen_head;
 	unsigned char		aen_tail;
-	long			flags; /* long req'd for set_bit --RR */
+	volatile long		flags; /* long req'd for set_bit --RR */
 	char			*ioctl_data[TW_Q_LENGTH];
+	int			reset_print;
 } TW_Device_Extension;
 
 /* Function prototypes */
@@ -397,12 +433,13 @@
 int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which);
 int tw_check_bits(u32 status_reg_value);
 int tw_check_errors(TW_Device_Extension *tw_dev);
+void tw_clear_all_interrupts(TW_Device_Extension *tw_dev);
 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev);
 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev);
-void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value);
-void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit);
+int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host);
+int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense);
 void tw_disable_interrupts(TW_Device_Extension *tw_dev);
-int tw_empty_response_que(TW_Device_Extension *tw_dev);
+void tw_empty_response_que(TW_Device_Extension *tw_dev);
 void tw_enable_interrupts(TW_Device_Extension *tw_dev);
 void tw_enable_and_clear_interrupts(TW_Device_Extension *tw_dev);
 int tw_findcards(Scsi_Host_Template *tw_host);
@@ -462,7 +499,7 @@
 	reset : NULL,					\
 	slave_attach : NULL,				\
 	bios_param : tw_scsi_biosparam,			\
-	can_queue : TW_Q_LENGTH,			\
+	can_queue : TW_Q_LENGTH-1,			\
 	this_id: -1,					\
 	sg_tablesize : TW_MAX_SGL_LENGTH,		\
 	cmd_per_lun: TW_MAX_CMDS_PER_LUN,		\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/ChangeLog.ips linux/drivers/scsi/ChangeLog.ips
--- linux.orig/drivers/scsi/ChangeLog.ips	2001-05-20 00:43:06.000000000 +0000
+++ linux/drivers/scsi/ChangeLog.ips	2002-07-20 01:08:33.000000000 +0000
@@ -1,10 +1,40 @@
 IBM ServeRAID driver Change Log
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+        4.90.11  - Don't actually RESET unless it's physically required
+                 - Remove unused compile options
+        
+        4.90.08  - Data Corruption if First Scatter Gather Element is > 64K
+        
+        4.90.08  - Increase Delays in Flashing ( Trombone Only - 4H )        
+        
+        4.90.05  - Use New PCI Architecture to facilitate Hot Plug Development
+        
+        4.90.01  - Add ServeRAID Version Checking
+
+        4.80.26  - Clean up potential code problems ( Arjan's recommendations )
+        
+        4.80.21  - Change memcpy() to copy_to_user() in NVRAM Page 5 IOCTL path   
+        
+        4.80.20  - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )
+                 - 5 second delay needed after resetting an i960 adapter
+        
+        4.80.14  - Take all semaphores off stack                    
+                 - Clean Up New_IOCTL path
+                   
+        4.80.04  - Eliminate calls to strtok() if 2.4.x or greater 
+                 - Adjustments to Device Queue Depth               
+
+        4.80.00  - Make ia64 Safe    
+        
+        4.72.01  - I/O Mapped Memory release ( so "insmod ips" does not Fail )    
+                 - Don't Issue Internal FFDC Command if there are Active Commands 
+                 - Close Window for getting too many IOCTL's active 
+                   
         4.72.00  - Allow for a Scatter-Gather Element to exceed MAX_XFER Size     
         
         4.71.00  - Change all memory allocations to not use GFP_DMA flag 
-                   Code Clean-Up for 2.4.x kernel      
+                 - Code Clean-Up for 2.4.x kernel      
         
         4.70.15  - Fix Breakup for very large ( non-SG ) requests
         
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- linux.orig/drivers/scsi/Config.in	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/Config.in	2002-07-20 01:08:34.000000000 +0000
@@ -218,6 +218,7 @@
    dep_tristate 'MESH (Power Mac internal SCSI) support' CONFIG_SCSI_MESH $CONFIG_SCSI
    if [ "$CONFIG_SCSI_MESH" != "n" ]; then
       int '  maximum synchronous transfer rate (MB/s) (0 = async)' CONFIG_SCSI_MESH_SYNC_RATE 5
+      int '  initial bus reset delay (ms) (0 = no reset)' CONFIG_SCSI_MESH_RESET_DELAY_MS 4000
    fi
    dep_tristate '53C94 (Power Mac external SCSI) support' CONFIG_SCSI_MAC53C94 $CONFIG_SCSI
 fi
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- linux.orig/drivers/scsi/Makefile	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -69,7 +69,7 @@
   obj-$(CONFIG_SCSI_AACRAID)	+= aacraid/aacraid.o
 endif
 ifeq ($(CONFIG_SCSI_AIC7XXX),y)
-obj-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx/aic7xxx_drv.o
+  obj-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx/aic7xxx.o
 endif
 obj-$(CONFIG_SCSI_AIC7XXX_OLD)	+= aic7xxx_old.o
 obj-$(CONFIG_SCSI_IPS)		+= ips.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/NCR53C9x.c linux/drivers/scsi/NCR53C9x.c
--- linux.orig/drivers/scsi/NCR53C9x.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/scsi/NCR53C9x.c	2002-07-20 01:08:28.000000000 +0000
@@ -3613,3 +3613,5 @@
 	esps_running = esps_in_use;
 }
 #endif
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/a2091.c linux/drivers/scsi/a2091.c
--- linux.orig/drivers/scsi/a2091.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/scsi/a2091.c	2002-07-20 01:08:21.000000000 +0000
@@ -248,3 +248,5 @@
 #endif
 	return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/a3000.c linux/drivers/scsi/a3000.c
--- linux.orig/drivers/scsi/a3000.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/scsi/a3000.c	2002-07-20 01:08:39.000000000 +0000
@@ -199,9 +199,7 @@
     return 1;
 
 fail_irq:
-#ifdef MODULE
     wd33c93_release();
-#endif /* MODULE */
     scsi_unregister(a3000_host);
 fail_register:
     release_mem_region(0xDD0000, 256);
@@ -216,11 +214,11 @@
 
 int __exit a3000_release(struct Scsi_Host *instance)
 {
-#ifdef MODULE
     wd33c93_release();
-#endif /* MODULE*/
     DMA(instance)->CNTR = 0;
     release_mem_region(0xDD0000, 256);
     free_irq(IRQ_AMIGA_PORTS, a3000_intr);
     return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
--- linux.orig/drivers/scsi/aacraid/Makefile	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/aacraid/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -1,16 +1,10 @@
 
 EXTRA_CFLAGS	+= -I$(TOPDIR)/drivers/scsi
 
+O_TARGET	:= aacraid.o
+obj-m		:= $(O_TARGET)
 
-O_TARGET	:= dummy.o
-
-list-multi	:= aacraid.o
-aacraid-objs	:= linit.o aachba.o commctrl.o comminit.o commsup.o \
+obj-y		:= linit.o aachba.o commctrl.o comminit.o commsup.o \
 		   dpcsup.o rx.o sap1sup.o
 
-obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
-
 include $(TOPDIR)/Rules.make
-
-aacraid.o: $(aacraid-objs)
-	$(LD) -r -o $@ $(aacraid-objs)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
--- linux.orig/drivers/scsi/aacraid/aachba.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/aacraid/aachba.c	2002-07-20 01:08:40.000000000 +0000
@@ -494,8 +494,9 @@
 			scsicmd->use_sg,
 			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 	else if(scsicmd->request_bufflen)
-		pci_unmap_single(dev->pdev, (u32)scsicmd->SCp.ptr, scsicmd->request_bufflen,
-				scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+		pci_unmap_single(dev->pdev, (dma_addr_t)(long)scsicmd->SCp.ptr,
+				 scsicmd->request_bufflen,
+				 scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 	readreply = (struct aac_read_reply *)fib_data(fibptr);
 	if (le32_to_cpu(readreply->status) == ST_OK)
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
@@ -537,8 +538,9 @@
 			scsicmd->use_sg,
 			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 	else if(scsicmd->request_bufflen)
-		pci_unmap_single(dev->pdev, (u32)scsicmd->SCp.ptr, scsicmd->request_bufflen,
-			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+		pci_unmap_single(dev->pdev, (dma_addr_t)(long)scsicmd->SCp.ptr,
+				 scsicmd->request_bufflen,
+				 scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 
 	writereply = (struct aac_write_reply *) fib_data(fibptr);
 	if (le32_to_cpu(writereply->status) == ST_OK)
@@ -641,10 +643,10 @@
 	}
 	else if(scsicmd->request_bufflen)
 	{
-		u32 addr;
+		dma_addr_t addr;
 		addr = pci_map_single(dev->pdev, scsicmd->request_buffer,
 				scsicmd->request_bufflen, scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
-		scsicmd->SCp.ptr = (void *)addr;
+		scsicmd->SCp.ptr = (void *)(long)addr;
 		readcmd->sg.sg[0].addr = cpu_to_le32(addr);
 		readcmd->sg.sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
 
@@ -763,14 +765,14 @@
 	}
 	else if(scsicmd->request_bufflen)
 	{
-		u32 addr; 
+		dma_addr_t addr; 
 		addr = pci_map_single(dev->pdev,
 				scsicmd->request_buffer,
 				scsicmd->request_bufflen,
 				scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 		writecmd->sg.sg[0].addr = cpu_to_le32(addr);
 		writecmd->sg.sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
-		scsicmd->SCp.ptr = (void *)addr;
+		scsicmd->SCp.ptr = (void *)(long)addr;
 		byte_count = scsicmd->request_bufflen;
 
 		if (byte_count > (64 * 1024))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aacraid/aacraid.h linux/drivers/scsi/aacraid/aacraid.h
--- linux.orig/drivers/scsi/aacraid/aacraid.h	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/aacraid/aacraid.h	2002-07-20 01:08:40.000000000 +0000
@@ -682,7 +682,7 @@
 	unsigned long		fsrev;		/* Main driver's revision number */
 	
 	struct aac_init		*init;		/* Holds initialization info to communicate with adapter */
-	void *			init_pa; 	/* Holds physical address of the init struct */
+	dma_addr_t		init_pa; 	/* Holds physical address of the init struct */
 	
 	struct pci_dev		*pdev;		/* Our PCI interface */
 	void *			printfbuf;	/* pointer to buffer used for printf's from the adapter */
@@ -1168,7 +1168,17 @@
 	u32	options;
 	u32	OEM;
 };
-	
+
+static inline u32 fib2addr(struct hw_fib *hw)
+{
+	return (u32)hw;
+}
+
+static inline struct hw_fib *addr2fib(u32 addr)
+{
+	return (struct hw_fib *)addr;
+}
+
 const char *aac_driverinfo(struct Scsi_Host *);
 struct fib *fib_alloc(struct aac_dev *dev);
 int fib_setup(struct aac_dev *dev);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
--- linux.orig/drivers/scsi/aacraid/comminit.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/aacraid/comminit.c	2002-07-20 01:08:23.000000000 +0000
@@ -65,12 +65,12 @@
 		printk(KERN_ERR "aacraid: unable to create mapping.\n");
 		return 0;
 	}
-	dev->comm_addr  = (void *)base;
+	dev->comm_addr = (void *)base;
 	dev->comm_phys = phys;
-	dev->comm_size     = size;
+	dev->comm_size = size;
 
 	dev->init = (struct aac_init *)(base + fibsize);
-	dev->init_pa = (struct aac_init *)(phys + fibsize);
+	dev->init_pa = phys + fibsize;
 
 	init = dev->init;
 
@@ -82,7 +82,7 @@
 	 *	Adapter Fibs are the first thing allocated so that they
 	 *	start page aligned
 	 */
-	init->AdapterFibsVirtualAddress = cpu_to_le32(base);
+	init->AdapterFibsVirtualAddress = cpu_to_le32((long)base);
 	init->AdapterFibsPhysicalAddress = cpu_to_le32(phys);
 	init->AdapterFibsSize = cpu_to_le32(fibsize);
 	init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
--- linux.orig/drivers/scsi/aacraid/commsup.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/aacraid/commsup.c	2002-07-20 01:08:25.000000000 +0000
@@ -445,13 +445,18 @@
 		fib->header.XferState |= cpu_to_le32(ResponseExpected);
 		FIB_COUNTER_INCREMENT(aac_config.NormalSent);
 	} 
-	fib->header.SenderData = (unsigned long)fibptr;	/* for callback */
+	/*
+	 *	Map the fib into 32bits by using the fib number
+	 */
+	fib->header.SenderData = fibptr-&dev->fibs[0];	/* for callback */
 	/*
 	 *	Set FIB state to indicate where it came from and if we want a
 	 *	response from the adapter. Also load the command from the
 	 *	caller.
+	 *
+	 *	Map the hw fib pointer as a 32bit value
 	 */
-	fib->header.SenderFibAddress = cpu_to_le32((u32)fib);
+	fib->header.SenderFibAddress = fib2addr(fib);
 	fib->header.Command = cpu_to_le16(command);
 	fib->header.XferState |= cpu_to_le32(SentFromHost);
 	fibptr->fib->header.Flags = 0;				/* Zero the flags field - its internal only...	 */
@@ -756,9 +761,9 @@
 	if (cp[length] != 0)
 		cp[length] = 0;
 	if (level == LOG_HIGH_ERROR)
-		printk(KERN_WARNING "aacraid:%s.\n", cp);
+		printk(KERN_WARNING "aacraid:%s", cp);
 	else
-		printk(KERN_INFO "aacraid:%s.\n", cp);
+		printk(KERN_INFO "aacraid:%s", cp);
 	memset(cp, 0,  256);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
--- linux.orig/drivers/scsi/aacraid/dpcsup.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/aacraid/dpcsup.c	2002-07-20 01:08:36.000000000 +0000
@@ -77,9 +77,9 @@
 		int fast;
 
 		fast = (int) (entry->addr & 0x01);
-		fib = (struct hw_fib *) (entry->addr & ~0x01);
+		fib = addr2fib(entry->addr & ~0x01);
 		aac_consumer_free(dev, q, HostNormRespQueue);
-		fibctx = (struct fib *)fib->header.SenderData;
+		fibctx = &dev->fibs[fib->header.SenderData];
 		/*
 		 *	Remove this fibctx from the Outstanding I/O queue.
 		 *	But only if it has not already been timed out.
@@ -172,7 +172,7 @@
 	while(aac_consumer_get(dev, q, &entry))
 	{
 		struct hw_fib * fib;
-		fib = (struct hw_fib *)entry->addr;
+		fib = addr2fib(entry->addr);
 
 		if (dev->aif_thread) {
 		        list_add_tail(&fib->header.FibLinks, &q->cmdq);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
--- linux.orig/drivers/scsi/aacraid/linit.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/aacraid/linit.c	2002-07-20 01:08:23.000000000 +0000
@@ -35,7 +35,7 @@
  *	
  */
 
-#define AAC_DRIVER_VERSION		"0.9.9ac2-rel"
+#define AAC_DRIVER_VERSION		"0.9.9ac4-rel"
 #define AAC_DRIVER_BUILD_DATE		__DATE__
 
 #include <linux/module.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- linux.orig/drivers/scsi/aha152x.c	2001-11-09 22:05:06.000000000 +0000
+++ linux/drivers/scsi/aha152x.c	2002-07-20 01:08:23.000000000 +0000
@@ -13,9 +13,14 @@
  * General Public License for more details.
  *
  *
- * $Id: aha152x.c,v 2.4 2000/12/16 12:53:56 fischer Exp $
+ * $Id: aha152x.c,v 2.5 2002/04/14 11:24:53 fischer Exp $
  *
  * $Log: aha152x.c,v $
+ * Revision 2.5  2002/04/14 11:24:53  fischer
+ * - isapnp support
+ * - abort fixed
+ * - 2.5 support
+ *
  * Revision 2.4  2000/12/16 12:53:56  fischer
  * - allow REQUEST SENSE to be queued
  * - handle shared PCI interrupts
@@ -222,7 +227,9 @@
 #endif
 
 #include <linux/sched.h>
+#include <asm/irq.h>
 #include <asm/io.h>
+#include <linux/version.h>
 #include <linux/blk.h>
 #include "scsi.h"
 #include "sd.h"
@@ -306,15 +313,17 @@
 
 #define DELAY_DEFAULT 1000
 
-/* possible irq range */
 #if defined(PCMCIA)
 #define IRQ_MIN 0
 #define IRQ_MAX 16
 #else
 #define IRQ_MIN 9
+#if defined(__PPC)
+#define IRQ_MAX (NR_IRQS-1)
+#else
 #define IRQ_MAX 12
 #endif
-#define IRQS    IRQ_MAX-IRQ_MIN+1
+#endif
 
 enum {
 	not_issued	= 0x0001,	/* command not yet issued */
@@ -417,7 +426,7 @@
 	char *conf;
 } setup[2];
 
-static struct Scsi_Host *aha152x_host[IRQS];
+static struct Scsi_Host *aha152x_host[2];
 
 /*
  * internal states of the host
@@ -593,6 +602,7 @@
 #define SCDONE(SCpnt)		SCDATA(SCpnt)->done
 #define SCSEM(SCpnt)		SCDATA(SCpnt)->sem
 
+#define SG_ADDRESS(buffer)	((char *) (page_address((buffer)->page)+(buffer)->offset))
 
 /* state handling */
 static void seldi_run(struct Scsi_Host *shpnt);
@@ -668,7 +678,6 @@
 
 /* possible i/o addresses for the AIC-6260; default first */
 static unsigned short ports[] = { 0x340, 0x140 };
-#define PORT_COUNT (sizeof(ports) / sizeof(unsigned short))
 
 #if !defined(SKIP_BIOSTEST)
 /* possible locations for the Adaptec BIOS; defaults first */
@@ -684,7 +693,6 @@
 	0xeb800,		/* VTech Platinum SMP */
 	0xf0000,
 };
-#define ADDRESS_COUNT (sizeof(addresses) / sizeof(unsigned int))
 
 /* signatures for various AIC-6[23]60 based controllers.
    The point in detecting signatures is to avoid useless and maybe
@@ -726,8 +734,6 @@
 	{ "DTC3520A Host Adapter BIOS", 0x318a, 26 },
 		/* DTC 3520A ISA SCSI */
 };
-
-#define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))
 #endif
 
 
@@ -806,7 +812,7 @@
 #if defined(PCMCIA) || !defined(MODULE)
 void aha152x_setup(char *str, int *ints)
 {
-	if(setup_count>2) {
+	if(setup_count>=ARRAY_SIZE(setup)) {
 		printk(KERN_ERR "aha152x: you can only configure up to two controllers\n");
 		return;
 	}
@@ -849,7 +855,7 @@
 #endif
 	int count=setup_count;
 
-	get_options(str, sizeof(ints)/sizeof(int), ints);
+	get_options(str, ARRAY_SIZE(ints), ints);
 	aha152x_setup(str,ints);
 
 	return count<setup_count;
@@ -903,10 +909,10 @@
 
 #if !defined(PCMCIA)
 	int i;
-	for (i = 0; i < PORT_COUNT && (setup->io_port != ports[i]); i++)
+	for (i = 0; i < ARRAY_SIZE(ports) && (setup->io_port != ports[i]); i++)
 		;
 
-	if (i == PORT_COUNT)
+	if (i == ARRAY_SIZE(ports))
 		return 0;
 #endif
 
@@ -939,12 +945,25 @@
 	return 1;
 }
 
+static inline struct Scsi_Host *lookup_irq(int irqno)
+{
+	int i;
+
+	for(i=0; i<ARRAY_SIZE(aha152x_host); i++)
+		if(aha152x_host[i] && aha152x_host[i]->irq==irqno)
+			return aha152x_host[i];
+
+	return 0;
+}
+
 static void swintr(int irqno, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *shpnt = aha152x_host[irqno - IRQ_MIN];
+	struct Scsi_Host *shpnt = lookup_irq(irqno);
 
-	if (!shpnt)
-        	printk(KERN_ERR "aha152x%d: catched software interrupt for unknown controller.\n", HOSTNO);
+	if (!shpnt) {
+        	printk(KERN_ERR "aha152x%d: catched software interrupt %d for unknown controller.\n", HOSTNO, irqno);
+		return;
+	}
 
 	HOSTDATA(shpnt)->swint++;
 
@@ -966,7 +985,7 @@
 #endif
 	tpnt->proc_name = "aha152x"; 
 
-	for (i = 0; i < IRQS; i++)
+	for (i = 0; i < ARRAY_SIZE(aha152x_host); i++)
 		aha152x_host[i] = (struct Scsi_Host *) NULL;
 
 	if (setup_count) {
@@ -981,7 +1000,7 @@
 	}
 
 #if defined(SETUP0)
-	if (setup_count < 2) {
+	if (setup_count < ARRAY_SIZE(setup)) {
 		struct aha152x_setup override = SETUP0;
 
 		if (setup_count == 0 || (override.io_port != setup[0].io_port)) {
@@ -1002,7 +1021,7 @@
 #endif
 
 #if defined(SETUP1)
-	if (setup_count < 2) {
+	if (setup_count < ARRAY_SIZE(setup)) {
 		struct aha152x_setup override = SETUP1;
 
 		if (setup_count == 0 || (override.io_port != setup[0].io_port)) {
@@ -1023,7 +1042,7 @@
 #endif
 
 #if defined(MODULE)
-	if (setup_count<2 && (aha152x[0]!=0 || io[0]!=0 || irq[0]!=0)) {
+	if (setup_count<ARRAY_SIZE(setup) && (aha152x[0]!=0 || io[0]!=0 || irq[0]!=0)) {
 		if(aha152x[0]!=0) {
 			setup[setup_count].conf        = "";
 			setup[setup_count].io_port     = aha152x[0];
@@ -1066,7 +1085,7 @@
 			       setup[setup_count].ext_trans);
 	}
 
-	if (setup_count < 2 && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) {
+	if (setup_count<ARRAY_SIZE(setup) && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) {
 		if(aha152x1[0]!=0) {
 			setup[setup_count].conf        = "";
 			setup[setup_count].io_port     = aha152x1[0];
@@ -1110,7 +1129,7 @@
 #endif
 
 #ifdef __ISAPNP__
-	while ( setup_count<2 && (dev=isapnp_find_dev(NULL, ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), dev)) ) {
+	while ( setup_count<ARRAY_SIZE(setup) && (dev=isapnp_find_dev(NULL, ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), dev)) ) {
 		if (dev->prepare(dev) < 0)
 			continue;
 		if (dev->active)
@@ -1145,11 +1164,11 @@
 
 
 #if defined(AUTOCONF)
-	if (setup_count < 2) {
+	if (setup_count<ARRAY_SIZE(setup)) {
 #if !defined(SKIP_BIOSTEST)
 		ok = 0;
-		for (i = 0; i < ADDRESS_COUNT && !ok; i++)
-			for (j = 0; (j < SIGNATURE_COUNT) && !ok; j++)
+		for (i = 0; i < ARRAY_SIZE(addresses) && !ok; i++)
+			for (j = 0; j<ARRAY_SIZE(signatures) && !ok; j++)
 				ok = isa_check_signature(addresses[i] + signatures[j].sig_offset,
 								signatures[j].signature, signatures[j].sig_length);
 
@@ -1162,7 +1181,7 @@
 #endif				/* !SKIP_BIOSTEST */
 
 		ok = 0;
-		for (i = 0; i < PORT_COUNT && setup_count < 2; i++) {
+		for (i = 0; i < ARRAY_SIZE(ports) && setup_count < 2; i++) {
 			if ((setup_count == 1) && (setup[0].io_port == ports[i]))
 				continue;
 
@@ -1217,7 +1236,7 @@
 	for (i=0; i<setup_count; i++) {
 		struct Scsi_Host *shpnt;
 
-		aha152x_host[setup[i].irq - IRQ_MIN] = shpnt =
+		aha152x_host[registered_count] = shpnt =
 		    scsi_register(tpnt, sizeof(struct aha152x_hostdata));
 
 		if(!shpnt) {
@@ -1341,7 +1360,7 @@
 			scsi_unregister(shpnt);
 			registered_count--;
 			release_region(shpnt->io_port, IO_RANGE);
-			aha152x_host[shpnt->irq - IRQ_MIN] = 0;
+			aha152x_host[registered_count] = 0;
 			shpnt = 0;
 			continue;
 		}
@@ -1349,9 +1368,13 @@
 
 		printk(KERN_INFO "aha152x%d: trying software interrupt, ", HOSTNO);
 		SETPORT(DMACNTRL0, SWINT|INTEN);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		spin_unlock_irq(&io_request_lock);
+#endif
 		mdelay(1000);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		spin_lock_irq(&io_request_lock);
+#endif
 		free_irq(shpnt->irq, shpnt);
 
 		if (!HOSTDATA(shpnt)->swint) {
@@ -1367,7 +1390,7 @@
 
 			registered_count--;
 			release_region(shpnt->io_port, IO_RANGE);
-			aha152x_host[shpnt->irq - IRQ_MIN] = 0;
+			aha152x_host[registered_count] = 0;
 			scsi_unregister(shpnt);
 			shpnt=NULL;
 			continue;
@@ -1382,10 +1405,11 @@
 		if (request_irq(shpnt->irq, intr, SA_INTERRUPT|SA_SHIRQ, "aha152x", shpnt) < 0) {
 			printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n", HOSTNO);
 
-			scsi_unregister(shpnt);
 			registered_count--;
 			release_region(shpnt->io_port, IO_RANGE);
-			shpnt = aha152x_host[shpnt->irq - IRQ_MIN] = 0;
+			aha152x_host[registered_count] = 0;
+			scsi_unregister(shpnt);
+			shpnt=NULL;
 			continue;
 		}
 	}
@@ -1494,7 +1518,7 @@
 	   SCp.phase            : current state of the command */
 	if (SCpnt->use_sg) {
 		SCpnt->SCp.buffer           = (struct scatterlist *) SCpnt->request_buffer;
-		SCpnt->SCp.ptr              = SCpnt->SCp.buffer->address;
+		SCpnt->SCp.ptr              = SG_ADDRESS(SCpnt->SCp.buffer);
 		SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;
 		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
 	} else {
@@ -1584,7 +1608,6 @@
 	if(HOSTDATA(shpnt)->debug & debug_eh) {
 		printk(DEBUG_LEAD "abort(%p)", CMDINFO(SCpnt), SCpnt);
 		show_queues(shpnt);
-		mdelay(1000);
 	}
 #endif
 
@@ -1622,9 +1645,19 @@
 
 static void timer_expired(unsigned long p)
 {
-	struct semaphore *sem = (void *)p;
+	Scsi_Cmnd	 *SCp   = (Scsi_Cmnd *)p;
+	struct semaphore *sem   = SCSEM(SCp);
+	struct Scsi_Host *shpnt = SCp->host;
+
+	/* remove command from issue queue */
+	if(remove_SC(&ISSUE_SC, SCp)) {
+		printk(KERN_INFO "aha152x: ABORT timed out - removed from issue queue\n");
+		kfree(SCp->host_scribble);
+		SCp->host_scribble=0;
+	} else {
+		printk(KERN_INFO "aha152x: ABORT timed out - not on issue queue\n");
+	}
 
-	printk(KERN_INFO "aha152x: timer expired\n");
 	up(sem);
 }
 
@@ -1645,7 +1678,6 @@
 	if(HOSTDATA(shpnt)->debug & debug_eh) {
 		printk(INFO_LEAD "aha152x_device_reset(%p)", CMDINFO(SCpnt), SCpnt);
 		show_queues(shpnt);
-		mdelay(1000);
 	}
 #endif
 
@@ -1663,13 +1695,13 @@
 	cmnd.request_bufflen = 0;
 
 	init_timer(&timer);
-	timer.data     = (unsigned long) &sem;
+	timer.data     = (unsigned long) &cmnd;
 	timer.expires  = jiffies + 100*HZ;   /* 10s */
 	timer.function = (void (*)(unsigned long)) timer_expired;
-	add_timer(&timer);
 
 	aha152x_internal_queue(&cmnd, &sem, resetting, 0, internal_done);
 
+	add_timer(&timer);
 	down(&sem);
 
 	del_timer(&timer);
@@ -1719,7 +1751,6 @@
 	if(HOSTDATA(shpnt)->debug & debug_eh) {
 		printk(DEBUG_LEAD "aha152x_bus_reset(%p)", CMDINFO(SCpnt), SCpnt);
 		show_queues(shpnt);
-		mdelay(1000);
 	}
 #endif
 
@@ -1878,7 +1909,7 @@
 static void run(void)
 {
 	int i;
-	for (i = 0; i < IRQS; i++) {
+	for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) {
 		struct Scsi_Host *shpnt = aha152x_host[i];
 		if (shpnt && HOSTDATA(shpnt)->service) {
 			HOSTDATA(shpnt)->service=0;
@@ -1894,10 +1925,10 @@
 
 static void intr(int irqno, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *shpnt = aha152x_host[irqno - IRQ_MIN];
+	struct Scsi_Host *shpnt = lookup_irq(irqno);
 
 	if (!shpnt) {
-		printk(KERN_ERR "aha152x: catched interrupt for unknown controller.\n");
+		printk(KERN_ERR "aha152x: catched interrupt %d for unknown controller.\n", irqno);
 		return;
 	}
 
@@ -2681,7 +2712,7 @@
                                		/* advance to next buffer */
                                		CURRENT_SC->SCp.buffers_residual--;
                                		CURRENT_SC->SCp.buffer++;
-                               		CURRENT_SC->SCp.ptr           = CURRENT_SC->SCp.buffer->address;
+                               		CURRENT_SC->SCp.ptr           = SG_ADDRESS(CURRENT_SC->SCp.buffer);
                                		CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
 				} 
                 	}
@@ -2791,7 +2822,7 @@
 			/* advance to next buffer */
 			CURRENT_SC->SCp.buffers_residual--;
 			CURRENT_SC->SCp.buffer++;
-			CURRENT_SC->SCp.ptr           = CURRENT_SC->SCp.buffer->address;
+			CURRENT_SC->SCp.ptr           = SG_ADDRESS(CURRENT_SC->SCp.buffer);
 			CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
 		}
 
@@ -2821,13 +2852,13 @@
 		CURRENT_SC->resid += data_count;
 
 		if(CURRENT_SC->use_sg) {
-			data_count -= CURRENT_SC->SCp.ptr - CURRENT_SC->SCp.buffer->address;
+			data_count -= CURRENT_SC->SCp.ptr - SG_ADDRESS(CURRENT_SC->SCp.buffer);
 			while(data_count>0) {
 				CURRENT_SC->SCp.buffer--;
 				CURRENT_SC->SCp.buffers_residual++;
 				data_count -= CURRENT_SC->SCp.buffer->length;
 			}
-			CURRENT_SC->SCp.ptr           = CURRENT_SC->SCp.buffer->address - data_count;
+			CURRENT_SC->SCp.ptr           = SG_ADDRESS(CURRENT_SC->SCp.buffer) - data_count;
 			CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length + data_count;
 		} else {
 			CURRENT_SC->SCp.ptr           -= data_count;
@@ -2955,10 +2986,9 @@
 	int pending;
 
 	DO_LOCK(flags);
-	if(HOSTDATA(shpnt)->in_intr!=0)
-	{
+	if(HOSTDATA(shpnt)->in_intr!=0) {
 		DO_UNLOCK(flags);
-		/* _error never returns.. */
+		/* aha152x_error never returns.. */
 		aha152x_error(shpnt, "bottom-half already running!?");
 	}
 	HOSTDATA(shpnt)->in_intr++;
@@ -3765,7 +3795,7 @@
 	unsigned long flags;
 	int thislength;
 
-	for (i = 0, shpnt = (struct Scsi_Host *) NULL; i < IRQS; i++)
+	for (i = 0, shpnt = (struct Scsi_Host *) NULL; i<ARRAY_SIZE(aha152x_host); i++)
 		if (aha152x_host[i] && aha152x_host[i]->host_no == hostno)
 			shpnt = aha152x_host[i];
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h
--- linux.orig/drivers/scsi/aha152x.h	2001-07-20 04:08:07.000000000 +0000
+++ linux/drivers/scsi/aha152x.h	2002-07-20 01:08:25.000000000 +0000
@@ -2,7 +2,7 @@
 #define _AHA152X_H
 
 /*
- * $Id: aha152x.h,v 2.4 2000/12/16 12:48:48 fischer Exp $
+ * $Id: aha152x.h,v 2.5 2002/04/14 11:24:12 fischer Exp $
  */
 
 #if defined(__KERNEL__)
@@ -27,7 +27,7 @@
    (unless we support more than 1 cmd_per_lun this should do) */
 #define AHA152X_MAXQUEUE 7
 
-#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 2.4 $"
+#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 2.5 $"
 
 /* Initial value of Scsi_Host entry */
 #define AHA152X { proc_name:			"aha152x",		\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/Config.in linux/drivers/scsi/aic7xxx/Config.in
--- linux.orig/drivers/scsi/aic7xxx/Config.in	2001-05-04 22:16:28.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/Config.in	2002-07-20 01:08:27.000000000 +0000
@@ -1,8 +1,13 @@
 if [ "$CONFIG_SCSI_AIC7XXX_OLD" != "y" ]; then
    dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
    if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
-      int  '  Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 253
-      int  '  Initial bus reset delay in milli-seconds' CONFIG_AIC7XXX_RESET_DELAY_MS 15000
-      bool  '  Build Adapter Firmware with Kernel Build' CONFIG_AIC7XXX_BUILD_FIRMWARE
+      int  '  Maximum number of TCQ commands per device' \
+	CONFIG_AIC7XXX_CMDS_PER_DEVICE 253
+      int  '  Initial bus reset delay in milli-seconds' \
+	CONFIG_AIC7XXX_RESET_DELAY_MS 15000
+      bool  '  Probe for EISA and VL AIC7XXX Adapters' \
+	CONFIG_AIC7XXX_PROBE_EISA_VL
+      bool  '  Build Adapter Firmware with Kernel Build' \
+	CONFIG_AIC7XXX_BUILD_FIRMWARE
    fi
 fi
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/Makefile linux/drivers/scsi/aic7xxx/Makefile
--- linux.orig/drivers/scsi/aic7xxx/Makefile	2001-08-12 17:51:42.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/Makefile	2002-07-20 01:08:35.000000000 +0000
@@ -6,35 +6,38 @@
 
 O_TARGET := aic7xxx_drv.o
 
-list-multi	:= aic7xxx_mod.o
+list-multi	:= aic7xxx.o
 
-obj-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx_mod.o
+obj-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx.o
 
 #EXTRA_CFLAGS += -g
 
 # Platform Specific Files
-AIC7XXX_OBJS = aic7xxx_linux.o 
-AIC7XXX_OBJS += aic7xxx_proc.o aic7770_linux.o
+obj-aic7xxx = aic7xxx_osm.o aic7xxx_proc.o aic7770_osm.o
 #PCI Specific Platform Files
 ifeq ($(CONFIG_PCI),y)
-AIC7XXX_OBJS += aic7xxx_linux_pci.o
+obj-aic7xxx += aic7xxx_osm_pci.o
 endif
 # Core Files
-AIC7XXX_OBJS += aic7xxx.o aic7xxx_93cx6.o aic7770.o
+obj-aic7xxx += aic7xxx_core.o aic7xxx_93cx6.o aic7770.o
 #PCI Specific Core Files
 ifeq ($(CONFIG_PCI),y)
-AIC7XXX_OBJS += aic7xxx_pci.o
+obj-aic7xxx += aic7xxx_pci.o
 endif
 
 # Override our module desitnation
-MOD_TARGET = aic7xxx.o
+MOD_DESTDIR = $(shell cd .. && $(CONFIG_SHELL) $(TOPDIR)/scripts/pathdown.sh)
 
 include $(TOPDIR)/Rules.make
 
-aic7xxx_mod.o: aic7xxx_seq.h aic7xxx_reg.h $(AIC7XXX_OBJS)
-	$(LD) $(LD_RFLAG) -r -o $@ $(AIC7XXX_OBJS)
+aic7xxx.o: $(obj-aic7xxx)
+	$(LD) $(LD_RFLAG) -r -o $@ $(obj-aic7xxx)
 
 ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
+aic7xxx_core.o: aic7xxx_seq.h
+
+$(obj-aic7xxx): aic7xxx_reg.h
+
 aic7xxx_seq.h aic7xxx_reg.h: aic7xxx.seq aic7xxx.reg aicasm/aicasm
 	aicasm/aicasm -I. -r aic7xxx_reg.h -o aic7xxx_seq.h aic7xxx.seq
 endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7770.c linux/drivers/scsi/aic7xxx/aic7770.c
--- linux.orig/drivers/scsi/aic7xxx/aic7770.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7770.c	2002-07-20 01:08:40.000000000 +0000
@@ -37,21 +37,27 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#14 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#21 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.1 2000/09/16 20:02:27 gibbs Exp $
  */
 
+#ifdef __linux__
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
 #include "aic7xxx_93cx6.h"
+#else
+#include <dev/aic7xxx/aic7xxx_osm.h>
+#include <dev/aic7xxx/aic7xxx_inline.h>
+#include <dev/aic7xxx/aic7xxx_93cx6.h>
+#endif
 
 #define ID_AIC7770	0x04907770
 #define ID_AHA_274x	0x04907771
 #define ID_AHA_284xB	0x04907756 /* BIOS enabled */
 #define ID_AHA_284x	0x04907757 /* BIOS disabled*/
 
-static void aha2840_load_seeprom(struct ahc_softc *ahc);
+static int aha2840_load_seeprom(struct ahc_softc *ahc);
 static ahc_device_setup_t ahc_aic7770_VL_setup;
 static ahc_device_setup_t ahc_aic7770_EISA_setup;;
 static ahc_device_setup_t ahc_aic7770_setup;
@@ -96,21 +102,33 @@
 }
 
 int
-aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry)
+aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
 {
+	u_long	l;
+	u_long	s;
 	int	error;
+	int	have_seeprom;
 	u_int	hostconf;
 	u_int   irq;
 	u_int	intdef;
 
 	error = entry->setup(ahc);
+	have_seeprom = 0;
 	if (error != 0)
 		return (error);
 
-	error = aic7770_map_registers(ahc);
+	error = aic7770_map_registers(ahc, io);
 	if (error != 0)
 		return (error);
 
+	/*
+	 * Before we continue probing the card, ensure that
+	 * its interrupts are *disabled*.  We don't want
+	 * a misstep to hang the machine in an interrupt
+	 * storm.
+	 */
+	ahc_intr_enable(ahc, FALSE);
+
 	ahc->description = entry->name;
 	error = ahc_softc_init(ahc);
 
@@ -168,21 +186,22 @@
 					ahc->flags |= AHC_TERM_ENB_B;
 			}
 		}
-		/*
-		 * We have no way to tell, so assume extended
-		 * translation is enabled.
-		 */
-		ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
+		if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS))
+			ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
 		break;
 	}
 	case AHC_VL:
 	{
-		aha2840_load_seeprom(ahc);
+		have_seeprom = aha2840_load_seeprom(ahc);
 		break;
 	}
 	default:
 		break;
 	}
+	if (have_seeprom == 0) {
+		free(ahc->seep_config, M_DEVBUF);
+		ahc->seep_config = NULL;
+	}
 
 	/*
 	 * Ensure autoflush is enabled
@@ -201,15 +220,16 @@
 	if (error != 0)
 		return (error);
 
+	error = aic7770_map_int(ahc, irq);
+	if (error != 0)
+		return (error);
+
+	ahc_list_lock(&l);
 	/*
 	 * Link this softc in with all other ahc instances.
 	 */
 	ahc_softc_insert(ahc);
 
-	error = aic7770_map_int(ahc, irq);
-	if (error != 0)
-		return (error);
-
 	/*
 	 * Enable the board's BUS drivers
 	 */
@@ -218,7 +238,11 @@
 	/*
 	 * Allow interrupts.
 	 */
+	ahc_lock(ahc, &s);
 	ahc_intr_enable(ahc, TRUE);
+	ahc_unlock(ahc, &s);
+
+	ahc_list_unlock(&l);
 
 	return (0);
 }
@@ -226,14 +250,13 @@
 /*
  * Read the 284x SEEPROM.
  */
-static void
+static int
 aha2840_load_seeprom(struct ahc_softc *ahc)
 {
-	struct	  seeprom_descriptor sd;
-	struct	  seeprom_config sc;
-	uint16_t  checksum = 0;
-	uint8_t   scsi_conf;
-	int	  have_seeprom;
+	struct	seeprom_descriptor sd;
+	struct	seeprom_config *sc;
+	int	have_seeprom;
+	uint8_t scsi_conf;
 
 	sd.sd_ahc = ahc;
 	sd.sd_control_offset = SEECTL_2840;
@@ -246,23 +269,16 @@
 	sd.sd_CK = CK_2840;
 	sd.sd_DO = DO_2840;
 	sd.sd_DI = DI_2840;
+	sc = ahc->seep_config;
 
 	if (bootverbose)
 		printf("%s: Reading SEEPROM...", ahc_name(ahc));
-	have_seeprom = read_seeprom(&sd,
-				    (uint16_t *)&sc,
-				    /*start_addr*/0,
-				    sizeof(sc)/2);
+	have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)&sc,
+					/*start_addr*/0, sizeof(sc)/2);
 
 	if (have_seeprom) {
-		/* Check checksum */
-		int i;
-		int maxaddr = (sizeof(sc)/2) - 1;
-		uint16_t *scarray = (uint16_t *)&sc;
-
-		for (i = 0; i < maxaddr; i++)
-			checksum = checksum + scarray[i];
-		if (checksum != sc.checksum) {
+
+		if (ahc_verify_cksum(sc) == 0) {
 			if(bootverbose)
 				printf ("checksum error\n");
 			have_seeprom = 0;
@@ -280,41 +296,44 @@
 		 * Put the data we've collected down into SRAM
 		 * where ahc_init will find it.
 		 */
-		int i;
-		int max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
+		int	 i;
+		int	 max_targ;
 		uint16_t discenable;
 
+		max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
 		discenable = 0;
 		for (i = 0; i < max_targ; i++){
-	                uint8_t target_settings;
-			target_settings = (sc.device_flags[i] & CFXFER) << 4;
-			if (sc.device_flags[i] & CFSYNCH)
+			uint8_t target_settings;
+
+			target_settings = (sc->device_flags[i] & CFXFER) << 4;
+			if (sc->device_flags[i] & CFSYNCH)
 				target_settings |= SOFS;
-			if (sc.device_flags[i] & CFWIDEB)
+			if (sc->device_flags[i] & CFWIDEB)
 				target_settings |= WIDEXFER;
-			if (sc.device_flags[i] & CFDISC)
+			if (sc->device_flags[i] & CFDISC)
 				discenable |= (0x01 << i);
 			ahc_outb(ahc, TARG_SCSIRATE + i, target_settings);
 		}
 		ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
 		ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
 
-		ahc->our_id = sc.brtime_id & CFSCSIID;
+		ahc->our_id = sc->brtime_id & CFSCSIID;
 
 		scsi_conf = (ahc->our_id & 0x7);
-		if (sc.adapter_control & CFSPARITY)
+		if (sc->adapter_control & CFSPARITY)
 			scsi_conf |= ENSPCHK;
-		if (sc.adapter_control & CFRESETB)
+		if (sc->adapter_control & CFRESETB)
 			scsi_conf |= RESET_SCSI;
 
-		if (sc.bios_control & CF284XEXTEND)		
+		if (sc->bios_control & CF284XEXTEND)		
 			ahc->flags |= AHC_EXTENDED_TRANS_A;
 		/* Set SCSICONF info */
 		ahc_outb(ahc, SCSICONF, scsi_conf);
 
-		if (sc.adapter_control & CF284XSTERM)
+		if (sc->adapter_control & CF284XSTERM)
 			ahc->flags |= AHC_TERM_ENB_A;
 	}
+	return (have_seeprom);
 }
 
 static int
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7770_linux.c linux/drivers/scsi/aic7xxx/aic7770_linux.c
--- linux.orig/drivers/scsi/aic7xxx/aic7770_linux.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7770_linux.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,153 +0,0 @@
-/*
- * Linux driver attachment glue for aic7770 based controllers.
- *
- * Copyright (c) 2000-2001 Adaptec Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon
- *    including a substantially similar Disclaimer requirement for further
- *    binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_linux.c#9 $
- */
-
-#include "aic7xxx_osm.h"
-
-#define MINSLOT			1
-#define NUMSLOTS		16
-#define IDOFFSET		0x80
-
-int
-aic7770_linux_probe(Scsi_Host_Template *template)
-{
-#if defined(__i386__) || defined(__alpha__)
-	struct aic7770_identity *entry;
-	struct ahc_softc *ahc;
-	int i, slot;
-	int eisaBase;
-	int found;
-
-	if (aic7xxx_no_probe)
-		return (0);
-
-	eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
-	found = 0;
-	for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
-		uint32_t eisa_id;
-		size_t	 id_size;
-
-		if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0)
-			continue;
-
-		eisa_id = 0;
-		id_size = sizeof(eisa_id);
-		for (i = 0; i < 4; i++) {
-			/* VLcards require priming*/
-			outb(0x80 + i, eisaBase + IDOFFSET);
-			eisa_id |= inb(eisaBase + IDOFFSET + i)
-				   << ((id_size-i-1) * 8);
-		}
-		if (eisa_id & 0x80000000)
-			continue;  /* no EISA card in slot */
-
-		entry = aic7770_find_device(eisa_id);
-		if (entry != NULL) {
-			char	 buf[80];
-			char	*name;
-			int	 error;
-
-			/*
-			 * Allocate a softc for this card and
-			 * set it up for attachment by our
-			 * common detect routine.
-			 */
-			sprintf(buf, "ahc_eisa:%d", slot);
-			name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
-			if (name == NULL)
-				break;
-			strcpy(name, buf);
-			ahc = ahc_alloc(template, name);
-			if (ahc == NULL) {
-				/*
-				 * If we can't allocate this one,
-				 * chances are we won't be able to
-				 * allocate future card structures.
-				 */
-				break;
-			}
-			ahc->tag = BUS_SPACE_PIO;
-			ahc->bsh.ioport = eisaBase;
-			error = aic7770_config(ahc, entry);
-			if (error != 0) {
-				ahc_free(ahc);
-				continue;
-			}
-			found++;
-		}
-	}
-	return (found);
-#else
-	return (0);
-#endif
-}
-
-int
-aic7770_map_registers(struct ahc_softc *ahc)
-{
-	/*
-	 * Lock out other contenders for our i/o space.
-	 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-	request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx");
-#else
-	if (request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx") == 0)
-		return (ENOMEM);
-#endif
-
-	return (0);
-}
-
-int
-aic7770_map_int(struct ahc_softc *ahc, u_int irq)
-{
-	int error;
-	int shared;
-
-	shared = 0;
-	if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
-		shared = SA_SHIRQ;
-
-	ahc->platform_data->irq = irq;
-	error = request_irq(ahc->platform_data->irq, ahc_linux_isr,
-			    shared, "aic7xxx", ahc);
-	
-	return (-error);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7770_osm.c linux/drivers/scsi/aic7xxx/aic7770_osm.c
--- linux.orig/drivers/scsi/aic7xxx/aic7770_osm.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7770_osm.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,150 @@
+/*
+ * Linux driver attachment glue for aic7770 based controllers.
+ *
+ * Copyright (c) 2000-2001 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#11 $
+ */
+
+#include "aic7xxx_osm.h"
+
+#define MINSLOT			1
+#define NUMSLOTS		16
+#define IDOFFSET		0x80
+
+int
+aic7770_linux_probe(Scsi_Host_Template *template)
+{
+#if defined(__i386__) || defined(__alpha__)
+	struct aic7770_identity *entry;
+	struct ahc_softc *ahc;
+	int i, slot;
+	int eisaBase;
+	int found;
+
+	eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
+	found = 0;
+	for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
+		uint32_t eisa_id;
+		size_t	 id_size;
+
+		if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0)
+			continue;
+
+		eisa_id = 0;
+		id_size = sizeof(eisa_id);
+		for (i = 0; i < 4; i++) {
+			/* VLcards require priming*/
+			outb(0x80 + i, eisaBase + IDOFFSET);
+			eisa_id |= inb(eisaBase + IDOFFSET + i)
+				   << ((id_size-i-1) * 8);
+		}
+		if (eisa_id & 0x80000000)
+			continue;  /* no EISA card in slot */
+
+		entry = aic7770_find_device(eisa_id);
+		if (entry != NULL) {
+			char	 buf[80];
+			char	*name;
+			int	 error;
+
+			/*
+			 * Allocate a softc for this card and
+			 * set it up for attachment by our
+			 * common detect routine.
+			 */
+			sprintf(buf, "ahc_eisa:%d", slot);
+			name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+			if (name == NULL)
+				break;
+			strcpy(name, buf);
+			ahc = ahc_alloc(template, name);
+			if (ahc == NULL) {
+				/*
+				 * If we can't allocate this one,
+				 * chances are we won't be able to
+				 * allocate future card structures.
+				 */
+				break;
+			}
+			error = aic7770_config(ahc, entry, eisaBase);
+			if (error != 0) {
+				ahc->bsh.ioport = 0;
+				ahc_free(ahc);
+				continue;
+			}
+			found++;
+		}
+	}
+	return (found);
+#else
+	return (0);
+#endif
+}
+
+int
+aic7770_map_registers(struct ahc_softc *ahc, u_int port)
+{
+	/*
+	 * Lock out other contenders for our i/o space.
+	 */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+	request_region(port, AHC_EISA_IOSIZE, "aic7xxx");
+#else
+	if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
+		return (ENOMEM);
+#endif
+	ahc->tag = BUS_SPACE_PIO;
+	ahc->bsh.ioport = port;
+	return (0);
+}
+
+int
+aic7770_map_int(struct ahc_softc *ahc, u_int irq)
+{
+	int error;
+	int shared;
+
+	shared = 0;
+	if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
+		shared = SA_SHIRQ;
+
+	error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
+	if (error == 0)
+		ahc->platform_data->irq = irq;
+	
+	return (-error);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx.c linux/drivers/scsi/aic7xxx/aic7xxx.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx.c	2001-10-25 20:53:48.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,6988 +0,0 @@
-/*
- * Core routines and tables shareable across OS platforms.
- *
- * Copyright (c) 1994-2001 Justin T. Gibbs.
- * Copyright (c) 2000-2001 Adaptec Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon
- *    including a substantially similar Disclaimer requirement for further
- *    binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#50 $
- *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.61 2000/11/13 03:35:43 gibbs Exp $
- */
-
-#include "aic7xxx_osm.h"
-#include "aic7xxx_inline.h"
-#include "aicasm/aicasm_insformat.h"
-
-/****************************** Softc Data ************************************/
-struct ahc_softc_tailq ahc_tailq = TAILQ_HEAD_INITIALIZER(ahc_tailq);
-
-/***************************** Lookup Tables **********************************/
-char *ahc_chip_names[] =
-{
-	"NONE",
-	"aic7770",
-	"aic7850",
-	"aic7855",
-	"aic7859",
-	"aic7860",
-	"aic7870",
-	"aic7880",
-	"aic7895",
-	"aic7895C",
-	"aic7890/91",
-	"aic7896/97",
-	"aic7892",
-	"aic7899"
-};
-static const u_int num_chip_names = NUM_ELEMENTS(ahc_chip_names);
-
-/*
- * Hardware error codes.
- */
-struct ahc_hard_error_entry {
-        uint8_t errno;
-	char *errmesg;
-};
-
-static struct ahc_hard_error_entry ahc_hard_errors[] = {
-	{ ILLHADDR,	"Illegal Host Access" },
-	{ ILLSADDR,	"Illegal Sequencer Address referrenced" },
-	{ ILLOPCODE,	"Illegal Opcode in sequencer program" },
-	{ SQPARERR,	"Sequencer Parity Error" },
-	{ DPARERR,	"Data-path Parity Error" },
-	{ MPARERR,	"Scratch or SCB Memory Parity Error" },
-	{ PCIERRSTAT,	"PCI Error detected" },
-	{ CIOPARERR,	"CIOBUS Parity Error" },
-};
-static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors);
-
-static struct ahc_phase_table_entry ahc_phase_table[] =
-{
-	{ P_DATAOUT,	MSG_NOOP,		"in Data-out phase"	},
-	{ P_DATAIN,	MSG_INITIATOR_DET_ERR,	"in Data-in phase"	},
-	{ P_DATAOUT_DT,	MSG_NOOP,		"in DT Data-out phase"	},
-	{ P_DATAIN_DT,	MSG_INITIATOR_DET_ERR,	"in DT Data-in phase"	},
-	{ P_COMMAND,	MSG_NOOP,		"in Command phase"	},
-	{ P_MESGOUT,	MSG_NOOP,		"in Message-out phase"	},
-	{ P_STATUS,	MSG_INITIATOR_DET_ERR,	"in Status phase"	},
-	{ P_MESGIN,	MSG_PARITY_ERROR,	"in Message-in phase"	},
-	{ P_BUSFREE,	MSG_NOOP,		"while idle"		},
-	{ 0,		MSG_NOOP,		"in unknown phase"	}
-};
-
-/*
- * In most cases we only wish to itterate over real phases, so
- * exclude the last element from the count.
- */
-static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1;
-
-/*
- * Valid SCSIRATE values.  (p. 3-17)
- * Provides a mapping of tranfer periods in ns to the proper value to
- * stick in the scsixfer reg.
- */
-static struct ahc_syncrate ahc_syncrates[] =
-{
-      /* ultra2    fast/ultra  period     rate */
-	{ 0x42,      0x000,      9,      "80.0" },
-	{ 0x03,      0x000,     10,      "40.0" },
-	{ 0x04,      0x000,     11,      "33.0" },
-	{ 0x05,      0x100,     12,      "20.0" },
-	{ 0x06,      0x110,     15,      "16.0" },
-	{ 0x07,      0x120,     18,      "13.4" },
-	{ 0x08,      0x000,     25,      "10.0" },
-	{ 0x19,      0x010,     31,      "8.0"  },
-	{ 0x1a,      0x020,     37,      "6.67" },
-	{ 0x1b,      0x030,     43,      "5.7"  },
-	{ 0x1c,      0x040,     50,      "5.0"  },
-	{ 0x00,      0x050,     56,      "4.4"  },
-	{ 0x00,      0x060,     62,      "4.0"  },
-	{ 0x00,      0x070,     68,      "3.6"  },
-	{ 0x00,      0x000,      0,      NULL   }
-};
-
-/* Our Sequencer Program */
-#include "aic7xxx_seq.h"
-
-/**************************** Function Declarations ***************************/
-static void		ahc_force_renegotiation(struct ahc_softc *ahc);
-static struct ahc_tmode_tstate*
-			ahc_alloc_tstate(struct ahc_softc *ahc,
-					 u_int scsi_id, char channel);
-#ifdef AHC_TARGET_MODE
-static void		ahc_free_tstate(struct ahc_softc *ahc,
-					u_int scsi_id, char channel, int force);
-#endif
-static struct ahc_syncrate*
-			ahc_devlimited_syncrate(struct ahc_softc *ahc,
-					        struct ahc_initiator_tinfo *,
-						u_int *period,
-						u_int *ppr_options,
-						role_t role);
-static void		ahc_update_pending_scbs(struct ahc_softc *ahc);
-static void		ahc_fetch_devinfo(struct ahc_softc *ahc,
-					  struct ahc_devinfo *devinfo);
-static void		ahc_scb_devinfo(struct ahc_softc *ahc,
-					struct ahc_devinfo *devinfo,
-					struct scb *scb);
-static void		ahc_assert_atn(struct ahc_softc *ahc);
-static void		ahc_setup_initiator_msgout(struct ahc_softc *ahc,
-						   struct ahc_devinfo *devinfo,
-						   struct scb *scb);
-static void		ahc_build_transfer_msg(struct ahc_softc *ahc,
-					       struct ahc_devinfo *devinfo);
-static void		ahc_construct_sdtr(struct ahc_softc *ahc,
-					   struct ahc_devinfo *devinfo,
-					   u_int period, u_int offset);
-static void		ahc_construct_wdtr(struct ahc_softc *ahc,
-					   struct ahc_devinfo *devinfo,
-					   u_int bus_width);
-static void		ahc_construct_ppr(struct ahc_softc *ahc,
-					  struct ahc_devinfo *devinfo,
-					  u_int period, u_int offset,
-					  u_int bus_width, u_int ppr_options);
-static void		ahc_clear_msg_state(struct ahc_softc *ahc);
-static void		ahc_handle_message_phase(struct ahc_softc *ahc);
-typedef enum {
-	AHCMSG_1B,
-	AHCMSG_2B,
-	AHCMSG_EXT
-} ahc_msgtype;
-static int		ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type,
-				     u_int msgval, int full);
-static int		ahc_parse_msg(struct ahc_softc *ahc,
-				      struct ahc_devinfo *devinfo);
-static int		ahc_handle_msg_reject(struct ahc_softc *ahc,
-					      struct ahc_devinfo *devinfo);
-static void		ahc_handle_ign_wide_residue(struct ahc_softc *ahc,
-						struct ahc_devinfo *devinfo);
-static void		ahc_reinitialize_dataptrs(struct ahc_softc *ahc);
-static void		ahc_handle_devreset(struct ahc_softc *ahc,
-					    struct ahc_devinfo *devinfo,
-					    cam_status status, char *message,
-					    int verbose_level);
-#if AHC_TARGET_MODE
-static void		ahc_setup_target_msgin(struct ahc_softc *ahc,
-					       struct ahc_devinfo *devinfo,
-					       struct scb *scb);
-#endif
-
-static bus_dmamap_callback_t	ahc_dmamap_cb; 
-static void			ahc_build_free_scb_list(struct ahc_softc *ahc);
-static int			ahc_init_scbdata(struct ahc_softc *ahc);
-static void			ahc_fini_scbdata(struct ahc_softc *ahc);
-static void		ahc_qinfifo_requeue(struct ahc_softc *ahc,
-					    struct scb *prev_scb,
-					    struct scb *scb);
-static int		ahc_qinfifo_count(struct ahc_softc *ahc);
-static u_int		ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,
-						   u_int prev, u_int scbptr);
-static void		ahc_add_curscb_to_free_list(struct ahc_softc *ahc);
-static u_int		ahc_rem_wscb(struct ahc_softc *ahc,
-				     u_int scbpos, u_int prev);
-static void		ahc_reset_current_bus(struct ahc_softc *ahc);
-#ifdef AHC_DUMP_SEQ
-static void		ahc_dumpseq(struct ahc_softc *ahc);
-#endif
-static void		ahc_loadseq(struct ahc_softc *ahc);
-static int		ahc_check_patch(struct ahc_softc *ahc,
-					struct patch **start_patch,
-					u_int start_instr, u_int *skip_addr);
-static void		ahc_download_instr(struct ahc_softc *ahc,
-					   u_int instrptr, uint8_t *dconsts);
-#ifdef AHC_TARGET_MODE
-static void		ahc_queue_lstate_event(struct ahc_softc *ahc,
-					       struct ahc_tmode_lstate *lstate,
-					       u_int initiator_id,
-					       u_int event_type,
-					       u_int event_arg);
-static void		ahc_update_scsiid(struct ahc_softc *ahc,
-					  u_int targid_mask);
-static int		ahc_handle_target_cmd(struct ahc_softc *ahc,
-					      struct target_cmd *cmd);
-#endif
-/************************* Sequencer Execution Control ************************/
-/*
- * Restart the sequencer program from address zero
- */
-void
-ahc_restart(struct ahc_softc *ahc)
-{
-
-	ahc_pause(ahc);
-
-	ahc_outb(ahc, SCSISIGO, 0);		/* De-assert BSY */
-	ahc_outb(ahc, MSG_OUT, MSG_NOOP);	/* No message to send */
-	ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
-	ahc_outb(ahc, LASTPHASE, P_BUSFREE);
-
-	/*
-	 * Ensure that the sequencer's idea of TQINPOS
-	 * matches our own.  The sequencer increments TQINPOS
-	 * only after it sees a DMA complete and a reset could
-	 * occur before the increment leaving the kernel to believe
-	 * the command arrived but the sequencer to not.
-	 */
-	ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
-
-	/* Always allow reselection */
-	ahc_outb(ahc, SCSISEQ,
-		 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
-	if ((ahc->features & AHC_CMD_CHAN) != 0) {
-		/* Ensure that no DMA operations are in progress */
-		ahc_outb(ahc, CCSCBCNT, 0);
-		ahc_outb(ahc, CCSGCTL, 0);
-		ahc_outb(ahc, CCSCBCTL, 0);
-	}
-	/*
-	 * If we were in the process of DMA'ing SCB data into
-	 * an SCB, replace that SCB on the free list.  This prevents
-	 * an SCB leak.
-	 */
-	if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {
-		ahc_add_curscb_to_free_list(ahc);
-		ahc_outb(ahc, SEQ_FLAGS2,
-			 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
-	}
-	ahc_outb(ahc, MWI_RESIDUAL, 0);
-	ahc_outb(ahc, SEQCTL, FASTMODE);
-	ahc_outb(ahc, SEQADDR0, 0);
-	ahc_outb(ahc, SEQADDR1, 0);
-	ahc_unpause(ahc);
-}
-
-/************************* Input/Output Queues ********************************/
-void
-ahc_run_qoutfifo(struct ahc_softc *ahc)
-{
-	struct scb *scb;
-	u_int  scb_index;
-
-	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
-	while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {
-
-		scb_index = ahc->qoutfifo[ahc->qoutfifonext];
-		if ((ahc->qoutfifonext & 0x03) == 0x03) {
-			u_int modnext;
-
-			/*
-			 * Clear 32bits of QOUTFIFO at a time
-			 * so that we don't clobber an incoming
-			 * byte DMA to the array on architectures
-			 * that only support 32bit load and store
-			 * operations.
-			 */
-			modnext = ahc->qoutfifonext & ~0x3;
-			*((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;
-			ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
-					ahc->shared_data_dmamap,
-					/*offset*/modnext, /*len*/4,
-					BUS_DMASYNC_PREREAD);
-		}
-		ahc->qoutfifonext++;
-
-		scb = ahc_lookup_scb(ahc, scb_index);
-		if (scb == NULL) {
-			printf("%s: WARNING no command for scb %d "
-			       "(cmdcmplt)\nQOUTPOS = %d\n",
-			       ahc_name(ahc), scb_index,
-			       ahc->qoutfifonext - 1);
-			continue;
-		}
-
-		/*
-		 * Save off the residual
-		 * if there is one.
-		 */
-		ahc_update_residual(scb);
-		ahc_done(ahc, scb);
-	}
-}
-
-void
-ahc_run_untagged_queues(struct ahc_softc *ahc)
-{
-	int i;
-
-	for (i = 0; i < 16; i++)
-		ahc_run_untagged_queue(ahc, &ahc->untagged_queues[i]);
-}
-
-void
-ahc_run_untagged_queue(struct ahc_softc *ahc, struct scb_tailq *queue)
-{
-	struct scb *scb;
-
-	if (ahc->untagged_queue_lock != 0)
-		return;
-
-	if ((scb = TAILQ_FIRST(queue)) != NULL
-	 && (scb->flags & SCB_ACTIVE) == 0) {
-		scb->flags |= SCB_ACTIVE;
-		ahc_queue_scb(ahc, scb);
-	}
-}
-
-/************************* Interrupt Handling *********************************/
-void
-ahc_handle_brkadrint(struct ahc_softc *ahc)
-{
-	/*
-	 * We upset the sequencer :-(
-	 * Lookup the error message
-	 */
-	int i;
-	int error;
-
-	error = ahc_inb(ahc, ERROR);
-	for (i = 0; error != 1 && i < num_errors; i++)
-		error >>= 1;
-	printf("%s: brkadrint, %s at seqaddr = 0x%x\n",
-	       ahc_name(ahc), ahc_hard_errors[i].errmesg,
-	       ahc_inb(ahc, SEQADDR0) |
-	       (ahc_inb(ahc, SEQADDR1) << 8));
-
-	ahc_dump_card_state(ahc);
-
-	/* Tell everyone that this HBA is no longer availible */
-	ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
-		       CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
-		       CAM_NO_HBA);
-
-	/* Disable all interrupt sources by resetting the controller */
-	ahc_shutdown(ahc);
-}
-
-void
-ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
-{
-	struct scb *scb;
-	struct ahc_devinfo devinfo;
-	
-	ahc_fetch_devinfo(ahc, &devinfo);
-
-	/*
-	 * Clear the upper byte that holds SEQINT status
-	 * codes and clear the SEQINT bit. We will unpause
-	 * the sequencer, if appropriate, after servicing
-	 * the request.
-	 */
-	ahc_outb(ahc, CLRINT, CLRSEQINT);
-	switch (intstat & SEQINT_MASK) {
-	case BAD_STATUS:
-	{
-		u_int  scb_index;
-		struct hardware_scb *hscb;
-
-		/*
-		 * Set the default return value to 0 (don't
-		 * send sense).  The sense code will change
-		 * this if needed.
-		 */
-		ahc_outb(ahc, RETURN_1, 0);
-
-		/*
-		 * The sequencer will notify us when a command
-		 * has an error that would be of interest to
-		 * the kernel.  This allows us to leave the sequencer
-		 * running in the common case of command completes
-		 * without error.  The sequencer will already have
-		 * dma'd the SCB back up to us, so we can reference
-		 * the in kernel copy directly.
-		 */
-		scb_index = ahc_inb(ahc, SCB_TAG);
-		scb = ahc_lookup_scb(ahc, scb_index);
-		if (scb == NULL) {
-			printf("%s:%c:%d: ahc_intr - referenced scb "
-			       "not valid during seqint 0x%x scb(%d)\n",
-			       ahc_name(ahc), devinfo.channel,
-			       devinfo.target, intstat, scb_index);
-			ahc_dump_card_state(ahc);
-			panic("for safety");
-			goto unpause;
-		}
-
-		hscb = scb->hscb; 
-
-		/* Don't want to clobber the original sense code */
-		if ((scb->flags & SCB_SENSE) != 0) {
-			/*
-			 * Clear the SCB_SENSE Flag and have
-			 * the sequencer do a normal command
-			 * complete.
-			 */
-			scb->flags &= ~SCB_SENSE;
-			ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
-			break;
-		}
-		ahc_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
-		/* Freeze the queue until the client sees the error. */
-		ahc_freeze_devq(ahc, scb);
-		ahc_freeze_scb(scb);
-		ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
-		switch (hscb->shared_data.status.scsi_status) {
-		case SCSI_STATUS_OK:
-			printf("%s: Interrupted for staus of 0???\n",
-			       ahc_name(ahc));
-			break;
-		case SCSI_STATUS_CMD_TERMINATED:
-		case SCSI_STATUS_CHECK_COND:
-		{
-			struct ahc_dma_seg *sg;
-			struct scsi_sense *sc;
-			struct ahc_initiator_tinfo *targ_info;
-			struct ahc_tmode_tstate *tstate;
-			struct ahc_transinfo *tinfo;
-#ifdef AHC_DEBUG
-			if (ahc_debug & AHC_SHOWSENSE) {
-				ahc_print_path(ahc, scb);
-				printf("SCB %d: requests Check Status\n",
-				       scb->hscb->tag);
-			}
-#endif
-
-			if (ahc_perform_autosense(scb) == 0)
-				break;
-
-			targ_info = ahc_fetch_transinfo(ahc,
-							devinfo.channel,
-							devinfo.our_scsiid,
-							devinfo.target,
-							&tstate);
-			tinfo = &targ_info->curr;
-			sg = scb->sg_list;
-			sc = (struct scsi_sense *)(&hscb->shared_data.cdb); 
-			/*
-			 * Save off the residual if there is one.
-			 */
-			ahc_update_residual(scb);
-#ifdef AHC_DEBUG
-			if (ahc_debug & AHC_SHOWSENSE) {
-				ahc_print_path(ahc, scb);
-				printf("Sending Sense\n");
-			}
-#endif
-			sg->addr = ahc_get_sense_bufaddr(ahc, scb);
-			sg->len = ahc_get_sense_bufsize(ahc, scb);
-			sg->len |= AHC_DMA_LAST_SEG;
-
-			/* Fixup byte order */
-			sg->addr = ahc_htole32(sg->addr);
-			sg->len = ahc_htole32(sg->len);
-
-			sc->opcode = REQUEST_SENSE;
-			sc->byte2 = 0;
-			if (tinfo->protocol_version <= SCSI_REV_2
-			 && SCB_GET_LUN(scb) < 8)
-				sc->byte2 = SCB_GET_LUN(scb) << 5;
-			sc->unused[0] = 0;
-			sc->unused[1] = 0;
-			sc->length = sg->len;
-			sc->control = 0;
-
-			/*
-			 * We can't allow the target to disconnect.
-			 * This will be an untagged transaction and
-			 * having the target disconnect will make this
-			 * transaction indestinguishable from outstanding
-			 * tagged transactions.
-			 */
-			hscb->control = 0;
-
-			/*
-			 * This request sense could be because the
-			 * the device lost power or in some other
-			 * way has lost our transfer negotiations.
-			 * Renegotiate if appropriate.  Unit attention
-			 * errors will be reported before any data
-			 * phases occur.
-			 */
-			if (ahc_get_residual(scb) 
-			 == ahc_get_transfer_length(scb)) {
-				ahc_update_neg_request(ahc, &devinfo,
-						       tstate, targ_info,
-						       /*force*/TRUE);
-			}
-			if (tstate->auto_negotiate & devinfo.target_mask) {
-				hscb->control |= MK_MESSAGE;
-				scb->flags &= ~SCB_NEGOTIATE;
-				scb->flags |= SCB_AUTO_NEGOTIATE;
-			}
-			hscb->cdb_len = sizeof(*sc);
-			hscb->dataptr = sg->addr; 
-			hscb->datacnt = sg->len;
-			hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;
-			hscb->sgptr = ahc_htole32(hscb->sgptr);
-			scb->sg_count = 1;
-			scb->flags |= SCB_SENSE;
-			ahc_qinfifo_requeue_tail(ahc, scb);
-			ahc_outb(ahc, RETURN_1, SEND_SENSE);
-#ifdef __FreeBSD__
-			/*
-			 * Ensure we have enough time to actually
-			 * retrieve the sense.
-			 */
-			untimeout(ahc_timeout, (caddr_t)scb,
-				  scb->io_ctx->ccb_h.timeout_ch);
-			scb->io_ctx->ccb_h.timeout_ch =
-			    timeout(ahc_timeout, (caddr_t)scb, 5 * hz);
-#endif
-			break;
-		}
-		default:
-			break;
-		}
-		break;
-	}
-	case NO_MATCH:
-	{
-		/* Ensure we don't leave the selection hardware on */
-		ahc_outb(ahc, SCSISEQ,
-			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
-
-		printf("%s:%c:%d: no active SCB for reconnecting "
-		       "target - issuing BUS DEVICE RESET\n",
-		       ahc_name(ahc), devinfo.channel, devinfo.target);
-		printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
-		       "ARG_1 == 0x%x ACCUM = 0x%x\n",
-		       ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
-		       ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
-		printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
-		       "SINDEX == 0x%x\n",
-		       ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
-		       ahc_index_busy_tcl(ahc,
-			    BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
-				      ahc_inb(ahc, SAVED_LUN))),
-		       ahc_inb(ahc, SINDEX));
-		printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
-		       "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
-		       ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
-		       ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
-		       ahc_inb(ahc, SCB_CONTROL));
-		printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
-		       ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
-		printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
-		printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
-		ahc_dump_card_state(ahc);
-		ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
-		ahc->msgout_len = 1;
-		ahc->msgout_index = 0;
-		ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
-		ahc_outb(ahc, MSG_OUT, HOST_MSG);
-		ahc_assert_atn(ahc);
-		break;
-	}
-	case SEND_REJECT: 
-	{
-		u_int rejbyte = ahc_inb(ahc, ACCUM);
-		printf("%s:%c:%d: Warning - unknown message received from "
-		       "target (0x%x).  Rejecting\n", 
-		       ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
-		break; 
-	}
-	case NO_IDENT: 
-	{
-		/*
-		 * The reconnecting target either did not send an identify
-		 * message, or did, but we didn't find an SCB to match and
-		 * before it could respond to our ATN/abort, it hit a dataphase.
-		 * The only safe thing to do is to blow it away with a bus
-		 * reset.
-		 */
-		int found;
-
-		printf("%s:%c:%d: Target did not send an IDENTIFY message. "
-		       "LASTPHASE = 0x%x, SAVED_SCSIID == 0x%x\n",
-		       ahc_name(ahc), devinfo.channel, devinfo.target,
-		       ahc_inb(ahc, LASTPHASE), ahc_inb(ahc, SAVED_SCSIID));
-		found = ahc_reset_channel(ahc, devinfo.channel, 
-					  /*initiate reset*/TRUE);
-		printf("%s: Issued Channel %c Bus Reset. "
-		       "%d SCBs aborted\n", ahc_name(ahc), devinfo.channel,
-		       found);
-		return;
-	}
-	case IGN_WIDE_RES:
-		ahc_handle_ign_wide_residue(ahc, &devinfo);
-		break;
-	case PDATA_REINIT:
-		ahc_reinitialize_dataptrs(ahc);
-		break;
-	case BAD_PHASE:
-	{
-		u_int lastphase;
-
-		lastphase = ahc_inb(ahc, LASTPHASE);
-		printf("%s:%c:%d: unknown scsi bus phase %x, "
-		       "lastphase = 0x%x.  Attempting to continue\n",
-		       ahc_name(ahc), devinfo.channel, devinfo.target,
-		       lastphase, ahc_inb(ahc, SCSISIGI));
-		break;
-	}
-	case MISSED_BUSFREE:
-	{
-		u_int lastphase;
-
-		lastphase = ahc_inb(ahc, LASTPHASE);
-		printf("%s:%c:%d: Missed busfree. "
-		       "Lastphase = 0x%x, Curphase = 0x%x\n",
-		       ahc_name(ahc), devinfo.channel, devinfo.target,
-		       lastphase, ahc_inb(ahc, SCSISIGI));
-		ahc_restart(ahc);
-		return;
-	}
-	case HOST_MSG_LOOP:
-	{
-		/*
-		 * The sequencer has encountered a message phase
-		 * that requires host assistance for completion.
-		 * While handling the message phase(s), we will be
-		 * notified by the sequencer after each byte is
-		 * transfered so we can track bus phase changes.
-		 *
-		 * If this is the first time we've seen a HOST_MSG_LOOP
-		 * interrupt, initialize the state of the host message
-		 * loop.
-		 */
-		if (ahc->msg_type == MSG_TYPE_NONE) {
-			struct scb *scb;
-			u_int scb_index;
-			u_int bus_phase;
-
-			bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
-			if (bus_phase != P_MESGIN
-			 && bus_phase != P_MESGOUT) {
-				printf("ahc_intr: HOST_MSG_LOOP bad "
-				       "phase 0x%x\n",
-				      bus_phase);
-				/*
-				 * Probably transitioned to bus free before
-				 * we got here.  Just punt the message.
-				 */
-				ahc_clear_intstat(ahc);
-				ahc_restart(ahc);
-				return;
-			}
-
-			scb_index = ahc_inb(ahc, SCB_TAG);
-			scb = ahc_lookup_scb(ahc, scb_index);
-			if (devinfo.role == ROLE_INITIATOR) {
-				if (scb == NULL)
-					panic("HOST_MSG_LOOP with "
-					      "invalid SCB %x\n", scb_index);
-
-				if (bus_phase == P_MESGOUT)
-					ahc_setup_initiator_msgout(ahc,
-								   &devinfo,
-								   scb);
-				else {
-					ahc->msg_type =
-					    MSG_TYPE_INITIATOR_MSGIN;
-					ahc->msgin_index = 0;
-				}
-			}
-#if AHC_TARGET_MODE
-			else {
-				if (bus_phase == P_MESGOUT) {
-					ahc->msg_type =
-					    MSG_TYPE_TARGET_MSGOUT;
-					ahc->msgin_index = 0;
-				}
-				else 
-					ahc_setup_target_msgin(ahc,
-							       &devinfo,
-							       scb);
-			}
-#endif
-		}
-
-		ahc_handle_message_phase(ahc);
-		break;
-	}
-	case PERR_DETECTED:
-	{
-		/*
-		 * If we've cleared the parity error interrupt
-		 * but the sequencer still believes that SCSIPERR
-		 * is true, it must be that the parity error is
-		 * for the currently presented byte on the bus,
-		 * and we are not in a phase (data-in) where we will
-		 * eventually ack this byte.  Ack the byte and
-		 * throw it away in the hope that the target will
-		 * take us to message out to deliver the appropriate
-		 * error message.
-		 */
-		if ((intstat & SCSIINT) == 0
-		 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {
-
-			if ((ahc->features & AHC_DT) == 0) {
-				u_int curphase;
-
-				/*
-				 * The hardware will only let you ack bytes
-				 * if the expected phase in SCSISIGO matches
-				 * the current phase.  Make sure this is
-				 * currently the case.
-				 */
-				curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
-				ahc_outb(ahc, LASTPHASE, curphase);
-				ahc_outb(ahc, SCSISIGO, curphase);
-			}
-			ahc_inb(ahc, SCSIDATL);
-		}
-		break;
-	}
-	case DATA_OVERRUN:
-	{
-		/*
-		 * When the sequencer detects an overrun, it
-		 * places the controller in "BITBUCKET" mode
-		 * and allows the target to complete its transfer.
-		 * Unfortunately, none of the counters get updated
-		 * when the controller is in this mode, so we have
-		 * no way of knowing how large the overrun was.
-		 */
-		u_int scbindex = ahc_inb(ahc, SCB_TAG);
-		u_int lastphase = ahc_inb(ahc, LASTPHASE);
-		u_int i;
-
-		scb = ahc_lookup_scb(ahc, scbindex);
-		for (i = 0; i < num_phases; i++) {
-			if (lastphase == ahc_phase_table[i].phase)
-				break;
-		}
-		ahc_print_path(ahc, scb);
-		printf("data overrun detected %s."
-		       "  Tag == 0x%x.\n",
-		       ahc_phase_table[i].phasemsg,
-  		       scb->hscb->tag);
-		ahc_print_path(ahc, scb);
-		printf("%s seen Data Phase.  Length = %ld.  NumSGs = %d.\n",
-		       ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
-		       ahc_get_transfer_length(scb), scb->sg_count);
-		if (scb->sg_count > 0) {
-			for (i = 0; i < scb->sg_count; i++) {
-
-				printf("sg[%d] - Addr 0x%x%x : Length %d\n",
-				       i,
-				       (ahc_le32toh(scb->sg_list[i].len) >> 24
-				        & SG_HIGH_ADDR_BITS),
-				       ahc_le32toh(scb->sg_list[i].addr),
-				       ahc_le32toh(scb->sg_list[i].len)
-				       & AHC_SG_LEN_MASK);
-			}
-		}
-		/*
-		 * Set this and it will take effect when the
-		 * target does a command complete.
-		 */
-		ahc_freeze_devq(ahc, scb);
-		ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
-		ahc_freeze_scb(scb);
-
-		if ((ahc->features & AHC_ULTRA2) != 0) {
-			/*
-			 * Clear the channel in case we return
-			 * to data phase later.
-			 */
-			ahc_outb(ahc, SXFRCTL0,
-				 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
-			ahc_outb(ahc, SXFRCTL0,
-				 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
-		}
-		if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
-			u_int dscommand1;
-
-			/* Ensure HHADDR is 0 for future DMA operations. */
-			dscommand1 = ahc_inb(ahc, DSCOMMAND1);
-			ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
-			ahc_outb(ahc, HADDR, 0);
-			ahc_outb(ahc, DSCOMMAND1, dscommand1);
-		}
-		break;
-	}
-	case MKMSG_FAILED:
-	{
-		u_int scbindex;
-
-		printf("%s:%c:%d:%d: Attempt to issue message failed\n",
-		       ahc_name(ahc), devinfo.channel, devinfo.target,
-		       devinfo.lun);
-		scbindex = ahc_inb(ahc, SCB_TAG);
-		scb = ahc_lookup_scb(ahc, scbindex);
-		if (scb != NULL
-		 && (scb->flags & SCB_RECOVERY_SCB) != 0)
-			/*
-			 * Ensure that we didn't put a second instance of this
-			 * SCB into the QINFIFO.
-			 */
-			ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
-					   SCB_GET_CHANNEL(ahc, scb),
-					   SCB_GET_LUN(scb), scb->hscb->tag,
-					   ROLE_INITIATOR, /*status*/0,
-					   SEARCH_REMOVE);
-		break;
-	}
-	case NO_FREE_SCB:
-	{
-		printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
-		ahc_dump_card_state(ahc);
-		panic("for safety");
-		break;
-	}
-	case SCB_MISMATCH:
-	{
-		u_int scbptr;
-
-		scbptr = ahc_inb(ahc, SCBPTR);
-		printf("Bogus TAG after DMA.  SCBPTR %d, tag %d, our tag %d\n",
-		       scbptr, ahc_inb(ahc, ARG_1),
-		       ahc->scb_data->hscbs[scbptr].tag);
-		ahc_dump_card_state(ahc);
-		panic("for saftey");
-		break;
-	}
-	case OUT_OF_RANGE:
-	{
-		printf("%s: BTT calculation out of range\n", ahc_name(ahc));
-		printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
-		       "ARG_1 == 0x%x ACCUM = 0x%x\n",
-		       ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
-		       ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
-		printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
-		       "SINDEX == 0x%x\n, A == 0x%x\n",
-		       ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
-		       ahc_index_busy_tcl(ahc,
-			    BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
-				      ahc_inb(ahc, SAVED_LUN))),
-		       ahc_inb(ahc, SINDEX),
-		       ahc_inb(ahc, ACCUM));
-		printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
-		       "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
-		       ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
-		       ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
-		       ahc_inb(ahc, SCB_CONTROL));
-		printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
-		       ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
-		ahc_dump_card_state(ahc);
-		panic("for safety");
-		break;
-	}
-	default:
-		printf("ahc_intr: seqint, "
-		       "intstat == 0x%x, scsisigi = 0x%x\n",
-		       intstat, ahc_inb(ahc, SCSISIGI));
-		break;
-	}
-unpause:
-	/*
-	 *  The sequencer is paused immediately on
-	 *  a SEQINT, so we should restart it when
-	 *  we're done.
-	 */
-	ahc_unpause(ahc);
-}
-
-void
-ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
-{
-	u_int	scb_index;
-	u_int	status0;
-	u_int	status;
-	struct	scb *scb;
-	char	cur_channel;
-	char	intr_channel;
-
-	/* Make sure the sequencer is in a safe location. */
-	ahc_clear_critical_section(ahc);
-
-	if ((ahc->features & AHC_TWIN) != 0
-	 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))
-		cur_channel = 'B';
-	else
-		cur_channel = 'A';
-	intr_channel = cur_channel;
-
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		status0 = ahc_inb(ahc, SSTAT0) & IOERR;
-	else
-		status0 = 0;
-	status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
-	if (status == 0 && status0 == 0) {
-		if ((ahc->features & AHC_TWIN) != 0) {
-			/* Try the other channel */
-		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
-			status = ahc_inb(ahc, SSTAT1)
-			       & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
-			intr_channel = (cur_channel == 'A') ? 'B' : 'A';
-		}
-		if (status == 0) {
-			printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
-			ahc_outb(ahc, CLRINT, CLRSCSIINT);
-			ahc_unpause(ahc);
-			return;
-		}
-	}
-
-	scb_index = ahc_inb(ahc, SCB_TAG);
-	scb = ahc_lookup_scb(ahc, scb_index);
-	if (scb != NULL
-	 && (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) == 0)
-		scb = NULL;
-
-	if ((ahc->features & AHC_ULTRA2) != 0
-	 && (status0 & IOERR) != 0) {
-		int now_lvd;
-
-		now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
-		printf("%s: Transceiver State Has Changed to %s mode\n",
-		       ahc_name(ahc), now_lvd ? "LVD" : "SE");
-		ahc_outb(ahc, CLRSINT0, CLRIOERR);
-		/*
-		 * When transitioning to SE mode, the reset line
-		 * glitches, triggering an arbitration bug in some
-		 * Ultra2 controllers.  This bug is cleared when we
-		 * assert the reset line.  Since a reset glitch has
-		 * already occurred with this transition and a
-		 * transceiver state change is handled just like
-		 * a bus reset anyway, asserting the reset line
-		 * ourselves is safe.
-		 */
-		ahc_reset_channel(ahc, intr_channel,
-				 /*Initiate Reset*/now_lvd == 0);
-	} else if ((status & SCSIRSTI) != 0) {
-		printf("%s: Someone reset channel %c\n",
-			ahc_name(ahc), intr_channel);
-		if (intr_channel != cur_channel)
-		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
-		ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE);
-	} else if ((status & SCSIPERR) != 0) {
-		/*
-		 * Determine the bus phase and queue an appropriate message.
-		 * SCSIPERR is latched true as soon as a parity error
-		 * occurs.  If the sequencer acked the transfer that
-		 * caused the parity error and the currently presented
-		 * transfer on the bus has correct parity, SCSIPERR will
-		 * be cleared by CLRSCSIPERR.  Use this to determine if
-		 * we should look at the last phase the sequencer recorded,
-		 * or the current phase presented on the bus.
-		 */
-		u_int mesg_out;
-		u_int curphase;
-		u_int errorphase;
-		u_int lastphase;
-		u_int scsirate;
-		u_int i;
-		u_int sstat2;
-
-		lastphase = ahc_inb(ahc, LASTPHASE);
-		curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
-		sstat2 = ahc_inb(ahc, SSTAT2);
-		ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
-		/*
-		 * For all phases save DATA, the sequencer won't
-		 * automatically ack a byte that has a parity error
-		 * in it.  So the only way that the current phase
-		 * could be 'data-in' is if the parity error is for
-		 * an already acked byte in the data phase.  During
-		 * synchronous data-in transfers, we may actually
-		 * ack bytes before latching the current phase in
-		 * LASTPHASE, leading to the discrepancy between
-		 * curphase and lastphase.
-		 */
-		if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0
-		 || curphase == P_DATAIN || curphase == P_DATAIN_DT)
-			errorphase = curphase;
-		else
-			errorphase = lastphase;
-
-		for (i = 0; i < num_phases; i++) {
-			if (errorphase == ahc_phase_table[i].phase)
-				break;
-		}
-		mesg_out = ahc_phase_table[i].mesg_out;
-		if (scb != NULL)
-			ahc_print_path(ahc, scb);
-		else
-			printf("%s:%c:%d: ", ahc_name(ahc), intr_channel,
-			       SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));
-		scsirate = ahc_inb(ahc, SCSIRATE);
-		printf("parity error detected %s. "
-		       "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
-		       ahc_phase_table[i].phasemsg,
-		       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8),
-		       scsirate);
-
-		if ((ahc->features & AHC_DT) != 0) {
-
-			if ((sstat2 & CRCVALERR) != 0)
-				printf("\tCRC Value Mismatch\n");
-			if ((sstat2 & CRCENDERR) != 0)
-				printf("\tNo terminal CRC packet recevied\n");
-			if ((sstat2 & CRCREQERR) != 0)
-				printf("\tIllegal CRC packet request\n");
-			if ((sstat2 & DUAL_EDGE_ERR) != 0)
-				printf("\tUnexpected %sDT Data Phase\n",
-				       (scsirate & SINGLE_EDGE) ? "" : "non-");
-		}
-
-		/*
-		 * We've set the hardware to assert ATN if we   
-		 * get a parity error on "in" phases, so all we  
-		 * need to do is stuff the message buffer with
-		 * the appropriate message.  "In" phases have set
-		 * mesg_out to something other than MSG_NOP.
-		 */
-		if (mesg_out != MSG_NOOP) {
-			if (ahc->msg_type != MSG_TYPE_NONE)
-				ahc->send_msg_perror = TRUE;
-			else
-				ahc_outb(ahc, MSG_OUT, mesg_out);
-		}
-		/*
-		 * Force a renegotiation with this target just in
-		 * case we are out of sync for some external reason
-		 * unknown (or unreported) by the target.
-		 */
-		ahc_force_renegotiation(ahc);
-		ahc_outb(ahc, CLRINT, CLRSCSIINT);
-		ahc_unpause(ahc);
-	} else if ((status & SELTO) != 0) {
-		u_int	scbptr;
-
-		/* Stop the selection */
-		ahc_outb(ahc, SCSISEQ, 0);
-
-		/* No more pending messages */
-		ahc_clear_msg_state(ahc);
-
-		/* Clear interrupt state */
-		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
-		ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
-
-		/*
-		 * Although the driver does not care about the
-		 * 'Selection in Progress' status bit, the busy
-		 * LED does.  SELINGO is only cleared by a sucessfull
-		 * selection, so we must manually clear it to insure
-		 * the LED turns off just incase no future successful
-		 * selections occur (e.g. no devices on the bus).
-		 */
-		ahc_outb(ahc, CLRSINT0, CLRSELINGO);
-
-		scbptr = ahc_inb(ahc, WAITING_SCBH);
-		ahc_outb(ahc, SCBPTR, scbptr);
-		scb_index = ahc_inb(ahc, SCB_TAG);
-
-		scb = ahc_lookup_scb(ahc, scb_index);
-		if (scb == NULL) {
-			printf("%s: ahc_intr - referenced scb not "
-			       "valid during SELTO scb(%d, %d)\n",
-			       ahc_name(ahc), scbptr, scb_index);
-		} else {
-			ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
-			ahc_freeze_devq(ahc, scb);
-		}
-		ahc_outb(ahc, CLRINT, CLRSCSIINT);
-		/*
-		 * Force a renegotiation with this target just in
-		 * case the cable was pulled and will later be
-		 * re-attached.  The target may forget its negotiation
-		 * settings with us should it attempt to reselect
-		 * during the interruption.  The target will not issue
-		 * a unit attention in this case, so we must always
-		 * renegotiate.
-		 */
-		ahc_force_renegotiation(ahc);
-		ahc_restart(ahc);
-	} else if ((status & BUSFREE) != 0
-		&& (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
-		u_int lastphase;
-		u_int saved_scsiid;
-		u_int saved_lun;
-		u_int target;
-		u_int initiator_role_id;
-		char channel;
-		int printerror;
-
-		/*
-		 * Clear our selection hardware as soon as possible.
-		 * We may have an entry in the waiting Q for this target,
-		 * that is affected by this busfree and we don't want to
-		 * go about selecting the target while we handle the event.
-		 */
-		ahc_outb(ahc, SCSISEQ,
-			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
-
-		/*
-		 * Disable busfree interrupts and clear the busfree
-		 * interrupt status.  We do this here so that several
-		 * bus transactions occur prior to clearing the SCSIINT
-		 * latch.  It can take a bit for the clearing to take effect.
-		 */
-		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
-		ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
-
-		/*
-		 * Look at what phase we were last in.
-		 * If its message out, chances are pretty good
-		 * that the busfree was in response to one of
-		 * our abort requests.
-		 */
-		lastphase = ahc_inb(ahc, LASTPHASE);
-		saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
-		saved_lun = ahc_inb(ahc, SAVED_LUN);
-		target = SCSIID_TARGET(ahc, saved_scsiid);
-		initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
-		channel = SCSIID_CHANNEL(ahc, saved_scsiid);
-		printerror = 1;
-
-		if (lastphase == P_MESGOUT) {
-			struct ahc_devinfo devinfo;
-			u_int tag;
-
-			ahc_fetch_devinfo(ahc, &devinfo);
-			tag = SCB_LIST_NULL;
-			if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)
-			 || ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {
-				if (ahc->msgout_buf[ahc->msgout_index - 1]
-				 == MSG_ABORT_TAG)
-					tag = scb->hscb->tag;
-				ahc_print_path(ahc, scb);
-				printf("SCB %d - Abort%s Completed.\n",
-				       scb->hscb->tag, tag == SCB_LIST_NULL ?
-				       "" : " Tag");
-				ahc_abort_scbs(ahc, target, channel,
-					       saved_lun, tag,
-					       ROLE_INITIATOR,
-					       CAM_REQ_ABORTED);
-				printerror = 0;
-			} else if (ahc_sent_msg(ahc, AHCMSG_1B,
-						MSG_BUS_DEV_RESET, TRUE)) {
-#ifdef __FreeBSD__
-				/*
-				 * Don't mark the user's request for this BDR
-				 * as completing with CAM_BDR_SENT.  CAM3
-				 * specifies CAM_REQ_CMP.
-				 */
-				if (scb != NULL
-				 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
-				 && ahc_match_scb(ahc, scb, target, channel,
-						  CAM_LUN_WILDCARD,
-						  SCB_LIST_NULL,
-						  ROLE_INITIATOR)) {
-					ahc_set_transaction_status(scb, CAM_REQ_CMP);
-				}
-#endif
-				ahc_compile_devinfo(&devinfo,
-						    initiator_role_id,
-						    target,
-						    CAM_LUN_WILDCARD,
-						    channel,
-						    ROLE_INITIATOR);
-				ahc_handle_devreset(ahc, &devinfo,
-						    CAM_BDR_SENT,
-						    "Bus Device Reset",
-						    /*verbose_level*/0);
-				printerror = 0;
-			} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
-						MSG_EXT_PPR, FALSE)) {
-				struct ahc_initiator_tinfo *tinfo;
-				struct ahc_tmode_tstate *tstate;
-
-				/*
-				 * PPR Rejected.  Try non-ppr negotiation
-				 * and retry command.
-				 */
-				tinfo = ahc_fetch_transinfo(ahc,
-							    devinfo.channel,
-							    devinfo.our_scsiid,
-							    devinfo.target,
-							    &tstate);
-				tinfo->curr.transport_version = 2;
-				tinfo->goal.transport_version = 2;
-				tinfo->goal.ppr_options = 0;
-				ahc_qinfifo_requeue_tail(ahc, scb);
-				printerror = 0;
-			} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
-						MSG_EXT_WDTR, FALSE)
-				|| ahc_sent_msg(ahc, AHCMSG_EXT,
-						MSG_EXT_SDTR, FALSE)) {
-				/*
-				 * Negotiation Rejected.  Go-async and
-				 * retry command.
-				 */
-				ahc_set_width(ahc, &devinfo,
-					      MSG_EXT_WDTR_BUS_8_BIT,
-					      AHC_TRANS_CUR|AHC_TRANS_GOAL,
-					      /*paused*/TRUE);
-				ahc_set_syncrate(ahc, &devinfo,
-						/*syncrate*/NULL,
-						/*period*/0, /*offset*/0,
-						/*ppr_options*/0,
-						AHC_TRANS_CUR|AHC_TRANS_GOAL,
-						/*paused*/TRUE);
-				ahc_qinfifo_requeue_tail(ahc, scb);
-				printerror = 0;
-			}
-		}
-		if (printerror != 0) {
-			u_int i;
-
-			if (scb != NULL) {
-				u_int tag;
-
-				if ((scb->hscb->control & TAG_ENB) != 0)
-					tag = scb->hscb->tag;
-				else
-					tag = SCB_LIST_NULL;
-				ahc_print_path(ahc, scb);
-				ahc_abort_scbs(ahc, target, channel,
-					       SCB_GET_LUN(scb), tag,
-					       ROLE_INITIATOR,
-					       CAM_UNEXP_BUSFREE);
-			} else {
-				/*
-				 * We had not fully identified this connection,
-				 * so we cannot abort anything.
-				 */
-				printf("%s: ", ahc_name(ahc));
-			}
-			for (i = 0; i < num_phases; i++) {
-				if (lastphase == ahc_phase_table[i].phase)
-					break;
-			}
-			printf("Unexpected busfree %s\n"
-			       "SEQADDR == 0x%x\n",
-			       ahc_phase_table[i].phasemsg,
-			       ahc_inb(ahc, SEQADDR0)
-				| (ahc_inb(ahc, SEQADDR1) << 8));
-		}
-		ahc_clear_msg_state(ahc);
-		ahc_outb(ahc, CLRINT, CLRSCSIINT);
-		ahc_restart(ahc);
-	} else {
-		printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",
-		       ahc_name(ahc), status);
-		ahc_outb(ahc, CLRINT, CLRSCSIINT);
-	}
-}
-
-/*
- * Force renegotiation to occur the next time we initiate
- * a command to the current device.
- */
-static void
-ahc_force_renegotiation(struct ahc_softc *ahc)
-{
-	struct	ahc_devinfo devinfo;
-	struct	ahc_initiator_tinfo *targ_info;
-	struct	ahc_tmode_tstate *tstate;
-
-	ahc_fetch_devinfo(ahc, &devinfo);
-	targ_info = ahc_fetch_transinfo(ahc,
-					devinfo.channel,
-					devinfo.our_scsiid,
-					devinfo.target,
-					&tstate);
-	ahc_update_neg_request(ahc, &devinfo, tstate,
-			       targ_info, /*force*/TRUE);
-}
-
-#define AHC_MAX_STEPS 2000
-void
-ahc_clear_critical_section(struct ahc_softc *ahc)
-{
-	int	stepping;
-	int	steps;
-	u_int	simode0;
-	u_int	simode1;
-
-	if (ahc->num_critical_sections == 0)
-		return;
-
-	stepping = FALSE;
-	steps = 0;
-	simode0 = 0;
-	simode1 = 0;
-	for (;;) {
-		struct	cs *cs;
-		u_int	seqaddr;
-		u_int	i;
-
-		seqaddr = ahc_inb(ahc, SEQADDR0)
-			| (ahc_inb(ahc, SEQADDR1) << 8);
-
-		/*
-		 * Seqaddr represents the next instruction to execute, 
-		 * so we are really executing the instruction just
-		 * before it.
-		 */
-		if (seqaddr != 0)
-			seqaddr -= 1;
-		cs = ahc->critical_sections;
-		for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
-			
-			if (cs->begin < seqaddr && cs->end >= seqaddr)
-				break;
-		}
-
-		if (i == ahc->num_critical_sections)
-			break;
-
-		if (steps > AHC_MAX_STEPS) {
-			printf("%s: Infinite loop in critical section\n",
-			       ahc_name(ahc));
-			ahc_dump_card_state(ahc);
-			panic("critical section loop");
-		}
-
-		steps++;
-		if (stepping == FALSE) {
-
-			/*
-			 * Disable all interrupt sources so that the
-			 * sequencer will not be stuck by a pausing
-			 * interrupt condition while we attempt to
-			 * leave a critical section.
-			 */
-			simode0 = ahc_inb(ahc, SIMODE0);
-			ahc_outb(ahc, SIMODE0, 0);
-			simode1 = ahc_inb(ahc, SIMODE1);
-			ahc_outb(ahc, SIMODE1, 0);
-			ahc_outb(ahc, CLRINT, CLRSCSIINT);
-			ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) | STEP);
-			stepping = TRUE;
-		}
-		ahc_outb(ahc, HCNTRL, ahc->unpause);
-		do {
-			ahc_delay(200);
-		} while (!ahc_is_paused(ahc));
-	}
-	if (stepping) {
-		ahc_outb(ahc, SIMODE0, simode0);
-		ahc_outb(ahc, SIMODE1, simode1);
-		ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) & ~STEP);
-	}
-}
-
-/*
- * Clear any pending interrupt status.
- */
-void
-ahc_clear_intstat(struct ahc_softc *ahc)
-{
-	/* Clear any interrupt conditions this may have caused */
-	ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
-				|CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
-				CLRREQINIT);
-	ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
-	ahc_outb(ahc, CLRINT, CLRSCSIINT);
-}
-
-/**************************** Debugging Routines ******************************/
-void
-ahc_print_scb(struct scb *scb)
-{
-	int i;
-
-	struct hardware_scb *hscb = scb->hscb;
-
-	printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
-	       (void *)scb,
-	       hscb->control,
-	       hscb->scsiid,
-	       hscb->lun,
-	       hscb->cdb_len);
-	printf("Shared Data: ");
-	for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
-		printf("%#02x", hscb->shared_data.cdb[i]);
-	printf("        dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
-		ahc_le32toh(hscb->dataptr),
-		ahc_le32toh(hscb->datacnt),
-		ahc_le32toh(hscb->sgptr),
-		hscb->tag);
-	if (scb->sg_count > 0) {
-		for (i = 0; i < scb->sg_count; i++) {
-			printf("sg[%d] - Addr 0x%x%x : Length %d\n",
-			       i,
-			       (ahc_le32toh(scb->sg_list[i].len) >> 24
-			        & SG_HIGH_ADDR_BITS),
-			       ahc_le32toh(scb->sg_list[i].addr),
-			       ahc_le32toh(scb->sg_list[i].len));
-		}
-	}
-}
-
-/************************* Transfer Negotiation *******************************/
-/*
- * Allocate per target mode instance (ID we respond to as a target)
- * transfer negotiation data structures.
- */
-static struct ahc_tmode_tstate *
-ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
-{
-	struct ahc_tmode_tstate *master_tstate;
-	struct ahc_tmode_tstate *tstate;
-	int i;
-
-	master_tstate = ahc->enabled_targets[ahc->our_id];
-	if (channel == 'B') {
-		scsi_id += 8;
-		master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];
-	}
-	if (ahc->enabled_targets[scsi_id] != NULL
-	 && ahc->enabled_targets[scsi_id] != master_tstate)
-		panic("%s: ahc_alloc_tstate - Target already allocated",
-		      ahc_name(ahc));
-	tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT);
-	if (tstate == NULL)
-		return (NULL);
-
-	/*
-	 * If we have allocated a master tstate, copy user settings from
-	 * the master tstate (taken from SRAM or the EEPROM) for this
-	 * channel, but reset our current and goal settings to async/narrow
-	 * until an initiator talks to us.
-	 */
-	if (master_tstate != NULL) {
-		memcpy(tstate, master_tstate, sizeof(*tstate));
-		memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
-		tstate->ultraenb = 0;
-		for (i = 0; i < 16; i++) {
-			memset(&tstate->transinfo[i].curr, 0,
-			      sizeof(tstate->transinfo[i].curr));
-			memset(&tstate->transinfo[i].goal, 0,
-			      sizeof(tstate->transinfo[i].goal));
-		}
-	} else
-		memset(tstate, 0, sizeof(*tstate));
-	ahc->enabled_targets[scsi_id] = tstate;
-	return (tstate);
-}
-
-#ifdef AHC_TARGET_MODE
-/*
- * Free per target mode instance (ID we respond to as a target)
- * transfer negotiation data structures.
- */
-static void
-ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
-{
-	struct ahc_tmode_tstate *tstate;
-
-	/*
-	 * Don't clean up our "master" tstate.
-	 * It has our default user settings.
-	 */
-	if (((channel == 'B' && scsi_id == ahc->our_id_b)
-	  || (channel == 'A' && scsi_id == ahc->our_id))
-	 && force == FALSE)
-		return;
-
-	if (channel == 'B')
-		scsi_id += 8;
-	tstate = ahc->enabled_targets[scsi_id];
-	if (tstate != NULL)
-		free(tstate, M_DEVBUF);
-	ahc->enabled_targets[scsi_id] = NULL;
-}
-#endif
-
-/*
- * Called when we have an active connection to a target on the bus,
- * this function finds the nearest syncrate to the input period limited
- * by the capabilities of the bus connectivity of and sync settings for
- * the target.
- */
-struct ahc_syncrate *
-ahc_devlimited_syncrate(struct ahc_softc *ahc,
-			struct ahc_initiator_tinfo *tinfo,
-			u_int *period, u_int *ppr_options, role_t role) {
-	struct	ahc_transinfo *transinfo;
-	u_int	maxsync;
-
-	if ((ahc->features & AHC_ULTRA2) != 0) {
-		if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0
-		 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {
-			maxsync = AHC_SYNCRATE_DT;
-		} else {
-			maxsync = AHC_SYNCRATE_ULTRA;
-			/* Can't do DT on an SE bus */
-			*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
-		}
-	} else if ((ahc->features & AHC_ULTRA) != 0) {
-		maxsync = AHC_SYNCRATE_ULTRA;
-	} else {
-		maxsync = AHC_SYNCRATE_FAST;
-	}
-	/*
-	 * Never allow a value higher than our current goal
-	 * period otherwise we may allow a target initiated
-	 * negotiation to go above the limit as set by the
-	 * user.  In the case of an initiator initiated
-	 * sync negotiation, we limit based on the user
-	 * setting.  This allows the system to still accept
-	 * incoming negotiations even if target initiated
-	 * negotiation is not performed.
-	 */
-	if (role == ROLE_TARGET)
-		transinfo = &tinfo->user;
-	else 
-		transinfo = &tinfo->goal;
-	*ppr_options &= transinfo->ppr_options;
-	if (transinfo->period == 0) {
-		*period = 0;
-		*ppr_options = 0;
-		return (NULL);
-	}
-	*period = MAX(*period, transinfo->period);
-	return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
-}
-
-/*
- * Look up the valid period to SCSIRATE conversion in our table.
- * Return the period and offset that should be sent to the target
- * if this was the beginning of an SDTR.
- */
-struct ahc_syncrate *
-ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
-		  u_int *ppr_options, u_int maxsync)
-{
-	struct ahc_syncrate *syncrate;
-
-	if ((ahc->features & AHC_DT) == 0)
-		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
-
-	/* Skip all DT only entries if DT is not available */
-	if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
-	 && maxsync < AHC_SYNCRATE_ULTRA2)
-		maxsync = AHC_SYNCRATE_ULTRA2;
-	
-	for (syncrate = &ahc_syncrates[maxsync];
-	     syncrate->rate != NULL;
-	     syncrate++) {
-
-		/*
-		 * The Ultra2 table doesn't go as low
-		 * as for the Fast/Ultra cards.
-		 */
-		if ((ahc->features & AHC_ULTRA2) != 0
-		 && (syncrate->sxfr_u2 == 0))
-			break;
-
-		if (*period <= syncrate->period) {
-			/*
-			 * When responding to a target that requests
-			 * sync, the requested rate may fall between
-			 * two rates that we can output, but still be
-			 * a rate that we can receive.  Because of this,
-			 * we want to respond to the target with
-			 * the same rate that it sent to us even
-			 * if the period we use to send data to it
-			 * is lower.  Only lower the response period
-			 * if we must.
-			 */
-			if (syncrate == &ahc_syncrates[maxsync])
-				*period = syncrate->period;
-
-			/*
-			 * At some speeds, we only support
-			 * ST transfers.
-			 */
-		 	if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
-				*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
-			break;
-		}
-	}
-
-	if ((*period == 0)
-	 || (syncrate->rate == NULL)
-	 || ((ahc->features & AHC_ULTRA2) != 0
-	  && (syncrate->sxfr_u2 == 0))) {
-		/* Use asynchronous transfers. */
-		*period = 0;
-		syncrate = NULL;
-		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
-	}
-	return (syncrate);
-}
-
-/*
- * Convert from an entry in our syncrate table to the SCSI equivalent
- * sync "period" factor.
- */
-u_int
-ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
-{
-	struct ahc_syncrate *syncrate;
-
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		scsirate &= SXFR_ULTRA2;
-	else
-		scsirate &= SXFR;
-
-	syncrate = &ahc_syncrates[maxsync];
-	while (syncrate->rate != NULL) {
-
-		if ((ahc->features & AHC_ULTRA2) != 0) {
-			if (syncrate->sxfr_u2 == 0)
-				break;
-			else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))
-				return (syncrate->period);
-		} else if (scsirate == (syncrate->sxfr & SXFR)) {
-				return (syncrate->period);
-		}
-		syncrate++;
-	}
-	return (0); /* async */
-}
-
-/*
- * Truncate the given synchronous offset to a value the
- * current adapter type and syncrate are capable of.
- */
-void
-ahc_validate_offset(struct ahc_softc *ahc,
-		    struct ahc_initiator_tinfo *tinfo,
-		    struct ahc_syncrate *syncrate,
-		    u_int *offset, int wide, role_t role)
-{
-	u_int maxoffset;
-
-	/* Limit offset to what we can do */
-	if (syncrate == NULL) {
-		maxoffset = 0;
-	} else if ((ahc->features & AHC_ULTRA2) != 0) {
-		maxoffset = MAX_OFFSET_ULTRA2;
-	} else {
-		if (wide)
-			maxoffset = MAX_OFFSET_16BIT;
-		else
-			maxoffset = MAX_OFFSET_8BIT;
-	}
-	*offset = MIN(*offset, maxoffset);
-	if (tinfo != NULL) {
-		if (role == ROLE_TARGET)
-			*offset = MIN(*offset, tinfo->user.offset);
-		else
-			*offset = MIN(*offset, tinfo->goal.offset);
-	}
-}
-
-/*
- * Truncate the given transfer width parameter to a value the
- * current adapter type is capable of.
- */
-void
-ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo,
-		   u_int *bus_width, role_t role)
-{
-	switch (*bus_width) {
-	default:
-		if (ahc->features & AHC_WIDE) {
-			/* Respond Wide */
-			*bus_width = MSG_EXT_WDTR_BUS_16_BIT;
-			break;
-		}
-		/* FALLTHROUGH */
-	case MSG_EXT_WDTR_BUS_8_BIT:
-		*bus_width = MSG_EXT_WDTR_BUS_8_BIT;
-		break;
-	}
-	if (tinfo != NULL) {
-		if (role == ROLE_TARGET)
-			*bus_width = MIN(tinfo->user.width, *bus_width);
-		else
-			*bus_width = MIN(tinfo->goal.width, *bus_width);
-	}
-}
-
-/*
- * Update the bitmask of targets for which the controller should
- * negotiate with at the next convenient oportunity.  This currently
- * means the next time we send the initial identify messages for
- * a new transaction.
- */
-int
-ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		       struct ahc_tmode_tstate *tstate,
-		       struct ahc_initiator_tinfo *tinfo, int force)
-{
-	u_int auto_negotiate_orig;
-
-	auto_negotiate_orig = tstate->auto_negotiate;
-	if (tinfo->curr.period != tinfo->goal.period
-	 || tinfo->curr.width != tinfo->goal.width
-	 || tinfo->curr.offset != tinfo->goal.offset
-	 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
-	 || (force
-	  && (tinfo->goal.period != 0
-	   || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
-	   || tinfo->goal.ppr_options != 0)))
-		tstate->auto_negotiate |= devinfo->target_mask;
-	else
-		tstate->auto_negotiate &= ~devinfo->target_mask;
-
-	return (auto_negotiate_orig != tstate->auto_negotiate);
-}
-
-/*
- * Update the user/goal/curr tables of synchronous negotiation
- * parameters as well as, in the case of a current or active update,
- * any data structures on the host controller.  In the case of an
- * active update, the specified target is currently talking to us on
- * the bus, so the transfer parameter update must take effect
- * immediately.
- */
-void
-ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		 struct ahc_syncrate *syncrate, u_int period,
-		 u_int offset, u_int ppr_options, u_int type, int paused)
-{
-	struct	ahc_initiator_tinfo *tinfo;
-	struct	ahc_tmode_tstate *tstate;
-	u_int	old_period;
-	u_int	old_offset;
-	u_int	old_ppr;
-	int	active;
-	int	update_needed;
-
-	active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
-	update_needed = 0;
-
-	if (syncrate == NULL) {
-		period = 0;
-		offset = 0;
-	}
-
-	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
-				    devinfo->target, &tstate);
-
-	if ((type & AHC_TRANS_USER) != 0) {
-		tinfo->user.period = period;
-		tinfo->user.offset = offset;
-		tinfo->user.ppr_options = ppr_options;
-	}
-
-	if ((type & AHC_TRANS_GOAL) != 0) {
-		tinfo->goal.period = period;
-		tinfo->goal.offset = offset;
-		tinfo->goal.ppr_options = ppr_options;
-	}
-
-	old_period = tinfo->curr.period;
-	old_offset = tinfo->curr.offset;
-	old_ppr	   = tinfo->curr.ppr_options;
-
-	if ((type & AHC_TRANS_CUR) != 0
-	 && (old_period != period
-	  || old_offset != offset
-	  || old_ppr != ppr_options)) {
-		u_int	scsirate;
-
-		update_needed++;
-		scsirate = tinfo->scsirate;
-		if ((ahc->features & AHC_ULTRA2) != 0) {
-
-			scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);
-			if (syncrate != NULL) {
-				scsirate |= syncrate->sxfr_u2;
-				if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0)
-					scsirate |= ENABLE_CRC;
-				else
-					scsirate |= SINGLE_EDGE;
-			}
-		} else {
-
-			scsirate &= ~(SXFR|SOFS);
-			/*
-			 * Ensure Ultra mode is set properly for
-			 * this target.
-			 */
-			tstate->ultraenb &= ~devinfo->target_mask;
-			if (syncrate != NULL) {
-				if (syncrate->sxfr & ULTRA_SXFR) {
-					tstate->ultraenb |=
-						devinfo->target_mask;
-				}
-				scsirate |= syncrate->sxfr & SXFR;
-				scsirate |= offset & SOFS;
-			}
-			if (active) {
-				u_int sxfrctl0;
-
-				sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
-				sxfrctl0 &= ~FAST20;
-				if (tstate->ultraenb & devinfo->target_mask)
-					sxfrctl0 |= FAST20;
-				ahc_outb(ahc, SXFRCTL0, sxfrctl0);
-			}
-		}
-		if (active) {
-			ahc_outb(ahc, SCSIRATE, scsirate);
-			if ((ahc->features & AHC_ULTRA2) != 0)
-				ahc_outb(ahc, SCSIOFFSET, offset);
-		}
-
-		tinfo->scsirate = scsirate;
-		tinfo->curr.period = period;
-		tinfo->curr.offset = offset;
-		tinfo->curr.ppr_options = ppr_options;
-
-		ahc_send_async(ahc, devinfo->channel, devinfo->target,
-			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
-		if (bootverbose) {
-			if (offset != 0) {
-				printf("%s: target %d synchronous at %sMHz%s, "
-				       "offset = 0x%x\n", ahc_name(ahc),
-				       devinfo->target, syncrate->rate,
-				       (ppr_options & MSG_EXT_PPR_DT_REQ)
-				       ? " DT" : "", offset);
-			} else {
-				printf("%s: target %d using "
-				       "asynchronous transfers\n",
-				       ahc_name(ahc), devinfo->target);
-			}
-		}
-	}
-
-	update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
-						tinfo, /*force*/FALSE);
-
-	if (update_needed)
-		ahc_update_pending_scbs(ahc);
-}
-
-/*
- * Update the user/goal/curr tables of wide negotiation
- * parameters as well as, in the case of a current or active update,
- * any data structures on the host controller.  In the case of an
- * active update, the specified target is currently talking to us on
- * the bus, so the transfer parameter update must take effect
- * immediately.
- */
-void
-ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-	      u_int width, u_int type, int paused)
-{
-	struct	ahc_initiator_tinfo *tinfo;
-	struct	ahc_tmode_tstate *tstate;
-	u_int	oldwidth;
-	int	active;
-	int	update_needed;
-
-	active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
-	update_needed = 0;
-	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
-				    devinfo->target, &tstate);
-
-	if ((type & AHC_TRANS_USER) != 0)
-		tinfo->user.width = width;
-
-	if ((type & AHC_TRANS_GOAL) != 0)
-		tinfo->goal.width = width;
-
-	oldwidth = tinfo->curr.width;
-	if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {
-		u_int	scsirate;
-
-		update_needed++;
-		scsirate =  tinfo->scsirate;
-		scsirate &= ~WIDEXFER;
-		if (width == MSG_EXT_WDTR_BUS_16_BIT)
-			scsirate |= WIDEXFER;
-
-		tinfo->scsirate = scsirate;
-
-		if (active)
-			ahc_outb(ahc, SCSIRATE, scsirate);
-
-		tinfo->curr.width = width;
-
-		ahc_send_async(ahc, devinfo->channel, devinfo->target,
-			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
-		if (bootverbose) {
-			printf("%s: target %d using %dbit transfers\n",
-			       ahc_name(ahc), devinfo->target,
-			       8 * (0x01 << width));
-		}
-	}
-
-	update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
-						tinfo, /*force*/FALSE);
-	if (update_needed)
-		ahc_update_pending_scbs(ahc);
-}
-
-/*
- * Update the current state of tagged queuing for a given target.
- */
-void
-ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-	     ahc_queue_alg alg)
-{
- 	ahc_platform_set_tags(ahc, devinfo, alg);
- 	ahc_send_async(ahc, devinfo->channel, devinfo->target,
- 		       devinfo->lun, AC_TRANSFER_NEG, &alg);
-}
-
-/*
- * When the transfer settings for a connection change, update any
- * in-transit SCBs to contain the new data so the hardware will
- * be set correctly during future (re)selections.
- */
-static void
-ahc_update_pending_scbs(struct ahc_softc *ahc)
-{
-	struct	scb *pending_scb;
-	int	pending_scb_count;
-	int	i;
-	int	paused;
-	u_int	saved_scbptr;
-
-	/*
-	 * Traverse the pending SCB list and ensure that all of the
-	 * SCBs there have the proper settings.
-	 */
-	pending_scb_count = 0;
-	LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
-		struct ahc_devinfo devinfo;
-		struct hardware_scb *pending_hscb;
-		struct ahc_initiator_tinfo *tinfo;
-		struct ahc_tmode_tstate *tstate;
-
-		ahc_scb_devinfo(ahc, &devinfo, pending_scb);
-		tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
-					    devinfo.our_scsiid,
-					    devinfo.target, &tstate);
-		pending_hscb = pending_scb->hscb;
-		pending_hscb->control &= ~ULTRAENB;
-		if ((tstate->ultraenb & devinfo.target_mask) != 0)
-			pending_hscb->control |= ULTRAENB;
-		pending_hscb->scsirate = tinfo->scsirate;
-		pending_hscb->scsioffset = tinfo->curr.offset;
-		if ((tstate->auto_negotiate & devinfo.target_mask) == 0
-		 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
-			pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
-			pending_hscb->control &= ~MK_MESSAGE;
-		}
-		ahc_sync_scb(ahc, pending_scb,
-			     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-		pending_scb_count++;
-	}
-
-	if (pending_scb_count == 0)
-		return;
-
-	if (ahc_is_paused(ahc)) {
-		paused = 1;
-	} else {
-		paused = 0;
-		ahc_pause(ahc);
-	}
-
-	saved_scbptr = ahc_inb(ahc, SCBPTR);
-	/* Ensure that the hscbs down on the card match the new information */
-	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
-		struct	hardware_scb *pending_hscb;
-		u_int	control;
-		u_int	scb_tag;
-
-		ahc_outb(ahc, SCBPTR, i);
-		scb_tag = ahc_inb(ahc, SCB_TAG);
-		pending_scb = ahc_lookup_scb(ahc, scb_tag);
-		if (pending_scb == NULL)
-			continue;
-
-		pending_hscb = pending_scb->hscb;
-		control = ahc_inb(ahc, SCB_CONTROL);
-		control &= ~(ULTRAENB|MK_MESSAGE);
-		control |= pending_hscb->control & (ULTRAENB|MK_MESSAGE);
-		ahc_outb(ahc, SCB_CONTROL, control);
-		ahc_outb(ahc, SCB_SCSIRATE, pending_hscb->scsirate);
-		ahc_outb(ahc, SCB_SCSIOFFSET, pending_hscb->scsioffset);
-	}
-	ahc_outb(ahc, SCBPTR, saved_scbptr);
-
-	if (paused == 0)
-		ahc_unpause(ahc);
-}
-
-/**************************** Pathing Information *****************************/
-static void
-ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
-{
-	u_int	saved_scsiid;
-	role_t	role;
-	int	our_id;
-
-	if (ahc_inb(ahc, SSTAT0) & TARGET)
-		role = ROLE_TARGET;
-	else
-		role = ROLE_INITIATOR;
-
-	if (role == ROLE_TARGET
-	 && (ahc->features & AHC_MULTI_TID) != 0
-	 && (ahc_inb(ahc, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) {
-		/* We were selected, so pull our id from TARGIDIN */
-		our_id = ahc_inb(ahc, TARGIDIN) & OID;
-	} else if ((ahc->features & AHC_ULTRA2) != 0)
-		our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
-	else
-		our_id = ahc_inb(ahc, SCSIID) & OID;
-
-	saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
-	ahc_compile_devinfo(devinfo,
-			    our_id,
-			    SCSIID_TARGET(ahc, saved_scsiid),
-			    ahc_inb(ahc, SAVED_LUN),
-			    SCSIID_CHANNEL(ahc, saved_scsiid),
-			    role);
-}
-
-struct ahc_phase_table_entry*
-ahc_lookup_phase_entry(int phase)
-{
-	struct ahc_phase_table_entry *entry;
-	struct ahc_phase_table_entry *last_entry;
-
-	/*
-	 * num_phases doesn't include the default entry which
-	 * will be returned if the phase doesn't match.
-	 */
-	last_entry = &ahc_phase_table[num_phases];
-	for (entry = ahc_phase_table; entry < last_entry; entry++) {
-		if (phase == entry->phase)
-			break;
-	}
-	return (entry);
-}
-
-void
-ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
-		    u_int lun, char channel, role_t role)
-{
-	devinfo->our_scsiid = our_id;
-	devinfo->target = target;
-	devinfo->lun = lun;
-	devinfo->target_offset = target;
-	devinfo->channel = channel;
-	devinfo->role = role;
-	if (channel == 'B')
-		devinfo->target_offset += 8;
-	devinfo->target_mask = (0x01 << devinfo->target_offset);
-}
-
-static void
-ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		struct scb *scb)
-{
-	role_t	role;
-	int	our_id;
-
-	our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
-	role = ROLE_INITIATOR;
-	if ((scb->hscb->control & TARGET_SCB) != 0)
-		role = ROLE_TARGET;
-	ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb),
-			    SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role);
-}
-
-
-/************************ Message Phase Processing ****************************/
-static void
-ahc_assert_atn(struct ahc_softc *ahc)
-{
-	u_int scsisigo;
-
-	scsisigo = ATNO;
-	if ((ahc->features & AHC_DT) == 0)
-		scsisigo |= ahc_inb(ahc, SCSISIGI);
-	ahc_outb(ahc, SCSISIGO, scsisigo);
-}
-
-/*
- * When an initiator transaction with the MK_MESSAGE flag either reconnects
- * or enters the initial message out phase, we are interrupted.  Fill our
- * outgoing message buffer with the appropriate message and beging handing
- * the message phase(s) manually.
- */
-static void
-ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-			   struct scb *scb)
-{
-	/*
-	 * To facilitate adding multiple messages together,
-	 * each routine should increment the index and len
-	 * variables instead of setting them explicitly.
-	 */
-	ahc->msgout_index = 0;
-	ahc->msgout_len = 0;
-
-	if ((scb->flags & SCB_DEVICE_RESET) == 0
-	 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {
-		u_int identify_msg;
-
-		identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
-		if ((scb->hscb->control & DISCENB) != 0)
-			identify_msg |= MSG_IDENTIFY_DISCFLAG;
-		ahc->msgout_buf[ahc->msgout_index++] = identify_msg;
-		ahc->msgout_len++;
-
-		if ((scb->hscb->control & TAG_ENB) != 0) {
-			ahc->msgout_buf[ahc->msgout_index++] =
-			    scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
-			ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;
-			ahc->msgout_len += 2;
-		}
-	}
-
-	if (scb->flags & SCB_DEVICE_RESET) {
-		ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
-		ahc->msgout_len++;
-		ahc_print_path(ahc, scb);
-		printf("Bus Device Reset Message Sent\n");
-		/*
-		 * Clear our selection hardware in advance of
-		 * the busfree.  We may have an entry in the waiting
-		 * Q for this target, and we don't want to go about
-		 * selecting while we handle the busfree and blow it
-		 * away.
-		 */
-		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
-	} else if ((scb->flags & SCB_ABORT) != 0) {
-		if ((scb->hscb->control & TAG_ENB) != 0)
-			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;
-		else
-			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
-		ahc->msgout_len++;
-		ahc_print_path(ahc, scb);
-		printf("Abort%s Message Sent\n",
-		       (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
-		/*
-		 * Clear our selection hardware in advance of
-		 * the busfree.  We may have an entry in the waiting
-		 * Q for this target, and we don't want to go about
-		 * selecting while we handle the busfree and blow it
-		 * away.
-		 */
-		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
-	} else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
-		ahc_build_transfer_msg(ahc, devinfo);
-	} else {
-		printf("ahc_intr: AWAITING_MSG for an SCB that "
-		       "does not have a waiting message\n");
-		printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
-		       devinfo->target_mask);
-		panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
-		      "SCB flags = %x", scb->hscb->tag, scb->hscb->control,
-		      ahc_inb(ahc, MSG_OUT), scb->flags);
-	}
-
-	/*
-	 * Clear the MK_MESSAGE flag from the SCB so we aren't
-	 * asked to send this message again.
-	 */
-	ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);
-	scb->hscb->control &= ~MK_MESSAGE;
-	ahc->msgout_index = 0;
-	ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
-}
-
-/*
- * Build an appropriate transfer negotiation message for the
- * currently active target.
- */
-static void
-ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
-{
-	/*
-	 * We need to initiate transfer negotiations.
-	 * If our current and goal settings are identical,
-	 * we want to renegotiate due to a check condition.
-	 */
-	struct	ahc_initiator_tinfo *tinfo;
-	struct	ahc_tmode_tstate *tstate;
-	struct	ahc_syncrate *rate;
-	int	dowide;
-	int	dosync;
-	int	doppr;
-	int	use_ppr;
-	u_int	period;
-	u_int	ppr_options;
-	u_int	offset;
-
-	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
-				    devinfo->target, &tstate);
-	/*
-	 * Filter our period based on the current connection.
-	 * If we can't perform DT transfers on this segment (not in LVD
-	 * mode for instance), then our decision to issue a PPR message
-	 * may change.
-	 */
-	period = tinfo->goal.period;
-	ppr_options = tinfo->goal.ppr_options;
-	/* Target initiated PPR is not allowed in the SCSI spec */
-	if (devinfo->role == ROLE_TARGET)
-		ppr_options = 0;
-	rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
-				       &ppr_options, devinfo->role);
-	dowide = tinfo->curr.width != tinfo->goal.width;
-	dosync = tinfo->curr.period != period;
-	doppr = tinfo->curr.ppr_options != ppr_options;
-
-	if (!dowide && !dosync && !doppr) {
-		dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
-		dosync = tinfo->goal.period != 0;
-		doppr = tinfo->goal.ppr_options != 0;
-	}
-
-	if (!dowide && !dosync && !doppr) {
-		panic("ahc_intr: AWAITING_MSG for negotiation, "
-		      "but no negotiation needed\n");	
-	}
-
-	use_ppr = (tinfo->curr.transport_version >= 3) || doppr;
-	/* Target initiated PPR is not allowed in the SCSI spec */
-	if (devinfo->role == ROLE_TARGET)
-		use_ppr = 0;
-
-	/*
-	 * Both the PPR message and SDTR message require the
-	 * goal syncrate to be limited to what the target device
-	 * is capable of handling (based on whether an LVD->SE
-	 * expander is on the bus), so combine these two cases.
-	 * Regardless, guarantee that if we are using WDTR and SDTR
-	 * messages that WDTR comes first.
-	 */
-	if (use_ppr || (dosync && !dowide)) {
-
-		offset = tinfo->goal.offset;
-		ahc_validate_offset(ahc, tinfo, rate, &offset,
-				    use_ppr ? tinfo->goal.width
-					    : tinfo->curr.width,
-				    devinfo->role);
-		if (use_ppr) {
-			ahc_construct_ppr(ahc, devinfo, period, offset,
-					  tinfo->goal.width, ppr_options);
-		} else {
-			ahc_construct_sdtr(ahc, devinfo, period, offset);
-		}
-	} else {
-		ahc_construct_wdtr(ahc, devinfo, tinfo->goal.width);
-	}
-}
-
-/*
- * Build a synchronous negotiation message in our message
- * buffer based on the input parameters.
- */
-static void
-ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		   u_int period, u_int offset)
-{
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN;
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
-	ahc->msgout_buf[ahc->msgout_index++] = period;
-	ahc->msgout_buf[ahc->msgout_index++] = offset;
-	ahc->msgout_len += 5;
-	if (bootverbose) {
-		printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
-		       ahc_name(ahc), devinfo->channel, devinfo->target,
-		       devinfo->lun, period, offset);
-	}
-}
-
-/*
- * Build a wide negotiation message in our message
- * buffer based on the input parameters.
- */
-static void
-ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		   u_int bus_width)
-{
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN;
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
-	ahc->msgout_buf[ahc->msgout_index++] = bus_width;
-	ahc->msgout_len += 4;
-	if (bootverbose) {
-		printf("(%s:%c:%d:%d): Sending WDTR %x\n",
-		       ahc_name(ahc), devinfo->channel, devinfo->target,
-		       devinfo->lun, bus_width);
-	}
-}
-
-/*
- * Build a parallel protocol request message in our message
- * buffer based on the input parameters.
- */
-static void
-ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		  u_int period, u_int offset, u_int bus_width,
-		  u_int ppr_options)
-{
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN;
-	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR;
-	ahc->msgout_buf[ahc->msgout_index++] = period;
-	ahc->msgout_buf[ahc->msgout_index++] = 0;
-	ahc->msgout_buf[ahc->msgout_index++] = offset;
-	ahc->msgout_buf[ahc->msgout_index++] = bus_width;
-	ahc->msgout_buf[ahc->msgout_index++] = ppr_options;
-	ahc->msgout_len += 8;
-	if (bootverbose) {
-		printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
-		       "offset %x, ppr_options %x\n", ahc_name(ahc),
-		       devinfo->channel, devinfo->target, devinfo->lun,
-		       bus_width, period, offset, ppr_options);
-	}
-}
-
-/*
- * Clear any active message state.
- */
-static void
-ahc_clear_msg_state(struct ahc_softc *ahc)
-{
-	ahc->msgout_len = 0;
-	ahc->msgin_index = 0;
-	ahc->msg_type = MSG_TYPE_NONE;
-	if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {
-		/*
-		 * The target didn't care to respond to our
-		 * message request, so clear ATN.
-		 */
-		ahc_outb(ahc, CLRSINT1, CLRATNO);
-	}
-	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
-	ahc_outb(ahc, SEQ_FLAGS2,
-		 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
-}
-
-/*
- * Manual message loop handler.
- */
-static void
-ahc_handle_message_phase(struct ahc_softc *ahc)
-{ 
-	struct	ahc_devinfo devinfo;
-	u_int	bus_phase;
-	int	end_session;
-
-	ahc_fetch_devinfo(ahc, &devinfo);
-	end_session = FALSE;
-	bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
-
-reswitch:
-	switch (ahc->msg_type) {
-	case MSG_TYPE_INITIATOR_MSGOUT:
-	{
-		int lastbyte;
-		int phasemis;
-		int msgdone;
-
-		if (ahc->msgout_len == 0)
-			panic("HOST_MSG_LOOP interrupt with no active message");
-
-		phasemis = bus_phase != P_MESGOUT;
-		if (phasemis) {
-			if (bus_phase == P_MESGIN) {
-				/*
-				 * Change gears and see if
-				 * this messages is of interest to
-				 * us or should be passed back to
-				 * the sequencer.
-				 */
-				ahc_outb(ahc, CLRSINT1, CLRATNO);
-				ahc->send_msg_perror = FALSE;
-				ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;
-				ahc->msgin_index = 0;
-				goto reswitch;
-			}
-			end_session = TRUE;
-			break;
-		}
-
-		if (ahc->send_msg_perror) {
-			ahc_outb(ahc, CLRSINT1, CLRATNO);
-			ahc_outb(ahc, CLRSINT1, CLRREQINIT);
-			ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
-			break;
-		}
-
-		msgdone	= ahc->msgout_index == ahc->msgout_len;
-		if (msgdone) {
-			/*
-			 * The target has requested a retry.
-			 * Re-assert ATN, reset our message index to
-			 * 0, and try again.
-			 */
-			ahc->msgout_index = 0;
-			ahc_assert_atn(ahc);
-		}
-
-		lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);
-		if (lastbyte) {
-			/* Last byte is signified by dropping ATN */
-			ahc_outb(ahc, CLRSINT1, CLRATNO);
-		}
-
-		/*
-		 * Clear our interrupt status and present
-		 * the next byte on the bus.
-		 */
-		ahc_outb(ahc, CLRSINT1, CLRREQINIT);
-		ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
-		break;
-	}
-	case MSG_TYPE_INITIATOR_MSGIN:
-	{
-		int phasemis;
-		int message_done;
-
-		phasemis = bus_phase != P_MESGIN;
-
-		if (phasemis) {
-			ahc->msgin_index = 0;
-			if (bus_phase == P_MESGOUT
-			 && (ahc->send_msg_perror == TRUE
-			  || (ahc->msgout_len != 0
-			   && ahc->msgout_index == 0))) {
-				ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
-				goto reswitch;
-			}
-			end_session = TRUE;
-			break;
-		}
-
-		/* Pull the byte in without acking it */
-		ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
-
-		message_done = ahc_parse_msg(ahc, &devinfo);
-
-		if (message_done) {
-			/*
-			 * Clear our incoming message buffer in case there
-			 * is another message following this one.
-			 */
-			ahc->msgin_index = 0;
-
-			/*
-			 * If this message illicited a response,
-			 * assert ATN so the target takes us to the
-			 * message out phase.
-			 */
-			if (ahc->msgout_len != 0)
-				ahc_assert_atn(ahc);
-		} else 
-			ahc->msgin_index++;
-
-		/* Ack the byte */
-		ahc_outb(ahc, CLRSINT1, CLRREQINIT);
-		ahc_inb(ahc, SCSIDATL);
-		break;
-	}
-	case MSG_TYPE_TARGET_MSGIN:
-	{
-		int msgdone;
-		int msgout_request;
-
-		if (ahc->msgout_len == 0)
-			panic("Target MSGIN with no active message");
-
-		/*
-		 * If we interrupted a mesgout session, the initiator
-		 * will not know this until our first REQ.  So, we
-		 * only honor mesgout requests after we've sent our
-		 * first byte.
-		 */
-		if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0
-		 && ahc->msgout_index > 0)
-			msgout_request = TRUE;
-		else
-			msgout_request = FALSE;
-
-		if (msgout_request) {
-
-			/*
-			 * Change gears and see if
-			 * this messages is of interest to
-			 * us or should be passed back to
-			 * the sequencer.
-			 */
-			ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;
-			ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);
-			ahc->msgin_index = 0;
-			/* Dummy read to REQ for first byte */
-			ahc_inb(ahc, SCSIDATL);
-			ahc_outb(ahc, SXFRCTL0,
-				 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
-			break;
-		}
-
-		msgdone = ahc->msgout_index == ahc->msgout_len;
-		if (msgdone) {
-			ahc_outb(ahc, SXFRCTL0,
-				 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
-			end_session = TRUE;
-			break;
-		}
-
-		/*
-		 * Present the next byte on the bus.
-		 */
-		ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);
-		ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
-		break;
-	}
-	case MSG_TYPE_TARGET_MSGOUT:
-	{
-		int lastbyte;
-		int msgdone;
-
-		/*
-		 * The initiator signals that this is
-		 * the last byte by dropping ATN.
-		 */
-		lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;
-
-		/*
-		 * Read the latched byte, but turn off SPIOEN first
-		 * so that we don't inadvertantly cause a REQ for the
-		 * next byte.
-		 */
-		ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
-		ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);
-		msgdone = ahc_parse_msg(ahc, &devinfo);
-		if (msgdone == MSGLOOP_TERMINATED) {
-			/*
-			 * The message is *really* done in that it caused
-			 * us to go to bus free.  The sequencer has already
-			 * been reset at this point, so pull the ejection
-			 * handle.
-			 */
-			return;
-		}
-		
-		ahc->msgin_index++;
-
-		/*
-		 * XXX Read spec about initiator dropping ATN too soon
-		 *     and use msgdone to detect it.
-		 */
-		if (msgdone == MSGLOOP_MSGCOMPLETE) {
-			ahc->msgin_index = 0;
-
-			/*
-			 * If this message illicited a response, transition
-			 * to the Message in phase and send it.
-			 */
-			if (ahc->msgout_len != 0) {
-				ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);
-				ahc_outb(ahc, SXFRCTL0,
-					 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
-				ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
-				ahc->msgin_index = 0;
-				break;
-			}
-		}
-
-		if (lastbyte)
-			end_session = TRUE;
-		else {
-			/* Ask for the next byte. */
-			ahc_outb(ahc, SXFRCTL0,
-				 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
-		}
-
-		break;
-	}
-	default:
-		panic("Unknown REQINIT message type");
-	}
-
-	if (end_session) {
-		ahc_clear_msg_state(ahc);
-		ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);
-	} else
-		ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
-}
-
-/*
- * See if we sent a particular extended message to the target.
- * If "full" is true, return true only if the target saw the full
- * message.  If "full" is false, return true if the target saw at
- * least the first byte of the message.
- */
-static int
-ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
-{
-	int found;
-	u_int index;
-
-	found = FALSE;
-	index = 0;
-
-	while (index < ahc->msgout_len) {
-		if (ahc->msgout_buf[index] == MSG_EXTENDED) {
-			u_int end_index;
-
-			end_index = index + 1 + ahc->msgout_buf[index + 1];
-			if (ahc->msgout_buf[index+2] == msgval
-			 && type == AHCMSG_EXT) {
-
-				if (full) {
-					if (ahc->msgout_index > end_index)
-						found = TRUE;
-				} else if (ahc->msgout_index > index)
-					found = TRUE;
-			}
-			index = end_index;
-		} else if (ahc->msgout_buf[index] >= MSG_SIMPLE_TASK
-			&& ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
-
-			/* Skip tag type and tag id or residue param*/
-			index += 2;
-		} else {
-			/* Single byte message */
-			if (type == AHCMSG_1B
-			 && ahc->msgout_buf[index] == msgval
-			 && ahc->msgout_index > index)
-				found = TRUE;
-			index++;
-		}
-
-		if (found)
-			break;
-	}
-	return (found);
-}
-
-/*
- * Wait for a complete incoming message, parse it, and respond accordingly.
- */
-static int
-ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
-{
-	struct	ahc_initiator_tinfo *tinfo;
-	struct	ahc_tmode_tstate *tstate;
-	int	reject;
-	int	done;
-	int	response;
-	u_int	targ_scsirate;
-
-	done = MSGLOOP_IN_PROG;
-	response = FALSE;
-	reject = FALSE;
-	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
-				    devinfo->target, &tstate);
-	targ_scsirate = tinfo->scsirate;
-
-	/*
-	 * Parse as much of the message as is availible,
-	 * rejecting it if we don't support it.  When
-	 * the entire message is availible and has been
-	 * handled, return MSGLOOP_MSGCOMPLETE, indicating
-	 * that we have parsed an entire message.
-	 *
-	 * In the case of extended messages, we accept the length
-	 * byte outright and perform more checking once we know the
-	 * extended message type.
-	 */
-	switch (ahc->msgin_buf[0]) {
-	case MSG_MESSAGE_REJECT:
-		response = ahc_handle_msg_reject(ahc, devinfo);
-		/* FALLTHROUGH */
-	case MSG_NOOP:
-		done = MSGLOOP_MSGCOMPLETE;
-		break;
-	case MSG_EXTENDED:
-	{
-		/* Wait for enough of the message to begin validation */
-		if (ahc->msgin_index < 2)
-			break;
-		switch (ahc->msgin_buf[2]) {
-		case MSG_EXT_SDTR:
-		{
-			struct	 ahc_syncrate *syncrate;
-			u_int	 period;
-			u_int	 ppr_options;
-			u_int	 offset;
-			u_int	 saved_offset;
-			
-			if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
-				reject = TRUE;
-				break;
-			}
-
-			/*
-			 * Wait until we have both args before validating
-			 * and acting on this message.
-			 *
-			 * Add one to MSG_EXT_SDTR_LEN to account for
-			 * the extended message preamble.
-			 */
-			if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))
-				break;
-
-			period = ahc->msgin_buf[3];
-			ppr_options = 0;
-			saved_offset = offset = ahc->msgin_buf[4];
-			syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
-							   &ppr_options,
-							   devinfo->role);
-			ahc_validate_offset(ahc, tinfo, syncrate, &offset,
-					    targ_scsirate & WIDEXFER,
-					    devinfo->role);
-			if (bootverbose) {
-				printf("(%s:%c:%d:%d): Received "
-				       "SDTR period %x, offset %x\n\t"
-				       "Filtered to period %x, offset %x\n",
-				       ahc_name(ahc), devinfo->channel,
-				       devinfo->target, devinfo->lun,
-				       ahc->msgin_buf[3], saved_offset,
-				       period, offset);
-			}
-			ahc_set_syncrate(ahc, devinfo, 
-					 syncrate, period,
-					 offset, ppr_options,
-					 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
-					 /*paused*/TRUE);
-
-			/*
-			 * See if we initiated Sync Negotiation
-			 * and didn't have to fall down to async
-			 * transfers.
-			 */
-			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, TRUE)) {
-				/* We started it */
-				if (saved_offset != offset) {
-					/* Went too low - force async */
-					reject = TRUE;
-				}
-			} else {
-				/*
-				 * Send our own SDTR in reply
-				 */
-				if (bootverbose
-				 && devinfo->role == ROLE_INITIATOR) {
-					printf("(%s:%c:%d:%d): Target "
-					       "Initiated SDTR\n",
-					       ahc_name(ahc), devinfo->channel,
-					       devinfo->target, devinfo->lun);
-				}
-				ahc->msgout_index = 0;
-				ahc->msgout_len = 0;
-				ahc_construct_sdtr(ahc, devinfo,
-						   period, offset);
-				ahc->msgout_index = 0;
-				response = TRUE;
-			}
-			done = MSGLOOP_MSGCOMPLETE;
-			break;
-		}
-		case MSG_EXT_WDTR:
-		{
-			u_int bus_width;
-			u_int saved_width;
-			u_int sending_reply;
-
-			sending_reply = FALSE;
-			if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
-				reject = TRUE;
-				break;
-			}
-
-			/*
-			 * Wait until we have our arg before validating
-			 * and acting on this message.
-			 *
-			 * Add one to MSG_EXT_WDTR_LEN to account for
-			 * the extended message preamble.
-			 */
-			if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))
-				break;
-
-			bus_width = ahc->msgin_buf[3];
-			saved_width = bus_width;
-			ahc_validate_width(ahc, tinfo, &bus_width,
-					   devinfo->role);
-			if (bootverbose) {
-				printf("(%s:%c:%d:%d): Received WDTR "
-				       "%x filtered to %x\n",
-				       ahc_name(ahc), devinfo->channel,
-				       devinfo->target, devinfo->lun,
-				       saved_width, bus_width);
-			}
-
-			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, TRUE)) {
-				/*
-				 * Don't send a WDTR back to the
-				 * target, since we asked first.
-				 * If the width went higher than our
-				 * request, reject it.
-				 */
-				if (saved_width > bus_width) {
-					reject = TRUE;
-					printf("(%s:%c:%d:%d): requested %dBit "
-					       "transfers.  Rejecting...\n",
-					       ahc_name(ahc), devinfo->channel,
-					       devinfo->target, devinfo->lun,
-					       8 * (0x01 << bus_width));
-					bus_width = 0;
-				}
-			} else {
-				/*
-				 * Send our own WDTR in reply
-				 */
-				if (bootverbose
-				 && devinfo->role == ROLE_INITIATOR) {
-					printf("(%s:%c:%d:%d): Target "
-					       "Initiated WDTR\n",
-					       ahc_name(ahc), devinfo->channel,
-					       devinfo->target, devinfo->lun);
-				}
-				ahc->msgout_index = 0;
-				ahc->msgout_len = 0;
-				ahc_construct_wdtr(ahc, devinfo, bus_width);
-				ahc->msgout_index = 0;
-				response = TRUE;
-				sending_reply = TRUE;
-			}
-			ahc_set_width(ahc, devinfo, bus_width,
-				      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
-				      /*paused*/TRUE);
-			/* After a wide message, we are async */
-			ahc_set_syncrate(ahc, devinfo,
-					 /*syncrate*/NULL, /*period*/0,
-					 /*offset*/0, /*ppr_options*/0,
-					 AHC_TRANS_ACTIVE, /*paused*/TRUE);
-			if (sending_reply == FALSE && reject == FALSE) {
-
-				if (tinfo->goal.period) {
-					ahc->msgout_index = 0;
-					ahc->msgout_len = 0;
-					ahc_build_transfer_msg(ahc, devinfo);
-					ahc->msgout_index = 0;
-					response = TRUE;
-				}
-			}
-			done = MSGLOOP_MSGCOMPLETE;
-			break;
-		}
-		case MSG_EXT_PPR:
-		{
-			struct	ahc_syncrate *syncrate;
-			u_int	period;
-			u_int	offset;
-			u_int	bus_width;
-			u_int	ppr_options;
-			u_int	saved_width;
-			u_int	saved_offset;
-			u_int	saved_ppr_options;
-
-			if (ahc->msgin_buf[1] != MSG_EXT_PPR_LEN) {
-				reject = TRUE;
-				break;
-			}
-
-			/*
-			 * Wait until we have all args before validating
-			 * and acting on this message.
-			 *
-			 * Add one to MSG_EXT_PPR_LEN to account for
-			 * the extended message preamble.
-			 */
-			if (ahc->msgin_index < (MSG_EXT_PPR_LEN + 1))
-				break;
-
-			period = ahc->msgin_buf[3];
-			offset = ahc->msgin_buf[5];
-			bus_width = ahc->msgin_buf[6];
-			saved_width = bus_width;
-			ppr_options = ahc->msgin_buf[7];
-			/*
-			 * According to the spec, a DT only
-			 * period factor with no DT option
-			 * set implies async.
-			 */
-			if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
-			 && period == 9)
-				offset = 0;
-			saved_ppr_options = ppr_options;
-			saved_offset = offset;
-
-			/*
-			 * Mask out any options we don't support
-			 * on any controller.  Transfer options are
-			 * only available if we are negotiating wide.
-			 */
-			ppr_options &= MSG_EXT_PPR_DT_REQ;
-			if (bus_width == 0)
-				ppr_options = 0;
-
-			ahc_validate_width(ahc, tinfo, &bus_width,
-					   devinfo->role);
-			syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
-							   &ppr_options,
-							   devinfo->role);
-			ahc_validate_offset(ahc, tinfo, syncrate,
-					    &offset, bus_width,
-					    devinfo->role);
-
-			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, TRUE)) {
-				/*
-				 * If we are unable to do any of the
-				 * requested options (we went too low),
-				 * then we'll have to reject the message.
-				 */
-				if (saved_width > bus_width
-				 || saved_offset != offset
-				 || saved_ppr_options != ppr_options) {
-					reject = TRUE;
-					period = 0;
-					offset = 0;
-					bus_width = 0;
-					ppr_options = 0;
-					syncrate = NULL;
-				}
-			} else {
-				if (devinfo->role != ROLE_TARGET)
-					printf("(%s:%c:%d:%d): Target "
-					       "Initiated PPR\n",
-					       ahc_name(ahc), devinfo->channel,
-					       devinfo->target, devinfo->lun);
-				else
-					printf("(%s:%c:%d:%d): Initiator "
-					       "Initiated PPR\n",
-					       ahc_name(ahc), devinfo->channel,
-					       devinfo->target, devinfo->lun);
-				ahc->msgout_index = 0;
-				ahc->msgout_len = 0;
-				ahc_construct_ppr(ahc, devinfo, period, offset,
-						  bus_width, ppr_options);
-				ahc->msgout_index = 0;
-				response = TRUE;
-			}
-			if (bootverbose) {
-				printf("(%s:%c:%d:%d): Received PPR width %x, "
-				       "period %x, offset %x,options %x\n"
-				       "\tFiltered to width %x, period %x, "
-				       "offset %x, options %x\n",
-				       ahc_name(ahc), devinfo->channel,
-				       devinfo->target, devinfo->lun,
-				       saved_width, ahc->msgin_buf[3],
-				       saved_offset, saved_ppr_options,
-				       bus_width, period, offset, ppr_options);
-			}
-			ahc_set_width(ahc, devinfo, bus_width,
-				      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
-				      /*paused*/TRUE);
-			ahc_set_syncrate(ahc, devinfo,
-					 syncrate, period,
-					 offset, ppr_options,
-					 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
-					 /*paused*/TRUE);
-			done = MSGLOOP_MSGCOMPLETE;
-			break;
-		}
-		default:
-			/* Unknown extended message.  Reject it. */
-			reject = TRUE;
-			break;
-		}
-		break;
-	}
-#ifdef AHC_TARGET_MODE
-	case MSG_BUS_DEV_RESET:
-		ahc_handle_devreset(ahc, devinfo,
-				    CAM_BDR_SENT,
-				    "Bus Device Reset Received",
-				    /*verbose_level*/0);
-		ahc_restart(ahc);
-		done = MSGLOOP_TERMINATED;
-		break;
-	case MSG_ABORT_TAG:
-	case MSG_ABORT:
-	case MSG_CLEAR_QUEUE:
-	{
-		int tag;
-
-		/* Target mode messages */
-		if (devinfo->role != ROLE_TARGET) {
-			reject = TRUE;
-			break;
-		}
-		tag = SCB_LIST_NULL;
-		if (ahc->msgin_buf[0] == MSG_ABORT_TAG)
-			tag = ahc_inb(ahc, INITIATOR_TAG);
-		ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
-			       devinfo->lun, tag, ROLE_TARGET,
-			       CAM_REQ_ABORTED);
-
-		tstate = ahc->enabled_targets[devinfo->our_scsiid];
-		if (tstate != NULL) {
-			struct ahc_tmode_lstate* lstate;
-
-			lstate = tstate->enabled_luns[devinfo->lun];
-			if (lstate != NULL) {
-				ahc_queue_lstate_event(ahc, lstate,
-						       devinfo->our_scsiid,
-						       ahc->msgin_buf[0],
-						       /*arg*/tag);
-				ahc_send_lstate_events(ahc, lstate);
-			}
-		}
-		ahc_restart(ahc);
-		done = MSGLOOP_TERMINATED;
-		break;
-	}
-#endif
-	case MSG_TERM_IO_PROC:
-	default:
-		reject = TRUE;
-		break;
-	}
-
-	if (reject) {
-		/*
-		 * Setup to reject the message.
-		 */
-		ahc->msgout_index = 0;
-		ahc->msgout_len = 1;
-		ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
-		done = MSGLOOP_MSGCOMPLETE;
-		response = TRUE;
-	}
-
-	if (done != MSGLOOP_IN_PROG && !response)
-		/* Clear the outgoing message buffer */
-		ahc->msgout_len = 0;
-
-	return (done);
-}
-
-/*
- * Process a message reject message.
- */
-static int
-ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
-{
-	/*
-	 * What we care about here is if we had an
-	 * outstanding SDTR or WDTR message for this
-	 * target.  If we did, this is a signal that
-	 * the target is refusing negotiation.
-	 */
-	struct scb *scb;
-	struct ahc_initiator_tinfo *tinfo;
-	struct ahc_tmode_tstate *tstate;
-	u_int scb_index;
-	u_int last_msg;
-	int   response = 0;
-
-	scb_index = ahc_inb(ahc, SCB_TAG);
-	scb = ahc_lookup_scb(ahc, scb_index);
-	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
-				    devinfo->our_scsiid,
-				    devinfo->target, &tstate);
-	/* Might be necessary */
-	last_msg = ahc_inb(ahc, LAST_MSG);
-
-	if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
-		/*
-		 * Target does not support the PPR message.
-		 * Attempt to negotiate SPI-2 style.
-		 */
-		if (bootverbose) {
-			printf("(%s:%c:%d:%d): PPR Rejected. "
-			       "Trying WDTR/SDTR\n",
-			       ahc_name(ahc), devinfo->channel,
-			       devinfo->target, devinfo->lun);
-		}
-		tinfo->goal.ppr_options = 0;
-		tinfo->curr.transport_version = 2;
-		tinfo->goal.transport_version = 2;
-		ahc->msgout_index = 0;
-		ahc->msgout_len = 0;
-		ahc_build_transfer_msg(ahc, devinfo);
-		ahc->msgout_index = 0;
-		response = 1;
-	} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
-
-		/* note 8bit xfers */
-		printf("(%s:%c:%d:%d): refuses WIDE negotiation.  Using "
-		       "8bit transfers\n", ahc_name(ahc),
-		       devinfo->channel, devinfo->target, devinfo->lun);
-		ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
-			      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
-			      /*paused*/TRUE);
-		/*
-		 * No need to clear the sync rate.  If the target
-		 * did not accept the command, our syncrate is
-		 * unaffected.  If the target started the negotiation,
-		 * but rejected our response, we already cleared the
-		 * sync rate before sending our WDTR.
-		 */
-		if (tinfo->goal.period) {
-
-			/* Start the sync negotiation */
-			ahc->msgout_index = 0;
-			ahc->msgout_len = 0;
-			ahc_build_transfer_msg(ahc, devinfo);
-			ahc->msgout_index = 0;
-			response = 1;
-		}
-	} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
-		/* note asynch xfers and clear flag */
-		ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
-				 /*offset*/0, /*ppr_options*/0,
-				 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
-				 /*paused*/TRUE);
-		printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
-		       "Using asynchronous transfers\n",
-		       ahc_name(ahc), devinfo->channel,
-		       devinfo->target, devinfo->lun);
-	} else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
-		int tag_type;
-		int mask;
-
-		tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
-
-		if (tag_type == MSG_SIMPLE_TASK) {
-			printf("(%s:%c:%d:%d): refuses tagged commands.  "
-			       "Performing non-tagged I/O\n", ahc_name(ahc),
-			       devinfo->channel, devinfo->target, devinfo->lun);
-			ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE);
-			mask = ~0x23;
-		} else {
-			printf("(%s:%c:%d:%d): refuses %s tagged commands.  "
-			       "Performing simple queue tagged I/O only\n",
-			       ahc_name(ahc), devinfo->channel, devinfo->target,
-			       devinfo->lun, tag_type == MSG_ORDERED_TASK
-			       ? "ordered" : "head of queue");
-			ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC);
-			mask = ~0x03;
-		}
-
-		/*
-		 * Resend the identify for this CCB as the target
-		 * may believe that the selection is invalid otherwise.
-		 */
-		ahc_outb(ahc, SCB_CONTROL,
-			 ahc_inb(ahc, SCB_CONTROL) & mask);
-	 	scb->hscb->control &= mask;
-		ahc_set_transaction_tag(scb, /*enabled*/FALSE,
-					/*type*/MSG_SIMPLE_TASK);
-		ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
-		ahc_assert_atn(ahc);
-
-		/*
-		 * This transaction is now at the head of
-		 * the untagged queue for this target.
-		 */
-		if ((ahc->flags & AHC_SCB_BTT) == 0) {
-			struct scb_tailq *untagged_q;
-
-			untagged_q =
-			    &(ahc->untagged_queues[devinfo->target_offset]);
-			TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
-			scb->flags |= SCB_UNTAGGEDQ;
-		}
-		ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
-			     scb->hscb->tag);
-
-		/*
-		 * Requeue all tagged commands for this target
-		 * currently in our posession so they can be
-		 * converted to untagged commands.
-		 */
-		ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
-				   SCB_GET_CHANNEL(ahc, scb),
-				   SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL,
-				   ROLE_INITIATOR, CAM_REQUEUE_REQ,
-				   SEARCH_COMPLETE);
-	} else {
-		/*
-		 * Otherwise, we ignore it.
-		 */
-		printf("%s:%c:%d: Message reject for %x -- ignored\n",
-		       ahc_name(ahc), devinfo->channel, devinfo->target,
-		       last_msg);
-	}
-	return (response);
-}
-
-/*
- * Process an ingnore wide residue message.
- */
-static void
-ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
-{
-	u_int scb_index;
-	struct scb *scb;
-
-	scb_index = ahc_inb(ahc, SCB_TAG);
-	scb = ahc_lookup_scb(ahc, scb_index);
-	/*
-	 * XXX Actually check data direction in the sequencer?
-	 * Perhaps add datadir to some spare bits in the hscb?
-	 */
-	if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
-	 || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {
-		/*
-		 * Ignore the message if we haven't
-		 * seen an appropriate data phase yet.
-		 */
-	} else {
-		/*
-		 * If the residual occurred on the last
-		 * transfer and the transfer request was
-		 * expected to end on an odd count, do
-		 * nothing.  Otherwise, subtract a byte
-		 * and update the residual count accordingly.
-		 */
-		uint32_t sgptr;
-
-		sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
-		if ((sgptr & SG_LIST_NULL) != 0
-		 && ahc_inb(ahc, DATA_COUNT_ODD) == 1) {
-			/*
-			 * If the residual occurred on the last
-			 * transfer and the transfer request was
-			 * expected to end on an odd count, do
-			 * nothing.
-			 */
-		} else {
-			struct ahc_dma_seg *sg;
-			uint32_t data_cnt;
-			uint32_t data_addr;
-			uint32_t sglen;
-
-			/* Pull in the rest of the sgptr */
-			sgptr |= (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
-			      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
-			      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8);
-			sgptr &= SG_PTR_MASK;
-			data_cnt = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+3) << 24)
-				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+2) << 16)
-				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+1) << 8)
-				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT));
-
-			data_addr = (ahc_inb(ahc, SHADDR + 3) << 24)
-				  | (ahc_inb(ahc, SHADDR + 2) << 16)
-				  | (ahc_inb(ahc, SHADDR + 1) << 8)
-				  | (ahc_inb(ahc, SHADDR));
-
-			data_cnt += 1;
-			data_addr -= 1;
-
-			sg = ahc_sg_bus_to_virt(scb, sgptr);
-			/*
-			 * The residual sg ptr points to the next S/G
-			 * to load so we must go back one.
-			 */
-			sg--;
-			sglen = ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
-			if (sg != scb->sg_list
-			 && sglen < (data_cnt & AHC_SG_LEN_MASK)) {
-
-				sg--;
-				sglen = ahc_le32toh(sg->len);
-				/*
-				 * Preserve High Address and SG_LIST bits
-				 * while setting the count to 1.
-				 */
-				data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));
-				data_addr = ahc_le32toh(sg->addr)
-					  + (sglen & AHC_SG_LEN_MASK) - 1;
-
-				/*
-				 * Increment sg so it points to the
-				 * "next" sg.
-				 */
-				sg++;
-				sgptr = ahc_sg_virt_to_bus(scb, sg);
-				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 3,
-					 sgptr >> 24);
-				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 2,
-					 sgptr >> 16);
-				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 1,
-					 sgptr >> 8);
-				ahc_outb(ahc, SCB_RESIDUAL_SGPTR, sgptr);
-			}
-
-			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24);
-			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16);
-			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8);
-			ahc_outb(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
-		}
-	}
-}
-
-
-/*
- * Reinitialize the data pointers for the active transfer
- * based on its current residual.
- */
-static void
-ahc_reinitialize_dataptrs(struct ahc_softc *ahc)
-{
-	struct	 scb *scb;
-	struct	 ahc_dma_seg *sg;
-	u_int	 scb_index;
-	uint32_t sgptr;
-	uint32_t resid;
-	uint32_t dataptr;
-
-	scb_index = ahc_inb(ahc, SCB_TAG);
-	scb = ahc_lookup_scb(ahc, scb_index);
-	sgptr = (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
-	      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
-	      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8)
-	      |	ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
-
-	sgptr &= SG_PTR_MASK;
-	sg = ahc_sg_bus_to_virt(scb, sgptr);
-
-	/* The residual sg_ptr always points to the next sg */
-	sg--;
-
-	resid = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 2) << 16)
-	      | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)
-	      | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);
-
-	dataptr = ahc_le32toh(sg->addr)
-		+ (ahc_le32toh(sg->len) & AHC_SG_LEN_MASK)
-		- resid;
-	if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
-		u_int dscommand1;
-
-		dscommand1 = ahc_inb(ahc, DSCOMMAND1);
-		ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
-		ahc_outb(ahc, HADDR,
-			 (ahc_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
-		ahc_outb(ahc, DSCOMMAND1, dscommand1);
-	}
-	ahc_outb(ahc, HADDR + 3, dataptr >> 24);
-	ahc_outb(ahc, HADDR + 2, dataptr >> 16);
-	ahc_outb(ahc, HADDR + 1, dataptr >> 8);
-	ahc_outb(ahc, HADDR, dataptr);
-	ahc_outb(ahc, HCNT + 2, resid >> 16);
-	ahc_outb(ahc, HCNT + 1, resid >> 8);
-	ahc_outb(ahc, HCNT, resid);
-	if ((ahc->features & AHC_ULTRA2) == 0) {
-		ahc_outb(ahc, STCNT + 2, resid >> 16);
-		ahc_outb(ahc, STCNT + 1, resid >> 8);
-		ahc_outb(ahc, STCNT, resid);
-	}
-}
-
-/*
- * Handle the effects of issuing a bus device reset message.
- */
-static void
-ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		    cam_status status, char *message, int verbose_level)
-{
-#ifdef AHC_TARGET_MODE
-	struct ahc_tmode_tstate* tstate;
-	u_int lun;
-#endif
-	int found;
-
-	found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
-			       CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
-			       status);
-
-#ifdef AHC_TARGET_MODE
-	/*
-	 * Send an immediate notify ccb to all target mord peripheral
-	 * drivers affected by this action.
-	 */
-	tstate = ahc->enabled_targets[devinfo->our_scsiid];
-	if (tstate != NULL) {
-		for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
-			struct ahc_tmode_lstate* lstate;
-
-			lstate = tstate->enabled_luns[lun];
-			if (lstate == NULL)
-				continue;
-
-			ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
-					       MSG_BUS_DEV_RESET, /*arg*/0);
-			ahc_send_lstate_events(ahc, lstate);
-		}
-	}
-#endif
-
-	/*
-	 * Go back to async/narrow transfers and renegotiate.
-	 */
-	ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
-		      AHC_TRANS_CUR, /*paused*/TRUE);
-	ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL,
-			 /*period*/0, /*offset*/0, /*ppr_options*/0,
-			 AHC_TRANS_CUR, /*paused*/TRUE);
-	
-	ahc_send_async(ahc, devinfo->channel, devinfo->target,
-		       CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
-
-	if (message != NULL
-	 && (verbose_level <= bootverbose))
-		printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
-		       message, devinfo->channel, devinfo->target, found);
-}
-
-#ifdef AHC_TARGET_MODE
-static void
-ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		       struct scb *scb)
-{
-
-	/*              
-	 * To facilitate adding multiple messages together,
-	 * each routine should increment the index and len
-	 * variables instead of setting them explicitly.
-	 */             
-	ahc->msgout_index = 0;
-	ahc->msgout_len = 0;
-
-	if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
-		ahc_build_transfer_msg(ahc, devinfo);
-	else
-		panic("ahc_intr: AWAITING target message with no message");
-
-	ahc->msgout_index = 0;
-	ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
-}
-#endif
-/**************************** Initialization **********************************/
-/*
- * Allocate a controller structure for a new device
- * and perform initial initializion.
- */
-struct ahc_softc *
-ahc_alloc(void *platform_arg, char *name)
-{
-	struct  ahc_softc *ahc;
-	int	i;
-
-#ifndef	__FreeBSD__
-	ahc = malloc(sizeof(*ahc), M_DEVBUF, M_NOWAIT);
-	if (!ahc) {
-		printf("aic7xxx: cannot malloc softc!\n");
-		free(name, M_DEVBUF);
-		return NULL;
-	}
-#else
-	ahc = device_get_softc((device_t)platform_arg);
-#endif
-	memset(ahc, 0, sizeof(*ahc));
-	LIST_INIT(&ahc->pending_scbs);
-	/* We don't know our unit number until the OSM sets it */
-	ahc->name = name;
-	ahc->unit = -1;
-	ahc->description = NULL;
-	ahc->channel = 'A';
-	ahc->channel_b = 'B';
-	ahc->chip = AHC_NONE;
-	ahc->features = AHC_FENONE;
-	ahc->bugs = AHC_BUGNONE;
-	ahc->flags = AHC_FNONE;
-
-	for (i = 0; i < 16; i++)
-		TAILQ_INIT(&ahc->untagged_queues[i]);
-	if (ahc_platform_alloc(ahc, platform_arg) != 0) {
-		ahc_free(ahc);
-		ahc = NULL;
-	}
-	return (ahc);
-}
-
-int
-ahc_softc_init(struct ahc_softc *ahc)
-{
-
-	/* The IRQMS bit is only valid on VL and EISA chips */
-	if ((ahc->chip & AHC_PCI) == 0)
-		ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
-	else
-		ahc->unpause = 0;
-	ahc->pause = ahc->unpause | PAUSE; 
-	/* XXX The shared scb data stuff should be deprecated */
-	if (ahc->scb_data == NULL) {
-		ahc->scb_data = malloc(sizeof(*ahc->scb_data),
-				       M_DEVBUF, M_NOWAIT);
-		if (ahc->scb_data == NULL)
-			return (ENOMEM);
-		memset(ahc->scb_data, 0, sizeof(*ahc->scb_data));
-	}
-
-	return (0);
-}
-
-void
-ahc_softc_insert(struct ahc_softc *ahc)
-{
-	struct ahc_softc *list_ahc;
-
-#if AHC_PCI_CONFIG > 0
-	/*
-	 * Second Function PCI devices need to inherit some
-	 * settings from function 0.
-	 */
-	if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
-	 && (ahc->features & AHC_MULTI_FUNC) != 0) {
-		TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
-			ahc_dev_softc_t list_pci;
-			ahc_dev_softc_t pci;
-
-			list_pci = list_ahc->dev_softc;
-			pci = ahc->dev_softc;
-			if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
-			 && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
-				struct ahc_softc *master;
-				struct ahc_softc *slave;
-
-				if (ahc_get_pci_function(list_pci) == 0) {
-					master = list_ahc;
-					slave = ahc;
-				} else {
-					master = ahc;
-					slave = list_ahc;
-				}
-				slave->flags &= ~AHC_BIOS_ENABLED; 
-				slave->flags |=
-				    master->flags & AHC_BIOS_ENABLED;
-				slave->flags &= ~AHC_PRIMARY_CHANNEL; 
-				slave->flags |=
-				    master->flags & AHC_PRIMARY_CHANNEL;
-				break;
-			}
-		}
-	}
-#endif
-
-	/*
-	 * Insertion sort into our list of softcs.
-	 */
-	list_ahc = TAILQ_FIRST(&ahc_tailq);
-	while (list_ahc != NULL
-	    && ahc_softc_comp(list_ahc, ahc) <= 0)
-		list_ahc = TAILQ_NEXT(list_ahc, links);
-	if (list_ahc != NULL)
-		TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
-	else
-		TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
-	ahc->init_level++;
-}
-
-void
-ahc_set_unit(struct ahc_softc *ahc, int unit)
-{
-	ahc->unit = unit;
-}
-
-void
-ahc_set_name(struct ahc_softc *ahc, char *name)
-{
-	if (ahc->name != NULL)
-		free(ahc->name, M_DEVBUF);
-	ahc->name = name;
-}
-
-void
-ahc_free(struct ahc_softc *ahc)
-{
-	int i;
-
-	ahc_fini_scbdata(ahc);
-	switch (ahc->init_level) {
-	default:
-	case 5:
-		ahc_shutdown(ahc);
-		TAILQ_REMOVE(&ahc_tailq, ahc, links);
-		/* FALLTHROUGH */
-	case 4:
-		ahc_dmamap_unload(ahc, ahc->shared_data_dmat,
-				  ahc->shared_data_dmamap);
-		/* FALLTHROUGH */
-	case 3:
-		ahc_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,
-				ahc->shared_data_dmamap);
-		ahc_dmamap_destroy(ahc, ahc->shared_data_dmat,
-				   ahc->shared_data_dmamap);
-		/* FALLTHROUGH */
-	case 2:
-		ahc_dma_tag_destroy(ahc, ahc->shared_data_dmat);
-	case 1:
-#ifndef __linux__
-		ahc_dma_tag_destroy(ahc, ahc->buffer_dmat);
-#endif
-		break;
-	case 0:
-		break;
-	}
-
-#ifndef __linux__
-	ahc_dma_tag_destroy(ahc, ahc->parent_dmat);
-#endif
-	ahc_platform_free(ahc);
-	for (i = 0; i < AHC_NUM_TARGETS; i++) {
-		struct ahc_tmode_tstate *tstate;
-
-		tstate = ahc->enabled_targets[i];
-		if (tstate != NULL) {
-#if AHC_TARGET_MODE
-			int j;
-
-			for (j = 0; j < AHC_NUM_LUNS; j++) {
-				struct ahc_tmode_lstate *lstate;
-
-				lstate = tstate->enabled_luns[j];
-				if (lstate != NULL) {
-					xpt_free_path(lstate->path);
-					free(lstate, M_DEVBUF);
-				}
-			}
-#endif
-			free(tstate, M_DEVBUF);
-		}
-	}
-#if AHC_TARGET_MODE
-	if (ahc->black_hole != NULL) {
-		xpt_free_path(ahc->black_hole->path);
-		free(ahc->black_hole, M_DEVBUF);
-	}
-#endif
-	if (ahc->name != NULL)
-		free(ahc->name, M_DEVBUF);
-#ifndef __FreeBSD__
-	free(ahc, M_DEVBUF);
-#endif
-	return;
-}
-
-void
-ahc_shutdown(void *arg)
-{
-	struct	ahc_softc *ahc;
-	int	i;
-
-	ahc = (struct ahc_softc *)arg;
-
-	/* This will reset most registers to 0, but not all */
-	ahc_reset(ahc);
-	ahc_outb(ahc, SCSISEQ, 0);
-	ahc_outb(ahc, SXFRCTL0, 0);
-	ahc_outb(ahc, DSPCISTATUS, 0);
-
-	for (i = TARG_SCSIRATE; i < HA_274_BIOSCTRL; i++)
-		ahc_outb(ahc, i, 0);
-}
-
-/*
- * Reset the controller and record some information about it
- * that is only availabel just after a reset.
- */
-int
-ahc_reset(struct ahc_softc *ahc)
-{
-	u_int	sblkctl;
-	u_int	sxfrctl1_a, sxfrctl1_b;
-	int	wait;
-	
-	/*
-	 * Preserve the value of the SXFRCTL1 register for all channels.
-	 * It contains settings that affect termination and we don't want
-	 * to disturb the integrity of the bus.
-	 */
-	ahc_pause(ahc);
-	sxfrctl1_b = 0;
-	if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
-		u_int sblkctl;
-
-		/*
-		 * Save channel B's settings in case this chip
-		 * is setup for TWIN channel operation.
-		 */
-		sblkctl = ahc_inb(ahc, SBLKCTL);
-		ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
-		sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
-		ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
-	}
-	sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
-
-	ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
-
-	/*
-	 * Ensure that the reset has finished
-	 */
-	wait = 1000;
-	do {
-		ahc_delay(1000);
-	} while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
-
-	if (wait == 0) {
-		printf("%s: WARNING - Failed chip reset!  "
-		       "Trying to initialize anyway.\n", ahc_name(ahc));
-	}
-	ahc_outb(ahc, HCNTRL, ahc->pause);
-
-	/* Determine channel configuration */
-	sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
-	/* No Twin Channel PCI cards */
-	if ((ahc->chip & AHC_PCI) != 0)
-		sblkctl &= ~SELBUSB;
-	switch (sblkctl) {
-	case 0:
-		/* Single Narrow Channel */
-		break;
-	case 2:
-		/* Wide Channel */
-		ahc->features |= AHC_WIDE;
-		break;
-	case 8:
-		/* Twin Channel */
-		ahc->features |= AHC_TWIN;
-		break;
-	default:
-		printf(" Unsupported adapter type.  Ignoring\n");
-		return(-1);
-	}
-
-	/*
-	 * Reload sxfrctl1.
-	 *
-	 * We must always initialize STPWEN to 1 before we
-	 * restore the saved values.  STPWEN is initialized
-	 * to a tri-state condition which can only be cleared
-	 * by turning it on.
-	 */
-	if ((ahc->features & AHC_TWIN) != 0) {
-		u_int sblkctl;
-
-		sblkctl = ahc_inb(ahc, SBLKCTL);
-		ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
-		ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
-		ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
-	}
-	ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
-
-#ifdef AHC_DUMP_SEQ
-	if (ahc->init_level == 0)
-		ahc_dumpseq(ahc);
-#endif
-
-	return (0);
-}
-
-/*
- * Determine the number of SCBs available on the controller
- */
-int
-ahc_probe_scbs(struct ahc_softc *ahc) {
-	int i;
-
-	for (i = 0; i < AHC_SCB_MAX; i++) {
-
-		ahc_outb(ahc, SCBPTR, i);
-		ahc_outb(ahc, SCB_BASE, i);
-		if (ahc_inb(ahc, SCB_BASE) != i)
-			break;
-		ahc_outb(ahc, SCBPTR, 0);
-		if (ahc_inb(ahc, SCB_BASE) != 0)
-			break;
-	}
-	return (i);
-}
-
-static void
-ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) 
-{
-	bus_addr_t *baddr;
-
-	baddr = (bus_addr_t *)arg;
-	*baddr = segs->ds_addr;
-}
-
-static void
-ahc_build_free_scb_list(struct ahc_softc *ahc)
-{
-	int i;
-
-	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
-		ahc_outb(ahc, SCBPTR, i);
-
-		/* Clear the control byte. */
-		ahc_outb(ahc, SCB_CONTROL, 0);
-
-		/* Set the next pointer */
-		if ((ahc->flags & AHC_PAGESCBS) != 0)
-			ahc_outb(ahc, SCB_NEXT, i+1);
-		else 
-			ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
-
-		/* Make the tag number invalid */
-		ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
-	}
-
-	/* Make sure that the last SCB terminates the free list */
-	ahc_outb(ahc, SCBPTR, i-1);
-	ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
-
-	/* Ensure we clear the 0 SCB's control byte. */
-	ahc_outb(ahc, SCBPTR, 0);
-	ahc_outb(ahc, SCB_CONTROL, 0);
-}
-
-static int
-ahc_init_scbdata(struct ahc_softc *ahc)
-{
-	struct scb_data *scb_data;
-
-	scb_data = ahc->scb_data;
-	SLIST_INIT(&scb_data->free_scbs);
-	SLIST_INIT(&scb_data->sg_maps);
-
-	/* Allocate SCB resources */
-	scb_data->scbarray =
-	    (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC,
-				 M_DEVBUF, M_NOWAIT);
-	if (scb_data->scbarray == NULL)
-		return (ENOMEM);
-	memset(scb_data->scbarray, 0, sizeof(struct scb) * AHC_SCB_MAX_ALLOC);
-
-	/* Determine the number of hardware SCBs and initialize them */
-
-	scb_data->maxhscbs = ahc_probe_scbs(ahc);
-	if ((ahc->flags & AHC_PAGESCBS) != 0) {
-		/* SCB 0 heads the free list */
-		ahc_outb(ahc, FREE_SCBH, 0);
-	} else {
-		ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
-	}
-
-	if (ahc->scb_data->maxhscbs == 0) {
-		printf("%s: No SCB space found\n", ahc_name(ahc));
-		return (ENXIO);
-	}
-
-	ahc_build_free_scb_list(ahc);
-
-	/*
-	 * Create our DMA tags.  These tags define the kinds of device
-	 * accessible memory allocations and memory mappings we will
-	 * need to perform during normal operation.
-	 *
-	 * Unless we need to further restrict the allocation, we rely
-	 * on the restrictions of the parent dmat, hence the common
-	 * use of MAXADDR and MAXSIZE.
-	 */
-
-	/* DMA tag for our hardware scb structures */
-	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
-			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
-			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
-			       /*highaddr*/BUS_SPACE_MAXADDR,
-			       /*filter*/NULL, /*filterarg*/NULL,
-			       AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
-			       /*nsegments*/1,
-			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
-			       /*flags*/0, &scb_data->hscb_dmat) != 0) {
-		goto error_exit;
-	}
-
-	scb_data->init_level++;
-
-	/* Allocation for our hscbs */
-	if (ahc_dmamem_alloc(ahc, scb_data->hscb_dmat,
-			     (void **)&scb_data->hscbs,
-			     BUS_DMA_NOWAIT, &scb_data->hscb_dmamap) != 0) {
-		goto error_exit;
-	}
-
-	scb_data->init_level++;
-
-	/* And permanently map them */
-	ahc_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,
-			scb_data->hscbs,
-			AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
-			ahc_dmamap_cb, &scb_data->hscb_busaddr, /*flags*/0);
-
-	scb_data->init_level++;
-
-	/* DMA tag for our sense buffers */
-	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
-			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
-			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
-			       /*highaddr*/BUS_SPACE_MAXADDR,
-			       /*filter*/NULL, /*filterarg*/NULL,
-			       AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
-			       /*nsegments*/1,
-			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
-			       /*flags*/0, &scb_data->sense_dmat) != 0) {
-		goto error_exit;
-	}
-
-	scb_data->init_level++;
-
-	/* Allocate them */
-	if (ahc_dmamem_alloc(ahc, scb_data->sense_dmat,
-			     (void **)&scb_data->sense,
-			     BUS_DMA_NOWAIT, &scb_data->sense_dmamap) != 0) {
-		goto error_exit;
-	}
-
-	scb_data->init_level++;
-
-	/* And permanently map them */
-	ahc_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,
-			scb_data->sense,
-			AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
-			ahc_dmamap_cb, &scb_data->sense_busaddr, /*flags*/0);
-
-	scb_data->init_level++;
-
-	/* DMA tag for our S/G structures.  We allocate in page sized chunks */
-	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
-			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
-			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
-			       /*highaddr*/BUS_SPACE_MAXADDR,
-			       /*filter*/NULL, /*filterarg*/NULL,
-			       PAGE_SIZE, /*nsegments*/1,
-			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
-			       /*flags*/0, &scb_data->sg_dmat) != 0) {
-		goto error_exit;
-	}
-
-	scb_data->init_level++;
-
-	/* Perform initial CCB allocation */
-	memset(scb_data->hscbs, 0,
-	       AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));
-	ahc_alloc_scbs(ahc);
-
-	if (scb_data->numscbs == 0) {
-		printf("%s: ahc_init_scbdata - "
-		       "Unable to allocate initial scbs\n",
-		       ahc_name(ahc));
-		goto error_exit;
-	}
-
-	/*
-	 * Tell the sequencer which SCB will be the next one it receives.
-	 */
-	ahc->next_queued_scb = ahc_get_scb(ahc);
-	ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
-
-	/*
-	 * Note that we were successfull
-	 */
-	return (0); 
-
-error_exit:
-
-	return (ENOMEM);
-}
-
-static void
-ahc_fini_scbdata(struct ahc_softc *ahc)
-{
-	struct scb_data *scb_data;
-
-	scb_data = ahc->scb_data;
-	if (scb_data == NULL)
-		return;
-
-	switch (scb_data->init_level) {
-	default:
-	case 7:
-	{
-		struct sg_map_node *sg_map;
-
-		while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
-			SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
-			ahc_dmamap_unload(ahc, scb_data->sg_dmat,
-					  sg_map->sg_dmamap);
-			ahc_dmamem_free(ahc, scb_data->sg_dmat,
-					sg_map->sg_vaddr,
-					sg_map->sg_dmamap);
-			free(sg_map, M_DEVBUF);
-		}
-		ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);
-	}
-	case 6:
-		ahc_dmamap_unload(ahc, scb_data->sense_dmat,
-				  scb_data->sense_dmamap);
-	case 5:
-		ahc_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,
-				scb_data->sense_dmamap);
-		ahc_dmamap_destroy(ahc, scb_data->sense_dmat,
-				   scb_data->sense_dmamap);
-	case 4:
-		ahc_dma_tag_destroy(ahc, scb_data->sense_dmat);
-	case 3:
-		ahc_dmamap_unload(ahc, scb_data->hscb_dmat,
-				  scb_data->hscb_dmamap);
-	case 2:
-		ahc_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,
-				scb_data->hscb_dmamap);
-		ahc_dmamap_destroy(ahc, scb_data->hscb_dmat,
-				   scb_data->hscb_dmamap);
-	case 1:
-		ahc_dma_tag_destroy(ahc, scb_data->hscb_dmat);
-		break;
-	case 0:
-		break;
-	}
-	if (scb_data->scbarray != NULL)
-		free(scb_data->scbarray, M_DEVBUF);
-}
-
-void
-ahc_alloc_scbs(struct ahc_softc *ahc)
-{
-	struct scb_data *scb_data;
-	struct scb *next_scb;
-	struct sg_map_node *sg_map;
-	bus_addr_t physaddr;
-	struct ahc_dma_seg *segs;
-	int newcount;
-	int i;
-
-	scb_data = ahc->scb_data;
-	if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)
-		/* Can't allocate any more */
-		return;
-
-	next_scb = &scb_data->scbarray[scb_data->numscbs];
-
-	sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
-
-	if (sg_map == NULL)
-		return;
-
-	/* Allocate S/G space for the next batch of SCBS */
-	if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,
-			     (void **)&sg_map->sg_vaddr,
-			     BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
-		free(sg_map, M_DEVBUF);
-		return;
-	}
-
-	SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
-
-	ahc_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,
-			sg_map->sg_vaddr, PAGE_SIZE, ahc_dmamap_cb,
-			&sg_map->sg_physaddr, /*flags*/0);
-
-	segs = sg_map->sg_vaddr;
-	physaddr = sg_map->sg_physaddr;
-
-	newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
-	newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
-	for (i = 0; i < newcount; i++) {
-		struct scb_platform_data *pdata;
-#ifndef __linux__
-		int error;
-#endif
-		pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
-							   M_DEVBUF, M_NOWAIT);
-		if (pdata == NULL)
-			break;
-		next_scb->platform_data = pdata;
-		next_scb->sg_map = sg_map;
-		next_scb->sg_list = segs;
-		/*
-		 * The sequencer always starts with the second entry.
-		 * The first entry is embedded in the scb.
-		 */
-		next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
-		next_scb->ahc_softc = ahc;
-		next_scb->flags = SCB_FREE;
-#ifndef __linux__
-		error = ahc_dmamap_create(ahc, ahc->buffer_dmat, /*flags*/0,
-					  &next_scb->dmamap);
-		if (error != 0)
-			break;
-#endif
-		next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
-		next_scb->hscb->tag = ahc->scb_data->numscbs;
-		SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
-				  next_scb, links.sle);
-		segs += AHC_NSEG;
-		physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
-		next_scb++;
-		ahc->scb_data->numscbs++;
-	}
-}
-
-void
-ahc_controller_info(struct ahc_softc *ahc, char *buf)
-{
-	int len;
-
-	len = sprintf(buf, "%s: ", ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
-	buf += len;
-	if ((ahc->features & AHC_TWIN) != 0)
- 		len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
-			      "B SCSI Id=%d, primary %c, ",
-			      ahc->our_id, ahc->our_id_b,
-			      (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
-	else {
-		const char *speed;
-		const char *type;
-
-		speed = "";
-		if ((ahc->features & AHC_ULTRA) != 0) {
-			speed = "Ultra ";
-		} else if ((ahc->features & AHC_DT) != 0) {
-			speed = "Ultra160 ";
-		} else if ((ahc->features & AHC_ULTRA2) != 0) {
-			speed = "Ultra2 ";
-		}
-		if ((ahc->features & AHC_WIDE) != 0) {
-			type = "Wide";
-		} else {
-			type = "Single";
-		}
-		len = sprintf(buf, "%s%s Channel %c, SCSI Id=%d, ",
-			      speed, type, ahc->channel, ahc->our_id);
-	}
-	buf += len;
-
-	if ((ahc->flags & AHC_PAGESCBS) != 0)
-		sprintf(buf, "%d/%d SCBs",
-			ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);
-	else
-		sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);
-}
-
-/*
- * Start the board, ready for normal operation
- */
-int
-ahc_init(struct ahc_softc *ahc)
-{
-	int	 max_targ;
-	int	 i;
-	int	 term;
-	u_int	 scsi_conf;
-	u_int	 scsiseq_template;
-	u_int	 ultraenb;
-	u_int	 discenable;
-	u_int	 tagenable;
-	size_t	 driver_data_size;
-	uint32_t physaddr;
-
-#ifdef AHC_DEBUG_SEQUENCER
-	ahc->flags |= AHC_SEQUENCER_DEBUG;
-#endif
-
-#ifdef AHC_PRINT_SRAM
-	printf("Scratch Ram:");
-	for (i = 0x20; i < 0x5f; i++) {
-		if (((i % 8) == 0) && (i != 0)) {
-			printf ("\n              ");
-		}
-		printf (" 0x%x", ahc_inb(ahc, i));
-	}
-	if ((ahc->features & AHC_MORE_SRAM) != 0) {
-		for (i = 0x70; i < 0x7f; i++) {
-			if (((i % 8) == 0) && (i != 0)) {
-				printf ("\n              ");
-			}
-			printf (" 0x%x", ahc_inb(ahc, i));
-		}
-	}
-	printf ("\n");
-#endif
-	max_targ = 15;
-
-	/*
-	 * Assume we have a board at this stage and it has been reset.
-	 */
-	if ((ahc->flags & AHC_USEDEFAULTS) != 0)
-		ahc->our_id = ahc->our_id_b = 7;
-	
-	/*
-	 * Default to allowing initiator operations.
-	 */
-	ahc->flags |= AHC_INITIATORROLE;
-
-	/*
-	 * Only allow target mode features if this unit has them enabled.
-	 */
-	if ((AHC_TMODE_ENABLE & (0x1 << ahc->unit)) == 0)
-		ahc->features &= ~AHC_TARGETMODE;
-
-#ifndef __linux__
-	/* DMA tag for mapping buffers into device visible space. */
-	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
-			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
-			       /*lowaddr*/BUS_SPACE_MAXADDR,
-			       /*highaddr*/BUS_SPACE_MAXADDR,
-			       /*filter*/NULL, /*filterarg*/NULL,
-			       /*maxsize*/MAXBSIZE, /*nsegments*/AHC_NSEG,
-			       /*maxsegsz*/AHC_MAXTRANSFER_SIZE,
-			       /*flags*/BUS_DMA_ALLOCNOW,
-			       &ahc->buffer_dmat) != 0) {
-		return (ENOMEM);
-	}
-#endif
-
-	ahc->init_level++;
-
-	/*
-	 * DMA tag for our command fifos and other data in system memory
-	 * the card's sequencer must be able to access.  For initiator
-	 * roles, we need to allocate space for the the qinfifo and qoutfifo.
-	 * The qinfifo and qoutfifo are composed of 256 1 byte elements. 
-	 * When providing for the target mode role, we must additionally
-	 * provide space for the incoming target command fifo and an extra
-	 * byte to deal with a dma bug in some chip versions.
-	 */
-	driver_data_size = 2 * 256 * sizeof(uint8_t);
-	if ((ahc->features & AHC_TARGETMODE) != 0)
-		driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
-				 + /*DMA WideOdd Bug Buffer*/1;
-	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
-			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
-			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
-			       /*highaddr*/BUS_SPACE_MAXADDR,
-			       /*filter*/NULL, /*filterarg*/NULL,
-			       driver_data_size,
-			       /*nsegments*/1,
-			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
-			       /*flags*/0, &ahc->shared_data_dmat) != 0) {
-		return (ENOMEM);
-	}
-
-	ahc->init_level++;
-
-	/* Allocation of driver data */
-	if (ahc_dmamem_alloc(ahc, ahc->shared_data_dmat,
-			     (void **)&ahc->qoutfifo,
-			     BUS_DMA_NOWAIT, &ahc->shared_data_dmamap) != 0) {
-		return (ENOMEM);
-	}
-
-	ahc->init_level++;
-
-	/* And permanently map it in */
-	ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
-			ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
-			&ahc->shared_data_busaddr, /*flags*/0);
-
-	if ((ahc->features & AHC_TARGETMODE) != 0) {
-		ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
-		ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
-		ahc->dma_bug_buf = ahc->shared_data_busaddr
-				 + driver_data_size - 1;
-		/* All target command blocks start out invalid. */
-		for (i = 0; i < AHC_TMODE_CMDS; i++)
-			ahc->targetcmds[i].cmd_valid = 0;
-		ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);
-		ahc->tqinfifonext = 1;
-		ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
-		ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
-		ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
-	}
-	ahc->qinfifo = &ahc->qoutfifo[256];
-
-	ahc->init_level++;
-
-	/* Allocate SCB data now that buffer_dmat is initialized */
-	if (ahc->scb_data->maxhscbs == 0)
-		if (ahc_init_scbdata(ahc) != 0)
-			return (ENOMEM);
-
-	/*
-	 * Allocate a tstate to house information for our
-	 * initiator presence on the bus as well as the user
-	 * data for any target mode initiator.
-	 */
-	if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
-		printf("%s: unable to allocate ahc_tmode_tstate.  "
-		       "Failing attach\n", ahc_name(ahc));
-		return (ENOMEM);
-	}
-
-	if ((ahc->features & AHC_TWIN) != 0) {
-		if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
-			printf("%s: unable to allocate ahc_tmode_tstate.  "
-			       "Failing attach\n", ahc_name(ahc));
-			return (ENOMEM);
-		}
-	}
-
-	ahc_outb(ahc, SEQ_FLAGS, 0);
-	ahc_outb(ahc, SEQ_FLAGS2, 0);
-
-	if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
-		ahc->flags |= AHC_PAGESCBS;
-	} else {
-		ahc->flags &= ~AHC_PAGESCBS;
-	}
-
-#ifdef AHC_DEBUG
-	if (ahc_debug & AHC_SHOWMISC) {
-		printf("%s: hardware scb %d bytes; kernel scb %d bytes; "
-		       "ahc_dma %d bytes\n",
-			ahc_name(ahc),
-			sizeof(struct hardware_scb),
-			sizeof(struct scb),
-			sizeof(struct ahc_dma_seg));
-	}
-#endif /* AHC_DEBUG */
-
-	/* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/
-	if (ahc->features & AHC_TWIN) {
-
-		/*
-		 * The device is gated to channel B after a chip reset,
-		 * so set those values first
-		 */
-		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
-		term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
-		ahc_outb(ahc, SCSIID, ahc->our_id_b);
-		scsi_conf = ahc_inb(ahc, SCSICONF + 1);
-		ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
-					|term|ahc->seltime_b|ENSTIMER|ACTNEGEN);
-		if ((ahc->features & AHC_ULTRA2) != 0)
-			ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
-		ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
-		ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
-
-		if ((scsi_conf & RESET_SCSI) != 0
-		 && (ahc->flags & AHC_INITIATORROLE) != 0)
-			ahc->flags |= AHC_RESET_BUS_B;
-
-		/* Select Channel A */
-		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
-	}
-	term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
-	else
-		ahc_outb(ahc, SCSIID, ahc->our_id);
-	scsi_conf = ahc_inb(ahc, SCSICONF);
-	ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
-				|term|ahc->seltime
-				|ENSTIMER|ACTNEGEN);
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
-	ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
-	ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
-
-	if ((scsi_conf & RESET_SCSI) != 0
-	 && (ahc->flags & AHC_INITIATORROLE) != 0)
-		ahc->flags |= AHC_RESET_BUS_A;
-
-	/*
-	 * Look at the information that board initialization or
-	 * the board bios has left us.
-	 */
-	ultraenb = 0;	
-	tagenable = ALL_TARGETS_MASK;
-
-	/* Grab the disconnection disable table and invert it for our needs */
-	if (ahc->flags & AHC_USEDEFAULTS) {
-		printf("%s: Host Adapter Bios disabled.  Using default SCSI "
-			"device parameters\n", ahc_name(ahc));
-		ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
-			      AHC_TERM_ENB_A|AHC_TERM_ENB_B;
-		discenable = ALL_TARGETS_MASK;
-		if ((ahc->features & AHC_ULTRA) != 0)
-			ultraenb = ALL_TARGETS_MASK;
-	} else {
-		discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)
-			   | ahc_inb(ahc, DISC_DSB));
-		if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)
-			ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
-				      | ahc_inb(ahc, ULTRA_ENB);
-	}
-
-	if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
-		max_targ = 7;
-
-	for (i = 0; i <= max_targ; i++) {
-		struct ahc_initiator_tinfo *tinfo;
-		struct ahc_tmode_tstate *tstate;
-		u_int our_id;
-		u_int target_id;
-		char channel;
-
-		channel = 'A';
-		our_id = ahc->our_id;
-		target_id = i;
-		if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
-			channel = 'B';
-			our_id = ahc->our_id_b;
-			target_id = i % 8;
-		}
-		tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
-					    target_id, &tstate);
-		/* Default to async narrow across the board */
-		memset(tinfo, 0, sizeof(*tinfo));
-		if (ahc->flags & AHC_USEDEFAULTS) {
-			if ((ahc->features & AHC_WIDE) != 0)
-				tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
-
-			/*
-			 * These will be truncated when we determine the
-			 * connection type we have with the target.
-			 */
-			tinfo->user.period = ahc_syncrates->period;
-			tinfo->user.offset = ~0;
-		} else {
-			u_int scsirate;
-			uint16_t mask;
-
-			/* Take the settings leftover in scratch RAM. */
-			scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);
-			mask = (0x01 << i);
-			if ((ahc->features & AHC_ULTRA2) != 0) {
-				u_int offset;
-				u_int maxsync;
-
-				if ((scsirate & SOFS) == 0x0F) {
-					/*
-					 * Haven't negotiated yet,
-					 * so the format is different.
-					 */
-					scsirate = (scsirate & SXFR) >> 4
-						 | (ultraenb & mask)
-						  ? 0x08 : 0x0
-						 | (scsirate & WIDEXFER);
-					offset = MAX_OFFSET_ULTRA2;
-				} else
-					offset = ahc_inb(ahc, TARG_OFFSET + i);
-				if ((scsirate & ~WIDEXFER) == 0 && offset != 0)
-					/* Set to the lowest sync rate, 5MHz */
-					scsirate |= 0x1c;
-				maxsync = AHC_SYNCRATE_ULTRA2;
-				if ((ahc->features & AHC_DT) != 0)
-					maxsync = AHC_SYNCRATE_DT;
-				tinfo->user.period =
-				    ahc_find_period(ahc, scsirate, maxsync);
-				if (offset == 0)
-					tinfo->user.period = 0;
-				else
-					tinfo->user.offset = ~0;
-				if ((scsirate & SXFR_ULTRA2) <= 8/*10MHz*/
-				 && (ahc->features & AHC_DT) != 0)
-					tinfo->user.ppr_options =
-					    MSG_EXT_PPR_DT_REQ;
-			} else if ((scsirate & SOFS) != 0) {
-				if ((scsirate & SXFR) == 0x40
-				 && (ultraenb & mask) != 0) {
-					/* Treat 10MHz as a non-ultra speed */
-					scsirate &= ~SXFR;
-				 	ultraenb &= ~mask;
-				}
-				tinfo->user.period = 
-				    ahc_find_period(ahc, scsirate,
-						    (ultraenb & mask)
-						   ? AHC_SYNCRATE_ULTRA
-						   : AHC_SYNCRATE_FAST);
-				if (tinfo->user.period != 0)
-					tinfo->user.offset = ~0;
-			}
-			if (tinfo->user.period == 0)
-				tinfo->user.offset = 0;
-			if ((scsirate & WIDEXFER) != 0
-			 && (ahc->features & AHC_WIDE) != 0)
-				tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
-			tinfo->user.protocol_version = 4;
-			if ((ahc->features & AHC_DT) != 0)
-				tinfo->user.transport_version = 3;
-			else
-				tinfo->user.transport_version = 2;
-			tinfo->goal.protocol_version = 2;
-			tinfo->goal.transport_version = 2;
-			tinfo->curr.protocol_version = 2;
-			tinfo->curr.transport_version = 2;
-		}
-		tstate->ultraenb = ultraenb;
-	}
-	ahc->user_discenable = discenable;
-	ahc->user_tagenable = tagenable;
-
-	/* There are no untagged SCBs active yet. */
-	for (i = 0; i < 16; i++) {
-		ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
-		if ((ahc->flags & AHC_SCB_BTT) != 0) {
-			int lun;
-
-			/*
-			 * The SCB based BTT allows an entry per
-			 * target and lun pair.
-			 */
-			for (lun = 1; lun < AHC_NUM_LUNS; lun++)
-				ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));
-		}
-	}
-
-	/* All of our queues are empty */
-	for (i = 0; i < 256; i++)
-		ahc->qoutfifo[i] = SCB_LIST_NULL;
-	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);
-
-	for (i = 0; i < 256; i++)
-		ahc->qinfifo[i] = SCB_LIST_NULL;
-
-	if ((ahc->features & AHC_MULTI_TID) != 0) {
-		ahc_outb(ahc, TARGID, 0);
-		ahc_outb(ahc, TARGID + 1, 0);
-	}
-
-	/*
-	 * Tell the sequencer where it can find our arrays in memory.
-	 */
-	physaddr = ahc->scb_data->hscb_busaddr;
-	ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
-	ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
-	ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
-	ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
-
-	physaddr = ahc->shared_data_busaddr;
-	ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);
-	ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);
-	ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);
-	ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);
-
-	/*
-	 * Initialize the group code to command length table.
-	 * This overrides the values in TARG_SCSIRATE, so only
-	 * setup the table after we have processed that information.
-	 */
-	ahc_outb(ahc, CMDSIZE_TABLE, 5);
-	ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
-	ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
-	ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
-	ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
-	ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
-	ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
-	ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
-		
-	/* Tell the sequencer of our initial queue positions */
-	ahc_outb(ahc, KERNEL_QINPOS, 0);
-	ahc_outb(ahc, QINPOS, 0);
-	ahc_outb(ahc, QOUTPOS, 0);
-
-	/*
-	 * Use the built in queue management registers
-	 * if they are available.
-	 */
-	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
-		ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
-		ahc_outb(ahc, SDSCB_QOFF, 0);
-		ahc_outb(ahc, SNSCB_QOFF, 0);
-		ahc_outb(ahc, HNSCB_QOFF, 0);
-	}
-
-
-	/* We don't have any waiting selections */
-	ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
-
-	/* Our disconnection list is empty too */
-	ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
-
-	/* Message out buffer starts empty */
-	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
-
-	/*
-	 * Setup the allowed SCSI Sequences based on operational mode.
-	 * If we are a target, we'll enalbe select in operations once
-	 * we've had a lun enabled.
-	 */
-	scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
-	if ((ahc->flags & AHC_INITIATORROLE) != 0)
-		scsiseq_template |= ENRSELI;
-	ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
-
-	/*
-	 * Load the Sequencer program and Enable the adapter
-	 * in "fast" mode.
-	 */
-	if (bootverbose)
-		printf("%s: Downloading Sequencer Program...",
-		       ahc_name(ahc));
-
-	ahc_loadseq(ahc);
-
-	if ((ahc->features & AHC_ULTRA2) != 0) {
-		int wait;
-
-		/*
-		 * Wait for up to 500ms for our transceivers
-		 * to settle.  If the adapter does not have
-		 * a cable attached, the tranceivers may
-		 * never settle, so don't complain if we
-		 * fail here.
-		 */
-		ahc_pause(ahc);
-		for (wait = 5000;
-		     (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
-		     wait--)
-			ahc_delay(100);
-		ahc_unpause(ahc);
-	}
-	return (0);
-}
-
-void
-ahc_intr_enable(struct ahc_softc *ahc, int enable)
-{
-	u_int hcntrl;
-
-	hcntrl = ahc_inb(ahc, HCNTRL);
-	hcntrl &= ~INTEN;
-	ahc->pause &= ~INTEN;
-	ahc->unpause &= ~INTEN;
-	if (enable) {
-		hcntrl |= INTEN;
-		ahc->pause |= INTEN;
-		ahc->unpause |= INTEN;
-	}
-	ahc_outb(ahc, HCNTRL, hcntrl);
-}
-
-/*
- * Ensure that the card is paused in a location
- * outside of all critical sections and that all
- * pending work is completed prior to returning.
- * This routine should only be called from outside
- * an interrupt context.
- */
-void
-ahc_pause_and_flushwork(struct ahc_softc *ahc)
-{
-	int intstat;
-	int maxloops;
-
-	maxloops = 1000;
-	ahc->flags |= AHC_ALL_INTERRUPTS;
-	intstat = 0;
-	do {
-		ahc_intr(ahc);
-		ahc_pause(ahc);
-		ahc_clear_critical_section(ahc);
-		if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0)
-			break;
-		maxloops--;
-	} while (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) && --maxloops);
-	if (maxloops == 0) {
-		printf("Infinite interrupt loop, INTSTAT = %x",
-		      ahc_inb(ahc, INTSTAT));
-	}
-	ahc_platform_flushwork(ahc);
-	ahc->flags &= ~AHC_ALL_INTERRUPTS;
-}
-
-int
-ahc_suspend(struct ahc_softc *ahc)
-{
-	uint8_t *ptr;
-	int	 i;
-
-	ahc_pause_and_flushwork(ahc);
-
-	if (LIST_FIRST(&ahc->pending_scbs) != NULL)
-		return (EBUSY);
-
-#if AHC_TARGET_MODE
-	/*
-	 * XXX What about ATIOs that have not yet been serviced?
-	 * Perhaps we should just refuse to be suspended if we
-	 * are acting in a target role.
-	 */
-	if (ahc->pending_device != NULL)
-		return (EBUSY);
-#endif
-
-	/* Save volatile registers */
-	if ((ahc->features & AHC_TWIN) != 0) {
-		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
-		ahc->suspend_state.channel[1].scsiseq = ahc_inb(ahc, SCSISEQ);
-		ahc->suspend_state.channel[1].sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
-		ahc->suspend_state.channel[1].sxfrctl1 = ahc_inb(ahc, SXFRCTL1);
-		ahc->suspend_state.channel[1].simode0 = ahc_inb(ahc, SIMODE0);
-		ahc->suspend_state.channel[1].simode1 = ahc_inb(ahc, SIMODE1);
-		ahc->suspend_state.channel[1].seltimer = ahc_inb(ahc, SELTIMER);
-		ahc->suspend_state.channel[1].seqctl = ahc_inb(ahc, SEQCTL);
-		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
-	}
-	ahc->suspend_state.channel[0].scsiseq = ahc_inb(ahc, SCSISEQ);
-	ahc->suspend_state.channel[0].sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
-	ahc->suspend_state.channel[0].sxfrctl1 = ahc_inb(ahc, SXFRCTL1);
-	ahc->suspend_state.channel[0].simode0 = ahc_inb(ahc, SIMODE0);
-	ahc->suspend_state.channel[0].simode1 = ahc_inb(ahc, SIMODE1);
-	ahc->suspend_state.channel[0].seltimer = ahc_inb(ahc, SELTIMER);
-	ahc->suspend_state.channel[0].seqctl = ahc_inb(ahc, SEQCTL);
-
-	if ((ahc->chip & AHC_PCI) != 0) {
-		ahc->suspend_state.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
-		ahc->suspend_state.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
-	}
-
-	if ((ahc->features & AHC_DT) != 0) {
-		u_int sfunct;
-
-		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
-		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
-		ahc->suspend_state.optionmode = ahc_inb(ahc, OPTIONMODE);
-		ahc_outb(ahc, SFUNCT, sfunct);
-		ahc->suspend_state.crccontrol1 = ahc_inb(ahc, CRCCONTROL1);
-	}
-
-	if ((ahc->features & AHC_MULTI_FUNC) != 0)
-		ahc->suspend_state.scbbaddr = ahc_inb(ahc, SCBBADDR);
-
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		ahc->suspend_state.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
-
-	ptr = ahc->suspend_state.scratch_ram;
-	for (i = 0; i < 64; i++)
-		*ptr++ = ahc_inb(ahc, SRAM_BASE + i);
-
-	if ((ahc->features & AHC_MORE_SRAM) != 0) {
-		for (i = 0; i < 16; i++)
-			*ptr++ = ahc_inb(ahc, TARG_OFFSET + i);
-	}
-
-	ptr = ahc->suspend_state.btt;
-	if ((ahc->flags & AHC_SCB_BTT) != 0) {
-		for (i = 0;i < AHC_NUM_TARGETS; i++) {
-			int j;
-
-			for (j = 0;j < AHC_NUM_LUNS; j++) {
-				u_int tcl;
-
-				tcl = BUILD_TCL(i << 4, j);
-				*ptr = ahc_index_busy_tcl(ahc, tcl);
-			}
-		}
-	}
-	ahc_shutdown(ahc);
-	return (0);
-}
-
-int
-ahc_resume(struct ahc_softc *ahc)
-{
-	uint8_t *ptr;
-	int	 i;
-
-	ahc_reset(ahc);
-
-	ahc_build_free_scb_list(ahc);
-
-	/* Restore volatile registers */
-	if ((ahc->features & AHC_TWIN) != 0) {
-		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
-		ahc_outb(ahc, SCSIID, ahc->our_id);
-		ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[1].scsiseq);
-		ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[1].sxfrctl0);
-		ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[1].sxfrctl1);
-		ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[1].simode0);
-		ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[1].simode1);
-		ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[1].seltimer);
-		ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[1].seqctl);
-		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
-	}
-	ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[0].scsiseq);
-	ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[0].sxfrctl0);
-	ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[0].sxfrctl1);
-	ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[0].simode0);
-	ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[0].simode1);
-	ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[0].seltimer);
-	ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[0].seqctl);
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
-	else
-		ahc_outb(ahc, SCSIID, ahc->our_id);
-
-	if ((ahc->chip & AHC_PCI) != 0) {
-		ahc_outb(ahc, DSCOMMAND0, ahc->suspend_state.dscommand0);
-		ahc_outb(ahc, DSPCISTATUS, ahc->suspend_state.dspcistatus);
-	}
-
-	if ((ahc->features & AHC_DT) != 0) {
-		u_int sfunct;
-
-		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
-		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
-		ahc_outb(ahc, OPTIONMODE, ahc->suspend_state.optionmode);
-		ahc_outb(ahc, SFUNCT, sfunct);
-		ahc_outb(ahc, CRCCONTROL1, ahc->suspend_state.crccontrol1);
-	}
-
-	if ((ahc->features & AHC_MULTI_FUNC) != 0)
-		ahc_outb(ahc, SCBBADDR, ahc->suspend_state.scbbaddr);
-
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		ahc_outb(ahc, DFF_THRSH, ahc->suspend_state.dff_thrsh);
-
-	ptr = ahc->suspend_state.scratch_ram;
-	for (i = 0; i < 64; i++)
-		ahc_outb(ahc, SRAM_BASE + i, *ptr++);
-
-	if ((ahc->features & AHC_MORE_SRAM) != 0) {
-		for (i = 0; i < 16; i++)
-			ahc_outb(ahc, TARG_OFFSET + i, *ptr++);
-	}
-
-	ptr = ahc->suspend_state.btt;
-	if ((ahc->flags & AHC_SCB_BTT) != 0) {
-		for (i = 0;i < AHC_NUM_TARGETS; i++) {
-			int j;
-
-			for (j = 0;j < AHC_NUM_LUNS; j++) {
-				u_int tcl;
-
-				tcl = BUILD_TCL(i << 4, j);
-				ahc_busy_tcl(ahc, tcl, *ptr);
-			}
-		}
-	}
-	return (0);
-}
-
-/************************** Busy Target Table *********************************/
-/*
- * Return the untagged transaction id for a given target/channel lun.
- * Optionally, clear the entry.
- */
-u_int
-ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
-{
-	u_int scbid;
-	u_int target_offset;
-
-	if ((ahc->flags & AHC_SCB_BTT) != 0) {
-		u_int saved_scbptr;
-		
-		saved_scbptr = ahc_inb(ahc, SCBPTR);
-		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
-		scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
-		ahc_outb(ahc, SCBPTR, saved_scbptr);
-	} else {
-		target_offset = TCL_TARGET_OFFSET(tcl);
-		scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
-	}
-
-	return (scbid);
-}
-
-void
-ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
-{
-	u_int target_offset;
-
-	if ((ahc->flags & AHC_SCB_BTT) != 0) {
-		u_int saved_scbptr;
-		
-		saved_scbptr = ahc_inb(ahc, SCBPTR);
-		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
-		ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
-		ahc_outb(ahc, SCBPTR, saved_scbptr);
-	} else {
-		target_offset = TCL_TARGET_OFFSET(tcl);
-		ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
-	}
-}
-
-void
-ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
-{
-	u_int target_offset;
-
-	if ((ahc->flags & AHC_SCB_BTT) != 0) {
-		u_int saved_scbptr;
-		
-		saved_scbptr = ahc_inb(ahc, SCBPTR);
-		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
-		ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
-		ahc_outb(ahc, SCBPTR, saved_scbptr);
-	} else {
-		target_offset = TCL_TARGET_OFFSET(tcl);
-		ahc_outb(ahc, BUSY_TARGETS + target_offset, scbid);
-	}
-}
-
-/************************** SCB and SCB queue management **********************/
-int
-ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,
-	      char channel, int lun, u_int tag, role_t role)
-{
-	int targ = SCB_GET_TARGET(ahc, scb);
-	char chan = SCB_GET_CHANNEL(ahc, scb);
-	int slun = SCB_GET_LUN(scb);
-	int match;
-
-	match = ((chan == channel) || (channel == ALL_CHANNELS));
-	if (match != 0)
-		match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
-	if (match != 0)
-		match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
-	if (match != 0) {
-#if AHC_TARGET_MODE
-		int group;
-
-		group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
-		if (role == ROLE_INITIATOR) {
-			match = (group != XPT_FC_GROUP_TMODE)
-			      && ((tag == scb->hscb->tag)
-			       || (tag == SCB_LIST_NULL));
-		} else if (role == ROLE_TARGET) {
-			match = (group == XPT_FC_GROUP_TMODE)
-			      && ((tag == scb->io_ctx->csio.tag_id)
-			       || (tag == SCB_LIST_NULL));
-		}
-#else /* !AHC_TARGET_MODE */
-		match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
-#endif /* AHC_TARGET_MODE */
-	}
-
-	return match;
-}
-
-void
-ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
-{
-	int	target;
-	char	channel;
-	int	lun;
-
-	target = SCB_GET_TARGET(ahc, scb);
-	lun = SCB_GET_LUN(scb);
-	channel = SCB_GET_CHANNEL(ahc, scb);
-	
-	ahc_search_qinfifo(ahc, target, channel, lun,
-			   /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
-			   CAM_REQUEUE_REQ, SEARCH_COMPLETE);
-
-	ahc_platform_freeze_devq(ahc, scb);
-}
-
-void
-ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb)
-{
-	struct scb *prev_scb;
-
-	prev_scb = NULL;
-	if (ahc_qinfifo_count(ahc) != 0) {
-		u_int prev_tag;
-		uint8_t prev_pos;
-
-		prev_pos = ahc->qinfifonext - 1;
-		prev_tag = ahc->qinfifo[prev_pos];
-		prev_scb = ahc_lookup_scb(ahc, prev_tag);
-	}
-	ahc_qinfifo_requeue(ahc, prev_scb, scb);
-	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
-		ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
-	} else {
-		ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
-	}
-}
-
-static void
-ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,
-		    struct scb *scb)
-{
-	if (prev_scb == NULL) {
-		ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
-	} else {
-		prev_scb->hscb->next = scb->hscb->tag;
-		ahc_sync_scb(ahc, prev_scb, 
-			     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-	}
-	ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
-	scb->hscb->next = ahc->next_queued_scb->hscb->tag;
-	ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-}
-
-static int
-ahc_qinfifo_count(struct ahc_softc *ahc)
-{
-	u_int8_t qinpos;
-	u_int8_t diff;
-
-	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
-		qinpos = ahc_inb(ahc, SNSCB_QOFF);
-		ahc_outb(ahc, SNSCB_QOFF, qinpos);
-	} else
-		qinpos = ahc_inb(ahc, QINPOS);
-	diff = ahc->qinfifonext - qinpos;
-	return (diff);
-}
-
-int
-ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
-		   int lun, u_int tag, role_t role, uint32_t status,
-		   ahc_search_action action)
-{
-	struct	scb *scb;
-	struct	scb *prev_scb;
-	uint8_t qinstart;
-	uint8_t qinpos;
-	uint8_t qintail;
-	uint8_t next, prev;
-	uint8_t curscbptr;
-	int	found;
-	int	maxtarget;
-	int	i;
-	int	have_qregs;
-
-	qintail = ahc->qinfifonext;
-	have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
-	if (have_qregs) {
-		qinstart = ahc_inb(ahc, SNSCB_QOFF);
-		ahc_outb(ahc, SNSCB_QOFF, qinstart);
-	} else
-		qinstart = ahc_inb(ahc, QINPOS);
-	qinpos = qinstart;
-	next = ahc_inb(ahc, NEXT_QUEUED_SCB);
-	found = 0;
-	prev_scb = NULL;
-
-	if (action == SEARCH_COMPLETE) {
-		/*
-		 * Don't attempt to run any queued untagged transactions
-		 * until we are done with the abort process.
-		 */
-		ahc_freeze_untagged_queues(ahc);
-	}
-
-	/*
-	 * Start with an empty queue.  Entries that are not chosen
-	 * for removal will be re-added to the queue as we go.
-	 */
-	ahc->qinfifonext = qinpos;
-	ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
-
-	while (qinpos != qintail) {
-		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
-		if (scb == NULL) {
-			printf("qinpos = %d, SCB index = %d\n",
-				qinpos, ahc->qinfifo[qinpos]);
-			panic("Loop 1\n");
-		}
-
-		if (ahc_match_scb(ahc, scb, target, channel, lun, tag, role)) {
-			/*
-			 * We found an scb that needs to be acted on.
-			 */
-			found++;
-			switch (action) {
-			case SEARCH_COMPLETE:
-			{
-				cam_status ostat;
-				cam_status cstat;
-
-				ostat = ahc_get_transaction_status(scb);
-				if (ostat == CAM_REQ_INPROG)
-					ahc_set_transaction_status(scb,
-								   status);
-				cstat = ahc_get_transaction_status(scb);
-				if (cstat != CAM_REQ_CMP)
-					ahc_freeze_scb(scb);
-				if ((scb->flags & SCB_ACTIVE) == 0)
-					printf("Inactive SCB in qinfifo\n");
-				ahc_done(ahc, scb);
-
-				/* FALLTHROUGH */
-			case SEARCH_REMOVE:
-				break;
-			}
-			case SEARCH_COUNT:
-				ahc_qinfifo_requeue(ahc, prev_scb, scb);
-				prev_scb = scb;
-				break;
-			}
-		} else {
-			ahc_qinfifo_requeue(ahc, prev_scb, scb);
-			prev_scb = scb;
-		}
-		qinpos++;
-	}
-
-	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
-		ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
-	} else {
-		ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
-	}
-
-	if (action != SEARCH_COUNT
-	 && (found != 0)
-	 && (qinstart != ahc->qinfifonext)) {
-		/*
-		 * The sequencer may be in the process of dmaing
-		 * down the SCB at the beginning of the queue.
-		 * This could be problematic if either the first,
-		 * or the second SCB is removed from the queue
-		 * (the first SCB includes a pointer to the "next"
-		 * SCB to dma). If we have removed any entries, swap
-		 * the first element in the queue with the next HSCB
-		 * so the sequencer will notice that NEXT_QUEUED_SCB
-		 * has changed during its dma attempt and will retry
-		 * the DMA.
-		 */
-		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
-
-		if (scb == NULL) {
-			printf("found = %d, qinstart = %d, qinfifionext = %d\n",
-				found, qinstart, ahc->qinfifonext);
-			panic("First/Second Qinfifo fixup\n");
-		}
-		/*
-		 * ahc_swap_with_next_hscb forces our next pointer to
-		 * point to the reserved SCB for future commands.  Save
-		 * and restore our original next pointer to maintain
-		 * queue integrity.
-		 */
-		next = scb->hscb->next;
-		ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
-		ahc_swap_with_next_hscb(ahc, scb);
-		scb->hscb->next = next;
-		ahc->qinfifo[qinstart] = scb->hscb->tag;
-
-		/* Tell the card about the new head of the qinfifo. */
-		ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
-
-		/* Fixup the tail "next" pointer. */
-		qintail = ahc->qinfifonext - 1;
-		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);
-		scb->hscb->next = ahc->next_queued_scb->hscb->tag;
-	}
-
-	/*
-	 * Search waiting for selection list.
-	 */
-	curscbptr = ahc_inb(ahc, SCBPTR);
-	next = ahc_inb(ahc, WAITING_SCBH);  /* Start at head of list. */
-	prev = SCB_LIST_NULL;
-
-	while (next != SCB_LIST_NULL) {
-		uint8_t scb_index;
-
-		ahc_outb(ahc, SCBPTR, next);
-		scb_index = ahc_inb(ahc, SCB_TAG);
-		if (scb_index >= ahc->scb_data->numscbs) {
-			printf("Waiting List inconsistency. "
-			       "SCB index == %d, yet numscbs == %d.",
-			       scb_index, ahc->scb_data->numscbs);
-			ahc_dump_card_state(ahc);
-			panic("for safety");
-		}
-		scb = ahc_lookup_scb(ahc, scb_index);
-		if (scb == NULL) {
-			printf("scb_index = %d, next = %d\n",
-				scb_index, next);
-			panic("Waiting List traversal\n");
-		}
-		if (ahc_match_scb(ahc, scb, target, channel,
-				  lun, SCB_LIST_NULL, role)) {
-			/*
-			 * We found an scb that needs to be acted on.
-			 */
-			found++;
-			switch (action) {
-			case SEARCH_COMPLETE:
-			{
-				cam_status ostat;
-				cam_status cstat;
-
-				ostat = ahc_get_transaction_status(scb);
-				if (ostat == CAM_REQ_INPROG)
-					ahc_set_transaction_status(scb,
-								   status);
-				cstat = ahc_get_transaction_status(scb);
-				if (cstat != CAM_REQ_CMP)
-					ahc_freeze_scb(scb);
-				if ((scb->flags & SCB_ACTIVE) == 0)
-					printf("Inactive SCB in Waiting List\n");
-				ahc_done(ahc, scb);
-				/* FALLTHROUGH */
-			}
-			case SEARCH_REMOVE:
-				next = ahc_rem_wscb(ahc, next, prev);
-				break;
-			case SEARCH_COUNT:
-				prev = next;
-				next = ahc_inb(ahc, SCB_NEXT);
-				break;
-			}
-		} else {
-			
-			prev = next;
-			next = ahc_inb(ahc, SCB_NEXT);
-		}
-	}
-	ahc_outb(ahc, SCBPTR, curscbptr);
-
-	/*
-	 * And lastly, the untagged holding queues.
-	 */
-	i = 0;
-	if ((ahc->flags & AHC_SCB_BTT) == 0) {
-
-		maxtarget = 16;
-		if (target != CAM_TARGET_WILDCARD) {
-
-			i = target;
-			if (channel == 'B')
-				i += 8;
-			maxtarget = i + 1;
-		}
-	} else {
-		maxtarget = 0;
-	}
-
-	for (; i < maxtarget; i++) {
-		struct scb_tailq *untagged_q;
-		struct scb *next_scb;
-
-		untagged_q = &(ahc->untagged_queues[i]);
-		next_scb = TAILQ_FIRST(untagged_q);
-		while (next_scb != NULL) {
-
-			scb = next_scb;
-			next_scb = TAILQ_NEXT(scb, links.tqe);
-
-			/*
-			 * The head of the list may be the currently
-			 * active untagged command for a device.
-			 * We're only searching for commands that
-			 * have not been started.  A transaction
-			 * marked active but still in the qinfifo
-			 * is removed by the qinfifo scanning code
-			 * above.
-			 */
-			if ((scb->flags & SCB_ACTIVE) != 0)
-				continue;
-
-			if (ahc_match_scb(ahc, scb, target, channel,
-					  lun, SCB_LIST_NULL, role)) {
-				/*
-				 * We found an scb that needs to be acted on.
-				 */
-				found++;
-				switch (action) {
-				case SEARCH_COMPLETE:
-				{
-					cam_status ostat;
-					cam_status cstat;
-
-					ostat = ahc_get_transaction_status(scb);
-					if (ostat == CAM_REQ_INPROG)
-						ahc_set_transaction_status(scb,
-								   status);
-					cstat = ahc_get_transaction_status(scb);
-					if (cstat != CAM_REQ_CMP)
-						ahc_freeze_scb(scb);
-					if ((scb->flags & SCB_ACTIVE) == 0)
-						printf("Inactive SCB in untaggedQ\n");
-					ahc_done(ahc, scb);
-					break;
-				}
-				case SEARCH_REMOVE:
-					TAILQ_REMOVE(untagged_q, scb,
-						     links.tqe);
-					break;
-				case SEARCH_COUNT:
-					break;
-				}
-			}
-		}
-	}
-
-	if (action == SEARCH_COMPLETE)
-		ahc_release_untagged_queues(ahc);
-	return (found);
-}
-
-int
-ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
-		     int lun, u_int tag, int stop_on_first, int remove,
-		     int save_state)
-{
-	struct	scb *scbp;
-	u_int	next;
-	u_int	prev;
-	u_int	count;
-	u_int	active_scb;
-
-	count = 0;
-	next = ahc_inb(ahc, DISCONNECTED_SCBH);
-	prev = SCB_LIST_NULL;
-
-	if (save_state) {
-		/* restore this when we're done */
-		active_scb = ahc_inb(ahc, SCBPTR);
-	} else
-		/* Silence compiler */
-		active_scb = SCB_LIST_NULL;
-
-	while (next != SCB_LIST_NULL) {
-		u_int scb_index;
-
-		ahc_outb(ahc, SCBPTR, next);
-		scb_index = ahc_inb(ahc, SCB_TAG);
-		if (scb_index >= ahc->scb_data->numscbs) {
-			printf("Disconnected List inconsistency. "
-			       "SCB index == %d, yet numscbs == %d.",
-			       scb_index, ahc->scb_data->numscbs);
-			ahc_dump_card_state(ahc);
-			panic("for safety");
-		}
-
-		if (next == prev) {
-			panic("Disconnected List Loop. "
-			      "cur SCBPTR == %x, prev SCBPTR == %x.",
-			      next, prev);
-		}
-		scbp = ahc_lookup_scb(ahc, scb_index);
-		if (ahc_match_scb(ahc, scbp, target, channel, lun,
-				  tag, ROLE_INITIATOR)) {
-			count++;
-			if (remove) {
-				next =
-				    ahc_rem_scb_from_disc_list(ahc, prev, next);
-			} else {
-				prev = next;
-				next = ahc_inb(ahc, SCB_NEXT);
-			}
-			if (stop_on_first)
-				break;
-		} else {
-			prev = next;
-			next = ahc_inb(ahc, SCB_NEXT);
-		}
-	}
-	if (save_state)
-		ahc_outb(ahc, SCBPTR, active_scb);
-	return (count);
-}
-
-/*
- * Remove an SCB from the on chip list of disconnected transactions.
- * This is empty/unused if we are not performing SCB paging.
- */
-static u_int
-ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)
-{
-	u_int next;
-
-	ahc_outb(ahc, SCBPTR, scbptr);
-	next = ahc_inb(ahc, SCB_NEXT);
-
-	ahc_outb(ahc, SCB_CONTROL, 0);
-
-	ahc_add_curscb_to_free_list(ahc);
-
-	if (prev != SCB_LIST_NULL) {
-		ahc_outb(ahc, SCBPTR, prev);
-		ahc_outb(ahc, SCB_NEXT, next);
-	} else
-		ahc_outb(ahc, DISCONNECTED_SCBH, next);
-
-	return (next);
-}
-
-/*
- * Add the SCB as selected by SCBPTR onto the on chip list of
- * free hardware SCBs.  This list is empty/unused if we are not
- * performing SCB paging.
- */
-static void
-ahc_add_curscb_to_free_list(struct ahc_softc *ahc)
-{
-	/*
-	 * Invalidate the tag so that our abort
-	 * routines don't think it's active.
-	 */
-	ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
-
-	if ((ahc->flags & AHC_PAGESCBS) != 0) {
-		ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));
-		ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));
-	}
-}
-
-/*
- * Manipulate the waiting for selection list and return the
- * scb that follows the one that we remove.
- */
-static u_int
-ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
-{       
-	u_int curscb, next;
-
-	/*
-	 * Select the SCB we want to abort and
-	 * pull the next pointer out of it.
-	 */
-	curscb = ahc_inb(ahc, SCBPTR);
-	ahc_outb(ahc, SCBPTR, scbpos);
-	next = ahc_inb(ahc, SCB_NEXT);
-
-	/* Clear the necessary fields */
-	ahc_outb(ahc, SCB_CONTROL, 0);
-
-	ahc_add_curscb_to_free_list(ahc);
-
-	/* update the waiting list */
-	if (prev == SCB_LIST_NULL) {
-		/* First in the list */
-		ahc_outb(ahc, WAITING_SCBH, next); 
-
-		/*
-		 * Ensure we aren't attempting to perform
-		 * selection for this entry.
-		 */
-		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
-	} else {
-		/*
-		 * Select the scb that pointed to us 
-		 * and update its next pointer.
-		 */
-		ahc_outb(ahc, SCBPTR, prev);
-		ahc_outb(ahc, SCB_NEXT, next);
-	}
-
-	/*
-	 * Point us back at the original scb position.
-	 */
-	ahc_outb(ahc, SCBPTR, curscb);
-	return next;
-}
-
-/******************************** Error Handling ******************************/
-/*
- * Abort all SCBs that match the given description (target/channel/lun/tag),
- * setting their status to the passed in status if the status has not already
- * been modified from CAM_REQ_INPROG.  This routine assumes that the sequencer
- * is paused before it is called.
- */
-int
-ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
-	       int lun, u_int tag, role_t role, uint32_t status)
-{
-	struct	scb *scbp;
-	struct	scb *scbp_next;
-	u_int	active_scb;
-	int	i, j;
-	int	maxtarget;
-	int	minlun;
-	int	maxlun;
-
-	int	found;
-
-	/*
-	 * Don't attempt to run any queued untagged transactions
-	 * until we are done with the abort process.
-	 */
-	ahc_freeze_untagged_queues(ahc);
-
-	/* restore this when we're done */
-	active_scb = ahc_inb(ahc, SCBPTR);
-
-	found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,
-				   role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
-
-	/*
-	 * Clean out the busy target table for any untagged commands.
-	 */
-	i = 0;
-	maxtarget = 16;
-	if (target != CAM_TARGET_WILDCARD) {
-		i = target;
-		if (channel == 'B')
-			i += 8;
-		maxtarget = i + 1;
-	}
-
-	if (lun == CAM_LUN_WILDCARD) {
-
-		/*
-		 * Unless we are using an SCB based
-		 * busy targets table, there is only
-		 * one table entry for all luns of
-		 * a target.
-		 */
-		minlun = 0;
-		maxlun = 1;
-		if ((ahc->flags & AHC_SCB_BTT) != 0)
-			maxlun = AHC_NUM_LUNS;
-	} else {
-		minlun = lun;
-		maxlun = lun + 1;
-	}
-
-	if (role != ROLE_TARGET) {
-		for (;i < maxtarget; i++) {
-			for (j = minlun;j < maxlun; j++) {
-				u_int scbid;
-				u_int tcl;
-
-				tcl = BUILD_TCL(i << 4, j);
-				scbid = ahc_index_busy_tcl(ahc, tcl);
-				scbp = ahc_lookup_scb(ahc, scbid);
-				if (scbp == NULL
-				 || ahc_match_scb(ahc, scbp, target, channel,
-						  lun, tag, role) == 0)
-					continue;
-				ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, j));
-			}
-		}
-
-		/*
-		 * Go through the disconnected list and remove any entries we
-		 * have queued for completion, 0'ing their control byte too.
-		 * We save the active SCB and restore it ourselves, so there
-		 * is no reason for this search to restore it too.
-		 */
-		ahc_search_disc_list(ahc, target, channel, lun, tag,
-				     /*stop_on_first*/FALSE, /*remove*/TRUE,
-				     /*save_state*/FALSE);
-	}
-
-	/*
-	 * Go through the hardware SCB array looking for commands that
-	 * were active but not on any list.  In some cases, these remnants
-	 * might not still have mappings in the scbindex array (e.g. unexpected
-	 * bus free with the same scb queued for an abort).  Don't hold this
-	 * against them.
-	 */
-	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
-		u_int scbid;
-
-		ahc_outb(ahc, SCBPTR, i);
-		scbid = ahc_inb(ahc, SCB_TAG);
-		scbp = ahc_lookup_scb(ahc, scbid);
-		if ((scbp == NULL && scbid != SCB_LIST_NULL)
-		 || (scbp != NULL
-		  && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)))
-			ahc_add_curscb_to_free_list(ahc);
-	}
-
-	/*
-	 * Go through the pending CCB list and look for
-	 * commands for this target that are still active.
-	 * These are other tagged commands that were
-	 * disconnected when the reset occurred.
-	 */
-	scbp_next = LIST_FIRST(&ahc->pending_scbs);
-	while (scbp_next != NULL) {
-		scbp = scbp_next;
-		scbp_next = LIST_NEXT(scbp, pending_links);
-		if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
-			cam_status ostat;
-
-			ostat = ahc_get_transaction_status(scbp);
-			if (ostat == CAM_REQ_INPROG)
-				ahc_set_transaction_status(scbp, status);
-			if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
-				ahc_freeze_scb(scbp);
-			if ((scbp->flags & SCB_ACTIVE) == 0)
-				printf("Inactive SCB on pending list\n");
-			ahc_done(ahc, scbp);
-			found++;
-		}
-	}
-	ahc_outb(ahc, SCBPTR, active_scb);
-	ahc_platform_abort_scbs(ahc, target, channel, lun, tag, role, status);
-	ahc_release_untagged_queues(ahc);
-	return found;
-}
-
-static void
-ahc_reset_current_bus(struct ahc_softc *ahc)
-{
-	uint8_t scsiseq;
-
-	ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
-	scsiseq = ahc_inb(ahc, SCSISEQ);
-	ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
-	ahc_delay(AHC_BUSRESET_DELAY);
-	/* Turn off the bus reset */
-	ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
-
-	ahc_clear_intstat(ahc);
-
-	/* Re-enable reset interrupts */
-	ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);
-}
-
-int
-ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
-{
-	struct	ahc_devinfo devinfo;
-	u_int	initiator, target, max_scsiid;
-	u_int	sblkctl;
-	u_int	scsiseq;
-	u_int	simode1;
-	int	found;
-	int	restart_needed;
-	char	cur_channel;
-
-	ahc->pending_device = NULL;
-
-	ahc_compile_devinfo(&devinfo,
-			    CAM_TARGET_WILDCARD,
-			    CAM_TARGET_WILDCARD,
-			    CAM_LUN_WILDCARD,
-			    channel, ROLE_UNKNOWN);
-	ahc_pause(ahc);
-
-	/* Make sure the sequencer is in a safe location. */
-	ahc_clear_critical_section(ahc);
-
-	/*
-	 * Run our command complete fifos to ensure that we perform
-	 * completion processing on any commands that 'completed'
-	 * before the reset occurred.
-	 */
-	ahc_run_qoutfifo(ahc);
-#if AHC_TARGET_MODE
-	if ((ahc->flags & AHC_TARGETROLE) != 0) {
-		ahc_run_tqinfifo(ahc, /*paused*/TRUE);
-	}
-#endif
-
-	/*
-	 * Reset the bus if we are initiating this reset
-	 */
-	sblkctl = ahc_inb(ahc, SBLKCTL);
-	cur_channel = 'A';
-	if ((ahc->features & AHC_TWIN) != 0
-	 && ((sblkctl & SELBUSB) != 0))
-	    cur_channel = 'B';
-	scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
-	if (cur_channel != channel) {
-		/* Case 1: Command for another bus is active
-		 * Stealthily reset the other bus without
-		 * upsetting the current bus.
-		 */
-		ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
-		simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
-		ahc_outb(ahc, SIMODE1, simode1);
-		if (initiate_reset)
-			ahc_reset_current_bus(ahc);
-		ahc_clear_intstat(ahc);
-#if AHC_TARGET_MODE
-		/*
-		 * Bus resets clear ENSELI, so we cannot
-		 * defer re-enabling bus reset interrupts
-		 * if we are in target mode.
-		 */
-		if ((ahc->flags & AHC_TARGETROLE) != 0)
-			ahc_outb(ahc, SIMODE1, simode1 | ENSCSIRST);
-#endif
-		ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
-		ahc_outb(ahc, SBLKCTL, sblkctl);
-		restart_needed = FALSE;
-	} else {
-		/* Case 2: A command from this bus is active or we're idle */
-		ahc_clear_msg_state(ahc);
-		simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
-		ahc_outb(ahc, SIMODE1, simode1);
-		if (initiate_reset)
-			ahc_reset_current_bus(ahc);
-		ahc_clear_intstat(ahc);
-#if AHC_TARGET_MODE
-		/*
-		 * Bus resets clear ENSELI, so we cannot
-		 * defer re-enabling bus reset interrupts
-		 * if we are in target mode.
-		 */
-		if ((ahc->flags & AHC_TARGETROLE) != 0)
-			ahc_outb(ahc, SIMODE1, simode1 | ENSCSIRST);
-#endif
-		ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
-		restart_needed = TRUE;
-	}
-
-	/*
-	 * Clean up all the state information for the
-	 * pending transactions on this bus.
-	 */
-	found = ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, channel,
-			       CAM_LUN_WILDCARD, SCB_LIST_NULL,
-			       ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
-
-	max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;
-
-#ifdef AHC_TARGET_MODE
-	/*
-	 * Send an immediate notify ccb to all target more peripheral
-	 * drivers affected by this action.
-	 */
-	for (target = 0; target <= max_scsiid; target++) {
-		struct ahc_tmode_tstate* tstate;
-		u_int lun;
-
-		tstate = ahc->enabled_targets[target];
-		if (tstate == NULL)
-			continue;
-		for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
-			struct ahc_tmode_lstate* lstate;
-
-			lstate = tstate->enabled_luns[lun];
-			if (lstate == NULL)
-				continue;
-
-			ahc_queue_lstate_event(ahc, lstate, CAM_TARGET_WILDCARD,
-					       EVENT_TYPE_BUS_RESET, /*arg*/0);
-			ahc_send_lstate_events(ahc, lstate);
-		}
-	}
-#endif
-	/* Notify the XPT that a bus reset occurred */
-	ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
-		       CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
-
-	/*
-	 * Revert to async/narrow transfers until we renegotiate.
-	 */
-	for (target = 0; target <= max_scsiid; target++) {
-
-		if (ahc->enabled_targets[target] == NULL)
-			continue;
-		for (initiator = 0; initiator <= max_scsiid; initiator++) {
-			struct ahc_devinfo devinfo;
-
-			ahc_compile_devinfo(&devinfo, target, initiator,
-					    CAM_LUN_WILDCARD,
-					    channel, ROLE_UNKNOWN);
-			ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
-				      AHC_TRANS_CUR, /*paused*/TRUE);
-			ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
-					 /*period*/0, /*offset*/0,
-					 /*ppr_options*/0, AHC_TRANS_CUR,
-					 /*paused*/TRUE);
-		}
-	}
-
-	if (restart_needed)
-		ahc_restart(ahc);
-	else
-		ahc_unpause(ahc);
-	return found;
-}
-
-
-/***************************** Residual Processing ****************************/
-/*
- * Calculate the residual for a just completed SCB.
- */
-void
-ahc_calc_residual(struct scb *scb)
-{
-	struct hardware_scb *hscb;
-	struct status_pkt *spkt;
-	uint32_t sgptr;
-	uint32_t resid_sgptr;
-	uint32_t resid;
-
-	/*
-	 * 5 cases.
-	 * 1) No residual.
-	 *    SG_RESID_VALID clear in sgptr.
-	 * 2) Transferless command
-	 * 3) Never performed any transfers.
-	 *    sgptr has SG_FULL_RESID set.
-	 * 4) No residual but target did not
-	 *    save data pointers after the
-	 *    last transfer, so sgptr was
-	 *    never updated.
-	 * 5) We have a partial residual.
-	 *    Use residual_sgptr to determine
-	 *    where we are.
-	 */
-
-	hscb = scb->hscb;
-	sgptr = ahc_le32toh(hscb->sgptr);
-	if ((sgptr & SG_RESID_VALID) == 0)
-		/* Case 1 */
-		return;
-	sgptr &= ~SG_RESID_VALID;
-
-	if ((sgptr & SG_LIST_NULL) != 0)
-		/* Case 2 */
-		return;
-
-	spkt = &hscb->shared_data.status;
-	resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);
-	if ((sgptr & SG_FULL_RESID) != 0) {
-		/* Case 3 */
-		resid = ahc_get_transfer_length(scb);
-	} else if ((resid_sgptr & SG_LIST_NULL) != 0) {
-		/* Case 4 */
-		return;
-	} else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
-		panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
-	} else {
-		struct ahc_dma_seg *sg;
-
-		/*
-		 * Remainder of the SG where the transfer
-		 * stopped.  
-		 */
-		resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
-		sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
-
-		/* The residual sg_ptr always points to the next sg */
-		sg--;
-
-		/*
-		 * Add up the contents of all residual
-		 * SG segments that are after the SG where
-		 * the transfer stopped.
-		 */
-		while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
-			sg++;
-			resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
-		}
-	}
-	if ((scb->flags & SCB_SENSE) == 0)
-		ahc_set_residual(scb, resid);
-	else
-		ahc_set_sense_residual(scb, resid);
-
-#ifdef AHC_DEBUG
-	if ((ahc_debug & AHC_SHOWMISC) != 0) {
-		ahc_print_path(ahc, scb);
-		printf("Handled Residual of %d bytes\n", resid);
-	}
-#endif
-}
-
-/******************************* Target Mode **********************************/
-#ifdef AHC_TARGET_MODE
-/*
- * Add a target mode event to this lun's queue
- */
-static void
-ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
-		       u_int initiator_id, u_int event_type, u_int event_arg)
-{
-	struct ahc_tmode_event *event;
-	int pending;
-
-	xpt_freeze_devq(lstate->path, /*count*/1);
-	if (lstate->event_w_idx >= lstate->event_r_idx)
-		pending = lstate->event_w_idx - lstate->event_r_idx;
-	else
-		pending = AHC_TMODE_EVENT_BUFFER_SIZE + 1
-			- (lstate->event_r_idx - lstate->event_w_idx);
-
-	if (event_type == EVENT_TYPE_BUS_RESET
-	 || event_type == MSG_BUS_DEV_RESET) {
-		/*
-		 * Any earlier events are irrelevant, so reset our buffer.
-		 * This has the effect of allowing us to deal with reset
-		 * floods (an external device holding down the reset line)
-		 * without losing the event that is really interesting.
-		 */
-		lstate->event_r_idx = 0;
-		lstate->event_w_idx = 0;
-		xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);
-	}
-
-	if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {
-		xpt_print_path(lstate->path);
-		printf("immediate event %x:%x lost\n",
-		       lstate->event_buffer[lstate->event_r_idx].event_type,
-		       lstate->event_buffer[lstate->event_r_idx].event_arg);
-		lstate->event_r_idx++;
-		if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
-			lstate->event_r_idx = 0;
-		xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);
-	}
-
-	event = &lstate->event_buffer[lstate->event_w_idx];
-	event->initiator_id = initiator_id;
-	event->event_type = event_type;
-	event->event_arg = event_arg;
-	lstate->event_w_idx++;
-	if (lstate->event_w_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
-		lstate->event_w_idx = 0;
-}
-
-/*
- * Send any target mode events queued up waiting
- * for immediate notify resources.
- */
-void
-ahc_send_lstate_events(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate)
-{
-	struct ccb_hdr *ccbh;
-	struct ccb_immed_notify *inot;
-
-	while (lstate->event_r_idx != lstate->event_w_idx
-	    && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
-		struct ahc_tmode_event *event;
-
-		event = &lstate->event_buffer[lstate->event_r_idx];
-		SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
-		inot = (struct ccb_immed_notify *)ccbh;
-		switch (event->event_type) {
-		case EVENT_TYPE_BUS_RESET:
-			ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
-			break;
-		default:
-			ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
-			inot->message_args[0] = event->event_type;
-			inot->message_args[1] = event->event_arg;
-			break;
-		}
-		inot->initiator_id = event->initiator_id;
-		inot->sense_len = 0;
-		xpt_done((union ccb *)inot);
-		lstate->event_r_idx++;
-		if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
-			lstate->event_r_idx = 0;
-	}
-}
-#endif
-
-/******************** Sequencer Program Patching/Download *********************/
-
-#ifdef AHC_DUMP_SEQ
-void
-ahc_dumpseq(struct ahc_softc* ahc)
-{
-	int i;
-	int max_prog;
-
-	if ((ahc->chip & AHC_BUS_MASK) < AHC_PCI)
-		max_prog = 448;
-	else if ((ahc->features & AHC_ULTRA2) != 0)
-		max_prog = 768;
-	else
-		max_prog = 512;
-
-	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
-	ahc_outb(ahc, SEQADDR0, 0);
-	ahc_outb(ahc, SEQADDR1, 0);
-	for (i = 0; i < max_prog; i++) {
-		uint8_t ins_bytes[4];
-
-		ahc_insb(ahc, SEQRAM, ins_bytes, 4);
-		printf("0x%08x\n", ins_bytes[0] << 24
-				 | ins_bytes[1] << 16
-				 | ins_bytes[2] << 8
-				 | ins_bytes[3]);
-	}
-}
-#endif
-
-static void
-ahc_loadseq(struct ahc_softc *ahc)
-{
-	struct	cs cs_table[num_critical_sections];
-	u_int	begin_set[num_critical_sections];
-	u_int	end_set[num_critical_sections];
-	struct	patch *cur_patch;
-	u_int	cs_count;
-	u_int	cur_cs;
-	u_int	i;
-	int	downloaded;
-	u_int	skip_addr;
-	u_int	sg_prefetch_cnt;
-	uint8_t	download_consts[7];
-
-	/*
-	 * Start out with 0 critical sections
-	 * that apply to this firmware load.
-	 */
-	cs_count = 0;
-	cur_cs = 0;
-	memset(begin_set, 0, sizeof(begin_set));
-	memset(end_set, 0, sizeof(end_set));
-
-	/* Setup downloadable constant table */
-	download_consts[QOUTFIFO_OFFSET] = 0;
-	if (ahc->targetcmds != NULL)
-		download_consts[QOUTFIFO_OFFSET] += 32;
-	download_consts[QINFIFO_OFFSET] = download_consts[QOUTFIFO_OFFSET] + 1;
-	download_consts[CACHESIZE_MASK] = ahc->pci_cachesize - 1;
-	download_consts[INVERTED_CACHESIZE_MASK] = ~(ahc->pci_cachesize - 1);
-	sg_prefetch_cnt = ahc->pci_cachesize;
-	if (sg_prefetch_cnt < (2 * sizeof(struct ahc_dma_seg)))
-		sg_prefetch_cnt = 2 * sizeof(struct ahc_dma_seg);
-	download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
-	download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_cnt - 1);
-	download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_cnt - 1);
-
-	cur_patch = patches;
-	downloaded = 0;
-	skip_addr = 0;
-	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
-	ahc_outb(ahc, SEQADDR0, 0);
-	ahc_outb(ahc, SEQADDR1, 0);
-
-	for (i = 0; i < sizeof(seqprog)/4; i++) {
-		if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {
-			/*
-			 * Don't download this instruction as it
-			 * is in a patch that was removed.
-			 */
-			continue;
-		}
-		/*
-		 * Move through the CS table until we find a CS
-		 * that might apply to this instruction.
-		 */
-		for (; cur_cs < num_critical_sections; cur_cs++) {
-			if (critical_sections[cur_cs].end <= i) {
-				if (begin_set[cs_count] == TRUE
-				 && end_set[cs_count] == FALSE) {
-					cs_table[cs_count].end = downloaded;
-				 	end_set[cs_count] = TRUE;
-					cs_count++;
-				}
-				continue;
-			}
-			if (critical_sections[cur_cs].begin <= i
-			 && begin_set[cs_count] == FALSE) {
-				cs_table[cs_count].begin = downloaded;
-				begin_set[cs_count] = TRUE;
-			}
-			break;
-		}
-		ahc_download_instr(ahc, i, download_consts);
-		downloaded++;
-	}
-
-	ahc->num_critical_sections = cs_count;
-	if (cs_count != 0) {
-
-		cs_count *= sizeof(struct cs);
-		ahc->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
-		if (ahc->critical_sections == NULL)
-			panic("ahc_loadseq: Could not malloc");
-		memcpy(ahc->critical_sections, cs_table, cs_count);
-	}
-	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
-	ahc_restart(ahc);
-
-	if (bootverbose)
-		printf(" %d instructions downloaded\n", downloaded);
-}
-
-static int
-ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch,
-		u_int start_instr, u_int *skip_addr)
-{
-	struct	patch *cur_patch;
-	struct	patch *last_patch;
-	u_int	num_patches;
-
-	num_patches = sizeof(patches)/sizeof(struct patch);
-	last_patch = &patches[num_patches];
-	cur_patch = *start_patch;
-
-	while (cur_patch < last_patch && start_instr == cur_patch->begin) {
-
-		if (cur_patch->patch_func(ahc) == 0) {
-
-			/* Start rejecting code */
-			*skip_addr = start_instr + cur_patch->skip_instr;
-			cur_patch += cur_patch->skip_patch;
-		} else {
-			/* Accepted this patch.  Advance to the next
-			 * one and wait for our intruction pointer to
-			 * hit this point.
-			 */
-			cur_patch++;
-		}
-	}
-
-	*start_patch = cur_patch;
-	if (start_instr < *skip_addr)
-		/* Still skipping */
-		return (0);
-
-	return (1);
-}
-
-static void
-ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts)
-{
-	union	ins_formats instr;
-	struct	ins_format1 *fmt1_ins;
-	struct	ins_format3 *fmt3_ins;
-	u_int	opcode;
-
-	/*
-	 * The firmware is always compiled into a little endian format.
-	 */
-	instr.integer = ahc_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
-
-	fmt1_ins = &instr.format1;
-	fmt3_ins = NULL;
-
-	/* Pull the opcode */
-	opcode = instr.format1.opcode;
-	switch (opcode) {
-	case AIC_OP_JMP:
-	case AIC_OP_JC:
-	case AIC_OP_JNC:
-	case AIC_OP_CALL:
-	case AIC_OP_JNE:
-	case AIC_OP_JNZ:
-	case AIC_OP_JE:
-	case AIC_OP_JZ:
-	{
-		struct patch *cur_patch;
-		int address_offset;
-		u_int address;
-		u_int skip_addr;
-		u_int i;
-
-		fmt3_ins = &instr.format3;
-		address_offset = 0;
-		address = fmt3_ins->address;
-		cur_patch = patches;
-		skip_addr = 0;
-
-		for (i = 0; i < address;) {
-
-			ahc_check_patch(ahc, &cur_patch, i, &skip_addr);
-
-			if (skip_addr > i) {
-				int end_addr;
-
-				end_addr = MIN(address, skip_addr);
-				address_offset += end_addr - i;
-				i = skip_addr;
-			} else {
-				i++;
-			}
-		}
-		address -= address_offset;
-		fmt3_ins->address = address;
-		/* FALLTHROUGH */
-	}
-	case AIC_OP_OR:
-	case AIC_OP_AND:
-	case AIC_OP_XOR:
-	case AIC_OP_ADD:
-	case AIC_OP_ADC:
-	case AIC_OP_BMOV:
-		if (fmt1_ins->parity != 0) {
-			fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
-		}
-		fmt1_ins->parity = 0;
-		if ((ahc->features & AHC_CMD_CHAN) == 0
-		 && opcode == AIC_OP_BMOV) {
-			/*
-			 * Block move was added at the same time
-			 * as the command channel.  Verify that
-			 * this is only a move of a single element
-			 * and convert the BMOV to a MOV
-			 * (AND with an immediate of FF).
-			 */
-			if (fmt1_ins->immediate != 1)
-				panic("%s: BMOV not supported\n",
-				      ahc_name(ahc));
-			fmt1_ins->opcode = AIC_OP_AND;
-			fmt1_ins->immediate = 0xff;
-		}
-		/* FALLTHROUGH */
-	case AIC_OP_ROL:
-		if ((ahc->features & AHC_ULTRA2) != 0) {
-			int i, count;
-
-			/* Calculate odd parity for the instruction */
-			for (i = 0, count = 0; i < 31; i++) {
-				uint32_t mask;
-
-				mask = 0x01 << i;
-				if ((instr.integer & mask) != 0)
-					count++;
-			}
-			if ((count & 0x01) == 0)
-				instr.format1.parity = 1;
-		} else {
-			/* Compress the instruction for older sequencers */
-			if (fmt3_ins != NULL) {
-				instr.integer =
-					fmt3_ins->immediate
-				      | (fmt3_ins->source << 8)
-				      | (fmt3_ins->address << 16)
-				      |	(fmt3_ins->opcode << 25);
-			} else {
-				instr.integer =
-					fmt1_ins->immediate
-				      | (fmt1_ins->source << 8)
-				      | (fmt1_ins->destination << 16)
-				      |	(fmt1_ins->ret << 24)
-				      |	(fmt1_ins->opcode << 25);
-			}
-		}
-		/* The sequencer is a little endian cpu */
-		instr.integer = ahc_htole32(instr.integer);
-		ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
-		break;
-	default:
-		panic("Unknown opcode encountered in seq program");
-		break;
-	}
-}
-
-void
-ahc_dump_card_state(struct ahc_softc *ahc)
-{
-	struct scb *scb;
-	struct scb_tailq *untagged_q;
-	int target;
-	int maxtarget;
-	int i;
-	uint8_t last_phase;
-	uint8_t qinpos;
-	uint8_t qintail;
-	uint8_t qoutpos;
-	uint8_t scb_index;
-	uint8_t saved_scbptr;
-
-	saved_scbptr = ahc_inb(ahc, SCBPTR);
-
-	last_phase = ahc_inb(ahc, LASTPHASE);
-	printf("%s: Dumping Card State %s, at SEQADDR 0x%x\n",
-	       ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
-	       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
-	printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
-	       ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
-	       ahc_inb(ahc, ARG_2));
-	printf("HCNT = 0x%x\n", ahc_inb(ahc, HCNT));
-	printf("SCSISEQ = 0x%x, SBLKCTL = 0x%x\n",
-	       ahc_inb(ahc, SCSISEQ), ahc_inb(ahc, SBLKCTL));
-	printf(" DFCNTRL = 0x%x, DFSTATUS = 0x%x\n",
-	       ahc_inb(ahc, DFCNTRL), ahc_inb(ahc, DFSTATUS));
-	printf("LASTPHASE = 0x%x, SCSISIGI = 0x%x, SXFRCTL0 = 0x%x\n",
-	       last_phase, ahc_inb(ahc, SCSISIGI), ahc_inb(ahc, SXFRCTL0));
-	printf("SSTAT0 = 0x%x, SSTAT1 = 0x%x\n",
-	       ahc_inb(ahc, SSTAT0), ahc_inb(ahc, SSTAT1));
-	if ((ahc->features & AHC_DT) != 0)
-		printf("SCSIPHASE = 0x%x\n", ahc_inb(ahc, SCSIPHASE));
-	printf("STACK == 0x%x, 0x%x, 0x%x, 0x%x\n",
-		ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
-		ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
-		ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
-		ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8));
-	printf("SCB count = %d\n", ahc->scb_data->numscbs);
-	printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
-	printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
-	/* QINFIFO */
-	printf("QINFIFO entries: ");
-	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
-		qinpos = ahc_inb(ahc, SNSCB_QOFF);
-		ahc_outb(ahc, SNSCB_QOFF, qinpos);
-	} else
-		qinpos = ahc_inb(ahc, QINPOS);
-	qintail = ahc->qinfifonext;
-	while (qinpos != qintail) {
-		printf("%d ", ahc->qinfifo[qinpos]);
-		qinpos++;
-	}
-	printf("\n");
-
-	printf("Waiting Queue entries: ");
-	scb_index = ahc_inb(ahc, WAITING_SCBH);
-	i = 0;
-	while (scb_index != SCB_LIST_NULL && i++ < 256) {
-		ahc_outb(ahc, SCBPTR, scb_index);
-		printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
-		scb_index = ahc_inb(ahc, SCB_NEXT);
-	}
-	printf("\n");
-
-	printf("Disconnected Queue entries: ");
-	scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);
-	i = 0;
-	while (scb_index != SCB_LIST_NULL && i++ < 256) {
-		ahc_outb(ahc, SCBPTR, scb_index);
-		printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
-		scb_index = ahc_inb(ahc, SCB_NEXT);
-	}
-	printf("\n");
-		
-	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
-	printf("QOUTFIFO entries: ");
-	qoutpos = ahc->qoutfifonext;
-	i = 0;
-	while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {
-		printf("%d ", ahc->qoutfifo[qoutpos]);
-		qoutpos++;
-	}
-	printf("\n");
-
-	printf("Sequencer Free SCB List: ");
-	scb_index = ahc_inb(ahc, FREE_SCBH);
-	i = 0;
-	while (scb_index != SCB_LIST_NULL && i++ < 256) {
-		ahc_outb(ahc, SCBPTR, scb_index);
-		printf("%d ", scb_index);
-		scb_index = ahc_inb(ahc, SCB_NEXT);
-	}
-	printf("\n");
-
-	printf("Pending list: ");
-	i = 0;
-	LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
-		if (i++ > 256)
-			break;
-		if (scb != LIST_FIRST(&ahc->pending_scbs))
-			printf(", ");
-		printf("%d", scb->hscb->tag);
-		if ((ahc->flags & AHC_PAGESCBS) == 0) {
-			ahc_outb(ahc, SCBPTR, scb->hscb->tag);
-			printf("(0x%x, 0x%x)", ahc_inb(ahc, SCB_CONTROL),
-			       ahc_inb(ahc, SCB_TAG));
-		}
-	}
-	printf("\n");
-
-	printf("Kernel Free SCB list: ");
-	i = 0;
-	SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
-		if (i++ > 256)
-			break;
-		printf("%d ", scb->hscb->tag);
-	}
-	printf("\n");
-
-	maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
-	for (target = 0; target <= maxtarget; target++) {
-		untagged_q = &ahc->untagged_queues[target];
-		if (TAILQ_FIRST(untagged_q) == NULL)
-			continue;
-		printf("Untagged Q(%d): ", target);
-		i = 0;
-		TAILQ_FOREACH(scb, untagged_q, links.tqe) {
-			if (i++ > 256)
-				break;
-			printf("%d ", scb->hscb->tag);
-		}
-		printf("\n");
-	}
-
-	ahc_platform_dump_card_state(ahc);
-	ahc_outb(ahc, SCBPTR, saved_scbptr);
-}
-
-/************************* Target Mode ****************************************/
-#ifdef AHC_TARGET_MODE
-cam_status
-ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,
-		    struct ahc_tmode_tstate **tstate,
-		    struct ahc_tmode_lstate **lstate,
-		    int notfound_failure)
-{
-
-	if ((ahc->features & AHC_TARGETMODE) == 0)
-		return (CAM_REQ_INVALID);
-
-	/*
-	 * Handle the 'black hole' device that sucks up
-	 * requests to unattached luns on enabled targets.
-	 */
-	if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
-	 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
-		*tstate = NULL;
-		*lstate = ahc->black_hole;
-	} else {
-		u_int max_id;
-
-		max_id = (ahc->features & AHC_WIDE) ? 15 : 7;
-		if (ccb->ccb_h.target_id > max_id)
-			return (CAM_TID_INVALID);
-
-		if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)
-			return (CAM_LUN_INVALID);
-
-		*tstate = ahc->enabled_targets[ccb->ccb_h.target_id];
-		*lstate = NULL;
-		if (*tstate != NULL)
-			*lstate =
-			    (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
-	}
-
-	if (notfound_failure != 0 && *lstate == NULL)
-		return (CAM_PATH_INVALID);
-
-	return (CAM_REQ_CMP);
-}
-
-void
-ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
-{
-	struct	   ahc_tmode_tstate *tstate;
-	struct	   ahc_tmode_lstate *lstate;
-	struct	   ccb_en_lun *cel;
-	cam_status status;
-	u_int	   target;
-	u_int	   lun;
-	u_int	   target_mask;
-	u_long	   s;
-	char	   channel;
-
-	status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate,
-				     /*notfound_failure*/FALSE);
-
-	if (status != CAM_REQ_CMP) {
-		ccb->ccb_h.status = status;
-		return;
-	}
-
-	if ((ahc->features & AHC_MULTIROLE) != 0) {
-		u_int	   our_id;
-
-		if (cam_sim_bus(sim) == 0)
-			our_id = ahc->our_id;
-		else
-			our_id = ahc->our_id_b;
-
-		if (ccb->ccb_h.target_id != our_id) {
-			if ((ahc->features & AHC_MULTI_TID) != 0
-		   	 && (ahc->flags & AHC_INITIATORROLE) != 0) {
-				/*
-				 * Only allow additional targets if
-				 * the initiator role is disabled.
-				 * The hardware cannot handle a re-select-in
-				 * on the initiator id during a re-select-out
-				 * on a different target id.
-				 */
-				status = CAM_TID_INVALID;
-			} else if ((ahc->flags & AHC_INITIATORROLE) != 0
-				|| ahc->enabled_luns > 0) {
-				/*
-				 * Only allow our target id to change
-				 * if the initiator role is not configured
-				 * and there are no enabled luns which
-				 * are attached to the currently registered
-				 * scsi id.
-				 */
-				status = CAM_TID_INVALID;
-			}
-		}
-	}
-
-	if (status != CAM_REQ_CMP) {
-		ccb->ccb_h.status = status;
-		return;
-	}
-
-	/*
-	 * We now have an id that is valid.
-	 * If we aren't in target mode, switch modes.
-	 */
-	if ((ahc->flags & AHC_TARGETROLE) == 0
-	 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
-		u_long	s;
-
-		printf("Configuring Target Mode\n");
-		ahc_lock(ahc, &s);
-		if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
-			ccb->ccb_h.status = CAM_BUSY;
-			ahc_unlock(ahc, &s);
-			return;
-		}
-		ahc->flags |= AHC_TARGETROLE;
-		if ((ahc->features & AHC_MULTIROLE) == 0)
-			ahc->flags &= ~AHC_INITIATORROLE;
-		ahc_pause(ahc);
-		ahc_loadseq(ahc);
-		ahc_unlock(ahc, &s);
-	}
-	cel = &ccb->cel;
-	target = ccb->ccb_h.target_id;
-	lun = ccb->ccb_h.target_lun;
-	channel = SIM_CHANNEL(ahc, sim);
-	target_mask = 0x01 << target;
-	if (channel == 'B')
-		target_mask <<= 8;
-
-	if (cel->enable != 0) {
-		u_int scsiseq;
-
-		/* Are we already enabled?? */
-		if (lstate != NULL) {
-			xpt_print_path(ccb->ccb_h.path);
-			printf("Lun already enabled\n");
-			ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
-			return;
-		}
-
-		if (cel->grp6_len != 0
-		 || cel->grp7_len != 0) {
-			/*
-			 * Don't (yet?) support vendor
-			 * specific commands.
-			 */
-			ccb->ccb_h.status = CAM_REQ_INVALID;
-			printf("Non-zero Group Codes\n");
-			return;
-		}
-
-		/*
-		 * Seems to be okay.
-		 * Setup our data structures.
-		 */
-		if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
-			tstate = ahc_alloc_tstate(ahc, target, channel);
-			if (tstate == NULL) {
-				xpt_print_path(ccb->ccb_h.path);
-				printf("Couldn't allocate tstate\n");
-				ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
-				return;
-			}
-		}
-		lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
-		if (lstate == NULL) {
-			xpt_print_path(ccb->ccb_h.path);
-			printf("Couldn't allocate lstate\n");
-			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
-			return;
-		}
-		memset(lstate, 0, sizeof(*lstate));
-		status = xpt_create_path(&lstate->path, /*periph*/NULL,
-					 xpt_path_path_id(ccb->ccb_h.path),
-					 xpt_path_target_id(ccb->ccb_h.path),
-					 xpt_path_lun_id(ccb->ccb_h.path));
-		if (status != CAM_REQ_CMP) {
-			free(lstate, M_DEVBUF);
-			xpt_print_path(ccb->ccb_h.path);
-			printf("Couldn't allocate path\n");
-			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
-			return;
-		}
-		SLIST_INIT(&lstate->accept_tios);
-		SLIST_INIT(&lstate->immed_notifies);
-		ahc_lock(ahc, &s);
-		ahc_pause(ahc);
-		if (target != CAM_TARGET_WILDCARD) {
-			tstate->enabled_luns[lun] = lstate;
-			ahc->enabled_luns++;
-
-			if ((ahc->features & AHC_MULTI_TID) != 0) {
-				u_int targid_mask;
-
-				targid_mask = ahc_inb(ahc, TARGID)
-					    | (ahc_inb(ahc, TARGID + 1) << 8);
-
-				targid_mask |= target_mask;
-				ahc_outb(ahc, TARGID, targid_mask);
-				ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
-				
-				ahc_update_scsiid(ahc, targid_mask);
-			} else {
-				u_int our_id;
-				char  channel;
-
-				channel = SIM_CHANNEL(ahc, sim);
-				our_id = SIM_SCSI_ID(ahc, sim);
-
-				/*
-				 * This can only happen if selections
-				 * are not enabled
-				 */
-				if (target != our_id) {
-					u_int sblkctl;
-					char  cur_channel;
-					int   swap;
-
-					sblkctl = ahc_inb(ahc, SBLKCTL);
-					cur_channel = (sblkctl & SELBUSB)
-						    ? 'B' : 'A';
-					if ((ahc->features & AHC_TWIN) == 0)
-						cur_channel = 'A';
-					swap = cur_channel != channel;
-					if (channel == 'A')
-						ahc->our_id = target;
-					else
-						ahc->our_id_b = target;
-
-					if (swap)
-						ahc_outb(ahc, SBLKCTL,
-							 sblkctl ^ SELBUSB);
-
-					ahc_outb(ahc, SCSIID, target);
-
-					if (swap)
-						ahc_outb(ahc, SBLKCTL, sblkctl);
-				}
-			}
-		} else
-			ahc->black_hole = lstate;
-		/* Allow select-in operations */
-		if (ahc->black_hole != NULL && ahc->enabled_luns > 0) {
-			scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
-			scsiseq |= ENSELI;
-			ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
-			scsiseq = ahc_inb(ahc, SCSISEQ);
-			scsiseq |= ENSELI;
-			ahc_outb(ahc, SCSISEQ, scsiseq);
-		}
-		ahc_unpause(ahc);
-		ahc_unlock(ahc, &s);
-		ccb->ccb_h.status = CAM_REQ_CMP;
-		xpt_print_path(ccb->ccb_h.path);
-		printf("Lun now enabled for target mode\n");
-	} else {
-		struct scb *scb;
-		int i, empty;
-
-		if (lstate == NULL) {
-			ccb->ccb_h.status = CAM_LUN_INVALID;
-			return;
-		}
-
-		ahc_lock(ahc, &s);
-		
-		ccb->ccb_h.status = CAM_REQ_CMP;
-		LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
-			struct ccb_hdr *ccbh;
-
-			ccbh = &scb->io_ctx->ccb_h;
-			if (ccbh->func_code == XPT_CONT_TARGET_IO
-			 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
-				printf("CTIO pending\n");
-				ccb->ccb_h.status = CAM_REQ_INVALID;
-				ahc_unlock(ahc, &s);
-				return;
-			}
-		}
-
-		if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
-			printf("ATIOs pending\n");
-			ccb->ccb_h.status = CAM_REQ_INVALID;
-		}
-
-		if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
-			printf("INOTs pending\n");
-			ccb->ccb_h.status = CAM_REQ_INVALID;
-		}
-
-		if (ccb->ccb_h.status != CAM_REQ_CMP) {
-			ahc_unlock(ahc, &s);
-			return;
-		}
-
-		xpt_print_path(ccb->ccb_h.path);
-		printf("Target mode disabled\n");
-		xpt_free_path(lstate->path);
-		free(lstate, M_DEVBUF);
-
-		ahc_pause(ahc);
-		/* Can we clean up the target too? */
-		if (target != CAM_TARGET_WILDCARD) {
-			tstate->enabled_luns[lun] = NULL;
-			ahc->enabled_luns--;
-			for (empty = 1, i = 0; i < 8; i++)
-				if (tstate->enabled_luns[i] != NULL) {
-					empty = 0;
-					break;
-				}
-
-			if (empty) {
-				ahc_free_tstate(ahc, target, channel,
-						/*force*/FALSE);
-				if (ahc->features & AHC_MULTI_TID) {
-					u_int targid_mask;
-
-					targid_mask = ahc_inb(ahc, TARGID)
-						    | (ahc_inb(ahc, TARGID + 1)
-						       << 8);
-
-					targid_mask &= ~target_mask;
-					ahc_outb(ahc, TARGID, targid_mask);
-					ahc_outb(ahc, TARGID+1,
-					 	 (targid_mask >> 8));
-					ahc_update_scsiid(ahc, targid_mask);
-				}
-			}
-		} else {
-
-			ahc->black_hole = NULL;
-
-			/*
-			 * We can't allow selections without
-			 * our black hole device.
-			 */
-			empty = TRUE;
-		}
-		if (ahc->enabled_luns == 0) {
-			/* Disallow select-in */
-			u_int scsiseq;
-
-			scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
-			scsiseq &= ~ENSELI;
-			ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
-			scsiseq = ahc_inb(ahc, SCSISEQ);
-			scsiseq &= ~ENSELI;
-			ahc_outb(ahc, SCSISEQ, scsiseq);
-
-			if ((ahc->features & AHC_MULTIROLE) == 0) {
-				printf("Configuring Initiator Mode\n");
-				ahc->flags &= ~AHC_TARGETROLE;
-				ahc->flags |= AHC_INITIATORROLE;
-				ahc_pause(ahc);
-				ahc_loadseq(ahc);
-			}
-		}
-		ahc_unpause(ahc);
-		ahc_unlock(ahc, &s);
-	}
-}
-
-static void
-ahc_update_scsiid(struct ahc_softc *ahc, u_int targid_mask)
-{
-	u_int scsiid_mask;
-	u_int scsiid;
-
-	if ((ahc->features & AHC_MULTI_TID) == 0)
-		panic("ahc_update_scsiid called on non-multitid unit\n");
-
-	/*
-	 * Since we will rely on the the TARGID mask
-	 * for selection enables, ensure that OID
-	 * in SCSIID is not set to some other ID
-	 * that we don't want to allow selections on.
-	 */
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		scsiid = ahc_inb(ahc, SCSIID_ULTRA2);
-	else
-		scsiid = ahc_inb(ahc, SCSIID);
-	scsiid_mask = 0x1 << (scsiid & OID);
-	if ((targid_mask & scsiid_mask) == 0) {
-		u_int our_id;
-
-		/* ffs counts from 1 */
-		our_id = ffs(targid_mask);
-		if (our_id == 0)
-			our_id = ahc->our_id;
-		else
-			our_id--;
-		scsiid &= TID;
-		scsiid |= our_id;
-	}
-	if ((ahc->features & AHC_ULTRA2) != 0)
-		ahc_outb(ahc, SCSIID_ULTRA2, scsiid);
-	else
-		ahc_outb(ahc, SCSIID, scsiid);
-}
-
-void
-ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)
-{
-	struct target_cmd *cmd;
-
-	/*
-	 * If the card supports auto-access pause,
-	 * we can access the card directly regardless
-	 * of whether it is paused or not.
-	 */
-	if ((ahc->features & AHC_AUTOPAUSE) != 0)
-		paused = TRUE;
-
-	ahc_sync_tqinfifo(ahc, BUS_DMASYNC_POSTREAD);
-	while ((cmd = &ahc->targetcmds[ahc->tqinfifonext])->cmd_valid != 0) {
-
-		/*
-		 * Only advance through the queue if we
-		 * have the resources to process the command.
-		 */
-		if (ahc_handle_target_cmd(ahc, cmd) != 0)
-			break;
-
-		cmd->cmd_valid = 0;
-		ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
-				ahc->shared_data_dmamap,
-				ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
-				sizeof(struct target_cmd),
-				BUS_DMASYNC_PREREAD);
-		ahc->tqinfifonext++;
-
-		/*
-		 * Lazily update our position in the target mode incoming
-		 * command queue as seen by the sequencer.
-		 */
-		if ((ahc->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
-			if ((ahc->features & AHC_HS_MAILBOX) != 0) {
-				u_int hs_mailbox;
-
-				hs_mailbox = ahc_inb(ahc, HS_MAILBOX);
-				hs_mailbox &= ~HOST_TQINPOS;
-				hs_mailbox |= ahc->tqinfifonext & HOST_TQINPOS;
-				ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
-			} else {
-				if (!paused)
-					ahc_pause(ahc);	
-				ahc_outb(ahc, KERNEL_TQINPOS,
-					 ahc->tqinfifonext & HOST_TQINPOS);
-				if (!paused)
-					ahc_unpause(ahc);
-			}
-		}
-	}
-}
-
-static int
-ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
-{
-	struct	  ahc_tmode_tstate *tstate;
-	struct	  ahc_tmode_lstate *lstate;
-	struct	  ccb_accept_tio *atio;
-	uint8_t *byte;
-	int	  initiator;
-	int	  target;
-	int	  lun;
-
-	initiator = SCSIID_TARGET(ahc, cmd->scsiid);
-	target = SCSIID_OUR_ID(cmd->scsiid);
-	lun    = (cmd->identify & MSG_IDENTIFY_LUNMASK);
-
-	byte = cmd->bytes;
-	tstate = ahc->enabled_targets[target];
-	lstate = NULL;
-	if (tstate != NULL)
-		lstate = tstate->enabled_luns[lun];
-
-	/*
-	 * Commands for disabled luns go to the black hole driver.
-	 */
-	if (lstate == NULL)
-		lstate = ahc->black_hole;
-
-	atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
-	if (atio == NULL) {
-		ahc->flags |= AHC_TQINFIFO_BLOCKED;
-		/*
-		 * Wait for more ATIOs from the peripheral driver for this lun.
-		 */
-		return (1);
-	} else
-		ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
-#if 0
-	printf("Incoming command from %d for %d:%d%s\n",
-	       initiator, target, lun,
-	       lstate == ahc->black_hole ? "(Black Holed)" : "");
-#endif
-	SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
-
-	if (lstate == ahc->black_hole) {
-		/* Fill in the wildcards */
-		atio->ccb_h.target_id = target;
-		atio->ccb_h.target_lun = lun;
-	}
-
-	/*
-	 * Package it up and send it off to
-	 * whomever has this lun enabled.
-	 */
-	atio->sense_len = 0;
-	atio->init_id = initiator;
-	if (byte[0] != 0xFF) {
-		/* Tag was included */
-		atio->tag_action = *byte++;
-		atio->tag_id = *byte++;
-		atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
-	} else {
-		atio->ccb_h.flags = 0;
-	}
-	byte++;
-
-	/* Okay.  Now determine the cdb size based on the command code */
-	switch (*byte >> CMD_GROUP_CODE_SHIFT) {
-	case 0:
-		atio->cdb_len = 6;
-		break;
-	case 1:
-	case 2:
-		atio->cdb_len = 10;
-		break;
-	case 4:
-		atio->cdb_len = 16;
-		break;
-	case 5:
-		atio->cdb_len = 12;
-		break;
-	case 3:
-	default:
-		/* Only copy the opcode. */
-		atio->cdb_len = 1;
-		printf("Reserved or VU command code type encountered\n");
-		break;
-	}
-	
-	memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
-
-	atio->ccb_h.status |= CAM_CDB_RECVD;
-
-	if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
-		/*
-		 * We weren't allowed to disconnect.
-		 * We're hanging on the bus until a
-		 * continue target I/O comes in response
-		 * to this accept tio.
-		 */
-#if 0
-		printf("Received Immediate Command %d:%d:%d - %p\n",
-		       initiator, target, lun, ahc->pending_device);
-#endif
-		ahc->pending_device = lstate;
-		ahc_freeze_ccb((union ccb *)atio);
-		atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
-	}
-	xpt_done((union ccb*)atio);
-	return (0);
-}
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx.h linux/drivers/scsi/aic7xxx/aic7xxx.h
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx.h	2002-07-20 01:08:21.000000000 +0000
@@ -37,9 +37,9 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#34 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#45 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.30 2000/11/10 20:13:40 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.16.2.13 2002/04/29 19:36:29 gibbs Exp $
  */
 
 #ifndef _AIC7XXX_H_
@@ -51,6 +51,7 @@
 /************************* Forward Declarations *******************************/
 struct ahc_platform_data;
 struct scb_platform_data;
+struct seeprom_descriptor;
 
 /****************************** Useful Macros *********************************/
 #ifndef MAX
@@ -350,9 +351,11 @@
 					   */
 	AHC_BIOS_ENABLED      = 0x80000,
 	AHC_ALL_INTERRUPTS    = 0x100000,
-	AHC_PAGESCBS	      = 0x400000, /* Enable SCB paging */
-	AHC_EDGE_INTERRUPT    = 0x800000, /* Device uses edge triggered ints */
-	AHC_39BIT_ADDRESSING  = 0x1000000 /* Use 39 bit addressing scheme. */
+	AHC_PAGESCBS	      = 0x400000,  /* Enable SCB paging */
+	AHC_EDGE_INTERRUPT    = 0x800000,  /* Device uses edge triggered ints */
+	AHC_39BIT_ADDRESSING  = 0x1000000, /* Use 39 bit addressing scheme. */
+	AHC_LSCBS_ENABLED     = 0x2000000, /* 64Byte SCBs enabled */
+	AHC_SCB_CONFIG_USED   = 0x4000000  /* No SEEPROM but SCB2 had info. */
 } ahc_flag;
 
 /************************* Hardware  SCB Definition ***************************/
@@ -941,6 +944,7 @@
 	ahc_feature		  features;
 	ahc_bug			  bugs;
 	ahc_flag		  flags;
+	struct seeprom_config	 *seep_config;
 
 	/* Values to store in the SEQCTL register for pause and unpause */
 	uint8_t			  unpause;
@@ -1093,7 +1097,8 @@
 /*************************** EISA/VL Front End ********************************/
 struct aic7770_identity *aic7770_find_device(uint32_t);
 int			 aic7770_config(struct ahc_softc *ahc,
-					struct aic7770_identity *);
+					struct aic7770_identity *,
+					u_int port);
 
 /************************** SCB and SCB queue management **********************/
 int		ahc_probe_scbs(struct ahc_softc *);
@@ -1116,6 +1121,7 @@
 int			 ahc_suspend(struct ahc_softc *ahc); 
 int			 ahc_resume(struct ahc_softc *ahc);
 void			 ahc_softc_insert(struct ahc_softc *);
+struct ahc_softc	*ahc_find_softc(struct ahc_softc *ahc);
 void			 ahc_set_unit(struct ahc_softc *, int);
 void			 ahc_set_name(struct ahc_softc *, char *);
 void			 ahc_alloc_scbs(struct ahc_softc *ahc);
@@ -1146,6 +1152,11 @@
 					   char channel, int lun, u_int tag,
 					   role_t role, uint32_t status,
 					   ahc_search_action action);
+int			ahc_search_untagged_queues(struct ahc_softc *ahc,
+						   ahc_io_ctx_t ctx,
+						   int target, char channel,
+						   int lun, uint32_t status,
+						   ahc_search_action action);
 int			ahc_search_disc_list(struct ahc_softc *ahc, int target,
 					     char channel, int lun, u_int tag,
 					     int stop_on_first, int remove,
@@ -1157,7 +1168,8 @@
 				       char channel, int lun, u_int tag,
 				       role_t role, uint32_t status);
 void			ahc_restart(struct ahc_softc *ahc);
-void			ahc_calc_residual(struct scb *scb);
+void			ahc_calc_residual(struct ahc_softc *ahc,
+					  struct scb *scb);
 /*************************** Utility Functions ********************************/
 struct ahc_phase_table_entry*
 			ahc_lookup_phase_entry(int phase);
@@ -1219,6 +1231,15 @@
 #endif
 #endif
 /******************************* Debug ***************************************/
+#ifdef AHC_DEBUG
+extern int ahc_debug;
+#define	AHC_SHOWMISC	0x1
+#define	AHC_SHOWSENSE	0x2
+#endif
 void			ahc_print_scb(struct scb *scb);
 void			ahc_dump_card_state(struct ahc_softc *ahc);
+/******************************* SEEPROM *************************************/
+int		ahc_acquire_seeprom(struct ahc_softc *ahc,
+				    struct seeprom_descriptor *sd);
+void		ahc_release_seeprom(struct seeprom_descriptor *sd);
 #endif /* _AIC7XXX_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx.reg linux/drivers/scsi/aic7xxx/aic7xxx.reg
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx.reg	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx.reg	2002-07-20 01:08:40.000000000 +0000
@@ -37,9 +37,9 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.reg,v 1.31 2000/11/10 20:13:40 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.reg,v 1.20.2.11 2002/04/29 19:36:30 gibbs Exp $
  */
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#24 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $"
 
 /*
  * This file is processed by the aic7xxx_asm utility for use in assembling
@@ -474,7 +474,7 @@
 	bit	SOFT1		0x80
 	bit	SOFT0		0x40
 	bit	SOFTCMDEN	0x20	
-	bit	HAS_BRDCTL	0x10	/* External Board control */
+	bit	EXT_BRDCTL	0x10	/* External Board control */
 	bit	SEEPROM		0x08	/* External serial eeprom logic */
 	bit	EEPROM		0x04	/* Writable external BIOS ROM */
 	bit	ROM		0x02	/* Logic for accessing external ROM */
@@ -1009,7 +1009,9 @@
  * SCB Definition (p. 5-4)
  */
 scb {
-	address			0x0a0
+	address		0x0a0
+	size		64
+
 	SCB_CDB_PTR {
 		size	4
 		alias	SCB_RESIDUAL_DATACNT
@@ -1254,7 +1256,8 @@
  */
 
 scratch_ram {
-	address			0x020
+	address		0x020
+	size		58
 
 	/*
 	 * 1 byte per target starting at this address for configuration values
@@ -1316,7 +1319,7 @@
 		bit	SDMAENACK	0x10
 		bit	HDMAEN		0x08
 		bit	HDMAENACK	0x08
-		bit	DIRECTION	0x04
+		bit	DIRECTION	0x04	/* Set indicates PCI->SCSI */
 		bit	FIFOFLUSH	0x02
 		bit	FIFORESET	0x01
 	}
@@ -1469,26 +1472,46 @@
 	DATA_COUNT_ODD {
 		size		1
 	}
+}
+
+scratch_ram {
+	address		0x056
+	size		4
+	/*
+	 * These scratch ram locations are initialized by the 274X BIOS.
+	 * We reuse them after capturing the BIOS settings during
+	 * initialization.
+	 */
 
 	/*
 	 * The initiator specified tag for this target mode transaction.
 	 */
-	INITIATOR_TAG {
-		size		1
+	HA_274_BIOSGLOBAL {
+		size	1
+		bit	HA_274_EXTENDED_TRANS	0x01
+		alias	INITIATOR_TAG
 	}
 
 	SEQ_FLAGS2 {
-		size		1
-		bit	SCB_DMA			  0x01
-		bit	TARGET_MSG_PENDING	  0x02
+		size	1
+		bit	SCB_DMA			0x01
+		bit	TARGET_MSG_PENDING	0x02
 	}
+}
+
+scratch_ram {
+	address		0x05a
+	size		6
 	/*
-	 * These are reserved registers in the card's scratch ram.  Some of
-	 * the values are specified in the AHA2742 technical reference manual
-	 * and are initialized by the BIOS at boot time.
+	 * These are reserved registers in the card's scratch ram on the 2742.
+	 * The EISA configuraiton chip is mapped here.  On Rev E. of the
+	 * aic7770, the sequencer can use this area for scratch, but the
+	 * host cannot directly access these registers.  On later chips, this
+	 * area can be read and written by both the host and the sequencer.
+	 * Even on later chips, many of these locations are initialized by
+	 * the BIOS.
 	 */
 	SCSICONF {
-		address		0x05a
 		size		1
 		bit	TERM_ENB	0x80
 		bit	RESET_SCSI	0x40
@@ -1513,11 +1536,16 @@
 		mask	BIOSDISABLED		0x30	
 		bit	CHANNEL_B_PRIMARY	0x08
 	}
+}
+
+scratch_ram {
+	address		0x070
+	size		16
+
 	/*
 	 * Per target SCSI offset values for Ultra2 controllers.
 	 */
 	TARG_OFFSET {
-		address		0x070
 		size		16
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx.seq linux/drivers/scsi/aic7xxx/aic7xxx.seq
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx.seq	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx.seq	2002-07-20 01:08:29.000000000 +0000
@@ -37,10 +37,11 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.seq,v 1.106 2000/11/12 05:19:46 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.seq,v 1.94.2.16 2002/04/29 19:36:30 gibbs Exp $
  */
 
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#37 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $"
+PATCH_ARG_LIST = "struct ahc_softc *ahc"
 
 #include "aic7xxx.reg"
 #include "scsi_message.h"
@@ -89,7 +90,7 @@
 	test	SSTAT0, SELDO|SELDI	jnz selection;
 test_queue:
 	/* Has the driver posted any work for us? */
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
 		test	QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
 	} else {
@@ -110,7 +111,7 @@
 		mov	SCBPTR, ARG_1;
 	}
 	or	SEQ_FLAGS2, SCB_DMA;
-END_CRITICAL
+END_CRITICAL;
 dma_queued_scb:
 	/*
 	 * DMA the SCB from host ram into the current SCB location.
@@ -124,7 +125,7 @@
 	 * value.
 	 */
 	mov	A, ARG_1;
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 	cmp	NEXT_QUEUED_SCB, A jne abort_qinscb;
 	if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
 		cmp	SCB_TAG, A je . + 2;
@@ -139,7 +140,7 @@
 		inc	QINPOS;
 	}
 	and	SEQ_FLAGS2, ~SCB_DMA;
-END_CRITICAL
+END_CRITICAL;
 start_waiting:
 	/*
 	 * Start the first entry on the waiting SCB list.
@@ -437,7 +438,6 @@
 select_out:
 	/* Turn off the selection hardware */
 	and	SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ;
-	mvi	CLRSINT0, CLRSELDO;
 	mov	SCBPTR, WAITING_SCBH;
 	mov	WAITING_SCBH,SCB_NEXT;
 	mov	SAVED_SCSIID, SCB_SCSIID;
@@ -452,6 +452,7 @@
 		 * sending our identify messages.
 		 */
 		mvi	P_MESGIN|BSYO call change_phase;
+		mvi	CLRSINT0, CLRSELDO;
 
 		/*
 		 * Start out with a simple identify message.
@@ -498,6 +499,7 @@
 		}
 		mvi	DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
 		mov	SCB_TAG	 call dma_scb;
+		call	set_transfer_settings;
 		jmp	target_synccmd;
 
 target_mesgout:
@@ -641,6 +643,7 @@
 	 */
 	mvi	MSG_OUT, MSG_IDENTIFYFLAG;
 	or	SEQ_FLAGS, IDENTIFY_SEEN;
+	mvi	CLRSINT0, CLRSELDO;
 
 	/*
 	 * Main loop for information transfer phases.  Wait for the
@@ -968,12 +971,12 @@
 ultra2_ensure_sg:
 		test	SG_CACHE_SHADOW, LAST_SEG jz ultra2_shvalid;
 		/* Record if we've consumed all S/G entries */
-		test    SSTAT2, SHVALID	jnz residuals_correct;
+		test	SSTAT2, SHVALID	jnz residuals_correct;
 		or	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL;
 		jmp	residuals_correct;
 
 ultra2_shvalid:
-                test    SSTAT2, SHVALID	jnz sgptr_fixup;
+		test	SSTAT2, SHVALID	jnz sgptr_fixup;
 		call	idle_loop;
 		jmp	ultra2_ensure_sg;
 
@@ -1397,7 +1400,7 @@
 	 * The data fifo seems to require 4 byte aligned
 	 * transfers from the sequencer.  Force this to
 	 * be the case by clearing HADDR[0] even though
-	 * we aren't going to touch host memeory.
+	 * we aren't going to touch host memory.
 	 */
 	clr	HADDR[0];
 	if ((ahc->features & AHC_ULTRA2) != 0) {
@@ -2003,7 +2006,7 @@
  * removal of the found SCB from the disconnected list.
  */
 if ((ahc->flags & AHC_PAGESCBS) != 0) {
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 findSCB:
 	mov	A, SINDEX;			/* Tag passed in SINDEX */
 	cmp	DISCONNECTED_SCBH, SCB_LIST_NULL je findSCB_notFound;
@@ -2025,7 +2028,7 @@
 	mov	SCBPTR, SINDEX ret;
 rHead:
 	mov	DISCONNECTED_SCBH,SCB_NEXT ret;
-END_CRITICAL
+END_CRITICAL;
 findSCB_notFound:
 	/*
 	 * We didn't find it.  Page in the SCB.
@@ -2150,7 +2153,7 @@
 	adc	DINDIR, A, SINDIR ret;
 
 /*
- * Either post or fetch and SCB from host memory based on the
+ * Either post or fetch an SCB from host memory based on the
  * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX.
  */
 dma_scb:
@@ -2308,11 +2311,11 @@
 	}
 add_scb_to_free_list:
 	if ((ahc->flags & AHC_PAGESCBS) != 0) {
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 		mov	SCB_NEXT, FREE_SCBH;
 		mvi	SCB_TAG, SCB_LIST_NULL;
 		mov	FREE_SCBH, SCBPTR ret;
-END_CRITICAL
+END_CRITICAL;
 	} else {
 		mvi	SCB_TAG, SCB_LIST_NULL ret;
 	}
@@ -2326,7 +2329,7 @@
 
 if ((ahc->flags & AHC_PAGESCBS) != 0) {
 get_free_or_disc_scb:
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 	cmp	FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;
 	cmp	DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;
 return_error:
@@ -2335,14 +2338,14 @@
 dequeue_disc_scb:
 	mov	SCBPTR, DISCONNECTED_SCBH;
 	mov	DISCONNECTED_SCBH, SCB_NEXT;
-END_CRITICAL
+END_CRITICAL;
 	mvi	DMAPARAMS, FIFORESET;
 	mov	SCB_TAG	jmp dma_scb;
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 dequeue_free_scb:
 	mov	SCBPTR, FREE_SCBH;
 	mov	FREE_SCBH, SCB_NEXT ret;
-END_CRITICAL
+END_CRITICAL;
 
 add_scb_to_disc_list:
 /*
@@ -2350,10 +2353,10 @@
  * candidates for paging out an SCB if one is needed for a new command.
  * Modifying the disconnected list is a critical(pause dissabled) section.
  */
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 	mov	SCB_NEXT, DISCONNECTED_SCBH;
 	mov	DISCONNECTED_SCBH, SCBPTR ret;
-END_CRITICAL
+END_CRITICAL;
 }
 set_seqint:
 	mov	INTSTAT, SINDEX;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_93cx6.c linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_93cx6.c	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.c	2002-07-20 01:08:35.000000000 +0000
@@ -28,9 +28,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#10 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#15 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v 1.9 2000/11/10 20:13:41 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v 1.8.2.5 2002/04/29 19:36:31 gibbs Exp $
  */
 
 /*
@@ -67,9 +67,15 @@
  *
  */
 
+#ifdef __linux__
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
 #include "aic7xxx_93cx6.h"
+#else
+#include <dev/aic7xxx/aic7xxx_osm.h>
+#include <dev/aic7xxx/aic7xxx_inline.h>
+#include <dev/aic7xxx/aic7xxx_93cx6.h>
+#endif
 
 /*
  * Right now, we only have to read the SEEPROM.  But we make it easier to
@@ -77,9 +83,13 @@
  */
 static struct seeprom_cmd {
   	uint8_t len;
- 	uint8_t bits[3];
+ 	uint8_t bits[9];
 } seeprom_read = {3, {1, 1, 0}};
 
+static struct seeprom_cmd seeprom_ewen = {9, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
+static struct seeprom_cmd seeprom_ewds = {9, {1, 0, 0, 0, 0, 0, 0, 0, 0}};
+static struct seeprom_cmd seeprom_write = {3, {1, 0, 1}};
+
 /*
  * Wait for the SEERDY to go high; about 800 ns.
  */
@@ -90,15 +100,55 @@
 	(void)SEEPROM_INB(sd);	/* Clear clock */
 
 /*
+ * Send a START condition and the given command
+ */
+static void
+send_seeprom_cmd(struct seeprom_descriptor *sd, struct seeprom_cmd *cmd)
+{
+	uint8_t temp;
+	int i = 0;
+
+	/* Send chip select for one clock cycle. */
+	temp = sd->sd_MS ^ sd->sd_CS;
+	SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+	CLOCK_PULSE(sd, sd->sd_RDY);
+
+	for (i = 0; i < cmd->len; i++) {
+		if (cmd->bits[i] != 0)
+			temp ^= sd->sd_DO;
+		SEEPROM_OUTB(sd, temp);
+		CLOCK_PULSE(sd, sd->sd_RDY);
+		SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+		CLOCK_PULSE(sd, sd->sd_RDY);
+		if (cmd->bits[i] != 0)
+			temp ^= sd->sd_DO;
+	}
+}
+
+/*
+ * Clear CS put the chip in the reset state, where it can wait for new commands.
+ */
+static void
+reset_seeprom(struct seeprom_descriptor *sd)
+{
+	uint8_t temp;
+
+	temp = sd->sd_MS;
+	SEEPROM_OUTB(sd, temp);
+	CLOCK_PULSE(sd, sd->sd_RDY);
+	SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+	CLOCK_PULSE(sd, sd->sd_RDY);
+	SEEPROM_OUTB(sd, temp);
+	CLOCK_PULSE(sd, sd->sd_RDY);
+}
+
+/*
  * Read the serial EEPROM and returns 1 if successful and 0 if
  * not successful.
  */
 int
-read_seeprom(sd, buf, start_addr, count)
-	struct seeprom_descriptor *sd;
-	uint16_t *buf;
-	u_int start_addr;
-	u_int count;
+ahc_read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
+		 u_int start_addr, u_int count)
 {
 	int i = 0;
 	u_int k = 0;
@@ -110,26 +160,14 @@
 	 * will range from 0 to count-1.
 	 */
 	for (k = start_addr; k < count + start_addr; k++) {
-		/* Send chip select for one clock cycle. */
-		temp = sd->sd_MS ^ sd->sd_CS;
-		SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
-		CLOCK_PULSE(sd, sd->sd_RDY);
-
 		/*
 		 * Now we're ready to send the read command followed by the
 		 * address of the 16-bit register we want to read.
 		 */
-		for (i = 0; i < seeprom_read.len; i++) {
-			if (seeprom_read.bits[i] != 0)
-				temp ^= sd->sd_DO;
-			SEEPROM_OUTB(sd, temp);
-			CLOCK_PULSE(sd, sd->sd_RDY);
-			SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
-			CLOCK_PULSE(sd, sd->sd_RDY);
-			if (seeprom_read.bits[i] != 0)
-				temp ^= sd->sd_DO;
-		}
+		send_seeprom_cmd(sd, &seeprom_read);
+
 		/* Send the 6 or 8 bit address (MSB first, LSB last). */
+		temp = sd->sd_MS ^ sd->sd_CS;
 		for (i = (sd->sd_chip - 1); i >= 0; i--) {
 			if ((k & (1 << i)) != 0)
 				temp ^= sd->sd_DO;
@@ -161,13 +199,7 @@
 		buf[k - start_addr] = v;
 
 		/* Reset the chip select for the next command cycle. */
-		temp = sd->sd_MS;
-		SEEPROM_OUTB(sd, temp);
-		CLOCK_PULSE(sd, sd->sd_RDY);
-		SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
-		CLOCK_PULSE(sd, sd->sd_RDY);
-		SEEPROM_OUTB(sd, temp);
-		CLOCK_PULSE(sd, sd->sd_RDY);
+		reset_seeprom(sd);
 	}
 #ifdef AHC_DUMP_EEPROM
 	printf("\nSerial EEPROM:\n\t");
@@ -182,8 +214,77 @@
 	return (1);
 }
 
+/*
+ * Write the serial EEPROM and return 1 if successful and 0 if
+ * not successful.
+ */
+int
+ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
+		  u_int start_addr, u_int count)
+{
+	uint16_t v;
+	uint8_t temp;
+	int i, k;
+
+	/* Place the chip into write-enable mode */
+	send_seeprom_cmd(sd, &seeprom_ewen);
+	reset_seeprom(sd);
+
+	/* Write all requested data out to the seeprom. */
+	temp = sd->sd_MS ^ sd->sd_CS;
+	for (k = start_addr; k < count + start_addr; k++) {
+		/* Send the write command */
+		send_seeprom_cmd(sd, &seeprom_write);
+
+		/* Send the 6 or 8 bit address (MSB first). */
+		for (i = (sd->sd_chip - 1); i >= 0; i--) {
+			if ((k & (1 << i)) != 0)
+				temp ^= sd->sd_DO;
+			SEEPROM_OUTB(sd, temp);
+			CLOCK_PULSE(sd, sd->sd_RDY);
+			SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+			CLOCK_PULSE(sd, sd->sd_RDY);
+			if ((k & (1 << i)) != 0)
+				temp ^= sd->sd_DO;
+		}
+
+		/* Write the 16 bit value, MSB first */
+		v = buf[k - start_addr];
+		for (i = 15; i >= 0; i--) {
+			if ((v & (1 << i)) != 0)
+				temp ^= sd->sd_DO;
+			SEEPROM_OUTB(sd, temp);
+			CLOCK_PULSE(sd, sd->sd_RDY);
+			SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+			CLOCK_PULSE(sd, sd->sd_RDY);
+			if ((v & (1 << i)) != 0)
+				temp ^= sd->sd_DO;
+		}
+
+		/* Wait for the chip to complete the write */
+		temp = sd->sd_MS;
+		SEEPROM_OUTB(sd, temp);
+		CLOCK_PULSE(sd, sd->sd_RDY);
+		temp = sd->sd_MS ^ sd->sd_CS;
+		do {
+			SEEPROM_OUTB(sd, temp);
+			CLOCK_PULSE(sd, sd->sd_RDY);
+			SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+			CLOCK_PULSE(sd, sd->sd_RDY);
+		} while ((SEEPROM_DATA_INB(sd) & sd->sd_DI) == 0);
+
+		reset_seeprom(sd);
+	}
+
+	/* Put the chip back into write-protect mode */
+	send_seeprom_cmd(sd, &seeprom_ewds);
+	reset_seeprom(sd);
+
+	return (1);
+}
+
 int
-verify_cksum(struct seeprom_config *sc)
+ahc_verify_cksum(struct seeprom_config *sc)
 {
 	int i;
 	int maxaddr;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_93cx6.h linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.h
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_93cx6.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_93cx6.h	2002-07-20 01:08:31.000000000 +0000
@@ -38,9 +38,9 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#7 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#10 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.h,v 1.8 2000/11/10 20:13:41 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.h,v 1.7.2.3 2002/04/29 19:36:31 gibbs Exp $
  */
 #ifndef _AIC7XXX_93CX6_H_
 #define _AIC7XXX_93CX6_H_
@@ -93,8 +93,10 @@
 #define	SEEPROM_DATA_INB(sd) \
 	ahc_inb(sd->sd_ahc, sd->sd_dataout_offset)
 
-int read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
-		 u_int start_addr, u_int count);
-int verify_cksum(struct seeprom_config *sc);
+int ahc_read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
+		     u_int start_addr, u_int count);
+int ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
+		      u_int start_addr, u_int count);
+int ahc_verify_cksum(struct seeprom_config *sc);
 
 #endif /* _AIC7XXX_93CX6_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_core.c linux/drivers/scsi/aic7xxx/aic7xxx_core.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_core.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_core.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,7127 @@
+/*
+ * Core routines and tables shareable across OS platforms.
+ *
+ * Copyright (c) 1994-2001 Justin T. Gibbs.
+ * Copyright (c) 2000-2001 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#69 $
+ *
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.41.2.22 2002/04/29 19:36:26 gibbs Exp $
+ */
+
+#ifdef __linux__
+#include "aic7xxx_osm.h"
+#include "aic7xxx_inline.h"
+#include "aicasm/aicasm_insformat.h"
+#else
+#include <dev/aic7xxx/aic7xxx_osm.h>
+#include <dev/aic7xxx/aic7xxx_inline.h>
+#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
+#endif
+
+/****************************** Softc Data ************************************/
+struct ahc_softc_tailq ahc_tailq = TAILQ_HEAD_INITIALIZER(ahc_tailq);
+
+/***************************** Lookup Tables **********************************/
+char *ahc_chip_names[] =
+{
+	"NONE",
+	"aic7770",
+	"aic7850",
+	"aic7855",
+	"aic7859",
+	"aic7860",
+	"aic7870",
+	"aic7880",
+	"aic7895",
+	"aic7895C",
+	"aic7890/91",
+	"aic7896/97",
+	"aic7892",
+	"aic7899"
+};
+static const u_int num_chip_names = NUM_ELEMENTS(ahc_chip_names);
+
+/*
+ * Hardware error codes.
+ */
+struct ahc_hard_error_entry {
+        uint8_t errno;
+	char *errmesg;
+};
+
+static struct ahc_hard_error_entry ahc_hard_errors[] = {
+	{ ILLHADDR,	"Illegal Host Access" },
+	{ ILLSADDR,	"Illegal Sequencer Address referrenced" },
+	{ ILLOPCODE,	"Illegal Opcode in sequencer program" },
+	{ SQPARERR,	"Sequencer Parity Error" },
+	{ DPARERR,	"Data-path Parity Error" },
+	{ MPARERR,	"Scratch or SCB Memory Parity Error" },
+	{ PCIERRSTAT,	"PCI Error detected" },
+	{ CIOPARERR,	"CIOBUS Parity Error" },
+};
+static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors);
+
+static struct ahc_phase_table_entry ahc_phase_table[] =
+{
+	{ P_DATAOUT,	MSG_NOOP,		"in Data-out phase"	},
+	{ P_DATAIN,	MSG_INITIATOR_DET_ERR,	"in Data-in phase"	},
+	{ P_DATAOUT_DT,	MSG_NOOP,		"in DT Data-out phase"	},
+	{ P_DATAIN_DT,	MSG_INITIATOR_DET_ERR,	"in DT Data-in phase"	},
+	{ P_COMMAND,	MSG_NOOP,		"in Command phase"	},
+	{ P_MESGOUT,	MSG_NOOP,		"in Message-out phase"	},
+	{ P_STATUS,	MSG_INITIATOR_DET_ERR,	"in Status phase"	},
+	{ P_MESGIN,	MSG_PARITY_ERROR,	"in Message-in phase"	},
+	{ P_BUSFREE,	MSG_NOOP,		"while idle"		},
+	{ 0,		MSG_NOOP,		"in unknown phase"	}
+};
+
+/*
+ * In most cases we only wish to itterate over real phases, so
+ * exclude the last element from the count.
+ */
+static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1;
+
+/*
+ * Valid SCSIRATE values.  (p. 3-17)
+ * Provides a mapping of tranfer periods in ns to the proper value to
+ * stick in the scsixfer reg.
+ */
+static struct ahc_syncrate ahc_syncrates[] =
+{
+      /* ultra2    fast/ultra  period     rate */
+	{ 0x42,      0x000,      9,      "80.0" },
+	{ 0x03,      0x000,     10,      "40.0" },
+	{ 0x04,      0x000,     11,      "33.0" },
+	{ 0x05,      0x100,     12,      "20.0" },
+	{ 0x06,      0x110,     15,      "16.0" },
+	{ 0x07,      0x120,     18,      "13.4" },
+	{ 0x08,      0x000,     25,      "10.0" },
+	{ 0x19,      0x010,     31,      "8.0"  },
+	{ 0x1a,      0x020,     37,      "6.67" },
+	{ 0x1b,      0x030,     43,      "5.7"  },
+	{ 0x1c,      0x040,     50,      "5.0"  },
+	{ 0x00,      0x050,     56,      "4.4"  },
+	{ 0x00,      0x060,     62,      "4.0"  },
+	{ 0x00,      0x070,     68,      "3.6"  },
+	{ 0x00,      0x000,      0,      NULL   }
+};
+
+/* Our Sequencer Program */
+#include "aic7xxx_seq.h"
+
+/**************************** Function Declarations ***************************/
+static void		ahc_force_renegotiation(struct ahc_softc *ahc);
+static struct ahc_tmode_tstate*
+			ahc_alloc_tstate(struct ahc_softc *ahc,
+					 u_int scsi_id, char channel);
+#ifdef AHC_TARGET_MODE
+static void		ahc_free_tstate(struct ahc_softc *ahc,
+					u_int scsi_id, char channel, int force);
+#endif
+static struct ahc_syncrate*
+			ahc_devlimited_syncrate(struct ahc_softc *ahc,
+					        struct ahc_initiator_tinfo *,
+						u_int *period,
+						u_int *ppr_options,
+						role_t role);
+static void		ahc_update_pending_scbs(struct ahc_softc *ahc);
+static void		ahc_fetch_devinfo(struct ahc_softc *ahc,
+					  struct ahc_devinfo *devinfo);
+static void		ahc_scb_devinfo(struct ahc_softc *ahc,
+					struct ahc_devinfo *devinfo,
+					struct scb *scb);
+static void		ahc_assert_atn(struct ahc_softc *ahc);
+static void		ahc_setup_initiator_msgout(struct ahc_softc *ahc,
+						   struct ahc_devinfo *devinfo,
+						   struct scb *scb);
+static void		ahc_build_transfer_msg(struct ahc_softc *ahc,
+					       struct ahc_devinfo *devinfo);
+static void		ahc_construct_sdtr(struct ahc_softc *ahc,
+					   struct ahc_devinfo *devinfo,
+					   u_int period, u_int offset);
+static void		ahc_construct_wdtr(struct ahc_softc *ahc,
+					   struct ahc_devinfo *devinfo,
+					   u_int bus_width);
+static void		ahc_construct_ppr(struct ahc_softc *ahc,
+					  struct ahc_devinfo *devinfo,
+					  u_int period, u_int offset,
+					  u_int bus_width, u_int ppr_options);
+static void		ahc_clear_msg_state(struct ahc_softc *ahc);
+static void		ahc_handle_message_phase(struct ahc_softc *ahc);
+typedef enum {
+	AHCMSG_1B,
+	AHCMSG_2B,
+	AHCMSG_EXT
+} ahc_msgtype;
+static int		ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type,
+				     u_int msgval, int full);
+static int		ahc_parse_msg(struct ahc_softc *ahc,
+				      struct ahc_devinfo *devinfo);
+static int		ahc_handle_msg_reject(struct ahc_softc *ahc,
+					      struct ahc_devinfo *devinfo);
+static void		ahc_handle_ign_wide_residue(struct ahc_softc *ahc,
+						struct ahc_devinfo *devinfo);
+static void		ahc_reinitialize_dataptrs(struct ahc_softc *ahc);
+static void		ahc_handle_devreset(struct ahc_softc *ahc,
+					    struct ahc_devinfo *devinfo,
+					    cam_status status, char *message,
+					    int verbose_level);
+#if AHC_TARGET_MODE
+static void		ahc_setup_target_msgin(struct ahc_softc *ahc,
+					       struct ahc_devinfo *devinfo,
+					       struct scb *scb);
+#endif
+
+static bus_dmamap_callback_t	ahc_dmamap_cb; 
+static void			ahc_build_free_scb_list(struct ahc_softc *ahc);
+static int			ahc_init_scbdata(struct ahc_softc *ahc);
+static void			ahc_fini_scbdata(struct ahc_softc *ahc);
+static void		ahc_qinfifo_requeue(struct ahc_softc *ahc,
+					    struct scb *prev_scb,
+					    struct scb *scb);
+static int		ahc_qinfifo_count(struct ahc_softc *ahc);
+static u_int		ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,
+						   u_int prev, u_int scbptr);
+static void		ahc_add_curscb_to_free_list(struct ahc_softc *ahc);
+static u_int		ahc_rem_wscb(struct ahc_softc *ahc,
+				     u_int scbpos, u_int prev);
+static void		ahc_reset_current_bus(struct ahc_softc *ahc);
+#ifdef AHC_DUMP_SEQ
+static void		ahc_dumpseq(struct ahc_softc *ahc);
+#endif
+static void		ahc_loadseq(struct ahc_softc *ahc);
+static int		ahc_check_patch(struct ahc_softc *ahc,
+					struct patch **start_patch,
+					u_int start_instr, u_int *skip_addr);
+static void		ahc_download_instr(struct ahc_softc *ahc,
+					   u_int instrptr, uint8_t *dconsts);
+#ifdef AHC_TARGET_MODE
+static void		ahc_queue_lstate_event(struct ahc_softc *ahc,
+					       struct ahc_tmode_lstate *lstate,
+					       u_int initiator_id,
+					       u_int event_type,
+					       u_int event_arg);
+static void		ahc_update_scsiid(struct ahc_softc *ahc,
+					  u_int targid_mask);
+static int		ahc_handle_target_cmd(struct ahc_softc *ahc,
+					      struct target_cmd *cmd);
+#endif
+/************************* Sequencer Execution Control ************************/
+/*
+ * Restart the sequencer program from address zero
+ */
+void
+ahc_restart(struct ahc_softc *ahc)
+{
+
+	ahc_pause(ahc);
+
+	/* No more pending messages. */
+	ahc_clear_msg_state(ahc);
+
+	ahc_outb(ahc, SCSISIGO, 0);		/* De-assert BSY */
+	ahc_outb(ahc, MSG_OUT, MSG_NOOP);	/* No message to send */
+	ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
+	ahc_outb(ahc, LASTPHASE, P_BUSFREE);
+	ahc_outb(ahc, SAVED_SCSIID, 0xFF);
+	ahc_outb(ahc, SAVED_LUN, 0xFF);
+
+	/*
+	 * Ensure that the sequencer's idea of TQINPOS
+	 * matches our own.  The sequencer increments TQINPOS
+	 * only after it sees a DMA complete and a reset could
+	 * occur before the increment leaving the kernel to believe
+	 * the command arrived but the sequencer to not.
+	 */
+	ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
+
+	/* Always allow reselection */
+	ahc_outb(ahc, SCSISEQ,
+		 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
+	if ((ahc->features & AHC_CMD_CHAN) != 0) {
+		/* Ensure that no DMA operations are in progress */
+		ahc_outb(ahc, CCSCBCNT, 0);
+		ahc_outb(ahc, CCSGCTL, 0);
+		ahc_outb(ahc, CCSCBCTL, 0);
+	}
+	/*
+	 * If we were in the process of DMA'ing SCB data into
+	 * an SCB, replace that SCB on the free list.  This prevents
+	 * an SCB leak.
+	 */
+	if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {
+		ahc_add_curscb_to_free_list(ahc);
+		ahc_outb(ahc, SEQ_FLAGS2,
+			 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
+	}
+	ahc_outb(ahc, MWI_RESIDUAL, 0);
+	ahc_outb(ahc, SEQCTL, FASTMODE);
+	ahc_outb(ahc, SEQADDR0, 0);
+	ahc_outb(ahc, SEQADDR1, 0);
+	ahc_unpause(ahc);
+}
+
+/************************* Input/Output Queues ********************************/
+void
+ahc_run_qoutfifo(struct ahc_softc *ahc)
+{
+	struct scb *scb;
+	u_int  scb_index;
+
+	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
+	while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {
+
+		scb_index = ahc->qoutfifo[ahc->qoutfifonext];
+		if ((ahc->qoutfifonext & 0x03) == 0x03) {
+			u_int modnext;
+
+			/*
+			 * Clear 32bits of QOUTFIFO at a time
+			 * so that we don't clobber an incoming
+			 * byte DMA to the array on architectures
+			 * that only support 32bit load and store
+			 * operations.
+			 */
+			modnext = ahc->qoutfifonext & ~0x3;
+			*((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;
+			ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
+					ahc->shared_data_dmamap,
+					/*offset*/modnext, /*len*/4,
+					BUS_DMASYNC_PREREAD);
+		}
+		ahc->qoutfifonext++;
+
+		scb = ahc_lookup_scb(ahc, scb_index);
+		if (scb == NULL) {
+			printf("%s: WARNING no command for scb %d "
+			       "(cmdcmplt)\nQOUTPOS = %d\n",
+			       ahc_name(ahc), scb_index,
+			       ahc->qoutfifonext - 1);
+			continue;
+		}
+
+		/*
+		 * Save off the residual
+		 * if there is one.
+		 */
+		ahc_update_residual(ahc, scb);
+		ahc_done(ahc, scb);
+	}
+}
+
+void
+ahc_run_untagged_queues(struct ahc_softc *ahc)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		ahc_run_untagged_queue(ahc, &ahc->untagged_queues[i]);
+}
+
+void
+ahc_run_untagged_queue(struct ahc_softc *ahc, struct scb_tailq *queue)
+{
+	struct scb *scb;
+
+	if (ahc->untagged_queue_lock != 0)
+		return;
+
+	if ((scb = TAILQ_FIRST(queue)) != NULL
+	 && (scb->flags & SCB_ACTIVE) == 0) {
+		scb->flags |= SCB_ACTIVE;
+		ahc_queue_scb(ahc, scb);
+	}
+}
+
+/************************* Interrupt Handling *********************************/
+void
+ahc_handle_brkadrint(struct ahc_softc *ahc)
+{
+	/*
+	 * We upset the sequencer :-(
+	 * Lookup the error message
+	 */
+	int i;
+	int error;
+
+	error = ahc_inb(ahc, ERROR);
+	for (i = 0; error != 1 && i < num_errors; i++)
+		error >>= 1;
+	printf("%s: brkadrint, %s at seqaddr = 0x%x\n",
+	       ahc_name(ahc), ahc_hard_errors[i].errmesg,
+	       ahc_inb(ahc, SEQADDR0) |
+	       (ahc_inb(ahc, SEQADDR1) << 8));
+
+	ahc_dump_card_state(ahc);
+
+	/* Tell everyone that this HBA is no longer availible */
+	ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
+		       CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
+		       CAM_NO_HBA);
+
+	/* Disable all interrupt sources by resetting the controller */
+	ahc_shutdown(ahc);
+}
+
+void
+ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
+{
+	struct scb *scb;
+	struct ahc_devinfo devinfo;
+	
+	ahc_fetch_devinfo(ahc, &devinfo);
+
+	/*
+	 * Clear the upper byte that holds SEQINT status
+	 * codes and clear the SEQINT bit. We will unpause
+	 * the sequencer, if appropriate, after servicing
+	 * the request.
+	 */
+	ahc_outb(ahc, CLRINT, CLRSEQINT);
+	switch (intstat & SEQINT_MASK) {
+	case BAD_STATUS:
+	{
+		u_int  scb_index;
+		struct hardware_scb *hscb;
+
+		/*
+		 * Set the default return value to 0 (don't
+		 * send sense).  The sense code will change
+		 * this if needed.
+		 */
+		ahc_outb(ahc, RETURN_1, 0);
+
+		/*
+		 * The sequencer will notify us when a command
+		 * has an error that would be of interest to
+		 * the kernel.  This allows us to leave the sequencer
+		 * running in the common case of command completes
+		 * without error.  The sequencer will already have
+		 * dma'd the SCB back up to us, so we can reference
+		 * the in kernel copy directly.
+		 */
+		scb_index = ahc_inb(ahc, SCB_TAG);
+		scb = ahc_lookup_scb(ahc, scb_index);
+		if (scb == NULL) {
+			printf("%s:%c:%d: ahc_intr - referenced scb "
+			       "not valid during seqint 0x%x scb(%d)\n",
+			       ahc_name(ahc), devinfo.channel,
+			       devinfo.target, intstat, scb_index);
+			ahc_dump_card_state(ahc);
+			panic("for safety");
+			goto unpause;
+		}
+
+		hscb = scb->hscb; 
+
+		/* Don't want to clobber the original sense code */
+		if ((scb->flags & SCB_SENSE) != 0) {
+			/*
+			 * Clear the SCB_SENSE Flag and have
+			 * the sequencer do a normal command
+			 * complete.
+			 */
+			scb->flags &= ~SCB_SENSE;
+			ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+			break;
+		}
+		ahc_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
+		/* Freeze the queue until the client sees the error. */
+		ahc_freeze_devq(ahc, scb);
+		ahc_freeze_scb(scb);
+		ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
+		switch (hscb->shared_data.status.scsi_status) {
+		case SCSI_STATUS_OK:
+			printf("%s: Interrupted for staus of 0???\n",
+			       ahc_name(ahc));
+			break;
+		case SCSI_STATUS_CMD_TERMINATED:
+		case SCSI_STATUS_CHECK_COND:
+		{
+			struct ahc_dma_seg *sg;
+			struct scsi_sense *sc;
+			struct ahc_initiator_tinfo *targ_info;
+			struct ahc_tmode_tstate *tstate;
+			struct ahc_transinfo *tinfo;
+#ifdef AHC_DEBUG
+			if (ahc_debug & AHC_SHOWSENSE) {
+				ahc_print_path(ahc, scb);
+				printf("SCB %d: requests Check Status\n",
+				       scb->hscb->tag);
+			}
+#endif
+
+			if (ahc_perform_autosense(scb) == 0)
+				break;
+
+			targ_info = ahc_fetch_transinfo(ahc,
+							devinfo.channel,
+							devinfo.our_scsiid,
+							devinfo.target,
+							&tstate);
+			tinfo = &targ_info->curr;
+			sg = scb->sg_list;
+			sc = (struct scsi_sense *)(&hscb->shared_data.cdb); 
+			/*
+			 * Save off the residual if there is one.
+			 */
+			ahc_update_residual(ahc, scb);
+#ifdef AHC_DEBUG
+			if (ahc_debug & AHC_SHOWSENSE) {
+				ahc_print_path(ahc, scb);
+				printf("Sending Sense\n");
+			}
+#endif
+			sg->addr = ahc_get_sense_bufaddr(ahc, scb);
+			sg->len = ahc_get_sense_bufsize(ahc, scb);
+			sg->len |= AHC_DMA_LAST_SEG;
+
+			/* Fixup byte order */
+			sg->addr = ahc_htole32(sg->addr);
+			sg->len = ahc_htole32(sg->len);
+
+			sc->opcode = REQUEST_SENSE;
+			sc->byte2 = 0;
+			if (tinfo->protocol_version <= SCSI_REV_2
+			 && SCB_GET_LUN(scb) < 8)
+				sc->byte2 = SCB_GET_LUN(scb) << 5;
+			sc->unused[0] = 0;
+			sc->unused[1] = 0;
+			sc->length = sg->len;
+			sc->control = 0;
+
+			/*
+			 * We can't allow the target to disconnect.
+			 * This will be an untagged transaction and
+			 * having the target disconnect will make this
+			 * transaction indestinguishable from outstanding
+			 * tagged transactions.
+			 */
+			hscb->control = 0;
+
+			/*
+			 * This request sense could be because the
+			 * the device lost power or in some other
+			 * way has lost our transfer negotiations.
+			 * Renegotiate if appropriate.  Unit attention
+			 * errors will be reported before any data
+			 * phases occur.
+			 */
+			if (ahc_get_residual(scb) 
+			 == ahc_get_transfer_length(scb)) {
+				ahc_update_neg_request(ahc, &devinfo,
+						       tstate, targ_info,
+						       /*force*/TRUE);
+			}
+			if (tstate->auto_negotiate & devinfo.target_mask) {
+				hscb->control |= MK_MESSAGE;
+				scb->flags &= ~SCB_NEGOTIATE;
+				scb->flags |= SCB_AUTO_NEGOTIATE;
+			}
+			hscb->cdb_len = sizeof(*sc);
+			hscb->dataptr = sg->addr; 
+			hscb->datacnt = sg->len;
+			hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;
+			hscb->sgptr = ahc_htole32(hscb->sgptr);
+			scb->sg_count = 1;
+			scb->flags |= SCB_SENSE;
+			ahc_qinfifo_requeue_tail(ahc, scb);
+			ahc_outb(ahc, RETURN_1, SEND_SENSE);
+#ifdef __FreeBSD__
+			/*
+			 * Ensure we have enough time to actually
+			 * retrieve the sense.
+			 */
+			untimeout(ahc_timeout, (caddr_t)scb,
+				  scb->io_ctx->ccb_h.timeout_ch);
+			scb->io_ctx->ccb_h.timeout_ch =
+			    timeout(ahc_timeout, (caddr_t)scb, 5 * hz);
+#endif
+			break;
+		}
+		default:
+			break;
+		}
+		break;
+	}
+	case NO_MATCH:
+	{
+		/* Ensure we don't leave the selection hardware on */
+		ahc_outb(ahc, SCSISEQ,
+			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
+
+		printf("%s:%c:%d: no active SCB for reconnecting "
+		       "target - issuing BUS DEVICE RESET\n",
+		       ahc_name(ahc), devinfo.channel, devinfo.target);
+		printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
+		       "ARG_1 == 0x%x ACCUM = 0x%x\n",
+		       ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
+		       ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
+		printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
+		       "SINDEX == 0x%x\n",
+		       ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
+		       ahc_index_busy_tcl(ahc,
+			    BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
+				      ahc_inb(ahc, SAVED_LUN))),
+		       ahc_inb(ahc, SINDEX));
+		printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
+		       "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
+		       ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
+		       ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
+		       ahc_inb(ahc, SCB_CONTROL));
+		printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
+		       ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
+		printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
+		printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
+		ahc_dump_card_state(ahc);
+		ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
+		ahc->msgout_len = 1;
+		ahc->msgout_index = 0;
+		ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
+		ahc_outb(ahc, MSG_OUT, HOST_MSG);
+		ahc_assert_atn(ahc);
+		break;
+	}
+	case SEND_REJECT: 
+	{
+		u_int rejbyte = ahc_inb(ahc, ACCUM);
+		printf("%s:%c:%d: Warning - unknown message received from "
+		       "target (0x%x).  Rejecting\n", 
+		       ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
+		break; 
+	}
+	case NO_IDENT: 
+	{
+		/*
+		 * The reconnecting target either did not send an identify
+		 * message, or did, but we didn't find an SCB to match and
+		 * before it could respond to our ATN/abort, it hit a dataphase.
+		 * The only safe thing to do is to blow it away with a bus
+		 * reset.
+		 */
+		int found;
+
+		printf("%s:%c:%d: Target did not send an IDENTIFY message. "
+		       "LASTPHASE = 0x%x, SAVED_SCSIID == 0x%x\n",
+		       ahc_name(ahc), devinfo.channel, devinfo.target,
+		       ahc_inb(ahc, LASTPHASE), ahc_inb(ahc, SAVED_SCSIID));
+		found = ahc_reset_channel(ahc, devinfo.channel, 
+					  /*initiate reset*/TRUE);
+		printf("%s: Issued Channel %c Bus Reset. "
+		       "%d SCBs aborted\n", ahc_name(ahc), devinfo.channel,
+		       found);
+		return;
+	}
+	case IGN_WIDE_RES:
+		ahc_handle_ign_wide_residue(ahc, &devinfo);
+		break;
+	case PDATA_REINIT:
+		ahc_reinitialize_dataptrs(ahc);
+		break;
+	case BAD_PHASE:
+	{
+		u_int lastphase;
+
+		lastphase = ahc_inb(ahc, LASTPHASE);
+		printf("%s:%c:%d: unknown scsi bus phase %x, "
+		       "lastphase = 0x%x.  Attempting to continue\n",
+		       ahc_name(ahc), devinfo.channel, devinfo.target,
+		       lastphase, ahc_inb(ahc, SCSISIGI));
+		break;
+	}
+	case MISSED_BUSFREE:
+	{
+		u_int lastphase;
+
+		lastphase = ahc_inb(ahc, LASTPHASE);
+		printf("%s:%c:%d: Missed busfree. "
+		       "Lastphase = 0x%x, Curphase = 0x%x\n",
+		       ahc_name(ahc), devinfo.channel, devinfo.target,
+		       lastphase, ahc_inb(ahc, SCSISIGI));
+		ahc_restart(ahc);
+		return;
+	}
+	case HOST_MSG_LOOP:
+	{
+		/*
+		 * The sequencer has encountered a message phase
+		 * that requires host assistance for completion.
+		 * While handling the message phase(s), we will be
+		 * notified by the sequencer after each byte is
+		 * transfered so we can track bus phase changes.
+		 *
+		 * If this is the first time we've seen a HOST_MSG_LOOP
+		 * interrupt, initialize the state of the host message
+		 * loop.
+		 */
+		if (ahc->msg_type == MSG_TYPE_NONE) {
+			struct scb *scb;
+			u_int scb_index;
+			u_int bus_phase;
+
+			bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
+			if (bus_phase != P_MESGIN
+			 && bus_phase != P_MESGOUT) {
+				printf("ahc_intr: HOST_MSG_LOOP bad "
+				       "phase 0x%x\n",
+				      bus_phase);
+				/*
+				 * Probably transitioned to bus free before
+				 * we got here.  Just punt the message.
+				 */
+				ahc_clear_intstat(ahc);
+				ahc_restart(ahc);
+				return;
+			}
+
+			scb_index = ahc_inb(ahc, SCB_TAG);
+			scb = ahc_lookup_scb(ahc, scb_index);
+			if (devinfo.role == ROLE_INITIATOR) {
+				if (scb == NULL)
+					panic("HOST_MSG_LOOP with "
+					      "invalid SCB %x\n", scb_index);
+
+				if (bus_phase == P_MESGOUT)
+					ahc_setup_initiator_msgout(ahc,
+								   &devinfo,
+								   scb);
+				else {
+					ahc->msg_type =
+					    MSG_TYPE_INITIATOR_MSGIN;
+					ahc->msgin_index = 0;
+				}
+			}
+#if AHC_TARGET_MODE
+			else {
+				if (bus_phase == P_MESGOUT) {
+					ahc->msg_type =
+					    MSG_TYPE_TARGET_MSGOUT;
+					ahc->msgin_index = 0;
+				}
+				else 
+					ahc_setup_target_msgin(ahc,
+							       &devinfo,
+							       scb);
+			}
+#endif
+		}
+
+		ahc_handle_message_phase(ahc);
+		break;
+	}
+	case PERR_DETECTED:
+	{
+		/*
+		 * If we've cleared the parity error interrupt
+		 * but the sequencer still believes that SCSIPERR
+		 * is true, it must be that the parity error is
+		 * for the currently presented byte on the bus,
+		 * and we are not in a phase (data-in) where we will
+		 * eventually ack this byte.  Ack the byte and
+		 * throw it away in the hope that the target will
+		 * take us to message out to deliver the appropriate
+		 * error message.
+		 */
+		if ((intstat & SCSIINT) == 0
+		 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {
+
+			if ((ahc->features & AHC_DT) == 0) {
+				u_int curphase;
+
+				/*
+				 * The hardware will only let you ack bytes
+				 * if the expected phase in SCSISIGO matches
+				 * the current phase.  Make sure this is
+				 * currently the case.
+				 */
+				curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
+				ahc_outb(ahc, LASTPHASE, curphase);
+				ahc_outb(ahc, SCSISIGO, curphase);
+			}
+			ahc_inb(ahc, SCSIDATL);
+		}
+		break;
+	}
+	case DATA_OVERRUN:
+	{
+		/*
+		 * When the sequencer detects an overrun, it
+		 * places the controller in "BITBUCKET" mode
+		 * and allows the target to complete its transfer.
+		 * Unfortunately, none of the counters get updated
+		 * when the controller is in this mode, so we have
+		 * no way of knowing how large the overrun was.
+		 */
+		u_int scbindex = ahc_inb(ahc, SCB_TAG);
+		u_int lastphase = ahc_inb(ahc, LASTPHASE);
+		u_int i;
+
+		scb = ahc_lookup_scb(ahc, scbindex);
+		for (i = 0; i < num_phases; i++) {
+			if (lastphase == ahc_phase_table[i].phase)
+				break;
+		}
+		ahc_print_path(ahc, scb);
+		printf("data overrun detected %s."
+		       "  Tag == 0x%x.\n",
+		       ahc_phase_table[i].phasemsg,
+  		       scb->hscb->tag);
+		ahc_print_path(ahc, scb);
+		printf("%s seen Data Phase.  Length = %ld.  NumSGs = %d.\n",
+		       ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
+		       ahc_get_transfer_length(scb), scb->sg_count);
+		if (scb->sg_count > 0) {
+			for (i = 0; i < scb->sg_count; i++) {
+
+				printf("sg[%d] - Addr 0x%x%x : Length %d\n",
+				       i,
+				       (ahc_le32toh(scb->sg_list[i].len) >> 24
+				        & SG_HIGH_ADDR_BITS),
+				       ahc_le32toh(scb->sg_list[i].addr),
+				       ahc_le32toh(scb->sg_list[i].len)
+				       & AHC_SG_LEN_MASK);
+			}
+		}
+		/*
+		 * Set this and it will take effect when the
+		 * target does a command complete.
+		 */
+		ahc_freeze_devq(ahc, scb);
+		if ((scb->flags & SCB_SENSE) == 0) {
+			ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
+		} else {
+			scb->flags &= ~SCB_SENSE;
+			ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+		}
+		ahc_freeze_scb(scb);
+
+		if ((ahc->features & AHC_ULTRA2) != 0) {
+			/*
+			 * Clear the channel in case we return
+			 * to data phase later.
+			 */
+			ahc_outb(ahc, SXFRCTL0,
+				 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
+			ahc_outb(ahc, SXFRCTL0,
+				 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
+		}
+		if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
+			u_int dscommand1;
+
+			/* Ensure HHADDR is 0 for future DMA operations. */
+			dscommand1 = ahc_inb(ahc, DSCOMMAND1);
+			ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
+			ahc_outb(ahc, HADDR, 0);
+			ahc_outb(ahc, DSCOMMAND1, dscommand1);
+		}
+		break;
+	}
+	case MKMSG_FAILED:
+	{
+		u_int scbindex;
+
+		printf("%s:%c:%d:%d: Attempt to issue message failed\n",
+		       ahc_name(ahc), devinfo.channel, devinfo.target,
+		       devinfo.lun);
+		scbindex = ahc_inb(ahc, SCB_TAG);
+		scb = ahc_lookup_scb(ahc, scbindex);
+		if (scb != NULL
+		 && (scb->flags & SCB_RECOVERY_SCB) != 0)
+			/*
+			 * Ensure that we didn't put a second instance of this
+			 * SCB into the QINFIFO.
+			 */
+			ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
+					   SCB_GET_CHANNEL(ahc, scb),
+					   SCB_GET_LUN(scb), scb->hscb->tag,
+					   ROLE_INITIATOR, /*status*/0,
+					   SEARCH_REMOVE);
+		break;
+	}
+	case NO_FREE_SCB:
+	{
+		printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
+		ahc_dump_card_state(ahc);
+		panic("for safety");
+		break;
+	}
+	case SCB_MISMATCH:
+	{
+		u_int scbptr;
+
+		scbptr = ahc_inb(ahc, SCBPTR);
+		printf("Bogus TAG after DMA.  SCBPTR %d, tag %d, our tag %d\n",
+		       scbptr, ahc_inb(ahc, ARG_1),
+		       ahc->scb_data->hscbs[scbptr].tag);
+		ahc_dump_card_state(ahc);
+		panic("for saftey");
+		break;
+	}
+	case OUT_OF_RANGE:
+	{
+		printf("%s: BTT calculation out of range\n", ahc_name(ahc));
+		printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
+		       "ARG_1 == 0x%x ACCUM = 0x%x\n",
+		       ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
+		       ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
+		printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
+		       "SINDEX == 0x%x\n, A == 0x%x\n",
+		       ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
+		       ahc_index_busy_tcl(ahc,
+			    BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
+				      ahc_inb(ahc, SAVED_LUN))),
+		       ahc_inb(ahc, SINDEX),
+		       ahc_inb(ahc, ACCUM));
+		printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
+		       "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
+		       ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
+		       ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
+		       ahc_inb(ahc, SCB_CONTROL));
+		printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
+		       ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
+		ahc_dump_card_state(ahc);
+		panic("for safety");
+		break;
+	}
+	default:
+		printf("ahc_intr: seqint, "
+		       "intstat == 0x%x, scsisigi = 0x%x\n",
+		       intstat, ahc_inb(ahc, SCSISIGI));
+		break;
+	}
+unpause:
+	/*
+	 *  The sequencer is paused immediately on
+	 *  a SEQINT, so we should restart it when
+	 *  we're done.
+	 */
+	ahc_unpause(ahc);
+}
+
+void
+ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
+{
+	u_int	scb_index;
+	u_int	status0;
+	u_int	status;
+	struct	scb *scb;
+	char	cur_channel;
+	char	intr_channel;
+
+	/* Make sure the sequencer is in a safe location. */
+	ahc_clear_critical_section(ahc);
+
+	if ((ahc->features & AHC_TWIN) != 0
+	 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))
+		cur_channel = 'B';
+	else
+		cur_channel = 'A';
+	intr_channel = cur_channel;
+
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		status0 = ahc_inb(ahc, SSTAT0) & IOERR;
+	else
+		status0 = 0;
+	status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
+	if (status == 0 && status0 == 0) {
+		if ((ahc->features & AHC_TWIN) != 0) {
+			/* Try the other channel */
+		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
+			status = ahc_inb(ahc, SSTAT1)
+			       & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
+			intr_channel = (cur_channel == 'A') ? 'B' : 'A';
+		}
+		if (status == 0) {
+			printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
+			ahc_outb(ahc, CLRINT, CLRSCSIINT);
+			ahc_unpause(ahc);
+			return;
+		}
+	}
+
+	scb_index = ahc_inb(ahc, SCB_TAG);
+	scb = ahc_lookup_scb(ahc, scb_index);
+	if (scb != NULL
+	 && (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) == 0)
+		scb = NULL;
+
+	if ((ahc->features & AHC_ULTRA2) != 0
+	 && (status0 & IOERR) != 0) {
+		int now_lvd;
+
+		now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
+		printf("%s: Transceiver State Has Changed to %s mode\n",
+		       ahc_name(ahc), now_lvd ? "LVD" : "SE");
+		ahc_outb(ahc, CLRSINT0, CLRIOERR);
+		/*
+		 * When transitioning to SE mode, the reset line
+		 * glitches, triggering an arbitration bug in some
+		 * Ultra2 controllers.  This bug is cleared when we
+		 * assert the reset line.  Since a reset glitch has
+		 * already occurred with this transition and a
+		 * transceiver state change is handled just like
+		 * a bus reset anyway, asserting the reset line
+		 * ourselves is safe.
+		 */
+		ahc_reset_channel(ahc, intr_channel,
+				 /*Initiate Reset*/now_lvd == 0);
+	} else if ((status & SCSIRSTI) != 0) {
+		printf("%s: Someone reset channel %c\n",
+			ahc_name(ahc), intr_channel);
+		if (intr_channel != cur_channel)
+		 	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
+		ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE);
+	} else if ((status & SCSIPERR) != 0) {
+		/*
+		 * Determine the bus phase and queue an appropriate message.
+		 * SCSIPERR is latched true as soon as a parity error
+		 * occurs.  If the sequencer acked the transfer that
+		 * caused the parity error and the currently presented
+		 * transfer on the bus has correct parity, SCSIPERR will
+		 * be cleared by CLRSCSIPERR.  Use this to determine if
+		 * we should look at the last phase the sequencer recorded,
+		 * or the current phase presented on the bus.
+		 */
+		u_int mesg_out;
+		u_int curphase;
+		u_int errorphase;
+		u_int lastphase;
+		u_int scsirate;
+		u_int i;
+		u_int sstat2;
+
+		lastphase = ahc_inb(ahc, LASTPHASE);
+		curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
+		sstat2 = ahc_inb(ahc, SSTAT2);
+		ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
+		/*
+		 * For all phases save DATA, the sequencer won't
+		 * automatically ack a byte that has a parity error
+		 * in it.  So the only way that the current phase
+		 * could be 'data-in' is if the parity error is for
+		 * an already acked byte in the data phase.  During
+		 * synchronous data-in transfers, we may actually
+		 * ack bytes before latching the current phase in
+		 * LASTPHASE, leading to the discrepancy between
+		 * curphase and lastphase.
+		 */
+		if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0
+		 || curphase == P_DATAIN || curphase == P_DATAIN_DT)
+			errorphase = curphase;
+		else
+			errorphase = lastphase;
+
+		for (i = 0; i < num_phases; i++) {
+			if (errorphase == ahc_phase_table[i].phase)
+				break;
+		}
+		mesg_out = ahc_phase_table[i].mesg_out;
+		if (scb != NULL)
+			ahc_print_path(ahc, scb);
+		else
+			printf("%s:%c:%d: ", ahc_name(ahc), intr_channel,
+			       SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));
+		scsirate = ahc_inb(ahc, SCSIRATE);
+		printf("parity error detected %s. "
+		       "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
+		       ahc_phase_table[i].phasemsg,
+		       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8),
+		       scsirate);
+
+		if ((ahc->features & AHC_DT) != 0) {
+
+			if ((sstat2 & CRCVALERR) != 0)
+				printf("\tCRC Value Mismatch\n");
+			if ((sstat2 & CRCENDERR) != 0)
+				printf("\tNo terminal CRC packet recevied\n");
+			if ((sstat2 & CRCREQERR) != 0)
+				printf("\tIllegal CRC packet request\n");
+			if ((sstat2 & DUAL_EDGE_ERR) != 0)
+				printf("\tUnexpected %sDT Data Phase\n",
+				       (scsirate & SINGLE_EDGE) ? "" : "non-");
+		}
+
+		/*
+		 * We've set the hardware to assert ATN if we   
+		 * get a parity error on "in" phases, so all we  
+		 * need to do is stuff the message buffer with
+		 * the appropriate message.  "In" phases have set
+		 * mesg_out to something other than MSG_NOP.
+		 */
+		if (mesg_out != MSG_NOOP) {
+			if (ahc->msg_type != MSG_TYPE_NONE)
+				ahc->send_msg_perror = TRUE;
+			else
+				ahc_outb(ahc, MSG_OUT, mesg_out);
+		}
+		/*
+		 * Force a renegotiation with this target just in
+		 * case we are out of sync for some external reason
+		 * unknown (or unreported) by the target.
+		 */
+		ahc_force_renegotiation(ahc);
+		ahc_outb(ahc, CLRINT, CLRSCSIINT);
+		ahc_unpause(ahc);
+	} else if ((status & SELTO) != 0) {
+		u_int	scbptr;
+
+		/* Stop the selection */
+		ahc_outb(ahc, SCSISEQ, 0);
+
+		/* No more pending messages */
+		ahc_clear_msg_state(ahc);
+
+		/* Clear interrupt state */
+		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
+		ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
+
+		/*
+		 * Although the driver does not care about the
+		 * 'Selection in Progress' status bit, the busy
+		 * LED does.  SELINGO is only cleared by a sucessfull
+		 * selection, so we must manually clear it to insure
+		 * the LED turns off just incase no future successful
+		 * selections occur (e.g. no devices on the bus).
+		 */
+		ahc_outb(ahc, CLRSINT0, CLRSELINGO);
+
+		scbptr = ahc_inb(ahc, WAITING_SCBH);
+		ahc_outb(ahc, SCBPTR, scbptr);
+		scb_index = ahc_inb(ahc, SCB_TAG);
+
+		scb = ahc_lookup_scb(ahc, scb_index);
+		if (scb == NULL) {
+			printf("%s: ahc_intr - referenced scb not "
+			       "valid during SELTO scb(%d, %d)\n",
+			       ahc_name(ahc), scbptr, scb_index);
+		} else {
+			ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
+			ahc_freeze_devq(ahc, scb);
+		}
+		ahc_outb(ahc, CLRINT, CLRSCSIINT);
+		/*
+		 * Force a renegotiation with this target just in
+		 * case the cable was pulled and will later be
+		 * re-attached.  The target may forget its negotiation
+		 * settings with us should it attempt to reselect
+		 * during the interruption.  The target will not issue
+		 * a unit attention in this case, so we must always
+		 * renegotiate.
+		 */
+		ahc_force_renegotiation(ahc);
+		ahc_restart(ahc);
+	} else if ((status & BUSFREE) != 0
+		&& (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
+		u_int lastphase;
+		u_int saved_scsiid;
+		u_int saved_lun;
+		u_int target;
+		u_int initiator_role_id;
+		char channel;
+		int printerror;
+
+		/*
+		 * Clear our selection hardware as soon as possible.
+		 * We may have an entry in the waiting Q for this target,
+		 * that is affected by this busfree and we don't want to
+		 * go about selecting the target while we handle the event.
+		 */
+		ahc_outb(ahc, SCSISEQ,
+			 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
+
+		/*
+		 * Disable busfree interrupts and clear the busfree
+		 * interrupt status.  We do this here so that several
+		 * bus transactions occur prior to clearing the SCSIINT
+		 * latch.  It can take a bit for the clearing to take effect.
+		 */
+		ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
+		ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
+
+		/*
+		 * Look at what phase we were last in.
+		 * If its message out, chances are pretty good
+		 * that the busfree was in response to one of
+		 * our abort requests.
+		 */
+		lastphase = ahc_inb(ahc, LASTPHASE);
+		saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
+		saved_lun = ahc_inb(ahc, SAVED_LUN);
+		target = SCSIID_TARGET(ahc, saved_scsiid);
+		initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
+		channel = SCSIID_CHANNEL(ahc, saved_scsiid);
+		printerror = 1;
+
+		if (lastphase == P_MESGOUT) {
+			struct ahc_devinfo devinfo;
+			u_int tag;
+
+			ahc_fetch_devinfo(ahc, &devinfo);
+			tag = SCB_LIST_NULL;
+			if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)
+			 || ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {
+				if (ahc->msgout_buf[ahc->msgout_index - 1]
+				 == MSG_ABORT_TAG)
+					tag = scb->hscb->tag;
+				ahc_print_path(ahc, scb);
+				printf("SCB %d - Abort%s Completed.\n",
+				       scb->hscb->tag, tag == SCB_LIST_NULL ?
+				       "" : " Tag");
+				ahc_abort_scbs(ahc, target, channel,
+					       saved_lun, tag,
+					       ROLE_INITIATOR,
+					       CAM_REQ_ABORTED);
+				printerror = 0;
+			} else if (ahc_sent_msg(ahc, AHCMSG_1B,
+						MSG_BUS_DEV_RESET, TRUE)) {
+#ifdef __FreeBSD__
+				/*
+				 * Don't mark the user's request for this BDR
+				 * as completing with CAM_BDR_SENT.  CAM3
+				 * specifies CAM_REQ_CMP.
+				 */
+				if (scb != NULL
+				 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
+				 && ahc_match_scb(ahc, scb, target, channel,
+						  CAM_LUN_WILDCARD,
+						  SCB_LIST_NULL,
+						  ROLE_INITIATOR)) {
+					ahc_set_transaction_status(scb, CAM_REQ_CMP);
+				}
+#endif
+				ahc_compile_devinfo(&devinfo,
+						    initiator_role_id,
+						    target,
+						    CAM_LUN_WILDCARD,
+						    channel,
+						    ROLE_INITIATOR);
+				ahc_handle_devreset(ahc, &devinfo,
+						    CAM_BDR_SENT,
+						    "Bus Device Reset",
+						    /*verbose_level*/0);
+				printerror = 0;
+			} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
+						MSG_EXT_PPR, FALSE)) {
+				struct ahc_initiator_tinfo *tinfo;
+				struct ahc_tmode_tstate *tstate;
+
+				/*
+				 * PPR Rejected.  Try non-ppr negotiation
+				 * and retry command.
+				 */
+				tinfo = ahc_fetch_transinfo(ahc,
+							    devinfo.channel,
+							    devinfo.our_scsiid,
+							    devinfo.target,
+							    &tstate);
+				tinfo->curr.transport_version = 2;
+				tinfo->goal.transport_version = 2;
+				tinfo->goal.ppr_options = 0;
+				ahc_qinfifo_requeue_tail(ahc, scb);
+				printerror = 0;
+			} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
+						MSG_EXT_WDTR, FALSE)
+				|| ahc_sent_msg(ahc, AHCMSG_EXT,
+						MSG_EXT_SDTR, FALSE)) {
+				/*
+				 * Negotiation Rejected.  Go-async and
+				 * retry command.
+				 */
+				ahc_set_width(ahc, &devinfo,
+					      MSG_EXT_WDTR_BUS_8_BIT,
+					      AHC_TRANS_CUR|AHC_TRANS_GOAL,
+					      /*paused*/TRUE);
+				ahc_set_syncrate(ahc, &devinfo,
+						/*syncrate*/NULL,
+						/*period*/0, /*offset*/0,
+						/*ppr_options*/0,
+						AHC_TRANS_CUR|AHC_TRANS_GOAL,
+						/*paused*/TRUE);
+				ahc_qinfifo_requeue_tail(ahc, scb);
+				printerror = 0;
+			}
+		}
+		if (printerror != 0) {
+			u_int i;
+
+			if (scb != NULL) {
+				u_int tag;
+
+				if ((scb->hscb->control & TAG_ENB) != 0)
+					tag = scb->hscb->tag;
+				else
+					tag = SCB_LIST_NULL;
+				ahc_print_path(ahc, scb);
+				ahc_abort_scbs(ahc, target, channel,
+					       SCB_GET_LUN(scb), tag,
+					       ROLE_INITIATOR,
+					       CAM_UNEXP_BUSFREE);
+			} else {
+				/*
+				 * We had not fully identified this connection,
+				 * so we cannot abort anything.
+				 */
+				printf("%s: ", ahc_name(ahc));
+			}
+			for (i = 0; i < num_phases; i++) {
+				if (lastphase == ahc_phase_table[i].phase)
+					break;
+			}
+			/*
+			 * Renegotiate with this device at the
+			 * next oportunity just in case this busfree
+			 * is due to a negotiation mismatch with the
+			 * device.
+			 */
+			ahc_force_renegotiation(ahc);
+			printf("Unexpected busfree %s\n"
+			       "SEQADDR == 0x%x\n",
+			       ahc_phase_table[i].phasemsg,
+			       ahc_inb(ahc, SEQADDR0)
+				| (ahc_inb(ahc, SEQADDR1) << 8));
+		}
+		ahc_outb(ahc, CLRINT, CLRSCSIINT);
+		ahc_restart(ahc);
+	} else {
+		printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",
+		       ahc_name(ahc), status);
+		ahc_outb(ahc, CLRINT, CLRSCSIINT);
+	}
+}
+
+/*
+ * Force renegotiation to occur the next time we initiate
+ * a command to the current device.
+ */
+static void
+ahc_force_renegotiation(struct ahc_softc *ahc)
+{
+	struct	ahc_devinfo devinfo;
+	struct	ahc_initiator_tinfo *targ_info;
+	struct	ahc_tmode_tstate *tstate;
+
+	ahc_fetch_devinfo(ahc, &devinfo);
+	targ_info = ahc_fetch_transinfo(ahc,
+					devinfo.channel,
+					devinfo.our_scsiid,
+					devinfo.target,
+					&tstate);
+	ahc_update_neg_request(ahc, &devinfo, tstate,
+			       targ_info, /*force*/TRUE);
+}
+
+#define AHC_MAX_STEPS 2000
+void
+ahc_clear_critical_section(struct ahc_softc *ahc)
+{
+	int	stepping;
+	int	steps;
+	u_int	simode0;
+	u_int	simode1;
+
+	if (ahc->num_critical_sections == 0)
+		return;
+
+	stepping = FALSE;
+	steps = 0;
+	simode0 = 0;
+	simode1 = 0;
+	for (;;) {
+		struct	cs *cs;
+		u_int	seqaddr;
+		u_int	i;
+
+		seqaddr = ahc_inb(ahc, SEQADDR0)
+			| (ahc_inb(ahc, SEQADDR1) << 8);
+
+		/*
+		 * Seqaddr represents the next instruction to execute, 
+		 * so we are really executing the instruction just
+		 * before it.
+		 */
+		if (seqaddr != 0)
+			seqaddr -= 1;
+		cs = ahc->critical_sections;
+		for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
+			
+			if (cs->begin < seqaddr && cs->end >= seqaddr)
+				break;
+		}
+
+		if (i == ahc->num_critical_sections)
+			break;
+
+		if (steps > AHC_MAX_STEPS) {
+			printf("%s: Infinite loop in critical section\n",
+			       ahc_name(ahc));
+			ahc_dump_card_state(ahc);
+			panic("critical section loop");
+		}
+
+		steps++;
+		if (stepping == FALSE) {
+
+			/*
+			 * Disable all interrupt sources so that the
+			 * sequencer will not be stuck by a pausing
+			 * interrupt condition while we attempt to
+			 * leave a critical section.
+			 */
+			simode0 = ahc_inb(ahc, SIMODE0);
+			ahc_outb(ahc, SIMODE0, 0);
+			simode1 = ahc_inb(ahc, SIMODE1);
+			ahc_outb(ahc, SIMODE1, 0);
+			ahc_outb(ahc, CLRINT, CLRSCSIINT);
+			ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) | STEP);
+			stepping = TRUE;
+		}
+		ahc_outb(ahc, HCNTRL, ahc->unpause);
+		while (!ahc_is_paused(ahc))
+			ahc_delay(200);
+	}
+	if (stepping) {
+		ahc_outb(ahc, SIMODE0, simode0);
+		ahc_outb(ahc, SIMODE1, simode1);
+		ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) & ~STEP);
+	}
+}
+
+/*
+ * Clear any pending interrupt status.
+ */
+void
+ahc_clear_intstat(struct ahc_softc *ahc)
+{
+	/* Clear any interrupt conditions this may have caused */
+	ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
+				|CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
+				CLRREQINIT);
+	ahc_flush_device_writes(ahc);
+	ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
+ 	ahc_flush_device_writes(ahc);
+	ahc_outb(ahc, CLRINT, CLRSCSIINT);
+	ahc_flush_device_writes(ahc);
+}
+
+/**************************** Debugging Routines ******************************/
+#ifdef AHC_DEBUG
+int ahc_debug = AHC_DEBUG;
+#endif
+
+void
+ahc_print_scb(struct scb *scb)
+{
+	int i;
+
+	struct hardware_scb *hscb = scb->hscb;
+
+	printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
+	       (void *)scb,
+	       hscb->control,
+	       hscb->scsiid,
+	       hscb->lun,
+	       hscb->cdb_len);
+	printf("Shared Data: ");
+	for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
+		printf("%#02x", hscb->shared_data.cdb[i]);
+	printf("        dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
+		ahc_le32toh(hscb->dataptr),
+		ahc_le32toh(hscb->datacnt),
+		ahc_le32toh(hscb->sgptr),
+		hscb->tag);
+	if (scb->sg_count > 0) {
+		for (i = 0; i < scb->sg_count; i++) {
+			printf("sg[%d] - Addr 0x%x%x : Length %d\n",
+			       i,
+			       (ahc_le32toh(scb->sg_list[i].len) >> 24
+			        & SG_HIGH_ADDR_BITS),
+			       ahc_le32toh(scb->sg_list[i].addr),
+			       ahc_le32toh(scb->sg_list[i].len));
+		}
+	}
+}
+
+/************************* Transfer Negotiation *******************************/
+/*
+ * Allocate per target mode instance (ID we respond to as a target)
+ * transfer negotiation data structures.
+ */
+static struct ahc_tmode_tstate *
+ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
+{
+	struct ahc_tmode_tstate *master_tstate;
+	struct ahc_tmode_tstate *tstate;
+	int i;
+
+	master_tstate = ahc->enabled_targets[ahc->our_id];
+	if (channel == 'B') {
+		scsi_id += 8;
+		master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];
+	}
+	if (ahc->enabled_targets[scsi_id] != NULL
+	 && ahc->enabled_targets[scsi_id] != master_tstate)
+		panic("%s: ahc_alloc_tstate - Target already allocated",
+		      ahc_name(ahc));
+	tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT);
+	if (tstate == NULL)
+		return (NULL);
+
+	/*
+	 * If we have allocated a master tstate, copy user settings from
+	 * the master tstate (taken from SRAM or the EEPROM) for this
+	 * channel, but reset our current and goal settings to async/narrow
+	 * until an initiator talks to us.
+	 */
+	if (master_tstate != NULL) {
+		memcpy(tstate, master_tstate, sizeof(*tstate));
+		memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
+		tstate->ultraenb = 0;
+		for (i = 0; i < AHC_NUM_TARGETS; i++) {
+			memset(&tstate->transinfo[i].curr, 0,
+			      sizeof(tstate->transinfo[i].curr));
+			memset(&tstate->transinfo[i].goal, 0,
+			      sizeof(tstate->transinfo[i].goal));
+		}
+	} else
+		memset(tstate, 0, sizeof(*tstate));
+	ahc->enabled_targets[scsi_id] = tstate;
+	return (tstate);
+}
+
+#ifdef AHC_TARGET_MODE
+/*
+ * Free per target mode instance (ID we respond to as a target)
+ * transfer negotiation data structures.
+ */
+static void
+ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
+{
+	struct ahc_tmode_tstate *tstate;
+
+	/*
+	 * Don't clean up our "master" tstate.
+	 * It has our default user settings.
+	 */
+	if (((channel == 'B' && scsi_id == ahc->our_id_b)
+	  || (channel == 'A' && scsi_id == ahc->our_id))
+	 && force == FALSE)
+		return;
+
+	if (channel == 'B')
+		scsi_id += 8;
+	tstate = ahc->enabled_targets[scsi_id];
+	if (tstate != NULL)
+		free(tstate, M_DEVBUF);
+	ahc->enabled_targets[scsi_id] = NULL;
+}
+#endif
+
+/*
+ * Called when we have an active connection to a target on the bus,
+ * this function finds the nearest syncrate to the input period limited
+ * by the capabilities of the bus connectivity of and sync settings for
+ * the target.
+ */
+struct ahc_syncrate *
+ahc_devlimited_syncrate(struct ahc_softc *ahc,
+			struct ahc_initiator_tinfo *tinfo,
+			u_int *period, u_int *ppr_options, role_t role)
+{
+	struct	ahc_transinfo *transinfo;
+	u_int	maxsync;
+
+	if ((ahc->features & AHC_ULTRA2) != 0) {
+		if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0
+		 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {
+			maxsync = AHC_SYNCRATE_DT;
+		} else {
+			maxsync = AHC_SYNCRATE_ULTRA;
+			/* Can't do DT on an SE bus */
+			*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
+		}
+	} else if ((ahc->features & AHC_ULTRA) != 0) {
+		maxsync = AHC_SYNCRATE_ULTRA;
+	} else {
+		maxsync = AHC_SYNCRATE_FAST;
+	}
+	/*
+	 * Never allow a value higher than our current goal
+	 * period otherwise we may allow a target initiated
+	 * negotiation to go above the limit as set by the
+	 * user.  In the case of an initiator initiated
+	 * sync negotiation, we limit based on the user
+	 * setting.  This allows the system to still accept
+	 * incoming negotiations even if target initiated
+	 * negotiation is not performed.
+	 */
+	if (role == ROLE_TARGET)
+		transinfo = &tinfo->user;
+	else 
+		transinfo = &tinfo->goal;
+	*ppr_options &= transinfo->ppr_options;
+	if (transinfo->period == 0) {
+		*period = 0;
+		*ppr_options = 0;
+		return (NULL);
+	}
+	*period = MAX(*period, transinfo->period);
+	return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
+}
+
+/*
+ * Look up the valid period to SCSIRATE conversion in our table.
+ * Return the period and offset that should be sent to the target
+ * if this was the beginning of an SDTR.
+ */
+struct ahc_syncrate *
+ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
+		  u_int *ppr_options, u_int maxsync)
+{
+	struct ahc_syncrate *syncrate;
+
+	if ((ahc->features & AHC_DT) == 0)
+		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
+
+	/* Skip all DT only entries if DT is not available */
+	if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
+	 && maxsync < AHC_SYNCRATE_ULTRA2)
+		maxsync = AHC_SYNCRATE_ULTRA2;
+	
+	for (syncrate = &ahc_syncrates[maxsync];
+	     syncrate->rate != NULL;
+	     syncrate++) {
+
+		/*
+		 * The Ultra2 table doesn't go as low
+		 * as for the Fast/Ultra cards.
+		 */
+		if ((ahc->features & AHC_ULTRA2) != 0
+		 && (syncrate->sxfr_u2 == 0))
+			break;
+
+		if (*period <= syncrate->period) {
+			/*
+			 * When responding to a target that requests
+			 * sync, the requested rate may fall between
+			 * two rates that we can output, but still be
+			 * a rate that we can receive.  Because of this,
+			 * we want to respond to the target with
+			 * the same rate that it sent to us even
+			 * if the period we use to send data to it
+			 * is lower.  Only lower the response period
+			 * if we must.
+			 */
+			if (syncrate == &ahc_syncrates[maxsync])
+				*period = syncrate->period;
+
+			/*
+			 * At some speeds, we only support
+			 * ST transfers.
+			 */
+		 	if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
+				*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
+			break;
+		}
+	}
+
+	if ((*period == 0)
+	 || (syncrate->rate == NULL)
+	 || ((ahc->features & AHC_ULTRA2) != 0
+	  && (syncrate->sxfr_u2 == 0))) {
+		/* Use asynchronous transfers. */
+		*period = 0;
+		syncrate = NULL;
+		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
+	}
+	return (syncrate);
+}
+
+/*
+ * Convert from an entry in our syncrate table to the SCSI equivalent
+ * sync "period" factor.
+ */
+u_int
+ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
+{
+	struct ahc_syncrate *syncrate;
+
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		scsirate &= SXFR_ULTRA2;
+	else
+		scsirate &= SXFR;
+
+	syncrate = &ahc_syncrates[maxsync];
+	while (syncrate->rate != NULL) {
+
+		if ((ahc->features & AHC_ULTRA2) != 0) {
+			if (syncrate->sxfr_u2 == 0)
+				break;
+			else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))
+				return (syncrate->period);
+		} else if (scsirate == (syncrate->sxfr & SXFR)) {
+				return (syncrate->period);
+		}
+		syncrate++;
+	}
+	return (0); /* async */
+}
+
+/*
+ * Truncate the given synchronous offset to a value the
+ * current adapter type and syncrate are capable of.
+ */
+void
+ahc_validate_offset(struct ahc_softc *ahc,
+		    struct ahc_initiator_tinfo *tinfo,
+		    struct ahc_syncrate *syncrate,
+		    u_int *offset, int wide, role_t role)
+{
+	u_int maxoffset;
+
+	/* Limit offset to what we can do */
+	if (syncrate == NULL) {
+		maxoffset = 0;
+	} else if ((ahc->features & AHC_ULTRA2) != 0) {
+		maxoffset = MAX_OFFSET_ULTRA2;
+	} else {
+		if (wide)
+			maxoffset = MAX_OFFSET_16BIT;
+		else
+			maxoffset = MAX_OFFSET_8BIT;
+	}
+	*offset = MIN(*offset, maxoffset);
+	if (tinfo != NULL) {
+		if (role == ROLE_TARGET)
+			*offset = MIN(*offset, tinfo->user.offset);
+		else
+			*offset = MIN(*offset, tinfo->goal.offset);
+	}
+}
+
+/*
+ * Truncate the given transfer width parameter to a value the
+ * current adapter type is capable of.
+ */
+void
+ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo,
+		   u_int *bus_width, role_t role)
+{
+	switch (*bus_width) {
+	default:
+		if (ahc->features & AHC_WIDE) {
+			/* Respond Wide */
+			*bus_width = MSG_EXT_WDTR_BUS_16_BIT;
+			break;
+		}
+		/* FALLTHROUGH */
+	case MSG_EXT_WDTR_BUS_8_BIT:
+		*bus_width = MSG_EXT_WDTR_BUS_8_BIT;
+		break;
+	}
+	if (tinfo != NULL) {
+		if (role == ROLE_TARGET)
+			*bus_width = MIN(tinfo->user.width, *bus_width);
+		else
+			*bus_width = MIN(tinfo->goal.width, *bus_width);
+	}
+}
+
+/*
+ * Update the bitmask of targets for which the controller should
+ * negotiate with at the next convenient oportunity.  This currently
+ * means the next time we send the initial identify messages for
+ * a new transaction.
+ */
+int
+ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		       struct ahc_tmode_tstate *tstate,
+		       struct ahc_initiator_tinfo *tinfo, int force)
+{
+	u_int auto_negotiate_orig;
+
+	auto_negotiate_orig = tstate->auto_negotiate;
+	if (tinfo->curr.period != tinfo->goal.period
+	 || tinfo->curr.width != tinfo->goal.width
+	 || tinfo->curr.offset != tinfo->goal.offset
+	 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
+	 || (force
+	  && (tinfo->goal.period != 0
+	   || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
+	   || tinfo->goal.ppr_options != 0)))
+		tstate->auto_negotiate |= devinfo->target_mask;
+	else
+		tstate->auto_negotiate &= ~devinfo->target_mask;
+
+	return (auto_negotiate_orig != tstate->auto_negotiate);
+}
+
+/*
+ * Update the user/goal/curr tables of synchronous negotiation
+ * parameters as well as, in the case of a current or active update,
+ * any data structures on the host controller.  In the case of an
+ * active update, the specified target is currently talking to us on
+ * the bus, so the transfer parameter update must take effect
+ * immediately.
+ */
+void
+ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		 struct ahc_syncrate *syncrate, u_int period,
+		 u_int offset, u_int ppr_options, u_int type, int paused)
+{
+	struct	ahc_initiator_tinfo *tinfo;
+	struct	ahc_tmode_tstate *tstate;
+	u_int	old_period;
+	u_int	old_offset;
+	u_int	old_ppr;
+	int	active;
+	int	update_needed;
+
+	active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
+	update_needed = 0;
+
+	if (syncrate == NULL) {
+		period = 0;
+		offset = 0;
+	}
+
+	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
+				    devinfo->target, &tstate);
+
+	if ((type & AHC_TRANS_USER) != 0) {
+		tinfo->user.period = period;
+		tinfo->user.offset = offset;
+		tinfo->user.ppr_options = ppr_options;
+	}
+
+	if ((type & AHC_TRANS_GOAL) != 0) {
+		tinfo->goal.period = period;
+		tinfo->goal.offset = offset;
+		tinfo->goal.ppr_options = ppr_options;
+	}
+
+	old_period = tinfo->curr.period;
+	old_offset = tinfo->curr.offset;
+	old_ppr	   = tinfo->curr.ppr_options;
+
+	if ((type & AHC_TRANS_CUR) != 0
+	 && (old_period != period
+	  || old_offset != offset
+	  || old_ppr != ppr_options)) {
+		u_int	scsirate;
+
+		update_needed++;
+		scsirate = tinfo->scsirate;
+		if ((ahc->features & AHC_ULTRA2) != 0) {
+
+			scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);
+			if (syncrate != NULL) {
+				scsirate |= syncrate->sxfr_u2;
+				if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0)
+					scsirate |= ENABLE_CRC;
+				else
+					scsirate |= SINGLE_EDGE;
+			}
+		} else {
+
+			scsirate &= ~(SXFR|SOFS);
+			/*
+			 * Ensure Ultra mode is set properly for
+			 * this target.
+			 */
+			tstate->ultraenb &= ~devinfo->target_mask;
+			if (syncrate != NULL) {
+				if (syncrate->sxfr & ULTRA_SXFR) {
+					tstate->ultraenb |=
+						devinfo->target_mask;
+				}
+				scsirate |= syncrate->sxfr & SXFR;
+				scsirate |= offset & SOFS;
+			}
+			if (active) {
+				u_int sxfrctl0;
+
+				sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
+				sxfrctl0 &= ~FAST20;
+				if (tstate->ultraenb & devinfo->target_mask)
+					sxfrctl0 |= FAST20;
+				ahc_outb(ahc, SXFRCTL0, sxfrctl0);
+			}
+		}
+		if (active) {
+			ahc_outb(ahc, SCSIRATE, scsirate);
+			if ((ahc->features & AHC_ULTRA2) != 0)
+				ahc_outb(ahc, SCSIOFFSET, offset);
+		}
+
+		tinfo->scsirate = scsirate;
+		tinfo->curr.period = period;
+		tinfo->curr.offset = offset;
+		tinfo->curr.ppr_options = ppr_options;
+
+		ahc_send_async(ahc, devinfo->channel, devinfo->target,
+			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
+		if (bootverbose) {
+			if (offset != 0) {
+				printf("%s: target %d synchronous at %sMHz%s, "
+				       "offset = 0x%x\n", ahc_name(ahc),
+				       devinfo->target, syncrate->rate,
+				       (ppr_options & MSG_EXT_PPR_DT_REQ)
+				       ? " DT" : "", offset);
+			} else {
+				printf("%s: target %d using "
+				       "asynchronous transfers\n",
+				       ahc_name(ahc), devinfo->target);
+			}
+		}
+	}
+
+	update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
+						tinfo, /*force*/FALSE);
+
+	if (update_needed)
+		ahc_update_pending_scbs(ahc);
+}
+
+/*
+ * Update the user/goal/curr tables of wide negotiation
+ * parameters as well as, in the case of a current or active update,
+ * any data structures on the host controller.  In the case of an
+ * active update, the specified target is currently talking to us on
+ * the bus, so the transfer parameter update must take effect
+ * immediately.
+ */
+void
+ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+	      u_int width, u_int type, int paused)
+{
+	struct	ahc_initiator_tinfo *tinfo;
+	struct	ahc_tmode_tstate *tstate;
+	u_int	oldwidth;
+	int	active;
+	int	update_needed;
+
+	active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
+	update_needed = 0;
+	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
+				    devinfo->target, &tstate);
+
+	if ((type & AHC_TRANS_USER) != 0)
+		tinfo->user.width = width;
+
+	if ((type & AHC_TRANS_GOAL) != 0)
+		tinfo->goal.width = width;
+
+	oldwidth = tinfo->curr.width;
+	if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {
+		u_int	scsirate;
+
+		update_needed++;
+		scsirate =  tinfo->scsirate;
+		scsirate &= ~WIDEXFER;
+		if (width == MSG_EXT_WDTR_BUS_16_BIT)
+			scsirate |= WIDEXFER;
+
+		tinfo->scsirate = scsirate;
+
+		if (active)
+			ahc_outb(ahc, SCSIRATE, scsirate);
+
+		tinfo->curr.width = width;
+
+		ahc_send_async(ahc, devinfo->channel, devinfo->target,
+			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
+		if (bootverbose) {
+			printf("%s: target %d using %dbit transfers\n",
+			       ahc_name(ahc), devinfo->target,
+			       8 * (0x01 << width));
+		}
+	}
+
+	update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
+						tinfo, /*force*/FALSE);
+	if (update_needed)
+		ahc_update_pending_scbs(ahc);
+}
+
+/*
+ * Update the current state of tagged queuing for a given target.
+ */
+void
+ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+	     ahc_queue_alg alg)
+{
+ 	ahc_platform_set_tags(ahc, devinfo, alg);
+ 	ahc_send_async(ahc, devinfo->channel, devinfo->target,
+ 		       devinfo->lun, AC_TRANSFER_NEG, &alg);
+}
+
+/*
+ * When the transfer settings for a connection change, update any
+ * in-transit SCBs to contain the new data so the hardware will
+ * be set correctly during future (re)selections.
+ */
+static void
+ahc_update_pending_scbs(struct ahc_softc *ahc)
+{
+	struct	scb *pending_scb;
+	int	pending_scb_count;
+	int	i;
+	int	paused;
+	u_int	saved_scbptr;
+
+	/*
+	 * Traverse the pending SCB list and ensure that all of the
+	 * SCBs there have the proper settings.
+	 */
+	pending_scb_count = 0;
+	LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
+		struct ahc_devinfo devinfo;
+		struct hardware_scb *pending_hscb;
+		struct ahc_initiator_tinfo *tinfo;
+		struct ahc_tmode_tstate *tstate;
+
+		ahc_scb_devinfo(ahc, &devinfo, pending_scb);
+		tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
+					    devinfo.our_scsiid,
+					    devinfo.target, &tstate);
+		pending_hscb = pending_scb->hscb;
+		pending_hscb->control &= ~ULTRAENB;
+		if ((tstate->ultraenb & devinfo.target_mask) != 0)
+			pending_hscb->control |= ULTRAENB;
+		pending_hscb->scsirate = tinfo->scsirate;
+		pending_hscb->scsioffset = tinfo->curr.offset;
+		if ((tstate->auto_negotiate & devinfo.target_mask) == 0
+		 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
+			pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
+			pending_hscb->control &= ~MK_MESSAGE;
+		}
+		ahc_sync_scb(ahc, pending_scb,
+			     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+		pending_scb_count++;
+	}
+
+	if (pending_scb_count == 0)
+		return;
+
+	if (ahc_is_paused(ahc)) {
+		paused = 1;
+	} else {
+		paused = 0;
+		ahc_pause(ahc);
+	}
+
+	saved_scbptr = ahc_inb(ahc, SCBPTR);
+	/* Ensure that the hscbs down on the card match the new information */
+	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
+		struct	hardware_scb *pending_hscb;
+		u_int	control;
+		u_int	scb_tag;
+
+		ahc_outb(ahc, SCBPTR, i);
+		scb_tag = ahc_inb(ahc, SCB_TAG);
+		pending_scb = ahc_lookup_scb(ahc, scb_tag);
+		if (pending_scb == NULL)
+			continue;
+
+		pending_hscb = pending_scb->hscb;
+		control = ahc_inb(ahc, SCB_CONTROL);
+		control &= ~(ULTRAENB|MK_MESSAGE);
+		control |= pending_hscb->control & (ULTRAENB|MK_MESSAGE);
+		ahc_outb(ahc, SCB_CONTROL, control);
+		ahc_outb(ahc, SCB_SCSIRATE, pending_hscb->scsirate);
+		ahc_outb(ahc, SCB_SCSIOFFSET, pending_hscb->scsioffset);
+	}
+	ahc_outb(ahc, SCBPTR, saved_scbptr);
+
+	if (paused == 0)
+		ahc_unpause(ahc);
+}
+
+/**************************** Pathing Information *****************************/
+static void
+ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
+{
+	u_int	saved_scsiid;
+	role_t	role;
+	int	our_id;
+
+	if (ahc_inb(ahc, SSTAT0) & TARGET)
+		role = ROLE_TARGET;
+	else
+		role = ROLE_INITIATOR;
+
+	if (role == ROLE_TARGET
+	 && (ahc->features & AHC_MULTI_TID) != 0
+	 && (ahc_inb(ahc, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) {
+		/* We were selected, so pull our id from TARGIDIN */
+		our_id = ahc_inb(ahc, TARGIDIN) & OID;
+	} else if ((ahc->features & AHC_ULTRA2) != 0)
+		our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
+	else
+		our_id = ahc_inb(ahc, SCSIID) & OID;
+
+	saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
+	ahc_compile_devinfo(devinfo,
+			    our_id,
+			    SCSIID_TARGET(ahc, saved_scsiid),
+			    ahc_inb(ahc, SAVED_LUN),
+			    SCSIID_CHANNEL(ahc, saved_scsiid),
+			    role);
+}
+
+struct ahc_phase_table_entry*
+ahc_lookup_phase_entry(int phase)
+{
+	struct ahc_phase_table_entry *entry;
+	struct ahc_phase_table_entry *last_entry;
+
+	/*
+	 * num_phases doesn't include the default entry which
+	 * will be returned if the phase doesn't match.
+	 */
+	last_entry = &ahc_phase_table[num_phases];
+	for (entry = ahc_phase_table; entry < last_entry; entry++) {
+		if (phase == entry->phase)
+			break;
+	}
+	return (entry);
+}
+
+void
+ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
+		    u_int lun, char channel, role_t role)
+{
+	devinfo->our_scsiid = our_id;
+	devinfo->target = target;
+	devinfo->lun = lun;
+	devinfo->target_offset = target;
+	devinfo->channel = channel;
+	devinfo->role = role;
+	if (channel == 'B')
+		devinfo->target_offset += 8;
+	devinfo->target_mask = (0x01 << devinfo->target_offset);
+}
+
+static void
+ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		struct scb *scb)
+{
+	role_t	role;
+	int	our_id;
+
+	our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
+	role = ROLE_INITIATOR;
+	if ((scb->hscb->control & TARGET_SCB) != 0)
+		role = ROLE_TARGET;
+	ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb),
+			    SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role);
+}
+
+
+/************************ Message Phase Processing ****************************/
+static void
+ahc_assert_atn(struct ahc_softc *ahc)
+{
+	u_int scsisigo;
+
+	scsisigo = ATNO;
+	if ((ahc->features & AHC_DT) == 0)
+		scsisigo |= ahc_inb(ahc, SCSISIGI);
+	ahc_outb(ahc, SCSISIGO, scsisigo);
+}
+
+/*
+ * When an initiator transaction with the MK_MESSAGE flag either reconnects
+ * or enters the initial message out phase, we are interrupted.  Fill our
+ * outgoing message buffer with the appropriate message and beging handing
+ * the message phase(s) manually.
+ */
+static void
+ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+			   struct scb *scb)
+{
+	/*
+	 * To facilitate adding multiple messages together,
+	 * each routine should increment the index and len
+	 * variables instead of setting them explicitly.
+	 */
+	ahc->msgout_index = 0;
+	ahc->msgout_len = 0;
+
+	if ((scb->flags & SCB_DEVICE_RESET) == 0
+	 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {
+		u_int identify_msg;
+
+		identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
+		if ((scb->hscb->control & DISCENB) != 0)
+			identify_msg |= MSG_IDENTIFY_DISCFLAG;
+		ahc->msgout_buf[ahc->msgout_index++] = identify_msg;
+		ahc->msgout_len++;
+
+		if ((scb->hscb->control & TAG_ENB) != 0) {
+			ahc->msgout_buf[ahc->msgout_index++] =
+			    scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
+			ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;
+			ahc->msgout_len += 2;
+		}
+	}
+
+	if (scb->flags & SCB_DEVICE_RESET) {
+		ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
+		ahc->msgout_len++;
+		ahc_print_path(ahc, scb);
+		printf("Bus Device Reset Message Sent\n");
+		/*
+		 * Clear our selection hardware in advance of
+		 * the busfree.  We may have an entry in the waiting
+		 * Q for this target, and we don't want to go about
+		 * selecting while we handle the busfree and blow it
+		 * away.
+		 */
+		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
+	} else if ((scb->flags & SCB_ABORT) != 0) {
+		if ((scb->hscb->control & TAG_ENB) != 0)
+			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;
+		else
+			ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
+		ahc->msgout_len++;
+		ahc_print_path(ahc, scb);
+		printf("Abort%s Message Sent\n",
+		       (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
+		/*
+		 * Clear our selection hardware in advance of
+		 * the busfree.  We may have an entry in the waiting
+		 * Q for this target, and we don't want to go about
+		 * selecting while we handle the busfree and blow it
+		 * away.
+		 */
+		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
+	} else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
+		ahc_build_transfer_msg(ahc, devinfo);
+	} else {
+		printf("ahc_intr: AWAITING_MSG for an SCB that "
+		       "does not have a waiting message\n");
+		printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
+		       devinfo->target_mask);
+		panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
+		      "SCB flags = %x", scb->hscb->tag, scb->hscb->control,
+		      ahc_inb(ahc, MSG_OUT), scb->flags);
+	}
+
+	/*
+	 * Clear the MK_MESSAGE flag from the SCB so we aren't
+	 * asked to send this message again.
+	 */
+	ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);
+	scb->hscb->control &= ~MK_MESSAGE;
+	ahc->msgout_index = 0;
+	ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
+}
+
+/*
+ * Build an appropriate transfer negotiation message for the
+ * currently active target.
+ */
+static void
+ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
+{
+	/*
+	 * We need to initiate transfer negotiations.
+	 * If our current and goal settings are identical,
+	 * we want to renegotiate due to a check condition.
+	 */
+	struct	ahc_initiator_tinfo *tinfo;
+	struct	ahc_tmode_tstate *tstate;
+	struct	ahc_syncrate *rate;
+	int	dowide;
+	int	dosync;
+	int	doppr;
+	int	use_ppr;
+	u_int	period;
+	u_int	ppr_options;
+	u_int	offset;
+
+	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
+				    devinfo->target, &tstate);
+	/*
+	 * Filter our period based on the current connection.
+	 * If we can't perform DT transfers on this segment (not in LVD
+	 * mode for instance), then our decision to issue a PPR message
+	 * may change.
+	 */
+	period = tinfo->goal.period;
+	ppr_options = tinfo->goal.ppr_options;
+	/* Target initiated PPR is not allowed in the SCSI spec */
+	if (devinfo->role == ROLE_TARGET)
+		ppr_options = 0;
+	rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
+				       &ppr_options, devinfo->role);
+	dowide = tinfo->curr.width != tinfo->goal.width;
+	dosync = tinfo->curr.period != period;
+	doppr = tinfo->curr.ppr_options != ppr_options;
+
+	if (!dowide && !dosync && !doppr) {
+		dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
+		dosync = tinfo->goal.period != 0;
+		doppr = tinfo->goal.ppr_options != 0;
+	}
+
+	if (!dowide && !dosync && !doppr) {
+		panic("ahc_intr: AWAITING_MSG for negotiation, "
+		      "but no negotiation needed\n");	
+	}
+
+	use_ppr = (tinfo->curr.transport_version >= 3) || doppr;
+	/* Target initiated PPR is not allowed in the SCSI spec */
+	if (devinfo->role == ROLE_TARGET)
+		use_ppr = 0;
+
+	/*
+	 * Both the PPR message and SDTR message require the
+	 * goal syncrate to be limited to what the target device
+	 * is capable of handling (based on whether an LVD->SE
+	 * expander is on the bus), so combine these two cases.
+	 * Regardless, guarantee that if we are using WDTR and SDTR
+	 * messages that WDTR comes first.
+	 */
+	if (use_ppr || (dosync && !dowide)) {
+
+		offset = tinfo->goal.offset;
+		ahc_validate_offset(ahc, tinfo, rate, &offset,
+				    use_ppr ? tinfo->goal.width
+					    : tinfo->curr.width,
+				    devinfo->role);
+		if (use_ppr) {
+			ahc_construct_ppr(ahc, devinfo, period, offset,
+					  tinfo->goal.width, ppr_options);
+		} else {
+			ahc_construct_sdtr(ahc, devinfo, period, offset);
+		}
+	} else {
+		ahc_construct_wdtr(ahc, devinfo, tinfo->goal.width);
+	}
+}
+
+/*
+ * Build a synchronous negotiation message in our message
+ * buffer based on the input parameters.
+ */
+static void
+ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		   u_int period, u_int offset)
+{
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN;
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
+	ahc->msgout_buf[ahc->msgout_index++] = period;
+	ahc->msgout_buf[ahc->msgout_index++] = offset;
+	ahc->msgout_len += 5;
+	if (bootverbose) {
+		printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
+		       ahc_name(ahc), devinfo->channel, devinfo->target,
+		       devinfo->lun, period, offset);
+	}
+}
+
+/*
+ * Build a wide negotiation message in our message
+ * buffer based on the input parameters.
+ */
+static void
+ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		   u_int bus_width)
+{
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN;
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
+	ahc->msgout_buf[ahc->msgout_index++] = bus_width;
+	ahc->msgout_len += 4;
+	if (bootverbose) {
+		printf("(%s:%c:%d:%d): Sending WDTR %x\n",
+		       ahc_name(ahc), devinfo->channel, devinfo->target,
+		       devinfo->lun, bus_width);
+	}
+}
+
+/*
+ * Build a parallel protocol request message in our message
+ * buffer based on the input parameters.
+ */
+static void
+ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		  u_int period, u_int offset, u_int bus_width,
+		  u_int ppr_options)
+{
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN;
+	ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR;
+	ahc->msgout_buf[ahc->msgout_index++] = period;
+	ahc->msgout_buf[ahc->msgout_index++] = 0;
+	ahc->msgout_buf[ahc->msgout_index++] = offset;
+	ahc->msgout_buf[ahc->msgout_index++] = bus_width;
+	ahc->msgout_buf[ahc->msgout_index++] = ppr_options;
+	ahc->msgout_len += 8;
+	if (bootverbose) {
+		printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
+		       "offset %x, ppr_options %x\n", ahc_name(ahc),
+		       devinfo->channel, devinfo->target, devinfo->lun,
+		       bus_width, period, offset, ppr_options);
+	}
+}
+
+/*
+ * Clear any active message state.
+ */
+static void
+ahc_clear_msg_state(struct ahc_softc *ahc)
+{
+	ahc->msgout_len = 0;
+	ahc->msgin_index = 0;
+	ahc->msg_type = MSG_TYPE_NONE;
+	if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {
+		/*
+		 * The target didn't care to respond to our
+		 * message request, so clear ATN.
+		 */
+		ahc_outb(ahc, CLRSINT1, CLRATNO);
+	}
+	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
+	ahc_outb(ahc, SEQ_FLAGS2,
+		 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
+}
+
+/*
+ * Manual message loop handler.
+ */
+static void
+ahc_handle_message_phase(struct ahc_softc *ahc)
+{ 
+	struct	ahc_devinfo devinfo;
+	u_int	bus_phase;
+	int	end_session;
+
+	ahc_fetch_devinfo(ahc, &devinfo);
+	end_session = FALSE;
+	bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
+
+reswitch:
+	switch (ahc->msg_type) {
+	case MSG_TYPE_INITIATOR_MSGOUT:
+	{
+		int lastbyte;
+		int phasemis;
+		int msgdone;
+
+		if (ahc->msgout_len == 0)
+			panic("HOST_MSG_LOOP interrupt with no active message");
+
+		phasemis = bus_phase != P_MESGOUT;
+		if (phasemis) {
+			if (bus_phase == P_MESGIN) {
+				/*
+				 * Change gears and see if
+				 * this messages is of interest to
+				 * us or should be passed back to
+				 * the sequencer.
+				 */
+				ahc_outb(ahc, CLRSINT1, CLRATNO);
+				ahc->send_msg_perror = FALSE;
+				ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;
+				ahc->msgin_index = 0;
+				goto reswitch;
+			}
+			end_session = TRUE;
+			break;
+		}
+
+		if (ahc->send_msg_perror) {
+			ahc_outb(ahc, CLRSINT1, CLRATNO);
+			ahc_outb(ahc, CLRSINT1, CLRREQINIT);
+			ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
+			break;
+		}
+
+		msgdone	= ahc->msgout_index == ahc->msgout_len;
+		if (msgdone) {
+			/*
+			 * The target has requested a retry.
+			 * Re-assert ATN, reset our message index to
+			 * 0, and try again.
+			 */
+			ahc->msgout_index = 0;
+			ahc_assert_atn(ahc);
+		}
+
+		lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);
+		if (lastbyte) {
+			/* Last byte is signified by dropping ATN */
+			ahc_outb(ahc, CLRSINT1, CLRATNO);
+		}
+
+		/*
+		 * Clear our interrupt status and present
+		 * the next byte on the bus.
+		 */
+		ahc_outb(ahc, CLRSINT1, CLRREQINIT);
+		ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
+		break;
+	}
+	case MSG_TYPE_INITIATOR_MSGIN:
+	{
+		int phasemis;
+		int message_done;
+
+		phasemis = bus_phase != P_MESGIN;
+
+		if (phasemis) {
+			ahc->msgin_index = 0;
+			if (bus_phase == P_MESGOUT
+			 && (ahc->send_msg_perror == TRUE
+			  || (ahc->msgout_len != 0
+			   && ahc->msgout_index == 0))) {
+				ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
+				goto reswitch;
+			}
+			end_session = TRUE;
+			break;
+		}
+
+		/* Pull the byte in without acking it */
+		ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
+
+		message_done = ahc_parse_msg(ahc, &devinfo);
+
+		if (message_done) {
+			/*
+			 * Clear our incoming message buffer in case there
+			 * is another message following this one.
+			 */
+			ahc->msgin_index = 0;
+
+			/*
+			 * If this message illicited a response,
+			 * assert ATN so the target takes us to the
+			 * message out phase.
+			 */
+			if (ahc->msgout_len != 0)
+				ahc_assert_atn(ahc);
+		} else 
+			ahc->msgin_index++;
+
+		if (message_done == MSGLOOP_TERMINATED) {
+			end_session = TRUE;
+		} else {
+			/* Ack the byte */
+			ahc_outb(ahc, CLRSINT1, CLRREQINIT);
+			ahc_inb(ahc, SCSIDATL);
+		}
+		break;
+	}
+	case MSG_TYPE_TARGET_MSGIN:
+	{
+		int msgdone;
+		int msgout_request;
+
+		if (ahc->msgout_len == 0)
+			panic("Target MSGIN with no active message");
+
+		/*
+		 * If we interrupted a mesgout session, the initiator
+		 * will not know this until our first REQ.  So, we
+		 * only honor mesgout requests after we've sent our
+		 * first byte.
+		 */
+		if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0
+		 && ahc->msgout_index > 0)
+			msgout_request = TRUE;
+		else
+			msgout_request = FALSE;
+
+		if (msgout_request) {
+
+			/*
+			 * Change gears and see if
+			 * this messages is of interest to
+			 * us or should be passed back to
+			 * the sequencer.
+			 */
+			ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;
+			ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);
+			ahc->msgin_index = 0;
+			/* Dummy read to REQ for first byte */
+			ahc_inb(ahc, SCSIDATL);
+			ahc_outb(ahc, SXFRCTL0,
+				 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
+			break;
+		}
+
+		msgdone = ahc->msgout_index == ahc->msgout_len;
+		if (msgdone) {
+			ahc_outb(ahc, SXFRCTL0,
+				 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
+			end_session = TRUE;
+			break;
+		}
+
+		/*
+		 * Present the next byte on the bus.
+		 */
+		ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);
+		ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
+		break;
+	}
+	case MSG_TYPE_TARGET_MSGOUT:
+	{
+		int lastbyte;
+		int msgdone;
+
+		/*
+		 * The initiator signals that this is
+		 * the last byte by dropping ATN.
+		 */
+		lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;
+
+		/*
+		 * Read the latched byte, but turn off SPIOEN first
+		 * so that we don't inadvertently cause a REQ for the
+		 * next byte.
+		 */
+		ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
+		ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);
+		msgdone = ahc_parse_msg(ahc, &devinfo);
+		if (msgdone == MSGLOOP_TERMINATED) {
+			/*
+			 * The message is *really* done in that it caused
+			 * us to go to bus free.  The sequencer has already
+			 * been reset at this point, so pull the ejection
+			 * handle.
+			 */
+			return;
+		}
+		
+		ahc->msgin_index++;
+
+		/*
+		 * XXX Read spec about initiator dropping ATN too soon
+		 *     and use msgdone to detect it.
+		 */
+		if (msgdone == MSGLOOP_MSGCOMPLETE) {
+			ahc->msgin_index = 0;
+
+			/*
+			 * If this message illicited a response, transition
+			 * to the Message in phase and send it.
+			 */
+			if (ahc->msgout_len != 0) {
+				ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);
+				ahc_outb(ahc, SXFRCTL0,
+					 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
+				ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
+				ahc->msgin_index = 0;
+				break;
+			}
+		}
+
+		if (lastbyte)
+			end_session = TRUE;
+		else {
+			/* Ask for the next byte. */
+			ahc_outb(ahc, SXFRCTL0,
+				 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
+		}
+
+		break;
+	}
+	default:
+		panic("Unknown REQINIT message type");
+	}
+
+	if (end_session) {
+		ahc_clear_msg_state(ahc);
+		ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);
+	} else
+		ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
+}
+
+/*
+ * See if we sent a particular extended message to the target.
+ * If "full" is true, return true only if the target saw the full
+ * message.  If "full" is false, return true if the target saw at
+ * least the first byte of the message.
+ */
+static int
+ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
+{
+	int found;
+	u_int index;
+
+	found = FALSE;
+	index = 0;
+
+	while (index < ahc->msgout_len) {
+		if (ahc->msgout_buf[index] == MSG_EXTENDED) {
+			u_int end_index;
+
+			end_index = index + 1 + ahc->msgout_buf[index + 1];
+			if (ahc->msgout_buf[index+2] == msgval
+			 && type == AHCMSG_EXT) {
+
+				if (full) {
+					if (ahc->msgout_index > end_index)
+						found = TRUE;
+				} else if (ahc->msgout_index > index)
+					found = TRUE;
+			}
+			index = end_index;
+		} else if (ahc->msgout_buf[index] >= MSG_SIMPLE_TASK
+			&& ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
+
+			/* Skip tag type and tag id or residue param*/
+			index += 2;
+		} else {
+			/* Single byte message */
+			if (type == AHCMSG_1B
+			 && ahc->msgout_buf[index] == msgval
+			 && ahc->msgout_index > index)
+				found = TRUE;
+			index++;
+		}
+
+		if (found)
+			break;
+	}
+	return (found);
+}
+
+/*
+ * Wait for a complete incoming message, parse it, and respond accordingly.
+ */
+static int
+ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
+{
+	struct	ahc_initiator_tinfo *tinfo;
+	struct	ahc_tmode_tstate *tstate;
+	int	reject;
+	int	done;
+	int	response;
+	u_int	targ_scsirate;
+
+	done = MSGLOOP_IN_PROG;
+	response = FALSE;
+	reject = FALSE;
+	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
+				    devinfo->target, &tstate);
+	targ_scsirate = tinfo->scsirate;
+
+	/*
+	 * Parse as much of the message as is availible,
+	 * rejecting it if we don't support it.  When
+	 * the entire message is availible and has been
+	 * handled, return MSGLOOP_MSGCOMPLETE, indicating
+	 * that we have parsed an entire message.
+	 *
+	 * In the case of extended messages, we accept the length
+	 * byte outright and perform more checking once we know the
+	 * extended message type.
+	 */
+	switch (ahc->msgin_buf[0]) {
+	case MSG_DISCONNECT:
+	case MSG_SAVEDATAPOINTER:
+	case MSG_CMDCOMPLETE:
+	case MSG_RESTOREPOINTERS:
+	case MSG_IGN_WIDE_RESIDUE:
+		/*
+		 * End our message loop as these are messages
+		 * the sequencer handles on its own.
+		 */
+		done = MSGLOOP_TERMINATED;
+		break;
+	case MSG_MESSAGE_REJECT:
+		response = ahc_handle_msg_reject(ahc, devinfo);
+		/* FALLTHROUGH */
+	case MSG_NOOP:
+		done = MSGLOOP_MSGCOMPLETE;
+		break;
+	case MSG_EXTENDED:
+	{
+		/* Wait for enough of the message to begin validation */
+		if (ahc->msgin_index < 2)
+			break;
+		switch (ahc->msgin_buf[2]) {
+		case MSG_EXT_SDTR:
+		{
+			struct	 ahc_syncrate *syncrate;
+			u_int	 period;
+			u_int	 ppr_options;
+			u_int	 offset;
+			u_int	 saved_offset;
+			
+			if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
+				reject = TRUE;
+				break;
+			}
+
+			/*
+			 * Wait until we have both args before validating
+			 * and acting on this message.
+			 *
+			 * Add one to MSG_EXT_SDTR_LEN to account for
+			 * the extended message preamble.
+			 */
+			if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))
+				break;
+
+			period = ahc->msgin_buf[3];
+			ppr_options = 0;
+			saved_offset = offset = ahc->msgin_buf[4];
+			syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
+							   &ppr_options,
+							   devinfo->role);
+			ahc_validate_offset(ahc, tinfo, syncrate, &offset,
+					    targ_scsirate & WIDEXFER,
+					    devinfo->role);
+			if (bootverbose) {
+				printf("(%s:%c:%d:%d): Received "
+				       "SDTR period %x, offset %x\n\t"
+				       "Filtered to period %x, offset %x\n",
+				       ahc_name(ahc), devinfo->channel,
+				       devinfo->target, devinfo->lun,
+				       ahc->msgin_buf[3], saved_offset,
+				       period, offset);
+			}
+			ahc_set_syncrate(ahc, devinfo, 
+					 syncrate, period,
+					 offset, ppr_options,
+					 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
+					 /*paused*/TRUE);
+
+			/*
+			 * See if we initiated Sync Negotiation
+			 * and didn't have to fall down to async
+			 * transfers.
+			 */
+			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, TRUE)) {
+				/* We started it */
+				if (saved_offset != offset) {
+					/* Went too low - force async */
+					reject = TRUE;
+				}
+			} else {
+				/*
+				 * Send our own SDTR in reply
+				 */
+				if (bootverbose
+				 && devinfo->role == ROLE_INITIATOR) {
+					printf("(%s:%c:%d:%d): Target "
+					       "Initiated SDTR\n",
+					       ahc_name(ahc), devinfo->channel,
+					       devinfo->target, devinfo->lun);
+				}
+				ahc->msgout_index = 0;
+				ahc->msgout_len = 0;
+				ahc_construct_sdtr(ahc, devinfo,
+						   period, offset);
+				ahc->msgout_index = 0;
+				response = TRUE;
+			}
+			done = MSGLOOP_MSGCOMPLETE;
+			break;
+		}
+		case MSG_EXT_WDTR:
+		{
+			u_int bus_width;
+			u_int saved_width;
+			u_int sending_reply;
+
+			sending_reply = FALSE;
+			if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
+				reject = TRUE;
+				break;
+			}
+
+			/*
+			 * Wait until we have our arg before validating
+			 * and acting on this message.
+			 *
+			 * Add one to MSG_EXT_WDTR_LEN to account for
+			 * the extended message preamble.
+			 */
+			if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))
+				break;
+
+			bus_width = ahc->msgin_buf[3];
+			saved_width = bus_width;
+			ahc_validate_width(ahc, tinfo, &bus_width,
+					   devinfo->role);
+			if (bootverbose) {
+				printf("(%s:%c:%d:%d): Received WDTR "
+				       "%x filtered to %x\n",
+				       ahc_name(ahc), devinfo->channel,
+				       devinfo->target, devinfo->lun,
+				       saved_width, bus_width);
+			}
+
+			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, TRUE)) {
+				/*
+				 * Don't send a WDTR back to the
+				 * target, since we asked first.
+				 * If the width went higher than our
+				 * request, reject it.
+				 */
+				if (saved_width > bus_width) {
+					reject = TRUE;
+					printf("(%s:%c:%d:%d): requested %dBit "
+					       "transfers.  Rejecting...\n",
+					       ahc_name(ahc), devinfo->channel,
+					       devinfo->target, devinfo->lun,
+					       8 * (0x01 << bus_width));
+					bus_width = 0;
+				}
+			} else {
+				/*
+				 * Send our own WDTR in reply
+				 */
+				if (bootverbose
+				 && devinfo->role == ROLE_INITIATOR) {
+					printf("(%s:%c:%d:%d): Target "
+					       "Initiated WDTR\n",
+					       ahc_name(ahc), devinfo->channel,
+					       devinfo->target, devinfo->lun);
+				}
+				ahc->msgout_index = 0;
+				ahc->msgout_len = 0;
+				ahc_construct_wdtr(ahc, devinfo, bus_width);
+				ahc->msgout_index = 0;
+				response = TRUE;
+				sending_reply = TRUE;
+			}
+			ahc_set_width(ahc, devinfo, bus_width,
+				      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
+				      /*paused*/TRUE);
+			/* After a wide message, we are async */
+			ahc_set_syncrate(ahc, devinfo,
+					 /*syncrate*/NULL, /*period*/0,
+					 /*offset*/0, /*ppr_options*/0,
+					 AHC_TRANS_ACTIVE, /*paused*/TRUE);
+			if (sending_reply == FALSE && reject == FALSE) {
+
+				if (tinfo->goal.period) {
+					ahc->msgout_index = 0;
+					ahc->msgout_len = 0;
+					ahc_build_transfer_msg(ahc, devinfo);
+					ahc->msgout_index = 0;
+					response = TRUE;
+				}
+			}
+			done = MSGLOOP_MSGCOMPLETE;
+			break;
+		}
+		case MSG_EXT_PPR:
+		{
+			struct	ahc_syncrate *syncrate;
+			u_int	period;
+			u_int	offset;
+			u_int	bus_width;
+			u_int	ppr_options;
+			u_int	saved_width;
+			u_int	saved_offset;
+			u_int	saved_ppr_options;
+
+			if (ahc->msgin_buf[1] != MSG_EXT_PPR_LEN) {
+				reject = TRUE;
+				break;
+			}
+
+			/*
+			 * Wait until we have all args before validating
+			 * and acting on this message.
+			 *
+			 * Add one to MSG_EXT_PPR_LEN to account for
+			 * the extended message preamble.
+			 */
+			if (ahc->msgin_index < (MSG_EXT_PPR_LEN + 1))
+				break;
+
+			period = ahc->msgin_buf[3];
+			offset = ahc->msgin_buf[5];
+			bus_width = ahc->msgin_buf[6];
+			saved_width = bus_width;
+			ppr_options = ahc->msgin_buf[7];
+			/*
+			 * According to the spec, a DT only
+			 * period factor with no DT option
+			 * set implies async.
+			 */
+			if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
+			 && period == 9)
+				offset = 0;
+			saved_ppr_options = ppr_options;
+			saved_offset = offset;
+
+			/*
+			 * Mask out any options we don't support
+			 * on any controller.  Transfer options are
+			 * only available if we are negotiating wide.
+			 */
+			ppr_options &= MSG_EXT_PPR_DT_REQ;
+			if (bus_width == 0)
+				ppr_options = 0;
+
+			ahc_validate_width(ahc, tinfo, &bus_width,
+					   devinfo->role);
+			syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
+							   &ppr_options,
+							   devinfo->role);
+			ahc_validate_offset(ahc, tinfo, syncrate,
+					    &offset, bus_width,
+					    devinfo->role);
+
+			if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, TRUE)) {
+				/*
+				 * If we are unable to do any of the
+				 * requested options (we went too low),
+				 * then we'll have to reject the message.
+				 */
+				if (saved_width > bus_width
+				 || saved_offset != offset
+				 || saved_ppr_options != ppr_options) {
+					reject = TRUE;
+					period = 0;
+					offset = 0;
+					bus_width = 0;
+					ppr_options = 0;
+					syncrate = NULL;
+				}
+			} else {
+				if (devinfo->role != ROLE_TARGET)
+					printf("(%s:%c:%d:%d): Target "
+					       "Initiated PPR\n",
+					       ahc_name(ahc), devinfo->channel,
+					       devinfo->target, devinfo->lun);
+				else
+					printf("(%s:%c:%d:%d): Initiator "
+					       "Initiated PPR\n",
+					       ahc_name(ahc), devinfo->channel,
+					       devinfo->target, devinfo->lun);
+				ahc->msgout_index = 0;
+				ahc->msgout_len = 0;
+				ahc_construct_ppr(ahc, devinfo, period, offset,
+						  bus_width, ppr_options);
+				ahc->msgout_index = 0;
+				response = TRUE;
+			}
+			if (bootverbose) {
+				printf("(%s:%c:%d:%d): Received PPR width %x, "
+				       "period %x, offset %x,options %x\n"
+				       "\tFiltered to width %x, period %x, "
+				       "offset %x, options %x\n",
+				       ahc_name(ahc), devinfo->channel,
+				       devinfo->target, devinfo->lun,
+				       saved_width, ahc->msgin_buf[3],
+				       saved_offset, saved_ppr_options,
+				       bus_width, period, offset, ppr_options);
+			}
+			ahc_set_width(ahc, devinfo, bus_width,
+				      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
+				      /*paused*/TRUE);
+			ahc_set_syncrate(ahc, devinfo,
+					 syncrate, period,
+					 offset, ppr_options,
+					 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
+					 /*paused*/TRUE);
+			done = MSGLOOP_MSGCOMPLETE;
+			break;
+		}
+		default:
+			/* Unknown extended message.  Reject it. */
+			reject = TRUE;
+			break;
+		}
+		break;
+	}
+#ifdef AHC_TARGET_MODE
+	case MSG_BUS_DEV_RESET:
+		ahc_handle_devreset(ahc, devinfo,
+				    CAM_BDR_SENT,
+				    "Bus Device Reset Received",
+				    /*verbose_level*/0);
+		ahc_restart(ahc);
+		done = MSGLOOP_TERMINATED;
+		break;
+	case MSG_ABORT_TAG:
+	case MSG_ABORT:
+	case MSG_CLEAR_QUEUE:
+	{
+		int tag;
+
+		/* Target mode messages */
+		if (devinfo->role != ROLE_TARGET) {
+			reject = TRUE;
+			break;
+		}
+		tag = SCB_LIST_NULL;
+		if (ahc->msgin_buf[0] == MSG_ABORT_TAG)
+			tag = ahc_inb(ahc, INITIATOR_TAG);
+		ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
+			       devinfo->lun, tag, ROLE_TARGET,
+			       CAM_REQ_ABORTED);
+
+		tstate = ahc->enabled_targets[devinfo->our_scsiid];
+		if (tstate != NULL) {
+			struct ahc_tmode_lstate* lstate;
+
+			lstate = tstate->enabled_luns[devinfo->lun];
+			if (lstate != NULL) {
+				ahc_queue_lstate_event(ahc, lstate,
+						       devinfo->our_scsiid,
+						       ahc->msgin_buf[0],
+						       /*arg*/tag);
+				ahc_send_lstate_events(ahc, lstate);
+			}
+		}
+		ahc_restart(ahc);
+		done = MSGLOOP_TERMINATED;
+		break;
+	}
+#endif
+	case MSG_TERM_IO_PROC:
+	default:
+		reject = TRUE;
+		break;
+	}
+
+	if (reject) {
+		/*
+		 * Setup to reject the message.
+		 */
+		ahc->msgout_index = 0;
+		ahc->msgout_len = 1;
+		ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
+		done = MSGLOOP_MSGCOMPLETE;
+		response = TRUE;
+	}
+
+	if (done != MSGLOOP_IN_PROG && !response)
+		/* Clear the outgoing message buffer */
+		ahc->msgout_len = 0;
+
+	return (done);
+}
+
+/*
+ * Process a message reject message.
+ */
+static int
+ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
+{
+	/*
+	 * What we care about here is if we had an
+	 * outstanding SDTR or WDTR message for this
+	 * target.  If we did, this is a signal that
+	 * the target is refusing negotiation.
+	 */
+	struct scb *scb;
+	struct ahc_initiator_tinfo *tinfo;
+	struct ahc_tmode_tstate *tstate;
+	u_int scb_index;
+	u_int last_msg;
+	int   response = 0;
+
+	scb_index = ahc_inb(ahc, SCB_TAG);
+	scb = ahc_lookup_scb(ahc, scb_index);
+	tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
+				    devinfo->our_scsiid,
+				    devinfo->target, &tstate);
+	/* Might be necessary */
+	last_msg = ahc_inb(ahc, LAST_MSG);
+
+	if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
+		/*
+		 * Target does not support the PPR message.
+		 * Attempt to negotiate SPI-2 style.
+		 */
+		if (bootverbose) {
+			printf("(%s:%c:%d:%d): PPR Rejected. "
+			       "Trying WDTR/SDTR\n",
+			       ahc_name(ahc), devinfo->channel,
+			       devinfo->target, devinfo->lun);
+		}
+		tinfo->goal.ppr_options = 0;
+		tinfo->curr.transport_version = 2;
+		tinfo->goal.transport_version = 2;
+		ahc->msgout_index = 0;
+		ahc->msgout_len = 0;
+		ahc_build_transfer_msg(ahc, devinfo);
+		ahc->msgout_index = 0;
+		response = 1;
+	} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
+
+		/* note 8bit xfers */
+		printf("(%s:%c:%d:%d): refuses WIDE negotiation.  Using "
+		       "8bit transfers\n", ahc_name(ahc),
+		       devinfo->channel, devinfo->target, devinfo->lun);
+		ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
+			      AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
+			      /*paused*/TRUE);
+		/*
+		 * No need to clear the sync rate.  If the target
+		 * did not accept the command, our syncrate is
+		 * unaffected.  If the target started the negotiation,
+		 * but rejected our response, we already cleared the
+		 * sync rate before sending our WDTR.
+		 */
+		if (tinfo->goal.period) {
+
+			/* Start the sync negotiation */
+			ahc->msgout_index = 0;
+			ahc->msgout_len = 0;
+			ahc_build_transfer_msg(ahc, devinfo);
+			ahc->msgout_index = 0;
+			response = 1;
+		}
+	} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
+		/* note asynch xfers and clear flag */
+		ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
+				 /*offset*/0, /*ppr_options*/0,
+				 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
+				 /*paused*/TRUE);
+		printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
+		       "Using asynchronous transfers\n",
+		       ahc_name(ahc), devinfo->channel,
+		       devinfo->target, devinfo->lun);
+	} else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
+		int tag_type;
+		int mask;
+
+		tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
+
+		if (tag_type == MSG_SIMPLE_TASK) {
+			printf("(%s:%c:%d:%d): refuses tagged commands.  "
+			       "Performing non-tagged I/O\n", ahc_name(ahc),
+			       devinfo->channel, devinfo->target, devinfo->lun);
+			ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE);
+			mask = ~0x23;
+		} else {
+			printf("(%s:%c:%d:%d): refuses %s tagged commands.  "
+			       "Performing simple queue tagged I/O only\n",
+			       ahc_name(ahc), devinfo->channel, devinfo->target,
+			       devinfo->lun, tag_type == MSG_ORDERED_TASK
+			       ? "ordered" : "head of queue");
+			ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC);
+			mask = ~0x03;
+		}
+
+		/*
+		 * Resend the identify for this CCB as the target
+		 * may believe that the selection is invalid otherwise.
+		 */
+		ahc_outb(ahc, SCB_CONTROL,
+			 ahc_inb(ahc, SCB_CONTROL) & mask);
+	 	scb->hscb->control &= mask;
+		ahc_set_transaction_tag(scb, /*enabled*/FALSE,
+					/*type*/MSG_SIMPLE_TASK);
+		ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
+		ahc_assert_atn(ahc);
+
+		/*
+		 * This transaction is now at the head of
+		 * the untagged queue for this target.
+		 */
+		if ((ahc->flags & AHC_SCB_BTT) == 0) {
+			struct scb_tailq *untagged_q;
+
+			untagged_q =
+			    &(ahc->untagged_queues[devinfo->target_offset]);
+			TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
+			scb->flags |= SCB_UNTAGGEDQ;
+		}
+		ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
+			     scb->hscb->tag);
+
+		/*
+		 * Requeue all tagged commands for this target
+		 * currently in our posession so they can be
+		 * converted to untagged commands.
+		 */
+		ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
+				   SCB_GET_CHANNEL(ahc, scb),
+				   SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL,
+				   ROLE_INITIATOR, CAM_REQUEUE_REQ,
+				   SEARCH_COMPLETE);
+	} else {
+		/*
+		 * Otherwise, we ignore it.
+		 */
+		printf("%s:%c:%d: Message reject for %x -- ignored\n",
+		       ahc_name(ahc), devinfo->channel, devinfo->target,
+		       last_msg);
+	}
+	return (response);
+}
+
+/*
+ * Process an ingnore wide residue message.
+ */
+static void
+ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
+{
+	u_int scb_index;
+	struct scb *scb;
+
+	scb_index = ahc_inb(ahc, SCB_TAG);
+	scb = ahc_lookup_scb(ahc, scb_index);
+	/*
+	 * XXX Actually check data direction in the sequencer?
+	 * Perhaps add datadir to some spare bits in the hscb?
+	 */
+	if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
+	 || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {
+		/*
+		 * Ignore the message if we haven't
+		 * seen an appropriate data phase yet.
+		 */
+	} else {
+		/*
+		 * If the residual occurred on the last
+		 * transfer and the transfer request was
+		 * expected to end on an odd count, do
+		 * nothing.  Otherwise, subtract a byte
+		 * and update the residual count accordingly.
+		 */
+		uint32_t sgptr;
+
+		sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
+		if ((sgptr & SG_LIST_NULL) != 0
+		 && ahc_inb(ahc, DATA_COUNT_ODD) == 1) {
+			/*
+			 * If the residual occurred on the last
+			 * transfer and the transfer request was
+			 * expected to end on an odd count, do
+			 * nothing.
+			 */
+		} else {
+			struct ahc_dma_seg *sg;
+			uint32_t data_cnt;
+			uint32_t data_addr;
+			uint32_t sglen;
+
+			/* Pull in the rest of the sgptr */
+			sgptr |= (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
+			      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
+			      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8);
+			sgptr &= SG_PTR_MASK;
+			data_cnt = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+3) << 24)
+				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+2) << 16)
+				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+1) << 8)
+				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT));
+
+			data_addr = (ahc_inb(ahc, SHADDR + 3) << 24)
+				  | (ahc_inb(ahc, SHADDR + 2) << 16)
+				  | (ahc_inb(ahc, SHADDR + 1) << 8)
+				  | (ahc_inb(ahc, SHADDR));
+
+			data_cnt += 1;
+			data_addr -= 1;
+
+			sg = ahc_sg_bus_to_virt(scb, sgptr);
+			/*
+			 * The residual sg ptr points to the next S/G
+			 * to load so we must go back one.
+			 */
+			sg--;
+			sglen = ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
+			if (sg != scb->sg_list
+			 && sglen < (data_cnt & AHC_SG_LEN_MASK)) {
+
+				sg--;
+				sglen = ahc_le32toh(sg->len);
+				/*
+				 * Preserve High Address and SG_LIST bits
+				 * while setting the count to 1.
+				 */
+				data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));
+				data_addr = ahc_le32toh(sg->addr)
+					  + (sglen & AHC_SG_LEN_MASK) - 1;
+
+				/*
+				 * Increment sg so it points to the
+				 * "next" sg.
+				 */
+				sg++;
+				sgptr = ahc_sg_virt_to_bus(scb, sg);
+				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 3,
+					 sgptr >> 24);
+				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 2,
+					 sgptr >> 16);
+				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 1,
+					 sgptr >> 8);
+				ahc_outb(ahc, SCB_RESIDUAL_SGPTR, sgptr);
+			}
+
+			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24);
+			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16);
+			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8);
+			ahc_outb(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
+		}
+	}
+}
+
+
+/*
+ * Reinitialize the data pointers for the active transfer
+ * based on its current residual.
+ */
+static void
+ahc_reinitialize_dataptrs(struct ahc_softc *ahc)
+{
+	struct	 scb *scb;
+	struct	 ahc_dma_seg *sg;
+	u_int	 scb_index;
+	uint32_t sgptr;
+	uint32_t resid;
+	uint32_t dataptr;
+
+	scb_index = ahc_inb(ahc, SCB_TAG);
+	scb = ahc_lookup_scb(ahc, scb_index);
+	sgptr = (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
+	      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
+	      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8)
+	      |	ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
+
+	sgptr &= SG_PTR_MASK;
+	sg = ahc_sg_bus_to_virt(scb, sgptr);
+
+	/* The residual sg_ptr always points to the next sg */
+	sg--;
+
+	resid = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 2) << 16)
+	      | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)
+	      | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);
+
+	dataptr = ahc_le32toh(sg->addr)
+		+ (ahc_le32toh(sg->len) & AHC_SG_LEN_MASK)
+		- resid;
+	if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
+		u_int dscommand1;
+
+		dscommand1 = ahc_inb(ahc, DSCOMMAND1);
+		ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
+		ahc_outb(ahc, HADDR,
+			 (ahc_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
+		ahc_outb(ahc, DSCOMMAND1, dscommand1);
+	}
+	ahc_outb(ahc, HADDR + 3, dataptr >> 24);
+	ahc_outb(ahc, HADDR + 2, dataptr >> 16);
+	ahc_outb(ahc, HADDR + 1, dataptr >> 8);
+	ahc_outb(ahc, HADDR, dataptr);
+	ahc_outb(ahc, HCNT + 2, resid >> 16);
+	ahc_outb(ahc, HCNT + 1, resid >> 8);
+	ahc_outb(ahc, HCNT, resid);
+	if ((ahc->features & AHC_ULTRA2) == 0) {
+		ahc_outb(ahc, STCNT + 2, resid >> 16);
+		ahc_outb(ahc, STCNT + 1, resid >> 8);
+		ahc_outb(ahc, STCNT, resid);
+	}
+}
+
+/*
+ * Handle the effects of issuing a bus device reset message.
+ */
+static void
+ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		    cam_status status, char *message, int verbose_level)
+{
+#ifdef AHC_TARGET_MODE
+	struct ahc_tmode_tstate* tstate;
+	u_int lun;
+#endif
+	int found;
+
+	found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
+			       CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
+			       status);
+
+#ifdef AHC_TARGET_MODE
+	/*
+	 * Send an immediate notify ccb to all target mord peripheral
+	 * drivers affected by this action.
+	 */
+	tstate = ahc->enabled_targets[devinfo->our_scsiid];
+	if (tstate != NULL) {
+		for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
+			struct ahc_tmode_lstate* lstate;
+
+			lstate = tstate->enabled_luns[lun];
+			if (lstate == NULL)
+				continue;
+
+			ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
+					       MSG_BUS_DEV_RESET, /*arg*/0);
+			ahc_send_lstate_events(ahc, lstate);
+		}
+	}
+#endif
+
+	/*
+	 * Go back to async/narrow transfers and renegotiate.
+	 */
+	ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
+		      AHC_TRANS_CUR, /*paused*/TRUE);
+	ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL,
+			 /*period*/0, /*offset*/0, /*ppr_options*/0,
+			 AHC_TRANS_CUR, /*paused*/TRUE);
+	
+	ahc_send_async(ahc, devinfo->channel, devinfo->target,
+		       CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
+
+	if (message != NULL
+	 && (verbose_level <= bootverbose))
+		printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
+		       message, devinfo->channel, devinfo->target, found);
+}
+
+#ifdef AHC_TARGET_MODE
+static void
+ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		       struct scb *scb)
+{
+
+	/*              
+	 * To facilitate adding multiple messages together,
+	 * each routine should increment the index and len
+	 * variables instead of setting them explicitly.
+	 */             
+	ahc->msgout_index = 0;
+	ahc->msgout_len = 0;
+
+	if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
+		ahc_build_transfer_msg(ahc, devinfo);
+	else
+		panic("ahc_intr: AWAITING target message with no message");
+
+	ahc->msgout_index = 0;
+	ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
+}
+#endif
+/**************************** Initialization **********************************/
+/*
+ * Allocate a controller structure for a new device
+ * and perform initial initializion.
+ */
+struct ahc_softc *
+ahc_alloc(void *platform_arg, char *name)
+{
+	struct  ahc_softc *ahc;
+	int	i;
+
+#ifndef	__FreeBSD__
+	ahc = malloc(sizeof(*ahc), M_DEVBUF, M_NOWAIT);
+	if (!ahc) {
+		printf("aic7xxx: cannot malloc softc!\n");
+		free(name, M_DEVBUF);
+		return NULL;
+	}
+#else
+	ahc = device_get_softc((device_t)platform_arg);
+#endif
+	memset(ahc, 0, sizeof(*ahc));
+	ahc->seep_config = malloc(sizeof(*ahc->seep_config),
+				  M_DEVBUF, M_NOWAIT);
+	if (ahc->seep_config == NULL) {
+#ifndef	__FreeBSD__
+		free(ahc, M_DEVBUF);
+#endif
+		free(name, M_DEVBUF);
+		return (NULL);
+	}
+	LIST_INIT(&ahc->pending_scbs);
+	/* We don't know our unit number until the OSM sets it */
+	ahc->name = name;
+	ahc->unit = -1;
+	ahc->description = NULL;
+	ahc->channel = 'A';
+	ahc->channel_b = 'B';
+	ahc->chip = AHC_NONE;
+	ahc->features = AHC_FENONE;
+	ahc->bugs = AHC_BUGNONE;
+	ahc->flags = AHC_FNONE;
+
+	for (i = 0; i < AHC_NUM_TARGETS; i++)
+		TAILQ_INIT(&ahc->untagged_queues[i]);
+	if (ahc_platform_alloc(ahc, platform_arg) != 0) {
+		ahc_free(ahc);
+		ahc = NULL;
+	}
+	return (ahc);
+}
+
+int
+ahc_softc_init(struct ahc_softc *ahc)
+{
+
+	/* The IRQMS bit is only valid on VL and EISA chips */
+	if ((ahc->chip & AHC_PCI) == 0)
+		ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
+	else
+		ahc->unpause = 0;
+	ahc->pause = ahc->unpause | PAUSE; 
+	/* XXX The shared scb data stuff should be deprecated */
+	if (ahc->scb_data == NULL) {
+		ahc->scb_data = malloc(sizeof(*ahc->scb_data),
+				       M_DEVBUF, M_NOWAIT);
+		if (ahc->scb_data == NULL)
+			return (ENOMEM);
+		memset(ahc->scb_data, 0, sizeof(*ahc->scb_data));
+	}
+
+	return (0);
+}
+
+void
+ahc_softc_insert(struct ahc_softc *ahc)
+{
+	struct ahc_softc *list_ahc;
+
+#if AHC_PCI_CONFIG > 0
+	/*
+	 * Second Function PCI devices need to inherit some
+	 * settings from function 0.
+	 */
+	if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
+	 && (ahc->features & AHC_MULTI_FUNC) != 0) {
+		TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
+			ahc_dev_softc_t list_pci;
+			ahc_dev_softc_t pci;
+
+			list_pci = list_ahc->dev_softc;
+			pci = ahc->dev_softc;
+			if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
+			 && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
+				struct ahc_softc *master;
+				struct ahc_softc *slave;
+
+				if (ahc_get_pci_function(list_pci) == 0) {
+					master = list_ahc;
+					slave = ahc;
+				} else {
+					master = ahc;
+					slave = list_ahc;
+				}
+				slave->flags &= ~AHC_BIOS_ENABLED; 
+				slave->flags |=
+				    master->flags & AHC_BIOS_ENABLED;
+				slave->flags &= ~AHC_PRIMARY_CHANNEL; 
+				slave->flags |=
+				    master->flags & AHC_PRIMARY_CHANNEL;
+				break;
+			}
+		}
+	}
+#endif
+
+	/*
+	 * Insertion sort into our list of softcs.
+	 */
+	list_ahc = TAILQ_FIRST(&ahc_tailq);
+	while (list_ahc != NULL
+	    && ahc_softc_comp(list_ahc, ahc) <= 0)
+		list_ahc = TAILQ_NEXT(list_ahc, links);
+	if (list_ahc != NULL)
+		TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
+	else
+		TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
+	ahc->init_level++;
+}
+
+/*
+ * Verify that the passed in softc pointer is for a
+ * controller that is still configured.
+ */
+struct ahc_softc *
+ahc_find_softc(struct ahc_softc *ahc)
+{
+	struct ahc_softc *list_ahc;
+
+	TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
+		if (list_ahc == ahc)
+			return (ahc);
+	}
+	return (NULL);
+}
+
+void
+ahc_set_unit(struct ahc_softc *ahc, int unit)
+{
+	ahc->unit = unit;
+}
+
+void
+ahc_set_name(struct ahc_softc *ahc, char *name)
+{
+	if (ahc->name != NULL)
+		free(ahc->name, M_DEVBUF);
+	ahc->name = name;
+}
+
+void
+ahc_free(struct ahc_softc *ahc)
+{
+	int i;
+
+	ahc_fini_scbdata(ahc);
+	switch (ahc->init_level) {
+	default:
+	case 5:
+		ahc_shutdown(ahc);
+		TAILQ_REMOVE(&ahc_tailq, ahc, links);
+		/* FALLTHROUGH */
+	case 4:
+		ahc_dmamap_unload(ahc, ahc->shared_data_dmat,
+				  ahc->shared_data_dmamap);
+		/* FALLTHROUGH */
+	case 3:
+		ahc_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,
+				ahc->shared_data_dmamap);
+		ahc_dmamap_destroy(ahc, ahc->shared_data_dmat,
+				   ahc->shared_data_dmamap);
+		/* FALLTHROUGH */
+	case 2:
+		ahc_dma_tag_destroy(ahc, ahc->shared_data_dmat);
+	case 1:
+#ifndef __linux__
+		ahc_dma_tag_destroy(ahc, ahc->buffer_dmat);
+#endif
+		break;
+	case 0:
+		break;
+	}
+
+#ifndef __linux__
+	ahc_dma_tag_destroy(ahc, ahc->parent_dmat);
+#endif
+	ahc_platform_free(ahc);
+	for (i = 0; i < AHC_NUM_TARGETS; i++) {
+		struct ahc_tmode_tstate *tstate;
+
+		tstate = ahc->enabled_targets[i];
+		if (tstate != NULL) {
+#if AHC_TARGET_MODE
+			int j;
+
+			for (j = 0; j < AHC_NUM_LUNS; j++) {
+				struct ahc_tmode_lstate *lstate;
+
+				lstate = tstate->enabled_luns[j];
+				if (lstate != NULL) {
+					xpt_free_path(lstate->path);
+					free(lstate, M_DEVBUF);
+				}
+			}
+#endif
+			free(tstate, M_DEVBUF);
+		}
+	}
+#if AHC_TARGET_MODE
+	if (ahc->black_hole != NULL) {
+		xpt_free_path(ahc->black_hole->path);
+		free(ahc->black_hole, M_DEVBUF);
+	}
+#endif
+	if (ahc->name != NULL)
+		free(ahc->name, M_DEVBUF);
+	if (ahc->seep_config != NULL)
+		free(ahc->seep_config, M_DEVBUF);
+#ifndef __FreeBSD__
+	free(ahc, M_DEVBUF);
+#endif
+	return;
+}
+
+void
+ahc_shutdown(void *arg)
+{
+	struct	ahc_softc *ahc;
+	int	i;
+
+	ahc = (struct ahc_softc *)arg;
+
+	/* This will reset most registers to 0, but not all */
+	ahc_reset(ahc);
+	ahc_outb(ahc, SCSISEQ, 0);
+	ahc_outb(ahc, SXFRCTL0, 0);
+	ahc_outb(ahc, DSPCISTATUS, 0);
+
+	for (i = TARG_SCSIRATE; i < SCSICONF; i++)
+		ahc_outb(ahc, i, 0);
+}
+
+/*
+ * Reset the controller and record some information about it
+ * that is only available just after a reset.
+ */
+int
+ahc_reset(struct ahc_softc *ahc)
+{
+	u_int	sblkctl;
+	u_int	sxfrctl1_a, sxfrctl1_b;
+	int	wait;
+	
+	/*
+	 * Preserve the value of the SXFRCTL1 register for all channels.
+	 * It contains settings that affect termination and we don't want
+	 * to disturb the integrity of the bus.
+	 */
+	ahc_pause(ahc);
+	sxfrctl1_b = 0;
+	if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
+		u_int sblkctl;
+
+		/*
+		 * Save channel B's settings in case this chip
+		 * is setup for TWIN channel operation.
+		 */
+		sblkctl = ahc_inb(ahc, SBLKCTL);
+		ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
+		sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
+		ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
+	}
+	sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
+
+	ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
+
+	/*
+	 * Ensure that the reset has finished.  We delay 1000us
+	 * prior to reading the register to make sure the chip
+	 * has sufficiently completed its reset to handle register
+	 * accesses.
+	 */
+	wait = 1000;
+	do {
+		ahc_delay(1000);
+	} while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
+
+	if (wait == 0) {
+		printf("%s: WARNING - Failed chip reset!  "
+		       "Trying to initialize anyway.\n", ahc_name(ahc));
+	}
+	ahc_outb(ahc, HCNTRL, ahc->pause);
+
+	/* Determine channel configuration */
+	sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
+	/* No Twin Channel PCI cards */
+	if ((ahc->chip & AHC_PCI) != 0)
+		sblkctl &= ~SELBUSB;
+	switch (sblkctl) {
+	case 0:
+		/* Single Narrow Channel */
+		break;
+	case 2:
+		/* Wide Channel */
+		ahc->features |= AHC_WIDE;
+		break;
+	case 8:
+		/* Twin Channel */
+		ahc->features |= AHC_TWIN;
+		break;
+	default:
+		printf(" Unsupported adapter type.  Ignoring\n");
+		return(-1);
+	}
+
+	/*
+	 * Reload sxfrctl1.
+	 *
+	 * We must always initialize STPWEN to 1 before we
+	 * restore the saved values.  STPWEN is initialized
+	 * to a tri-state condition which can only be cleared
+	 * by turning it on.
+	 */
+	if ((ahc->features & AHC_TWIN) != 0) {
+		u_int sblkctl;
+
+		sblkctl = ahc_inb(ahc, SBLKCTL);
+		ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
+		ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
+		ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
+	}
+	ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
+
+#ifdef AHC_DUMP_SEQ
+	if (ahc->init_level == 0)
+		ahc_dumpseq(ahc);
+#endif
+
+	return (0);
+}
+
+/*
+ * Determine the number of SCBs available on the controller
+ */
+int
+ahc_probe_scbs(struct ahc_softc *ahc) {
+	int i;
+
+	for (i = 0; i < AHC_SCB_MAX; i++) {
+
+		ahc_outb(ahc, SCBPTR, i);
+		ahc_outb(ahc, SCB_BASE, i);
+		if (ahc_inb(ahc, SCB_BASE) != i)
+			break;
+		ahc_outb(ahc, SCBPTR, 0);
+		if (ahc_inb(ahc, SCB_BASE) != 0)
+			break;
+	}
+	return (i);
+}
+
+static void
+ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) 
+{
+	bus_addr_t *baddr;
+
+	baddr = (bus_addr_t *)arg;
+	*baddr = segs->ds_addr;
+}
+
+static void
+ahc_build_free_scb_list(struct ahc_softc *ahc)
+{
+	int scbsize;
+	int i;
+
+	scbsize = 32;
+	if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)
+		scbsize = 64;
+
+	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
+		int j;
+
+		ahc_outb(ahc, SCBPTR, i);
+
+		/*
+		 * Touch all SCB bytes to avoid parity errors
+		 * should one of our debugging routines read
+		 * an otherwise uninitiatlized byte.
+		 */
+		for (j = 0; j < scbsize; j++)
+			ahc_outb(ahc, SCB_BASE+j, 0xFF);
+
+		/* Clear the control byte. */
+		ahc_outb(ahc, SCB_CONTROL, 0);
+
+		/* Set the next pointer */
+		if ((ahc->flags & AHC_PAGESCBS) != 0)
+			ahc_outb(ahc, SCB_NEXT, i+1);
+		else 
+			ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
+
+		/* Make the tag number, SCSIID, and lun invalid */
+		ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
+		ahc_outb(ahc, SCB_SCSIID, 0xFF);
+		ahc_outb(ahc, SCB_LUN, 0xFF);
+	}
+
+	/* Make sure that the last SCB terminates the free list */
+	ahc_outb(ahc, SCBPTR, i-1);
+	ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
+}
+
+static int
+ahc_init_scbdata(struct ahc_softc *ahc)
+{
+	struct scb_data *scb_data;
+
+	scb_data = ahc->scb_data;
+	SLIST_INIT(&scb_data->free_scbs);
+	SLIST_INIT(&scb_data->sg_maps);
+
+	/* Allocate SCB resources */
+	scb_data->scbarray =
+	    (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC,
+				 M_DEVBUF, M_NOWAIT);
+	if (scb_data->scbarray == NULL)
+		return (ENOMEM);
+	memset(scb_data->scbarray, 0, sizeof(struct scb) * AHC_SCB_MAX_ALLOC);
+
+	/* Determine the number of hardware SCBs and initialize them */
+
+	scb_data->maxhscbs = ahc_probe_scbs(ahc);
+	if ((ahc->flags & AHC_PAGESCBS) != 0) {
+		/* SCB 0 heads the free list */
+		ahc_outb(ahc, FREE_SCBH, 0);
+	} else {
+		ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
+	}
+
+	if (ahc->scb_data->maxhscbs == 0) {
+		printf("%s: No SCB space found\n", ahc_name(ahc));
+		return (ENXIO);
+	}
+
+	ahc_build_free_scb_list(ahc);
+
+	/*
+	 * Create our DMA tags.  These tags define the kinds of device
+	 * accessible memory allocations and memory mappings we will
+	 * need to perform during normal operation.
+	 *
+	 * Unless we need to further restrict the allocation, we rely
+	 * on the restrictions of the parent dmat, hence the common
+	 * use of MAXADDR and MAXSIZE.
+	 */
+
+	/* DMA tag for our hardware scb structures */
+	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+			       /*highaddr*/BUS_SPACE_MAXADDR,
+			       /*filter*/NULL, /*filterarg*/NULL,
+			       AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
+			       /*nsegments*/1,
+			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
+			       /*flags*/0, &scb_data->hscb_dmat) != 0) {
+		goto error_exit;
+	}
+
+	scb_data->init_level++;
+
+	/* Allocation for our hscbs */
+	if (ahc_dmamem_alloc(ahc, scb_data->hscb_dmat,
+			     (void **)&scb_data->hscbs,
+			     BUS_DMA_NOWAIT, &scb_data->hscb_dmamap) != 0) {
+		goto error_exit;
+	}
+
+	scb_data->init_level++;
+
+	/* And permanently map them */
+	ahc_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,
+			scb_data->hscbs,
+			AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
+			ahc_dmamap_cb, &scb_data->hscb_busaddr, /*flags*/0);
+
+	scb_data->init_level++;
+
+	/* DMA tag for our sense buffers */
+	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+			       /*highaddr*/BUS_SPACE_MAXADDR,
+			       /*filter*/NULL, /*filterarg*/NULL,
+			       AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
+			       /*nsegments*/1,
+			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
+			       /*flags*/0, &scb_data->sense_dmat) != 0) {
+		goto error_exit;
+	}
+
+	scb_data->init_level++;
+
+	/* Allocate them */
+	if (ahc_dmamem_alloc(ahc, scb_data->sense_dmat,
+			     (void **)&scb_data->sense,
+			     BUS_DMA_NOWAIT, &scb_data->sense_dmamap) != 0) {
+		goto error_exit;
+	}
+
+	scb_data->init_level++;
+
+	/* And permanently map them */
+	ahc_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,
+			scb_data->sense,
+			AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
+			ahc_dmamap_cb, &scb_data->sense_busaddr, /*flags*/0);
+
+	scb_data->init_level++;
+
+	/* DMA tag for our S/G structures.  We allocate in page sized chunks */
+	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+			       /*highaddr*/BUS_SPACE_MAXADDR,
+			       /*filter*/NULL, /*filterarg*/NULL,
+			       PAGE_SIZE, /*nsegments*/1,
+			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
+			       /*flags*/0, &scb_data->sg_dmat) != 0) {
+		goto error_exit;
+	}
+
+	scb_data->init_level++;
+
+	/* Perform initial CCB allocation */
+	memset(scb_data->hscbs, 0,
+	       AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));
+	ahc_alloc_scbs(ahc);
+
+	if (scb_data->numscbs == 0) {
+		printf("%s: ahc_init_scbdata - "
+		       "Unable to allocate initial scbs\n",
+		       ahc_name(ahc));
+		goto error_exit;
+	}
+
+	/*
+	 * Tell the sequencer which SCB will be the next one it receives.
+	 */
+	ahc->next_queued_scb = ahc_get_scb(ahc);
+	ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
+
+	/*
+	 * Note that we were successfull
+	 */
+	return (0); 
+
+error_exit:
+
+	return (ENOMEM);
+}
+
+static void
+ahc_fini_scbdata(struct ahc_softc *ahc)
+{
+	struct scb_data *scb_data;
+
+	scb_data = ahc->scb_data;
+	if (scb_data == NULL)
+		return;
+
+	switch (scb_data->init_level) {
+	default:
+	case 7:
+	{
+		struct sg_map_node *sg_map;
+
+		while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
+			SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
+			ahc_dmamap_unload(ahc, scb_data->sg_dmat,
+					  sg_map->sg_dmamap);
+			ahc_dmamem_free(ahc, scb_data->sg_dmat,
+					sg_map->sg_vaddr,
+					sg_map->sg_dmamap);
+			free(sg_map, M_DEVBUF);
+		}
+		ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);
+	}
+	case 6:
+		ahc_dmamap_unload(ahc, scb_data->sense_dmat,
+				  scb_data->sense_dmamap);
+	case 5:
+		ahc_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,
+				scb_data->sense_dmamap);
+		ahc_dmamap_destroy(ahc, scb_data->sense_dmat,
+				   scb_data->sense_dmamap);
+	case 4:
+		ahc_dma_tag_destroy(ahc, scb_data->sense_dmat);
+	case 3:
+		ahc_dmamap_unload(ahc, scb_data->hscb_dmat,
+				  scb_data->hscb_dmamap);
+	case 2:
+		ahc_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,
+				scb_data->hscb_dmamap);
+		ahc_dmamap_destroy(ahc, scb_data->hscb_dmat,
+				   scb_data->hscb_dmamap);
+	case 1:
+		ahc_dma_tag_destroy(ahc, scb_data->hscb_dmat);
+		break;
+	case 0:
+		break;
+	}
+	if (scb_data->scbarray != NULL)
+		free(scb_data->scbarray, M_DEVBUF);
+}
+
+void
+ahc_alloc_scbs(struct ahc_softc *ahc)
+{
+	struct scb_data *scb_data;
+	struct scb *next_scb;
+	struct sg_map_node *sg_map;
+	bus_addr_t physaddr;
+	struct ahc_dma_seg *segs;
+	int newcount;
+	int i;
+
+	scb_data = ahc->scb_data;
+	if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)
+		/* Can't allocate any more */
+		return;
+
+	next_scb = &scb_data->scbarray[scb_data->numscbs];
+
+	sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
+
+	if (sg_map == NULL)
+		return;
+
+	/* Allocate S/G space for the next batch of SCBS */
+	if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,
+			     (void **)&sg_map->sg_vaddr,
+			     BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
+		free(sg_map, M_DEVBUF);
+		return;
+	}
+
+	SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
+
+	ahc_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,
+			sg_map->sg_vaddr, PAGE_SIZE, ahc_dmamap_cb,
+			&sg_map->sg_physaddr, /*flags*/0);
+
+	segs = sg_map->sg_vaddr;
+	physaddr = sg_map->sg_physaddr;
+
+	newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
+	newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
+	for (i = 0; i < newcount; i++) {
+		struct scb_platform_data *pdata;
+#ifndef __linux__
+		int error;
+#endif
+		pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
+							   M_DEVBUF, M_NOWAIT);
+		if (pdata == NULL)
+			break;
+		next_scb->platform_data = pdata;
+		next_scb->sg_map = sg_map;
+		next_scb->sg_list = segs;
+		/*
+		 * The sequencer always starts with the second entry.
+		 * The first entry is embedded in the scb.
+		 */
+		next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
+		next_scb->ahc_softc = ahc;
+		next_scb->flags = SCB_FREE;
+#ifndef __linux__
+		error = ahc_dmamap_create(ahc, ahc->buffer_dmat, /*flags*/0,
+					  &next_scb->dmamap);
+		if (error != 0)
+			break;
+#endif
+		next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
+		next_scb->hscb->tag = ahc->scb_data->numscbs;
+		SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
+				  next_scb, links.sle);
+		segs += AHC_NSEG;
+		physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
+		next_scb++;
+		ahc->scb_data->numscbs++;
+	}
+}
+
+void
+ahc_controller_info(struct ahc_softc *ahc, char *buf)
+{
+	int len;
+
+	len = sprintf(buf, "%s: ", ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
+	buf += len;
+	if ((ahc->features & AHC_TWIN) != 0)
+ 		len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
+			      "B SCSI Id=%d, primary %c, ",
+			      ahc->our_id, ahc->our_id_b,
+			      (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
+	else {
+		const char *speed;
+		const char *type;
+
+		speed = "";
+		if ((ahc->features & AHC_ULTRA) != 0) {
+			speed = "Ultra ";
+		} else if ((ahc->features & AHC_DT) != 0) {
+			speed = "Ultra160 ";
+		} else if ((ahc->features & AHC_ULTRA2) != 0) {
+			speed = "Ultra2 ";
+		}
+		if ((ahc->features & AHC_WIDE) != 0) {
+			type = "Wide";
+		} else {
+			type = "Single";
+		}
+		len = sprintf(buf, "%s%s Channel %c, SCSI Id=%d, ",
+			      speed, type, ahc->channel, ahc->our_id);
+	}
+	buf += len;
+
+	if ((ahc->flags & AHC_PAGESCBS) != 0)
+		sprintf(buf, "%d/%d SCBs",
+			ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);
+	else
+		sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);
+}
+
+/*
+ * Start the board, ready for normal operation
+ */
+int
+ahc_init(struct ahc_softc *ahc)
+{
+	int	 max_targ;
+	int	 i;
+	int	 term;
+	u_int	 scsi_conf;
+	u_int	 scsiseq_template;
+	u_int	 ultraenb;
+	u_int	 discenable;
+	u_int	 tagenable;
+	size_t	 driver_data_size;
+	uint32_t physaddr;
+
+#ifdef AHC_DEBUG_SEQUENCER
+	ahc->flags |= AHC_SEQUENCER_DEBUG;
+#endif
+
+#ifdef AHC_PRINT_SRAM
+	printf("Scratch Ram:");
+	for (i = 0x20; i < 0x5f; i++) {
+		if (((i % 8) == 0) && (i != 0)) {
+			printf ("\n              ");
+		}
+		printf (" 0x%x", ahc_inb(ahc, i));
+	}
+	if ((ahc->features & AHC_MORE_SRAM) != 0) {
+		for (i = 0x70; i < 0x7f; i++) {
+			if (((i % 8) == 0) && (i != 0)) {
+				printf ("\n              ");
+			}
+			printf (" 0x%x", ahc_inb(ahc, i));
+		}
+	}
+	printf ("\n");
+	/*
+	 * Reading uninitialized scratch ram may
+	 * generate parity errors.
+	 */
+	ahc_outb(ahc, CLRINT, CLRPARERR);
+	ahc_outb(ahc, CLRINT, CLRBRKADRINT);
+#endif
+	max_targ = 15;
+
+	/*
+	 * Assume we have a board at this stage and it has been reset.
+	 */
+	if ((ahc->flags & AHC_USEDEFAULTS) != 0)
+		ahc->our_id = ahc->our_id_b = 7;
+	
+	/*
+	 * Default to allowing initiator operations.
+	 */
+	ahc->flags |= AHC_INITIATORROLE;
+
+	/*
+	 * Only allow target mode features if this unit has them enabled.
+	 */
+	if ((AHC_TMODE_ENABLE & (0x1 << ahc->unit)) == 0)
+		ahc->features &= ~AHC_TARGETMODE;
+
+#ifndef __linux__
+	/* DMA tag for mapping buffers into device visible space. */
+	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+			       /*lowaddr*/BUS_SPACE_MAXADDR,
+			       /*highaddr*/BUS_SPACE_MAXADDR,
+			       /*filter*/NULL, /*filterarg*/NULL,
+			       /*maxsize*/MAXBSIZE, /*nsegments*/AHC_NSEG,
+			       /*maxsegsz*/AHC_MAXTRANSFER_SIZE,
+			       /*flags*/BUS_DMA_ALLOCNOW,
+			       &ahc->buffer_dmat) != 0) {
+		return (ENOMEM);
+	}
+#endif
+
+	ahc->init_level++;
+
+	/*
+	 * DMA tag for our command fifos and other data in system memory
+	 * the card's sequencer must be able to access.  For initiator
+	 * roles, we need to allocate space for the the qinfifo and qoutfifo.
+	 * The qinfifo and qoutfifo are composed of 256 1 byte elements. 
+	 * When providing for the target mode role, we must additionally
+	 * provide space for the incoming target command fifo and an extra
+	 * byte to deal with a dma bug in some chip versions.
+	 */
+	driver_data_size = 2 * 256 * sizeof(uint8_t);
+	if ((ahc->features & AHC_TARGETMODE) != 0)
+		driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
+				 + /*DMA WideOdd Bug Buffer*/1;
+	if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+			       /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+			       /*highaddr*/BUS_SPACE_MAXADDR,
+			       /*filter*/NULL, /*filterarg*/NULL,
+			       driver_data_size,
+			       /*nsegments*/1,
+			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
+			       /*flags*/0, &ahc->shared_data_dmat) != 0) {
+		return (ENOMEM);
+	}
+
+	ahc->init_level++;
+
+	/* Allocation of driver data */
+	if (ahc_dmamem_alloc(ahc, ahc->shared_data_dmat,
+			     (void **)&ahc->qoutfifo,
+			     BUS_DMA_NOWAIT, &ahc->shared_data_dmamap) != 0) {
+		return (ENOMEM);
+	}
+
+	ahc->init_level++;
+
+	/* And permanently map it in */
+	ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
+			ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
+			&ahc->shared_data_busaddr, /*flags*/0);
+
+	if ((ahc->features & AHC_TARGETMODE) != 0) {
+		ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
+		ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
+		ahc->dma_bug_buf = ahc->shared_data_busaddr
+				 + driver_data_size - 1;
+		/* All target command blocks start out invalid. */
+		for (i = 0; i < AHC_TMODE_CMDS; i++)
+			ahc->targetcmds[i].cmd_valid = 0;
+		ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);
+		ahc->tqinfifonext = 1;
+		ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
+		ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
+		ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
+	}
+	ahc->qinfifo = &ahc->qoutfifo[256];
+
+	ahc->init_level++;
+
+	/* Allocate SCB data now that buffer_dmat is initialized */
+	if (ahc->scb_data->maxhscbs == 0)
+		if (ahc_init_scbdata(ahc) != 0)
+			return (ENOMEM);
+
+	/*
+	 * Allocate a tstate to house information for our
+	 * initiator presence on the bus as well as the user
+	 * data for any target mode initiator.
+	 */
+	if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
+		printf("%s: unable to allocate ahc_tmode_tstate.  "
+		       "Failing attach\n", ahc_name(ahc));
+		return (ENOMEM);
+	}
+
+	if ((ahc->features & AHC_TWIN) != 0) {
+		if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
+			printf("%s: unable to allocate ahc_tmode_tstate.  "
+			       "Failing attach\n", ahc_name(ahc));
+			return (ENOMEM);
+		}
+	}
+
+	ahc_outb(ahc, SEQ_FLAGS, 0);
+	ahc_outb(ahc, SEQ_FLAGS2, 0);
+
+	if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
+		ahc->flags |= AHC_PAGESCBS;
+	} else {
+		ahc->flags &= ~AHC_PAGESCBS;
+	}
+
+#ifdef AHC_DEBUG
+	if (ahc_debug & AHC_SHOWMISC) {
+		printf("%s: hardware scb %d bytes; kernel scb %d bytes; "
+		       "ahc_dma %d bytes\n",
+			ahc_name(ahc),
+			sizeof(struct hardware_scb),
+			sizeof(struct scb),
+			sizeof(struct ahc_dma_seg));
+	}
+#endif /* AHC_DEBUG */
+
+	/* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/
+	if (ahc->features & AHC_TWIN) {
+
+		/*
+		 * The device is gated to channel B after a chip reset,
+		 * so set those values first
+		 */
+		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
+		term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
+		ahc_outb(ahc, SCSIID, ahc->our_id_b);
+		scsi_conf = ahc_inb(ahc, SCSICONF + 1);
+		ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
+					|term|ahc->seltime_b|ENSTIMER|ACTNEGEN);
+		if ((ahc->features & AHC_ULTRA2) != 0)
+			ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
+		ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
+		ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
+
+		if ((scsi_conf & RESET_SCSI) != 0
+		 && (ahc->flags & AHC_INITIATORROLE) != 0)
+			ahc->flags |= AHC_RESET_BUS_B;
+
+		/* Select Channel A */
+		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
+	}
+	term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
+	else
+		ahc_outb(ahc, SCSIID, ahc->our_id);
+	scsi_conf = ahc_inb(ahc, SCSICONF);
+	ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
+				|term|ahc->seltime
+				|ENSTIMER|ACTNEGEN);
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
+	ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
+	ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
+
+	if ((scsi_conf & RESET_SCSI) != 0
+	 && (ahc->flags & AHC_INITIATORROLE) != 0)
+		ahc->flags |= AHC_RESET_BUS_A;
+
+	/*
+	 * Look at the information that board initialization or
+	 * the board bios has left us.
+	 */
+	ultraenb = 0;	
+	tagenable = ALL_TARGETS_MASK;
+
+	/* Grab the disconnection disable table and invert it for our needs */
+	if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
+		printf("%s: Host Adapter Bios disabled.  Using default SCSI "
+			"device parameters\n", ahc_name(ahc));
+		ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
+			      AHC_TERM_ENB_A|AHC_TERM_ENB_B;
+		discenable = ALL_TARGETS_MASK;
+		if ((ahc->features & AHC_ULTRA) != 0)
+			ultraenb = ALL_TARGETS_MASK;
+	} else {
+		discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)
+			   | ahc_inb(ahc, DISC_DSB));
+		if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)
+			ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
+				      | ahc_inb(ahc, ULTRA_ENB);
+	}
+
+	if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
+		max_targ = 7;
+
+	for (i = 0; i <= max_targ; i++) {
+		struct ahc_initiator_tinfo *tinfo;
+		struct ahc_tmode_tstate *tstate;
+		u_int our_id;
+		u_int target_id;
+		char channel;
+
+		channel = 'A';
+		our_id = ahc->our_id;
+		target_id = i;
+		if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
+			channel = 'B';
+			our_id = ahc->our_id_b;
+			target_id = i % 8;
+		}
+		tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
+					    target_id, &tstate);
+		/* Default to async narrow across the board */
+		memset(tinfo, 0, sizeof(*tinfo));
+		if (ahc->flags & AHC_USEDEFAULTS) {
+			if ((ahc->features & AHC_WIDE) != 0)
+				tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
+
+			/*
+			 * These will be truncated when we determine the
+			 * connection type we have with the target.
+			 */
+			tinfo->user.period = ahc_syncrates->period;
+			tinfo->user.offset = ~0;
+		} else {
+			u_int scsirate;
+			uint16_t mask;
+
+			/* Take the settings leftover in scratch RAM. */
+			scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);
+			mask = (0x01 << i);
+			if ((ahc->features & AHC_ULTRA2) != 0) {
+				u_int offset;
+				u_int maxsync;
+
+				if ((scsirate & SOFS) == 0x0F) {
+					/*
+					 * Haven't negotiated yet,
+					 * so the format is different.
+					 */
+					scsirate = (scsirate & SXFR) >> 4
+						 | (ultraenb & mask)
+						  ? 0x08 : 0x0
+						 | (scsirate & WIDEXFER);
+					offset = MAX_OFFSET_ULTRA2;
+				} else
+					offset = ahc_inb(ahc, TARG_OFFSET + i);
+				if ((scsirate & ~WIDEXFER) == 0 && offset != 0)
+					/* Set to the lowest sync rate, 5MHz */
+					scsirate |= 0x1c;
+				maxsync = AHC_SYNCRATE_ULTRA2;
+				if ((ahc->features & AHC_DT) != 0)
+					maxsync = AHC_SYNCRATE_DT;
+				tinfo->user.period =
+				    ahc_find_period(ahc, scsirate, maxsync);
+				if (offset == 0)
+					tinfo->user.period = 0;
+				else
+					tinfo->user.offset = ~0;
+				if ((scsirate & SXFR_ULTRA2) <= 8/*10MHz*/
+				 && (ahc->features & AHC_DT) != 0)
+					tinfo->user.ppr_options =
+					    MSG_EXT_PPR_DT_REQ;
+			} else if ((scsirate & SOFS) != 0) {
+				if ((scsirate & SXFR) == 0x40
+				 && (ultraenb & mask) != 0) {
+					/* Treat 10MHz as a non-ultra speed */
+					scsirate &= ~SXFR;
+				 	ultraenb &= ~mask;
+				}
+				tinfo->user.period = 
+				    ahc_find_period(ahc, scsirate,
+						    (ultraenb & mask)
+						   ? AHC_SYNCRATE_ULTRA
+						   : AHC_SYNCRATE_FAST);
+				if (tinfo->user.period != 0)
+					tinfo->user.offset = ~0;
+			}
+			if (tinfo->user.period == 0)
+				tinfo->user.offset = 0;
+			if ((scsirate & WIDEXFER) != 0
+			 && (ahc->features & AHC_WIDE) != 0)
+				tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
+			tinfo->user.protocol_version = 4;
+			if ((ahc->features & AHC_DT) != 0)
+				tinfo->user.transport_version = 3;
+			else
+				tinfo->user.transport_version = 2;
+			tinfo->goal.protocol_version = 2;
+			tinfo->goal.transport_version = 2;
+			tinfo->curr.protocol_version = 2;
+			tinfo->curr.transport_version = 2;
+		}
+		tstate->ultraenb = ultraenb;
+	}
+	ahc->user_discenable = discenable;
+	ahc->user_tagenable = tagenable;
+
+	/* There are no untagged SCBs active yet. */
+	for (i = 0; i < 16; i++) {
+		ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
+		if ((ahc->flags & AHC_SCB_BTT) != 0) {
+			int lun;
+
+			/*
+			 * The SCB based BTT allows an entry per
+			 * target and lun pair.
+			 */
+			for (lun = 1; lun < AHC_NUM_LUNS; lun++)
+				ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));
+		}
+	}
+
+	/* All of our queues are empty */
+	for (i = 0; i < 256; i++)
+		ahc->qoutfifo[i] = SCB_LIST_NULL;
+	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);
+
+	for (i = 0; i < 256; i++)
+		ahc->qinfifo[i] = SCB_LIST_NULL;
+
+	if ((ahc->features & AHC_MULTI_TID) != 0) {
+		ahc_outb(ahc, TARGID, 0);
+		ahc_outb(ahc, TARGID + 1, 0);
+	}
+
+	/*
+	 * Tell the sequencer where it can find our arrays in memory.
+	 */
+	physaddr = ahc->scb_data->hscb_busaddr;
+	ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
+	ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
+	ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
+	ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
+
+	physaddr = ahc->shared_data_busaddr;
+	ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);
+	ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);
+	ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);
+	ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);
+
+	/*
+	 * Initialize the group code to command length table.
+	 * This overrides the values in TARG_SCSIRATE, so only
+	 * setup the table after we have processed that information.
+	 */
+	ahc_outb(ahc, CMDSIZE_TABLE, 5);
+	ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
+	ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
+	ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
+	ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
+	ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
+	ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
+	ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
+		
+	/* Tell the sequencer of our initial queue positions */
+	ahc_outb(ahc, KERNEL_QINPOS, 0);
+	ahc_outb(ahc, QINPOS, 0);
+	ahc_outb(ahc, QOUTPOS, 0);
+
+	/*
+	 * Use the built in queue management registers
+	 * if they are available.
+	 */
+	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
+		ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
+		ahc_outb(ahc, SDSCB_QOFF, 0);
+		ahc_outb(ahc, SNSCB_QOFF, 0);
+		ahc_outb(ahc, HNSCB_QOFF, 0);
+	}
+
+
+	/* We don't have any waiting selections */
+	ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
+
+	/* Our disconnection list is empty too */
+	ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
+
+	/* Message out buffer starts empty */
+	ahc_outb(ahc, MSG_OUT, MSG_NOOP);
+
+	/*
+	 * Setup the allowed SCSI Sequences based on operational mode.
+	 * If we are a target, we'll enalbe select in operations once
+	 * we've had a lun enabled.
+	 */
+	scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
+	if ((ahc->flags & AHC_INITIATORROLE) != 0)
+		scsiseq_template |= ENRSELI;
+	ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
+
+	/*
+	 * Load the Sequencer program and Enable the adapter
+	 * in "fast" mode.
+	 */
+	if (bootverbose)
+		printf("%s: Downloading Sequencer Program...",
+		       ahc_name(ahc));
+
+	ahc_loadseq(ahc);
+
+	if ((ahc->features & AHC_ULTRA2) != 0) {
+		int wait;
+
+		/*
+		 * Wait for up to 500ms for our transceivers
+		 * to settle.  If the adapter does not have
+		 * a cable attached, the tranceivers may
+		 * never settle, so don't complain if we
+		 * fail here.
+		 */
+		ahc_pause(ahc);
+		for (wait = 5000;
+		     (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
+		     wait--)
+			ahc_delay(100);
+		ahc_unpause(ahc);
+	}
+	return (0);
+}
+
+void
+ahc_intr_enable(struct ahc_softc *ahc, int enable)
+{
+	u_int hcntrl;
+
+	hcntrl = ahc_inb(ahc, HCNTRL);
+	hcntrl &= ~INTEN;
+	ahc->pause &= ~INTEN;
+	ahc->unpause &= ~INTEN;
+	if (enable) {
+		hcntrl |= INTEN;
+		ahc->pause |= INTEN;
+		ahc->unpause |= INTEN;
+	}
+	ahc_outb(ahc, HCNTRL, hcntrl);
+}
+
+/*
+ * Ensure that the card is paused in a location
+ * outside of all critical sections and that all
+ * pending work is completed prior to returning.
+ * This routine should only be called from outside
+ * an interrupt context.
+ */
+void
+ahc_pause_and_flushwork(struct ahc_softc *ahc)
+{
+	int intstat;
+	int maxloops;
+
+	maxloops = 1000;
+	ahc->flags |= AHC_ALL_INTERRUPTS;
+	intstat = 0;
+	do {
+		ahc_intr(ahc);
+		ahc_pause(ahc);
+		ahc_clear_critical_section(ahc);
+		if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0)
+			break;
+		maxloops--;
+	} while (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) && --maxloops);
+	if (maxloops == 0) {
+		printf("Infinite interrupt loop, INTSTAT = %x",
+		      ahc_inb(ahc, INTSTAT));
+	}
+	ahc_platform_flushwork(ahc);
+	ahc->flags &= ~AHC_ALL_INTERRUPTS;
+}
+
+int
+ahc_suspend(struct ahc_softc *ahc)
+{
+	uint8_t *ptr;
+	int	 i;
+
+	ahc_pause_and_flushwork(ahc);
+
+	if (LIST_FIRST(&ahc->pending_scbs) != NULL)
+		return (EBUSY);
+
+#if AHC_TARGET_MODE
+	/*
+	 * XXX What about ATIOs that have not yet been serviced?
+	 * Perhaps we should just refuse to be suspended if we
+	 * are acting in a target role.
+	 */
+	if (ahc->pending_device != NULL)
+		return (EBUSY);
+#endif
+
+	/* Save volatile registers */
+	if ((ahc->features & AHC_TWIN) != 0) {
+		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
+		ahc->suspend_state.channel[1].scsiseq = ahc_inb(ahc, SCSISEQ);
+		ahc->suspend_state.channel[1].sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
+		ahc->suspend_state.channel[1].sxfrctl1 = ahc_inb(ahc, SXFRCTL1);
+		ahc->suspend_state.channel[1].simode0 = ahc_inb(ahc, SIMODE0);
+		ahc->suspend_state.channel[1].simode1 = ahc_inb(ahc, SIMODE1);
+		ahc->suspend_state.channel[1].seltimer = ahc_inb(ahc, SELTIMER);
+		ahc->suspend_state.channel[1].seqctl = ahc_inb(ahc, SEQCTL);
+		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
+	}
+	ahc->suspend_state.channel[0].scsiseq = ahc_inb(ahc, SCSISEQ);
+	ahc->suspend_state.channel[0].sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
+	ahc->suspend_state.channel[0].sxfrctl1 = ahc_inb(ahc, SXFRCTL1);
+	ahc->suspend_state.channel[0].simode0 = ahc_inb(ahc, SIMODE0);
+	ahc->suspend_state.channel[0].simode1 = ahc_inb(ahc, SIMODE1);
+	ahc->suspend_state.channel[0].seltimer = ahc_inb(ahc, SELTIMER);
+	ahc->suspend_state.channel[0].seqctl = ahc_inb(ahc, SEQCTL);
+
+	if ((ahc->chip & AHC_PCI) != 0) {
+		ahc->suspend_state.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
+		ahc->suspend_state.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
+	}
+
+	if ((ahc->features & AHC_DT) != 0) {
+		u_int sfunct;
+
+		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
+		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
+		ahc->suspend_state.optionmode = ahc_inb(ahc, OPTIONMODE);
+		ahc_outb(ahc, SFUNCT, sfunct);
+		ahc->suspend_state.crccontrol1 = ahc_inb(ahc, CRCCONTROL1);
+	}
+
+	if ((ahc->features & AHC_MULTI_FUNC) != 0)
+		ahc->suspend_state.scbbaddr = ahc_inb(ahc, SCBBADDR);
+
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		ahc->suspend_state.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
+
+	ptr = ahc->suspend_state.scratch_ram;
+	for (i = 0; i < 64; i++)
+		*ptr++ = ahc_inb(ahc, SRAM_BASE + i);
+
+	if ((ahc->features & AHC_MORE_SRAM) != 0) {
+		for (i = 0; i < 16; i++)
+			*ptr++ = ahc_inb(ahc, TARG_OFFSET + i);
+	}
+
+	ptr = ahc->suspend_state.btt;
+	if ((ahc->flags & AHC_SCB_BTT) != 0) {
+		for (i = 0;i < AHC_NUM_TARGETS; i++) {
+			int j;
+
+			for (j = 0;j < AHC_NUM_LUNS; j++) {
+				u_int tcl;
+
+				tcl = BUILD_TCL(i << 4, j);
+				*ptr = ahc_index_busy_tcl(ahc, tcl);
+			}
+		}
+	}
+	ahc_shutdown(ahc);
+	return (0);
+}
+
+int
+ahc_resume(struct ahc_softc *ahc)
+{
+	uint8_t *ptr;
+	int	 i;
+
+	ahc_reset(ahc);
+
+	ahc_build_free_scb_list(ahc);
+
+	/* Restore volatile registers */
+	if ((ahc->features & AHC_TWIN) != 0) {
+		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
+		ahc_outb(ahc, SCSIID, ahc->our_id);
+		ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[1].scsiseq);
+		ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[1].sxfrctl0);
+		ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[1].sxfrctl1);
+		ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[1].simode0);
+		ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[1].simode1);
+		ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[1].seltimer);
+		ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[1].seqctl);
+		ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
+	}
+	ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[0].scsiseq);
+	ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[0].sxfrctl0);
+	ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[0].sxfrctl1);
+	ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[0].simode0);
+	ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[0].simode1);
+	ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[0].seltimer);
+	ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[0].seqctl);
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
+	else
+		ahc_outb(ahc, SCSIID, ahc->our_id);
+
+	if ((ahc->chip & AHC_PCI) != 0) {
+		ahc_outb(ahc, DSCOMMAND0, ahc->suspend_state.dscommand0);
+		ahc_outb(ahc, DSPCISTATUS, ahc->suspend_state.dspcistatus);
+	}
+
+	if ((ahc->features & AHC_DT) != 0) {
+		u_int sfunct;
+
+		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
+		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
+		ahc_outb(ahc, OPTIONMODE, ahc->suspend_state.optionmode);
+		ahc_outb(ahc, SFUNCT, sfunct);
+		ahc_outb(ahc, CRCCONTROL1, ahc->suspend_state.crccontrol1);
+	}
+
+	if ((ahc->features & AHC_MULTI_FUNC) != 0)
+		ahc_outb(ahc, SCBBADDR, ahc->suspend_state.scbbaddr);
+
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		ahc_outb(ahc, DFF_THRSH, ahc->suspend_state.dff_thrsh);
+
+	ptr = ahc->suspend_state.scratch_ram;
+	for (i = 0; i < 64; i++)
+		ahc_outb(ahc, SRAM_BASE + i, *ptr++);
+
+	if ((ahc->features & AHC_MORE_SRAM) != 0) {
+		for (i = 0; i < 16; i++)
+			ahc_outb(ahc, TARG_OFFSET + i, *ptr++);
+	}
+
+	ptr = ahc->suspend_state.btt;
+	if ((ahc->flags & AHC_SCB_BTT) != 0) {
+		for (i = 0;i < AHC_NUM_TARGETS; i++) {
+			int j;
+
+			for (j = 0;j < AHC_NUM_LUNS; j++) {
+				u_int tcl;
+
+				tcl = BUILD_TCL(i << 4, j);
+				ahc_busy_tcl(ahc, tcl, *ptr);
+			}
+		}
+	}
+	return (0);
+}
+
+/************************** Busy Target Table *********************************/
+/*
+ * Return the untagged transaction id for a given target/channel lun.
+ * Optionally, clear the entry.
+ */
+u_int
+ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
+{
+	u_int scbid;
+	u_int target_offset;
+
+	if ((ahc->flags & AHC_SCB_BTT) != 0) {
+		u_int saved_scbptr;
+		
+		saved_scbptr = ahc_inb(ahc, SCBPTR);
+		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
+		scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
+		ahc_outb(ahc, SCBPTR, saved_scbptr);
+	} else {
+		target_offset = TCL_TARGET_OFFSET(tcl);
+		scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
+	}
+
+	return (scbid);
+}
+
+void
+ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
+{
+	u_int target_offset;
+
+	if ((ahc->flags & AHC_SCB_BTT) != 0) {
+		u_int saved_scbptr;
+		
+		saved_scbptr = ahc_inb(ahc, SCBPTR);
+		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
+		ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
+		ahc_outb(ahc, SCBPTR, saved_scbptr);
+	} else {
+		target_offset = TCL_TARGET_OFFSET(tcl);
+		ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
+	}
+}
+
+void
+ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
+{
+	u_int target_offset;
+
+	if ((ahc->flags & AHC_SCB_BTT) != 0) {
+		u_int saved_scbptr;
+		
+		saved_scbptr = ahc_inb(ahc, SCBPTR);
+		ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
+		ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
+		ahc_outb(ahc, SCBPTR, saved_scbptr);
+	} else {
+		target_offset = TCL_TARGET_OFFSET(tcl);
+		ahc_outb(ahc, BUSY_TARGETS + target_offset, scbid);
+	}
+}
+
+/************************** SCB and SCB queue management **********************/
+int
+ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,
+	      char channel, int lun, u_int tag, role_t role)
+{
+	int targ = SCB_GET_TARGET(ahc, scb);
+	char chan = SCB_GET_CHANNEL(ahc, scb);
+	int slun = SCB_GET_LUN(scb);
+	int match;
+
+	match = ((chan == channel) || (channel == ALL_CHANNELS));
+	if (match != 0)
+		match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
+	if (match != 0)
+		match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
+	if (match != 0) {
+#if AHC_TARGET_MODE
+		int group;
+
+		group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
+		if (role == ROLE_INITIATOR) {
+			match = (group != XPT_FC_GROUP_TMODE)
+			      && ((tag == scb->hscb->tag)
+			       || (tag == SCB_LIST_NULL));
+		} else if (role == ROLE_TARGET) {
+			match = (group == XPT_FC_GROUP_TMODE)
+			      && ((tag == scb->io_ctx->csio.tag_id)
+			       || (tag == SCB_LIST_NULL));
+		}
+#else /* !AHC_TARGET_MODE */
+		match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
+#endif /* AHC_TARGET_MODE */
+	}
+
+	return match;
+}
+
+void
+ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
+{
+	int	target;
+	char	channel;
+	int	lun;
+
+	target = SCB_GET_TARGET(ahc, scb);
+	lun = SCB_GET_LUN(scb);
+	channel = SCB_GET_CHANNEL(ahc, scb);
+	
+	ahc_search_qinfifo(ahc, target, channel, lun,
+			   /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
+			   CAM_REQUEUE_REQ, SEARCH_COMPLETE);
+
+	ahc_platform_freeze_devq(ahc, scb);
+}
+
+void
+ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb)
+{
+	struct scb *prev_scb;
+
+	prev_scb = NULL;
+	if (ahc_qinfifo_count(ahc) != 0) {
+		u_int prev_tag;
+		uint8_t prev_pos;
+
+		prev_pos = ahc->qinfifonext - 1;
+		prev_tag = ahc->qinfifo[prev_pos];
+		prev_scb = ahc_lookup_scb(ahc, prev_tag);
+	}
+	ahc_qinfifo_requeue(ahc, prev_scb, scb);
+	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
+		ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
+	} else {
+		ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
+	}
+}
+
+static void
+ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,
+		    struct scb *scb)
+{
+	if (prev_scb == NULL) {
+		ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
+	} else {
+		prev_scb->hscb->next = scb->hscb->tag;
+		ahc_sync_scb(ahc, prev_scb, 
+			     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+	}
+	ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
+	scb->hscb->next = ahc->next_queued_scb->hscb->tag;
+	ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+}
+
+static int
+ahc_qinfifo_count(struct ahc_softc *ahc)
+{
+	u_int8_t qinpos;
+	u_int8_t diff;
+
+	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
+		qinpos = ahc_inb(ahc, SNSCB_QOFF);
+		ahc_outb(ahc, SNSCB_QOFF, qinpos);
+	} else
+		qinpos = ahc_inb(ahc, QINPOS);
+	diff = ahc->qinfifonext - qinpos;
+	return (diff);
+}
+
+int
+ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
+		   int lun, u_int tag, role_t role, uint32_t status,
+		   ahc_search_action action)
+{
+	struct	scb *scb;
+	struct	scb *prev_scb;
+	uint8_t qinstart;
+	uint8_t qinpos;
+	uint8_t qintail;
+	uint8_t next;
+	uint8_t prev;
+	uint8_t curscbptr;
+	int	found;
+	int	have_qregs;
+
+	qintail = ahc->qinfifonext;
+	have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
+	if (have_qregs) {
+		qinstart = ahc_inb(ahc, SNSCB_QOFF);
+		ahc_outb(ahc, SNSCB_QOFF, qinstart);
+	} else
+		qinstart = ahc_inb(ahc, QINPOS);
+	qinpos = qinstart;
+	found = 0;
+	prev_scb = NULL;
+
+	if (action == SEARCH_COMPLETE) {
+		/*
+		 * Don't attempt to run any queued untagged transactions
+		 * until we are done with the abort process.
+		 */
+		ahc_freeze_untagged_queues(ahc);
+	}
+
+	/*
+	 * Start with an empty queue.  Entries that are not chosen
+	 * for removal will be re-added to the queue as we go.
+	 */
+	ahc->qinfifonext = qinpos;
+	ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
+
+	while (qinpos != qintail) {
+		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
+		if (scb == NULL) {
+			printf("qinpos = %d, SCB index = %d\n",
+				qinpos, ahc->qinfifo[qinpos]);
+			panic("Loop 1\n");
+		}
+
+		if (ahc_match_scb(ahc, scb, target, channel, lun, tag, role)) {
+			/*
+			 * We found an scb that needs to be acted on.
+			 */
+			found++;
+			switch (action) {
+			case SEARCH_COMPLETE:
+			{
+				cam_status ostat;
+				cam_status cstat;
+
+				ostat = ahc_get_transaction_status(scb);
+				if (ostat == CAM_REQ_INPROG)
+					ahc_set_transaction_status(scb, status);
+				cstat = ahc_get_transaction_status(scb);
+				if (cstat != CAM_REQ_CMP)
+					ahc_freeze_scb(scb);
+				if ((scb->flags & SCB_ACTIVE) == 0)
+					printf("Inactive SCB in qinfifo\n");
+				ahc_done(ahc, scb);
+
+				/* FALLTHROUGH */
+			}
+			case SEARCH_REMOVE:
+				break;
+			case SEARCH_COUNT:
+				ahc_qinfifo_requeue(ahc, prev_scb, scb);
+				prev_scb = scb;
+				break;
+			}
+		} else {
+			ahc_qinfifo_requeue(ahc, prev_scb, scb);
+			prev_scb = scb;
+		}
+		qinpos++;
+	}
+
+	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
+		ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
+	} else {
+		ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
+	}
+
+	if (action != SEARCH_COUNT
+	 && (found != 0)
+	 && (qinstart != ahc->qinfifonext)) {
+		/*
+		 * The sequencer may be in the process of dmaing
+		 * down the SCB at the beginning of the queue.
+		 * This could be problematic if either the first,
+		 * or the second SCB is removed from the queue
+		 * (the first SCB includes a pointer to the "next"
+		 * SCB to dma). If we have removed any entries, swap
+		 * the first element in the queue with the next HSCB
+		 * so the sequencer will notice that NEXT_QUEUED_SCB
+		 * has changed during its dma attempt and will retry
+		 * the DMA.
+		 */
+		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
+
+		if (scb == NULL) {
+			printf("found = %d, qinstart = %d, qinfifionext = %d\n",
+				found, qinstart, ahc->qinfifonext);
+			panic("First/Second Qinfifo fixup\n");
+		}
+		/*
+		 * ahc_swap_with_next_hscb forces our next pointer to
+		 * point to the reserved SCB for future commands.  Save
+		 * and restore our original next pointer to maintain
+		 * queue integrity.
+		 */
+		next = scb->hscb->next;
+		ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
+		ahc_swap_with_next_hscb(ahc, scb);
+		scb->hscb->next = next;
+		ahc->qinfifo[qinstart] = scb->hscb->tag;
+
+		/* Tell the card about the new head of the qinfifo. */
+		ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
+
+		/* Fixup the tail "next" pointer. */
+		qintail = ahc->qinfifonext - 1;
+		scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);
+		scb->hscb->next = ahc->next_queued_scb->hscb->tag;
+	}
+
+	/*
+	 * Search waiting for selection list.
+	 */
+	curscbptr = ahc_inb(ahc, SCBPTR);
+	next = ahc_inb(ahc, WAITING_SCBH);  /* Start at head of list. */
+	prev = SCB_LIST_NULL;
+
+	while (next != SCB_LIST_NULL) {
+		uint8_t scb_index;
+
+		ahc_outb(ahc, SCBPTR, next);
+		scb_index = ahc_inb(ahc, SCB_TAG);
+		if (scb_index >= ahc->scb_data->numscbs) {
+			printf("Waiting List inconsistency. "
+			       "SCB index == %d, yet numscbs == %d.",
+			       scb_index, ahc->scb_data->numscbs);
+			ahc_dump_card_state(ahc);
+			panic("for safety");
+		}
+		scb = ahc_lookup_scb(ahc, scb_index);
+		if (scb == NULL) {
+			printf("scb_index = %d, next = %d\n",
+				scb_index, next);
+			panic("Waiting List traversal\n");
+		}
+		if (ahc_match_scb(ahc, scb, target, channel,
+				  lun, SCB_LIST_NULL, role)) {
+			/*
+			 * We found an scb that needs to be acted on.
+			 */
+			found++;
+			switch (action) {
+			case SEARCH_COMPLETE:
+			{
+				cam_status ostat;
+				cam_status cstat;
+
+				ostat = ahc_get_transaction_status(scb);
+				if (ostat == CAM_REQ_INPROG)
+					ahc_set_transaction_status(scb,
+								   status);
+				cstat = ahc_get_transaction_status(scb);
+				if (cstat != CAM_REQ_CMP)
+					ahc_freeze_scb(scb);
+				if ((scb->flags & SCB_ACTIVE) == 0)
+					printf("Inactive SCB in Waiting List\n");
+				ahc_done(ahc, scb);
+				/* FALLTHROUGH */
+			}
+			case SEARCH_REMOVE:
+				next = ahc_rem_wscb(ahc, next, prev);
+				break;
+			case SEARCH_COUNT:
+				prev = next;
+				next = ahc_inb(ahc, SCB_NEXT);
+				break;
+			}
+		} else {
+			
+			prev = next;
+			next = ahc_inb(ahc, SCB_NEXT);
+		}
+	}
+	ahc_outb(ahc, SCBPTR, curscbptr);
+
+	found += ahc_search_untagged_queues(ahc, /*ahc_io_ctx_t*/NULL, target,
+					    channel, lun, status, action);
+
+	if (action == SEARCH_COMPLETE)
+		ahc_release_untagged_queues(ahc);
+	return (found);
+}
+
+int
+ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx,
+			   int target, char channel, int lun, uint32_t status,
+			   ahc_search_action action)
+{
+	struct	scb *scb;
+	int	maxtarget;
+	int	found;
+	int	i;
+
+	if (action == SEARCH_COMPLETE) {
+		/*
+		 * Don't attempt to run any queued untagged transactions
+		 * until we are done with the abort process.
+		 */
+		ahc_freeze_untagged_queues(ahc);
+	}
+
+	found = 0;
+	i = 0;
+	if ((ahc->flags & AHC_SCB_BTT) == 0) {
+
+		maxtarget = 16;
+		if (target != CAM_TARGET_WILDCARD) {
+
+			i = target;
+			if (channel == 'B')
+				i += 8;
+			maxtarget = i + 1;
+		}
+	} else {
+		maxtarget = 0;
+	}
+
+	for (; i < maxtarget; i++) {
+		struct scb_tailq *untagged_q;
+		struct scb *next_scb;
+
+		untagged_q = &(ahc->untagged_queues[i]);
+		next_scb = TAILQ_FIRST(untagged_q);
+		while (next_scb != NULL) {
+
+			scb = next_scb;
+			next_scb = TAILQ_NEXT(scb, links.tqe);
+
+			/*
+			 * The head of the list may be the currently
+			 * active untagged command for a device.
+			 * We're only searching for commands that
+			 * have not been started.  A transaction
+			 * marked active but still in the qinfifo
+			 * is removed by the qinfifo scanning code
+			 * above.
+			 */
+			if ((scb->flags & SCB_ACTIVE) != 0)
+				continue;
+
+			if (ahc_match_scb(ahc, scb, target, channel, lun,
+					  SCB_LIST_NULL, ROLE_INITIATOR) == 0
+			 || (ctx != NULL && ctx != scb->io_ctx))
+				continue;
+
+			/*
+			 * We found an scb that needs to be acted on.
+			 */
+			found++;
+			switch (action) {
+			case SEARCH_COMPLETE:
+			{
+				cam_status ostat;
+				cam_status cstat;
+
+				ostat = ahc_get_transaction_status(scb);
+				if (ostat == CAM_REQ_INPROG)
+					ahc_set_transaction_status(scb, status);
+				cstat = ahc_get_transaction_status(scb);
+				if (cstat != CAM_REQ_CMP)
+					ahc_freeze_scb(scb);
+				if ((scb->flags & SCB_ACTIVE) == 0)
+					printf("Inactive SCB in untaggedQ\n");
+				ahc_done(ahc, scb);
+				break;
+			}
+			case SEARCH_REMOVE:
+				TAILQ_REMOVE(untagged_q, scb, links.tqe);
+				break;
+			case SEARCH_COUNT:
+				break;
+			}
+		}
+	}
+
+	if (action == SEARCH_COMPLETE)
+		ahc_release_untagged_queues(ahc);
+	return (found);
+}
+
+int
+ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
+		     int lun, u_int tag, int stop_on_first, int remove,
+		     int save_state)
+{
+	struct	scb *scbp;
+	u_int	next;
+	u_int	prev;
+	u_int	count;
+	u_int	active_scb;
+
+	count = 0;
+	next = ahc_inb(ahc, DISCONNECTED_SCBH);
+	prev = SCB_LIST_NULL;
+
+	if (save_state) {
+		/* restore this when we're done */
+		active_scb = ahc_inb(ahc, SCBPTR);
+	} else
+		/* Silence compiler */
+		active_scb = SCB_LIST_NULL;
+
+	while (next != SCB_LIST_NULL) {
+		u_int scb_index;
+
+		ahc_outb(ahc, SCBPTR, next);
+		scb_index = ahc_inb(ahc, SCB_TAG);
+		if (scb_index >= ahc->scb_data->numscbs) {
+			printf("Disconnected List inconsistency. "
+			       "SCB index == %d, yet numscbs == %d.",
+			       scb_index, ahc->scb_data->numscbs);
+			ahc_dump_card_state(ahc);
+			panic("for safety");
+		}
+
+		if (next == prev) {
+			panic("Disconnected List Loop. "
+			      "cur SCBPTR == %x, prev SCBPTR == %x.",
+			      next, prev);
+		}
+		scbp = ahc_lookup_scb(ahc, scb_index);
+		if (ahc_match_scb(ahc, scbp, target, channel, lun,
+				  tag, ROLE_INITIATOR)) {
+			count++;
+			if (remove) {
+				next =
+				    ahc_rem_scb_from_disc_list(ahc, prev, next);
+			} else {
+				prev = next;
+				next = ahc_inb(ahc, SCB_NEXT);
+			}
+			if (stop_on_first)
+				break;
+		} else {
+			prev = next;
+			next = ahc_inb(ahc, SCB_NEXT);
+		}
+	}
+	if (save_state)
+		ahc_outb(ahc, SCBPTR, active_scb);
+	return (count);
+}
+
+/*
+ * Remove an SCB from the on chip list of disconnected transactions.
+ * This is empty/unused if we are not performing SCB paging.
+ */
+static u_int
+ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)
+{
+	u_int next;
+
+	ahc_outb(ahc, SCBPTR, scbptr);
+	next = ahc_inb(ahc, SCB_NEXT);
+
+	ahc_outb(ahc, SCB_CONTROL, 0);
+
+	ahc_add_curscb_to_free_list(ahc);
+
+	if (prev != SCB_LIST_NULL) {
+		ahc_outb(ahc, SCBPTR, prev);
+		ahc_outb(ahc, SCB_NEXT, next);
+	} else
+		ahc_outb(ahc, DISCONNECTED_SCBH, next);
+
+	return (next);
+}
+
+/*
+ * Add the SCB as selected by SCBPTR onto the on chip list of
+ * free hardware SCBs.  This list is empty/unused if we are not
+ * performing SCB paging.
+ */
+static void
+ahc_add_curscb_to_free_list(struct ahc_softc *ahc)
+{
+	/*
+	 * Invalidate the tag so that our abort
+	 * routines don't think it's active.
+	 */
+	ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
+
+	if ((ahc->flags & AHC_PAGESCBS) != 0) {
+		ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));
+		ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));
+	}
+}
+
+/*
+ * Manipulate the waiting for selection list and return the
+ * scb that follows the one that we remove.
+ */
+static u_int
+ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
+{       
+	u_int curscb, next;
+
+	/*
+	 * Select the SCB we want to abort and
+	 * pull the next pointer out of it.
+	 */
+	curscb = ahc_inb(ahc, SCBPTR);
+	ahc_outb(ahc, SCBPTR, scbpos);
+	next = ahc_inb(ahc, SCB_NEXT);
+
+	/* Clear the necessary fields */
+	ahc_outb(ahc, SCB_CONTROL, 0);
+
+	ahc_add_curscb_to_free_list(ahc);
+
+	/* update the waiting list */
+	if (prev == SCB_LIST_NULL) {
+		/* First in the list */
+		ahc_outb(ahc, WAITING_SCBH, next); 
+
+		/*
+		 * Ensure we aren't attempting to perform
+		 * selection for this entry.
+		 */
+		ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
+	} else {
+		/*
+		 * Select the scb that pointed to us 
+		 * and update its next pointer.
+		 */
+		ahc_outb(ahc, SCBPTR, prev);
+		ahc_outb(ahc, SCB_NEXT, next);
+	}
+
+	/*
+	 * Point us back at the original scb position.
+	 */
+	ahc_outb(ahc, SCBPTR, curscb);
+	return next;
+}
+
+/******************************** Error Handling ******************************/
+/*
+ * Abort all SCBs that match the given description (target/channel/lun/tag),
+ * setting their status to the passed in status if the status has not already
+ * been modified from CAM_REQ_INPROG.  This routine assumes that the sequencer
+ * is paused before it is called.
+ */
+int
+ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
+	       int lun, u_int tag, role_t role, uint32_t status)
+{
+	struct	scb *scbp;
+	struct	scb *scbp_next;
+	u_int	active_scb;
+	int	i, j;
+	int	maxtarget;
+	int	minlun;
+	int	maxlun;
+
+	int	found;
+
+	/*
+	 * Don't attempt to run any queued untagged transactions
+	 * until we are done with the abort process.
+	 */
+	ahc_freeze_untagged_queues(ahc);
+
+	/* restore this when we're done */
+	active_scb = ahc_inb(ahc, SCBPTR);
+
+	found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,
+				   role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
+
+	/*
+	 * Clean out the busy target table for any untagged commands.
+	 */
+	i = 0;
+	maxtarget = 16;
+	if (target != CAM_TARGET_WILDCARD) {
+		i = target;
+		if (channel == 'B')
+			i += 8;
+		maxtarget = i + 1;
+	}
+
+	if (lun == CAM_LUN_WILDCARD) {
+
+		/*
+		 * Unless we are using an SCB based
+		 * busy targets table, there is only
+		 * one table entry for all luns of
+		 * a target.
+		 */
+		minlun = 0;
+		maxlun = 1;
+		if ((ahc->flags & AHC_SCB_BTT) != 0)
+			maxlun = AHC_NUM_LUNS;
+	} else {
+		minlun = lun;
+		maxlun = lun + 1;
+	}
+
+	if (role != ROLE_TARGET) {
+		for (;i < maxtarget; i++) {
+			for (j = minlun;j < maxlun; j++) {
+				u_int scbid;
+				u_int tcl;
+
+				tcl = BUILD_TCL(i << 4, j);
+				scbid = ahc_index_busy_tcl(ahc, tcl);
+				scbp = ahc_lookup_scb(ahc, scbid);
+				if (scbp == NULL
+				 || ahc_match_scb(ahc, scbp, target, channel,
+						  lun, tag, role) == 0)
+					continue;
+				ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, j));
+			}
+		}
+
+		/*
+		 * Go through the disconnected list and remove any entries we
+		 * have queued for completion, 0'ing their control byte too.
+		 * We save the active SCB and restore it ourselves, so there
+		 * is no reason for this search to restore it too.
+		 */
+		ahc_search_disc_list(ahc, target, channel, lun, tag,
+				     /*stop_on_first*/FALSE, /*remove*/TRUE,
+				     /*save_state*/FALSE);
+	}
+
+	/*
+	 * Go through the hardware SCB array looking for commands that
+	 * were active but not on any list.  In some cases, these remnants
+	 * might not still have mappings in the scbindex array (e.g. unexpected
+	 * bus free with the same scb queued for an abort).  Don't hold this
+	 * against them.
+	 */
+	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
+		u_int scbid;
+
+		ahc_outb(ahc, SCBPTR, i);
+		scbid = ahc_inb(ahc, SCB_TAG);
+		scbp = ahc_lookup_scb(ahc, scbid);
+		if ((scbp == NULL && scbid != SCB_LIST_NULL)
+		 || (scbp != NULL
+		  && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)))
+			ahc_add_curscb_to_free_list(ahc);
+	}
+
+	/*
+	 * Go through the pending CCB list and look for
+	 * commands for this target that are still active.
+	 * These are other tagged commands that were
+	 * disconnected when the reset occurred.
+	 */
+	scbp_next = LIST_FIRST(&ahc->pending_scbs);
+	while (scbp_next != NULL) {
+		scbp = scbp_next;
+		scbp_next = LIST_NEXT(scbp, pending_links);
+		if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
+			cam_status ostat;
+
+			ostat = ahc_get_transaction_status(scbp);
+			if (ostat == CAM_REQ_INPROG)
+				ahc_set_transaction_status(scbp, status);
+			if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
+				ahc_freeze_scb(scbp);
+			if ((scbp->flags & SCB_ACTIVE) == 0)
+				printf("Inactive SCB on pending list\n");
+			ahc_done(ahc, scbp);
+			found++;
+		}
+	}
+	ahc_outb(ahc, SCBPTR, active_scb);
+	ahc_platform_abort_scbs(ahc, target, channel, lun, tag, role, status);
+	ahc_release_untagged_queues(ahc);
+	return found;
+}
+
+static void
+ahc_reset_current_bus(struct ahc_softc *ahc)
+{
+	uint8_t scsiseq;
+
+	ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
+	scsiseq = ahc_inb(ahc, SCSISEQ);
+	ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
+	ahc_flush_device_writes(ahc);
+	ahc_delay(AHC_BUSRESET_DELAY);
+	/* Turn off the bus reset */
+	ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
+
+	ahc_clear_intstat(ahc);
+
+	/* Re-enable reset interrupts */
+	ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);
+}
+
+int
+ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
+{
+	struct	ahc_devinfo devinfo;
+	u_int	initiator, target, max_scsiid;
+	u_int	sblkctl;
+	u_int	scsiseq;
+	u_int	simode1;
+	int	found;
+	int	restart_needed;
+	char	cur_channel;
+
+	ahc->pending_device = NULL;
+
+	ahc_compile_devinfo(&devinfo,
+			    CAM_TARGET_WILDCARD,
+			    CAM_TARGET_WILDCARD,
+			    CAM_LUN_WILDCARD,
+			    channel, ROLE_UNKNOWN);
+	ahc_pause(ahc);
+
+	/* Make sure the sequencer is in a safe location. */
+	ahc_clear_critical_section(ahc);
+
+	/*
+	 * Run our command complete fifos to ensure that we perform
+	 * completion processing on any commands that 'completed'
+	 * before the reset occurred.
+	 */
+	ahc_run_qoutfifo(ahc);
+#if AHC_TARGET_MODE
+	/*
+	 * XXX - In Twin mode, the tqinfifo may have commands
+	 *	 for an unaffected channel in it.  However, if
+	 *	 we have run out of ATIO resources to drain that
+	 *	 queue, we may not get them all out here.  Further,
+	 *	 the blocked transactions for the reset channel
+	 *	 should just be killed off, irrespecitve of whether
+	 *	 we are blocked on ATIO resources.  Write a routine
+	 *	 to compact the tqinfifo appropriately.
+	 */
+	if ((ahc->flags & AHC_TARGETROLE) != 0) {
+		ahc_run_tqinfifo(ahc, /*paused*/TRUE);
+	}
+#endif
+
+	/*
+	 * Reset the bus if we are initiating this reset
+	 */
+	sblkctl = ahc_inb(ahc, SBLKCTL);
+	cur_channel = 'A';
+	if ((ahc->features & AHC_TWIN) != 0
+	 && ((sblkctl & SELBUSB) != 0))
+	    cur_channel = 'B';
+	scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
+	if (cur_channel != channel) {
+		/* Case 1: Command for another bus is active
+		 * Stealthily reset the other bus without
+		 * upsetting the current bus.
+		 */
+		ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
+		simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
+#if AHC_TARGET_MODE
+		/*
+		 * Bus resets clear ENSELI, so we cannot
+		 * defer re-enabling bus reset interrupts
+		 * if we are in target mode.
+		 */
+		if ((ahc->flags & AHC_TARGETROLE) != 0)
+			simode1 |= ENSCSIRST;
+#endif
+		ahc_outb(ahc, SIMODE1, simode1);
+		if (initiate_reset)
+			ahc_reset_current_bus(ahc);
+		ahc_clear_intstat(ahc);
+		ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
+		ahc_outb(ahc, SBLKCTL, sblkctl);
+		restart_needed = FALSE;
+	} else {
+		/* Case 2: A command from this bus is active or we're idle */
+		simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
+#if AHC_TARGET_MODE
+		/*
+		 * Bus resets clear ENSELI, so we cannot
+		 * defer re-enabling bus reset interrupts
+		 * if we are in target mode.
+		 */
+		if ((ahc->flags & AHC_TARGETROLE) != 0)
+			simode1 |= ENSCSIRST;
+#endif
+		ahc_outb(ahc, SIMODE1, simode1);
+		if (initiate_reset)
+			ahc_reset_current_bus(ahc);
+		ahc_clear_intstat(ahc);
+		ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
+		restart_needed = TRUE;
+	}
+
+	/*
+	 * Clean up all the state information for the
+	 * pending transactions on this bus.
+	 */
+	found = ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, channel,
+			       CAM_LUN_WILDCARD, SCB_LIST_NULL,
+			       ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
+
+	max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;
+
+#ifdef AHC_TARGET_MODE
+	/*
+	 * Send an immediate notify ccb to all target more peripheral
+	 * drivers affected by this action.
+	 */
+	for (target = 0; target <= max_scsiid; target++) {
+		struct ahc_tmode_tstate* tstate;
+		u_int lun;
+
+		tstate = ahc->enabled_targets[target];
+		if (tstate == NULL)
+			continue;
+		for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
+			struct ahc_tmode_lstate* lstate;
+
+			lstate = tstate->enabled_luns[lun];
+			if (lstate == NULL)
+				continue;
+
+			ahc_queue_lstate_event(ahc, lstate, CAM_TARGET_WILDCARD,
+					       EVENT_TYPE_BUS_RESET, /*arg*/0);
+			ahc_send_lstate_events(ahc, lstate);
+		}
+	}
+#endif
+	/* Notify the XPT that a bus reset occurred */
+	ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
+		       CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
+
+	/*
+	 * Revert to async/narrow transfers until we renegotiate.
+	 */
+	for (target = 0; target <= max_scsiid; target++) {
+
+		if (ahc->enabled_targets[target] == NULL)
+			continue;
+		for (initiator = 0; initiator <= max_scsiid; initiator++) {
+			struct ahc_devinfo devinfo;
+
+			ahc_compile_devinfo(&devinfo, target, initiator,
+					    CAM_LUN_WILDCARD,
+					    channel, ROLE_UNKNOWN);
+			ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
+				      AHC_TRANS_CUR, /*paused*/TRUE);
+			ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
+					 /*period*/0, /*offset*/0,
+					 /*ppr_options*/0, AHC_TRANS_CUR,
+					 /*paused*/TRUE);
+		}
+	}
+
+	if (restart_needed)
+		ahc_restart(ahc);
+	else
+		ahc_unpause(ahc);
+	return found;
+}
+
+
+/***************************** Residual Processing ****************************/
+/*
+ * Calculate the residual for a just completed SCB.
+ */
+void
+ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
+{
+	struct hardware_scb *hscb;
+	struct status_pkt *spkt;
+	uint32_t sgptr;
+	uint32_t resid_sgptr;
+	uint32_t resid;
+
+	/*
+	 * 5 cases.
+	 * 1) No residual.
+	 *    SG_RESID_VALID clear in sgptr.
+	 * 2) Transferless command
+	 * 3) Never performed any transfers.
+	 *    sgptr has SG_FULL_RESID set.
+	 * 4) No residual but target did not
+	 *    save data pointers after the
+	 *    last transfer, so sgptr was
+	 *    never updated.
+	 * 5) We have a partial residual.
+	 *    Use residual_sgptr to determine
+	 *    where we are.
+	 */
+
+	hscb = scb->hscb;
+	sgptr = ahc_le32toh(hscb->sgptr);
+	if ((sgptr & SG_RESID_VALID) == 0)
+		/* Case 1 */
+		return;
+	sgptr &= ~SG_RESID_VALID;
+
+	if ((sgptr & SG_LIST_NULL) != 0)
+		/* Case 2 */
+		return;
+
+	spkt = &hscb->shared_data.status;
+	resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);
+	if ((sgptr & SG_FULL_RESID) != 0) {
+		/* Case 3 */
+		resid = ahc_get_transfer_length(scb);
+	} else if ((resid_sgptr & SG_LIST_NULL) != 0) {
+		/* Case 4 */
+		return;
+	} else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
+		panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
+	} else {
+		struct ahc_dma_seg *sg;
+
+		/*
+		 * Remainder of the SG where the transfer
+		 * stopped.  
+		 */
+		resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
+		sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
+
+		/* The residual sg_ptr always points to the next sg */
+		sg--;
+
+		/*
+		 * Add up the contents of all residual
+		 * SG segments that are after the SG where
+		 * the transfer stopped.
+		 */
+		while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
+			sg++;
+			resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
+		}
+	}
+	if ((scb->flags & SCB_SENSE) == 0)
+		ahc_set_residual(scb, resid);
+	else
+		ahc_set_sense_residual(scb, resid);
+
+#ifdef AHC_DEBUG
+	if ((ahc_debug & AHC_SHOWMISC) != 0) {
+		ahc_print_path(ahc, scb);
+		printf("Handled Residual of %d bytes\n", resid);
+	}
+#endif
+}
+
+/******************************* Target Mode **********************************/
+#ifdef AHC_TARGET_MODE
+/*
+ * Add a target mode event to this lun's queue
+ */
+static void
+ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
+		       u_int initiator_id, u_int event_type, u_int event_arg)
+{
+	struct ahc_tmode_event *event;
+	int pending;
+
+	xpt_freeze_devq(lstate->path, /*count*/1);
+	if (lstate->event_w_idx >= lstate->event_r_idx)
+		pending = lstate->event_w_idx - lstate->event_r_idx;
+	else
+		pending = AHC_TMODE_EVENT_BUFFER_SIZE + 1
+			- (lstate->event_r_idx - lstate->event_w_idx);
+
+	if (event_type == EVENT_TYPE_BUS_RESET
+	 || event_type == MSG_BUS_DEV_RESET) {
+		/*
+		 * Any earlier events are irrelevant, so reset our buffer.
+		 * This has the effect of allowing us to deal with reset
+		 * floods (an external device holding down the reset line)
+		 * without losing the event that is really interesting.
+		 */
+		lstate->event_r_idx = 0;
+		lstate->event_w_idx = 0;
+		xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);
+	}
+
+	if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {
+		xpt_print_path(lstate->path);
+		printf("immediate event %x:%x lost\n",
+		       lstate->event_buffer[lstate->event_r_idx].event_type,
+		       lstate->event_buffer[lstate->event_r_idx].event_arg);
+		lstate->event_r_idx++;
+		if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
+			lstate->event_r_idx = 0;
+		xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);
+	}
+
+	event = &lstate->event_buffer[lstate->event_w_idx];
+	event->initiator_id = initiator_id;
+	event->event_type = event_type;
+	event->event_arg = event_arg;
+	lstate->event_w_idx++;
+	if (lstate->event_w_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
+		lstate->event_w_idx = 0;
+}
+
+/*
+ * Send any target mode events queued up waiting
+ * for immediate notify resources.
+ */
+void
+ahc_send_lstate_events(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate)
+{
+	struct ccb_hdr *ccbh;
+	struct ccb_immed_notify *inot;
+
+	while (lstate->event_r_idx != lstate->event_w_idx
+	    && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
+		struct ahc_tmode_event *event;
+
+		event = &lstate->event_buffer[lstate->event_r_idx];
+		SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
+		inot = (struct ccb_immed_notify *)ccbh;
+		switch (event->event_type) {
+		case EVENT_TYPE_BUS_RESET:
+			ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
+			break;
+		default:
+			ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
+			inot->message_args[0] = event->event_type;
+			inot->message_args[1] = event->event_arg;
+			break;
+		}
+		inot->initiator_id = event->initiator_id;
+		inot->sense_len = 0;
+		xpt_done((union ccb *)inot);
+		lstate->event_r_idx++;
+		if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
+			lstate->event_r_idx = 0;
+	}
+}
+#endif
+
+/******************** Sequencer Program Patching/Download *********************/
+
+#ifdef AHC_DUMP_SEQ
+void
+ahc_dumpseq(struct ahc_softc* ahc)
+{
+	int i;
+	int max_prog;
+
+	if ((ahc->chip & AHC_BUS_MASK) < AHC_PCI)
+		max_prog = 448;
+	else if ((ahc->features & AHC_ULTRA2) != 0)
+		max_prog = 768;
+	else
+		max_prog = 512;
+
+	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
+	ahc_outb(ahc, SEQADDR0, 0);
+	ahc_outb(ahc, SEQADDR1, 0);
+	for (i = 0; i < max_prog; i++) {
+		uint8_t ins_bytes[4];
+
+		ahc_insb(ahc, SEQRAM, ins_bytes, 4);
+		printf("0x%08x\n", ins_bytes[0] << 24
+				 | ins_bytes[1] << 16
+				 | ins_bytes[2] << 8
+				 | ins_bytes[3]);
+	}
+}
+#endif
+
+static void
+ahc_loadseq(struct ahc_softc *ahc)
+{
+	struct	cs cs_table[num_critical_sections];
+	u_int	begin_set[num_critical_sections];
+	u_int	end_set[num_critical_sections];
+	struct	patch *cur_patch;
+	u_int	cs_count;
+	u_int	cur_cs;
+	u_int	i;
+	int	downloaded;
+	u_int	skip_addr;
+	u_int	sg_prefetch_cnt;
+	uint8_t	download_consts[7];
+
+	/*
+	 * Start out with 0 critical sections
+	 * that apply to this firmware load.
+	 */
+	cs_count = 0;
+	cur_cs = 0;
+	memset(begin_set, 0, sizeof(begin_set));
+	memset(end_set, 0, sizeof(end_set));
+
+	/* Setup downloadable constant table */
+	download_consts[QOUTFIFO_OFFSET] = 0;
+	if (ahc->targetcmds != NULL)
+		download_consts[QOUTFIFO_OFFSET] += 32;
+	download_consts[QINFIFO_OFFSET] = download_consts[QOUTFIFO_OFFSET] + 1;
+	download_consts[CACHESIZE_MASK] = ahc->pci_cachesize - 1;
+	download_consts[INVERTED_CACHESIZE_MASK] = ~(ahc->pci_cachesize - 1);
+	sg_prefetch_cnt = ahc->pci_cachesize;
+	if (sg_prefetch_cnt < (2 * sizeof(struct ahc_dma_seg)))
+		sg_prefetch_cnt = 2 * sizeof(struct ahc_dma_seg);
+	download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
+	download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_cnt - 1);
+	download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_cnt - 1);
+
+	cur_patch = patches;
+	downloaded = 0;
+	skip_addr = 0;
+	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
+	ahc_outb(ahc, SEQADDR0, 0);
+	ahc_outb(ahc, SEQADDR1, 0);
+
+	for (i = 0; i < sizeof(seqprog)/4; i++) {
+		if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {
+			/*
+			 * Don't download this instruction as it
+			 * is in a patch that was removed.
+			 */
+			continue;
+		}
+		/*
+		 * Move through the CS table until we find a CS
+		 * that might apply to this instruction.
+		 */
+		for (; cur_cs < num_critical_sections; cur_cs++) {
+			if (critical_sections[cur_cs].end <= i) {
+				if (begin_set[cs_count] == TRUE
+				 && end_set[cs_count] == FALSE) {
+					cs_table[cs_count].end = downloaded;
+				 	end_set[cs_count] = TRUE;
+					cs_count++;
+				}
+				continue;
+			}
+			if (critical_sections[cur_cs].begin <= i
+			 && begin_set[cs_count] == FALSE) {
+				cs_table[cs_count].begin = downloaded;
+				begin_set[cs_count] = TRUE;
+			}
+			break;
+		}
+		ahc_download_instr(ahc, i, download_consts);
+		downloaded++;
+	}
+
+	ahc->num_critical_sections = cs_count;
+	if (cs_count != 0) {
+
+		cs_count *= sizeof(struct cs);
+		ahc->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
+		if (ahc->critical_sections == NULL)
+			panic("ahc_loadseq: Could not malloc");
+		memcpy(ahc->critical_sections, cs_table, cs_count);
+	}
+	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
+	ahc_restart(ahc);
+
+	if (bootverbose)
+		printf(" %d instructions downloaded\n", downloaded);
+}
+
+static int
+ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch,
+		u_int start_instr, u_int *skip_addr)
+{
+	struct	patch *cur_patch;
+	struct	patch *last_patch;
+	u_int	num_patches;
+
+	num_patches = sizeof(patches)/sizeof(struct patch);
+	last_patch = &patches[num_patches];
+	cur_patch = *start_patch;
+
+	while (cur_patch < last_patch && start_instr == cur_patch->begin) {
+
+		if (cur_patch->patch_func(ahc) == 0) {
+
+			/* Start rejecting code */
+			*skip_addr = start_instr + cur_patch->skip_instr;
+			cur_patch += cur_patch->skip_patch;
+		} else {
+			/* Accepted this patch.  Advance to the next
+			 * one and wait for our intruction pointer to
+			 * hit this point.
+			 */
+			cur_patch++;
+		}
+	}
+
+	*start_patch = cur_patch;
+	if (start_instr < *skip_addr)
+		/* Still skipping */
+		return (0);
+
+	return (1);
+}
+
+static void
+ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts)
+{
+	union	ins_formats instr;
+	struct	ins_format1 *fmt1_ins;
+	struct	ins_format3 *fmt3_ins;
+	u_int	opcode;
+
+	/*
+	 * The firmware is always compiled into a little endian format.
+	 */
+	instr.integer = ahc_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
+
+	fmt1_ins = &instr.format1;
+	fmt3_ins = NULL;
+
+	/* Pull the opcode */
+	opcode = instr.format1.opcode;
+	switch (opcode) {
+	case AIC_OP_JMP:
+	case AIC_OP_JC:
+	case AIC_OP_JNC:
+	case AIC_OP_CALL:
+	case AIC_OP_JNE:
+	case AIC_OP_JNZ:
+	case AIC_OP_JE:
+	case AIC_OP_JZ:
+	{
+		struct patch *cur_patch;
+		int address_offset;
+		u_int address;
+		u_int skip_addr;
+		u_int i;
+
+		fmt3_ins = &instr.format3;
+		address_offset = 0;
+		address = fmt3_ins->address;
+		cur_patch = patches;
+		skip_addr = 0;
+
+		for (i = 0; i < address;) {
+
+			ahc_check_patch(ahc, &cur_patch, i, &skip_addr);
+
+			if (skip_addr > i) {
+				int end_addr;
+
+				end_addr = MIN(address, skip_addr);
+				address_offset += end_addr - i;
+				i = skip_addr;
+			} else {
+				i++;
+			}
+		}
+		address -= address_offset;
+		fmt3_ins->address = address;
+		/* FALLTHROUGH */
+	}
+	case AIC_OP_OR:
+	case AIC_OP_AND:
+	case AIC_OP_XOR:
+	case AIC_OP_ADD:
+	case AIC_OP_ADC:
+	case AIC_OP_BMOV:
+		if (fmt1_ins->parity != 0) {
+			fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
+		}
+		fmt1_ins->parity = 0;
+		if ((ahc->features & AHC_CMD_CHAN) == 0
+		 && opcode == AIC_OP_BMOV) {
+			/*
+			 * Block move was added at the same time
+			 * as the command channel.  Verify that
+			 * this is only a move of a single element
+			 * and convert the BMOV to a MOV
+			 * (AND with an immediate of FF).
+			 */
+			if (fmt1_ins->immediate != 1)
+				panic("%s: BMOV not supported\n",
+				      ahc_name(ahc));
+			fmt1_ins->opcode = AIC_OP_AND;
+			fmt1_ins->immediate = 0xff;
+		}
+		/* FALLTHROUGH */
+	case AIC_OP_ROL:
+		if ((ahc->features & AHC_ULTRA2) != 0) {
+			int i, count;
+
+			/* Calculate odd parity for the instruction */
+			for (i = 0, count = 0; i < 31; i++) {
+				uint32_t mask;
+
+				mask = 0x01 << i;
+				if ((instr.integer & mask) != 0)
+					count++;
+			}
+			if ((count & 0x01) == 0)
+				instr.format1.parity = 1;
+		} else {
+			/* Compress the instruction for older sequencers */
+			if (fmt3_ins != NULL) {
+				instr.integer =
+					fmt3_ins->immediate
+				      | (fmt3_ins->source << 8)
+				      | (fmt3_ins->address << 16)
+				      |	(fmt3_ins->opcode << 25);
+			} else {
+				instr.integer =
+					fmt1_ins->immediate
+				      | (fmt1_ins->source << 8)
+				      | (fmt1_ins->destination << 16)
+				      |	(fmt1_ins->ret << 24)
+				      |	(fmt1_ins->opcode << 25);
+			}
+		}
+		/* The sequencer is a little endian cpu */
+		instr.integer = ahc_htole32(instr.integer);
+		ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
+		break;
+	default:
+		panic("Unknown opcode encountered in seq program");
+		break;
+	}
+}
+
+void
+ahc_dump_card_state(struct ahc_softc *ahc)
+{
+	struct scb *scb;
+	struct scb_tailq *untagged_q;
+	int target;
+	int maxtarget;
+	int i;
+	uint8_t last_phase;
+	uint8_t qinpos;
+	uint8_t qintail;
+	uint8_t qoutpos;
+	uint8_t scb_index;
+	uint8_t saved_scbptr;
+
+	saved_scbptr = ahc_inb(ahc, SCBPTR);
+
+	last_phase = ahc_inb(ahc, LASTPHASE);
+	printf("%s: Dumping Card State %s, at SEQADDR 0x%x\n",
+	       ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
+	       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
+	printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
+	       ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
+	       ahc_inb(ahc, ARG_2));
+	printf("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),
+	       ahc_inb(ahc, SCBPTR));
+	printf("SCSISEQ = 0x%x, SBLKCTL = 0x%x\n",
+	       ahc_inb(ahc, SCSISEQ), ahc_inb(ahc, SBLKCTL));
+	printf(" DFCNTRL = 0x%x, DFSTATUS = 0x%x\n",
+	       ahc_inb(ahc, DFCNTRL), ahc_inb(ahc, DFSTATUS));
+	printf("LASTPHASE = 0x%x, SCSISIGI = 0x%x, SXFRCTL0 = 0x%x\n",
+	       last_phase, ahc_inb(ahc, SCSISIGI), ahc_inb(ahc, SXFRCTL0));
+	printf("SSTAT0 = 0x%x, SSTAT1 = 0x%x\n",
+	       ahc_inb(ahc, SSTAT0), ahc_inb(ahc, SSTAT1));
+	if ((ahc->features & AHC_DT) != 0)
+		printf("SCSIPHASE = 0x%x\n", ahc_inb(ahc, SCSIPHASE));
+	printf("STACK == 0x%x, 0x%x, 0x%x, 0x%x\n",
+		ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
+		ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
+		ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
+		ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8));
+	printf("SCB count = %d\n", ahc->scb_data->numscbs);
+	printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
+	printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
+	/* QINFIFO */
+	printf("QINFIFO entries: ");
+	if ((ahc->features & AHC_QUEUE_REGS) != 0) {
+		qinpos = ahc_inb(ahc, SNSCB_QOFF);
+		ahc_outb(ahc, SNSCB_QOFF, qinpos);
+	} else
+		qinpos = ahc_inb(ahc, QINPOS);
+	qintail = ahc->qinfifonext;
+	while (qinpos != qintail) {
+		printf("%d ", ahc->qinfifo[qinpos]);
+		qinpos++;
+	}
+	printf("\n");
+
+	printf("Waiting Queue entries: ");
+	scb_index = ahc_inb(ahc, WAITING_SCBH);
+	i = 0;
+	while (scb_index != SCB_LIST_NULL && i++ < 256) {
+		ahc_outb(ahc, SCBPTR, scb_index);
+		printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
+		scb_index = ahc_inb(ahc, SCB_NEXT);
+	}
+	printf("\n");
+
+	printf("Disconnected Queue entries: ");
+	scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);
+	i = 0;
+	while (scb_index != SCB_LIST_NULL && i++ < 256) {
+		ahc_outb(ahc, SCBPTR, scb_index);
+		printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
+		scb_index = ahc_inb(ahc, SCB_NEXT);
+	}
+	printf("\n");
+		
+	ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
+	printf("QOUTFIFO entries: ");
+	qoutpos = ahc->qoutfifonext;
+	i = 0;
+	while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {
+		printf("%d ", ahc->qoutfifo[qoutpos]);
+		qoutpos++;
+	}
+	printf("\n");
+
+	printf("Sequencer Free SCB List: ");
+	scb_index = ahc_inb(ahc, FREE_SCBH);
+	i = 0;
+	while (scb_index != SCB_LIST_NULL && i++ < 256) {
+		ahc_outb(ahc, SCBPTR, scb_index);
+		printf("%d ", scb_index);
+		scb_index = ahc_inb(ahc, SCB_NEXT);
+	}
+	printf("\n");
+
+	printf("Sequencer SCB Info: ");
+	for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
+		ahc_outb(ahc, SCBPTR, i);
+		printf("%d(c 0x%x, s 0x%x, l %d, t 0x%x) ",
+		       i, ahc_inb(ahc, SCB_CONTROL),
+		       ahc_inb(ahc, SCB_SCSIID),
+		       ahc_inb(ahc, SCB_LUN),
+		       ahc_inb(ahc, SCB_TAG));
+	}
+	printf("\n");
+
+	printf("Pending list: ");
+	i = 0;
+	LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
+		if (i++ > 256)
+			break;
+		if (scb != LIST_FIRST(&ahc->pending_scbs))
+			printf(", ");
+		printf("%d(c 0x%x, s 0x%x, l %d)", scb->hscb->tag,
+		       scb->hscb->control, scb->hscb->scsiid, scb->hscb->lun);
+		if ((ahc->flags & AHC_PAGESCBS) == 0) {
+			ahc_outb(ahc, SCBPTR, scb->hscb->tag);
+			printf("(0x%x, 0x%x)", ahc_inb(ahc, SCB_CONTROL),
+			       ahc_inb(ahc, SCB_TAG));
+		}
+	}
+	printf("\n");
+
+	printf("Kernel Free SCB list: ");
+	i = 0;
+	SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
+		if (i++ > 256)
+			break;
+		printf("%d ", scb->hscb->tag);
+	}
+	printf("\n");
+
+	maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
+	for (target = 0; target <= maxtarget; target++) {
+		untagged_q = &ahc->untagged_queues[target];
+		if (TAILQ_FIRST(untagged_q) == NULL)
+			continue;
+		printf("Untagged Q(%d): ", target);
+		i = 0;
+		TAILQ_FOREACH(scb, untagged_q, links.tqe) {
+			if (i++ > 256)
+				break;
+			printf("%d ", scb->hscb->tag);
+		}
+		printf("\n");
+	}
+
+	ahc_platform_dump_card_state(ahc);
+	ahc_outb(ahc, SCBPTR, saved_scbptr);
+}
+
+/************************* Target Mode ****************************************/
+#ifdef AHC_TARGET_MODE
+cam_status
+ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,
+		    struct ahc_tmode_tstate **tstate,
+		    struct ahc_tmode_lstate **lstate,
+		    int notfound_failure)
+{
+
+	if ((ahc->features & AHC_TARGETMODE) == 0)
+		return (CAM_REQ_INVALID);
+
+	/*
+	 * Handle the 'black hole' device that sucks up
+	 * requests to unattached luns on enabled targets.
+	 */
+	if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
+	 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
+		*tstate = NULL;
+		*lstate = ahc->black_hole;
+	} else {
+		u_int max_id;
+
+		max_id = (ahc->features & AHC_WIDE) ? 15 : 7;
+		if (ccb->ccb_h.target_id > max_id)
+			return (CAM_TID_INVALID);
+
+		if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)
+			return (CAM_LUN_INVALID);
+
+		*tstate = ahc->enabled_targets[ccb->ccb_h.target_id];
+		*lstate = NULL;
+		if (*tstate != NULL)
+			*lstate =
+			    (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
+	}
+
+	if (notfound_failure != 0 && *lstate == NULL)
+		return (CAM_PATH_INVALID);
+
+	return (CAM_REQ_CMP);
+}
+
+void
+ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
+{
+	struct	   ahc_tmode_tstate *tstate;
+	struct	   ahc_tmode_lstate *lstate;
+	struct	   ccb_en_lun *cel;
+	cam_status status;
+	u_int	   target;
+	u_int	   lun;
+	u_int	   target_mask;
+	u_long	   s;
+	char	   channel;
+
+	status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate,
+				     /*notfound_failure*/FALSE);
+
+	if (status != CAM_REQ_CMP) {
+		ccb->ccb_h.status = status;
+		return;
+	}
+
+	if ((ahc->features & AHC_MULTIROLE) != 0) {
+		u_int	   our_id;
+
+		if (cam_sim_bus(sim) == 0)
+			our_id = ahc->our_id;
+		else
+			our_id = ahc->our_id_b;
+
+		if (ccb->ccb_h.target_id != our_id) {
+			if ((ahc->features & AHC_MULTI_TID) != 0
+		   	 && (ahc->flags & AHC_INITIATORROLE) != 0) {
+				/*
+				 * Only allow additional targets if
+				 * the initiator role is disabled.
+				 * The hardware cannot handle a re-select-in
+				 * on the initiator id during a re-select-out
+				 * on a different target id.
+				 */
+				status = CAM_TID_INVALID;
+			} else if ((ahc->flags & AHC_INITIATORROLE) != 0
+				|| ahc->enabled_luns > 0) {
+				/*
+				 * Only allow our target id to change
+				 * if the initiator role is not configured
+				 * and there are no enabled luns which
+				 * are attached to the currently registered
+				 * scsi id.
+				 */
+				status = CAM_TID_INVALID;
+			}
+		}
+	}
+
+	if (status != CAM_REQ_CMP) {
+		ccb->ccb_h.status = status;
+		return;
+	}
+
+	/*
+	 * We now have an id that is valid.
+	 * If we aren't in target mode, switch modes.
+	 */
+	if ((ahc->flags & AHC_TARGETROLE) == 0
+	 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
+		u_long	s;
+
+		printf("Configuring Target Mode\n");
+		ahc_lock(ahc, &s);
+		if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
+			ccb->ccb_h.status = CAM_BUSY;
+			ahc_unlock(ahc, &s);
+			return;
+		}
+		ahc->flags |= AHC_TARGETROLE;
+		if ((ahc->features & AHC_MULTIROLE) == 0)
+			ahc->flags &= ~AHC_INITIATORROLE;
+		ahc_pause(ahc);
+		ahc_loadseq(ahc);
+		ahc_unlock(ahc, &s);
+	}
+	cel = &ccb->cel;
+	target = ccb->ccb_h.target_id;
+	lun = ccb->ccb_h.target_lun;
+	channel = SIM_CHANNEL(ahc, sim);
+	target_mask = 0x01 << target;
+	if (channel == 'B')
+		target_mask <<= 8;
+
+	if (cel->enable != 0) {
+		u_int scsiseq;
+
+		/* Are we already enabled?? */
+		if (lstate != NULL) {
+			xpt_print_path(ccb->ccb_h.path);
+			printf("Lun already enabled\n");
+			ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
+			return;
+		}
+
+		if (cel->grp6_len != 0
+		 || cel->grp7_len != 0) {
+			/*
+			 * Don't (yet?) support vendor
+			 * specific commands.
+			 */
+			ccb->ccb_h.status = CAM_REQ_INVALID;
+			printf("Non-zero Group Codes\n");
+			return;
+		}
+
+		/*
+		 * Seems to be okay.
+		 * Setup our data structures.
+		 */
+		if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
+			tstate = ahc_alloc_tstate(ahc, target, channel);
+			if (tstate == NULL) {
+				xpt_print_path(ccb->ccb_h.path);
+				printf("Couldn't allocate tstate\n");
+				ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+				return;
+			}
+		}
+		lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
+		if (lstate == NULL) {
+			xpt_print_path(ccb->ccb_h.path);
+			printf("Couldn't allocate lstate\n");
+			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+			return;
+		}
+		memset(lstate, 0, sizeof(*lstate));
+		status = xpt_create_path(&lstate->path, /*periph*/NULL,
+					 xpt_path_path_id(ccb->ccb_h.path),
+					 xpt_path_target_id(ccb->ccb_h.path),
+					 xpt_path_lun_id(ccb->ccb_h.path));
+		if (status != CAM_REQ_CMP) {
+			free(lstate, M_DEVBUF);
+			xpt_print_path(ccb->ccb_h.path);
+			printf("Couldn't allocate path\n");
+			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+			return;
+		}
+		SLIST_INIT(&lstate->accept_tios);
+		SLIST_INIT(&lstate->immed_notifies);
+		ahc_lock(ahc, &s);
+		ahc_pause(ahc);
+		if (target != CAM_TARGET_WILDCARD) {
+			tstate->enabled_luns[lun] = lstate;
+			ahc->enabled_luns++;
+
+			if ((ahc->features & AHC_MULTI_TID) != 0) {
+				u_int targid_mask;
+
+				targid_mask = ahc_inb(ahc, TARGID)
+					    | (ahc_inb(ahc, TARGID + 1) << 8);
+
+				targid_mask |= target_mask;
+				ahc_outb(ahc, TARGID, targid_mask);
+				ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
+				
+				ahc_update_scsiid(ahc, targid_mask);
+			} else {
+				u_int our_id;
+				char  channel;
+
+				channel = SIM_CHANNEL(ahc, sim);
+				our_id = SIM_SCSI_ID(ahc, sim);
+
+				/*
+				 * This can only happen if selections
+				 * are not enabled
+				 */
+				if (target != our_id) {
+					u_int sblkctl;
+					char  cur_channel;
+					int   swap;
+
+					sblkctl = ahc_inb(ahc, SBLKCTL);
+					cur_channel = (sblkctl & SELBUSB)
+						    ? 'B' : 'A';
+					if ((ahc->features & AHC_TWIN) == 0)
+						cur_channel = 'A';
+					swap = cur_channel != channel;
+					if (channel == 'A')
+						ahc->our_id = target;
+					else
+						ahc->our_id_b = target;
+
+					if (swap)
+						ahc_outb(ahc, SBLKCTL,
+							 sblkctl ^ SELBUSB);
+
+					ahc_outb(ahc, SCSIID, target);
+
+					if (swap)
+						ahc_outb(ahc, SBLKCTL, sblkctl);
+				}
+			}
+		} else
+			ahc->black_hole = lstate;
+		/* Allow select-in operations */
+		if (ahc->black_hole != NULL && ahc->enabled_luns > 0) {
+			scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
+			scsiseq |= ENSELI;
+			ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
+			scsiseq = ahc_inb(ahc, SCSISEQ);
+			scsiseq |= ENSELI;
+			ahc_outb(ahc, SCSISEQ, scsiseq);
+		}
+		ahc_unpause(ahc);
+		ahc_unlock(ahc, &s);
+		ccb->ccb_h.status = CAM_REQ_CMP;
+		xpt_print_path(ccb->ccb_h.path);
+		printf("Lun now enabled for target mode\n");
+	} else {
+		struct scb *scb;
+		int i, empty;
+
+		if (lstate == NULL) {
+			ccb->ccb_h.status = CAM_LUN_INVALID;
+			return;
+		}
+
+		ahc_lock(ahc, &s);
+		
+		ccb->ccb_h.status = CAM_REQ_CMP;
+		LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
+			struct ccb_hdr *ccbh;
+
+			ccbh = &scb->io_ctx->ccb_h;
+			if (ccbh->func_code == XPT_CONT_TARGET_IO
+			 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
+				printf("CTIO pending\n");
+				ccb->ccb_h.status = CAM_REQ_INVALID;
+				ahc_unlock(ahc, &s);
+				return;
+			}
+		}
+
+		if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
+			printf("ATIOs pending\n");
+			ccb->ccb_h.status = CAM_REQ_INVALID;
+		}
+
+		if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
+			printf("INOTs pending\n");
+			ccb->ccb_h.status = CAM_REQ_INVALID;
+		}
+
+		if (ccb->ccb_h.status != CAM_REQ_CMP) {
+			ahc_unlock(ahc, &s);
+			return;
+		}
+
+		xpt_print_path(ccb->ccb_h.path);
+		printf("Target mode disabled\n");
+		xpt_free_path(lstate->path);
+		free(lstate, M_DEVBUF);
+
+		ahc_pause(ahc);
+		/* Can we clean up the target too? */
+		if (target != CAM_TARGET_WILDCARD) {
+			tstate->enabled_luns[lun] = NULL;
+			ahc->enabled_luns--;
+			for (empty = 1, i = 0; i < 8; i++)
+				if (tstate->enabled_luns[i] != NULL) {
+					empty = 0;
+					break;
+				}
+
+			if (empty) {
+				ahc_free_tstate(ahc, target, channel,
+						/*force*/FALSE);
+				if (ahc->features & AHC_MULTI_TID) {
+					u_int targid_mask;
+
+					targid_mask = ahc_inb(ahc, TARGID)
+						    | (ahc_inb(ahc, TARGID + 1)
+						       << 8);
+
+					targid_mask &= ~target_mask;
+					ahc_outb(ahc, TARGID, targid_mask);
+					ahc_outb(ahc, TARGID+1,
+					 	 (targid_mask >> 8));
+					ahc_update_scsiid(ahc, targid_mask);
+				}
+			}
+		} else {
+
+			ahc->black_hole = NULL;
+
+			/*
+			 * We can't allow selections without
+			 * our black hole device.
+			 */
+			empty = TRUE;
+		}
+		if (ahc->enabled_luns == 0) {
+			/* Disallow select-in */
+			u_int scsiseq;
+
+			scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
+			scsiseq &= ~ENSELI;
+			ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
+			scsiseq = ahc_inb(ahc, SCSISEQ);
+			scsiseq &= ~ENSELI;
+			ahc_outb(ahc, SCSISEQ, scsiseq);
+
+			if ((ahc->features & AHC_MULTIROLE) == 0) {
+				printf("Configuring Initiator Mode\n");
+				ahc->flags &= ~AHC_TARGETROLE;
+				ahc->flags |= AHC_INITIATORROLE;
+				ahc_pause(ahc);
+				ahc_loadseq(ahc);
+			}
+		}
+		ahc_unpause(ahc);
+		ahc_unlock(ahc, &s);
+	}
+}
+
+static void
+ahc_update_scsiid(struct ahc_softc *ahc, u_int targid_mask)
+{
+	u_int scsiid_mask;
+	u_int scsiid;
+
+	if ((ahc->features & AHC_MULTI_TID) == 0)
+		panic("ahc_update_scsiid called on non-multitid unit\n");
+
+	/*
+	 * Since we will rely on the the TARGID mask
+	 * for selection enables, ensure that OID
+	 * in SCSIID is not set to some other ID
+	 * that we don't want to allow selections on.
+	 */
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		scsiid = ahc_inb(ahc, SCSIID_ULTRA2);
+	else
+		scsiid = ahc_inb(ahc, SCSIID);
+	scsiid_mask = 0x1 << (scsiid & OID);
+	if ((targid_mask & scsiid_mask) == 0) {
+		u_int our_id;
+
+		/* ffs counts from 1 */
+		our_id = ffs(targid_mask);
+		if (our_id == 0)
+			our_id = ahc->our_id;
+		else
+			our_id--;
+		scsiid &= TID;
+		scsiid |= our_id;
+	}
+	if ((ahc->features & AHC_ULTRA2) != 0)
+		ahc_outb(ahc, SCSIID_ULTRA2, scsiid);
+	else
+		ahc_outb(ahc, SCSIID, scsiid);
+}
+
+void
+ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)
+{
+	struct target_cmd *cmd;
+
+	/*
+	 * If the card supports auto-access pause,
+	 * we can access the card directly regardless
+	 * of whether it is paused or not.
+	 */
+	if ((ahc->features & AHC_AUTOPAUSE) != 0)
+		paused = TRUE;
+
+	ahc_sync_tqinfifo(ahc, BUS_DMASYNC_POSTREAD);
+	while ((cmd = &ahc->targetcmds[ahc->tqinfifonext])->cmd_valid != 0) {
+
+		/*
+		 * Only advance through the queue if we
+		 * have the resources to process the command.
+		 */
+		if (ahc_handle_target_cmd(ahc, cmd) != 0)
+			break;
+
+		cmd->cmd_valid = 0;
+		ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
+				ahc->shared_data_dmamap,
+				ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
+				sizeof(struct target_cmd),
+				BUS_DMASYNC_PREREAD);
+		ahc->tqinfifonext++;
+
+		/*
+		 * Lazily update our position in the target mode incoming
+		 * command queue as seen by the sequencer.
+		 */
+		if ((ahc->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
+			if ((ahc->features & AHC_HS_MAILBOX) != 0) {
+				u_int hs_mailbox;
+
+				hs_mailbox = ahc_inb(ahc, HS_MAILBOX);
+				hs_mailbox &= ~HOST_TQINPOS;
+				hs_mailbox |= ahc->tqinfifonext & HOST_TQINPOS;
+				ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
+			} else {
+				if (!paused)
+					ahc_pause(ahc);	
+				ahc_outb(ahc, KERNEL_TQINPOS,
+					 ahc->tqinfifonext & HOST_TQINPOS);
+				if (!paused)
+					ahc_unpause(ahc);
+			}
+		}
+	}
+}
+
+static int
+ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
+{
+	struct	  ahc_tmode_tstate *tstate;
+	struct	  ahc_tmode_lstate *lstate;
+	struct	  ccb_accept_tio *atio;
+	uint8_t *byte;
+	int	  initiator;
+	int	  target;
+	int	  lun;
+
+	initiator = SCSIID_TARGET(ahc, cmd->scsiid);
+	target = SCSIID_OUR_ID(cmd->scsiid);
+	lun    = (cmd->identify & MSG_IDENTIFY_LUNMASK);
+
+	byte = cmd->bytes;
+	tstate = ahc->enabled_targets[target];
+	lstate = NULL;
+	if (tstate != NULL)
+		lstate = tstate->enabled_luns[lun];
+
+	/*
+	 * Commands for disabled luns go to the black hole driver.
+	 */
+	if (lstate == NULL)
+		lstate = ahc->black_hole;
+
+	atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
+	if (atio == NULL) {
+		ahc->flags |= AHC_TQINFIFO_BLOCKED;
+		/*
+		 * Wait for more ATIOs from the peripheral driver for this lun.
+		 */
+		if (bootverbose)
+			printf("%s: ATIOs exhausted\n", ahc_name(ahc));
+		return (1);
+	} else
+		ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
+#if 0
+	printf("Incoming command from %d for %d:%d%s\n",
+	       initiator, target, lun,
+	       lstate == ahc->black_hole ? "(Black Holed)" : "");
+#endif
+	SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
+
+	if (lstate == ahc->black_hole) {
+		/* Fill in the wildcards */
+		atio->ccb_h.target_id = target;
+		atio->ccb_h.target_lun = lun;
+	}
+
+	/*
+	 * Package it up and send it off to
+	 * whomever has this lun enabled.
+	 */
+	atio->sense_len = 0;
+	atio->init_id = initiator;
+	if (byte[0] != 0xFF) {
+		/* Tag was included */
+		atio->tag_action = *byte++;
+		atio->tag_id = *byte++;
+		atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
+	} else {
+		atio->ccb_h.flags = 0;
+	}
+	byte++;
+
+	/* Okay.  Now determine the cdb size based on the command code */
+	switch (*byte >> CMD_GROUP_CODE_SHIFT) {
+	case 0:
+		atio->cdb_len = 6;
+		break;
+	case 1:
+	case 2:
+		atio->cdb_len = 10;
+		break;
+	case 4:
+		atio->cdb_len = 16;
+		break;
+	case 5:
+		atio->cdb_len = 12;
+		break;
+	case 3:
+	default:
+		/* Only copy the opcode. */
+		atio->cdb_len = 1;
+		printf("Reserved or VU command code type encountered\n");
+		break;
+	}
+	
+	memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
+
+	atio->ccb_h.status |= CAM_CDB_RECVD;
+
+	if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
+		/*
+		 * We weren't allowed to disconnect.
+		 * We're hanging on the bus until a
+		 * continue target I/O comes in response
+		 * to this accept tio.
+		 */
+#if 0
+		printf("Received Immediate Command %d:%d:%d - %p\n",
+		       initiator, target, lun, ahc->pending_device);
+#endif
+		ahc->pending_device = lstate;
+		ahc_freeze_ccb((union ccb *)atio);
+		atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
+	}
+	xpt_done((union ccb*)atio);
+	return (0);
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_host.h linux/drivers/scsi/aic7xxx/aic7xxx_host.h
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_host.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_host.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,95 @@
+/*
+ * Adaptec AIC7xxx device driver host template for Linux.
+ *
+ * Copyright (c) 2000-2001 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#9 $
+ */
+
+#ifndef _AIC7XXX_HOST_H_
+#define _AIC7XXX_HOST_H_
+
+int		 ahc_linux_proc_info(char *, char **, off_t, int, int, int);
+int		 ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+int		 ahc_linux_detect(Scsi_Host_Template *);
+int		 ahc_linux_release(struct Scsi_Host *);
+const char	*ahc_linux_info(struct Scsi_Host *);
+int		 ahc_linux_biosparam(Disk *, kdev_t, int[]);
+int		 ahc_linux_bus_reset(Scsi_Cmnd *);
+int		 ahc_linux_dev_reset(Scsi_Cmnd *);
+int		 ahc_linux_abort(Scsi_Cmnd *);
+
+#if defined(__i386__)
+#  define AIC7XXX_BIOSPARAM ahc_linux_biosparam
+#else
+#  define AIC7XXX_BIOSPARAM NULL
+#endif
+
+/*
+ * Scsi_Host_Template (see hosts.h) for AIC-7xxx - some fields
+ * to do with card config are filled in after the card is detected.
+ */
+#define AIC7XXX	{						\
+	next: NULL,						\
+	module: NULL,						\
+	proc_dir: NULL,						\
+	proc_info: ahc_linux_proc_info,				\
+	name: NULL,						\
+	detect: ahc_linux_detect,				\
+	release: ahc_linux_release,				\
+	info: ahc_linux_info,					\
+	command: NULL,						\
+	queuecommand: ahc_linux_queue,				\
+	eh_strategy_handler: NULL,				\
+	eh_abort_handler: ahc_linux_abort,			\
+	eh_device_reset_handler: ahc_linux_dev_reset,		\
+	eh_bus_reset_handler: ahc_linux_bus_reset,		\
+	eh_host_reset_handler: NULL,				\
+	abort: NULL,						\
+	reset: NULL,						\
+	slave_attach: NULL,					\
+	bios_param: AIC7XXX_BIOSPARAM,				\
+	can_queue: AHC_MAX_QUEUE,/* max simultaneous cmds     */\
+	this_id: -1,		 /* scsi id of host adapter   */\
+	sg_tablesize: AHC_NSEG,	 /* max scatter-gather cmds   */\
+	cmd_per_lun: 2,		 /* cmds per lun	      */\
+	present: 0,		 /* number of 7xxx's present  */\
+	unchecked_isa_dma: 0,	 /* no memory DMA restrictions*/\
+	use_clustering: ENABLE_CLUSTERING,			\
+	use_new_eh_code: 1					\
+}
+
+#endif /* _AIC7XXX_HOST_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_inline.h linux/drivers/scsi/aic7xxx/aic7xxx_inline.h
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_inline.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_inline.h	2002-07-20 01:08:36.000000000 +0000
@@ -37,9 +37,9 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#31 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#35 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_inline.h,v 1.8 2000/11/12 05:19:46 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_inline.h,v 1.2.2.11 2002/04/29 19:36:31 gibbs Exp $
  */
 
 #ifndef _AIC7XXX_INLINE_H_
@@ -231,7 +231,8 @@
 
 /*********************** Miscelaneous Support Functions ***********************/
 
-static __inline void	ahc_update_residual(struct scb *scb);
+static __inline void	ahc_update_residual(struct ahc_softc *ahc,
+					    struct scb *scb);
 static __inline struct ahc_initiator_tinfo *
 			ahc_fetch_transinfo(struct ahc_softc *ahc,
 					    char channel, u_int our_id,
@@ -255,13 +256,13 @@
  * for this SCB/transaction.
  */
 static __inline void
-ahc_update_residual(struct scb *scb)
+ahc_update_residual(struct ahc_softc *ahc, struct scb *scb)
 {
 	uint32_t sgptr;
 
 	sgptr = ahc_le32toh(scb->hscb->sgptr);
 	if ((sgptr & SG_RESID_VALID) != 0)
-		ahc_calc_residual(scb);
+		ahc_calc_residual(ahc, scb);
 }
 
 /*
@@ -357,8 +358,8 @@
 	memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
 	if ((scb->flags & SCB_CDB32_PTR) != 0) {
 		q_hscb->shared_data.cdb_ptr =
-		    ahc_hscb_busaddr(ahc, q_hscb->tag)
-		  + offsetof(struct hardware_scb, cdb32);	
+		    ahc_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag)
+			      + offsetof(struct hardware_scb, cdb32));
 	}
 	q_hscb->tag = saved_tag;
 	q_hscb->next = scb->hscb->tag;
@@ -471,7 +472,8 @@
 	if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL)
 		retval |= AHC_RUN_QOUTFIFO;
 #ifdef AHC_TARGET_MODE
-	if ((ahc->flags & AHC_TARGETROLE) != 0) {
+	if ((ahc->flags & AHC_TARGETROLE) != 0
+	 && (ahc->flags & AHC_TQINFIFO_BLOCKED) == 0) {
 		ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
 				ahc->shared_data_dmamap,
 				ahc_targetcmd_offset(ahc, ahc->tqinfifofnext),
@@ -517,10 +519,7 @@
 		 * and asserted the interrupt again.
 		 */
 		ahc_flush_device_writes(ahc);
-#ifdef AHC_TARGET_MODE
-		if ((ahc->flags & AHC_INITIATORROLE) != 0)
-#endif
-			ahc_run_qoutfifo(ahc);
+		ahc_run_qoutfifo(ahc);
 #ifdef AHC_TARGET_MODE
 		if ((ahc->flags & AHC_TARGETROLE) != 0)
 			ahc_run_tqinfifo(ahc, /*paused*/FALSE);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_linux.c linux/drivers/scsi/aic7xxx/aic7xxx_linux.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_linux.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_linux.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,2843 +0,0 @@
-/*
- * Adaptec AIC7xxx device driver for Linux.
- *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_linux.c#79 $
- *
- * Copyright (c) 1994 John Aycock
- *   The University of Calgary Department of Computer Science.
- *
- * 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, 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; see the file COPYING.  If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F
- * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA
- * config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide,
- * the Linux Kernel Hacker's Guide, Writing a SCSI Device Driver for Linux,
- * the Adaptec 1542 driver (aha1542.c), the Adaptec EISA overlay file
- * (adp7770.ovl), the Adaptec AHA-2740 Series Technical Reference Manual,
- * the Adaptec AIC-7770 Data Book, the ANSI SCSI specification, the
- * ANSI SCSI-2 specification (draft 10c), ...
- *
- * --------------------------------------------------------------------------
- *
- *  Modifications by Daniel M. Eischen (deischen@iworks.InterWorks.org):
- *
- *  Substantially modified to include support for wide and twin bus
- *  adapters, DMAing of SCBs, tagged queueing, IRQ sharing, bug fixes,
- *  SCB paging, and other rework of the code.
- *
- * --------------------------------------------------------------------------
- * Copyright (c) 1994-2000 Justin T. Gibbs.
- * Copyright (c) 2000-2001 Adaptec Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon
- *    including a substantially similar Disclaimer requirement for further
- *    binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- *
- *---------------------------------------------------------------------------
- *
- *  Thanks also go to (in alphabetical order) the following:
- *
- *    Rory Bolt     - Sequencer bug fixes
- *    Jay Estabrook - Initial DEC Alpha support
- *    Doug Ledford  - Much needed abort/reset bug fixes
- *    Kai Makisara  - DMAing of SCBs
- *
- *  A Boot time option was also added for not resetting the scsi bus.
- *
- *    Form:  aic7xxx=extended
- *           aic7xxx=no_reset
- *           aic7xxx=verbose
- *
- *  Daniel M. Eischen, deischen@iworks.InterWorks.org, 1/23/97
- *
- *  Id: aic7xxx.c,v 4.1 1997/06/12 08:23:42 deang Exp
- */
-
-/*
- * Further driver modifications made by Doug Ledford <dledford@redhat.com>
- *
- * Copyright (c) 1997-1999 Doug Ledford
- *
- * These changes are released under the same licensing terms as the FreeBSD
- * driver written by Justin Gibbs.  Please see his Copyright notice above
- * for the exact terms and conditions covering my changes as well as the
- * warranty statement.
- *
- * Modifications made to the aic7xxx.c,v 4.1 driver from Dan Eischen include
- * but are not limited to:
- *
- *  1: Import of the latest FreeBSD sequencer code for this driver
- *  2: Modification of kernel code to accomodate different sequencer semantics
- *  3: Extensive changes throughout kernel portion of driver to improve
- *     abort/reset processing and error hanndling
- *  4: Other work contributed by various people on the Internet
- *  5: Changes to printk information and verbosity selection code
- *  6: General reliability related changes, especially in IRQ management
- *  7: Modifications to the default probe/attach order for supported cards
- *  8: SMP friendliness has been improved
- *
- */
-
-#include "aic7xxx_osm.h"
-#include "aic7xxx_inline.h"
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-#include <linux/init.h>		/* __setup */
-#endif
-
-#include "../sd.h"		/* For geometry detection */
-
-#include <linux/mm.h>		/* For fetching system memory size */
-#include <linux/blk.h>
-
-/*
- * To generate the correct addresses for the controller to issue
- * on the bus.  Originally added for DEC Alpha support.
- */
-#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a))
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-struct proc_dir_entry proc_scsi_aic7xxx = {
-	PROC_SCSI_AIC7XXX, 7, "aic7xxx",
-	S_IFDIR | S_IRUGO | S_IXUGO, 2,
-	0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-#endif
-
-/*
- * Set this to the delay in seconds after SCSI bus reset.
- * Note, we honor this only for the initial bus reset.
- * The scsi error recovery code performs its own bus settle
- * delay handling for error recovery actions.
- */
-#ifdef CONFIG_AIC7XXX_RESET_DELAY_MS
-#define AIC7XXX_RESET_DELAY CONFIG_AIC7XXX_RESET_DELAY_MS
-#else
-#define AIC7XXX_RESET_DELAY 5000
-#endif
-
-/*
- * Control collection of SCSI transfer statistics for the /proc filesystem.
- *
- * NOTE: Do NOT enable this when running on kernels version 1.2.x and below.
- * NOTE: This does affect performance since it has to maintain statistics.
- */
-#ifdef CONFIG_AIC7XXX_PROC_STATS
-#define AIC7XXX_PROC_STATS
-#endif
-
-/*
- * To change the default number of tagged transactions allowed per-device,
- * add a line to the lilo.conf file like:
- * append="aic7xxx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}"
- * which will result in the first four devices on the first two
- * controllers being set to a tagged queue depth of 32.
- *
- * The tag_commands is an array of 16 to allow for wide and twin adapters.
- * Twin adapters will use indexes 0-7 for channel 0, and indexes 8-15
- * for channel 1.
- */
-typedef struct {
-	uint8_t tag_commands[16];	/* Allow for wide/twin adapters. */
-} adapter_tag_info_t;
-
-/*
- * Modify this as you see fit for your system.
- *
- * 0			tagged queuing disabled
- * 1 <= n <= 253	n == max tags ever dispatched.
- *
- * The driver will throttle the number of commands dispatched to a
- * device if it returns queue full.  For devices with a fixed maximum
- * queue depth, the driver will eventually determine this depth and
- * lock it in (a console message is printed to indicate that a lock
- * has occurred).  On some devices, queue full is returned for a temporary
- * resource shortage.  These devices will return queue full at varying
- * depths.  The driver will throttle back when the queue fulls occur and
- * attempt to slowly increase the depth over time as the device recovers
- * from the resource shortage.
- *
- * In this example, the first line will disable tagged queueing for all
- * the devices on the first probed aic7xxx adapter.
- *
- * The second line enables tagged queueing with 4 commands/LUN for IDs
- * (0, 2-11, 13-15), disables tagged queueing for ID 12, and tells the
- * driver to attempt to use up to 64 tags for ID 1.
- *
- * The third line is the same as the first line.
- *
- * The fourth line disables tagged queueing for devices 0 and 3.  It
- * enables tagged queueing for the other IDs, with 16 commands/LUN
- * for IDs 1 and 4, 127 commands/LUN for ID 8, and 4 commands/LUN for
- * IDs 2, 5-7, and 9-15.
- */
-
-/*
- * NOTE: The below structure is for reference only, the actual structure
- *       to modify in order to change things is just below this comment block.
-adapter_tag_info_t aic7xxx_tag_info[] =
-{
-	{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
-	{{4, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4}},
-	{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
-	{{0, 16, 4, 0, 16, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4}}
-};
-*/
-
-#ifdef CONFIG_AIC7XXX_CMDS_PER_DEVICE
-#define AIC7XXX_CMDS_PER_DEVICE CONFIG_AIC7XXX_CMDS_PER_DEVICE
-#else
-#define AIC7XXX_CMDS_PER_DEVICE AHC_MAX_QUEUE
-#endif
-
-#define AIC7XXX_CONFIGED_TAG_COMMANDS {					\
-	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
-	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
-	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
-	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
-	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
-	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
-	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
-	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE		\
-}
-
-/*
- * By default, use the number of commands specified by
- * the users kernel configuration.
- */
-static adapter_tag_info_t aic7xxx_tag_info[] =
-{
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS},
-	{AIC7XXX_CONFIGED_TAG_COMMANDS}
-};
-
-/*
- * There should be a specific return value for this in scsi.h, but
- * it seems that most drivers ignore it.
- */
-#define DID_UNDERFLOW   DID_ERROR
-
-void
-ahc_print_path(struct ahc_softc *ahc, struct scb *scb)
-{
-	printk("(scsi%d:%c:%d:%d): ",
-	       ahc->platform_data->host->host_no,
-	       scb != NULL ? SCB_GET_CHANNEL(ahc, scb) : 'X',
-	       scb != NULL ? SCB_GET_TARGET(ahc, scb) : -1,
-	       scb != NULL ? SCB_GET_LUN(scb) : -1);
-}
-
-/*
- * XXX - these options apply unilaterally to _all_ 274x/284x/294x
- *       cards in the system.  This should be fixed.  Exceptions to this
- *       rule are noted in the comments.
- */
-
-/*
- * Skip the scsi bus reset.  Non 0 make us skip the reset at startup.  This
- * has no effect on any later resets that might occur due to things like
- * SCSI bus timeouts.
- */
-static uint32_t aic7xxx_no_reset;
-
-/*
- * Certain PCI motherboards will scan PCI devices from highest to lowest,
- * others scan from lowest to highest, and they tend to do all kinds of
- * strange things when they come into contact with PCI bridge chips.  The
- * net result of all this is that the PCI card that is actually used to boot
- * the machine is very hard to detect.  Most motherboards go from lowest
- * PCI slot number to highest, and the first SCSI controller found is the
- * one you boot from.  The only exceptions to this are when a controller
- * has its BIOS disabled.  So, we by default sort all of our SCSI controllers
- * from lowest PCI slot number to highest PCI slot number.  We also force
- * all controllers with their BIOS disabled to the end of the list.  This
- * works on *almost* all computers.  Where it doesn't work, we have this
- * option.  Setting this option to non-0 will reverse the order of the sort
- * to highest first, then lowest, but will still leave cards with their BIOS
- * disabled at the very end.  That should fix everyone up unless there are
- * really strange cirumstances.
- */
-static int aic7xxx_reverse_scan = 0;
-
-/*
- * Should we force EXTENDED translation on a controller.
- *     0 == Use whatever is in the SEEPROM or default to off
- *     1 == Use whatever is in the SEEPROM or default to on
- */
-static uint32_t aic7xxx_extended = 0;
-
-/*
- * PCI bus parity checking of the Adaptec controllers.  This is somewhat
- * dubious at best.  To my knowledge, this option has never actually
- * solved a PCI parity problem, but on certain machines with broken PCI
- * chipset configurations, it can generate tons of false error messages.
- * It's included in the driver for completeness.
- *   0 = Shut off PCI parity check
- *  -1 = Normal polarity pci parity checking
- *   1 = reverse polarity pci parity checking
- *
- * NOTE: you can't actually pass -1 on the lilo prompt.  So, to set this
- * variable to -1 you would actually want to simply pass the variable
- * name without a number.  That will invert the 0 which will result in
- * -1.
- */
-static int aic7xxx_pci_parity = 0;
-
-/*
- * Certain newer motherboards have put new PCI based devices into the
- * IO spaces that used to typically be occupied by VLB or EISA cards.
- * This overlap can cause these newer motherboards to lock up when scanned
- * for older EISA and VLB devices.  Setting this option to non-0 will
- * cause the driver to skip scanning for any VLB or EISA controllers and
- * only support the PCI controllers.  NOTE: this means that if the kernel
- * os compiled with PCI support disabled, then setting this to non-0
- * would result in never finding any devices :)
- */
-int aic7xxx_no_probe;
-
-/*
- * aic7xxx_detect() has been run, so register all device arrivals
- * immediately with the system rather than deferring to the sorted
- * attachment performed by aic7xxx_detect().
- */
-int aic7xxx_detect_complete;
-
-/*
- * So that we can set how long each device is given as a selection timeout.
- * The table of values goes like this:
- *   0 - 256ms
- *   1 - 128ms
- *   2 - 64ms
- *   3 - 32ms
- * We default to 256ms because some older devices need a longer time
- * to respond to initial selection.
- */
-static int aic7xxx_seltime = 0x00;
-
-/*
- * Certain devices do not perform any aging on commands.  Should the
- * device be saturated by commands in one portion of the disk, it is
- * possible for transactions on far away sectors to never be serviced.
- * To handle these devices, we can periodically send an ordered tag to
- * force all outstanding transactions to be serviced prior to a new
- * transaction.
- */
-int aic7xxx_periodic_otag;
-
-/*
- * Module information and settable options.
- */
-#ifdef MODULE
-static char *aic7xxx = NULL;
-/*
- * Just in case someone uses commas to separate items on the insmod
- * command line, we define a dummy buffer here to avoid having insmod
- * write wild stuff into our code segment
- */
-static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";
-
-MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
-MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)
-MODULE_LICENSE("Dual BSD/GPL");
-#endif
-MODULE_PARM(aic7xxx, "s");
-MODULE_PARM_DESC(aic7xxx, "period delimited, options string.
-	verbose			Enable verbose/diagnostic logging
-	no_probe		Disable EISA/VLB controller probing
-	no_reset		Supress initial bus resets
-	extended		Enable extended geometry on all controllers
-	periodic_otag		Send an ordered tagged transaction periodically
-				to prevent tag starvation.  This may be
-				required by some older disk drives/RAID arrays. 
-	reverse_scan		Sort PCI devices highest Bus/Slot to lowest
-	tag_info:<tag_str>	Set per-target tag depth
-	seltime:<int>		Selection Timeout(0/256ms,1/128ms,2/64ms,3/32ms)
-
-	Sample /etc/modules.conf line:
-		Enable verbose logging
-		Disable EISA/VLB probing
-		Set tag depth on Controller 2/Target 2 to 10 tags
-		Shorten the selection timeout to 128ms from its default of 256
-
-	options aic7xxx='\"verbose.no_probe.tag_info:{{}.{}.{..10}}.seltime:1\"'
-");
-#endif
-
-static void ahc_linux_handle_scsi_status(struct ahc_softc *,
-					 struct ahc_linux_device *,
-					 struct scb *);
-static void ahc_linux_filter_command(struct ahc_softc*, Scsi_Cmnd*,
-				     struct scb*);
-static void ahc_linux_sem_timeout(u_long arg);
-static void ahc_linux_freeze_sim_queue(struct ahc_softc *ahc);
-static void ahc_linux_release_sim_queue(u_long arg);
-static int  ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag);
-static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
-static void ahc_linux_select_queue_depth(struct Scsi_Host *host,
-					 Scsi_Device *scsi_devs);
-static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
-					 Scsi_Device *device);
-static struct ahc_linux_target*	ahc_linux_alloc_target(struct ahc_softc*,
-						       u_int, u_int);
-static void			ahc_linux_free_target(struct ahc_softc*,
-						      struct ahc_linux_target*);
-static struct ahc_linux_device*	ahc_linux_alloc_device(struct ahc_softc*,
-						       struct ahc_linux_target*,
-						       u_int);
-static void			ahc_linux_free_device(struct ahc_softc*,
-						      struct ahc_linux_device*);
-static void ahc_linux_run_device_queue(struct ahc_softc*,
-				       struct ahc_linux_device*);
-static void ahc_linux_setup_tag_info(char *p, char *end);
-static int ahc_linux_next_unit(void);
-static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf);
-
-static __inline struct ahc_linux_device*
-		     ahc_linux_get_device(struct ahc_softc *ahc, u_int channel,
-					  u_int target, u_int lun, int alloc);
-static __inline void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
-						  Scsi_Cmnd *cmd);
-static __inline void ahc_linux_run_complete_queue(struct ahc_softc *ahc,
-						  struct ahc_cmd *acmd);
-static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc,
-						  struct ahc_linux_device *dev);
-static __inline void ahc_linux_sniff_command(struct ahc_softc*, Scsi_Cmnd*,
-					     struct scb*);
-static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
-
-static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
-		 		      struct ahc_dma_seg *sg,
-				      bus_addr_t addr, bus_size_t len);
-
-static __inline struct ahc_linux_device*
-ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
-	       u_int lun, int alloc)
-{
-	struct ahc_linux_target *targ;
-	struct ahc_linux_device *dev;
-	u_int target_offset;
-
-	target_offset = target;
-	if (channel != 0)
-		target_offset += 8;
-	targ = ahc->platform_data->targets[target_offset];
-	if (targ == NULL) {
-		if (alloc != 0) {
-			targ = ahc_linux_alloc_target(ahc, channel, target);
-			if (targ == NULL)
-				return (NULL);
-		} else
-			return (NULL);
-	}
-	dev = targ->devices[lun];
-	if (dev == NULL && alloc != 0)
-		dev = ahc_linux_alloc_device(ahc, targ, lun);
-	return (dev);
-}
-
-static __inline void
-ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd)
-{
-	/*
-	 * Typically, the complete queue has very few entries
-	 * queued to it before the queue is emptied by
-	 * ahc_linux_run_complete_queue, so sorting the entries
-	 * by generation number should be inexpensive.
-	 * We perform the sort so that commands that complete
-	 * with an error are retuned in the order origionally
-	 * queued to the controller so that any subsequent retries
-	 * are performed in order.  The underlying ahc routines do
-	 * not guarantee the order that aborted commands will be
-	 * returned to us.
-	 */
-	struct ahc_completeq *completeq;
-	struct ahc_cmd *list_cmd;
-	struct ahc_cmd *acmd;
-
-	/*
-	 * If we want the request requeued, make sure there
-	 * are sufficent retries.  In the old scsi error code,
-	 * we used to be able to specify a result code that
-	 * bypassed the retry count.  Now we must use this
-	 * hack.
-	 */
-	if (cmd->result == (CAM_REQUEUE_REQ << 16))
-		cmd->retries--;
-	completeq = &ahc->platform_data->completeq;
-	list_cmd = TAILQ_FIRST(completeq);
-	acmd = (struct ahc_cmd *)cmd;
-	while (list_cmd != NULL
-	    && acmd_scsi_cmd(list_cmd).serial_number
-	     < acmd_scsi_cmd(acmd).serial_number)
-		list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe);
-	if (list_cmd != NULL)
-		TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe);
-	else
-		TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe);
-}
-
-static __inline void
-ahc_linux_run_complete_queue(struct ahc_softc *ahc, struct ahc_cmd *acmd)
-{	
-	u_long done_flags;
-
-	ahc_done_lock(ahc, &done_flags);
-	while (acmd != NULL) {
-		Scsi_Cmnd *cmd;
-
-		cmd = &acmd_scsi_cmd(acmd);
-		acmd = TAILQ_NEXT(acmd, acmd_links.tqe);
-		cmd->host_scribble = NULL;
-		cmd->scsi_done(cmd);
-	}
-	ahc_done_unlock(ahc, &done_flags);
-}
-
-static __inline void
-ahc_linux_check_device_queue(struct ahc_softc *ahc,
-			     struct ahc_linux_device *dev)
-{
-	if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) != 0
-	 && dev->active == 0) {
-		dev->flags &= ~AHC_DEV_FREEZE_TIL_EMPTY;
-		dev->qfrozen--;
-	}
-
-	if (TAILQ_FIRST(&dev->busyq) == NULL
-	 || dev->openings == 0 || dev->qfrozen != 0)
-		return;
-
-	ahc_linux_run_device_queue(ahc, dev);
-}
-
-static __inline void
-ahc_linux_run_device_queues(struct ahc_softc *ahc)
-{
-	struct ahc_linux_device *dev;
-
-	while ((ahc->flags & AHC_RESOURCE_SHORTAGE) == 0
-	    && ahc->platform_data->qfrozen == 0
-	    && (dev = TAILQ_FIRST(&ahc->platform_data->device_runq)) != NULL) {
-		TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
-		dev->flags &= ~AHC_DEV_ON_RUN_LIST;
-		ahc_linux_check_device_queue(ahc, dev);
-	}
-}
-
-static __inline void
-ahc_linux_sniff_command(struct ahc_softc *ahc, Scsi_Cmnd *cmd, struct scb *scb)
-{
-	/*
-	 * Determine whether we care to filter
-	 * information out of this command.  If so,
-	 * pass it on to ahc_linux_filter_command() for more
-	 * heavy weight processing.
-	 */
-	if (cmd->cmnd[0] == INQUIRY)
-		ahc_linux_filter_command(ahc, cmd, scb);
-}
-
-static __inline void
-ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
-{
-	Scsi_Cmnd *cmd;
-
-	cmd = scb->io_ctx;
-	ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE);
-	if (cmd->use_sg != 0) {
-		struct scatterlist *sg;
-
-		sg = (struct scatterlist *)cmd->request_buffer;
-		pci_unmap_sg(ahc->dev_softc, sg, cmd->use_sg,
-			     scsi_to_pci_dma_dir(cmd->sc_data_direction));
-	} else if (cmd->request_bufflen != 0) {
-		u_int32_t high_addr;
-
-		high_addr = ahc_le32toh(scb->sg_list[0].len)
-			  & AHC_SG_HIGH_ADDR_MASK;
-		pci_unmap_single(ahc->dev_softc,
-				 ahc_le32toh(scb->sg_list[0].addr)
-			        | (((dma_addr_t)high_addr) << 8),
-				 cmd->request_bufflen,
-				 scsi_to_pci_dma_dir(cmd->sc_data_direction));
-	}
-}
-
-static __inline int
-ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
-		  struct ahc_dma_seg *sg, bus_addr_t addr, bus_size_t len)
-{
-	int	 consumed;
-
-	if ((scb->sg_count + 1) > AHC_NSEG)
-		panic("Too few segs for dma mapping.  "
-		      "Increase AHC_NSEG\n");
-
-	consumed = 1;
-	sg->addr = ahc_htole32(addr & 0xFFFFFFFF);
-	scb->platform_data->xfer_len += len;
-	if (sizeof(bus_addr_t) > 4
-	 && (ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
-		/*
-		 * Due to DAC restrictions, we can't
-		 * cross a 4GB boundary.
-		 */
-		if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) {
-			struct	 ahc_dma_seg *next_sg;
-			uint32_t next_len;
-
-			printf("Crossed Seg\n");
-			if ((scb->sg_count + 2) > AHC_NSEG)
-				panic("Too few segs for dma mapping.  "
-				      "Increase AHC_NSEG\n");
-
-			consumed++;
-			next_sg = sg + 1;
-			next_sg->addr = 0;
-			next_len = 0x100000000 - (addr & 0xFFFFFFFF);
-			len -= next_len;
-			next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000;
-			next_sg->len = ahc_htole32(next_len);
-		}
-		len |= (addr >> 8) & 0x7F000000;
-	}
-	sg->len = ahc_htole32(len);
-	return (consumed);
-}
-
-/************************ Shutdown/halt/reboot hook ***************************/
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-
-static struct notifier_block ahc_linux_notifier = {
-	ahc_linux_halt, NULL, 0
-};
-
-static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf)
-{
-	struct ahc_softc *ahc;
-
-	if (event == SYS_DOWN || event == SYS_HALT) {
-		TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-			ahc_shutdown(ahc);
-		}
-	}
-	return (NOTIFY_OK);
-}
-
-/******************************** Macros **************************************/
-#define BUILD_SCSIID(ahc, cmd)						\
-	((((cmd)->target << TID_SHIFT) & TID)				\
-	| (((cmd)->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b)	\
-	| (((cmd)->channel == 0) ? 0 : TWIN_CHNLB))
-
-/******************************** Bus DMA *************************************/
-int
-ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
-		   bus_size_t alignment, bus_size_t boundary,
-		   bus_addr_t lowaddr, bus_addr_t highaddr,
-		   bus_dma_filter_t *filter, void *filterarg,
-		   bus_size_t maxsize, int nsegments,
-		   bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
-{
-	bus_dma_tag_t dmat;
-
-	dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
-	if (dmat == NULL)
-		return (ENOMEM);
-
-	/*
-	 * Linux is very simplistic about DMA memory.  For now don't
-	 * maintain all specification information.  Once Linux supplies
-	 * better facilities for doing these operations, or the
-	 * needs of this particular driver change, we might need to do
-	 * more here.
-	 */
-	dmat->alignment = alignment;
-	dmat->boundary = boundary;
-	dmat->maxsize = maxsize;
-	*ret_tag = dmat;
-	return (0);
-}
-
-void
-ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat)
-{
-	free(dmat, M_DEVBUF);
-}
-
-int
-ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr,
-		 int flags, bus_dmamap_t *mapp)
-{
-	bus_dmamap_t map;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-	map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
-	if (map == NULL)
-		return (ENOMEM);
-	/*
-	 * Although we can dma data above 4GB, our
-	 * "consistent" memory is below 4GB for
-	 * space efficiency reasons (only need a 4byte
-	 * address).  For this reason, we have to reset
-	 * our dma mask when doing allocations.
-	 */
-	if(ahc->dev_softc)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
-		pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF);
-#else
-		ahc->dev_softc->dma_mask = 0xFFFFFFFF;
-#endif
-	*vaddr = pci_alloc_consistent(ahc->dev_softc,
-				      dmat->maxsize, &map->bus_addr);
-	if (ahc->dev_softc)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
-		pci_set_dma_mask(ahc->dev_softc, ahc->platform_data->hw_dma_mask);
-#else
-		ahc->dev_softc->dma_mask = ahc->platform_data->hw_dma_mask;
-#endif
-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */
-	/*
-	 * At least in 2.2.14, malloc is a slab allocator so all
-	 * allocations are aligned.  We assume for these kernel versions
-	 * that all allocations will be bellow 4Gig, physically contiguous,
-	 * and accessable via DMA by the controller.
-	 */
-	map = NULL; /* No additional information to store */
-	*vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT);
-#endif
-	if (*vaddr == NULL)
-		return (ENOMEM);
-	*mapp = map;
-	return(0);
-}
-
-void
-ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat,
-		void* vaddr, bus_dmamap_t map)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-	pci_free_consistent(ahc->dev_softc, dmat->maxsize,
-			    vaddr, map->bus_addr);
-#else
-	free(vaddr, M_DEVBUF);
-#endif
-}
-
-int
-ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
-		void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
-		void *cb_arg, int flags)
-{
-	/*
-	 * Assume for now that this will only be used during
-	 * initialization and not for per-transaction buffer mapping.
-	 */
-	bus_dma_segment_t stack_sg;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-	stack_sg.ds_addr = map->bus_addr;
-#else
-	stack_sg.ds_addr = VIRT_TO_BUS(buf);
-#endif
-	stack_sg.ds_len = dmat->maxsize;
-	cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0);
-	return (0);
-}
-
-void
-ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
-{
-	/*
-	 * The map may is NULL in our < 2.3.X implementation.
-	 */
-	if (map != NULL)
-		free(map, M_DEVBUF);
-}
-
-int
-ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
-{
-	/* Nothing to do */
-	return (0);
-}
-
-/********************* Platform Dependent Functions ***************************/
-int
-ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
-{
-	int	value;
-	int	rvalue;
-	int	lvalue;
-
-	/*
-	 * Under Linux, cards are ordered as follows:
-	 *	1) VLB/EISA BIOS enabled devices sorted by BIOS address.
-	 *	2) PCI devices with BIOS enabled sorted by bus/slot/func.
-	 *	3) All remaining VLB/EISA devices sorted by ioport.
-	 *	4) All remaining PCI devices sorted by bus/slot/func.
-	 */
-	value = (lahc->flags & AHC_BIOS_ENABLED)
-	      - (rahc->flags & AHC_BIOS_ENABLED);
-	if (value != 0)
-		/* Controllers with BIOS enabled have a *higher* priority */
-		return (-value);
-
-	/*
-	 * Same BIOS setting, now sort based on bus type.
-	 * EISA and VL controllers sort together.  EISA/VL
-	 * have higher priority than PCI.
-	 */
-	rvalue = (rahc->chip & AHC_BUS_MASK);
- 	if (rvalue == AHC_VL)
-		rvalue = AHC_EISA;
-	lvalue = (lahc->chip & AHC_BUS_MASK);
- 	if (lvalue == AHC_VL)
-		lvalue = AHC_EISA;
-	value = lvalue - rvalue;
-	if (value != 0)
-		return (value);
-
-	/* Still equal.  Sort by BIOS address, ioport, or bus/slot/func. */
-	switch (rvalue) {
-	case AHC_PCI:
-	{
-		char primary_channel;
-
-		if (aic7xxx_reverse_scan != 0)
-			value = ahc_get_pci_bus(rahc->dev_softc)
-			      - ahc_get_pci_bus(lahc->dev_softc);
-		else
-			value = ahc_get_pci_bus(lahc->dev_softc)
-			      - ahc_get_pci_bus(rahc->dev_softc);
-		if (value != 0)
-			break;
-		if (aic7xxx_reverse_scan != 0)
-			value = ahc_get_pci_slot(rahc->dev_softc)
-			      - ahc_get_pci_slot(lahc->dev_softc);
-		else
-			value = ahc_get_pci_slot(lahc->dev_softc)
-			      - ahc_get_pci_slot(rahc->dev_softc);
-		if (value != 0)
-			break;
-		/*
-		 * On multi-function devices, the user can choose
-		 * to have function 1 probed before function 0.
-		 * Give whichever channel is the primary channel
-		 * the lowest priority.
-		 */
-		primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A';
-		value = 1;
-		if (lahc->channel == primary_channel)
-			value = -1;
-		break;
-	}
-	case AHC_EISA:
-		if ((rahc->flags & AHC_BIOS_ENABLED) != 0) {
-			value = lahc->platform_data->bios_address
-			      - rahc->platform_data->bios_address; 
-		} else {
-			value = lahc->bsh.ioport
-			      - rahc->bsh.ioport; 
-		}
-		break;
-	default:
-		panic("ahc_softc_sort: invalid bus type");
-	}
-	return (value);
-}
-
-static void
-ahc_linux_setup_tag_info(char *p, char *end)
-{
-	char	*base;
-	char	*tok;
-	char	*tok_end;
-	char	*tok_end2;
-	int      i;
-	int      instance;
-	int	 targ;
-	int	 done;
-	char	 tok_list[] = {'.', ',', '{', '}', '\0'};
-
-	if (*p != ':')
-		return;
-
-	instance = -1;
-	targ = -1;
-	done = FALSE;
-	base = p;
-	/* Forward us just past the ':' */
-	tok = base + 1;
-	tok_end = strchr(tok, '\0');
-	if (tok_end < end)
-		*tok_end = ',';
-	while (!done) {
-		switch (*tok) {
-		case '{':
-			if (instance == -1)
-				instance = 0;
-			else if (targ == -1)
-				targ = 0;
-			tok++;
-			break;
-		case '}':
-			if (targ != -1)
-				targ = -1;
-			else if (instance != -1)
-				instance = -1;
-			tok++;
-			break;
-		case ',':
-		case '.':
-			if (instance == -1)
-				done = TRUE;
-			else if (targ >= 0)
-				targ++;
-			else if (instance >= 0)
-				instance++;
-			if ((targ >= AHC_NUM_TARGETS) ||
-			    (instance >= NUM_ELEMENTS(aic7xxx_tag_info)))
-				done = TRUE;
-			tok++;
-			if (!done) {
-				base = tok;
-			}
-			break;
-		case '\0':
-			done = TRUE;
-			break;
-		default:
-			done = TRUE;
-			tok_end = strchr(tok, '\0');
-			for (i = 0; tok_list[i]; i++) {
-				tok_end2 = strchr(tok, tok_list[i]);
-				if ((tok_end2) && (tok_end2 < tok_end)) {
-					tok_end = tok_end2;
-					done = FALSE;
-				}
-			}
-			if ((instance >= 0) && (targ >= 0)
-			 && (instance < NUM_ELEMENTS(aic7xxx_tag_info))
-			 && (targ < AHC_NUM_TARGETS)) {
-				aic7xxx_tag_info[instance].tag_commands[targ] =
-				    simple_strtoul(tok, NULL, 0) & 0xff;
-			}
-			tok = tok_end;
-			break;
-		}
-	}
-	while ((p != base) && (p != NULL))
-		p = strtok(NULL, ",.");
-}
-
-/*
- * Handle Linux boot parameters. This routine allows for assigning a value
- * to a parameter with a ':' between the parameter and the value.
- * ie. aic7xxx=stpwlev:1,extended
- */
-int
-aic7xxx_setup(char *s)
-{
-	int	i, n;
-	char   *p;
-	char   *end;
-
-	static struct {
-		const char *name;
-		uint32_t *flag;
-	} options[] = {
-		{ "extended", &aic7xxx_extended },
-		{ "no_reset", &aic7xxx_no_reset },
-		{ "verbose", &aic7xxx_verbose },
-		{ "reverse_scan", &aic7xxx_reverse_scan },
-		{ "no_probe", &aic7xxx_no_probe },
-		{ "periodic_otag", &aic7xxx_periodic_otag },
-		{ "pci_parity", &aic7xxx_pci_parity },
-		{ "seltime", &aic7xxx_seltime },
-		{ "tag_info", NULL }
-	};
-
-	end = strchr(s, '\0');
-
-	for (p = strtok(s, ",."); p; p = strtok(NULL, ",.")) {
-		for (i = 0; i < NUM_ELEMENTS(options); i++) {
-			n = strlen(options[i].name);
-
-			if (strncmp(options[i].name, p, n) != 0)
-				continue;
-
-			if (strncmp(p, "tag_info", n) == 0) {
-				ahc_linux_setup_tag_info(p + n, end);
-			} else if (p[n] == ':') {
-				*(options[i].flag) =
-				    simple_strtoul(p + n + 1, NULL, 0);
-			} else if (!strncmp(p, "verbose", n)) {
-				*(options[i].flag) = 1;
-			} else {
-				*(options[i].flag) = ~(*(options[i].flag));
-			}
-			break;
-		}
-	}
-	register_reboot_notifier(&ahc_linux_notifier);
-	return 1;
-}
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)
-__setup("aic7xxx=", aic7xxx_setup);
-#endif
-
-int aic7xxx_verbose;
-
-/*
- * Try to detect an Adaptec 7XXX controller.
- */
-int
-ahc_linux_detect(Scsi_Host_Template *template)
-{
-	struct	ahc_softc *ahc;
-	int     found;
-
-	/*
-	 * Sanity checking of Linux SCSI data structures so
-	 * that some of our hacks^H^H^H^H^Hassumptions aren't
-	 * violated.
-	 */
-	if (offsetof(struct ahc_cmd_internal, end)
-	  > offsetof(struct scsi_cmnd, host_scribble)) {
-		printf("ahc_linux_detect: SCSI data structures changed.\n");
-		printf("ahc_linux_detect: Unable to attach\n");
-		return (0);
-	}
-#ifdef MODULE
-	/*
-	 * If we've been passed any parameters, process them now.
-	 */
-	if (aic7xxx)
-		aic7xxx_setup(aic7xxx);
-	if (dummy_buffer[0] != 'P')
-		printk(KERN_WARNING
-"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n"
-"aic7xxx: to see the proper way to specify options to the aic7xxx module\n"
-"aic7xxx: Specifically, don't use any commas when passing arguments to\n"
-"aic7xxx: insmod or else it might trash certain memory areas.\n");
-#endif
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)
-	template->proc_name = "aic7xxx";
-#else
-	template->proc_dir = &proc_scsi_aic7xxx;
-#endif
-	template->sg_tablesize = AHC_NSEG;
-
-#ifdef CONFIG_PCI
-	ahc_linux_pci_probe(template);
-#endif
-
-	if (aic7xxx_no_probe == 0)
-		aic7770_linux_probe(template);
-
-	/*
-	 * Register with the SCSI layer all
-	 * controllers we've found.
-	 */
-	found = 0;
-	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-
-		if (ahc_linux_register_host(ahc, template) == 0)
-			found++;
-	}
-	aic7xxx_detect_complete++;
-	return (found);
-}
-
-int
-ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
-{
-	char  buf[80];
-	struct Scsi_Host *host;
-	char *new_name;
-	u_long s;
-
-
-	template->name = ahc->description;
-	host = scsi_register(template, sizeof(struct ahc_softc *));
-	if (host == NULL)
-		return (ENOMEM);
-
-	ahc_lock(ahc, &s);
-	*((struct ahc_softc **)host->hostdata) = ahc;
-	ahc->platform_data->host = host;
-	host->can_queue = AHC_MAX_QUEUE;
-	host->cmd_per_lun = 2;
-	host->sg_tablesize = AHC_NSEG;
-	host->select_queue_depths = ahc_linux_select_queue_depth;
-	/* XXX No way to communicate the ID for multiple channels */
-	host->this_id = ahc->our_id;
-	host->irq = ahc->platform_data->irq;
-	host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
-	host->max_lun = AHC_NUM_LUNS;
-	host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
-	ahc_set_unit(ahc, ahc_linux_next_unit());
-	sprintf(buf, "scsi%d", host->host_no);
-	new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
-	if (new_name != NULL) {
-		strcpy(new_name, buf);
-		ahc_set_name(ahc, new_name);
-	}
-	host->unique_id = ahc->unit;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
-	scsi_set_pci_device(host, ahc->dev_softc);
-#endif
-	ahc_linux_initialize_scsi_bus(ahc);
-	ahc_unlock(ahc, &s);
-	return (0);
-}
-
-uint64_t
-ahc_linux_get_memsize()
-{
-	struct sysinfo si;
-
-	si_meminfo(&si);
-	return (si.totalram << PAGE_SHIFT);
-}
-
-/*
- * Find the smallest available unit number to use
- * for a new device.  We don't just use a static
- * count to handle the "repeated hot-(un)plug"
- * scenario.
- */
-static int
-ahc_linux_next_unit()
-{
-	struct ahc_softc *ahc;
-	int unit;
-
-	unit = 0;
-retry:
-	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-		if (ahc->unit == unit) {
-			unit++;
-			goto retry;
-		}
-	}
-	return (unit);
-}
-
-/*
- * Place the SCSI bus into a known state by either resetting it,
- * or forcing transfer negotiations on the next command to any
- * target.
- */
-void
-ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
-{
-	int i;
-	int numtarg;
-
-	i = 0;
-	numtarg = 0;
-
-	if (aic7xxx_no_reset != 0)
-		ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
-
-	if ((ahc->flags & AHC_RESET_BUS_A) != 0)
-		ahc_reset_channel(ahc, 'A', /*initiate_reset*/TRUE);
-	else
-		numtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
-
-	if ((ahc->features & AHC_TWIN) != 0) {
-
-		if ((ahc->flags & AHC_RESET_BUS_B) != 0) {
-			ahc_reset_channel(ahc, 'B', /*initiate_reset*/TRUE);
-		} else {
-			if (numtarg == 0)
-				i = 8;
-			numtarg += 8;
-		}
-	}
-
-	for (; i < numtarg; i++) {
-		struct ahc_devinfo devinfo;
-		struct ahc_initiator_tinfo *tinfo;
-		struct ahc_tmode_tstate *tstate;
-		u_int our_id;
-		u_int target_id;
-		char channel;
-
-		channel = 'A';
-		our_id = ahc->our_id;
-		target_id = i;
-		if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
-			channel = 'B';
-			our_id = ahc->our_id_b;
-			target_id = i % 8;
-		}
-		tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
-					    target_id, &tstate);
-		tinfo->goal = tinfo->user;
-		/*
-		 * Don't try negotiations that require PPR messages
-		 * until we successfully retrieve Inquiry data.
-		 */
-		tinfo->goal.ppr_options = 0;
-		if (tinfo->goal.transport_version > SCSI_REV_2)
-			tinfo->goal.transport_version = SCSI_REV_2;
-		ahc_compile_devinfo(&devinfo, our_id, target_id,
-				   CAM_LUN_WILDCARD, channel, ROLE_INITIATOR);
-		ahc_update_neg_request(ahc, &devinfo, tstate,
-				       tinfo, /*force*/FALSE);
-	}
-	/* Give the bus some time to recover */
-	if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
-		ahc_linux_freeze_sim_queue(ahc);
-		init_timer(&ahc->platform_data->reset_timer);
-		ahc->platform_data->reset_timer.data = (u_long)ahc;
-		ahc->platform_data->reset_timer.expires =
-		    jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000;
-		ahc->platform_data->reset_timer.function =
-		    ahc_linux_release_sim_queue;
-		add_timer(&ahc->platform_data->reset_timer);
-	}
-}
-
-int
-ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
-{
-	ahc->platform_data =
-	    malloc(sizeof(struct ahc_platform_data), M_DEVBUF, M_NOWAIT);
-	if (ahc->platform_data == NULL)
-		return (ENOMEM);
-	memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
-	TAILQ_INIT(&ahc->platform_data->completeq);
-	TAILQ_INIT(&ahc->platform_data->device_runq);
-	ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
-	ahc_lockinit(ahc);
-	ahc_done_lockinit(ahc);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-	init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
-#else
-	ahc->platform_data->eh_sem = MUTEX_LOCKED;
-#endif
-	ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
-	ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
-	return (0);
-}
-
-void
-ahc_platform_free(struct ahc_softc *ahc)
-{
-	if (ahc->platform_data != NULL) {
-		if (ahc->platform_data->host != NULL)
-			scsi_unregister(ahc->platform_data->host);
-		if (ahc->platform_data->irq)
-			free_irq(ahc->platform_data->irq, ahc);
-		if (ahc->tag == BUS_SPACE_PIO
-		 && ahc->bsh.ioport != 0)
-			release_region(ahc->bsh.ioport, 256);
-		if (ahc->tag == BUS_SPACE_MEMIO
-		 && ahc->bsh.maddr != NULL) {
-			u_long base_addr;
-
-			base_addr = (u_long)ahc->bsh.maddr;
-			base_addr &= PAGE_MASK;
-			iounmap((void *)base_addr);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-			release_mem_region(ahc->platform_data->mem_busaddr,
-					   0x1000);
-#endif
-		}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		/* XXX Need an instance detach in the PCI code */
-		if (ahc->dev_softc != NULL)
-			ahc->dev_softc->driver = NULL;
-#endif
-		free(ahc->platform_data, M_DEVBUF);
-	}
-}
-
-void
-ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
-{
-	ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
-				SCB_GET_CHANNEL(ahc, scb),
-				SCB_GET_LUN(scb), SCB_LIST_NULL,
-				ROLE_UNKNOWN, CAM_REQUEUE_REQ);
-}
-
-void
-ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		      ahc_queue_alg alg)
-{
-	struct ahc_linux_device *dev;
-	int was_queuing;
-	int now_queuing;
-
-	dev = ahc_linux_get_device(ahc, devinfo->channel - 'A',
-				   devinfo->target,
-				   devinfo->lun, /*alloc*/FALSE);
-	if (dev == NULL)
-		return;
-	was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
-	now_queuing = alg != AHC_QUEUE_NONE;
-	if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0
-	 && (was_queuing != now_queuing)
-	 && (dev->active != 0)) {
-		dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY;
-		dev->qfrozen++;
-	}
-
-	dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG);
-	if (now_queuing) {
-
-		if (!was_queuing) {
-			/*
-			 * Start out agressively and allow our
-			 * dynamic queue depth algorithm to take
-			 * care of the rest.
-			 */
-			dev->maxtags = AHC_MAX_QUEUE;
-			dev->openings = dev->maxtags - dev->active;
-		}
-		if (alg == AHC_QUEUE_TAGGED) {
-			dev->flags |= AHC_DEV_Q_TAGGED;
-			if (aic7xxx_periodic_otag != 0)
-				dev->flags |= AHC_DEV_PERIODIC_OTAG;
-		} else
-			dev->flags |= AHC_DEV_Q_BASIC;
-	} else {
-		/* We can only have one opening */
-		dev->maxtags = 0;
-		dev->openings =  1 - dev->active;
-	}
-}
-
-int
-ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
-			int lun, u_int tag, role_t role, uint32_t status)
-{
-	int chan;
-	int maxchan;
-	int targ;
-	int maxtarg;
-	int clun;
-	int maxlun;
-	int count;
-
-	if (tag != SCB_LIST_NULL)
-		return (0);
-
-	chan = 0;
-	if (channel != ALL_CHANNELS) {
-		chan = channel - 'A';
-		maxchan = chan + 1;
-	} else {
-		maxchan = (ahc->features & AHC_TWIN) ? 2 : 1;
-	}
-	targ = 0;
-	if (target != CAM_TARGET_WILDCARD) {
-		targ = target;
-		maxtarg = targ + 1;
-	} else {
-		maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
-	}
-	clun = 0;
-	if (lun != CAM_LUN_WILDCARD) {
-		clun = lun;
-		maxlun = clun + 1;
-	} else {
-		maxlun = 16;
-	}
-
-	count = 0;
-	for (; chan < maxchan; chan++) {
-		for (; targ < maxtarg; targ++) {
-			for (; clun < maxlun; clun++) {
-				struct ahc_linux_device *dev;
-				struct ahc_busyq *busyq;
-				struct ahc_cmd *acmd;
-
-				dev = ahc_linux_get_device(ahc, chan,
-							   targ, clun,
-							   /*alloc*/FALSE);
-				if (dev == NULL)
-					continue;
-
-				busyq = &dev->busyq;
-				while ((acmd = TAILQ_FIRST(busyq)) != NULL) {
-					Scsi_Cmnd *cmd;
-
-					cmd = &acmd_scsi_cmd(acmd);
-					TAILQ_REMOVE(busyq, acmd,
-						     acmd_links.tqe);
-					count++;
-					cmd->result = status << 16;
-					ahc_linux_queue_cmd_complete(ahc, cmd);
-				}
-			}
-		}
-	}
-
-	return (count);
-}
-
-/*
- * Sets the queue depth for each SCSI device hanging
- * off the input host adapter.
- */
-static void
-ahc_linux_select_queue_depth(struct Scsi_Host * host,
-			     Scsi_Device * scsi_devs)
-{
-	Scsi_Device *device;
-	struct	ahc_softc *ahc;
-	u_long	flags;
-	int	scbnum;
-
-	ahc = *((struct ahc_softc **)host->hostdata);
-	ahc_lock(ahc, &flags);
-	scbnum = 0;
-	for (device = scsi_devs; device != NULL; device = device->next) {
-		if (device->host == host) {
-			ahc_linux_device_queue_depth(ahc, device);
-			scbnum += device->queue_depth;
-		}
-	}
-	ahc_unlock(ahc, &flags);
-}
-
-/*
- * Determines the queue depth for a given device.
- */
-static void
-ahc_linux_device_queue_depth(struct ahc_softc *ahc, Scsi_Device * device)
-{
-	struct	ahc_devinfo devinfo;
-	struct	ahc_initiator_tinfo *targ_info;
-	struct	ahc_tmode_tstate *tstate;
-	uint8_t tags;
-
-	ahc_compile_devinfo(&devinfo,
-			    device->channel == 0 ? ahc->our_id : ahc->our_id_b,
-			    device->id, device->lun,
-			    device->channel == 0 ? 'A' : 'B',
-			    ROLE_INITIATOR);
-	targ_info = ahc_fetch_transinfo(ahc, devinfo.channel,
-					devinfo.our_scsiid,
-					devinfo.target, &tstate);
-
-	tags = 0;
-	if (device->tagged_supported != 0
-	 && (ahc->user_discenable & devinfo.target_mask) != 0) {
-		if (ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) {
-
-			printf("aic7xxx: WARNING, insufficient "
-			       "tag_info instances for installed "
-			       "controllers. Using defaults\n");
-			printf("aic7xxx: Please update the "
-			       "aic7xxx_tag_info array in the "
-			       "aic7xxx.c source file.\n");
-			tags = AHC_MAX_QUEUE;
-		} else {
-			adapter_tag_info_t *tag_info;
-
-			tag_info = &aic7xxx_tag_info[ahc->unit];
-			tags = tag_info->tag_commands[devinfo.target_offset];
-			if (tags > AHC_MAX_QUEUE)
-				tags = AHC_MAX_QUEUE;
-		}
-	}
-	if (tags != 0) {
-		device->queue_depth = tags;
-		ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED);
-		printf("scsi%d:%c:%d:%d: Tagged Queuing enabled.  Depth %d\n",
-	       	       ahc->platform_data->host->host_no, device->channel + 'A',
-		       device->id, device->lun, tags);
-	} else {
-		/*
-		 * We allow the OS to queue 2 untagged transactions to
-		 * us at any time even though we can only execute them
-		 * serially on the controller/device.  This should remove
-		 * some latency.
-		 */
-		device->queue_depth = 2;
-	}
-}
-
-/*
- * Queue an SCB to the controller.
- */
-int
-ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
-{
-	struct	 ahc_softc *ahc;
-	struct	 ahc_linux_device *dev;
-	u_long	 flags;
-
-	ahc = *(struct ahc_softc **)cmd->host->hostdata;
-
-	/*
-	 * Save the callback on completion function.
-	 */
-	cmd->scsi_done = scsi_done;
-
-	ahc_lock(ahc, &flags);
-	dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target,
-				   cmd->lun, /*alloc*/TRUE);
-	if (dev == NULL) {
-		ahc_unlock(ahc, &flags);
-		printf("aic7xxx_linux_queue: Unable to allocate device!\n");
-		return (-ENOMEM);
-	}
-	cmd->result = CAM_REQ_INPROG << 16;
-	TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe);
-	if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
-		TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
-		dev->flags |= AHC_DEV_ON_RUN_LIST;
-		ahc_linux_run_device_queues(ahc);
-	}
-	ahc_unlock(ahc, &flags);
-	return (0);
-}
-
-static void
-ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
-{
-	struct	 ahc_cmd *acmd;
-	struct	 scsi_cmnd *cmd;
-	struct	 scb *scb;
-	struct	 hardware_scb *hscb;
-	struct	 ahc_initiator_tinfo *tinfo;
-	struct	 ahc_tmode_tstate *tstate;
-	uint16_t mask;
-
-	if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0)
-		panic("running device on run list");
-
-	while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
-	    && dev->openings > 0 && dev->qfrozen == 0) {
-
-		/*
-		 * Schedule us to run later.  The only reason we are not
-		 * running is because the whole controller Q is frozen.
-		 */
-		if (ahc->platform_data->qfrozen != 0) {
-
-			TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
-					  dev, links);
-			dev->flags |= AHC_DEV_ON_RUN_LIST;
-			return;
-		}
-		/*
-		 * Get an scb to use.
-		 */
-		if ((scb = ahc_get_scb(ahc)) == NULL) {
-			TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
-					 dev, links);
-			dev->flags |= AHC_DEV_ON_RUN_LIST;
-			ahc->flags |= AHC_RESOURCE_SHORTAGE;
-			return;
-		}
-		TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe);
-		cmd = &acmd_scsi_cmd(acmd);
-		scb->io_ctx = cmd;
-		scb->platform_data->dev = dev;
-		hscb = scb->hscb;
-		cmd->host_scribble = (char *)scb;
-
-		/*
-		 * Fill out basics of the HSCB.
-		 */
-		hscb->control = 0;
-		hscb->scsiid = BUILD_SCSIID(ahc, cmd);
-		hscb->lun = cmd->lun;
-		mask = SCB_GET_TARGET_MASK(ahc, scb);
-		tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
-					    SCB_GET_OUR_ID(scb),
-					    SCB_GET_TARGET(ahc, scb), &tstate);
-		hscb->scsirate = tinfo->scsirate;
-		hscb->scsioffset = tinfo->curr.offset;
-		if ((tstate->ultraenb & mask) != 0)
-			hscb->control |= ULTRAENB;
-
-		if ((ahc->user_discenable & mask) != 0)
-			hscb->control |= DISCENB;
-
-		if ((tstate->auto_negotiate & mask) != 0) {
-			scb->flags |= SCB_AUTO_NEGOTIATE;
-			scb->hscb->control |= MK_MESSAGE;
-		}
-
-		if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
-			if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
-			 && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
-				hscb->control |= MSG_ORDERED_TASK;
-				dev->commands_since_idle_or_otag = 0;
-			} else {
-				hscb->control |= MSG_SIMPLE_TASK;
-			}
-		}
-
-		hscb->cdb_len = cmd->cmd_len;
-		if (hscb->cdb_len <= 12) {
-			memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
-		} else {
-			memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
-			scb->flags |= SCB_CDB32_PTR;
-		}
-
-		scb->platform_data->xfer_len = 0;
-		ahc_set_residual(scb, 0);
-		ahc_set_sense_residual(scb, 0);
-		if (cmd->use_sg != 0) {
-			struct	ahc_dma_seg *sg;
-			struct	scatterlist *cur_seg;
-			struct	scatterlist *end_seg;
-			int	nseg;
-
-			cur_seg = (struct scatterlist *)cmd->request_buffer;
-			nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
-				 scsi_to_pci_dma_dir(cmd ->sc_data_direction));
-			end_seg = cur_seg + nseg;
-			/* Copy the segments into the SG list. */
-			sg = scb->sg_list;
-			/*
-			 * The sg_count may be larger than nseg if
-			 * a transfer crosses a 32bit page.
-			 */ 
-			scb->sg_count = 0;
-			while(cur_seg < end_seg) {
-				bus_addr_t addr;
-				bus_size_t len;
-				int consumed;
-
-				addr = sg_dma_address(cur_seg);
-				len = sg_dma_len(cur_seg);
-				consumed = ahc_linux_map_seg(ahc, scb,
-							     sg, addr, len);
-				sg += consumed;
-				scb->sg_count += consumed;
-				cur_seg++;
-			}
-			sg--;
-			sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
-
-			/*
-			 * Reset the sg list pointer.
-			 */
-			scb->hscb->sgptr =
-			    ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
-
-			/*
-			 * Copy the first SG into the "current"
-			 * data pointer area.
-			 */
-			scb->hscb->dataptr = scb->sg_list->addr;
-			scb->hscb->datacnt = scb->sg_list->len;
-		} else if (cmd->request_bufflen != 0) {
-			struct	 ahc_dma_seg *sg;
-			bus_addr_t addr;
-
-			sg = scb->sg_list;
-			addr = pci_map_single(ahc->dev_softc,
-			       cmd->request_buffer,
-			       cmd->request_bufflen,
-			       scsi_to_pci_dma_dir(cmd->sc_data_direction));
-			scb->sg_count = 0;
-			scb->sg_count = ahc_linux_map_seg(ahc, scb,
-							  sg, addr,
-							  cmd->request_bufflen);
-			sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
-
-			/*
-			 * Reset the sg list pointer.
-			 */
-			scb->hscb->sgptr =
-			    ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
-
-			/*
-			 * Copy the first SG into the "current"
-			 * data pointer area.
-			 */
-			scb->hscb->dataptr = sg->addr;
-			scb->hscb->datacnt = sg->len;
-		} else {
-			scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
-			scb->hscb->dataptr = 0;
-			scb->hscb->datacnt = 0;
-			scb->sg_count = 0;
-		}
-
-		ahc_sync_sglist(ahc, scb, BUS_DMASYNC_PREWRITE);
-		LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
-		dev->openings--;
-		dev->active++;
-		dev->commands_issued++;
-		if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
-			dev->commands_since_idle_or_otag++;
-
-		/*
-		 * We only allow one untagged transaction
-		 * per target in the initiator role unless
-		 * we are storing a full busy target *lun*
-		 * table in SCB space.
-		 */
-		if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
-		 && (ahc->features & AHC_SCB_BTT) == 0) {
-			struct scb_tailq *untagged_q;
-			int target_offset;
-
-			target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
-			untagged_q = &(ahc->untagged_queues[target_offset]);
-			TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
-			scb->flags |= SCB_UNTAGGEDQ;
-			if (TAILQ_FIRST(untagged_q) != scb)
-				continue;
-		}
-		scb->flags |= SCB_ACTIVE;
-		ahc_queue_scb(ahc, scb);
-	}
-}
-
-/*
- * SCSI controller interrupt handler.
- */
-void
-ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct ahc_softc *ahc;
-	struct ahc_cmd *acmd;
-	u_long flags;
-
-	ahc = (struct ahc_softc *) dev_id;
-	ahc_lock(ahc, &flags); 
-	ahc_intr(ahc);
-	/*
-	 * It would be nice to run the device queues from a
-	 * bottom half handler, but as there is no way to
-	 * dynamically register one, we'll have to postpone
-	 * that until we get integrated into the kernel.
-	 */
-	ahc_linux_run_device_queues(ahc);
-	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
-	TAILQ_INIT(&ahc->platform_data->completeq);
-	ahc_unlock(ahc, &flags);
-	if (acmd != NULL)
-		ahc_linux_run_complete_queue(ahc, acmd);
-}
-
-void
-ahc_platform_flushwork(struct ahc_softc *ahc)
-{
-	struct ahc_cmd *acmd;
-
-	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
-	TAILQ_INIT(&ahc->platform_data->completeq);
-	if (acmd != NULL)
-		ahc_linux_run_complete_queue(ahc, acmd);
-}
-
-static struct ahc_linux_target*
-ahc_linux_alloc_target(struct ahc_softc *ahc, u_int channel, u_int target)
-{
-	struct ahc_linux_target *targ;
-	u_int target_offset;
-
-	targ = malloc(sizeof(*targ), M_DEVBUG, M_NOWAIT);
-	if (targ == NULL)
-		return (NULL);
-	memset(targ, 0, sizeof(*targ));
-	targ->channel = channel;
-	targ->target = target;
-	target_offset = target;
-	if (channel != 0)
-		target_offset += 8;
-	ahc->platform_data->targets[target_offset] = targ;
-	return (targ);
-}
-
-static void
-ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ)
-{
-	u_int target_offset;
-
-	target_offset = targ->target;
-	if (targ->channel != 0)
-		target_offset += 8;
-	ahc->platform_data->targets[target_offset] = NULL;
-	free(targ, M_DEVBUF);
-}
-
-static struct ahc_linux_device*
-ahc_linux_alloc_device(struct ahc_softc *ahc,
-		 struct ahc_linux_target *targ, u_int lun)
-{
-	struct ahc_linux_device *dev;
-
-	dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT);
-	if (dev == NULL)
-		return (NULL);
-	memset(dev, 0, sizeof(*dev));
-	TAILQ_INIT(&dev->busyq);
-	dev->flags = AHC_DEV_UNCONFIGURED;
-	dev->lun = lun;
-	dev->target = targ;
-
-	/*
-	 * We start out life using untagged
-	 * transactions of which we allow one.
-	 */
-	dev->openings = 1;
-
-	/*
-	 * Set maxtags to 0.  This will be changed if we
-	 * later determine that we are dealing with
-	 * a tagged queuing capable device.
-	 */
-	dev->maxtags = 0;
-	
-	targ->refcount++;
-	targ->devices[lun] = dev;
-	return (dev);
-}
-
-static void
-ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
-{
-	struct ahc_linux_target *targ;
-
-	targ = dev->target;
-	targ->devices[dev->lun] = NULL;
-	free(dev, M_DEVBUF);
-	targ->refcount--;
-	if (targ->refcount == 0)
-		ahc_linux_free_target(ahc, targ);
-}
-
-/*
- * Return a string describing the driver.
- */
-const char *
-ahc_linux_info(struct Scsi_Host *host)
-{
-	static char buffer[512];
-	char	ahc_info[256];
-	char   *bp;
-	struct ahc_softc *ahc;
-
-	bp = &buffer[0];
-	ahc = *(struct ahc_softc **)host->hostdata;
-	memset(bp, 0, sizeof(buffer));
-	strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev ");
-	strcat(bp, AIC7XXX_DRIVER_VERSION);
-	strcat(bp, "\n");
-	strcat(bp, "        <");
-	strcat(bp, ahc->description);
-	strcat(bp, ">\n");
-	strcat(bp, "        ");
-	ahc_controller_info(ahc, ahc_info);
-	strcat(bp, ahc_info);
-	strcat(bp, "\n");
-
-	return (bp);
-}
-
-void
-ahc_send_async(struct ahc_softc *ahc, char channel,
-	       u_int target, u_int lun, ac_code code, void *arg)
-{
-	switch (code) {
-	case AC_TRANSFER_NEG:
-	{
-		char	buf[80];
-		struct	ahc_linux_target *targ;
-		struct	info_str info;
-		struct	ahc_initiator_tinfo *tinfo;
-		struct	ahc_tmode_tstate *tstate;
-		int	target_offset;
-
-		info.buffer = buf;
-		info.length = sizeof(buf);
-		info.offset = 0;
-		info.pos = 0;
-		tinfo = ahc_fetch_transinfo(ahc, channel,
-						channel == 'A' ? ahc->our_id
-							       : ahc->our_id_b,
-						target, &tstate);
-
-		/*
-		 * Don't bother reporting results while
-		 * negotiations are still pending.
-		 */
-		if (tinfo->curr.period != tinfo->goal.period
-		 || tinfo->curr.width != tinfo->goal.width
-		 || tinfo->curr.offset != tinfo->goal.offset
-		 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
-			if (bootverbose == 0)
-				break;
-
-		/*
-		 * Don't bother reporting results that
-		 * are identical to those last reported.
-		 */
-		target_offset = target;
-		if (channel == 'B')
-			target_offset += 8;
-		targ = ahc->platform_data->targets[target_offset];
-		if (targ != NULL
-		 && tinfo->curr.period == targ->last_tinfo.period
-		 && tinfo->curr.width == targ->last_tinfo.width
-		 && tinfo->curr.offset == targ->last_tinfo.offset
-		 && tinfo->curr.ppr_options == targ->last_tinfo.ppr_options)
-			if (bootverbose == 0)
-				break;
-
-		targ->last_tinfo.period = tinfo->curr.period;
-		targ->last_tinfo.width = tinfo->curr.width;
-		targ->last_tinfo.offset = tinfo->curr.offset;
-		targ->last_tinfo.ppr_options = tinfo->curr.ppr_options;
-
-		printf("(%s:%c:", ahc_name(ahc), channel);
-		if (target == CAM_TARGET_WILDCARD)
-			printf("*): ");
-		else
-			printf("%d): ", target);
-		ahc_format_transinfo(&info, &tinfo->curr);
-		if (info.pos < info.length)
-			*info.buffer = '\0';
-		else
-			buf[info.length - 1] = '\0';
-		printf("%s", buf);
-		break;
-	}
-        case AC_SENT_BDR:
-		break;
-        case AC_BUS_RESET:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-		if (ahc->platform_data->host != NULL) {
-			scsi_report_bus_reset(ahc->platform_data->host,
-					      channel - 'A');
-		}
-#endif
-                break;
-        default:
-                panic("ahc_send_async: Unexpected async event");
-        }
-}
-
-/*
- * Calls the higher level scsi done function and frees the scb.
- */
-void
-ahc_done(struct ahc_softc *ahc, struct scb * scb)
-{
-	Scsi_Cmnd *cmd;
-	struct ahc_linux_device *dev;
-
-	LIST_REMOVE(scb, pending_links);
-	if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
-		struct scb_tailq *untagged_q;
-		int target_offset;
-
-		target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
-		untagged_q = &(ahc->untagged_queues[target_offset]);
-		TAILQ_REMOVE(untagged_q, scb, links.tqe);
-		ahc_run_untagged_queue(ahc, untagged_q);
-	}
-
-	if ((scb->flags & SCB_ACTIVE) == 0) {
-		printf("SCB %d done'd twice\n", scb->hscb->tag);
-		ahc_dump_card_state(ahc);
-		panic("Stopping for safety");
-	}
-	cmd = scb->io_ctx;
-	dev = scb->platform_data->dev;
-	dev->active--;
-	dev->openings++;
-	ahc_linux_unmap_scb(ahc, scb);
-	if (scb->flags & SCB_SENSE) {
-		memcpy(cmd->sense_buffer, ahc_get_sense_buf(ahc, scb),
-		       MIN(sizeof(struct scsi_sense_data),
-			   sizeof(cmd->sense_buffer)));
-		cmd->result |= (DRIVER_SENSE << 24);
-	} else {
-		/*
-		 * Guard against stale sense data.
-		 * The Linux mid-layer assumes that sense
-		 * was retrieved anytime the first byte of
-		 * the sense buffer looks "sane".
-		 */
-		cmd->sense_buffer[0] = 0;
-	}
-	if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) {
-		uint32_t amount_xferred;
-
-		amount_xferred =
-		    ahc_get_transfer_length(scb) - ahc_get_residual(scb);
-		if (amount_xferred < scb->io_ctx->underflow) {
-			printf("Saw underflow (%ld of %ld bytes). "
-			       "Treated as error\n",
-				ahc_get_residual(scb),
-				ahc_get_transfer_length(scb));
-			ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
-		} else {
-			ahc_set_transaction_status(scb, CAM_REQ_CMP);
-			ahc_linux_sniff_command(ahc, cmd, scb);
-		}
-	} else if (ahc_get_transaction_status(scb) == DID_OK) {
-		ahc_linux_handle_scsi_status(ahc, dev, scb);
-	} else if (ahc_get_transaction_status(scb) == DID_NO_CONNECT) {
-		/*
-		 * Should a selection timeout kill the device?
-		 * That depends on whether the selection timeout
-		 * is persistent.  Since we have no guarantee that
-		 * the mid-layer will issue an inquiry for this device
-		 * again, we can't just kill it off.
-		dev->flags |= AHC_DEV_UNCONFIGURED;
-		 */
-	}
-
-	if (dev->openings == 1
-	 && ahc_get_transaction_status(scb) == CAM_REQ_CMP
-	 && ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
-		dev->tag_success_count++;
-	/*
-	 * Some devices deal with temporary internal resource
-	 * shortages by returning queue full.  When the queue
-	 * full occurrs, we throttle back.  Slowly try to get
-	 * back to our previous queue depth.
-	 */
-	if ((dev->openings + dev->active) < dev->maxtags
-	 && dev->tag_success_count > AHC_TAG_SUCCESS_INTERVAL) {
-		dev->tag_success_count = 0;
-		dev->openings++;
-	}
-
-	if (dev->active == 0)
-		dev->commands_since_idle_or_otag = 0;
-
-	if (TAILQ_EMPTY(&dev->busyq)) {
-		if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0
-		 && dev->active == 0)
-			ahc_linux_free_device(ahc, dev);
-	} else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
-		TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
-		dev->flags |= AHC_DEV_ON_RUN_LIST;
-	}
-
-	if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
-		printf("Recovery SCB completes\n");
-		up(&ahc->platform_data->eh_sem);
-	}
-
-	ahc_free_scb(ahc, scb);
-	ahc_linux_queue_cmd_complete(ahc, cmd);
-}
-
-static void
-ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
-			     struct ahc_linux_device *dev, struct scb *scb)
-{
-	/*
-	 * We don't currently trust the mid-layer to
-	 * properly deal with queue full or busy.  So,
-	 * when one occurs, we tell the mid-layer to
-	 * unconditionally requeue the command to us
-	 * so that we can retry it ourselves.  We also
-	 * implement our own throttling mechanism so
-	 * we don't clobber the device with too many
-	 * commands.
-	 */
-	switch (ahc_get_scsi_status(scb)) {
-	default:
-		break;
-	case SCSI_STATUS_QUEUE_FULL:
-	{
-		/*
-		 * By the time the core driver has returned this
-		 * command, all other commands that were queued
-		 * to us but not the device have been returned.
-		 * This ensures that dev->active is equal to
-		 * the number of commands actually queued to
-		 * the device.
-		 */
-		dev->tag_success_count = 0;
-		if (dev->active != 0) {
-			/*
-			 * Drop our opening count to the number
-			 * of commands currently outstanding.
-			 */
-			dev->openings = 0;
-/*
-			ahc_print_path(ahc, scb);
-			printf("Dropping tag count to %d\n", dev->active);
- */
-			if (dev->active == dev->tags_on_last_queuefull) {
-
-				dev->last_queuefull_same_count++;
-				/*
-				 * If we repeatedly see a queue full
-				 * at the same queue depth, this
-				 * device has a fixed number of tag
-				 * slots.  Lock in this tag depth
-				 * so we stop seeing queue fulls from
-				 * this device.
-				 */
-				if (dev->last_queuefull_same_count
-				 == AHC_LOCK_TAGS_COUNT) {
-					dev->maxtags = dev->active;
-					ahc_print_path(ahc, scb);
-					printf("Locking max tag count at %d\n",
-					       dev->active);
-				}
-			} else {
-				dev->tags_on_last_queuefull = dev->active;
-				dev->last_queuefull_same_count = 0;
-			}
-			ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
-			ahc_set_scsi_status(scb, SCSI_STATUS_OK);
-			break;
-		}
-		/*
-		 * Drop down to a single opening, and treat this
-		 * as if the target return BUSY SCSI status.
-		 */
-		dev->openings = 1;
-		/* FALLTHROUGH */
-	}
-	case SCSI_STATUS_BUSY:
-		/*
-		 * XXX Set a timer and handle ourselves????
-		 * For now we pray that the mid-layer does something
-		 * sane for devices that are busy.
-		 */
-		ahc_set_scsi_status(scb, SCSI_STATUS_BUSY);
-		break;
-	}
-}
-
-static void
-ahc_linux_filter_command(struct ahc_softc *ahc, Scsi_Cmnd *cmd, struct scb *scb)
-{
-	switch (cmd->cmnd[0]) {
-	case INQUIRY:
-	{
-		struct	ahc_devinfo devinfo;
-		struct	scsi_inquiry *inq;
-		struct	scsi_inquiry_data *sid;
-		struct	ahc_initiator_tinfo *targ_info;
-		struct	ahc_tmode_tstate *tstate;
-		struct	ahc_syncrate *syncrate;
-		struct	ahc_linux_device *dev;
-		u_int	scsiid;
-		u_int	maxsync;
-		int	transferred_len;
-		int	minlen;
-		u_int	width;
-		u_int	period;
-		u_int	offset;
-		u_int	ppr_options;
-
-		 /*
-		  * Validate the command.  We only want to filter
-		  * standard inquiry commands, not those querying
-		  * Vital Product Data.
-		  */
-		inq = (struct scsi_inquiry *)cmd->cmnd;
-		if ((inq->byte2 & SI_EVPD) != 0
-		 || inq->page_code != 0)
-			break;
-
-		if (cmd->use_sg != 0) {
-			printf("%s: SG Inquiry response ignored\n",
-			       ahc_name(ahc));
-			break;
-		}
-		transferred_len = ahc_get_transfer_length(scb)
-				- ahc_get_residual(scb);
-		sid = (struct scsi_inquiry_data *)cmd->request_buffer;
-
-		/*
-		 * Determine if this lun actually exists.  If so,
-		 * hold on to its corresponding device structure.
-		 * If not, make sure we release the device and
-		 * don't bother processing the rest of this inquiry
-		 * command.
-		 */
-		dev = ahc_linux_get_device(ahc, cmd->channel,
-					   cmd->target, cmd->lun,
-					   /*alloc*/FALSE);
-		if (transferred_len >= 1
-		 && SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) {
-
-			dev->flags &= ~AHC_DEV_UNCONFIGURED;
-		} else {
-			dev->flags |= AHC_DEV_UNCONFIGURED;
-			break;
-		}
-
-		/*
-		 * Update our notion of this device's transfer
-		 * negotiation capabilities.
-		 */
-		scsiid = BUILD_SCSIID(ahc, cmd);
-		ahc_compile_devinfo(&devinfo, SCSIID_OUR_ID(scsiid),
-				    cmd->target, cmd->lun,
-				    SCSIID_CHANNEL(ahc, scsiid),
-				    ROLE_INITIATOR);
-		targ_info = ahc_fetch_transinfo(ahc, devinfo.channel,
-						devinfo.our_scsiid,
-						devinfo.target, &tstate);
-		width = targ_info->user.width;
-		period = targ_info->user.period;
-		offset = targ_info->user.offset;
-		ppr_options = targ_info->user.ppr_options;
-		minlen = offsetof(struct scsi_inquiry_data, version) + 1;
-		if (transferred_len >= minlen) {
-			targ_info->curr.protocol_version = SID_ANSI_REV(sid);
-
-			/*
-			 * Only attempt SPI3 once we've verified that
-			 * the device claims to support SPI3 features.
-			 */
-			if (targ_info->curr.protocol_version < SCSI_REV_2)
-				targ_info->curr.transport_version =
-				    SID_ANSI_REV(sid);
-			else
-				targ_info->curr.transport_version =
-				     SCSI_REV_2;
-		}
-
-		minlen = offsetof(struct scsi_inquiry_data, flags) + 1;
-		if (transferred_len >= minlen
-		 && (sid->additional_length + 4) >= minlen) {
-			if ((sid->flags & SID_WBus16) == 0)
-				width = MSG_EXT_WDTR_BUS_8_BIT;
-			if ((sid->flags & SID_Sync) == 0) {
-				period = 0;
-				offset = 0;
-				ppr_options = 0;
-			}
-		} else {
-			/* Keep current settings */
-			break;
-		}
-		minlen = offsetof(struct scsi_inquiry_data, spi3data) + 1;
-		/*
-		 * This is a kludge to deal with inquiry requests that
-		 * are not large enough for us to pull the spi3 bits.
-		 * In this case, we assume that a device that tells us
-		 * they can provide inquiry data that spans the SPI3
-		 * bits and says its SCSI3 can handle a PPR request.
-		 * If the inquiry request has sufficient buffer space to
-		 * cover these bits, we check them to see if any ppr options
-		 * are available.
-		 */
-		if ((sid->additional_length + 4) >= minlen) {
-			if (transferred_len >= minlen
-			 && (sid->spi3data & SID_SPI_CLOCK_DT) == 0)
-				ppr_options = 0;
-
-			if (targ_info->curr.protocol_version > SCSI_REV_2)
-				targ_info->curr.transport_version = 3;
-			else
-				ppr_options = 0;
-		} else {
-			ppr_options = 0;
-		}
-		ahc_validate_width(ahc, /*tinfo limit*/NULL, &width,
-				   ROLE_UNKNOWN);
-		if ((ahc->features & AHC_ULTRA2) != 0)
-			maxsync = AHC_SYNCRATE_DT;
-		else if ((ahc->features & AHC_ULTRA) != 0)
-			maxsync = AHC_SYNCRATE_ULTRA;
-		else
-			maxsync = AHC_SYNCRATE_FAST;
-
-		syncrate = ahc_find_syncrate(ahc, &period,
-					     &ppr_options, maxsync);
-		ahc_validate_offset(ahc, /*tinfo limit*/NULL, syncrate,
-				    &offset, width, ROLE_UNKNOWN);
-		if (offset == 0 || period == 0) {
-			period = 0;
-			offset = 0;
-			ppr_options = 0;
-		}
-		/* Apply our filtered user settings. */
-		ahc_set_width(ahc, &devinfo, width,
-			      AHC_TRANS_GOAL, /*paused*/FALSE);
-		ahc_set_syncrate(ahc, &devinfo, syncrate, period,
-				 offset, ppr_options, AHC_TRANS_GOAL,
-				 /*paused*/FALSE);
-		break;
-	}
-	default:
-		panic("ahc_linux_filter_command: Unexpected Command type  %x\n",
-		      cmd->cmnd[0]);
-		break;
-	}
-}
-
-static void
-ahc_linux_sem_timeout(u_long arg)
-{
-	struct semaphore *sem;
-
-	sem = (struct semaphore *)arg;
-	up(sem);
-}
-
-static void
-ahc_linux_freeze_sim_queue(struct ahc_softc *ahc)
-{
-	ahc->platform_data->qfrozen++;
-	if (ahc->platform_data->qfrozen == 1)
-		scsi_block_requests(ahc->platform_data->host);
-}
-
-static void
-ahc_linux_release_sim_queue(u_long arg)
-{
-	struct ahc_softc *ahc;
-	u_long s;
-	int    unblock_reqs;
-
-	ahc = (struct ahc_softc *)arg;
-	unblock_reqs = 0;
-	ahc_lock(ahc, &s);
-	if (ahc->platform_data->qfrozen > 0)
-		ahc->platform_data->qfrozen--;
-	if (ahc->platform_data->qfrozen == 0) {
-		unblock_reqs = 1;
-		ahc_linux_run_device_queues(ahc);
-	}
-	ahc_unlock(ahc, &s);
-	/*
-	 * There is still a race here.  The mid-layer
-	 * should keep its own freeze count and use
-	 * a bottom half handler to run the queues
-	 * so we can unblock with our own lock held.
-	 */
-	if (unblock_reqs)
-		scsi_unblock_requests(ahc->platform_data->host);
-}
-
-static int
-ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
-{
-	struct ahc_softc *ahc;
-	struct ahc_cmd *acmd;
-	struct ahc_cmd *list_acmd;
-	struct ahc_linux_device *dev;
-	struct scb *pending_scb;
-	u_long s;
-	u_int  saved_scbptr;
-	u_int  active_scb_index;
-	u_int  last_phase;
-	int    retval;
-	int    paused;
-	int    wait;
-	int    disconnected;
-
-	paused = FALSE;
-	wait = FALSE;
-	ahc = *(struct ahc_softc **)cmd->host->hostdata;
-	acmd = (struct ahc_cmd *)cmd;
-
-	printf("%s:%d:%d:%d: Attempting to queue a%s message\n",
-	       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun,
-	       flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
-
-	/*
-	 * It is a bug that the upper layer takes
-	 * this lock just prior to calling us.
-	 */
-	spin_unlock_irq(&io_request_lock);
-
-	ahc_lock(ahc, &s);
-
-	/*
-	 * First determine if we currently own this command.
-	 * Start by searching the device queue.  If not found
-	 * there, check the pending_scb list.  If not found
-	 * at all, and the system wanted us to just abort the
-	 * command return success.
-	 */
-	dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target,
-				   cmd->lun, /*alloc*/FALSE);
-
-	if (dev == NULL) {
-		/*
-		 * No target device for this command exists,
-		 * so we must not still own the command.
-		 */
-		printf("%s:%d:%d:%d: Is not an active device\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
-		retval = SUCCESS;
-		goto no_cmd;
-	}
-
-	TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) {
-		if (list_acmd == acmd)
-			break;
-	}
-
-	if (list_acmd != NULL) {
-		printf("%s:%d:%d:%d: Command found on device queue\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
-		if (flag == SCB_ABORT) {
-			TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
-			cmd->result = DID_ABORT << 16;
-			ahc_linux_queue_cmd_complete(ahc, cmd);
-			retval = SUCCESS;
-			goto done;
-		}
-	}
-
-	/*
-	 * See if we can find a matching cmd in the pending list.
-	 */
-	LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
-		if (pending_scb->io_ctx == cmd)
-			break;
-	}
-
-	if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
-
-		/* Any SCB for this device will do for a target reset */
-		LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
-		  	if (ahc_match_scb(ahc, pending_scb, cmd->target,
-					  cmd->channel, CAM_LUN_WILDCARD,
-					  SCB_LIST_NULL, ROLE_INITIATOR) == 0)
-				break;
-		}
-	}
-
-	if (pending_scb == NULL) {
-		printf("%s:%d:%d:%d: Command not found\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
-		goto no_cmd;
-	}
-
-	if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
-		/*
-		 * We can't queue two recovery actions using the same SCB
-		 */
-		retval = FAILED;
-		goto  done;
-	}
-
-	/*
-	 * Ensure that the card doesn't do anything
-	 * behind our back.  Also make sure that we
-	 * didn't "just" miss an interrupt that would
-	 * affect this cmd.
-	 */
-	ahc->flags |= AHC_ALL_INTERRUPTS;
-	do {
-		ahc_intr(ahc);
-		ahc_pause(ahc);
-		ahc_clear_critical_section(ahc);
-	} while (ahc_inb(ahc, INTSTAT) & INT_PEND);
-	ahc->flags &= ~AHC_ALL_INTERRUPTS;
-	paused = TRUE;
-
-	ahc_dump_card_state(ahc);
-
-	if ((pending_scb->flags & SCB_ACTIVE) == 0) {
-		printf("%s:%d:%d:%d: Command already completed\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
-		goto no_cmd;
-	}
-
-	disconnected = TRUE;
-	if (flag == SCB_ABORT) {
-		if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
-				       cmd->lun, pending_scb->hscb->tag,
-				       ROLE_INITIATOR, CAM_REQ_ABORTED,
-				       SEARCH_COMPLETE) > 0) {
-			printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
-			       ahc_name(ahc), cmd->channel, cmd->target,
-					cmd->lun);
-			retval = SUCCESS;
-			goto done;
-		}
-	} else if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
-				      cmd->lun, pending_scb->hscb->tag,
-				      ROLE_INITIATOR, /*status*/0,
-				      SEARCH_COUNT) > 0) {
-		disconnected = FALSE;
-	}
-
-	/*
-	 * At this point, pending_scb is the scb associated with the
-	 * passed in command.  That command is currently active on the
-	 * bus, is in the disconnected state, or we're hoping to find
-	 * a command for the same target active on the bus to abuse to
-	 * send a BDR.  Queue the appropriate message based on which of
-	 * these states we are in.
-	 */
-	last_phase = ahc_inb(ahc, LASTPHASE);
-	saved_scbptr = ahc_inb(ahc, SCBPTR);
-	active_scb_index = ahc_inb(ahc, SCB_TAG);
-	if (last_phase != P_BUSFREE
-	 && (pending_scb->hscb->tag == active_scb_index
-	  || (flag == SCB_DEVICE_RESET
-	   && SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)) == cmd->target))) {
-
-		/*
-		 * We're active on the bus, so assert ATN
-		 * and hope that the target responds.
-		 */
-		pending_scb = ahc_lookup_scb(ahc, active_scb_index);
-		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
-		ahc_outb(ahc, MSG_OUT, HOST_MSG);
-		ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
-		printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
-		wait = TRUE;
-	} else if (disconnected) {
-
-		/*
-		 * Actually re-queue this SCB in an attempt
-		 * to select the device before it reconnects.
-		 * In either case (selection or reselection),
-		 * we will now issue the approprate message
-		 * to the timed-out device.
-		 *
-		 * Set the MK_MESSAGE control bit indicating
-		 * that we desire to send a message.  We
-		 * also set the disconnected flag since
-		 * in the paging case there is no guarantee
-		 * that our SCB control byte matches the
-		 * version on the card.  We don't want the
-		 * sequencer to abort the command thinking
-		 * an unsolicited reselection occurred.
-		 */
-		pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
-		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
-
-		/*
-		 * Remove any cached copy of this SCB in the
-		 * disconnected list in preparation for the
-		 * queuing of our abort SCB.  We use the
-		 * same element in the SCB, SCB_NEXT, for
-		 * both the qinfifo and the disconnected list.
-		 */
-		ahc_search_disc_list(ahc, cmd->target, cmd->channel + 'A',
-				     cmd->lun, pending_scb->hscb->tag,
-				     /*stop_on_first*/TRUE,
-				     /*remove*/TRUE,
-				     /*save_state*/FALSE);
-
-		/*
-		 * In the non-paging case, the sequencer will
-		 * never re-reference the in-core SCB.
-		 * To make sure we are notified during
-		 * reslection, set the MK_MESSAGE flag in
-		 * the card's copy of the SCB.
-		 */
-		if ((ahc->flags & AHC_PAGESCBS) == 0) {
-			ahc_outb(ahc, SCBPTR, pending_scb->hscb->tag);
-			ahc_outb(ahc, SCB_CONTROL,
-				 ahc_inb(ahc, SCB_CONTROL)|MK_MESSAGE);
-		}
-
-		/*
-		 * Clear out any entries in the QINFIFO first
-		 * so we are the next SCB for this target
-		 * to run.
-		 */
-		ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
-				   cmd->lun, SCB_LIST_NULL, ROLE_INITIATOR,
-				   CAM_REQUEUE_REQ, SEARCH_COMPLETE);
-		ahc_print_path(ahc, pending_scb);
-		printf("Queuing a recovery SCB\n");
-		ahc_qinfifo_requeue_tail(ahc, pending_scb);
-		ahc_outb(ahc, SCBPTR, saved_scbptr);
-		printf("%s:%d:%d:%d: Device is disconnected, re-queuing SCB\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
-		wait = TRUE;
-	} else {
-		printf("%s:%d:%d:%d: Unable to deliver message\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
-		retval = FAILED;
-		goto done;
-	}
-
-no_cmd:
-	/*
-	 * Our assumption is that if we don't have the command, no
-	 * recovery action was required, so we return success.  Again,
-	 * the semantics of the mid-layer recovery engine are not
-	 * well defined, so this may change in time.
-	 */
-	retval = SUCCESS;
-done:
-	if (paused)
-		ahc_unpause(ahc);
-	if (wait) {
-		struct timer_list timer;
-		int ret;
-
-		ahc_unlock(ahc, &s);
-		init_timer(&timer);
-		timer.data = (u_long)&ahc->platform_data->eh_sem;
-		timer.expires = jiffies + (5 * HZ);
-		timer.function = ahc_linux_sem_timeout;
-		add_timer(&timer);
-		printf("Recovery code sleeping\n");
-		down(&ahc->platform_data->eh_sem);
-		printf("Recovery code awake\n");
-        	ret = del_timer(&timer);
-		if (ret == 0) {
-			printf("Timer Expired\n");
-			retval = FAILED;
-		}
-		ahc_lock(ahc, &s);
-	}
-	ahc_linux_run_device_queues(ahc);
-	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
-	TAILQ_INIT(&ahc->platform_data->completeq);
-	ahc_unlock(ahc, &s);
-	if (acmd != NULL)
-		ahc_linux_run_complete_queue(ahc, acmd);
-	spin_lock_irq(&io_request_lock);
-	return (retval);
-}
-
-/*
- * Abort the current SCSI command(s).
- */
-int
-ahc_linux_abort(Scsi_Cmnd *cmd)
-{
-	int error;
-
-	error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
-	if (error != 0)
-		printf("aic7xxx_abort returns 0x%x\n", error);
-	return (error);
-}
-
-/*
- * Attempt to send a target reset message to the device that timed out.
- */
-int
-ahc_linux_dev_reset(Scsi_Cmnd *cmd)
-{
-	int error;
-
-	error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
-	if (error != 0)
-		printf("aic7xxx_dev_reset returns 0x%x\n", error);
-	return (error);
-}
-
-/*
- * Reset the SCSI bus.
- */
-int
-ahc_linux_bus_reset(Scsi_Cmnd *cmd)
-{
-	struct ahc_softc *ahc;
-	struct ahc_cmd *acmd;
-	u_long s;
-	int    found;
-
-	/*
-	 * It is a bug that the upper layer takes
-	 * this lock just prior to calling us.
-	 */
-	spin_unlock_irq(&io_request_lock);
-
-	ahc = *(struct ahc_softc **)cmd->host->hostdata;
-	ahc_lock(ahc, &s);
-	found = ahc_reset_channel(ahc, cmd->channel + 'A',
-				  /*initiate reset*/TRUE);
-	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
-	TAILQ_INIT(&ahc->platform_data->completeq);
-	ahc_unlock(ahc, &s);
-	if (bootverbose)
-		printf("%s: SCSI bus reset delivered. "
-		       "%d SCBs aborted.\n", ahc_name(ahc), found);
-
-	if (acmd != NULL)
-		ahc_linux_run_complete_queue(ahc, acmd);
-
-	spin_lock_irq(&io_request_lock);
-	return SUCCESS;
-}
-
-/*
- * Return the disk geometry for the given SCSI device.
- */
-int
-ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
-{
-	int	heads;
-	int	sectors;
-	int	cylinders;
-	int	ret;
-	int	extended;
-	struct	ahc_softc *ahc;
-	struct	buffer_head *bh;
-
-	ahc = *((struct ahc_softc **)disk->device->host->hostdata);
-	bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev));
-
-	if (bh) {
-		ret = scsi_partsize(bh, disk->capacity,
-				    &geom[2], &geom[0], &geom[1]);
-		brelse(bh);
-		if (ret != -1)
-			return (ret);
-	}
-	heads = 64;
-	sectors = 32;
-	cylinders = disk->capacity / (heads * sectors);
-
-	if (aic7xxx_extended != 0)
-		extended = 1;
-	else if (disk->device->channel == 0)
-		extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0;
-	else
-		extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0;
-	if (extended && cylinders >= 1024) {
-		heads = 255;
-		sectors = 63;
-		cylinders = disk->capacity / (heads * sectors);
-	}
-	geom[0] = heads;
-	geom[1] = sectors;
-	geom[2] = cylinders;
-	return (0);
-}
-
-/*
- * Free the passed in Scsi_Host memory structures prior to unloading the
- * module.
- */
-int
-ahc_linux_release(struct Scsi_Host * host)
-{
-	struct ahc_softc *ahc;
-
-	if (host != NULL) {
-
-		ahc = *(struct ahc_softc **)host->hostdata;
-		ahc_free(ahc);
-	}
-	if (TAILQ_EMPTY(&ahc_tailq)) {
-		unregister_reboot_notifier(&ahc_linux_notifier);
-#ifdef CONFIG_PCI
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		pci_unregister_driver(&aic7xxx_pci_driver);
-#endif
-#endif
-	}
-	return (0);
-}
-
-void
-ahc_platform_dump_card_state(struct ahc_softc *ahc)
-{
-	struct ahc_linux_device *dev;
-	int channel;
-	int maxchannel;
-	int target;
-	int maxtarget;
-	int lun;
-	int i;
-
-	maxchannel = (ahc->features & AHC_TWIN) ? 1 : 0;
-	maxtarget = (ahc->features & AHC_WIDE) ? 15 : 7;
-	for (channel = 0; channel <= maxchannel; channel++) {
-		for (target = 0; target <=maxtarget; target++) {
-			for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
-				struct ahc_cmd *acmd;
-
-				dev = ahc_linux_get_device(ahc, channel, target,
-							   lun, /*alloc*/FALSE);
-				if (dev == NULL)
-					continue;
-
-				printf("DevQ(%d:%d:%d): ",
-				       channel, target, lun);
-				i = 0;
-				TAILQ_FOREACH(acmd, &dev->busyq,
-					      acmd_links.tqe) {
-					if (i++ > 256)
-						break;
-				}
-				printf("%d waiting\n", i);
-			}
-		}
-	}
-}
-
-#if defined(MODULE) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-static Scsi_Host_Template driver_template = AIC7XXX;
-Scsi_Host_Template *aic7xxx_driver_template = &driver_template;
-#include "../scsi_module.c"
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_linux_host.h linux/drivers/scsi/aic7xxx/aic7xxx_linux_host.h
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_linux_host.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_linux_host.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,95 +0,0 @@
-/*
- * Adaptec AIC7xxx device driver host template for Linux.
- *
- * Copyright (c) 2000-2001 Adaptec Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon
- *    including a substantially similar Disclaimer requirement for further
- *    binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_linux_host.h#5 $
- */
-
-#ifndef _AIC7XXX_LINUX_HOST_H_
-#define _AIC7XXX_LINUX_HOST_H_
-
-int		 ahc_linux_proc_info(char *, char **, off_t, int, int, int);
-int		 ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
-int		 ahc_linux_detect(Scsi_Host_Template *);
-int		 ahc_linux_release(struct Scsi_Host *);
-const char	*ahc_linux_info(struct Scsi_Host *);
-int		 ahc_linux_biosparam(Disk *, kdev_t, int[]);
-int		 ahc_linux_bus_reset(Scsi_Cmnd *);
-int		 ahc_linux_dev_reset(Scsi_Cmnd *);
-int		 ahc_linux_abort(Scsi_Cmnd *);
-
-#if defined(__i386__)
-#  define AIC7XXX_BIOSPARAM ahc_linux_biosparam
-#else
-#  define AIC7XXX_BIOSPARAM NULL
-#endif
-
-/*
- * Scsi_Host_Template (see hosts.h) for AIC-7xxx - some fields
- * to do with card config are filled in after the card is detected.
- */
-#define AIC7XXX	{						\
-	next: NULL,						\
-	module: NULL,						\
-	proc_dir: NULL,						\
-	proc_info: ahc_linux_proc_info,				\
-	name: NULL,						\
-	detect: ahc_linux_detect,				\
-	release: ahc_linux_release,				\
-	info: ahc_linux_info,					\
-	command: NULL,						\
-	queuecommand: ahc_linux_queue,				\
-	eh_strategy_handler: NULL,				\
-	eh_abort_handler: ahc_linux_abort,			\
-	eh_device_reset_handler: ahc_linux_dev_reset,		\
-	eh_bus_reset_handler: ahc_linux_bus_reset,		\
-	eh_host_reset_handler: NULL,				\
-	abort: NULL,						\
-	reset: NULL,						\
-	slave_attach: NULL,					\
-	bios_param: AIC7XXX_BIOSPARAM,				\
-	can_queue: 253,		/* max simultaneous cmds      */\
-	this_id: -1,		/* scsi id of host adapter    */\
-	sg_tablesize: 0,	/* max scatter-gather cmds    */\
-	cmd_per_lun: 2,		/* cmds per lun		      */\
-	present: 0,		/* number of 7xxx's present   */\
-	unchecked_isa_dma: 0,	/* no memory DMA restrictions */\
-	use_clustering: ENABLE_CLUSTERING,			\
-	use_new_eh_code: 1					\
-}
-
-#endif /* _AIC7XXX_LINUX_HOST_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_linux_pci.c linux/drivers/scsi/aic7xxx/aic7xxx_linux_pci.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_linux_pci.c	2001-11-13 17:19:41.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_linux_pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,407 +0,0 @@
-/*
- * Linux driver attachment glue for PCI based controllers.
- *
- * Copyright (c) 2000-2001 Adaptec Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon
- *    including a substantially similar Disclaimer requirement for further
- *    binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_linux_pci.c#27 $
- */
-
-#include "aic7xxx_osm.h"
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-struct pci_device_id
-{
-};
-#endif
-
-static int	ahc_linux_pci_dev_probe(struct pci_dev *pdev,
-					const struct pci_device_id *ent);
-static int	ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
-						u_long *base);
-#ifdef MMAPIO
-static int	ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
-						 u_long *bus_addr,
-						 uint8_t **maddr);
-#endif /* MMAPIO */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-static void	ahc_linux_pci_dev_remove(struct pci_dev *pdev);
-
-/* We do our own ID filtering.  So, grab all SCSI storage class devices. */
-static struct pci_device_id ahc_linux_pci_id_table[] = {
-	{
-		0x9004, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-		PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0
-	},
-	{
-		0x9005, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-		PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0
-	},
-	{ 0 }
-};
-MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table);
-
-struct pci_driver aic7xxx_pci_driver = {
-	name:		"aic7xxx",
-	probe:		ahc_linux_pci_dev_probe,
-	remove:		ahc_linux_pci_dev_remove,
-	id_table:	ahc_linux_pci_id_table
-};
-
-static void
-ahc_linux_pci_dev_remove(struct pci_dev *pdev)
-{
-	struct ahc_softc *ahc;
-	struct ahc_softc *list_ahc;
-
-	/*
-	 * We should be able to just perform
-	 * the free directly, but check our
-	 * list for extra sanity.
-	 */
-	ahc = pci_get_drvdata(pdev);
-	TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
-		if (list_ahc == ahc) {
-			ahc_free(ahc);
-			break;
-		}
-	}
-}
-#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */
-
-static int
-ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	char		 buf[80];
-	struct		 ahc_softc *ahc;
-	ahc_dev_softc_t	 pci;
-	struct		 ahc_pci_identity *entry;
-	char		*name;
-	int		 error;
-
-	/*
-	 * Some BIOSen report the same device multiple times.
-	 */
-	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-		struct pci_dev *probed_pdev;
-
-		probed_pdev = ahc->dev_softc;
-		if (probed_pdev->bus->number == pdev->bus->number
-		 && probed_pdev->devfn == pdev->devfn)
-			break;
-	}
-	if (ahc != NULL) {
-		/* Skip duplicate. */
-		return (-ENODEV);
-	}
-
-	pci = pdev;
-	entry = ahc_find_pci_device(pci);
-	if (entry == NULL)
-		return (-ENODEV);
-
-	/*
-	 * Allocate a softc for this card and
-	 * set it up for attachment by our
-	 * common detect routine.
-	 */
-	sprintf(buf, "ahc_pci:%d:%d:%d",
-		ahc_get_pci_bus(pci),
-		ahc_get_pci_slot(pci),
-		ahc_get_pci_function(pci));
-	name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
-	if (name == NULL)
-		return (-ENOMEM);
-	strcpy(name, buf);
-	ahc = ahc_alloc(NULL, name);
-	if (ahc == NULL)
-		return (-ENOMEM);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-	if (pci_enable_device(pdev)) {
-		ahc_free(ahc);
-		return (-ENODEV);
-	}
-	pci_set_master(pdev);
-
-	if (sizeof(bus_addr_t) > 4
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
-	 && ahc_linux_get_memsize() > 0x80000000
-	 && pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) {
-#else
-	 && ahc_linux_get_memsize() > 0x80000000) {
-
-		ahc->dev_softc->dma_mask = 
-		    (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
-#endif
-		ahc->flags |= AHC_39BIT_ADDRESSING;
-		ahc->platform_data->hw_dma_mask =
-		    (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
-	}
-#endif
-	ahc->dev_softc = pci;
-	ahc->platform_data->irq = pdev->irq;
-	error = ahc_pci_config(ahc, entry);
-	if (error != 0) {
-		ahc_free(ahc);
-		return (-error);
-	}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-	pci_set_drvdata(pdev, ahc);
-	if (aic7xxx_detect_complete)
-		ahc_linux_register_host(ahc, aic7xxx_driver_template);
-#endif
-	return (0);
-}
-
-int
-ahc_linux_pci_probe(Scsi_Host_Template *template)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-	return (pci_module_init(&aic7xxx_pci_driver));
-#else
-	struct pci_dev *pdev;
-	u_int class;
-	int found;
-
-	/* If we don't have a PCI bus, we can't find any adapters. */
-	if (pci_present() == 0)
-		return (0);
-
-	found = 0;
-	pdev = NULL;
-	class = PCI_CLASS_STORAGE_SCSI << 8;
-	while ((pdev = pci_find_class(class, pdev)) != NULL) {
-		ahc_dev_softc_t pci;
-		int error;
-
-		pci = pdev;
-		error = ahc_linux_pci_dev_probe(pdev, /*pci_devid*/NULL);
-		if (error == 0)
-			found++;
-	}
-	return (found);
-#endif
-}
-
-static int
-ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-	*base = pci_resource_start(ahc->dev_softc, 0);
-#else
-	*base = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS, 4);
-	*base &= PCI_BASE_ADDRESS_IO_MASK;
-#endif
-	if (base == 0)
-		return (ENOMEM);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-	if (check_region(*base, 256) != 0)
-		return (ENOMEM);
-	else
-		request_region(*base, 256, "aic7xxx");
-#else
-	if (request_region(*base, 256, "aic7xxx") == 0)
-		return (ENOMEM);
-#endif
-	return (0);
-}
-
-#ifdef MMAPIO
-static int
-ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
-				 u_long *bus_addr,
-				 uint8_t **maddr)
-{
-	u_long	start;
-	u_long	base_page;
-	u_long	base_offset;
-	int	error;
-
-	error = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-	start = pci_resource_start(ahc->dev_softc, 1);
-	base_page = start & PAGE_MASK;
-	base_offset = start - base_page;
-#else
-	start = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS+4, 4);
-	base_offset = start & PCI_BASE_ADDRESS_MEM_MASK;
-	base_page = base_offset & PAGE_MASK;
-	base_offset -= base_page;
-#endif
-	if (start != 0) {
-		*bus_addr = start;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		if (request_mem_region(start, 0x1000, "aic7xxx") == 0)
-			error = ENOMEM;
-#endif
-		if (error == 0) {
-			*maddr = ioremap_nocache(base_page, base_offset + 256);
-			if (*maddr == NULL)
-				error = ENOMEM;
-			else
-				*maddr += base_offset;
-		}
-	} else
-		error = ENOMEM;
-	return (error);
-}
-#endif /* MMAPIO */
-
-int
-ahc_pci_map_registers(struct ahc_softc *ahc)
-{
-	uint32_t command;
-	u_long	 base;
-	uint8_t	*maddr;
-	int	 error;
-	int	 io_error;
-
-	/*
-	 * We always reserve both our register spaces to avoid
-	 * other devices claiming them.
-	 */
-	command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 4);
-	command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
-	base = 0;
-	maddr = NULL;
-#ifdef MMAPIO
-	error = ahc_linux_pci_reserve_mem_region(ahc, &base, &maddr);
-	if (error == 0) {
-		ahc->platform_data->mem_busaddr = base;
-		ahc->tag = BUS_SPACE_MEMIO;
-		ahc->bsh.maddr = maddr;
-		ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
-				     command | PCIM_CMD_MEMEN, 4);
-
-		/*
-		 * Do a quick test to see if memory mapped
-		 * I/O is functioning correctly.
-		 */
-		if (ahc_inb(ahc, HCNTRL) == 0xFF) {
-
-			printf("aic7xxx: PCI Device %d:%d:%d "
-			       "failed memory mapped test\n",
-			       ahc_get_pci_bus(ahc->dev_softc),
-			       ahc_get_pci_slot(ahc->dev_softc),
-			       ahc_get_pci_function(ahc->dev_softc));
-			maddr = NULL;
-		} else
-			command |= PCIM_CMD_MEMEN;
-	} else {
-		printf("aic7xxx: PCI%d:%d:%d MEM region 0x%lx "
-		       "unavailable. Cannot map device.\n",
-		       ahc_get_pci_bus(ahc->dev_softc),
-		       ahc_get_pci_slot(ahc->dev_softc),
-		       ahc_get_pci_function(ahc->dev_softc),
-		       base);
-	}
-#endif
-
-	/*
-	 * We always prefer memory mapped access.  Only
-	 * complain about our ioport conflicting with
-	 * another device if we are going to use it.
-	 */
-	io_error = ahc_linux_pci_reserve_io_region(ahc, &base);
-	if (maddr == NULL) {
-		error = io_error;
-		if (error != 0) {
-			printf("aic7xxx: PCI%d:%d:%d IO region 0x%lx[0..255] "
-			       "unavailable. Cannot map device.\n",
-			       ahc_get_pci_bus(ahc->dev_softc),
-			       ahc_get_pci_slot(ahc->dev_softc),
-			       ahc_get_pci_function(ahc->dev_softc),
-			       base);
-			base = 0;
-		} else {
-			ahc->tag = BUS_SPACE_PIO;
-			ahc->bsh.ioport = base;
-			command |= PCIM_CMD_PORTEN;
-		}
-	}
-	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 4);
-	return (error);
-}
-
-int
-ahc_pci_map_int(struct ahc_softc *ahc)
-{
-	int error;
-
-	ahc->platform_data->irq = ahc->dev_softc->irq;
-	error = request_irq(ahc->platform_data->irq, ahc_linux_isr,
-			    SA_SHIRQ, "aic7xxx", ahc);
-	
-	return (-error);
-}
-
-void
-ahc_power_state_change(struct ahc_softc *ahc, ahc_power_state new_state)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-	pci_set_power_state(ahc->dev_softc, new_state);
-#else
-	uint32_t cap;
-	u_int cap_offset;
-
-	/*
-	 * Traverse the capability list looking for
-	 * the power management capability.
-	 */
-	cap = 0;
-	cap_offset = ahc_pci_read_config(ahc->dev_softc,
-					 PCIR_CAP_PTR, /*bytes*/1);
-	while (cap_offset != 0) {
-
-		cap = ahc_pci_read_config(ahc->dev_softc,
-					  cap_offset, /*bytes*/4);
-		if ((cap & 0xFF) == 1
-		 && ((cap >> 16) & 0x3) > 0) {
-			uint32_t pm_control;
-
-			pm_control = ahc_pci_read_config(ahc->dev_softc,
-							 cap_offset + 4,
-							 /*bytes*/4);
-			pm_control &= ~0x3;
-			pm_control |= new_state;
-			ahc_pci_write_config(ahc->dev_softc,
-					     cap_offset + 4,
-					     pm_control, /*bytes*/2);
-			break;
-		}
-		cap_offset = (cap >> 8) & 0xFF;
-	}
-#endif 
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_osm.c linux/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_osm.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_osm.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,3038 @@
+/*
+ * Adaptec AIC7xxx device driver for Linux.
+ *
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#103 $
+ *
+ * Copyright (c) 1994 John Aycock
+ *   The University of Calgary Department of Computer Science.
+ *
+ * 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, 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; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F
+ * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA
+ * config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide,
+ * the Linux Kernel Hacker's Guide, Writing a SCSI Device Driver for Linux,
+ * the Adaptec 1542 driver (aha1542.c), the Adaptec EISA overlay file
+ * (adp7770.ovl), the Adaptec AHA-2740 Series Technical Reference Manual,
+ * the Adaptec AIC-7770 Data Book, the ANSI SCSI specification, the
+ * ANSI SCSI-2 specification (draft 10c), ...
+ *
+ * --------------------------------------------------------------------------
+ *
+ *  Modifications by Daniel M. Eischen (deischen@iworks.InterWorks.org):
+ *
+ *  Substantially modified to include support for wide and twin bus
+ *  adapters, DMAing of SCBs, tagged queueing, IRQ sharing, bug fixes,
+ *  SCB paging, and other rework of the code.
+ *
+ * --------------------------------------------------------------------------
+ * Copyright (c) 1994-2000 Justin T. Gibbs.
+ * Copyright (c) 2000-2001 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ *---------------------------------------------------------------------------
+ *
+ *  Thanks also go to (in alphabetical order) the following:
+ *
+ *    Rory Bolt     - Sequencer bug fixes
+ *    Jay Estabrook - Initial DEC Alpha support
+ *    Doug Ledford  - Much needed abort/reset bug fixes
+ *    Kai Makisara  - DMAing of SCBs
+ *
+ *  A Boot time option was also added for not resetting the scsi bus.
+ *
+ *    Form:  aic7xxx=extended
+ *           aic7xxx=no_reset
+ *           aic7xxx=verbose
+ *
+ *  Daniel M. Eischen, deischen@iworks.InterWorks.org, 1/23/97
+ *
+ *  Id: aic7xxx.c,v 4.1 1997/06/12 08:23:42 deang Exp
+ */
+
+/*
+ * Further driver modifications made by Doug Ledford <dledford@redhat.com>
+ *
+ * Copyright (c) 1997-1999 Doug Ledford
+ *
+ * These changes are released under the same licensing terms as the FreeBSD
+ * driver written by Justin Gibbs.  Please see his Copyright notice above
+ * for the exact terms and conditions covering my changes as well as the
+ * warranty statement.
+ *
+ * Modifications made to the aic7xxx.c,v 4.1 driver from Dan Eischen include
+ * but are not limited to:
+ *
+ *  1: Import of the latest FreeBSD sequencer code for this driver
+ *  2: Modification of kernel code to accomodate different sequencer semantics
+ *  3: Extensive changes throughout kernel portion of driver to improve
+ *     abort/reset processing and error hanndling
+ *  4: Other work contributed by various people on the Internet
+ *  5: Changes to printk information and verbosity selection code
+ *  6: General reliability related changes, especially in IRQ management
+ *  7: Modifications to the default probe/attach order for supported cards
+ *  8: SMP friendliness has been improved
+ *
+ */
+
+/*
+ * This is the only file where module.h should
+ * embed module global version info.
+ */
+#define AHC_MODVERSION_FILE
+
+#include "aic7xxx_osm.h"
+#include "aic7xxx_inline.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+#include <linux/init.h>		/* __setup */
+#endif
+
+#include "../sd.h"		/* For geometry detection */
+
+#include <linux/mm.h>		/* For fetching system memory size */
+#include <linux/blk.h>		/* For block_size() */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
+/*
+ * Lock protecting manipulation of the ahc softc list.
+ */
+spinlock_t ahc_list_spinlock;
+#endif
+
+/*
+ * To generate the correct addresses for the controller to issue
+ * on the bus.  Originally added for DEC Alpha support.
+ */
+#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a))
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+struct proc_dir_entry proc_scsi_aic7xxx = {
+	PROC_SCSI_AIC7XXX, 7, "aic7xxx",
+	S_IFDIR | S_IRUGO | S_IXUGO, 2,
+	0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+#endif
+
+/*
+ * Set this to the delay in seconds after SCSI bus reset.
+ * Note, we honor this only for the initial bus reset.
+ * The scsi error recovery code performs its own bus settle
+ * delay handling for error recovery actions.
+ */
+#ifdef CONFIG_AIC7XXX_RESET_DELAY_MS
+#define AIC7XXX_RESET_DELAY CONFIG_AIC7XXX_RESET_DELAY_MS
+#else
+#define AIC7XXX_RESET_DELAY 5000
+#endif
+
+/*
+ * Control collection of SCSI transfer statistics for the /proc filesystem.
+ *
+ * NOTE: Do NOT enable this when running on kernels version 1.2.x and below.
+ * NOTE: This does affect performance since it has to maintain statistics.
+ */
+#ifdef CONFIG_AIC7XXX_PROC_STATS
+#define AIC7XXX_PROC_STATS
+#endif
+
+/*
+ * To change the default number of tagged transactions allowed per-device,
+ * add a line to the lilo.conf file like:
+ * append="aic7xxx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}"
+ * which will result in the first four devices on the first two
+ * controllers being set to a tagged queue depth of 32.
+ *
+ * The tag_commands is an array of 16 to allow for wide and twin adapters.
+ * Twin adapters will use indexes 0-7 for channel 0, and indexes 8-15
+ * for channel 1.
+ */
+typedef struct {
+	uint8_t tag_commands[16];	/* Allow for wide/twin adapters. */
+} adapter_tag_info_t;
+
+/*
+ * Modify this as you see fit for your system.
+ *
+ * 0			tagged queuing disabled
+ * 1 <= n <= 253	n == max tags ever dispatched.
+ *
+ * The driver will throttle the number of commands dispatched to a
+ * device if it returns queue full.  For devices with a fixed maximum
+ * queue depth, the driver will eventually determine this depth and
+ * lock it in (a console message is printed to indicate that a lock
+ * has occurred).  On some devices, queue full is returned for a temporary
+ * resource shortage.  These devices will return queue full at varying
+ * depths.  The driver will throttle back when the queue fulls occur and
+ * attempt to slowly increase the depth over time as the device recovers
+ * from the resource shortage.
+ *
+ * In this example, the first line will disable tagged queueing for all
+ * the devices on the first probed aic7xxx adapter.
+ *
+ * The second line enables tagged queueing with 4 commands/LUN for IDs
+ * (0, 2-11, 13-15), disables tagged queueing for ID 12, and tells the
+ * driver to attempt to use up to 64 tags for ID 1.
+ *
+ * The third line is the same as the first line.
+ *
+ * The fourth line disables tagged queueing for devices 0 and 3.  It
+ * enables tagged queueing for the other IDs, with 16 commands/LUN
+ * for IDs 1 and 4, 127 commands/LUN for ID 8, and 4 commands/LUN for
+ * IDs 2, 5-7, and 9-15.
+ */
+
+/*
+ * NOTE: The below structure is for reference only, the actual structure
+ *       to modify in order to change things is just below this comment block.
+adapter_tag_info_t aic7xxx_tag_info[] =
+{
+	{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+	{{4, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4}},
+	{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+	{{0, 16, 4, 0, 16, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4}}
+};
+*/
+
+#ifdef CONFIG_AIC7XXX_CMDS_PER_DEVICE
+#define AIC7XXX_CMDS_PER_DEVICE CONFIG_AIC7XXX_CMDS_PER_DEVICE
+#else
+#define AIC7XXX_CMDS_PER_DEVICE AHC_MAX_QUEUE
+#endif
+
+#define AIC7XXX_CONFIGED_TAG_COMMANDS {					\
+	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
+	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
+	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
+	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
+	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
+	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
+	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE,		\
+	AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE		\
+}
+
+/*
+ * By default, use the number of commands specified by
+ * the users kernel configuration.
+ */
+static adapter_tag_info_t aic7xxx_tag_info[] =
+{
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS},
+	{AIC7XXX_CONFIGED_TAG_COMMANDS}
+};
+
+/*
+ * There should be a specific return value for this in scsi.h, but
+ * it seems that most drivers ignore it.
+ */
+#define DID_UNDERFLOW   DID_ERROR
+
+void
+ahc_print_path(struct ahc_softc *ahc, struct scb *scb)
+{
+	printk("(scsi%d:%c:%d:%d): ",
+	       ahc->platform_data->host->host_no,
+	       scb != NULL ? SCB_GET_CHANNEL(ahc, scb) : 'X',
+	       scb != NULL ? SCB_GET_TARGET(ahc, scb) : -1,
+	       scb != NULL ? SCB_GET_LUN(scb) : -1);
+}
+
+/*
+ * XXX - these options apply unilaterally to _all_ 274x/284x/294x
+ *       cards in the system.  This should be fixed.  Exceptions to this
+ *       rule are noted in the comments.
+ */
+
+/*
+ * Skip the scsi bus reset.  Non 0 make us skip the reset at startup.  This
+ * has no effect on any later resets that might occur due to things like
+ * SCSI bus timeouts.
+ */
+static uint32_t aic7xxx_no_reset;
+
+/*
+ * Certain PCI motherboards will scan PCI devices from highest to lowest,
+ * others scan from lowest to highest, and they tend to do all kinds of
+ * strange things when they come into contact with PCI bridge chips.  The
+ * net result of all this is that the PCI card that is actually used to boot
+ * the machine is very hard to detect.  Most motherboards go from lowest
+ * PCI slot number to highest, and the first SCSI controller found is the
+ * one you boot from.  The only exceptions to this are when a controller
+ * has its BIOS disabled.  So, we by default sort all of our SCSI controllers
+ * from lowest PCI slot number to highest PCI slot number.  We also force
+ * all controllers with their BIOS disabled to the end of the list.  This
+ * works on *almost* all computers.  Where it doesn't work, we have this
+ * option.  Setting this option to non-0 will reverse the order of the sort
+ * to highest first, then lowest, but will still leave cards with their BIOS
+ * disabled at the very end.  That should fix everyone up unless there are
+ * really strange cirumstances.
+ */
+static int aic7xxx_reverse_scan = 0;
+
+/*
+ * Should we force EXTENDED translation on a controller.
+ *     0 == Use whatever is in the SEEPROM or default to off
+ *     1 == Use whatever is in the SEEPROM or default to on
+ */
+static uint32_t aic7xxx_extended = 0;
+
+/*
+ * PCI bus parity checking of the Adaptec controllers.  This is somewhat
+ * dubious at best.  To my knowledge, this option has never actually
+ * solved a PCI parity problem, but on certain machines with broken PCI
+ * chipset configurations, it can generate tons of false error messages.
+ * It's included in the driver for completeness.
+ *   0 = Shut off PCI parity check
+ *  -1 = Normal polarity pci parity checking
+ *   1 = reverse polarity pci parity checking
+ *
+ * NOTE: you can't actually pass -1 on the lilo prompt.  So, to set this
+ * variable to -1 you would actually want to simply pass the variable
+ * name without a number.  That will invert the 0 which will result in
+ * -1.
+ */
+static int aic7xxx_pci_parity = 0;
+
+/*
+ * Certain newer motherboards have put new PCI based devices into the
+ * IO spaces that used to typically be occupied by VLB or EISA cards.
+ * This overlap can cause these newer motherboards to lock up when scanned
+ * for older EISA and VLB devices.  Setting this option to non-0 will
+ * cause the driver to skip scanning for any VLB or EISA controllers and
+ * only support the PCI controllers.  NOTE: this means that if the kernel
+ * os compiled with PCI support disabled, then setting this to non-0
+ * would result in never finding any devices :)
+ */
+#ifndef CONFIG_AIC7XXX_PROBE_EISA_VL
+#define CONFIG_AIC7XXX_PROBE_EISA_VL n
+#endif
+#if CONFIG_AIC7XXX_PROBE_EISA_VL == n
+static int aic7xxx_no_probe = 1;
+#else
+static int aic7xxx_no_probe;
+#endif
+
+/*
+ * aic7xxx_detect() has been run, so register all device arrivals
+ * immediately with the system rather than deferring to the sorted
+ * attachment performed by aic7xxx_detect().
+ */
+int aic7xxx_detect_complete;
+
+/*
+ * So that we can set how long each device is given as a selection timeout.
+ * The table of values goes like this:
+ *   0 - 256ms
+ *   1 - 128ms
+ *   2 - 64ms
+ *   3 - 32ms
+ * We default to 256ms because some older devices need a longer time
+ * to respond to initial selection.
+ */
+static int aic7xxx_seltime = 0x00;
+
+/*
+ * Certain devices do not perform any aging on commands.  Should the
+ * device be saturated by commands in one portion of the disk, it is
+ * possible for transactions on far away sectors to never be serviced.
+ * To handle these devices, we can periodically send an ordered tag to
+ * force all outstanding transactions to be serviced prior to a new
+ * transaction.
+ */
+int aic7xxx_periodic_otag;
+
+/*
+ * Module information and settable options.
+ */
+#ifdef MODULE
+static char *aic7xxx = NULL;
+/*
+ * Just in case someone uses commas to separate items on the insmod
+ * command line, we define a dummy buffer here to avoid having insmod
+ * write wild stuff into our code segment
+ */
+static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";
+
+MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
+MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver");
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)
+MODULE_LICENSE("Dual BSD/GPL");
+#endif
+MODULE_PARM(aic7xxx, "s");
+MODULE_PARM_DESC(aic7xxx, "period delimited, options string.
+	verbose			Enable verbose/diagnostic logging
+	no_probe		Disable EISA/VLB controller probing
+	no_reset		Supress initial bus resets
+	extended		Enable extended geometry on all controllers
+	periodic_otag		Send an ordered tagged transaction periodically
+				to prevent tag starvation.  This may be
+				required by some older disk drives/RAID arrays. 
+	reverse_scan		Sort PCI devices highest Bus/Slot to lowest
+	tag_info:<tag_str>	Set per-target tag depth
+	seltime:<int>		Selection Timeout(0/256ms,1/128ms,2/64ms,3/32ms)
+
+	Sample /etc/modules.conf line:
+		Enable verbose logging
+		Disable EISA/VLB probing
+		Set tag depth on Controller 2/Target 2 to 10 tags
+		Shorten the selection timeout to 128ms from its default of 256
+
+	options aic7xxx='\"verbose.no_probe.tag_info:{{}.{}.{..10}}.seltime:1\"'
+");
+#endif
+
+static void ahc_linux_handle_scsi_status(struct ahc_softc *,
+					 struct ahc_linux_device *,
+					 struct scb *);
+static void ahc_linux_filter_command(struct ahc_softc*, Scsi_Cmnd*,
+				     struct scb*);
+static void ahc_linux_sem_timeout(u_long arg);
+static void ahc_linux_freeze_sim_queue(struct ahc_softc *ahc);
+static void ahc_linux_release_sim_queue(u_long arg);
+static void ahc_linux_dev_timed_unfreeze(u_long arg);
+static int  ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag);
+static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
+static void ahc_linux_select_queue_depth(struct Scsi_Host *host,
+					 Scsi_Device *scsi_devs);
+static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
+				     struct ahc_devinfo *devinfo);
+static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
+					 Scsi_Device *device);
+static struct ahc_linux_target*	ahc_linux_alloc_target(struct ahc_softc*,
+						       u_int, u_int);
+static void			ahc_linux_free_target(struct ahc_softc*,
+						      struct ahc_linux_target*);
+static struct ahc_linux_device*	ahc_linux_alloc_device(struct ahc_softc*,
+						       struct ahc_linux_target*,
+						       u_int);
+static void			ahc_linux_free_device(struct ahc_softc*,
+						      struct ahc_linux_device*);
+static void ahc_linux_run_device_queue(struct ahc_softc*,
+				       struct ahc_linux_device*);
+static void ahc_linux_setup_tag_info(char *p, char *end);
+static int ahc_linux_next_unit(void);
+static void ahc_runq_tasklet(unsigned long data);
+static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf);
+
+static __inline struct ahc_linux_device*
+		     ahc_linux_get_device(struct ahc_softc *ahc, u_int channel,
+					  u_int target, u_int lun, int alloc);
+static __inline void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
+						  Scsi_Cmnd *cmd);
+static __inline void ahc_linux_run_complete_queue(struct ahc_softc *ahc,
+						  struct ahc_cmd *acmd);
+static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc,
+						  struct ahc_linux_device *dev);
+static __inline struct ahc_linux_device *
+		     ahc_linux_next_device_to_run(struct ahc_softc *ahc);
+static __inline void ahc_linux_run_device_queues(struct ahc_softc *ahc);
+static __inline void ahc_linux_sniff_command(struct ahc_softc*, Scsi_Cmnd*,
+					     struct scb*);
+static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
+
+static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
+		 		      struct ahc_dma_seg *sg,
+				      bus_addr_t addr, bus_size_t len);
+
+static __inline struct ahc_linux_device*
+ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
+	       u_int lun, int alloc)
+{
+	struct ahc_linux_target *targ;
+	struct ahc_linux_device *dev;
+	u_int target_offset;
+
+	target_offset = target;
+	if (channel != 0)
+		target_offset += 8;
+	targ = ahc->platform_data->targets[target_offset];
+	if (targ == NULL) {
+		if (alloc != 0) {
+			targ = ahc_linux_alloc_target(ahc, channel, target);
+			if (targ == NULL)
+				return (NULL);
+		} else
+			return (NULL);
+	}
+	dev = targ->devices[lun];
+	if (dev == NULL && alloc != 0)
+		dev = ahc_linux_alloc_device(ahc, targ, lun);
+	return (dev);
+}
+
+static __inline void
+ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd)
+{
+	/*
+	 * Typically, the complete queue has very few entries
+	 * queued to it before the queue is emptied by
+	 * ahc_linux_run_complete_queue, so sorting the entries
+	 * by generation number should be inexpensive.
+	 * We perform the sort so that commands that complete
+	 * with an error are retuned in the order origionally
+	 * queued to the controller so that any subsequent retries
+	 * are performed in order.  The underlying ahc routines do
+	 * not guarantee the order that aborted commands will be
+	 * returned to us.
+	 */
+	struct ahc_completeq *completeq;
+	struct ahc_cmd *list_cmd;
+	struct ahc_cmd *acmd;
+
+	/*
+	 * If we want the request requeued, make sure there
+	 * are sufficent retries.  In the old scsi error code,
+	 * we used to be able to specify a result code that
+	 * bypassed the retry count.  Now we must use this
+	 * hack.
+	 */
+	if (cmd->result == (CAM_REQUEUE_REQ << 16))
+		cmd->retries--;
+	completeq = &ahc->platform_data->completeq;
+	list_cmd = TAILQ_FIRST(completeq);
+	acmd = (struct ahc_cmd *)cmd;
+	while (list_cmd != NULL
+	    && acmd_scsi_cmd(list_cmd).serial_number
+	     < acmd_scsi_cmd(acmd).serial_number)
+		list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe);
+	if (list_cmd != NULL)
+		TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe);
+	else
+		TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe);
+}
+
+static __inline void
+ahc_linux_run_complete_queue(struct ahc_softc *ahc, struct ahc_cmd *acmd)
+{	
+	u_long done_flags;
+
+	ahc_done_lock(ahc, &done_flags);
+	while (acmd != NULL) {
+		Scsi_Cmnd *cmd;
+
+		cmd = &acmd_scsi_cmd(acmd);
+		acmd = TAILQ_NEXT(acmd, acmd_links.tqe);
+		cmd->host_scribble = NULL;
+		cmd->scsi_done(cmd);
+	}
+	ahc_done_unlock(ahc, &done_flags);
+}
+
+static __inline void
+ahc_linux_check_device_queue(struct ahc_softc *ahc,
+			     struct ahc_linux_device *dev)
+{
+	if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) != 0
+	 && dev->active == 0) {
+		dev->flags &= ~AHC_DEV_FREEZE_TIL_EMPTY;
+		dev->qfrozen--;
+	}
+
+	if (TAILQ_FIRST(&dev->busyq) == NULL
+	 || dev->openings == 0 || dev->qfrozen != 0)
+		return;
+
+	ahc_linux_run_device_queue(ahc, dev);
+}
+
+static __inline struct ahc_linux_device *
+ahc_linux_next_device_to_run(struct ahc_softc *ahc)
+{
+	
+	if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0
+	 || ahc->platform_data->qfrozen != 0)
+		return (NULL);
+	return (TAILQ_FIRST(&ahc->platform_data->device_runq));
+}
+
+static __inline void
+ahc_linux_run_device_queues(struct ahc_softc *ahc)
+{
+	struct ahc_linux_device *dev;
+
+	while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) {
+		TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
+		dev->flags &= ~AHC_DEV_ON_RUN_LIST;
+		ahc_linux_check_device_queue(ahc, dev);
+	}
+}
+
+static __inline void
+ahc_linux_sniff_command(struct ahc_softc *ahc, Scsi_Cmnd *cmd, struct scb *scb)
+{
+	/*
+	 * Determine whether we care to filter
+	 * information out of this command.  If so,
+	 * pass it on to ahc_linux_filter_command() for more
+	 * heavy weight processing.
+	 */
+	if (cmd->cmnd[0] == INQUIRY)
+		ahc_linux_filter_command(ahc, cmd, scb);
+}
+
+static __inline void
+ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
+{
+	Scsi_Cmnd *cmd;
+
+	cmd = scb->io_ctx;
+	ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE);
+	if (cmd->use_sg != 0) {
+		struct scatterlist *sg;
+
+		sg = (struct scatterlist *)cmd->request_buffer;
+		pci_unmap_sg(ahc->dev_softc, sg, cmd->use_sg,
+			     scsi_to_pci_dma_dir(cmd->sc_data_direction));
+	} else if (cmd->request_bufflen != 0) {
+		pci_unmap_single(ahc->dev_softc,
+				 scb->platform_data->buf_busaddr,
+				 cmd->request_bufflen,
+				 scsi_to_pci_dma_dir(cmd->sc_data_direction));
+	}
+}
+
+static __inline int
+ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
+		  struct ahc_dma_seg *sg, bus_addr_t addr, bus_size_t len)
+{
+	int	 consumed;
+
+	if ((scb->sg_count + 1) > AHC_NSEG)
+		panic("Too few segs for dma mapping.  "
+		      "Increase AHC_NSEG\n");
+
+	consumed = 1;
+	sg->addr = ahc_htole32(addr & 0xFFFFFFFF);
+	scb->platform_data->xfer_len += len;
+	if (sizeof(bus_addr_t) > 4
+	 && (ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
+		/*
+		 * Due to DAC restrictions, we can't
+		 * cross a 4GB boundary.
+		 */
+		if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) {
+			struct	 ahc_dma_seg *next_sg;
+			uint32_t next_len;
+
+			printf("Crossed Seg\n");
+			if ((scb->sg_count + 2) > AHC_NSEG)
+				panic("Too few segs for dma mapping.  "
+				      "Increase AHC_NSEG\n");
+
+			consumed++;
+			next_sg = sg + 1;
+			next_sg->addr = 0;
+			next_len = 0x100000000 - (addr & 0xFFFFFFFF);
+			len -= next_len;
+			next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000;
+			next_sg->len = ahc_htole32(next_len);
+		}
+		len |= (addr >> 8) & 0x7F000000;
+	}
+	sg->len = ahc_htole32(len);
+	return (consumed);
+}
+
+/**************************** Tasklet Handler *********************************/
+
+static void
+ahc_runq_tasklet(unsigned long data)
+{
+	struct ahc_softc* ahc;
+	struct ahc_linux_device *dev;
+	u_long flags;
+
+	ahc = (struct ahc_softc *)data;
+	ahc_lock(ahc, &flags);
+	while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) {
+	
+		TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
+		dev->flags &= ~AHC_DEV_ON_RUN_LIST;
+		ahc_linux_check_device_queue(ahc, dev);
+		/* Yeild to our interrupt handler */
+		ahc_unlock(ahc, &flags);
+		ahc_lock(ahc, &flags);
+	}
+	ahc_unlock(ahc, &flags);
+}
+
+/************************ Shutdown/halt/reboot hook ***************************/
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+static struct notifier_block ahc_linux_notifier = {
+	ahc_linux_halt, NULL, 0
+};
+
+static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf)
+{
+	struct ahc_softc *ahc;
+
+	if (event == SYS_DOWN || event == SYS_HALT) {
+		TAILQ_FOREACH(ahc, &ahc_tailq, links) {
+			ahc_shutdown(ahc);
+		}
+	}
+	return (NOTIFY_OK);
+}
+
+/******************************** Macros **************************************/
+#define BUILD_SCSIID(ahc, cmd)						\
+	((((cmd)->target << TID_SHIFT) & TID)				\
+	| (((cmd)->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b)	\
+	| (((cmd)->channel == 0) ? 0 : TWIN_CHNLB))
+
+/******************************** Bus DMA *************************************/
+int
+ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
+		   bus_size_t alignment, bus_size_t boundary,
+		   bus_addr_t lowaddr, bus_addr_t highaddr,
+		   bus_dma_filter_t *filter, void *filterarg,
+		   bus_size_t maxsize, int nsegments,
+		   bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
+{
+	bus_dma_tag_t dmat;
+
+	dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
+	if (dmat == NULL)
+		return (ENOMEM);
+
+	/*
+	 * Linux is very simplistic about DMA memory.  For now don't
+	 * maintain all specification information.  Once Linux supplies
+	 * better facilities for doing these operations, or the
+	 * needs of this particular driver change, we might need to do
+	 * more here.
+	 */
+	dmat->alignment = alignment;
+	dmat->boundary = boundary;
+	dmat->maxsize = maxsize;
+	*ret_tag = dmat;
+	return (0);
+}
+
+void
+ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat)
+{
+	free(dmat, M_DEVBUF);
+}
+
+int
+ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr,
+		 int flags, bus_dmamap_t *mapp)
+{
+	bus_dmamap_t map;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
+	if (map == NULL)
+		return (ENOMEM);
+	/*
+	 * Although we can dma data above 4GB, our
+	 * "consistent" memory is below 4GB for
+	 * space efficiency reasons (only need a 4byte
+	 * address).  For this reason, we have to reset
+	 * our dma mask when doing allocations.
+	 */
+	if (ahc->dev_softc != NULL) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
+		pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF);
+#else
+		ahc->dev_softc->dma_mask = 0xFFFFFFFF;
+#endif
+	}
+	*vaddr = pci_alloc_consistent(ahc->dev_softc,
+				      dmat->maxsize, &map->bus_addr);
+	if (ahc->dev_softc != NULL) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
+		pci_set_dma_mask(ahc->dev_softc,
+				 ahc->platform_data->hw_dma_mask);
+#else
+		ahc->dev_softc->dma_mask = ahc->platform_data->hw_dma_mask;
+#endif
+	}
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */
+	/*
+	 * At least in 2.2.14, malloc is a slab allocator so all
+	 * allocations are aligned.  We assume for these kernel versions
+	 * that all allocations will be bellow 4Gig, physically contiguous,
+	 * and accessable via DMA by the controller.
+	 */
+	map = NULL; /* No additional information to store */
+	*vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT);
+#endif
+	if (*vaddr == NULL)
+		return (ENOMEM);
+	*mapp = map;
+	return(0);
+}
+
+void
+ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat,
+		void* vaddr, bus_dmamap_t map)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	pci_free_consistent(ahc->dev_softc, dmat->maxsize,
+			    vaddr, map->bus_addr);
+#else
+	free(vaddr, M_DEVBUF);
+#endif
+}
+
+int
+ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
+		void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
+		void *cb_arg, int flags)
+{
+	/*
+	 * Assume for now that this will only be used during
+	 * initialization and not for per-transaction buffer mapping.
+	 */
+	bus_dma_segment_t stack_sg;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	stack_sg.ds_addr = map->bus_addr;
+#else
+	stack_sg.ds_addr = VIRT_TO_BUS(buf);
+#endif
+	stack_sg.ds_len = dmat->maxsize;
+	cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0);
+	return (0);
+}
+
+void
+ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+	/*
+	 * The map may is NULL in our < 2.3.X implementation.
+	 */
+	if (map != NULL)
+		free(map, M_DEVBUF);
+}
+
+int
+ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+	/* Nothing to do */
+	return (0);
+}
+
+/********************* Platform Dependent Functions ***************************/
+int
+ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
+{
+	int	value;
+	int	rvalue;
+	int	lvalue;
+
+	/*
+	 * Under Linux, cards are ordered as follows:
+	 *	1) VLB/EISA BIOS enabled devices sorted by BIOS address.
+	 *	2) PCI devices with BIOS enabled sorted by bus/slot/func.
+	 *	3) All remaining VLB/EISA devices sorted by ioport.
+	 *	4) All remaining PCI devices sorted by bus/slot/func.
+	 */
+	value = (lahc->flags & AHC_BIOS_ENABLED)
+	      - (rahc->flags & AHC_BIOS_ENABLED);
+	if (value != 0)
+		/* Controllers with BIOS enabled have a *higher* priority */
+		return (-value);
+
+	/*
+	 * Same BIOS setting, now sort based on bus type.
+	 * EISA and VL controllers sort together.  EISA/VL
+	 * have higher priority than PCI.
+	 */
+	rvalue = (rahc->chip & AHC_BUS_MASK);
+ 	if (rvalue == AHC_VL)
+		rvalue = AHC_EISA;
+	lvalue = (lahc->chip & AHC_BUS_MASK);
+ 	if (lvalue == AHC_VL)
+		lvalue = AHC_EISA;
+	value = lvalue - rvalue;
+	if (value != 0)
+		return (value);
+
+	/* Still equal.  Sort by BIOS address, ioport, or bus/slot/func. */
+	switch (rvalue) {
+	case AHC_PCI:
+	{
+		char primary_channel;
+
+		if (aic7xxx_reverse_scan != 0)
+			value = ahc_get_pci_bus(rahc->dev_softc)
+			      - ahc_get_pci_bus(lahc->dev_softc);
+		else
+			value = ahc_get_pci_bus(lahc->dev_softc)
+			      - ahc_get_pci_bus(rahc->dev_softc);
+		if (value != 0)
+			break;
+		if (aic7xxx_reverse_scan != 0)
+			value = ahc_get_pci_slot(rahc->dev_softc)
+			      - ahc_get_pci_slot(lahc->dev_softc);
+		else
+			value = ahc_get_pci_slot(lahc->dev_softc)
+			      - ahc_get_pci_slot(rahc->dev_softc);
+		if (value != 0)
+			break;
+		/*
+		 * On multi-function devices, the user can choose
+		 * to have function 1 probed before function 0.
+		 * Give whichever channel is the primary channel
+		 * the lowest priority.
+		 */
+		primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A';
+		value = 1;
+		if (lahc->channel == primary_channel)
+			value = -1;
+		break;
+	}
+	case AHC_EISA:
+		if ((rahc->flags & AHC_BIOS_ENABLED) != 0) {
+			value = lahc->platform_data->bios_address
+			      - rahc->platform_data->bios_address; 
+		} else {
+			value = lahc->bsh.ioport
+			      - rahc->bsh.ioport; 
+		}
+		break;
+	default:
+		panic("ahc_softc_sort: invalid bus type");
+	}
+	return (value);
+}
+
+static void
+ahc_linux_setup_tag_info(char *p, char *end)
+{
+	char	*base;
+	char	*tok;
+	char	*tok_end;
+	char	*tok_end2;
+	int      i;
+	int      instance;
+	int	 targ;
+	int	 done;
+	char	 tok_list[] = {'.', ',', '{', '}', '\0'};
+
+	if (*p != ':')
+		return;
+
+	instance = -1;
+	targ = -1;
+	done = FALSE;
+	base = p;
+	/* Forward us just past the ':' */
+	tok = base + 1;
+	tok_end = strchr(tok, '\0');
+	if (tok_end < end)
+		*tok_end = ',';
+	while (!done) {
+		switch (*tok) {
+		case '{':
+			if (instance == -1)
+				instance = 0;
+			else if (targ == -1)
+				targ = 0;
+			tok++;
+			break;
+		case '}':
+			if (targ != -1)
+				targ = -1;
+			else if (instance != -1)
+				instance = -1;
+			tok++;
+			break;
+		case ',':
+		case '.':
+			if (instance == -1)
+				done = TRUE;
+			else if (targ >= 0)
+				targ++;
+			else if (instance >= 0)
+				instance++;
+			if ((targ >= AHC_NUM_TARGETS) ||
+			    (instance >= NUM_ELEMENTS(aic7xxx_tag_info)))
+				done = TRUE;
+			tok++;
+			if (!done) {
+				base = tok;
+			}
+			break;
+		case '\0':
+			done = TRUE;
+			break;
+		default:
+			done = TRUE;
+			tok_end = strchr(tok, '\0');
+			for (i = 0; tok_list[i]; i++) {
+				tok_end2 = strchr(tok, tok_list[i]);
+				if ((tok_end2) && (tok_end2 < tok_end)) {
+					tok_end = tok_end2;
+					done = FALSE;
+				}
+			}
+			if ((instance >= 0) && (targ >= 0)
+			 && (instance < NUM_ELEMENTS(aic7xxx_tag_info))
+			 && (targ < AHC_NUM_TARGETS)) {
+				aic7xxx_tag_info[instance].tag_commands[targ] =
+				    simple_strtoul(tok, NULL, 0) & 0xff;
+			}
+			tok = tok_end;
+			break;
+		}
+	}
+	while ((p != base) && (p != NULL))
+		p = strtok(NULL, ",.");
+}
+
+/*
+ * Handle Linux boot parameters. This routine allows for assigning a value
+ * to a parameter with a ':' between the parameter and the value.
+ * ie. aic7xxx=stpwlev:1,extended
+ */
+int
+aic7xxx_setup(char *s)
+{
+	int	i, n;
+	char   *p;
+	char   *end;
+
+	static struct {
+		const char *name;
+		uint32_t *flag;
+	} options[] = {
+		{ "extended", &aic7xxx_extended },
+		{ "no_reset", &aic7xxx_no_reset },
+		{ "verbose", &aic7xxx_verbose },
+		{ "reverse_scan", &aic7xxx_reverse_scan },
+		{ "no_probe", &aic7xxx_no_probe },
+		{ "periodic_otag", &aic7xxx_periodic_otag },
+		{ "pci_parity", &aic7xxx_pci_parity },
+		{ "seltime", &aic7xxx_seltime },
+		{ "tag_info", NULL }
+	};
+
+	end = strchr(s, '\0');
+
+	for (p = strtok(s, ",."); p; p = strtok(NULL, ",.")) {
+		for (i = 0; i < NUM_ELEMENTS(options); i++) {
+			n = strlen(options[i].name);
+
+			if (strncmp(options[i].name, p, n) != 0)
+				continue;
+
+			if (strncmp(p, "tag_info", n) == 0) {
+				ahc_linux_setup_tag_info(p + n, end);
+			} else if (p[n] == ':') {
+				*(options[i].flag) =
+				    simple_strtoul(p + n + 1, NULL, 0);
+			} else if (!strncmp(p, "verbose", n)) {
+				*(options[i].flag) = 1;
+			} else {
+				*(options[i].flag) = ~(*(options[i].flag));
+			}
+			break;
+		}
+	}
+	return 1;
+}
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)
+__setup("aic7xxx=", aic7xxx_setup);
+#endif
+
+int aic7xxx_verbose;
+
+/*
+ * Try to detect an Adaptec 7XXX controller.
+ */
+int
+ahc_linux_detect(Scsi_Host_Template *template)
+{
+	struct	ahc_softc *ahc;
+	int     found;
+
+	/*
+	 * It is a bug that the upper layer takes
+	 * this lock just prior to calling us.
+	 */
+	spin_unlock_irq(&io_request_lock);
+
+	/*
+	 * Sanity checking of Linux SCSI data structures so
+	 * that some of our hacks^H^H^H^H^Hassumptions aren't
+	 * violated.
+	 */
+	if (offsetof(struct ahc_cmd_internal, end)
+	  > offsetof(struct scsi_cmnd, host_scribble)) {
+		printf("ahc_linux_detect: SCSI data structures changed.\n");
+		printf("ahc_linux_detect: Unable to attach\n");
+		return (0);
+	}
+#ifdef MODULE
+	/*
+	 * If we've been passed any parameters, process them now.
+	 */
+	if (aic7xxx)
+		aic7xxx_setup(aic7xxx);
+	if (dummy_buffer[0] != 'P')
+		printk(KERN_WARNING
+"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n"
+"aic7xxx: to see the proper way to specify options to the aic7xxx module\n"
+"aic7xxx: Specifically, don't use any commas when passing arguments to\n"
+"aic7xxx: insmod or else it might trash certain memory areas.\n");
+#endif
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)
+	template->proc_name = "aic7xxx";
+#else
+	template->proc_dir = &proc_scsi_aic7xxx;
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
+	/*
+	 * We can only map 16MB per-SG
+	 * so create a sector limit of
+	 * "16MB" in 2K sectors.
+	 */
+	template->max_sectors = 8192;
+#endif
+
+	/*
+	 * Initialize our softc list lock prior to
+	 * probing for any adapters.
+	 */
+	ahc_list_lockinit();
+
+#ifdef CONFIG_PCI
+	ahc_linux_pci_probe(template);
+#endif
+
+	if (aic7xxx_no_probe == 0)
+		aic7770_linux_probe(template);
+
+	/*
+	 * Register with the SCSI layer all
+	 * controllers we've found.
+	 */
+	spin_lock_irq(&io_request_lock);
+	found = 0;
+	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
+
+		if (ahc_linux_register_host(ahc, template) == 0)
+			found++;
+	}
+	aic7xxx_detect_complete++;
+	return (found);
+}
+
+int
+ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
+{
+	char  buf[80];
+	struct Scsi_Host *host;
+	char *new_name;
+	u_long s;
+
+
+	template->name = ahc->description;
+	host = scsi_register(template, sizeof(struct ahc_softc *));
+	if (host == NULL)
+		return (ENOMEM);
+
+	ahc_lock(ahc, &s);
+	*((struct ahc_softc **)host->hostdata) = ahc;
+	ahc->platform_data->host = host;
+	host->can_queue = AHC_MAX_QUEUE;
+	host->cmd_per_lun = 2;
+	host->sg_tablesize = AHC_NSEG;
+	host->select_queue_depths = ahc_linux_select_queue_depth;
+	/* XXX No way to communicate the ID for multiple channels */
+	host->this_id = ahc->our_id;
+	host->irq = ahc->platform_data->irq;
+	host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
+	host->max_lun = AHC_NUM_LUNS;
+	host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
+	ahc_set_unit(ahc, ahc_linux_next_unit());
+	sprintf(buf, "scsi%d", host->host_no);
+	new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+	if (new_name != NULL) {
+		strcpy(new_name, buf);
+		ahc_set_name(ahc, new_name);
+	}
+	host->unique_id = ahc->unit;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
+	scsi_set_pci_device(host, ahc->dev_softc);
+#endif
+	ahc_linux_initialize_scsi_bus(ahc);
+	ahc_unlock(ahc, &s);
+	return (0);
+}
+
+uint64_t
+ahc_linux_get_memsize()
+{
+	struct sysinfo si;
+
+	si_meminfo(&si);
+	return (si.totalram << PAGE_SHIFT);
+}
+
+/*
+ * Find the smallest available unit number to use
+ * for a new device.  We don't just use a static
+ * count to handle the "repeated hot-(un)plug"
+ * scenario.
+ */
+static int
+ahc_linux_next_unit()
+{
+	struct ahc_softc *ahc;
+	int unit;
+
+	unit = 0;
+retry:
+	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
+		if (ahc->unit == unit) {
+			unit++;
+			goto retry;
+		}
+	}
+	return (unit);
+}
+
+/*
+ * Place the SCSI bus into a known state by either resetting it,
+ * or forcing transfer negotiations on the next command to any
+ * target.
+ */
+void
+ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
+{
+	int i;
+	int numtarg;
+
+	i = 0;
+	numtarg = 0;
+
+	if (aic7xxx_no_reset != 0)
+		ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
+
+	if ((ahc->flags & AHC_RESET_BUS_A) != 0)
+		ahc_reset_channel(ahc, 'A', /*initiate_reset*/TRUE);
+	else
+		numtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
+
+	if ((ahc->features & AHC_TWIN) != 0) {
+
+		if ((ahc->flags & AHC_RESET_BUS_B) != 0) {
+			ahc_reset_channel(ahc, 'B', /*initiate_reset*/TRUE);
+		} else {
+			if (numtarg == 0)
+				i = 8;
+			numtarg += 8;
+		}
+	}
+
+	for (; i < numtarg; i++) {
+		struct ahc_devinfo devinfo;
+		struct ahc_initiator_tinfo *tinfo;
+		struct ahc_tmode_tstate *tstate;
+		u_int our_id;
+		u_int target_id;
+		char channel;
+
+		channel = 'A';
+		our_id = ahc->our_id;
+		target_id = i;
+		if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
+			channel = 'B';
+			our_id = ahc->our_id_b;
+			target_id = i % 8;
+		}
+		tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
+					    target_id, &tstate);
+		tinfo->goal = tinfo->user;
+		/*
+		 * Don't try negotiations that require PPR messages
+		 * until we successfully retrieve Inquiry data.
+		 */
+		tinfo->goal.ppr_options = 0;
+		if (tinfo->goal.transport_version > SCSI_REV_2)
+			tinfo->goal.transport_version = SCSI_REV_2;
+		ahc_compile_devinfo(&devinfo, our_id, target_id,
+				   CAM_LUN_WILDCARD, channel, ROLE_INITIATOR);
+		ahc_update_neg_request(ahc, &devinfo, tstate,
+				       tinfo, /*force*/FALSE);
+	}
+	/* Give the bus some time to recover */
+	if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
+		ahc_linux_freeze_sim_queue(ahc);
+		init_timer(&ahc->platform_data->reset_timer);
+		ahc->platform_data->reset_timer.data = (u_long)ahc;
+		ahc->platform_data->reset_timer.expires =
+		    jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000;
+		ahc->platform_data->reset_timer.function =
+		    ahc_linux_release_sim_queue;
+		add_timer(&ahc->platform_data->reset_timer);
+	}
+}
+
+int
+ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
+{
+	ahc->platform_data =
+	    malloc(sizeof(struct ahc_platform_data), M_DEVBUF, M_NOWAIT);
+	if (ahc->platform_data == NULL)
+		return (ENOMEM);
+	memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
+	TAILQ_INIT(&ahc->platform_data->completeq);
+	TAILQ_INIT(&ahc->platform_data->device_runq);
+	ahc->platform_data->irq = AHC_LINUX_NOIRQ;
+	ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
+	ahc_lockinit(ahc);
+	ahc_done_lockinit(ahc);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
+#else
+	ahc->platform_data->eh_sem = MUTEX_LOCKED;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet,
+		     (unsigned long)ahc);
+#endif
+	ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
+	ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
+	if (TAILQ_EMPTY(&ahc_tailq))
+		register_reboot_notifier(&ahc_linux_notifier);
+	return (0);
+}
+
+void
+ahc_platform_free(struct ahc_softc *ahc)
+{
+	if (ahc->platform_data != NULL) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		tasklet_kill(&ahc->platform_data->runq_tasklet);
+#endif
+		if (ahc->platform_data->host != NULL)
+			scsi_unregister(ahc->platform_data->host);
+		if (ahc->platform_data->irq != AHC_LINUX_NOIRQ)
+			free_irq(ahc->platform_data->irq, ahc);
+		if (ahc->tag == BUS_SPACE_PIO
+		 && ahc->bsh.ioport != 0)
+			release_region(ahc->bsh.ioport, 256);
+		if (ahc->tag == BUS_SPACE_MEMIO
+		 && ahc->bsh.maddr != NULL) {
+			u_long base_addr;
+
+			base_addr = (u_long)ahc->bsh.maddr;
+			base_addr &= PAGE_MASK;
+			iounmap((void *)base_addr);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+			release_mem_region(ahc->platform_data->mem_busaddr,
+					   0x1000);
+#endif
+		}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		/* XXX Need an instance detach in the PCI code */
+		if (ahc->dev_softc != NULL)
+			ahc->dev_softc->driver = NULL;
+#endif
+		free(ahc->platform_data, M_DEVBUF);
+	}
+	if (TAILQ_EMPTY(&ahc_tailq)) {
+		unregister_reboot_notifier(&ahc_linux_notifier);
+#ifdef CONFIG_PCI
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		pci_unregister_driver(&aic7xxx_pci_driver);
+#endif
+#endif
+	}
+}
+
+void
+ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
+{
+	ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
+				SCB_GET_CHANNEL(ahc, scb),
+				SCB_GET_LUN(scb), SCB_LIST_NULL,
+				ROLE_UNKNOWN, CAM_REQUEUE_REQ);
+}
+
+void
+ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+		      ahc_queue_alg alg)
+{
+	struct ahc_linux_device *dev;
+	int was_queuing;
+	int now_queuing;
+
+	dev = ahc_linux_get_device(ahc, devinfo->channel - 'A',
+				   devinfo->target,
+				   devinfo->lun, /*alloc*/FALSE);
+	if (dev == NULL)
+		return;
+	was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
+	now_queuing = alg != AHC_QUEUE_NONE;
+	if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0
+	 && (was_queuing != now_queuing)
+	 && (dev->active != 0)) {
+		dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY;
+		dev->qfrozen++;
+	}
+
+	dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG);
+	if (now_queuing) {
+		u_int usertags;
+
+		usertags = ahc_linux_user_tagdepth(ahc, devinfo);
+		if (!was_queuing) {
+			/*
+			 * Start out agressively and allow our
+			 * dynamic queue depth algorithm to take
+			 * care of the rest.
+			 */
+			dev->maxtags = usertags;
+			dev->openings = dev->maxtags - dev->active;
+		}
+		if (alg == AHC_QUEUE_TAGGED) {
+			dev->flags |= AHC_DEV_Q_TAGGED;
+			if (aic7xxx_periodic_otag != 0)
+				dev->flags |= AHC_DEV_PERIODIC_OTAG;
+		} else
+			dev->flags |= AHC_DEV_Q_BASIC;
+	} else {
+		/* We can only have one opening. */
+		dev->maxtags = 0;
+		dev->openings =  1 - dev->active;
+	}
+}
+
+int
+ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
+			int lun, u_int tag, role_t role, uint32_t status)
+{
+	int chan;
+	int maxchan;
+	int targ;
+	int maxtarg;
+	int clun;
+	int maxlun;
+	int count;
+
+	if (tag != SCB_LIST_NULL)
+		return (0);
+
+	chan = 0;
+	if (channel != ALL_CHANNELS) {
+		chan = channel - 'A';
+		maxchan = chan + 1;
+	} else {
+		maxchan = (ahc->features & AHC_TWIN) ? 2 : 1;
+	}
+	targ = 0;
+	if (target != CAM_TARGET_WILDCARD) {
+		targ = target;
+		maxtarg = targ + 1;
+	} else {
+		maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
+	}
+	clun = 0;
+	if (lun != CAM_LUN_WILDCARD) {
+		clun = lun;
+		maxlun = clun + 1;
+	} else {
+		maxlun = AHC_NUM_LUNS;
+	}
+
+	count = 0;
+	for (; chan < maxchan; chan++) {
+
+		for (; targ < maxtarg; targ++) {
+
+			for (; clun < maxlun; clun++) {
+				struct ahc_linux_device *dev;
+				struct ahc_busyq *busyq;
+				struct ahc_cmd *acmd;
+
+				dev = ahc_linux_get_device(ahc, chan,
+							   targ, clun,
+							   /*alloc*/FALSE);
+				if (dev == NULL)
+					continue;
+
+				busyq = &dev->busyq;
+				while ((acmd = TAILQ_FIRST(busyq)) != NULL) {
+					Scsi_Cmnd *cmd;
+
+					cmd = &acmd_scsi_cmd(acmd);
+					TAILQ_REMOVE(busyq, acmd,
+						     acmd_links.tqe);
+					count++;
+					cmd->result = status << 16;
+					ahc_linux_queue_cmd_complete(ahc, cmd);
+				}
+			}
+		}
+	}
+
+	return (count);
+}
+
+/*
+ * Sets the queue depth for each SCSI device hanging
+ * off the input host adapter.
+ */
+static void
+ahc_linux_select_queue_depth(struct Scsi_Host * host,
+			     Scsi_Device * scsi_devs)
+{
+	Scsi_Device *device;
+	struct	ahc_softc *ahc;
+	u_long	flags;
+	int	scbnum;
+
+	ahc = *((struct ahc_softc **)host->hostdata);
+	ahc_lock(ahc, &flags);
+	scbnum = 0;
+	for (device = scsi_devs; device != NULL; device = device->next) {
+		if (device->host == host) {
+			ahc_linux_device_queue_depth(ahc, device);
+			scbnum += device->queue_depth;
+		}
+	}
+	ahc_unlock(ahc, &flags);
+}
+
+static u_int
+ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
+{
+	static int warned_user;
+	u_int tags;
+
+	tags = 0;
+	if ((ahc->user_discenable & devinfo->target_mask) != 0) {
+		if (warned_user == 0
+		 && ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) {
+
+			printf("aic7xxx: WARNING, insufficient "
+			       "tag_info instances for installed "
+			       "controllers. Using defaults\n");
+			printf("aic7xxx: Please update the "
+			       "aic7xxx_tag_info array in the "
+			       "aic7xxx.c source file.\n");
+			tags = AHC_MAX_QUEUE;
+			warned_user++;
+		} else {
+			adapter_tag_info_t *tag_info;
+
+			tag_info = &aic7xxx_tag_info[ahc->unit];
+			tags = tag_info->tag_commands[devinfo->target_offset];
+			if (tags > AHC_MAX_QUEUE)
+				tags = AHC_MAX_QUEUE;
+		}
+	}
+	return (tags);
+}
+
+/*
+ * Determines the queue depth for a given device.
+ */
+static void
+ahc_linux_device_queue_depth(struct ahc_softc *ahc, Scsi_Device * device)
+{
+	struct	ahc_devinfo devinfo;
+	u_int	tags;
+
+	ahc_compile_devinfo(&devinfo,
+			    device->channel == 0 ? ahc->our_id : ahc->our_id_b,
+			    device->id, device->lun,
+			    device->channel == 0 ? 'A' : 'B',
+			    ROLE_INITIATOR);
+	tags = ahc_linux_user_tagdepth(ahc, &devinfo);
+	if (tags != 0
+	 && device->tagged_supported != 0) {
+
+		device->queue_depth = tags;
+		ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED);
+		printf("scsi%d:%c:%d:%d: Tagged Queuing enabled.  Depth %d\n",
+	       	       ahc->platform_data->host->host_no, devinfo.channel,
+		       devinfo.target, devinfo.lun, tags);
+	} else {
+		/*
+		 * We allow the OS to queue 2 untagged transactions to
+		 * us at any time even though we can only execute them
+		 * serially on the controller/device.  This should remove
+		 * some latency.
+		 */
+		device->queue_depth = 2;
+	}
+}
+
+/*
+ * Queue an SCB to the controller.
+ */
+int
+ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
+{
+	struct	 ahc_softc *ahc;
+	struct	 ahc_linux_device *dev;
+	u_long	 flags;
+
+	ahc = *(struct ahc_softc **)cmd->host->hostdata;
+
+	/*
+	 * Save the callback on completion function.
+	 */
+	cmd->scsi_done = scsi_done;
+
+	ahc_lock(ahc, &flags);
+	dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target,
+				   cmd->lun, /*alloc*/TRUE);
+	if (dev == NULL) {
+		ahc_unlock(ahc, &flags);
+		printf("aic7xxx_linux_queue: Unable to allocate device!\n");
+		return (-ENOMEM);
+	}
+	cmd->result = CAM_REQ_INPROG << 16;
+	TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe);
+	if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
+		TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
+		dev->flags |= AHC_DEV_ON_RUN_LIST;
+		ahc_linux_run_device_queues(ahc);
+	}
+	ahc_unlock(ahc, &flags);
+	return (0);
+}
+
+static void
+ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
+{
+	struct	 ahc_cmd *acmd;
+	struct	 scsi_cmnd *cmd;
+	struct	 scb *scb;
+	struct	 hardware_scb *hscb;
+	struct	 ahc_initiator_tinfo *tinfo;
+	struct	 ahc_tmode_tstate *tstate;
+	uint16_t mask;
+
+	if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0)
+		panic("running device on run list");
+
+	while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
+	    && dev->openings > 0 && dev->qfrozen == 0) {
+
+		/*
+		 * Schedule us to run later.  The only reason we are not
+		 * running is because the whole controller Q is frozen.
+		 */
+		if (ahc->platform_data->qfrozen != 0) {
+
+			TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
+					  dev, links);
+			dev->flags |= AHC_DEV_ON_RUN_LIST;
+			return;
+		}
+		/*
+		 * Get an scb to use.
+		 */
+		if ((scb = ahc_get_scb(ahc)) == NULL) {
+			TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
+					 dev, links);
+			dev->flags |= AHC_DEV_ON_RUN_LIST;
+			ahc->flags |= AHC_RESOURCE_SHORTAGE;
+			return;
+		}
+		TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe);
+		cmd = &acmd_scsi_cmd(acmd);
+		scb->io_ctx = cmd;
+		scb->platform_data->dev = dev;
+		hscb = scb->hscb;
+		cmd->host_scribble = (char *)scb;
+
+		/*
+		 * Fill out basics of the HSCB.
+		 */
+		hscb->control = 0;
+		hscb->scsiid = BUILD_SCSIID(ahc, cmd);
+		hscb->lun = cmd->lun;
+		mask = SCB_GET_TARGET_MASK(ahc, scb);
+		tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
+					    SCB_GET_OUR_ID(scb),
+					    SCB_GET_TARGET(ahc, scb), &tstate);
+		hscb->scsirate = tinfo->scsirate;
+		hscb->scsioffset = tinfo->curr.offset;
+		if ((tstate->ultraenb & mask) != 0)
+			hscb->control |= ULTRAENB;
+
+		if ((ahc->user_discenable & mask) != 0)
+			hscb->control |= DISCENB;
+
+		if ((tstate->auto_negotiate & mask) != 0) {
+			scb->flags |= SCB_AUTO_NEGOTIATE;
+			scb->hscb->control |= MK_MESSAGE;
+		}
+
+		if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
+			if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
+			 && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
+				hscb->control |= MSG_ORDERED_TASK;
+				dev->commands_since_idle_or_otag = 0;
+			} else {
+				hscb->control |= MSG_SIMPLE_TASK;
+			}
+		}
+
+		hscb->cdb_len = cmd->cmd_len;
+		if (hscb->cdb_len <= 12) {
+			memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
+		} else {
+			memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
+			scb->flags |= SCB_CDB32_PTR;
+		}
+
+		scb->platform_data->xfer_len = 0;
+		ahc_set_residual(scb, 0);
+		ahc_set_sense_residual(scb, 0);
+		scb->sg_count = 0;
+		if (cmd->use_sg != 0) {
+			struct	ahc_dma_seg *sg;
+			struct	scatterlist *cur_seg;
+			struct	scatterlist *end_seg;
+			int	nseg;
+
+			cur_seg = (struct scatterlist *)cmd->request_buffer;
+			nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
+				 scsi_to_pci_dma_dir(cmd ->sc_data_direction));
+			end_seg = cur_seg + nseg;
+			/* Copy the segments into the SG list. */
+			sg = scb->sg_list;
+			/*
+			 * The sg_count may be larger than nseg if
+			 * a transfer crosses a 32bit page.
+			 */ 
+			while (cur_seg < end_seg) {
+				bus_addr_t addr;
+				bus_size_t len;
+				int consumed;
+
+				addr = sg_dma_address(cur_seg);
+				len = sg_dma_len(cur_seg);
+				consumed = ahc_linux_map_seg(ahc, scb,
+							     sg, addr, len);
+				sg += consumed;
+				scb->sg_count += consumed;
+				cur_seg++;
+			}
+			sg--;
+			sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
+
+			/*
+			 * Reset the sg list pointer.
+			 */
+			scb->hscb->sgptr =
+			    ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
+
+			/*
+			 * Copy the first SG into the "current"
+			 * data pointer area.
+			 */
+			scb->hscb->dataptr = scb->sg_list->addr;
+			scb->hscb->datacnt = scb->sg_list->len;
+		} else if (cmd->request_bufflen != 0) {
+			struct	 ahc_dma_seg *sg;
+			bus_addr_t addr;
+
+			sg = scb->sg_list;
+			addr = pci_map_single(ahc->dev_softc,
+			       cmd->request_buffer,
+			       cmd->request_bufflen,
+			       scsi_to_pci_dma_dir(cmd->sc_data_direction));
+			scb->platform_data->buf_busaddr = addr;
+			scb->sg_count = ahc_linux_map_seg(ahc, scb,
+							  sg, addr,
+							  cmd->request_bufflen);
+			sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
+
+			/*
+			 * Reset the sg list pointer.
+			 */
+			scb->hscb->sgptr =
+			    ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
+
+			/*
+			 * Copy the first SG into the "current"
+			 * data pointer area.
+			 */
+			scb->hscb->dataptr = sg->addr;
+			scb->hscb->datacnt = sg->len;
+		} else {
+			scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
+			scb->hscb->dataptr = 0;
+			scb->hscb->datacnt = 0;
+			scb->sg_count = 0;
+		}
+
+		ahc_sync_sglist(ahc, scb, BUS_DMASYNC_PREWRITE);
+		LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
+		dev->openings--;
+		dev->active++;
+		dev->commands_issued++;
+		if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
+			dev->commands_since_idle_or_otag++;
+
+		/*
+		 * We only allow one untagged transaction
+		 * per target in the initiator role unless
+		 * we are storing a full busy target *lun*
+		 * table in SCB space.
+		 */
+		if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
+		 && (ahc->features & AHC_SCB_BTT) == 0) {
+			struct scb_tailq *untagged_q;
+			int target_offset;
+
+			target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
+			untagged_q = &(ahc->untagged_queues[target_offset]);
+			TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
+			scb->flags |= SCB_UNTAGGEDQ;
+			if (TAILQ_FIRST(untagged_q) != scb)
+				continue;
+		}
+		scb->flags |= SCB_ACTIVE;
+		ahc_queue_scb(ahc, scb);
+	}
+}
+
+/*
+ * SCSI controller interrupt handler.
+ */
+void
+ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct	ahc_softc *ahc;
+	struct	ahc_cmd *acmd;
+	u_long	flags;
+	struct	ahc_linux_device *next_dev;
+
+	ahc = (struct ahc_softc *) dev_id;
+	ahc_lock(ahc, &flags); 
+	ahc_intr(ahc);
+	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
+	TAILQ_INIT(&ahc->platform_data->completeq);
+	next_dev = ahc_linux_next_device_to_run(ahc);
+	ahc_unlock(ahc, &flags);
+	if (next_dev) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		tasklet_schedule(&ahc->platform_data->runq_tasklet);
+#else
+		ahc_runq_tasklet((unsigned long)ahc);
+#endif
+	}
+	if (acmd != NULL)
+		ahc_linux_run_complete_queue(ahc, acmd);
+}
+
+void
+ahc_platform_flushwork(struct ahc_softc *ahc)
+{
+	struct ahc_cmd *acmd;
+
+	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
+	TAILQ_INIT(&ahc->platform_data->completeq);
+	if (acmd != NULL)
+		ahc_linux_run_complete_queue(ahc, acmd);
+}
+
+static struct ahc_linux_target*
+ahc_linux_alloc_target(struct ahc_softc *ahc, u_int channel, u_int target)
+{
+	struct ahc_linux_target *targ;
+	u_int target_offset;
+
+	targ = malloc(sizeof(*targ), M_DEVBUG, M_NOWAIT);
+	if (targ == NULL)
+		return (NULL);
+	memset(targ, 0, sizeof(*targ));
+	targ->channel = channel;
+	targ->target = target;
+	targ->ahc = ahc;
+	target_offset = target;
+	if (channel != 0)
+		target_offset += 8;
+	ahc->platform_data->targets[target_offset] = targ;
+	return (targ);
+}
+
+static void
+ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ)
+{
+	u_int target_offset;
+
+	target_offset = targ->target;
+	if (targ->channel != 0)
+		target_offset += 8;
+	ahc->platform_data->targets[target_offset] = NULL;
+	free(targ, M_DEVBUF);
+}
+
+static struct ahc_linux_device*
+ahc_linux_alloc_device(struct ahc_softc *ahc,
+		 struct ahc_linux_target *targ, u_int lun)
+{
+	struct ahc_linux_device *dev;
+
+	dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT);
+	if (dev == NULL)
+		return (NULL);
+	memset(dev, 0, sizeof(*dev));
+	init_timer(&dev->timer);
+	TAILQ_INIT(&dev->busyq);
+	dev->flags = AHC_DEV_UNCONFIGURED;
+	dev->lun = lun;
+	dev->target = targ;
+
+	/*
+	 * We start out life using untagged
+	 * transactions of which we allow one.
+	 */
+	dev->openings = 1;
+
+	/*
+	 * Set maxtags to 0.  This will be changed if we
+	 * later determine that we are dealing with
+	 * a tagged queuing capable device.
+	 */
+	dev->maxtags = 0;
+	
+	targ->refcount++;
+	targ->devices[lun] = dev;
+	return (dev);
+}
+
+static void
+ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
+{
+	struct ahc_linux_target *targ;
+
+	del_timer(&dev->timer);
+	targ = dev->target;
+	targ->devices[dev->lun] = NULL;
+	free(dev, M_DEVBUF);
+	targ->refcount--;
+	if (targ->refcount == 0)
+		ahc_linux_free_target(ahc, targ);
+}
+
+/*
+ * Return a string describing the driver.
+ */
+const char *
+ahc_linux_info(struct Scsi_Host *host)
+{
+	static char buffer[512];
+	char	ahc_info[256];
+	char   *bp;
+	struct ahc_softc *ahc;
+
+	bp = &buffer[0];
+	ahc = *(struct ahc_softc **)host->hostdata;
+	memset(bp, 0, sizeof(buffer));
+	strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev ");
+	strcat(bp, AIC7XXX_DRIVER_VERSION);
+	strcat(bp, "\n");
+	strcat(bp, "        <");
+	strcat(bp, ahc->description);
+	strcat(bp, ">\n");
+	strcat(bp, "        ");
+	ahc_controller_info(ahc, ahc_info);
+	strcat(bp, ahc_info);
+	strcat(bp, "\n");
+
+	return (bp);
+}
+
+void
+ahc_send_async(struct ahc_softc *ahc, char channel,
+	       u_int target, u_int lun, ac_code code, void *arg)
+{
+	switch (code) {
+	case AC_TRANSFER_NEG:
+	{
+		char	buf[80];
+		struct	ahc_linux_target *targ;
+		struct	info_str info;
+		struct	ahc_initiator_tinfo *tinfo;
+		struct	ahc_tmode_tstate *tstate;
+		int	target_offset;
+
+		info.buffer = buf;
+		info.length = sizeof(buf);
+		info.offset = 0;
+		info.pos = 0;
+		tinfo = ahc_fetch_transinfo(ahc, channel,
+						channel == 'A' ? ahc->our_id
+							       : ahc->our_id_b,
+						target, &tstate);
+
+		/*
+		 * Don't bother reporting results while
+		 * negotiations are still pending.
+		 */
+		if (tinfo->curr.period != tinfo->goal.period
+		 || tinfo->curr.width != tinfo->goal.width
+		 || tinfo->curr.offset != tinfo->goal.offset
+		 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
+			if (bootverbose == 0)
+				break;
+
+		/*
+		 * Don't bother reporting results that
+		 * are identical to those last reported.
+		 */
+		target_offset = target;
+		if (channel == 'B')
+			target_offset += 8;
+		targ = ahc->platform_data->targets[target_offset];
+		if (targ == NULL)
+			break;
+		if (tinfo->curr.period == targ->last_tinfo.period
+		 && tinfo->curr.width == targ->last_tinfo.width
+		 && tinfo->curr.offset == targ->last_tinfo.offset
+		 && tinfo->curr.ppr_options == targ->last_tinfo.ppr_options)
+			if (bootverbose == 0)
+				break;
+
+		targ->last_tinfo.period = tinfo->curr.period;
+		targ->last_tinfo.width = tinfo->curr.width;
+		targ->last_tinfo.offset = tinfo->curr.offset;
+		targ->last_tinfo.ppr_options = tinfo->curr.ppr_options;
+
+		printf("(%s:%c:", ahc_name(ahc), channel);
+		if (target == CAM_TARGET_WILDCARD)
+			printf("*): ");
+		else
+			printf("%d): ", target);
+		ahc_format_transinfo(&info, &tinfo->curr);
+		if (info.pos < info.length)
+			*info.buffer = '\0';
+		else
+			buf[info.length - 1] = '\0';
+		printf("%s", buf);
+		break;
+	}
+        case AC_SENT_BDR:
+		break;
+        case AC_BUS_RESET:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+		if (ahc->platform_data->host != NULL) {
+			scsi_report_bus_reset(ahc->platform_data->host,
+					      channel - 'A');
+		}
+#endif
+                break;
+        default:
+                panic("ahc_send_async: Unexpected async event");
+        }
+}
+
+/*
+ * Calls the higher level scsi done function and frees the scb.
+ */
+void
+ahc_done(struct ahc_softc *ahc, struct scb * scb)
+{
+	Scsi_Cmnd *cmd;
+	struct ahc_linux_device *dev;
+
+	LIST_REMOVE(scb, pending_links);
+	if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
+		struct scb_tailq *untagged_q;
+		int target_offset;
+
+		target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
+		untagged_q = &(ahc->untagged_queues[target_offset]);
+		TAILQ_REMOVE(untagged_q, scb, links.tqe);
+		ahc_run_untagged_queue(ahc, untagged_q);
+	}
+
+	if ((scb->flags & SCB_ACTIVE) == 0) {
+		printf("SCB %d done'd twice\n", scb->hscb->tag);
+		ahc_dump_card_state(ahc);
+		panic("Stopping for safety");
+	}
+	cmd = scb->io_ctx;
+	dev = scb->platform_data->dev;
+	dev->active--;
+	dev->openings++;
+	ahc_linux_unmap_scb(ahc, scb);
+	if (scb->flags & SCB_SENSE) {
+		memcpy(cmd->sense_buffer, ahc_get_sense_buf(ahc, scb),
+		       MIN(sizeof(struct scsi_sense_data),
+			   sizeof(cmd->sense_buffer)));
+		cmd->result |= (DRIVER_SENSE << 24);
+	} else {
+		/*
+		 * Guard against stale sense data.
+		 * The Linux mid-layer assumes that sense
+		 * was retrieved anytime the first byte of
+		 * the sense buffer looks "sane".
+		 */
+		cmd->sense_buffer[0] = 0;
+	}
+	if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) {
+		uint32_t amount_xferred;
+
+		amount_xferred =
+		    ahc_get_transfer_length(scb) - ahc_get_residual(scb);
+		if (amount_xferred < scb->io_ctx->underflow) {
+			printf("Saw underflow (%ld of %ld bytes). "
+			       "Treated as error\n",
+				ahc_get_residual(scb),
+				ahc_get_transfer_length(scb));
+			ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
+		} else {
+			ahc_set_transaction_status(scb, CAM_REQ_CMP);
+			ahc_linux_sniff_command(ahc, cmd, scb);
+		}
+	} else if (ahc_get_transaction_status(scb) == DID_OK) {
+		ahc_linux_handle_scsi_status(ahc, dev, scb);
+	} else if (ahc_get_transaction_status(scb) == DID_NO_CONNECT) {
+		/*
+		 * Should a selection timeout kill the device?
+		 * That depends on whether the selection timeout
+		 * is persistent.  Since we have no guarantee that
+		 * the mid-layer will issue an inquiry for this device
+		 * again, we can't just kill it off.
+		dev->flags |= AHC_DEV_UNCONFIGURED;
+		 */
+	}
+
+	if (dev->openings == 1
+	 && ahc_get_transaction_status(scb) == CAM_REQ_CMP
+	 && ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
+		dev->tag_success_count++;
+	/*
+	 * Some devices deal with temporary internal resource
+	 * shortages by returning queue full.  When the queue
+	 * full occurrs, we throttle back.  Slowly try to get
+	 * back to our previous queue depth.
+	 */
+	if ((dev->openings + dev->active) < dev->maxtags
+	 && dev->tag_success_count > AHC_TAG_SUCCESS_INTERVAL) {
+		dev->tag_success_count = 0;
+		dev->openings++;
+	}
+
+	if (dev->active == 0)
+		dev->commands_since_idle_or_otag = 0;
+
+	if (TAILQ_EMPTY(&dev->busyq)) {
+		if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0
+		 && dev->active == 0)
+			ahc_linux_free_device(ahc, dev);
+	} else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
+		TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
+		dev->flags |= AHC_DEV_ON_RUN_LIST;
+	}
+
+	if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
+		printf("Recovery SCB completes\n");
+		up(&ahc->platform_data->eh_sem);
+	}
+
+	ahc_free_scb(ahc, scb);
+	ahc_linux_queue_cmd_complete(ahc, cmd);
+}
+
+static void
+ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
+			     struct ahc_linux_device *dev, struct scb *scb)
+{
+	/*
+	 * We don't currently trust the mid-layer to
+	 * properly deal with queue full or busy.  So,
+	 * when one occurs, we tell the mid-layer to
+	 * unconditionally requeue the command to us
+	 * so that we can retry it ourselves.  We also
+	 * implement our own throttling mechanism so
+	 * we don't clobber the device with too many
+	 * commands.
+	 */
+	switch (ahc_get_scsi_status(scb)) {
+	default:
+		break;
+	case SCSI_STATUS_QUEUE_FULL:
+	{
+		/*
+		 * By the time the core driver has returned this
+		 * command, all other commands that were queued
+		 * to us but not the device have been returned.
+		 * This ensures that dev->active is equal to
+		 * the number of commands actually queued to
+		 * the device.
+		 */
+		dev->tag_success_count = 0;
+		if (dev->active != 0) {
+			/*
+			 * Drop our opening count to the number
+			 * of commands currently outstanding.
+			 */
+			dev->openings = 0;
+/*
+			ahc_print_path(ahc, scb);
+			printf("Dropping tag count to %d\n", dev->active);
+ */
+			if (dev->active == dev->tags_on_last_queuefull) {
+
+				dev->last_queuefull_same_count++;
+				/*
+				 * If we repeatedly see a queue full
+				 * at the same queue depth, this
+				 * device has a fixed number of tag
+				 * slots.  Lock in this tag depth
+				 * so we stop seeing queue fulls from
+				 * this device.
+				 */
+				if (dev->last_queuefull_same_count
+				 == AHC_LOCK_TAGS_COUNT) {
+					dev->maxtags = dev->active;
+					ahc_print_path(ahc, scb);
+					printf("Locking max tag count at %d\n",
+					       dev->active);
+				}
+			} else {
+				dev->tags_on_last_queuefull = dev->active;
+				dev->last_queuefull_same_count = 0;
+			}
+			ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
+			ahc_set_scsi_status(scb, SCSI_STATUS_OK);
+			break;
+		}
+		/*
+		 * Drop down to a single opening, and treat this
+		 * as if the target return BUSY SCSI status.
+		 */
+		dev->openings = 1;
+		/* FALLTHROUGH */
+	}
+	case SCSI_STATUS_BUSY:
+	{
+		/*
+		 * Set a short timer to defer sending commands for
+		 * a bit since Linux will not delay in this case.
+		 */
+		if ((dev->flags & AHC_DEV_TIMER_ACTIVE) != 0) {
+			printf("%s:%c:%d: Device Timer still active during "
+			       "busy processing\n", ahc_name(ahc),
+				dev->target->channel, dev->target->target);
+			break;
+		}
+		dev->flags |= AHC_DEV_TIMER_ACTIVE;
+		dev->qfrozen++;
+		init_timer(&dev->timer);
+		dev->timer.data = (u_long)dev;
+		dev->timer.expires = jiffies + (HZ/2);
+		dev->timer.function = ahc_linux_dev_timed_unfreeze;
+		add_timer(&dev->timer);
+		break;
+	}
+	}
+}
+
+static void
+ahc_linux_filter_command(struct ahc_softc *ahc, Scsi_Cmnd *cmd, struct scb *scb)
+{
+	switch (cmd->cmnd[0]) {
+	case INQUIRY:
+	{
+		struct	ahc_devinfo devinfo;
+		struct	scsi_inquiry *inq;
+		struct	scsi_inquiry_data *sid;
+		struct	ahc_initiator_tinfo *tinfo;
+		struct	ahc_transinfo *user;
+		struct	ahc_transinfo *goal;
+		struct	ahc_transinfo *curr;
+		struct	ahc_tmode_tstate *tstate;
+		struct	ahc_syncrate *syncrate;
+		struct	ahc_linux_device *dev;
+		u_int	scsiid;
+		u_int	maxsync;
+		int	transferred_len;
+		int	minlen;
+		u_int	width;
+		u_int	period;
+		u_int	offset;
+		u_int	ppr_options;
+
+		 /*
+		  * Validate the command.  We only want to filter
+		  * standard inquiry commands, not those querying
+		  * Vital Product Data.
+		  */
+		inq = (struct scsi_inquiry *)cmd->cmnd;
+		if ((inq->byte2 & SI_EVPD) != 0
+		 || inq->page_code != 0)
+			break;
+
+		if (cmd->use_sg != 0) {
+			printf("%s: SG Inquiry response ignored\n",
+			       ahc_name(ahc));
+			break;
+		}
+		transferred_len = ahc_get_transfer_length(scb)
+				- ahc_get_residual(scb);
+		sid = (struct scsi_inquiry_data *)cmd->request_buffer;
+
+		/*
+		 * Determine if this lun actually exists.  If so,
+		 * hold on to its corresponding device structure.
+		 * If not, make sure we release the device and
+		 * don't bother processing the rest of this inquiry
+		 * command.
+		 */
+		dev = ahc_linux_get_device(ahc, cmd->channel,
+					   cmd->target, cmd->lun,
+					   /*alloc*/FALSE);
+		if (transferred_len >= 1
+		 && SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) {
+
+			dev->flags &= ~AHC_DEV_UNCONFIGURED;
+		} else {
+			dev->flags |= AHC_DEV_UNCONFIGURED;
+			break;
+		}
+
+		/*
+		 * Update our notion of this device's transfer
+		 * negotiation capabilities.
+		 */
+		scsiid = BUILD_SCSIID(ahc, cmd);
+		ahc_compile_devinfo(&devinfo, SCSIID_OUR_ID(scsiid),
+				    cmd->target, cmd->lun,
+				    SCSIID_CHANNEL(ahc, scsiid),
+				    ROLE_INITIATOR);
+		tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
+					    devinfo.our_scsiid,
+					    devinfo.target, &tstate);
+		user = &tinfo->user;
+		goal = &tinfo->goal;
+		curr = &tinfo->curr;
+		width = user->width;
+		period = user->period;
+		offset = user->offset;
+		ppr_options = user->ppr_options;
+		minlen = offsetof(struct scsi_inquiry_data, version) + 1;
+		if (transferred_len >= minlen) {
+			curr->protocol_version = SID_ANSI_REV(sid);
+
+			/*
+			 * Only attempt SPI3 once we've verified that
+			 * the device claims to support SPI3 features.
+			 */
+			if (curr->protocol_version < SCSI_REV_2)
+				curr->transport_version = SID_ANSI_REV(sid);
+			else
+				curr->transport_version = SCSI_REV_2;
+		}
+
+		minlen = offsetof(struct scsi_inquiry_data, flags) + 1;
+		if (transferred_len >= minlen
+		 && (sid->additional_length + 4) >= minlen) {
+			if ((sid->flags & SID_WBus16) == 0)
+				width = MSG_EXT_WDTR_BUS_8_BIT;
+			if ((sid->flags & SID_Sync) == 0) {
+				period = 0;
+				offset = 0;
+				ppr_options = 0;
+			}
+		} else {
+			/* Keep current settings */
+			break;
+		}
+		minlen = offsetof(struct scsi_inquiry_data, spi3data) + 1;
+		/*
+		 * This is a kludge to deal with inquiry requests that
+		 * are not large enough for us to pull the spi3/4 bits.
+		 * In this case, we assume that a device that tells us
+		 * they can provide inquiry data that spans the SPI3
+		 * bits and says its SCSI3 can handle a PPR request.
+		 * If the inquiry request has sufficient buffer space to
+		 * cover SPI3 bits, we honor them regardless of reported
+		 * SCSI REV.  We also allow any device that has had its
+		 * goal ppr_options set to allow DT speeds to keep that
+		 * option if a short inquiry occurs that would fail the
+		 * normal tests outlined above.
+		 */
+		if ((sid->additional_length + 4) >= minlen) {
+			if (transferred_len >= minlen) {
+				 if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0)
+					ppr_options = 0;
+			} else if ((goal->ppr_options & MSG_EXT_PPR_DT_REQ)== 0)
+				ppr_options = 0;
+
+			if (curr->protocol_version > SCSI_REV_2)
+				curr->transport_version = 3;
+		} else {
+			ppr_options = 0;
+		}
+		ahc_validate_width(ahc, /*tinfo limit*/NULL, &width,
+				   ROLE_UNKNOWN);
+		if ((ahc->features & AHC_ULTRA2) != 0)
+			maxsync = AHC_SYNCRATE_DT;
+		else if ((ahc->features & AHC_ULTRA) != 0)
+			maxsync = AHC_SYNCRATE_ULTRA;
+		else
+			maxsync = AHC_SYNCRATE_FAST;
+
+		syncrate = ahc_find_syncrate(ahc, &period,
+					     &ppr_options, maxsync);
+		ahc_validate_offset(ahc, /*tinfo limit*/NULL, syncrate,
+				    &offset, width, ROLE_UNKNOWN);
+		if (offset == 0 || period == 0) {
+			period = 0;
+			offset = 0;
+			ppr_options = 0;
+		}
+		/* Apply our filtered user settings. */
+		ahc_set_width(ahc, &devinfo, width,
+			      AHC_TRANS_GOAL, /*paused*/FALSE);
+		ahc_set_syncrate(ahc, &devinfo, syncrate, period,
+				 offset, ppr_options, AHC_TRANS_GOAL,
+				 /*paused*/FALSE);
+		break;
+	}
+	default:
+		panic("ahc_linux_filter_command: Unexpected Command type  %x\n",
+		      cmd->cmnd[0]);
+		break;
+	}
+}
+
+static void
+ahc_linux_sem_timeout(u_long arg)
+{
+	struct semaphore *sem;
+
+	sem = (struct semaphore *)arg;
+	up(sem);
+}
+
+static void
+ahc_linux_freeze_sim_queue(struct ahc_softc *ahc)
+{
+	ahc->platform_data->qfrozen++;
+	if (ahc->platform_data->qfrozen == 1)
+		scsi_block_requests(ahc->platform_data->host);
+}
+
+static void
+ahc_linux_release_sim_queue(u_long arg)
+{
+	struct ahc_softc *ahc;
+	u_long s;
+	int    unblock_reqs;
+
+	ahc = (struct ahc_softc *)arg;
+	unblock_reqs = 0;
+	ahc_lock(ahc, &s);
+	if (ahc->platform_data->qfrozen > 0)
+		ahc->platform_data->qfrozen--;
+	if (ahc->platform_data->qfrozen == 0) {
+		unblock_reqs = 1;
+	}
+	ahc_unlock(ahc, &s);
+	/*
+	 * There is still a race here.  The mid-layer
+	 * should keep its own freeze count and use
+	 * a bottom half handler to run the queues
+	 * so we can unblock with our own lock held.
+	 */
+	if (unblock_reqs) {
+		scsi_unblock_requests(ahc->platform_data->host);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		tasklet_schedule(&ahc->platform_data->runq_tasklet);
+#else
+		ahc_runq_tasklet((unsigned long)ahc);
+#endif
+	}
+}
+
+static void
+ahc_linux_dev_timed_unfreeze(u_long arg)
+{
+	struct ahc_linux_device *dev;
+	struct ahc_softc *ahc;
+	u_long s;
+
+	dev = (struct ahc_linux_device *)arg;
+	ahc = dev->target->ahc;
+	ahc_lock(ahc, &s);
+	dev->flags &= ~AHC_DEV_TIMER_ACTIVE;
+	if (dev->qfrozen > 0)
+		dev->qfrozen--;
+	if (dev->qfrozen == 0
+	 && (dev->flags & AHC_DEV_ON_RUN_LIST) == 0)
+		ahc_linux_run_device_queue(ahc, dev);
+	ahc_unlock(ahc, &s);
+}
+
+static int
+ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
+{
+	struct ahc_softc *ahc;
+	struct ahc_cmd *acmd;
+	struct ahc_cmd *list_acmd;
+	struct ahc_linux_device *dev;
+	struct scb *pending_scb;
+	u_long s;
+	u_int  saved_scbptr;
+	u_int  active_scb_index;
+	u_int  last_phase;
+	int    retval;
+	int    paused;
+	int    wait;
+	int    disconnected;
+
+	paused = FALSE;
+	wait = FALSE;
+	ahc = *(struct ahc_softc **)cmd->host->hostdata;
+	acmd = (struct ahc_cmd *)cmd;
+
+	printf("%s:%d:%d:%d: Attempting to queue a%s message\n",
+	       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun,
+	       flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
+
+	/*
+	 * It is a bug that the upper layer takes
+	 * this lock just prior to calling us.
+	 */
+	spin_unlock_irq(&io_request_lock);
+
+	ahc_lock(ahc, &s);
+
+	/*
+	 * First determine if we currently own this command.
+	 * Start by searching the device queue.  If not found
+	 * there, check the pending_scb list.  If not found
+	 * at all, and the system wanted us to just abort the
+	 * command return success.
+	 */
+	dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target,
+				   cmd->lun, /*alloc*/FALSE);
+
+	if (dev == NULL) {
+		/*
+		 * No target device for this command exists,
+		 * so we must not still own the command.
+		 */
+		printf("%s:%d:%d:%d: Is not an active device\n",
+		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		retval = SUCCESS;
+		goto no_cmd;
+	}
+
+	TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) {
+		if (list_acmd == acmd)
+			break;
+	}
+
+	if (list_acmd != NULL) {
+		printf("%s:%d:%d:%d: Command found on device queue\n",
+		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		if (flag == SCB_ABORT) {
+			TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
+			cmd->result = DID_ABORT << 16;
+			ahc_linux_queue_cmd_complete(ahc, cmd);
+			retval = SUCCESS;
+			goto done;
+		}
+	}
+
+	if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
+	 && ahc_search_untagged_queues(ahc, cmd, cmd->target,
+				       cmd->channel + 'A', cmd->lun,
+				       CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) {
+		printf("%s:%d:%d:%d: Command found on untagged queue\n",
+		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		retval = SUCCESS;
+		goto done;
+	}
+
+	/*
+	 * See if we can find a matching cmd in the pending list.
+	 */
+	LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
+		if (pending_scb->io_ctx == cmd)
+			break;
+	}
+
+	if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
+
+		/* Any SCB for this device will do for a target reset */
+		LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
+		  	if (ahc_match_scb(ahc, pending_scb, cmd->target,
+					  cmd->channel + 'A', CAM_LUN_WILDCARD,
+					  SCB_LIST_NULL, ROLE_INITIATOR) == 0)
+				break;
+		}
+	}
+
+	if (pending_scb == NULL) {
+		printf("%s:%d:%d:%d: Command not found\n",
+		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		goto no_cmd;
+	}
+
+	if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
+		/*
+		 * We can't queue two recovery actions using the same SCB
+		 */
+		retval = FAILED;
+		goto  done;
+	}
+
+	/*
+	 * Ensure that the card doesn't do anything
+	 * behind our back and that no selections have occurred
+	 * that have not been serviced.  Also make sure that we
+	 * didn't "just" miss an interrupt that would
+	 * affect this cmd.
+	 */
+	ahc->flags |= AHC_ALL_INTERRUPTS;
+	do {
+		if (paused)
+			ahc_unpause(ahc);
+		ahc_intr(ahc);
+		ahc_pause(ahc);
+		paused = TRUE;
+		ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO);
+		ahc_clear_critical_section(ahc);
+	} while ((ahc_inb(ahc, INTSTAT) & INT_PEND) != 0
+	      || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)));
+	ahc->flags &= ~AHC_ALL_INTERRUPTS;
+
+	ahc_dump_card_state(ahc);
+
+	if ((pending_scb->flags & SCB_ACTIVE) == 0) {
+		printf("%s:%d:%d:%d: Command already completed\n",
+		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		goto no_cmd;
+	}
+
+	disconnected = TRUE;
+	if (flag == SCB_ABORT) {
+		if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
+				       cmd->lun, pending_scb->hscb->tag,
+				       ROLE_INITIATOR, CAM_REQ_ABORTED,
+				       SEARCH_COMPLETE) > 0) {
+			printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
+			       ahc_name(ahc), cmd->channel, cmd->target,
+					cmd->lun);
+			retval = SUCCESS;
+			goto done;
+		}
+	} else if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
+				      cmd->lun, pending_scb->hscb->tag,
+				      ROLE_INITIATOR, /*status*/0,
+				      SEARCH_COUNT) > 0) {
+		disconnected = FALSE;
+	}
+
+	if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & IDENTIFY_SEEN) != 0) {
+		struct scb *bus_scb;
+
+		bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG));
+		if (bus_scb == pending_scb)
+			disconnected = FALSE;
+		else if (flag != SCB_ABORT
+		      && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
+		      && ahc_inb(ahc, SAVED_LUN) == pending_scb->hscb->lun)
+			disconnected = FALSE;
+	}
+
+	/*
+	 * At this point, pending_scb is the scb associated with the
+	 * passed in command.  That command is currently active on the
+	 * bus, is in the disconnected state, or we're hoping to find
+	 * a command for the same target active on the bus to abuse to
+	 * send a BDR.  Queue the appropriate message based on which of
+	 * these states we are in.
+	 */
+	last_phase = ahc_inb(ahc, LASTPHASE);
+	saved_scbptr = ahc_inb(ahc, SCBPTR);
+	active_scb_index = ahc_inb(ahc, SCB_TAG);
+	if (last_phase != P_BUSFREE
+	 && (pending_scb->hscb->tag == active_scb_index
+	  || (flag == SCB_DEVICE_RESET
+	   && SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)) == cmd->target))) {
+
+		/*
+		 * We're active on the bus, so assert ATN
+		 * and hope that the target responds.
+		 */
+		pending_scb = ahc_lookup_scb(ahc, active_scb_index);
+		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
+		ahc_outb(ahc, MSG_OUT, HOST_MSG);
+		ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
+		printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
+		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		wait = TRUE;
+	} else if (disconnected) {
+
+		/*
+		 * Actually re-queue this SCB in an attempt
+		 * to select the device before it reconnects.
+		 * In either case (selection or reselection),
+		 * we will now issue the approprate message
+		 * to the timed-out device.
+		 *
+		 * Set the MK_MESSAGE control bit indicating
+		 * that we desire to send a message.  We
+		 * also set the disconnected flag since
+		 * in the paging case there is no guarantee
+		 * that our SCB control byte matches the
+		 * version on the card.  We don't want the
+		 * sequencer to abort the command thinking
+		 * an unsolicited reselection occurred.
+		 */
+		pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
+		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
+
+		/*
+		 * Remove any cached copy of this SCB in the
+		 * disconnected list in preparation for the
+		 * queuing of our abort SCB.  We use the
+		 * same element in the SCB, SCB_NEXT, for
+		 * both the qinfifo and the disconnected list.
+		 */
+		ahc_search_disc_list(ahc, cmd->target, cmd->channel + 'A',
+				     cmd->lun, pending_scb->hscb->tag,
+				     /*stop_on_first*/TRUE,
+				     /*remove*/TRUE,
+				     /*save_state*/FALSE);
+
+		/*
+		 * In the non-paging case, the sequencer will
+		 * never re-reference the in-core SCB.
+		 * To make sure we are notified during
+		 * reslection, set the MK_MESSAGE flag in
+		 * the card's copy of the SCB.
+		 */
+		if ((ahc->flags & AHC_PAGESCBS) == 0) {
+			ahc_outb(ahc, SCBPTR, pending_scb->hscb->tag);
+			ahc_outb(ahc, SCB_CONTROL,
+				 ahc_inb(ahc, SCB_CONTROL)|MK_MESSAGE);
+		}
+
+		/*
+		 * Clear out any entries in the QINFIFO first
+		 * so we are the next SCB for this target
+		 * to run.
+		 */
+		ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
+				   cmd->lun, SCB_LIST_NULL, ROLE_INITIATOR,
+				   CAM_REQUEUE_REQ, SEARCH_COMPLETE);
+		ahc_print_path(ahc, pending_scb);
+		printf("Queuing a recovery SCB\n");
+		ahc_qinfifo_requeue_tail(ahc, pending_scb);
+		ahc_outb(ahc, SCBPTR, saved_scbptr);
+		printf("%s:%d:%d:%d: Device is disconnected, re-queuing SCB\n",
+		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		wait = TRUE;
+	} else {
+		printf("%s:%d:%d:%d: Unable to deliver message\n",
+		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		retval = FAILED;
+		goto done;
+	}
+
+no_cmd:
+	/*
+	 * Our assumption is that if we don't have the command, no
+	 * recovery action was required, so we return success.  Again,
+	 * the semantics of the mid-layer recovery engine are not
+	 * well defined, so this may change in time.
+	 */
+	retval = SUCCESS;
+done:
+	if (paused)
+		ahc_unpause(ahc);
+	if (wait) {
+		struct timer_list timer;
+		int ret;
+
+		ahc_unlock(ahc, &s);
+		init_timer(&timer);
+		timer.data = (u_long)&ahc->platform_data->eh_sem;
+		timer.expires = jiffies + (5 * HZ);
+		timer.function = ahc_linux_sem_timeout;
+		add_timer(&timer);
+		printf("Recovery code sleeping\n");
+		down(&ahc->platform_data->eh_sem);
+		printf("Recovery code awake\n");
+        	ret = del_timer(&timer);
+		if (ret == 0) {
+			printf("Timer Expired\n");
+			retval = FAILED;
+		}
+		ahc_lock(ahc, &s);
+	}
+	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
+	TAILQ_INIT(&ahc->platform_data->completeq);
+	ahc_unlock(ahc, &s);
+	if (acmd != NULL)
+		ahc_linux_run_complete_queue(ahc, acmd);
+	ahc_runq_tasklet((unsigned long)ahc);
+	spin_lock_irq(&io_request_lock);
+	return (retval);
+}
+
+/*
+ * Abort the current SCSI command(s).
+ */
+int
+ahc_linux_abort(Scsi_Cmnd *cmd)
+{
+	int error;
+
+	error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
+	if (error != 0)
+		printf("aic7xxx_abort returns 0x%x\n", error);
+	return (error);
+}
+
+/*
+ * Attempt to send a target reset message to the device that timed out.
+ */
+int
+ahc_linux_dev_reset(Scsi_Cmnd *cmd)
+{
+	int error;
+
+	error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
+	if (error != 0)
+		printf("aic7xxx_dev_reset returns 0x%x\n", error);
+	return (error);
+}
+
+/*
+ * Reset the SCSI bus.
+ */
+int
+ahc_linux_bus_reset(Scsi_Cmnd *cmd)
+{
+	struct ahc_softc *ahc;
+	struct ahc_cmd *acmd;
+	u_long s;
+	int    found;
+
+	/*
+	 * It is a bug that the upper layer takes
+	 * this lock just prior to calling us.
+	 */
+	spin_unlock_irq(&io_request_lock);
+
+	ahc = *(struct ahc_softc **)cmd->host->hostdata;
+	ahc_lock(ahc, &s);
+	found = ahc_reset_channel(ahc, cmd->channel + 'A',
+				  /*initiate reset*/TRUE);
+	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
+	TAILQ_INIT(&ahc->platform_data->completeq);
+	ahc_unlock(ahc, &s);
+	if (bootverbose)
+		printf("%s: SCSI bus reset delivered. "
+		       "%d SCBs aborted.\n", ahc_name(ahc), found);
+
+	if (acmd != NULL)
+		ahc_linux_run_complete_queue(ahc, acmd);
+
+	spin_lock_irq(&io_request_lock);
+	return SUCCESS;
+}
+
+/*
+ * Return the disk geometry for the given SCSI device.
+ */
+int
+ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
+{
+	int	heads;
+	int	sectors;
+	int	cylinders;
+	int	ret;
+	int	extended;
+	struct	ahc_softc *ahc;
+	struct	buffer_head *bh;
+
+	ahc = *((struct ahc_softc **)disk->device->host->hostdata);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17)
+	bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev));
+#else
+	bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024);
+#endif
+
+	if (bh) {
+		ret = scsi_partsize(bh, disk->capacity,
+				    &geom[2], &geom[0], &geom[1]);
+		brelse(bh);
+		if (ret != -1)
+			return (ret);
+	}
+	heads = 64;
+	sectors = 32;
+	cylinders = disk->capacity / (heads * sectors);
+
+	if (aic7xxx_extended != 0)
+		extended = 1;
+	else if (disk->device->channel == 0)
+		extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0;
+	else
+		extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0;
+	if (extended && cylinders >= 1024) {
+		heads = 255;
+		sectors = 63;
+		cylinders = disk->capacity / (heads * sectors);
+	}
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = cylinders;
+	return (0);
+}
+
+/*
+ * Free the passed in Scsi_Host memory structures prior to unloading the
+ * module.
+ */
+int
+ahc_linux_release(struct Scsi_Host * host)
+{
+	struct ahc_softc *ahc;
+	u_long l;
+
+	ahc_list_lock(&l);
+	if (host != NULL) {
+
+		/*
+		 * We should be able to just perform
+		 * the free directly, but check our
+		 * list for extra sanity.
+		 */
+		ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata);
+		if (ahc != NULL) {
+			u_long s;
+
+			ahc_lock(ahc, &s);
+			ahc_intr_enable(ahc, FALSE);
+			ahc_unlock(ahc, &s);
+			ahc_free(ahc);
+		}
+	}
+	ahc_list_unlock(&l);
+	return (0);
+}
+
+void
+ahc_platform_dump_card_state(struct ahc_softc *ahc)
+{
+	struct ahc_linux_device *dev;
+	int channel;
+	int maxchannel;
+	int target;
+	int maxtarget;
+	int lun;
+	int i;
+
+	maxchannel = (ahc->features & AHC_TWIN) ? 1 : 0;
+	maxtarget = (ahc->features & AHC_WIDE) ? 15 : 7;
+	for (channel = 0; channel <= maxchannel; channel++) {
+
+		for (target = 0; target <=maxtarget; target++) {
+
+			for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
+				struct ahc_cmd *acmd;
+
+				dev = ahc_linux_get_device(ahc, channel, target,
+							   lun, /*alloc*/FALSE);
+				if (dev == NULL)
+					continue;
+
+				printf("DevQ(%d:%d:%d): ",
+				       channel, target, lun);
+				i = 0;
+				TAILQ_FOREACH(acmd, &dev->busyq,
+					      acmd_links.tqe) {
+					if (i++ > AHC_SCB_MAX)
+						break;
+				}
+				printf("%d waiting\n", i);
+			}
+		}
+	}
+}
+
+#if defined(MODULE) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+static Scsi_Host_Template driver_template = AIC7XXX;
+Scsi_Host_Template *aic7xxx_driver_template = &driver_template;
+#include "../scsi_module.c"
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_osm.h linux/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_osm.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_osm.h	2002-07-20 01:08:32.000000000 +0000
@@ -18,7 +18,7 @@
  * along with this program; see the file COPYING.  If not, write to
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  * 
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_linux.h#72 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#82 $
  *
  * Copyright (c) 2000-2001 Adaptec Inc.
  * All rights reserved.
@@ -55,7 +55,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_linux.h#72 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#82 $
  *
  */
 #ifndef _AIC7XXX_LINUX_H_
@@ -66,9 +66,11 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/version.h>
+#ifndef AHC_MODVERSION_FILE
+#define __NO_VERSION__
+#endif
 #include <linux/module.h>
 #include <asm/byteorder.h>
 
@@ -77,7 +79,11 @@
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#include <linux/interrupt.h> /* For tasklet support. */
 #include <linux/config.h>
+#include <linux/slab.h>
+#else
+#include <linux/malloc.h>
 #endif
 
 /* Core SCSI definitions */
@@ -391,7 +397,7 @@
 
 /********************************** Includes **********************************/
 /* Host template and function declarations referenced by the template. */
-#include "aic7xxx_linux_host.h"
+#include "aic7xxx_host.h"
 
 /* Core driver definitions */
 #include "aic7xxx.h"
@@ -403,7 +409,7 @@
 #include <linux/smp.h>
 #endif
 
-#define AIC7XXX_DRIVER_VERSION  "6.2.4"
+#define AIC7XXX_DRIVER_VERSION  "6.2.8"
 
 /**************************** Front End Queues ********************************/
 /*
@@ -462,7 +468,7 @@
 	 * The number of transactions currently
 	 * queued to the device.
 	 */
-	int		active;
+	int			active;
 
 	/*
 	 * The currently allowed number of 
@@ -472,18 +478,18 @@
 	 * mode where the device may have more
 	 * than one outstanding active transaction.
 	 */
-	int		openings;
+	int			openings;
 
 	/*
 	 * A positive count indicates that this
 	 * device's queue is halted.
 	 */
-	u_int		qfrozen;
+	u_int			qfrozen;
 	
 	/*
 	 * Cumulative command counter.
 	 */
-	u_long		commands_issued;
+	u_long			commands_issued;
 
 	/*
 	 * The number of tagged transactions when
@@ -491,21 +497,26 @@
 	 * that have been successfully received by
 	 * this device since the last QUEUE FULL.
 	 */
-	u_int		tag_success_count;
+	u_int			tag_success_count;
 #define AHC_TAG_SUCCESS_INTERVAL 50
 
-	ahc_dev_flags	flags;
+	ahc_dev_flags		flags;
+
+	/*
+	 * Per device timer.
+	 */
+	struct timer_list	timer;
 
 	/*
 	 * The high limit for the tags variable.
 	 */
-	u_int		maxtags;
+	u_int			maxtags;
 
 	/*
 	 * The computed number of tags outstanding
 	 * at the time of the last QUEUE FULL event.
 	 */
-	u_int		tags_on_last_queuefull;
+	u_int			tags_on_last_queuefull;
 
 	/*
 	 * How many times we have seen a queue full
@@ -513,7 +524,7 @@
 	 * to stop our adaptive queue depth algorithm
 	 * on devices with a fixed number of tags.
 	 */
-	u_int		last_queuefull_same_count;
+	u_int			last_queuefull_same_count;
 #define AHC_LOCK_TAGS_COUNT 50
 
 	/*
@@ -525,11 +536,11 @@
 	 * if the AHC_DEV_PERIODIC_OTAG flag is set
 	 * on this device.
 	 */
-	u_int		commands_since_idle_or_otag;
+	u_int			commands_since_idle_or_otag;
 #define AHC_OTAG_THRESH	500
 
-	int		lun;
-	struct		ahc_linux_target *target;
+	int			lun;
+	struct			ahc_linux_target *target;
 };
 
 struct ahc_linux_target {
@@ -538,6 +549,7 @@
 	int	target;
 	int	refcount;
 	struct	ahc_transinfo last_tinfo;
+	struct	ahc_softc *ahc;
 };
 
 /********************* Definitions Required by the Core ***********************/
@@ -554,6 +566,7 @@
  */
 struct scb_platform_data {
 	struct ahc_linux_device	*dev;
+	bus_addr_t		 buf_busaddr;
 	uint32_t		 xfer_len;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
 	uint32_t		 resid;		/* Transfer residual */
@@ -575,13 +588,17 @@
 	TAILQ_HEAD(, ahc_linux_device) device_runq;
 	struct ahc_completeq	 completeq;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
 	spinlock_t		 spin_lock;
 #endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	struct tasklet_struct	 runq_tasklet;
+#endif
 	u_int			 qfrozen;
 	struct timer_list	 reset_timer;
 	struct semaphore	 eh_sem;
 	struct Scsi_Host        *host;		/* pointer to scsi host */
+#define AHC_LINUX_NOIRQ	((uint32_t)~0)
 	uint32_t		 irq;		/* IRQ for this adapter */
 	uint32_t		 bios_address;
 	uint32_t		 mem_busaddr;	/* Mem Base Addr */
@@ -712,6 +729,12 @@
 static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags);
 static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);
 
+/* Lock held during ahc_list manipulation and ahc softc frees */
+extern spinlock_t ahc_list_spinlock;
+static __inline void ahc_list_lockinit(void);
+static __inline void ahc_list_lock(unsigned long *flags);
+static __inline void ahc_list_unlock(unsigned long *flags);
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
 static __inline void
 ahc_lockinit(struct ahc_softc *ahc)
@@ -751,6 +774,25 @@
 	spin_unlock_irqrestore(&io_request_lock, *flags);
 }
 
+static __inline void
+ahc_list_lockinit()
+{
+	spin_lock_init(&ahc_list_spinlock);
+}
+
+static __inline void
+ahc_list_lock(unsigned long *flags)
+{
+	*flags = 0;
+	spin_lock_irqsave(&ahc_list_spinlock, *flags);
+}
+
+static __inline void
+ahc_list_unlock(unsigned long *flags)
+{
+	spin_unlock_irqrestore(&ahc_list_spinlock, *flags);
+}
+
 #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */
 
 ahc_lockinit(struct ahc_softc *ahc)
@@ -771,6 +813,7 @@
 	restore_flags(*flags);
 }
 
+static __inline void
 ahc_done_lockinit(struct ahc_softc *ahc)
 {
 }
@@ -789,6 +832,25 @@
 ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
 {
 }
+
+static __inline void
+ahc_list_lockinit()
+{
+}
+
+static __inline void
+ahc_list_lock(unsigned long *flags)
+{
+	*flags = 0;
+	save_flags(*flags);
+	cli();
+}
+
+static __inline void
+ahc_list_unlock(unsigned long *flags)
+{
+	restore_flags(*flags);
+}
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */
 
 /******************************* PCI Definitions ******************************/
@@ -843,7 +905,8 @@
 			    ahc_power_state new_state);
 /**************************** VL/EISA Routines ********************************/
 int			 aic7770_linux_probe(Scsi_Host_Template *);
-int			 aic7770_map_registers(struct ahc_softc *ahc);
+int			 aic7770_map_registers(struct ahc_softc *ahc,
+					       u_int port);
 int			 aic7770_map_int(struct ahc_softc *ahc, u_int irq);
 
 /******************************* PCI Routines *********************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,416 @@
+/*
+ * Linux driver attachment glue for PCI based controllers.
+ *
+ * Copyright (c) 2000-2001 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#32 $
+ */
+
+#include "aic7xxx_osm.h"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+struct pci_device_id
+{
+};
+#endif
+
+static int	ahc_linux_pci_dev_probe(struct pci_dev *pdev,
+					const struct pci_device_id *ent);
+static int	ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
+						u_long *base);
+#ifdef MMAPIO
+static int	ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
+						 u_long *bus_addr,
+						 uint8_t **maddr);
+#endif /* MMAPIO */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+static void	ahc_linux_pci_dev_remove(struct pci_dev *pdev);
+
+/* We do our own ID filtering.  So, grab all SCSI storage class devices. */
+static struct pci_device_id ahc_linux_pci_id_table[] = {
+	{
+		0x9004, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0
+	},
+	{
+		0x9005, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table);
+
+struct pci_driver aic7xxx_pci_driver = {
+	name:		"aic7xxx",
+	probe:		ahc_linux_pci_dev_probe,
+	remove:		ahc_linux_pci_dev_remove,
+	id_table:	ahc_linux_pci_id_table
+};
+
+static void
+ahc_linux_pci_dev_remove(struct pci_dev *pdev)
+{
+	struct ahc_softc *ahc;
+	u_long l;
+
+	/*
+	 * We should be able to just perform
+	 * the free directly, but check our
+	 * list for extra sanity.
+	 */
+	ahc_list_lock(&l);
+	ahc = ahc_find_softc((struct ahc_softc *)pdev->driver_data);
+	if (ahc != NULL) {
+		u_long s;
+
+		ahc_lock(ahc, &s);
+		ahc_intr_enable(ahc, FALSE);
+		ahc_unlock(ahc, &s);
+		ahc_free(ahc);
+	}
+	ahc_list_unlock(&l);
+}
+#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */
+
+static int
+ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	char		 buf[80];
+	struct		 ahc_softc *ahc;
+	ahc_dev_softc_t	 pci;
+	struct		 ahc_pci_identity *entry;
+	char		*name;
+	int		 error;
+
+	/*
+	 * Some BIOSen report the same device multiple times.
+	 */
+	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
+		struct pci_dev *probed_pdev;
+
+		probed_pdev = ahc->dev_softc;
+		if (probed_pdev->bus->number == pdev->bus->number
+		 && probed_pdev->devfn == pdev->devfn)
+			break;
+	}
+	if (ahc != NULL) {
+		/* Skip duplicate. */
+		return (-ENODEV);
+	}
+
+	pci = pdev;
+	entry = ahc_find_pci_device(pci);
+	if (entry == NULL)
+		return (-ENODEV);
+
+	/*
+	 * Allocate a softc for this card and
+	 * set it up for attachment by our
+	 * common detect routine.
+	 */
+	sprintf(buf, "ahc_pci:%d:%d:%d",
+		ahc_get_pci_bus(pci),
+		ahc_get_pci_slot(pci),
+		ahc_get_pci_function(pci));
+	name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+	if (name == NULL)
+		return (-ENOMEM);
+	strcpy(name, buf);
+	ahc = ahc_alloc(NULL, name);
+	if (ahc == NULL)
+		return (-ENOMEM);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	if (pci_enable_device(pdev)) {
+		ahc_free(ahc);
+		return (-ENODEV);
+	}
+	pci_set_master(pdev);
+
+	if (sizeof(bus_addr_t) > 4
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
+	 && ahc_linux_get_memsize() > 0x80000000
+	 && pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) {
+#else
+	 && ahc_linux_get_memsize() > 0x80000000) {
+
+		ahc->dev_softc->dma_mask = 
+		    (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
+#endif
+		ahc->flags |= AHC_39BIT_ADDRESSING;
+		ahc->platform_data->hw_dma_mask =
+		    (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
+	}
+#endif
+	ahc->dev_softc = pci;
+	error = ahc_pci_config(ahc, entry);
+	if (error != 0) {
+		ahc_free(ahc);
+		return (-error);
+	}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	pci_set_drvdata(pdev, ahc);
+	if (aic7xxx_detect_complete)
+		ahc_linux_register_host(ahc, aic7xxx_driver_template);
+#endif
+	return (0);
+}
+
+int
+ahc_linux_pci_probe(Scsi_Host_Template *template)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	return (pci_module_init(&aic7xxx_pci_driver));
+#else
+	struct pci_dev *pdev;
+	u_int class;
+	int found;
+
+	/* If we don't have a PCI bus, we can't find any adapters. */
+	if (pci_present() == 0)
+		return (0);
+
+	found = 0;
+	pdev = NULL;
+	class = PCI_CLASS_STORAGE_SCSI << 8;
+	while ((pdev = pci_find_class(class, pdev)) != NULL) {
+		ahc_dev_softc_t pci;
+		int error;
+
+		pci = pdev;
+		error = ahc_linux_pci_dev_probe(pdev, /*pci_devid*/NULL);
+		if (error == 0)
+			found++;
+	}
+	return (found);
+#endif
+}
+
+static int
+ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	*base = pci_resource_start(ahc->dev_softc, 0);
+#else
+	*base = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS, 4);
+	*base &= PCI_BASE_ADDRESS_IO_MASK;
+#endif
+	if (*base == 0)
+		return (ENOMEM);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+	if (check_region(*base, 256) != 0)
+		return (ENOMEM);
+	else
+		request_region(*base, 256, "aic7xxx");
+#else
+	if (request_region(*base, 256, "aic7xxx") == 0)
+		return (ENOMEM);
+#endif
+	return (0);
+}
+
+#ifdef MMAPIO
+static int
+ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
+				 u_long *bus_addr,
+				 uint8_t **maddr)
+{
+	u_long	start;
+	u_long	base_page;
+	u_long	base_offset;
+	int	error;
+
+	error = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	start = pci_resource_start(ahc->dev_softc, 1);
+	base_page = start & PAGE_MASK;
+	base_offset = start - base_page;
+#else
+	start = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS+4, 4);
+	base_offset = start & PCI_BASE_ADDRESS_MEM_MASK;
+	base_page = base_offset & PAGE_MASK;
+	base_offset -= base_page;
+#endif
+	if (start != 0) {
+		*bus_addr = start;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		if (request_mem_region(start, 0x1000, "aic7xxx") == 0)
+			error = ENOMEM;
+#endif
+		if (error == 0) {
+			*maddr = ioremap_nocache(base_page, base_offset + 256);
+			if (*maddr == NULL) {
+				error = ENOMEM;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+				release_mem_region(start, 0x1000);
+#endif
+			} else
+				*maddr += base_offset;
+		}
+	} else
+		error = ENOMEM;
+	return (error);
+}
+#endif /* MMAPIO */
+
+int
+ahc_pci_map_registers(struct ahc_softc *ahc)
+{
+	uint32_t command;
+	u_long	 base;
+	uint8_t	*maddr;
+	int	 error;
+
+	/*
+	 * If its allowed, we prefer memory mapped access.
+	 */
+	command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 4);
+	command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
+	base = 0;
+	maddr = NULL;
+#ifdef MMAPIO
+	error = ahc_linux_pci_reserve_mem_region(ahc, &base, &maddr);
+	if (error == 0) {
+		ahc->platform_data->mem_busaddr = base;
+		ahc->tag = BUS_SPACE_MEMIO;
+		ahc->bsh.maddr = maddr;
+		ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
+				     command | PCIM_CMD_MEMEN, 4);
+
+		/*
+		 * Do a quick test to see if memory mapped
+		 * I/O is functioning correctly.
+		 */
+		if (ahc_inb(ahc, HCNTRL) == 0xFF) {
+
+			printf("aic7xxx: PCI Device %d:%d:%d "
+			       "failed memory mapped test\n",
+			       ahc_get_pci_bus(ahc->dev_softc),
+			       ahc_get_pci_slot(ahc->dev_softc),
+			       ahc_get_pci_function(ahc->dev_softc));
+			iounmap((void *)((u_long)maddr & PAGE_MASK));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+			release_mem_region(ahc->platform_data->mem_busaddr,
+					   0x1000);
+#endif
+			ahc->bsh.maddr = NULL;
+			maddr = NULL;
+		} else
+			command |= PCIM_CMD_MEMEN;
+	} else {
+		printf("aic7xxx: PCI%d:%d:%d MEM region 0x%lx "
+		       "unavailable. Cannot memory map device.\n",
+		       ahc_get_pci_bus(ahc->dev_softc),
+		       ahc_get_pci_slot(ahc->dev_softc),
+		       ahc_get_pci_function(ahc->dev_softc),
+		       base);
+	}
+#endif /* MMAPIO */
+
+	/*
+	 * We always prefer memory mapped access.
+	 */
+	if (maddr == NULL) {
+
+		error = ahc_linux_pci_reserve_io_region(ahc, &base);
+		if (error == 0) {
+			ahc->tag = BUS_SPACE_PIO;
+			ahc->bsh.ioport = base;
+			command |= PCIM_CMD_PORTEN;
+		} else {
+			printf("aic7xxx: PCI%d:%d:%d IO region 0x%lx[0..255] "
+			       "unavailable. Cannot map device.\n",
+			       ahc_get_pci_bus(ahc->dev_softc),
+			       ahc_get_pci_slot(ahc->dev_softc),
+			       ahc_get_pci_function(ahc->dev_softc),
+			       base);
+		}
+	}
+	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 4);
+	return (error);
+}
+
+int
+ahc_pci_map_int(struct ahc_softc *ahc)
+{
+	int error;
+
+	error = request_irq(ahc->dev_softc->irq, ahc_linux_isr,
+			    SA_SHIRQ, "aic7xxx", ahc);
+	if (error == 0)
+		ahc->platform_data->irq = ahc->dev_softc->irq;
+	
+	return (-error);
+}
+
+void
+ahc_power_state_change(struct ahc_softc *ahc, ahc_power_state new_state)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	pci_set_power_state(ahc->dev_softc, new_state);
+#else
+	uint32_t cap;
+	u_int cap_offset;
+
+	/*
+	 * Traverse the capability list looking for
+	 * the power management capability.
+	 */
+	cap = 0;
+	cap_offset = ahc_pci_read_config(ahc->dev_softc,
+					 PCIR_CAP_PTR, /*bytes*/1);
+	while (cap_offset != 0) {
+
+		cap = ahc_pci_read_config(ahc->dev_softc,
+					  cap_offset, /*bytes*/4);
+		if ((cap & 0xFF) == 1
+		 && ((cap >> 16) & 0x3) > 0) {
+			uint32_t pm_control;
+
+			pm_control = ahc_pci_read_config(ahc->dev_softc,
+							 cap_offset + 4,
+							 /*bytes*/4);
+			pm_control &= ~0x3;
+			pm_control |= new_state;
+			ahc_pci_write_config(ahc->dev_softc,
+					     cap_offset + 4,
+					     pm_control, /*bytes*/2);
+			break;
+		}
+		cap_offset = (cap >> 8) & 0xFF;
+	}
+#endif 
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_pci.c linux/drivers/scsi/aic7xxx/aic7xxx_pci.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_pci.c	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_pci.c	2002-07-20 01:08:24.000000000 +0000
@@ -39,14 +39,20 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#32 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#46 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_pci.c,v 1.6 2000/11/10 20:13:41 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_pci.c,v 1.2.2.14 2002/04/29 19:36:31 gibbs Exp $
  */
 
+#ifdef __linux__
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
 #include "aic7xxx_93cx6.h"
+#else
+#include <dev/aic7xxx/aic7xxx_osm.h>
+#include <dev/aic7xxx/aic7xxx_inline.h>
+#include <dev/aic7xxx/aic7xxx_93cx6.h>
+#endif
 
 #define AHC_PCI_IOADDR	PCIR_MAPS	/* I/O Address */
 #define AHC_PCI_MEMADDR	(PCIR_MAPS + 4)	/* Mem I/O Address */
@@ -207,7 +213,7 @@
 	 : ((id) & 0x1000) >> 12)
 /*
  * Informational only. Should use chip register to be
- * ceratian, but may be use in identification strings.
+ * certain, but may be use in identification strings.
  */
 #define SUBID_9005_CARD_SCSIWIDTH_MASK	0x2000
 #define SUBID_9005_CARD_PCIWIDTH_MASK	0x4000
@@ -661,6 +667,8 @@
 				  int pcheck, int fast, int large);
 static void ahc_probe_ext_scbram(struct ahc_softc *ahc);
 static void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1);
+static void ahc_parse_pci_eeprom(struct ahc_softc *ahc,
+				 struct seeprom_config *sc);
 static void configure_termination(struct ahc_softc *ahc,
 				  struct seeprom_descriptor *sd,
 				  u_int adapter_control,
@@ -679,9 +687,6 @@
 static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
 				 int *externalcable_present,
 				 int *eeprom_present);
-static int acquire_seeprom(struct ahc_softc *ahc,
-			   struct seeprom_descriptor *sd);
-static void release_seeprom(struct seeprom_descriptor *sd);
 static void write_brdctl(struct ahc_softc *ahc, uint8_t value);
 static uint8_t read_brdctl(struct ahc_softc *ahc);
 
@@ -767,6 +772,8 @@
 ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
 {
 	struct scb_data *shared_scb_data;
+	u_long		 l;
+	u_long		 s;
 	u_int		 command;
 	u_int		 our_id = 0;
 	u_int		 sxfrctl1;
@@ -782,11 +789,19 @@
 	ahc->chip |= AHC_PCI;
 	ahc->description = entry->name;
 
+	ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
+
 	error = ahc_pci_map_registers(ahc);
 	if (error != 0)
 		return (error);
 
-	ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
+	/*
+	 * Before we continue probing the card, ensure that
+	 * its interrupts are *disabled*.  We don't want
+	 * a misstep to hang the machine in an interrupt
+	 * storm.
+	 */
+	ahc_intr_enable(ahc, FALSE);
 
 	/*
 	 * If we need to support high memory, enable dual
@@ -964,19 +979,23 @@
 		return (error);
 
 	/*
-	 * Link this softc in with all other ahc instances.
-	 */
-	ahc_softc_insert(ahc);
-
-	/*
 	 * Allow interrupts now that we are completely setup.
 	 */
 	error = ahc_pci_map_int(ahc);
 	if (error != 0)
 		return (error);
 
+	ahc_list_lock(&l);
+	/*
+	 * Link this softc in with all other ahc instances.
+	 */
+	ahc_softc_insert(ahc);
+
+	ahc_lock(ahc, &s);
 	ahc_intr_enable(ahc, TRUE);
+	ahc_unlock(ahc, &s);
 
+	ahc_list_unlock(&l);
 	return (0);
 }
 
@@ -999,6 +1018,14 @@
 
 	if ((ahc->features & AHC_ULTRA2) != 0)
 		ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0;
+	else if (chip == AHC_AIC7895 || chip == AHC_AIC7895C)
+		/*
+		 * External SCBRAM arbitration is flakey
+		 * on these chips.  Unfortunately this means
+		 * we don't use the extra SCB ram space on the
+		 * 3940AUW.
+		 */
+		ramps = 0;
 	else if (chip >= AHC_AIC7870)
 		ramps = (devconfig & RAMPSM) != 0;
 	else
@@ -1026,6 +1053,9 @@
 		ahc_outb(ahc, SCBBADDR, ahc_get_pci_function(ahc->dev_softc));
 	}
 
+	ahc->flags &= ~AHC_LSCBS_ENABLED;
+	if (large)
+		ahc->flags |= AHC_LSCBS_ENABLED;
 	devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
 	if ((ahc->features & AHC_ULTRA2) != 0) {
 		u_int dscommand0;
@@ -1172,9 +1202,7 @@
 check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
 {
 	struct	seeprom_descriptor sd;
-	struct	seeprom_config sc;
-	u_int	scsi_conf;
-	u_int	adapter_control;
+	struct	seeprom_config *sc;
 	int	have_seeprom;
 	int	have_autoterm;
 
@@ -1182,6 +1210,7 @@
 	sd.sd_control_offset = SEECTL;		
 	sd.sd_status_offset = SEECTL;		
 	sd.sd_dataout_offset = SEECTL;		
+	sc = ahc->seep_config;
 
 	/*
 	 * For some multi-channel devices, the c46 is simply too
@@ -1201,7 +1230,7 @@
 	sd.sd_DO = SEEDO;
 	sd.sd_DI = SEEDI;
 
-	have_seeprom = acquire_seeprom(ahc, &sd);
+	have_seeprom = ahc_acquire_seeprom(ahc, &sd);
 	if (have_seeprom) {
 
 		if (bootverbose) 
@@ -1212,11 +1241,12 @@
 
 			start_addr = 32 * (ahc->channel - 'A');
 
-			have_seeprom = read_seeprom(&sd, (uint16_t *)&sc,
-						    start_addr, sizeof(sc)/2);
+			have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
+							start_addr,
+							sizeof(*sc)/2);
 
 			if (have_seeprom)
-				have_seeprom = verify_cksum(&sc);
+				have_seeprom = ahc_verify_cksum(sc);
 
 			if (have_seeprom != 0 || sd.sd_chip == C56_66) {
 				if (bootverbose) {
@@ -1229,7 +1259,7 @@
 			}
 			sd.sd_chip = C56_66;
 		}
-		release_seeprom(&sd);
+		ahc_release_seeprom(&sd);
 	}
 
 	if (!have_seeprom) {
@@ -1248,7 +1278,7 @@
 			uint16_t *sc_data;
 			int	  i;
 
-			sc_data = (uint16_t *)&sc;
+			sc_data = (uint16_t *)sc;
 			for (i = 0; i < 32; i++) {
 				uint16_t val;
 				int	 j;
@@ -1257,129 +1287,27 @@
 				val = ahc_inb(ahc, SRAM_BASE + j)
 				    | ahc_inb(ahc, SRAM_BASE + j + 1) << 8;
 			}
-			have_seeprom = verify_cksum(&sc);
+			have_seeprom = ahc_verify_cksum(sc);
+			if (have_seeprom)
+				ahc->flags |= AHC_SCB_CONFIG_USED;
 		}
+		/*
+		 * Clear any SCB parity errors in case this data and
+		 * its associated parity was not initialized by the BIOS
+		 */
+		ahc_outb(ahc, CLRINT, CLRPARERR);
+		ahc_outb(ahc, CLRINT, CLRBRKADRINT);
 	}
 
 	if (!have_seeprom) {
 		if (bootverbose)
 			printf("%s: No SEEPROM available.\n", ahc_name(ahc));
 		ahc->flags |= AHC_USEDEFAULTS;
+		free(ahc->seep_config, M_DEVBUF);
+		ahc->seep_config = NULL;
+		sc = NULL;
 	} else {
-		/*
-		 * Put the data we've collected down into SRAM
-		 * where ahc_init will find it.
-		 */
-		int i;
-		int max_targ = sc.max_targets & CFMAXTARG;
-		uint16_t discenable;
-		uint16_t ultraenb;
-
-		discenable = 0;
-		ultraenb = 0;
-		if ((sc.adapter_control & CFULTRAEN) != 0) {
-			/*
-			 * Determine if this adapter has a "newstyle"
-			 * SEEPROM format.
-			 */
-			for (i = 0; i < max_targ; i++) {
-				if ((sc.device_flags[i] & CFSYNCHISULTRA) != 0){
-					ahc->flags |= AHC_NEWEEPROM_FMT;
-					break;
-				}
-			}
-		}
-
-		for (i = 0; i < max_targ; i++) {
-			u_int     scsirate;
-			uint16_t target_mask;
-
-			target_mask = 0x01 << i;
-			if (sc.device_flags[i] & CFDISC)
-				discenable |= target_mask;
-			if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) {
-				if ((sc.device_flags[i] & CFSYNCHISULTRA) != 0)
-					ultraenb |= target_mask;
-			} else if ((sc.adapter_control & CFULTRAEN) != 0) {
-				ultraenb |= target_mask;
-			}
-			if ((sc.device_flags[i] & CFXFER) == 0x04
-			 && (ultraenb & target_mask) != 0) {
-				/* Treat 10MHz as a non-ultra speed */
-				sc.device_flags[i] &= ~CFXFER;
-			 	ultraenb &= ~target_mask;
-			}
-			if ((ahc->features & AHC_ULTRA2) != 0) {
-				u_int offset;
-
-				if (sc.device_flags[i] & CFSYNCH)
-					offset = MAX_OFFSET_ULTRA2;
-				else 
-					offset = 0;
-				ahc_outb(ahc, TARG_OFFSET + i, offset);
-
-				/*
-				 * The ultra enable bits contain the
-				 * high bit of the ultra2 sync rate
-				 * field.
-				 */
-				scsirate = (sc.device_flags[i] & CFXFER)
-					 | ((ultraenb & target_mask)
-					    ? 0x8 : 0x0);
-				if (sc.device_flags[i] & CFWIDEB)
-					scsirate |= WIDEXFER;
-			} else {
-				scsirate = (sc.device_flags[i] & CFXFER) << 4;
-				if (sc.device_flags[i] & CFSYNCH)
-					scsirate |= SOFS;
-				if (sc.device_flags[i] & CFWIDEB)
-					scsirate |= WIDEXFER;
-			}
-			ahc_outb(ahc, TARG_SCSIRATE + i, scsirate);
-		}
-		ahc->our_id = sc.brtime_id & CFSCSIID;
-
-		scsi_conf = (ahc->our_id & 0x7);
-		if (sc.adapter_control & CFSPARITY)
-			scsi_conf |= ENSPCHK;
-		if (sc.adapter_control & CFRESETB)
-			scsi_conf |= RESET_SCSI;
-
-		ahc->flags |=
-		    (sc.adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT;
-
-		if (sc.bios_control & CFEXTEND)
-			ahc->flags |= AHC_EXTENDED_TRANS_A;
-
-		if (sc.bios_control & CFBIOSEN)
-			ahc->flags |= AHC_BIOS_ENABLED;
-		if (ahc->features & AHC_ULTRA
-		 && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) {
-			/* Should we enable Ultra mode? */
-			if (!(sc.adapter_control & CFULTRAEN))
-				/* Treat us as a non-ultra card */
-				ultraenb = 0;
-		}
-
-		if (sc.signature == CFSIGNATURE
-		 || sc.signature == CFSIGNATURE2) {
-			uint32_t devconfig;
-
-			/* Honor the STPWLEVEL settings */
-			devconfig = ahc_pci_read_config(ahc->dev_softc,
-							DEVCONFIG, /*bytes*/4);
-			devconfig &= ~STPWLEVEL;
-			if ((sc.bios_control & CFSTPWLEVEL) != 0)
-				devconfig |= STPWLEVEL;
-			ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
-					     devconfig, /*bytes*/4);
-		}
-		/* Set SCSICONF info */
-		ahc_outb(ahc, SCSICONF, scsi_conf);
-		ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
-		ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
-		ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff);
-		ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff);
+		ahc_parse_pci_eeprom(ahc, sc);
 	}
 
 	/*
@@ -1389,10 +1317,6 @@
 	 * hasn't failed yet...
 	 */
 	have_autoterm = have_seeprom;
-	if (have_seeprom)
-		adapter_control = sc.adapter_control;
-	else
-		adapter_control = CFAUTOTERM;
 
 	/*
 	 * Some low-cost chips have SEEPROM and auto-term control built
@@ -1400,17 +1324,141 @@
 	 * if the termination logic is enabled.
 	 */
 	if ((ahc->features & AHC_SPIOCAP) != 0) {
-		if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) != 0)
-			have_autoterm = TRUE;
-		else
+		if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) == 0)
 			have_autoterm = FALSE;
 	}
 
 	if (have_autoterm) {
-		acquire_seeprom(ahc, &sd);
-		configure_termination(ahc, &sd, adapter_control, sxfrctl1);
-		release_seeprom(&sd);
+		ahc_acquire_seeprom(ahc, &sd);
+		configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1);
+		ahc_release_seeprom(&sd);
+	} else if (have_seeprom) {
+		*sxfrctl1 &= ~STPWEN;
+		if ((sc->adapter_control & CFSTERM) != 0)
+			*sxfrctl1 |= STPWEN;
+		if (bootverbose)
+			printf("%s: Low byte termination %sabled\n",
+			       ahc_name(ahc),
+			       (*sxfrctl1 & STPWEN) ? "en" : "dis");
+	}
+}
+
+static void
+ahc_parse_pci_eeprom(struct ahc_softc *ahc, struct seeprom_config *sc)
+{
+	/*
+	 * Put the data we've collected down into SRAM
+	 * where ahc_init will find it.
+	 */
+	int	 i;
+	int	 max_targ = sc->max_targets & CFMAXTARG;
+	u_int	 scsi_conf;
+	uint16_t discenable;
+	uint16_t ultraenb;
+
+	discenable = 0;
+	ultraenb = 0;
+	if ((sc->adapter_control & CFULTRAEN) != 0) {
+		/*
+		 * Determine if this adapter has a "newstyle"
+		 * SEEPROM format.
+		 */
+		for (i = 0; i < max_targ; i++) {
+			if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0) {
+				ahc->flags |= AHC_NEWEEPROM_FMT;
+				break;
+			}
+		}
+	}
+
+	for (i = 0; i < max_targ; i++) {
+		u_int     scsirate;
+		uint16_t target_mask;
+
+		target_mask = 0x01 << i;
+		if (sc->device_flags[i] & CFDISC)
+			discenable |= target_mask;
+		if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) {
+			if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0)
+				ultraenb |= target_mask;
+		} else if ((sc->adapter_control & CFULTRAEN) != 0) {
+			ultraenb |= target_mask;
+		}
+		if ((sc->device_flags[i] & CFXFER) == 0x04
+		 && (ultraenb & target_mask) != 0) {
+			/* Treat 10MHz as a non-ultra speed */
+			sc->device_flags[i] &= ~CFXFER;
+		 	ultraenb &= ~target_mask;
+		}
+		if ((ahc->features & AHC_ULTRA2) != 0) {
+			u_int offset;
+
+			if (sc->device_flags[i] & CFSYNCH)
+				offset = MAX_OFFSET_ULTRA2;
+			else 
+				offset = 0;
+			ahc_outb(ahc, TARG_OFFSET + i, offset);
+
+			/*
+			 * The ultra enable bits contain the
+			 * high bit of the ultra2 sync rate
+			 * field.
+			 */
+			scsirate = (sc->device_flags[i] & CFXFER)
+				 | ((ultraenb & target_mask) ? 0x8 : 0x0);
+			if (sc->device_flags[i] & CFWIDEB)
+				scsirate |= WIDEXFER;
+		} else {
+			scsirate = (sc->device_flags[i] & CFXFER) << 4;
+			if (sc->device_flags[i] & CFSYNCH)
+				scsirate |= SOFS;
+			if (sc->device_flags[i] & CFWIDEB)
+				scsirate |= WIDEXFER;
+		}
+		ahc_outb(ahc, TARG_SCSIRATE + i, scsirate);
 	}
+	ahc->our_id = sc->brtime_id & CFSCSIID;
+
+	scsi_conf = (ahc->our_id & 0x7);
+	if (sc->adapter_control & CFSPARITY)
+		scsi_conf |= ENSPCHK;
+	if (sc->adapter_control & CFRESETB)
+		scsi_conf |= RESET_SCSI;
+
+	ahc->flags |= (sc->adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT;
+
+	if (sc->bios_control & CFEXTEND)
+		ahc->flags |= AHC_EXTENDED_TRANS_A;
+
+	if (sc->bios_control & CFBIOSEN)
+		ahc->flags |= AHC_BIOS_ENABLED;
+	if (ahc->features & AHC_ULTRA
+	 && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) {
+		/* Should we enable Ultra mode? */
+		if (!(sc->adapter_control & CFULTRAEN))
+			/* Treat us as a non-ultra card */
+			ultraenb = 0;
+	}
+
+	if (sc->signature == CFSIGNATURE
+	 || sc->signature == CFSIGNATURE2) {
+		uint32_t devconfig;
+
+		/* Honor the STPWLEVEL settings */
+		devconfig = ahc_pci_read_config(ahc->dev_softc,
+						DEVCONFIG, /*bytes*/4);
+		devconfig &= ~STPWLEVEL;
+		if ((sc->bios_control & CFSTPWLEVEL) != 0)
+			devconfig |= STPWLEVEL;
+		ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
+				     devconfig, /*bytes*/4);
+	}
+	/* Set SCSICONF info */
+	ahc_outb(ahc, SCSICONF, scsi_conf);
+	ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
+	ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
+	ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff);
+	ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff);
 }
 
 static void
@@ -1453,10 +1501,10 @@
 		enablePRI_high = 0;
 		if ((ahc->features & AHC_NEW_TERMCTL) != 0) {
 			ahc_new_term_detect(ahc, &enableSEC_low,
-					       &enableSEC_high,
-					       &enablePRI_low,
-					       &enablePRI_high,
-					       &eeprom_present);
+					    &enableSEC_high,
+					    &enablePRI_low,
+					    &enablePRI_high,
+					    &eeprom_present);
 			if ((adapter_control & CFSEAUTOTERM) == 0) {
 				if (bootverbose)
 					printf("%s: Manual SE Termination\n",
@@ -1534,6 +1582,15 @@
 			       "Only two connectors on the "
 			       "adapter may be used at a "
 			       "time!\n", ahc_name(ahc));
+
+			/*
+			 * Pretend there are no cables in the hope
+			 * that having all of the termination on
+			 * gives us a more stable bus.
+			 */
+		 	internal50_present = 0;
+			internal68_present = 0;
+			externalcable_present = 0;
 		}
 
 		if ((ahc->features & AHC_WIDE) != 0
@@ -1696,7 +1753,12 @@
 		     int *externalcable_present, int *eeprom_present)
 {
 	uint8_t brdctl;
+	uint8_t spiocap;
 
+	spiocap = ahc_inb(ahc, SPIOCAP);
+	spiocap &= ~SOFTCMDEN;
+	spiocap |= EXT_BRDCTL;
+	ahc_outb(ahc, SPIOCAP, spiocap);
 	ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
 	ahc_outb(ahc, BRDCTL, 0);
 	brdctl = ahc_inb(ahc, BRDCTL);
@@ -1706,8 +1768,8 @@
 	*eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0;
 }
 	
-static int
-acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd)
+int
+ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd)
 {
 	int wait;
 
@@ -1734,8 +1796,8 @@
 	return(1);
 }
 
-static void
-release_seeprom(struct seeprom_descriptor *sd)
+void
+ahc_release_seeprom(struct seeprom_descriptor *sd)
 {
 	/* Release access to the memory port and the serial EEPROM. */
 	SEEPROM_OUTB(sd, 0);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_proc.c linux/drivers/scsi/aic7xxx/aic7xxx_proc.c
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_proc.c	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_proc.c	2002-07-20 01:08:22.000000000 +0000
@@ -37,10 +37,11 @@
  * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
  * sym driver.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#13 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#19 $
  */
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
+#include "aic7xxx_93cx6.h"
 
 static void	copy_mem_info(struct info_str *info, char *data, int len);
 static int	copy_info(struct info_str *info, char *fmt, ...);
@@ -51,6 +52,8 @@
 				      u_int target_id, u_int target_offset);
 static void	ahc_dump_device_state(struct info_str *info,
 				      struct ahc_linux_device *dev);
+static int	ahc_proc_write_seeprom(struct ahc_softc *ahc,
+				       char *buffer, int length);
 
 static void
 copy_mem_info(struct info_str *info, char *data, int len)
@@ -225,6 +228,96 @@
 	copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen);
 }
 
+static int
+ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length)
+{
+	struct seeprom_descriptor sd;
+	int have_seeprom;
+	u_long s;
+	int paused;
+	int written;
+
+	/* Default to failure. */
+	written = -EINVAL;
+	ahc_lock(ahc, &s);
+	paused = ahc_is_paused(ahc);
+	if (!paused)
+		ahc_pause(ahc);
+
+	if (length != sizeof(struct seeprom_config)) {
+		printf("ahc_proc_write_seeprom: incorrect buffer size\n");
+		goto done;
+	}
+
+	have_seeprom = ahc_verify_cksum((struct seeprom_config*)buffer);
+	if (have_seeprom == 0) {
+		printf("ahc_proc_write_seeprom: cksum verification failed\n");
+		goto done;
+	}
+
+	sd.sd_ahc = ahc;
+	if ((ahc->chip & AHC_VL) != 0) {
+		sd.sd_control_offset = SEECTL_2840;
+		sd.sd_status_offset = STATUS_2840;
+		sd.sd_dataout_offset = STATUS_2840;		
+		sd.sd_chip = C46;
+		sd.sd_MS = 0;
+		sd.sd_RDY = EEPROM_TF;
+		sd.sd_CS = CS_2840;
+		sd.sd_CK = CK_2840;
+		sd.sd_DO = DO_2840;
+		sd.sd_DI = DI_2840;
+		have_seeprom = TRUE;
+	} else {
+		sd.sd_control_offset = SEECTL;
+		sd.sd_status_offset = SEECTL;
+		sd.sd_dataout_offset = SEECTL;
+		if (ahc->flags & AHC_LARGE_SEEPROM)
+			sd.sd_chip = C56_66;
+		else
+			sd.sd_chip = C46;
+		sd.sd_MS = SEEMS;
+		sd.sd_RDY = SEERDY;
+		sd.sd_CS = SEECS;
+		sd.sd_CK = SEECK;
+		sd.sd_DO = SEEDO;
+		sd.sd_DI = SEEDI;
+		have_seeprom = ahc_acquire_seeprom(ahc, &sd);
+	}
+
+	if (!have_seeprom) {
+		printf("ahc_proc_write_seeprom: No Serial EEPROM\n");
+		goto done;
+	} else {
+		u_int start_addr;
+
+		if (ahc->seep_config == NULL) {
+			ahc->seep_config = malloc(sizeof(*ahc->seep_config),
+						  M_DEVBUF, M_NOWAIT);
+			if (ahc->seep_config == NULL) {
+				printf("aic7xxx: Unable to allocate serial "
+				       "eeprom buffer.  Write failing\n");
+				goto done;
+			}
+		}
+		printf("aic7xxx: Writing Serial EEPROM\n");
+		start_addr = 32 * (ahc->channel - 'A');
+		ahc_write_seeprom(&sd, (u_int16_t *)buffer, start_addr,
+				  sizeof(struct seeprom_config)/2);
+		ahc_read_seeprom(&sd, (uint16_t *)ahc->seep_config,
+				 start_addr, sizeof(struct seeprom_config)/2);
+		if ((ahc->chip & AHC_VL) == 0)
+			ahc_release_seeprom(&sd);
+		written = length;
+	}
+
+done:
+	if (!paused)
+		ahc_unpause(ahc);
+	ahc_unlock(ahc, &s);
+	return (written);
+}
+
 /*
  * Return information to handle /proc support for the driver.
  */
@@ -235,20 +328,26 @@
 	struct	ahc_softc *ahc;
 	struct	info_str info;
 	char	ahc_info[256];
+	u_long	s;
 	u_int	max_targ;
 	u_int	i;
+	int	retval;
 
+	retval = -EINVAL;
+	ahc_list_lock(&s);
 	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
 		if (ahc->platform_data->host->host_no == hostno)
 			break;
 	}
 
 	if (ahc == NULL)
-		return (-EINVAL);
+		goto done;
 
 	 /* Has data been written to the file? */ 
-	if (inout == TRUE)
-		return (-ENOSYS);
+	if (inout == TRUE) {
+		retval = ahc_proc_write_seeprom(ahc, buffer, length);
+		goto done;
+	}
 
 	if (start)
 		*start = buffer;
@@ -261,7 +360,22 @@
 	copy_info(&info, "Adaptec AIC7xxx driver version: %s\n",
 		  AIC7XXX_DRIVER_VERSION);
 	ahc_controller_info(ahc, ahc_info);
-	copy_info(&info, "%s\n", ahc_info);
+	copy_info(&info, "%s\n\n", ahc_info);
+
+	if (ahc->seep_config == NULL)
+		copy_info(&info, "No Serial EEPROM\n");
+	else {
+		copy_info(&info, "Serial EEPROM:\n");
+		for (i = 0; i < sizeof(*ahc->seep_config)/2; i++) {
+			if (((i % 8) == 0) && (i != 0)) {
+				copy_info(&info, "\n");
+			}
+			copy_info(&info, "0x%.4x ",
+				  ((uint16_t*)ahc->seep_config)[i]);
+		}
+		copy_info(&info, "\n");
+	}
+	copy_info(&info, "\n");
 
 	max_targ = 15;
 	if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
@@ -284,5 +398,8 @@
 		ahc_dump_target_state(ahc, &info, our_id,
 				      channel, target_id, i);
 	}
-	return (info.pos > info.offset ? info.pos - info.offset : 0);
+	retval = info.pos > info.offset ? info.pos - info.offset : 0;
+done:
+	ahc_list_unlock(&s);
+	return (retval);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_reg.h linux/drivers/scsi/aic7xxx/aic7xxx_reg.h
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_reg.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_reg.h	2002-07-20 01:08:24.000000000 +0000
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#37 $
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#24 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $
  */
 
 #define	SCSISEQ         		0x00
@@ -184,7 +184,7 @@
 #define		SOFT1           	0x80
 #define		SOFT0           	0x40
 #define		SOFTCMDEN       	0x20
-#define		HAS_BRDCTL      	0x10
+#define		EXT_BRDCTL      	0x10
 #define		SEEPROM         	0x08
 #define		EEPROM          	0x04
 #define		ROM             	0x02
@@ -228,8 +228,6 @@
 #define	BUSY_TARGETS    		0x20
 #define	TARG_SCSIRATE   		0x20
 
-#define	SRAM_BASE       		0x20
-
 #define	ULTRA_ENB       		0x30
 #define	CMDSIZE_TABLE   		0x30
 
@@ -329,7 +327,9 @@
 
 #define	DATA_COUNT_ODD  		0x55
 
+#define	HA_274_BIOSGLOBAL		0x56
 #define	INITIATOR_TAG   		0x56
+#define		HA_274_EXTENDED_TRANS	0x01
 
 #define	SEQ_FLAGS2      		0x57
 #define		TARGET_MSG_PENDING	0x02
@@ -396,6 +396,8 @@
 
 #define	TARG_OFFSET     		0x70
 
+#define	SRAM_BASE       		0x70
+
 #define	BCTL            		0x84
 #define		ACE             	0x08
 #define		ENABLE          	0x01
@@ -714,3 +716,7 @@
 #define	SG_PREFETCH_CNT	0x04
 #define	CACHESIZE_MASK	0x02
 #define	QINFIFO_OFFSET	0x01
+#define	DOWNLOAD_CONST_COUNT	0x07
+
+
+/* Exported Labels */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aic7xxx_seq.h linux/drivers/scsi/aic7xxx/aic7xxx_seq.h
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_seq.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aic7xxx_seq.h	2002-07-20 01:08:37.000000000 +0000
@@ -2,13 +2,13 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#37 $
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#24 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $
  */
 static uint8_t seqprog[] = {
 	0xb2, 0x00, 0x00, 0x08,
 	0xf7, 0x11, 0x22, 0x08,
-	0x00, 0x65, 0xe0, 0x59,
+	0x00, 0x65, 0xe4, 0x59,
 	0xf7, 0x01, 0x02, 0x08,
 	0xff, 0x6a, 0x24, 0x08,
 	0x40, 0x00, 0x40, 0x68,
@@ -21,15 +21,15 @@
 	0x01, 0x4d, 0xc8, 0x30,
 	0x00, 0x4c, 0x12, 0x70,
 	0x01, 0x39, 0xa2, 0x30,
-	0x00, 0x6a, 0xb2, 0x5e,
+	0x00, 0x6a, 0xb6, 0x5e,
 	0x01, 0x51, 0x20, 0x31,
 	0x01, 0x57, 0xae, 0x00,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0x51, 0x04, 0x5e,
+	0x00, 0x51, 0x08, 0x5e,
 	0x01, 0x51, 0xc8, 0x30,
 	0x00, 0x39, 0xc8, 0x60,
 	0x00, 0xbb, 0x30, 0x70,
-	0xc1, 0x6a, 0xca, 0x5e,
+	0xc1, 0x6a, 0xce, 0x5e,
 	0x01, 0xbf, 0x72, 0x30,
 	0x01, 0x40, 0x7e, 0x31,
 	0x01, 0x90, 0x80, 0x30,
@@ -49,10 +49,10 @@
 	0x08, 0x3c, 0x78, 0x00,
 	0x01, 0x50, 0xc8, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0xee, 0x5d,
+	0x48, 0x6a, 0xf2, 0x5d,
 	0x01, 0x6a, 0xdc, 0x01,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0xee, 0x5d,
+	0x48, 0x6a, 0xf2, 0x5d,
 	0x01, 0x6a, 0x26, 0x01,
 	0xf0, 0x19, 0x7a, 0x08,
 	0x0f, 0x18, 0xc8, 0x08,
@@ -63,7 +63,7 @@
 	0x80, 0x3d, 0x7a, 0x00,
 	0x01, 0x3d, 0xd8, 0x31,
 	0x01, 0x3d, 0x32, 0x31,
-	0x10, 0x03, 0x46, 0x79,
+	0x10, 0x03, 0x48, 0x79,
 	0x00, 0x65, 0xf4, 0x58,
 	0x80, 0x66, 0xae, 0x78,
 	0x01, 0x66, 0xd8, 0x31,
@@ -79,7 +79,7 @@
 	0x00, 0x65, 0xaa, 0x48,
 	0x01, 0x66, 0xd8, 0x31,
 	0x01, 0x66, 0x32, 0x31,
-	0x10, 0x03, 0x46, 0x79,
+	0x10, 0x03, 0x48, 0x79,
 	0x00, 0x65, 0xf4, 0x58,
 	0x01, 0x66, 0xd8, 0x31,
 	0x01, 0x66, 0x32, 0x31,
@@ -88,12 +88,12 @@
 	0xff, 0x6a, 0xd8, 0x01,
 	0xff, 0x6a, 0x32, 0x01,
 	0x90, 0x3c, 0x78, 0x00,
-	0x02, 0x57, 0x3a, 0x69,
-	0x10, 0x03, 0x38, 0x69,
+	0x02, 0x57, 0x3c, 0x69,
+	0x10, 0x03, 0x3a, 0x69,
 	0x00, 0x65, 0x1e, 0x41,
 	0x02, 0x57, 0xae, 0x00,
 	0x00, 0x65, 0x9e, 0x40,
-	0x61, 0x6a, 0xca, 0x5e,
+	0x61, 0x6a, 0xce, 0x5e,
 	0x08, 0x51, 0x1e, 0x71,
 	0x02, 0x0b, 0xb2, 0x78,
 	0x00, 0x65, 0xae, 0x40,
@@ -105,8 +105,8 @@
 	0x08, 0x1f, 0xc4, 0x78,
 	0x80, 0x3d, 0x7a, 0x00,
 	0x20, 0x6a, 0x16, 0x00,
-	0x00, 0x65, 0xc0, 0x41,
-	0x00, 0x65, 0xa4, 0x5e,
+	0x00, 0x65, 0xc4, 0x41,
+	0x00, 0x65, 0xa8, 0x5e,
 	0x00, 0x65, 0x12, 0x40,
 	0x20, 0x11, 0xd2, 0x68,
 	0x20, 0x6a, 0x18, 0x00,
@@ -133,58 +133,59 @@
 	0xf7, 0x01, 0x02, 0x08,
 	0x01, 0x06, 0xcc, 0x34,
 	0xb2, 0x00, 0x00, 0x08,
-	0x40, 0x6a, 0x16, 0x00,
 	0x01, 0x40, 0x20, 0x31,
 	0x01, 0xbf, 0x80, 0x30,
 	0x01, 0xb9, 0x7a, 0x30,
 	0x01, 0xba, 0x7c, 0x30,
 	0x00, 0x65, 0xea, 0x58,
-	0x80, 0x0b, 0xbc, 0x79,
-	0xe4, 0x6a, 0x60, 0x5d,
-	0x80, 0xba, 0x76, 0x5d,
+	0x80, 0x0b, 0xbe, 0x79,
+	0xe4, 0x6a, 0x64, 0x5d,
+	0x40, 0x6a, 0x16, 0x00,
+	0x80, 0xba, 0x7a, 0x5d,
 	0x20, 0xb8, 0x16, 0x79,
-	0x20, 0x6a, 0x76, 0x5d,
-	0x00, 0xab, 0x76, 0x5d,
+	0x20, 0x6a, 0x7a, 0x5d,
+	0x00, 0xab, 0x7a, 0x5d,
 	0x01, 0xa9, 0x78, 0x30,
 	0x10, 0xb8, 0x1e, 0x79,
-	0xe4, 0x6a, 0x60, 0x5d,
+	0xe4, 0x6a, 0x64, 0x5d,
 	0x00, 0x65, 0xae, 0x40,
-	0x10, 0x03, 0x36, 0x69,
-	0x08, 0x3c, 0x52, 0x69,
-	0x04, 0x3c, 0x8a, 0x69,
-	0x02, 0x3c, 0x90, 0x69,
-	0x01, 0x3c, 0x3c, 0x79,
+	0x10, 0x03, 0x38, 0x69,
+	0x08, 0x3c, 0x54, 0x69,
+	0x04, 0x3c, 0x8c, 0x69,
+	0x02, 0x3c, 0x92, 0x69,
+	0x01, 0x3c, 0x3e, 0x79,
 	0x01, 0x6a, 0xa2, 0x30,
-	0x00, 0x65, 0x9c, 0x59,
+	0x00, 0x65, 0x9e, 0x59,
 	0x04, 0x51, 0x2c, 0x61,
-	0x00, 0x6a, 0xb2, 0x5e,
+	0x00, 0x6a, 0xb6, 0x5e,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0xbb, 0x04, 0x5e,
+	0x00, 0xbb, 0x08, 0x5e,
+	0x00, 0x65, 0xec, 0x58,
 	0x00, 0x65, 0x16, 0x41,
 	0xa4, 0x6a, 0x06, 0x00,
 	0x00, 0x65, 0xf4, 0x58,
 	0x00, 0x65, 0xae, 0x40,
-	0xe4, 0x6a, 0x60, 0x5d,
-	0x20, 0x3c, 0x42, 0x79,
-	0x02, 0x6a, 0x76, 0x5d,
-	0x04, 0x6a, 0x76, 0x5d,
-	0x01, 0x03, 0x44, 0x69,
+	0xe4, 0x6a, 0x64, 0x5d,
+	0x20, 0x3c, 0x44, 0x79,
+	0x02, 0x6a, 0x7a, 0x5d,
+	0x04, 0x6a, 0x7a, 0x5d,
+	0x01, 0x03, 0x46, 0x69,
 	0xf7, 0x11, 0x22, 0x08,
 	0xff, 0x6a, 0x24, 0x08,
 	0xff, 0x6a, 0x06, 0x08,
 	0x01, 0x6a, 0x7e, 0x00,
-	0x00, 0x65, 0x9c, 0x59,
+	0x00, 0x65, 0x9e, 0x59,
 	0x00, 0x65, 0x04, 0x40,
 	0x80, 0x86, 0xc8, 0x08,
 	0x01, 0x4f, 0xc8, 0x30,
-	0x00, 0x50, 0x64, 0x61,
-	0xc4, 0x6a, 0x60, 0x5d,
-	0x40, 0x3c, 0x60, 0x79,
-	0x28, 0x6a, 0x76, 0x5d,
-	0x00, 0x65, 0x44, 0x41,
-	0x08, 0x6a, 0x76, 0x5d,
-	0x00, 0x65, 0x44, 0x41,
-	0x84, 0x6a, 0x60, 0x5d,
+	0x00, 0x50, 0x66, 0x61,
+	0xc4, 0x6a, 0x64, 0x5d,
+	0x40, 0x3c, 0x62, 0x79,
+	0x28, 0x6a, 0x7a, 0x5d,
+	0x00, 0x65, 0x46, 0x41,
+	0x08, 0x6a, 0x7a, 0x5d,
+	0x00, 0x65, 0x46, 0x41,
+	0x84, 0x6a, 0x64, 0x5d,
 	0x00, 0x65, 0xf4, 0x58,
 	0x01, 0x66, 0xc8, 0x30,
 	0x01, 0x64, 0xd8, 0x31,
@@ -192,60 +193,61 @@
 	0x5b, 0x64, 0xc8, 0x28,
 	0x30, 0x64, 0xca, 0x18,
 	0x01, 0x6c, 0xc8, 0x30,
-	0xff, 0x64, 0x86, 0x79,
+	0xff, 0x64, 0x88, 0x79,
 	0x08, 0x01, 0x02, 0x00,
-	0x02, 0x0b, 0x78, 0x79,
-	0x01, 0x64, 0x7e, 0x61,
+	0x02, 0x0b, 0x7a, 0x79,
+	0x01, 0x64, 0x80, 0x61,
 	0xf7, 0x01, 0x02, 0x08,
 	0x01, 0x06, 0xd8, 0x31,
 	0x01, 0x06, 0x32, 0x31,
 	0xff, 0x64, 0xc8, 0x18,
-	0xff, 0x64, 0x78, 0x69,
+	0xff, 0x64, 0x7a, 0x69,
 	0xf7, 0x3c, 0x78, 0x08,
 	0x00, 0x65, 0x1e, 0x41,
 	0x40, 0xaa, 0x7e, 0x10,
-	0x04, 0xaa, 0x60, 0x5d,
-	0x00, 0x65, 0x52, 0x42,
-	0xc4, 0x6a, 0x60, 0x5d,
+	0x04, 0xaa, 0x64, 0x5d,
+	0x00, 0x65, 0x56, 0x42,
+	0xc4, 0x6a, 0x64, 0x5d,
 	0xc0, 0x6a, 0x7e, 0x00,
-	0x00, 0xa8, 0x76, 0x5d,
+	0x00, 0xa8, 0x7a, 0x5d,
 	0xe4, 0x6a, 0x06, 0x00,
-	0x00, 0x6a, 0x76, 0x5d,
-	0x00, 0x65, 0x44, 0x41,
-	0x10, 0x3c, 0xa0, 0x69,
-	0x00, 0xbb, 0x80, 0x44,
+	0x00, 0x6a, 0x7a, 0x5d,
+	0x00, 0x65, 0x46, 0x41,
+	0x10, 0x3c, 0xa2, 0x69,
+	0x00, 0xbb, 0x84, 0x44,
 	0x18, 0x6a, 0xda, 0x01,
 	0x01, 0x69, 0xd8, 0x31,
 	0x1c, 0x6a, 0xd0, 0x01,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0xa8, 0x79,
+	0x80, 0xee, 0xaa, 0x79,
 	0xff, 0x6a, 0xdc, 0x09,
 	0x01, 0x93, 0x26, 0x01,
 	0x03, 0x6a, 0x2a, 0x01,
 	0x01, 0x69, 0x32, 0x31,
-	0x1c, 0x6a, 0xd2, 0x5d,
+	0x1c, 0x6a, 0xd6, 0x5d,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0x9a, 0x5e,
+	0x00, 0x65, 0x9e, 0x5e,
 	0x01, 0x50, 0xa0, 0x18,
 	0x02, 0x6a, 0x22, 0x05,
 	0x80, 0x6a, 0x74, 0x00,
 	0x80, 0x3c, 0x78, 0x00,
-	0x00, 0x65, 0xca, 0x5d,
+	0x40, 0x6a, 0x16, 0x00,
+	0x00, 0x65, 0xce, 0x5d,
 	0x01, 0x3f, 0xc8, 0x30,
-	0xbf, 0x64, 0x52, 0x7a,
-	0x80, 0x64, 0xa6, 0x73,
-	0xa0, 0x64, 0x04, 0x74,
-	0xc0, 0x64, 0xf8, 0x73,
-	0xe0, 0x64, 0x34, 0x74,
-	0x01, 0x6a, 0xca, 0x5e,
-	0x00, 0x65, 0xc0, 0x41,
+	0xbf, 0x64, 0x56, 0x7a,
+	0x80, 0x64, 0xaa, 0x73,
+	0xa0, 0x64, 0x08, 0x74,
+	0xc0, 0x64, 0xfc, 0x73,
+	0xe0, 0x64, 0x38, 0x74,
+	0x01, 0x6a, 0xce, 0x5e,
+	0x00, 0x65, 0xc4, 0x41,
 	0xf7, 0x11, 0x22, 0x08,
 	0x01, 0x06, 0xd4, 0x30,
 	0xff, 0x6a, 0x24, 0x08,
 	0xf7, 0x01, 0x02, 0x08,
-	0x09, 0x0c, 0xda, 0x79,
+	0x09, 0x0c, 0xde, 0x79,
 	0x08, 0x0c, 0x04, 0x68,
-	0xb1, 0x6a, 0xca, 0x5e,
+	0xb1, 0x6a, 0xce, 0x5e,
 	0xff, 0x6a, 0x26, 0x09,
 	0x12, 0x01, 0x02, 0x00,
 	0x02, 0x6a, 0x08, 0x30,
@@ -258,33 +260,33 @@
 	0x00, 0xa5, 0x4a, 0x21,
 	0x00, 0xa6, 0x4c, 0x21,
 	0x00, 0xa7, 0x4e, 0x25,
-	0x08, 0xeb, 0xce, 0x7e,
-	0x80, 0xeb, 0xfa, 0x79,
+	0x08, 0xeb, 0xd2, 0x7e,
+	0x80, 0xeb, 0xfe, 0x79,
 	0xff, 0x6a, 0xd6, 0x09,
-	0x08, 0xeb, 0xfe, 0x69,
+	0x08, 0xeb, 0x02, 0x6a,
 	0xff, 0x6a, 0xd4, 0x0c,
-	0x80, 0xa3, 0xce, 0x6e,
-	0x88, 0xeb, 0x14, 0x72,
-	0x08, 0xeb, 0xce, 0x6e,
-	0x04, 0xea, 0x18, 0xe2,
-	0x08, 0xee, 0xce, 0x6e,
+	0x80, 0xa3, 0xd2, 0x6e,
+	0x88, 0xeb, 0x18, 0x72,
+	0x08, 0xeb, 0xd2, 0x6e,
+	0x04, 0xea, 0x1c, 0xe2,
+	0x08, 0xee, 0xd2, 0x6e,
 	0x04, 0x6a, 0xd0, 0x81,
 	0x05, 0xa4, 0xc0, 0x89,
 	0x03, 0xa5, 0xc2, 0x31,
 	0x09, 0x6a, 0xd6, 0x05,
-	0x00, 0x65, 0xfc, 0x59,
+	0x00, 0x65, 0x00, 0x5a,
 	0x06, 0xa4, 0xd4, 0x89,
-	0x80, 0x94, 0xce, 0x7e,
+	0x80, 0x94, 0xd2, 0x7e,
 	0x07, 0xe9, 0x10, 0x31,
-	0x01, 0x8c, 0x20, 0x7a,
+	0x01, 0x8c, 0x24, 0x7a,
 	0x01, 0x55, 0xaa, 0x10,
 	0x01, 0xe9, 0x46, 0x31,
-	0x00, 0xa3, 0xac, 0x5e,
-	0x00, 0x65, 0xee, 0x59,
+	0x00, 0xa3, 0xb0, 0x5e,
+	0x00, 0x65, 0xf2, 0x59,
 	0x01, 0xa4, 0xca, 0x30,
-	0x01, 0x55, 0x2c, 0x7a,
+	0x01, 0x55, 0x30, 0x7a,
 	0x04, 0x65, 0xca, 0x00,
-	0x80, 0xa3, 0x30, 0x7a,
+	0x80, 0xa3, 0x34, 0x7a,
 	0x02, 0x65, 0xca, 0x00,
 	0x01, 0x65, 0xf8, 0x31,
 	0x80, 0x93, 0x26, 0x01,
@@ -292,168 +294,168 @@
 	0x01, 0x8c, 0xc8, 0x30,
 	0x00, 0x88, 0xc8, 0x18,
 	0x02, 0x64, 0xc8, 0x88,
-	0xff, 0x64, 0xce, 0x7e,
-	0xff, 0x8d, 0x46, 0x6a,
-	0xff, 0x8e, 0x46, 0x6a,
+	0xff, 0x64, 0xd2, 0x7e,
+	0xff, 0x8d, 0x4a, 0x6a,
+	0xff, 0x8e, 0x4a, 0x6a,
 	0x03, 0x8c, 0xd4, 0x98,
-	0x00, 0x65, 0xce, 0x56,
+	0x00, 0x65, 0xd2, 0x56,
 	0x01, 0x64, 0x70, 0x30,
 	0xff, 0x64, 0xc8, 0x10,
 	0x01, 0x64, 0xc8, 0x18,
 	0x00, 0x8c, 0x18, 0x19,
 	0xff, 0x8d, 0x1a, 0x21,
 	0xff, 0x8e, 0x1c, 0x25,
-	0x80, 0x3c, 0x56, 0x6a,
-	0x21, 0x6a, 0xca, 0x46,
+	0x80, 0x3c, 0x5a, 0x6a,
+	0x21, 0x6a, 0xce, 0x46,
 	0xa8, 0x6a, 0x76, 0x00,
 	0x79, 0x6a, 0x76, 0x00,
-	0x40, 0x3f, 0x5e, 0x6a,
+	0x40, 0x3f, 0x62, 0x6a,
 	0x04, 0x3b, 0x76, 0x00,
 	0x04, 0x6a, 0xd4, 0x81,
-	0x20, 0x3c, 0x66, 0x7a,
-	0x51, 0x6a, 0xca, 0x5e,
-	0x00, 0x65, 0x80, 0x42,
+	0x20, 0x3c, 0x6a, 0x7a,
+	0x51, 0x6a, 0xce, 0x5e,
+	0x00, 0x65, 0x84, 0x42,
 	0x20, 0x3c, 0x78, 0x00,
-	0x00, 0xb3, 0xac, 0x5e,
+	0x00, 0xb3, 0xb0, 0x5e,
 	0x07, 0xac, 0x10, 0x31,
 	0x05, 0xb3, 0x46, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xac, 0x6a, 0xe0, 0x5d,
+	0xac, 0x6a, 0xe4, 0x5d,
 	0xa3, 0x6a, 0xcc, 0x00,
-	0xb3, 0x6a, 0xe4, 0x5d,
-	0x00, 0x65, 0x36, 0x5a,
+	0xb3, 0x6a, 0xe8, 0x5d,
+	0x00, 0x65, 0x3a, 0x5a,
 	0xfd, 0xa4, 0x48, 0x09,
 	0x01, 0x8c, 0xaa, 0x08,
 	0x03, 0x8c, 0x10, 0x30,
-	0x00, 0x65, 0xd8, 0x5d,
-	0x01, 0xa4, 0x92, 0x7a,
+	0x00, 0x65, 0xdc, 0x5d,
+	0x01, 0xa4, 0x96, 0x7a,
 	0x04, 0x3b, 0x76, 0x08,
 	0x01, 0x3b, 0x26, 0x31,
 	0x80, 0x02, 0x04, 0x00,
-	0x10, 0x0c, 0x88, 0x7a,
-	0x03, 0x9e, 0x8a, 0x6a,
+	0x10, 0x0c, 0x8c, 0x7a,
+	0x03, 0x9e, 0x8e, 0x6a,
 	0x7f, 0x02, 0x04, 0x08,
-	0x91, 0x6a, 0xca, 0x5e,
-	0x00, 0x65, 0xc0, 0x41,
+	0x91, 0x6a, 0xce, 0x5e,
+	0x00, 0x65, 0xc4, 0x41,
 	0x01, 0xa4, 0xca, 0x30,
-	0x80, 0xa3, 0x98, 0x7a,
+	0x80, 0xa3, 0x9c, 0x7a,
 	0x02, 0x65, 0xca, 0x00,
-	0x01, 0x55, 0x9c, 0x7a,
+	0x01, 0x55, 0xa0, 0x7a,
 	0x04, 0x65, 0xca, 0x00,
 	0x01, 0x65, 0xf8, 0x31,
 	0x01, 0x3b, 0x26, 0x31,
-	0x00, 0x65, 0x02, 0x5a,
-	0x01, 0xfc, 0xaa, 0x6a,
-	0x80, 0x0b, 0xa0, 0x6a,
-	0x10, 0x0c, 0xa0, 0x7a,
-	0x20, 0x93, 0xa0, 0x6a,
+	0x00, 0x65, 0x06, 0x5a,
+	0x01, 0xfc, 0xae, 0x6a,
+	0x80, 0x0b, 0xa4, 0x6a,
+	0x10, 0x0c, 0xa4, 0x7a,
+	0x20, 0x93, 0xa4, 0x6a,
 	0x02, 0x93, 0x26, 0x01,
-	0x02, 0xfc, 0xb4, 0x7a,
-	0x40, 0x0d, 0xce, 0x6a,
+	0x02, 0xfc, 0xb8, 0x7a,
+	0x40, 0x0d, 0xd2, 0x6a,
 	0x01, 0xa4, 0x48, 0x01,
-	0x00, 0x65, 0xce, 0x42,
-	0x40, 0x0d, 0xba, 0x6a,
-	0x00, 0x65, 0x02, 0x5a,
-	0x00, 0x65, 0xac, 0x42,
-	0x80, 0xfc, 0xc4, 0x7a,
-	0x80, 0xa4, 0xc4, 0x6a,
+	0x00, 0x65, 0xd2, 0x42,
+	0x40, 0x0d, 0xbe, 0x6a,
+	0x00, 0x65, 0x06, 0x5a,
+	0x00, 0x65, 0xb0, 0x42,
+	0x80, 0xfc, 0xc8, 0x7a,
+	0x80, 0xa4, 0xc8, 0x6a,
 	0xff, 0xa5, 0x4a, 0x19,
 	0xff, 0xa6, 0x4c, 0x21,
 	0xff, 0xa7, 0x4e, 0x21,
 	0xf8, 0xfc, 0x48, 0x09,
 	0xff, 0x6a, 0xaa, 0x08,
-	0x04, 0xfc, 0xcc, 0x7a,
+	0x04, 0xfc, 0xd0, 0x7a,
 	0x01, 0x55, 0xaa, 0x00,
 	0xff, 0x6a, 0x46, 0x09,
-	0x04, 0x3b, 0xe6, 0x6a,
+	0x04, 0x3b, 0xea, 0x6a,
 	0x02, 0x93, 0x26, 0x01,
-	0x01, 0x94, 0xd0, 0x7a,
-	0x01, 0x94, 0xd0, 0x7a,
-	0x01, 0x94, 0xd0, 0x7a,
-	0x01, 0x94, 0xd0, 0x7a,
-	0x01, 0x94, 0xd0, 0x7a,
-	0x01, 0xa4, 0xe4, 0x7a,
-	0x01, 0xfc, 0xde, 0x7a,
-	0x01, 0x94, 0xe6, 0x6a,
-	0x00, 0x65, 0x80, 0x42,
-	0x01, 0x94, 0xe4, 0x7a,
-	0x10, 0x94, 0xe6, 0x6a,
+	0x01, 0x94, 0xd4, 0x7a,
+	0x01, 0x94, 0xd4, 0x7a,
+	0x01, 0x94, 0xd4, 0x7a,
+	0x01, 0x94, 0xd4, 0x7a,
+	0x01, 0x94, 0xd4, 0x7a,
+	0x01, 0xa4, 0xe8, 0x7a,
+	0x01, 0xfc, 0xe2, 0x7a,
+	0x01, 0x94, 0xea, 0x6a,
+	0x00, 0x65, 0x84, 0x42,
+	0x01, 0x94, 0xe8, 0x7a,
+	0x10, 0x94, 0xea, 0x6a,
 	0xd7, 0x93, 0x26, 0x09,
-	0x28, 0x93, 0xea, 0x6a,
+	0x28, 0x93, 0xee, 0x6a,
 	0x01, 0x85, 0x0a, 0x01,
-	0x02, 0xfc, 0xf2, 0x6a,
+	0x02, 0xfc, 0xf6, 0x6a,
 	0x01, 0x14, 0x46, 0x31,
 	0xff, 0x6a, 0x10, 0x09,
 	0xfe, 0x85, 0x0a, 0x09,
-	0xff, 0x38, 0x00, 0x6b,
-	0x80, 0xa3, 0x00, 0x7b,
-	0x80, 0x0b, 0xfe, 0x7a,
-	0x04, 0x3b, 0x00, 0x7b,
+	0xff, 0x38, 0x04, 0x6b,
+	0x80, 0xa3, 0x04, 0x7b,
+	0x80, 0x0b, 0x02, 0x7b,
+	0x04, 0x3b, 0x04, 0x7b,
 	0xbf, 0x3b, 0x76, 0x08,
 	0x01, 0x3b, 0x26, 0x31,
-	0x00, 0x65, 0x02, 0x5a,
-	0x01, 0x0b, 0x0e, 0x6b,
-	0x10, 0x0c, 0x02, 0x7b,
-	0x04, 0x93, 0x0c, 0x6b,
-	0x01, 0x94, 0x0a, 0x7b,
-	0x10, 0x94, 0x0c, 0x6b,
+	0x00, 0x65, 0x06, 0x5a,
+	0x01, 0x0b, 0x12, 0x6b,
+	0x10, 0x0c, 0x06, 0x7b,
+	0x04, 0x93, 0x10, 0x6b,
+	0x01, 0x94, 0x0e, 0x7b,
+	0x10, 0x94, 0x10, 0x6b,
 	0xc7, 0x93, 0x26, 0x09,
 	0x01, 0x99, 0xd4, 0x30,
-	0x38, 0x93, 0x10, 0x6b,
-	0xff, 0x08, 0x62, 0x6b,
-	0xff, 0x09, 0x62, 0x6b,
-	0xff, 0x0a, 0x62, 0x6b,
-	0xff, 0x38, 0x2c, 0x7b,
+	0x38, 0x93, 0x14, 0x6b,
+	0xff, 0x08, 0x66, 0x6b,
+	0xff, 0x09, 0x66, 0x6b,
+	0xff, 0x0a, 0x66, 0x6b,
+	0xff, 0x38, 0x30, 0x7b,
 	0x04, 0x14, 0x10, 0x31,
 	0x01, 0x38, 0x18, 0x31,
 	0x02, 0x6a, 0x1a, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x14, 0x6a, 0xe6, 0x5d,
-	0x00, 0x38, 0xd2, 0x5d,
+	0x14, 0x6a, 0xea, 0x5d,
+	0x00, 0x38, 0xd6, 0x5d,
 	0xff, 0x6a, 0x70, 0x08,
-	0x00, 0x65, 0x58, 0x43,
-	0x80, 0xa3, 0x32, 0x7b,
+	0x00, 0x65, 0x5c, 0x43,
+	0x80, 0xa3, 0x36, 0x7b,
 	0x01, 0xa4, 0x48, 0x01,
-	0x00, 0x65, 0x62, 0x43,
-	0x08, 0xeb, 0x38, 0x7b,
-	0x00, 0x65, 0x02, 0x5a,
-	0x08, 0xeb, 0x34, 0x6b,
+	0x00, 0x65, 0x66, 0x43,
+	0x08, 0xeb, 0x3c, 0x7b,
+	0x00, 0x65, 0x06, 0x5a,
+	0x08, 0xeb, 0x38, 0x6b,
 	0x07, 0xe9, 0x10, 0x31,
 	0x01, 0xe9, 0xca, 0x30,
 	0x01, 0x65, 0x46, 0x31,
-	0x00, 0x6a, 0xac, 0x5e,
+	0x00, 0x6a, 0xb0, 0x5e,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xa4, 0x6a, 0xe6, 0x5d,
-	0x08, 0x6a, 0xd2, 0x5d,
+	0xa4, 0x6a, 0xea, 0x5d,
+	0x08, 0x6a, 0xd6, 0x5d,
 	0x0d, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0x9a, 0x5e,
+	0x00, 0x65, 0x9e, 0x5e,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x00, 0x65, 0x7c, 0x5e,
+	0x00, 0x65, 0x80, 0x5e,
 	0x01, 0x99, 0x46, 0x31,
-	0x00, 0xa3, 0xac, 0x5e,
+	0x00, 0xa3, 0xb0, 0x5e,
 	0x01, 0x88, 0x10, 0x31,
-	0x00, 0x65, 0x36, 0x5a,
-	0x00, 0x65, 0xee, 0x59,
+	0x00, 0x65, 0x3a, 0x5a,
+	0x00, 0x65, 0xf2, 0x59,
 	0x03, 0x8c, 0x10, 0x30,
-	0x00, 0x65, 0xd8, 0x5d,
-	0x01, 0x8c, 0x60, 0x7b,
+	0x00, 0x65, 0xdc, 0x5d,
+	0x01, 0x8c, 0x64, 0x7b,
 	0x01, 0x55, 0xaa, 0x10,
-	0x80, 0x0b, 0x80, 0x6a,
-	0x80, 0x0b, 0x6a, 0x6b,
-	0x01, 0x0c, 0x64, 0x7b,
-	0x10, 0x0c, 0x80, 0x7a,
-	0x03, 0x9e, 0x80, 0x6a,
-	0x00, 0x65, 0xf8, 0x59,
-	0x00, 0x6a, 0xac, 0x5e,
-	0x01, 0xa4, 0x8a, 0x6b,
-	0xff, 0x38, 0x80, 0x7b,
+	0x80, 0x0b, 0x84, 0x6a,
+	0x80, 0x0b, 0x6e, 0x6b,
+	0x01, 0x0c, 0x68, 0x7b,
+	0x10, 0x0c, 0x84, 0x7a,
+	0x03, 0x9e, 0x84, 0x6a,
+	0x00, 0x65, 0xfc, 0x59,
+	0x00, 0x6a, 0xb0, 0x5e,
+	0x01, 0xa4, 0x8e, 0x6b,
+	0xff, 0x38, 0x84, 0x7b,
 	0x01, 0x38, 0xc8, 0x30,
 	0x00, 0x08, 0x40, 0x19,
 	0xff, 0x6a, 0xc8, 0x08,
 	0x00, 0x09, 0x42, 0x21,
 	0x00, 0x0a, 0x44, 0x21,
 	0xff, 0x6a, 0x70, 0x08,
-	0x00, 0x65, 0x82, 0x43,
+	0x00, 0x65, 0x86, 0x43,
 	0x03, 0x08, 0x40, 0x31,
 	0x03, 0x08, 0x40, 0x31,
 	0x01, 0x08, 0x40, 0x31,
@@ -462,19 +464,19 @@
 	0xfd, 0xb4, 0x68, 0x09,
 	0x12, 0x01, 0x02, 0x00,
 	0x12, 0x01, 0x02, 0x00,
-	0x04, 0x3c, 0xc0, 0x79,
+	0x04, 0x3c, 0xc4, 0x79,
 	0xfb, 0x3c, 0x78, 0x08,
 	0x04, 0x93, 0x1e, 0x79,
-	0x01, 0x0c, 0x96, 0x6b,
+	0x01, 0x0c, 0x9a, 0x6b,
 	0x01, 0x55, 0x1e, 0x79,
 	0x80, 0x04, 0x1e, 0x79,
-	0xe4, 0x6a, 0x60, 0x5d,
-	0x23, 0x6a, 0x76, 0x5d,
-	0x01, 0x6a, 0x76, 0x5d,
+	0xe4, 0x6a, 0x64, 0x5d,
+	0x23, 0x6a, 0x7a, 0x5d,
+	0x01, 0x6a, 0x7a, 0x5d,
 	0x00, 0x65, 0x1e, 0x41,
-	0x00, 0x65, 0xc0, 0x41,
-	0x80, 0x3c, 0xaa, 0x6b,
-	0x21, 0x6a, 0xca, 0x46,
+	0x00, 0x65, 0xc4, 0x41,
+	0x80, 0x3c, 0xae, 0x6b,
+	0x21, 0x6a, 0xce, 0x46,
 	0x01, 0xbc, 0x18, 0x31,
 	0x02, 0x6a, 0x1a, 0x31,
 	0x02, 0x6a, 0xf8, 0x01,
@@ -484,16 +486,16 @@
 	0xff, 0x6a, 0x12, 0x08,
 	0xff, 0x6a, 0x14, 0x08,
 	0xf3, 0xbc, 0xd4, 0x18,
-	0xa0, 0x6a, 0xd0, 0x53,
+	0xa0, 0x6a, 0xd4, 0x53,
 	0x04, 0xa0, 0x10, 0x31,
 	0xac, 0x6a, 0x26, 0x01,
 	0x04, 0xa0, 0x10, 0x31,
 	0x03, 0x08, 0x18, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xa0, 0x6a, 0xe6, 0x5d,
-	0x00, 0xbc, 0xd2, 0x5d,
+	0xa0, 0x6a, 0xea, 0x5d,
+	0x00, 0xbc, 0xd6, 0x5d,
 	0x3d, 0x6a, 0x26, 0x01,
-	0x00, 0x65, 0xe8, 0x43,
+	0x00, 0x65, 0xec, 0x43,
 	0xff, 0x6a, 0x10, 0x09,
 	0xa4, 0x6a, 0x26, 0x01,
 	0x0c, 0xa0, 0x32, 0x31,
@@ -503,117 +505,117 @@
 	0x36, 0x6a, 0x26, 0x01,
 	0x02, 0x93, 0x26, 0x01,
 	0x35, 0x6a, 0x26, 0x01,
-	0x00, 0x65, 0x8e, 0x5e,
-	0x00, 0x65, 0x8e, 0x5e,
+	0x00, 0x65, 0x92, 0x5e,
+	0x00, 0x65, 0x92, 0x5e,
 	0x02, 0x93, 0x26, 0x01,
-	0x04, 0x0b, 0xec, 0x6b,
-	0x10, 0x0c, 0xe8, 0x7b,
-	0x01, 0x03, 0xec, 0x6b,
-	0x20, 0x93, 0xe8, 0x6b,
+	0x04, 0x0b, 0xf0, 0x6b,
+	0x10, 0x0c, 0xec, 0x7b,
+	0x01, 0x03, 0xf0, 0x6b,
+	0x20, 0x93, 0xec, 0x6b,
 	0xc7, 0x93, 0x26, 0x09,
-	0x38, 0x93, 0xf2, 0x6b,
+	0x38, 0x93, 0xf6, 0x6b,
 	0x10, 0x01, 0x02, 0x00,
-	0x00, 0x65, 0xc0, 0x41,
-	0x80, 0x3c, 0xfc, 0x6b,
-	0x21, 0x6a, 0xca, 0x46,
+	0x00, 0x65, 0xc4, 0x41,
+	0x80, 0x3c, 0x00, 0x6c,
+	0x21, 0x6a, 0xce, 0x46,
 	0x01, 0x06, 0x50, 0x31,
-	0x00, 0x65, 0xc0, 0x41,
+	0x00, 0x65, 0xc4, 0x41,
 	0x10, 0x3f, 0x06, 0x00,
 	0x10, 0x6a, 0x06, 0x00,
 	0x01, 0x3a, 0xca, 0x30,
-	0x80, 0x65, 0x20, 0x64,
-	0x10, 0xb8, 0x44, 0x6c,
+	0x80, 0x65, 0x24, 0x64,
+	0x10, 0xb8, 0x48, 0x6c,
 	0xc0, 0xba, 0xca, 0x00,
-	0x40, 0xb8, 0x10, 0x6c,
+	0x40, 0xb8, 0x14, 0x6c,
 	0xbf, 0x65, 0xca, 0x08,
-	0x20, 0xb8, 0x24, 0x7c,
+	0x20, 0xb8, 0x28, 0x7c,
 	0x01, 0x65, 0x0c, 0x30,
-	0x00, 0x65, 0xca, 0x5d,
-	0xa0, 0x3f, 0x2c, 0x64,
+	0x00, 0x65, 0xce, 0x5d,
+	0xa0, 0x3f, 0x30, 0x64,
 	0x23, 0xb8, 0x0c, 0x08,
-	0x00, 0x65, 0xca, 0x5d,
-	0xa0, 0x3f, 0x2c, 0x64,
-	0x00, 0xbb, 0x24, 0x44,
-	0xff, 0x65, 0x24, 0x64,
-	0x00, 0x65, 0x44, 0x44,
+	0x00, 0x65, 0xce, 0x5d,
+	0xa0, 0x3f, 0x30, 0x64,
+	0x00, 0xbb, 0x28, 0x44,
+	0xff, 0x65, 0x28, 0x64,
+	0x00, 0x65, 0x48, 0x44,
 	0x40, 0x6a, 0x18, 0x00,
 	0x01, 0x65, 0x0c, 0x30,
-	0x00, 0x65, 0xca, 0x5d,
-	0xa0, 0x3f, 0x00, 0x74,
+	0x00, 0x65, 0xce, 0x5d,
+	0xa0, 0x3f, 0x04, 0x74,
 	0x40, 0x6a, 0x18, 0x00,
 	0x01, 0x3a, 0xa6, 0x30,
 	0x08, 0x6a, 0x74, 0x00,
-	0x00, 0x65, 0xc0, 0x41,
-	0x64, 0x6a, 0x5a, 0x5d,
-	0x80, 0x64, 0xca, 0x6c,
-	0x04, 0x64, 0x90, 0x74,
-	0x02, 0x64, 0x9e, 0x74,
-	0x00, 0x6a, 0x60, 0x74,
-	0x03, 0x64, 0xbc, 0x74,
-	0x23, 0x64, 0x4c, 0x74,
-	0x08, 0x64, 0x5c, 0x74,
-	0x61, 0x6a, 0xca, 0x5e,
-	0x00, 0x65, 0xca, 0x5d,
-	0x08, 0x51, 0xc2, 0x71,
-	0x00, 0x65, 0x44, 0x44,
-	0x80, 0x04, 0x5a, 0x7c,
-	0x51, 0x6a, 0x50, 0x5d,
-	0x01, 0x51, 0x5a, 0x64,
-	0x01, 0xa4, 0x56, 0x7c,
-	0x01, 0x55, 0x5c, 0x7c,
-	0x41, 0x6a, 0xca, 0x5e,
-	0x00, 0x65, 0x5c, 0x44,
-	0x07, 0x6a, 0x46, 0x5d,
+	0x00, 0x65, 0xc4, 0x41,
+	0x64, 0x6a, 0x5e, 0x5d,
+	0x80, 0x64, 0xce, 0x6c,
+	0x04, 0x64, 0x94, 0x74,
+	0x02, 0x64, 0xa2, 0x74,
+	0x00, 0x6a, 0x64, 0x74,
+	0x03, 0x64, 0xc0, 0x74,
+	0x23, 0x64, 0x50, 0x74,
+	0x08, 0x64, 0x60, 0x74,
+	0x61, 0x6a, 0xce, 0x5e,
+	0x00, 0x65, 0xce, 0x5d,
+	0x08, 0x51, 0xc6, 0x71,
+	0x00, 0x65, 0x48, 0x44,
+	0x80, 0x04, 0x5e, 0x7c,
+	0x51, 0x6a, 0x54, 0x5d,
+	0x01, 0x51, 0x5e, 0x64,
+	0x01, 0xa4, 0x5a, 0x7c,
+	0x01, 0x55, 0x60, 0x7c,
+	0x41, 0x6a, 0xce, 0x5e,
+	0x00, 0x65, 0x60, 0x44,
+	0x07, 0x6a, 0x4a, 0x5d,
 	0x01, 0x06, 0xd4, 0x30,
-	0x00, 0x65, 0xc0, 0x41,
-	0x10, 0xb8, 0x64, 0x7c,
-	0xa1, 0x6a, 0xca, 0x5e,
-	0x01, 0xb4, 0x6a, 0x6c,
-	0x02, 0xb4, 0x6c, 0x6c,
-	0x01, 0xa4, 0x6c, 0x7c,
-	0xff, 0xa8, 0x7c, 0x7c,
+	0x00, 0x65, 0xc4, 0x41,
+	0x10, 0xb8, 0x68, 0x7c,
+	0xa1, 0x6a, 0xce, 0x5e,
+	0x01, 0xb4, 0x6e, 0x6c,
+	0x02, 0xb4, 0x70, 0x6c,
+	0x01, 0xa4, 0x70, 0x7c,
+	0xff, 0xa8, 0x80, 0x7c,
 	0x04, 0xb4, 0x68, 0x01,
 	0x01, 0x6a, 0x76, 0x00,
-	0x00, 0xbb, 0x04, 0x5e,
-	0xff, 0xa8, 0x7c, 0x7c,
-	0x71, 0x6a, 0xca, 0x5e,
-	0x40, 0x51, 0x7c, 0x64,
-	0x00, 0x65, 0xa4, 0x5e,
-	0x00, 0x65, 0xd2, 0x41,
-	0x00, 0xbb, 0x80, 0x5c,
-	0x00, 0x65, 0xd2, 0x41,
-	0x00, 0x65, 0xa4, 0x5e,
+	0x00, 0xbb, 0x08, 0x5e,
+	0xff, 0xa8, 0x80, 0x7c,
+	0x71, 0x6a, 0xce, 0x5e,
+	0x40, 0x51, 0x80, 0x64,
+	0x00, 0x65, 0xa8, 0x5e,
+	0x00, 0x65, 0xd6, 0x41,
+	0x00, 0xbb, 0x84, 0x5c,
+	0x00, 0x65, 0xd6, 0x41,
+	0x00, 0x65, 0xa8, 0x5e,
 	0x01, 0x65, 0xa2, 0x30,
 	0x01, 0xf8, 0xc8, 0x30,
 	0x01, 0x4e, 0xc8, 0x30,
-	0x00, 0x6a, 0xa8, 0xdd,
-	0x00, 0x51, 0xba, 0x5d,
+	0x00, 0x6a, 0xac, 0xdd,
+	0x00, 0x51, 0xbe, 0x5d,
 	0x01, 0x4e, 0x9c, 0x18,
 	0x02, 0x6a, 0x22, 0x05,
 	0x04, 0xb8, 0x70, 0x01,
-	0x00, 0x65, 0xc6, 0x5e,
-	0x20, 0xb8, 0xd2, 0x69,
+	0x00, 0x65, 0xca, 0x5e,
+	0x20, 0xb8, 0xd6, 0x69,
 	0x01, 0xbb, 0xa2, 0x30,
 	0x01, 0xba, 0x7c, 0x30,
-	0x00, 0xb9, 0xc0, 0x5c,
-	0x00, 0x65, 0xd2, 0x41,
+	0x00, 0xb9, 0xc4, 0x5c,
+	0x00, 0x65, 0xd6, 0x41,
 	0x01, 0x06, 0xd4, 0x30,
-	0x20, 0x3c, 0xc0, 0x79,
-	0x20, 0x3c, 0x5c, 0x7c,
-	0x01, 0xa4, 0xac, 0x7c,
+	0x20, 0x3c, 0xc4, 0x79,
+	0x20, 0x3c, 0x60, 0x7c,
+	0x01, 0xa4, 0xb0, 0x7c,
 	0x01, 0xb4, 0x68, 0x01,
-	0x00, 0x65, 0xc0, 0x41,
-	0x00, 0x65, 0x5c, 0x44,
+	0x00, 0x65, 0xc4, 0x41,
+	0x00, 0x65, 0x60, 0x44,
 	0x04, 0x14, 0x58, 0x31,
 	0x01, 0x06, 0xd4, 0x30,
 	0x08, 0xa0, 0x60, 0x31,
 	0xac, 0x6a, 0xcc, 0x00,
-	0x14, 0x6a, 0xe6, 0x5d,
+	0x14, 0x6a, 0xea, 0x5d,
 	0x01, 0x06, 0xd4, 0x30,
-	0xa0, 0x6a, 0xde, 0x5d,
-	0x00, 0x65, 0xc0, 0x41,
+	0xa0, 0x6a, 0xe2, 0x5d,
+	0x00, 0x65, 0xc4, 0x41,
 	0xdf, 0x3c, 0x78, 0x08,
-	0x00, 0x65, 0x5c, 0x44,
+	0x00, 0x65, 0x60, 0x44,
 	0x4c, 0x65, 0xcc, 0x28,
 	0x01, 0x3e, 0x20, 0x31,
 	0xd0, 0x66, 0xcc, 0x18,
@@ -624,102 +626,102 @@
 	0xd0, 0x65, 0xca, 0x18,
 	0x01, 0x3e, 0x20, 0x31,
 	0x30, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0xd8, 0x4c,
+	0x00, 0x65, 0xdc, 0x4c,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x20, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0xe0, 0x54,
+	0x00, 0x65, 0xe4, 0x54,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x20, 0x65, 0xca, 0x18,
 	0xe0, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0xea, 0x4c,
+	0x00, 0x65, 0xee, 0x4c,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xd0, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0xf2, 0x54,
+	0x00, 0x65, 0xf6, 0x54,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x01, 0x6c, 0xa2, 0x30,
-	0xff, 0x51, 0x04, 0x75,
-	0x00, 0x51, 0x80, 0x5d,
+	0xff, 0x51, 0x08, 0x75,
+	0x00, 0x51, 0x84, 0x5d,
 	0x01, 0x51, 0x20, 0x31,
-	0x00, 0x65, 0x26, 0x45,
+	0x00, 0x65, 0x2a, 0x45,
 	0x01, 0xba, 0xc8, 0x30,
-	0x00, 0x3e, 0x26, 0x75,
-	0x00, 0x65, 0xa2, 0x5e,
+	0x00, 0x3e, 0x2a, 0x75,
+	0x00, 0x65, 0xa6, 0x5e,
 	0x80, 0x3c, 0x78, 0x00,
 	0x01, 0x06, 0xd4, 0x30,
-	0x00, 0x65, 0xca, 0x5d,
+	0x00, 0x65, 0xce, 0x5d,
 	0x01, 0x3c, 0x78, 0x00,
-	0xe0, 0x3f, 0x42, 0x65,
+	0xe0, 0x3f, 0x46, 0x65,
 	0x02, 0x3c, 0x78, 0x00,
-	0x20, 0x12, 0x42, 0x65,
-	0x51, 0x6a, 0x50, 0x5d,
-	0x00, 0x51, 0x80, 0x5d,
-	0x51, 0x6a, 0x50, 0x5d,
+	0x20, 0x12, 0x46, 0x65,
+	0x51, 0x6a, 0x54, 0x5d,
+	0x00, 0x51, 0x84, 0x5d,
+	0x51, 0x6a, 0x54, 0x5d,
 	0x01, 0x51, 0x20, 0x31,
 	0x04, 0x3c, 0x78, 0x00,
 	0x01, 0xb9, 0xc8, 0x30,
-	0x00, 0x3d, 0x40, 0x65,
+	0x00, 0x3d, 0x44, 0x65,
 	0x08, 0x3c, 0x78, 0x00,
 	0x01, 0xba, 0xc8, 0x30,
-	0x00, 0x3e, 0x40, 0x65,
+	0x00, 0x3e, 0x44, 0x65,
 	0x10, 0x3c, 0x78, 0x00,
-	0x04, 0xb8, 0x40, 0x7d,
+	0x04, 0xb8, 0x44, 0x7d,
 	0xfb, 0xb8, 0x70, 0x09,
-	0x20, 0xb8, 0x36, 0x6d,
+	0x20, 0xb8, 0x3a, 0x6d,
 	0x01, 0x90, 0xc8, 0x30,
 	0xff, 0x6a, 0xa2, 0x00,
-	0x00, 0x3d, 0xc0, 0x5c,
+	0x00, 0x3d, 0xc4, 0x5c,
 	0x01, 0x64, 0x20, 0x31,
 	0x80, 0x6a, 0x78, 0x00,
 	0x00, 0x65, 0xec, 0x58,
-	0x10, 0xb8, 0x5c, 0x7c,
-	0xff, 0x6a, 0x46, 0x5d,
-	0x00, 0x65, 0x5c, 0x44,
-	0x00, 0x65, 0xa2, 0x5e,
-	0x31, 0x6a, 0xca, 0x5e,
-	0x00, 0x65, 0x5c, 0x44,
+	0x10, 0xb8, 0x60, 0x7c,
+	0xff, 0x6a, 0x4a, 0x5d,
+	0x00, 0x65, 0x60, 0x44,
+	0x00, 0x65, 0xa6, 0x5e,
+	0x31, 0x6a, 0xce, 0x5e,
+	0x00, 0x65, 0x60, 0x44,
 	0x10, 0x3f, 0x06, 0x00,
 	0x10, 0x6a, 0x06, 0x00,
 	0x01, 0x65, 0x74, 0x34,
-	0x81, 0x6a, 0xca, 0x5e,
-	0x00, 0x65, 0x52, 0x45,
+	0x81, 0x6a, 0xce, 0x5e,
+	0x00, 0x65, 0x56, 0x45,
 	0x01, 0x06, 0xd4, 0x30,
-	0x01, 0x0c, 0x52, 0x7d,
-	0x04, 0x0c, 0x4c, 0x6d,
+	0x01, 0x0c, 0x56, 0x7d,
+	0x04, 0x0c, 0x50, 0x6d,
 	0xe0, 0x03, 0x7e, 0x08,
-	0xe0, 0x3f, 0xc0, 0x61,
+	0xe0, 0x3f, 0xc4, 0x61,
 	0x01, 0x65, 0xcc, 0x30,
 	0x01, 0x12, 0xda, 0x34,
 	0x01, 0x06, 0xd4, 0x34,
-	0x01, 0x03, 0x60, 0x6d,
+	0x01, 0x03, 0x64, 0x6d,
 	0x40, 0x03, 0xcc, 0x08,
 	0x01, 0x65, 0x06, 0x30,
 	0x40, 0x65, 0xc8, 0x08,
-	0x00, 0x66, 0x6e, 0x75,
-	0x40, 0x65, 0x6e, 0x7d,
-	0x00, 0x65, 0x6e, 0x5d,
+	0x00, 0x66, 0x72, 0x75,
+	0x40, 0x65, 0x72, 0x7d,
+	0x00, 0x65, 0x72, 0x5d,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x0c,
 	0x08, 0x01, 0x02, 0x00,
-	0x02, 0x0b, 0x78, 0x7d,
-	0x01, 0x65, 0x0c, 0x30,
 	0x02, 0x0b, 0x7c, 0x7d,
+	0x01, 0x65, 0x0c, 0x30,
+	0x02, 0x0b, 0x80, 0x7d,
 	0xf7, 0x01, 0x02, 0x0c,
 	0x01, 0x65, 0xc8, 0x30,
-	0xff, 0x41, 0xa0, 0x75,
+	0xff, 0x41, 0xa4, 0x75,
 	0x01, 0x41, 0x20, 0x31,
 	0xff, 0x6a, 0xa4, 0x00,
-	0x00, 0x65, 0x90, 0x45,
-	0xff, 0xbf, 0xa0, 0x75,
+	0x00, 0x65, 0x94, 0x45,
+	0xff, 0xbf, 0xa4, 0x75,
 	0x01, 0x90, 0xa4, 0x30,
 	0x01, 0xbf, 0x20, 0x31,
-	0x00, 0xbb, 0x8a, 0x65,
-	0xff, 0x52, 0x9e, 0x75,
+	0x00, 0xbb, 0x8e, 0x65,
+	0xff, 0x52, 0xa2, 0x75,
 	0x01, 0xbf, 0xcc, 0x30,
 	0x01, 0x90, 0xca, 0x30,
 	0x01, 0x52, 0x20, 0x31,
@@ -727,28 +729,28 @@
 	0x01, 0x65, 0x20, 0x35,
 	0x01, 0xbf, 0x82, 0x34,
 	0x01, 0x64, 0xa2, 0x30,
-	0x00, 0x6a, 0xb2, 0x5e,
+	0x00, 0x6a, 0xb6, 0x5e,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0x51, 0x04, 0x46,
+	0x00, 0x51, 0x08, 0x46,
 	0x01, 0x65, 0xa4, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0xf8, 0x5d,
+	0x48, 0x6a, 0xfc, 0x5d,
 	0x01, 0x6a, 0xd0, 0x01,
 	0x01, 0x6a, 0xdc, 0x05,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0xf8, 0x5d,
-	0x01, 0x6a, 0xd2, 0x5d,
+	0x48, 0x6a, 0xfc, 0x5d,
+	0x01, 0x6a, 0xd6, 0x5d,
 	0x01, 0x6a, 0x26, 0x05,
 	0x01, 0x65, 0xd8, 0x31,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0xbe, 0x7d,
+	0x80, 0xee, 0xc2, 0x7d,
 	0xff, 0x6a, 0xdc, 0x0d,
 	0x01, 0x65, 0x32, 0x31,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0x9a, 0x46,
-	0x81, 0x6a, 0xca, 0x5e,
-	0x01, 0x0c, 0xca, 0x7d,
-	0x04, 0x0c, 0xc8, 0x6d,
+	0x00, 0x65, 0x9e, 0x46,
+	0x81, 0x6a, 0xce, 0x5e,
+	0x01, 0x0c, 0xce, 0x7d,
+	0x04, 0x0c, 0xcc, 0x6d,
 	0xe0, 0x03, 0x06, 0x08,
 	0xe0, 0x03, 0x7e, 0x0c,
 	0x01, 0x65, 0x18, 0x31,
@@ -767,7 +769,7 @@
 	0x01, 0x6c, 0xda, 0x34,
 	0x3d, 0x64, 0xa4, 0x28,
 	0x55, 0x64, 0xc8, 0x28,
-	0x00, 0x65, 0xf8, 0x45,
+	0x00, 0x65, 0xfc, 0x45,
 	0x2e, 0x64, 0xa4, 0x28,
 	0x66, 0x64, 0xc8, 0x28,
 	0x00, 0x6c, 0xda, 0x18,
@@ -778,63 +780,63 @@
 	0x00, 0x6c, 0xda, 0x24,
 	0x01, 0x65, 0xc8, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x44, 0x6a, 0xf4, 0x5d,
+	0x44, 0x6a, 0xf8, 0x5d,
 	0x01, 0x90, 0xe2, 0x31,
-	0x04, 0x3b, 0x18, 0x7e,
+	0x04, 0x3b, 0x1c, 0x7e,
 	0x30, 0x6a, 0xd0, 0x01,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x1d, 0x6a, 0xdc, 0x01,
-	0xdc, 0xee, 0x14, 0x66,
-	0x00, 0x65, 0x30, 0x46,
+	0xdc, 0xee, 0x18, 0x66,
+	0x00, 0x65, 0x34, 0x46,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x01, 0x6a, 0xdc, 0x01,
 	0x20, 0xa0, 0xd8, 0x31,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0x20, 0x7e,
+	0x80, 0xee, 0x24, 0x7e,
 	0x11, 0x6a, 0xdc, 0x01,
-	0x50, 0xee, 0x24, 0x66,
+	0x50, 0xee, 0x28, 0x66,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x09, 0x6a, 0xdc, 0x01,
-	0x88, 0xee, 0x2a, 0x66,
+	0x88, 0xee, 0x2e, 0x66,
 	0x19, 0x6a, 0xdc, 0x01,
-	0xd8, 0xee, 0x2e, 0x66,
+	0xd8, 0xee, 0x32, 0x66,
 	0xff, 0x6a, 0xdc, 0x09,
-	0x18, 0xee, 0x32, 0x6e,
+	0x18, 0xee, 0x36, 0x6e,
 	0xff, 0x6a, 0xd4, 0x0c,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x44, 0x6a, 0xf4, 0x5d,
-	0x20, 0x6a, 0xd2, 0x5d,
+	0x44, 0x6a, 0xf8, 0x5d,
+	0x20, 0x6a, 0xd6, 0x5d,
 	0x01, 0x3b, 0x26, 0x31,
-	0x04, 0x3b, 0x4c, 0x6e,
+	0x04, 0x3b, 0x50, 0x6e,
 	0xa0, 0x6a, 0xca, 0x00,
 	0x20, 0x65, 0xc8, 0x18,
-	0x00, 0x65, 0x8a, 0x5e,
-	0x00, 0x65, 0x44, 0x66,
+	0x00, 0x65, 0x8e, 0x5e,
+	0x00, 0x65, 0x48, 0x66,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0x9a, 0x46,
+	0x00, 0x65, 0x9e, 0x46,
 	0xa0, 0x6a, 0xcc, 0x00,
 	0xff, 0x6a, 0xc8, 0x08,
-	0x20, 0x94, 0x50, 0x6e,
-	0x10, 0x94, 0x52, 0x6e,
-	0x08, 0x94, 0x6c, 0x6e,
-	0x08, 0x94, 0x6c, 0x6e,
-	0x08, 0x94, 0x6c, 0x6e,
+	0x20, 0x94, 0x54, 0x6e,
+	0x10, 0x94, 0x56, 0x6e,
+	0x08, 0x94, 0x70, 0x6e,
+	0x08, 0x94, 0x70, 0x6e,
+	0x08, 0x94, 0x70, 0x6e,
 	0xff, 0x8c, 0xc8, 0x10,
 	0xc1, 0x64, 0xc8, 0x18,
 	0xf8, 0x64, 0xc8, 0x08,
 	0x01, 0x99, 0xda, 0x30,
-	0x00, 0x66, 0x60, 0x66,
-	0xc0, 0x66, 0x9c, 0x76,
+	0x00, 0x66, 0x64, 0x66,
+	0xc0, 0x66, 0xa0, 0x76,
 	0x60, 0x66, 0xc8, 0x18,
 	0x3d, 0x64, 0xc8, 0x28,
-	0x00, 0x65, 0x50, 0x46,
+	0x00, 0x65, 0x54, 0x46,
 	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0x6e, 0x6e,
+	0x08, 0x93, 0x72, 0x6e,
 	0x00, 0x62, 0xc4, 0x18,
-	0x00, 0x65, 0x9a, 0x5e,
-	0x00, 0x65, 0x7a, 0x5e,
-	0x00, 0x65, 0x7a, 0x5e,
-	0x00, 0x65, 0x7a, 0x5e,
+	0x00, 0x65, 0x9e, 0x5e,
+	0x00, 0x65, 0x7e, 0x5e,
+	0x00, 0x65, 0x7e, 0x5e,
+	0x00, 0x65, 0x7e, 0x5e,
 	0x01, 0x99, 0xda, 0x30,
 	0x01, 0x99, 0xda, 0x30,
 	0x01, 0x99, 0xda, 0x30,
@@ -851,11 +853,11 @@
 	0x01, 0x6c, 0x32, 0x31,
 	0x01, 0x6c, 0x32, 0x31,
 	0x01, 0x6c, 0x32, 0x35,
-	0x08, 0x94, 0x9a, 0x7e,
+	0x08, 0x94, 0x9e, 0x7e,
 	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0x9e, 0x6e,
+	0x08, 0x93, 0xa2, 0x6e,
 	0xff, 0x6a, 0xd4, 0x0c,
-	0x04, 0xb8, 0xc6, 0x6e,
+	0x04, 0xb8, 0xca, 0x6e,
 	0x01, 0x42, 0x7e, 0x31,
 	0xff, 0x6a, 0x76, 0x01,
 	0x01, 0x90, 0x84, 0x34,
@@ -863,14 +865,14 @@
 	0x01, 0x85, 0x0a, 0x01,
 	0x7f, 0x65, 0x10, 0x09,
 	0xfe, 0x85, 0x0a, 0x0d,
-	0xff, 0x42, 0xc2, 0x66,
-	0xff, 0x41, 0xba, 0x66,
-	0xd1, 0x6a, 0xca, 0x5e,
+	0xff, 0x42, 0xc6, 0x66,
+	0xff, 0x41, 0xbe, 0x66,
+	0xd1, 0x6a, 0xce, 0x5e,
 	0xff, 0x6a, 0xca, 0x04,
 	0x01, 0x41, 0x20, 0x31,
 	0x01, 0xbf, 0x82, 0x30,
 	0x01, 0x6a, 0x76, 0x00,
-	0x00, 0xbb, 0x04, 0x46,
+	0x00, 0xbb, 0x08, 0x46,
 	0x01, 0x42, 0x20, 0x31,
 	0x01, 0xbf, 0x84, 0x34,
 	0x01, 0x41, 0x7e, 0x31,
@@ -880,420 +882,420 @@
 	0xff, 0x6a, 0xd4, 0x0c
 };
 
-static int ahc_patch23_func(struct ahc_softc *ahc);
+static int aic_patch23_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch23_func(struct ahc_softc *ahc)
+aic_patch23_func(struct ahc_softc *ahc)
 {
 	return ((ahc->bugs & AHC_SCBCHAN_UPLOAD_BUG) != 0);
 }
 
-static int ahc_patch22_func(struct ahc_softc *ahc);
+static int aic_patch22_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch22_func(struct ahc_softc *ahc)
+aic_patch22_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_CMD_CHAN) == 0);
 }
 
-static int ahc_patch21_func(struct ahc_softc *ahc);
+static int aic_patch21_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch21_func(struct ahc_softc *ahc)
+aic_patch21_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_QUEUE_REGS) == 0);
 }
 
-static int ahc_patch20_func(struct ahc_softc *ahc);
+static int aic_patch20_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch20_func(struct ahc_softc *ahc)
+aic_patch20_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_WIDE) != 0);
 }
 
-static int ahc_patch19_func(struct ahc_softc *ahc);
+static int aic_patch19_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch19_func(struct ahc_softc *ahc)
+aic_patch19_func(struct ahc_softc *ahc)
 {
 	return ((ahc->flags & AHC_SCB_BTT) != 0);
 }
 
-static int ahc_patch18_func(struct ahc_softc *ahc);
+static int aic_patch18_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch18_func(struct ahc_softc *ahc)
+aic_patch18_func(struct ahc_softc *ahc)
 {
 	return ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0);
 }
 
-static int ahc_patch17_func(struct ahc_softc *ahc);
+static int aic_patch17_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch17_func(struct ahc_softc *ahc)
+aic_patch17_func(struct ahc_softc *ahc)
 {
 	return ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0);
 }
 
-static int ahc_patch16_func(struct ahc_softc *ahc);
+static int aic_patch16_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch16_func(struct ahc_softc *ahc)
+aic_patch16_func(struct ahc_softc *ahc)
 {
 	return ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0);
 }
 
-static int ahc_patch15_func(struct ahc_softc *ahc);
+static int aic_patch15_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch15_func(struct ahc_softc *ahc)
+aic_patch15_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_ULTRA2) == 0);
 }
 
-static int ahc_patch14_func(struct ahc_softc *ahc);
+static int aic_patch14_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch14_func(struct ahc_softc *ahc)
+aic_patch14_func(struct ahc_softc *ahc)
 {
 	return ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0);
 }
 
-static int ahc_patch13_func(struct ahc_softc *ahc);
+static int aic_patch13_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch13_func(struct ahc_softc *ahc)
+aic_patch13_func(struct ahc_softc *ahc)
 {
 	return ((ahc->flags & AHC_39BIT_ADDRESSING) != 0);
 }
 
-static int ahc_patch12_func(struct ahc_softc *ahc);
+static int aic_patch12_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch12_func(struct ahc_softc *ahc)
+aic_patch12_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_HS_MAILBOX) != 0);
 }
 
-static int ahc_patch11_func(struct ahc_softc *ahc);
+static int aic_patch11_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch11_func(struct ahc_softc *ahc)
+aic_patch11_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_ULTRA) != 0);
 }
 
-static int ahc_patch10_func(struct ahc_softc *ahc);
+static int aic_patch10_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch10_func(struct ahc_softc *ahc)
+aic_patch10_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_MULTI_TID) != 0);
 }
 
-static int ahc_patch9_func(struct ahc_softc *ahc);
+static int aic_patch9_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch9_func(struct ahc_softc *ahc)
+aic_patch9_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_CMD_CHAN) != 0);
 }
 
-static int ahc_patch8_func(struct ahc_softc *ahc);
+static int aic_patch8_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch8_func(struct ahc_softc *ahc)
+aic_patch8_func(struct ahc_softc *ahc)
 {
 	return ((ahc->flags & AHC_INITIATORROLE) != 0);
 }
 
-static int ahc_patch7_func(struct ahc_softc *ahc);
+static int aic_patch7_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch7_func(struct ahc_softc *ahc)
+aic_patch7_func(struct ahc_softc *ahc)
 {
 	return ((ahc->flags & AHC_TARGETROLE) != 0);
 }
 
-static int ahc_patch6_func(struct ahc_softc *ahc);
+static int aic_patch6_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch6_func(struct ahc_softc *ahc)
+aic_patch6_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_DT) == 0);
 }
 
-static int ahc_patch5_func(struct ahc_softc *ahc);
+static int aic_patch5_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch5_func(struct ahc_softc *ahc)
+aic_patch5_func(struct ahc_softc *ahc)
 {
 	return ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0);
 }
 
-static int ahc_patch4_func(struct ahc_softc *ahc);
+static int aic_patch4_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch4_func(struct ahc_softc *ahc)
+aic_patch4_func(struct ahc_softc *ahc)
 {
 	return ((ahc->flags & AHC_PAGESCBS) != 0);
 }
 
-static int ahc_patch3_func(struct ahc_softc *ahc);
+static int aic_patch3_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch3_func(struct ahc_softc *ahc)
+aic_patch3_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_QUEUE_REGS) != 0);
 }
 
-static int ahc_patch2_func(struct ahc_softc *ahc);
+static int aic_patch2_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch2_func(struct ahc_softc *ahc)
+aic_patch2_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_TWIN) != 0);
 }
 
-static int ahc_patch1_func(struct ahc_softc *ahc);
+static int aic_patch1_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch1_func(struct ahc_softc *ahc)
+aic_patch1_func(struct ahc_softc *ahc)
 {
 	return ((ahc->features & AHC_ULTRA2) != 0);
 }
 
-static int ahc_patch0_func(struct ahc_softc *ahc);
+static int aic_patch0_func(struct ahc_softc *ahc);
 
 static int
-ahc_patch0_func(struct ahc_softc *ahc)
+aic_patch0_func(struct ahc_softc *ahc)
 {
 	return (0);
 }
 
-typedef int patch_func_t (struct ahc_softc *);
-struct patch {
+typedef int patch_func_t (struct ahc_softc *ahc);
+static struct patch {
 	patch_func_t	*patch_func;
 	uint32_t	begin	   :10,
 			skip_instr :10,
 			skip_patch :12;
 } patches[] = {
-	{ ahc_patch1_func, 4, 1, 1 },
-	{ ahc_patch2_func, 6, 2, 1 },
-	{ ahc_patch2_func, 9, 1, 1 },
-	{ ahc_patch3_func, 11, 1, 2 },
-	{ ahc_patch0_func, 12, 2, 1 },
-	{ ahc_patch4_func, 15, 1, 2 },
-	{ ahc_patch0_func, 16, 1, 1 },
-	{ ahc_patch5_func, 22, 2, 1 },
-	{ ahc_patch3_func, 27, 1, 2 },
-	{ ahc_patch0_func, 28, 1, 1 },
-	{ ahc_patch6_func, 34, 1, 1 },
-	{ ahc_patch7_func, 37, 54, 19 },
-	{ ahc_patch8_func, 37, 1, 1 },
-	{ ahc_patch9_func, 42, 3, 2 },
-	{ ahc_patch0_func, 45, 3, 1 },
-	{ ahc_patch10_func, 49, 1, 2 },
-	{ ahc_patch0_func, 50, 2, 3 },
-	{ ahc_patch1_func, 50, 1, 2 },
-	{ ahc_patch0_func, 51, 1, 1 },
-	{ ahc_patch2_func, 53, 2, 1 },
-	{ ahc_patch9_func, 55, 1, 2 },
-	{ ahc_patch0_func, 56, 1, 1 },
-	{ ahc_patch9_func, 60, 1, 2 },
-	{ ahc_patch0_func, 61, 1, 1 },
-	{ ahc_patch9_func, 71, 1, 2 },
-	{ ahc_patch0_func, 72, 1, 1 },
-	{ ahc_patch9_func, 75, 1, 2 },
-	{ ahc_patch0_func, 76, 1, 1 },
-	{ ahc_patch9_func, 79, 1, 2 },
-	{ ahc_patch0_func, 80, 1, 1 },
-	{ ahc_patch8_func, 91, 9, 4 },
-	{ ahc_patch1_func, 93, 1, 2 },
-	{ ahc_patch0_func, 94, 1, 1 },
-	{ ahc_patch2_func, 96, 2, 1 },
-	{ ahc_patch2_func, 105, 4, 1 },
-	{ ahc_patch1_func, 109, 1, 2 },
-	{ ahc_patch0_func, 110, 2, 3 },
-	{ ahc_patch2_func, 110, 1, 2 },
-	{ ahc_patch0_func, 111, 1, 1 },
-	{ ahc_patch7_func, 112, 4, 2 },
-	{ ahc_patch0_func, 116, 1, 1 },
-	{ ahc_patch11_func, 118, 2, 1 },
-	{ ahc_patch1_func, 120, 1, 2 },
-	{ ahc_patch0_func, 121, 1, 1 },
-	{ ahc_patch7_func, 122, 4, 1 },
-	{ ahc_patch7_func, 133, 89, 11 },
-	{ ahc_patch4_func, 151, 1, 1 },
-	{ ahc_patch1_func, 164, 1, 1 },
-	{ ahc_patch12_func, 169, 1, 2 },
-	{ ahc_patch0_func, 170, 1, 1 },
-	{ ahc_patch9_func, 181, 1, 2 },
-	{ ahc_patch0_func, 182, 1, 1 },
-	{ ahc_patch9_func, 191, 1, 2 },
-	{ ahc_patch0_func, 192, 1, 1 },
-	{ ahc_patch9_func, 208, 6, 2 },
-	{ ahc_patch0_func, 214, 6, 1 },
-	{ ahc_patch8_func, 222, 18, 2 },
-	{ ahc_patch1_func, 235, 1, 1 },
-	{ ahc_patch1_func, 242, 1, 2 },
-	{ ahc_patch0_func, 243, 2, 2 },
-	{ ahc_patch11_func, 244, 1, 1 },
-	{ ahc_patch9_func, 252, 31, 3 },
-	{ ahc_patch1_func, 268, 14, 2 },
-	{ ahc_patch13_func, 273, 1, 1 },
-	{ ahc_patch14_func, 283, 14, 1 },
-	{ ahc_patch1_func, 299, 1, 2 },
-	{ ahc_patch0_func, 300, 1, 1 },
-	{ ahc_patch9_func, 303, 1, 1 },
-	{ ahc_patch13_func, 308, 1, 1 },
-	{ ahc_patch9_func, 309, 2, 2 },
-	{ ahc_patch0_func, 311, 4, 1 },
-	{ ahc_patch14_func, 315, 1, 1 },
-	{ ahc_patch15_func, 318, 2, 3 },
-	{ ahc_patch9_func, 318, 1, 2 },
-	{ ahc_patch0_func, 319, 1, 1 },
-	{ ahc_patch6_func, 324, 1, 2 },
-	{ ahc_patch0_func, 325, 1, 1 },
-	{ ahc_patch1_func, 329, 50, 11 },
-	{ ahc_patch6_func, 338, 2, 4 },
-	{ ahc_patch7_func, 338, 1, 1 },
-	{ ahc_patch8_func, 339, 1, 1 },
-	{ ahc_patch0_func, 340, 1, 1 },
-	{ ahc_patch16_func, 341, 1, 1 },
-	{ ahc_patch6_func, 360, 6, 3 },
-	{ ahc_patch16_func, 360, 5, 1 },
-	{ ahc_patch0_func, 366, 5, 1 },
-	{ ahc_patch13_func, 374, 5, 1 },
-	{ ahc_patch0_func, 379, 54, 17 },
-	{ ahc_patch14_func, 379, 1, 1 },
-	{ ahc_patch7_func, 381, 2, 2 },
-	{ ahc_patch17_func, 382, 1, 1 },
-	{ ahc_patch9_func, 385, 1, 1 },
-	{ ahc_patch18_func, 392, 1, 1 },
-	{ ahc_patch14_func, 397, 9, 3 },
-	{ ahc_patch9_func, 398, 3, 2 },
-	{ ahc_patch0_func, 401, 3, 1 },
-	{ ahc_patch9_func, 409, 6, 2 },
-	{ ahc_patch0_func, 415, 9, 2 },
-	{ ahc_patch13_func, 415, 1, 1 },
-	{ ahc_patch13_func, 424, 2, 1 },
-	{ ahc_patch14_func, 426, 1, 1 },
-	{ ahc_patch9_func, 428, 1, 2 },
-	{ ahc_patch0_func, 429, 1, 1 },
-	{ ahc_patch7_func, 432, 1, 1 },
-	{ ahc_patch7_func, 433, 1, 1 },
-	{ ahc_patch8_func, 434, 3, 3 },
-	{ ahc_patch6_func, 435, 1, 2 },
-	{ ahc_patch0_func, 436, 1, 1 },
-	{ ahc_patch9_func, 437, 1, 1 },
-	{ ahc_patch15_func, 438, 1, 2 },
-	{ ahc_patch13_func, 438, 1, 1 },
-	{ ahc_patch14_func, 440, 9, 4 },
-	{ ahc_patch9_func, 440, 1, 1 },
-	{ ahc_patch9_func, 447, 2, 1 },
-	{ ahc_patch0_func, 449, 4, 3 },
-	{ ahc_patch9_func, 449, 1, 2 },
-	{ ahc_patch0_func, 450, 3, 1 },
-	{ ahc_patch1_func, 454, 2, 1 },
-	{ ahc_patch7_func, 456, 10, 2 },
-	{ ahc_patch0_func, 466, 1, 1 },
-	{ ahc_patch8_func, 467, 109, 23 },
-	{ ahc_patch1_func, 469, 3, 2 },
-	{ ahc_patch0_func, 472, 5, 3 },
-	{ ahc_patch9_func, 472, 2, 2 },
-	{ ahc_patch0_func, 474, 3, 1 },
-	{ ahc_patch1_func, 479, 2, 2 },
-	{ ahc_patch0_func, 481, 6, 3 },
-	{ ahc_patch9_func, 481, 2, 2 },
-	{ ahc_patch0_func, 483, 3, 1 },
-	{ ahc_patch1_func, 489, 2, 2 },
-	{ ahc_patch0_func, 491, 9, 7 },
-	{ ahc_patch9_func, 491, 5, 6 },
-	{ ahc_patch19_func, 491, 1, 2 },
-	{ ahc_patch0_func, 492, 1, 1 },
-	{ ahc_patch19_func, 494, 1, 2 },
-	{ ahc_patch0_func, 495, 1, 1 },
-	{ ahc_patch0_func, 496, 4, 1 },
-	{ ahc_patch6_func, 500, 3, 2 },
-	{ ahc_patch0_func, 503, 1, 1 },
-	{ ahc_patch1_func, 506, 1, 1 },
-	{ ahc_patch6_func, 512, 1, 2 },
-	{ ahc_patch0_func, 513, 1, 1 },
-	{ ahc_patch20_func, 550, 7, 1 },
-	{ ahc_patch3_func, 578, 1, 2 },
-	{ ahc_patch0_func, 579, 1, 1 },
-	{ ahc_patch21_func, 582, 1, 1 },
-	{ ahc_patch8_func, 584, 104, 33 },
-	{ ahc_patch4_func, 585, 1, 1 },
-	{ ahc_patch1_func, 591, 2, 2 },
-	{ ahc_patch0_func, 593, 1, 1 },
-	{ ahc_patch1_func, 596, 1, 2 },
-	{ ahc_patch0_func, 597, 1, 1 },
-	{ ahc_patch9_func, 598, 3, 3 },
-	{ ahc_patch15_func, 599, 1, 1 },
-	{ ahc_patch0_func, 601, 4, 1 },
-	{ ahc_patch19_func, 609, 2, 2 },
-	{ ahc_patch0_func, 611, 1, 1 },
-	{ ahc_patch19_func, 615, 10, 3 },
-	{ ahc_patch5_func, 617, 8, 1 },
-	{ ahc_patch0_func, 625, 9, 2 },
-	{ ahc_patch5_func, 626, 8, 1 },
-	{ ahc_patch4_func, 636, 1, 2 },
-	{ ahc_patch0_func, 637, 1, 1 },
-	{ ahc_patch19_func, 638, 1, 2 },
-	{ ahc_patch0_func, 639, 3, 2 },
-	{ ahc_patch4_func, 641, 1, 1 },
-	{ ahc_patch5_func, 642, 1, 1 },
-	{ ahc_patch5_func, 645, 1, 1 },
-	{ ahc_patch5_func, 647, 1, 1 },
-	{ ahc_patch4_func, 649, 2, 2 },
-	{ ahc_patch0_func, 651, 2, 1 },
-	{ ahc_patch5_func, 653, 1, 1 },
-	{ ahc_patch5_func, 656, 1, 1 },
-	{ ahc_patch5_func, 659, 1, 1 },
-	{ ahc_patch19_func, 663, 1, 1 },
-	{ ahc_patch19_func, 666, 1, 1 },
-	{ ahc_patch4_func, 672, 1, 1 },
-	{ ahc_patch6_func, 675, 1, 2 },
-	{ ahc_patch0_func, 676, 1, 1 },
-	{ ahc_patch7_func, 688, 16, 1 },
-	{ ahc_patch4_func, 704, 20, 1 },
-	{ ahc_patch9_func, 725, 4, 2 },
-	{ ahc_patch0_func, 729, 4, 1 },
-	{ ahc_patch9_func, 733, 4, 2 },
-	{ ahc_patch0_func, 737, 3, 1 },
-	{ ahc_patch6_func, 743, 1, 1 },
-	{ ahc_patch22_func, 745, 14, 1 },
-	{ ahc_patch7_func, 759, 3, 1 },
-	{ ahc_patch9_func, 771, 24, 8 },
-	{ ahc_patch19_func, 775, 1, 2 },
-	{ ahc_patch0_func, 776, 1, 1 },
-	{ ahc_patch15_func, 781, 4, 2 },
-	{ ahc_patch0_func, 785, 7, 3 },
-	{ ahc_patch23_func, 785, 5, 2 },
-	{ ahc_patch0_func, 790, 2, 1 },
-	{ ahc_patch0_func, 795, 42, 3 },
-	{ ahc_patch18_func, 807, 18, 2 },
-	{ ahc_patch0_func, 825, 1, 1 },
-	{ ahc_patch4_func, 849, 1, 1 },
-	{ ahc_patch4_func, 850, 3, 2 },
-	{ ahc_patch0_func, 853, 1, 1 },
-	{ ahc_patch13_func, 854, 3, 1 },
-	{ ahc_patch4_func, 857, 12, 1 }
+	{ aic_patch1_func, 4, 1, 1 },
+	{ aic_patch2_func, 6, 2, 1 },
+	{ aic_patch2_func, 9, 1, 1 },
+	{ aic_patch3_func, 11, 1, 2 },
+	{ aic_patch0_func, 12, 2, 1 },
+	{ aic_patch4_func, 15, 1, 2 },
+	{ aic_patch0_func, 16, 1, 1 },
+	{ aic_patch5_func, 22, 2, 1 },
+	{ aic_patch3_func, 27, 1, 2 },
+	{ aic_patch0_func, 28, 1, 1 },
+	{ aic_patch6_func, 34, 1, 1 },
+	{ aic_patch7_func, 37, 54, 19 },
+	{ aic_patch8_func, 37, 1, 1 },
+	{ aic_patch9_func, 42, 3, 2 },
+	{ aic_patch0_func, 45, 3, 1 },
+	{ aic_patch10_func, 49, 1, 2 },
+	{ aic_patch0_func, 50, 2, 3 },
+	{ aic_patch1_func, 50, 1, 2 },
+	{ aic_patch0_func, 51, 1, 1 },
+	{ aic_patch2_func, 53, 2, 1 },
+	{ aic_patch9_func, 55, 1, 2 },
+	{ aic_patch0_func, 56, 1, 1 },
+	{ aic_patch9_func, 60, 1, 2 },
+	{ aic_patch0_func, 61, 1, 1 },
+	{ aic_patch9_func, 71, 1, 2 },
+	{ aic_patch0_func, 72, 1, 1 },
+	{ aic_patch9_func, 75, 1, 2 },
+	{ aic_patch0_func, 76, 1, 1 },
+	{ aic_patch9_func, 79, 1, 2 },
+	{ aic_patch0_func, 80, 1, 1 },
+	{ aic_patch8_func, 91, 9, 4 },
+	{ aic_patch1_func, 93, 1, 2 },
+	{ aic_patch0_func, 94, 1, 1 },
+	{ aic_patch2_func, 96, 2, 1 },
+	{ aic_patch2_func, 105, 4, 1 },
+	{ aic_patch1_func, 109, 1, 2 },
+	{ aic_patch0_func, 110, 2, 3 },
+	{ aic_patch2_func, 110, 1, 2 },
+	{ aic_patch0_func, 111, 1, 1 },
+	{ aic_patch7_func, 112, 4, 2 },
+	{ aic_patch0_func, 116, 1, 1 },
+	{ aic_patch11_func, 118, 2, 1 },
+	{ aic_patch1_func, 120, 1, 2 },
+	{ aic_patch0_func, 121, 1, 1 },
+	{ aic_patch7_func, 122, 4, 1 },
+	{ aic_patch7_func, 132, 91, 11 },
+	{ aic_patch4_func, 151, 1, 1 },
+	{ aic_patch1_func, 165, 1, 1 },
+	{ aic_patch12_func, 170, 1, 2 },
+	{ aic_patch0_func, 171, 1, 1 },
+	{ aic_patch9_func, 182, 1, 2 },
+	{ aic_patch0_func, 183, 1, 1 },
+	{ aic_patch9_func, 192, 1, 2 },
+	{ aic_patch0_func, 193, 1, 1 },
+	{ aic_patch9_func, 209, 6, 2 },
+	{ aic_patch0_func, 215, 6, 1 },
+	{ aic_patch8_func, 223, 19, 2 },
+	{ aic_patch1_func, 237, 1, 1 },
+	{ aic_patch1_func, 244, 1, 2 },
+	{ aic_patch0_func, 245, 2, 2 },
+	{ aic_patch11_func, 246, 1, 1 },
+	{ aic_patch9_func, 254, 31, 3 },
+	{ aic_patch1_func, 270, 14, 2 },
+	{ aic_patch13_func, 275, 1, 1 },
+	{ aic_patch14_func, 285, 14, 1 },
+	{ aic_patch1_func, 301, 1, 2 },
+	{ aic_patch0_func, 302, 1, 1 },
+	{ aic_patch9_func, 305, 1, 1 },
+	{ aic_patch13_func, 310, 1, 1 },
+	{ aic_patch9_func, 311, 2, 2 },
+	{ aic_patch0_func, 313, 4, 1 },
+	{ aic_patch14_func, 317, 1, 1 },
+	{ aic_patch15_func, 320, 2, 3 },
+	{ aic_patch9_func, 320, 1, 2 },
+	{ aic_patch0_func, 321, 1, 1 },
+	{ aic_patch6_func, 326, 1, 2 },
+	{ aic_patch0_func, 327, 1, 1 },
+	{ aic_patch1_func, 331, 50, 11 },
+	{ aic_patch6_func, 340, 2, 4 },
+	{ aic_patch7_func, 340, 1, 1 },
+	{ aic_patch8_func, 341, 1, 1 },
+	{ aic_patch0_func, 342, 1, 1 },
+	{ aic_patch16_func, 343, 1, 1 },
+	{ aic_patch6_func, 362, 6, 3 },
+	{ aic_patch16_func, 362, 5, 1 },
+	{ aic_patch0_func, 368, 5, 1 },
+	{ aic_patch13_func, 376, 5, 1 },
+	{ aic_patch0_func, 381, 54, 17 },
+	{ aic_patch14_func, 381, 1, 1 },
+	{ aic_patch7_func, 383, 2, 2 },
+	{ aic_patch17_func, 384, 1, 1 },
+	{ aic_patch9_func, 387, 1, 1 },
+	{ aic_patch18_func, 394, 1, 1 },
+	{ aic_patch14_func, 399, 9, 3 },
+	{ aic_patch9_func, 400, 3, 2 },
+	{ aic_patch0_func, 403, 3, 1 },
+	{ aic_patch9_func, 411, 6, 2 },
+	{ aic_patch0_func, 417, 9, 2 },
+	{ aic_patch13_func, 417, 1, 1 },
+	{ aic_patch13_func, 426, 2, 1 },
+	{ aic_patch14_func, 428, 1, 1 },
+	{ aic_patch9_func, 430, 1, 2 },
+	{ aic_patch0_func, 431, 1, 1 },
+	{ aic_patch7_func, 434, 1, 1 },
+	{ aic_patch7_func, 435, 1, 1 },
+	{ aic_patch8_func, 436, 3, 3 },
+	{ aic_patch6_func, 437, 1, 2 },
+	{ aic_patch0_func, 438, 1, 1 },
+	{ aic_patch9_func, 439, 1, 1 },
+	{ aic_patch15_func, 440, 1, 2 },
+	{ aic_patch13_func, 440, 1, 1 },
+	{ aic_patch14_func, 442, 9, 4 },
+	{ aic_patch9_func, 442, 1, 1 },
+	{ aic_patch9_func, 449, 2, 1 },
+	{ aic_patch0_func, 451, 4, 3 },
+	{ aic_patch9_func, 451, 1, 2 },
+	{ aic_patch0_func, 452, 3, 1 },
+	{ aic_patch1_func, 456, 2, 1 },
+	{ aic_patch7_func, 458, 10, 2 },
+	{ aic_patch0_func, 468, 1, 1 },
+	{ aic_patch8_func, 469, 109, 23 },
+	{ aic_patch1_func, 471, 3, 2 },
+	{ aic_patch0_func, 474, 5, 3 },
+	{ aic_patch9_func, 474, 2, 2 },
+	{ aic_patch0_func, 476, 3, 1 },
+	{ aic_patch1_func, 481, 2, 2 },
+	{ aic_patch0_func, 483, 6, 3 },
+	{ aic_patch9_func, 483, 2, 2 },
+	{ aic_patch0_func, 485, 3, 1 },
+	{ aic_patch1_func, 491, 2, 2 },
+	{ aic_patch0_func, 493, 9, 7 },
+	{ aic_patch9_func, 493, 5, 6 },
+	{ aic_patch19_func, 493, 1, 2 },
+	{ aic_patch0_func, 494, 1, 1 },
+	{ aic_patch19_func, 496, 1, 2 },
+	{ aic_patch0_func, 497, 1, 1 },
+	{ aic_patch0_func, 498, 4, 1 },
+	{ aic_patch6_func, 502, 3, 2 },
+	{ aic_patch0_func, 505, 1, 1 },
+	{ aic_patch1_func, 508, 1, 1 },
+	{ aic_patch6_func, 514, 1, 2 },
+	{ aic_patch0_func, 515, 1, 1 },
+	{ aic_patch20_func, 552, 7, 1 },
+	{ aic_patch3_func, 580, 1, 2 },
+	{ aic_patch0_func, 581, 1, 1 },
+	{ aic_patch21_func, 584, 1, 1 },
+	{ aic_patch8_func, 586, 104, 33 },
+	{ aic_patch4_func, 587, 1, 1 },
+	{ aic_patch1_func, 593, 2, 2 },
+	{ aic_patch0_func, 595, 1, 1 },
+	{ aic_patch1_func, 598, 1, 2 },
+	{ aic_patch0_func, 599, 1, 1 },
+	{ aic_patch9_func, 600, 3, 3 },
+	{ aic_patch15_func, 601, 1, 1 },
+	{ aic_patch0_func, 603, 4, 1 },
+	{ aic_patch19_func, 611, 2, 2 },
+	{ aic_patch0_func, 613, 1, 1 },
+	{ aic_patch19_func, 617, 10, 3 },
+	{ aic_patch5_func, 619, 8, 1 },
+	{ aic_patch0_func, 627, 9, 2 },
+	{ aic_patch5_func, 628, 8, 1 },
+	{ aic_patch4_func, 638, 1, 2 },
+	{ aic_patch0_func, 639, 1, 1 },
+	{ aic_patch19_func, 640, 1, 2 },
+	{ aic_patch0_func, 641, 3, 2 },
+	{ aic_patch4_func, 643, 1, 1 },
+	{ aic_patch5_func, 644, 1, 1 },
+	{ aic_patch5_func, 647, 1, 1 },
+	{ aic_patch5_func, 649, 1, 1 },
+	{ aic_patch4_func, 651, 2, 2 },
+	{ aic_patch0_func, 653, 2, 1 },
+	{ aic_patch5_func, 655, 1, 1 },
+	{ aic_patch5_func, 658, 1, 1 },
+	{ aic_patch5_func, 661, 1, 1 },
+	{ aic_patch19_func, 665, 1, 1 },
+	{ aic_patch19_func, 668, 1, 1 },
+	{ aic_patch4_func, 674, 1, 1 },
+	{ aic_patch6_func, 677, 1, 2 },
+	{ aic_patch0_func, 678, 1, 1 },
+	{ aic_patch7_func, 690, 16, 1 },
+	{ aic_patch4_func, 706, 20, 1 },
+	{ aic_patch9_func, 727, 4, 2 },
+	{ aic_patch0_func, 731, 4, 1 },
+	{ aic_patch9_func, 735, 4, 2 },
+	{ aic_patch0_func, 739, 3, 1 },
+	{ aic_patch6_func, 745, 1, 1 },
+	{ aic_patch22_func, 747, 14, 1 },
+	{ aic_patch7_func, 761, 3, 1 },
+	{ aic_patch9_func, 773, 24, 8 },
+	{ aic_patch19_func, 777, 1, 2 },
+	{ aic_patch0_func, 778, 1, 1 },
+	{ aic_patch15_func, 783, 4, 2 },
+	{ aic_patch0_func, 787, 7, 3 },
+	{ aic_patch23_func, 787, 5, 2 },
+	{ aic_patch0_func, 792, 2, 1 },
+	{ aic_patch0_func, 797, 42, 3 },
+	{ aic_patch18_func, 809, 18, 2 },
+	{ aic_patch0_func, 827, 1, 1 },
+	{ aic_patch4_func, 851, 1, 1 },
+	{ aic_patch4_func, 852, 3, 2 },
+	{ aic_patch0_func, 855, 1, 1 },
+	{ aic_patch13_func, 856, 3, 1 },
+	{ aic_patch4_func, 859, 12, 1 }
 };
-struct cs {
+static struct cs {
 	u_int16_t	begin;
 	u_int16_t	end;
 } critical_sections[] = {
 	{ 11, 18 },
 	{ 21, 30 },
-	{ 704, 720 },
-	{ 850, 853 },
-	{ 857, 863 },
-	{ 865, 867 },
-	{ 867, 869 }
+	{ 706, 722 },
+	{ 852, 855 },
+	{ 859, 865 },
+	{ 867, 869 },
+	{ 869, 871 }
 };
-const int num_critical_sections = sizeof(critical_sections)
-				 / sizeof(*critical_sections);
+static const int num_critical_sections = sizeof(critical_sections)
+				       / sizeof(*critical_sections);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/Makefile linux/drivers/scsi/aic7xxx/aicasm/Makefile
--- linux.orig/drivers/scsi/aic7xxx/aicasm/Makefile	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/Makefile	2002-07-20 01:08:31.000000000 +0000
@@ -1,13 +1,16 @@
 PROG=	aicasm
 
-.SUFFIXES= .l .y .c
+.SUFFIXES= .l .y .c .h
 
 CSRCS=	aicasm.c aicasm_symbol.c
-GENSRCS= aicasm_gram.c aicasm_scan.c
-GENHDRS= y.tab.h aicdb.h
+YSRCS=	aicasm_gram.y aicasm_macro_gram.y
+LSRCS=	aicasm_scan.l aicasm_macro_scan.l
 
-SRCS=	${GENSRCS} ${CSRCS}
-CLEANFILES= ${GENSRCS} ${GENHDRS} y.output
+GENHDRS=	aicdb.h $(YSRCS:.y=.h)
+GENSRCS=	$(YSRCS:.y=.c) $(LSRCS:.l=.c)
+
+SRCS=	${CSRCS} ${GENSRCS}
+CLEANFILES= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output)
 # Override default kernel CFLAGS.  This is a userland app.
 AICASM_CFLAGS:= -I/usr/include -I. -ldb
 YFLAGS= -d
@@ -26,7 +29,7 @@
 LFLAGS= -d
 endif
 
-$(PROG):  $(SRCS) $(GENHDRS)
+$(PROG):  ${GENHDRS} $(SRCS)
 	$(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG)
 
 aicdb.h:
@@ -45,8 +48,18 @@
 clean:
 	rm -f $(CLEANFILES) $(PROG)
 
-y.tab.h aicasm_gram.c: aicasm_gram.y
-	$(YACC) $(YFLAGS) aicasm_gram.y
-	mv y.tab.c aicasm_gram.c
+aicasm_gram.c aicasm_gram.h: aicasm_gram.y
+	$(YACC) $(YFLAGS) -b $(<:.y=) $<
+	mv $(<:.y=).tab.c $(<:.y=.c)
+	mv $(<:.y=).tab.h $(<:.y=.h)
+
+aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y
+	$(YACC) $(YFLAGS) -b $(<:.y=) -p mm $<
+	mv $(<:.y=).tab.c $(<:.y=.c)
+	mv $(<:.y=).tab.h $(<:.y=.h)
+
+aicasm_scan.c: aicasm_scan.l
+	$(LEX) $(LFLAGS) -o$@ $<
 
-aicasm_scan.c: y.tab.h
+aicasm_macro_scan.c: aicasm_macro_scan.l
+	$(LEX) $(LFLAGS) -Pmm -o$@ $<
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm.c linux/drivers/scsi/aic7xxx/aicasm/aicasm.c
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm.c	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm.c	2002-07-20 01:08:32.000000000 +0000
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#11 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#15 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm.c,v 1.29 2000/10/05 04:25:42 gibbs Exp $
  */
@@ -46,6 +46,7 @@
 
 #include <ctype.h>
 #include <inttypes.h>
+#include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -90,6 +91,8 @@
 FILE *regfile;
 char *listfilename;
 FILE *listfile;
+int   src_mode;
+int   dst_mode;
 
 static STAILQ_HEAD(,instruction) seq_program;
 struct cs_tailq cs_tailq;
@@ -98,7 +101,9 @@
 
 #if DEBUG
 extern int yy_flex_debug;
+extern int mm_flex_debug;
 extern int yydebug;
+extern int mmdebug;
 #endif
 extern FILE *yyin;
 extern int yyparse(void);
@@ -131,7 +136,9 @@
 	listfile = NULL;
 #if DEBUG
 	yy_flex_debug = 0;
+	mm_flex_debug = 0;
 	yydebug = 0;
+	mmdebug = 0;
 #endif
 	while ((ch = getopt(argc, argv, "d:l:n:o:r:I:O:")) != -1) {
 		switch(ch) {
@@ -139,8 +146,10 @@
 #if DEBUG
 			if (strcmp(optarg, "s") == 0) {
 				yy_flex_debug = 1;
+				mm_flex_debug = 1;
 			} else if (strcmp(optarg, "p") == 0) {
 				yydebug = 1;
+				mmdebug = 1;
 			} else {
 				fprintf(stderr, "%s: -d Requires either an "
 					"'s' or 'p' argument\n", appname);
@@ -243,8 +252,7 @@
 	if (retval == 0) {
 		if (SLIST_FIRST(&scope_stack) == NULL
 		 || SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) {
-			stop("Unterminated conditional expression",
-			     EX_DATAERR);
+			stop("Unterminated conditional expression", EX_DATAERR);
 			/* NOTREACHED */
 		}
 
@@ -355,6 +363,10 @@
 	}
 	fprintf(ofile, "\n};\n\n");
 
+	if (patch_arg_list == NULL)
+		stop("Patch argument list not defined",
+		     EX_DATAERR);
+
 	/*
 	 *  Output patch information.  Patch functions first.
 	 */
@@ -362,31 +374,33 @@
 	     cur_node != NULL;
 	     cur_node = SLIST_NEXT(cur_node,links)) {
 		fprintf(ofile,
-"static int ahc_patch%d_func(struct ahc_softc *ahc);
+"static int aic_patch%d_func(%s);
 
 static int
-ahc_patch%d_func(struct ahc_softc *ahc)
+aic_patch%d_func(%s)
 {
 	return (%s);
 }\n\n",
 			cur_node->symbol->info.condinfo->func_num,
+			patch_arg_list,
 			cur_node->symbol->info.condinfo->func_num,
+			patch_arg_list,
 			cur_node->symbol->name);
 	}
 
 	fprintf(ofile,
-"typedef int patch_func_t (struct ahc_softc *);
-struct patch {
+"typedef int patch_func_t (%s);
+static struct patch {
 	patch_func_t	*patch_func;
 	uint32_t	begin	   :10,
 			skip_instr :10,
 			skip_patch :12;
-} patches[] = {\n");
+} patches[] = {\n", patch_arg_list);
 
-	for(cur_patch = STAILQ_FIRST(&patches);
-	    cur_patch != NULL;
-	    cur_patch = STAILQ_NEXT(cur_patch,links)) {
-		fprintf(ofile, "%s\t{ ahc_patch%d_func, %d, %d, %d }",
+	for (cur_patch = STAILQ_FIRST(&patches);
+	     cur_patch != NULL;
+	     cur_patch = STAILQ_NEXT(cur_patch,links)) {
+		fprintf(ofile, "%s\t{ aic_patch%d_func, %d, %d, %d }",
 			cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n",
 			cur_patch->patch_func, cur_patch->begin,
 			cur_patch->skip_instr, cur_patch->skip_patch);
@@ -395,14 +409,14 @@
 	fprintf(ofile, "\n};\n");
 
 	fprintf(ofile,
-"struct cs {
+"static struct cs {
 	u_int16_t	begin;
 	u_int16_t	end;
 } critical_sections[] = {\n");
 
-	for(cs = TAILQ_FIRST(&cs_tailq);
-	    cs != NULL;
-	    cs = TAILQ_NEXT(cs, links)) {
+	for (cs = TAILQ_FIRST(&cs_tailq);
+	     cs != NULL;
+	     cs = TAILQ_NEXT(cs, links)) {
 		fprintf(ofile, "%s\t{ %d, %d }",
 			cs == TAILQ_FIRST(&cs_tailq) ? "" : ",\n",
 			cs->begin_addr, cs->end_addr);
@@ -411,8 +425,8 @@
 	fprintf(ofile, "\n};\n");
 
 	fprintf(ofile,
-"const int num_critical_sections = sizeof(critical_sections)
-				 / sizeof(*critical_sections);\n");
+"static const int num_critical_sections = sizeof(critical_sections)
+				       / sizeof(*critical_sections);\n");
 
 	fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);
 }
@@ -555,9 +569,9 @@
 
 	/* Now output the listing */
 	cur_patch = STAILQ_FIRST(&patches);
-	for(cur_instr = STAILQ_FIRST(&seq_program);
-	    cur_instr != NULL;
-	    cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
+	for (cur_instr = STAILQ_FIRST(&seq_program);
+	     cur_instr != NULL;
+	     cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
 
 		if (check_patch(&cur_patch, instrcount,
 				&skip_addr, func_values) == 0) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm.h linux/drivers/scsi/aic7xxx/aicasm/aicasm.h
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm.h	2002-07-20 01:08:31.000000000 +0000
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#7 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#9 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm.h,v 1.11 2000/09/22 22:19:54 gibbs Exp $
  */
@@ -78,10 +78,15 @@
 extern char *appname;
 extern int yylineno;
 extern char *yyfilename;
+extern char *patch_arg_list;
 extern char *versions;
+extern int   src_mode;
+extern int   dst_mode;
+struct symbol;
 
 void stop(const char *errstring, int err_code);
 void include_file(char *file_name, include_type type);
+void expand_macro(struct symbol *macro_symbol);
 struct instruction *seq_alloc(void);
 struct critical_section *cs_alloc(void);
 struct scope *scope_alloc(void);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y linux/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y	2002-07-20 01:08:26.000000000 +0000
@@ -38,18 +38,20 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#9 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#14 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_gram.y,v 1.12 2000/10/31 18:44:32 gibbs Exp $
  */
 
+#include <sys/types.h>
+
 #include <inttypes.h>
+#include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sysexits.h>
 
-#include <sys/types.h>
 #ifdef __linux__
 #include "../queue.h"
 #else
@@ -62,21 +64,29 @@
 
 int yylineno;
 char *yyfilename;
+char *patch_arg_list;
 char *versions;
+static char errbuf[255];
+static char regex_pattern[255];
 static symbol_t *cur_symbol;
+static symbol_t *scb_or_sram_symbol;
 static symtype cur_symtype;
-static symbol_t *accumulator;
+static symbol_ref_t accumulator;
+static symbol_ref_t mode_ptr;
 static symbol_ref_t allones;
 static symbol_ref_t allzeros;
 static symbol_ref_t none;
 static symbol_ref_t sindex;
 static int instruction_ptr;
+static int num_srams;
 static int sram_or_scb_offset;
 static int download_constant_count;
 static int in_critical_section;
 
 static void process_bitmask(int mask_type, symbol_t *sym, int mask);
 static void initialize_symbol(symbol_t *symbol);
+static void add_macro_arg(const char *argtext, int position);
+static void add_macro_body(const char *bodytext);
 static void process_register(symbol_t **p_symbol);
 static void format_1_instr(int opcode, symbol_ref_t *dest,
 			   expression_t *immed, symbol_ref_t *src, int ret);
@@ -92,13 +102,12 @@
 static void add_version(const char *verstring);
 static int  is_download_const(expression_t *immed);
 
-#define YYDEBUG 1
 #define SRAM_SYMNAME "SRAM_BASE"
 #define SCB_SYMNAME "SCB_BASE"
 %}
 
 %union {
-	int		value;
+	u_int		value;
 	char		*str;
 	symbol_t	*sym;
 	symbol_ref_t	sym_ref;
@@ -109,6 +118,8 @@
 
 %token <value> T_CONST
 
+%token T_EXPORT
+
 %token T_DOWNLOAD
 
 %token T_SCB
@@ -119,10 +130,22 @@
 
 %token T_SIZE
 
+%token T_EXPR_LSHIFT
+
+%token T_EXPR_RSHIFT
+
 %token <value> T_ADDRESS
 
 %token T_ACCESS_MODE
 
+%token T_MODES
+
+%token T_DEFINE
+
+%token T_SET_SRC_MODE
+
+%token T_SET_DST_MODE
+
 %token <value> T_MODE
 
 %token T_BEGIN_CS
@@ -135,11 +158,11 @@
 
 %token <value> T_NUMBER
 
-%token <str> T_PATH T_STRING
+%token <str> T_PATH T_STRING T_ARG T_MACROBODY
 
 %token <sym> T_CEXPR
 
-%token T_EOF T_INCLUDE T_VERSION
+%token T_EOF T_INCLUDE T_VERSION T_PATCH_ARG_LIST
 
 %token <value> T_SHR T_SHL T_ROR T_ROL
 
@@ -163,7 +186,7 @@
 
 %token T_NOP
 
-%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX
+%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX T_MODE_PTR
 
 %token T_A
 
@@ -177,13 +200,15 @@
 
 %type <expression> expression immediate immediate_or_a
 
-%type <value> ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne
+%type <value> export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne
 
-%type <value> numerical_value
+%type <value> numerical_value mode_value mode_list macro_arglist
 
 %left '|'
 %left '&'
+%left T_EXPR_LSHIFT T_EXPR_RSHIFT
 %left '+' '-'
+%left '*' '/'
 %right '~'
 %nonassoc UMINUS
 %%
@@ -191,18 +216,26 @@
 program:
 	include
 |	program include
+|	patch_arg_list
+|	program patch_arg_list
 |	version
 |	program version
 |	register
 |	program register
 |	constant
 |	program constant
+|	macrodefn
+|	program macrodefn
 |	scratch_ram
 |	program scratch_ram
 |	scb
 |	program scb
 |	label
 |	program label
+|	set_src_mode
+|	program set_src_mode
+|	set_dst_mode
+|	program set_dst_mode
 |	critical_section_start
 |	program critical_section_start
 |	critical_section_end
@@ -224,6 +257,18 @@
 	}
 ;
 
+patch_arg_list:
+	T_PATCH_ARG_LIST '=' T_STRING
+	{
+		if (patch_arg_list != NULL)
+			stop("Patch argument list multiply defined",
+			     EX_DATAERR);
+		patch_arg_list = strdup($3);
+		if (patch_arg_list == NULL)
+			stop("Unable to record patch arg list", EX_SOFTWARE);
+	}
+;
+
 version:
 	T_VERSION '=' T_STRING
 	{ add_version($3); }
@@ -280,10 +325,12 @@
 	reg_address
 |	size
 |	access_mode
+|	modes
 |	bit_defn
 |	mask_defn
 |	alias
 |	accumulator
+|	mode_pointer
 |	allones
 |	allzeros
 |	none
@@ -301,6 +348,18 @@
 	T_SIZE T_NUMBER
 	{
 		cur_symbol->info.rinfo->size = $2;
+		if (scb_or_sram_symbol != NULL) {
+			u_int max_addr;
+			u_int sym_max_addr;
+
+			max_addr = scb_or_sram_symbol->info.rinfo->address
+				 + scb_or_sram_symbol->info.rinfo->size;
+			sym_max_addr = cur_symbol->info.rinfo->address
+				     + cur_symbol->info.rinfo->size;
+
+			if (sym_max_addr > max_addr)
+				stop("SCB or SRAM space exhausted", EX_DATAERR);
+		}
 	}
 ;
 
@@ -311,6 +370,54 @@
 	}
 ;
 
+modes:
+	T_MODES mode_list
+	{
+		cur_symbol->info.rinfo->modes = $2;
+	}
+;
+
+mode_list:
+	mode_value
+	{
+		$$ = $1;
+	}
+|	mode_list ',' mode_value
+	{
+		$$ = $1 | $3;
+	}
+;
+
+mode_value:
+	T_NUMBER
+	{
+		if ($1 > 4) {
+			stop("Valid register modes range between 0 and 4.",
+			     EX_DATAERR);
+			/* NOTREACHED */
+		}
+
+		$$ = (0x1 << $1);
+	}
+|	T_SYMBOL
+	{
+		symbol_t *symbol;
+
+		symbol = $1;
+		if (symbol->type != CONST) {
+			stop("Only \"const\" symbols allowed in "
+			     "mode definitions.", EX_DATAERR);
+			/* NOTREACHED */
+		}
+		if (symbol->info.cinfo->value > 4) {
+			stop("Valid register modes range between 0 and 4.",
+			     EX_DATAERR);
+			/* NOTREACHED */
+		}
+		$$ = (0x1 << symbol->info.cinfo->value);
+	}
+;
+
 bit_defn:
 	T_BIT T_SYMBOL T_NUMBER
 	{
@@ -342,12 +449,24 @@
 accumulator:
 	T_ACCUM
 	{
-		if (accumulator != NULL) {
+		if (accumulator.symbol != NULL) {
 			stop("Only one accumulator definition allowed",
 			     EX_DATAERR);
 			/* NOTREACHED */
 		}
-		accumulator = cur_symbol;
+		accumulator.symbol = cur_symbol;
+	}
+;
+
+mode_pointer:
+	T_MODE_PTR
+	{
+		if (mode_ptr.symbol != NULL) {
+			stop("Only one mode pointer definition allowed",
+			     EX_DATAERR);
+			/* NOTREACHED */
+		}
+		mode_ptr.symbol = cur_symbol;
 	}
 ;
 
@@ -428,6 +547,34 @@
 			       &($1.referenced_syms),
 			       &($3.referenced_syms));
 	}
+|	expression '*' expression
+	{
+		$$.value = $1.value * $3.value;
+		symlist_merge(&($$.referenced_syms),
+			       &($1.referenced_syms),
+			       &($3.referenced_syms));
+	}
+|	expression '/' expression
+	{
+		$$.value = $1.value / $3.value;
+		symlist_merge(&($$.referenced_syms),
+			       &($1.referenced_syms),
+			       &($3.referenced_syms));
+	}
+| 	expression T_EXPR_LSHIFT expression
+	{
+		$$.value = $1.value << $3.value;
+		symlist_merge(&$$.referenced_syms,
+			       &$1.referenced_syms,
+			       &$3.referenced_syms);
+	}
+| 	expression T_EXPR_RSHIFT expression
+	{
+		$$.value = $1.value >> $3.value;
+		symlist_merge(&$$.referenced_syms,
+			       &$1.referenced_syms,
+			       &$3.referenced_syms);
+	}
 |	'(' expression ')'
 	{
 		$$ = $2;
@@ -471,12 +618,10 @@
 		case UNINITIALIZED:
 		default:
 		{
-			char buf[255];
-
-			snprintf(buf, sizeof(buf),
+			snprintf(errbuf, sizeof(errbuf),
 				 "Undefined symbol %s referenced",
 				 symbol->name);
-			stop(buf, EX_DATAERR);
+			stop(errbuf, EX_DATAERR);
 			/* NOTREACHED */
 			break;
 		}
@@ -497,7 +642,6 @@
 		$2->type = CONST;
 		initialize_symbol($2);
 		$2->info.cinfo->value = $3;
-		$2->info.cinfo->define = $1;
 	}
 |	T_CONST T_SYMBOL T_DOWNLOAD
 	{
@@ -514,7 +658,54 @@
 		$2->type = DOWNLOAD_CONST;
 		initialize_symbol($2);
 		$2->info.cinfo->value = download_constant_count++;
-		$2->info.cinfo->define = FALSE;
+	}
+;
+
+macrodefn_prologue:
+	T_DEFINE T_SYMBOL
+	{
+		if ($2->type != UNINITIALIZED) {
+			stop("Re-definition of symbol as a macro",
+			     EX_DATAERR);
+			/* NOTREACHED */
+		}
+		cur_symbol = $2;
+		cur_symbol->type = MACRO;
+		initialize_symbol(cur_symbol);
+	}
+;
+
+macrodefn:
+	macrodefn_prologue T_MACROBODY
+	{
+		add_macro_body($2);
+	}
+|	macrodefn_prologue '(' macro_arglist ')' T_MACROBODY
+	{
+		add_macro_body($5);
+		cur_symbol->info.macroinfo->narg = $3;
+	}
+;
+
+macro_arglist:
+	{
+		/* Macros can take no arguments */
+		$$ = 0;
+	}
+|	T_ARG
+	{
+		$$ = 1;
+		add_macro_arg($1, 0);
+	}
+|	macro_arglist ',' T_ARG
+	{
+		if ($1 == 0) {
+			stop("Comma without preceeding argument in arg list",
+			     EX_DATAERR);
+			/* NOTREACHED */
+		}
+		$$ = $1 + 1;
+		add_macro_arg($3, $1);
 	}
 ;
 
@@ -532,13 +723,10 @@
 scratch_ram:
 	T_SRAM '{'
 		{
+			snprintf(errbuf, sizeof(errbuf), "%s%d", SRAM_SYMNAME,
+				 num_srams);
 			cur_symbol = symtable_get(SRAM_SYMNAME);
 			cur_symtype = SRAMLOC;
-			if (cur_symbol->type != UNINITIALIZED) {
-				stop("Only one SRAM definition allowed",
-				     EX_DATAERR);
-				/* NOTREACHED */
-			}
 			cur_symbol->type = SRAMLOC;
 			initialize_symbol(cur_symbol);
 		}
@@ -546,10 +734,15 @@
 		{
 			sram_or_scb_offset = cur_symbol->info.rinfo->address;
 		}
-		scb_or_sram_reg_list
+		size
+		{
+			scb_or_sram_symbol = cur_symbol;
+		}
+		scb_or_sram_attributes
 	'}'
 		{
 			cur_symbol = NULL;
+			scb_or_sram_symbol = NULL;
 		}
 ;
 
@@ -572,13 +765,25 @@
 		{
 			sram_or_scb_offset = cur_symbol->info.rinfo->address;
 		}
-		scb_or_sram_reg_list
+		size
+		{
+			scb_or_sram_symbol = cur_symbol;
+		}
+		scb_or_sram_attributes
 	'}'
 		{
 			cur_symbol = NULL;
+			scb_or_sram_symbol = NULL;
 		}
 ;
 
+scb_or_sram_attributes:
+	/* NULL definition is okay */
+|	modes
+|	scb_or_sram_reg_list
+|	modes scb_or_sram_reg_list
+;
+
 scb_or_sram_reg_list:
 	reg_definition
 |	scb_or_sram_reg_list reg_definition
@@ -619,11 +824,11 @@
 	}
 |	T_A
 	{
-		if (accumulator == NULL) {
+		if (accumulator.symbol == NULL) {
 			stop("No accumulator has been defined", EX_DATAERR);
 			/* NOTREACHED */
 		}
-		$$.symbol = accumulator;
+		$$.symbol = accumulator.symbol;
 		$$.offset = 0;
 	}
 ;
@@ -644,6 +849,14 @@
 immediate_or_a:
 	expression
 	{
+		if ($1.value == 0 && is_download_const(&$1) == 0) {
+			snprintf(errbuf, sizeof(errbuf),
+				 "\nExpression evaluates to 0 and thus "
+				 "references the accumulator.\n "
+				 "If this is the desired effect, use 'A' "
+				 "instead.\n");
+			stop(errbuf, EX_DATAERR);
+		}
 		$$ = $1;
 	}
 |	T_A
@@ -676,8 +889,22 @@
 	{ $$ = 1; }
 ;
 
+set_src_mode:
+	T_SET_SRC_MODE T_NUMBER ';'
+	{
+		src_mode = $2;
+	}
+;
+
+set_dst_mode:
+	T_SET_DST_MODE T_NUMBER ';'
+	{
+		dst_mode = $2;
+	}
+;
+
 critical_section_start:
-	T_BEGIN_CS
+	T_BEGIN_CS ';'
 	{
 		critical_section_t *cs;
 
@@ -692,7 +919,7 @@
 	}
 
 critical_section_end:
-	T_END_CS
+	T_END_CS ';'
 	{
 		critical_section_t *cs;
 
@@ -705,16 +932,23 @@
 		in_critical_section = FALSE;
 	}
 
+export:
+	{ $$ = 0; }
+|	T_EXPORT
+	{ $$ = 1; }
+;
+
 label:
-	T_SYMBOL ':'
+	export T_SYMBOL ':'
 	{
-		if ($1->type != UNINITIALIZED) {
+		if ($2->type != UNINITIALIZED) {
 			stop("Program label multiply defined", EX_DATAERR);
 			/* NOTREACHED */
 		}
-		$1->type = LABEL;
-		initialize_symbol($1);
-		$1->info.linfo->address = instruction_ptr;
+		$2->type = LABEL;
+		initialize_symbol($2);
+		$2->info.linfo->address = instruction_ptr;
+		$2->info.linfo->exported = $1;
 	}
 ;
 
@@ -1128,6 +1362,16 @@
 		}
 		memset(symbol->info.rinfo, 0,
 		       sizeof(struct reg_info));
+		/*
+		 * Default to allowing access in all register modes
+		 * or to the mode specified by the SCB or SRAM space
+		 * we are in.
+		 */
+		if (scb_or_sram_symbol != NULL)
+			symbol->info.rinfo->modes =
+			    scb_or_sram_symbol->info.rinfo->modes;
+		else
+			symbol->info.rinfo->modes = ~0;
 		break;
         case ALIAS:
 		symbol->info.ainfo =
@@ -1181,6 +1425,17 @@
 		memset(symbol->info.condinfo, 0,
 		       sizeof(struct cond_info));
 		break;
+	case MACRO:
+		symbol->info.macroinfo = 
+		    (struct macro_info *)malloc(sizeof(struct macro_info));
+		if (symbol->info.macroinfo == NULL) {
+			stop("Can't create macro info", EX_SOFTWARE);
+			/* NOTREACHED */
+		}
+		memset(symbol->info.macroinfo, 0,
+		       sizeof(struct macro_info));
+		STAILQ_INIT(&symbol->info.macroinfo->args);
+		break;
 	default:
 		stop("Call to initialize_symbol with invalid symbol type",
 		     EX_SOFTWARE);
@@ -1190,25 +1445,75 @@
 }
 
 static void
+add_macro_arg(const char *argtext, int argnum)
+{
+	struct macro_arg *marg;
+	int i;
+	int retval;
+		
+
+	if (cur_symbol == NULL || cur_symbol->type != MACRO) {
+		stop("Invalid current symbol for adding macro arg",
+		     EX_SOFTWARE);
+		/* NOTREACHED */
+	}
+
+	marg = (struct macro_arg *)malloc(sizeof(*marg));
+	if (marg == NULL) {
+		stop("Can't create macro_arg structure", EX_SOFTWARE);
+		/* NOTREACHED */
+	}
+	marg->replacement_text = NULL;
+	retval = snprintf(regex_pattern, sizeof(regex_pattern),
+			  "[^-/A-Za-z0-9_](%s)([^-/A-Za-z0-9_]|$)",
+			  argtext);
+	if (retval >= sizeof(regex_pattern)) {
+		stop("Regex text buffer too small for arg",
+		     EX_SOFTWARE);
+		/* NOTREACHED */
+	}
+	retval = regcomp(&marg->arg_regex, regex_pattern, REG_EXTENDED);
+	if (retval != 0) {
+		stop("Regex compilation failed", EX_SOFTWARE);
+		/* NOTREACHED */
+	}
+	STAILQ_INSERT_TAIL(&cur_symbol->info.macroinfo->args, marg, links);
+}
+
+static void
+add_macro_body(const char *bodytext)
+{
+	if (cur_symbol == NULL || cur_symbol->type != MACRO) {
+		stop("Invalid current symbol for adding macro arg",
+		     EX_SOFTWARE);
+		/* NOTREACHED */
+	}
+	cur_symbol->info.macroinfo->body = strdup(bodytext);
+	if (cur_symbol->info.macroinfo->body == NULL) {
+		stop("Can't duplicate macro body text", EX_SOFTWARE);
+		/* NOTREACHED */
+	}
+}
+
+static void
 process_register(symbol_t **p_symbol)
 {
-	char buf[255];
 	symbol_t *symbol = *p_symbol;
 
 	if (symbol->type == UNINITIALIZED) {
-		snprintf(buf, sizeof(buf), "Undefined register %s",
+		snprintf(errbuf, sizeof(errbuf), "Undefined register %s",
 			 symbol->name);
-		stop(buf, EX_DATAERR);
+		stop(errbuf, EX_DATAERR);
 		/* NOTREACHED */
 	} else if (symbol->type == ALIAS) {
 		*p_symbol = symbol->info.ainfo->parent;
 	} else if ((symbol->type != REGISTER)
 		&& (symbol->type != SCBLOC)
 		&& (symbol->type != SRAMLOC)) {
-		snprintf(buf, sizeof(buf),
+		snprintf(errbuf, sizeof(errbuf),
 			 "Specified symbol %s is not a register",
 			 symbol->name);
-		stop(buf, EX_DATAERR);
+		stop(errbuf, EX_DATAERR);
 	}
 }
 
@@ -1242,6 +1547,47 @@
 
 	if (is_download_const(immed))
 		f1_instr->parity = 1;
+	else if (dest->symbol == mode_ptr.symbol) {
+		u_int src_value;
+		u_int dst_value;
+
+		/*
+		 * Attempt to update mode information if
+		 * we are operating on the mode register.
+		 */
+		if (src->symbol == allones.symbol)
+			src_value = 0xFF;
+		else if (src->symbol == allzeros.symbol)
+			src_value = 0;
+		else if (src->symbol == mode_ptr.symbol)
+			src_value = (dst_mode << 4) | src_mode;
+		else
+			goto cant_update;
+
+		switch (opcode) {
+		case AIC_OP_AND:
+			dst_value = src_value & immed->value;
+			break;
+		case AIC_OP_XOR:
+			dst_value = src_value ^ immed->value;
+			break;
+		case AIC_OP_ADD:
+			dst_value = (src_value + immed->value) & 0xFF;
+			break;
+		case AIC_OP_OR:
+			dst_value = src_value | immed->value;
+			break;
+			break;
+		case AIC_OP_BMOV:
+			dst_value = src_value;
+			break;
+		default:
+			goto cant_update;
+		}
+		src_mode = dst_value & 0xF;
+		dst_mode = (dst_value >> 4) & 0xF;
+cant_update:
+	}
 
 	symlist_free(&immed->referenced_syms);
 	instruction_ptr++;
@@ -1350,6 +1696,14 @@
 static void
 test_readable_symbol(symbol_t *symbol)
 {
+	
+	if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) {
+		snprintf(errbuf, sizeof(errbuf),
+			"Register %s unavailable in source reg mode %d",
+			symbol->name, src_mode);
+		stop(errbuf, EX_DATAERR);
+	}
+
 	if (symbol->info.rinfo->mode == WO) {
 		stop("Write Only register specified as source",
 		     EX_DATAERR);
@@ -1360,6 +1714,14 @@
 static void
 test_writable_symbol(symbol_t *symbol)
 {
+	
+	if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) {
+		snprintf(errbuf, sizeof(errbuf),
+			"Register %s unavailable in destination reg mode %d",
+			symbol->name, dst_mode);
+		stop(errbuf, EX_DATAERR);
+	}
+
 	if (symbol->info.rinfo->mode == RO) {
 		stop("Read Only register specified as destination",
 		     EX_DATAERR);
@@ -1372,7 +1734,6 @@
 {
 	symbol_node_t *node;
 	int and_op;
-	char buf[255];
 
 	and_op = FALSE;
 	if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ)
@@ -1385,11 +1746,11 @@
 	 */
 	if (and_op == FALSE
 	 && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) {
-		snprintf(buf, sizeof(buf),
+		snprintf(errbuf, sizeof(errbuf),
 			 "Invalid bit(s) 0x%x in immediate written to %s",
 			 expression->value & ~symbol->info.rinfo->valid_bitmask,
 			 symbol->name);
-		stop(buf, EX_DATAERR);
+		stop(errbuf, EX_DATAERR);
 		/* NOTREACHED */
 	}
 
@@ -1397,7 +1758,7 @@
 	 * Now make sure that all of the symbols referenced by the
 	 * expression are defined for this register.
 	 */
-	if(symbol->info.rinfo->typecheck_masks != FALSE) {
+	if (symbol->info.rinfo->typecheck_masks != FALSE) {
 		for(node = expression->referenced_syms.slh_first;
 		    node != NULL;
 		    node = node->links.sle_next) {
@@ -1405,11 +1766,11 @@
 			  || node->symbol->type == BIT)
 			 && symlist_search(&node->symbol->info.minfo->symrefs,
 					   symbol->name) == NULL) {
-				snprintf(buf, sizeof(buf),
+				snprintf(errbuf, sizeof(errbuf),
 					 "Invalid bit or mask %s "
 					 "for register %s",
 					 node->symbol->name, symbol->name);
-				stop(buf, EX_DATAERR);
+				stop(errbuf, EX_DATAERR);
 				/* NOTREACHED */
 			}
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h	2002-07-20 01:08:40.000000000 +0000
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#7 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#8 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_insformat.h,v 1.3 2000/09/22 22:19:54 gibbs Exp $
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y linux/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,164 @@
+%{
+/*
+ * Sub-parser for macro invocation in the Aic7xxx SCSI
+ * Host adapter sequencer assembler.
+ *
+ * Copyright (c) 2001 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $Id$
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+
+#include <inttypes.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+
+#ifdef __linux__
+#include "../queue.h"
+#else
+#include <sys/queue.h>
+#endif
+
+#include "aicasm.h"
+#include "aicasm_symbol.h"
+#include "aicasm_insformat.h"
+
+static symbol_t *macro_symbol;
+
+static void add_macro_arg(const char *argtext, int position);
+
+%}
+
+%union {
+	int		value;
+	char		*str;
+	symbol_t	*sym;
+}
+
+
+%token <str> T_ARG
+
+%token <sym> T_SYMBOL
+
+%type <value> macro_arglist
+
+%%
+
+macrocall:
+	T_SYMBOL '('
+	{
+		macro_symbol = $1;
+	}
+	macro_arglist ')'
+	{
+		if (macro_symbol->info.macroinfo->narg != $4) {
+			printf("Narg == %d", macro_symbol->info.macroinfo->narg);
+			stop("Too few arguments for macro invocation",
+			     EX_DATAERR);
+			/* NOTREACHED */
+		}
+		macro_symbol = NULL;
+		YYACCEPT;
+	}
+;
+
+macro_arglist:
+	{
+		/* Macros can take 0 arguments */
+		$$ = 0;
+	}
+|	T_ARG
+	{
+		$$ = 1;
+		add_macro_arg($1, 1);
+	}
+|	macro_arglist ',' T_ARG
+	{
+		if ($1 == 0) {
+			stop("Comma without preceeding argument in arg list",
+			     EX_DATAERR);
+			/* NOTREACHED */
+		}
+		$$ = $1 + 1;
+		add_macro_arg($3, $$);
+	}
+;
+
+%%
+
+static void
+add_macro_arg(const char *argtext, int argnum)
+{
+	struct macro_arg *marg;
+	int i;
+
+	if (macro_symbol == NULL || macro_symbol->type != MACRO) {
+		stop("Invalid current symbol for adding macro arg",
+		     EX_SOFTWARE);
+		/* NOTREACHED */
+	}
+	/*
+	 * Macro Invocation.  Find the appropriate argument and fill
+	 * in the replace ment text for this call.
+	 */
+	i = 0;
+	STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
+		i++;
+		if (i == argnum)
+			break;
+	}
+	if (marg == NULL) {
+		stop("Too many arguments for macro invocation", EX_DATAERR);
+		/* NOTREACHED */
+	}
+	marg->replacement_text = strdup(argtext);
+	if (marg->replacement_text == NULL) {
+		stop("Unable to replicate replacement text", EX_SOFTWARE);
+		/* NOTREACHED */
+	}
+}
+
+void
+mmerror(const char *string)
+{
+	stop(string, EX_DATAERR);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l linux/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,154 @@
+%{
+/*
+ * Sub-Lexical Analyzer for macro invokation in 
+ * the Aic7xxx SCSI Host adapter sequencer assembler.
+ *
+ * Copyright (c) 2001 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $Id$
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <regex.h>
+#include <stdio.h>
+#include <string.h>
+#include <sysexits.h>
+#ifdef __linux__
+#include "../queue.h"
+#else
+#include <sys/queue.h>
+#endif
+
+#include "aicasm.h"
+#include "aicasm_symbol.h"
+#include "aicasm_macro_gram.h"
+
+#define MAX_STR_CONST 4096
+static char string_buf[MAX_STR_CONST];
+static char *string_buf_ptr;
+static int  parren_count;
+static char buf[255];
+%}
+
+WORD		[A-Za-z_][-A-Za-z_0-9]*
+SPACE		[ \t]+
+MCARG		[^(), \t]+
+
+%x ARGLIST
+
+%%
+\n			{
+				++yylineno;
+			}
+<ARGLIST>{SPACE}	;
+<ARGLIST>\(		{
+				parren_count++;
+				if (parren_count == 1) {
+					string_buf_ptr = string_buf;
+					return ('(');
+				}
+				*string_buf_ptr++ = '(';
+			}
+<ARGLIST>\)		{
+				if (parren_count == 1) {
+					if (string_buf_ptr != string_buf) {
+						/*
+						 * Return an argument and
+						 * rescan this parren so we
+						 * can return it as well.
+						 */
+						*string_buf_ptr = '\0';
+						mmlval.str = string_buf;
+						string_buf_ptr = string_buf;
+						unput(')');
+						return T_ARG;
+					}
+					BEGIN INITIAL;
+					return (')');
+				}
+				parren_count--;
+				*string_buf_ptr++ = ')';
+			}
+<ARGLIST>{MCARG}	{
+				char *yptr;
+
+				yptr = mmtext;
+				while (*yptr)
+					*string_buf_ptr++ = *yptr++;
+			}
+<ARGLIST>\,		{
+				if (string_buf_ptr != string_buf) {
+					/*
+					 * Return an argument and
+					 * rescan this comma so we
+					 * can return it as well.
+					 */
+					*string_buf_ptr = '\0';
+					mmlval.str = string_buf;
+					string_buf_ptr = string_buf;
+					unput(',');
+					return T_ARG;
+				}
+				return ',';
+			}
+{WORD}[(]		{
+				/* May be a symbol or a macro invocation. */
+				mmlval.sym = symtable_get(mmtext);
+				if (mmlval.sym->type != MACRO) {
+					stop("Expecting Macro Name",
+					     EX_DATAERR);
+				}
+				unput('(');
+				parren_count = 0;
+				BEGIN ARGLIST;
+				return T_SYMBOL;
+			}
+.			{ 
+				snprintf(buf, sizeof(buf), "Invalid character "
+					 "'%c'", mmtext[0]);
+				stop(buf, EX_DATAERR);
+			}
+%%
+
+int
+mmwrap()
+{
+	stop("EOF encountered in macro call", EX_DATAERR);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l linux/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l	2002-07-20 01:08:29.000000000 +0000
@@ -38,14 +38,15 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#7 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#10 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_scan.l,v 1.13 2000/09/22 22:19:54 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_scan.l,v 1.13.2.3 2001/07/28 18:46:44 gibbs Exp $
  */
 
 #include <sys/types.h>
 
 #include <limits.h>
+#include <regex.h>
 #include <stdio.h>
 #include <string.h>
 #include <sysexits.h>
@@ -57,23 +58,31 @@
 
 #include "aicasm.h"
 #include "aicasm_symbol.h"
-#include "y.tab.h"
+#include "aicasm_gram.h"
 
-#define MAX_STR_CONST 256
-char string_buf[MAX_STR_CONST];
-char *string_buf_ptr;
-int  parren_count;
-int  quote_count;
+/* This is used for macro body capture too, so err on the large size. */
+#define MAX_STR_CONST 4096
+static char string_buf[MAX_STR_CONST];
+static char *string_buf_ptr;
+static int  parren_count;
+static int  quote_count;
+static char buf[255];
 %}
 
-PATH		[-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]*
+PATH		([/]*[-A-Za-z0-9_.])+
 WORD		[A-Za-z_][-A-Za-z_0-9]*
 SPACE		[ \t]+
+MCARG		[^(), \t]+
+MBODY		((\\[^\n])*[^\n\\]*)+
 
 %x COMMENT
 %x CEXPR
 %x INCLUDE
 %x STRING
+%x MACRODEF
+%x MACROARGLIST
+%x MACROCALLARGS
+%x MACROBODY
 
 %%
 \n			{ ++yylineno; }
@@ -122,6 +131,7 @@
 			}
 
 VERSION			{ return T_VERSION; }
+PATCH_ARG_LIST		{ return T_PATCH_ARG_LIST; }
 \"			{
 				string_buf_ptr = string_buf;
 				BEGIN STRING;
@@ -140,14 +150,16 @@
 				yylval.str = string_buf;
 				return T_STRING;
 			}
-{SPACE}			;
+{SPACE}			 ;
 
 	/* Register/SCB/SRAM definition keywords */
+export			{ return T_EXPORT; }
 register		{ return T_REGISTER; }
 const			{ yylval.value = FALSE; return T_CONST; }
 download		{ return T_DOWNLOAD; }
 address			{ return T_ADDRESS; }
 access_mode		{ return T_ACCESS_MODE; }
+modes			{ return T_MODES; }
 RW|RO|WO		{
 				 if (strcmp(yytext, "RW") == 0)
 					yylval.value = RW;
@@ -159,6 +171,8 @@
 			}
 BEGIN_CRITICAL		{ return T_BEGIN_CS; }
 END_CRITICAL		{ return T_END_CS; }
+SET_SRC_MODE		{ return T_SET_SRC_MODE; }
+SET_DST_MODE		{ return T_SET_DST_MODE; }
 bit			{ return T_BIT; }
 mask			{ return T_MASK; }
 alias			{ return T_ALIAS; }
@@ -166,6 +180,7 @@
 scb			{ return T_SCB; }
 scratch_ram		{ return T_SRAM; }
 accumulator		{ return T_ACCUM; }
+mode_pointer		{ return T_MODE_PTR; }
 allones			{ return T_ALLONES; }
 allzeros		{ return T_ALLZEROS; }
 none			{ return T_NONE; }
@@ -206,7 +221,9 @@
 else			{ return T_ELSE; }
 
 	/* Allowed Symbols */
-[-+,:()~|&."{};<>[\]!=]	{ return yytext[0]; }
+\<\<			{ return T_EXPR_LSHIFT; }
+\>\>			{ return T_EXPR_RSHIFT; }
+[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; }
 
 	/* Number processing */
 0[0-7]*			{
@@ -223,7 +240,6 @@
 				yylval.value = strtol(yytext, NULL, 10);
 				return T_NUMBER;
 			}
-
 	/* Include Files */
 #include{SPACE}		{
 				BEGIN INCLUDE;
@@ -238,13 +254,7 @@
 				quote_count++;
 				return yytext[0];
 			}
-<INCLUDE>.		{ stop("Invalid include line", EX_DATAERR); }
-
-	/* For parsing C include files with #define foo */
-#define			{ yylval.value = TRUE; return T_CONST; }
-	/* Throw away macros */
-#define[^\n]*[()]+[^\n]* ;
-<INITIAL,INCLUDE>{PATH}	{
+<INCLUDE>{PATH}		{
 				char *yptr;
 
 				yptr = yytext;
@@ -255,12 +265,158 @@
 				*string_buf_ptr = '\0';
 				return T_PATH;
 			}
+<INCLUDE>.		{ stop("Invalid include line", EX_DATAERR); }
+#define{SPACE}		{
+				BEGIN MACRODEF;
+				return T_DEFINE;
+			}
+<MACRODEF>{WORD}{SPACE}	{ 
+				char *yptr;
 
-{WORD}			{ yylval.sym = symtable_get(yytext);  return T_SYMBOL; }
+				/* Strip space and return as a normal symbol */
+				yptr = yytext;
+				while (*yptr != ' ' && *yptr != '\t')
+					yptr++;
+				*yptr = '\0';
+				yylval.sym = symtable_get(yytext);
+				string_buf_ptr = string_buf;
+				BEGIN MACROBODY;
+				return T_SYMBOL;
+			}
+<MACRODEF>{WORD}\(	{
+				/*
+				 * We store the symbol with its opening
+				 * parren so we can differentiate macros
+				 * that take args from macros with the
+				 * same name that do not take args as
+				 * is allowed in C.
+				 */
+				BEGIN MACROARGLIST;
+				yylval.sym = symtable_get(yytext);
+				unput('(');
+				return T_SYMBOL;
+			}
+<MACROARGLIST>{WORD}	{
+				yylval.str = yytext;
+				return T_ARG;
+			}
+<MACROARGLIST>{SPACE}   ;
+<MACROARGLIST>[(,]	{
+				return yytext[0];
+			}
+<MACROARGLIST>[)]	{
+				string_buf_ptr = string_buf;
+				BEGIN MACROBODY;
+				return ')';
+			}
+<MACROARGLIST>.		{
+				snprintf(buf, sizeof(buf), "Invalid character "
+					 "'%c' in macro argument list",
+					 yytext[0]);
+				stop(buf, EX_DATAERR);
+			}
+<MACROCALLARGS>{SPACE}  ;
+<MACROCALLARGS>\(	{
+				parren_count++;
+				if (parren_count == 1)
+					return ('(');
+				*string_buf_ptr++ = '(';
+			}
+<MACROCALLARGS>\)	{
+				parren_count--;
+				if (parren_count == 0) {
+					BEGIN INITIAL;
+					return (')');
+				}
+				*string_buf_ptr++ = ')';
+			}
+<MACROCALLARGS>{MCARG}	{
+				char *yptr;
 
-.			{ 
-				char buf[255];
+				yptr = yytext;
+				while (*yptr)
+					*string_buf_ptr++ = *yptr++;
+			}
+<MACROCALLARGS>\,	{
+				if (string_buf_ptr != string_buf) {
+					/*
+					 * Return an argument and
+					 * rescan this comma so we
+					 * can return it as well.
+					 */
+					*string_buf_ptr = '\0';
+					yylval.str = string_buf;
+					string_buf_ptr = string_buf;
+					unput(',');
+					return T_ARG;
+				}
+				return ',';
+			}
+<MACROBODY>\\\n		{
+				/* Eat escaped newlines. */
+				++yylineno;
+			}
+<MACROBODY>\n		{
+				/* Macros end on the first unescaped newline. */
+				BEGIN INITIAL;
+				*string_buf_ptr = '\0';
+				yylval.str = string_buf;
+				++yylineno;
+				return T_MACROBODY;
+			}
+<MACROBODY>{MBODY}	{
+				char *yptr;
 
+				yptr = yytext;
+				while (*yptr)
+					*string_buf_ptr++ = *yptr++;
+			}
+{WORD}\(		{
+				char *yptr;
+				char *ycopy;
+
+				/* May be a symbol or a macro invocation. */
+				yylval.sym = symtable_get(yytext);
+				if (yylval.sym->type == MACRO) {
+					YY_BUFFER_STATE old_state;
+					YY_BUFFER_STATE temp_state;
+
+					ycopy = strdup(yytext);
+					yptr = ycopy + yyleng;
+					while (yptr > ycopy)
+						unput(*--yptr);
+					old_state = YY_CURRENT_BUFFER;
+					temp_state =
+					    yy_create_buffer(stdin,
+							     YY_BUF_SIZE);
+					yy_switch_to_buffer(temp_state);
+					mm_switch_to_buffer(old_state);
+					mmparse();
+					mm_switch_to_buffer(temp_state);
+					yy_switch_to_buffer(old_state);
+					mm_delete_buffer(temp_state);
+					expand_macro(yylval.sym);
+				} else {
+					if (yylval.sym->type == UNINITIALIZED) {
+						/* Try without the '(' */
+						symbol_delete(yylval.sym);
+						yytext[yyleng-1] = '\0';
+						yylval.sym =
+						    symtable_get(yytext);
+					}
+					unput('(');
+					return T_SYMBOL;
+				}
+			}
+{WORD}			{
+				yylval.sym = symtable_get(yytext);
+				if (yylval.sym->type == MACRO) {
+					expand_macro(yylval.sym);
+				} else {
+					return T_SYMBOL;
+				}
+			}
+.			{ 
 				snprintf(buf, sizeof(buf), "Invalid character "
 					 "'%c'", yytext[0]);
 				stop(buf, EX_DATAERR);
@@ -329,6 +485,92 @@
 	yyfilename = strdup(file_name);
 }
 
+static void next_substitution(struct symbol *mac_symbol, const char *body_pos,
+			      const char **next_match,
+			      struct macro_arg **match_marg, regmatch_t *match);
+
+void
+expand_macro(struct symbol *macro_symbol)
+{
+	struct macro_arg *marg;
+	struct macro_arg *match_marg;
+	const char *body_head;
+	const char *body_pos;
+	const char *next_match;
+
+	/*
+	 * Due to the nature of unput, we must work
+	 * backwards through the macro body performing
+	 * any expansions.
+	 */
+	body_head = macro_symbol->info.macroinfo->body;
+	body_pos = body_head + strlen(body_head);
+	while (body_pos > body_head) {
+		regmatch_t match;
+
+		next_match = body_head;
+		match_marg = NULL;
+		next_substitution(macro_symbol, body_pos, &next_match,
+				  &match_marg, &match);
+
+		/* Put back everything up until the replacement. */
+		while (body_pos > next_match)
+			unput(*--body_pos);
+
+		/* Perform the replacement. */
+		if (match_marg != NULL) {
+			const char *strp;
+
+			next_match = match_marg->replacement_text;
+			strp = next_match + strlen(next_match);
+			while (strp > next_match)
+				unput(*--strp);
+
+			/* Skip past the unexpanded macro arg. */
+			body_pos -= match.rm_eo - match.rm_so;
+		}
+	}
+
+	/* Cleanup replacement text. */
+	STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
+		free(marg->replacement_text);
+	}
+}
+
+/*
+ * Find the next substitution in the macro working backwards from
+ * body_pos until the beginning of the macro buffer.  next_match
+ * should be initialized to the beginning of the macro buffer prior
+ * to calling this routine.
+ */
+static void
+next_substitution(struct symbol *mac_symbol, const char *body_pos,
+		  const char **next_match, struct macro_arg **match_marg,
+		  regmatch_t *match)
+{
+	regmatch_t	  matches[2];
+	struct macro_arg *marg;
+	const char	 *search_pos;
+	int		  retval;
+
+	do {
+		search_pos = *next_match;
+
+		STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) {
+
+			retval = regexec(&marg->arg_regex, search_pos, 2,
+					 matches, 0);
+			if (retval == 0
+			 && (matches[1].rm_eo + search_pos) <= body_pos
+			 && (matches[1].rm_eo + search_pos) > *next_match) {
+				*match = matches[1];
+				*next_match = match->rm_eo + search_pos;
+				*match_marg = marg;
+			}
+		}
+	} while (search_pos != *next_match);
+}
+
 int
 yywrap()
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c	2002-07-20 01:08:35.000000000 +0000
@@ -36,7 +36,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#9 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#13 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.c,v 1.11 2000/09/22 22:19:54 gibbs Exp $
  */
@@ -49,6 +49,7 @@
 #include <db.h>
 #endif
 #include <fcntl.h>
+#include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -318,12 +319,15 @@
 	symlist_t constants;
 	symlist_t download_constants;
 	symlist_t aliases;
+	symlist_t exported_labels;
+	u_int	  i;
 
 	SLIST_INIT(&registers);
 	SLIST_INIT(&masks);
 	SLIST_INIT(&constants);
 	SLIST_INIT(&download_constants);
 	SLIST_INIT(&aliases);
+	SLIST_INIT(&exported_labels);
 
 	if (symtable != NULL) {
 		DBT	 key;
@@ -345,10 +349,8 @@
 				symlist_add(&masks, cursym, SYMLIST_SORT);
 				break;
 			case CONST:
-				if (cursym->info.cinfo->define == FALSE) {
-					symlist_add(&constants, cursym,
-						    SYMLIST_INSERT_HEAD);
-				}
+				symlist_add(&constants, cursym,
+					    SYMLIST_INSERT_HEAD);
 				break;
 			case DOWNLOAD_CONST:
 				symlist_add(&download_constants, cursym,
@@ -358,6 +360,12 @@
 				symlist_add(&aliases, cursym,
 					    SYMLIST_INSERT_HEAD);
 				break;
+			case LABEL:
+				if (cursym->info.linfo->exported == 0)
+					break;
+				symlist_add(&exported_labels, cursym,
+					    SYMLIST_INSERT_HEAD);
+				break;
 			default:
 				break;
 			}
@@ -403,7 +411,7 @@
 %s */\n", versions);
 		while (SLIST_FIRST(&registers) != NULL) {
 			symbol_node_t *curnode;
-			u_int8_t value;
+			u_int value;
 			char *tab_str;
 			char *tab_str2;
 
@@ -463,7 +471,7 @@
 		
 		fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
 
-		while (SLIST_FIRST(&download_constants) != NULL) {
+		for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
 			symbol_node_t *curnode;
 
 			curnode = SLIST_FIRST(&download_constants);
@@ -473,6 +481,20 @@
 				curnode->symbol->info.cinfo->value);
 			free(curnode);
 		}
+		fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i);
+
+		fprintf(ofile, "\n\n/* Exported Labels */\n");
+
+		while (SLIST_FIRST(&exported_labels) != NULL) {
+			symbol_node_t *curnode;
+
+			curnode = SLIST_FIRST(&exported_labels);
+			SLIST_REMOVE_HEAD(&exported_labels, links);
+			fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n",
+				curnode->symbol->name,
+				curnode->symbol->info.linfo->address);
+			free(curnode);
+		}
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
--- linux.orig/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h	2002-07-20 01:08:26.000000000 +0000
@@ -36,7 +36,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#6 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#10 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.h,v 1.11 2000/09/22 22:19:55 gibbs Exp $
  */
@@ -58,8 +58,9 @@
 	CONST,
 	DOWNLOAD_CONST,
 	LABEL,
-	CONDITIONAL
-}symtype;
+	CONDITIONAL,
+	MACRO
+} symtype;
 
 typedef enum {
 	RO = 0x01,
@@ -68,10 +69,11 @@
 }amode_t;
 
 struct reg_info {
-	u_int8_t address;
+	u_int	 address;
 	int	 size;
 	amode_t	 mode;
 	u_int8_t valid_bitmask;
+	u_int8_t modes;
 	int	 typecheck_masks;
 };
 
@@ -83,8 +85,8 @@
 };
 
 struct const_info {
-	u_int8_t value;
-	int	 define;
+	u_int	value;
+	int	define;
 };
 
 struct alias_info {
@@ -93,12 +95,26 @@
 
 struct label_info {
 	int	address;
+	int	exported;
 };
 
 struct cond_info {
 	int	func_num;
 };
 
+struct macro_arg {
+	STAILQ_ENTRY(macro_arg)	links;
+	regex_t	arg_regex;
+	char   *replacement_text;
+};
+STAILQ_HEAD(macro_arg_list, macro_arg) args;
+
+struct macro_info {
+	struct macro_arg_list args;
+	int   narg;
+	const char* body;
+};
+
 typedef struct expression_info {
         symlist_t       referenced_syms;
         int             value;
@@ -108,12 +124,13 @@
 	char	*name;
 	symtype	type;
 	union	{
-		struct reg_info *rinfo;
-		struct mask_info *minfo;
+		struct reg_info	  *rinfo;
+		struct mask_info  *minfo;
 		struct const_info *cinfo;
 		struct alias_info *ainfo;
 		struct label_info *linfo;
-		struct cond_info *condinfo;
+		struct cond_info  *condinfo;
+		struct macro_info *macroinfo;
 	}info;
 } symbol_t;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/aic7xxx/scsi_message.h linux/drivers/scsi/aic7xxx/scsi_message.h
--- linux.orig/drivers/scsi/aic7xxx/scsi_message.h	2001-03-04 22:30:18.000000000 +0000
+++ linux/drivers/scsi/aic7xxx/scsi_message.h	2002-07-20 01:08:27.000000000 +0000
@@ -46,7 +46,7 @@
 #define MSG_IDENTIFY_DISCFLAG	0x40 
 #define MSG_IDENTIFY(lun, disc)	(((disc) ? 0xc0 : MSG_IDENTIFYFLAG) | (lun))
 #define MSG_ISIDENTIFY(m)	((m) & MSG_IDENTIFYFLAG)
-#define MSG_IDENTIFY_LUNMASK	0x03F 
+#define MSG_IDENTIFY_LUNMASK	0x3F 
 
 /* Extended messages (opcode and length) */
 #define MSG_EXT_SDTR		0x01
@@ -60,6 +60,11 @@
 
 #define MSG_EXT_PPR		0x04 /* SPI3 */
 #define MSG_EXT_PPR_LEN		0x06
-#define MSG_EXT_PPR_QAS_REQ	0x04
-#define MSG_EXT_PPR_DT_REQ	0x02
+#define	MSG_EXT_PPR_PCOMP_EN	0x80
+#define	MSG_EXT_PPR_RTI		0x40
+#define	MSG_EXT_PPR_RD_STRM	0x20
+#define	MSG_EXT_PPR_WR_FLOW	0x10
+#define	MSG_EXT_PPR_HOLD_MCS	0x08
+#define	MSG_EXT_PPR_QAS_REQ	0x04
+#define	MSG_EXT_PPR_DT_REQ	0x02
 #define MSG_EXT_PPR_IU_REQ	0x01
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/atari_NCR5380.c linux/drivers/scsi/atari_NCR5380.c
--- linux.orig/drivers/scsi/atari_NCR5380.c	1999-08-31 18:23:03.000000000 +0000
+++ linux/drivers/scsi/atari_NCR5380.c	2002-07-20 01:08:38.000000000 +0000
@@ -644,10 +644,7 @@
 
 static volatile int main_running = 0;
 static struct tq_struct NCR5380_tqueue = {
-    NULL,		/* next */
-    0,			/* sync */
-    (void (*)(void*))NCR5380_main,  /* routine, must have (void *) arg... */
-    NULL		/* data */
+    routine:	(void (*)(void*))NCR5380_main	/* must have (void *) arg... */
 };
 
 static __inline__ void queue_main(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/atari_scsi.c linux/drivers/scsi/atari_scsi.c
--- linux.orig/drivers/scsi/atari_scsi.c	2001-03-07 03:44:37.000000000 +0000
+++ linux/drivers/scsi/atari_scsi.c	2002-07-20 01:08:36.000000000 +0000
@@ -1144,3 +1144,5 @@
 
 static Scsi_Host_Template driver_template = ATARI_SCSI;
 #include "scsi_module.c"
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/atp870u.c linux/drivers/scsi/atp870u.c
--- linux.orig/drivers/scsi/atp870u.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/scsi/atp870u.c	2002-07-20 01:08:34.000000000 +0000
@@ -11,7 +11,8 @@
  *		   enable 32 bit fifo transfer
  *		   support cdrom & remove device run ultra speed
  *		   fix disconnect bug  2000/12/21
- *		   support atp880 chip lvd u160 2001/05/15 (7.1)
+ *		   support atp880 chip lvd u160 2001/05/15
+ *		   fix prd table bug 2001/09/12 (7.1)
  */
 
 #include <linux/module.h>
@@ -803,8 +804,18 @@
 		sgpnt = (struct scatterlist *) workrequ->request_buffer;
 		i = 0;
 		for (j = 0; j < workrequ->use_sg; j++) {
-			(unsigned long) (((unsigned long *) (prd))[i >> 1]) = virt_to_bus(sgpnt[j].address);
-			(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = sgpnt[j].length;
+			bttl = virt_to_bus(sgpnt[j].address);
+			l = sgpnt[j].length;
+			while (l > 0x10000) {
+				(unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x0000;
+				(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = 0x0000;
+				(unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
+				l -= 0x10000;
+				bttl += 0x10000;
+				i += 0x04;
+			}
+			(unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
+			(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = l;
 			(unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0;
 			i += 0x04;
 		}
@@ -2527,7 +2538,7 @@
 		   host_id = inb(base_io + 0x39);
 		   host_id >>= 0x04;
 
-		   printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra160 LVD/SE SCSI Adapter: %d    IO:%x, IRQ:%d.\n"
+		   printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d    IO:%x, IRQ:%d.\n"
 			  ,h, base_io, irq);
 		   dev->ioport = base_io + 0x40;
 		   dev->pciport = base_io + 0x28;
@@ -2764,7 +2775,7 @@
 {
 	static char buffer[128];
 
-	strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.5+ac ");
+	strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
 
 	return buffer;
 }
@@ -2809,7 +2820,7 @@
 	if (offset == 0) {
 		memset(buff, 0, sizeof(buff));
 	}
-	size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.5+ac\n");
+	size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
 	len += size;
 	pos = begin + len;
 	size = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/blz1230.c linux/drivers/scsi/blz1230.c
--- linux.orig/drivers/scsi/blz1230.c	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/blz1230.c	2002-07-20 01:08:26.000000000 +0000
@@ -296,3 +296,5 @@
 #endif
 	return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/blz2060.c linux/drivers/scsi/blz2060.c
--- linux.orig/drivers/scsi/blz2060.c	2001-10-25 20:53:49.000000000 +0000
+++ linux/drivers/scsi/blz2060.c	2002-07-20 01:08:35.000000000 +0000
@@ -254,3 +254,5 @@
 #endif
 	return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/cpqfcTSstructs.h linux/drivers/scsi/cpqfcTSstructs.h
--- linux.orig/drivers/scsi/cpqfcTSstructs.h	2001-10-25 20:53:50.000000000 +0000
+++ linux/drivers/scsi/cpqfcTSstructs.h	2002-07-20 01:08:34.000000000 +0000
@@ -27,7 +27,7 @@
 
 #define DbgDelay(secs) { int wait_time; printk( " DbgDelay %ds ", secs); \
                          for( wait_time=jiffies + (secs*HZ); \
-		         wait_time > jiffies ;) ; }
+		         time_before(jiffies, wait_time) ;) ; }
 
 #define CPQFCTS_DRIVER_VER(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 // don't forget to also change MODULE_DESCRIPTION in cpqfcTSinit.c
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/cyberstorm.c linux/drivers/scsi/cyberstorm.c
--- linux.orig/drivers/scsi/cyberstorm.c	2001-10-25 20:53:50.000000000 +0000
+++ linux/drivers/scsi/cyberstorm.c	2002-07-20 01:08:29.000000000 +0000
@@ -320,3 +320,5 @@
 #endif
 	return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/cyberstormII.c linux/drivers/scsi/cyberstormII.c
--- linux.orig/drivers/scsi/cyberstormII.c	2001-10-25 20:53:50.000000000 +0000
+++ linux/drivers/scsi/cyberstormII.c	2002-07-20 01:08:30.000000000 +0000
@@ -271,3 +271,5 @@
 #endif
 	return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- linux.orig/drivers/scsi/eata.c	2001-11-09 22:05:06.000000000 +0000
+++ linux/drivers/scsi/eata.c	2002-07-20 01:08:31.000000000 +0000
@@ -1,6 +1,9 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      01 Jan 2002 Rev. 6.50 for linux 2.4.16
+ *        + Use the dynamic DMA mapping API.
+ *
  *       1 May 2001 Rev. 6.05 for linux 2.4.4
  *        + Clean up all pci related routines.
  *        + Fix data transfer direction for opcode SEND_CUE_SHEET (0x5d)
@@ -220,7 +223,7 @@
  *          This driver is based on the CAM (Common Access Method Committee)
  *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
  *
- *  Copyright (C) 1994-2001 Dario Ballabio (ballabio_dario@emc.com)
+ *  Copyright (C) 1994-2002 Dario Ballabio (ballabio_dario@emc.com)
  *
  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
@@ -438,13 +441,6 @@
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 
-#define SPIN_FLAGS unsigned long spin_flags;
-#define SPIN_LOCK spin_lock_irq(&io_request_lock);
-#define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags);
-#define SPIN_UNLOCK spin_unlock_irq(&io_request_lock);
-#define SPIN_UNLOCK_RESTORE \
-                  spin_unlock_irqrestore(&io_request_lock, spin_flags);
-
 /* Subversion values */
 #define ISA  0
 #define ESA 1
@@ -638,7 +634,7 @@
    u_int32_t data_len;   /* If sg=0 Data Length, if sg=1 sglist length */
    u_int32_t cpp_index;  /* Index of address to be returned in sp */
    u_int32_t data_address; /* If sg=0 Data Address, if sg=1 sglist address */
-   u_int32_t sp_addr;    /* Address where sp is DMA'ed when cp completes */
+   u_int32_t sp_dma_addr;  /* Address where sp is DMA'ed when cp completes */
    u_int32_t sense_addr; /* Address where Sense Data is DMA'ed on error */
    /* Additional fields begin here. */
    Scsi_Cmnd *SCpnt;
@@ -660,7 +656,11 @@
    unsigned long last_retried_pid;      /* Pid of last retried command */
    unsigned char subversion;            /* Bus type, either ISA or EISA/PCI */
    unsigned char protocol_rev;          /* EATA 2.0 rev., 'A' or 'B' or 'C' */
-   struct mssp sp[2];                   /* Returned status for this board */
+   unsigned char is_pci;                /* TRUE is bus type is PCI */
+   struct pci_dev *pdev;                /* pdev for PCI bus, NULL otherwise */
+   struct mssp *sp_cpu_addr;            /* cpu addr for DMA buffer sp */
+   dma_addr_t sp_dma_addr;              /* dma handle for DMA buffer sp */
+   struct mssp sp;                      /* Local copy of sp buffer */
    };
 
 static struct Scsi_Host *sh[MAX_BOARDS + 1];
@@ -697,10 +697,11 @@
 #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
 #define BN(board) (HD(board)->board_name)
 
-#define H2DEV(x) htonl(x)
-#define DEV2H(x) H2DEV(x)
+/* Device is Big Endian */
+#define H2DEV(x) cpu_to_be32(x)
+#define DEV2H(x) be32_to_cpu(x)
+
 #define V2DEV(addr) ((addr) ? H2DEV(virt_to_bus((void *)addr)) : 0)
-#define DEV2V(addr) ((addr) ? DEV2H(bus_to_virt((unsigned long)addr)) : 0)
 
 static void do_interrupt_handler(int, void *, struct pt_regs *);
 static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);
@@ -859,7 +860,7 @@
 
 static inline int port_detect \
       (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt) {
-   unsigned char irq, dma_channel, subversion, i;
+   unsigned char irq, dma_channel, subversion, i, is_pci = FALSE;
    unsigned char protocol_rev;
    struct eata_info info;
    char *bus_type, dma_name[16], tag_type;
@@ -911,10 +912,12 @@
 
    if (!setup_done && j > 0 && j <= MAX_PCI) {
       bus_type = "PCI";
+      is_pci = TRUE;
       subversion = ESA;
       }
    else if (port_base > MAX_EISA_ADDR || (protocol_rev == 'C' && info.pci)) {
       bus_type = "PCI";
+      is_pci = TRUE;
       subversion = ESA;
       }
    else if (port_base >= MIN_EISA_ADDR || (protocol_rev == 'C' && info.eisa)) {
@@ -927,6 +930,7 @@
       }
    else if (port_base > MAX_ISA_ADDR) {
       bus_type = "PCI";
+      is_pci = TRUE;
       subversion = ESA;
       }
    else {
@@ -967,7 +971,13 @@
       printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
              name, irq);
 
-   pdev = get_pci_dev(port_base);
+   if (is_pci) {
+      pdev = get_pci_dev(port_base);
+      if (!pdev) 
+         printk("%s: warning, failed to get pci_dev structure.\n", name);
+      }
+   else
+      pdev = NULL;
 
    if (pdev && (irq != pdev->irq)) {
       printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, pdev->irq);
@@ -997,7 +1007,7 @@
 
    /* Set board configuration */
    memset((char *)&config, 0, sizeof(struct eata_config));
-   config.len = (ushort) htons((ushort)510);
+   config.len = (ushort) cpu_to_be16((ushort)510);
    config.ocena = TRUE;
 
    if (do_dma(port_base, (unsigned long)&config, SET_CONFIG_DMA)) {
@@ -1026,14 +1036,16 @@
    sh[j]->n_io_port = REGION_SIZE;
    sh[j]->dma_channel = dma_channel;
    sh[j]->irq = irq;
-   sh[j]->sg_tablesize = (ushort) ntohs(info.scatt_size);
+   sh[j]->sg_tablesize = (ushort) be16_to_cpu(info.scatt_size);
    sh[j]->this_id = (ushort) info.host_addr[3];
-   sh[j]->can_queue = (ushort) ntohs(info.queue_size);
+   sh[j]->can_queue = (ushort) be16_to_cpu(info.queue_size);
    sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
    sh[j]->select_queue_depths = select_queue_depths;
    memset(HD(j), 0, sizeof(struct hostdata));
    HD(j)->subversion = subversion;
    HD(j)->protocol_rev = protocol_rev;
+   HD(j)->is_pci = is_pci;
+   HD(j)->pdev = pdev;
    HD(j)->board_number = j;
 
    if (HD(j)->subversion == ESA)
@@ -1042,14 +1054,14 @@
       unsigned long flags;
       scsi_register_blocked_host(sh[j]);
       sh[j]->unchecked_isa_dma = TRUE;
-      
+
       flags=claim_dma_lock();
       disable_dma(dma_channel);
       clear_dma_ff(dma_channel);
       set_dma_mode(dma_channel, DMA_MODE_CASCADE);
       enable_dma(dma_channel);
       release_dma_lock(flags);
-      
+
       }
 
    strcpy(BN(j), name);
@@ -1098,6 +1110,13 @@
          return FALSE;
          }
 
+   if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev, 
+         sizeof(struct mssp), &HD(j)->sp_dma_addr))) {
+      printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j));
+      eata2x_release(sh[j]);
+      return FALSE;
+      }
+
    if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
        max_queue_depth = MAX_TAGGED_CMD_PER_LUN;
 
@@ -1112,7 +1131,7 @@
    else                                 tag_type = 'n';
 
    if (j == 0) {
-      printk("EATA/DMA 2.0x: Copyright (C) 1994-2001 Dario Ballabio.\n");
+      printk("EATA/DMA 2.0x: Copyright (C) 1994-2002 Dario Ballabio.\n");
       printk("%s config options -> tc:%c, lc:%c, mq:%d, rs:%c, et:%c.\n",
              driver_name, tag_type, YESNO(linked_comm), max_queue_depth,
              YESNO(rev_scan), YESNO(ext_tran));
@@ -1148,7 +1167,11 @@
              info.pci, info.eisa, info.raidnum);
 #endif
 
-   if (pdev) pci_set_master(pdev);
+   if (HD(j)->pdev) {
+      pci_set_master(HD(j)->pdev);
+      if (pci_set_dma_mask(HD(j)->pdev, 0xffffffff))
+         printk("%s: warning, pci_set_dma_mask failed.\n", BN(j));
+      }
 
    return TRUE;
 }
@@ -1275,25 +1298,92 @@
    return j;
 }
 
-static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
-   unsigned int k;
+static inline void map_dma(unsigned int i, unsigned int j) {
+   unsigned int k, count, pci_dir;
    struct scatterlist *sgpnt;
+   struct mscp *cpp;
+   Scsi_Cmnd *SCpnt;
+
+   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
+   pci_dir = scsi_to_pci_dma_dir(SCpnt->sc_data_direction);
+
+   if (SCpnt->sense_buffer)
+      cpp->sense_addr = H2DEV(pci_map_single(HD(j)->pdev, SCpnt->sense_buffer,
+                           sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE));
+
+   cpp->sense_len = sizeof SCpnt->sense_buffer;
+
+   if (!SCpnt->use_sg) {
+
+      if (!SCpnt->request_bufflen)
+         cpp->data_address = V2DEV(SCpnt->request_buffer);
+
+      else if (SCpnt->request_buffer)
+         cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev,
+                  SCpnt->request_buffer, SCpnt->request_bufflen, pci_dir));
+
+      cpp->data_len = H2DEV(SCpnt->request_bufflen);
+      return;
+      }
 
    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
+   count = pci_map_sg(HD(j)->pdev, sgpnt, SCpnt->use_sg, pci_dir);
 
-   for (k = 0; k < SCpnt->use_sg; k++) {
-      cpp->sglist[k].address = V2DEV(sgpnt[k].address);
-      cpp->sglist[k].num_bytes = H2DEV(sgpnt[k].length);
+   for (k = 0; k < count; k++) {
+      cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
+      cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
       }
 
+   cpp->sg = TRUE;
    cpp->data_address = V2DEV(cpp->sglist);
    cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
 }
 
-static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
-   unsigned int i, j, k;
+static void unmap_dma(unsigned int i, unsigned int j) {
+   unsigned int pci_dir;
    struct mscp *cpp;
-   struct mssp *spp;
+   Scsi_Cmnd *SCpnt;
+
+   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
+   pci_dir = scsi_to_pci_dma_dir(SCpnt->sc_data_direction);
+
+   if (DEV2H(cpp->sense_addr))
+      pci_unmap_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
+                       DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
+
+   if (SCpnt->use_sg) 
+      pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir);
+
+   else if (DEV2H(cpp->data_address) && DEV2H(cpp->data_len))
+      pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address), 
+                       DEV2H(cpp->data_len), pci_dir);
+
+}
+
+static void sync_dma(unsigned int i, unsigned int j) {
+   unsigned int pci_dir;
+   struct mscp *cpp;
+   Scsi_Cmnd *SCpnt;
+
+   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
+   pci_dir = scsi_to_pci_dma_dir(SCpnt->sc_data_direction);
+
+   if (DEV2H(cpp->sense_addr))
+      pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
+                          DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
+
+   if (SCpnt->use_sg) 
+      pci_dma_sync_sg(HD(j)->pdev, SCpnt->request_buffer, 
+                         SCpnt->use_sg, pci_dir);
+
+   else if (DEV2H(cpp->data_address) && DEV2H(cpp->data_len))
+      pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->data_address), 
+                          DEV2H(cpp->data_len), pci_dir);
+
+}
+
+static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
+   unsigned int k;
 
    static const unsigned char data_out_cmds[] = {
       0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e,
@@ -1304,9 +1394,53 @@
    static const unsigned char data_none_cmds[] = {
       0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e,
       0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47,
-      0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5
+      0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00
       };
 
+   struct mscp *cpp;
+   Scsi_Cmnd *SCpnt;
+
+   cpp = &HD(j)->cp[i];
+   SCpnt = cpp->SCpnt;
+
+   if (SCpnt->sc_data_direction == SCSI_DATA_READ) {
+      cpp->din  = TRUE;
+      cpp->dout = FALSE;
+      return;
+      }
+   else if (SCpnt->sc_data_direction == SCSI_DATA_WRITE) {
+      cpp->din  = FALSE;
+      cpp->dout = TRUE;
+      return;
+      }
+   else if (SCpnt->sc_data_direction == SCSI_DATA_NONE) {
+      cpp->din  = FALSE;
+      cpp->dout = FALSE;
+      return;
+      }
+
+   if (SCpnt->sc_data_direction != SCSI_DATA_UNKNOWN) 
+      panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", BN(j));
+
+   for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
+      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
+         cpp->dout = TRUE;
+         break;
+         }
+
+   if ((cpp->din = !cpp->dout))
+      for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
+         if (SCpnt->cmnd[0] == data_none_cmds[k]) {
+            cpp->din = FALSE;
+            break;
+            }
+
+}
+
+static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
+   unsigned int i, j, k;
+   struct mscp *cpp;
+
    /* j is the board number */
    j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;
 
@@ -1338,11 +1472,8 @@
 
    memset(cpp, 0, sizeof(struct mscp) - sizeof(struct sg_list *));
 
-   /* Set pointer to status packet structure */
-   spp = &HD(j)->sp[0];
-
-   /* The EATA protocol uses Big Endian format */
-   cpp->sp_addr = V2DEV(spp);
+   /* Set pointer to status packet structure, Big Endian format */
+   cpp->sp_dma_addr = H2DEV(HD(j)->sp_dma_addr);
 
    SCpnt->scsi_done = done;
    cpp->cpp_index = i;
@@ -1352,19 +1483,6 @@
                         BN(j), i, SCpnt->channel, SCpnt->target,
                         SCpnt->lun, SCpnt->pid);
 
-   for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
-     if (SCpnt->cmnd[0] == data_out_cmds[k]) {
-        cpp->dout = TRUE;
-        break;
-        }
-
-   if ((cpp->din = !cpp->dout))
-      for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
-        if (SCpnt->cmnd[0] == data_none_cmds[k]) {
-           cpp->din = FALSE;
-           break;
-           }
-
    cpp->reqsen = TRUE;
    cpp->dispri = TRUE;
 #if 0
@@ -1375,8 +1493,13 @@
    cpp->target = SCpnt->target;
    cpp->lun = SCpnt->lun;
    cpp->SCpnt = SCpnt;
-   cpp->sense_addr = V2DEV(SCpnt->sense_buffer);
-   cpp->sense_len = sizeof SCpnt->sense_buffer;
+   memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+
+   /* Use data transfer direction SCpnt->sc_data_direction */
+   scsi_to_dev_dir(i, j);
+
+   /* Map DMA buffers and SG list */
+   map_dma(i, j);
 
    if (SCpnt->device->tagged_queue) {
 
@@ -1396,17 +1519,6 @@
       cpp->mess[1] = SCpnt->device->current_tag++;
       }
 
-   if (SCpnt->use_sg) {
-      cpp->sg = TRUE;
-      build_sg_list(cpp, SCpnt);
-      }
-   else {
-      cpp->data_address = V2DEV(SCpnt->request_buffer);
-      cpp->data_len = H2DEV(SCpnt->request_bufflen);
-      }
-
-   memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
-
    if (linked_comm && SCpnt->device->queue_depth > 2
                                      && TLDEV(SCpnt->device->type)) {
       HD(j)->cp_stat[i] = READY;
@@ -1416,6 +1528,7 @@
 
    /* Send control packet to the board */
    if (do_dma(sh[j]->io_port, (unsigned long) cpp, SEND_CP_DMA)) {
+      unmap_dma(i, j);
       SCpnt->host_scribble = NULL;
       printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
              BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid);
@@ -1472,6 +1585,7 @@
          printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i);
 
       if (SCarg->eh_state == SCSI_STATE_TIMEOUT) {
+         unmap_dma(i, j);
          SCarg->host_scribble = NULL;
          HD(j)->cp_stat[i] = FREE;
          printk("%s, abort, mbox %d, eh_state timeout, pid %ld.\n",
@@ -1493,6 +1607,7 @@
       }
 
    if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
+      unmap_dma(i, j);
       SCarg->result = DID_ABORT << 16;
       SCarg->host_scribble = NULL;
       HD(j)->cp_stat[i] = FREE;
@@ -1589,16 +1704,19 @@
 #endif
 
    HD(j)->in_reset = TRUE;
-   SPIN_UNLOCK
+
+   spin_unlock_irq(&io_request_lock);
    time = jiffies;
    while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);
-   SPIN_LOCK
+   spin_lock_irq(&io_request_lock);
+
    printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
 
    for (i = 0; i < sh[j]->can_queue; i++) {
 
       if (HD(j)->cp_stat[i] == IN_RESET) {
          SCpnt = HD(j)->cp[i].SCpnt;
+         unmap_dma(i, j);
          SCpnt->result = DID_RESET << 16;
          SCpnt->host_scribble = NULL;
 
@@ -1611,6 +1729,7 @@
 
       else if (HD(j)->cp_stat[i] == ABORTING) {
          SCpnt = HD(j)->cp[i].SCpnt;
+         unmap_dma(i, j);
          SCpnt->result = DID_RESET << 16;
          SCpnt->host_scribble = NULL;
 
@@ -1823,7 +1942,7 @@
 static inline void ihdlr(int irq, unsigned int j) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, k, c, status, tstatus, reg;
-   struct mssp *dspp, *spp;
+   struct mssp *spp;
    struct mscp *cpp;
 
    if (sh[j]->irq != irq)
@@ -1845,14 +1964,13 @@
       return;
       }
 
-   dspp = &HD(j)->sp[0];
-   spp  = &HD(j)->sp[1];
+   spp  = &HD(j)->sp;
 
    /* Make a local copy just before clearing the interrupt indication */
-   memcpy(spp, dspp, sizeof(struct mssp));
+   memcpy(spp, HD(j)->sp_cpu_addr, sizeof(struct mssp));
 
    /* Clear the completion flag and cp pointer on the dynamic copy of sp */
-   memset(dspp, 0, sizeof(struct mssp));
+   memset(HD(j)->sp_cpu_addr, 0, sizeof(struct mssp));
 
    /* Read the status register to clear the interrupt indication */
    reg = inb(sh[j]->io_port + REG_STATUS);
@@ -1910,6 +2028,8 @@
       panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
             BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble);
 
+   sync_dma(i, j);
+
    if (linked_comm && SCpnt->device->queue_depth > 2
                                      && TLDEV(SCpnt->device->type))
       flush_dev(SCpnt->device, SCpnt->request.sector, j, TRUE);
@@ -1987,6 +2107,7 @@
 #else
             status = DID_BUS_BUSY << 16;
 #endif
+
             HD(j)->retries++;
             HD(j)->last_retried_pid = SCpnt->pid;
             }
@@ -2023,6 +2144,8 @@
              SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
              reg, HD(j)->iocount);
 
+   unmap_dma(i, j);
+
    /* Set the command state to inactive */
    SCpnt->host_scribble = NULL;
 
@@ -2036,14 +2159,14 @@
 
 static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) {
    unsigned int j;
-   SPIN_FLAGS
+   unsigned long spin_flags;
 
    /* Check if the interrupt must be processed by this handler */
    if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return;
 
-   SPIN_LOCK_SAVE
+   spin_lock_irqsave(&io_request_lock, spin_flags);
    ihdlr(irq, j);
-   SPIN_UNLOCK_RESTORE
+   spin_unlock_irqrestore(&io_request_lock, spin_flags);
 }
 
 int eata2x_release(struct Scsi_Host *shpnt) {
@@ -2054,13 +2177,15 @@
    if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n",
                             driver_name);
 
-   if( sh[j]->unchecked_isa_dma ) {
-	   scsi_deregister_blocked_host(sh[j]);
-   }
+   if(sh[j]->unchecked_isa_dma) scsi_deregister_blocked_host(sh[j]);
 
    for (i = 0; i < sh[j]->can_queue; i++)
       if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
 
+   if (HD(j)->sp_cpu_addr) 
+      pci_free_consistent(HD(j)->pdev, sizeof(struct mssp),
+                          HD(j)->sp_cpu_addr, HD(j)->sp_dma_addr);
+                       
    free_irq(sh[j]->irq, &sha[j]);
 
    if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel);
@@ -2077,4 +2202,4 @@
 #ifndef MODULE
 __setup("eata=", option_setup);
 #endif /* end MODULE */
-MODULE_LICENSE("Dual BSD/GPL");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/eata.h linux/drivers/scsi/eata.h
--- linux.orig/drivers/scsi/eata.h	2001-05-20 00:43:06.000000000 +0000
+++ linux/drivers/scsi/eata.h	2002-07-20 01:08:27.000000000 +0000
@@ -13,7 +13,7 @@
 int eata2x_reset(Scsi_Cmnd *);
 int eata2x_biosparam(Disk *, kdev_t, int *);
 
-#define EATA_VERSION "6.05.00"
+#define EATA_VERSION "6.50.00"
 
 #define EATA {                                                               \
                 name:              "EATA/DMA 2.0x rev. " EATA_VERSION " ",   \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/fastlane.c linux/drivers/scsi/fastlane.c
--- linux.orig/drivers/scsi/fastlane.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/fastlane.c	2002-07-20 01:08:33.000000000 +0000
@@ -372,3 +372,5 @@
 #endif
 	return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/gdth_proc.c linux/drivers/scsi/gdth_proc.c
--- linux.orig/drivers/scsi/gdth_proc.c	2001-09-07 16:28:37.000000000 +0000
+++ linux/drivers/scsi/gdth_proc.c	2002-07-20 01:08:36.000000000 +0000
@@ -1464,7 +1464,7 @@
             timer_table[SCSI_TIMER].expires = jiffies + timeout;
             timer_active |= 1 << SCSI_TIMER;
         } else {
-            if (jiffies + timeout < timer_table[SCSI_TIMER].expires)
+            if (time_before(jiffies + timeout, timer_table[SCSI_TIMER].expires))
                 timer_table[SCSI_TIMER].expires = jiffies + timeout;
         }
     }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/gvp11.c linux/drivers/scsi/gvp11.c
--- linux.orig/drivers/scsi/gvp11.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/gvp11.c	2002-07-20 01:08:39.000000000 +0000
@@ -372,3 +372,5 @@
 #endif
     return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux.orig/drivers/scsi/ide-scsi.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/ide-scsi.c	2002-07-20 01:08:23.000000000 +0000
@@ -529,28 +529,35 @@
 	return 0;
 }
 
+int idescsi_reinit(ide_drive_t *drive);
+
 /*
  *	IDE subdriver functions, registered with ide.c
  */
 static ide_driver_t idescsi_driver = {
-	"ide-scsi",		/* name */
-	IDESCSI_VERSION,	/* version */
-	ide_scsi,		/* media */
-	0,			/* busy */
-	1,			/* supports_dma */
-	0,			/* supports_dsc_overlap */
-	idescsi_cleanup,	/* cleanup */
-	idescsi_do_request,	/* do_request */
-	idescsi_end_request,	/* end_request */
-	NULL,			/* ioctl */
-	idescsi_open,		/* open */
-	idescsi_ide_release,	/* release */
-	NULL,			/* media_change */
-	NULL,			/* revalidate */
-	NULL,			/* pre_reset */
-	NULL,			/* capacity */
-	NULL,			/* special */
-	NULL			/* proc */
+	name:			"ide-scsi",
+	version:		IDESCSI_VERSION,
+	media:			ide_scsi,
+	busy:			0,
+	supports_dma:		1,
+	supports_dsc_overlap:	0,
+	cleanup:		idescsi_cleanup,
+	standby:		NULL,
+	flushcache:		NULL,
+	do_request:		idescsi_do_request,
+	end_request:		idescsi_end_request,
+	ioctl:			NULL,
+	open:			idescsi_open,
+	release:		idescsi_ide_release,
+	media_change:		NULL,
+	revalidate:		NULL,
+	pre_reset:		NULL,
+	capacity:		NULL,
+	special:		NULL,
+	proc:			NULL,
+	reinit:			idescsi_reinit,
+	ata_prebuilder:		NULL,
+	atapi_prebuilder:	NULL,
 };
 
 int idescsi_init (void);
@@ -561,6 +568,43 @@
 	NULL
 };
 
+int idescsi_reinit (ide_drive_t *drive)
+{
+#if 0
+	idescsi_scsi_t *scsi;
+	byte media[] = {TYPE_DISK, TYPE_TAPE, TYPE_PROCESSOR, TYPE_WORM, TYPE_ROM, TYPE_SCANNER, TYPE_MOD, 255};
+	int i, failed, id;
+
+	if (!idescsi_initialized)
+		return 0;
+	for (i = 0; i < MAX_HWIFS * MAX_DRIVES; i++)
+		idescsi_drives[i] = NULL;
+
+	MOD_INC_USE_COUNT;
+	for (i = 0; media[i] != 255; i++) {
+		failed = 0;
+		while ((drive = ide_scan_devices (media[i], idescsi_driver.name, NULL, failed++)) != NULL) {
+
+			if ((scsi = (idescsi_scsi_t *) kmalloc (sizeof (idescsi_scsi_t), GFP_KERNEL)) == NULL) {
+				printk (KERN_ERR "ide-scsi: %s: Can't allocate a scsi structure\n", drive->name);
+				continue;
+			}
+			if (ide_register_subdriver (drive, &idescsi_driver, IDE_SUBDRIVER_VERSION)) {
+				printk (KERN_ERR "ide-scsi: %s: Failed to register the driver with ide.c\n", drive->name);
+				kfree (scsi);
+				continue;
+			}
+			for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++);
+				idescsi_setup (drive, scsi, id);
+			failed--;
+		}
+	}
+	ide_register_module(&idescsi_module);
+	MOD_DEC_USE_COUNT;
+#endif
+	return 0;
+}
+
 /*
  *	idescsi_init will register the driver for each scsi.
  */
@@ -591,7 +635,7 @@
 				continue;
 			}
 			for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++);
-			idescsi_setup (drive, scsi, id);
+				idescsi_setup (drive, scsi, id);
 			failed--;
 		}
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/ips.c linux/drivers/scsi/ips.c
--- linux.orig/drivers/scsi/ips.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/ips.c	2002-07-20 01:08:22.000000000 +0000
@@ -81,7 +81,7 @@
 /*            2.3.18 and later                                               */
 /*          - Sync with other changes from the 2.3 kernels                   */
 /* 4.00.06  - Fix timeout with initial FFDC command                          */
-/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@infradead.org> */
+/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@caldera.de>    */
 /* 4.10.00  - Add support for ServeRAID 4M/4L                                */
 /* 4.10.13  - Fix for dynamic unload and proc file system                    */
 /* 4.20.03  - Rename version to coincide with new release schedules          */
@@ -105,15 +105,22 @@
 /*            Code Clean-Up for 2.4.x kernel                                 */
 /* 4.72.00  - Allow for a Scatter-Gather Element to exceed MAX_XFER Size     */
 /* 4.72.01  - I/O Mapped Memory release ( so "insmod ips" does not Fail )    */
-/*            Don't Issue Internal FFDC Command if there are Active Commands */
-/*            Close Window for getting too many IOCTL's active               */
-/* 4.80.00    Make ia64 Safe                                                 */
-/* 4.80.04    Eliminate calls to strtok() if 2.4.x or greater                */
-/*            Adjustments to Device Queue Depth                              */
-/* 4.80.14    Take all semaphores off stack                                  */
-/*            Clean Up New_IOCTL path                                        */
-/* 4.80.20    Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )  */
-/*            5 second delay needed after resetting an i960 adapter          */
+/*          - Don't Issue Internal FFDC Command if there are Active Commands */
+/*          - Close Window for getting too many IOCTL's active               */
+/* 4.80.00  - Make ia64 Safe                                                 */
+/* 4.80.04  - Eliminate calls to strtok() if 2.4.x or greater                */
+/*          - Adjustments to Device Queue Depth                              */
+/* 4.80.14  - Take all semaphores off stack                                  */
+/*          - Clean Up New_IOCTL path                                        */
+/* 4.80.20  - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )  */
+/*          - 5 second delay needed after resetting an i960 adapter          */
+/* 4.80.26  - Clean up potential code problems ( Arjan's recommendations )   */
+/* 4.90.01  - Version Matching for FirmWare, BIOS, and Driver                */
+/* 4.90.05  - Use New PCI Architecture to facilitate Hot Plug Development    */
+/* 4.90.08  - Increase Delays in Flashing ( Trombone Only - 4H )             */
+/* 4.90.08  - Data Corruption if First Scatter Gather Element is > 64K       */
+/* 4.90.11  - Don't actually RESET unless it's physically required           */
+/*          - Remove unused compile options                                  */
 /*****************************************************************************/
 
 /*
@@ -121,20 +128,15 @@
  *
  * IPS_DEBUG            - Turn on debugging info
  *
- *
  * Parameters:
  *
  * debug:<number>       - Set debug level to <number>
- *                        NOTE: only works when IPS_DEBUG compile directive
- *                              is used.
- *
+ *                        NOTE: only works when IPS_DEBUG compile directive is used.
  *       1              - Normal debug messages
  *       2              - Verbose debug messages
  *       11             - Method trace (non interrupt)
  *       12             - Method trace (includes interrupt)
  *
- * noreset              - Don't reset the controller
- * nocmdline            - Turn off passthru support
  * noi2o                - Don't use I2O Queues (ServeRAID 4 only)
  * nommap               - Don't use memory mapped I/O
  * ioctlsize            - Initial size of the IOCTL buffer
@@ -162,9 +164,7 @@
 #include <linux/blk.h>
 #include <linux/types.h>
 
-#ifndef NO_IPS_CMDLINE
 #include <scsi/sg.h>
-#endif
 
 #include "sd.h"
 #include "scsi.h"
@@ -176,14 +176,11 @@
 #include <linux/stat.h>
 #include <linux/config.h>
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,18)
-#include <linux/spinlock.h>
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+  #include <linux/spinlock.h>
+  #include <linux/init.h>
 #else
-#include <asm/spinlock.h>
-#endif
-
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
-#include <linux/init.h>
+  #include <asm/spinlock.h>
 #endif
 
 #include <linux/smp.h>
@@ -196,10 +193,10 @@
 /*
  * DRIVER_VER
  */
-#define IPS_VERSION_HIGH        "4.80"
-#define IPS_VERSION_LOW         ".26 "
+#define IPS_VERSION_HIGH        "4.90"
+#define IPS_VERSION_LOW         ".18 "
 
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
 struct proc_dir_entry proc_scsi_ips = {
    0,
    3, "ips",
@@ -213,10 +210,29 @@
 
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)
    #error "This driver only works with kernel 2.2.0 and later"
-#endif
-
-#if !defined(NO_IPS_CMDLINE) && ((SG_BIG_BUFF < 8192) || !defined(SG_BIG_BUFF))
-   #error "To use the command-line interface you need to define SG_BIG_BUFF"
+#elif LINUX_VERSION_CODE <= LinuxVersionCode(2,3,18)
+    #define dma_addr_t uint32_t
+    
+    static inline void *pci_alloc_consistent(struct pci_dev *dev,int size,
+                                             dma_addr_t *dmahandle) {
+       void * ptr = kmalloc(size, GFP_ATOMIC); 
+       if(ptr){     
+          *dmahandle = VIRT_TO_BUS(ptr);
+       }
+       return ptr;
+    }
+    
+    #define pci_free_consistent(a,size,address,dmahandle) kfree(address)
+    
+    #define pci_map_sg(a,b,n,z)       (n)
+    #define pci_unmap_sg(a,b,c,d)     
+    #define pci_map_single(a,b,c,d)   (VIRT_TO_BUS(b))
+    #define pci_unmap_single(a,b,c,d) 
+    #ifndef sg_dma_address
+      #define sg_dma_address(x)         (VIRT_TO_BUS((x)->address))
+      #define sg_dma_len(x)             ((x)->length)
+    #endif
+    #define pci_unregister_driver(x)
 #endif
 
 #ifdef IPS_DEBUG
@@ -233,8 +249,8 @@
  * global variables
  */
 static const char   ips_name[] = "ips";
-static struct Scsi_Host * ips_sh[IPS_MAX_ADAPTERS];  /* Array of host controller structures */
-static ips_ha_t * ips_ha[IPS_MAX_ADAPTERS];          /* Array of HA structures */
+static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS];   /* Array of host controller structures */
+static ips_ha_t    *ips_ha[IPS_MAX_ADAPTERS];        /* Array of HA structures */
 static unsigned int ips_next_controller = 0;
 static unsigned int ips_num_controllers = 0;
 static unsigned int ips_released_controllers = 0;
@@ -242,15 +258,34 @@
 static int          ips_reset_timeout = 60 * 5;
 static int          ips_force_memio = 1;             /* Always use Memory Mapped I/O    */
 static int          ips_force_i2o = 1;               /* Always use I2O command delivery */
-static int          ips_resetcontroller = 1;         /* Reset the controller            */
-static int          ips_cmdline = 1;                 /* Support for passthru            */
 static int          ips_ioctlsize = IPS_IOCTL_SIZE;  /* Size of the ioctl buffer        */
 static int          ips_cd_boot = 0;                 /* Booting from ServeRAID Manager CD */
 static char        *ips_FlashData = NULL;            /* CD Boot - Flash Data Buffer      */
 static int          ips_FlashDataInUse = 0;          /* CD Boot - Flash Data In Use Flag */
 
-#ifdef IPS_DEBUG
-static int          ips_debug = 0;                   /* Debug mode                      */
+IPS_DEFINE_COMPAT_TABLE( Compatable );               /* Version Compatability Table      */
+
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+   static struct  pci_device_id  ips_pci_table[]  __devinitdata = {
+           { 0x1014, 0x002E, PCI_ANY_ID,PCI_ANY_ID, 0, 0, 0 },
+           { 0x1014, 0x01BD, PCI_ANY_ID,PCI_ANY_ID, 0, 0, 0 },
+           { 0, }
+   };
+
+   MODULE_DEVICE_TABLE( pci, ips_pci_table );
+
+   static char ips_hot_plug_name[] = "ips";
+   
+   static int __devinit  ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
+   static void __devexit ips_remove_device(struct pci_dev *pci_dev);
+   
+   struct pci_driver ips_pci_driver = {
+       name:		ips_hot_plug_name,
+       id_table:	ips_pci_table,
+       probe:		ips_insert_device,
+       remove:		__devexit_p(ips_remove_device),
+   };
 #endif
 
 /*
@@ -271,7 +306,9 @@
    "ServeRAID 4M",
    "ServeRAID 4L",
    "ServeRAID 4Mx",
-   "ServeRAID 4Lx"
+   "ServeRAID 4Lx",
+   "ServeRAID 5I",
+   "ServeRAID 5I"
 };
 
 static struct notifier_block ips_notifier = {
@@ -356,6 +393,7 @@
 static int ips_rdcap(ips_ha_t *, ips_scb_t *);
 static int ips_msense(ips_ha_t *, ips_scb_t *);
 static int ips_reqsen(ips_ha_t *, ips_scb_t *);
+static int ips_deallocatescbs(ips_ha_t *, int);
 static int ips_allocatescbs(ips_ha_t *);
 static int ips_reset_copperhead(ips_ha_t *);
 static int ips_reset_copperhead_memio(ips_ha_t *);
@@ -381,15 +419,18 @@
 static int ips_isinit_copperhead_memio(ips_ha_t *);
 static int ips_isinit_morpheus(ips_ha_t *);
 static int ips_erase_bios(ips_ha_t *);
-static int ips_program_bios(ips_ha_t *, char *, u_int32_t, u_int32_t);
-static int ips_verify_bios(ips_ha_t *, char *, u_int32_t, u_int32_t);
+static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);
+static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);
 static int ips_erase_bios_memio(ips_ha_t *);
-static int ips_program_bios_memio(ips_ha_t *, char *, u_int32_t, u_int32_t);
-static int ips_verify_bios_memio(ips_ha_t *, char *, u_int32_t, u_int32_t);
+static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
+static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
 static void ips_flash_bios_section(void *);
 static void ips_flash_bios_segment(void *);
+static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
+static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
+static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
+static void ips_free_flash_copperhead(ips_ha_t *ha);
 static void ips_scheduled_flash_bios(void *);
-static void ips_create_nvrampage5(ips_ha_t *, IPS_NVRAM_P5 *);
 static void ips_get_bios_version(ips_ha_t *, int);
 static void ips_identify_controller(ips_ha_t *);
 static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
@@ -410,10 +451,10 @@
 static void ips_statinit_memio(ips_ha_t *);
 static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
 static void ips_ffdc_reset(ips_ha_t *, int);
-static void ips_ffdc_time(ips_ha_t *, int);
-static u_int32_t ips_statupd_copperhead(ips_ha_t *);
-static u_int32_t ips_statupd_copperhead_memio(ips_ha_t *);
-static u_int32_t ips_statupd_morpheus(ips_ha_t *);
+static void ips_ffdc_time(ips_ha_t *);
+static uint32_t ips_statupd_copperhead(ips_ha_t *);
+static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
+static uint32_t ips_statupd_morpheus(ips_ha_t *);
 static ips_scb_t * ips_getscb(ips_ha_t *);
 static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
 static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *);
@@ -428,18 +469,23 @@
 static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *);
 static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *);
 
-#ifndef NO_IPS_CMDLINE
 static int ips_is_passthru(Scsi_Cmnd *);
 static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
 static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 static int ips_newusrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
-#endif
 
 int  ips_proc_info(char *, char **, off_t, int, int, int);
 static int ips_host_info(ips_ha_t *, char *, off_t, int);
 static void copy_mem_info(IPS_INFOSTR *, char *, int);
 static int copy_info(IPS_INFOSTR *, char *, ...);
+static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr );
+static void ips_version_check(ips_ha_t *ha, int intr);
+static int ips_init_phase2( int index );
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr );
+#endif
 
 /*--------------------------------------------------------------------------*/
 /* Exported Functions                                                       */
@@ -454,37 +500,25 @@
 /*   setup parameters to the driver                                         */
 /*                                                                          */
 /****************************************************************************/
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
 static int
 ips_setup(char *ips_str) {
 #else
 void
 ips_setup(char *ips_str, int *dummy) {
 #endif
-   int        i;
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
-   char      *p;
-   char       tokens[3] = {',', '.', 0};
-#endif
 
+   int        i;
    char      *key;
    char      *value;
    IPS_OPTION options[] = {
-      {"noreset", &ips_resetcontroller, 0},
-#ifdef IPS_DEBUG
-      {"debug", &ips_debug, 1},
-#endif
       {"noi2o", &ips_force_i2o, 0},
       {"nommap", &ips_force_memio, 0},
-      {"nocmdline", &ips_cmdline, 0},
       {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
       {"cdboot", &ips_cd_boot, 0},
    };
-
-   METHOD_TRACE("ips_setup", 1);
-
-/* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
+    
+   /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
    /* Search for value */
    while ((key = strsep(&ips_str, ",."))) {
@@ -507,7 +541,15 @@
         }
       }
    }
+
+   return (1);
+}
+
 #else
+
+  char      *p;
+   char       tokens[3] = {',', '.', 0};
+
    for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) {
       p = key;
 
@@ -536,17 +578,11 @@
          }
       }
    }
-#endif
-
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
-   return (1);
-#endif
 }
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
-__setup("ips=", ips_setup);
 #endif
 
+
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_detect                                                 */
@@ -562,36 +598,36 @@
 ips_detect(Scsi_Host_Template *SHT) {
    struct Scsi_Host *sh;
    ips_ha_t         *ha;
-   u_int32_t         io_addr;
-   u_int32_t         mem_addr;
-   u_int32_t         io_len;
-   u_int32_t         mem_len;
-   u_int16_t         planer;
-   u_int8_t          revision_id;
-   u_int8_t          bus;
-   u_int8_t          func;
-   u_int8_t          irq;
-   u_int16_t         deviceID[2];
-   u_int16_t         subdevice_id;
+   uint32_t          io_addr;
+   uint32_t          mem_addr;
+   uint32_t          io_len;
+   uint32_t          mem_len;
+   uint16_t          planer;
+   uint8_t           revision_id;
+   uint8_t           bus;
+   uint8_t           func;
+   uint8_t           irq;
+   uint16_t          deviceID[2];
+   uint16_t          subdevice_id;
    int               i;
    int               j;
-   u_int32_t         count;
+   uint32_t          count;
    char             *ioremap_ptr;
    char             *mem_ptr;
    struct pci_dev   *dev[2];
    struct pci_dev   *morpheus = NULL;
    struct pci_dev   *trombone = NULL;
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,14)
-   u_int32_t         currbar;
-   u_int32_t         maskbar;
-   u_int8_t          barnum;
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
+   uint32_t          currbar;
+   uint32_t          maskbar;
+   uint8_t           barnum;
 #endif
 
    METHOD_TRACE("ips_detect", 1);
 
 #ifdef MODULE
    if (ips)
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
       ips_setup(ips);
 #else
       ips_setup(ips, NULL);
@@ -609,7 +645,7 @@
    }                                                                               
 
    SHT->proc_info = ips_proc_info;
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
    SHT->proc_dir = &proc_scsi_ips;
 #else
    SHT->proc_name = "ips";
@@ -667,6 +703,18 @@
       }
    }
 
+/**********************************************************************************/
+/* For Kernel Versions 2.4 or greater, use new PCI ( Hot Pluggable ) architecture */
+/**********************************************************************************/
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+   spin_unlock_irq(&io_request_lock);
+   pci_module_init(&ips_pci_driver);
+   spin_lock_irq(&io_request_lock);
+   if (ips_num_controllers > 0) 
+      register_reboot_notifier(&ips_notifier);
+   return (ips_num_controllers);
+#endif
+
    /* Now scan the controllers */
    for (i = 0; i < 2; i++) {
       if (!dev[i])
@@ -704,17 +752,6 @@
                mem_addr = pci_resource_start(dev[i], j);
                mem_len = pci_resource_len(dev[i], j);
             }
-#elif LINUX_VERSION_CODE >= LinuxVersionCode(2,3,14)
-            if (!dev[i]->resource[j].start)
-               break;
-
-            if ((dev[i]->resource[j].start & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
-               io_addr = dev[i]->resource[j].start;
-               io_len = dev[i]->resource[j].end - dev[i]->resource[j].start + 1;
-            } else {
-               mem_addr = dev[i]->resource[j].start;
-               mem_len = dev[i]->resource[j].end - dev[i]->resource[j].start + 1;
-            }
 #else
             if (!dev[i]->base_address[j])
                break;
@@ -747,13 +784,13 @@
 
          /* setup memory mapped area (if applicable) */
          if (mem_addr) {
-            u_int32_t base;
-            u_int32_t offs;
+            uint32_t base;
+            uint32_t offs;
 
             DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d",
                       ips_name, ips_next_controller, mem_addr, mem_len);
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
             if (check_mem_region(mem_addr, mem_len)) {
                /* Couldn't allocate io space */
                printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
@@ -829,7 +866,7 @@
             continue;
          }
 
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,15)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
          /* get the subdevice id */
          if (pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id)) {
             printk(KERN_WARNING "(%s%d) can't get subdevice id.\n",
@@ -1003,9 +1040,9 @@
 
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
          sh->max_sectors = 128;
-#endif
+#endif                      
 
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,32)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
          sh->wish_block = FALSE;
 #endif
 
@@ -1078,6 +1115,7 @@
          /*
           * Initialize the card if it isn't already
           */
+
          if (!(*ha->func.isinit)(ha)) {
             if (!(*ha->func.init)(ha)) {
                /*
@@ -1117,8 +1155,8 @@
          /*
           * Allocate a temporary SCB for initialization
           */
-         ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_KERNEL);
-         if (!ha->scbs) {
+         ha->max_cmds = 1;
+         if (!ips_allocatescbs(ha)) {
             /* couldn't allocate a temp SCB */
             printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
                    ips_name, ips_next_controller);
@@ -1135,27 +1173,6 @@
             continue;
          }
 
-         memset(ha->scbs, 0, sizeof(ips_scb_t));
-         ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_KERNEL);
-         if (!ha->scbs->sg_list) {
-            /* couldn't allocate a temp SCB S/G list */
-            printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
-                   ips_name, ips_next_controller);
-
-            ha->active = 0;
-            ips_free(ha);
-            scsi_unregister(sh);
-            ips_ha[ips_next_controller] = 0;
-            ips_sh[ips_next_controller] = 0;
-            free_irq(ha->irq, ha);
-            ips_next_controller++;
-            ips_num_controllers--;
-
-            continue;
-         }
-
-         ha->max_cmds = 1;
-
          ips_next_controller++;
       } while ((dev[i] = pci_find_device(IPS_VENDORID, deviceID[i], dev[i])));
    }
@@ -1167,65 +1184,13 @@
    for (i = 0; i < ips_next_controller; i++) {
 
       if (ips_ha[i] == 0) {
-         printk(KERN_WARNING "(%s%d) ignoring bad controller\n",
-                ips_name, i);
+         printk(KERN_WARNING "(%s%d) ignoring bad controller\n", ips_name, i);
          continue;
       }
 
-      ha = ips_ha[i];
-      sh = ips_sh[i];
-
-      if (!ha->active) {
-         scsi_unregister(sh);
-         ips_ha[i] = NULL;
-         ips_sh[i] = NULL;
-
-         continue;
-      }
-
-      if (!ips_hainit(ha)) {
-         printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping\n",
-                ips_name, i);
-
-         ha->active = 0;
-         ips_free(ha);
-         free_irq(ha->irq, ha);
-         scsi_unregister(sh);
-         ips_ha[i] = NULL;
-         ips_sh[i] = NULL;
+      if (ips_init_phase2(i) != SUCCESS)
          ips_num_controllers--;
 
-         continue;
-      }
-
-      /*
-       * Free the temporary SCB
-       */
-      kfree(ha->scbs->sg_list);
-      kfree(ha->scbs);
-      ha->scbs = NULL;
-
-      /* allocate CCBs */
-      if (!ips_allocatescbs(ha)) {
-         printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
-                ips_name, i);
-
-         ha->active = 0;
-         ips_free(ha);
-         free_irq(ha->irq, ha);
-         scsi_unregister(sh);
-         ips_ha[i] = NULL;
-         ips_sh[i] = NULL;
-         ips_num_controllers--;
-
-         continue;
-      }
-
-      /* finish setting values */
-      sh->max_id = ha->ntargets;
-      sh->max_lun = ha->nlun;
-      sh->max_channel = ha->nbus - 1;
-      sh->can_queue = ha->max_cmds-1;
    }
 
    if (ips_num_controllers > 0)
@@ -1314,9 +1279,10 @@
 
    ips_released_controllers++;
 
-   if (ips_num_controllers == ips_released_controllers)
+   if (ips_num_controllers == ips_released_controllers){
       unregister_reboot_notifier(&ips_notifier);
-
+      pci_unregister_driver(&ips_pci_driver);
+   }
    return (FALSE);
 }
 
@@ -1511,6 +1477,46 @@
       return (SUCCESS);
    }
 
+   /* An explanation for the casual observer:                              */
+   /* Part of the function of a RAID controller is automatic error         */
+   /* detection and recovery.  As such, the only problem that physically   */
+   /* resetting a ServeRAID adapter will ever fix is when, for some reason,*/
+   /* the driver is not successfully communicating with the adapter.       */
+   /* Therefore, we will attempt to flush this adapter.  If that succeeds, */
+   /* then there's no real purpose in a physical reset. This will complete */
+   /* much faster and avoids any problems that might be caused by a        */
+   /* physical reset ( such as having to fail all the outstanding I/O's ). */
+                                                           
+   if (ha->ioctl_reset == 0) {          /* IF Not an IOCTL Requested Reset */
+      scb = &ha->scbs[ha->max_cmds-1];
+
+      ips_init_scb(ha, scb);
+
+      scb->timeout = ips_cmd_timeout;
+      scb->cdb[0] = IPS_CMD_FLUSH;
+
+      scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
+      scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
+      scb->cmd.flush_cache.state = IPS_NORM_STATE;
+      scb->cmd.flush_cache.reserved = 0;
+      scb->cmd.flush_cache.reserved2 = 0;
+      scb->cmd.flush_cache.reserved3 = 0;
+      scb->cmd.flush_cache.reserved4 = 0;
+
+      /* Attempt the flush command */
+      ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
+      if (ret == IPS_SUCCESS) {
+         printk(KERN_NOTICE "(%s%d) Reset Request - Flushed Cache\n", ips_name, ha->host_num);
+         clear_bit(IPS_IN_RESET, &ha->flags);
+         return (SUCCESS);
+         }
+   }
+
+   /* Either we can't communicate with the adapter or it's an IOCTL request */
+   /* from a ServeRAID utility.  A physical reset is needed at this point.  */
+
+   ha->ioctl_reset = 0;             /* Reset the IOCTL Requested Reset Flag */
+
    /*
     * command must have already been sent
     * reset the controller
@@ -1633,6 +1639,10 @@
 
 }
 
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+__setup("ips=", ips_setup);
+#endif
+
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_queue                                                  */
@@ -1649,6 +1659,7 @@
 ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
    ips_ha_t         *ha;
    unsigned long     cpu_flags;
+   ips_passthru_t   *pt;                                             
 
    METHOD_TRACE("ips_queue", 1);
 
@@ -1660,7 +1671,6 @@
    if (!ha->active)
       return (DID_ERROR);
 
-#ifndef NO_IPS_CMDLINE
    if (ips_is_passthru(SC)) {
       IPS_QUEUE_LOCK(&ha->copp_waitlist);
       if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
@@ -1673,7 +1683,6 @@
          IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
       }
    } else {
-#endif
       IPS_QUEUE_LOCK(&ha->scb_waitlist);
       if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
          IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
@@ -1685,9 +1694,7 @@
          IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
       }
 
-#ifndef NO_IPS_CMDLINE
    }
-#endif
 
    SC->scsi_done = done;
 
@@ -1707,7 +1714,6 @@
       return (0);
    }
 
-#ifndef NO_IPS_CMDLINE
    if (ips_is_passthru(SC)) {
 
       ips_copp_wait_item_t *scratch;
@@ -1726,6 +1732,24 @@
          }
       }
 
+      /* A Reset IOCTL is only sent by the ServeRAID boot CD in extreme cases. */
+      /* There can never be any system activity ( network or disk ), but check */
+      /* anyway just as a good practice.                                       */
+      pt = (ips_passthru_t *) SC->request_buffer;                                
+      if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&            
+           (pt->CoppCP.cmd.reset.adapter_flag == 1))  {                         
+         if (ha->scb_activelist.count != 0) {
+             SC->result = DID_BUS_BUSY << 16;
+             done(SC);
+             return (0);
+         }
+         ha->ioctl_reset = 1;           /* This reset request is from an IOCTL */
+         ips_eh_reset(SC);                                                         
+         SC->result = DID_OK << 16;                                                
+         SC->scsi_done(SC);                                                        
+         return (0);                                                               
+      }
+
       /* allocate space for the scribble */
       scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC);
 
@@ -1744,7 +1768,6 @@
       ips_putq_copp_tail(&ha->copp_waitlist, scratch);
    }
    else
-#endif
       ips_putq_wait_tail(&ha->scb_waitlist, SC);
 
    IPS_HA_LOCK(cpu_flags);
@@ -1767,7 +1790,7 @@
    if (ips_is_passthru(SC) && SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
       char      *user_area;
       char      *kern_area;
-      u_int32_t  datasize;
+      uint32_t  datasize;
 
       /* free io_request_lock */
       spin_unlock_irq(&io_request_lock);
@@ -1775,13 +1798,10 @@
       /* wait for the command to finish */
       down(&ha->ioctl_sem);
 
-      /* reobtain the lock */
-      spin_lock_irq(&io_request_lock);
-
       /* command finished -- copy back */
       user_area = *((char **) &SC->cmnd[4]);
       kern_area = ha->ioctl_data;
-      datasize = *((u_int32_t *) &SC->cmnd[8]);
+      datasize = *((uint32_t *) &SC->cmnd[8]);
 
       if (datasize) {
          if (copy_to_user(user_area, kern_area, datasize) > 0) {
@@ -1791,17 +1811,18 @@
          }
       }
 
+      /* reobtain the lock */
+      spin_lock_irq(&io_request_lock);
       SC->scsi_done(SC);
    }
 
    /* If We were using the CD Boot Flash Buffer, Restore the Old Values */
    if ( ips_FlashData == ha->ioctl_data ) {                               
-      ha->ioctl_data = ha->save_ioctl_data;                           
-      ha->ioctl_order = ha->save_ioctl_order;                          
-      ha->ioctl_datasize = ha->save_ioctl_datasize;                       
+      ha->ioctl_data = ha->flash_data;                           
+      ha->ioctl_order = ha->flash_order;                          
+      ha->ioctl_datasize = ha->flash_datasize;                       
       ips_FlashDataInUse = 0;                                             
    }
-
    return (0);
 }
 
@@ -1917,7 +1938,9 @@
    METHOD_TRACE("do_ipsintr", 2);
 
    ha = (ips_ha_t *) dev_id;
-
+   if (!ha) 
+      return;
+   
    spin_lock_irqsave(&io_request_lock, cpu_flags);
 
    if (test_and_set_bit(IPS_IN_INTR, &ha->flags)) {
@@ -1926,13 +1949,6 @@
       return ;
    }
 
-   if (!ha) {
-      clear_bit(IPS_IN_INTR, &ha->flags);
-      spin_unlock_irqrestore(&io_request_lock, cpu_flags);
-
-      return;
-   }
-
    if (!ha->active) {
       clear_bit(IPS_IN_INTR, &ha->flags);
       spin_unlock_irqrestore(&io_request_lock, cpu_flags);
@@ -2182,8 +2198,6 @@
 /* Helper Functions                                                         */
 /*--------------------------------------------------------------------------*/
 
-#ifndef NO_IPS_CMDLINE
-
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_is_passthru                                            */
@@ -2204,16 +2218,22 @@
        (SC->channel == 0) &&
        (SC->target == IPS_ADAPTER_ID) &&
        (SC->lun == 0) &&
-       (SC->request_bufflen) &&
-       (!SC->use_sg) &&
-       (((char *) SC->request_buffer)[0] == 'C') &&
-       (((char *) SC->request_buffer)[1] == 'O') &&
-       (((char *) SC->request_buffer)[2] == 'P') &&
-       (((char *) SC->request_buffer)[3] == 'P')) {
-      return (1);
-   } else {
-      return (0);
+        SC->request_buffer){
+      if((!SC->use_sg) && SC->request_bufflen &&
+         (((char *) SC->request_buffer)[0] == 'C') &&
+         (((char *) SC->request_buffer)[1] == 'O') &&
+         (((char *) SC->request_buffer)[2] == 'P') &&
+         (((char *) SC->request_buffer)[3] == 'P'))
+         return 1;
+      else if(SC->use_sg){
+         struct scatterlist *sg = SC->request_buffer;
+         char *buffer = sg[0].address;
+         if(buffer && buffer[0] == 'C' && buffer[1] == 'O' && 
+            buffer[2] == 'P' && buffer[3] == 'P')
+            return 1;
+      }
    }
+   return 0;
 }
 
 /****************************************************************************/
@@ -2227,40 +2247,74 @@
 /****************************************************************************/
 static int
 ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) {
-   IPS_NVRAM_P5    nvram;
    ips_passthru_t *pt;
+   char *buffer;
+   int length = 0;
 
    METHOD_TRACE("ips_make_passthru", 1);
 
-   if (!SC->request_bufflen || !SC->request_buffer) {
+   if(!SC->use_sg){
+      buffer = SC->request_buffer;
+      length = SC->request_bufflen;
+   }else{
+      struct scatterlist *sg = SC->request_buffer;
+      int i;
+      for(i = 0; i < SC->use_sg; i++)
+         length += sg[i].length;
+
+      if (length < sizeof(ips_passthru_t)) {
+         /* wrong size */
+         DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
+             ips_name, ha->host_num);
+         return (IPS_FAILURE);
+      }else if(!ha->ioctl_data || length > (PAGE_SIZE << ha->ioctl_order)){
+         void *bigger_buf;
+         int count;
+         int order;
+         /* try to allocate a bigger buffer */
+         for (count = PAGE_SIZE, order = 0;
+              count < length;
+              order++, count <<= 1);
+         bigger_buf = (void *) __get_free_pages(GFP_ATOMIC, order);
+         if (bigger_buf) {
+            /* free the old memory */
+            free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
+            /* use the new memory */
+            ha->ioctl_data = (char *) bigger_buf;
+            ha->ioctl_order = order;
+            ha->ioctl_datasize = count;
+         } else {
+             pt = (ips_passthru_t*)sg[0].address;
+             pt->BasicStatus = 0x0B;
+             pt->ExtendedStatus = 0x00;
+             SC->result = DID_ERROR << 16;
+             return (IPS_FAILURE);
+         }
+      }
+      ha->ioctl_datasize = length;
+      length = 0;
+      for(i = 0; i < SC->use_sg; i++){
+         memcpy(&ha->ioctl_data[length], sg[i].address, sg[i].length);
+         length += sg[i].length;
+      }
+      pt = (ips_passthru_t *)ha->ioctl_data;
+      buffer = ha->ioctl_data;
+   }
+   if (!length || !buffer) {
       /* no data */
       DEBUG_VAR(1, "(%s%d) No passthru structure",
                 ips_name, ha->host_num);
 
       return (IPS_FAILURE);
    }
-
-   if (SC->request_bufflen < sizeof(ips_passthru_t)) {
+   if (length < sizeof(ips_passthru_t)) {
       /* wrong size */
       DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
              ips_name, ha->host_num);
 
       return (IPS_FAILURE);
    }
-
-   if ((((char *) SC->request_buffer)[0] != 'C') ||
-       (((char *) SC->request_buffer)[1] != 'O') ||
-       (((char *) SC->request_buffer)[2] != 'P') ||
-       (((char *) SC->request_buffer)[3] != 'P')) {
-      /* signature doesn't match */
-      DEBUG_VAR(1, "(%s%d) Wrong signature on passthru structure.",
-                ips_name, ha->host_num);
-
-      return (IPS_FAILURE);
-   }
-
-   pt = (ips_passthru_t *) SC->request_buffer;
-
+   pt = (ips_passthru_t*) buffer;
    /*
     * Some notes about the passthru interface used
     *
@@ -2280,14 +2334,14 @@
 
    switch (pt->CoppCmd) {
    case IPS_NUMCTRLS:
-      memcpy(SC->request_buffer + sizeof(ips_passthru_t),
+      memcpy(buffer + sizeof(ips_passthru_t),
              &ips_num_controllers, sizeof(int));
       SC->result = DID_OK << 16;
 
       return (IPS_SUCCESS_IMM);
 
    case IPS_CTRLINFO:
-      memcpy(SC->request_buffer + sizeof(ips_passthru_t),
+      memcpy(buffer + sizeof(ips_passthru_t),
              ha, sizeof(ips_ha_t));
       SC->result = DID_OK << 16;
 
@@ -2296,7 +2350,7 @@
    case IPS_COPPUSRCMD:
    case IPS_COPPIOCCMD:
       if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
-         if (SC->request_bufflen < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
+         if (length < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
             /* wrong size */
             DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
                       ips_name, ha->host_num);
@@ -2304,14 +2358,14 @@
             return (IPS_FAILURE);
          }
 
+         if(ha->device_id == IPS_DEVICEID_COPPERHEAD &&
+            pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)
+            return ips_flash_copperhead(ha, pt, scb);
          if (ips_usrcmd(ha, pt, scb))
             return (IPS_SUCCESS);
          else
             return (IPS_FAILURE);
       } else if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-         char      *user_area;
-         char      *kern_area;
-         u_int32_t  datasize;
 
          if (SC->request_bufflen < (sizeof(ips_passthru_t))) {
             /* wrong size */
@@ -2329,54 +2383,14 @@
               (pt->CmdBSize == IPS_IMAGE_SIZE) &&                                   
               (ips_FlashDataInUse == 0) ) {                                 
             ips_FlashDataInUse = 1;                                         
-            ha->save_ioctl_data  = ha->ioctl_data;                          
-            ha->save_ioctl_order = ha->ioctl_order;                         
-            ha->save_ioctl_datasize = ha->ioctl_datasize;                   
+            ha->flash_data  = ha->ioctl_data;
+            ha->flash_order = ha->ioctl_order;
+            ha->flash_datasize = ha->ioctl_datasize;
             ha->ioctl_data  = ips_FlashData;                                
             ha->ioctl_order = 7;                                            
             ha->ioctl_datasize = IPS_IMAGE_SIZE;                                    
          }  
 
-         if ((pt->CoppCP.cmd.nvram.op_code == IPS_CMD_RW_NVRAM_PAGE) &&
-             (pt->CoppCP.cmd.nvram.page == 5) &&
-             (pt->CoppCP.cmd.nvram.write == 0)) {
-
-            datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
-
-            if (datasize < sizeof(IPS_NVRAM_P5)) {
-               pt->BasicStatus = 0x0B;
-               pt->ExtendedStatus = 0x00;
-               SC->result = DID_ERROR << 16;
-
-            return (IPS_FAILURE);
-      }
-
-            ips_get_bios_version(ha, IPS_INTR_IORL);
-            ips_create_nvrampage5(ha, &nvram);
-
-            user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
-            kern_area = (char *) &nvram;
-            datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
-
-            if (datasize > sizeof(IPS_NVRAM_P5))
-               datasize = sizeof(IPS_NVRAM_P5);
-
-            /* Copy out the buffer */
-            if (copy_to_user((void *) user_area, (void *) kern_area, datasize) > 0) {
-               pt->BasicStatus = 0x0B;
-               pt->ExtendedStatus = 0x00;
-               SC->result = DID_ERROR << 16;
-
-               return (EFAULT);
-            }
-
-            pt->BasicStatus = 0x00;
-            pt->ExtendedStatus = 0x00;
-            SC->result = DID_OK << 16;
-
-            return (IPS_SUCCESS_IMM);
-         }
-
          /*
           * IPSSEND flashing BIOS
           */
@@ -2433,8 +2447,8 @@
             /* make sure buffer is big enough */
             if (pt->CmdBSize > ha->ioctl_datasize) {
                void *bigger_struct;
-               u_int32_t count;
-               u_int32_t order;
+               uint32_t count;
+               uint32_t order;
 
                /* try to allocate a bigger struct */
                for (count = PAGE_SIZE, order = 0;
@@ -2512,9 +2526,9 @@
             struct tq_struct  task;
             IPS_FLASH_DATA    flash_data;
 
-      /* copy in the size/buffer ptr from the scsi command */
-      memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
-      memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
+            /* copy in the size/buffer ptr from the scsi command */
+            memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
+            memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
 
             if (pt->CmdBSize > le32_to_cpu(pt->CoppCP.cmd.flashbios.count)) {
                pt->CmdBSize = le32_to_cpu(pt->CoppCP.cmd.flashbios.count);
@@ -2544,14 +2558,14 @@
                pt->ExtendedStatus = 0x00;
                SC->result = DID_ERROR << 16;
 
-         return (IPS_FAILURE);
+               return (IPS_FAILURE);
             }
 
       /* make sure buffer is big enough */
       if (pt->CmdBSize > ha->ioctl_datasize) {
          void *bigger_struct;
-               u_int32_t count;
-               u_int32_t order;
+               uint32_t count;
+               uint32_t order;
 
          /* try to allocate a bigger struct */
                for (count = PAGE_SIZE, order = 0;
@@ -2663,6 +2677,176 @@
       }
 
 /****************************************************************************/
+/* Routine Name: ips_flash_copperhead                                       */
+/* Routine Description:                                                     */
+/*   Flash the BIOS/FW on a Copperhead style controller                     */
+/****************************************************************************/
+static int
+ips_flash_copperhead(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb){
+   int datasize, count;
+
+   /* Trombone is the only copperhead that can do packet flash, but only
+    * for firmware. No one said it had to make sence. */
+   if(IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE){
+      if(ips_usrcmd(ha, pt, scb))
+         return IPS_SUCCESS;
+      else
+         return IPS_FAILURE;
+   }
+   pt->BasicStatus = 0x0B;
+   pt->ExtendedStatus = 0;
+   scb->scsi_cmd->result = DID_OK <<16;
+   /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can     */
+   /* avoid allocating a huge buffer per adapter ( which can fail ). */
+   if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+      pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){
+      pt->BasicStatus = 0;
+      return ips_flash_bios(ha, pt, scb);
+   }else if(pt->CoppCP.cmd.flashfw.packet_num == 0){
+      if(ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
+         ha->flash_data  = ips_FlashData;
+         ha->flash_order = 7;
+         ha->flash_datasize = 0;
+      }else if(!ha->flash_data){
+         datasize = pt->CoppCP.cmd.flashfw.total_packets *
+                    pt->CoppCP.cmd.flashfw.count;
+         for (count = PAGE_SIZE, ha->flash_order = 0; count < datasize;
+              ha->flash_order++, count <<= 1);
+         ha->flash_data = (char *)__get_free_pages(GFP_ATOMIC, ha->flash_order);
+         ha->flash_datasize = 0;
+      }else
+         return IPS_FAILURE;
+   }else{
+      if(pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
+        (PAGE_SIZE << ha->flash_order)){
+         ips_free_flash_copperhead(ha);
+         printk(KERN_WARNING "failed size sanity check\n");
+         return IPS_FAILURE;
+      }
+   }
+   if(!ha->flash_data)
+      return IPS_FAILURE;
+   pt->BasicStatus = 0;
+   memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
+          pt->CoppCP.cmd.flashfw.count);
+   ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
+   if(pt->CoppCP.cmd.flashfw.packet_num ==
+      pt->CoppCP.cmd.flashfw.total_packets - 1){
+      if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
+         return ips_flash_bios(ha, pt, scb);
+      else if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
+         return ips_flash_firmware(ha, pt, scb);
+   }
+   return IPS_SUCCESS_IMM;
+}
+
+/****************************************************************************/
+/* Routine Name: ips_flash_bios                                             */
+/* Routine Description:                                                     */
+/*   flashes the bios of a copperhead adapter                               */
+/****************************************************************************/
+static int
+ips_flash_bios(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){
+
+   if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+      pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS){
+      if ((!ha->func.programbios) || (!ha->func.erasebios) ||
+          (!ha->func.verifybios))
+         goto error;
+      if((*ha->func.erasebios)(ha)){
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
+                   ips_name, ha->host_num);
+         goto error;
+      }else if ((*ha->func.programbios)(ha, ha->flash_data + IPS_BIOS_HEADER,
+          ha->flash_datasize - IPS_BIOS_HEADER, 0 )) {
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to flash",
+                   ips_name, ha->host_num);
+         goto error;
+      }else if ((*ha->func.verifybios)(ha, ha->flash_data + IPS_BIOS_HEADER,
+          ha->flash_datasize - IPS_BIOS_HEADER, 0 )) {
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
+                   ips_name, ha->host_num);
+         goto error;
+      }
+      ips_free_flash_copperhead(ha);
+      return IPS_SUCCESS_IMM;
+   }else if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+      pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){
+      if(!ha->func.erasebios)
+         goto error;
+      if((*ha->func.erasebios)(ha)){
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
+                   ips_name, ha->host_num);
+         goto error;
+      }
+      return IPS_SUCCESS_IMM;
+   }
+error:
+   pt->BasicStatus = 0x0B;
+   pt->ExtendedStatus = 0x00;
+   ips_free_flash_copperhead(ha);
+   return IPS_FAILURE;
+}
+
+/****************************************************************************/
+/* Routine Name: ips_flash_firmware                                         */
+/* Routine Description:                                                     */
+/*   flashes the firmware of a copperhead adapter                           */
+/****************************************************************************/
+static int
+ips_flash_firmware(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){
+   IPS_SG_LIST *sg_list;
+
+   if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
+      pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW ){
+      memset(&pt->CoppCP.cmd, 0, sizeof(IPS_HOST_COMMAND));
+      pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
+      pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
+   }else{
+      pt->BasicStatus = 0x0B;
+      pt->ExtendedStatus = 0x00;
+      ips_free_flash_copperhead(ha);
+      return IPS_FAILURE;
+   }
+   /* Save the S/G list pointer so it doesn't get clobbered */
+   sg_list = scb->sg_list;
+   /* copy in the CP */
+   memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
+   /* FIX stuff that might be wrong */
+   scb->sg_list = sg_list;
+   scb->scb_busaddr = VIRT_TO_BUS(scb);
+   scb->bus = scb->scsi_cmd->channel;
+   scb->target_id = scb->scsi_cmd->target;
+   scb->lun = scb->scsi_cmd->lun;
+   scb->sg_len = 0;
+   scb->data_len = 0;
+   scb->flags = 0;
+   scb->op_code = 0;
+   scb->callback = ipsintr_done;
+   scb->timeout = ips_cmd_timeout;
+   scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
+   scb->cmd.flashfw.buffer_addr = VIRT_TO_BUS(ha->flash_data);
+   if (pt->TimeOut)
+      scb->timeout = pt->TimeOut;
+   scb->scsi_cmd->result = DID_OK <<16;
+   return IPS_SUCCESS;
+}
+
+/****************************************************************************/
+/* Routine Name: ips_free_flash_copperhead                                  */
+/* Routine Description:                                                     */
+/*   release the memory resources used to hold the flash image              */
+/****************************************************************************/
+static void
+ips_free_flash_copperhead(ips_ha_t *ha){
+   if(ha->flash_data == ips_FlashData)
+      test_and_clear_bit(0, &ips_FlashDataInUse);
+   else if(ha->flash_data)
+      free_pages((unsigned long)ha->flash_data, ha->flash_order);
+   ha->flash_data = NULL;
+}
+
+/****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_scheduled_flash_bios                                   */
 /*                                                                          */
@@ -2851,7 +3035,10 @@
       return (0);
 
    if (pt->CmdBSize) {
-      scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + sizeof(ips_passthru_t));
+      if(!scb->scsi_cmd->use_sg)
+         scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + sizeof(ips_passthru_t));
+      else
+         scb->data_busaddr = VIRT_TO_BUS(ha->ioctl_data + sizeof(ips_passthru_t));
    } else {
       scb->data_busaddr = 0L;
    }
@@ -2899,9 +3086,9 @@
    IPS_SG_LIST    *sg_list;
    char           *user_area;
    char           *kern_area;
-   u_int32_t       datasize;
+   uint32_t        datasize;
 
-   METHOD_TRACE("ips_usrcmd", 1);
+   METHOD_TRACE("ips_newusrcmd", 1);
 
    if ((!scb) || (!pt) || (!ha))
       return (0);
@@ -2936,8 +3123,8 @@
    if (pt->CmdBSize) {
       if (pt->CmdBSize > ha->ioctl_datasize) {
          void *bigger_struct;
-         u_int32_t count;
-         u_int32_t order;
+         uint32_t count;
+         uint32_t order;
 
          /* try to allocate a bigger struct */
          for (count = PAGE_SIZE, order = 0;
@@ -2963,7 +3150,7 @@
       /* Attempt to copy in the data */
       user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
       kern_area = ha->ioctl_data;
-      datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
+      datasize = *((uint32_t *) &scb->scsi_cmd->cmnd[8]);
 
       if (copy_from_user(kern_area, user_area, datasize) > 0) {
          DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data",
@@ -3026,8 +3213,10 @@
 
       return ;
    }
-
-   pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
+   if(!scb->scsi_cmd->use_sg)
+      pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
+   else
+      pt = (ips_passthru_t *) ha->ioctl_data;
 
    /* Copy data back to the user */
    if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)        /* Copy DCDB Back to Caller's Area */
@@ -3035,13 +3224,24 @@
    
    pt->BasicStatus = scb->basic_status;
    pt->ExtendedStatus = scb->extended_status;
-
+   pt->AdapterType = ha->ad_type;
    if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) 
       up(&ha->ioctl_sem);
-   
-}
 
-#endif
+   if(ha->device_id == IPS_DEVICEID_COPPERHEAD && 
+     (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD || 
+     scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
+      ips_free_flash_copperhead(ha);
+
+   if(scb->scsi_cmd->use_sg){
+      int i, length = 0;
+      struct scatterlist *sg = scb->scsi_cmd->request_buffer;
+      for(i = 0; i < scb->scsi_cmd->use_sg; i++){
+         memcpy(sg[i].address, &ha->ioctl_data[length], sg[i].length);
+         length += sg[i].length;
+      }
+   }
+}
 
 /****************************************************************************/
 /*                                                                          */
@@ -3236,6 +3436,14 @@
       case IPS_SUBDEVICEID_4LX:
          ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
          break;
+
+      case IPS_SUBDEVICEID_5I2:
+         ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
+         break;
+
+      case IPS_SUBDEVICEID_5I1:
+         ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
+         break;
       }
 
       break;
@@ -3244,31 +3452,6 @@
 
 /****************************************************************************/
 /*                                                                          */
-/* Routine Name: ips_create_nvrampage5                                      */
-/*                                                                          */
-/* Routine Description:                                                     */
-/*                                                                          */
-/*   Create a pseudo nvram page 5                                           */
-/*                                                                          */
-/****************************************************************************/
-static void
-ips_create_nvrampage5(ips_ha_t *ha, IPS_NVRAM_P5 *nvram) {
-   METHOD_TRACE("ips_create_nvrampage5", 1);
-
-   memset(nvram, 0, sizeof(IPS_NVRAM_P5));
-
-   nvram->signature = IPS_NVRAM_P5_SIG;
-   nvram->adapter_slot = ha->slot_num;
-   nvram->adapter_type = ha->ad_type;
-   nvram->operating_system = IPS_OS_LINUX;
-   strncpy((char *) nvram->driver_high, IPS_VERSION_HIGH, 4);
-   strncpy((char *) nvram->driver_low, IPS_VERSION_LOW, 4);
-   strncpy((char *) nvram->bios_high, ha->bios_version, 4);
-   strncpy((char *) nvram->bios_low, ha->bios_version + 4, 4);
-}
-
-/****************************************************************************/
-/*                                                                          */
 /* Routine Name: ips_get_bios_version                                       */
 /*                                                                          */
 /* Routine Description:                                                     */
@@ -3280,10 +3463,10 @@
 ips_get_bios_version(ips_ha_t *ha, int intr) {
    ips_scb_t *scb;
    int        ret;
-   u_int8_t   major;
-   u_int8_t   minor;
-   u_int8_t   subminor;
-   u_int8_t  *buffer;
+   uint8_t   major;
+   uint8_t   minor;
+   uint8_t   subminor;
+   uint8_t  *buffer;
    char       hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 
    METHOD_TRACE("ips_get_bios_version", 1);
@@ -3300,35 +3483,35 @@
          /* test 1st byte */
          writel(0, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
             return;
 
-         writel(cpu_to_le32(1), ha->mem_ptr + IPS_REG_FLAP);
+         writel(1, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
             return;
 
          /* Get Major version */
-         writel(cpu_to_le32(0x1FF), ha->mem_ptr + IPS_REG_FLAP);
+         writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          major = readb(ha->mem_ptr + IPS_REG_FLDP);
 
          /* Get Minor version */
-         writel(cpu_to_le32(0x1FE), ha->mem_ptr + IPS_REG_FLAP);
+         writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          minor = readb(ha->mem_ptr + IPS_REG_FLDP);
 
          /* Get SubMinor version */
-         writel(cpu_to_le32(0x1FD), ha->mem_ptr + IPS_REG_FLAP);
+         writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
 
       } else {
@@ -3337,14 +3520,14 @@
          /* test 1st byte */
          outl(0, ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
             return ;
 
          outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
             return ;
@@ -3352,21 +3535,21 @@
          /* Get Major version */
          outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          major = inb(ha->io_addr + IPS_REG_FLDP);
 
          /* Get Minor version */
          outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          minor = inb(ha->io_addr + IPS_REG_FLDP);
 
          /* Get SubMinor version */
          outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          subminor = inb(ha->io_addr + IPS_REG_FLDP);
 
@@ -3569,9 +3752,8 @@
    Scsi_Cmnd            *q;
    ips_copp_wait_item_t *item;
    int                   ret;
-   int                   intr_status;
    unsigned long         cpu_flags;
-   unsigned long         cpu_flags2;
+   unsigned long         cpu_flags2 = 0;
 
    METHOD_TRACE("ips_next", 1);
 
@@ -3582,16 +3764,9 @@
     * Block access to the queue function so
     * this command won't time out
     */
-   if (intr == IPS_INTR_ON) {
+   if (intr == IPS_INTR_ON) 
        spin_lock_irqsave(&io_request_lock, cpu_flags2);
-       intr_status = IPS_INTR_IORL;
-   } else {
-       intr_status = intr;
-
-       /* Quiet the compiler */
-       cpu_flags2 = 0;
-   }
-
+   
    if ((ha->subsys->param[3] & 0x300000)  && ( ha->scb_activelist.count == 0 )) {
       struct timeval tv;
 
@@ -3601,7 +3776,7 @@
       if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
          ha->last_ffdc = tv.tv_sec;
          IPS_HA_UNLOCK(cpu_flags);
-         ips_ffdc_time(ha, intr_status);
+         ips_ffdc_time(ha);
       } else {
          IPS_HA_UNLOCK(cpu_flags);
       }
@@ -3610,7 +3785,6 @@
    if (intr == IPS_INTR_ON)
        spin_unlock_irqrestore(&io_request_lock, cpu_flags2);
 
-#ifndef NO_IPS_CMDLINE
    /*
     * Send passthru commands
     * These have priority over normal I/O
@@ -3641,7 +3815,7 @@
 
             /* raise the semaphore */
             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-               u_int32_t datasize;
+               uint32_t datasize;
 
                datasize = 0;
                memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
@@ -3659,7 +3833,7 @@
 
             /* raise the semaphore */
             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-               u_int32_t datasize;
+               uint32_t datasize;
 
                datasize = 0;
                memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
@@ -3680,7 +3854,7 @@
          IPS_QUEUE_LOCK(&ha->copp_waitlist);
          ha->num_ioctl--;
          continue;
-      }
+     }
 
       ret = ips_send_cmd(ha, scb);
 
@@ -3720,7 +3894,6 @@
 
    IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
    IPS_HA_UNLOCK(cpu_flags);
-#endif
 
    /*
     * Send "Normal" I/O commands
@@ -3767,33 +3940,33 @@
          int                 i;
 
          sg = SC->request_buffer;
-
-         if (SC->use_sg == 1) {
-            if (sg[0].length > ha->max_xfer) {
-               scb->breakup = 1;
+         scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg, PCI_DMA_BIDIRECTIONAL);
+         scb->flags |= IPS_SCB_MAP_SG;
+         if (scb->sg_count == 1) {
+            if (sg_dma_len(sg) > ha->max_xfer) {
+     	       scb->breakup = 1;
                scb->data_len = ha->max_xfer;
             } else
-               scb->data_len = sg[0].length;
+               scb->data_len = sg_dma_len(sg);
 
             scb->dcdb.transfer_length = scb->data_len;
-            scb->data_busaddr = VIRT_TO_BUS(sg[0].address);
+            scb->data_busaddr = sg_dma_address(sg);
             scb->sg_len = 0;
          } else {
             /* Check for the first Element being bigger than MAX_XFER */
-            if (sg[0].length > ha->max_xfer) {
-               scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[0].address));
+            if (sg_dma_len(&sg[0]) > ha->max_xfer) {
+               scb->sg_list[0].address = cpu_to_le32(sg_dma_address(&sg[0]));
                scb->sg_list[0].length = ha->max_xfer;
                scb->data_len = ha->max_xfer;
                scb->breakup = 0; 
                scb->sg_break=1;  
                scb->sg_len = 1;
-            }
-            else {
-               for (i = 0; i < SC->use_sg; i++) {
-                  scb->sg_list[i].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
-                  scb->sg_list[i].length = cpu_to_le32(sg[i].length);
+            } else {
+               for (i = 0; i < scb->sg_count; i++) {
+                  scb->sg_list[i].address = cpu_to_le32(sg_dma_address(&sg[i]));
+                  scb->sg_list[i].length = cpu_to_le32(sg_dma_len(&sg[i]));
             
-                  if (scb->data_len + sg[i].length > ha->max_xfer) {
+                  if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) {
                      /*
                       * Data Breakup required
                       */
@@ -3801,17 +3974,17 @@
                      break;
                   }
                
-                  scb->data_len += sg[i].length;
+                  scb->data_len += sg_dma_len(&sg[i]);
                }
 
                if (!scb->breakup)
-                  scb->sg_len = SC->use_sg;
+                  scb->sg_len = scb->sg_count;
                else
                   scb->sg_len = scb->breakup;
             }
 
             scb->dcdb.transfer_length = scb->data_len;
-            scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
+            scb->data_busaddr = scb->sg_busaddr;
          }
       } else {
          if (SC->request_bufflen) {
@@ -3826,7 +3999,9 @@
             }
 
             scb->dcdb.transfer_length = scb->data_len;
-            scb->data_busaddr = VIRT_TO_BUS(SC->request_buffer);
+            scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer,
+                                               scb->data_len, PCI_DMA_BIDIRECTIONAL);
+            scb->flags |= IPS_SCB_MAP_SINGLE;
             scb->sg_len = 0;
          } else {
             scb->data_busaddr = 0L;
@@ -4434,42 +4609,40 @@
    if (!scb)
       return ;
 
-#ifndef NO_IPS_CMDLINE
    if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
       ips_cleanup_passthru(ha, scb);
       IPS_HA_LOCK(cpu_flags);
       ha->num_ioctl--;
       IPS_HA_UNLOCK(cpu_flags);
    } else {
-#endif
       /*
        * Check to see if this command had too much
        * data and had to be broke up.  If so, queue
        * the rest of the data and continue.
        */
-      if (scb->breakup) {
+      if ((scb->breakup) || (scb->sg_break)) {
          /* we had a data breakup */
-         u_int8_t bk_save;
+         uint8_t bk_save;
 
          bk_save = scb->breakup;
          scb->breakup = 0;
 
-         if (scb->scsi_cmd->use_sg) {
+         if (scb->sg_count) {
             /* S/G request */
             struct scatterlist *sg;
             int                 i;
 
             sg = scb->scsi_cmd->request_buffer;
 
-            if (scb->scsi_cmd->use_sg == 1) {
-               if (sg[0].length - (bk_save * ha->max_xfer) > ha->max_xfer) {
+            if (scb->sg_count == 1) {
+               if (sg_dma_len(sg) - (bk_save * ha->max_xfer) > ha->max_xfer) {
                   /* Further breakup required */
                   scb->data_len = ha->max_xfer;
-                  scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
+                  scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer);
                   scb->breakup = bk_save + 1;
                } else {
-                  scb->data_len = sg[0].length - (bk_save * ha->max_xfer);
-                  scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
+                  scb->data_len = sg_dma_len(sg) - (bk_save * ha->max_xfer);
+                  scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer);
                }
 
                scb->dcdb.transfer_length = scb->data_len;
@@ -4486,45 +4659,46 @@
                /* pointed to by bk_save                                             */
                if (scb->sg_break) {
                   scb->sg_len = 1;
-        			   scb->sg_list[0].address = VIRT_TO_BUS(sg[bk_save].address+ha->max_xfer*scb->sg_break);
-                  if (ha->max_xfer > sg[bk_save].length-ha->max_xfer * scb->sg_break) 
-                     scb->sg_list[0].length = sg[bk_save].length-ha->max_xfer * scb->sg_break;
+                  scb->sg_list[0].address = sg_dma_address(&sg[bk_save])
+                                            + ha->max_xfer*scb->sg_break;
+                  if (ha->max_xfer > sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break) 
+                     scb->sg_list[0].length = sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break;
                   else 
                      scb->sg_list[0].length = ha->max_xfer;
                   scb->sg_break++;              /* MUST GO HERE for math below to work */
-			         scb->data_len = scb->sg_list[0].length;;
+                  scb->data_len = scb->sg_list[0].length;;
 
-		            if (sg[bk_save].length <= ha->max_xfer * scb->sg_break ) {
+                  if (sg_dma_len(&sg[bk_save]) <= ha->max_xfer * scb->sg_break ) {
                      scb->sg_break = 0;         /* No more work in this unit */
-                     if (( bk_save + 1 ) >= scb->scsi_cmd->use_sg) 
+                     if (( bk_save + 1 ) >= scb->sg_count) 
                         scb->breakup = 0;
-                     else 
+                     else
                         scb->breakup = bk_save + 1;
                   }
                } else {
 			         /* ( sg_break == 0 ), so this is our first look at a new sg piece */
-                  if (sg[bk_save].length > ha->max_xfer) {
-			            scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[bk_save].address));
-				         scb->sg_list[0].length = ha->max_xfer;
-				         scb->breakup = bk_save;
-				         scb->sg_break = 1;
-				         scb->data_len = ha->max_xfer;
-				         scb->sg_len = 1;
- 	        		   } else {
-				         /* OK, the next sg is a short one, so loop until full */
-			            scb->data_len = 0;
-		     	         scb->sg_len = 0;
-      			      scb->sg_break = 0;
+                  if (sg_dma_len(&sg[bk_save]) > ha->max_xfer) {
+                     scb->sg_list[0].address = sg_dma_address(&sg[bk_save]);
+                     scb->sg_list[0].length = ha->max_xfer;
+                     scb->breakup = bk_save;
+                     scb->sg_break = 1;
+                     scb->data_len = ha->max_xfer;
+                     scb->sg_len = 1;
+ 	          } else {
+	         /* OK, the next sg is a short one, so loop until full */
+                     scb->data_len = 0;
+                     scb->sg_len = 0;
+                     scb->sg_break = 0;
                      /*   We're only doing full units here */
-				         for (i = bk_save; i < scb->scsi_cmd->use_sg; i++) {
-					         scb->sg_list[i - bk_save].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
-				            scb->sg_list[i - bk_save].length = cpu_to_le32(sg[i].length);
-                        if (scb->data_len + sg[i].length > ha->max_xfer) {
-					            scb->breakup = i;  /* sneaky, if not more work, than breakup is 0 */
-					            break;
-					         }
-					         scb->data_len += sg[i].length;
-					         scb->sg_len++;           /* only if we didn't get too big */
+                     for (i = bk_save; i < scb->sg_count; i++) {
+                        scb->sg_list[i - bk_save].address = sg_dma_address(&sg[i]);
+                        scb->sg_list[i - bk_save].length = cpu_to_le32(sg_dma_len(&sg[i]));
+                        if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) {
+                           scb->breakup = i;  /* sneaky, if not more work, than breakup is 0 */
+                           break;
+                        }
+                        scb->data_len += sg_dma_len(&sg[i]);
+                        scb->sg_len++;           /* only if we didn't get too big */
 		  		         }
 			         }
 		         }
@@ -4532,20 +4706,22 @@
                /* Also, we need to be sure we don't queue work ( breakup != 0 )
                   if no more sg units for next time */
                scb->dcdb.transfer_length = scb->data_len;
-               scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
+               scb->data_busaddr = scb->sg_busaddr;
             }
                                               
-             } else {
+         } else {
             /* Non S/G Request */
+            pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
+                             PCI_DMA_BIDIRECTIONAL);
             if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) {
                /* Further breakup required */
                scb->data_len = ha->max_xfer;
-               scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer));
+               scb->data_busaddr = pci_map_single(ha->pcidev, scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer), scb->data_len, PCI_DMA_BIDIRECTIONAL);
                scb->breakup = bk_save + 1;
             } else {
                scb->data_len = scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer);
-               scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer));
-            }
+               scb->data_busaddr = pci_map_single(ha->pcidev, scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer), scb->data_len, PCI_DMA_BIDIRECTIONAL);
+	    }
 
             scb->dcdb.transfer_length = scb->data_len;
             scb->sg_len = 0;
@@ -4587,9 +4763,7 @@
 
          return ;
       }
-#ifndef NO_IPS_CMDLINE
    } /* end if passthru */
-#endif
 
    if (scb->bus) {
       IPS_HA_LOCK(cpu_flags);
@@ -4742,6 +4916,8 @@
 /*                                                                          */
 /*   Send a command to the controller and wait for it to return             */
 /*                                                                          */
+/*   The FFDC Time Stamp use this function for the callback, but doesn't    */
+/*   actually need to wait.                                                 */
 /****************************************************************************/
 static int
 ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) {
@@ -4749,15 +4925,18 @@
 
    METHOD_TRACE("ips_send_wait", 1);
 
-   ha->waitflag = TRUE;
-   ha->cmd_in_progress = scb->cdb[0];
+   if (intr != IPS_FFDC) {      /* Won't be Waiting if this is a Time Stamp */
+      ha->waitflag = TRUE;
+      ha->cmd_in_progress = scb->cdb[0];
+    }
 
    ret = ips_send(ha, scb, ipsintr_blocking);
 
    if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
       return (ret);
 
-   ret = ips_wait(ha, timeout, intr);
+   if (intr != IPS_FFDC)       /* Don't Wait around if this is a Time Stamp */
+      ret = ips_wait(ha, timeout, intr);
 
    return (ret);
 }
@@ -4794,11 +4973,7 @@
 
          return (1);
       }
-#ifndef NO_IPS_CMDLINE
    } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
-#else
-   } else if (scb->bus == 0) {
-#endif
       /* command to logical bus -- interpret */
       ret = IPS_SUCCESS_IMM;
 
@@ -5046,8 +5221,8 @@
 ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
    ips_scb_t  *scb;
    ips_stat_t *sp;
-   u_int8_t    basic_status;
-   u_int8_t    ext_status;
+   uint8_t     basic_status;
+   uint8_t     ext_status;
    int         errcode;
 
    METHOD_TRACE("ips_chkstatus", 1);
@@ -5076,11 +5251,9 @@
              scb->target_id,
              scb->lun);
 
-#ifndef NO_IPS_CMDLINE
    if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
       /* passthru - just returns the raw result */
       return ;
-#endif
 
    errcode = DID_OK;
 
@@ -5270,7 +5443,7 @@
    cap = (IPS_SCSI_CAPACITY *) scb->scsi_cmd->request_buffer;
 
    cap->lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1);
-   cap->len = cpu_to_be32((u_int32_t) IPS_BLKSIZE);
+   cap->len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
 
    return (1);
 }
@@ -5286,9 +5459,9 @@
 /****************************************************************************/
 static int
 ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
-   u_int16_t               heads;
-   u_int16_t               sectors;
-   u_int32_t               cylinders;
+   uint16_t               heads;
+   uint16_t               sectors;
+   uint32_t               cylinders;
    IPS_SCSI_MODE_PAGE_DATA mdata;
 
    METHOD_TRACE("ips_msense", 1);
@@ -5391,7 +5564,6 @@
 /****************************************************************************/
 static void
 ips_free(ips_ha_t *ha) {
-   int i;
 
    METHOD_TRACE("ips_free", 1);
 
@@ -5432,16 +5604,7 @@
          ha->ioctl_datasize = 0;
          ha->ioctl_order = 0;
       }
-
-      if (ha->scbs) {
-         for (i = 0; i < ha->max_cmds; i++) {
-            if (ha->scbs[i].sg_list)
-               kfree(ha->scbs[i].sg_list);
-         }
-
-         kfree(ha->scbs);
-         ha->scbs = NULL;
-      } /* end if */
+      ips_deallocatescbs(ha, ha->max_cmds);
 
       /* free memory mapped (if applicable) */
       if (ha->mem_ptr) {
@@ -5450,7 +5613,7 @@
          ha->mem_ptr = NULL;
       }
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
       if (ha->mem_addr) 
           release_mem_region(ha->mem_addr, ha->mem_len);
 #endif
@@ -5458,6 +5621,26 @@
 
    }
 }
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_deallocatescbs                                         */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Free the command blocks                                                */
+/*                                                                          */
+/****************************************************************************/
+static int
+ips_deallocatescbs(ips_ha_t *ha, int cmds) {
+   if (ha->scbs) {
+      pci_free_consistent(ha->pcidev,sizeof(IPS_SG_LIST) * IPS_MAX_SG *
+                          cmds, ha->scbs->sg_list, ha->scbs->sg_busaddr);
+      pci_free_consistent(ha->pcidev, sizeof(ips_scb_t) * cmds,
+                          ha->scbs, ha->scbs->scb_busaddr);
+      ha->scbs = NULL;
+   } /* end if */
+return 1;
+}
 
 /****************************************************************************/
 /*                                                                          */
@@ -5471,25 +5654,32 @@
 static int
 ips_allocatescbs(ips_ha_t *ha) {
    ips_scb_t *scb_p;
+   IPS_SG_LIST* ips_sg;
    int        i;
-
+   dma_addr_t command_dma, sg_dma;
+   
    METHOD_TRACE("ips_allocatescbs", 1);
 
-   /* Allocate memory for the CCBs */
-   ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_KERNEL);
+   /* Allocate memory for the SCBs */
+   ha->scbs = pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof(ips_scb_t),
+	                           &command_dma);
    if (ha->scbs == NULL)
       return 0;
+   ips_sg = pci_alloc_consistent(ha->pcidev, sizeof(IPS_SG_LIST) * IPS_MAX_SG * 
+	                         ha->max_cmds, &sg_dma);
+   if(ips_sg == NULL){
+      pci_free_consistent(ha->pcidev,ha->max_cmds * sizeof(ips_scb_t),ha->scbs, command_dma);
+      return 0;
+   }
 
    memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t));
 
    for (i = 0; i < ha->max_cmds; i++) {
       scb_p = &ha->scbs[i];
-
-      /* allocate S/G list */
-      scb_p->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_ATOMIC);
-
-      if (! scb_p->sg_list)
-         return (0);
+      scb_p->scb_busaddr = command_dma + sizeof(ips_scb_t) * i;
+      /* set up S/G list */
+      scb_p->sg_list = ips_sg + i * IPS_MAX_SG;
+      scb_p->sg_busaddr = sg_dma + sizeof(IPS_SG_LIST) * IPS_MAX_SG * i;
 
       /* add to the free list */
       if (i < ha->max_cmds - 1) {
@@ -5514,14 +5704,15 @@
 static void
 ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
    IPS_SG_LIST *sg_list;
-
+   uint32_t cmd_busaddr, sg_busaddr;
    METHOD_TRACE("ips_init_scb", 1);
 
    if (scb == NULL)
       return ;
 
    sg_list = scb->sg_list;
-
+   cmd_busaddr = scb->scb_busaddr;
+   sg_busaddr = scb->sg_busaddr;
    /* zero fill */
    memset(scb, 0, sizeof(ips_scb_t));
    memset(ha->dummy, 0, sizeof(IPS_IO_CMD));
@@ -5532,11 +5723,12 @@
    ha->dummy->command_id = IPS_MAX_CMDS;
 
    /* set bus address of scb */
-   scb->scb_busaddr = VIRT_TO_BUS(scb);
+   scb->scb_busaddr = cmd_busaddr;
+   scb->sg_busaddr = sg_busaddr;
    scb->sg_list = sg_list;
 
    /* Neptune Fix */
-   scb->cmd.basic_io.cccr = cpu_to_le32((u_int32_t) IPS_BIT_ILE);
+   scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
    scb->cmd.basic_io.ccsar = cpu_to_le32(VIRT_TO_BUS(ha->dummy));
 }
 
@@ -5591,6 +5783,10 @@
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_freescb", 1);
+   if(scb->flags & IPS_SCB_MAP_SG)
+      pci_unmap_sg(ha->pcidev,scb->scsi_cmd->request_buffer, scb->scsi_cmd->use_sg, PCI_DMA_BIDIRECTIONAL); 
+   else if(scb->flags & IPS_SCB_MAP_SINGLE)
+      pci_unmap_single(ha->pcidev,scb->cmd.basic_io.sg_addr, scb->data_len, PCI_DMA_BIDIRECTIONAL);
 
    /* check to make sure this is not our "special" scb */
    if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
@@ -5607,13 +5803,13 @@
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
-/*   Reset the controller                                                   */
+/*   Is controller initialized ?                                            */
 /*                                                                          */
 /****************************************************************************/
 static int
 ips_isinit_copperhead(ips_ha_t *ha) {
-   u_int8_t scpr;
-   u_int8_t isr;
+   uint8_t scpr;
+   uint8_t isr;
 
    METHOD_TRACE("ips_isinit_copperhead", 1);
 
@@ -5632,13 +5828,13 @@
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
-/*   Reset the controller                                                   */
+/*   Is controller initialized ?                                            */
 /*                                                                          */
 /****************************************************************************/
 static int
 ips_isinit_copperhead_memio(ips_ha_t *ha) {
-   u_int8_t isr=0;
-   u_int8_t scpr;
+   uint8_t isr=0;
+   uint8_t scpr;
 
    METHOD_TRACE("ips_is_init_copperhead_memio", 1);
 
@@ -5657,18 +5853,18 @@
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
-/*   Reset the controller                                                   */
+/*   Is controller initialized ?                                            */
 /*                                                                          */
 /****************************************************************************/
 static int
 ips_isinit_morpheus(ips_ha_t *ha) {
-   u_int32_t post;
-   u_int32_t bits;
+   uint32_t post;
+   uint32_t bits;
 
    METHOD_TRACE("ips_is_init_morpheus", 1);
 
-   post = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG0));
-   bits = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
+   post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
+   bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
 
    if (post == 0)
        return (0);
@@ -5718,13 +5914,13 @@
 /****************************************************************************/
 static void
 ips_enable_int_morpheus(ips_ha_t *ha) {
-   u_int32_t  Oimr;
+   uint32_t  Oimr;
 
    METHOD_TRACE("ips_enable_int_morpheus", 1);
 
-   Oimr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_OIMR));
+   Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
    Oimr &= ~0x08;
-   writel(cpu_to_le32(Oimr), ha->mem_ptr + IPS_REG_I960_OIMR);
+   writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
 }
 
 /****************************************************************************/
@@ -5738,11 +5934,11 @@
 /****************************************************************************/
 static int
 ips_init_copperhead(ips_ha_t *ha) {
-   u_int8_t  Isr;
-   u_int8_t  Cbsp;
-   u_int8_t  PostByte[IPS_MAX_POST_BYTES];
-   u_int8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
-   int i, j;
+   uint8_t  Isr;
+   uint8_t  Cbsp;
+   uint8_t  PostByte[IPS_MAX_POST_BYTES];
+   uint8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
+   int      i, j;
 
    METHOD_TRACE("ips_init_copperhead", 1);
 
@@ -5752,8 +5948,9 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
+         /* Delay for 1 Second */
          MDELAY(IPS_ONE_SEC);
-      }
+       }
 
       if (j >= 45)
          /* error occurred */
@@ -5776,7 +5973,8 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
-         MDELAY(IPS_ONE_SEC);    /* 1 sec */
+         /* Delay for 1 Second */
+         MDELAY(IPS_ONE_SEC);
       }
 
       if (j >= 240)
@@ -5791,8 +5989,9 @@
       Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
 
       if ((Cbsp & IPS_BIT_OP) == 0)
-         break;
+         break; 
 
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
    }
 
@@ -5827,11 +6026,11 @@
 /****************************************************************************/
 static int
 ips_init_copperhead_memio(ips_ha_t *ha) {
-   u_int8_t  Isr=0;
-   u_int8_t  Cbsp;
-   u_int8_t  PostByte[IPS_MAX_POST_BYTES];
-   u_int8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
-   int i, j;
+   uint8_t  Isr=0;
+   uint8_t  Cbsp;
+   uint8_t  PostByte[IPS_MAX_POST_BYTES];
+   uint8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
+   int      i, j;
 
    METHOD_TRACE("ips_init_copperhead_memio", 1);
 
@@ -5841,6 +6040,7 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
+         /* Delay for 1 Second */
          MDELAY(IPS_ONE_SEC);
       }
 
@@ -5865,7 +6065,8 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
-         MDELAY(IPS_ONE_SEC); /* 100 msec */
+         /* Delay for 1 Second */
+         MDELAY(IPS_ONE_SEC);
       }
 
       if (j >= 240)
@@ -5882,6 +6083,7 @@
       if ((Cbsp & IPS_BIT_OP) == 0)
          break;
 
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
    }
 
@@ -5890,7 +6092,7 @@
       return (0);
 
    /* setup CCCR */
-   writel(cpu_to_le32(0x1010), ha->mem_ptr + IPS_REG_CCCR);
+   writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
 
    /* Enable busmastering */
    writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
@@ -5917,21 +6119,22 @@
 /****************************************************************************/
 static int
 ips_init_morpheus(ips_ha_t *ha) {
-   u_int32_t Post;
-   u_int32_t Config;
-   u_int32_t Isr;
-   u_int32_t Oimr;
+   uint32_t  Post;
+   uint32_t  Config;
+   uint32_t  Isr;
+   uint32_t  Oimr;
    int       i;
 
    METHOD_TRACE("ips_init_morpheus", 1);
 
    /* Wait up to 45 secs for Post */
    for (i = 0; i < 45; i++) {
-      Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
+      Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
 
       if (Isr & IPS_BIT_I960_MSG0I)
          break;
 
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
    }
 
@@ -5943,11 +6146,11 @@
       return (0);
    }
 
-   Post = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG0));
+   Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
 
    /* Clear the interrupt bit */
-   Isr = (u_int32_t) IPS_BIT_I960_MSG0I;
-   writel(cpu_to_le32(Isr), ha->mem_ptr + IPS_REG_I2O_HIR);
+   Isr = (uint32_t) IPS_BIT_I960_MSG0I;
+   writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
 
    if (Post < (IPS_GOOD_POST_STATUS << 8)) {
       printk(KERN_WARNING "(%s%d) reset controller fails (post status %x).\n",
@@ -5958,12 +6161,13 @@
 
    /* Wait up to 240 secs for config bytes */
    for (i = 0; i < 240; i++) {
-      Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
+      Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
 
       if (Isr & IPS_BIT_I960_MSG1I)
          break;
 
-      MDELAY(IPS_ONE_SEC); /* 100 msec */
+      /* Delay for 1 Second */
+      MDELAY(IPS_ONE_SEC);
    }
 
    if (i >= 240) {
@@ -5974,16 +6178,16 @@
       return (0);
    }
 
-   Config = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG1));
+   Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
 
    /* Clear interrupt bit */
-   Isr = (u_int32_t) IPS_BIT_I960_MSG1I;
-   writel(cpu_to_le32(Isr), ha->mem_ptr + IPS_REG_I2O_HIR);
+   Isr = (uint32_t) IPS_BIT_I960_MSG1I;
+   writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
 
    /* Turn on the interrupts */
-   Oimr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_OIMR));
+   Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
    Oimr &= ~0x8;
-   writel(cpu_to_le32(Oimr), ha->mem_ptr + IPS_REG_I960_OIMR);
+   writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
 
    /* if we get here then everything went OK */
    return (1);
@@ -6016,10 +6220,15 @@
       reset_counter++;
 
       outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
+
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
+ 
       outb(0, ha->io_addr + IPS_REG_SCPR);
-      MDELAY(IPS_ONE_SEC);
 
+      /* Delay for 1 Second */
+      MDELAY(IPS_ONE_SEC);
+      
       if ((*ha->func.init)(ha))
          break;
       else if (reset_counter >= 2) {
@@ -6061,10 +6270,15 @@
       reset_counter++;
 
       writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
+
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
+ 
       writeb(0, ha->mem_ptr + IPS_REG_SCPR);
-      MDELAY(IPS_ONE_SEC);
 
+      /* Delay for 1 Second */
+      MDELAY(IPS_ONE_SEC);
+ 
       if ((*ha->func.init)(ha))
          break;
       else if (reset_counter >= 2) {
@@ -6091,7 +6305,7 @@
 static int
 ips_reset_morpheus(ips_ha_t *ha) {
    int           reset_counter;
-   u_int8_t      junk;
+   uint8_t       junk;
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_reset_morpheus", 1);
@@ -6106,11 +6320,11 @@
    while (reset_counter < 2) {
       reset_counter++;
 
-      writel(cpu_to_le32(0x80000000), ha->mem_ptr + IPS_REG_I960_IDR);
+      writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
 
-      /* Delay for 5 sec */
+      /* Delay for 5 Seconds */
       MDELAY(5 * IPS_ONE_SEC);
-
+ 
       /* Do a PCI config read to wait for adapter */
       pci_read_config_byte(ha->pcidev, 4, &junk);
 
@@ -6139,7 +6353,7 @@
 /****************************************************************************/
 static void
 ips_statinit(ips_ha_t *ha) {
-   u_int32_t phys_status_start;
+   uint32_t phys_status_start;
 
    METHOD_TRACE("ips_statinit", 1);
 
@@ -6168,7 +6382,7 @@
 /****************************************************************************/
 static void
 ips_statinit_memio(ips_ha_t *ha) {
-   u_int32_t phys_status_start;
+   uint32_t phys_status_start;
 
    METHOD_TRACE("ips_statinit_memio", 1);
 
@@ -6177,10 +6391,10 @@
    ha->adapt->p_status_tail = ha->adapt->status;
 
    phys_status_start = VIRT_TO_BUS(ha->adapt->status);
-   writel(cpu_to_le32(phys_status_start), ha->mem_ptr + IPS_REG_SQSR);
-   writel(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->mem_ptr + IPS_REG_SQER);
-   writel(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->mem_ptr + IPS_REG_SQHR);
-   writel(cpu_to_le32(phys_status_start), ha->mem_ptr + IPS_REG_SQTR);
+   writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
+   writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER);
+   writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
+   writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
 
    ha->adapt->hw_status_start = phys_status_start;
    ha->adapt->hw_status_tail = phys_status_start;
@@ -6195,7 +6409,7 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u_int32_t
+static uint32_t
 ips_statupd_copperhead(ips_ha_t *ha) {
    METHOD_TRACE("ips_statupd_copperhead", 1);
 
@@ -6221,7 +6435,7 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u_int32_t
+static uint32_t
 ips_statupd_copperhead_memio(ips_ha_t *ha) {
    METHOD_TRACE("ips_statupd_copperhead_memio", 1);
 
@@ -6233,7 +6447,7 @@
       ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
    }
 
-   writel(cpu_to_le32(ha->adapt->hw_status_tail), ha->mem_ptr + IPS_REG_SQTR);
+   writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
 
    return (ha->adapt->p_status_tail->value);
 }
@@ -6247,13 +6461,13 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u_int32_t
+static uint32_t
 ips_statupd_morpheus(ips_ha_t *ha) {
-   u_int32_t val;
+   uint32_t val;
 
    METHOD_TRACE("ips_statupd_morpheus", 1);
 
-   val = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ));
+   val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
 
    return (val);
 }
@@ -6269,8 +6483,8 @@
 /****************************************************************************/
 static int
 ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
-   u_int32_t TimeOut;
-   u_int32_t val;
+   uint32_t TimeOut;
+   uint32_t val;
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_issue_copperhead", 1);
@@ -6332,8 +6546,8 @@
 /****************************************************************************/
 static int
 ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
-   u_int32_t     TimeOut;
-   u_int32_t     val;
+   uint32_t      TimeOut;
+   uint32_t      val;
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_issue_copperhead_memio", 1);
@@ -6358,7 +6572,7 @@
 
    TimeOut = 0;
 
-   while ((val = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
+   while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
       udelay(1000);
 
       if (++TimeOut >= IPS_SEM_TIMEOUT) {
@@ -6376,8 +6590,8 @@
       } /* end if */
    } /* end while */
 
-   writel(cpu_to_le32(scb->scb_busaddr), ha->mem_ptr + IPS_REG_CCSAR);
-   writel(cpu_to_le32(IPS_BIT_START_CMD), ha->mem_ptr + IPS_REG_CCCR);
+   writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
+   writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
 
    IPS_HA_UNLOCK(cpu_flags);
 
@@ -6457,7 +6671,7 @@
 
    IPS_HA_LOCK(cpu_flags);
 
-   writel(cpu_to_le32(scb->scb_busaddr), ha->mem_ptr + IPS_REG_I2O_INMSGQ);
+   writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
 
    IPS_HA_UNLOCK(cpu_flags);
 
@@ -6475,7 +6689,7 @@
 /****************************************************************************/
 static int
 ips_isintr_copperhead(ips_ha_t *ha) {
-   u_int8_t Isr;
+   uint8_t Isr;
 
    METHOD_TRACE("ips_isintr_copperhead", 2);
 
@@ -6507,7 +6721,7 @@
 /****************************************************************************/
 static int
 ips_isintr_copperhead_memio(ips_ha_t *ha) {
-   u_int8_t Isr;
+   uint8_t Isr;
 
    METHOD_TRACE("ips_isintr_memio", 2);
 
@@ -6539,11 +6753,11 @@
 /****************************************************************************/
 static int
 ips_isintr_morpheus(ips_ha_t *ha) {
-   u_int32_t Isr;
+   uint32_t Isr;
 
    METHOD_TRACE("ips_isintr_morpheus", 2);
 
-   Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
+   Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
 
    if (Isr & IPS_BIT_I2O_OPQI)
       return (1);
@@ -6562,15 +6776,15 @@
 /****************************************************************************/
 static int
 ips_wait(ips_ha_t *ha, int time, int intr) {
-   int        ret;
-   u_int8_t   done;
+   int   ret;
+   int   done;
 
    METHOD_TRACE("ips_wait", 1);
 
    ret = IPS_FAILURE;
    done = FALSE;
 
-   time *= IPS_ONE_SEC; /* convert seconds to milliseconds */
+   time *= IPS_ONE_SEC;                       /* convert seconds */
 
    while ((time > 0) && (!done)) {
       if (intr == IPS_INTR_ON) {
@@ -6603,37 +6817,10 @@
          (*ha->func.intr)(ha);
 
          clear_bit(IPS_IN_INTR, &ha->flags);
-      } else if (intr == IPS_INTR_HAL) {
-         if (ha->waitflag == FALSE) {
-            /*
-             * controller generated an interrupt to
-             * acknowledge completion of the command
-             * and ips_intr() has serviced the interrupt.
-             */
-            ret = IPS_SUCCESS;
-            done = TRUE;
-            break;
-         }
+      } 
 
-         /*
-          * NOTE: since we were not called with the iorequest lock
-          * we must obtain it before we can call the interrupt handler.
-          * We were called under the HA lock so we can assume that interrupts
-          * are masked.
-          */
-         spin_lock(&io_request_lock);
-
-         while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
-            udelay(1000);
-
-         (*ha->func.intr)(ha);
-
-         clear_bit(IPS_IN_INTR, &ha->flags);
-
-         spin_unlock(&io_request_lock);
-      }
-
-      udelay(1000); /* 1 milisecond */
+      /* This looks like a very evil loop, but it only does this during start-up */
+      udelay(1000);        
       time--;
    }
 
@@ -6687,6 +6874,8 @@
    strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
    strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
 
+   ips_version_check(ha, intr);                           /* Check BIOS/FW/Driver Versions */
+
    /* now update the page */
    if (!ips_readwrite_page5(ha, TRUE, intr)) {
       printk(KERN_WARNING "(%s%d) unable to write NVRAM page 5.\n",
@@ -6827,6 +7016,10 @@
       for (i = 0; i < 4; i++)
          ha->conf->init_id[i] = 7;
 
+      /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */
+      if ((scb->basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_CMPLT_WERROR)   
+         return (1);                      
+      
       return (0);
    }
 
@@ -6980,7 +7173,7 @@
 /*                                                                          */
 /****************************************************************************/
 static void
-ips_ffdc_time(ips_ha_t *ha, int intr) {
+ips_ffdc_time(ips_ha_t *ha) {
    ips_scb_t *scb;
 
    METHOD_TRACE("ips_ffdc_time", 1);
@@ -7003,7 +7196,7 @@
    ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
 
    /* issue command */
-   ips_send_wait(ha, scb, ips_cmd_timeout, intr);
+   ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC);
 }
 
 /****************************************************************************/
@@ -7083,7 +7276,7 @@
 static int
 ips_erase_bios(ips_ha_t *ha) {
    int      timeout;
-   u_int8_t status=0;
+   uint8_t  status=0;
 
    METHOD_TRACE("ips_erase_bios", 1);
 
@@ -7092,33 +7285,33 @@
    /* Clear the status register */
    outl(0, ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    outb(0x50, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Setup */
    outb(0x20, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Confirm */
    outb(0xD0, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Status */
    outb(0x70, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    timeout = 80000; /* 80 seconds */
 
    while (timeout > 0) {
       if (ha->revision_id == IPS_REVID_TROMBONE64) {
          outl(0, ha->io_addr + IPS_REG_FLAP);
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
       }
 
       status = inb(ha->io_addr + IPS_REG_FLDP);
@@ -7137,14 +7330,14 @@
       /* try to suspend the erase */
       outb(0xB0, ha->io_addr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       /* wait for 10 seconds */
       timeout = 10000;
       while (timeout > 0) {
          if (ha->revision_id == IPS_REVID_TROMBONE64) {
             outl(0, ha->io_addr + IPS_REG_FLAP);
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          }
 
          status = inb(ha->io_addr + IPS_REG_FLDP);
@@ -7173,12 +7366,12 @@
    /* clear status */
    outb(0x50, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* enable reads */
    outb(0xFF, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    return (0);
 }
@@ -7194,7 +7387,7 @@
 static int
 ips_erase_bios_memio(ips_ha_t *ha) {
    int      timeout;
-   u_int8_t status;
+   uint8_t  status;
 
    METHOD_TRACE("ips_erase_bios_memio", 1);
 
@@ -7203,33 +7396,33 @@
    /* Clear the status register */
    writel(0, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Setup */
    writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Confirm */
    writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Status */
    writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    timeout = 80000; /* 80 seconds */
 
    while (timeout > 0) {
       if (ha->revision_id == IPS_REVID_TROMBONE64) {
          writel(0, ha->mem_ptr + IPS_REG_FLAP);
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
       }
 
       status = readb(ha->mem_ptr + IPS_REG_FLDP);
@@ -7248,14 +7441,14 @@
       /* try to suspend the erase */
       writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       /* wait for 10 seconds */
       timeout = 10000;
       while (timeout > 0) {
          if (ha->revision_id == IPS_REVID_TROMBONE64) {
             writel(0, ha->mem_ptr + IPS_REG_FLAP);
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          }
 
          status = readb(ha->mem_ptr + IPS_REG_FLDP);
@@ -7284,12 +7477,12 @@
    /* clear status */
    writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* enable reads */
    writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    return (0);
 }
@@ -7303,10 +7496,10 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_program_bios(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
+ips_program_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
    int      i;
    int      timeout;
-   u_int8_t status=0;
+   uint8_t  status=0;
 
    METHOD_TRACE("ips_program_bios", 1);
 
@@ -7316,22 +7509,22 @@
       /* write a byte */
       outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       outb(0x40, ha->io_addr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       /* wait up to one second */
       timeout = 1000;
       while (timeout > 0) {
          if (ha->revision_id == IPS_REVID_TROMBONE64) {
             outl(0, ha->io_addr + IPS_REG_FLAP);
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          }
 
          status = inb(ha->io_addr + IPS_REG_FLDP);
@@ -7347,11 +7540,11 @@
          /* timeout error */
          outl(0, ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          outb(0xFF, ha->io_addr + IPS_REG_FLDP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          return (1);
       }
@@ -7361,11 +7554,11 @@
          /* programming error */
          outl(0, ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          outb(0xFF, ha->io_addr + IPS_REG_FLDP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          return (1);
       }
@@ -7374,11 +7567,11 @@
    /* Enable reading */
    outl(0, ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    outb(0xFF, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    return (0);
 }
@@ -7392,10 +7585,10 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_program_bios_memio(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
+ips_program_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
    int      i;
    int      timeout;
-   u_int8_t status=0;
+   uint8_t  status=0;
 
    METHOD_TRACE("ips_program_bios_memio", 1);
 
@@ -7403,24 +7596,24 @@
 
    for (i = 0; i < buffersize; i++) {
       /* write a byte */
-      writel(cpu_to_le32(i + offset), ha->mem_ptr + IPS_REG_FLAP);
+      writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       /* wait up to one second */
       timeout = 1000;
       while (timeout > 0) {
          if (ha->revision_id == IPS_REVID_TROMBONE64) {
             writel(0, ha->mem_ptr + IPS_REG_FLAP);
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          }
 
          status = readb(ha->mem_ptr + IPS_REG_FLDP);
@@ -7436,11 +7629,11 @@
          /* timeout error */
          writel(0, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          return (1);
       }
@@ -7450,11 +7643,11 @@
          /* programming error */
          writel(0, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          return (1);
       }
@@ -7463,11 +7656,11 @@
    /* Enable reading */
    writel(0, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    return (0);
 }
@@ -7481,8 +7674,8 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_verify_bios(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
-   u_int8_t checksum;
+ips_verify_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
+   uint8_t  checksum;
    int      i;
 
    METHOD_TRACE("ips_verify_bios", 1);
@@ -7490,14 +7683,14 @@
    /* test 1st byte */
    outl(0, ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
       return (1);
 
    outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
    if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
       return (1);
 
@@ -7506,9 +7699,9 @@
 
       outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
-      checksum = (u_int8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
+      checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
    }
 
    if (checksum != 0)
@@ -7528,8 +7721,8 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
-   u_int8_t checksum;
+ips_verify_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
+   uint8_t  checksum;
    int      i;
 
    METHOD_TRACE("ips_verify_bios_memio", 1);
@@ -7537,25 +7730,25 @@
    /* test 1st byte */
    writel(0, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
       return (1);
 
    writel(1, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
    if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
       return (1);
 
    checksum = 0xff;
    for (i = 2; i < buffersize; i++) {
 
-      writel(cpu_to_le32(i + offset), ha->mem_ptr + IPS_REG_FLAP);
+      writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
-      checksum = (u_int8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
+      checksum = (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
    }
 
    if (checksum != 0)
@@ -7566,11 +7759,589 @@
       return (0);
 }
 
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_version_check                                         */
+/*                                                                           */
+/*   Dependencies:                                                           */
+/*     Assumes that ips_read_adapter_status() is called first filling in     */
+/*     the data for SubSystem Parameters.                                    */
+/*     Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */
+/*     Data is availaible.                                                   */
+/*                                                                           */
+/*---------------------------------------------------------------------------*/
+static void ips_version_check(ips_ha_t *ha, int intr) {
+ IPS_VERSION_DATA VersionInfo;
+ uint8_t  FirmwareVersion[ IPS_COMPAT_ID_LENGTH + 1 ];
+ uint8_t  BiosVersion[ IPS_COMPAT_ID_LENGTH + 1];
+ int      MatchError;
+ int      rc;
+
+ METHOD_TRACE("ips_version_check", 1);
+
+ memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
+ memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
+
+ /* Get the Compatible BIOS Version from NVRAM Page 5 */
+ memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, IPS_COMPAT_ID_LENGTH);
+ 
+ rc = IPS_FAILURE;
+ if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT)  /* If Versioning is Supported */
+ {
+     /* Get the Version Info with a Get Version Command */
+     rc = ips_get_version_info(ha, &VersionInfo, intr);
+     if  (rc == IPS_SUCCESS)
+        memcpy(FirmwareVersion, VersionInfo.compatibilityId, IPS_COMPAT_ID_LENGTH);
+ }
+
+ if  (rc != IPS_SUCCESS)      /* If Data Not Obtainable from a GetVersion Command */
+ {
+     /* Get the Firmware Version from Enquiry Data */
+     memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, IPS_COMPAT_ID_LENGTH);
+ }
+
+ /* printk(KERN_WARNING "Adapter's BIOS Version  = %s\n", BiosVersion);          */
+ /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS);      */
+ /* printk(KERN_WARNING "Adapter's Firmware Version  = %s\n", FirmwareVersion);  */
+ /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */
+
+ MatchError = 0;
+
+ if  (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0)
+ {
+     /* if (ips_cd_boot == 0)                                                                              */
+     /*   printk(KERN_WARNING "Warning: Adapter %d Firmware Compatible Version is %s, but should be %s\n", */
+     /*          ha->host_num, FirmwareVersion, Compatable[ ha->nvram->adapter_type ]);                    */
+     MatchError = 1;
+ }
+
+ if  (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
+ {
+     /* if (ips_cd_boot == 0)                                                                          */
+     /*   printk(KERN_WARNING "Warning: Adapter %d BIOS Compatible Version is %s, but should be %s\n", */
+     /*          ha->host_num, BiosVersion, IPS_COMPAT_BIOS);                                          */
+     MatchError = 1;
+ }
+
+ ha->nvram->versioning = 1;          /* Indicate the Driver Supports Versioning */
+
+ if  (MatchError)
+ {
+     ha->nvram->version_mismatch = 1;
+     /* if (ips_cd_boot == 0)                                               */
+     /*  printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n"); */
+ }
+ else
+ {
+     ha->nvram->version_mismatch = 0;
+ }
+
+ return;
+}
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_get_version_info                                      */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Issue an internal GETVERSION ServeRAID Command                        */
+/*                                                                           */
+/*   Return Value:                                                           */
+/*     0 if Successful, else non-zero                                        */
+/*---------------------------------------------------------------------------*/
+static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ) {
+   ips_scb_t *scb;
+   int        rc;
+
+   METHOD_TRACE("ips_get_version_info", 1);
+
+   memset(Buffer, 0, sizeof(IPS_VERSION_DATA));
+   scb = &ha->scbs[ha->max_cmds-1];
+
+   ips_init_scb(ha, scb);
+
+   scb->timeout = ips_cmd_timeout;
+   scb->cdb[0] = IPS_CMD_GET_VERSION_INFO;
+   scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO;
+   scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb);
+   scb->cmd.version_info.reserved = 0;
+   scb->cmd.version_info.count = sizeof( IPS_VERSION_DATA);
+   scb->cmd.version_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(Buffer));
+   scb->cmd.version_info.reserved2 = 0;
+
+   /* issue command */
+   rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
+   return( rc );
+}
+
+  
+
 #if defined (MODULE) || (LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0))
 static Scsi_Host_Template driver_template = IPS;
 #include "scsi_module.c"
 #endif
 
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_remove_device                                         */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Remove one Adapter ( Hot Plugging )                                   */
+/*---------------------------------------------------------------------------*/
+static void __devexit ips_remove_device(struct pci_dev *pci_dev)
+{
+   int    i;
+   struct Scsi_Host *sh;
+   ips_ha_t *ha;                                                                 
+   
+   for (i = 0; i < IPS_MAX_ADAPTERS; i++) {
+      ha = ips_ha[i];
+      if (ha) {
+         if ( (pci_dev->bus->number == ha->pcidev->bus->number) &&
+              (pci_dev->devfn == ha->pcidev->devfn)) {
+            sh = ips_sh[i];
+            ips_release(sh);     
+         }
+      }
+   }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_insert_device                                         */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Add One Adapter ( Hot Plug )                                          */
+/*                                                                           */
+/*   Return Value:                                                           */
+/*     0 if Successful, else non-zero                                        */
+/*---------------------------------------------------------------------------*/
+static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
+{
+    int  index;
+    int  rc;
+
+    METHOD_TRACE("ips_insert_device", 1);
+    if (pci_enable_device(pci_dev)) 
+		return -1;
+
+    rc = ips_init_phase1(pci_dev, &index);
+    if (rc == SUCCESS)
+       rc = ips_init_phase2(index);  
+
+    if (rc == SUCCESS)
+       ips_num_controllers++;
+
+    ips_next_controller = ips_num_controllers;
+    return rc;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_init_phase1                                           */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Adapter Initialization                                                */
+/*                                                                           */
+/*   Return Value:                                                           */
+/*     0 if Successful, else non-zero                                        */
+/*---------------------------------------------------------------------------*/
+static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
+{         
+   struct Scsi_Host *sh;
+   ips_ha_t         *ha;
+   uint32_t          io_addr;
+   uint32_t          mem_addr;
+   uint32_t          io_len;
+   uint32_t          mem_len;
+   uint8_t           revision_id;
+   uint8_t           bus;
+   uint8_t           func;
+   uint8_t           irq;
+   uint16_t          subdevice_id;
+   int               j;
+   int               index; 
+   uint32_t          count;
+   char             *ioremap_ptr;
+   char             *mem_ptr;             
+
+   METHOD_TRACE("ips_init_phase1", 1);
+   index = IPS_MAX_ADAPTERS;
+   for (j = 0; j < IPS_MAX_ADAPTERS; j++) {
+       if (ips_ha[j] ==0) {
+          index = j;
+          break;
+       }
+   }
+
+   if (index >= IPS_MAX_ADAPTERS)
+      return -1;
+   
+   /* stuff that we get in dev */
+    irq  = pci_dev->irq;
+    bus  = pci_dev->bus->number;
+    func = pci_dev->devfn;
+
+    /* Init MEM/IO addresses to 0 */
+    mem_addr = 0;
+    io_addr  = 0;
+    mem_len  = 0;
+    io_len   = 0;
+
+    for (j = 0; j < 2; j++) {
+       if (!pci_resource_start(pci_dev, j))
+          break;
+
+       if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) {
+          io_addr = pci_resource_start(pci_dev, j);
+          io_len = pci_resource_len(pci_dev, j);
+       } else {
+          mem_addr = pci_resource_start(pci_dev, j);
+          mem_len = pci_resource_len(pci_dev, j);
+       }
+    }
+
+    /* setup memory mapped area (if applicable) */
+    if (mem_addr) {
+       uint32_t base;
+       uint32_t offs;
+
+       if (check_mem_region(mem_addr, mem_len)) {
+          printk(KERN_WARNING "Couldn't allocate IO Memory space %x len %d.\n", mem_addr, mem_len);
+          return -1;
+          }
+
+       request_mem_region(mem_addr, mem_len, "ips");
+       base = mem_addr & PAGE_MASK;
+       offs = mem_addr - base;
+       ioremap_ptr = ioremap(base, PAGE_SIZE);
+       mem_ptr = ioremap_ptr + offs;
+    } else {
+       ioremap_ptr = NULL;
+       mem_ptr = NULL;
+    }
+
+    /* setup I/O mapped area (if applicable) */
+    if (io_addr) {
+       if (check_region(io_addr, io_len)) {
+          printk(KERN_WARNING "Couldn't allocate IO space %x len %d.\n", io_addr, io_len);
+          return -1;
+       }
+       request_region(io_addr, io_len, "ips");
+    }
+
+    /* get the revision ID */
+    if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) {
+       printk(KERN_WARNING "Can't get revision id.\n" );
+       return -1;
+    }
+
+    subdevice_id = pci_dev->subsystem_device;
+
+    /* found a controller */
+    sh = scsi_register(&driver_template, sizeof(ips_ha_t));
+    if (sh == NULL) {
+       printk(KERN_WARNING "Unable to register controller with SCSI subsystem\n" );
+       return -1;
+    }
+
+    ha = IPS_HA(sh);
+    memset(ha, 0, sizeof(ips_ha_t));
+
+    /* Initialize spin lock */
+    spin_lock_init(&ha->scb_lock);
+    spin_lock_init(&ha->copp_lock);                                                              spin_lock_init(&ha->ips_lock);
+    spin_lock_init(&ha->copp_waitlist.lock);
+    spin_lock_init(&ha->scb_waitlist.lock);
+    spin_lock_init(&ha->scb_activelist.lock);
+
+    ips_sh[index] = sh;
+    ips_ha[index] = ha;
+    ha->active = 1;
+
+    ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL);
+
+    if (!ha->enq) {
+       printk(KERN_WARNING "Unable to allocate host inquiry structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL);
+
+    if (!ha->adapt) {
+       printk(KERN_WARNING "Unable to allocate host adapt structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL);
+
+    if (!ha->conf) {
+       printk(KERN_WARNING "Unable to allocate host conf structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL);
+
+    if (!ha->nvram) {
+       printk(KERN_WARNING "Unable to allocate host NVRAM structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL);
+
+    if (!ha->subsys) {
+       printk(KERN_WARNING "Unable to allocate host subsystem structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL);
+
+    if (!ha->dummy) {
+       printk(KERN_WARNING "Unable to allocate host dummy structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    for (count = PAGE_SIZE, ha->ioctl_order = 0;
+         count < ips_ioctlsize;
+         ha->ioctl_order++, count <<= 1);
+
+    ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order);
+    ha->ioctl_datasize = count;
+
+    if (!ha->ioctl_data) {
+       printk(KERN_WARNING "Unable to allocate IOCTL data\n" );
+       ha->ioctl_data = NULL;
+       ha->ioctl_order = 0;
+       ha->ioctl_datasize = 0;
+    }
+
+    /* Store away needed values for later use */
+    sh->io_port = io_addr;
+    sh->n_io_port = io_addr ? 255 : 0;
+    sh->unique_id = (io_addr) ? io_addr : mem_addr;
+    sh->irq = irq;
+    sh->select_queue_depths = ips_select_queue_depth;
+    sh->sg_tablesize = sh->hostt->sg_tablesize;
+    sh->can_queue = sh->hostt->can_queue;
+    sh->cmd_per_lun = sh->hostt->cmd_per_lun;
+    sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
+    sh->use_clustering = sh->hostt->use_clustering;
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
+    sh->max_sectors = 128;
+#endif                      
+
+    /* Store info in HA structure */
+    ha->irq = irq;
+    ha->io_addr = io_addr;
+    ha->io_len = io_len;
+    ha->mem_addr = mem_addr;
+    ha->mem_len = mem_len;
+    ha->mem_ptr = mem_ptr;
+    ha->ioremap_ptr = ioremap_ptr;
+    ha->host_num = ( uint32_t) index;
+    ha->revision_id = revision_id;
+    ha->slot_num = PCI_SLOT(pci_dev->devfn);
+    ha->device_id = pci_dev->device;
+    ha->subdevice_id = subdevice_id;
+    ha->pcidev = pci_dev;
+
+    /*
+     * Setup Functions
+     */
+    if (IPS_IS_MORPHEUS(ha)) {
+       /* morpheus */
+       ha->func.isintr = ips_isintr_morpheus;
+       ha->func.isinit = ips_isinit_morpheus;
+       ha->func.issue = ips_issue_i2o_memio;
+       ha->func.init = ips_init_morpheus;
+       ha->func.statupd = ips_statupd_morpheus;
+       ha->func.reset = ips_reset_morpheus;
+       ha->func.intr = ips_intr_morpheus;
+       ha->func.enableint = ips_enable_int_morpheus;
+    } else if (IPS_USE_MEMIO(ha)) {
+       /* copperhead w/MEMIO */
+       ha->func.isintr = ips_isintr_copperhead_memio;
+       ha->func.isinit = ips_isinit_copperhead_memio;
+       ha->func.init = ips_init_copperhead_memio;
+       ha->func.statupd = ips_statupd_copperhead_memio;
+       ha->func.statinit = ips_statinit_memio;
+       ha->func.reset = ips_reset_copperhead_memio;
+       ha->func.intr = ips_intr_copperhead;
+       ha->func.erasebios = ips_erase_bios_memio;
+       ha->func.programbios = ips_program_bios_memio;
+       ha->func.verifybios = ips_verify_bios_memio;
+       ha->func.enableint = ips_enable_int_copperhead_memio;
+
+       if (IPS_USE_I2O_DELIVER(ha))
+          ha->func.issue = ips_issue_i2o_memio;
+       else
+          ha->func.issue = ips_issue_copperhead_memio;
+    } else {
+       /* copperhead */
+       ha->func.isintr = ips_isintr_copperhead;
+       ha->func.isinit = ips_isinit_copperhead;
+       ha->func.init = ips_init_copperhead;
+       ha->func.statupd = ips_statupd_copperhead;
+       ha->func.statinit = ips_statinit;
+       ha->func.reset = ips_reset_copperhead;
+       ha->func.intr = ips_intr_copperhead;
+       ha->func.erasebios = ips_erase_bios;
+       ha->func.programbios = ips_program_bios;
+       ha->func.verifybios = ips_verify_bios;
+       ha->func.enableint = ips_enable_int_copperhead;
+
+       if (IPS_USE_I2O_DELIVER(ha))
+          ha->func.issue = ips_issue_i2o;
+       else
+          ha->func.issue = ips_issue_copperhead;
+    }
+
+    /*
+     * Initialize the card if it isn't already
+     */
+
+    if (!(*ha->func.isinit)(ha)) {
+       if (!(*ha->func.init)(ha)) {
+          /*
+           * Initialization failed
+           */
+          printk(KERN_WARNING "Unable to initialize controller\n" );
+          ha->active = 0;
+          ips_free(ha);
+          scsi_unregister(sh);
+          ips_ha[index] = 0;
+          ips_sh[index] = 0;
+          return -1;
+       }
+    }
+
+    /* Install the interrupt handler */
+     if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
+       printk(KERN_WARNING "Unable to install interrupt handler\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    /*
+     * Allocate a temporary SCB for initialization
+     */
+    ha->max_cmds = 1;
+    if (!ips_allocatescbs(ha)) {
+       printk(KERN_WARNING "Unable to allocate a CCB\n" );
+       ha->active = 0;
+       free_irq(ha->irq, ha);
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    *indexPtr = index;
+    return SUCCESS;
+}
+
+#endif
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_init_phase2                                           */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Adapter Initialization Phase 2                                        */
+/*                                                                           */
+/*   Return Value:                                                           */
+/*     0 if Successful, else non-zero                                        */
+/*---------------------------------------------------------------------------*/
+static int ips_init_phase2( int index )
+{         
+    struct Scsi_Host *sh;
+    ips_ha_t         *ha;
+
+    ha = ips_ha[index];
+    sh = ips_sh[index];
+
+    METHOD_TRACE("ips_init_phase2", 1);
+    if (!ha->active) {
+       scsi_unregister(sh);
+       ips_ha[index] = NULL;
+       ips_sh[index] = NULL;
+       return -1;;
+    }
+
+    if (!ips_hainit(ha)) {
+       printk(KERN_WARNING "Unable to initialize controller\n" );
+       ha->active = 0;
+       ips_free(ha);
+       free_irq(ha->irq, ha);
+       scsi_unregister(sh);
+       ips_ha[index] = NULL;
+       ips_sh[index] = NULL;
+       return -1;
+    }
+    /* Free the temporary SCB */
+    ips_deallocatescbs(ha, 1);
+
+    /* allocate CCBs */
+    if (!ips_allocatescbs(ha)) {
+       printk(KERN_WARNING "Unable to allocate CCBs\n" );
+       ha->active = 0;
+       ips_free(ha);
+       free_irq(ha->irq, ha);
+       scsi_unregister(sh);
+       ips_ha[index] = NULL;
+       ips_sh[index] = NULL;
+       return -1;
+    }
+
+    /* finish setting values */
+    sh->max_id = ha->ntargets;
+    sh->max_lun = ha->nlun;
+    sh->max_channel = ha->nbus - 1;
+    sh->can_queue = ha->max_cmds-1;
+
+    return SUCCESS;
+}
+
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,9)
+MODULE_LICENSE("GPL");
+#endif
+
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/ips.h linux/drivers/scsi/ips.h
--- linux.orig/drivers/scsi/ips.h	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/scsi/ips.h	2002-07-20 01:08:29.000000000 +0000
@@ -50,12 +50,6 @@
    #include <asm/uaccess.h>
    #include <asm/io.h>
 
-   /* type definitions */
-   #define u_int8_t  uint8_t
-   #define u_int16_t uint16_t
-   #define u_int32_t uint32_t
-   #define u_int64_t uint64_t
-
    /* Prototypes */
    extern int ips_detect(Scsi_Host_Template *);
    extern int ips_release(struct Scsi_Host *);
@@ -64,7 +58,7 @@
    extern int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
    extern int ips_biosparam(Disk *, kdev_t, int *);
    extern const char * ips_info(struct Scsi_Host *);
-   extern void do_ipsintr(int, void *, struct pt_regs *);
+   extern void do_ips(int, void *, struct pt_regs *);
 
    /*
     * Some handy macros
@@ -91,11 +85,7 @@
                                           (ips_force_memio))) ? 1 : 0)
 
    #ifndef VIRT_TO_BUS
-      #define VIRT_TO_BUS(x)           (unsigned int)virt_to_bus((void *) x)
-   #endif
-
-   #ifndef UDELAY
-      #define UDELAY udelay
+      #define VIRT_TO_BUS(x)           (uint32_t) virt_to_bus((void *) x)
    #endif
 
    #ifndef MDELAY
@@ -180,7 +170,10 @@
    #define IPS_CMD_DCDB_SG              0x84
    #define IPS_CMD_CONFIG_SYNC          0x58
    #define IPS_CMD_ERROR_TABLE          0x17
+   #define IPS_CMD_DOWNLOAD             0x20
    #define IPS_CMD_RW_BIOSFW            0x22
+   #define IPS_CMD_GET_VERSION_INFO     0xC6
+   #define IPS_CMD_RESET_CHANNEL        0x1A
 
    /*
     * Adapter Equates
@@ -209,7 +202,7 @@
    #define IPS_IOCTL_NEW_COMMAND        0x81
    #define IPS_INTR_ON                  0
    #define IPS_INTR_IORL                1
-   #define IPS_INTR_HAL                 2
+   #define IPS_FFDC                     99
    #define IPS_ADAPTER_ID               0xF
    #define IPS_VENDORID                 0x1014
    #define IPS_DEVICEID_COPPERHEAD      0x002E
@@ -218,6 +211,8 @@
    #define IPS_SUBDEVICEID_4L           0x01BF
    #define IPS_SUBDEVICEID_4MX          0x0208
    #define IPS_SUBDEVICEID_4LX          0x020E
+   #define IPS_SUBDEVICEID_5I2          0x0259
+   #define IPS_SUBDEVICEID_5I1          0x0258
    #define IPS_IOCTL_SIZE               8192
    #define IPS_STATUS_SIZE              4
    #define IPS_STATUS_Q_SIZE            (IPS_MAX_CMDS+1) * IPS_STATUS_SIZE
@@ -298,6 +293,8 @@
    #define IPS_ADTYPE_SERVERAID4L       0x09
    #define IPS_ADTYPE_SERVERAID4MX      0x0A
    #define IPS_ADTYPE_SERVERAID4LX      0x0B
+   #define IPS_ADTYPE_SERVERAID5I2      0x0C
+   #define IPS_ADTYPE_SERVERAID5I1      0x0D
 
    /*
     * Adapter Command/Status Packet Definitions
@@ -390,6 +387,8 @@
     */
    #define IPS_SCB_ACTIVE               0x00001
    #define IPS_SCB_WAITING              0x00002
+   #define IPS_SCB_MAP_SG               0x00008
+   #define IPS_SCB_MAP_SINGLE           0X00010
 
    /*
     * Passthru stuff
@@ -400,6 +399,14 @@
    #define IPS_CTRLINFO                (('C'<<8) | 69)
    #define IPS_FLASHBIOS               (('C'<<8) | 70)
 
+   /* flashing defines */
+   #define IPS_FW_IMAGE                0x00
+   #define IPS_BIOS_IMAGE              0x01
+   #define IPS_WRITE_FW                0x01
+   #define IPS_WRITE_BIOS              0x02
+   #define IPS_ERASE_BIOS              0x03
+   #define IPS_BIOS_HEADER             0xC0
+
    /* time oriented stuff */
    #define IPS_IS_LEAP_YEAR(y)           (((y % 4 == 0) && ((y % 100 != 0) || (y % 400 == 0))) ? 1 : 0)
    #define IPS_NUM_LEAP_YEARS_THROUGH(y) ((y) / 4 - (y) / 100 + (y) / 400)
@@ -415,7 +422,7 @@
    /*
     * Scsi_Host Template
     */
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
  #define IPS {                            \
     next : NULL,                          \
     module : NULL,                        \
@@ -480,201 +487,232 @@
  * IBM PCI Raid Command Formats
  */
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  log_drv;
-   u_int8_t  sg_count;
-   u_int32_t lba;
-   u_int32_t sg_addr;
-   u_int16_t sector_count;
-   u_int16_t reserved;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  log_drv;
+   uint8_t  sg_count;
+   uint32_t lba;
+   uint32_t sg_addr;
+   uint16_t sector_count;
+   uint16_t reserved;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_IO_CMD, *PIPS_IO_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int16_t reserved;
-   u_int32_t reserved2;
-   u_int32_t buffer_addr;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint16_t reserved;
+   uint32_t reserved2;
+   uint32_t buffer_addr;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_LD_CMD, *PIPS_LD_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  reserved;
-   u_int8_t  reserved2;
-   u_int32_t reserved3;
-   u_int32_t buffer_addr;
-   u_int32_t reserved4;
-} IPS_IOCTL_CMD, *PIPS_IOCTL_CMD;
-
-typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int16_t reserved;
-   u_int32_t reserved2;
-   u_int32_t dcdb_address;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  reserved;
+   uint8_t  reserved2;
+   uint32_t reserved3;
+   uint32_t buffer_addr;
+   uint32_t reserved4;
+} IPS_IOCTL_CMD, *PIPS_IOCTL_CMD; 
+
+typedef struct {
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  channel;
+   uint8_t  reserved3;
+   uint8_t  reserved4;
+   uint8_t  reserved5;
+   uint8_t  reserved6;
+   uint8_t  reserved7;
+   uint8_t  reserved8;
+   uint8_t  reserved9;
+   uint8_t  reserved10;
+   uint8_t  reserved11;
+   uint8_t  reserved12;
+   uint8_t  reserved13;
+   uint8_t  reserved14;
+   uint8_t  adapter_flag;
+} IPS_RESET_CMD, *PIPS_RESET_CMD;
+
+typedef struct {
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint16_t reserved;
+   uint32_t reserved2;
+   uint32_t dcdb_address;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_DCDB_CMD, *PIPS_DCDB_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  channel;
-   u_int8_t  source_target;
-   u_int32_t reserved;
-   u_int32_t reserved2;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  channel;
+   uint8_t  source_target;
+   uint32_t reserved;
+   uint32_t reserved2;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_CS_CMD, *PIPS_CS_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  log_drv;
-   u_int8_t  control;
-   u_int32_t reserved;
-   u_int32_t reserved2;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  log_drv;
+   uint8_t  control;
+   uint32_t reserved;
+   uint32_t reserved2;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_US_CMD, *PIPS_US_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  reserved;
-   u_int8_t  state;
-   u_int32_t reserved2;
-   u_int32_t reserved3;
-   u_int32_t reserved4;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  reserved;
+   uint8_t  state;
+   uint32_t reserved2;
+   uint32_t reserved3;
+   uint32_t reserved4;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_FC_CMD, *PIPS_FC_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  reserved;
-   u_int8_t  desc;
-   u_int32_t reserved2;
-   u_int32_t buffer_addr;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  reserved;
+   uint8_t  desc;
+   uint32_t reserved2;
+   uint32_t buffer_addr;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_STATUS_CMD, *PIPS_STATUS_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  page;
-   u_int8_t  write;
-   u_int32_t reserved;
-   u_int32_t buffer_addr;
-   u_int32_t reserved2;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  page;
+   uint8_t  write;
+   uint32_t reserved;
+   uint32_t buffer_addr;
+   uint32_t reserved2;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_NVRAM_CMD, *PIPS_NVRAM_CMD;
 
-typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  reset_count;
-   u_int8_t  reset_type;
-   u_int8_t  second;
-   u_int8_t  minute;
-   u_int8_t  hour;
-   u_int8_t  day;
-   u_int8_t  reserved1[4];
-   u_int8_t  month;
-   u_int8_t  yearH;
-   u_int8_t  yearL;
-   u_int8_t  reserved2;
+typedef struct 
+{
+    uint8_t  op_code;
+    uint8_t  command_id;
+    uint16_t reserved;
+    uint32_t count;
+    uint32_t buffer_addr;
+    uint32_t reserved2;
+} IPS_VERSION_INFO, *PIPS_VERSION_INFO;
+
+typedef struct {
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  reset_count;
+   uint8_t  reset_type;
+   uint8_t  second;
+   uint8_t  minute;
+   uint8_t  hour;
+   uint8_t  day;
+   uint8_t  reserved1[4];
+   uint8_t  month;
+   uint8_t  yearH;
+   uint8_t  yearL;
+   uint8_t  reserved2;
 } IPS_FFDC_CMD, *PIPS_FFDC_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  type;
-   u_int8_t  direction;
-   u_int32_t count;
-   u_int32_t buffer_addr;
-   u_int8_t  total_packets;
-   u_int8_t  packet_num;
-   u_int16_t reserved;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  type;
+   uint8_t  direction;
+   uint32_t count;
+   uint32_t buffer_addr;
+   uint8_t  total_packets;
+   uint8_t  packet_num;
+   uint16_t reserved;
 } IPS_FLASHFW_CMD, *PIPS_FLASHFW_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  type;
-   u_int8_t  direction;
-   u_int32_t count;
-   u_int32_t buffer_addr;
-   u_int32_t offset;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  type;
+   uint8_t  direction;
+   uint32_t count;
+   uint32_t buffer_addr;
+   uint32_t offset;
 } IPS_FLASHBIOS_CMD, *PIPS_FLASHBIOS_CMD;
 
 typedef union {
-   IPS_IO_CMD        basic_io;
-   IPS_LD_CMD        logical_info;
-   IPS_IOCTL_CMD     ioctl_info;
-   IPS_DCDB_CMD      dcdb;
-   IPS_CS_CMD        config_sync;
-   IPS_US_CMD        unlock_stripe;
-   IPS_FC_CMD        flush_cache;
-   IPS_STATUS_CMD    status;
-   IPS_NVRAM_CMD     nvram;
-   IPS_FFDC_CMD      ffdc;
+   IPS_IO_CMD         basic_io;
+   IPS_LD_CMD         logical_info;
+   IPS_IOCTL_CMD      ioctl_info;
+   IPS_DCDB_CMD       dcdb;
+   IPS_CS_CMD         config_sync;
+   IPS_US_CMD         unlock_stripe;
+   IPS_FC_CMD         flush_cache;
+   IPS_STATUS_CMD     status;
+   IPS_NVRAM_CMD      nvram;
+   IPS_FFDC_CMD       ffdc;
    IPS_FLASHFW_CMD    flashfw;
    IPS_FLASHBIOS_CMD  flashbios;
+   IPS_VERSION_INFO   version_info;
+   IPS_RESET_CMD      reset;
 } IPS_HOST_COMMAND, *PIPS_HOST_COMMAND;
 
 typedef struct {
-   u_int8_t  logical_id;
-   u_int8_t  reserved;
-   u_int8_t  raid_level;
-   u_int8_t  state;
-   u_int32_t sector_count;
+   uint8_t  logical_id;
+   uint8_t  reserved;
+   uint8_t  raid_level;
+   uint8_t  state;
+   uint32_t sector_count;
 } IPS_DRIVE_INFO, *PIPS_DRIVE_INFO;
 
 typedef struct {
-   u_int8_t       no_of_log_drive;
-   u_int8_t       reserved[3];
+   uint8_t       no_of_log_drive;
+   uint8_t       reserved[3];
    IPS_DRIVE_INFO drive_info[IPS_MAX_LD];
 } IPS_LD_INFO, *PIPS_LD_INFO;
 
 typedef struct {
-   u_int8_t   device_address;
-   u_int8_t   cmd_attribute;
-   u_int16_t  transfer_length;
-   u_int32_t  buffer_pointer;
-   u_int8_t   cdb_length;
-   u_int8_t   sense_length;
-   u_int8_t   sg_count;
-   u_int8_t   reserved;
-   u_int8_t   scsi_cdb[12];
-   u_int8_t   sense_info[64];
-   u_int8_t   scsi_status;
-   u_int8_t   reserved2[3];
+   uint8_t   device_address;
+   uint8_t   cmd_attribute;
+   uint16_t  transfer_length;
+   uint32_t  buffer_pointer;
+   uint8_t   cdb_length;
+   uint8_t   sense_length;
+   uint8_t   sg_count;
+   uint8_t   reserved;
+   uint8_t   scsi_cdb[12];
+   uint8_t   sense_info[64];
+   uint8_t   scsi_status;
+   uint8_t   reserved2[3];
 } IPS_DCDB_TABLE, *PIPS_DCDB_TABLE;
 
 typedef union {
    struct {
-      volatile u_int8_t  reserved;
-      volatile u_int8_t  command_id;
-      volatile u_int8_t  basic_status;
-      volatile u_int8_t  extended_status;
+      volatile uint8_t  reserved;
+      volatile uint8_t  command_id;
+      volatile uint8_t  basic_status;
+      volatile uint8_t  extended_status;
    } fields;
 
-   volatile u_int32_t    value;
+   volatile uint32_t    value;
 } IPS_STATUS, *PIPS_STATUS;
 
 typedef struct {
@@ -682,110 +720,134 @@
    volatile PIPS_STATUS p_status_start;
    volatile PIPS_STATUS p_status_end;
    volatile PIPS_STATUS p_status_tail;
-   volatile u_int32_t   hw_status_start;
-   volatile u_int32_t   hw_status_tail;
+   volatile uint32_t    hw_status_start;
+   volatile uint32_t    hw_status_tail;
    IPS_LD_INFO          logical_drive_info;
 } IPS_ADAPTER, *PIPS_ADAPTER;
 
 typedef struct {
-   u_int8_t  ucLogDriveCount;
-   u_int8_t  ucMiscFlag;
-   u_int8_t  ucSLTFlag;
-   u_int8_t  ucBSTFlag;
-   u_int8_t  ucPwrChgCnt;
-   u_int8_t  ucWrongAdrCnt;
-   u_int8_t  ucUnidentCnt;
-   u_int8_t  ucNVramDevChgCnt;
-   u_int8_t  CodeBlkVersion[8];
-   u_int8_t  BootBlkVersion[8];
-   u_int32_t ulDriveSize[IPS_MAX_LD];
-   u_int8_t  ucConcurrentCmdCount;
-   u_int8_t  ucMaxPhysicalDevices;
-   u_int16_t usFlashRepgmCount;
-   u_int8_t  ucDefunctDiskCount;
-   u_int8_t  ucRebuildFlag;
-   u_int8_t  ucOfflineLogDrvCount;
-   u_int8_t  ucCriticalDrvCount;
-   u_int16_t usConfigUpdateCount;
-   u_int8_t  ucBlkFlag;
-   u_int8_t  reserved;
-   u_int16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS];
+   uint8_t  ucLogDriveCount;
+   uint8_t  ucMiscFlag;
+   uint8_t  ucSLTFlag;
+   uint8_t  ucBSTFlag;
+   uint8_t  ucPwrChgCnt;
+   uint8_t  ucWrongAdrCnt;
+   uint8_t  ucUnidentCnt;
+   uint8_t  ucNVramDevChgCnt;
+   uint8_t  CodeBlkVersion[8];
+   uint8_t  BootBlkVersion[8];
+   uint32_t ulDriveSize[IPS_MAX_LD];
+   uint8_t  ucConcurrentCmdCount;
+   uint8_t  ucMaxPhysicalDevices;
+   uint16_t usFlashRepgmCount;
+   uint8_t  ucDefunctDiskCount;
+   uint8_t  ucRebuildFlag;
+   uint8_t  ucOfflineLogDrvCount;
+   uint8_t  ucCriticalDrvCount;
+   uint16_t usConfigUpdateCount;
+   uint8_t  ucBlkFlag;
+   uint8_t  reserved;
+   uint16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS];
 } IPS_ENQ, *PIPS_ENQ;
 
 typedef struct {
-   u_int8_t  ucInitiator;
-   u_int8_t  ucParameters;
-   u_int8_t  ucMiscFlag;
-   u_int8_t  ucState;
-   u_int32_t ulBlockCount;
-   u_int8_t  ucDeviceId[28];
+   uint8_t  ucInitiator;
+   uint8_t  ucParameters;
+   uint8_t  ucMiscFlag;
+   uint8_t  ucState;
+   uint32_t ulBlockCount;
+   uint8_t  ucDeviceId[28];
 } IPS_DEVSTATE, *PIPS_DEVSTATE;
 
 typedef struct {
-   u_int8_t  ucChn;
-   u_int8_t  ucTgt;
-   u_int16_t ucReserved;
-   u_int32_t ulStartSect;
-   u_int32_t ulNoOfSects;
+   uint8_t  ucChn;
+   uint8_t  ucTgt;
+   uint16_t ucReserved;
+   uint32_t ulStartSect;
+   uint32_t ulNoOfSects;
 } IPS_CHUNK, *PIPS_CHUNK;
 
 typedef struct {
-   u_int16_t ucUserField;
-   u_int8_t  ucState;
-   u_int8_t  ucRaidCacheParam;
-   u_int8_t  ucNoOfChunkUnits;
-   u_int8_t  ucStripeSize;
-   u_int8_t  ucParams;
-   u_int8_t  ucReserved;
-   u_int32_t ulLogDrvSize;
+   uint16_t ucUserField;
+   uint8_t  ucState;
+   uint8_t  ucRaidCacheParam;
+   uint8_t  ucNoOfChunkUnits;
+   uint8_t  ucStripeSize;
+   uint8_t  ucParams;
+   uint8_t  ucReserved;
+   uint32_t ulLogDrvSize;
    IPS_CHUNK chunk[IPS_MAX_CHUNKS];
 } IPS_LD, *PIPS_LD;
 
 typedef struct {
-   u_int8_t  board_disc[8];
-   u_int8_t  processor[8];
-   u_int8_t  ucNoChanType;
-   u_int8_t  ucNoHostIntType;
-   u_int8_t  ucCompression;
-   u_int8_t  ucNvramType;
-   u_int32_t ulNvramSize;
+   uint8_t  board_disc[8];
+   uint8_t  processor[8];
+   uint8_t  ucNoChanType;
+   uint8_t  ucNoHostIntType;
+   uint8_t  ucCompression;
+   uint8_t  ucNvramType;
+   uint32_t ulNvramSize;
 } IPS_HARDWARE, *PIPS_HARDWARE;
 
 typedef struct {
-   u_int8_t       ucLogDriveCount;
-   u_int8_t       ucDateD;
-   u_int8_t       ucDateM;
-   u_int8_t       ucDateY;
-   u_int8_t       init_id[4];
-   u_int8_t       host_id[12];
-   u_int8_t       time_sign[8];
-   u_int32_t      UserOpt;
-   u_int16_t      user_field;
-   u_int8_t       ucRebuildRate;
-   u_int8_t       ucReserve;
+   uint8_t        ucLogDriveCount;
+   uint8_t        ucDateD;
+   uint8_t        ucDateM;
+   uint8_t        ucDateY;
+   uint8_t        init_id[4];
+   uint8_t        host_id[12];
+   uint8_t        time_sign[8];
+   uint32_t       UserOpt;
+   uint16_t       user_field;
+   uint8_t        ucRebuildRate;
+   uint8_t        ucReserve;
    IPS_HARDWARE   hardware_disc;
    IPS_LD         logical_drive[IPS_MAX_LD];
    IPS_DEVSTATE   dev[IPS_MAX_CHANNELS][IPS_MAX_TARGETS+1];
-   u_int8_t       reserved[512];
+   uint8_t        reserved[512];
 } IPS_CONF, *PIPS_CONF;
 
 typedef struct {
-   u_int32_t  signature;
-   u_int8_t   reserved;
-   u_int8_t   adapter_slot;
-   u_int16_t  adapter_type;
-   u_int8_t   bios_high[4];
-   u_int8_t   bios_low[4];
-   u_int16_t  reserved2;
-   u_int8_t   reserved3;
-   u_int8_t   operating_system;
-   u_int8_t   driver_high[4];
-   u_int8_t   driver_low[4];
-   u_int8_t   reserved4[100];
+   uint32_t  signature;
+   uint8_t   reserved1;
+   uint8_t   adapter_slot;
+   uint16_t  adapter_type;
+   uint8_t   ctrl_bios[8];
+   uint8_t   versioning;                   /* 1 = Versioning Supported, else 0 */
+   uint8_t   version_mismatch;             /* 1 = Versioning MisMatch,  else 0 */
+   uint8_t   reserved2;
+   uint8_t   operating_system;
+   uint8_t   driver_high[4];
+   uint8_t   driver_low[4];
+   uint8_t   BiosCompatibilityID[8];
+   uint8_t   ReservedForOS2[8];
+   uint8_t   bios_high[4];                 /* Adapter's Flashed BIOS Version   */
+   uint8_t   bios_low[4];
+   uint8_t   Filler[76];
 } IPS_NVRAM_P5, *PIPS_NVRAM_P5;
 
+/*--------------------------------------------------------------------------*/
+/* Data returned from a GetVersion Command                                  */
+/*--------------------------------------------------------------------------*/
+
+                                             /* SubSystem Parameter[4]      */
+#define  IPS_GET_VERSION_SUPPORT 0x00018000  /* Mask for Versioning Support */
+
+typedef struct 
+{
+   uint32_t  revision;
+   uint8_t   bootBlkVersion[32];
+   uint8_t   bootBlkAttributes[4];
+   uint8_t   codeBlkVersion[32];
+   uint8_t   biosVersion[32];
+   uint8_t   biosAttributes[4];
+   uint8_t   compatibilityId[32];
+   uint8_t   reserved[4];
+} IPS_VERSION_DATA;
+
+
 typedef struct _IPS_SUBSYS {
-   u_int32_t  param[128];
+   uint32_t  param[128];
 } IPS_SUBSYS, *PIPS_SUBSYS;
 
 /**
@@ -796,102 +858,103 @@
  * Inquiry Data Format
  */
 typedef struct {
-   u_int8_t  DeviceType;
-   u_int8_t  DeviceTypeQualifier;
-   u_int8_t  Version;
-   u_int8_t  ResponseDataFormat;
-   u_int8_t  AdditionalLength;
-   u_int8_t  Reserved;
-   u_int8_t  Flags[2];
-   char      VendorId[8];
-   char      ProductId[16];
-   char      ProductRevisionLevel[4];
+   uint8_t   DeviceType;
+   uint8_t   DeviceTypeQualifier;
+   uint8_t   Version;
+   uint8_t   ResponseDataFormat;
+   uint8_t   AdditionalLength;
+   uint8_t   Reserved;
+   uint8_t   Flags[2];
+   uint8_t   VendorId[8];
+   uint8_t   ProductId[16];
+   uint8_t   ProductRevisionLevel[4];
+   uint8_t   Reserved2;                                  /* Provides NULL terminator to name */
 } IPS_SCSI_INQ_DATA, *PIPS_SCSI_INQ_DATA;
 
 /*
  * Read Capacity Data Format
  */
 typedef struct {
-   u_int32_t lba;
-   u_int32_t len;
+   uint32_t lba;
+   uint32_t len;
 } IPS_SCSI_CAPACITY;
 
 /*
  * Request Sense Data Format
  */
 typedef struct {
-   u_int8_t  ResponseCode;
-   u_int8_t  SegmentNumber;
-   u_int8_t  Flags;
-   u_int8_t  Information[4];
-   u_int8_t  AdditionalLength;
-   u_int8_t  CommandSpecific[4];
-   u_int8_t  AdditionalSenseCode;
-   u_int8_t  AdditionalSenseCodeQual;
-   u_int8_t  FRUCode;
-   u_int8_t  SenseKeySpecific[3];
+   uint8_t  ResponseCode;
+   uint8_t  SegmentNumber;
+   uint8_t  Flags;
+   uint8_t  Information[4];
+   uint8_t  AdditionalLength;
+   uint8_t  CommandSpecific[4];
+   uint8_t  AdditionalSenseCode;
+   uint8_t  AdditionalSenseCodeQual;
+   uint8_t  FRUCode;
+   uint8_t  SenseKeySpecific[3];
 } IPS_SCSI_REQSEN;
 
 /*
  * Sense Data Format - Page 3
  */
 typedef struct {
-   u_int8_t  PageCode;
-   u_int8_t  PageLength;
-   u_int16_t TracksPerZone;
-   u_int16_t AltSectorsPerZone;
-   u_int16_t AltTracksPerZone;
-   u_int16_t AltTracksPerVolume;
-   u_int16_t SectorsPerTrack;
-   u_int16_t BytesPerSector;
-   u_int16_t Interleave;
-   u_int16_t TrackSkew;
-   u_int16_t CylinderSkew;
-   u_int8_t  flags;
-   u_int8_t  reserved[3];
+   uint8_t  PageCode;
+   uint8_t  PageLength;
+   uint16_t TracksPerZone;
+   uint16_t AltSectorsPerZone;
+   uint16_t AltTracksPerZone;
+   uint16_t AltTracksPerVolume;
+   uint16_t SectorsPerTrack;
+   uint16_t BytesPerSector;
+   uint16_t Interleave;
+   uint16_t TrackSkew;
+   uint16_t CylinderSkew;
+   uint8_t  flags;
+   uint8_t  reserved[3];
 } IPS_SCSI_MODE_PAGE3;
 
 /*
  * Sense Data Format - Page 4
  */
 typedef struct {
-   u_int8_t  PageCode;
-   u_int8_t  PageLength;
-   u_int16_t CylindersHigh;
-   u_int8_t  CylindersLow;
-   u_int8_t  Heads;
-   u_int16_t WritePrecompHigh;
-   u_int8_t  WritePrecompLow;
-   u_int16_t ReducedWriteCurrentHigh;
-   u_int8_t  ReducedWriteCurrentLow;
-   u_int16_t StepRate;
-   u_int16_t LandingZoneHigh;
-   u_int8_t  LandingZoneLow;
-   u_int8_t  flags;
-   u_int8_t  RotationalOffset;
-   u_int8_t  Reserved;
-   u_int16_t MediumRotationRate;
-   u_int8_t  Reserved2[2];
+   uint8_t  PageCode;
+   uint8_t  PageLength;
+   uint16_t CylindersHigh;
+   uint8_t  CylindersLow;
+   uint8_t  Heads;
+   uint16_t WritePrecompHigh;
+   uint8_t  WritePrecompLow;
+   uint16_t ReducedWriteCurrentHigh;
+   uint8_t  ReducedWriteCurrentLow;
+   uint16_t StepRate;
+   uint16_t LandingZoneHigh;
+   uint8_t  LandingZoneLow;
+   uint8_t  flags;
+   uint8_t  RotationalOffset;
+   uint8_t  Reserved;
+   uint16_t MediumRotationRate;
+   uint8_t  Reserved2[2];
 } IPS_SCSI_MODE_PAGE4;
 
 /*
  * Sense Data Format - Block Descriptor (DASD)
  */
 typedef struct {
-   u_int32_t NumberOfBlocks;
-   u_int8_t  DensityCode;
-   u_int16_t BlockLengthHigh;
-   u_int8_t  BlockLengthLow;
+   uint32_t NumberOfBlocks;
+   uint8_t  DensityCode;
+   uint16_t BlockLengthHigh;
+   uint8_t  BlockLengthLow;
 } IPS_SCSI_MODE_PAGE_BLKDESC;
 
 /*
  * Sense Data Format - Mode Page Header
  */
 typedef struct {
-   u_int8_t  DataLength;
-   u_int8_t  MediumType;
-   u_int8_t  Reserved;
-   u_int8_t  BlockDescLength;
+   uint8_t  DataLength;
+   uint8_t  MediumType;
+   uint8_t  Reserved;
+   uint8_t  BlockDescLength;
 } IPS_SCSI_MODE_PAGE_HEADER;
 
 typedef struct {
@@ -908,8 +971,8 @@
  * Scatter Gather list format
  */
 typedef struct ips_sglist {
-   u_int32_t address;
-   u_int32_t length;
+   uint32_t address;
+   uint32_t length;
 } IPS_SG_LIST, *PIPS_SG_LIST;
 
 typedef struct _IPS_INFOSTR {
@@ -928,24 +991,24 @@
 
 typedef struct {
    void             *userbuffer;
-   u_int32_t         usersize;
+   uint32_t          usersize;
    void             *kernbuffer;
-   u_int32_t         kernsize;
+   uint32_t          kernsize;
    void             *ha;
    void             *SC;
    void             *pt;
    struct semaphore *sem;
-   u_int32_t         offset;
-   u_int32_t         retcode;
+   uint32_t          offset;
+   uint32_t          retcode;
 } IPS_FLASH_DATA;
 
 /*
  * Status Info
  */
 typedef struct ips_stat {
-   u_int32_t residue_len;
+   uint32_t residue_len;
    void     *scb_addr;
-   u_int8_t  padding[12 - sizeof(void *)];
+   uint8_t  padding[12 - sizeof(void *)];
 } ips_stat_t;
 
 /*
@@ -954,8 +1017,8 @@
 typedef struct ips_scb_queue {
    struct ips_scb *head;
    struct ips_scb *tail;
-   u_int32_t       count;
-   u_int32_t       cpu_flags;
+   int             count;
+   unsigned long   cpu_flags;
    spinlock_t      lock;
 } ips_scb_queue_t;
 
@@ -965,8 +1028,8 @@
 typedef struct ips_wait_queue {
    Scsi_Cmnd      *head;
    Scsi_Cmnd      *tail;
-   u_int32_t       count;
-   u_int32_t       cpu_flags;
+   int             count;
+   unsigned long   cpu_flags;
    spinlock_t      lock;
 } ips_wait_queue_t;
 
@@ -979,8 +1042,8 @@
 typedef struct ips_copp_queue {
    struct ips_copp_wait_item *head;
    struct ips_copp_wait_item *tail;
-   u_int32_t                  count;
-   u_int32_t                  cpu_flags;
+   int                        count;
+   unsigned long              cpu_flags;
    spinlock_t                 lock;
 } ips_copp_queue_t;
 
@@ -994,27 +1057,27 @@
    int       (*isintr)(struct ips_ha *);
    int       (*init)(struct ips_ha *);
    int       (*erasebios)(struct ips_ha *);
-   int       (*programbios)(struct ips_ha *, char *, u_int32_t, u_int32_t);
-   int       (*verifybios)(struct ips_ha *, char *, u_int32_t, u_int32_t);
+   int       (*programbios)(struct ips_ha *, char *, uint32_t, uint32_t);
+   int       (*verifybios)(struct ips_ha *, char *, uint32_t, uint32_t);
    void      (*statinit)(struct ips_ha *);
    void      (*intr)(struct ips_ha *);
    void      (*enableint)(struct ips_ha *);
-   u_int32_t (*statupd)(struct ips_ha *);
+   uint32_t (*statupd)(struct ips_ha *);
 } ips_hw_func_t;
 
 typedef struct ips_ha {
-   u_int8_t           ha_id[IPS_MAX_CHANNELS+1];
-   u_int32_t          dcdb_active[IPS_MAX_CHANNELS];
-   u_int32_t          io_addr;            /* Base I/O address           */
-   u_int8_t           irq;                /* IRQ for adapter            */
-   u_int8_t           ntargets;           /* Number of targets          */
-   u_int8_t           nbus;               /* Number of buses            */
-   u_int8_t           nlun;               /* Number of Luns             */
-   u_int16_t          ad_type;            /* Adapter type               */
-   u_int16_t          host_num;           /* Adapter number             */
-   u_int32_t          max_xfer;           /* Maximum Xfer size          */
-   u_int32_t          max_cmds;           /* Max concurrent commands    */
-   u_int32_t          num_ioctl;          /* Number of Ioctls           */
+   uint8_t            ha_id[IPS_MAX_CHANNELS+1];
+   uint32_t           dcdb_active[IPS_MAX_CHANNELS];
+   uint32_t           io_addr;            /* Base I/O address           */
+   uint8_t            irq;                /* IRQ for adapter            */
+   uint8_t            ntargets;           /* Number of targets          */
+   uint8_t            nbus;               /* Number of buses            */
+   uint8_t            nlun;               /* Number of Luns             */
+   uint16_t           ad_type;            /* Adapter type               */
+   uint16_t           host_num;           /* Adapter number             */
+   uint32_t           max_xfer;           /* Maximum Xfer size          */
+   uint32_t           max_cmds;           /* Max concurrent commands    */
+   uint32_t           num_ioctl;          /* Number of Ioctls           */
    ips_stat_t         sp;                 /* Status packer pointer      */
    struct ips_scb    *scbs;               /* Array of all CCBS          */
    struct ips_scb    *scb_freelist;       /* SCB free list              */
@@ -1028,23 +1091,24 @@
    IPS_NVRAM_P5      *nvram;              /* NVRAM page 5 data          */
    IPS_SUBSYS        *subsys;             /* Subsystem parameters       */
    char              *ioctl_data;         /* IOCTL data area            */
-   u_int32_t          ioctl_datasize;     /* IOCTL data size            */
-   u_int32_t          cmd_in_progress;    /* Current command in progress*/
+   uint32_t           ioctl_datasize;     /* IOCTL data size            */
+   uint32_t           cmd_in_progress;    /* Current command in progress*/
    unsigned long      flags;              /* HA flags                   */
-   u_int8_t           waitflag;           /* are we waiting for cmd     */
-   u_int8_t           active;
-   u_int16_t          reset_count;        /* number of resets           */
-   u_int32_t          last_ffdc;          /* last time we sent ffdc info*/
-   u_int8_t           revision_id;        /* Revision level             */
-   u_int16_t          device_id;          /* PCI device ID              */
-   u_int8_t           slot_num;           /* PCI Slot Number            */
-   u_int16_t          subdevice_id;       /* Subsystem device ID        */
-   u_int8_t           ioctl_order;        /* Number of pages in ioctl   */
-   u_int8_t           reserved2;          /* Empty                      */
-   u_int8_t           bios_version[8];    /* BIOS Revision              */
-   u_int32_t          mem_addr;           /* Memory mapped address      */
-   u_int32_t          io_len;             /* Size of IO Address         */
-   u_int32_t          mem_len;            /* Size of memory address     */
+   uint8_t            waitflag;           /* are we waiting for cmd     */
+   uint8_t            active;
+   int                ioctl_reset;        /* IOCTL Requested Reset Flag */
+   uint16_t           reset_count;        /* number of resets           */
+   time_t             last_ffdc;          /* last time we sent ffdc info*/
+   uint8_t            revision_id;        /* Revision level             */
+   uint16_t           device_id;          /* PCI device ID              */
+   uint8_t            slot_num;           /* PCI Slot Number            */
+   uint16_t           subdevice_id;       /* Subsystem device ID        */
+   uint8_t            ioctl_order;        /* Number of pages in ioctl   */
+   uint8_t            reserved2;          /* Empty                      */
+   uint8_t            bios_version[8];    /* BIOS Revision              */
+   uint32_t           mem_addr;           /* Memory mapped address      */
+   uint32_t           io_len;             /* Size of IO Address         */
+   uint32_t           mem_len;            /* Size of memory address     */
    char              *mem_ptr;            /* Memory mapped Ptr          */
    char              *ioremap_ptr;        /* ioremapped memory pointer  */
    ips_hw_func_t      func;               /* hw function pointers       */
@@ -1054,9 +1118,9 @@
    spinlock_t         ips_lock;
    struct semaphore   ioctl_sem;          /* Semaphore for new IOCTL's  */
    struct semaphore   flash_ioctl_sem;    /* Semaphore for Flashing     */
-   char              *save_ioctl_data;    /* Save Area for ioctl_data   */
-   u8                 save_ioctl_order;   /* Save Area for ioctl_order  */
-   u32                save_ioctl_datasize;/* Save Area for ioctl_datasize */
+   char              *flash_data;         /* Save Area for flash data   */
+   u8                 flash_order;        /* Save Area for flash size order  */
+   u32                flash_datasize;   /* Save Area for flash data size */
 } ips_ha_t;
 
 typedef void (*ips_scb_callback) (ips_ha_t *, struct ips_scb *);
@@ -1067,45 +1131,47 @@
 typedef struct ips_scb {
    IPS_HOST_COMMAND  cmd;
    IPS_DCDB_TABLE    dcdb;
-   u_int8_t          target_id;
-   u_int8_t          bus;
-   u_int8_t          lun;
-   u_int8_t          cdb[12];
-   u_int32_t         scb_busaddr;
-   u_int32_t         data_busaddr;
-   u_int32_t         timeout;
-   u_int8_t          basic_status;
-   u_int8_t          extended_status;
-   u_int8_t          breakup;
-   u_int8_t          sg_break;
-   u_int32_t         data_len;
-   u_int32_t         sg_len;
-   u_int32_t         flags;
-   u_int32_t         op_code;
+   uint8_t           target_id;
+   uint8_t           bus;
+   uint8_t           lun;
+   uint8_t           cdb[12];
+   uint32_t          scb_busaddr;
+   uint32_t          data_busaddr;
+   uint32_t          timeout;
+   uint8_t           basic_status;
+   uint8_t           extended_status;
+   uint8_t           breakup;
+   uint8_t           sg_break;
+   uint32_t          data_len;
+   uint32_t          sg_len;
+   uint32_t          flags;
+   uint32_t          op_code;
    IPS_SG_LIST      *sg_list;
    Scsi_Cmnd        *scsi_cmd;
    struct ips_scb   *q_next;
    ips_scb_callback  callback;
    struct semaphore *sem;
+   uint32_t          sg_busaddr;
+   int               sg_count;
 } ips_scb_t;
 
 typedef struct ips_scb_pt {
    IPS_HOST_COMMAND  cmd;
    IPS_DCDB_TABLE    dcdb;
-   u_int8_t          target_id;
-   u_int8_t          bus;
-   u_int8_t          lun;
-   u_int8_t          cdb[12];
-   u_int32_t         scb_busaddr;
-   u_int32_t         data_busaddr;
-   u_int32_t         timeout;
-   u_int8_t          basic_status;
-   u_int8_t          extended_status;
-   u_int16_t         breakup;
-   u_int32_t         data_len;
-   u_int32_t         sg_len;
-   u_int32_t         flags;
-   u_int32_t         op_code;
+   uint8_t           target_id;
+   uint8_t           bus;
+   uint8_t           lun;
+   uint8_t           cdb[12];
+   uint32_t          scb_busaddr;
+   uint32_t          data_busaddr;
+   uint32_t          timeout;
+   uint8_t           basic_status;
+   uint8_t           extended_status;
+   uint16_t          breakup;
+   uint32_t          data_len;
+   uint32_t          sg_len;
+   uint32_t          flags;
+   uint32_t          op_code;
    IPS_SG_LIST      *sg_list;
    Scsi_Cmnd        *scsi_cmd;
    struct ips_scb   *q_next;
@@ -1116,20 +1182,86 @@
  * Passthru Command Format
  */
 typedef struct {
-   u_int8_t      CoppID[4];
-   u_int32_t     CoppCmd;
-   u_int32_t     PtBuffer;
-   u_int8_t     *CmdBuffer;
-   u_int32_t     CmdBSize;
+   uint8_t       CoppID[4];
+   uint32_t      CoppCmd;
+   uint32_t      PtBuffer;
+   uint8_t      *CmdBuffer;
+   uint32_t      CmdBSize;
    ips_scb_pt_t  CoppCP;
-   u_int32_t     TimeOut;
-   u_int8_t      BasicStatus;
-   u_int8_t      ExtendedStatus;
-   u_int16_t     reserved;
+   uint32_t      TimeOut;
+   uint8_t       BasicStatus;
+   uint8_t       ExtendedStatus;
+   uint8_t       AdapterType;
+   uint8_t       reserved;
 } ips_passthru_t;
 
 #endif
 
+/* The Version Information below gets created by SED during the build process. */
+/* Do not modify the next line; it's what SED is looking for to do the insert. */
+/* Version Info                                                                */
+/*************************************************************************
+*
+* VERSION.H -- version numbers and copyright notices in various formats
+*
+*************************************************************************/
+
+#define IPS_VER_MAJOR 4
+#define IPS_VER_MAJOR_STRING "4"
+#define IPS_VER_MINOR 90
+#define IPS_VER_MINOR_STRING "90"
+#define IPS_VER_BUILD_STRING "18"
+#define IPS_VER_STRING "4.90.18"
+#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved."
+#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002."
+
+/* Version numbers for various adapters */
+#define IPS_VER_SERVERAID1 "2.25.01"
+#define IPS_VER_SERVERAID2 "2.88.13"
+#define IPS_VER_NAVAJO "2.88.13"
+#define IPS_VER_SERVERAID3 "3.84.01"
+#define IPS_VER_SERVERAID4H "4.84.01"
+#define IPS_VER_SERVERAID4MLx "4.90.18"
+#define IPS_VER_SARASOTA "0.00.00"
+
+/* Compatability IDs for various adapters */
+#define IPS_COMPAT_UNKNOWN ""
+#define IPS_COMPAT_SERVERAID1 "2.25.01"
+#define IPS_COMPAT_SERVERAID2 "2.88.13"
+#define IPS_COMPAT_NAVAJO  "2.88.13"
+#define IPS_COMPAT_KIOWA "2.88.13"
+#define IPS_COMPAT_SERVERAID3H  "3.84.01"
+#define IPS_COMPAT_SERVERAID3L  "3.84.01"
+#define IPS_COMPAT_SERVERAID4H  "4.84.01"
+#define IPS_COMPAT_SERVERAID4M  "MA490"
+#define IPS_COMPAT_SERVERAID4L  "MA490"
+#define IPS_COMPAT_SERVERAID4Mx "MA490"
+#define IPS_COMPAT_SERVERAID4Lx "MA490"
+#define IPS_COMPAT_SARASOTA     "XXXXX"
+#define IPS_COMPAT_BIOS "MA490"
+
+#define IPS_COMPAT_MAX_ADAPTER_TYPE 14
+#define IPS_COMPAT_ID_LENGTH 8
+
+#define IPS_DEFINE_COMPAT_TABLE(tablename) \
+   char tablename[IPS_COMPAT_MAX_ADAPTER_TYPE] [IPS_COMPAT_ID_LENGTH] = { \
+      IPS_COMPAT_UNKNOWN, \
+      IPS_COMPAT_SERVERAID1, \
+      IPS_COMPAT_SERVERAID2, \
+      IPS_COMPAT_NAVAJO, \
+      IPS_COMPAT_KIOWA, \
+      IPS_COMPAT_SERVERAID3H, \
+      IPS_COMPAT_SERVERAID3L, \
+      IPS_COMPAT_SERVERAID4H, \
+      IPS_COMPAT_SERVERAID4M, \
+      IPS_COMPAT_SERVERAID4L, \
+      IPS_COMPAT_SERVERAID4Mx, \
+      IPS_COMPAT_SERVERAID4Lx, \
+      IPS_COMPAT_SARASOTA, \
+      IPS_COMPAT_SARASOTA \
+   }
+
+
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/jazz_esp.c linux/drivers/scsi/jazz_esp.c
--- linux.orig/drivers/scsi/jazz_esp.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/jazz_esp.c	2002-07-20 01:08:24.000000000 +0000
@@ -123,7 +123,7 @@
 	            NULL);
 
 	/*
-	 * FIXME, look if the scsi id is availabe from NVRAM
+	 * FIXME, look if the scsi id is available from NVRAM
 	 */
 	esp->scsi_id = 7;
 		
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/mac_NCR5380.c linux/drivers/scsi/mac_NCR5380.c
--- linux.orig/drivers/scsi/mac_NCR5380.c	2001-01-04 21:00:55.000000000 +0000
+++ linux/drivers/scsi/mac_NCR5380.c	2002-07-20 01:08:29.000000000 +0000
@@ -662,10 +662,7 @@
 
 static volatile int main_running = 0;
 static struct tq_struct NCR5380_tqueue = {
-    NULL,		/* next */
-    0,			/* sync */
-    (void (*)(void*))NCR5380_main,  /* routine, must have (void *) arg... */
-    NULL		/* data */
+    routine:	(void (*)(void*))NCR5380_main	/* must have (void *) arg... */
 };
 
 static __inline__ void queue_main(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/mac_esp.c linux/drivers/scsi/mac_esp.c
--- linux.orig/drivers/scsi/mac_esp.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/mac_esp.c	2002-07-20 01:08:36.000000000 +0000
@@ -713,3 +713,5 @@
 static Scsi_Host_Template driver_template = SCSI_MAC_ESP;
 
 #include "scsi_module.c"
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
--- linux.orig/drivers/scsi/megaraid.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/megaraid.c	2002-07-20 01:08:21.000000000 +0000
@@ -3005,11 +3005,10 @@
 
 		if (!(flag & BOARD_QUARTZ)) {
 			/* Request our IO Range */
-			if (check_region (megaBase, 16)) {
+			if (!request_region(megaBase, 16, "megaraid")) {
 				printk(KERN_WARNING "megaraid: Couldn't register I/O range!\n");
 				goto err_unregister;
 			}
-			request_region(megaBase, 16, "megaraid");
 		}
 
 		/* Request our IRQ */
@@ -3077,10 +3076,12 @@
 			/*
 			 * which firmware
 			 */
-			if( strcmp(megaCfg->fwVer, "H01.07") == 0 ||
-					strcmp(megaCfg->fwVer, "H01.08") == 0 ) {
+			if( strcmp(megaCfg->fwVer, "H01.07") == 0 || 
+			    strcmp(megaCfg->fwVer, "H01.08") == 0 ||
+			    strcmp(megaCfg->fwVer, "H01.09") == 0 )
+			{
 				printk(KERN_WARNING
-						"megaraid: Firmware H.01.07 or H.01.08 on 1M/2M "
+						"megaraid: Firmware H.01.07/8/9 on 1M/2M "
 						"controllers\nmegaraid: do not support 64 bit "
 						"addressing.\n"
 						"megaraid: DISABLING 64 bit support.\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/mesh.c linux/drivers/scsi/mesh.c
--- linux.orig/drivers/scsi/mesh.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/mesh.c	2002-07-20 01:08:25.000000000 +0000
@@ -6,8 +6,16 @@
  *
  * Paul Mackerras, August 1996.
  * Copyright (C) 1996 Paul Mackerras.
+ *
+ * Apr. 14 2002  - BenH		Rework bus reset code for new error handler
+ *                              Add delay after initial bus reset
+ *                              Add module parameters
+ * To do:
+ * - handle aborts correctly
+ * - retry arbitration if lost (unless higher levels do this for us)
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -20,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
 #include <linux/spinlock.h>
+#include <linux/pci.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -30,6 +39,7 @@
 #include <asm/processor.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
+#include <asm/pci-bridge.h>
 #ifdef CONFIG_PMAC_PBOOK
 #include <linux/adb.h>
 #include <linux/pmu.h>
@@ -39,35 +49,39 @@
 #include "hosts.h"
 #include "mesh.h"
 
-/*
- * To do:
- * - handle aborts correctly
- * - retry arbitration if lost (unless higher levels do this for us)
- */
-
-#define MESH_NEW_STYLE_EH
-
 #if 1
 #undef KERN_DEBUG
 #define KERN_DEBUG KERN_WARNING
 #endif
 
-#if CONFIG_SCSI_MESH_SYNC_RATE == 0
-int mesh_sync_period = 100;
-int mesh_sync_offset = 0;
-#else
-int mesh_sync_period = 1000 / CONFIG_SCSI_MESH_SYNC_RATE;	/* ns */
-int mesh_sync_offset = 15;
-#endif
-
-int mesh_sync_targets = 0xff;	/* targets to set synchronous (bitmap) */
-int mesh_resel_targets = 0xff;	/* targets that we let disconnect (bitmap) */
-int mesh_debug_targets = 0;	/* print debug for these targets */
-unsigned char use_active_neg = 0;  /* bit mask for SEQ_ACTIVE_NEG if used */
-
-#define ALLOW_SYNC(tgt)		((mesh_sync_targets >> (tgt)) & 1)
-#define ALLOW_RESEL(tgt)	((mesh_resel_targets >> (tgt)) & 1)
-#define ALLOW_DEBUG(tgt)	((mesh_debug_targets >> (tgt)) & 1)
+MODULE_AUTHOR("Paul Mackerras (paulus@samba.org)");
+MODULE_DESCRIPTION("PowerMac MESH SCSI driver");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(sync_rate, "i");
+MODULE_PARM_DESC(sync_rate, "Synchronous rate (0..10, 0=async)");
+MODULE_PARM(sync_targets, "i");
+MODULE_PARM_DESC(sync_targets, "Bitmask of targets allowed to set synchronous");
+MODULE_PARM(resel_targets, "i");
+MODULE_PARM_DESC(resel_targets, "Bitmask of targets allowed to set disconnect");
+MODULE_PARM(debug_targets, "i");
+MODULE_PARM_DESC(debug_targets, "Bitmask of debugged targets");
+MODULE_PARM(init_reset_delay, "i");
+MODULE_PARM_DESC(init_reset_delay, "Initial bus reset delay (0=no reset)");
+
+static int sync_rate = CONFIG_SCSI_MESH_SYNC_RATE;
+static int sync_targets = 0xff;
+static int resel_targets = 0xff;
+static int debug_targets = 0;	/* print debug for these targets */
+static int init_reset_delay = CONFIG_SCSI_MESH_RESET_DELAY_MS;
+
+static int mesh_sync_period = 100;
+static int mesh_sync_offset = 0;
+static unsigned char use_active_neg = 0;  /* bit mask for SEQ_ACTIVE_NEG if used */
+
+#define ALLOW_SYNC(tgt)		((sync_targets >> (tgt)) & 1)
+#define ALLOW_RESEL(tgt)	((resel_targets >> (tgt)) & 1)
+#define ALLOW_DEBUG(tgt)	((debug_targets >> (tgt)) & 1)
 #define DEBUG_TARGET(cmd)	((cmd) && ALLOW_DEBUG((cmd)->target))
 
 #undef MESH_DBG
@@ -95,7 +109,8 @@
 	statusing,
 	busfreeing,
 	disconnecting,
-	reselecting
+	reselecting,
+	sleeping
 };
 
 enum msg_phase {
@@ -119,7 +134,6 @@
 	int	data_goes_out;		/* guess as to data direction */
 	Scsi_Cmnd *current_req;
 	u32	saved_ptr;
-	int	want_abort;
 #ifdef MESH_DBG
 	int	log_ix;
 	int	n_log;
@@ -156,11 +170,7 @@
 	struct mesh_target tgts[8];
 	void	*dma_cmd_space;
 	struct device_node *ofnode;
-#ifndef MESH_NEW_STYLE_EH
-	Scsi_Cmnd *completed_q;
-	Scsi_Cmnd *completed_qtail;
-	struct tq_struct tqueue;
-#endif
+	struct pci_dev* pdev;
 #ifdef MESH_DBG
 	int	log_ix;
 	int	n_log;
@@ -192,9 +202,6 @@
 static void mesh_dump_regs(struct mesh_state *);
 static void mesh_start(struct mesh_state *);
 static void mesh_start_cmd(struct mesh_state *, Scsi_Cmnd *);
-#ifndef MESH_NEW_STYLE_EH
-static void finish_cmds(void *);
-#endif
 static void add_sdtr_msg(struct mesh_state *);
 static void set_sdtr(struct mesh_state *, int, int);
 static void start_phase(struct mesh_state *);
@@ -240,6 +247,12 @@
 	struct Scsi_Host *mesh_host;
 	void *dma_cmd_space;
 
+	/* The SCSI layer is dumb ! It calls us with the IO request
+	 * lock held and interrupts disabled here... This doesn't happen
+	 * in 2.5
+	 */
+	spin_unlock_irq(&io_request_lock);
+	
 	if (_machine == _MACH_Pmac) {
 	    use_active_neg = (find_devices("mac-io") ? 0 : SEQ_ACTIVE_NEG);
 	} else {
@@ -247,6 +260,16 @@
 	    use_active_neg = SEQ_ACTIVE_NEG;
 	}
 
+	/* Calculate sync rate from module parameters */
+	if (sync_rate > 10)
+		sync_rate = 10;
+	if (sync_rate > 0) {
+		printk(KERN_INFO "mesh: configured for synchronous %d MB/s\n", sync_rate);
+		mesh_sync_period = 1000 / sync_rate;	/* ns */
+		mesh_sync_offset = 15;
+	} else
+		printk(KERN_INFO "mesh: configured for asynchronous\n");
+
 	nmeshes = 0;
 	prev_statep = &all_meshes;
 	/*
@@ -258,11 +281,23 @@
 	if (mesh == 0)
 		mesh = find_compatible_devices("scsi", "chrp,mesh0");
 	for (; mesh != 0; mesh = mesh->next) {
+		u8 pci_bus, pci_devfn;
+		struct pci_dev* pdev = NULL;
+		
 		if (mesh->n_addrs != 2 || mesh->n_intrs != 2) {
 			printk(KERN_ERR "mesh: expected 2 addrs and 2 intrs"
-			       " (got %d,%d)", mesh->n_addrs, mesh->n_intrs);
+			       " (got %d,%d)\n", mesh->n_addrs, mesh->n_intrs);
+			continue;
+		}
+		if (mesh->parent != NULL
+		    && pci_device_from_OF_node(mesh->parent, &pci_bus,
+					       &pci_devfn) == 0)
+			pdev = pci_find_slot(pci_bus, pci_devfn);
+		if (pdev == NULL) {
+			printk(KERN_ERR "mesh: Can't locate PCI entry\n");
 			continue;
 		}
+
 		mesh_host = scsi_register(tp, sizeof(struct mesh_state));
 		if (mesh_host == 0) {
 			printk(KERN_ERR "mesh: couldn't register host");
@@ -279,6 +314,7 @@
 		memset(ms, 0, sizeof(*ms));
 		ms->host = mesh_host;
 		ms->ofnode = mesh;
+		ms->pdev = pdev;
 		ms->mesh = (volatile struct mesh_regs *)
 			ioremap(mesh->addrs[0].address, 0x1000);
 		ms->dma = (volatile struct dbdma_regs *)
@@ -303,10 +339,6 @@
 			ms->tgts[tgt].sync_params = ASYNC_PARAMS;
 			ms->tgts[tgt].current_req = 0;
 		}
-#ifndef MESH_NEW_STYLE_EH
-		ms->tqueue.routine = finish_cmds;
-		ms->tqueue.data = ms;
-#endif
 		*prev_statep = ms;
 		prev_statep = &ms->next;
 
@@ -341,6 +373,9 @@
 		register_reboot_notifier(&mesh_notifier);
 	}
 
+	/* Return to the SCSI layer in the same state we got called */
+	spin_lock_irq(&io_request_lock);
+
 	return nmeshes;
 }
 
@@ -395,15 +430,33 @@
 		
 	case PBOOK_SLEEP_NOW:
 		for (ms = all_meshes; ms != 0; ms = ms->next) {
+			unsigned long flags;
+
+			scsi_block_requests(ms->host);
+			spin_lock_irqsave(&io_request_lock, flags);
+			while(ms->phase != idle) {
+				spin_unlock_irqrestore(&io_request_lock, flags);
+				current->state = TASK_UNINTERRUPTIBLE;
+				schedule_timeout(1);
+				spin_lock_irqsave(&io_request_lock, flags);
+			}
+			ms->phase = sleeping;
+			spin_unlock_irqrestore(&io_request_lock, flags);
 			disable_irq(ms->meshintr);
 			set_mesh_power(ms, 0);
 		}
 		break;
 	case PBOOK_WAKE:
 		for (ms = all_meshes; ms != 0; ms = ms->next) {
+			unsigned long flags;
+			
 			set_mesh_power(ms, 1);
 			mesh_init(ms);
+			spin_lock_irqsave(&io_request_lock, flags);
+			mesh_start(ms);
+			spin_unlock_irqrestore(&io_request_lock, flags);
 			enable_irq(ms->meshintr);
+			scsi_unblock_requests(ms->host);
 		}
 		break;
 	}
@@ -411,10 +464,13 @@
 }
 #endif /* CONFIG_PMAC_PBOOK */
 
+/*
+ * Called by midlayer with host locked to queue a new
+ * request
+ */
 int
 mesh_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
-	unsigned long flags;
 	struct mesh_state *ms;
 
 	cmd->scsi_done = done;
@@ -422,8 +478,6 @@
 
 	ms = (struct mesh_state *) cmd->host->hostdata;
 
-	save_flags(flags);
-	cli();
 	if (ms->request_q == NULL)
 		ms->request_q = cmd;
 	else
@@ -433,19 +487,25 @@
 	if (ms->phase == idle)
 		mesh_start(ms);
 
-	restore_flags(flags);
 	return 0;
 }
 
+/* Todo: here we can at least try to remove the command from the
+ * queue if it isn't connected yet, and for pending command, assert
+ * ATN until the bus gets freed.
+ */
 int
 mesh_abort(Scsi_Cmnd *cmd)
 {
 	struct mesh_state *ms = (struct mesh_state *) cmd->host->hostdata;
+	unsigned long flags;
 
 	printk(KERN_DEBUG "mesh_abort(%p)\n", cmd);
+	spin_lock_irqsave(&io_request_lock, flags);
 	mesh_dump_regs(ms);
 	dumplog(ms, cmd->target);
 	dumpslog(ms);
+	spin_unlock_irqrestore(&io_request_lock, flags);
 	return SCSI_ABORT_SNOOZE;
 }
 
@@ -482,49 +542,41 @@
 	}
 }
 
+/*
+ * Called by the midlayer with the lock held to reset the
+ * SCSI host and bus.
+ * The midlayer will wait for devices to come back, we don't need
+ * to do that ourselves
+ */
 int
-mesh_reset(Scsi_Cmnd *cmd, unsigned how)
+mesh_host_reset(Scsi_Cmnd *cmd)
 {
 	struct mesh_state *ms = (struct mesh_state *) cmd->host->hostdata;
 	volatile struct mesh_regs *mr = ms->mesh;
 	volatile struct dbdma_regs *md = ms->dma;
-	unsigned long flags;
-	int ret;
 
-	printk(KERN_DEBUG "mesh_reset %x\n", how);
-	ret = SCSI_RESET_BUS_RESET;
-	save_flags(flags);
-	cli();
+	printk(KERN_DEBUG "mesh_host_reset\n");
+
+	/* Reset the controller & dbdma channel */
 	out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16);	/* stop dma */
 	out_8(&mr->exception, 0xff);	/* clear all exception bits */
 	out_8(&mr->error, 0xff);	/* clear all error bits */
-	if (how & SCSI_RESET_SUGGEST_HOST_RESET) {
-		out_8(&mr->sequence, SEQ_RESETMESH);
-		ret |= SCSI_RESET_HOST_RESET;
-		udelay(1);
-		out_8(&mr->intr_mask, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
-		out_8(&mr->source_id, ms->host->this_id);
-		out_8(&mr->sel_timeout, 25);	/* 250ms */
-		out_8(&mr->sync_params, ASYNC_PARAMS);
-	}
+	out_8(&mr->sequence, SEQ_RESETMESH);
+	udelay(1);
+	out_8(&mr->intr_mask, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
+	out_8(&mr->source_id, ms->host->this_id);
+	out_8(&mr->sel_timeout, 25);	/* 250ms */
+	out_8(&mr->sync_params, ASYNC_PARAMS);
+
+	/* Reset the bus */
 	out_8(&mr->bus_status1, BS1_RST);	/* assert RST */
 	udelay(30);			/* leave it on for >= 25us */
 	out_8(&mr->bus_status1, 0);	/* negate RST */
-#ifdef DO_ASYNC_RESET
-	if (how & SCSI_RESET_ASYNCHRONOUS) {
-		restore_flags(flags);
-		ret |= SCSI_RESET_PENDING;
-	} else
-#endif
-	{
-		handle_reset(ms);
-		restore_flags(flags);
-#ifndef MESH_NEW_STYLE_EH
-		finish_cmds(ms);
-#endif
-		ret |= SCSI_RESET_SUCCESS;
-	}
-	return ret;
+
+	/* Complete pending commands */
+	handle_reset(ms);
+	
+	return SUCCESS;
 }
 
 /*
@@ -553,13 +605,10 @@
 	return NOTIFY_DONE;
 }
 
-int
-mesh_command(Scsi_Cmnd *cmd)
-{
-	printk(KERN_WARNING "whoops... mesh_command called\n");
-	return -1;
-}
-
+/* Called with  meshinterrupt disabled, initialize the chipset
+ * and eventually do the initial bus reset. The lock must not be
+ * held since we can schedule.
+ */
 static void
 mesh_init(struct mesh_state *ms)
 {
@@ -568,6 +617,7 @@
 
 	udelay(100);
 
+	/* Reset controller */
 	out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16);	/* stop dma */
 	out_8(&mr->exception, 0xff);	/* clear all exception bits */
 	out_8(&mr->error, 0xff);	/* clear all error bits */
@@ -578,15 +628,28 @@
 	out_8(&mr->sel_timeout, 25);	/* 250ms */
 	out_8(&mr->sync_params, ASYNC_PARAMS);
 
-	out_8(&mr->bus_status1, BS1_RST);	/* assert RST */
-	udelay(30);			/* leave it on for >= 25us */
-	out_8(&mr->bus_status1, 0);	/* negate RST */
-
+	if (init_reset_delay) {
+		printk(KERN_INFO "mesh: performing initial bus reset...\n");
+		
+		/* Reset bus */
+		out_8(&mr->bus_status1, BS1_RST);	/* assert RST */
+		udelay(30);			/* leave it on for >= 25us */
+		out_8(&mr->bus_status1, 0);	/* negate RST */
+
+		/* Wait for bus to come back */
+		current->state = TASK_UNINTERRUPTIBLE;
+		schedule_timeout((init_reset_delay * HZ) / 1000);
+	}
+	
+	/* Reconfigure controller */
+	out_8(&mr->interrupt, 0xff);	/* clear all interrupt bits */
 	out_8(&mr->sequence, SEQ_FLUSHFIFO);
 	udelay(1);
 	out_8(&mr->sync_params, ASYNC_PARAMS);
 	out_8(&mr->sequence, SEQ_ENBRESEL);
-	out_8(&mr->interrupt, 0xff);	/* clear all interrupt bits */
+
+	ms->phase = idle;
+	ms->msgphase = msg_none;
 }
 
 /*
@@ -646,6 +709,8 @@
 		       cmd->use_sg, cmd->request_buffer, cmd->request_bufflen);
 	}
 #endif
+	if (ms->dma_started)
+		panic("mesh: double DMA start !\n");
 
 	ms->phase = arbitrating;
 	ms->msgphase = msg_none;
@@ -770,28 +835,6 @@
 	}
 }
 
-#ifndef MESH_NEW_STYLE_EH
-static void
-finish_cmds(void *data)
-{
-	struct mesh_state *ms = data;
-	Scsi_Cmnd *cmd;
-	unsigned long flags;
-
-	for (;;) {
-		spin_lock_irqsave(&io_request_lock, flags);
-		cmd = ms->completed_q;
-		if (cmd == NULL) {
-			spin_unlock_irqrestore(&io_request_lock, flags);
-			break;
-		}
-		ms->completed_q = (Scsi_Cmnd *) cmd->host_scribble;
-		(*cmd->scsi_done)(cmd);
-		spin_unlock_irqrestore(&io_request_lock, flags);
-	}
-}
-#endif /* MESH_NEW_STYLE_EH */
-
 static inline void
 add_sdtr_msg(struct mesh_state *ms)
 {
@@ -1316,10 +1359,13 @@
 		dumpslog(ms);
 	}
 
+	if (ms->dma_started) {
+		printk(KERN_ERR "mesh: reselected with DMA started !\n");
+		halt_dma(ms);
+	}
 	ms->current_req = NULL;
 	ms->phase = dataing;
 	ms->msgphase = msg_in;
-	ms->dma_started = 0;
 	ms->n_msgout = 0;
 	ms->last_n_msgout = 0;
 	prev = ms->conn_tgt;
@@ -1738,18 +1784,7 @@
 static void
 mesh_completed(struct mesh_state *ms, Scsi_Cmnd *cmd)
 {
-#ifdef MESH_NEW_STYLE_EH
 	(*cmd->scsi_done)(cmd);
-#else
-	if (ms->completed_q == NULL)
-		ms->completed_q = cmd;
-	else
-		ms->completed_qtail->host_scribble = (void *) cmd;
-	ms->completed_qtail = cmd;
-	cmd->host_scribble = NULL;
-	queue_task(&ms->tqueue, &tq_immediate);
-	mark_bh(IMMEDIATE_BH);
-#endif /* MESH_NEW_STYLE_EH */
 }
 
 /*
@@ -1769,24 +1804,29 @@
 	if (cmd) {
 		cmd->SCp.this_residual = cmd->request_bufflen;
 		if (cmd->use_sg > 0) {
+			int nseg;
 			total = 0;
 			scl = (struct scatterlist *) cmd->buffer;
 			off = ms->data_ptr;
-			for (i = 0; i < cmd->use_sg; ++i, ++scl) {
+			nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg,
+				 scsi_to_pci_dma_dir(cmd ->sc_data_direction));
+			for (i = 0; i <nseg; ++i, ++scl) {
+				u32 dma_addr = sg_dma_address(scl);
+				u32 dma_len = sg_dma_len(scl);
+				
 				total += scl->length;
-				if (off >= scl->length) {
-					off -= scl->length;
+				if (off >= dma_len) {
+					off -= dma_len;
 					continue;
 				}
-				if (scl->length > 0xffff)
+				if (dma_len > 0xffff)
 					panic("mesh: scatterlist element >= 64k");
-				st_le16(&dcmds->req_count, scl->length - off);
+				st_le16(&dcmds->req_count, dma_len - off);
 				st_le16(&dcmds->command, dma_cmd);
-				st_le32(&dcmds->phy_addr,
-					virt_to_phys(scl->address) + off);
+				st_le32(&dcmds->phy_addr, dma_addr + off);
 				dcmds->xfer_status = 0;
 				++dcmds;
-				dtot += scl->length - off;
+				dtot += dma_len - off;
 				off = 0;
 			}
 		} else if (ms->data_ptr < cmd->request_bufflen) {
@@ -1794,6 +1834,7 @@
 			if (dtot > 0xffff)
 				panic("mesh: transfer size >= 64k");
 			st_le16(&dcmds->req_count, dtot);
+			/* XXX Use pci DMA API here ... */
 			st_le32(&dcmds->phy_addr,
 				virt_to_phys(cmd->request_buffer) + ms->data_ptr);
 			dcmds->xfer_status = 0;
@@ -1860,6 +1901,12 @@
 		       ms->conn_tgt, ms->data_ptr, cmd->request_bufflen,
 		       ms->tgts[ms->conn_tgt].data_goes_out);
 	}
+	if (cmd->use_sg != 0) {
+		struct scatterlist *sg;
+		sg = (struct scatterlist *)cmd->request_buffer;
+		pci_unmap_sg(ms->pdev, sg, cmd->use_sg,
+			     scsi_to_pci_dma_dir(cmd->sc_data_direction));
+	}
 	ms->dma_started = 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/mesh.h linux/drivers/scsi/mesh.h
--- linux.orig/drivers/scsi/mesh.h	2000-09-19 15:31:53.000000000 +0000
+++ linux/drivers/scsi/mesh.h	2002-07-20 01:08:28.000000000 +0000
@@ -9,26 +9,27 @@
 
 int mesh_detect(Scsi_Host_Template *);
 int mesh_release(struct Scsi_Host *);
-int mesh_command(Scsi_Cmnd *);
 int mesh_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int mesh_abort(Scsi_Cmnd *);
-int mesh_reset(Scsi_Cmnd *, unsigned int);
+int mesh_host_reset(Scsi_Cmnd *);
 
-#define SCSI_MESH {					\
-	proc_name:	"mesh",				\
-	name:		"MESH",				\
-	detect:		mesh_detect,			\
-	release:	mesh_release,			\
-	command:	mesh_command,			\
-	queuecommand:	mesh_queue,			\
-	abort:		mesh_abort,			\
-	reset:		mesh_reset,			\
-	can_queue:	20,				\
-	this_id:	7,				\
-	sg_tablesize:	SG_ALL,				\
-	cmd_per_lun:	2,				\
-	use_clustering:	DISABLE_CLUSTERING,		\
-	use_new_eh_code: 1,				\
+#define SCSI_MESH {						\
+	proc_name:			"mesh",			\
+	name:				"MESH",			\
+	detect:				mesh_detect,		\
+	release:			mesh_release,		\
+	command:			NULL,			\
+	queuecommand:			mesh_queue,		\
+	eh_abort_handler:		mesh_abort,		\
+	eh_device_reset_handler:	NULL,			\
+	eh_bus_reset_handler:		NULL,			\
+	eh_host_reset_handler:		mesh_host_reset,	\
+	can_queue:			20,			\
+	this_id:			7,			\
+	sg_tablesize:			SG_ALL,			\
+	cmd_per_lun:			2,			\
+	use_clustering:			DISABLE_CLUSTERING,	\
+	use_new_eh_code: 		1,			\
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/oktagon_esp.c linux/drivers/scsi/oktagon_esp.c
--- linux.orig/drivers/scsi/oktagon_esp.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/oktagon_esp.c	2002-07-20 01:08:23.000000000 +0000
@@ -77,7 +77,9 @@
 long oktag_to_io(long *paddr, long *addr, long len);
 long oktag_from_io(long *addr, long *paddr, long len);
 
-static struct tq_struct tq_fake_dma = { NULL, 0, dma_commit, NULL };
+static struct tq_struct tq_fake_dma = {
+    routine:	dma_commit,
+};
 
 #define DMA_MAXTRANSFER 0x8000
 
@@ -589,3 +591,5 @@
 #endif
 	return 1;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/qlogicfas.c linux/drivers/scsi/qlogicfas.c
--- linux.orig/drivers/scsi/qlogicfas.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/qlogicfas.c	2002-07-20 01:08:36.000000000 +0000
@@ -271,11 +271,11 @@
 int	i,k;
 	k = 0;
 	i = jiffies + WATCHDOG;
-	while ( i > jiffies && !qabort && !((k = inb(qbase + 4)) & 0xe0)) {
+	while (time_before(jiffies, i) && !qabort && !((k = inb(qbase + 4)) & 0xe0)) {
 		barrier();
 		cpu_relax();
 	}
-	if (i <= jiffies)
+	if (time_after_eq(jiffies, i))
 		return (DID_TIME_OUT);
 	if (qabort)
 		return (qabort == 1 ? DID_ABORT : DID_RESET);
@@ -405,8 +405,8 @@
 	}
 /*** Enter Status (and Message In) Phase ***/
 	k = jiffies + WATCHDOG;
-	while ( k > jiffies && !qabort && !(inb(qbase + 4) & 6));	/* wait for status phase */
-	if ( k <= jiffies ) {
+	while ( time_before(jiffies, k) && !qabort && !(inb(qbase + 4) & 6));	/* wait for status phase */
+	if ( time_after_eq(jiffies, k) ) {
 		ql_zap();
 		return (DID_TIME_OUT << 16);
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- linux.orig/drivers/scsi/qlogicfc.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/qlogicfc.c	2002-07-20 01:08:27.000000000 +0000
@@ -803,7 +803,7 @@
 			outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
 			isp2x00_enable_irqs(host);
 			/* wait for the loop to come up */
-			for (wait_time = jiffies + 10 * HZ; wait_time > jiffies && hostdata->adapter_state == AS_LOOP_DOWN;) {
+			for (wait_time = jiffies + 10 * HZ; time_before(jiffies, wait_time) && hostdata->adapter_state == AS_LOOP_DOWN;) {
 			        barrier();
 				cpu_relax();
 			}
@@ -820,7 +820,7 @@
 	   some time before recognizing it is attached to a fabric */
 
 #if ISP2x00_FABRIC
-	for (wait_time = jiffies + 5 * HZ; wait_time > jiffies;) {
+	for (wait_time = jiffies + 5 * HZ; time_before(jiffies, wait_time);) {
 		barrier();
 		cpu_relax();
 	}
@@ -1343,18 +1343,11 @@
 
 	num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
 	num_free = (num_free > 2) ? num_free - 2 : 0;
-	host->can_queue = hostdata->queued + num_free;
+	host->can_queue = host->host_busy + num_free;
 	if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
 		host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
 	host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
 
-	/* this is really gross */
-	if (host->can_queue <= host->host_busy){
-	        if (host->can_queue+2 < host->host_busy) 
-			DEBUG(printk("qlogicfc%d.c crosses its fingers.\n", hostdata->host_id));
-		host->can_queue = host->host_busy + 1;
-	}
-
 	LEAVE("isp2x00_queuecommand");
 
 	return 0;
@@ -1623,17 +1616,11 @@
 
 	num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
 	num_free = (num_free > 2) ? num_free - 2 : 0;
-	host->can_queue = hostdata->queued + num_free;
+	host->can_queue = host->host_busy + num_free;
 	if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
 		host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
 	host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
 
-	if (host->can_queue <= host->host_busy){
-	        if (host->can_queue+2 < host->host_busy) 
-		        DEBUG(printk("qlogicfc%d : crosses its fingers.\n", hostdata->host_id));
-		host->can_queue = host->host_busy + 1;
-	}
-
 	outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
 	LEAVE_INTR("isp2x00_intr_handler");
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- linux.orig/drivers/scsi/scsi.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/scsi.c	2002-07-20 01:08:37.000000000 +0000
@@ -156,7 +156,12 @@
  */
 extern void scsi_old_done(Scsi_Cmnd * SCpnt);
 extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
+extern int scsi_old_reset(Scsi_Cmnd *SCpnt, unsigned int flag);
 
+/* 
+ * Private interface into the new error handling code.
+ */
+extern int scsi_new_reset(Scsi_Cmnd *SCpnt, unsigned int flag);
 
 /*
  * Function:    scsi_initialize_queue()
@@ -2726,6 +2731,102 @@
 }
 
 /*
+ * Function:	scsi_reset_provider_done_command
+ *
+ * Purpose:	Dummy done routine.
+ *
+ * Notes:	Some low level drivers will call scsi_done and end up here,
+ *		others won't bother.
+ *		We don't want the bogus command used for the bus/device
+ *		reset to find its way into the mid-layer so we intercept
+ *		it here.
+ */
+static void
+scsi_reset_provider_done_command(Scsi_Cmnd *SCpnt)
+{
+}
+
+/*
+ * Function:	scsi_reset_provider
+ *
+ * Purpose:	Send requested reset to a bus or device at any phase.
+ *
+ * Arguments:	device	- device to send reset to
+ *		flag - reset type (see scsi.h)
+ *
+ * Returns:	SUCCESS/FAILURE.
+ *
+ * Notes:	This is used by the SCSI Generic driver to provide
+ *		Bus/Device reset capability.
+ */
+int
+scsi_reset_provider(Scsi_Device *dev, int flag)
+{
+	Scsi_Cmnd SC, *SCpnt = &SC;
+	int rtn;
+
+	memset(&SCpnt->eh_timeout, 0, sizeof(SCpnt->eh_timeout));
+	SCpnt->host                    	= dev->host;
+	SCpnt->device                  	= dev;
+	SCpnt->target                  	= dev->id;
+	SCpnt->lun                     	= dev->lun;
+	SCpnt->channel                 	= dev->channel;
+	SCpnt->request.rq_status       	= RQ_SCSI_BUSY;
+	SCpnt->request.waiting        	= NULL;
+	SCpnt->use_sg                  	= 0;
+	SCpnt->old_use_sg              	= 0;
+	SCpnt->old_cmd_len             	= 0;
+	SCpnt->underflow               	= 0;
+	SCpnt->transfersize            	= 0;
+	SCpnt->resid			= 0;
+	SCpnt->serial_number           	= 0;
+	SCpnt->serial_number_at_timeout	= 0;
+	SCpnt->host_scribble           	= NULL;
+	SCpnt->next                    	= NULL;
+	SCpnt->state                   	= SCSI_STATE_INITIALIZING;
+	SCpnt->owner	     		= SCSI_OWNER_MIDLEVEL;
+    
+	memset(&SCpnt->cmnd, '\0', sizeof(SCpnt->cmnd));
+    
+	SCpnt->scsi_done		= scsi_reset_provider_done_command;
+	SCpnt->done			= NULL;
+	SCpnt->reset_chain		= NULL;
+        
+	SCpnt->buffer			= NULL;
+	SCpnt->bufflen			= 0;
+	SCpnt->request_buffer		= NULL;
+	SCpnt->request_bufflen		= 0;
+
+	SCpnt->internal_timeout		= NORMAL_TIMEOUT;
+	SCpnt->abort_reason		= DID_ABORT;
+
+	SCpnt->cmd_len			= 0;
+
+	SCpnt->sc_data_direction	= SCSI_DATA_UNKNOWN;
+	SCpnt->sc_request		= NULL;
+	SCpnt->sc_magic			= SCSI_CMND_MAGIC;
+
+	/*
+	 * Sometimes the command can get back into the timer chain,
+	 * so use the pid as an identifier.
+	 */
+	SCpnt->pid			= 0;
+
+	if (dev->host->hostt->use_new_eh_code) {
+		rtn = scsi_new_reset(SCpnt, flag);
+	} else {
+		unsigned long flags;
+
+		spin_lock_irqsave(&io_request_lock, flags);
+		rtn = scsi_old_reset(SCpnt, flag);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+	}
+
+	scsi_delete_timer(SCpnt);
+	return rtn;
+}
+
+/*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
  * adjust the settings for this buffer only.  This must remain at the end
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- linux.orig/drivers/scsi/scsi.h	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/scsi.h	2002-07-20 01:08:29.000000000 +0000
@@ -849,6 +849,16 @@
 	current->state = TASK_RUNNING;	\
     }; }
 
+/*
+ * old style reset request from external source
+ * (private to sg.c and scsi_error.c, supplied by scsi_obsolete.c)
+ */
+#define SCSI_TRY_RESET_DEVICE	1
+#define SCSI_TRY_RESET_BUS	2
+#define SCSI_TRY_RESET_HOST	3
+
+extern int scsi_reset_provider(Scsi_Device *, int);
+
 #endif
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
--- linux.orig/drivers/scsi/scsi_debug.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/scsi_debug.c	2002-07-20 01:08:24.000000000 +0000
@@ -14,7 +14,7 @@
  *
  *   D. Gilbert (dpg) work for MOD device test [20010421]
  *   dpg, work for devfs large number of disks [20010809]
- *   dpg, make more generic [20011123]
+ *   dpg, use vmalloc() more inquiry+mode_sense [20020302]
  */
 
 #include <linux/config.h>
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
+#include <linux/vmalloc.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -45,7 +46,7 @@
 #include <linux/version.h>
 #endif
 
-static char scsi_debug_version_str[] = "Version: 0.57 (20011209)";
+static char scsi_debug_version_str[] = "Version: 0.58 (20020302)";
 
 #ifndef SCSI_CMD_READ_16
 #define SCSI_CMD_READ_16 0x88
@@ -59,22 +60,26 @@
 #define DEF_DEV_SIZE_MB   8
 #define DEF_FAKE_BLK0   0
 
+#define DEF_OPTS   0
+#define SCSI_DEBUG_OPT_NOISE   1
+#define SCSI_DEBUG_OPT_MEDIUM_ERR   2
+
+#define OPT_MEDIUM_ERR_ADDR   0x1234
+
 static int scsi_debug_num_devs = DEF_NR_FAKE_DEVS;
+static int scsi_debug_opts = DEF_OPTS;
 
 #define NR_HOSTS_PRESENT (((scsi_debug_num_devs - 1) / 7) + 1)
 #define N_HEAD          8
 #define N_SECTOR        32
-#define DISK_READONLY(TGT)      (0)
-#define DISK_REMOVEABLE(TGT)    (0)
+#define DEV_READONLY(TGT)      (0)
+#define DEV_REMOVEABLE(TGT)    (0)
 #define DEVICE_TYPE(TGT) (TYPE_DISK);
 
 #define SCSI_DEBUG_MAILBOXES (scsi_debug_num_devs + 1)
 
 static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
 #define STORE_SIZE (scsi_debug_dev_size_mb * 1024 * 1024)
-#define STORE_ELEM_ORDER 1
-#define STORE_ELEM_SIZE (PAGE_SIZE * (1 << STORE_ELEM_ORDER))
-#define STORE_ELEMENTS ((STORE_SIZE / STORE_ELEM_SIZE) + 1)
 
 /* default sector size is 512 bytes, 2**9 bytes */
 #define POW2_SECT_SIZE 9
@@ -82,8 +87,6 @@
 
 #define N_CYLINDER (STORE_SIZE / (SECT_SIZE * N_SECTOR * N_HEAD))
 
-static int scsi_debug_fake_blk0 = DEF_FAKE_BLK0;
-
 /* Do not attempt to use a timer to simulate a real disk with latency */
 /* Only use this in the actual kernel, not in the simulator. */
 #define IMMEDIATE
@@ -94,20 +97,14 @@
 #define DISK_SPEED     (HZ/10)	/* 100ms */
 #define CAPACITY (N_HEAD * N_SECTOR * N_CYLINDER)
 #define SECT_SIZE_PER(TGT) SECT_SIZE
-#define SECT_PER_ELEM (STORE_ELEM_SIZE / SECT_SIZE)
 
 static int starts[] =
 {N_SECTOR,
  N_HEAD * N_SECTOR,		/* Single cylinder */
  N_HEAD * N_SECTOR * 4,
  0 /* CAPACITY */, 0};
-static int npart = 0;
 
-typedef struct scsi_debug_store_elem {
-	unsigned char * p;
-} Sd_store_elem;
-
-static Sd_store_elem * store_arr = 0;
+static unsigned char * fake_storep;
 
 typedef struct sdebug_dev_info {
 	Scsi_Device * sdp;
@@ -132,13 +129,18 @@
 
 static volatile done_fct_t * do_done = 0;
 
-struct Scsi_Host * SHpnt = NULL;
+static struct Scsi_Host * SHpnt = NULL;
 
+static int scsi_debug_inquiry(unsigned char * cmd, int target,
+			      unsigned char * buff, int bufflen,
+			      Sdebug_dev_info * devip);
+static int scsi_debug_mode_sense(unsigned char * cmd, int target,
+			         unsigned char * buff, int bufflen,
+			         Sdebug_dev_info * devip);
 static int scsi_debug_read(Scsi_Cmnd * SCpnt, int upper_blk, int block, 
 			   int num, int * errstsp, Sdebug_dev_info * devip);
 static int scsi_debug_write(Scsi_Cmnd * SCpnt, int upper_blk, int block, 
 			    int num, int * errstsp, Sdebug_dev_info * devip);
-static void scsi_debug_send_self_command(struct Scsi_Host * shpnt);
 static void scsi_debug_intr_handle(unsigned long);
 static Sdebug_dev_info * devInfoReg(Scsi_Device * sdp);
 static void mk_sense_buffer(Sdebug_dev_info * devip, int index, int key, 
@@ -157,101 +159,11 @@
 #define SENSE_BUFF_LEN 32
 static char sense_buffers[NUM_SENSE_BUFFS][SENSE_BUFF_LEN];
 
-#ifdef SCSI_DUMP
-static void scsi_dump(Scsi_Cmnd * SCpnt, int flag)
-{
-	int i;
-	unsigned int *lpnt;
-	struct scatterlist *sgpnt = NULL;
-	printk("use_sg: %d", SCpnt->use_sg);
-	if (SCpnt->use_sg) {
-		sgpnt = (struct scatterlist *) SCpnt->buffer;
-		for (i = 0; i < SCpnt->use_sg; i++) {
-			lpnt = (int *) sgpnt[i].alt_address;
-			printk(":%p %p %d\n", sgpnt[i].alt_address, 
-			       sgpnt[i].address, sgpnt[i].length);
-			if (lpnt)
-				printk(" (Alt %x) ", lpnt[15]);
-		}
-	} else {
-		printk("nosg: %p %p %d\n", SCpnt->request.buffer, SCpnt->buffer,
-		       SCpnt->bufflen);
-		lpnt = (int *) SCpnt->request.buffer;
-		if (lpnt)
-			printk(" (Alt %x) ", lpnt[15]);
-	}
-	lpnt = (unsigned int *) SCpnt;
-	for (i = 0; i < sizeof(Scsi_Cmnd) / 4 + 1; i++) {
-		if ((i & 7) == 0)
-			printk("\n");
-		printk("%x ", *lpnt++);
-	}
-	printk("\n");
-	if (flag == 0)
-		return;
-	lpnt = (unsigned int *) sgpnt[0].alt_address;
-	for (i = 0; i < sizeof(Scsi_Cmnd) / 4 + 1; i++) {
-		if ((i & 7) == 0)
-			printk("\n");
-		printk("%x ", *lpnt++);
-	}
-#if 0
-	printk("\n");
-	lpnt = (unsigned int *) sgpnt[0].address;
-	for (i = 0; i < sizeof(Scsi_Cmnd) / 4 + 1; i++) {
-		if ((i & 7) == 0)
-			printk("\n");
-		printk("%x ", *lpnt++);
-	}
-	printk("\n");
-#endif
-	printk("DMA free %d sectors.\n", scsi_dma_free_sectors);
-}
-#endif
-
-static int made_block0 = 0;
-
-static void scsi_debug_mkblock0(unsigned char * buff, int bufflen,
-				Scsi_Cmnd * SCpnt)
-{
-	int i;
-	struct partition *p;
-
-	memset(buff, 0, bufflen);
-	*((unsigned short *) (buff + 510)) = 0xAA55;
-	p = (struct partition *) (buff + 0x1be);
-	i = 0;
-	while (starts[i + 1]) {
-		int start_cyl, end_cyl;
-
-		start_cyl = starts[i] / N_HEAD / N_SECTOR;
-		end_cyl = (starts[i + 1] - 1) / N_HEAD / N_SECTOR;
-		p->boot_ind = 0;
-
-		p->head = (i == 0 ? 1 : 0);
-		p->sector = 1 | ((start_cyl >> 8) << 6);
-		p->cyl = (start_cyl & 0xff);
-
-		p->end_head = N_HEAD - 1;
-		p->end_sector = N_SECTOR | ((end_cyl >> 8) << 6);
-		p->end_cyl = (end_cyl & 0xff);
-
-		p->start_sect = starts[i];
-		p->nr_sects = starts[i + 1] - starts[i];
-		p->sys_ind = 0x83;	/* Linux ext2 partition */
-		p++;
-		i++;
-	}
-	if (!npart)
-		npart = i;
-	made_block0 = 1;
-	i = (bufflen > STORE_ELEM_SIZE) ? STORE_ELEM_SIZE : bufflen;
-	memcpy(store_arr[0].p, buff, i);
-}
 
+static
 int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
-	unchar *cmd = (unchar *) SCpnt->cmnd;
+	unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
 	int block;
 	int upper_blk;
 	unsigned char *buff;
@@ -263,17 +175,12 @@
 	Sdebug_dev_info * devip = NULL;
 	char * sbuff;
 
-#ifdef CONFIG_SMP
-        /*
-         * The io_request_lock *must* be held at this point.
-         */
-        if(! spin_is_locked(&io_request_lock))
-        {
-                printk("Warning - io_request_lock is not held in "
-		       "queuecommand\n");
-        }
-#endif
-
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
+		printk(KERN_INFO "scsi_debug: queue_command: cmd ");
+		for (i = 0, num = SCpnt->cmd_len; i < num; ++i)
+	            printk("%02x ", cmd[i]);
+		printk("   use_sg=%d\n", SCpnt->use_sg);
+	}
 	/*
 	 * If we are being notified of the mid-level reposessing a command
 	 * due to timeout, just return.
@@ -282,14 +189,23 @@
 		return 0;
 	}
 
-	buff = (unsigned char *) SCpnt->request_buffer;
+        if (SCpnt->use_sg) { /* just use first element */
+                struct scatterlist *sgpnt = (struct scatterlist *)
+                                                SCpnt->request_buffer;
+
+                buff = sgpnt[0].address;
+                bufflen = sgpnt[0].length;
+                /* READ and WRITE process scatterlist themselves */
+        }
+        else
+                buff = (unsigned char *) SCpnt->request_buffer;
 
         /*
          * If a command comes for the ID of the host itself, just print
          * a silly message and return.
          */
         if(target == 7) {
-                printk("How do you do!\n");
+                printk(KERN_WARNING "How do you do!\n");
                 SCpnt->result = 0;
                 done(SCpnt);
                 return 0;
@@ -303,7 +219,7 @@
 #if 0
 	printk(KERN_INFO "sdebug:qc: host_no=%d, id=%d, sdp=%p, cmd=0x%x\n",
 	       (int)SCpnt->device->host->host_no, (int)SCpnt->device->id,
-	       SCpnt->device, (int)(unsigned char)*cmd);
+	       SCpnt->device, (int)*cmd);
 #endif
 	if (NULL == SCpnt->device->hostdata) {
 		devip = devInfoReg(SCpnt->device);
@@ -317,6 +233,13 @@
 	devip = SCpnt->device->hostdata;
 
 	switch (*cmd) {
+	case INQUIRY:     /* mandatory */
+		scsi_debug_errsts = scsi_debug_inquiry(cmd, target, buff, 
+						       bufflen, devip);
+		/* assume INQUIRY called first so setup max_cmd_len */
+		if (SCpnt->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
+			SCpnt->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
+		break;
 	case REQUEST_SENSE:	/* mandatory */
 		SCSI_LOG_LLQUEUE(3, printk("Request sense...\n"));
 		if (devip) {
@@ -354,23 +277,6 @@
 		}
 		scsi_debug_errsts = 0;
 		break;
-	case INQUIRY:     /* mandatory */
-		SCSI_LOG_LLQUEUE(3, printk("Inquiry...(%p %d)\n", buff, bufflen));
-		memset(buff, 0, bufflen);
-		buff[0] = DEVICE_TYPE(target);
-		buff[1] = DISK_REMOVEABLE(target) ? 0x80 : 0;	
-				/* Removable disk */
-		buff[2] = 2;	/* claim SCSI 2 */
-		buff[4] = 36 - 5;
-		memcpy(&buff[8], "Linux   ", 8);
-		memcpy(&buff[16], "scsi_debug      ", 16);
-		memcpy(&buff[32], "0002", 4);
-		scsi_debug_errsts = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)
-		if (SCpnt->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
-			SCpnt->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
-#endif
-		break;
 	case SEND_DIAGNOSTIC:     /* mandatory */
 		SCSI_LOG_LLQUEUE(3, printk("Send Diagnostic\n"));
 		if (buff)
@@ -378,7 +284,8 @@
 		scsi_debug_errsts = 0;
 		break;
 	case TEST_UNIT_READY:     /* mandatory */
-		SCSI_LOG_LLQUEUE(3, printk("Test unit ready(%p %d)\n", buff, bufflen));
+		SCSI_LOG_LLQUEUE(3, printk("Test unit ready(%p %d)\n", 
+					   buff, bufflen));
 		if (buff)
 			memset(buff, 0, bufflen);
 		scsi_debug_errsts = 0;
@@ -484,19 +391,15 @@
 		(done) (SCpnt);	
 		return 0;
 	case MODE_SENSE:
-		/*
-		 * Used to detect write protected status.
-		 */
-		scsi_debug_errsts = 0;
-		memset(buff, 0, 6);
+	case MODE_SENSE_10:
+		scsi_debug_errsts = 
+		    scsi_debug_mode_sense(cmd, target, buff, bufflen, devip);
 		break;
 	default:
 #if 0
-		SCSI_LOG_LLQUEUE(3, printk("Unknown command %d\n", *cmd));
-		SCpnt->result = DID_NO_CONNECT << 16;
-		done(SCpnt);
-		return 0;
-#else
+		printk(KERN_INFO "scsi_debug: Unsupported command, "
+		       "opcode=0x%x\n", (int)cmd[0]);
+#endif
 		if (check_reset(SCpnt, devip)) {
 			done(SCpnt);
 			return 0;
@@ -505,7 +408,6 @@
 				    (CHECK_CONDITION << 1);
 		mk_sense_buffer(devip, 2, ILLEGAL_REQUEST, 0x20, 0, 14);
 		break;
-#endif
 	}
 
 	spin_lock_irqsave(&mailbox_lock, iflags);
@@ -545,10 +447,11 @@
 	spin_unlock_irqrestore(&mailbox_lock, iflags);
 	add_timer(&timeout[i]);
 	if (!done)
-		printk("scsi_debug_queuecommand: done can't be NULL\n");
+		printk(KERN_ERR "scsi_debug_queuecommand: "
+		       "done can't be NULL\n");
 
 #if 0
-	printk("Sending command (%d %x %d %d)...", i, done, 
+	printk(KERN_INFO "Sending command (%d %x %d %d)...", i, done, 
 	       timeout[i].expires, jiffies);
 #endif
 #endif
@@ -556,6 +459,14 @@
 	return 0;
 }
 
+static int scsi_debug_ioctl(Scsi_Device *dev, int cmd, void *arg)
+{
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
+		printk(KERN_INFO "scsi_debug: ioctl: cmd=0x%x\n", cmd);
+	}
+	return -ENOTTY;
+}
+
 static int check_reset(Scsi_Cmnd * SCpnt, Sdebug_dev_info * devip)
 {
 	if (devip->reset) {
@@ -568,6 +479,190 @@
 	return 0;
 }
 
+#define SDEBUG_MAX_INQ_SZ 58
+
+static int scsi_debug_inquiry(unsigned char * cmd, int target,
+			      unsigned char * buff, int bufflen,
+			      Sdebug_dev_info * devip)
+{
+	unsigned char pq_pdt;
+	unsigned char arr[SDEBUG_MAX_INQ_SZ];
+	int min_len = bufflen > SDEBUG_MAX_INQ_SZ ? 
+			SDEBUG_MAX_INQ_SZ : bufflen;
+
+	SCSI_LOG_LLQUEUE(3, printk("Inquiry...(%p %d)\n", buff, bufflen));
+	if (bufflen < cmd[4])
+		printk(KERN_INFO "scsi_debug: inquiry: bufflen=%d "
+		       "< alloc_length=%d\n", bufflen, (int)cmd[4]);
+	memset(buff, 0, bufflen);
+	memset(arr, 0, SDEBUG_MAX_INQ_SZ);
+	pq_pdt = DEVICE_TYPE(target);
+	arr[0] = pq_pdt;
+	if (0x2 & cmd[1]) {  /* CMDDT bit set */
+		mk_sense_buffer(devip, 1, ILLEGAL_REQUEST, 0x24, 0, 14);
+		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+	}
+	else if (0x1 & cmd[1]) {  /* EVPD bit set */
+		if (0 == cmd[2]) { /* supported vital product data pages */
+			arr[3] = 1;
+			arr[4] = 0x80; /* ... only unit serial number */
+		}
+		else if (0x80 == cmd[2]) { /* unit serial number */
+			arr[1] = 0x80;
+			arr[3] = 4;
+			arr[4] = '1'; arr[5] = '2'; arr[6] = '3';
+			arr[7] = '4';
+		}
+		else {
+			/* Illegal request, invalid field in cdb */
+			mk_sense_buffer(devip, 1, ILLEGAL_REQUEST, 0x24, 0, 14);
+			return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		}
+		memcpy(buff, arr, min_len); 
+		return 0;
+	}
+	/* drops through here for a standard inquiry */
+	arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0;	/* Removable disk */
+	arr[2] = 3;	/* claim SCSI 3 */
+	arr[4] = SDEBUG_MAX_INQ_SZ - 5;
+	arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */
+	memcpy(&arr[8], "Linux   ", 8);
+	memcpy(&arr[16], "scsi_debug      ", 16);
+	memcpy(&arr[32], "0003", 4);
+	memcpy(buff, arr, min_len);
+	return 0;
+}
+
+/* <<Following mode page info copied from ST318451LW>> */ 
+
+static int sdebug_err_recov_pg(unsigned char * p, int pcontrol, int target)
+{	/* Read-Write Error Recovery page for mode_sense */
+	unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, 
+					5, 0, 0xff, 0xff};
+
+	memcpy(p, err_recov_pg, sizeof(err_recov_pg));
+	if (1 == pcontrol)
+		memset(p + 2, 0, sizeof(err_recov_pg) - 2);
+	return sizeof(err_recov_pg);
+}
+
+static int sdebug_disconnect_pg(unsigned char * p, int pcontrol, int target)
+{ 	/* Disconnect-Reconnect page for mode_sense */
+	unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, 
+					 0, 0, 0, 0, 0, 0, 0, 0};
+
+	memcpy(p, disconnect_pg, sizeof(disconnect_pg));
+	if (1 == pcontrol)
+		memset(p + 2, 0, sizeof(disconnect_pg) - 2);
+	return sizeof(disconnect_pg);
+}
+
+static int sdebug_caching_pg(unsigned char * p, int pcontrol, int target)
+{ 	/* Caching page for mode_sense */
+	unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, 
+		0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0,     0, 0, 0, 0};
+
+	memcpy(p, caching_pg, sizeof(caching_pg));
+	if (1 == pcontrol)
+		memset(p + 2, 0, sizeof(caching_pg) - 2);
+	return sizeof(caching_pg);
+}
+
+static int sdebug_ctrl_m_pg(unsigned char * p, int pcontrol, int target)
+{ 	/* Control mode page for mode_sense */
+	unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
+				     0, 0, 0x2, 0x4b};
+
+	memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
+	if (1 == pcontrol)
+		memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
+	return sizeof(ctrl_m_pg);
+}
+
+
+#define SDEBUG_MAX_MSENSE_SZ 256
+
+static int scsi_debug_mode_sense(unsigned char * cmd, int target,
+			         unsigned char * buff, int bufflen,
+			         Sdebug_dev_info * devip)
+{
+	unsigned char dbd;
+	int pcontrol, pcode;
+	unsigned char dev_spec;
+	int alloc_len, msense_6, offset, len;
+	unsigned char * ap;
+	unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
+	int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ? 
+			SDEBUG_MAX_MSENSE_SZ : bufflen;
+
+	SCSI_LOG_LLQUEUE(3, printk("Mode sense ...(%p %d)\n", buff, bufflen));
+	dbd = cmd[1] & 0x8;
+	pcontrol = (cmd[2] & 0xc0) >> 6;
+	pcode = cmd[2] & 0x3f;
+	msense_6 = (MODE_SENSE == cmd[0]);
+	alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[6]);
+	/* printk(KERN_INFO "msense: dbd=%d pcontrol=%d pcode=%d "
+		"msense_6=%d alloc_len=%d\n", dbd, pcontrol, pcode, "
+		"msense_6, alloc_len); */
+	if (bufflen < alloc_len)
+		printk(KERN_INFO "scsi_debug: mode_sense: bufflen=%d "
+		       "< alloc_length=%d\n", bufflen, alloc_len);
+	memset(buff, 0, bufflen);
+	memset(arr, 0, SDEBUG_MAX_MSENSE_SZ);
+	if (0x3 == pcontrol) {  /* Saving values not supported */
+		mk_sense_buffer(devip, 1, ILLEGAL_REQUEST, 0x39, 0, 14);
+		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+	}
+	dev_spec = DEV_READONLY(target) ? 0x80 : 0x0;
+	if (msense_6) {
+		arr[2] = dev_spec;
+		offset = 4;
+	}
+	else {
+		arr[3] = dev_spec;
+		offset = 8;
+	}
+	ap = arr + offset;
+
+	switch (pcode) {
+	case 0x1:	/* Read-Write error recovery page, direct access */
+		len = sdebug_err_recov_pg(ap, pcontrol, target);
+		offset += len;
+		break;
+	case 0x2:	/* Disconnect-Reconnect page, all devices */
+		len = sdebug_disconnect_pg(ap, pcontrol, target);
+		offset += len;
+		break;
+	case 0x8:	/* Caching page, direct access */
+		len = sdebug_caching_pg(ap, pcontrol, target);
+		offset += len;
+		break;
+	case 0xa:	/* Control Mode page, all devices */
+		len = sdebug_ctrl_m_pg(ap, pcontrol, target);
+		offset += len;
+		break;
+	case 0x3f:	/* Read all Mode pages */
+		len = sdebug_err_recov_pg(ap, pcontrol, target);
+		len += sdebug_disconnect_pg(ap + len, pcontrol, target);
+		len += sdebug_caching_pg(ap + len, pcontrol, target);
+		len += sdebug_ctrl_m_pg(ap + len, pcontrol, target);
+		offset += len;
+		break;
+	default:
+		mk_sense_buffer(devip, 1, ILLEGAL_REQUEST, 0x24, 0, 14);
+		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+	}
+	if (msense_6)
+		arr[0] = offset - 1;
+	else {
+		offset -= 2;
+		arr[0] = (offset >> 8) & 0xff; 
+		arr[1] = offset & 0xff; 
+	}
+	memcpy(buff, arr, min_len);
+	return 0;
+}
+
 static int scsi_debug_read(Scsi_Cmnd * SCpnt, int upper_blk, int block, 
 			   int num, int * errstsp, Sdebug_dev_info * devip)
 {
@@ -592,11 +687,19 @@
 			usleep(delay);
 	}
 #endif
-
+	if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
+	    (block >= OPT_MEDIUM_ERR_ADDR) && 
+	    (block < (OPT_MEDIUM_ERR_ADDR + num))) {
+		*errstsp = (COMMAND_COMPLETE << 8) |
+			   (CHECK_CONDITION << 1);
+		mk_sense_buffer(devip, 1, MEDIUM_ERROR, 0x11, 0, 14);
+		/* claim unrecoverable read error */
+		return 1;
+	}
 	read_lock_irqsave(&sdebug_atomic_rw, iflags);
         sgcount = 0;
 	nbytes = bufflen;
-	/* printk("scsi_debug_read: block=%d, tot_bufflen=%d\n", 
+	/* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n", 
 	       block, bufflen); */
 	if (SCpnt->use_sg) {
 		sgcount = 0;
@@ -606,30 +709,7 @@
 	}
 	*errstsp = 0;
 	do {
-		int resid, k, off, len, rem, blk;
-		unsigned char * bp;
-
-		/* If this is block 0, then we want to read the partition
-		 * table for this device.  Let's make one up */
-		if (scsi_debug_fake_blk0 && (block == 0) && (! made_block0)) {
-			scsi_debug_mkblock0(buff, bufflen, SCpnt);
-			*errstsp = 0;
-			break;
-		}
-		bp = buff;
-		blk = block;
-		for (resid = bufflen; resid > 0; resid -= len) {
-			k = blk / SECT_PER_ELEM; 
-			off = (blk % SECT_PER_ELEM) * SECT_SIZE;
-			rem = STORE_ELEM_SIZE - off;
-			len = (resid > rem) ? rem : resid;
-/* printk("sdr: blk=%d k=%d off=%d rem=%d resid"
-			       "=%d len=%d  sgcount=%d\n", blk, k, 
-				off, rem, resid, len, sgcount); */
-			memcpy(bp, store_arr[k].p + off, len);
-			bp += len;
-			blk += len / SECT_SIZE;
-		}
+		memcpy(buff, fake_storep + (block * SECT_SIZE), bufflen);
 #if 0
 		/* Simulate a disk change */
 		if (block == 0xfff0) {
@@ -655,7 +735,8 @@
 			}
 		}
 		else if (nbytes > 0)
-			printk("sdebug_read: unexpected nbytes=%d\n", nbytes);
+			printk(KERN_WARNING "sdebug_read: unexpected "
+			       "nbytes=%d\n", nbytes);
 	} while (nbytes);
 	read_unlock_irqrestore(&sdebug_atomic_rw, iflags);
 	return 0;
@@ -679,13 +760,6 @@
 
 	write_lock_irqsave(&sdebug_atomic_rw, iflags);
         sgcount = 0;
-#ifdef SCSI_DUMP
-	if (block != *((unsigned long *) (buff + 60))) {
-		printk("%x %x :", block, *((unsigned long *) (buff + 60)));
-		scsi_dump(SCpnt, 1);
-		printk("Bad block written.\n");
-	}
-#endif
 	nbytes = bufflen;
 	if (SCpnt->use_sg) {
 		sgcount = 0;
@@ -695,20 +769,7 @@
 	}
 	*errstsp = 0;
 	do {
-		int resid, k, off, len, rem, blk;
-		unsigned char * bp;
-
-		bp = buff;
-		blk = block;
-		for (resid = bufflen; resid > 0; resid -= len) {
-			k = blk / SECT_PER_ELEM; 
-			off = (blk % SECT_PER_ELEM) * SECT_SIZE;
-			rem = STORE_ELEM_SIZE - off;
-			len = (resid > rem) ? rem : resid;
-			memcpy(store_arr[k].p + off, bp, len);
-			bp += len;
-			blk += len / SECT_SIZE;
-		}
+		memcpy(fake_storep + (block * SECT_SIZE), buff, bufflen);
 
 		nbytes -= bufflen;
 		if (SCpnt->use_sg) {
@@ -720,52 +781,13 @@
 			}
 		}
 		else if (nbytes > 0)
-			printk("sdebug_write: unexpected nbytes=%d\n", nbytes);
+			printk(KERN_WARNING "sdebug_write: "
+			       "unexpected nbytes=%d\n", nbytes);
 	} while (nbytes);
 	write_unlock_irqrestore(&sdebug_atomic_rw, iflags);
 	return 0;
 }
 
-static void scsi_debug_send_self_command(struct Scsi_Host * shpnt)
-{
-	static unsigned char cmd[6] =
-	{TEST_UNIT_READY, 0, 0, 0, 0, 0};
-
-        Scsi_Request  * scp;
-        Scsi_Device   * sdev;
-        
-        printk("Allocating host dev\n");
-        sdev = scsi_get_host_dev(shpnt);
-        if(sdev==NULL)
-        {
-        	printk("Out of memory.\n");
-        	return;
-        }
-        
-        printk("Got %p. Allocating command block\n", sdev);
-        scp  = scsi_allocate_request(sdev);
-        printk("Got %p\n", scp);
-        
-        if(scp==NULL)
-        {
-        	printk("Out of memory.\n");
-        	goto bail;
-        }
-
-        scp->sr_cmd_len = 6;
-        scp->sr_use_sg = 0;
-        
-        printk("Sending command\n");
-        scsi_wait_req (scp, (void *) cmd, (void *) NULL,
-                       0, 100, 3);
-        
-        printk("Releasing command\n");
-        scsi_release_request(scp);
-bail:
-	printk("Freeing device\n");
-        scsi_free_host_dev(sdev);
-}
-
 /* A "high" level interrupt handler.  This should be called once per jiffy
  * to simulate a regular scsi disk.  We use a timer to do this. */
 
@@ -784,18 +806,19 @@
 	SCint[indx] = NULL;
 
 	if (!my_done) {
-		printk("scsi_debug_intr_handle: Unexpected interrupt\n");
+		printk(KERN_ERR "scsi_debug_intr_handle: Unexpected "
+		       "interrupt\n");
 		return;
 	}
 #if 0
-	printk("In intr_handle...");
-	printk("...done %d %x %d %d\n", i, my_done, to, jiffies);
-	printk("In intr_handle: %d %x %x\n", i, SCtmp, my_done);
+	printk(KERN_INFO "In intr_handle...");
+	printk(KERN_INFO "...done %d %x %d %d\n", i, my_done, to, jiffies);
+	printk(KERN_INFO "In intr_handle: %d %x %x\n", i, SCtmp, my_done);
 #endif
 
 	my_done(SCtmp);
 #if 0
-	printk("Called done.\n");
+	printk(KERN_INFO "Called done.\n");
 #endif
 }
 
@@ -803,39 +826,44 @@
 
 static int do_init(void)
 {
-	int sz;
+	int sz = STORE_SIZE;
 
 	starts[3] = CAPACITY;
-	sz = sizeof(Sd_store_elem) * STORE_ELEMENTS;
-	store_arr = kmalloc(sz, GFP_ATOMIC);
-	if (NULL == store_arr)
+	fake_storep = vmalloc(sz);
+	if (NULL == fake_storep)
 		return 1;
-	memset(store_arr, 0, sz);
+	memset(fake_storep, 0, sz);
+
 	sz = sizeof(done_fct_t) * SCSI_DEBUG_MAILBOXES;
 	do_done = kmalloc(sz, GFP_ATOMIC);
-	if (NULL == do_done) {
-		kfree(store_arr);
-		return 1;
-	}
+	if (NULL == do_done)
+		goto out;
 	memset((void *)do_done, 0, sz);
+
 	sz = sizeof(struct timer_list) * SCSI_DEBUG_MAILBOXES;
 	timeout = kmalloc(sz, GFP_ATOMIC);
-	if (NULL == timeout) {
-		kfree((void *)do_done);
-		kfree(store_arr);
-		return 1;
-	}
+	if (NULL == timeout)
+		goto out;
 	memset(timeout, 0, sz);
+
 	sz = sizeof(Scsi_Cmnd *) * SCSI_DEBUG_MAILBOXES;
 	SCint = kmalloc(sz, GFP_ATOMIC);
-	if (NULL == SCint) {
-		kfree(timeout);
-		kfree((void *)do_done);
-		kfree(store_arr);
-		return 1;
-	}
+	if (NULL == SCint)
+		goto out;
 	memset(SCint, 0, sz);
+
 	return 0;
+
+out:
+	if (fake_storep)
+		vfree(fake_storep);
+	if (do_done)
+		kfree((void *)do_done);
+	if (timeout)
+		kfree(timeout);
+	if (SCint)
+		kfree(SCint);
+	return 1;
 }
 
 static void do_end(void)
@@ -843,34 +871,31 @@
 	kfree(SCint);
 	kfree(timeout);
 	kfree((void *)do_done);
-	kfree(store_arr);
+	vfree(fake_storep);
 }
 
 
-int scsi_debug_detect(Scsi_Host_Template * tpnt)
+static int scsi_debug_detect(Scsi_Host_Template * tpnt)
 {
-	int k, num, sz;
+	int k, sz;
 
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+		printk(KERN_INFO "scsi_debug: detect\n");
 	if (0 == initialized) {
 		++initialized;
 		sz = sizeof(Sdebug_dev_info) * scsi_debug_num_devs;
 		devInfop = kmalloc(sz, GFP_ATOMIC);
 		if (NULL == devInfop) {
-			printk("scsi_debug_detect: out of memory, 0.5\n");
+			printk(KERN_ERR "scsi_debug_detect: out of "
+			       "memory, 0.5\n");
 			return 0;
 		}
 		memset(devInfop, 0, sz);
 		if (do_init()) {
-			printk("scsi_debug_detect: out of memory, 0\n");
+			printk(KERN_ERR "scsi_debug_detect: out of memory"
+			       ", 0\n");
 			return 0;
 		}
-		for (k = 0; k < STORE_ELEMENTS; ++k) {
-			store_arr[k].p = (unsigned char *)
-				__get_free_pages(GFP_ATOMIC, STORE_ELEM_ORDER);
-			if (0 == store_arr[k].p)
-				goto detect_err;
-			memset(store_arr[k].p, 0, STORE_ELEM_SIZE);
-		}
 		for (k = 0; k < NUM_SENSE_BUFFS; ++k)
 			sense_buffers[k][0] = 0x70;
 		for (k = 0; k < NR_HOSTS_PRESENT; k++) {
@@ -880,43 +905,21 @@
 		return NR_HOSTS_PRESENT;
 	}
 	else {
-		printk("scsi_debug_detect: called again\n");
+		printk(KERN_WARNING "scsi_debug_detect: called again\n");
 		return 0;
 	}
-
-detect_err:
-	num = k;
-	for (k = 0; k < STORE_ELEMENTS; ++k) {
-		if (0 != store_arr[k].p) {
-			free_pages((unsigned long)store_arr[k].p, 
-				   STORE_ELEM_ORDER);
-			store_arr[k].p = NULL;
-		}
-	}
-	printk("scsi_debug_detect: out of memory: %d out of %d bytes\n",
-	       (int)(num * STORE_ELEM_SIZE), 
-	       (int)(scsi_debug_dev_size_mb * 1024 * 1024));
-	return 0;
 }
 
 
 static int num_releases = 0;
 
-int scsi_debug_release(struct Scsi_Host * hpnt)
+static int scsi_debug_release(struct Scsi_Host * hpnt)
 {
-	int k;
-	
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+		printk(KERN_INFO "scsi_debug: release\n");
 	scsi_unregister(hpnt);
 	if (++num_releases != NR_HOSTS_PRESENT)
 		return 0;
-
-	for (k = 0; k < STORE_ELEMENTS; ++k) {
-		if (0 != store_arr[k].p) {
-			free_pages((unsigned long)store_arr[k].p, 
-				   STORE_ELEM_ORDER);
-			store_arr[k].p = NULL;
-		}
-	}
 	do_end();
 	kfree(devInfop);
 	return 0;
@@ -966,8 +969,10 @@
 	sbuff[13] = asq;
 }
 
-int scsi_debug_abort(Scsi_Cmnd * SCpnt)
+static int scsi_debug_abort(Scsi_Cmnd * SCpnt)
 {
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+		printk(KERN_INFO "scsi_debug: abort\n");
 #if 1
 	++num_aborts;
 	return SUCCESS;
@@ -991,8 +996,10 @@
 #endif
 }
 
-int scsi_debug_biosparam(Disk * disk, kdev_t dev, int *info)
+static int scsi_debug_biosparam(Disk * disk, kdev_t dev, int *info)
 {
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+		printk(KERN_INFO "scsi_debug: biosparam\n");
 	/* int size = disk->capacity; */
 	info[0] = N_HEAD;
 	info[1] = N_SECTOR;
@@ -1002,36 +1009,13 @@
 	return 0;
 }
 
-#if 0
-int scsi_debug_reset(Scsi_Cmnd * SCpnt, unsigned int why)
-{
-	int i;
-	unsigned long iflags;
-
-	void (*my_done) (Scsi_Cmnd *);
-	printk("Bus unlocked by reset - %d\n", why);
-	scsi_debug_lockup = 0;
-	for (i = 0; i < SCSI_DEBUG_MAILBOXES; i++) {
-		if (SCint[i] == NULL)
-			continue;
-		SCint[i]->result = DID_RESET << 16;
-		my_done = do_done[i];
-		my_done(SCint[i]);
-		spin_lock_irqsave(&mailbox_lock, iflags);
-		SCint[i] = NULL;
-		do_done[i] = NULL;
-		timeout[i].function = NULL;
-		spin_unlock_irqrestore(&mailbox_lock, iflags);
-	}
-	return SCSI_RESET_SUCCESS;
-}
-#endif
-
-int scsi_debug_device_reset(Scsi_Cmnd * SCpnt)
+static int scsi_debug_device_reset(Scsi_Cmnd * SCpnt)
 {
 	Scsi_Device * sdp;
 	int k;
 
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+		printk(KERN_INFO "scsi_debug: device_reset\n");
 	++num_dev_resets;
 	if (SCpnt && ((sdp = SCpnt->device))) {
 		for (k = 0; k < scsi_debug_num_devs; ++k) {
@@ -1044,12 +1028,14 @@
 	return SUCCESS;
 }
 
-int scsi_debug_bus_reset(Scsi_Cmnd * SCpnt)
+static int scsi_debug_bus_reset(Scsi_Cmnd * SCpnt)
 {
 	Scsi_Device * sdp;
 	struct Scsi_Host * hp;
 	int k;
 
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+		printk(KERN_INFO "scsi_debug: bus_reset\n");
 	++num_bus_resets;
 	if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) {
 		for (k = 0; k < scsi_debug_num_devs; ++k) {
@@ -1060,10 +1046,12 @@
 	return SUCCESS;
 }
 
-int scsi_debug_host_reset(Scsi_Cmnd * SCpnt)
+static int scsi_debug_host_reset(Scsi_Cmnd * SCpnt)
 {
 	int k;
 
+	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+		printk(KERN_INFO "scsi_debug: host_reset\n");
 	++num_host_resets;
 	for (k = 0; k < scsi_debug_num_devs; ++k)
 		devInfop[k].reset = 1;
@@ -1081,7 +1069,7 @@
             scsi_debug_num_devs = tmp;
         return 1;
     } else {
-        printk("scsi_debug_num_devs: usage scsi_debug_num_devs=<n> "
+        printk(KERN_INFO "scsi_debug_num_devs: usage scsi_debug_num_devs=<n> "
                "(<n> can be from 1 to around 2000)\n");
         return 0;
     }
@@ -1098,13 +1086,32 @@
             scsi_debug_dev_size_mb = tmp;
         return 1;
     } else {
-        printk("scsi_debug_dev_size_mb: usage scsi_debug_dev_size_mb=<n>\n"
+        printk(KERN_INFO "scsi_debug_dev_size_mb: usage "
+	       "scsi_debug_dev_size_mb=<n>\n"
                "    (<n> is number of MB ram shared by all devs\n");
         return 0;
     }
 }
 
 __setup("scsi_debug_dev_size_mb=", scsi_debug_dev_size_mb_setup);
+
+static int __init scsi_debug_opts_setup(char *str)
+{   
+    int tmp; 
+    
+    if (get_option(&str, &tmp) == 1) {
+        if (tmp > 0)
+            scsi_debug_opts = tmp;
+        return 1;
+    } else {
+        printk(KERN_INFO "scsi_debug_opts: usage "
+	       "scsi_debug_opts=<n>\n"
+               "    (1->noise, 2->medium_error, 4->... (can be or-ed)\n");
+        return 0;
+    }
+}
+
+__setup("scsi_debug_opts=", scsi_debug_opts_setup);
 #endif
 
 MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
@@ -1113,6 +1120,8 @@
 MODULE_PARM_DESC(scsi_debug_num_devs, "number of SCSI devices to simulate");
 MODULE_PARM(scsi_debug_dev_size_mb, "i");
 MODULE_PARM_DESC(scsi_debug_dev_size_mb, "size in MB of ram shared by devs");
+MODULE_PARM(scsi_debug_opts, "i");
+MODULE_PARM_DESC(scsi_debug_opts, "1->noise, 2->medium_error, 4->...");
 
 #ifdef MODULE_LICENSE
 MODULE_LICENSE("GPL");
@@ -1123,8 +1132,9 @@
 const char * scsi_debug_info(struct Scsi_Host * shp)
 {
 	sprintf(sdebug_info, "scsi_debug, %s, num_devs=%d, "
-		"dev_size_mb=%d\n", scsi_debug_version_str,
-		scsi_debug_num_devs, scsi_debug_dev_size_mb);
+		"dev_size_mb=%d, opts=0x%x", scsi_debug_version_str,
+		scsi_debug_num_devs, scsi_debug_dev_size_mb,
+		scsi_debug_opts);
 	return sdebug_info;
 }
 
@@ -1140,55 +1150,28 @@
 	orig_length = length;
 
 	if (inout == 1) {
-		/* First check for the Signature */
-		if (length >= 10 && strncmp(buffer, "scsi_debug", 10) == 0) {
-			buffer += 11;
-			length -= 11;
-
-			if (buffer[length - 1] == '\n') {
-				buffer[length - 1] = '\0';
-				length--;
-			}
-			/*
-			 * OK, we are getting some kind of command.  Figure out
-			 * what we are supposed to do here.  Simulate bus lockups
-			 * to test our reset capability.
-			 */
-			if (length == 4 && strncmp(buffer, "test", length) == 0) {
-                                printk("Testing send self command %p\n", SHpnt);
-                                scsi_debug_send_self_command(SHpnt);
-                                return orig_length;
-                        }
-			if (length == 6 && strncmp(buffer, "lockup", length) == 0) {
-				scsi_debug_lockup = 1;
-				return orig_length;
-			}
-			if (length == 6 && strncmp(buffer, "unlock", length) == 0) {
-				scsi_debug_lockup = 0;
-				return orig_length;
-			}
-			printk("Unknown command:%s (%d)\n", buffer, length);
-		} else
-			printk("Wrong Signature:%10s\n", (char *) buffer);
-
-		return -EINVAL;
+		char arr[16];
+		int minLen = length > 15 ? 15 : length;
 
+		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+			return -EACCES;
+		memcpy(arr, buffer, minLen);
+		arr[minLen] = '\0';
+		if (1 != sscanf(arr, "%d", &pos))
+			return -EINVAL;
+		scsi_debug_opts = pos;
+		return length;
 	}
 	begin = 0;
 	pos = len = sprintf(buffer, "scsi_debug adapter driver, %s\n"
-	    "num_devs=%d, shared (ram) size=%d MB, sector_size=%d bytes\n" 
-	    "cylinders=%d, heads=%d, sectors=%d\n"
+	    "num_devs=%d, shared (ram) size=%d MB, opts=0x%x\n"
+	    "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n"
 	    "number of aborts=%d, device_reset=%d, bus_resets=%d, " 
 	    "host_resets=%d\n",
 	    scsi_debug_version_str, scsi_debug_num_devs, 
-	    scsi_debug_dev_size_mb, SECT_SIZE,
+	    scsi_debug_dev_size_mb, scsi_debug_opts, SECT_SIZE,
 	    N_CYLINDER, N_HEAD, N_SECTOR,
 	    num_aborts, num_dev_resets, num_bus_resets, num_host_resets);
-#if 0
-	 "This driver is not a real scsi driver, but it plays one on TV.\n"
-	 "It is very handy for debugging specific problems because you\n"
-			 "can simulate a variety of error conditions\n");
-#endif
 	if (pos < offset) {
 		len = 0;
 		begin = pos;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi_debug.h linux/drivers/scsi/scsi_debug.h
--- linux.orig/drivers/scsi/scsi_debug.h	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/scsi_debug.h	2002-07-20 01:08:36.000000000 +0000
@@ -3,24 +3,23 @@
 #include <linux/types.h>
 #include <linux/kdev_t.h>
 
-int scsi_debug_detect(Scsi_Host_Template *);
-int scsi_debug_command(Scsi_Cmnd *);
-int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-int scsi_debug_abort(Scsi_Cmnd *);
-int scsi_debug_biosparam(Disk *, kdev_t, int[]);
-int scsi_debug_bus_reset(Scsi_Cmnd *);
-int scsi_debug_dev_reset(Scsi_Cmnd *);
-int scsi_debug_host_reset(Scsi_Cmnd *);
-int scsi_debug_proc_info(char *, char **, off_t, int, int, int);
-const char * scsi_debug_info(struct Scsi_Host *);
+static int scsi_debug_detect(Scsi_Host_Template *);
+/* static int scsi_debug_command(Scsi_Cmnd *); */
+static int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+static int scsi_debug_abort(Scsi_Cmnd *);
+static int scsi_debug_biosparam(Disk *, kdev_t, int[]);
+static int scsi_debug_bus_reset(Scsi_Cmnd *);
+static int scsi_debug_device_reset(Scsi_Cmnd *);
+static int scsi_debug_host_reset(Scsi_Cmnd *);
+static int scsi_debug_proc_info(char *, char **, off_t, int, int, int);
+static const char * scsi_debug_info(struct Scsi_Host *);
 
 #ifndef NULL
 #define NULL 0
 #endif
 
 /*
- * Allow the driver to reject commands.  Thus we accept only one, but
- * and the mid-level will queue the remainder.
+ * This driver is written for the lk 2.4 series
  */
 #define SCSI_DEBUG_CANQUEUE  255
 
@@ -32,6 +31,7 @@
 		    info:              scsi_debug_info,		\
 		    detect:            scsi_debug_detect,	\
 		    release:           scsi_debug_release,	\
+		    ioctl:             scsi_debug_ioctl,	\
 		    queuecommand:      scsi_debug_queuecommand, \
 		    eh_abort_handler:  scsi_debug_abort,	\
 		    eh_bus_reset_handler: scsi_debug_bus_reset,	\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c
--- linux.orig/drivers/scsi/scsi_error.c	2001-09-09 17:52:35.000000000 +0000
+++ linux/drivers/scsi/scsi_error.c	2002-07-20 01:08:22.000000000 +0000
@@ -984,15 +984,24 @@
 	case DID_SOFT_ERROR:
 		goto maybe_retry;
 
+	case DID_ERROR:
+		if (msg_byte(SCpnt->result) == COMMAND_COMPLETE &&
+		    status_byte(SCpnt->result) == RESERVATION_CONFLICT)
+			/*
+			 * execute reservation conflict processing code
+			 * lower down
+			 */
+			break;
+		/* FALLTHROUGH */
+
 	case DID_BUS_BUSY:
 	case DID_PARITY:
-	case DID_ERROR:
 		goto maybe_retry;
 	case DID_TIME_OUT:
 		/*
-		   * When we scan the bus, we get timeout messages for
-		   * these commands if there is no device available.
-		   * Other hosts report DID_NO_CONNECT for the same thing.
+		 * When we scan the bus, we get timeout messages for
+		 * these commands if there is no device available.
+		 * Other hosts report DID_NO_CONNECT for the same thing.
 		 */
 		if ((SCpnt->cmnd[0] == TEST_UNIT_READY ||
 		     SCpnt->cmnd[0] == INQUIRY)) {
@@ -1009,13 +1018,7 @@
 			SCpnt->flags &= ~IS_RESETTING;
 			goto maybe_retry;
 		}
-		/*
-		 * Examine the sense data to figure out how to proceed from here.
-		 * If there is no sense data, we will be forced into the error
-		 * handler thread, where we get to examine the thing in a lot more
-		 * detail.
-		 */
-		return scsi_check_sense(SCpnt);
+		return SUCCESS;
 	default:
 		return FAILED;
 	}
@@ -1053,8 +1056,13 @@
 		 */
 		return SUCCESS;
 	case BUSY:
-	case RESERVATION_CONFLICT:
 		goto maybe_retry;
+
+	case RESERVATION_CONFLICT:
+		printk("scsi%d (%d,%d,%d) : RESERVATION CONFLICT\n", 
+		       SCpnt->host->host_no, SCpnt->channel,
+		       SCpnt->device->id, SCpnt->device->lun);
+		return SUCCESS; /* causes immediate I/O error */
 	default:
 		return FAILED;
 	}
@@ -1860,6 +1868,7 @@
 	 */
 
 	daemonize();
+	reparent_to_init();
 
 	/*
 	 * Set the name of this process.
@@ -1960,6 +1969,45 @@
 }
 
 /*
+ * Function:	scsi_new_reset
+ *
+ * Purpose:	Send requested reset to a bus or device at any phase.
+ *
+ * Arguments:	SCpnt	- command ptr to send reset with (usually a dummy)
+ *		flag - reset type (see scsi.h)
+ *
+ * Returns:	SUCCESS/FAILURE.
+ *
+ * Notes:	This is used by the SCSI Generic driver to provide
+ *		Bus/Device reset capability.
+ */
+int
+scsi_new_reset(Scsi_Cmnd *SCpnt, int flag)
+{
+	int rtn;
+
+	switch(flag) {
+	case SCSI_TRY_RESET_DEVICE:
+		rtn = scsi_try_bus_device_reset(SCpnt, 0);
+		if (rtn == SUCCESS)
+			break;
+		/* FALLTHROUGH */
+	case SCSI_TRY_RESET_BUS:
+		rtn = scsi_try_bus_reset(SCpnt);
+		if (rtn == SUCCESS)
+			break;
+		/* FALLTHROUGH */
+	case SCSI_TRY_RESET_HOST:
+		rtn = scsi_try_host_reset(SCpnt);
+		break;
+	default:
+		rtn = FAILED;
+	}
+
+	return rtn;
+}
+
+/*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
  * adjust the settings for this buffer only.  This must remain at the end
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- linux.orig/drivers/scsi/scsi_ioctl.c	2001-08-15 08:22:16.000000000 +0000
+++ linux/drivers/scsi/scsi_ioctl.c	2002-07-20 01:08:40.000000000 +0000
@@ -377,9 +377,12 @@
 scsi_ioctl_get_pci(Scsi_Device * dev, void *arg)
 {
 
-        if (!dev->host->pci_dev) return -ENXIO;
-        return copy_to_user(arg, dev->host->pci_dev->slot_name,
-                            sizeof(dev->host->pci_dev->slot_name));
+        if (!dev->host->pci_dev)
+        	return -ENXIO;
+        if(copy_to_user(arg, dev->host->pci_dev->slot_name,
+                            sizeof(dev->host->pci_dev->slot_name)))
+		return -EFAULT;
+	return 0;
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi_lib.c linux/drivers/scsi/scsi_lib.c
--- linux.orig/drivers/scsi/scsi_lib.c	2001-10-12 22:35:54.000000000 +0000
+++ linux/drivers/scsi/scsi_lib.c	2002-07-20 01:08:37.000000000 +0000
@@ -426,6 +426,7 @@
 	if (req->waiting != NULL) {
 		complete(req->waiting);
 	}
+	req_finished_io(req);
 	add_blkdev_randomness(MAJOR(req->rq_dev));
 
         SDpnt = SCpnt->device;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi_obsolete.c linux/drivers/scsi/scsi_obsolete.c
--- linux.orig/drivers/scsi/scsi_obsolete.c	2001-07-05 18:28:17.000000000 +0000
+++ linux/drivers/scsi/scsi_obsolete.c	2002-07-20 01:08:21.000000000 +0000
@@ -503,11 +503,18 @@
 					break;
 
 				case RESERVATION_CONFLICT:
-					printk("scsi%d, channel %d : RESERVATION CONFLICT performing"
-					       " reset.\n", SCpnt->host->host_no, SCpnt->channel);
-					scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS);
-					status = REDO;
+					/*
+					 * Most HAs will return an error for
+					 * this, so usually reservation
+					 * conflicts will  be processed under
+					 * DID_ERROR code
+					 */
+					printk("scsi%d (%d,%d,%d) : RESERVATION CONFLICT\n", 
+					       SCpnt->host->host_no, SCpnt->channel,
+					       SCpnt->device->id, SCpnt->device->lun);
+					status = CMD_FINISHED; /* returns I/O error */
 					break;
+                                        
 				default:
 					printk("Internal error %s %d \n"
 					 "status byte = %d \n", __FILE__,
@@ -557,6 +564,14 @@
 		exit = (DRIVER_HARD | SUGGEST_ABORT);
 		break;
 	case DID_ERROR:
+		if (msg_byte(result) == COMMAND_COMPLETE &&
+		    status_byte(result) == RESERVATION_CONFLICT) {
+			printk("scsi%d (%d,%d,%d) : RESERVATION CONFLICT\n", 
+			       SCpnt->host->host_no, SCpnt->channel,
+			       SCpnt->device->id, SCpnt->device->lun);
+			status = CMD_FINISHED; /* returns I/O error */
+			break;
+		}
 		status = MAYREDO;
 		exit = (DRIVER_HARD | SUGGEST_ABORT);
 		break;
@@ -1100,6 +1115,34 @@
 
 
 /*
+ * This function exports SCSI Bus, Device or Host reset capability
+ * and is for use with the SCSI generic driver.
+ */
+int
+scsi_old_reset(Scsi_Cmnd *SCpnt, unsigned int flag)
+{
+	unsigned int old_flags = SCSI_RESET_SYNCHRONOUS;
+
+	switch(flag) {
+	case SCSI_TRY_RESET_DEVICE:
+		/* no suggestion flags to add, device reset is default */
+		break;
+	case SCSI_TRY_RESET_BUS:
+		old_flags |= SCSI_RESET_SUGGEST_BUS_RESET;
+		break;
+	case SCSI_TRY_RESET_HOST:
+		old_flags |= SCSI_RESET_SUGGEST_HOST_RESET;
+		break;
+	default:
+		return FAILED;
+	}
+
+	if (scsi_reset(SCpnt, old_flags))
+		return FAILED;
+	return SUCCESS;
+}
+
+/*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
  * adjust the settings for this buffer only.  This must remain at the end
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- linux.orig/drivers/scsi/scsi_scan.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/scsi_scan.c	2002-07-20 01:08:29.000000000 +0000
@@ -23,21 +23,20 @@
 #include <linux/kmod.h>
 #endif
 
-/* The following devices are known not to tolerate a lun != 0 scan for
- * one reason or another.  Some will respond to all luns, others will
- * lock up.
+/* 
+ * Flags for irregular SCSI devices that need special treatment 
  */
-
-#define BLIST_NOLUN     	0x001
-#define BLIST_FORCELUN  	0x002
-#define BLIST_BORKEN    	0x004
-#define BLIST_KEY       	0x008
-#define BLIST_SINGLELUN 	0x010
-#define BLIST_NOTQ		0x020
-#define BLIST_SPARSELUN 	0x040
-#define BLIST_MAX5LUN		0x080
-#define BLIST_ISDISK    	0x100
-#define BLIST_ISROM     	0x200
+#define BLIST_NOLUN     	0x001	/* Don't scan for LUNs */
+#define BLIST_FORCELUN  	0x002	/* Known to have LUNs, force sanning */
+#define BLIST_BORKEN    	0x004	/* Flag for broken handshaking */
+#define BLIST_KEY       	0x008	/* Needs to be unlocked by special command */
+#define BLIST_SINGLELUN 	0x010	/* LUNs should better not be used in parallel */
+#define BLIST_NOTQ		0x020	/* Buggy Tagged Command Queuing */
+#define BLIST_SPARSELUN 	0x040	/* Non consecutive LUN numbering */
+#define BLIST_MAX5LUN		0x080	/* Avoid LUNS >= 5 */
+#define BLIST_ISDISK    	0x100	/* Treat as (removable) disk */
+#define BLIST_ISROM     	0x200	/* Treat as (removable) CD-ROM */
+#define BLIST_LARGELUN		0x400	/* LUNs larger than 7 despite reporting as SCSI 2 */
 
 static void print_inquiry(unsigned char *data);
 static int scan_scsis_single(unsigned int channel, unsigned int dev,
@@ -62,6 +61,10 @@
  */
 static struct dev_info device_list[] =
 {
+/* The following devices are known not to tolerate a lun != 0 scan for
+ * one reason or another.  Some will respond to all luns, others will
+ * lock up.
+ */
 	{"Aashima", "IMAGERY 2400SP", "1.03", BLIST_NOLUN},	/* Locks up if polled for lun != 0 */
 	{"CHINON", "CD-ROM CDS-431", "H42", BLIST_NOLUN},	/* Locks up if polled for lun != 0 */
 	{"CHINON", "CD-ROM CDS-535", "Q14", BLIST_NOLUN},	/* Locks up if polled for lun != 0 */
@@ -75,7 +78,6 @@
 	{"MAXTOR", "XT-4170S", "B5A", BLIST_NOLUN},		/* Locks-up sometimes when LUN>0 polled. */
 	{"MAXTOR", "XT-8760S", "B7B", BLIST_NOLUN},		/* guess what? */
 	{"MEDIAVIS", "RENO CD-ROMX2A", "2.03", BLIST_NOLUN},	/*Responds to all lun */
-	{"MICROP", "4110", "*", BLIST_NOTQ},			/* Buggy Tagged Queuing */
 	{"NEC", "CD-ROM DRIVE:841", "1.0", BLIST_NOLUN},	/* Locks-up when LUN>0 polled. */
 	{"PHILIPS", "PCA80SC", "V4-2", BLIST_NOLUN},		/* Responds to all lun */
 	{"RODIME", "RO3000S", "2.33", BLIST_NOLUN},		/* Locks up if polled for lun != 0 */
@@ -108,6 +110,10 @@
 	{"HP", "C1750A", "3226", BLIST_NOLUN},			/* scanjet iic */
 	{"HP", "C1790A", "", BLIST_NOLUN},			/* scanjet iip */
 	{"HP", "C2500A", "", BLIST_NOLUN},			/* scanjet iicx */
+	{"HP", "A6188A", "*", BLIST_SPARSELUN},			/* HP Va7100 Array */
+	{"HP", "A6189A", "*", BLIST_SPARSELUN},			/* HP Va7400 Array */
+	{"HP", "A6189B", "*", BLIST_SPARSELUN},			/* HP Va7410 Array */
+	{"HP", "OPEN-", "*", BLIST_SPARSELUN},			/* HP XP Arrays */
 	{"YAMAHA", "CDR100", "1.00", BLIST_NOLUN},		/* Locks up if polled for lun != 0 */
 	{"YAMAHA", "CDR102", "1.00", BLIST_NOLUN},		/* Locks up if polled for lun != 0  
 								 * extra reset */
@@ -115,6 +121,8 @@
 	{"YAMAHA", "CRW6416S", "1.0c", BLIST_NOLUN},		/* Locks up if polled for lun != 0 */
 	{"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN},	/* Locks up if polled for lun != 0 */
 	{"RELISYS", "Scorpio", "*", BLIST_NOLUN},		/* responds to all LUN */
+	{"RELISYS", "VM3530+", "*", BLIST_NOLUN},		/* responds to all LUN */
+	{"ACROSS", "", "*", BLIST_NOLUN},			/* responds to all LUN */
 	{"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN},	/* responds to all LUN */
 
 /*
@@ -126,6 +134,7 @@
 	{"INSITE", "Floptical   F*8I", "*", BLIST_KEY},
 	{"INSITE", "I325VM", "*", BLIST_KEY},
 	{"LASOUND","CDX7405","3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
+	{"MICROP", "4110", "*", BLIST_NOTQ},			/* Buggy Tagged Queuing */
 	{"NRC", "MBR-7", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"NRC", "MBR-7.4", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"REGAL", "CDC-4X", "*", BLIST_MAX5LUN | BLIST_SINGLELUN},
@@ -146,15 +155,16 @@
  	{"TOSHIBA","CDROM","*", BLIST_ISROM},
  	{"TOSHIBA","CD-ROM","*", BLIST_ISROM},
 	{"MegaRAID", "LD", "*", BLIST_FORCELUN},
-	{"DGC",  "RAID",      "*", BLIST_SPARSELUN}, // Dell PV 650F (tgt @ LUN 0)
-	{"DGC",  "DISK",      "*", BLIST_SPARSELUN}, // Dell PV 650F (no tgt @ LUN 0) 
-	{"DELL", "PV660F",   "*", BLIST_SPARSELUN},
-	{"DELL", "PV660F   PSEUDO",   "*", BLIST_SPARSELUN},
-	{"DELL", "PSEUDO DEVICE .",   "*", BLIST_SPARSELUN}, // Dell PV 530F
-	{"DELL", "PV530F",    "*", BLIST_SPARSELUN}, // Dell PV 530F
-	{"EMC", "SYMMETRIX", "*", BLIST_SPARSELUN},
-	{"CMD", "CRA-7280", "*", BLIST_SPARSELUN},   // CMD RAID Controller
-	{"CNSI", "G7324", "*", BLIST_SPARSELUN},     // Chaparral G7324 RAID
+	{"DGC",  "RAID",      "*", BLIST_SPARSELUN | BLIST_LARGELUN}, // Dell PV 650F (tgt @ LUN 0)
+	{"DGC",  "DISK",      "*", BLIST_SPARSELUN | BLIST_LARGELUN}, // Dell PV 650F (no tgt @ LUN 0) 
+	{"DELL", "PV660F",   "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"DELL", "PV660F   PSEUDO",   "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"DELL", "PSEUDO DEVICE .",   "*", BLIST_SPARSELUN | BLIST_LARGELUN}, // Dell PV 530F
+	{"DELL", "PV530F",    "*", BLIST_SPARSELUN | BLIST_LARGELUN}, // Dell PV 530F
+	{"EMC", "SYMMETRIX", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN},
+	{"HP", "A6189A", "*", BLIST_SPARSELUN |  BLIST_LARGELUN}, // HP VA7400, by Alar Aun
+	{"CMD", "CRA-7280", "*", BLIST_SPARSELUN | BLIST_LARGELUN},   // CMD RAID Controller
+	{"CNSI", "G7324", "*", BLIST_SPARSELUN | BLIST_LARGELUN},     // Chaparral G7324 RAID
 	{"CNSi", "G8324", "*", BLIST_SPARSELUN},     // Chaparral G8324 RAID
 	{"Zzyzx", "RocketStor 500S", "*", BLIST_SPARSELUN},
 	{"Zzyzx", "RocketStor 2000", "*", BLIST_SPARSELUN},
@@ -164,6 +174,13 @@
 	{"ADAPTEC", "AACRAID", "*", BLIST_FORCELUN},
 	{"ADAPTEC", "Adaptec 5400S", "*", BLIST_FORCELUN},
 	{"COMPAQ", "MSA1000", "*", BLIST_FORCELUN},
+	{"HP", "C1557A", "*", BLIST_FORCELUN},
+	{"IBM", "AuSaV1S2", "*", BLIST_FORCELUN},
+	{"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"DDN", "SAN DataDirector", "*", BLIST_SPARSELUN},
+	{"HITACHI", "DF400", "*", BLIST_SPARSELUN},
+	{"HITACHI", "DF500", "*", BLIST_SPARSELUN},
+	{"HITACHI", "DF600", "*", BLIST_SPARSELUN},
 
 	/*
 	 * Must be at end of list...
@@ -434,8 +451,13 @@
 								       scsi_result)
 						    && !sparse_lun)
 							break;	/* break means don't probe further for luns!=0 */
-						if (SDpnt && (0 == lun))
-							lun0_sl = SDpnt->scsi_level;
+						if (SDpnt && (0 == lun)) {
+							int bflags = get_device_flags (scsi_result);
+							if (bflags & BLIST_LARGELUN)
+								lun0_sl = SCSI_3; /* treat as SCSI 3 */
+							else
+								lun0_sl = SDpnt->scsi_level;
+						}
 					}	/* for lun ends */
 				}	/* if this_id != id ends */
 			}	/* for dev ends */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c
--- linux.orig/drivers/scsi/scsi_syms.c	2001-07-02 22:27:56.000000000 +0000
+++ linux/drivers/scsi/scsi_syms.c	2002-07-20 01:08:37.000000000 +0000
@@ -84,6 +84,11 @@
 EXPORT_SYMBOL(scsi_deregister_blocked_host);
 
 /*
+ * This symbol is for the highlevel drivers (e.g. sg) only.
+ */
+EXPORT_SYMBOL(scsi_reset_provider);
+
+/*
  * These are here only while I debug the rest of the scsi stuff.
  */
 EXPORT_SYMBOL(scsi_hostlist);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- linux.orig/drivers/scsi/sd.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/sd.c	2002-07-20 01:08:28.000000000 +0000
@@ -65,8 +65,13 @@
  *  static const char RCSid[] = "$Header:";
  */
 
+/* system major --> sd_gendisks index */
+#define SD_MAJOR_IDX(i)		(MAJOR(i) & SD_MAJOR_MASK)
+/* sd_gendisks index --> system major */
 #define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
 
+#define SD_PARTITION(dev)	((SD_MAJOR_IDX(dev) << 8) | (MINOR(dev) & 255))
+
 #define SCSI_DISKS_PER_MAJOR	16
 #define SD_MAJOR_NUMBER(i)	SD_MAJOR((i) >> 8)
 #define SD_MINOR_NUMBER(i)	((i) & 255)
@@ -84,9 +89,8 @@
 #define SD_TIMEOUT (30 * HZ)
 #define SD_MOD_TIMEOUT (75 * HZ)
 
-struct hd_struct *sd;
-
 static Scsi_Disk *rscsi_disks;
+static struct gendisk *sd_gendisks;
 static int *sd_sizes;
 static int *sd_blocksizes;
 static int *sd_hardsizes;	/* Hardware sector size */
@@ -195,7 +199,9 @@
 			if (put_user(diskinfo[0], &loc->heads) ||
 				put_user(diskinfo[1], &loc->sectors) ||
 				put_user(diskinfo[2], &loc->cylinders) ||
-				put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start))
+				put_user(sd_gendisks[SD_MAJOR_IDX(
+				    inode->i_rdev)].part[MINOR(
+				    inode->i_rdev)].start_sect, &loc->start))
 				return -EFAULT;
 			return 0;
 		}
@@ -226,7 +232,9 @@
 			if (put_user(diskinfo[0], &loc->heads) ||
 				put_user(diskinfo[1], &loc->sectors) ||
 				put_user(diskinfo[2], (unsigned int *) &loc->cylinders) ||
-				put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start))
+				put_user(sd_gendisks[SD_MAJOR_IDX(
+				    inode->i_rdev)].part[MINOR(
+				    inode->i_rdev)].start_sect, &loc->start))
 				return -EFAULT;
 			return 0;
 		}
@@ -279,37 +287,39 @@
  	target = DEVICE_NR(dev);
 
 	dpnt = &rscsi_disks[target];
-	if (!dpnt)
+	if (!dpnt->device)
 		return NULL;	/* No such device */
 	return &dpnt->device->request_queue;
 }
 
 static int sd_init_command(Scsi_Cmnd * SCpnt)
 {
-	int dev, devm, block, this_count;
+	int dev, block, this_count;
+	struct hd_struct *ppnt;
 	Scsi_Disk *dpnt;
 #if CONFIG_SCSI_LOGGING
 	char nbuff[6];
 #endif
 
-	devm = SD_PARTITION(SCpnt->request.rq_dev);
+	ppnt = &sd_gendisks[SD_MAJOR_IDX(SCpnt->request.rq_dev)].part[MINOR(SCpnt->request.rq_dev)];
 	dev = DEVICE_NR(SCpnt->request.rq_dev);
 
 	block = SCpnt->request.sector;
 	this_count = SCpnt->request_bufflen >> 9;
 
-	SCSI_LOG_HLQUEUE(1, printk("Doing sd request, dev = %d, block = %d\n", devm, block));
+	SCSI_LOG_HLQUEUE(1, printk("Doing sd request, dev = 0x%x, block = %d\n",
+	    SCpnt->request.rq_dev, block));
 
 	dpnt = &rscsi_disks[dev];
-	if (devm >= (sd_template.dev_max << 4) ||
-	    !dpnt ||
+	if (dev >= sd_template.dev_max ||
+	    !dpnt->device ||
 	    !dpnt->device->online ||
- 	    block + SCpnt->request.nr_sectors > sd[devm].nr_sects) {
+ 	    block + SCpnt->request.nr_sectors > ppnt->nr_sects) {
 		SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", SCpnt->request.nr_sectors));
 		SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
 		return 0;
 	}
-	block += sd[devm].start_sect;
+	block += ppnt->start_sect;
 	if (dpnt->device->changed) {
 		/*
 		 * quietly refuse to do anything to a changed disc until the changed
@@ -318,7 +328,7 @@
 		/* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
 		return 0;
 	}
-	SCSI_LOG_HLQUEUE(2, sd_devname(devm, nbuff));
+	SCSI_LOG_HLQUEUE(2, sd_devname(dev, nbuff));
 	SCSI_LOG_HLQUEUE(2, printk("%s : real dev = /dev/%d, block = %d\n",
 				   nbuff, dev, block));
 
@@ -576,8 +586,6 @@
 	fops:		&sd_fops,
 };
 
-static struct gendisk *sd_gendisks = &sd_gendisk;
-
 #define SD_GENDISK(i)    sd_gendisks[(i) / SCSI_DISKS_PER_MAJOR]
 
 /*
@@ -595,6 +603,7 @@
 	int this_count = SCpnt->bufflen >> 9;
 	int good_sectors = (result == 0 ? this_count : 0);
 	int block_sectors = 1;
+	long error_sector;
 
 	SCSI_LOG_HLCOMPLETE(1, sd_devname(DEVICE_NR(SCpnt->request.rq_dev), nbuff));
 
@@ -611,10 +620,11 @@
 	 */
 
 	/* An error occurred */
-	if (driver_byte(result) != 0) {
-		/* Sense data is valid */
-		if (SCpnt->sense_buffer[0] == 0xF0 && SCpnt->sense_buffer[2] == MEDIUM_ERROR) {
-			long error_sector = (SCpnt->sense_buffer[3] << 24) |
+	if (driver_byte(result) != 0 && 	/* An error occured */
+	    SCpnt->sense_buffer[0] == 0xF0) {	/* Sense data is valid */
+		switch (SCpnt->sense_buffer[2]) {
+		case MEDIUM_ERROR:
+			error_sector = (SCpnt->sense_buffer[3] << 24) |
 			(SCpnt->sense_buffer[4] << 16) |
 			(SCpnt->sense_buffer[5] << 8) |
 			SCpnt->sense_buffer[6];
@@ -642,18 +652,37 @@
 			default:
 				break;
 			}
-			error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect;
+			error_sector -= sd_gendisks[SD_MAJOR_IDX(
+				SCpnt->request.rq_dev)].part[MINOR(
+				SCpnt->request.rq_dev)].start_sect;
 			error_sector &= ~(block_sectors - 1);
 			good_sectors = error_sector - SCpnt->request.sector;
 			if (good_sectors < 0 || good_sectors >= this_count)
 				good_sectors = 0;
-		}
-		if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
+			break;
+
+		case RECOVERED_ERROR:
+			/*
+			 * An error occured, but it recovered.  Inform the
+			 * user, but make sure that it's not treated as a
+			 * hard error.
+			 */
+			print_sense("sd", SCpnt);
+			result = 0;
+			SCpnt->sense_buffer[0] = 0x0;
+			good_sectors = this_count;
+			break;
+
+		case ILLEGAL_REQUEST:
 			if (SCpnt->device->ten == 1) {
 				if (SCpnt->cmnd[0] == READ_10 ||
 				    SCpnt->cmnd[0] == WRITE_10)
 					SCpnt->device->ten = 0;
 			}
+			break;
+
+		default:
+			break;
 		}
 	}
 	/*
@@ -1127,23 +1156,12 @@
 		hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4);
 		max_sectors[SD_MAJOR(i)] = sd_max_sectors + i * (SCSI_DISKS_PER_MAJOR << 4);
 	}
-	/*
-	 * FIXME: should unregister blksize_size, hardsect_size and max_sectors when
-	 * the module is unloaded.
-	 */
-	sd = kmalloc((sd_template.dev_max << 4) *
-					  sizeof(struct hd_struct),
-					  GFP_ATOMIC);
-	if (!sd)
-		goto cleanup_sd;
-	memset(sd, 0, (sd_template.dev_max << 4) * sizeof(struct hd_struct));
-
-	if (N_USED_SD_MAJORS > 1)
-		sd_gendisks = kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC);
-		if (!sd_gendisks)
-			goto cleanup_sd_gendisks;
+
+	sd_gendisks = kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC);
+	if (!sd_gendisks)
+		goto cleanup_sd_gendisks;
 	for (i = 0; i < N_USED_SD_MAJORS; i++) {
-		sd_gendisks[i] = sd_gendisk;
+		sd_gendisks[i] = sd_gendisk;	/* memcpy */
 		sd_gendisks[i].de_arr = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr,
                                                  GFP_ATOMIC);
 		if (!sd_gendisks[i].de_arr)
@@ -1160,7 +1178,11 @@
 		sd_gendisks[i].major_name = "sd";
 		sd_gendisks[i].minor_shift = 4;
 		sd_gendisks[i].max_p = 1 << 4;
-		sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4);
+		sd_gendisks[i].part = kmalloc((SCSI_DISKS_PER_MAJOR << 4) * sizeof(struct hd_struct),
+						GFP_ATOMIC);
+		if (!sd_gendisks[i].part)
+			goto cleanup_gendisks_part;
+		memset(sd_gendisks[i].part, 0, (SCSI_DISKS_PER_MAJOR << 4) * sizeof(struct hd_struct));
 		sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4);
 		sd_gendisks[i].nr_real = 0;
 		sd_gendisks[i].real_devices =
@@ -1169,18 +1191,19 @@
 
 	return 0;
 
+cleanup_gendisks_part:
+	kfree(sd_gendisks[i].flags);
 cleanup_gendisks_flags:
 	kfree(sd_gendisks[i].de_arr);
 cleanup_gendisks_de_arr:
 	while (--i >= 0 ) {
 		kfree(sd_gendisks[i].de_arr);
 		kfree(sd_gendisks[i].flags);
+		kfree(sd_gendisks[i].part);
 	}
-	if (sd_gendisks != &sd_gendisk)
-		kfree(sd_gendisks);
+	kfree(sd_gendisks);
+	sd_gendisks = NULL;
 cleanup_sd_gendisks:
-	kfree(sd);
-cleanup_sd:
 	kfree(sd_max_sectors);
 cleanup_max_sectors:
 	kfree(sd_hardsizes);
@@ -1301,6 +1324,7 @@
  */
 int revalidate_scsidisk(kdev_t dev, int maxusage)
 {
+	struct gendisk *sdgd;
 	int target;
 	int max_p;
 	int start;
@@ -1314,14 +1338,15 @@
 	}
 	DEVICE_BUSY = 1;
 
-	max_p = sd_gendisks->max_p;
-	start = target << sd_gendisks->minor_shift;
+	sdgd = &SD_GENDISK(target);
+	max_p = sd_gendisk.max_p;
+	start = target << sd_gendisk.minor_shift;
 
 	for (i = max_p - 1; i >= 0; i--) {
 		int index = start + i;
 		invalidate_device(MKDEV_SD_PARTITION(index), 1);
-		sd_gendisks->part[index].start_sect = 0;
-		sd_gendisks->part[index].nr_sects = 0;
+		sdgd->part[SD_MINOR_NUMBER(index)].start_sect = 0;
+		sdgd->part[SD_MINOR_NUMBER(index)].nr_sects = 0;
 		/*
 		 * Reset the blocksize for everything so that we can read
 		 * the partition table.  Technically we will determine the
@@ -1353,6 +1378,7 @@
 static void sd_detach(Scsi_Device * SDp)
 {
 	Scsi_Disk *dpnt;
+	struct gendisk *sdgd;
 	int i, j;
 	int max_p;
 	int start;
@@ -1365,17 +1391,18 @@
 
 			/* If we are disconnecting a disk driver, sync and invalidate
 			 * everything */
+			sdgd = &SD_GENDISK(i);
 			max_p = sd_gendisk.max_p;
 			start = i << sd_gendisk.minor_shift;
 
 			for (j = max_p - 1; j >= 0; j--) {
 				int index = start + j;
 				invalidate_device(MKDEV_SD_PARTITION(index), 1);
-				sd_gendisks->part[index].start_sect = 0;
-				sd_gendisks->part[index].nr_sects = 0;
+				sdgd->part[SD_MINOR_NUMBER(index)].start_sect = 0;
+				sdgd->part[SD_MINOR_NUMBER(index)].nr_sects = 0;
 				sd_sizes[index] = 0;
 			}
-                        devfs_register_partitions (&SD_GENDISK (i),
+                        devfs_register_partitions (sdgd,
                                                    SD_MINOR_NUMBER (start), 1);
 			/* unregister_disk() */
 			dpnt->has_part_table = 0;
@@ -1411,16 +1438,22 @@
 		kfree(sd_sizes);
 		kfree(sd_blocksizes);
 		kfree(sd_hardsizes);
-		kfree((char *) sd);
+		for (i = 0; i < N_USED_SD_MAJORS; i++) {
+#if 0 /* XXX aren't we forgetting to deallocate something? */
+			kfree(sd_gendisks[i].de_arr);
+			kfree(sd_gendisks[i].flags);
+#endif
+			kfree(sd_gendisks[i].part);
+		}
 	}
 	for (i = 0; i < N_USED_SD_MAJORS; i++) {
 		del_gendisk(&sd_gendisks[i]);
-		blk_size[SD_MAJOR(i)] = NULL;
+		blk_size[SD_MAJOR(i)] = NULL;	/* XXX blksize_size actually? */
 		hardsect_size[SD_MAJOR(i)] = NULL;
 		read_ahead[SD_MAJOR(i)] = 0;
 	}
 	sd_template.dev_max = 0;
-	if (sd_gendisks != &sd_gendisk)
+	if (sd_gendisks != NULL)    /* kfree tests for 0, but leave explicit */
 		kfree(sd_gendisks);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sd.h linux/drivers/scsi/sd.h
--- linux.orig/drivers/scsi/sd.h	2001-11-22 19:49:15.000000000 +0000
+++ linux/drivers/scsi/sd.h	2002-07-20 01:08:38.000000000 +0000
@@ -23,8 +23,6 @@
 #include <linux/genhd.h>
 #endif
 
-extern struct hd_struct *sd;
-
 typedef struct scsi_disk {
 	unsigned capacity;	/* size in blocks */
 	Scsi_Device *device;
@@ -45,7 +43,6 @@
 #define N_SD_MAJORS	8
 
 #define SD_MAJOR_MASK	(N_SD_MAJORS - 1)
-#define SD_PARTITION(i)		(((MAJOR(i) & SD_MAJOR_MASK) << 8) | (MINOR(i) & 255))
 
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- linux.orig/drivers/scsi/sg.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/sg.c	2002-07-20 01:08:35.000000000 +0000
@@ -7,7 +7,7 @@
  * Original driver (sg.c):
  *        Copyright (C) 1992 Lawrence Foard
  * Version 2 and 3 extensions to driver:
- *        Copyright (C) 1998 - 2001 Douglas Gilbert
+ *        Copyright (C) 1998 - 2002 Douglas Gilbert
  *
  *  Modified  19-JAN-1998  Richard Gooch <rgooch@atnf.csiro.au>  Devfs support
  *
@@ -19,9 +19,9 @@
  */
 #include <linux/config.h>
 #ifdef CONFIG_PROC_FS
- static char sg_version_str[] = "Version: 3.1.22 (20011208)";
+ static char * sg_version_str = "Version: 3.1.24 (20020505)";
 #endif
- static int sg_version_num = 30122; /* 2 digits for each component */
+ static int sg_version_num = 30124; /* 2 digits for each component */
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
  *      - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -287,7 +287,7 @@
 
     if (flags & O_EXCL) {
         if (O_RDONLY == (flags & O_ACCMODE))  {
-            retval = -EACCES;   /* Can't lock it with read only access */
+            retval = -EPERM;   /* Can't lock it with read only access */
 	    goto error_out;
 	}
 	if (sdp->headfp && (flags & O_NONBLOCK))
@@ -580,7 +580,7 @@
     hp->iovec_count = 0;
     hp->mx_sb_len = 0;
     if (input_size > 0)
-	hp->dxfer_direction = ((old_hdr.reply_len - SZ_SG_HEADER) > 0) ?
+	hp->dxfer_direction = (old_hdr.reply_len > SZ_SG_HEADER) ?
 			      SG_DXFER_TO_FROM_DEV : SG_DXFER_TO_DEV;
     else
 	hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV :
@@ -649,7 +649,7 @@
     if (read_only &&
 	(! sg_allow_access(cmnd[0], sfp->parentdp->device->type))) {
 	sg_remove_request(sfp, srp);
-	return -EACCES;
+	return -EPERM;
     }
     k = sg_common_write(sfp, srp, cmnd, timeout, blocking);
     if (k < 0) return k;
@@ -981,7 +981,7 @@
 
 	    copy_from_user(&opcode, siocp->data, 1);
 	    if (! sg_allow_access(opcode, sdp->device->type))
-		return -EACCES;
+		return -EPERM;
 	}
         return scsi_ioctl_send_command(sdp->device, (void *)arg);
     case SG_SET_DEBUG:
@@ -998,7 +998,7 @@
         return scsi_ioctl(sdp->device, cmd_in, (void *)arg);
     default:
 	if (read_only)
-            return -EACCES; /* don't know so take safe approach */
+            return -EPERM; /* don't know so take safe approach */
         return scsi_ioctl(sdp->device, cmd_in, (void *)arg);
     }
 }
@@ -1884,8 +1884,11 @@
 	    res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
 	    if (res) return res;
 
-	    for (; (k < schp->k_use_sg) && p;
-		 ++k, ++sclp, ksglen = (int)sclp->length, p = sclp->address) {
+	    for (; k < schp->k_use_sg; ++k, ++sclp) {
+		ksglen = (int)sclp->length;
+		p = sclp->address;
+		if (NULL == p)
+		    break;
 		ok = (SG_USER_MEM != mem_src_arr[k]);
 		if (usglen <= 0)
 		    break;
@@ -2037,8 +2040,11 @@
 	    res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
 	    if (res) return res;
 
-	    for (; (k < schp->k_use_sg) && p;
-		 ++k, ++sclp, ksglen = (int)sclp->length, p = sclp->address) {
+	    for (; k < schp->k_use_sg; ++k, ++sclp) {
+		ksglen = (int)sclp->length;
+		p = sclp->address;
+		if (NULL == p)
+		    break;
 		ok = (SG_USER_MEM != mem_src_arr[k]);
 		if (usglen <= 0)
 		    break;
@@ -2452,7 +2458,11 @@
         return resp;
     if (SG_HEAP_KMAL == mem_src) {
         resp = kmalloc(rqSz, page_mask);
-        if (resp && retSzp) *retSzp = rqSz;
+	if (resp) {
+	    if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+	    	memset(resp, 0, rqSz);
+	    if (retSzp) *retSzp = rqSz;
+	}
         return resp;
     }
     if (SG_HEAP_POOL == mem_src) {
@@ -2469,6 +2479,8 @@
                 (scsi_dma_free_sectors > (SG_LOW_POOL_THRESHHOLD + num_sect))) {
                 resp = scsi_malloc(rqSz);
                 if (resp) {
+		    if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+			memset(resp, 0, rqSz);
                     if (retSzp) *retSzp = rqSz;
                     sg_pool_secs_avail -= num_sect;
                     return resp;
@@ -2494,7 +2506,11 @@
             resp = (char *)__get_free_pages(page_mask, order); /* try half */
             resSz = a_size;
         }
-        if (retSzp) *retSzp = resSz;
+	if (resp) {
+	    if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+                memset(resp, 0, resSz);
+	    if (retSzp) *retSzp = resSz;
+	}
     }
     else
         printk(KERN_ERR "sg_low_malloc: bad mem_src=%d, rqSz=%df\n", 
@@ -2632,9 +2648,9 @@
     }
 }
 
-static unsigned char allow_ops[] = {TEST_UNIT_READY, INQUIRY,
-READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
-MODE_SENSE, MODE_SENSE_10};
+static unsigned char allow_ops[] = {TEST_UNIT_READY, REQUEST_SENSE,
+INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
+MODE_SENSE, MODE_SENSE_10, LOG_SENSE};
 
 static int sg_allow_access(unsigned char opcode, char dev_type)
 {
@@ -3036,17 +3052,28 @@
 				 int size, int * eof, void * data)
 { SG_PROC_READ_FN(sg_proc_hoststrs_info); }
 
+#define SG_MAX_HOST_STR_LEN 256
+
 static int sg_proc_hoststrs_info(char * buffer, int * len, off_t * begin,
 				 off_t offset, int size)
 {
     struct Scsi_Host * shp;
     int k;
+    char buff[SG_MAX_HOST_STR_LEN];
+    char * cp;
 
     for (k = 0, shp = scsi_hostlist; shp; shp = shp->next, ++k) {
     	for ( ; k < shp->host_no; ++k)
 	    PRINT_PROC("<no active host>\n");
-	PRINT_PROC("%s\n", shp->hostt->info ? shp->hostt->info(shp) :
-		    (shp->hostt->name ? shp->hostt->name : "<no name>"));
+	strncpy(buff, shp->hostt->info ? shp->hostt->info(shp) :
+		    (shp->hostt->name ? shp->hostt->name : "<no name>"),
+		SG_MAX_HOST_STR_LEN);
+	buff[SG_MAX_HOST_STR_LEN - 1] = '\0';
+	for (cp = buff; *cp; ++cp) {
+	    if ('\n' == *cp)
+		*cp = ' '; /* suppress imbedded newlines */
+	}
+	PRINT_PROC("%s\n", buff);
     }
     return 1;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sgiwd93.c linux/drivers/scsi/sgiwd93.c
--- linux.orig/drivers/scsi/sgiwd93.c	2001-09-09 17:52:35.000000000 +0000
+++ linux/drivers/scsi/sgiwd93.c	2002-07-20 01:08:40.000000000 +0000
@@ -4,10 +4,13 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *		 1999 Andrew R. Baker (andrewb@uab.edu)
  *		      - Support for 2nd SCSI controller on Indigo2
+ *		 2001 Florian Lohoff (flo@rfc822.org)
+ *		      - Delete HPC scatter gather (Read corruption on 
+ *		        multiple disks)
+ *		      - Cleanup wback cache handling
  * 
  * (In all truth, Jed Schimmel wrote all this code.)
  *
- * $Id: sgiwd93.c,v 1.19 2000/02/04 07:40:47 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/types.h>
@@ -36,29 +39,34 @@
 
 struct hpc_chunk {
 	struct hpc_dma_desc desc;
-	unsigned long padding;
+	u32 _padding;	/* align to quadword boundary */
 };
 
 struct Scsi_Host *sgiwd93_host = NULL;
 struct Scsi_Host *sgiwd93_host1 = NULL;
 
 /* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */
-static inline void write_wd33c93_count(wd33c93_regs *regp, unsigned long value)
+static inline void write_wd33c93_count(const wd33c93_regs regs,
+                                      unsigned long value)
 {
-	regp->SASR = WD_TRANSFER_COUNT_MSB;
-	regp->SCMD = ((value >> 16) & 0xff);
-	regp->SCMD = ((value >>  8) & 0xff);
-	regp->SCMD = ((value >>  0) & 0xff);
+	*regs.SASR = WD_TRANSFER_COUNT_MSB;
+	mb();
+	*regs.SCMD = ((value >> 16) & 0xff);
+	*regs.SCMD = ((value >>  8) & 0xff);
+	*regs.SCMD = ((value >>  0) & 0xff);
+	mb();
 }
 
-static inline unsigned long read_wd33c93_count(wd33c93_regs *regp)
+static inline unsigned long read_wd33c93_count(const wd33c93_regs regs)
 {
 	unsigned long value;
 
-	regp->SASR = WD_TRANSFER_COUNT_MSB;
-	value =  ((regp->SCMD & 0xff) << 16);
-	value |= ((regp->SCMD & 0xff) <<  8);
-	value |= ((regp->SCMD & 0xff) <<  0);
+	*regs.SASR = WD_TRANSFER_COUNT_MSB;
+	mb();
+	value =  ((*regs.SCMD & 0xff) << 16);
+	value |= ((*regs.SCMD & 0xff) <<  8);
+	value |= ((*regs.SCMD & 0xff) <<  0);
+	mb();
 	return value;
 }
 
@@ -80,7 +88,6 @@
 	unsigned long physaddr;
 	unsigned long count;
 	
-	dma_cache_wback_inv((unsigned long)addr,len);
 	physaddr = PHYSADDR(addr);
 	while (len) {
 		/*
@@ -99,7 +106,6 @@
 static int dma_setup(Scsi_Cmnd *cmd, int datainp)
 {
 	struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
-	wd33c93_regs *regp = hdata->regp;
 	struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->host->base;
 	struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->dma_bounce_buffer;
 
@@ -110,42 +116,17 @@
 
 	hdata->dma_dir = datainp;
 
-	if(cmd->SCp.buffers_residual) {
-		struct scatterlist *slp = cmd->SCp.buffer;
-		int i, totlen = 0;
+	/*
+	 * wd33c93 shouldn't pass us bogus dma_setups, but
+	 * it does:-( The other wd33c93 drivers deal with
+	 * it the same way (which isn't that obvious).
+	 * IMHO a better fix would be, not to do these
+	 * dma setups in the first place
+	 */
+	if (cmd->SCp.ptr == NULL)
+		return 1;
 
-#ifdef DEBUG_DMA
-		printk("SCLIST<");
-#endif
-		for(i = 0; i <= cmd->SCp.buffers_residual; i++) {
-#ifdef DEBUG_DMA
-			printk("[%p,%d]", slp[i].address, slp[i].length);
-#endif
-			fill_hpc_entries (&hcp, slp[i].address, slp[i].length);
-			totlen += slp[i].length;
-		}
-#ifdef DEBUG_DMA
-		printk(">tlen<%d>", totlen);
-#endif
-		hdata->dma_bounce_len = totlen; /* a trick... */
-		write_wd33c93_count(regp, totlen);
-	} else {
-		/* Non-scattered dma. */
-#ifdef DEBUG_DMA
-		printk("ONEBUF<%p,%d>", cmd->SCp.ptr, cmd->SCp.this_residual);
-#endif
-		/*
-		 * wd33c93 shouldn't pass us bogus dma_setups, but
-		 * it does:-( The other wd33c93 drivers deal with
-		 * it the same way (which isn't that obvious).
-		 * IMHO a better fix would be, not to do these
-		 * dma setups in the first place
-		 */
-		if (cmd->SCp.ptr == NULL)
-			return 1;
-		fill_hpc_entries (&hcp, cmd->SCp.ptr,cmd->SCp.this_residual);
-		write_wd33c93_count(regp, cmd->SCp.this_residual);
-	}
+	fill_hpc_entries (&hcp, cmd->SCp.ptr,cmd->SCp.this_residual);
 
 	/* To make sure, if we trip an HPC bug, that we transfer
 	 * every single byte, we tag on an extra zero length dma
@@ -160,10 +141,14 @@
 
 	/* Start up the HPC. */
 	hregs->ndptr = PHYSADDR(hdata->dma_bounce_buffer);
-	if(datainp)
+	if(datainp) {
+		dma_cache_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual);
 		hregs->ctrl = (HPC3_SCTRL_ACTIVE);
-	else
+	} else {
+		dma_cache_wback_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual);
 		hregs->ctrl = (HPC3_SCTRL_ACTIVE | HPC3_SCTRL_DIR);
+	}
+
 	return 0;
 }
 
@@ -171,7 +156,6 @@
 		     int status)
 {
 	struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)instance->hostdata;
-	wd33c93_regs *regp = hdata->regp;
 	struct hpc3_scsiregs *hregs;
 
 	if (!SCpnt)
@@ -191,44 +175,6 @@
 	}
 	hregs->ctrl = 0;
 
-	/* See how far we got and update scatterlist state if necessary. */
-	if(SCpnt->SCp.buffers_residual) {
-		struct scatterlist *slp = SCpnt->SCp.buffer;
-		int totlen, wd93_residual, transferred, i;
-
-		/* Yep, we were doing the scatterlist thang. */
-		totlen = hdata->dma_bounce_len;
-		wd93_residual = read_wd33c93_count(regp);
-		transferred = totlen - wd93_residual;
-
-#ifdef DEBUG_DMA
-		printk("tlen<%d>resid<%d>transf<%d> ",
-		       totlen, wd93_residual, transferred);
-#endif
-
-		/* Avoid long winded partial-transfer search for common case. */
-		if(transferred != totlen) {
-			/* This is the nut case. */
-#ifdef DEBUG_DMA
-			printk("Jed was here...");
-#endif
-			for(i = 0; i <= SCpnt->SCp.buffers_residual; i++) {
-				if(slp[i].length >= transferred)
-					break;
-				transferred -= slp[i].length;
-			}
-		} else {
-			/* This is the common case. */
-#ifdef DEBUG_DMA
-			printk("did it all...");
-#endif
-			i = SCpnt->SCp.buffers_residual;
-		}
-		SCpnt->SCp.buffer = &slp[i];
-		SCpnt->SCp.buffers_residual = SCpnt->SCp.buffers_residual - i;
-		SCpnt->SCp.ptr = (char *) slp[i].address;
-		SCpnt->SCp.this_residual = slp[i].length;
-	}
 #ifdef DEBUG_DMA
 	printk("\n");
 #endif
@@ -258,6 +204,9 @@
 	};
 	hcp--;
 	hcp->desc.pnext = PHYSADDR(buf);
+
+	/* Force flush to memory */
+	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
 }
 
 int __init sgiwd93_detect(Scsi_Host_Template *SGIblows)
@@ -267,6 +216,7 @@
 	struct hpc3_scsiregs *hregs1 = &hpc3c0->scsi_chan1;
 	struct WD33C93_hostdata *hdata;
 	struct WD33C93_hostdata *hdata1;
+	wd33c93_regs regs;
 	uchar *buf;
 	
 	if(called)
@@ -287,10 +237,11 @@
 		return 0;
 	}
 	init_hpc_chain(buf);
-	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
+	
 	/* HPC_SCSI_REG0 | 0x03 | KSEG1 */
-	wd33c93_init(sgiwd93_host, (wd33c93_regs *) KSEG1ADDR (0x1fbc0003),
-		     dma_setup, dma_stop, WD33C93_FS_16_20);
+	regs.SASR = (unsigned char*) KSEG1ADDR (0x1fbc0003);
+	regs.SCMD = (unsigned char*) KSEG1ADDR (0x1fbc0007);
+	wd33c93_init(sgiwd93_host, regs, dma_setup, dma_stop, WD33C93_FS_16_20);
 
 	hdata = (struct WD33C93_hostdata *)sgiwd93_host->hostdata;
 	hdata->no_sync = 0;
@@ -321,15 +272,16 @@
 				return 1; /* We registered host0 so return success*/
 			}
 			init_hpc_chain(buf);
-			dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
+
 			/* HPC_SCSI_REG1 | 0x03 | KSEG1 */
-			wd33c93_init(sgiwd93_host1, (wd33c93_regs *) KSEG1ADDR (0x1fbc8003),
-				     dma_setup, dma_stop, WD33C93_FS_16_20);
+			regs.SASR = (unsigned char*) KSEG1ADDR(0x1fbc8003);
+			regs.SCMD = (unsigned char*) KSEG1ADDR(0x1fbc8007);
+			wd33c93_init(sgiwd93_host1, regs, dma_setup, dma_stop,
+			             WD33C93_FS_16_20);
 	
 			hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata;
 			hdata1->no_sync = 0;
 			hdata1->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf));
-			dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
 	
 			if (request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1)) {
 				printk(KERN_WARNING "sgiwd93: Could not allocate irq %d (for host1).\n", SGI_WD93_1_IRQ);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sim710.c linux/drivers/scsi/sim710.c
--- linux.orig/drivers/scsi/sim710.c	2001-09-30 19:26:07.000000000 +0000
+++ linux/drivers/scsi/sim710.c	2002-07-20 01:08:30.000000000 +0000
@@ -18,6 +18,9 @@
  *----------------------------------------------------------------------------
  *
  * MCA card detection code by Trent McNair.
+ * Fixes to not explicitly nul bss data from Xavier Bestel.
+ * Some multiboard fixes from Rolf Eike Beer.
+ * Auto probing of EISA config space from Trevor Hemsley.
  *
  * Various bits of code in this driver have been copied from 53c7,8xx,c,
  * which is coyright Drew Eckhardt.  The scripts for the SCSI chip are
@@ -41,6 +44,16 @@
  * and insmod parameters similar to
  *	sim710="addr:0x9000 irq:15"
  *
+ * Multiple controllers can also be set up by command line, provided the
+ * addr: parameter is specified first for each controller.  e.g.
+ *      sim710="addr:0x9000 irq:15 addr:0x8000 irq:14"
+ *
+ * To seperate the different options, ' ', '+', and ',' can be used, except
+ * that ',' can not be used in module parameters.  ' ' can be a pain, because
+ * it needs to be quoted, which causes problems with some installers.
+ * The command line above is completely equivalent to
+ *      sim710="addr:0x9000+irq:15+addr:0x8000+irq:14"
+ *
  * The complete list of options are:
  *
  * addr:0x9000		Specifies the base I/O port (or address) of the 53C710.
@@ -49,12 +62,18 @@
  * ignore:0x0a		Makes the driver ignore SCSI IDs 0 and 2.
  * nodisc:0x70		Prevents disconnects from IDs 6, 5 and 4.
  * noneg:0x10		Prevents SDTR negotiation on ID 4.
+ * disabled:1		Completely disables the driver. When present, overrides
+ *			all other options.
+ *
+ * The driver will auto-probe chip addresses and IRQs now, so typically no
+ * parameters are needed.  Auto-probing of addresses is disabled if any addr:
+ * parameters are specified.
  *
  * Current limitations:
  *
  * o  Async only
  * o  Severely lacking in error recovery
- * o  Auto detection of IRQs and chip addresses only on MCA architectures
+ * o  'debug:' should be per host really.
  *
  */
 
@@ -71,27 +90,20 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/mca.h>
+#include <linux/interrupt.h>
 #include <asm/dma.h>
 #include <asm/system.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17)
 #include <linux/spinlock.h>
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
-#include <asm/spinlock.h>
-#endif
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/byteorder.h>
 #include <linux/blk.h>
 
-#ifdef CONFIG_TP34V_SCSI
-
-#include <asm/tp34vhw.h>
-#define MEM_MAPPED
-
-#elif defined(CONFIG_MCA)
-
+/* All targets are I/O mapped at the moment */
 #define IO_MAPPED
 
+#if defined(CONFIG_MCA)
+
 /*
  * For each known microchannel card using the 53c710 we need a list
  * of possible IRQ and IO settings, as well as their corresponding
@@ -116,12 +128,6 @@
 
 #define MCA_004F_IRQS { 5, 9, 14 }
 
-#else
-
-/* Assume an Intel platform */
-
-#define IO_MAPPED
-
 #endif
 
 #include "scsi.h"
@@ -151,7 +157,7 @@
 
 #ifdef DEBUG
 #define DEB(m,x) if (sim710_debug & m) x
-int sim710_debug = 0;
+int sim710_debug;
 #else
 #define DEB(m,x)
 #endif
@@ -178,7 +184,7 @@
 #define STATE_BUSY		3
 #define STATE_DISABLED		4
 
-#define MAXBOARDS 2	/* Increase this and the sizes of the
+#define MAXBOARDS 4	/* Increase this and the sizes of the
 			   arrays below, if you need more.. */
 
 #ifdef MODULE
@@ -193,44 +199,15 @@
 
 #endif
 
-static int sim710_errors = 0;	/* Count of error interrupts */
-static int sim710_intrs = 0;	/* Count of all interrupts */
-static int ignore_ids = 0;	/* Accept all SCSI IDs */
-static int opt_nodisc = 0;	/* Allow disconnect on all IDs */
-static int opt_noneg = 0;	/* Allow SDTR negotiation on all IDs */
-
-#ifdef CONFIG_TP34V_SCSI
-
-/* Special hardwired case for Tadpole TP34V at the moment, otherwise
- * boot parameters 'sim710=addr:0x8000,irq:15' (for example) must be given.
- */
-
-static int no_of_boards = 2;
-
-static unsigned int bases[MAXBOARDS] = {
-	TP34V_SCSI0_BASE, TP34V_SCSI1_BASE
-};
-static unsigned int irq_vectors[MAXBOARDS] = {
-	TP34V_SCSI0_VECTOR, TP34V_SCSI1_VECTOR
-};
-static unsigned int irq_index[MAXBOARDS] = {
-	TP34V_SCSI0_IRQ_INDEX, TP34V_SCSI1_IRQ_INDEX
-};
-
-#else
-
-/* All other cases use boot/module params, or auto-detect */
-
-static int no_of_boards = 0;
-
-static unsigned int bases[MAXBOARDS] = {
-	0
-};
-static unsigned int irq_vectors[MAXBOARDS] = {
-	0
-};
-
-#endif
+static int sim710_errors;		/* Count of error interrupts */
+static int sim710_intrs;		/* Count of all interrupts */
+static int ignore_ids[MAXBOARDS];	/* Accept all SCSI IDs */
+static int opt_nodisc[MAXBOARDS];	/* Allow disconnect on all IDs */
+static int opt_noneg[MAXBOARDS];	/* Allow SDTR negotiation on all IDs */
+static int hostdata_order;		/* Encoded size of hostdata for free_pages() */
+static int no_of_boards;		/* Actual number of boards/chips */
+static unsigned int bases[MAXBOARDS];	/* Base addresses of chips */
+static unsigned int irq_vectors[MAXBOARDS]; /* IRQ vectors used by chips */
 
 /* The SCSI Script!!! */
 
@@ -249,7 +226,6 @@
 
 #define MAX_SG		128	/* Scatter/Gather elements */
 
-
 #define MAX_MSGOUT	8
 #define MAX_MSGIN	8
 #define MAX_CMND	12
@@ -263,6 +239,9 @@
     u8 negotiate;
     u8 reselected_identify;
     u8 msgin_buf[MAX_MSGIN];
+    u8 msg_reject;
+    u32 test1_src __attribute__ ((aligned (4)));
+    u32 test1_dst;
 
     struct sim710_target {
 	Scsi_Cmnd *cur_cmd;
@@ -294,82 +273,127 @@
 
 
 /*
- * Function: int param_setup(char *str)
+ * Function : static void ncr_dump (struct Scsi_Host *host)
+ *
+ * Purpose :  Dump (possibly) useful info
+ *
+ * Inputs : host - pointer to this host adapter's structure
  */
 
-#ifdef MODULE
-#define ARG_SEP ' '
-#else
-#define ARG_SEP ','
-#endif
+static void
+ncr_dump (struct Scsi_Host *host)
+{
+    unsigned long flags;
+    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
+       host->hostdata[0];
 
-static int
+    save_flags(flags);
+    cli();
+    printk("scsi%d: Chip register contents:\n", host->host_no);
+    printk(" (script at virt %p, bus %lx)\n",
+           hostdata->script, virt_to_bus(hostdata->script));
+    printk(" 00  sien:  %02x  sdid:  %02x  scntl1:%02x  scntl0:%02x\n"
+	   " 04  socl:  %02x  sodl:  %02x  sxfer: %02x  scid:  %02x\n"
+	   " 08  sbcl:  %02x  sbdl:  %02x  sidl:  %02x  sfbr:  %02x\n"
+	   " 0C  sstat2:%02x  sstat1:%02x  sstat0:%02x  dstat: %02x\n"
+	   " 10  dsa:   %08x\n"
+	   " 14  ctest3:%02x  ctest2:%02x  ctest1:%02x  ctest0:%02x\n"
+	   " 18  ctest7:%02x  ctest6:%02x  ctest5:%02x  ctest4:%02x\n"
+	   " 1C  temp:  %08x\n"
+	   " 20  lcrc:  %02x  ctest8:%02x  istat: %02x  dfifo: %02x\n"
+	   " 24  dbc:   %08x  dnad:  %08x  dsp:   %08x\n"
+	   " 30  dsps:  %08x  scratch:%08x\n"
+	   " 38  dcntl: %02x  dwt:   %02x  dien:  %02x  dmode: %02x\n"
+	   " 3C  adder: %08x\n",
+	  NCR_read8(SIEN_REG), NCR_read8(SDID_REG), NCR_read8(SCNTL1_REG),
+	  NCR_read8(SCNTL0_REG), NCR_read8(SOCL_REG), NCR_read8(SODL_REG),
+	  NCR_read8(SXFER_REG), NCR_read8(SCID_REG), NCR_read8(SBCL_REG),
+	  NCR_read8(SBDL_REG), NCR_read8(SIDL_REG), NCR_read8(SFBR_REG),
+	  NCR_read8(SSTAT2_REG), NCR_read8(SSTAT1_REG), NCR_read8(SSTAT0_REG),
+	  NCR_read8(DSTAT_REG), NCR_read32(DSA_REG), NCR_read8(CTEST3_REG),
+	  NCR_read8(CTEST2_REG), NCR_read8(CTEST1_REG), NCR_read8(CTEST0_REG),
+	  NCR_read8(CTEST7_REG), NCR_read8(CTEST6_REG), NCR_read8(CTEST5_REG),
+	  NCR_read8(CTEST4_REG), NCR_read8(TEMP_REG), NCR_read8(LCRC_REG),
+	  NCR_read8(CTEST8_REG), NCR_read8(ISTAT_REG), NCR_read8(DFIFO_REG),
+	  NCR_read32(DBC_REG), NCR_read32(DNAD_REG), NCR_read32(DSP_REG),
+	  NCR_read32(DSPS_REG), NCR_read32(SCRATCH_REG), NCR_read8(DCNTL_REG),
+	  NCR_read8(DWT_REG), NCR_read8(DIEN_REG), NCR_read8(DMODE_REG),
+	  NCR_read32(ADDER_REG));
+
+    restore_flags(flags);
+}
+
+
+/*
+ * Function: int param_setup(char *str)
+ */
+
+__init int
 param_setup(char *str)
 {
     char *cur = str;
-    char *pc, *pv;
+    char *p, *pc, *pv;
     int val;
-    int base;
     int c;
 
     no_of_boards = 0;
-    while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+    while (no_of_boards < MAXBOARDS && cur != NULL &&
+		(pc = strchr(cur, ':')) != NULL) {
 	char *pe;
 
 	val = 0;
 	pv = pc;
 	c = *++pv;
 
-	if (c == 'n')
-	    val = 0;
-	else if	(c == 'y')
-	    val = 1;
-	else {
-	    base = 0;
-	    val = (int) simple_strtoul(pv, &pe, base);
-	}
+	val = (int) simple_strtoul(pv, &pe, 0);
+
 	if (!strncmp(cur, "addr:", 5)) {
-	    bases[0] = val;
-	    no_of_boards = 1;
+	    bases[no_of_boards++] = val;
+	}
+#ifdef DEBUG
+	else if (!strncmp(cur, "debug:", 6)) {
+	    sim710_debug = val;
+	}
+#endif
+	else if (no_of_boards == 0) {
+	    printk("sim710: Invalid parameters, addr: must come first\n");
+	    no_of_boards = -1;
+	    return 1;
 	}
 	else if	(!strncmp(cur, "irq:", 4))
-	    irq_vectors[0] = val;
+	    irq_vectors[no_of_boards-1] = val;
 	else if	(!strncmp(cur, "ignore:", 7))
-	    ignore_ids = val;
+	    ignore_ids[no_of_boards-1] = val;
 	else if	(!strncmp(cur, "nodisc:", 7))
-	    opt_nodisc = val;
+	    opt_nodisc[no_of_boards-1] = val;
 	else if	(!strncmp(cur, "noneg:", 6))
-	    opt_noneg = val;
-	else if	(!strncmp(cur, "disabled:", 5)) {
+	    opt_noneg[no_of_boards-1] = val;
+	else if	(!strncmp(cur, "disabled:", 9)) {
 	    no_of_boards = -1;
 	    return 1;
 	}
-#ifdef DEBUG
-	else if (!strncmp(cur, "debug:", 6)) {
-	    sim710_debug = val;
+	else {
+	    printk("sim710: unexpected boot option '%.*s'\n", (int)(pc-cur+1), cur);
+	    no_of_boards = -1;
+	    return 1;
 	}
-#endif
-	else
-	    printk("sim710: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
 
-	if ((cur = strchr(cur, ARG_SEP)) != NULL)
-	    ++cur;
+	/* Allow ',', ' ', or '+' seperators.  Used to be ',' at boot and
+	 * ' ' for module load, some installers crap out on the space and
+	 * insmod doesn't like the comma.
+	 */
+       if ((p = strchr(cur, ',')) || (p = strchr(cur, ' ')) ||
+               (p = strchr(cur, '+')))
+           cur = p + 1;
+        else
+           break;
     }
     return 1;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)
 #ifndef MODULE
 __setup("sim710=", param_setup);
 #endif
-#else
-/* Old boot param syntax support */
-void
-sim710_setup(char *str, int *ints)
-{
-    param_setup(str);
-}
-#endif
 
 
 /*
@@ -398,22 +422,6 @@
 
 
 /*
- * Function: static void disable (struct Scsi_Host *host)
- */
-
-static void
-disable (struct Scsi_Host *host)
-{
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
-	host->hostdata[0];
-
-    hostdata->state = STATE_DISABLED;
-    printk (KERN_ALERT "scsi%d : disabled.  Unload and reload\n",
-		            host->host_no);
-}
-
-
-/*
  * Function : static int ncr_halt (struct Scsi_Host *host)
  *
  * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
@@ -431,6 +439,8 @@
     struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
 	host->hostdata[0];
     int stage;
+    int timeout;
+    int res = 0;
 
     save_flags(flags);
     cli();
@@ -438,8 +448,10 @@
        Stage 1 : set ABORT
        Stage 2 : eat all but abort interrupts
        Stage 3 : eat all interrupts
+       We loop for 50000 times with a delay of 10us which should give us
+       about half a second.
      */
-    for (stage = 0;;) {
+    for (stage = 0, timeout = 50000; timeout; timeout--) {
 	if (stage == 1) {
 	    DEB(DEB_HALT, printk("ncr_halt: writing ISTAT_ABRT\n"));
 	    NCR_write8(ISTAT_REG, ISTAT_ABRT);
@@ -460,9 +472,8 @@
 		    NCR_write8(ISTAT_REG, 0);
 		    ++stage;
 		} else {
-		    printk(KERN_ALERT "scsi%d : could not halt NCR chip\n",
-			host->host_no);
-		    disable (host);
+		    res = 1;
+		    break;
 	    	}
     	    }
 	}
@@ -472,10 +483,18 @@
 	    else if (stage == 3)
 		break;
 	}
+	udelay(10);
     }
-    hostdata->state = STATE_HALTED;
     restore_flags(flags);
-    return 0;
+
+    if (timeout == 0 || res) {
+	printk(KERN_ALERT "scsi%d: could not halt NCR chip\n", host->host_no);
+	return 1;
+    }
+    else {
+	hostdata->state = STATE_HALTED;
+	return 0;
+    }
 }
 
 /*
@@ -494,16 +513,9 @@
 sim710_soft_reset (struct Scsi_Host *host)
 {
     unsigned long flags;
-#ifdef CONFIG_TP34V_SCSI
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
-	host->hostdata[0];
-#endif
 
     save_flags(flags);
     cli();
-#ifdef CONFIG_TP34V_SCSI
-    tpvic.loc_icr[irq_index[hostdata->chip]].icr = 0x80;
-#endif
     /*
      * Do a soft reset of the chip so that everything is
      * reinitialized to the power-on state.
@@ -528,6 +540,7 @@
 
     mdelay(1000);				/* Let devices recover */
 
+    NCR_write32(SCRATCH_REG, 0);
     NCR_write8(DCNTL_REG, DCNTL_10_COM | DCNTL_700_CF_3);
     NCR_write8(CTEST7_REG, CTEST7_10_CDIS|CTEST7_STD);
     NCR_write8(DMODE_REG, DMODE_10_BL_8 | DMODE_10_FC2);
@@ -544,11 +557,6 @@
     NCR_write8(SIEN_REG_700,
 	    SIEN_PAR | SIEN_700_STO | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
 
-
-#ifdef CONFIG_TP34V_SCSI
-    tpvic.loc_icr[irq_index[hostdata->chip]].icr = 0x30 | TP34V_SCSI0n1_IPL;
-#endif
-
     restore_flags(flags);
 }
 
@@ -577,6 +585,12 @@
     	virt_to_bus((void *)&(hostdata->reselected_identify)));
     patch_abs_32 (hostdata->script, 0, msgin_buf, 
     	virt_to_bus((void *)&(hostdata->msgin_buf[0])));
+    patch_abs_32 (hostdata->script, 0, msg_reject, 
+	virt_to_bus((void *)&(hostdata->msg_reject)));
+    patch_abs_32 (hostdata->script, 0, test1_src, 
+	virt_to_bus((void *)&(hostdata->test1_src)));
+    patch_abs_32 (hostdata->script, 0, test1_dst, 
+	virt_to_bus((void *)&(hostdata->test1_dst)));
     hostdata->state = STATE_INITIALISED;
     hostdata->negotiate = 0xff;
 }
@@ -587,7 +601,7 @@
  * spurious request from the target.  Don't really expect target initiated
  * SDTRs, because we always negotiate on the first command.  Could still
  * get them though..
- * The chip is currently paused with ACK asserted o the last byte of the
+ * The chip is currently paused with ACK asserted on the last byte of the
  * SDTR.
  * resa is the resume address if the message is in response to our outgoing
  * SDTR.  Only possible on initial identify.
@@ -739,6 +753,12 @@
 		host->host_no);
 	    resume_offset = Ent_resume_cmd;
 	}
+	else if (sbcl == SBCL_PHASE_STATIN) {
+	    /* Some devices do this on parity error, at least */
+	    printk("scsi%d: Unexpected switch to STATUSIN on initial message out\n",
+		host->host_no);
+	    resume_offset = Ent_end_data_trans;
+	}
 	else {
 	    printk("scsi%d: Unexpected phase change to %s on initial msgout\n",
 		host->host_no, sbcl_to_phase(sbcl));
@@ -801,6 +821,14 @@
 	    resume_offset = Ent_resume_pmm;
 	}
     }
+    else if (sbcl == SBCL_PHASE_STATIN) {
+	/* Change to Status In at some random point; probably wants to report a
+	 * parity error or similar.
+	 */
+	printk("scsi%d: Unexpected phase change to STATUSIN at index 0x%x\n",
+		host->host_no, index);
+	resume_offset = Ent_end_data_trans;
+    }
     else {
 	printk("scsi%d: Unexpected phase change to %s at index 0x%x\n",
 		host->host_no, sbcl_to_phase(sbcl), index);
@@ -868,12 +896,6 @@
 	printk("scsi%d: int_data_bad_phase, phase %s (%x)\n",
 		host->host_no, sbcl_to_phase(sbcl), sbcl);
 	break;
-    case A_int_bad_extmsg1a:
-    case A_int_bad_extmsg1b:
-    case A_int_bad_extmsg2a:
-    case A_int_bad_extmsg2b:
-    case A_int_bad_extmsg3a:
-    case A_int_bad_extmsg3b:
     case A_int_bad_msg1:
     case A_int_bad_msg2:
     case A_int_bad_msg3:
@@ -917,21 +939,22 @@
 static void
 sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
 {
-    unsigned int flags;
     struct Scsi_Host * host = (struct Scsi_Host *)dev_id;
     struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
     Scsi_Cmnd * cmd;
     unsigned char istat, dstat;
     unsigned char sstat0;
-    u32 dsps, resume_offset = 0;
+    u32 scratch, dsps, resume_offset = 0;
 
-    save_flags(flags);
-    cli();
-    sim710_intrs++;
-    while ((istat = NCR_read8(ISTAT_REG)) & (ISTAT_SIP|ISTAT_DIP)) {
+    istat = NCR_read8(ISTAT_REG);
+    if (!(istat & (ISTAT_SIP|ISTAT_DIP)))
+	return;
+    else {
+	sim710_intrs++;
 	dsps = NCR_read32(DSPS_REG);
 	hostdata->state = STATE_HALTED;
 	sstat0 = dstat = 0;
+	scratch = NCR_read32(SCRATCH_REG);
 	if (istat & ISTAT_SIP) {
 	    sstat0 = NCR_read8(SSTAT0_REG);
 	}
@@ -944,7 +967,13 @@
 		"dstat %02x, dsp [%04x], scratch %02x\n",
 	    host->host_no, sim710_intrs, istat, sstat0, dstat,
 	    (u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
-	    NCR_read32(SCRATCH_REG)));
+	    scratch));
+	if (scratch & 0x100) {
+	    u8 *p = hostdata->msgin_buf;
+
+	    DEB(DEB_INTS, printk("  msgin_buf: %02x %02x %02x %02x\n",
+			p[0], p[1], p[2], p[3]));
+	}
 	if ((dstat & DSTAT_SIR) && dsps == A_int_reselected) {
 	    /* Reselected.  Identify the target from LCRC_REG, and
 	     * update current command.  If we were trying to select
@@ -1001,12 +1030,7 @@
 	    hostdata->target[cmd->target].cur_cmd = NULL;
 	    resume_offset = Ent_reselect;
 	}
-	else if (dstat & DSTAT_SIR)
-	    resume_offset = handle_script_int(host, cmd);
-	else if (sstat0 & SSTAT0_MA) {
-	    resume_offset = handle_phase_mismatch(host, cmd);
-	}
-	else if (sstat0 & (SSTAT0_MA|SSTAT0_SGE|SSTAT0_UDC|SSTAT0_RST|SSTAT0_PAR)) {
+	else if (sstat0 & (SSTAT0_SGE|SSTAT0_UDC|SSTAT0_RST|SSTAT0_PAR)) {
 	    printk("scsi%d: Serious error, sstat0 = %02x\n", host->host_no,
 			    sstat0);
 	    sim710_errors++;
@@ -1018,6 +1042,10 @@
 	    sim710_errors++;
 	    /* resume_offset is zero, which will cause a host reset */
 	}
+	else if (dstat & DSTAT_SIR)
+	    resume_offset = handle_script_int(host, cmd);
+	else if (sstat0 & SSTAT0_MA)
+	    resume_offset = handle_phase_mismatch(host, cmd);
 	else if (dstat & DSTAT_IID) {
 	    /* This can be due to a quick reselect while doing a WAIT
 	     * DISCONNECT.
@@ -1043,18 +1071,19 @@
 #ifdef DEBUG_LIMIT_INTS
 	if (sim710_intrs < DEBUG_LIMIT_INTS)
 #endif
-	NCR_write32(DSP_REG, virt_to_bus(hostdata->script+resume_offset/4));
+	{
+	    NCR_write32(SCRATCH_REG, 0);
+	    NCR_write32(DSP_REG, virt_to_bus(hostdata->script+resume_offset/4));
+	}
 	if (resume_offset == Ent_reselect)
 	    run_process_issue_queue(hostdata);
     }
     else {
 	printk("scsi%d: Failed to handle interrupt.  Failing commands "
 		"and resetting SCSI bus and chip\n", host->host_no);
-	mdelay(4000);		/* Give chance to read screen!! */
+	mdelay(1000);		/* Give chance to read screen!! */
 	full_reset(host);
     }
-
-    restore_flags(flags);
 }
 
 
@@ -1100,9 +1129,9 @@
     memcpy(targdata->dsa_cdb, cmd->cmnd, MAX_CMND);
 
     targdata->dsa_msgout[0] =
-		IDENTIFY((opt_nodisc & (1<<cmd->target)) ? 0 : 1 ,0);
+		IDENTIFY((opt_nodisc[hostdata->chip] & (1<<cmd->target)) ? 0 : 1 ,0);
     if (hostdata->negotiate & (1 << cmd->target)) {
-	if (opt_noneg & (1 << cmd->target)) {
+	if (opt_noneg[hostdata->chip] & (1 << cmd->target)) {
 	    hostdata->negotiate ^= (1 << cmd->target);
 	    targdata->dsa[DSA_MSGOUT] = 1;
 	}
@@ -1143,16 +1172,10 @@
 		cmd->request_bufflen;
 
 	if (datain) {
-#ifdef CONFIG_TP34V_SCSI
-	    cache_clear(virt_to_phys((void *)vbuf), cnt);
-#endif
 	    *dip++	= cnt;
 	    *dip++	= bbuf;
 	}
 	if (dataout) {
-#ifdef CONFIG_TP34V_SCSI
-	    cache_push(virt_to_phys((void *)vbuf), cnt);
-#endif
 	    *dop++	= cnt;
 	    *dop++	= bbuf;
 	}
@@ -1288,7 +1311,7 @@
     save_flags(flags);
     cli();
 
-    if (ignore_ids & (1 << cmd->target)) {
+    if (ignore_ids[hostdata->chip] & (1 << cmd->target)) {
 	printk("scsi%d: ignoring target %d\n", host->host_no, cmd->target);
 	cmd->result = (DID_BAD_TARGET << 16);
 	done(cmd);
@@ -1320,18 +1343,25 @@
 }
 
 
-int
+__init int
 sim710_detect(Scsi_Host_Template * tpnt)
 {
-    unsigned char irq_vector;
     unsigned char scsi_id;
     unsigned int base_addr;
     struct Scsi_Host * host = NULL;
     struct sim710_hostdata *hostdata;
+    unsigned long timeout;
+    unsigned long irq_mask;
+    int requested_irq;
+    int probed_irq;
+    u32 dsps;
     int chips = 0;
+    int limit;
     int indx;
     int revision;
-    int order, size;
+    int size;
+    volatile u8 tmp;
+    struct Scsi_Host *our_hosts[MAXBOARDS+1];
 
 #ifdef MODULE
     if (sim710)
@@ -1433,83 +1463,190 @@
     }
 #endif
 
+#ifdef CONFIG_EISA
+    /* Auto probe, if no boards specified in boot parameters */
+    if (no_of_boards == 0) {
+	int io_addr;
+	/* reverse probe, so my on-board controller at 0x9000 is always scsi0 */
+	for (io_addr = 0x9000; no_of_boards < MAXBOARDS && io_addr >= 0x1000; io_addr -= 0x1000) {
+	    if (request_region(io_addr, 0x40, "sim710") != NULL) {
+		int id0 = inw(io_addr + 0xc80);
+		int id1 = inw(io_addr + 0xc82);
+		/* The on-board controller on my Proliant 2000 is 0x1044,
+		 * my EISA card is 0x1144.
+		 */
+		if (id0 == 0x110e && (id1 == 0x1044 || id1 == 0x1144)) {
+		    bases[no_of_boards] = io_addr;
+#if 0
+		    /* This should detect the IRQ, but I havn't proved it for
+		     * myself.  Leave the old probe code active for now, as
+		     * no-one has reported problems with it.
+		     */
+		    switch (inb(io_addr + 0xc88)) {
+			case (0x00):
+			    irq_vectors[no_of_boards] = 11;
+			    break;
+			case (0x01):
+			    irq_vectors[no_of_boards] = 14;
+			    break;
+			case (0x02):
+			    irq_vectors[no_of_boards] = 15;
+			    break;
+			case (0x03):
+			    irq_vectors[no_of_boards] = 10;
+			    break;
+			case (0x04):
+			    irq_vectors[no_of_boards] = 9;
+			    break;
+			default:
+			    printk("sim710.c: irq nasty\n");
+		    }
+#endif
+		    no_of_boards++;
+		}
+		release_region(io_addr, 64);
+	    }
+	}
+    }
+#endif
     if (!no_of_boards) {
-       printk("sim710: No NCR53C710 adapter found.\n");
-       return 0;
+	printk("sim710: No NCR53C710 adapter found.\n");
+	return 0;
     }
 
     size = sizeof(struct sim710_hostdata);
-    order = 0;
-    while (size > (PAGE_SIZE << order))
-	order++;
-    size = PAGE_SIZE << order;
+    hostdata_order = 0;
+    while (size > (PAGE_SIZE << hostdata_order))
+	hostdata_order++;
+    size = PAGE_SIZE << hostdata_order;
 
     DEB(DEB_ANY, printk("sim710: hostdata %d bytes, size %d, order %d\n",
-	sizeof(struct sim710_hostdata), size, order));
+	sizeof(struct sim710_hostdata), size, hostdata_order));
 
     tpnt->proc_name = "sim710";
 
-    for(indx = 0; indx < no_of_boards; indx++) {
-        unsigned long page = __get_free_pages(GFP_ATOMIC, order);
+    memset(our_hosts, 0, sizeof(our_hosts));
+    for (indx = 0; indx < no_of_boards; indx++) {
+        unsigned long page = __get_free_pages(GFP_ATOMIC, hostdata_order);
         if(page == 0UL)
         {
-        	printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx);
-        	break;
+	    printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx);
+	    break;
         }
 	host = scsi_register(tpnt, 4);
-	if(host == NULL)
-		break;
+	if(host == NULL) {
+	    free_pages(host->hostdata[0], hostdata_order);
+	    break;
+	}
+	our_hosts[chips] = host;
 	host->hostdata[0] = page;
 	hostdata = (struct sim710_hostdata *)host->hostdata[0];
 	memset(hostdata, 0, size);
-#ifdef CONFIG_TP34V_SCSI
-	cache_push(virt_to_phys(hostdata), size);
-	cache_clear(virt_to_phys(hostdata), size);
-	kernel_set_cachemode((void *)hostdata,size,IOMAP_NOCACHE_SER);
-#endif
 	scsi_id = 7;
 	base_addr = bases[indx];
-	irq_vector = irq_vectors[indx];
-	printk("sim710: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n",
-	    		scsi_id, base_addr, irq_vector);
+	requested_irq = irq_vectors[indx];
+	printk("scsi%d: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n",
+			host->host_no, scsi_id, base_addr, requested_irq);
 	DEB(DEB_ANY, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n",
 			hostdata, sizeof(struct sim710_hostdata),
 			 hostdata->target[0].dsa));
 	hostdata->chip = indx;
-	host->irq = irq_vector;
+	host->irq = requested_irq;
 	host->this_id = scsi_id;
 	host->unique_id = base_addr;
 	host->base = base_addr;
+	hostdata->msg_reject = MESSAGE_REJECT;
 
-	ncr_halt(host);
-
+	if (ncr_halt(host)) {
+	    free_pages(host->hostdata[0], hostdata_order);
+	    scsi_unregister (host);
+	    printk("scsi%d: Failed to initialise 53c710 at address %x\n",
+			host->host_no, base_addr);
+	    continue;
+	}
+	DEB(DEB_ANY,ncr_dump(host));
 	revision = (NCR_read8(CTEST8_REG) & 0xF0) >> 4;
 	printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
-
 	sim710_soft_reset(host);
 
 	sim710_driver_init(host);
 
-#ifdef CONFIG_TP34V_SCSI
-	if (request_irq(irq_vector,do_sim710_intr_handle, 0, "sim710", host))
-#else
-	if (request_irq(irq_vector,do_sim710_intr_handle, SA_INTERRUPT, "sim710", host))
-#endif
-	{
-	    printk("scsi%d : IRQ%d not free, detaching\n",
-	    		host->host_no, host->irq);
-
-	    scsi_unregister (host);
+	request_region((u32)host->base, 64, "sim710");
+	/* Now run test1 */
+	hostdata->test1_src = 0x53c710aa;
+	hostdata->test1_dst = 0x76543210;
+	NCR_write32(DSPS_REG, 0x89abcdef);
+	irq_mask = probe_irq_on();
+	NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_test1/4));
+	timeout = 5;
+	while (hostdata->test1_dst != hostdata->test1_src && timeout--)
+	    mdelay(100);
+	tmp = NCR_read8(ISTAT_REG);
+	tmp = NCR_read8(SSTAT0_REG);
+	udelay(10);
+	tmp = NCR_read8(DSTAT_REG);
+	probed_irq = probe_irq_off(irq_mask);
+	if (requested_irq == 0) {
+	    if (probed_irq > 0) {
+		printk("scsi%d: Chip is using IRQ %d\n", host->host_no,
+			probed_irq);
+		requested_irq = host->irq = probed_irq;
+	    }
+	    else {
+		printk("scsi%d: Failed to probe for IRQ (returned %d)\n",
+			host->host_no, probed_irq);
+		ncr_halt(host);
+		free_pages(host->hostdata[0], hostdata_order);
+		scsi_unregister (host);
+		release_region((u32)host->base, 64);
+		continue;
+	    }
 	}
-	else {
-#ifdef IO_MAPPED
-	    request_region((u32)host->base, 64, "sim710");
-#endif
-	    chips++;
+	else if (probed_irq > 0 && probed_irq != requested_irq)
+	    printk("scsi%d: WARNING requested IRQ %d, but probed as %d\n",
+			host->host_no, requested_irq, probed_irq);
+	else if (probed_irq <= 0)
+	    printk("scsi%d: WARNING IRQ probe failed, (returned %d)\n",
+			host->host_no, probed_irq);
+  
+	dsps = NCR_read32(DSPS_REG);
+	if (hostdata->test1_dst != 0x53c710aa || dsps != A_int_test1) {
+	    if (hostdata->test1_dst != 0x53c710aa)
+		printk("scsi%d: test 1 FAILED: data: exp 0x53c710aa, got 0x%08x\n",
+			host->host_no, hostdata->test1_dst);
+	    if (dsps != A_int_test1)
+		printk("scsi%d: test 1 FAILED: dsps: exp 0x%08x, got 0x%08x\n",
+			host->host_no, A_int_test1, dsps);
+	    ncr_dump(host);
+	    ncr_halt(host);
+	    free_pages(host->hostdata[0], hostdata_order);
+	    scsi_unregister (host);
+	    release_region((u32)host->base, 64);
+	    continue;
 	}
+	printk("scsi%d: test 1 completed ok.\n", host->host_no);
+
 	NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4));
 	hostdata->state = STATE_IDLE;
+	chips++;
     }
+    /* OK, now run down our_hosts[] calling request_irq(... SA_SHIRQ ...).
+     * Couldn't call request_irq earlier, as probing would have failed.
+     */
+    for (indx = 0, limit = chips; indx < limit; indx++) {
+	host = our_hosts[indx];
+	if (request_irq(host->irq, do_sim710_intr_handle,
+                       SA_INTERRUPT | SA_SHIRQ, "sim710", host))
+	{
+	    printk("scsi%d : IRQ%d not free, detaching\n",
+			host->host_no, host->irq);
+	    ncr_halt(host);
+	    free_pages(host->hostdata[0], hostdata_order);
+	    scsi_unregister (host);
+	    chips--;
+	}
+    }
+
     return chips;
 }
 
@@ -1557,12 +1694,34 @@
 	    host->hostdata[0];
     int target;
     Scsi_Cmnd *cmd;
+    u32 istat, dstat = 0, sstat0 = 0, sstat1 = 0, dsp, dsps, scratch;
+    unsigned long flags;
 
-    ncr_halt(host);
-    printk("scsi%d: dsp = %08x (script[0x%04x]), scratch = %08x\n",
-	host->host_no, NCR_read32(DSP_REG),
-	((u32)bus_to_virt(NCR_read32(DSP_REG)) - (u32)hostdata->script)/4,
-	NCR_read32(SCRATCH_REG));
+    save_flags(flags);
+    cli();
+
+    istat = NCR_read8(ISTAT_REG);
+    if (istat & ISTAT_SIP) {
+	sstat0 = NCR_read8(SSTAT0_REG);
+	sstat1 = NCR_read8(SSTAT1_REG);
+	udelay(10);
+    }
+    if (istat & ISTAT_DIP)
+	dstat = NCR_read8(DSTAT_REG);
+
+    if (ncr_halt(host)) {
+	restore_flags(flags);
+	return FAILED;
+    }
+    restore_flags(flags);
+    dsp = NCR_read32(DSP_REG);
+    dsps = NCR_read32(DSPS_REG);
+    scratch = NCR_read32(SCRATCH_REG);
+    printk("scsi%d: istat = %02x, sstat0 = %02x, sstat1 = %02x, dstat = %02x\n",
+		host->host_no, istat, sstat0, sstat1, dstat);
+    printk("scsi%d: dsp = %08x (script[0x%04x]), dsps = %08x, scratch = %08x\n",
+		host->host_no, dsp,
+		((u32)bus_to_virt(dsp) - (u32)hostdata->script)/4, dsps, scratch);
 
     for (target = 0; target < 7; target++) {
 	if ((cmd = hostdata->target[target].cur_cmd)) {
@@ -1604,10 +1763,10 @@
 int
 sim710_release(struct Scsi_Host *host)
 {
+    ncr_halt(host);
+    free_pages(host->hostdata[0], hostdata_order);
     free_irq(host->irq, host);
-#ifdef IO_MAPPED
     release_region((u32)host->base, 64);
-#endif
     return 1;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sim710.h linux/drivers/scsi/sim710.h
--- linux.orig/drivers/scsi/sim710.h	2001-07-20 04:07:45.000000000 +0000
+++ linux/drivers/scsi/sim710.h	2002-07-20 01:08:37.000000000 +0000
@@ -23,8 +23,8 @@
 
 #include <scsi/scsicam.h>
 
-#define SIM710_SCSI { proc_name:		"sim710",	\
-		      name:			"Simple 53c710", 	\
+#define SIM710_SCSI { proc_name:		"sim710",		\
+		      name:			"53c710",	 	\
 		      detect:			sim710_detect,		\
 		      release:			sim710_release,		\
 		      queuecommand:		sim710_queuecommand,	\
@@ -414,7 +414,7 @@
 #define CTEST3_800_FM		0x02	/* Fetch mode pin */
 /* bit 0 is reserved on 800 series chips */
 
-#define CTEST4_REG_400		(0x18^bE)	/* Chip test 4 rw */
+#define CTEST4_REG_700		(0x18^bE)	/* Chip test 4 rw */
 #define CTEST4_REG_800		(0x21^bE)	/* Chip test 4 rw */
 /* 0x80 is reserved on 700 series chips */
 #define CTEST4_800_BDIS		0x80	/* Burst mode disable */
@@ -792,6 +792,20 @@
 
 #define ISTAT_REG	ISTAT_REG_700
 #define SCRATCH_REG	SCRATCHB_REG_10
+#define ADDER_REG	ADDER_REG_10
+#define SIEN_REG	SIEN_REG_700
+#define SDID_REG	SDID_REG_700
+#define CTEST0_REG	CTEST0_REG_700
+#define CTEST1_REG	CTEST1_REG_700
+#define CTEST2_REG	CTEST2_REG_700
+#define CTEST3_REG	CTEST3_REG_700
+#define CTEST4_REG	CTEST4_REG_700
+#define CTEST5_REG	CTEST5_REG_700
+#define CTEST6_REG	CTEST6_REG_700
+#define SODL_REG	SODL_REG_700
+#define SBDL_REG	SBDL_REG_700
+#define SIDL_REG	SIDL_REG_700
+#define LCRC_REG	LCRC_REG_10
 
 #ifdef MEM_MAPPED
 #define NCR_read8(address) 					\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sim710.scr linux/drivers/scsi/sim710.scr
--- linux.orig/drivers/scsi/sim710.scr	1999-10-07 17:17:09.000000000 +0000
+++ linux/drivers/scsi/sim710.scr	2002-07-20 01:08:22.000000000 +0000
@@ -15,15 +15,12 @@
 
 ABSOLUTE reselected_identify = 0
 ABSOLUTE msgin_buf = 0
+ABSOLUTE msg_reject = 0
+ABSOLUTE test1_src = 0
+ABSOLUTE test1_dst = 0
 
 /* Interrupt values passed back to driver */
 
-ABSOLUTE int_bad_extmsg1a	= 0xab930000
-ABSOLUTE int_bad_extmsg1b	= 0xab930001
-ABSOLUTE int_bad_extmsg2a	= 0xab930002
-ABSOLUTE int_bad_extmsg2b	= 0xab930003
-ABSOLUTE int_bad_extmsg3a	= 0xab930004
-ABSOLUTE int_bad_extmsg3b	= 0xab930005
 ABSOLUTE int_bad_msg1		= 0xab930006
 ABSOLUTE int_bad_msg2		= 0xab930007
 ABSOLUTE int_bad_msg3		= 0xab930008
@@ -47,9 +44,9 @@
 ABSOLUTE int_disc2		= 0xab93001a
 ABSOLUTE int_disc3		= 0xab93001b
 ABSOLUTE int_not_rej		= 0xab93001c
+ABSOLUTE int_test1		= 0xab93001d
 
-
-/* Bit field settings used to record status in SCRATCH */
+/* Bit field settings used to record status in SCRATCH0 */
 
 ABSOLUTE had_select	= 0x01
 ABSOLUTE had_msgout	= 0x02
@@ -60,6 +57,9 @@
 ABSOLUTE had_msgin	= 0x40
 ABSOLUTE had_extmsg	= 0x80
 
+/* Bit field settings used to record status in SCRATCH1 */
+
+ABSOLUTE did_reject	= 0x01
 
 /* These scripts are heavily based on the examples in the NCR 53C710
  * Programmer's Guide (Preliminary).
@@ -68,7 +68,6 @@
 ENTRY do_select
 do_select:
 	CLEAR TARGET
-	MOVE SCRATCH0 & 0 TO SCRATCH0
 	; Enable selection timer
 	MOVE CTEST7 & 0xef TO CTEST7
 	SELECT ATN FROM dsa_select, reselect
@@ -401,17 +400,23 @@
 	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
 	CLEAR ACK
 	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-	JUMP ext_msg1a, IF 0x03
-	INT int_bad_extmsg1a
-ext_msg1a:
+	JUMP reject_msg1, IF NOT 0x03	; Only handle SDTR
 	CLEAR ACK
 	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-	JUMP ext_msg1b, IF 0x01		; Must be SDTR
-	INT int_bad_extmsg1b
-ext_msg1b:
+	JUMP reject_msg1, IF NOT 0x01	; Only handle SDTR
 	CLEAR ACK
 	MOVE 2, msgin_buf + 3, WHEN MSG_IN
 	INT int_msg_sdtr1
+reject_msg1:
+	MOVE SCRATCH1 | did_reject TO SCRATCH1
+	SET ATN
+	CLEAR ACK
+	JUMP reject_msg1a, WHEN NOT MSG_IN
+	MOVE 1, msgin_buf + 7, WHEN MSG_IN
+	JUMP reject_msg1
+reject_msg1a:
+	MOVE 1, msg_reject, WHEN MSG_OUT
+	JUMP redo_msgin1
 disc1:
 	CLEAR ACK
 ENTRY wait_disc1
@@ -446,17 +451,23 @@
 	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
 	CLEAR ACK
 	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-	JUMP ext_msg2a, IF 0x03
-	INT int_bad_extmsg2a
-ext_msg2a:
+	JUMP reject_msg2, IF NOT 0x03	; Only handle SDTR
 	CLEAR ACK
 	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-	JUMP ext_msg2b, IF 0x01		; Must be SDTR
-	INT int_bad_extmsg2b
-ext_msg2b:
+	JUMP reject_msg2, IF NOT 0x01	; Only handle SDTR
 	CLEAR ACK
 	MOVE 2, msgin_buf + 3, WHEN MSG_IN
 	INT int_msg_sdtr2
+reject_msg2:
+	MOVE SCRATCH1 | did_reject TO SCRATCH1
+	SET ATN
+	CLEAR ACK
+	JUMP reject_msg2a, WHEN NOT MSG_IN
+	MOVE 1, msgin_buf + 7, WHEN MSG_IN
+	JUMP reject_msg2
+reject_msg2a:
+	MOVE 1, msg_reject, WHEN MSG_OUT
+	JUMP redo_msgin2
 disc2:
 	CLEAR ACK
 ENTRY wait_disc2
@@ -491,17 +502,23 @@
 	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
 	CLEAR ACK
 	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-	JUMP ext_msg3a, IF 0x03
-	INT int_bad_extmsg3a
-ext_msg3a:
+	JUMP reject_msg3, IF NOT 0x03	; Only handle SDTR
 	CLEAR ACK
 	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-	JUMP ext_msg3b, IF 0x01		; Must be SDTR
-	INT int_bad_extmsg3b
-ext_msg3b:
+	JUMP reject_msg3, IF NOT 0x01	; Only handle  SDTR
 	CLEAR ACK
 	MOVE 2, msgin_buf + 3, WHEN MSG_IN
 	INT int_msg_sdtr3
+reject_msg3:
+	MOVE SCRATCH1 | did_reject TO SCRATCH1
+	SET ATN
+	CLEAR ACK
+	JUMP reject_msg3a, WHEN NOT MSG_IN
+	MOVE 1, msgin_buf + 7, WHEN MSG_IN
+	JUMP reject_msg3
+reject_msg3a:
+	MOVE 1, msg_reject, WHEN MSG_OUT
+	JUMP redo_msgin3
 disc3:
 	CLEAR ACK
 ENTRY wait_disc3
@@ -552,3 +569,8 @@
 selected:
 	INT int_selected
 
+ENTRY test1
+test1:
+	MOVE MEMORY 4, test1_src, test1_dst
+	INT int_test1
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sim710_u.h linux/drivers/scsi/sim710_u.h
--- linux.orig/drivers/scsi/sim710_u.h	1999-10-07 17:17:09.000000000 +0000
+++ linux/drivers/scsi/sim710_u.h	2002-07-20 01:08:25.000000000 +0000
@@ -1,3 +1,4 @@
+#undef A_did_reject
 #undef A_dsa_cmnd
 #undef A_dsa_datain
 #undef A_dsa_dataout
@@ -14,12 +15,6 @@
 #undef A_had_msgout
 #undef A_had_select
 #undef A_had_status
-#undef A_int_bad_extmsg1a
-#undef A_int_bad_extmsg1b
-#undef A_int_bad_extmsg2a
-#undef A_int_bad_extmsg2b
-#undef A_int_bad_extmsg3a
-#undef A_int_bad_extmsg3b
 #undef A_int_bad_msg1
 #undef A_int_bad_msg2
 #undef A_int_bad_msg3
@@ -43,8 +38,12 @@
 #undef A_int_sel_not_cmd
 #undef A_int_selected
 #undef A_int_status_not_msgin
+#undef A_int_test1
+#undef A_msg_reject
 #undef A_msgin_buf
 #undef A_reselected_identify
+#undef A_test1_dst
+#undef A_test1_src
 #undef Ent_do_select
 #undef Ent_done_ident
 #undef Ent_end_data_trans
@@ -61,6 +60,7 @@
 #undef Ent_resume_msgin3b
 #undef Ent_resume_pmm
 #undef Ent_resume_rej_ident
+#undef Ent_test1
 #undef Ent_wait_disc1
 #undef Ent_wait_disc2
 #undef Ent_wait_disc3
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- linux.orig/drivers/scsi/sr.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/sr.c	2002-07-20 01:08:29.000000000 +0000
@@ -198,6 +198,7 @@
 	int good_sectors = (result == 0 ? this_count : 0);
 	int block_sectors = 0;
 	int device_nr = DEVICE_NR(SCpnt->request.rq_dev);
+	long error_sector;
 
 #ifdef DEBUG
 	printk("sr.c done: %x %p\n", result, SCpnt->request.bh->b_data);
@@ -210,33 +211,52 @@
 
 
 	if (driver_byte(result) != 0 &&		/* An error occurred */
-	    SCpnt->sense_buffer[0] == 0xF0 &&	/* Sense data is valid */
-	    (SCpnt->sense_buffer[2] == MEDIUM_ERROR ||
-	     SCpnt->sense_buffer[2] == VOLUME_OVERFLOW ||
-	     SCpnt->sense_buffer[2] == ILLEGAL_REQUEST)) {
-		long error_sector = (SCpnt->sense_buffer[3] << 24) |
-		(SCpnt->sense_buffer[4] << 16) |
-		(SCpnt->sense_buffer[5] << 8) |
-		SCpnt->sense_buffer[6];
-		if (SCpnt->request.bh != NULL)
-			block_sectors = SCpnt->request.bh->b_size >> 9;
-		if (block_sectors < 4)
-			block_sectors = 4;
-		if (scsi_CDs[device_nr].device->sector_size == 2048)
-			error_sector <<= 2;
-		error_sector &= ~(block_sectors - 1);
-		good_sectors = error_sector - SCpnt->request.sector;
-		if (good_sectors < 0 || good_sectors >= this_count)
-			good_sectors = 0;
-		/*
-		 * The SCSI specification allows for the value returned by READ
-		 * CAPACITY to be up to 75 2K sectors past the last readable
-		 * block.  Therefore, if we hit a medium error within the last
-		 * 75 2K sectors, we decrease the saved size value.
-		 */
-		if ((error_sector >> 1) < sr_sizes[device_nr] &&
-		    scsi_CDs[device_nr].capacity - error_sector < 4 * 75)
-			sr_sizes[device_nr] = error_sector >> 1;
+	    SCpnt->sense_buffer[0] == 0xF0) {	/* Sense data is valid */
+		switch (SCpnt->sense_buffer[2]) {
+		case MEDIUM_ERROR:
+		case VOLUME_OVERFLOW:
+		case ILLEGAL_REQUEST:
+			error_sector = (SCpnt->sense_buffer[3] << 24) |
+			(SCpnt->sense_buffer[4] << 16) |
+			(SCpnt->sense_buffer[5] << 8) |
+			SCpnt->sense_buffer[6];
+			if (SCpnt->request.bh != NULL)
+				block_sectors = SCpnt->request.bh->b_size >> 9;
+			if (block_sectors < 4)
+				block_sectors = 4;
+			if (scsi_CDs[device_nr].device->sector_size == 2048)
+				error_sector <<= 2;
+			error_sector &= ~(block_sectors - 1);
+			good_sectors = error_sector - SCpnt->request.sector;
+			if (good_sectors < 0 || good_sectors >= this_count)
+				good_sectors = 0;
+			/*
+			 * The SCSI specification allows for the value returned
+			 * by READ CAPACITY to be up to 75 2K sectors past the
+			 * last readable block.  Therefore, if we hit a medium
+			 * error within the last 75 2K sectors, we decrease the
+			 * saved size value.
+			 */
+			if ((error_sector >> 1) < sr_sizes[device_nr] &&
+			    scsi_CDs[device_nr].capacity - error_sector < 4 *75)
+				sr_sizes[device_nr] = error_sector >> 1;
+			break;
+
+		case RECOVERED_ERROR:
+			/*
+			 * An error occured, but it recovered.  Inform the
+			 * user, but make sure that it's not treated as a
+			 * hard error.
+			 */
+			print_sense("sr", SCpnt);
+			result = 0;
+			SCpnt->sense_buffer[0] = 0x0;
+			good_sectors = this_count;
+			break;
+
+		default:
+			break;
+		}
 	}
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- linux.orig/drivers/scsi/sr_ioctl.c	2001-10-15 20:27:42.000000000 +0000
+++ linux/drivers/scsi/sr_ioctl.c	2002-07-20 01:08:38.000000000 +0000
@@ -48,7 +48,7 @@
 	
 	if (ti->cdti_trk1 == ntracks) 
 		ti->cdti_trk1 = CDROM_LEADOUT;
-	else 
+	else if (ti->cdti_trk1 != CDROM_LEADOUT)
 		ti->cdti_trk1 ++;
 
 	trk0_te.cdte_track = ti->cdti_trk0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sun3_NCR5380.c linux/drivers/scsi/sun3_NCR5380.c
--- linux.orig/drivers/scsi/sun3_NCR5380.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/sun3_NCR5380.c	2002-07-20 01:08:25.000000000 +0000
@@ -647,10 +647,7 @@
 
 static volatile int main_running = 0;
 static struct tq_struct NCR5380_tqueue = {
-//    NULL,		/* next */
-    sync: 0,			/* sync */
-    routine: (void (*)(void*))NCR5380_main,  /* routine, must have (void *) arg... */
-    data: NULL		/* data */
+    routine:	(void (*)(void*))NCR5380_main	/* must have (void *) arg... */
 };
 
 static __inline__ void queue_main(void)
@@ -1219,9 +1216,9 @@
 
     if((sun3scsi_dma_finish(hostdata->connected->request.cmd))) {
 	    printk("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", HOSTNO);
-	    printk("please e-mail sammy@oh.verio.com with a description of how this\n");
+	    printk("please e-mail sammy@sammy.net with a description of how this\n");
 	    printk("error was produced.\n");
-	    machine_halt();
+	    BUG();
     }
 
     /* make sure we're not stuck in a data phase */
@@ -1232,9 +1229,9 @@
 	    printk("scsi%d: bus stuck in data phase -- probably a
  single byte overrun!\n", HOSTNO); 
 	    printk("not prepared for this error!\n");
-	    printk("please e-mail sammy@oh.verio.com with a description of how this\n");
+	    printk("please e-mail sammy@sammy.net with a description of how this\n");
 	    printk("error was produced.\n");
-	    machine_halt();
+	    BUG();
     }
 
 
@@ -1922,7 +1919,7 @@
     /* sanity check */
     if(!sun3_dma_setup_done) {
 	 printk("scsi%d: transfer_dma without setup!\n", HOSTNO);
-	 machine_halt();
+	 BUG();
     }
 
     hostdata->dma_len = c;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sun3_scsi.c linux/drivers/scsi/sun3_scsi.c
--- linux.orig/drivers/scsi/sun3_scsi.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/scsi/sun3_scsi.c	2002-07-20 01:08:25.000000000 +0000
@@ -80,8 +80,10 @@
 #include "NCR5380.h"
 #include "constants.h"
 
+/* #define OLDDMA */
+
 #define USE_WRAPPER
-#define RESET_BOOT
+/*#define RESET_BOOT */
 #define DRIVER_SETUP
 
 #define NDEBUG 0
@@ -94,7 +96,7 @@
 #undef DRIVER_SETUP
 #endif
 
-#undef SUPPORT_TAGS
+/* #define SUPPORT_TAGS */
 
 #define	ENABLE_IRQ()	enable_irq( IRQ_SUN3_SCSI ); 
 
@@ -126,7 +128,9 @@
 
 static volatile unsigned char *sun3_scsi_regp;
 static volatile struct sun3_dma_regs *dregs;
+#ifdef OLDDMA
 static unsigned char *dmabuf = NULL; /* dma memory buffer */
+#endif
 static struct sun3_udc_regs *udc_regs = NULL;
 static unsigned char *sun3_dma_orig_addr = NULL;
 static unsigned long sun3_dma_orig_count = 0;
@@ -260,7 +264,7 @@
 #endif
 #ifdef SUPPORT_TAGS
 	if (setup_use_tagged_queuing < 0)
-		setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING;
+		setup_use_tagged_queuing = USE_TAGGED_QUEUING;
 #endif
 
 	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
@@ -310,6 +314,11 @@
 	dregs->fifo_count = 0;
 
 	called = 1;
+
+#ifdef RESET_BOOT
+	sun3_scsi_reset_boot(instance);
+#endif
+
 	return 1;
 }
 
@@ -341,7 +350,7 @@
 	printk( "Sun3 SCSI: resetting the SCSI bus..." );
 
 	/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
-       	sun3_disable_irq( IRQ_SUN3_SCSI );
+//       	sun3_disable_irq( IRQ_SUN3_SCSI );
 
 	/* get in phase */
 	NCR5380_write( TARGET_COMMAND_REG,
@@ -361,7 +370,7 @@
 		barrier();
 
 	/* switch on SCSI IRQ again */
-       	sun3_enable_irq( IRQ_SUN3_SCSI );
+//       	sun3_enable_irq( IRQ_SUN3_SCSI );
 
 	printk( " done\n" );
 }
@@ -427,8 +436,12 @@
 #else
 	void *addr;
 
+	if(sun3_dma_orig_addr != NULL)
+		dvma_unmap(sun3_dma_orig_addr);
+
 //	addr = sun3_dvma_page((unsigned long)data, (unsigned long)dmabuf);
 	addr = (void *)dvma_map((unsigned long) data, count);
+		
 	sun3_dma_orig_addr = addr;
 	sun3_dma_orig_count = count;
 #endif
@@ -454,7 +467,6 @@
 	dregs->csr &= ~CSR_FIFO;
 	dregs->csr |= CSR_FIFO;
 	
-
 	if(dregs->fifo_count != count) { 
 		printk("scsi%d: fifo_mismatch %04x not %04x\n",
 		       default_instance->host_no, dregs->fifo_count,
@@ -533,10 +545,10 @@
 	int ret = 0;
 	
 	sun3_dma_active = 0;
-
+#if 1
 	// check to empty the fifo on a read
 	if(!write_flag) {
-		int tmo = 200000; /* 2 sec */
+		int tmo = 20000; /* .2 sec */
 		
 		while(1) {
 			if(dregs->csr & CSR_FIFO_EMPTY)
@@ -549,6 +561,7 @@
 		}
 	}
 		
+#endif
 
 	count = sun3scsi_dma_count(default_instance);
 #ifdef OLDDMA
@@ -588,6 +601,7 @@
 	}
 
 	dvma_unmap(sun3_dma_orig_addr);
+	sun3_dma_orig_addr = NULL;
 #endif
 	sun3_udc_write(UDC_RESET, UDC_CSR);
 	dregs->fifo_count = 0;
@@ -609,3 +623,4 @@
 
 #include "scsi_module.c"
 
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sun3x_esp.c linux/drivers/scsi/sun3x_esp.c
--- linux.orig/drivers/scsi/sun3x_esp.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/sun3x_esp.c	2002-07-20 01:08:26.000000000 +0000
@@ -376,3 +376,5 @@
 static Scsi_Host_Template driver_template = SCSI_SUN3X_ESP;
 
 #include "scsi_module.c"
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- linux.orig/drivers/scsi/sym53c8xx.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/sym53c8xx.c	2002-07-20 01:08:26.000000000 +0000
@@ -14111,7 +14111,7 @@
 	if (len)
 		return -EINVAL;
 	else {
-		long flags;
+		unsigned long flags;
 
 		NCR_LOCK_NCB(np, flags);
 		ncr_usercmd (np);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sym53c8xx_2/sym_hipd.c linux/drivers/scsi/sym53c8xx_2/sym_hipd.c
--- linux.orig/drivers/scsi/sym53c8xx_2/sym_hipd.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/sym53c8xx_2/sym_hipd.c	2002-07-20 01:08:21.000000000 +0000
@@ -5947,7 +5947,7 @@
 	 */
 attach_failed:
 		sym_hcb_free(np);
-	return ENXIO;
+	return -ENXIO;
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/sym53c8xx_defs.h linux/drivers/scsi/sym53c8xx_defs.h
--- linux.orig/drivers/scsi/sym53c8xx_defs.h	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/scsi/sym53c8xx_defs.h	2002-07-20 01:08:29.000000000 +0000
@@ -51,6 +51,10 @@
 **  NVRAM detection and reading.
 **    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
 **
+**  Added support for MIPS big endian systems.
+**  Carsten Langgaard, carstenl@mips.com
+**  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+**
 *******************************************************************************
 */
 
@@ -384,7 +388,16 @@
 #define	readl_l2b(a)	le32_to_cpu(readl(a))
 #define	writew_b2l(v,a)	writew(cpu_to_le16(v),a)
 #define	writel_b2l(v,a)	writel(cpu_to_le32(v),a)
-#else	/* Other bid-endian */
+#elif defined(__mips__)
+#define readw_l2b	readw
+#define readl_l2b	readl
+#define writew_b2l	writew
+#define writel_b2l	writel
+#define inw_l2b 	inw
+#define inl_l2b 	inl
+#define outw_b2l	outw
+#define outl_b2l	outl
+#else	/* Other big-endian */
 #define	readw_l2b	readw
 #define	readl_l2b	readl
 #define	writew_b2l	writew
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- linux.orig/drivers/scsi/u14-34f.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/u14-34f.c	2002-07-20 01:08:31.000000000 +0000
@@ -1,6 +1,9 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      01 Jan 2002 Rev. 6.50 for linux 2.4.16
+ *        + Use the dynamic DMA mapping API.
+ *
  *       1 May 2001 Rev. 6.05 for linux 2.4.4
  *        + Fix data transfer direction for opcode SEND_CUE_SHEET (0x5d)
  *
@@ -183,7 +186,7 @@
  *
  *          Multiple U14F and/or U34F host adapters are supported.
  *
- *  Copyright (C) 1994-2001 Dario Ballabio (ballabio_dario@emc.com)
+ *  Copyright (C) 1994-2002 Dario Ballabio (ballabio_dario@emc.com)
  *
  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
@@ -334,7 +337,6 @@
  *  the driver sets host->wish_block = TRUE for all ISA boards.
  */
 
-#include <linux/module.h>
 #include <linux/version.h>
 
 #ifndef LinuxVersionCode
@@ -343,6 +345,9 @@
 
 #define MAX_INT_PARAM 10
 
+#if defined(MODULE)
+#include <linux/module.h>
+
 MODULE_PARM(boot_options, "s");
 MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
 MODULE_PARM(linked_comm, "i");
@@ -352,6 +357,8 @@
 MODULE_PARM(ext_tran, "i");
 MODULE_AUTHOR("Dario Ballabio");
 
+#endif
+
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -370,17 +377,11 @@
 #include "u14-34f.h"
 #include <linux/stat.h>
 #include <linux/config.h>
+#include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 
-#define SPIN_FLAGS unsigned long spin_flags;
-#define SPIN_LOCK spin_lock_irq(&io_request_lock);
-#define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags);
-#define SPIN_UNLOCK spin_unlock_irq(&io_request_lock);
-#define SPIN_UNLOCK_RESTORE \
-                  spin_unlock_irqrestore(&io_request_lock, spin_flags);
-
 /* Values for the PRODUCT_ID ports for the 14/34F */
 #define PRODUCT_ID1  0x56
 #define PRODUCT_ID2  0x40        /* NOTE: Only upper nibble is used */
@@ -483,13 +484,13 @@
    unsigned char clink_id;              /* identifies command in chain */
    unsigned char use_sg;                /* (if sg is set) 8 bytes per list */
    unsigned char sense_len;
-   unsigned char scsi_cdbs_len;         /* 6, 10, or 12 */
-   unsigned char scsi_cdbs[12];         /* SCSI commands */
+   unsigned char cdb_len;               /* 6, 10, or 12 */
+   unsigned char cdb[12];               /* SCSI Command Descriptor Block */
    unsigned char adapter_status;        /* non-zero indicates HA error */
    unsigned char target_status;         /* non-zero indicates target error */
    unsigned int sense_addr PACKED;
    Scsi_Cmnd *SCpnt;
-   unsigned int index;                  /* cp index */
+   unsigned int cpp_index;              /* cp index */
    struct sg_list *sglist;
    };
 
@@ -507,6 +508,7 @@
    unsigned int retries;                /* Number of internal retries */
    unsigned long last_retried_pid;      /* Pid of last retried command */
    unsigned char subversion;            /* Bus type, either ISA or ESA */
+   struct pci_dev *pdev;                /* Always NULL */
    unsigned char heads;
    unsigned char sectors;
 
@@ -537,21 +539,11 @@
 #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
 #define BN(board) (HD(board)->board_name)
 
-#define SWAP_BYTE(x) ((unsigned long)( \
-        (((unsigned long)(x) & 0x000000ffU) << 24) | \
-        (((unsigned long)(x) & 0x0000ff00U) <<  8) | \
-        (((unsigned long)(x) & 0x00ff0000U) >>  8) | \
-        (((unsigned long)(x) & 0xff000000U) >> 24)))
-
-#if defined(__BIG_ENDIAN)
-#define H2DEV(x) SWAP_BYTE(x)
-#else
-#define H2DEV(x) (x)
-#endif
+/* Device is Little Endian */
+#define H2DEV(x) cpu_to_le32(x)
+#define DEV2H(x) le32_to_cpu(x)
 
-#define DEV2H(x) H2DEV(x)
 #define V2DEV(addr) ((addr) ? H2DEV(virt_to_bus((void *)addr)) : 0)
-#define DEV2V(addr) ((addr) ? DEV2H(bus_to_virt((unsigned long)addr)) : 0)
 
 static void do_interrupt_handler(int, void *, struct pt_regs *);
 static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);
@@ -653,8 +645,8 @@
    cpp->xdir = DTD_IN;
    cpp->data_address = V2DEV(HD(j)->board_id);
    cpp->data_len = H2DEV(sizeof(HD(j)->board_id));
-   cpp->scsi_cdbs_len = 6;
-   cpp->scsi_cdbs[0] = HA_CMD_INQUIRY;
+   cpp->cdb_len = 6;
+   cpp->cdb[0] = HA_CMD_INQUIRY;
 
    if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
       printk("%s: board_inquiry, adapter busy.\n", BN(j));
@@ -672,10 +664,10 @@
    /* Issue OGM interrupt */
    outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
 
-   SPIN_UNLOCK
+   spin_unlock_irq(&io_request_lock);
    time = jiffies;
    while ((jiffies - time) < HZ && limit++ < 20000) udelay(100L);
-   SPIN_LOCK
+   spin_lock_irq(&io_request_lock);
 
    if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) {
       HD(j)->cp_stat[0] = FREE;
@@ -834,14 +826,14 @@
       unsigned long flags;
       scsi_register_blocked_host(sh[j]);
       sh[j]->unchecked_isa_dma = TRUE;
-      
+
       flags=claim_dma_lock();
       disable_dma(dma_channel);
       clear_dma_ff(dma_channel);
       set_dma_mode(dma_channel, DMA_MODE_CASCADE);
       enable_dma(dma_channel);
       release_dma_lock(flags);
-      
+
       sh[j]->dma_channel = dma_channel;
       sprintf(BN(j), "U14F%d", j);
       bus_type = "ISA";
@@ -881,7 +873,7 @@
    if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;
 
    if (j == 0) {
-      printk("UltraStor 14F/34F: Copyright (C) 1994-2001 Dario Ballabio.\n");
+      printk("UltraStor 14F/34F: Copyright (C) 1994-2002 Dario Ballabio.\n");
       printk("%s config options -> of:%c, lc:%c, mq:%d, et:%c.\n",
              driver_name, YESNO(have_old_firmware), YESNO(linked_comm),
              max_queue_depth, YESNO(ext_tran));
@@ -951,8 +943,7 @@
    return 1;
 }
 
-int u14_34f_detect(Scsi_Host_Template *tpnt)
-{
+int u14_34f_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
 
    tpnt->proc_name = "u14-34f";
@@ -980,26 +971,94 @@
    return j;
 }
 
-static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
-   unsigned int k, data_len = 0;
+static inline void map_dma(unsigned int i, unsigned int j) {
+   unsigned int k, count, data_len = 0, pci_dir;
    struct scatterlist *sgpnt;
+   struct mscp *cpp;
+   Scsi_Cmnd *SCpnt;
+
+   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
+   pci_dir = scsi_to_pci_dma_dir(SCpnt->sc_data_direction);
+
+   if (SCpnt->sense_buffer)
+      cpp->sense_addr = H2DEV(pci_map_single(HD(j)->pdev, SCpnt->sense_buffer,
+                           sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE));
+
+   cpp->sense_len = sizeof SCpnt->sense_buffer;
+
+   if (!SCpnt->use_sg) {
+
+      if (!SCpnt->request_bufflen)
+         cpp->data_address = V2DEV(SCpnt->request_buffer);
+
+      else if (SCpnt->request_buffer)
+         cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev,
+                  SCpnt->request_buffer, SCpnt->request_bufflen, pci_dir));
+
+      cpp->data_len = H2DEV(SCpnt->request_bufflen);
+      return;
+      }
 
    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
+   count = pci_map_sg(HD(j)->pdev, sgpnt, SCpnt->use_sg, pci_dir);
 
-   for (k = 0; k < SCpnt->use_sg; k++) {
-      cpp->sglist[k].address = V2DEV(sgpnt[k].address);
-      cpp->sglist[k].num_bytes = H2DEV(sgpnt[k].length);
+   for (k = 0; k < count; k++) {
+      cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
+      cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
       data_len += sgpnt[k].length;
       }
 
+   cpp->sg = TRUE;
    cpp->use_sg = SCpnt->use_sg;
    cpp->data_address = V2DEV(cpp->sglist);
    cpp->data_len = H2DEV(data_len);
 }
 
-static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
-   unsigned int i, j, k;
+static void unmap_dma(unsigned int i, unsigned int j) {
+   unsigned int pci_dir;
    struct mscp *cpp;
+   Scsi_Cmnd *SCpnt;
+
+   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
+   pci_dir = scsi_to_pci_dma_dir(SCpnt->sc_data_direction);
+
+   if (DEV2H(cpp->sense_addr))
+      pci_unmap_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
+                       DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
+
+   if (SCpnt->use_sg) 
+      pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir);
+
+   else if (DEV2H(cpp->data_address) && DEV2H(cpp->data_len))
+      pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address), 
+                       DEV2H(cpp->data_len), pci_dir);
+
+}
+
+static void sync_dma(unsigned int i, unsigned int j) {
+   unsigned int pci_dir;
+   struct mscp *cpp;
+   Scsi_Cmnd *SCpnt;
+
+   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
+   pci_dir = scsi_to_pci_dma_dir(SCpnt->sc_data_direction);
+
+   if (DEV2H(cpp->sense_addr))
+      pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
+                          DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
+
+   if (SCpnt->use_sg) 
+      pci_dma_sync_sg(HD(j)->pdev, SCpnt->request_buffer, 
+                         SCpnt->use_sg, pci_dir);
+
+   else if (DEV2H(cpp->data_address) && DEV2H(cpp->data_len))
+      pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->data_address), 
+                          DEV2H(cpp->data_len), pci_dir);
+
+}
+
+static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
+   unsigned int k;
 
    static const unsigned char data_out_cmds[] = {
       0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e,
@@ -1010,9 +1069,51 @@
    static const unsigned char data_none_cmds[] = {
       0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e,
       0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47,
-      0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5
+      0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00
       };
 
+   struct mscp *cpp;
+   Scsi_Cmnd *SCpnt;
+
+   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
+
+   if (SCpnt->sc_data_direction == SCSI_DATA_READ) {
+      cpp->xdir = DTD_IN;
+      return;
+      }
+   else if (SCpnt->sc_data_direction == SCSI_DATA_WRITE) {
+      cpp->xdir = DTD_OUT;
+      return;
+      }
+   else if (SCpnt->sc_data_direction == SCSI_DATA_NONE) {
+      cpp->xdir = DTD_NONE;
+      return;
+      }
+
+   if (SCpnt->sc_data_direction != SCSI_DATA_UNKNOWN) 
+      panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", BN(j));
+
+   cpp->xdir = DTD_IN;
+
+   for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
+      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
+         cpp->xdir = DTD_OUT;
+         break;
+         }
+
+   if (cpp->xdir == DTD_IN)
+      for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
+         if (SCpnt->cmnd[0] == data_none_cmds[k]) {
+            cpp->xdir = DTD_NONE;
+            break;
+            }
+
+}
+
+static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
+   unsigned int i, j, k;
+   struct mscp *cpp;
+
    /* j is the board number */
    j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;
 
@@ -1044,47 +1145,26 @@
 
    memset(cpp, 0, sizeof(struct mscp) - sizeof(struct sg_list *));
    SCpnt->scsi_done = done;
-   cpp->index = i;
-   SCpnt->host_scribble = (unsigned char *) &cpp->index;
+   cpp->cpp_index = i;
+   SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
 
    if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
                         BN(j), i, SCpnt->channel, SCpnt->target,
                         SCpnt->lun, SCpnt->pid);
 
-   cpp->xdir = DTD_IN;
-
-   for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
-      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
-         cpp->xdir = DTD_OUT;
-         break;
-         }
-
-   if (cpp->xdir == DTD_IN)
-      for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
-         if (SCpnt->cmnd[0] == data_none_cmds[k]) {
-            cpp->xdir = DTD_NONE;
-            break;
-            }
-
    cpp->opcode = OP_SCSI;
    cpp->channel = SCpnt->channel;
    cpp->target = SCpnt->target;
    cpp->lun = SCpnt->lun;
    cpp->SCpnt = SCpnt;
-   cpp->sense_addr = V2DEV(SCpnt->sense_buffer);
-   cpp->sense_len = sizeof SCpnt->sense_buffer;
+   cpp->cdb_len = SCpnt->cmd_len;
+   memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
 
-   if (SCpnt->use_sg) {
-      cpp->sg = TRUE;
-      build_sg_list(cpp, SCpnt);
-      }
-   else {
-      cpp->data_address = V2DEV(SCpnt->request_buffer);
-      cpp->data_len = H2DEV(SCpnt->request_bufflen);
-      }
+   /* Use data transfer direction SCpnt->sc_data_direction */
+   scsi_to_dev_dir(i, j);
 
-   cpp->scsi_cdbs_len = SCpnt->cmd_len;
-   memcpy(cpp->scsi_cdbs, SCpnt->cmnd, cpp->scsi_cdbs_len);
+   /* Map DMA buffers and SG list */
+   map_dma(i, j);
 
    if (linked_comm && SCpnt->device->queue_depth > 2
                                      && TLDEV(SCpnt->device->type)) {
@@ -1094,6 +1174,7 @@
       }
 
    if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
+      unmap_dma(i, j);
       SCpnt->host_scribble = NULL;
       printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
              BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid);
@@ -1156,6 +1237,7 @@
          printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i);
 
       if (SCarg->eh_state == SCSI_STATE_TIMEOUT) {
+         unmap_dma(i, j);
          SCarg->host_scribble = NULL;
          HD(j)->cp_stat[i] = FREE;
          printk("%s, abort, mbox %d, eh_state timeout, pid %ld.\n",
@@ -1177,6 +1259,7 @@
       }
 
    if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
+      unmap_dma(i, j);
       SCarg->result = DID_ABORT << 16;
       SCarg->host_scribble = NULL;
       HD(j)->cp_stat[i] = FREE;
@@ -1274,16 +1357,19 @@
 #endif
 
    HD(j)->in_reset = TRUE;
-   SPIN_UNLOCK
+
+   spin_unlock_irq(&io_request_lock);
    time = jiffies;
    while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);
-   SPIN_LOCK
+   spin_lock_irq(&io_request_lock);
+
    printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
 
    for (i = 0; i < sh[j]->can_queue; i++) {
 
       if (HD(j)->cp_stat[i] == IN_RESET) {
          SCpnt = HD(j)->cp[i].SCpnt;
+         unmap_dma(i, j);
          SCpnt->result = DID_RESET << 16;
          SCpnt->host_scribble = NULL;
 
@@ -1296,6 +1382,7 @@
 
       else if (HD(j)->cp_stat[i] == ABORTING) {
          SCpnt = HD(j)->cp[i].SCpnt;
+         unmap_dma(i, j);
          SCpnt->result = DID_RESET << 16;
          SCpnt->host_scribble = NULL;
 
@@ -1536,23 +1623,25 @@
       return;
       }
 
-   spp = (struct mscp *)DEV2V(ret = inl(sh[j]->io_port + REG_ICM));
-   cpp = spp;
+   ret = inl(sh[j]->io_port + REG_ICM);
 
    /* Clear interrupt pending flag */
    outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
 
-#if defined(DEBUG_GENERATE_ABORTS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return;
-#endif
-
    /* Find the mailbox to be serviced on this board */
-   i = cpp - HD(j)->cp;
+   for (i = 0; i < sh[j]->can_queue; i++)
+      if (V2DEV(&(HD(j)->cp[i])) == ret) break;
 
-   if (cpp < HD(j)->cp || cpp >= HD(j)->cp + sh[j]->can_queue
-                                     || i >= sh[j]->can_queue)
+   if (i >= sh[j]->can_queue)
       panic("%s: ihdlr, invalid mscp bus address %p, cp0 %p.\n", BN(j),
-            (void *)ret, HD(j)->cp);
+            (void *)ret, (void *)V2DEV(HD(j)->cp));
+
+   cpp = &(HD(j)->cp[i]);
+   spp = cpp;
+
+#if defined(DEBUG_GENERATE_ABORTS)
+   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return;
+#endif
 
    if (HD(j)->cp_stat[i] == IGNORE) {
       HD(j)->cp_stat[i] = FREE;
@@ -1588,6 +1677,8 @@
       panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
             BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble);
 
+   sync_dma(i, j);
+
    if (linked_comm && SCpnt->device->queue_depth > 2
                                      && TLDEV(SCpnt->device->type))
       flush_dev(SCpnt->device, SCpnt->request.sector, j, TRUE);
@@ -1705,6 +1796,8 @@
              SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
              reg, HD(j)->iocount);
 
+   unmap_dma(i, j);
+
    /* Set the command state to inactive */
    SCpnt->host_scribble = NULL;
 
@@ -1718,14 +1811,14 @@
 
 static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) {
    unsigned int j;
-   SPIN_FLAGS
+   unsigned long spin_flags;
 
    /* Check if the interrupt must be processed by this handler */
    if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return;
 
-   SPIN_LOCK_SAVE
+   spin_lock_irqsave(&io_request_lock, spin_flags);
    ihdlr(irq, j);
-   SPIN_UNLOCK_RESTORE
+   spin_unlock_irqrestore(&io_request_lock, spin_flags);
 }
 
 int u14_34f_release(struct Scsi_Host *shpnt) {
@@ -1736,9 +1829,7 @@
    if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n",
                             driver_name);
 
-   if( sh[j]->unchecked_isa_dma ) {
-	   scsi_deregister_blocked_host(sh[j]);
-   }
+   if(sh[j]->unchecked_isa_dma) scsi_deregister_blocked_host(sh[j]);
 
    for (i = 0; i < sh[j]->can_queue; i++)
       if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
@@ -1752,7 +1843,6 @@
    return FALSE;
 }
 
-MODULE_LICENSE("BSD without advertisement clause");
 static Scsi_Host_Template driver_template = ULTRASTOR_14_34F;
 
 #include "scsi_module.c"
@@ -1760,3 +1850,4 @@
 #ifndef MODULE
 __setup("u14-34f=", option_setup);
 #endif /* end MODULE */
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h
--- linux.orig/drivers/scsi/u14-34f.h	2001-05-20 00:43:06.000000000 +0000
+++ linux/drivers/scsi/u14-34f.h	2002-07-20 01:08:39.000000000 +0000
@@ -13,7 +13,7 @@
 int u14_34f_reset(Scsi_Cmnd *);
 int u14_34f_biosparam(Disk *, kdev_t, int *);
 
-#define U14_34F_VERSION "6.05.00"
+#define U14_34F_VERSION "6.50.00"
 
 #define ULTRASTOR_14_34F {                                                   \
                 name:         "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- linux.orig/drivers/scsi/ultrastor.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/scsi/ultrastor.c	2002-07-20 01:08:21.000000000 +0000
@@ -371,14 +371,14 @@
 	return FALSE;
 
 #ifdef PORT_OVERRIDE
-    if(check_region(PORT_OVERRIDE, 0xc)) {
+    if(!request_region(PORT_OVERRIDE, 0xc, "ultrastor")) {
       printk("Ultrastor I/O space already in use\n");
       return FALSE;
     };
     config.port_address = PORT_OVERRIDE;
 #else
     for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
-      if(check_region(ultrastor_ports_14f[i], 0x0c)) continue;
+      if(!request_region(ultrastor_ports_14f[i], 0x0c, "ultrastor")) continue;
       config.port_address = ultrastor_ports_14f[i];
 #endif
 
@@ -396,8 +396,9 @@
 # endif
 #endif
 #ifdef PORT_OVERRIDE
-	    return FALSE;
+	    goto out_release_port;
 #else
+	    release_region(config.port_address, 0x0c);
 	    continue;
 #endif
 	}
@@ -412,8 +413,9 @@
 # endif
 #endif
 #ifdef PORT_OVERRIDE
-	    return FALSE;
+	    goto out_release_port;
 #else
+	    release_region(config.port_address, 0x0c);
 	    continue;
 #endif
 	}
@@ -425,6 +427,7 @@
 # if (ULTRASTOR_DEBUG & UD_DETECT)
 	printk("US14F: detect: no port address found!\n");
 # endif
+	/* all ports probed already released - we can just go straight out */
 	return FALSE;
     }
 #endif
@@ -441,7 +444,6 @@
     /* All above tests passed, must be the right thing.  Get some useful
        info. */
 
-    request_region(config.port_address, 0x0c,"ultrastor"); 
     /* Register the I/O space that we use */
 
     *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
@@ -465,7 +467,7 @@
 #if (ULTRASTOR_DEBUG & UD_DETECT)
 	printk("US14F: detect: not detected.\n");
 #endif
-	return FALSE;
+	goto out_release_port;
     }
 
     /* Final consistency check, verify previous info. */
@@ -474,7 +476,7 @@
 #if (ULTRASTOR_DEBUG & UD_DETECT)
 	    printk("US14F: detect: consistency check failed\n");
 #endif
-	    return FALSE;
+           goto out_release_port;
 	}
 
     /* If we were TRULY paranoid, we could issue a host adapter inquiry
@@ -503,19 +505,22 @@
     if (request_irq(config.interrupt, do_ultrastor_interrupt, 0, "Ultrastor", NULL)) {
 	printk("Unable to allocate IRQ%u for UltraStor controller.\n",
 	       config.interrupt);
-	return FALSE;
+	goto out_release_port;
     }
     if (config.dma_channel && request_dma(config.dma_channel,"Ultrastor")) {
 	printk("Unable to allocate DMA channel %u for UltraStor controller.\n",
 	       config.dma_channel);
 	free_irq(config.interrupt, NULL);
-	return FALSE;
+	goto out_release_port;
     }
     tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG;
     printk("UltraStor driver version" VERSION ".  Using %d SG lists.\n",
 	   ULTRASTOR_14F_MAX_SG);
 
     return TRUE;
+out_release_port:
+    release_region(config.port_address, 0x0c);
+    return FALSE;
 }
 
 static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/scsi/wd33c93.c linux/drivers/scsi/wd33c93.c
--- linux.orig/drivers/scsi/wd33c93.c	2001-10-25 20:53:51.000000000 +0000
+++ linux/drivers/scsi/wd33c93.c	2002-07-20 01:08:26.000000000 +0000
@@ -1407,12 +1407,32 @@
 
 
 
-static void reset_wd33c93(struct Scsi_Host *instance)
+void reset_wd33c93(struct Scsi_Host *instance)
 {
 struct WD33C93_hostdata *hostdata = (struct WD33C93_hostdata *)instance->hostdata;
 const wd33c93_regs regs = hostdata->regs;
 uchar sr;
 
+#ifdef CONFIG_SGI_IP22
+{
+int busycount = 0;
+extern void sgiwd93_reset(unsigned long);
+   /* wait 'til the chip gets some time for us */
+   while ((READ_AUX_STAT() & ASR_BSY) && busycount++ < 100)
+	udelay (10);
+   /*
+    * there are scsi devices out there, which manage to lock up
+    * the wd33c93 in a busy condition. In this state it won't
+    * accept the reset command. The only way to solve this is to
+    * give the chip a hardware reset (if possible). The code below
+    * does this for the SGI Indy, where this is possible
+    */
+   /* still busy ? */
+   if (READ_AUX_STAT() & ASR_BSY)
+	sgiwd93_reset(instance->base); /* yeah, give it the hard one */
+}
+#endif
+
    write_wd33c93(regs, WD_OWN_ID, OWNID_EAF | OWNID_RAF |
                  instance->this_id | hostdata->clock_freq);
    write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
@@ -2034,3 +2054,5 @@
 {
    MOD_DEC_USE_COUNT;
 }
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sgi/char/Makefile linux/drivers/sgi/char/Makefile
--- linux.orig/drivers/sgi/char/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux/drivers/sgi/char/Makefile	2002-07-20 01:08:22.000000000 +0000
@@ -9,7 +9,7 @@
 
 O_TARGET := sgichar.o
 
-export-objs	:= newport.o shmiq.o sgicons.o usema.o
+export-objs	:= newport.o rrm.o shmiq.o sgicons.o usema.o
 obj-y		:= newport.o shmiq.o sgicons.o usema.o streamable.o
 
 obj-$(CONFIG_SGI_SERIAL)	+= sgiserial.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sgi/char/ds1286.c linux/drivers/sgi/char/ds1286.c
--- linux.orig/drivers/sgi/char/ds1286.c	2001-08-27 15:56:31.000000000 +0000
+++ linux/drivers/sgi/char/ds1286.c	2002-07-20 01:08:32.000000000 +0000
@@ -61,8 +61,9 @@
 
 static unsigned int ds1286_poll(struct file *file, poll_table *wait);
 
-void get_rtc_time (struct rtc_time *rtc_tm);
-void get_rtc_alm_time (struct rtc_time *alm_tm);
+void ds1286_get_alm_time (struct rtc_time *alm_tm);
+void ds1286_get_time(struct rtc_time *rtc_tm);
+int ds1286_set_time(struct rtc_time *rtc_tm);
 
 void set_rtc_irq_bit(unsigned char bit);
 void clear_rtc_irq_bit(unsigned char bit);
@@ -173,7 +174,7 @@
 		 * tm_min, and tm_sec values are filled in.
 		 */
 
-		get_rtc_alm_time(&wtime);
+		ds1286_get_alm_time(&wtime);
 		break; 
 	}
 	case RTC_ALM_SET:	/* Store a time into the alarm */
@@ -215,15 +216,12 @@
 	}
 	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
 	{
-		get_rtc_time(&wtime);
+		ds1286_get_time(&wtime);
 		break;
 	}
 	case RTC_SET_TIME:	/* Set the RTC */
 	{
 		struct rtc_time rtc_tm;
-		unsigned char mon, day, hrs, min, sec, leap_yr;
-		unsigned char save_control;
-		unsigned int yrs, flags;
 
 		if (!capable(CAP_SYS_TIME))
 			return -EACCES;
@@ -231,57 +229,8 @@
 		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
 				   sizeof(struct rtc_time)))
 			return -EFAULT;
-
-		yrs = rtc_tm.tm_year + 1900;
-		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
-		day = rtc_tm.tm_mday;
-		hrs = rtc_tm.tm_hour;
-		min = rtc_tm.tm_min;
-		sec = rtc_tm.tm_sec;
-
-		if (yrs < 1970)
-			return -EINVAL;
-
-		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
-
-		if ((mon > 12) || (day == 0))
-			return -EINVAL;
-
-		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
-			return -EINVAL;
-
-		if ((hrs >= 24) || (min >= 60) || (sec >= 60))
-			return -EINVAL;
-
-		if ((yrs -= 1940) > 255)    /* They are unsigned */
-			return -EINVAL;
-
-		if (yrs >= 100)
-			yrs -= 100;
-
-		BIN_TO_BCD(sec);
-		BIN_TO_BCD(min);
-		BIN_TO_BCD(hrs);
-		BIN_TO_BCD(day);
-		BIN_TO_BCD(mon);
-		BIN_TO_BCD(yrs);
-
-		spin_lock_irqsave(&ds1286_lock, flags);
-		save_control = CMOS_READ(RTC_CMD);
-		CMOS_WRITE((save_control|RTC_TE), RTC_CMD);
-
-		CMOS_WRITE(yrs, RTC_YEAR);
-		CMOS_WRITE(mon, RTC_MONTH);
-		CMOS_WRITE(day, RTC_DATE);
-		CMOS_WRITE(hrs, RTC_HOURS);
-		CMOS_WRITE(min, RTC_MINUTES);
-		CMOS_WRITE(sec, RTC_SECONDS);
-		CMOS_WRITE(0, RTC_HUNDREDTH_SECOND);
-
-		CMOS_WRITE(save_control, RTC_CMD);
-		spin_unlock_irqrestore(&ds1286_lock, flags);
-
-		return 0;
+		
+		return ds1286_set_time(&rtc_tm);
 	}
 	default:
 		return -EINVAL;
@@ -369,7 +318,7 @@
 
 	p = buf;
 
-	get_rtc_time(&tm);
+	ds1286_get_time(&tm);
 	hundredth = CMOS_READ(RTC_HUNDREDTH_SECOND);
 	BCD_TO_BIN(hundredth);
 
@@ -384,7 +333,7 @@
 	 * match any value for that particular field. Values that are
 	 * greater than a valid time, but less than 0xc0 shouldn't appear.
 	 */
-	get_rtc_alm_time(&tm);
+	ds1286_get_alm_time(&tm);
 	p += sprintf(p, "alarm\t\t: %s ", days[tm.tm_wday]);
 	if (tm.tm_hour <= 24)
 		p += sprintf(p, "%02d:", tm.tm_hour);
@@ -441,12 +390,13 @@
 	return CMOS_READ(RTC_CMD) & RTC_TE;
 }
 
-void get_rtc_time(struct rtc_time *rtc_tm)
+
+void ds1286_get_time(struct rtc_time *rtc_tm)
 {
-	unsigned long uip_watchdog = jiffies;
 	unsigned char save_control;
 	unsigned int flags;
-
+	unsigned long uip_watchdog = jiffies;
+	
 	/*
 	 * read RTC once any update in progress is done. The update
 	 * can take just over 2ms. We wait 10 to 20ms. There is no need to
@@ -500,7 +450,66 @@
 	rtc_tm->tm_mon--;
 }
 
-void get_rtc_alm_time(struct rtc_time *alm_tm)
+int ds1286_set_time(struct rtc_time *rtc_tm)
+{
+	unsigned char mon, day, hrs, min, sec, leap_yr;
+	unsigned char save_control;
+	unsigned int yrs, flags;
+
+
+	yrs = rtc_tm->tm_year + 1900;
+	mon = rtc_tm->tm_mon + 1;   /* tm_mon starts at zero */
+	day = rtc_tm->tm_mday;
+	hrs = rtc_tm->tm_hour;
+	min = rtc_tm->tm_min;
+	sec = rtc_tm->tm_sec;
+
+	if (yrs < 1970)
+		return -EINVAL;
+
+	leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
+
+	if ((mon > 12) || (day == 0))
+		return -EINVAL;
+
+	if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
+		return -EINVAL;
+
+	if ((hrs >= 24) || (min >= 60) || (sec >= 60))
+		return -EINVAL;
+
+	if ((yrs -= 1940) > 255)    /* They are unsigned */
+		return -EINVAL;
+
+	if (yrs >= 100)
+		yrs -= 100;
+
+	BIN_TO_BCD(sec);
+	BIN_TO_BCD(min);
+	BIN_TO_BCD(hrs);
+	BIN_TO_BCD(day);
+	BIN_TO_BCD(mon);
+	BIN_TO_BCD(yrs);
+
+	spin_lock_irqsave(&ds1286_lock, flags);
+	save_control = CMOS_READ(RTC_CMD);
+	CMOS_WRITE((save_control|RTC_TE), RTC_CMD);
+
+	CMOS_WRITE(yrs, RTC_YEAR);
+	CMOS_WRITE(mon, RTC_MONTH);
+	CMOS_WRITE(day, RTC_DATE);
+	CMOS_WRITE(hrs, RTC_HOURS);
+	CMOS_WRITE(min, RTC_MINUTES);
+	CMOS_WRITE(sec, RTC_SECONDS);
+	CMOS_WRITE(0, RTC_HUNDREDTH_SECOND);
+
+	CMOS_WRITE(save_control, RTC_CMD);
+	spin_unlock_irqrestore(&ds1286_lock, flags);
+
+	return 0;
+}
+
+void ds1286_get_alm_time(struct rtc_time *alm_tm)
 {
 	unsigned char cmd;
 	unsigned int flags;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sgi/char/sgiserial.c linux/drivers/sgi/char/sgiserial.c
--- linux.orig/drivers/sgi/char/sgiserial.c	2001-08-27 15:56:31.000000000 +0000
+++ linux/drivers/sgi/char/sgiserial.c	2002-07-20 01:08:30.000000000 +0000
@@ -49,8 +49,6 @@
 #define NUM_SERIAL 1     /* One chip on board. */
 #define NUM_CHANNELS (NUM_SERIAL * 2)
 
-extern wait_queue_head_t keypress_wait;
-
 struct sgi_zslayout *zs_chips[NUM_SERIAL] = { 0, };
 struct sgi_zschannel *zs_channels[NUM_CHANNELS] = { 0, 0, };
 struct sgi_zschannel *zs_conschan;
@@ -428,8 +426,6 @@
 			show_buffers();
 			return;
 		}
-		/* It is a 'keyboard interrupt' ;-) */
-		wake_up(&keypress_wait);
 	}
 	/* Look for kgdb 'stop' character, consult the gdb documentation
 	 * for remote target debugging and arch/sparc/kernel/sparc-stub.c
@@ -1239,7 +1235,7 @@
 	tmp.close_delay = info->close_delay;
 	tmp.closing_wait = info->closing_wait;
 	tmp.custom_divisor = info->custom_divisor;
-	return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+	return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0;
 }
 
 static int set_serial_info(struct sgi_serial * info,
@@ -1875,7 +1871,11 @@
 	
 	memset(&serial_driver, 0, sizeof(struct tty_driver));
 	serial_driver.magic = TTY_DRIVER_MAGIC;
+#ifdef CONFIG_DEVFS_FS
+	serial_driver.name = "tts/%d";
+#else
 	serial_driver.name = "ttyS";
+#endif
 	serial_driver.major = TTY_MAJOR;
 	serial_driver.minor_start = 64;
 	serial_driver.num = NUM_CHANNELS;
@@ -1911,14 +1911,18 @@
 	 * major number and the subtype code.
 	 */
 	callout_driver = serial_driver;
+#ifdef CONFIG_DEVFS_FS
+	callout_driver.name = "cua/%d";
+#else
 	callout_driver.name = "cua";
+#endif
 	callout_driver.major = TTYAUX_MAJOR;
 	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
 	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register serial driver\n");
+		panic("Couldn't register serial driver");
 	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
+		panic("Couldn't register callout driver");
 	
 	save_flags(flags); cli();
 
@@ -2017,7 +2021,7 @@
 
 	if (request_irq(zilog_irq, rs_interrupt, (SA_INTERRUPT),
 			"Zilog8530", zs_chain))
-		panic("Unable to attach zs intr\n");
+		panic("Unable to attach zs intr");
 	restore_flags(flags);
 
 	return 0;
@@ -2117,12 +2121,6 @@
 	rs_fair_output();
 }
 
-static int zs_console_wait_key(struct console *con)
-{
-	sleep_on(&keypress_wait);
-	return 0;
-}
-
 static kdev_t zs_console_device(struct console *con)
 {
 	return MKDEV(TTY_MAJOR, 64 + con->index);
@@ -2274,7 +2272,6 @@
 	name:		"ttyS",
 	write:		zs_console_write,
 	device:		zs_console_device,
-	wait_key:	zs_console_wait_key,
 	setup:		zs_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/Config.in linux/drivers/sound/Config.in
--- linux.orig/drivers/sound/Config.in	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/sound/Config.in	2002-07-20 01:08:38.000000000 +0000
@@ -6,7 +6,7 @@
 
 # Prompt user for primary drivers.
 
-dep_tristate '  BT878 audio dma' CONFIG_SOUND_BT878 $CONFIG_SOUND
+dep_tristate '  BT878 audio dma' CONFIG_SOUND_BT878 $CONFIG_SOUND $CONFIG_PCI
 dep_tristate '  C-Media PCI (CMI8338/8738)' CONFIG_SOUND_CMPCI $CONFIG_SOUND $CONFIG_PCI
 if [ "$CONFIG_SOUND_CMPCI" = "y" -o "$CONFIG_SOUND_CMPCI" = "m" ]; then
     bool '    Enable legacy FM' CONFIG_SOUND_CMPCI_FM
@@ -32,26 +32,40 @@
 fi
 dep_tristate '  Creative SBLive! (EMU10K1)' CONFIG_SOUND_EMU10K1 $CONFIG_SOUND $CONFIG_PCI
 dep_mbool    '    Creative SBLive! MIDI' CONFIG_MIDI_EMU10K1 $CONFIG_SOUND_EMU10K1 $CONFIG_EXPERIMENTAL
-dep_tristate '  Crystal SoundFusion (CS4280/461x)' CONFIG_SOUND_FUSION $CONFIG_SOUND
-dep_tristate '  Crystal Sound CS4281' CONFIG_SOUND_CS4281 $CONFIG_SOUND
+dep_tristate '  Crystal SoundFusion (CS4280/461x)' CONFIG_SOUND_FUSION $CONFIG_SOUND $CONFIG_PCI
+dep_tristate '  Crystal Sound CS4281' CONFIG_SOUND_CS4281 $CONFIG_SOUND $CONFIG_PCI
+if [ "$CONFIG_SIBYTE_SB1250" = "y" -a "$CONFIG_REMOTE_DEBUG" != "y" ]; then
+    dep_tristate '  Crystal Sound CS4297a (for Swarm)' CONFIG_SOUND_BCM_CS4297A $CONFIG_SOUND
+fi
 dep_tristate '  Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND $CONFIG_PCI
 dep_tristate '  Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND $CONFIG_PCI
-dep_tristate '  ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND
-dep_tristate '  ESS Maestro, Maestro2, Maestro2E driver' CONFIG_SOUND_MAESTRO $CONFIG_SOUND
+dep_tristate '  ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND $CONFIG_PCI
+dep_tristate '  ESS Maestro, Maestro2, Maestro2E driver' CONFIG_SOUND_MAESTRO $CONFIG_SOUND $CONFIG_PCI
 dep_tristate '  ESS Maestro3/Allegro driver (EXPERIMENTAL)' CONFIG_SOUND_MAESTRO3 $CONFIG_SOUND $CONFIG_PCI $CONFIG_EXPERIMENTAL
-dep_tristate '  Intel ICH (i8xx) audio support' CONFIG_SOUND_ICH $CONFIG_PCI
+dep_tristate '  Intel ICH (i8xx), SiS 7012, NVidia nForce Audio or AMD 768' CONFIG_SOUND_ICH $CONFIG_PCI
 if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then
     dep_tristate '  IT8172G Sound' CONFIG_SOUND_IT8172 $CONFIG_SOUND
 fi
 dep_tristate '  RME Hammerfall (RME96XX) support' CONFIG_SOUND_RME96XX $CONFIG_SOUND $CONFIG_PCI $CONFIG_EXPERIMENTAL
-dep_tristate '  S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND
+dep_tristate '  S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND $CONFIG_PCI
 if [ "$CONFIG_VISWS" = "y" ]; then
-    dep_tristate '  SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
+    dep_tristate '  SGI Visual Workstation sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
+fi
+if [ "$CONFIG_SGI_IP22" = "y" ] ; then
+   dep_tristate '  SGI HAL2 sound (EXPERIMENTAL)' CONFIG_SOUND_HAL2 $CONFIG_SOUND $CONFIG_SGI_IP22 $CONFIG_EXPERIMENTAL
+fi
+
+if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then
+    dep_tristate '  IT8172G Sound' CONFIG_SOUND_IT8172 $CONFIG_SOUND
 fi
 if [ "$CONFIG_DDB5477" = "y" ]; then
     dep_tristate '  NEC Vrc5477 AC97 sound' CONFIG_SOUND_VRC5477 $CONFIG_SOUND
 fi
-dep_tristate '  Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND
+if [ "$CONFIG_MIPS_AU1000" = "y" ]; then
+    dep_tristate '  Au1000 Sound' CONFIG_SOUND_AU1000 $CONFIG_SOUND
+fi
+
+dep_tristate '  Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND $CONFIG_PCI
 
 dep_tristate '  Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND
 if [ "$CONFIG_SOUND_MSNDCLAS" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "m" ]; then
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/Makefile linux/drivers/sound/Makefile
--- linux.orig/drivers/sound/Makefile	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/sound/Makefile	2002-07-20 01:08:30.000000000 +0000
@@ -20,6 +20,7 @@
 
 # Please leave it as is, cause the link order is significant !
 
+obj-$(CONFIG_SOUND_HAL2)	+= hal2.o
 obj-$(CONFIG_SOUND_AEDSP16)	+= aedsp16.o
 obj-$(CONFIG_SOUND_PSS)		+= pss.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_TRIX)	+= trix.o ad1848.o sb_lib.o uart401.o
@@ -64,16 +65,17 @@
 obj-$(CONFIG_SOUND_ES1370)	+= es1370.o
 obj-$(CONFIG_SOUND_ES1371)	+= es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_VRC5477)	+= nec_vrc5477.o ac97_codec.o
+obj-$(CONFIG_SOUND_AU1000)      += au1000.o ac97_codec.o  
 obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
 obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o ac97_codec.o
 obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
 obj-$(CONFIG_SOUND_MAESTRO3)	+= maestro3.o ac97_codec.o
 obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o ac97_codec.o
 obj-$(CONFIG_SOUND_EMU10K1)	+= ac97_codec.o
+obj-$(CONFIG_SOUND_BCM_CS4297A)	+= swarm_cs4297a.o
 obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o
 obj-$(CONFIG_SOUND_BT878)	+= btaudio.o
-obj-$(CONFIG_SOUND_EMU10K1)	+= ac97_codec.o
-obj-$(CONFIG_SOUND_IT8172)     += ite8172.o ac97_codec.o
+obj-$(CONFIG_SOUND_IT8172)	+= ite8172.o ac97_codec.o
 
 ifeq ($(CONFIG_MIDI_EMU10K1),y)
   obj-$(CONFIG_SOUND_EMU10K1)	+= sound.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
--- linux.orig/drivers/sound/ac97_codec.c	2001-11-12 18:02:54.000000000 +0000
+++ linux/drivers/sound/ac97_codec.c	2002-07-20 01:08:26.000000000 +0000
@@ -31,6 +31,8 @@
  **************************************************************************
  *
  * History
+ * Mar 28, 2002 Randolph Bentson <bentson@holmsjoen.com>
+ *	corrections to support WM9707 in ViewPad 1000
  * v0.4 Mar 15 2000 Ollie Lho
  *	dual codecs support verified with 4 channels output
  * v0.3 Feb 22 2000 Ollie Lho
@@ -59,12 +61,15 @@
 
 static int ac97_init_mixer(struct ac97_codec *codec);
 
-static int wolfson_init(struct ac97_codec * codec);
+static int wolfson_init00(struct ac97_codec * codec);
+static int wolfson_init03(struct ac97_codec * codec);
+static int wolfson_init04(struct ac97_codec * codec);
 static int tritech_init(struct ac97_codec * codec);
 static int tritech_maestro_init(struct ac97_codec * codec);
 static int sigmatel_9708_init(struct ac97_codec *codec);
 static int sigmatel_9721_init(struct ac97_codec *codec);
 static int sigmatel_9744_init(struct ac97_codec *codec);
+static int ad1886_init(struct ac97_codec *codec);
 static int eapd_control(struct ac97_codec *codec, int);
 static int crystal_digital_control(struct ac97_codec *codec, int mode);
 
@@ -87,13 +92,16 @@
  
 static struct ac97_ops null_ops = { NULL, NULL, NULL };
 static struct ac97_ops default_ops = { NULL, eapd_control, NULL };
-static struct ac97_ops wolfson_ops = { wolfson_init, NULL, NULL };
+static struct ac97_ops wolfson_ops00 = { wolfson_init00, NULL, NULL };
+static struct ac97_ops wolfson_ops03 = { wolfson_init03, NULL, NULL };
+static struct ac97_ops wolfson_ops04 = { wolfson_init04, NULL, NULL };
 static struct ac97_ops tritech_ops = { tritech_init, NULL, NULL };
 static struct ac97_ops tritech_m_ops = { tritech_maestro_init, NULL, NULL };
 static struct ac97_ops sigmatel_9708_ops = { sigmatel_9708_init, NULL, NULL };
 static struct ac97_ops sigmatel_9721_ops = { sigmatel_9721_init, NULL, NULL };
 static struct ac97_ops sigmatel_9744_ops = { sigmatel_9744_init, NULL, NULL };
 static struct ac97_ops crystal_digital_ops = { NULL, eapd_control, crystal_digital_control };
+static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL };
 
 /* sorted by vendor/device id */
 static const struct {
@@ -105,11 +113,14 @@
 	{0x41445340, "Analog Devices AD1881",	&null_ops},
 	{0x41445348, "Analog Devices AD1881A",	&null_ops},
 	{0x41445360, "Analog Devices AD1885",	&default_ops},
+	{0x41445361, "Analog Devices AD1886",	&ad1886_ops},
 	{0x41445460, "Analog Devices AD1885",	&default_ops},
+	{0x41445461, "Analog Devices AD1886",	&ad1886_ops},
 	{0x414B4D00, "Asahi Kasei AK4540",	&null_ops},
 	{0x414B4D01, "Asahi Kasei AK4542",	&null_ops},
 	{0x414B4D02, "Asahi Kasei AK4543",	&null_ops},
 	{0x414C4710, "ALC200/200P",		&null_ops},
+	{0x414C4720, "ALC650",			&null_ops},
 	{0x43525900, "Cirrus Logic CS4297",	&default_ops},
 	{0x43525903, "Cirrus Logic CS4297",	&default_ops},
 	{0x43525913, "Cirrus Logic CS4297A rev A", &default_ops},
@@ -131,9 +142,9 @@
 	{0x54524106, "TriTech TR28026",		&null_ops},
 	{0x54524108, "TriTech TR28028",		&tritech_ops},
 	{0x54524123, "TriTech TR A5",		&null_ops},
-	{0x574D4C00, "Wolfson WM9704",		&wolfson_ops},
-	{0x574D4C03, "Wolfson WM9703/9704",	&wolfson_ops},
-	{0x574D4C04, "Wolfson WM9704 (quad)",	&wolfson_ops},
+	{0x574D4C00, "Wolfson WM9700A",		&wolfson_ops00},
+	{0x574D4C03, "Wolfson WM9703/WM9707",	&wolfson_ops03},
+	{0x574D4C04, "Wolfson WM9704M/WM9704Q",	&wolfson_ops04},
 	{0x83847600, "SigmaTel STAC????",	&null_ops},
 	{0x83847604, "SigmaTel STAC9701/3/4/5", &null_ops},
 	{0x83847605, "SigmaTel STAC9704",	&null_ops},
@@ -141,6 +152,7 @@
 	{0x83847609, "SigmaTel STAC9721/23",	&sigmatel_9721_ops},
 	{0x83847644, "SigmaTel STAC9744/45",	&sigmatel_9744_ops},
 	{0x83847656, "SigmaTel STAC9756/57",	&sigmatel_9744_ops},
+	{0x83847666, "SigmaTel STAC9750T",	&sigmatel_9744_ops},
 	{0x83847684, "SigmaTel STAC9783/84?",	&null_ops},
 	{0x57454301, "Winbond 83971D",		&null_ops},
 };
@@ -734,10 +746,10 @@
 
 	/* detect bit resolution */
 	codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020);
-	if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x1f1f)
-		codec->bit_resolution = 5;
-	else
+	if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x2020)
 		codec->bit_resolution = 6;
+	else
+		codec->bit_resolution = 5;
 
 	/* generic OSS to AC97 wrapper */
 	codec->read_mixer = ac97_read_mixer;
@@ -833,7 +845,38 @@
 }
 
 
-static int wolfson_init(struct ac97_codec * codec)
+static int wolfson_init00(struct ac97_codec * codec)
+{
+	/* This initialization is suspect, but not known to be wrong.
+	   It was copied from the initialization for the WM9704Q, but
+	   that same sequence is known to fail for the WM9707.  Thus
+	   this warning may help someone with hardware to test
+	   this code. */
+	codec->codec_write(codec, 0x72, 0x0808);
+	codec->codec_write(codec, 0x74, 0x0808);
+
+	// patch for DVD noise
+	codec->codec_write(codec, 0x5a, 0x0200);
+
+	// init vol as PCM vol
+	codec->codec_write(codec, 0x70,
+		codec->codec_read(codec, AC97_PCMOUT_VOL));
+
+	codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
+	return 0;
+}
+
+
+static int wolfson_init03(struct ac97_codec * codec)
+{
+	/* this is known to work for the ViewSonic ViewPad 1000 */
+	codec->codec_write(codec, 0x72, 0x0808);
+	codec->codec_write(codec, 0x20, 0x8000);
+	return 0;
+}
+
+
+static int wolfson_init04(struct ac97_codec * codec)
 {
 	codec->codec_write(codec, 0x72, 0x0808);
 	codec->codec_write(codec, 0x74, 0x0808);
@@ -871,6 +914,26 @@
 }
 
 
+
+/* 
+ *	Presario700 workaround 
+ * 	for Jack Sense/SPDIF Register mis-setting causing
+ *	no audible output
+ *	by Santiago Nullo 04/05/2002
+ */
+
+#define AC97_AD1886_JACK_SENSE 0x72
+
+static int ad1886_init(struct ac97_codec * codec)
+{
+	/* from AD1886 Specs */
+	codec->codec_write(codec, AC97_AD1886_JACK_SENSE, 0x0010);
+	return 0;
+}
+
+
+
+
 /*
  *	This is basically standard AC97. It should work as a default for
  *	almost all modern codecs. Note that some cards wire EAPD *backwards*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/ad1816.c linux/drivers/sound/ad1816.c
--- linux.orig/drivers/sound/ad1816.c	2001-11-09 23:22:54.000000000 +0000
+++ linux/drivers/sound/ad1816.c	2002-07-20 01:08:39.000000000 +0000
@@ -1318,26 +1318,13 @@
 	return(ad1816_dev);
 }
 
-static struct ad1816_data {
-	struct pci_dev * (*initfunc)(struct pci_bus*, struct pci_dev *, struct address_info *);
-	char *name;
-} ad1816_pnp_data[] __initdata = {
-	{ &ad1816_init_generic, "Analog Devices 1815" },
-	{ &ad1816_init_generic, "Analog Devices 1816A" }
-};
-
-static struct {
-	unsigned short card_vendor, card_device;
-	unsigned short vendor;
-	unsigned short function;
-	struct ad1816_data *data;
-} isapnp_ad1816_list[] __initdata = {
+struct isapnp_device_id isapnp_ad1816_list[] __initdata = {
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
 		ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7150), 
-		&ad1816_pnp_data[0] },
+		0 },
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
 		ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7180),
-		&ad1816_pnp_data[1] },
+		0 },
 	{0}
 };
 
@@ -1346,27 +1333,22 @@
 static int __init ad1816_init_isapnp(struct address_info *hw_config,
 	struct pci_bus *bus, struct pci_dev *card, int slot)
 {
+	char *busname = bus->name[0] ? bus->name : "Analog Devices AD1816a";
 	struct pci_dev *idev = NULL;
-	
-	/* You missed the init func? That's bad. */
-	if(isapnp_ad1816_list[slot].data->initfunc) {
-		char *busname = bus->name[0] ? bus->name : isapnp_ad1816_list[slot].data->name;
 		
-		printk(KERN_INFO "ad1816: %s detected\n", busname);
+	printk(KERN_INFO "ad1816: %s detected\n", busname);
 		
-		/* Initialize this baby. */
-		if((idev = isapnp_ad1816_list[slot].data->initfunc(bus, card, hw_config))) {
-			/* We got it. */
-
-			printk(KERN_NOTICE "ad1816: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
-				busname,
-				hw_config->io_base, hw_config->irq, hw_config->dma,
-				hw_config->dma2);
-			return 1;
-		} else
-			printk(KERN_INFO "ad1816: Failed to initialize %s\n", busname);
+	/* Initialize this baby. */
+	if ((idev = ad1816_init_generic(bus, card, hw_config))) {
+		/* We got it. */
+
+		printk(KERN_NOTICE "ad1816: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
+			busname,
+			hw_config->io_base, hw_config->irq, hw_config->dma,
+			hw_config->dma2);
+		return 1;
 	} else
-		printk(KERN_ERR "ad1816: Bad entry in ad1816.c PnP table\n");
+		printk(KERN_INFO "ad1816: Failed to initialize %s\n", busname);
 	
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- linux.orig/drivers/sound/ad1848.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/sound/ad1848.c	2002-07-20 01:08:24.000000000 +0000
@@ -33,6 +33,7 @@
  * Alan Cox		: Added CS4236->4239 identification
  * Daniel T. Cobra	: Alernate config/mixer for later chips
  * Alan Cox		: Merged chip idents and config code
+ * Zwane Mwaikambo	: Fix ISA PnP scan
  *
  * TODO
  *		APM save restore assist code on IBM thinkpad
@@ -3003,11 +3004,10 @@
 	return(dev);
 }
 
-static struct pci_dev *ad1848_init_generic(struct pci_bus *bus, struct address_info *hw_config, int slot)
+static struct pci_dev *ad1848_init_generic(struct pci_dev *dev, struct address_info *hw_config, int slot)
 {
-
-	/* Configure Audio device */
-	if((ad1848_dev = isapnp_find_dev(bus, ad1848_isapnp_list[slot].vendor, ad1848_isapnp_list[slot].function, NULL)))
+	/* Configure Audio device, point ad1848_dev to device found */
+	if((ad1848_dev = dev))
 	{
 		int ret;
 		ret = ad1848_dev->prepare(ad1848_dev);
@@ -3038,25 +3038,25 @@
 	return(ad1848_dev);
 }
 
-static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pci_bus *bus, int slot)
+static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pci_dev *dev, int slot)
 {
-	char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name;
+	char *devname = dev->name[0] ? dev->name : ad1848_isapnp_list[slot].name;
 
-	printk(KERN_INFO "ad1848: %s detected\n", busname);
+	printk(KERN_INFO "ad1848: %s detected\n", devname);
 
 	/* Initialize this baby. */
 
-	if(ad1848_init_generic(bus, hw_config, slot)) {
+	if(ad1848_init_generic(dev, hw_config, slot)) {
 		/* We got it. */
 
 		printk(KERN_NOTICE "ad1848: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
-		       busname,
+		       devname,
 		       hw_config->io_base, hw_config->irq, hw_config->dma,
 		       hw_config->dma2);
 		return 1;
 	}
 	else
-		printk(KERN_INFO "ad1848: Failed to initialize %s\n", busname);
+		printk(KERN_INFO "ad1848: Failed to initialize %s\n", devname);
 
 	return 0;
 }
@@ -3080,14 +3080,14 @@
 		i = isapnpjump;
 	first = 0;
 	while(ad1848_isapnp_list[i].card_vendor != 0) {
-		static struct pci_bus *bus = NULL;
-
-		while ((bus = isapnp_find_card(
-				ad1848_isapnp_list[i].card_vendor,
-				ad1848_isapnp_list[i].card_device,
-				bus))) {
+		static struct pci_dev *dev = NULL;
 
-			if(ad1848_isapnp_init(hw_config, bus, i)) {
+		while ((dev = isapnp_find_dev(NULL,
+				ad1848_isapnp_list[i].vendor,
+				ad1848_isapnp_list[i].function,
+				NULL))) {
+			
+			if(ad1848_isapnp_init(hw_config, dev, i)) {
 				isapnpjump = i; /* start next search from here */
 				return 0;
 			}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/au1000.c linux/drivers/sound/au1000.c
--- linux.orig/drivers/sound/au1000.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/sound/au1000.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,2158 @@
+/*
+ *      au1000.c  --  Sound driver for Alchemy Au1000 MIPS Internet Edge
+ *                    Processor.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	stevel@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Module command line parameters:
+ *
+ *  Supported devices:
+ *  /dev/dsp    standard OSS /dev/dsp device
+ *  /dev/mixer  standard OSS /dev/mixer device
+ *
+ * Notes:
+ *
+ *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
+ *     taken, slightly modified or not at all, from the ES1371 driver,
+ *     so refer to the credits in es1371.c for those. The rest of the
+ *     code (probe, open, read, write, the ISR, etc.) is new.
+ *
+ *  Revision history
+ *    06.27.2001  Initial version
+ */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/slab.h>
+#include <linux/soundcard.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/au1000.h>
+#include <asm/au1000_dma.h>
+
+/* --------------------------------------------------------------------- */
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+#define AU1000_DEBUG
+#undef AU1000_VERBOSE_DEBUG
+
+
+#define AU1000_MODULE_NAME "Au1000 audio"
+#define PFX AU1000_MODULE_NAME
+
+#ifdef AU1000_DEBUG
+#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
+
+
+/* misc stuff */
+#define POLL_COUNT   0x5000
+#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
+
+/* Boot options */
+static int      vra = 0;	// 0 = no VRA, 1 = use VRA if codec supports it
+MODULE_PARM(vra, "i");
+MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
+
+
+/* --------------------------------------------------------------------- */
+
+struct au1000_state {
+	/* soundcore stuff */
+	int             dev_audio;
+
+#ifdef AU1000_DEBUG
+	/* debug /proc entry */
+	struct proc_dir_entry *ps;
+	struct proc_dir_entry *ac97_ps;
+#endif				/* AU1000_DEBUG */
+
+	struct ac97_codec codec;
+	unsigned        codec_base_caps;	// AC'97 reg 00h, "Reset Register"
+	unsigned        codec_ext_caps;	// AC'97 reg 28h, "Extended Audio ID"
+	int             no_vra;	// do not use VRA
+
+	spinlock_t      lock;
+	struct semaphore open_sem;
+	mode_t          open_mode;
+	wait_queue_head_t open_wait;
+
+	struct dmabuf {
+		unsigned int    dmanr;	// DMA Channel number
+		int             irq;	// DMA Channel Done IRQ number
+		unsigned        sample_rate;	// Hz
+		unsigned src_factor;     // SRC interp/decimation (no vra)
+		unsigned        sample_size;	// 8 or 16
+		int             num_channels;	// 1 = mono, 2 = stereo, 4, 6
+		int dma_bytes_per_sample;// DMA bytes per audio sample frame
+		int user_bytes_per_sample;// User bytes per audio sample frame
+		int cnt_factor;          // user-to-DMA bytes per audio
+		//  sample frame
+		void           *rawbuf;
+		dma_addr_t      dmaaddr;
+		unsigned        buforder;
+		unsigned numfrag;        // # of DMA fragments in DMA buffer
+		unsigned        fragshift;
+		void           *nextIn;	// ptr to next-in to DMA buffer
+		void           *nextOut;	// ptr to next-out from DMA buffer
+		int             count;	// current byte count in DMA buffer
+		unsigned        total_bytes;	// total bytes written or read
+		unsigned        error;	// over/underrun
+		wait_queue_head_t wait;
+		/* redundant, but makes calculations easier */
+		unsigned fragsize;       // user perception of fragment size
+		unsigned dma_fragsize;   // DMA (real) fragment size
+		unsigned dmasize;        // Total DMA buffer size
+		//   (mult. of DMA fragsize)
+		/* OSS stuff */
+		unsigned        mapped:1;
+		unsigned        ready:1;
+		unsigned        stopped:1;
+		unsigned        ossfragshift;
+		int             ossmaxfrags;
+		unsigned        subdivision;
+	} dma_dac      , dma_adc;
+} au1000_state;
+
+/* --------------------------------------------------------------------- */
+
+
+static inline unsigned ld2(unsigned int x)
+{
+	unsigned        r = 0;
+
+	if (x >= 0x10000) {
+		x >>= 16;
+		r += 16;
+	}
+	if (x >= 0x100) {
+		x >>= 8;
+		r += 8;
+	}
+	if (x >= 0x10) {
+		x >>= 4;
+		r += 4;
+	}
+	if (x >= 4) {
+		x >>= 2;
+		r += 2;
+	}
+	if (x >= 2)
+		r++;
+	return r;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static void au1000_delay(int msec)
+{
+	unsigned long   tmo;
+	signed long     tmo2;
+
+	if (in_interrupt())
+		return;
+
+	tmo = jiffies + (msec * HZ) / 1000;
+	for (;;) {
+		tmo2 = tmo - jiffies;
+		if (tmo2 <= 0)
+			break;
+		schedule_timeout(tmo2);
+	}
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static u16 rdcodec(struct ac97_codec *codec, u8 addr)
+{
+	struct au1000_state *s = (struct au1000_state *)codec->private_data;
+	unsigned long   flags;
+	u32             cmd;
+	u16             data;
+	int             i;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	for (i = 0; i < POLL_COUNT; i++)
+		if (!(au_readl(AC97C_STATUS) & AC97C_CP))
+			break;
+	if (i == POLL_COUNT)
+		err("rdcodec: codec cmd pending expired!");
+
+	cmd = (u32) addr & AC97C_INDEX_MASK;
+	cmd |= AC97C_READ;	// read command
+	au_writel(cmd, AC97C_CMD);
+
+	/* now wait for the data */
+	for (i = 0; i < POLL_COUNT; i++)
+		if (!(au_readl(AC97C_STATUS) & AC97C_CP))
+			break;
+	if (i == POLL_COUNT) {
+		err("rdcodec: read poll expired!");
+		return 0;
+	}
+
+	data = au_readl(AC97C_CMD) & 0xffff;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	return data;
+}
+
+
+static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+	struct au1000_state *s = (struct au1000_state *)codec->private_data;
+	unsigned long   flags;
+	u32             cmd;
+	int             i;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	for (i = 0; i < POLL_COUNT; i++)
+		if (!(au_readl(AC97C_STATUS) & AC97C_CP))
+			break;
+	if (i == POLL_COUNT)
+		err("wrcodec: codec cmd pending expired!");
+
+	cmd = (u32) addr & AC97C_INDEX_MASK;
+	cmd &= ~AC97C_READ;	// write command
+	cmd |= ((u32) data << AC97C_WD_BIT);	// OR in the data word
+	au_writel(cmd, AC97C_CMD);
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void waitcodec(struct ac97_codec *codec)
+{
+	u16             temp;
+	int             i;
+
+	/* codec_wait is used to wait for a ready state after
+	   an AC97C_RESET. */
+	au1000_delay(10);
+
+	// first poll the CODEC_READY tag bit
+	for (i = 0; i < POLL_COUNT; i++)
+		if (au_readl(AC97C_STATUS) & AC97C_READY)
+			break;
+	if (i == POLL_COUNT) {
+		err("waitcodec: CODEC_READY poll expired!");
+		return;
+	}
+	// get AC'97 powerdown control/status register
+	temp = rdcodec(codec, AC97_POWER_CONTROL);
+
+	// If anything is powered down, power'em up
+	if (temp & 0x7f00) {
+		// Power on
+		wrcodec(codec, AC97_POWER_CONTROL, 0);
+		au1000_delay(100);
+		// Reread
+		temp = rdcodec(codec, AC97_POWER_CONTROL);
+	}
+    
+	// Check if Codec REF,ANL,DAC,ADC ready
+	if ((temp & 0x7f0f) != 0x000f)
+		err("codec reg 26 status (0x%x) not ready!!", temp);
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static void set_adc_rate(struct au1000_state *s, unsigned rate)
+{
+	struct dmabuf  *adc = &s->dma_adc;
+	struct dmabuf  *dac = &s->dma_dac;
+	unsigned        adc_rate, dac_rate;
+	u16             ac97_extstat;
+
+	if (s->no_vra) {
+		// calc SRC factor
+		adc->src_factor = ((96000 / rate) + 1) >> 1;
+		adc->sample_rate = 48000 / adc->src_factor;
+		return;
+	}
+
+	adc->src_factor = 1;
+
+	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
+
+	rate = rate > 48000 ? 48000 : rate;
+
+	// enable VRA
+	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+		ac97_extstat | AC97_EXTSTAT_VRA);
+	// now write the sample rate
+	wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
+	// read it back for actual supported rate
+	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg(__FUNCTION__ ": set to %d Hz", adc_rate);
+#endif
+
+	// some codec's don't allow unequal DAC and ADC rates, in which case
+	// writing one rate reg actually changes both.
+	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+	if (dac->num_channels > 2)
+		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
+	if (dac->num_channels > 4)
+		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
+
+	adc->sample_rate = adc_rate;
+	dac->sample_rate = dac_rate;
+}
+
+static void set_dac_rate(struct au1000_state *s, unsigned rate)
+{
+	struct dmabuf  *dac = &s->dma_dac;
+	struct dmabuf  *adc = &s->dma_adc;
+	unsigned        adc_rate, dac_rate;
+	u16             ac97_extstat;
+
+	if (s->no_vra) {
+		// calc SRC factor
+		dac->src_factor = ((96000 / rate) + 1) >> 1;
+		dac->sample_rate = 48000 / dac->src_factor;
+		return;
+	}
+
+	dac->src_factor = 1;
+
+	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
+
+	rate = rate > 48000 ? 48000 : rate;
+
+	// enable VRA
+	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+		ac97_extstat | AC97_EXTSTAT_VRA);
+	// now write the sample rate
+	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
+	// I don't support different sample rates for multichannel,
+	// so make these channels the same.
+	if (dac->num_channels > 2)
+		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
+	if (dac->num_channels > 4)
+		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
+	// read it back for actual supported rate
+	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg(__FUNCTION__ ": set to %d Hz", dac_rate);
+#endif
+
+	// some codec's don't allow unequal DAC and ADC rates, in which case
+	// writing one rate reg actually changes both.
+	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
+
+	dac->sample_rate = dac_rate;
+	adc->sample_rate = adc_rate;
+}
+
+static void stop_dac(struct au1000_state *s)
+{
+	struct dmabuf  *db = &s->dma_dac;
+	unsigned long   flags;
+
+	if (db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	disable_dma(db->dmanr);
+
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void  stop_adc(struct au1000_state *s)
+{
+	struct dmabuf  *db = &s->dma_adc;
+	unsigned long   flags;
+
+	if (db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	disable_dma(db->dmanr);
+
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void set_xmit_slots(int num_channels)
+{
+	u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_XMIT_SLOTS_MASK;
+
+	switch (num_channels) {
+	case 1:		// mono
+	case 2:		// stereo, slots 3,4
+		ac97_config |= (0x3 << AC97C_XMIT_SLOTS_BIT);
+		break;
+	case 4:		// stereo with surround, slots 3,4,7,8
+		ac97_config |= (0x33 << AC97C_XMIT_SLOTS_BIT);
+		break;
+	case 6:		// stereo with surround and center/LFE, slots 3,4,6,7,8,9
+		ac97_config |= (0x7b << AC97C_XMIT_SLOTS_BIT);
+		break;
+	}
+
+	au_writel(ac97_config, AC97C_CONFIG);
+}
+
+static void     set_recv_slots(int num_channels)
+{
+	u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_RECV_SLOTS_MASK;
+
+	/*
+	 * Always enable slots 3 and 4 (stereo). Slot 6 is
+	 * optional Mic ADC, which I don't support yet.
+	 */
+	ac97_config |= (0x3 << AC97C_RECV_SLOTS_BIT);
+
+	au_writel(ac97_config, AC97C_CONFIG);
+}
+
+static void start_dac(struct au1000_state *s)
+{
+	struct dmabuf  *db = &s->dma_dac;
+	unsigned long   flags;
+	unsigned long   buf1, buf2;
+
+	if (!db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	au_readl(AC97C_STATUS);	// read status to clear sticky bits
+
+	// reset Buffer 1 and 2 pointers to nextOut and nextOut+dma_fragsize
+	buf1 = virt_to_phys(db->nextOut);
+	buf2 = buf1 + db->dma_fragsize;
+	if (buf2 >= db->dmaaddr + db->dmasize)
+		buf2 -= db->dmasize;
+
+	set_xmit_slots(db->num_channels);
+
+	set_dma_count(db->dmanr, db->dma_fragsize>>1);
+	if (get_dma_active_buffer(db->dmanr) == 0) {
+		set_dma_addr0(db->dmanr, buf1);
+		set_dma_addr1(db->dmanr, buf2);
+	} else {
+		set_dma_addr1(db->dmanr, buf1);
+		set_dma_addr0(db->dmanr, buf2);
+	}
+	enable_dma_buffers(db->dmanr);
+
+	enable_dma(db->dmanr);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dump_au1000_dma_channel(db->dmanr);
+#endif
+
+	db->stopped = 0;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void start_adc(struct au1000_state *s)
+{
+	struct dmabuf  *db = &s->dma_adc;
+	unsigned long   flags;
+	unsigned long   buf1, buf2;
+
+	if (!db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	au_readl(AC97C_STATUS);	// read status to clear sticky bits
+
+	// reset Buffer 1 and 2 pointers to nextIn and nextIn+dma_fragsize
+	buf1 = virt_to_phys(db->nextIn);
+	buf2 = buf1 + db->dma_fragsize;
+	if (buf2 >= db->dmaaddr + db->dmasize)
+		buf2 -= db->dmasize;
+
+	set_recv_slots(db->num_channels);
+
+	set_dma_count(db->dmanr, db->dma_fragsize>>1);
+	if (get_dma_active_buffer(db->dmanr) == 0) {
+		set_dma_addr0(db->dmanr, buf1);
+		set_dma_addr1(db->dmanr, buf2);
+	} else {
+		set_dma_addr1(db->dmanr, buf1);
+		set_dma_addr0(db->dmanr, buf2);
+	}
+	enable_dma_buffers(db->dmanr);
+
+	enable_dma(db->dmanr);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dump_au1000_dma_channel(db->dmanr);
+#endif
+
+	db->stopped = 0;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+/* --------------------------------------------------------------------- */
+
+#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
+#define DMABUF_MINORDER 1
+
+extern inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db)
+{
+	struct page    *page, *pend;
+
+	if (db->rawbuf) {
+		/* undo marking the pages as reserved */
+		pend = virt_to_page(db->rawbuf +
+				    (PAGE_SIZE << db->buforder) - 1);
+		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+			mem_map_unreserve(page);
+		pci_free_consistent(NULL, PAGE_SIZE << db->buforder,
+				    db->rawbuf, db->dmaaddr);
+	}
+	db->rawbuf = db->nextIn = db->nextOut = NULL;
+	db->mapped = db->ready = 0;
+}
+
+static int prog_dmabuf(struct au1000_state *s, struct dmabuf *db)
+{
+	int             order;
+	unsigned user_bytes_per_sec;
+	unsigned        bufs;
+	struct page    *page, *pend;
+	unsigned        rate = db->sample_rate;
+
+	if (!db->rawbuf) {
+		db->ready = db->mapped = 0;
+		for (order = DMABUF_DEFAULTORDER;
+		     order >= DMABUF_MINORDER; order--)
+			if ((db->rawbuf =
+			     pci_alloc_consistent(NULL,
+						  PAGE_SIZE << order,
+						  &db->dmaaddr)))
+				break;
+		if (!db->rawbuf)
+			return -ENOMEM;
+		db->buforder = order;
+		/* now mark the pages as reserved;
+		   otherwise remap_page_range doesn't do what we want */
+		pend = virt_to_page(db->rawbuf +
+				    (PAGE_SIZE << db->buforder) - 1);
+		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+			mem_map_reserve(page);
+	}
+
+	db->cnt_factor = 1;
+	if (db->sample_size == 8)
+		db->cnt_factor *= 2;
+	if (db->num_channels == 1)
+		db->cnt_factor *= 2;
+	db->cnt_factor *= db->src_factor;
+
+	db->count = 0;
+	db->nextIn = db->nextOut = db->rawbuf;
+
+	db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
+	db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
+					2 : db->num_channels);
+
+	user_bytes_per_sec = rate * db->user_bytes_per_sample;
+	bufs = PAGE_SIZE << db->buforder;
+	if (db->ossfragshift) {
+		if ((1000 << db->ossfragshift) < user_bytes_per_sec)
+			db->fragshift = ld2(user_bytes_per_sec/1000);
+		else
+			db->fragshift = db->ossfragshift;
+	} else {
+		db->fragshift = ld2(user_bytes_per_sec / 100 /
+				    (db->subdivision ? db->subdivision : 1));
+		if (db->fragshift < 3)
+			db->fragshift = 3;
+	}
+
+	db->fragsize = 1 << db->fragshift;
+	db->dma_fragsize = db->fragsize * db->cnt_factor;
+	db->numfrag = bufs / db->dma_fragsize;
+
+	while (db->numfrag < 4 && db->fragshift > 3) {
+		db->fragshift--;
+		db->fragsize = 1 << db->fragshift;
+		db->dma_fragsize = db->fragsize * db->cnt_factor;
+		db->numfrag = bufs / db->dma_fragsize;
+	}
+
+	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+		db->numfrag = db->ossmaxfrags;
+
+	db->dmasize = db->dma_fragsize * db->numfrag;
+	memset(db->rawbuf, 0, bufs);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg("rate=%d, samplesize=%d, channels=%d",
+	    rate, db->sample_size, db->num_channels);
+	dbg("fragsize=%d, cnt_factor=%d, dma_fragsize=%d",
+	    db->fragsize, db->cnt_factor, db->dma_fragsize);
+	dbg("numfrag=%d, dmasize=%d", db->numfrag, db->dmasize);
+#endif
+
+	db->ready = 1;
+	return 0;
+}
+
+extern inline int prog_dmabuf_adc(struct au1000_state *s)
+{
+	stop_adc(s);
+	return prog_dmabuf(s, &s->dma_adc);
+
+}
+
+extern inline int prog_dmabuf_dac(struct au1000_state *s)
+{
+	stop_dac(s);
+	return prog_dmabuf(s, &s->dma_dac);
+}
+
+
+/* hold spinlock for the following */
+static void dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct au1000_state *s = (struct au1000_state *) dev_id;
+	struct dmabuf  *dac = &s->dma_dac;
+	unsigned long   newptr;
+	u32 ac97c_stat, buff_done;
+
+	ac97c_stat = au_readl(AC97C_STATUS);
+#ifdef AU1000_VERBOSE_DEBUG
+	if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
+		dbg("AC97C status = 0x%08x", ac97c_stat);
+#endif
+
+	if ((buff_done = get_dma_buffer_done(dac->dmanr)) == 0) {
+		/* fastpath out, to ease interrupt sharing */
+		return;
+	}
+
+	if (buff_done != (DMA_D0 | DMA_D1)) {
+		dac->nextOut += dac->dma_fragsize;
+		if (dac->nextOut >= dac->rawbuf + dac->dmasize)
+			dac->nextOut -= dac->dmasize;
+
+		/* update playback pointers */
+		newptr = virt_to_phys(dac->nextOut) + dac->dma_fragsize;
+		if (newptr >= dac->dmaaddr + dac->dmasize)
+			newptr -= dac->dmasize;
+
+		dac->count -= dac->dma_fragsize;
+		dac->total_bytes += dac->dma_fragsize;
+
+		if (dac->count <= 0)
+			stop_dac(s);
+		else if (buff_done == DMA_D0) {
+			clear_dma_done0(dac->dmanr);	// clear DMA done bit
+			set_dma_count0(dac->dmanr, dac->dma_fragsize>>1);
+			set_dma_addr0(dac->dmanr, newptr);
+			enable_dma_buffer0(dac->dmanr);	// reenable
+		} else {
+			clear_dma_done1(dac->dmanr);	// clear DMA done bit
+			set_dma_count1(dac->dmanr, dac->dma_fragsize>>1);
+			set_dma_addr1(dac->dmanr, newptr);
+			enable_dma_buffer1(dac->dmanr);	// reenable
+		}
+	} else {
+		// both done bits set, we missed an interrupt
+		stop_dac(s);
+
+		dac->nextOut += 2*dac->dma_fragsize;
+		if (dac->nextOut >= dac->rawbuf + dac->dmasize)
+			dac->nextOut -= dac->dmasize;
+
+		dac->count -= 2*dac->dma_fragsize;
+		dac->total_bytes += 2*dac->dma_fragsize;
+
+		if (dac->count > 0)
+			start_dac(s);
+	}
+
+
+	/* wake up anybody listening */
+	if (waitqueue_active(&dac->wait))
+		wake_up_interruptible(&dac->wait);
+}
+
+
+static void adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct au1000_state *s = (struct au1000_state *) dev_id;
+	struct dmabuf  *adc = &s->dma_adc;
+	unsigned long   newptr;
+	u32 ac97c_stat, buff_done;
+
+	ac97c_stat = au_readl(AC97C_STATUS);
+#ifdef AU1000_VERBOSE_DEBUG
+	if (ac97c_stat & (AC97C_RU | AC97C_RO))
+		dbg("AC97C status = 0x%08x", ac97c_stat);
+#endif
+
+	if ((buff_done = get_dma_buffer_done(adc->dmanr)) == 0) {
+		/* fastpath out, to ease interrupt sharing */
+		return;
+	}
+
+	if (buff_done != (DMA_D0 | DMA_D1)) {
+		if (adc->count + adc->dma_fragsize > adc->dmasize) {
+			// Overrun. Stop ADC and log the error
+			stop_adc(s);
+			adc->error++;
+			err("adc overrun");
+			return;
+		}
+
+		adc->nextIn += adc->dma_fragsize;
+		if (adc->nextIn >= adc->rawbuf + adc->dmasize)
+			adc->nextIn -= adc->dmasize;
+
+		/* update capture pointers */
+		newptr = virt_to_phys(adc->nextIn) + adc->dma_fragsize;
+		if (newptr >= adc->dmaaddr + adc->dmasize)
+			newptr -= adc->dmasize;
+
+		adc->count += adc->dma_fragsize;
+		adc->total_bytes += adc->dma_fragsize;
+
+		if (buff_done == DMA_D0) {
+			clear_dma_done0(adc->dmanr);	// clear DMA done bit
+			set_dma_count0(adc->dmanr, adc->dma_fragsize>>1);
+			set_dma_addr0(adc->dmanr, newptr);
+			enable_dma_buffer0(adc->dmanr);	// reenable
+		} else {
+			clear_dma_done1(adc->dmanr);	// clear DMA done bit
+			set_dma_count1(adc->dmanr, adc->dma_fragsize>>1);
+			set_dma_addr1(adc->dmanr, newptr);
+			enable_dma_buffer1(adc->dmanr);	// reenable
+		}
+	} else {
+		// both done bits set, we missed an interrupt
+		stop_adc(s);
+		
+		if (adc->count + 2*adc->dma_fragsize > adc->dmasize) {
+			// Overrun. Log the error
+			adc->error++;
+			err("adc overrun");
+			return;
+		}
+
+		adc->nextIn += 2*adc->dma_fragsize;
+		if (adc->nextIn >= adc->rawbuf + adc->dmasize)
+			adc->nextIn -= adc->dmasize;
+
+		adc->count += 2*adc->dma_fragsize;
+		adc->total_bytes += 2*adc->dma_fragsize;
+		
+		start_adc(s);
+	}
+
+	/* wake up anybody listening */
+	if (waitqueue_active(&adc->wait))
+		wake_up_interruptible(&adc->wait);
+}
+
+/* --------------------------------------------------------------------- */
+
+static loff_t au1000_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+
+static int au1000_open_mixdev(struct inode *inode, struct file *file)
+{
+	file->private_data = &au1000_state;
+	return 0;
+}
+
+static int au1000_release_mixdev(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+                        unsigned long arg)
+{
+	return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int au1000_ioctl_mixdev(struct inode *inode, struct file *file,
+			       unsigned int cmd, unsigned long arg)
+{
+	struct au1000_state *s = (struct au1000_state *)file->private_data;
+	struct ac97_codec *codec = &s->codec;
+
+	return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const */ struct file_operations au1000_mixer_fops = {
+	owner:THIS_MODULE,
+	llseek:au1000_llseek,
+	ioctl:au1000_ioctl_mixdev,
+	open:au1000_open_mixdev,
+	release:au1000_release_mixdev,
+};
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct au1000_state *s, int nonblock)
+{
+	unsigned long   flags;
+	int             count, tmo;
+
+	if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
+		return 0;
+
+	for (;;) {
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count <= 0)
+			break;
+		if (signal_pending(current))
+			break;
+		if (nonblock)
+			return -EBUSY;
+		tmo = 1000 * count / (s->no_vra ?
+				      48000 : s->dma_dac.sample_rate);
+		tmo /= s->dma_dac.dma_bytes_per_sample;
+		au1000_delay(tmo);
+	}
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static inline u8 S16_TO_U8(s16 ch)
+{
+	return (u8) (ch >> 8) + 0x80;
+}
+static inline s16 U8_TO_S16(u8 ch)
+{
+	return (s16) (ch - 0x80) << 8;
+}
+
+/*
+ * Translates user samples to dma buffer suitable for AC'97 DAC data:
+ *     If mono, copy left channel to right channel in dma buffer.
+ *     If 8 bit samples, cvt to 16-bit before writing to dma buffer.
+ *     If interpolating (no VRA), duplicate every audio frame src_factor times.
+ */
+static int translate_from_user(struct dmabuf *db,
+			       char* dmabuf,
+			       char* userbuf,
+			       int dmacount)
+{
+	int             sample, i;
+	int             interp_bytes_per_sample;
+	int             num_samples;
+	int             mono = (db->num_channels == 1);
+	char            usersample[12];
+	s16             ch, dmasample[6];
+
+	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
+		// no translation necessary, just copy
+		if (copy_from_user(dmabuf, userbuf, dmacount))
+			return -EFAULT;
+		return dmacount;
+	}
+
+	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
+	num_samples = dmacount / interp_bytes_per_sample;
+
+	for (sample = 0; sample < num_samples; sample++) {
+		if (copy_from_user(usersample, userbuf,
+				   db->user_bytes_per_sample)) {
+			dbg(__FUNCTION__ "fault");
+			return -EFAULT;
+		}
+
+		for (i = 0; i < db->num_channels; i++) {
+			if (db->sample_size == 8)
+				ch = U8_TO_S16(usersample[i]);
+			else
+				ch = *((s16 *) (&usersample[i * 2]));
+			dmasample[i] = ch;
+			if (mono)
+				dmasample[i + 1] = ch;	// right channel
+		}
+
+		// duplicate every audio frame src_factor times
+		for (i = 0; i < db->src_factor; i++)
+			memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
+
+		userbuf += db->user_bytes_per_sample;
+		dmabuf += interp_bytes_per_sample;
+	}
+
+	return num_samples * interp_bytes_per_sample;
+}
+
+/*
+ * Translates AC'97 ADC samples to user buffer:
+ *     If mono, send only left channel to user buffer.
+ *     If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
+ *     If decimating (no VRA), skip over src_factor audio frames.
+ */
+static int translate_to_user(struct dmabuf *db,
+			     char* userbuf,
+			     char* dmabuf,
+			     int dmacount)
+{
+	int             sample, i;
+	int             interp_bytes_per_sample;
+	int             num_samples;
+	int             mono = (db->num_channels == 1);
+	char            usersample[12];
+
+	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
+		// no translation necessary, just copy
+		if (copy_to_user(userbuf, dmabuf, dmacount))
+			return -EFAULT;
+		return dmacount;
+	}
+
+	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
+	num_samples = dmacount / interp_bytes_per_sample;
+
+	for (sample = 0; sample < num_samples; sample++) {
+		for (i = 0; i < db->num_channels; i++) {
+			if (db->sample_size == 8)
+				usersample[i] =
+					S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
+			else
+				*((s16 *) (&usersample[i * 2])) =
+					*((s16 *) (&dmabuf[i * 2]));
+		}
+
+		if (copy_to_user(userbuf, usersample,
+				 db->user_bytes_per_sample)) {
+			dbg(__FUNCTION__ "fault");
+			return -EFAULT;
+		}
+
+		userbuf += db->user_bytes_per_sample;
+		dmabuf += interp_bytes_per_sample;
+	}
+
+	return num_samples * interp_bytes_per_sample;
+}
+
+/*
+ * Copy audio data to/from user buffer from/to dma buffer, taking care
+ * that we wrap when reading/writing the dma buffer. Returns actual byte
+ * count written to or read from the dma buffer.
+ */
+static int copy_dmabuf_user(struct dmabuf *db, char* userbuf,
+			    int count, int to_user)
+{
+	char           *bufptr = to_user ? db->nextOut : db->nextIn;
+	char           *bufend = db->rawbuf + db->dmasize;
+	int             cnt, ret;
+
+	if (bufptr + count > bufend) {
+		int             partial = (int) (bufend - bufptr);
+		if (to_user) {
+			if ((cnt = translate_to_user(db, userbuf,
+						     bufptr, partial)) < 0)
+				return cnt;
+			ret = cnt;
+			if ((cnt = translate_to_user(db, userbuf + partial,
+						     db->rawbuf,
+						     count - partial)) < 0)
+				return cnt;
+			ret += cnt;
+		} else {
+			if ((cnt = translate_from_user(db, bufptr, userbuf,
+						       partial)) < 0)
+				return cnt;
+			ret = cnt;
+			if ((cnt = translate_from_user(db, db->rawbuf,
+						       userbuf + partial,
+						       count - partial)) < 0)
+				return cnt;
+			ret += cnt;
+		}
+	} else {
+		if (to_user)
+			ret = translate_to_user(db, userbuf, bufptr, count);
+		else
+			ret = translate_from_user(db, bufptr, userbuf, count);
+	}
+
+	return ret;
+}
+
+
+static ssize_t au1000_read(struct file *file, char *buffer,
+			   size_t count, loff_t *ppos)
+{
+	struct au1000_state *s = (struct au1000_state *)file->private_data;
+	struct dmabuf  *db = &s->dma_adc;
+	ssize_t         ret;
+	unsigned long   flags;
+	int             cnt, remainder, usercnt, avail;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	count *= db->cnt_factor;
+
+	while (count > 0) {
+		// wait for samples in ADC dma buffer
+		do {
+			if (db->stopped)
+				start_adc(s);
+			spin_lock_irqsave(&s->lock, flags);
+			avail = db->count;
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					return ret;
+				}
+				interruptible_sleep_on(&db->wait);
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					return ret;
+				}
+			}
+		} while (avail <= 0);
+
+		// copy from nextOut to user
+		if ((cnt = copy_dmabuf_user(db, buffer,
+					    count > avail ?
+					    avail : count, 1)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			return ret;
+		}
+
+		spin_lock_irqsave(&s->lock, flags);
+		db->count -= cnt;
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		db->nextOut += cnt;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+
+		count -= cnt;
+		usercnt = cnt / db->cnt_factor;
+		buffer += usercnt;
+		ret += usercnt;
+	}			// while (count > 0)
+
+	/*
+	 * See if the dma buffer count after this read call is
+	 * aligned on a dma_fragsize boundary. If not, read from
+	 * buffer until we reach a boundary, and let's hope this
+	 * is just the last remainder of an audio record. If not
+	 * it means the user is not reading in fragsize chunks, in
+	 * which case it's his/her fault that there are audio gaps
+	 * in their record.
+	 */
+	spin_lock_irqsave(&s->lock, flags);
+	remainder = db->count % db->dma_fragsize;
+	if (remainder) {
+		db->nextOut += remainder;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+		db->count -= remainder;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	return ret;
+}
+
+static ssize_t au1000_write(struct file *file, const char *buffer,
+	     		    size_t count, loff_t * ppos)
+{
+	struct au1000_state *s = (struct au1000_state *)file->private_data;
+	struct dmabuf  *db = &s->dma_dac;
+	ssize_t         ret = 0;
+	unsigned long   flags;
+	int             cnt, remainder, usercnt, avail;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+
+	count *= db->cnt_factor;
+
+	while (count > 0) {
+		// wait for space in playback buffer
+		do {
+			spin_lock_irqsave(&s->lock, flags);
+			avail = (int) db->dmasize - db->count;
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					return ret;
+				}
+				interruptible_sleep_on(&db->wait);
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					return ret;
+				}
+			}
+		} while (avail <= 0);
+
+		// copy to nextIn
+		if ((cnt = copy_dmabuf_user(db, (char *) buffer,
+					    count > avail ?
+					    avail : count, 0)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			return ret;
+		}
+
+		spin_lock_irqsave(&s->lock, flags);
+		db->count += cnt;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (db->stopped)
+			start_dac(s);
+
+		db->nextIn += cnt;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+
+		count -= cnt;
+		usercnt = cnt / db->cnt_factor;
+		buffer += usercnt;
+		ret += usercnt;
+	}			// while (count > 0)
+
+	/*
+	 * See if the dma buffer count after this write call is
+	 * aligned on a dma_fragsize boundary. If not, fill buffer
+	 * with silence to the next boundary, and let's hope this
+	 * is just the last remainder of an audio playback. If not
+	 * it means the user is not sending us fragsize chunks, in
+	 * which case it's his/her fault that there are audio gaps
+	 * in their playback.
+	 */
+	spin_lock_irqsave(&s->lock, flags);
+	remainder = db->count % db->dma_fragsize;
+	if (remainder) {
+		int fill_cnt = db->dma_fragsize - remainder;
+		memset(db->nextIn, 0, fill_cnt);
+		db->nextIn += fill_cnt;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+		db->count += fill_cnt;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	return ret;
+}
+
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int au1000_poll(struct file *file,
+				struct poll_table_struct *wait)
+{
+	struct au1000_state *s = (struct au1000_state *)file->private_data;
+	unsigned long   flags;
+	unsigned int    mask = 0;
+
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac.ready)
+			return 0;
+		poll_wait(file, &s->dma_dac.wait, wait);
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready)
+			return 0;
+		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+	if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if (s->dma_dac.mapped) {
+			if (s->dma_dac.count >=
+			    (signed)s->dma_dac.dma_fragsize) 
+				mask |= POLLOUT | POLLWRNORM;
+		} else {
+			if ((signed) s->dma_dac.dmasize >=
+			    s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return mask;
+}
+
+static int au1000_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct au1000_state *s = (struct au1000_state *)file->private_data;
+	struct dmabuf  *db;
+	unsigned long   size;
+
+	dbg(__FUNCTION__);
+    
+	lock_kernel();
+	if (vma->vm_flags & VM_WRITE)
+		db = &s->dma_dac;
+	else if (vma->vm_flags & VM_READ)
+		db = &s->dma_adc;
+	else {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	if (vma->vm_pgoff != 0) {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	size = vma->vm_end - vma->vm_start;
+	if (size > (PAGE_SIZE << db->buforder)) {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
+			     size, vma->vm_page_prot)) {
+		unlock_kernel();
+		return -EAGAIN;
+	}
+	db->mapped = 1;
+	unlock_kernel();
+	return 0;
+}
+
+
+#ifdef AU1000_VERBOSE_DEBUG
+static struct ioctl_str_t {
+	unsigned int    cmd;
+	const char     *str;
+} ioctl_str[] = {
+	{SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+	{SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+	{SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+	{SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+	{SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+	{SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+	{SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+	{SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+	{SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+	{SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+	{SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+	{SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+	{SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+	{SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+	{SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+	{SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+	{SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+	{SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+	{SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+	{SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+	{SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+	{SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+	{SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+	{SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+	{SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+	{SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+	{SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+	{SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+	{SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+	{OSS_GETVERSION, "OSS_GETVERSION"},
+	{SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+	{SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+	{SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+	{SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif
+
+// Need to hold a spin-lock before calling this!
+static int dma_count_done(struct dmabuf *db)
+{
+	if (db->stopped)
+		return 0;
+
+	return db->dma_fragsize - get_dma_residue(db->dmanr);
+}
+
+
+static int au1000_ioctl(struct inode *inode, struct file *file,
+                        unsigned int cmd, unsigned long arg)
+{
+	struct au1000_state *s = (struct au1000_state *)file->private_data;
+	unsigned long   flags;
+	audio_buf_info  abinfo;
+	count_info      cinfo;
+	int             count;
+	int             val, mapped, ret, diff;
+
+	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+		if (ioctl_str[count].cmd == cmd)
+			break;
+	}
+	if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
+		dbg("ioctl %s, arg=0x%x", ioctl_str[count].str, arg);
+	else
+		dbg("ioctl 0x%s unknown, arg=0x%x", cmd, arg);
+#endif
+
+	switch (cmd) {
+	case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	case SNDCTL_DSP_SYNC:
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(s, file->f_flags & O_NONBLOCK);
+		return 0;
+
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+				DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+
+	case SNDCTL_DSP_RESET:
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			synchronize_irq();
+			s->dma_dac.count = s->dma_dac.total_bytes = 0;
+			s->dma_dac.nextIn = s->dma_dac.nextOut =
+				s->dma_dac.rawbuf;
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			synchronize_irq();
+			s->dma_adc.count = s->dma_adc.total_bytes = 0;
+			s->dma_adc.nextIn = s->dma_adc.nextOut =
+				s->dma_adc.rawbuf;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val >= 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				set_adc_rate(s, val);
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				set_dac_rate(s, val);
+			}
+			if (s->open_mode & FMODE_READ)
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			if (s->open_mode & FMODE_WRITE)
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+		}
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->dma_adc.sample_rate :
+				s->dma_dac.sample_rate,
+				(int *)arg);
+
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.num_channels = val ? 2 : 1;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.num_channels = val ? 2 : 1;
+			if (s->codec_ext_caps & AC97_EXT_DACS) {
+				// disable surround and center/lfe in AC'97
+				u16 ext_stat = rdcodec(&s->codec,
+						       AC97_EXTENDED_STATUS);
+				wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+					ext_stat | (AC97_EXTSTAT_PRI |
+						    AC97_EXTSTAT_PRJ |
+						    AC97_EXTSTAT_PRK));
+			}
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 0) {
+			if (file->f_mode & FMODE_READ) {
+				if (val < 0 || val > 2)
+					return -EINVAL;
+				stop_adc(s);
+				s->dma_adc.num_channels = val;
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				switch (val) {
+				case 1:
+				case 2:
+					break;
+				case 3:
+				case 5:
+					return -EINVAL;
+				case 4:
+					if (!(s->codec_ext_caps &
+					      AC97_EXTID_SDAC))
+						return -EINVAL;
+					break;
+				case 6:
+					if ((s->codec_ext_caps &
+					     AC97_EXT_DACS) != AC97_EXT_DACS)
+						return -EINVAL;
+					break;
+				default:
+					return -EINVAL;
+				}
+
+				stop_dac(s);
+				if (val <= 2 &&
+				    (s->codec_ext_caps & AC97_EXT_DACS)) {
+					// disable surround and center/lfe
+					// channels in AC'97
+					u16             ext_stat =
+						rdcodec(&s->codec,
+							AC97_EXTENDED_STATUS);
+					wrcodec(&s->codec,
+						AC97_EXTENDED_STATUS,
+						ext_stat | (AC97_EXTSTAT_PRI |
+							    AC97_EXTSTAT_PRJ |
+							    AC97_EXTSTAT_PRK));
+				} else if (val >= 4) {
+					// enable surround, center/lfe
+					// channels in AC'97
+					u16             ext_stat =
+						rdcodec(&s->codec,
+							AC97_EXTENDED_STATUS);
+					ext_stat &= ~AC97_EXTSTAT_PRJ;
+					if (val == 6)
+						ext_stat &=
+							~(AC97_EXTSTAT_PRI |
+							  AC97_EXTSTAT_PRK);
+					wrcodec(&s->codec,
+						AC97_EXTENDED_STATUS,
+						ext_stat);
+				}
+
+				s->dma_dac.num_channels = val;
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		}
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETFMTS:	/* Returns a mask */
+		return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
+
+	case SNDCTL_DSP_SETFMT:	/* Selects ONE fmt */
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != AFMT_QUERY) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				if (val == AFMT_S16_LE)
+					s->dma_adc.sample_size = 16;
+				else {
+					val = AFMT_U8;
+					s->dma_adc.sample_size = 8;
+				}
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				if (val == AFMT_S16_LE)
+					s->dma_dac.sample_size = 16;
+				else {
+					val = AFMT_U8;
+					s->dma_dac.sample_size = 8;
+				}
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		} else {
+			if (file->f_mode & FMODE_READ)
+				val = (s->dma_adc.sample_size == 16) ?
+					AFMT_S16_LE : AFMT_U8;
+			else
+				val = (s->dma_dac.sample_size == 16) ?
+					AFMT_S16_LE : AFMT_U8;
+		}
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_POST:
+		return 0;
+
+	case SNDCTL_DSP_GETTRIGGER:
+		val = 0;
+		spin_lock_irqsave(&s->lock, flags);
+		if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
+			val |= PCM_ENABLE_INPUT;
+		if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
+			val |= PCM_ENABLE_OUTPUT;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_SETTRIGGER:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			if (val & PCM_ENABLE_INPUT)
+				start_adc(s);
+			else
+				stop_adc(s);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val & PCM_ENABLE_OUTPUT)
+				start_dac(s);
+			else
+				stop_dac(s);
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_dac.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		count -= dma_count_done(&s->dma_dac);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = (s->dma_dac.dmasize - count) /
+			s->dma_dac.cnt_factor;
+		abinfo.fragstotal = s->dma_dac.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_adc.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_adc.count;
+		count += dma_count_done(&s->dma_adc);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = count / s->dma_adc.cnt_factor;
+		abinfo.fragstotal = s->dma_adc.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		count -= dma_count_done(&s->dma_dac);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		count /= s->dma_dac.cnt_factor;
+		return put_user(count, (int *) arg);
+
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_adc.total_bytes;
+		count = s->dma_adc.count;
+		if (!s->dma_adc.stopped) {
+			diff = dma_count_done(&s->dma_adc);
+			count += diff;
+			cinfo.bytes += diff;
+			cinfo.ptr =  virt_to_phys(s->dma_adc.nextIn) + diff -
+				s->dma_adc.dmaaddr;
+		} else
+			cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
+				s->dma_adc.dmaaddr;
+		if (s->dma_adc.mapped)
+			s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_adc.fragshift;
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_dac.total_bytes;
+		count = s->dma_dac.count;
+		if (!s->dma_dac.stopped) {
+			diff = dma_count_done(&s->dma_dac);
+			count -= diff;
+			cinfo.bytes += diff;
+			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
+				s->dma_dac.dmaaddr;
+		} else
+			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
+				s->dma_dac.dmaaddr;
+		if (s->dma_dac.mapped)
+			s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_dac.fragshift;
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE)
+			return put_user(s->dma_dac.fragsize, (int *) arg);
+		else
+			return put_user(s->dma_adc.fragsize, (int *) arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.ossfragshift = val & 0xffff;
+			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_adc.ossfragshift < 4)
+				s->dma_adc.ossfragshift = 4;
+			if (s->dma_adc.ossfragshift > 15)
+				s->dma_adc.ossfragshift = 15;
+			if (s->dma_adc.ossmaxfrags < 4)
+				s->dma_adc.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.ossfragshift = val & 0xffff;
+			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_dac.ossfragshift < 4)
+				s->dma_dac.ossfragshift = 4;
+			if (s->dma_dac.ossfragshift > 15)
+				s->dma_dac.ossfragshift = 15;
+			if (s->dma_dac.ossmaxfrags < 4)
+				s->dma_dac.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+			return -EINVAL;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 1 && val != 2 && val != 4)
+			return -EINVAL;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.subdivision = val;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.subdivision = val;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SOUND_PCM_READ_RATE:
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->dma_adc.sample_rate :
+				s->dma_dac.sample_rate,
+				(int *)arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->dma_adc.num_channels, (int *)arg);
+		else
+			return put_user(s->dma_dac.num_channels, (int *)arg);
+
+	case SOUND_PCM_READ_BITS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->dma_adc.sample_size, (int *)arg);
+		else
+			return put_user(s->dma_dac.sample_size, (int *)arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
+
+	return mixdev_ioctl(&s->codec, cmd, arg);
+}
+
+
+static int  au1000_open(struct inode *inode, struct file *file)
+{
+	int             minor = MINOR(inode->i_rdev);
+	DECLARE_WAITQUEUE(wait, current);
+	struct au1000_state *s = &au1000_state;
+	int             ret;
+
+#ifdef AU1000_VERBOSE_DEBUG
+	if (file->f_flags & O_NONBLOCK)
+		dbg(__FUNCTION__ ": non-blocking");
+	else
+		dbg(__FUNCTION__ ": blocking");
+#endif
+	
+	file->private_data = s;
+	/* wait for device to become free */
+	down(&s->open_sem);
+	while (s->open_mode & file->f_mode) {
+		if (file->f_flags & O_NONBLOCK) {
+			up(&s->open_sem);
+			return -EBUSY;
+		}
+		add_wait_queue(&s->open_wait, &wait);
+		__set_current_state(TASK_INTERRUPTIBLE);
+		up(&s->open_sem);
+		schedule();
+		remove_wait_queue(&s->open_wait, &wait);
+		set_current_state(TASK_RUNNING);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		down(&s->open_sem);
+	}
+
+	stop_dac(s);
+	stop_adc(s);
+
+	if (file->f_mode & FMODE_READ) {
+		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+			s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
+		s->dma_adc.num_channels = 1;
+		s->dma_adc.sample_size = 8;
+		set_adc_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->dma_adc.sample_size = 16;
+	}
+
+	if (file->f_mode & FMODE_WRITE) {
+		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+			s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
+		s->dma_dac.num_channels = 1;
+		s->dma_dac.sample_size = 8;
+		set_dac_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->dma_dac.sample_size = 16;
+	}
+
+	if (file->f_mode & FMODE_READ) {
+		if ((ret = prog_dmabuf_adc(s)))
+			return ret;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if ((ret = prog_dmabuf_dac(s)))
+			return ret;
+	}
+
+	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+	up(&s->open_sem);
+	return 0;
+}
+
+static int au1000_release(struct inode *inode, struct file *file)
+{
+	struct au1000_state *s = (struct au1000_state *)file->private_data;
+
+	lock_kernel();
+	if (file->f_mode & FMODE_WRITE)
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+	down(&s->open_sem);
+	if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		dealloc_dmabuf(s, &s->dma_dac);
+	}
+	if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		dealloc_dmabuf(s, &s->dma_adc);
+	}
+	s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
+	up(&s->open_sem);
+	wake_up(&s->open_wait);
+	unlock_kernel();
+	return 0;
+}
+
+static /*const */ struct file_operations au1000_audio_fops = {
+	owner:		THIS_MODULE,
+	llseek:		au1000_llseek,
+	read:		au1000_read,
+	write:		au1000_write,
+	poll:		au1000_poll,
+	ioctl:		au1000_ioctl,
+	mmap:		au1000_mmap,
+	open:		au1000_open,
+	release:	au1000_release,
+};
+
+
+/* --------------------------------------------------------------------- */
+
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * for debugging purposes, we'll create a proc device that dumps the
+ * CODEC chipstate
+ */
+
+#ifdef AU1000_DEBUG
+static int proc_au1000_dump(char *buf, char **start, off_t fpos,
+			    int length, int *eof, void *data)
+{
+	struct au1000_state *s = &au1000_state;
+	int             cnt, len = 0;
+
+	/* print out header */
+	len += sprintf(buf + len, "\n\t\tAU1000 Audio Debug\n\n");
+
+	// print out digital controller state
+	len += sprintf(buf + len, "AU1000 Audio Controller registers\n");
+	len += sprintf(buf + len, "---------------------------------\n");
+	len += sprintf (buf + len, "AC97C_CONFIG = %08x\n", au_readl(AC97C_CONFIG));
+	len += sprintf (buf + len, "AC97C_STATUS = %08x\n", au_readl(AC97C_STATUS));
+	len += sprintf (buf + len, "AC97C_CNTRL  = %08x\n", au_readl(AC97C_CNTRL));
+
+	/* print out CODEC state */
+	len += sprintf(buf + len, "\nAC97 CODEC registers\n");
+	len += sprintf(buf + len, "----------------------\n");
+	for (cnt = 0; cnt <= 0x7e; cnt += 2)
+		len += sprintf(buf + len, "reg %02x = %04x\n",
+			       cnt, rdcodec(&s->codec, cnt));
+
+	if (fpos >= len) {
+		*start = buf;
+		*eof = 1;
+		return 0;
+	}
+	*start = buf + fpos;
+	if ((len -= fpos) > length)
+		return length;
+	*eof = 1;
+	return len;
+
+}
+#endif /* AU1000_DEBUG */
+
+/* --------------------------------------------------------------------- */
+
+MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
+MODULE_DESCRIPTION("Au1000 Audio Driver");
+
+/* --------------------------------------------------------------------- */
+
+static int __devinit au1000_probe(void)
+{
+	struct au1000_state *s = &au1000_state;
+	int             val;
+	char            proc_str[80];
+
+	memset(s, 0, sizeof(struct au1000_state));
+
+	init_waitqueue_head(&s->dma_adc.wait);
+	init_waitqueue_head(&s->dma_dac.wait);
+	init_waitqueue_head(&s->open_wait);
+	init_MUTEX(&s->open_sem);
+	spin_lock_init(&s->lock);
+	s->codec.private_data = s;
+	s->codec.id = 0;
+	s->codec.codec_read = rdcodec;
+	s->codec.codec_write = wrcodec;
+	s->codec.codec_wait = waitcodec;
+
+	if (!request_region(virt_to_phys((void *) AC97C_CONFIG),
+			    0x14, AU1000_MODULE_NAME)) {
+		err("AC'97 ports in use");
+		return -1;
+	}
+	// Allocate the DMA Channels
+	if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX,
+						   "audio DAC")) < 0) {
+		err("Can't get DAC DMA");
+		goto err_dma1;
+	}
+	if ((s->dma_adc.dmanr = request_au1000_dma(DMA_ID_AC97C_RX,
+						   "audio ADC")) < 0) {
+		err("Can't get ADC DMA");
+		goto err_dma2;
+	}
+
+	s->dma_dac.irq = get_dma_done_irq(s->dma_dac.dmanr);
+	s->dma_adc.irq = get_dma_done_irq(s->dma_adc.dmanr);
+
+	if (request_irq(s->dma_dac.irq, dac_dma_interrupt,
+			SA_INTERRUPT, "audio DAC", s)) {
+		err("Can't get DAC irq #%d", s->dma_dac.irq);
+		goto err_irq1;
+	}
+	if (request_irq(s->dma_adc.irq, adc_dma_interrupt,
+			SA_INTERRUPT, "audio ADC", s)) {
+		err("Can't get ADC irq #%d", s->dma_adc.irq);
+		goto err_irq2;
+	}
+
+	info("DAC: DMA%d/IRQ%d, ADC: DMA%d/IRQ%d",
+	     s->dma_dac.dmanr, s->dma_dac.irq,
+	     s->dma_adc.dmanr, s->dma_adc.irq);
+
+	/* register devices */
+
+	if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0)
+		goto err_dev1;
+	if ((s->codec.dev_mixer =
+	     register_sound_mixer(&au1000_mixer_fops, -1)) < 0)
+		goto err_dev2;
+
+#ifdef AU1000_DEBUG
+	/* intialize the debug proc device */
+	s->ps = create_proc_read_entry(AU1000_MODULE_NAME, 0, NULL,
+				       proc_au1000_dump, NULL);
+#endif /* AU1000_DEBUG */
+
+	// configure pins for AC'97
+	au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
+
+	// Assert reset for 10msec to the AC'97 controller, and enable clock
+	au_writel(AC97C_RS | AC97C_CE, AC97C_CNTRL);
+	au1000_delay(10);
+	au_writel(AC97C_CE, AC97C_CNTRL);
+	au1000_delay(10);	// wait for clock to stabilize
+
+	/* cold reset the AC'97 */
+	au_writel(AC97C_RESET, AC97C_CONFIG);
+	au1000_delay(10);
+	au_writel(0, AC97C_CONFIG);
+	/* need to delay around 500msec(bleech) to give
+	   some CODECs enough time to wakeup */
+	au1000_delay(500);
+
+	/* warm reset the AC'97 to start the bitclk */
+	au_writel(AC97C_SG | AC97C_SYNC, AC97C_CONFIG);
+	udelay(100);
+	au_writel(0, AC97C_CONFIG);
+
+	/* codec init */
+	if (!ac97_probe_codec(&s->codec))
+		goto err_dev3;
+
+	s->codec_base_caps = rdcodec(&s->codec, AC97_RESET);
+	s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID);
+	info("AC'97 Base/Extended ID = %04x/%04x",
+	     s->codec_base_caps, s->codec_ext_caps);
+
+	/*
+	 * On the Pb1000, audio playback is on the AUX_OUT
+	 * channel (which defaults to LNLVL_OUT in AC'97
+	 * rev 2.2) so make sure this channel is listed
+	 * as supported (soundcard.h calls this channel
+	 * ALTPCM). ac97_codec.c does not handle detection
+	 * of this channel correctly.
+	 */
+	s->codec.supported_mixers |= SOUND_MASK_ALTPCM;
+	/*
+	 * Now set AUX_OUT's default volume.
+	 */
+	val = 0x4343;
+	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM,
+		     (unsigned long) &val);
+	
+	if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
+		// codec does not support VRA
+		s->no_vra = 1;
+	} else if (!vra) {
+		// Boot option says disable VRA
+		u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
+		wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+			ac97_extstat & ~AC97_EXTSTAT_VRA);
+		s->no_vra = 1;
+	}
+	if (s->no_vra)
+		info("no VRA, interpolating and decimating");
+
+	/* set mic to be the recording source */
+	val = SOUND_MASK_MIC;
+	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
+		     (unsigned long) &val);
+
+#ifdef AU1000_DEBUG
+	sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME,
+		s->codec.id);
+	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+					     ac97_read_proc, &s->codec);
+#endif
+
+	return 0;
+
+ err_dev3:
+	unregister_sound_mixer(s->codec.dev_mixer);
+ err_dev2:
+	unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+	free_au1000_dma(s->dma_adc.dmanr);
+ err_dma2:
+	free_au1000_dma(s->dma_dac.dmanr);
+ err_dma1:
+	free_irq(s->dma_adc.irq, s);
+ err_irq2:
+	free_irq(s->dma_dac.irq, s);
+ err_irq1:
+	release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14);
+	return -1;
+}
+
+static void __devinit au1000_remove(void)
+{
+	struct au1000_state *s = &au1000_state;
+
+	if (!s)
+		return;
+#ifdef AU1000_DEBUG
+	if (s->ps)
+		remove_proc_entry(AU1000_MODULE_NAME, NULL);
+#endif /* AU1000_DEBUG */
+	synchronize_irq();
+	free_irq(s->dma_adc.irq, s);
+	free_irq(s->dma_dac.irq, s);
+	free_au1000_dma(s->dma_adc.dmanr);
+	free_au1000_dma(s->dma_dac.dmanr);
+	release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14);
+	unregister_sound_dsp(s->dev_audio);
+	unregister_sound_mixer(s->codec.dev_mixer);
+}
+
+static int __init init_au1000(void)
+{
+	info("stevel@mvista.com, built " __TIME__ " on " __DATE__);
+	return au1000_probe();
+}
+
+static void __exit cleanup_au1000(void)
+{
+	info("unloading");
+	au1000_remove();
+}
+
+module_init(init_au1000);
+module_exit(cleanup_au1000);
+
+/* --------------------------------------------------------------------- */
+
+#ifndef MODULE
+
+static int __init au1000_setup(char *options)
+{
+	char           *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	for(this_opt=strtok(options, ",");
+	    this_opt; this_opt=strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "vra", 3)) {
+			vra = 1;
+		}
+	}
+
+	return 1;
+}
+
+__setup("au1000_audio=", au1000_setup);
+
+#endif /* MODULE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/btaudio.c linux/drivers/sound/btaudio.c
--- linux.orig/drivers/sound/btaudio.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sound/btaudio.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,7 +1,7 @@
 /*
     btaudio - bt878 audio dma driver for linux 2.4.x
 
-    (c) 2000 Gerd Knorr <kraxel@bytesex.org>
+    (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org>
 
     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
@@ -33,6 +33,7 @@
 #include <linux/sound.h>
 #include <linux/soundcard.h>
 #include <linux/slab.h>
+#include <linux/kdev_t.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -300,7 +301,7 @@
 
 static int btaudio_mixer_open(struct inode *inode, struct file *file)
 {
-	int minor = MINOR(inode->i_rdev);
+	int minor = minor(inode->i_rdev);
 	struct btaudio *bta;
 
 	for (bta = btaudios; bta != NULL; bta = bta->next)
@@ -459,7 +460,7 @@
 
 static int btaudio_dsp_open_digital(struct inode *inode, struct file *file)
 {
-	int minor = MINOR(inode->i_rdev);
+	int minor = minor(inode->i_rdev);
 	struct btaudio *bta;
 
 	for (bta = btaudios; bta != NULL; bta = bta->next)
@@ -475,7 +476,7 @@
 
 static int btaudio_dsp_open_analog(struct inode *inode, struct file *file)
 {
-	int minor = MINOR(inode->i_rdev);
+	int minor = minor(inode->i_rdev);
 	struct btaudio *bta;
 
 	for (bta = btaudios; bta != NULL; bta = bta->next)
@@ -682,7 +683,7 @@
 		return put_user((bta->channels)-1, (int *)arg);
 
         case SNDCTL_DSP_CHANNELS:
-		if (!analog) {
+		if (!bta->analog) {
 			if (get_user(val, (int*)arg))
 				return -EFAULT;
 			bta->channels    = (val > 1) ? 2 : 1;
@@ -697,7 +698,7 @@
 		return put_user(bta->channels, (int *)arg);
 		
         case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-		if (analog)
+		if (bta->analog)
 			return put_user(AFMT_S16_LE|AFMT_S8, (int*)arg);
 		else
 			return put_user(AFMT_S16_LE, (int*)arg);
@@ -706,7 +707,7 @@
 		if (get_user(val, (int*)arg))
 			return -EFAULT;
                 if (val != AFMT_QUERY) {
-			if (analog)
+			if (bta->analog)
 				bta->bits = (val == AFMT_S8) ? 8 : 16;
 			else
 				bta->bits = 16;
@@ -783,7 +784,7 @@
 
 	poll_wait(file, &bta->readq, wait);
 
-	if (0 == bta->read_count)
+	if (0 != bta->read_count)
 		mask |= (POLLIN | POLLRDNORM);
 
 	return mask;
@@ -886,10 +887,8 @@
 
 	bta = kmalloc(sizeof(*bta),GFP_ATOMIC);
 	if (!bta) {
-		printk(KERN_WARNING 
-		       "btaudio: not enough memory\n");
 		rc = -ENOMEM;
-		goto fail1;
+		goto fail0;
 	}
 	memset(bta,0,sizeof(*bta));
 
@@ -942,6 +941,8 @@
 			       "btaudio: can't register digital dsp (rc=%d)\n",rc);
 			goto fail2;
 		}
+		printk(KERN_INFO "btaudio: registered device dsp%d [digital]\n",
+		       bta->dsp_digital >> 4);
 	}
 	if (analog) {
 		rc = bta->dsp_analog =
@@ -951,16 +952,17 @@
 			       "btaudio: can't register analog dsp (rc=%d)\n",rc);
 			goto fail3;
 		}
+		printk(KERN_INFO "btaudio: registered device dsp%d [analog]\n",
+		       bta->dsp_analog >> 4);
 		rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops,mixer);
 		if (rc < 0) {
 			printk(KERN_WARNING
 			       "btaudio: can't register mixer (rc=%d)\n",rc);
 			goto fail4;
 		}
+		printk(KERN_INFO "btaudio: registered device mixer%d\n",
+		       bta->mixer_dev >> 4);
 	}
-	if (debug)
-		printk(KERN_DEBUG "btaudio: minors: digital=%d, analog=%d, mixer=%d\n",
-		       bta->dsp_digital, bta->dsp_analog, bta->mixer_dev);
 
 	/* hook into linked list */
 	bta->next = btaudios;
@@ -977,9 +979,10 @@
  fail2:
         free_irq(bta->irq,bta);	
  fail1:
+	kfree(bta);
+ fail0:
 	release_mem_region(pci_resource_start(pci_dev,0),
 			   pci_resource_len(pci_dev,0));
-	kfree(bta);
 	return rc;
 }
 
@@ -1039,16 +1042,16 @@
         remove:   __devexit_p(btaudio_remove),
 };
 
-int btaudio_init_module(void)
+static int btaudio_init_module(void)
 {
 	printk(KERN_INFO "btaudio: driver version 0.6 loaded [%s%s%s]\n",
-	       analog ? "analog" : "",
+	       digital ? "digital" : "",
 	       analog && digital ? "+" : "",
-	       digital ? "digital" : "");
+	       analog ? "analog" : "");
 	return pci_module_init(&btaudio_pci_driver);
 }
 
-void btaudio_cleanup_module(void)
+static void btaudio_cleanup_module(void)
 {
 	pci_unregister_driver(&btaudio_pci_driver);
 	return;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- linux.orig/drivers/sound/cmpci.c	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/sound/cmpci.c	2002-07-20 01:08:21.000000000 +0000
@@ -2032,7 +2032,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo))  ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -2049,7 +2049,7 @@
 				s->dma_adc.count &= s->dma_adc.fragsize-1;
 		}
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/cs4232.c linux/drivers/sound/cs4232.c
--- linux.orig/drivers/sound/cs4232.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sound/cs4232.c	2002-07-20 01:08:23.000000000 +0000
@@ -34,6 +34,8 @@
  * anyway.
  *
  * Changes
+ *      John Rood               Added Bose Sound System Support.
+ *      Toshio Spoor
  *	Alan Cox		Modularisation, Basic cleanups.
  *      Paul Barton-Davis	Separated MPU configuration, added
  *                                       Tropez+ (WaveFront) support
@@ -58,6 +60,10 @@
 
 #define KEY_PORT	0x279	/* Same as LPT1 status port */
 #define CSN_NUM		0x99	/* Just a random number */
+#define INDEX_ADDRESS   0x00    /* (R0) Index Address Register */
+#define INDEX_DATA      0x01    /* (R1) Indexed Data Register */
+#define PIN_CONTROL     0x0a    /* (I10) Pin Control */
+#define ENABLE_PINS     0xc0    /* XCTRL0/XCTRL1 enable */
 
 static void CS_OUT(unsigned char a)
 {
@@ -67,6 +73,7 @@
 #define CS_OUT2(a, b)		{CS_OUT(a);CS_OUT(b);}
 #define CS_OUT3(a, b, c)	{CS_OUT(a);CS_OUT(b);CS_OUT(c);}
 
+static int __initdata bss       = 0;
 static int mpu_base = 0, mpu_irq = 0;
 static int synth_base = 0, synth_irq = 0;
 static int mpu_detected = 0;
@@ -97,6 +104,30 @@
 	schedule_timeout(howlong);
 }
 
+static void enable_xctrl(int baseio)
+{
+        unsigned char regd;
+                
+        /*
+         * Some IBM Aptiva's have the Bose Sound System. By default
+         * the Bose Amplifier is disabled. The amplifier will be 
+         * activated, by setting the XCTRL0 and XCTRL1 bits.
+         * Volume of the monitor bose speakers/woofer, can then
+         * be set by changing the PCM volume.
+         *
+         */
+                
+        printk("cs4232: enabling Bose Sound System Amplifier.\n");
+        
+        /* Switch to Pin Control Address */                   
+        regd = inb(baseio + INDEX_ADDRESS) & 0xe0;
+        outb(((unsigned char) (PIN_CONTROL | regd)), baseio + INDEX_ADDRESS );
+        
+        /* Activate the XCTRL0 and XCTRL1 Pins */
+        regd = inb(baseio + INDEX_DATA);
+        outb(((unsigned char) (ENABLE_PINS | regd)), baseio + INDEX_DATA );
+}
+
 int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured)
 {
 	int i, n;
@@ -275,6 +306,11 @@
 		}
 		hw_config->slots[1] = hw_config2.slots[1];
 	}
+	
+	if (bss)
+	{
+        	enable_xctrl(base);
+	}
 }
 
 void unload_cs4232(struct address_info *hw_config)
@@ -349,6 +385,8 @@
 MODULE_PARM_DESC(synthirq,"Maui WaveTable IRQ");
 MODULE_PARM(isapnp,"i");
 MODULE_PARM_DESC(isapnp,"Enable ISAPnP probing (default 1)");
+MODULE_PARM(bss,"i");
+MODULE_PARM_DESC(bss,"Enable Bose Sound System Support (default 0)");
 
 /*
  *	Install a CS4232 based card. Need to have ad1848 and mpu401
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/cs4281/cs4281_wrapper.h linux/drivers/sound/cs4281/cs4281_wrapper.h
--- linux.orig/drivers/sound/cs4281/cs4281_wrapper.h	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sound/cs4281/cs4281_wrapper.h	2002-07-20 01:08:25.000000000 +0000
@@ -28,7 +28,7 @@
 #define __CS4281_WRAPPER_H
 
 /* 2.4.x wrapper */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,12)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,9)
 static int cs4281_null_suspend(struct pci_dev *pcidev, u32 unused) { return 0; }
 static int cs4281_null_resume(struct pci_dev *pcidev) { return 0; }
 #else
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/cs4281/cs4281m.c linux/drivers/sound/cs4281/cs4281m.c
--- linux.orig/drivers/sound/cs4281/cs4281m.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sound/cs4281/cs4281m.c	2002-07-20 01:08:40.000000000 +0000
@@ -2628,17 +2628,6 @@
 	}
 }
 
-
-// --------------------------------------------------------------------- 
-
-static loff_t cs4281_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
-
-// --------------------------------------------------------------------- 
-
 static int cs4281_open_mixdev(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
@@ -2694,7 +2683,7 @@
 //   Mixer file operations struct.
 // ******************************************************************************************
 static /*const */ struct file_operations cs4281_mixer_fops = {
-	llseek:cs4281_llseek,
+	llseek:no_llseek,
 	ioctl:cs4281_ioctl_mixdev,
 	open:cs4281_open_mixdev,
 	release:cs4281_release_mixdev,
@@ -3587,7 +3576,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize - 1;
 		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -3611,7 +3600,7 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.fragsize - 1;
 		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -3835,7 +3824,7 @@
 //   Wave (audio) file operations struct.
 // ******************************************************************************************
 static /*const */ struct file_operations cs4281_audio_fops = {
-	llseek:cs4281_llseek,
+	llseek:no_llseek,
 	read:cs4281_read,
 	write:cs4281_write,
 	poll:cs4281_poll,
@@ -4184,7 +4173,7 @@
 //   Midi file operations struct.
 // ******************************************************************************************
 static /*const */ struct file_operations cs4281_midi_fops = {
-	llseek:cs4281_llseek,
+	llseek:no_llseek,
 	read:cs4281_midi_read,
 	write:cs4281_midi_write,
 	poll:cs4281_midi_poll,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
--- linux.orig/drivers/sound/cs46xx.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sound/cs46xx.c	2002-07-20 01:08:22.000000000 +0000
@@ -2212,7 +2212,7 @@
 	if(!state)
 		return -ENODEV;
 	if (!access_ok(VERIFY_READ, buffer, count))
-		return EFAULT;
+		return -EFAULT;
 	dmabuf = &state->dmabuf;
 
 	if (ppos != &file->f_pos)
@@ -2960,7 +2960,7 @@
 			cinfo.blocks = dmabuf->count/dmabuf->divisor >> dmabuf->fragshift;
 			cinfo.ptr = dmabuf->hwptr/dmabuf->divisor;
 			spin_unlock_irqrestore(&state->card->lock, flags);
-			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 		}
 		return -ENODEV;
 
@@ -2993,7 +2993,7 @@
 			    "cs46xx: GETOPTR bytes=%d blocks=%d ptr=%d\n",
 				cinfo.bytes,cinfo.blocks,cinfo.ptr) );
 			spin_unlock_irqrestore(&state->card->lock, flags);
-			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 		}
 		return -ENODEV;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/dmasound/dmasound.h linux/drivers/sound/dmasound/dmasound.h
--- linux.orig/drivers/sound/dmasound/dmasound.h	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sound/dmasound/dmasound.h	2002-07-20 01:08:37.000000000 +0000
@@ -252,17 +252,14 @@
 #define WAKE_UP(queue)		(wake_up_interruptible(&queue))
 
 extern struct sound_queue dmasound_write_sq;
-#ifdef HAS_RECORD
-extern struct sound_queue dmasound_read_sq;
-#endif
-
 #define write_sq	dmasound_write_sq
+
 #ifdef HAS_RECORD
+extern struct sound_queue dmasound_read_sq;
 #define read_sq		dmasound_read_sq
 #endif
 
 extern int dmasound_catchRadius;
-
 #define catchRadius	dmasound_catchRadius
 
 /* define the value to be put in the byte-swap reg in mac-io
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/dmasound/dmasound_atari.c linux/drivers/sound/dmasound/dmasound_atari.c
--- linux.orig/drivers/sound/dmasound/dmasound_atari.c	2002-02-25 19:38:04.000000000 +0000
+++ linux/drivers/sound/dmasound/dmasound_atari.c	2002-07-20 01:08:30.000000000 +0000
@@ -143,7 +143,7 @@
 static int AtaMixerIoctl(u_int cmd, u_long arg);
 static int TTMixerIoctl(u_int cmd, u_long arg);
 static int FalconMixerIoctl(u_int cmd, u_long arg);
-static void AtaWriteSqSetup(void);
+static int AtaWriteSqSetup(void);
 static int AtaSqOpen(mode_t mode);
 static int TTStateInfo(char *buffer, size_t space);
 static int FalconStateInfo(char *buffer, size_t space);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/dmasound/dmasound_awacs.c linux/drivers/sound/dmasound/dmasound_awacs.c
--- linux.orig/drivers/sound/dmasound/dmasound_awacs.c	2002-02-25 19:38:05.000000000 +0000
+++ linux/drivers/sound/dmasound/dmasound_awacs.c	2002-07-20 01:08:32.000000000 +0000
@@ -963,7 +963,9 @@
 			st_le16(&cp->res_count, 0);
 			st_le16(&cp->xfer_status, 0);
 			st_le32(&cp->phy_addr, phy);
-			st_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS);
+			st_le32(&cp->cmd_dep, virt_to_bus(&awacs_tx_cmds[(i+1)%write_sq.max_count]));
+			st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS);
+			
 			/* point at our patched up command block */
 			out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
 			/* we must re-start the controller */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/dmasound/dmasound_core.c linux/drivers/sound/dmasound/dmasound_core.c
--- linux.orig/drivers/sound/dmasound/dmasound_core.c	2002-02-25 19:38:05.000000000 +0000
+++ linux/drivers/sound/dmasound/dmasound_core.c	2002-07-20 01:08:26.000000000 +0000
@@ -195,20 +195,20 @@
      */
 
 int dmasound_catchRadius = 0;
-static unsigned int numWriteBufs = DEFAULT_N_BUFFERS;
-static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ;	/* in bytes */
-#ifdef HAS_RECORD
-static unsigned int numReadBufs = DEFAULT_N_BUFFERS;
-static unsigned int readBufSize = DEFAULT_BUFF_SIZE;	/* in bytes */
-#endif
-
 MODULE_PARM(dmasound_catchRadius, "i");
+
+static unsigned int numWriteBufs = DEFAULT_N_BUFFERS;
 MODULE_PARM(numWriteBufs, "i");
+static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ;	/* in bytes */
 MODULE_PARM(writeBufSize, "i");
+
 #ifdef HAS_RECORD
+static unsigned int numReadBufs = DEFAULT_N_BUFFERS;
 MODULE_PARM(numReadBufs, "i");
+static unsigned int readBufSize = DEFAULT_BUFF_SIZE;	/* in bytes */
 MODULE_PARM(readBufSize, "i");
 #endif
+
 MODULE_LICENSE("GPL");
 
 #ifdef MODULE
@@ -396,12 +396,9 @@
      */
 
 struct sound_queue dmasound_write_sq;
-#ifdef HAS_RECORD
-struct sound_queue dmasound_read_sq;
-#endif
-
 static void sq_reset_output(void) ;
 #ifdef HAS_RECORD
+struct sound_queue dmasound_read_sq;
 static void sq_reset_input(void) ;
 #endif
 
@@ -444,7 +441,7 @@
 
 static int sq_setup(struct sound_queue *sq)
 {
-	int (*setup_func)(void);
+	int (*setup_func)(void) = 0;
 	int hard_frame ;
 
 	if (sq->locked) { /* are we already set? - and not changeable */
@@ -548,7 +545,7 @@
 {
 	ssize_t uWritten = 0;
 	u_char *dest;
-	ssize_t uUsed, bUsed, bLeft;
+	ssize_t uUsed = 0, bUsed, bLeft;
 	unsigned long flags ;
 
 	/* ++TeSche: Is something like this necessary?
@@ -859,6 +856,13 @@
 #define read_sq_release_buffers()	sq_release_buffers(&read_sq)
 #define read_sq_open(file)	\
 	sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize )
+#else
+#define read_sq_init_waitqueue()	do {} while (0)
+#if 0 /* blocking open() */
+#define read_sq_wake_up(file)		do {} while (0)
+#endif
+#define read_sq_release_buffers()	do {} while (0)
+#define sq_reset_input()		do {} while (0)
 #endif
 
 static int sq_open(struct inode *inode, struct file *file)
@@ -981,9 +985,7 @@
 static void sq_reset(void)
 {
 	sq_reset_output() ;
-#ifdef HAS_RECORD
 	sq_reset_input() ;
-#endif
 	/* we could consider resetting the shared_resources_owner here... but I
 	   think it is probably still rather non-obvious to application writer
 	*/
@@ -1058,9 +1060,7 @@
 	/* Iain: hmm I don't understand this next comment ... */
 	/* There is probably a DOS atack here. They change the mode flag. */
 	/* XXX add check here,*/
-#ifdef HAS_RECORD
 	read_sq_wake_up(file); /* checks f_mode */
-#endif
 	write_sq_wake_up(file); /* checks f_mode */
 #endif /* blocking open() */
 
@@ -1200,10 +1200,8 @@
 		   everything - read, however, is killed imediately.
 		*/
 		result = 0 ;
-#ifdef HAS_RECORD
 		if ((file->f_mode & FMODE_READ) && dmasound.mach.record)
 			sq_reset_input() ;
-#endif
 		if (file->f_mode & FMODE_WRITE) {
 			result = sq_fsync(file, file->f_dentry);
 			sq_reset_output() ;
@@ -1252,6 +1250,8 @@
 		} else
 			return -EINVAL ;
 		break ;
+	case SOUND_PCM_READ_CHANNELS:
+		return IOCTL_OUT(arg, dmasound.soft.stereo+1);
 	case SNDCTL_DSP_SETFMT:
 		if (shared_resources_are_mine(file->f_mode) &&
 		    queues_are_quiescent()) {
@@ -1262,8 +1262,6 @@
 			result = IOCTL_OUT(arg, format);
 			if (result < 0)
 				return result;
-			if (format != data)
-				return -EINVAL;
 			return 0;
 		} else
 			return -EINVAL ;
@@ -1356,9 +1354,7 @@
 	}
 
 	write_sq_init_waitqueue();
-#ifdef HAS_RECORD
 	read_sq_init_waitqueue();
-#endif
 
 	/* These parameters will be restored for every clean open()
 	 * in the case of multiple open()s (e.g. dsp0 & dsp1) they
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/dmasound/dmasound_paula.c linux/drivers/sound/dmasound/dmasound_paula.c
--- linux.orig/drivers/sound/dmasound/dmasound_paula.c	2002-02-25 19:38:05.000000000 +0000
+++ linux/drivers/sound/dmasound/dmasound_paula.c	2002-07-20 01:08:22.000000000 +0000
@@ -122,7 +122,7 @@
 
 static void AmiMixerInit(void);
 static int AmiMixerIoctl(u_int cmd, u_long arg);
-static void AmiWriteSqSetup(void);
+static int AmiWriteSqSetup(void);
 static int AmiStateInfo(char *buffer, size_t space);
 
 
@@ -655,10 +655,11 @@
 }
 
 
-static void AmiWriteSqSetup(void)
+static int AmiWriteSqSetup(void)
 {
 	write_sq_block_size_half = write_sq.block_size>>1;
 	write_sq_block_size_quarter = write_sq_block_size_half>>1;
+	return 0;
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/dmasound/dmasound_q40.c linux/drivers/sound/dmasound/dmasound_q40.c
--- linux.orig/drivers/sound/dmasound/dmasound_q40.c	2002-02-25 19:38:05.000000000 +0000
+++ linux/drivers/sound/dmasound/dmasound_q40.c	2002-07-20 01:08:22.000000000 +0000
@@ -20,6 +20,7 @@
 #include <linux/soundcard.h>
 
 #include <asm/uaccess.h>
+#include <asm/q40ints.h>
 #include <asm/q40_master.h>
 
 #include "dmasound.h"
@@ -56,7 +57,7 @@
 /*** Mid level stuff *********************************************************/
 
 
-#if 1
+
 /* userCount, frameUsed, frameLeft == byte counts */
 static ssize_t q40_ct_law(const u_char *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
@@ -77,42 +78,8 @@
 	*frameUsed += used ;
 	return used;
 }
-#else
-static ssize_t q40_ct_law(const u_char *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8;
-	ssize_t count, used;
-	u_char *p = (u_char *) &frame[*frameUsed];
-	u_char val;
-	int stereo = sound.soft.stereo;
-
 
-	frameLeft >>= 1;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min_t(size_t, userCount, frameLeft);
-	while (count > 0) {
-		u_char data;
-		if (get_user(data, userPtr++))
-			return -EFAULT;
-		val = table[data]+128;
-		*p++ = val;
-		if (stereo) {
-			if (get_user(data, userPtr++))
-				return -EFAULT;
-			val = table[data]+128;
-		}
-		*p++ = val;
-		count--;
-	}
-	*frameUsed += used * 2;
-	return stereo? used * 2: used;
-}
-#endif
 
-#if 1
 static ssize_t q40_ct_s8(const u_char *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft)
@@ -131,40 +98,7 @@
 	*frameUsed += used;
 	return used;
 }
-#else
-static ssize_t q40_ct_s8(const u_char *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	ssize_t count, used;
-	u_char *p = (u_char *) &frame[*frameUsed];
-	u_char val;
-	int stereo = dmasound.soft.stereo;
 
-	frameLeft >>= 1;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min_t(size_t, userCount, frameLeft);
-	while (count > 0) {
-		u_char data;
-		if (get_user(data, userPtr++))
-			return -EFAULT;
-		val = data + 128;
-		*p++ = val;
-		if (stereo) {
-			if (get_user(data, userPtr++))
-				return -EFAULT;
-			val = data + 128;
-		}
-		*p++ = val;
-		count--;
-	}
-	*frameUsed += used * 2;
-	return stereo? used * 2: used;
-}
-#endif
-
-#if 1
 static ssize_t q40_ct_u8(const u_char *userPtr, size_t userCount,
 			  u_char frame[], ssize_t *frameUsed,
 			  ssize_t frameLeft)
@@ -178,40 +112,8 @@
 	*frameUsed += used;
 	return used;
 }
-#else
-static ssize_t q40_ct_u8(const u_char *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	ssize_t count, used;
-	u_char *p = (u_char *) &frame[*frameUsed];
-	u_char val;
-	int stereo = dmasound.soft.stereo;
 
 
-	frameLeft >>= 1;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min_t(size_t, userCount, frameLeft);
-	while (count > 0) {
-		u_char data;
-		if (get_user(data, userPtr++))
-			return -EFAULT;
-		val = data;
-		*p++ = val;
-		if (stereo) {
-			if (get_user(data, userPtr++))
-				return -EFAULT;
-			val = data;
-		}
-		*p++ = val;
-		count--;
-	}
-	*frameUsed += used * 2;
-	return stereo? used * 2: used;
-}
-#endif
-
 /* a bit too complicated to optimise right now ..*/
 static ssize_t q40_ctx_law(const u_char *userPtr, size_t userCount,
 			    u_char frame[], ssize_t *frameUsed,
@@ -322,6 +224,125 @@
 	return utotal;
 }
 
+/* compressing versions */
+static ssize_t q40_ctc_law(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
+{
+	unsigned char *table = (unsigned char *)
+		(dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8);
+	unsigned int data = expand_data;
+	u_char *p = (u_char *) &frame[*frameUsed];
+	int bal = expand_bal;
+	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
+	int utotal, ftotal;
+ 
+	ftotal = frameLeft;
+	utotal = userCount;
+	while (frameLeft) {
+		u_char c;
+		while(bal<0) {
+			if (userCount == 0)
+				goto lout;
+			if (!(bal<(-hSpeed))) {
+				if (get_user(c, userPtr))
+					return -EFAULT;
+				data = 0x80 + table[c];
+			}
+			userPtr++;
+			userCount--;
+			bal += hSpeed;
+		}
+		*p++ = data;
+		frameLeft--;
+		bal -= sSpeed;
+	}
+ lout:
+	expand_bal = bal;
+	expand_data = data;
+	*frameUsed += (ftotal - frameLeft);
+	utotal -= userCount;
+	return utotal;
+}
+
+
+static ssize_t q40_ctc_s8(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
+{
+	u_char *p = (u_char *) &frame[*frameUsed];
+	unsigned int data = expand_data;
+	int bal = expand_bal;
+	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
+	int utotal, ftotal;
+
+	ftotal = frameLeft;
+	utotal = userCount;
+	while (frameLeft) {
+		u_char c;
+		while (bal < 0) {
+			if (userCount == 0)
+				goto lout;
+			if (!(bal<(-hSpeed))) {
+				if (get_user(c, userPtr))
+					return -EFAULT;
+				data = c + 0x80;
+			}
+			userPtr++;
+			userCount--;
+			bal += hSpeed;
+		}
+		*p++ = data;
+		frameLeft--;
+		bal -= sSpeed;
+	}
+ lout:
+	expand_bal = bal;
+	expand_data = data;
+	*frameUsed += (ftotal - frameLeft);
+	utotal -= userCount;
+	return utotal;
+}
+
+
+static ssize_t q40_ctc_u8(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
+{
+	u_char *p = (u_char *) &frame[*frameUsed];
+	unsigned int data = expand_data;
+	int bal = expand_bal;
+	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
+	int utotal, ftotal;
+
+	ftotal = frameLeft;
+	utotal = userCount;
+	while (frameLeft) {
+		u_char c;
+		while (bal < 0) {
+			if (userCount == 0)
+				goto lout;
+			if (!(bal<(-hSpeed))) {
+				if (get_user(c, userPtr))
+					return -EFAULT;
+				data = c ;
+			}
+			userPtr++;
+			userCount--;
+			bal += hSpeed;
+		}
+		*p++ = data;
+		frameLeft--;
+		bal -= sSpeed;
+	}
+ lout:
+	expand_bal = bal;
+	expand_data = data;
+	*frameUsed += (ftotal - frameLeft) ;
+	utotal -= userCount;
+	return utotal;
+}
+
 
 static TRANS transQ40Normal = {
 	q40_ct_law, q40_ct_law, q40_ct_s8, q40_ct_u8, NULL, NULL, NULL, NULL
@@ -331,6 +352,10 @@
 	q40_ctx_law, q40_ctx_law, q40_ctx_s8, q40_ctx_u8, NULL, NULL, NULL, NULL
 };
 
+static TRANS transQ40Compressing = {
+	q40_ctc_law, q40_ctc_law, q40_ctc_s8, q40_ctc_u8, NULL, NULL, NULL, NULL
+};
+
 
 /*** Low level stuff *********************************************************/
 
@@ -378,7 +403,7 @@
 static void Q40Silence(void)
 {
         master_outb(0,SAMPLE_ENABLE_REG);
-	*DAC_LEFT=*DAC_RIGHT=0;
+	*DAC_LEFT=*DAC_RIGHT=127;
 }
 
 static char *q40_pp=NULL;
@@ -473,7 +498,7 @@
 	if (q40_sc<2)
 	      { /* there was nothing to play, disable irq */
 		master_outb(0,SAMPLE_ENABLE_REG);
-		*DAC_LEFT=*DAC_RIGHT=0;
+		*DAC_LEFT=*DAC_RIGHT=127;
 	      }
 	WAKE_UP(write_sq.action_queue);
 
@@ -506,10 +531,10 @@
 
 	Q40Silence();
 
-	if (dmasound.hard.speed > 20000) {
-		/* we would need to squeeze the sound, but we won't do that */
+	if (dmasound.hard.speed > 20200) {
+		/* squeeze the sound, we do that */
 		dmasound.hard.speed = 20000;
-		dmasound.trans_write = &transQ40Normal;
+		dmasound.trans_write = &transQ40Compressing;
 	} else if (dmasound.hard.speed > 10000) {
 		dmasound.hard.speed = 20000;
 	} else {
@@ -584,6 +609,7 @@
 	setFormat:	Q40SetFormat,
 	setVolume:	Q40SetVolume,
 	play:		Q40Play,
+ 	min_dsp_speed:	10000,
 	version:	((DMASOUND_Q40_REVISION<<8) | DMASOUND_Q40_EDITION),
 	hardware_afmts:	AFMT_U8, /* h'ware-supported formats *only* here */
         capabilities:	DSP_CAP_BATCH  /* As per SNDCTL_DSP_GETCAPS */
@@ -611,4 +637,6 @@
 
 module_init(dmasound_q40_init);
 module_exit(dmasound_q40_cleanup);
+
+MODULE_DESCRIPTION("Q40/Q60 sound driver");
 MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/audio.c linux/drivers/sound/emu10k1/audio.c
--- linux.orig/drivers/sound/emu10k1/audio.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/audio.c	2002-07-20 01:08:25.000000000 +0000
@@ -1365,6 +1365,13 @@
 
 	buffer->fragment_size = 1 << buffer->ossfragshift;
 
+	while (buffer->fragment_size * WAVEOUT_MINFRAGS > WAVEOUT_MAXBUFSIZE)
+		buffer->fragment_size >>= 1;
+
+	/* now we are sure that:
+	 (2^WAVEOUT_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEOUT_MAXBUFSIZE / WAVEOUT_MINFRAGS)
+	*/
+
 	if (!buffer->numfrags) {
 		u32 numfrags;
 
@@ -1379,19 +1386,14 @@
 		}
 	}
 
-	if (buffer->numfrags < MINFRAGS)
-		buffer->numfrags = MINFRAGS;
+	if (buffer->numfrags < WAVEOUT_MINFRAGS)
+		buffer->numfrags = WAVEOUT_MINFRAGS;
 
-	if (buffer->numfrags * buffer->fragment_size > WAVEOUT_MAXBUFSIZE) {
+	if (buffer->numfrags * buffer->fragment_size > WAVEOUT_MAXBUFSIZE)
 		buffer->numfrags = WAVEOUT_MAXBUFSIZE / buffer->fragment_size;
 
-		if (buffer->numfrags < MINFRAGS) {
-			buffer->numfrags = MINFRAGS;
-			buffer->fragment_size = WAVEOUT_MAXBUFSIZE / MINFRAGS;
-		}
-
-	} else if (buffer->numfrags * buffer->fragment_size < WAVEOUT_MINBUFSIZE)
-		buffer->numfrags = WAVEOUT_MINBUFSIZE / buffer->fragment_size;
+	if (buffer->numfrags < WAVEOUT_MINFRAGS)
+		BUG();
 
 	buffer->size = buffer->fragment_size * buffer->numfrags;
 	buffer->pages = buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
@@ -1425,24 +1427,29 @@
 
 	buffer->fragment_size = 1 << buffer->ossfragshift;
 
+	while (buffer->fragment_size * WAVEIN_MINFRAGS > WAVEIN_MAXBUFSIZE)
+		buffer->fragment_size >>= 1;
+
+	/* now we are sure that:
+	   (2^WAVEIN_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEIN_MAXBUFSIZE / WAVEIN_MINFRAGS)
+        */
+
+
 	if (!buffer->numfrags)
 		buffer->numfrags = (wiinst->format.bytespersec * WAVEIN_DEFAULTBUFLEN) / (buffer->fragment_size * 1000) - 1;
 
-	if (buffer->numfrags < MINFRAGS)
-		buffer->numfrags = MINFRAGS;
+	if (buffer->numfrags < WAVEIN_MINFRAGS)
+		buffer->numfrags = WAVEIN_MINFRAGS;
 
-	if (buffer->numfrags * buffer->fragment_size > WAVEIN_MAXBUFSIZE) {
+	if (buffer->numfrags * buffer->fragment_size > WAVEIN_MAXBUFSIZE)
 		buffer->numfrags = WAVEIN_MAXBUFSIZE / buffer->fragment_size;
 
-		if (buffer->numfrags < MINFRAGS) {
-			buffer->numfrags = MINFRAGS;
-			buffer->fragment_size = WAVEIN_MAXBUFSIZE / MINFRAGS;
-		}
-	} else if (buffer->numfrags * buffer->fragment_size < WAVEIN_MINBUFSIZE)
-		buffer->numfrags = WAVEIN_MINBUFSIZE / buffer->fragment_size;
+	if (buffer->numfrags < WAVEIN_MINFRAGS)
+		BUG();
 
 	bufsize = buffer->fragment_size * buffer->numfrags;
 
+	/* the buffer size for recording is restricted to certain values, adjust it now */
 	if (bufsize >= 0x10000) {
 		buffer->size = 0x10000;
 		buffer->sizeregval = 0x1f;
@@ -1468,10 +1475,12 @@
 		}
 	}
 
+	/* adjust the fragment size so that buffer size is an integer multiple */
+	while (buffer->size % buffer->fragment_size)
+		buffer->fragment_size >>= 1;
+
 	buffer->numfrags = buffer->size / buffer->fragment_size;
 	buffer->pages =  buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
-	if (buffer->size % buffer->fragment_size)
-		BUG();
 
 	DPD(2, " calculated recording fragment_size -> %d\n", buffer->fragment_size);
 	DPD(2, " calculated recording numfrags -> %d\n", buffer->numfrags);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/audio.h linux/drivers/sound/emu10k1/audio.h
--- linux.orig/drivers/sound/emu10k1/audio.h	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/audio.h	2002-07-20 01:08:40.000000000 +0000
@@ -33,8 +33,6 @@
 #ifndef _AUDIO_H
 #define _AUDIO_H
 
-#define MINFRAGS	3	/* _don't_ go bellow 3 */
-
 struct emu10k1_wavedevice
 {
         struct emu10k1_card *card;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/cardwi.h linux/drivers/sound/emu10k1/cardwi.h
--- linux.orig/drivers/sound/emu10k1/cardwi.h	2001-08-11 04:02:18.000000000 +0000
+++ linux/drivers/sound/emu10k1/cardwi.h	2002-07-20 01:08:40.000000000 +0000
@@ -69,13 +69,14 @@
 	u16 fxwc;
 };
 
-#define WAVEIN_MAXBUFSIZE         65536
-#define WAVEIN_MINBUFSIZE	  368
+#define WAVEIN_MAXBUFSIZE	65536
+#define WAVEIN_MINBUFSIZE	368
 
-#define WAVEIN_DEFAULTFRAGLEN     100 
-#define WAVEIN_DEFAULTBUFLEN      1000
+#define WAVEIN_DEFAULTFRAGLEN	100 
+#define WAVEIN_DEFAULTBUFLEN	1000
 
-#define WAVEIN_MINFRAGSHIFT   	  8 
+#define WAVEIN_MINFRAGSHIFT	8 
+#define WAVEIN_MINFRAGS		2
 
 int emu10k1_wavein_open(struct emu10k1_wavedevice *);
 void emu10k1_wavein_close(struct emu10k1_wavedevice *);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/cardwo.h linux/drivers/sound/emu10k1/cardwo.h
--- linux.orig/drivers/sound/emu10k1/cardwo.h	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/cardwo.h	2002-07-20 01:08:39.000000000 +0000
@@ -39,13 +39,13 @@
 
 /* setting this to other than a power of two may break some applications */
 #define WAVEOUT_MAXBUFSIZE	MAXBUFSIZE
-#define WAVEOUT_MINBUFSIZE	64
 
 #define WAVEOUT_DEFAULTFRAGLEN	20 /* Time to play a fragment in ms (latency) */
 #define WAVEOUT_DEFAULTBUFLEN	500 /* Time to play the entire buffer in ms */
 
-#define WAVEOUT_MINFRAGSHIFT	6
-#define WAVEOUT_MAXVOICES 6
+#define WAVEOUT_MINFRAGSHIFT	6 /* Minimum fragment size in bytes is 2^6 */
+#define WAVEOUT_MINFRAGS	3 /* _don't_ go bellow 3, it would break silence filling */
+#define WAVEOUT_MAXVOICES	6
 
 struct waveout_buffer {
 	u16 ossfragshift;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/efxmgr.c linux/drivers/sound/emu10k1/efxmgr.c
--- linux.orig/drivers/sound/emu10k1/efxmgr.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/efxmgr.c	2002-07-20 01:08:24.000000000 +0000
@@ -38,7 +38,7 @@
         struct dsp_patch *patch;
 	struct dsp_rpatch *rpatch;
 	char s[PATCH_NAME_SIZE + 4];
-	u32 *gpr_used;
+	unsigned long *gpr_used;
 	int i;
 
 	DPD(2, "emu10k1_find_control_gpr(): %s %s\n", patch_name, gpr_name);
@@ -103,7 +103,7 @@
 
 	card->ac97.mixer_state[oss_mixer] = (right << 8) | left;
 
-	if (!card->isaps)
+	if (!card->is_aps)
 		card->ac97.write_mixer(&card->ac97, oss_mixer, left, right);
 	
 	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left,
@@ -171,7 +171,6 @@
 {
 	struct patch_manager *mgr = &card->mgr;
 	unsigned long flags;
-	int muting;
 
 	static const s32 log2lin[4] ={           //  attenuation (dB)
 		0x7fffffff,                      //       0.0         
@@ -183,12 +182,10 @@
 	if (addr < 0)
 		return;
 
-	muting = (scale == 0x10) ? 0x7f: scale;
-	
 	vol = (100 - vol ) * scale / 100;
 
 	// Thanks to the comp.dsp newsgroup for this neat trick:
-	vol = (vol >= muting) ? 0 : (log2lin[vol & 3] >> (vol >> 2));
+	vol = (vol >= scale) ? 0 : (log2lin[vol & 3] >> (vol >> 2));
 
 	spin_lock_irqsave(&mgr->lock, flags);
 	emu10k1_set_control_gpr(card, addr, vol, 0);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/efxmgr.h linux/drivers/sound/emu10k1/efxmgr.h
--- linux.orig/drivers/sound/emu10k1/efxmgr.h	2001-10-09 17:53:18.000000000 +0000
+++ linux/drivers/sound/emu10k1/efxmgr.h	2002-07-20 01:08:35.000000000 +0000
@@ -35,9 +35,9 @@
 #define WRITE_EFX(a, b, c) sblive_writeptr((a), MICROCODEBASE + (b), 0, (c))
 
 #define OP(op, z, w, x, y) \
-        do { WRITE_EFX(card, (pc) * 2, ((x) << 10) | (y)); \
-        WRITE_EFX(card, (pc) * 2 + 1, ((op) << 20) | ((z) << 10) | (w)); \
-        ++pc; } while (0)
+	do { WRITE_EFX(card, (pc) * 2, ((x) << 10) | (y)); \
+	WRITE_EFX(card, (pc) * 2 + 1, ((op) << 20) | ((z) << 10) | (w)); \
+	++pc; } while (0)
 
 #define NUM_INPUTS 0x20
 #define NUM_OUTPUTS 0x20
@@ -47,52 +47,52 @@
 
 struct dsp_rpatch {
 	char name[PATCH_NAME_SIZE];
-        u16 code_start;
-        u16 code_size;
+	u16 code_start;
+	u16 code_size;
 
-        u32 gpr_used[NUM_GPRS / 32];
-        u32 gpr_input[NUM_GPRS / 32];
-        u32 route[NUM_OUTPUTS];
-        u32 route_v[NUM_OUTPUTS];
+	unsigned long gpr_used[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
+	unsigned long gpr_input[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
+	unsigned long route[NUM_OUTPUTS];
+	unsigned long route_v[NUM_OUTPUTS];
 };
 
 struct dsp_patch {
-        char name[PATCH_NAME_SIZE];
-        u8 id;
-        u32 input;                      /* bitmap of the lines used as inputs */
-	u32 output;                     /* bitmap of the lines used as outputs */
-        u16 code_start;
-        u16 code_size;
-
-        u32 gpr_used[NUM_GPRS / 32];    /* bitmap of used gprs */
-        u32 gpr_input[NUM_GPRS / 32];
-        u8 traml_istart;  /* starting address of the internal tram lines used */
-        u8 traml_isize;   /* number of internal tram lines used */
-
-        u8 traml_estart;
-        u8 traml_esize;
-
-        u16 tramb_istart;        /* starting address of the internal tram memory used */
-        u16 tramb_isize;         /* amount of internal memory used */
-        u32 tramb_estart;
-        u32 tramb_esize;
+	char name[PATCH_NAME_SIZE];
+	u8 id;
+	unsigned long input;	/* bitmap of the lines used as inputs */
+	unsigned long output;	/* bitmap of the lines used as outputs */
+	u16 code_start;
+	u16 code_size;
+
+	unsigned long gpr_used[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];	/* bitmap of used gprs */
+	unsigned long gpr_input[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
+	u8 traml_istart;	/* starting address of the internal tram lines used */
+	u8 traml_isize;		/* number of internal tram lines used */
+
+	u8 traml_estart;
+	u8 traml_esize;
+
+	u16 tramb_istart;        /* starting address of the internal tram memory used */
+	u16 tramb_isize;         /* amount of internal memory used */
+	u32 tramb_estart;
+	u32 tramb_esize;
 };
 
 struct dsp_gpr {
-        u8 type;                      /* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */
-        char name[GPR_NAME_SIZE];       /* gpr value, only valid for control gprs */
-        s32 min, max;         /* value range for this gpr, only valid for control gprs */
-        u8 line;                    /* which input/output line is the gpr attached, only valid for input/output gprs */
-        u8 usage;
+	u8 type;			/* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */
+	char name[GPR_NAME_SIZE];	/* gpr value, only valid for control gprs */
+	s32 min, max;			/* value range for this gpr, only valid for control gprs */
+	u8 line;			/* which input/output line is the gpr attached, only valid for input/output gprs */
+	u8 usage;
 };
 
 enum {
-        GPR_TYPE_NULL = 0,
-        GPR_TYPE_IO,
-        GPR_TYPE_STATIC,
-        GPR_TYPE_DYNAMIC,
-        GPR_TYPE_CONTROL,
-        GPR_TYPE_CONSTANT
+	GPR_TYPE_NULL = 0,
+	GPR_TYPE_IO,
+	GPR_TYPE_STATIC,
+	GPR_TYPE_DYNAMIC,
+	GPR_TYPE_CONTROL,
+	GPR_TYPE_CONSTANT
 };
 
 #define GPR_BASE 0x100
@@ -101,15 +101,14 @@
 #define MAX_PATCHES_PAGES 32
 
 struct patch_manager {
-        void *patch[MAX_PATCHES_PAGES];
+	void *patch[MAX_PATCHES_PAGES];
 	int current_pages;
-        struct dsp_rpatch rpatch;
-        struct dsp_gpr gpr[NUM_GPRS];   /* gpr usage table */
+	struct dsp_rpatch rpatch;
+	struct dsp_gpr gpr[NUM_GPRS];   /* gpr usage table */
 	spinlock_t lock;
 	s16 ctrl_gpr[SOUND_MIXER_NRDEVICES][2];
 };
 
-
 #define PATCHES_PER_PAGE (PAGE_SIZE / sizeof(struct dsp_patch))
 
 #define PATCH(mgr, i) ((struct dsp_patch *) (mgr)->patch[(i) / PATCHES_PER_PAGE] + (i) % PATCHES_PER_PAGE)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/hwaccess.h linux/drivers/sound/emu10k1/hwaccess.h
--- linux.orig/drivers/sound/emu10k1/hwaccess.h	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/hwaccess.h	2002-07-20 01:08:33.000000000 +0000
@@ -182,7 +182,7 @@
 
 	u8 chiprev;                    /* Chip revision                */
 
-	int isaps;
+	u8 is_aps;
 
 	struct patch_manager mgr;
 	struct pt_data pt;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/main.c linux/drivers/sound/emu10k1/main.c
--- linux.orig/drivers/sound/emu10k1/main.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/main.c	2002-07-20 01:08:34.000000000 +0000
@@ -78,7 +78,9 @@
  *          Cleaned up poll() functions (audio and midi). Don't start input.
  *	    Restrict DMA pages used to 512Mib range.
  *	    New AC97_BOOST mixer ioctl.
- *
+ *     0.19 Real fix for kernel with highmem support (cast dma_handle to u32)
+ *	    Fix recording buffering parameters calculation
+ *	    Use unsigned long for variables in bit ops.
  *********************************************************************/
 
 /* These are only included once per module */
@@ -111,7 +113,7 @@
 #define SNDCARD_EMU10K1 46
 #endif
  
-#define DRIVER_VERSION "0.18"
+#define DRIVER_VERSION "0.19"
 
 /* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */
 #define EMU10K1_DMA_MASK                0x1fffffff	/* DMA buffer mask for pci_alloc_consist */
@@ -196,7 +198,7 @@
 
 	/* Assign default recording parameters */
 	/* FIXME */
-	if(card->isaps)
+	if (card->is_aps)
 		card->wavein.recsrc = WAVERECORD_FX;
 	else
 		card->wavein.recsrc = WAVERECORD_AC97;
@@ -229,7 +231,7 @@
 
 	card->ac97.private_data = card;
 
-	if (!card->isaps) {
+	if (!card->is_aps) {
 		card->ac97.id = 0;
 		card->ac97.codec_read = emu10k1_ac97_read;
         	card->ac97.codec_write = emu10k1_ac97_write;
@@ -287,7 +289,7 @@
 {
 	char s[32];
 
-	if (!card->isaps) {
+	if (!card->is_aps) {
 		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);
 		remove_proc_entry(s, NULL);
 
@@ -867,19 +869,19 @@
 	}
 
 	for (pagecount = 0; pagecount < MAXPAGES; pagecount++)
-		((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32((card->silentpage.dma_handle * 2) | pagecount);
+		((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32(((u32) card->silentpage.dma_handle * 2) | pagecount);
 
 	/* Init page table & tank memory base register */
 	sblive_writeptr_tag(card, 0,
-			    PTB, card->virtualpagetable.dma_handle,
+			    PTB, (u32) card->virtualpagetable.dma_handle,
 			    TCB, 0,
 			    TCBS, 0,
 			    TAGLIST_END);
 
 	for (nCh = 0; nCh < NUM_G; nCh++) {
 		sblive_writeptr_tag(card, nCh,
-				    MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
-				    MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+				    MAPA, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
+				    MAPB, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
 				    TAGLIST_END);
 	}
 
@@ -1059,7 +1061,7 @@
 		card->iobase + card->length - 1, card->irq);
 
 	pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
-	card->isaps = (subsysvid == EMU_APS_SUBID);
+	card->is_aps = (subsysvid == EMU_APS_SUBID);
 
 	spin_lock_init(&card->lock);
 	init_MUTEX(&card->open_sem);
@@ -1090,7 +1092,7 @@
 		goto err_emu10k1_init;
 	}
 
-	if (card->isaps)
+	if (card->is_aps)
 		emu10k1_ecard_init(card);
 
 	list_add(&card->list, &emu10k1_devs);
@@ -1135,7 +1137,7 @@
 	pci_set_drvdata(pci_dev, NULL);
 }
 
-MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@opensource.creative.com)");
+MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@lists.sourceforge.net)");
 MODULE_DESCRIPTION("Creative EMU10K1 PCI Audio Driver v" DRIVER_VERSION "\nCopyright (C) 1999 Creative Technology Ltd.");
 MODULE_LICENSE("GPL");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/mixer.c linux/drivers/sound/emu10k1/mixer.c
--- linux.orig/drivers/sound/emu10k1/mixer.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/mixer.c	2002-07-20 01:08:27.000000000 +0000
@@ -251,7 +251,7 @@
 		case CMD_SETRECSRC:
 			switch (ctl->val[0]) {
 			case WAVERECORD_AC97:
-				if (card->isaps) {
+				if (card->is_aps) {
 					ret = -EINVAL;
 					break;
 				}
@@ -455,7 +455,7 @@
 
 			card->mgr.ctrl_gpr[id][ch] = addr;
 
-			if (card->isaps)
+			if (card->is_aps)
 				break;
 
 			if (addr >= 0) {
@@ -558,7 +558,7 @@
 
 				card->tankmem.size = size;
 
-				sblive_writeptr_tag(card, 0, TCB, card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END);
+				sblive_writeptr_tag(card, 0, TCB, (u32) card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END);
 
 				emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0);
 			}
@@ -621,7 +621,7 @@
 	unsigned int oss_mixer = _IOC_NR(cmd);
 	
 	ret = -EINVAL;
-	if (!card->isaps) {
+	if (!card->is_aps) {
 		if (cmd == SOUND_MIXER_INFO) {
 			mixer_info info;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/recmgr.c linux/drivers/sound/emu10k1/recmgr.c
--- linux.orig/drivers/sound/emu10k1/recmgr.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/recmgr.c	2002-07-20 01:08:37.000000000 +0000
@@ -130,9 +130,9 @@
 		break;
 	}
 
-	DPD(2, "bus addx: %#lx\n", (unsigned long) buffer->dma_handle);
+	DPD(2, "bus addx: %#x\n", (u32) buffer->dma_handle);
 
-	sblive_writeptr(card, buffer->addrreg, 0, buffer->dma_handle);
+	sblive_writeptr(card, buffer->addrreg, 0, (u32) buffer->dma_handle);
 
 	return;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/emu10k1/voicemgr.c linux/drivers/sound/emu10k1/voicemgr.c
--- linux.orig/drivers/sound/emu10k1/voicemgr.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/emu10k1/voicemgr.c	2002-07-20 01:08:23.000000000 +0000
@@ -43,7 +43,7 @@
 int emu10k1_voice_alloc_buffer(struct emu10k1_card *card, struct voice_mem *mem, u32 pages)
 {
 	u32 pageindex, pagecount;
-	unsigned long busaddx;
+	u32 busaddx;
 	int i;
 
 	DPD(2, "requested pages is: %d\n", pages);
@@ -66,9 +66,9 @@
 		DPD(2, "Virtual Addx: %p\n", mem->addr[pagecount]);
 
 		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
-			busaddx = mem->dma_handle[pagecount] + i * EMUPAGESIZE;
+			busaddx = (u32) mem->dma_handle[pagecount] + i * EMUPAGESIZE;
 
-			DPD(3, "Bus Addx: %#lx\n", busaddx);
+			DPD(3, "Bus Addx: %#x\n", busaddx);
 
 			pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
 
@@ -102,7 +102,7 @@
 		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
 			pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
 			((u32 *) card->virtualpagetable.addr)[pageindex] =
-				cpu_to_le32((card->silentpage.dma_handle * 2) | pageindex);
+				cpu_to_le32(((u32) card->silentpage.dma_handle * 2) | pageindex);
 		}
 	}
 
@@ -231,8 +231,8 @@
 				    Z1, 0,
 				    Z2, 0,
 				    /* Invalidate maps */
-				    MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
-				    MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+				    MAPA, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
+				    MAPB, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
 				/* modulation envelope */
 				    CVCF, 0x0000ffff,
 				    VTFT, 0x0000ffff,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/es1370.c linux/drivers/sound/es1370.c
--- linux.orig/drivers/sound/es1370.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/es1370.c	2002-07-20 01:08:36.000000000 +0000
@@ -397,7 +397,7 @@
  * so that it cannot wreak havoc. The attribute makes sure it doesn't
  * cross a page boundary and ensures dword alignment for the DMA engine
  */
-static unsigned char bugbuf[16] __attribute__ ((aligned (16)));
+static unsigned char *bugbuf;  // [16] __attribute__ ((aligned (16)));
 
 /* --------------------------------------------------------------------- */
 
@@ -1638,7 +1638,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1656,7 +1656,7 @@
 		if (s->dma_dac2.mapped)
 			s->dma_dac2.count &= s->dma_dac2.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -2115,7 +2115,7 @@
 		if (s->dma_dac1.mapped)
 			s->dma_dac1.count &= s->dma_dac1.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if ((val = prog_dmabuf_dac1(s)))
@@ -2564,6 +2564,11 @@
 	mm_segment_t fs;
 	int i, val, ret;
 
+	if (bugbuf == NULL)
+		bugbuf = kmalloc(16, GFP_KERNEL);
+	if (bugbuf == NULL)
+		return -ENOMEM;
+	
 	if ((ret=pci_enable_device(pcidev)))
 		return ret;
 
@@ -2747,6 +2752,8 @@
 {
 	printk(KERN_INFO "es1370: unloading\n");
 	pci_unregister_driver(&es1370_driver);
+	if(bugbuf)
+		kfree(bugbuf);
 }
 
 module_init(init_es1370);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/es1371.c linux/drivers/sound/es1371.c
--- linux.orig/drivers/sound/es1371.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/es1371.c	2002-07-20 01:08:28.000000000 +0000
@@ -1824,7 +1824,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1842,7 +1842,7 @@
 		if (s->dma_dac2.mapped)
 			s->dma_dac2.count &= s->dma_dac2.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -2292,7 +2292,7 @@
 		if (s->dma_dac1.mapped)
 			s->dma_dac1.count &= s->dma_dac1.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if ((val = prog_dmabuf_dac1(s)))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c
--- linux.orig/drivers/sound/esssolo1.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/esssolo1.c	2002-07-20 01:08:26.000000000 +0000
@@ -1468,7 +1468,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1492,7 +1492,7 @@
 		       cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift,
 		       s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples);
 #endif
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/hal2.c linux/drivers/sound/hal2.c
--- linux.orig/drivers/sound/hal2.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/sound/hal2.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,1497 @@
+/*
+ *  Driver for HAL2 sound processors
+ *  Copyright (c) 2001, 2002 Ladislav Michl <ladis@psi.cz>
+ *  
+ *  Based on Ulf Carlsson's code.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Supported devices:
+ *  /dev/dsp    standard dsp device, (mostly) OSS compatible
+ *  /dev/mixer	standard mixer device, (mostly) OSS compatible
+ *
+ *  BUGS:
+ *  + Driver currently supports indigo mode only.
+ *  + Recording doesn't work. I guess that it is caused by PBUS channel
+ *    misconfiguration, but until I get relevant info I'm unable to fix it.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/sound.h>
+#include <linux/soundcard.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/sgi/sgint23.h>
+
+#include "hal2.h"
+
+#if 0
+#define DEBUG(args...)		printk(args)
+#else
+#define DEBUG(args...)
+#endif
+
+#if 0 
+#define DEBUG_MIX(args...)	printk(args)
+#else
+#define DEBUG_MIX(args...)
+#endif
+
+#define H2_INDIRECT_WAIT(regs)	while (regs->isr & H2_ISR_TSTATUS);
+
+#define H2_READ_ADDR(addr)	(addr | (1<<7))
+#define H2_WRITE_ADDR(addr)	(addr)
+
+static char *hal2str = "HAL2 audio";
+static int ibuffers = 32;
+static int obuffers = 32;
+
+/* I doubt anyone has a machine with two HAL2 cards. It's possible to
+ * have two HPC's, so it is probably possible to have two HAL2 cards.
+ * Try to deal with it, but note that it is not tested.
+ */
+#define MAXCARDS	2
+static hal2_card_t* hal2_card[MAXCARDS];
+
+static const struct {
+	unsigned char idx:4, avail:1;
+} mixtable[SOUND_MIXER_NRDEVICES] = {
+	[SOUND_MIXER_PCM] = { H2_MIX_OUTPUT_ATT, 1 },	/* voice */
+	[SOUND_MIXER_MIC] = { H2_MIX_INPUT_GAIN, 1 },	/* mic */
+};
+
+#define H2_SUPPORTED_FORMATS	(AFMT_S16_LE | AFMT_S16_BE)
+
+static inline void hal2_isr_write(hal2_card_t *hal2, u32 val)
+{
+	hal2->ctl_regs->isr = val;
+}
+
+static inline u32 hal2_isr_look(hal2_card_t *hal2)
+{
+	return hal2->ctl_regs->isr;
+}
+
+static inline u32 hal2_rev_look(hal2_card_t *hal2)
+{
+	return hal2->ctl_regs->rev;
+}
+
+#if 0
+static u16 hal2_i_look16(hal2_card_t *hal2, u32 addr)
+{
+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
+
+	regs->iar = H2_READ_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+	return (regs->idr0 & 0xffff);
+}
+#endif
+
+static u32 hal2_i_look32(hal2_card_t *hal2, u32 addr)
+{
+	u32 ret;
+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
+
+	regs->iar = H2_READ_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+	ret = regs->idr0 & 0xffff;
+	regs->iar = H2_READ_ADDR(addr | 0x1);
+	H2_INDIRECT_WAIT(regs);
+	ret |= (regs->idr0 & 0xffff) << 16;
+	return ret;
+}
+
+static void hal2_i_write16(hal2_card_t *hal2, u32 addr, u16 val)
+{
+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
+
+	regs->idr0 = val;
+	regs->idr1 = 0;
+	regs->idr2 = 0;
+	regs->idr3 = 0;
+	regs->iar = H2_WRITE_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+}
+
+static void hal2_i_write32(hal2_card_t *hal2, u32 addr, u32 val)
+{
+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
+
+	regs->idr0 = val & 0xffff;
+	regs->idr1 = val >> 16;
+	regs->idr2 = 0;
+	regs->idr3 = 0;
+	regs->iar = H2_WRITE_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+}
+
+static void hal2_i_setbit16(hal2_card_t *hal2, u32 addr, u16 bit)
+{
+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
+
+	regs->iar = H2_READ_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+	regs->idr0 = regs->idr0 | bit;
+	regs->idr1 = 0;
+	regs->idr2 = 0;
+	regs->idr3 = 0;
+	regs->iar = H2_WRITE_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+}
+
+static void hal2_i_setbit32(hal2_card_t *hal2, u32 addr, u32 bit)
+{
+	u32 tmp;
+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
+
+	regs->iar = H2_READ_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+	tmp = regs->idr0 | (regs->idr1 << 16) | bit;
+	regs->idr0 = tmp & 0xffff;
+	regs->idr1 = tmp >> 16;
+	regs->idr2 = 0;
+	regs->idr3 = 0;
+	regs->iar = H2_WRITE_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+}
+
+static void hal2_i_clearbit16(hal2_card_t *hal2, u32 addr, u16 bit)
+{
+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
+
+	regs->iar = H2_READ_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+	regs->idr0 = regs->idr0 & ~bit;
+	regs->idr1 = 0;
+	regs->idr2 = 0;
+	regs->idr3 = 0;
+	regs->iar = H2_WRITE_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+}
+
+#if 0
+static void hal2_i_clearbit32(hal2_card_t *hal2, u32 addr, u32 bit)
+{
+	u32 tmp;
+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
+
+	regs->iar = H2_READ_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+	tmp = (regs->idr0 | (regs->idr1 << 16)) & ~bit;
+	regs->idr0 = tmp & 0xffff;
+	regs->idr1 = tmp >> 16;
+	regs->idr2 = 0;
+	regs->idr3 = 0;
+	regs->iar = H2_WRITE_ADDR(addr);
+	H2_INDIRECT_WAIT(regs);
+}
+#endif
+
+#ifdef HAL2_DEBUG
+static void hal2_dump_regs(hal2_card_t *hal2)
+{
+	printk("isr: %08hx ", hal2_isr_look(hal2));
+	printk("rev: %08hx\n", hal2_rev_look(hal2));
+	printk("relay: %04hx\n", hal2_i_look16(hal2, H2I_RELAY_C));
+	printk("port en: %04hx ", hal2_i_look16(hal2, H2I_DMA_PORT_EN));
+	printk("dma end: %04hx ", hal2_i_look16(hal2, H2I_DMA_END));
+	printk("dma drv: %04hx\n", hal2_i_look16(hal2, H2I_DMA_DRV));
+	printk("syn ctl: %04hx ", hal2_i_look16(hal2, H2I_SYNTH_C));
+	printk("aesrx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESRX_C));
+	printk("aestx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESTX_C));
+	printk("dac ctl1: %04hx ", hal2_i_look16(hal2, H2I_ADC_C1));
+	printk("dac ctl2: %08lx ", hal2_i_look32(hal2, H2I_ADC_C2));
+	printk("adc ctl1: %04hx ", hal2_i_look16(hal2, H2I_DAC_C1));
+	printk("adc ctl2: %08lx ", hal2_i_look32(hal2, H2I_DAC_C2));
+	printk("syn map: %04hx\n", hal2_i_look16(hal2, H2I_SYNTH_MAP_C));
+	printk("bres1 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES1_C1));
+	printk("bres1 ctl2: %04lx ", hal2_i_look32(hal2, H2I_BRES1_C2));
+	printk("bres2 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES2_C1));
+	printk("bres2 ctl2: %04lx ", hal2_i_look32(hal2, H2I_BRES2_C2));
+	printk("bres3 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES3_C1));
+	printk("bres3 ctl2: %04lx\n", hal2_i_look32(hal2, H2I_BRES3_C2));
+}
+#endif
+
+static hal2_card_t* hal2_dsp_find_card(int minor)
+{
+	int i;
+
+	for (i = 0; i < MAXCARDS; i++)
+		if (hal2_card[i] != NULL && hal2_card[i]->dev_dsp == minor)
+			return hal2_card[i];
+	return NULL;
+}
+
+static hal2_card_t* hal2_mixer_find_card(int minor)
+{
+	int i;
+
+	for (i = 0; i < MAXCARDS; i++)
+		if (hal2_card[i] != NULL && hal2_card[i]->dev_mixer == minor)
+			return hal2_card[i];
+	return NULL;
+}
+
+
+static void hal2_dac_interrupt(hal2_codec_t *dac)
+{
+	int running;
+
+	spin_lock(&dac->lock);
+	
+	/* if tail buffer contains zero samples DMA stream was already
+	 * stopped */
+	running = dac->tail->info.cnt;
+	dac->tail->info.cnt = 0;
+	dac->tail->info.desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX;
+	dma_cache_wback_inv((unsigned long) dac->tail,
+			    sizeof(struct hpc_dma_desc));
+	/* we just proccessed empty buffer, don't update tail pointer */
+	if (running)
+		dac->tail = dac->tail->info.next;
+
+	spin_unlock(&dac->lock);
+
+	wake_up(&dac->dma_wait);
+}
+
+static void hal2_adc_interrupt(hal2_codec_t *adc)
+{
+	int running;
+	
+	spin_lock(&adc->lock);
+
+	/* if head buffer contains nonzero samples DMA stream was already
+	 * stopped */
+	running = !adc->head->info.cnt;
+	adc->head->info.cnt = H2_BUFFER_SIZE;
+	adc->head->info.desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX;
+	dma_cache_wback_inv((unsigned long) adc->head,
+			    sizeof(struct hpc_dma_desc));
+	/* we just proccessed empty buffer, don't update head pointer */
+	if (running) {
+		dma_cache_inv((unsigned long) adc->head->data, H2_BUFFER_SIZE);
+		adc->head = adc->head->info.next;
+	}
+
+	spin_unlock(&adc->lock);
+
+	wake_up(&adc->dma_wait);
+}
+
+static void hal2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	hal2_card_t *hal2 = (hal2_card_t*)dev_id;
+
+	/* decide what caused this interrupt */
+	if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT)
+		hal2_dac_interrupt(&hal2->dac);
+	if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT)
+		hal2_adc_interrupt(&hal2->adc);
+}
+
+static int hal2_compute_rate(hal2_codec_t *codec, unsigned int rate)
+{
+	unsigned short inc;
+	
+	/* We default to 44.1 kHz and if it isn't possible to fall back to
+	 * 48.0 kHz with the needed adjustments of real_rate.
+	 */
+
+	DEBUG("rate: %d\n", rate);
+	
+	/* Refer to CS4216 data sheet */
+	if (rate < 4000)
+		rate = 4000;
+	if (rate > 50000)
+		rate = 50000;
+
+	/* Note: This is NOT the way they set up the bresenham clock generators
+	 * in the specification. I've tried to implement that method but it
+	 * doesn't work. It's probably another silly bug in the spec.
+	 *
+	 * I accidently discovered this method while I was testing and it seems
+	 * to work very well with all frequencies, and thee shall follow rule #1
+	 * of programming :-)
+	 */
+	
+	if (44100 % rate == 0) {
+		inc = 44100 / rate;
+		if (inc < 1) inc = 1;
+		codec->master = 44100;
+	} else {
+		inc = 48000 / rate;
+		if (inc < 1) inc = 1;
+		rate = 48000 / inc;
+		codec->master = 48000;
+	}
+	codec->inc = inc;
+	codec->mod = 1;
+	
+	DEBUG("real_rate: %d\n", rate);
+
+	return rate;
+}
+
+static void hal2_set_dac_rate(hal2_card_t *hal2)
+{
+	unsigned int master = hal2->dac.master;
+	int inc = hal2->dac.inc;
+	int mod = hal2->dac.mod;
+
+	DEBUG("master: %d inc: %d mod: %d\n", master, inc, mod);
+	
+	hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0);
+	hal2_i_write32(hal2, H2I_BRES1_C2, ((0xffff & (mod - inc - 1)) << 16) | 1);
+}
+
+static void hal2_set_adc_rate(hal2_card_t *hal2)
+{
+	unsigned int master = hal2->adc.master;
+	int inc = hal2->adc.inc;
+	int mod = hal2->adc.mod;
+
+	DEBUG("master: %d inc: %d mod: %d\n", master, inc, mod);
+	
+	hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0);
+	hal2_i_write32(hal2, H2I_BRES2_C2, ((0xffff & (mod - inc - 1)) << 16) | 1);
+}
+
+static void hal2_setup_dac(hal2_card_t *hal2)
+{
+	unsigned int fifobeg, fifoend, highwater, sample_size;
+	hal2_pbus_t *pbus = &hal2->dac.pbus;
+
+	DEBUG("hal2_setup_dac\n");
+	
+	/* Now we set up some PBUS information. The PBUS needs information about
+	 * what portion of the fifo it will use. If it's receiving or
+	 * transmitting, and finally whether the stream is little endian or big
+	 * endian. The information is written later, on the start call.
+	 */
+	sample_size = 2 * hal2->dac.voices;
+
+	/* Fifo should be set to hold exactly four samples. Highwater mark
+	 * should be set to two samples. */
+	highwater = (sample_size * 2) >> 1;	/* halfwords */
+	fifobeg = 0;				/* playback is first */
+	fifoend = (sample_size * 4) >> 3;	/* doublewords */
+	pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD |
+		     (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
+	/* We disable everything before we do anything at all */
+	pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
+	hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
+	hal2_i_clearbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
+	/* Setup the HAL2 for playback */
+	hal2_set_dac_rate(hal2);
+	/* We are using 1st Bresenham clock generator for playback */
+	hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
+			| (1 << H2I_C1_CLKID_SHIFT)
+			| (hal2->dac.voices << H2I_C1_DATAT_SHIFT));
+}
+
+static void hal2_setup_adc(hal2_card_t *hal2)
+{
+	unsigned int fifobeg, fifoend, highwater, sample_size;
+	hal2_pbus_t *pbus = &hal2->adc.pbus;
+
+	DEBUG("hal2_setup_adc\n");
+	
+	sample_size = 2 * hal2->adc.voices;
+
+	highwater = (sample_size * 2) >> 1;		/* halfwords */
+	fifobeg = (4 * 4) >> 3;				/* record is second */
+	fifoend = (4 * 4 + sample_size * 4) >> 3;	/* doublewords */
+	pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD | 
+		     (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
+	pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
+	hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
+	hal2_i_clearbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
+	/* Setup the HAL2 for record */
+	hal2_set_adc_rate(hal2);
+	/* We are using 2nd Bresenham clock generator for record */
+	hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
+			| (2 << H2I_C1_CLKID_SHIFT)
+			| (hal2->adc.voices << H2I_C1_DATAT_SHIFT));
+}
+
+static void hal2_start_dac(hal2_card_t *hal2)
+{
+	hal2_pbus_t *pbus = &hal2->dac.pbus;
+
+	DEBUG("hal2_start_dac\n");
+	
+	pbus->pbus->pbdma_dptr = PHYSADDR(hal2->dac.tail);
+	pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
+
+	/* set endianess */
+	if (hal2->dac.format & AFMT_S16_LE)
+		hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
+	else
+		hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
+	/* set DMA bus */
+	hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
+	/* enable DAC */
+	hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
+}
+
+static void hal2_start_adc(hal2_card_t *hal2)
+{
+	hal2_pbus_t *pbus = &hal2->adc.pbus;
+
+	DEBUG("hal2_start_adc\n");
+	
+	pbus->pbus->pbdma_dptr = PHYSADDR(hal2->adc.head);
+	pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
+	
+	/* set endianess */
+	if (hal2->adc.format & AFMT_S16_LE)
+		hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
+	else
+		hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
+	/* set DMA bus */
+	hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
+	/* enable ADC */
+	hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
+}
+
+static inline void hal2_stop_dac(hal2_card_t *hal2)
+{
+	DEBUG("hal2_stop_dac\n");
+	
+	hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
+	/* The HAL2 itself may remain enabled safely */
+}
+
+static inline void hal2_stop_adc(hal2_card_t *hal2)
+{
+	DEBUG("hal2_stop_adc\n");
+	
+	hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
+}
+
+#define hal2_alloc_dac_dmabuf(hal2)	hal2_alloc_dmabuf(hal2, 1)
+#define hal2_alloc_adc_dmabuf(hal2)	hal2_alloc_dmabuf(hal2, 0)
+static int hal2_alloc_dmabuf(hal2_card_t *hal2, int is_dac)
+{
+	int buffers, cntinfo;
+	hal2_buf_t *buf, *prev;
+	hal2_codec_t *codec;
+
+	if (is_dac) {
+		codec = &hal2->dac;
+		buffers = obuffers;
+		cntinfo = HPCDMA_XIE | HPCDMA_EOX;
+	} else {
+		codec = &hal2->adc;
+		buffers = ibuffers;
+		cntinfo = HPCDMA_XIE | H2_BUFFER_SIZE;
+	}
+	
+	DEBUG("allocating %d DMA buffers.\n", buffers);
+	
+	buf = (hal2_buf_t*) get_zeroed_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	codec->head = buf;
+	codec->tail = buf;
+	
+	while (--buffers) {
+		buf->info.desc.pbuf = PHYSADDR(&buf->data);
+		buf->info.desc.cntinfo = cntinfo;
+		buf->info.cnt = 0;
+		prev = buf;
+		buf = (hal2_buf_t*) get_zeroed_page(GFP_KERNEL);
+		if (!buf) {
+			printk("HAL2: Not enough memory for DMA buffer.\n");
+			buf = codec->head;
+			while (buf) {
+				prev = buf;
+				free_page((unsigned long) buf);
+				buf = prev->info.next;
+			}
+			return -ENOMEM;
+		}
+		prev->info.next = buf;
+		prev->info.desc.pnext = PHYSADDR(buf);
+		/* The PBUS can prolly not read this stuff when it's in
+		 * the cache so we have to flush it back to main memory
+		 */
+		dma_cache_wback_inv((unsigned long) prev, PAGE_SIZE);
+	}
+	buf->info.desc.pbuf = PHYSADDR(&buf->data);
+	buf->info.desc.cntinfo = cntinfo;
+	buf->info.cnt = 0;
+	buf->info.next = codec->head;
+	buf->info.desc.pnext = PHYSADDR(codec->head);
+	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
+	
+	return 0;
+}
+
+#define hal2_free_dac_dmabuf(hal2)	hal2_free_dmabuf(hal2, 1)
+#define hal2_free_adc_dmabuf(hal2)	hal2_free_dmabuf(hal2, 0)
+static void hal2_free_dmabuf(hal2_card_t *hal2, int is_dac)
+{
+	hal2_buf_t *buf, *next;
+	hal2_codec_t *codec = (is_dac) ? &hal2->dac : &hal2->adc;
+
+	if (!codec->head)
+		return;
+	
+	buf = codec->head->info.next;
+	codec->head->info.next = NULL;
+	while (buf) {
+		next = buf->info.next;
+		free_page((unsigned long) buf);
+		buf = next;
+	}
+	codec->head = codec->tail = NULL;
+}
+
+/* 
+ * Add 'count' bytes to 'buffer' from DMA ring buffers. Return number of
+ * bytes added or -EFAULT if copy_from_user failed.
+ */
+static int hal2_get_buffer(hal2_card_t *hal2, char *buffer, int count)
+{
+	unsigned long flags;
+	int size, ret = 0;
+	hal2_codec_t *adc = &hal2->adc;
+	
+	spin_lock_irqsave(&adc->lock, flags);
+	
+	DEBUG("getting %d bytes ", count);
+
+	/* enable DMA stream if there are no data */
+	if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) &&
+	    adc->tail->info.cnt == 0)
+		hal2_start_adc(hal2);
+
+	DEBUG("... ");
+
+	while (adc->tail->info.cnt > 0 && count > 0) {
+		size = min(adc->tail->info.cnt, count);
+		spin_unlock_irqrestore(&adc->lock, flags);
+
+		if (copy_to_user(buffer, &adc->tail->data[H2_BUFFER_SIZE-size],
+				 size)) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		spin_lock_irqsave(&adc->lock, flags);
+		
+		adc->tail->info.cnt -= size;
+		/* buffer is empty, update tail pointer */
+		if (adc->tail->info.cnt == 0) {
+			adc->tail->info.desc.cntinfo = HPCDMA_XIE |
+						       H2_BUFFER_SIZE;
+			dma_cache_wback_inv((unsigned long) adc->tail,
+					    sizeof(struct hpc_dma_desc));
+			adc->tail = adc->tail->info.next;
+			/* enable DMA stream again if needed */
+			if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT))
+				hal2_start_adc(hal2);
+
+		}
+		buffer += size;
+		ret += size;
+		count -= size;
+
+		DEBUG("(%d) ", size);
+	}
+	spin_unlock_irqrestore(&adc->lock, flags);
+out:	
+	DEBUG("\n");
+	
+	return ret;
+} 
+
+/* 
+ * Add 'count' bytes from 'buffer' to DMA ring buffers. Return number of
+ * bytes added or -EFAULT if copy_from_user failed.
+ */
+static int hal2_add_buffer(hal2_card_t *hal2, char *buffer, int count)
+{
+	unsigned long flags;
+	int size, ret = 0;
+	hal2_codec_t *dac = &hal2->dac;
+	
+	spin_lock_irqsave(&dac->lock, flags);
+	
+	DEBUG("adding %d bytes ", count);
+
+	while (dac->head->info.cnt == 0 && count > 0) {
+		size = min((int)H2_BUFFER_SIZE, count);
+		spin_unlock_irqrestore(&dac->lock, flags);
+		
+		if (copy_from_user(dac->head->data, buffer, size)) {
+			ret = -EFAULT;
+			goto out;
+		}
+		spin_lock_irqsave(&dac->lock, flags);
+
+		dac->head->info.desc.cntinfo = size | HPCDMA_XIE;
+		dac->head->info.cnt = size;
+		dma_cache_wback_inv((unsigned long) dac->head, 
+				    size + PAGE_SIZE - H2_BUFFER_SIZE);
+		buffer += size;
+		ret += size;
+		count -= size;
+		dac->head = dac->head->info.next;
+
+		DEBUG("(%d) ", size);
+	}
+	if (!(dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) && ret > 0)
+		hal2_start_dac(hal2);
+	
+	spin_unlock_irqrestore(&dac->lock, flags);
+out:	
+	DEBUG("\n");
+	
+	return ret;
+}
+
+#define hal2_reset_dac_pointer(hal2)	hal2_reset_pointer(hal2, 1)
+#define hal2_reset_adc_pointer(hal2)	hal2_reset_pointer(hal2, 0)
+static void hal2_reset_pointer(hal2_card_t *hal2, int is_dac)
+{
+	hal2_codec_t *codec = (is_dac) ? &hal2->dac : &hal2->adc;
+	
+	DEBUG("hal2_reset_pointer\n");
+
+	codec->tail = codec->head;
+	do {
+		codec->tail->info.desc.cntinfo = HPCDMA_XIE | (is_dac) ? 
+						 HPCDMA_EOX : H2_BUFFER_SIZE;
+		codec->tail->info.cnt = 0;
+		dma_cache_wback_inv((unsigned long) codec->tail, 
+				    sizeof(struct hpc_dma_desc));
+		codec->tail = codec->tail->info.next;
+	} while (codec->tail != codec->head);
+}
+
+static int hal2_sync_dac(hal2_card_t *hal2)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	hal2_codec_t *dac = &hal2->dac;
+	int ret = 0;
+	signed long timeout = 1000 * H2_BUFFER_SIZE * 2 * dac->voices *
+			      HZ / dac->sample_rate / 900;
+
+	down(&dac->sem);
+	
+	while (dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) {
+		add_wait_queue(&dac->dma_wait, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (!schedule_timeout(timeout))
+			/* We may get bogus timeout when system is 
+			 * heavily loaded */
+			if (dac->tail->info.cnt) {
+				printk("HAL2: timeout...\n");
+				ret = -ETIME;
+			}
+		if (signal_pending(current))
+			ret = -ERESTARTSYS;
+		if (ret) {
+			hal2_stop_dac(hal2);
+			hal2_reset_dac_pointer(hal2);
+		}
+		remove_wait_queue(&dac->dma_wait, &wait);
+	}
+
+	up(&dac->sem);
+	
+	return ret;
+}
+
+static int hal2_write_mixer(hal2_card_t *hal2, int index, int vol)
+{
+	unsigned int l, r;
+
+	DEBUG_MIX("mixer %d write\n", index);
+	
+	if (index >= SOUND_MIXER_NRDEVICES || !mixtable[index].avail)
+		return -EINVAL;
+
+	r = (vol >> 8) & 0xff;
+	if (r > 100)
+		r = 100;
+	l = vol & 0xff;
+	if (l > 100)
+		l = 100;
+	
+	hal2->mixer.volume[mixtable[index].idx] = l | (r << 8);
+
+	switch (mixtable[index].idx) {
+	case H2_MIX_OUTPUT_ATT: {
+
+		DEBUG_MIX("output attenuator %d,%d\n", l, r);
+
+		if (r | l) {
+			unsigned int tmp = hal2_i_look32(hal2, H2I_DAC_C2); 
+		
+			tmp &= ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
+
+			/* Attenuator has five bits */
+			l = (31 * (100 - l) / 99);
+			r = (31 * (100 - r) / 99);
+			
+			DEBUG_MIX("left: %d, right %d\n", l, r);
+
+			tmp |= (l << H2I_C2_L_ATT_SHIFT) & H2I_C2_L_ATT_M;
+			tmp |= (r << H2I_C2_R_ATT_SHIFT) & H2I_C2_R_ATT_M;
+			hal2_i_write32(hal2, H2I_DAC_C2, tmp);
+		} else 
+			hal2_i_setbit32(hal2, H2I_DAC_C2, H2I_C2_MUTE);
+	}
+	case H2_MIX_INPUT_GAIN: {
+		/* TODO */
+	}
+	}
+	return 0;
+}
+
+static void hal2_init_mixer(hal2_card_t *hal2)
+{
+	int i;
+
+	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+		hal2_write_mixer(hal2, i, 100 | (100 << 8));
+		
+}
+
+static int hal2_mixer_ioctl(hal2_card_t *hal2, unsigned int cmd, 
+			    unsigned long arg)
+{
+	int val;
+
+        if (cmd == SOUND_MIXER_INFO) {
+		mixer_info info;
+		
+		strncpy(info.id, hal2str, sizeof(info.id));
+		strncpy(info.name, hal2str, sizeof(info.name));
+		info.modify_counter = hal2->mixer.modcnt;
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == SOUND_OLD_MIXER_INFO) {
+		_old_mixer_info info;
+		
+		strncpy(info.id, hal2str, sizeof(info.id));
+		strncpy(info.name, hal2str, sizeof(info.name));
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == OSS_GETVERSION)
+		return put_user(SOUND_VERSION, (int *)arg);
+
+	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
+                return -EINVAL;
+
+        if (_IOC_DIR(cmd) == _IOC_READ) {
+                switch (_IOC_NR(cmd)) {
+		/* Give the current record source */
+		case SOUND_MIXER_RECSRC:
+			val = 0;	/* FIXME */
+			break;
+		/* Give the supported mixers, all of them support stereo */
+                case SOUND_MIXER_DEVMASK:
+                case SOUND_MIXER_STEREODEVS: {
+			int i;
+			
+			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+				if (mixtable[i].avail)
+					val |= 1 << i;
+			break;
+			}
+		/* Arg contains a bit for each supported recording source */
+                case SOUND_MIXER_RECMASK:
+			val = 0;
+			break;
+                case SOUND_MIXER_CAPS:
+			val = 0;
+			break;
+		/* Read a specific mixer */
+		default: {
+			int i = _IOC_NR(cmd);
+			
+			if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
+				return -EINVAL;
+			val = hal2->mixer.volume[mixtable[i].idx];
+			break;
+			}
+		}
+		return put_user(val, (int *)arg);
+	}
+	
+        if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
+		return -EINVAL;
+	
+	hal2->mixer.modcnt++;
+
+	if (get_user(val, (int *)arg))
+		return -EFAULT;
+
+	switch (_IOC_NR(cmd)) {
+	/* Arg contains a bit for each recording source */
+	case SOUND_MIXER_RECSRC:
+		return 0;	/* FIXME */
+	default:
+		return hal2_write_mixer(hal2, _IOC_NR(cmd), val);
+	}
+
+	return 0;
+}
+
+static int hal2_open_mixdev(struct inode *inode, struct file *file)
+{
+	hal2_card_t *hal2 = hal2_mixer_find_card(MINOR(inode->i_rdev));
+
+	if (hal2) {
+		file->private_data = hal2;
+		return 0;
+	}
+	return -ENODEV;
+}
+
+static int hal2_release_mixdev(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int hal2_ioctl_mixdev(struct inode *inode, struct file *file,
+			     unsigned int cmd, unsigned long arg)
+{
+	return hal2_mixer_ioctl((hal2_card_t *)file->private_data, cmd, arg);
+}
+
+
+static int hal2_ioctl(struct inode *inode, struct file *file, 
+		      unsigned int cmd, unsigned long arg)
+{
+	int val;
+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
+
+	switch (cmd) {
+	case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *)arg);
+		
+	case SNDCTL_DSP_SYNC:
+		if (file->f_mode & FMODE_WRITE)
+			return hal2_sync_dac(hal2);
+		return 0;
+		
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_MULTI, (int *)arg);
+		
+	case SNDCTL_DSP_RESET:
+		if (file->f_mode & FMODE_READ) {
+			hal2_stop_adc(hal2);
+			hal2_reset_adc_pointer(hal2);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			hal2_stop_dac(hal2);
+			hal2_reset_dac_pointer(hal2);
+		}
+		return 0;
+
+ 	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			hal2_stop_adc(hal2);
+			val = hal2_compute_rate(&hal2->adc, val);
+			hal2->adc.sample_rate = val;
+			hal2_set_adc_rate(hal2);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			hal2_stop_dac(hal2);
+			val = hal2_compute_rate(&hal2->dac, val);
+			hal2->dac.sample_rate = val;
+			hal2_set_dac_rate(hal2);
+		}
+		return put_user(val, (int *)arg);
+		
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			hal2_stop_adc(hal2);
+			hal2->adc.voices = (val) ? 2 : 1;
+			hal2_setup_adc(hal2);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			hal2_stop_dac(hal2);
+			hal2->dac.voices = (val) ? 2 : 1;
+			hal2_setup_dac(hal2);
+                }
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val != 0) {
+			if (file->f_mode & FMODE_READ) {
+				hal2_stop_adc(hal2);
+				hal2->adc.voices = (val == 1) ? 1 : 2;
+				hal2_setup_adc(hal2);
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				hal2_stop_dac(hal2);
+				hal2->dac.voices = (val == 1) ? 1 : 2;
+				hal2_setup_dac(hal2);
+			}
+		}
+		val = -EINVAL;
+		if (file->f_mode & FMODE_READ)
+			val = hal2->adc.voices;
+		if (file->f_mode & FMODE_WRITE)
+			val = hal2->dac.voices;
+		return put_user(val, (int *)arg);
+		
+	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+                return put_user(H2_SUPPORTED_FORMATS, (int *)arg);
+		
+	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val != AFMT_QUERY) {
+			if (!(val & H2_SUPPORTED_FORMATS))
+				return -EINVAL;
+			if (file->f_mode & FMODE_READ) {
+				hal2_stop_adc(hal2);
+				hal2->adc.format = val;
+				hal2_setup_adc(hal2);
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				hal2_stop_dac(hal2);
+				hal2->dac.format = val;
+				hal2_setup_dac(hal2);
+			}
+		} else {
+			val = -EINVAL;
+			if (file->f_mode & FMODE_READ)
+				val = hal2->adc.format;
+			if (file->f_mode & FMODE_WRITE)
+				val = hal2->dac.format;
+		}
+		return put_user(val, (int *)arg);
+		
+	case SNDCTL_DSP_POST:
+		return 0;
+
+	case SNDCTL_DSP_GETOSPACE: {
+		unsigned long flags;
+		audio_buf_info info;
+		hal2_buf_t *buf;
+		hal2_codec_t *dac = &hal2->dac;
+		
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		
+		spin_lock_irqsave(&dac->lock, flags);
+		info.fragments = 0;
+		buf = dac->head;
+		while (buf->info.cnt == 0 && buf != dac->tail) {
+			info.fragments++;
+			buf = buf->info.next;
+		}
+		spin_unlock_irqrestore(&dac->lock, flags);
+		
+		info.fragstotal = obuffers;
+		info.fragsize = H2_BUFFER_SIZE;
+                info.bytes = info.fragsize * info.fragments;
+
+		return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
+	}
+			   
+	case SNDCTL_DSP_GETISPACE: {
+		unsigned long flags;
+		audio_buf_info info;
+		hal2_buf_t *buf;
+		hal2_codec_t *adc = &hal2->adc;
+			
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		
+		spin_lock_irqsave(&adc->lock, flags);
+		info.fragments = 0;
+		info.bytes = 0;
+		buf = adc->tail;
+		while (buf->info.cnt > 0 && buf != adc->head) {
+			info.fragments++;
+			info.bytes += buf->info.cnt;
+			buf = buf->info.next;
+		}
+		spin_unlock_irqrestore(&adc->lock, flags);
+
+		info.fragstotal = ibuffers;
+		info.fragsize = H2_BUFFER_SIZE;
+		
+		return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
+	}
+
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+		
+	case SNDCTL_DSP_GETBLKSIZE:
+		return put_user(H2_BUFFER_SIZE, (int *)arg);
+	
+	case SNDCTL_DSP_SETFRAGMENT:
+		return 0;
+
+	case SOUND_PCM_READ_RATE:
+		val = -EINVAL;
+		if (file->f_mode & FMODE_READ)
+			val = hal2->adc.sample_rate;
+		if (file->f_mode & FMODE_WRITE)
+			val = hal2->dac.sample_rate;
+		return put_user(val, (int *)arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		val = -EINVAL;
+		if (file->f_mode & FMODE_READ)
+			val = hal2->adc.voices;
+		if (file->f_mode & FMODE_WRITE)
+			val = hal2->dac.voices;
+		return put_user(val, (int *)arg);
+
+	case SOUND_PCM_READ_BITS:
+		val = 16;
+		return put_user(val, (int *)arg);
+	}
+	
+	return hal2_mixer_ioctl(hal2, cmd, arg);
+}
+
+static ssize_t hal2_read(struct file *file, char *buffer,
+			 size_t count, loff_t *ppos)
+{
+	ssize_t err;
+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
+	hal2_codec_t *adc = &hal2->adc;
+
+	if (count == 0)
+		return 0;
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	
+	down(&adc->sem);
+	
+	if (file->f_flags & O_NONBLOCK) {
+		err = hal2_get_buffer(hal2, buffer, count);
+		err = err == 0 ? -EAGAIN : err;
+	} else {
+		do {
+			/* ~10% longer */
+			signed long timeout = 1000 * H2_BUFFER_SIZE *
+				2 * adc->voices * HZ / adc->sample_rate / 900;
+			DECLARE_WAITQUEUE(wait, current);
+			ssize_t cnt = 0;
+			
+			err = hal2_get_buffer(hal2, buffer, count);
+			if (err > 0) {
+				count -= err;
+				cnt += err;
+				buffer += err;
+				err = cnt;
+			}
+			if (count > 0 && err >= 0) {
+				add_wait_queue(&adc->dma_wait, &wait);
+				set_current_state(TASK_INTERRUPTIBLE);
+				/* Well, it is possible, that interrupt already
+				 * arrived. Hmm, shit happens, we have one more
+				 * buffer filled ;) */
+				if (!schedule_timeout(timeout))
+					/* We may get bogus timeout when system
+					 * is heavily loaded */
+					if (!adc->tail->info.cnt) {
+						printk("HAL2: timeout...\n");
+						hal2_stop_adc(hal2);
+						hal2_reset_adc_pointer(hal2);
+						err = -EAGAIN;
+					}
+				if (signal_pending(current))
+					err = -ERESTARTSYS;
+				remove_wait_queue(&adc->dma_wait, &wait);
+			}
+		} while (count > 0 && err >= 0);
+	
+	}
+	
+	up(&adc->sem);
+	
+	return err;
+}
+
+static ssize_t hal2_write(struct file *file, const char *buffer,
+			  size_t count, loff_t *ppos)
+{
+	ssize_t err;
+	char *buf = (char*) buffer;
+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
+	hal2_codec_t *dac = &hal2->dac;
+
+	if (count == 0)
+		return 0;
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	down(&dac->sem);
+
+	if (file->f_flags & O_NONBLOCK) {
+		err = hal2_add_buffer(hal2, buf, count);
+		err = err == 0 ? -EAGAIN : err;
+	} else {
+		do {
+			/* ~10% longer */
+			signed long timeout = 1000 * H2_BUFFER_SIZE *
+				2 * dac->voices * HZ / dac->sample_rate / 900;
+			DECLARE_WAITQUEUE(wait, current);
+			ssize_t cnt = 0;
+			
+			err = hal2_add_buffer(hal2, buf, count);
+			if (err > 0) {
+				count -= err;
+				cnt += err;
+				buf += err;
+				err = cnt;
+			}
+			if (count > 0 && err >= 0) {
+				add_wait_queue(&dac->dma_wait, &wait);
+				set_current_state(TASK_INTERRUPTIBLE);
+				/* Well, it is possible, that interrupt already
+				 * arrived. Hmm, shit happens, we have one more
+				 * buffer free ;) */
+				if (!schedule_timeout(timeout))
+					/* We may get bogus timeout when system
+					 * is heavily loaded */
+					if (dac->head->info.cnt) {
+						printk("HAL2: timeout...\n");
+						hal2_stop_dac(hal2);
+						hal2_reset_dac_pointer(hal2);
+						err = -EAGAIN;
+					}
+				if (signal_pending(current))
+					err = -ERESTARTSYS;
+				remove_wait_queue(&dac->dma_wait, &wait);
+			}
+		} while (count > 0 && err >= 0);
+	}
+	
+	up(&dac->sem);
+
+	return err;
+}
+
+static unsigned int hal2_poll(struct file *file, struct poll_table_struct *wait)
+{
+	unsigned long flags;
+	unsigned int mask = 0;
+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
+
+	if (file->f_mode & FMODE_READ) {
+		hal2_codec_t *adc = &hal2->adc;
+		
+		poll_wait(file, &hal2->adc.dma_wait, wait);
+		spin_lock_irqsave(&adc->lock, flags);
+		if (adc->tail->info.cnt > 0)
+			mask |= POLLIN;
+		spin_unlock_irqrestore(&adc->lock, flags);
+	}
+	
+	if (file->f_mode & FMODE_WRITE) {
+		hal2_codec_t *dac = &hal2->dac;
+		
+		poll_wait(file, &dac->dma_wait, wait);
+		spin_lock_irqsave(&dac->lock, flags);
+		if (dac->head->info.cnt == 0)
+			mask |= POLLOUT;
+		spin_unlock_irqrestore(&dac->lock, flags);
+	}
+	
+	return mask;
+}
+
+static int hal2_open(struct inode *inode, struct file *file)
+{
+	int err;
+	hal2_card_t *hal2 = hal2_dsp_find_card(MINOR(inode->i_rdev));
+
+	DEBUG("opening audio device.\n");
+
+	if (!hal2) {
+		printk("HAL2: Whee?! Open door and go away!\n");
+		return -ENODEV;
+	}
+	file->private_data = hal2;
+
+	if (file->f_mode & FMODE_READ) {
+		if (hal2->adc.usecount)
+			return -EBUSY;
+		
+		/* OSS spec wanted us to use 8 bit, 8 kHz mono by default,
+		 * but HAL2 can't do 8bit audio */
+		hal2->adc.format = AFMT_S16_BE;
+		hal2->adc.voices = 1;
+		hal2->adc.sample_rate = hal2_compute_rate(&hal2->adc, 8000);
+		hal2_set_adc_rate(hal2);
+
+		/* alloc DMA buffers */
+		err = hal2_alloc_adc_dmabuf(hal2);
+		if (err)
+			return err;
+		hal2_setup_adc(hal2);
+
+		hal2->adc.usecount++;
+	}
+
+	if (file->f_mode & FMODE_WRITE) {
+		if (hal2->dac.usecount)
+			return -EBUSY;
+
+		hal2->dac.format = AFMT_S16_BE;
+		hal2->dac.voices = 1;
+		hal2->dac.sample_rate = hal2_compute_rate(&hal2->dac, 8000);
+		hal2_set_dac_rate(hal2);
+
+		/* alloc DMA buffers */
+		err = hal2_alloc_dac_dmabuf(hal2);
+		if (err)
+			return err;
+		hal2_setup_dac(hal2);
+		
+		hal2->dac.usecount++;
+	}
+	
+	return 0;
+}
+
+static int hal2_release(struct inode *inode, struct file *file)
+{
+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
+
+	if (file->f_mode & FMODE_READ) {
+		hal2_stop_adc(hal2);
+		hal2_free_adc_dmabuf(hal2);
+		hal2->adc.usecount--;
+	}
+
+	if (file->f_mode & FMODE_WRITE) {
+		hal2_sync_dac(hal2);
+		hal2_free_dac_dmabuf(hal2);
+		hal2->dac.usecount--;
+	}
+
+	return 0;
+}
+
+static struct file_operations hal2_audio_fops = {
+	owner:		THIS_MODULE,
+	llseek:		no_llseek,
+	read:		hal2_read,
+	write:		hal2_write,
+	poll:		hal2_poll,
+	ioctl:		hal2_ioctl,
+	open:		hal2_open,
+	release:	hal2_release,
+};
+
+static struct file_operations hal2_mixer_fops = {
+	owner:		THIS_MODULE,
+	llseek:		no_llseek,
+	ioctl:		hal2_ioctl_mixdev,
+	open:		hal2_open_mixdev,
+	release:	hal2_release_mixdev,
+};
+
+static int hal2_request_irq(hal2_card_t *hal2, int irq)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	save_and_cli(flags);
+	if (request_irq(irq, hal2_interrupt, SA_SHIRQ, hal2str, hal2)) {
+		printk(KERN_ERR "HAL2: Can't get irq %d\n", irq);
+		ret = -EAGAIN;
+	}
+	restore_flags(flags);
+	return ret;
+}
+
+static int hal2_alloc_resources(hal2_card_t *hal2, struct hpc3_regs *hpc3)
+{
+	hal2_pbus_t *pbus;
+
+	pbus = &hal2->dac.pbus;
+	pbus->pbusnr = 0;
+	pbus->pbus = &hpc3->pbdma[pbus->pbusnr];
+	/* The spec says that we should write 0x08248844 but that's WRONG. HAL2
+	 * does 8 bit DMA, not 16 bit even if it generates 16 bit audio. */
+	hpc3->pbus_dmacfgs[pbus->pbusnr][0] = 0x08208844;	/* Magic :-) */
+
+	pbus = &hal2->adc.pbus;
+	pbus->pbusnr = 1;
+	pbus->pbus = &hpc3->pbdma[pbus->pbusnr];
+	hpc3->pbus_dmacfgs[pbus->pbusnr][0] = 0x08208844;	/* Magic :-) */
+
+	return hal2_request_irq(hal2, SGI_HPCDMA_IRQ);
+}
+
+static void hal2_init_codec(hal2_codec_t *codec)
+{
+	init_waitqueue_head(&codec->dma_wait);
+	init_MUTEX(&codec->sem);
+	spin_lock_init(&codec->lock);
+}
+
+static void hal2_free_resources(hal2_card_t *hal2)
+{
+	free_irq(SGI_HPCDMA_IRQ, hal2);
+}
+
+static int hal2_detect(hal2_card_t *hal2)
+{
+	unsigned short board, major, minor;
+	unsigned short rev;
+
+	/* reset HAL2 */
+	hal2_isr_write(hal2, 0);
+
+	/* release reset */
+	hal2_isr_write(hal2, H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N);
+
+	hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE); 
+
+	if ((rev = hal2_rev_look(hal2)) & H2_REV_AUDIO_PRESENT) {
+		DEBUG("HAL2: no device detected, rev: 0x%04hx\n", rev);
+		return -ENODEV;
+	}
+
+	board = (rev & H2_REV_BOARD_M) >> 12;
+	major = (rev & H2_REV_MAJOR_CHIP_M) >> 4;
+	minor = (rev & H2_REV_MINOR_CHIP_M);
+
+	printk("SGI HAL2 Processor revision %i.%i.%i detected\n",
+	       board, major, minor);
+
+	if (board != 4 || major != 1 || minor != 0) 
+		printk( "Other revision than 4.1.0 detected. "
+			"Your card is probably unsupported\n");
+
+	return 0;
+}
+
+static int hal2_init_card(hal2_card_t **phal2, struct hpc3_regs *hpc3,
+			  unsigned long hpc3_base)
+{
+	int ret = 0;
+	hal2_card_t *hal2;
+	
+	hal2 = (hal2_card_t *) kmalloc(sizeof(hal2_card_t), GFP_KERNEL);
+	if (!hal2)
+		return -ENOMEM;
+	memset(hal2, 0, sizeof(hal2_card_t));
+
+	hal2->ctl_regs = (hal2_ctl_regs_t *) KSEG1ADDR(hpc3_base + H2_CTL_PIO);
+	hal2->aes_regs = (hal2_aes_regs_t *) KSEG1ADDR(hpc3_base + H2_AES_PIO);
+	hal2->vol_regs = (hal2_vol_regs_t *) KSEG1ADDR(hpc3_base + H2_VOL_PIO);
+	hal2->syn_regs = (hal2_syn_regs_t *) KSEG1ADDR(hpc3_base + H2_SYN_PIO);
+
+	if (hal2_detect(hal2) < 0) {
+		printk("HAL2 audio processor not found\n");
+		ret = -ENODEV;
+		goto fail1;
+	}
+
+	hal2_init_codec(&hal2->dac);
+	hal2_init_codec(&hal2->adc);
+
+	ret = hal2_alloc_resources(hal2, hpc3);
+	if (ret)
+		goto fail1;
+	
+	hal2_init_mixer(hal2);
+
+	hal2->dev_dsp = register_sound_dsp(&hal2_audio_fops, -1);
+	if (hal2->dev_dsp < 0) {
+		ret = hal2->dev_dsp;
+		goto fail2;
+	}
+
+	hal2->dev_mixer = register_sound_mixer(&hal2_mixer_fops, -1);
+	if (hal2->dev_mixer < 0) {
+		ret = hal2->dev_mixer;
+		goto fail3;
+	}
+	
+	*phal2 = hal2;
+	return 0;
+fail3:
+	unregister_sound_dsp(hal2->dev_dsp);
+fail2:
+	hal2_free_resources(hal2);
+fail1:
+	kfree(hal2);
+	
+	return ret;
+}
+
+/* 
+ * We are assuming only one HAL2 card. If you ever meet machine with more than
+ * one, tell immediately about it to someone. Preferably to me. --ladis
+ */
+static int __init init_hal2(void)
+{
+	int i;
+
+	for (i = 0; i < MAXCARDS; i++)
+		hal2_card[i] = NULL;
+
+	return hal2_init_card(&hal2_card[0], hpc3c0, HPC3_CHIP0_PBASE);
+}
+
+static void __exit exit_hal2(void)
+{
+	int i;
+	
+	for (i = 0; i < MAXCARDS; i++)
+		if (hal2_card[i]) {
+			hal2_free_resources(hal2_card[i]);
+			unregister_sound_dsp(hal2_card[i]->dev_dsp);
+			unregister_sound_mixer(hal2_card[i]->dev_mixer);
+			kfree(hal2_card[i]);
+	}
+}
+
+module_init(init_hal2);
+module_exit(exit_hal2);
+
+MODULE_DESCRIPTION("OSS compatible driver for SGI HAL2 audio");
+MODULE_AUTHOR("Ladislav Michl");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/hal2.h linux/drivers/sound/hal2.h
--- linux.orig/drivers/sound/hal2.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/sound/hal2.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,328 @@
+#ifndef __HAL2_H
+#define __HAL2_H
+
+/*
+ *  Driver for HAL2 sound processors
+ *  Copyright (c) 1999 Ulf Carlsson <ulfc@bun.falkenberg.se>
+ *  Copyright (c) 2001 Ladislav Michl <ladis@psi.cz>
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <asm/addrspace.h>
+#include <asm/sgi/sgihpc.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define H2_HAL2_BASE		0x58000
+#define H2_CTL_PIO		(H2_HAL2_BASE + 0 * 0x400)
+#define H2_AES_PIO		(H2_HAL2_BASE + 1 * 0x400)
+#define H2_VOL_PIO		(H2_HAL2_BASE + 2 * 0x400)
+#define H2_SYN_PIO		(H2_HAL2_BASE + 3 * 0x400)
+
+/* Indirect status register */
+
+#define H2_ISR_TSTATUS		0x01	/* RO: transaction status 1=busy */
+#define H2_ISR_USTATUS		0x02	/* RO: utime status bit 1=armed */
+#define H2_ISR_QUAD_MODE	0x04	/* codec mode 0=indigo 1=quad */
+#define H2_ISR_GLOBAL_RESET_N	0x08	/* chip global reset 0=reset */
+#define H2_ISR_CODEC_RESET_N	0x10	/* codec/synth reset 0=reset  */
+
+/* Revision register */
+
+#define H2_REV_AUDIO_PRESENT	0x8000	/* RO: audio present 0=present */
+#define H2_REV_BOARD_M		0x7000	/* RO: bits 14:12, board revision */
+#define H2_REV_MAJOR_CHIP_M	0x00F0	/* RO: bits 7:4, major chip revision */
+#define H2_REV_MINOR_CHIP_M	0x000F	/* RO: bits 3:0, minor chip revision */
+
+/* Indirect address register */
+
+/*
+ * Address of indirect internal register to be accessed. A write to this
+ * register initiates read or write access to the indirect registers in the
+ * HAL2. Note that there af four indirect data registers for write access to
+ * registers larger than 16 byte.
+ */
+
+#define H2_IAR_TYPE_M		0xF000	/* bits 15:12, type of functional */
+					/* block the register resides in */
+					/* 1=DMA Port */
+					/* 9=Global DMA Control */
+					/* 2=Bresenham */
+					/* 3=Unix Timer */
+#define H2_IAR_NUM_M		0x0F00	/* bits 11:8 instance of the */
+					/* blockin which the indirect */
+					/* register resides */
+					/* If IAR_TYPE_M=DMA Port: */
+					/* 1=Synth In */
+					/* 2=AES In */
+					/* 3=AES Out */
+					/* 4=DAC Out */
+					/* 5=ADC Out */
+					/* 6=Synth Control */
+					/* If IAR_TYPE_M=Global DMA Control: */
+					/* 1=Control */
+					/* If IAR_TYPE_M=Bresenham: */
+					/* 1=Bresenham Clock Gen 1 */
+					/* 2=Bresenham Clock Gen 2 */
+					/* 3=Bresenham Clock Gen 3 */
+					/* If IAR_TYPE_M=Unix Timer: */
+					/* 1=Unix Timer */
+#define H2_IAR_ACCESS_SELECT	0x0080	/* 1=read 0=write */
+#define H2_IAR_PARAM		0x000C	/* Parameter Select */
+#define H2_IAR_RB_INDEX_M	0x0003	/* Read Back Index */
+					/* 00:word0 */
+					/* 01:word1 */
+					/* 10:word2 */
+					/* 11:word3 */
+/*
+ * HAL2 internal addressing
+ *
+ * The HAL2 has "indirect registers" (idr) which are accessed by writing to the
+ * Indirect Data registers. Write the address to the Indirect Address register
+ * to transfer the data.
+ *
+ * We define the H2IR_* to the read address and H2IW_* to the write address and
+ * H2I_* to be fields in whatever register is referred to.
+ *
+ * When we write to indirect registers which are larger than one word (16 bit)
+ * we have to fill more than one indirect register before writing. When we read
+ * back however we have to read several times, each time with different Read
+ * Back Indexes (there are defs for doing this easily).
+ */
+
+/*
+ * Relay Control
+ */
+#define H2I_RELAY_C		0x9100
+#define H2I_RELAY_C_STATE	0x01		/* state of RELAY pin signal */
+
+/* DMA port enable */
+
+#define H2I_DMA_PORT_EN		0x9104
+#define H2I_DMA_PORT_EN_SY_IN	0x01		/* Synth_in DMA port */
+#define H2I_DMA_PORT_EN_AESRX	0x02		/* AES receiver DMA port */
+#define H2I_DMA_PORT_EN_AESTX	0x04		/* AES transmitter DMA port */
+#define H2I_DMA_PORT_EN_CODECTX	0x08		/* CODEC transmit DMA port */
+#define H2I_DMA_PORT_EN_CODECR	0x10		/* CODEC receive DMA port */
+
+#define H2I_DMA_END		0x9108 		/* global dma endian select */
+#define H2I_DMA_END_SY_IN	0x01		/* Synth_in DMA port */
+#define H2I_DMA_END_AESRX	0x02		/* AES receiver DMA port */
+#define H2I_DMA_END_AESTX	0x04		/* AES transmitter DMA port */
+#define H2I_DMA_END_CODECTX	0x08		/* CODEC transmit DMA port */
+#define H2I_DMA_END_CODECR	0x10		/* CODEC receive DMA port */
+						/* 0=b_end 1=l_end */
+
+#define H2I_DMA_DRV		0x910C  	/* global PBUS DMA enable */
+
+#define H2I_SYNTH_C		0x1104		/* Synth DMA control */
+
+#define H2I_AESRX_C		0x1204	 	/* AES RX dma control */
+
+#define H2I_C_TS_EN		0x20		/* Timestamp enable */
+#define H2I_C_TS_FRMT		0x40		/* Timestamp format */
+#define H2I_C_NAUDIO		0x80		/* Sign extend */
+
+/* AESRX CTL, 16 bit */
+
+#define H2I_AESTX_C		0x1304		/* AES TX DMA control */
+#define H2I_AESTX_C_CLKID_SHIFT	3		/* Bresenham Clock Gen 1-3 */
+#define H2I_AESTX_C_CLKID_M	0x18
+#define H2I_AESTX_C_DATAT_SHIFT	8		/* 1=mono 2=stereo (3=quad) */
+#define H2I_AESTX_C_DATAT_M	0x300
+
+/* CODEC registers */
+
+#define H2I_DAC_C1		0x1404 		/* DAC DMA control, 16 bit */
+#define H2I_DAC_C2		0x1408		/* DAC DMA control, 32 bit */
+#define H2I_ADC_C1		0x1504 		/* ADC DMA control, 16 bit */
+#define H2I_ADC_C2		0x1508		/* ADC DMA control, 32 bit */
+
+/* Bits in CTL1 register */
+
+#define H2I_C1_DMA_SHIFT	0		/* DMA channel */
+#define H2I_C1_DMA_M		0x7
+#define H2I_C1_CLKID_SHIFT	3		/* Bresenham Clock Gen 1-3 */
+#define H2I_C1_CLKID_M		0x18
+#define H2I_C1_DATAT_SHIFT	8		/* 1=mono 2=stereo (3=quad) */
+#define H2I_C1_DATAT_M		0x300
+
+/* Bits in CTL2 register */
+
+#define H2I_C2_R_GAIN_SHIFT	0		/* right a/d input gain */	
+#define H2I_C2_R_GAIN_M		0xf	
+#define H2I_C2_L_GAIN_SHIFT	4		/* left a/d input gain */
+#define H2I_C2_L_GAIN_M		0xf0
+#define H2I_C2_R_SEL		0x100		/* right input select */
+#define H2I_C2_L_SEL		0x200		/* left input select */
+#define H2I_C2_MUTE		0x400		/* mute */
+#define H2I_C2_DO1		0x00010000	/* digital output port bit 0 */
+#define H2I_C2_DO2		0x00020000	/* digital output port bit 1 */
+#define H2I_C2_R_ATT_SHIFT	18		/* right d/a output - */
+#define H2I_C2_R_ATT_M		0x007c0000	/* attenuation */
+#define H2I_C2_L_ATT_SHIFT	23		/* left d/a output - */
+#define H2I_C2_L_ATT_M		0x0f800000	/* attenuation */
+
+#define H2I_SYNTH_MAP_C		0x1104		/* synth dma handshake ctrl */
+
+/* Clock generator CTL 1, 16 bit */
+
+#define H2I_BRES1_C1		0x2104
+#define H2I_BRES2_C1		0x2204
+#define H2I_BRES3_C1		0x2304
+
+#define H2I_BRES_C1_SHIFT	0		/* 0=48.0 1=44.1 2=aes_rx */
+#define H2I_BRES_C1_M		0x03
+				
+/* Clock generator CTL 2, 32 bit */
+
+#define H2I_BRES1_C2		0x2108
+#define H2I_BRES2_C2		0x2208
+#define H2I_BRES3_C2		0x2308
+
+#define H2I_BRES_C2_INC_SHIFT	0		/* increment value */
+#define H2I_BRES_C2_INC_M	0xffff
+#define H2I_BRES_C2_MOD_SHIFT	16		/* modcontrol value */
+#define H2I_BRES_C2_MOD_M	0xffff0000	/* modctrl=0xffff&(modinc-1) */
+
+/* Unix timer, 64 bit */
+
+#define H2I_UTIME		0x3104
+#define H2I_UTIME_0_LD		0xffff		/* microseconds, LSB's */
+#define H2I_UTIME_1_LD0		0x0f		/* microseconds, MSB's */
+#define H2I_UTIME_1_LD1		0xf0		/* tenths of microseconds */
+#define H2I_UTIME_2_LD		0xffff		/* seconds, LSB's */
+#define H2I_UTIME_3_LD		0xffff		/* seconds, MSB's */
+
+typedef volatile u32 hal2_reg_t;
+
+typedef struct stru_hal2_ctl_regs hal2_ctl_regs_t;
+struct stru_hal2_ctl_regs {
+	hal2_reg_t _unused0[4];
+	hal2_reg_t isr;			/* 0x10 Status Register */
+	hal2_reg_t _unused1[3];
+	hal2_reg_t rev;			/* 0x20 Revision Register */
+	hal2_reg_t _unused2[3];
+	hal2_reg_t iar;			/* 0x30 Indirect Address Register */
+	hal2_reg_t _unused3[3];
+	hal2_reg_t idr0;		/* 0x40 Indirect Data Register 0 */
+	hal2_reg_t _unused4[3];
+	hal2_reg_t idr1;		/* 0x50 Indirect Data Register 1 */
+	hal2_reg_t _unused5[3];
+	hal2_reg_t idr2;		/* 0x60 Indirect Data Register 2 */
+	hal2_reg_t _unused6[3];
+	hal2_reg_t idr3;		/* 0x70 Indirect Data Register 3 */
+};
+
+typedef struct stru_hal2_aes_regs hal2_aes_regs_t;
+struct stru_hal2_aes_regs {
+	hal2_reg_t rx_stat[2];		/* Status registers */
+	hal2_reg_t rx_cr[2];		/* Control registers */
+	hal2_reg_t rx_ud[4];		/* User data window */
+	hal2_reg_t rx_st[24];		/* Channel status data */
+	
+	hal2_reg_t tx_stat[1];		/* Status register */
+	hal2_reg_t tx_cr[3];		/* Control registers */
+	hal2_reg_t tx_ud[4];		/* User data window */
+	hal2_reg_t tx_st[24];		/* Channel status data */
+};
+
+typedef struct stru_hal2_vol_regs hal2_vol_regs_t;
+struct stru_hal2_vol_regs {
+	hal2_reg_t right;		/* 0x00 Right volume */
+	hal2_reg_t left;		/* 0x04 Left volume */
+};
+
+typedef struct stru_hal2_syn_regs hal2_syn_regs_t;
+struct stru_hal2_syn_regs {
+	hal2_reg_t _unused0[2];
+	hal2_reg_t page;		/* DOC Page register */
+	hal2_reg_t regsel;		/* DOC Register selection */
+	hal2_reg_t dlow;		/* DOC Data low */
+	hal2_reg_t dhigh;		/* DOC Data high */
+	hal2_reg_t irq;			/* IRQ Status */
+	hal2_reg_t dram;		/* DRAM Access */
+};
+
+/* HAL2 specific structures */
+
+typedef struct stru_hal2_pbus hal2_pbus_t;
+struct stru_hal2_pbus {
+	struct hpc3_pbus_dmacregs *pbus;
+	int pbusnr;
+	unsigned int ctrl;		/* Current state of pbus->pbdma_ctrl */
+};
+
+typedef struct stru_hal2_binfo hal2_binfo_t;
+typedef struct stru_hal2_buffer hal2_buf_t;
+struct stru_hal2_binfo {
+	volatile struct hpc_dma_desc desc;
+	hal2_buf_t *next;		/* pointer to next buffer */
+	int cnt;			/* bytes in buffer */
+};
+#define H2_BUFFER_SIZE	(PAGE_SIZE - \
+		((sizeof(hal2_binfo_t) - 1) / 8 + 1) * 8)
+struct stru_hal2_buffer {
+	hal2_binfo_t info;
+	char data[H2_BUFFER_SIZE] __attribute__((aligned(8)));
+};
+
+typedef struct stru_hal2_codec hal2_codec_t;
+struct stru_hal2_codec {
+	hal2_buf_t *head;
+	hal2_buf_t *tail; 
+	hal2_pbus_t pbus;
+	unsigned int format;		/* Audio data format */
+	int voices;			/* mono/stereo */
+	unsigned int sample_rate;
+	unsigned int master;		/* Master frequency */
+	unsigned short mod;		/* MOD value */
+	unsigned short inc;		/* INC value */
+
+	wait_queue_head_t dma_wait;
+	spinlock_t lock;
+	struct semaphore sem;
+
+	int usecount;			/* recording and playback are 
+					 * independent */
+};
+
+#define H2_MIX_OUTPUT_ATT	0
+#define H2_MIX_INPUT_GAIN	1
+#define H2_MIXERS		2
+typedef struct stru_hal2_mixer hal2_mixer_t;
+struct stru_hal2_mixer {
+	int modcnt;
+	unsigned int volume[H2_MIXERS];
+};
+
+typedef struct stru_hal2_card hal2_card_t;
+struct stru_hal2_card {
+	int dev_dsp;			/* audio device */
+	int dev_mixer;			/* mixer device */
+	int dev_midi;			/* midi device */
+	
+	hal2_ctl_regs_t *ctl_regs;	/* HAL2 ctl registers */
+	hal2_aes_regs_t *aes_regs;	/* HAL2 vol registers */
+	hal2_vol_regs_t *vol_regs;	/* HAL2 aes registers */
+	hal2_syn_regs_t *syn_regs;	/* HAL2 syn registers */
+
+	hal2_codec_t dac;
+	hal2_codec_t adc;
+	hal2_mixer_t mixer;
+};
+
+#endif				/* __HAL2_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- linux.orig/drivers/sound/i810_audio.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/i810_audio.c	2002-07-20 01:08:39.000000000 +0000
@@ -101,6 +101,9 @@
 #ifndef PCI_DEVICE_ID_INTEL_ICH3
 #define PCI_DEVICE_ID_INTEL_ICH3	0x2485
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH4
+#define PCI_DEVICE_ID_INTEL_ICH4	0x24c5
+#endif
 #ifndef PCI_DEVICE_ID_INTEL_440MX
 #define PCI_DEVICE_ID_INTEL_440MX	0x7195
 #endif
@@ -110,6 +113,9 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO
 #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO	0x01b1
 #endif
+#ifndef PCI_DEVICE_ID_AMD_768_AUDIO
+#define PCI_DEVICE_ID_AMD_768_AUDIO	0x7445
+#endif
 
 static int ftsodell=0;
 static int strict_clocking=0;
@@ -230,8 +236,10 @@
 	INTEL440MX,
 	INTELICH2,
 	INTELICH3,
+	INTELICH4,
 	SI7012,
-	NVIDIA_NFORCE
+	NVIDIA_NFORCE,
+	AMD768
 };
 
 static char * card_names[] = {
@@ -240,8 +248,10 @@
 	"Intel 440MX",
 	"Intel ICH2",
 	"Intel ICH3",
+	"Intel ICH4",
 	"SiS 7012",
-	"NVIDIA nForce Audio"
+	"NVIDIA nForce Audio",
+	"AMD 768"
 };
 
 static struct pci_device_id i810_pci_tbl [] __initdata = {
@@ -255,10 +265,14 @@
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH2},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH3,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH3},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH4,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7012,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SI7012},
 	{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE},
+	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_768_AUDIO,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD768},
 	{0,}
 };
 
@@ -2015,7 +2029,7 @@
 		printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
 			cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
@@ -2054,7 +2068,7 @@
 		printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
 			cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_NONBLOCK:
 #ifdef DEBUG
@@ -2662,7 +2676,7 @@
 		codec->codec_write = i810_ac97_set;
 	
 		if(!i810_ac97_probe_and_powerup(card,codec)) {
-			printk("i810_audio: timed out waiting for codec %d analog ready", num_ac97);
+			printk("i810_audio: timed out waiting for codec %d analog ready.\n", num_ac97);
 			kfree(codec);
 			break;	/* it didn't work */
 		}
@@ -2679,6 +2693,14 @@
 			break;
 		}
 		
+		codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L);
+		if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID))
+		{
+			printk(KERN_WARNING "i810_audio: codec %d is a softmodem - skipping.\n", num_ac97);
+			kfree(codec);
+			continue;
+		}
+	
 		card->ac97_features = eid;
 				
 		/* Now check the codec for useful features to make up for
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/ite8172.c linux/drivers/sound/ite8172.c
--- linux.orig/drivers/sound/ite8172.c	2001-10-25 20:53:52.000000000 +0000
+++ linux/drivers/sound/ite8172.c	2002-07-20 01:08:28.000000000 +0000
@@ -42,14 +42,15 @@
  *      * Memory mapping the audio buffers, and the ioctl controls that go
  *        with it.
  *      * S/PDIF output.
+ *      * I2S support.
  *  3. The following is not supported:
- *      * I2S input.
  *      * legacy audio mode.
  *  4. Support for volume button interrupts is implemented but doesn't
  *     work yet.
  *
  *  Revision history
- *    02.08.2001  0.1   Initial release
+ *    02.08.2001  Initial release
+ *    06.22.2001  Added I2S support
  */
 #include <linux/version.h>
 #include <linux/module.h>
@@ -82,6 +83,19 @@
 #undef IT8172_VERBOSE_DEBUG
 #define DBG(x) {}
 
+#define IT8172_MODULE_NAME "IT8172 audio"
+#define PFX IT8172_MODULE_NAME
+
+#ifdef IT8172_DEBUG
+#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
+
+
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
 
@@ -228,75 +242,84 @@
 #define POLL_COUNT   0x5000
 
 
-#define IT8172_MODULE_NAME "IT8172 audio"
-#define PFX IT8172_MODULE_NAME ": "
+/* --------------------------------------------------------------------- */
 
+/*
+ * Define DIGITAL1 as the I2S channel, since it is not listed in
+ * soundcard.h.
+ */
+#define SOUND_MIXER_I2S        SOUND_MIXER_DIGITAL1
+#define SOUND_MASK_I2S         SOUND_MASK_DIGITAL1
+#define SOUND_MIXER_READ_I2S   MIXER_READ(SOUND_MIXER_I2S)
+#define SOUND_MIXER_WRITE_I2S  MIXER_WRITE(SOUND_MIXER_I2S)
 
 /* --------------------------------------------------------------------- */
 
 struct it8172_state {
-    /* list of it8172 devices */
-    struct list_head devs;
+	/* list of it8172 devices */
+	struct list_head devs;
 
-    /* the corresponding pci_dev structure */
-    struct pci_dev *dev;
+	/* the corresponding pci_dev structure */
+	struct pci_dev *dev;
 
-    /* soundcore stuff */
-    int dev_audio;
-
-    /* hardware resources */
-    unsigned long io;
-    unsigned int irq;
-
-    /* PCI ID's */
-    u16 vendor;
-    u16 device;
-    u8 rev; /* the chip revision */
-
-    /* options */
-    int spdif_volume; /* S/PDIF output is enabled if != -1 */
+	/* soundcore stuff */
+	int dev_audio;
 
+	/* hardware resources */
+	unsigned long io;
+	unsigned int irq;
+
+	/* PCI ID's */
+	u16 vendor;
+	u16 device;
+	u8 rev; /* the chip revision */
+
+	/* options */
+	int spdif_volume; /* S/PDIF output is enabled if != -1 */
+	int i2s_volume;   /* current I2S out volume, in OSS format */
+	int i2s_recording;/* 1 = recording from I2S, 0 = not */
+    
 #ifdef IT8172_DEBUG
-    /* debug /proc entry */
-    struct proc_dir_entry *ps;
-    struct proc_dir_entry *ac97_ps;
+	/* debug /proc entry */
+	struct proc_dir_entry *ps;
+	struct proc_dir_entry *ac97_ps;
 #endif /* IT8172_DEBUG */
 
-    struct ac97_codec codec;
+	struct ac97_codec codec;
 
-    unsigned short pcc, capcc;
-    unsigned dacrate, adcrate;
+	unsigned short pcc, capcc;
+	unsigned dacrate, adcrate;
 
-    spinlock_t lock;
-    struct semaphore open_sem;
-    mode_t open_mode;
-    wait_queue_head_t open_wait;
-
-    struct dmabuf {
-	void *rawbuf;
-	dma_addr_t dmaaddr;
-	unsigned buforder;
-	unsigned numfrag;
-	unsigned fragshift;
-	void* nextIn;
-	void* nextOut;
-	int count;
-	int curBufPtr;
-	unsigned total_bytes;
-	unsigned error; /* over/underrun */
-	wait_queue_head_t wait;
-	/* redundant, but makes calculations easier */
-	unsigned fragsize;
-	unsigned dmasize;
-	unsigned fragsamples;
-	/* OSS stuff */
-	unsigned mapped:1;
-	unsigned ready:1;
-	unsigned stopped:1;
-	unsigned ossfragshift;
-	int ossmaxfrags;
-	unsigned subdivision;
-    } dma_dac, dma_adc;
+	spinlock_t lock;
+	struct semaphore open_sem;
+	mode_t open_mode;
+	wait_queue_head_t open_wait;
+
+	struct dmabuf {
+		void *rawbuf;
+		dma_addr_t dmaaddr;
+		unsigned buforder;
+		unsigned numfrag;
+		unsigned fragshift;
+		void* nextIn;
+		void* nextOut;
+		int count;
+		int curBufPtr;
+		unsigned total_bytes;
+		unsigned error; /* over/underrun */
+		wait_queue_head_t wait;
+		/* redundant, but makes calculations easier */
+		unsigned fragsize;
+		unsigned dmasize;
+		unsigned fragsamples;
+		/* OSS stuff */
+		unsigned mapped:1;
+		unsigned ready:1;
+		unsigned stopped:1;
+		unsigned ossfragshift;
+		int ossmaxfrags;
+		unsigned subdivision;
+	} dma_dac, dma_adc;
 };
 
 /* --------------------------------------------------------------------- */
@@ -305,116 +328,116 @@
 
 /* --------------------------------------------------------------------- */
 
-extern inline unsigned ld2(unsigned int x)
+static inline unsigned ld2(unsigned int x)
 {
-    unsigned r = 0;
+	unsigned r = 0;
 	
-    if (x >= 0x10000) {
-	x >>= 16;
-	r += 16;
-    }
-    if (x >= 0x100) {
-	x >>= 8;
-	r += 8;
-    }
-    if (x >= 0x10) {
-	x >>= 4;
-	r += 4;
-    }
-    if (x >= 4) {
-	x >>= 2;
-	r += 2;
-    }
-    if (x >= 2)
-	r++;
-    return r;
+	if (x >= 0x10000) {
+		x >>= 16;
+		r += 16;
+	}
+	if (x >= 0x100) {
+		x >>= 8;
+		r += 8;
+	}
+	if (x >= 0x10) {
+		x >>= 4;
+		r += 4;
+	}
+	if (x >= 4) {
+		x >>= 2;
+		r += 2;
+	}
+	if (x >= 2)
+		r++;
+	return r;
 }
 
 /* --------------------------------------------------------------------- */
 
 static void it8172_delay(int msec)
 {
-    unsigned long tmo;
-    signed long tmo2;
+	unsigned long tmo;
+	signed long tmo2;
 
-    if (in_interrupt())
-	return;
+	if (in_interrupt())
+		return;
     
-    tmo = jiffies + (msec*HZ)/1000;
-    for (;;) {
-	tmo2 = tmo - jiffies;
-	if (tmo2 <= 0)
-	    break;
-	schedule_timeout(tmo2);
-    }
+	tmo = jiffies + (msec*HZ)/1000;
+	for (;;) {
+		tmo2 = tmo - jiffies;
+		if (tmo2 <= 0)
+			break;
+		schedule_timeout(tmo2);
+	}
 }
 
 
 static unsigned short
 get_compat_rate(unsigned* rate)
 {
-    unsigned rate_out = *rate;
-    unsigned short sr;
+	unsigned rate_out = *rate;
+	unsigned short sr;
     
-    if (rate_out >= 46050) {
-	sr = CC_SR_48000; rate_out = 48000;
-    } else if (rate_out >= 41250) {
-	sr = CC_SR_44100; rate_out = 44100;
-    } else if (rate_out >= 35200) {
-	sr = CC_SR_38400; rate_out = 38400;
-    } else if (rate_out >= 27025) {
-	sr = CC_SR_32000; rate_out = 32000;
-    } else if (rate_out >= 20625) {
-	sr = CC_SR_22050; rate_out = 22050;
-    } else if (rate_out >= 17600) {
-	sr = CC_SR_19200; rate_out = 19200;
-    } else if (rate_out >= 13513) {
-	sr = CC_SR_16000; rate_out = 16000;
-    } else if (rate_out >= 10313) {
-	sr = CC_SR_11025; rate_out = 11025;
-    } else if (rate_out >= 8800) {
-	sr = CC_SR_9600; rate_out = 9600;
-    } else if (rate_out >= 6750) {
-	sr = CC_SR_8000; rate_out = 8000;
-    } else {
-	sr = CC_SR_5500; rate_out = 5500;
-    }
+	if (rate_out >= 46050) {
+		sr = CC_SR_48000; rate_out = 48000;
+	} else if (rate_out >= 41250) {
+		sr = CC_SR_44100; rate_out = 44100;
+	} else if (rate_out >= 35200) {
+		sr = CC_SR_38400; rate_out = 38400;
+	} else if (rate_out >= 27025) {
+		sr = CC_SR_32000; rate_out = 32000;
+	} else if (rate_out >= 20625) {
+		sr = CC_SR_22050; rate_out = 22050;
+	} else if (rate_out >= 17600) {
+		sr = CC_SR_19200; rate_out = 19200;
+	} else if (rate_out >= 13513) {
+		sr = CC_SR_16000; rate_out = 16000;
+	} else if (rate_out >= 10313) {
+		sr = CC_SR_11025; rate_out = 11025;
+	} else if (rate_out >= 8800) {
+		sr = CC_SR_9600; rate_out = 9600;
+	} else if (rate_out >= 6750) {
+		sr = CC_SR_8000; rate_out = 8000;
+	} else {
+		sr = CC_SR_5500; rate_out = 5500;
+	}
 
-    *rate = rate_out;
-    return sr;
+	*rate = rate_out;
+	return sr;
 }
 
 static void set_adc_rate(struct it8172_state *s, unsigned rate)
 {
-    unsigned long flags;
-    unsigned short sr;
+	unsigned long flags;
+	unsigned short sr;
     
-    sr = get_compat_rate(&rate);
+	sr = get_compat_rate(&rate);
 
-    spin_lock_irqsave(&s->lock, flags);
-    s->capcc &= ~CC_SR_MASK;
-    s->capcc |= sr;
-    outw(s->capcc, s->io+IT_AC_CAPCC);
-    spin_unlock_irqrestore(&s->lock, flags);
+	spin_lock_irqsave(&s->lock, flags);
+	s->capcc &= ~CC_SR_MASK;
+	s->capcc |= sr;
+	outw(s->capcc, s->io+IT_AC_CAPCC);
+	spin_unlock_irqrestore(&s->lock, flags);
 
-    s->adcrate = rate;
+	s->adcrate = rate;
 }
 
 
 static void set_dac_rate(struct it8172_state *s, unsigned rate)
 {
-    unsigned long flags;
-    unsigned short sr;
+	unsigned long flags;
+	unsigned short sr;
     
-    sr = get_compat_rate(&rate);
+	sr = get_compat_rate(&rate);
 
-    spin_lock_irqsave(&s->lock, flags);
-    s->pcc &= ~CC_SR_MASK;
-    s->pcc |= sr;
-    outw(s->pcc, s->io+IT_AC_PCC);
-    spin_unlock_irqrestore(&s->lock, flags);
+	spin_lock_irqsave(&s->lock, flags);
+	s->pcc &= ~CC_SR_MASK;
+	s->pcc |= sr;
+	outw(s->pcc, s->io+IT_AC_PCC);
+	spin_unlock_irqrestore(&s->lock, flags);
 
-    s->dacrate = rate;
+	s->dacrate = rate;
 }
 
 
@@ -422,210 +445,209 @@
 
 static u16 rdcodec(struct ac97_codec *codec, u8 addr)
 {
-    struct it8172_state *s = (struct it8172_state *)codec->private_data;
-    unsigned long flags;
-    unsigned short circp, data;
-    int i;
-    
-    spin_lock_irqsave(&s->lock, flags);
-
-    for (i = 0; i < POLL_COUNT; i++)
-	if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
-	    break;
-    if (i == POLL_COUNT)
-	printk(KERN_INFO PFX "rdcodec: codec ready poll expired!\n");
-
-    circp = addr & CIRCP_CIA_MASK;
-    circp |= (codec->id << CIRCP_CID_BIT);
-    circp |= CIRCP_RWC; // read command
-    outw(circp, s->io+IT_AC_CIRCP);
-
-    /* now wait for the data */
-    for (i = 0; i < POLL_COUNT; i++)
-	if (inw(s->io+IT_AC_CIRCP) & CIRCP_DPVF)
-	    break;
-    if (i == POLL_COUNT)
-	printk(KERN_INFO PFX "rdcodec: read poll expired!\n");
+	struct it8172_state *s = (struct it8172_state *)codec->private_data;
+	unsigned long flags;
+	unsigned short circp, data;
+	int i;
+    
+	spin_lock_irqsave(&s->lock, flags);
 
-    data = inw(s->io+IT_AC_CIRDP);
-    spin_unlock_irqrestore(&s->lock, flags);
+	for (i = 0; i < POLL_COUNT; i++)
+		if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
+			break;
+	if (i == POLL_COUNT)
+		err("rdcodec: codec ready poll expired!");
+
+	circp = addr & CIRCP_CIA_MASK;
+	circp |= (codec->id << CIRCP_CID_BIT);
+	circp |= CIRCP_RWC; // read command
+	outw(circp, s->io+IT_AC_CIRCP);
+
+	/* now wait for the data */
+	for (i = 0; i < POLL_COUNT; i++)
+		if (inw(s->io+IT_AC_CIRCP) & CIRCP_DPVF)
+			break;
+	if (i == POLL_COUNT)
+		err("rdcodec: read poll expired!");
 
-    return data;
+	data = inw(s->io+IT_AC_CIRDP);
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	return data;
 }
 
 
 static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
 {
-    struct it8172_state *s = (struct it8172_state *)codec->private_data;
-    unsigned long flags;
-    unsigned short circp;
-    int i;
-    
-    spin_lock_irqsave(&s->lock, flags);
-
-    for (i = 0; i < POLL_COUNT; i++)
-	if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
-	    break;
-    if (i == POLL_COUNT)
-	printk(KERN_INFO PFX "wrcodec: codec ready poll expired!\n");
-
-    circp = addr & CIRCP_CIA_MASK;
-    circp |= (codec->id << CIRCP_CID_BIT);
-    circp &= ~CIRCP_RWC; // write command
+	struct it8172_state *s = (struct it8172_state *)codec->private_data;
+	unsigned long flags;
+	unsigned short circp;
+	int i;
+    
+	spin_lock_irqsave(&s->lock, flags);
+
+	for (i = 0; i < POLL_COUNT; i++)
+		if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
+			break;
+	if (i == POLL_COUNT)
+		err("wrcodec: codec ready poll expired!");
+
+	circp = addr & CIRCP_CIA_MASK;
+	circp |= (codec->id << CIRCP_CID_BIT);
+	circp &= ~CIRCP_RWC; // write command
 
-    outw(data,  s->io+IT_AC_CIRDP);  // send data first
-    outw(circp, s->io+IT_AC_CIRCP);
+	outw(data,  s->io+IT_AC_CIRDP);  // send data first
+	outw(circp, s->io+IT_AC_CIRCP);
 
-    spin_unlock_irqrestore(&s->lock, flags);
+	spin_unlock_irqrestore(&s->lock, flags);
 }
 
 
 static void waitcodec(struct ac97_codec *codec)
 {
-    unsigned short temp;
+	unsigned short temp;
+
+	/* codec_wait is used to wait for a ready state after
+	   an AC97_RESET. */
+	it8172_delay(10);
 
-    /* codec_wait is used to wait for a ready state after
-       an AC97_RESET. */
-    it8172_delay(10);
-
-    temp = rdcodec(codec, 0x26);
-
-    // If power down, power up
-    if (temp & 0x3f00) {
-	// Power on
-	wrcodec(codec, 0x26, 0);
-	it8172_delay(100);
-	// Reread
 	temp = rdcodec(codec, 0x26);
-    }
+
+	// If power down, power up
+	if (temp & 0x3f00) {
+		// Power on
+		wrcodec(codec, 0x26, 0);
+		it8172_delay(100);
+		// Reread
+		temp = rdcodec(codec, 0x26);
+	}
     
-    // Check if Codec REF,ANL,DAC,ADC ready***/
-    if ((temp & 0x3f0f) != 0x000f) {
-	printk(KERN_INFO PFX "codec reg 26 status (0x%x) not ready!!\n",
-	       temp);
-	return;
-    }
+	// Check if Codec REF,ANL,DAC,ADC ready***/
+	if ((temp & 0x3f0f) != 0x000f) {
+		err("codec reg 26 status (0x%x) not ready!!", temp);
+		return;
+	}
 }
 
 
 /* --------------------------------------------------------------------- */
 
-extern inline void stop_adc(struct it8172_state *s)
+static inline void stop_adc(struct it8172_state *s)
 {
-    struct dmabuf* db = &s->dma_adc;
-    unsigned long flags;
-    unsigned char imc;
+	struct dmabuf* db = &s->dma_adc;
+	unsigned long flags;
+	unsigned char imc;
     
-    if (db->stopped)
-	return;
+	if (db->stopped)
+		return;
 
-    spin_lock_irqsave(&s->lock, flags);
+	spin_lock_irqsave(&s->lock, flags);
 
-    s->capcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
-    s->capcc |= CC_CSP;
-    outw(s->capcc, s->io+IT_AC_CAPCC);
+	s->capcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
+	s->capcc |= CC_CSP;
+	outw(s->capcc, s->io+IT_AC_CAPCC);
     
-    // disable capture interrupt
-    imc = inb(s->io+IT_AC_IMC);
-    outb(imc | IMC_CCIM, s->io+IT_AC_IMC);
+	// disable capture interrupt
+	imc = inb(s->io+IT_AC_IMC);
+	outb(imc | IMC_CCIM, s->io+IT_AC_IMC);
 
-    db->stopped = 1;
+	db->stopped = 1;
 
-    spin_unlock_irqrestore(&s->lock, flags);
+	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
-extern inline void stop_dac(struct it8172_state *s)
+static inline void stop_dac(struct it8172_state *s)
 {
-    struct dmabuf* db = &s->dma_dac;
-    unsigned long flags;
-    unsigned char imc;
+	struct dmabuf* db = &s->dma_dac;
+	unsigned long flags;
+	unsigned char imc;
     
-    if (db->stopped)
-	return;
+	if (db->stopped)
+		return;
 
-    spin_lock_irqsave(&s->lock, flags);
+	spin_lock_irqsave(&s->lock, flags);
 
-    s->pcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
-    s->pcc |= CC_CSP;
-    outw(s->pcc, s->io+IT_AC_PCC);
+	s->pcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
+	s->pcc |= CC_CSP;
+	outw(s->pcc, s->io+IT_AC_PCC);
     
-    // disable playback interrupt
-    imc = inb(s->io+IT_AC_IMC);
-    outb(imc | IMC_PCIM, s->io+IT_AC_IMC);
+	// disable playback interrupt
+	imc = inb(s->io+IT_AC_IMC);
+	outb(imc | IMC_PCIM, s->io+IT_AC_IMC);
 
-    db->stopped = 1;
+	db->stopped = 1;
     
-    spin_unlock_irqrestore(&s->lock, flags);
+	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
 static void start_dac(struct it8172_state *s)
 {
-    struct dmabuf* db = &s->dma_dac;
-    unsigned long flags;
-    unsigned char imc;
-    unsigned long buf1, buf2;
+	struct dmabuf* db = &s->dma_dac;
+	unsigned long flags;
+	unsigned char imc;
+	unsigned long buf1, buf2;
     
-    if (!db->stopped)
-	return;
+	if (!db->stopped)
+		return;
     
-    spin_lock_irqsave(&s->lock, flags);
+	spin_lock_irqsave(&s->lock, flags);
 
-    // reset Buffer 1 and 2 pointers to nextOut and nextOut+fragsize
-    buf1 = virt_to_bus(db->nextOut);
-    buf2 = buf1 + db->fragsize;
-    if (buf2 >= db->dmaaddr + db->dmasize)
-	buf2 -= db->dmasize;
-    
-    outl(buf1, s->io+IT_AC_PCB1STA);
-    outl(buf2, s->io+IT_AC_PCB2STA);
-    db->curBufPtr = IT_AC_PCB1STA;
-    
-    // enable playback interrupt
-    imc = inb(s->io+IT_AC_IMC);
-    outb(imc & ~IMC_PCIM, s->io+IT_AC_IMC);
+	// reset Buffer 1 and 2 pointers to nextOut and nextOut+fragsize
+	buf1 = virt_to_bus(db->nextOut);
+	buf2 = buf1 + db->fragsize;
+	if (buf2 >= db->dmaaddr + db->dmasize)
+		buf2 -= db->dmasize;
+    
+	outl(buf1, s->io+IT_AC_PCB1STA);
+	outl(buf2, s->io+IT_AC_PCB2STA);
+	db->curBufPtr = IT_AC_PCB1STA;
+    
+	// enable playback interrupt
+	imc = inb(s->io+IT_AC_IMC);
+	outb(imc & ~IMC_PCIM, s->io+IT_AC_IMC);
 
-    s->pcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
-    s->pcc |= CC_CA;
-    outw(s->pcc, s->io+IT_AC_PCC);
+	s->pcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
+	s->pcc |= CC_CA;
+	outw(s->pcc, s->io+IT_AC_PCC);
     
-    db->stopped = 0;
+	db->stopped = 0;
 
-    spin_unlock_irqrestore(&s->lock, flags);
+	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
 static void start_adc(struct it8172_state *s)
 {
-    struct dmabuf* db = &s->dma_adc;
-    unsigned long flags;
-    unsigned char imc;
-    unsigned long buf1, buf2;
+	struct dmabuf* db = &s->dma_adc;
+	unsigned long flags;
+	unsigned char imc;
+	unsigned long buf1, buf2;
     
-    if (!db->stopped)
-	return;
-
-    spin_lock_irqsave(&s->lock, flags);
+	if (!db->stopped)
+		return;
 
-    // reset Buffer 1 and 2 pointers to nextIn and nextIn+fragsize
-    buf1 = virt_to_bus(db->nextIn);
-    buf2 = buf1 + db->fragsize;
-    if (buf2 >= db->dmaaddr + db->dmasize)
-	buf2 -= db->dmasize;
-    
-    outl(buf1, s->io+IT_AC_CAPB1STA);
-    outl(buf2, s->io+IT_AC_CAPB2STA);
-    db->curBufPtr = IT_AC_CAPB1STA;
+	spin_lock_irqsave(&s->lock, flags);
 
-    // enable capture interrupt
-    imc = inb(s->io+IT_AC_IMC);
-    outb(imc & ~IMC_CCIM, s->io+IT_AC_IMC);
+	// reset Buffer 1 and 2 pointers to nextIn and nextIn+fragsize
+	buf1 = virt_to_bus(db->nextIn);
+	buf2 = buf1 + db->fragsize;
+	if (buf2 >= db->dmaaddr + db->dmasize)
+		buf2 -= db->dmasize;
+    
+	outl(buf1, s->io+IT_AC_CAPB1STA);
+	outl(buf2, s->io+IT_AC_CAPB2STA);
+	db->curBufPtr = IT_AC_CAPB1STA;
+
+	// enable capture interrupt
+	imc = inb(s->io+IT_AC_IMC);
+	outb(imc & ~IMC_CCIM, s->io+IT_AC_IMC);
 
-    s->capcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
-    s->capcc |= CC_CA;
-    outw(s->capcc, s->io+IT_AC_CAPCC);
+	s->capcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
+	s->capcc |= CC_CA;
+	outw(s->capcc, s->io+IT_AC_CAPCC);
     
-    db->stopped = 0;
+	db->stopped = 0;
 
-    spin_unlock_irqrestore(&s->lock, flags);
+	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
 /* --------------------------------------------------------------------- */
@@ -633,96 +655,105 @@
 #define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
 #define DMABUF_MINORDER 1
 
-extern inline void dealloc_dmabuf(struct it8172_state *s, struct dmabuf *db)
+static inline void dealloc_dmabuf(struct it8172_state *s, struct dmabuf *db)
 {
-    struct page *page, *pend;
+	struct page *page, *pend;
 
-    if (db->rawbuf) {
-	/* undo marking the pages as reserved */
-	pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-	for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-	    mem_map_unreserve(page);
-	pci_free_consistent(s->dev, PAGE_SIZE << db->buforder,
-			    db->rawbuf, db->dmaaddr);
-    }
-    db->rawbuf = db->nextIn = db->nextOut = NULL;
-    db->mapped = db->ready = 0;
+	if (db->rawbuf) {
+		/* undo marking the pages as reserved */
+		pend = virt_to_page(db->rawbuf +
+				    (PAGE_SIZE << db->buforder) - 1);
+		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+			mem_map_unreserve(page);
+		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder,
+				    db->rawbuf, db->dmaaddr);
+	}
+	db->rawbuf = db->nextIn = db->nextOut = NULL;
+	db->mapped = db->ready = 0;
 }
 
 static int prog_dmabuf(struct it8172_state *s, struct dmabuf *db,
 		       unsigned rate, unsigned fmt, unsigned reg)
 {
-    int order;
-    unsigned bytepersec;
-    unsigned bufs;
-    struct page *page, *pend;
-
-    if (!db->rawbuf) {
-	db->ready = db->mapped = 0;
-	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-	    if ((db->rawbuf = pci_alloc_consistent(s->dev,
-						   PAGE_SIZE << order,
-						   &db->dmaaddr)))
-		break;
-	if (!db->rawbuf)
-	    return -ENOMEM;
-	db->buforder = order;
-	/* now mark the pages as reserved;
-	   otherwise remap_page_range doesn't do what we want */
-	pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-	for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-	    mem_map_reserve(page);
-    }
-
-    db->count = 0;
-    db->nextIn = db->nextOut = db->rawbuf;
-    
-    bytepersec = rate << sample_shift[fmt];
-    bufs = PAGE_SIZE << db->buforder;
-    if (db->ossfragshift) {
-	if ((1000 << db->ossfragshift) < bytepersec)
-	    db->fragshift = ld2(bytepersec/1000);
-	else
-	    db->fragshift = db->ossfragshift;
-    } else {
-	db->fragshift = ld2(bytepersec/100/(db->subdivision ?
-					    db->subdivision : 1));
-	if (db->fragshift < 3)
-	    db->fragshift = 3;
-    }
-    db->numfrag = bufs >> db->fragshift;
-    while (db->numfrag < 4 && db->fragshift > 3) {
-	db->fragshift--;
+	int order;
+	unsigned bytepersec;
+	unsigned bufs;
+	struct page *page, *pend;
+
+	if (!db->rawbuf) {
+		db->ready = db->mapped = 0;
+		for (order = DMABUF_DEFAULTORDER;
+		     order >= DMABUF_MINORDER; order--)
+			if ((db->rawbuf =
+			     pci_alloc_consistent(s->dev,
+						  PAGE_SIZE << order,
+						  &db->dmaaddr)))
+				break;
+		if (!db->rawbuf)
+			return -ENOMEM;
+		db->buforder = order;
+		/* now mark the pages as reserved;
+		   otherwise remap_page_range doesn't do what we want */
+		pend = virt_to_page(db->rawbuf +
+				    (PAGE_SIZE << db->buforder) - 1);
+		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+			mem_map_reserve(page);
+	}
+
+	db->count = 0;
+	db->nextIn = db->nextOut = db->rawbuf;
+    
+	bytepersec = rate << sample_shift[fmt];
+	bufs = PAGE_SIZE << db->buforder;
+	if (db->ossfragshift) {
+		if ((1000 << db->ossfragshift) < bytepersec)
+			db->fragshift = ld2(bytepersec/1000);
+		else
+			db->fragshift = db->ossfragshift;
+	} else {
+		db->fragshift = ld2(bytepersec/100/(db->subdivision ?
+						    db->subdivision : 1));
+		if (db->fragshift < 3)
+			db->fragshift = 3;
+	}
 	db->numfrag = bufs >> db->fragshift;
-    }
-    db->fragsize = 1 << db->fragshift;
-    if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-	db->numfrag = db->ossmaxfrags;
-    db->fragsamples = db->fragsize >> sample_shift[fmt];
-    db->dmasize = db->numfrag << db->fragshift;
-    memset(db->rawbuf, (fmt & (CC_DF>>CC_FMT_BIT)) ? 0 : 0x80, db->dmasize);
+	while (db->numfrag < 4 && db->fragshift > 3) {
+		db->fragshift--;
+		db->numfrag = bufs >> db->fragshift;
+	}
+	db->fragsize = 1 << db->fragshift;
+	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+		db->numfrag = db->ossmaxfrags;
+	db->fragsamples = db->fragsize >> sample_shift[fmt];
+	db->dmasize = db->numfrag << db->fragshift;
+	memset(db->rawbuf, (fmt & (CC_DF>>CC_FMT_BIT)) ? 0 : 0x80, bufs);
     
-    // set data length register
-    outw(db->fragsize, s->io+reg+2);
-    db->ready = 1;
+#ifdef IT8172_VERBOSE_DEBUG
+	dbg("rate=%d, fragsize=%d, numfrag=%d, dmasize=%d",
+	    rate, db->fragsize, db->numfrag, db->dmasize);
+#endif
+
+	// set data length register
+	outw(db->fragsize, s->io+reg+2);
+	db->ready = 1;
 
-    return 0;
+	return 0;
 }
 
-extern inline int prog_dmabuf_adc(struct it8172_state *s)
+static inline int prog_dmabuf_adc(struct it8172_state *s)
 {
-    stop_adc(s);
-    return prog_dmabuf(s, &s->dma_adc, s->adcrate,
-		       (s->capcc & CC_FMT_MASK) >> CC_FMT_BIT,
-		       IT_AC_CAPCC);
+	stop_adc(s);
+	return prog_dmabuf(s, &s->dma_adc, s->adcrate,
+			   (s->capcc & CC_FMT_MASK) >> CC_FMT_BIT,
+			   IT_AC_CAPCC);
 }
 
-extern inline int prog_dmabuf_dac(struct it8172_state *s)
+static inline int prog_dmabuf_dac(struct it8172_state *s)
 {
-    stop_dac(s);
-    return prog_dmabuf(s, &s->dma_dac, s->dacrate,
-		       (s->pcc & CC_FMT_MASK) >> CC_FMT_BIT,
-		       IT_AC_PCC);
+	stop_dac(s);
+	return prog_dmabuf(s, &s->dma_dac, s->dacrate,
+			   (s->pcc & CC_FMT_MASK) >> CC_FMT_BIT,
+			   IT_AC_PCC);
 }
 
 
@@ -730,917 +761,1126 @@
 
 static void it8172_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-    struct it8172_state *s = (struct it8172_state *)dev_id;
-    struct dmabuf* dac = &s->dma_dac;
-    struct dmabuf* adc = &s->dma_adc;
-    unsigned char isc, vs;
-    unsigned short vol, mute;
-    unsigned long newptr;
-    
-    spin_lock(&s->lock);
-
-    isc = inb(s->io+IT_AC_ISC);
-
-    /* fastpath out, to ease interrupt sharing */
-    if (!(isc & (ISC_VCI | ISC_CCI | ISC_PCI)))
-	return;
-
-    /* clear audio interrupts first */
-    outb(isc | ISC_VCI | ISC_CCI | ISC_PCI, s->io+IT_AC_ISC);
-    
-    /* handle volume button events */
-    if (isc & ISC_VCI) {
-	vs = inb(s->io+IT_AC_VS);
-	outb(0, s->io+IT_AC_VS);
-	vol = inw(s->io+IT_AC_PCMOV);
-	mute = vol & PCMOV_PCMOM;
-	vol &= PCMOV_PCMLCG_MASK;
-	if ((vs & VS_VUP) && vol > 0)
-	    vol--;
-	if ((vs & VS_VDP) && vol < 0x1f)
-	    vol++;
-	vol |= (vol << PCMOV_PCMRCG_BIT);
-	if (vs & VS_VMP)
-	    vol |= (mute ^ PCMOV_PCMOM);
-	outw(vol, s->io+IT_AC_PCMOV);
-    }
-    
-    /* update capture pointers */
-    if (isc & ISC_CCI) {
-	if (adc->count > adc->dmasize - adc->fragsize) {
-	    // Overrun. Stop ADC and log the error
-	    stop_adc(s);
-	    adc->error++;
-	    printk(KERN_INFO PFX "adc overrun\n");
-	} else {
-	    newptr = virt_to_bus(adc->nextIn) + 2*adc->fragsize;
-	    if (newptr >= adc->dmaaddr + adc->dmasize)
-		newptr -= adc->dmasize;
+	struct it8172_state *s = (struct it8172_state *)dev_id;
+	struct dmabuf* dac = &s->dma_dac;
+	struct dmabuf* adc = &s->dma_adc;
+	unsigned char isc, vs;
+	unsigned short vol, mute;
+	unsigned long newptr;
+    
+	spin_lock(&s->lock);
+
+	isc = inb(s->io+IT_AC_ISC);
+
+	/* fastpath out, to ease interrupt sharing */
+	if (!(isc & (ISC_VCI | ISC_CCI | ISC_PCI))) {
+		spin_unlock(&s->lock);
+		return;
+	}
+    
+	/* clear audio interrupts first */
+	outb(isc | ISC_VCI | ISC_CCI | ISC_PCI, s->io+IT_AC_ISC);
+    
+	/* handle volume button events (ignore if S/PDIF enabled) */
+	if ((isc & ISC_VCI) && s->spdif_volume == -1) {
+		vs = inb(s->io+IT_AC_VS);
+		outb(0, s->io+IT_AC_VS);
+		vol = inw(s->io+IT_AC_PCMOV);
+		mute = vol & PCMOV_PCMOM;
+		vol &= PCMOV_PCMLCG_MASK;
+		if ((vs & VS_VUP) && vol > 0)
+			vol--;
+		if ((vs & VS_VDP) && vol < 0x1f)
+			vol++;
+		vol |= (vol << PCMOV_PCMRCG_BIT);
+		if (vs & VS_VMP)
+			vol |= (mute ^ PCMOV_PCMOM);
+		outw(vol, s->io+IT_AC_PCMOV);
+	}
+    
+	/* update capture pointers */
+	if (isc & ISC_CCI) {
+		if (adc->count > adc->dmasize - adc->fragsize) {
+			// Overrun. Stop ADC and log the error
+			stop_adc(s);
+			adc->error++;
+			dbg("adc overrun");
+		} else {
+			newptr = virt_to_bus(adc->nextIn) + 2*adc->fragsize;
+			if (newptr >= adc->dmaaddr + adc->dmasize)
+				newptr -= adc->dmasize;
 	    
-	    outl(newptr, s->io+adc->curBufPtr);
-	    adc->curBufPtr = (adc->curBufPtr == IT_AC_CAPB1STA) ?
-		IT_AC_CAPB2STA : IT_AC_CAPB1STA;
+			outl(newptr, s->io+adc->curBufPtr);
+			adc->curBufPtr = (adc->curBufPtr == IT_AC_CAPB1STA) ?
+				IT_AC_CAPB2STA : IT_AC_CAPB1STA;
 	    
-	    adc->nextIn += adc->fragsize;
-	    if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-		adc->nextIn -= adc->dmasize;
+			adc->nextIn += adc->fragsize;
+			if (adc->nextIn >= adc->rawbuf + adc->dmasize)
+				adc->nextIn -= adc->dmasize;
 	    
-	    adc->count += adc->fragsize;
-	    adc->total_bytes += adc->fragsize;
+			adc->count += adc->fragsize;
+			adc->total_bytes += adc->fragsize;
 
-	    /* wake up anybody listening */
-	    if (waitqueue_active(&adc->wait))
-		wake_up_interruptible(&adc->wait);
-	}
-    }
-    
-    /* update playback pointers */
-    if (isc & ISC_PCI) {
-	newptr = virt_to_bus(dac->nextOut) + 2*dac->fragsize;
-	if (newptr >= dac->dmaaddr + dac->dmasize)
-	    newptr -= dac->dmasize;
+			/* wake up anybody listening */
+			if (waitqueue_active(&adc->wait))
+				wake_up_interruptible(&adc->wait);
+		}
+	}
+    
+	/* update playback pointers */
+	if (isc & ISC_PCI) {
+		newptr = virt_to_bus(dac->nextOut) + 2*dac->fragsize;
+		if (newptr >= dac->dmaaddr + dac->dmasize)
+			newptr -= dac->dmasize;
 	
-	outl(newptr, s->io+dac->curBufPtr);
-	dac->curBufPtr = (dac->curBufPtr == IT_AC_PCB1STA) ?
-	    IT_AC_PCB2STA : IT_AC_PCB1STA;
+		outl(newptr, s->io+dac->curBufPtr);
+		dac->curBufPtr = (dac->curBufPtr == IT_AC_PCB1STA) ?
+			IT_AC_PCB2STA : IT_AC_PCB1STA;
 	
-	dac->nextOut += dac->fragsize;
-	if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-	    dac->nextOut -= dac->dmasize;
+		dac->nextOut += dac->fragsize;
+		if (dac->nextOut >= dac->rawbuf + dac->dmasize)
+			dac->nextOut -= dac->dmasize;
 	
-	dac->count -= dac->fragsize;
-	dac->total_bytes += dac->fragsize;
+		dac->count -= dac->fragsize;
+		dac->total_bytes += dac->fragsize;
 
-	/* wake up anybody listening */
-	if (waitqueue_active(&dac->wait))
-	    wake_up_interruptible(&dac->wait);
+		/* wake up anybody listening */
+		if (waitqueue_active(&dac->wait))
+			wake_up_interruptible(&dac->wait);
 	
-	if (dac->count <= 0)
-	    stop_dac(s);
-    }
+		if (dac->count <= 0)
+			stop_dac(s);
+	}
     
-    spin_unlock(&s->lock);
+	spin_unlock(&s->lock);
 }
 
 /* --------------------------------------------------------------------- */
 
 static loff_t it8172_llseek(struct file *file, loff_t offset, int origin)
 {
-    return -ESPIPE;
+	return -ESPIPE;
 }
 
 
 static int it8172_open_mixdev(struct inode *inode, struct file *file)
 {
-    int minor = MINOR(inode->i_rdev);
-    struct list_head *list;
-    struct it8172_state *s;
-
-    for (list = devs.next; ; list = list->next) {
-	if (list == &devs)
-	    return -ENODEV;
-	s = list_entry(list, struct it8172_state, devs);
-	if (s->codec.dev_mixer == minor)
-	    break;
-    }
-    file->private_data = s;
-    return 0;
+	int minor = MINOR(inode->i_rdev);
+	struct list_head *list;
+	struct it8172_state *s;
+
+	for (list = devs.next; ; list = list->next) {
+		if (list == &devs)
+			return -ENODEV;
+		s = list_entry(list, struct it8172_state, devs);
+		if (s->codec.dev_mixer == minor)
+			break;
+	}
+	file->private_data = s;
+	return 0;
 }
 
 static int it8172_release_mixdev(struct inode *inode, struct file *file)
 {
-    return 0;
+	return 0;
+}
+
+
+static u16
+cvt_ossvol(unsigned int gain)
+{
+	u16 ret;
+    
+	if (gain == 0)
+		return 0;
+    
+	if (gain > 100)
+		gain = 100;
+    
+	ret = (100 - gain + 32) / 4;
+	ret = ret > 31 ? 31 : ret;
+	return ret;
 }
 
 
 static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
 			unsigned long arg)
 {
-    return codec->mixer_ioctl(codec, cmd, arg);
+	struct it8172_state *s = (struct it8172_state *)codec->private_data;
+	unsigned int left, right;
+	unsigned long flags;
+	int val;
+	u16 vol;
+    
+	/*
+	 * When we are in S/PDIF mode, we want to disable any analog output so
+	 * we filter the master/PCM channel volume ioctls.
+	 *
+	 * Also filter I2S channel, which AC'97 knows nothing about.
+	 */
+
+	switch (cmd) {
+	case SOUND_MIXER_WRITE_VOLUME:
+		// if not in S/PDIF mode, pass to AC'97
+		if (s->spdif_volume == -1)
+			break;
+		return 0;
+	case SOUND_MIXER_WRITE_PCM:
+		// if not in S/PDIF mode, pass to AC'97
+		if (s->spdif_volume == -1)
+			break;
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		right = ((val >> 8)  & 0xff);
+		left = (val  & 0xff);
+		if (right > 100)
+			right = 100;
+		if (left > 100)
+			left = 100;
+		s->spdif_volume = (right << 8) | left;
+		vol = cvt_ossvol(left);
+		vol |= (cvt_ossvol(right) << PCMOV_PCMRCG_BIT);
+		if (vol == 0)
+			vol = PCMOV_PCMOM; // mute
+		spin_lock_irqsave(&s->lock, flags);
+		outw(vol, s->io+IT_AC_PCMOV);
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(s->spdif_volume, (int *)arg);
+	case SOUND_MIXER_READ_PCM:
+		// if not in S/PDIF mode, pass to AC'97
+		if (s->spdif_volume == -1)
+			break;
+		return put_user(s->spdif_volume, (int *)arg);
+	case SOUND_MIXER_WRITE_I2S:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		right = ((val >> 8)  & 0xff);
+		left = (val  & 0xff);
+		if (right > 100)
+			right = 100;
+		if (left > 100)
+			left = 100;
+		s->i2s_volume = (right << 8) | left;
+		vol = cvt_ossvol(left);
+		vol |= (cvt_ossvol(right) << I2SV_I2SRCG_BIT);
+		if (vol == 0)
+			vol = I2SV_I2SOM; // mute
+		outw(vol, s->io+IT_AC_I2SV);
+		return put_user(s->i2s_volume, (int *)arg);
+	case SOUND_MIXER_READ_I2S:
+		return put_user(s->i2s_volume, (int *)arg);
+	case SOUND_MIXER_WRITE_RECSRC:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val & SOUND_MASK_I2S) {
+			s->i2s_recording = 1;
+			outb(DRSS_I2S, s->io+IT_AC_DRSS);
+			return 0;
+		} else {
+			s->i2s_recording = 0;
+			outb(DRSS_AC97_PRIM, s->io+IT_AC_DRSS);
+			// now let AC'97 select record source
+			break;
+		}
+	case SOUND_MIXER_READ_RECSRC:
+		if (s->i2s_recording)
+			return put_user(SOUND_MASK_I2S, (int *)arg);
+		else
+			// let AC'97 report recording source
+			break;
+	}
+
+	return codec->mixer_ioctl(codec, cmd, arg);
 }
 
 static int it8172_ioctl_mixdev(struct inode *inode, struct file *file,
 			       unsigned int cmd, unsigned long arg)
 {
-    struct it8172_state *s = (struct it8172_state *)file->private_data;
-    struct ac97_codec *codec = &s->codec;
+	struct it8172_state *s = (struct it8172_state *)file->private_data;
+	struct ac97_codec *codec = &s->codec;
 
-    return mixdev_ioctl(codec, cmd, arg);
+	return mixdev_ioctl(codec, cmd, arg);
 }
 
 static /*const*/ struct file_operations it8172_mixer_fops = {
-    owner:	THIS_MODULE,
-    llseek:	it8172_llseek,
-    ioctl:	it8172_ioctl_mixdev,
-    open:	it8172_open_mixdev,
-    release:	it8172_release_mixdev,
+	owner:	THIS_MODULE,
+	llseek:	it8172_llseek,
+	ioctl:	it8172_ioctl_mixdev,
+	open:	it8172_open_mixdev,
+	release:	it8172_release_mixdev,
 };
 
 /* --------------------------------------------------------------------- */
 
 static int drain_dac(struct it8172_state *s, int nonblock)
 {
-    unsigned long flags;
-    int count, tmo;
+	unsigned long flags;
+	int count, tmo;
 	
-    if (s->dma_dac.mapped || !s->dma_dac.ready)
-	return 0;
+	if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
+		return 0;
 
-    for (;;) {
-	spin_lock_irqsave(&s->lock, flags);
-	count = s->dma_dac.count;
-	spin_unlock_irqrestore(&s->lock, flags);
-	if (count <= 0)
-	    break;
+	for (;;) {
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count <= 0)
+			break;
+		if (signal_pending(current))
+			break;
+		//if (nonblock)
+		//return -EBUSY;
+		tmo = 1000 * count / s->dacrate;
+		tmo >>= sample_shift[(s->pcc & CC_FMT_MASK) >> CC_FMT_BIT];
+		it8172_delay(tmo);
+	}
 	if (signal_pending(current))
-	    break;
-	if (nonblock)
-	    return -EBUSY;
-	tmo = 1000 * count / s->dacrate;
-	tmo >>= sample_shift[(s->pcc & CC_FMT_MASK) >> CC_FMT_BIT];
-	it8172_delay(tmo);
-    }
-    if (signal_pending(current))
-	return -ERESTARTSYS;
-    return 0;
+		return -ERESTARTSYS;
+	return 0;
 }
 
 /* --------------------------------------------------------------------- */
 
+
+/*
+ * Copy audio data to/from user buffer from/to dma buffer, taking care
+ * that we wrap when reading/writing the dma buffer. Returns actual byte
+ * count written to or read from the dma buffer.
+ */
+static int copy_dmabuf_user(struct dmabuf *db, char* userbuf,
+			    int count, int to_user)
+{
+	char* bufptr = to_user ? db->nextOut : db->nextIn;
+	char* bufend = db->rawbuf + db->dmasize;
+	
+	if (bufptr + count > bufend) {
+		int partial = (int)(bufend - bufptr);
+		if (to_user) {
+			if (copy_to_user(userbuf, bufptr, partial))
+				return -EFAULT;
+			if (copy_to_user(userbuf + partial, db->rawbuf,
+					 count - partial))
+				return -EFAULT;
+		} else {
+			if (copy_from_user(bufptr, userbuf, partial))
+				return -EFAULT;
+			if (copy_from_user(db->rawbuf,
+					   userbuf + partial,
+					   count - partial))
+				return -EFAULT;
+		}
+	} else {
+		if (to_user) {
+			if (copy_to_user(userbuf, bufptr, count))
+				return -EFAULT;
+		} else {
+			if (copy_from_user(bufptr, userbuf, count))
+				return -EFAULT;
+		}
+	}
+	
+	return count;
+}
+
+
 static ssize_t it8172_read(struct file *file, char *buffer,
 			   size_t count, loff_t *ppos)
 {
-    struct it8172_state *s = (struct it8172_state *)file->private_data;
-    struct dmabuf *db = &s->dma_adc;
-    ssize_t ret;
-    unsigned long flags;
-    int cnt, bufcnt, avail;
-
-    if (ppos != &file->f_pos)
-	return -ESPIPE;
-    if (db->mapped)
-	return -ENXIO;
-    if (!access_ok(VERIFY_WRITE, buffer, count))
-	return -EFAULT;
-    ret = 0;
-
-    while (count > 0) {
-	// wait for samples in capture buffer
-	do {
-	    spin_lock_irqsave(&s->lock, flags);
-	    if (db->stopped)
-		start_adc(s);
-	    avail = db->count;
-	    spin_unlock_irqrestore(&s->lock, flags);
-	    if (avail <= 0) {
-		if (file->f_flags & O_NONBLOCK) {
-		    if (!ret)
-			ret = -EAGAIN;
-		    return ret;
-		}
-		interruptible_sleep_on(&db->wait);
-		if (signal_pending(current)) {
-		    if (!ret)
-			ret = -ERESTARTSYS;
-		    return ret;
-		}
-	    }
-	} while (avail <= 0);
-
-	cnt = count > avail ? avail : count;
-	bufcnt = cnt;
-	if (cnt % db->fragsize) {
-	    // round count up to nearest fragment
-	    int newcnt = db->fragsize * ((cnt + db->fragsize) / db->fragsize);
-	    cnt = newcnt;
-	}
-
-	// copy from nextOut to user
-	if (copy_to_user(buffer, db->nextOut, bufcnt)) {
-	    if (!ret)
-		ret = -EFAULT;
-	    return ret;
-	}
+	struct it8172_state *s = (struct it8172_state *)file->private_data;
+	struct dmabuf *db = &s->dma_adc;
+	ssize_t ret;
+	unsigned long flags;
+	int cnt, remainder, avail;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	while (count > 0) {
+		// wait for samples in capture buffer
+		do {
+			spin_lock_irqsave(&s->lock, flags);
+			if (db->stopped)
+				start_adc(s);
+			avail = db->count;
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					return ret;
+				}
+				interruptible_sleep_on(&db->wait);
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					return ret;
+				}
+			}
+		} while (avail <= 0);
+
+		// copy from nextOut to user
+		if ((cnt = copy_dmabuf_user(db, buffer, count > avail ?
+					    avail : count, 1)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			return ret;
+		}
 
+		spin_lock_irqsave(&s->lock, flags);
+		db->count -= cnt;
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		db->nextOut += cnt;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;	
+
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+	} // while (count > 0)
+
+	/*
+	 * See if the dma buffer count after this read call is
+	 * aligned on a fragsize boundary. If not, read from
+	 * buffer until we reach a boundary, and let's hope this
+	 * is just the last remainder of an audio record. If not
+	 * it means the user is not reading in fragsize chunks, in
+	 * which case it's his/her fault that there are audio gaps
+	 * in their record.
+	 */
 	spin_lock_irqsave(&s->lock, flags);
-	db->count -= cnt;
+	remainder = db->count % db->fragsize;
+	if (remainder) {
+		db->nextOut += remainder;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+		db->count -= remainder;
+	}
 	spin_unlock_irqrestore(&s->lock, flags);
 
-	db->nextOut += cnt;
-	if (db->nextOut >= db->rawbuf + db->dmasize)
-	    db->nextOut -= db->dmasize;	
-
-	count -= bufcnt;
-	buffer += bufcnt;
-	ret += bufcnt;
-    } // while (count > 0)
-
-    return ret;
+	return ret;
 }
 
 static ssize_t it8172_write(struct file *file, const char *buffer,
 			    size_t count, loff_t *ppos)
 {
-    struct it8172_state *s = (struct it8172_state *)file->private_data;
-    struct dmabuf *db = &s->dma_dac;
-    ssize_t ret;
-    unsigned long flags;
-    int cnt, bufcnt, avail;
-
-    if (ppos != &file->f_pos)
-	return -ESPIPE;
-    if (db->mapped)
-	return -ENXIO;
-    if (!access_ok(VERIFY_READ, buffer, count))
-	return -EFAULT;
-    ret = 0;
-    
-    while (count > 0) {
-	// wait for space in playback buffer
-	do {
-	    spin_lock_irqsave(&s->lock, flags);
-	    avail = db->dmasize - db->count;
-	    spin_unlock_irqrestore(&s->lock, flags);
-	    if (avail <= 0) {
-		if (file->f_flags & O_NONBLOCK) {
-		    if (!ret)
-			ret = -EAGAIN;
-		    return ret;
-		}
-		interruptible_sleep_on(&db->wait);
-		if (signal_pending(current)) {
-		    if (!ret)
-			ret = -ERESTARTSYS;
-		    return ret;
-		}
-	    }
-	} while (avail <= 0);
+	struct it8172_state *s = (struct it8172_state *)file->private_data;
+	struct dmabuf *db = &s->dma_dac;
+	ssize_t ret;
+	unsigned long flags;
+	int cnt, remainder, avail;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+	ret = 0;
+    
+	while (count > 0) {
+		// wait for space in playback buffer
+		do {
+			spin_lock_irqsave(&s->lock, flags);
+			avail = db->dmasize - db->count;
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					return ret;
+				}
+				interruptible_sleep_on(&db->wait);
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					return ret;
+				}
+			}
+		} while (avail <= 0);
 	
-	cnt = count > avail ? avail : count;
-	// copy to nextIn
-	if (copy_from_user(db->nextIn, buffer, cnt)) {
-	    if (!ret)
-		ret = -EFAULT;
-	    return ret;
-	}
-
-	bufcnt = cnt;
-	if (cnt % db->fragsize) {
-	    // round count up to nearest fragment, and fill remainder of
-	    // fragment with silence
-	    int newcnt = db->fragsize * ((cnt + db->fragsize) / db->fragsize);
-	    memset(db->nextIn + cnt, (s->pcc & CC_DF) ? 0 : 0x80, newcnt - cnt);
-	    cnt = newcnt;
-	}
+		// copy to nextIn
+		if ((cnt = copy_dmabuf_user(db, (char*)buffer,
+					    count > avail ?
+					    avail : count, 0)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			return ret;
+		}
 
-	spin_lock_irqsave(&s->lock, flags);
-	db->count += cnt;
-	if (db->stopped)
-	    start_dac(s);
-	spin_unlock_irqrestore(&s->lock, flags);
+		spin_lock_irqsave(&s->lock, flags);
+		db->count += cnt;
+		if (db->stopped)
+			start_dac(s);
+		spin_unlock_irqrestore(&s->lock, flags);
 	
-	db->nextIn += cnt;
-	if (db->nextIn >= db->rawbuf + db->dmasize)
-	    db->nextIn -= db->dmasize;
+		db->nextIn += cnt;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
 	
-	count -= bufcnt;
-	buffer += bufcnt;
-	ret += bufcnt;
-    } // while (count > 0)
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+	} // while (count > 0)
 	
-    return ret;
+	/*
+	 * See if the dma buffer count after this write call is
+	 * aligned on a fragsize boundary. If not, fill buffer
+	 * with silence to the next boundary, and let's hope this
+	 * is just the last remainder of an audio playback. If not
+	 * it means the user is not sending us fragsize chunks, in
+	 * which case it's his/her fault that there are audio gaps
+	 * in their playback.
+	 */
+	spin_lock_irqsave(&s->lock, flags);
+	remainder = db->count % db->fragsize;
+	if (remainder) {
+		int fill_cnt = db->fragsize - remainder;
+		memset(db->nextIn, 0, fill_cnt);
+		db->nextIn += fill_cnt;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+		db->count += fill_cnt;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	return ret;
 }
 
 /* No kernel lock - we have our own spinlock */
 static unsigned int it8172_poll(struct file *file,
 				struct poll_table_struct *wait)
 {
-    struct it8172_state *s = (struct it8172_state *)file->private_data;
-    unsigned long flags;
-    unsigned int mask = 0;
-
-    if (file->f_mode & FMODE_WRITE)
-	poll_wait(file, &s->dma_dac.wait, wait);
-    if (file->f_mode & FMODE_READ)
-	poll_wait(file, &s->dma_adc.wait, wait);
-    spin_lock_irqsave(&s->lock, flags);
-    if (file->f_mode & FMODE_READ) {
-	if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-	    mask |= POLLIN | POLLRDNORM;
-    }
-    if (file->f_mode & FMODE_WRITE) {
-	if (s->dma_dac.mapped) {
-	    if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-		mask |= POLLOUT | POLLWRNORM;
-	} else {
-	    if ((signed)s->dma_dac.dmasize >=
-		s->dma_dac.count + (signed)s->dma_dac.fragsize)
-		mask |= POLLOUT | POLLWRNORM;
-	}
-    }
-    spin_unlock_irqrestore(&s->lock, flags);
-    return mask;
+	struct it8172_state *s = (struct it8172_state *)file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac.ready)
+			return 0;
+		poll_wait(file, &s->dma_dac.wait, wait);
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready)
+			return 0;
+		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+	
+	spin_lock_irqsave(&s->lock, flags);
+	if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if (s->dma_dac.mapped) {
+			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
+				mask |= POLLOUT | POLLWRNORM;
+		} else {
+			if ((signed)s->dma_dac.dmasize >=
+			    s->dma_dac.count + (signed)s->dma_dac.fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return mask;
 }
 
 static int it8172_mmap(struct file *file, struct vm_area_struct *vma)
 {
-    struct it8172_state *s = (struct it8172_state *)file->private_data;
-    struct dmabuf *db;
-    unsigned long size;
-
-    lock_kernel();
-    if (vma->vm_flags & VM_WRITE)
-	db = &s->dma_dac;
-    else if (vma->vm_flags & VM_READ)
-	db = &s->dma_adc;
-    else {
-	unlock_kernel();
-	return -EINVAL;
-    }
-    if (vma->vm_pgoff != 0) {
-	unlock_kernel();
-	return -EINVAL;
-    }
-    size = vma->vm_end - vma->vm_start;
-    if (size > (PAGE_SIZE << db->buforder)) {
-	unlock_kernel();
-	return -EINVAL;
-    }
-    if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
-			 size, vma->vm_page_prot)) {
+	struct it8172_state *s = (struct it8172_state *)file->private_data;
+	struct dmabuf *db;
+	unsigned long size;
+
+	lock_kernel();
+	if (vma->vm_flags & VM_WRITE)
+		db = &s->dma_dac;
+	else if (vma->vm_flags & VM_READ)
+		db = &s->dma_adc;
+	else {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	if (vma->vm_pgoff != 0) {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	size = vma->vm_end - vma->vm_start;
+	if (size > (PAGE_SIZE << db->buforder)) {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
+			     size, vma->vm_page_prot)) {
+		unlock_kernel();
+		return -EAGAIN;
+	}
+	db->mapped = 1;
 	unlock_kernel();
-	return -EAGAIN;
-    }
-    db->mapped = 1;
-    unlock_kernel();
-    return 0;
+	return 0;
 }
 
 
 #ifdef IT8172_VERBOSE_DEBUG
 static struct ioctl_str_t {
-    unsigned int cmd;
-    const char* str;
+	unsigned int cmd;
+	const char* str;
 } ioctl_str[] = {
-    {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
-    {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
-    {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
-    {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
-    {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
-    {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
-    {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
-    {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
-    {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
-    {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
-    {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
-    {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
-    {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
-    {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
-    {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
-    {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
-    {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
-    {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
-    {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
-    {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
-    {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
-    {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
-    {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
-    {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
-    {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
-    {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
-    {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
-    {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
-    {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
-    {OSS_GETVERSION, "OSS_GETVERSION"},
-    {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
-    {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
-    {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
-    {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+	{SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+	{SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+	{SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+	{SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+	{SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+	{SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+	{SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+	{SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+	{SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+	{SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+	{SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+	{SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+	{SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+	{SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+	{SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+	{SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+	{SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+	{SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+	{SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+	{SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+	{SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+	{SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+	{SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+	{SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+	{SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+	{SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+	{SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+	{SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+	{SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+	{OSS_GETVERSION, "OSS_GETVERSION"},
+	{SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+	{SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+	{SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+	{SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
 };
 #endif    
 
 static int it8172_ioctl(struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
-    struct it8172_state *s = (struct it8172_state *)file->private_data;
-    unsigned long flags;
-    audio_buf_info abinfo;
-    count_info cinfo;
-    int count;
-    int val, mapped, ret, diff;
+	struct it8172_state *s = (struct it8172_state *)file->private_data;
+	unsigned long flags;
+	audio_buf_info abinfo;
+	count_info cinfo;
+	int count;
+	int val, mapped, ret, diff;
 
-    mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-	((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
 
 #ifdef IT8172_VERBOSE_DEBUG
-    for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
-	if (ioctl_str[count].cmd == cmd)
-	    break;
-    }
-    if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
-	printk(KERN_INFO PFX "ioctl %s\n", ioctl_str[count].str);
-    else
-	printk(KERN_INFO PFX "ioctl unknown, 0x%x\n", cmd);
+	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+		if (ioctl_str[count].cmd == cmd)
+			break;
+	}
+	if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
+		dbg("ioctl %s, arg=0x%08x",
+		    ioctl_str[count].str, (unsigned int)arg);
+	else
+		dbg("ioctl unknown, 0x%x", cmd);
 #endif
     
-    switch (cmd) {
-    case OSS_GETVERSION:
-	return put_user(SOUND_VERSION, (int *)arg);
-
-    case SNDCTL_DSP_SYNC:
-	if (file->f_mode & FMODE_WRITE)
-	    return drain_dac(s, file->f_flags & O_NONBLOCK);
-	return 0;
+	switch (cmd) {
+	case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *)arg);
+
+	case SNDCTL_DSP_SYNC:
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(s, file->f_flags & O_NONBLOCK);
+		return 0;
 		
-    case SNDCTL_DSP_SETDUPLEX:
-	return 0;
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
 
-    case SNDCTL_DSP_GETCAPS:
-	return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-			DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+				DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
 		
-    case SNDCTL_DSP_RESET:
-	if (file->f_mode & FMODE_WRITE) {
-	    stop_dac(s);
-	    synchronize_irq();
-	    s->dma_dac.count = s->dma_dac.total_bytes = 0;
-	    s->dma_dac.nextIn = s->dma_dac.nextOut = s->dma_dac.rawbuf;
-	}
-	if (file->f_mode & FMODE_READ) {
-	    stop_adc(s);
-	    synchronize_irq();
-	    s->dma_adc.count = s->dma_adc.total_bytes = 0;
-	    s->dma_adc.nextIn = s->dma_adc.nextOut = s->dma_adc.rawbuf;
-	}
-	return 0;
+	case SNDCTL_DSP_RESET:
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			synchronize_irq();
+			s->dma_dac.count = s->dma_dac.total_bytes = 0;
+			s->dma_dac.nextIn = s->dma_dac.nextOut =
+				s->dma_dac.rawbuf;
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			synchronize_irq();
+			s->dma_adc.count = s->dma_adc.total_bytes = 0;
+			s->dma_adc.nextIn = s->dma_adc.nextOut =
+				s->dma_adc.rawbuf;
+		}
+		return 0;
 
-    case SNDCTL_DSP_SPEED:
-	if (get_user(val, (int *)arg))
-	    return -EFAULT;
-	if (val >= 0) {
-	    if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		set_adc_rate(s, val);
-		if ((ret = prog_dmabuf_adc(s)))
-		    return ret;
-	    }
-	    if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-		set_dac_rate(s, val);
-		if ((ret = prog_dmabuf_dac(s)))
-		    return ret;
-	    }
-	}
-	return put_user((file->f_mode & FMODE_READ) ?
-			s->adcrate : s->dacrate, (int *)arg);
-
-    case SNDCTL_DSP_STEREO:
-	if (get_user(val, (int *)arg))
-	    return -EFAULT;
-	if (file->f_mode & FMODE_READ) {
-	    stop_adc(s);
-	    if (val)
-		s->capcc |= CC_SM;
-	    else
-		s->capcc &= ~CC_SM;
-	    outw(s->capcc, s->io+IT_AC_CAPCC);
-	    if ((ret = prog_dmabuf_adc(s)))
-		return ret;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-	    stop_dac(s);
-	    if (val)
-		s->pcc |= CC_SM;
-	    else
-		s->pcc &= ~CC_SM;
-	    outw(s->pcc, s->io+IT_AC_PCC);
-	    if ((ret = prog_dmabuf_dac(s)))
-		return ret;
-	}
-	return 0;
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val >= 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				set_adc_rate(s, val);
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				set_dac_rate(s, val);
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		}
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->adcrate : s->dacrate, (int *)arg);
 
-    case SNDCTL_DSP_CHANNELS:
-	if (get_user(val, (int *)arg))
-	    return -EFAULT;
-	if (val != 0) {
-	    if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		if (val >= 2) {
-		    val = 2;
-		    s->capcc |= CC_SM;
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			if (val)
+				s->capcc |= CC_SM;
+			else
+				s->capcc &= ~CC_SM;
+			outw(s->capcc, s->io+IT_AC_CAPCC);
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
 		}
-		else
-		    s->capcc &= ~CC_SM;
-		outw(s->capcc, s->io+IT_AC_CAPCC);
-		if ((ret = prog_dmabuf_adc(s)))
-		    return ret;
-	    }
-	    if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-		switch (val) {
-		case 1:
-		    s->pcc &= ~CC_SM;
-		    break;
-		case 2:
-		    s->pcc |= CC_SM;
-		    break;
-		default:
-		    // FIX! support multichannel???
-		    val = 2;
-		    s->pcc |= CC_SM;
-		    break;
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			if (val)
+				s->pcc |= CC_SM;
+			else
+				s->pcc &= ~CC_SM;
+			outw(s->pcc, s->io+IT_AC_PCC);
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
 		}
-		outw(s->pcc, s->io+IT_AC_PCC);
-		if ((ret = prog_dmabuf_dac(s)))
-		    return ret;
-	    }
-	}
-	return put_user(val, (int *)arg);
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val != 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				if (val >= 2) {
+					val = 2;
+					s->capcc |= CC_SM;
+				}
+				else
+					s->capcc &= ~CC_SM;
+				outw(s->capcc, s->io+IT_AC_CAPCC);
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				switch (val) {
+				case 1:
+					s->pcc &= ~CC_SM;
+					break;
+				case 2:
+					s->pcc |= CC_SM;
+					break;
+				default:
+					// FIX! support multichannel???
+					val = 2;
+					s->pcc |= CC_SM;
+					break;
+				}
+				outw(s->pcc, s->io+IT_AC_PCC);
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		}
+		return put_user(val, (int *)arg);
 		
-    case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-	return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+		return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
 		
-    case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-	if (get_user(val, (int *)arg))
-	    return -EFAULT;
-	if (val != AFMT_QUERY) {
-	    if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		if (val == AFMT_S16_LE)
-		    s->capcc |= CC_DF;
-		else {
-		    val = AFMT_U8;
-		    s->capcc &= ~CC_DF;
-		}
-		outw(s->capcc, s->io+IT_AC_CAPCC);
-		if ((ret = prog_dmabuf_adc(s)))
-		    return ret;
-	    }
-	    if (file->f_mode & FMODE_WRITE) {
-		stop_dac(s);
-		if (val == AFMT_S16_LE)
-		    s->pcc |= CC_DF;
-		else {
-		    val = AFMT_U8;
-		    s->pcc &= ~CC_DF;
+	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val != AFMT_QUERY) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				if (val == AFMT_S16_LE)
+					s->capcc |= CC_DF;
+				else {
+					val = AFMT_U8;
+					s->capcc &= ~CC_DF;
+				}
+				outw(s->capcc, s->io+IT_AC_CAPCC);
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				if (val == AFMT_S16_LE)
+					s->pcc |= CC_DF;
+				else {
+					val = AFMT_U8;
+					s->pcc &= ~CC_DF;
+				}
+				outw(s->pcc, s->io+IT_AC_PCC);
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		} else {
+			if (file->f_mode & FMODE_READ)
+				val = (s->capcc & CC_DF) ?
+					AFMT_S16_LE : AFMT_U8;
+			else
+				val = (s->pcc & CC_DF) ?
+					AFMT_S16_LE : AFMT_U8;
 		}
-		outw(s->pcc, s->io+IT_AC_PCC);
-		if ((ret = prog_dmabuf_dac(s)))
-		    return ret;
-	    }
-	} else {
-	    if (file->f_mode & FMODE_READ)
-		val = (s->capcc & CC_DF) ? AFMT_S16_LE : AFMT_U8;
-	    else
-		val = (s->pcc & CC_DF) ? AFMT_S16_LE : AFMT_U8;
-	}
-	return put_user(val, (int *)arg);
+		return put_user(val, (int *)arg);
 		
-    case SNDCTL_DSP_POST:
-	return 0;
+	case SNDCTL_DSP_POST:
+		return 0;
 
-    case SNDCTL_DSP_GETTRIGGER:
-	val = 0;
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
-	    val |= PCM_ENABLE_INPUT;
-	if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
-	    val |= PCM_ENABLE_OUTPUT;
-	spin_unlock_irqrestore(&s->lock, flags);
-	return put_user(val, (int *)arg);
+	case SNDCTL_DSP_GETTRIGGER:
+		val = 0;
+		spin_lock_irqsave(&s->lock, flags);
+		if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
+			val |= PCM_ENABLE_INPUT;
+		if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
+			val |= PCM_ENABLE_OUTPUT;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(val, (int *)arg);
 		
-    case SNDCTL_DSP_SETTRIGGER:
-	if (get_user(val, (int *)arg))
-	    return -EFAULT;
-	if (file->f_mode & FMODE_READ) {
-	    if (val & PCM_ENABLE_INPUT)
-		start_adc(s);
-	    else
-		stop_adc(s);
-	}
-	if (file->f_mode & FMODE_WRITE) {
-	    if (val & PCM_ENABLE_OUTPUT)
-		start_dac(s);
-	    else
-		stop_dac(s);
-	}
-	return 0;
+	case SNDCTL_DSP_SETTRIGGER:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			if (val & PCM_ENABLE_INPUT)
+				start_adc(s);
+			else
+				stop_adc(s);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val & PCM_ENABLE_OUTPUT)
+				start_dac(s);
+			else
+				stop_dac(s);
+		}
+		return 0;
 
-    case SNDCTL_DSP_GETOSPACE:
-	if (!(file->f_mode & FMODE_WRITE))
-	    return -EINVAL;
-	abinfo.fragsize = s->dma_dac.fragsize;
-	spin_lock_irqsave(&s->lock, flags);
-	count = s->dma_dac.count;
-	if (!s->dma_dac.stopped)
-	    count -= (s->dma_dac.fragsize - inw(s->io+IT_AC_PCDL));
-	spin_unlock_irqrestore(&s->lock, flags);
-	if (count < 0)
-	    count = 0;
-	abinfo.bytes = s->dma_dac.dmasize - count;
-	abinfo.fragstotal = s->dma_dac.numfrag;
-	abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-	return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-    case SNDCTL_DSP_GETISPACE:
-	if (!(file->f_mode & FMODE_READ))
-	    return -EINVAL;
-	abinfo.fragsize = s->dma_adc.fragsize;
-	spin_lock_irqsave(&s->lock, flags);
-	count = s->dma_adc.count;
-	if (!s->dma_adc.stopped)
-	    count += (s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL));
-	spin_unlock_irqrestore(&s->lock, flags);
-	if (count < 0)
-	    count = 0;
-	abinfo.bytes = count;
-	abinfo.fragstotal = s->dma_adc.numfrag;
-	abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-	return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_dac.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		if (!s->dma_dac.stopped)
+			count -= (s->dma_dac.fragsize -
+				  inw(s->io+IT_AC_PCDL));
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = s->dma_dac.dmasize - count;
+		abinfo.fragstotal = s->dma_dac.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ?
+			-EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_adc.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_adc.count;
+		if (!s->dma_adc.stopped)
+			count += (s->dma_adc.fragsize -
+				  inw(s->io+IT_AC_CAPCDL));
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = count;
+		abinfo.fragstotal = s->dma_adc.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ?
+			-EFAULT : 0;
 		
-    case SNDCTL_DSP_NONBLOCK:
-	file->f_flags |= O_NONBLOCK;
-	return 0;
-
-    case SNDCTL_DSP_GETODELAY:
-	if (!(file->f_mode & FMODE_WRITE))
-	    return -EINVAL;
-	spin_lock_irqsave(&s->lock, flags);
-	count = s->dma_dac.count;
-	if (!s->dma_dac.stopped)
-	    count -= (s->dma_dac.fragsize - inw(s->io+IT_AC_PCDL));
-	spin_unlock_irqrestore(&s->lock, flags);
-	if (count < 0)
-	    count = 0;
-	return put_user(count, (int *)arg);
-
-    case SNDCTL_DSP_GETIPTR:
-	if (!(file->f_mode & FMODE_READ))
-	    return -EINVAL;
-	spin_lock_irqsave(&s->lock, flags);
-	cinfo.bytes = s->dma_adc.total_bytes;
-	count = s->dma_adc.count;
-	if (!s->dma_adc.stopped) {
-	    diff = s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL);
-	    count += diff;
-	    cinfo.bytes += diff;
-	    cinfo.ptr = inl(s->io+s->dma_adc.curBufPtr) - s->dma_adc.dmaaddr;
-	} else
-	    cinfo.ptr = virt_to_bus(s->dma_adc.nextIn) - s->dma_adc.dmaaddr;
-	if (s->dma_adc.mapped)
-	    s->dma_adc.count &= s->dma_adc.fragsize-1;
-	spin_unlock_irqrestore(&s->lock, flags);
-	if (count < 0)
-	    count = 0;
-	cinfo.blocks = count >> s->dma_adc.fragshift;
-	return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
-
-    case SNDCTL_DSP_GETOPTR:
-	if (!(file->f_mode & FMODE_READ))
-	    return -EINVAL;
-	spin_lock_irqsave(&s->lock, flags);
-	cinfo.bytes = s->dma_dac.total_bytes;
-	count = s->dma_dac.count;
-	if (!s->dma_dac.stopped) {
-	    diff = s->dma_dac.fragsize - inw(s->io+IT_AC_CAPCDL);
-	    count -= diff;
-	    cinfo.bytes += diff;
-	    cinfo.ptr = inl(s->io+s->dma_dac.curBufPtr) - s->dma_dac.dmaaddr;
-	} else
-	    cinfo.ptr = virt_to_bus(s->dma_dac.nextOut) - s->dma_dac.dmaaddr;
-	if (s->dma_dac.mapped)
-	    s->dma_dac.count &= s->dma_dac.fragsize-1;
-	spin_unlock_irqrestore(&s->lock, flags);
-	if (count < 0)
-	    count = 0;
-	cinfo.blocks = count >> s->dma_dac.fragshift;
-	return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
-
-    case SNDCTL_DSP_GETBLKSIZE:
-	if (file->f_mode & FMODE_WRITE)
-	    return put_user(s->dma_dac.fragsize, (int *)arg);
-	else
-	    return put_user(s->dma_adc.fragsize, (int *)arg);
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		if (!s->dma_dac.stopped)
+			count -= (s->dma_dac.fragsize -
+				  inw(s->io+IT_AC_PCDL));
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		return put_user(count, (int *)arg);
+
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_adc.total_bytes;
+		count = s->dma_adc.count;
+		if (!s->dma_adc.stopped) {
+			diff = s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL);
+			count += diff;
+			cinfo.bytes += diff;
+			cinfo.ptr = inl(s->io+s->dma_adc.curBufPtr) -
+				s->dma_adc.dmaaddr;
+		} else
+			cinfo.ptr = virt_to_bus(s->dma_adc.nextIn) -
+				s->dma_adc.dmaaddr;
+		if (s->dma_adc.mapped)
+			s->dma_adc.count &= s->dma_adc.fragsize-1;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_adc.fragshift;
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_dac.total_bytes;
+		count = s->dma_dac.count;
+		if (!s->dma_dac.stopped) {
+			diff = s->dma_dac.fragsize - inw(s->io+IT_AC_CAPCDL);
+			count -= diff;
+			cinfo.bytes += diff;
+			cinfo.ptr = inl(s->io+s->dma_dac.curBufPtr) -
+				s->dma_dac.dmaaddr;
+		} else
+			cinfo.ptr = virt_to_bus(s->dma_dac.nextOut) -
+				s->dma_dac.dmaaddr;
+		if (s->dma_dac.mapped)
+			s->dma_dac.count &= s->dma_dac.fragsize-1;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_dac.fragshift;
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE)
+			return put_user(s->dma_dac.fragsize, (int *)arg);
+		else
+			return put_user(s->dma_adc.fragsize, (int *)arg);
 
-    case SNDCTL_DSP_SETFRAGMENT:
-	if (get_user(val, (int *)arg))
-	    return -EFAULT;
-	if (file->f_mode & FMODE_READ) {
-	    stop_adc(s);
-	    s->dma_adc.ossfragshift = val & 0xffff;
-	    s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-	    if (s->dma_adc.ossfragshift < 4)
-		s->dma_adc.ossfragshift = 4;
-	    if (s->dma_adc.ossfragshift > 15)
-		s->dma_adc.ossfragshift = 15;
-	    if (s->dma_adc.ossmaxfrags < 4)
-		s->dma_adc.ossmaxfrags = 4;
-	    if ((ret = prog_dmabuf_adc(s)))
-		return ret;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-	    stop_dac(s);
-	    s->dma_dac.ossfragshift = val & 0xffff;
-	    s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-	    if (s->dma_dac.ossfragshift < 4)
-		s->dma_dac.ossfragshift = 4;
-	    if (s->dma_dac.ossfragshift > 15)
-		s->dma_dac.ossfragshift = 15;
-	    if (s->dma_dac.ossmaxfrags < 4)
-		s->dma_dac.ossmaxfrags = 4;
-	    if ((ret = prog_dmabuf_dac(s)))
-		return ret;
-	}
-	return 0;
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.ossfragshift = val & 0xffff;
+			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_adc.ossfragshift < 4)
+				s->dma_adc.ossfragshift = 4;
+			if (s->dma_adc.ossfragshift > 15)
+				s->dma_adc.ossfragshift = 15;
+			if (s->dma_adc.ossmaxfrags < 4)
+				s->dma_adc.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.ossfragshift = val & 0xffff;
+			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_dac.ossfragshift < 4)
+				s->dma_dac.ossfragshift = 4;
+			if (s->dma_dac.ossfragshift > 15)
+				s->dma_dac.ossfragshift = 15;
+			if (s->dma_dac.ossmaxfrags < 4)
+				s->dma_dac.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
 
-    case SNDCTL_DSP_SUBDIVIDE:
-	if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-	    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-	    return -EINVAL;
-	if (get_user(val, (int *)arg))
-	    return -EFAULT;
-	if (val != 1 && val != 2 && val != 4)
-	    return -EINVAL;
-	if (file->f_mode & FMODE_READ) {
-	    stop_adc(s);
-	    s->dma_adc.subdivision = val;
-	    if ((ret = prog_dmabuf_adc(s)))
-		return ret;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-	    stop_dac(s);
-	    s->dma_dac.subdivision = val;
-	    if ((ret = prog_dmabuf_dac(s)))
-		return ret;
-	}
-	return 0;
+	case SNDCTL_DSP_SUBDIVIDE:
+		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+			return -EINVAL;
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val != 1 && val != 2 && val != 4)
+			return -EINVAL;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.subdivision = val;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.subdivision = val;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
 
-    case SOUND_PCM_READ_RATE:
-	return put_user((file->f_mode & FMODE_READ) ?
-			s->adcrate : s->dacrate, (int *)arg);
-
-    case SOUND_PCM_READ_CHANNELS:
-	if (file->f_mode & FMODE_READ)
-	    return put_user((s->capcc & CC_SM) ? 2 : 1, (int *)arg);
-	else
-	    return put_user((s->pcc & CC_SM) ? 2 : 1, (int *)arg);
+	case SOUND_PCM_READ_RATE:
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->adcrate : s->dacrate, (int *)arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		if (file->f_mode & FMODE_READ)
+			return put_user((s->capcc & CC_SM) ? 2 : 1,
+					(int *)arg);
+		else
+			return put_user((s->pcc & CC_SM) ? 2 : 1,
+					(int *)arg);
 	    
-    case SOUND_PCM_READ_BITS:
-	if (file->f_mode & FMODE_READ)
-	    return put_user((s->capcc & CC_DF) ? 16 : 8, (int *)arg);
-	else
-	    return put_user((s->pcc & CC_DF) ? 16 : 8, (int *)arg);
+	case SOUND_PCM_READ_BITS:
+		if (file->f_mode & FMODE_READ)
+			return put_user((s->capcc & CC_DF) ? 16 : 8,
+					(int *)arg);
+		else
+			return put_user((s->pcc & CC_DF) ? 16 : 8,
+					(int *)arg);
 
-    case SOUND_PCM_WRITE_FILTER:
-    case SNDCTL_DSP_SETSYNCRO:
-    case SOUND_PCM_READ_FILTER:
-	return -EINVAL;
-    }
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
 
-    return mixdev_ioctl(&s->codec, cmd, arg);
+	return mixdev_ioctl(&s->codec, cmd, arg);
 }
 
 
 static int it8172_open(struct inode *inode, struct file *file)
 {
-    int minor = MINOR(inode->i_rdev);
-    DECLARE_WAITQUEUE(wait, current);
-    unsigned long flags;
-    struct list_head *list;
-    struct it8172_state *s;
-    int ret;
-    
-    for (list = devs.next; ; list = list->next) {
-	if (list == &devs)
-	    return -ENODEV;
-	s = list_entry(list, struct it8172_state, devs);
-	if (!((s->dev_audio ^ minor) & ~0xf))
-	    break;
-    }
-    file->private_data = s;
-    /* wait for device to become free */
-    down(&s->open_sem);
-    while (s->open_mode & file->f_mode) {
-	if (file->f_flags & O_NONBLOCK) {
-	    up(&s->open_sem);
-	    return -EBUSY;
+	int minor = MINOR(inode->i_rdev);
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+	struct list_head *list;
+	struct it8172_state *s;
+	int ret;
+    
+#ifdef IT8172_VERBOSE_DEBUG
+	if (file->f_flags & O_NONBLOCK)
+		dbg(__FUNCTION__ ": non-blocking");
+	else
+		dbg(__FUNCTION__ ": blocking");
+#endif
+	
+	for (list = devs.next; ; list = list->next) {
+		if (list == &devs)
+			return -ENODEV;
+		s = list_entry(list, struct it8172_state, devs);
+		if (!((s->dev_audio ^ minor) & ~0xf))
+			break;
 	}
-	add_wait_queue(&s->open_wait, &wait);
-	__set_current_state(TASK_INTERRUPTIBLE);
-	up(&s->open_sem);
-	schedule();
-	remove_wait_queue(&s->open_wait, &wait);
-	set_current_state(TASK_RUNNING);
-	if (signal_pending(current))
-	    return -ERESTARTSYS;
+	file->private_data = s;
+	/* wait for device to become free */
 	down(&s->open_sem);
-    }
+	while (s->open_mode & file->f_mode) {
+		if (file->f_flags & O_NONBLOCK) {
+			up(&s->open_sem);
+			return -EBUSY;
+		}
+		add_wait_queue(&s->open_wait, &wait);
+		__set_current_state(TASK_INTERRUPTIBLE);
+		up(&s->open_sem);
+		schedule();
+		remove_wait_queue(&s->open_wait, &wait);
+		set_current_state(TASK_RUNNING);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		down(&s->open_sem);
+	}
 
-    spin_lock_irqsave(&s->lock, flags);
+	spin_lock_irqsave(&s->lock, flags);
 
-    if (file->f_mode & FMODE_READ) {
-	s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-	    s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
-	s->capcc &= ~(CC_SM | CC_DF);
-	set_adc_rate(s, 8000);
-	if ((minor & 0xf) == SND_DEV_DSP16)
-	    s->capcc |= CC_DF;
-	outw(s->capcc, s->io+IT_AC_CAPCC);
-	if ((ret = prog_dmabuf_adc(s)))
-	    return ret;
-    }
-    if (file->f_mode & FMODE_WRITE) {
-	s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-	    s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
-	s->pcc &= ~(CC_SM | CC_DF);
-	set_dac_rate(s, 8000);
-	if ((minor & 0xf) == SND_DEV_DSP16)
-	    s->pcc |= CC_DF;
-	outw(s->pcc, s->io+IT_AC_PCC);
-	if ((ret = prog_dmabuf_dac(s)))
-	    return ret;
-    }
-
-    spin_unlock_irqrestore(&s->lock, flags);
-
-    s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-    up(&s->open_sem);
-    return 0;
+	if (file->f_mode & FMODE_READ) {
+		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+			s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
+		s->capcc &= ~(CC_SM | CC_DF);
+		set_adc_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->capcc |= CC_DF;
+		outw(s->capcc, s->io+IT_AC_CAPCC);
+		if ((ret = prog_dmabuf_adc(s))) {
+			spin_unlock_irqrestore(&s->lock, flags);
+			return ret;
+		}
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+			s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
+		s->pcc &= ~(CC_SM | CC_DF);
+		set_dac_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->pcc |= CC_DF;
+		outw(s->pcc, s->io+IT_AC_PCC);
+		if ((ret = prog_dmabuf_dac(s))) {
+			spin_unlock_irqrestore(&s->lock, flags);
+			return ret;
+		}
+	}
+    
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	s->open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
+	up(&s->open_sem);
+	return 0;
 }
 
 static int it8172_release(struct inode *inode, struct file *file)
 {
-    struct it8172_state *s = (struct it8172_state *)file->private_data;
+	struct it8172_state *s = (struct it8172_state *)file->private_data;
 
-    lock_kernel();
-    if (file->f_mode & FMODE_WRITE)
-	drain_dac(s, file->f_flags & O_NONBLOCK);
-    down(&s->open_sem);
-    if (file->f_mode & FMODE_WRITE) {
-	stop_dac(s);
-	dealloc_dmabuf(s, &s->dma_dac);
-    }
-    if (file->f_mode & FMODE_READ) {
-	stop_adc(s);
-	dealloc_dmabuf(s, &s->dma_adc);
-    }
-    s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-    up(&s->open_sem);
-    wake_up(&s->open_wait);
-    unlock_kernel();
-    return 0;
+#ifdef IT8172_VERBOSE_DEBUG
+	dbg(__FUNCTION__);
+#endif
+	lock_kernel();
+	if (file->f_mode & FMODE_WRITE)
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+	down(&s->open_sem);
+	if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		dealloc_dmabuf(s, &s->dma_dac);
+	}
+	if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		dealloc_dmabuf(s, &s->dma_adc);
+	}
+	s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
+	up(&s->open_sem);
+	wake_up(&s->open_wait);
+	unlock_kernel();
+	return 0;
 }
 
 static /*const*/ struct file_operations it8172_audio_fops = {
-    owner:	THIS_MODULE,
-    llseek:	it8172_llseek,
-    read:	it8172_read,
-    write:	it8172_write,
-    poll:	it8172_poll,
-    ioctl:	it8172_ioctl,
-    mmap:	it8172_mmap,
-    open:	it8172_open,
-    release:	it8172_release,
+	owner:	THIS_MODULE,
+	llseek:	it8172_llseek,
+	read:	it8172_read,
+	write:	it8172_write,
+	poll:	it8172_poll,
+	ioctl:	it8172_ioctl,
+	mmap:	it8172_mmap,
+	open:	it8172_open,
+	release:	it8172_release,
 };
 
 
@@ -1658,51 +1898,51 @@
 static int proc_it8172_dump (char *buf, char **start, off_t fpos,
 			     int length, int *eof, void *data)
 {
-    struct it8172_state *s;
-    int cnt, len = 0;
-
-    if (list_empty(&devs))
-	return 0;
-    s = list_entry(devs.next, struct it8172_state, devs);
-
-    /* print out header */
-    len += sprintf(buf + len, "\n\t\tIT8172 Audio Debug\n\n");
+	struct it8172_state *s;
+	int cnt, len = 0;
 
-    // print out digital controller state
-    len += sprintf (buf + len, "IT8172 Audio Controller registers\n");
-    len += sprintf (buf + len, "---------------------------------\n");
-    cnt=0;
-    while (cnt < 0x72) {
-	if (cnt == IT_AC_PCB1STA || cnt == IT_AC_PCB2STA ||
-	    cnt == IT_AC_CAPB1STA || cnt == IT_AC_CAPB2STA ||
-	    cnt == IT_AC_PFDP) {
-	    len+= sprintf (buf + len, "reg %02x = %08x\n",
-			   cnt, inl(s->io+cnt));
-	    cnt += 4;
-	} else {
-	    len+= sprintf (buf + len, "reg %02x = %04x\n",
-			   cnt, inw(s->io+cnt));
-	    cnt += 2;
-	}
-    }
-    
-    /* print out CODEC state */
-    len += sprintf (buf + len, "\nAC97 CODEC registers\n");
-    len += sprintf (buf + len, "----------------------\n");
-    for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
-	len+= sprintf (buf + len, "reg %02x = %04x\n",
-		       cnt, rdcodec(&s->codec, cnt));
-
-    if (fpos >=len){
-	*start = buf;
+	if (list_empty(&devs))
+		return 0;
+	s = list_entry(devs.next, struct it8172_state, devs);
+
+	/* print out header */
+	len += sprintf(buf + len, "\n\t\tIT8172 Audio Debug\n\n");
+
+	// print out digital controller state
+	len += sprintf (buf + len, "IT8172 Audio Controller registers\n");
+	len += sprintf (buf + len, "---------------------------------\n");
+	cnt=0;
+	while (cnt < 0x72) {
+		if (cnt == IT_AC_PCB1STA || cnt == IT_AC_PCB2STA ||
+		    cnt == IT_AC_CAPB1STA || cnt == IT_AC_CAPB2STA ||
+		    cnt == IT_AC_PFDP) {
+			len+= sprintf (buf + len, "reg %02x = %08x\n",
+				       cnt, inl(s->io+cnt));
+			cnt += 4;
+		} else {
+			len+= sprintf (buf + len, "reg %02x = %04x\n",
+				       cnt, inw(s->io+cnt));
+			cnt += 2;
+		}
+	}
+    
+	/* print out CODEC state */
+	len += sprintf (buf + len, "\nAC97 CODEC registers\n");
+	len += sprintf (buf + len, "----------------------\n");
+	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
+		len+= sprintf (buf + len, "reg %02x = %04x\n",
+			       cnt, rdcodec(&s->codec, cnt));
+
+	if (fpos >=len){
+		*start = buf;
+		*eof =1;
+		return 0;
+	}
+	*start = buf + fpos;
+	if ((len -= fpos) > length)
+		return length;
 	*eof =1;
-	return 0;
-    }
-    *start = buf + fpos;
-    if ((len -= fpos) > length)
-	return length;
-    *eof =1;
-    return len;
+	return len;
 
 }
 #endif /* IT8172_DEBUG */
@@ -1713,246 +1953,299 @@
 #define NR_DEVICE 5
 
 static int spdif[NR_DEVICE] = { 0, };
+static int i2s_fmt[NR_DEVICE] = { 0, };
 
 static unsigned int devindex = 0;
 
 MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i");
 MODULE_PARM_DESC(spdif, "if 1 the S/PDIF digital output is enabled");
+MODULE_PARM(i2s_fmt, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(i2s_fmt, "the format of I2S");
 
 MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
-MODULE_DESCRIPTION("IT8172 AudioPCI97 Driver");
-MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IT8172 Audio Driver");
 
 /* --------------------------------------------------------------------- */
 
 static int __devinit it8172_probe(struct pci_dev *pcidev,
 				  const struct pci_device_id *pciid)
 {
-    struct it8172_state *s;
-    int i, val;
-    unsigned short pcisr, vol;
-    unsigned char legacy, imc;
-    char proc_str[80];
-    
-    if (pcidev->irq == 0) 
-	return -1;
-
-    if (!(s = kmalloc(sizeof(struct it8172_state), GFP_KERNEL))) {
-	printk(KERN_ERR PFX "alloc of device struct failed\n");
-	return -1;
-    }
+	struct it8172_state *s;
+	int i, val;
+	unsigned short pcisr, vol;
+	unsigned char legacy, imc;
+	char proc_str[80];
+    
+	if (pcidev->irq == 0) 
+		return -1;
+
+	if (!(s = kmalloc(sizeof(struct it8172_state), GFP_KERNEL))) {
+		err("alloc of device struct failed");
+		return -1;
+	}
 	
-    memset(s, 0, sizeof(struct it8172_state));
-    init_waitqueue_head(&s->dma_adc.wait);
-    init_waitqueue_head(&s->dma_dac.wait);
-    init_waitqueue_head(&s->open_wait);
-    init_MUTEX(&s->open_sem);
-    spin_lock_init(&s->lock);
-    s->dev = pcidev;
-    s->io = pci_resource_start(pcidev, 0);
-    s->irq = pcidev->irq;
-    s->vendor = pcidev->vendor;
-    s->device = pcidev->device;
-    pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
-    s->codec.private_data = s;
-    s->codec.id = 0;
-    s->codec.codec_read = rdcodec;
-    s->codec.codec_write = wrcodec;
-    s->codec.codec_wait = waitcodec;
-
-    if (!request_region(s->io, pci_resource_len(pcidev,0),
-			IT8172_MODULE_NAME)) {
-	printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
-		s->io, s->io + pci_resource_len(pcidev,0)-1);
-	goto err_region;
-    }
-    if (request_irq(s->irq, it8172_interrupt, SA_INTERRUPT,
-		    IT8172_MODULE_NAME, s)) {
-	printk(KERN_ERR PFX "irq %u in use\n", s->irq);
-	goto err_irq;
-    }
-
-    printk(KERN_INFO PFX "IO at %#lx, IRQ %d\n", s->io, s->irq);
-
-    /* register devices */
-    if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
-	goto err_dev1;
-    if ((s->codec.dev_mixer =
-	 register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
-	goto err_dev2;
+	memset(s, 0, sizeof(struct it8172_state));
+	init_waitqueue_head(&s->dma_adc.wait);
+	init_waitqueue_head(&s->dma_dac.wait);
+	init_waitqueue_head(&s->open_wait);
+	init_MUTEX(&s->open_sem);
+	spin_lock_init(&s->lock);
+	s->dev = pcidev;
+	s->io = pci_resource_start(pcidev, 0);
+	s->irq = pcidev->irq;
+	s->vendor = pcidev->vendor;
+	s->device = pcidev->device;
+	pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
+	s->codec.private_data = s;
+	s->codec.id = 0;
+	s->codec.codec_read = rdcodec;
+	s->codec.codec_write = wrcodec;
+	s->codec.codec_wait = waitcodec;
+
+	if (!request_region(s->io, pci_resource_len(pcidev,0),
+			    IT8172_MODULE_NAME)) {
+		err("io ports %#lx->%#lx in use",
+		    s->io, s->io + pci_resource_len(pcidev,0)-1);
+		goto err_region;
+	}
+	if (request_irq(s->irq, it8172_interrupt, SA_INTERRUPT,
+			IT8172_MODULE_NAME, s)) {
+		err("irq %u in use", s->irq);
+		goto err_irq;
+	}
+
+	info("IO at %#lx, IRQ %d", s->io, s->irq);
+
+	/* register devices */
+	if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
+		goto err_dev1;
+	if ((s->codec.dev_mixer =
+	     register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
+		goto err_dev2;
 
 #ifdef IT8172_DEBUG
-    /* intialize the debug proc device */
-    s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
-				   proc_it8172_dump, NULL);
+	/* intialize the debug proc device */
+	s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
+				       proc_it8172_dump, NULL);
 #endif /* IT8172_DEBUG */
 	
-    /*
-     * Reset the Audio device using the IT8172 PCI Reset register. This
-     * creates an audible double click on a speaker connected to Line-out.
-     */
-    IT_IO_READ16(IT_PM_PCISR, pcisr);
-    pcisr |= IT_PM_PCISR_ACSR;
-    IT_IO_WRITE16(IT_PM_PCISR, pcisr);
-    /* wait up to 100msec for reset to complete */
-    for (i=0; pcisr & IT_PM_PCISR_ACSR; i++) {
-	it8172_delay(10);
-	if (i == 10)
-	    break;
+	/*
+	 * Reset the Audio device using the IT8172 PCI Reset register. This
+	 * creates an audible double click on a speaker connected to Line-out.
+	 */
 	IT_IO_READ16(IT_PM_PCISR, pcisr);
-    }
-    if (i == 10) {
-	printk(KERN_ERR PFX "chip reset timeout!\n");
-	goto err_dev3;
-    }
-    
-    /* enable pci io and bus mastering */
-    if (pci_enable_device(pcidev))
-	goto err_dev3;
-    pci_set_master(pcidev);
-
-    /* get out of legacy mode */
-    pci_read_config_byte (pcidev, 0x40, &legacy);
-    pci_write_config_byte (pcidev, 0x40, legacy & ~1);
-    
-    s->spdif_volume = -1;
-    /* check to see if s/pdif mode is being requested */
-    if (spdif[devindex]) {
-	printk(KERN_INFO PFX "enabling S/PDIF output\n");
-	s->spdif_volume = 0;
-	outb(GC_SOE, s->io+IT_AC_GC);
-    } else {
-	printk(KERN_INFO PFX "disabling S/PDIF output\n");
-	outb(0, s->io+IT_AC_GC);
-    }
-    
-    /* cold reset the AC97 */
-    outw(CODECC_CR, s->io+IT_AC_CODECC);
-    udelay(1000);
-    outw(0, s->io+IT_AC_CODECC);
-    /* need to delay around 500msec(bleech) to give
-       some CODECs enough time to wakeup */
-    it8172_delay(500);
-    
-    /* AC97 warm reset to start the bitclk */
-    outw(CODECC_WR, s->io+IT_AC_CODECC);
-    udelay(1000);
-    outw(0, s->io+IT_AC_CODECC);
-    
-    /* codec init */
-    if (!ac97_probe_codec(&s->codec))
-	goto err_dev3;
-
-    /* Enable Volume button interrupts */
-    imc = inb(s->io+IT_AC_IMC);
-    outb(imc & ~IMC_VCIM, s->io+IT_AC_IMC);
-
-    /* Un-mute PCM and FM out on the controller */
-    vol = inw(s->io+IT_AC_PCMOV);
-    outw(vol & ~PCMOV_PCMOM, s->io+IT_AC_PCMOV);
-    vol = inw(s->io+IT_AC_FMOV);
-    outw(vol & ~FMOV_FMOM, s->io+IT_AC_FMOV);
-
-    /* set channel defaults to 8-bit, mono, 8 Khz */
-    s->pcc = 0;
-    s->capcc = 0;
-    set_dac_rate(s, 8000);
-    set_adc_rate(s, 8000);
-
-    /* set mic to be the recording source */
-    val = SOUND_MASK_MIC;
-    mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-
-    /* mute master and PCM when in S/PDIF mode */
-    if (s->spdif_volume != -1) {
-	val = 0x0000;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
-		     (unsigned long)&val);
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
+	pcisr |= IT_PM_PCISR_ACSR;
+	IT_IO_WRITE16(IT_PM_PCISR, pcisr);
+	/* wait up to 100msec for reset to complete */
+	for (i=0; pcisr & IT_PM_PCISR_ACSR; i++) {
+		it8172_delay(10);
+		if (i == 10)
+			break;
+		IT_IO_READ16(IT_PM_PCISR, pcisr);
+	}
+	if (i == 10) {
+		err("chip reset timeout!");
+		goto err_dev3;
+	}
+    
+	/* enable pci io and bus mastering */
+	if (pci_enable_device(pcidev))
+		goto err_dev3;
+	pci_set_master(pcidev);
+
+	/* get out of legacy mode */
+	pci_read_config_byte (pcidev, 0x40, &legacy);
+	pci_write_config_byte (pcidev, 0x40, legacy & ~1);
+    
+	s->spdif_volume = -1;
+	/* check to see if s/pdif mode is being requested */
+	if (spdif[devindex]) {
+		info("enabling S/PDIF output");
+		s->spdif_volume = 0;
+		outb(GC_SOE, s->io+IT_AC_GC);
+	} else {
+		info("disabling S/PDIF output");
+		outb(0, s->io+IT_AC_GC);
+	}
+    
+	/* check to see if I2S format requested */
+	if (i2s_fmt[devindex]) {
+		info("setting I2S format to 0x%02x", i2s_fmt[devindex]);
+		outb(i2s_fmt[devindex], s->io+IT_AC_I2SMC);
+	} else {
+		outb(I2SMC_I2SF_I2S, s->io+IT_AC_I2SMC);
+	}
+
+	/* cold reset the AC97 */
+	outw(CODECC_CR, s->io+IT_AC_CODECC);
+	udelay(1000);
+	outw(0, s->io+IT_AC_CODECC);
+	/* need to delay around 500msec(bleech) to give
+	   some CODECs enough time to wakeup */
+	it8172_delay(500);
+    
+	/* AC97 warm reset to start the bitclk */
+	outw(CODECC_WR, s->io+IT_AC_CODECC);
+	udelay(1000);
+	outw(0, s->io+IT_AC_CODECC);
+    
+	/* codec init */
+	if (!ac97_probe_codec(&s->codec))
+		goto err_dev3;
+
+	/* add I2S as allowable recording source */
+	s->codec.record_sources |= SOUND_MASK_I2S;
+	
+	/* Enable Volume button interrupts */
+	imc = inb(s->io+IT_AC_IMC);
+	outb(imc & ~IMC_VCIM, s->io+IT_AC_IMC);
+
+	/* Un-mute PCM and FM out on the controller */
+	vol = inw(s->io+IT_AC_PCMOV);
+	outw(vol & ~PCMOV_PCMOM, s->io+IT_AC_PCMOV);
+	vol = inw(s->io+IT_AC_FMOV);
+	outw(vol & ~FMOV_FMOM, s->io+IT_AC_FMOV);
+    
+	/* set channel defaults to 8-bit, mono, 8 Khz */
+	s->pcc = 0;
+	s->capcc = 0;
+	set_dac_rate(s, 8000);
+	set_adc_rate(s, 8000);
+
+	/* set mic to be the recording source */
+	val = SOUND_MASK_MIC;
+	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
 		     (unsigned long)&val);
-    }
+
+	/* mute AC'97 master and PCM when in S/PDIF mode */
+	if (s->spdif_volume != -1) {
+		val = 0x0000;
+		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
+				     (unsigned long)&val);
+		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
+				     (unsigned long)&val);
+	}
     
 #ifdef IT8172_DEBUG
-    sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME, s->codec.id);
-    s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-					 ac97_read_proc, &s->codec);
+	sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME,
+		s->codec.id);
+	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+					     ac97_read_proc, &s->codec);
 #endif
     
-    /* store it in the driver field */
-    pci_set_drvdata(pcidev, s);
-    pcidev->dma_mask = 0xffffffff;
-    /* put it into driver list */
-    list_add_tail(&s->devs, &devs);
-    /* increment devindex */
-    if (devindex < NR_DEVICE-1)
-	devindex++;
-    return 0;
+	/* store it in the driver field */
+	pci_set_drvdata(pcidev, s);
+	pcidev->dma_mask = 0xffffffff;
+	/* put it into driver list */
+	list_add_tail(&s->devs, &devs);
+	/* increment devindex */
+	if (devindex < NR_DEVICE-1)
+		devindex++;
+	return 0;
 
  err_dev3:
-    unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec.dev_mixer);
  err_dev2:
-    unregister_sound_dsp(s->dev_audio);
+	unregister_sound_dsp(s->dev_audio);
  err_dev1:
-    printk(KERN_ERR PFX "cannot register misc device\n");
-    free_irq(s->irq, s);
+	err("cannot register misc device");
+	free_irq(s->irq, s);
  err_irq:
-    release_region(s->io, pci_resource_len(pcidev,0));
+	release_region(s->io, pci_resource_len(pcidev,0));
  err_region:
-    kfree(s);
-    return -1;
+	kfree(s);
+	return -1;
 }
 
 static void __devinit it8172_remove(struct pci_dev *dev)
 {
-    struct it8172_state *s = pci_get_drvdata(dev);
+	struct it8172_state *s = pci_get_drvdata(dev);
 
-    if (!s)
-	return;
-    list_del(&s->devs);
+	if (!s)
+		return;
+	list_del(&s->devs);
 #ifdef IT8172_DEBUG
-    if (s->ps)
-	remove_proc_entry(IT8172_MODULE_NAME, NULL);
+	if (s->ps)
+		remove_proc_entry(IT8172_MODULE_NAME, NULL);
 #endif /* IT8172_DEBUG */
-    synchronize_irq();
-    free_irq(s->irq, s);
-    release_region(s->io, pci_resource_len(dev,0));
-    unregister_sound_dsp(s->dev_audio);
-    unregister_sound_mixer(s->codec.dev_mixer);
-    kfree(s);
-    pci_set_drvdata(dev, NULL);
+	synchronize_irq();
+	free_irq(s->irq, s);
+	release_region(s->io, pci_resource_len(dev,0));
+	unregister_sound_dsp(s->dev_audio);
+	unregister_sound_mixer(s->codec.dev_mixer);
+	kfree(s);
+	pci_set_drvdata(dev, NULL);
 }
 
 
 
 static struct pci_device_id id_table[] __devinitdata = {
-    { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G_AUDIO, PCI_ANY_ID,
-      PCI_ANY_ID, 0, 0 },
-    { 0, }
+	{ PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G_AUDIO, PCI_ANY_ID,
+	  PCI_ANY_ID, 0, 0 },
+	{ 0, }
 };
 
 MODULE_DEVICE_TABLE(pci, id_table);
 
 static struct pci_driver it8172_driver = {
-    name: IT8172_MODULE_NAME,
-    id_table: id_table,
-    probe: it8172_probe,
-    remove: it8172_remove
+	name: IT8172_MODULE_NAME,
+	id_table: id_table,
+	probe: it8172_probe,
+	remove: it8172_remove
 };
 
 static int __init init_it8172(void)
 {
-    if (!pci_present())   /* No PCI bus in this machine! */
-	return -ENODEV;
-    printk("version v0.26 time " __TIME__ " " __DATE__ "\n");
-    return pci_module_init(&it8172_driver);
+	if (!pci_present())   /* No PCI bus in this machine! */
+		return -ENODEV;
+	info("version v0.5 time " __TIME__ " " __DATE__);
+	return pci_module_init(&it8172_driver);
 }
 
 static void __exit cleanup_it8172(void)
 {
-    printk(KERN_INFO PFX "unloading\n");
-    pci_unregister_driver(&it8172_driver);
+	info("unloading");
+	pci_unregister_driver(&it8172_driver);
 }
 
 module_init(init_it8172);
 module_exit(cleanup_it8172);
 
+/* --------------------------------------------------------------------- */
+
+#ifndef MODULE
+
+/* format is: it8172=[spdif],[i2s:<I2S format>] */
+
+static int __init it8172_setup(char *options)
+{
+	char* this_opt;
+	static unsigned __initdata nr_dev = 0;
+
+	if (nr_dev >= NR_DEVICE)
+		return 0;
+
+	if (!options || !*options)
+		return 0;
+
+	for(this_opt=strtok(options, ",");
+	    this_opt; this_opt=strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "spdif", 5)) {
+			spdif[nr_dev] = 1;
+		} else if (!strncmp(this_opt, "i2s:", 4)) {
+			if (!strncmp(this_opt+4, "dac", 3))
+				i2s_fmt[nr_dev] = I2SMC_I2SF_DAC;
+			else if (!strncmp(this_opt+4, "adc", 3))
+				i2s_fmt[nr_dev] = I2SMC_I2SF_ADC;
+			else if (!strncmp(this_opt+4, "i2s", 3))
+				i2s_fmt[nr_dev] = I2SMC_I2SF_I2S;
+		}
+	}
+
+	nr_dev++;
+	return 1;
+}
+
+__setup("it8172=", it8172_setup);
+
+#endif /* MODULE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/mad16.c linux/drivers/sound/mad16.c
--- linux.orig/drivers/sound/mad16.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/sound/mad16.c	2002-07-20 01:08:28.000000000 +0000
@@ -42,6 +42,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/gameport.h>
 
 #include "sound_config.h"
 
@@ -51,6 +52,7 @@
 
 static int      mad16_conf;
 static int      mad16_cdsel;
+static struct gameport gameport;
 
 static int      already_initialized = 0;
 
@@ -664,13 +666,13 @@
 
 	outb((bits | dma_bits[dma] | dma2_bit), config_port);	/* Write IRQ+DMA setup */
 
-	hw_config->slots[0] = ad1848_init("MAD16 WSS", hw_config->io_base + 4,
+	hw_config->slots[0] = ad1848_init("mad16 WSS", hw_config->io_base + 4,
 					  hw_config->irq,
 					  dma,
 					  dma2, 0,
 					  hw_config->osp,
 					  THIS_MODULE);
-	request_region(hw_config->io_base, 4, "MAD16 WSS config");
+	request_region(hw_config->io_base, 4, "mad16 WSS config");
 }
 
 static int __init probe_mad16_mpu(struct address_info *hw_config)
@@ -1010,14 +1012,6 @@
 	}
 
 	printk(".\n");
-        printk(KERN_INFO "Joystick port ");
-        if (joystick == 1)
-                printk("enabled.\n");
-        else
-        {
-                joystick = 0;
-                printk("disabled.\n");
-        }
 
 	cfg.io_base = io;
 	cfg.irq = irq;
@@ -1038,6 +1032,18 @@
 	attach_mad16(&cfg);
 
 	found_mpu = probe_mad16_mpu(&cfg_mpu);
+
+	if (joystick == 1) {
+	        /* register gameport */
+                if (!request_region(0x201, 1, "mad16 gameport"))
+                        printk(KERN_ERR "mad16: gameport address 0x201 already in use\n");
+                else {
+			printk(KERN_ERR "mad16: gameport enabled at 0x201\n");
+                        gameport.io = 0x201;
+		        gameport_register_port(&gameport);
+                }
+	}
+	else printk(KERN_ERR "mad16: gameport disabled.\n");
 	return 0;
 }
 
@@ -1055,16 +1061,17 @@
 static int __init setup_mad16(char *str)
 {
         /* io, irq */
-	int ints[7];
+	int ints[8];
 	
 	str = get_options(str, ARRAY_SIZE(ints), ints);
 
-	io	= ints[1];
-	irq	= ints[2];
-	dma	= ints[3];
-	dma16	= ints[4];
-	mpu_io	= ints[5];
-	mpu_irq = ints[6];
+	io	 = ints[1];
+	irq	 = ints[2];
+	dma	 = ints[3];
+	dma16	 = ints[4];
+	mpu_io	 = ints[5];
+	mpu_irq  = ints[6];
+	joystick = ints[7];
 
 	return 1;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/maestro.c linux/drivers/sound/maestro.c
--- linux.orig/drivers/sound/maestro.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/sound/maestro.c	2002-07-20 01:08:31.000000000 +0000
@@ -2756,7 +2756,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -2771,7 +2771,7 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -3569,9 +3569,19 @@
 static void maestro_remove(struct pci_dev *pcidev) {
 	struct ess_card *card = pci_get_drvdata(pcidev);
 	int i;
+	u32 n;
 	
 	/* XXX maybe should force stop bob, but should be all 
 		stopped by _release by now */
+
+	/* Turn off hardware volume control interrupt.
+	   This has to come before we leave the IRQ below,
+	   or a crash results if a button is pressed ! */
+
+	n = inw(card->iobase+0x18);
+	n&=~(1<<6);
+	outw(n, card->iobase+0x18);
+
 	free_irq(card->irq, card);
 	unregister_sound_mixer(card->dev_mixer);
 	for(i=0;i<NR_DSPS;i++)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c
--- linux.orig/drivers/sound/maestro3.c	2001-11-09 21:41:42.000000000 +0000
+++ linux/drivers/sound/maestro3.c	2002-07-20 01:08:39.000000000 +0000
@@ -1805,7 +1805,7 @@
         if (s->dma_adc.mapped)
             s->dma_adc.count &= s->dma_adc.fragsize-1;
         spin_unlock_irqrestore(&s->lock, flags);
-        return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+        return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
     case SNDCTL_DSP_GETOPTR:
         if (!(file->f_mode & FMODE_WRITE))
@@ -1818,7 +1818,7 @@
         if (s->dma_dac.mapped)
             s->dma_dac.count &= s->dma_dac.fragsize-1;
         spin_unlock_irqrestore(&s->lock, flags);
-        return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+        return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
     case SNDCTL_DSP_GETBLKSIZE:
         if (file->f_mode & FMODE_WRITE) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/mpu401.c linux/drivers/sound/mpu401.c
--- linux.orig/drivers/sound/mpu401.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/mpu401.c	2002-07-20 01:08:40.000000000 +0000
@@ -15,6 +15,7 @@
  * Alan Cox		modularisation, use normal request_irq, use dev_id
  * Bartlomiej Zolnierkiewicz	removed some __init to allow using many drivers
  * Chris Rankin		Update the module-usage counter for the coprocessor
+ * Zwane Mwaikambo	Changed attach/unload resource freeing
  */
 
 #include <linux/module.h>
@@ -77,7 +78,7 @@
 
 static void mpu401_close(int dev);
 
-static int mpu401_status(struct mpu_config *devc)
+static inline int mpu401_status(struct mpu_config *devc)
 {
 	return inb(STATPORT(devc->base));
 }
@@ -85,17 +86,17 @@
 #define input_avail(devc)		(!(mpu401_status(devc)&INPUT_AVAIL))
 #define output_ready(devc)		(!(mpu401_status(devc)&OUTPUT_READY))
 
-static void write_command(struct mpu_config *devc, unsigned char cmd)
+static inline void write_command(struct mpu_config *devc, unsigned char cmd)
 {
 	outb(cmd, COMDPORT(devc->base));
 }
 
-static int read_data(struct mpu_config *devc)
+static inline int read_data(struct mpu_config *devc)
 {
 	return inb(DATAPORT(devc->base));
 }
 
-static void write_data(struct mpu_config *devc, unsigned char byte)
+static inline void write_data(struct mpu_config *devc, unsigned char byte)
 {
 	outb(byte, DATAPORT(devc->base));
 }
@@ -965,12 +966,12 @@
 	restore_flags(flags);
 }
 
-void attach_mpu401(struct address_info *hw_config, struct module *owner)
+int attach_mpu401(struct address_info *hw_config, struct module *owner)
 {
 	unsigned long flags;
 	char revision_char;
 
-	int m;
+	int m, ret;
 	struct mpu_config *devc;
 
 	hw_config->slots[1] = -1;
@@ -978,7 +979,8 @@
 	if (m == -1)
 	{
 		printk(KERN_WARNING "MPU-401: Too many midi devices detected\n");
-		return;
+		ret = -ENOMEM;
+		goto out_err;
 	}
 	devc = &dev_conf[m];
 	devc->base = hw_config->io_base;
@@ -1008,16 +1010,16 @@
 		if (!reset_mpu401(devc))
 		{
 			printk(KERN_WARNING "mpu401: Device didn't respond\n");
-			sound_unload_mididev(m);
-			return;
+			ret = -ENODEV;
+			goto out_mididev;
 		}
 		if (!devc->shared_irq)
 		{
 			if (request_irq(devc->irq, mpuintr, 0, "mpu401", (void *)m) < 0)
 			{
 				printk(KERN_WARNING "mpu401: Failed to allocate IRQ%d\n", devc->irq);
-				sound_unload_mididev(m);
-				return;
+				ret = -ENOMEM;
+				goto out_mididev;
 			}
 		}
 		save_flags(flags);
@@ -1027,7 +1029,12 @@
 			mpu401_chk_version(m, devc);
 		restore_flags(flags);
 	}
-	request_region(hw_config->io_base, 2, "mpu401");
+
+	if (!request_region(hw_config->io_base, 2, "mpu401"))
+	{
+		ret = -ENOMEM;
+		goto out_irq;
+	}	
 
 	if (devc->version != 0)
 		if (mpu_cmd(m, 0xC5, 0) >= 0)	/* Set timebase OK */
@@ -1039,9 +1046,9 @@
 
 	if (mpu401_synth_operations[m] == NULL)
 	{
-		sound_unload_mididev(m);
 		printk(KERN_ERR "mpu401: Can't allocate memory\n");
-		return;
+		ret = -ENOMEM;
+		goto out_resource;
 	}
 	if (!(devc->capabilities & MPU_CAP_INTLG))	/* No intelligent mode */
 	{
@@ -1120,6 +1127,17 @@
 
 	hw_config->slots[1] = m;
 	sequencer_init();
+	
+	return 0;
+
+out_resource:
+	release_region(hw_config->io_base, 2);
+out_irq:
+	free_irq(devc->irq, (void *)m);
+out_mididev:
+	sound_unload_mididev(m);
+out_err:
+	return ret;
 }
 
 static int reset_mpu401(struct mpu_config *devc)
@@ -1231,15 +1249,17 @@
 {
 	void *p;
 	int n=hw_config->slots[1];
-	
-	release_region(hw_config->io_base, 2);
-	if (hw_config->always_detect == 0 && hw_config->irq > 0)
-		free_irq(hw_config->irq, (void *)n);
-	p=mpu401_synth_operations[n];
-	sound_unload_mididev(n);
-	sound_unload_timerdev(hw_config->slots[2]);
-	if(p)
-		kfree(p);
+		
+	if (n != -1) {
+		release_region(hw_config->io_base, 2);
+		if (hw_config->always_detect == 0 && hw_config->irq > 0)
+			free_irq(hw_config->irq, (void *)n);
+		p=mpu401_synth_operations[n];
+		sound_unload_mididev(n);
+		sound_unload_timerdev(hw_config->slots[2]);
+		if(p)
+			kfree(p);
+	}
 }
 
 /*****************************************************
@@ -1754,6 +1774,7 @@
 
 int __init init_mpu401(void)
 {
+	int ret;
 	/* Can be loaded either for module use or to provide functions
 	   to others */
 	if (io != -1 && irq != -1) {
@@ -1761,7 +1782,8 @@
 		cfg.io_base = io;
 		if (probe_mpu401(&cfg) == 0)
 			return -ENODEV;
-		attach_mpu401(&cfg, THIS_MODULE);
+		if ((ret = attach_mpu401(&cfg, THIS_MODULE)))
+			return ret;
 	}
 	
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/mpu401.h linux/drivers/sound/mpu401.h
--- linux.orig/drivers/sound/mpu401.h	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/mpu401.h	2002-07-20 01:08:34.000000000 +0000
@@ -7,7 +7,7 @@
 
 /*	From mpu401.c */
 int probe_mpu401(struct address_info *hw_config);
-void attach_mpu401(struct address_info * hw_config, struct module *owner);
+int attach_mpu401(struct address_info * hw_config, struct module *owner);
 void unload_mpu401(struct address_info *hw_info);
 
 int intchk_mpu401(void *dev_id);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
--- linux.orig/drivers/sound/msnd_pinnacle.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/sound/msnd_pinnacle.c	2002-07-20 01:08:24.000000000 +0000
@@ -564,11 +564,11 @@
 		mixer_info info;
 		set_mixer_info();
 		info.modify_counter = dev.mixer_mod_count;
-		return copy_to_user((void *)arg, &info, sizeof(info));
+		return copy_to_user((void *)arg, &info, sizeof(info))?-EFAULT:0;
 	} else if (cmd == SOUND_OLD_MIXER_INFO) {
 		_old_mixer_info info;
 		set_mixer_info();
-		return copy_to_user((void *)arg, &info, sizeof(info));
+		return copy_to_user((void *)arg, &info, sizeof(info))?-EFAULT:0;
 	} else if (cmd == SOUND_MIXER_PRIVATE1) {
 		dev.nresets = 0;
 		dsp_full_reset();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/nec_vrc5477.c linux/drivers/sound/nec_vrc5477.c
--- linux.orig/drivers/sound/nec_vrc5477.c	2001-10-25 20:53:52.000000000 +0000
+++ linux/drivers/sound/nec_vrc5477.c	2002-07-20 01:08:39.000000000 +0000
@@ -6,6 +6,8 @@
  *     AC97 sound dirver for NEC Vrc5477 chip (an integrated, 
  *     multi-function controller chip for MIPS CPUs)
  *
+ * VRA support Copyright 2001 Bradley D. LaRonde <brad@ltc.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
@@ -83,17 +85,25 @@
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 
-#include <asm/ddb5xxx/debug.h>
+/* -------------------debug macros -------------------------------------- */
+/* #undef VRC5477_AC97_DEBUG */
+#define VRC5477_AC97_DEBUG
 
 #undef VRC5477_AC97_VERBOSE_DEBUG
+/* #define VRC5477_AC97_VERBOSE_DEBUG */
 
-/* one must turn on CONFIG_LL_DEBUG before VERBOSE_DEBUG is turned */
 #if defined(VRC5477_AC97_VERBOSE_DEBUG)
-#if !defined(CONFIG_LL_DEBUG)
-#error "You must turn CONFIG_LL_DEBUG"
-#endif
+#define VRC5477_AC97_DEBUG
 #endif
 
+#if defined(VRC5477_AC97_DEBUG)
+#include <linux/kernel.h>
+#define ASSERT(x)  if (!(x)) { \
+	panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+#else
+#define	ASSERT(x)
+#endif /* VRC5477_AC97_DEBUG */
+
 #if defined(VRC5477_AC97_VERBOSE_DEBUG)
 static u16 inTicket=0; 		/* check sync between intr & write */
 static u16 outTicket=0;
@@ -179,16 +189,17 @@
 	unsigned long io;
 	unsigned int irq;
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 	/* debug /proc entry */
 	struct proc_dir_entry *ps;
 	struct proc_dir_entry *ac97_ps;
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
 
 	struct ac97_codec codec;
 
 	unsigned dacChannels, adcChannels;
 	unsigned short dacRate, adcRate;
+	unsigned short extended_status;
 
 	spinlock_t lock;
 	struct semaphore open_sem;
@@ -226,7 +237,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern inline unsigned ld2(unsigned int x)
+static inline unsigned ld2(unsigned int x)
 {
     unsigned r = 0;
 	
@@ -275,7 +286,7 @@
                 (VRC5477_CODEC_RD_RRDYA | VRC5477_CODEC_RD_RRDYD) ) {
 		/* we get either addr or data, or both */
 		if (result & VRC5477_CODEC_RD_RRDYA) {
-			MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+			ASSERT(addr == ((result >> 16) & 0x7f) );
 		}
 		if (result & VRC5477_CODEC_RD_RRDYD) {
 			break;
@@ -315,6 +326,43 @@
 	while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
 }
 
+static int ac97_codec_not_present(struct ac97_codec *codec)
+{
+	struct vrc5477_ac97_state *s = 
+		(struct vrc5477_ac97_state *)codec->private_data;
+	unsigned long flags;
+	unsigned short count  = 0xffff; 
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	/* wait until we can access codec registers */
+	do {
+	       if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
+		       break;
+	} while (--count);
+
+	if (count == 0) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return -1;
+	}
+
+	/* write 0 to reset */
+	outl((AC97_RESET << 16) | 0, s->io + VRC5477_CODEC_WR);
+
+	/* test whether we get a response from ac97 chip */
+	count  = 0xffff; 
+	do { 
+	       if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
+		       break;
+	} while (--count);
+
+	if (count == 0) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return -1;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return 0;
+}
 
 /* --------------------------------------------------------------------- */
 
@@ -345,14 +393,16 @@
 
 static void set_dac_rate(struct vrc5477_ac97_state *s, unsigned rate)
 {
+	if(s->extended_status & AC97_EXTSTAT_VRA) {
 	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, rate);
-	s->dacRate = rate;
+		s->dacRate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+	}
 }
 
 
 /* --------------------------------------------------------------------- */
 
-extern inline void 
+static inline void 
 stop_dac(struct vrc5477_ac97_state *s)
 {
 	struct dmabuf* db = &s->dma_dac;
@@ -408,7 +458,7 @@
 	}
 
 	/* we should have some data to do the DMA trasnfer */
-	MIPS_ASSERT(db->count >= db->fragSize);
+	ASSERT(db->count >= db->fragSize);
 
 	/* clear pending fales interrupts */
 	outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END, 
@@ -442,12 +492,12 @@
 	outl (temp, s->io + VRC5477_CTRL);
 
 	/* it is time to setup next dma transfer */
-	MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
-	MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+	ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+	ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
 
 	temp = db->nextOut + db->fragSize;
 	if (temp >= db->fragTotalSize) {
-		MIPS_ASSERT(temp == db->fragTotalSize);
+		ASSERT(temp == db->fragTotalSize);
 		temp = 0;
 	}
 
@@ -463,14 +513,14 @@
 #if defined(VRC5477_AC97_VERBOSE_DEBUG)
 	outTicket = *(u16*)(db->lbuf+db->nextOut);
 	if (db->count > db->fragSize) {
-		MIPS_ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
+		ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
 	}
 #endif
 
 	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
-extern inline void stop_adc(struct vrc5477_ac97_state *s)
+static inline void stop_adc(struct vrc5477_ac97_state *s)
 {
 	struct dmabuf* db = &s->dma_adc;
 	unsigned long flags;
@@ -521,7 +571,7 @@
 	}
 
 	/* we should at least have some free space in the buffer */
-	MIPS_ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
+	ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
 
 	/* clear pending ones */
 	outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END, 
@@ -553,7 +603,7 @@
 	/* it is time to setup next dma transfer */
 	temp = db->nextIn + db->fragSize;
 	if (temp >= db->fragTotalSize) {
-		MIPS_ASSERT(temp == db->fragTotalSize);
+		ASSERT(temp == db->fragTotalSize);
 		temp = 0;
 	}
 	outl(db->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
@@ -569,11 +619,11 @@
 #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
 #define DMABUF_MINORDER 1
 
-extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
+static inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
 				  struct dmabuf *db)
 {
 	if (db->lbuf) {
-		MIPS_ASSERT(db->rbuf);
+		ASSERT(db->rbuf);
 		pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
 				    db->lbuf, db->lbufDma);
 		pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
@@ -592,7 +642,7 @@
 	unsigned bufsize;
 
 	if (!db->lbuf) {
-		MIPS_ASSERT(!db->rbuf);
+		ASSERT(!db->rbuf);
 
 		db->ready = 0;
 		for (order = DMABUF_DEFAULTORDER; 
@@ -606,7 +656,7 @@
 							&db->rbufDma);
 			if (db->lbuf && db->rbuf) break;
 			if (db->lbuf) {
-			    MIPS_ASSERT(!db->rbuf);
+			    ASSERT(!db->rbuf);
 			    pci_free_consistent(s->dev, 
 						PAGE_SIZE << order,
 						db->lbuf,
@@ -614,7 +664,7 @@
 			}
 		}
 		if (!db->lbuf) {
-			MIPS_ASSERT(!db->rbuf);
+			ASSERT(!db->rbuf);
 			return -ENOMEM;
 		}
 
@@ -643,13 +693,13 @@
 	return 0;
 }
 
-extern inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
+static inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
 {
     stop_adc(s);
     return prog_dmabuf(s, &s->dma_adc, s->adcRate);
 }
 
-extern inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
+static inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
 {
     stop_dac(s);
     return prog_dmabuf(s, &s->dma_dac, s->dacRate);
@@ -677,7 +727,7 @@
 	/* set the base addr for next DMA transfer */
 	temp = adc->nextIn + 2*adc->fragSize;
 	if (temp >= adc->fragTotalSize) {
-		MIPS_ASSERT( (temp == adc->fragTotalSize) ||
+		ASSERT( (temp == adc->fragTotalSize) ||
                              (temp == adc->fragTotalSize + adc->fragSize) );
 		temp -= adc->fragTotalSize;
 	}
@@ -687,7 +737,7 @@
 	/* adjust nextIn */
 	adc->nextIn += adc->fragSize;
 	if (adc->nextIn >= adc->fragTotalSize) {
-		MIPS_ASSERT(adc->nextIn == adc->fragTotalSize);
+		ASSERT(adc->nextIn == adc->fragTotalSize);
 		adc->nextIn = 0;
 	}
 
@@ -706,13 +756,13 @@
 	unsigned temp;
 
 	/* next DMA transfer should already started */
-	MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
-	MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+	// ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+	// ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
 
 	/* let us set for next next DMA transfer */
 	temp = dac->nextOut + dac->fragSize*2;
 	if (temp >= dac->fragTotalSize) {
-		MIPS_ASSERT( (temp == dac->fragTotalSize) || 
+		ASSERT( (temp == dac->fragTotalSize) || 
                              (temp == dac->fragTotalSize + dac->fragSize) );
 		temp -= dac->fragTotalSize;
 	}
@@ -728,35 +778,35 @@
 		printk("assert fail: - %d vs %d\n", 
 		        *(u16*)(dac->lbuf +  dac->nextOut),
                         outTicket);
-                MIPS_ASSERT(1 == 0);
+                ASSERT(1 == 0);
 	}
 #endif
 
 	/* adjust nextOut pointer */
 	dac->nextOut += dac->fragSize;
 	if (dac->nextOut >= dac->fragTotalSize) {
-		MIPS_ASSERT(dac->nextOut == dac->fragTotalSize);
+		ASSERT(dac->nextOut == dac->fragTotalSize);
 		dac->nextOut = 0;
 	}
 
 	/* adjust count */
 	dac->count -= dac->fragSize;
 	if (dac->count <=0 ) {
-		MIPS_ASSERT(dac->count == 0);
-		MIPS_ASSERT(dac->nextIn == dac->nextOut);
 		/* buffer under run */
+		dac->count = 0;
+		dac->nextIn = dac->nextOut;
 		stop_dac(s);
 	}
 
 #if defined(VRC5477_AC97_VERBOSE_DEBUG)
 	if (dac->count) {
 		outTicket ++;
-		MIPS_ASSERT(*(u16*)(dac->lbuf +  dac->nextOut) == outTicket);
+		ASSERT(*(u16*)(dac->lbuf +  dac->nextOut) == outTicket);
 	}
 #endif
 	
 	/* we cannot have both under run and someone is waiting on us */
-	MIPS_ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
+	ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
 
 	/* wake up anybody listening */
 	if (waitqueue_active(&dac->wait))
@@ -805,12 +855,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static loff_t vrc5477_ac97_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
-
 static int vrc5477_ac97_open_mixdev(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
@@ -852,7 +896,7 @@
 
 static /*const*/ struct file_operations vrc5477_ac97_mixer_fops = {
 	owner:		THIS_MODULE,
-	llseek:		vrc5477_ac97_llseek,
+	llseek:		no_llseek,
 	ioctl:		vrc5477_ac97_ioctl_mixdev,
 	open:		vrc5477_ac97_open_mixdev,
 	release:	vrc5477_ac97_release_mixdev,
@@ -911,7 +955,7 @@
 
 		copyCount -= count;
 		bufStart += count;
-		MIPS_ASSERT(bufStart <= db->fragTotalSize);
+		ASSERT(bufStart <= db->fragTotalSize);
 		buffer += count *2;
 	}
 	return 0;
@@ -943,12 +987,12 @@
 		}
 		if (copyCount + db->nextOut > db->fragTotalSize) {
 			copyCount = db->fragTotalSize - db->nextOut;
-			MIPS_ASSERT((copyCount % db->fragSize) == 0);
+			ASSERT((copyCount % db->fragSize) == 0);
 		}
 
 		copyFragCount = (copyCount-1) >> db->fragShift;
 		copyFragCount = (copyFragCount+1) << db->fragShift;
-		MIPS_ASSERT(copyFragCount >= copyCount);
+		ASSERT(copyFragCount >= copyCount);
 
 		/* we copy differently based on adc channels */
 		if (s->adcChannels == 1) {
@@ -971,12 +1015,12 @@
 
 		db->nextOut += copyFragCount;
 		if (db->nextOut >= db->fragTotalSize) {
-			MIPS_ASSERT(db->nextOut == db->fragTotalSize);
+			ASSERT(db->nextOut == db->fragTotalSize);
 			db->nextOut = 0;
 		}
 
-		MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
-		MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+		ASSERT((copyFragCount % db->fragSize) == 0);
+		ASSERT( (count == 0) || (copyCount == copyFragCount));
 	}
 
 	spin_lock_irqsave(&s->lock, flags);
@@ -1005,7 +1049,7 @@
 	if (!access_ok(VERIFY_WRITE, buffer, count))
 		return -EFAULT;
 
-	MIPS_ASSERT(db->ready);
+	ASSERT(db->ready);
 
 	while (count > 0) {
 		// wait for samples in capture buffer
@@ -1030,7 +1074,7 @@
 			}
 		} while (avail <= 0);
 
-		MIPS_ASSERT( (avail % db->fragSize) == 0);
+		ASSERT( (avail % db->fragSize) == 0);
 		copyCount = copy_adc_to_user(s, buffer, count, avail);
 		if (copyCount <=0 ) {
 			if (!ret) ret = -EFAULT;
@@ -1053,7 +1097,7 @@
 	struct dmabuf *db = &s->dma_dac;
 	int bufStart = db->nextIn;
 
-	MIPS_ASSERT(db->ready);
+	ASSERT(db->ready);
 
         for (; copyCount > 0; ) {
                 int i;
@@ -1071,7 +1115,7 @@
 
                 copyCount -= count;
 		bufStart += count;
-		MIPS_ASSERT(bufStart <= db->fragTotalSize);
+		ASSERT(bufStart <= db->fragTotalSize);
                 buffer += count *2;
         }
         return 0;
@@ -1107,13 +1151,11 @@
 		}
                 if (copyCount + db->nextIn > db->fragTotalSize) {
                         copyCount = db->fragTotalSize - db->nextIn;
-                        MIPS_ASSERT((copyCount % db->fragSize) == 0);
-                        MIPS_ASSERT(copyCount > 0);
+                        ASSERT(copyCount > 0);
                 }
 
-		copyFragCount = (copyCount-1) >> db->fragShift;
-		copyFragCount = (copyFragCount+1) << db->fragShift;
-		MIPS_ASSERT(copyFragCount >= copyCount);
+		copyFragCount = copyCount;
+		ASSERT(copyFragCount >= copyCount);
 
 		/* we copy differently based on the number channels */
 		if (s->dacChannels == 1) {
@@ -1153,12 +1195,11 @@
 
 		db->nextIn += copyFragCount;
 		if (db->nextIn >= db->fragTotalSize) {
-			MIPS_ASSERT(db->nextIn == db->fragTotalSize);
+			ASSERT(db->nextIn == db->fragTotalSize);
 			db->nextIn = 0;
 		}
 
-		MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
-		MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+		ASSERT( (count == 0) || (copyCount == copyFragCount));
 	}
 
 	spin_lock_irqsave(&s->lock, flags);
@@ -1168,7 +1209,7 @@
 	}
 
 	/* nextIn should not be equal to nextOut unless we are full */
-	MIPS_ASSERT( ( (db->count == db->fragTotalSize) && 
+	ASSERT( ( (db->count == db->fragTotalSize) && 
                        (db->nextIn == db->nextOut) ) ||
                      ( (db->count < db->fragTotalSize) &&
                        (db->nextIn != db->nextOut) ) );
@@ -1216,7 +1257,6 @@
 			}
 		} while (avail <= 0);
 	
-		MIPS_ASSERT( (avail % db->fragSize) == 0);
 		copyCount = copy_dac_from_user(s, buffer, count, avail);
 		if (copyCount < 0) {
 			if (!ret) ret = -EFAULT;
@@ -1257,7 +1297,7 @@
 	return mask;
 }
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 static struct ioctl_str_t {
     unsigned int cmd;
     const char* str;
@@ -1308,7 +1348,7 @@
 	int count;
 	int val, ret;
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
 		if (ioctl_str[count].cmd == cmd)
 			break;
@@ -1618,7 +1658,7 @@
 
 static /*const*/ struct file_operations vrc5477_ac97_audio_fops = {
 	owner:	THIS_MODULE,
-	llseek:		vrc5477_ac97_llseek,
+	llseek:		no_llseek,
 	read:		vrc5477_ac97_read,
 	write:		vrc5477_ac97_write,
 	poll:		vrc5477_ac97_poll,
@@ -1639,7 +1679,7 @@
  * CODEC chipstate
  */
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 
 struct {
        const char *regname;
@@ -1763,7 +1803,7 @@
 	return len;
 
 }
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
 
 /* --------------------------------------------------------------------- */
 
@@ -1776,88 +1816,13 @@
 MODULE_DESCRIPTION("NEC Vrc5477 audio (AC97) Driver");
 MODULE_LICENSE("GPL");
 
-/* --------------------------------------------------------------------- */
-extern void jsun_scan_pci_bus(void);
-extern void vrc5477_show_pci_regs(void);
-extern void vrc5477_show_pdar_regs(void);
-
-/* -------------------------------------------------------- */
-#define         AC97_BASE               0xbb000000
-#define         myinl(x)                  *(volatile u32*)(AC97_BASE + (x))
-#define         myoutl(x,y)               *(volatile u32*)(AC97_BASE + (y)) = (x)
-
-u16 myrdcodec(u8 addr)
-{
-        u32 result;
-
-        /* wait until we can access codec registers */
-        // while (inl(VRC5477_CODEC_WR) & 0x80000000);
-
-        /* write the address and "read" command to codec */
-        addr = addr & 0x7f;
-        myoutl((addr << 16) | VRC5477_CODEC_WR_RWC, VRC5477_CODEC_WR);
-
-        /* get the return result */
-        udelay(100); /* workaround hardware bug */
-        // dump_memory(0xbb000000, 48);
-        while ( ((result=myinl(VRC5477_CODEC_RD)) & 0xc0000000) != 0xc0000000);
-        MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
-        return result & 0xffff;
-}
-
-void mywrcodec(u8 addr, u16 data)
-{
-        /* wait until we can access codec registers */
-        while (myinl(VRC5477_CODEC_WR) & 0x80000000);
-
-        /* write the address and value to codec */
-        myoutl((addr << 16) | data, VRC5477_CODEC_WR);
-
-}
-
-
-void jsun_ac97_test(struct vrc5477_ac97_state *s)
-{
-        int i;
-
-        /* reset codec */
-	/*
-        wrcodec(&s->codec, 0, 0);
-        while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
-	*/
-        mywrcodec(0, 0);
-        while (myinl(VRC5477_CODEC_WR) & 0x80000000);
-
-	for (i=0; i< 0x40; i+=4) {	
-	MIPS_ASSERT(inl(s->io+i) == myinl(i));
-	}
-
-        printk("codec registers : ");
-        for (i=0; i<= 0x3a; i+=2) {
-                if ( (i%0x10) == 0) {
-                        printk("\n%02x\t", i);
-                }
-                // printk("%04x\t", rdcodec(&s->codec, i));
-                printk("%04x\t", myrdcodec(i));
-        }
-        printk("\n\n");
-        printk("codec registers : ");
-        for (i=0; i<= 0x3a; i+=2) {
-                if ( (i%0x10) == 0) {
-                        printk("\n%02x\t", i);
-                }
-                printk("%04x\t", rdcodec(&s->codec, i));
-        }
-        printk("\n\n");
-}
-
 static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev,
 					const struct pci_device_id *pciid)
 {
 	struct vrc5477_ac97_state *s;
+#ifdef VRC5477_AC97_DEBUG
 	char proc_str[80];
-
-	MIPS_DEBUG(printk("vrc5477_ac97_probe() invoked\n"));
+#endif
 
 	if (pcidev->irq == 0) 
 		return -1;
@@ -1889,6 +1854,13 @@
          * no persistent state across file opens.
 	 */
 
+	/* test if get response from ac97, if not return */
+        if (ac97_codec_not_present(&(s->codec))) {
+		printk(KERN_ERR PFX "no ac97 codec\n");
+		goto err_region;
+
+        }
+
 	if (!request_region(s->io, pci_resource_len(pcidev,0),
 			    VRC5477_AC97_MODULE_NAME)) {
 		printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
@@ -1910,37 +1882,27 @@
 	     register_sound_mixer(&vrc5477_ac97_mixer_fops, -1)) < 0)
 		goto err_dev2;
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 	/* intialize the debug proc device */
 	s->ps = create_proc_read_entry(VRC5477_AC97_MODULE_NAME, 0, NULL,
 				       proc_vrc5477_ac97_dump, NULL);
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
 	
 	/* enable pci io and bus mastering */
 	if (pci_enable_device(pcidev))
 		goto err_dev3;
 	pci_set_master(pcidev);
 
-/*
-jsun_scan_pci_bus();
-vrc5477_show_pci_regs();
-vrc5477_show_pdar_regs();
-*/
-
 	/* cold reset the AC97 */
 	outl(VRC5477_ACLINK_CTRL_RST_ON | VRC5477_ACLINK_CTRL_RST_TIME,
 	     s->io + VRC5477_ACLINK_CTRL);
 	while (inl(s->io + VRC5477_ACLINK_CTRL) & VRC5477_ACLINK_CTRL_RST_ON);
 
-/*
-jsun_ac97_test(s);
-*/
-
 	/* codec init */
 	if (!ac97_probe_codec(&s->codec))
 		goto err_dev3;
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 	sprintf(proc_str, "driver/%s/%d/ac97", 
 		VRC5477_AC97_MODULE_NAME, s->codec.id);
 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
@@ -1948,16 +1910,28 @@
 	/* TODO : why this proc file does not show up? */
 #endif
 
+	/* Try to enable variable rate audio mode. */
+	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+		rdcodec(&s->codec, AC97_EXTENDED_STATUS) | AC97_EXTSTAT_VRA);
+	/* Did we enable it? */
+	if(rdcodec(&s->codec, AC97_EXTENDED_STATUS) & AC97_EXTSTAT_VRA)
+		s->extended_status |= AC97_EXTSTAT_VRA;
+	else {
+		s->dacRate = 48000;
+		printk(KERN_INFO PFX "VRA mode not enabled; rate fixed at %d.",
+			s->dacRate);
+	}
+
         /* let us get the default volumne louder */
-        wrcodec(&s->codec, 0x2, 0);
-        wrcodec(&s->codec, 0x18, 0x0707);
-	/* mute line in loopback to line out */
-	wrcodec(&s->codec, 0x10, 0x8000);
+        wrcodec(&s->codec, 0x2, 0x1010);	/* master volume, middle */
+        wrcodec(&s->codec, 0xc, 0x10);		/* phone volume, middle */
+        // wrcodec(&s->codec, 0xe, 0x10);		/* misc volume, middle */
+	wrcodec(&s->codec, 0x10, 0x8000);	/* line-in 2 line-out disable */
+        wrcodec(&s->codec, 0x18, 0x0707);	/* PCM out (line out) middle */
+
 
 	/* by default we select line in the input */
 	wrcodec(&s->codec, 0x1a, 0x0404);
-	/* pick middle value for record gain */
-	// wrcodec(&s->codec, 0x1c, 0x0707);
 	wrcodec(&s->codec, 0x1c, 0x0f0f);
 	wrcodec(&s->codec, 0x1e, 0x07);
 
@@ -1995,10 +1969,12 @@
 	if (!s)
 		return;
 	list_del(&s->devs);
-#ifdef CONFIG_LL_DEBUG
+
+#ifdef VRC5477_AC97_DEBUG
 	if (s->ps)
 		remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL);
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
+
 	synchronize_irq();
 	free_irq(s->irq, s);
 	release_region(s->io, pci_resource_len(dev,0));
@@ -2009,8 +1985,6 @@
 }
 
 
-#define		PCI_VENDOR_ID_NEC		0x1033
-#define		PCI_DEVICE_ID_NEC_VRC5477_AC97	0x00A6
 static struct pci_device_id id_table[] __devinitdata = {
     { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC5477_AC97, 
       PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
@@ -2030,7 +2004,7 @@
 {
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
-	printk("Vrc5477 AC97 driver: version v0.1 time " __TIME__ " " __DATE__ " by Jun Sun\n");
+	printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n");
 	return pci_module_init(&vrc5477_ac97_driver);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/nm256_audio.c linux/drivers/sound/nm256_audio.c
--- linux.orig/drivers/sound/nm256_audio.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/sound/nm256_audio.c	2002-07-20 01:08:35.000000000 +0000
@@ -896,7 +896,7 @@
 
     /* Reset the mixer.  'Tis magic!  */
     nm256_writePort8 (card, 2, 0x6c0, 1);
-    nm256_writePort8 (card, 2, 0x6cc, 0x87);
+//  nm256_writePort8 (card, 2, 0x6cc, 0x87);	/* This crashes Dell latitudes */
     nm256_writePort8 (card, 2, 0x6cc, 0x80);
     nm256_writePort8 (card, 2, 0x6cc, 0x0);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- linux.orig/drivers/sound/opl3sa2.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/opl3sa2.c	2002-07-20 01:08:21.000000000 +0000
@@ -56,6 +56,7 @@
  * Scott Murray            Some small cleanups to the init code output.
  *                         (Jan 7, 2001)
  * Zwane Mwaikambo	   Added PM support. (Dec 4 2001)
+ * Zwane Mwaikambo	   Code, data structure cleanups. (Feb 15 2002)
  *
  */
 
@@ -71,6 +72,7 @@
 #include "mpu401.h"
 
 #define OPL3SA2_MODULE_NAME	"opl3sa2"
+#define PFX			OPL3SA2_MODULE_NAME ": "
 
 /* Useful control port indexes: */
 #define OPL3SA2_PM	     0x01
@@ -92,9 +94,10 @@
 #define DEFAULT_TIMBRE 0
 
 /* Power saving modes */
-#define OPL3SA2_PM_MODE1	0x05
-#define OPL3SA2_PM_MODE2	0x04
-#define OPL3SA2_PM_MODE3	0x03
+#define OPL3SA2_PM_MODE0	0x00
+#define OPL3SA2_PM_MODE1	0x04	/* PSV */
+#define OPL3SA2_PM_MODE2	0x05	/* PSV | PDX */
+#define OPL3SA2_PM_MODE3	0x27	/* ADOWN | PSV | PDN | PDX */
 
 /* For checking against what the card returns: */
 #define VERSION_UNKNOWN 0
@@ -108,6 +111,7 @@
 #define CHIPSET_UNKNOWN -1
 #define CHIPSET_OPL3SA2 0
 #define CHIPSET_OPL3SA3 1
+static const char *CHIPSET_TABLE[] = {"OPL3-SA2", "OPL3-SA3"};
 
 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
 #define OPL3SA2_CARDS_MAX 4
@@ -118,38 +122,40 @@
 /* This should be pretty obvious */
 static int opl3sa2_cards_num; /* = 0 */
 
-/* What's my version(s)? */
-static int chipset[OPL3SA2_CARDS_MAX] = { CHIPSET_UNKNOWN };
-
-/* Oh well, let's just cache the name(s) */
-static char chipset_name[OPL3SA2_CARDS_MAX][12];
+typedef struct {
+	/* device resources */
+	unsigned short cfg_port;
+	struct address_info cfg;
+	struct address_info cfg_mss;
+	struct address_info cfg_mpu;
 
-/* Where's my mixer(s)? */
-static int opl3sa2_mixer[OPL3SA2_CARDS_MAX] = { -1 };
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+	/* PnP Stuff */
+	struct pci_dev* pdev;
+	int activated;			/* Whether said devices have been activated */
+#endif
 
-/* Bag o' mixer data */
-typedef struct opl3sa2_mixerdata_tag {
-	unsigned short cfg_port;
-	unsigned short padding;
-	unsigned char  pm_reg;
-	unsigned int   in_suspend;
-	struct pm_dev  *pmdev;
-	unsigned int   card;
-	unsigned int   volume_l;
-	unsigned int   volume_r;
-	unsigned int   mic;
-	unsigned int   bass_l;
-	unsigned int   bass_r;
-	unsigned int   treble_l;
-	unsigned int   treble_r;
-	unsigned int   wide_l;
-	unsigned int   wide_r;
-} opl3sa2_mixerdata;
-static opl3sa2_mixerdata opl3sa2_data[OPL3SA2_CARDS_MAX];
-
-static struct address_info cfg[OPL3SA2_CARDS_MAX];
-static struct address_info cfg_mss[OPL3SA2_CARDS_MAX];
-static struct address_info cfg_mpu[OPL3SA2_CARDS_MAX];
+#ifdef CONFIG_PM
+	unsigned int	in_suspend;
+	struct pm_dev	*pmdev;
+#endif
+	unsigned int	card;
+	int		chipset;	/* What's my version(s)? */
+	char		*chipset_name;
+
+	/* mixer data */
+	int		mixer;
+	unsigned int	volume_l;
+	unsigned int	volume_r;
+	unsigned int	mic;
+	unsigned int	bass_l;
+	unsigned int	bass_r;
+	unsigned int	treble_l;
+	unsigned int	treble_r;
+	unsigned int	wide_l;
+	unsigned int	wide_r;
+} opl3sa2_state_t;
+static opl3sa2_state_t opl3sa2_state[OPL3SA2_CARDS_MAX];
 
 /* Our parameters */
 static int __initdata io	= -1;
@@ -166,11 +172,6 @@
 static int __initdata isapnp = 1;
 static int __initdata multiple = 1;
 
-/* PnP devices */
-struct pci_dev* opl3sa2_dev[OPL3SA2_CARDS_MAX];
-
-/* Whether said devices have been activated */
-static int opl3sa2_activated[OPL3SA2_CARDS_MAX];
 #else
 static int __initdata isapnp; /* = 0 */
 static int __initdata multiple; /* = 0 */
@@ -240,7 +241,7 @@
  * All of the mixer functions...
  */
 
-static void opl3sa2_set_volume(opl3sa2_mixerdata* devc, int left, int right)
+static void opl3sa2_set_volume(opl3sa2_state_t* devc, int left, int right)
 {
 	static unsigned char scale[101] = {
 		0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e,
@@ -275,7 +276,7 @@
 }
 
 
-static void opl3sa2_set_mic(opl3sa2_mixerdata* devc, int level)
+static void opl3sa2_set_mic(opl3sa2_state_t* devc, int level)
 {
 	unsigned char vol = 0x1F;
 
@@ -290,7 +291,7 @@
 }
 
 
-static void opl3sa3_set_bass(opl3sa2_mixerdata* devc, int left, int right)
+static void opl3sa3_set_bass(opl3sa2_state_t* devc, int left, int right)
 {
 	unsigned char bass;
 
@@ -301,7 +302,7 @@
 }
 
 
-static void opl3sa3_set_treble(opl3sa2_mixerdata* devc, int left, int right)
+static void opl3sa3_set_treble(opl3sa2_state_t* devc, int left, int right)
 {	
 	unsigned char treble;
 
@@ -312,7 +313,7 @@
 }
 
 
-static void opl3sa3_set_wide(opl3sa2_mixerdata* devc, int left, int right)
+static void opl3sa3_set_wide(opl3sa2_state_t* devc, int left, int right)
 {	
 	unsigned char wide;
 
@@ -323,7 +324,7 @@
 }
 
 
-static void opl3sa2_mixer_reset(opl3sa2_mixerdata* devc, int card)
+static void opl3sa2_mixer_reset(opl3sa2_state_t* devc)
 {
 	if(devc) {
 		opl3sa2_set_volume(devc, DEFAULT_VOLUME, DEFAULT_VOLUME);
@@ -332,7 +333,7 @@
 		opl3sa2_set_mic(devc, DEFAULT_MIC);
 		devc->mic = DEFAULT_MIC;
 
-		if(chipset[card] == CHIPSET_OPL3SA3) {
+		if(devc->chipset == CHIPSET_OPL3SA3) {
 			opl3sa3_set_bass(devc, DEFAULT_TIMBRE, DEFAULT_TIMBRE);
 			devc->bass_l = devc->bass_r = DEFAULT_TIMBRE;
 			opl3sa3_set_treble(devc, DEFAULT_TIMBRE, DEFAULT_TIMBRE);
@@ -342,13 +343,13 @@
 }
 
 
-static void opl3sa2_mixer_restore(opl3sa2_mixerdata* devc, int card)
+static void opl3sa2_mixer_restore(opl3sa2_state_t* devc)
 {
 	if (devc) {
 		opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
 		opl3sa2_set_mic(devc, devc->mic);
 
-		if (chipset[card] == CHIPSET_OPL3SA3) {
+		if (devc->chipset == CHIPSET_OPL3SA3) {
 			opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r);
 			opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r);
 		}
@@ -390,7 +391,7 @@
 {
 	int cmdf = cmd & 0xff;
 
-	opl3sa2_mixerdata* devc = (opl3sa2_mixerdata*) mixer_devs[dev]->devc;
+	opl3sa2_state_t* devc = (opl3sa2_state_t *) mixer_devs[dev]->devc;
 	
 	switch(cmdf) {
 		case SOUND_MIXER_VOLUME:
@@ -473,7 +474,7 @@
 {
 	int cmdf = cmd & 0xff;
 
-	opl3sa2_mixerdata* devc = (opl3sa2_mixerdata*) mixer_devs[dev]->devc;
+	opl3sa2_state_t* devc = (opl3sa2_state_t *) mixer_devs[dev]->devc;
 
 	switch(cmdf) {
 		case SOUND_MIXER_BASS:
@@ -616,7 +617,7 @@
 			AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
 		}
 		else {
-			printk(KERN_ERR "opl3sa2: MSS mixer not installed?\n");
+			printk(KERN_ERR PFX "MSS mixer not installed?\n");
 		}
 	}
 }
@@ -633,15 +634,14 @@
 	unsigned char misc;
 	unsigned char tmp;
 	unsigned char version;
-	char tag;
 
 	/*
 	 * Try and allocate our I/O port range.
 	 */
 	if(!request_region(hw_config->io_base, 2, OPL3SA2_MODULE_NAME)) {
-		printk(KERN_ERR "opl3sa2: Control I/O port %#x not free\n",
+		printk(KERN_ERR PFX "Control I/O port %#x not free\n",
 		       hw_config->io_base);
-		return 0;
+		goto out_nodev;
 	}
 
 	/*
@@ -652,9 +652,9 @@
 	opl3sa2_write(hw_config->io_base, OPL3SA2_MISC, misc ^ 0x07);
 	opl3sa2_read(hw_config->io_base, OPL3SA2_MISC, &tmp);
 	if(tmp != misc) {
-		printk(KERN_ERR "opl3sa2: Control I/O port %#x is not a YMF7xx chipset!\n",
+		printk(KERN_ERR PFX "Control I/O port %#x is not a YMF7xx chipset!\n",
 		       hw_config->io_base);
-		return 0;
+		goto out_region;
 	}
 
 	/*
@@ -665,9 +665,9 @@
 	opl3sa2_read(hw_config->io_base, OPL3SA2_MIC, &tmp);
 	if((tmp & 0x9f) != 0x8a) {
 		printk(KERN_ERR
-		       "opl3sa2: Control I/O port %#x is not a YMF7xx chipset!\n",
+		       PFX "Control I/O port %#x is not a YMF7xx chipset!\n",
 		       hw_config->io_base);
-		return 0;
+		goto out_region;
 	}
 	opl3sa2_write(hw_config->io_base, OPL3SA2_MIC, tmp);
 
@@ -678,50 +678,49 @@
 	 * of the miscellaneous register.
 	 */
 	version = misc & 0x07;
-	printk(KERN_DEBUG "opl3sa2: chipset version = %#x\n", version);
+	printk(KERN_DEBUG PFX "chipset version = %#x\n", version);
 	switch(version) {
 		case 0:
-			chipset[card] = CHIPSET_UNKNOWN;
-			tag = '?'; /* silence compiler warning */
+			opl3sa2_state[card].chipset = CHIPSET_UNKNOWN;
 			printk(KERN_ERR
-			       "opl3sa2: Unknown Yamaha audio controller version\n");
+			       PFX "Unknown Yamaha audio controller version\n");
 			break;
 
 		case VERSION_YMF711:
-			chipset[card] = CHIPSET_OPL3SA2;
-			tag = '2';
-			printk(KERN_INFO "opl3sa2: Found OPL3-SA2 (YMF711)\n");
+			opl3sa2_state[card].chipset = CHIPSET_OPL3SA2;
+			printk(KERN_INFO PFX "Found OPL3-SA2 (YMF711)\n");
 			break;
 
 		case VERSION_YMF715:
-			chipset[card] = CHIPSET_OPL3SA3;
-			tag = '3';
+			opl3sa2_state[card].chipset = CHIPSET_OPL3SA3;
 			printk(KERN_INFO
-			       "opl3sa2: Found OPL3-SA3 (YMF715 or YMF719)\n");
+			       PFX "Found OPL3-SA3 (YMF715 or YMF719)\n");
 			break;
 
 		case VERSION_YMF715B:
-			chipset[card] = CHIPSET_OPL3SA3;
-			tag = '3';
+			opl3sa2_state[card].chipset = CHIPSET_OPL3SA3;
 			printk(KERN_INFO
-			       "opl3sa2: Found OPL3-SA3 (YMF715B or YMF719B)\n");
+			       PFX "Found OPL3-SA3 (YMF715B or YMF719B)\n");
 			break;
 
 		case VERSION_YMF715E:
 		default:
-			chipset[card] = CHIPSET_OPL3SA3;
-			tag = '3';
+			opl3sa2_state[card].chipset = CHIPSET_OPL3SA3;
 			printk(KERN_INFO
-			       "opl3sa2: Found OPL3-SA3 (YMF715E or YMF719E)\n");
+			       PFX "Found OPL3-SA3 (YMF715E or YMF719E)\n");
 			break;
 	}
 
-	if(chipset[card] != CHIPSET_UNKNOWN) {
+	if(opl3sa2_state[card].chipset != CHIPSET_UNKNOWN) {
 		/* Generate a pretty name */
-		sprintf(chipset_name[card], "OPL3-SA%c", tag);
-		return 1;
+		opl3sa2_state[card].chipset_name = (char *)CHIPSET_TABLE[opl3sa2_state[card].chipset];
+		return 0;
 	}
-	return 0;
+
+out_region:
+	release_region(hw_config->io_base, 2);
+out_nodev:
+	return -ENODEV;
 }
 
 
@@ -746,30 +745,28 @@
 static void __init attach_opl3sa2_mixer(struct address_info *hw_config, int card)
 {
 	struct mixer_operations* mixer_operations;
-	opl3sa2_mixerdata* devc;
+	opl3sa2_state_t* devc = &opl3sa2_state[card];
 
 	/* Install master mixer */
-	if(chipset[card] == CHIPSET_OPL3SA3) {
+	if(devc->chipset == CHIPSET_OPL3SA3) {
 		mixer_operations = &opl3sa3_mixer_operations;
 	}
 	else {
 		mixer_operations = &opl3sa2_mixer_operations;
 	}
 
-	if((devc = &opl3sa2_data[card])) {
-		devc->cfg_port = hw_config->io_base;
-
-		opl3sa2_mixer[card] = sound_install_mixer(MIXER_DRIVER_VERSION,
-							  mixer_operations->name,
-							  mixer_operations,
-							  sizeof(struct mixer_operations),
-							  devc);
-		if(opl3sa2_mixer[card] < 0) {
-			printk(KERN_ERR "opl3sa2: Could not install %s master mixer\n",
-				 mixer_operations->name);
-		}
-		else
-			opl3sa2_mixer_reset(devc, card);
+	devc->cfg_port = hw_config->io_base;
+	devc->mixer = sound_install_mixer(MIXER_DRIVER_VERSION,
+					  mixer_operations->name,
+					  mixer_operations,
+					  sizeof(struct mixer_operations),
+					  devc);
+	if(devc->mixer < 0) {
+		printk(KERN_ERR PFX "Could not install %s master mixer\n",
+			 mixer_operations->name);
+	}
+	else {
+			opl3sa2_mixer_reset(devc);
 	}
 }
 
@@ -803,7 +800,7 @@
 		opl3sa2_write(hw_config->io_base, OPL3SA2_SYS_CTRL, sys_ctrl);
 	}
 	else {
-		printk(KERN_ERR "opl3sa2: not setting ymode, it must be one of 0,1,2,3\n");
+		printk(KERN_ERR PFX "not setting ymode, it must be one of 0,1,2,3\n");
 	}
 }
 
@@ -818,7 +815,7 @@
 		opl3sa2_write(hw_config->io_base, OPL3SA2_MISC, misc);
 	}
 	else {
-		printk(KERN_ERR "opl3sa2: not setting loopback, it must be either 0 or 1\n");
+		printk(KERN_ERR PFX "not setting loopback, it must be either 0 or 1\n");
 	}
 }
 
@@ -829,8 +826,8 @@
 	release_region(hw_config->io_base, 2);
 
 	/* Unload mixer */
-	if(opl3sa2_mixer[card] >= 0)
-		sound_unload_mixerdev(opl3sa2_mixer[card]);
+	if(opl3sa2_state[card].mixer >= 0)
+		sound_unload_mixerdev(opl3sa2_state[card].mixer);
 }
 
 
@@ -868,21 +865,21 @@
 	 */
 	ret = dev->prepare(dev);
 	if(ret && ret != -EBUSY) {
-		printk(KERN_ERR "opl3sa2: ISA PnP found device that could not be autoconfigured.\n");
+		printk(KERN_ERR PFX "ISA PnP found device that could not be autoconfigured.\n");
 		return -ENODEV;
 	}
 	if(ret == -EBUSY) {
-		opl3sa2_activated[card] = 1;
+		opl3sa2_state[card].activated = 1;
 	}
 	else {
 		if(dev->activate(dev) < 0) {
-			printk(KERN_WARNING "opl3sa2: ISA PnP activate failed\n");
-			opl3sa2_activated[card] = 0;
+			printk(KERN_WARNING PFX "ISA PnP activate failed\n");
+			opl3sa2_state[card].activated = 0;
 			return -ENODEV;
 		}
 
 		printk(KERN_DEBUG
-		       "opl3sa2: Activated ISA PnP card %d (active=%d)\n",
+		       PFX "Activated ISA PnP card %d (active=%d)\n",
 		       card, dev->active);
 
 	}
@@ -911,7 +908,7 @@
 	opl3sa2_clear_slots(mss_cfg);
 	opl3sa2_clear_slots(mpu_cfg);
 
-	opl3sa2_dev[card] = dev;
+	opl3sa2_state[card].pdev = dev;
 
 	return 0;
 }
@@ -919,11 +916,12 @@
 
 /* End of component functions */
 
+#ifdef CONFIG_PM
 /* Power Management support functions */
 static int opl3sa2_suspend(struct pm_dev *pdev, unsigned char pm_mode)
 {
 	unsigned long flags;
-	opl3sa2_mixerdata *p;
+	opl3sa2_state_t *p;
 
 	if (!pdev)
 		return -EINVAL;
@@ -931,7 +929,7 @@
 	save_flags(flags);
 	cli();
 
-	p = (opl3sa2_mixerdata *) pdev->data;
+	p = (opl3sa2_state_t *) pdev->data;
 
 	switch (pm_mode) {
 	case 1:
@@ -951,8 +949,7 @@
 
 	p->in_suspend = 1;
 	/* its supposed to automute before suspending, so we wont bother */
-	opl3sa2_read(p->cfg_port, OPL3SA2_PM, &p->pm_reg);
-	opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->pm_reg | pm_mode);
+	opl3sa2_write(p->cfg_port, OPL3SA2_PM, pm_mode);
 	/* wait a while for the clock oscillator to stabilise */
 	mdelay(10);
 
@@ -963,18 +960,17 @@
 static int opl3sa2_resume(struct pm_dev *pdev)
 {
 	unsigned long flags;
-	opl3sa2_mixerdata *p;
+	opl3sa2_state_t *p;
 
 	if (!pdev)
 		return -EINVAL;
 
-	p = (opl3sa2_mixerdata *) pdev->data;
+	p = (opl3sa2_state_t *) pdev->data;
 	save_flags(flags);
 	cli();
 
-	/* I don't think this is necessary */
-	opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->pm_reg);
-	opl3sa2_mixer_restore(p, p->card);
+	opl3sa2_write(p->cfg_port, OPL3SA2_PM, OPL3SA2_PM_MODE0);
+	opl3sa2_mixer_restore(p);
 	p->in_suspend = 0;
 
 	restore_flags(flags);
@@ -983,7 +979,7 @@
 
 static int opl3sa2_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
 {
-	unsigned char mode = (unsigned  char)data;
+	unsigned char mode = (unsigned  long)data;
 
 	switch (rqst) {
 		case PM_SUSPEND:
@@ -994,6 +990,7 @@
 	}
 	return 0;
 }
+#endif /* CONFIG_PM */
 
 /*
  * Install OPL3-SA2 based card(s).
@@ -1017,16 +1014,16 @@
 		 * should still be able to disable PNP support for this 
 		 * single driver!
 		 */
-		if(isapnp && opl3sa2_isapnp_probe(&cfg[card],
-						  &cfg_mss[card],
-						  &cfg_mpu[card],
+		if(isapnp && opl3sa2_isapnp_probe(&opl3sa2_state[card].cfg,
+						  &opl3sa2_state[card].cfg_mss,
+						  &opl3sa2_state[card].cfg_mpu,
 						  card) < 0) {
 			if(!opl3sa2_cards_num)
-				printk(KERN_INFO "opl3sa2: No PnP cards found\n");
+				printk(KERN_INFO PFX "No PnP cards found\n");
 			if(io == -1)
 				break;
 			isapnp=0;
-			printk(KERN_INFO "opl3sa2: Search for a card at 0x%d.\n", io);
+			printk(KERN_INFO PFX "Search for a card at 0x%d.\n", io);
 			/* Fall through */
 		}
 #endif
@@ -1036,7 +1033,7 @@
 			if(io == -1 || irq == -1 || dma == -1 ||
 			   dma2 == -1 || mss_io == -1) {
 				printk(KERN_ERR
-				       "opl3sa2: io, mss_io, irq, dma, and dma2 must be set\n");
+				       PFX "io, mss_io, irq, dma, and dma2 must be set\n");
 				return -EINVAL;
 			}
 
@@ -1045,31 +1042,31 @@
 			 * (NOTE: IRQ and DMA aren't used, so they're set to
 			 *  give pretty output from conf_printf. :)
 			 */
-			cfg[card].io_base = io;
-			cfg[card].irq     = irq;
-			cfg[card].dma     = dma;
-			cfg[card].dma2    = dma2;
+			opl3sa2_state[card].cfg.io_base = io;
+			opl3sa2_state[card].cfg.irq     = irq;
+			opl3sa2_state[card].cfg.dma     = dma;
+			opl3sa2_state[card].cfg.dma2    = dma2;
 	
 			/* The MSS config: */
-			cfg_mss[card].io_base      = mss_io;
-			cfg_mss[card].irq          = irq;
-			cfg_mss[card].dma          = dma;
-			cfg_mss[card].dma2         = dma2;
-			cfg_mss[card].card_subtype = 1; /* No IRQ or DMA setup */
-
-			cfg_mpu[card].io_base       = mpu_io;
-			cfg_mpu[card].irq           = irq;
-			cfg_mpu[card].dma           = -1;
-			cfg_mpu[card].always_detect = 1; /* Use shared IRQs */
+			opl3sa2_state[card].cfg_mss.io_base      = mss_io;
+			opl3sa2_state[card].cfg_mss.irq          = irq;
+			opl3sa2_state[card].cfg_mss.dma          = dma;
+			opl3sa2_state[card].cfg_mss.dma2         = dma2;
+			opl3sa2_state[card].cfg_mss.card_subtype = 1; /* No IRQ or DMA setup */
+
+			opl3sa2_state[card].cfg_mpu.io_base       = mpu_io;
+			opl3sa2_state[card].cfg_mpu.irq           = irq;
+			opl3sa2_state[card].cfg_mpu.dma           = -1;
+			opl3sa2_state[card].cfg_mpu.always_detect = 1; /* Use shared IRQs */
 
 			/* Call me paranoid: */
-			opl3sa2_clear_slots(&cfg[card]);
-			opl3sa2_clear_slots(&cfg_mss[card]);
-			opl3sa2_clear_slots(&cfg_mpu[card]);
+			opl3sa2_clear_slots(&opl3sa2_state[card].cfg);
+			opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mss);
+			opl3sa2_clear_slots(&opl3sa2_state[card].cfg_mpu);
 		}
 
-		if(!probe_opl3sa2(&cfg[card], card) ||
-		   !probe_opl3sa2_mss(&cfg_mss[card])) {
+		if(probe_opl3sa2(&opl3sa2_state[card].cfg, card) ||
+		   !probe_opl3sa2_mss(&opl3sa2_state[card].cfg_mss)) {
 			/*
 			 * If one or more cards are already registered, don't
 			 * return an error but print a warning.  Note, this
@@ -1078,7 +1075,7 @@
 			 */
 			if(opl3sa2_cards_num) {
 				printk(KERN_WARNING
-				       "opl3sa2: There was a problem probing one "
+				       PFX "There was a problem probing one "
 				       " of the ISA PNP cards, continuing\n");
 				opl3sa2_cards_num--;
 				continue;
@@ -1086,47 +1083,51 @@
 				return -ENODEV;
 		}
 
-		attach_opl3sa2(&cfg[card], card);
-		conf_printf(chipset_name[card], &cfg[card]);
-		attach_opl3sa2_mss(&cfg_mss[card]);
-		attach_opl3sa2_mixer(&cfg[card], card);
+		attach_opl3sa2(&opl3sa2_state[card].cfg, card);
+		conf_printf(opl3sa2_state[card].chipset_name, &opl3sa2_state[card].cfg);
+		attach_opl3sa2_mss(&opl3sa2_state[card].cfg_mss);
+		attach_opl3sa2_mixer(&opl3sa2_state[card].cfg, card);
+
+		/* ewww =) */
+		opl3sa2_state[card].card = card;
 
-		opl3sa2_data[card].card = card;
+#ifdef CONFIG_PM
 		/* register our power management capabilities */
-		opl3sa2_data[card].pmdev = pm_register(PM_ISA_DEV, card, opl3sa2_pm_callback);
-		if (opl3sa2_data[card].pmdev)
-			opl3sa2_data[card].pmdev->data = &opl3sa2_data[card];
+		opl3sa2_state[card].pmdev = pm_register(PM_ISA_DEV, card, opl3sa2_pm_callback);
+		if (opl3sa2_state[card].pmdev)
+			opl3sa2_state[card].pmdev->data = &opl3sa2_state[card];
+#endif
 
 		/*
 		 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
 		 * it's supported.
 		 */
 		if(ymode != -1) {
-			if(chipset[card] == CHIPSET_OPL3SA2) {
+			if(opl3sa2_state[card].chipset == CHIPSET_OPL3SA2) {
 				printk(KERN_ERR
-				       "opl3sa2: ymode not supported on OPL3-SA2\n");
+				       PFX "ymode not supported on OPL3-SA2\n");
 			}
 			else {
-				opl3sa2_set_ymode(&cfg[card], ymode);
+				opl3sa2_set_ymode(&opl3sa2_state[card].cfg, ymode);
 			}
 		}
 
 
 		/* Set A/D input to Mono loopback if asked to. */
 		if(loopback != -1) {
-			opl3sa2_set_loopback(&cfg[card], loopback);
+			opl3sa2_set_loopback(&opl3sa2_state[card].cfg, loopback);
 		}
 		
 		/* Attach MPU if we've been asked to do so */
-		if(cfg_mpu[card].io_base != -1) {
-			if(probe_opl3sa2_mpu(&cfg_mpu[card])) {
-				attach_opl3sa2_mpu(&cfg_mpu[card]);
+		if(opl3sa2_state[card].cfg_mpu.io_base != -1) {
+			if(probe_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu)) {
+				attach_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu);
 			}
 		}
 	}
 
 	if(isapnp) {
-		printk(KERN_NOTICE "opl3sa2: %d PnP card(s) found.\n", opl3sa2_cards_num);
+		printk(KERN_NOTICE PFX "%d PnP card(s) found.\n", opl3sa2_cards_num);
 	}
 
 	return 0;
@@ -1141,22 +1142,23 @@
 	int card;
 
 	for(card = 0; card < opl3sa2_cards_num; card++) {
-		if (opl3sa2_data[card].pmdev)
-			pm_unregister(opl3sa2_data[card].pmdev);
-
-	        if(cfg_mpu[card].slots[1] != -1) {
-			unload_opl3sa2_mpu(&cfg_mpu[card]);
+#ifdef CONFIG_PM
+		if (opl3sa2_state[card].pmdev)
+			pm_unregister(opl3sa2_state[card].pmdev);
+#endif
+	        if(opl3sa2_state[card].cfg_mpu.slots[1] != -1) {
+			unload_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu);
 		}
-		unload_opl3sa2_mss(&cfg_mss[card]);
-		unload_opl3sa2(&cfg[card], card);
+		unload_opl3sa2_mss(&opl3sa2_state[card].cfg_mss);
+		unload_opl3sa2(&opl3sa2_state[card].cfg, card);
 
 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
-		if(opl3sa2_activated[card] && opl3sa2_dev[card]) {
-			opl3sa2_dev[card]->deactivate(opl3sa2_dev[card]);
+		if(opl3sa2_state[card].activated && opl3sa2_state[card].pdev) {
+			opl3sa2_state[card].pdev->deactivate(opl3sa2_state[card].pdev);
 
 			printk(KERN_DEBUG
-			       "opl3sa2: Deactivated ISA PnP card %d (active=%d)\n",
-			       card, opl3sa2_dev[card]->active);
+			       PFX "Deactivated ISA PnP card %d (active=%d)\n",
+			       card, opl3sa2_state[card].pdev->active);
 		}
 #endif
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/rme96xx.c linux/drivers/sound/rme96xx.c
--- linux.orig/drivers/sound/rme96xx.c	2001-10-25 20:53:52.000000000 +0000
+++ linux/drivers/sound/rme96xx.c	2002-07-20 01:08:33.000000000 +0000
@@ -2,14 +2,23 @@
    with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
    based on es1370.c
 
-
-
    *  10 Jan 2001: 0.1 initial version
    *  19 Jan 2001: 0.2 fixed bug in select()
    *  27 Apr 2001: 0.3 more than one card usable
    *  11 May 2001: 0.4 fixed for SMP, included into kernel source tree
    *  17 May 2001: 0.5 draining code didn't work on new cards
    *  18 May 2001: 0.6 remove synchronize_irq() call 
+   *  17 Jul 2001: 0.7 updated xrmectrl to make it work for newer cards
+   *   2 feb 2002: 0.8 fixed pci device handling, see below for patches from Heiko (Thanks!)
+                       Marcus Meissner <Marcus.Meissner@caldera.de>
+
+		       Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
+		       HP20020108 fixed handling of "large" read()
+		       HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
+		       HP20020118 made mixer ioctl and handling of devices>1 more safe
+		       HP20020201 fixed handling of "large" read() properly
+		       added REV 1.5 S/P-DIF receiver support
+		       SNDCTL_DSP_SPEED now returns the actual speed
 
 TODO:
    - test more than one card --- done
@@ -19,15 +28,18 @@
    - mixer mmap interface
    - mixer ioctl
    - get rid of noise upon first open (why ??)
-   - allow multiple open(at least for read)
+   - allow multiple open (at least for read)
    - allow multiple open for non overlapping regions
    - recheck the multiple devices part (offsets of different devices, etc)
    - do decent draining in _release --- done
    - SMP support
+   - what about using fragstotal>2 for small fragsize? (HP20020118)
+   - add support for AFMT_S32_LE
 */
 
+
 #ifndef RMEVERSION
-#define RMEVERSION "0.6"
+#define RMEVERSION "0.8"
 #endif
 
 #include <linux/version.h>
@@ -54,7 +66,7 @@
 
 MODULE_AUTHOR("Guenter Geiger, geiger@debian.org");
 MODULE_DESCRIPTION("RME9652/36 \"Hammerfall\" Driver");
-MODULE_LICENSE("GPL");
+/*MODULE_LICENSE("GPL");*/
 
 
 #ifdef DEBUG
@@ -125,48 +137,60 @@
 
 #define RME96xx_tc_busy      0x0100000 /* 1=time-code copy in progress (960ms) */
 #define RME96xx_tc_out       0x0200000 /* time-code out bit */
-#define RME96xx_F_0          0x0400000 /*  000=64kHz, 100=88.2kHz, 011=96kHz  */
-#define RME96xx_F_1          0x0800000 /*  111=32kHz, 110=44.1kHz, 101=48kHz, */
+#define RME96xx_F_0          0x0400000 /*  000=64kHz, 100=88.2kHz, 011=96kHz */
+#define RME96xx_F_1          0x0800000 /*  111=32kHz, 110=44.1kHz, 101=48kHz */
 
-#define RME96xx_F_2          0x1000000 /*  od external Crystal Chip if ERF=1*/
+#define RME96xx_F_2          0x1000000 /*  001=Rev 1.5+ external Crystal Chip */
 #define RME96xx_ERF          0x2000000 /* Error-Flag of SDPIF Receiver (1=No Lock)*/
 #define RME96xx_buffer_id    0x4000000 /* toggles by each interrupt on rec/play */
 #define RME96xx_tc_valid     0x8000000 /* 1 = a signal is detected on time-code input */
+#define RME96xx_SPDIF_READ  0x10000000 /* byte available from Rev 1.5+ SPDIF interface */
 
 /* Status Register Fields */
 
 #define RME96xx_lock            (RME96xx_lock_0|RME96xx_lock_1|RME96xx_lock_2)
-#define RME96xx_buf_pos          0x000FFC0 
 #define RME96xx_sync            (RME96xx_sync_0|RME96xx_sync_1|RME96xx_sync_2)
 #define RME96xx_F               (RME96xx_F_0|RME96xx_F_1|RME96xx_F_2)
+#define rme96xx_decode_spdif_rate(x) ((x)>>22)
 
+/* Bit 6..15 : h/w buffer pointer */
+#define RME96xx_buf_pos          0x000FFC0 
+/* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later
+   Rev G EEPROMS and Rev 1.5 cards or later.
+*/ 
+#define RME96xx_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME96xx_buf_pos))
 
 
 /* Control-Register: */			    
 /*--------------------------------------------------------------------------------*/
 
-#define RME96xx_start_bit	   0x0001    /* start record/play */
-#define RME96xx_latency0	   0x0002    /* Bit 0 -  Buffer size or latency */
-#define RME96xx_latency1	   0x0004    /* Bit 1 - Buffer size or latency */
-#define RME96xx_latency2	   0x0008    /* Bit 2 - Buffer size or latency */
-
-#define RME96xx_Master		   0x0010   /* Clock Mode Master=1,Slave/Auto=0 */
-#define RME96xx_IE		   0x0020   /* Interupt Enable */
-#define RME96xx_freq		   0x0040   /* samplerate 0=44.1/88.2, 1=48/96 kHz*/
-
-
-#define RME96xx_DS                 0x0100   /* Doule Speed 0=44.1/48, 1=88.2/96 Khz */
-#define RME96xx_PRO		   0x0200    /* spdif 0=consumer, 1=professional Mode*/
-#define RME96xx_EMP		   0x0400    /* spdif Emphasis 0=None, 1=ON */
-#define RME96xx_Dolby		   0x0800    /* spdif Non-audio bit 1=set, 0=unset */
-
-#define RME96xx_opt_out	           0x1000  /* Use 1st optical OUT as SPDIF: 1=yes,0=no */
-#define RME96xx_wsel               0x2000  /* use Wordclock as sync (overwrites master)*/
-#define RME96xx_inp_0              0x4000  /* SPDIF-IN: 00=optical (ADAT1),     */
-#define RME96xx_inp_1              0x8000  /* 01=koaxial (Cinch), 10=Internal CDROM*/
-
-#define RME96xx_SyncRef0           0x10000  /* preferred sync-source in autosync */
-#define RME96xx_SyncRef1           0x20000  /* 00=ADAT1,01=ADAT2,10=ADAT3,11=SPDIF */
+#define RME96xx_start_bit	0x0001 /* start record/play */
+#define RME96xx_latency0	0x0002 /* Buffer size / latency */
+#define RME96xx_latency1	0x0004 /*   buffersize = 512Bytes * 2^n */
+#define RME96xx_latency2	0x0008 /*   0=64samples ... 7=8192samples */
+
+#define RME96xx_Master		0x0010 /* Clock Mode 1=Master, 0=Slave/Auto */
+#define RME96xx_IE		0x0020 /* Interupt Enable */
+#define RME96xx_freq		0x0040 /* samplerate 0=44.1/88.2, 1=48/96 kHz*/
+#define RME96xx_freq1		0x0080 /* samplerate 0=32 kHz, 1=other rates ??? (from ALSA, but may be wrong) */
+#define RME96xx_DS              0x0100 /* double speed 0=44.1/48, 1=88.2/96 Khz */
+#define RME96xx_PRO		0x0200 /* SPDIF-OUT 0=consumer, 1=professional */
+#define RME96xx_EMP		0x0400 /* SPDIF-OUT emphasis 0=off, 1=on */
+#define RME96xx_Dolby		0x0800 /* SPDIF-OUT non-audio bit 1=set, 0=unset */
+
+#define RME96xx_opt_out	        0x1000 /* use 1st optical OUT as SPDIF: 1=yes, 0=no */
+#define RME96xx_wsel            0x2000 /* use Wordclock as sync (overwrites master) */
+#define RME96xx_inp_0           0x4000 /* SPDIF-IN 00=optical (ADAT1), */
+#define RME96xx_inp_1           0x8000 /* 01=coaxial (Cinch), 10=internal CDROM */
+
+#define RME96xx_SyncRef0       0x10000 /* preferred sync-source in autosync */
+#define RME96xx_SyncRef1       0x20000 /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
+
+#define RME96xx_SPDIF_RESET    (1<<18) /* Rev 1.5+: h/w SPDIF receiver */
+#define RME96xx_SPDIF_SELECT   (1<<19)
+#define RME96xx_SPDIF_CLOCK    (1<<20)
+#define RME96xx_SPDIF_WRITE    (1<<21)
+#define RME96xx_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */
 
 
 #define RME96xx_ctrl_init            (RME96xx_latency0 |\
@@ -174,13 +198,14 @@
                                      RME96xx_inp_1)
                               
 
-
 /* Control register fields and shortcuts */
 
 #define RME96xx_latency (RME96xx_latency0|RME96xx_latency1|RME96xx_latency2)
 #define RME96xx_inp         (RME96xx_inp_0|RME96xx_inp_1)
 #define RME96xx_SyncRef    (RME96xx_SyncRef0|RME96xx_SyncRef1)
-/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit0 */
+#define RME96xx_mixer_allowed (RME96xx_Master|RME96xx_PRO|RME96xx_EMP|RME96xx_Dolby|RME96xx_opt_out|RME96xx_wsel|RME96xx_inp|RME96xx_SyncRef|RME96xx_ADAT1_INTERNAL)
+
+/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit1  (??? HP20020201) */
 
 #define RME96xx_SET_LATENCY(x)   (((x)&0x7)<<1)
 #define RME96xx_GET_LATENCY(x)   (((x)>>1)&0x7)
@@ -205,8 +230,10 @@
 
 
 #define RME96xx_MAX_DEVS 4 /* we provide some OSS stereodevs */
+#define RME96xx_MASK_DEVS 0x3 /* RME96xx_MAX_DEVS-1 */
 
 #define RME_MESS "rme96xx:"
+
 /*------------------------------------------------------------------------ 
                   Types, struct and function declarations 
  ------------------------------------------------------------------------*/
@@ -253,8 +280,10 @@
 
 	u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */
 
-	int open_count;
+	int hw_rev;             /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */
+	char *card_name;	/* hammerfall or hammerfall light names */
 
+	int open_count;         /* unused ???   HP20020201 */
 
 	int rate;
 	int latency;
@@ -318,6 +347,181 @@
 
 }
 
+inline int rme96xx_get_sample_rate_status(rme96xx_info* s)
+{
+	int val;
+	u32 status;
+	status = readl(s->iobase + RME96xx_status_register);
+	val = (status & RME96xx_fs48) ? 48000 : 44100;
+	if (status & RME96xx_DS_rd)
+		val *= 2;
+	return val;
+}
+
+inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s)
+{
+	int val;
+	val = (s->control_register & RME96xx_freq) ? 48000 : 44100;
+	if (s->control_register & RME96xx_DS)
+		val *= 2;
+	return val;
+}
+
+
+/* code from ALSA card-rme9652.c for rev 1.5 SPDIF receiver   HP 20020201 */
+
+static void rme96xx_spdif_set_bit (rme96xx_info* s, int mask, int onoff)
+{
+	if (onoff) 
+		s->control_register |= mask;
+	else 
+		s->control_register &= ~mask;
+		
+	writel(s->control_register,s->iobase + RME96xx_control_register);
+}
+
+static void rme96xx_spdif_write_byte (rme96xx_info* s, const int val)
+{
+	long mask;
+	long i;
+
+	for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
+		if (val & mask)
+			rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 1);
+		else 
+			rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 0);
+
+		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
+		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
+	}
+}
+
+static int rme96xx_spdif_read_byte (rme96xx_info* s)
+{
+	long mask;
+	long val;
+	long i;
+
+	val = 0;
+
+	for (i = 0, mask = 0x80;  i < 8; i++, mask >>= 1) {
+		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
+		if (readl(s->iobase + RME96xx_status_register) & RME96xx_SPDIF_READ)
+			val |= mask;
+		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
+	}
+
+	return val;
+}
+
+static void rme96xx_write_spdif_codec (rme96xx_info* s, const int address, const int data)
+{
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
+	rme96xx_spdif_write_byte (s, 0x20);
+	rme96xx_spdif_write_byte (s, address);
+	rme96xx_spdif_write_byte (s, data);
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
+}
+
+
+static int rme96xx_spdif_read_codec (rme96xx_info* s, const int address)
+{
+	int ret;
+
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
+	rme96xx_spdif_write_byte (s, 0x20);
+	rme96xx_spdif_write_byte (s, address);
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
+
+	rme96xx_spdif_write_byte (s, 0x21);
+	ret = rme96xx_spdif_read_byte (s);
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
+
+	return ret;
+}
+
+static void rme96xx_initialize_spdif_receiver (rme96xx_info* s)
+{
+	/* XXX what unsets this ? */
+	/* no idea ???   HP 20020201 */
+
+	s->control_register |= RME96xx_SPDIF_RESET;
+
+	rme96xx_write_spdif_codec (s, 4, 0x40);
+	rme96xx_write_spdif_codec (s, 17, 0x13);
+	rme96xx_write_spdif_codec (s, 6, 0x02);
+}
+
+static inline int rme96xx_spdif_sample_rate (rme96xx_info *s, int *spdifrate)
+{
+	unsigned int rate_bits;
+
+	*spdifrate = 0x1;
+	if (readl(s->iobase + RME96xx_status_register) & RME96xx_ERF) {
+		return -1;	/* error condition */
+	}
+	
+	if (s->hw_rev == 15) {
+
+		int x, y, ret;
+		
+		x = rme96xx_spdif_read_codec (s, 30);
+
+		if (x != 0) 
+			y = 48000 * 64 / x;
+		else
+			y = 0;
+
+		if      (y > 30400 && y < 33600)  {ret = 32000; *spdifrate = 0x7;}
+		else if (y > 41900 && y < 46000)  {ret = 44100; *spdifrate = 0x6;}
+		else if (y > 46000 && y < 50400)  {ret = 48000; *spdifrate = 0x5;}
+		else if (y > 60800 && y < 67200)  {ret = 64000; *spdifrate = 0x0;}
+		else if (y > 83700 && y < 92000)  {ret = 88200; *spdifrate = 0x4;}
+		else if (y > 92000 && y < 100000) {ret = 96000; *spdifrate = 0x3;}
+		else                              {ret = 0; *spdifrate = 0x1;}
+		return ret;
+	}
+
+	rate_bits = readl(s->iobase + RME96xx_status_register) & RME96xx_F;
+
+	switch (*spdifrate = rme96xx_decode_spdif_rate(rate_bits)) {
+	case 0x7:
+		return 32000;
+		break;
+
+	case 0x6:
+		return 44100;
+		break;
+
+	case 0x5:
+		return 48000;
+		break;
+
+	case 0x4:
+		return 88200;
+		break;
+
+	case 0x3:
+		return 96000;
+		break;
+
+	case 0x0:
+		return 64000;
+		break;
+
+	default:
+		/* was an ALSA warning ...
+		  snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
+		  s->card_name, rate_bits);
+		*/
+		return 0;
+		break;
+	}
+}
+
+/* end of code from ALSA card-rme9652.c */
+
 
 
 /* the hwbuf in the status register seems to have some jitter, to get rid of
@@ -656,6 +860,9 @@
 int rme96xx_init(rme96xx_info* s)
 {
 	int i;
+	int status;
+	unsigned short rev;
+
 	DBG(printk(__FUNCTION__"\n"));
 	numcards++;
 
@@ -688,6 +895,56 @@
 		rme96xx_dmabuf_init(s,dma,2*i,2*i);
 	}
 
+	/* code from ALSA card-rme9652.c   HP 20020201 */
+        /* Determine the h/w rev level of the card. This seems like
+	   a particularly kludgy way to encode it, but its what RME
+	   chose to do, so we follow them ...
+	*/
+
+	status = readl(s->iobase + RME96xx_status_register);
+	if (rme96xx_decode_spdif_rate(status&RME96xx_F) == 1) {
+		s->hw_rev = 15;
+	} else {
+		s->hw_rev = 11;
+	}
+
+	/* Differentiate between the standard Hammerfall, and the
+	   "Light", which does not have the expansion board. This
+	   method comes from information received from Mathhias
+	   Clausen at RME. Display the EEPROM and h/w revID where
+	   relevant.  
+	*/
+
+	pci_read_config_word(s->pcidev, PCI_CLASS_REVISION, &rev);
+	switch (rev & 0xff) {
+	case 8: /* original eprom */
+		if (s->hw_rev == 15) {
+			s->card_name = "RME Digi9636 (Rev 1.5)";
+		} else {
+			s->card_name = "RME Digi9636";
+		}
+		break;
+	case 9: /* W36_G EPROM */
+		s->card_name = "RME Digi9636 (Rev G)";
+		break;
+	case 4: /* W52_G EPROM */
+		s->card_name = "RME Digi9652 (Rev G)";
+		break;
+	default:
+	case 3: /* original eprom */
+		if (s->hw_rev == 15) {
+			s->card_name = "RME Digi9652 (Rev 1.5)";
+		} else {
+			s->card_name = "RME Digi9652";
+		}
+		break;
+	}
+
+	printk(KERN_INFO RME_MESS" detected %s (hw_rev %d)\n",s->card_name,s->hw_rev); 
+
+	if (s->hw_rev == 15)
+		rme96xx_initialize_spdif_receiver (s);
+
 	s->started = 0;
 	rme96xx_setlatency(s,7);
 
@@ -728,7 +985,7 @@
 
 	if (pci_enable_device(pcidev))
 		goto err_irq;
-	if (request_irq(s->irq, rme96xx_interrupt, SA_SHIRQ, "es1370", s)) {
+	if (request_irq(s->irq, rme96xx_interrupt, SA_SHIRQ, "rme96xx", s)) {
 		printk(KERN_ERR RME_MESS" irq %u in use\n", s->irq);
 		goto err_irq;
 	}
@@ -825,6 +1082,7 @@
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
 	printk(KERN_INFO RME_MESS" version "RMEVERSION" time " __TIME__ " " __DATE__ "\n");
+	devices = ((devices-1) & RME96xx_MASK_DEVS) + 1;
 	printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices);
         numcards = 0;
 	return pci_module_init(&rme96xx_driver);
@@ -848,13 +1106,11 @@
 ---------------------------------------------------------------------------*/
 
 #define RME96xx_FMT (AFMT_S16_LE|AFMT_U8|AFMT_S32_BLOCKED)
+/* AFTM_U8 is not (yet?) supported ...  HP20020201 */
 
-
-static int rme96xx_ioctl(struct inode *in, struct file *file, 
-						unsigned int cmd, unsigned long arg)
+static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg)
 {
 
-
 	struct dmabuf * dma = (struct dmabuf *)file->private_data; 
 	rme96xx_info *s = dma->s;
 	unsigned long flags;
@@ -907,14 +1163,23 @@
 			case 96000: 
 				rme96xx_set_ctrl(s,RME96xx_freq);
 				break;
+			/* just report current rate as default
+			   e.g. use 0 to "select" current digital input rate
 			default:
 				rme96xx_unset_ctrl(s,RME96xx_freq);
 				val = 44100;
+			*/
 			}
 			if (val > 50000)
 				rme96xx_set_ctrl(s,RME96xx_DS);
 			else
 				rme96xx_unset_ctrl(s,RME96xx_DS);
+			/* set val to actual value  HP 20020201 */
+			/* NOTE: if not "Sync Master", reported rate might be not yet "updated" ... but I don't want to insert a long udelay() here */
+			if ((s->control_register & RME96xx_Master) && !(s->control_register & RME96xx_wsel))
+				val = rme96xx_get_sample_rate_ctrl(s);
+			else
+				val = rme96xx_get_sample_rate_status(s);
 			s->rate = val;
 			spin_unlock_irqrestore(&s->lock, flags);
 		}
@@ -1083,7 +1348,7 @@
 			dma->readptr &= s->fragsize<<1;
 		spin_unlock_irqrestore(&s->lock,flags);
 
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_READ))
@@ -1100,7 +1365,7 @@
 		if (dma->mmapped)
 			dma->writeptr &= s->fragsize<<1;
 		spin_unlock_irqrestore(&s->lock,flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
         case SNDCTL_DSP_GETBLKSIZE:
 	     return put_user(s->fragsize, (int *)arg);
 
@@ -1131,6 +1396,8 @@
 		return 0;
 
         case SOUND_PCM_READ_RATE:
+		/* HP20020201 */
+		s->rate = rme96xx_get_sample_rate_status(s);
 		return put_user(s->rate, (int *)arg);
 
         case SOUND_PCM_READ_CHANNELS:
@@ -1164,28 +1431,29 @@
 {
 	int minor = MINOR(in->i_rdev);
 	struct list_head *list;
-	int devnum = ((minor-3)/16) % devices; /* default = 0 */
+	int devnum;
 	rme96xx_info *s;
 	struct dmabuf* dma;
 	DECLARE_WAITQUEUE(wait, current); 
 
 	DBG(printk("device num %d open\n",devnum));
 
-/* ??? */
 	for (list = devs.next; ; list = list->next) {
 		if (list == &devs)
 			return -ENODEV;
 		s = list_entry(list, rme96xx_info, devs);
-		if (!((s->dspnum[devnum] ^ minor) & ~0xf)) 
+		for (devnum=0; devnum<devices; devnum++)
+			if (!((s->dspnum[devnum] ^ minor) & ~0xf)) 
+				break;
+		if (devnum<devices)
 			break;
 	}
        	VALIDATE_STATE(s);
-/* ??? */
 
 	dma = &s->dma[devnum];
 	f->private_data = dma;
 	/* wait for device to become free */
-	down(&s->dma[devnum].open_sem);
+	down(&dma->open_sem);
 	while (dma->open_mode & f->f_mode) {
 		if (f->f_flags & O_NONBLOCK) {
 			up(&dma->open_sem);
@@ -1204,11 +1472,11 @@
 
 	COMM                ("hardware open")
 
-	if (!s->dma[devnum].opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset);
+	if (!dma->opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset);
 
-	s->dma[devnum].open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE));
-	s->dma[devnum].opened = 1;
-	up(&s->dma[devnum].open_sem);
+	dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE));
+	dma->opened = 1;
+	up(&dma->open_sem);
 
 	DBG(printk("device num %d open finished\n",devnum));
 	return 0;
@@ -1217,7 +1485,7 @@
 static int rme96xx_release(struct inode *in, struct file *file)
 {
 	struct dmabuf * dma = (struct dmabuf*) file->private_data;
-	int hwp;
+	/* int hwp;  ... was unused   HP20020201 */
 	DBG(printk(__FUNCTION__"\n"));
 
 	COMM          ("draining")
@@ -1246,8 +1514,7 @@
 }
 
 
-static ssize_t rme96xx_write(struct file *file, const char *buffer, 
-									  size_t count, loff_t *ppos)
+static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
 {
 	struct dmabuf *dma = (struct dmabuf *)file->private_data;
 	ssize_t ret = 0;
@@ -1269,7 +1536,7 @@
 	if (!access_ok(VERIFY_READ, buffer, count))
 		return -EFAULT;
 
-	if (! (dma->open_mode  & FMODE_WRITE))
+	if (! (dma->open_mode & FMODE_WRITE))
                 return -ENXIO;
 
 	if (!dma->s->started) rme96xx_startcard(dma->s,exact);
@@ -1281,7 +1548,6 @@
 		dma->readptr = hwp;
 		dma->writeptr = hwp;
 		dma->started = 1;
-		COMM          ("first write done")
 	}
 
   	while (count > 0) {
@@ -1316,11 +1582,11 @@
 	return ret;
 }
 
-static ssize_t rme96xx_read(struct file *file, char *buffer,size_t count, loff_t *ppos)
+static ssize_t rme96xx_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 { 
 	struct dmabuf *dma = (struct dmabuf *)file->private_data;
 	ssize_t ret = 0;
-	int cnt;
+	int cnt; /* number of bytes from "buffer" that will/can be used */
 	int hop = count/dma->inchannels;
 	int hwp;
 	int exact = (file->f_flags & O_NONBLOCK); 
@@ -1341,9 +1607,6 @@
 	if (! (dma->open_mode  & FMODE_READ))
                 return -ENXIO;
 
-	if (count > ((dma->s->fragsize*dma->inchannels)>>dma->formatshift))
-	    return -EFAULT;
-
 	if (!dma->s->started) rme96xx_startcard(dma->s,exact);
 	hwp = rme96xx_gethwptr(dma->s,0);
 
@@ -1359,15 +1622,12 @@
 		cnt = rme96xx_getispace(dma,hwp);		
 		cnt>>=dma->formatshift;
 		cnt*=dma->inchannels;
-
 		if (cnt > count)
 			cnt = count;
 
 		if (cnt != 0) {
-		        
 			if (rme96xx_copytouser(dma,buffer,cnt,hop))
 				return ret ? ret : -EFAULT;
-			
 			count -= cnt;
 			buffer += cnt;
 			ret += cnt;
@@ -1382,6 +1642,7 @@
 			if (signal_pending(current))
 				return ret ? ret : -ERESTARTSYS;
 		}			
+
 		hwp = rme96xx_gethwptr(dma->s,exact);
 
 	}; /* count > 0 */
@@ -1500,7 +1761,7 @@
 		if (list == &devs)
 			return -ENODEV;
 		s = list_entry(list, rme96xx_info, devs);
-		if (s->mixer== minor)
+		if (s->mixer == minor)
 			break;
 	}
        	VALIDATE_STATE(s);
@@ -1514,19 +1775,34 @@
 {
 	rme96xx_info *s = (rme96xx_info *)file->private_data;
 	u32 status;
+	int spdifrate;
 
 	status = readl(s->iobase + RME96xx_status_register);
+	/* hack to convert rev 1.5 SPDIF rate to "crystalrate" format   HP 20020201 */
+	rme96xx_spdif_sample_rate(s,&spdifrate);
+	status = (status & ~RME96xx_F) | ((spdifrate<<22) & RME96xx_F);
 
 	VALIDATE_STATE(s);
 	if (cmd == SOUND_MIXER_PRIVATE1) {
 		rme_mixer mixer;
 		copy_from_user(&mixer,(void*)arg,sizeof(mixer));
 		
-		if (file->f_mode & FMODE_WRITE) {
-		     s->dma[mixer.devnr].outoffset = mixer.o_offset;
-		     s->dma[mixer.devnr].inoffset = mixer.i_offset;
+		mixer.devnr &= RME96xx_MASK_DEVS;
+		if (mixer.devnr >= devices)
+			mixer.devnr = devices-1;
+		if (file->f_mode & FMODE_WRITE && !s->dma[mixer.devnr].opened) {
+			/* modify only if device not open */
+			if (mixer.o_offset < 0)
+				mixer.o_offset = 0;
+			if (mixer.o_offset >= RME96xx_CHANNELS_PER_CARD)
+				mixer.o_offset = RME96xx_CHANNELS_PER_CARD-1;
+			if (mixer.i_offset < 0)
+				mixer.i_offset = 0;
+			if (mixer.i_offset >= RME96xx_CHANNELS_PER_CARD)
+				mixer.i_offset = RME96xx_CHANNELS_PER_CARD-1;
+			s->dma[mixer.devnr].outoffset = mixer.o_offset;
+			s->dma[mixer.devnr].inoffset = mixer.i_offset;
 		}
-
 		mixer.o_offset = s->dma[mixer.devnr].outoffset;
 		mixer.i_offset = s->dma[mixer.devnr].inoffset;
 
@@ -1536,14 +1812,15 @@
 		return put_user(status, (int *)arg);
 	}
 	if (cmd == SOUND_MIXER_PRIVATE3) {
-	     u32 control;
-	     copy_from_user(&control,(void*)arg,sizeof(control)); 
-	     if (file->f_mode & FMODE_WRITE) {
-		  s->control_register = control;
-		  writel(control,s->iobase + RME96xx_control_register);
-	     }
+		u32 control;
+		copy_from_user(&control,(void*)arg,sizeof(control)); 
+		if (file->f_mode & FMODE_WRITE) {
+			s->control_register &= ~RME96xx_mixer_allowed;
+			s->control_register |= control & RME96xx_mixer_allowed;
+			writel(control,s->iobase + RME96xx_control_register);
+		}
 
-	     return put_user(s->control_register, (int *)arg);
+		return put_user(s->control_register, (int *)arg);
 	}
 	return -1;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/rme96xx.h linux/drivers/sound/rme96xx.h
--- linux.orig/drivers/sound/rme96xx.h	2001-08-12 17:51:42.000000000 +0000
+++ linux/drivers/sound/rme96xx.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,5 +1,12 @@
 /* (C) 2000 Guenter Geiger <geiger@debian.org>
    with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
+
+Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
+   HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
+   HP20020201 completed?
+
+A text/graphic control panel (rmectrl/xrmectrl) is available from
+   http://gige.xdv.org/pages/soft/pages/rme
 */
 
 
@@ -7,55 +14,65 @@
 #define AFMT_S32_BLOCKED 0x0000400
 #endif
 
+/* AFMT_S16_BLOCKED not yet supported */
 #ifndef AFMT_S16_BLOCKED 
 #define AFMT_S16_BLOCKED 0x0000800
 #endif
 
 
 typedef struct rme_status {
-     unsigned int irq:1;    /* high or low */
-     unsigned int lockmask:3;  /* ADAT1, ADAT2, ADAT3 */
-     unsigned int sr48:1;   /* current sample rate */
-     unsigned int wclock:1; /* wordclock used ? */
-     unsigned int bufpoint:10;
-
-     unsigned int syncmask:3;  /* ADAT1, ADAT2, ADAT3 */
-     unsigned int doublespeed:1;
-     unsigned int tc_busy:1;
-     unsigned int tc_out:1;
-     unsigned int crystalrate:3;
-     unsigned int spdif_error:1;
-     unsigned int bufid:1;
-     unsigned int tc_valid:1;     
+	unsigned int irq:1;
+	unsigned int lockmask:3;     /* ADAT input PLLs locked */
+	                             /*   100=ADAT1, 010=ADAT2, 001=ADAT3 */
+	unsigned int sr48:1;         /* sample rate: 0=44.1/88.2 1=48/96 kHz */
+	unsigned int wclock:1;       /* 1=wordclock used */
+	unsigned int bufpoint:10;
+	unsigned int syncmask:3;     /* ADAT input in sync with system clock */
+	                             /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */
+	unsigned int doublespeed:1;  /* sample rate: 0=44.1/48 1=88.2/96 kHz */
+	unsigned int tc_busy:1;
+	unsigned int tc_out:1;
+	unsigned int crystalrate:3;  /* spdif input sample rate: */
+	                             /*   000=64kHz, 100=88.2kHz, 011=96kHz */
+	                             /*   111=32kHz, 110=44.1kHz, 101=48kHz */
+	unsigned int spdif_error:1;  /* 1=no spdif lock */
+	unsigned int bufid:1;
+	unsigned int tc_valid:1;     /* 1=timecode input detected */
+	unsigned int spdif_read:1;
 } rme_status_t;
 
 
+/* only fields marked W: can be modified by writing to SOUND_MIXER_PRIVATE3 */
 typedef struct rme_control {
-     unsigned int start:1;
-     unsigned int latency:3;
-
-     unsigned int master:1;
-     unsigned int ie:1;
-     unsigned int sr48:1;
-     unsigned int spare:1;
-
-     unsigned int doublespeed:1;
-     unsigned int pro:1;
-     unsigned int emphasis:1;
-     unsigned int dolby:1;
-
-     unsigned int opt_out:1;
-     unsigned int wordclock:1;
-     unsigned int spdif_in:2;
-
-     unsigned int sync_ref:2;
+	unsigned int start:1;
+	unsigned int latency:3;      /* buffer size / latency [samples]: */
+	                             /*   0=64 ... 7=8192 */
+	unsigned int master:1;       /* W: clock mode: 1=master 0=slave/auto */
+	unsigned int ie:1;
+	unsigned int sr48:1;         /* samplerate 0=44.1/88.2, 1=48/96 kHz */
+	unsigned int spare:1;
+	unsigned int doublespeed:1;  /* double speed 0=44.1/48, 1=88.2/96 Khz */
+	unsigned int pro:1;          /* W: SPDIF-OUT 0=consumer, 1=professional */
+	unsigned int emphasis:1;     /* W: SPDIF-OUT emphasis 0=off, 1=on */
+	unsigned int dolby:1;        /* W: SPDIF-OUT non-audio bit 1=set, 0=unset */
+	unsigned int opt_out:1;      /* W: use 1st optical OUT as SPDIF: 1=yes, 0=no */
+	unsigned int wordclock:1;    /* W: use Wordclock as sync (overwrites master) */
+        unsigned int spdif_in:2;     /* W: SPDIF-IN: */
+                                     /*    00=optical (ADAT1), 01=coaxial (Cinch), 10=internal CDROM */
+	unsigned int sync_ref:2;     /* W: preferred sync-source in autosync */
+                                     /*    00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
+	unsigned int spdif_reset:1;
+	unsigned int spdif_select:1;
+	unsigned int spdif_clock:1;
+	unsigned int spdif_write:1;
+	unsigned int adat1_cd:1;     /* W: Rev 1.5+: if set, internal CD connector carries ADAT */
 } rme_ctrl_t;
 
 
 typedef struct _rme_mixer {
-     int i_offset;
-     int o_offset;
-     int devnr;
-     int spare[8];
+	int i_offset;
+	int o_offset;
+	int devnr;
+	int spare[8];
 } rme_mixer;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- linux.orig/drivers/sound/sb_card.c	2002-02-25 19:38:06.000000000 +0000
+++ linux/drivers/sound/sb_card.c	2002-07-20 01:08:25.000000000 +0000
@@ -373,6 +373,11 @@
 		0,0,0,0,
 		0,1,1,-1},
 	{"Sound Blaster AWE 32",
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0046),
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
+		0,0,0,0,
+		0,1,1,-1},
+	{"Sound Blaster AWE 32",
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0047),
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
 		0,0,0,0,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c
--- linux.orig/drivers/sound/sonicvibes.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/sound/sonicvibes.c	2002-07-20 01:08:35.000000000 +0000
@@ -1802,7 +1802,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1820,7 +1820,7 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/sound_config.h linux/drivers/sound/sound_config.h
--- linux.orig/drivers/sound/sound_config.h	2000-12-11 21:02:27.000000000 +0000
+++ linux/drivers/sound/sound_config.h	2002-07-20 01:08:26.000000000 +0000
@@ -113,14 +113,14 @@
 
 #if OPEN_READ == FMODE_READ && OPEN_WRITE == FMODE_WRITE
 
-extern __inline__ int translate_mode(struct file *file)
+static inline int translate_mode(struct file *file)
 {
 	return file->f_mode;
 }
 
 #else
 
-extern __inline__ int translate_mode(struct file *file)
+static inline int translate_mode(struct file *file)
 {
 	return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) |
 		((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/swarm_cs4297a.c linux/drivers/sound/swarm_cs4297a.c
--- linux.orig/drivers/sound/swarm_cs4297a.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/sound/swarm_cs4297a.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,2747 @@
+/*******************************************************************************
+*
+*      "swarm_cs4297a.c" --  Cirrus Logic-Crystal CS4297a linux audio driver.
+*
+*      Copyright (C) 2001  Broadcom Corporation.
+*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
+*            -- adapted from drivers by Thomas Sailer, 
+*            -- but don't bug him; Problems should go to:
+*            -- tom woller (twoller@crystal.cirrus.com) or
+*               (audio@crystal.cirrus.com).
+*            -- adapted from cs4281 PCI driver for cs4297a on
+*               BCM1250 Synchronous Serial interface
+*               (kwalker@broadcom.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+* Module command line parameters:
+*   none
+*
+*  Supported devices:
+*  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
+*  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
+*  /dev/midi   simple MIDI UART interface, no ioctl
+*
+* Modification History
+* 08/20/00 trw - silence and no stopping DAC until release
+* 08/23/00 trw - added CS_DBG statements, fix interrupt hang issue on DAC stop.
+* 09/18/00 trw - added 16bit only record with conversion 
+* 09/24/00 trw - added Enhanced Full duplex (separate simultaneous 
+*                capture/playback rates)
+* 10/03/00 trw - fixed mmap (fixed GRECORD and the XMMS mmap test plugin  
+*                libOSSm.so)
+* 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal)
+* 11/03/00 trw - fixed interrupt loss/stutter, added debug.
+* 11/10/00 bkz - added __devinit to cs4297a_hw_init()
+* 11/10/00 trw - fixed SMP and capture spinlock hang.
+* 12/04/00 trw - cleaned up CSDEBUG flags and added "defaultorder" moduleparm.
+* 12/05/00 trw - fixed polling (myth2), and added underrun swptr fix.
+* 12/08/00 trw - added PM support. 
+* 12/14/00 trw - added wrapper code, builds under 2.4.0, 2.2.17-20, 2.2.17-8 
+*		 (RH/Dell base), 2.2.18, 2.2.12.  cleaned up code mods by ident.
+* 12/19/00 trw - added PM support for 2.2 base (apm_callback). other PM cleanup.
+* 12/21/00 trw - added fractional "defaultorder" inputs. if >100 then use 
+*		 defaultorder-100 as power of 2 for the buffer size. example:
+*		 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
+*
+*******************************************************************************/
+
+#include <linux/list.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/slab.h>
+#include <linux/soundcard.h>
+#include <linux/ac97_codec.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/smp_lock.h>
+#include <linux/wrapper.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_dma.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/sb1250_syncser.h>
+#include <asm/sibyte/sb1250_mac.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/64bit.h>
+
+struct cs4297a_state;
+EXPORT_NO_SYMBOLS;
+
+static void stop_dac(struct cs4297a_state *s);
+static void stop_adc(struct cs4297a_state *s);
+static void start_dac(struct cs4297a_state *s);
+static void start_adc(struct cs4297a_state *s);
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+// --------------------------------------------------------------------- 
+
+#define CS4297a_MAGIC           0xf00beef1
+
+// buffer order determines the size of the dma buffer for the driver.
+// under Linux, a smaller buffer allows more responsiveness from many of the 
+// applications (e.g. games).  A larger buffer allows some of the apps (esound) 
+// to not underrun the dma buffer as easily.  As default, use 32k (order=3)
+// rather than 64k as some of the games work more responsively.
+// log base 2( buff sz = 32k).
+
+//static unsigned long defaultorder = 3;
+//MODULE_PARM(defaultorder, "i");
+
+//
+// Turn on/off debugging compilation by commenting out "#define CSDEBUG"
+//
+#define CSDEBUG 0
+#if CSDEBUG
+#define CSDEBUG_INTERFACE 1
+#else
+#undef CSDEBUG_INTERFACE
+#endif
+//
+// cs_debugmask areas
+//
+#define CS_INIT	 	0x00000001	// initialization and probe functions
+#define CS_ERROR 	0x00000002	// tmp debugging bit placeholder
+#define CS_INTERRUPT	0x00000004	// interrupt handler (separate from all other)
+#define CS_FUNCTION 	0x00000008	// enter/leave functions
+#define CS_WAVE_WRITE 	0x00000010	// write information for wave
+#define CS_WAVE_READ 	0x00000020	// read information for wave
+#define CS_AC97         0x00000040      // AC97 register access
+#define CS_DESCR        0x00000080      // descriptor management
+#define CS_OPEN		0x00000400	// all open functions in the driver
+#define CS_RELEASE	0x00000800	// all release functions in the driver
+#define CS_PARMS	0x00001000	// functional and operational parameters
+#define CS_IOCTL	0x00002000	// ioctl (non-mixer)
+#define CS_TMP		0x10000000	// tmp debug mask bit
+
+//
+// CSDEBUG is usual mode is set to 1, then use the
+// cs_debuglevel and cs_debugmask to turn on or off debugging.
+// Debug level of 1 has been defined to be kernel errors and info
+// that should be printed on any released driver.
+//
+#if CSDEBUG
+#define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask) ) {x;}
+#else
+#define CS_DBGOUT(mask,level,x)
+#endif
+
+#if CSDEBUG
+static unsigned long cs_debuglevel = 4;	// levels range from 1-9
+static unsigned long cs_debugmask = CS_INIT /*| CS_IOCTL*/;
+MODULE_PARM(cs_debuglevel, "i");
+MODULE_PARM(cs_debugmask, "i");
+#endif
+#define CS_TRUE 	1
+#define CS_FALSE 	0
+
+#define CS_TYPE_ADC 0
+#define CS_TYPE_DAC 1
+
+#define SER_BASE    (A_SER_BASE_1 + KSEG1)
+#define SS_CSR(t)   (SER_BASE+t)
+#define SS_TXTBL(t) (SER_BASE+R_SER_TX_TABLE_BASE+(t*8))
+#define SS_RXTBL(t) (SER_BASE+R_SER_RX_TABLE_BASE+(t*8))
+
+#define FRAME_BYTES            32
+#define FRAME_SAMPLE_BYTES      4
+
+/* Should this be variable? */
+#define SAMPLE_BUF_SIZE        (16*1024)
+#define SAMPLE_FRAME_COUNT     (SAMPLE_BUF_SIZE / FRAME_SAMPLE_BYTES)
+/* The driver can explode/shrink the frames to/from a smaller sample
+   buffer */
+#define DMA_BLOAT_FACTOR       1
+#define DMA_DESCR              (SAMPLE_FRAME_COUNT / DMA_BLOAT_FACTOR)
+#define DMA_BUF_SIZE           (DMA_DESCR * FRAME_BYTES)
+
+/* Use the maxmium count (255 == 5.1 ms between interrupts) */
+#define DMA_INT_CNT            ((1 << S_DMA_INT_PKTCNT) - 1)
+
+/* Figure this out: how many TX DMAs ahead to schedule a reg access */
+#define REG_LATENCY            150
+
+#define FRAME_TX_US             20
+
+#define SERDMA_NEXTBUF(d,f) (((d)->f+1) % (d)->ringsz)
+
+static const char invalid_magic[] =
+    KERN_CRIT "cs4297a: invalid magic value\n";
+
+#define VALIDATE_STATE(s)                          \
+({                                                 \
+        if (!(s) || (s)->magic != CS4297a_MAGIC) { \
+                printk(invalid_magic);             \
+                return -ENXIO;                     \
+        }                                          \
+})
+
+#define list_for_each(pos, head) \
+        for (pos = (head)->next; pos != (head); pos = pos->next)
+
+struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs };
+
+typedef struct serdma_descr_s {
+        u64 descr_a;
+        u64 descr_b;
+} serdma_descr_t;
+
+typedef unsigned long paddr_t;
+
+typedef struct serdma_s {
+        unsigned         ringsz;
+        serdma_descr_t  *descrtab;
+        serdma_descr_t  *descrtab_end;
+        paddr_t          descrtab_phys;
+        
+        serdma_descr_t  *descr_add;
+        serdma_descr_t  *descr_rem;
+        
+        u64  *dma_buf;           // buffer for DMA contents (frames)
+        paddr_t          dma_buf_phys;
+        u16  *sample_buf;		// tmp buffer for sample conversions
+        u16  *sb_swptr;
+        u16  *sb_hwptr;
+        u16  *sb_end;
+
+        dma_addr_t dmaaddr;
+//        unsigned buforder;	// Log base 2 of 'dma_buf' size in bytes..
+        unsigned numfrag;	// # of 'fragments' in the buffer.
+        unsigned fragshift;	// Log base 2 of fragment size.
+        unsigned hwptr, swptr;
+        unsigned total_bytes;	// # bytes process since open.
+        unsigned blocks;	// last returned blocks value GETOPTR
+        unsigned wakeup;	// interrupt occurred on block 
+        int count;
+        unsigned underrun;	// underrun flag
+        unsigned error;	// over/underrun 
+        wait_queue_head_t wait;
+        wait_queue_head_t reg_wait;
+        // redundant, but makes calculations easier 
+        unsigned fragsize;	// 2**fragshift..
+        unsigned sbufsz;	// 2**buforder.
+        unsigned fragsamples;
+        // OSS stuff 
+        unsigned mapped:1;	// Buffer mapped in cs4297a_mmap()?
+        unsigned ready:1;	// prog_dmabuf_dac()/adc() successful?
+        unsigned endcleared:1;
+        unsigned type:1;	// adc or dac buffer (CS_TYPE_XXX)
+        unsigned ossfragshift;
+        int ossmaxfrags;
+        unsigned subdivision;
+} serdma_t;
+
+struct cs4297a_state {
+	// magic 
+	unsigned int magic;
+
+	struct list_head list;
+
+	// soundcore stuff 
+	int dev_audio;
+	int dev_mixer;
+
+	// hardware resources 
+	unsigned int irq;
+
+        struct {
+                unsigned int rx_ovrrn; /* FIFO */
+                unsigned int rx_overflow; /* staging buffer */
+                unsigned int tx_underrun;
+                unsigned int rx_bad;
+                unsigned int rx_good;
+        } stats;
+
+	// mixer registers 
+	struct {
+		unsigned short vol[10];
+		unsigned int recsrc;
+		unsigned int modcnt;
+		unsigned short micpreamp;
+	} mix;
+
+	// wave stuff   
+	struct properties {
+		unsigned fmt;
+		unsigned fmt_original;	// original requested format
+		unsigned channels;
+		unsigned rate;
+	} prop_dac, prop_adc;
+	unsigned conversion:1;	// conversion from 16 to 8 bit in progress
+	unsigned ena;
+	spinlock_t lock;
+	struct semaphore open_sem;
+	struct semaphore open_sem_adc;
+	struct semaphore open_sem_dac;
+	mode_t open_mode;
+	wait_queue_head_t open_wait;
+	wait_queue_head_t open_wait_adc;
+	wait_queue_head_t open_wait_dac;
+
+	dma_addr_t dmaaddr_sample_buf;
+	unsigned buforder_sample_buf;	// Log base 2 of 'dma_buf' size in bytes..
+
+        serdma_t dma_dac, dma_adc;
+
+        volatile u16 read_value;
+        volatile u16 read_reg;
+        volatile u64 reg_request;
+};
+
+#if 1
+#define prog_codec(a,b)
+#define dealloc_dmabuf(a,b);
+#endif
+
+static int prog_dmabuf_adc(struct cs4297a_state *s)
+{
+	s->dma_adc.ready = 1;
+	return 0;
+}
+
+
+static int prog_dmabuf_dac(struct cs4297a_state *s)
+{
+	s->dma_dac.ready = 1;
+	return 0;
+}
+
+static void clear_advance(void *buf, unsigned bsize, unsigned bptr,
+			  unsigned len, unsigned char c)
+{
+	if (bptr + len > bsize) {
+		unsigned x = bsize - bptr;
+		memset(((char *) buf) + bptr, c, x);
+		bptr = 0;
+		len -= x;
+	}
+	CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
+		"cs4297a: clear_advance(): memset %d at 0x%.8x for %d size \n",
+			(unsigned)c, (unsigned)((char *) buf) + bptr, len));
+	memset(((char *) buf) + bptr, c, len);
+}
+
+#if CSDEBUG
+
+// DEBUG ROUTINES
+
+#define SOUND_MIXER_CS_GETDBGLEVEL 	_SIOWR('M',120, int)
+#define SOUND_MIXER_CS_SETDBGLEVEL 	_SIOWR('M',121, int)
+#define SOUND_MIXER_CS_GETDBGMASK 	_SIOWR('M',122, int)
+#define SOUND_MIXER_CS_SETDBGMASK 	_SIOWR('M',123, int)
+
+static void cs_printioctl(unsigned int x)
+{
+	unsigned int i;
+	unsigned char vidx;
+	// Index of mixtable1[] member is Device ID 
+	// and must be <= SOUND_MIXER_NRDEVICES.
+	// Value of array member is index into s->mix.vol[]
+	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
+		[SOUND_MIXER_PCM] = 1,	// voice 
+		[SOUND_MIXER_LINE1] = 2,	// AUX
+		[SOUND_MIXER_CD] = 3,	// CD 
+		[SOUND_MIXER_LINE] = 4,	// Line 
+		[SOUND_MIXER_SYNTH] = 5,	// FM
+		[SOUND_MIXER_MIC] = 6,	// Mic 
+		[SOUND_MIXER_SPEAKER] = 7,	// Speaker 
+		[SOUND_MIXER_RECLEV] = 8,	// Recording level 
+		[SOUND_MIXER_VOLUME] = 9	// Master Volume 
+	};
+
+	switch (x) {
+	case SOUND_MIXER_CS_GETDBGMASK:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_MIXER_CS_GETDBGMASK:\n"));
+		break;
+	case SOUND_MIXER_CS_GETDBGLEVEL:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_MIXER_CS_GETDBGLEVEL:\n"));
+		break;
+	case SOUND_MIXER_CS_SETDBGMASK:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_MIXER_CS_SETDBGMASK:\n"));
+		break;
+	case SOUND_MIXER_CS_SETDBGLEVEL:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_MIXER_CS_SETDBGLEVEL:\n"));
+		break;
+	case OSS_GETVERSION:
+		CS_DBGOUT(CS_IOCTL, 4, printk("OSS_GETVERSION:\n"));
+		break;
+	case SNDCTL_DSP_SYNC:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SYNC:\n"));
+		break;
+	case SNDCTL_DSP_SETDUPLEX:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETDUPLEX:\n"));
+		break;
+	case SNDCTL_DSP_GETCAPS:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETCAPS:\n"));
+		break;
+	case SNDCTL_DSP_RESET:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_RESET:\n"));
+		break;
+	case SNDCTL_DSP_SPEED:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SPEED:\n"));
+		break;
+	case SNDCTL_DSP_STEREO:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_STEREO:\n"));
+		break;
+	case SNDCTL_DSP_CHANNELS:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_CHANNELS:\n"));
+		break;
+	case SNDCTL_DSP_GETFMTS:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETFMTS:\n"));
+		break;
+	case SNDCTL_DSP_SETFMT:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETFMT:\n"));
+		break;
+	case SNDCTL_DSP_POST:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_POST:\n"));
+		break;
+	case SNDCTL_DSP_GETTRIGGER:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETTRIGGER:\n"));
+		break;
+	case SNDCTL_DSP_SETTRIGGER:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETTRIGGER:\n"));
+		break;
+	case SNDCTL_DSP_GETOSPACE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOSPACE:\n"));
+		break;
+	case SNDCTL_DSP_GETISPACE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETISPACE:\n"));
+		break;
+	case SNDCTL_DSP_NONBLOCK:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_NONBLOCK:\n"));
+		break;
+	case SNDCTL_DSP_GETODELAY:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETODELAY:\n"));
+		break;
+	case SNDCTL_DSP_GETIPTR:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETIPTR:\n"));
+		break;
+	case SNDCTL_DSP_GETOPTR:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOPTR:\n"));
+		break;
+	case SNDCTL_DSP_GETBLKSIZE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETBLKSIZE:\n"));
+		break;
+	case SNDCTL_DSP_SETFRAGMENT:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SNDCTL_DSP_SETFRAGMENT:\n"));
+		break;
+	case SNDCTL_DSP_SUBDIVIDE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SUBDIVIDE:\n"));
+		break;
+	case SOUND_PCM_READ_RATE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_RATE:\n"));
+		break;
+	case SOUND_PCM_READ_CHANNELS:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_PCM_READ_CHANNELS:\n"));
+		break;
+	case SOUND_PCM_READ_BITS:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_BITS:\n"));
+		break;
+	case SOUND_PCM_WRITE_FILTER:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_PCM_WRITE_FILTER:\n"));
+		break;
+	case SNDCTL_DSP_SETSYNCRO:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETSYNCRO:\n"));
+		break;
+	case SOUND_PCM_READ_FILTER:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_FILTER:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE1:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE1:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE2:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE2:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE3:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE3:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE4:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE4:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE5:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE5:\n"));
+		break;
+	case SOUND_MIXER_INFO:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_INFO:\n"));
+		break;
+	case SOUND_OLD_MIXER_INFO:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_OLD_MIXER_INFO:\n"));
+		break;
+
+	default:
+		switch (_IOC_NR(x)) {
+		case SOUND_MIXER_VOLUME:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_VOLUME:\n"));
+			break;
+		case SOUND_MIXER_SPEAKER:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_SPEAKER:\n"));
+			break;
+		case SOUND_MIXER_RECLEV:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_RECLEV:\n"));
+			break;
+		case SOUND_MIXER_MIC:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_MIC:\n"));
+			break;
+		case SOUND_MIXER_SYNTH:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_SYNTH:\n"));
+			break;
+		case SOUND_MIXER_RECSRC:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_RECSRC:\n"));
+			break;
+		case SOUND_MIXER_DEVMASK:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_DEVMASK:\n"));
+			break;
+		case SOUND_MIXER_RECMASK:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_RECMASK:\n"));
+			break;
+		case SOUND_MIXER_STEREODEVS:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_STEREODEVS:\n"));
+			break;
+		case SOUND_MIXER_CAPS:
+			CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_CAPS:\n"));
+			break;
+		default:
+			i = _IOC_NR(x);
+			if (i >= SOUND_MIXER_NRDEVICES
+			    || !(vidx = mixtable1[i])) {
+				CS_DBGOUT(CS_IOCTL, 4, printk
+					("UNKNOWN IOCTL: 0x%.8x NR=%d\n",
+						x, i));
+			} else {
+				CS_DBGOUT(CS_IOCTL, 4, printk
+					("SOUND_MIXER_IOCTL AC9x: 0x%.8x NR=%d\n",
+						x, i));
+			}
+			break;
+		}
+	}
+}
+#endif
+
+
+static int ser_init(struct cs4297a_state *s)
+{
+        int i;
+
+        CS_DBGOUT(CS_INIT, 2, 
+                  printk(KERN_INFO "cs4297a: Setting up serial parameters\n"));
+
+        out64(M_SYNCSER_CMD_RX_RESET | M_SYNCSER_CMD_TX_RESET, SS_CSR(R_SER_CMD));
+
+        out64(M_SYNCSER_MSB_FIRST, SS_CSR(R_SER_MODE));
+        out64(32, SS_CSR(R_SER_MINFRM_SZ));
+        out64(32, SS_CSR(R_SER_MAXFRM_SZ));
+
+        out64(1, SS_CSR(R_SER_TX_RD_THRSH));
+        out64(4, SS_CSR(R_SER_TX_WR_THRSH));
+        out64(8, SS_CSR(R_SER_RX_RD_THRSH));
+
+        /* This looks good from experimentation */
+        out64((M_SYNCSER_TXSYNC_INT | V_SYNCSER_TXSYNC_DLY(0) | M_SYNCSER_TXCLK_EXT |
+               M_SYNCSER_RXSYNC_INT | V_SYNCSER_RXSYNC_DLY(1) | M_SYNCSER_RXCLK_EXT | M_SYNCSER_RXSYNC_EDGE),
+              SS_CSR(R_SER_LINE_MODE));
+
+        /* This looks good from experimentation */
+        out64(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
+              SS_TXTBL(0));
+        out64(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+              SS_TXTBL(1));
+        out64(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+              SS_TXTBL(2));
+        out64(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE |
+              M_SYNCSER_SEQ_STROBE | M_SYNCSER_SEQ_LAST, SS_TXTBL(3));
+
+        out64(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
+              SS_RXTBL(0));
+        out64(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+              SS_RXTBL(1));
+        out64(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+              SS_RXTBL(2));
+        out64(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE |
+              M_SYNCSER_SEQ_LAST, SS_RXTBL(3));
+
+        for (i=4; i<16; i++) {
+                /* Just in case... */
+                out64(M_SYNCSER_SEQ_LAST, SS_TXTBL(i));
+                out64(M_SYNCSER_SEQ_LAST, SS_RXTBL(i));
+        }
+
+        return 0;
+}
+
+static int init_serdma(serdma_t *dma)
+{
+        CS_DBGOUT(CS_INIT, 2,
+                  printk(KERN_ERR "cs4297a: desc - %d sbufsize - %d dbufsize - %d\n",
+                         DMA_DESCR, SAMPLE_BUF_SIZE, DMA_BUF_SIZE));
+
+        /* Descriptors */
+        dma->ringsz = DMA_DESCR;
+        dma->descrtab = kmalloc(dma->ringsz * sizeof(serdma_descr_t), GFP_KERNEL);
+        if (!dma->descrtab) {
+                printk(KERN_ERR "cs4297a: kmalloc descrtab failed\n");
+                return -1;
+        }
+        memset(dma->descrtab, 0, dma->ringsz * sizeof(serdma_descr_t));
+        dma->descrtab_end = dma->descrtab + dma->ringsz;
+	/* XXX bloddy mess, use proper DMA API here ...  */
+	dma->descrtab_phys = PHYSADDR((int)dma->descrtab);
+        dma->descr_add = dma->descr_rem = dma->descrtab;
+
+        /* Frame buffer area */
+        dma->dma_buf = kmalloc(DMA_BUF_SIZE, GFP_KERNEL);
+        if (!dma->dma_buf) {
+                printk(KERN_ERR "cs4297a: kmalloc dma_buf failed\n");
+                kfree(dma->descrtab);
+                return -1;
+        }
+        memset(dma->dma_buf, 0, DMA_BUF_SIZE);
+        dma->dma_buf_phys = PHYSADDR((int)dma->dma_buf);
+
+        /* Samples buffer area */
+        dma->sbufsz = SAMPLE_BUF_SIZE;
+        dma->sample_buf = kmalloc(dma->sbufsz, GFP_KERNEL);
+        if (!dma->sample_buf) {
+                printk(KERN_ERR "cs4297a: kmalloc sample_buf failed\n");
+                kfree(dma->descrtab);
+                kfree(dma->dma_buf);
+                return -1;
+        }
+        dma->sb_swptr = dma->sb_hwptr = dma->sample_buf;
+        dma->sb_end = (u16 *)((void *)dma->sample_buf + dma->sbufsz);
+        dma->fragsize = dma->sbufsz >> 1;
+
+        CS_DBGOUT(CS_INIT, 4, 
+                  printk(KERN_ERR "cs4297a: descrtab - %08x dma_buf - %x sample_buf - %x\n",
+                         (int)dma->descrtab, (int)dma->dma_buf, 
+                         (int)dma->sample_buf));
+
+        return 0;
+}
+
+static int dma_init(struct cs4297a_state *s)
+{
+        int i;
+
+        CS_DBGOUT(CS_INIT, 2, 
+                  printk(KERN_INFO "cs4297a: Setting up DMA\n"));
+
+        if (init_serdma(&s->dma_adc) ||
+            init_serdma(&s->dma_dac))
+                return -1;
+
+        if (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_RX))||
+            in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) {
+                panic("DMA state corrupted?!");
+        }
+
+        /* Initialize now - the descr/buffer pairings will never
+           change... */
+        for (i=0; i<DMA_DESCR; i++) {
+                s->dma_dac.descrtab[i].descr_a = M_DMA_SERRX_SOP | V_DMA_DSCRA_A_SIZE(1) | 
+                        (s->dma_dac.dma_buf_phys + i*FRAME_BYTES);
+                s->dma_dac.descrtab[i].descr_b = V_DMA_DSCRB_PKT_SIZE(FRAME_BYTES);
+                s->dma_adc.descrtab[i].descr_a = V_DMA_DSCRA_A_SIZE(1) |
+                        (s->dma_adc.dma_buf_phys + i*FRAME_BYTES);
+                s->dma_adc.descrtab[i].descr_b = 0;
+        }
+
+        out64((M_DMA_EOP_INT_EN | V_DMA_INT_PKTCNT(DMA_INT_CNT) |
+               V_DMA_RINGSZ(DMA_DESCR) | M_DMA_TDX_EN),
+              SS_CSR(R_SER_DMA_CONFIG0_RX));
+        out64(M_DMA_L2CA, SS_CSR(R_SER_DMA_CONFIG1_RX));
+        out64(s->dma_adc.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_RX));
+
+        out64(V_DMA_RINGSZ(DMA_DESCR), SS_CSR(R_SER_DMA_CONFIG0_TX));
+        out64(M_DMA_L2CA | M_DMA_NO_DSCR_UPDT, SS_CSR(R_SER_DMA_CONFIG1_TX));
+        out64(s->dma_dac.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_TX));
+
+        /* Prep the receive DMA descriptor ring */
+        out64(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+
+        out64(M_SYNCSER_DMA_RX_EN | M_SYNCSER_DMA_TX_EN, SS_CSR(R_SER_DMA_ENABLE));
+
+        out64((M_SYNCSER_RX_SYNC_ERR | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_EOP_COUNT),
+              SS_CSR(R_SER_INT_MASK));
+
+        /* Enable the rx/tx; let the codec warm up to the sync and
+           start sending good frames before the receive FIFO is
+           enabled */
+        out64(M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
+        udelay(1000);
+        out64(M_SYNCSER_CMD_RX_EN | M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
+
+        /* XXXKW is this magic? (the "1" part) */
+        while ((in64(SS_CSR(R_SER_STATUS)) & 0xf1) != 1)
+                ;
+
+        CS_DBGOUT(CS_INIT, 4, 
+                  printk(KERN_INFO "cs4297a: status: %08x\n",
+                         (unsigned int)(in64(SS_CSR(R_SER_STATUS)) & 0xffffffff)));
+
+        return 0;
+}
+
+static int serdma_reg_access(struct cs4297a_state *s, u64 data)
+{
+        serdma_t *d = &s->dma_dac;
+        u64 *data_p;
+        unsigned swptr;
+        int flags;
+        serdma_descr_t *descr;
+
+        if (s->reg_request) {
+                printk(KERN_ERR "cs4297a: attempt to issue multiple reg_access\n");
+                return -1;
+        }
+
+        if (s->ena & FMODE_WRITE) {
+                /* Since a writer has the DSP open, we have to mux the
+                   request in */
+                s->reg_request = data;
+                interruptible_sleep_on(&s->dma_dac.reg_wait);
+                /* XXXKW how can I deal with the starvation case where
+                   the opener isn't writing? */
+        } else {
+                /* Be safe when changing ring pointers */
+		spin_lock_irqsave(&s->lock, flags);
+                if (d->hwptr != d->swptr) {
+                        printk(KERN_ERR "cs4297a: reg access found bookkeeping error (hw/sw = %d/%d\n",
+                               d->hwptr, d->swptr);
+                        spin_unlock_irqrestore(&s->lock, flags);
+                        return -1;
+                }
+                swptr = d->swptr;
+                d->hwptr = d->swptr = (d->swptr + 1) % d->ringsz;
+		spin_unlock_irqrestore(&s->lock, flags);
+
+                descr = &d->descrtab[swptr];
+                data_p = &d->dma_buf[swptr * 4];
+                *data_p = data;
+                out64(1, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
+                CS_DBGOUT(CS_DESCR, 4,
+                          printk(KERN_INFO "cs4297a: add_tx  %p (%x -> %x)\n",
+                                 data_p, swptr, d->hwptr));
+        }
+
+        CS_DBGOUT(CS_FUNCTION, 6,
+                  printk(KERN_INFO "cs4297a: serdma_reg_access()-\n"));
+        
+        return 0;
+}
+
+//****************************************************************************
+// "cs4297a_read_ac97" -- Reads an AC97 register
+//****************************************************************************
+static int cs4297a_read_ac97(struct cs4297a_state *s, u32 offset,
+			    u32 * value)
+{
+        CS_DBGOUT(CS_AC97, 1,
+                  printk(KERN_INFO "cs4297a: read reg %2x\n", offset));
+        if (serdma_reg_access(s, (0xCLL << 60) | (1LL << 47) | ((u64)(offset & 0x7F) << 40)))
+                return -1;
+
+        interruptible_sleep_on(&s->dma_adc.reg_wait);
+        *value = s->read_value;
+        CS_DBGOUT(CS_AC97, 2,
+                  printk(KERN_INFO "cs4297a: rdr reg %x -> %x\n", s->read_reg, s->read_value));
+
+        return 0;
+}
+
+
+//****************************************************************************
+// "cs4297a_write_ac97()"-- writes an AC97 register
+//****************************************************************************
+static int cs4297a_write_ac97(struct cs4297a_state *s, u32 offset,
+			     u32 value)
+{
+        CS_DBGOUT(CS_AC97, 1,
+                  printk(KERN_INFO "cs4297a: write reg %2x -> %04x\n", offset, value));
+        return (serdma_reg_access(s, (0xELL << 60) | ((u64)(offset & 0x7F) << 40) | ((value & 0xffff) << 12)));
+}
+
+static void stop_dac(struct cs4297a_state *s)
+{
+	unsigned long flags;
+
+	CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4297a: stop_dac():\n"));
+	spin_lock_irqsave(&s->lock, flags);
+	s->ena &= ~FMODE_WRITE;
+#if 0
+        /* XXXKW what do I really want here?  My theory for now is
+           that I just flip the "ena" bit, and the interrupt handler
+           will stop processing the xmit channel */
+        out64((s->ena & FMODE_READ) ? M_SYNCSER_DMA_RX_EN : 0,
+              SS_CSR(R_SER_DMA_ENABLE));
+#endif
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void start_dac(struct cs4297a_state *s)
+{
+	unsigned long flags;
+
+	CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4297a: start_dac()+\n"));
+	spin_lock_irqsave(&s->lock, flags);
+	if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
+					(s->dma_dac.count > 0
+	    				&& s->dma_dac.ready))) {
+		s->ena |= FMODE_WRITE;
+                /* XXXKW what do I really want here?  My theory for
+                   now is that I just flip the "ena" bit, and the
+                   interrupt handler will start processing the xmit
+                   channel */
+
+		CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO
+			"cs4297a: start_dac(): start dma\n"));
+
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	CS_DBGOUT(CS_FUNCTION, 3,
+		  printk(KERN_INFO "cs4297a: start_dac()-\n"));
+}
+
+
+static void stop_adc(struct cs4297a_state *s)
+{
+	unsigned long flags;
+
+	CS_DBGOUT(CS_FUNCTION, 3,
+		  printk(KERN_INFO "cs4297a: stop_adc()+\n"));
+
+	spin_lock_irqsave(&s->lock, flags);
+	s->ena &= ~FMODE_READ;
+
+	if (s->conversion == 1) {
+		s->conversion = 0;
+		s->prop_adc.fmt = s->prop_adc.fmt_original;
+	}
+        /* Nothing to do really, I need to keep the DMA going
+           XXXKW when do I get here, and is there more I should do? */
+	spin_unlock_irqrestore(&s->lock, flags);
+	CS_DBGOUT(CS_FUNCTION, 3,
+		  printk(KERN_INFO "cs4297a: stop_adc()-\n"));
+}
+
+
+static void start_adc(struct cs4297a_state *s)
+{
+	unsigned long flags;
+
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4297a: start_adc()+\n"));
+
+	if (!(s->ena & FMODE_READ) &&
+	    (s->dma_adc.mapped || s->dma_adc.count <=
+	     (signed) (s->dma_adc.sbufsz - 2 * s->dma_adc.fragsize))
+	    && s->dma_adc.ready) {
+		if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) {
+			// 
+			// now only use 16 bit capture, due to truncation issue
+			// in the chip, noticable distortion occurs.
+			// allocate buffer and then convert from 16 bit to 
+			// 8 bit for the user buffer.
+			//
+			s->prop_adc.fmt_original = s->prop_adc.fmt;
+			if (s->prop_adc.fmt & AFMT_S8) {
+				s->prop_adc.fmt &= ~AFMT_S8;
+				s->prop_adc.fmt |= AFMT_S16_LE;
+			}
+			if (s->prop_adc.fmt & AFMT_U8) {
+				s->prop_adc.fmt &= ~AFMT_U8;
+				s->prop_adc.fmt |= AFMT_U16_LE;
+			}
+			//
+			// prog_dmabuf_adc performs a stop_adc() but that is
+			// ok since we really haven't started the DMA yet.
+			//
+			prog_codec(s, CS_TYPE_ADC);
+
+                        prog_dmabuf_adc(s);
+			s->conversion = 1;
+		}
+		spin_lock_irqsave(&s->lock, flags);
+		s->ena |= FMODE_READ;
+                /* Nothing to do really, I am probably already
+                   DMAing...  XXXKW when do I get here, and is there
+                   more I should do? */
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		CS_DBGOUT(CS_PARMS, 6, printk(KERN_INFO
+			 "cs4297a: start_adc(): start adc\n"));
+	}
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4297a: start_adc()-\n"));
+
+}
+
+
+// call with spinlock held! 
+static void cs4297a_update_ptr(struct cs4297a_state *s, int intflag)
+{
+	int good_diff, diff, diff2;
+        u64 *data_p, data;
+        u32 *s_ptr;
+	unsigned hwptr;
+        u32 status;
+        serdma_t *d;
+        serdma_descr_t *descr;
+
+	// update ADC pointer 
+        status = intflag ? in64(SS_CSR(R_SER_STATUS)) : 0;
+
+	if ((s->ena & FMODE_READ) || (status & (M_SYNCSER_RX_EOP_COUNT))) {
+                d = &s->dma_adc;
+                hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                                     d->descrtab_phys) / sizeof(serdma_descr_t));
+
+                if (s->ena & FMODE_READ) {
+                        CS_DBGOUT(CS_FUNCTION, 2, 
+                                  printk(KERN_INFO "cs4297a: upd_rcv sw->hw->hw %x/%x/%x (int-%d)n",
+                                         d->swptr, d->hwptr, hwptr, intflag));
+                        /* Number of DMA buffers available for software: */
+                        diff2 = diff = (d->ringsz + hwptr - d->hwptr) % d->ringsz;
+                        d->hwptr = hwptr;
+                        good_diff = 0;
+                        s_ptr = (u32 *)&(d->dma_buf[d->swptr*4]);
+                        descr = &d->descrtab[d->swptr];
+                        while (diff2--) {
+                                u64 data = *(u64 *)s_ptr;
+                                u64 descr_a;
+                                u16 left, right;
+                                descr_a = descr->descr_a;
+                                descr->descr_a &= ~M_DMA_SERRX_SOP;
+                                if ((descr_a & M_DMA_DSCRA_A_ADDR) != PHYSADDR((int)s_ptr)) {
+                                        printk(KERN_ERR "cs4297a: RX Bad address (read)\n");
+                                }
+                                if (((data & 0x9800000000000000) != 0x9800000000000000) ||
+                                    (!(descr_a & M_DMA_SERRX_SOP)) ||
+                                    (G_DMA_DSCRB_PKT_SIZE(descr->descr_b) != FRAME_BYTES)) {
+                                        s->stats.rx_bad++;
+                                        printk(KERN_DEBUG "cs4297a: RX Bad attributes (read)\n");
+                                        continue;
+                                }
+                                s->stats.rx_good++;
+                                if ((data >> 61) == 7) {
+                                        s->read_value = (data >> 12) & 0xffff;
+                                        s->read_reg = (data >> 40) & 0x7f;
+                                        wake_up(&d->reg_wait);
+                                }
+                                if (d->count && (d->sb_hwptr == d->sb_swptr)) {
+                                        s->stats.rx_overflow++;
+                                        printk(KERN_DEBUG "cs4297a: RX overflow\n");
+                                        continue;
+                                }
+                                good_diff++;
+                                left = ((s_ptr[1] & 0xff) << 8) | ((s_ptr[2] >> 24) & 0xff);
+                                right = (s_ptr[2] >> 4) & 0xffff;
+                                *d->sb_hwptr++ = left;
+                                *d->sb_hwptr++ = right;
+                                if (d->sb_hwptr == d->sb_end)
+                                        d->sb_hwptr = d->sample_buf;
+                                descr++;
+                                if (descr == d->descrtab_end) {
+                                        descr = d->descrtab;
+                                        s_ptr = (u32 *)s->dma_adc.dma_buf;
+                                } else {
+                                        s_ptr += 8;
+                                }
+                        }
+                        d->total_bytes += good_diff * FRAME_SAMPLE_BYTES;
+                        d->count += good_diff * FRAME_SAMPLE_BYTES;
+                        if (d->count > d->sbufsz) {
+                                printk(KERN_ERR "cs4297a: bogus receive overflow!!\n");
+                        }
+                        d->swptr = (d->swptr + diff) % d->ringsz;
+                        out64(diff, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+                        if (d->mapped) {
+                                if (d->count >= (signed) d->fragsize)
+                                        wake_up(&d->wait);
+                        } else {
+                                if (d->count > 0) {
+                                        CS_DBGOUT(CS_WAVE_READ, 4,
+                                                  printk(KERN_INFO
+                                                         "cs4297a: update count -> %d\n", d->count));
+                                        wake_up(&d->wait);
+                                }
+                        }
+                } else {
+                        /* Receive is going even if no one is
+                           listening (for register accesses and to
+                           avoid FIFO overrun) */
+                        diff2 = diff = (hwptr + d->ringsz - d->hwptr) % d->ringsz;
+                        if (!diff) {
+                                printk(KERN_ERR "cs4297a: RX full or empty?\n");
+                        }
+                        
+                        descr = &d->descrtab[d->swptr];
+                        data_p = &d->dma_buf[d->swptr*4];
+
+                        /* Force this to happen at least once; I got
+                           here because of an interrupt, so there must
+                           be a buffer to process. */
+                        do {
+                                data = *data_p;
+                                if ((descr->descr_a & M_DMA_DSCRA_A_ADDR) != PHYSADDR((int)data_p)) {
+                                        printk(KERN_ERR "cs4297a: RX Bad address %d (%x %x)\n", d->swptr,
+                                               (int)(descr->descr_a & M_DMA_DSCRA_A_ADDR),
+                                               (int)PHYSADDR((int)data_p));
+                                }
+                                if (!(data & (1LL << 63)) ||
+                                    !(descr->descr_a & M_DMA_SERRX_SOP) ||
+                                    (G_DMA_DSCRB_PKT_SIZE(descr->descr_b) != FRAME_BYTES)) {
+                                        s->stats.rx_bad++;
+                                        printk(KERN_DEBUG "cs4297a: RX Bad attributes\n");
+                                } else {
+                                        s->stats.rx_good++;
+                                        if ((data >> 61) == 7) {
+                                                s->read_value = (data >> 12) & 0xffff;
+                                                s->read_reg = (data >> 40) & 0x7f;
+                                                wake_up(&d->reg_wait);
+                                        }
+                                }
+                                descr->descr_a &= ~M_DMA_SERRX_SOP;
+                                descr++;
+                                d->swptr++;
+                                data_p += 4;
+                                if (descr == d->descrtab_end) {
+                                        descr = d->descrtab;
+                                        d->swptr = 0;
+                                        data_p = d->dma_buf;
+                                }
+                                out64(1, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+                        } while (--diff);
+                        d->hwptr = hwptr;
+
+                        CS_DBGOUT(CS_DESCR, 6, 
+                                  printk(KERN_INFO "cs4297a: hw/sw %x/%x\n", d->hwptr, d->swptr));
+                }
+
+		CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
+			"cs4297a: cs4297a_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
+				(unsigned)s, d->hwptr, 
+				d->total_bytes, d->count));
+	}
+
+        /* XXXKW worry about s->reg_request -- there is a starvation
+           case if s->ena has FMODE_WRITE on, but the client isn't
+           doing writes */
+
+	// update DAC pointer 
+	//
+	// check for end of buffer, means that we are going to wait for another interrupt
+	// to allow silence to fill the fifos on the part, to keep pops down to a minimum.
+	//
+	if (s->ena & FMODE_WRITE) {
+                serdma_t *d = &s->dma_dac;
+                hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                                     d->descrtab_phys) / sizeof(serdma_descr_t));
+                diff = (d->ringsz + hwptr - d->hwptr) % d->ringsz;
+                CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
+                                                   "cs4297a: cs4297a_update_ptr(): hw/hw/sw %x/%x/%x diff %d count %d\n",
+                                                   d->hwptr, hwptr, d->swptr, diff, d->count));
+                d->hwptr = hwptr;
+                /* XXXKW stereo? conversion? Just assume 2 16-bit samples for now */
+                d->total_bytes += diff * FRAME_SAMPLE_BYTES;
+		if (d->mapped) {
+			d->count += diff * FRAME_SAMPLE_BYTES;
+			if (d->count >= d->fragsize) {
+				d->wakeup = 1;
+				wake_up(&d->wait);
+				if (d->count > d->sbufsz)
+					d->count &= d->sbufsz - 1;
+			}
+		} else {
+			d->count -= diff * FRAME_SAMPLE_BYTES;
+			if (d->count <= 0) {
+				//
+				// fill with silence, and do not shut down the DAC.
+				// Continue to play silence until the _release.
+				//
+				CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO
+					"cs4297a: cs4297a_update_ptr(): memset %d at 0x%.8x for %d size \n",
+						(unsigned)(s->prop_dac.fmt & 
+						(AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, 
+						(unsigned)d->dma_buf, 
+						d->ringsz));
+				memset(d->dma_buf, 0, d->ringsz * FRAME_BYTES);
+				if (d->count < 0) {
+					d->underrun = 1;
+                                        s->stats.tx_underrun++;
+					d->count = 0;
+					CS_DBGOUT(CS_ERROR, 9, printk(KERN_INFO
+					 "cs4297a: cs4297a_update_ptr(): underrun\n"));
+				}
+			} else if (d->count <=
+				   (signed) d->fragsize
+				   && !d->endcleared) {
+                          /* XXXKW what is this for? */
+				clear_advance(d->dma_buf,
+					      d->sbufsz,
+					      d->swptr,
+					      d->fragsize,
+					      0);
+				d->endcleared = 1;
+			}
+			if ( (d->count <= (signed) d->sbufsz/2) || intflag)
+			{
+                                CS_DBGOUT(CS_WAVE_WRITE, 4,
+                                          printk(KERN_INFO
+                                                 "cs4297a: update count -> %d\n", d->count));
+				wake_up(&d->wait);
+			}
+		}
+		CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
+			"cs4297a: cs4297a_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
+				(unsigned) s, d->hwptr, 
+				d->total_bytes, d->count));
+	}
+}
+
+static int mixer_ioctl(struct cs4297a_state *s, unsigned int cmd,
+		       unsigned long arg)
+{
+	// Index to mixer_src[] is value of AC97 Input Mux Select Reg.
+	// Value of array member is recording source Device ID Mask.
+	static const unsigned int mixer_src[8] = {
+		SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
+		SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
+	};
+
+	// Index of mixtable1[] member is Device ID 
+	// and must be <= SOUND_MIXER_NRDEVICES.
+	// Value of array member is index into s->mix.vol[]
+	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
+		[SOUND_MIXER_PCM] = 1,	// voice 
+		[SOUND_MIXER_LINE1] = 2,	// AUX
+		[SOUND_MIXER_CD] = 3,	// CD 
+		[SOUND_MIXER_LINE] = 4,	// Line 
+		[SOUND_MIXER_SYNTH] = 5,	// FM
+		[SOUND_MIXER_MIC] = 6,	// Mic 
+		[SOUND_MIXER_SPEAKER] = 7,	// Speaker 
+		[SOUND_MIXER_RECLEV] = 8,	// Recording level 
+		[SOUND_MIXER_VOLUME] = 9	// Master Volume 
+	};
+
+	static const unsigned mixreg[] = {
+		AC97_PCMOUT_VOL,
+		AC97_AUX_VOL,
+		AC97_CD_VOL,
+		AC97_LINEIN_VOL
+	};
+	unsigned char l, r, rl, rr, vidx;
+	unsigned char attentbl[11] =
+	    { 63, 42, 26, 17, 14, 11, 8, 6, 4, 2, 0 };
+	unsigned temp1;
+	int i, val;
+
+	VALIDATE_STATE(s);
+	CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
+		 "cs4297a: mixer_ioctl(): s=0x%.8x cmd=0x%.8x\n",
+			 (unsigned) s, cmd));
+#if CSDEBUG
+	cs_printioctl(cmd);
+#endif
+#if CSDEBUG_INTERFACE
+
+	if ((cmd == SOUND_MIXER_CS_GETDBGMASK) ||
+	    (cmd == SOUND_MIXER_CS_SETDBGMASK) ||
+	    (cmd == SOUND_MIXER_CS_GETDBGLEVEL) ||
+	    (cmd == SOUND_MIXER_CS_SETDBGLEVEL))
+	{
+		switch (cmd) {
+
+		case SOUND_MIXER_CS_GETDBGMASK:
+			return put_user(cs_debugmask,
+					(unsigned long *) arg);
+
+		case SOUND_MIXER_CS_GETDBGLEVEL:
+			return put_user(cs_debuglevel,
+					(unsigned long *) arg);
+
+		case SOUND_MIXER_CS_SETDBGMASK:
+			if (get_user(val, (unsigned long *) arg))
+				return -EFAULT;
+			cs_debugmask = val;
+			return 0;
+
+		case SOUND_MIXER_CS_SETDBGLEVEL:
+			if (get_user(val, (unsigned long *) arg))
+				return -EFAULT;
+			cs_debuglevel = val;
+			return 0;
+		default:
+			CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
+				"cs4297a: mixer_ioctl(): ERROR unknown debug cmd\n"));
+			return 0;
+		}
+	}
+#endif
+
+	if (cmd == SOUND_MIXER_PRIVATE1) {
+                return -EINVAL;
+	}
+	if (cmd == SOUND_MIXER_PRIVATE2) {
+		// enable/disable/query spatializer 
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != -1) {
+			temp1 = (val & 0x3f) >> 2;
+			cs4297a_write_ac97(s, AC97_3D_CONTROL, temp1);
+			cs4297a_read_ac97(s, AC97_GENERAL_PURPOSE,
+					 &temp1);
+			cs4297a_write_ac97(s, AC97_GENERAL_PURPOSE,
+					  temp1 | 0x2000);
+		}
+		cs4297a_read_ac97(s, AC97_3D_CONTROL, &temp1);
+		return put_user((temp1 << 2) | 3, (int *) arg);
+	}
+	if (cmd == SOUND_MIXER_INFO) {
+		mixer_info info;
+		strncpy(info.id, "CS4297a", sizeof(info.id));
+		strncpy(info.name, "Crystal CS4297a", sizeof(info.name));
+		info.modify_counter = s->mix.modcnt;
+		if (copy_to_user((void *) arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == SOUND_OLD_MIXER_INFO) {
+		_old_mixer_info info;
+		strncpy(info.id, "CS4297a", sizeof(info.id));
+		strncpy(info.name, "Crystal CS4297a", sizeof(info.name));
+		if (copy_to_user((void *) arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == OSS_GETVERSION)
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
+		return -EINVAL;
+
+	// If ioctl has only the SIOC_READ bit(bit 31)
+	// on, process the only-read commands. 
+	if (_SIOC_DIR(cmd) == _SIOC_READ) {
+		switch (_IOC_NR(cmd)) {
+		case SOUND_MIXER_RECSRC:	// Arg contains a bit for each recording source 
+			cs4297a_read_ac97(s, AC97_RECORD_SELECT,
+					 &temp1);
+			return put_user(mixer_src[temp1 & 7], (int *) arg);
+
+		case SOUND_MIXER_DEVMASK:	// Arg contains a bit for each supported device 
+			return put_user(SOUND_MASK_PCM | SOUND_MASK_LINE |
+					SOUND_MASK_VOLUME | SOUND_MASK_RECLEV,
+                                        (int *) arg);
+
+		case SOUND_MIXER_RECMASK:	// Arg contains a bit for each supported recording source 
+			return put_user(SOUND_MASK_LINE | SOUND_MASK_VOLUME,
+                                        (int *) arg);
+
+		case SOUND_MIXER_STEREODEVS:	// Mixer channels supporting stereo 
+			return put_user(SOUND_MASK_PCM | SOUND_MASK_LINE |
+					SOUND_MASK_VOLUME | SOUND_MASK_RECLEV,
+                                        (int *) arg);
+
+		case SOUND_MIXER_CAPS:
+			return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
+
+		default:
+			i = _IOC_NR(cmd);
+			if (i >= SOUND_MIXER_NRDEVICES
+			    || !(vidx = mixtable1[i]))
+				return -EINVAL;
+			return put_user(s->mix.vol[vidx - 1], (int *) arg);
+		}
+	}
+	// If ioctl doesn't have both the SIOC_READ and 
+	// the SIOC_WRITE bit set, return invalid.
+	if (_SIOC_DIR(cmd) != (_SIOC_READ | _SIOC_WRITE))
+		return -EINVAL;
+
+	// Increment the count of volume writes.
+	s->mix.modcnt++;
+
+	// Isolate the command; it must be a write.
+	switch (_IOC_NR(cmd)) {
+
+	case SOUND_MIXER_RECSRC:	// Arg contains a bit for each recording source 
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		i = hweight32(val);	// i = # bits on in val.
+		if (i != 1)	// One & only 1 bit must be on.
+			return 0;
+		for (i = 0; i < sizeof(mixer_src) / sizeof(int); i++) {
+			if (val == mixer_src[i]) {
+				temp1 = (i << 8) | i;
+				cs4297a_write_ac97(s,
+						  AC97_RECORD_SELECT,
+						  temp1);
+				return 0;
+			}
+		}
+		return 0;
+
+	case SOUND_MIXER_VOLUME:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;	// Max soundcard.h vol is 100.
+		if (l < 6) {
+			rl = 63;
+			l = 0;
+		} else
+			rl = attentbl[(10 * l) / 100];	// Convert 0-100 vol to 63-0 atten.
+
+		r = (val >> 8) & 0xff;
+		if (r > 100)
+			r = 100;	// Max right volume is 100, too
+		if (r < 6) {
+			rr = 63;
+			r = 0;
+		} else
+			rr = attentbl[(10 * r) / 100];	// Convert volume to attenuation.
+
+		if ((rl > 60) && (rr > 60))	// If both l & r are 'low',          
+			temp1 = 0x8000;	//  turn on the mute bit.
+		else
+			temp1 = 0;
+
+		temp1 |= (rl << 8) | rr;
+
+		cs4297a_write_ac97(s, AC97_MASTER_VOL_STEREO, temp1);
+		cs4297a_write_ac97(s, AC97_PHONE_VOL, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[8] = ((unsigned int) r << 8) | l;
+#else
+		s->mix.vol[8] = val;
+#endif
+		return put_user(s->mix.vol[8], (int *) arg);
+
+	case SOUND_MIXER_SPEAKER:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		if (l < 3) {
+			rl = 0;
+			l = 0;
+		} else {
+			rl = (l * 2 - 5) / 13;	// Convert 0-100 range to 0-15.
+			l = (rl * 13 + 5) / 2;
+		}
+
+		if (rl < 3) {
+			temp1 = 0x8000;
+			rl = 0;
+		} else
+			temp1 = 0;
+		rl = 15 - rl;	// Convert volume to attenuation.
+		temp1 |= rl << 1;
+		cs4297a_write_ac97(s, AC97_PCBEEP_VOL, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[6] = l << 8;
+#else
+		s->mix.vol[6] = val;
+#endif
+		return put_user(s->mix.vol[6], (int *) arg);
+
+	case SOUND_MIXER_RECLEV:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		r = (val >> 8) & 0xff;
+		if (r > 100)
+			r = 100;
+		rl = (l * 2 - 5) / 13;	// Convert 0-100 scale to 0-15.
+		rr = (r * 2 - 5) / 13;
+		if (rl < 3 && rr < 3)
+			temp1 = 0x8000;
+		else
+			temp1 = 0;
+
+		temp1 = temp1 | (rl << 8) | rr;
+		cs4297a_write_ac97(s, AC97_RECORD_GAIN, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[7] = ((unsigned int) r << 8) | l;
+#else
+		s->mix.vol[7] = val;
+#endif
+		return put_user(s->mix.vol[7], (int *) arg);
+
+	case SOUND_MIXER_MIC:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		if (l < 1) {
+			l = 0;
+			rl = 0;
+		} else {
+			rl = ((unsigned) l * 5 - 4) / 16;	// Convert 0-100 range to 0-31.
+			l = (rl * 16 + 4) / 5;
+		}
+		cs4297a_read_ac97(s, AC97_MIC_VOL, &temp1);
+		temp1 &= 0x40;	// Isolate 20db gain bit.
+		if (rl < 3) {
+			temp1 |= 0x8000;
+			rl = 0;
+		}
+		rl = 31 - rl;	// Convert volume to attenuation.
+		temp1 |= rl;
+		cs4297a_write_ac97(s, AC97_MIC_VOL, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[5] = val << 8;
+#else
+		s->mix.vol[5] = val;
+#endif
+		return put_user(s->mix.vol[5], (int *) arg);
+
+
+	case SOUND_MIXER_SYNTH:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		r = (val >> 8) & 0xff;
+		if (r > 100)
+			r = 100;
+		rl = (l * 2 - 11) / 3;	// Convert 0-100 range to 0-63.
+		rr = (r * 2 - 11) / 3;
+		if (rl < 3)	// If l is low, turn on
+			temp1 = 0x0080;	//  the mute bit.
+		else
+			temp1 = 0;
+
+		rl = 63 - rl;	// Convert vol to attenuation.
+//		writel(temp1 | rl, s->pBA0 + FMLVC);
+		if (rr < 3)	//  If rr is low, turn on
+			temp1 = 0x0080;	//   the mute bit.
+		else
+			temp1 = 0;
+		rr = 63 - rr;	// Convert vol to attenuation.
+//		writel(temp1 | rr, s->pBA0 + FMRVC);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[4] = (r << 8) | l;
+#else
+		s->mix.vol[4] = val;
+#endif
+		return put_user(s->mix.vol[4], (int *) arg);
+
+
+	default:
+		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
+			"cs4297a: mixer_ioctl(): default\n"));
+
+		i = _IOC_NR(cmd);
+		if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
+			return -EINVAL;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		if (l < 1) {
+			l = 0;
+			rl = 31;
+		} else
+			rl = (attentbl[(l * 10) / 100]) >> 1;
+
+		r = (val >> 8) & 0xff;
+		if (r > 100)
+			r = 100;
+		if (r < 1) {
+			r = 0;
+			rr = 31;
+		} else
+			rr = (attentbl[(r * 10) / 100]) >> 1;
+		if ((rl > 30) && (rr > 30))
+			temp1 = 0x8000;
+		else
+			temp1 = 0;
+		temp1 = temp1 | (rl << 8) | rr;
+		cs4297a_write_ac97(s, mixreg[vidx - 1], temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[vidx - 1] = ((unsigned int) r << 8) | l;
+#else
+		s->mix.vol[vidx - 1] = val;
+#endif
+		return put_user(s->mix.vol[vidx - 1], (int *) arg);
+	}
+}
+
+
+// --------------------------------------------------------------------- 
+
+static loff_t cs4297a_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+
+// --------------------------------------------------------------------- 
+
+static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct cs4297a_state *s=NULL;
+	struct list_head *entry;
+
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
+		  printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n"));
+
+	list_for_each(entry, &cs4297a_devs)
+	{
+		s = list_entry(entry, struct cs4297a_state, list);
+		if(s->dev_mixer == minor)
+			break;
+	}
+	if (!s)
+	{
+		CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
+			printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n"));
+		return -ENODEV;
+	}
+	VALIDATE_STATE(s);
+	file->private_data = s;
+	MOD_INC_USE_COUNT;
+
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
+		  printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n"));
+
+	return 0;
+}
+
+
+static int cs4297a_release_mixdev(struct inode *inode, struct file *file)
+{
+	struct cs4297a_state *s =
+	    (struct cs4297a_state *) file->private_data;
+
+	VALIDATE_STATE(s);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+
+static int cs4297a_ioctl_mixdev(struct inode *inode, struct file *file,
+			       unsigned int cmd, unsigned long arg)
+{
+	return mixer_ioctl((struct cs4297a_state *) file->private_data, cmd,
+			   arg);
+}
+
+
+// ******************************************************************************************
+//   Mixer file operations struct.
+// ******************************************************************************************
+static /*const */ struct file_operations cs4297a_mixer_fops = {
+	llseek:cs4297a_llseek,
+	ioctl:cs4297a_ioctl_mixdev,
+	open:cs4297a_open_mixdev,
+	release:cs4297a_release_mixdev,
+};
+
+// --------------------------------------------------------------------- 
+
+
+static int drain_adc(struct cs4297a_state *s, int nonblock)
+{
+        /* This routine serves no purpose currently - any samples
+           sitting in the receive queue will just be processed by the
+           background consumer.  This would be different if DMA
+           actually stopped when there were no clients. */
+	return 0;
+}
+
+static int drain_dac(struct cs4297a_state *s, int nonblock)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+        unsigned hwptr;
+	unsigned tmo;
+	int count;
+
+	if (s->dma_dac.mapped)
+		return 0;
+        if (nonblock)
+                return -EBUSY;
+	add_wait_queue(&s->dma_dac.wait, &wait);
+        while ((count = in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) ||
+               (s->dma_dac.count > 0)) {
+                if (!signal_pending(current)) {
+                        set_current_state(TASK_INTERRUPTIBLE);
+                        /* XXXKW is this calculation working? */
+                        tmo = ((count * FRAME_TX_US) * HZ) / 1000000;
+                        schedule_timeout(tmo + 1);
+                } else {
+                        /* XXXKW do I care if there is a signal pending? */
+                }
+        }
+        spin_lock_irqsave(&s->lock, flags);
+        /* Reset the bookkeeping */
+        hwptr = (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                       s->dma_dac.descrtab_phys) / sizeof(serdma_descr_t));
+        s->dma_dac.hwptr = s->dma_dac.swptr = hwptr;
+        spin_unlock_irqrestore(&s->lock, flags);
+	remove_wait_queue(&s->dma_dac.wait, &wait);
+	current->state = TASK_RUNNING;
+	return 0;
+}
+
+
+// --------------------------------------------------------------------- 
+
+static ssize_t cs4297a_read(struct file *file, char *buffer, size_t count,
+			   loff_t * ppos)
+{
+	struct cs4297a_state *s =
+	    (struct cs4297a_state *) file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	int cnt, count_fr, cnt_by;
+	unsigned copied = 0;
+
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
+		  printk(KERN_INFO "cs4297a: cs4297a_read()+ %d \n", count));
+
+	VALIDATE_STATE(s);
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (s->dma_adc.mapped)
+		return -ENXIO;
+	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+		return ret;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+//
+// "count" is the amount of bytes to read (from app), is decremented each loop
+//      by the amount of bytes that have been returned to the user buffer.
+// "cnt" is the running total of each read from the buffer (changes each loop)
+// "buffer" points to the app's buffer
+// "ret" keeps a running total of the amount of bytes that have been copied
+//      to the user buffer.
+// "copied" is the total bytes copied into the user buffer for each loop.
+//
+	while (count > 0) {
+		CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
+			"_read() count>0 count=%d .count=%d .swptr=%d .hwptr=%d \n",
+				count, s->dma_adc.count,
+				s->dma_adc.swptr, s->dma_adc.hwptr));
+		spin_lock_irqsave(&s->lock, flags);
+
+                /* cnt will be the number of available samples (16-bit
+                   stereo); it starts out as the maxmimum consequetive
+                   samples */
+		cnt = (s->dma_adc.sb_end - s->dma_adc.sb_swptr) / 2;
+                count_fr = s->dma_adc.count / FRAME_SAMPLE_BYTES;
+
+		// dma_adc.count is the current total bytes that have not been read.
+		// if the amount of unread bytes from the current sw pointer to the
+		// end of the buffer is greater than the current total bytes that
+		// have not been read, then set the "cnt" (unread bytes) to the
+		// amount of unread bytes.  
+
+		if (count_fr < cnt)
+			cnt = count_fr;
+                cnt_by = cnt * FRAME_SAMPLE_BYTES;
+		spin_unlock_irqrestore(&s->lock, flags);
+		//
+		// if we are converting from 8/16 then we need to copy
+		// twice the number of 16 bit bytes then 8 bit bytes.
+		// 
+		if (s->conversion) {
+			if (cnt_by > (count * 2)) {
+				cnt = (count * 2) / FRAME_SAMPLE_BYTES;
+                                cnt_by = count * 2;
+                        }
+		} else {
+			if (cnt_by > count) {
+				cnt = count / FRAME_SAMPLE_BYTES;
+                                cnt_by = count;
+                        }
+		}
+		//
+		// "cnt" NOW is the smaller of the amount that will be read,
+		// and the amount that is requested in this read (or partial).
+		// if there are no bytes in the buffer to read, then start the
+		// ADC and wait for the interrupt handler to wake us up.
+		//
+		if (cnt <= 0) {
+
+			// start up the dma engine and then continue back to the top of
+			// the loop when wake up occurs.
+			start_adc(s);
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : -EAGAIN;
+			interruptible_sleep_on(&s->dma_adc.wait);
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+			continue;
+		}
+		// there are bytes in the buffer to read.
+		// copy from the hw buffer over to the user buffer.
+		// user buffer is designated by "buffer"
+		// virtual address to copy from is dma_buf+swptr
+		// the "cnt" is the number of bytes to read.
+
+		CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO
+			"_read() copy_to cnt=%d count=%d ", cnt_by, count));
+		CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
+			 " .sbufsz=%d .count=%d buffer=0x%.8x ret=%d\n",
+				 s->dma_adc.sbufsz, s->dma_adc.count,
+				 (unsigned) buffer, ret));
+
+		if (copy_to_user (buffer, ((void *)s->dma_adc.sb_swptr), cnt_by))
+			return ret ? ret : -EFAULT;
+                copied = cnt_by;
+
+                /* Return the descriptors */
+		spin_lock_irqsave(&s->lock, flags);
+                CS_DBGOUT(CS_FUNCTION, 2, 
+                          printk(KERN_INFO "cs4297a: upd_rcv sw->hw %x/%x\n", s->dma_adc.swptr, s->dma_adc.hwptr));
+		s->dma_adc.count -= cnt_by;
+                s->dma_adc.sb_swptr += cnt * 2;
+                if (s->dma_adc.sb_swptr == s->dma_adc.sb_end)
+                        s->dma_adc.sb_swptr = s->dma_adc.sample_buf;
+		spin_unlock_irqrestore(&s->lock, flags);
+		count -= copied;
+		buffer += copied;
+		ret += copied;
+		start_adc(s);
+	}
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
+		  printk(KERN_INFO "cs4297a: cs4297a_read()- %d\n", ret));
+	return ret;
+}
+
+
+static ssize_t cs4297a_write(struct file *file, const char *buffer,
+			    size_t count, loff_t * ppos)
+{
+	struct cs4297a_state *s =
+	    (struct cs4297a_state *) file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned swptr, hwptr;
+	int cnt;
+
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
+		  printk(KERN_INFO "cs4297a: cs4297a_write()+ count=%d\n",
+			 count));
+	VALIDATE_STATE(s);
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (s->dma_dac.mapped)
+		return -ENXIO;
+	if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+		return ret;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+	ret = 0;
+	while (count > 0) {
+                serdma_t *d = &s->dma_dac;
+                int copy_cnt;
+                u32 *s_tmpl;
+                u32 *t_tmpl;
+                u32 left, right;
+                /* XXXKW check system endian here ... */
+                int swap = (s->prop_dac.fmt == AFMT_S16_LE) || (s->prop_dac.fmt == AFMT_U16_LE);
+                
+                /* XXXXXX this is broken for BLOAT_FACTOR */
+		spin_lock_irqsave(&s->lock, flags);
+		if (d->count < 0) {
+			d->count = 0;
+			d->swptr = d->hwptr;
+		}
+		if (d->underrun) {
+			d->underrun = 0;
+                        hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                                             d->descrtab_phys) / sizeof(serdma_descr_t));
+			d->swptr = d->hwptr = hwptr;
+		}
+		swptr = d->swptr;
+		cnt = d->sbufsz - (swptr * FRAME_SAMPLE_BYTES);
+                /* Will this write fill up the buffer? */
+		if (d->count + cnt > d->sbufsz)
+			cnt = d->sbufsz - d->count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (cnt > count)
+			cnt = count;
+		if (cnt <= 0) {
+			start_dac(s);
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : -EAGAIN;
+			interruptible_sleep_on(&d->wait);
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+			continue;
+		}
+		if (copy_from_user(d->sample_buf, buffer, cnt))
+			return ret ? ret : -EFAULT;
+
+                copy_cnt = cnt;
+                s_tmpl = (u32 *)d->sample_buf;
+                t_tmpl = (u32 *)(d->dma_buf + (swptr * 4));
+
+                /* XXXKW assuming 16-bit stereo! */
+                do {
+                        t_tmpl[0] = 0x98000000;
+                        left = s_tmpl[0] >> 16;
+                        if (left & 0x8000)
+                                left |= 0xf0000;
+                        right = s_tmpl[0] & 0xffff;
+                        if (right & 0x8000)
+                                right |= 0xf0000;
+                        if (swap) {
+                          t_tmpl[1] = left & 0xff;
+                          t_tmpl[2] = ((left & 0xff00) << 16) | ((right & 0xff) << 12) |
+                              ((right & 0xff00) >> 4);
+                        } else {
+                          t_tmpl[1] = left >> 8;
+                          t_tmpl[2] = ((left & 0xff) << 24) | (right << 4);
+                        }
+                        s_tmpl++;
+                        t_tmpl += 8;
+                        copy_cnt -= 4;
+                } while (copy_cnt);
+
+                /* Mux in any pending read/write accesses */
+                if (s->reg_request) {
+                        *(u64 *)(d->dma_buf + (swptr * 4)) |= s->reg_request;
+                        s->reg_request = 0;
+                        wake_up(&s->dma_dac.reg_wait);
+                }
+
+                CS_DBGOUT(CS_WAVE_WRITE, 4,
+                          printk(KERN_INFO
+                                 "cs4297a: copy in %d to swptr %x\n", cnt, swptr));
+
+		swptr = (swptr + (cnt/FRAME_SAMPLE_BYTES)) % d->ringsz;
+                out64(cnt/FRAME_SAMPLE_BYTES, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
+		spin_lock_irqsave(&s->lock, flags);
+		d->swptr = swptr;
+		d->count += cnt;
+		d->endcleared = 0;
+		spin_unlock_irqrestore(&s->lock, flags);
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+		start_dac(s);
+	}
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
+		  printk(KERN_INFO "cs4297a: cs4297a_write()- %d\n", ret));
+	return ret;
+}
+
+
+static unsigned int cs4297a_poll(struct file *file,
+				struct poll_table_struct *wait)
+{
+	struct cs4297a_state *s =
+	    (struct cs4297a_state *) file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+		  printk(KERN_INFO "cs4297a: cs4297a_poll()+\n"));
+	VALIDATE_STATE(s);
+	if (file->f_mode & FMODE_WRITE) {
+		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+			  printk(KERN_INFO
+				 "cs4297a: cs4297a_poll() wait on FMODE_WRITE\n"));
+		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
+			return 0;
+		poll_wait(file, &s->dma_dac.wait, wait);
+	}
+	if (file->f_mode & FMODE_READ) {
+		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+			  printk(KERN_INFO
+				 "cs4297a: cs4297a_poll() wait on FMODE_READ\n"));
+		if(!s->dma_dac.ready && prog_dmabuf_adc(s))
+			return 0;
+		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+	spin_lock_irqsave(&s->lock, flags);
+	cs4297a_update_ptr(s,CS_FALSE);
+	if (file->f_mode & FMODE_WRITE) {
+		if (s->dma_dac.mapped) {
+			if (s->dma_dac.count >=
+			    (signed) s->dma_dac.fragsize) {
+				if (s->dma_dac.wakeup)
+					mask |= POLLOUT | POLLWRNORM;
+				else
+					mask = 0;
+				s->dma_dac.wakeup = 0;
+			}
+		} else {
+			if ((signed) (s->dma_dac.sbufsz/2) >= s->dma_dac.count)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	} else if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.mapped) {
+			if (s->dma_adc.count >= (signed) s->dma_adc.fragsize) 
+				mask |= POLLIN | POLLRDNORM;
+		} else {
+			if (s->dma_adc.count > 0)
+				mask |= POLLIN | POLLRDNORM;
+		}
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+		  printk(KERN_INFO "cs4297a: cs4297a_poll()- 0x%.8x\n",
+			 mask));
+	return mask;
+}
+
+
+static int cs4297a_mmap(struct file *file, struct vm_area_struct *vma)
+{
+        /* XXXKW currently no mmap support */
+        return -EINVAL;
+	return 0;
+}
+
+
+static int cs4297a_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	struct cs4297a_state *s =
+	    (struct cs4297a_state *) file->private_data;
+	unsigned long flags;
+	audio_buf_info abinfo;
+	count_info cinfo;
+	int val, mapped, ret;
+
+	CS_DBGOUT(CS_FUNCTION|CS_IOCTL, 4, printk(KERN_INFO
+		 "cs4297a: cs4297a_ioctl(): file=0x%.8x cmd=0x%.8x\n",
+			 (unsigned) file, cmd));
+#if CSDEBUG
+	cs_printioctl(cmd);
+#endif
+	VALIDATE_STATE(s);
+	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+	    ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+	switch (cmd) {
+	case OSS_GETVERSION:
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			"cs4297a: cs4297a_ioctl(): SOUND_VERSION=0x%.8x\n",
+				 SOUND_VERSION));
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	case SNDCTL_DSP_SYNC:
+		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
+			 "cs4297a: cs4297a_ioctl(): DSP_SYNC\n"));
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(s,
+					 0 /*file->f_flags & O_NONBLOCK */
+					 );
+		return 0;
+
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+				DSP_CAP_TRIGGER | DSP_CAP_MMAP,
+				(int *) arg);
+
+	case SNDCTL_DSP_RESET:
+		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
+			 "cs4297a: cs4297a_ioctl(): DSP_RESET\n"));
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			synchronize_irq();
+                        s->dma_dac.count = s->dma_dac.total_bytes =
+                                s->dma_dac.blocks = s->dma_dac.wakeup = 0;
+			s->dma_dac.swptr = s->dma_dac.hwptr =
+                                (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                                       s->dma_dac.descrtab_phys) / sizeof(serdma_descr_t));
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			synchronize_irq();
+                        s->dma_adc.count = s->dma_adc.total_bytes =
+                                s->dma_adc.blocks = s->dma_dac.wakeup = 0;
+			s->dma_adc.swptr = s->dma_adc.hwptr =
+                                (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                                       s->dma_adc.descrtab_phys) / sizeof(serdma_descr_t));
+		}
+		return 0;
+
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			 "cs4297a: cs4297a_ioctl(): DSP_SPEED val=%d -> 48000\n", val));
+                val = 48000;
+                return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			 "cs4297a: cs4297a_ioctl(): DSP_STEREO val=%d\n", val));
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.ready = 0;
+			s->prop_adc.channels = val ? 2 : 1;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.ready = 0;
+			s->prop_dac.channels = val ? 2 : 1;
+		}
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			 "cs4297a: cs4297a_ioctl(): DSP_CHANNELS val=%d\n",
+				 val));
+		if (val != 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				s->dma_adc.ready = 0;
+				if (val >= 2)
+					s->prop_adc.channels = 2;
+				else
+					s->prop_adc.channels = 1;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				s->dma_dac.ready = 0;
+				if (val >= 2)
+					s->prop_dac.channels = 2;
+				else
+					s->prop_dac.channels = 1;
+			}
+		}
+
+		if (file->f_mode & FMODE_WRITE)
+			val = s->prop_dac.channels;
+		else if (file->f_mode & FMODE_READ)
+			val = s->prop_adc.channels;
+
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETFMTS:	// Returns a mask 
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			"cs4297a: cs4297a_ioctl(): DSP_GETFMT val=0x%.8x\n",
+				 AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
+				 AFMT_U8));
+		return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
+				AFMT_U8, (int *) arg);
+
+	case SNDCTL_DSP_SETFMT:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			 "cs4297a: cs4297a_ioctl(): DSP_SETFMT val=0x%.8x\n",
+				 val));
+		if (val != AFMT_QUERY) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				s->dma_adc.ready = 0;
+				if (val != AFMT_S16_LE
+				    && val != AFMT_U16_LE && val != AFMT_S8
+				    && val != AFMT_U8)
+					val = AFMT_U8;
+				s->prop_adc.fmt = val;
+				s->prop_adc.fmt_original = s->prop_adc.fmt;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				s->dma_dac.ready = 0;
+				if (val != AFMT_S16_LE
+				    && val != AFMT_U16_LE && val != AFMT_S8
+				    && val != AFMT_U8)
+					val = AFMT_U8;
+				s->prop_dac.fmt = val;
+				s->prop_dac.fmt_original = s->prop_dac.fmt;
+			}
+		} else {
+			if (file->f_mode & FMODE_WRITE)
+				val = s->prop_dac.fmt_original;
+			else if (file->f_mode & FMODE_READ)
+				val = s->prop_adc.fmt_original;
+		}
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+		  "cs4297a: cs4297a_ioctl(): DSP_SETFMT return val=0x%.8x\n", 
+			val));
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_POST:
+		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
+			 "cs4297a: cs4297a_ioctl(): DSP_POST\n"));
+		return 0;
+
+	case SNDCTL_DSP_GETTRIGGER:
+		val = 0;
+		if (file->f_mode & s->ena & FMODE_READ)
+			val |= PCM_ENABLE_INPUT;
+		if (file->f_mode & s->ena & FMODE_WRITE)
+			val |= PCM_ENABLE_OUTPUT;
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_SETTRIGGER:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			if (val & PCM_ENABLE_INPUT) {
+				if (!s->dma_adc.ready
+				    && (ret = prog_dmabuf_adc(s)))
+					return ret;
+				start_adc(s);
+			} else
+				stop_adc(s);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val & PCM_ENABLE_OUTPUT) {
+				if (!s->dma_dac.ready
+				    && (ret = prog_dmabuf_dac(s)))
+					return ret;
+				start_dac(s);
+			} else
+				stop_dac(s);
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
+			return val;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4297a_update_ptr(s,CS_FALSE);
+		abinfo.fragsize = s->dma_dac.fragsize;
+		if (s->dma_dac.mapped)
+			abinfo.bytes = s->dma_dac.sbufsz;
+		else
+			abinfo.bytes =
+			    s->dma_dac.sbufsz - s->dma_dac.count;
+		abinfo.fragstotal = s->dma_dac.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+		CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO
+			"cs4297a: cs4297a_ioctl(): GETOSPACE .fragsize=%d .bytes=%d .fragstotal=%d .fragments=%d\n",
+				abinfo.fragsize,abinfo.bytes,abinfo.fragstotal,
+				abinfo.fragments));
+		spin_unlock_irqrestore(&s->lock, flags);
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
+			return val;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4297a_update_ptr(s,CS_FALSE);
+		if (s->conversion) {
+			abinfo.fragsize = s->dma_adc.fragsize / 2;
+			abinfo.bytes = s->dma_adc.count / 2;
+			abinfo.fragstotal = s->dma_adc.numfrag;
+			abinfo.fragments =
+			    abinfo.bytes >> (s->dma_adc.fragshift - 1);
+		} else {
+			abinfo.fragsize = s->dma_adc.fragsize;
+			abinfo.bytes = s->dma_adc.count;
+			abinfo.fragstotal = s->dma_adc.numfrag;
+			abinfo.fragments =
+			    abinfo.bytes >> s->dma_adc.fragshift;
+		}
+		spin_unlock_irqrestore(&s->lock, flags);
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
+			return 0;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4297a_update_ptr(s,CS_FALSE);
+		val = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		if(!s->dma_adc.ready && prog_dmabuf_adc(s))
+			return 0;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4297a_update_ptr(s,CS_FALSE);
+		cinfo.bytes = s->dma_adc.total_bytes;
+		if (s->dma_adc.mapped) {
+			cinfo.blocks =
+			    (cinfo.bytes >> s->dma_adc.fragshift) -
+			    s->dma_adc.blocks;
+			s->dma_adc.blocks =
+			    cinfo.bytes >> s->dma_adc.fragshift;
+		} else {
+			if (s->conversion) {
+				cinfo.blocks =
+				    s->dma_adc.count /
+				    2 >> (s->dma_adc.fragshift - 1);
+			} else
+				cinfo.blocks =
+				    s->dma_adc.count >> s->dma_adc.
+				    fragshift;
+		}
+		if (s->conversion)
+			cinfo.ptr = s->dma_adc.hwptr / 2;
+		else
+			cinfo.ptr = s->dma_adc.hwptr;
+		if (s->dma_adc.mapped)
+			s->dma_adc.count &= s->dma_adc.fragsize - 1;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
+			return 0;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4297a_update_ptr(s,CS_FALSE);
+		cinfo.bytes = s->dma_dac.total_bytes;
+		if (s->dma_dac.mapped) {
+			cinfo.blocks =
+			    (cinfo.bytes >> s->dma_dac.fragshift) -
+			    s->dma_dac.blocks;
+			s->dma_dac.blocks =
+			    cinfo.bytes >> s->dma_dac.fragshift;
+		} else {
+			cinfo.blocks =
+			    s->dma_dac.count >> s->dma_dac.fragshift;
+		}
+		cinfo.ptr = s->dma_dac.hwptr;
+		if (s->dma_dac.mapped)
+			s->dma_dac.count &= s->dma_dac.fragsize - 1;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE) {
+			if ((val = prog_dmabuf_dac(s)))
+				return val;
+			return put_user(s->dma_dac.fragsize, (int *) arg);
+		}
+		if ((val = prog_dmabuf_adc(s)))
+			return val;
+		if (s->conversion)
+			return put_user(s->dma_adc.fragsize / 2,
+					(int *) arg);
+		else
+			return put_user(s->dma_adc.fragsize, (int *) arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		return 0;	// Say OK, but do nothing.
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision)
+		    || (file->f_mode & FMODE_WRITE
+			&& s->dma_dac.subdivision)) return -EINVAL;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 1 && val != 2 && val != 4)
+			return -EINVAL;
+		if (file->f_mode & FMODE_READ)
+			s->dma_adc.subdivision = val;
+		else if (file->f_mode & FMODE_WRITE)
+			s->dma_dac.subdivision = val;
+		return 0;
+
+	case SOUND_PCM_READ_RATE:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->prop_adc.rate, (int *) arg);
+		else if (file->f_mode & FMODE_WRITE)
+			return put_user(s->prop_dac.rate, (int *) arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->prop_adc.channels, (int *) arg);
+		else if (file->f_mode & FMODE_WRITE)
+			return put_user(s->prop_dac.channels, (int *) arg);
+
+	case SOUND_PCM_READ_BITS:
+		if (file->f_mode & FMODE_READ)
+			return
+			    put_user(
+				     (s->prop_adc.
+				      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
+				     (int *) arg);
+		else if (file->f_mode & FMODE_WRITE)
+			return
+			    put_user(
+				     (s->prop_dac.
+				      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
+				     (int *) arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
+	return mixer_ioctl(s, cmd, arg);
+}
+
+
+static int cs4297a_release(struct inode *inode, struct file *file)
+{
+	struct cs4297a_state *s =
+	    (struct cs4297a_state *) file->private_data;
+
+        CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk(KERN_INFO
+		 "cs4297a: cs4297a_release(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n",
+			 (unsigned) inode, (unsigned) file, file->f_mode));
+	VALIDATE_STATE(s);
+
+	if (file->f_mode & FMODE_WRITE) {
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+		down(&s->open_sem_dac);
+		stop_dac(s);
+		dealloc_dmabuf(s, &s->dma_dac);
+		s->open_mode &= ~FMODE_WRITE;
+		up(&s->open_sem_dac);
+		wake_up(&s->open_wait_dac);
+		MOD_DEC_USE_COUNT;
+	}
+	if (file->f_mode & FMODE_READ) {
+		drain_adc(s, file->f_flags & O_NONBLOCK);
+		down(&s->open_sem_adc);
+		stop_adc(s);
+		dealloc_dmabuf(s, &s->dma_adc);
+		s->open_mode &= ~FMODE_READ;
+		up(&s->open_sem_adc);
+		wake_up(&s->open_wait_adc);
+		MOD_DEC_USE_COUNT;
+	}
+	return 0;
+}
+
+static int cs4297a_open(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct cs4297a_state *s=NULL;
+	struct list_head *entry;
+
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
+		"cs4297a: cs4297a_open(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n",
+			(unsigned) inode, (unsigned) file, file->f_mode));
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
+                "cs4297a: status = %08x\n", (int)in64(SS_CSR(R_SER_STATUS_DEBUG))));
+
+	list_for_each(entry, &cs4297a_devs)
+	{
+		s = list_entry(entry, struct cs4297a_state, list);
+
+		if (!((s->dev_audio ^ minor) & ~0xf))
+			break;
+	}
+	if (entry == &cs4297a_devs)
+		return -ENODEV;
+	if (!s) {
+		CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
+			"cs4297a: cs4297a_open(): Error - unable to find audio state struct\n"));
+		return -ENODEV;
+	}
+	VALIDATE_STATE(s);
+	file->private_data = s;
+
+	// wait for device to become free 
+	if (!(file->f_mode & (FMODE_WRITE | FMODE_READ))) {
+		CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, printk(KERN_INFO
+			 "cs4297a: cs4297a_open(): Error - must open READ and/or WRITE\n"));
+		return -ENODEV;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+                if (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)) != 0) {
+                        printk(KERN_ERR "cs4297a: TX pipe needs to drain\n");
+                        while (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)))
+                                ;
+                }
+          
+		down(&s->open_sem_dac);
+		while (s->open_mode & FMODE_WRITE) {
+			if (file->f_flags & O_NONBLOCK) {
+				up(&s->open_sem_dac);
+				return -EBUSY;
+			}
+			up(&s->open_sem_dac);
+			interruptible_sleep_on(&s->open_wait_dac);
+
+			if (signal_pending(current)) {
+                                printk("open - sig pending\n");
+				return -ERESTARTSYS;
+                        }
+			down(&s->open_sem_dac);
+		}
+	}
+	if (file->f_mode & FMODE_READ) {
+		down(&s->open_sem_adc);
+		while (s->open_mode & FMODE_READ) {
+			if (file->f_flags & O_NONBLOCK) {
+				up(&s->open_sem_adc);
+				return -EBUSY;
+			}
+			up(&s->open_sem_adc);
+			interruptible_sleep_on(&s->open_wait_adc);
+
+			if (signal_pending(current)) {
+                                printk("open - sig pending\n");
+				return -ERESTARTSYS;
+                        }
+			down(&s->open_sem_adc);
+		}
+	}
+	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+	if (file->f_mode & FMODE_READ) {
+		s->prop_adc.fmt = AFMT_S16_BE;
+		s->prop_adc.fmt_original = s->prop_adc.fmt;
+		s->prop_adc.channels = 2;
+		s->prop_adc.rate = 48000;
+		s->conversion = 0;
+		s->ena &= ~FMODE_READ;
+		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+		    s->dma_adc.subdivision = 0;
+		up(&s->open_sem_adc);
+		MOD_INC_USE_COUNT;
+
+		if (prog_dmabuf_adc(s)) {
+			CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
+				"cs4297a: adc Program dmabufs failed.\n"));
+			cs4297a_release(inode, file);
+			return -ENOMEM;
+		}
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		s->prop_dac.fmt = AFMT_S16_BE;
+		s->prop_dac.fmt_original = s->prop_dac.fmt;
+		s->prop_dac.channels = 2;
+		s->prop_dac.rate = 48000;
+		s->conversion = 0;
+		s->ena &= ~FMODE_WRITE;
+		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+		    s->dma_dac.subdivision = 0;
+		up(&s->open_sem_dac);
+		MOD_INC_USE_COUNT;
+
+		if (prog_dmabuf_dac(s)) {
+			CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
+				"cs4297a: dac Program dmabufs failed.\n"));
+			cs4297a_release(inode, file);
+			return -ENOMEM;
+		}
+	}
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
+		  printk(KERN_INFO "cs4297a: cs4297a_open()- 0\n"));
+	return 0;
+}
+
+
+// ******************************************************************************************
+//   Wave (audio) file operations struct.
+// ******************************************************************************************
+static /*const */ struct file_operations cs4297a_audio_fops = {
+	llseek:cs4297a_llseek,
+	read:cs4297a_read,
+	write:cs4297a_write,
+	poll:cs4297a_poll,
+	ioctl:cs4297a_ioctl,
+	mmap:cs4297a_mmap,
+	open:cs4297a_open,
+	release:cs4297a_release,
+};
+
+static void cs4297a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct cs4297a_state *s = (struct cs4297a_state *) dev_id;
+        u32 status;
+
+        status = in64(SS_CSR(R_SER_STATUS_DEBUG));
+
+        CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
+                 "cs4297a: cs4297a_interrupt() HISR=0x%.8x\n", status));
+
+#if 0
+        /* XXXKW what check *should* be done here? */
+        if (!(status & (M_SYNCSER_RX_EOP_COUNT | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_SYNC_ERR))) {
+                status = in64(SS_CSR(R_SER_STATUS));
+                printk(KERN_ERR "cs4297a: unexpected interrupt (status %08x)\n", status);
+                return;
+        }
+#endif
+
+        if (status & M_SYNCSER_RX_SYNC_ERR) {
+                status = in64(SS_CSR(R_SER_STATUS));
+                printk(KERN_ERR "cs4297a: rx sync error (status %08x)\n", status);
+                return;
+        }
+
+        if (status & M_SYNCSER_RX_OVERRUN) {
+                int newptr, i;
+                s->stats.rx_ovrrn++;
+                printk(KERN_ERR "cs4297a: receive FIFO overrun\n");
+
+                /* Fix things up: get the receive descriptor pool
+                   clean and give them back to the hardware */
+                while (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_RX)))
+                        ;
+                newptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                                     s->dma_adc.descrtab_phys) / sizeof(serdma_descr_t));
+                for (i=0; i<DMA_DESCR; i++) {
+                        s->dma_adc.descrtab[i].descr_a &= ~M_DMA_SERRX_SOP;
+                }
+                s->dma_adc.swptr = s->dma_adc.hwptr = newptr;
+                s->dma_adc.count = 0;
+                s->dma_adc.sb_swptr = s->dma_adc.sb_hwptr = s->dma_adc.sample_buf;
+                out64(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+        }
+
+	spin_lock(&s->lock);
+	cs4297a_update_ptr(s,CS_TRUE);
+	spin_unlock(&s->lock);
+
+	CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
+		  "cs4297a: cs4297a_interrupt()-\n"));
+}
+
+static struct initvol {
+	int mixch;
+	int vol;
+} initvol[] __initdata = {
+
+  	{SOUND_MIXER_WRITE_VOLUME, 0x4040},
+        {SOUND_MIXER_WRITE_PCM, 0x4040},
+        {SOUND_MIXER_WRITE_SYNTH, 0x4040},
+	{SOUND_MIXER_WRITE_CD, 0x4040},
+	{SOUND_MIXER_WRITE_LINE, 0x4040},
+	{SOUND_MIXER_WRITE_LINE1, 0x4040},
+	{SOUND_MIXER_WRITE_RECLEV, 0x0000},
+	{SOUND_MIXER_WRITE_SPEAKER, 0x4040},
+	{SOUND_MIXER_WRITE_MIC, 0x0000}
+};
+
+static int __init cs4297a_init(void)
+{
+	struct cs4297a_state *s;
+        u64 cfg;
+        u32 pwr, id;
+	mm_segment_t fs;
+        int rval, mdio_val;
+
+	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
+		"cs4297a: cs4297a_init_module()+ \n"));
+
+        mdio_val = in64(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)) &
+                (M_MAC_MDIO_DIR|M_MAC_MDIO_OUT);
+
+        /* Check syscfg for synchronous serial on port 1 */
+        cfg = in64(KSEG1 + A_SCD_SYSTEM_CFG);
+        if (!(cfg & M_SYS_SER1_ENABLE)) {
+                out64(cfg | M_SYS_SER1_ENABLE, KSEG1+A_SCD_SYSTEM_CFG);
+                cfg = in64(KSEG1 + A_SCD_SYSTEM_CFG);
+                if (!(cfg & M_SYS_SER1_ENABLE)) {
+                  printk(KERN_INFO "cs4297a: serial port 1 not configured for synchronous operation\n");
+                  return -1;
+                }
+
+                printk(KERN_INFO "cs4297a: serial port 1 switching to synchronous operation\n");
+                
+                /* Force the codec (on SWARM) to reset by clearing
+                   GENO, preserving MDIO (no effect on CSWARM) */
+                out64(mdio_val, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
+                udelay(10);
+        }
+
+        /* Now set GENO */
+        out64(mdio_val | M_MAC_GENC, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
+        /* Give the codec some time to finish resetting (start the bit clock) */
+        udelay(100);
+
+	if (!(s = kmalloc(sizeof(struct cs4297a_state), GFP_KERNEL))) {
+		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+		      "cs4297a: probe() no memory for state struct.\n"));
+		return -1;
+	}
+	memset(s, 0, sizeof(struct cs4297a_state));
+        s->magic = CS4297a_MAGIC;
+	init_waitqueue_head(&s->dma_adc.wait);
+	init_waitqueue_head(&s->dma_dac.wait);
+	init_waitqueue_head(&s->dma_adc.reg_wait);
+	init_waitqueue_head(&s->dma_dac.reg_wait);
+	init_waitqueue_head(&s->open_wait);
+	init_waitqueue_head(&s->open_wait_adc);
+	init_waitqueue_head(&s->open_wait_dac);
+	init_MUTEX(&s->open_sem_adc);
+	init_MUTEX(&s->open_sem_dac);
+	spin_lock_init(&s->lock);
+
+        s->irq = K_INT_SER_1;
+
+	if (request_irq
+	    (s->irq, cs4297a_interrupt, 0, "Crystal CS4297a", s)) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
+			  printk(KERN_ERR "cs4297a: irq %u in use\n", s->irq));
+		goto err_irq;
+	}
+	if ((s->dev_audio = register_sound_dsp(&cs4297a_audio_fops, -1)) <
+	    0) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
+			 "cs4297a: probe() register_sound_dsp() failed.\n"));
+		goto err_dev1;
+	}
+	if ((s->dev_mixer = register_sound_mixer(&cs4297a_mixer_fops, -1)) <
+	    0) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
+			 "cs4297a: probe() register_sound_mixer() failed.\n"));
+		goto err_dev2;
+	}
+
+        if (ser_init(s) || dma_init(s)) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
+			 "cs4297a: ser_init failed.\n"));
+		goto err_dev3;
+        }
+
+        do {
+                udelay(4000);
+                rval = cs4297a_read_ac97(s, AC97_POWER_CONTROL, &pwr);
+        } while (!rval && (pwr != 0xf));
+
+        if (!rval) {
+                fs = get_fs();
+                set_fs(KERNEL_DS);
+#if 0
+                val = SOUND_MASK_LINE;
+                mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val);
+                for (i = 0; i < sizeof(initvol) / sizeof(initvol[0]); i++) {
+                        val = initvol[i].vol;
+                        mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val);
+                }
+//                cs4297a_write_ac97(s, 0x18, 0x0808);
+#else
+                //                cs4297a_write_ac97(s, 0x5e, 0x180);
+                cs4297a_write_ac97(s, 0x02, 0x0808);
+                cs4297a_write_ac97(s, 0x18, 0x0808);
+#endif
+                set_fs(fs);
+
+                list_add(&s->list, &cs4297a_devs);
+
+                cs4297a_read_ac97(s, AC97_VENDOR_ID1, &id);
+                
+                printk(KERN_INFO "cs4297a: initialized (vendor id = %x)\n", id);
+
+                CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
+                          printk(KERN_INFO "cs4297a: cs4297a_init_module()-\n"));
+                
+                return 0;
+        }
+
+ err_dev3:
+	unregister_sound_mixer(s->dev_mixer);
+ err_dev2:
+	unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+	free_irq(s->irq, s);
+ err_irq:
+	kfree(s);
+
+        printk(KERN_INFO "cs4297a: initialization failed\n");
+
+        return -1;
+}
+
+static void __exit cs4297a_cleanup(void)
+{
+        /*
+          XXXKW 
+           disable_irq, free_irq
+           drain DMA queue
+           disable DMA
+           disable TX/RX
+           free memory
+        */
+	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4297a: cleanup_cs4297a() finished\n"));
+}
+
+// --------------------------------------------------------------------- 
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Kip Walker, kwalker@broadcom.com");
+MODULE_DESCRIPTION("Cirrus Logic CS4297a Driver for Broadcom SWARM board");
+
+// --------------------------------------------------------------------- 
+
+module_init(cs4297a_init);
+module_exit(cs4297a_cleanup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/trident.c linux/drivers/sound/trident.c
--- linux.orig/drivers/sound/trident.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/sound/trident.c	2002-07-20 01:08:39.000000000 +0000
@@ -2447,7 +2447,7 @@
 		if (dmabuf->mapped)
 			dmabuf->count &= dmabuf->fragsize-1;
 		spin_unlock_irqrestore(&state->card->lock, flags);
-		ret = copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		ret = copy_to_user((void *)arg, &cinfo, sizeof(cinfo))?-EFAULT:0;
 		break;
 
 	case SNDCTL_DSP_GETOPTR:
@@ -3297,11 +3297,18 @@
 			ali_ac97_write(card->ac97_codec[0], 0x02, 8080);
 			ali_ac97_write(card->ac97_codec[0], 0x36, 0);
 			ali_ac97_write(card->ac97_codec[0], 0x38, 0);
-			ali_ac97_write(card->ac97_codec[1], 0x36, 0);
-			ali_ac97_write(card->ac97_codec[1], 0x38, 0);
-			ali_ac97_write(card->ac97_codec[1], 0x02, 0x0606);
-			ali_ac97_write(card->ac97_codec[1], 0x18, 0x0303);
-			ali_ac97_write(card->ac97_codec[1], 0x74, 0x3);
+			/*
+			 *	On a board with a single codec you won't get the
+			 *	surround. On other boards configure it.
+			 */
+			if(card->ac97_codec[1]!=NULL)
+			{
+				ali_ac97_write(card->ac97_codec[1], 0x36, 0);
+				ali_ac97_write(card->ac97_codec[1], 0x38, 0);
+				ali_ac97_write(card->ac97_codec[1], 0x02, 0x0606);
+				ali_ac97_write(card->ac97_codec[1], 0x18, 0x0303);
+				ali_ac97_write(card->ac97_codec[1], 0x74, 0x3);
+			}
 			return 1;
 		}
 	}
@@ -3813,7 +3820,7 @@
 	pci_write_config_dword(pci_dev, 0x44, dwVal & 0xfffbffff);
 	udelay(5000);
 
-	wCount = 200;
+	wCount = 2000;
 	while(wCount--) {
 		wReg = ali_ac97_get(card, 0, AC97_POWER_CONTROL);
 		if((wReg & 0x000f) == 0x000f)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/trident.h linux/drivers/sound/trident.h
--- linux.orig/drivers/sound/trident.h	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/sound/trident.h	2002-07-20 01:08:21.000000000 +0000
@@ -333,7 +333,7 @@
 #define VALIDATE_STATE(a) VALIDATE_MAGIC(a,TRIDENT_STATE_MAGIC)
 #define VALIDATE_CARD(a) VALIDATE_MAGIC(a,TRIDENT_CARD_MAGIC)
 
-extern __inline__ unsigned ld2(unsigned int x)
+static inline unsigned ld2(unsigned int x)
 {
 	unsigned r = 0;
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c
--- linux.orig/drivers/sound/via82cxxx_audio.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/sound/via82cxxx_audio.c	2002-07-20 01:08:30.000000000 +0000
@@ -354,8 +354,6 @@
 static struct pci_device_id via_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
 	  PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5,
-	  PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci,via_pci_tbl);
@@ -2051,7 +2049,7 @@
 	while ((count > 0) && (chan->slop_len < chan->frag_size)) {
 		size_t slop_left = chan->frag_size - chan->slop_len;
 		void *base = chan->pgtbl[n / (PAGE_SIZE / chan->frag_size)].cpuaddr;
-		unsigned ofs = n % (PAGE_SIZE / chan->frag_size);
+		unsigned ofs = (n % (PAGE_SIZE / chan->frag_size)) * chan->frag_size;
 
 		size = (count < slop_left) ? count : slop_left;
 		if (copy_to_user (userbuf,
@@ -2528,7 +2526,7 @@
 		info.fragments,
 		info.bytes);
 
-	return copy_to_user (arg, &info, sizeof (info));
+	return copy_to_user (arg, &info, sizeof (info))?-EFAULT:0;
 }
 
 
@@ -2572,7 +2570,7 @@
 		info.blocks,
 		info.ptr);
 
-	return copy_to_user (arg, &info, sizeof (info));
+	return copy_to_user (arg, &info, sizeof (info))?-EFAULT:0;
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/vwsnd.c linux/drivers/sound/vwsnd.c
--- linux.orig/drivers/sound/vwsnd.c	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/sound/vwsnd.c	2002-07-20 01:08:22.000000000 +0000
@@ -535,7 +535,7 @@
 {
 	unsigned long later = jiffies + 2;
 	while (li_readl(lith, LI_CODEC_COMMAND) & LI_CC_BUSY)
-		if (jiffies >= later)
+		if (time_after_eq(jiffies, later))
 			return -EBUSY;
 	return 0;
 }
@@ -1358,7 +1358,7 @@
 	later = jiffies + HZ / 2;	/* roughly half a second */
 	DBGDO(shut_up++);
 	while (ad1843_read_bits(lith, &ad1843_PDNO)) {
-		if (jiffies > later) {
+		if (time_after(jiffies, later)) {
 			printk(KERN_ERR
 			       "vwsnd audio: AD1843 won't power up\n");
 			return -EIO;
@@ -2650,7 +2650,7 @@
 		DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n",
 		     buf_info.fragments, buf_info.fragstotal,
 		     buf_info.fragsize, buf_info.bytes);
-		return copy_to_user((void *) arg, &buf_info, sizeof buf_info);
+		return copy_to_user((void *) arg, &buf_info, sizeof buf_info) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETISPACE:	/* _SIOR ('P',13, audio_buf_info) */
 		DBGX("SNDCTL_DSP_GETISPACE\n");
@@ -2667,7 +2667,7 @@
 		DBGX("SNDCTL_DSP_GETISPACE returns { %d %d %d %d }\n",
 		     buf_info.fragments, buf_info.fragstotal,
 		     buf_info.fragsize, buf_info.bytes);
-		return copy_to_user((void *) arg, &buf_info, sizeof buf_info);
+		return copy_to_user((void *) arg, &buf_info, sizeof buf_info) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_NONBLOCK:	/* _SIO  ('P',14) */
 		DBGX("SNDCTL_DSP_NONBLOCK\n");
@@ -2725,7 +2725,7 @@
 			rport->frag_count = 0;
 		}
 		spin_unlock_irqrestore(&rport->lock, flags);
-		return copy_to_user((void *) arg, &info, sizeof info);
+		return copy_to_user((void *) arg, &info, sizeof info) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETOPTR:	/* _SIOR ('P',18, count_info) */
 		DBGX("SNDCTL_DSP_GETOPTR\n");
@@ -2747,7 +2747,7 @@
 			wport->frag_count = 0;
 		}
 		spin_unlock_irqrestore(&wport->lock, flags);
-		return copy_to_user((void *) arg, &info, sizeof info);
+		return copy_to_user((void *) arg, &info, sizeof info) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETODELAY:	/* _SIOR ('P', 23, int) */
 		DBGX("SNDCTL_DSP_GETODELAY\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- linux.orig/drivers/sound/ymfpci.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/sound/ymfpci.c	2002-07-20 01:08:24.000000000 +0000
@@ -1,6 +1,8 @@
 /*
  *  Copyright 1999 Jaroslav Kysela <perex@suse.cz>
  *  Copyright 2000 Alan Cox <alan@redhat.com>
+ *  Copyright 2001 Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
+ *  Copyright 2002 Pete Zaitcev <zaitcev@yahoo.com>
  *
  *  Yamaha YMF7xx driver.
  *
@@ -37,9 +39,16 @@
  *  - Remove prog_dmabuf from read/write, leave it in open.
  *  - 2001/01/07 Replace the OPL3 part of CONFIG_SOUND_YMFPCI_LEGACY code with
  *    native synthesizer through a playback slot.
- *  - Use new 2.3.x cache coherent PCI DMA routines instead of virt_to_bus.
- *  - Make the thing big endian compatible. ALSA has it done.
  *  - 2001/11/29 ac97_save_state
+ *    Talk to Kai to remove ac97_save_state before it's too late!
+ *  - Second AC97
+ *  - Restore S/PDIF - Toshibas have it.
+ *
+ * Kai used pci_alloc_consistent for DMA buffer, which sounds a little
+ * unconventional. However, given how small our fragments can be,
+ * a little uncached access is perhaps better than endless flushing.
+ * On i386 and other I/O-coherent architectures pci_alloc_consistent
+ * is entirely harmless.
  */
 
 #include <linux/config.h>
@@ -147,7 +156,7 @@
 {
 	signed long end_time;
 	u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
-	
+
 	end_time = jiffies + 3 * (HZ / 4);
 	do {
 		if ((ymfpci_readw(codec, reg) & 0x8000) == 0)
@@ -281,18 +290,22 @@
 #define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
 #define DMABUF_MINORDER 1
 
-/* allocate DMA buffer, playback and recording buffer should be allocated seperately */
-static int alloc_dmabuf(struct ymf_dmabuf *dmabuf)
+/*
+ * Allocate DMA buffer
+ */
+static int alloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf)
 {
 	void *rawbuf = NULL;
+	dma_addr_t dma_addr;
 	int order;
-	struct page * map,  * mapend;
+	struct page *map, *mapend;
 
 	/* alloc as big a chunk as we can */
-	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-		if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order)))
+	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) {
+		rawbuf = pci_alloc_consistent(unit->pci, PAGE_SIZE << order, &dma_addr);
+		if (rawbuf)
 			break;
-
+	}
 	if (!rawbuf)
 		return -ENOMEM;
 
@@ -303,6 +316,7 @@
 
 	dmabuf->ready  = dmabuf->mapped = 0;
 	dmabuf->rawbuf = rawbuf;
+	dmabuf->dma_addr = dma_addr;
 	dmabuf->buforder = order;
 
 	/* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
@@ -313,8 +327,10 @@
 	return 0;
 }
 
-/* free DMA buffer */
-static void dealloc_dmabuf(struct ymf_dmabuf *dmabuf)
+/*
+ * Free DMA buffer
+ */
+static void dealloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf)
 {
 	struct page *map, *mapend;
 
@@ -323,7 +339,9 @@
 		mapend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
 		for (map = virt_to_page(dmabuf->rawbuf); map <= mapend; map++)
 			clear_bit(PG_reserved, &map->flags);
-		free_pages((unsigned long)dmabuf->rawbuf,dmabuf->buforder);
+
+		pci_free_consistent(unit->pci, PAGE_SIZE << dmabuf->buforder,
+		    dmabuf->rawbuf, dmabuf->dma_addr);
 	}
 	dmabuf->rawbuf = NULL;
 	dmabuf->mapped = dmabuf->ready = 0;
@@ -349,7 +367,7 @@
 
 	/* allocate DMA buffer if not allocated yet */
 	if (!dmabuf->rawbuf)
-		if ((ret = alloc_dmabuf(dmabuf)))
+		if ((ret = alloc_dmabuf(state->unit, dmabuf)))
 			return ret;
 
 	/*
@@ -589,7 +607,8 @@
 	if (ypcm->running) {
 		YMFDBGI("ymfpci: %d, intr bank %d count %d start 0x%x:%x\n",
 		   voice->number, codec->active_bank, dmabuf->count,
-		   voice->bank[0].start, voice->bank[1].start);
+		   le32_to_cpu(voice->bank[0].start),
+		   le32_to_cpu(voice->bank[1].start));
 		silence = (ymf_pcm_format_width(state->format.format) == 16) ?
 		    0 : 0x80;
 		/* We need actual left-hand-side redzone size here. */
@@ -597,7 +616,7 @@
 		redzone <<= (state->format.shift + 1);
 		swptr = dmabuf->swptr;
 
-		pos = voice->bank[codec->active_bank].start;
+		pos = le32_to_cpu(voice->bank[codec->active_bank].start);
 		pos <<= state->format.shift;
 		if (pos < 0 || pos >= dmabuf->dmasize) {	/* ucode bug */
 			printk(KERN_ERR "ymfpci%d: runaway voice %d: hwptr %d=>%d dmasize %d\n",
@@ -700,7 +719,7 @@
 		redzone = ymf_calc_lend(state->format.rate);
 		redzone <<= (state->format.shift + 1);
 
-		pos = cap->bank[unit->active_bank].start;
+		pos = le32_to_cpu(cap->bank[unit->active_bank].start);
 		// pos <<= state->format.shift;
 		if (pos < 0 || pos >= dmabuf->dmasize) {	/* ucode bug */
 			printk(KERN_ERR "ymfpci%d: runaway capture %d: hwptr %d=>%d dmasize %d\n",
@@ -744,9 +763,11 @@
 		return -EINVAL;
 	}
 	if (cmd != 0) {
-		codec->ctrl_playback[ypcm->voices[0]->number + 1] = virt_to_bus(ypcm->voices[0]->bank);
+		codec->ctrl_playback[ypcm->voices[0]->number + 1] =
+		    cpu_to_le32(ypcm->voices[0]->bank_ba);
 		if (ypcm->voices[1] != NULL)
-			codec->ctrl_playback[ypcm->voices[1]->number + 1] = virt_to_bus(ypcm->voices[1]->bank);
+			codec->ctrl_playback[ypcm->voices[1]->number + 1] =
+			    cpu_to_le32(ypcm->voices[1]->bank_ba);
 		ypcm->running = 1;
 	} else {
 		codec->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
@@ -813,6 +834,14 @@
 	ymfpci_playback_bank_t *bank;
 	int nbank;
 
+	/*
+	 * The gain is a floating point number. According to the manual,
+	 * bit 31 indicates a sign bit, bit 30 indicates an integer part,
+	 * and bits [29:15] indicate a decimal fraction part. Thus,
+	 * for a gain of 1.0 the constant of 0x40000000 is loaded.
+	 */
+	unsigned default_gain = cpu_to_le32(0x40000000);
+
 	format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000);
 	if (stereo)
 		end >>= 1;
@@ -820,24 +849,24 @@
 		end >>= 1;
 	for (nbank = 0; nbank < 2; nbank++) {
 		bank = &voice->bank[nbank];
-		bank->format = format;
+		bank->format = cpu_to_le32(format);
 		bank->loop_default = 0;	/* 0-loops forever, otherwise count */
-		bank->base = addr;
+		bank->base = cpu_to_le32(addr);
 		bank->loop_start = 0;
-		bank->loop_end = end;
+		bank->loop_end = cpu_to_le32(end);
 		bank->loop_frac = 0;
-		bank->eg_gain_end = 0x40000000;
-		bank->lpfQ = lpfQ;
+		bank->eg_gain_end = default_gain;
+		bank->lpfQ = cpu_to_le32(lpfQ);
 		bank->status = 0;
 		bank->num_of_frames = 0;
 		bank->loop_count = 0;
 		bank->start = 0;
 		bank->start_frac = 0;
 		bank->delta =
-		bank->delta_end = delta;
+		bank->delta_end = cpu_to_le32(delta);
 		bank->lpfK =
-		bank->lpfK_end = lpfK;
-		bank->eg_gain = 0x40000000;
+		bank->lpfK_end = cpu_to_le32(lpfK);
+		bank->eg_gain = default_gain;
 		bank->lpfD1 =
 		bank->lpfD2 = 0;
 
@@ -857,31 +886,31 @@
 				bank->left_gain = 
 				bank->right_gain =
 				bank->left_gain_end =
-				bank->right_gain_end = 0x40000000;
+				bank->right_gain_end = default_gain;
 			} else {
 				bank->eff2_gain =
 				bank->eff2_gain_end =
 				bank->eff3_gain =
-				bank->eff3_gain_end = 0x40000000;
+				bank->eff3_gain_end = default_gain;
 			}
 		} else {
 			if (!spdif) {
 				if ((voice->number & 1) == 0) {
 					bank->left_gain =
-					bank->left_gain_end = 0x40000000;
+					bank->left_gain_end = default_gain;
 				} else {
-					bank->format |= 1;
+					bank->format |= cpu_to_le32(1);
 					bank->right_gain =
-					bank->right_gain_end = 0x40000000;
+					bank->right_gain_end = default_gain;
 				}
 			} else {
 				if ((voice->number & 1) == 0) {
 					bank->eff2_gain =
-					bank->eff2_gain_end = 0x40000000;
+					bank->eff2_gain_end = default_gain;
 				} else {
-					bank->format |= 1;
+					bank->format |= cpu_to_le32(1);
 					bank->eff3_gain =
-					bank->eff3_gain_end = 0x40000000;
+					bank->eff3_gain_end = default_gain;
 				}
 			}
 		}
@@ -922,7 +951,7 @@
 		ymf_pcm_init_voice(ypcm->voices[nvoice],
 		    state->format.voices == 2, state->format.rate,
 		    ymf_pcm_format_width(state->format.format) == 16,
-		    virt_to_bus(ypcm->dmabuf.rawbuf), ypcm->dmabuf.dmasize,
+		    ypcm->dmabuf.dma_addr, ypcm->dmabuf.dmasize,
 		    ypcm->spdif);
 	}
 	return 0;
@@ -971,9 +1000,9 @@
 	}
 	for (nbank = 0; nbank < 2; nbank++) {
 		bank = unit->bank_capture[ypcm->capture_bank_number][nbank];
-		bank->base = virt_to_bus(ypcm->dmabuf.rawbuf);
+		bank->base = cpu_to_le32(ypcm->dmabuf.dma_addr);
 		// bank->loop_end = ypcm->dmabuf.dmasize >> state->format.shift;
-		bank->loop_end = ypcm->dmabuf.dmasize;
+		bank->loop_end = cpu_to_le32(ypcm->dmabuf.dmasize);
 		bank->start = 0;
 		bank->num_of_loops = 0;
 	}
@@ -1810,9 +1839,9 @@
 		    cinfo.ptr, cinfo.bytes);
 		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
-	case SNDCTL_DSP_SETDUPLEX:	/* XXX TODO */
+	case SNDCTL_DSP_SETDUPLEX:
 		YMFDBGX("ymf_ioctl: cmd 0x%x(SETDUPLEX)\n", cmd);
-		return -EINVAL;
+		return 0;		/* Always duplex */
 
 	case SOUND_PCM_READ_RATE:
 		YMFDBGX("ymf_ioctl: cmd 0x%x(READ_RATE)\n", cmd);
@@ -1839,6 +1868,7 @@
 		 * Some programs mix up audio devices and ioctls
 		 * or perhaps they expect "universal" ioctls,
 		 * for instance we get SNDCTL_TMR_CONTINUE here.
+		 * (mpg123 -g 100 ends here too - to be fixed.)
 		 */
 		YMFDBGX("ymf_ioctl: cmd 0x%x unknown\n", cmd);
 		break;
@@ -1923,8 +1953,8 @@
 	 * a nestable exception, but here it is not nestable due to semaphore.
 	 * XXX Doubtful technique of self-describing objects....
 	 */
-	dealloc_dmabuf(&state->wpcm.dmabuf);
-	dealloc_dmabuf(&state->rpcm.dmabuf);
+	dealloc_dmabuf(unit, &state->wpcm.dmabuf);
+	dealloc_dmabuf(unit, &state->rpcm.dmabuf);
 	ymf_pcm_free_substream(&state->wpcm);
 	ymf_pcm_free_substream(&state->rpcm);
 
@@ -1952,8 +1982,8 @@
 	 */
 	ymf_wait_dac(state);
 	ymf_stop_adc(state);		/* fortunately, it's immediate */
-	dealloc_dmabuf(&state->wpcm.dmabuf);
-	dealloc_dmabuf(&state->rpcm.dmabuf);
+	dealloc_dmabuf(unit, &state->wpcm.dmabuf);
+	dealloc_dmabuf(unit, &state->rpcm.dmabuf);
 	ymf_pcm_free_substream(&state->wpcm);
 	ymf_pcm_free_substream(&state->rpcm);
 
@@ -2043,11 +2073,6 @@
 
 	unit->suspended = 1;
 
-	/*
-	 * XXX Talk to Kai to remove ac97_save_state before it's too late!
-	 * Other drivers call ac97_reset, which does not have
-	 * a save counterpart. Current ac97_save_state is empty.
-	 */
 	for (i = 0; i < NR_AC97; i++) {
 		if ((codec = unit->ac97_codec[i]) != NULL)
 			ac97_save_state(codec);
@@ -2288,29 +2313,39 @@
 
 static int ymfpci_memalloc(ymfpci_t *codec)
 {
-	long size, playback_ctrl_size;
+	unsigned int playback_ctrl_size;
+	unsigned int bank_size_playback;
+	unsigned int bank_size_capture;
+	unsigned int bank_size_effect;
+	unsigned int size;
+	unsigned int off;
+	char *ptr;
+	dma_addr_t pba;
 	int voice, bank;
-	u8 *ptr;
 
 	playback_ctrl_size = 4 + 4 * YDSXG_PLAYBACK_VOICES;
-	codec->bank_size_playback = ymfpci_readl(codec, YDSXGR_PLAYCTRLSIZE) << 2;
-	codec->bank_size_capture = ymfpci_readl(codec, YDSXGR_RECCTRLSIZE) << 2;
-	codec->bank_size_effect = ymfpci_readl(codec, YDSXGR_EFFCTRLSIZE) << 2;
+	bank_size_playback = ymfpci_readl(codec, YDSXGR_PLAYCTRLSIZE) << 2;
+	bank_size_capture = ymfpci_readl(codec, YDSXGR_RECCTRLSIZE) << 2;
+	bank_size_effect = ymfpci_readl(codec, YDSXGR_EFFCTRLSIZE) << 2;
 	codec->work_size = YDSXG_DEFAULT_WORK_SIZE;
 
 	size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) +
-	    ((codec->bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0xff) & ~0xff) +
-	    ((codec->bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0xff) & ~0xff) +
-	    ((codec->bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0xff) & ~0xff) +
+	    ((bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0xff) & ~0xff) +
+	    ((bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0xff) & ~0xff) +
+	    ((bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0xff) & ~0xff) +
 	    codec->work_size;
 
-	ptr = (u8 *)kmalloc(size + 0x00ff, GFP_KERNEL);
+	ptr = pci_alloc_consistent(codec->pci, size + 0xff, &pba);
 	if (ptr == NULL)
 		return -ENOMEM;
-
-	codec->work_ptr = ptr;
-	ptr += 0x00ff;
-	(long)ptr &= ~0x00ff;
+	codec->dma_area_va = ptr;
+	codec->dma_area_ba = pba;
+	codec->dma_area_size = size + 0xff;
+
+	if ((off = ((uint) ptr) & 0xff) != 0) {
+		ptr += 0x100 - off;
+		pba += 0x100 - off;
+	}
 
 	/*
 	 * Hardware requires only ptr[playback_ctrl_size] zeroed,
@@ -2318,34 +2353,49 @@
 	 */
 	memset(ptr, 0, size);
 
-	codec->bank_base_playback = ptr;
 	codec->ctrl_playback = (u32 *)ptr;
-	codec->ctrl_playback[0] = YDSXG_PLAYBACK_VOICES;
+	codec->ctrl_playback_ba = pba;
+	codec->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
 	ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
+	pba += (playback_ctrl_size + 0x00ff) & ~0x00ff;
+
+	off = 0;
 	for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
-		for (bank = 0; bank < 2; bank++) {
-			codec->bank_playback[voice][bank] = (ymfpci_playback_bank_t *)ptr;
-			ptr += codec->bank_size_playback;
-		}
 		codec->voices[voice].number = voice;
-		codec->voices[voice].bank = codec->bank_playback[voice][0];
-	}
-	ptr += (codec->bank_size_playback + 0x00ff) & ~0x00ff;
-	codec->bank_base_capture = ptr;
+		codec->voices[voice].bank =
+		    (ymfpci_playback_bank_t *) (ptr + off);
+		codec->voices[voice].bank_ba = pba + off;
+		off += 2 * bank_size_playback;		/* 2 banks */
+	}
+	off = (off + 0xff) & ~0xff;
+	ptr += off;
+	pba += off;
+
+	off = 0;
+	codec->bank_base_capture = pba;
 	for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
 		for (bank = 0; bank < 2; bank++) {
-			codec->bank_capture[voice][bank] = (ymfpci_capture_bank_t *)ptr;
-			ptr += codec->bank_size_capture;
-		}
-	ptr += (codec->bank_size_capture + 0x00ff) & ~0x00ff;
-	codec->bank_base_effect = ptr;
+			codec->bank_capture[voice][bank] =
+			    (ymfpci_capture_bank_t *) (ptr + off);
+			off += bank_size_capture;
+		}
+	off = (off + 0xff) & ~0xff;
+	ptr += off;
+	pba += off;
+
+	off = 0;
+	codec->bank_base_effect = pba;
 	for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
 		for (bank = 0; bank < 2; bank++) {
-			codec->bank_effect[voice][bank] = (ymfpci_effect_bank_t *)ptr;
-			ptr += codec->bank_size_effect;
-		}
-	ptr += (codec->bank_size_effect + 0x00ff) & ~0x00ff;
-	codec->work_base = ptr;
+			codec->bank_effect[voice][bank] =
+			    (ymfpci_effect_bank_t *) (ptr + off);
+			off += bank_size_effect;
+		}
+	off = (off + 0xff) & ~0xff;
+	ptr += off;
+	pba += off;
+
+	codec->work_base = pba;
 
 	return 0;
 }
@@ -2357,16 +2407,17 @@
 	ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0);
 	ymfpci_writel(codec, YDSXGR_WORKBASE, 0);
 	ymfpci_writel(codec, YDSXGR_WORKSIZE, 0);
-	kfree(codec->work_ptr);
+	pci_free_consistent(codec->pci,
+	    codec->dma_area_size, codec->dma_area_va, codec->dma_area_ba);
 }
 
 static void ymf_memload(ymfpci_t *unit)
 {
 
-	ymfpci_writel(unit, YDSXGR_PLAYCTRLBASE, virt_to_bus(unit->bank_base_playback));
-	ymfpci_writel(unit, YDSXGR_RECCTRLBASE, virt_to_bus(unit->bank_base_capture));
-	ymfpci_writel(unit, YDSXGR_EFFCTRLBASE, virt_to_bus(unit->bank_base_effect));
-	ymfpci_writel(unit, YDSXGR_WORKBASE, virt_to_bus(unit->work_base));
+	ymfpci_writel(unit, YDSXGR_PLAYCTRLBASE, unit->ctrl_playback_ba);
+	ymfpci_writel(unit, YDSXGR_RECCTRLBASE, unit->bank_base_capture);
+	ymfpci_writel(unit, YDSXGR_EFFCTRLBASE, unit->bank_base_effect);
+	ymfpci_writel(unit, YDSXGR_WORKBASE, unit->work_base);
 	ymfpci_writel(unit, YDSXGR_WORKSIZE, unit->work_size >> 2);
 
 	/* S/PDIF output initialization */
@@ -2531,7 +2582,7 @@
 	codec->opl3_data.irq     = -1;
 
 	codec->mpu_data.io_base  = codec->iomidi;
-	codec->mpu_data.irq      = -1;	/* XXX Make it ours. */
+	codec->mpu_data.irq      = -1;	/* May be different from our PCI IRQ. */
 
 	if (codec->iomidi) {
 		if (!probe_uart401(&codec->mpu_data, THIS_MODULE)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/sound/ymfpci.h linux/drivers/sound/ymfpci.h
--- linux.orig/drivers/sound/ymfpci.h	2001-08-12 17:51:42.000000000 +0000
+++ linux/drivers/sound/ymfpci.h	2002-07-20 01:08:33.000000000 +0000
@@ -227,6 +227,7 @@
 	char use, pcm, synth, midi;	// bool
 	ymfpci_playback_bank_t *bank;
 	struct ymf_pcm *ypcm;
+	dma_addr_t bank_ba;
 };
 
 struct ymf_capture {
@@ -239,19 +240,17 @@
 struct ymf_unit {
 	u8 rev;				/* PCI revision */
 	void *reg_area_virt;
-	void *work_ptr;
-
-	unsigned int bank_size_playback;
-	unsigned int bank_size_capture;
-	unsigned int bank_size_effect;
+	void *dma_area_va;
+	dma_addr_t dma_area_ba;
+	unsigned int dma_area_size;
+
+	dma_addr_t bank_base_capture;
+	dma_addr_t bank_base_effect;
+	dma_addr_t work_base;
 	unsigned int work_size;
 
-	void *bank_base_playback;
-	void *bank_base_capture;
-	void *bank_base_effect;
-	void *work_base;
-
 	u32 *ctrl_playback;
+	dma_addr_t ctrl_playback_ba;
 	ymfpci_playback_bank_t *bank_playback[YDSXG_PLAYBACK_VOICES][2];
 	ymfpci_capture_bank_t *bank_capture[YDSXG_CAPTURE_VOICES][2];
 	ymfpci_effect_bank_t *bank_effect[YDSXG_EFFECT_VOICES][2];
@@ -286,10 +285,11 @@
 };
 
 struct ymf_dmabuf {
-
-	/* OSS buffer management stuff */
+	dma_addr_t dma_addr;
 	void *rawbuf;
 	unsigned buforder;
+
+	/* OSS buffer management stuff */
 	unsigned numfrag;
 	unsigned fragshift;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/tc/lk201.c linux/drivers/tc/lk201.c
--- linux.orig/drivers/tc/lk201.c	2001-08-27 15:56:31.000000000 +0000
+++ linux/drivers/tc/lk201.c	2002-07-20 01:08:40.000000000 +0000
@@ -4,13 +4,22 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
+ * Copyright (C) 2001 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
  */
+
+#include <linux/config.h>
+
 #include <linux/errno.h>
+#include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kbd_ll.h>
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+
+#include <asm/keyboard.h>
 #include <asm/wbflush.h>
 #include <asm/dec/tc.h>
 #include <asm/dec/machtype.h>
@@ -27,6 +36,8 @@
  */
 unsigned char lk201_sysrq_xlate[128];
 unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate;
+
+unsigned char kbd_sysrq_key = -1;
 #endif
 
 #define KEYB_LINE	3
@@ -71,6 +82,8 @@
 	LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
 };
 
+static struct dec_serial* lk201kbd_info;
+
 static int __init lk201_reset(struct dec_serial *info)
 {
 	int i;
@@ -83,9 +96,115 @@
 	return 0;
 }
 
+#define DEFAULT_KEYB_REP_DELAY	(250/5)	/* [5ms] */
+#define DEFAULT_KEYB_REP_RATE	30	/* [cps] */
+
+static struct kbd_repeat kbdrate = {
+	DEFAULT_KEYB_REP_DELAY,
+	DEFAULT_KEYB_REP_RATE
+};
+
+static void parse_kbd_rate(struct kbd_repeat *r)
+{
+	if (r->delay <= 0)
+		r->delay = kbdrate.delay;
+	if (r->rate <= 0)
+		r->rate = kbdrate.rate;
+
+	if (r->delay < 5)
+		r->delay = 5;
+	if (r->delay > 630)
+		r->delay = 630;
+	if (r->rate < 12)
+		r->rate = 12;
+	if (r->rate > 127)
+		r->rate = 127;
+	if (r->rate == 125)
+		r->rate = 124;
+}
+
+static int write_kbd_rate(struct kbd_repeat *rep)
+{
+	struct dec_serial* info = lk201kbd_info;
+	int delay, rate;
+	int i;
+
+	delay = rep->delay / 5;
+	rate = rep->rate;
+	for (i = 0; i < 4; i++) {
+		if (info->hook->poll_tx_char(info, LK_CMD_RPT_RATE(i)))
+			return 1;
+		if (info->hook->poll_tx_char(info, LK_PARAM_DELAY(delay)))
+			return 1;
+		if (info->hook->poll_tx_char(info, LK_PARAM_RATE(rate)))
+			return 1;
+	}
+	return 0;
+}
+
+static int lk201kbd_rate(struct kbd_repeat *rep)
+{
+	if (rep == NULL)
+		return -EINVAL;
+
+	parse_kbd_rate(rep);
+
+	if (write_kbd_rate(rep)) {
+		memcpy(rep, &kbdrate, sizeof(struct kbd_repeat));
+		return -EIO;
+	}
+
+	memcpy(&kbdrate, rep, sizeof(struct kbd_repeat));
+
+	return 0;
+}
+
+static void lk201kd_mksound(unsigned int hz, unsigned int ticks)
+{
+	struct dec_serial* info = lk201kbd_info;
+
+	if (!ticks)
+		return;
+
+	/*
+	 * Can't set frequency and we "approximate"
+	 * duration by volume. ;-)
+	 */
+	ticks /= HZ / 32;
+	if (ticks > 7)
+		ticks = 7;
+	ticks = 7 - ticks;
+
+	if (info->hook->poll_tx_char(info, LK_CMD_ENB_BELL))
+		return;
+	if (info->hook->poll_tx_char(info, LK_PARAM_VOLUME(ticks)))
+		return;
+	if (info->hook->poll_tx_char(info, LK_CMD_BELL))
+		return;
+}
+
 void kbd_leds(unsigned char leds)
 {
-	return;
+	struct dec_serial* info = lk201kbd_info;
+	unsigned char l = 0;
+
+	if (!info)		/* FIXME */
+		return;
+
+	/* FIXME -- Only Hold and Lock LEDs for now. --macro */
+	if (leds & LED_SCR)
+		l |= LK_LED_HOLD;
+	if (leds & LED_CAP)
+		l |= LK_LED_LOCK;
+
+	if (info->hook->poll_tx_char(info, LK_CMD_LEDS_ON))
+		return;
+	if (info->hook->poll_tx_char(info, LK_PARAM_LED_MASK(l)))
+		return;
+	if (info->hook->poll_tx_char(info, LK_CMD_LEDS_OFF))
+		return;
+	if (info->hook->poll_tx_char(info, LK_PARAM_LED_MASK(~l)))
+		return;
 }
 
 int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
@@ -118,7 +237,12 @@
 
 	if (!stat || stat == 4) {
 		switch (ch) {
-		case LK_KEY_ACK:
+		case LK_STAT_RESUME_ERR:
+		case LK_STAT_ERROR:
+		case LK_STAT_INHIBIT_ACK:
+		case LK_STAT_TEST_ACK:
+		case LK_STAT_MODE_KEYDOWN:
+		case LK_STAT_MODE_ACK:
 			break;
 		case LK_KEY_LOCK:
 			shift_state ^= LK_LOCK;
@@ -157,6 +281,7 @@
 		}
 	} else
 		printk("Error reading LKx01 keyboard: 0x%02x\n", stat);
+	tasklet_schedule(&keyboard_tasklet);
 }
 
 static void __init lk201_info(struct dec_serial *info)
@@ -200,6 +325,10 @@
 	 */
 	info->hook->rx_char = lk201_kbd_rx_char;
 
+	lk201kbd_info = info;
+	kbd_rate = lk201kbd_rate;
+	kd_mksound = lk201kd_mksound;
+
 	return 0;
 }
 
@@ -231,7 +360,3 @@
 		printk("LK201 Support for DS3100 not yet ready ...\n");
 	}
 }
-
-
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/tc/lk201.h linux/drivers/tc/lk201.h
--- linux.orig/drivers/tc/lk201.h	2001-08-27 15:56:31.000000000 +0000
+++ linux/drivers/tc/lk201.h	2002-07-20 01:08:35.000000000 +0000
@@ -2,52 +2,121 @@
  *	Commands to the keyboard processor
  */
 
-#define	LK_PARAM		0x80	/* start/end parameter list */
+#define LK_PARAM		0x80	/* start/end parameter list */
 
-#define	LK_CMD_RESUME		0x8b
-#define	LK_CMD_INHIBIT		0xb9
-#define	LK_CMD_LEDS_ON		0x13	/* 1 param: led bitmask */
-#define	LK_CMD_LEDS_OFF		0x11	/* 1 param: led bitmask */
-#define	LK_CMD_DIS_KEYCLK	0x99
-#define	LK_CMD_ENB_KEYCLK	0x1b	/* 1 param: volume */
-#define	LK_CMD_DIS_CTLCLK	0xb9
-#define	LK_CMD_ENB_CTLCLK	0xbb
-#define	LK_CMD_SOUND_CLK	0x9f
-#define	LK_CMD_DIS_BELL		0xa1
-#define	LK_CMD_ENB_BELL		0x23	/* 1 param: volume */
-#define	LK_CMD_BELL		0xa7
-#define	LK_CMD_TMP_NORPT	0xc1
-#define	LK_CMD_ENB_RPT		0xe3
-#define	LK_CMD_DIS_RPT		0xe1
-#define	LK_CMD_RPT_TO_DOWN	0xd9
-#define	LK_CMD_REQ_ID		0xab
-#define	LK_CMD_POWER_UP		0xfd
-#define	LK_CMD_TEST_MODE	0xcb
-#define	LK_CMD_SET_DEFAULTS	0xd3
+#define LK_CMD_RESUME		0x8b	/* resume transmission to the host */
+#define LK_CMD_INHIBIT		0x89	/* stop transmission to the host */
+#define LK_CMD_LEDS_ON		0x13	/* light LEDs */
+					/* 1st param: led bitmask */
+#define LK_CMD_LEDS_OFF		0x11	/* turn off LEDs */
+					/* 1st param: led bitmask */
+#define LK_CMD_DIS_KEYCLK	0x99	/* disable the keyclick */
+#define LK_CMD_ENB_KEYCLK	0x1b	/* enable the keyclick */
+					/* 1st param: volume */
+#define LK_CMD_DIS_CTLCLK	0xb9	/* disable the Ctrl keyclick */
+#define LK_CMD_ENB_CTLCLK	0xbb	/* enable the Ctrl keyclick */
+#define LK_CMD_SOUND_CLK	0x9f	/* emit a keyclick */
+#define LK_CMD_DIS_BELL		0xa1	/* disable the bell */
+#define LK_CMD_ENB_BELL		0x23	/* enable the bell */
+					/* 1st param: volume */
+#define LK_CMD_BELL		0xa7	/* emit a bell */
+#define LK_CMD_TMP_NORPT	0xc1	/* disable typematic */
+					/* for the currently pressed key */
+#define LK_CMD_ENB_RPT		0xe3	/* enable typematic */
+					/* for RPT_DOWN groups */
+#define LK_CMD_DIS_RPT		0xe1	/* disable typematic */
+					/* for RPT_DOWN groups */
+#define LK_CMD_RPT_TO_DOWN	0xd9	/* set RPT_DOWN groups to DOWN */
+#define LK_CMD_REQ_ID		0xab	/* request the keyboard ID */
+#define LK_CMD_POWER_UP		0xfd	/* init power-up sequence */
+#define LK_CMD_TEST_MODE	0xcb	/* enter the factory test mode */
+#define LK_CMD_TEST_EXIT	0x80	/* exit the factory test mode */
+#define LK_CMD_SET_DEFAULTS	0xd3	/* set power-up defaults */
+
+#define LK_CMD_MODE(m,div)	(LK_PARAM|(((div)&0xf)<<3)|m)
+					/* select the repeat mode */
+					/* for the selected key group */
+#define LK_CMD_MODE_AR(m,div)	((((div)&0xf)<<3)|m)
+					/* select the repeat mode */
+					/* and the repeat register */
+					/* for the selected key group */
+					/* 1st param: register number */
+#define LK_CMD_RPT_RATE(r)	(0x04|((((r)&0x3)<<1)))
+					/* set the delay and repeat rate */
+					/* for the selected repeat register */
+					/* 1st param: initial delay */
+					/* 2nd param: repeat rate */
 
 /* there are 4 leds, represent them in the low 4 bits of a byte */
-#define	LK_PARAM_LED_MASK(ledbmap)	(LK_PARAM|(ledbmap))
+#define LK_PARAM_LED_MASK(ledbmap)	(LK_PARAM|((ledbmap)&0xf))
+#define LK_LED_WAIT		0x1	/* Wait LED */
+#define LK_LED_COMP		0x2	/* Compose LED */
+#define LK_LED_LOCK		0x4	/* Lock LED */
+#define LK_LED_HOLD		0x8	/* Hold Screen LED */
 
 /* max volume is 0, lowest is 0x7 */
-#define	LK_PARAM_VOLUME(v)		(LK_PARAM|((v)&0x7))
+#define LK_PARAM_VOLUME(v)		(LK_PARAM|((v)&0x7))
 
-/* mode set command(s) details */
-#define	LK_MODE_DOWN		0x0
-#define	LK_MODE_RPT_DOWN	0x2
-#define	LK_MODE_DOWN_UP		0x6
-#define	LK_CMD_MODE(m,div)	(LK_PARAM|(div<<3)|m)
+/* mode set command details, div is a key group number */
+#define LK_MODE_DOWN		0x0	/* make only */
+#define LK_MODE_RPT_DOWN	0x2	/* make and typematic */
+#define LK_MODE_DOWN_UP		0x6	/* make and release */
+
+/* there are 4 repeat registers */
+#define LK_PARAM_AR(r)		(LK_PARAM|((v)&0x3))
+
+/*
+ * Mappings between key groups and keycodes are as follows:
+ *
+ *  1: 0xbf - 0xfb -- alphanumeric,
+ *  2: 0x92 - 0xa4 -- numeric keypad,
+ *  3: 0xbc        -- Backspace,
+ *  4: 0xbd - 0xbe -- Tab, Return,
+ *  5: 0xb0 - 0xb1 -- Lock, Compose Character,
+ *  6: 0xae - 0xaf -- Ctrl, Shift,
+ *  7: 0xa7 - 0xa8 -- Left Arrow, Right Arrow,
+ *  8: 0xa9 - 0xab -- Up Arrow, Down Arrow, Right Shift,
+ *  9: 0x8a - 0x8f -- editor keypad,
+ * 10: 0x56 - 0x5a -- F1 - F5,
+ * 11: 0x64 - 0x68 -- F6 - F10,
+ * 12: 0x71 - 0x74 -- F11 - F14,
+ * 13: 0x7c - 0x7d -- Help, Do,
+ * 14: 0x80 - 0x83 -- F17 - F20.
+ *
+ * Others, i.e. 0x55, 0xac, 0xad, 0xb2, are undiscovered.
+ */
+
+/* delay is 5 - 630 ms; 0x00 and 0x7f are reserved */
+#define LK_PARAM_DELAY(t)	((t)&0x7f)
+
+/* rate is 12 - 127 Hz; 0x00 - 0x0b and 0x7d (power-up!) are reserved */
+#define LK_PARAM_RATE(r)	(LK_PARAM|((r)&0x7f))
 
 #define LK_SHIFT 1<<0
 #define LK_CTRL 1<<1
 #define LK_LOCK 1<<2
 #define LK_COMP 1<<3
 
-#define LK_KEY_SHIFT 174
-#define LK_KEY_CTRL 175
-#define LK_KEY_LOCK 176
-#define LK_KEY_COMP 177
-#define LK_KEY_RELEASE 179
-#define LK_KEY_REPEAT 180
-#define LK_KEY_ACK 186
+#define LK_KEY_SHIFT		0xae
+#define LK_KEY_CTRL		0xaf
+#define LK_KEY_LOCK		0xb0
+#define LK_KEY_COMP		0xb1
+
+#define LK_KEY_RELEASE		0xb3	/* all keys released */
+#define LK_KEY_REPEAT		0xb4	/* repeat the last key */
+
+/* status responses */
+#define LK_STAT_RESUME_ERR	0xb5	/* keystrokes lost while inhibited */
+#define LK_STAT_ERROR		0xb6	/* an invalid command received */
+#define LK_STAT_INHIBIT_ACK	0xb7	/* transmission inhibited */
+#define LK_STAT_TEST_ACK	0xb8	/* the factory test mode entered */
+#define LK_STAT_MODE_KEYDOWN	0xb9	/* a key is down on a change */
+					/* to the DOWN_UP mode; */
+					/* the keycode follows */
+#define LK_STAT_MODE_ACK	0xba	/* the mode command succeeded */
+
+#define LK_STAT_PWRUP_OK	0x00	/* the power-up self test OK */
+#define LK_STAT_PWRUP_KDOWN	0x3d	/* a key was down during the test */
+#define LK_STAT_PWRUP_ERROR	0x3e	/* keyboard self test failure */
 
-extern unsigned char scancodeRemap[256];
\ No newline at end of file
+extern unsigned char scancodeRemap[256];
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/tc/zs.c linux/drivers/tc/zs.c
--- linux.orig/drivers/tc/zs.c	2001-08-27 15:56:31.000000000 +0000
+++ linux/drivers/tc/zs.c	2002-07-20 01:08:30.000000000 +0000
@@ -1473,7 +1473,7 @@
 		schedule_timeout(char_time);
 		if (signal_pending(current))
 			break;
-		if (timeout && ((orig_jiffies + timeout) < jiffies))
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
 			break;
 	}
 	current->state = TASK_RUNNING;
@@ -1925,9 +1925,9 @@
 	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
 	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register serial driver\n");
+		panic("Couldn't register serial driver");
 	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
+		panic("Couldn't register callout driver");
 
 	save_flags(flags); cli();
 
@@ -2125,18 +2125,6 @@
 	}
 }
 
-/*
- *	Receive character from the serial port
- */
-static int serial_console_wait_key(struct console *co)
-{
-	struct dec_serial *info;
-
-        info = zs_soft + co->index;
-
-        return zs_poll_rx_char(info);
-}
-
 static kdev_t serial_console_device(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
@@ -2271,7 +2259,6 @@
 	name:		"ttyS",
 	write:		serial_console_write,
 	device:		serial_console_device,
-	wait_key:	serial_console_wait_key,
 	setup:		serial_console_setup,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/telephony/Config.in linux/drivers/telephony/Config.in
--- linux.orig/drivers/telephony/Config.in	2001-09-07 16:28:37.000000000 +0000
+++ linux/drivers/telephony/Config.in	2002-07-20 01:08:25.000000000 +0000
@@ -6,5 +6,5 @@
 
 tristate 'Linux telephony support' CONFIG_PHONE
 dep_tristate 'QuickNet Internet LineJack/PhoneJack support' CONFIG_PHONE_IXJ $CONFIG_PHONE
-dep_tristate 'QuickNet Internet LineJack/PhoneJack PCMCIA support' CONFIG_PHONE_IXJ_PCMCIA $CONFIG_PHONE_IXJ
+dep_tristate 'QuickNet Internet LineJack/PhoneJack PCMCIA support' CONFIG_PHONE_IXJ_PCMCIA $CONFIG_PHONE_IXJ $CONFIG_PCMCIA
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/telephony/ixj.c linux/drivers/telephony/ixj.c
--- linux.orig/drivers/telephony/ixj.c	2001-10-25 20:53:52.000000000 +0000
+++ linux/drivers/telephony/ixj.c	2002-07-20 01:08:23.000000000 +0000
@@ -387,7 +387,7 @@
 #ifdef PERFMON_STATS
 #define ixj_perfmon(x)	((x)++)
 #else
-#define ixj_perfmon(x)	do {} while(0);
+#define ixj_perfmon(x)	do { } while(0)
 #endif
 
 static int ixj_convert_loaded;
@@ -3451,7 +3451,7 @@
 	j->cidcw_wait = 0;
 	if(!j->flags.cidcw_ack) {
 		if(ixjdebug & 0x0200) {
-			printk("IXJ cidcw phone%d did not recieve ACK from display %ld\n", j->board, jiffies);
+			printk("IXJ cidcw phone%d did not receive ACK from display %ld\n", j->board, jiffies);
 		}
 		ixj_post_cid(j);
 		if(j->cid_play_flag) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/CDCEther.c linux/drivers/usb/CDCEther.c
--- linux.orig/drivers/usb/CDCEther.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/usb/CDCEther.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,4 +1,4 @@
-// Portions of this file taken from 
+// Portions of this file taken from
 // Petko Manolov - Petkan (petkan@dce.bg)
 // from his driver pegasus.c
 
@@ -25,20 +25,27 @@
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/usb.h>
 #include <linux/module.h>
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
+
+#define DEBUG
+#include <linux/usb.h>
+
 #include "CDCEther.h"
 
-static const char *version = __FILE__ ": v0.98.5 22 Sep 2001 Brad Hards and another";
+#define SHORT_DRIVER_DESC "CDC Ethernet Class"
+#define DRIVER_VERSION "0.98.6"
 
-/* Take any CDC device, and sort it out in probe() */
+static const char *version = __FILE__ ": " DRIVER_VERSION " 7 Jan 2002 Brad Hards and another";
+// We only try to claim CDC Ethernet model devices */
 static struct usb_device_id CDCEther_ids[] = {
-	{ USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
-	{ } /* Terminating null entry */
+	{ USB_INTERFACE_INFO(USB_CLASS_COMM, 6, 0) },
+	{ }
 };
 
-/* 
- * module parameter that provides an alternate upper limit on the 
+/*
+ * module parameter that provides an alternate upper limit on the
  * number of multicast filters we use, with a default to use all
  * the filters available to us. Note that the actual number used
  * is the lesser of this parameter and the number returned in the
@@ -47,7 +54,6 @@
  */
 static int multicast_filter_limit = 32767;
 
-
 //////////////////////////////////////////////////////////////////////////////
 // Callback routines from USB device /////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
@@ -59,7 +65,16 @@
 	int count = urb->actual_length, res;
 	struct sk_buff	*skb;
 
-	// Sanity check 
+	switch ( urb->status ) {
+		case USB_ST_NOERROR:
+			break;
+		case USB_ST_URB_KILLED:
+			return;
+		default:
+			dbg("rx status %d", urb->status);
+	}
+
+	// Sanity check
 	if ( !ether_dev || !(ether_dev->flags & CDC_ETHER_RUNNING) ) {
 		dbg("BULK IN callback but driver is not active!");
 		return;
@@ -133,7 +148,7 @@
 	// Give this to the USB subsystem so it can tell us 
 	// when more data arrives.
 	if ( (res = usb_submit_urb(&ether_dev->rx_urb)) ) {
-		warn( __FUNCTION__ " failed submint rx_urb %d", res);
+		warn( __FUNCTION__ " failed submit rx_urb %d", res);
 	}
 	
 	// We are no longer busy, show us the frames!!!
@@ -160,47 +175,69 @@
 
 	// Hmm...  What on Earth could have happened???
 	if ( urb->status ) {
-		info("%s: TX status %d", ether_dev->net->name, urb->status);
+		dbg("%s: TX status %d", ether_dev->net->name, urb->status);
 	}
 
 	// Update the network interface and tell it we are
 	// ready for another frame
 	ether_dev->net->trans_start = jiffies;
 	netif_wake_queue( ether_dev->net );
+
 }
 
-//static void intr_callback( struct urb *urb )
-//{
-//	ether_dev_t *ether_dev = urb->context;
-//	struct net_device *net;
-//	__u8	*d;
-//
-//	if ( !ether_dev )
-//		return;
-//		
-//	switch ( urb->status ) {
-//		case USB_ST_NOERROR:
-//			break;
-//		case USB_ST_URB_KILLED:
-//			return;
-//		default:
-//			info("intr status %d", urb->status);
-//	}
-//
-//	d = urb->transfer_buffer;
-//	net = ether_dev->net;
-//	if ( d[0] & 0xfc ) {
-//		ether_dev->stats.tx_errors++;
-//		if ( d[0] & TX_UNDERRUN )
-//			ether_dev->stats.tx_fifo_errors++;
-//		if ( d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT) )
-//			ether_dev->stats.tx_aborted_errors++;
-//		if ( d[0] & LATE_COL )
-//			ether_dev->stats.tx_window_errors++;
-//		if ( d[0] & (NO_CARRIER | LOSS_CARRIER) )
-//			ether_dev->stats.tx_carrier_errors++;
-//	}
-//}
+#if 0
+static void setpktfilter_done( struct urb *urb )
+{
+	ether_dev_t *ether_dev = urb->context;
+	struct net_device *net;
+
+	if ( !ether_dev )
+		return;
+	dbg("got ctrl callback for setting packet filter");
+	switch ( urb->status ) {
+		case USB_ST_NOERROR:
+			break;
+		case USB_ST_URB_KILLED:
+			return;
+		default:
+			dbg("intr status %d", urb->status);
+	}
+}
+#endif 
+
+static void intr_callback( struct urb *urb )
+{
+	ether_dev_t *ether_dev = urb->context;
+	struct net_device *net;
+	__u8	*d;
+
+	if ( !ether_dev )
+		return;
+	dbg("got intr callback");
+	switch ( urb->status ) {
+		case USB_ST_NOERROR:
+			break;
+		case USB_ST_URB_KILLED:
+			return;
+		default:
+			dbg("intr status %d", urb->status);
+	}
+
+	d = urb->transfer_buffer;
+	dbg("d: %x", d[0]);
+	net = ether_dev->net;
+	if ( d[0] & 0xfc ) {
+		ether_dev->stats.tx_errors++;
+		if ( d[0] & TX_UNDERRUN )
+			ether_dev->stats.tx_fifo_errors++;
+		if ( d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT) )
+			ether_dev->stats.tx_aborted_errors++;
+		if ( d[0] & LATE_COL )
+			ether_dev->stats.tx_window_errors++;
+		if ( d[0] & (NO_CARRIER | LOSS_CARRIER) )
+			netif_carrier_off(net);
+	}
+}
 
 //////////////////////////////////////////////////////////////////////////////
 // Routines for turning net traffic on and off on the USB side ///////////////
@@ -213,8 +250,8 @@
 	// Here would be the time to set the data interface to the configuration where
 	// it has two endpoints that use a protocol we can understand.
 
-	if (usb_set_interface( usb, 
-	                        ether_dev->data_bInterfaceNumber, 
+	if (usb_set_interface( usb,
+	                        ether_dev->data_bInterfaceNumber,
 	                        ether_dev->data_bAlternateSetting_with_traffic ) )  {
 		err("usb_set_interface() failed" );
 		err("Attempted to set interface %d", ether_dev->data_bInterfaceNumber);
@@ -230,8 +267,8 @@
 	// no endpoints.  This is what the spec suggests.
 
 	if (ether_dev->data_interface_altset_num_without_traffic >= 0 ) {
-		if (usb_set_interface( ether_dev->usb, 
-		                        ether_dev->data_bInterfaceNumber, 
+		if (usb_set_interface( ether_dev->usb,
+		                        ether_dev->data_bInterfaceNumber,
 		                        ether_dev->data_bAlternateSetting_without_traffic ) ) 	{
 			err("usb_set_interface() failed");
 		}
@@ -326,6 +363,9 @@
 	return 0;
 }
 
+//////////////////////////////////////////////////////////////////////////////
+// Standard routines for kernel Ethernet Device //////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
 static struct net_device_stats *CDCEther_netdev_stats( struct net_device *net )
 {
 	// Easy enough!
@@ -343,19 +383,33 @@
 		return -EIO;
 	}
 
-	// Prep a receive URB
+	/* Prep a receive URB */
 	FILL_BULK_URB( &ether_dev->rx_urb, ether_dev->usb,
 			usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in),
-			ether_dev->rx_buff, ether_dev->wMaxSegmentSize, 
+			ether_dev->rx_buff, ether_dev->wMaxSegmentSize,
 			read_bulk_callback, ether_dev );
 
-	// Put it out there so the device can send us stuff
-	if ( (res = usb_submit_urb(&ether_dev->rx_urb)) )
-	{
-		// Hmm...  Okay...
+	/* Put it out there so the device can send us stuff */
+	if ( (res = usb_submit_urb(&ether_dev->rx_urb)) ) {
+		/* Hmm...  Okay... */
 		warn( __FUNCTION__ " failed rx_urb %d", res );
 	}
 
+	if (ether_dev->properties & HAVE_NOTIFICATION_ELEMENT) {
+		/* Arm and submit the interrupt URB */
+		FILL_INT_URB( &ether_dev->intr_urb,
+			ether_dev->usb,
+			usb_rcvintpipe(ether_dev->usb, ether_dev->comm_ep_in),
+			ether_dev->intr_buff,
+			8, /* Transfer buffer length */
+			intr_callback,
+			ether_dev,
+			ether_dev->intr_interval);
+		if ( (res = usb_submit_urb(&ether_dev->intr_urb)) ) {
+			warn( __FUNCTION__ " failed intr_urb %d", res );
+		}
+	}
+
 	// Tell the kernel we are ready to start receiving from it
 	netif_start_queue( net );
 	
@@ -386,92 +440,133 @@
 	usb_unlink_urb( &ether_dev->rx_urb );
 	usb_unlink_urb( &ether_dev->tx_urb );
 	usb_unlink_urb( &ether_dev->intr_urb );
-	
+	usb_unlink_urb( &ether_dev->ctrl_urb );
+
 	// That's it.  I'm done.
 	return 0;
 }
 
-static int CDCEther_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
+static int netdev_ethtool_ioctl(struct net_device *netdev, void *useraddr)
 {
-	//__u16 *data = (__u16 *)&rq->ifr_data;
-	//ether_dev_t	*ether_dev = net->priv;
+	ether_dev_t *ether_dev = netdev->priv;
+	u32 cmd;
+	char tmp[40];
+
+	if (get_user(cmd, (u32 *)useraddr))
+		return -EFAULT;
+
+	switch (cmd) {
+	/* get driver info */
+	case ETHTOOL_GDRVINFO: {
+	struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strncpy(info.driver, SHORT_DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
+		strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
+		sprintf(tmp, "usb%d:%d", ether_dev->usb->bus->busnum, ether_dev->usb->devnum);
+		strncpy(info.bus_info, tmp, ETHTOOL_BUSINFO_LEN);
+		sprintf(tmp, "CDC %x.%x", ((ether_dev->bcdCDC & 0xff00)>>8), (ether_dev->bcdCDC & 0x00ff) );
+		strncpy(info.fw_version, tmp, ETHTOOL_BUSINFO_LEN);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	/* get link status */
+	case ETHTOOL_GLINK: {
+		struct ethtool_value edata = {ETHTOOL_GLINK};
+		edata.data = netif_carrier_ok(netdev);
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	}
+	dbg("Got unsupported ioctl: %x", cmd);
+	return -EOPNOTSUPP; /* the ethtool user space tool relies on this */
+}
 
-	// No support here yet.
-	// Do we need support???
+static int CDCEther_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
+{
 	switch(cmd) {
-		case SIOCDEVPRIVATE:
-			return -EOPNOTSUPP;
-		case SIOCDEVPRIVATE+1:
-			return -EOPNOTSUPP;
-		case SIOCDEVPRIVATE+2:
-			//return 0;
-			return -EOPNOTSUPP;
-		default:
-			return -EOPNOTSUPP;
+	case SIOCETHTOOL:
+		return netdev_ethtool_ioctl(net, (void *) rq->ifr_data);
+	default:
+		return -ENOTTY; /* per ioctl man page */
 	}
 }
 
+/* Multicast routines */
+
 static void CDC_SetEthernetPacketFilter (ether_dev_t *ether_dev)
 {
-	usb_control_msg(ether_dev->usb,
+#if 0
+	devrequest *dr = &ether_dev->ctrl_dr;
+	int res;
+
+	dr->requesttype = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE;
+	dr->request = SET_ETHERNET_PACKET_FILTER;
+	dr->value = cpu_to_le16(ether_dev->mode_flags);
+	dr->index = cpu_to_le16((u16)ether_dev->comm_interface);
+	dr->length = 0;
+
+	FILL_CONTROL_URB(&ether_dev->ctrl_urb,
+			ether_dev->usb,
 			usb_sndctrlpipe(ether_dev->usb, 0),
-			SET_ETHERNET_PACKET_FILTER, /* request */
-			USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, /* request type */
-			cpu_to_le16(ether_dev->mode_flags), /* value */
-			cpu_to_le16((u16)ether_dev->comm_interface), /* index */
+			dr,
+			NULL,
 			NULL,
-			0, /* size */
-			HZ); /* timeout */
-}	
+			setpktfilter_done,
+			ether_dev);
+	if ( (res = usb_submit_urb(&ether_dev->ctrl_urb)) ) {
+		warn( __FUNCTION__ " failed submit ctrl_urb %d", res);
+	}
+#endif
 
+}
 
 static void CDCEther_set_multicast( struct net_device *net )
 {
 	ether_dev_t *ether_dev = net->priv;
 	int i;
 	__u8 *buff;
-	
 
 	// Tell the kernel to stop sending us frames while we get this
 	// all set up.
 	netif_stop_queue(net);
 
-      /* Note: do not reorder, GCC is clever about common statements. */
-        if (net->flags & IFF_PROMISC) {
-                /* Unconditionally log net taps. */
-                info( "%s: Promiscuous mode enabled", net->name);
+	/* Note: do not reorder, GCC is clever about common statements. */
+	if (net->flags & IFF_PROMISC) {
+		/* Unconditionally log net taps. */
+		dbg( "%s: Promiscuous mode enabled", net->name);
 		ether_dev->mode_flags = MODE_FLAG_PROMISCUOUS |
 			MODE_FLAG_ALL_MULTICAST |
 			MODE_FLAG_DIRECTED |
 			MODE_FLAG_BROADCAST |
 			MODE_FLAG_MULTICAST;
-        } else if (net->mc_count > ether_dev->wNumberMCFilters) {
-                /* Too many to filter perfectly -- accept all multicasts. */
-		info("%s: set too many MC filters, using allmulti", net->name);
+	} else if (net->mc_count > ether_dev->wNumberMCFilters) {
+		/* Too many to filter perfectly -- accept all multicasts. */
+		dbg("%s: too many MC filters for hardware, using allmulti", net->name);
 		ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST |
 			MODE_FLAG_DIRECTED |
 			MODE_FLAG_BROADCAST |
 			MODE_FLAG_MULTICAST;
 	} else if (net->flags & IFF_ALLMULTI) {
-                /* Filter in software */
-		info("%s: using allmulti", net->name);
+		/* Filter in software */
+		dbg("%s: using allmulti", net->name);
 		ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST |
 			MODE_FLAG_DIRECTED |
 			MODE_FLAG_BROADCAST |
 			MODE_FLAG_MULTICAST;
-        } else {
+	} else {
 		/* do multicast filtering in hardware */
-                struct dev_mc_list *mclist;
-		info("%s: set multicast filters", net->name);
+		struct dev_mc_list *mclist;
+		dbg("%s: set multicast filters", net->name);
 		ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST |
 			MODE_FLAG_DIRECTED |
 			MODE_FLAG_BROADCAST |
 			MODE_FLAG_MULTICAST;
 		buff = kmalloc(6 * net->mc_count, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
-                for (i = 0, mclist = net->mc_list;
-		     mclist && i < net->mc_count;
-                     i++, mclist = mclist->next) {
-			memcpy(&mclist->dmi_addr, &buff[i * 6], 6);
+		for (i = 0, mclist = net->mc_list;
+			mclist && i < net->mc_count;
+			i++, mclist = mclist->next) {
+				memcpy(&mclist->dmi_addr, &buff[i * 6], 6);
 		}
 #if 0
 		usb_control_msg(ether_dev->usb,
@@ -487,10 +582,9 @@
 		kfree(buff);
 	}
 
-#if 0 
 	CDC_SetEthernetPacketFilter(ether_dev);
-#endif	
-        // Tell the kernel to start giving frames to us again.
+
+	/* Tell the kernel to start giving frames to us again. */
 	netif_wake_queue(net);
 }
 
@@ -498,40 +592,42 @@
 // Routines used to parse out the Functional Descriptors /////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-static int parse_header_functional_descriptor( int *bFunctionLength, 
-                                               int bDescriptorType, 
+/* Header Descriptor - CDC Spec 5.2.3.1, Table 26 */
+static int parse_header_functional_descriptor( int *bFunctionLength,
+                                               int bDescriptorType,
                                                int bDescriptorSubtype,
                                                unsigned char *data,
                                                ether_dev_t *ether_dev,
                                                int *requirements )
 {
-	// Check to make sure we haven't seen one of these already.
+	/* Check to make sure we haven't seen one of these already. */
 	if ( (~*requirements) & REQ_HDR_FUNC_DESCR ) {
 		err( "Multiple Header Functional Descriptors found." );
 		return -1;
 	}
-	
-	// Is it the right size???
-	if (*bFunctionLength != 5) {
-		info( "Invalid length in Header Functional Descriptor" );
-		// This is a hack to get around a particular device (NO NAMES)
-		// It has this function length set to the length of the
-		// whole class-specific descriptor
-		*bFunctionLength = 5;
+
+	/* Check for appropriate length */
+	if (*bFunctionLength != HEADER_FUNC_DESC_LEN) {
+		dbg( "Invalid length in Header Functional Descriptor, working around it." );
+		/* This is a hack to get around a particular device (NO NAMES)
+		 * It has this function length set to the length of the
+		 * whole class-specific descriptor */
+		*bFunctionLength = HEADER_FUNC_DESC_LEN;
 	}
 	
-	// Nothing extremely useful here.
-	// We'll keep it for posterity
+	/* Nothing extremely useful here */
+	/* We'll keep it for posterity */
 	ether_dev->bcdCDC = data[0] + (data[1] << 8);
-	dbg( "Found Header descriptor, CDC version %x", ether_dev->bcdCDC);
+	dbg( "Found Header descriptor, CDC version %x.", ether_dev->bcdCDC);
 
-	// We've seen one of these
+	/* We've seen one of these */
 	*requirements &= ~REQ_HDR_FUNC_DESCR;
-	
-	// It's all good.
+
+	/* Success */
 	return 0;
 }
 
+/* Union Descriptor - CDC Spec 5.2.3.8, Table 33 */
 static int parse_union_functional_descriptor( int *bFunctionLength, 
                                               int bDescriptorType, 
                                               int bDescriptorSubtype,
@@ -539,77 +635,89 @@
                                               ether_dev_t *ether_dev,
                                               int *requirements )
 {
-	// Check to make sure we haven't seen one of these already.
+	/* Check to make sure we haven't seen one of these already. */
 	if ( (~*requirements) & REQ_UNION_FUNC_DESCR ) {
 		err( "Multiple Union Functional Descriptors found." );
 		return -1;
 	}
 
-	// Is it the right size?
-	if (*bFunctionLength != 5) {
+	/* Check for appropriate length */
+	if (*bFunctionLength != UNION_FUNC_DESC_LEN) {
 		// It is NOT the size we expected.
-		err( "Unsupported length in Union Functional Descriptor" );
+		err( "Invalid length in Union Functional Descriptor." );
 		return -1;
 	}
 	
-	// Sanity check of sorts
+	/* Sanity check of sorts */
 	if (ether_dev->comm_interface != data[0]) {
-		// This tells us that we are chasing the wrong comm
-		// interface or we are crazy or something else weird.
+		/* This tells us that we are chasing the wrong comm
+		 * interface or we are crazy or something else weird. */
 		if (ether_dev->comm_interface == data[1]) {
-			info( "Probably broken Union descriptor, fudging data interface" );
-			// We'll need this in a few microseconds, 
-			// so guess here, and hope for the best
+			dbg( "Probably broken Union descriptor, fudging data interface." );
+			/* We'll need this in a few microseconds,
+			 * so if the comm interface was the first slave,
+			 * then probably the master interface is the data one
+			 * Just hope for the best */
 			ether_dev->data_interface = data[0];
 		} else {
-			err( "Union Functional Descriptor is broken beyond repair" );
+			err( "Union Functional Descriptor is broken beyond repair." );
 			return -1;
 		}
-	} else{ // Descriptor is OK
-       		// We'll need this in a few microseconds!
+	} else{ /* Descriptor is OK */
 		ether_dev->data_interface = data[1];
 	}
 
-	// We've seen one of these now.
+	/* We've seen one of these */
 	*requirements &= ~REQ_UNION_FUNC_DESCR;
-	
-	// Done
+
+	/* Success */
 	return 0;
 }
 
-static int parse_ethernet_functional_descriptor( int *bFunctionLength, 
+/* Ethernet Descriptor - CDC Spec 5.2.3.16, Table 41 */
+static int parse_ethernet_functional_descriptor( int *bFunctionLength,
                                                  int bDescriptorType, 
                                                  int bDescriptorSubtype,
                                                  unsigned char *data,
                                                  ether_dev_t *ether_dev,
                                                  int *requirements )
 {
-	// Check to make sure we haven't seen one of these already.
+	//* Check to make sure we haven't seen one of these already. */
 	if ( (~*requirements) & REQ_ETH_FUNC_DESCR ) {
 		err( "Multiple Ethernet Functional Descriptors found." );
 		return -1;
 	}
 	
-	// Is it the right size?
-	if (*bFunctionLength != 13) {
-		err( "Invalid length in Ethernet Networking Functional Descriptor" );
+	/* Check for appropriate length */
+	if (*bFunctionLength != ETHERNET_FUNC_DESC_LEN) {
+		err( "Invalid length in Ethernet Networking Functional Descriptor." );
 		return -1;
 	}
-	
-	// Lots of goodies from this one.  They are all important.
+
+	/* Lots of goodies from this one.  They are all important. */
 	ether_dev->iMACAddress = data[0];
 	ether_dev->bmEthernetStatistics = data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24);
 	ether_dev->wMaxSegmentSize = data[5] + (data[6] << 8);
-	ether_dev->wNumberMCFilters = (data[7] + (data[8] << 8)) & 0x00007FFF;
+	ether_dev->wNumberMCFilters = (data[7] + (data[8] << 8));
+	if (ether_dev->wNumberMCFilters & (1 << 15)) {
+		ether_dev->properties |= PERFECT_FILTERING;
+		dbg("Perfect filtering support");
+	} else {
+		dbg("Imperfect filtering support - need sw hashing");
+	}
+	if (0 == (ether_dev->wNumberMCFilters & (0x7f))) {
+		ether_dev->properties |= NO_SET_MULTICAST;
+		dbg("Can't use SetEthernetMulticastFilters request");
+	}
 	if (ether_dev->wNumberMCFilters > multicast_filter_limit) {
 		ether_dev->wNumberMCFilters = multicast_filter_limit;
-		}	
+	}
 	ether_dev->bNumberPowerFilters = data[9];
 	
-	// We've seen one of these now.
+	/* We've seen one of these */
 	*requirements &= ~REQ_ETH_FUNC_DESCR;
-	
-	// That's all she wrote.
+
+	/* Success */
 	return 0;
 }
 
@@ -620,15 +728,15 @@
                                                       ether_dev_t *ether_dev,
                                                       int *requirements )
 {
-	// There should only be one type if we are sane
+	/* There should only be one type if we are sane */
 	if (bDescriptorType != CS_INTERFACE) {
-		info( "Invalid bDescriptorType found." );
+		err( "Invalid bDescriptorType found." );
 		return -1;
 	}
 
-	// The Subtype tells the tale.
-	switch (bDescriptorSubtype){
-		case 0x00:	// Header Functional Descriptor
+	/* The Subtype tells the tale - CDC spec Table 25 */
+	switch (bDescriptorSubtype) {
+		case 0x00:	/* Header Functional Descriptor */
 			return parse_header_functional_descriptor( bFunctionLength,
 			                                           bDescriptorType,
 			                                           bDescriptorSubtype,
@@ -636,7 +744,7 @@
 			                                           ether_dev,
 			                                           requirements );
 			break;
-		case 0x06:	// Union Functional Descriptor
+		case 0x06:	/* Union Functional Descriptor */
 			return parse_union_functional_descriptor( bFunctionLength,
 			                                          bDescriptorType,
 			                                          bDescriptorSubtype,
@@ -644,7 +752,7 @@
 			                                          ether_dev,
 			                                          requirements );
 			break;
-		case 0x0F:	// Ethernet Networking Functional Descriptor
+		case 0x0F:	/* Ethernet Networking Functional Descriptor */
 			return parse_ethernet_functional_descriptor( bFunctionLength,
 			                                             bDescriptorType,
 			                                             bDescriptorSubtype,
@@ -652,12 +760,12 @@
 			                                             ether_dev,
 			                                             requirements );
 			break;
-		default:	// We don't support this at this time...
-			// However that doesn't necessarily indicate an error.
-			dbg( "Unexpected header type %x:", bDescriptorSubtype );
+		default:	/* We don't support this at this time... */
+				/* However that doesn't necessarily indicate an error. */
+			dbg( "Unexpected header type %x.", bDescriptorSubtype );
 			return 0;
 	}
-	// How did we get here???
+	/* How did we get here? */
 	return -1;
 }
 
@@ -668,46 +776,49 @@
 	int bFunctionLength;
 	int bDescriptorType;
 	int bDescriptorSubtype;
-	int requirements = REQUIREMENTS_TOTAL;
+	int requirements = REQUIREMENTS_TOTAL; /* We init to our needs, and then clear
+						* bits as we find the descriptors */
 
-	// As long as there is something here, we will try to parse it
+	/* As long as there is something here, we will try to parse it */
+	/* All of the functional descriptors start with the same 3 byte pattern */
 	while (loc < length) {
-		// Length
+		/* Length */
 		bFunctionLength = data[loc];
 		loc++;
-		
-		// Type
+
+		/* Type */
 		bDescriptorType = data[loc];
 		loc++;
-		
-		// Subtype
+
+		/* Subtype */
 		bDescriptorSubtype = data[loc];
 		loc++;
 		
-		// ship this off to be processed elsewhere.
+		/* ship this off to be processed */
 		rc = parse_protocol_unit_functional_descriptor( &bFunctionLength, 
 		                                                bDescriptorType, 
 		                                                bDescriptorSubtype, 
 		                                                &data[loc],
 		                                                ether_dev,
 		                                                &requirements );
-		// Did it process okay?
+		/* Did it process okay? */
 		if (rc)	{
-			// Something was hosed somewhere.
-			// No need to continue;
+			/* Something was hosed somewhere. */
+			/*  No need to continue */
 			err("Bad descriptor parsing: %x", rc );
 			return -1;
 		}
-		// We have already taken three bytes.
+		/* We move the loc pointer along, remembering
+		 * that we have already taken three bytes */
 		loc += (bFunctionLength - 3);
 	}
-	// Check to see if we got everything we need.
+	/* Check to see if we got everything we need. */
 	if (requirements) {
 		// We missed some of the requirements...
-		err( "Not all required functional descriptors present 0x%08X", requirements );
+		err( "Not all required functional descriptors present 0x%08X.", requirements );
 		return -1;
 	}
-	// We got everything.
+	/* We got everything */
 	return 0;
 }
 
@@ -721,28 +832,28 @@
 	struct usb_interface *comm_intf_group = NULL;
 	struct usb_interface_descriptor *comm_intf = NULL;
 	int rc = -1;
-	// The assumption here is that find_ethernet_comm_interface
-	// and find_valid_configuration 
-	// have already filled in the information about where to find
-	// the a valid commication interface.
+	/* The assumption here is that find_ethernet_comm_interface
+	 * and find_valid_configuration
+	 * have already filled in the information about where to find
+	 * the a valid commication interface. */
 
 	conf = &( device->config[ether_dev->configuration_num] );
 	comm_intf_group = &( conf->interface[ether_dev->comm_interface] );
 	comm_intf = &( comm_intf_group->altsetting[ether_dev->comm_interface_altset_num] );
-	// Let's check and see if it has the extra information we need...
 
+	/* Let's check and see if it has the extra information we need */
 	if (comm_intf->extralen > 0) {
-		// This is where the information is SUPPOSED to be.
+		/* This is where the information is SUPPOSED to be */
 		rc = parse_ethernet_class_information( comm_intf->extra, comm_intf->extralen, ether_dev );
 	} else if (conf->extralen > 0) {
-		// This is a hack.  The spec says it should be at the interface 
-		// location checked above.  However I have seen it here also.
-		// This is the same device that requires the functional descriptor hack above
-		warn( "Ethernet information found at device configuration.  This is broken." );
+		/* This is a hack.  The spec says it should be at the interface
+		 * location checked above.  However I have seen it here also.
+		 * This is the same device that requires the functional descriptor hack above */
+		dbg( "Ethernet information found at device configuration.  Trying to use it anyway." );
 		rc = parse_ethernet_class_information( conf->extra, conf->extralen, ether_dev );
 	} else 	{
-		// I don't know where else to look.
-		warn( "No ethernet information found." );
+		/* I don't know where else to look */
+		err( "No ethernet information found." );
 		rc = -1;
 	}
 	return rc;
@@ -757,47 +868,43 @@
 	struct usb_config_descriptor *conf = NULL;
 	struct usb_interface *data_intf_group = NULL;
 	struct usb_interface_descriptor *data_intf = NULL;
-	
-	// Walk through and get to the data interface we are checking.
+
+	/* Walk through and get to the data interface we are checking. */
 	conf = &( device->config[ether_dev->configuration_num] );
 	data_intf_group = &( conf->interface[ether_dev->data_interface] );
 	data_intf = &( data_intf_group->altsetting[ether_dev->data_interface_altset_num_with_traffic] );
 
-	// Start out assuming we won't find anything we can use
+	/* Start out assuming we won't find anything we can use */
 	ether_dev->data_ep_in = 0;
 	ether_dev->data_ep_out = 0;
-	
-	// If these are not BULK endpoints, we don't want them
-	if ( data_intf->endpoint[0].bmAttributes != 0x02 ) {
+
+	/* If these are not BULK endpoints, we don't want them */
+	if ( data_intf->endpoint[0].bmAttributes != USB_ENDPOINT_XFER_BULK ) {
 		return -1;
-	} if ( data_intf->endpoint[1].bmAttributes != 0x02 ) {
+	}
+	if ( data_intf->endpoint[1].bmAttributes != USB_ENDPOINT_XFER_BULK ) {
 		return -1;
 	}
 
-	// Check the first endpoint to see if it is IN or OUT
-	if ( data_intf->endpoint[0].bEndpointAddress & 0x80 ) {
-		// This endpoint is IN
+	/* Check the first endpoint to see if it is IN or OUT */
+	if ( data_intf->endpoint[0].bEndpointAddress & USB_DIR_IN ) {
 		ether_dev->data_ep_in = data_intf->endpoint[0].bEndpointAddress & 0x7F;
 	} else {
-		// This endpoint is OUT
-		ether_dev->data_ep_out = data_intf->endpoint[0].bEndpointAddress & 0x7F;
+		ether_dev->data_ep_out = data_intf->endpoint[0].bEndpointAddress;
 		ether_dev->data_ep_out_size = data_intf->endpoint[0].wMaxPacketSize;
 	}
 
-	// Check the second endpoint to see if it is IN or OUT
-	if ( data_intf->endpoint[1].bEndpointAddress & 0x80 ) {
-		// This endpoint is IN
+	/* Check the second endpoint to see if it is IN or OUT */
+	if ( data_intf->endpoint[1].bEndpointAddress & USB_DIR_IN ) {
 		ether_dev->data_ep_in = data_intf->endpoint[1].bEndpointAddress & 0x7F;
 	} else	{
-		// This endpoint is OUT
-		ether_dev->data_ep_out = data_intf->endpoint[1].bEndpointAddress & 0x7F;
+		ether_dev->data_ep_out = data_intf->endpoint[1].bEndpointAddress;
 		ether_dev->data_ep_out_size = data_intf->endpoint[1].wMaxPacketSize;
 	}
-	
-	// Now make sure we got both an IN and an OUT
+
+	/* Now make sure we got both an IN and an OUT */
 	if (ether_dev->data_ep_in && ether_dev->data_ep_out) {
-		// We did get both, we are in good shape...
-		info( "detected BULK OUT packets of size %d", ether_dev->data_ep_out_size );
+		dbg( "detected BULK OUT packets of size %d", ether_dev->data_ep_out_size );
 		return 0;
 	}
 	return -1;
@@ -887,45 +994,45 @@
 		for ( altset_num = 0; altset_num < comm_intf_group->num_altsetting; altset_num++ ) {
 			comm_intf = &( comm_intf_group->altsetting[altset_num] );
 
-			// Is this a communication class of interface of the
-			// ethernet subclass variety.
-			if ( ( comm_intf->bInterfaceClass == 0x02 )
-			   && ( comm_intf->bInterfaceSubClass == 0x06 )
-			   && ( comm_intf->bInterfaceProtocol == 0x00 ) ) {
-				if ( comm_intf->bNumEndpoints == 1 ) {
-					// Good, we found one, we will try this one
-					// Fill in the structure...
-					ether_dev->comm_interface = intf_num;
-					ether_dev->comm_bInterfaceNumber = comm_intf->bInterfaceNumber;
-					ether_dev->comm_interface_altset_num = altset_num;
-					ether_dev->comm_bAlternateSetting = comm_intf->bAlternateSetting;
-
-					// Look for the Ethernet Functional Descriptors
-					rc = find_and_parse_ethernet_class_information( device, ether_dev );
-					if (rc) {
-						// Nope this was no good after all.
-						continue;
-					}
-
-					// Check that we really can talk to the data
-					// interface 
-					// This includes # of endpoints, protocols,
-					// etc.
-					rc = verify_ethernet_data_interface( device, ether_dev );
-					if (rc)	{
-						// We got something we didn't like
-						continue;
-					}
-					// This communication interface seems to give us everything
-					// we require.  We have all the ethernet info we need.
-					// Let's get out of here and go home right now.
-					return 0;
-				} else {
-                                        // bNumEndPoints != 1
-					// We found an interface that had the wrong number of 
-					// endpoints but would have otherwise been okay
-				} // end bNumEndpoints check.
-			} // end interface specifics check.
+			/* Good, we found one, we will try this one */
+			/* Fill in the structure */
+			ether_dev->comm_interface = intf_num;
+			ether_dev->comm_bInterfaceNumber = comm_intf->bInterfaceNumber;
+			ether_dev->comm_interface_altset_num = altset_num;
+			ether_dev->comm_bAlternateSetting = comm_intf->bAlternateSetting;
+
+			// Look for the Ethernet Functional Descriptors
+			rc = find_and_parse_ethernet_class_information( device, ether_dev );
+			if (rc) {
+				// Nope this was no good after all.
+				continue;
+			}
+
+			/* Check that we really can talk to the data interface
+			 * This includes # of endpoints, protocols, etc. */
+			rc = verify_ethernet_data_interface( device, ether_dev );
+			if (rc)	{
+				/* We got something we didn't like */
+				continue;
+			}
+			/* It is a bit ambiguous whether the Ethernet model really requires
+			 * the notification element (usually an interrupt endpoint) or not
+			 * And some products (eg Sharp Zaurus) don't support it, so we
+			 * only use the notification element if present */
+			/* We check for a sane endpoint before using it */
+			if ( (comm_intf->bNumEndpoints == 1) &&
+				(comm_intf->endpoint[0].bEndpointAddress & USB_DIR_IN) &&
+				(comm_intf->endpoint[0].bmAttributes == USB_ENDPOINT_XFER_INT)) {
+					ether_dev->properties |= HAVE_NOTIFICATION_ELEMENT;
+					ether_dev->comm_ep_in = (comm_intf->endpoint[0].bEndpointAddress & 0x7F);
+					dbg("interrupt address: %x",ether_dev->comm_ep_in);
+					ether_dev->intr_interval = (comm_intf->endpoint[0].bInterval);
+					dbg("interrupt interval: %d",ether_dev->intr_interval);
+			}
+			// This communication interface seems to give us everything
+			// we require.  We have all the ethernet info we need.
+
+			return 0;
 		} // end for altset_num
 	} // end for intf_num
 	return -1;
@@ -1005,8 +1112,8 @@
 
 static inline unsigned char hex2dec( unsigned char digit )
 {
-	// Is there a standard way to do this???
-	// I have written this code TOO MANY times.
+	/* Is there a standard way to do this??? */
+	/* I have written this code TOO MANY times. */
 	if ( (digit >= '0') && (digit <= '9') )	{
 		return (digit - '0');
 	}
@@ -1016,9 +1123,14 @@
 	if ( (digit >= 'A') && (digit <= 'F') )	{
 		return (digit - 'A' + 10);
 	}
-	return 0;
+	return 16;
 }
 
+/* CDC Ethernet devices provide the MAC address as a string */
+/* We get an index to the string in the Ethernet functional header */
+/* This routine retrieves the string, sanity checks it, and sets the */
+/* MAC address in the network device */
+/* The encoding is a bit wacky - see CDC Spec Table 41 for details */
 static void set_ethernet_addr( ether_dev_t *ether_dev )
 {
 	unsigned char	mac_addr[6];
@@ -1026,7 +1138,7 @@
 	int 		len;
 	unsigned char	buffer[13];
 
-	// Let's assume we don't get anything...
+	/* Let's assume we don't get anything */
 	mac_addr[0] = 0x00;
 	mac_addr[1] = 0x00;
 	mac_addr[2] = 0x00;
@@ -1034,22 +1146,30 @@
 	mac_addr[4] = 0x00;
 	mac_addr[5] = 0x00;
 
-	// Let's ask the device...
-	len = usb_string(ether_dev->usb, ether_dev->iMACAddress, buffer, 13);
+	/* Let's ask the device */
+	if (0 > (len = usb_string(ether_dev->usb, ether_dev->iMACAddress, buffer, 13))) {
+		err("Attempting to get MAC address failed: %d", -1*len);
+		return;
+	}
 
-	// Sanity check!
+	/* Sanity check */
 	if (len != 12)	{
-		// You gotta love failing sanity checks
+		/* You gotta love failing sanity checks */
 		err("Attempting to get MAC address returned %d bytes", len);
 		return;
 	}
 
-	// Fill in the mac_addr
+	/* Fill in the mac_addr */
 	for (i = 0; i < 6; i++)	{
-		mac_addr[i] = ( hex2dec( buffer[2 * i] ) << 4 ) + hex2dec( buffer[2 * i + 1] );
+		if ((16 == buffer[2 * i]) || (16 == buffer[2 * i + 1])) {
+			err("Bad value in MAC address");
+		}
+		else {
+			mac_addr[i] = ( hex2dec( buffer[2 * i] ) << 4 ) + hex2dec( buffer[2 * i + 1] );
+		}
 	}
 
-	// Now copy it over to the kernel's network driver.
+	/* Now copy it over to our network device structure */
 	memcpy( ether_dev->net->dev_addr, mac_addr, sizeof(mac_addr) );
 }
 
@@ -1067,12 +1187,12 @@
 	unsigned char sern[256];
 	unsigned char *mac_addr;
 
-	// Default empty strings in case we don't find a real one
+	/* Default empty strings in case we don't find a real one */
 	manu[0] = 0x00;
 	prod[0] = 0x00;
 	sern[0] = 0x00;
 
-	// Try to get the device Manufacturer
+	/*  Try to get the device Manufacturer */
 	string_num = ether_dev->usb->descriptor.iManufacturer;
 	if (string_num)	{
 		// Put it into its buffer
@@ -1081,7 +1201,7 @@
 		manu[len] = 0x00;
 	}
 
-	// Try to get the device Product Name
+	/* Try to get the device Product Name */
 	string_num = ether_dev->usb->descriptor.iProduct;
 	if (string_num)	{
 		// Put it into its buffer
@@ -1090,7 +1210,7 @@
 		prod[len] = 0x00;
 	}
 
-	// Try to get the device Serial Number
+	/* Try to get the device Serial Number */
 	string_num = ether_dev->usb->descriptor.iSerialNumber;
 	if (string_num)	{
 		// Put it into its buffer
@@ -1099,14 +1219,20 @@
 		sern[len] = 0x00;
 	}
 
-	// This makes it easier for us to print
+	/* This makes it easier for us to print */
 	mac_addr = ether_dev->net->dev_addr;
 
-	// Now send everything we found to the syslog
-	info( "%s: %s %s %s %02X:%02X:%02X:%02X:%02X:%02X", 
-	      ether_dev->net->name, manu, prod, sern, mac_addr[0], 
-	      mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], 
-	      mac_addr[5] );
+	/* Now send everything we found to the syslog */
+	info( "%s: %s %s %s", ether_dev->net->name, manu, prod, sern);
+	dbg( "%s: %02X:%02X:%02X:%02X:%02X:%02X",
+		ether_dev->net->name,
+		mac_addr[0],
+		mac_addr[1],
+		mac_addr[2],
+		mac_addr[3],
+		mac_addr[4],
+		mac_addr[5] );
+
 }
 
 /* Forward declaration */
@@ -1227,11 +1353,7 @@
 	// Send a message to syslog about what we are handling
 	log_device_info( ether_dev );
 
-	// I claim this interface to be a CDC Ethernet Networking device
-	usb_driver_claim_interface( &CDCEther_driver, 
-	                            &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]), 
-	                            ether_dev );
-	// I claim this interface to be a CDC Ethernet Networking device
+	/* We need to manually claim the data interface, while the comm interface gets claimed in the return */
 	usb_driver_claim_interface( &CDCEther_driver, 
 	                            &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]), 
 	                            ether_dev );
@@ -1239,11 +1361,8 @@
 	// Does this REALLY do anything???
 	usb_inc_dev_use( usb );
 
-	// TODO - last minute HACK
-	ether_dev->comm_ep_in = 5;
-
 	// Okay, we are finally done...
-	return NULL;
+	return ether_dev;
 }
 
 
@@ -1313,7 +1432,7 @@
 
 int __init CDCEther_init(void)
 {
-	info( "%s", version );
+	dbg( "%s", version );
 	return usb_register( &CDCEther_driver );
 }
 
@@ -1333,11 +1452,10 @@
 MODULE_DESCRIPTION("USB CDC Ethernet driver");
 MODULE_LICENSE("GPL");
 
+MODULE_DEVICE_TABLE (usb, CDCEther_ids);
 MODULE_PARM (multicast_filter_limit, "i");
 MODULE_PARM_DESC (multicast_filter_limit, "CDCEther maximum number of filtered multicast addresses");
 
-MODULE_DEVICE_TABLE (usb, CDCEther_ids);
-
 //////////////////////////////////////////////////////////////////////////////
 // End of file ///////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/CDCEther.h linux/drivers/usb/CDCEther.h
--- linux.orig/drivers/usb/CDCEther.h	2001-09-23 16:49:00.000000000 +0000
+++ linux/drivers/usb/CDCEther.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,4 +1,4 @@
-// Portions of this file taken from 
+// Portions of this file taken from
 // Petko Manolov - Petkan (petkan@dce.bg)
 // from his driver pegasus.h
 
@@ -18,11 +18,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
-
+/* From CDC Spec Table 24 */
 #define CS_INTERFACE			0x24
 
 #define	CDC_ETHER_MAX_MTU		1536
 
+/* These definitions are used with the ether_dev_t flags element */
 #define	CDC_ETHER_PRESENT		0x00000001
 #define	CDC_ETHER_RUNNING		0x00000002
 #define	CDC_ETHER_TX_BUSY		0x00000004
@@ -31,10 +32,10 @@
 
 #define	CDC_ETHER_TX_TIMEOUT	(HZ*10)
 
-#define	TX_UNDERRUN				0x80
+#define	TX_UNDERRUN			0x80
 #define	EXCESSIVE_COL			0x40
-#define	LATE_COL				0x20
-#define	NO_CARRIER				0x10
+#define	LATE_COL			0x20
+#define	NO_CARRIER			0x10
 #define	LOSS_CARRIER			0x08
 #define	JABBER_TIMEOUT			0x04
 
@@ -43,22 +44,13 @@
 #define	CDC_ETHER_REQ_GET_REGS	0xf0
 #define	CDC_ETHER_REQ_SET_REGS	0xf1
 #define	CDC_ETHER_REQ_SET_REG	PIPERIDER_REQ_SET_REGS
-#define	ALIGN(x)		x __attribute__((aligned(L1_CACHE_BYTES)))
-
-#define MODE_FLAG_PROMISCUOUS   (1<<0)
-#define MODE_FLAG_ALL_MULTICAST (1<<1)
-#define MODE_FLAG_DIRECTED      (1<<2)
-#define MODE_FLAG_BROADCAST     (1<<3)
-#define MODE_FLAG_MULTICAST     (1<<4)
-
-#define SET_ETHERNET_MULTICAST_FILTER    0x40
-#define SET_ETHERNET_PACKET_FILTER       0x43
 
 typedef struct _ether_dev_t {
 	struct usb_device	*usb;
 	struct net_device	*net;
 	struct net_device_stats	stats;
 	unsigned		flags;
+	unsigned		properties;
 	int			configuration_num;
 	int			bConfigurationValue;
 	int			comm_interface;
@@ -79,20 +71,44 @@
 	__u8			iMACAddress;
 	__u32			bmEthernetStatistics;
 	__u16			wMaxSegmentSize;
-	__u16                   mode_flags;
 	__u16			wNumberMCFilters;
 	__u8			bNumberPowerFilters;
+	__u16			mode_flags;
 	int			intr_interval;
-	struct urb		rx_urb, tx_urb, intr_urb;
-	unsigned char		ALIGN(rx_buff[CDC_ETHER_MAX_MTU]);
-	unsigned char		ALIGN(tx_buff[CDC_ETHER_MAX_MTU]);
-	unsigned char		ALIGN(intr_buff[8]);
+	devrequest		ctrl_dr;
+	struct urb		rx_urb, tx_urb, intr_urb, ctrl_urb;
+	unsigned char		rx_buff[CDC_ETHER_MAX_MTU] __attribute__((aligned(L1_CACHE_BYTES)));
+	unsigned char		tx_buff[CDC_ETHER_MAX_MTU] __attribute__((aligned(L1_CACHE_BYTES)));
+	unsigned char		intr_buff[8] __attribute__((aligned(L1_CACHE_BYTES))) ;
 } ether_dev_t;
 
+/* These definitions used in the Ethernet Packet Filtering requests */
+/* See CDC Spec Table 62 */
+#define MODE_FLAG_PROMISCUOUS   (1<<0)
+#define MODE_FLAG_ALL_MULTICAST (1<<1)
+#define MODE_FLAG_DIRECTED      (1<<2)
+#define MODE_FLAG_BROADCAST     (1<<3)
+#define MODE_FLAG_MULTICAST     (1<<4)
+
+/* CDC Spec class requests - CDC Spec Table 46 */
+#define SET_ETHERNET_MULTICAST_FILTER    0x40
+#define SET_ETHERNET_PACKET_FILTER       0x43
+
+
+/* These definitions are used with the ether_dev_t properties field */
+#define HAVE_NOTIFICATION_ELEMENT	0x0001
+#define PERFECT_FILTERING		0x0002
+#define NO_SET_MULTICAST		0x0004
+
+/* These definitions are used in the requirements parser */
 #define REQ_HDR_FUNC_DESCR	0x0001
 #define REQ_UNION_FUNC_DESCR	0x0002
 #define REQ_ETH_FUNC_DESCR	0x0004
-#define REQUIREMENTS_TOTAL	0x0007
+#define REQUIREMENTS_TOTAL	REQ_ETH_FUNC_DESCR | REQ_UNION_FUNC_DESCR | REQ_HDR_FUNC_DESCR
 
+/* Some useful lengths */
+#define HEADER_FUNC_DESC_LEN	0x5
+#define UNION_FUNC_DESC_LEN	0x5
+#define ETHERNET_FUNC_DESC_LEN	0xD /* 13 for all you decimal weenies */
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/Config.in linux/drivers/usb/Config.in
--- linux.orig/drivers/usb/Config.in	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/Config.in	2002-07-20 01:08:33.000000000 +0000
@@ -8,7 +8,7 @@
 if [ "$CONFIG_USB" = "y" -o  "$CONFIG_USB" = "m" ]; then
    bool '  USB verbose debug messages' CONFIG_USB_DEBUG
 
-comment 'Miscellaneous USB options'
+   comment 'Miscellaneous USB options'
    bool '  Preliminary USB device filesystem' CONFIG_USB_DEVICEFS
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       bool '  Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH
@@ -16,87 +16,91 @@
       define_bool CONFIG_USB_BANDWIDTH n
    fi
    bool '  Long timeout for slow-responding devices (some MGE Ellipse UPSes)' CONFIG_USB_LONG_TIMEOUT
-fi
 
-comment 'USB Controllers'
-if [ "$CONFIG_USB_UHCI_ALT" != "y" ]; then
-   dep_tristate '  UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB
-fi
-if [ "$CONFIG_USB_UHCI" != "y" ]; then
-   dep_tristate '  UHCI Alternate Driver (JE) support' CONFIG_USB_UHCI_ALT $CONFIG_USB
-else
-   define_bool CONFIG_USB_UHCI_ALT n
-fi
-dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
+   comment 'USB Host Controller Drivers'
+   source drivers/usb/hcd/Config.in
+   if [ "$CONFIG_USB_UHCI_ALT" != "y" ]; then
+      dep_tristate '  UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB
+   fi
+   if [ "$CONFIG_USB_UHCI" != "y" ]; then
+      dep_tristate '  UHCI Alternate Driver (JE) support' CONFIG_USB_UHCI_ALT $CONFIG_USB
+   else
+      define_bool CONFIG_USB_UHCI_ALT n
+   fi
+   dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
 
-comment 'USB Device Class drivers'
-dep_tristate '  USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
-dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
-if [ "$CONFIG_SCSI" = "n" ]; then
-   comment '  SCSI support is needed for USB Storage'
-fi
-dep_tristate '  USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI
-   dep_mbool '    USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG $CONFIG_USB_STORAGE
-   dep_mbool '    Datafab MDCFE-B Compact Flash Reader support' CONFIG_USB_STORAGE_DATAFAB $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
-   dep_mbool '    Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM  $CONFIG_USB_STORAGE
-   dep_mbool '    ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200 $CONFIG_USB_STORAGE
-   dep_mbool '    Microtech CompactFlash/SmartMedia support' CONFIG_USB_STORAGE_DPCM $CONFIG_USB_STORAGE
-   dep_mbool '    HP CD-Writer 82xx support' CONFIG_USB_STORAGE_HP8200e $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
-   dep_mbool '    SanDisk SDDR-09 (and other SmartMedia) support' CONFIG_USB_STORAGE_SDDR09 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
-   dep_mbool '    Lexar Jumpshot Compact Flash Reader' CONFIG_USB_STORAGE_JUMPSHOT $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
-dep_tristate '  USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
-dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
-
-comment 'USB Human Interface Devices (HID)'
-if [ "$CONFIG_INPUT" = "n" ]; then
-   comment '  Input core support is needed for USB HID'
-else
-   dep_tristate '  USB Human Interface Device (full HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT
-      dep_mbool '    /dev/hiddev raw HID device support (EXPERIMENTAL)' CONFIG_USB_HIDDEV $CONFIG_USB_HID
+   comment 'USB Device Class drivers'
+   dep_tristate '  USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
+   dep_tristate '    EMI 2|6 USB Audio interface support' CONFIG_USB_EMI26 $CONFIG_USB_AUDIO
+   dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
+   if [ "$CONFIG_SCSI" = "n" ]; then
+      comment '  SCSI support is needed for USB Storage'
+   fi
+   dep_tristate '  USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI
+      dep_mbool '    USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG $CONFIG_USB_STORAGE
+      dep_mbool '    Datafab MDCFE-B Compact Flash Reader support' CONFIG_USB_STORAGE_DATAFAB $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+      dep_mbool '    Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM  $CONFIG_USB_STORAGE
+      dep_mbool '    ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200 $CONFIG_USB_STORAGE
+      dep_mbool '    Microtech CompactFlash/SmartMedia support' CONFIG_USB_STORAGE_DPCM $CONFIG_USB_STORAGE
+      dep_mbool '    HP CD-Writer 82xx support' CONFIG_USB_STORAGE_HP8200e $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+      dep_mbool '    SanDisk SDDR-09 (and other SmartMedia) support' CONFIG_USB_STORAGE_SDDR09 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+      dep_mbool '    Lexar Jumpshot Compact Flash Reader' CONFIG_USB_STORAGE_JUMPSHOT $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
+   dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
+
+   comment 'USB Human Interface Devices (HID)'
+   dep_tristate '  USB Human Interface Device (full HID) support' CONFIG_USB_HID $CONFIG_USB
+   if [ "$CONFIG_INPUT" = "n" ]; then
+      comment '    Input core support is needed for USB HID input layer or HIDBP support'
+   fi
+      dep_mbool '    HID input layer support' CONFIG_USB_HIDINPUT $CONFIG_INPUT $CONFIG_USB_HID
+      dep_mbool '    /dev/hiddev raw HID device support' CONFIG_USB_HIDDEV $CONFIG_USB_HID
    if [ "$CONFIG_USB_HID" != "y" ]; then
       dep_tristate '  USB HIDBP Keyboard (basic) support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT
       dep_tristate '  USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
    fi
    dep_tristate '  Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
-fi
 
-comment 'USB Imaging devices'
-dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
-dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
-dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
-dep_tristate '  Microtek X6USB scanner support' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
-dep_tristate '  HP53xx USB scanner support (EXPERIMENTAL)' CONFIG_USB_HPUSBSCSI $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
-
-comment 'USB Multimedia devices'
-if [ "$CONFIG_VIDEO_DEV" = "n" ]; then
-   comment '  Video4Linux support is needed for USB Multimedia device support'
-else
-   dep_tristate '  USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
-   dep_tristate '  USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB $CONFIG_VIDEO_DEV
-   dep_tristate '  USB Philips Cameras' CONFIG_USB_PWC $CONFIG_USB $CONFIG_VIDEO_DEV
-   dep_tristate '  USB SE401 Camera support' CONFIG_USB_SE401 $CONFIG_USB $CONFIG_VIDEO_DEV
-   dep_tristate '  USB STV680 (Pencam) Camera support' CONFIG_USB_STV680 $CONFIG_USB $CONFIG_VIDEO_DEV
-   dep_tristate '  USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)' CONFIG_USB_VICAM $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
-   dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
-   dep_tristate '  DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
-fi
-
-comment 'USB Network adaptors'
-if [ "$CONFIG_NET" = "n" ]; then
-   comment '  Networking support is needed for USB Networking device support'
-else
-   dep_tristate '  USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB KLSI KL5USB101-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_KAWETH $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB Communication Class Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CDCETHER $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB-to-USB Networking cable device support (EXPERIMENTAL)' CONFIG_USB_USBNET $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
-fi
-
-comment 'USB port drivers'
-dep_tristate '  USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
-source drivers/usb/serial/Config.in
+   comment 'USB Imaging devices'
+   dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
+   dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
+   dep_tristate '  Microtek X6USB scanner support' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
+   dep_tristate '  HP53xx USB scanner support (EXPERIMENTAL)' CONFIG_USB_HPUSBSCSI $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
+
+   comment 'USB Multimedia devices'
+   if [ "$CONFIG_VIDEO_DEV" = "n" ]; then
+      comment '  Video4Linux support is needed for USB Multimedia device support'
+   else
+      dep_tristate '  USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
+      dep_tristate '  USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB $CONFIG_VIDEO_DEV
+      dep_tristate '  USB Philips Cameras' CONFIG_USB_PWC $CONFIG_USB $CONFIG_VIDEO_DEV
+      dep_tristate '  USB SE401 Camera support' CONFIG_USB_SE401 $CONFIG_USB $CONFIG_VIDEO_DEV
+      dep_tristate '  USB STV680 (Pencam) Camera support' CONFIG_USB_STV680 $CONFIG_USB $CONFIG_VIDEO_DEV
+      dep_tristate '  USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)' CONFIG_USB_VICAM $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
+      dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
+      dep_tristate '  DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
+   fi
 
-comment 'USB Miscellaneous drivers'
-dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL
+   comment 'USB Network adaptors'
+   if [ "$CONFIG_NET" = "n" ]; then
+      comment '  Networking support is needed for USB Networking device support'
+   else
+      dep_tristate '  USB Pegasus/Pegasus-II based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+      dep_tristate '  USB Realtek RTL8150 based ethernet device support (EXPERIMENTAL)' CONFIG_USB_RTL8150 $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+      dep_tristate '  USB KLSI KL5USB101-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_KAWETH $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+      dep_tristate '  USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+      dep_tristate '  USB Communication Class Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CDCETHER $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+      dep_tristate '  USB-to-USB Networking cable device support (EXPERIMENTAL)' CONFIG_USB_USBNET $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+   fi
 
+   comment 'USB port drivers'
+   dep_tristate '  USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
+   source drivers/usb/serial/Config.in
+
+   comment 'USB Miscellaneous drivers'
+   dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB Auerswald ISDN support (EXPERIMENTAL)' CONFIG_USB_AUERSWALD $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate '  Tieman Voyager USB Braille display support (EXPERIMENTAL)' CONFIG_USB_BRLVGER $CONFIG_USB $CONFIG_EXPERIMENTAL
+fi
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/Makefile linux/drivers/usb/Makefile
--- linux.orig/drivers/usb/Makefile	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -10,13 +10,13 @@
 
 # Objects that export symbols.
 
-export-objs		:= usb.o ov511.o pwc-uncompress.o
+export-objs		:= hcd.o usb.o ov511.o pwc-uncompress.o
 
 # Multipart objects.
 
 list-multi		:= usbcore.o hid.o pwc.o
 usbcore-objs		:= usb.o usb-debug.o hub.o
-hid-objs		:= hid-core.o hid-input.o
+hid-objs		:= hid-core.o
 pwc-objs		:= pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o
 
 
@@ -30,6 +30,10 @@
 	hid-objs	+= hiddev.o
 endif
 
+ifeq ($(CONFIG_USB_HIDINPUT),y)
+	hid-objs	+= hid-input.o
+endif
+
 # Object file lists.
 
 obj-y	:=
@@ -40,10 +44,21 @@
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_USB)		+= usbcore.o
+
+# EHCI should initialize/link before the other HCDs
+ifeq ($(CONFIG_USB_EHCI_HCD),y)
+	obj-y += hcd/ehci-hcd.o
+endif
+
 obj-$(CONFIG_USB_UHCI)		+= usb-uhci.o
 obj-$(CONFIG_USB_UHCI_ALT)	+= uhci.o
 obj-$(CONFIG_USB_OHCI)		+= usb-ohci.o
 
+ifneq ($(CONFIG_USB_EHCI_HCD),n)
+	usbcore-objs		+= hcd.o
+endif
+subdir-$(CONFIG_USB_EHCI_HCD)	+= hcd
+
 obj-$(CONFIG_USB_MOUSE)		+= usbmouse.o
 obj-$(CONFIG_USB_HID)		+= hid.o
 obj-$(CONFIG_USB_KBD)		+= usbkbd.o
@@ -53,6 +68,7 @@
 obj-$(CONFIG_USB_ACM)		+= acm.o
 obj-$(CONFIG_USB_PRINTER)	+= printer.o
 obj-$(CONFIG_USB_AUDIO)		+= audio.o
+obj-$(CONFIG_USB_EMI26)		+= emi26.o
 obj-$(CONFIG_USB_IBMCAM)	+= ibmcam.o usbvideo.o ultracam.o
 obj-$(CONFIG_USB_PWC)		+= pwc.o
 obj-$(CONFIG_USB_DC2XX)		+= dc2xx.o
@@ -64,6 +80,7 @@
 obj-$(CONFIG_USB_SE401)		+= se401.o
 obj-$(CONFIG_USB_STV680)	+= stv680.o
 obj-$(CONFIG_USB_PEGASUS)	+= pegasus.o
+obj-$(CONFIG_USB_RTL8150)	+= rtl8150.o
 obj-$(CONFIG_USB_CATC)		+= catc.o
 obj-$(CONFIG_USB_KAWETH)        += kaweth.o
 obj-$(CONFIG_USB_CDCETHER)	+= CDCEther.o
@@ -73,9 +90,11 @@
 obj-$(CONFIG_USB_HPUSBSCSI)	+= hpusbscsi.o
 obj-$(CONFIG_USB_BLUETOOTH)	+= bluetooth.o
 obj-$(CONFIG_USB_USBNET)	+= usbnet.o
+obj-$(CONFIG_USB_AUERSWALD)	+= auerswald.o
+obj-$(CONFIG_USB_BRLVGER)	+= brlvger.o
 
 # Object files in subdirectories
-mod-subdirs	:= serial
+mod-subdirs	:= serial hcd
 
 subdir-$(CONFIG_USB_SERIAL)	+= serial
 subdir-$(CONFIG_USB_STORAGE)	+= storage
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/audio.c linux/drivers/usb/audio.c
--- linux.orig/drivers/usb/audio.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/audio.c	2002-07-20 01:08:35.000000000 +0000
@@ -399,7 +399,7 @@
 
 /* prevent picking up a bogus abs macro */
 #undef abs
-extern inline int abs(int x)
+static inline int abs(int x)
 {
         if (x < 0)
 		return -x;
@@ -408,7 +408,7 @@
                                 
 /* --------------------------------------------------------------------- */
 
-extern inline unsigned ld2(unsigned int x)
+static inline unsigned ld2(unsigned int x)
 {
 	unsigned r = 0;
 	
@@ -1931,13 +1931,13 @@
 	kfree(s);
 }
 
-extern inline int prog_dmabuf_in(struct usb_audiodev *as)
+static inline int prog_dmabuf_in(struct usb_audiodev *as)
 {
 	usbin_stop(as);
 	return dmabuf_init(&as->usbin.dma);
 }
 
-extern inline int prog_dmabuf_out(struct usb_audiodev *as)
+static inline int prog_dmabuf_out(struct usb_audiodev *as)
 {
 	usbout_stop(as);
 	return dmabuf_init(&as->usbout.dma);
@@ -2536,7 +2536,7 @@
 		if (as->usbin.dma.mapped)
 			as->usbin.dma.count &= as->usbin.dma.fragsize-1;
 		spin_unlock_irqrestore(&as->lock, flags);
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -2548,7 +2548,7 @@
 		if (as->usbout.dma.mapped)
 			as->usbout.dma.count &= as->usbout.dma.fragsize-1;
 		spin_unlock_irqrestore(&as->lock, flags);
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
        case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -3207,7 +3207,7 @@
 
 static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid);
 
-extern inline int checkmixbmap(unsigned char *bmap, unsigned char flg, unsigned int inidx, unsigned int numoch)
+static inline int checkmixbmap(unsigned char *bmap, unsigned char flg, unsigned int inidx, unsigned int numoch)
 {
 	unsigned int idx;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/auerswald.c linux/drivers/usb/auerswald.c
--- linux.orig/drivers/usb/auerswald.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/auerswald.c	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,2196 @@
+/*****************************************************************************/
+/*
+ *      auerswald.c  --  Auerswald PBX/System Telephone usb driver.
+ *
+ *      Copyright (C) 2001  Wolfgang Mües (wmues@nexgo.de)
+ *
+ *      Very much code of this driver is borrowed from dabusb.c (Deti Fliegl)
+ *      and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you.
+ *
+ *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+ /*****************************************************************************/
+
+/* Standard Linux module include files */
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/devfs_fs_kernel.h>
+#undef DEBUG   		/* include debug macros until it's done	*/
+#include <linux/usb.h>
+
+/*-------------------------------------------------------------------*/
+/* Debug support 						     */
+#ifdef DEBUG
+#define dump( adr, len) \
+do {			\
+	unsigned int u;	\
+	printk (KERN_DEBUG); \
+	for (u = 0; u < len; u++) \
+		printk (" %02X", adr[u] & 0xFF); \
+	printk ("\n"); \
+} while (0)
+#else
+#define dump( adr, len)
+#endif
+
+/*-------------------------------------------------------------------*/
+/* Version Information */
+#define DRIVER_VERSION "0.9.11"
+#define DRIVER_AUTHOR  "Wolfgang Mües <wmues@nexgo.de>"
+#define DRIVER_DESC    "Auerswald PBX/System Telephone usb driver"
+
+/*-------------------------------------------------------------------*/
+/* Private declarations for Auerswald USB driver                     */
+
+/* Auerswald Vendor ID */
+#define ID_AUERSWALD  	0x09BF
+
+#ifndef AUER_MINOR_BASE		/* allow external override */
+#define AUER_MINOR_BASE	112	/* auerswald driver minor number */
+#endif
+
+/* we can have up to this number of device plugged in at once */
+#define AUER_MAX_DEVICES 16
+
+/* prefix for the device descriptors in /dev/usb */
+#define AU_PREFIX	"auer"
+
+/* Number of read buffers for each device */
+#define AU_RBUFFERS     10
+
+/* Number of chain elements for each control chain */
+#define AUCH_ELEMENTS   20
+
+/* Number of retries in communication */
+#define AU_RETRIES	10
+
+/*-------------------------------------------------------------------*/
+/* vendor specific protocol                                          */
+/* Header Byte */
+#define AUH_INDIRMASK   0x80    /* mask for direct/indirect bit */
+#define AUH_DIRECT      0x00    /* data is for USB device */
+#define AUH_INDIRECT    0x80    /* USB device is relay */
+
+#define AUH_SPLITMASK   0x40    /* mask for split bit */
+#define AUH_UNSPLIT     0x00    /* data block is full-size */
+#define AUH_SPLIT       0x40    /* data block is part of a larger one,
+                                   split-byte follows */
+
+#define AUH_TYPEMASK    0x3F    /* mask for type of data transfer */
+#define AUH_TYPESIZE    0x40    /* different types */
+#define AUH_DCHANNEL    0x00    /* D channel data */
+#define AUH_B1CHANNEL   0x01    /* B1 channel transparent */
+#define AUH_B2CHANNEL   0x02    /* B2 channel transparent */
+/*                0x03..0x0F       reserved for driver internal use */
+#define AUH_COMMAND     0x10    /* Command channel */
+#define AUH_BPROT       0x11    /* Configuration block protocol */
+#define AUH_DPROTANA    0x12    /* D channel protocol analyzer */
+#define AUH_TAPI        0x13    /* telephone api data (ATD) */
+/*                0x14..0x3F       reserved for other protocols */
+#define AUH_UNASSIGNED  0xFF    /* if char device has no assigned service */
+#define AUH_FIRSTUSERCH 0x11    /* first channel which is available for driver users */
+
+#define AUH_SIZE	1 	/* Size of Header Byte */
+
+/* Split Byte. Only present if split bit in header byte set.*/
+#define AUS_STARTMASK   0x80    /* mask for first block of splitted frame */
+#define AUS_FIRST       0x80    /* first block */
+#define AUS_FOLLOW      0x00    /* following block */
+
+#define AUS_ENDMASK     0x40    /* mask for last block of splitted frame */
+#define AUS_END         0x40    /* last block */
+#define AUS_NOEND       0x00    /* not the last block */
+
+#define AUS_LENMASK     0x3F    /* mask for block length information */
+
+/* Request types */
+#define AUT_RREQ        (USB_DIR_IN  | USB_TYPE_VENDOR | USB_RECIP_OTHER)   /* Read Request */
+#define AUT_WREQ        (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER)   /* Write Request */
+
+/* Vendor Requests */
+#define AUV_GETINFO     0x00    /* GetDeviceInfo */
+#define AUV_WBLOCK      0x01    /* Write Block */
+#define AUV_RBLOCK      0x02    /* Read Block */
+#define AUV_CHANNELCTL  0x03    /* Channel Control */
+#define AUV_DUMMY	0x04	/* Dummy Out for retry */
+
+/* Device Info Types */
+#define AUDI_NUMBCH     0x0000  /* Number of supported B channels */
+#define AUDI_OUTFSIZE   0x0001  /* Size of OUT B channel fifos */
+#define AUDI_MBCTRANS   0x0002  /* max. Blocklength of control transfer */
+
+/* Interrupt endpoint definitions */
+#define AU_IRQENDP      1       /* Endpoint number */
+#define AU_IRQCMDID     16      /* Command-block ID */
+#define AU_BLOCKRDY     0       /* Command: Block data ready on ctl endpoint */
+#define AU_IRQMINSIZE	5	/* Nr. of bytes decoded in this driver */
+
+/* Device String Descriptors */
+#define AUSI_VENDOR   	1	/* "Auerswald GmbH & Co. KG" */
+#define AUSI_DEVICE   	2	/* Name of the Device */
+#define AUSI_SERIALNR 	3	/* Serial Number */
+#define AUSI_MSN      	4	/* "MSN ..." (first) Multiple Subscriber Number */
+
+#define AUSI_DLEN	100	/* Max. Length of Device Description */
+
+#define AUV_RETRY	0x101	/* First Firmware version which can do control retries */
+
+/*-------------------------------------------------------------------*/
+/* External data structures / Interface                              */
+typedef struct
+{
+        char *buf;               /* return buffer for string contents */
+        unsigned int bsize;      /* size of return buffer */
+} audevinfo_t,*paudevinfo_t;
+
+/* IO controls */
+#define IOCTL_AU_SLEN	  _IOR( 'U', 0xF0, int)         /* return the max. string descriptor length */
+#define IOCTL_AU_DEVINFO  _IOWR('U', 0xF1, audevinfo_t) /* get name of a specific device */
+#define IOCTL_AU_SERVREQ  _IOW( 'U', 0xF2, int) 	/* request a service channel */
+#define IOCTL_AU_BUFLEN	  _IOR( 'U', 0xF3, int)         /* return the max. buffer length for the device */
+#define IOCTL_AU_RXAVAIL  _IOR( 'U', 0xF4, int)         /* return != 0 if Receive Data available */
+#define IOCTL_AU_CONNECT  _IOR( 'U', 0xF5, int)         /* return != 0 if connected to a service channel */
+#define IOCTL_AU_TXREADY  _IOR( 'U', 0xF6, int)         /* return != 0 if Transmitt channel ready to send */
+/*                              'U'  0xF7..0xFF reseved */
+
+/*-------------------------------------------------------------------*/
+/* Internal data structures                                          */
+
+/* ..................................................................*/
+/* urb chain element */
+struct  auerchain;                      /* forward for circular reference */
+typedef struct
+{
+        struct auerchain *chain;        /* pointer to the chain to which this element belongs */
+        urb_t * urbp;                   /* pointer to attached urb */
+        void *context;                  /* saved URB context */
+        usb_complete_t complete;        /* saved URB completion function */
+        struct list_head list;          /* to include element into a list */
+} auerchainelement_t,*pauerchainelement_t;
+
+/* urb chain */
+typedef struct auerchain
+{
+        pauerchainelement_t active;     /* element which is submitted to urb */
+	spinlock_t lock;                /* protection agains interrupts */
+        struct list_head waiting_list;  /* list of waiting elements */
+        struct list_head free_list;     /* list of available elements */
+} auerchain_t,*pauerchain_t;
+
+/* urb blocking completion helper struct */
+typedef struct
+{
+	wait_queue_head_t wqh;    	/* wait for completion */
+	unsigned int done;		/* completion flag */
+} auerchain_chs_t,*pauerchain_chs_t;
+
+/* ...................................................................*/
+/* buffer element */
+struct  auerbufctl;                     /* forward */
+typedef struct
+{
+        char *bufp;                     /* reference to allocated data buffer */
+        unsigned int len;               /* number of characters in data buffer */
+	unsigned int retries;		/* for urb retries */
+        devrequest *dr;                 /* for setup data in control messages */
+        urb_t * urbp;                   /* USB urb */
+        struct auerbufctl *list;        /* pointer to list */
+        struct list_head buff_list;     /* reference to next buffer in list */
+} auerbuf_t,*pauerbuf_t;
+
+/* buffer list control block */
+typedef struct auerbufctl
+{
+        spinlock_t lock;                /* protection in interrupt */
+        struct list_head free_buff_list;/* free buffers */
+        struct list_head rec_buff_list; /* buffers with receive data */
+} auerbufctl_t,*pauerbufctl_t;
+
+/* ...................................................................*/
+/* service context */
+struct  auerscon;                       /* forward */
+typedef void (*auer_dispatch_t)(struct auerscon*, pauerbuf_t);
+typedef void (*auer_disconn_t) (struct auerscon*);
+typedef struct auerscon
+{
+        unsigned int id;                /* protocol service id AUH_xxxx */
+        auer_dispatch_t dispatch;       /* dispatch read buffer */
+	auer_disconn_t disconnect;	/* disconnect from device, wake up all char readers */
+} auerscon_t,*pauerscon_t;
+
+/* ...................................................................*/
+/* USB device context */
+typedef struct
+{
+	struct semaphore 	mutex;         	    /* protection in user context */
+	char 			name[16];	    /* name of the /dev/usb entry */
+	unsigned int		dtindex;	    /* index in the device table */
+	devfs_handle_t 		devfs;	 	    /* devfs device node */
+	struct usb_device *	usbdev;      	    /* USB device handle */
+	int			open_count;	    /* count the number of open character channels */
+        char 			dev_desc[AUSI_DLEN];/* for storing a textual description */
+        unsigned int 		maxControlLength;   /* max. Length of control paket (without header) */
+        urb_t * 		inturbp;            /* interrupt urb */
+        char *			intbufp;            /* data buffer for interrupt urb */
+	unsigned int 		irqsize;	    /* size of interrupt endpoint 1 */
+        struct auerchain 	controlchain;  	    /* for chaining of control messages */
+	auerbufctl_t 		bufctl;             /* Buffer control for control transfers */
+        pauerscon_t 	     	services[AUH_TYPESIZE];/* context pointers for each service */
+	unsigned int		version;	    /* Version of the device */
+	wait_queue_head_t 	bufferwait;         /* wait for a control buffer */
+} auerswald_t,*pauerswald_t;
+
+/* the global usb devfs handle */
+extern devfs_handle_t usb_devfs_handle;
+
+/* array of pointers to our devices that are currently connected */
+static pauerswald_t dev_table[AUER_MAX_DEVICES];
+
+/* lock to protect the dev_table structure */
+static struct semaphore dev_table_mutex;
+
+/* ................................................................... */
+/* character device context */
+typedef struct
+{
+	struct semaphore mutex;         /* protection in user context */
+	pauerswald_t auerdev;           /* context pointer of assigned device */
+        auerbufctl_t bufctl;            /* controls the buffer chain */
+        auerscon_t scontext;            /* service context */
+	wait_queue_head_t readwait;     /* for synchronous reading */
+	struct semaphore readmutex;     /* protection against multiple reads */
+	pauerbuf_t readbuf;		/* buffer held for partial reading */
+	unsigned int readoffset;	/* current offset in readbuf */
+	unsigned int removed;		/* is != 0 if device is removed */
+} auerchar_t,*pauerchar_t;
+
+
+/*-------------------------------------------------------------------*/
+/* Forwards */
+static void auerswald_ctrlread_complete (urb_t * urb);
+static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp);
+
+
+/*-------------------------------------------------------------------*/
+/* USB chain helper functions                                        */
+/* --------------------------                                        */
+
+/* completion function for chained urbs */
+static void auerchain_complete (urb_t * urb)
+{
+	unsigned long flags;
+        int result;
+
+        /* get pointer to element and to chain */
+        pauerchainelement_t acep = (pauerchainelement_t) urb->context;
+        pauerchain_t         acp = acep->chain;
+
+        /* restore original entries in urb */
+        urb->context  = acep->context;
+        urb->complete = acep->complete;
+
+        dbg ("auerchain_complete called");
+
+        /* call original completion function
+           NOTE: this function may lead to more urbs submitted into the chain.
+                 (no chain lock at calling complete()!)
+                 acp->active != NULL is protecting us against recursion.*/
+        urb->complete (urb);
+
+        /* detach element from chain data structure */
+	spin_lock_irqsave (&acp->lock, flags);
+        if (acp->active != acep) /* paranoia debug check */
+	        dbg ("auerchain_complete: completion on non-active element called!");
+        else
+                acp->active = NULL;
+
+        /* add the used chain element to the list of free elements */
+	list_add_tail (&acep->list, &acp->free_list);
+        acep = NULL;
+
+        /* is there a new element waiting in the chain? */
+        if (!acp->active && !list_empty (&acp->waiting_list)) {
+                /* yes: get the entry */
+                struct list_head *tmp = acp->waiting_list.next;
+                list_del (tmp);
+                acep = list_entry (tmp, auerchainelement_t, list);
+                acp->active = acep;
+        }
+        spin_unlock_irqrestore (&acp->lock, flags);
+
+        /* submit the new urb */
+        if (acep) {
+                urb    = acep->urbp;
+                dbg ("auerchain_complete: submitting next urb from chain");
+		urb->status = 0;	/* needed! */
+		result = usb_submit_urb( urb);
+
+                /* check for submit errors */
+                if (result) {
+                        urb->status = result;
+                        dbg("auerchain_complete: usb_submit_urb with error code %d", result);
+                        /* and do error handling via *this* completion function (recursive) */
+                        auerchain_complete( urb);
+                }
+        } else {
+                /* simple return without submitting a new urb.
+                   The empty chain is detected with acp->active == NULL. */
+        };
+}
+
+
+/* submit function for chained urbs
+   this function may be called from completion context or from user space!
+   early = 1 -> submit in front of chain
+*/
+static int auerchain_submit_urb_list (pauerchain_t acp, urb_t * urb, int early)
+{
+        int result;
+        unsigned long flags;
+        pauerchainelement_t acep = NULL;
+
+        dbg ("auerchain_submit_urb called");
+
+        /* try to get a chain element */
+        spin_lock_irqsave (&acp->lock, flags);
+        if (!list_empty (&acp->free_list)) {
+                /* yes: get the entry */
+                struct list_head *tmp = acp->free_list.next;
+                list_del (tmp);
+                acep = list_entry (tmp, auerchainelement_t, list);
+        }
+        spin_unlock_irqrestore (&acp->lock, flags);
+
+        /* if no chain element available: return with error */
+        if (!acep) {
+                return -ENOMEM;
+        }
+
+        /* fill in the new chain element values */
+        acep->chain    = acp;
+        acep->context  = urb->context;
+        acep->complete = urb->complete;
+        acep->urbp     = urb;
+        INIT_LIST_HEAD (&acep->list);
+
+        /* modify urb */
+        urb->context   = acep;
+        urb->complete  = auerchain_complete;
+        urb->status    = -EINPROGRESS;    /* usb_submit_urb does this, too */
+
+        /* add element to chain - or start it immediately */
+        spin_lock_irqsave (&acp->lock, flags);
+        if (acp->active) {
+                /* there is traffic in the chain, simple add element to chain */
+		if (early) {
+			dbg ("adding new urb to head of chain");
+			list_add (&acep->list, &acp->waiting_list);
+		} else {
+			dbg ("adding new urb to end of chain");
+			list_add_tail (&acep->list, &acp->waiting_list);
+		}
+		acep = NULL;
+        } else {
+                /* the chain is empty. Prepare restart */
+                acp->active = acep;
+        }
+        /* Spin has to be removed before usb_submit_urb! */
+        spin_unlock_irqrestore (&acp->lock, flags);
+
+        /* Submit urb if immediate restart */
+        if (acep) {
+                dbg("submitting urb immediate");
+		urb->status = 0;	/* needed! */
+                result = usb_submit_urb( urb);
+                /* check for submit errors */
+                if (result) {
+                        urb->status = result;
+                        dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result);
+                        /* and do error handling via completion function */
+                        auerchain_complete( urb);
+                }
+        }
+
+        return 0;
+}
+
+/* submit function for chained urbs
+   this function may be called from completion context or from user space!
+*/
+static int auerchain_submit_urb (pauerchain_t acp, urb_t * urb)
+{
+	return auerchain_submit_urb_list (acp, urb, 0);
+}
+
+/* cancel an urb which is submitted to the chain
+   the result is 0 if the urb is cancelled, or -EINPROGRESS if
+   USB_ASYNC_UNLINK is set and the function is successfully started.
+*/
+static int auerchain_unlink_urb (pauerchain_t acp, urb_t * urb)
+{
+	unsigned long flags;
+        urb_t * urbp;
+        pauerchainelement_t acep;
+        struct list_head *tmp;
+
+        dbg ("auerchain_unlink_urb called");
+
+        /* search the chain of waiting elements */
+        spin_lock_irqsave (&acp->lock, flags);
+        list_for_each (tmp, &acp->waiting_list) {
+                acep = list_entry (tmp, auerchainelement_t, list);
+                if (acep->urbp == urb) {
+                        list_del (tmp);
+                        urb->context = acep->context;
+                        urb->complete = acep->complete;
+                        list_add_tail (&acep->list, &acp->free_list);
+                        spin_unlock_irqrestore (&acp->lock, flags);
+                        dbg ("unlink waiting urb");
+                        urb->status = -ENOENT;
+                        urb->complete (urb);
+                        return 0;
+                }
+        }
+        /* not found. */
+        spin_unlock_irqrestore (&acp->lock, flags);
+
+        /* get the active urb */
+        acep = acp->active;
+        if (acep) {
+                urbp = acep->urbp;
+
+                /* check if we have to cancel the active urb */
+                if (urbp == urb) {
+                        /* note that there is a race condition between the check above
+                           and the unlink() call because of no lock. This race is harmless,
+                           because the usb module will detect the unlink() after completion.
+                           We can't use the acp->lock here because the completion function
+                           wants to grab it.
+			*/
+                        dbg ("unlink active urb");
+                        return usb_unlink_urb (urbp);
+                }
+        }
+
+        /* not found anyway
+           ... is some kind of success
+	*/
+        dbg ("urb to unlink not found in chain");
+        return 0;
+}
+
+/* cancel all urbs which are in the chain.
+   this function must not be called from interrupt or completion handler.
+*/
+static void auerchain_unlink_all (pauerchain_t acp)
+{
+	unsigned long flags;
+        urb_t * urbp;
+        pauerchainelement_t acep;
+
+        dbg ("auerchain_unlink_all called");
+
+        /* clear the chain of waiting elements */
+        spin_lock_irqsave (&acp->lock, flags);
+        while (!list_empty (&acp->waiting_list)) {
+                /* get the next entry */
+                struct list_head *tmp = acp->waiting_list.next;
+                list_del (tmp);
+                acep = list_entry (tmp, auerchainelement_t, list);
+                urbp = acep->urbp;
+                urbp->context = acep->context;
+                urbp->complete = acep->complete;
+                list_add_tail (&acep->list, &acp->free_list);
+                spin_unlock_irqrestore (&acp->lock, flags);
+                dbg ("unlink waiting urb");
+                urbp->status = -ENOENT;
+                urbp->complete (urbp);
+                spin_lock_irqsave (&acp->lock, flags);
+        }
+        spin_unlock_irqrestore (&acp->lock, flags);
+
+        /* clear the active urb */
+        acep = acp->active;
+        if (acep) {
+                urbp = acep->urbp;
+                urbp->transfer_flags &= ~USB_ASYNC_UNLINK;
+                dbg ("unlink active urb");
+                usb_unlink_urb (urbp);
+        }
+}
+
+
+/* free the chain.
+   this function must not be called from interrupt or completion handler.
+*/
+static void auerchain_free (pauerchain_t acp)
+{
+	unsigned long flags;
+        pauerchainelement_t acep;
+
+        dbg ("auerchain_free called");
+
+        /* first, cancel all pending urbs */
+        auerchain_unlink_all (acp);
+
+        /* free the elements */
+        spin_lock_irqsave (&acp->lock, flags);
+        while (!list_empty (&acp->free_list)) {
+                /* get the next entry */
+                struct list_head *tmp = acp->free_list.next;
+                list_del (tmp);
+                spin_unlock_irqrestore (&acp->lock, flags);
+		acep = list_entry (tmp, auerchainelement_t, list);
+                kfree (acep);
+	        spin_lock_irqsave (&acp->lock, flags);
+	}
+        spin_unlock_irqrestore (&acp->lock, flags);
+}
+
+
+/* Init the chain control structure */
+static void auerchain_init (pauerchain_t acp)
+{
+        /* init the chain data structure */
+        acp->active = NULL;
+	spin_lock_init (&acp->lock);
+        INIT_LIST_HEAD (&acp->waiting_list);
+        INIT_LIST_HEAD (&acp->free_list);
+}
+
+/* setup a chain.
+   It is assumed that there is no concurrency while setting up the chain
+   requirement: auerchain_init()
+*/
+static int auerchain_setup (pauerchain_t acp, unsigned int numElements)
+{
+        pauerchainelement_t acep;
+
+        dbg ("auerchain_setup called with %d elements", numElements);
+
+        /* fill the list of free elements */
+        for (;numElements; numElements--) {
+                acep = (pauerchainelement_t) kmalloc (sizeof (auerchainelement_t), GFP_KERNEL);
+                if (!acep) goto ac_fail;
+		memset (acep, 0, sizeof (auerchainelement_t));
+                INIT_LIST_HEAD (&acep->list);
+                list_add_tail (&acep->list, &acp->free_list);
+        }
+        return 0;
+
+ac_fail:/* free the elements */
+        while (!list_empty (&acp->free_list)) {
+                /* get the next entry */
+                struct list_head *tmp = acp->free_list.next;
+                list_del (tmp);
+                acep = list_entry (tmp, auerchainelement_t, list);
+                kfree (acep);
+        }
+        return -ENOMEM;
+}
+
+
+/* completion handler for synchronous chained URBs */
+static void auerchain_blocking_completion (urb_t *urb)
+{
+	pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context;
+	pchs->done = 1;
+	wmb();
+	wake_up (&pchs->wqh);
+}
+
+
+/* Starts chained urb and waits for completion or timeout */
+static int auerchain_start_wait_urb (pauerchain_t acp, urb_t *urb, int timeout, int* actual_length)
+{
+	DECLARE_WAITQUEUE (wait, current);
+	auerchain_chs_t chs;
+	int status;
+
+	dbg ("auerchain_start_wait_urb called");
+	init_waitqueue_head (&chs.wqh);
+	chs.done = 0;
+
+	set_current_state (TASK_UNINTERRUPTIBLE);
+	add_wait_queue (&chs.wqh, &wait);
+	urb->context = &chs;
+	status = auerchain_submit_urb (acp, urb);
+	if (status) {
+		/* something went wrong */
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&chs.wqh, &wait);
+		return status;
+	}
+
+	while (timeout && !chs.done)
+	{
+		timeout = schedule_timeout (timeout);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		rmb();
+	}
+
+	set_current_state (TASK_RUNNING);
+	remove_wait_queue (&chs.wqh, &wait);
+
+	if (!timeout && !chs.done) {
+		if (urb->status != -EINPROGRESS) {	/* No callback?!! */
+			dbg ("auerchain_start_wait_urb: raced timeout");
+			status = urb->status;
+		} else {
+			dbg ("auerchain_start_wait_urb: timeout");
+			auerchain_unlink_urb (acp, urb);  /* remove urb safely */
+			status = -ETIMEDOUT;
+		}
+	} else
+		status = urb->status;
+
+	if (actual_length)
+		*actual_length = urb->actual_length;
+
+  	return status;
+}
+
+
+/* auerchain_control_msg - Builds a control urb, sends it off and waits for completion
+   acp: pointer to the auerchain
+   dev: pointer to the usb device to send the message to
+   pipe: endpoint "pipe" to send the message to
+   request: USB message request value
+   requesttype: USB message request type value
+   value: USB message value
+   index: USB message index value
+   data: pointer to the data to send
+   size: length in bytes of the data to send
+   timeout: time to wait for the message to complete before timing out (if 0 the wait is forever)
+
+   This function sends a simple control message to a specified endpoint
+   and waits for the message to complete, or timeout.
+
+   If successful, it returns the transfered length, othwise a negative error number.
+
+   Don't use this function from within an interrupt context, like a
+   bottom half handler.  If you need a asyncronous message, or need to send
+   a message from within interrupt context, use auerchain_submit_urb()
+*/
+static int auerchain_control_msg (pauerchain_t acp, struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
+			          __u16 value, __u16 index, void *data, __u16 size, int timeout)
+{
+	int ret;
+	devrequest *dr;
+	urb_t *urb;
+        int length;
+
+        dbg ("auerchain_control_msg");
+        dr = kmalloc (sizeof (devrequest), GFP_KERNEL);
+	if (!dr)
+		return -ENOMEM;
+	urb = usb_alloc_urb (0);
+	if (!urb) {
+        	kfree (dr);
+		return -ENOMEM;
+        }
+
+	dr->requesttype = requesttype;
+	dr->request = request;
+	dr->value  = cpu_to_le16 (value);
+	dr->index  = cpu_to_le16 (index);
+	dr->length = cpu_to_le16 (size);
+
+	FILL_CONTROL_URB (urb, dev, pipe, (unsigned char*)dr, data, size,    /* build urb */
+		          (usb_complete_t)auerchain_blocking_completion,0);
+	ret = auerchain_start_wait_urb (acp, urb, timeout, &length);
+
+	usb_free_urb (urb);
+	kfree (dr);
+
+        if (ret < 0)
+		return ret;
+	else
+		return length;
+}
+
+
+/*-------------------------------------------------------------------*/
+/* Buffer List helper functions                                      */
+
+/* free a single auerbuf */
+static void auerbuf_free (pauerbuf_t bp)
+{
+	if (bp->bufp) {
+		kfree (bp->bufp);
+	}
+	if (bp->dr) {
+		kfree (bp->dr);
+	}
+	if (bp->urbp) {
+		usb_free_urb (bp->urbp);
+	}
+	kfree (bp);
+}
+
+/* free the buffers from an auerbuf list */
+static void auerbuf_free_list (struct list_head *q)
+{
+        struct list_head *tmp;
+	struct list_head *p;
+	pauerbuf_t bp;
+
+	dbg ("auerbuf_free_list");
+	for (p = q->next; p != q;) {
+		bp = list_entry (p, auerbuf_t, buff_list);
+		tmp = p->next;
+		list_del (p);
+		p = tmp;
+		auerbuf_free (bp);
+	}
+}
+
+/* init the members of a list control block */
+static void auerbuf_init (pauerbufctl_t bcp)
+{
+	dbg ("auerbuf_init");
+	spin_lock_init (&bcp->lock);
+        INIT_LIST_HEAD (&bcp->free_buff_list);
+        INIT_LIST_HEAD (&bcp->rec_buff_list);
+}
+
+/* free all buffers from an auerbuf chain */
+static void auerbuf_free_buffers (pauerbufctl_t bcp)
+{
+	unsigned long flags;
+	dbg ("auerbuf_free_buffers");
+
+        spin_lock_irqsave (&bcp->lock, flags);
+
+	auerbuf_free_list (&bcp->free_buff_list);
+	auerbuf_free_list (&bcp->rec_buff_list);
+
+        spin_unlock_irqrestore (&bcp->lock, flags);
+}
+
+/* setup a list of buffers */
+/* requirement: auerbuf_init() */
+static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned int bufsize)
+{
+        pauerbuf_t bep;
+
+        dbg ("auerbuf_setup called with %d elements of %d bytes", numElements, bufsize);
+
+        /* fill the list of free elements */
+        for (;numElements; numElements--) {
+                bep = (pauerbuf_t) kmalloc (sizeof (auerbuf_t), GFP_KERNEL);
+                if (!bep) goto bl_fail;
+	        memset (bep, 0, sizeof (auerbuf_t));
+                bep->list = bcp;
+                INIT_LIST_HEAD (&bep->buff_list);
+                bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL);
+                if (!bep->bufp) goto bl_fail;
+                bep->dr = (devrequest *) kmalloc (sizeof (devrequest), GFP_KERNEL);
+                if (!bep->dr) goto bl_fail;
+                bep->urbp = usb_alloc_urb (0);
+                if (!bep->urbp) goto bl_fail;
+                list_add_tail (&bep->buff_list, &bcp->free_buff_list);
+        }
+        return 0;
+
+bl_fail:/* not enought memory. Free allocated elements */
+        dbg ("auerbuf_setup: no more memory");
+        auerbuf_free_buffers (bcp);
+        return -ENOMEM;
+}
+
+/* insert a used buffer into the free list */
+static void auerbuf_releasebuf( pauerbuf_t bp)
+{
+        unsigned long flags;
+        pauerbufctl_t bcp = bp->list;
+	bp->retries = 0;
+
+        dbg ("auerbuf_releasebuf called");
+        spin_lock_irqsave (&bcp->lock, flags);
+	list_add_tail (&bp->buff_list, &bcp->free_buff_list);
+        spin_unlock_irqrestore (&bcp->lock, flags);
+}
+
+
+/*-------------------------------------------------------------------*/
+/* Completion handlers */
+
+/* Values of urb->status or results of usb_submit_urb():
+0		Initial, OK
+-EINPROGRESS	during submission until end
+-ENOENT		if urb is unlinked
+-ETIMEDOUT	Transfer timed out, NAK
+-ENOMEM		Memory Overflow
+-ENODEV		Specified USB-device or bus doesn't exist
+-ENXIO		URB already queued
+-EINVAL		a) Invalid transfer type specified (or not supported)
+		b) Invalid interrupt interval (0n256)
+-EAGAIN		a) Specified ISO start frame too early
+		b) (using ISO-ASAP) Too much scheduled for the future wait some time and try again.
+-EFBIG		Too much ISO frames requested (currently uhci900)
+-EPIPE		Specified pipe-handle/Endpoint is already stalled
+-EMSGSIZE	Endpoint message size is zero, do interface/alternate setting
+-EPROTO		a) Bitstuff error
+		b) Unknown USB error
+-EILSEQ		CRC mismatch
+-ENOSR		Buffer error
+-EREMOTEIO	Short packet detected
+-EXDEV		ISO transfer only partially completed look at individual frame status for details
+-EINVAL		ISO madness, if this happens: Log off and go home
+-EOVERFLOW	babble
+*/
+
+/* check if a status code allows a retry */
+static int auerswald_status_retry (int status)
+{
+	switch (status) {
+	case 0:
+	case -ETIMEDOUT:
+	case -EOVERFLOW:
+	case -EAGAIN:
+	case -EPIPE:
+	case -EPROTO:
+	case -EILSEQ:
+	case -ENOSR:
+	case -EREMOTEIO:
+		return 1; /* do a retry */
+	}
+	return 0;	/* no retry possible */
+}
+
+/* Completion of asynchronous write block */
+static void auerchar_ctrlwrite_complete (urb_t * urb)
+{
+	pauerbuf_t bp = (pauerbuf_t) urb->context;
+	pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
+	dbg ("auerchar_ctrlwrite_complete called");
+
+	/* reuse the buffer */
+	auerbuf_releasebuf (bp);
+	/* Wake up all processes waiting for a buffer */
+	wake_up (&cp->bufferwait);
+}
+
+/* Completion handler for dummy retry packet */
+static void auerswald_ctrlread_wretcomplete (urb_t * urb)
+{
+        pauerbuf_t bp = (pauerbuf_t) urb->context;
+        pauerswald_t cp;
+	int ret;
+        dbg ("auerswald_ctrlread_wretcomplete called");
+        dbg ("complete with status: %d", urb->status);
+	cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
+
+	/* check if it is possible to advance */
+	if (!auerswald_status_retry (urb->status) || !cp->usbdev) {
+		/* reuse the buffer */
+		err ("control dummy: transmission error %d, can not retry", urb->status);
+		auerbuf_releasebuf (bp);
+		/* Wake up all processes waiting for a buffer */
+		wake_up (&cp->bufferwait);
+		return;
+	}
+
+	/* fill the control message */
+	bp->dr->requesttype = AUT_RREQ;
+	bp->dr->request     = AUV_RBLOCK;
+	bp->dr->length      = bp->dr->value;	/* temporary stored */
+	bp->dr->value       = cpu_to_le16 (1);	/* Retry Flag */
+	/* bp->dr->index    = channel id;          remains */
+	FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0),
+                          (unsigned char*)bp->dr, bp->bufp, le16_to_cpu (bp->dr->length),
+		          (usb_complete_t)auerswald_ctrlread_complete,bp);
+
+	/* submit the control msg as next paket */
+	ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1);
+        if (ret) {
+        	dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
+        	bp->urbp->status = ret;
+        	auerswald_ctrlread_complete (bp->urbp);
+    	}
+}
+
+/* completion handler for receiving of control messages */
+static void auerswald_ctrlread_complete (urb_t * urb)
+{
+        unsigned int  serviceid;
+        pauerswald_t  cp;
+        pauerscon_t   scp;
+        pauerbuf_t    bp  = (pauerbuf_t) urb->context;
+	int ret;
+        dbg ("auerswald_ctrlread_complete called");
+
+	cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
+
+	/* check if there is valid data in this urb */
+        if (urb->status) {
+		dbg ("complete with non-zero status: %d", urb->status);
+		/* should we do a retry? */
+		if (!auerswald_status_retry (urb->status)
+		 || !cp->usbdev
+		 || (cp->version < AUV_RETRY)
+                 || (bp->retries >= AU_RETRIES)) {
+			/* reuse the buffer */
+			err ("control read: transmission error %d, can not retry", urb->status);
+			auerbuf_releasebuf (bp);
+			/* Wake up all processes waiting for a buffer */
+			wake_up (&cp->bufferwait);
+			return;
+		}
+		bp->retries++;
+		dbg ("Retry count = %d", bp->retries);
+		/* send a long dummy control-write-message to allow device firmware to react */
+		bp->dr->requesttype = AUT_WREQ;
+		bp->dr->request     = AUV_DUMMY;
+		bp->dr->value       = bp->dr->length; /* temporary storage */
+		// bp->dr->index    channel ID remains
+		bp->dr->length      = cpu_to_le16 (32); /* >= 8 bytes */
+		FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0),
+  			(unsigned char*)bp->dr, bp->bufp, 32,
+	   		(usb_complete_t)auerswald_ctrlread_wretcomplete,bp);
+
+		/* submit the control msg as next paket */
+       		ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1);
+       		if (ret) {
+               		dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
+               		bp->urbp->status = ret;
+               		auerswald_ctrlread_wretcomplete (bp->urbp);
+		}
+                return;
+        }
+
+        /* get the actual bytecount (incl. headerbyte) */
+        bp->len = urb->actual_length;
+        serviceid = bp->bufp[0] & AUH_TYPEMASK;
+        dbg ("Paket with serviceid %d and %d bytes received", serviceid, bp->len);
+
+        /* dispatch the paket */
+        scp = cp->services[serviceid];
+        if (scp) {
+                /* look, Ma, a listener! */
+                scp->dispatch (scp, bp);
+        }
+
+        /* release the paket */
+        auerbuf_releasebuf (bp);
+	/* Wake up all processes waiting for a buffer */
+	wake_up (&cp->bufferwait);
+}
+
+/*-------------------------------------------------------------------*/
+/* Handling of Interrupt Endpoint                                    */
+/* This interrupt Endpoint is used to inform the host about waiting
+   messages from the USB device.
+*/
+/* int completion handler. */
+static void auerswald_int_complete (urb_t * urb)
+{
+        unsigned long flags;
+        unsigned  int channelid;
+        unsigned  int bytecount;
+        int ret;
+        pauerbuf_t   bp = NULL;
+        pauerswald_t cp = (pauerswald_t) urb->context;
+
+        dbg ("auerswald_int_complete called");
+
+        /* do not respond to an error condition */
+        if (urb->status != 0) {
+                dbg ("nonzero URB status = %d", urb->status);
+                return;
+        }
+
+        /* check if all needed data was received */
+	if (urb->actual_length < AU_IRQMINSIZE) {
+                dbg ("invalid data length received: %d bytes", urb->actual_length);
+                return;
+        }
+
+        /* check the command code */
+        if (cp->intbufp[0] != AU_IRQCMDID) {
+                dbg ("invalid command received: %d", cp->intbufp[0]);
+                return;
+        }
+
+        /* check the command type */
+        if (cp->intbufp[1] != AU_BLOCKRDY) {
+                dbg ("invalid command type received: %d", cp->intbufp[1]);
+                return;
+        }
+
+        /* now extract the information */
+        channelid = cp->intbufp[2];
+        bytecount = le16_to_cpup (&cp->intbufp[3]);
+
+        /* check the channel id */
+        if (channelid >= AUH_TYPESIZE) {
+                dbg ("invalid channel id received: %d", channelid);
+                return;
+        }
+
+        /* check the byte count */
+        if (bytecount > (cp->maxControlLength+AUH_SIZE)) {
+                dbg ("invalid byte count received: %d", bytecount);
+                return;
+        }
+        dbg ("Service Channel = %d", channelid);
+        dbg ("Byte Count = %d", bytecount);
+
+        /* get a buffer for the next data paket */
+        spin_lock_irqsave (&cp->bufctl.lock, flags);
+        if (!list_empty (&cp->bufctl.free_buff_list)) {
+                /* yes: get the entry */
+                struct list_head *tmp = cp->bufctl.free_buff_list.next;
+                list_del (tmp);
+                bp = list_entry (tmp, auerbuf_t, buff_list);
+        }
+        spin_unlock_irqrestore (&cp->bufctl.lock, flags);
+
+        /* if no buffer available: skip it */
+        if (!bp) {
+                dbg ("auerswald_int_complete: no data buffer available");
+                /* can we do something more?
+		   This is a big problem: if this int packet is ignored, the
+		   device will wait forever and not signal any more data.
+		   The only real solution is: having enought buffers!
+		   Or perhaps temporary disabling the int endpoint?
+		*/
+		return;
+        }
+
+	/* fill the control message */
+        bp->dr->requesttype = AUT_RREQ;
+	bp->dr->request     = AUV_RBLOCK;
+	bp->dr->value       = cpu_to_le16 (0);
+	bp->dr->index       = cpu_to_le16 (channelid | AUH_DIRECT | AUH_UNSPLIT);
+	bp->dr->length      = cpu_to_le16 (bytecount);
+	FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0),
+                          (unsigned char*)bp->dr, bp->bufp, bytecount,
+		          (usb_complete_t)auerswald_ctrlread_complete,bp);
+
+        /* submit the control msg */
+        ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
+        if (ret) {
+                dbg ("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret);
+                bp->urbp->status = ret;
+                auerswald_ctrlread_complete( bp->urbp);
+		/* here applies the same problem as above: device locking! */
+        }
+}
+
+/* int memory deallocation
+   NOTE: no mutex please!
+*/
+static void auerswald_int_free (pauerswald_t cp)
+{
+        if (cp->inturbp) {
+                usb_free_urb (cp->inturbp);
+                cp->inturbp = NULL;
+        }
+        if (cp->intbufp) {
+                kfree (cp->intbufp);
+                cp->intbufp = NULL;
+        }
+}
+
+/* This function is called to activate the interrupt
+   endpoint. This function returns 0 if successfull or an error code.
+   NOTE: no mutex please!
+*/
+static int auerswald_int_open (pauerswald_t cp)
+{
+        int ret;
+	struct usb_endpoint_descriptor *ep;
+	int irqsize;
+	dbg ("auerswald_int_open");
+
+	ep = usb_epnum_to_ep_desc (cp->usbdev, USB_DIR_IN | AU_IRQENDP);
+	if (!ep) {
+		ret = -EFAULT;
+  		goto intoend;
+    	}
+	irqsize = ep->wMaxPacketSize;
+	cp->irqsize = irqsize;
+
+	/* allocate the urb and data buffer */
+        if (!cp->inturbp) {
+                cp->inturbp = usb_alloc_urb (0);
+                if (!cp->inturbp) {
+                        ret = -ENOMEM;
+                        goto intoend;
+                }
+        }
+        if (!cp->intbufp) {
+                cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL);
+                if (!cp->intbufp) {
+                        ret = -ENOMEM;
+                        goto intoend;
+                }
+        }
+        /* setup urb */
+        FILL_INT_URB (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval);
+        /* start the urb */
+	cp->inturbp->status = 0;	/* needed! */
+	ret = usb_submit_urb (cp->inturbp);
+
+intoend:
+        if (ret < 0) {
+                /* activation of interrupt endpoint has failed. Now clean up. */
+                dbg ("auerswald_int_open: activation of int endpoint failed");
+
+                /* deallocate memory */
+                auerswald_int_free (cp);
+        }
+        return ret;
+}
+
+/* This function is called to deactivate the interrupt
+   endpoint. This function returns 0 if successfull or an error code.
+   NOTE: no mutex please!
+*/
+static int auerswald_int_release (pauerswald_t cp)
+{
+        int ret = 0;
+        dbg ("auerswald_int_release");
+
+        /* stop the int endpoint */
+        if (cp->inturbp) {
+                ret = usb_unlink_urb (cp->inturbp);
+                if (ret)
+	                dbg ("nonzero int unlink result received: %d", ret);
+        }
+
+        /* deallocate memory */
+        auerswald_int_free (cp);
+
+        return ret;
+}
+
+/* --------------------------------------------------------------------- */
+/* Helper functions                                                      */
+
+/* wake up waiting readers */
+static void auerchar_disconnect (pauerscon_t scp)
+{
+        pauerchar_t ccp = ((pauerchar_t)((char *)(scp)-(unsigned long)(&((pauerchar_t)0)->scontext)));
+	dbg ("auerchar_disconnect called");
+	ccp->removed = 1;
+	wake_up (&ccp->readwait);
+}
+
+
+/* dispatch a read paket to a waiting character device */
+static void auerchar_ctrlread_dispatch (pauerscon_t scp, pauerbuf_t bp)
+{
+	unsigned long flags;
+        pauerchar_t ccp;
+        pauerbuf_t newbp = NULL;
+        char * charp;
+        dbg ("auerchar_ctrlread_dispatch called");
+        ccp = ((pauerchar_t)((char *)(scp)-(unsigned long)(&((pauerchar_t)0)->scontext)));
+
+        /* get a read buffer from character device context */
+        spin_lock_irqsave (&ccp->bufctl.lock, flags);
+        if (!list_empty (&ccp->bufctl.free_buff_list)) {
+                /* yes: get the entry */
+                struct list_head *tmp = ccp->bufctl.free_buff_list.next;
+                list_del (tmp);
+                newbp = list_entry (tmp, auerbuf_t, buff_list);
+        }
+        spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
+
+        if (!newbp) {
+                dbg ("No read buffer available, discard paket!");
+                return;     /* no buffer, no dispatch */
+        }
+
+        /* copy information to new buffer element
+           (all buffers have the same length) */
+        charp = newbp->bufp;
+        newbp->bufp = bp->bufp;
+        bp->bufp = charp;
+        newbp->len = bp->len;
+
+        /* insert new buffer in read list */
+        spin_lock_irqsave (&ccp->bufctl.lock, flags);
+	list_add_tail (&newbp->buff_list, &ccp->bufctl.rec_buff_list);
+        spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
+        dbg ("read buffer appended to rec_list");
+
+        /* wake up pending synchronous reads */
+	wake_up (&ccp->readwait);
+}
+
+
+/* Delete an auerswald driver context */
+static void auerswald_delete( pauerswald_t cp)
+{
+	dbg( "auerswald_delete");
+	if (cp == NULL) return;
+
+	/* Wake up all processes waiting for a buffer */
+	wake_up (&cp->bufferwait);
+
+	/* Cleaning up */
+	auerswald_int_release (cp);
+	auerchain_free (&cp->controlchain);
+	auerbuf_free_buffers (&cp->bufctl);
+
+	/* release the memory */
+	kfree( cp);
+}
+
+
+/* Delete an auerswald character context */
+static void auerchar_delete( pauerchar_t ccp)
+{
+	dbg ("auerchar_delete");
+	if (ccp == NULL) return;
+
+        /* wake up pending synchronous reads */
+	ccp->removed = 1;
+	wake_up (&ccp->readwait);
+
+	/* remove the read buffer */
+	if (ccp->readbuf) {
+		auerbuf_releasebuf (ccp->readbuf);
+		ccp->readbuf = NULL;
+	}
+
+	/* remove the character buffers */
+	auerbuf_free_buffers (&ccp->bufctl);
+
+	/* release the memory */
+	kfree( ccp);
+}
+
+
+/* add a new service to the device
+   scp->id must be set!
+   return: 0 if OK, else error code
+*/
+static int auerswald_addservice (pauerswald_t cp, pauerscon_t scp)
+{
+	int ret;
+
+	/* is the device available? */
+	if (!cp->usbdev) {
+		dbg ("usbdev == NULL");
+		return -EIO;	/*no: can not add a service, sorry*/
+	}
+
+	/* is the service available? */
+	if (cp->services[scp->id]) {
+		dbg ("service is busy");
+                return -EBUSY;
+	}
+
+	/* device is available, service is free */
+	cp->services[scp->id] = scp;
+
+	/* register service in device */
+	ret = auerchain_control_msg(
+		&cp->controlchain,                      /* pointer to control chain */
+		cp->usbdev,                             /* pointer to device */
+		usb_sndctrlpipe (cp->usbdev, 0),        /* pipe to control endpoint */
+		AUV_CHANNELCTL,                         /* USB message request value */
+		AUT_WREQ,                               /* USB message request type value */
+		0x01,              /* open                 USB message value */
+		scp->id,            		        /* USB message index value */
+		NULL,                                   /* pointer to the data to send */
+		0,                                      /* length in bytes of the data to send */
+		HZ * 2);                                /* time to wait for the message to complete before timing out */
+	if (ret < 0) {
+		dbg ("auerswald_addservice: auerchain_control_msg returned error code %d", ret);
+		/* undo above actions */
+		cp->services[scp->id] = NULL;
+		return ret;
+	}
+
+	dbg ("auerswald_addservice: channel open OK");
+	return 0;
+}
+
+
+/* remove a service from the the device
+   scp->id must be set! */
+static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp)
+{
+	dbg ("auerswald_removeservice called");
+
+	/* check if we have a service allocated */
+	if (scp->id == AUH_UNASSIGNED) return;
+
+	/* If there is a device: close the channel */
+	if (cp->usbdev) {
+		/* Close the service channel inside the device */
+		int ret = auerchain_control_msg(
+		&cp->controlchain,            		/* pointer to control chain */
+		cp->usbdev,         		        /* pointer to device */
+		usb_sndctrlpipe (cp->usbdev, 0),	/* pipe to control endpoint */
+		AUV_CHANNELCTL,                         /* USB message request value */
+		AUT_WREQ,                               /* USB message request type value */
+		0x00,              // close             /* USB message value */
+		scp->id,            		        /* USB message index value */
+		NULL,                                   /* pointer to the data to send */
+		0,                                      /* length in bytes of the data to send */
+		HZ * 2);                                /* time to wait for the message to complete before timing out */
+		if (ret < 0) {
+			dbg ("auerswald_removeservice: auerchain_control_msg returned error code %d", ret);
+		}
+		else {
+			dbg ("auerswald_removeservice: channel close OK");
+		}
+	}
+
+	/* remove the service from the device */
+	cp->services[scp->id] = NULL;
+	scp->id = AUH_UNASSIGNED;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Char device functions                                                 */
+
+/* Open a new character device */
+static int auerchar_open (struct inode *inode, struct file *file)
+{
+	int dtindex = MINOR(inode->i_rdev) - AUER_MINOR_BASE;
+	pauerswald_t cp = NULL;
+	pauerchar_t ccp = NULL;
+        int ret;
+
+        /* minor number in range? */
+	if ((dtindex < 0) || (dtindex >= AUER_MAX_DEVICES)) {
+		return -ENODEV;
+        }
+	/* usb device available? */
+	if (down_interruptible (&dev_table_mutex)) {
+		return -ERESTARTSYS;
+	}
+	cp = dev_table[dtindex];
+	if (cp == NULL) {
+		up (&dev_table_mutex);
+		return -ENODEV;
+	}
+	if (down_interruptible (&cp->mutex)) {
+		up (&dev_table_mutex);
+		return -ERESTARTSYS;
+	}
+	up (&dev_table_mutex);
+
+	/* we have access to the device. Now lets allocate memory */
+	ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL);
+	if (ccp == NULL) {
+		err ("out of memory");
+		ret = -ENOMEM;
+		goto ofail;
+	}
+
+	/* Initialize device descriptor */
+	memset( ccp, 0, sizeof(auerchar_t));
+	init_MUTEX( &ccp->mutex);
+	init_MUTEX( &ccp->readmutex);
+        auerbuf_init (&ccp->bufctl);
+        ccp->scontext.id = AUH_UNASSIGNED;
+        ccp->scontext.dispatch = auerchar_ctrlread_dispatch;
+	ccp->scontext.disconnect = auerchar_disconnect;
+	init_waitqueue_head (&ccp->readwait);
+
+	ret = auerbuf_setup (&ccp->bufctl, AU_RBUFFERS, cp->maxControlLength+AUH_SIZE);
+       	if (ret) {
+		goto ofail;
+	}
+
+	cp->open_count++;
+	ccp->auerdev = cp;
+	dbg("open %s as /dev/usb/%s", cp->dev_desc, cp->name);
+	up (&cp->mutex);
+
+	/* file IO stuff */
+	file->f_pos = 0;
+	file->private_data = ccp;
+	return 0;
+
+	/* Error exit */
+ofail:	up (&cp->mutex);
+	auerchar_delete (ccp);
+	return ret;
+}
+
+
+/* IOCTL functions */
+static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	pauerchar_t ccp = (pauerchar_t) file->private_data;
+	int ret = 0;
+        audevinfo_t devinfo;
+        pauerswald_t cp = NULL;
+	unsigned int u;
+        dbg ("ioctl");
+
+	/* get the mutexes */
+	if (down_interruptible (&ccp->mutex)) {
+		return -ERESTARTSYS;
+	}
+	cp = ccp->auerdev;
+	if (!cp) {
+		up (&ccp->mutex);
+                return -ENODEV;
+	}
+	if (down_interruptible (&cp->mutex)) {
+		up(&ccp->mutex);
+		return -ERESTARTSYS;
+	}
+
+	/* Check for removal */
+	if (!cp->usbdev) {
+		up(&cp->mutex);
+		up(&ccp->mutex);
+                return -ENODEV;
+	}
+
+	switch (cmd) {
+
+	/* return != 0 if Transmitt channel ready to send */
+	case IOCTL_AU_TXREADY:
+		dbg ("IOCTL_AU_TXREADY");
+		u   = ccp->auerdev
+		   && (ccp->scontext.id != AUH_UNASSIGNED)
+		   && !list_empty (&cp->bufctl.free_buff_list);
+	        ret = put_user (u, (unsigned int *) arg);
+		break;
+
+	/* return != 0 if connected to a service channel */
+	case IOCTL_AU_CONNECT:
+		dbg ("IOCTL_AU_CONNECT");
+		u = (ccp->scontext.id != AUH_UNASSIGNED);
+	        ret = put_user (u, (unsigned int *) arg);
+		break;
+
+	/* return != 0 if Receive Data available */
+	case IOCTL_AU_RXAVAIL:
+		dbg ("IOCTL_AU_RXAVAIL");
+		if (ccp->scontext.id == AUH_UNASSIGNED) {
+                        ret = -EIO;
+                        break;
+                }
+		u = 0;	/* no data */
+		if (ccp->readbuf) {
+			int restlen = ccp->readbuf->len - ccp->readoffset;
+			if (restlen > 0) u = 1;
+		}
+		if (!u) {
+        		if (!list_empty (&ccp->bufctl.rec_buff_list)) {
+				u = 1;
+			}
+		}
+	        ret = put_user (u, (unsigned int *) arg);
+		break;
+
+	/* return the max. buffer length for the device */
+	case IOCTL_AU_BUFLEN:
+		dbg ("IOCTL_AU_BUFLEN");
+		u = cp->maxControlLength;
+	        ret = put_user (u, (unsigned int *) arg);
+		break;
+
+	/* requesting a service channel */
+        case IOCTL_AU_SERVREQ:
+		dbg ("IOCTL_AU_SERVREQ");
+                /* requesting a service means: release the previous one first */
+		auerswald_removeservice (cp, &ccp->scontext);
+		/* get the channel number */
+		ret = get_user (u, (unsigned int *) arg);
+		if (ret) {
+			break;
+		}
+		if ((u < AUH_FIRSTUSERCH) || (u >= AUH_TYPESIZE)) {
+                        ret = -EIO;
+                        break;
+                }
+                dbg ("auerchar service request parameters are ok");
+		ccp->scontext.id = u;
+
+		/* request the service now */
+		ret = auerswald_addservice (cp, &ccp->scontext);
+		if (ret) {
+			/* no: revert service entry */
+                	ccp->scontext.id = AUH_UNASSIGNED;
+		}
+		break;
+
+	/* get a string descriptor for the device */
+	case IOCTL_AU_DEVINFO:
+		dbg ("IOCTL_AU_DEVINFO");
+                if (copy_from_user (&devinfo, (void *) arg, sizeof (audevinfo_t))) {
+        		ret = -EFAULT;
+	        	break;
+                }
+		u = strlen(cp->dev_desc)+1;
+		if (u > devinfo.bsize) {
+			u = devinfo.bsize;
+		}
+		ret = copy_to_user(devinfo.buf, cp->dev_desc, u)?-EFAULT:0;
+		break;
+
+	/* get the max. string descriptor length */
+        case IOCTL_AU_SLEN:
+		dbg ("IOCTL_AU_SLEN");
+		u = AUSI_DLEN;
+	        ret = put_user (u, (unsigned int *) arg);
+		break;
+
+	default:
+		dbg ("IOCTL_AU_UNKNOWN");
+		ret = -ENOIOCTLCMD;
+		break;
+        }
+	/* release the mutexes */
+	up(&cp->mutex);
+	up(&ccp->mutex);
+	return ret;
+}
+
+
+/* Seek is not supported */
+static loff_t auerchar_llseek (struct file *file, loff_t offset, int origin)
+{
+        dbg ("auerchar_seek");
+        return -ESPIPE;
+}
+
+
+/* Read data from the device */
+static ssize_t auerchar_read (struct file *file, char *buf, size_t count, loff_t * ppos)
+{
+        unsigned long flags;
+	pauerchar_t ccp = (pauerchar_t) file->private_data;
+        pauerbuf_t   bp = NULL;
+	wait_queue_t wait;
+
+        dbg ("auerchar_read");
+
+	/* Error checking */
+	if (!ccp)
+		return -EIO;
+	if (*ppos)
+ 		return -ESPIPE;
+        if (count == 0)
+		return 0;
+
+	/* get the mutex */
+	if (down_interruptible (&ccp->mutex))
+		return -ERESTARTSYS;
+
+	/* Can we expect to read something? */
+	if (ccp->scontext.id == AUH_UNASSIGNED) {
+		up (&ccp->mutex);
+                return -EIO;
+	}
+
+	/* only one reader per device allowed */
+	if (down_interruptible (&ccp->readmutex)) {
+		up (&ccp->mutex);
+		return -ERESTARTSYS;
+	}
+
+	/* read data from readbuf, if available */
+doreadbuf:
+	bp = ccp->readbuf;
+	if (bp) {
+		/* read the maximum bytes */
+		int restlen = bp->len - ccp->readoffset;
+		if (restlen < 0)
+			restlen = 0;
+		if (count > restlen)
+			count = restlen;
+		if (count) {
+			if (copy_to_user (buf, bp->bufp+ccp->readoffset, count)) {
+				dbg ("auerswald_read: copy_to_user failed");
+				up (&ccp->readmutex);
+				up (&ccp->mutex);
+				return -EFAULT;
+			}
+		}
+		/* advance the read offset */
+		ccp->readoffset += count;
+		restlen -= count;
+		// reuse the read buffer
+		if (restlen <= 0) {
+			auerbuf_releasebuf (bp);
+			ccp->readbuf = NULL;
+		}
+		/* return with number of bytes read */
+		if (count) {
+			up (&ccp->readmutex);
+			up (&ccp->mutex);
+			return count;
+		}
+	}
+
+	/* a read buffer is not available. Try to get the next data block. */
+doreadlist:
+	/* Preparing for sleep */
+	init_waitqueue_entry (&wait, current);
+	set_current_state (TASK_INTERRUPTIBLE);
+	add_wait_queue (&ccp->readwait, &wait);
+
+	bp = NULL;
+	spin_lock_irqsave (&ccp->bufctl.lock, flags);
+        if (!list_empty (&ccp->bufctl.rec_buff_list)) {
+                /* yes: get the entry */
+                struct list_head *tmp = ccp->bufctl.rec_buff_list.next;
+                list_del (tmp);
+                bp = list_entry (tmp, auerbuf_t, buff_list);
+        }
+        spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
+
+	/* have we got data? */
+	if (bp) {
+		ccp->readbuf = bp;
+		ccp->readoffset = AUH_SIZE; /* for headerbyte */
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&ccp->readwait, &wait);
+		goto doreadbuf;		  /* now we can read! */
+	}
+
+	/* no data available. Should we wait? */
+	if (file->f_flags & O_NONBLOCK) {
+                dbg ("No read buffer available, returning -EAGAIN");
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&ccp->readwait, &wait);
+		up (&ccp->readmutex);
+		up (&ccp->mutex);
+		return -EAGAIN;  /* nonblocking, no data available */
+        }
+
+	/* yes, we should wait! */
+	up (&ccp->mutex); /* allow other operations while we wait */
+	schedule();
+	remove_wait_queue (&ccp->readwait, &wait);
+	if (signal_pending (current)) {
+		/* waked up by a signal */
+		up (&ccp->readmutex);
+		return -ERESTARTSYS;
+	}
+
+	/* Anything left to read? */
+	if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) {
+		up (&ccp->readmutex);
+		return -EIO;
+	}
+
+	if (down_interruptible (&ccp->mutex)) {
+		up (&ccp->readmutex);
+		return -ERESTARTSYS;
+	}
+
+	/* try to read the incomming data again */
+	goto doreadlist;
+}
+
+
+/* Write a data block into the right service channel of the device */
+static ssize_t auerchar_write (struct file *file, const char *buf, size_t len, loff_t *ppos)
+{
+	pauerchar_t ccp = (pauerchar_t) file->private_data;
+        pauerswald_t cp = NULL;
+        pauerbuf_t bp;
+        unsigned long flags;
+	int ret;
+	wait_queue_t wait;
+
+        dbg ("auerchar_write %d bytes", len);
+
+	/* Error checking */
+	if (!ccp)
+		return -EIO;
+        if (*ppos)
+		return -ESPIPE;
+        if (len == 0)
+                return 0;
+
+write_again:
+	/* get the mutex */
+	if (down_interruptible (&ccp->mutex))
+		return -ERESTARTSYS;
+
+	/* Can we expect to write something? */
+	if (ccp->scontext.id == AUH_UNASSIGNED) {
+		up (&ccp->mutex);
+                return -EIO;
+	}
+
+	cp = ccp->auerdev;
+	if (!cp) {
+		up (&ccp->mutex);
+		return -ERESTARTSYS;
+	}
+	if (down_interruptible (&cp->mutex)) {
+		up (&ccp->mutex);
+		return -ERESTARTSYS;
+	}
+	if (!cp->usbdev) {
+		up (&cp->mutex);
+		up (&ccp->mutex);
+		return -EIO;
+	}
+	/* Prepare for sleep */
+	init_waitqueue_entry (&wait, current);
+	set_current_state (TASK_INTERRUPTIBLE);
+	add_wait_queue (&cp->bufferwait, &wait);
+
+	/* Try to get a buffer from the device pool.
+	   We can't use a buffer from ccp->bufctl because the write
+	   command will last beond a release() */
+	bp = NULL;
+	spin_lock_irqsave (&cp->bufctl.lock, flags);
+        if (!list_empty (&cp->bufctl.free_buff_list)) {
+                /* yes: get the entry */
+                struct list_head *tmp = cp->bufctl.free_buff_list.next;
+                list_del (tmp);
+                bp = list_entry (tmp, auerbuf_t, buff_list);
+        }
+        spin_unlock_irqrestore (&cp->bufctl.lock, flags);
+
+	/* are there any buffers left? */
+	if (!bp) {
+		up (&cp->mutex);
+		up (&ccp->mutex);
+
+		/* NONBLOCK: don't wait */
+		if (file->f_flags & O_NONBLOCK) {
+			set_current_state (TASK_RUNNING);
+			remove_wait_queue (&cp->bufferwait, &wait);
+			return -EAGAIN;
+		}
+
+		/* BLOCKING: wait */
+		schedule();
+		remove_wait_queue (&cp->bufferwait, &wait);
+		if (signal_pending (current)) {
+			/* waked up by a signal */
+			return -ERESTARTSYS;
+		}
+		goto write_again;
+	} else {
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&cp->bufferwait, &wait);
+	}
+
+	/* protect against too big write requests */
+	if (len > cp->maxControlLength) len = cp->maxControlLength;
+
+	/* Fill the buffer */
+	if (copy_from_user ( bp->bufp+AUH_SIZE, buf, len)) {
+		dbg ("copy_from_user failed");
+		auerbuf_releasebuf (bp);
+		/* Wake up all processes waiting for a buffer */
+		wake_up (&cp->bufferwait);
+		up (&cp->mutex);
+		up (&ccp->mutex);
+		return -EIO;
+	}
+
+	/* set the header byte */
+        *(bp->bufp) = ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT;
+
+	/* Set the transfer Parameters */
+	bp->len = len+AUH_SIZE;
+        bp->dr->requesttype = AUT_WREQ;
+	bp->dr->request     = AUV_WBLOCK;
+	bp->dr->value       = cpu_to_le16 (0);
+	bp->dr->index       = cpu_to_le16 (ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT);
+	bp->dr->length      = cpu_to_le16 (len+AUH_SIZE);
+	FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0),
+                   (unsigned char*)bp->dr, bp->bufp, len+AUH_SIZE,
+		    auerchar_ctrlwrite_complete, bp);
+	/* up we go */
+	ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
+	up (&cp->mutex);
+	if (ret) {
+		dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret);
+		auerbuf_releasebuf (bp);
+		/* Wake up all processes waiting for a buffer */
+		wake_up (&cp->bufferwait);
+		up (&ccp->mutex);
+		return -EIO;
+	}
+	else {
+		dbg ("auerchar_write: Write OK");
+		up (&ccp->mutex);
+		return len;
+	}
+}
+
+
+/* Close a character device */
+static int auerchar_release (struct inode *inode, struct file *file)
+{
+	pauerchar_t ccp = (pauerchar_t) file->private_data;
+	pauerswald_t cp;
+	dbg("release");
+
+	/* get the mutexes */
+	if (down_interruptible (&ccp->mutex)) {
+		return -ERESTARTSYS;
+	}
+	cp = ccp->auerdev;
+	if (cp) {
+		if (down_interruptible (&cp->mutex)) {
+			up (&ccp->mutex);
+			return -ERESTARTSYS;
+		}
+		/* remove an open service */
+		auerswald_removeservice (cp, &ccp->scontext);
+		/* detach from device */
+		if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) {
+			/* usb device waits for removal */
+			up (&cp->mutex);
+			auerswald_delete (cp);
+		} else {
+			up (&cp->mutex);
+		}
+		cp = NULL;
+		ccp->auerdev = NULL;
+	}
+	up (&ccp->mutex);
+	auerchar_delete (ccp);
+
+	return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+/* File operation structure                                             */
+static struct file_operations auerswald_fops =
+{
+	owner:		THIS_MODULE,
+	llseek:		auerchar_llseek,
+	read:		auerchar_read,
+	write:          auerchar_write,
+	ioctl:		auerchar_ioctl,
+	open:		auerchar_open,
+	release:	auerchar_release,
+};
+
+
+/* --------------------------------------------------------------------- */
+/* Special USB driver functions                                          */
+
+/* Probe if this driver wants to serve an USB device
+
+   This entry point is called whenever a new device is attached to the bus.
+   Then the device driver has to create a new instance of its internal data
+   structures for the new device.
+
+   The  dev argument specifies the device context, which contains pointers
+   to all USB descriptors. The  interface argument specifies the interface
+   number. If a USB driver wants to bind itself to a particular device and
+   interface it has to return a pointer. This pointer normally references
+   the device driver's context structure.
+
+   Probing normally is done by checking the vendor and product identifications
+   or the class and subclass definitions. If they match the interface number
+   is compared with the ones supported by the driver. When probing is done
+   class based it might be necessary to parse some more USB descriptors because
+   the device properties can differ in a wide range.
+*/
+static void *auerswald_probe (struct usb_device *usbdev, unsigned int ifnum,
+			      const struct usb_device_id *id)
+{
+	pauerswald_t cp = NULL;
+	DECLARE_WAIT_QUEUE_HEAD (wqh);
+	unsigned int dtindex;
+	unsigned int u = 0;
+	char *pbuf;
+	int ret;
+
+	dbg ("probe: vendor id 0x%x, device id 0x%x ifnum:%d",
+	     usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);
+
+	/* See if the device offered us matches that we can accept */
+	if (usbdev->descriptor.idVendor != ID_AUERSWALD) return NULL;
+
+        /* we use only the first -and only- interface */
+        if (ifnum != 0) return NULL;
+
+	/* prevent module unloading while sleeping */
+	MOD_INC_USE_COUNT;
+
+	/* allocate memory for our device and intialize it */
+	cp = kmalloc (sizeof(auerswald_t), GFP_KERNEL);
+	if (cp == NULL) {
+		err ("out of memory");
+		goto pfail;
+	}
+
+	/* Initialize device descriptor */
+	memset (cp, 0, sizeof(auerswald_t));
+	init_MUTEX (&cp->mutex);
+	cp->usbdev = usbdev;
+	auerchain_init (&cp->controlchain);
+        auerbuf_init (&cp->bufctl);
+	init_waitqueue_head (&cp->bufferwait);
+
+	/* find a free slot in the device table */
+	down (&dev_table_mutex);
+	for (dtindex = 0; dtindex < AUER_MAX_DEVICES; ++dtindex) {
+		if (dev_table[dtindex] == NULL)
+			break;
+	}
+	if ( dtindex >= AUER_MAX_DEVICES) {
+		err ("more than %d devices plugged in, can not handle this device", AUER_MAX_DEVICES);
+		up (&dev_table_mutex);
+		goto pfail;
+	}
+
+	/* Give the device a name */
+	sprintf (cp->name, AU_PREFIX "%d", dtindex);
+
+	/* Store the index */
+	cp->dtindex = dtindex;
+	dev_table[dtindex] = cp;
+	up (&dev_table_mutex);
+
+	/* initialize the devfs node for this device and register it */
+	cp->devfs = devfs_register (usb_devfs_handle, cp->name,
+				    DEVFS_FL_DEFAULT, USB_MAJOR,
+				    AUER_MINOR_BASE + dtindex,
+				    S_IFCHR | S_IRUGO | S_IWUGO,
+				    &auerswald_fops, NULL);
+
+	/* Get the usb version of the device */
+	cp->version = cp->usbdev->descriptor.bcdDevice;
+	dbg ("Version is %X", cp->version);
+
+	/* allow some time to settle the device */
+	sleep_on_timeout (&wqh, HZ / 3 );
+
+	/* Try to get a suitable textual description of the device */
+	/* Device name:*/
+	ret = usb_string( cp->usbdev, AUSI_DEVICE, cp->dev_desc, AUSI_DLEN-1);
+	if (ret >= 0) {
+		u += ret;
+		/* Append Serial Number */
+		memcpy(&cp->dev_desc[u], ",Ser# ", 6);
+		u += 6;
+		ret = usb_string( cp->usbdev, AUSI_SERIALNR, &cp->dev_desc[u], AUSI_DLEN-u-1);
+		if (ret >= 0) {
+			u += ret;
+			/* Append subscriber number */
+			memcpy(&cp->dev_desc[u], ", ", 2);
+			u += 2;
+			ret = usb_string( cp->usbdev, AUSI_MSN, &cp->dev_desc[u], AUSI_DLEN-u-1);
+			if (ret >= 0) {
+				u += ret;
+			}
+		}
+	}
+	cp->dev_desc[u] = '\0';
+	info("device is a %s", cp->dev_desc);
+
+        /* get the maximum allowed control transfer length */
+        pbuf = (char *) kmalloc (2, GFP_KERNEL);    /* use an allocated buffer because of urb target */
+        if (!pbuf) {
+		err( "out of memory");
+		goto pfail;
+	}
+        ret = usb_control_msg(cp->usbdev,           /* pointer to device */
+                usb_rcvctrlpipe( cp->usbdev, 0 ),   /* pipe to control endpoint */
+                AUV_GETINFO,                        /* USB message request value */
+                AUT_RREQ,                           /* USB message request type value */
+                0,                                  /* USB message value */
+                AUDI_MBCTRANS,                      /* USB message index value */
+                pbuf,                               /* pointer to the receive buffer */
+                2,                                  /* length of the buffer */
+                HZ * 2);                            /* time to wait for the message to complete before timing out */
+        if (ret == 2) {
+	        cp->maxControlLength = le16_to_cpup(pbuf);
+                kfree(pbuf);
+                dbg("setup: max. allowed control transfersize is %d bytes", cp->maxControlLength);
+        } else {
+                kfree(pbuf);
+                err("setup: getting max. allowed control transfer length failed with error %d", ret);
+		goto pfail;
+        }
+
+	/* allocate a chain for the control messages */
+        if (auerchain_setup (&cp->controlchain, AUCH_ELEMENTS)) {
+		err ("out of memory");
+		goto pfail;
+	}
+
+        /* allocate buffers for control messages */
+	if (auerbuf_setup (&cp->bufctl, AU_RBUFFERS, cp->maxControlLength+AUH_SIZE)) {
+		err ("out of memory");
+		goto pfail;
+	}
+
+	/* start the interrupt endpoint */
+	if (auerswald_int_open (cp)) {
+		err ("int endpoint failed");
+		goto pfail;
+	}
+
+	/* all OK */
+	return cp;
+
+	/* Error exit: clean up the memory */
+pfail:	auerswald_delete (cp);
+	MOD_DEC_USE_COUNT;
+	return NULL;
+}
+
+
+/* Disconnect driver from a served device
+
+   This function is called whenever a device which was served by this driver
+   is disconnected.
+
+   The argument  dev specifies the device context and the  driver_context
+   returns a pointer to the previously registered  driver_context of the
+   probe function. After returning from the disconnect function the USB
+   framework completly deallocates all data structures associated with
+   this device. So especially the usb_device structure must not be used
+   any longer by the usb driver.
+*/
+static void auerswald_disconnect (struct usb_device *usbdev, void *driver_context)
+{
+	pauerswald_t cp = (pauerswald_t) driver_context;
+	unsigned int u;
+
+	down (&cp->mutex);
+	info ("device /dev/usb/%s now disconnecting", cp->name);
+
+	/* remove from device table */
+	/* Nobody can open() this device any more */
+	down (&dev_table_mutex);
+	dev_table[cp->dtindex] = NULL;
+	up (&dev_table_mutex);
+
+	/* remove our devfs node */
+	/* Nobody can see this device any more */
+	devfs_unregister (cp->devfs);
+
+	/* Stop the interrupt endpoint */
+	auerswald_int_release (cp);
+
+	/* remove the control chain allocated in auerswald_probe
+	   This has the benefit of
+	   a) all pending (a)synchronous urbs are unlinked
+	   b) all buffers dealing with urbs are reclaimed
+	*/
+	auerchain_free (&cp->controlchain);
+
+	if (cp->open_count == 0) {
+		/* nobody is using this device. So we can clean up now */
+		up (&cp->mutex);/* up() is possible here because no other task
+				   can open the device (see above). I don't want
+				   to kfree() a locked mutex. */
+		auerswald_delete (cp);
+	} else {
+		/* device is used. Remove the pointer to the
+		   usb device (it's not valid any more). The last
+		   release() will do the clean up */
+		cp->usbdev = NULL;
+		up (&cp->mutex);
+		/* Terminate waiting writers */
+		wake_up (&cp->bufferwait);
+		/* Inform all waiting readers */
+		for ( u = 0; u < AUH_TYPESIZE; u++) {
+			pauerscon_t scp = cp->services[u];
+			if (scp) scp->disconnect( scp);
+		}
+	}
+
+	/* The device releases this module */
+	MOD_DEC_USE_COUNT;
+}
+
+/* Descriptor for the devices which are served by this driver.
+   NOTE: this struct is parsed by the usbmanager install scripts.
+         Don't change without caution!
+*/
+static struct usb_device_id auerswald_ids [] = {
+	{ USB_DEVICE (ID_AUERSWALD, 0x00C0) },          /* COMpact 2104 USB */
+	{ USB_DEVICE (ID_AUERSWALD, 0x00DB) },          /* COMpact 4410/2206 USB */
+	{ USB_DEVICE (ID_AUERSWALD, 0x00F1) },          /* Comfort 2000 System Telephone */
+	{ USB_DEVICE (ID_AUERSWALD, 0x00F2) },          /* Comfort 1200 System Telephone */
+        { }			                        /* Terminating entry */
+};
+
+/* Standard module device table */
+MODULE_DEVICE_TABLE (usb, auerswald_ids);
+
+/* Standard usb driver struct */
+static struct usb_driver auerswald_driver = {
+	name:		"auerswald",
+	probe:		auerswald_probe,
+	disconnect:	auerswald_disconnect,
+	fops:		&auerswald_fops,
+	minor:		AUER_MINOR_BASE,
+	id_table:	auerswald_ids,
+};
+
+
+/* --------------------------------------------------------------------- */
+/* Module loading/unloading                                              */
+
+/* Driver initialisation. Called after module loading.
+   NOTE: there is no concurrency at _init
+*/
+static int __init auerswald_init (void)
+{
+	int result;
+	dbg ("init");
+
+	/* initialize the device table */
+	memset (&dev_table, 0, sizeof(dev_table));
+	init_MUTEX (&dev_table_mutex);
+
+	/* register driver at the USB subsystem */
+	result = usb_register (&auerswald_driver);
+	if (result < 0) {
+		err ("driver could not be registered");
+		return -1;
+	}
+	return 0;
+}
+
+/* Driver deinit. Called before module removal.
+   NOTE: there is no concurrency at _cleanup
+*/
+static void __exit auerswald_cleanup (void)
+{
+	dbg ("cleanup");
+	usb_deregister (&auerswald_driver);
+}
+
+/* --------------------------------------------------------------------- */
+/* Linux device driver module description                                */
+
+MODULE_AUTHOR (DRIVER_AUTHOR);
+MODULE_DESCRIPTION (DRIVER_DESC);
+
+module_init (auerswald_init);
+module_exit (auerswald_cleanup);
+
+/* --------------------------------------------------------------------- */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/brlvger.c linux/drivers/usb/brlvger.c
--- linux.orig/drivers/usb/brlvger.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/brlvger.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,1034 @@
+/*
+ *      Tieman Voyager braille display USB driver.
+ *
+ *      Copyright 2001-2002 Stephane Dalton <sdalton@videotron.ca>
+ *                      and Stéphane Doyon  <s.doyon@videotron.ca>
+ *            Maintained by Stéphane Doyon  <s.doyon@videotron.ca>.
+ */
+/*
+ *  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
+ */
+/* History:
+ * 0.8 April 2002: Integration into the kernel tree.
+ * 0.7 October 2001: First public release as a module, distributed with
+ *     the BRLTTY package (beta versions around 2.99y).
+ */
+
+#define DRIVER_VERSION "v0.8"
+#define DATE "April 2002"
+#define DRIVER_AUTHOR \
+	"Stephane Dalton <sdalton@videotron.ca> " \
+	"and Stéphane Doyon <s.doyon@videotron.ca>"
+#define DRIVER_DESC "Tieman Voyager braille display USB driver for Linux 2.4"
+#define DRIVER_SHORTDESC "Voyager"
+
+#define BANNER \
+	KERN_INFO DRIVER_SHORTDESC " " DRIVER_VERSION " (" DATE ")\n" \
+	KERN_INFO "   by " DRIVER_AUTHOR "\n"
+
+static const char longbanner[] = {
+	DRIVER_DESC ", " DRIVER_VERSION " (" DATE "), by " DRIVER_AUTHOR
+};
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/poll.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/brlvger.h>
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
+
+/* Module parameters */
+
+static int debug = 1;
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug level, 0-3");
+
+static int write_repeats = 2;
+MODULE_PARM(write_repeats, "i");
+MODULE_PARM_DESC(write_repeats, "Hack: repetitions for command to "
+		 "display braille pattern");
+		 /* to get rid of weird extra dots (perhaps only on
+		    early hardware versions?) */
+
+static int stall_tries = 3;
+MODULE_PARM(stall_tries, "i");
+MODULE_PARM_DESC(stall_tries, "Hack: retransmits of stalled USB "
+		 "control messages");
+                 /* broken early hardware versions? */
+
+#define BRLVGER_RAW_VOLTAGE 89
+/* from 0->300V to 255->200V, we are told 265V is normal operating voltage,
+   but we don't know the scale. Assuming it is linear. */
+static int raw_voltage = BRLVGER_RAW_VOLTAGE;
+MODULE_PARM(raw_voltage, "i");
+MODULE_PARM_DESC(raw_voltage, "Parameter for the call to SET_DISPLAY_VOLTAGE");
+
+
+/* protocol and display type defines */
+#define MAX_BRLVGER_CELLS 72
+#define MAX_INTERRUPT_DATA 8
+/* control message request types */
+#define BRLVGER_READ_REQ 0xC2
+#define BRLVGER_WRITE_REQ 0x42
+/* control message request codes */
+#define BRLVGER_SET_DISPLAY_ON 0
+#define BRLVGER_SET_DISPLAY_VOLTAGE 1
+#define BRLVGER_GET_SERIAL 3
+#define BRLVGER_GET_HWVERSION 4
+#define BRLVGER_GET_FWVERSION 5
+#define BRLVGER_GET_LENGTH 6
+#define BRLVGER_SEND_BRAILLE 7
+#define BRLVGER_BEEP 9
+#if 0 /* not used and not sure they're working */
+#define BRLVGER_GET_DISPLAY_VOLTAGE 2
+#define BRLVGER_GET_CURRENT 8
+#endif
+
+/* Prototypes */
+static void *brlvger_probe (struct usb_device *dev, unsigned ifnum,
+			    const struct usb_device_id *id);
+static void brlvger_disconnect(struct usb_device *dev, void *ptr);
+static int brlvger_open(struct inode *inode, struct file *file);
+static int brlvger_release(struct inode *inode, struct file *file);
+static ssize_t brlvger_write(struct file *file, const char *buffer,
+			     size_t count, loff_t *pos);
+static ssize_t brlvger_read(struct file *file, char *buffer,
+			    size_t count, loff_t *unused_pos);
+static int brlvger_ioctl(struct inode *inode, struct file *file,
+			 unsigned cmd, unsigned long arg);
+static unsigned brlvger_poll(struct file *file, poll_table *wait);
+static loff_t brlvger_llseek(struct file * file, loff_t offset, int orig);
+static void intr_callback(struct urb *urb);
+struct brlvger_priv;
+static int brlvger_get_hw_version(struct brlvger_priv *priv,
+				  unsigned char *verbuf);
+static int brlvger_get_fw_version(struct brlvger_priv *priv,
+				  unsigned char *buf);
+static int brlvger_get_serial(struct brlvger_priv *priv,
+			      unsigned char *buf);
+static int brlvger_get_display_length(struct brlvger_priv *priv);
+static int brlvger_set_display_on_off(struct brlvger_priv *priv, __u16 on);
+static int brlvger_beep(struct brlvger_priv *priv, __u16 duration);
+static int brlvger_set_display_voltage(struct brlvger_priv *priv,
+				       __u16 voltage);
+static int mycontrolmsg(const char *funcname,
+                        struct brlvger_priv *priv, unsigned pipe_dir,
+                        __u8 request, __u8 requesttype, __u16 value,
+                        __u16 index, void *data, __u16 size);
+
+#define controlmsg(priv,pipe_dir,a,b,c,d,e,f) \
+     mycontrolmsg(__FUNCTION__, priv, pipe_dir, \
+                  a,b,c,d,e,f)
+#define sndcontrolmsg(priv,a,b,c,d,e,f) \
+    controlmsg(priv, 0, a,b,c,d,e,f)
+#define rcvcontrolmsg(priv,a,b,c,d,e,f) \
+    controlmsg(priv, USB_DIR_IN, a,b,c,d,e,f)
+
+extern devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
+
+/* ----------------------------------------------------------------------- */
+
+/* Data */
+
+/* key event queue size */
+#define MAX_INTERRUPT_BUFFER 10
+
+/* private state */
+struct brlvger_priv {
+	struct usb_device   *dev; /* USB device handle */
+	struct usb_endpoint_descriptor *in_interrupt;
+	struct urb *intr_urb;
+	devfs_handle_t devfs;
+
+	int subminor; /* which minor dev #? */
+
+	unsigned char hwver[BRLVGER_HWVER_SIZE]; /* hardware version */
+	unsigned char fwver[BRLVGER_FWVER_SIZE]; /* firmware version */
+	unsigned char serialnum[BRLVGER_SERIAL_SIZE];
+
+	int llength; /* logical length */
+	int plength; /* physical length */
+
+	__u8 obuf[MAX_BRLVGER_CELLS];
+	__u8 intr_buff[MAX_INTERRUPT_DATA];
+	__u8 event_queue[MAX_INTERRUPT_BUFFER][MAX_INTERRUPT_DATA];
+	atomic_t intr_idx, read_idx;
+	spinlock_t intr_idx_lock; /* protects intr_idx */
+	wait_queue_head_t read_wait;
+
+	int opened;
+	struct semaphore open_sem; /* protects ->opened */
+	struct semaphore dev_sem; /* protects ->dev */
+};
+
+/* Globals */
+
+/* Table of connected devices, a different minor for each. */
+static struct brlvger_priv *display_table[ MAX_NR_BRLVGER_DEVS ];
+
+/* Mutex for the operation of removing a device from display_table */
+static DECLARE_MUTEX(disconnect_sem);
+
+/* For blocking open */
+static DECLARE_WAIT_QUEUE_HEAD(open_wait);
+
+/* Some print macros */
+#ifdef dbg
+#undef dbg
+#endif
+#ifdef info
+#undef info
+#endif
+#ifdef err
+#undef err
+#endif
+#define info(args...) \
+    ({ printk(KERN_INFO "Voyager: " args); \
+       printk("\n"); })
+#define err(args...) \
+    ({ printk(KERN_ERR "Voyager: " args); \
+       printk("\n"); })
+#define dbgprint(args...) \
+    ({ printk(KERN_DEBUG "Voyager: " __FUNCTION__ ": " args); \
+       printk("\n"); })
+#define dbg(args...) \
+    ({ if(debug >= 1) dbgprint(args); })
+#define dbg2(args...) \
+    ({ if(debug >= 2) dbgprint(args); })
+#define dbg3(args...) \
+    ({ if(debug >= 3) dbgprint(args); })
+
+/* ----------------------------------------------------------------------- */
+
+/* Driver registration */
+
+static struct usb_device_id brlvger_ids [] = {
+	{ USB_DEVICE(0x0798, 0x0001) },
+	{ }                     /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, brlvger_ids);
+
+static struct file_operations brlvger_fops =
+{
+	owner:		THIS_MODULE,
+	llseek:		brlvger_llseek,
+	read:		brlvger_read,
+	write:		brlvger_write,
+	ioctl:		brlvger_ioctl,
+	open:		brlvger_open,
+	release:	brlvger_release,
+	poll:		brlvger_poll,
+};
+
+static struct usb_driver brlvger_driver =
+{
+	name:		"brlvger",
+	probe:		brlvger_probe,
+	disconnect:	brlvger_disconnect,
+	fops:		&brlvger_fops,
+	minor:		BRLVGER_MINOR,
+	id_table:	brlvger_ids,
+};
+
+static int
+__init brlvger_init (void)
+{
+	printk(BANNER);
+
+	if(stall_tries < 1 || write_repeats < 1)
+	  return -EINVAL;
+
+	memset(display_table, 0, sizeof(display_table));
+
+	if (usb_register(&brlvger_driver)) {
+		err("USB registration failed");
+		return -ENOSYS;
+	}
+
+	return 0;
+}
+
+static void
+__exit brlvger_cleanup (void)
+{
+	usb_deregister (&brlvger_driver);
+	dbg("Driver unregistered");
+}
+
+module_init (brlvger_init);
+module_exit (brlvger_cleanup);
+
+/* ----------------------------------------------------------------------- */
+
+/* Probe and disconnect functions */
+
+static void *
+brlvger_probe (struct usb_device *dev, unsigned ifnum,
+	       const struct usb_device_id *id)
+{
+	struct brlvger_priv *priv = NULL;
+	int i;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_interface_descriptor *actifsettings;
+	/* protects against reentrance: once we've found a free slot
+	   we reserve it.*/
+	static DECLARE_MUTEX(reserve_sem);
+        char devfs_name[16];
+
+	actifsettings = dev->actconfig->interface->altsetting;
+
+	if( dev->descriptor.bNumConfigurations != 1
+			|| dev->config->bNumInterfaces != 1 
+			|| actifsettings->bNumEndpoints != 1 ) {
+		err ("Bogus braille display config info");
+		return NULL;
+	}
+
+	endpoint = actifsettings->endpoint;
+	if (!(endpoint->bEndpointAddress & 0x80) ||
+		((endpoint->bmAttributes & 3) != 0x03)) {
+		err ("Bogus braille display config info, wrong endpoints");
+		return NULL;
+	}
+
+	down(&reserve_sem);
+
+	for( i = 0; i < MAX_NR_BRLVGER_DEVS; i++ )
+		if( display_table[i] == NULL )
+			break;
+
+	if( i == MAX_NR_BRLVGER_DEVS ) {
+		err( "This driver cannot handle more than %d "
+				"braille displays", MAX_NR_BRLVGER_DEVS);
+		goto error;
+	}
+
+	if( !(priv = kmalloc (sizeof *priv, GFP_KERNEL)) ){
+		err("No more memory");
+		goto error;
+	}
+
+	memset(priv, 0, sizeof(*priv));
+	atomic_set(&priv->intr_idx, 0);
+	atomic_set(&priv->read_idx, MAX_INTERRUPT_BUFFER-1);
+	spin_lock_init(&priv->intr_idx_lock);
+	init_waitqueue_head(&priv->read_wait);
+	/* opened is memset'ed to 0 */
+	init_MUTEX(&priv->open_sem);
+	init_MUTEX(&priv->dev_sem);
+
+	priv->subminor = i;
+
+	/* we found a interrupt in endpoint */
+	priv->in_interrupt = endpoint;
+
+	priv->dev = dev;
+
+	if(brlvger_get_hw_version(priv, priv->hwver) <0) {
+		err("Unable to get hardware version");
+		goto error;
+	}
+	dbg("Hw ver %d.%d", priv->hwver[0], priv->hwver[1]);
+	if(brlvger_get_fw_version(priv, priv->fwver) <0) {
+		err("Unable to get firmware version");
+		goto error;
+	}
+	dbg("Fw ver: %s", priv->fwver);
+
+	if(brlvger_get_serial(priv, priv->serialnum) <0) {
+		err("Unable to get serial number");
+		goto error;
+	}
+	dbg("Serial number: %s", priv->serialnum);
+
+	if( (priv->llength = brlvger_get_display_length(priv)) <0 ){
+		err("Unable to get display length");
+		goto error;
+	}
+	switch(priv->llength) {
+	case 48:
+		priv->plength = 44;
+		break;
+	case 72:
+		priv->plength = 70;
+		break;
+	default:
+		err("Unsupported display length: %d", priv->llength);
+		goto error;
+	};
+	dbg("Display length: %d", priv->plength);
+
+	sprintf(devfs_name, "brlvger%d", priv->subminor);
+	priv->devfs = devfs_register(usb_devfs_handle, devfs_name,
+				     DEVFS_FL_DEFAULT, USB_MAJOR,
+				     BRLVGER_MINOR+priv->subminor,
+				     S_IFCHR |S_IRUSR|S_IWUSR |S_IRGRP|S_IWGRP,
+				     &brlvger_fops, NULL);
+	if (!priv->devfs) {
+#ifdef CONFIG_DEVFS_FS
+		err("devfs node registration failed");
+#endif
+	}
+
+	display_table[i] = priv;
+
+	info( "Braille display %d is device major %d minor %d",
+				i, USB_MAJOR, BRLVGER_MINOR + i);
+
+	/* Tell anyone waiting on a blocking open */
+	wake_up_interruptible(&open_wait);
+
+	goto out;
+
+ error:
+	if(priv) {
+		kfree( priv );
+		priv = NULL;
+	}
+
+ out:
+	up(&reserve_sem);
+	return priv;
+}
+
+static void
+brlvger_disconnect(struct usb_device *dev, void *ptr)
+{
+	struct brlvger_priv *priv = (struct brlvger_priv *)ptr;
+	int r;
+
+	if(priv){
+		info("Display %d disconnecting", priv->subminor);
+
+		devfs_unregister(priv->devfs);
+		
+		down(&disconnect_sem);
+		display_table[priv->subminor] = NULL;
+		up(&disconnect_sem);
+
+		down(&priv->open_sem);
+		down(&priv->dev_sem);
+		if(priv->opened) {
+			/* Disable interrupts */
+			if((r = usb_unlink_urb(priv->intr_urb)) <0)
+				err("usb_unlink_urb returns %d", r);
+			usb_free_urb(priv->intr_urb);
+			/* mark device as dead and prevent control
+			   messages to it */
+			priv->dev = NULL;
+			/* Tell anyone hung up on a read that it
+			   won't be coming */
+			wake_up_interruptible(&priv->read_wait);
+			up(&priv->dev_sem);
+			up(&priv->open_sem);
+		}else
+			/* no corresponding up()s */
+			kfree(priv);
+	}
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* fops implementation */
+
+static int
+brlvger_open(struct inode *inode, struct file *file)
+{
+	int devnum = MINOR (inode->i_rdev);
+	struct brlvger_priv *priv;
+	int n, ret;
+
+	if (devnum < BRLVGER_MINOR
+	    || devnum >= (BRLVGER_MINOR + MAX_NR_BRLVGER_DEVS))
+		return -ENXIO;
+
+	n = devnum - BRLVGER_MINOR;
+
+	MOD_INC_USE_COUNT;
+
+	do {
+		down(&disconnect_sem);
+		priv = display_table[n];
+		
+		if(!priv) {
+			up(&disconnect_sem);
+			if (file->f_flags & O_NONBLOCK) {
+				dbg3("Failing non-blocking open: "
+				     "device %d not connected", n);
+				MOD_DEC_USE_COUNT;
+				return -EAGAIN;
+			}
+			/* Blocking open. One global wait queue will
+			   suffice. We wait until a device for the selected
+			   minor is connected. */
+			dbg2("Waiting for device %d to be connected", n);
+			ret = wait_event_interruptible(open_wait,
+						       display_table[n]
+						       != NULL);
+			if(ret) {
+				dbg2("Interrupted wait for device %d", n);
+				MOD_DEC_USE_COUNT;
+				return ret;
+			}
+		}
+	} while(!priv);
+	/* We grabbed an existing device. */
+
+	if(down_interruptible(&priv->open_sem))
+		return -ERESTARTSYS;
+	up(&disconnect_sem);
+
+	/* Only one process can open each device, no sharing. */
+	ret = -EBUSY;
+	if(priv->opened)
+		goto error;
+
+	dbg("Opening display %d", priv->subminor);
+
+	/* Setup interrupt handler for receiving key input */
+	priv->intr_urb = usb_alloc_urb(0);
+	if(!priv->intr_urb) {
+		err("Unable to allocate URB");
+		goto error;
+	}
+	FILL_INT_URB( priv->intr_urb, priv->dev,
+			usb_rcvintpipe(priv->dev,
+				       priv->in_interrupt->bEndpointAddress),
+			priv->intr_buff, sizeof(priv->intr_buff),
+			intr_callback, priv, priv->in_interrupt->bInterval);
+	if((ret = usb_submit_urb(priv->intr_urb)) <0){
+		err("Error %d while submitting URB", ret);
+		goto error;
+	}
+
+	/* Set voltage */
+	if(brlvger_set_display_voltage(priv, raw_voltage) <0) {
+		err("Unable to set voltage");
+		goto error;
+	}
+
+	/* Turn display on */
+	if((ret = brlvger_set_display_on_off(priv, 1)) <0) {
+		err("Error %d while turning display on", ret);
+		goto error;
+	}
+
+	/* Mark as opened, so disconnect cannot free priv. */
+	priv->opened = 1;
+
+	file->private_data = priv;
+
+	ret = 0;
+	goto out;
+
+ error:
+	MOD_DEC_USE_COUNT;
+ out:
+	up(&priv->open_sem);
+	return ret;
+}
+
+static int
+brlvger_release(struct inode *inode, struct file *file)
+{
+	struct brlvger_priv *priv = file->private_data;
+	int r;
+
+	/* Turn display off. Safe even if disconnected. */
+	brlvger_set_display_on_off(priv, 0);
+
+	/* mutex with disconnect and with open */
+	down(&priv->open_sem);
+
+	if(!priv->dev) {
+		dbg("Releasing disconnected device %d", priv->subminor);
+		/* no up(&priv->open_sem) */
+		kfree(priv);
+	}else{
+		dbg("Closing display %d", priv->subminor);
+		/* Disable interrupts */
+		if((r = usb_unlink_urb(priv->intr_urb)) <0)
+			err("usb_unlink_urb returns %d", r);
+		usb_free_urb(priv->intr_urb);
+		priv->opened = 0;
+		up(&priv->open_sem);
+	}
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+static ssize_t
+brlvger_write(struct file *file, const char *buffer,
+	      size_t count, loff_t *pos)
+{
+	struct brlvger_priv *priv = file->private_data;
+	char buf[MAX_BRLVGER_CELLS];
+	int ret;
+	int rs, off;
+	__u16 written;
+
+	if(!priv->dev)
+		return -ENOLINK;
+
+	off = *pos;
+
+	if(off > priv->plength)
+		return -ESPIPE;;
+
+	rs = priv->plength - off;
+
+	if(count > rs)
+		count = rs;
+	written = count;
+
+	if (copy_from_user (buf, buffer, count ) )
+		return -EFAULT;
+
+	memset(priv->obuf, 0xaa, sizeof(priv->obuf));
+
+	/* Firmware supports multiples of 8cells, so some cells are absent
+	   and for some reason there actually are holes! euurkkk! */
+
+	if( priv->plength == 44 ) {
+		/* Two ghost cells at the beginning of the display, plus
+		   two more after the sixth physical cell. */
+		if(off > 5) {
+			off +=4;
+			memcpy(priv->obuf, buf, count);
+		}else{
+			int firstpart = 6 - off;
+			
+#ifdef WRITE_DEBUG
+			dbg3("off: %d, rs: %d, count: %d, firstpart: %d",
+			     off, rs, count, firstpart);
+#endif
+
+			firstpart = (firstpart < count) ? firstpart : count;
+
+#ifdef WRITE_DEBUG
+			dbg3("off: %d", off);
+			dbg3("firstpart: %d", firstpart);
+#endif
+
+			memcpy(priv->obuf, buf, firstpart);
+
+			if(firstpart != count) {
+				int secondpart = count - firstpart;
+#ifdef WRITE_DEBUG
+				dbg3("secondpart: %d", secondpart);
+#endif
+
+				memcpy(priv->obuf+(firstpart+2),
+				       buf+firstpart, secondpart);
+				written +=2;
+			}
+
+			off +=2;
+
+#ifdef WRITE_DEBUG
+			dbg3("off: %d, rs: %d, count: %d, firstpart: %d, "
+				"written: %d", 	off, rs, count, firstpart, written);
+#endif
+		}
+	}else{
+		/* Two ghost cells at the beginningg of the display. */
+		memcpy(priv->obuf, buf, count);
+		off += 2;
+	}
+
+	{
+		int repeat = write_repeats;
+		/* Dirty hack: sometimes some of the dots are wrong and somehow
+		   right themselves if the command is repeated. */
+		while(repeat--) {
+			ret = sndcontrolmsg(priv,
+				BRLVGER_SEND_BRAILLE, BRLVGER_WRITE_REQ, 0,
+				off, priv->obuf, written);
+			if(ret <0)
+				return ret;
+		}
+	}
+
+	return count;
+}
+
+static int
+read_index(struct brlvger_priv *priv)
+{
+	int intr_idx, read_idx;
+
+	read_idx = atomic_read(&priv->read_idx);
+	read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
+
+	intr_idx = atomic_read(&priv->intr_idx);
+
+	return(read_idx == intr_idx ? -1 : read_idx);
+}
+
+static ssize_t
+brlvger_read(struct file *file, char *buffer,
+	     size_t count, loff_t *unused_pos)
+{
+	struct brlvger_priv *priv = file->private_data;
+	int read_idx;
+
+	if(count != MAX_INTERRUPT_DATA)
+		return -EINVAL;
+
+	if(!priv->dev)
+		return -ENOLINK;
+
+	if((read_idx = read_index(priv)) == -1) {
+		/* queue empty */
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		else{
+			int r = wait_event_interruptible(priv->read_wait,
+							 (!priv->dev || (read_idx = read_index(priv)) != -1));
+			if(!priv->dev)
+				return -ENOLINK;
+			if(r)
+				return r;
+			if(read_idx == -1)
+				/* should not happen */
+				return 0;
+		}
+	}
+
+	if (copy_to_user (buffer, priv->event_queue[read_idx], count) )
+		return( -EFAULT);
+
+	atomic_set(&priv->read_idx, read_idx);
+	/* Multiple opens are not allowed. Yet on SMP, two processes could
+	   read at the same time (on a shared file descriptor); then it is not
+	   deterministic whether or not they will get duplicates of a key
+	   event. */
+	return MAX_INTERRUPT_DATA;
+}
+
+static int
+brlvger_ioctl(struct inode *inode, struct file *file,
+	      unsigned cmd, unsigned long arg)
+{
+	struct brlvger_priv *priv = file->private_data;
+
+	if(!priv->dev)
+		return -ENOLINK;
+
+	switch(cmd) {
+	case BRLVGER_GET_INFO: {
+		struct brlvger_info vi;
+
+		strncpy(vi.driver_version, DRIVER_VERSION,
+			sizeof(vi.driver_version));
+		vi.driver_version[sizeof(vi.driver_version)-1] = 0;
+		strncpy(vi.driver_banner, longbanner,
+			sizeof(vi.driver_banner));
+		vi.driver_banner[sizeof(vi.driver_banner)-1] = 0;
+
+		vi.display_length = priv->plength;
+		
+		memcpy(&vi.hwver, priv->hwver, BRLVGER_HWVER_SIZE);
+		memcpy(&vi.fwver, priv->fwver, BRLVGER_FWVER_SIZE);
+		memcpy(&vi.serialnum, priv->serialnum, BRLVGER_SERIAL_SIZE);
+
+		if(copy_to_user((void *)arg, &vi, sizeof(vi)))
+			return -EFAULT;
+		return 0;
+	}
+	case BRLVGER_DISPLAY_ON:
+		return brlvger_set_display_on_off(priv, 1);
+	case BRLVGER_DISPLAY_OFF:
+		return brlvger_set_display_on_off(priv, 0);
+	case BRLVGER_BUZZ: {
+		__u16 duration;
+		if(get_user(duration, (__u16 *)arg))
+			return -EFAULT;
+		return brlvger_beep(priv, duration);
+	}
+
+#if 0 /* Underlying commands don't seem to work for some reason; not clear if
+	 we'd want to export these anyway. */
+	case BRLVGER_SET_VOLTAGE: {
+		__u16 voltage;
+		if(get_user(voltage, (__u16 *)arg))
+			return -EFAULT;
+		return brlvger_set_display_voltage(priv, voltage);
+	}
+	case BRLVGER_GET_VOLTAGE: {
+		__u8 voltage;
+		int r = brlvger_get_display_voltage(priv);
+		if(r <0)
+			return r;
+		voltage = r;
+		if(put_user(voltage, (__u8 *)arg))
+			return -EFAULT;
+		return 0;
+	}
+#endif
+	default:
+		return -EINVAL;
+	};
+}
+
+static loff_t
+brlvger_llseek(struct file *file, loff_t offset, int orig)
+{
+	struct brlvger_priv *priv = file->private_data;
+
+	if(!priv->dev)
+		return -ENOLINK;
+
+	switch (orig) {
+		case 0:
+			/*  nothing to do */
+			break;
+		case 1:
+			offset +=file->f_pos;
+			break;
+		case 2:
+			offset += priv->plength;
+		default:
+			return -EINVAL;
+	}
+
+	if((offset >= priv->plength) || (offset < 0))
+		return -EINVAL;
+
+	return (file->f_pos = offset);
+}
+
+static unsigned
+brlvger_poll(struct file *file, poll_table *wait) 
+{
+	struct brlvger_priv *priv = file->private_data;
+
+	if(!priv->dev)
+		return POLLERR | POLLHUP;
+
+	poll_wait(file, &priv->read_wait, wait);
+
+	if(!priv->dev)
+		return POLLERR | POLLHUP;
+	if(read_index(priv) != -1)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+static void
+intr_callback(struct urb *urb)
+{
+	struct brlvger_priv *priv = urb->context;
+	int intr_idx, read_idx;
+
+	if( urb->status ) {
+		if(urb->status == -ETIMEDOUT)
+			dbg2("Status -ETIMEDOUT, "
+			     "probably disconnected");
+		else if(urb->status != -ENOENT)
+			err("Status: %d", urb->status);
+		return;
+	}
+
+	read_idx = atomic_read(&priv->read_idx);
+	spin_lock(&priv->intr_idx_lock);
+	intr_idx = atomic_read(&priv->intr_idx);
+	if(read_idx == intr_idx) {
+		dbg2("Queue full, dropping braille display input");
+		spin_unlock(&priv->intr_idx_lock);
+		return;	/* queue full */
+	}
+
+	memcpy(priv->event_queue[intr_idx], urb->transfer_buffer,
+	       MAX_INTERRUPT_DATA);
+
+	intr_idx = (++intr_idx == MAX_INTERRUPT_BUFFER)? 0 : intr_idx;
+	atomic_set(&priv->intr_idx, intr_idx);
+	spin_unlock(&priv->intr_idx_lock);
+
+	wake_up_interruptible(&priv->read_wait);
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* Hardware access functions */
+
+static int
+mycontrolmsg(const char *funcname,
+	     struct brlvger_priv *priv, unsigned pipe_dir,
+	     __u8 request, __u8 requesttype, __u16 value,
+	     __u16 index, void *data, __u16 size)
+{
+	int ret=0, tries = stall_tries;
+
+	/* Make sure the device was not disconnected */
+	if(down_interruptible(&priv->dev_sem))
+		return -ERESTARTSYS;
+	if(!priv->dev) {
+		up(&priv->dev_sem);
+		return -ENOLINK;
+	}
+
+	/* Dirty hack for retransmission: stalls and fails all the time
+	   without this on the hardware we tested. */
+	while(tries--) {
+		ret = usb_control_msg(priv->dev,
+		    usb_sndctrlpipe(priv->dev,0) |pipe_dir,
+		    request, requesttype, value,
+		    index, data, size,
+		    HZ);
+		if(ret != -EPIPE)
+			break;
+		dbg2("Stalled, remaining %d tries", tries);
+	}
+	up(&priv->dev_sem);
+	if(ret <0) {
+		err("%s: usb_control_msg returns %d",
+				funcname, ret);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int
+brlvger_get_hw_version(struct brlvger_priv *priv, unsigned char *verbuf)
+{
+	return rcvcontrolmsg(priv,
+	    BRLVGER_GET_HWVERSION, BRLVGER_READ_REQ, 0,
+	    0, verbuf, BRLVGER_HWVER_SIZE);
+	/* verbuf should be 2 bytes */
+}
+
+static int
+brlvger_get_fw_version(struct brlvger_priv *priv, unsigned char *buf)
+{
+	unsigned char rawbuf[(BRLVGER_FWVER_SIZE-1)*2+2];
+	int i, len;
+	int r = rcvcontrolmsg(priv,
+			      BRLVGER_GET_FWVERSION, BRLVGER_READ_REQ, 0,
+			      0, rawbuf, sizeof(rawbuf));
+	if(r<0)
+		return r;
+
+	/* If I guess correctly: succession of 16bit words, the string is
+           formed of the first byte of each of these words. First byte in
+           buffer indicates total length of data; not sure what second byte is
+           for. */
+	len = rawbuf[0]-2;
+	if(len<0)
+		len = 0;
+	else if(len+1 > BRLVGER_FWVER_SIZE)
+		len = BRLVGER_FWVER_SIZE-1;
+	for(i=0; i<len; i++)
+		buf[i] = rawbuf[2+2*i];
+	buf[i] = 0;
+	return 0;
+}
+
+static int
+brlvger_get_serial(struct brlvger_priv *priv, unsigned char *buf)
+{
+	unsigned char rawserial[BRLVGER_SERIAL_BIN_SIZE];
+	int i;
+	int r = rcvcontrolmsg(priv,
+			      BRLVGER_GET_SERIAL, BRLVGER_READ_REQ, 0,
+			      0, rawserial, sizeof(rawserial));
+	if(r<0)
+		return r;
+
+	for(i=0; i<BRLVGER_SERIAL_BIN_SIZE; i++) {
+#define NUM_TO_HEX(n) (((n)>9) ? (n)+'A' : (n)+'0')
+		buf[2*i] = NUM_TO_HEX(rawserial[i] >>4);
+		buf[2*i+1] = NUM_TO_HEX(rawserial[i] &0xf);
+	}
+	buf[2*i] = 0;
+	return 0;
+}
+
+static int
+brlvger_get_display_length(struct brlvger_priv *priv)
+{
+	unsigned char data[2];
+	int ret = rcvcontrolmsg(priv,
+	    BRLVGER_GET_LENGTH, BRLVGER_READ_REQ, 0,
+	    0, data, 2);
+	if(ret<0)
+		return ret;
+	return data[1];
+}
+
+static int
+brlvger_beep(struct brlvger_priv *priv, __u16 duration)
+{
+	return sndcontrolmsg(priv,
+	    BRLVGER_BEEP, BRLVGER_WRITE_REQ, duration,
+	    0, NULL, 0);
+}
+
+static int
+brlvger_set_display_on_off(struct brlvger_priv *priv, __u16 on)
+{
+	dbg2("Turning display %s", ((on) ? "on" : "off"));
+	return sndcontrolmsg(priv,
+	    BRLVGER_SET_DISPLAY_ON,	BRLVGER_WRITE_REQ, on,
+	    0, NULL, 0);
+}
+
+static int
+brlvger_set_display_voltage(struct brlvger_priv *priv, __u16 voltage)
+{
+	dbg("SET_DISPLAY_VOLTAGE to %u", voltage);
+        return sndcontrolmsg(priv,
+	     BRLVGER_SET_DISPLAY_VOLTAGE, BRLVGER_WRITE_REQ, voltage,
+	     0, NULL, 0);
+}
+
+#if 0 /* Had problems testing these commands. Not particularly useful anyway.*/
+
+static int
+brlvger_get_display_voltage(struct brlvger_priv *priv)
+{
+	__u8 voltage = 0;
+	int ret = rcvcontrolmsg(priv,
+	    BRLVGER_GET_DISPLAY_VOLTAGE, BRLVGER_READ_REQ, 0,
+	    0, &voltage, 1);
+	if(ret<0)
+		return ret;
+	return voltage;
+}
+
+static int
+brlvger_get_current(struct brlvger_priv *priv)
+{
+	unsigned char data;
+	int ret = rcvcontrolmsg(priv,
+	    BRLVGER_GET_CURRENT,	BRLVGER_READ_REQ,	0,
+	    0, &data, 1);
+	if(ret<0)
+		return ret;
+	return data;
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/catc.c linux/drivers/usb/catc.c
--- linux.orig/drivers/usb/catc.c	2001-11-13 17:19:41.000000000 +0000
+++ linux/drivers/usb/catc.c	2002-07-20 01:08:36.000000000 +0000
@@ -38,7 +38,9 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
+#include <linux/ethtool.h>
 #include <asm/bitops.h>
+#include <asm/uaccess.h>
 
 #undef DEBUG
 
@@ -48,9 +50,10 @@
  * Version information.
  */
 
-#define DRIVER_VERSION "v2.7"
+#define DRIVER_VERSION "v2.8"
 #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
 #define DRIVER_DESC "CATC EL1210A NetMate USB Ethernet driver"
+#define SHORT_DRIVER_DESC "EL1210A NetMate USB Ethernet"
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -259,11 +262,15 @@
 		} 
 	}
 
-	if (data[1] & 0x40)
+	if (data[1] & 0x40) {
+		netif_carrier_on(catc->netdev);
 		dbg("link ok");
+	}
 
-	if (data[1] & 0x20) 
+	if (data[1] & 0x20) {
+		netif_carrier_off(catc->netdev);
 		dbg("link bad");
+	}
 }
 
 /*
@@ -402,7 +409,7 @@
 {
 	struct catc *catc = urb->context;
 	struct ctrl_queue *q;
-	long flags;
+	unsigned long flags;
 
 	if (urb->status)
 		dbg("ctrl_done, status %d, len %d.", urb->status, urb->actual_length);
@@ -436,7 +443,7 @@
 {
 	struct ctrl_queue *q;
 	int retval = 0;
-	long flags;
+	unsigned long flags;
 
 	spin_lock_irqsave(&catc->ctrl_lock, flags);
 	
@@ -564,6 +571,54 @@
 }
 
 /*
+ * ioctl's
+ */
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+        struct catc *catc = dev->priv;
+        u32 cmd;
+	char tmp[40];
+        
+        if (get_user(cmd, (u32 *)useraddr))
+                return -EFAULT;
+
+        switch (cmd) {
+        /* get driver info */
+        case ETHTOOL_GDRVINFO: {
+                struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+                strncpy(info.driver, SHORT_DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
+                strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
+		sprintf(tmp, "usb%d:%d", catc->usbdev->bus->busnum, catc->usbdev->devnum);
+                strncpy(info.bus_info, tmp,ETHTOOL_BUSINFO_LEN);
+                if (copy_to_user(useraddr, &info, sizeof(info)))
+                        return -EFAULT;
+                return 0;
+        }
+        /* get link status */
+        case ETHTOOL_GLINK: {
+                struct ethtool_value edata = {ETHTOOL_GLINK};
+                edata.data = netif_carrier_ok(dev);
+                if (copy_to_user(useraddr, &edata, sizeof(edata)))
+                        return -EFAULT;
+                return 0;
+        }
+	}
+        /* Note that the ethtool user space code requires EOPNOTSUPP */
+        return -EOPNOTSUPP;
+}
+
+static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+        switch(cmd) {
+        case SIOCETHTOOL:
+	       return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+        default:
+	       return -ENOTTY; /* Apparently this is the standard ioctl errno */
+        }
+}
+
+
+/*
  * Open, close.
  */
 
@@ -629,6 +684,7 @@
 	netdev->tx_timeout = catc_tx_timeout;
 	netdev->watchdog_timeo = TX_TIMEOUT;
 	netdev->set_multicast_list = catc_set_multicast_list;
+	netdev->do_ioctl = catc_ioctl;
 	netdev->priv = catc;
 
 	catc->usbdev = usbdev;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/devices.c linux/drivers/usb/devices.c
--- linux.orig/drivers/usb/devices.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/usb/devices.c	2002-07-20 01:08:35.000000000 +0000
@@ -105,8 +105,8 @@
   "I:  If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
 
 static char *format_endpt =
-/* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms */
-  "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%3dms\n";
+/* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */
+  "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n";
 
 
 /*
@@ -166,24 +166,71 @@
 	return (clas_info[ix].class_name);
 }
 
-static char *usb_dump_endpoint_descriptor(char *start, char *end, const struct usb_endpoint_descriptor *desc)
-{
-	char *EndpointType [4] = {"Ctrl", "Isoc", "Bulk", "Int."};
+static char *usb_dump_endpoint_descriptor (
+	int speed,
+	char *start,
+	char *end,
+	const struct usb_endpoint_descriptor *desc
+)
+{
+	char dir, unit, *type;
+	unsigned interval, in, bandwidth = 1;
 
 	if (start > end)
 		return start;
-	start += sprintf(start, format_endpt, desc->bEndpointAddress,
-			 (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_CONTROL
-			 	? 'B' :			/* bidirectional */
-			 (desc->bEndpointAddress & USB_DIR_IN) ? 'I' : 'O',
-			 desc->bmAttributes, EndpointType[desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK],
-			 desc->wMaxPacketSize, desc->bInterval);
-	return start;
-}
+	in = (desc->bEndpointAddress & USB_DIR_IN);
+	dir = in ? 'I' : 'O';
+	if (speed == USB_SPEED_HIGH) {
+		switch (desc->wMaxPacketSize & (0x03 << 11)) {
+		case 1 << 11:	bandwidth = 2; break;
+		case 2 << 11:	bandwidth = 3; break;
+		}
+	}
 
-static char *usb_dump_endpoint(char *start, char *end, const struct usb_endpoint_descriptor *endpoint)
-{
-	return usb_dump_endpoint_descriptor(start, end, endpoint);
+	/* this isn't checking for illegal values */
+	switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		type = "Ctrl";
+		if (speed == USB_SPEED_HIGH) 	/* uframes per NAK */
+			interval = desc->bInterval;
+		else
+			interval = 0;
+		dir = 'B';			/* ctrl is bidirectional */
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		type = "Isoc";
+		interval = 1 << (desc->bInterval - 1);
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+		type = "Bulk";
+		if (speed == USB_SPEED_HIGH && !in)	/* uframes per NAK */
+			interval = desc->bInterval;
+		else
+			interval = 0;
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		type = "Int.";
+		if (speed == USB_SPEED_HIGH) {
+			interval = 1 << (desc->bInterval - 1);
+		} else
+			interval = desc->bInterval;
+		break;
+	default:	/* "can't happen" */
+		return start;
+	}
+	interval *= (speed == USB_SPEED_HIGH) ? 125 : 1000;
+	if (interval % 1000)
+		unit = 'u';
+	else {
+		unit = 'm';
+		interval /= 1000;
+	}
+
+	start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
+			 desc->bmAttributes, type,
+			 (desc->wMaxPacketSize & 0x07ff) * bandwidth,
+			 interval, unit);
+	return start;
 }
 
 static char *usb_dump_interface_descriptor(char *start, char *end, const struct usb_interface *iface, int setno)
@@ -204,8 +251,13 @@
 	return start;
 }
 
-static char *usb_dump_interface(char *start, char *end, const struct usb_interface *iface, int setno)
-{
+static char *usb_dump_interface(
+	int speed,
+	char *start,
+	char *end,
+	const struct usb_interface *iface,
+	int setno
+) {
 	struct usb_interface_descriptor *desc = &iface->altsetting[setno];
 	int i;
 
@@ -213,7 +265,8 @@
 	for (i = 0; i < desc->bNumEndpoints; i++) {
 		if (start > end)
 			return start;
-		start = usb_dump_endpoint(start, end, desc->endpoint + i);
+		start = usb_dump_endpoint_descriptor(speed,
+				start, end, desc->endpoint + i);
 	}
 	return start;
 }
@@ -238,7 +291,13 @@
 	return start;
 }
 
-static char *usb_dump_config(char *start, char *end, const struct usb_config_descriptor *config, int active)
+static char *usb_dump_config (
+	int speed,
+	char *start,
+	char *end,
+	const struct usb_config_descriptor *config,
+	int active
+)
 {
 	int i, j;
 	struct usb_interface *interface;
@@ -255,7 +314,8 @@
 		for (j = 0; j < interface->num_altsetting; j++) {
 			if (start > end)
 				return start;
-			start = usb_dump_interface(start, end, interface, j);
+			start = usb_dump_interface(speed,
+					start, end, interface, j);
 		}
 	}
 	return start;
@@ -336,8 +396,10 @@
 	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
 		if (start > end)
 			return start;
-		start = usb_dump_config(start, end, dev->config + i,
-					(dev->config + i) == dev->actconfig); /* active ? */
+		start = usb_dump_config(dev->speed,
+				start, end, dev->config + i,
+				/* active ? */
+				(dev->config + i) == dev->actconfig);
 	}
 	return start;
 }
@@ -429,12 +491,26 @@
 	 * count = device count at this level
 	 */
 	/* If this is the root hub, display the bandwidth information */
-	if (level == 0)
-		data_end += sprintf(data_end, format_bandwidth, bus->bandwidth_allocated,
-				FRAME_TIME_MAX_USECS_ALLOC,
-				(100 * bus->bandwidth_allocated + FRAME_TIME_MAX_USECS_ALLOC / 2) / FRAME_TIME_MAX_USECS_ALLOC,
-			         bus->bandwidth_int_reqs, bus->bandwidth_isoc_reqs);
-	
+ 	if (level == 0) {
+ 		int	max;
+ 
+ 		/* high speed reserves 80%, full/low reserves 90% */
+ 		if (usbdev->speed == USB_SPEED_HIGH)
+ 			max = 800;
+ 		else
+ 			max = FRAME_TIME_MAX_USECS_ALLOC;
+ 
+ 		/* report "average" periodic allocation over a microsecond.
+ 		 * the schedules are actually bursty, HCDs need to deal with
+ 		 * that and just compute/report this average.
+ 		 */
+ 		data_end += sprintf(data_end, format_bandwidth,
+ 				bus->bandwidth_allocated, max,
+ 				(100 * bus->bandwidth_allocated + max / 2)
+ 					/ max,
+ 			         bus->bandwidth_int_reqs,
+ 				 bus->bandwidth_isoc_reqs);
+ 	}
 	data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, usbdev);
 	
 	if (data_end > (pages_start + (2 * PAGE_SIZE) - 256))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/devio.c linux/drivers/usb/devio.c
--- linux.orig/drivers/usb/devio.c	2001-11-03 01:18:58.000000000 +0000
+++ linux/drivers/usb/devio.c	2002-07-20 01:08:37.000000000 +0000
@@ -286,7 +286,9 @@
 }
 
 /*
- * interface claiming
+ * interface claims are made only at the request of user level code,
+ * which can also release them (explicitly or by closing files).
+ * they're also undone when devices disconnect.
  */
 
 static void *driver_probe(struct usb_device *dev, unsigned int intf,
@@ -299,7 +301,20 @@
 {
 	struct dev_state *ps = (struct dev_state *)context;
 
+	if (!ps)
+		return;
+
+	/* this waits till synchronous requests complete */
+	down_write (&ps->devsem);
+
+	/* prevent new I/O requests */
+	ps->dev = 0;
 	ps->ifclaimed = 0;
+
+	/* force async requests to complete */
+	destroy_all_async (ps);
+
+	up_write (&ps->devsem);
 }
 
 struct usb_driver usbdevfs_driver = {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/emi26.c linux/drivers/usb/emi26.c
--- linux.orig/drivers/usb/emi26.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/emi26.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,240 @@
+/* 
+ * Emagic EMI 2|6 usb audio interface firmware loader.
+ * Copyright (C) 2002
+ * 	Tapio Laxström (tapio.laxstrom@iptime.fi)
+ *
+ * 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.
+ * 
+ * emi26.c,v 1.13 2002/03/08 13:10:26 tapio Exp
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+
+#define MAX_INTEL_HEX_RECORD_LENGTH 16
+typedef struct _INTEL_HEX_RECORD
+{
+	__u32	length;
+	__u32	address;
+	__u32	type;
+	__u8	data[MAX_INTEL_HEX_RECORD_LENGTH];
+} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
+
+/* include firmware (variables) */
+#include "emi26_fw.h"
+
+#define EMI26_VENDOR_ID 		0x086a  /* Emagic Soft-und Hardware GmBH */
+#define EMI26_PRODUCT_ID		0x0100	/* EMI 2|6 without firmware */
+
+#define ANCHOR_LOAD_INTERNAL	0xA0	/* Vendor specific request code for Anchor Upload/Download (This one is implemented in the core) */
+#define ANCHOR_LOAD_EXTERNAL	0xA3	/* This command is not implemented in the core. Requires firmware */
+#define ANCHOR_LOAD_FPGA	0xA5	/* This command is not implemented in the core. Requires firmware. Emagic extension */
+#define MAX_INTERNAL_ADDRESS	0x1B3F	/* This is the highest internal RAM address for the AN2131Q */
+#define CPUCS_REG		0x7F92  /* EZ-USB Control and Status Register.  Bit 0 controls 8051 reset */ 
+#define INTERNAL_RAM(address)   (address <= MAX_INTERNAL_ADDRESS)
+
+static int emi26_writememory( struct usb_device *dev, int address, unsigned char *data, int length, __u8 bRequest);
+static int emi26_set_reset(struct usb_device *dev, unsigned char reset_bit);
+static int emi26_load_firmware (struct usb_device *dev);
+static void *emi26_probe(struct usb_device *dev, unsigned int if_num, const struct usb_device_id *id);
+static void emi26_disconnect(struct usb_device *dev, void *drv_context);
+static int __init emi26_init (void);
+static void __exit emi26_exit (void);
+
+
+/* thanks to drivers/usb/serial/keyspan_pda.c code */
+static int emi26_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request)
+{
+	int result;
+	unsigned char *buffer =  kmalloc (length, GFP_KERNEL);
+
+	if (!buffer) {
+		printk(KERN_ERR "emi26: kmalloc(%d) failed.", length);
+		return -ENOMEM;
+	}
+	memcpy (buffer, data, length);
+	/* Note: usb_control_msg returns negative value on error or length of the
+	 * 		 data that was written! */
+	result = usb_control_msg (dev, usb_sndctrlpipe(dev, 0), request, 0x40, address, 0, buffer, length, 300);
+	kfree (buffer);
+	return result;
+}
+
+/* thanks to drivers/usb/serial/keyspan_pda.c code */
+static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit)
+{
+	int response;
+	printk(KERN_INFO "%s - %d", __FUNCTION__, reset_bit);
+	/* printk(KERN_DEBUG "%s - %d", __FUNCTION__, reset_bit); */
+	response = emi26_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
+	if (response < 0) {
+		printk(KERN_ERR "emi26: set_reset (%d) failed", reset_bit);
+	}
+	return response;
+}
+
+static int emi26_load_firmware (struct usb_device *dev)
+{
+	int err;
+	int i;
+	int pos = 0;	/* Position in hex record */
+	__u32 addr;	/* Address to write */
+	__u8 buf[1023];
+
+	/* Assert reset (stop the CPU in the EMI) */
+	err = emi26_set_reset(dev,1);
+	if (err < 0) {
+		printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+		return err;
+	}
+
+	/* 1. We need to put the loader for the FPGA into the EZ-USB */
+	for (i=0; g_Loader[i].type == 0; i++) {
+		err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
+		if (err < 0) {
+			printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+			return err;
+		}
+	}
+
+	/* De-assert reset (let the CPU run) */
+	err = emi26_set_reset(dev,0);
+
+	/* 2. We upload the FPGA firmware into the EMI
+	 * Note: collect up to 1023 (yes!) bytes and send them with
+	 * a single request. This is _much_ faster! */
+	do {
+		i = 0;
+		addr = g_bitstream[pos].address;
+
+		/* intel hex records are terminated with type 0 element */
+		while ((g_bitstream[pos].type == 0) && (i + g_bitstream[pos].length < sizeof(buf))) {
+			memcpy(buf + i, g_bitstream[pos].data, g_bitstream[pos].length);
+			i += g_bitstream[pos].length;
+			pos++;
+		}
+		err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
+		if (err < 0) {
+			printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+			return err;
+		}
+	} while (i > 0);
+
+	/* Assert reset (stop the CPU in the EMI) */
+	err = emi26_set_reset(dev,1);
+	if (err < 0) {
+		printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+		return err;
+	}
+
+	/* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
+	for (i=0; g_Loader[i].type == 0; i++) {
+		err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
+		if (err < 0) {
+			printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+			return err;
+		}
+	}
+
+	/* De-assert reset (let the CPU run) */
+	err = emi26_set_reset(dev,0);
+	if (err < 0) {
+		printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+		return err;
+	}
+
+	/* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
+	for (i=0; g_Firmware[i].type == 0; i++) {
+		if (!INTERNAL_RAM(g_Firmware[i].address)) {
+			err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL);
+			if (err < 0) {
+				printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+				return err;
+			}
+		}
+	}
+	
+	/* Assert reset (stop the CPU in the EMI) */
+	err = emi26_set_reset(dev,1);
+	if (err < 0) {
+		printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+		return err;
+	}
+
+	for (i=0; g_Firmware[i].type == 0; i++) {
+		if (INTERNAL_RAM(g_Firmware[i].address)) {
+			err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL);
+			if (err < 0) {
+				printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+				return err;
+			}
+		}
+	}
+
+	/* De-assert reset (let the CPU run) */
+	err = emi26_set_reset(dev,0);
+	if (err < 0) {
+		printk(KERN_ERR "%s - error loading firmware: error = %d", __FUNCTION__, err);
+		return err;
+	}
+
+	/* return 1 to fail the driver inialization
+	 * and give real driver change to load */
+	return 1;
+}
+
+static __devinitdata struct usb_device_id id_table [] = {
+	{ USB_DEVICE(EMI26_VENDOR_ID, EMI26_PRODUCT_ID) },
+	{ }                                             /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table);
+
+static void * emi26_probe(struct usb_device *dev, unsigned int if_num, const struct usb_device_id *id)
+{
+	printk(KERN_INFO "%s start", __FUNCTION__); 
+	
+	if((dev->descriptor.idVendor == EMI26_VENDOR_ID) && (dev->descriptor.idProduct == EMI26_PRODUCT_ID)) {
+		emi26_load_firmware(dev);
+	}
+	
+	/* do not return the driver context, let real audio driver do that */
+	return 0;
+}
+
+static void emi26_disconnect(struct usb_device *dev, void *drv_context)
+{
+}
+
+struct usb_driver emi26_driver = {
+name:			"emi26 - firmware loader",
+probe:			emi26_probe,
+disconnect:		emi26_disconnect,
+id_table:		NULL,
+};
+
+static int __init emi26_init (void)
+{
+	usb_register (&emi26_driver);
+	return 0;
+}
+
+static void __exit emi26_exit (void)
+{
+	usb_deregister (&emi26_driver);
+}
+
+module_init(emi26_init);
+module_exit(emi26_exit);
+
+MODULE_AUTHOR("tapio laxström");
+MODULE_DESCRIPTION("Emagic EMI 2|6 firmware loader.");
+MODULE_LICENSE("GPL");
+
+/* vi:ai:syntax=c:sw=8:ts=8:tw=80
+ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/emi26_fw.h linux/drivers/usb/emi26_fw.h
--- linux.orig/drivers/usb/emi26_fw.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/emi26_fw.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,5775 @@
+/*
+ * This file is generated from three different files, provided by Emagic.
+ */
+/* generated Fri Mar 8 15:11:35 EET 2002 */
+
+/*
+ * This firmware is for the Emagic EMI 2|6 Audio Interface
+ *
+ * The firmware contained herein is Copyright (c) 1999-2002 Emagic
+ * as an unpublished work. This notice does not imply unrestricted
+ * or public access to this firmware which is a trade secret of Emagic,
+ * and which may not be reproduced, used, sold or transferred to
+ * any third party without Emagic's written consent. All Rights Reserved.
+ *
+ * This firmware may not be modified and may only be used with the
+ * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of
+ * any driver which includes this firmware, in whole or in part,
+ * requires the inclusion of this statement.
+ */
+INTEL_HEX_RECORD g_bitstream[]={
+{  16, 0x8010, 0, {0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x07 } },
+{  16, 0x8020, 0, {0x30,0x01,0x60,0x01,0x00,0x00,0x00,0x0b,0x30,0x01,0x20,0x01,0x00,0x80,0x3f,0x2d } },
+{  16, 0x8030, 0, {0x30,0x00,0xc0,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x09 } },
+{  16, 0x8040, 0, {0x30,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x01 } },
+{  16, 0x8050, 0, {0x30,0x00,0x40,0x00,0x50,0x00,0x3e,0x04,0x08,0x12,0x10,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04 } },
+{  16, 0x8080, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x10,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8090, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x84 } },
+{  16, 0x80b0, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00 } },
+{  16, 0x80e0, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8110, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04 } },
+{  16, 0x8140, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x13,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8170, 0, {0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84 } },
+{  16, 0x81a0, 0, {0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf7,0x10,0x01,0x14,0x00,0x25,0x00,0x05 } },
+{  16, 0x81b0, 0, {0x40,0x01,0x50,0x00,0x94,0x00,0x15,0x00,0x07,0x40,0x01,0xd0,0x00,0x94,0x00,0x25 } },
+{  16, 0x81c0, 0, {0x80,0x01,0x60,0x02,0xd8,0x00,0xf6,0x00,0x2f,0x80,0x02,0xe0,0x04,0xd8,0x37,0x44 } },
+{  16, 0x81d0, 0, {0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf2,0x00,0xcc,0x90,0x39,0x20 } },
+{  16, 0x81e0, 0, {0x0d,0x98,0x03,0xd2,0x00,0xe7,0x80,0x37,0x04,0x0e,0xf1,0x83,0x7e,0x00,0xdf,0x90 } },
+{  16, 0x81f0, 0, {0x31,0xe4,0x8f,0x79,0x03,0x7c,0x20,0xdf,0x22,0x33,0xc0,0x0c,0xf0,0x22,0x30,0x00 } },
+{  16, 0x8200, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0x62,0x00,0x80,0x24,0x22,0x20 } },
+{  16, 0x8210, 0, {0x08,0x98,0x12,0xe2,0x00,0x8b,0x81,0x20,0x94,0x08,0x74,0x02,0x2e,0x00,0x8a,0x01 } },
+{  16, 0x8220, 0, {0x22,0xc8,0x08,0x92,0x02,0x3d,0x80,0x8b,0x60,0x22,0x80,0x08,0xb0,0x02,0x20,0x04 } },
+{  16, 0x8230, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc8,0x00,0xa0,0x00,0x20,0x00 } },
+{  16, 0x8240, 0, {0x0b,0x10,0x02,0xc0,0x00,0xa1,0x00,0x24,0x09,0x4a,0x32,0x02,0x48,0x00,0xb1,0x00 } },
+{  16, 0x8250, 0, {0x62,0xc0,0x09,0xa0,0x46,0xcc,0x24,0x93,0x49,0x2a,0x80,0x48,0x30,0x22,0x62,0x01 } },
+{  16, 0x8260, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa8,0x12,0xa8,0x00,0x22,0x00 } },
+{  16, 0x8270, 0, {0x08,0x90,0x02,0xe0,0x00,0x89,0x80,0x22,0x44,0x08,0xb0,0x12,0xa8,0x00,0xa9,0x40 } },
+{  16, 0x8280, 0, {0x22,0xc0,0x08,0x90,0x82,0xac,0x00,0x9b,0x04,0x2a,0xc4,0x08,0xb0,0x02,0x70,0x04 } },
+{  16, 0x8290, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x84,0x00,0xe9,0x80,0xb2,0x64 } },
+{  16, 0x82a0, 0, {0x4d,0xa0,0x03,0xea,0x20,0xe9,0xc0,0x36,0x40,0x0e,0xb0,0x03,0x44,0x00,0xfb,0x90 } },
+{  16, 0x82b0, 0, {0xb2,0x88,0x0d,0xbc,0x03,0xec,0x08,0x5b,0x00,0x38,0x60,0x2c,0xb0,0x63,0x40,0x04 } },
+{  16, 0x82c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb4,0x26,0xdd,0x90,0x37,0x40 } },
+{  16, 0x82d0, 0, {0x4f,0xe0,0x13,0xf2,0x80,0xfd,0x00,0x3d,0xa0,0x0d,0x70,0x03,0x75,0x00,0x5e,0x00 } },
+{  16, 0x82e0, 0, {0x3f,0xa4,0x0d,0xf9,0x03,0x5c,0x10,0xeb,0x00,0x37,0x20,0x0f,0x30,0x03,0xb8,0x00 } },
+{  16, 0x82f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xe9,0x80,0x32,0x40 } },
+{  16, 0x8300, 0, {0x0c,0xa1,0x83,0xe8,0x00,0xe9,0x00,0x32,0x42,0x0e,0xb0,0x03,0xac,0x48,0xe9,0x00 } },
+{  16, 0x8310, 0, {0x3a,0x80,0x0e,0xa4,0x03,0xec,0x00,0xeb,0x00,0xb2,0x03,0x0e,0xb0,0x0b,0x10,0x04 } },
+{  16, 0x8320, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2e,0x80,0x89,0xd1,0x20,0x40 } },
+{  16, 0x8330, 0, {0x08,0xa0,0x02,0xc0,0x00,0x81,0x80,0x22,0x58,0x08,0xf5,0x02,0x2f,0x40,0x8b,0x00 } },
+{  16, 0x8340, 0, {0x20,0xc0,0x08,0x30,0x43,0x7c,0x00,0x87,0x00,0x22,0x40,0x08,0xf0,0x02,0x32,0x00 } },
+{  16, 0x8350, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x42,0x01,0x9a,0x44,0x28,0xa2 } },
+{  16, 0x8360, 0, {0x08,0x18,0x02,0xc0,0x80,0xa1,0x80,0xa0,0x00,0x08,0x30,0x02,0x8e,0x00,0xab,0x00 } },
+{  16, 0x8370, 0, {0x2c,0x40,0x0a,0x30,0x02,0x0c,0x00,0xa3,0x00,0x20,0x44,0x0a,0x30,0x02,0x38,0x00 } },
+{  16, 0x8380, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x32,0x00,0x96,0x82,0x2b,0xa2 } },
+{  16, 0x8390, 0, {0x88,0x5a,0x02,0xf2,0x00,0x05,0x80,0x29,0xa0,0x08,0x78,0x42,0xbe,0x00,0x8e,0x84 } },
+{  16, 0x83a0, 0, {0x2f,0x61,0x0a,0xd8,0x02,0x4e,0x10,0xa7,0x80,0x20,0x28,0x08,0x78,0x02,0x18,0x00 } },
+{  16, 0x83b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x00,0xf2,0x24,0x38,0x80 } },
+{  16, 0x83c0, 0, {0x2c,0x1a,0x03,0xc4,0x00,0xe0,0x58,0xa0,0x80,0x2e,0x30,0x03,0x88,0x41,0xe3,0x02 } },
+{  16, 0x83d0, 0, {0x3c,0x40,0x06,0x20,0x03,0x8c,0x00,0xe3,0x00,0x10,0x00,0x0e,0x31,0x43,0x12,0x02 } },
+{  16, 0x83e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0x98,0x00,0xee,0x01,0x37,0x84 } },
+{  16, 0x83f0, 0, {0x9f,0xd9,0x03,0xf0,0x48,0xfd,0x10,0x37,0xc0,0x07,0xb0,0x03,0x5c,0x00,0xf6,0x10 } },
+{  16, 0x8400, 0, {0x33,0xc0,0x0d,0xe1,0x03,0xed,0x20,0xdf,0x10,0x3f,0x48,0x0f,0xf0,0x23,0xd0,0x06 } },
+{  16, 0x8410, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x02,0xcb,0x80,0x30,0xc0 } },
+{  16, 0x8420, 0, {0x0c,0xa0,0x03,0xe2,0x02,0xc9,0x00,0x3a,0x40,0x0d,0xb6,0x03,0x64,0x00,0xeb,0x00 } },
+{  16, 0x8430, 0, {0x3e,0xc0,0x0f,0xb0,0x03,0xed,0x00,0xfb,0x01,0x3e,0xe0,0x0c,0xb0,0x02,0xea,0x00 } },
+{  16, 0x8440, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x00,0x87,0x00,0x21,0xc0 } },
+{  16, 0x8450, 0, {0x28,0x60,0x02,0xd0,0x00,0x85,0x00,0x2d,0x80,0x48,0xf0,0x82,0x1c,0x00,0xb7,0x00 } },
+{  16, 0x8460, 0, {0x2d,0x00,0x0b,0x50,0x02,0xdc,0x00,0xb7,0xa0,0x2f,0x80,0x28,0x7a,0x02,0xd2,0x04 } },
+{  16, 0x8470, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc1,0x00,0xbe,0x00,0x87,0x80,0x21,0xe0 } },
+{  16, 0x8480, 0, {0x28,0x68,0x02,0xd7,0x00,0x84,0x80,0x2d,0xe0,0x49,0x79,0x06,0x53,0x09,0xb5,0x80 } },
+{  16, 0x8490, 0, {0x2d,0xe2,0x0b,0x78,0x02,0xde,0x80,0xb7,0x90,0x2d,0xb0,0x08,0x79,0x02,0xf0,0x00 } },
+{  16, 0x84a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x10,0x83,0x01,0x28,0xc8 } },
+{  16, 0x84b0, 0, {0x08,0x20,0x02,0xc2,0x06,0x81,0x00,0x2c,0xc8,0x88,0x30,0x62,0x0e,0x21,0xb3,0xa0 } },
+{  16, 0x84c0, 0, {0x2c,0xc1,0x0b,0xb6,0x02,0xcc,0x00,0xb3,0x00,0x2c,0xe0,0x08,0x30,0x02,0xd2,0x04 } },
+{  16, 0x84d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xca,0x40,0xb0,0x80 } },
+{  16, 0x84e0, 0, {0x0c,0x2c,0x02,0xf8,0x00,0xc6,0x20,0x3f,0x90,0x0d,0xa0,0x03,0x7b,0x01,0xee,0xe0 } },
+{  16, 0x84f0, 0, {0x3f,0xb4,0x0f,0xec,0x03,0xe8,0x00,0xfa,0x00,0x3f,0xa0,0x0c,0xa0,0x03,0xfa,0x04 } },
+{  16, 0x8500, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe3,0x00,0xf8,0x09,0x26,0x00 } },
+{  16, 0x8510, 0, {0x0f,0xc1,0x83,0xe0,0x10,0xf8,0x40,0x3c,0x00,0x0f,0x80,0x03,0xe0,0x01,0xf8,0x00 } },
+{  16, 0x8520, 0, {0x3e,0x00,0x0f,0x81,0x03,0xe0,0x04,0xf8,0x00,0x3e,0x10,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0x8530, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x00,0x3e,0x40 } },
+{  16, 0x8540, 0, {0x4f,0x90,0x63,0x26,0x84,0x39,0x02,0xb2,0x40,0x0c,0x91,0x03,0x24,0x00,0xf9,0x00 } },
+{  16, 0x8550, 0, {0x3e,0x40,0x0f,0x90,0x03,0x24,0x00,0xf1,0x00,0x3a,0x44,0x0f,0x90,0x03,0xc2,0x04 } },
+{  16, 0x8560, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x45,0x00,0x89,0x40,0x2e,0x40 } },
+{  16, 0x8570, 0, {0x08,0x92,0x0a,0x24,0x00,0xb9,0x31,0x22,0x60,0x88,0x94,0x8a,0x24,0x20,0xb9,0x00 } },
+{  16, 0x8580, 0, {0x2e,0x40,0x0b,0x90,0x02,0x24,0x00,0xb9,0x00,0x22,0x68,0x0b,0x90,0x02,0xe0,0x00 } },
+{  16, 0x8590, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0xa0,0x8d,0x84,0x2f,0x40 } },
+{  16, 0x85a0, 0, {0x0b,0xd1,0x02,0x24,0x00,0xb9,0x00,0x22,0x4a,0x08,0x10,0x02,0x2c,0x40,0xb9,0x00 } },
+{  16, 0x85b0, 0, {0x2e,0x40,0x0b,0x90,0x02,0x24,0x00,0xb9,0x00,0x2a,0x40,0x0b,0x90,0x02,0xc6,0x00 } },
+{  16, 0x85c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x14,0x00,0x85,0x80,0x2d,0x40 } },
+{  16, 0x85d0, 0, {0x08,0x50,0x02,0x04,0x0c,0xb9,0x00,0xa0,0x50,0x08,0x14,0x22,0x04,0x00,0xb1,0x00 } },
+{  16, 0x85e0, 0, {0x2c,0x40,0x0b,0x10,0x02,0x04,0x00,0xb1,0x28,0x20,0x4a,0x0b,0x13,0x02,0xc2,0x01 } },
+{  16, 0x85f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc0,0x50,0x3e,0x80 } },
+{  16, 0x8600, 0, {0x0f,0xc0,0x43,0x20,0x00,0xf8,0x00,0x30,0x00,0x2c,0x80,0x23,0x20,0x00,0xf8,0x51 } },
+{  16, 0x8610, 0, {0x3e,0x14,0x8f,0x85,0x0b,0x21,0x40,0xf8,0x70,0x3a,0x08,0x0f,0x84,0x83,0xee,0x03 } },
+{  16, 0x8620, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xc4,0x00,0xf9,0x04,0x3e,0x40 } },
+{  16, 0x8630, 0, {0x0f,0x90,0x23,0xd4,0x00,0xfd,0x00,0x3f,0x50,0x0f,0x94,0x03,0xf4,0x04,0xfd,0x00 } },
+{  16, 0x8640, 0, {0x3f,0x41,0x8f,0xd0,0x43,0xe5,0x0c,0xf9,0x02,0x3f,0x4a,0x0f,0x92,0x03,0xe6,0x02 } },
+{  16, 0x8650, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xd4,0x01,0xfd,0x00,0x3d,0x40 } },
+{  16, 0x8660, 0, {0x0c,0xd0,0x13,0xf4,0x00,0xd5,0x00,0x33,0x6a,0x1c,0xdc,0x83,0x34,0x00,0xd1,0x04 } },
+{  16, 0x8670, 0, {0x3e,0x50,0x0c,0x91,0x03,0xe6,0xc0,0xdd,0xb0,0x33,0x6a,0x2c,0x9c,0x83,0xe6,0x00 } },
+{  16, 0x8680, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x09,0xf8,0x80,0x2e,0x00 } },
+{  16, 0x8690, 0, {0x88,0x80,0x00,0xe8,0x00,0xba,0x00,0x22,0xb0,0x08,0x8e,0x02,0x28,0x00,0x88,0xa8 } },
+{  16, 0x86a0, 0, {0x26,0x28,0x08,0x8a,0x22,0xe2,0x00,0x88,0xe4,0x22,0x30,0x08,0x8c,0x02,0xce,0x04 } },
+{  16, 0x86b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x28,0x2e,0x40 } },
+{  16, 0x86c0, 0, {0x08,0x10,0x02,0xc4,0x00,0x99,0x00,0x20,0x42,0x48,0x10,0x02,0x64,0x01,0x91,0x80 } },
+{  16, 0x86d0, 0, {0x2c,0x48,0x08,0x10,0x02,0xc4,0xc0,0x81,0x40,0x20,0x4a,0x08,0x12,0x02,0xc2,0x01 } },
+{  16, 0x86e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x94,0xa9,0x02,0x2e,0x40 } },
+{  16, 0x86f0, 0, {0x0a,0x90,0x02,0x64,0x00,0xb9,0x00,0x82,0x60,0x08,0x90,0x02,0x66,0x00,0x89,0x10 } },
+{  16, 0x8700, 0, {0x24,0x62,0x08,0x90,0x02,0xe4,0x00,0x89,0x02,0x22,0x40,0x18,0x90,0x02,0xc6,0x04 } },
+{  16, 0x8710, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe6,0x00,0xb9,0x04,0x3e,0x40 } },
+{  16, 0x8720, 0, {0x0c,0x90,0x13,0xe4,0x00,0xd1,0xc0,0x12,0x50,0x28,0x90,0x03,0x44,0x00,0xd9,0x00 } },
+{  16, 0x8730, 0, {0x3e,0x40,0x28,0x92,0x03,0xe4,0x02,0xd9,0x00,0x32,0x42,0x8c,0x90,0x12,0xe8,0x04 } },
+{  16, 0x8740, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa6,0x20,0xf9,0x00,0x3e,0x41 } },
+{  16, 0x8750, 0, {0x2d,0x90,0x03,0xe4,0x00,0xf9,0x20,0x3e,0x40,0x4f,0x90,0x01,0xa4,0x00,0xf9,0x00 } },
+{  16, 0x8760, 0, {0x36,0x40,0x8f,0x92,0x07,0xe4,0x00,0xf1,0x00,0xbe,0x40,0x0f,0x90,0x03,0xca,0x00 } },
+{  16, 0x8770, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x00,0x3e,0x20 } },
+{  16, 0x8780, 0, {0x0c,0x80,0x03,0xe0,0x40,0xf8,0x00,0x36,0x12,0x2c,0x00,0x03,0xe0,0xc0,0xf8,0x00 } },
+{  16, 0x8790, 0, {0x32,0x10,0x0d,0x84,0x03,0xa0,0x00,0xf8,0x02,0x3e,0x08,0x0f,0x80,0x00,0xca,0x04 } },
+{  16, 0x87a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x3a,0x90,0x8e,0x00,0x2d,0xa0 } },
+{  16, 0x87b0, 0, {0x80,0xe8,0x02,0xfa,0x00,0xbe,0x40,0x23,0x80,0x08,0xe8,0x02,0xfa,0x00,0x8a,0x00 } },
+{  16, 0x87c0, 0, {0x36,0x80,0x08,0xa0,0x02,0xe8,0x00,0xba,0x00,0x2f,0x80,0x0b,0xa0,0x03,0x8a,0x00 } },
+{  16, 0x87d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x46,0x02,0x83,0x00,0x2c,0x80 } },
+{  16, 0x87e0, 0, {0x08,0x22,0x42,0xc6,0x80,0xb1,0x60,0x2e,0xf4,0x08,0x38,0x22,0xce,0x00,0xa3,0x00 } },
+{  16, 0x87f0, 0, {0x20,0xc0,0x08,0x30,0x02,0xac,0x00,0xb1,0x00,0x2e,0x40,0x0b,0x30,0x02,0xca,0x00 } },
+{  16, 0x8800, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1e,0x02,0x85,0x01,0x2d,0xc2 } },
+{  16, 0x8810, 0, {0xa8,0x44,0x02,0xd4,0x00,0xbd,0x01,0x29,0x40,0x18,0x68,0xd2,0xdc,0x00,0x8f,0x80 } },
+{  16, 0x8820, 0, {0x25,0xcc,0x28,0x73,0x42,0xdc,0x80,0xb5,0x30,0x2d,0xc0,0x1b,0x72,0x02,0xe8,0x00 } },
+{  16, 0x8830, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x04,0xc6,0x82,0x3d,0xe0 } },
+{  16, 0x8840, 0, {0x0c,0x48,0x12,0xd6,0x10,0xf5,0x80,0x3c,0xa0,0x0c,0x70,0x03,0xde,0x00,0xe7,0x90 } },
+{  16, 0x8850, 0, {0x23,0xea,0x04,0x7a,0x03,0x9e,0x00,0xf5,0x80,0x3d,0xe0,0x0f,0x7a,0x03,0xea,0x02 } },
+{  16, 0x8860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0d,0xac,0x00,0x9c,0x00,0x3e,0xc0 } },
+{  16, 0x8870, 0, {0x0f,0x80,0x03,0xe4,0x10,0xf9,0x00,0x36,0x01,0x0f,0xa0,0x03,0xc0,0x00,0xeb,0x00 } },
+{  16, 0x8880, 0, {0x3e,0xd8,0x4e,0xb0,0x83,0xec,0x00,0xf9,0x00,0x3e,0xc0,0x0f,0xb4,0x43,0x82,0x06 } },
+{  16, 0x8890, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xde,0x00,0xcf,0x84,0x31,0xe0 } },
+{  16, 0x88a0, 0, {0x0e,0xc8,0x43,0xd6,0x00,0xcd,0x80,0x33,0xe0,0xcd,0xd9,0x03,0x3a,0x00,0xff,0x88 } },
+{  16, 0x88b0, 0, {0x33,0xe0,0x0f,0xf9,0x13,0xfe,0x24,0xfd,0x80,0x3f,0x20,0x0c,0xf6,0x83,0x10,0x00 } },
+{  16, 0x88c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0x85,0x00,0x21,0xc4 } },
+{  16, 0x88d0, 0, {0x28,0x40,0x82,0xd0,0x00,0xd5,0x00,0x23,0x80,0x48,0xc9,0x02,0x1c,0x00,0xb7,0x00 } },
+{  16, 0x88e0, 0, {0x21,0xc0,0x0b,0x71,0x02,0xde,0x80,0xb5,0x10,0x2d,0xc0,0x28,0xf0,0x02,0x2a,0x04 } },
+{  16, 0x88f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x9c,0x00,0x96,0x00,0x21,0xc0 } },
+{  16, 0x8900, 0, {0x0a,0x41,0x02,0xf5,0x40,0x8d,0x00,0x21,0x40,0x09,0x52,0x02,0x98,0x20,0xb7,0x00 } },
+{  16, 0x8910, 0, {0x21,0xc0,0x0b,0x70,0x06,0xdc,0x80,0xb5,0x00,0x2d,0xc0,0x08,0x70,0x02,0x04,0x00 } },
+{  16, 0x8920, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xcc,0x10,0x98,0x00,0x00,0xc0 } },
+{  16, 0x8930, 0, {0x88,0x04,0x82,0xc0,0x00,0x91,0x04,0x20,0x03,0x09,0x00,0x02,0x8a,0x00,0xb3,0x0a } },
+{  16, 0x8940, 0, {0x20,0xc4,0x8b,0x34,0x02,0xcc,0x00,0xb9,0x00,0x2c,0xc0,0x00,0x30,0x02,0x18,0x04 } },
+{  16, 0x8950, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x15,0xac,0x00,0xdb,0x00,0xb0,0xc0 } },
+{  16, 0x8960, 0, {0x0e,0x9c,0x02,0xc5,0x00,0xc1,0x10,0xb2,0xc0,0x0d,0xb0,0x0b,0xa7,0x08,0xff,0x00 } },
+{  16, 0x8970, 0, {0xb3,0xc0,0x0f,0xfa,0x03,0xfc,0x00,0xfd,0x00,0x3e,0xd4,0x0c,0xf0,0x0b,0x2e,0x04 } },
+{  16, 0x8980, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x04,0xed,0x00,0x3e,0x40 } },
+{  16, 0x8990, 0, {0x0f,0x84,0x03,0xe5,0x40,0xf9,0x40,0x3e,0x60,0xce,0xb4,0x43,0x64,0x00,0xfb,0x80 } },
+{  16, 0x89a0, 0, {0x3e,0xc2,0x0f,0xb0,0x13,0xec,0x00,0xf9,0x02,0x3e,0xc0,0x4f,0xb0,0x03,0xe1,0x00 } },
+{  16, 0x89b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x10,0xff,0x00,0xce,0x00,0x33,0xc0 } },
+{  16, 0x89c0, 0, {0x0e,0xc0,0x07,0x74,0x04,0xec,0x00,0x11,0x80,0x0c,0xca,0x03,0xfe,0x60,0xff,0x00 } },
+{  16, 0x89d0, 0, {0x3f,0xc0,0x0f,0xf0,0x83,0x3c,0x00,0xdd,0x00,0xb3,0x50,0x2c,0xf0,0x03,0x20,0x04 } },
+{  16, 0x89e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x4c,0x04,0x8b,0x0b,0x22,0x70 } },
+{  16, 0x89f0, 0, {0x08,0x08,0x03,0x67,0x20,0x8a,0x88,0xa2,0x00,0x28,0x84,0x02,0xe7,0x00,0xbb,0x00 } },
+{  16, 0x8a00, 0, {0x3e,0xc0,0x0b,0xb0,0x02,0x2c,0x00,0xb9,0x00,0x22,0x61,0x08,0xb0,0x03,0x60,0x40 } },
+{  16, 0x8a10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x20,0x22,0xe2 } },
+{  16, 0x8a20, 0, {0x0a,0x8c,0x02,0x26,0x00,0xa9,0x80,0x2a,0xc0,0x08,0xb4,0x42,0xed,0x00,0xbb,0x00 } },
+{  16, 0x8a30, 0, {0x2e,0xc0,0x0b,0x30,0x02,0x2c,0x00,0xb9,0x00,0x20,0x80,0x08,0x30,0x02,0x60,0x00 } },
+{  16, 0x8a40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0e,0x01,0x81,0x00,0xa0,0xc0 } },
+{  16, 0x8a50, 0, {0x08,0x81,0x02,0x44,0x00,0x81,0x00,0x28,0x81,0x08,0x32,0x02,0xcc,0x00,0xb3,0x00 } },
+{  16, 0x8a60, 0, {0x28,0xc0,0x0b,0x30,0x02,0x0c,0x80,0xb1,0x00,0x20,0xc0,0x08,0x30,0x12,0x42,0x01 } },
+{  16, 0x8a70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0d,0x6c,0x00,0xc2,0x01,0x32,0xc0 } },
+{  16, 0x8a80, 0, {0x2e,0x80,0x16,0x2c,0x08,0xe9,0x00,0x3a,0x40,0x0c,0x80,0x03,0xec,0x00,0xf7,0x00 } },
+{  16, 0x8a90, 0, {0x2f,0xc0,0x0f,0xf0,0x0b,0x2c,0x00,0xd9,0x00,0x30,0x40,0x0c,0xf0,0x03,0x60,0x03 } },
+{  16, 0x8aa0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x0d,0xf8,0x08,0xff,0x00,0x3f,0xc0 } },
+{  16, 0x8ab0, 0, {0x0f,0xc2,0x17,0xfc,0x00,0xf7,0x00,0x37,0x00,0x0f,0x84,0x03,0xfc,0x00,0xff,0x00 } },
+{  16, 0x8ac0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xed,0x00,0xfd,0x00,0x3f,0x40,0x0f,0xf0,0x03,0xe8,0x06 } },
+{  16, 0x8ad0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xcf,0x30,0x17,0x48 } },
+{  16, 0x8ae0, 0, {0x0c,0x59,0x03,0xb9,0x00,0xdf,0x28,0x35,0x24,0x0d,0x82,0xa3,0x7c,0x80,0xff,0x00 } },
+{  16, 0x8af0, 0, {0x3f,0xc8,0x0f,0xf2,0x03,0xe4,0xa0,0xef,0x80,0x3f,0xe1,0x8c,0xd8,0x43,0x30,0x00 } },
+{  16, 0x8b00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xed,0x48,0x89,0x34,0xa3,0x70 } },
+{  16, 0x8b10, 0, {0x28,0xb0,0x23,0x60,0x00,0x8b,0xc0,0x22,0x40,0x08,0xb4,0x82,0x2f,0x40,0xbf,0xd1 } },
+{  16, 0x8b20, 0, {0x6f,0xf4,0x8e,0xbd,0x02,0xe7,0x00,0xbb,0x80,0x3a,0xe0,0x08,0x98,0x0a,0x28,0x04 } },
+{  16, 0x8b30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0xb0,0x91,0x00,0xa8,0x50 } },
+{  16, 0x8b40, 0, {0x08,0xb2,0x02,0xc8,0x84,0x93,0x00,0x24,0x49,0x0b,0x02,0x02,0x4c,0x00,0xb3,0x04 } },
+{  16, 0x8b50, 0, {0x2c,0xc0,0x0b,0x30,0x42,0x84,0x00,0xb3,0x00,0x2e,0x00,0x0a,0xb0,0x12,0x22,0x01 } },
+{  16, 0x8b60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xac,0x02,0x99,0x18,0x2a,0x44 } },
+{  16, 0x8b70, 0, {0x08,0xb8,0x82,0xa2,0x01,0xbb,0x00,0x28,0x60,0x0a,0xa0,0x12,0x6c,0x00,0xbb,0x00 } },
+{  16, 0x8b80, 0, {0x6e,0xc0,0x0a,0xb0,0x02,0xe4,0x00,0xbb,0x00,0x2a,0x00,0x2a,0xb0,0x02,0x38,0x04 } },
+{  16, 0x8b90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xe4,0x08,0xda,0xc0,0x3a,0x60 } },
+{  16, 0x8ba0, 0, {0x0c,0x18,0x0a,0xeb,0x04,0xdb,0x00,0x36,0xe0,0x07,0x85,0x83,0x6c,0x00,0xfb,0x00 } },
+{  16, 0x8bb0, 0, {0x2e,0xc0,0x0f,0xb0,0x43,0xe4,0x00,0xeb,0x00,0x3e,0x88,0x0e,0x18,0x03,0x10,0x04 } },
+{  16, 0x8bc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x41,0x9c,0x10,0xe9,0x00,0x37,0x60 } },
+{  16, 0x8bd0, 0, {0x87,0xf0,0x17,0x70,0x00,0xcf,0x01,0x37,0xc0,0x4c,0x98,0x03,0xbc,0x00,0xfb,0x00 } },
+{  16, 0x8be0, 0, {0x3f,0xc2,0x0f,0xf0,0x03,0xe4,0x00,0xff,0x40,0x3f,0xe4,0x0d,0xd9,0x03,0xf0,0x00 } },
+{  16, 0x8bf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa4,0x00,0xf4,0x00,0x30,0x40 } },
+{  16, 0x8c00, 0, {0x0f,0xb4,0x03,0x99,0x00,0xfb,0x00,0x3e,0xc0,0x0d,0x04,0x23,0x2c,0x08,0xfb,0x88 } },
+{  16, 0x8c10, 0, {0x32,0xc0,0x0f,0xb0,0x03,0xe6,0x00,0xdb,0x10,0x3e,0x02,0x0f,0xb0,0x83,0xd0,0x04 } },
+{  16, 0x8c20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xb9,0x50,0xa2,0x48 } },
+{  16, 0x8c30, 0, {0x8b,0xb0,0x03,0x20,0x00,0xd7,0x80,0x2e,0xd8,0x00,0x80,0x02,0x3c,0x00,0xbf,0x80 } },
+{  16, 0x8c40, 0, {0x23,0xe8,0x8b,0xf0,0x02,0xf4,0x40,0x8b,0x40,0x0c,0x42,0x03,0xb6,0x02,0xf2,0x00 } },
+{  16, 0x8c50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb2,0x44,0x00,0xc8 } },
+{  16, 0x8c60, 0, {0x0b,0x30,0x12,0x8c,0x00,0xa3,0x80,0x24,0xc8,0x0b,0x00,0x0a,0xcc,0x00,0xb3,0x44 } },
+{  16, 0x8c70, 0, {0x04,0xc0,0x1b,0x36,0x02,0xc5,0x01,0x83,0x0c,0x2c,0xa0,0x0b,0x30,0x02,0xf8,0x00 } },
+{  16, 0x8c80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x08,0xb7,0x90,0x21,0x64 } },
+{  16, 0x8c90, 0, {0x0b,0xf8,0x02,0x4a,0x04,0x97,0x81,0x2f,0xe4,0x0a,0x78,0x02,0x9e,0x00,0xb7,0x80 } },
+{  16, 0x8ca0, 0, {0x21,0xe0,0x8b,0x78,0x82,0xd6,0x86,0x87,0x84,0x2d,0xa0,0x0b,0x78,0x02,0xc0,0x00 } },
+{  16, 0x8cb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x04,0x00,0xf2,0x00,0x30,0xc0 } },
+{  16, 0x8cc0, 0, {0x0f,0x30,0x03,0x8c,0x00,0xe3,0x0a,0x3c,0xc0,0x0f,0x18,0x03,0x8c,0x00,0xf3,0x02 } },
+{  16, 0x8cd0, 0, {0x30,0xc0,0x1f,0x30,0x01,0xc6,0x80,0xc3,0x00,0x3c,0xc0,0x0f,0x12,0x03,0xda,0x02 } },
+{  16, 0x8ce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x0d,0xbc,0x00,0xff,0x00,0x3f,0x41 } },
+{  16, 0x8cf0, 0, {0x0f,0xf0,0x03,0xb8,0x08,0xff,0x08,0x3f,0xc0,0x0d,0xf0,0x03,0x3c,0x20,0xff,0x08 } },
+{  16, 0x8d00, 0, {0x3b,0xd2,0x0f,0xf0,0x03,0xf4,0x40,0xef,0x00,0x3f,0xc4,0x0f,0xd0,0x03,0xd0,0x06 } },
+{  16, 0x8d10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xfe,0x00,0x32,0xc2 } },
+{  16, 0x8d20, 0, {0x0c,0x30,0x0b,0x26,0x00,0xfb,0x80,0x36,0xc0,0x0d,0xa0,0x03,0xec,0x00,0xfb,0xe0 } },
+{  16, 0x8d30, 0, {0x32,0xd0,0x0f,0xb8,0x43,0x64,0x44,0xdb,0x04,0x3e,0x80,0x0f,0xb0,0x03,0xe2,0x00 } },
+{  16, 0x8d40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0xb7,0x00,0xa1,0xc0 } },
+{  16, 0x8d50, 0, {0x88,0x70,0x03,0x10,0x00,0xb7,0x20,0x21,0xc0,0x08,0x70,0x02,0xdc,0x80,0xb3,0x30 } },
+{  16, 0x8d60, 0, {0x31,0xc8,0x0b,0x74,0x02,0x14,0x00,0x87,0x40,0x2d,0xc0,0x4b,0x70,0x02,0xd2,0x00 } },
+{  16, 0x8d70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x96,0x20,0xb6,0x80,0x20,0xe0 } },
+{  16, 0x8d80, 0, {0x28,0xf8,0x02,0x94,0x10,0xb7,0x81,0x27,0xe2,0x09,0x78,0x02,0xde,0x00,0xb7,0xa0 } },
+{  16, 0x8d90, 0, {0xa9,0xe8,0x0b,0x38,0x02,0x76,0x00,0x87,0x80,0x2d,0xa0,0x0b,0x58,0x02,0xf0,0x00 } },
+{  16, 0x8da0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xce,0x10,0xb3,0x00,0x20,0xc4 } },
+{  16, 0x8db0, 0, {0x08,0x20,0x02,0x80,0x10,0xb3,0x00,0x22,0xc8,0x08,0xb0,0x02,0xcc,0x11,0xb3,0x02 } },
+{  16, 0x8dc0, 0, {0x28,0xc0,0x0b,0x30,0x02,0x04,0x00,0x93,0x80,0x2c,0xd2,0x0b,0x10,0x02,0xd2,0x04 } },
+{  16, 0x8dd0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfe,0x40,0x32,0xa0 } },
+{  16, 0x8de0, 0, {0x0c,0xe4,0x03,0x98,0x80,0xfa,0x00,0x37,0xa0,0x0d,0xe0,0x83,0xe8,0x00,0xfe,0x00 } },
+{  16, 0x8df0, 0, {0x3a,0x80,0x0b,0xa0,0x03,0x68,0x00,0xd8,0xa0,0x3f,0x90,0x0f,0xa0,0x03,0xfa,0x04 } },
+{  16, 0x8e00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x08,0xf8,0x08,0x3e,0x00 } },
+{  16, 0x8e10, 0, {0x0f,0x80,0x03,0x20,0x00,0xf8,0x40,0x3e,0x00,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x04 } },
+{  16, 0x8e20, 0, {0x30,0x10,0x0f,0x80,0x03,0xe0,0x02,0xe8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0x8e30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf1,0x00,0x32,0x40 } },
+{  16, 0x8e40, 0, {0x0e,0x90,0x83,0xa4,0x00,0xc9,0x80,0x3e,0x40,0x0e,0x90,0x03,0xa4,0x00,0xf9,0x00 } },
+{  16, 0x8e50, 0, {0x3e,0x40,0x0c,0x90,0x03,0xe4,0x00,0xc8,0x00,0x3e,0x40,0x8f,0x90,0x03,0x02,0x04 } },
+{  16, 0x8e60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x40,0xa0,0x62 } },
+{  16, 0x8e70, 0, {0x08,0x10,0x02,0x24,0x10,0x89,0x00,0x2e,0x40,0x08,0x90,0x02,0x24,0x00,0xb9,0x00 } },
+{  16, 0x8e80, 0, {0x2e,0x52,0x08,0x94,0x02,0xc4,0x00,0x89,0x40,0x2e,0x40,0x0b,0x10,0x03,0x60,0x10 } },
+{  16, 0x8e90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x18,0x22,0x44 } },
+{  16, 0x8ea0, 0, {0x0a,0x90,0x02,0xac,0x00,0x89,0x10,0x2e,0xc0,0x0a,0x90,0x02,0xa4,0x00,0xb9,0x80 } },
+{  16, 0x8eb0, 0, {0x2e,0x60,0x08,0x98,0x02,0xe6,0x02,0x89,0x08,0x2e,0x40,0x0b,0x90,0x02,0x06,0x00 } },
+{  16, 0x8ec0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x80,0xb1,0x20,0xa0,0x48 } },
+{  16, 0x8ed0, 0, {0x08,0x90,0x02,0x24,0x08,0x81,0x23,0x2c,0x50,0x08,0x10,0x02,0x04,0x80,0xb1,0x20 } },
+{  16, 0x8ee0, 0, {0x2c,0x48,0x28,0x12,0x02,0xe4,0x80,0x81,0x20,0x2c,0x40,0x0b,0x98,0x02,0x42,0x05 } },
+{  16, 0x8ef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x50,0x32,0x00 } },
+{  16, 0x8f00, 0, {0x0e,0x85,0x03,0xa1,0xe0,0xca,0x00,0x3e,0x00,0x0e,0x85,0x03,0xa0,0x00,0xf8,0x00 } },
+{  16, 0x8f10, 0, {0x2e,0x00,0x9c,0xa0,0x03,0xe0,0x00,0xc8,0x28,0x3e,0x00,0x0f,0x80,0x03,0x2e,0x01 } },
+{  16, 0x8f20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x40,0xf5,0x10,0x3f,0x44 } },
+{  16, 0x8f30, 0, {0x0f,0xd0,0x03,0xf4,0x00,0xf1,0x10,0x3d,0x40,0x8f,0xd4,0x03,0xe4,0x50,0xf9,0x10 } },
+{  16, 0x8f40, 0, {0x3e,0x45,0x0f,0x91,0x03,0xd4,0x40,0xfc,0x00,0x3f,0xc0,0x8f,0xd0,0x23,0xe6,0x04 } },
+{  16, 0x8f50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x20,0xcd,0xa8,0x33,0x40 } },
+{  16, 0x8f60, 0, {0x8d,0xd0,0x03,0x26,0x80,0xcd,0x00,0x3d,0x50,0x0c,0x9a,0x03,0x64,0x00,0xf9,0xa0 } },
+{  16, 0x8f70, 0, {0x7a,0x6a,0x0f,0x9a,0x63,0xe6,0x80,0xc9,0x80,0x3e,0x40,0x0f,0x90,0x03,0x06,0x00 } },
+{  16, 0x8f80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x00,0x88,0xe0,0x36,0x00 } },
+{  16, 0x8f90, 0, {0x08,0x80,0x0a,0x21,0x42,0xc8,0x00,0x2e,0x29,0x0c,0xa4,0x42,0x20,0x00,0xb8,0x40 } },
+{  16, 0x8fa0, 0, {0x2e,0x00,0x0b,0x81,0x02,0xe1,0x00,0x88,0x02,0x3a,0x01,0x0b,0xc0,0x02,0x0e,0x04 } },
+{  16, 0x8fb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x02,0x81,0x08,0x24,0x40 } },
+{  16, 0x8fc0, 0, {0x09,0x10,0x02,0x04,0x00,0x91,0x00,0x2c,0x40,0x4b,0x14,0x02,0x44,0x00,0xb5,0x10 } },
+{  16, 0x8fd0, 0, {0x29,0x40,0x0b,0x50,0x02,0xf5,0x00,0xb5,0x00,0x2d,0x40,0x0b,0xd0,0x02,0x02,0x01 } },
+{  16, 0x8fe0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa6,0x01,0x89,0x00,0x26,0x40 } },
+{  16, 0x8ff0, 0, {0x08,0x94,0x02,0x24,0x01,0x89,0x00,0x2e,0x40,0x1a,0x90,0x02,0x6c,0x00,0xbf,0x02 } },
+{  16, 0x9000, 0, {0x2f,0x40,0x0b,0xd0,0x02,0xf4,0x02,0xbd,0x80,0x2b,0x40,0x8b,0xd8,0x3a,0x06,0x04 } },
+{  16, 0x9010, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x05,0x36,0x41 } },
+{  16, 0x9020, 0, {0x0d,0x1c,0x03,0x24,0x00,0xd9,0x00,0x3e,0x42,0x2f,0x94,0x03,0x64,0x00,0xf9,0x00 } },
+{  16, 0x9030, 0, {0x3a,0x40,0x0f,0x90,0x03,0xc4,0x00,0xf9,0x00,0x3e,0x70,0x0f,0x10,0x03,0x28,0x04 } },
+{  16, 0x9040, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x84,0x08,0xf9,0x24,0x3e,0x40 } },
+{  16, 0x9050, 0, {0x0f,0x91,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x41,0x0d,0x10,0x03,0xa4,0x00,0xf9,0x00 } },
+{  16, 0x9060, 0, {0x3e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xc9,0x00,0x3e,0x64,0x0f,0x90,0x03,0xca,0x00 } },
+{  16, 0x9070, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x08,0xc8,0x80,0x32,0x02 } },
+{  16, 0x9080, 0, {0x0f,0x80,0x03,0x00,0x00,0xc8,0x08,0x3a,0x10,0xce,0x84,0x03,0xe0,0x00,0xfc,0x00 } },
+{  16, 0x9090, 0, {0x3f,0x00,0x8f,0xc0,0x03,0xf0,0x80,0xfc,0x00,0x3f,0x18,0x0f,0xc0,0x43,0xca,0x04 } },
+{  16, 0x90a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8e,0x00,0xa1,0x80 } },
+{  16, 0x90b0, 0, {0x0b,0xe0,0x02,0x28,0x00,0xde,0xc2,0x23,0x90,0x00,0xa0,0x02,0xe8,0x00,0xba,0x00 } },
+{  16, 0x90c0, 0, {0x2e,0x80,0x0b,0xa0,0x02,0xe8,0x00,0xfa,0x00,0x2e,0x80,0x0b,0xa0,0x02,0xca,0x00 } },
+{  16, 0x90d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x99,0x81,0x60,0xc0 } },
+{  16, 0x90e0, 0, {0x0b,0x10,0x02,0x0c,0x00,0x90,0x10,0x2a,0xfc,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x00 } },
+{  16, 0x90f0, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x00,0x2c,0xc0,0x0b,0x30,0x02,0xca,0x00 } },
+{  16, 0x9100, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x82,0x95,0x40,0x21,0xc0 } },
+{  16, 0x9110, 0, {0x0b,0x50,0x02,0x1c,0x80,0x90,0x80,0x23,0x01,0x09,0x72,0x12,0xdc,0x00,0xb6,0x00 } },
+{  16, 0x9120, 0, {0x2d,0x00,0x0b,0x40,0x02,0xd0,0x00,0xb4,0x09,0x2d,0x00,0x4b,0x40,0x82,0xe8,0x00 } },
+{  16, 0x9130, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x80,0xdd,0x80,0xb1,0xe0 } },
+{  16, 0x9140, 0, {0x0f,0xda,0x03,0x0f,0x80,0xd4,0x80,0x39,0xe0,0x0b,0x7a,0x03,0xde,0x00,0xf5,0x80 } },
+{  16, 0x9150, 0, {0x3d,0x20,0x0f,0x48,0x03,0xd6,0x10,0xf6,0x81,0x3d,0xe0,0x8f,0x68,0x03,0xea,0x02 } },
+{  16, 0x9160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xed,0x00,0x3e,0x00 } },
+{  16, 0x9170, 0, {0x0f,0x91,0x0b,0xec,0x10,0xf8,0x00,0x3e,0x00,0x0e,0xb0,0x03,0xec,0x00,0xf8,0x00 } },
+{  16, 0x9180, 0, {0x3e,0xc0,0x4f,0xb0,0x03,0xe8,0x00,0xe9,0x01,0x3e,0x00,0x0f,0x90,0x03,0xc2,0x06 } },
+{  16, 0x9190, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x20,0xbf,0x81,0x33,0xa4 } },
+{  16, 0x91a0, 0, {0x8c,0x19,0x03,0x3e,0x00,0xcd,0x80,0x3f,0xe0,0x0f,0xf8,0x83,0x3e,0x00,0xef,0x80 } },
+{  16, 0x91b0, 0, {0x3f,0xe0,0x0f,0xf9,0x13,0xfa,0x10,0xfd,0x80,0x3f,0xa4,0x0f,0xd8,0x03,0xc0,0x00 } },
+{  16, 0x91c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xbf,0x20,0x31,0xc2 } },
+{  16, 0x91d0, 0, {0x08,0x5a,0x02,0x3c,0x02,0x87,0x00,0x2d,0x94,0x0b,0x70,0x0a,0x1c,0x40,0x86,0x10 } },
+{  16, 0x91e0, 0, {0x2d,0x00,0x0b,0x40,0x02,0xd4,0x00,0xf6,0x00,0x2d,0x40,0x4b,0x60,0x02,0xea,0x04 } },
+{  16, 0x91f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x01,0x23,0x80 } },
+{  16, 0x9200, 0, {0x28,0x50,0x02,0x1c,0x00,0x84,0x00,0x2d,0xc0,0x0b,0x30,0x02,0x1c,0x00,0xb5,0x00 } },
+{  16, 0x9210, 0, {0x2d,0x00,0x0b,0x40,0x06,0xd0,0x40,0xb4,0x08,0x2d,0x80,0x0b,0x48,0x02,0xc0,0x00 } },
+{  16, 0x9220, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x00,0xb3,0x08,0xa0,0x20 } },
+{  16, 0x9230, 0, {0x08,0x11,0x8a,0x0e,0x00,0x80,0x00,0x2c,0x90,0x0b,0x37,0x02,0x0c,0x00,0x90,0x00 } },
+{  16, 0x9240, 0, {0x2c,0xc0,0x0b,0x30,0x42,0xcc,0x04,0xa3,0x80,0x2c,0x50,0x0b,0x30,0x02,0xc8,0x04 } },
+{  16, 0x9250, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xf9,0x80,0x32,0x60 } },
+{  16, 0x9260, 0, {0x0c,0xd4,0x03,0x3c,0x80,0x88,0x00,0x3e,0xd0,0x0f,0xf8,0x03,0x28,0x00,0xfa,0x00 } },
+{  16, 0x9270, 0, {0x3e,0xc0,0x0f,0xb0,0x07,0xec,0x01,0xbb,0x80,0x3e,0x54,0x0f,0xb0,0x06,0xea,0x04 } },
+{  16, 0x9280, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xee,0x08,0xf9,0x80,0x3a,0xc0 } },
+{  16, 0x9290, 0, {0x0f,0x90,0x03,0xec,0x00,0xf8,0x40,0x3e,0x58,0x0f,0xb0,0x43,0xe9,0x00,0xeb,0x44 } },
+{  16, 0x92a0, 0, {0x3e,0x00,0x0f,0x80,0x03,0xe0,0x0d,0xf8,0x00,0x3e,0x80,0x0f,0x80,0x03,0xe0,0x00 } },
+{  16, 0x92b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xcf,0x00,0x33,0x40 } },
+{  16, 0x92c0, 0, {0x0c,0xd0,0x03,0x3c,0x30,0xcc,0x00,0x3b,0xc0,0x2d,0xf0,0x03,0xd8,0x02,0xcc,0x00 } },
+{  16, 0x92d0, 0, {0x3d,0x00,0x0c,0xc0,0x03,0xf4,0x00,0xee,0x02,0x37,0x40,0x0c,0xe0,0x03,0xc0,0x44 } },
+{  16, 0x92e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x18,0x83,0x84,0x20,0x00 } },
+{  16, 0x92f0, 0, {0x4a,0x10,0x02,0x0c,0x00,0xa8,0x48,0x2e,0x60,0x08,0xb0,0x02,0xe9,0x00,0x89,0x40 } },
+{  16, 0x9300, 0, {0x2e,0xc0,0x08,0xb0,0x02,0xe8,0x10,0xb1,0x01,0x20,0x80,0x0a,0x90,0x03,0xa0,0x40 } },
+{  16, 0x9310, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x82,0x22,0x08 } },
+{  16, 0x9320, 0, {0x08,0x90,0x02,0x2c,0x14,0x88,0x04,0x2c,0x08,0x08,0xb0,0x12,0xe8,0x00,0x8a,0x00 } },
+{  16, 0x9330, 0, {0x2e,0xc0,0x0a,0xb0,0x02,0xe8,0x01,0xb9,0x00,0x26,0x04,0x08,0x90,0x02,0xe0,0x00 } },
+{  16, 0x9340, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0x83,0x80,0xa2,0xc0 } },
+{  16, 0x9350, 0, {0x0a,0x92,0x02,0x2c,0x00,0xa2,0x00,0x2c,0x00,0x08,0x34,0x02,0xc8,0x00,0x83,0x00 } },
+{  16, 0x9360, 0, {0x2c,0x00,0x28,0x00,0x02,0xc4,0x01,0xba,0x00,0x22,0xc0,0x02,0x20,0x06,0xc2,0x01 } },
+{  16, 0x9370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xca,0x00,0xb2,0x00 } },
+{  16, 0x9380, 0, {0x0c,0x92,0x0b,0x2c,0x04,0xc8,0x04,0x3a,0x00,0x0c,0xb4,0x03,0xe8,0x00,0xc8,0x00 } },
+{  16, 0x9390, 0, {0x2e,0x00,0x0c,0x80,0x33,0xe1,0x40,0xe8,0x00,0x36,0x00,0x0c,0x80,0x03,0xc0,0x03 } },
+{  16, 0x93a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xff,0x00,0x3d,0x00 } },
+{  16, 0x93b0, 0, {0x0f,0xd1,0x0b,0xfc,0x01,0xfc,0x00,0x3f,0x00,0x0f,0xf0,0x03,0xd8,0x00,0xfd,0x00 } },
+{  16, 0x93c0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x80,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x07,0xa8,0x06 } },
+{  16, 0x93d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xf3,0x00,0xcf,0x80,0x35,0x60 } },
+{  16, 0x93e0, 0, {0x4e,0x68,0x43,0x5c,0x00,0xe7,0x80,0x39,0xc0,0x0c,0xc1,0x03,0x7e,0x00,0xcf,0x34 } },
+{  16, 0x93f0, 0, {0x35,0xe1,0x4d,0xf2,0x03,0x7c,0x00,0xdf,0x38,0x3f,0xc8,0x0f,0xf8,0x03,0xf0,0x00 } },
+{  16, 0x9400, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0xc8,0x00,0xdb,0x84,0x22,0x60 } },
+{  16, 0x9410, 0, {0x08,0xac,0x0a,0x2c,0x00,0x8b,0x80,0x22,0x30,0x08,0x91,0x22,0x2c,0x90,0x27,0x61 } },
+{  16, 0x9420, 0, {0x22,0xca,0x88,0xfc,0x22,0xbf,0x00,0x8b,0x62,0x2f,0xd0,0x09,0xb8,0x03,0xb0,0x04 } },
+{  16, 0x9430, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0xe2,0x80,0xa9,0x02,0x24,0x40 } },
+{  16, 0x9440, 0, {0x82,0x34,0x42,0x04,0x00,0xa9,0x00,0x28,0xc5,0x48,0x32,0x02,0x4c,0x20,0x83,0x30 } },
+{  16, 0x9450, 0, {0x20,0xc0,0x08,0x31,0x02,0x0d,0x00,0xb3,0x20,0x2c,0xc4,0x0b,0x30,0x02,0xf2,0x01 } },
+{  16, 0x9460, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xaa,0x02,0xb9,0x04,0x22,0x60 } },
+{  16, 0x9470, 0, {0x28,0xb2,0x02,0x26,0x00,0x89,0x88,0x02,0xc0,0x08,0x31,0x12,0xec,0x00,0x8b,0x00 } },
+{  16, 0x9480, 0, {0x2a,0xd0,0x08,0xb0,0x02,0xac,0x00,0x2b,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0xb0,0x04 } },
+{  16, 0x9490, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xe2,0x00,0xe3,0x00,0x36,0x20 } },
+{  16, 0x94a0, 0, {0x0e,0xa4,0x63,0x6e,0x00,0xe1,0xc0,0x1a,0xc1,0x0c,0x80,0x03,0x68,0x70,0xcb,0x00 } },
+{  16, 0x94b0, 0, {0x36,0x80,0x0d,0xb0,0x03,0x4c,0x00,0xfb,0x04,0x3e,0xc1,0x0f,0xb0,0x03,0xd0,0x04 } },
+{  16, 0x94c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb8,0x04,0xdf,0x00,0x3f,0x00 } },
+{  16, 0x94d0, 0, {0x0f,0xe8,0x03,0xfc,0x00,0xfd,0x00,0x3f,0x00,0x2b,0x98,0x03,0x3a,0x00,0x77,0x00 } },
+{  16, 0x94e0, 0, {0x27,0xe4,0x0f,0xf0,0x03,0xfc,0x00,0xdf,0x00,0x3e,0xc0,0x0d,0xf0,0x43,0xf8,0x00 } },
+{  16, 0x94f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0xa4,0x68,0xcb,0x20,0x3a,0x90 } },
+{  16, 0x9500, 0, {0x0f,0x24,0xa3,0xac,0x00,0xe9,0x50,0x3a,0xc0,0x0e,0xb4,0x83,0x2c,0x08,0xeb,0x00 } },
+{  16, 0x9510, 0, {0x3a,0x90,0x0e,0xb0,0x8b,0xec,0x80,0xfb,0x00,0x3e,0xc0,0x0e,0xb0,0x03,0x90,0x04 } },
+{  16, 0x9520, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x01,0x0a,0x00,0x8b,0xa0,0x20,0x80 } },
+{  16, 0x9530, 0, {0x0d,0xa8,0x02,0x2c,0x04,0x89,0x40,0x28,0xe8,0x08,0xb2,0x02,0x2c,0x00,0xaf,0x00 } },
+{  16, 0x9540, 0, {0x02,0x80,0x08,0x7c,0x03,0x3d,0x80,0x3f,0x00,0x2f,0xc0,0x08,0xb0,0x02,0x36,0x00 } },
+{  16, 0x9550, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x49,0x00,0x03,0x40,0x28,0xc0 } },
+{  16, 0x9560, 0, {0x2b,0x28,0x4a,0x28,0x00,0xa1,0x00,0x68,0xd2,0x0a,0x20,0x42,0xa4,0x01,0xa3,0x00 } },
+{  16, 0x9570, 0, {0x02,0x40,0x0a,0x34,0x02,0x0d,0x00,0x33,0x00,0x2c,0xc0,0x0a,0x30,0x00,0xb8,0x00 } },
+{  16, 0x9580, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x01,0x1a,0x00,0x87,0x90,0x21,0xe4 } },
+{  16, 0x9590, 0, {0x2b,0xc8,0x12,0x3a,0x00,0x85,0xc0,0x2b,0x21,0x28,0x68,0x02,0xb6,0x00,0xa7,0x84 } },
+{  16, 0x95a0, 0, {0x23,0x60,0x08,0x38,0x80,0x1e,0x00,0xb7,0x80,0x2d,0xe0,0x08,0x78,0x02,0x2e,0x00 } },
+{  16, 0x95b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x00,0xc1,0x00,0x38,0x54 } },
+{  16, 0x95c0, 0, {0x0f,0x26,0x83,0x80,0x00,0xe0,0x34,0x28,0xc8,0x0e,0x2c,0x0b,0x8c,0x00,0xe3,0x00 } },
+{  16, 0x95d0, 0, {0x78,0x45,0x0e,0x30,0x03,0x8e,0x80,0xf3,0x00,0x3c,0xc8,0x0e,0x30,0x03,0x92,0x02 } },
+{  16, 0x95e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb8,0x00,0xf5,0x02,0x3f,0x44 } },
+{  16, 0x95f0, 0, {0x0d,0x90,0x03,0xf8,0x00,0xbd,0x14,0x1f,0xc0,0x0f,0xe1,0x23,0x5c,0x44,0x9f,0x42 } },
+{  16, 0x9600, 0, {0x3f,0xc0,0x0f,0xf4,0x82,0x7d,0x40,0xff,0x10,0x3f,0xc0,0x4f,0x70,0x07,0xd0,0x06 } },
+{  16, 0x9610, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe8,0x02,0xcb,0x00,0x38,0xc0 } },
+{  16, 0x9620, 0, {0x3c,0xa0,0x03,0xec,0x00,0xe9,0x00,0x3e,0xc0,0x0c,0xb0,0x03,0x20,0x04,0xfb,0x21 } },
+{  16, 0x9630, 0, {0x3e,0x80,0x4f,0xb4,0x03,0xcf,0x00,0xcb,0x00,0x3e,0xcc,0x4f,0xb0,0x43,0xea,0x00 } },
+{  16, 0x9640, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x91,0x98,0x00,0x87,0x00,0x21,0xc0 } },
+{  16, 0x9650, 0, {0x08,0x40,0x02,0xdc,0x04,0xb5,0x00,0x2d,0x00,0x2d,0x70,0x02,0x1c,0x1c,0xb7,0x02 } },
+{  16, 0x9660, 0, {0x2d,0xc0,0x0b,0x72,0x02,0xdc,0x00,0x87,0x40,0x2d,0xca,0x8b,0x70,0x02,0xf2,0x04 } },
+{  16, 0x9670, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xba,0x00,0x87,0x88,0x2b,0xe0 } },
+{  16, 0x9680, 0, {0x18,0x78,0x22,0xd6,0x11,0xa4,0x82,0x2f,0xe0,0x08,0x78,0x02,0x12,0x00,0xb7,0x94 } },
+{  16, 0x9690, 0, {0x6d,0x60,0x4b,0x7a,0x02,0xde,0x40,0xb7,0xa0,0x2d,0xe0,0x0b,0x78,0x06,0xe0,0x00 } },
+{  16, 0x96a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xc9,0x12,0x83,0x82,0x28,0xd4 } },
+{  16, 0x96b0, 0, {0x98,0x00,0x06,0xef,0x05,0xb1,0x90,0x2c,0xc1,0x09,0xb4,0x02,0x0c,0x04,0xb3,0x01 } },
+{  16, 0x96c0, 0, {0x6c,0xf0,0x0b,0x30,0x02,0xcc,0x00,0xbb,0x00,0x2e,0xc0,0x0b,0x30,0x02,0xd2,0x04 } },
+{  16, 0x96d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x40,0xca,0x80,0x3b,0xa0 } },
+{  16, 0x96e0, 0, {0x4c,0xe5,0x02,0xf8,0x80,0xee,0x00,0x3d,0x80,0x2c,0xe0,0x0f,0x38,0x80,0xfa,0x00 } },
+{  16, 0x96f0, 0, {0x3f,0xa9,0x0f,0xa0,0x03,0xe8,0x00,0xba,0x02,0x3e,0x80,0x8b,0xa0,0x03,0xfa,0x04 } },
+{  16, 0x9700, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x10,0xf8,0x00,0x26,0x02 } },
+{  16, 0x9710, 0, {0x0f,0x84,0x03,0xe0,0x24,0xf8,0x00,0x3e,0x00,0x4f,0x80,0xa3,0xe0,0x30,0xf8,0x00 } },
+{  16, 0x9720, 0, {0x36,0x02,0x0f,0x80,0x23,0xe0,0x04,0x08,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0x9730, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x00,0xb6,0x41 } },
+{  16, 0x9740, 0, {0x4e,0x99,0x0b,0xa4,0x00,0x69,0x10,0x3e,0x40,0x0c,0x90,0x03,0xa4,0x10,0xc9,0x00 } },
+{  16, 0x9750, 0, {0x3e,0x40,0x0d,0x92,0x03,0xe6,0x00,0xf9,0x00,0x3a,0x40,0x0e,0x90,0x03,0xc2,0x04 } },
+{  16, 0x9760, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x81,0x00,0x20,0x42 } },
+{  16, 0x9770, 0, {0x08,0x14,0x9a,0x24,0x00,0x89,0x00,0x6e,0x50,0x00,0x90,0x02,0x24,0x10,0xd9,0x02 } },
+{  16, 0x9780, 0, {0x6e,0x40,0x0b,0x94,0x03,0xa7,0x00,0xb9,0x00,0x22,0x40,0x08,0x90,0x03,0xe0,0x00 } },
+{  16, 0x9790, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x06,0x00,0x99,0x00,0xa6,0x41 } },
+{  16, 0x97a0, 0, {0x0a,0x90,0x06,0x2c,0x00,0xa9,0x09,0x6e,0x50,0x08,0x91,0x02,0x84,0x04,0x89,0x00 } },
+{  16, 0x97b0, 0, {0x0e,0x40,0x0b,0x94,0x02,0xe5,0x49,0xb9,0x00,0x0a,0x40,0x0a,0x90,0x02,0xc6,0x00 } },
+{  16, 0x97c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x06,0x00,0x81,0x00,0x22,0x40 } },
+{  16, 0x97d0, 0, {0x08,0x12,0x22,0x04,0x81,0xa1,0x00,0x2c,0x40,0x08,0x16,0x02,0x04,0x00,0x91,0x20 } },
+{  16, 0x97e0, 0, {0x2c,0x40,0x0b,0x12,0x42,0x84,0x89,0xb1,0x20,0x20,0x48,0x08,0x10,0x02,0xc2,0x01 } },
+{  16, 0x97f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x00,0x36,0x00 } },
+{  16, 0x9800, 0, {0x0a,0x80,0x03,0xa1,0x40,0xe8,0x00,0x2e,0x00,0x0c,0x00,0x23,0xa1,0x40,0xc8,0x50 } },
+{  16, 0x9810, 0, {0x2e,0x14,0x0d,0x80,0x03,0xe0,0x00,0xf8,0x50,0x3a,0x00,0x0e,0x80,0x03,0xee,0x03 } },
+{  16, 0x9820, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x1d,0xd4,0x00,0xf5,0x00,0xbf,0x40 } },
+{  16, 0x9830, 0, {0x0f,0xd1,0x03,0xf4,0x44,0xdd,0x02,0x3d,0x50,0x2b,0xd1,0x23,0xf4,0x00,0xf9,0x10 } },
+{  16, 0x9840, 0, {0x3f,0x40,0x0d,0x91,0x03,0xa4,0x48,0xf9,0x12,0x3e,0x4e,0x1f,0x90,0x03,0xa6,0x02 } },
+{  16, 0x9850, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xf4,0x00,0xc5,0x04,0x3b,0x40 } },
+{  16, 0x9860, 0, {0x0f,0xd8,0x03,0xa7,0x80,0xfd,0x00,0xb3,0x68,0x0d,0xd8,0x43,0xa5,0x10,0xc9,0xa0 } },
+{  16, 0x9870, 0, {0x32,0x51,0x4f,0x5a,0x43,0x36,0x00,0xc9,0xa0,0x7a,0x68,0x0b,0xd0,0x03,0xc6,0x01 } },
+{  16, 0x9880, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x18,0xca,0x88,0x88,0x02,0x02,0x00 } },
+{  16, 0x9890, 0, {0x8d,0x84,0x22,0x23,0x42,0xf8,0x00,0x22,0x04,0x28,0x8a,0xa2,0xaa,0x94,0x88,0xe9 } },
+{  16, 0x98a0, 0, {0x20,0xa8,0x0a,0x80,0x0a,0x21,0x40,0x80,0xe2,0x2e,0x28,0x0b,0x80,0x02,0xce,0x04 } },
+{  16, 0x98b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x20,0xa1,0x04,0xa8,0xc0 } },
+{  16, 0x98c0, 0, {0x0b,0x1c,0x2a,0x24,0x00,0x39,0x04,0x20,0x40,0x2a,0x1e,0x02,0xe4,0x80,0xb1,0x10 } },
+{  16, 0x98d0, 0, {0x2a,0x48,0x09,0x14,0x46,0x04,0x00,0x81,0x38,0x2c,0x5b,0x0b,0x10,0x02,0xd2,0x00 } },
+{  16, 0x98e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xa4,0x12,0xa9,0x24,0x22,0x40 } },
+{  16, 0x98f0, 0, {0x29,0x90,0x02,0x24,0x00,0x39,0x00,0x02,0x58,0x08,0x18,0x10,0xe6,0x01,0xb9,0x00 } },
+{  16, 0x9900, 0, {0xaa,0x44,0x08,0x90,0x02,0x24,0x00,0x89,0x00,0x0e,0x41,0x0b,0x90,0x02,0xc6,0x04 } },
+{  16, 0x9910, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe4,0x00,0xe1,0x01,0x2a,0x64 } },
+{  16, 0x9920, 0, {0x2f,0x94,0x13,0x24,0x02,0x71,0x60,0x12,0x60,0x4d,0x90,0x00,0xc5,0x02,0xf9,0x00 } },
+{  16, 0x9930, 0, {0x3a,0x40,0x0f,0x90,0x23,0x24,0x02,0xc9,0x02,0x3a,0x40,0x0f,0x90,0x02,0xe8,0x04 } },
+{  16, 0x9940, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x01,0xa4,0x00,0xd9,0x00,0x3e,0x60 } },
+{  16, 0x9950, 0, {0xaf,0x90,0x83,0x64,0x88,0xf9,0x20,0x3e,0x62,0x03,0x90,0x83,0xa4,0x00,0xc9,0x00 } },
+{  16, 0x9960, 0, {0x36,0x60,0x0f,0x10,0x03,0xc4,0x00,0xf9,0x00,0x7e,0x40,0x0f,0x90,0x03,0xda,0x00 } },
+{  16, 0x9970, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa1,0x00,0xc8,0x82,0x32,0x00 } },
+{  16, 0x9980, 0, {0x6f,0x00,0x03,0xa0,0x00,0xd8,0x40,0x30,0x00,0x0e,0x80,0x03,0x60,0x04,0xf8,0x01 } },
+{  16, 0x9990, 0, {0x3e,0x10,0x4f,0x80,0x8b,0x22,0x00,0xf8,0x00,0x32,0x01,0x0e,0x80,0x03,0xca,0x04 } },
+{  16, 0x99a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x38,0x00,0x0e,0x00,0xa9,0x90 } },
+{  16, 0x99b0, 0, {0x2f,0xe6,0x20,0x88,0x00,0x9e,0x80,0x23,0x80,0x0a,0xe8,0x03,0x28,0x00,0xba,0x00 } },
+{  16, 0x99c0, 0, {0x18,0x80,0x0d,0xec,0x02,0x38,0x80,0xba,0x00,0xa2,0x80,0x08,0xa0,0x03,0x8a,0x00 } },
+{  16, 0x99d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6c,0x02,0x83,0x80,0x20,0xc8 } },
+{  16, 0x99e0, 0, {0x0b,0x20,0x02,0x0c,0x01,0x92,0x10,0x68,0xc0,0x3a,0x3c,0x02,0xcc,0x10,0x3b,0x02 } },
+{  16, 0x99f0, 0, {0x0c,0xc0,0x28,0x3c,0x02,0x4e,0x00,0xb3,0x00,0x28,0xc0,0x28,0x30,0x02,0xca,0x00 } },
+{  16, 0x9a00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x14,0x00,0x87,0x42,0x2b,0xc0 } },
+{  16, 0x9a10, 0, {0x29,0x70,0x22,0x9c,0x00,0xb6,0x00,0x2b,0xc2,0x0a,0x60,0x86,0x1c,0x00,0xb7,0x21 } },
+{  16, 0x9a20, 0, {0x29,0xc0,0x00,0x74,0x02,0x5c,0x00,0x37,0x91,0x01,0xe0,0x08,0x74,0x02,0xa8,0x00 } },
+{  16, 0x9a30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0x80,0x21,0xe0 } },
+{  16, 0x9a40, 0, {0x2f,0x78,0x02,0x9e,0x00,0x96,0x80,0x39,0xe0,0x2e,0xf8,0x03,0xde,0x30,0xf7,0xd0 } },
+{  16, 0x9a50, 0, {0x2d,0xf2,0x00,0x78,0x03,0x52,0x00,0xf7,0xa2,0x3b,0xe0,0x0e,0x78,0x07,0xea,0x02 } },
+{  16, 0x9a60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xb4,0x00,0xfb,0x00,0x0c,0xc0 } },
+{  16, 0x9a70, 0, {0x0f,0x30,0x03,0xec,0x10,0xd3,0x00,0xb4,0xc0,0x2f,0x80,0x03,0x6c,0x48,0xfb,0x00 } },
+{  16, 0x9a80, 0, {0x3e,0xc8,0x4d,0x90,0x03,0xa4,0x00,0xfb,0x20,0x1e,0xc0,0x0f,0xb0,0x03,0xc2,0x06 } },
+{  16, 0x9a90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xcc,0x80,0x2b,0x2c } },
+{  16, 0x9aa0, 0, {0x2f,0xf8,0x03,0x7e,0x00,0x6e,0x80,0x3b,0xa1,0x0d,0xd8,0x43,0x3e,0x00,0xff,0x90 } },
+{  16, 0x9ab0, 0, {0x33,0xe0,0x0f,0xe9,0x33,0xfe,0x00,0xcf,0xc0,0x3f,0xe2,0x0f,0xd8,0x03,0xc0,0x00 } },
+{  16, 0x9ac0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xb4,0x40,0x87,0x00,0x21,0x04 } },
+{  16, 0x9ad0, 0, {0x08,0x78,0x02,0x1c,0x00,0x86,0x00,0x21,0xc0,0x28,0x90,0x02,0xdc,0x00,0xb7,0x10 } },
+{  16, 0x9ae0, 0, {0x21,0xc0,0x0f,0x73,0x02,0xcc,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x50,0x02,0xea,0x00 } },
+{  16, 0x9af0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9d,0x00,0xa4,0x00,0x29,0x48 } },
+{  16, 0x9b00, 0, {0x6a,0xf0,0x82,0x4c,0x00,0xae,0x00,0xa1,0xc4,0x29,0x74,0x02,0x5c,0x40,0xa3,0x10 } },
+{  16, 0x9b10, 0, {0x61,0xc2,0x0b,0x60,0x06,0xc8,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x50,0x02,0xc0,0x04 } },
+{  16, 0x9b20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xe6,0x01,0xa3,0x02,0x20,0x40 } },
+{  16, 0x9b30, 0, {0x28,0x3c,0x02,0x0c,0x00,0x83,0x42,0x20,0xc8,0x08,0x10,0x02,0xcd,0x00,0xb3,0x00 } },
+{  16, 0x9b40, 0, {0x28,0xf0,0x0b,0x30,0x02,0xcc,0x01,0x83,0x04,0x2c,0xc0,0x83,0x10,0x02,0xc8,0x04 } },
+{  16, 0x9b50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xaa,0x80,0xeb,0x00,0x38,0xc0 } },
+{  16, 0x9b60, 0, {0x0a,0x90,0x03,0x7c,0x22,0xa2,0x40,0x32,0x48,0x0d,0xb0,0x0b,0x3e,0x00,0xff,0x00 } },
+{  16, 0x9b70, 0, {0x33,0xf4,0x0f,0x90,0x03,0xec,0x00,0x8f,0x02,0x3f,0xc0,0x0f,0x90,0x03,0xea,0x04 } },
+{  16, 0x9b80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe0,0x00,0xd9,0x02,0x3e,0xc0 } },
+{  16, 0x9b90, 0, {0x0e,0xb6,0x03,0xec,0x00,0xfa,0x20,0x3e,0xc0,0x4f,0x24,0x23,0xac,0x60,0xfb,0x00 } },
+{  16, 0x9ba0, 0, {0xa6,0xc0,0x0e,0x90,0x03,0xe4,0x00,0xfb,0x00,0x3c,0xc1,0x0f,0x90,0x03,0xe0,0x00 } },
+{  16, 0x9bb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf8,0x02,0xcf,0x00,0x33,0xe0 } },
+{  16, 0x9bc0, 0, {0x2c,0xf0,0x13,0xbc,0x00,0x2e,0x10,0xb1,0x64,0x2e,0xf0,0x02,0x3c,0x00,0xff,0x02 } },
+{  16, 0x9bd0, 0, {0x3f,0xc1,0x4d,0xec,0x63,0xfe,0x00,0xb7,0x00,0x3b,0xc0,0x0c,0xd8,0x03,0xc0,0x44 } },
+{  16, 0x9be0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x6c,0x28,0x81,0x81,0x22,0xe0 } },
+{  16, 0x9bf0, 0, {0x0a,0x38,0x02,0x3c,0x04,0xba,0xc9,0x32,0xe0,0x20,0x84,0x02,0x2c,0x00,0xbb,0x00 } },
+{  16, 0x9c00, 0, {0x2e,0xc0,0x0b,0x9c,0x02,0xe7,0x81,0xbb,0x04,0x22,0xc0,0x0a,0x99,0x02,0xe0,0x00 } },
+{  16, 0x9c10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x28,0x40,0x88,0x80,0x22,0x88 } },
+{  16, 0x9c20, 0, {0x28,0xbc,0x42,0xac,0x00,0xba,0x00,0x2a,0x80,0x08,0x84,0x02,0xac,0x00,0xbb,0x00 } },
+{  16, 0x9c30, 0, {0x2e,0xc0,0x0b,0xb0,0x82,0xe8,0x90,0xab,0x00,0x62,0xc0,0x08,0xb0,0x12,0xe0,0x00 } },
+{  16, 0x9c40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x89,0x00,0x2a,0x80 } },
+{  16, 0x9c50, 0, {0x28,0xb2,0x02,0x0c,0x00,0xba,0x00,0x20,0xc0,0x08,0x00,0x02,0x8c,0x00,0xb3,0x00 } },
+{  16, 0x9c60, 0, {0x2c,0xc0,0x0b,0x30,0x20,0x4c,0x14,0xb3,0x00,0x20,0xc0,0x08,0x30,0x02,0xc2,0x01 } },
+{  16, 0x9c70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x68,0x00,0xc8,0x00,0xb2,0xc0 } },
+{  16, 0x9c80, 0, {0x2c,0xb2,0x03,0xac,0x00,0xfa,0x00,0x3a,0xc0,0x4e,0xa5,0x03,0xbc,0x00,0xff,0x00 } },
+{  16, 0x9c90, 0, {0x3f,0xc0,0x09,0xa0,0x03,0xe9,0x04,0xef,0x00,0xba,0xc0,0x0c,0xb0,0x01,0xc0,0x01 } },
+{  16, 0x9ca0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xfc,0x00,0xf5,0x00,0x35,0xc0 } },
+{  16, 0x9cb0, 0, {0xaf,0x34,0x03,0xfc,0x00,0xf4,0x00,0x39,0xc0,0x0f,0xc2,0x03,0x7c,0x00,0xff,0x01 } },
+{  16, 0x9cc0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0xa0,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8,0x05 } },
+{  16, 0x9cd0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xff,0x29,0x3d,0x20 } },
+{  16, 0x9ce0, 0, {0x8e,0xc1,0x03,0x32,0x48,0xdc,0x80,0x23,0x25,0x0e,0xf2,0x03,0x3c,0xc0,0xdf,0x84 } },
+{  16, 0x9cf0, 0, {0x33,0xc9,0x0f,0xf2,0x03,0xfc,0x00,0xcf,0x80,0x33,0x40,0x0c,0xf2,0x03,0x30,0x00 } },
+{  16, 0x9d00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0xc0,0xbb,0x60,0x2e,0x08 } },
+{  16, 0x9d10, 0, {0x08,0x81,0x02,0x20,0x04,0x88,0x20,0x20,0x48,0x08,0xf1,0x82,0x2d,0xc0,0x83,0x00 } },
+{  16, 0x9d20, 0, {0x22,0xd4,0x09,0xf5,0x02,0xfc,0x08,0x8b,0x01,0x22,0x40,0x28,0xb4,0x02,0x20,0x04 } },
+{  16, 0x9d30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x20,0xb3,0x09,0x2c,0x82 } },
+{  16, 0x9d40, 0, {0x08,0x10,0x16,0xa0,0x10,0x90,0x08,0x28,0x48,0x0a,0x32,0x02,0x0c,0x00,0xbb,0x00 } },
+{  16, 0x9d50, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x02,0x93,0x01,0x20,0x00,0x8a,0x31,0x22,0xe2,0x01 } },
+{  16, 0x9d60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x04,0xbb,0x00,0x2c,0x80 } },
+{  16, 0x9d70, 0, {0x08,0x86,0x02,0xa0,0x20,0xa0,0x00,0x2a,0x60,0x0a,0xb0,0x10,0x2c,0x00,0xab,0x0c } },
+{  16, 0x9d80, 0, {0x6e,0xc0,0x09,0xb0,0x02,0xcc,0x00,0x9b,0x00,0x22,0x60,0x0a,0xb0,0x02,0xf0,0x04 } },
+{  16, 0x9d90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xec,0x00,0xbb,0x00,0x3e,0x34 } },
+{  16, 0x9da0, 0, {0x08,0xa0,0x0b,0x83,0x00,0xd9,0x02,0x3a,0xe0,0x2e,0xb0,0x0b,0x2c,0x00,0xf8,0x80 } },
+{  16, 0x9db0, 0, {0x3e,0xc0,0x4f,0xb0,0x03,0xec,0x00,0xca,0x40,0xb2,0x72,0x0e,0xb0,0x0b,0xc0,0x04 } },
+{  16, 0x9dc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbc,0x10,0xfb,0x00,0x3f,0x00 } },
+{  16, 0x9dd0, 0, {0x0d,0xf8,0x13,0x70,0x48,0xdd,0x40,0x37,0xc2,0x8d,0xf0,0x03,0xdc,0x00,0xdd,0xc8 } },
+{  16, 0x9de0, 0, {0x13,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xee,0x40,0x7f,0x40,0x0d,0x70,0x03,0x38,0x00 } },
+{  16, 0x9df0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x01,0x32,0xc0 } },
+{  16, 0x9e00, 0, {0x04,0x10,0x03,0x20,0x40,0xe8,0x10,0x3a,0xc0,0x0d,0xb0,0x03,0xac,0x08,0xf8,0x40 } },
+{  16, 0x9e10, 0, {0xb2,0xc0,0x2c,0xb0,0x33,0xa4,0x82,0xda,0x40,0xba,0x40,0x0f,0xb0,0x03,0xd0,0x04 } },
+{  16, 0x9e20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3c,0x08,0xbf,0x80,0x22,0xc8 } },
+{  16, 0x9e30, 0, {0x08,0xb7,0x00,0x23,0x44,0x88,0xd0,0x22,0xd0,0x08,0x70,0x82,0xfc,0x00,0xb2,0xe0 } },
+{  16, 0x9e40, 0, {0x03,0xf4,0x08,0xf5,0x02,0x37,0x04,0x8b,0xd1,0x22,0x60,0x4b,0xfd,0x02,0xf2,0x00 } },
+{  16, 0x9e50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb3,0x10,0xa4,0x40 } },
+{  16, 0x9e60, 0, {0x08,0x00,0x02,0x48,0x00,0xa0,0x42,0x2a,0xd0,0x01,0x30,0x02,0x8c,0x00,0xb3,0x80 } },
+{  16, 0x9e70, 0, {0x2c,0xc0,0x09,0x31,0x02,0xcc,0x00,0x89,0x00,0x22,0xe8,0x03,0x38,0x02,0xf8,0x00 } },
+{  16, 0x9e80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x1e,0x00,0xb7,0x80,0x27,0x64 } },
+{  16, 0x9e90, 0, {0x68,0x4a,0x02,0x52,0x00,0x8c,0x80,0x21,0xe0,0x08,0x78,0x02,0xde,0x00,0xb7,0x80 } },
+{  16, 0x9ea0, 0, {0x2d,0xe2,0x19,0x39,0x02,0x5e,0x30,0x85,0x98,0x21,0xe4,0x0b,0x79,0x02,0xd8,0x00 } },
+{  16, 0x9eb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xf3,0x20,0x34,0x00 } },
+{  16, 0x9ec0, 0, {0x0c,0xb8,0x03,0x48,0x80,0xe2,0x22,0x38,0xc0,0x0d,0x30,0x03,0x8c,0x00,0xf3,0x00 } },
+{  16, 0x9ed0, 0, {0x3e,0xc0,0x0d,0x31,0x03,0xec,0x00,0xcb,0x00,0x38,0x06,0x0f,0x30,0x83,0xd2,0x02 } },
+{  16, 0x9ee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x00,0xff,0x00,0x3b,0x01 } },
+{  16, 0x9ef0, 0, {0x0f,0xd0,0x03,0x90,0x00,0xf6,0x00,0x3f,0xc0,0x0f,0xf4,0x01,0xfc,0x00,0xff,0x01 } },
+{  16, 0x9f00, 0, {0x33,0xc2,0x0e,0xf5,0x13,0xbc,0x00,0xed,0x00,0x3f,0xc4,0x0f,0xf0,0x03,0xd0,0x06 } },
+{  16, 0x9f10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xfb,0x00,0x3c,0xc0 } },
+{  16, 0x9f20, 0, {0x0e,0xa0,0x01,0x64,0x01,0xd8,0x00,0x32,0xe0,0x2c,0xb5,0x03,0x2c,0x00,0xf2,0x00 } },
+{  16, 0x9f30, 0, {0x7a,0xc0,0x0d,0xb4,0x03,0x2d,0x80,0xc9,0x02,0x32,0xc0,0x0c,0xb0,0x03,0x2a,0x00 } },
+{  16, 0x9f40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x80,0xb7,0x00,0x2d,0xc0 } },
+{  16, 0x9f50, 0, {0x0d,0x60,0x02,0xd0,0x01,0x84,0x00,0x21,0xc0,0x08,0x30,0x02,0x1d,0x00,0xb7,0x00 } },
+{  16, 0x9f60, 0, {0x21,0xc8,0x0b,0xf4,0x03,0x1e,0xc0,0x86,0x00,0x21,0xc0,0x08,0x7c,0x03,0x52,0x04 } },
+{  16, 0x9f70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0xc0,0xb7,0x90,0x2d,0xe0 } },
+{  16, 0x9f80, 0, {0x08,0x78,0x06,0xd6,0x01,0xb4,0x82,0x21,0xe0,0x08,0x78,0x0a,0x1e,0x00,0xb5,0xc0 } },
+{  16, 0x9f90, 0, {0x29,0xe8,0x09,0x78,0x02,0x36,0xc1,0x97,0x80,0x28,0xb0,0x0a,0x7a,0x02,0x30,0x00 } },
+{  16, 0x9fa0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xbb,0x00,0x2c,0xe0 } },
+{  16, 0x9fb0, 0, {0x09,0x35,0x82,0xc0,0xc1,0xa0,0x51,0x20,0xe4,0x08,0x30,0x02,0x8c,0x00,0xbb,0xc4 } },
+{  16, 0x9fc0, 0, {0x20,0xc0,0x0b,0x30,0x02,0x06,0x00,0x93,0x18,0xaa,0xb0,0x2a,0x30,0x0a,0x52,0x04 } },
+{  16, 0x9fd0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x01,0x3d,0xac } },
+{  16, 0x9fe0, 0, {0x4c,0xec,0x13,0x78,0x10,0xf6,0x80,0xb3,0x90,0x0c,0xa0,0x03,0x28,0x00,0xfe,0x00 } },
+{  16, 0x9ff0, 0, {0x3a,0x81,0x0d,0xa0,0x0f,0x2a,0x80,0xde,0x04,0x3b,0xa0,0x0e,0xa0,0x03,0x3a,0x04 } },
+{  16, 0xa000, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x00 } },
+{  16, 0xa010, 0, {0x0d,0x80,0x02,0xe1,0x00,0xd8,0x48,0x3e,0x12,0x0f,0x80,0x13,0x60,0x00,0xf8,0x60 } },
+{  16, 0xa020, 0, {0x3e,0x00,0x07,0x80,0x03,0xa0,0x02,0xe8,0x04,0x26,0x08,0x05,0x80,0x03,0x92,0x00 } },
+{  16, 0xa030, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x04,0x3a,0x40 } },
+{  16, 0xa040, 0, {0x0c,0x12,0x03,0x24,0x82,0xc9,0x00,0x36,0x44,0x0f,0x10,0x03,0x24,0x00,0xf9,0x00 } },
+{  16, 0xa050, 0, {0x36,0x40,0x04,0x90,0x03,0x04,0x00,0xc9,0x00,0x12,0x40,0x0c,0x90,0x03,0x02,0x04 } },
+{  16, 0xa060, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x81,0x22,0x40 } },
+{  16, 0xa070, 0, {0x08,0x90,0x1a,0x24,0x00,0x89,0x00,0x22,0x68,0x0b,0x99,0x02,0x24,0x00,0xb9,0x00 } },
+{  16, 0xa080, 0, {0x22,0x40,0x68,0x90,0x0a,0x24,0x00,0x89,0x00,0xa2,0x40,0x08,0x90,0x0a,0x20,0x00 } },
+{  16, 0xa090, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x10,0x22,0xe0 } },
+{  16, 0xa0a0, 0, {0x08,0x94,0x00,0x04,0x04,0x8b,0x08,0x26,0xc0,0x0b,0x90,0x02,0x24,0x04,0xb9,0x0c } },
+{  16, 0xa0b0, 0, {0x24,0x40,0x0a,0x10,0x02,0x24,0x00,0x23,0x02,0x2a,0x40,0xa8,0x10,0x02,0x06,0x00 } },
+{  16, 0xa0c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x90,0xb1,0x20,0x22,0x40 } },
+{  16, 0xa0d0, 0, {0x08,0x12,0x02,0x0c,0x10,0x81,0x02,0xa0,0x50,0x0b,0x12,0x02,0x04,0x80,0xb1,0x05 } },
+{  16, 0xa0e0, 0, {0x00,0x48,0x0a,0x10,0x02,0x04,0xa0,0xa1,0x00,0x28,0x4a,0x08,0x12,0x00,0x02,0x01 } },
+{  16, 0xa0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x50,0xba,0x14 } },
+{  16, 0xa100, 0, {0x0c,0x85,0x03,0x01,0x42,0xc8,0x50,0x34,0x00,0x0f,0x85,0x03,0x21,0x40,0xf8,0x00 } },
+{  16, 0xa110, 0, {0x36,0x00,0x0e,0x80,0x13,0x20,0x80,0xe0,0x00,0x1a,0x08,0x0c,0x00,0x03,0x2e,0x03 } },
+{  16, 0xa120, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x44,0xf9,0x10,0x3f,0x40 } },
+{  16, 0xa130, 0, {0x2f,0xd1,0x13,0xf4,0x04,0xf5,0x00,0x3f,0x40,0x0f,0x91,0x0b,0xe4,0x40,0xff,0x28 } },
+{  16, 0xa140, 0, {0xbe,0x4e,0x0d,0x96,0x83,0xd4,0xa2,0xdd,0x28,0x37,0x4a,0x0f,0x93,0x83,0xe6,0x06 } },
+{  16, 0xa150, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x05,0xe4,0x10,0xcd,0x00,0x3f,0x40 } },
+{  16, 0xa160, 0, {0x0f,0xd0,0x03,0x35,0x02,0x5d,0x01,0x31,0x44,0x0f,0xd0,0x03,0x24,0x00,0xf9,0x00 } },
+{  16, 0xa170, 0, {0x32,0x60,0x0c,0x98,0x83,0xe6,0x40,0xd9,0x00,0x36,0x6a,0x0c,0x9e,0x83,0x26,0x01 } },
+{  16, 0xa180, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x00,0x88,0x00,0x2e,0x00 } },
+{  16, 0xa190, 0, {0x0b,0x80,0x42,0x02,0x80,0x8a,0x00,0x22,0x20,0x88,0x80,0x03,0x20,0x08,0xb8,0x82 } },
+{  16, 0xa1a0, 0, {0x22,0x21,0x08,0x88,0x82,0xe2,0x42,0x88,0xa8,0x22,0x20,0x08,0xce,0x02,0x0e,0x04 } },
+{  16, 0xa1b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x02,0x81,0x00,0x68,0x40 } },
+{  16, 0xa1c0, 0, {0x0b,0x10,0x02,0x84,0x01,0xb9,0x00,0x20,0x40,0x49,0x10,0x0a,0x04,0x00,0xb5,0x08 } },
+{  16, 0xa1d0, 0, {0x21,0x46,0x08,0x50,0x02,0xd4,0x00,0x8d,0x20,0x25,0x4a,0x0b,0x50,0x02,0x42,0x01 } },
+{  16, 0xa1e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x00,0x89,0x04,0x6e,0x54 } },
+{  16, 0xa1f0, 0, {0x0b,0x10,0x12,0xa4,0x01,0xa9,0x00,0xa2,0x40,0x18,0x90,0x16,0x24,0x00,0xb9,0x00 } },
+{  16, 0xa200, 0, {0x23,0x40,0x18,0xd0,0x02,0xf4,0x00,0x8d,0x40,0x21,0x4a,0x0b,0xd0,0x02,0x46,0x04 } },
+{  16, 0xa210, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x00,0x3a,0x50 } },
+{  16, 0xa220, 0, {0x8f,0x96,0x0b,0x84,0x02,0xf1,0x01,0x30,0x48,0x8d,0x90,0x03,0x24,0x10,0xf9,0x00 } },
+{  16, 0xa230, 0, {0xb2,0x40,0x2c,0x90,0x03,0xe6,0x40,0xd1,0xc0,0x36,0x50,0x2f,0x90,0x0b,0x68,0x04 } },
+{  16, 0xa240, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x60 } },
+{  16, 0xa250, 0, {0x0f,0x99,0xc3,0x64,0x00,0xd9,0x28,0x3e,0x40,0x0d,0x90,0x03,0xa4,0x00,0xf9,0x40 } },
+{  16, 0xa260, 0, {0x3e,0x40,0x0f,0x90,0x03,0xe4,0x20,0xf9,0x40,0x3e,0x40,0x0c,0x90,0x03,0x8a,0x00 } },
+{  16, 0xa270, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x01,0x36,0x00 } },
+{  16, 0xa280, 0, {0x8f,0x80,0x03,0xe0,0x02,0xf8,0x04,0x32,0x00,0x0d,0x80,0x43,0x20,0x02,0xcc,0x00 } },
+{  16, 0xa290, 0, {0x3f,0x00,0x0f,0xc0,0x13,0x90,0x02,0xdc,0x40,0x3f,0x10,0x4c,0xc0,0x23,0x0a,0x04 } },
+{  16, 0xa2a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0xba,0x00,0x22,0x80 } },
+{  16, 0xa2b0, 0, {0x0b,0xe8,0x20,0xf8,0x00,0x4e,0xc0,0x23,0xa0,0x08,0xa0,0x03,0x68,0x00,0x8a,0x00 } },
+{  16, 0xa2c0, 0, {0x2e,0x80,0x1f,0xa0,0x02,0x2a,0x06,0x8a,0x00,0x2e,0xa0,0x02,0x60,0x03,0x0a,0x00 } },
+{  16, 0xa2d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6c,0x00,0xb3,0x00,0x20,0xc0 } },
+{  16, 0xa2e0, 0, {0x0b,0x3d,0x02,0xc0,0x03,0x23,0x00,0x20,0xe0,0x01,0xb0,0x06,0x4c,0x00,0x8b,0x00 } },
+{  16, 0xa2f0, 0, {0x2e,0xc0,0x4b,0x30,0x02,0x8e,0x08,0x83,0x80,0x2c,0xc4,0x00,0x34,0x8e,0x4a,0x00 } },
+{  16, 0xa300, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x80,0xb5,0x80,0x61,0xc0 } },
+{  16, 0xa310, 0, {0x0b,0x40,0x02,0xd4,0x00,0x84,0x08,0x23,0xc2,0x08,0x50,0x02,0x5e,0xc0,0x84,0x01 } },
+{  16, 0xa320, 0, {0x2d,0x00,0x8a,0x08,0x02,0x10,0x24,0x84,0x08,0x6d,0x00,0x0a,0x03,0x12,0x28,0x00 } },
+{  16, 0xa330, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf5,0x82,0x21,0x60 } },
+{  16, 0xa340, 0, {0x0f,0x78,0x03,0xd6,0x04,0xae,0x80,0x31,0xe0,0x0d,0x58,0x23,0x7e,0x00,0xc6,0x80 } },
+{  16, 0xa350, 0, {0x2d,0xe0,0x0b,0x78,0x03,0x8e,0x00,0xd7,0x82,0x3d,0xf0,0x0c,0x7a,0x03,0x6a,0x02 } },
+{  16, 0xa360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xf1,0x00,0xba,0xd8 } },
+{  16, 0xa370, 0, {0x0f,0x80,0x03,0xe4,0x12,0xf8,0x00,0xbe,0x80,0x0e,0x10,0x03,0xec,0x00,0xf9,0x00 } },
+{  16, 0xa380, 0, {0x3e,0x00,0x5f,0x80,0x03,0xe0,0x08,0xf8,0x04,0x3c,0x00,0x0f,0x80,0x03,0xc2,0x06 } },
+{  16, 0xa390, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x20,0xff,0x80,0x3f,0xf0 } },
+{  16, 0xa3a0, 0, {0x0f,0xf8,0x03,0xd2,0x00,0xef,0x84,0xb3,0x61,0x0c,0xb9,0x03,0xfe,0x00,0xff,0x80 } },
+{  16, 0xa3b0, 0, {0x33,0xe0,0x0c,0xf8,0x13,0x22,0x11,0xcd,0x90,0x3f,0x60,0x0c,0xe8,0x03,0x10,0x00 } },
+{  16, 0xa3c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xf5,0x00,0x2d,0xc0 } },
+{  16, 0xa3d0, 0, {0x0b,0x00,0x02,0xd4,0x04,0x84,0x20,0x23,0x40,0x08,0x5a,0x02,0xdc,0x00,0xb4,0x00 } },
+{  16, 0xa3e0, 0, {0x21,0x00,0x28,0xc2,0x02,0x1e,0x04,0x86,0x04,0x2d,0x88,0x08,0xd0,0x02,0x2a,0x04 } },
+{  16, 0xa3f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x9c,0x00,0xb5,0x00,0x2d,0x40 } },
+{  16, 0xa400, 0, {0x0b,0x70,0x02,0xf4,0x20,0xa7,0x04,0x21,0xc0,0x0a,0x50,0x02,0xdc,0x00,0xbe,0x00 } },
+{  16, 0xa410, 0, {0x21,0xc0,0x08,0x70,0x12,0x00,0x00,0x85,0x00,0x2d,0x40,0x88,0x68,0x0a,0x04,0x00 } },
+{  16, 0xa420, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xcc,0x00,0xa1,0x00,0x2e,0xc0 } },
+{  16, 0xa430, 0, {0x1b,0x08,0x06,0xc4,0x20,0x80,0x00,0x20,0x98,0x1a,0x10,0x02,0xcc,0x00,0xb1,0x08 } },
+{  16, 0xa440, 0, {0x20,0x00,0x08,0x00,0x02,0x0c,0x01,0x82,0xc0,0x2c,0xac,0x28,0x90,0x22,0x18,0x04 } },
+{  16, 0xa450, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xb3,0x00,0x3e,0x40 } },
+{  16, 0xa460, 0, {0x0f,0xba,0x03,0xe5,0x02,0xe9,0x04,0x32,0x90,0xae,0xb0,0x03,0xfc,0x10,0xfb,0x40 } },
+{  16, 0xa470, 0, {0xb2,0x00,0x0c,0x80,0x0b,0x2c,0x02,0x82,0x18,0x3f,0xa0,0x0c,0xd0,0x03,0x2e,0x04 } },
+{  16, 0xa480, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0xec,0x04,0xfb,0x01,0x3e,0x40 } },
+{  16, 0xa490, 0, {0x0f,0xb6,0x43,0xe4,0x00,0xf8,0x00,0x3e,0x80,0x01,0x90,0x03,0xec,0x00,0xf8,0x81 } },
+{  16, 0xa4a0, 0, {0x3e,0xd0,0x0d,0xb4,0x53,0xe0,0x00,0xf9,0x40,0x3e,0x40,0x0f,0xa0,0x03,0xe0,0x00 } },
+{  16, 0xa4b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xdc,0x02,0xcd,0x80,0x33,0x60 } },
+{  16, 0xa4c0, 0, {0x2c,0xda,0x03,0xfc,0x00,0xec,0x00,0x33,0x40,0x0f,0xf2,0x03,0x7c,0x04,0xfe,0x00 } },
+{  16, 0xa4d0, 0, {0x32,0x00,0x0c,0xc8,0x03,0x3c,0x00,0xce,0x00,0x31,0x80,0x0c,0xd1,0x03,0x24,0x04 } },
+{  16, 0xa4e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x91,0x04,0x6c,0x00,0x09,0x00,0x2a,0x64 } },
+{  16, 0xa4f0, 0, {0x08,0x8e,0x02,0xc2,0x10,0xa0,0x10,0x3e,0x10,0x0b,0x98,0x02,0xec,0x00,0xb9,0x00 } },
+{  16, 0xa500, 0, {0x02,0xd8,0x08,0xbe,0x22,0x20,0x00,0x89,0x00,0x22,0x50,0x08,0xa0,0x02,0x20,0x40 } },
+{  16, 0xa510, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x0b,0x20,0x22,0x40 } },
+{  16, 0xa520, 0, {0x08,0xa0,0x02,0xe5,0x42,0xab,0x04,0x22,0x18,0x0b,0xb0,0x02,0x6c,0x00,0xb3,0x00 } },
+{  16, 0xa530, 0, {0x20,0x04,0x08,0x01,0x02,0x00,0x04,0xa8,0x40,0x22,0x10,0x08,0x80,0x02,0x20,0x00 } },
+{  16, 0xa540, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x08,0x83,0x00,0x28,0x40 } },
+{  16, 0xa550, 0, {0x08,0x04,0x02,0xc4,0x02,0xa8,0x00,0x2c,0x00,0x0b,0x12,0x02,0xcc,0x00,0xb0,0x00 } },
+{  16, 0xa560, 0, {0x20,0xc0,0x40,0x30,0x02,0x0c,0x00,0x8b,0x00,0xa8,0xc0,0x08,0x30,0x02,0x02,0x11 } },
+{  16, 0xa570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0d,0x6c,0x00,0xc9,0x00,0x33,0x40 } },
+{  16, 0xa580, 0, {0x0c,0xb0,0x03,0xec,0x02,0xeb,0x00,0x32,0x40,0x0f,0xb0,0x03,0x6c,0x00,0xfa,0x00 } },
+{  16, 0xa590, 0, {0x32,0x00,0x0c,0x80,0x03,0x20,0x80,0xc8,0x00,0x30,0x00,0x0c,0x80,0x03,0x20,0x03 } },
+{  16, 0xa5a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xfc,0x00,0xfd,0x00,0x3f,0x40 } },
+{  16, 0xa5b0, 0, {0x0f,0xc2,0x13,0xf0,0x00,0xf4,0x00,0x3f,0x00,0x4f,0xd4,0x03,0xfc,0x00,0xf5,0x00 } },
+{  16, 0xa5c0, 0, {0x3f,0xc0,0x8f,0xf0,0x03,0xfc,0x40,0xff,0x00,0x37,0xc0,0x2f,0xf0,0x03,0xe8,0x06 } },
+{  16, 0xa5d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0x00,0xcc,0x00,0x33,0x00 } },
+{  16, 0xa5e0, 0, {0x0e,0xd0,0x0b,0x33,0x00,0xcc,0x00,0x33,0xe0,0x0f,0xc0,0x83,0x7c,0x00,0xcf,0x20 } },
+{  16, 0xa5f0, 0, {0x7b,0x09,0x8c,0xf8,0x03,0xfe,0x50,0xcf,0x38,0x3f,0xe1,0x0d,0xc2,0x03,0xf0,0x00 } },
+{  16, 0xa600, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe2,0x00,0x98,0x08,0x20,0x80 } },
+{  16, 0xa610, 0, {0x08,0x98,0x02,0x20,0x00,0x88,0xd0,0x22,0xe0,0x0e,0xb4,0x22,0x7d,0x19,0x9f,0x69 } },
+{  16, 0xa620, 0, {0x2e,0x90,0x08,0x30,0x92,0x28,0x81,0xdb,0x64,0x2e,0xe1,0x88,0x16,0xa2,0xe0,0x04 } },
+{  16, 0xa630, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc8,0x00,0x90,0x24,0x20,0x01 } },
+{  16, 0xa640, 0, {0x08,0x10,0x16,0x00,0x82,0x83,0x01,0x28,0xc1,0x0b,0x02,0x82,0x0c,0xe0,0xa3,0x10 } },
+{  16, 0xa650, 0, {0x28,0x0e,0x1b,0x92,0x02,0x84,0x84,0x93,0x20,0x2e,0xc0,0x08,0x31,0x02,0xe2,0x01 } },
+{  16, 0xa660, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa8,0x10,0x98,0x00,0x22,0x80 } },
+{  16, 0xa670, 0, {0x08,0x90,0x02,0x00,0x60,0x8a,0x10,0x2a,0xc0,0x0a,0x20,0x02,0x6c,0x18,0xbb,0x00 } },
+{  16, 0xa680, 0, {0x6e,0x60,0x2b,0x90,0x02,0x46,0x20,0x8b,0x00,0x2e,0xc2,0x08,0xb1,0x82,0xf0,0x04 } },
+{  16, 0xa690, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xe4,0x02,0xcb,0x00,0xb2,0x40 } },
+{  16, 0xa6a0, 0, {0x2c,0x92,0x03,0x27,0x00,0x88,0x00,0xba,0xc0,0x0f,0x88,0x03,0x2c,0x00,0xeb,0x04 } },
+{  16, 0xa6b0, 0, {0x3a,0xa0,0xcf,0x2c,0xa3,0xed,0x00,0x9b,0x00,0x3c,0xf0,0x2d,0x8c,0x33,0xd0,0x04 } },
+{  16, 0xa6c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb4,0x04,0xef,0x00,0x3f,0xc0 } },
+{  16, 0xa6d0, 0, {0x0d,0x51,0x03,0xf0,0x00,0xf1,0x81,0x37,0xc0,0x0e,0xf4,0x03,0x9c,0x10,0xcf,0x00 } },
+{  16, 0xa6e0, 0, {0x3d,0x80,0x0c,0xec,0x07,0xb8,0x08,0xff,0x02,0x1f,0xc4,0x0f,0xc8,0x03,0xf8,0x00 } },
+{  16, 0xa6f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x9e,0x00,0xc3,0x00,0x38,0x40 } },
+{  16, 0xa700, 0, {0x0c,0x92,0x03,0xa4,0x80,0xfb,0x20,0x3a,0xc0,0x0d,0x94,0x03,0x2c,0x40,0xfb,0x00 } },
+{  16, 0xa710, 0, {0x3e,0x01,0x0f,0x80,0x03,0xe5,0x00,0xeb,0x00,0x3a,0xc0,0x0d,0x84,0x0b,0x10,0x04 } },
+{  16, 0xa720, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x08,0x8b,0x02,0x22,0xc0 } },
+{  16, 0xa730, 0, {0x08,0x92,0x03,0x21,0x00,0x8b,0x48,0x22,0xc0,0x0b,0xb7,0x02,0x3d,0x40,0x3f,0x01 } },
+{  16, 0xa740, 0, {0x22,0x74,0x0b,0x90,0x02,0x28,0x04,0xbf,0x00,0xb2,0xc0,0x0b,0x85,0x02,0x32,0x00 } },
+{  16, 0xa750, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x40,0x01,0x80,0x00,0x28,0x00 } },
+{  16, 0xa760, 0, {0x08,0x2c,0x12,0x88,0x40,0xb0,0x40,0x08,0xc0,0x0b,0x18,0x02,0x0e,0x00,0xb3,0x00 } },
+{  16, 0xa770, 0, {0x28,0x20,0x11,0x30,0x02,0x0c,0x00,0xb3,0x00,0x24,0x00,0x09,0x00,0x06,0x38,0x00 } },
+{  16, 0xa780, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x12,0x00,0x84,0x80,0x21,0xa0 } },
+{  16, 0xa790, 0, {0x28,0x68,0x12,0x3a,0x00,0x84,0x80,0x25,0xe0,0x8b,0x58,0x02,0x1e,0x40,0xb7,0x82 } },
+{  16, 0xa7a0, 0, {0x21,0xa6,0x0b,0x78,0x02,0x1a,0x00,0xb7,0x80,0x21,0x20,0x0b,0x58,0x02,0x08,0x00 } },
+{  16, 0xa7b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x00,0xc8,0x21,0x38,0x09 } },
+{  16, 0xa7c0, 0, {0x0c,0x28,0x03,0x80,0x01,0xf1,0x00,0x38,0xc0,0x0d,0x85,0x02,0x0c,0x00,0xfb,0x00 } },
+{  16, 0xa7d0, 0, {0x38,0x85,0x0f,0x10,0x03,0x8c,0x00,0xeb,0x10,0x3c,0xc8,0x0d,0x30,0x03,0x12,0x02 } },
+{  16, 0xa7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0x98,0x00,0xfc,0x01,0x3f,0x80 } },
+{  16, 0xa7f0, 0, {0x0f,0x68,0x03,0xd0,0x40,0xfc,0x00,0x3b,0xc0,0x0d,0xc0,0x03,0xfc,0x20,0xff,0x00 } },
+{  16, 0xa800, 0, {0x3b,0xc5,0x0f,0xf0,0x0b,0xb4,0x40,0xff,0x18,0x3f,0x00,0x0f,0xf1,0x03,0xd0,0x06 } },
+{  16, 0xa810, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xeb,0x00,0xb0,0x41 } },
+{  16, 0xa820, 0, {0x0c,0xa0,0x03,0xe0,0x04,0xca,0x04,0xb0,0xe0,0x0e,0xb0,0x03,0xec,0x80,0xcb,0x20 } },
+{  16, 0xa830, 0, {0x32,0x81,0x0c,0xa0,0x03,0xee,0x00,0xdb,0x00,0x3e,0x00,0x0e,0xb0,0x03,0x2a,0x00 } },
+{  16, 0xa840, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x04,0x87,0x00,0x21,0xc0 } },
+{  16, 0xa850, 0, {0x48,0x60,0x02,0xf0,0x00,0x87,0x00,0x21,0xc0,0x08,0x70,0x02,0xfc,0xa0,0x83,0x28 } },
+{  16, 0xa860, 0, {0xa3,0x80,0x08,0x60,0x02,0xdc,0x00,0x87,0x20,0x2d,0xc0,0x0b,0x70,0x02,0x12,0x04 } },
+{  16, 0xa870, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9c,0x02,0xa3,0x80,0x21,0x60 } },
+{  16, 0xa880, 0, {0x08,0x68,0x02,0xd2,0x00,0x87,0x80,0x21,0xe0,0x29,0x78,0x02,0xde,0x80,0x87,0x90 } },
+{  16, 0xa890, 0, {0x21,0xa0,0x19,0x48,0x02,0xfe,0x00,0x97,0x80,0x2d,0xe0,0x0a,0x38,0x82,0x30,0x00 } },
+{  16, 0xa8a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x01,0x83,0x80,0x20,0xc0 } },
+{  16, 0xa8b0, 0, {0x08,0x20,0x42,0xc0,0x30,0x83,0x70,0xa0,0xc0,0x89,0x34,0x02,0xcc,0x02,0x83,0x00 } },
+{  16, 0xa8c0, 0, {0x60,0xc0,0x29,0x00,0x02,0xce,0x00,0x83,0x00,0x2c,0xc8,0x0b,0xbc,0x02,0x12,0x04 } },
+{  16, 0xa8d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa9,0x00,0xea,0xe2,0x32,0x90 } },
+{  16, 0xa8e0, 0, {0x2c,0xe0,0x03,0xfb,0x02,0xce,0xc0,0x32,0x80,0x0f,0xe4,0x03,0xe8,0x00,0x8a,0x00 } },
+{  16, 0xa8f0, 0, {0x33,0x88,0x0d,0x64,0xc3,0xfa,0x00,0xda,0x00,0x3d,0x90,0x0e,0xe0,0x0b,0x3a,0x04 } },
+{  16, 0xa900, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xc0,0x24,0xf8,0x08,0x3e,0x12 } },
+{  16, 0xa910, 0, {0x0f,0xc0,0x03,0xe0,0x48,0xf0,0x00,0x3e,0x00,0x0e,0x80,0x93,0xc0,0x00,0xf8,0x00 } },
+{  16, 0xa920, 0, {0x7e,0x01,0x0e,0x80,0xc2,0xe0,0x40,0xf8,0x00,0x7e,0x00,0x8f,0x84,0x03,0xd2,0x00 } },
+{  16, 0xa930, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe5,0x00,0xc1,0x01,0x32,0x48 } },
+{  16, 0xa940, 0, {0x0c,0x98,0x03,0xe6,0x40,0xc9,0x00,0x32,0x40,0x0f,0x90,0x03,0x66,0x00,0xc9,0x00 } },
+{  16, 0xa950, 0, {0x18,0x61,0x0c,0x90,0x03,0x64,0x20,0xf9,0x05,0x3e,0x40,0x0c,0x90,0x83,0x02,0x04 } },
+{  16, 0xa960, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x66,0x20,0x89,0x00,0x20,0x52 } },
+{  16, 0xa970, 0, {0x28,0x10,0xc2,0x26,0x02,0xa9,0x00,0x22,0x40,0x0b,0x90,0x0a,0x27,0x00,0xa9,0x00 } },
+{  16, 0xa980, 0, {0x22,0x70,0x08,0x90,0x02,0x24,0x08,0xb9,0x00,0x2e,0x40,0x0a,0x90,0x0a,0x20,0x00 } },
+{  16, 0xa990, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x02,0x8d,0x00,0x23,0x40 } },
+{  16, 0xa9a0, 0, {0x08,0xd1,0x02,0x84,0x20,0x89,0x00,0x22,0x60,0x0b,0x11,0xf2,0x24,0xb0,0x81,0x00 } },
+{  16, 0xa9b0, 0, {0x2a,0x46,0x08,0x90,0x42,0x64,0x08,0xb9,0x00,0x2e,0x40,0x08,0x92,0x02,0x06,0x00 } },
+{  16, 0xa9c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x14,0x80,0x85,0x20,0x23,0x48 } },
+{  16, 0xa9d0, 0, {0x08,0x52,0x02,0x84,0x08,0x81,0x00,0x20,0x40,0x0b,0x12,0x02,0x04,0x80,0xa1,0x20 } },
+{  16, 0xa9e0, 0, {0x28,0x49,0x28,0x90,0x02,0x04,0x00,0x31,0x20,0x2e,0x40,0x08,0x32,0x02,0x02,0x01 } },
+{  16, 0xa9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc8,0x50,0xb2,0x14 } },
+{  16, 0xaa00, 0, {0x0c,0xc0,0x03,0xa1,0x40,0xc8,0x00,0xb2,0x00,0x07,0x85,0x03,0x21,0x40,0xc8,0x50 } },
+{  16, 0xaa10, 0, {0x3a,0x15,0x0c,0x85,0x03,0x61,0x40,0xf8,0x51,0x3e,0x00,0x2c,0x85,0x03,0x2e,0x03 } },
+{  16, 0xaa20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xc4,0x48,0xf9,0x10,0x3e,0x44 } },
+{  16, 0xaa30, 0, {0x4f,0x91,0x03,0x74,0x00,0xf5,0x44,0x3e,0x40,0x0f,0xd1,0x03,0xe4,0x40,0xf9,0x10 } },
+{  16, 0xaa40, 0, {0x37,0x44,0x0f,0xd0,0x03,0xd4,0x00,0xf9,0x10,0x3f,0xc0,0x0f,0xd1,0x03,0xe6,0x06 } },
+{  16, 0xaa50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xf6,0xa0,0xdd,0x8c,0x33,0x78 } },
+{  16, 0xaa60, 0, {0x0e,0xda,0x03,0x35,0x00,0xcd,0xa0,0x33,0x40,0x0d,0xf8,0x0b,0x36,0x81,0xe9,0x80 } },
+{  16, 0xaa70, 0, {0x33,0x70,0x0c,0x91,0x03,0xe4,0x40,0xf9,0xc0,0x3e,0xc0,0x0f,0xdc,0x03,0xc6,0x00 } },
+{  16, 0xaa80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x04,0xb8,0x40,0x20,0x3c } },
+{  16, 0xaa90, 0, {0x0c,0x85,0x02,0x02,0x84,0x8a,0x40,0x22,0x00,0x08,0x8f,0x82,0x23,0x00,0xb8,0xe8 } },
+{  16, 0xaaa0, 0, {0x22,0x20,0x08,0x88,0x02,0xe2,0x00,0xb8,0xd0,0x2e,0x00,0x0b,0x8c,0x02,0xce,0x04 } },
+{  16, 0xaab0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0x91,0x00,0x60,0x48 } },
+{  16, 0xaac0, 0, {0x4b,0x10,0x02,0x04,0x8a,0x81,0x40,0x60,0x40,0x49,0x10,0x02,0x8d,0xa0,0xa1,0x41 } },
+{  16, 0xaad0, 0, {0x20,0x50,0x09,0x12,0x22,0xc4,0x80,0xb1,0x20,0x2c,0x40,0x4b,0x3e,0x02,0xc2,0x01 } },
+{  16, 0xaae0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x08,0xb9,0x04,0xa0,0x40 } },
+{  16, 0xaaf0, 0, {0x48,0xb0,0x02,0x24,0x00,0x89,0x00,0x82,0x40,0x08,0x90,0xa6,0xa4,0x00,0xb9,0x04 } },
+{  16, 0xab00, 0, {0x22,0x54,0x29,0x95,0x02,0xe5,0x40,0xb9,0x00,0x6e,0x40,0x0b,0x92,0x02,0xc6,0x04 } },
+{  16, 0xab10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe4,0x00,0x91,0x00,0x32,0x40 } },
+{  16, 0xab20, 0, {0x0f,0x90,0x09,0x24,0x00,0x89,0x90,0x32,0x40,0x0d,0x94,0x03,0xa4,0x00,0xe9,0x02 } },
+{  16, 0xab30, 0, {0x72,0x60,0x0d,0x94,0x03,0xe4,0x01,0xf9,0x01,0x3e,0x60,0x0f,0x90,0x03,0xe8,0x04 } },
+{  16, 0xab40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x40,0xf9,0x00,0x3e,0x40 } },
+{  16, 0xab50, 0, {0x4f,0x90,0x03,0xe7,0x10,0xf9,0x80,0x3e,0x40,0x0f,0x10,0x13,0x64,0x00,0xf1,0x00 } },
+{  16, 0xab60, 0, {0xbe,0x40,0x0e,0x90,0x03,0xe6,0x08,0xf9,0x01,0x3e,0x64,0x0f,0x90,0x03,0xca,0x00 } },
+{  16, 0xab70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x00,0xf8,0x00,0x32,0x08 } },
+{  16, 0xab80, 0, {0x0c,0x01,0x0b,0x20,0x40,0xc8,0x40,0x32,0x00,0x0e,0x84,0x83,0x20,0x00,0xf8,0x04 } },
+{  16, 0xab90, 0, {0x3e,0x04,0x0f,0x80,0x03,0x21,0x00,0xe8,0x00,0x3e,0x10,0x0f,0x88,0x03,0xca,0x04 } },
+{  16, 0xaba0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x38,0x00,0x3e,0x04,0x23,0x80 } },
+{  16, 0xabb0, 0, {0x08,0xec,0x12,0x39,0x44,0xa6,0x00,0x28,0x81,0x08,0xe0,0x00,0x38,0x08,0xba,0x00 } },
+{  16, 0xabc0, 0, {0x3f,0x80,0x0b,0xa0,0x02,0xa8,0x00,0x8a,0x02,0x2e,0x80,0x0b,0xe0,0x02,0xca,0x00 } },
+{  16, 0xabd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x48,0x00,0x31,0x00,0x24,0xd0 } },
+{  16, 0xabe0, 0, {0x08,0x3e,0x12,0xae,0x08,0x81,0xa0,0x2c,0xc0,0x0a,0x38,0x00,0x4c,0x00,0xb3,0x00 } },
+{  16, 0xabf0, 0, {0x6e,0xc0,0x0a,0x30,0x02,0x0c,0x00,0xa3,0x00,0x6c,0xc0,0x0b,0x30,0x02,0xca,0x00 } },
+{  16, 0xac00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x18,0x00,0xb5,0x10,0x25,0xc0 } },
+{  16, 0xac10, 0, {0x28,0x60,0x12,0x90,0x10,0xa5,0x08,0x2d,0xc2,0x08,0x64,0x22,0x58,0x18,0xb7,0x00 } },
+{  16, 0xac20, 0, {0x2d,0x80,0x0b,0x79,0x02,0xbe,0xc0,0x87,0x01,0x6d,0xc0,0x0b,0x60,0x02,0xe8,0x00 } },
+{  16, 0xac30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf5,0x84,0x35,0x20 } },
+{  16, 0xac40, 0, {0x8c,0x18,0x02,0x92,0x10,0xc5,0x80,0x3d,0x60,0x0e,0xc8,0x0b,0x5a,0x08,0x77,0xf3 } },
+{  16, 0xac50, 0, {0x3d,0xa0,0x0f,0xf8,0x03,0x1e,0xb0,0xe7,0x85,0x3d,0xe0,0x0f,0x78,0x03,0xea,0x02 } },
+{  16, 0xac60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xf1,0x04,0xba,0x01 } },
+{  16, 0xac70, 0, {0x0f,0xa0,0x43,0x60,0x09,0xe1,0x00,0x38,0x40,0x0e,0xa0,0x03,0xa8,0x14,0xfb,0x20 } },
+{  16, 0xac80, 0, {0x3a,0x80,0x0f,0xb4,0x1b,0x4c,0x80,0xfb,0x29,0x3e,0xc0,0x0f,0xb0,0x23,0xc2,0x06 } },
+{  16, 0xac90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfa,0x00,0xcd,0x80,0x3b,0xe0 } },
+{  16, 0xaca0, 0, {0x4e,0xf8,0x03,0xf2,0x02,0xd4,0x81,0x3b,0xe0,0x8e,0x98,0x07,0x3e,0x44,0xef,0x91 } },
+{  16, 0xacb0, 0, {0x3f,0xe0,0x4f,0xfc,0x07,0xee,0xd0,0xcf,0x98,0x33,0xe4,0x0f,0xf8,0x03,0xc0,0x00 } },
+{  16, 0xacc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x01,0x98,0x00,0x85,0x10,0x2d,0xc4 } },
+{  16, 0xacd0, 0, {0x0d,0x11,0x02,0xf0,0x00,0x85,0x20,0x31,0xc4,0x0b,0x7b,0x00,0x38,0x40,0xd7,0x10 } },
+{  16, 0xace0, 0, {0x2d,0x80,0x0b,0x70,0x62,0xfe,0xe1,0x87,0x14,0x39,0xc0,0x0b,0x60,0x02,0xea,0x04 } },
+{  16, 0xacf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xbc,0x40,0xa5,0x00,0x29,0x40 } },
+{  16, 0xad00, 0, {0x0b,0x50,0x82,0xdc,0x40,0x84,0x04,0x2d,0xc0,0x0b,0x10,0x06,0x58,0x44,0xa7,0x10 } },
+{  16, 0xad10, 0, {0x2d,0x80,0x0b,0x71,0x02,0xdc,0x00,0x87,0x04,0x21,0xc2,0x0b,0x50,0x02,0xc0,0x10 } },
+{  16, 0xad20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x0a,0xa1,0x01,0x2c,0x40 } },
+{  16, 0xad30, 0, {0x89,0x18,0x02,0xc1,0x00,0xa1,0x08,0x20,0xc0,0x0b,0x34,0x06,0x40,0x00,0x93,0x05 } },
+{  16, 0xad40, 0, {0x2c,0x14,0x0b,0x3c,0x86,0xce,0x10,0x83,0x01,0x28,0xf1,0x0b,0x14,0x02,0xc8,0x04 } },
+{  16, 0xad50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa0,0x00,0xed,0x00,0x3a,0xc0 } },
+{  16, 0xad60, 0, {0x07,0xbc,0x63,0xed,0x00,0x81,0x40,0x3e,0xc0,0x0e,0x88,0x03,0x64,0x00,0xef,0x00 } },
+{  16, 0xad70, 0, {0x7e,0x50,0x0f,0xf0,0x02,0xfd,0x42,0xcf,0x00,0x72,0xc0,0x1f,0xb4,0x03,0xea,0x04 } },
+{  16, 0xad80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe8,0x00,0x99,0x00,0x3e,0xe0 } },
+{  16, 0xad90, 0, {0x4f,0xb4,0x83,0xed,0x90,0x09,0x40,0x3e,0xc0,0x0f,0xa1,0x83,0xa8,0x01,0xeb,0x01 } },
+{  16, 0xada0, 0, {0x3e,0x00,0x0f,0xb1,0x13,0xec,0x0c,0xfb,0x00,0x3a,0xc0,0x5f,0x20,0x23,0xe0,0x00 } },
+{  16, 0xadb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf8,0x00,0xfd,0x04,0x3f,0xb0 } },
+{  16, 0xadc0, 0, {0x0d,0x60,0x03,0x3e,0x00,0xcd,0x00,0x33,0xf0,0x0f,0xf2,0x01,0xf0,0x00,0xff,0x03 } },
+{  16, 0xadd0, 0, {0x3f,0x03,0x0f,0xf0,0x01,0xfc,0x00,0xfb,0x02,0x33,0xc2,0x0f,0xf0,0xe3,0x00,0x44 } },
+{  16, 0xade0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6a,0x00,0xb9,0x02,0x2e,0xa0 } },
+{  16, 0xadf0, 0, {0x4a,0xac,0x02,0x0e,0x80,0xf9,0xc0,0x36,0xe1,0x0b,0xa0,0x02,0x2a,0x08,0xbb,0x00 } },
+{  16, 0xae00, 0, {0x2e,0x20,0x0e,0xb0,0x02,0xec,0x00,0xeb,0x00,0x22,0xc0,0x8b,0xb0,0x02,0x20,0x40 } },
+{  16, 0xae10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x23,0x00,0xa9,0x00,0x28,0xc0 } },
+{  16, 0xae20, 0, {0x09,0xb2,0x22,0x6c,0x40,0x89,0x89,0x2a,0xc0,0x0b,0x14,0x06,0x26,0x00,0xab,0x02 } },
+{  16, 0xae30, 0, {0x6e,0xe0,0x09,0xb0,0x06,0x6c,0x00,0xb3,0x02,0x22,0xc0,0x0b,0xb0,0x02,0x20,0x00 } },
+{  16, 0xae40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x08,0x00,0xb1,0x00,0x2c,0xc0 } },
+{  16, 0xae50, 0, {0x0a,0x30,0x02,0x2c,0x00,0xbb,0x00,0x64,0xc0,0x0b,0x32,0x0a,0x08,0x00,0x33,0x00 } },
+{  16, 0xae60, 0, {0x6c,0x80,0x02,0x30,0x46,0xcc,0x18,0xa3,0x00,0x20,0xc0,0x0b,0x28,0x02,0x02,0x11 } },
+{  16, 0xae70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x68,0x00,0xe9,0x00,0x38,0xc1 } },
+{  16, 0xae80, 0, {0x0d,0xb1,0x0b,0x2c,0x00,0x89,0x00,0x3a,0xc0,0x0b,0x90,0x03,0x60,0x00,0xff,0x02 } },
+{  16, 0xae90, 0, {0x3e,0x80,0x0f,0xf0,0x03,0xfc,0x80,0xff,0x00,0x32,0xc0,0x8f,0x80,0x0b,0x00,0x03 } },
+{  16, 0xaea0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xd8,0x00,0xfd,0x04,0x3f,0xc0 } },
+{  16, 0xaeb0, 0, {0x2f,0xf2,0x03,0xfc,0x11,0xef,0x00,0x3f,0xc0,0x0f,0xf4,0x43,0x70,0x00,0xff,0x00 } },
+{  16, 0xaec0, 0, {0x3f,0x00,0x46,0xf0,0x03,0xfd,0x00,0xef,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xe8,0x06 } },
+{  16, 0xaed0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x00,0xff,0x80,0x3d,0xe0 } },
+{  16, 0xaee0, 0, {0x0c,0xf9,0x13,0xde,0x00,0x7f,0x80,0xb3,0xe0,0x0f,0xfc,0x03,0xbe,0x40,0xcf,0x80 } },
+{  16, 0xaef0, 0, {0x33,0xf0,0x0f,0xf8,0x03,0x7c,0x04,0xcc,0x80,0x33,0xa0,0x0c,0xf0,0x0b,0x30,0x01 } },
+{  16, 0xaf00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe0,0x20,0x88,0x00,0x2e,0x20 } },
+{  16, 0xaf10, 0, {0x08,0x82,0x12,0xe0,0x80,0xa8,0x81,0x22,0x02,0x0b,0x80,0x02,0x20,0x80,0xa8,0x80 } },
+{  16, 0xaf20, 0, {0x22,0x08,0x0b,0x80,0x02,0x2c,0x02,0x88,0x04,0xaa,0x20,0x08,0xb0,0x02,0x20,0x04 } },
+{  16, 0xaf30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xec,0x00,0xa3,0x08,0x2c,0x80 } },
+{  16, 0xaf40, 0, {0x08,0x32,0x02,0xc4,0x20,0xa3,0x00,0x28,0x40,0x0b,0x92,0x02,0x84,0x00,0xa9,0x01 } },
+{  16, 0xaf50, 0, {0x28,0xc8,0x1b,0x12,0x82,0xcc,0x40,0xa8,0x00,0x24,0xe0,0x0a,0x30,0x42,0x22,0x01 } },
+{  16, 0xaf60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xa8,0x80,0xa8,0x02,0x2e,0x40 } },
+{  16, 0xaf70, 0, {0x68,0x80,0x10,0xc8,0x00,0xb8,0x40,0x2a,0x90,0x0b,0xa0,0x00,0x28,0x00,0xaa,0x08 } },
+{  16, 0xaf80, 0, {0x2a,0x02,0x03,0x20,0x02,0x8c,0x00,0xa8,0x88,0x2e,0x20,0x0a,0xb0,0x02,0x30,0x04 } },
+{  16, 0xaf90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe8,0x04,0xfa,0x00,0x3c,0x40 } },
+{  16, 0xafa0, 0, {0x0c,0xa0,0x03,0xe8,0x00,0xeb,0x00,0x3a,0xc0,0x0f,0x20,0x53,0xa8,0x00,0xe3,0x40 } },
+{  16, 0xafb0, 0, {0x2a,0x40,0x0f,0xa0,0x03,0x6c,0x00,0xa8,0x80,0x34,0x20,0x1e,0xb0,0x03,0x10,0x04 } },
+{  16, 0xafc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb4,0x00,0x9d,0x91,0x3f,0x80 } },
+{  16, 0xafd0, 0, {0x0f,0xda,0x23,0xf4,0x00,0xcc,0x20,0x37,0x00,0x07,0xd0,0x13,0x74,0x00,0xbc,0x00 } },
+{  16, 0xafe0, 0, {0xb7,0x80,0x0b,0xd0,0x43,0x7c,0x00,0xdc,0x04,0x3b,0x00,0x6d,0xf0,0x03,0xf8,0x00 } },
+{  16, 0xaff0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa8,0x00,0xfa,0x80,0x3a,0x00 } },
+{  16, 0xb000, 0, {0x2c,0xa0,0x0b,0x20,0x02,0xcb,0x62,0x3e,0x50,0x0e,0x88,0x03,0x20,0x00,0xd9,0x10 } },
+{  16, 0xb010, 0, {0x3e,0x70,0x8c,0x80,0x33,0xec,0x80,0xd8,0x40,0x3a,0x02,0x0d,0xb0,0x03,0x10,0x04 } },
+{  16, 0xb020, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x01,0x0c,0x00,0x39,0x80,0x22,0xc0 } },
+{  16, 0xb030, 0, {0x0c,0x9d,0x82,0x2c,0x10,0xd0,0x40,0x2e,0xa0,0x08,0xb8,0x03,0x4e,0x02,0x8a,0x40 } },
+{  16, 0xb040, 0, {0x0e,0xa0,0x0d,0xb0,0x03,0x3d,0x00,0xd0,0x90,0x36,0x10,0x0b,0xf0,0x02,0xb2,0x00 } },
+{  16, 0xb050, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb1,0x00,0x60,0xc0 } },
+{  16, 0xb060, 0, {0x8a,0x18,0x02,0x8c,0x08,0x80,0x40,0x0c,0xa0,0x02,0x30,0x02,0xce,0x00,0x82,0x48 } },
+{  16, 0xb070, 0, {0x2c,0x80,0x2b,0x30,0x06,0x8c,0x00,0x81,0x02,0x20,0x90,0x09,0xb0,0x02,0x38,0x00 } },
+{  16, 0xb080, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x12,0x00,0xb6,0x90,0xa3,0x30 } },
+{  16, 0xb090, 0, {0x08,0xe8,0x22,0xb2,0x14,0x87,0x80,0x2d,0x60,0x08,0x49,0x12,0x12,0x61,0x95,0x90 } },
+{  16, 0xb0a0, 0, {0x2d,0x61,0x0a,0x48,0x16,0x1e,0x80,0x95,0x80,0x25,0x20,0x0b,0x78,0x02,0x88,0x00 } },
+{  16, 0xb0b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xf1,0x00,0x28,0x8c } },
+{  16, 0xb0c0, 0, {0x8e,0x10,0x03,0x84,0x80,0x80,0x00,0x2c,0x02,0x0a,0x9a,0x02,0xe4,0x00,0xd0,0x00 } },
+{  16, 0xb0d0, 0, {0x3e,0x80,0x0b,0x91,0x03,0x8e,0x80,0xc2,0x08,0x38,0x80,0x0d,0xb0,0x03,0x12,0x02 } },
+{  16, 0xb0e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb0,0x00,0xf6,0x00,0x3f,0x44 } },
+{  16, 0xb0f0, 0, {0x0f,0x21,0x13,0x78,0x00,0xff,0x00,0x3d,0xc0,0x0f,0xe0,0x03,0x78,0x00,0xef,0x04 } },
+{  16, 0xb100, 0, {0x3f,0x40,0x8d,0xe8,0x03,0xdc,0x04,0xf6,0x00,0x3f,0x00,0x0f,0xf0,0x83,0xd0,0x06 } },
+{  16, 0xb110, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe8,0x00,0xe8,0x80,0x32,0x40 } },
+{  16, 0xb120, 0, {0x0f,0x88,0x0b,0x28,0x00,0x78,0x02,0x3e,0x80,0x0e,0x28,0x03,0x28,0x00,0xca,0x80 } },
+{  16, 0xb130, 0, {0x32,0x00,0x0f,0xa0,0x03,0xec,0x00,0xc9,0x80,0x32,0x80,0x0f,0xb0,0x03,0x2a,0x00 } },
+{  16, 0xb140, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x8c,0x00,0x8f,0x00,0xa1,0x80 } },
+{  16, 0xb150, 0, {0x0b,0x70,0x42,0x14,0x00,0xb7,0x00,0x2d,0x41,0x0b,0x50,0x42,0x14,0x00,0xa5,0x00 } },
+{  16, 0xb160, 0, {0xa1,0xc0,0x0b,0x50,0x02,0xfc,0x80,0xa5,0x00,0x21,0x00,0x0b,0xf2,0x02,0x12,0x04 } },
+{  16, 0xb170, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0xba,0x00,0xa4,0x80,0x29,0x30 } },
+{  16, 0xb180, 0, {0x4b,0x48,0x06,0x52,0x08,0xb4,0x80,0x2d,0x20,0x0b,0x48,0x42,0x32,0x00,0x84,0x80 } },
+{  16, 0xb190, 0, {0x21,0x20,0x0b,0x48,0x12,0xde,0x40,0x86,0x81,0x29,0xa0,0x0b,0x78,0x0a,0x30,0x00 } },
+{  16, 0xb1a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0x83,0x05,0x20,0xe0 } },
+{  16, 0xb1b0, 0, {0x0b,0x34,0x02,0x6c,0x10,0xb3,0x00,0x2c,0xc0,0x0b,0x36,0x4a,0x0d,0x0d,0xa3,0x00 } },
+{  16, 0xb1c0, 0, {0x20,0xc0,0x0b,0x34,0x82,0xcc,0x02,0xa2,0x00,0x28,0x00,0x0b,0x30,0x02,0x12,0x04 } },
+{  16, 0xb1d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa9,0x20,0xea,0x40,0x30,0xa0 } },
+{  16, 0xb1e0, 0, {0x07,0xa0,0x43,0x69,0x40,0xfa,0x00,0x3c,0x80,0x0f,0xa0,0x03,0x08,0x40,0xca,0x00 } },
+{  16, 0xb1f0, 0, {0x30,0xa0,0x0f,0xa4,0x03,0xe8,0x00,0xce,0x00,0x3b,0x98,0x0f,0xa0,0x03,0x3a,0x04 } },
+{  16, 0xb200, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xd2,0x00,0xfc,0x08,0x3f,0x00 } },
+{  16, 0xb210, 0, {0x0b,0xc2,0x03,0xb0,0x00,0xfc,0x00,0x3f,0x00,0x0f,0xc0,0x03,0xf0,0x00,0xfc,0x00 } },
+{  16, 0xb220, 0, {0x3f,0x04,0x0f,0xc0,0x03,0xe0,0x00,0xf8,0x00,0xb6,0x02,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0xb230, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x00,0x3e,0x68 } },
+{  16, 0xb240, 0, {0x4c,0x91,0x01,0xe4,0x08,0xc9,0x00,0x3e,0x40,0x2c,0x92,0x03,0xe4,0x02,0xc9,0xa0 } },
+{  16, 0xb250, 0, {0x3e,0x70,0x0e,0x90,0x03,0xc6,0x42,0xc9,0x00,0x3e,0x40,0x0f,0x10,0x03,0x02,0x04 } },
+{  16, 0xb260, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0x86,0x0e,0x60 } },
+{  16, 0xb270, 0, {0x08,0x98,0x02,0xe4,0x08,0x89,0x10,0x2e,0x60,0x08,0x90,0x02,0xe4,0x00,0x89,0x0c } },
+{  16, 0xb280, 0, {0x2e,0x60,0x08,0x90,0x02,0xe6,0x88,0x89,0x00,0x2e,0x40,0x0b,0x90,0x02,0xa0,0x00 } },
+{  16, 0xb290, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x9d,0x10,0x2f,0x40 } },
+{  16, 0xb2a0, 0, {0x28,0xd0,0x06,0xf4,0x02,0xad,0x00,0x2f,0x60,0x08,0xd0,0x02,0xf4,0x00,0x8d,0x00 } },
+{  16, 0xb2b0, 0, {0x2f,0x40,0x0a,0xd0,0x02,0xe4,0x00,0x89,0x00,0x2e,0x60,0x0b,0x90,0x02,0x06,0x00 } },
+{  16, 0xb2c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x34,0x00,0x85,0x00,0x2d,0x40 } },
+{  16, 0xb2d0, 0, {0x08,0x58,0x02,0xd4,0x00,0xa5,0x02,0x2d,0x40,0x08,0x50,0x00,0xd4,0x00,0x85,0x00 } },
+{  16, 0xb2e0, 0, {0x2d,0x40,0x08,0x54,0x02,0xc4,0x80,0x81,0x00,0x2c,0x60,0x0b,0x14,0x02,0x82,0x01 } },
+{  16, 0xb2f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x52,0x3e,0x00 } },
+{  16, 0xb300, 0, {0x0c,0x05,0x03,0xe1,0x40,0xe8,0x04,0x3e,0x14,0x0c,0x85,0x03,0xe1,0x40,0xc8,0x00 } },
+{  16, 0xb310, 0, {0x3e,0x14,0x0e,0xc0,0x03,0xe0,0x00,0xc0,0x02,0x3e,0x00,0x4f,0x80,0x23,0x2e,0x03 } },
+{  16, 0xb320, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x00,0xf9,0x01,0x3e,0x40 } },
+{  16, 0xb330, 0, {0x4f,0x90,0x13,0xe4,0x00,0xd9,0x00,0x1e,0x40,0x0f,0x90,0x03,0xc4,0x10,0xf1,0x00 } },
+{  16, 0xb340, 0, {0x1e,0x40,0x0f,0x90,0x03,0xe4,0xe0,0xfd,0x28,0x3f,0x40,0x0f,0x94,0x03,0xe6,0x06 } },
+{  16, 0xb350, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xa4,0x00,0xfd,0x00,0x3f,0x40 } },
+{  16, 0xb360, 0, {0x4d,0x50,0x02,0xe4,0x00,0x95,0x04,0x33,0x40,0x28,0xd0,0x03,0xf4,0x00,0xfd,0x00 } },
+{  16, 0xb370, 0, {0x33,0x40,0x0f,0x91,0x03,0x34,0x00,0xcd,0x40,0x33,0x40,0x0f,0x98,0x81,0x06,0x00 } },
+{  16, 0xb380, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x10,0xb8,0x00,0x2e,0x00 } },
+{  16, 0xb390, 0, {0x0b,0x80,0x02,0xe0,0x10,0xb8,0x00,0x22,0x00,0x08,0x80,0x02,0xe0,0x00,0xb8,0x00 } },
+{  16, 0xb3a0, 0, {0x22,0x00,0x0b,0x88,0x03,0xc2,0x80,0x88,0x80,0x22,0x00,0x0b,0x8c,0x02,0x0e,0x04 } },
+{  16, 0xb3b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0xc4,0x00,0xb1,0x00,0x2c,0xc0 } },
+{  16, 0xb3c0, 0, {0x0b,0x10,0x02,0xc4,0x00,0xbb,0x00,0x22,0x40,0x08,0x10,0x02,0xc4,0x01,0xb9,0x00 } },
+{  16, 0xb3d0, 0, {0x20,0x40,0x1b,0x90,0x02,0x04,0x22,0x89,0x00,0x20,0x60,0x0b,0x12,0x82,0x02,0x01 } },
+{  16, 0xb3e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x44,0xb9,0x00,0x2e,0xc0 } },
+{  16, 0xb3f0, 0, {0x4b,0x90,0x02,0xe4,0x10,0xb9,0x02,0x02,0x40,0x08,0x91,0x42,0xe4,0x00,0xb9,0x80 } },
+{  16, 0xb400, 0, {0x22,0x40,0x0b,0x92,0x02,0xc4,0x00,0x99,0x40,0x22,0x40,0x4b,0x90,0x12,0x06,0x04 } },
+{  16, 0xb410, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe6,0x00,0xb9,0x01,0x3e,0x58 } },
+{  16, 0xb420, 0, {0x0d,0x90,0x03,0xe6,0x00,0xd1,0x00,0x32,0x60,0x0c,0x98,0x02,0xe6,0x40,0xf9,0x00 } },
+{  16, 0xb430, 0, {0xb2,0x40,0x0f,0x18,0x03,0x24,0x00,0xc9,0x80,0x32,0x50,0x0f,0x90,0x23,0x28,0x04 } },
+{  16, 0xb440, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x42 } },
+{  16, 0xb450, 0, {0x0b,0x90,0x03,0xe7,0x08,0xf9,0x00,0xbe,0x48,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00 } },
+{  16, 0xb460, 0, {0x3e,0x40,0x0f,0x98,0x03,0xa4,0x00,0xe9,0xa0,0xbe,0x40,0x0f,0x10,0x0b,0x4a,0x00 } },
+{  16, 0xb470, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x01,0x3e,0x00 } },
+{  16, 0xb480, 0, {0x0f,0x80,0x8b,0x20,0x00,0xf8,0x20,0x3e,0x01,0x0f,0x81,0x03,0xe0,0x00,0xf8,0x08 } },
+{  16, 0xb490, 0, {0x3a,0x00,0x0c,0x80,0x03,0xe0,0x00,0xd8,0x40,0x32,0x00,0x0f,0x80,0x13,0x0a,0x04 } },
+{  16, 0xb4a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8a,0x80,0x2f,0x91 } },
+{  16, 0xb4b0, 0, {0x0b,0xee,0x02,0x28,0x01,0xbe,0x00,0x20,0x80,0x0b,0xa0,0x02,0xea,0x80,0xb6,0x48 } },
+{  16, 0xb4c0, 0, {0x22,0x80,0x0d,0xa0,0x02,0xfa,0x02,0x86,0x41,0xa3,0xa6,0x0b,0xa0,0x03,0x0a,0x00 } },
+{  16, 0xb4d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0x80,0x2c,0xc0 } },
+{  16, 0xb4e0, 0, {0x0b,0x30,0x02,0x0c,0x10,0xb3,0x00,0x28,0xc0,0x0b,0x38,0x02,0xcc,0x00,0xb3,0x00 } },
+{  16, 0xb4f0, 0, {0x28,0xc0,0x09,0x30,0x02,0xc6,0x01,0x83,0x60,0x20,0x70,0x0b,0x30,0x0a,0x4a,0x00 } },
+{  16, 0xb500, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x2e,0x88,0x85,0x08,0x2d,0x80 } },
+{  16, 0xb510, 0, {0x4b,0xf8,0x06,0x1c,0x80,0xb7,0x00,0x21,0xc0,0x0b,0x50,0x02,0xd4,0x00,0xb6,0x00 } },
+{  16, 0xb520, 0, {0x29,0x60,0x09,0x70,0x02,0xd0,0xa0,0x8d,0x00,0x21,0x40,0x0b,0x32,0x02,0x28,0x00 } },
+{  16, 0xb530, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xd5,0x80,0x3d,0xe0 } },
+{  16, 0xb540, 0, {0x8f,0x78,0x03,0x1e,0x84,0xb7,0x82,0x3d,0x60,0x0f,0x59,0x03,0xde,0x00,0xf7,0x80 } },
+{  16, 0xb550, 0, {0x29,0x60,0x15,0x78,0x03,0xde,0x00,0xc7,0x80,0x31,0x60,0x0f,0x7c,0x03,0x6a,0x02 } },
+{  16, 0xb560, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x40,0xe9,0x00,0x3e,0x80 } },
+{  16, 0xb570, 0, {0x0f,0xa0,0x03,0xed,0x30,0xfb,0x00,0x36,0xc1,0x0f,0x96,0x03,0xe4,0x00,0xb3,0x00 } },
+{  16, 0xb580, 0, {0x34,0x40,0x0f,0xb7,0x83,0xec,0x40,0x21,0x00,0x3e,0x40,0x0f,0xb0,0x03,0xc2,0x06 } },
+{  16, 0xb590, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xff,0x81,0x33,0xe0 } },
+{  16, 0xb5a0, 0, {0x0f,0xf9,0x03,0xde,0x20,0xcf,0x81,0x3f,0xe0,0x07,0x78,0x03,0x3e,0x00,0xff,0x80 } },
+{  16, 0xb5b0, 0, {0x3f,0xe0,0x04,0xf8,0x13,0xfe,0x02,0xde,0x80,0x33,0x60,0x0f,0xf8,0x03,0x00,0x00 } },
+{  16, 0xb5c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xb7,0x00,0x21,0xc4 } },
+{  16, 0xb5d0, 0, {0x0b,0x5a,0x02,0xdc,0x48,0x86,0x50,0x2d,0xc0,0x0b,0x31,0x02,0x94,0x60,0xb4,0x18 } },
+{  16, 0xb5e0, 0, {0x2d,0x40,0x48,0x70,0x02,0xe8,0x00,0xa5,0x10,0x21,0x40,0x0b,0x71,0x02,0x2a,0x04 } },
+{  16, 0xb5f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xbd,0x00,0x21,0x42 } },
+{  16, 0xb600, 0, {0x0b,0x70,0x02,0xfc,0x02,0x85,0x00,0x25,0x40,0x0b,0x50,0x02,0x9c,0x00,0xb7,0x00 } },
+{  16, 0xb610, 0, {0x2f,0x40,0x28,0x71,0x02,0xdc,0x00,0xa6,0x00,0x21,0xc0,0x0b,0x70,0x02,0x00,0x00 } },
+{  16, 0xb620, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0x6d,0x80,0xb1,0x20,0xa0,0x50 } },
+{  16, 0xb630, 0, {0x0b,0xb2,0x06,0xce,0x00,0xa0,0x34,0x2e,0xf0,0x0b,0x18,0x02,0x85,0x20,0xb3,0x4a } },
+{  16, 0xb640, 0, {0x2c,0x54,0x88,0x38,0x02,0xcc,0x10,0xa1,0x00,0x20,0xb0,0x0b,0x30,0x02,0x08,0x04 } },
+{  16, 0xb650, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbe,0x80,0xf3,0x08,0x10,0x54 } },
+{  16, 0xb660, 0, {0x0b,0x88,0x13,0xff,0x00,0xc0,0x80,0x3e,0x64,0x0f,0xb4,0x83,0x07,0x00,0xf9,0xc0 } },
+{  16, 0xb670, 0, {0x3e,0xf0,0x0c,0xfc,0x13,0xf4,0x00,0xea,0x00,0x32,0x70,0x0f,0xf0,0x0b,0x2a,0x04 } },
+{  16, 0xb680, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xf9,0x00,0x3e,0x10 } },
+{  16, 0xb690, 0, {0x07,0x91,0x03,0xec,0xc0,0x58,0x00,0x3e,0x44,0x0f,0x92,0x03,0xe4,0x00,0xf9,0x00 } },
+{  16, 0xb6a0, 0, {0x3e,0xc0,0x8f,0xb3,0x03,0xe0,0x00,0xbb,0x00,0xbe,0x44,0x0f,0xb0,0x03,0xe0,0x00 } },
+{  16, 0xb6b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x02,0xcd,0x04,0x33,0xe0 } },
+{  16, 0xb6c0, 0, {0x0c,0xc0,0x03,0x3c,0x08,0xfe,0x00,0x33,0x60,0x2c,0xd0,0x02,0xb4,0x80,0xcf,0x00 } },
+{  16, 0xb6d0, 0, {0x3f,0x52,0x07,0xf0,0x13,0xfc,0x00,0xce,0x10,0x33,0x42,0x0c,0xb0,0x03,0xc0,0x44 } },
+{  16, 0xb6e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x00,0x89,0x00,0x2a,0xb0 } },
+{  16, 0xb6f0, 0, {0x08,0x88,0x02,0x2c,0x00,0xba,0x00,0x36,0x44,0x08,0x90,0x00,0x26,0x00,0xdb,0xc0 } },
+{  16, 0xb700, 0, {0x2e,0x40,0x0b,0xb0,0x02,0xec,0x00,0x83,0xc0,0x28,0x40,0x0a,0xb0,0x02,0xe0,0x40 } },
+{  16, 0xb710, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x00,0x22,0x08 } },
+{  16, 0xb720, 0, {0x1a,0xa2,0x02,0x2c,0x10,0xb9,0x20,0x22,0x40,0x08,0x30,0x02,0x2c,0x04,0xaa,0x54 } },
+{  16, 0xb730, 0, {0x2e,0xc0,0x0b,0xb0,0x12,0xcc,0x00,0x8b,0x08,0x22,0x40,0x08,0xb0,0x02,0xe0,0x00 } },
+{  16, 0xb740, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0x83,0x04,0x2a,0x00 } },
+{  16, 0xb750, 0, {0x0a,0x08,0x82,0x0c,0x00,0xb8,0x00,0x64,0x40,0x08,0x30,0x02,0xa4,0x00,0xb0,0x00 } },
+{  16, 0xb760, 0, {0x2c,0xc0,0x8b,0x30,0x10,0xc8,0x02,0x8b,0x00,0x2a,0x40,0x0a,0x30,0x02,0xc2,0x01 } },
+{  16, 0xb770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xc9,0x00,0x32,0x00 } },
+{  16, 0xb780, 0, {0x1a,0x82,0x03,0x3c,0x00,0xf9,0x00,0x32,0x40,0x0c,0xd1,0x03,0xac,0x00,0xeb,0x00 } },
+{  16, 0xb790, 0, {0x3e,0x40,0x0f,0xf0,0x03,0xed,0x00,0xc3,0x00,0x32,0xc0,0x8c,0xb0,0x03,0xc0,0x03 } },
+{  16, 0xb7a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xfc,0x00,0xf5,0x00,0x3f,0x00 } },
+{  16, 0xb7b0, 0, {0x0d,0x80,0x4b,0xfc,0x00,0x7c,0x00,0x3f,0x40,0x0f,0xd2,0x0b,0x74,0x00,0xdf,0x00 } },
+{  16, 0xb7c0, 0, {0x1d,0x40,0x8f,0xf0,0x03,0xfc,0xa0,0xff,0x00,0x3f,0x80,0x0f,0xf0,0x03,0xe8,0x06 } },
+{  16, 0xb7d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xdf,0x84,0x3b,0xe0 } },
+{  16, 0xb7e0, 0, {0x0f,0xf8,0x0b,0x3e,0x00,0xec,0x80,0x33,0xe1,0x0c,0x30,0x03,0x3c,0x80,0xcf,0x48 } },
+{  16, 0xb7f0, 0, {0x37,0xc0,0x0e,0x40,0x03,0xe0,0xc0,0xc7,0x91,0xb3,0x04,0x0c,0xf0,0x03,0x30,0x00 } },
+{  16, 0xb800, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xef,0x04,0x8b,0x80,0x22,0x41 } },
+{  16, 0xb810, 0, {0x0b,0xb0,0x82,0x2e,0x00,0x88,0x80,0xa2,0xe0,0x0a,0xa2,0x92,0xad,0x80,0x87,0x42 } },
+{  16, 0xb820, 0, {0x23,0xd8,0x8a,0xad,0x02,0xe0,0xc0,0x8b,0x00,0x20,0x4c,0x48,0xa4,0x02,0x20,0x04 } },
+{  16, 0xb830, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x58,0xbb,0x00,0x28,0x80 } },
+{  16, 0xb840, 0, {0x0b,0xb2,0x42,0x24,0x00,0xa8,0x00,0x2a,0xc0,0x0a,0x10,0x02,0x04,0x60,0xa3,0x20 } },
+{  16, 0xb850, 0, {0x24,0xd2,0x08,0x00,0x42,0x8c,0x83,0x9b,0x01,0x20,0x49,0x08,0x33,0xc2,0x22,0x01 } },
+{  16, 0xb860, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x00,0xab,0x88,0x22,0xa0 } },
+{  16, 0xb870, 0, {0x0b,0xb8,0x02,0x26,0x0c,0xa8,0x00,0x2a,0xc0,0x0a,0x92,0x02,0xa4,0x00,0xab,0x06 } },
+{  16, 0xb880, 0, {0x22,0xc0,0x0a,0xb0,0x02,0xe8,0x00,0x9b,0x00,0x02,0x40,0x08,0xa0,0x42,0x30,0x04 } },
+{  16, 0xb890, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xd3,0x80,0x3a,0xe0 } },
+{  16, 0xb8a0, 0, {0x0f,0x18,0x01,0x06,0x00,0xe8,0x30,0x38,0x66,0x0e,0xb8,0x03,0x2a,0x40,0xeb,0x00 } },
+{  16, 0xb8b0, 0, {0x36,0xc1,0x0e,0x96,0x03,0xe2,0x80,0xda,0x08,0x32,0x80,0x2c,0xbb,0x03,0x10,0x04 } },
+{  16, 0xb8c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x9c,0x00,0xdf,0x00,0x3f,0xc0 } },
+{  16, 0xb8d0, 0, {0x0f,0xd0,0x03,0xf4,0x00,0xdc,0x80,0x37,0x60,0x0f,0xe8,0x03,0xfa,0x00,0xdf,0x01 } },
+{  16, 0xb8e0, 0, {0x3f,0xc0,0x0f,0xc0,0x43,0xe6,0x4c,0xef,0xa0,0x3f,0x44,0x0f,0xa0,0x03,0xf8,0x00 } },
+{  16, 0xb8f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x40,0xdb,0x00,0x36,0x80 } },
+{  16, 0xb900, 0, {0x0c,0x98,0x03,0x26,0x00,0xf8,0x00,0x3e,0xc0,0x0e,0x18,0x03,0x84,0x02,0xe3,0x01 } },
+{  16, 0xb910, 0, {0x38,0xc1,0x0e,0xb4,0x03,0xac,0x80,0xca,0x18,0x3a,0xd0,0x2c,0x30,0x03,0x10,0x04 } },
+{  16, 0xb920, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3f,0x40,0xb9,0x88,0x2e,0x80 } },
+{  16, 0xb930, 0, {0x08,0xbc,0x02,0xa3,0x00,0xb0,0x00,0x0e,0xc0,0x08,0xb0,0x06,0x20,0x00,0x8f,0x04 } },
+{  16, 0xb940, 0, {0x23,0xc1,0x08,0xb9,0x12,0x2f,0x00,0x83,0x80,0x36,0x40,0x08,0xad,0x02,0x32,0x00 } },
+{  16, 0xb950, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb2,0x00,0x2c,0xc0 } },
+{  16, 0xb960, 0, {0x09,0x32,0x02,0x84,0x00,0x33,0x00,0x2c,0xb2,0x0a,0x36,0x12,0x8c,0x08,0x93,0x05 } },
+{  16, 0xb970, 0, {0x20,0xc0,0x0b,0x18,0x02,0xed,0x00,0x91,0x80,0x6a,0x00,0x08,0x10,0x02,0x38,0x00 } },
+{  16, 0xb980, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x00,0xb7,0x80,0x2d,0xe0 } },
+{  16, 0xb990, 0, {0x09,0x78,0x02,0x97,0x40,0xb4,0x80,0x2f,0xa0,0x08,0xe8,0x02,0x0e,0x40,0x97,0x82 } },
+{  16, 0xb9a0, 0, {0x21,0xe0,0x98,0x68,0x82,0x1a,0x18,0x9d,0x90,0x2d,0xa1,0x18,0x58,0x02,0x08,0x00 } },
+{  16, 0xb9b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0xc0,0xf3,0x00,0x3e,0xc0 } },
+{  16, 0xb9c0, 0, {0x0d,0xb0,0x43,0x84,0x40,0xf0,0x00,0x3c,0x82,0x0e,0x38,0x12,0x8c,0x44,0xf3,0x30 } },
+{  16, 0xb9d0, 0, {0xba,0xc1,0x1e,0x10,0x47,0x8e,0x22,0xd1,0x10,0x38,0x18,0x0c,0x30,0x83,0x12,0x02 } },
+{  16, 0xb9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x40,0xff,0x00,0x3f,0xc0 } },
+{  16, 0xb9f0, 0, {0x0e,0xe0,0x03,0xf4,0x40,0xfc,0x00,0x3d,0xc4,0x0f,0xd0,0x01,0xf4,0x41,0xef,0x18 } },
+{  16, 0xba00, 0, {0x3f,0xc4,0x1f,0xf0,0x03,0xf8,0x48,0xef,0x14,0x33,0x80,0x0f,0xc1,0x03,0xd0,0x06 } },
+{  16, 0xba10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xfc,0x40,0xfb,0x00,0x3e,0xc0 } },
+{  16, 0xba20, 0, {0x0f,0x98,0x03,0x24,0x00,0xcb,0x00,0x3e,0x40,0x0f,0xb0,0x03,0xa8,0x00,0xdb,0x28 } },
+{  16, 0xba30, 0, {0x3e,0xc4,0x1f,0x90,0x23,0xec,0x00,0xca,0x00,0x32,0xe0,0x0c,0x90,0x03,0xea,0x00 } },
+{  16, 0xba40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x80,0xb7,0x00,0x2d,0xc0 } },
+{  16, 0xba50, 0, {0x4b,0x50,0x52,0x14,0x00,0xd4,0x01,0x2d,0x80,0x0b,0x60,0x02,0xd8,0x00,0xa7,0x20 } },
+{  16, 0xba60, 0, {0x2d,0xc5,0x0b,0x40,0x16,0xdc,0x00,0x84,0x00,0x23,0xc0,0x08,0x40,0x02,0xd2,0x04 } },
+{  16, 0xba70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x80,0xb7,0x80,0x2d,0xe0 } },
+{  16, 0xba80, 0, {0x0b,0x78,0x0a,0x96,0x00,0x94,0x80,0x2d,0x60,0x1b,0x78,0x06,0xd2,0x00,0xa7,0x80 } },
+{  16, 0xba90, 0, {0x2d,0xe0,0x0b,0x78,0x22,0xde,0x00,0x87,0x82,0x21,0xe0,0x08,0x58,0x02,0xf0,0x00 } },
+{  16, 0xbaa0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xb3,0xe4,0x2c,0xc0 } },
+{  16, 0xbab0, 0, {0x1b,0x21,0x02,0x81,0x00,0x90,0x00,0x2c,0xc8,0x0b,0x39,0x02,0xce,0x00,0xa3,0x00 } },
+{  16, 0xbac0, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcd,0x00,0x8b,0x20,0x20,0xf0,0x08,0xb2,0x02,0xd2,0x04 } },
+{  16, 0xbad0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfe,0xa0,0x3f,0x82 } },
+{  16, 0xbae0, 0, {0x0f,0xe8,0x03,0x98,0x30,0xd6,0x00,0x3f,0xa0,0x0f,0xe0,0x03,0xba,0xc0,0xfa,0x00 } },
+{  16, 0xbaf0, 0, {0x3e,0x80,0x0f,0xec,0x33,0xf8,0x02,0xce,0x00,0xb3,0xb8,0x2c,0xec,0x83,0xfa,0x04 } },
+{  16, 0xbb00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x18,0xf8,0x40,0x3e,0x00 } },
+{  16, 0xbb10, 0, {0x0f,0x80,0x02,0x60,0x84,0xf8,0x05,0x2e,0x04,0x8f,0x80,0x41,0xe0,0x00,0x78,0x02 } },
+{  16, 0xbb20, 0, {0x3e,0x00,0x0f,0x81,0x83,0xe0,0x20,0xf8,0x00,0xbe,0x02,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0xbb30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe6,0x18,0xf9,0x20,0x3e,0x40 } },
+{  16, 0xbb40, 0, {0x0f,0x9c,0x03,0xe4,0x40,0xc9,0x00,0x32,0x61,0x0c,0x90,0x13,0xc4,0x08,0xc9,0x01 } },
+{  16, 0xbb50, 0, {0x3e,0x41,0x0f,0x18,0x03,0x24,0x00,0xc9,0xa0,0x32,0x40,0x0f,0x98,0x43,0x02,0x04 } },
+{  16, 0xbb60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x65,0x00,0xb1,0xc0,0x22,0x40 } },
+{  16, 0xbb70, 0, {0x0b,0x9c,0x02,0xe7,0x10,0x89,0x00,0x28,0x44,0x08,0x94,0x22,0xe4,0x10,0x89,0x00 } },
+{  16, 0xbb80, 0, {0x2e,0x40,0x0b,0x9f,0x22,0x26,0x60,0x89,0x80,0x22,0x40,0x0b,0x91,0x0a,0x20,0x00 } },
+{  16, 0xbb90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x80,0xb9,0x00,0x2e,0xc0 } },
+{  16, 0xbba0, 0, {0x4b,0xb4,0x02,0xe4,0x20,0x89,0x20,0x22,0x40,0x08,0x94,0x02,0xec,0x00,0x89,0x00 } },
+{  16, 0xbbb0, 0, {0x2e,0x41,0x0b,0x90,0x02,0x04,0x00,0x89,0x40,0x22,0x40,0x0b,0x90,0x02,0x06,0x00 } },
+{  16, 0xbbc0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0xb1,0x04,0x20,0x40 } },
+{  16, 0xbbd0, 0, {0x8b,0x10,0x02,0xe4,0x05,0x81,0x00,0x28,0x40,0x28,0x12,0x12,0xc4,0x82,0x81,0x20 } },
+{  16, 0xbbe0, 0, {0x2c,0x48,0x0b,0x12,0x0a,0x04,0x82,0x81,0x00,0x20,0x48,0x0b,0x12,0x02,0x02,0x01 } },
+{  16, 0xbbf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x68,0xa0,0xfa,0x02,0x3e,0x14 } },
+{  16, 0xbc00, 0, {0x0f,0x85,0x03,0xe0,0x00,0xc8,0x00,0x32,0x00,0x0c,0x85,0x03,0xc1,0x40,0xc8,0x53 } },
+{  16, 0xbc10, 0, {0x3e,0x14,0x0f,0x80,0x03,0x01,0x48,0xc0,0x50,0xb2,0x14,0x0f,0x85,0x03,0x2e,0x03 } },
+{  16, 0xbc20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x00,0xfd,0x00,0xbf,0x40 } },
+{  16, 0xbc30, 0, {0x0f,0x50,0x13,0xd4,0x02,0xfd,0x00,0x2f,0xc0,0x0f,0xd1,0x03,0xf4,0x40,0xf9,0x10 } },
+{  16, 0xbc40, 0, {0x3e,0x44,0x0f,0xd1,0x03,0xf4,0x40,0xff,0x00,0xbf,0x44,0x0f,0xd1,0x03,0xe6,0x06 } },
+{  16, 0xbc50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0xa0,0xfd,0x01,0x3e,0x44 } },
+{  16, 0xbc60, 0, {0x0f,0xd1,0x03,0xd4,0x00,0xc5,0x00,0x33,0x41,0x0f,0xdb,0x03,0x27,0x20,0xd9,0xe0 } },
+{  16, 0xbc70, 0, {0xb2,0x70,0x0d,0xda,0x83,0xf6,0x40,0xcf,0x10,0x32,0x78,0x2d,0xda,0x03,0x06,0x00 } },
+{  16, 0xbc80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x00,0xb8,0x00,0x2e,0x28 } },
+{  16, 0xbc90, 0, {0x0b,0x88,0x42,0xe0,0x10,0xd8,0x00,0x22,0x00,0x0b,0x8c,0x0a,0x23,0x00,0x88,0xc0 } },
+{  16, 0xbca0, 0, {0x22,0x28,0x08,0x84,0x02,0xc2,0x80,0x80,0xa0,0x22,0x30,0x48,0xaa,0x82,0x0e,0x04 } },
+{  16, 0xbcb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x2c,0x40 } },
+{  16, 0xbcc0, 0, {0x8b,0x12,0x02,0xc4,0x00,0x99,0x02,0x28,0x40,0x8b,0x16,0x02,0x84,0x81,0x91,0x30 } },
+{  16, 0xbcd0, 0, {0x20,0x58,0x09,0x10,0x02,0xc5,0x00,0x81,0x00,0x64,0x4d,0x08,0x34,0x02,0x02,0x01 } },
+{  16, 0xbce0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xac,0x0c,0xb9,0x04,0x2e,0x48 } },
+{  16, 0xbcf0, 0, {0x0b,0x94,0x06,0xe4,0x00,0x99,0x40,0xaa,0x40,0x0b,0x92,0x22,0xa4,0x00,0x89,0x00 } },
+{  16, 0xbd00, 0, {0x60,0x40,0x08,0x94,0x02,0xe4,0x00,0x89,0x80,0xa6,0x50,0x08,0x92,0x02,0x06,0x04 } },
+{  16, 0xbd10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x98,0x3e,0x48 } },
+{  16, 0xbd20, 0, {0x0f,0x98,0x03,0xe5,0x20,0xd9,0x00,0x3a,0x64,0x0f,0x94,0x83,0xa4,0xc0,0xd9,0x02 } },
+{  16, 0xbd30, 0, {0x72,0x40,0x4d,0x90,0x42,0xe4,0x82,0xc9,0x40,0x36,0x40,0x0c,0x90,0x0b,0x28,0x04 } },
+{  16, 0xbd40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xac,0x28,0xf9,0x88,0x3e,0x40 } },
+{  16, 0xbd50, 0, {0x0f,0x99,0x13,0xe7,0x00,0xf9,0xc0,0x36,0x60,0x0f,0x90,0x03,0x66,0x00,0xf1,0x00 } },
+{  16, 0xbd60, 0, {0x7e,0x40,0x0f,0x99,0x07,0xe4,0x60,0xf9,0x00,0x38,0x40,0x0f,0x98,0x03,0xca,0x00 } },
+{  16, 0xbd70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x10,0x32,0x00 } },
+{  16, 0xbd80, 0, {0x0f,0x82,0x0b,0x21,0x00,0xe8,0x00,0x36,0x04,0x0c,0x86,0x03,0xe1,0x00,0xd8,0x00 } },
+{  16, 0xbd90, 0, {0x32,0x00,0x0f,0x80,0x03,0x61,0x00,0xc8,0x00,0x32,0x00,0x0f,0x00,0x03,0x0a,0x04 } },
+{  16, 0xbda0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x20,0xbe,0x00,0x22,0x80 } },
+{  16, 0xbdb0, 0, {0x28,0xec,0x02,0x19,0x04,0x82,0x00,0x03,0x80,0x0d,0xe4,0x82,0xe8,0x00,0x8a,0x01 } },
+{  16, 0xbdc0, 0, {0xaa,0x80,0x8b,0xed,0x82,0x3b,0x80,0x8e,0x90,0x36,0x80,0x0b,0xe0,0x03,0x4a,0x00 } },
+{  16, 0xbdd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x42,0x00,0xb3,0x80,0x20,0xc0 } },
+{  16, 0xbde0, 0, {0x6b,0x34,0x16,0x40,0xc0,0x83,0x10,0x24,0x72,0x88,0xb0,0x02,0xec,0x00,0x83,0x00 } },
+{  16, 0xbdf0, 0, {0x24,0xc0,0x0b,0x04,0x02,0x6f,0x09,0x9b,0x00,0x24,0xc0,0x0b,0x30,0x02,0x0a,0x00 } },
+{  16, 0xbe00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x14,0x00,0xb7,0x80,0x23,0xe4 } },
+{  16, 0xbe10, 0, {0x28,0x78,0x82,0x74,0x14,0x8f,0x00,0x61,0xe0,0x09,0x50,0x12,0xdc,0x04,0x87,0x22 } },
+{  16, 0xbe20, 0, {0x25,0xc8,0x1b,0x78,0x02,0x14,0x00,0x94,0x40,0xa5,0xc0,0x0b,0x60,0x22,0x68,0x00 } },
+{  16, 0xbe30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x20,0xb7,0x80,0xb1,0xe0 } },
+{  16, 0xbe40, 0, {0x8f,0xf8,0x03,0x12,0x02,0xe7,0x80,0x35,0xe0,0x0c,0x68,0x06,0xcf,0xc2,0xcf,0xb0 } },
+{  16, 0xbe50, 0, {0x25,0xf4,0x0f,0x58,0x03,0x5a,0x02,0xd5,0x80,0x75,0xfa,0x4f,0xf8,0x03,0x2a,0x02 } },
+{  16, 0xbe60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xa5,0x90,0xf3,0x00,0x3d,0xc0 } },
+{  16, 0xbe70, 0, {0x4f,0xb0,0x13,0xa8,0x04,0xfb,0x00,0x3c,0xc0,0x0f,0x80,0x43,0xec,0x80,0xeb,0x60 } },
+{  16, 0xbe80, 0, {0x3a,0xc9,0x0f,0x30,0x03,0xec,0x00,0xe9,0x00,0x3e,0xc8,0x0f,0xa0,0x03,0xc2,0x06 } },
+{  16, 0xbe90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xee,0x80,0x3f,0xe0 } },
+{  16, 0xbea0, 0, {0x0d,0x89,0x03,0xd2,0x40,0xe5,0x81,0x39,0xe0,0x3c,0xf9,0x07,0xfe,0x00,0xcf,0x88 } },
+{  16, 0xbeb0, 0, {0x3f,0xe0,0x0f,0xe8,0x03,0xf2,0x08,0xce,0x80,0x33,0xe0,0x0c,0xf8,0x03,0x00,0x00 } },
+{  16, 0xbec0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x94,0x44,0xc6,0x00,0x2f,0xc0 } },
+{  16, 0xbed0, 0, {0x08,0x58,0x02,0xd0,0xc4,0x85,0x24,0x21,0x90,0x08,0x54,0x12,0xdc,0x82,0x07,0x00 } },
+{  16, 0xbee0, 0, {0x2d,0xc0,0x0b,0x70,0x06,0xd4,0x00,0x8e,0x48,0x21,0xc0,0x0a,0x60,0x02,0x2a,0x04 } },
+{  16, 0xbef0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xa7,0x40,0x2d,0xc0 } },
+{  16, 0xbf00, 0, {0x08,0x42,0x02,0xd0,0x00,0xad,0x00,0x29,0xc0,0x08,0x70,0x22,0xdc,0x28,0x87,0x00 } },
+{  16, 0xbf10, 0, {0x2d,0xc0,0x0b,0x40,0x02,0x98,0x00,0x97,0x00,0xa0,0xc4,0x08,0x70,0x02,0x00,0x00 } },
+{  16, 0xbf20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x08,0x93,0x00,0x2c,0xe0 } },
+{  16, 0xbf30, 0, {0x08,0x3c,0x22,0xc1,0x00,0x81,0x00,0x20,0x80,0x88,0x15,0x02,0xce,0x30,0x83,0x00 } },
+{  16, 0xbf40, 0, {0x2c,0xc0,0x0b,0x3c,0x02,0xcc,0x04,0x93,0xc0,0x20,0xf4,0x4a,0x0c,0x82,0x08,0x04 } },
+{  16, 0xbf50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa0,0x00,0xe3,0xc0,0x1f,0xe0 } },
+{  16, 0xbf60, 0, {0x6c,0x10,0x83,0xe0,0x04,0xeb,0x00,0x3a,0x52,0x4c,0xb4,0x03,0xfe,0x02,0xcf,0x00 } },
+{  16, 0xbf70, 0, {0x3f,0xc0,0x0f,0x84,0x43,0xe1,0x02,0xd8,0xc2,0x33,0xc0,0x0c,0x84,0x0b,0x2a,0x04 } },
+{  16, 0xbf80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe9,0x00,0xeb,0x10,0x3e,0xc4 } },
+{  16, 0xbf90, 0, {0x0e,0x94,0x03,0xe4,0x00,0xfb,0x18,0x3e,0xc2,0x0f,0xb6,0x03,0xec,0x00,0xfb,0x01 } },
+{  16, 0xbfa0, 0, {0x3e,0xc0,0x0f,0x35,0x03,0xc4,0x28,0xea,0x42,0x3e,0xc0,0x0f,0x81,0x03,0xe0,0x00 } },
+{  16, 0xbfb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x40,0xff,0x00,0x33,0xc0 } },
+{  16, 0xbfc0, 0, {0x0c,0xc0,0xa3,0x30,0x28,0xcd,0xa0,0x33,0xc0,0x0c,0xe8,0x03,0x0c,0x00,0xef,0x05 } },
+{  16, 0xbfd0, 0, {0x3d,0xc0,0x0c,0xca,0x83,0x3c,0x00,0xcd,0x08,0x3f,0xc2,0x0c,0xa0,0x03,0xc0,0x44 } },
+{  16, 0xbfe0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x67,0x00,0xbb,0x80,0x20,0xc0 } },
+{  16, 0xbff0, 0, {0x08,0xaa,0x02,0x08,0x00,0xa1,0x01,0x34,0xd1,0x08,0xa4,0x12,0x2c,0x00,0x8b,0x00 } },
+{  16, 0xc000, 0, {0x6e,0xc0,0x88,0xb2,0x02,0x2c,0x08,0x89,0x80,0x2e,0xc0,0x0a,0xa8,0x03,0xa0,0x40 } },
+{  16, 0xc010, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xba,0x80,0xa2,0xc0 } },
+{  16, 0xc020, 0, {0x08,0xa8,0x0a,0xa0,0x00,0x8b,0x00,0xa2,0xc0,0x48,0x11,0x02,0xac,0x04,0x8b,0x00 } },
+{  16, 0xc030, 0, {0x2e,0xc0,0x00,0x80,0x12,0x2a,0x08,0x8b,0x14,0x2c,0xc0,0x08,0x88,0x02,0xe0,0x00 } },
+{  16, 0xc040, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0xb2,0x00,0x22,0xc0 } },
+{  16, 0xc050, 0, {0x08,0xb2,0x12,0x80,0x00,0xab,0x01,0x24,0xc0,0x08,0x00,0x02,0x0c,0x04,0x83,0x00 } },
+{  16, 0xc060, 0, {0x2c,0xc0,0x08,0x30,0x02,0x07,0x00,0x82,0x00,0x24,0xc0,0x08,0x08,0x02,0x82,0x01 } },
+{  16, 0xc070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xfb,0x00,0x32,0xc0 } },
+{  16, 0xc080, 0, {0x0c,0xa2,0x03,0xa0,0x00,0xc9,0x00,0x32,0xc0,0x24,0x94,0x03,0x3c,0x02,0xcf,0x00 } },
+{  16, 0xc090, 0, {0x2f,0xc0,0x04,0x80,0x0b,0x09,0x02,0xcb,0x01,0x3f,0xc0,0x2c,0xa0,0x03,0xc0,0x03 } },
+{  16, 0xc0a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xdc,0x00,0xfd,0x02,0x3f,0xc0 } },
+{  16, 0xc0b0, 0, {0x4f,0xe4,0x13,0x70,0x00,0xfd,0x00,0x3f,0xc0,0x0f,0xc2,0x83,0xfc,0x00,0xff,0x00 } },
+{  16, 0xc0c0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xa8,0x06 } },
+{  16, 0xc0d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x20,0xef,0x30,0x3f,0x04 } },
+{  16, 0xc0e0, 0, {0x6c,0x88,0x03,0x3a,0x42,0xe4,0x91,0x3f,0x0d,0x0d,0x48,0x03,0x3c,0xc0,0xff,0x02 } },
+{  16, 0xc0f0, 0, {0x33,0x44,0x0c,0xf4,0x03,0xfc,0x82,0xdf,0x30,0x33,0x60,0x0d,0xf1,0x03,0x30,0x00 } },
+{  16, 0xc100, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0xed,0x00,0x8b,0x70,0x2e,0x18 } },
+{  16, 0xc110, 0, {0x88,0x22,0x4a,0x2c,0x82,0xea,0x26,0x2e,0x0c,0x0b,0xb8,0x42,0x3d,0x80,0xbf,0x90 } },
+{  16, 0xc120, 0, {0x2a,0x54,0x28,0xb4,0x02,0xcd,0x00,0xdb,0x40,0x2a,0x4a,0x48,0x30,0x02,0xa0,0x04 } },
+{  16, 0xc130, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0xb0,0xa3,0x00,0x6c,0x10 } },
+{  16, 0xc140, 0, {0x09,0x00,0x82,0x20,0x82,0xa0,0x20,0x2c,0x88,0x4b,0x80,0x00,0x0c,0x40,0xb3,0x01 } },
+{  16, 0xc150, 0, {0x20,0x48,0x0b,0x36,0x02,0x8c,0xe0,0x83,0x64,0x24,0x40,0x28,0x32,0x02,0x22,0x01 } },
+{  16, 0xc160, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x11,0xac,0x00,0x8b,0x00,0x2e,0x00 } },
+{  16, 0xc170, 0, {0x09,0x80,0x80,0xa6,0x00,0xba,0x11,0x2e,0x88,0x0b,0xb0,0x00,0x2c,0x00,0xbb,0x02 } },
+{  16, 0xc180, 0, {0x02,0x40,0x09,0xb0,0x02,0xec,0x00,0x8b,0x00,0x2c,0xc8,0x08,0xb8,0x82,0xb0,0x04 } },
+{  16, 0xc190, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xeb,0x00,0x3e,0x92 } },
+{  16, 0xc1a0, 0, {0x0d,0x80,0x03,0x0a,0x20,0xe9,0x00,0x3e,0x50,0x45,0x80,0x01,0x2c,0x04,0xf3,0x00 } },
+{  16, 0xc1b0, 0, {0x90,0x60,0x09,0xb0,0x03,0xec,0x00,0x8b,0x02,0x26,0x50,0x8d,0xbc,0x03,0x10,0x04 } },
+{  16, 0xc1c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xbc,0x00,0xff,0x02,0x3f,0x80 } },
+{  16, 0xc1d0, 0, {0x0e,0xf9,0x02,0x7c,0x22,0xaf,0x00,0x3f,0x60,0x03,0xc0,0x0b,0xfc,0x10,0xff,0x00 } },
+{  16, 0xc1e0, 0, {0x3f,0x4a,0x4e,0xf0,0x03,0xfc,0x00,0xf7,0x00,0x2b,0x60,0x0f,0x70,0x03,0xf8,0x00 } },
+{  16, 0xc1f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x00,0xb0,0x00 } },
+{  16, 0xc200, 0, {0x0f,0x82,0x0b,0xa9,0x00,0xc9,0x00,0x32,0xd2,0x0f,0xa0,0x83,0xac,0x00,0xcb,0x10 } },
+{  16, 0xc210, 0, {0x3e,0x40,0x0c,0xb0,0x03,0xec,0x00,0xdb,0x00,0x32,0x50,0x2c,0x95,0x03,0x10,0x04 } },
+{  16, 0xc220, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3c,0x04,0xbf,0x02,0x22,0x80 } },
+{  16, 0xc230, 0, {0x0b,0x98,0x00,0x29,0x00,0xcb,0x40,0x22,0xc0,0x0b,0x24,0x02,0x3c,0x08,0x8f,0x50 } },
+{  16, 0xc240, 0, {0x2e,0x50,0x0d,0xf0,0x02,0xfd,0x42,0x8f,0x58,0x22,0xe0,0x48,0xb5,0x02,0x32,0x00 } },
+{  16, 0xc250, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x6c,0x00,0xb3,0x00,0x24,0x40 } },
+{  16, 0xc260, 0, {0x4b,0x94,0x00,0x49,0x00,0x90,0x80,0x04,0x30,0x09,0x00,0x0e,0x4c,0x00,0x83,0x80 } },
+{  16, 0xc270, 0, {0x2c,0xc0,0x09,0x30,0x22,0x6e,0x42,0x83,0x80,0x20,0x48,0x08,0x38,0x02,0x38,0x00 } },
+{  16, 0xc280, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x00,0xb7,0x80,0x65,0x20 } },
+{  16, 0xc290, 0, {0x0b,0x78,0x82,0x7a,0x08,0x8c,0xc0,0x25,0xa3,0x4b,0x78,0x02,0x5e,0x04,0x87,0x84 } },
+{  16, 0xc2a0, 0, {0x2d,0x61,0x89,0x78,0x02,0xde,0x04,0x87,0x80,0xe9,0x62,0x08,0x78,0x02,0x08,0x00 } },
+{  16, 0xc2b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xfb,0x00,0x34,0x48 } },
+{  16, 0xc2c0, 0, {0x0f,0x3b,0x03,0x48,0x00,0x93,0x48,0x34,0x50,0x0d,0x00,0x03,0x6c,0x00,0xc3,0x10 } },
+{  16, 0xc2d0, 0, {0x1c,0xc2,0x05,0x30,0x03,0xcc,0x40,0xcb,0x00,0x32,0x40,0x0c,0x20,0x03,0x12,0x02 } },
+{  16, 0xc2e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x20,0xff,0x01,0x03,0x40 } },
+{  16, 0xc2f0, 0, {0x0f,0xf0,0x23,0x1c,0x00,0xff,0x00,0x3b,0x80,0x0f,0xb0,0x23,0x3c,0x02,0xff,0x50 } },
+{  16, 0xc300, 0, {0x3d,0xc4,0x0f,0xf1,0x03,0xec,0x00,0xef,0x00,0xb7,0xc0,0x0f,0xe1,0x03,0xd0,0x06 } },
+{  16, 0xc310, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xec,0x00,0xfb,0x02,0x3e,0xe0 } },
+{  16, 0xc320, 0, {0x0c,0x80,0x03,0x48,0x02,0xc8,0x81,0x32,0x00,0x0f,0x90,0x42,0xec,0xa0,0xfb,0x10 } },
+{  16, 0xc330, 0, {0x3e,0xe0,0x0c,0xb1,0x03,0xec,0x40,0xfb,0x10,0x32,0x40,0x1f,0xf0,0x03,0x2a,0x00 } },
+{  16, 0xc340, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0xb7,0x24,0x2d,0x80 } },
+{  16, 0xc350, 0, {0x08,0x70,0x42,0xd8,0x10,0x8c,0x02,0x21,0x40,0x0b,0x50,0x02,0xdd,0x00,0xe7,0x20 } },
+{  16, 0xc360, 0, {0x2f,0x40,0x08,0x70,0x02,0xdc,0x05,0xb7,0x00,0x21,0xc0,0x0b,0xf0,0x02,0x12,0x04 } },
+{  16, 0xc370, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0x90,0x2f,0x40 } },
+{  16, 0xc380, 0, {0x0a,0x68,0x02,0x7a,0x00,0x97,0x80,0x21,0xe0,0x0b,0x78,0x02,0xde,0x00,0xb7,0x80 } },
+{  16, 0xc390, 0, {0x2d,0xe0,0x08,0x78,0x06,0xde,0x00,0xb7,0xa0,0x21,0x60,0x0b,0x78,0x42,0x30,0x00 } },
+{  16, 0xc3a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xb3,0x00,0x2c,0xc0 } },
+{  16, 0xc3b0, 0, {0x0a,0x34,0x02,0xc8,0x00,0x83,0x4a,0x20,0xf8,0x0b,0x31,0x02,0xcc,0x00,0xa3,0x00 } },
+{  16, 0xc3c0, 0, {0x2c,0xc0,0x08,0x30,0x02,0xcc,0x00,0xb3,0x00,0x20,0xb2,0x0b,0x20,0x42,0x12,0x04 } },
+{  16, 0xc3d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xba,0x00,0x3f,0x88 } },
+{  16, 0xc3e0, 0, {0x2e,0xe0,0x43,0x59,0x88,0xde,0x00,0x33,0xb0,0x0f,0x6c,0x03,0xe8,0x00,0xfa,0x00 } },
+{  16, 0xc3f0, 0, {0x3e,0x80,0x2c,0xa0,0x03,0xe8,0x04,0xfa,0x00,0x23,0xb8,0x0f,0xe0,0x8b,0x3a,0x04 } },
+{  16, 0xc400, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x04,0xf8,0x01,0x3e,0x00 } },
+{  16, 0xc410, 0, {0x09,0x82,0x21,0xe0,0x00,0xf8,0x40,0xbe,0x14,0x0f,0x84,0x81,0xe0,0x00,0xe8,0x00 } },
+{  16, 0xc420, 0, {0x3e,0x00,0x1f,0x80,0x03,0xe0,0x00,0xf8,0x00,0xbe,0x00,0x0f,0x88,0x03,0xd2,0x00 } },
+{  16, 0xc430, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xe1,0x00,0x32,0x40 } },
+{  16, 0xc440, 0, {0x0c,0x90,0x43,0xe4,0x20,0xd9,0x00,0x3c,0x44,0x08,0x90,0x03,0x24,0x00,0xf9,0x01 } },
+{  16, 0xc450, 0, {0x3e,0x48,0x0f,0x10,0x43,0x25,0x00,0xc9,0x00,0xb2,0x40,0x0c,0x90,0x03,0x02,0x04 } },
+{  16, 0xc460, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x00,0xa0,0x40 } },
+{  16, 0xc470, 0, {0x08,0x98,0x02,0xe6,0x08,0xa9,0x60,0x2e,0x49,0x08,0x94,0x02,0x24,0x00,0xb9,0x00 } },
+{  16, 0xc480, 0, {0x2e,0x70,0x0b,0x90,0x02,0x26,0x02,0x89,0x00,0xa0,0x40,0x0a,0x90,0x0a,0x20,0x00 } },
+{  16, 0xc490, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x00,0x22,0x40 } },
+{  16, 0xc4a0, 0, {0x08,0x98,0x04,0xe6,0x00,0x99,0x80,0x2e,0x40,0x0a,0xb1,0x02,0x24,0x00,0xb9,0x00 } },
+{  16, 0xc4b0, 0, {0x0e,0x40,0x0b,0x90,0x0a,0x04,0x00,0x81,0x01,0x22,0xc0,0x08,0x10,0x02,0x06,0x00 } },
+{  16, 0xc4c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x80,0xb1,0x20,0x22,0x48 } },
+{  16, 0xc4d0, 0, {0x08,0x18,0x06,0xc4,0x00,0xa1,0x00,0x2c,0x48,0x2a,0x30,0x02,0x04,0x80,0xb1,0x22 } },
+{  16, 0xc4e0, 0, {0x2c,0x48,0x0b,0x12,0x02,0x05,0x80,0x81,0x60,0x22,0x50,0x0a,0x14,0x02,0x02,0x01 } },
+{  16, 0xc4f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x50,0x32,0x14 } },
+{  16, 0xc500, 0, {0x0c,0x85,0x03,0xe1,0x40,0xd8,0x50,0x3e,0x14,0x0e,0x80,0x0b,0x21,0x40,0xfa,0x00 } },
+{  16, 0xc510, 0, {0x3e,0x94,0x0f,0x85,0x03,0x20,0x00,0xc0,0x00,0x32,0x00,0x0c,0x80,0x03,0x2e,0x03 } },
+{  16, 0xc520, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x41,0xf9,0x10,0x3d,0x45 } },
+{  16, 0xc530, 0, {0x0f,0xd0,0x03,0xf4,0x00,0xff,0x00,0x3f,0x45,0x0d,0xd0,0x03,0xe4,0x40,0xf9,0x10 } },
+{  16, 0xc540, 0, {0x3f,0x44,0x0f,0x91,0x03,0xe4,0x42,0xf9,0x10,0x3f,0x40,0x0f,0xd4,0x03,0xe6,0x06 } },
+{  16, 0xc550, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe4,0x00,0xf9,0x00,0x3e,0x40 } },
+{  16, 0xc560, 0, {0x0c,0xd0,0x03,0xf4,0x08,0x8d,0x02,0x3f,0x40,0x0f,0xd0,0x03,0xe4,0x00,0xcd,0x00 } },
+{  16, 0xc570, 0, {0x33,0x40,0x0c,0x90,0x03,0x24,0x00,0xf9,0x00,0x32,0x40,0x4c,0x98,0x23,0x06,0x00 } },
+{  16, 0xc580, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x00,0xe8,0x00,0x2e,0x00 } },
+{  16, 0xc590, 0, {0x48,0x80,0x02,0xe8,0x00,0xd0,0x00,0x2e,0x80,0x0b,0x80,0x12,0xe0,0x02,0x88,0x00 } },
+{  16, 0xc5a0, 0, {0xa2,0x00,0x0a,0x80,0x12,0x22,0x00,0xb8,0x81,0x22,0x28,0x08,0xcf,0x02,0x0e,0x04 } },
+{  16, 0xc5b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x2c,0x40 } },
+{  16, 0xc5c0, 0, {0x28,0x10,0x02,0xc4,0x00,0x81,0x00,0x2c,0x40,0x0b,0x10,0x02,0xc4,0x00,0x91,0x00 } },
+{  16, 0xc5d0, 0, {0x26,0x40,0x09,0x10,0x02,0x54,0xa0,0xb5,0x2c,0xa5,0x42,0x08,0x50,0x82,0x02,0x01 } },
+{  16, 0xc5e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x00,0xa9,0x00,0x2e,0x50 } },
+{  16, 0xc5f0, 0, {0x58,0x90,0x02,0xe4,0x80,0x9b,0x00,0x2e,0x45,0x8b,0x92,0x02,0xe4,0x00,0x99,0x00 } },
+{  16, 0xc600, 0, {0x26,0x44,0x0b,0x90,0x02,0x64,0x08,0xb5,0x00,0x25,0x4a,0x08,0x51,0x02,0x06,0x04 } },
+{  16, 0xc610, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x00,0x3e,0x54 } },
+{  16, 0xc620, 0, {0x0c,0x90,0x43,0xc4,0x00,0xc9,0x90,0x3e,0x70,0x0f,0x98,0x03,0xe4,0x00,0xd9,0x00 } },
+{  16, 0xc630, 0, {0x34,0x60,0x4d,0x90,0x0a,0x64,0x00,0xf9,0x00,0x36,0x40,0x2c,0x9e,0x03,0x28,0x04 } },
+{  16, 0xc640, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x00,0x3c,0x40 } },
+{  16, 0xc650, 0, {0x0f,0x9c,0x03,0xe6,0x30,0xf9,0x00,0x3e,0x62,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x00 } },
+{  16, 0xc660, 0, {0x3a,0x40,0x4e,0x90,0x03,0xa4,0x00,0x79,0x0c,0x3a,0x40,0x0f,0x90,0x1b,0xca,0x00 } },
+{  16, 0xc670, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x00,0x3e,0x00 } },
+{  16, 0xc680, 0, {0x0c,0x81,0x13,0xe1,0x08,0xc8,0x48,0x32,0x00,0x3c,0x80,0x03,0xc0,0x00,0xf0,0x10 } },
+{  16, 0xc690, 0, {0x3e,0x06,0x0c,0x80,0x03,0xf0,0x08,0xcc,0x00,0x33,0x04,0x0c,0xc0,0x03,0x0a,0x04 } },
+{  16, 0xc6a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0xba,0x00,0x2e,0x80 } },
+{  16, 0xc6b0, 0, {0x08,0xec,0x42,0xfa,0x20,0x8e,0x00,0x23,0xa0,0x08,0xe8,0x42,0xe8,0x00,0xbe,0x80 } },
+{  16, 0xc6c0, 0, {0x2f,0x80,0x08,0xa0,0x02,0xe8,0x00,0xda,0x00,0x22,0x80,0x48,0xe0,0x02,0x0a,0x00 } },
+{  16, 0xc6d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x00,0x2c,0xc0 } },
+{  16, 0xc6e0, 0, {0x09,0x34,0x82,0xc9,0x00,0x83,0x80,0x20,0xf0,0x08,0x30,0x82,0xcc,0x00,0xb3,0x80 } },
+{  16, 0xc6f0, 0, {0x2c,0xf0,0x08,0xb0,0x02,0xc1,0x20,0x80,0x00,0xa0,0x32,0x08,0x00,0x02,0x0a,0x00 } },
+{  16, 0xc700, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0xc0,0xb7,0x01,0x2f,0xc8 } },
+{  16, 0xc710, 0, {0x89,0x50,0x02,0xd8,0x02,0x87,0xc4,0x21,0xe2,0x48,0x70,0x82,0xdc,0x00,0xb7,0x00 } },
+{  16, 0xc720, 0, {0x2c,0x40,0x08,0x72,0x02,0xce,0x00,0x97,0x08,0x23,0xc0,0x08,0x70,0x02,0x28,0x00 } },
+{  16, 0xc730, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf7,0xe1,0x3d,0xe8 } },
+{  16, 0xc740, 0, {0x2d,0x68,0x03,0xf2,0x00,0xc7,0x80,0xb0,0xe0,0x08,0x68,0x03,0xdf,0x80,0xf6,0x80 } },
+{  16, 0xc750, 0, {0x3d,0xe0,0x8c,0x7e,0x03,0xda,0x00,0xcc,0x80,0x31,0x20,0x0c,0xc8,0x0b,0x2a,0x02 } },
+{  16, 0xc760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x08,0xfb,0x00,0x3c,0xc0 } },
+{  16, 0xc770, 0, {0x0e,0x80,0x03,0xe0,0x08,0xf9,0x00,0x3e,0x40,0x0f,0xb0,0x02,0xec,0x00,0xfa,0x00 } },
+{  16, 0xc780, 0, {0x3e,0x40,0x2f,0xb0,0x03,0xe4,0x00,0xfb,0x00,0x3c,0xc0,0x2f,0xb0,0x03,0xc2,0x06 } },
+{  16, 0xc790, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xff,0x92,0x7f,0xea } },
+{  16, 0xc7a0, 0, {0x0c,0xf8,0x03,0xfe,0x00,0xcc,0xa0,0x3f,0x20,0x0d,0xf9,0x03,0x3e,0x00,0xcf,0x80 } },
+{  16, 0xc7b0, 0, {0x33,0x60,0x0f,0xf8,0x03,0xf6,0x00,0xef,0x84,0x33,0xe0,0x2c,0xc8,0x03,0x00,0x00 } },
+{  16, 0xc7c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xb7,0x00,0x2f,0xc8 } },
+{  16, 0xc7d0, 0, {0x08,0x54,0x02,0xd8,0x00,0xd6,0x04,0x2d,0x01,0x08,0x69,0x02,0x1c,0x00,0x85,0x00 } },
+{  16, 0xc7e0, 0, {0x21,0x43,0x0b,0x70,0x03,0x9a,0xc0,0x8c,0x00,0xa3,0x02,0x08,0xf1,0x02,0x2a,0x04 } },
+{  16, 0xc7f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x01,0x2d,0xcc } },
+{  16, 0xc800, 0, {0x08,0x70,0x02,0xd4,0x00,0x94,0x28,0x2d,0xc2,0x08,0xc2,0x02,0x5c,0x00,0x86,0x00 } },
+{  16, 0xc810, 0, {0x21,0x80,0x0b,0x71,0x02,0xdc,0x00,0xa7,0x10,0x21,0xc0,0x08,0x48,0x02,0x40,0x00 } },
+{  16, 0xc820, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x08,0xb3,0x00,0x2c,0xf0 } },
+{  16, 0xc830, 0, {0x08,0x05,0x02,0xc0,0x20,0x90,0x80,0x2e,0x00,0x08,0x00,0x82,0x4c,0x02,0x80,0x00 } },
+{  16, 0xc840, 0, {0xa0,0x61,0x0b,0x30,0x02,0xa0,0x00,0x80,0x00,0xa0,0x30,0x88,0xb1,0x0a,0x48,0x04 } },
+{  16, 0xc850, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xff,0x00,0x2d,0xc8 } },
+{  16, 0xc860, 0, {0x0c,0x3d,0x03,0xe4,0x00,0xdb,0x02,0x3e,0xf0,0x2c,0x90,0x4b,0x7c,0x00,0xc1,0x00 } },
+{  16, 0xc870, 0, {0x32,0x20,0x4f,0xf0,0x13,0xe0,0x00,0xe8,0x01,0x32,0x00,0x8c,0xac,0x03,0x6a,0x04 } },
+{  16, 0xc880, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xfb,0x04,0x3e,0xc2 } },
+{  16, 0xc890, 0, {0x4f,0xb0,0x03,0xe0,0x04,0xfa,0x40,0x3e,0xc2,0x4e,0x98,0x23,0xac,0x10,0xf8,0x00 } },
+{  16, 0xc8a0, 0, {0x3e,0x50,0x07,0xb0,0x13,0xac,0x00,0xfb,0x00,0x3e,0xc2,0x0f,0x92,0x03,0xa0,0x00 } },
+{  16, 0xc8b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xcf,0x00,0x3f,0xc0 } },
+{  16, 0xc8c0, 0, {0x0c,0xc8,0x23,0x36,0x82,0xcf,0x80,0x3f,0x80,0x0c,0xe0,0x03,0xec,0x00,0xf9,0x20 } },
+{  16, 0xc8d0, 0, {0x33,0xc0,0x0e,0xf0,0x03,0xf8,0x10,0xdc,0x00,0x33,0x00,0x4c,0xe8,0x21,0x00,0x44 } },
+{  16, 0xc8e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x00,0xab,0x00,0x2e,0xc0 } },
+{  16, 0xc8f0, 0, {0x4a,0x8d,0x42,0x21,0x00,0x8b,0x42,0x2e,0xd2,0x08,0xb0,0x03,0xec,0x00,0xb8,0x88 } },
+{  16, 0xc900, 0, {0x34,0x62,0x0d,0xb0,0x02,0xe4,0x00,0x8b,0x00,0x22,0xc0,0x08,0x90,0x0a,0x20,0x40 } },
+{  16, 0xc910, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x00,0x2e,0xc0 } },
+{  16, 0xc920, 0, {0x08,0xa0,0x02,0x0d,0x00,0x89,0x10,0x2e,0x08,0x28,0x92,0x02,0xec,0x04,0xbb,0x00 } },
+{  16, 0xc930, 0, {0x22,0xa0,0x08,0xb0,0x02,0x64,0x02,0xb3,0x02,0x20,0xc0,0x08,0xa2,0x02,0xa0,0x00 } },
+{  16, 0xc940, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0xa3,0x00,0x2e,0xc0 } },
+{  16, 0xc950, 0, {0x0a,0x90,0x22,0x0c,0x10,0x80,0x00,0x2c,0x00,0x18,0x02,0x82,0xcc,0x00,0xb0,0x00 } },
+{  16, 0xc960, 0, {0x26,0x40,0x09,0x30,0x02,0xc8,0x20,0x80,0x00,0x20,0x00,0x08,0x10,0x06,0x82,0x01 } },
+{  16, 0xc970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xcb,0x00,0x2e,0xc0 } },
+{  16, 0xc980, 0, {0x0c,0xa1,0x02,0x24,0x00,0x88,0x00,0x3c,0x00,0x0c,0x80,0x03,0xec,0x00,0xfb,0x00 } },
+{  16, 0xc990, 0, {0x32,0x80,0x0e,0xb0,0x03,0xcc,0x80,0xdb,0x00,0x32,0xc0,0x0c,0xa0,0x03,0x80,0x03 } },
+{  16, 0xc9a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xff,0x00,0x3f,0xc0 } },
+{  16, 0xc9b0, 0, {0x4f,0xc2,0x13,0xd4,0x10,0xfc,0x00,0x3f,0x00,0x0f,0x00,0x03,0xbc,0x00,0xfc,0x00 } },
+{  16, 0xc9c0, 0, {0x3f,0x40,0x0f,0xf0,0x23,0xe0,0x12,0xfc,0x01,0xbf,0x00,0x0f,0xd0,0x03,0x68,0x02 } },
+{  16, 0xc9d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xc7,0x80,0x33,0xc0 } },
+{  16, 0xc9e0, 0, {0x8b,0xb4,0x03,0xb0,0xc0,0xcf,0x2e,0x1f,0x0c,0x4f,0xc3,0x03,0x30,0x80,0xff,0x01 } },
+{  16, 0xc9f0, 0, {0x3f,0x08,0x0f,0xf0,0x00,0x7c,0x00,0xff,0x21,0x33,0xe4,0x0c,0xe0,0x03,0x30,0x00 } },
+{  16, 0xca00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xee,0x00,0x8b,0x82,0x23,0xf0 } },
+{  16, 0xca10, 0, {0x0b,0xb5,0x12,0x0d,0x88,0x88,0xc0,0x0e,0x98,0x0b,0x86,0x02,0x21,0x00,0xbb,0xc0 } },
+{  16, 0xca20, 0, {0x2e,0xe4,0x4b,0xf7,0x83,0x2f,0x44,0xbf,0x90,0x22,0xc8,0x48,0xa6,0x82,0x20,0x04 } },
+{  16, 0xca30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x09,0x8a,0x00,0x20,0x50 } },
+{  16, 0xca40, 0, {0x4b,0xb2,0x0a,0x80,0xcc,0x83,0x01,0x0c,0x8c,0x0b,0x23,0x0a,0x04,0x60,0xb3,0x14 } },
+{  16, 0xca50, 0, {0x24,0x40,0x4b,0x30,0x02,0xcc,0x10,0xb3,0x00,0x20,0xc8,0xe9,0x11,0x06,0x62,0x01 } },
+{  16, 0xca60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x01,0x8a,0x80,0xa2,0x44 } },
+{  16, 0xca70, 0, {0x0b,0xb0,0x02,0xa1,0x04,0x88,0x40,0x2e,0xa0,0x0b,0x20,0x02,0x28,0x20,0xbb,0x40 } },
+{  16, 0xca80, 0, {0x2e,0x40,0x0b,0xb0,0x02,0x2c,0x08,0xbb,0x00,0x22,0xc0,0x09,0xb0,0x02,0x70,0x04 } },
+{  16, 0xca90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xc3,0x83,0x32,0xe0 } },
+{  16, 0xcaa0, 0, {0x8f,0x00,0x03,0xa0,0x02,0xcb,0xc4,0x3e,0x28,0x07,0x8b,0x03,0x21,0x00,0xf9,0xc0 } },
+{  16, 0xcab0, 0, {0x3e,0x10,0x0f,0xb0,0x03,0xec,0x00,0x7b,0x00,0x32,0xc0,0x0d,0xa0,0x03,0x50,0x04 } },
+{  16, 0xcac0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x9c,0x02,0xff,0x00,0x3f,0xe0 } },
+{  16, 0xcad0, 0, {0x0f,0xf4,0x43,0x5e,0x80,0xfc,0x94,0x3f,0x00,0x0f,0xc0,0x2b,0xf2,0x50,0xfd,0x21 } },
+{  16, 0xcae0, 0, {0x7e,0x84,0x8f,0xf0,0x03,0x6c,0x0c,0xff,0x00,0x3f,0xc0,0x0e,0x62,0x03,0xb8,0x00 } },
+{  16, 0xcaf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xeb,0x00,0x32,0x40 } },
+{  16, 0xcb00, 0, {0x2c,0x80,0x03,0x69,0x00,0xcb,0x30,0xb2,0x00,0x4f,0xb3,0x43,0xe5,0x00,0xcb,0x40 } },
+{  16, 0xcb10, 0, {0x72,0x18,0x2c,0xb0,0x03,0xec,0x28,0xc3,0x21,0x3a,0xc1,0x0f,0x94,0x03,0x10,0x04 } },
+{  16, 0xcb20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3c,0x00,0x8b,0x20,0x22,0x50 } },
+{  16, 0xcb30, 0, {0x08,0xb0,0x02,0x28,0x00,0x88,0xc0,0x2a,0x00,0x8b,0xb4,0x02,0xe8,0x00,0xdb,0x00 } },
+{  16, 0xcb40, 0, {0x62,0x30,0x08,0xf0,0x02,0xfc,0x00,0x8f,0x80,0x22,0xc0,0x0b,0x95,0x47,0x32,0x00 } },
+{  16, 0xcb50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb1,0x00,0x20,0xc2 } },
+{  16, 0xcb60, 0, {0x48,0x30,0x02,0x49,0x80,0x83,0x42,0x60,0x12,0x0b,0x30,0x02,0xc8,0x00,0x82,0x02 } },
+{  16, 0xcb70, 0, {0x2c,0x30,0x09,0xb0,0x02,0xcf,0x01,0x83,0x50,0x2a,0xc0,0x0b,0x20,0x02,0xb8,0x00 } },
+{  16, 0xcb80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x00,0x9d,0x80,0xa0,0xe0 } },
+{  16, 0xcb90, 0, {0x08,0x79,0x22,0x5e,0x60,0x87,0x90,0x29,0xa0,0x0b,0x78,0x02,0xc6,0x00,0x92,0x81 } },
+{  16, 0xcba0, 0, {0x05,0xe0,0x09,0x78,0x02,0xde,0x40,0x87,0x80,0x21,0xe0,0x0b,0x29,0x02,0x08,0x00 } },
+{  16, 0xcbb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x40,0xf2,0x00,0x30,0xc0 } },
+{  16, 0xcbc0, 0, {0x08,0x3a,0x03,0x44,0x04,0xc3,0x14,0x30,0xc0,0x0f,0x22,0x03,0xcc,0x80,0xc2,0x00 } },
+{  16, 0xcbd0, 0, {0xa4,0xd2,0x0d,0x30,0x13,0xcc,0x20,0xc3,0x00,0x38,0xc4,0x4f,0x04,0x43,0x12,0x02 } },
+{  16, 0xcbe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0x9c,0x00,0xee,0x00,0x3f,0xe0 } },
+{  16, 0xcbf0, 0, {0x0f,0x70,0x03,0xb4,0x02,0xf4,0x10,0x3f,0xc0,0x8f,0xa0,0x03,0xfc,0x00,0x7e,0x00 } },
+{  16, 0xcc00, 0, {0x3b,0xc0,0x0e,0xf0,0x83,0xec,0x00,0xf7,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xd0,0x06 } },
+{  16, 0xcc10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xfc,0x00,0xf9,0x00,0x3e,0xc0 } },
+{  16, 0xcc20, 0, {0x0f,0xa0,0x03,0xaa,0x12,0xcb,0x01,0x32,0x80,0x0f,0xb0,0x13,0x28,0x14,0xf9,0x80 } },
+{  16, 0xcc30, 0, {0x3a,0x40,0x03,0xb4,0x03,0xec,0x42,0xcb,0x18,0x3e,0xc0,0x0f,0xb0,0x03,0x2a,0x00 } },
+{  16, 0xcc40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9d,0x00,0xb5,0x00,0x2d,0xc4 } },
+{  16, 0xcc50, 0, {0x0b,0x70,0x4b,0x7c,0x00,0x84,0x00,0x21,0x80,0x0b,0x70,0x02,0x94,0x10,0xb2,0x00 } },
+{  16, 0xcc60, 0, {0x29,0xc0,0x0b,0x72,0x82,0xdc,0x00,0x87,0x20,0x2d,0xc1,0x0e,0x70,0x02,0x12,0x04 } },
+{  16, 0xcc70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0x80,0x2d,0xe0 } },
+{  16, 0xcc80, 0, {0x0b,0x68,0x02,0x9e,0x00,0x83,0x80,0x21,0xe0,0x5b,0x38,0x02,0x1e,0x00,0xb4,0xc0 } },
+{  16, 0xcc90, 0, {0x25,0xe0,0x09,0x78,0x32,0xce,0x00,0x97,0x80,0x2d,0xe0,0x0b,0x5c,0x4e,0x30,0x00 } },
+{  16, 0xcca0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xb3,0x44,0x2c,0xc0 } },
+{  16, 0xccb0, 0, {0x0b,0x3c,0x02,0xcc,0x40,0x93,0x08,0x20,0xe0,0x0b,0x30,0x02,0x8c,0x10,0xb3,0xc0 } },
+{  16, 0xccc0, 0, {0x28,0xd8,0x1b,0x30,0x02,0xcc,0x08,0x93,0x01,0x6c,0xc0,0x0a,0xb8,0x82,0x12,0x04 } },
+{  16, 0xccd0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xf6,0x10,0x3e,0x80 } },
+{  16, 0xcce0, 0, {0x4b,0xed,0x83,0xb8,0x00,0xce,0xe4,0xb3,0xa3,0x0f,0xe0,0x03,0x38,0x00,0xfe,0x00 } },
+{  16, 0xccf0, 0, {0x3b,0x80,0x0d,0xa0,0x02,0xe8,0x00,0xda,0x00,0x3e,0x80,0x0f,0xe8,0x02,0x3a,0x04 } },
+{  16, 0xcd00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x10,0xf8,0x40,0x3e,0x00 } },
+{  16, 0xcd10, 0, {0x0f,0x80,0x13,0x60,0x00,0xe0,0x00,0x3e,0x00,0x43,0x08,0x03,0xe0,0x00,0xf8,0x08 } },
+{  16, 0xcd20, 0, {0x3a,0x00,0x0f,0x80,0x03,0xe0,0x00,0xe8,0x40,0x3e,0x00,0x0e,0x80,0x23,0xd2,0x00 } },
+{  16, 0xcd30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x00,0xd9,0xc0,0xbe,0x40 } },
+{  16, 0xcd40, 0, {0x0f,0x90,0x03,0xe6,0x00,0xf9,0x00,0x32,0x40,0x01,0x9a,0x03,0x24,0x00,0xf9,0x00 } },
+{  16, 0xcd50, 0, {0x3e,0x40,0x0f,0x90,0x03,0xc4,0x40,0x09,0x10,0x0e,0x40,0x0f,0x9a,0x03,0x02,0x04 } },
+{  16, 0xcd60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x04,0x89,0x04,0xa2,0x60 } },
+{  16, 0xcd70, 0, {0x8b,0x9d,0x80,0xa6,0x00,0xb9,0x80,0x22,0x40,0x48,0x98,0x02,0x24,0x00,0xb9,0x00 } },
+{  16, 0xcd80, 0, {0x2e,0x40,0x8b,0x90,0x02,0xe4,0x94,0x89,0x60,0x2e,0x40,0x0b,0x94,0x0b,0x20,0x00 } },
+{  16, 0xcd90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x99,0x08,0xae,0x48 } },
+{  16, 0xcda0, 0, {0x4b,0x10,0x02,0xe5,0x81,0xb9,0x10,0x20,0x44,0x1b,0x94,0x02,0x24,0x10,0xb9,0x00 } },
+{  16, 0xcdb0, 0, {0x6e,0x60,0x0b,0x90,0x02,0xe4,0x00,0x89,0x00,0x2e,0x40,0x0b,0x94,0x02,0x06,0x00 } },
+{  16, 0xcdc0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x80,0x89,0x00,0xa0,0x68 } },
+{  16, 0xcdd0, 0, {0x0b,0x12,0x02,0x84,0x89,0xb1,0x20,0x20,0x48,0x1a,0x12,0x12,0x04,0x80,0xb1,0x22 } },
+{  16, 0xcde0, 0, {0x0c,0x48,0x0b,0x12,0x02,0xc4,0x81,0xa1,0x20,0x2c,0x40,0x0b,0x12,0x02,0x02,0x01 } },
+{  16, 0xcdf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xd8,0x00,0xbe,0x00 } },
+{  16, 0xce00, 0, {0x0f,0x05,0x0b,0xe1,0x40,0xf8,0x00,0x32,0x14,0x0f,0x85,0x03,0x21,0x40,0xf8,0x00 } },
+{  16, 0xce10, 0, {0x2e,0x80,0x0f,0x85,0x13,0xe0,0x02,0xc8,0x00,0x3e,0x14,0x0f,0x05,0x01,0x2e,0x03 } },
+{  16, 0xce20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x40,0xfd,0x00,0xbf,0x44 } },
+{  16, 0xce30, 0, {0x0f,0xd1,0x03,0xf4,0x40,0x7d,0x10,0xbf,0x44,0x45,0xf1,0x2b,0xf4,0x40,0xfd,0x10 } },
+{  16, 0xce40, 0, {0x3f,0x44,0x0f,0x91,0x03,0xe4,0x40,0xd9,0x10,0x3e,0x40,0x0f,0xd1,0x03,0xa6,0x06 } },
+{  16, 0xce50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x00,0xfd,0x00,0x1f,0x62 } },
+{  16, 0xce60, 0, {0x0f,0xd8,0x82,0x36,0x00,0xbd,0xa0,0x3b,0x68,0x0c,0xdc,0x83,0x26,0xc8,0xd9,0xa0 } },
+{  16, 0xce70, 0, {0x33,0x60,0x0d,0x99,0x83,0x56,0x20,0xd5,0xa8,0x2e,0x44,0x0c,0xd8,0x83,0x86,0x04 } },
+{  16, 0xce80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x48,0xb8,0x00,0x2e,0x00 } },
+{  16, 0xce90, 0, {0x0b,0x0a,0x82,0x22,0x20,0xb8,0x50,0x22,0xba,0x08,0x8a,0x22,0x22,0x80,0x88,0x00 } },
+{  16, 0xcea0, 0, {0x22,0x01,0x08,0x0c,0x02,0x20,0x00,0x88,0x00,0x2e,0x28,0x88,0x88,0x02,0xce,0x04 } },
+{  16, 0xceb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x2c,0x40 } },
+{  16, 0xcec0, 0, {0x1b,0x10,0x0a,0x84,0x40,0xb1,0x00,0x28,0x58,0x0a,0x32,0x02,0x05,0x00,0x99,0x40 } },
+{  16, 0xced0, 0, {0x20,0x65,0x09,0x10,0x42,0xc4,0x00,0x91,0x00,0x2c,0x40,0x0a,0x30,0x82,0xc2,0x01 } },
+{  16, 0xcee0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x00,0xb9,0x00,0x2e,0x40 } },
+{  16, 0xcef0, 0, {0x1b,0x90,0x02,0xa5,0x80,0xb9,0x10,0x22,0x48,0x08,0x10,0x42,0x04,0x10,0x09,0x00 } },
+{  16, 0xcf00, 0, {0x22,0x40,0x08,0x90,0x02,0xe4,0x00,0x9b,0x00,0x2c,0x40,0x0a,0x94,0x22,0xc6,0x04 } },
+{  16, 0xcf10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x20,0x3e,0x40 } },
+{  16, 0xcf20, 0, {0x0f,0x90,0x13,0xa7,0x10,0xf9,0x60,0xba,0x50,0x2e,0x9c,0x0a,0x25,0x84,0xd1,0xf0 } },
+{  16, 0xcf30, 0, {0xb2,0x60,0x0d,0x90,0x03,0xe4,0x00,0xd9,0x00,0x3e,0x40,0x0e,0x90,0x03,0xa8,0x00 } },
+{  16, 0xcf40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x0c,0xf9,0x90,0x3e,0x6a } },
+{  16, 0xcf50, 0, {0x8f,0x90,0x23,0x66,0x00,0xf1,0x08,0x3c,0x40,0x0f,0x9c,0x43,0xe4,0x40,0xf9,0x80 } },
+{  16, 0xcf60, 0, {0x3a,0x44,0x0f,0x90,0x03,0x24,0x04,0xe9,0x02,0x3e,0x40,0x2d,0x91,0x13,0xca,0x00 } },
+{  16, 0xcf70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xe8,0x20,0x3e,0x01 } },
+{  16, 0xcf80, 0, {0x0c,0x00,0x03,0xa1,0x20,0xe8,0x50,0x32,0x10,0x2c,0x8c,0x03,0x21,0x00,0xe8,0x00 } },
+{  16, 0xcf90, 0, {0x32,0x02,0x0f,0x00,0x13,0x20,0x88,0xc8,0x08,0x32,0x00,0x0f,0x8c,0x03,0xca,0x00 } },
+{  16, 0xcfa0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x20,0x8e,0xe3,0x2f,0x90 } },
+{  16, 0xcfb0, 0, {0x0a,0xe0,0x06,0x3b,0x00,0xee,0x04,0x23,0x90,0x08,0xe0,0x02,0x28,0x08,0x8a,0x02 } },
+{  16, 0xcfc0, 0, {0x75,0x90,0x8b,0xa0,0x41,0x58,0x90,0x8e,0x80,0x2a,0x81,0x0b,0xe0,0x03,0x8a,0x10 } },
+{  16, 0xcfd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4e,0x00,0xa3,0x00,0x6c,0x60 } },
+{  16, 0xcfe0, 0, {0x08,0x38,0x1a,0x8e,0x40,0xa0,0x80,0x20,0xcc,0x09,0x30,0x02,0x0c,0x05,0xa3,0x04 } },
+{  16, 0xcff0, 0, {0x28,0xc4,0x0b,0x30,0x02,0x0d,0x01,0x83,0xc0,0x20,0xc0,0x0b,0x30,0x02,0xca,0x00 } },
+{  16, 0xd000, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1e,0x08,0x87,0x00,0x2d,0x62 } },
+{  16, 0xd010, 0, {0x0b,0x70,0x92,0x1c,0x08,0xa0,0x00,0x61,0xc0,0x09,0x60,0x06,0x1c,0x80,0xa7,0x00 } },
+{  16, 0xd020, 0, {0x21,0xc0,0x0b,0x72,0x02,0x58,0x01,0x87,0x88,0x29,0xc0,0x0b,0x60,0x12,0xa8,0x00 } },
+{  16, 0xd030, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xe6,0x80,0x3d,0x60 } },
+{  16, 0xd040, 0, {0x0c,0x78,0x42,0x96,0x00,0xe4,0x80,0xa3,0x60,0x0d,0x78,0x03,0x3f,0x00,0xe3,0x80 } },
+{  16, 0xd050, 0, {0x21,0xe0,0x0f,0x7b,0x03,0x16,0x08,0xc7,0x80,0x31,0xe2,0x4f,0x78,0x43,0xea,0x02 } },
+{  16, 0xd060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0x8c,0x01,0xf8,0x00,0x3c,0x40 } },
+{  16, 0xd070, 0, {0x0e,0xb0,0x02,0xec,0x00,0xf8,0x01,0x3e,0x40,0x4e,0x30,0x33,0xed,0x20,0xdb,0x01 } },
+{  16, 0xd080, 0, {0xbe,0xc0,0x0f,0xb4,0x03,0xec,0x00,0xfb,0x00,0x3e,0xd8,0x0f,0xa0,0x03,0xc2,0x06 } },
+{  16, 0xd090, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xc7,0x84,0x23,0x60 } },
+{  16, 0xd0a0, 0, {0x0c,0x78,0x0b,0xbe,0x00,0xfd,0x80,0x3f,0xe0,0x0f,0xeb,0x03,0x3e,0x00,0xcf,0x80 } },
+{  16, 0xd0b0, 0, {0x3b,0x25,0x0c,0xf8,0x83,0x7e,0x40,0xcd,0x80,0x33,0xe2,0x0b,0xf9,0x03,0x00,0x00 } },
+{  16, 0xd0c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x02,0x87,0x00,0x15,0x48 } },
+{  16, 0xd0d0, 0, {0x08,0x70,0x02,0x14,0x20,0xb6,0x00,0x35,0x9a,0x49,0xc8,0x03,0x9c,0x84,0xa7,0x00 } },
+{  16, 0xd0e0, 0, {0x39,0xd0,0x0a,0x70,0x02,0x1a,0x08,0xa4,0x00,0x21,0xc0,0x09,0x61,0x42,0x2a,0x04 } },
+{  16, 0xd0f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x87,0x00,0x21,0x40 } },
+{  16, 0xd100, 0, {0x08,0x71,0x02,0x94,0x00,0xb5,0x00,0x2d,0x40,0x0b,0xf1,0x22,0x5c,0x02,0x07,0x08 } },
+{  16, 0xd110, 0, {0x2c,0x50,0x08,0x70,0x02,0x50,0x00,0x87,0x00,0x2d,0xc4,0x0b,0x50,0x42,0x00,0x00 } },
+{  16, 0xd120, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x00,0x83,0x02,0x24,0x40 } },
+{  16, 0xd130, 0, {0x18,0x3d,0x0a,0x01,0x00,0xb0,0x58,0x24,0x20,0x09,0x30,0x02,0x8f,0x40,0x83,0xe0 } },
+{  16, 0xd140, 0, {0x2c,0xc1,0x0a,0x30,0x42,0x08,0x00,0xb3,0x01,0x6c,0xc0,0x09,0x08,0x16,0x08,0x04 } },
+{  16, 0xd150, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x8c,0x00,0x8b,0x00,0x32,0x40 } },
+{  16, 0xd160, 0, {0x0c,0x25,0x03,0xa8,0x48,0xf8,0x81,0x3e,0x80,0x0f,0x80,0x63,0x7c,0x00,0xcb,0x80 } },
+{  16, 0xd170, 0, {0x3a,0xc0,0x0c,0xf0,0x03,0x6c,0x00,0xca,0x02,0xbf,0xc0,0x0f,0x98,0x8b,0x2a,0x04 } },
+{  16, 0xd180, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xf9,0x00,0x3e,0x50 } },
+{  16, 0xd190, 0, {0x2f,0xa4,0x0b,0xc8,0x00,0xf0,0x40,0x3e,0xd0,0x0f,0xa0,0x33,0xec,0x20,0xfb,0x04 } },
+{  16, 0xd1a0, 0, {0x7a,0xe0,0x0f,0xb0,0x03,0xed,0x08,0xe9,0x03,0x32,0xc0,0x0d,0x90,0x03,0xe0,0x00 } },
+{  16, 0xd1b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xec,0x40,0xee,0x00,0x3e,0xc0 } },
+{  16, 0xd1c0, 0, {0x0c,0xda,0x03,0x70,0x04,0xcc,0x02,0xb1,0xa0,0x0e,0xf0,0x23,0xec,0x00,0xff,0x00 } },
+{  16, 0xd1d0, 0, {0x37,0x20,0xcd,0xb0,0x73,0xec,0x88,0xfb,0x80,0x3f,0xc0,0x0f,0x30,0x03,0x00,0x44 } },
+{  16, 0xd1e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6e,0x00,0x88,0x80,0x2c,0xe1 } },
+{  16, 0xd1f0, 0, {0x08,0x94,0x0a,0xa9,0x02,0x88,0x40,0x22,0xd0,0x08,0xb9,0x42,0xec,0x04,0xbb,0x00 } },
+{  16, 0xd200, 0, {0x2c,0xd4,0x0d,0xb0,0x02,0xed,0x20,0xbb,0xd0,0x2e,0xc0,0x0b,0xb0,0x02,0xa0,0x40 } },
+{  16, 0xd210, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x24,0x00,0xab,0x80,0x2e,0xf0 } },
+{  16, 0xd220, 0, {0x29,0xa0,0x82,0x6d,0x00,0x88,0x08,0x22,0x04,0x08,0x90,0x42,0xec,0x00,0xbb,0x00 } },
+{  16, 0xd230, 0, {0x2a,0x81,0x08,0xb0,0x02,0xe4,0x09,0xba,0x04,0x2e,0xc1,0x4b,0x98,0x82,0x20,0x00 } },
+{  16, 0xd240, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0x83,0x00,0x2c,0xc0 } },
+{  16, 0xd250, 0, {0x0a,0x21,0x02,0x84,0x10,0x82,0x00,0xe0,0x00,0x18,0x0a,0x12,0xcc,0x00,0xb3,0x00 } },
+{  16, 0xd260, 0, {0x0c,0xc0,0x09,0x30,0x02,0xcc,0x90,0xb0,0x00,0x2c,0xc0,0x0b,0x10,0x02,0x82,0x01 } },
+{  16, 0xd270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x64,0x00,0xeb,0x00,0x3e,0x00 } },
+{  16, 0xd280, 0, {0x2c,0xb4,0x03,0x64,0x08,0x88,0x00,0xb2,0x00,0x0c,0xb2,0x43,0xfc,0x00,0xfb,0x00 } },
+{  16, 0xd290, 0, {0x56,0x00,0x0c,0xf0,0x01,0xe4,0x00,0xfb,0x00,0x3f,0xc0,0x0f,0x80,0x0b,0x00,0x03 } },
+{  16, 0xd2a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf4,0x00,0xff,0x00,0x3f,0x40 } },
+{  16, 0xd2b0, 0, {0x2d,0xf0,0x61,0xf0,0x00,0xf4,0x00,0x27,0x01,0x0d,0xb1,0x11,0xfc,0x00,0xff,0x02 } },
+{  16, 0xd2c0, 0, {0x07,0xc0,0x0f,0xf0,0x03,0xec,0x40,0xff,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0x68,0x06 } },
+{  16, 0xd2d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf6,0x00,0xef,0x90,0x3d,0x4c } },
+{  16, 0xd2e0, 0, {0x2c,0xc0,0x13,0xf4,0x08,0xfd,0x20,0x37,0x4c,0x8e,0x82,0x83,0x74,0x84,0xdc,0xc2 } },
+{  16, 0xd2f0, 0, {0x3f,0xd8,0x0d,0xf2,0x03,0xec,0xc0,0xff,0x81,0x3f,0x00,0x0c,0xf8,0x03,0xf0,0x00 } },
+{  16, 0xd300, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe6,0x00,0x8b,0x24,0x2e,0x5c } },
+{  16, 0xd310, 0, {0x08,0x8d,0x02,0xff,0x48,0xb9,0x90,0x2f,0x54,0x0b,0x84,0x82,0x3e,0x40,0xa0,0x80 } },
+{  16, 0xd320, 0, {0x2e,0xc4,0x0a,0xfc,0x42,0xed,0x80,0xb9,0x80,0x2e,0x60,0x0a,0x98,0x12,0xe0,0x04 } },
+{  16, 0xd330, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe4,0x01,0xa3,0x00,0x28,0x48 } },
+{  16, 0xd340, 0, {0x0a,0x00,0x42,0xc4,0x00,0xb1,0x00,0x2c,0x49,0x0b,0x0a,0x42,0x04,0xa2,0x91,0x21 } },
+{  16, 0xd350, 0, {0x2c,0xc9,0x08,0x31,0x02,0x8c,0xc1,0xa3,0x00,0x2c,0x40,0x08,0x18,0x02,0xa2,0x01 } },
+{  16, 0xd360, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa0,0x20,0x8b,0x82,0x2e,0x44 } },
+{  16, 0xd370, 0, {0x58,0x80,0x02,0xe4,0x00,0xbb,0x10,0x2e,0x40,0x0b,0xa1,0x12,0x0c,0x01,0x89,0x10 } },
+{  16, 0xd380, 0, {0x2e,0xc0,0x0a,0xb0,0x02,0xec,0x01,0xb8,0x80,0x2e,0xe2,0x0a,0xa1,0x02,0xf0,0x04 } },
+{  16, 0xd390, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xeb,0x40,0xeb,0x40,0x3e,0x60 } },
+{  16, 0xd3a0, 0, {0x0e,0x87,0x33,0xe4,0x00,0xb9,0xa1,0x36,0xc0,0x0e,0xa8,0x0b,0x26,0x00,0xda,0xc0 } },
+{  16, 0xd3b0, 0, {0x3e,0xc0,0x8d,0xb0,0x03,0xec,0x00,0xfb,0x85,0x3e,0xe1,0x08,0xb8,0x03,0x90,0x05 } },
+{  16, 0xd3c0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb8,0x00,0xff,0x02,0x2f,0x60 } },
+{  16, 0xd3d0, 0, {0x03,0xe8,0x83,0xfc,0x10,0xfd,0x80,0x1f,0x40,0x1f,0xd0,0x13,0xbe,0x40,0xee,0x04 } },
+{  16, 0xd3e0, 0, {0x3f,0xc0,0x0f,0xf0,0x43,0xfc,0x08,0xfd,0x00,0x3c,0xc0,0x0f,0xd0,0x11,0xf8,0x00 } },
+{  16, 0xd3f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa4,0x00,0xdb,0x00,0xb2,0x40 } },
+{  16, 0xd400, 0, {0x0e,0x94,0x03,0x24,0x00,0xd9,0x00,0xba,0xc0,0x0c,0x20,0x03,0xe4,0x90,0xfb,0x00 } },
+{  16, 0xd410, 0, {0x3a,0xc0,0x0c,0xb0,0x03,0xec,0x01,0xfa,0x00,0x3e,0xd0,0x2c,0x98,0x03,0x90,0x04 } },
+{  16, 0xd420, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x03,0x00,0x8b,0x00,0x22,0x48 } },
+{  16, 0xd430, 0, {0x08,0x84,0x22,0x2c,0x00,0xb9,0x00,0x22,0xc0,0x08,0xa0,0x02,0xed,0x00,0x8b,0xa0 } },
+{  16, 0xd440, 0, {0x21,0xc0,0x08,0xf0,0x02,0xfc,0x00,0xb9,0x80,0x2e,0xc0,0x08,0xa0,0x02,0x32,0x00 } },
+{  16, 0xd450, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x45,0x20,0x93,0x00,0x22,0xf8 } },
+{  16, 0xd460, 0, {0x0b,0x30,0x0a,0x84,0x40,0xb2,0x00,0x20,0x40,0x08,0x10,0x02,0xc4,0x00,0x80,0x80 } },
+{  16, 0xd470, 0, {0x28,0xc0,0x28,0x39,0x02,0x4c,0x00,0xb1,0x00,0x2c,0xc0,0x08,0x30,0x02,0xb8,0x00 } },
+{  16, 0xd480, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x36,0x00,0x9f,0x80,0x21,0x60 } },
+{  16, 0xd490, 0, {0x09,0x38,0x02,0x9e,0x00,0xb2,0xc0,0x20,0x60,0x48,0x48,0x12,0xd6,0xc6,0x86,0xd0 } },
+{  16, 0xd4a0, 0, {0x21,0xe0,0x08,0x78,0x00,0xde,0x80,0xb7,0x82,0x2d,0xe0,0x08,0xf8,0x02,0x08,0x00 } },
+{  16, 0xd4b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x20,0xd3,0x10,0x30,0xc8 } },
+{  16, 0xd4c0, 0, {0x0f,0x30,0x03,0x84,0x00,0xf1,0x00,0x30,0x40,0x24,0x19,0x03,0xe4,0xc0,0xe0,0x40 } },
+{  16, 0xd4d0, 0, {0x3a,0xc0,0x0c,0x32,0x03,0xce,0x80,0xb1,0x28,0x3c,0xc0,0x0c,0x30,0x13,0x92,0x02 } },
+{  16, 0xd4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0x9c,0x00,0xe6,0x00,0x7f,0xc0 } },
+{  16, 0xd4f0, 0, {0x0e,0xf0,0x23,0x74,0x40,0xff,0x10,0x3f,0x40,0x4f,0xd0,0x03,0xfc,0xd2,0xce,0x04 } },
+{  16, 0xd500, 0, {0x3f,0xc0,0x0f,0xf4,0x03,0xfc,0x00,0xfe,0x00,0x3f,0xc0,0x0f,0x71,0x03,0xd0,0x12 } },
+{  16, 0xd510, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xee,0x00,0xcb,0x00,0x16,0xc0 } },
+{  16, 0xd520, 0, {0x0d,0x80,0x03,0x27,0x20,0xcb,0x00,0x3e,0xc2,0x0a,0xb0,0x53,0xe4,0x28,0xc1,0x81 } },
+{  16, 0xd530, 0, {0x32,0xc1,0x0e,0xb9,0x03,0x2c,0x00,0xf1,0x80,0x35,0xe0,0x0c,0xb8,0x03,0x2a,0x04 } },
+{  16, 0xd540, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x02,0x87,0x10,0x2d,0x40 } },
+{  16, 0xd550, 0, {0x08,0x70,0x03,0x5c,0x00,0xa7,0x00,0x2d,0x40,0x28,0x70,0x02,0xd4,0x04,0x87,0x04 } },
+{  16, 0xd560, 0, {0xa1,0xd0,0x0b,0x72,0x02,0x1d,0x00,0xf7,0x00,0x21,0xc0,0x0d,0x50,0x02,0x12,0x04 } },
+{  16, 0xd570, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0x85,0x80,0x25,0xe0 } },
+{  16, 0xd580, 0, {0x09,0x78,0x02,0x37,0x03,0x87,0x80,0x2f,0xe0,0x08,0x78,0x12,0xc6,0x10,0x8d,0x80 } },
+{  16, 0xd590, 0, {0x25,0xe8,0x0b,0x38,0x02,0x1e,0x80,0xbc,0x84,0x25,0xe0,0x08,0x58,0x02,0x70,0x00 } },
+{  16, 0xd5a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcd,0x80,0x83,0x88,0x2c,0xc0 } },
+{  16, 0xd5b0, 0, {0x08,0x3c,0x02,0x4e,0x01,0xa3,0xd2,0x2e,0xc4,0x08,0xb1,0x02,0xcc,0x00,0x83,0x80 } },
+{  16, 0xd5c0, 0, {0x24,0xc1,0x0b,0x30,0x02,0x0c,0x00,0xb3,0x40,0xa0,0xd2,0x09,0x30,0x12,0x52,0x00 } },
+{  16, 0xd5d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xba,0x00,0xca,0xc0,0x36,0x80 } },
+{  16, 0xd5e0, 0, {0x0d,0x67,0x13,0x28,0x00,0xce,0x00,0x3e,0xa0,0x0c,0xed,0x03,0xe8,0x00,0xce,0xe0 } },
+{  16, 0xd5f0, 0, {0x36,0x80,0x1e,0xa0,0x0b,0x28,0x04,0xfe,0x00,0xb7,0xb2,0x0c,0xe0,0x0b,0x7a,0x00 } },
+{  16, 0xd600, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x40,0xf8,0x10,0x2e,0x10 } },
+{  16, 0xd610, 0, {0x0f,0x80,0x03,0xe0,0x01,0xd8,0x0a,0x3e,0x00,0x0f,0x80,0x03,0xc0,0x02,0xf8,0x08 } },
+{  16, 0xd620, 0, {0x3a,0x00,0x0f,0x80,0x03,0xe0,0x10,0xe8,0x20,0xbe,0x00,0x0f,0x80,0x13,0x92,0x00 } },
+{  16, 0xd630, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe5,0x00,0xfb,0x00,0x3e,0x40 } },
+{  16, 0xd640, 0, {0x0c,0x91,0x03,0x26,0x00,0x61,0x80,0x32,0x40,0x0c,0x90,0x03,0x24,0x00,0xc9,0x00 } },
+{  16, 0xd650, 0, {0x1e,0x40,0x0c,0x9c,0x03,0xe4,0x01,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xc2,0x00 } },
+{  16, 0xd660, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x67,0x00,0xb9,0x00,0x2c,0x40 } },
+{  16, 0xd670, 0, {0x00,0x9c,0x02,0xa6,0x00,0x79,0x00,0x22,0x40,0x28,0x90,0x02,0x24,0x00,0x89,0x00 } },
+{  16, 0xd680, 0, {0x2c,0x44,0x08,0x98,0x02,0xe4,0x00,0xb9,0x80,0x2e,0x40,0x0b,0x90,0x02,0xe0,0x01 } },
+{  16, 0xd690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xbb,0x00,0x26,0x50 } },
+{  16, 0xd6a0, 0, {0x28,0x90,0x82,0x24,0x84,0x99,0x20,0x22,0x40,0x49,0x90,0x02,0x24,0x00,0x89,0x00 } },
+{  16, 0xd6b0, 0, {0x2e,0x40,0x08,0x90,0x02,0xe4,0x00,0xb9,0x60,0x2e,0x40,0x0b,0x90,0x02,0xc6,0x04 } },
+{  16, 0xd6c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x06,0x00,0xb1,0x00,0x2e,0x48 } },
+{  16, 0xd6d0, 0, {0x08,0x12,0x02,0x84,0x80,0xb1,0x20,0xa0,0x48,0x09,0x12,0x0a,0x04,0x80,0x81,0x00 } },
+{  16, 0xd6e0, 0, {0x2c,0x48,0x28,0x12,0x42,0xc4,0x88,0x31,0x00,0x2c,0x40,0x0b,0x18,0x02,0xc2,0x01 } },
+{  16, 0xd6f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xf8,0x50,0x36,0x14 } },
+{  16, 0xd700, 0, {0x0c,0x80,0x03,0x20,0x00,0xe8,0x00,0x32,0x14,0x0c,0x85,0x03,0x21,0x40,0xc8,0x50 } },
+{  16, 0xd710, 0, {0x3e,0x14,0x0c,0x80,0x03,0xe1,0x40,0x38,0x00,0x3e,0x00,0x8f,0x80,0x03,0xee,0x03 } },
+{  16, 0xd720, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xd4,0x00,0xfb,0x04,0x3d,0x44 } },
+{  16, 0xd730, 0, {0x0f,0x51,0x23,0xd4,0x48,0xed,0x10,0x3d,0x44,0x4e,0xd1,0x23,0xf4,0x42,0xfd,0x00 } },
+{  16, 0xd740, 0, {0x3e,0x44,0x8f,0x91,0x03,0xe4,0x58,0xfd,0x00,0x3f,0x50,0x0f,0x50,0x03,0xe6,0x06 } },
+{  16, 0xd750, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf4,0x00,0xf9,0x00,0x3d,0x40 } },
+{  16, 0xd760, 0, {0x0c,0xd0,0x03,0xf4,0x00,0xdd,0x02,0x3e,0x40,0x0c,0x90,0x03,0xe4,0x40,0xc9,0x10 } },
+{  16, 0xd770, 0, {0x37,0x40,0x07,0xd0,0x07,0x24,0x00,0xe5,0x00,0x2f,0x6a,0x0f,0x70,0x03,0x06,0x00 } },
+{  16, 0xd780, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x00,0xb8,0x00,0x3a,0x00 } },
+{  16, 0xd790, 0, {0x80,0x80,0x02,0xe0,0x00,0x88,0x00,0x2e,0x00,0x0a,0x80,0x53,0xa2,0x80,0x2c,0xa0 } },
+{  16, 0xd7a0, 0, {0x22,0x00,0x0b,0x80,0x0a,0x20,0x00,0xb8,0x00,0x2e,0x10,0x09,0x80,0x03,0x0e,0x04 } },
+{  16, 0xd7b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x6c,0x40 } },
+{  16, 0xd7c0, 0, {0x2a,0x10,0x02,0x84,0x01,0x81,0x80,0x2e,0x40,0x09,0x10,0x02,0xf4,0x00,0x8d,0x04 } },
+{  16, 0xd7d0, 0, {0x20,0x40,0x0b,0x10,0x02,0x84,0x00,0xb1,0x00,0x2c,0x40,0x0b,0x98,0x02,0x42,0x01 } },
+{  16, 0xd7e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x20,0xb9,0x00,0x2a,0x40 } },
+{  16, 0xd7f0, 0, {0x88,0xb4,0x02,0xe6,0x01,0xa9,0x20,0x2e,0x48,0x0a,0x90,0x00,0xa4,0x40,0xad,0x40 } },
+{  16, 0xd800, 0, {0x22,0x40,0x0b,0x90,0x12,0xa4,0x04,0xb9,0x01,0x2e,0x41,0x0b,0x90,0x02,0x06,0x04 } },
+{  16, 0xd810, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0xc0,0x3e,0x60 } },
+{  16, 0xd820, 0, {0x0c,0x94,0x13,0xa6,0x02,0xd9,0x42,0x1c,0x60,0x0c,0x9e,0x01,0xc6,0x04,0xc1,0x00 } },
+{  16, 0xd830, 0, {0xb2,0x40,0x1f,0x90,0x02,0xa4,0x00,0xe9,0x08,0x3e,0x68,0x4f,0x98,0x0b,0x68,0x04 } },
+{  16, 0xd840, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa6,0x40,0xf9,0x20,0x38,0x70 } },
+{  16, 0xd850, 0, {0x0f,0x91,0x03,0xe4,0x00,0xd9,0x80,0x3e,0x40,0x0f,0x9c,0x13,0xa4,0x00,0xf9,0x00 } },
+{  16, 0xd860, 0, {0x3e,0x40,0x0f,0x10,0x03,0x64,0x10,0xf9,0x0a,0x3e,0x50,0x0d,0x9a,0x03,0xca,0x00 } },
+{  16, 0xd870, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xd8,0x04,0x3e,0x00 } },
+{  16, 0xd880, 0, {0x0c,0x81,0x13,0xc0,0x02,0xd8,0x20,0x3e,0x00,0x2d,0x84,0x03,0xe0,0x00,0xcc,0x08 } },
+{  16, 0xd890, 0, {0x3a,0x00,0x0f,0x80,0x43,0xe0,0x00,0xf8,0x41,0x32,0x00,0x07,0x81,0x8b,0x0a,0x04 } },
+{  16, 0xd8a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x3a,0x60,0x8a,0x00,0x2f,0xa8 } },
+{  16, 0xd8b0, 0, {0x0a,0xe0,0x22,0xe8,0x02,0x7e,0x48,0x2e,0x80,0x08,0xa0,0x42,0xe8,0x04,0x8e,0x00 } },
+{  16, 0xd8c0, 0, {0x23,0xa8,0x0b,0xa8,0x82,0xe8,0x00,0xee,0x00,0xa2,0x80,0x4b,0x60,0x02,0x0a,0x00 } },
+{  16, 0xd8d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0x00,0x6c,0xc0 } },
+{  16, 0xd8e0, 0, {0x08,0x30,0x02,0xcc,0x00,0x13,0x81,0x2c,0xc0,0x08,0x30,0x02,0xce,0x40,0x82,0x40 } },
+{  16, 0xd8f0, 0, {0x28,0xe0,0x0b,0x38,0x02,0xcc,0x00,0xb3,0x10,0x24,0xc0,0x8b,0x38,0x02,0x0a,0x00 } },
+{  16, 0xd900, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1e,0x00,0x87,0x20,0x2f,0xc0 } },
+{  16, 0xd910, 0, {0x0a,0x70,0x02,0xdc,0x0a,0xb6,0x00,0x2c,0xc8,0x88,0x72,0x06,0xd8,0x00,0x86,0x00 } },
+{  16, 0xd920, 0, {0x21,0xc0,0x0b,0x70,0x02,0xdc,0x84,0xaf,0x80,0xa5,0xc0,0x0b,0xd0,0x02,0x28,0x00 } },
+{  16, 0xd930, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xd7,0x80,0x3d,0xa0 } },
+{  16, 0xd940, 0, {0x1c,0x78,0x13,0xd6,0x02,0xd7,0x80,0x3d,0xec,0x08,0x7e,0x23,0xfe,0x00,0xce,0x80 } },
+{  16, 0xd950, 0, {0x39,0x60,0x0f,0x78,0x03,0xdf,0x00,0xf6,0x80,0x75,0xe0,0x0f,0x78,0x03,0x2a,0x02 } },
+{  16, 0xd960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0x8c,0x00,0xfb,0x10,0x3e,0x80 } },
+{  16, 0xd970, 0, {0x1f,0xa0,0x21,0xcc,0x00,0xfa,0x00,0x3e,0xc0,0x0e,0xb0,0x03,0xe8,0x02,0xfa,0x00 } },
+{  16, 0xd980, 0, {0x3e,0x40,0x0f,0xb0,0x13,0xec,0x00,0xea,0x01,0x3a,0xc0,0x0f,0x90,0x03,0xc2,0x06 } },
+{  16, 0xd990, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfc,0x00,0xff,0x80,0x3f,0x60 } },
+{  16, 0xd9a0, 0, {0x08,0x99,0x07,0x7e,0x00,0xdd,0x80,0x3f,0xe2,0x0c,0xf8,0x03,0xf6,0x02,0xdf,0x80 } },
+{  16, 0xd9b0, 0, {0xb3,0xe0,0x0c,0xf8,0x03,0x3e,0x41,0xcc,0x80,0x33,0xe4,0x0f,0xf8,0x03,0xc0,0x00 } },
+{  16, 0xd9c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x40,0xb7,0x00,0x2d,0xc0 } },
+{  16, 0xd9d0, 0, {0x0d,0x5a,0x22,0xdc,0x80,0x75,0x00,0x2d,0xc0,0x08,0x71,0x02,0xf0,0x20,0x87,0x00 } },
+{  16, 0xd9e0, 0, {0x21,0xc0,0x0a,0x70,0x02,0x1c,0x00,0xd4,0x28,0x21,0xc0,0x0b,0x72,0x02,0xea,0x04 } },
+{  16, 0xd9f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x40,0xb7,0x00,0x2d,0x00 } },
+{  16, 0xda00, 0, {0x08,0x72,0x22,0xf4,0x00,0x87,0x00,0x2d,0xc2,0x08,0x70,0x02,0xd4,0x00,0x87,0x80 } },
+{  16, 0xda10, 0, {0x25,0x40,0x09,0x30,0x02,0x5c,0x01,0xad,0x00,0x29,0xd0,0x4b,0x70,0x02,0xc0,0x00 } },
+{  16, 0xda20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x00,0xbb,0xc8,0x2c,0xa0 } },
+{  16, 0xda30, 0, {0x09,0x20,0x02,0xce,0x00,0xa3,0x00,0x2c,0xe0,0xa8,0x3d,0x42,0xc2,0x00,0x8b,0x80 } },
+{  16, 0xda40, 0, {0x24,0x40,0x0b,0x30,0x0a,0x6c,0x08,0xa3,0x40,0xa8,0xe0,0x0b,0x34,0x02,0xc8,0x04 } },
+{  16, 0xda50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xad,0x00,0xff,0x48,0x3c,0x28 } },
+{  16, 0xda60, 0, {0x0c,0xa9,0x23,0x6c,0x80,0x8b,0x00,0x3f,0xc0,0x0c,0xfc,0x03,0xec,0x00,0xd8,0x80 } },
+{  16, 0xda70, 0, {0x34,0x40,0x0d,0x30,0x03,0x7c,0x02,0xa3,0x40,0x38,0x68,0x0f,0x24,0x03,0xea,0x04 } },
+{  16, 0xda80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xed,0x88,0xfb,0x00,0x3e,0x50 } },
+{  16, 0xda90, 0, {0x0f,0xa1,0x03,0xec,0x04,0x3a,0xc0,0x3e,0xc0,0x0f,0xb0,0x83,0xe8,0x02,0xf8,0x10 } },
+{  16, 0xdaa0, 0, {0x3a,0x41,0x0e,0x90,0x03,0xac,0x00,0x9b,0x08,0xb6,0x40,0x0f,0x81,0x03,0xe0,0x00 } },
+{  16, 0xdab0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x00,0xb3,0x20 } },
+{  16, 0xdac0, 0, {0x0c,0x50,0x13,0x1c,0x09,0xcd,0x83,0x33,0xc0,0x83,0x70,0x00,0x3c,0x00,0xdc,0x10 } },
+{  16, 0xdad0, 0, {0x32,0x60,0x0e,0xf1,0x43,0x2c,0x00,0xce,0x04,0x3b,0x70,0x0c,0xf0,0x83,0x00,0x44 } },
+{  16, 0xdae0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x67,0x80,0xbb,0x01,0x62,0x21 } },
+{  16, 0xdaf0, 0, {0x8a,0x89,0x20,0x2c,0x00,0x80,0xe0,0x22,0xc0,0x0b,0xb0,0x03,0xd8,0x10,0x8c,0x04 } },
+{  16, 0xdb00, 0, {0x22,0x40,0x05,0x90,0x02,0xac,0x00,0xd8,0x80,0x36,0x40,0x0a,0x90,0x02,0x20,0x40 } },
+{  16, 0xdb10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x26,0x00,0xbb,0x00,0x22,0x06 } },
+{  16, 0xdb20, 0, {0x08,0x80,0x02,0x2e,0x00,0x88,0x20,0x22,0xc0,0x09,0xb0,0x02,0xa4,0x00,0x99,0x00 } },
+{  16, 0xdb30, 0, {0x62,0xc4,0x08,0xb0,0x06,0x2c,0x00,0x88,0x80,0x22,0x41,0x08,0xa0,0x02,0x20,0x00 } },
+{  16, 0xdb40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0xb3,0x00,0x20,0x40 } },
+{  16, 0xdb50, 0, {0x0a,0x00,0x82,0x0c,0x00,0x80,0x00,0x20,0xc0,0x0b,0x30,0x22,0xa0,0x00,0x81,0x00 } },
+{  16, 0xdb60, 0, {0xa0,0xc0,0x09,0x30,0x02,0x8c,0x00,0x90,0x00,0x24,0x40,0x0a,0x28,0x02,0x02,0x01 } },
+{  16, 0xdb70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xfb,0x02,0x20,0x00 } },
+{  16, 0xdb80, 0, {0x2c,0x92,0x03,0x2c,0x02,0x88,0x00,0x31,0xc0,0x0b,0xb5,0x02,0xa4,0x00,0xd1,0x04 } },
+{  16, 0xdb90, 0, {0x32,0x40,0x0e,0x90,0x03,0x2c,0x40,0xc9,0x00,0x3a,0x40,0x8c,0xa0,0x03,0x00,0x03 } },
+{  16, 0xdba0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf4,0x00,0xff,0x00,0x2f,0x00 } },
+{  16, 0xdbb0, 0, {0x0f,0xc0,0x03,0xdc,0x00,0xfc,0x00,0x3f,0xc1,0x0f,0xf0,0x43,0xf0,0x00,0xfd,0x00 } },
+{  16, 0xdbc0, 0, {0x3f,0x40,0x4f,0xd0,0x03,0xfc,0x00,0xf5,0x00,0x3f,0x40,0x0f,0xe0,0x03,0xe8,0x06 } },
+{  16, 0xdbd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xd8,0x80,0xcc,0x00,0xb7,0x04 } },
+{  16, 0xdbe0, 0, {0x4e,0xe1,0x03,0x3c,0x20,0xdf,0x10,0x31,0x80,0x06,0xf0,0x03,0x7f,0x00,0xff,0xc0 } },
+{  16, 0xdbf0, 0, {0x3b,0xc0,0x0e,0xf2,0x03,0x5e,0x00,0xef,0x10,0x33,0xd0,0x2c,0xf2,0x03,0x30,0x00 } },
+{  16, 0xdc00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x10,0xe9,0x00,0x88,0xc6,0x20,0x5c } },
+{  16, 0xdc10, 0, {0x08,0xa4,0x57,0x65,0x00,0x8f,0x52,0x2a,0xf0,0x09,0xfc,0x02,0x04,0x00,0xbb,0x00 } },
+{  16, 0xdc20, 0, {0x2d,0xd9,0x09,0x74,0x83,0x64,0x28,0x83,0x44,0x22,0x84,0x88,0x06,0x82,0x30,0x04 } },
+{  16, 0xdc30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0xc9,0x00,0x80,0x10,0x20,0x08 } },
+{  16, 0xdc40, 0, {0x08,0x31,0x12,0x04,0xb2,0xa3,0x00,0x20,0x84,0x1b,0x34,0x02,0x0c,0x80,0xb3,0x20 } },
+{  16, 0xdc50, 0, {0x2c,0xc7,0x09,0x36,0x02,0x8c,0x80,0x93,0x40,0xac,0xc8,0x08,0x31,0x28,0x32,0x01 } },
+{  16, 0xdc60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa9,0x00,0x88,0x00,0xa2,0x50 } },
+{  16, 0xdc70, 0, {0x08,0x35,0x02,0x24,0x00,0x8b,0x04,0x2e,0xc1,0x09,0xb0,0x02,0x24,0x94,0xbb,0x00 } },
+{  16, 0xdc80, 0, {0x2e,0xc0,0x0b,0xb0,0x02,0xcc,0x60,0x8b,0x00,0x2e,0x80,0x08,0x80,0x00,0x30,0x04 } },
+{  16, 0xdc90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xe7,0x02,0xcb,0x18,0xb2,0x80 } },
+{  16, 0xdca0, 0, {0x2c,0xac,0x0a,0x2e,0x08,0xeb,0x00,0x32,0x12,0x4e,0xb0,0x03,0x2b,0x80,0xfb,0x00 } },
+{  16, 0xdcb0, 0, {0x3a,0xc0,0x0a,0xb0,0x03,0xab,0x08,0xeb,0x04,0x2e,0x48,0x0c,0xb8,0x83,0x00,0x04 } },
+{  16, 0xdcc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb6,0x80,0xff,0x80,0x39,0xca } },
+{  16, 0xdcd0, 0, {0x0d,0xe8,0x03,0xd6,0x40,0xe7,0x04,0x3b,0x66,0x4e,0x70,0x03,0xb8,0x00,0xff,0x01 } },
+{  16, 0xdce0, 0, {0x3f,0xc0,0x6c,0xf0,0x03,0x70,0x06,0xe7,0x00,0x31,0x04,0x0f,0xc1,0x43,0xf8,0x00 } },
+{  16, 0xdcf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x85,0x00,0xcb,0x40,0x32,0x90 } },
+{  16, 0xdd00, 0, {0x2f,0xb0,0x0b,0x64,0x80,0xfb,0x08,0xba,0x10,0x0d,0xb0,0xa7,0x2d,0x00,0xfb,0x04 } },
+{  16, 0xdd10, 0, {0x3e,0xc0,0x8e,0xb0,0x03,0x6d,0x00,0xdb,0x01,0x32,0x40,0x8c,0x33,0x03,0x90,0x04 } },
+{  16, 0xdd20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0x24,0x00,0x83,0xe0,0xa2,0xd0 } },
+{  16, 0xdd30, 0, {0x40,0xb0,0x02,0x25,0x04,0xbf,0x80,0xa0,0x50,0x08,0xf8,0x02,0x20,0x00,0x8b,0x02 } },
+{  16, 0xdd40, 0, {0x2f,0xd0,0x08,0xf0,0x02,0x24,0x00,0x8f,0x80,0x36,0x01,0x08,0x84,0x42,0x36,0x00 } },
+{  16, 0xdd50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0x44,0x00,0x83,0x48,0x20,0xc4 } },
+{  16, 0xdd60, 0, {0x09,0x00,0x02,0x46,0x00,0xb3,0x01,0xa8,0x90,0x19,0x30,0x12,0x8c,0x00,0xa3,0x04 } },
+{  16, 0xdd70, 0, {0x2e,0xe2,0x0a,0xb0,0x02,0x0c,0x00,0x83,0x49,0x28,0xc0,0x09,0x3c,0x02,0x38,0x00 } },
+{  16, 0xdd80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x01,0x36,0x04,0x83,0x80,0x21,0xe1 } },
+{  16, 0xdd90, 0, {0x08,0x38,0x12,0x1e,0x28,0xb3,0x98,0x21,0xa0,0x19,0x38,0x82,0x96,0x00,0x87,0x83 } },
+{  16, 0xdda0, 0, {0x2d,0xe2,0x08,0x78,0x22,0x36,0x8c,0x87,0x80,0x2d,0xe0,0x09,0x79,0x02,0x3e,0x00 } },
+{  16, 0xddb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x04,0x00,0xc3,0x30,0x30,0xc8 } },
+{  16, 0xddc0, 0, {0x4d,0x00,0x0b,0x4c,0x80,0xf3,0x12,0x38,0xc0,0x0d,0x3a,0x02,0x8c,0x80,0xf3,0x00 } },
+{  16, 0xddd0, 0, {0x3c,0xc0,0x0e,0x30,0x0b,0x0e,0x00,0xc3,0x0c,0x3a,0xc0,0x0d,0x30,0x03,0x12,0x02 } },
+{  16, 0xdde0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb4,0x06,0xff,0x10,0x3f,0xc0 } },
+{  16, 0xddf0, 0, {0x0f,0xb0,0x13,0xbc,0x00,0xff,0x10,0x7f,0xc0,0x0e,0xf1,0xa3,0x7c,0x00,0xff,0x12 } },
+{  16, 0xde00, 0, {0x3f,0xc2,0x0f,0xf5,0x23,0xbc,0x41,0xef,0x18,0x37,0x80,0xae,0xc0,0x03,0x50,0x06 } },
+{  16, 0xde10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xdb,0x00,0x3e,0xda } },
+{  16, 0xde20, 0, {0x0c,0x80,0x03,0x66,0x10,0x8b,0x00,0x32,0x80,0x8c,0xb6,0x03,0x4a,0x00,0x4b,0x80 } },
+{  16, 0xde30, 0, {0x32,0xc8,0x0c,0xb4,0x03,0x0a,0x10,0xdb,0x00,0x3e,0xc1,0x0c,0xb0,0x43,0x2a,0x00 } },
+{  16, 0xde40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x11,0xb4,0x00,0x87,0x04,0x2c,0xc0 } },
+{  16, 0xde50, 0, {0x0d,0x70,0x03,0x1c,0x08,0x87,0x48,0x20,0x81,0x0d,0x72,0x82,0x5c,0x00,0xd7,0x00 } },
+{  16, 0xde60, 0, {0x21,0xcc,0x28,0xf0,0x02,0x1c,0x10,0x87,0x20,0x2c,0x00,0x08,0x40,0x0a,0x32,0x04 } },
+{  16, 0xde70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x96,0x00,0xb7,0x81,0x2d,0xe0 } },
+{  16, 0xde80, 0, {0x08,0x48,0x02,0x0e,0x04,0x87,0x80,0x21,0xe0,0x08,0x78,0x02,0x3e,0x01,0x87,0x80 } },
+{  16, 0xde90, 0, {0x21,0xe0,0x18,0x79,0x02,0x3a,0x01,0x97,0xa0,0x2d,0x60,0x08,0x38,0x02,0x20,0x00 } },
+{  16, 0xdea0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xc6,0x00,0xa3,0xc6,0x2c,0xc0 } },
+{  16, 0xdeb0, 0, {0x09,0x30,0x02,0x0c,0x01,0x83,0x00,0x20,0xe0,0x09,0x30,0x02,0x4e,0x00,0x93,0x00 } },
+{  16, 0xdec0, 0, {0x20,0xc0,0x49,0x30,0x22,0x0f,0x64,0x83,0x02,0x6c,0xd4,0x28,0x30,0x02,0x12,0x04 } },
+{  16, 0xded0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x11,0xab,0x80,0xfa,0xe0,0x3c,0x88 } },
+{  16, 0xdee0, 0, {0x0c,0xe0,0x02,0x28,0x02,0xca,0x00,0xb3,0xa9,0x0c,0xa0,0x03,0x3b,0x10,0xca,0x00 } },
+{  16, 0xdef0, 0, {0xa2,0x80,0x0c,0xa0,0x0b,0x38,0x00,0xda,0x00,0x3f,0xb0,0x0c,0xe6,0x03,0x3a,0x04 } },
+{  16, 0xdf00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xc0,0x20,0x98,0x08,0x3e,0x00 } },
+{  16, 0xdf10, 0, {0x0f,0x80,0x0b,0xe1,0x00,0xf8,0x01,0x3c,0x10,0x4f,0x00,0x03,0xa0,0x40,0xf8,0x00 } },
+{  16, 0xdf20, 0, {0x3e,0x10,0x0e,0x80,0x03,0xe0,0x00,0xf8,0x00,0x3c,0x02,0x2f,0x04,0x93,0xd2,0x00 } },
+{  16, 0xdf30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xc1,0xc1,0x32,0x40 } },
+{  16, 0xdf40, 0, {0x0c,0x98,0x03,0x26,0x40,0xf9,0x00,0x32,0x40,0x0c,0x98,0x03,0x24,0x24,0xf9,0x00 } },
+{  16, 0xdf50, 0, {0x3c,0x60,0x0c,0x10,0x03,0xa4,0x00,0xf9,0x82,0x32,0x40,0x0c,0x90,0x03,0x02,0x04 } },
+{  16, 0xdf60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x50 } },
+{  16, 0xdf70, 0, {0x0d,0x98,0x02,0x25,0x80,0xb9,0x00,0x22,0x52,0x0d,0x9c,0x02,0x24,0x00,0xb9,0x00 } },
+{  16, 0xdf80, 0, {0x2e,0x60,0x08,0x90,0x42,0x24,0x00,0xb9,0x40,0x36,0x40,0x08,0x90,0x0a,0x20,0x00 } },
+{  16, 0xdf90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x8d,0x00,0x23,0x40 } },
+{  16, 0xdfa0, 0, {0x08,0x12,0x02,0x24,0x00,0xa1,0x10,0xa2,0x60,0x08,0x92,0x8a,0x24,0x00,0xb9,0x01 } },
+{  16, 0xdfb0, 0, {0x2e,0x46,0x08,0x90,0x02,0xa4,0x00,0xb1,0x50,0x22,0x40,0x28,0x90,0x82,0x06,0x00 } },
+{  16, 0xdfc0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x84,0x85,0x20,0xa1,0xd8 } },
+{  16, 0xdfd0, 0, {0x09,0x10,0x02,0x04,0x80,0xb3,0x20,0x20,0x40,0x29,0x12,0x06,0x04,0x00,0xb1,0x01 } },
+{  16, 0xdfe0, 0, {0x2c,0x48,0x28,0x12,0x02,0x04,0x00,0xb1,0x20,0x24,0x48,0x08,0x12,0x02,0x02,0x01 } },
+{  16, 0xdff0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x42,0x8a,0x00,0xb3,0x00 } },
+{  16, 0xe000, 0, {0x0c,0x05,0x03,0x21,0x40,0xe0,0x50,0xb2,0x00,0x2c,0x80,0x02,0x21,0x40,0xf0,0x50 } },
+{  16, 0xe010, 0, {0x3c,0x14,0x0c,0x85,0x13,0xa1,0x50,0xf8,0x50,0x32,0x14,0x0c,0x85,0x23,0x2e,0x03 } },
+{  16, 0xe020, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x40,0xf9,0x10,0x3e,0x44 } },
+{  16, 0xe030, 0, {0x0f,0xd4,0x0b,0xf4,0x44,0xf9,0x10,0x3f,0x50,0x4f,0x11,0x03,0xf4,0x00,0xf9,0x00 } },
+{  16, 0xe040, 0, {0x3e,0x44,0x0f,0x91,0x53,0xf4,0x14,0xf9,0x10,0x3f,0x44,0x0f,0xd1,0x03,0xe6,0x02 } },
+{  16, 0xe050, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x05,0xe6,0xa0,0xdd,0x88,0xb3,0x66 } },
+{  16, 0xe060, 0, {0x0c,0xdc,0x83,0x36,0x88,0xbd,0xa0,0x37,0x6a,0x0c,0xda,0x0b,0x25,0x02,0xc9,0x40 } },
+{  16, 0xe070, 0, {0x3f,0x78,0x4f,0x98,0xb3,0xe5,0x04,0xcd,0xa0,0x72,0x78,0x0c,0xd8,0x8b,0x26,0x14 } },
+{  16, 0xe080, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe3,0x00,0x88,0x42,0x22,0x31 } },
+{  16, 0xe090, 0, {0x08,0x0a,0x02,0x22,0xa0,0xb8,0xf9,0x22,0x10,0x0d,0x84,0x12,0x6a,0x80,0x88,0x80 } },
+{  16, 0xe0a0, 0, {0x2e,0x20,0x0b,0x08,0x02,0xe2,0x80,0xa8,0xa8,0xa2,0x38,0x48,0xa8,0x02,0x0e,0x00 } },
+{  16, 0xe0b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0xa2,0x81,0x00,0x20,0x48 } },
+{  16, 0xe0c0, 0, {0x08,0x12,0x42,0x45,0x00,0xb1,0x00,0x24,0x40,0x09,0x14,0x02,0x24,0x00,0x81,0x20 } },
+{  16, 0xe0d0, 0, {0x2c,0x58,0x0b,0x10,0x82,0xc4,0x04,0x91,0x40,0x64,0x6c,0x08,0x30,0x82,0x12,0x05 } },
+{  16, 0xe0e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x00,0x89,0x00,0x22,0x41 } },
+{  16, 0xe0f0, 0, {0x08,0x90,0x8a,0x64,0x80,0xb9,0x00,0x22,0x50,0x09,0x90,0x06,0x64,0x08,0x99,0x00 } },
+{  16, 0xe100, 0, {0x2e,0x40,0x0b,0x90,0x06,0xc4,0x01,0xb9,0x02,0x26,0x61,0x88,0x90,0x02,0x06,0x04 } },
+{  16, 0xe110, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x00,0x22,0x40 } },
+{  16, 0xe120, 0, {0x2c,0x94,0x23,0x64,0x00,0xb9,0x00,0x36,0x40,0x09,0x90,0x13,0x05,0x00,0xc9,0x00 } },
+{  16, 0xe130, 0, {0x3e,0x40,0x4f,0x90,0x13,0xe5,0xc0,0xd9,0x00,0x26,0x40,0x2c,0x94,0x03,0x28,0x00 } },
+{  16, 0xe140, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x01,0xa4,0x02,0xe9,0x08,0x3c,0x40 } },
+{  16, 0xe150, 0, {0x0f,0x90,0x0b,0xa4,0x00,0xf1,0x00,0x3e,0x41,0x0f,0x90,0x43,0xa4,0x88,0xe9,0x04 } },
+{  16, 0xe160, 0, {0x3e,0x40,0x0f,0x90,0x03,0xe6,0x00,0xe1,0x00,0x3a,0x40,0x9f,0x92,0x63,0xda,0x00 } },
+{  16, 0xe170, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0x80,0x10,0xe0,0x01,0x32,0x00 } },
+{  16, 0xe180, 0, {0x8f,0x80,0x03,0x20,0x00,0xd8,0x08,0x30,0x01,0x8c,0x00,0x03,0xe1,0x02,0xc8,0x04 } },
+{  16, 0xe190, 0, {0x3e,0x00,0x0c,0x80,0x0b,0x21,0x00,0xc8,0x00,0x78,0x00,0x0f,0x86,0x03,0x0a,0x00 } },
+{  16, 0xe1a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8e,0x40,0x2b,0x82 } },
+{  16, 0xe1b0, 0, {0x0b,0xa0,0x02,0x3a,0x00,0x8e,0x80,0x23,0x82,0x08,0xe2,0x02,0x28,0x10,0x8a,0x00 } },
+{  16, 0xe1c0, 0, {0x2f,0x98,0x28,0xa0,0x12,0x28,0x00,0x8e,0x20,0x2e,0x80,0x4b,0xe4,0x02,0x0a,0x00 } },
+{  16, 0xe1d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x02,0xa2,0x40,0x20,0x80 } },
+{  16, 0xe1e0, 0, {0x0b,0xb0,0x02,0x4e,0x40,0x93,0xc0,0xa0,0x20,0x08,0x36,0x02,0x8c,0x00,0x93,0x00 } },
+{  16, 0xe1f0, 0, {0x2c,0xe2,0x08,0x30,0x06,0x4c,0x12,0x93,0x08,0x28,0xc0,0x0b,0xb0,0x02,0x0a,0x00 } },
+{  16, 0xe200, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x08,0x82,0x40,0x29,0x40 } },
+{  16, 0xe210, 0, {0x0b,0x70,0x02,0x5e,0x08,0x84,0x08,0x23,0x40,0x08,0x70,0x06,0x1c,0x80,0x87,0x00 } },
+{  16, 0xe220, 0, {0x2d,0x20,0x08,0x79,0x12,0x5c,0x00,0x94,0x00,0x2d,0xc0,0x0b,0x30,0x42,0x28,0x00 } },
+{  16, 0xe230, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x00,0xe4,0x80,0x31,0xa1 } },
+{  16, 0xe240, 0, {0x0f,0x58,0x13,0x76,0x00,0xd0,0x80,0x31,0xc0,0x0c,0x38,0x03,0xbe,0x80,0xd7,0x81 } },
+{  16, 0xe250, 0, {0x3f,0x20,0x8c,0x79,0x03,0x7f,0x01,0xd6,0x80,0x39,0xe8,0x4f,0x68,0x03,0x2a,0x00 } },
+{  16, 0xe260, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xbe,0x00,0xfa,0x00,0x3e,0x00 } },
+{  16, 0xe270, 0, {0x8f,0x96,0x0b,0xa4,0x00,0xea,0x00,0x3c,0xc0,0x0f,0x90,0x03,0xac,0x20,0xfb,0x40 } },
+{  16, 0xe280, 0, {0x2e,0x00,0x0f,0xb2,0x03,0xad,0xa0,0xea,0x00,0x3e,0xc0,0x0f,0xa0,0x1b,0xc2,0x04 } },
+{  16, 0xe290, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x08,0xde,0x81,0x33,0xa4 } },
+{  16, 0xe2a0, 0, {0x0e,0xfc,0x13,0x3e,0x00,0xfc,0x80,0x13,0x20,0x0c,0x68,0x03,0x3e,0x20,0xff,0xc8 } },
+{  16, 0xe2b0, 0, {0x3f,0x60,0x1d,0xf8,0x03,0x7e,0x00,0xc7,0x80,0x33,0xe2,0x0c,0xd8,0x03,0x10,0x00 } },
+{  16, 0xe2c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0x86,0x41,0x31,0xc4 } },
+{  16, 0xe2d0, 0, {0x08,0x79,0x42,0x9c,0x00,0xbc,0x10,0x21,0x40,0x85,0x35,0x03,0x5c,0x00,0xb7,0x00 } },
+{  16, 0xe2e0, 0, {0x2d,0xc0,0x08,0x72,0x02,0x2c,0x00,0xa7,0x01,0x37,0xc0,0x08,0x51,0x42,0x2a,0x00 } },
+{  16, 0xe2f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x8c,0x40,0x82,0x00,0x24,0x81 } },
+{  16, 0xe300, 0, {0x08,0xd8,0x02,0x14,0x20,0xb5,0x00,0x20,0x40,0x09,0x60,0x02,0x1c,0x40,0xb7,0x00 } },
+{  16, 0xe310, 0, {0x2c,0x40,0x0b,0x30,0x22,0xdc,0x00,0x97,0x00,0x21,0xc4,0x08,0x40,0x02,0x44,0x00 } },
+{  16, 0xe320, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xec,0x00,0x92,0x06,0x20,0x90 } },
+{  16, 0xe330, 0, {0x38,0x15,0x02,0x86,0x00,0xb8,0x00,0x60,0x50,0x09,0x30,0x02,0x4e,0x01,0xbb,0x00 } },
+{  16, 0xe340, 0, {0x2e,0x40,0x0b,0x30,0x02,0xce,0x20,0xb3,0x00,0x24,0xf0,0x48,0x02,0x0a,0x58,0x04 } },
+{  16, 0xe350, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xca,0x00,0xa6,0x94 } },
+{  16, 0xe360, 0, {0x2c,0x90,0x03,0x2e,0x00,0xfb,0x05,0xb2,0x85,0x0d,0x90,0x03,0x3f,0x90,0xff,0x00 } },
+{  16, 0xe370, 0, {0x7e,0x80,0x1f,0xf0,0x43,0xfc,0x21,0x9a,0x00,0x33,0xc8,0x3c,0xb2,0x03,0x6a,0x04 } },
+{  16, 0xe380, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0xec,0x02,0xea,0x40,0x3d,0x80 } },
+{  16, 0xe390, 0, {0x0f,0x10,0x93,0xed,0x00,0xfb,0x40,0x3e,0x90,0x8f,0x30,0x03,0xec,0x80,0xfb,0x00 } },
+{  16, 0xe3a0, 0, {0x3e,0x91,0x1c,0xb0,0x03,0x2c,0x10,0xe8,0x00,0x3e,0xc8,0x1f,0x90,0x03,0xa5,0x10 } },
+{  16, 0xe3b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xfc,0x02,0xe4,0x00,0x73,0xa0 } },
+{  16, 0xe3c0, 0, {0x0c,0xfc,0x03,0x7c,0x02,0xff,0x10,0x13,0xc4,0x1c,0xc0,0x03,0x3c,0x00,0xff,0x00 } },
+{  16, 0xe3d0, 0, {0x37,0xe0,0x0d,0xf0,0x03,0xfc,0x00,0xed,0x80,0x31,0xc0,0x0c,0x32,0x63,0x20,0x04 } },
+{  16, 0xe3e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x6c,0x00,0x8a,0xc0,0x22,0xb1 } },
+{  16, 0xe3f0, 0, {0x8a,0xb8,0x43,0x4a,0x10,0xdb,0x20,0x20,0xf0,0x0a,0x94,0x03,0x6c,0x00,0xbb,0x07 } },
+{  16, 0xe400, 0, {0x22,0xb8,0x08,0xb0,0x02,0xec,0x11,0xe8,0xc0,0xb2,0xc0,0x2a,0x92,0x1a,0x20,0x00 } },
+{  16, 0xe410, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x2c,0x00,0xaa,0x80,0x22,0x98 } },
+{  16, 0xe420, 0, {0x08,0x90,0x02,0x2f,0x03,0xbb,0x01,0x2a,0x83,0x08,0xb2,0x4e,0x2c,0x04,0xab,0x02 } },
+{  16, 0xe430, 0, {0x22,0xc4,0x28,0xb0,0x22,0xec,0x09,0xb3,0x50,0x62,0xc0,0x08,0xb0,0x02,0x20,0x00 } },
+{  16, 0xe440, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x01,0x83,0x00,0x60,0x80 } },
+{  16, 0xe450, 0, {0x08,0x12,0x0a,0x44,0x00,0x93,0x00,0x2a,0x80,0x4a,0x30,0x02,0x0c,0x00,0xb3,0x00 } },
+{  16, 0xe460, 0, {0x60,0xc0,0x08,0x30,0x02,0xcc,0x00,0xb3,0x02,0x60,0xc0,0x08,0x00,0x46,0x02,0x01 } },
+{  16, 0xe470, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0d,0x6c,0x00,0xe8,0x02,0x22,0x80 } },
+{  16, 0xe480, 0, {0x2c,0xf2,0x43,0x2c,0x00,0xfb,0x00,0xba,0xc0,0x08,0xa5,0x02,0x3c,0x00,0xef,0x00 } },
+{  16, 0xe490, 0, {0x36,0xc0,0x4d,0xf0,0x13,0xfd,0x51,0xfb,0x00,0x32,0xc0,0x0c,0xb0,0x03,0x20,0x01 } },
+{  16, 0xe4a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0x7e,0x04,0x3f,0x80 } },
+{  16, 0xe4b0, 0, {0x0f,0x31,0x43,0xf0,0x02,0xff,0x00,0x37,0xc0,0x0f,0xf0,0x03,0xfc,0x08,0xff,0x00 } },
+{  16, 0xe4c0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xef,0x00,0x3b,0xc0,0x0f,0xc0,0x03,0xe8,0x16 } },
+{  16, 0xe4d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf2,0x40,0xfc,0x80,0x3f,0x24 } },
+{  16, 0xe4e0, 0, {0x0d,0xd8,0x53,0xd6,0x04,0xdf,0x32,0x3f,0xcc,0x4c,0xc0,0x43,0xfc,0x00,0xdf,0x60 } },
+{  16, 0xe4f0, 0, {0x37,0xc0,0x0f,0xc4,0x03,0x7c,0xd0,0xdf,0x20,0x33,0xd8,0x0d,0xf8,0x43,0xf0,0x00 } },
+{  16, 0xe500, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x18,0xe8,0x80,0xb0,0x01,0x2e,0x08 } },
+{  16, 0xe510, 0, {0x88,0x90,0x02,0xec,0x20,0x8b,0x70,0x2f,0xcc,0x08,0xb3,0x82,0xfd,0xe0,0xbf,0x40 } },
+{  16, 0xe520, 0, {0x22,0xd8,0x0b,0x93,0x02,0xfd,0xc0,0xaf,0x10,0x28,0xf0,0x08,0xbc,0x12,0xf0,0x04 } },
+{  16, 0xe530, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x00,0xb0,0x00,0x2e,0x01 } },
+{  16, 0xe540, 0, {0x0a,0x12,0x82,0xec,0x80,0xb3,0x00,0x2c,0xc8,0x0a,0x00,0x32,0x8c,0x00,0xa3,0x30 } },
+{  16, 0xe550, 0, {0x20,0xd2,0x09,0x00,0x02,0x8c,0x80,0x83,0x00,0x28,0xd8,0x0b,0x34,0x12,0xf2,0x01 } },
+{  16, 0xe560, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xac,0x01,0xb8,0x02,0x2e,0x00 } },
+{  16, 0xe570, 0, {0x0a,0x90,0x12,0xec,0x10,0x8b,0x00,0x2e,0xc0,0x0a,0xb0,0x00,0xec,0x00,0xb3,0x00 } },
+{  16, 0xe580, 0, {0x22,0xc1,0x0b,0x92,0x02,0xcc,0x01,0xab,0x00,0x2a,0xc0,0x02,0xb0,0x02,0xf0,0x04 } },
+{  16, 0xe590, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe0,0x00,0xfa,0x0c,0x3e,0xc0 } },
+{  16, 0xe5a0, 0, {0x0f,0xa0,0x13,0xee,0x20,0xdb,0x00,0x3e,0xc0,0x2e,0x88,0x53,0xec,0x00,0xfb,0x00 } },
+{  16, 0xe5b0, 0, {0xb2,0xc0,0x8f,0xac,0x83,0xac,0x08,0xdb,0x00,0x1a,0xc0,0x4f,0xb0,0x03,0xc0,0x04 } },
+{  16, 0xe5c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb8,0x00,0xfe,0x00,0x3f,0xc0 } },
+{  16, 0xe5d0, 0, {0x2d,0xe0,0x03,0xfe,0x80,0x7f,0x00,0x3f,0xc0,0x0d,0xd2,0x03,0xfc,0x00,0xbf,0x01 } },
+{  16, 0xe5e0, 0, {0x3e,0xc0,0x0d,0xc8,0x03,0xfc,0x0c,0xff,0x00,0x3f,0xc0,0x09,0xf0,0x23,0xf8,0x00 } },
+{  16, 0xe5f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa4,0x00,0xfa,0x40,0x32,0xc1 } },
+{  16, 0xe600, 0, {0x0f,0xa0,0x03,0x29,0x08,0xdb,0x00,0x3e,0xc0,0x0e,0x85,0x03,0xec,0x20,0xcb,0x00 } },
+{  16, 0xe610, 0, {0x3a,0xc0,0x0e,0xa4,0x03,0xec,0x00,0xfb,0x00,0x3a,0xc2,0x0e,0xb0,0x03,0x10,0x04 } },
+{  16, 0xe620, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xba,0x60,0x20,0xc0 } },
+{  16, 0xe630, 0, {0x0b,0xa0,0x02,0x08,0x00,0xaf,0x00,0x2f,0xd0,0x0b,0xb5,0x02,0xfe,0x02,0x8f,0x00 } },
+{  16, 0xe640, 0, {0x2f,0xc0,0x0d,0x80,0x0a,0x3c,0x00,0xb7,0x00,0x23,0xc2,0x05,0xf0,0x22,0x36,0x00 } },
+{  16, 0xe650, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x04,0x40,0x00,0xb1,0x88,0x20,0x00 } },
+{  16, 0xe660, 0, {0x0b,0x10,0x02,0x0c,0x00,0x83,0x00,0x2e,0xc8,0x0b,0x08,0x06,0x4d,0x40,0x83,0x00 } },
+{  16, 0xe670, 0, {0x20,0xc0,0x08,0x30,0x06,0x0c,0x08,0x93,0x20,0x0a,0xe0,0x4a,0x30,0x02,0x38,0x00 } },
+{  16, 0xe680, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x10,0x5a,0x00,0xb5,0x90,0x21,0x20 } },
+{  16, 0xe690, 0, {0x0b,0x58,0x42,0x3e,0x00,0xa7,0x80,0x2d,0xe0,0x0b,0x69,0x02,0xde,0x40,0x87,0x92 } },
+{  16, 0xe6a0, 0, {0x2d,0xe0,0x09,0x18,0x02,0x9e,0x01,0xb7,0x80,0x29,0xe0,0x03,0x70,0x02,0x3e,0x00 } },
+{  16, 0xe6b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x44,0x00,0xf1,0x01,0x30,0x00 } },
+{  16, 0xe6c0, 0, {0x5f,0x18,0x03,0x0c,0x10,0x83,0x00,0x3c,0xc4,0x0e,0x04,0x03,0xec,0x00,0x83,0x00 } },
+{  16, 0xe6d0, 0, {0x30,0xc4,0x0c,0x31,0x03,0x8c,0x00,0xf3,0x00,0x38,0xc8,0x0e,0x31,0x03,0x12,0x02 } },
+{  16, 0xe6e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xbc,0x00,0xfd,0x04,0xbf,0x04 } },
+{  16, 0xe6f0, 0, {0x4f,0x58,0x03,0xf8,0x08,0xef,0x08,0x3f,0xc0,0x0f,0xf0,0x01,0xfc,0x00,0xff,0x4c } },
+{  16, 0xe700, 0, {0x3f,0xc1,0x0f,0xd0,0x03,0x3c,0x00,0xf7,0x00,0x37,0xc2,0x0d,0x72,0x03,0xd0,0x06 } },
+{  16, 0xe710, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xe2,0x00,0xdb,0x00,0x32,0xc0 } },
+{  16, 0xe720, 0, {0x4d,0xa8,0x03,0x2c,0x08,0xfb,0x00,0x7e,0xc8,0x8f,0xb0,0x0b,0x6f,0x45,0xeb,0xc2 } },
+{  16, 0xe730, 0, {0x36,0xc0,0x07,0xa0,0x03,0xef,0x20,0xcb,0x50,0xb2,0xc0,0x0c,0x79,0x03,0x2a,0x00 } },
+{  16, 0xe740, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x19,0x98,0x00,0x8f,0x00,0x21,0xc0 } },
+{  16, 0xe750, 0, {0x0b,0x60,0x03,0x5c,0x00,0x37,0x00,0x2d,0xd2,0x0b,0x30,0x02,0x0c,0xa8,0x87,0x24 } },
+{  16, 0xe760, 0, {0x21,0xd0,0x09,0x70,0x02,0xdd,0x88,0x87,0x2a,0x23,0xe8,0x08,0x70,0x02,0x32,0x04 } },
+{  16, 0xe770, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xb6,0x00,0x97,0x80,0x21,0xe0 } },
+{  16, 0xe780, 0, {0x0b,0x68,0x02,0x1e,0x00,0xb7,0x80,0x2d,0xe8,0x8b,0x48,0x82,0x1e,0x80,0xa3,0x84 } },
+{  16, 0xe790, 0, {0x25,0xe8,0x0b,0x68,0x02,0xce,0x02,0x87,0x80,0x21,0xe0,0x08,0x7a,0x02,0x20,0x00 } },
+{  16, 0xe7a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x04,0xcc,0x08,0x83,0x82,0x20,0xe0 } },
+{  16, 0xe7b0, 0, {0x8b,0x2a,0x02,0x48,0x40,0xb3,0x00,0x2c,0xc0,0x0b,0x30,0x82,0x0c,0x00,0x83,0x00 } },
+{  16, 0xe7c0, 0, {0x00,0xc1,0x09,0x31,0x02,0xcc,0x00,0x83,0x00,0x20,0xc0,0x08,0x30,0x0a,0x12,0x04 } },
+{  16, 0xe7d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xe8,0x00,0xda,0xa0,0x32,0xa8 } },
+{  16, 0xe7e0, 0, {0x8d,0xa8,0x03,0x3b,0x00,0xfa,0x00,0x3e,0x80,0x0f,0xe4,0x03,0x68,0x00,0xea,0x02 } },
+{  16, 0xe7f0, 0, {0x36,0x80,0x0f,0xe4,0x03,0xe8,0x00,0xca,0x00,0x32,0x80,0x2c,0xa0,0x03,0x3a,0x04 } },
+{  16, 0xe800, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x01,0xa0,0x10,0xf8,0x00,0xbe,0x20 } },
+{  16, 0xe810, 0, {0x8f,0xc1,0x03,0xe0,0x24,0xf8,0x00,0x3e,0x10,0x0f,0x84,0x03,0xe0,0x00,0xf8,0x01 } },
+{  16, 0xe820, 0, {0x3e,0x00,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x01,0xbe,0x10,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0xe830, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa4,0x00,0xf9,0x40,0x32,0x40 } },
+{  16, 0xe840, 0, {0xcf,0x90,0x03,0xe4,0x00,0xc9,0x00,0x0e,0x50,0x0f,0x1a,0x03,0x26,0x00,0xf9,0x00 } },
+{  16, 0xe850, 0, {0x3e,0x40,0x0f,0x90,0x81,0xe4,0x00,0xf9,0x80,0x32,0x40,0x0c,0x90,0x03,0xc2,0x04 } },
+{  16, 0xe860, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x04,0xb1,0x04,0x22,0x40 } },
+{  16, 0xe870, 0, {0x0b,0x90,0x02,0xe4,0x00,0xa9,0x00,0x2e,0x53,0x0b,0x92,0x0a,0x26,0x48,0xb9,0x04 } },
+{  16, 0xe880, 0, {0x2e,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x80,0x02,0x50,0x08,0x90,0x02,0xe0,0x00 } },
+{  16, 0xe890, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x05,0x24,0x00,0xbd,0x00,0x23,0x40 } },
+{  16, 0xe8a0, 0, {0x0b,0xd0,0x12,0xc4,0x00,0x89,0x02,0x2e,0x40,0x0b,0x90,0x22,0x24,0x00,0xb9,0x00 } },
+{  16, 0xe8b0, 0, {0x2e,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb1,0x20,0x20,0x40,0x68,0x90,0x22,0xc6,0x00 } },
+{  16, 0xe8c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x14,0x14,0x00,0xbf,0x12,0xa1,0x40 } },
+{  16, 0xe8d0, 0, {0x0b,0x50,0x02,0xc4,0x00,0xa1,0x20,0x2c,0x48,0x0b,0x12,0x02,0x04,0x10,0xb1,0x11 } },
+{  16, 0xe8e0, 0, {0x2c,0x48,0x0b,0x13,0x22,0xc4,0x00,0xb1,0x40,0x20,0x5a,0x08,0x10,0x02,0xc2,0x01 } },
+{  16, 0xe8f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x40,0x32,0x14 } },
+{  16, 0xe900, 0, {0x0f,0x45,0x03,0xe1,0x40,0xc8,0x50,0x3e,0x15,0x8f,0x85,0x03,0x21,0xe8,0xf8,0x68 } },
+{  16, 0xe910, 0, {0x3e,0x14,0x0f,0x84,0x03,0xe1,0xe0,0xf0,0x28,0x32,0xa8,0xcc,0x80,0x23,0xee,0x03 } },
+{  16, 0xe920, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x15,0xc4,0x10,0xf9,0x20,0x3e,0x40 } },
+{  16, 0xe930, 0, {0x0f,0x90,0x03,0xf4,0x00,0xf9,0x10,0x3e,0x44,0x0f,0xd1,0x03,0xe4,0x00,0xf9,0x20 } },
+{  16, 0xe940, 0, {0x3e,0x44,0x0f,0xd3,0x03,0xe4,0x00,0xf9,0x00,0xbe,0x40,0x0f,0x94,0x03,0xe6,0x06 } },
+{  16, 0xe950, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xe4,0x00,0xfd,0x10,0x33,0x40 } },
+{  16, 0xe960, 0, {0x0c,0xd0,0x03,0x24,0x00,0xd9,0x00,0x3f,0x40,0x4c,0xd0,0x03,0xf6,0x00,0xfd,0x90 } },
+{  16, 0xe970, 0, {0x3a,0x40,0x0c,0x90,0x03,0xe6,0xa0,0xfd,0xa8,0x37,0x68,0x0c,0xd8,0x83,0x26,0x00 } },
+{  16, 0xe980, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x08,0xc8,0xa0,0x22,0x00 } },
+{  16, 0xe990, 0, {0x08,0x80,0x02,0x20,0x00,0x88,0x00,0x2e,0x00,0x0c,0x80,0x12,0xe0,0x00,0xb8,0x80 } },
+{  16, 0xe9a0, 0, {0x22,0x00,0x0d,0x0a,0x02,0xe3,0x80,0xb0,0xc0,0x20,0x34,0x08,0x84,0x03,0x4e,0x04 } },
+{  16, 0xe9b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x84,0x09,0xa1,0x00,0x20,0x41 } },
+{  16, 0xe9c0, 0, {0x08,0x90,0x02,0x24,0x00,0x91,0x00,0x2c,0x40,0x08,0x10,0x02,0xc5,0x00,0xb1,0x60 } },
+{  16, 0xe9d0, 0, {0x20,0x40,0x08,0x10,0xa2,0xc4,0x20,0xb1,0x28,0x24,0x4a,0x08,0x10,0x02,0x52,0x01 } },
+{  16, 0xe9e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x14,0xa4,0x01,0x81,0x00,0xa2,0x40 } },
+{  16, 0xe9f0, 0, {0xa8,0x90,0x00,0x25,0x40,0x89,0x01,0x2c,0x40,0x08,0x94,0x02,0xe4,0x00,0xb9,0x00 } },
+{  16, 0xea00, 0, {0x2a,0x40,0x09,0x90,0x02,0xe4,0x01,0xb9,0x04,0x22,0x41,0x48,0x90,0x02,0x46,0x04 } },
+{  16, 0xea10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x14,0xa5,0x20,0xe9,0x00,0x32,0x40 } },
+{  16, 0xea20, 0, {0x4c,0x10,0x0b,0x26,0x00,0xd9,0x00,0x3e,0x40,0x2c,0x98,0x03,0xe4,0x00,0xf9,0x00 } },
+{  16, 0xea30, 0, {0xb2,0x40,0x0c,0x90,0x03,0xe4,0x00,0xf9,0x00,0x36,0x40,0x2c,0x90,0x03,0x68,0x04 } },
+{  16, 0xea40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x01,0xa4,0x00,0xe9,0x00,0x3e,0x40 } },
+{  16, 0xea50, 0, {0x0f,0x90,0x03,0xe6,0x00,0xf9,0x00,0x3e,0x40,0x0e,0x9a,0x03,0xe4,0x00,0xf9,0x00 } },
+{  16, 0xea60, 0, {0x36,0x40,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3c,0x40,0x0f,0x90,0x03,0xda,0x00 } },
+{  16, 0xea70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa1,0x00,0xf8,0x00,0x32,0x00 } },
+{  16, 0xea80, 0, {0x0f,0x80,0x13,0xa0,0x00,0xc8,0x00,0x32,0x04,0x8c,0x80,0x03,0xa0,0xc0,0xf8,0x00 } },
+{  16, 0xea90, 0, {0x3a,0x00,0x0f,0x80,0x03,0x20,0x00,0xc0,0x09,0x32,0x00,0x4c,0x80,0x01,0x0a,0x04 } },
+{  16, 0xeaa0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0xbe,0x00,0x20,0x80 } },
+{  16, 0xeab0, 0, {0x0b,0xe0,0x02,0x88,0x00,0xaa,0x00,0x03,0xa0,0x0a,0xe6,0x02,0xfa,0x00,0x8a,0x00 } },
+{  16, 0xeac0, 0, {0x32,0x80,0x0b,0xa0,0x02,0x28,0x00,0x8e,0x80,0xa3,0x80,0x28,0x20,0x02,0x8a,0x00 } },
+{  16, 0xead0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6c,0x00,0xb3,0x48,0x20,0x40 } },
+{  16, 0xeae0, 0, {0x0b,0x10,0x02,0x0c,0x00,0x83,0x00,0x20,0xc0,0x08,0x34,0x82,0x8e,0x04,0x99,0x00 } },
+{  16, 0xeaf0, 0, {0x0a,0xc0,0x1b,0x30,0x02,0x0c,0x02,0x90,0x50,0x20,0x60,0x08,0x30,0x02,0x0a,0x00 } },
+{  16, 0xeb00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x11,0x1c,0x80,0xbd,0x0a,0x21,0x48 } },
+{  16, 0xeb10, 0, {0x0b,0x52,0x02,0x9c,0x40,0xa3,0xa0,0x20,0x80,0x0a,0x60,0x02,0xce,0x00,0x85,0x20 } },
+{  16, 0xeb20, 0, {0x21,0xc4,0x0b,0x7a,0x06,0x1e,0x80,0x95,0x20,0x21,0x90,0x08,0x70,0x02,0x28,0x00 } },
+{  16, 0xeb30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x08,0x1e,0x80,0xf7,0x80,0xb1,0x79 } },
+{  16, 0xeb40, 0, {0x0f,0xdb,0x02,0x3e,0x20,0xc7,0xa0,0xb1,0x60,0xcc,0x78,0x13,0x96,0x00,0xf1,0xf0 } },
+{  16, 0xeb50, 0, {0x39,0xe2,0x0f,0x7b,0x13,0x0f,0x00,0xd4,0xa0,0x31,0x60,0x2c,0x70,0x03,0x2a,0x02 } },
+{  16, 0xeb60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x15,0xac,0x00,0xf7,0x00,0x3e,0x40 } },
+{  16, 0xeb70, 0, {0x0f,0x90,0x03,0xed,0x80,0xfb,0x10,0x3e,0x40,0x0b,0xb0,0x23,0xec,0x00,0xf9,0x20 } },
+{  16, 0xeb80, 0, {0x3a,0xd8,0x0f,0xb0,0x0b,0xed,0x81,0xed,0x10,0x3e,0x80,0x0f,0x30,0x03,0xc2,0x06 } },
+{  16, 0xeb90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xbe,0x20,0xee,0x80,0x33,0x60 } },
+{  16, 0xeba0, 0, {0x0c,0xd8,0x83,0x1e,0x00,0x6f,0x80,0x33,0xe0,0x0f,0xb8,0x11,0x32,0x04,0xf5,0x80 } },
+{  16, 0xebb0, 0, {0x33,0xe0,0x0f,0xf8,0x83,0x2f,0x40,0xfe,0x80,0xb3,0xe0,0x0c,0xf8,0x03,0x10,0x00 } },
+{  16, 0xebc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x18,0x9c,0x00,0xbc,0x00,0xa1,0x44 } },
+{  16, 0xebd0, 0, {0x08,0x10,0x03,0x5c,0x00,0x8f,0x00,0x21,0x80,0x0b,0xea,0x22,0x1c,0x80,0xb5,0x01 } },
+{  16, 0xebe0, 0, {0x21,0xc0,0x0b,0xf0,0x02,0x1e,0x80,0xbe,0x00,0x23,0x80,0x2a,0x70,0x02,0x2a,0x04 } },
+{  16, 0xebf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x20,0xa7,0x00,0x23,0x40 } },
+{  16, 0xec00, 0, {0x0b,0x50,0x0a,0x3c,0x00,0xa7,0x00,0x25,0xc0,0x0a,0x43,0x02,0x10,0x00,0xb5,0x00 } },
+{  16, 0xec10, 0, {0x21,0xc0,0x0b,0x70,0x82,0x1c,0x80,0xb4,0x00,0x21,0xc0,0x08,0x70,0x02,0x04,0x00 } },
+{  16, 0xec20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x04,0x8e,0x04,0xb3,0x00,0x22,0x40 } },
+{  16, 0xec30, 0, {0x09,0x14,0x02,0x4c,0x00,0x83,0x00,0x20,0xc0,0x0b,0x24,0x82,0x04,0x00,0xb1,0x00 } },
+{  16, 0xec40, 0, {0x20,0xc0,0x8b,0x3a,0x02,0x2c,0x01,0xb0,0x00,0x20,0x80,0x0a,0x30,0x02,0x1a,0x04 } },
+{  16, 0xec50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x9e,0x00,0xeb,0x04,0x33,0x40 } },
+{  16, 0xec60, 0, {0x2d,0xdc,0x03,0x1d,0x60,0xef,0x00,0x32,0x00,0xcf,0x9a,0x03,0x28,0x00,0xfd,0x00 } },
+{  16, 0xec70, 0, {0x33,0xc1,0x8b,0xfc,0x0b,0x3c,0x00,0xfc,0x00,0x32,0x80,0x0c,0x90,0x03,0x2a,0x04 } },
+{  16, 0xec80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xac,0x10,0xf8,0x00,0x3e,0x40 } },
+{  16, 0xec90, 0, {0x0e,0x98,0x23,0xac,0x04,0xfb,0x00,0x3c,0x00,0x0f,0x84,0x20,0xed,0x00,0xf9,0x00 } },
+{  16, 0xeca0, 0, {0x3e,0xc0,0x4f,0xb0,0x03,0xec,0x00,0xfd,0x00,0x3e,0x80,0x0f,0x90,0x03,0xe4,0x00 } },
+{  16, 0xecb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x10,0xfc,0x00,0xcf,0x80,0x33,0x40 } },
+{  16, 0xecc0, 0, {0x0c,0xd0,0x83,0xfc,0x00,0xef,0x00,0x3f,0x40,0x0c,0xf1,0x41,0x30,0x10,0xcd,0x00 } },
+{  16, 0xecd0, 0, {0x3f,0xc0,0x00,0x70,0x13,0x3c,0x00,0xe4,0x00,0xb1,0xd0,0x0c,0x10,0x03,0x20,0x04 } },
+{  16, 0xece0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,0x04,0x2c,0x00,0x8a,0xe4,0x2a,0x40 } },
+{  16, 0xecf0, 0, {0x28,0x90,0x02,0xec,0x00,0x8b,0x00,0x3e,0x02,0x0a,0x80,0x02,0x2c,0x82,0x89,0x04 } },
+{  16, 0xed00, 0, {0x2e,0xc1,0x0a,0xb0,0x0a,0x2c,0x00,0x89,0x02,0x22,0xf2,0x2a,0x98,0x02,0x20,0x00 } },
+{  16, 0xed10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x02,0x80,0x14,0x2a,0x40 } },
+{  16, 0xed20, 0, {0x08,0x90,0x02,0xec,0x08,0xab,0x04,0x2e,0x84,0x08,0x10,0x82,0x80,0x10,0x89,0x03 } },
+{  16, 0xed30, 0, {0x2c,0xc0,0x4a,0xb0,0x22,0x2c,0x00,0xaa,0x00,0x22,0x80,0x08,0x91,0x02,0x20,0x00 } },
+{  16, 0xed40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x2c,0x00,0x80,0x00,0x28,0x40 } },
+{  16, 0xed50, 0, {0x08,0x11,0x02,0xec,0x00,0x83,0x00,0x2c,0x81,0x0a,0x00,0x5a,0x88,0x00,0x01,0x00 } },
+{  16, 0xed60, 0, {0x2c,0xc0,0x0a,0x30,0x02,0x0c,0x00,0x82,0x00,0x20,0x80,0x0a,0x10,0x02,0x02,0x01 } },
+{  16, 0xed70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xc9,0x00,0x3a,0x40 } },
+{  16, 0xed80, 0, {0x0c,0xd4,0x03,0xfc,0x00,0xeb,0x00,0x3e,0x40,0x0c,0x92,0x03,0xa0,0x00,0x4d,0x00 } },
+{  16, 0xed90, 0, {0x3f,0xc0,0x0e,0xf0,0x33,0x3c,0x80,0xe8,0x00,0x32,0xc0,0x0c,0x90,0x03,0x20,0x03 } },
+{  16, 0xeda0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xfc,0x00,0xfc,0x00,0x3d,0x40 } },
+{  16, 0xedb0, 0, {0x0f,0x50,0x03,0xfc,0x02,0x3f,0x04,0x3b,0x01,0x4f,0xc4,0x13,0x70,0x00,0xfd,0x00 } },
+{  16, 0xedc0, 0, {0x3f,0xc0,0x1f,0xf0,0x01,0xfc,0x40,0xfc,0x00,0x3f,0xc0,0x0f,0xd0,0x13,0xe8,0x06 } },
+{  16, 0xedd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf8,0xe0,0xff,0x80,0x3d,0xc0 } },
+{  16, 0xede0, 0, {0x0d,0xf3,0x82,0xf0,0x80,0xff,0x40,0x31,0xcb,0x0c,0xf3,0x03,0xfd,0x04,0xef,0xc1 } },
+{  16, 0xedf0, 0, {0x33,0xe0,0x0f,0x79,0x03,0xfe,0x00,0xcf,0x42,0x33,0xf0,0x4c,0xf8,0x03,0x30,0x00 } },
+{  16, 0xee00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0xe9,0x08,0xb9,0x81,0x2f,0xf0 } },
+{  16, 0xee10, 0, {0x08,0xf4,0x52,0xe9,0x20,0xbf,0x40,0x23,0xf0,0x0a,0xf3,0x02,0xfd,0x08,0x8b,0x00 } },
+{  16, 0xee20, 0, {0x36,0xe0,0x0b,0x80,0x22,0xe8,0x80,0x8f,0x40,0x22,0xc0,0x08,0xb0,0x82,0x30,0x04 } },
+{  16, 0xee30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0xcc,0x00,0xb1,0x80,0x2c,0xc5 } },
+{  16, 0xee40, 0, {0x09,0x32,0x42,0xc8,0xc0,0xb3,0x31,0x20,0xc1,0x08,0x32,0x02,0xcc,0xd4,0xbb,0x20 } },
+{  16, 0xee50, 0, {0x68,0xc0,0x0b,0x30,0x02,0xcc,0x20,0x93,0x60,0x20,0x88,0x08,0x32,0x02,0x32,0x01 } },
+{  16, 0xee60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x15,0xa0,0x00,0xbb,0x80,0x2e,0xc0 } },
+{  16, 0xee70, 0, {0x08,0xb0,0x02,0xea,0x00,0xbb,0x00,0x62,0xc1,0x0a,0xb0,0x02,0xcc,0x00,0xab,0x00 } },
+{  16, 0xee80, 0, {0x2e,0xc0,0x0b,0xa0,0x00,0xe8,0x00,0x83,0x00,0x22,0xc1,0x08,0x30,0x02,0x30,0x04 } },
+{  16, 0xee90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xe8,0x90,0xfb,0x80,0x3e,0xc0 } },
+{  16, 0xeea0, 0, {0x0d,0xb0,0x03,0xe2,0x10,0xfb,0x00,0x32,0xc0,0x4c,0xb0,0x13,0xec,0x00,0xe9,0x54 } },
+{  16, 0xeeb0, 0, {0x3a,0xc0,0x0f,0xb0,0x03,0xe6,0x00,0xcb,0x00,0xb2,0x40,0x0c,0xb0,0x03,0x04,0x04 } },
+{  16, 0xeec0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb8,0x00,0xff,0x00,0x3f,0xc0 } },
+{  16, 0xeed0, 0, {0x8f,0xf0,0x03,0xf0,0x00,0xf7,0x02,0xbf,0xc1,0x0f,0xf0,0x23,0xfc,0x00,0xdf,0x06 } },
+{  16, 0xeee0, 0, {0x37,0xc0,0x8f,0xc9,0x07,0xfa,0x92,0xff,0x04,0x3f,0x50,0x2f,0xf0,0x03,0xf8,0x00 } },
+{  16, 0xeef0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x10,0xac,0x00,0xc9,0x00,0x3e,0xc2 } },
+{  16, 0xef00, 0, {0x0e,0xb0,0x23,0xe4,0x00,0xeb,0x00,0x3a,0xc8,0x0e,0xb0,0x03,0xec,0x00,0xf9,0x00 } },
+{  16, 0xef10, 0, {0x3e,0xc0,0x0f,0xb4,0x03,0xa4,0x00,0xfb,0x00,0x3e,0x80,0x0f,0xb0,0x83,0xd0,0x04 } },
+{  16, 0xef20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x28,0x00,0x8b,0x74,0x2d,0xc0 } },
+{  16, 0xef30, 0, {0x08,0xf0,0x02,0xe4,0x00,0x8f,0x00,0x21,0xf0,0x08,0xf0,0x02,0xfc,0x10,0xd3,0x00 } },
+{  16, 0xef40, 0, {0x2e,0xc0,0x0b,0x90,0x12,0x2c,0x00,0xef,0x00,0x2e,0xc0,0x0b,0xb6,0x02,0xf6,0x00 } },
+{  16, 0xef50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0x48,0x00,0xa3,0x00,0x2c,0xc4 } },
+{  16, 0xef60, 0, {0x0a,0x30,0x02,0xc0,0x00,0xa3,0x00,0x68,0xf0,0x0a,0x30,0x12,0xcc,0x04,0xa2,0x00 } },
+{  16, 0xef70, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xec,0x00,0xb3,0x01,0x2e,0xc0,0x0b,0x34,0x02,0xf8,0x00 } },
+{  16, 0xef80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x01,0x0c,0x00,0x87,0x80,0x2d,0xe8 } },
+{  16, 0xef90, 0, {0x08,0x78,0x42,0xda,0x00,0x87,0x80,0x25,0xe0,0x08,0x79,0x02,0xce,0x00,0x96,0x80 } },
+{  16, 0xefa0, 0, {0x2d,0xe0,0x0b,0xd9,0x02,0xde,0x00,0xa7,0x80,0x2d,0xe0,0x0b,0x78,0x02,0xfc,0x00 } },
+{  16, 0xefb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x40,0xe3,0x10,0x3c,0xc0 } },
+{  16, 0xefc0, 0, {0x0a,0x38,0x03,0xe8,0x00,0xeb,0x00,0x38,0xc2,0x0a,0x30,0x03,0xcc,0x00,0xe3,0x40 } },
+{  16, 0xefd0, 0, {0x3c,0xc0,0x0f,0x34,0x03,0xcd,0x00,0xf3,0x20,0x3c,0x88,0x0f,0x30,0x03,0xd2,0x02 } },
+{  16, 0xefe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb4,0x80,0xff,0x04,0x3f,0xc8 } },
+{  16, 0xeff0, 0, {0x0f,0xf0,0x83,0xf8,0x40,0xff,0x18,0x3b,0xc0,0x0f,0xf4,0x83,0xfc,0x00,0xee,0x02 } },
+{  16, 0xf000, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0x3c,0x00,0xef,0x08,0x3f,0x80,0x0f,0xf0,0x13,0xd0,0x06 } },
+{  16, 0xf010, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe8,0x00,0xcb,0x00,0x3e,0xf2 } },
+{  16, 0xf020, 0, {0x4d,0xb2,0x13,0xe8,0x04,0xcb,0x01,0x32,0xf8,0x4d,0xb2,0x13,0x6d,0x20,0xf8,0x00 } },
+{  16, 0xf030, 0, {0x3e,0xc0,0x0f,0x30,0x03,0x24,0x00,0xfb,0x00,0x3e,0x40,0x8f,0xb8,0x03,0x2a,0x00 } },
+{  16, 0xf040, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x11,0x8c,0x00,0x86,0x00,0x2c,0xc0 } },
+{  16, 0xf050, 0, {0x08,0x73,0x02,0xd8,0x12,0x87,0x30,0x20,0xcb,0x08,0xf2,0x02,0x1d,0x05,0xb5,0x00 } },
+{  16, 0xf060, 0, {0x2d,0xc0,0x0b,0x60,0x03,0x50,0x10,0xb7,0x09,0x2d,0xc0,0x0b,0xf0,0x02,0x32,0x04 } },
+{  16, 0xf070, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x00,0x87,0x80,0x2d,0xe4 } },
+{  16, 0xf080, 0, {0x09,0x7a,0x02,0xce,0x01,0x87,0x80,0x21,0xec,0x09,0x78,0x02,0x5e,0x80,0xb7,0xc0 } },
+{  16, 0xf090, 0, {0x2d,0xe0,0x0b,0xf8,0x02,0x1e,0x00,0xb7,0xa0,0x2d,0x60,0x0b,0x78,0x02,0x20,0x00 } },
+{  16, 0xf0a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xee,0x00,0x82,0x80,0x2c,0xc0 } },
+{  16, 0xf0b0, 0, {0x08,0x30,0x02,0xec,0x00,0x83,0x00,0xa0,0xc0,0x08,0x30,0x02,0x0c,0x00,0xb3,0x80 } },
+{  16, 0xf0c0, 0, {0x2c,0xc1,0x0b,0x30,0x02,0x4e,0x00,0xb3,0x00,0x2c,0xf1,0x0b,0x30,0x0a,0x12,0x04 } },
+{  16, 0xf0d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xba,0x80,0xc6,0x00,0x3e,0x80 } },
+{  16, 0xf0e0, 0, {0x0d,0xa0,0x03,0xf8,0x40,0xca,0x00,0x32,0x80,0x0d,0xa0,0x13,0x68,0x00,0xfe,0x02 } },
+{  16, 0xf0f0, 0, {0x7e,0x80,0x0f,0xed,0x83,0x39,0x10,0xfa,0x00,0x3f,0x8c,0x0f,0xa0,0x03,0x3a,0x04 } },
+{  16, 0xf100, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x12,0xf8,0x90,0x3e,0x00 } },
+{  16, 0xf110, 0, {0x0f,0x80,0x03,0xe0,0x00,0xf8,0x05,0x3e,0x00,0x0e,0x00,0x03,0xe0,0x00,0xf8,0x80 } },
+{  16, 0xf120, 0, {0x3e,0x00,0x0f,0x80,0x03,0xe0,0x60,0xf8,0x00,0x7e,0x00,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0xf130, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xc9,0x80,0x32,0x64 } },
+{  16, 0xf140, 0, {0x0f,0x90,0x43,0xe4,0x06,0xc1,0x04,0x3a,0x40,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x00 } },
+{  16, 0xf150, 0, {0x32,0x40,0x0f,0x90,0x03,0x24,0x00,0xc1,0x01,0x32,0x40,0x0c,0x90,0x03,0xc2,0x04 } },
+{  16, 0xf160, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0xc0,0x22,0x40 } },
+{  16, 0xf170, 0, {0x0b,0x90,0x02,0x24,0x00,0x89,0x00,0x22,0x50,0x1b,0x90,0x22,0x24,0x00,0x81,0x00 } },
+{  16, 0xf180, 0, {0x22,0x40,0x0b,0x90,0x22,0x24,0x08,0xc9,0x00,0x20,0x40,0x08,0x94,0x02,0xe0,0x00 } },
+{  16, 0xf190, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x99,0x20,0x22,0x40 } },
+{  16, 0xf1a0, 0, {0x0b,0x10,0x02,0xa4,0x00,0x89,0x00,0x2a,0x58,0x0b,0x90,0x02,0x84,0x00,0xa9,0x00 } },
+{  16, 0xf1b0, 0, {0x22,0x40,0x0b,0x10,0x0a,0x04,0x00,0x99,0x02,0x22,0xc1,0x08,0x90,0x82,0xc6,0x00 } },
+{  16, 0xf1c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0x91,0x02,0xa0,0xc8 } },
+{  16, 0xf1d0, 0, {0x0b,0x12,0x02,0x04,0x80,0x81,0x22,0x20,0x48,0x9b,0x12,0x02,0x04,0x90,0x89,0x01 } },
+{  16, 0xf1e0, 0, {0x20,0x40,0x0b,0x10,0x02,0x04,0x02,0x81,0x22,0x22,0x40,0x08,0x10,0x02,0xc2,0x01 } },
+{  16, 0xf1f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x42,0xda,0x01,0x32,0x01 } },
+{  16, 0xf200, 0, {0x0f,0x85,0x03,0xa1,0x40,0xc0,0x50,0x3a,0x01,0x8b,0x85,0x23,0xa1,0x44,0xe8,0x50 } },
+{  16, 0xf210, 0, {0xb2,0x00,0x0f,0x85,0x03,0x21,0x48,0xd8,0x51,0x32,0x14,0x2c,0x85,0x03,0xee,0x03 } },
+{  16, 0xf220, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf5,0x00,0xed,0x02,0x3e,0x44 } },
+{  16, 0xf230, 0, {0x0f,0x91,0x03,0xf4,0x40,0xf9,0x10,0x3e,0x44,0x0f,0x91,0x03,0xe4,0x40,0xfd,0x00 } },
+{  16, 0xf240, 0, {0x3e,0x40,0x0f,0xd0,0x03,0xf4,0x00,0xe9,0x10,0xbf,0x40,0x0f,0x90,0x03,0x66,0x06 } },
+{  16, 0xf250, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x21,0xc5,0x00,0x33,0x68 } },
+{  16, 0xf260, 0, {0x0f,0x9a,0x03,0x6f,0x88,0xc9,0xc0,0x33,0x68,0x0c,0x9e,0x03,0x27,0x80,0xd9,0x40 } },
+{  16, 0xf270, 0, {0x3e,0x40,0x0f,0x90,0x03,0xc5,0x10,0xd9,0xe8,0x36,0x50,0x0c,0xd0,0x03,0xe6,0x00 } },
+{  16, 0xf280, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x08,0x88,0x00,0x82,0x00 } },
+{  16, 0xf290, 0, {0x0b,0x8e,0x82,0xeb,0xc8,0x88,0xe0,0x22,0x00,0x28,0x88,0x42,0xa2,0x80,0x8a,0x80 } },
+{  16, 0xf2a0, 0, {0x22,0x00,0x0b,0xaa,0x02,0xe2,0x00,0x88,0xc0,0x22,0xa9,0x08,0x8a,0x03,0x8e,0x04 } },
+{  16, 0xf2b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x00,0x81,0x00,0x20,0xd0 } },
+{  16, 0xf2c0, 0, {0x0b,0x11,0x32,0x84,0x84,0x81,0x60,0x60,0x50,0x08,0x16,0x06,0x05,0x00,0x91,0x20 } },
+{  16, 0xf2d0, 0, {0x20,0x40,0x0b,0x10,0x82,0xe4,0x09,0x91,0x20,0x24,0x40,0x08,0x10,0xc2,0xd2,0x01 } },
+{  16, 0xf2e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x04,0x89,0x04,0x22,0x40 } },
+{  16, 0xf2f0, 0, {0x0b,0x90,0x02,0xc4,0x00,0xa9,0x00,0x22,0x41,0x00,0x90,0x02,0xa4,0x00,0x81,0x00 } },
+{  16, 0xf300, 0, {0x22,0x40,0x0b,0x92,0x22,0xe5,0x80,0x99,0x01,0x22,0x61,0x08,0x90,0x02,0x86,0x04 } },
+{  16, 0xf310, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x14,0xa5,0x82,0x81,0x90,0x32,0x40 } },
+{  16, 0xf320, 0, {0x0f,0x90,0x13,0x67,0x02,0xc9,0x00,0x32,0x40,0x0c,0x90,0x23,0x24,0x04,0xd9,0xc0 } },
+{  16, 0xf330, 0, {0xb2,0x40,0x0f,0x9c,0x03,0xe6,0x00,0xd9,0x00,0x36,0x50,0x0c,0x90,0x03,0xe8,0x04 } },
+{  16, 0xf340, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x00,0xa6,0x80,0xf9,0x00,0x3e,0x40 } },
+{  16, 0xf350, 0, {0x0f,0x90,0x03,0xe7,0x00,0xd9,0x00,0xbc,0x42,0x0f,0x90,0x53,0xe4,0x04,0xf9,0x10 } },
+{  16, 0xf360, 0, {0x3e,0x40,0x0f,0x98,0x03,0xe6,0x04,0xe1,0x00,0x3e,0x40,0x2f,0x90,0x03,0xda,0x00 } },
+{  16, 0xf370, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0x81,0x10,0x48,0x10,0x32,0x08 } },
+{  16, 0xf380, 0, {0x0c,0x80,0x0f,0x21,0x02,0xc8,0x00,0x3a,0x04,0x0f,0x80,0x07,0x60,0x00,0xf8,0x40 } },
+{  16, 0xf390, 0, {0xb2,0x00,0x0f,0x84,0x0b,0x20,0x00,0xd8,0x00,0x36,0x10,0x0c,0x80,0x03,0xca,0x04 } },
+{  16, 0xf3a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x04,0x28,0x04,0x8e,0x80,0x23,0x80 } },
+{  16, 0xf3b0, 0, {0x08,0xa0,0x42,0x28,0x00,0x8a,0x00,0x23,0xa0,0x4b,0xa0,0x02,0xe8,0x00,0xba,0x00 } },
+{  16, 0xf3c0, 0, {0x76,0x80,0x0b,0xa0,0x02,0x08,0x00,0x8a,0x00,0x32,0x80,0x08,0xe0,0x03,0xca,0x00 } },
+{  16, 0xf3d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x82,0x00,0x20,0xd0 } },
+{  16, 0xf3e0, 0, {0x08,0x30,0x02,0x0c,0x00,0x9b,0x00,0x28,0xc0,0x1a,0xb0,0x02,0x6c,0x00,0xb3,0x02 } },
+{  16, 0xf3f0, 0, {0x20,0xc0,0x0b,0x30,0x02,0x0c,0x00,0xa3,0x00,0x22,0xc0,0x28,0x34,0x82,0xca,0x00 } },
+{  16, 0xf400, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1c,0x00,0x87,0x00,0x20,0xe0 } },
+{  16, 0xf410, 0, {0x08,0x78,0x02,0x0c,0x00,0x97,0x20,0x25,0xc0,0x0b,0x71,0x02,0xdc,0x81,0xb7,0x20 } },
+{  16, 0xf420, 0, {0x21,0xc0,0x0b,0x7a,0x42,0x3c,0x80,0x87,0x20,0x21,0xc0,0x08,0x70,0x02,0xe8,0x00 } },
+{  16, 0xf430, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x0e,0x82,0xc7,0x80,0xb1,0xe0 } },
+{  16, 0xf440, 0, {0x2c,0xfa,0x06,0x1e,0x08,0xd3,0xb1,0x39,0x60,0x4e,0x78,0x12,0x5e,0xa0,0xff,0xf0 } },
+{  16, 0xf450, 0, {0x21,0xe0,0x0f,0xf8,0x03,0x1f,0x08,0xe3,0xa0,0x33,0xe0,0x0c,0x68,0x03,0xea,0x02 } },
+{  16, 0xf460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x40,0xfb,0x00,0x3e,0xc0 } },
+{  16, 0xf470, 0, {0x0f,0xb2,0x03,0xed,0xa8,0xeb,0x10,0x3a,0x80,0x0f,0xb0,0xc3,0xec,0x40,0xfb,0x00 } },
+{  16, 0xf480, 0, {0x3e,0xc0,0x0f,0xb0,0x83,0xec,0x80,0xeb,0x70,0xbe,0xc4,0x0f,0xb0,0x03,0x82,0x06 } },
+{  16, 0xf490, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xce,0x80,0xb3,0x60 } },
+{  16, 0xf4a0, 0, {0x0f,0xfc,0x83,0x7e,0x20,0xef,0xb0,0x3b,0xe0,0x0f,0xb8,0x03,0x3e,0x00,0xcf,0x81 } },
+{  16, 0xf4b0, 0, {0x3f,0xe0,0x8f,0xf8,0x83,0xef,0x40,0xff,0xc2,0x33,0xe1,0x0c,0xf8,0x03,0xd0,0x00 } },
+{  16, 0xf4c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x82,0x87,0x18,0x21,0x80 } },
+{  16, 0xf4d0, 0, {0x0b,0x30,0x02,0x1c,0x60,0xd7,0x10,0x21,0xd0,0x0b,0x7b,0x02,0x3c,0x00,0xd7,0x00 } },
+{  16, 0xf4e0, 0, {0x2d,0xc0,0x0b,0x70,0x02,0xde,0x00,0xbf,0x00,0xa3,0xc4,0x08,0x70,0x03,0xaa,0x04 } },
+{  16, 0xf4f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0x11,0x87,0x00,0x21,0xc0 } },
+{  16, 0xf500, 0, {0x0b,0x30,0x02,0x1c,0x00,0x93,0x20,0x69,0xc0,0x0b,0x70,0x02,0x1c,0x00,0x87,0x00 } },
+{  16, 0xf510, 0, {0x2d,0xc0,0x0b,0x71,0x02,0xdc,0x20,0xb7,0x10,0x21,0xc0,0x08,0x60,0x02,0x84,0x00 } },
+{  16, 0xf520, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xcd,0x00,0x83,0x40,0x20,0xc0 } },
+{  16, 0xf530, 0, {0x4b,0x30,0x02,0x0c,0x01,0x83,0x00,0x20,0xc0,0x0b,0x30,0x02,0x0c,0x00,0x93,0x80 } },
+{  16, 0xf540, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x01,0xb3,0x00,0x20,0xc0,0x08,0x30,0x22,0x98,0x04 } },
+{  16, 0xf550, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbf,0x20,0xca,0xc0,0x32,0x80 } },
+{  16, 0xf560, 0, {0x0f,0xf0,0x03,0x3e,0x00,0x9f,0x00,0x3a,0x80,0x0f,0xf0,0x0b,0x3c,0x00,0xcf,0x98 } },
+{  16, 0xf570, 0, {0x3e,0xc0,0x0f,0xf6,0x03,0xff,0x00,0xff,0x00,0x31,0xe0,0x2c,0xb0,0x03,0xae,0x04 } },
+{  16, 0xf580, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xcc,0x80,0xfb,0x00,0x3e,0x50 } },
+{  16, 0xf590, 0, {0x0f,0xb0,0x03,0xac,0x02,0xfb,0x00,0x7e,0x50,0x0f,0xb0,0x03,0xec,0x00,0xfb,0x00 } },
+{  16, 0xf5a0, 0, {0x3e,0xc0,0x0f,0xb2,0x03,0xec,0x20,0xf3,0x00,0x3e,0xc6,0x0f,0x90,0x03,0xa0,0x00 } },
+{  16, 0xf5b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x02,0xcf,0x98,0x73,0xc8 } },
+{  16, 0xf5c0, 0, {0x0f,0x70,0x03,0x3c,0x00,0xff,0x00,0x33,0x28,0x0f,0xb0,0x02,0x1c,0x00,0x4f,0x00 } },
+{  16, 0xf5d0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x01,0x33,0xc0,0x0c,0xe4,0x03,0xe4,0x04 } },
+{  16, 0xf5e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x6c,0x00,0x83,0x80,0xa2,0xf8 } },
+{  16, 0xf5f0, 0, {0x0b,0xb0,0x42,0x2c,0x00,0xbb,0x00,0x32,0x10,0x0f,0xb0,0x03,0x6c,0x04,0xab,0x00 } },
+{  16, 0xf600, 0, {0x2e,0xc0,0x0b,0xb0,0x12,0xec,0x04,0xeb,0x00,0x22,0xc0,0x4a,0x94,0x82,0xe0,0x00 } },
+{  16, 0xf610, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x6c,0x00,0x8a,0x00,0x22,0x00 } },
+{  16, 0xf620, 0, {0x0b,0xb0,0x02,0x2c,0x00,0xb3,0x00,0xa2,0xc0,0x0b,0x30,0x02,0xac,0x00,0xab,0x04 } },
+{  16, 0xf630, 0, {0x2e,0xc0,0x0b,0xb0,0x42,0xec,0x00,0xbb,0x00,0x22,0xc0,0x08,0xb0,0x22,0xe0,0x00 } },
+{  16, 0xf640, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0c,0x00,0x8b,0x01,0x20,0x00 } },
+{  16, 0xf650, 0, {0x0b,0x30,0x06,0x0c,0x00,0xb3,0x00,0x20,0xc0,0x0a,0x32,0x0a,0xcc,0x00,0xa3,0x00 } },
+{  16, 0xf660, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x00,0xa3,0x00,0x22,0xc0,0x4a,0x00,0x12,0xc2,0x01 } },
+{  16, 0xf670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x6c,0x00,0x8b,0x04,0x22,0xc0 } },
+{  16, 0xf680, 0, {0x0f,0xf1,0x03,0x1c,0x00,0xff,0x04,0x32,0xc0,0x0b,0xf2,0x03,0xbc,0x00,0xef,0x00 } },
+{  16, 0xf690, 0, {0x3e,0xc0,0x07,0xf0,0x03,0xfc,0x80,0xff,0x00,0xb2,0xc0,0x0c,0xa0,0x03,0xe0,0x03 } },
+{  16, 0xf6a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xdc,0x00,0xf5,0x00,0x3f,0xc0 } },
+{  16, 0xf6b0, 0, {0x0f,0xf0,0x03,0xfc,0x01,0xff,0x02,0x3b,0xc0,0x0f,0xf1,0x03,0x7c,0x00,0xff,0x00 } },
+{  16, 0xf6c0, 0, {0x3f,0xc0,0x0f,0xf0,0x13,0xfc,0x40,0xef,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xe8,0x06 } },
+{  16, 0xf6d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xf2,0x40,0xcc,0x80,0x37,0x20 } },
+{  16, 0xf6e0, 0, {0x0c,0xd8,0x03,0xb0,0x44,0xfc,0x08,0x3f,0x0e,0x0f,0xc1,0x03,0xfc,0x00,0xcc,0x94 } },
+{  16, 0xf6f0, 0, {0x3f,0x0a,0x2e,0xc4,0x03,0x7d,0x80,0xcf,0x10,0x3f,0xc0,0x0f,0xc0,0x83,0x30,0x00 } },
+{  16, 0xf700, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0xe0,0x90,0x88,0x02,0x22,0x81 } },
+{  16, 0xf710, 0, {0x08,0x92,0x13,0xa4,0x40,0x3b,0x60,0x22,0x18,0x0b,0x81,0x02,0xfc,0xd4,0x81,0x00 } },
+{  16, 0xf720, 0, {0x3a,0xb0,0x0a,0x94,0x02,0x3d,0x40,0xaf,0x63,0x2f,0xdf,0x0b,0x98,0x00,0x20,0x04 } },
+{  16, 0xf730, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe0,0x00,0x88,0x00,0x20,0x40 } },
+{  16, 0xf740, 0, {0x88,0x30,0x82,0xc0,0x00,0xb0,0x08,0x28,0x80,0x0a,0x10,0x02,0xcc,0x20,0x80,0x01 } },
+{  16, 0xf750, 0, {0x2c,0x40,0x1b,0x06,0x02,0x8c,0x90,0x93,0x60,0x68,0xc0,0x4a,0x00,0x42,0x22,0x01 } },
+{  16, 0xf760, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xa0,0x02,0x88,0x00,0x22,0xc0 } },
+{  16, 0xf770, 0, {0x08,0xb0,0x02,0xe4,0x20,0xbb,0x88,0x26,0x98,0x0b,0x80,0x42,0xcc,0x18,0x8a,0x00 } },
+{  16, 0xf780, 0, {0x2e,0xc2,0x1b,0x98,0x02,0xac,0x00,0xab,0x00,0x2e,0xc0,0x0b,0x98,0x82,0x30,0x04 } },
+{  16, 0xf790, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0xe3,0xc0,0xcb,0x02,0x32,0x00 } },
+{  16, 0xf7a0, 0, {0x2c,0x80,0x03,0xae,0x08,0xb9,0x00,0x3e,0x70,0x0f,0xb9,0x03,0xec,0x02,0x48,0x48 } },
+{  16, 0xf7b0, 0, {0x3c,0xc0,0x0f,0x8c,0x93,0xec,0x00,0xdb,0x00,0x1a,0xc0,0x0e,0xac,0x03,0x10,0x04 } },
+{  16, 0xf7c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb2,0x00,0xff,0x00,0xbb,0x80 } },
+{  16, 0xf7d0, 0, {0x0f,0xc0,0x43,0xb6,0x40,0xbd,0x00,0x3b,0x60,0x0f,0xe8,0x03,0xfc,0x00,0xff,0x94 } },
+{  16, 0xf7e0, 0, {0x3b,0xe4,0x0e,0x60,0x0f,0x6c,0x08,0xef,0x01,0x3f,0xc0,0x0f,0x60,0x03,0xf8,0x00 } },
+{  16, 0xf7f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa1,0x00,0xfb,0x00,0x3e,0x60 } },
+{  16, 0xf800, 0, {0x0f,0xa0,0x03,0xed,0x00,0xf9,0x40,0x3a,0x00,0x0f,0x90,0x03,0xec,0x02,0xc9,0x04 } },
+{  16, 0xf810, 0, {0x32,0xd0,0x0f,0x90,0x03,0x2c,0x08,0xdb,0x00,0xb6,0xc0,0x0d,0xb4,0x03,0xd0,0x04 } },
+{  16, 0xf820, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x00,0x00,0xb3,0x89,0x2e,0xe0 } },
+{  16, 0xf830, 0, {0x0b,0xa4,0x03,0xa4,0x01,0xb9,0x00,0x2e,0x01,0x0b,0x90,0x42,0xfc,0x10,0x89,0x50 } },
+{  16, 0xf840, 0, {0xa2,0xc0,0x8d,0xb4,0x02,0x3c,0x44,0x8f,0x00,0x23,0xc0,0x08,0xb0,0x02,0xf2,0x00 } },
+{  16, 0xf850, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x04,0x0c,0x00,0xb0,0x80,0x2e,0x00 } },
+{  16, 0xf860, 0, {0x0b,0x12,0x02,0xc8,0x00,0xba,0x00,0x2c,0xc0,0x0b,0x20,0x02,0xcc,0x00,0xa2,0x00 } },
+{  16, 0xf870, 0, {0x20,0x00,0x2b,0x2d,0x9a,0x2e,0x42,0x83,0x00,0x28,0xc0,0x08,0x20,0x02,0xf8,0x00 } },
+{  16, 0xf880, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x1e,0x04,0xb4,0x80,0x2d,0xa0 } },
+{  16, 0xf890, 0, {0x0b,0x58,0x02,0x92,0x00,0xb6,0x80,0x2d,0xe0,0x0b,0x68,0x02,0xde,0x40,0xa6,0x80 } },
+{  16, 0xf8a0, 0, {0x21,0x24,0x29,0x48,0x02,0x1e,0x80,0x87,0x80,0x69,0xe0,0x08,0x61,0x02,0xc8,0x00 } },
+{  16, 0xf8b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x18,0x0c,0x00,0xf0,0x30,0x3c,0x4c } },
+{  16, 0xf8c0, 0, {0x0f,0x32,0x03,0xc8,0x80,0xb2,0x00,0x38,0x80,0x0f,0x1b,0x03,0xec,0x00,0xe0,0x30 } },
+{  16, 0xf8d0, 0, {0x30,0x04,0x0f,0xb1,0x03,0x0e,0x85,0xcb,0x00,0x3a,0xc0,0x0c,0x31,0x03,0xd2,0x02 } },
+{  16, 0xf8e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1c,0xbc,0x00,0xfc,0x11,0x3f,0xc4 } },
+{  16, 0xf8f0, 0, {0x0f,0xb8,0x13,0xb0,0x04,0xfe,0x02,0x3f,0x80,0x0f,0xc0,0x03,0xfd,0x00,0xdf,0x12 } },
+{  16, 0xf900, 0, {0x1d,0x04,0x0f,0xd0,0x43,0xbc,0x01,0xef,0x10,0x33,0xc4,0x0e,0xf3,0x03,0xd0,0x06 } },
+{  16, 0xf910, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xee,0x00,0xcb,0x00,0x3e,0x00 } },
+{  16, 0xf920, 0, {0x0f,0x80,0x03,0x28,0x00,0xf8,0x00,0x3e,0x40,0x3d,0xb0,0x03,0xef,0x08,0xc9,0x00 } },
+{  16, 0xf930, 0, {0x3a,0x00,0x0c,0xa0,0x03,0xec,0x98,0xfb,0x20,0x32,0xd2,0x0c,0xa8,0x03,0x2a,0x02 } },
+{  16, 0xf940, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0x87,0x01,0x2d,0x80 } },
+{  16, 0xf950, 0, {0x0b,0x40,0x42,0x1c,0x04,0x37,0x00,0xa1,0x40,0x08,0x60,0x02,0xcc,0x80,0x87,0x00 } },
+{  16, 0xf960, 0, {0x2d,0x80,0x2e,0x70,0x02,0xdc,0xa9,0xb7,0x28,0x21,0xd0,0x08,0x70,0x02,0x12,0x00 } },
+{  16, 0xf970, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xbe,0x02,0x87,0x80,0x2d,0x60 } },
+{  16, 0xf980, 0, {0x4b,0xe8,0x02,0x5a,0x01,0xb4,0x88,0x28,0xe0,0x88,0x78,0xc2,0xde,0x52,0x86,0xc0 } },
+{  16, 0xf990, 0, {0x29,0x60,0x08,0x68,0x02,0xde,0x40,0xb3,0x92,0xe1,0xe8,0x28,0x28,0x02,0x70,0x00 } },
+{  16, 0xf9a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x14,0xcc,0x00,0x8b,0x80,0x2e,0xc0 } },
+{  16, 0xf9b0, 0, {0x0b,0x20,0x02,0x4d,0x80,0x9b,0x20,0x20,0xe0,0x08,0x38,0x02,0xcc,0x00,0x83,0x80 } },
+{  16, 0xf9c0, 0, {0x2c,0xc0,0x0a,0xb0,0x02,0xcc,0x08,0xb3,0x00,0x20,0xc0,0x08,0x31,0x02,0x52,0x04 } },
+{  16, 0xf9d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0xa8,0x00,0xca,0xe0,0x3e,0x80 } },
+{  16, 0xf9e0, 0, {0x1f,0xa4,0x0b,0x79,0x00,0xfe,0x00,0x3f,0x82,0x1d,0xe0,0x03,0xe8,0x00,0xce,0x40 } },
+{  16, 0xf9f0, 0, {0x3b,0x88,0x2c,0xe4,0x03,0xe8,0x01,0xfa,0x00,0x32,0x80,0x0c,0xe8,0x03,0x7a,0x04 } },
+{  16, 0xfa00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0xa0,0x00,0xf8,0x09,0x3e,0x00 } },
+{  16, 0xfa10, 0, {0x8f,0xc0,0x83,0xa0,0x18,0xf8,0x00,0x3c,0x20,0x0f,0x88,0x03,0xe0,0x00,0xf8,0x08 } },
+{  16, 0xfa20, 0, {0x3e,0x20,0x0e,0x80,0x83,0xe1,0x01,0xf0,0x00,0x3c,0x00,0x0f,0x80,0x0b,0x92,0x00 } },
+{  16, 0xfa30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa4,0x00,0xf9,0x42,0x32,0x40 } },
+{  16, 0xfa40, 0, {0x4c,0x98,0x03,0x04,0x00,0xc9,0x00,0x3a,0x40,0x0f,0x90,0x23,0x24,0x00,0xb9,0x81 } },
+{  16, 0xfa50, 0, {0x3c,0x40,0x0c,0x92,0x03,0x24,0x00,0xf9,0x05,0x32,0x40,0x6c,0x90,0xc3,0xc2,0x04 } },
+{  16, 0xfa60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x24,0x14,0xb9,0x00,0xa2,0x54 } },
+{  16, 0xfa70, 0, {0x08,0x9b,0x1a,0x24,0x02,0x89,0x00,0x22,0x40,0x28,0x90,0x02,0xa4,0x00,0xb9,0x90 } },
+{  16, 0xfa80, 0, {0x2e,0x40,0x28,0x9c,0x82,0x25,0x04,0xb9,0x00,0x22,0x40,0x08,0x98,0x12,0xe0,0x00 } },
+{  16, 0xfa90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xad,0x00,0x23,0x40 } },
+{  16, 0xfaa0, 0, {0x08,0x50,0x02,0x64,0x00,0x89,0x00,0x2a,0x40,0x08,0x10,0x02,0x64,0x00,0xb9,0x00 } },
+{  16, 0xfab0, 0, {0x6e,0x40,0x08,0x90,0x02,0x25,0x00,0xa9,0x00,0x22,0x40,0x08,0x91,0x06,0xc6,0x00 } },
+{  16, 0xfac0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x14,0x00,0xb5,0x10,0xa1,0x44 } },
+{  16, 0xfad0, 0, {0x28,0x50,0x02,0x44,0x80,0x81,0x30,0x20,0x48,0x08,0x12,0x02,0x84,0x40,0xb1,0x80 } },
+{  16, 0xfae0, 0, {0x6c,0xc8,0x08,0x12,0x02,0x04,0x80,0xb1,0x34,0x20,0x48,0x08,0x12,0x02,0xc2,0x01 } },
+{  16, 0xfaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xe8,0x40,0x32,0x90 } },
+{  16, 0xfb00, 0, {0x0c,0xc5,0x03,0x61,0x40,0xc0,0x40,0x3a,0x14,0x0f,0x85,0x03,0x21,0xb0,0xf8,0x50 } },
+{  16, 0xfb10, 0, {0x3e,0x00,0x0c,0x85,0x03,0x21,0x40,0xf8,0x40,0xb0,0x14,0x0c,0x80,0x03,0xee,0x01 } },
+{  16, 0xfb20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x1d,0xc4,0x04,0xf9,0x22,0x0e,0x48 } },
+{  16, 0xfb30, 0, {0x0f,0x10,0x13,0xb4,0x40,0xfd,0x30,0x3f,0x44,0x4f,0xd1,0x00,0xe4,0x84,0xff,0x01 } },
+{  16, 0xfb40, 0, {0x3d,0x44,0x0f,0xd1,0x0b,0xe4,0x40,0xf9,0x30,0x3e,0x44,0x0f,0xd1,0x03,0xe6,0x04 } },
+{  16, 0xfb50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x05,0xe4,0x00,0xdd,0x40,0x3f,0x50 } },
+{  16, 0xfb60, 0, {0x0c,0xd0,0x03,0x2c,0x00,0xc9,0x00,0x36,0x40,0x0f,0x90,0x13,0x27,0x04,0xf5,0x01 } },
+{  16, 0xfb70, 0, {0x37,0x40,0x0c,0xf0,0x03,0xf6,0x20,0xf9,0xa8,0x32,0x68,0x0c,0xd0,0x03,0xc6,0x00 } },
+{  16, 0xfb80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xe0,0x00,0x88,0xa0,0x2e,0x28 } },
+{  16, 0xfb90, 0, {0x28,0x80,0x02,0x20,0x00,0x88,0xa0,0x22,0x00,0x0b,0x80,0x0a,0x62,0x80,0xb8,0x00 } },
+{  16, 0xfba0, 0, {0x22,0x00,0x08,0x80,0x02,0xe1,0x00,0xb8,0xe0,0x22,0x3a,0x08,0xa0,0x02,0xce,0x04 } },
+{  16, 0xfbb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x84,0x02,0x81,0x00,0x2e,0x40 } },
+{  16, 0xfbc0, 0, {0x08,0x10,0x0a,0x44,0x02,0x81,0x08,0x24,0x40,0x0a,0x10,0x02,0x45,0x80,0xb9,0x00 } },
+{  16, 0xfbd0, 0, {0x24,0x40,0x29,0x10,0x02,0xc4,0x00,0xb1,0x08,0x24,0x44,0x08,0x10,0x02,0xc2,0x01 } },
+{  16, 0xfbe0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x14,0xa4,0x04,0x89,0x01,0x2e,0x50 } },
+{  16, 0xfbf0, 0, {0x48,0xb2,0x02,0x64,0x00,0x91,0x00,0x22,0x46,0x0b,0x90,0x02,0x64,0x00,0xb9,0x01 } },
+{  16, 0xfc00, 0, {0x26,0xc0,0x09,0xb0,0x12,0xe4,0x00,0xb1,0x00,0x26,0x40,0x08,0x90,0x02,0xc6,0x04 } },
+{  16, 0xfc10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x04,0xe4,0x00,0xc9,0x00,0x3c,0x40 } },
+{  16, 0xfc20, 0, {0x0c,0x90,0x03,0x64,0x00,0xc9,0x02,0x36,0x50,0x0e,0x93,0x03,0x24,0x00,0xf9,0x90 } },
+{  16, 0xfc30, 0, {0x36,0x48,0x0d,0x94,0x83,0xe4,0x08,0xf9,0x00,0xb6,0x40,0x0c,0x94,0x03,0xe8,0x04 } },
+{  16, 0xfc40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0xa4,0x00,0xe9,0x00,0x3e,0x40 } },
+{  16, 0xfc50, 0, {0x0f,0x90,0x13,0xa4,0x00,0xe9,0x02,0x2e,0x61,0x05,0x90,0x03,0xa4,0x00,0xf9,0x00 } },
+{  16, 0xfc60, 0, {0x3a,0x40,0x0e,0x90,0x43,0xe4,0x10,0xf9,0x00,0x38,0x40,0x2f,0x90,0x03,0xca,0x00 } },
+{  16, 0xfc70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x01,0x32,0x04 } },
+{  16, 0xfc80, 0, {0x0f,0x80,0x43,0xc0,0x01,0xc8,0x00,0xb2,0x01,0x0c,0x80,0x03,0x20,0x00,0xc8,0x40 } },
+{  16, 0xfc90, 0, {0x30,0x00,0x8c,0x84,0x83,0xe0,0x00,0xc8,0x00,0x32,0x00,0x6c,0x84,0x03,0xca,0x04 } },
+{  16, 0xfca0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x28,0x00,0xba,0x00,0x23,0x80 } },
+{  16, 0xfcb0, 0, {0x0b,0xea,0x02,0xe8,0x00,0xaa,0x00,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0x86,0x20 } },
+{  16, 0xfcc0, 0, {0x37,0xa0,0x8d,0xe4,0x02,0xf8,0x00,0xda,0x00,0x22,0x80,0x08,0xa0,0x02,0xca,0x00 } },
+{  16, 0xfcd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x6c,0x00,0xb3,0x00,0x20,0xc0 } },
+{  16, 0xfce0, 0, {0x0b,0xb8,0x02,0x4c,0x04,0x83,0x00,0x20,0xc0,0x08,0xb0,0x02,0x0c,0x02,0x83,0x00 } },
+{  16, 0xfcf0, 0, {0x20,0x40,0x28,0x34,0x02,0xce,0x90,0x83,0x00,0xa0,0xc0,0x08,0x30,0x02,0xca,0x00 } },
+{  16, 0xfd00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1c,0xc0,0xb5,0x88,0x21,0x40 } },
+{  16, 0xfd10, 0, {0x0b,0x70,0x02,0xdc,0x80,0xa3,0x20,0x21,0xe0,0x48,0x32,0x42,0x0e,0x90,0x8e,0x01 } },
+{  16, 0xfd20, 0, {0x65,0x50,0x09,0x70,0x02,0xde,0x20,0x93,0x21,0x21,0xc0,0x08,0x70,0x02,0xe8,0x00 } },
+{  16, 0xfd30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x18,0x1e,0x00,0xff,0x80,0xb1,0xa0 } },
+{  16, 0xfd40, 0, {0x0f,0x48,0x02,0x7e,0x00,0x87,0xa0,0x33,0xe0,0x28,0x7a,0x0b,0x1f,0x00,0xc4,0x80 } },
+{  16, 0xfd50, 0, {0x31,0x60,0x8c,0x58,0x03,0xfe,0x00,0xc7,0xc8,0x33,0xe8,0x0c,0x58,0x03,0xea,0x02 } },
+{  16, 0xfd60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xff,0x00,0x3e,0x00 } },
+{  16, 0xfd70, 0, {0x0f,0x90,0x23,0xec,0xa0,0xfb,0x40,0x3e,0xc0,0x8f,0xb5,0x03,0xed,0x80,0xf8,0x00 } },
+{  16, 0xfd80, 0, {0x3c,0x40,0x0f,0xb0,0x03,0xe8,0x00,0xfb,0x02,0x3e,0xd0,0x0f,0x90,0x03,0xc2,0x06 } },
+{  16, 0xfd90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x04,0xbe,0x00,0xff,0x80,0x3f,0xe0 } },
+{  16, 0xfda0, 0, {0x0f,0xd9,0x03,0xfe,0x20,0xcf,0xc8,0x33,0xea,0x8f,0xfc,0x03,0x3f,0x00,0xfd,0x80 } },
+{  16, 0xfdb0, 0, {0x3f,0x60,0x0e,0xe8,0x03,0xf2,0x00,0xcf,0x80,0x2f,0xfe,0x0c,0x78,0x03,0x00,0x00 } },
+{  16, 0xfdc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x00,0x9c,0x00,0xb5,0x02,0x2d,0xc0 } },
+{  16, 0xfdd0, 0, {0x0b,0x58,0x42,0xdc,0x80,0xcf,0x00,0x21,0xc1,0x0b,0x30,0x12,0x1c,0x40,0xb4,0x02 } },
+{  16, 0xfde0, 0, {0x2d,0x46,0x08,0x71,0x12,0xc8,0x00,0xe7,0x00,0x2d,0xc4,0x08,0x70,0x03,0x6a,0x04 } },
+{  16, 0xfdf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x00,0x2d,0x02 } },
+{  16, 0xfe00, 0, {0x0b,0x46,0x02,0xdc,0x08,0x97,0x00,0x21,0xc9,0x0a,0x30,0x22,0x1c,0x00,0xb4,0x00 } },
+{  16, 0xfe10, 0, {0x2d,0x40,0x0a,0x50,0x82,0xc4,0x00,0xb7,0x00,0x2c,0xc8,0x28,0x50,0x02,0x40,0x10 } },
+{  16, 0xfe20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x14,0x8c,0x18,0xb3,0x00,0x2e,0x20 } },
+{  16, 0xfe30, 0, {0x0b,0x18,0x02,0xcf,0x4a,0x83,0xc2,0x20,0xc1,0x0b,0x34,0x22,0x0c,0x04,0xb8,0x58 } },
+{  16, 0xfe40, 0, {0x2c,0x40,0x0b,0x28,0x02,0xc8,0x00,0xa3,0x00,0x2c,0xc0,0x08,0x14,0x02,0x48,0x04 } },
+{  16, 0xfe50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xbc,0x00,0xfb,0x00,0x3e,0x80 } },
+{  16, 0xfe60, 0, {0x0f,0xa0,0x02,0xfc,0x00,0xdf,0xa0,0xb3,0xc0,0x0e,0xf0,0x0b,0x3c,0x00,0xfb,0xc0 } },
+{  16, 0xfe70, 0, {0x3c,0xa0,0x0e,0xbd,0x03,0xec,0x00,0xff,0x00,0x3f,0xc0,0x0c,0x30,0x03,0x6a,0x04 } },
+{  16, 0xfe80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0xec,0x00,0xf9,0x00,0x3e,0x01 } },
+{  16, 0xfe90, 0, {0x8f,0xb1,0x43,0xec,0x00,0xf3,0x00,0x3e,0xc0,0x4f,0xb0,0x13,0xec,0x00,0xfb,0x00 } },
+{  16, 0xfea0, 0, {0x3e,0x80,0x0c,0x84,0x03,0xe1,0x00,0x73,0x00,0x3e,0xc1,0x0f,0xb2,0x43,0xe0,0x00 } },
+{  16, 0xfeb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x50,0xfc,0x10,0xff,0x80,0x37,0xc0 } },
+{  16, 0xfec0, 0, {0x0c,0xe0,0x03,0xfc,0x20,0xff,0x08,0x33,0xc0,0x0f,0xf0,0x83,0xbc,0x00,0xff,0x00 } },
+{  16, 0xfed0, 0, {0x33,0xc0,0x2e,0x40,0x03,0x1c,0x01,0xcf,0x00,0x11,0xc0,0x4c,0xd0,0x03,0x00,0x44 } },
+{  16, 0xfee0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x04,0xb3,0x02,0x22,0x72 } },
+{  16, 0xfef0, 0, {0x08,0xa1,0x16,0xec,0x00,0xbb,0x04,0x22,0xc0,0x0b,0xb0,0x42,0xec,0x00,0xba,0x19 } },
+{  16, 0xff00, 0, {0xb6,0xd0,0x08,0x9c,0x4a,0x26,0x80,0xdb,0x00,0x22,0xc0,0x08,0x90,0x03,0x60,0x40 } },
+{  16, 0xff10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xb9,0x10,0x62,0x20 } },
+{  16, 0xff20, 0, {0x48,0xa0,0x02,0xec,0x00,0xbb,0x00,0x22,0xc0,0x0b,0xb0,0x02,0xec,0x10,0xbb,0x00 } },
+{  16, 0xff30, 0, {0x66,0x08,0x0a,0xa8,0x12,0x26,0x10,0x9b,0x00,0x2a,0xc0,0x28,0xb0,0x26,0x20,0x00 } },
+{  16, 0xff40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0c,0x00,0xb9,0x00,0x20,0x00 } },
+{  16, 0xff50, 0, {0x08,0x32,0x02,0xcc,0x04,0xb3,0x00,0x20,0xc0,0x4b,0x30,0x02,0xcc,0x00,0xb3,0x00 } },
+{  16, 0xff60, 0, {0x20,0x00,0x08,0x00,0x02,0x01,0x00,0x93,0x00,0x28,0xc0,0x08,0x30,0x06,0x42,0x11 } },
+{  16, 0xff70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x6c,0x00,0xf9,0x00,0xb2,0x40 } },
+{  16, 0xff80, 0, {0x0c,0x82,0x02,0xdc,0x01,0xff,0x00,0xb2,0xc0,0x0b,0xf1,0x03,0xbc,0x00,0xf9,0x00 } },
+{  16, 0xff90, 0, {0x26,0x40,0x2e,0x80,0x03,0x21,0x04,0xcf,0x00,0xbb,0xc0,0x0c,0x90,0x03,0x00,0x03 } },
+{  16, 0xffa0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xfd,0x00,0x3f,0x40 } },
+{  16, 0xffb0, 0, {0x0f,0x81,0x03,0xfc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x23,0xfc,0x00,0xfc,0x00 } },
+{  16, 0xffc0, 0, {0x2d,0x40,0x2f,0xc0,0x03,0xf0,0x88,0xff,0x00,0x37,0xc0,0x8f,0xd0,0x03,0xe8,0x02 } },
+{  16, 0xffd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x40,0xff,0x80,0x33,0xc2 } },
+{  16, 0xffe0, 0, {0x0c,0xf8,0x03,0x7c,0xa0,0xff,0x90,0x3f,0xc4,0x2c,0xb4,0x03,0xbc,0x80,0xcf,0x40 } },
+{  16, 0xfff0, 0, {0x37,0xe0,0x0f,0xf1,0x93,0x6e,0x44,0xbf,0x30,0x3f,0x20,0x2c,0xf8,0x63,0xf0,0x04 } },
+{  16, 0x8010, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0x00,0xeb,0x20,0x23,0xf0 } },
+{  16, 0x8020, 0, {0x08,0xb8,0x52,0x3d,0x00,0xb3,0x00,0x2e,0xdc,0x08,0xf4,0x42,0x1c,0x42,0x8b,0x40 } },
+{  16, 0x8030, 0, {0x22,0xc8,0x0b,0xf6,0x03,0x6c,0x88,0xbb,0x30,0x2e,0x00,0x08,0xb2,0x02,0xe0,0x04 } },
+{  16, 0x8040, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xbb,0x08,0x20,0xc0 } },
+{  16, 0x8050, 0, {0x08,0x30,0x02,0x4c,0xa0,0xb3,0x20,0x26,0x80,0x88,0x36,0x02,0xcc,0xa0,0x93,0x60 } },
+{  16, 0x8060, 0, {0xa4,0xc2,0x0a,0x32,0x42,0x4c,0x90,0xb3,0x20,0x2c,0x0b,0x88,0x30,0x82,0xe2,0x01 } },
+{  16, 0x8070, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x08,0xbb,0x22,0xa2,0xc0 } },
+{  16, 0x8080, 0, {0x08,0xb0,0x02,0x2c,0x00,0xbb,0x00,0x2e,0x90,0x08,0xb0,0x02,0xec,0x00,0x9b,0x00 } },
+{  16, 0x8090, 0, {0x22,0xc0,0x0b,0xb0,0x02,0x6c,0x00,0xbb,0x02,0x2e,0x20,0x08,0xb0,0x02,0xf0,0x00 } },
+{  16, 0x80a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xb1,0x83,0x32,0xc0 } },
+{  16, 0x80b0, 0, {0x0c,0x1a,0x03,0x6c,0x10,0xfb,0x00,0x34,0xc0,0x0c,0xb0,0x03,0xec,0x08,0xda,0x00 } },
+{  16, 0x80c0, 0, {0x36,0xc0,0x0e,0xb0,0x0b,0x6c,0x00,0xfb,0x00,0x3e,0x28,0x0c,0xb0,0x02,0xd0,0x00 } },
+{  16, 0x80d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbc,0x00,0xed,0x80,0x3f,0xc0 } },
+{  16, 0x80e0, 0, {0x0f,0xd4,0x03,0xec,0x00,0xff,0x00,0x3f,0xc8,0x0f,0xb0,0x03,0x3c,0x00,0xee,0x40 } },
+{  16, 0x80f0, 0, {0x3f,0xc0,0x0f,0x70,0x03,0xfc,0x00,0xff,0x00,0x3f,0x80,0x0f,0xf0,0x03,0xf8,0x00 } },
+{  16, 0x8100, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x20,0xb0,0xc0 } },
+{  16, 0x8110, 0, {0x0f,0xb4,0x03,0xac,0x02,0xcb,0x00,0x32,0x90,0x0e,0xb0,0x03,0x6c,0x00,0xeb,0x00 } },
+{  16, 0x8120, 0, {0x3a,0xc0,0x0c,0xb0,0x02,0xec,0x00,0xfb,0x00,0x3e,0x91,0x0f,0xb0,0x03,0x90,0x00 } },
+{  16, 0x8130, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xbb,0x80,0x23,0xd7 } },
+{  16, 0x8140, 0, {0x0b,0x90,0x02,0x3c,0x14,0x8b,0x00,0x6a,0x08,0x28,0xf0,0x00,0xbc,0x00,0x83,0x00 } },
+{  16, 0x8150, 0, {0xbe,0xc0,0x88,0xf0,0x13,0x2c,0x00,0xef,0x00,0x2e,0x80,0x0b,0xb0,0x07,0xb2,0x00 } },
+{  16, 0x8160, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb3,0x40,0x20,0xd0 } },
+{  16, 0x8170, 0, {0x0b,0x28,0x02,0x8c,0x00,0x83,0x01,0x20,0xc0,0x1a,0xb8,0x00,0x6c,0x10,0xa1,0x00 } },
+{  16, 0x8180, 0, {0x68,0xc0,0x2a,0x30,0x02,0x8c,0x00,0xb3,0x02,0x2e,0x00,0x4b,0x30,0x02,0xf8,0x04 } },
+{  16, 0x8190, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x00,0xb7,0xa0,0x21,0xe0 } },
+{  16, 0x81a0, 0, {0x0b,0xec,0xc2,0x1e,0x04,0x87,0x80,0x29,0xe4,0x08,0x79,0x82,0x9e,0x40,0xaf,0x90 } },
+{  16, 0x81b0, 0, {0x29,0xe0,0x0a,0x38,0x00,0x1e,0x00,0xa7,0x90,0x2d,0x24,0x0b,0x78,0x02,0x88,0x00 } },
+{  16, 0x81c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x50,0xfb,0x09,0x30,0xc0 } },
+{  16, 0x81d0, 0, {0x0f,0x20,0x02,0x8c,0x40,0xc3,0x00,0x20,0xc0,0x0a,0x38,0x03,0x4c,0x44,0xe1,0x00 } },
+{  16, 0x81e0, 0, {0xaa,0xc0,0x0e,0x31,0x43,0x8e,0x00,0xf3,0x00,0x3c,0x00,0x0f,0x30,0x03,0xd2,0x02 } },
+{  16, 0x81f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x4d,0xbc,0x00,0xff,0x20,0x3f,0xd0 } },
+{  16, 0x8200, 0, {0x4f,0x70,0x03,0xfc,0x00,0xff,0x00,0x3d,0xc0,0x0f,0xf3,0x43,0xfc,0x40,0xd7,0x00 } },
+{  16, 0x8210, 0, {0xbf,0xc0,0x0d,0xf4,0xc3,0xfc,0x40,0xff,0x00,0x3f,0x40,0x0f,0xf0,0x03,0xd0,0x06 } },
+{  16, 0x8220, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xfb,0x00,0x32,0xd0 } },
+{  16, 0x8230, 0, {0x0d,0x90,0x01,0xed,0xc0,0xfb,0x00,0x3e,0xc0,0x1f,0xba,0x03,0xac,0xc0,0xc8,0x00 } },
+{  16, 0x8240, 0, {0x32,0xe0,0x8d,0xb4,0x43,0xec,0x00,0xfb,0x00,0x36,0xa0,0x0c,0xb0,0x03,0x6a,0x00 } },
+{  16, 0x8250, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0xb7,0x00,0x21,0xc8 } },
+{  16, 0x8260, 0, {0x08,0x60,0x02,0xdc,0x20,0xb7,0x00,0x2d,0xc0,0x0f,0x74,0xa2,0x1c,0x28,0xd6,0x00 } },
+{  16, 0x8270, 0, {0x35,0xc0,0x08,0x72,0x02,0x5c,0x08,0xb7,0x44,0xa1,0x80,0x48,0x70,0x02,0x12,0x00 } },
+{  16, 0x8280, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0x80,0x20,0xe4 } },
+{  16, 0x8290, 0, {0x09,0x78,0x26,0xde,0x00,0xb7,0x80,0x2d,0xe2,0x0a,0x70,0x12,0x8c,0x88,0x81,0x80 } },
+{  16, 0x82a0, 0, {0x21,0xe0,0x09,0x78,0x02,0xde,0x00,0xb3,0xa0,0x25,0xa0,0x28,0x78,0x02,0x70,0x04 } },
+{  16, 0x82b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x01,0xbb,0x80,0x20,0xc0 } },
+{  16, 0x82c0, 0, {0x08,0x30,0x42,0xec,0x00,0xb3,0x00,0x2c,0xc0,0x0a,0x30,0x22,0x0c,0x00,0x93,0x00 } },
+{  16, 0x82d0, 0, {0x24,0xc1,0x08,0x30,0x02,0xcc,0x00,0xb3,0x00,0x20,0xe0,0x08,0xb0,0x02,0x12,0x04 } },
+{  16, 0x82e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x08,0xb2,0x80 } },
+{  16, 0x82f0, 0, {0x0d,0xe2,0x03,0xe8,0x00,0xfa,0x00,0x3f,0x80,0x0a,0xa0,0x03,0xa8,0x00,0xce,0x50 } },
+{  16, 0x8300, 0, {0x32,0x80,0x05,0xa0,0x03,0xe8,0x00,0xfa,0x00,0x37,0xa8,0x0c,0xa0,0x03,0x7a,0x04 } },
+{  16, 0x8310, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x60,0x08,0xf8,0x00,0x3c,0x00 } },
+{  16, 0x8320, 0, {0x0f,0x88,0x01,0xe0,0x00,0xf8,0x04,0x3c,0x00,0x4f,0x00,0x13,0xc0,0x00,0xf8,0x00 } },
+{  16, 0x8330, 0, {0x3e,0x00,0x0f,0x80,0x03,0x60,0x00,0xf8,0x02,0x3e,0x01,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0x8340, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x90,0x12,0x40 } },
+{  16, 0x8350, 0, {0x0c,0x90,0x03,0xa4,0x00,0xc9,0x00,0x3e,0x70,0x0e,0x94,0x33,0x24,0x08,0xc9,0x00 } },
+{  16, 0x8360, 0, {0x2a,0x40,0x0b,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3a,0x40,0x0f,0x90,0x03,0x02,0x04 } },
+{  16, 0x8370, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x42,0x22,0x60 } },
+{  16, 0x8380, 0, {0x08,0x10,0x02,0x24,0x00,0x89,0x03,0x2e,0x40,0x08,0x90,0x02,0xa4,0x01,0x81,0x04 } },
+{  16, 0x8390, 0, {0x3e,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x02,0x22,0x40,0x0e,0x90,0x02,0x20,0x00 } },
+{  16, 0x83a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x40,0x2a,0x4a } },
+{  16, 0x83b0, 0, {0x08,0x91,0x02,0xa4,0x00,0x89,0x00,0x2e,0x40,0x1a,0x90,0x0a,0x24,0x04,0x89,0x00 } },
+{  16, 0x83c0, 0, {0x2a,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb1,0x00,0x2a,0x40,0x0b,0x90,0x02,0x06,0x00 } },
+{  16, 0x83d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0xb1,0x01,0xa8,0x48 } },
+{  16, 0x83e0, 0, {0x88,0x90,0x02,0x04,0x80,0x81,0x40,0x2c,0x50,0x18,0x14,0x0a,0x84,0x10,0x89,0x40 } },
+{  16, 0x83f0, 0, {0x2c,0x40,0x0b,0x10,0x02,0xc4,0x00,0x31,0x20,0x20,0x40,0x0a,0x10,0x0a,0x02,0x01 } },
+{  16, 0x8400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf0,0x50,0x3a,0x00 } },
+{  16, 0x8410, 0, {0x2c,0xa0,0x02,0xa1,0x42,0xc8,0x00,0x3e,0x00,0xde,0x00,0x23,0x21,0x42,0x88,0x00 } },
+{  16, 0x8420, 0, {0x38,0x14,0x0f,0x85,0x03,0xe1,0x40,0xf8,0x50,0x38,0x14,0x0f,0x05,0x03,0x2e,0x01 } },
+{  16, 0x8430, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x08,0xfd,0x00,0x36,0x44 } },
+{  16, 0x8440, 0, {0x0f,0xd0,0x03,0x64,0x40,0xf9,0x00,0x3d,0x50,0x0f,0x94,0x03,0xe5,0x00,0x7d,0x40 } },
+{  16, 0x8450, 0, {0x3e,0x40,0x0f,0x94,0x03,0xe4,0x00,0xf9,0x10,0x3f,0x40,0x0e,0x90,0x03,0xe6,0x04 } },
+{  16, 0x8460, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe4,0x00,0xfd,0x40,0x33,0x68 } },
+{  16, 0x8470, 0, {0x0c,0xd0,0x03,0xe7,0x81,0xf9,0x00,0x33,0x78,0x0d,0xd8,0x13,0x26,0xa0,0xcd,0xa0 } },
+{  16, 0x8480, 0, {0x32,0x40,0x0d,0x9b,0x03,0x24,0x00,0xf9,0xa0,0x3c,0x44,0x2c,0x90,0x07,0x86,0x00 } },
+{  16, 0x8490, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x00,0xb8,0xa0,0xa2,0x10 } },
+{  16, 0x84a0, 0, {0x18,0x80,0x03,0x82,0x84,0xb8,0x80,0x36,0x2c,0x2e,0x0f,0x02,0xa3,0xa0,0xd8,0xe0 } },
+{  16, 0x84b0, 0, {0x36,0x22,0x8b,0x08,0x03,0x42,0xa0,0xf8,0xe0,0x2e,0x28,0x08,0x88,0x02,0xce,0x04 } },
+{  16, 0x84c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0xa0,0x50 } },
+{  16, 0x84d0, 0, {0x28,0x30,0x02,0xc5,0x80,0xb1,0x08,0x20,0x40,0x09,0x10,0xa2,0x44,0x08,0x81,0x48 } },
+{  16, 0x84e0, 0, {0x20,0x40,0x0b,0x14,0x02,0x04,0x80,0xb1,0x38,0x2c,0x48,0x08,0x12,0x82,0x82,0x01 } },
+{  16, 0x84f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x00,0xb1,0x00,0x22,0x40 } },
+{  16, 0x8500, 0, {0x08,0x92,0x02,0xe4,0x00,0xb9,0x02,0x26,0x58,0x4a,0x90,0x02,0xe4,0x08,0x99,0x40 } },
+{  16, 0x8510, 0, {0x26,0x40,0x0b,0x90,0x02,0x64,0x08,0xb9,0x01,0x2c,0x48,0x08,0x90,0x12,0xc6,0x04 } },
+{  16, 0x8520, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x80,0x32,0x40 } },
+{  16, 0x8530, 0, {0x08,0x98,0x83,0xe4,0x04,0xb9,0x01,0x30,0x40,0x0d,0x90,0x0b,0x64,0x02,0xc9,0x00 } },
+{  16, 0x8540, 0, {0x32,0x40,0x0f,0x90,0x03,0x24,0x00,0xf9,0x00,0x1e,0x58,0x0c,0x90,0x03,0xa8,0x04 } },
+{  16, 0x8550, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x20,0x3c,0x40 } },
+{  16, 0x8560, 0, {0x0f,0x98,0x03,0xa4,0x00,0xb9,0x00,0x3e,0x42,0x8e,0x10,0x4b,0x84,0x04,0xf9,0x00 } },
+{  16, 0x8570, 0, {0x3e,0x40,0x8f,0x90,0x03,0xe4,0x00,0xe9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xca,0x00 } },
+{  16, 0x8580, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x00,0x32,0x08 } },
+{  16, 0x8590, 0, {0x0f,0x84,0x83,0xa0,0x04,0xc8,0x04,0x3e,0x00,0x83,0x80,0x01,0x20,0x00,0xc0,0x00 } },
+{  16, 0x85a0, 0, {0x32,0x00,0x0f,0x00,0x03,0xa0,0x00,0xc8,0x00,0x32,0x10,0x4e,0x80,0x13,0xca,0x04 } },
+{  16, 0x85b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8e,0x90,0xa3,0x80 } },
+{  16, 0x85c0, 0, {0x0b,0xe4,0x02,0x28,0x00,0xca,0x00,0x2f,0x80,0x4a,0xa0,0x13,0xa8,0x00,0xaa,0x00 } },
+{  16, 0x85d0, 0, {0x36,0x81,0x0b,0xa0,0x02,0x28,0x00,0x8a,0x00,0x22,0x80,0x08,0xa0,0x03,0x8a,0x00 } },
+{  16, 0x85e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0xc0,0x20,0xd0 } },
+{  16, 0x85f0, 0, {0x0b,0x34,0x02,0x8c,0x00,0x8b,0x00,0x2c,0xf0,0x8b,0x18,0x02,0x4c,0x00,0x83,0x00 } },
+{  16, 0x8600, 0, {0x60,0xc0,0x0b,0x30,0x02,0x8c,0x02,0x83,0x00,0x28,0xc1,0x0a,0x30,0x02,0xca,0x00 } },
+{  16, 0x8610, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1e,0x00,0xb4,0x0b,0x69,0xc0 } },
+{  16, 0x8620, 0, {0x09,0x58,0x06,0x1e,0x80,0x97,0x10,0x2f,0xc2,0x48,0x70,0x82,0x9c,0x80,0xa7,0x08 } },
+{  16, 0x8630, 0, {0x25,0xcc,0x0b,0x70,0x02,0x1e,0x81,0x87,0xa2,0xab,0xc4,0x08,0x73,0x02,0xe8,0x00 } },
+{  16, 0x8640, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x10,0xdc,0x84,0x21,0xe0 } },
+{  16, 0x8650, 0, {0x0f,0x78,0x42,0x9f,0x02,0xc7,0x88,0x3d,0xe0,0x2f,0x71,0x03,0x4e,0x00,0xcf,0x80 } },
+{  16, 0x8660, 0, {0x21,0xe2,0x0f,0x78,0x83,0x9e,0x49,0xcf,0xd0,0x39,0xe8,0x0e,0x78,0x03,0xea,0x02 } },
+{  16, 0x8670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x4d,0xac,0x40,0xca,0x00,0x36,0x00 } },
+{  16, 0x8680, 0, {0x8f,0x30,0x23,0xec,0xa8,0xeb,0x40,0x3c,0xc0,0x0f,0x96,0x43,0xed,0x80,0xfb,0x00 } },
+{  16, 0x8690, 0, {0x3e,0xd8,0x8f,0xb1,0x43,0xed,0x80,0xfb,0x20,0x36,0xca,0x0f,0xb0,0xa3,0x82,0x06 } },
+{  16, 0x86a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x80,0xfc,0x80,0x31,0xe0 } },
+{  16, 0x86b0, 0, {0x05,0xaa,0x10,0xfe,0x44,0xff,0x90,0x3f,0xe1,0xcf,0xf9,0x17,0x3f,0x20,0xd7,0x80 } },
+{  16, 0x86c0, 0, {0x8b,0xe4,0x0f,0xf8,0x03,0x3e,0x30,0xff,0x80,0x37,0xe0,0x0f,0xf8,0x00,0x40,0x00 } },
+{  16, 0x86d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xbd,0x10,0x21,0xc0 } },
+{  16, 0x86e0, 0, {0x08,0x4a,0x02,0xdc,0xc0,0xb7,0x00,0x2d,0xc2,0x0c,0xd3,0x02,0x1c,0x80,0x87,0x00 } },
+{  16, 0x86f0, 0, {0x29,0xc0,0x4b,0x72,0x02,0x1c,0x00,0xb7,0x01,0x21,0xc0,0x0b,0xf0,0x12,0x2a,0x04 } },
+{  16, 0x8700, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x90,0x34,0x00,0x21,0x80 } },
+{  16, 0x8710, 0, {0x09,0x70,0x00,0x5c,0x0c,0xb7,0x00,0x2d,0xc4,0x08,0x50,0x1a,0x0c,0x00,0x97,0x00 } },
+{  16, 0x8720, 0, {0x21,0xc0,0x4b,0x30,0x02,0x1c,0x00,0xb7,0x00,0x25,0xc0,0x0b,0x70,0x02,0x40,0x00 } },
+{  16, 0x8730, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x00,0xb0,0x00,0x60,0x00 } },
+{  16, 0x8740, 0, {0x08,0x3e,0x02,0xcc,0x00,0xb3,0x02,0x0c,0xe0,0x2b,0xb0,0x02,0x0c,0x00,0x93,0x00 } },
+{  16, 0x8750, 0, {0x28,0xc0,0x0b,0xb0,0x02,0x2c,0x10,0xb3,0x00,0x20,0xd6,0x03,0x30,0x02,0x08,0x04 } },
+{  16, 0x8760, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xfb,0x00,0xb2,0x00 } },
+{  16, 0x8770, 0, {0x05,0xbe,0x03,0x7c,0x00,0xff,0x00,0x3e,0x20,0x0c,0xb0,0x03,0x3c,0x00,0xd9,0x80 } },
+{  16, 0x8780, 0, {0x33,0xc0,0x8b,0xf0,0x03,0x3c,0x00,0xff,0x00,0x37,0xe0,0x0f,0xf0,0x03,0x6a,0x04 } },
+{  16, 0x8790, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xfb,0x04,0x3e,0x00 } },
+{  16, 0x87a0, 0, {0x0f,0xa4,0x23,0xcc,0x00,0xfb,0x00,0x3e,0x81,0x08,0x90,0x03,0xec,0x00,0xe9,0x14 } },
+{  16, 0x87b0, 0, {0x3e,0xc0,0x0f,0xb0,0x03,0xec,0x10,0xfb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xe0,0x00 } },
+{  16, 0x87c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x00,0x37,0x80 } },
+{  16, 0x87d0, 0, {0x0f,0xfa,0x03,0xfc,0x00,0xcf,0x00,0x3f,0x90,0x06,0xdc,0x23,0x3c,0x00,0xfd,0x10 } },
+{  16, 0x87e0, 0, {0x33,0xc0,0x0f,0xf0,0x0b,0x3c,0x00,0x43,0x00,0x33,0xc0,0x0f,0xf0,0x03,0xc0,0x44 } },
+{  16, 0x87f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x6c,0x09,0xbb,0x19,0x22,0x32 } },
+{  16, 0x8800, 0, {0x0b,0xbe,0x03,0x6c,0x00,0x8b,0x00,0x2c,0x90,0x0d,0xb8,0x02,0xac,0x00,0xb1,0x00 } },
+{  16, 0x8810, 0, {0xf2,0xc0,0x0b,0xb0,0x12,0xac,0x00,0x8b,0x00,0x22,0xc0,0x0b,0xb0,0x03,0xa0,0x40 } },
+{  16, 0x8820, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x10,0xb3,0x00,0x26,0x20 } },
+{  16, 0x8830, 0, {0x0b,0x90,0x12,0xec,0x01,0x8b,0x00,0x2a,0xc2,0x0a,0x90,0x02,0x2c,0x00,0xbb,0x00 } },
+{  16, 0x8840, 0, {0xa2,0xc0,0x0b,0xb0,0x02,0x2c,0x00,0xab,0x00,0x2a,0xc0,0x0b,0xb0,0x02,0xe0,0x00 } },
+{  16, 0x8850, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x01,0xb3,0x00,0x20,0x00 } },
+{  16, 0x8860, 0, {0x0b,0x00,0x02,0x8c,0x00,0x83,0x00,0x2e,0xc0,0x0b,0x34,0x02,0x8c,0x00,0xbb,0x00 } },
+{  16, 0x8870, 0, {0x20,0xc0,0x0b,0x30,0x02,0x0d,0x00,0xa3,0x00,0xa0,0xc0,0x0b,0x30,0x02,0x82,0x01 } },
+{  16, 0x8880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xbb,0x04,0x36,0x80 } },
+{  16, 0x8890, 0, {0x0f,0xb2,0x02,0xfc,0x02,0xcf,0x02,0x38,0xc0,0x0e,0xf0,0x03,0x3c,0x00,0xfb,0x00 } },
+{  16, 0x88a0, 0, {0x23,0xc0,0x0f,0xf0,0x03,0x3d,0x02,0xef,0x00,0x33,0xc0,0x0f,0xf0,0x43,0xc0,0x03 } },
+{  16, 0x88b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xff,0x00,0x3f,0x00 } },
+{  16, 0x88c0, 0, {0x0f,0xf4,0x23,0x7c,0x00,0xff,0x00,0x3f,0xc0,0x0d,0xd0,0x03,0xfc,0x00,0xff,0x00 } },
+{  16, 0x88d0, 0, {0x3b,0xc0,0x0f,0xf0,0x03,0xfc,0x88,0xdf,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xa8,0x06 } },
+{  16, 0x88e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0x50,0xce,0x12,0x33,0xd0 } },
+{  16, 0x88f0, 0, {0x4c,0x86,0x83,0x30,0x80,0x5f,0x68,0x33,0xc4,0x0f,0xf3,0x83,0x3c,0xc0,0xcc,0x38 } },
+{  16, 0x8900, 0, {0xb3,0x08,0x0c,0xc6,0x03,0xf1,0xa0,0xff,0x00,0x33,0x24,0x0c,0xc2,0x03,0xf0,0x00 } },
+{  16, 0x8910, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0x80,0xd2,0x20,0x23,0xd8 } },
+{  16, 0x8920, 0, {0x0d,0x96,0x02,0x88,0x60,0xaf,0x40,0x23,0xdc,0x0b,0xf6,0x02,0x3c,0xc2,0x88,0x60 } },
+{  16, 0x8930, 0, {0x22,0x52,0x08,0x91,0x22,0xe1,0x00,0xb7,0x24,0xa2,0x48,0x8a,0x84,0x82,0x60,0x04 } },
+{  16, 0x8940, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x00,0x81,0x00,0xe0,0xc4 } },
+{  16, 0x8950, 0, {0x0a,0x00,0x02,0x04,0x80,0xa3,0x20,0xa8,0xc0,0x1b,0x30,0x0a,0x0c,0x00,0xa0,0x00 } },
+{  16, 0x8960, 0, {0x28,0x0c,0x09,0x02,0x02,0xc4,0x80,0xb3,0x1c,0x22,0x08,0x19,0x03,0x02,0xe2,0x11 } },
+{  16, 0x8970, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa4,0x00,0x99,0x80,0x62,0xc0 } },
+{  16, 0x8980, 0, {0x0b,0xa0,0x32,0xa4,0x51,0xab,0x00,0x2a,0xc0,0x8b,0xb0,0x00,0x0c,0x00,0xa9,0xc0 } },
+{  16, 0x8990, 0, {0x2a,0x21,0x08,0xb8,0x22,0xe2,0x00,0xbb,0x00,0x22,0x84,0x1b,0xa8,0x42,0x70,0x04 } },
+{  16, 0x89a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe2,0x00,0xcb,0xc9,0x32,0xc0 } },
+{  16, 0x89b0, 0, {0x0e,0x8b,0x13,0x22,0x10,0xdb,0x01,0x32,0xc0,0x0f,0xb0,0x0b,0x2c,0x00,0x68,0x81 } },
+{  16, 0x89c0, 0, {0x3a,0x22,0x2c,0x88,0x23,0xe3,0x00,0xfb,0x00,0x30,0x30,0x8d,0x9c,0x83,0xd0,0x04 } },
+{  16, 0x89d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xba,0x40,0xf7,0x04,0x3e,0xc2 } },
+{  16, 0x89e0, 0, {0x0d,0xd8,0x23,0xd8,0x00,0x7b,0x00,0x37,0xc0,0x0f,0x70,0x33,0xfc,0x10,0xd2,0x00 } },
+{  16, 0x89f0, 0, {0x35,0xc0,0x8f,0xc0,0x03,0xf4,0x00,0xf7,0x02,0x3f,0xe0,0x0e,0x80,0x03,0xf8,0x00 } },
+{  16, 0x8a00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x81,0x20,0xc8,0x08,0x30,0xc0 } },
+{  16, 0x8a10, 0, {0x0c,0x00,0x83,0x24,0x40,0xc3,0x89,0x3a,0xc0,0x0e,0xb0,0x0b,0x2c,0x08,0xc9,0x48 } },
+{  16, 0x8a20, 0, {0x72,0x54,0x0f,0x91,0x03,0xed,0x02,0xeb,0x8a,0x3a,0x62,0x8c,0x80,0x0b,0x10,0x04 } },
+{  16, 0x8a30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2b,0x04,0x88,0x40,0xa3,0xc2 } },
+{  16, 0x8a40, 0, {0x02,0xae,0x12,0x27,0x42,0x8f,0x44,0x23,0xc2,0x0b,0xf4,0x02,0x3d,0x00,0x0a,0x40 } },
+{  16, 0x8a50, 0, {0x22,0xe0,0x0b,0xb5,0x02,0xec,0x20,0x8f,0x44,0xa2,0x40,0x8d,0xbd,0x23,0x32,0x00 } },
+{  16, 0x8a60, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x49,0x40,0x83,0x81,0x24,0xc1 } },
+{  16, 0x8a70, 0, {0x08,0x28,0x02,0x01,0x00,0x93,0x00,0xa0,0xe8,0x0a,0x30,0x82,0x8f,0x60,0xb3,0x90 } },
+{  16, 0x8a80, 0, {0x60,0xb8,0x0b,0x28,0x12,0x4a,0x00,0x93,0x00,0x20,0x90,0x09,0x20,0x02,0x78,0x00 } },
+{  16, 0x8a90, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x02,0x87,0xa8,0x25,0xe0 } },
+{  16, 0x8aa0, 0, {0x0a,0x7b,0x02,0x1a,0x04,0x87,0x80,0x21,0xe4,0x0b,0x78,0x82,0x8e,0x02,0x96,0x91 } },
+{  16, 0x8ab0, 0, {0x21,0x21,0x0b,0x69,0x40,0xdb,0x40,0x97,0x92,0x23,0xa0,0x89,0x58,0x82,0x08,0x00 } },
+{  16, 0x8ac0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x25,0x82,0xc3,0x00,0x34,0xc0 } },
+{  16, 0x8ad0, 0, {0x0c,0x9b,0x43,0x08,0xd0,0xd3,0x20,0x38,0xc0,0x0e,0xb0,0x03,0x8c,0x00,0xb3,0x00 } },
+{  16, 0x8ae0, 0, {0x20,0x80,0x07,0x10,0x03,0xe0,0x00,0xd3,0x10,0x38,0x18,0x0d,0x30,0x03,0x52,0x02 } },
+{  16, 0x8af0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb4,0x00,0x7f,0x20,0x1b,0xd0 } },
+{  16, 0x8b00, 0, {0x0f,0xf1,0x03,0xf8,0x40,0xef,0x00,0x3f,0xc0,0x0f,0xb4,0x03,0x7c,0x20,0xcf,0x04 } },
+{  16, 0x8b10, 0, {0xbf,0x40,0x0f,0xf0,0x03,0xe4,0x10,0xef,0x18,0x3d,0xc0,0x0f,0xe0,0x03,0xd0,0x06 } },
+{  16, 0x8b20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe8,0x00,0xe3,0x00,0xb2,0xc4 } },
+{  16, 0x8b30, 0, {0x0c,0xa0,0x03,0x24,0x00,0xdb,0x68,0x32,0xc8,0x0c,0xb4,0x03,0xec,0x80,0xc8,0x80 } },
+{  16, 0x8b40, 0, {0xb6,0xe0,0x0c,0xa0,0x03,0x2e,0x00,0xcb,0xe0,0xb2,0x60,0x0c,0xb8,0x0b,0x2a,0x00 } },
+{  16, 0x8b50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x02,0x87,0x00,0xa1,0xc8 } },
+{  16, 0x8b60, 0, {0x08,0x70,0x02,0x1c,0x08,0x97,0x02,0x21,0xd4,0x08,0x74,0x02,0xdc,0xc0,0x07,0x00 } },
+{  16, 0x8b70, 0, {0x21,0xc0,0x88,0x70,0x02,0x18,0x00,0x83,0x08,0x21,0xc0,0x08,0x50,0x02,0x12,0x04 } },
+{  16, 0x8b80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x20,0xad,0x80,0x29,0xe0 } },
+{  16, 0x8b90, 0, {0x08,0x58,0x02,0x1e,0x00,0x97,0xb0,0x21,0xe8,0x08,0x78,0x02,0xde,0x10,0x15,0x80 } },
+{  16, 0x8ba0, 0, {0x21,0xa1,0x08,0x48,0x02,0x5e,0x00,0x87,0xa4,0x65,0xa0,0x08,0x78,0x02,0x30,0x00 } },
+{  16, 0x8bb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcf,0x10,0x81,0x70,0xa8,0xc0 } },
+{  16, 0x8bc0, 0, {0x38,0x30,0x0a,0x0d,0x00,0x93,0x00,0xa0,0xc1,0x28,0x30,0x02,0xcc,0x02,0x83,0x88 } },
+{  16, 0x8bd0, 0, {0x20,0xe0,0x38,0x34,0x0a,0x4d,0x72,0x83,0x00,0x24,0xe8,0x28,0x34,0x82,0x12,0x04 } },
+{  16, 0x8be0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xba,0x40,0xee,0xc0,0xba,0x80 } },
+{  16, 0x8bf0, 0, {0x0c,0xe0,0x03,0x39,0x10,0xda,0x00,0x32,0x80,0x0c,0xa0,0x03,0xe8,0x00,0xde,0xc8 } },
+{  16, 0x8c00, 0, {0x33,0xa0,0x0c,0xe0,0x03,0x7b,0x00,0xca,0x00,0x37,0xb1,0x0c,0xe4,0x23,0x3a,0x04 } },
+{  16, 0x8c10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xc1,0x00,0xf8,0x00,0x36,0x00 } },
+{  16, 0x8c20, 0, {0x0f,0x80,0x03,0xc0,0x20,0x38,0x00,0x3e,0x00,0x0f,0x00,0x03,0xe0,0x00,0xf8,0x02 } },
+{  16, 0x8c30, 0, {0x3a,0x24,0x0f,0x80,0x83,0xa0,0x01,0xf8,0x04,0x3a,0x04,0x0d,0x80,0x13,0xd2,0x00 } },
+{  16, 0x8c40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x44,0xc1,0x00,0x32,0x40 } },
+{  16, 0x8c50, 0, {0x0c,0x90,0x32,0x24,0x0c,0xc1,0x06,0x38,0x40,0x0d,0x90,0x09,0x04,0x00,0xd9,0x00 } },
+{  16, 0x8c60, 0, {0x3e,0x40,0x0f,0x18,0x03,0x24,0x00,0xf9,0x01,0x3e,0x40,0x0f,0x90,0x03,0xc2,0x04 } },
+{  16, 0x8c70, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x06,0x89,0x00,0x2a,0x50 } },
+{  16, 0x8c80, 0, {0x08,0x94,0x0a,0x24,0x00,0x89,0x42,0x22,0x50,0x0a,0x90,0x12,0x25,0x00,0x89,0x00 } },
+{  16, 0x8c90, 0, {0x2e,0x50,0x0b,0x9c,0x0a,0x25,0x10,0xb9,0x00,0x2e,0x50,0x0b,0x90,0x02,0xe0,0x00 } },
+{  16, 0x8ca0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x20,0x89,0x00,0x20,0x42 } },
+{  16, 0x8cb0, 0, {0x08,0x10,0xc2,0xac,0x10,0x89,0x08,0x2a,0x42,0x09,0x90,0x02,0x24,0x20,0x99,0x00 } },
+{  16, 0x8cc0, 0, {0x2e,0x42,0x0a,0xb1,0x82,0x2c,0x20,0xb9,0x00,0x6e,0x42,0x0b,0x90,0x02,0xc6,0x00 } },
+{  16, 0x8cd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0x83,0x00,0x28,0x48 } },
+{  16, 0x8ce0, 0, {0x08,0x12,0x62,0x8c,0x80,0x81,0x00,0x20,0x40,0x02,0x10,0x02,0x84,0x80,0x81,0x20 } },
+{  16, 0x8cf0, 0, {0x2c,0x49,0x0b,0x12,0x06,0x04,0x84,0xb3,0x02,0x6c,0x40,0x0b,0x12,0x02,0xc2,0x01 } },
+{  16, 0x8d00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x41,0xe0,0xc8,0x78,0x30,0x14 } },
+{  16, 0x8d10, 0, {0x4c,0x05,0x13,0xa1,0x42,0xc0,0x78,0x38,0x1e,0x0d,0x87,0x83,0x01,0x40,0xd0,0x50 } },
+{  16, 0x8d20, 0, {0x3c,0x14,0x0e,0x05,0x03,0x01,0x40,0xf8,0x78,0x3c,0x14,0x0f,0x05,0x03,0xee,0x03 } },
+{  16, 0x8d30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xfc,0x00,0xff,0x00,0x0e,0x44 } },
+{  16, 0x8d40, 0, {0x2f,0xf1,0x03,0x74,0x40,0xf9,0x00,0x3e,0x40,0x0d,0x90,0x03,0x64,0x40,0xfd,0x10 } },
+{  16, 0x8d50, 0, {0x3f,0x44,0x0f,0xd1,0x01,0xf4,0x40,0xf9,0x01,0x3f,0xc0,0x0f,0xd1,0x03,0xe6,0x06 } },
+{  16, 0x8d60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x22,0xe9,0x88,0xb2,0x40 } },
+{  16, 0x8d70, 0, {0x0f,0x90,0x03,0x24,0x16,0xc9,0x8c,0x36,0x7b,0x8f,0x9c,0x83,0xa7,0x90,0xc9,0x00 } },
+{  16, 0x8d80, 0, {0x3e,0x50,0x04,0x94,0x13,0x24,0x50,0xc9,0xe0,0x3e,0x50,0x0f,0x90,0x03,0x06,0x00 } },
+{  16, 0x8d90, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe2,0x80,0x88,0xa0,0x22,0x28 } },
+{  16, 0x8da0, 0, {0x0b,0x8a,0x02,0x2a,0x80,0x88,0xa4,0x22,0x30,0x08,0x8e,0x0a,0x22,0x02,0x88,0xa0 } },
+{  16, 0x8db0, 0, {0x2e,0x28,0x88,0xaa,0x12,0x22,0x90,0x88,0xf4,0x2e,0x20,0x0b,0xc8,0x02,0x0e,0x04 } },
+{  16, 0x8dc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xd4,0x20,0xa5,0x08,0x21,0x42 } },
+{  16, 0x8dd0, 0, {0x0b,0x50,0x82,0x14,0x31,0x85,0x08,0x25,0x40,0x0a,0x50,0x22,0x94,0x40,0x85,0x08 } },
+{  16, 0x8de0, 0, {0x6d,0x40,0x08,0x50,0x02,0x54,0x02,0x95,0x00,0x2d,0x48,0x0b,0x50,0x82,0x42,0x01 } },
+{  16, 0x8df0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0x84,0x00,0x8d,0x10,0x23,0x40 } },
+{  16, 0x8e00, 0, {0x0b,0xd0,0x00,0x34,0x01,0x8d,0x00,0x23,0x41,0x58,0xd0,0x02,0x34,0x00,0x8d,0x08 } },
+{  16, 0x8e10, 0, {0x2f,0x50,0x08,0xd2,0x02,0x74,0x80,0x9d,0x00,0x2f,0x48,0x0b,0xdc,0x02,0x46,0x04 } },
+{  16, 0x8e20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x40,0xe9,0xc0,0x32,0x40 } },
+{  16, 0x8e30, 0, {0x0f,0x90,0x09,0x26,0x00,0xc9,0x04,0x36,0x40,0x1f,0x90,0x23,0xa4,0x08,0xc9,0x40 } },
+{  16, 0x8e40, 0, {0x3e,0x40,0x0c,0x94,0x0b,0x64,0x20,0xd9,0x02,0x3e,0x41,0x0f,0x94,0x03,0x68,0x04 } },
+{  16, 0x8e50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x80,0x3e,0x40 } },
+{  16, 0x8e60, 0, {0x0f,0x14,0x03,0xc5,0x08,0xf9,0x00,0x3e,0x40,0x1f,0x90,0x23,0xe4,0x00,0xf9,0x00 } },
+{  16, 0x8e70, 0, {0x3c,0x40,0xaf,0x98,0x03,0x86,0x00,0xe9,0x00,0x3e,0x40,0x0f,0x10,0x0b,0x8a,0x00 } },
+{  16, 0x8e80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xb0,0x00,0xdc,0x40,0xb3,0x00 } },
+{  16, 0x8e90, 0, {0x0f,0xc0,0x03,0x31,0x02,0xc4,0x04,0xb1,0x00,0x3c,0x40,0x03,0x10,0x00,0xfc,0x40 } },
+{  16, 0x8ea0, 0, {0x33,0x00,0x0c,0xc4,0x03,0xb1,0x00,0xcc,0x00,0xb3,0x00,0x0c,0xc4,0x03,0xca,0x04 } },
+{  16, 0x8eb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8a,0x80,0x22,0xa0 } },
+{  16, 0x8ec0, 0, {0x0b,0xa0,0x02,0x2a,0x00,0x8a,0x84,0x22,0xa1,0x08,0xa0,0x02,0x28,0x08,0xba,0x01 } },
+{  16, 0x8ed0, 0, {0x22,0x80,0x08,0xa0,0x2b,0x28,0x00,0x8a,0x80,0x2a,0x80,0x08,0xe0,0x02,0xca,0x00 } },
+{  16, 0x8ee0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x02,0x9b,0x81,0x20,0xe0 } },
+{  16, 0x8ef0, 0, {0x8b,0x38,0x06,0xce,0x00,0x93,0x80,0x20,0xc0,0x08,0x38,0x02,0x0c,0x00,0xb3,0x80 } },
+{  16, 0x8f00, 0, {0x6c,0xe0,0x0a,0xb0,0x02,0x4c,0x00,0x93,0x00,0x20,0xe0,0x08,0x30,0x02,0xca,0x00 } },
+{  16, 0x8f10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x10,0x04,0x80,0x08,0x21,0x02 } },
+{  16, 0x8f20, 0, {0x4b,0x44,0x06,0xd0,0x20,0x90,0x08,0x21,0x02,0x80,0x44,0x02,0x10,0x00,0xb4,0xc0 } },
+{  16, 0x8f30, 0, {0x2d,0x10,0x48,0x40,0x02,0x00,0x00,0x94,0x89,0x29,0x30,0x08,0x40,0x02,0xe8,0x00 } },
+{  16, 0x8f40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x32,0x00,0xd6,0x80,0x31,0xa0 } },
+{  16, 0x8f50, 0, {0x0f,0xe8,0x0b,0xca,0x00,0xd6,0x80,0x23,0xa0,0x04,0xf8,0x0b,0x1a,0x00,0xff,0x80 } },
+{  16, 0x8f60, 0, {0xbf,0xa0,0x2e,0xc8,0x13,0xda,0x02,0x5e,0x80,0x73,0xa0,0x2c,0x78,0x03,0xea,0x02 } },
+{  16, 0x8f70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xf9,0x00,0x3e,0x40 } },
+{  16, 0x8f80, 0, {0x0f,0x90,0x03,0x24,0x00,0xe9,0x00,0x3e,0x40,0x0e,0x80,0x03,0xe4,0x00,0xf8,0x00 } },
+{  16, 0x8f90, 0, {0x32,0x40,0x0f,0xb0,0x03,0xe4,0x01,0xe9,0x04,0x36,0x40,0x0f,0x80,0x03,0xc2,0x06 } },
+{  16, 0x8fa0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xcd,0x80,0x33,0x60 } },
+{  16, 0x8fb0, 0, {0x0c,0xd8,0x43,0x36,0x00,0xcd,0x80,0x33,0x60,0x0c,0xd9,0x23,0xbe,0x00,0x4d,0x80 } },
+{  16, 0x8fc0, 0, {0x33,0x60,0x08,0xf8,0x0b,0x3e,0x00,0xfd,0x84,0x3f,0x60,0x0f,0xf9,0x03,0xc0,0x00 } },
+{  16, 0x8fd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x90,0x04,0xde,0x00,0x23,0x80 } },
+{  16, 0x8fe0, 0, {0x08,0x60,0x02,0xb8,0x20,0x8e,0x04,0x23,0x80,0x08,0x68,0x02,0x10,0x00,0x8e,0x20 } },
+{  16, 0x8ff0, 0, {0x23,0x82,0x08,0x40,0x02,0x12,0x00,0xf6,0x00,0x2d,0x80,0x0b,0x41,0xa0,0xea,0x04 } },
+{  16, 0x9000, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x84,0x00,0x21,0x00 } },
+{  16, 0x9010, 0, {0x08,0x41,0x02,0x50,0x40,0x94,0x00,0x21,0x00,0x0a,0x52,0x02,0xd8,0x00,0x85,0x02 } },
+{  16, 0x9020, 0, {0x25,0x04,0x08,0x40,0x22,0x18,0x08,0xb4,0x00,0x2d,0x10,0x0b,0x78,0x40,0xc0,0x00 } },
+{  16, 0x9030, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xee,0x22,0x93,0x00,0x20,0xc0 } },
+{  16, 0x9040, 0, {0x08,0x38,0x02,0xec,0x00,0x93,0x00,0x20,0xc1,0x2a,0x20,0x02,0x64,0x02,0x82,0x10 } },
+{  16, 0x9050, 0, {0x24,0xf0,0x0a,0x3c,0x42,0x24,0x28,0xb3,0x00,0x2c,0xe0,0x0b,0x88,0x82,0xc8,0x04 } },
+{  16, 0x9060, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xad,0x00,0xcb,0x00,0xb2,0xc0 } },
+{  16, 0x9070, 0, {0xac,0xbe,0x03,0x6e,0x02,0xdb,0x00,0xb2,0xc0,0x1e,0xa0,0x03,0xe4,0x00,0xca,0x11 } },
+{  16, 0x9080, 0, {0xb6,0xd0,0xac,0xbc,0x03,0x24,0x00,0xfb,0x00,0x3e,0xc0,0xcf,0x84,0x03,0xea,0x04 } },
+{  16, 0x9090, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe0,0x40,0xf8,0x00,0x3c,0x00 } },
+{  16, 0x90a0, 0, {0x2f,0x82,0x03,0xa0,0x00,0xe8,0x00,0x3e,0x00,0x1d,0x90,0x13,0xa8,0x00,0xf9,0x00 } },
+{  16, 0x90b0, 0, {0x3a,0x00,0x81,0x83,0x43,0xe8,0x00,0xe8,0x03,0x3e,0x04,0x0f,0xb0,0x03,0xe0,0x00 } },
+{  16, 0x90c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xe0,0x00,0xd6,0x00,0x37,0x80 } },
+{  16, 0x90d0, 0, {0x0c,0xa0,0x03,0xf8,0x00,0xce,0x00,0x33,0x80,0x0d,0xa0,0x13,0x20,0x08,0xce,0x00 } },
+{  16, 0x90e0, 0, {0x33,0x82,0x0c,0x40,0x73,0x30,0x18,0xce,0x00,0x1f,0x80,0x4f,0xc1,0x43,0x00,0x44 } },
+{  16, 0x90f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x7c,0x00,0x8d,0x00,0x23,0x40 } },
+{  16, 0x9100, 0, {0x0a,0xd0,0x02,0xf4,0x00,0x8d,0x00,0x23,0x40,0x08,0xd4,0x80,0x3e,0x42,0x8d,0x40 } },
+{  16, 0x9110, 0, {0x23,0x40,0x08,0xf0,0x02,0x3e,0x40,0x8d,0x00,0x0f,0x40,0x0b,0xf4,0x02,0x20,0x40 } },
+{  16, 0x9120, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x99,0x00,0xa6,0x40 } },
+{  16, 0x9130, 0, {0x08,0x90,0x06,0xe4,0x00,0x91,0x00,0x20,0x40,0x88,0x00,0x02,0x24,0x08,0x80,0x40 } },
+{  16, 0x9140, 0, {0x20,0x40,0x0a,0xb0,0x02,0x24,0x00,0x89,0x00,0x0e,0x40,0x0b,0x84,0x02,0x20,0x00 } },
+{  16, 0x9150, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x82,0x00,0x20,0x80 } },
+{  16, 0x9160, 0, {0x0a,0x21,0x06,0xc8,0x01,0x82,0x00,0x20,0x80,0x08,0x32,0x82,0x08,0x08,0x83,0x00 } },
+{  16, 0x9170, 0, {0x60,0x80,0x0a,0x00,0x12,0x08,0x80,0x82,0x00,0x2c,0x80,0x0b,0x30,0x0a,0x02,0x01 } },
+{  16, 0x9180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xd8,0x00,0x36,0x00 } },
+{  16, 0x9190, 0, {0x0c,0x84,0x23,0xe0,0x00,0xc8,0x00,0x32,0x00,0x0d,0x82,0x0b,0x20,0x02,0xc8,0x00 } },
+{  16, 0x91a0, 0, {0x32,0x00,0x0e,0x00,0x03,0x20,0x02,0xc8,0x00,0x3e,0x00,0x0f,0x80,0x03,0x00,0x03 } },
+{  16, 0x91b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xbf,0x00,0x3f,0xc0 } },
+{  16, 0x91c0, 0, {0x0f,0xf0,0x03,0xfc,0x00,0xff,0x00,0xbf,0xc0,0x8f,0xb0,0x03,0xfc,0x08,0xff,0x02 } },
+{  16, 0x91d0, 0, {0x3f,0xc0,0x0d,0xf0,0x03,0xed,0x00,0xff,0x02,0x3f,0xc0,0x0f,0xf0,0x03,0xe8,0x06 } },
+{  16, 0x91e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xf0,0x8c,0xff,0x00,0x3d,0x60 } },
+{  16, 0x91f0, 0, {0x2c,0xb2,0x83,0x7c,0x90,0xdf,0x38,0x31,0xe0,0x0f,0xf8,0x03,0x3c,0x00,0xff,0x20 } },
+{  16, 0x9200, 0, {0x3f,0xc4,0x0e,0xf4,0x03,0x7c,0x00,0xf4,0x80,0x33,0x00,0x0d,0xf8,0x03,0xf0,0x00 } },
+{  16, 0x9210, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe1,0x20,0xbb,0x62,0x2e,0x42 } },
+{  16, 0x9220, 0, {0x28,0xf4,0x42,0x3e,0x40,0x8f,0x44,0x22,0xe0,0x0b,0xb0,0x83,0x7f,0x44,0xbf,0xc1 } },
+{  16, 0x9230, 0, {0x2d,0xdc,0x2a,0xf6,0x02,0x3f,0x45,0xb8,0x80,0x22,0x61,0x88,0xb8,0x02,0xe0,0x04 } },
+{  16, 0x9240, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc5,0x80,0xb2,0x18,0x2e,0xc8 } },
+{  16, 0x9250, 0, {0x29,0x30,0x32,0x0c,0x08,0xb3,0x20,0x20,0xc0,0x4b,0x92,0x02,0x0c,0x00,0xb3,0x40 } },
+{  16, 0x9260, 0, {0x2c,0xc0,0x89,0x34,0x12,0x4c,0x00,0xb0,0x00,0x24,0xc1,0x49,0x30,0x02,0xe2,0x01 } },
+{  16, 0x9270, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xa4,0x00,0xba,0x0c,0x2e,0xe0 } },
+{  16, 0x9280, 0, {0xa9,0xb0,0x06,0x2c,0x00,0x8b,0x00,0xa2,0xc0,0x0b,0x90,0x00,0x6c,0x00,0xbb,0x00 } },
+{  16, 0x9290, 0, {0x2e,0xc0,0x0b,0x30,0x02,0x6c,0x00,0xba,0x80,0x26,0xf0,0x08,0xb0,0x02,0xf0,0x04 } },
+{  16, 0x92a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xee,0x00,0xfb,0xc4,0x3e,0x78 } },
+{  16, 0x92b0, 0, {0x2d,0xb0,0x03,0x6c,0x08,0xfb,0x00,0x32,0xc0,0x8b,0x24,0x83,0x2c,0x00,0xfb,0x00 } },
+{  16, 0x92c0, 0, {0x3e,0xc0,0x8f,0xb0,0x0b,0x6c,0x08,0xb2,0xe0,0x16,0x60,0x8d,0xb0,0x23,0xd0,0x04 } },
+{  16, 0x92d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbe,0x98,0xff,0x40,0x3f,0xc0 } },
+{  16, 0x92e0, 0, {0x0e,0x70,0x03,0xdc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xe0,0x03,0xfc,0x00,0xff,0x00 } },
+{  16, 0x92f0, 0, {0x3f,0xc0,0x0e,0xf0,0x03,0xac,0x00,0xfe,0x00,0xb9,0xc0,0x0f,0xf0,0x03,0xf8,0x00 } },
+{  16, 0x9300, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xad,0x00,0xfa,0x40,0x3e,0xd0 } },
+{  16, 0x9310, 0, {0x0e,0xb2,0x03,0xec,0x00,0xc3,0x00,0x3e,0xc0,0x0c,0xa0,0x03,0x2c,0x01,0xfb,0x00 } },
+{  16, 0x9320, 0, {0x3c,0xc0,0x0e,0xb8,0x03,0xec,0x00,0xda,0x00,0x3a,0xd0,0x4f,0xb0,0x23,0xd0,0x04 } },
+{  16, 0x9330, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xba,0x00,0x2c,0xc0 } },
+{  16, 0x9340, 0, {0x08,0xf4,0x07,0xbc,0x14,0xdf,0x00,0x3e,0xc0,0x1a,0xa0,0x52,0xbc,0x00,0xbf,0x04 } },
+{  16, 0x9350, 0, {0x3f,0xc0,0x8a,0xf0,0x03,0xbc,0x00,0xfa,0x00,0x22,0xc8,0x0f,0xb0,0x03,0xf2,0x00 } },
+{  16, 0x9360, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x48,0x01,0xb1,0x00,0x6c,0xc2 } },
+{  16, 0x9370, 0, {0x0a,0x30,0x42,0xcc,0x00,0x83,0x05,0x2c,0xc0,0x08,0x30,0x02,0x8c,0x01,0xb3,0x04 } },
+{  16, 0x9380, 0, {0x2c,0xc0,0x0a,0x30,0x22,0x8c,0x00,0x80,0x80,0x28,0xc0,0x0b,0x30,0x22,0xf8,0x00 } },
+{  16, 0x9390, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x08,0xb7,0x80,0x6f,0xe0 } },
+{  16, 0x93a0, 0, {0x18,0x78,0x02,0x8e,0x40,0xb7,0x80,0x2d,0xe0,0x0a,0x78,0x02,0x9e,0x00,0xb7,0x80 } },
+{  16, 0x93b0, 0, {0x29,0xe1,0x0a,0x78,0x02,0x9e,0x01,0xbc,0x80,0x29,0xe4,0x0b,0x78,0x02,0xc8,0x00 } },
+{  16, 0x93c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x09,0x40,0xf1,0x20,0x3c,0xc4 } },
+{  16, 0x93d0, 0, {0x0e,0x39,0x02,0xcc,0x00,0xc3,0x00,0x2c,0xc4,0x08,0x92,0x03,0x8c,0x88,0xb3,0x10 } },
+{  16, 0x93e0, 0, {0x2c,0xc4,0x0e,0xb0,0x07,0x8c,0x00,0xc2,0x08,0x38,0xc0,0x0f,0x30,0x43,0xd2,0x02 } },
+{  16, 0x93f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x10,0xfc,0x00,0x7f,0xc0 } },
+{  16, 0x9400, 0, {0x0f,0xf0,0x83,0xfc,0x21,0xdf,0x08,0x3b,0xc0,0x8f,0x90,0x01,0xfc,0x21,0xff,0x0c } },
+{  16, 0x9410, 0, {0x3f,0xc2,0x0f,0xf1,0x03,0xec,0x00,0xef,0x00,0x77,0xc0,0x1e,0xf0,0x03,0x90,0x06 } },
+{  16, 0x9420, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe8,0x01,0xf9,0x00,0x32,0xc0 } },
+{  16, 0x9430, 0, {0x0f,0xb2,0x03,0xee,0x90,0xdb,0xe1,0x3a,0xc0,0x4d,0x38,0x13,0x2d,0x30,0xfb,0x00 } },
+{  16, 0x9440, 0, {0x3e,0xe0,0x4f,0xba,0x43,0x2c,0x40,0xfa,0x00,0x3f,0xc0,0x8c,0xb0,0x03,0xea,0x00 } },
+{  16, 0x9450, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0xb1,0x00,0x21,0xc0 } },
+{  16, 0x9460, 0, {0x0b,0x71,0x02,0xcc,0x20,0xa7,0x28,0x21,0xc0,0x0b,0x70,0x13,0x5c,0x08,0xb7,0x10 } },
+{  16, 0x9470, 0, {0x2d,0xc4,0x4b,0x34,0x83,0x1c,0xc1,0xb7,0x02,0x2d,0xc0,0x1a,0x70,0x02,0xd2,0x04 } },
+{  16, 0x9480, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x20,0xb4,0xc4,0x25,0xa2 } },
+{  16, 0x9490, 0, {0x0b,0x78,0x06,0xde,0x00,0x83,0x80,0x29,0xe0,0x1b,0xf8,0x02,0x5e,0x80,0xa7,0xa0 } },
+{  16, 0x94a0, 0, {0x2d,0xc8,0x0a,0x72,0x02,0x1e,0x00,0xa6,0x80,0x28,0xe0,0x08,0x78,0x02,0xf0,0x00 } },
+{  16, 0x94b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xed,0x00,0xb3,0x40,0x24,0xc3 } },
+{  16, 0x94c0, 0, {0x0b,0x30,0x42,0xcc,0x00,0xa3,0x00,0x20,0xc0,0x1b,0x34,0x02,0x4c,0x00,0xb3,0x00 } },
+{  16, 0x94d0, 0, {0x2c,0xc0,0x4b,0x30,0x02,0x0c,0x00,0xb3,0x88,0x2c,0xd4,0x0a,0x30,0x02,0xd2,0x04 } },
+{  16, 0x94e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x00,0xfe,0x40,0xb7,0xa0 } },
+{  16, 0x94f0, 0, {0x0f,0xa0,0x03,0xe8,0x00,0xda,0x00,0x3a,0x80,0x0f,0xe2,0x03,0x68,0x00,0xfa,0x00 } },
+{  16, 0x9500, 0, {0x3e,0x80,0x0f,0xa0,0x0b,0x28,0x00,0xee,0xe0,0x3f,0xb0,0x04,0xa0,0x03,0xfa,0x04 } },
+{  16, 0x9510, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x04,0xf0,0x08,0x3a,0x10 } },
+{  16, 0x9520, 0, {0x0f,0x84,0x03,0xe0,0x10,0xf8,0x00,0x3e,0x00,0x4f,0x80,0x83,0xe0,0x00,0xf8,0x00 } },
+{  16, 0x9530, 0, {0x3c,0x00,0x0f,0x80,0x03,0x80,0x00,0xf8,0x40,0x3e,0x09,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0x9540, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x20,0xe9,0x00,0x32,0x44 } },
+{  16, 0x9550, 0, {0x0c,0x90,0x03,0x24,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x13,0xe4,0x00,0xb9,0x00 } },
+{  16, 0x9560, 0, {0x1e,0x40,0x0c,0x10,0x03,0x24,0x00,0xc9,0xa0,0x3c,0x64,0x0c,0x90,0x03,0x82,0x04 } },
+{  16, 0x9570, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x68 } },
+{  16, 0x9580, 0, {0x08,0x13,0x02,0x24,0x08,0xf9,0x00,0x2e,0x48,0x1b,0x90,0x02,0xe4,0x00,0xb9,0x00 } },
+{  16, 0x9590, 0, {0x3e,0x40,0x0c,0x90,0x02,0x24,0x08,0xf9,0x40,0x2e,0x60,0x0a,0x90,0x06,0xe0,0x00 } },
+{  16, 0x95a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xa9,0x00,0x20,0x40 } },
+{  16, 0x95b0, 0, {0x08,0x90,0x02,0x24,0x00,0xb9,0x01,0x2e,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x00 } },
+{  16, 0x95c0, 0, {0x2e,0x40,0x08,0x92,0x22,0x24,0x00,0x89,0x00,0x2e,0x40,0x08,0x90,0x02,0xc6,0x00 } },
+{  16, 0x95d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x80,0x81,0x21,0xe0,0x50 } },
+{  16, 0x95e0, 0, {0x28,0x16,0x0a,0x04,0x80,0xa1,0x40,0x2c,0x40,0x4b,0x14,0x22,0xc4,0x00,0xb1,0x00 } },
+{  16, 0x95f0, 0, {0x2c,0x50,0x09,0x14,0x02,0x04,0x04,0xb1,0x00,0x2c,0x40,0x0a,0x10,0x02,0xc2,0x01 } },
+{  16, 0x9600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xe8,0x50,0x32,0x00 } },
+{  16, 0x9610, 0, {0x8c,0x80,0x02,0x20,0x00,0xb8,0x00,0x3e,0x00,0x0b,0x80,0x33,0xe0,0x10,0xf8,0x00 } },
+{  16, 0x9620, 0, {0x3e,0x00,0x0c,0x80,0x03,0x20,0x08,0xca,0x00,0x3e,0x00,0x0c,0x80,0x03,0xae,0x03 } },
+{  16, 0x9630, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xfc,0x40,0xfd,0x10,0x2f,0x41 } },
+{  16, 0x9640, 0, {0x4f,0x91,0x03,0xe4,0x40,0xf9,0x40,0x3e,0x40,0x4f,0xd0,0x63,0xe5,0x00,0xf9,0x40 } },
+{  16, 0x9650, 0, {0x3a,0x50,0x2e,0x94,0x03,0x65,0x00,0xed,0x00,0x3f,0x50,0x0f,0x90,0x03,0xe6,0x06 } },
+{  16, 0x9660, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xe6,0x00,0xf9,0xe0,0x33,0x50 } },
+{  16, 0x9670, 0, {0x0c,0xda,0x03,0xa6,0x00,0xd9,0x80,0x3f,0x40,0x0f,0x91,0x03,0xa6,0x00,0xf9,0x88 } },
+{  16, 0x9680, 0, {0x3e,0x68,0x0c,0xde,0x03,0x66,0x00,0xed,0x00,0x3b,0x69,0x0c,0x90,0x03,0xc6,0x00 } },
+{  16, 0x9690, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x08,0xb8,0xe0,0x20,0x20 } },
+{  16, 0x96a0, 0, {0x18,0x8e,0x26,0xe1,0x00,0x80,0xa0,0x2e,0x00,0x4b,0x88,0x42,0xe1,0x50,0xb8,0x40 } },
+{  16, 0x96b0, 0, {0x2e,0x2a,0x0d,0x0a,0x02,0x20,0x08,0xb8,0x00,0x2e,0x14,0x0d,0x80,0x02,0xce,0x04 } },
+{  16, 0x96c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb1,0x60,0x20,0x40 } },
+{  16, 0x96d0, 0, {0x08,0x31,0xa2,0xc5,0x00,0x91,0x48,0x2c,0x40,0x1b,0x12,0x02,0x84,0x00,0xb1,0x00 } },
+{  16, 0x96e0, 0, {0x2c,0x50,0x09,0x16,0x02,0x05,0x00,0xa3,0x04,0x28,0x40,0x08,0x10,0x02,0xc2,0x01 } },
+{  16, 0x96f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xa4,0x00,0xb9,0x08,0x20,0x70 } },
+{  16, 0x9700, 0, {0x28,0x90,0x02,0xe4,0x00,0x89,0x00,0x2e,0x40,0x0b,0x90,0x02,0xe4,0x08,0xb9,0x03 } },
+{  16, 0x9710, 0, {0x2c,0x40,0x29,0x90,0x02,0x64,0x00,0xb9,0x00,0x2e,0x62,0x09,0x90,0x02,0xc6,0x04 } },
+{  16, 0x9720, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe5,0x00,0xf9,0xd0,0xb2,0x70 } },
+{  16, 0x9730, 0, {0x08,0x90,0x03,0xe4,0x00,0xd9,0x04,0x3e,0x40,0x0f,0x90,0x03,0xa4,0x10,0xf9,0x02 } },
+{  16, 0x9740, 0, {0x3e,0x40,0x0d,0x90,0x2b,0x64,0x00,0xe9,0x8d,0x3a,0x60,0x0c,0x90,0x03,0xe8,0x04 } },
+{  16, 0x9750, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x80,0x3e,0x42 } },
+{  16, 0x9760, 0, {0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x9a,0x03,0xe4,0x00,0xf9,0x00 } },
+{  16, 0x9770, 0, {0x3e,0x40,0x2f,0x10,0x03,0xa4,0x00,0xf9,0x22,0x3c,0x40,0x4f,0x90,0x03,0xca,0x00 } },
+{  16, 0x9780, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x00,0xf0,0x40,0x32,0x00 } },
+{  16, 0x9790, 0, {0x0c,0x80,0x03,0xc0,0x00,0xf8,0x00,0x32,0x20,0x1f,0x80,0x03,0xe0,0x00,0xc8,0x00 } },
+{  16, 0x97a0, 0, {0x32,0x00,0x0c,0x80,0x02,0x20,0x00,0xc8,0xc0,0x3e,0x00,0x0c,0x80,0x03,0xca,0x04 } },
+{  16, 0x97b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x15,0x28,0x10,0xba,0x00,0x23,0xa0 } },
+{  16, 0x97c0, 0, {0x0a,0xe4,0x02,0xe8,0x00,0xba,0x00,0x2b,0xa1,0x0b,0xa0,0x02,0xe8,0x00,0xaa,0x00 } },
+{  16, 0x97d0, 0, {0x2a,0x81,0x0a,0xa0,0x03,0xe8,0x08,0xde,0x00,0x2e,0x80,0x0a,0xa0,0x02,0xca,0x00 } },
+{  16, 0x97e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x04,0xa0,0xb1 } },
+{  16, 0x97f0, 0, {0x08,0x36,0x22,0xcc,0x00,0xb3,0x00,0x20,0xe4,0x0b,0x30,0x02,0xcc,0x00,0x83,0x00 } },
+{  16, 0x9800, 0, {0x20,0xc0,0x08,0x18,0x02,0x0c,0x00,0x91,0x01,0x2c,0xc0,0x08,0x30,0x06,0xca,0x00 } },
+{  16, 0x9810, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0xc8,0xb3,0x21,0x21,0xc2 } },
+{  16, 0x9820, 0, {0x2a,0x70,0x02,0xdc,0x00,0xb7,0xa0,0x29,0xc0,0x0b,0x72,0x02,0xce,0x00,0xa7,0x81 } },
+{  16, 0x9830, 0, {0x29,0xc0,0x4a,0x74,0x02,0xfe,0x00,0x97,0x01,0x2c,0xc0,0x0a,0x70,0x12,0xe8,0x00 } },
+{  16, 0x9840, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x80,0xf7,0xc0,0x31,0xe0 } },
+{  16, 0x9850, 0, {0x0c,0x48,0x03,0xde,0x11,0xf7,0x80,0x21,0xe0,0x0b,0x7a,0x03,0xde,0x00,0xc3,0x80 } },
+{  16, 0x9860, 0, {0x33,0xd8,0x6c,0x78,0x03,0x3e,0x00,0xd6,0x80,0x3d,0xe0,0x0c,0x78,0x03,0xea,0x02 } },
+{  16, 0x9870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0d,0xac,0x08,0xfb,0x80,0x3e,0xc0 } },
+{  16, 0x9880, 0, {0x0f,0xd0,0x03,0xec,0x04,0xfb,0x3c,0x3e,0xc0,0x0f,0xb6,0x07,0x6c,0x01,0xfb,0x00 } },
+{  16, 0x9890, 0, {0x3e,0xd0,0x0f,0x94,0x07,0xec,0x01,0xea,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xc2,0x06 } },
+{  16, 0x98a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xfe,0x00,0xcf,0xa4,0x3b,0x60 } },
+{  16, 0x98b0, 0, {0x08,0xd9,0x03,0x7e,0x00,0xcf,0x80,0x3f,0x25,0x4f,0xfc,0x87,0xbe,0x00,0xcf,0x80 } },
+{  16, 0x98c0, 0, {0x7f,0xfc,0x0c,0xfc,0x03,0x7c,0x00,0xf6,0x90,0x33,0xe0,0x0f,0xf8,0x03,0xc0,0x00 } },
+{  16, 0x98d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x08,0x8f,0x28,0x21,0x40 } },
+{  16, 0x98e0, 0, {0x08,0xd0,0x02,0x1c,0x40,0xa7,0x20,0x31,0x04,0x1b,0x78,0x02,0xdc,0x80,0xd7,0x00 } },
+{  16, 0x98f0, 0, {0x2f,0xc4,0x1a,0xd0,0x02,0x1e,0x48,0xb6,0x00,0x61,0xc0,0x0b,0x70,0x06,0xea,0x04 } },
+{  16, 0x9900, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x00,0x87,0x30,0x69,0x44 } },
+{  16, 0x9910, 0, {0x08,0x50,0x22,0x0c,0x00,0x87,0x01,0x2d,0x44,0x8b,0x70,0x06,0x8c,0x10,0x87,0x00 } },
+{  16, 0x9920, 0, {0x29,0xc9,0x08,0x50,0x02,0x1c,0x44,0xa6,0x00,0x61,0xc0,0x0b,0x70,0x02,0xc0,0x00 } },
+{  16, 0x9930, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcd,0x00,0x83,0x88,0x60,0x40 } },
+{  16, 0x9940, 0, {0x00,0x10,0x02,0x4c,0x00,0x2b,0x00,0x2c,0x41,0x1b,0x30,0x02,0xcc,0x00,0x93,0x00 } },
+{  16, 0x9950, 0, {0x2c,0xc0,0x0a,0x30,0x42,0x0c,0x00,0xb2,0x40,0x20,0xf1,0x0b,0x30,0x02,0xc8,0x04 } },
+{  16, 0x9960, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbd,0x41,0xcf,0xc0,0xba,0xf0 } },
+{  16, 0x9970, 0, {0x28,0x90,0x1b,0x6c,0x08,0xcf,0x00,0x2c,0xc0,0x0f,0xf0,0x03,0xac,0x00,0x8b,0x00 } },
+{  16, 0x9980, 0, {0x3f,0xc0,0x6c,0xb0,0x4b,0x2c,0x01,0xfb,0x40,0x22,0xc8,0x0f,0xb0,0x03,0xea,0x04 } },
+{  16, 0x9990, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x04,0xfb,0x04,0x3f,0xd4 } },
+{  16, 0x99a0, 0, {0x0f,0x10,0x03,0xac,0x00,0xfb,0x00,0x32,0xc0,0x5f,0xb0,0x03,0xec,0x00,0xfb,0x04 } },
+{  16, 0x99b0, 0, {0x3e,0xc0,0x4f,0x10,0x13,0xec,0x00,0xfb,0x88,0x3e,0xc0,0x4f,0xb0,0x03,0xe0,0x00 } },
+{  16, 0x99c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xc7,0x00,0x33,0x62 } },
+{  16, 0x99d0, 0, {0x0c,0xc0,0x0b,0x3c,0x00,0xef,0x00,0x33,0xe0,0x1c,0xf0,0x13,0x3c,0x08,0xf7,0x00 } },
+{  16, 0x99e0, 0, {0x31,0xc0,0x0e,0xd8,0x03,0xbc,0x00,0xfe,0x00,0x3d,0xc6,0x0c,0xf0,0x03,0xc0,0x44 } },
+{  16, 0x99f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x00,0xcb,0x03,0x22,0x47 } },
+{  16, 0x9a00, 0, {0x08,0x98,0x42,0x2c,0x00,0x9b,0x00,0x2a,0xc0,0x0a,0xb0,0x02,0x2c,0x00,0xbb,0x04 } },
+{  16, 0x9a10, 0, {0x2a,0xc0,0x0a,0xb0,0x02,0xac,0x08,0xfa,0x00,0x2e,0x60,0x08,0xb0,0x02,0xe0,0x40 } },
+{  16, 0x9a20, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x9b,0x00,0x20,0x40 } },
+{  16, 0x9a30, 0, {0x08,0x98,0x02,0x2c,0x00,0xbb,0x00,0x22,0x88,0x08,0x30,0x02,0x2c,0x00,0xbb,0x00 } },
+{  16, 0x9a40, 0, {0x22,0xc0,0x8a,0x92,0x02,0xac,0x00,0xaa,0x80,0x2e,0xc0,0x08,0xb0,0x06,0xe0,0x00 } },
+{  16, 0x9a50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0x83,0x00,0xa0,0x40 } },
+{  16, 0x9a60, 0, {0x08,0x10,0x02,0x0c,0x00,0xb3,0x00,0x28,0x80,0x0a,0x32,0x12,0x0c,0x00,0xb3,0x04 } },
+{  16, 0x9a70, 0, {0x28,0xc0,0x0a,0x30,0x22,0x8c,0x20,0xb2,0x00,0x2c,0xc0,0x08,0x30,0x02,0xc2,0x01 } },
+{  16, 0x9a80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x02,0xcb,0x00,0x30,0x40 } },
+{  16, 0x9a90, 0, {0x1c,0x94,0x03,0x2c,0x00,0xef,0x00,0x32,0xc0,0x88,0xf0,0x8b,0x2c,0x00,0xfb,0x00 } },
+{  16, 0x9aa0, 0, {0x33,0xc0,0xae,0xf0,0x03,0xac,0x80,0xea,0x01,0x3e,0xc0,0x2c,0xb0,0x03,0xc0,0x03 } },
+{  16, 0x9ab0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xff,0x00,0x2f,0x40 } },
+{  16, 0x9ac0, 0, {0x07,0xd2,0x83,0xfc,0x00,0xdf,0x04,0x3f,0xc0,0x0f,0xb0,0x03,0xfc,0x00,0xff,0x00 } },
+{  16, 0x9ad0, 0, {0x3f,0xc0,0x0f,0xd0,0x0b,0xec,0x00,0xee,0x00,0x3f,0x40,0x0f,0xf0,0x03,0xe8,0x06 } },
+{  16, 0x9ae0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf5,0x00,0xcf,0x08,0x3f,0x48 } },
+{  16, 0x9af0, 0, {0x0f,0xc3,0x93,0x70,0xd0,0xdc,0x30,0x3f,0xd8,0x0c,0xb2,0x03,0x3c,0xc0,0xff,0x40 } },
+{  16, 0x9b00, 0, {0x33,0xc4,0x2c,0xf1,0x03,0x62,0x50,0xfc,0x34,0x33,0x00,0x0f,0x5c,0x03,0xf0,0x00 } },
+{  16, 0x9b10, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xc4,0x80,0x8b,0x00,0x2f,0x5a } },
+{  16, 0x9b20, 0, {0x0b,0xa6,0x12,0x21,0xc0,0x89,0x70,0x2f,0xdc,0x08,0xf2,0xc2,0x3d,0xd0,0xbf,0x40 } },
+{  16, 0x9b30, 0, {0x37,0xdc,0x88,0xf5,0x0a,0x20,0x80,0xe8,0x10,0x2a,0x16,0x0b,0x90,0x02,0xe0,0x04 } },
+{  16, 0x9b40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc0,0x00,0x83,0x08,0x2c,0x44 } },
+{  16, 0x9b50, 0, {0x0b,0x02,0x02,0x0c,0x00,0x80,0x00,0x2c,0xc8,0x08,0x33,0x42,0x8c,0x90,0xb3,0x30 } },
+{  16, 0x9b60, 0, {0x28,0xc8,0x4a,0x32,0x12,0x80,0x0c,0xb0,0xa0,0x28,0x28,0x0b,0x12,0x02,0xe2,0x01 } },
+{  16, 0x9b70, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa2,0x00,0x8b,0x00,0x2e,0x48 } },
+{  16, 0x9b80, 0, {0x0b,0xa0,0x22,0x20,0x20,0x88,0x80,0x2e,0xc0,0x28,0xb0,0x0a,0xac,0x00,0xbb,0x00 } },
+{  16, 0x9b90, 0, {0x2e,0xc0,0x0a,0xb0,0x02,0xa0,0x00,0xab,0x82,0x2a,0xa0,0x0b,0xb2,0x02,0xf0,0x04 } },
+{  16, 0x9ba0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe7,0x00,0xcb,0x00,0x3e,0xc0 } },
+{  16, 0x9bb0, 0, {0xcf,0x9c,0x0b,0x21,0x00,0xd8,0x88,0x3e,0xc0,0x0c,0xb0,0x03,0xac,0x00,0xfb,0x00 } },
+{  16, 0x9bc0, 0, {0x3a,0xc0,0x0e,0xb0,0x43,0xe8,0x40,0xf8,0x80,0x3a,0x60,0x0f,0x98,0x03,0xd0,0x04 } },
+{  16, 0x9bd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb4,0x00,0xff,0x00,0x0f,0xe0 } },
+{  16, 0x9be0, 0, {0x07,0xa1,0x03,0xe8,0x02,0xfb,0x00,0x3f,0xc0,0x0f,0x70,0x23,0x7c,0x00,0xff,0x02 } },
+{  16, 0x9bf0, 0, {0x35,0xc0,0x4d,0xb0,0x03,0x74,0x20,0xfc,0x01,0x3f,0x00,0x0f,0xf8,0x03,0xf8,0x00 } },
+{  16, 0x9c00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa5,0x00,0xcb,0x00,0xba,0x40 } },
+{  16, 0x9c10, 0, {0x0c,0x14,0x0b,0x2f,0x22,0xc9,0x40,0x32,0xc0,0x8e,0xb0,0x03,0xac,0x00,0xfb,0x00 } },
+{  16, 0x9c20, 0, {0x3e,0xc0,0x0e,0xb0,0x03,0xe4,0x00,0xc9,0x00,0x32,0x00,0x2c,0x90,0x03,0x10,0x04 } },
+{  16, 0x9c30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x01,0x24,0x00,0x8f,0x00,0x22,0x40 } },
+{  16, 0x9c40, 0, {0x2c,0xa5,0x42,0x29,0x00,0x8b,0x04,0xa3,0xc1,0x0d,0xf0,0x0a,0x3c,0x00,0xbf,0x00 } },
+{  16, 0x9c50, 0, {0x3f,0xc0,0x08,0xf0,0x01,0x69,0x00,0xda,0x05,0x22,0xd0,0x08,0x94,0x03,0x72,0x00 } },
+{  16, 0x9c60, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x60,0x40,0x83,0x01,0x20,0xc0 } },
+{  16, 0x9c70, 0, {0x09,0x00,0x02,0x20,0x00,0x82,0x60,0x22,0xc0,0x08,0x30,0x42,0x4c,0x10,0xbb,0x02 } },
+{  16, 0x9c80, 0, {0x2c,0xc0,0x08,0xb0,0x12,0x05,0x00,0x9b,0x00,0x20,0x82,0x09,0x32,0x02,0x38,0x00 } },
+{  16, 0x9c90, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x16,0x90,0x87,0x80,0x20,0xe0 } },
+{  16, 0x9ca0, 0, {0x08,0x58,0x02,0x16,0x14,0x84,0x81,0x21,0xe0,0x29,0x39,0x02,0x5e,0x00,0xb7,0x80 } },
+{  16, 0x9cb0, 0, {0x28,0xe0,0x08,0x78,0x02,0x7a,0x80,0x96,0x81,0x21,0xe0,0x09,0xf8,0x02,0x48,0x00 } },
+{  16, 0x9cc0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x09,0x8b,0x10,0x38,0x44 } },
+{  16, 0x9cd0, 0, {0x4d,0x25,0x12,0x0c,0x00,0xc2,0x10,0x22,0xc8,0x0a,0x38,0x03,0xcc,0x00,0xf3,0x10 } },
+{  16, 0x9ce0, 0, {0x2c,0xc0,0x0c,0x30,0x03,0x8a,0xc0,0xd9,0x10,0x32,0x40,0x2d,0x10,0x03,0x12,0x02 } },
+{  16, 0x9cf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x80,0xff,0x00,0x3f,0x40 } },
+{  16, 0x9d00, 0, {0x0f,0xf0,0x03,0xf4,0x40,0xed,0x00,0x3f,0xc0,0x0e,0xf3,0x03,0xbc,0x04,0xff,0x00 } },
+{  16, 0x9d10, 0, {0x3f,0xc2,0x0f,0xf0,0x0b,0xd4,0x00,0xff,0x10,0xbf,0x80,0x0e,0xf0,0x03,0xd0,0x06 } },
+{  16, 0x9d20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xfa,0x00,0xcb,0x02,0x3e,0xc0 } },
+{  16, 0x9d30, 0, {0x0f,0x90,0x03,0xa0,0x00,0xcb,0x00,0x3a,0xca,0x0c,0xb3,0x13,0xaf,0x24,0xcb,0x48 } },
+{  16, 0x9d40, 0, {0x1e,0xc8,0x0f,0xb6,0x03,0x2c,0x00,0xfa,0x00,0x3e,0xc0,0x0f,0x90,0x03,0xea,0x00 } },
+{  16, 0x9d50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x08,0x87,0x20,0x2d,0xc4 } },
+{  16, 0x9d60, 0, {0x0b,0x50,0x12,0xdc,0x04,0x87,0x00,0x2c,0xc0,0x08,0x70,0xa2,0x1d,0x00,0xa7,0x40 } },
+{  16, 0x9d70, 0, {0x25,0xcb,0x8b,0x74,0x82,0x1c,0x00,0xb7,0x00,0x2d,0xc1,0x0b,0x70,0x02,0xd2,0x04 } },
+{  16, 0x9d80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x01,0x87,0x90,0x2d,0xe0 } },
+{  16, 0x9d90, 0, {0x0b,0x78,0x02,0xce,0x00,0x86,0x80,0x2d,0xe4,0x29,0x7a,0x02,0x9e,0x80,0x87,0xa0 } },
+{  16, 0x9da0, 0, {0x6d,0xe8,0x0b,0x78,0x02,0x1e,0x00,0xb5,0x80,0x2d,0x60,0x0b,0x78,0x02,0xf0,0x00 } },
+{  16, 0x9db0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcd,0x00,0x83,0x02,0x2c,0xe0 } },
+{  16, 0x9dc0, 0, {0x0b,0x30,0x02,0xcc,0x00,0x83,0xe0,0x2c,0xc0,0x08,0x30,0x02,0x0c,0x00,0xa3,0x00 } },
+{  16, 0x9dd0, 0, {0x24,0xc0,0x0b,0xb0,0x02,0x0e,0x20,0xb3,0x08,0x2c,0xc0,0x0b,0x30,0x02,0xd2,0x04 } },
+{  16, 0x9de0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x82,0xca,0x00,0x3e,0xa8 } },
+{  16, 0x9df0, 0, {0x0f,0xe0,0x03,0xf8,0x02,0x8e,0x80,0x3e,0x80,0x0d,0xa0,0x5b,0xa8,0x00,0xca,0x00 } },
+{  16, 0x9e00, 0, {0x3e,0x80,0x0f,0xa0,0x03,0x3b,0x80,0xfe,0x42,0x2f,0x80,0x0f,0xa8,0x03,0xfa,0x04 } },
+{  16, 0x9e10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x20,0xf8,0x00,0x3e,0x00 } },
+{  16, 0x9e20, 0, {0x0f,0x06,0x03,0xc0,0x00,0xf8,0x11,0x3e,0x00,0x0f,0x00,0x03,0xe0,0x00,0xf8,0x00 } },
+{  16, 0x9e30, 0, {0x36,0x00,0x0f,0x80,0x0b,0xe0,0x00,0xf8,0x04,0x3e,0x20,0x0f,0x81,0x03,0xd2,0x00 } },
+{  16, 0x9e40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x00,0x3e,0x40 } },
+{  16, 0x9e50, 0, {0x0c,0x9a,0x03,0x24,0x40,0xc9,0xc0,0x3e,0x40,0x4c,0x90,0x03,0x24,0x00,0xf9,0x00 } },
+{  16, 0x9e60, 0, {0x36,0x40,0x07,0x90,0x03,0x24,0x00,0xc9,0x04,0x32,0x60,0x0f,0x90,0x03,0xc2,0x04 } },
+{  16, 0x9e70, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x02,0x2e,0x40 } },
+{  16, 0x9e80, 0, {0x0a,0x92,0x02,0x25,0x02,0x89,0xe0,0x2e,0x40,0x98,0x90,0x02,0x24,0x00,0xb9,0x00 } },
+{  16, 0x9e90, 0, {0x22,0x40,0x09,0x90,0x02,0x04,0x00,0xd9,0x00,0x22,0x44,0x0b,0x9c,0x02,0xe0,0x00 } },
+{  16, 0x9ea0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x2c,0x00,0xb9,0x00,0x2c,0x40 } },
+{  16, 0x9eb0, 0, {0x08,0x90,0x02,0x24,0x28,0x89,0x00,0x2c,0x40,0x68,0x90,0x42,0x24,0x0c,0xb1,0x04 } },
+{  16, 0x9ec0, 0, {0x26,0x40,0x0b,0x90,0x0a,0x2c,0x80,0x81,0x00,0x22,0x40,0xcb,0x92,0x82,0xc6,0x00 } },
+{  16, 0x9ed0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0xb1,0x20,0x2c,0x48 } },
+{  16, 0x9ee0, 0, {0x0a,0x12,0x02,0x04,0x80,0x81,0x21,0x2c,0x4c,0x08,0x11,0x02,0x04,0x08,0xb1,0x10 } },
+{  16, 0x9ef0, 0, {0x20,0x4c,0x09,0x12,0x02,0x24,0x01,0x91,0x20,0xa0,0x48,0x0b,0x10,0x02,0xc2,0x01 } },
+{  16, 0x9f00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x41,0xe0,0xf8,0x50,0x3e,0x14 } },
+{  16, 0x9f10, 0, {0x0c,0x85,0x03,0x21,0x40,0xc8,0x50,0x3e,0x10,0x08,0x06,0x83,0x01,0xf0,0xf8,0x68 } },
+{  16, 0x9f20, 0, {0x36,0x10,0x0f,0x05,0x03,0x29,0x40,0xc8,0x50,0x32,0x94,0x0f,0x85,0x03,0xee,0x03 } },
+{  16, 0x9f30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x00,0xf9,0x10,0x3f,0x44 } },
+{  16, 0x9f40, 0, {0x0f,0xd1,0x0b,0xf4,0x40,0xfd,0x12,0x2e,0x4c,0x03,0x92,0x0b,0xe4,0x00,0xf9,0x20 } },
+{  16, 0x9f50, 0, {0x3e,0x4c,0x0f,0x91,0x03,0xfc,0x00,0xfd,0x10,0x3f,0x44,0x0f,0xd0,0x03,0xe6,0x06 } },
+{  16, 0x9f60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x20,0xc9,0x01,0x3e,0x40 } },
+{  16, 0x9f70, 0, {0x0f,0xd0,0x03,0x3c,0x00,0xbd,0x00,0x32,0x63,0x0c,0x9e,0x43,0x27,0x00,0xe9,0xc0 } },
+{  16, 0x9f80, 0, {0x3e,0x68,0x0c,0x98,0x03,0x34,0x00,0xf9,0x10,0x3f,0x40,0x0f,0xd0,0x03,0xc6,0x00 } },
+{  16, 0x9f90, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xc2,0x20,0xd8,0x00,0x2e,0x00 } },
+{  16, 0x9fa0, 0, {0x0b,0x80,0x52,0x28,0x04,0xb8,0x00,0x22,0x38,0x08,0x88,0x03,0x62,0x00,0x88,0xf0 } },
+{  16, 0x9fb0, 0, {0x2e,0x3a,0x48,0x8f,0x0a,0x20,0x00,0xb0,0x80,0x2e,0x00,0x0b,0x80,0x02,0xce,0x04 } },
+{  16, 0x9fc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0x81,0x00,0x2c,0x40 } },
+{  16, 0x9fd0, 0, {0x0b,0x10,0x02,0x04,0x00,0xb1,0x00,0x20,0x42,0x48,0x14,0x42,0x05,0x80,0xa1,0x20 } },
+{  16, 0x9fe0, 0, {0x2c,0x44,0x08,0x10,0x82,0x04,0x00,0xb1,0x20,0x2c,0x40,0x0b,0x10,0x02,0xc2,0x01 } },
+{  16, 0x9ff0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa5,0x01,0x99,0x00,0x2e,0x40 } },
+{  16, 0xa000, 0, {0x0b,0x90,0x02,0x24,0x40,0xbb,0x01,0x22,0x41,0x08,0x90,0x12,0x24,0x00,0xa9,0x00 } },
+{  16, 0xa010, 0, {0x2c,0x40,0x08,0x10,0x40,0x24,0x08,0xb9,0x40,0x6e,0x50,0x0b,0x92,0x02,0xc6,0x04 } },
+{  16, 0xa020, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x14,0xc9,0x05,0x3e,0x41 } },
+{  16, 0xa030, 0, {0x0f,0x90,0x0b,0x24,0x04,0xf9,0x08,0xb2,0x40,0x2c,0x90,0x0a,0x24,0x00,0xe9,0x00 } },
+{  16, 0xa040, 0, {0x3e,0x40,0x2c,0x90,0x03,0x27,0x00,0xf9,0x80,0x3e,0x60,0x0f,0x90,0x03,0xe8,0x04 } },
+{  16, 0xa050, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x84,0x88,0xf9,0x00,0x3e,0x48 } },
+{  16, 0xa060, 0, {0x0f,0x99,0x03,0xe6,0x00,0xf9,0x02,0x3c,0x40,0xaf,0x10,0x03,0xe4,0x12,0xd9,0x04 } },
+{  16, 0xa070, 0, {0x3e,0x40,0x0f,0x90,0x03,0xe5,0x00,0xf9,0xc0,0x3e,0x64,0x0f,0x90,0x83,0xca,0x00 } },
+{  16, 0xa080, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xc8,0x00,0x3e,0x00 } },
+{  16, 0xa090, 0, {0x0f,0x80,0x03,0x21,0x00,0xc8,0x40,0xb2,0x00,0x0c,0x80,0x03,0x20,0x10,0xc8,0x00 } },
+{  16, 0xa0a0, 0, {0x32,0x00,0x0c,0x80,0x03,0xe0,0x80,0xf8,0x04,0x32,0x00,0x2c,0x80,0x0b,0x0a,0x04 } },
+{  16, 0xa0b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0xca,0x00,0x2e,0x80 } },
+{  16, 0xa0c0, 0, {0x0b,0xe8,0x0a,0x38,0x10,0x8e,0xc0,0x22,0x80,0x0d,0xa0,0x02,0x28,0x00,0x0a,0x04 } },
+{  16, 0xa0d0, 0, {0x02,0x80,0x28,0xa0,0x02,0xfb,0x00,0xba,0x00,0x37,0xb0,0x48,0xea,0x02,0x0a,0x00 } },
+{  16, 0xa0e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0x01,0x2c,0xc0 } },
+{  16, 0xa0f0, 0, {0x8b,0xb0,0x42,0x0c,0x90,0x9b,0x20,0x20,0xc0,0x48,0x30,0x42,0x2c,0x00,0x83,0x00 } },
+{  16, 0xa100, 0, {0x20,0xc0,0x08,0x30,0x02,0xcd,0x40,0xb3,0x00,0x24,0xc8,0x08,0x38,0x02,0x0a,0x00 } },
+{  16, 0xa110, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x14,0x00,0x87,0x00,0x2d,0xc0 } },
+{  16, 0xa120, 0, {0x0b,0x24,0x06,0x16,0x00,0x93,0x08,0x21,0xc8,0x09,0x31,0x02,0x0c,0x80,0x87,0xa0 } },
+{  16, 0xa130, 0, {0x21,0xc0,0x18,0x72,0x02,0xdc,0x00,0xb7,0xb4,0x24,0xe3,0x08,0x78,0x02,0x28,0x00 } },
+{  16, 0xa140, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x02,0x97,0xa0,0x3d,0xf0 } },
+{  16, 0xa150, 0, {0x0f,0x48,0x03,0x3e,0x00,0xd6,0x80,0x30,0xe0,0x2c,0x7a,0x02,0x1e,0x82,0xc3,0xf0 } },
+{  16, 0xa160, 0, {0x33,0xec,0x0c,0x7c,0x03,0xd6,0x00,0xf7,0x80,0x35,0xe0,0x0c,0xd8,0x03,0x2a,0x02 } },
+{  16, 0xa170, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x19,0xa5,0xa0,0xfb,0x00,0x3e,0xca } },
+{  16, 0xa180, 0, {0x0f,0x80,0x03,0xec,0x02,0xea,0x00,0x3e,0xc6,0x0f,0xb4,0x0b,0xed,0x40,0xfb,0x00 } },
+{  16, 0xa190, 0, {0xbe,0xc0,0x0f,0xb6,0x43,0xe0,0x00,0xfb,0x02,0x3e,0x80,0x0f,0x90,0x03,0xc2,0x06 } },
+{  16, 0xa1a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x02,0xcf,0x88,0x3f,0xe0 } },
+{  16, 0xa1b0, 0, {0x0c,0xb9,0x03,0xfe,0x00,0xdd,0x81,0x33,0xe0,0x8c,0xfc,0x03,0x3f,0x04,0xcf,0x80 } },
+{  16, 0xa1c0, 0, {0x33,0xe2,0x4f,0xfc,0x03,0x3e,0x00,0xcf,0xc0,0x33,0x64,0x0c,0xf8,0x03,0xc0,0x00 } },
+{  16, 0xa1d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x94,0x40,0x87,0x00,0x2f,0xc1 } },
+{  16, 0xa1e0, 0, {0x0d,0x69,0xa2,0xd0,0x40,0xbc,0x00,0x23,0xc0,0x08,0xf0,0x02,0x9c,0x00,0x87,0x00 } },
+{  16, 0xa1f0, 0, {0x21,0xc0,0x0b,0x70,0x0a,0x3c,0x04,0x87,0x10,0x21,0x4c,0x08,0x60,0x02,0xea,0x04 } },
+{  16, 0xa200, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9e,0x00,0x87,0x00,0x2d,0xc0 } },
+{  16, 0xa210, 0, {0x09,0x62,0x02,0xd8,0x00,0x97,0x00,0x21,0xc4,0x08,0x70,0x02,0x0c,0x40,0x97,0x00 } },
+{  16, 0xa220, 0, {0x21,0xc4,0x0b,0x30,0x02,0x58,0x00,0xa7,0x08,0x21,0x80,0x08,0x60,0x82,0xc0,0x00 } },
+{  16, 0xa230, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xe4,0x25,0x83,0x00,0x2c,0xc0 } },
+{  16, 0xa240, 0, {0x09,0x22,0x02,0xcc,0x20,0xb2,0x00,0x20,0xc0,0x28,0xb0,0x02,0x8c,0x00,0x93,0x00 } },
+{  16, 0xa250, 0, {0x20,0xc0,0x0b,0x30,0x42,0x6c,0x20,0x83,0x08,0x20,0xe2,0x08,0xb8,0x02,0xc8,0x04 } },
+{  16, 0xa260, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa4,0x00,0xcf,0x00,0x3f,0xc0 } },
+{  16, 0xa270, 0, {0x0d,0x9c,0x03,0xe8,0x00,0xdb,0x80,0x33,0xc0,0x0c,0xf0,0x0b,0x3c,0x06,0xdf,0x00 } },
+{  16, 0xa280, 0, {0xb3,0xc0,0x0b,0xf0,0x07,0x68,0x00,0xef,0x40,0x32,0xa8,0x0c,0xa8,0x03,0xea,0x04 } },
+{  16, 0xa290, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xfb,0x00,0x2e,0xc0 } },
+{  16, 0xa2a0, 0, {0x0f,0x94,0x03,0xc5,0x40,0xfa,0x30,0x3e,0xc0,0x0f,0xb0,0x03,0x6c,0x00,0xeb,0x00 } },
+{  16, 0xa2b0, 0, {0x3e,0xc0,0x0f,0x30,0x13,0xad,0x40,0xfb,0x02,0x3e,0xd0,0x0f,0xb4,0x03,0xe0,0x00 } },
+{  16, 0xa2c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xe4,0x00,0xc7,0x00,0x31,0xc1 } },
+{  16, 0xa2d0, 0, {0x8c,0xd0,0x03,0x34,0x00,0xcd,0x00,0x3d,0xc0,0x0c,0xf0,0x01,0x7c,0x00,0xdb,0x01 } },
+{  16, 0xa2e0, 0, {0x3d,0xc0,0x4c,0xf0,0x0b,0x30,0x02,0xc3,0x00,0x32,0x00,0x0f,0xd0,0x03,0x00,0x44 } },
+{  16, 0xa2f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6e,0x40,0x8b,0x00,0x2a,0xc0 } },
+{  16, 0xa300, 0, {0x28,0x84,0x42,0x22,0x80,0x88,0x80,0x3a,0xc0,0x0d,0xb0,0x02,0xac,0x08,0x8b,0x00 } },
+{  16, 0xa310, 0, {0x2e,0xc0,0x08,0xb0,0x02,0x23,0x20,0x8b,0x00,0x22,0x30,0x8b,0x8c,0x02,0x20,0x40 } },
+{  16, 0xa320, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x24,0x00,0x8b,0x00,0x22,0xc0 } },
+{  16, 0xa330, 0, {0x08,0x38,0x86,0x2a,0x00,0x89,0x80,0x2a,0xc0,0x08,0xb0,0x02,0xcc,0x00,0x9b,0x00 } },
+{  16, 0xa340, 0, {0x2e,0xc0,0x08,0xb0,0x42,0x26,0x00,0x8b,0x00,0x22,0x71,0x0b,0x8c,0x02,0x20,0x00 } },
+{  16, 0xa350, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0x83,0x00,0x28,0xc0 } },
+{  16, 0xa360, 0, {0x08,0x32,0x42,0x00,0x00,0x81,0x00,0x28,0xc0,0x09,0x30,0x52,0x8c,0x08,0x83,0x00 } },
+{  16, 0xa370, 0, {0x2c,0xc0,0x18,0x30,0x06,0x00,0x00,0x83,0x00,0xa0,0x00,0x0b,0x00,0x02,0x02,0x01 } },
+{  16, 0xa380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x74,0x02,0x8b,0x00,0x33,0xc0 } },
+{  16, 0xa390, 0, {0x0c,0x92,0x0b,0x20,0x02,0xc8,0x00,0x3b,0xc0,0x0c,0xf5,0x03,0xfc,0x00,0xdf,0x01 } },
+{  16, 0xa3a0, 0, {0x3f,0xc1,0x04,0xf0,0x33,0x21,0x40,0xcf,0x00,0x32,0x00,0x0f,0x80,0x0b,0x00,0x03 } },
+{  16, 0xa3b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xfc,0x00,0xff,0x00,0x3f,0xc0 } },
+{  16, 0xa3c0, 0, {0x0f,0xc4,0x03,0xf0,0x00,0x9c,0x00,0x3b,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x00 } },
+{  16, 0xa3d0, 0, {0x2f,0xc0,0x0f,0xf0,0x03,0xf0,0x80,0xff,0x00,0x3f,0x00,0x0f,0xc0,0x03,0xe8,0x06 } },
+{  16, 0xa3e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0xc0,0xff,0xa0,0x31,0x24 } },
+{  16, 0xa3f0, 0, {0x0e,0xf0,0x63,0x10,0x04,0xef,0x64,0x3f,0xc0,0x4c,0xf3,0x03,0x1c,0x80,0xdf,0x08 } },
+{  16, 0xa400, 0, {0x37,0xc0,0x0f,0xf0,0x03,0xf0,0xa0,0xfc,0x00,0x31,0x08,0x2c,0xd2,0x03,0xf0,0x00 } },
+{  16, 0xa410, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe1,0x00,0xbb,0xc1,0x22,0x48 } },
+{  16, 0xa420, 0, {0x08,0xfd,0x02,0x2e,0x00,0x97,0x00,0x2f,0xc2,0x48,0x71,0x23,0x7e,0x40,0xbf,0x00 } },
+{  16, 0xa430, 0, {0x21,0xc5,0x4b,0xf5,0x02,0xef,0x00,0xbb,0x40,0x36,0xe0,0x08,0xa8,0x02,0xe0,0x04 } },
+{  16, 0xa440, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc5,0x84,0xb3,0x11,0xa2,0xc9 } },
+{  16, 0xa450, 0, {0x0a,0x30,0x02,0x00,0x01,0xb3,0x30,0x28,0xc4,0x08,0x32,0x42,0x0c,0x00,0xa3,0x08 } },
+{  16, 0xa460, 0, {0xa0,0xca,0x0a,0x32,0x82,0x80,0x10,0xb0,0x41,0x24,0x11,0x08,0x31,0x02,0xe2,0x01 } },
+{  16, 0xa470, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa5,0x00,0xbb,0x00,0x22,0xe1 } },
+{  16, 0xa480, 0, {0x28,0xb0,0x02,0x2c,0x80,0x9b,0x00,0x2e,0xc0,0x08,0xb0,0x02,0x6c,0x00,0xb3,0x00 } },
+{  16, 0xa490, 0, {0x22,0xc0,0x0b,0xb0,0x00,0xec,0x20,0xbb,0x00,0x26,0xc0,0x08,0x80,0x02,0xf0,0x04 } },
+{  16, 0xa4a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe3,0x40,0xf7,0x04,0x32,0xc0 } },
+{  16, 0xa4b0, 0, {0x4e,0xb0,0x23,0x2e,0x20,0xeb,0x00,0x1e,0xc0,0x0c,0xb0,0x01,0x2c,0x00,0xfb,0x00 } },
+{  16, 0xa4c0, 0, {0x36,0xc0,0x1f,0xb0,0x03,0xe1,0x40,0xfb,0x00,0x36,0x98,0x0c,0x90,0x03,0xd0,0x04 } },
+{  16, 0xa4d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb6,0x04,0xff,0x02,0x3f,0xc0 } },
+{  16, 0xa4e0, 0, {0x0f,0xf0,0x03,0xfe,0x00,0xef,0x02,0x3d,0xc0,0x0f,0xf0,0x23,0xfc,0x00,0xff,0x00 } },
+{  16, 0xa4f0, 0, {0x3f,0xc0,0x4f,0xf0,0x03,0xfc,0x00,0xf4,0x00,0x3b,0x40,0x0f,0xa0,0x13,0xf8,0x00 } },
+{  16, 0xa500, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xaa,0x20,0xeb,0x10,0x36,0xc0 } },
+{  16, 0xa510, 0, {0x0d,0xb0,0x07,0xec,0x20,0xdb,0x00,0x32,0xc0,0x0c,0xb0,0x02,0x6c,0x20,0xeb,0x00 } },
+{  16, 0xa520, 0, {0x3e,0xc1,0x0d,0xb0,0x03,0xe0,0x20,0xdb,0xa0,0x32,0x90,0x4c,0xb0,0x0b,0x10,0x04 } },
+{  16, 0xa530, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2d,0x00,0x8f,0x80,0x20,0xc1 } },
+{  16, 0xa540, 0, {0x08,0x70,0x12,0xcf,0x00,0x8f,0x00,0xa3,0xc0,0x0d,0xf0,0x02,0x3c,0x00,0x8f,0x00 } },
+{  16, 0xa550, 0, {0x37,0xc0,0x88,0xf0,0x02,0xec,0x00,0x88,0x00,0x20,0x40,0x08,0x80,0x02,0x32,0x00 } },
+{  16, 0xa560, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xa3,0x80,0x24,0x81 } },
+{  16, 0xa570, 0, {0x09,0x30,0x06,0xcc,0x40,0x93,0x00,0x28,0xc1,0x08,0xb0,0x02,0xcf,0x40,0xa3,0x00 } },
+{  16, 0xa580, 0, {0x2c,0xc0,0x09,0x30,0x02,0xcd,0x00,0x90,0x40,0x60,0x40,0x28,0x10,0x02,0x38,0x00 } },
+{  16, 0xa590, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x0e,0x00,0x87,0x80,0x23,0xe0 } },
+{  16, 0xa5a0, 0, {0x48,0x79,0x02,0xde,0x41,0x97,0x80,0x29,0xe0,0x19,0x78,0x06,0x9e,0x00,0x87,0x80 } },
+{  16, 0xa5b0, 0, {0x25,0xe0,0x08,0x78,0x02,0xd2,0x03,0x83,0x80,0x21,0xa0,0x08,0x68,0x02,0x08,0x00 } },
+{  16, 0xa5c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xa3,0x00,0x34,0xc0 } },
+{  16, 0xa5d0, 0, {0x0d,0x30,0x42,0xcc,0x01,0xd3,0x10,0x3a,0xc5,0x0c,0x39,0x03,0xcc,0x00,0xe3,0x04 } },
+{  16, 0xa5e0, 0, {0x3c,0xc4,0x0d,0x30,0x03,0xce,0x00,0xd0,0x00,0x30,0x40,0x0c,0x30,0x03,0x12,0x02 } },
+{  16, 0xa5f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x00,0xf7,0x00,0x3f,0xc0 } },
+{  16, 0xa600, 0, {0x1f,0xf0,0x53,0xfc,0x00,0xef,0x08,0x37,0xd1,0x0f,0xf0,0x83,0x7c,0x00,0xf7,0x40 } },
+{  16, 0xa610, 0, {0x3f,0xc1,0x0f,0xf1,0x03,0xd0,0x00,0xff,0x00,0xbf,0x84,0x0f,0xc8,0x03,0xd0,0x06 } },
+{  16, 0xa620, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe0,0x00,0xfb,0x00,0x3e,0xe0 } },
+{  16, 0xa630, 0, {0x2c,0xbe,0x83,0xec,0x00,0xeb,0x40,0x3e,0xc0,0x0f,0xb4,0x03,0xed,0x20,0xfb,0x10 } },
+{  16, 0xa640, 0, {0xb6,0xd2,0x0f,0xb4,0x83,0xec,0x00,0xdb,0x80,0x36,0xc1,0x0c,0x90,0x21,0x2a,0x00 } },
+{  16, 0xa650, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x00,0xb7,0x00,0x2f,0xc0 } },
+{  16, 0xa660, 0, {0x08,0x36,0x02,0x0c,0x08,0x87,0x30,0x2d,0xd9,0x8b,0x72,0x86,0xdd,0x00,0xb3,0x20 } },
+{  16, 0xa670, 0, {0x21,0xc8,0x0b,0x74,0x02,0xd0,0x02,0x84,0x00,0xa0,0x00,0x28,0x20,0x02,0x12,0x04 } },
+{  16, 0xa680, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x00,0xb7,0x80,0x2d,0xe0 } },
+{  16, 0xa690, 0, {0x08,0x7a,0x02,0x9d,0x00,0xa7,0xa0,0x2d,0xe0,0x0b,0x78,0x02,0x9e,0x80,0xa7,0x80 } },
+{  16, 0xa6a0, 0, {0x21,0xe4,0x08,0x7a,0x26,0x9e,0x18,0x83,0x04,0x21,0xe0,0x08,0x78,0x0a,0x70,0x00 } },
+{  16, 0xa6b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xb3,0x00,0x2c,0xe0 } },
+{  16, 0xa6c0, 0, {0x58,0x30,0x12,0x0e,0x82,0x83,0x00,0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x01,0xb3,0x00 } },
+{  16, 0xa6d0, 0, {0x20,0xc1,0x0b,0x30,0x02,0xc0,0x08,0x88,0xd2,0x20,0x20,0x08,0x00,0x02,0x52,0x04 } },
+{  16, 0xa6e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x60,0xfa,0x00,0x3f,0x82 } },
+{  16, 0xa6f0, 0, {0x0c,0xa0,0x03,0xfa,0x00,0xaa,0x00,0x1e,0x80,0x8f,0xa0,0x03,0xe8,0x00,0xf2,0x00 } },
+{  16, 0xa700, 0, {0x32,0x80,0x1f,0xa0,0x03,0xe8,0x00,0xda,0x00,0x36,0x88,0xac,0xe0,0x03,0x7a,0x04 } },
+{  16, 0xa710, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe1,0x00,0xf8,0x00,0x3e,0x20 } },
+{  16, 0xa720, 0, {0x4f,0x80,0x03,0xe1,0x00,0xf0,0x00,0x3c,0x00,0x0b,0x80,0x03,0xe0,0x00,0xf8,0x02 } },
+{  16, 0xa730, 0, {0x3a,0x00,0x0f,0x80,0x43,0xf1,0x00,0xfc,0x0a,0x3d,0x00,0x0f,0xc0,0x03,0x92,0x00 } },
+{  16, 0xa740, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe6,0x00,0xc9,0x90,0x3e,0x40 } },
+{  16, 0xa750, 0, {0x0f,0x92,0x03,0xe4,0x00,0xd9,0x00,0x32,0x40,0x04,0x90,0x07,0xe7,0x00,0xf9,0x10 } },
+{  16, 0xa760, 0, {0x30,0x40,0x0c,0x90,0x43,0xe4,0x09,0xd9,0x80,0x22,0x40,0x2c,0x10,0x0b,0x02,0x04 } },
+{  16, 0xa770, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x60,0x89,0xc0,0x2e,0x40 } },
+{  16, 0xa780, 0, {0x0b,0x98,0x26,0xc5,0x80,0x89,0x00,0x22,0x40,0x28,0x90,0x12,0xe7,0x10,0xb9,0x00 } },
+{  16, 0xa790, 0, {0x36,0x40,0x28,0x90,0x12,0xc5,0x83,0xc9,0x80,0xb6,0x40,0x08,0x90,0x02,0x20,0x00 } },
+{  16, 0xa7a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x00,0x89,0x40,0x2e,0x41 } },
+{  16, 0xa7b0, 0, {0x4b,0x90,0x02,0xe4,0x00,0x99,0x00,0xa2,0x40,0x0a,0x90,0x02,0xe5,0x00,0xb9,0x00 } },
+{  16, 0xa7c0, 0, {0xe2,0x41,0x08,0x90,0x42,0xe4,0x00,0x9d,0x50,0xab,0x4a,0x08,0xd0,0x26,0x06,0x00 } },
+{  16, 0xa7d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x82,0x81,0x20,0x2c,0x50 } },
+{  16, 0xa7e0, 0, {0x0b,0x10,0x02,0xe4,0x00,0x81,0x40,0x20,0x50,0x4a,0x14,0x32,0xc4,0x00,0xb1,0x40 } },
+{  16, 0xa7f0, 0, {0x24,0x51,0x18,0x14,0x12,0xd4,0x00,0x85,0x40,0x2d,0x40,0x08,0x50,0x06,0x02,0x01 } },
+{  16, 0xa800, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xc8,0x00,0x3e,0x00 } },
+{  16, 0xa810, 0, {0x0f,0x80,0x02,0xe0,0x00,0xd8,0x00,0x32,0x00,0x0a,0x80,0x02,0xe0,0x10,0xf8,0x00 } },
+{  16, 0xa820, 0, {0x32,0x00,0x04,0x80,0x03,0xe0,0x00,0xd8,0x00,0x3a,0x00,0x0c,0xc0,0x03,0x2e,0x03 } },
+{  16, 0xa830, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x40,0xf9,0x10,0x3f,0x41 } },
+{  16, 0xa840, 0, {0x0f,0x94,0x03,0xf5,0x00,0xf9,0x40,0x3e,0x50,0x0d,0x94,0x03,0xe5,0x10,0xf9,0x40 } },
+{  16, 0xa850, 0, {0x3e,0x50,0x4f,0x94,0x03,0xc5,0x00,0xe9,0x41,0x36,0x50,0x0f,0x94,0x03,0xe6,0x06 } },
+{  16, 0xa860, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x00,0xfd,0xa8,0x3a,0x40 } },
+{  16, 0xa870, 0, {0x0c,0xd8,0x23,0x36,0x00,0xe9,0xa0,0x3e,0x78,0x0f,0x9e,0x03,0xb6,0x80,0xcd,0xe2 } },
+{  16, 0xa880, 0, {0x32,0x68,0x0c,0x9b,0x03,0x36,0x82,0x4d,0xa0,0x37,0x68,0x8c,0x98,0x03,0x06,0x00 } },
+{  16, 0xa890, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xeb,0xa0,0xb8,0x40,0x20,0x20 } },
+{  16, 0xa8a0, 0, {0x08,0x85,0x02,0x21,0x51,0x88,0xc0,0x2e,0x29,0x0b,0x8e,0x02,0xe1,0x00,0xd8,0xe0 } },
+{  16, 0xa8b0, 0, {0x22,0x32,0x0d,0x8d,0x23,0x61,0x48,0x98,0xd4,0xa2,0x10,0x28,0x84,0x02,0x0e,0x04 } },
+{  16, 0xa8c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb3,0x00,0x2a,0x4a } },
+{  16, 0xa8d0, 0, {0x28,0x10,0x4e,0xa4,0x08,0xa1,0x68,0x28,0x44,0x0b,0x14,0x02,0xc5,0x00,0x81,0x40 } },
+{  16, 0xa8e0, 0, {0xa0,0x50,0x08,0x10,0x02,0x04,0x02,0x91,0x2a,0x20,0x44,0x28,0x14,0x4a,0x02,0x01 } },
+{  16, 0xa8f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xac,0x80,0xb9,0x00,0x22,0x40 } },
+{  16, 0xa900, 0, {0x48,0x90,0x06,0xa4,0x00,0xa9,0x00,0x2e,0x40,0x0b,0x90,0x22,0xe4,0x00,0x99,0x00 } },
+{  16, 0xa910, 0, {0x22,0x40,0x09,0x10,0x02,0x64,0x02,0x99,0x00,0x22,0x40,0x08,0x90,0x02,0x06,0x04 } },
+{  16, 0xa920, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x00,0x38,0x58 } },
+{  16, 0xa930, 0, {0x0c,0x90,0x53,0x84,0x14,0xa9,0x04,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xc9,0x00 } },
+{  16, 0xa940, 0, {0x32,0x40,0x0c,0x90,0x03,0x24,0x04,0xd9,0x00,0xb6,0x40,0x4c,0x90,0x0b,0x28,0x04 } },
+{  16, 0xa950, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x02,0x3e,0x49 } },
+{  16, 0xa960, 0, {0x0f,0x10,0x43,0x64,0x00,0xd9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xc4,0x00,0xf1,0x02 } },
+{  16, 0xa970, 0, {0x3e,0x40,0x0f,0x90,0x03,0xc4,0x02,0xe9,0x04,0x3c,0x40,0x0f,0x1c,0x03,0xca,0x00 } },
+{  16, 0xa980, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x80,0xc8,0x20,0x3e,0x00 } },
+{  16, 0xa990, 0, {0x8c,0x80,0x0b,0x20,0x00,0xe8,0x02,0x3e,0x00,0x0f,0x80,0x03,0xa0,0x82,0xc8,0x00 } },
+{  16, 0xa9a0, 0, {0x6c,0x00,0x0f,0x80,0x03,0x20,0x10,0xc8,0x00,0x32,0x02,0x0c,0x80,0x03,0x0a,0x04 } },
+{  16, 0xa9b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x38,0x00,0x86,0x00,0x2e,0x80 } },
+{  16, 0xa9c0, 0, {0x68,0xa8,0x80,0x3a,0x00,0x8a,0x00,0x2e,0x80,0x0b,0xa0,0x02,0xf8,0x00,0x8a,0x00 } },
+{  16, 0xa9d0, 0, {0x2e,0x80,0x0b,0xa0,0x0a,0x3a,0x00,0x8e,0x10,0x23,0x80,0x08,0xa0,0x03,0x0a,0x00 } },
+{  16, 0xa9e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4d,0x00,0x83,0x00,0x2c,0xc0 } },
+{  16, 0xa9f0, 0, {0x08,0x38,0x00,0x0c,0x60,0x23,0x00,0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x40,0x83,0x00 } },
+{  16, 0xaa00, 0, {0x2c,0xc0,0x0b,0x30,0x02,0x0c,0x02,0x8a,0x80,0xa0,0xe0,0x28,0x30,0x0a,0x4a,0x00 } },
+{  16, 0xaa10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x16,0x20,0x87,0x02,0x2d,0xc1 } },
+{  16, 0xaa20, 0, {0x48,0x70,0x12,0x7c,0x00,0xa7,0x20,0x2d,0xc9,0x0b,0x72,0x00,0xdc,0x00,0x87,0x08 } },
+{  16, 0xaa30, 0, {0x2d,0xc4,0x1b,0x32,0x02,0x1d,0x01,0x87,0x42,0x21,0xc2,0x08,0x70,0x02,0x28,0x00 } },
+{  16, 0xaa40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x02,0xc7,0x80,0x3d,0xec } },
+{  16, 0xaa50, 0, {0x0c,0x58,0x03,0x1e,0x00,0xe7,0x80,0x3d,0xec,0x0f,0x7f,0x03,0x96,0x00,0xc7,0x80 } },
+{  16, 0xaa60, 0, {0x2d,0xe2,0x07,0x79,0x03,0x0a,0x06,0xc3,0x80,0x30,0x20,0x8c,0x38,0x03,0x6a,0x02 } },
+{  16, 0xaa70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xfb,0x00,0x3e,0xc0 } },
+{  16, 0xaa80, 0, {0x0f,0x10,0x43,0x8c,0x00,0xdb,0x38,0x3e,0xd8,0x0f,0xb0,0x03,0xcc,0x04,0xfb,0x44 } },
+{  16, 0xaa90, 0, {0x3e,0xc0,0x8f,0xb6,0x13,0xec,0x02,0xff,0x02,0x3e,0x00,0x0f,0xb0,0x03,0xc2,0x06 } },
+{  16, 0xaaa0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfa,0x00,0xff,0x80,0x31,0xe3 } },
+{  16, 0xaab0, 0, {0x0e,0xf8,0x23,0xfe,0x02,0xdf,0x80,0xb7,0xe2,0x0e,0xf8,0x03,0x7e,0x00,0x6d,0xd0 } },
+{  16, 0xaac0, 0, {0x33,0xe0,0x0c,0xf8,0x9b,0x76,0xc0,0xdf,0x84,0xb3,0xe0,0x04,0xf8,0x03,0xc0,0x00 } },
+{  16, 0xaad0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x90,0x40,0xb7,0x02,0x21,0xc4 } },
+{  16, 0xaae0, 0, {0x08,0x7b,0x42,0xdc,0x00,0x87,0x00,0x21,0xc4,0x0b,0x30,0x00,0x10,0x80,0x8d,0x00 } },
+{  16, 0xaaf0, 0, {0x23,0xc0,0x0d,0xf2,0x02,0x04,0x42,0x8f,0x00,0x29,0xc8,0x28,0x70,0x02,0xea,0x04 } },
+{  16, 0xab00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x00,0xb6,0x00,0x23,0xc0 } },
+{  16, 0xab10, 0, {0x0a,0x72,0x02,0x8c,0x00,0x87,0x00,0x21,0xc0,0x0a,0x30,0x02,0x04,0x01,0xa7,0x02 } },
+{  16, 0xab20, 0, {0x21,0xc0,0x08,0x70,0x42,0x00,0x8a,0x87,0x00,0x21,0xc0,0x28,0x70,0x02,0xc0,0x00 } },
+{  16, 0xab30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xc5,0x00,0xb0,0x00,0xa0,0xd0 } },
+{  16, 0xab40, 0, {0x08,0xb0,0x02,0xc9,0x42,0x8b,0x00,0x20,0xc0,0x0b,0x30,0x22,0x04,0x00,0x83,0x00 } },
+{  16, 0xab50, 0, {0xa0,0xc0,0x49,0x30,0x02,0x45,0x40,0x93,0xc0,0xa8,0xd4,0x00,0x35,0x02,0xc8,0x04 } },
+{  16, 0xab60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xbb,0x00,0x31,0xc0 } },
+{  16, 0xab70, 0, {0x0e,0xb0,0x23,0xcd,0x00,0xdf,0x00,0x37,0xc0,0x0e,0xf0,0x01,0x68,0x00,0xe3,0x00 } },
+{  16, 0xab80, 0, {0x33,0xc0,0x1c,0xf0,0x03,0x45,0x00,0xda,0xc8,0x92,0xd4,0x2c,0xb4,0x03,0xea,0x04 } },
+{  16, 0xab90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe5,0x20,0xfb,0x00,0x3e,0xc0 } },
+{  16, 0xaba0, 0, {0x0f,0xb0,0x03,0xec,0x00,0xfb,0x00,0x3e,0xc0,0x4f,0xb0,0x03,0xad,0x00,0xfb,0x00 } },
+{  16, 0xabb0, 0, {0x7e,0xc0,0x1f,0x30,0x03,0xa4,0x80,0xe9,0x20,0x3c,0xc0,0x0f,0x32,0x03,0xe0,0x00 } },
+{  16, 0xabc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xc7,0x00,0x33,0xc2 } },
+{  16, 0xabd0, 0, {0x2c,0xf0,0x03,0x3e,0x20,0xdb,0x00,0x13,0xc0,0x0c,0x70,0x03,0x3c,0x80,0xef,0x04 } },
+{  16, 0xabe0, 0, {0x73,0xc1,0x0f,0xf0,0x22,0x30,0x00,0xc6,0x00,0xb2,0xc0,0x0c,0xf0,0x03,0x00,0x44 } },
+{  16, 0xabf0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x69,0x00,0x8b,0x44,0xa2,0xc1 } },
+{  16, 0xac00, 0, {0x88,0xb0,0x03,0x6c,0x00,0x8b,0x00,0x22,0xc0,0x28,0xb0,0x0a,0x2d,0x00,0xbb,0x00 } },
+{  16, 0xac10, 0, {0x62,0xc0,0x0b,0xb0,0x02,0x26,0x02,0x8b,0x80,0x22,0xc0,0x08,0xb0,0x03,0x20,0x40 } },
+{  16, 0xac20, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x28,0x01,0x8a,0x08,0x22,0xc0 } },
+{  16, 0xac30, 0, {0x08,0xb2,0x02,0x6c,0x40,0x9b,0x00,0x28,0xc0,0x48,0xb0,0x16,0x29,0x04,0xb9,0x01 } },
+{  16, 0xac40, 0, {0x22,0xc0,0x49,0xb0,0x06,0xae,0x09,0x8b,0x80,0x22,0xe0,0x48,0xb0,0x02,0x20,0x00 } },
+{  16, 0xac50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x02,0x82,0x00,0x22,0xc0 } },
+{  16, 0xac60, 0, {0x88,0xb0,0x02,0x44,0x00,0x83,0x00,0x28,0xc0,0x08,0x30,0x02,0x08,0x00,0xb1,0x00 } },
+{  16, 0xac70, 0, {0x20,0xc0,0x0b,0x30,0x02,0x8c,0x00,0x83,0x80,0x20,0xe0,0x08,0x30,0x0a,0x02,0x01 } },
+{  16, 0xac80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x64,0x00,0xca,0x00,0x33,0xc0 } },
+{  16, 0xac90, 0, {0x0c,0xb2,0x03,0x2c,0x00,0xdf,0x00,0x3b,0xc0,0x4c,0xf5,0x13,0x2c,0x04,0xef,0x00 } },
+{  16, 0xaca0, 0, {0xa3,0xc0,0x0d,0xf0,0x03,0xa8,0x40,0xcb,0x00,0xb2,0x00,0x2c,0xb0,0x03,0x00,0x03 } },
+{  16, 0xacb0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf0,0x00,0xf4,0x00,0x3f,0xc0 } },
+{  16, 0xacc0, 0, {0x0f,0xb1,0x03,0xf0,0x00,0xff,0x00,0x37,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x00 } },
+{  16, 0xacd0, 0, {0x3f,0xc0,0x07,0xf0,0x0b,0x7c,0x08,0xff,0x01,0x3f,0x00,0x0f,0xf0,0x03,0xa8,0x06 } },
+{  16, 0xace0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0xc5,0xed,0x33,0x3b,0xcc } },
+{  16, 0xacf0, 0, {0x0c,0xf0,0x03,0x30,0x40,0xff,0x25,0x3f,0xcc,0x0c,0xf3,0x83,0x3c,0xd0,0xdf,0x48 } },
+{  16, 0xad00, 0, {0x37,0x30,0x4c,0xf3,0x03,0xfd,0x80,0xcf,0x28,0x33,0xd8,0x0c,0xf1,0x03,0x30,0x00 } },
+{  16, 0xad10, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0xd0,0xbb,0x31,0x20,0xcc } },
+{  16, 0xad20, 0, {0x88,0xf3,0x42,0x20,0x50,0xbf,0x90,0x2f,0xc4,0x0a,0xf6,0x02,0x7d,0xc0,0x8f,0x40 } },
+{  16, 0xad30, 0, {0x26,0x40,0x8f,0xf6,0x02,0xfd,0x00,0xff,0x08,0x39,0xc8,0x08,0xf6,0x02,0xa0,0x04 } },
+{  16, 0xad40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x80,0xa1,0x20,0x28,0xc9 } },
+{  16, 0xad50, 0, {0x08,0x30,0x9a,0x00,0x09,0xb3,0x00,0x2c,0xc0,0x20,0x30,0x02,0x4c,0x90,0x83,0x20 } },
+{  16, 0xad60, 0, {0x02,0x08,0x0b,0x33,0x12,0xcd,0x80,0x93,0x20,0x24,0xd8,0x08,0x34,0x22,0x22,0x01 } },
+{  16, 0xad70, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xae,0x00,0xbb,0x10,0x22,0xc0 } },
+{  16, 0xad80, 0, {0x08,0xb0,0x02,0x26,0x01,0x3b,0x01,0x6e,0xc0,0x08,0xb0,0x02,0x4c,0x08,0x8b,0x00 } },
+{  16, 0xad90, 0, {0xa2,0x89,0x0b,0xb0,0x02,0xec,0x00,0xab,0x00,0x6a,0xc1,0x28,0xb0,0x02,0xb0,0x04 } },
+{  16, 0xada0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0x6e,0x00,0xe8,0xc1,0x3a,0xc0 } },
+{  16, 0xadb0, 0, {0x2c,0xb0,0x43,0x26,0x00,0xfb,0x06,0x3e,0xc1,0x0c,0xb0,0x0b,0x2c,0x02,0xcb,0x00 } },
+{  16, 0xadc0, 0, {0x34,0x22,0x9f,0xb0,0x43,0xec,0x00,0x9b,0x02,0x36,0xc1,0x8c,0xb0,0x03,0x10,0x04 } },
+{  16, 0xadd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbc,0x00,0xfc,0x80,0x3d,0xd0 } },
+{  16, 0xade0, 0, {0x2f,0xf0,0x03,0xfc,0x00,0xfb,0x00,0x3d,0xc0,0x07,0x30,0x03,0xbc,0x00,0xef,0x04 } },
+{  16, 0xadf0, 0, {0x3f,0xe0,0x5e,0xb0,0x01,0xfc,0x00,0xff,0x00,0x1b,0xc0,0x0f,0xf0,0x03,0xf8,0x00 } },
+{  16, 0xae00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xcb,0x01,0x3e,0xc9 } },
+{  16, 0xae10, 0, {0x0c,0xb0,0x17,0x20,0x84,0xeb,0x00,0xb2,0xc1,0x0d,0xb0,0x03,0x6c,0x00,0xc3,0x00 } },
+{  16, 0xae20, 0, {0x32,0x50,0x0f,0xb0,0x03,0x0c,0x40,0xc3,0x00,0x7e,0xc0,0x0c,0x30,0x03,0x10,0x04 } },
+{  16, 0xae30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0x8a,0x58,0x2e,0xe0 } },
+{  16, 0xae40, 0, {0x48,0xf0,0x02,0x2d,0x00,0xef,0x01,0x23,0xc0,0x08,0xf0,0x22,0x3c,0x04,0x8f,0x60 } },
+{  16, 0xae50, 0, {0x36,0x54,0x0b,0xf0,0x0a,0x3d,0x40,0x8f,0x00,0x2f,0xc0,0x08,0xf0,0x03,0x72,0x00 } },
+{  16, 0xae60, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x40,0x00,0x89,0x80,0x2c,0x10 } },
+{  16, 0xae70, 0, {0x08,0xb0,0x02,0x49,0x00,0xa3,0xa0,0x24,0xc0,0x09,0x30,0x02,0x4c,0x00,0x83,0xc9 } },
+{  16, 0xae80, 0, {0x20,0x90,0x42,0x30,0x12,0x4d,0x00,0x83,0x00,0x6a,0xc0,0x09,0x30,0x02,0x38,0x00 } },
+{  16, 0xae90, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x16,0x00,0x85,0x80,0x6d,0x62 } },
+{  16, 0xaea0, 0, {0x08,0x7e,0x02,0x56,0x40,0x27,0x80,0x25,0xe0,0x19,0x78,0x06,0x0e,0x00,0x83,0x80 } },
+{  16, 0xaeb0, 0, {0x61,0xa0,0x0b,0x78,0x02,0x4e,0x00,0x87,0x82,0x6d,0xe0,0x09,0x79,0x02,0x48,0x00 } },
+{  16, 0xaec0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x2c,0x02,0xc3,0x61,0x3c,0x88 } },
+{  16, 0xaed0, 0, {0x2c,0xba,0x12,0x49,0x10,0xe3,0x2c,0x36,0xc0,0x0d,0x30,0x53,0x4c,0x44,0xc3,0x00 } },
+{  16, 0xaee0, 0, {0x20,0x01,0x0f,0x31,0x03,0x4c,0x00,0xc3,0x01,0x3c,0xc0,0x2d,0xb1,0x03,0x12,0x02 } },
+{  16, 0xaef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x00,0xff,0x00,0x3f,0x00 } },
+{  16, 0xaf00, 0, {0x4f,0xf1,0x09,0xb0,0x00,0xff,0x00,0x3b,0xc0,0x0e,0xf4,0x01,0xfd,0x24,0xff,0x40 } },
+{  16, 0xaf10, 0, {0xbf,0xc0,0x07,0xf0,0x03,0xbc,0x00,0x6f,0x10,0x3f,0xc4,0x1e,0xf1,0x83,0xd0,0x06 } },
+{  16, 0xaf20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xc4,0x00,0xe8,0x04,0x32,0x00 } },
+{  16, 0xaf30, 0, {0x0c,0xb6,0x03,0xe8,0x02,0xcb,0x00,0x36,0xca,0x0f,0xb5,0x03,0xad,0x00,0xfb,0x20 } },
+{  16, 0xaf40, 0, {0x3e,0x40,0x0f,0xb3,0x03,0xec,0x80,0xfb,0xa8,0x32,0xc6,0x8c,0xb6,0x03,0x2a,0x00 } },
+{  16, 0xaf50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x02,0xe6,0x00,0x20,0x00 } },
+{  16, 0xaf60, 0, {0x08,0x73,0x02,0xdc,0x00,0x87,0x70,0x2d,0xd0,0x0b,0xf0,0x02,0x1c,0x84,0xb7,0x20 } },
+{  16, 0xaf70, 0, {0x2d,0xc0,0x0b,0x70,0x82,0xdd,0x24,0xb7,0x40,0x34,0xc9,0x28,0x72,0x82,0x92,0x04 } },
+{  16, 0xaf80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0xbe,0x02,0xac,0x80,0xa1,0x20 } },
+{  16, 0xaf90, 0, {0x08,0x79,0x00,0xce,0x04,0x87,0x80,0x65,0xe0,0x0b,0x7a,0x02,0x9e,0x00,0xb7,0x90 } },
+{  16, 0xafa0, 0, {0x6d,0xa0,0x0b,0x78,0x02,0xde,0x00,0xb7,0x80,0x21,0xe0,0x08,0x78,0x02,0x30,0x00 } },
+{  16, 0xafb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xed,0x82,0xab,0xe0,0x20,0xe4 } },
+{  16, 0xafc0, 0, {0x08,0x30,0x02,0xee,0x04,0x83,0x00,0x2c,0xc1,0x1b,0x30,0x02,0x0c,0x08,0xb3,0x00 } },
+{  16, 0xafd0, 0, {0x64,0xf6,0x0b,0xb0,0x02,0xcc,0x04,0xb3,0x00,0x26,0xc0,0x08,0x30,0x02,0x92,0x04 } },
+{  16, 0xafe0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xbb,0x80,0xee,0x49,0x31,0xa0 } },
+{  16, 0xaff0, 0, {0x2c,0xa0,0x03,0xfa,0x00,0xca,0x02,0x36,0x80,0x0f,0xa0,0x03,0xa8,0x00,0xfa,0x02 } },
+{  16, 0xb000, 0, {0x3f,0x90,0x0f,0xa0,0x63,0xe8,0x00,0xfa,0x00,0x32,0x80,0x0c,0xa0,0x23,0x3a,0x04 } },
+{  16, 0xb010, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x0a,0xe8,0x00,0x3e,0x08 } },
+{  16, 0xb020, 0, {0x0f,0x80,0x03,0xe3,0x50,0xf0,0x00,0x3e,0x00,0x0f,0x80,0x13,0xe0,0x00,0xf8,0x00 } },
+{  16, 0xb030, 0, {0x3e,0x00,0x0f,0x80,0x03,0xe0,0x01,0xf8,0x01,0x7e,0x00,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0xb040, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x40,0xc9,0xa1,0x32,0x40 } },
+{  16, 0xb050, 0, {0x20,0x11,0x01,0xa6,0x40,0xc9,0x84,0x36,0x40,0x0d,0x90,0x03,0x44,0x00,0x41,0x00 } },
+{  16, 0xb060, 0, {0x32,0x40,0x0f,0x90,0x0b,0x24,0x00,0xf9,0x00,0x3e,0x40,0x4c,0x10,0x03,0x02,0x04 } },
+{  16, 0xb070, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0x82,0xa2,0x40 } },
+{  16, 0xb080, 0, {0x08,0x9c,0x02,0x25,0x00,0x89,0xc8,0x22,0x40,0x08,0x90,0x42,0x24,0x00,0x89,0x20 } },
+{  16, 0xb090, 0, {0x22,0x60,0x0b,0x90,0x02,0x24,0x10,0xb9,0x00,0x2e,0x40,0x08,0x90,0x03,0x60,0x00 } },
+{  16, 0xb0a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x89,0x04,0x22,0xca } },
+{  16, 0xb0b0, 0, {0x0a,0x90,0x0a,0x25,0x02,0x89,0x20,0x20,0x40,0x28,0x10,0x02,0x64,0x01,0xa9,0x00 } },
+{  16, 0xb0c0, 0, {0x22,0x4b,0x0b,0x90,0x02,0x24,0x01,0xb9,0x00,0x2e,0x41,0x28,0x90,0x02,0x06,0x00 } },
+{  16, 0xb0d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x90,0x81,0xa0,0x20,0x48 } },
+{  16, 0xb0e0, 0, {0x0a,0x32,0x02,0x04,0x80,0x81,0x00,0x20,0x44,0x08,0x11,0x02,0x04,0xd0,0xa1,0x20 } },
+{  16, 0xb0f0, 0, {0x20,0x40,0x0b,0x11,0x02,0x06,0x00,0xb1,0x31,0x2c,0x48,0x08,0x14,0x02,0x42,0x01 } },
+{  16, 0xb100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x42,0xc8,0x54,0x32,0x14 } },
+{  16, 0xb110, 0, {0x0e,0x85,0x03,0x21,0x44,0xc8,0x28,0xb2,0x1a,0x4c,0x86,0x93,0x61,0x14,0xe8,0x50 } },
+{  16, 0xb120, 0, {0x22,0x14,0x0f,0x86,0x83,0x21,0x40,0xf0,0x40,0x1e,0x14,0x0c,0x00,0x03,0x2e,0x03 } },
+{  16, 0xb130, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0x74,0x44,0xf5,0x10,0x3f,0x44 } },
+{  16, 0xb140, 0, {0x0d,0x91,0x03,0x74,0x40,0xf9,0x00,0x3e,0x48,0x0b,0x92,0x03,0xe4,0xc2,0xd9,0x10 } },
+{  16, 0xb150, 0, {0xbf,0x40,0x0f,0x92,0x03,0xe5,0x04,0xf9,0x30,0x3e,0x44,0x0f,0x94,0x43,0xe6,0x06 } },
+{  16, 0xb160, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x22,0xcd,0xa1,0x33,0x61 } },
+{  16, 0xb170, 0, {0x0c,0xd8,0xd3,0x34,0x10,0xcd,0xa8,0x3e,0x60,0x8e,0x9c,0x93,0xa7,0x08,0xcd,0x80 } },
+{  16, 0xb180, 0, {0x33,0x40,0x0e,0x9a,0xd3,0x36,0xa0,0xc9,0x80,0x32,0x60,0x0c,0x99,0x03,0x06,0x00 } },
+{  16, 0xb190, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe3,0x88,0x8a,0xa0,0x20,0x28 } },
+{  16, 0xb1a0, 0, {0x08,0x80,0x22,0x20,0x12,0x88,0x40,0x2c,0x28,0x08,0x8a,0x02,0x22,0x00,0x88,0x00 } },
+{  16, 0xb1b0, 0, {0x22,0x00,0x0b,0x8c,0x03,0x21,0x00,0x88,0xd0,0xa2,0x3e,0x28,0x8d,0x02,0x0e,0x04 } },
+{  16, 0xb1c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xce,0x20,0xa1,0x48,0x20,0x52 } },
+{  16, 0xb1d0, 0, {0x29,0x10,0x02,0x24,0x03,0x81,0x00,0x2c,0x52,0x0a,0x10,0x12,0x85,0x10,0x91,0x40 } },
+{  16, 0xb1e0, 0, {0xa4,0x40,0x0a,0x12,0x82,0x44,0x00,0x91,0x28,0x24,0x40,0x28,0x12,0x02,0x02,0x01 } },
+{  16, 0xb1f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x00,0xa9,0x14,0x22,0x40 } },
+{  16, 0xb200, 0, {0x09,0x90,0x02,0xa4,0x01,0x89,0x04,0x2c,0x40,0x08,0x90,0x02,0x24,0x00,0x99,0x00 } },
+{  16, 0xb210, 0, {0x22,0x44,0x4b,0x10,0x42,0x24,0x14,0x99,0x00,0x26,0x40,0x08,0x10,0x02,0x06,0x04 } },
+{  16, 0xb220, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x40,0xe9,0x40,0xb2,0x78 } },
+{  16, 0xb230, 0, {0x0d,0x90,0x0b,0x24,0x22,0xc9,0x03,0x3e,0x41,0x0e,0x90,0x03,0xa4,0x02,0xd9,0x00 } },
+{  16, 0xb240, 0, {0x16,0x58,0x06,0x90,0x0b,0x64,0x02,0xd9,0x00,0x36,0x40,0x0c,0x90,0x0b,0x28,0x04 } },
+{  16, 0xb250, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x84,0x00,0xd9,0x80,0x3e,0x4a } },
+{  16, 0xb260, 0, {0x0e,0x90,0x03,0x64,0x20,0xf9,0x08,0x3e,0x41,0x0f,0x90,0x03,0xe4,0x00,0xe1,0x08 } },
+{  16, 0xb270, 0, {0x3e,0x40,0x0f,0x90,0x03,0xc4,0x00,0xe1,0x00,0x38,0x40,0x0f,0x90,0x03,0xca,0x00 } },
+{  16, 0xb280, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x09,0xf0,0x40,0xb0,0x10 } },
+{  16, 0xb290, 0, {0x4c,0x00,0x0b,0x20,0x00,0xf8,0x00,0x3a,0x00,0x1c,0x00,0x03,0xe0,0x00,0xc8,0x00 } },
+{  16, 0xb2a0, 0, {0x36,0x00,0x0c,0x80,0x03,0x20,0x00,0xc8,0x00,0x32,0x00,0x0f,0x80,0x03,0x0a,0x04 } },
+{  16, 0xb2b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x3e,0x88,0x23,0xa2 } },
+{  16, 0xb2c0, 0, {0x48,0xe0,0x00,0x19,0x80,0xbe,0x88,0x2e,0x80,0x0d,0xa0,0x42,0xe8,0x00,0x8e,0x00 } },
+{  16, 0xb2d0, 0, {0x23,0x90,0x08,0xa0,0x0a,0x3a,0x00,0xda,0x00,0x36,0x80,0x0b,0xa0,0x0a,0x0a,0x00 } },
+{  16, 0xb2e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x80,0x20,0xe0 } },
+{  16, 0xb2f0, 0, {0x28,0x30,0xc2,0x0f,0x10,0xb3,0x40,0x28,0xc0,0x0b,0x30,0x02,0xec,0x11,0x83,0x40 } },
+{  16, 0xb300, 0, {0x28,0xd2,0x0a,0x30,0x02,0x0c,0xc0,0x83,0x00,0x20,0xc0,0x0b,0x30,0x02,0x0a,0x00 } },
+{  16, 0xb310, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x00,0xb6,0x00,0x21,0xc0 } },
+{  16, 0xb320, 0, {0x08,0x20,0xc2,0x1c,0x10,0xb5,0x00,0x2d,0xc8,0x0a,0x72,0x02,0xdc,0x40,0x85,0x08 } },
+{  16, 0xb330, 0, {0x29,0xa2,0x1a,0x72,0x22,0x0c,0x00,0x93,0x30,0x05,0xc4,0x0b,0x32,0x22,0x28,0x00 } },
+{  16, 0xb340, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x16,0x00,0xb2,0x80,0x31,0x20 } },
+{  16, 0xb350, 0, {0x0c,0x58,0x03,0x1e,0x00,0xf7,0x80,0x39,0xf8,0x0b,0x7c,0x22,0xce,0x40,0xcf,0x80 } },
+{  16, 0xb360, 0, {0x9b,0x60,0x2e,0x3b,0x03,0x1a,0x00,0xc7,0xa8,0x11,0xe0,0x0f,0x78,0x03,0x2a,0x02 } },
+{  16, 0xb370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xa4,0x00,0xfa,0x00,0x3e,0xc0 } },
+{  16, 0xb380, 0, {0x0f,0x90,0x23,0xe8,0x00,0xfb,0x00,0x3e,0xd0,0x2d,0xb6,0x03,0xed,0x02,0xf9,0x00 } },
+{  16, 0xb390, 0, {0x32,0x40,0x0d,0xb0,0x07,0xec,0x00,0xfb,0x60,0x3e,0xc8,0x0f,0xb5,0x03,0xc2,0x06 } },
+{  16, 0xb3a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xff,0x80,0x33,0xa0 } },
+{  16, 0xb3b0, 0, {0x0c,0xf8,0x0b,0x32,0x40,0xce,0x81,0x37,0xf0,0x0c,0xbc,0x03,0xfe,0x00,0xff,0x84 } },
+{  16, 0xb3c0, 0, {0x33,0xe0,0x2c,0xf8,0x83,0xe6,0x02,0xcf,0x85,0x33,0xf0,0x0c,0xfc,0x03,0x00,0x14 } },
+{  16, 0xb3d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xbe,0x00,0x35,0xc6 } },
+{  16, 0xb3e0, 0, {0x28,0x30,0x02,0x30,0x40,0x87,0x00,0x23,0xc0,0x08,0x7a,0x02,0xdc,0x00,0xbe,0x00 } },
+{  16, 0xb3f0, 0, {0x23,0xc0,0x08,0x70,0x12,0xfe,0x00,0x87,0x00,0x21,0xc0,0x08,0xf0,0x02,0x2a,0x04 } },
+{  16, 0xb400, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95,0x20,0xb6,0x00,0x20,0x80 } },
+{  16, 0xb410, 0, {0x08,0x31,0x02,0x5c,0x01,0x87,0x00,0x25,0xc0,0x08,0x72,0x02,0xdc,0x00,0xb6,0x00 } },
+{  16, 0xb420, 0, {0x21,0xd0,0x09,0x70,0x02,0xd4,0x08,0x93,0x00,0x20,0xc0,0x08,0x70,0x02,0x00,0x00 } },
+{  16, 0xb430, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xc4,0x00,0xb0,0xe0,0x24,0x60 } },
+{  16, 0xb440, 0, {0x08,0x20,0x06,0x48,0x01,0x80,0x00,0x20,0xc0,0x08,0x30,0x02,0xcc,0x04,0xb3,0x00 } },
+{  16, 0xb450, 0, {0x20,0x84,0x0b,0x30,0x02,0xe8,0x00,0x9b,0x00,0x20,0xc0,0x08,0x30,0x02,0x08,0x04 } },
+{  16, 0xb460, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xb9,0xe0,0x32,0x80 } },
+{  16, 0xb470, 0, {0x6c,0xb0,0x23,0x6f,0x00,0xc3,0x00,0x37,0xc1,0x3c,0xf0,0x03,0xfc,0x00,0xfa,0x00 } },
+{  16, 0xb480, 0, {0xb0,0xc0,0x09,0xf0,0x03,0xec,0x10,0xdf,0x00,0x73,0xc0,0x0c,0xf0,0x0b,0x2a,0x00 } },
+{  16, 0xb490, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x10,0xf8,0x00,0x3e,0x42 } },
+{  16, 0xb4a0, 0, {0x0f,0x24,0x03,0xa8,0x60,0xf8,0x00,0x3c,0xc1,0x0f,0xb0,0x03,0xec,0x00,0xf9,0x40 } },
+{  16, 0xb4b0, 0, {0x3e,0x80,0x04,0xb0,0x23,0xe1,0x00,0xeb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xe0,0x00 } },
+{  16, 0xb4c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf4,0x00,0xee,0x00,0x3d,0x30 } },
+{  16, 0xb4d0, 0, {0x0c,0xc0,0x03,0x14,0x00,0xcc,0xa0,0xb3,0xc0,0x4c,0x70,0x03,0x5c,0x10,0xdf,0x00 } },
+{  16, 0xb4e0, 0, {0x3f,0x00,0x0c,0xf0,0x03,0xf8,0x00,0xcf,0x00,0x23,0xc0,0x0c,0xf0,0x03,0x00,0x40 } },
+{  16, 0xb4f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x64,0x00,0xba,0x81,0x2e,0x58 } },
+{  16, 0xb500, 0, {0x08,0x88,0x02,0x27,0x80,0x89,0x20,0x22,0xc0,0x28,0xb0,0x02,0x2c,0x00,0x88,0x83 } },
+{  16, 0xb510, 0, {0x2e,0x20,0x05,0xb0,0x62,0xe3,0x00,0x8b,0x00,0x2a,0xc0,0x08,0xb0,0x03,0x60,0x40 } },
+{  16, 0xb520, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x26,0x00,0xb9,0x81,0x2e,0x40 } },
+{  16, 0xb530, 0, {0x08,0x8c,0x06,0x26,0x00,0x88,0x00,0x22,0xc0,0x08,0xb0,0x16,0x6c,0x00,0x98,0x88 } },
+{  16, 0xb540, 0, {0x2e,0x20,0x08,0xb0,0x04,0xe3,0x01,0x0b,0x00,0x28,0xc0,0x08,0x30,0x02,0x20,0x00 } },
+{  16, 0xb550, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0xb0,0x00,0x2c,0xc0 } },
+{  16, 0xb560, 0, {0x28,0x00,0x0e,0x00,0x10,0x80,0x00,0x20,0xc0,0x08,0x32,0x02,0x0c,0x00,0x80,0x04 } },
+{  16, 0xb570, 0, {0x2e,0x20,0x09,0x30,0x02,0xc4,0x12,0x83,0x00,0x28,0xc0,0x08,0x30,0x02,0x42,0x01 } },
+{  16, 0xb580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xfa,0x00,0x3e,0x00 } },
+{  16, 0xb590, 0, {0x2c,0x91,0x03,0x20,0x00,0x8a,0x00,0x33,0xc0,0x0c,0xf0,0x03,0x7c,0x00,0xd8,0x00 } },
+{  16, 0xb5a0, 0, {0x2e,0x40,0x0c,0xf0,0x03,0xe0,0x80,0xcf,0x00,0x3b,0xc0,0x0c,0xf0,0x03,0x00,0x03 } },
+{  16, 0xb5b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xfc,0x01,0x3f,0x40 } },
+{  16, 0xb5c0, 0, {0x0f,0xc0,0x13,0xf0,0x00,0xf4,0x00,0x3f,0xc1,0x0f,0xf4,0x23,0xfc,0x08,0xfc,0x00 } },
+{  16, 0xb5d0, 0, {0x3f,0x00,0x0f,0xf0,0x03,0xf0,0x40,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8,0x06 } },
+{  16, 0xb5e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x20,0xcd,0x10,0x39,0xc8 } },
+{  16, 0xb5f0, 0, {0x0d,0xc1,0x03,0x3c,0x80,0xef,0x90,0x23,0xd8,0x0f,0xf8,0x00,0xfe,0x00,0xcf,0x80 } },
+{  16, 0xb600, 0, {0x1f,0xd0,0x0f,0xf9,0x03,0xff,0x00,0xe7,0xc0,0x33,0xc4,0x0f,0xf0,0x03,0xb0,0x00 } },
+{  16, 0xb610, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x10,0xfe,0x02,0x89,0x40,0x23,0xf0 } },
+{  16, 0xb620, 0, {0x08,0x85,0x10,0x3c,0x00,0x8b,0x00,0xa3,0xdc,0x4b,0xb2,0x82,0xec,0x20,0x8b,0x00 } },
+{  16, 0xb630, 0, {0x26,0xc0,0x4b,0xb0,0x02,0xec,0x10,0xb9,0x04,0x2a,0xc9,0x0b,0xb5,0x80,0xf0,0x04 } },
+{  16, 0xb640, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0xcc,0x00,0x81,0x64,0x28,0xc4 } },
+{  16, 0xb650, 0, {0x09,0xb2,0x0a,0x0c,0xf0,0xa3,0x20,0x20,0xc8,0x0b,0x32,0x02,0xec,0x02,0x83,0x08 } },
+{  16, 0xb660, 0, {0x2c,0xc8,0x09,0x32,0x02,0xcc,0x80,0xab,0xa0,0x20,0xc8,0x0b,0x32,0x00,0xb2,0x01 } },
+{  16, 0xb670, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x10,0x89,0x00,0x22,0xc0 } },
+{  16, 0xb680, 0, {0x08,0xb2,0x12,0x2c,0x02,0x0b,0x00,0x22,0xc0,0x0b,0xb8,0x02,0xec,0x00,0x8b,0x00 } },
+{  16, 0xb690, 0, {0x26,0xc0,0x4b,0xb0,0x46,0xec,0x00,0xb9,0x00,0x0a,0xc0,0x0b,0xb0,0x02,0xf0,0x04 } },
+{  16, 0xb6a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x15,0xec,0x10,0xc9,0xe0,0x3a,0xc0 } },
+{  16, 0xb6b0, 0, {0x0d,0x28,0x03,0x2c,0x00,0xeb,0x10,0x32,0xc0,0x0f,0x82,0x03,0xc4,0x00,0xcb,0x00 } },
+{  16, 0xb6c0, 0, {0x3e,0xc1,0x0f,0xb0,0x06,0xec,0x08,0xe9,0x00,0xb2,0xc0,0x0f,0xb0,0x13,0x90,0x04 } },
+{  16, 0xb6d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x9c,0x00,0xf5,0xa0,0x3f,0xc0 } },
+{  16, 0xb6e0, 0, {0x0f,0xe8,0x03,0xfc,0x08,0xff,0x00,0x3f,0xc0,0x8f,0xc0,0x03,0xfc,0x00,0xff,0x00 } },
+{  16, 0xb6f0, 0, {0x37,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x04,0x3e,0xc0,0x0f,0xf0,0x03,0xf8,0x00 } },
+{  16, 0xb700, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x10,0xac,0x00,0xf9,0x40,0x34,0xc0 } },
+{  16, 0xb710, 0, {0x0d,0xb4,0x03,0x2c,0x00,0xdb,0x40,0x3e,0xc0,0x2c,0x80,0x03,0x64,0x08,0xfb,0x10 } },
+{  16, 0xb720, 0, {0x3e,0xc6,0x8f,0xb0,0x03,0xec,0x00,0xf9,0x80,0x32,0xc0,0x0c,0xb0,0x0b,0x14,0x04 } },
+{  16, 0xb730, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3e,0x20,0xe9,0xc8,0x37,0xd4 } },
+{  16, 0xb740, 0, {0x48,0xaa,0x22,0x1c,0x00,0x8b,0x00,0x6f,0xe0,0x08,0x85,0x82,0xed,0x40,0xbb,0x84 } },
+{  16, 0xb750, 0, {0x2f,0xc0,0x4b,0xb8,0x03,0xad,0x40,0xb3,0x00,0x23,0xd4,0x08,0xf7,0x02,0x32,0x00 } },
+{  16, 0xb760, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x4c,0x00,0xb1,0x64,0xa4,0xc0 } },
+{  16, 0xb770, 0, {0x09,0x20,0x0a,0x0c,0x04,0xb8,0x00,0x6c,0xc0,0x08,0x38,0x02,0xc8,0x40,0xb3,0x80 } },
+{  16, 0xb780, 0, {0x2c,0xd1,0x0b,0x30,0x02,0xcc,0x04,0xb3,0x00,0x28,0xc0,0x08,0x30,0x02,0x3a,0x00 } },
+{  16, 0xb790, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x01,0x1e,0x00,0xa5,0x80,0x25,0xe0 } },
+{  16, 0xb7a0, 0, {0x88,0x3a,0x12,0x1e,0x00,0xa6,0x90,0x2d,0xe2,0x08,0x79,0x02,0xda,0x00,0xb7,0x82 } },
+{  16, 0xb7b0, 0, {0x2d,0xe0,0x03,0x78,0x82,0x9e,0x00,0xbc,0xc1,0x29,0xe0,0x08,0x78,0x02,0x2c,0x10 } },
+{  16, 0xb7c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x08,0x0c,0x00,0xf3,0x00,0x34,0xc0 } },
+{  16, 0xb7d0, 0, {0x0d,0x3e,0x03,0x0c,0x00,0xf0,0x40,0x2e,0xc0,0x0c,0x30,0x43,0xc8,0x00,0xf3,0x00 } },
+{  16, 0xb7e0, 0, {0x3c,0xc0,0x07,0x30,0x03,0xcc,0x80,0xf2,0x00,0x38,0xc0,0x0c,0x30,0x03,0x12,0x02 } },
+{  16, 0xb7f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x19,0xbd,0x20,0xf7,0x00,0x3f,0xc2 } },
+{  16, 0xb800, 0, {0x0f,0xf1,0x0b,0xdc,0x20,0xde,0x04,0x3f,0xd2,0x07,0xf0,0x13,0xf8,0x40,0xff,0x00 } },
+{  16, 0xb810, 0, {0x3f,0xc0,0x07,0xf0,0x03,0xfc,0x00,0xfd,0x00,0x37,0xc0,0x0f,0x70,0x03,0xd0,0x06 } },
+{  16, 0xb820, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x05,0xcf,0x00,0xdc,0x00,0x3e,0xca } },
+{  16, 0xb830, 0, {0x0f,0xa0,0x00,0xac,0x92,0xc9,0x00,0x32,0xc0,0x0f,0xb0,0x11,0xa4,0x08,0xfb,0x00 } },
+{  16, 0xb840, 0, {0x2e,0xc0,0x4f,0xb0,0x23,0xec,0x00,0xf9,0x00,0x3e,0xc4,0x0f,0xb0,0x03,0xea,0x00 } },
+{  16, 0xb850, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x91,0x9c,0x00,0x84,0x00,0x01,0xc0 } },
+{  16, 0xb860, 0, {0x4b,0x70,0x22,0x1c,0xc0,0x87,0x00,0x21,0xc0,0x4b,0x70,0x02,0x1c,0x00,0xb7,0x01 } },
+{  16, 0xb870, 0, {0x25,0xd8,0x0b,0x70,0x22,0xdc,0x00,0xb6,0x00,0x2d,0xc0,0x0b,0x72,0x22,0xf2,0x04 } },
+{  16, 0xb880, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x80,0x97,0x80,0xa9,0xe0 } },
+{  16, 0xb890, 0, {0x0b,0xf8,0x02,0xce,0x08,0x85,0x80,0x29,0xe8,0x0b,0xfc,0x02,0x17,0x00,0xb7,0x80 } },
+{  16, 0xb8a0, 0, {0x2d,0xe0,0x8b,0x78,0x02,0xde,0x00,0xb4,0xc0,0x2d,0xe8,0x0b,0x79,0x02,0xe0,0x00 } },
+{  16, 0xb8b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0x83,0x08,0xa0,0xc0 } },
+{  16, 0xb8c0, 0, {0x8b,0x3c,0x02,0x4c,0x00,0x83,0x00,0xa0,0xc0,0x1b,0x3c,0x0a,0x0f,0x29,0xb3,0x00 } },
+{  16, 0xb8d0, 0, {0x24,0xc0,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x80,0x2c,0xc0,0x0b,0x30,0x02,0xd2,0x04 } },
+{  16, 0xb8e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xde,0x00,0x3a,0x80 } },
+{  16, 0xb8f0, 0, {0x0f,0xea,0x02,0xe8,0x00,0xce,0x00,0x3a,0x80,0x0f,0xe0,0x03,0x38,0x00,0xfa,0x00 } },
+{  16, 0xb900, 0, {0x3e,0x80,0x0f,0xa0,0x03,0xe8,0x00,0xfe,0x00,0x3e,0x80,0x0b,0xa0,0x03,0xfa,0x04 } },
+{  16, 0xb910, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x00,0xf8,0x04,0xba,0x01 } },
+{  16, 0xb920, 0, {0x0f,0x82,0x0b,0x80,0x04,0xf8,0x80,0x3e,0x00,0x0f,0x86,0x03,0x60,0x00,0xf8,0x00 } },
+{  16, 0xb930, 0, {0x36,0x00,0x0f,0x80,0x23,0xe1,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2,0x00 } },
+{  16, 0xb940, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x01,0xf9,0x00,0x32,0x40 } },
+{  16, 0xb950, 0, {0x0f,0x90,0x03,0xe4,0x00,0x49,0x00,0x32,0x40,0x0b,0x90,0x03,0x24,0x00,0x49,0x00 } },
+{  16, 0xb960, 0, {0x3c,0x40,0x0d,0x90,0x03,0xe4,0x08,0xc9,0x00,0x3e,0x60,0x0c,0x90,0x03,0x02,0x04 } },
+{  16, 0xb970, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x40,0xa2,0x64 } },
+{  16, 0xb980, 0, {0x0b,0x18,0x02,0x25,0x00,0xd1,0x50,0x36,0x50,0x4e,0x90,0x0a,0x24,0x02,0x89,0x40 } },
+{  16, 0xb990, 0, {0x3a,0x51,0x08,0x94,0x02,0xe5,0x22,0x89,0x44,0x2e,0x60,0x28,0x90,0x0a,0x20,0x00 } },
+{  16, 0xb9a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xb1,0x08,0x22,0x40 } },
+{  16, 0xb9b0, 0, {0x4b,0x92,0x82,0xa5,0x00,0xa9,0x08,0x22,0x50,0x0a,0x10,0x02,0x0c,0x00,0xa9,0x40 } },
+{  16, 0xb9c0, 0, {0x6e,0x50,0x0b,0x94,0x02,0xc4,0x04,0x89,0x44,0x6c,0x48,0x88,0x10,0x02,0x46,0x00 } },
+{  16, 0xb9d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x00,0xb1,0x40,0xe0,0x40 } },
+{  16, 0xb9e0, 0, {0x1b,0x14,0x0a,0x04,0x00,0xb9,0x00,0x24,0x40,0x1a,0x10,0x22,0x04,0x00,0xa1,0x00 } },
+{  16, 0xb9f0, 0, {0x28,0x40,0x0a,0x10,0x12,0xc4,0x00,0x81,0x02,0x6c,0x40,0x08,0x12,0x02,0x42,0x01 } },
+{  16, 0xba00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x08,0xb0,0x00,0x32,0x00 } },
+{  16, 0xba10, 0, {0x4f,0x80,0x02,0xa1,0x50,0xe0,0x50,0x32,0x14,0x0e,0xa5,0x23,0x21,0x40,0xe8,0x50 } },
+{  16, 0xba20, 0, {0x3e,0x14,0x0f,0x85,0x03,0xe1,0x40,0xc8,0x50,0x1e,0x14,0x0c,0x85,0x43,0x6e,0x03 } },
+{  16, 0xba30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd8,0x19,0xe5,0x00,0xfd,0x40,0x3e,0x50 } },
+{  16, 0xba40, 0, {0x0f,0x74,0x03,0xa5,0x00,0x5d,0x00,0x3e,0x50,0x0a,0x50,0x13,0xf4,0x00,0xd9,0x00 } },
+{  16, 0xba50, 0, {0x3a,0x50,0x0d,0x90,0x13,0xe4,0x00,0xff,0x00,0x3e,0x50,0x0f,0x91,0x03,0xa6,0x06 } },
+{  16, 0xba60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x90,0xbd,0xe8,0x23,0x6b } },
+{  16, 0xba70, 0, {0x0b,0xda,0x0b,0x36,0x80,0xc9,0x00,0x32,0x68,0x46,0x90,0x43,0xe4,0x00,0x49,0x00 } },
+{  16, 0xba80, 0, {0x32,0x68,0x0c,0x90,0x03,0x24,0x40,0xf9,0x00,0x32,0x60,0x0c,0x9c,0x03,0xc6,0x01 } },
+{  16, 0xba90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x10,0xe1,0x00,0xb8,0xe0,0xa2,0x11 } },
+{  16, 0xbaa0, 0, {0x0b,0x8e,0x0a,0x23,0x22,0x88,0x80,0x2a,0x31,0x28,0x88,0x02,0x62,0x00,0x88,0x80 } },
+{  16, 0xbab0, 0, {0xa2,0x30,0x28,0x88,0x8a,0x22,0x00,0xb8,0xa8,0xa2,0x39,0x08,0xca,0x02,0xce,0x04 } },
+{  16, 0xbac0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc5,0x08,0x21,0x00,0x00,0x40 } },
+{  16, 0xbad0, 0, {0x03,0x14,0x82,0x85,0x80,0xad,0x08,0x21,0x52,0x98,0x50,0x82,0x34,0x23,0x85,0x08 } },
+{  16, 0xbae0, 0, {0x21,0x52,0x08,0x50,0x06,0x54,0x00,0xb5,0x20,0x21,0x5a,0x09,0x54,0x02,0xd2,0x01 } },
+{  16, 0xbaf0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x00,0xb9,0x61,0x22,0x40 } },
+{  16, 0xbb00, 0, {0x0b,0x90,0x06,0x04,0x00,0xad,0x00,0x69,0x40,0x08,0xd0,0x02,0x74,0x00,0x85,0x00 } },
+{  16, 0xbb10, 0, {0x01,0x40,0x00,0x70,0x06,0x74,0x04,0xb5,0x00,0x23,0x40,0x09,0xd0,0x02,0xc6,0x04 } },
+{  16, 0xbb20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x14,0xa4,0x00,0xe9,0x00,0x32,0x40 } },
+{  16, 0xbb30, 0, {0x4f,0x95,0x0b,0xa4,0x00,0xe9,0x00,0x32,0x40,0x8c,0x90,0x03,0x24,0x00,0xc9,0x00 } },
+{  16, 0xbb40, 0, {0x32,0x40,0x0c,0x90,0x03,0x64,0x08,0xf9,0x00,0x32,0x40,0x3d,0x90,0x03,0xe8,0x04 } },
+{  16, 0xbb50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x01,0xa4,0x08,0xf9,0x00,0x3e,0x40 } },
+{  16, 0xbb60, 0, {0x4f,0x90,0x8b,0xe4,0x04,0xd9,0x01,0x3e,0x40,0x0d,0x90,0x03,0x64,0x00,0xd9,0x01 } },
+{  16, 0xbb70, 0, {0x3e,0x40,0x0f,0x90,0x03,0xa4,0x00,0xf9,0x00,0x3c,0x40,0x0e,0x90,0x03,0xda,0x00 } },
+{  16, 0xbb80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x40,0x36,0x20 } },
+{  16, 0xbb90, 0, {0x17,0x84,0x03,0x20,0x21,0xc8,0x00,0x7e,0x02,0x2c,0x80,0x43,0x20,0x00,0xe8,0x02 } },
+{  16, 0xbba0, 0, {0x3e,0x01,0x0f,0x80,0x03,0xe0,0x00,0xc8,0x40,0x1e,0x00,0x0f,0x80,0x03,0xca,0x04 } },
+{  16, 0xbbb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x2a,0x88,0xb6,0x02,0x23,0xa0 } },
+{  16, 0xbbc0, 0, {0x0b,0xec,0x42,0x2b,0x00,0xd2,0x80,0x6e,0xb1,0x08,0xa0,0x22,0x08,0x00,0xea,0x04 } },
+{  16, 0xbbd0, 0, {0x3a,0x80,0x9f,0xa0,0x03,0xa8,0x00,0x8a,0x04,0x2e,0x80,0x0b,0xa8,0x02,0xca,0x00 } },
+{  16, 0xbbe0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb2,0x00,0xa4,0xe1 } },
+{  16, 0xbbf0, 0, {0x8b,0xb4,0x32,0x47,0x45,0x83,0x90,0x2c,0xf4,0x4b,0x38,0x12,0x0e,0x44,0xa3,0x01 } },
+{  16, 0xbc00, 0, {0x2c,0xc0,0x4b,0x30,0x02,0xce,0x00,0x93,0x00,0x6c,0xc0,0x0b,0x38,0x02,0xca,0x00 } },
+{  16, 0xbc10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x00,0xb7,0x44,0x21,0xc2 } },
+{  16, 0xbc20, 0, {0x0b,0x54,0x02,0x54,0x05,0x87,0x00,0x2c,0x40,0x9b,0x6c,0x02,0x18,0x10,0xa7,0x04 } },
+{  16, 0xbc30, 0, {0x29,0xc0,0x0a,0x70,0x02,0x9b,0x00,0x97,0x04,0x0d,0x80,0x0b,0x60,0x82,0xe8,0x00 } },
+{  16, 0xbc40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf3,0x80,0x35,0xe0 } },
+{  16, 0xbc50, 0, {0x0b,0x38,0x02,0x52,0x10,0x84,0x80,0x2d,0xa0,0x0f,0xf8,0x0b,0x1e,0x00,0xe6,0x80 } },
+{  16, 0xbc60, 0, {0x1d,0xa0,0x0b,0x68,0x03,0xfe,0x02,0xd6,0x80,0x3d,0xe0,0x0f,0x78,0x03,0xea,0x02 } },
+{  16, 0xbc70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x1d,0xac,0x00,0xfb,0x00,0x3e,0xc1 } },
+{  16, 0xbc80, 0, {0x8b,0x90,0x0b,0x80,0x0a,0xb8,0x01,0x2e,0x00,0x0c,0xb0,0x03,0xe8,0x00,0xfa,0x00 } },
+{  16, 0xbc90, 0, {0x3e,0xc0,0x0f,0xa0,0x43,0xec,0x00,0xeb,0x00,0x3e,0x80,0x0f,0xa6,0x23,0xc2,0x02 } },
+{  16, 0xbca0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xfe,0x80,0x33,0x20 } },
+{  16, 0xbcb0, 0, {0x4e,0xc9,0x12,0xf6,0x50,0xef,0x90,0x3f,0xe0,0x0c,0x19,0x00,0xb6,0x42,0xcf,0x21 } },
+{  16, 0xbcc0, 0, {0x3f,0xe0,0x0e,0xf9,0x02,0xe6,0xc0,0xff,0x80,0x3f,0xe0,0x4c,0xdc,0x03,0x40,0x00 } },
+{  16, 0xbcd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x11,0x94,0x00,0xb7,0x00,0x81,0x40 } },
+{  16, 0xbce0, 0, {0x08,0x03,0x02,0x14,0xc4,0x87,0x01,0x2d,0xc8,0x08,0x6a,0x12,0x38,0x40,0x87,0x02 } },
+{  16, 0xbcf0, 0, {0x2d,0xc0,0x08,0x71,0x12,0xd2,0x80,0xb7,0x00,0x2d,0x80,0x08,0x60,0x02,0x2a,0x04 } },
+{  16, 0xbd00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x10,0x21,0x80 } },
+{  16, 0xbd10, 0, {0x08,0xf4,0x12,0x94,0x04,0xa6,0x00,0x2c,0xc0,0x18,0xd2,0x02,0x14,0x48,0x86,0x10 } },
+{  16, 0xbd20, 0, {0x2d,0x80,0x0a,0x61,0x32,0xd4,0x00,0xb6,0x18,0x2d,0xc4,0x08,0x58,0x02,0x00,0x10 } },
+{  16, 0xbd30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xc4,0x00,0xb3,0x00,0x20,0xc0 } },
+{  16, 0xbd40, 0, {0x40,0xb0,0x22,0x04,0x00,0x82,0x81,0x0c,0xc0,0x08,0x30,0x0a,0x0a,0x00,0x8a,0x00 } },
+{  16, 0xbd50, 0, {0x2e,0xc0,0x08,0xa0,0x02,0xc4,0x00,0xbb,0x00,0x2e,0x80,0x08,0x20,0x02,0x08,0x04 } },
+{  16, 0xbd60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xfb,0x00,0xa0,0xc0 } },
+{  16, 0xbd70, 0, {0x24,0x94,0x23,0xac,0x10,0xeb,0xa0,0x0e,0xc0,0x0c,0xb0,0x02,0x2e,0x20,0xc9,0x00 } },
+{  16, 0xbd80, 0, {0x2e,0x40,0x0e,0x90,0x03,0xec,0x00,0xf9,0x80,0x3e,0x40,0x6c,0xa0,0x0b,0x2a,0x04 } },
+{  16, 0xbd90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xcc,0x00,0xfb,0x00,0x3e,0xc0 } },
+{  16, 0xbda0, 0, {0x89,0x90,0x03,0x2c,0x00,0xfb,0x02,0x3e,0x40,0x4f,0xa0,0x03,0x6d,0x01,0xfb,0x41 } },
+{  16, 0xbdb0, 0, {0x3e,0xc0,0x8f,0xb4,0x03,0xe8,0x00,0xfb,0x20,0x3e,0x50,0x0f,0xa4,0x03,0xe0,0x00 } },
+{  16, 0xbdc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xc3,0x20,0xb2,0xc0 } },
+{  16, 0xbdd0, 0, {0x0d,0xd0,0x03,0x38,0x00,0xcd,0x00,0x3f,0x80,0x0d,0xf0,0x03,0xfc,0x00,0xfd,0x02 } },
+{  16, 0xbde0, 0, {0x36,0x00,0x0c,0xd0,0x03,0x3f,0x08,0xfc,0x04,0x12,0xc0,0x0c,0xa0,0x03,0xc0,0x44 } },
+{  16, 0xbdf0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x6c,0x02,0x8b,0xc8,0x22,0xc0 } },
+{  16, 0xbe00, 0, {0x08,0x98,0x0a,0x2a,0x40,0x89,0x20,0x2e,0x01,0x8e,0xb0,0x12,0xec,0x80,0xbb,0xf0 } },
+{  16, 0xbe10, 0, {0x22,0xe5,0x08,0xbd,0x02,0x2e,0x00,0xbb,0x90,0x22,0xed,0x08,0xa2,0x02,0xe0,0x00 } },
+{  16, 0xbe20, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x01,0x22,0x00 } },
+{  16, 0xbe30, 0, {0x49,0xa8,0x1e,0x04,0x00,0x8b,0x01,0x2e,0xc0,0x49,0x90,0x02,0xe4,0x00,0xb9,0x00 } },
+{  16, 0xbe40, 0, {0x22,0x40,0x0a,0x90,0x02,0x2c,0x00,0xb9,0x00,0x2a,0x40,0x08,0x80,0x02,0xe0,0x00 } },
+{  16, 0xbe50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0x81,0x00,0x20,0x40 } },
+{  16, 0xbe60, 0, {0x08,0x20,0x02,0x04,0x00,0x83,0x00,0x2c,0xc0,0x0a,0x20,0x42,0xcc,0x00,0xb3,0x00 } },
+{  16, 0xbe70, 0, {0x20,0xc0,0x02,0x30,0x02,0x08,0x84,0xb3,0x04,0x08,0x40,0x08,0x20,0x02,0xc2,0x11 } },
+{  16, 0xbe80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0x8b,0x00,0xb2,0x80 } },
+{  16, 0xbe90, 0, {0x0d,0xb1,0x03,0x24,0x02,0xcb,0x01,0x3e,0xc0,0x4d,0x90,0x43,0xe4,0x00,0xf9,0x00 } },
+{  16, 0xbea0, 0, {0xb2,0x00,0x2e,0x90,0x0b,0x2c,0x80,0xf8,0x00,0xba,0xc0,0x2c,0x80,0x03,0xc0,0x03 } },
+{  16, 0xbeb0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf4,0x00,0x7d,0x00,0x3f,0xc0 } },
+{  16, 0xbec0, 0, {0x0f,0x72,0x03,0xd4,0x00,0xff,0x00,0x3f,0xc0,0x0e,0xf1,0x47,0xfc,0x00,0xff,0x00 } },
+{  16, 0xbed0, 0, {0x3b,0xc0,0x0d,0xf0,0x13,0xfc,0x50,0xff,0x00,0x37,0xc0,0x0f,0xe0,0x03,0xe8,0x06 } },
+{  16, 0xbee0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0xc4,0xcc,0x33,0x3f,0x04 } },
+{  16, 0xbef0, 0, {0x2c,0xf6,0x03,0x38,0x60,0xcc,0x90,0xb3,0x20,0x0f,0xf1,0x23,0xf0,0x60,0xff,0x01 } },
+{  16, 0xbf00, 0, {0x23,0xc8,0x0c,0xf2,0x8a,0x3c,0x81,0xdf,0x30,0x3f,0x64,0x0c,0xd8,0x03,0x30,0x04 } },
+{  16, 0xbf10, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe0,0xc2,0x8a,0x30,0x2e,0x18 } },
+{  16, 0xbf20, 0, {0x08,0xf5,0x30,0xa5,0x94,0x58,0x22,0x22,0x21,0x4b,0xf3,0x02,0xe1,0x00,0x9f,0x70 } },
+{  16, 0xbf30, 0, {0x2b,0xe4,0x0a,0xf4,0x12,0x1d,0x40,0xaf,0x72,0x2c,0x49,0x2f,0x30,0x82,0xa0,0x06 } },
+{  16, 0xbf40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x80,0x80,0xa0,0x2c,0x98 } },
+{  16, 0xbf50, 0, {0x08,0x32,0x22,0x08,0x00,0x82,0x00,0x28,0x00,0x03,0x32,0x02,0xc0,0x84,0xb3,0x0c } },
+{  16, 0xbf60, 0, {0x20,0xc0,0x58,0x32,0x92,0x8c,0x30,0xa3,0x20,0x2e,0xc0,0x48,0x12,0x42,0x62,0x01 } },
+{  16, 0xbf70, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa8,0x00,0x8b,0x00,0x2e,0x20 } },
+{  16, 0xbf80, 0, {0x08,0xb0,0x0a,0x20,0x01,0x98,0x00,0x2a,0x22,0x0b,0xb0,0x02,0xe6,0x00,0x9b,0x00 } },
+{  16, 0xbf90, 0, {0x22,0xc0,0x0a,0xb0,0x12,0xac,0x04,0xab,0x00,0x2e,0xc0,0x03,0xb0,0x02,0xf0,0x00 } },
+{  16, 0xbfa0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xe5,0x00,0xc8,0x00,0x3e,0xb0 } },
+{  16, 0xbfb0, 0, {0x0c,0xb0,0x03,0x29,0x00,0xc8,0x00,0x3a,0x20,0x4f,0xb0,0x03,0xe2,0x20,0xfb,0x01 } },
+{  16, 0xbfc0, 0, {0xb0,0xc0,0x0c,0xb0,0x03,0x2c,0x00,0xfb,0x02,0x3c,0x41,0x0c,0x90,0x43,0x48,0x04 } },
+{  16, 0xbfd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xa2,0x80,0xfe,0x40,0x3e,0x00 } },
+{  16, 0xbfe0, 0, {0x0f,0xf0,0x63,0xec,0x00,0xbf,0xc4,0x17,0x42,0x0f,0xf0,0x03,0xec,0x00,0xff,0x00 } },
+{  16, 0xbff0, 0, {0x1f,0xc1,0x0f,0xb0,0x03,0x5c,0x00,0xfb,0x00,0x3f,0x40,0x4f,0xf0,0x00,0xb8,0x00 } },
+{  16, 0xc000, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa5,0x02,0xc8,0x00,0x3e,0x90 } },
+{  16, 0xc010, 0, {0x2c,0xb0,0x0b,0x01,0x06,0xcb,0x01,0x3e,0x50,0x5f,0xb0,0x13,0x21,0x10,0xcb,0x00 } },
+{  16, 0xc020, 0, {0x7e,0xc0,0x0c,0xb0,0x0b,0x2c,0x00,0xcb,0x00,0x32,0xc0,0x0c,0x90,0x03,0x10,0x04 } },
+{  16, 0xc030, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x28,0x01,0x8b,0xd0,0x2c,0x34 } },
+{  16, 0xc040, 0, {0x48,0xff,0x02,0x30,0x00,0xaa,0x04,0x2e,0x69,0x0f,0xf0,0x03,0x68,0x10,0xdf,0x00 } },
+{  16, 0xc050, 0, {0x2f,0xd4,0x0d,0xf0,0x02,0x3e,0x00,0x5f,0x04,0xb6,0xc0,0x08,0xb0,0x03,0x72,0x00 } },
+{  16, 0xc060, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x69,0x90,0x81,0x80,0x2c,0x00 } },
+{  16, 0xc070, 0, {0x48,0xb8,0x02,0x08,0x09,0x99,0x00,0x4c,0xb0,0x0b,0x30,0x02,0x0c,0x00,0x8b,0x00 } },
+{  16, 0xc080, 0, {0x2c,0xc0,0x09,0xb0,0x40,0x0c,0x40,0x83,0x00,0x00,0x40,0x0a,0x90,0x02,0x30,0x00 } },
+{  16, 0xc090, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x16,0x00,0x84,0x88,0x2d,0xe4 } },
+{  16, 0xc0a0, 0, {0x48,0x39,0x02,0x16,0x00,0xb4,0x80,0x2d,0xe0,0x0a,0x7b,0x06,0x5e,0x00,0x97,0x80 } },
+{  16, 0xc0b0, 0, {0x2d,0xe2,0x09,0x78,0x02,0x1e,0x90,0x97,0x80,0x25,0x64,0x8a,0x78,0x02,0x48,0x00 } },
+{  16, 0xc0c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0d,0x00,0x81,0x10,0x2c,0x96 } },
+{  16, 0xc0d0, 0, {0x08,0x31,0x23,0x0c,0x00,0x90,0x20,0x3c,0xc4,0x1b,0xb8,0x02,0x08,0x40,0xc3,0x00 } },
+{  16, 0xc0e0, 0, {0x2c,0xc4,0x0d,0x30,0x03,0x0e,0x40,0xc3,0x10,0x30,0xc0,0x4e,0x10,0x07,0x1a,0x12 } },
+{  16, 0xc0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x00,0x7d,0x05,0x3f,0xc5 } },
+{  16, 0xc100, 0, {0x0f,0xb1,0x0b,0xf4,0x00,0xef,0x00,0x1f,0x45,0x0f,0xf0,0x43,0xfc,0x01,0xff,0x40 } },
+{  16, 0xc110, 0, {0x3d,0xc4,0x1f,0xf0,0x06,0xfc,0x10,0xff,0x00,0x3b,0xc1,0x2d,0xf1,0x03,0xd0,0x06 } },
+{  16, 0xc120, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x04,0xcb,0x04,0x3e,0xa0 } },
+{  16, 0xc130, 0, {0x44,0xb6,0x03,0x28,0x04,0xcb,0x80,0x32,0x80,0x0f,0xb3,0x93,0x60,0x08,0xfb,0x20 } },
+{  16, 0xc140, 0, {0x3e,0xd2,0x1f,0xb3,0x03,0x2d,0x80,0xfb,0x61,0x7e,0x40,0x8c,0x98,0x03,0x2a,0x00 } },
+{  16, 0xc150, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x84,0x0c,0x86,0x05,0x2d,0xc0 } },
+{  16, 0xc160, 0, {0x08,0xf4,0x82,0x8c,0x90,0x85,0x00,0xa1,0xc0,0x0b,0xf0,0x02,0x5c,0x00,0x37,0x00 } },
+{  16, 0xc170, 0, {0x2d,0xd0,0x0b,0x71,0x02,0x1c,0xc8,0xb7,0x48,0x2d,0x40,0x0a,0x70,0x02,0x12,0x04 } },
+{  16, 0xc180, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0x87,0x80,0x2d,0xa1 } },
+{  16, 0xc190, 0, {0x60,0x78,0x4a,0x16,0xd0,0xa7,0x80,0x29,0xe0,0x0b,0x78,0x52,0x96,0x01,0xb7,0x90 } },
+{  16, 0xc1a0, 0, {0x2d,0xe8,0x0b,0x7a,0x22,0x5e,0x40,0xb7,0xa0,0x2f,0xe1,0x48,0x50,0x22,0x30,0x00 } },
+{  16, 0xc1b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x10,0x83,0x84,0x2c,0xc0 } },
+{  16, 0xc1c0, 0, {0x08,0x30,0x02,0xa4,0x10,0x83,0xcb,0x28,0xe0,0x0b,0x30,0x2a,0x4f,0x40,0x93,0x00 } },
+{  16, 0xc1d0, 0, {0x2c,0xc0,0x0b,0x30,0x02,0x4c,0x10,0xb3,0x02,0x2c,0xc0,0xaa,0x30,0x02,0x12,0x04 } },
+{  16, 0xc1e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x00,0xce,0xa0,0x3f,0x80 } },
+{  16, 0xc1f0, 0, {0x4c,0xa0,0x2b,0x3a,0x00,0xce,0x40,0x3b,0xb8,0x0f,0xa0,0x03,0xb9,0x00,0xba,0x00 } },
+{  16, 0xc200, 0, {0x3e,0x80,0x0f,0xa0,0x03,0x68,0x00,0xfa,0x00,0x7e,0x80,0x1c,0xa0,0x0b,0x3a,0x04 } },
+{  16, 0xc210, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x02,0xf8,0x00,0x3e,0x04 } },
+{  16, 0xc220, 0, {0x8f,0x00,0x03,0xe0,0x4a,0xf8,0x10,0x26,0x18,0x0f,0x80,0x03,0xa0,0x80,0xf8,0x02 } },
+{  16, 0xc230, 0, {0x3e,0x00,0x8f,0x00,0x0b,0xa0,0x00,0xf8,0x02,0x3e,0x00,0x0f,0x80,0x13,0xd2,0x00 } },
+{  16, 0xc240, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x20,0xc9,0x00,0x32,0x40 } },
+{  16, 0xc250, 0, {0x4d,0x99,0x03,0x24,0x00,0xc9,0x02,0x3e,0x68,0x0f,0x90,0x02,0x24,0x00,0xe9,0x00 } },
+{  16, 0xc260, 0, {0x30,0x40,0x8c,0x90,0x03,0x04,0x40,0xc9,0x00,0x3e,0x40,0x0c,0x90,0x03,0x02,0x04 } },
+{  16, 0xc270, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x20,0x89,0x06,0x22,0x50 } },
+{  16, 0xc280, 0, {0x8b,0x9c,0xc2,0x24,0x00,0xd9,0x01,0x2e,0x40,0x0b,0x90,0x42,0x24,0x08,0xb9,0x01 } },
+{  16, 0xc290, 0, {0x22,0x46,0x0d,0x90,0x0a,0x26,0x02,0x89,0x00,0x2c,0x40,0x0a,0x10,0x02,0x20,0x00 } },
+{  16, 0xc2a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x06,0x00,0x91,0x40,0x42,0x70 } },
+{  16, 0xc2b0, 0, {0x0b,0x90,0x12,0x2c,0x02,0x8b,0x00,0x2e,0x40,0x0b,0x10,0x22,0xe4,0x10,0xb1,0x00 } },
+{  16, 0xc2c0, 0, {0xa2,0x40,0x48,0x90,0x12,0x24,0x08,0x99,0x02,0x2e,0x40,0x08,0x90,0x02,0x06,0x00 } },
+{  16, 0xc2d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x92,0x91,0x20,0xe0,0x48 } },
+{  16, 0xc2e0, 0, {0x0b,0x12,0x02,0x04,0x02,0x91,0x10,0x2c,0xc0,0x0b,0x10,0x06,0x84,0xc0,0xb1,0x10 } },
+{  16, 0xc2f0, 0, {0x20,0x48,0x89,0x11,0x02,0x05,0x80,0x91,0x40,0x2e,0x44,0x2a,0x94,0x02,0x02,0x01 } },
+{  16, 0xc300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x50,0x30,0x14 } },
+{  16, 0xc310, 0, {0x0f,0x85,0x0b,0x21,0xe0,0x80,0x40,0x3e,0x00,0x0f,0x87,0x8b,0xe1,0x0c,0xf8,0x6c } },
+{  16, 0xc320, 0, {0x32,0x00,0x84,0x06,0x83,0x20,0x04,0xd8,0x28,0x3e,0x10,0x0c,0x00,0x03,0x2e,0x03 } },
+{  16, 0xc330, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x40,0xad,0x10,0x3f,0x45 } },
+{  16, 0xc340, 0, {0x0f,0x91,0x03,0xfc,0x18,0x7d,0x20,0x1f,0x41,0x0f,0x90,0x03,0x74,0xc0,0xf9,0x21 } },
+{  16, 0xc350, 0, {0x3e,0x44,0x0f,0x92,0x01,0xe4,0x40,0xe9,0x00,0x3d,0x48,0x4f,0xd0,0x03,0xe6,0x06 } },
+{  16, 0xc360, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf7,0x80,0xfd,0xe0,0x33,0x70 } },
+{  16, 0xc370, 0, {0x0c,0xda,0x03,0x26,0x20,0xc9,0x40,0x31,0x40,0x0e,0x9a,0x03,0x24,0x00,0xf9,0x80 } },
+{  16, 0xc380, 0, {0x3b,0x60,0x0f,0x9c,0x83,0x36,0xa0,0xf9,0xa1,0xb0,0x40,0x0f,0x91,0x03,0xc6,0x00 } },
+{  16, 0xc390, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe2,0x90,0xb8,0xa0,0x22,0x28 } },
+{  16, 0xc3a0, 0, {0x28,0x88,0x0a,0x22,0x02,0x88,0xa0,0x22,0x00,0x08,0x88,0x02,0xc2,0x80,0xb8,0x88 } },
+{  16, 0xc3b0, 0, {0x22,0x04,0x0b,0x8e,0x03,0x22,0x80,0xb8,0xd0,0x2a,0x20,0x0b,0x88,0x02,0xce,0x04 } },
+{  16, 0xc3c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x80,0xb1,0x61,0x00,0x58 } },
+{  16, 0xc3d0, 0, {0x48,0x16,0x8a,0x04,0xa0,0x89,0x01,0x22,0x40,0x1a,0x14,0x88,0x04,0x20,0xb1,0x40 } },
+{  16, 0xc3e0, 0, {0x28,0x40,0x0b,0x10,0x0a,0x04,0x20,0xb1,0x2c,0x20,0x4a,0x0b,0x12,0x02,0xc2,0x01 } },
+{  16, 0xc3f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa5,0x90,0xbb,0x40,0x20,0x40 } },
+{  16, 0xc400, 0, {0x08,0x90,0x02,0x24,0x40,0x89,0x42,0x62,0x58,0x08,0x10,0x02,0xe5,0x00,0xb9,0x03 } },
+{  16, 0xc410, 0, {0x22,0xc0,0x0b,0x90,0x02,0xa4,0x14,0x31,0x00,0x2a,0x44,0x0b,0x90,0x02,0xc6,0x04 } },
+{  16, 0xc420, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0xa5,0x00,0xf9,0x01,0x32,0x40 } },
+{  16, 0xc430, 0, {0x8c,0x90,0x03,0x27,0x00,0xc1,0x94,0x30,0x40,0x0e,0x90,0x03,0x24,0x00,0xf9,0x00 } },
+{  16, 0xc440, 0, {0x3a,0x40,0x0f,0x90,0x03,0x24,0x00,0xf9,0x00,0x32,0x60,0x07,0x90,0x27,0xe8,0x05 } },
+{  16, 0xc450, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa4,0x18,0xf9,0x00,0xbe,0x44 } },
+{  16, 0xc460, 0, {0x0f,0x90,0x03,0xc4,0x00,0xf9,0x00,0xbe,0x61,0x8f,0x90,0x03,0xa4,0x00,0xf1,0x00 } },
+{  16, 0xc470, 0, {0x1e,0x40,0x0f,0x10,0x03,0x24,0x08,0xf9,0x00,0x7e,0x40,0x0f,0x90,0x03,0xca,0x00 } },
+{  16, 0xc480, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x81,0xf8,0x00,0x32,0x04 } },
+{  16, 0xc490, 0, {0x0c,0x00,0xd3,0x21,0x00,0xd8,0x04,0x3a,0x14,0x9c,0x80,0x03,0x21,0x01,0xc8,0x00 } },
+{  16, 0xc4a0, 0, {0x36,0x00,0x0c,0x80,0x13,0x20,0x10,0xc8,0x00,0x32,0x00,0x2c,0x80,0x03,0xca,0x04 } },
+{  16, 0xc4b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x04,0x3a,0x00,0xbe,0x84,0x23,0x85 } },
+{  16, 0xc4c0, 0, {0x08,0xec,0x83,0x68,0x04,0x8a,0x00,0x2f,0x90,0x4d,0xa0,0x02,0x28,0x01,0xda,0x00 } },
+{  16, 0xc4d0, 0, {0x23,0xb0,0x0a,0xa0,0x02,0x2a,0x08,0xda,0x01,0x22,0x80,0x0f,0xa0,0x02,0xca,0x00 } },
+{  16, 0xc4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xbb,0xf0,0x20,0xc0 } },
+{  16, 0xc4f0, 0, {0x08,0x3c,0x0a,0x0c,0x00,0x93,0x01,0x28,0xc8,0x89,0x30,0x06,0x4c,0x00,0x83,0x02 } },
+{  16, 0xc500, 0, {0x2c,0xf6,0x08,0x30,0x02,0x04,0x00,0xa3,0x00,0x20,0xc0,0x0a,0x30,0x02,0xca,0x00 } },
+{  16, 0xc510, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1d,0x11,0xb3,0x00,0xa0,0xc0 } },
+{  16, 0xc520, 0, {0x08,0x50,0x02,0x5c,0x10,0x87,0x01,0x6d,0x81,0x49,0x32,0x52,0x1e,0xc3,0x87,0x00 } },
+{  16, 0xc530, 0, {0x28,0xe0,0x0a,0x32,0x26,0x1f,0x00,0x37,0x00,0x23,0xe0,0x0b,0x72,0x02,0xc8,0x00 } },
+{  16, 0xc540, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x12,0x00,0xb7,0x82,0x31,0x20 } },
+{  16, 0xc550, 0, {0x08,0x08,0x37,0x0f,0x08,0xd7,0xe0,0x39,0x60,0x19,0x7a,0x0b,0x5e,0x0c,0x83,0xb2 } },
+{  16, 0xc560, 0, {0x7d,0xe0,0x0c,0x7a,0x0b,0x3e,0x02,0xaf,0xa0,0xb1,0xe0,0x0e,0x7a,0x03,0xca,0x02 } },
+{  16, 0xc570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xa0,0x10,0xfb,0x00,0x3e,0xc0 } },
+{  16, 0xc580, 0, {0x6f,0xb0,0x43,0xec,0x11,0xfb,0x00,0x3e,0x40,0x0f,0xb5,0x03,0xec,0x20,0xfb,0x50 } },
+{  16, 0xc590, 0, {0x36,0x00,0x0f,0xb5,0x43,0xe5,0xa1,0xdb,0x78,0x3e,0xc0,0x0f,0xb4,0x03,0xc2,0x06 } },
+{  16, 0xc5a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xff,0xa0,0x3f,0xa0 } },
+{  16, 0xc5b0, 0, {0x0d,0xc9,0x13,0x3e,0x00,0xcf,0xd0,0x3d,0xe8,0x02,0xff,0x13,0x3e,0x00,0xcf,0x82 } },
+{  16, 0xc5c0, 0, {0x3f,0x60,0x0c,0xfc,0x23,0x3e,0x10,0xef,0x80,0x33,0xf2,0x0c,0xfc,0x83,0x10,0x00 } },
+{  16, 0xc5d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x40,0xb5,0x01,0x2d,0xd0 } },
+{  16, 0xc5e0, 0, {0x08,0x58,0x02,0x1c,0x40,0x57,0x10,0x2d,0x5a,0x28,0x31,0x02,0xbc,0x01,0x97,0x10 } },
+{  16, 0xc5f0, 0, {0x2d,0x00,0x0a,0x70,0x02,0x84,0x04,0xcf,0x00,0x29,0xc0,0x0a,0xf0,0x02,0x2a,0x04 } },
+{  16, 0xc600, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0xb7,0x2a,0x2d,0x82 } },
+{  16, 0xc610, 0, {0x08,0x42,0x22,0x3c,0x00,0x87,0x11,0x0d,0xcc,0x88,0x32,0x02,0x1d,0x00,0x97,0x00 } },
+{  16, 0xc620, 0, {0x2c,0xc4,0x08,0x30,0x02,0x14,0x00,0xa7,0x00,0x23,0xc0,0x09,0x70,0x82,0x00,0x00 } },
+{  16, 0xc630, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xc0,0x20,0xb0,0x20,0x2c,0x50 } },
+{  16, 0xc640, 0, {0x08,0x10,0x02,0x2d,0xc0,0x93,0xe2,0x2c,0x21,0x08,0x30,0x02,0x0e,0x08,0x93,0x00 } },
+{  16, 0xc650, 0, {0x2c,0x40,0x0a,0x30,0x02,0x8c,0x00,0x93,0x00,0x2a,0xc0,0x0b,0x30,0x02,0x18,0x04 } },
+{  16, 0xc660, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xf8,0xc0,0x3e,0x80 } },
+{  16, 0xc670, 0, {0x2c,0xa0,0x0b,0x3f,0x00,0xc7,0x60,0x3e,0xd0,0x0c,0xf0,0x0b,0x3c,0x00,0xcf,0x00 } },
+{  16, 0xc680, 0, {0x3e,0x80,0x0c,0xf0,0x0b,0x2c,0x00,0xef,0x00,0x33,0xc1,0x0d,0xf0,0x0b,0x2a,0x04 } },
+{  16, 0xc690, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x40,0xf3,0x40,0x3e,0x50 } },
+{  16, 0xc6a0, 0, {0x8e,0xb4,0x03,0xec,0x10,0xfb,0x00,0x3e,0x09,0x0f,0xb0,0x13,0xec,0x42,0xeb,0x00 } },
+{  16, 0xc6b0, 0, {0x3c,0x00,0x8f,0xb0,0x13,0xc4,0x11,0xe3,0x00,0x3e,0xc0,0x0e,0xb0,0x03,0xe0,0x00 } },
+{  16, 0xc6c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xfc,0x80,0x31,0x22 } },
+{  16, 0xc6d0, 0, {0x0c,0xa8,0x03,0x3c,0x00,0xcf,0x00,0x33,0xa0,0x0e,0xf0,0x03,0xdc,0x00,0xcf,0x00 } },
+{  16, 0xc6e0, 0, {0x1f,0xf0,0x0c,0xf0,0x03,0xf4,0x00,0xcf,0x02,0x33,0xc0,0x0c,0xf0,0x02,0x00,0x54 } },
+{  16, 0xc6f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6f,0x00,0xbb,0xc0,0x22,0x70 } },
+{  16, 0xc700, 0, {0x0a,0xb9,0x42,0x2c,0x10,0x8b,0x00,0x76,0x11,0x83,0xb0,0x02,0xec,0x10,0xab,0x00 } },
+{  16, 0xc710, 0, {0x2e,0xb0,0x0a,0xb0,0x03,0xec,0x04,0x8b,0x00,0xa2,0xc0,0x28,0xb0,0x02,0x20,0x40 } },
+{  16, 0xc720, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x65,0x40,0xb8,0x20,0x22,0x44 } },
+{  16, 0xc730, 0, {0x58,0x34,0x0a,0x2c,0x00,0x8b,0x00,0x22,0x84,0x4b,0xb0,0x02,0xec,0x00,0x8b,0x00 } },
+{  16, 0xc740, 0, {0x6e,0xc0,0x08,0xb0,0x42,0xe6,0x04,0x8b,0x00,0x02,0xc0,0x08,0x30,0x02,0xa0,0x01 } },
+{  16, 0xc750, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0xb1,0x00,0x20,0xc0 } },
+{  16, 0xc760, 0, {0x0a,0x30,0x0a,0x0c,0x00,0x8b,0x03,0x24,0x80,0x0b,0x30,0x02,0xcc,0x00,0xa3,0x00 } },
+{  16, 0xc770, 0, {0x6c,0x00,0x0a,0x30,0x02,0x8d,0x00,0x83,0x00,0x20,0xc0,0x18,0x30,0x02,0x82,0x00 } },
+{  16, 0xc780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x64,0x00,0xf8,0x00,0x30,0x00 } },
+{  16, 0xc790, 0, {0x4c,0xa0,0x0b,0x2c,0x02,0xcf,0x00,0x22,0x40,0x0e,0xf5,0x03,0xfc,0x00,0xcf,0x01 } },
+{  16, 0xc7a0, 0, {0x3e,0x00,0x0c,0xf0,0x12,0xdd,0x02,0xcf,0x02,0x33,0xc0,0x4c,0xf0,0x0b,0x80,0x03 } },
+{  16, 0xc7b0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa4,0x19,0xf0,0x00,0xfc,0x00,0x3f,0x40 } },
+{  16, 0xc7c0, 0, {0x0f,0xb1,0x03,0xdc,0x00,0xbf,0x01,0x3f,0x00,0x0f,0xf2,0x23,0xfc,0x10,0xff,0x00 } },
+{  16, 0xc7d0, 0, {0x3f,0x00,0x0f,0xf0,0x01,0xf4,0x84,0xff,0x00,0x3d,0xc0,0x4f,0xf0,0x13,0x68,0x06 } },
+{  16, 0xc7e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x40,0xdf,0x80,0x33,0xc8 } },
+{  16, 0xc7f0, 0, {0x0c,0xf8,0x03,0x3c,0x0a,0x9f,0xc0,0x3f,0xf0,0x08,0xb8,0x02,0x3e,0x00,0xff,0x80 } },
+{  16, 0xc800, 0, {0x3f,0xd8,0x0c,0xf9,0x61,0x2e,0x40,0x6f,0x90,0x3f,0xe4,0x8f,0xf1,0x83,0x30,0x00 } },
+{  16, 0xc810, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0x04,0x8b,0x80,0x23,0xf0 } },
+{  16, 0xc820, 0, {0x08,0xb8,0x02,0x3d,0x40,0xab,0x00,0x0e,0x08,0x48,0x22,0x82,0x6c,0x20,0xbb,0x00 } },
+{  16, 0xc830, 0, {0x2f,0xd0,0x48,0xb0,0x02,0x2c,0x00,0xbb,0x00,0x2e,0xc1,0x0b,0xb0,0x02,0x30,0x04 } },
+{  16, 0xc840, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x02,0x83,0x01,0xa0,0xc5 } },
+{  16, 0xc850, 0, {0x08,0xb0,0x4a,0x4c,0xa0,0x80,0x24,0x28,0xc8,0x09,0x32,0x02,0x4c,0x00,0xb3,0x08 } },
+{  16, 0xc860, 0, {0x2e,0xd1,0x29,0xb2,0x3a,0x0c,0x84,0xa3,0x21,0x2c,0xc8,0x4b,0xb2,0x0a,0x32,0x01 } },
+{  16, 0xc870, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x08,0x8b,0x00,0x22,0xc0 } },
+{  16, 0xc880, 0, {0x08,0xb0,0x02,0x4c,0x00,0x88,0x21,0x24,0x21,0x09,0xb0,0x46,0x6c,0x00,0xbb,0x06 } },
+{  16, 0xc890, 0, {0x2e,0xc0,0x09,0xb0,0x02,0x2c,0x10,0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0x30,0x04 } },
+{  16, 0xc8a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xcb,0x00,0x32,0xc0 } },
+{  16, 0xc8b0, 0, {0x0c,0xb9,0x02,0x6c,0x00,0xcb,0xc8,0x3a,0xc0,0x2d,0x90,0x0b,0x2c,0x08,0xfb,0x00 } },
+{  16, 0xc8c0, 0, {0x3e,0xc0,0x0d,0x30,0x42,0x2c,0x00,0xeb,0x00,0x3e,0xc0,0x0f,0xb0,0x13,0x00,0x04 } },
+{  16, 0xc8d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbc,0x00,0xef,0x00,0x3d,0xc0 } },
+{  16, 0xc8e0, 0, {0x0f,0xf0,0x03,0xbc,0x06,0xef,0x82,0x3f,0x40,0x4e,0xc9,0x83,0xbc,0x00,0xff,0x00 } },
+{  16, 0xc8f0, 0, {0x7f,0xc0,0x1c,0xf0,0x13,0x7c,0x00,0xff,0x04,0x3f,0xc0,0x0f,0xf0,0x03,0xf8,0x00 } },
+{  16, 0xc900, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x02,0x3e,0xc0 } },
+{  16, 0xc910, 0, {0x0e,0xb0,0x03,0xac,0x20,0xd8,0x40,0x3e,0xc0,0x8c,0x90,0x0b,0x2c,0x00,0xfb,0x00 } },
+{  16, 0xc920, 0, {0x3e,0xc9,0x0d,0xb0,0x33,0xec,0x08,0xfb,0x02,0x3e,0xc0,0x0f,0xb0,0x0b,0x54,0x04 } },
+{  16, 0xc930, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xb3,0x00,0x2f,0xc0 } },
+{  16, 0xc940, 0, {0x0b,0x30,0x12,0xfc,0x00,0x88,0xa0,0x2e,0x40,0x28,0x94,0x02,0x2c,0x10,0xbb,0x04 } },
+{  16, 0xc950, 0, {0x2d,0xc0,0x28,0xb0,0x02,0xec,0x00,0xbb,0x00,0x2e,0xc0,0x0b,0x72,0x06,0x32,0x00 } },
+{  16, 0xc960, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x6c,0x00,0xb3,0x00,0x2c,0xe0 } },
+{  16, 0xc970, 0, {0x0a,0x10,0x02,0xcd,0x00,0x93,0x00,0x2c,0xc0,0x08,0xb0,0x02,0x4c,0x00,0xb3,0x00 } },
+{  16, 0xc980, 0, {0x28,0xc0,0x08,0x30,0x02,0xcc,0x00,0xb3,0x00,0x2c,0xc0,0x0b,0x30,0x02,0x3a,0x00 } },
+{  16, 0xc990, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x40,0xb7,0x80,0x2d,0xe2 } },
+{  16, 0xc9a0, 0, {0x0b,0x58,0x02,0xde,0x02,0x97,0x81,0x2f,0xa0,0x08,0x68,0x02,0x5e,0x00,0xb7,0x81 } },
+{  16, 0xc9b0, 0, {0x2f,0xe0,0x08,0x79,0x02,0xde,0x00,0xb7,0x81,0x2d,0xe0,0x0b,0x78,0x02,0x3c,0x00 } },
+{  16, 0xc9c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xf3,0x00,0x3c,0xc0 } },
+{  16, 0xc9d0, 0, {0x0e,0x32,0x03,0xcc,0x80,0xd3,0x00,0x3c,0xc4,0x0c,0x39,0x03,0x4c,0x08,0xf3,0x1a } },
+{  16, 0xc9e0, 0, {0x3c,0xc6,0x0d,0x30,0x03,0xce,0x20,0xf3,0x08,0x3c,0xc0,0x0f,0x30,0x03,0x52,0x02 } },
+{  16, 0xc9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xac,0x00,0xfb,0x00,0x2e,0xc0 } },
+{  16, 0xca00, 0, {0x0b,0xb0,0x03,0xcc,0x20,0xeb,0x00,0x3c,0x80,0x0f,0xb0,0x41,0xac,0x00,0xfb,0x00 } },
+{  16, 0xca10, 0, {0x3c,0xc2,0x0f,0xb0,0x03,0xec,0x40,0xfb,0x00,0x3e,0xc0,0x0f,0x30,0x03,0xd0,0x06 } },
+{  16, 0xca20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xee,0x02,0xc3,0x80,0x30,0xce } },
+{  16, 0xca30, 0, {0x0d,0x98,0x03,0xac,0xa0,0xc3,0x80,0xb2,0xc0,0x0f,0xb0,0x03,0xec,0x00,0xfb,0x00 } },
+{  16, 0xca40, 0, {0x3e,0xd2,0x4f,0xb0,0x09,0x2e,0x08,0x4b,0x01,0x3e,0xc0,0x24,0xb0,0x03,0xea,0x00 } },
+{  16, 0xca50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0x87,0x01,0x21,0xc0 } },
+{  16, 0xca60, 0, {0x48,0x50,0x12,0x4c,0x00,0x87,0x00,0x35,0xc0,0x4b,0x60,0x02,0xdc,0x04,0xb7,0x01 } },
+{  16, 0xca70, 0, {0x2d,0xc0,0x0b,0x70,0x02,0x1c,0x00,0x87,0x00,0x2d,0xc1,0x0c,0x72,0x02,0xf2,0x04 } },
+{  16, 0xca80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0x87,0x80,0x23,0xe0 } },
+{  16, 0xca90, 0, {0x08,0xf8,0x02,0xde,0x80,0x8f,0x81,0x21,0xe0,0x4b,0x78,0x12,0xde,0x04,0x37,0x80 } },
+{  16, 0xcaa0, 0, {0x2d,0xe8,0x0b,0xf8,0x02,0x3e,0x18,0x87,0x80,0x2f,0xe0,0x09,0x79,0x02,0xe0,0x00 } },
+{  16, 0xcab0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0x83,0x00,0xa0,0xc0 } },
+{  16, 0xcac0, 0, {0x28,0x30,0x42,0x4c,0x00,0x83,0x00,0x24,0xc0,0x0b,0x38,0x06,0xcc,0x04,0xb3,0x00 } },
+{  16, 0xcad0, 0, {0x2c,0xc0,0x0b,0x30,0x02,0x0c,0x02,0x83,0x00,0x2c,0xc0,0x08,0x30,0x02,0xd2,0x04 } },
+{  16, 0xcae0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xca,0x00,0x31,0x80 } },
+{  16, 0xcaf0, 0, {0x08,0xe0,0x02,0x98,0x02,0xce,0x00,0x33,0x84,0x0b,0xea,0x03,0xe8,0x00,0xba,0x00 } },
+{  16, 0xcb00, 0, {0x3f,0x81,0x0f,0xa0,0x03,0x28,0x00,0xca,0x00,0x3e,0x80,0x0d,0xe0,0x03,0xfa,0x04 } },
+{  16, 0xcb10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x00 } },
+{  16, 0xcb20, 0, {0x0e,0x84,0x23,0xa0,0x00,0xf8,0x00,0x3a,0x10,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x00 } },
+{  16, 0xcb30, 0, {0x3e,0x10,0x0f,0x80,0x13,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0d,0x80,0x03,0xd2,0x00 } },
+{  16, 0xcb40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x01,0xf9,0x00,0x3e,0x40 } },
+{  16, 0xcb50, 0, {0x0c,0x9a,0x13,0xe4,0x00,0xc9,0x00,0x3e,0x40,0x0c,0x98,0x23,0xe4,0x80,0xf9,0x00 } },
+{  16, 0xcb60, 0, {0x3e,0x40,0x2c,0x98,0x03,0x64,0x00,0xf9,0x00,0x3e,0x40,0x0c,0x90,0x03,0xc2,0x04 } },
+{  16, 0xcb70, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x04,0xb9,0x00,0x2e,0x40 } },
+{  16, 0xcb80, 0, {0x68,0x9c,0x22,0xe4,0x02,0x89,0x01,0x7c,0x50,0x8d,0x98,0x22,0xe4,0x80,0xb9,0x20 } },
+{  16, 0xcb90, 0, {0x2e,0x50,0x48,0x10,0x0b,0x25,0x00,0xb9,0x44,0x2c,0x40,0x28,0x90,0x00,0xe0,0x00 } },
+{  16, 0xcba0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x00,0x2e,0x50 } },
+{  16, 0xcbb0, 0, {0x08,0x90,0x02,0xe4,0x04,0x89,0x00,0x2e,0x50,0x0a,0x92,0x02,0xe4,0x00,0xb9,0x00 } },
+{  16, 0xcbc0, 0, {0x2c,0x40,0x08,0x91,0x02,0x24,0x00,0xb9,0x00,0x2e,0x40,0x08,0x90,0x02,0xc6,0x00 } },
+{  16, 0xcbd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x05,0x00,0xb1,0x01,0x2c,0x40 } },
+{  16, 0xcbe0, 0, {0x48,0x30,0x02,0xe4,0x00,0x81,0x00,0x2a,0x40,0x4b,0x10,0x02,0xc4,0x00,0xb1,0x00 } },
+{  16, 0xcbf0, 0, {0x0c,0xc0,0x08,0x90,0x02,0x0c,0x00,0xb3,0x00,0x2e,0x40,0x48,0x12,0x02,0xc2,0x01 } },
+{  16, 0xcc00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xb8,0x01,0x3e,0x00 } },
+{  16, 0xcc10, 0, {0x1c,0x80,0x07,0xe1,0x50,0xc8,0x50,0x2e,0x14,0x1e,0x85,0x03,0xe1,0x41,0xf8,0x50 } },
+{  16, 0xcc20, 0, {0x3e,0x14,0x0c,0x85,0x13,0x21,0x48,0xf8,0x50,0x3e,0x14,0x0c,0x85,0x43,0xee,0x03 } },
+{  16, 0xcc30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x19,0xc4,0x00,0xf9,0x00,0x3e,0x51 } },
+{  16, 0xcc40, 0, {0x0f,0x50,0x03,0xe5,0x00,0xfd,0x00,0x3f,0x40,0x1d,0xd0,0x03,0xf4,0x10,0xf9,0x00 } },
+{  16, 0xcc50, 0, {0x3e,0x50,0x0f,0x50,0x00,0x94,0x00,0xf9,0x00,0x3d,0x40,0x0f,0x91,0x03,0xe6,0x06 } },
+{  16, 0xcc60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xe4,0x50,0xcd,0x00,0x31,0x60 } },
+{  16, 0xcc70, 0, {0x04,0xd0,0x03,0x36,0x80,0xc1,0x42,0x2e,0x50,0x1f,0x94,0x03,0xe5,0x00,0xe9,0x02 } },
+{  16, 0xcc80, 0, {0x2e,0x72,0x0a,0x90,0x22,0x05,0x08,0xe9,0x40,0x3e,0x50,0x40,0x9c,0x03,0x26,0x00 } },
+{  16, 0xcc90, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xc2,0x82,0x88,0x00,0x22,0x15 } },
+{  16, 0xcca0, 0, {0x08,0x80,0x02,0x23,0x58,0x88,0xa0,0x2e,0x28,0x0b,0xaa,0x42,0xe2,0x82,0x88,0x80 } },
+{  16, 0xccb0, 0, {0x2e,0x38,0x28,0x88,0x02,0x22,0x80,0xb8,0xa0,0x3a,0x28,0x08,0xcd,0x02,0x0e,0x04 } },
+{  16, 0xccc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0x81,0x00,0xa6,0x40 } },
+{  16, 0xccd0, 0, {0x28,0x10,0x0a,0x24,0x26,0x95,0x00,0x0d,0x40,0x0b,0x50,0x02,0x74,0x00,0x85,0x08 } },
+{  16, 0xcce0, 0, {0x2f,0x40,0x79,0xd2,0xaa,0x14,0x00,0xa5,0x01,0x2f,0x40,0x38,0x50,0x02,0x12,0x01 } },
+{  16, 0xccf0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x04,0x89,0x00,0x26,0x40 } },
+{  16, 0xcd00, 0, {0x08,0x91,0x02,0x24,0x10,0x9d,0x08,0x2f,0x40,0x0b,0xd0,0x02,0xf4,0x00,0x8d,0x02 } },
+{  16, 0xcd10, 0, {0x2f,0x40,0x09,0xd0,0x00,0x34,0x00,0xbd,0x00,0x0b,0x40,0x18,0x70,0x02,0x06,0x04 } },
+{  16, 0xcd20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xc4,0x00,0xc9,0x05,0x36,0x41 } },
+{  16, 0xcd30, 0, {0x4c,0x90,0x63,0x24,0x00,0xd9,0x00,0x3e,0x40,0x0b,0x90,0x03,0x44,0x08,0xc9,0x00 } },
+{  16, 0xcd40, 0, {0x3e,0x40,0x15,0x10,0x03,0x24,0x00,0xe9,0x00,0x3c,0x40,0x0c,0x90,0x03,0x28,0x04 } },
+{  16, 0xcd50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x04,0xf9,0x00,0x3a,0x40 } },
+{  16, 0xcd60, 0, {0x4f,0x98,0x03,0xe4,0x00,0xe9,0x99,0x3e,0x40,0x4f,0x90,0x03,0xe4,0x20,0xf9,0x0a } },
+{  16, 0xcd70, 0, {0x3e,0x40,0x0e,0x90,0x43,0x64,0x24,0xf9,0x08,0x3a,0x42,0x0f,0x90,0x8b,0xda,0x00 } },
+{  16, 0xcd80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x00,0x12,0x00 } },
+{  16, 0xcd90, 0, {0x0c,0x80,0x43,0xe0,0x00,0xc8,0x40,0x32,0x00,0x0f,0x84,0x53,0xe0,0x10,0xf8,0x00 } },
+{  16, 0xcda0, 0, {0x3e,0x00,0x0d,0x80,0x23,0x20,0x00,0xd8,0x00,0x3e,0x00,0x0f,0x80,0x03,0x0a,0x04 } },
+{  16, 0xcdb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x38,0x02,0x82,0x00,0xa1,0x88 } },
+{  16, 0xcdc0, 0, {0x08,0x60,0x22,0xc8,0x00,0x8a,0x40,0x36,0xa1,0x0b,0xa0,0x02,0xe9,0x10,0xba,0x44 } },
+{  16, 0xcdd0, 0, {0x2c,0x80,0x0c,0xa4,0x12,0x29,0x02,0x8a,0x44,0x2e,0x98,0x0b,0xa4,0x02,0x0a,0x00 } },
+{  16, 0xcde0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x10,0x83,0x00,0x20,0xe0 } },
+{  16, 0xcdf0, 0, {0x18,0x30,0x92,0xc4,0x08,0x93,0x40,0x20,0xe0,0x0b,0x30,0x02,0xcd,0x00,0xb3,0x40 } },
+{  16, 0xce00, 0, {0x2c,0xc0,0x0b,0x3a,0x42,0xcd,0x00,0x83,0x40,0x2c,0xd0,0x0b,0x38,0x02,0x4a,0x00 } },
+{  16, 0xce10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x41,0x1c,0x00,0x87,0x00,0x21,0xc0 } },
+{  16, 0xce20, 0, {0x28,0x70,0x02,0xd1,0x00,0x9d,0x80,0x25,0xc2,0x4b,0x60,0x02,0xdc,0x08,0xb7,0x02 } },
+{  16, 0xce30, 0, {0x2c,0xc0,0x0a,0x74,0x02,0xfe,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x34,0x02,0x68,0x00 } },
+{  16, 0xce40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0x84,0x31,0xe0 } },
+{  16, 0xce50, 0, {0x0c,0x68,0x03,0xd6,0x00,0x97,0x80,0x31,0xa0,0x0f,0x58,0x13,0xde,0x08,0xf7,0x82 } },
+{  16, 0xce60, 0, {0x3d,0xa0,0x0f,0xf8,0x0b,0xde,0x00,0xc7,0x80,0x3d,0xe0,0x0f,0x78,0x8b,0x6a,0x02 } },
+{  16, 0xce70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xad,0x80,0xf3,0x00,0x3e,0xc1 } },
+{  16, 0xce80, 0, {0x0f,0xa0,0x23,0xc0,0x02,0xe9,0x00,0x3e,0x81,0x0f,0x80,0x03,0xec,0x00,0xfb,0x00 } },
+{  16, 0xce90, 0, {0x3e,0xc0,0x0d,0xb0,0x13,0x2c,0x00,0xeb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x82,0x02 } },
+{  16, 0xcea0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0x32,0xc7,0x80,0x33,0x60 } },
+{  16, 0xceb0, 0, {0x0f,0x78,0x03,0x3e,0xc8,0x4e,0x80,0x23,0x64,0x0c,0xf8,0x03,0x3a,0x00,0xce,0x80 } },
+{  16, 0xcec0, 0, {0x13,0xec,0x06,0xd8,0x03,0x3a,0x00,0xde,0x80,0x33,0xa4,0x0c,0xc8,0x03,0xd0,0x00 } },
+{  16, 0xced0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0x87,0x10,0x01,0xc0 } },
+{  16, 0xcee0, 0, {0x0b,0x70,0x02,0x18,0x50,0x84,0x00,0x2b,0x44,0x08,0x60,0x12,0x98,0x00,0x86,0x13 } },
+{  16, 0xcef0, 0, {0x21,0xc4,0x88,0x50,0x02,0x18,0x80,0x86,0x00,0x21,0x80,0x08,0x61,0x02,0xea,0x04 } },
+{  16, 0xcf00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x87,0x00,0x21,0x40 } },
+{  16, 0xcf10, 0, {0x0b,0xf1,0x02,0x5c,0x80,0x06,0x00,0x21,0x00,0x88,0xd0,0x02,0x5c,0x00,0x87,0x00 } },
+{  16, 0xcf20, 0, {0x20,0x89,0x8a,0xf1,0x02,0x1c,0x08,0x87,0x10,0x21,0x81,0x88,0x48,0x02,0xc6,0x00 } },
+{  16, 0xcf30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x10,0x83,0x04,0xa0,0xc1 } },
+{  16, 0xcf40, 0, {0x0b,0x30,0x0a,0x48,0x0c,0x88,0x06,0x60,0x38,0x08,0x04,0x42,0xec,0x01,0x8b,0x04 } },
+{  16, 0xcf50, 0, {0x22,0xc1,0x08,0x30,0x0a,0x2c,0x00,0x8b,0x00,0x22,0x80,0x00,0x20,0x02,0xd8,0x04 } },
+{  16, 0xcf60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xc3,0x00,0x22,0x80 } },
+{  16, 0xcf70, 0, {0x8f,0x90,0x03,0x64,0x0a,0xcb,0x02,0xb2,0xf2,0x20,0x35,0x12,0x64,0x0a,0xc9,0x00 } },
+{  16, 0xcf80, 0, {0xb2,0x40,0x0e,0xa0,0x03,0x24,0x0a,0xc9,0x00,0xa2,0x40,0x2c,0xa0,0x03,0xee,0x04 } },
+{  16, 0xcf90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xfb,0x00,0x3c,0x80 } },
+{  16, 0xcfa0, 0, {0x0f,0x90,0x03,0xa5,0x00,0xdb,0x40,0x3e,0xd0,0x4d,0xb4,0x13,0xa4,0x08,0xfb,0x01 } },
+{  16, 0xcfb0, 0, {0x3e,0xc0,0x1c,0xa0,0x03,0x6c,0x00,0xfb,0x04,0x3e,0x50,0x4f,0xa4,0x03,0xe0,0x00 } },
+{  16, 0xcfc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x00,0x33,0xc0 } },
+{  16, 0xcfd0, 0, {0x0c,0xe8,0x43,0x26,0x00,0xdf,0x80,0xb3,0xe0,0x0f,0xf8,0x03,0x7c,0x00,0xcd,0x00 } },
+{  16, 0xcfe0, 0, {0x33,0x04,0x0c,0xe0,0x23,0x34,0x40,0xcd,0x00,0x23,0x40,0x0c,0xe0,0x03,0xe0,0x04 } },
+{  16, 0xcff0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x10,0xbb,0x00,0xa2,0xd2 } },
+{  16, 0xd000, 0, {0x08,0x28,0x02,0x04,0x60,0x8b,0x19,0x22,0xc6,0x0e,0xb1,0x8a,0x2e,0x40,0x8b,0x90 } },
+{  16, 0xd010, 0, {0x22,0xc1,0x08,0xa4,0x82,0x2c,0x00,0x8b,0x90,0x22,0x64,0x48,0xa4,0x02,0xe0,0x00 } },
+{  16, 0xd020, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xbb,0x00,0x22,0x00 } },
+{  16, 0xd030, 0, {0x08,0x91,0x2e,0x24,0x00,0x9b,0x00,0x22,0xc0,0x8b,0xb0,0x12,0x20,0x04,0x88,0x00 } },
+{  16, 0xd040, 0, {0x22,0x40,0x08,0x10,0x22,0x20,0x00,0x88,0x01,0x2a,0xd0,0x08,0x80,0x42,0xe0,0x00 } },
+{  16, 0xd050, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0xb3,0x04,0x20,0x80 } },
+{  16, 0xd060, 0, {0x08,0x10,0x06,0x04,0x10,0x83,0x00,0x20,0xc0,0x8b,0xb0,0x12,0x00,0x00,0x82,0x00 } },
+{  16, 0xd070, 0, {0x20,0xc0,0x28,0x10,0x42,0x09,0x06,0x82,0x00,0x28,0xc0,0x08,0x20,0x02,0xc2,0x01 } },
+{  16, 0xd080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0xbb,0x00,0x32,0x40 } },
+{  16, 0xd090, 0, {0x2c,0xb0,0x03,0x24,0x00,0xd3,0x00,0x32,0xc0,0x5f,0xb5,0x03,0x0c,0x02,0xc1,0x00 } },
+{  16, 0xd0a0, 0, {0xb2,0x00,0x0c,0xb0,0x0b,0x05,0x00,0xc1,0x00,0xb8,0xc0,0x2c,0x80,0x13,0xe0,0x03 } },
+{  16, 0xd0b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xdc,0x00,0xff,0x00,0x1f,0xc0 } },
+{  16, 0xd0c0, 0, {0x87,0xf0,0x01,0xf4,0x00,0xff,0x00,0x3f,0xc0,0x0e,0x70,0x43,0xfc,0x10,0x7f,0x00 } },
+{  16, 0xd0d0, 0, {0x3f,0xc0,0x0f,0x70,0x03,0xfc,0x00,0xff,0x00,0x37,0xc0,0x0f,0xe0,0x03,0xe8,0x06 } },
+{  16, 0xd0e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf1,0x84,0xfe,0x61,0x31,0xd8 } },
+{  16, 0xd0f0, 0, {0x0c,0xb2,0xc3,0xfc,0xe0,0xcc,0x80,0x7b,0xc0,0x0e,0xf1,0x03,0x7c,0xe0,0xcc,0x83 } },
+{  16, 0xd100, 0, {0x3f,0x20,0x0f,0xf0,0xcb,0x32,0x44,0xdc,0x84,0x3f,0x25,0x4c,0xf2,0x43,0x30,0x00 } },
+{  16, 0xd110, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe4,0x48,0xb0,0x10,0x22,0xdc } },
+{  16, 0xd120, 0, {0x08,0xb6,0x02,0xfd,0x92,0x88,0x85,0x23,0xf4,0x40,0xf1,0x02,0xed,0x00,0x88,0x2d } },
+{  16, 0xd130, 0, {0x0e,0x60,0x0b,0xbc,0x12,0x2c,0x10,0xa8,0x82,0x2e,0x00,0x0a,0xfc,0x22,0xa0,0x04 } },
+{  16, 0xd140, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc0,0x80,0xb3,0x22,0x28,0xc0 } },
+{  16, 0xd150, 0, {0x08,0x30,0x82,0xcc,0x01,0x88,0x00,0x2c,0xc0,0x4a,0x32,0x02,0xcc,0x00,0x01,0x01 } },
+{  16, 0xd160, 0, {0x28,0x00,0x4b,0xb0,0x02,0xa0,0x00,0x80,0x00,0x2c,0x09,0x08,0x34,0x02,0x62,0x01 } },
+{  16, 0xd170, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x04,0xb2,0x10,0x2a,0xc1 } },
+{  16, 0xd180, 0, {0x08,0xb0,0x02,0xec,0x10,0x89,0x80,0x22,0xc0,0x08,0xb0,0x02,0xec,0x08,0x88,0x00 } },
+{  16, 0xd190, 0, {0x2e,0x40,0x83,0xb0,0x02,0xa0,0x40,0xb9,0x80,0x2c,0x21,0x0a,0xb0,0x02,0xf0,0x04 } },
+{  16, 0xd1a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xfa,0x00,0xba,0xc0 } },
+{  16, 0xd1b0, 0, {0x2c,0xb0,0x43,0xec,0x00,0xc0,0x80,0x3e,0xc0,0x8e,0xb0,0x03,0x4c,0x0c,0xc8,0x10 } },
+{  16, 0xd1c0, 0, {0x3e,0x80,0x8f,0xb0,0x03,0x82,0x10,0xd8,0x82,0x3e,0x28,0x0c,0xb0,0x0b,0x50,0x04 } },
+{  16, 0xd1d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb6,0x80,0xfd,0x02,0x37,0xc1 } },
+{  16, 0xd1e0, 0, {0x0f,0xb0,0x03,0xfc,0x00,0xfd,0x00,0x3e,0xc0,0x0f,0xb0,0x53,0xfc,0x02,0xff,0x01 } },
+{  16, 0xd1f0, 0, {0x2f,0xa4,0x8b,0xf0,0x83,0x7c,0x00,0xad,0x02,0x2f,0x40,0x03,0x70,0x03,0xb8,0x00 } },
+{  16, 0xd200, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x04,0x32,0xc0 } },
+{  16, 0xd210, 0, {0x4c,0xb0,0x23,0x2c,0x00,0xf8,0x40,0x3e,0xc2,0x0c,0xb0,0x03,0x2c,0x00,0xfb,0x41 } },
+{  16, 0xd220, 0, {0x32,0xc2,0x0f,0xb0,0x43,0x2d,0x00,0xc8,0x50,0x3e,0x40,0x0c,0xb0,0x0b,0x10,0x04 } },
+{  16, 0xd230, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2f,0x90,0xb9,0x50,0x03,0xc0 } },
+{  16, 0xd240, 0, {0x18,0xf0,0x1a,0x3c,0x00,0xb9,0x32,0x2d,0xe0,0x38,0xf0,0x60,0x3c,0x04,0xf9,0x00 } },
+{  16, 0xd250, 0, {0x3e,0xf0,0x0b,0x7c,0x80,0x2c,0x00,0xd9,0xc0,0x2e,0x40,0x0d,0xf0,0x02,0x32,0x00 } },
+{  16, 0xd260, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4b,0x24,0xb2,0x10,0x02,0xc1 } },
+{  16, 0xd270, 0, {0x28,0x30,0x02,0x6c,0x04,0xb2,0xc1,0x2c,0xc0,0x08,0x30,0x00,0x0c,0x00,0xb2,0x00 } },
+{  16, 0xd280, 0, {0x28,0x24,0x03,0x3c,0x0a,0x00,0x00,0x82,0xc8,0x2c,0xa0,0x08,0x30,0x02,0x38,0x00 } },
+{  16, 0xd290, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x16,0x00,0xb4,0x80,0x21,0xe4 } },
+{  16, 0xd2a0, 0, {0x48,0x7b,0x02,0x5e,0x00,0xb6,0x80,0x6d,0xe2,0x48,0x79,0x22,0x1e,0x40,0xac,0x84 } },
+{  16, 0xd2b0, 0, {0x2d,0xe0,0x0b,0xfa,0x00,0x52,0x40,0x96,0x80,0x2d,0xe8,0x19,0x38,0x02,0x08,0x00 } },
+{  16, 0xd2c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x40,0xf3,0x10,0xb0,0xc4 } },
+{  16, 0xd2d0, 0, {0x08,0x3a,0x02,0x4c,0x90,0xf3,0x10,0x3c,0xcc,0x08,0x31,0x03,0x0c,0x49,0xb0,0x40 } },
+{  16, 0xd2e0, 0, {0x30,0x05,0x0f,0x30,0x07,0x21,0x40,0x43,0x01,0x3e,0xc2,0x1c,0x30,0x43,0x12,0x02 } },
+{  16, 0xd2f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x0d,0xbc,0x10,0xfc,0x10,0x3f,0xc5 } },
+{  16, 0xd300, 0, {0x0f,0xf1,0x01,0xbc,0x04,0xff,0x04,0x3f,0xc4,0x0f,0xb1,0x4b,0xfc,0x64,0xf7,0x00 } },
+{  16, 0xd310, 0, {0x37,0xc0,0x0f,0x72,0x53,0xac,0x44,0xff,0x01,0x3f,0xc9,0x0f,0xf4,0x03,0xd0,0x06 } },
+{  16, 0xd320, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x08,0xfa,0x00,0x3e,0xe0 } },
+{  16, 0xd330, 0, {0x0c,0xb0,0x03,0x2c,0x00,0xcb,0x02,0x3e,0xca,0x0f,0xb2,0x07,0x2e,0x00,0xdb,0x02 } },
+{  16, 0xd340, 0, {0x32,0x08,0x0f,0x31,0x03,0x2c,0x00,0xcb,0x04,0x3e,0x80,0x0c,0x35,0x03,0x2a,0x00 } },
+{  16, 0xd350, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x00,0xb5,0x00,0x2d,0xc8 } },
+{  16, 0xd360, 0, {0x08,0x70,0x0a,0x1c,0x22,0x87,0x00,0x2d,0xc9,0x0b,0xf2,0x82,0x9c,0x80,0xa6,0x00 } },
+{  16, 0xd370, 0, {0x09,0x8b,0x0b,0x70,0x0a,0x1c,0x02,0x85,0x00,0x2d,0x40,0x08,0x70,0x02,0x92,0x04 } },
+{  16, 0xd380, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0x80,0x2c,0xec } },
+{  16, 0xd390, 0, {0x08,0x7b,0x02,0x5e,0x40,0x85,0x89,0x2d,0xec,0x8b,0x7b,0x02,0x4e,0x84,0x8f,0x80 } },
+{  16, 0xd3a0, 0, {0x25,0x64,0x0b,0xfa,0x02,0x12,0x08,0x97,0x80,0x6f,0xe1,0x08,0x7a,0x02,0x30,0x00 } },
+{  16, 0xd3b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x20,0xb3,0x64,0x2c,0xc0 } },
+{  16, 0xd3c0, 0, {0x08,0x30,0x06,0x0c,0x10,0x83,0x8a,0x6c,0xc0,0x5b,0x30,0x42,0xcc,0x00,0xab,0x10 } },
+{  16, 0xd3d0, 0, {0x2c,0xf2,0x0b,0x30,0x02,0x0d,0x00,0x93,0x04,0x2c,0xd5,0x08,0x30,0x0a,0x92,0x04 } },
+{  16, 0xd3e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xbb,0x00,0xfe,0xc0,0x3e,0x80 } },
+{  16, 0xd3f0, 0, {0x2c,0xa0,0x03,0x68,0x00,0xc6,0x40,0x3f,0x80,0x0f,0xa0,0x02,0x68,0x00,0xce,0x44 } },
+{  16, 0xd400, 0, {0x36,0x90,0x4f,0x60,0x03,0x1b,0x70,0xde,0xd8,0x3f,0xa0,0x0c,0x20,0x03,0x3a,0x04 } },
+{  16, 0xd410, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x40,0xf8,0x10,0x3e,0x00 } },
+{  16, 0xd420, 0, {0x0f,0x80,0x03,0xa0,0x10,0xf8,0x42,0x3e,0x10,0x1f,0x80,0x03,0xa0,0x00,0xe8,0x0c } },
+{  16, 0xd430, 0, {0x3a,0x04,0x1f,0x80,0x03,0xe0,0x00,0xe8,0x45,0x7e,0x02,0x2f,0x80,0x03,0xd2,0x00 } },
+{  16, 0xd440, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x64,0x00,0xe9,0x80,0x32,0x40 } },
+{  16, 0xd450, 0, {0x0f,0x90,0x0b,0x04,0x08,0xd9,0x80,0x36,0x40,0x0f,0x10,0x13,0x24,0x08,0xf9,0x00 } },
+{  16, 0xd460, 0, {0x72,0x70,0x0f,0x91,0x13,0x24,0x10,0xc9,0x10,0x3e,0x69,0x0c,0x90,0x03,0x02,0x04 } },
+{  16, 0xd470, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x08,0xb9,0x80,0x22,0x40 } },
+{  16, 0xd480, 0, {0x0b,0x10,0x02,0x24,0x00,0x89,0xc4,0x22,0x52,0x0b,0x90,0x42,0x24,0x00,0xb9,0x00 } },
+{  16, 0xd490, 0, {0x22,0xe0,0x0b,0x90,0x12,0x24,0x04,0xd9,0x4a,0x2e,0x60,0x08,0x90,0x03,0x60,0x00 } },
+{  16, 0xd4a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb1,0x18,0x22,0x40 } },
+{  16, 0xd4b0, 0, {0x0b,0x90,0x02,0x24,0x00,0x8b,0x20,0x26,0x49,0x0b,0x90,0x02,0x64,0x00,0xb9,0x00 } },
+{  16, 0xd4c0, 0, {0xa2,0x40,0x0b,0x90,0x8a,0x24,0x00,0x8b,0x00,0x2c,0x40,0xa8,0x90,0x02,0x06,0x00 } },
+{  16, 0xd4d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x84,0xb1,0x20,0xa0,0x48 } },
+{  16, 0xd4e0, 0, {0x0b,0x11,0x06,0x04,0x00,0x83,0x00,0x00,0x40,0x4b,0x11,0x02,0x04,0x49,0xb1,0x10 } },
+{  16, 0xd4f0, 0, {0x28,0x40,0x0b,0x10,0x02,0x24,0x41,0x91,0x00,0x2c,0x50,0x08,0x10,0x02,0x42,0x01 } },
+{  16, 0xd500, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x69,0x40,0xe8,0x50,0x32,0x14 } },
+{  16, 0xd510, 0, {0x0f,0x86,0x93,0x21,0xe2,0xc8,0x00,0x36,0x0a,0x0b,0x86,0x8b,0x61,0xa8,0xf8,0x40 } },
+{  16, 0xd520, 0, {0x22,0x80,0x0f,0x82,0xa3,0x21,0x08,0xc8,0x02,0x3e,0x00,0x0c,0x80,0x43,0x2e,0x03 } },
+{  16, 0xd530, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x48,0xfd,0x12,0x3e,0x44 } },
+{  16, 0xd540, 0, {0x0f,0x12,0x03,0xc4,0x00,0x7d,0x01,0x1e,0x40,0x0b,0x92,0x03,0xe4,0x80,0xf5,0x20 } },
+{  16, 0xd550, 0, {0x36,0x40,0x0f,0x90,0x03,0xd4,0x90,0x7d,0x00,0x3d,0x40,0x0f,0x94,0x03,0xe6,0x06 } },
+{  16, 0xd560, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xf6,0xc1,0xdd,0x88,0x32,0x72 } },
+{  16, 0xd570, 0, {0x0c,0x98,0x03,0x26,0x22,0xdd,0x00,0x3f,0x62,0x2c,0x99,0x83,0x46,0xa0,0xc9,0x40 } },
+{  16, 0xd580, 0, {0xb2,0x40,0x0f,0xd8,0x03,0x24,0x00,0xfd,0x00,0x33,0x51,0x2c,0xd8,0x83,0x06,0x00 } },
+{  16, 0xd590, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe3,0xc2,0x88,0xc0,0x22,0x30 } },
+{  16, 0xd5a0, 0, {0x08,0x8c,0x42,0x22,0x11,0x8a,0x01,0x2e,0x00,0x08,0x88,0x52,0x23,0x00,0x80,0xa3 } },
+{  16, 0xd5b0, 0, {0x2a,0x00,0x4b,0x80,0x42,0x22,0xa0,0xb8,0x00,0x22,0x28,0x08,0x84,0x02,0x8e,0x04 } },
+{  16, 0xd5c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0x81,0x2d,0x20,0x48 } },
+{  16, 0xd5d0, 0, {0x68,0x14,0x80,0x04,0x20,0x81,0x00,0x2e,0x40,0x0b,0x12,0x12,0x04,0x24,0x81,0x20 } },
+{  16, 0xd5e0, 0, {0x20,0x40,0x0b,0x94,0x32,0x04,0x90,0xb9,0x00,0x20,0x40,0x48,0x10,0x4a,0x02,0x01 } },
+{  16, 0xd5f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x00,0x89,0x20,0x22,0x40 } },
+{  16, 0xd600, 0, {0x08,0x90,0x12,0x24,0x00,0x89,0x00,0x2e,0x40,0x08,0x90,0x02,0x24,0x08,0x89,0x40 } },
+{  16, 0xd610, 0, {0x22,0x50,0x0b,0xb0,0x02,0x24,0x20,0xb9,0x09,0xa2,0x44,0x08,0x90,0x02,0x86,0x04 } },
+{  16, 0xd620, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xd9,0x08,0xb2,0x40 } },
+{  16, 0xd630, 0, {0x4c,0x10,0x23,0x04,0x04,0xd9,0xc1,0x3e,0x40,0x8f,0x90,0x0b,0x04,0x08,0xc1,0x40 } },
+{  16, 0xd640, 0, {0x12,0x40,0x0f,0x90,0x43,0x24,0x04,0xf1,0x41,0x30,0x78,0x0c,0x90,0x03,0x28,0x04 } },
+{  16, 0xd650, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x86,0x64,0xf9,0x80,0x3e,0x40 } },
+{  16, 0xd660, 0, {0x0f,0x90,0x0b,0xe4,0x00,0xf9,0x98,0x3e,0x40,0x2f,0x10,0x03,0xa4,0x02,0xf9,0x10 } },
+{  16, 0xd670, 0, {0x3e,0x40,0x0f,0x90,0x0b,0xe6,0x40,0xf9,0x90,0x3e,0x60,0x0f,0x90,0x03,0xca,0x00 } },
+{  16, 0xd680, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x41,0x32,0x00 } },
+{  16, 0xd690, 0, {0x0c,0x80,0x07,0x20,0x10,0xc8,0x10,0x3e,0x0c,0x0e,0x80,0x03,0xe0,0x04,0xc8,0x00 } },
+{  16, 0xd6a0, 0, {0xba,0x00,0x0f,0x81,0x43,0x20,0x00,0xf8,0x70,0x3e,0x00,0x0f,0x00,0x0b,0x0a,0x04 } },
+{  16, 0xd6b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x39,0x02,0x8e,0x20,0xa3,0x80 } },
+{  16, 0xd6c0, 0, {0x28,0xe0,0x0a,0x38,0x10,0xae,0x04,0x3d,0xa1,0x8e,0xe0,0x02,0xf8,0x00,0x8e,0x00 } },
+{  16, 0xd6d0, 0, {0x76,0x80,0x0b,0x60,0x03,0x78,0x00,0xbe,0x40,0x2f,0x82,0x0b,0xa0,0x03,0xca,0x00 } },
+{  16, 0xd6e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4d,0x00,0x8b,0x88,0x22,0xc0 } },
+{  16, 0xd6f0, 0, {0x18,0x30,0x02,0x0c,0x00,0x83,0x44,0x2c,0xd0,0x1b,0x30,0x12,0xcc,0x06,0x83,0x00 } },
+{  16, 0xd700, 0, {0x20,0xc1,0x0b,0x30,0x82,0x0c,0x01,0xb3,0x00,0x2c,0x40,0x0b,0x30,0x02,0x0a,0x00 } },
+{  16, 0xd710, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x00,0x85,0x00,0x20,0xcc } },
+{  16, 0xd720, 0, {0x08,0x70,0x06,0x1c,0x84,0xa7,0x01,0x29,0xc0,0x0b,0x72,0x22,0xdc,0x80,0x87,0x34 } },
+{  16, 0xd730, 0, {0x61,0x80,0x0b,0x10,0x02,0x5c,0x00,0xb7,0x00,0x2d,0xc0,0x0b,0x70,0x02,0xe8,0x00 } },
+{  16, 0xd740, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x0e,0x00,0x8c,0x80,0x31,0xe0 } },
+{  16, 0xd750, 0, {0x0c,0xfe,0x02,0x3f,0x00,0xc5,0x80,0x2d,0xe0,0x0e,0x78,0x03,0xdf,0xa0,0xc7,0xa0 } },
+{  16, 0xd760, 0, {0x21,0x60,0x0f,0x78,0x03,0x1e,0x80,0xf7,0x80,0x3d,0xe0,0x0f,0x78,0x03,0x2a,0x02 } },
+{  16, 0xd770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xf9,0x00,0x3e,0xc0 } },
+{  16, 0xd780, 0, {0x0f,0xb0,0x03,0xec,0x00,0xfa,0x00,0x3e,0xc0,0x06,0xb0,0x03,0xec,0x80,0xfb,0x28 } },
+{  16, 0xd790, 0, {0x36,0xd8,0x4f,0xa0,0x03,0xec,0x10,0xfa,0x00,0x3e,0x50,0x0f,0x30,0x03,0xc2,0x06 } },
+{  16, 0xd7a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfa,0x00,0xcc,0x80,0xb3,0xe0 } },
+{  16, 0xd7b0, 0, {0x0f,0xf8,0x03,0x3e,0x00,0xcf,0x90,0x3f,0x60,0x4f,0xf8,0xc3,0x3e,0x00,0xef,0x80 } },
+{  16, 0xd7c0, 0, {0x33,0xf0,0x0c,0x7a,0x03,0x3e,0x70,0xc5,0x90,0x33,0xf1,0x0c,0x78,0x03,0x00,0x00 } },
+{  16, 0xd7d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xb8,0x00,0x87,0x00,0x21,0xc0 } },
+{  16, 0xd7e0, 0, {0x0b,0x70,0x4a,0x1c,0x00,0x87,0x10,0x2d,0xc0,0x4b,0x71,0x0a,0x3c,0x44,0x8f,0x12 } },
+{  16, 0xd7f0, 0, {0x21,0x86,0x0d,0x72,0x02,0x1e,0x00,0x87,0x00,0x23,0x40,0x08,0x70,0x0a,0x2a,0x04 } },
+{  16, 0xd800, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x84,0x00,0x25,0xc0 } },
+{  16, 0xd810, 0, {0x0b,0x71,0x0a,0x0c,0x00,0xa7,0x12,0x2d,0x84,0x0b,0x70,0x0a,0x1c,0x00,0xb7,0x08 } },
+{  16, 0xd820, 0, {0x23,0x40,0x09,0xf3,0x1a,0x5c,0x86,0x97,0x08,0x25,0x40,0x08,0x70,0x02,0x00,0x00 } },
+{  16, 0xd830, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x20,0x81,0x20,0x26,0xc0 } },
+{  16, 0xd840, 0, {0x0b,0x30,0x02,0x2c,0x00,0x82,0x42,0x2c,0x80,0x0b,0x30,0x22,0x0c,0x08,0x9b,0x80 } },
+{  16, 0xd850, 0, {0x20,0xe0,0x09,0x20,0x02,0x4d,0x08,0x92,0x00,0x24,0xe5,0x08,0x30,0x0a,0x08,0x04 } },
+{  16, 0xd860, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xae,0x82,0xca,0xe0,0xb7,0xc0 } },
+{  16, 0xd870, 0, {0x0f,0xf0,0x13,0x3c,0x0a,0xc9,0xc8,0x3e,0x40,0x0f,0xf0,0x03,0x3c,0x04,0xff,0x84 } },
+{  16, 0xd880, 0, {0x32,0xc0,0x0d,0x90,0x13,0x7c,0x00,0xd9,0x00,0xf6,0xc0,0x2c,0x10,0x03,0x2a,0x04 } },
+{  16, 0xd890, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe4,0x00,0xf3,0x00,0x3a,0xc1 } },
+{  16, 0xd8a0, 0, {0x4f,0xb0,0x03,0xec,0x00,0xf9,0x08,0x3c,0x00,0x0f,0x30,0x13,0xec,0x00,0xeb,0x04 } },
+{  16, 0xd8b0, 0, {0xbe,0x18,0x0f,0x90,0x23,0xac,0x60,0xe9,0x02,0x3a,0x40,0x4f,0x90,0x03,0xe0,0x00 } },
+{  16, 0xd8c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xca,0x00,0x33,0xc0 } },
+{  16, 0xd8d0, 0, {0x0c,0xf0,0x03,0xfc,0x00,0xcd,0x02,0x7f,0x40,0x0c,0xf0,0x42,0x3c,0x00,0xcf,0x08 } },
+{  16, 0xd8e0, 0, {0x37,0x10,0x0f,0xd0,0x03,0xfc,0x10,0xcd,0x08,0x3f,0x66,0x2c,0xd9,0x03,0x00,0x44 } },
+{  16, 0xd8f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x63,0x80,0x8b,0xe0,0x22,0xc0 } },
+{  16, 0xd900, 0, {0x08,0xb0,0x22,0xec,0x00,0xd8,0x80,0x6e,0x20,0x68,0xb0,0x1a,0x2c,0x01,0xfb,0x00 } },
+{  16, 0xd910, 0, {0x22,0x18,0x0b,0x88,0x43,0x4c,0x00,0x88,0xa0,0x2c,0xc0,0x1d,0x90,0x02,0x20,0x40 } },
+{  16, 0xd920, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x08,0x80,0x8b,0x20,0x22,0xc0 } },
+{  16, 0xd930, 0, {0x08,0xb0,0x22,0xec,0x00,0x88,0x88,0x2e,0x62,0x48,0xb0,0x1a,0xcc,0x00,0x8b,0x00 } },
+{  16, 0xd940, 0, {0x26,0xc0,0x4a,0x88,0x02,0xec,0x00,0x08,0x84,0x2e,0x40,0x09,0x90,0x02,0x20,0x00 } },
+{  16, 0xd950, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x83,0x00,0x60,0xc0 } },
+{  16, 0xd960, 0, {0x08,0x30,0x02,0xcc,0x00,0x90,0x06,0x6c,0x00,0x08,0x30,0x02,0x8c,0x00,0xa3,0x04 } },
+{  16, 0xd970, 0, {0x20,0x00,0x8b,0x00,0x06,0x4c,0x21,0x80,0x00,0x6c,0xc0,0x49,0x10,0x0a,0x02,0x01 } },
+{  16, 0xd980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xca,0x00,0xb2,0xc1 } },
+{  16, 0xd990, 0, {0x88,0xb4,0x03,0xec,0x10,0xc8,0x00,0x2e,0x00,0x0c,0xb0,0x0b,0xbc,0x08,0x8f,0x00 } },
+{  16, 0xd9a0, 0, {0x36,0x00,0x06,0x80,0x03,0xec,0x80,0xc8,0x02,0x3f,0xc1,0x0c,0x90,0x03,0x00,0x03 } },
+{  16, 0xd9b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf0,0x00,0xff,0x00,0x3f,0xc0 } },
+{  16, 0xd9c0, 0, {0x0f,0x72,0x83,0xfc,0x18,0xfc,0x03,0x3f,0x00,0x8f,0x70,0x03,0x7c,0x00,0xff,0x00 } },
+{  16, 0xd9d0, 0, {0x3d,0x00,0x0f,0xc0,0x23,0x8c,0x06,0xfc,0x00,0x3f,0x40,0x0e,0xd0,0x03,0xe8,0x06 } },
+{  16, 0xd9e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x41,0x03,0x70,0x40,0xdc,0x10 } },
+{  16, 0xd9f0, 0, {0x37,0x04,0x0d,0xc1,0x03,0x70,0x40,0xdc,0x10,0x37,0x04,0x0d,0xc1,0x01,0x70,0x40 } },
+{  16, 0xda00, 0, {0x9c,0x10,0x17,0x14,0x05,0xc1,0x03,0x70,0x40,0xdc,0x10,0x17,0x04,0x0d,0xc0,0x31 } },
+{  16, 0xda10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x44,0x05,0x71,0x01,0x5c,0x40 } },
+{  16, 0xda20, 0, {0x57,0x10,0x15,0xc4,0x05,0x21,0x01,0x5c,0x40,0x57,0x10,0x15,0xc4,0x01,0x71,0x01 } },
+{  16, 0xda30, 0, {0x5c,0x40,0x17,0x10,0x05,0xc4,0x05,0x71,0x05,0x5c,0x41,0x57,0x10,0x15,0xc0,0x11 } },
+{  16, 0xda40, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x01,0x20,0x80,0x48,0x20 } },
+{  16, 0xda50, 0, {0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 } },
+{  16, 0xda60, 0, {0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x20 } },
+{  16, 0xda70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x60,0x00,0x58,0x00 } },
+{  16, 0xda80, 0, {0x16,0x00,0x05,0x80,0x01,0x60,0x00,0x58,0x00,0x16,0x00,0x05,0x80,0x05,0x60,0x00 } },
+{  16, 0xda90, 0, {0x58,0x00,0x16,0x18,0x01,0x80,0x01,0x60,0x00,0x58,0x00,0x56,0x00,0x05,0x80,0x20 } },
+{  16, 0xdaa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x48,0x05,0x22,0x01,0x1c,0x80 } },
+{  16, 0xdab0, 0, {0x47,0x20,0x11,0xc8,0x04,0x72,0x01,0x5c,0x80,0x57,0x20,0x11,0xc8,0x04,0x72,0x41 } },
+{  16, 0xdac0, 0, {0x5c,0x80,0x57,0x20,0x11,0xc8,0x04,0x72,0x01,0x1c,0x80,0x47,0x20,0x15,0xc0,0x31 } },
+{  16, 0xdad0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x00,0x60,0x00,0x18,0x00 } },
+{  16, 0xdae0, 0, {0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00 } },
+{  16, 0xdaf0, 0, {0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x31 } },
+{  16, 0xdb00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x48,0x04,0x22,0x01,0x08,0x80 } },
+{  16, 0xdb10, 0, {0x42,0x20,0x10,0x88,0x04,0x22,0x01,0x08,0x80,0x42,0x20,0x10,0x80,0x04,0x23,0x01 } },
+{  16, 0xdb20, 0, {0x08,0x80,0x42,0x20,0x10,0x88,0x04,0x22,0x01,0x08,0x00,0x42,0x20,0x10,0x80,0x21 } },
+{  16, 0xdb30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x4a,0x05,0x42,0x81,0x50,0xa0 } },
+{  16, 0xdb40, 0, {0x44,0x2c,0x11,0x0b,0x04,0x42,0x81,0x10,0xe0,0x54,0x28,0x11,0x02,0x00,0x42,0x81 } },
+{  16, 0xdb50, 0, {0x10,0xa0,0x44,0x38,0x11,0x0b,0x05,0x42,0x81,0x10,0x21,0x14,0x28,0x15,0x00,0x31 } },
+{  16, 0xdb60, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0c,0x01,0x57,0x00,0x54,0xc0 } },
+{  16, 0xdb70, 0, {0x15,0x30,0x04,0x4c,0x01,0x13,0x00,0x54,0xc0,0x15,0x70,0x05,0x4c,0x01,0x53,0x00 } },
+{  16, 0xdb80, 0, {0x54,0xc0,0x15,0x30,0x85,0x4c,0x01,0x13,0x00,0x54,0xc0,0x15,0x30,0x05,0x40,0x21 } },
+{  16, 0xdb90, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x40,0x00,0x10,0x00 } },
+{  16, 0xdba0, 0, {0x04,0x00,0x00,0x40,0x00,0x10,0x00,0x10,0x62,0x04,0x00,0x01,0x08,0x04,0x41,0x00 } },
+{  16, 0xdbb0, 0, {0x10,0x00,0x44,0x18,0x11,0x00,0x00,0x10,0x00,0x10,0x80,0x04,0x00,0x01,0x01,0x20 } },
+{  16, 0xdbc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x60,0x02,0x08,0x00,0x82,0x00 } },
+{  16, 0xdbd0, 0, {0x20,0x80,0x08,0x60,0x02,0x18,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x00,0x08,0x20 } },
+{  16, 0xdbe0, 0, {0x82,0x00,0x00,0x80,0x80,0x20,0x02,0x18,0x00,0x82,0x00,0x20,0x80,0x08,0x01,0x31 } },
+{  16, 0xdbf0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x05,0x64,0x01,0x58,0x00 } },
+{  16, 0xdc00, 0, {0x56,0x00,0x15,0x80,0x05,0x60,0x01,0x58,0x00,0x56,0x40,0x15,0x80,0x05,0x60,0x01 } },
+{  16, 0xdc10, 0, {0x58,0x00,0x56,0x00,0x15,0x80,0x05,0x60,0x01,0x58,0x00,0x76,0x00,0x15,0x80,0x31 } },
+{  16, 0xdc20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x03,0x60,0x00,0xd8,0x00 } },
+{  16, 0xdc30, 0, {0x36,0x00,0x0d,0x80,0x03,0x60,0x00,0x98,0x00,0x36,0x00,0x1d,0x88,0x05,0x60,0x00 } },
+{  16, 0xdc40, 0, {0xd8,0x00,0x16,0x00,0x0d,0x80,0x03,0x60,0x00,0xd8,0x80,0x46,0x00,0x0d,0x80,0x31 } },
+{  16, 0xdc50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x04,0x30,0x81,0x0c,0x20 } },
+{  16, 0xdc60, 0, {0x43,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x22,0x41,0x08,0x18,0xc2,0x04,0x30,0x89 } },
+{  16, 0xdc70, 0, {0x0c,0x20,0x03,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x10,0xc0,0x10 } },
+{  16, 0xdc80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x30,0x00,0x0c,0x00 } },
+{  16, 0xdc90, 0, {0x03,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x30,0x00 } },
+{  16, 0xdca0, 0, {0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x01 } },
+{  16, 0xdcb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x01,0x30,0x80,0x4c,0x20 } },
+{  16, 0xdcc0, 0, {0x13,0x08,0x04,0xc2,0x01,0x30,0x80,0x4c,0x20,0x13,0x08,0x04,0xc3,0x01,0x30,0x80 } },
+{  16, 0xdcd0, 0, {0x4c,0x20,0x13,0x08,0x04,0xc2,0x01,0x30,0x80,0x4c,0x30,0x13,0x08,0x04,0xc0,0x21 } },
+{  16, 0xdce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x05,0x60,0x81,0x58,0x20 } },
+{  16, 0xdcf0, 0, {0x56,0x08,0x11,0x82,0x05,0x60,0x81,0x58,0x20,0x56,0x08,0x11,0x83,0x00,0x60,0x81 } },
+{  16, 0xdd00, 0, {0x58,0x20,0x46,0x08,0x11,0x82,0x04,0x60,0x81,0x18,0x30,0x56,0x08,0x15,0x80,0x30 } },
+{  16, 0xdd10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x00,0x20,0x80,0x08,0x20 } },
+{  16, 0xdd20, 0, {0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x30,0x80 } },
+{  16, 0xdd30, 0, {0x08,0x20,0x02,0x00,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x03,0x08,0x00,0x80,0x31 } },
+{  16, 0xdd40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x04,0x60,0x81,0x18,0x20 } },
+{  16, 0xdd50, 0, {0x46,0x48,0x11,0x92,0x04,0x60,0x81,0x19,0x20,0x46,0x28,0x11,0x82,0x00,0x34,0x81 } },
+{  16, 0xdd60, 0, {0x18,0x20,0x46,0x48,0x11,0x92,0x04,0x60,0x81,0x18,0x20,0x43,0x08,0x11,0x80,0x11 } },
+{  16, 0xdd70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x60,0x04,0x58,0x01,0x56,0x00 } },
+{  16, 0xdd80, 0, {0x55,0x80,0x15,0x60,0x04,0x58,0x01,0x16,0x00,0x55,0x80,0x01,0x60,0x04,0x18,0x01 } },
+{  16, 0xdd90, 0, {0x56,0x00,0x45,0x80,0x11,0x60,0x04,0x58,0x01,0x16,0x00,0x41,0x80,0x11,0x40,0x31 } },
+{  16, 0xdda0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x06,0x01,0x41,0x80,0x50,0x60 } },
+{  16, 0xddb0, 0, {0x14,0x18,0x05,0x06,0x01,0x41,0x80,0x50,0x60,0x04,0x18,0x05,0x06,0x00,0x41,0x80 } },
+{  16, 0xddc0, 0, {0x10,0x60,0x14,0x18,0x05,0x06,0x01,0x41,0x80,0x50,0x60,0x14,0x18,0x05,0x00,0x20 } },
+{  16, 0xddd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x80,0x40,0x20 } },
+{  16, 0xdde0, 0, {0x10,0x48,0x04,0x12,0x01,0x00,0x80,0x41,0x20,0x10,0x08,0x04,0x02,0x01,0x04,0x80 } },
+{  16, 0xddf0, 0, {0x40,0x20,0x50,0x48,0x04,0x12,0x01,0x00,0x84,0x40,0x20,0x10,0x08,0x04,0x00,0x20 } },
+{  16, 0xde00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x46,0x03,0x51,0x80,0xd4,0x60 } },
+{  16, 0xde10, 0, {0x30,0x18,0x0d,0x46,0x03,0x51,0x80,0xd5,0x60,0x35,0x18,0x0d,0x46,0x03,0x05,0x80 } },
+{  16, 0xde20, 0, {0xd4,0x60,0x15,0x18,0x0d,0x46,0x03,0x11,0x80,0xd4,0x60,0x35,0x18,0x0d,0x40,0x31 } },
+{  16, 0xde30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x46,0x05,0x71,0x80,0x5c,0x60 } },
+{  16, 0xde40, 0, {0x97,0x18,0x15,0xc6,0x05,0x71,0x81,0x5c,0x20,0x57,0x18,0x15,0xc6,0x03,0x70,0x81 } },
+{  16, 0xde50, 0, {0x5c,0x60,0x57,0x18,0x11,0xc6,0x05,0x31,0x81,0x5c,0x60,0x77,0x18,0x15,0xc0,0x31 } },
+{  16, 0xde60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x46,0x03,0x71,0x80,0xdc,0x60 } },
+{  16, 0xde70, 0, {0x37,0x18,0x0d,0xc6,0x03,0x71,0x80,0xdd,0x60,0x37,0x18,0x05,0xc6,0x01,0x75,0x81 } },
+{  16, 0xde80, 0, {0xdc,0x60,0x37,0x18,0x0d,0xc6,0x03,0x71,0x84,0x5c,0x60,0x17,0x18,0x19,0xc0,0x11 } },
+{  16, 0xde90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x46,0x05,0x71,0x81,0x5c,0x60 } },
+{  16, 0xdea0, 0, {0x57,0x18,0x14,0x86,0x05,0x71,0x81,0x5c,0x60,0x57,0x18,0x05,0xc6,0x04,0x31,0x81 } },
+{  16, 0xdeb0, 0, {0x5c,0x60,0x57,0x18,0x15,0xc6,0x05,0x71,0x80,0x5c,0x60,0x43,0x18,0x15,0xc0,0x11 } },
+{  16, 0xdec0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x20,0x80,0x48,0x20 } },
+{  16, 0xded0, 0, {0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x70,0x80 } },
+{  16, 0xdee0, 0, {0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x17,0x08,0x04,0x80,0x00 } },
+{  16, 0xdef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x01,0x61,0x80,0x58,0x60 } },
+{  16, 0xdf00, 0, {0x16,0x18,0x41,0x86,0x01,0x61,0x80,0x18,0x60,0x06,0x3c,0x05,0x86,0x04,0x61,0x80 } },
+{  16, 0xdf10, 0, {0x18,0x60,0x16,0x18,0x01,0x86,0x00,0x61,0x80,0x58,0x60,0x56,0x18,0x15,0x80,0x10 } },
+{  16, 0xdf20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x40,0x05,0x70,0x01,0x5c,0x00 } },
+{  16, 0xdf30, 0, {0x57,0x00,0x15,0xc0,0x04,0x70,0x01,0x5c,0x00,0x57,0x00,0x10,0xc0,0x04,0x70,0x00 } },
+{  16, 0xdf40, 0, {0x1c,0x00,0x47,0x00,0x11,0xc0,0x04,0x70,0x01,0x5c,0x00,0x47,0x00,0x01,0xc0,0x11 } },
+{  16, 0xdf50, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x42,0x00,0x60,0x80,0x18,0x20 } },
+{  16, 0xdf60, 0, {0x06,0x08,0x01,0x82,0x00,0x60,0x80,0x18,0x20,0x06,0x08,0x00,0x82,0x00,0x60,0x80 } },
+{  16, 0xdf70, 0, {0x18,0x20,0x06,0x08,0x01,0x82,0x00,0x60,0x80,0x18,0x20,0x06,0x08,0x01,0x80,0x11 } },
+{  16, 0xdf80, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x42,0x04,0x20,0x81,0x08,0x20 } },
+{  16, 0xdf90, 0, {0x42,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x11,0x82,0x04,0x20,0x80 } },
+{  16, 0xdfa0, 0, {0x08,0x20,0x42,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x00,0x80,0x11 } },
+{  16, 0xdfb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x42,0x05,0x40,0x81,0x50,0x20 } },
+{  16, 0xdfc0, 0, {0x54,0x08,0x15,0x02,0x05,0x40,0x81,0x10,0x20,0x54,0x0c,0x15,0x42,0x00,0x40,0x81 } },
+{  16, 0xdfd0, 0, {0x50,0x20,0x44,0x08,0x11,0x02,0x05,0x40,0x81,0x10,0x20,0x14,0x08,0x05,0x00,0x11 } },
+{  16, 0xdfe0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x01,0x50,0xc0,0x54,0x30 } },
+{  16, 0xdff0, 0, {0x15,0x08,0x05,0x42,0x01,0x50,0xc0,0x54,0x30,0x15,0x0c,0x05,0x43,0x01,0x50,0xc0 } },
+{  16, 0xe000, 0, {0x54,0x30,0x15,0x0c,0x05,0x42,0x01,0x50,0xc0,0x54,0x30,0x15,0x0c,0x05,0x40,0x10 } },
+{  16, 0xe010, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x42,0x00,0x10,0x80 } },
+{  16, 0xe020, 0, {0x04,0x20,0x01,0x88,0x00,0x62,0x00,0x10,0x80,0x04,0x00,0x11,0x08,0x00,0x42,0x00 } },
+{  16, 0xe030, 0, {0x10,0x80,0x04,0x20,0x01,0x08,0x00,0x42,0x01,0x10,0x80,0x04,0x20,0x01,0x00,0x00 } },
+{  16, 0xe040, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x42,0x02,0x00,0x80,0x80,0x20 } },
+{  16, 0xe050, 0, {0x20,0x08,0x08,0x02,0x02,0x20,0x80,0x80,0x20,0x20,0x28,0x00,0x02,0x02,0x00,0x80 } },
+{  16, 0xe060, 0, {0x80,0x20,0x20,0x0a,0x08,0x02,0x02,0x00,0x80,0x00,0x20,0x20,0x08,0x08,0x00,0x11 } },
+{  16, 0xe070, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x40,0x05,0x60,0x01,0x58,0x00 } },
+{  16, 0xe080, 0, {0x56,0x00,0x05,0x80,0x05,0x60,0x01,0x58,0x08,0x56,0x00,0x15,0x80,0x07,0x60,0x02 } },
+{  16, 0xe090, 0, {0x58,0x00,0x56,0x40,0x15,0x80,0x05,0x60,0x03,0x18,0x00,0x76,0x00,0x15,0x80,0x11 } },
+{  16, 0xe0a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x03,0x60,0x00,0xd8,0x00 } },
+{  16, 0xe0b0, 0, {0x36,0x00,0x0d,0x80,0x01,0x60,0x00,0xd8,0x0a,0x36,0x00,0x0d,0x80,0x05,0x70,0x09 } },
+{  16, 0xe0c0, 0, {0xd8,0x01,0x36,0x00,0x0d,0x80,0x03,0x60,0x00,0xd8,0x00,0x57,0x00,0x0d,0x80,0x00 } },
+{  16, 0xe0d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x30,0x01,0x0c,0x00 } },
+{  16, 0xe0e0, 0, {0x43,0x00,0x10,0xc0,0x00,0x30,0x01,0x0c,0x00,0x43,0x20,0x10,0xc0,0x04,0x60,0x01 } },
+{  16, 0xe0f0, 0, {0x0c,0x00,0x43,0x40,0x50,0xc1,0x04,0x30,0x01,0x0c,0x00,0x46,0x00,0x10,0xc0,0x00 } },
+{  16, 0xe100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0c,0x00 } },
+{  16, 0xe110, 0, {0x01,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xd0,0x00,0x20,0x00 } },
+{  16, 0xe120, 0, {0x0c,0x00,0x03,0x40,0x00,0xc0,0x00,0x30,0x00,0x0d,0x00,0x02,0x00,0x00,0xc0,0x00 } },
+{  16, 0xe130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,0x31,0x40,0x4c,0x50 } },
+{  16, 0xe140, 0, {0x13,0x10,0x04,0xc4,0x01,0x31,0x40,0x4c,0x50,0x13,0x14,0x04,0xc5,0x11,0x31,0x41 } },
+{  16, 0xe150, 0, {0x4c,0x50,0x13,0x14,0x04,0xc5,0x01,0x31,0x40,0x4c,0x50,0x13,0x14,0x04,0xc0,0x00 } },
+{  16, 0xe160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x05,0x68,0xc1,0x5a,0x30 } },
+{  16, 0xe170, 0, {0x56,0x8c,0x11,0xa3,0x04,0x68,0xc1,0x1a,0x30,0x56,0x8c,0x11,0xa3,0x05,0x68,0xc0 } },
+{  16, 0xe180, 0, {0x5a,0x30,0x46,0x8c,0x11,0xa3,0x04,0x68,0xc1,0x5a,0x30,0x16,0x8c,0x15,0x80,0x00 } },
+{  16, 0xe190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x00 } },
+{  16, 0xe1a0, 0, {0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x20,0x00,0x90,0x00,0x20,0x00 } },
+{  16, 0xe1b0, 0, {0x08,0x00,0x02,0x40,0x00,0x80,0x00,0x20,0x00,0x09,0x00,0x02,0x00,0x00,0x80,0x00 } },
+{  16, 0xe1c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x44,0x62,0x01,0x18,0x84 } },
+{  16, 0xe1d0, 0, {0x46,0x21,0x11,0x88,0x44,0x62,0x11,0x18,0x84,0x46,0x01,0x11,0x88,0x44,0x62,0x10 } },
+{  16, 0xe1e0, 0, {0x18,0x84,0x46,0x21,0x11,0x88,0x44,0x62,0x11,0x18,0x84,0x06,0x21,0x11,0x80,0x00 } },
+{  16, 0xe1f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x50,0x11,0x54,0x04 } },
+{  16, 0xe200, 0, {0x55,0x01,0x11,0x40,0x45,0x50,0x11,0x14,0x00,0x45,0x01,0x11,0x40,0x44,0x50,0x00 } },
+{  16, 0xe210, 0, {0x14,0x04,0x45,0x00,0x15,0x40,0x44,0x50,0x11,0x14,0x04,0x55,0x01,0x11,0x40,0x00 } },
+{  16, 0xe220, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x21,0x42,0x08,0x50,0x82 } },
+{  16, 0xe230, 0, {0x14,0x20,0x85,0x08,0x21,0x42,0x08,0x50,0x82,0x04,0x20,0x85,0x08,0x21,0x42,0x08 } },
+{  16, 0xe240, 0, {0x50,0x82,0x14,0x20,0x05,0x08,0x21,0x42,0x08,0x50,0x82,0x14,0x20,0x85,0x00,0x00 } },
+{  16, 0xe250, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0 } },
+{  16, 0xe260, 0, {0x10,0x28,0x04,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x40,0x0a,0x01,0x02,0x80 } },
+{  16, 0xe270, 0, {0x40,0xa0,0x10,0x28,0x44,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x00,0x00 } },
+{  16, 0xe280, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x03,0x53,0x00,0xd4,0xc0 } },
+{  16, 0xe290, 0, {0x35,0x30,0x0d,0x4c,0x01,0x53,0x00,0xd4,0xc0,0x35,0x10,0x0c,0x4c,0x03,0x53,0x00 } },
+{  16, 0xe2a0, 0, {0xd4,0xc0,0x35,0x30,0x0d,0x4c,0x03,0x53,0x00,0xd4,0xc0,0x35,0x30,0x0d,0x40,0x00 } },
+{  16, 0xe2b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x72,0x01,0x5c,0x80 } },
+{  16, 0xe2c0, 0, {0x17,0x20,0x05,0xc8,0x06,0x72,0x01,0x5c,0x80,0x57,0x20,0x15,0xc8,0x02,0x72,0x01 } },
+{  16, 0xe2d0, 0, {0x5c,0x80,0x57,0x20,0x15,0xc8,0x05,0x72,0x01,0x5c,0x80,0x37,0x20,0x11,0xc0,0x00 } },
+{  16, 0xe2e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x18,0x40,0xc6,0x12,0x31 } },
+{  16, 0xe2f0, 0, {0x84,0x8c,0x21,0x23,0x08,0x48,0xc6,0x12,0x30,0x84,0x0c,0x61,0x23,0x10,0x48,0xc2 } },
+{  16, 0xe300, 0, {0x12,0x31,0x84,0x8c,0x01,0x23,0x08,0x48,0xc6,0x12,0x31,0x04,0x8c,0x61,0x00,0x00 } },
+{  16, 0xe310, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x4f,0xff,0xd3,0xff } },
+{  16, 0xe320, 0, {0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff } },
+{  16, 0xe330, 0, {0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x00,0x00 } },
+{  16, 0xe340, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xe350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xe360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xe370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xdb,0x0f,0xb6,0xc2,0xcd } },
+{  16, 0xe380, 0, {0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2,0xdf,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x7e } },
+{  16, 0xe390, 0, {0xc2,0xcd,0xb0,0xb7,0xfd,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x00,0x00 } },
+{  16, 0xe3a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x3c,0x4f,0xcf,0x13,0x33 } },
+{  16, 0xe3b0, 0, {0xc4,0xcc,0xf1,0x33,0x3c,0x4c,0xcf,0x13,0x3f,0xc4,0xcc,0xf1,0x33,0x3c,0x4c,0xff } },
+{  16, 0xe3c0, 0, {0x13,0x33,0xc4,0xcf,0xfd,0x33,0x3c,0x4c,0xcf,0x13,0x33,0xc4,0xcc,0xf1,0x00,0x00 } },
+{  16, 0xe3d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0x7e,0x4e,0xdf,0x93,0xb7 } },
+{  16, 0xe3e0, 0, {0xe4,0xec,0x79,0x3b,0x1e,0x4e,0xdf,0x93,0xbf,0xe4,0x8d,0xf9,0x3b,0x78,0x4e,0xff } },
+{  16, 0xe3f0, 0, {0x93,0xb7,0xe4,0xed,0xfd,0x3b,0x1e,0x4e,0xdf,0x93,0xb7,0x84,0xed,0xf9,0x00,0x00 } },
+{  16, 0xe400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x70,0x40,0x9c,0x10 } },
+{  16, 0xe410, 0, {0x27,0x1c,0x09,0xc1,0x01,0x30,0x40,0x1c,0x10,0x67,0x04,0x09,0xc1,0x02,0x70,0x41 } },
+{  16, 0xe420, 0, {0x9c,0x11,0x07,0x14,0x01,0xc1,0x02,0x70,0x40,0x9c,0x50,0x07,0x1c,0x01,0xc0,0x00 } },
+{  16, 0xe430, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x05,0x71,0x01,0x5c,0x40 } },
+{  16, 0xe440, 0, {0x57,0x10,0x55,0xc4,0x01,0x31,0x00,0x5c,0x40,0x57,0x10,0x15,0xc4,0x05,0x71,0x01 } },
+{  16, 0xe450, 0, {0xdc,0x40,0x17,0x18,0x1d,0xc4,0x05,0x71,0x05,0x5c,0x40,0x57,0x10,0x1d,0xc0,0x00 } },
+{  16, 0xe460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x20,0x80,0x48,0x20 } },
+{  16, 0xe470, 0, {0x12,0x00,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 } },
+{  16, 0xe480, 0, {0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x60,0x12,0x08,0x04,0x80,0x00 } },
+{  16, 0xe490, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00 } },
+{  16, 0xe4a0, 0, {0x06,0x00,0x41,0x80,0x00,0x60,0x00,0x18,0x00,0x46,0x00,0x01,0x80,0x00,0x60,0x00 } },
+{  16, 0xe4b0, 0, {0x10,0x00,0x06,0x10,0x01,0x80,0x00,0x60,0x00,0x18,0x20,0x46,0x10,0x01,0x80,0x00 } },
+{  16, 0xe4c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x72,0x01,0x1c,0x80 } },
+{  16, 0xe4d0, 0, {0x47,0x20,0x11,0xc8,0x04,0x72,0x01,0x1c,0x80,0x07,0x20,0x11,0xc8,0x04,0x73,0x00 } },
+{  16, 0xe4e0, 0, {0x1c,0x80,0x47,0x20,0x11,0xcc,0x04,0x72,0x01,0x1c,0x80,0x47,0x20,0x11,0xc0,0x00 } },
+{  16, 0xe4f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00 } },
+{  16, 0xe500, 0, {0x06,0x00,0x01,0x84,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x40 } },
+{  16, 0xe510, 0, {0x18,0x00,0x06,0x04,0x01,0x81,0x00,0x60,0x00,0x18,0x00,0x06,0x14,0x01,0x80,0x00 } },
+{  16, 0xe520, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x22,0x01,0x08,0x80 } },
+{  16, 0xe530, 0, {0x42,0x70,0x10,0x8c,0x04,0x22,0x01,0x08,0xc0,0x02,0x20,0x10,0x88,0x04,0x22,0x00 } },
+{  16, 0xe540, 0, {0x08,0x80,0x42,0x50,0x10,0x08,0x04,0x22,0x01,0x09,0x00,0x42,0x40,0x10,0x80,0x00 } },
+{  16, 0xe550, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0x04,0x4a,0x81,0x12,0xa0 } },
+{  16, 0xe560, 0, {0x44,0xa8,0x11,0x2a,0x04,0x4a,0x81,0x12,0xa0,0x04,0xa8,0x11,0x2a,0x04,0x4b,0x80 } },
+{  16, 0xe570, 0, {0x12,0xa0,0x44,0x88,0x01,0x2e,0x04,0x4a,0x81,0x12,0x20,0x04,0x98,0x01,0x00,0x00 } },
+{  16, 0xe580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x0e,0x00,0x53,0x00,0x14,0xc0 } },
+{  16, 0xe590, 0, {0x05,0x30,0x01,0x4c,0x00,0x53,0x00,0x14,0xe0,0x05,0x30,0x01,0x4c,0x00,0x53,0x00 } },
+{  16, 0xe5a0, 0, {0x04,0xc0,0x05,0x30,0x00,0x4c,0x00,0x03,0x00,0x14,0xc0,0x05,0x30,0x00,0x40,0x10 } },
+{  16, 0xe5b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x04,0x00,0x40,0x00,0x10,0x00 } },
+{  16, 0xe5c0, 0, {0x04,0x58,0x01,0x04,0x00,0x40,0x00,0x10,0x00,0x04,0x00,0x01,0x00,0x00,0x41,0x00 } },
+{  16, 0xe5d0, 0, {0x04,0x00,0x44,0x58,0x10,0x44,0x00,0x00,0x00,0x11,0x80,0x04,0x50,0x10,0x40,0x30 } },
+{  16, 0xe5e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x40,0x02,0x00,0x00,0x80,0x00 } },
+{  16, 0xe5f0, 0, {0x20,0x00,0x08,0x00,0x40,0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00 } },
+{  16, 0xe600, 0, {0x84,0x00,0x00,0x00,0x08,0x40,0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x40,0x30 } },
+{  16, 0xe610, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x40,0x00,0x60,0x01,0x18,0x00 } },
+{  16, 0xe620, 0, {0x46,0x00,0x01,0x80,0x06,0x60,0x01,0x98,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01 } },
+{  16, 0xe630, 0, {0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x20,0x01,0x18,0x00,0x66,0x00,0x11,0x80,0x30 } },
+{  16, 0xe640, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x40,0x00,0x60,0x00,0x98,0x00 } },
+{  16, 0xe650, 0, {0x26,0x00,0x09,0x80,0x02,0x60,0x01,0x98,0x00,0x06,0x00,0x0c,0x80,0x02,0x60,0x00 } },
+{  16, 0xe660, 0, {0x18,0x00,0x06,0x00,0x01,0x80,0x02,0x60,0x00,0x98,0x80,0x06,0x00,0x01,0x82,0x00 } },
+{  16, 0xe670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x00,0x30,0x81,0x0c,0x20 } },
+{  16, 0xe680, 0, {0x43,0x08,0x10,0xc2,0x24,0x30,0x81,0x8c,0x20,0x03,0x08,0x10,0xc2,0x04,0x20,0x80 } },
+{  16, 0xe690, 0, {0x0c,0x20,0x03,0x08,0x18,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x18,0xc0,0x11 } },
+{  16, 0xe6a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x30,0x00,0x0c,0x00 } },
+{  16, 0xe6b0, 0, {0x03,0x00,0x00,0xc0,0x40,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0x80,0x00,0x30,0x00 } },
+{  16, 0xe6c0, 0, {0x0c,0x00,0x03,0x20,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x20,0x00,0xc0,0x00 } },
+{  16, 0xe6d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x02,0x10,0x30,0x80,0x0c,0x20 } },
+{  16, 0xe6e0, 0, {0x03,0x08,0x00,0xc2,0x00,0x30,0x80,0x0c,0x20,0x03,0x08,0x00,0xc2,0x01,0x20,0x80 } },
+{  16, 0xe6f0, 0, {0x0c,0x20,0x03,0x2c,0x00,0xc2,0x00,0x30,0x80,0x0c,0x30,0x43,0x2c,0x00,0xc0,0x00 } },
+{  16, 0xe700, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x04,0x60,0x81,0x18,0x20 } },
+{  16, 0xe710, 0, {0x46,0x08,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x46,0x08,0x11,0x82,0x04,0x60,0x81 } },
+{  16, 0xe720, 0, {0x18,0x20,0x46,0x0c,0x11,0xc2,0x04,0x60,0x81,0x18,0x30,0x46,0x0c,0x11,0xc0,0x11 } },
+{  16, 0xe730, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x42,0x00,0x20,0x80,0x08,0x20 } },
+{  16, 0xe740, 0, {0x02,0x28,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80 } },
+{  16, 0xe750, 0, {0x08,0x20,0x02,0x08,0x01,0x82,0x00,0x20,0x80,0x08,0x20,0x03,0x08,0x01,0x80,0x00 } },
+{  16, 0xe760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x01,0x42,0x04,0x60,0x81,0x18,0x20 } },
+{  16, 0xe770, 0, {0x46,0x28,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x46,0x08,0x11,0x82,0x04,0x60,0x81 } },
+{  16, 0xe780, 0, {0x18,0x20,0x46,0x08,0x10,0x82,0x04,0x60,0x81,0x18,0x20,0x43,0x08,0x10,0x80,0x00 } },
+{  16, 0xe790, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x40,0x04,0x50,0x01,0x14,0x00 } },
+{  16, 0xe7a0, 0, {0x45,0x00,0x11,0x40,0x25,0x00,0x00,0x14,0x00,0x45,0x00,0x11,0x40,0x04,0x50,0x01 } },
+{  16, 0xe7b0, 0, {0x14,0x00,0x45,0x00,0x00,0x40,0x04,0x50,0x01,0x40,0x00,0x01,0x00,0x00,0x42,0x11 } },
+{  16, 0xe7c0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x06,0x00,0x41,0x80,0x10,0x60 } },
+{  16, 0xe7d0, 0, {0x04,0x18,0x01,0x06,0x00,0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x06,0x00,0x41,0x80 } },
+{  16, 0xe7e0, 0, {0x10,0x60,0x04,0x18,0x01,0x06,0x00,0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x00,0x00 } },
+{  16, 0xe7f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x02,0x05,0x00,0x80,0x40,0x21 } },
+{  16, 0xe800, 0, {0x10,0x08,0x04,0x00,0x01,0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x80 } },
+{  16, 0xe810, 0, {0x40,0x20,0x50,0x08,0x14,0x02,0x11,0x00,0x84,0x40,0x20,0x10,0x08,0x14,0x00,0x00 } },
+{  16, 0xe820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x46,0x01,0x51,0x80,0xd4,0x60 } },
+{  16, 0xe830, 0, {0x35,0x18,0x0d,0x46,0x03,0x51,0x80,0xd4,0x60,0x15,0x18,0x0d,0x46,0x03,0x51,0x80 } },
+{  16, 0xe840, 0, {0x54,0x60,0x15,0x18,0x0d,0x46,0x03,0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x40,0x11 } },
+{  16, 0xe850, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x46,0x04,0x71,0x81,0x1c,0x60 } },
+{  16, 0xe860, 0, {0x45,0x18,0x11,0xd6,0x04,0x71,0x81,0x1c,0x60,0x67,0x18,0x11,0xc6,0x04,0x71,0x81 } },
+{  16, 0xe870, 0, {0x9c,0x60,0x47,0x18,0x11,0xc6,0x04,0x71,0x81,0x1c,0x60,0x67,0x18,0x11,0xc0,0x00 } },
+{  16, 0xe880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x46,0x02,0x71,0x80,0x9c,0x60 } },
+{  16, 0xe890, 0, {0x27,0x18,0x09,0xc6,0x00,0x71,0x80,0x9c,0x60,0x67,0x18,0x09,0xc6,0x02,0x71,0x80 } },
+{  16, 0xe8a0, 0, {0x9c,0x61,0x27,0x18,0x01,0xc6,0x02,0x71,0x80,0x9c,0x60,0x07,0x18,0x01,0xc0,0x00 } },
+{  16, 0xe8b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x45,0x46,0x05,0x71,0x81,0x5c,0x60 } },
+{  16, 0xe8c0, 0, {0x57,0x18,0x55,0xd6,0x01,0x71,0x81,0x5c,0x60,0x57,0x18,0x15,0xc6,0x05,0x71,0x81 } },
+{  16, 0xe8d0, 0, {0x5c,0x60,0x57,0x18,0x18,0xc6,0x05,0x71,0x81,0x5c,0x60,0x43,0x18,0x18,0x82,0x11 } },
+{  16, 0xe8e0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x52,0x01,0x20,0x80,0x48,0x20 } },
+{  16, 0xe8f0, 0, {0x12,0x48,0x04,0x90,0x01,0x20,0x80,0x49,0x20,0x12,0x08,0x04,0x82,0x01,0x24,0x80 } },
+{  16, 0xe900, 0, {0x48,0x20,0x12,0x48,0x00,0x92,0x01,0x20,0x80,0x48,0x20,0x17,0x48,0x04,0x80,0x01 } },
+{  16, 0xe910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x06,0x00,0x61,0x80,0x18,0x60 } },
+{  16, 0xe920, 0, {0x06,0x3c,0x01,0x86,0x00,0x61,0x80,0x18,0x60,0x46,0x18,0x01,0x86,0x00,0x61,0x80 } },
+{  16, 0xe930, 0, {0x18,0x60,0x06,0x18,0x01,0x86,0x00,0x61,0x80,0x18,0x60,0x46,0x18,0x01,0x80,0x01 } },
+{  16, 0xe940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x60,0x04,0x78,0x01,0x1e,0x00 } },
+{  16, 0xe950, 0, {0x47,0x80,0x11,0xe0,0x24,0x78,0x01,0x1e,0x00,0x07,0x80,0x11,0xe0,0x04,0x78,0x01 } },
+{  16, 0xe960, 0, {0x1e,0x00,0x47,0x80,0x11,0xe0,0x04,0x38,0x01,0x1e,0x00,0x47,0x80,0x11,0xc0,0x11 } },
+{  16, 0xe970, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x12,0x00,0x60,0x80,0x18,0x20 } },
+{  16, 0xe980, 0, {0x06,0x48,0x01,0x92,0x00,0x60,0x80,0x19,0x20,0x06,0x08,0x01,0x82,0x00,0x64,0x80 } },
+{  16, 0xe990, 0, {0x18,0x20,0x06,0x48,0x01,0x93,0x00,0x20,0x80,0x18,0x20,0x06,0x48,0x01,0x80,0x00 } },
+{  16, 0xe9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x42,0x04,0x20,0x81,0x08,0x20 } },
+{  16, 0xe9b0, 0, {0x42,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x02,0x08,0x10,0x82,0x04,0x20,0x81 } },
+{  16, 0xe9c0, 0, {0x08,0x20,0x42,0x08,0x10,0x8a,0x04,0x60,0x81,0x08,0x20,0x42,0x08,0x10,0x80,0x00 } },
+{  16, 0xe9d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x04,0x40,0x81,0x10,0x20 } },
+{  16, 0xe9e0, 0, {0x44,0x08,0x11,0x02,0x04,0x40,0x81,0x10,0x20,0x04,0x08,0x11,0x02,0x04,0x40,0x81 } },
+{  16, 0xe9f0, 0, {0x10,0x21,0x44,0x08,0x01,0x02,0x04,0x50,0x81,0x10,0x20,0x04,0x08,0x01,0x00,0x11 } },
+{  16, 0xea00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x03,0x00,0x50,0xc0,0x14,0x30 } },
+{  16, 0xea10, 0, {0x05,0x0c,0x01,0x43,0x00,0x50,0xc0,0x14,0x30,0x05,0x0c,0x01,0x43,0x00,0x50,0x80 } },
+{  16, 0xea20, 0, {0x14,0x30,0x05,0x08,0x01,0x4a,0x00,0x50,0xc0,0x14,0x30,0x05,0x08,0x01,0x40,0x00 } },
+{  16, 0xea30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x08,0x00,0x42,0x00,0x10,0x80 } },
+{  16, 0xea40, 0, {0x04,0x20,0x01,0x08,0x00,0x42,0x00,0x10,0x80,0x04,0x20,0x01,0x08,0x00,0x42,0x00 } },
+{  16, 0xea50, 0, {0x10,0x80,0x04,0x20,0x11,0x00,0x00,0x42,0x00,0x10,0x80,0x04,0x20,0x11,0x00,0x10 } },
+{  16, 0xea60, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x02,0x00,0x80,0x80,0x20 } },
+{  16, 0xea70, 0, {0x20,0x08,0x08,0x02,0x00,0x00,0x80,0x80,0x20,0x20,0x08,0x08,0x02,0x02,0x00,0x80 } },
+{  16, 0xea80, 0, {0x80,0x20,0x20,0x08,0x08,0x02,0x02,0x00,0x80,0x80,0x20,0x20,0x08,0x08,0x00,0x11 } },
+{  16, 0xea90, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x00,0x60,0x01,0x18,0x00 } },
+{  16, 0xeaa0, 0, {0x46,0x00,0x11,0x80,0x06,0x60,0x01,0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01 } },
+{  16, 0xeab0, 0, {0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01,0x18,0x00,0x66,0x00,0x11,0x80,0x10 } },
+{  16, 0xeac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x02,0x64,0x00,0x98,0x00 } },
+{  16, 0xead0, 0, {0x26,0x00,0x09,0x90,0x06,0x60,0x01,0x98,0x00,0x26,0x40,0x09,0x80,0x02,0x60,0x00 } },
+{  16, 0xeae0, 0, {0x98,0x00,0x26,0x00,0x00,0x90,0x02,0x60,0x00,0x98,0x00,0x07,0x00,0x01,0x80,0x00 } },
+{  16, 0xeaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x60,0x04,0x38,0x05,0x0e,0x00 } },
+{  16, 0xeb00, 0, {0x43,0x80,0x10,0xe0,0x44,0x38,0x01,0x0e,0x00,0x43,0x80,0x10,0xe0,0x04,0x38,0x01 } },
+{  16, 0xeb10, 0, {0x0e,0x00,0x43,0x80,0x18,0xa0,0x04,0x38,0x01,0x0e,0x00,0x46,0x80,0x18,0x80,0x11 } },
+{  16, 0xeb20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00,0x30,0x40,0x0c,0x10 } },
+{  16, 0xeb30, 0, {0x03,0x04,0x00,0xc5,0x00,0x30,0x40,0x0c,0x10,0x03,0x14,0x00,0xc1,0x00,0x30,0x40 } },
+{  16, 0xeb40, 0, {0x0c,0x10,0x03,0x04,0x00,0x87,0x40,0x30,0x40,0x0c,0x10,0x02,0x04,0x00,0x80,0x00 } },
+{  16, 0xeb50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x05,0x00,0x35,0x40,0x0c,0x50 } },
+{  16, 0xeb60, 0, {0x03,0x14,0x00,0xd5,0x04,0x31,0x41,0x0c,0x50,0x03,0x5c,0x00,0xc5,0x00,0x31,0x00 } },
+{  16, 0xeb70, 0, {0x0c,0x50,0x03,0x10,0x00,0x94,0x00,0x31,0x40,0x0c,0x50,0x43,0x10,0x00,0xc2,0x00 } },
+{  16, 0xeb80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x43,0x05,0x20,0xc1,0x18,0x30 } },
+{  16, 0xeb90, 0, {0x46,0x0c,0x11,0x97,0x00,0x60,0xc0,0x18,0x30,0x46,0x1c,0x11,0x83,0x04,0x60,0xc1 } },
+{  16, 0xeba0, 0, {0x18,0x30,0x52,0x0c,0x11,0x87,0x04,0x60,0xc1,0x18,0x30,0x46,0x0c,0x11,0x80,0x11 } },
+{  16, 0xebb0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x00,0x00,0x21,0x40,0x08,0x00 } },
+{  16, 0xebc0, 0, {0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x20,0x00 } },
+{  16, 0xebd0, 0, {0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00 } },
+{  16, 0xebe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x48,0x44,0x22,0x01,0x18,0x84 } },
+{  16, 0xebf0, 0, {0x46,0x21,0x11,0x98,0x00,0x62,0x10,0x18,0x84,0x44,0x20,0x11,0x88,0x44,0x62,0x11 } },
+{  16, 0xec00, 0, {0x18,0x84,0x42,0x21,0x11,0x80,0x44,0x62,0x11,0x18,0x84,0x46,0x21,0x11,0x80,0x00 } },
+{  16, 0xec10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x40,0x04,0x50,0x11,0x14,0x04 } },
+{  16, 0xec20, 0, {0x45,0x00,0x11,0x41,0x00,0x50,0x10,0x14,0x00,0x45,0x01,0x11,0x40,0x44,0x50,0x11 } },
+{  16, 0xec30, 0, {0x14,0x04,0x45,0x01,0x01,0x40,0x44,0x50,0x11,0x14,0x04,0x05,0x01,0x01,0x40,0x11 } },
+{  16, 0xec40, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x08,0x20,0x42,0x08,0x10,0x82 } },
+{  16, 0xec50, 0, {0x04,0x20,0x01,0x08,0x20,0x42,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08 } },
+{  16, 0xec60, 0, {0x10,0x82,0x04,0x22,0x81,0x08,0x20,0x52,0x08,0x10,0x8a,0x04,0x22,0x81,0x00,0x00 } },
+{  16, 0xec70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0a,0x01,0x02,0x84,0x40,0xa1 } },
+{  16, 0xec80, 0, {0x10,0x28,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x0a,0x01,0x02,0x80 } },
+{  16, 0xec90, 0, {0x40,0xa0,0x10,0x2c,0x14,0x0a,0x00,0x02,0x80,0x40,0xb0,0x10,0x2c,0x14,0x00,0x00 } },
+{  16, 0xeca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x4d,0x03,0x53,0x40,0xd4,0xd0 } },
+{  16, 0xecb0, 0, {0x35,0x30,0x0c,0x4d,0x03,0x53,0x40,0xd4,0xd0,0x35,0x34,0x0d,0x4d,0x03,0x53,0x40 } },
+{  16, 0xecc0, 0, {0xd4,0xd0,0x35,0x34,0x0d,0x4d,0x02,0x13,0x40,0xd4,0xd0,0x35,0x34,0x0d,0x40,0x11 } },
+{  16, 0xecd0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x08,0x04,0x72,0x01,0x1c,0x80 } },
+{  16, 0xece0, 0, {0x47,0x20,0x15,0xc8,0x04,0x72,0x01,0x1c,0x80,0x47,0x20,0x11,0xc8,0x04,0x72,0x11 } },
+{  16, 0xecf0, 0, {0x1c,0x80,0x47,0x26,0x11,0xc8,0x44,0x72,0x01,0x1c,0x90,0x67,0x26,0x11,0xc0,0x00 } },
+{  16, 0xed00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x08,0x40,0xc6,0x12,0x31 } },
+{  16, 0xed10, 0, {0x84,0x8c,0x01,0x03,0x08,0x48,0xc6,0x12,0x30,0x84,0x0c,0x61,0x23,0x18,0x48,0xc2 } },
+{  16, 0xed20, 0, {0x12,0x31,0x84,0x8c,0x01,0x03,0x08,0x48,0xc6,0x12,0x31,0x04,0x8c,0x01,0x00,0x00 } },
+{  16, 0xed30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x4f,0xff,0xd3,0xff } },
+{  16, 0xed40, 0, {0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff } },
+{  16, 0xed50, 0, {0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x00,0x00 } },
+{  16, 0xed60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xed70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xed80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xed90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0xfb,0x0f,0xb6,0xc2,0xcd } },
+{  16, 0xeda0, 0, {0xb0,0xb7,0xfd,0x3f,0xfb,0x0b,0x36,0xc2,0xdf,0xb0,0xfb,0x6c,0x2c,0xdb,0x0b,0x7e } },
+{  16, 0xedb0, 0, {0xc2,0xcd,0xb0,0xb7,0xfd,0x3f,0xfb,0x0b,0x36,0xc2,0xcd,0xf4,0xb7,0xfd,0x00,0x00 } },
+{  16, 0xedc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0xfc,0x4f,0xcf,0x13,0x33 } },
+{  16, 0xedd0, 0, {0xc4,0xcf,0xfd,0x3f,0xfc,0x4c,0xcf,0x13,0x3f,0xc4,0xfc,0xf1,0x33,0x3c,0x4c,0xff } },
+{  16, 0xede0, 0, {0x13,0x33,0xc4,0xcf,0xfd,0x3f,0xfc,0x4c,0xcf,0x13,0x33,0xf4,0xcf,0xfd,0x00,0x00 } },
+{  16, 0xedf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0x7e,0x4e,0xdf,0x93,0xb7 } },
+{  16, 0xee00, 0, {0xe4,0xed,0xf9,0x3f,0xfe,0x4e,0xdf,0x93,0xb7,0xe4,0xed,0xf9,0x3b,0x7e,0x4e,0xc7 } },
+{  16, 0xee10, 0, {0x93,0xb7,0xe4,0xec,0x61,0x23,0x1e,0x4e,0xdf,0x93,0xb7,0x84,0xec,0x61,0x00,0x00 } },
+{  16, 0xee20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x24,0xa1,0x4a,0x24 } },
+{  16, 0xee30, 0, {0x63,0x01,0x14,0x02,0x44,0x00,0x81,0x0b,0x28,0x71,0x02,0x10,0x82,0x40,0x38,0x11 } },
+{  16, 0xee40, 0, {0x41,0x04,0x50,0x08,0x18,0x82,0x87,0x38,0x31,0xc3,0x2c,0x52,0x0a,0x10,0x00,0x00 } },
+{  16, 0xee50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x45,0x12,0x81,0x44,0x80 } },
+{  16, 0xee60, 0, {0x71,0x21,0x1c,0x0a,0x07,0x1a,0x81,0x02,0xa0,0x52,0x20,0x14,0x48,0x07,0x12,0x81 } },
+{  16, 0xee70, 0, {0xc6,0x80,0x60,0x20,0x08,0x88,0x47,0x02,0x01,0x4a,0x80,0x70,0x20,0x10,0x00,0x00 } },
+{  16, 0xee80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc5,0x2c,0x01,0x4a,0x00 } },
+{  16, 0xee90, 0, {0x52,0x09,0x1c,0x80,0x07,0x24,0x21,0x08,0x08,0x71,0x02,0x10,0x80,0x45,0x20,0xa1 } },
+{  16, 0xeea0, 0, {0x49,0x28,0x52,0x01,0x14,0xc0,0x45,0x00,0x91,0xc4,0x00,0x72,0x02,0x10,0x00,0x00 } },
+{  16, 0xeeb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x07,0x20,0x01,0xc1,0x00 } },
+{  16, 0xeec0, 0, {0x71,0x09,0x10,0x80,0x07,0x00,0x01,0x01,0x00,0x70,0x08,0x18,0x80,0x07,0x00,0x01 } },
+{  16, 0xeed0, 0, {0x89,0x20,0x52,0x01,0x0c,0x80,0x46,0x30,0x81,0x45,0x04,0x60,0x00,0x10,0x00,0x00 } },
+{  16, 0xeee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc2,0x02,0x20,0x00,0x88 } },
+{  16, 0xeef0, 0, {0x20,0x22,0x00,0x08,0xc2,0x22,0x80,0x40,0x88,0x02,0x22,0x00,0x08,0x82,0x0a,0xa0 } },
+{  16, 0xef00, 0, {0x0c,0xa8,0x02,0x22,0x00,0x08,0x80,0x0a,0x00,0x80,0x8c,0x02,0x22,0x00,0x00,0x00 } },
+{  16, 0xef10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x43,0x00,0x00,0x40,0x20 } },
+{  16, 0xef20, 0, {0x30,0x08,0x04,0x40,0x41,0x30,0x10,0xc8,0x00,0x00,0x00,0x00,0x02,0x03,0x00,0x10 } },
+{  16, 0xef30, 0, {0xc0,0x00,0x11,0x08,0x00,0xc2,0x43,0x10,0x80,0xc0,0x20,0x01,0x08,0x00,0x02,0x00 } },
+{  16, 0xef40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xc3,0x0a,0x20,0xc1,0x8c } },
+{  16, 0xef50, 0, {0x12,0x22,0x04,0x88,0x01,0x36,0x20,0xc3,0x08,0x12,0x28,0x04,0x08,0x01,0x04,0x00 } },
+{  16, 0xef60, 0, {0x4a,0xa8,0x22,0x01,0x04,0xc8,0x41,0x26,0x30,0xc0,0x88,0x02,0x21,0x00,0x02,0x00 } },
+{  16, 0xef70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x0a,0x10,0xc1,0x80 } },
+{  16, 0xef80, 0, {0x32,0x21,0x0c,0x88,0x43,0x02,0x80,0x44,0x80,0x12,0x29,0x04,0x08,0x42,0x0a,0x90 } },
+{  16, 0xef90, 0, {0x8a,0x80,0x00,0x20,0x04,0x48,0x03,0x0a,0x10,0x82,0x80,0x00,0x20,0x00,0x02,0x00 } },
+{  16, 0xefa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x87,0x02,0xa1,0x80,0xac } },
+{  16, 0xefb0, 0, {0x43,0x29,0x14,0x8a,0x84,0x02,0xa1,0x00,0xac,0x41,0x20,0x10,0x08,0x06,0x26,0x31 } },
+{  16, 0xefc0, 0, {0x80,0xa4,0x60,0x20,0x14,0x4a,0x44,0x32,0x81,0x81,0xac,0x60,0x2a,0x18,0x02,0x00 } },
+{  16, 0xefd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x07,0x22,0x01,0xc5,0x80 } },
+{  16, 0xefe0, 0, {0x73,0x21,0x1c,0xc8,0x07,0x2a,0x01,0x0c,0x80,0x72,0x20,0x10,0x48,0x47,0x26,0x11 } },
+{  16, 0xeff0, 0, {0xc5,0x80,0x73,0x20,0x1c,0x88,0x07,0x2a,0x11,0x49,0x80,0x70,0x20,0x14,0x02,0x00 } },
+{  16, 0xf000, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x45,0x10,0x31,0xc9,0x0c } },
+{  16, 0xf010, 0, {0x73,0x02,0x1c,0xc0,0x47,0x04,0x01,0x0a,0x0c,0x51,0x0a,0x10,0x82,0x47,0x20,0x31 } },
+{  16, 0xf020, 0, {0xc8,0x00,0x72,0x02,0x1c,0x40,0x05,0x30,0x11,0xc4,0x00,0x72,0x01,0x18,0x02,0x00 } },
+{  16, 0xf030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x10,0x06,0x24,0x01,0x45,0x04 } },
+{  16, 0xf040, 0, {0x51,0x81,0x18,0x90,0x47,0x14,0x01,0x04,0x04,0x71,0x88,0x10,0x12,0x05,0x34,0x01 } },
+{  16, 0xf050, 0, {0x44,0x04,0x51,0x40,0x18,0xd0,0x07,0x38,0x01,0xc4,0x04,0x52,0x01,0x14,0xc2,0x04 } },
+{  16, 0xf060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87,0x00,0x21,0x89,0x0c } },
+{  16, 0xf070, 0, {0x60,0x01,0x1c,0xd0,0x45,0x24,0x01,0xc1,0x0c,0x42,0x01,0x00,0x00,0xc5,0x20,0x31 } },
+{  16, 0xf080, 0, {0x41,0x08,0x40,0x00,0x18,0x80,0x45,0x00,0x21,0x41,0x0c,0x70,0x42,0x1c,0xc2,0x00 } },
+{  16, 0xf090, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x1c,0x80,0xc4,0x20 } },
+{  16, 0xf0a0, 0, {0x31,0x08,0x10,0x42,0x42,0x08,0x80,0xc6,0x20,0x31,0x09,0x00,0x20,0x03,0x1c,0x90 } },
+{  16, 0xf0b0, 0, {0xc4,0x20,0x01,0x49,0x0c,0x42,0x43,0x10,0x80,0x44,0x20,0x31,0x08,0x10,0x00,0x00 } },
+{  16, 0xf0c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x83,0x20,0x30,0x48,0x0c } },
+{  16, 0xf0d0, 0, {0x32,0x40,0x10,0x90,0x81,0x24,0x20,0xc8,0x04,0x32,0x40,0x10,0x20,0xc3,0x20,0x80 } },
+{  16, 0xf0e0, 0, {0xc8,0x00,0x02,0x4a,0x0c,0xa0,0x01,0x24,0x10,0xc8,0x08,0x32,0x41,0x10,0x00,0x00 } },
+{  16, 0xf0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0x03,0x00,0x00,0xc9,0x04 } },
+{  16, 0xf100, 0, {0x30,0x40,0x00,0x90,0x00,0x20,0x00,0x80,0x00,0x10,0x40,0x10,0x00,0x40,0x20,0x10 } },
+{  16, 0xf110, 0, {0xc2,0x00,0x00,0x80,0x08,0x20,0x43,0x08,0x10,0x81,0x00,0x32,0x40,0x0c,0xc0,0x04 } },
+{  16, 0xf120, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x40,0x00,0x00,0x00 } },
+{  16, 0xf130, 0, {0x10,0x00,0x00,0xf0,0x10,0x20,0x00,0x00,0x00,0x10,0x00,0x00,0xf0,0x10,0x80,0x40 } },
+{  16, 0xf140, 0, {0x00,0x00,0x00,0x40,0x00,0xf0,0x10,0x90,0x80,0x00,0x00,0x00,0x00,0x00,0xc0,0x00 } },
+{  16, 0xf150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x10,0x80,0x90,0x40,0x00,0x00 } },
+{  16, 0xf160, 0, {0x00,0x80,0x10,0x90,0xa0,0x90,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x80,0x00 } },
+{  16, 0xf170, 0, {0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x90,0x00,0x00,0x00,0x00,0x40,0x10,0x8f,0x0f } },
+{  16, 0xf180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xc6,0xba,0x06,0xc0,0x1c } },
+{  16, 0xf190, 0, {0x49,0x28,0x61,0x14,0x2b,0x1c,0x0e,0x40,0x3f,0xd9,0xbf,0xd9,0xaa,0xbc,0x1a,0x5f } },
+{  16, 0xf1a0, 0, {0x00,0x10,0xa6,0x50,0x3b,0x61,0xb3,0x25,0xbc,0x40,0x19,0xbf,0xff,0xe9,0x80,0x00 } },
+{  16, 0xf1b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x92,0x14,0x94,0x80,0x0c } },
+{  16, 0xf1c0, 0, {0x07,0x3f,0x2b,0x94,0x86,0x14,0x84,0x80,0x28,0x00,0x00,0x49,0x14,0x04,0x86,0x12 } },
+{  16, 0xf1d0, 0, {0x80,0x00,0x41,0x27,0x34,0xd0,0x90,0x84,0x92,0x00,0x2d,0x8a,0x21,0x1e,0x80,0x00 } },
+{  16, 0xf1e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xa2 } },
+{  16, 0xf1f0, 0, {0xb1,0x01,0x01,0x00,0x00,0x00,0x00,0x08,0x84,0xb1,0x78,0x28,0x00,0x00,0x00,0x00 } },
+{  16, 0xf200, 0, {0x08,0xb1,0x32,0x14,0x14,0x00,0x00,0x00,0x00,0x08,0xa8,0x23,0x54,0x21,0x40,0x00 } },
+{  16, 0xf210, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf220, 0, {0x00,0x00,0x00,0x2f,0xff,0xfe,0xf7,0xc0,0x00,0x00,0x00,0x00,0x2f,0xd7,0xfe,0xef } },
+{  16, 0xf230, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf240, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf250, 0, {0x00,0x00,0x00,0x0f,0xef,0x77,0xff,0xc0,0x00,0x00,0x00,0x00,0x3e,0xff,0xfe,0xef } },
+{  16, 0xf260, 0, {0x40,0x00,0x00,0x00,0x00,0x3f,0xff,0xbf,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf280, 0, {0x00,0x00,0x00,0x3f,0xff,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff } },
+{  16, 0xf290, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0x7f,0x2f,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf2a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf2b0, 0, {0x00,0x00,0x00,0x1f,0xff,0xff,0xef,0xc0,0x00,0x00,0x00,0x00,0x1f,0xef,0xef,0xef } },
+{  16, 0xf2c0, 0, {0xc0,0x00,0x00,0x00,0x00,0x2f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf2d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf2e0, 0, {0x00,0x00,0x00,0x3f,0xff,0xef,0xff,0xc0,0x00,0x00,0x00,0x00,0x2f,0xaf,0xdf,0xff } },
+{  16, 0xf2f0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xef,0xff,0xf7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf310, 0, {0x00,0x00,0x00,0x3f,0xdf,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff } },
+{  16, 0xf320, 0, {0xc0,0x00,0x00,0x00,0x00,0x1f,0xff,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf330, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc4,0x24,0xa1,0x00,0x2c } },
+{  16, 0xf340, 0, {0x52,0x0b,0x18,0xc2,0x86,0x2c,0xa1,0x80,0x38,0x62,0x0a,0x08,0x40,0xc4,0x2c,0xa1 } },
+{  16, 0xf350, 0, {0x08,0x28,0x42,0x0b,0x14,0x00,0x85,0x14,0xa1,0x08,0x28,0x43,0x0a,0x10,0x00,0x00 } },
+{  16, 0xf360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x12,0x01,0x03,0x80 } },
+{  16, 0xf370, 0, {0x61,0x20,0x10,0x08,0x07,0x12,0x41,0x42,0x80,0x70,0x20,0x1c,0x08,0x04,0x1a,0x01 } },
+{  16, 0xf380, 0, {0x84,0x81,0x40,0x20,0x18,0x08,0x46,0x36,0x81,0x05,0x80,0x63,0x20,0x10,0x00,0x01 } },
+{  16, 0xf390, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x24,0x21,0x00,0x0c } },
+{  16, 0xf3a0, 0, {0x52,0x02,0x14,0x00,0x87,0x28,0x21,0x81,0x08,0x72,0x06,0x1c,0x82,0x84,0x20,0x21 } },
+{  16, 0xf3b0, 0, {0x48,0x18,0x42,0x03,0x54,0x80,0x45,0x30,0x25,0x4a,0x18,0x53,0x02,0x10,0x00,0x01 } },
+{  16, 0xf3c0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x22,0x01,0x01,0x80 } },
+{  16, 0xf3d0, 0, {0x42,0x20,0x18,0xc8,0x44,0x22,0x01,0x80,0x84,0x42,0x20,0x1c,0x88,0x04,0x22,0x01 } },
+{  16, 0xf3e0, 0, {0x00,0x80,0x40,0x20,0x10,0x88,0x44,0x36,0x01,0x40,0x80,0x41,0x00,0x10,0x00,0x00 } },
+{  16, 0xf3f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x08,0x20,0x00,0x0c } },
+{  16, 0xf400, 0, {0x22,0x03,0x04,0x40,0x81,0x00,0x20,0x84,0x08,0x03,0x00,0x00,0x80,0xc2,0x00,0x20 } },
+{  16, 0xf410, 0, {0xc4,0x08,0x00,0x03,0x08,0x88,0x82,0x16,0xa0,0x40,0x88,0x32,0x22,0x80,0x00,0x00 } },
+{  16, 0xf420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x01,0x00,0x80,0x04,0x20 } },
+{  16, 0xf430, 0, {0x10,0x08,0x0c,0xc2,0x12,0x10,0x84,0xc8,0x22,0x12,0x08,0x04,0x02,0x03,0x00,0x88 } },
+{  16, 0xf440, 0, {0x00,0x21,0x00,0x0c,0x0c,0x40,0x41,0x30,0x00,0x84,0x20,0x10,0x08,0x00,0x02,0x00 } },
+{  16, 0xf450, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x82,0x06,0x20,0x08,0x8c } },
+{  16, 0xf460, 0, {0x32,0x22,0x0c,0x88,0x81,0x26,0x20,0x4d,0x88,0x23,0x22,0x80,0x88,0x83,0x06,0x20 } },
+{  16, 0xf470, 0, {0x08,0x88,0x00,0x23,0x04,0x8a,0x81,0x36,0x20,0x4b,0x88,0x32,0x22,0x00,0x00,0x00 } },
+{  16, 0xf480, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x02,0x02,0x00,0x09,0x80 } },
+{  16, 0xf490, 0, {0x32,0x20,0x04,0x88,0x60,0x22,0x00,0x89,0x84,0x00,0x20,0x08,0x98,0x00,0x02,0x00 } },
+{  16, 0xf4a0, 0, {0x00,0x80,0x00,0x20,0x00,0x08,0x02,0x3a,0x80,0x48,0x80,0x30,0x20,0x00,0x02,0x00 } },
+{  16, 0xf4b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0a,0xc4,0x1a,0xa1,0x80,0xa8 } },
+{  16, 0xf4c0, 0, {0x41,0x2a,0x10,0xca,0xc7,0x1a,0xa1,0x04,0xad,0x71,0x2a,0x18,0x4a,0xd4,0x06,0xb1 } },
+{  16, 0xf4d0, 0, {0x00,0xa8,0x71,0x2a,0x10,0x08,0x84,0x26,0x29,0x06,0xac,0x52,0x2a,0x10,0x02,0x00 } },
+{  16, 0xf4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x04,0x2a,0x01,0x41,0x80 } },
+{  16, 0xf4f0, 0, {0x42,0x20,0x1c,0x00,0x04,0x0a,0x01,0x09,0x84,0x51,0x20,0x1c,0x88,0x44,0x02,0x01 } },
+{  16, 0xf500, 0, {0x08,0x80,0x40,0x20,0x10,0x4a,0x47,0x02,0x01,0x48,0x80,0x63,0x20,0x10,0x02,0x00 } },
+{  16, 0xf510, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xc4,0x10,0x21,0x81,0x0c } },
+{  16, 0xf520, 0, {0x41,0x02,0x0c,0x00,0xc0,0x20,0x61,0x0d,0x0e,0x72,0x02,0x1c,0x40,0xc4,0x08,0x31 } },
+{  16, 0xf530, 0, {0x04,0x18,0x42,0x02,0x10,0x80,0x87,0x20,0xb1,0xc4,0x0c,0x53,0x02,0x10,0x00,0x00 } },
+{  16, 0xf540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x20,0x07,0x24,0x01,0xcc,0x00 } },
+{  16, 0xf550, 0, {0x72,0x40,0x14,0x00,0x04,0x24,0x01,0x08,0x00,0x73,0x41,0x10,0xc0,0x07,0x30,0x11 } },
+{  16, 0xf560, 0, {0xcc,0x00,0x71,0x01,0x10,0x02,0x04,0x20,0x81,0x46,0x10,0x42,0x40,0x10,0x02,0x04 } },
+{  16, 0xf570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xc5,0x10,0x21,0x00,0x08 } },
+{  16, 0xf580, 0, {0x62,0x02,0x1c,0x90,0xc5,0x24,0x21,0x00,0x0c,0x70,0x82,0x1c,0x10,0xc4,0x20,0x31 } },
+{  16, 0xf590, 0, {0x88,0x02,0x40,0x06,0x1c,0x00,0x85,0x00,0xa1,0x00,0x0c,0x40,0x42,0x00,0x02,0x00 } },
+{  16, 0xf5a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x05,0x14,0x80,0x01,0x20 } },
+{  16, 0xf5b0, 0, {0x30,0x08,0x0c,0x42,0x06,0x00,0x80,0x01,0x24,0x51,0x08,0x0c,0x02,0x41,0x00,0x80 } },
+{  16, 0xf5c0, 0, {0x4c,0x20,0x00,0x08,0x0c,0x30,0x42,0x04,0x00,0x04,0x20,0x00,0x08,0x00,0x00,0x00 } },
+{  16, 0xf5d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xc6,0x24,0x20,0x00,0x0c } },
+{  16, 0xf5e0, 0, {0x32,0xc2,0x04,0x80,0xc7,0x30,0x20,0x00,0x0c,0x53,0xc2,0x04,0x10,0xc2,0x28,0x70 } },
+{  16, 0xf5f0, 0, {0x0c,0x09,0x02,0x02,0x4c,0x80,0x81,0x04,0x30,0x09,0x0c,0x02,0x42,0x10,0x00,0x00 } },
+{  16, 0xf600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x80,0x01,0x38,0x00,0x02,0x00 } },
+{  16, 0xf610, 0, {0x12,0x40,0x0c,0x20,0x07,0x34,0x04,0x02,0x00,0x63,0x01,0x08,0x10,0x00,0x24,0x10 } },
+{  16, 0xf620, 0, {0x04,0x00,0x02,0x01,0x04,0x82,0x01,0x08,0x80,0x09,0x10,0x02,0x40,0x10,0x00,0x04 } },
+{  16, 0xf630, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x20,0x10,0x80,0x00,0x00 } },
+{  16, 0xf640, 0, {0x20,0x80,0x00,0xf0,0x20,0x10,0x80,0x00,0x00,0x20,0x80,0x00,0xd0,0x80,0x00,0x00 } },
+{  16, 0xf650, 0, {0x40,0x00,0x00,0x00,0x00,0x30,0x10,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0xcc,0x40 } },
+{  16, 0xf660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x10,0x80,0x80,0x00,0x00,0x00 } },
+{  16, 0xf670, 0, {0x00,0x00,0x10,0x90,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x00,0x90 } },
+{  16, 0xf680, 0, {0x80,0x00,0x10,0x00,0x00,0x10,0xa0,0x80,0x00,0x00,0x00,0x20,0x00,0x10,0x8c,0x08 } },
+{  16, 0xf690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x1a,0xbe,0x17,0x80,0x00 } },
+{  16, 0xf6a0, 0, {0x3e,0x40,0x26,0x6f,0xba,0xe3,0x24,0x80,0x00,0x16,0x59,0xbd,0x82,0x81,0x82,0xd8 } },
+{  16, 0xf6b0, 0, {0x80,0x00,0x00,0x19,0x99,0x86,0x80,0x64,0x80,0xc0,0x3f,0xd9,0x99,0x80,0x00,0x01 } },
+{  16, 0xf6c0, 0, {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x16,0x02,0x94,0x00,0x16 } },
+{  16, 0xf6d0, 0, {0xc0,0x16,0x94,0x82,0x90,0x16,0x10,0x80,0x21,0x18,0x28,0x28,0x02,0x0a,0x02,0x08 } },
+{  16, 0xf6e0, 0, {0x80,0x00,0x00,0x00,0x00,0x02,0x82,0x80,0x14,0x00,0x01,0x14,0x11,0xa0,0x40,0x00 } },
+{  16, 0xf6f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x84 } },
+{  16, 0xf700, 0, {0x02,0x84,0xa8,0x80,0x00,0x00,0x00,0x08,0x91,0x22,0x84,0x41,0xa2,0x08,0x24,0x01 } },
+{  16, 0xf710, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x84,0x01,0x44,0x01,0x00,0x00 } },
+{  16, 0xf720, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf730, 0, {0x00,0x00,0x00,0x3e,0xf7,0xff,0xf7,0xc0,0x00,0x00,0x00,0x00,0x2f,0xe7,0xb7,0xff } },
+{  16, 0xf740, 0, {0xc0,0x00,0x00,0x00,0x00,0x2f,0xfe,0x7f,0xf7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf750, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf760, 0, {0x00,0x00,0x00,0x36,0xbf,0xfe,0xdf,0xc0,0x00,0x00,0x00,0x00,0x0f,0xf7,0xdf,0xff } },
+{  16, 0xf770, 0, {0xc0,0x00,0x00,0x00,0x00,0x3d,0xb7,0xb7,0xef,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf790, 0, {0x00,0x00,0x00,0x1f,0xdf,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x0f,0xdf,0xdf,0xff } },
+{  16, 0xf7a0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xef,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf7b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf7c0, 0, {0x00,0x00,0x00,0x3f,0xbf,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0x7f,0xf7 } },
+{  16, 0xf7d0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xdf,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf7f0, 0, {0x00,0x00,0x00,0x3f,0x7e,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x3f,0xfe,0xff,0xff } },
+{  16, 0xf800, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf810, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } },
+{  16, 0xf820, 0, {0x00,0x00,0x00,0x37,0xff,0x6f,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff } },
+{  16, 0xf830, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x20,0x01,0x02,0x00,0x00,0x00 } },
+{  16, 0xf880, 0, {0x30,0x00,0x43,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf8a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf8b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf8c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf8d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf8e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf8f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x00,0x00,0x00,0x00,0x30 } },
+{  16, 0xf900, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf920, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf950, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x30,0xc0,0x00 } },
+{  16, 0xf960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf990, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf9b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x30,0xc0,0x30,0xc0,0x30 } },
+{  16, 0xf9c0, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf9d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xf9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfa00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfa10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x0f } },
+{  16, 0xfa20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfa30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfa40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfa50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfa60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfa70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x00,0x00,0x00,0x00,0x3f } },
+{  16, 0xfa80, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfa90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfaa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfab0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfad0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x30,0xc0,0x30,0xc0,0x0f } },
+{  16, 0xfae0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x6b,0x00,0xc0,0x00,0xcf,0x2c } },
+{  16, 0xfb40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfb90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,0x00,0x00 } },
+{  16, 0xfba0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfbb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfbc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfbd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfbe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfbf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x0f,0x00,0x0f,0x00,0x30 } },
+{  16, 0xfc00, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfc10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfc20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfc30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfc40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfc50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x3f,0xc0,0x00 } },
+{  16, 0xfc60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfc70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfc80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfc90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfcb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x3f,0xc0,0x3f,0xc0,0x30 } },
+{  16, 0xfcc0, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfcd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfcf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfd00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfd10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f } },
+{  16, 0xfd20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfd30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfd40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfd50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfd60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfd70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x0f,0x00,0x0f,0x00,0x3f } },
+{  16, 0xfd80, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfd90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfda0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfdb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfdc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfdd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x3f,0xc0,0x3f,0xc0,0x0f } },
+{  16, 0xfde0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfdf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x33,0x5d,0x80,0xc0,0x00,0xfd,0xac } },
+{  16, 0xfe40, 0, {0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfe90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfea0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfeb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfec0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfed0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x00,0x00,0x00,0x00,0x30 } },
+{  16, 0xff00, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xff10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xff20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xff30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xff40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xff50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x30,0xc0,0x00 } },
+{  16, 0xff60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xff70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xff80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xff90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xffa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xffb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x30,0xc0,0x30,0xc0,0x30 } },
+{  16, 0xffc0, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xffd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xffe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0xfff0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8010, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8020, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x0f } },
+{  16, 0x8030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8040, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8050, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x00,0x00,0x00,0x00,0x3f } },
+{  16, 0x8090, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x80e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x30,0xc0,0x30,0xc0,0x0f } },
+{  16, 0x80f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8110, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8140, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x74,0xc0,0xc0,0x00,0xf0,0xec } },
+{  16, 0x8150, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8170, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x81a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,0x00,0x00 } },
+{  16, 0x81b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x81c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x81d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x81e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x81f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8200, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x0f,0x00,0x0f,0x00,0x30 } },
+{  16, 0x8210, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8220, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8230, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8240, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8250, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8260, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x3f,0xc0,0x00 } },
+{  16, 0x8270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8280, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8290, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x82a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x82b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x82c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x86,0x10,0x80,0x30,0x82,0x3d } },
+{  16, 0x82d0, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x82e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x82f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8310, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8320, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f } },
+{  16, 0x8330, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8340, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x0f,0x00,0x0f,0x00,0x3f } },
+{  16, 0x8390, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x83a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x83b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x83c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x83d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x83e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x3f,0xc0,0x3f,0xc0,0x0f } },
+{  16, 0x83f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8410, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8430, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8440, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x65,0x25,0xe4,0x80,0x00,0xb0,0x88 } },
+{  16, 0x8450, 0, {0xab,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8470, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8480, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8490, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x84a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x84b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x84c0, 0, {0x00,0x00,0x00,0x00,0x30,0x00,0x20,0x01,0x02,0x02,0x00,0x00,0x30,0x00,0x43,0x00 } },
+{  16, 0x84d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x84e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x84f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8500, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8510, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8520, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8530, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8550, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8560, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8590, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x85a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x85b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x85c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x85d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x85e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x85f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8610, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8620, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8630, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8640, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8650, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8680, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x86a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x86b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x86c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x86d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x86e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x86f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8700, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8710, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8720, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8730, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8740, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8750, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8790, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x87a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x87b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x87c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x87d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x87e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x87f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8800, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8810, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8830, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x88a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x88b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x88c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x88d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x88e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x88f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8900, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8920, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8950, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8990, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x89a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x89b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x89c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x89d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x89e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x89f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8a90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8aa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ab0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ad0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ae0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8af0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8b90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ba0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8bb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8bc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8bd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8be0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8bf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8c90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8cb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8cc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8cd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8cf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8d90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8da0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8db0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8dc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8dd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8de0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8df0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8e90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ea0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8eb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ec0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ed0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8f90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8fa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8fb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8fc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8fd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8fe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x8ff0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9000, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9010, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9020, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9040, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9050, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9090, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x90a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x90b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x90c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x90d0, 0, {0x30,0x00,0x00,0x01,0x00,0x00,0x44,0x72,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x03 } },
+{  16, 0x90e0, 0, {0x30,0x00,0x40,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x90f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  16, 0x9110, 0, {0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x05,0x30,0x00,0xa0,0x01 } },
+{  16, 0x9120, 0, {0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x01,0x00,0x00,0xe1,0x5a,0x00,0x00,0x00,0x00 } },
+{  12, 0x9130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } },
+{  0 , 0x0000, 1, {0 }}
+};
+// VERSION=1.1.1.131
+// DATE=2001dec06
+// PRODUCT=EMI 2|6
+/*
+ * This firmware is for the Emagic EMI 2|6 Audio Interface
+ *
+ * The firmware contained herein is Copyright (c) 1999-2002 Emagic
+ * as an unpublished work. This notice does not imply unrestricted
+ * or public access to this firmware which is a trade secret of Emagic,
+ * and which may not be reproduced, used, sold or transferred to
+ * any third party without Emagic's written consent. All Rights Reserved.
+ *
+ * This firmware may not be modified and may only be used with the
+ * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of
+ * any driver which includes this firmware, in whole or in part,
+ * requires the inclusion of this statement.
+ */
+INTEL_HEX_RECORD g_Firmware[] = {
+{   3,0x0000,0,{0x02,0x43,0x56} },
+{   3,0x0003,0,{0x02,0x4b,0xcd} },
+{   3,0x000b,0,{0x02,0x4b,0xd2} },
+{   3,0x0013,0,{0x02,0x4b,0x92} },
+{   3,0x001b,0,{0x02,0x4b,0xd5} },
+{   3,0x0023,0,{0x02,0x1b,0x39} },
+{   3,0x002b,0,{0x02,0x43,0xe2} },
+{   3,0x0033,0,{0x02,0x3f,0xf3} },
+{   3,0x003b,0,{0x02,0x4b,0xc0} },
+{   3,0x0043,0,{0x02,0x47,0x00} },
+{   3,0x004b,0,{0x02,0x3f,0xfc} },
+{   3,0x0053,0,{0x02,0x37,0xfa} },
+{   3,0x005b,0,{0x02,0x4b,0xc7} },
+{   3,0x0063,0,{0x02,0x46,0xfc} },
+{  16,0x0500,0,{0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x40,0x6a,0x08,0x01,0x01,0x00,0x01,0x01,0x02} },
+{  16,0x0510,0,{0x00,0x01,0x09,0x02,0xb8,0x01,0x03,0x01,0x00,0x80,0xa0,0x09,0x04,0x00,0x00,0x00} },
+{  16,0x0520,0,{0x01,0x01,0x00,0x00,0x0a,0x24,0x01,0x00,0x01,0x56,0x00,0x02,0x01,0x02,0x0c,0x24} },
+{  16,0x0530,0,{0x02,0x01,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x15,0x24,0x06,0x05,0x01,0x02} },
+{  16,0x0540,0,{0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09} },
+{  16,0x0550,0,{0x24,0x03,0x02,0x04,0x03,0x00,0x05,0x00,0x0c,0x24,0x02,0x03,0x01,0x02,0x00,0x02} },
+{  16,0x0560,0,{0x00,0x00,0x00,0x00,0x0d,0x24,0x06,0x06,0x03,0x02,0x03,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x0570,0,{0x00,0x09,0x24,0x03,0x04,0x01,0x01,0x00,0x06,0x00,0x09,0x04,0x01,0x00,0x00,0x01} },
+{  16,0x0580,0,{0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01} },
+{  16,0x0590,0,{0x00,0x01,0x00,0x11,0x24,0x02,0x01,0x02,0x02,0x10,0x03,0x44,0xac,0x00,0x80,0xbb} },
+{  16,0x05a0,0,{0x00,0x00,0x77,0x01,0x09,0x05,0x0a,0x05,0x84,0x01,0x01,0x00,0x8f,0x07,0x25,0x01} },
+{  16,0x05b0,0,{0x01,0x00,0x00,0x00,0x09,0x05,0x8f,0x01,0x03,0x00,0x01,0x06,0x00,0x09,0x04,0x01} },
+{  16,0x05c0,0,{0x02,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01,0x00,0x01,0x00,0x0e,0x24,0x02} },
+{  16,0x05d0,0,{0x01,0x06,0x02,0x10,0x02,0x44,0xac,0x00,0x80,0xbb,0x00,0x09,0x05,0x0a,0x05,0x4c} },
+{  16,0x05e0,0,{0x02,0x01,0x00,0x8f,0x07,0x25,0x01,0x01,0x00,0x00,0x00,0x09,0x05,0x8f,0x01,0x03} },
+{  16,0x05f0,0,{0x00,0x01,0x06,0x00,0x09,0x04,0x01,0x03,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01} },
+{  16,0x0600,0,{0x01,0x00,0x01,0x00,0x0e,0x24,0x02,0x01,0x06,0x03,0x18,0x02,0x44,0xac,0x00,0x80} },
+{  16,0x0610,0,{0xbb,0x00,0x09,0x05,0x0a,0x05,0x72,0x03,0x01,0x00,0x8f,0x07,0x25,0x01,0x01,0x00} },
+{  16,0x0620,0,{0x00,0x00,0x09,0x05,0x8f,0x01,0x03,0x00,0x01,0x06,0x00,0x09,0x04,0x01,0x04,0x02} },
+{  16,0x0630,0,{0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01,0x00,0x01,0x00,0x0b,0x24,0x02,0x01,0x02} },
+{  16,0x0640,0,{0x03,0x18,0x01,0x00,0x77,0x01,0x09,0x05,0x0a,0x05,0x46,0x02,0x01,0x00,0x8f,0x07} },
+{  16,0x0650,0,{0x25,0x01,0x01,0x00,0x00,0x00,0x09,0x05,0x8f,0x01,0x03,0x00,0x01,0x06,0x00,0x09} },
+{  16,0x0660,0,{0x04,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x09,0x04,0x02,0x01,0x01,0x01,0x02,0x00} },
+{  16,0x0670,0,{0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x11,0x24,0x02,0x01,0x02,0x02,0x10,0x03} },
+{  16,0x0680,0,{0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05,0x8c,0x05,0x84,0x01,0x01} },
+{  16,0x0690,0,{0x00,0x00,0x07,0x25,0x01,0x01,0x02,0x00,0x00,0x09,0x04,0x02,0x02,0x01,0x01,0x02} },
+{  16,0x06a0,0,{0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x11,0x24,0x02,0x01,0x02,0x03,0x18} },
+{  16,0x06b0,0,{0x03,0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05,0x8c,0x05,0x46,0x02} },
+{  16,0x06c0,0,{0x01,0x00,0x00,0x07,0x25,0x01,0x01,0x02,0x00,0x00,0x05,0x0c,0x09,0x01,0xa1,0x01} },
+{  16,0x06d0,0,{0x05,0x0c,0x09,0xe9,0x05,0x0c,0x09,0xea,0x15,0x00,0x25,0x01,0x95,0x02,0x75,0x01} },
+{  16,0x06e0,0,{0x81,0x42,0x95,0x01,0x75,0x06,0x81,0x01,0x05,0x0c,0x09,0x00,0x05,0x0c,0x09,0x00} },
+{  16,0x06f0,0,{0x15,0x00,0x25,0x01,0x95,0x02,0x75,0x01,0x91,0x06,0x95,0x01,0x75,0x06,0x91,0x03} },
+{  16,0x0700,0,{0xc0,0x04,0x03,0x09,0x04,0x18,0x03,0x45,0x00,0x4d,0x00,0x41,0x00,0x47,0x00,0x49} },
+{  16,0x0710,0,{0x00,0x43,0x00,0x20,0x00,0x47,0x00,0x6d,0x00,0x62,0x00,0x48,0x00,0x1e,0x03,0x45} },
+{  16,0x0720,0,{0x00,0x6d,0x00,0x61,0x00,0x67,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x45,0x00,0x4d} },
+{  16,0x0730,0,{0x00,0x49,0x00,0x20,0x00,0x32,0x00,0x7c,0x00,0x36,0x00,0x2a,0x03,0x43,0x00,0x6f} },
+{  16,0x0740,0,{0x00,0x6e,0x00,0x66,0x00,0x69,0x00,0x67,0x00,0x75,0x00,0x72,0x00,0x61,0x00,0x74} },
+{  16,0x0750,0,{0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69} },
+{  16,0x0760,0,{0x00,0x6e,0x00,0x67,0x00,0x22,0x03,0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x72} },
+{  16,0x0770,0,{0x00,0x66,0x00,0x61,0x00,0x63,0x00,0x65,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72} },
+{   9,0x0780,0,{0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x00,0x00} },
+{  16,0x0789,0,{0x74,0x00,0xf5,0x86,0x90,0xfd,0xa5,0x7c,0x05,0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9} },
+{   1,0x0799,0,{0x22} },
+{  16,0x079a,0,{0x90,0x7f,0xd6,0xe0,0x44,0x80,0xf0,0x43,0x87,0x01,0x00,0x00,0x00,0x00,0x00,0x22} },
+{  16,0x07aa,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0x8d,0xe0,0xc0,0xe0} },
+{  16,0x07ba,0,{0x8c,0xe0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x05,0x86,0xc0,0x84,0xc0,0x85,0xe5,0x18} },
+{  16,0x07ca,0,{0xb4,0x02,0x03,0x02,0x07,0xd9,0xb4,0x01,0x03,0x02,0x07,0xde,0x02,0x07,0xfa,0x7d} },
+{  16,0x07da,0,{0x01,0x02,0x08,0x16,0xe5,0x19,0x14,0xf5,0x19,0xc3,0xb5,0x13,0x03,0x02,0x07,0xf5} },
+{  16,0x07ea,0,{0x50,0x09,0xb4,0x00,0xea,0x75,0x19,0x0a,0x02,0x07,0xd9,0x7d,0x00,0x02,0x08,0x16} },
+{  16,0x07fa,0,{0xe5,0x19,0x14,0xf5,0x19,0xc3,0xb5,0x14,0x03,0x02,0x08,0x11,0x50,0x09,0xb4,0x00} },
+{  16,0x080a,0,{0xce,0x75,0x19,0x0a,0x02,0x07,0xd9,0x7d,0x02,0x02,0x08,0x16,0x7c,0x05,0x90,0x7f} },
+{  16,0x081a,0,{0x99,0xe0,0x54,0x40,0xdc,0x03,0x02,0x08,0x43,0xb4,0x00,0x1d,0x90,0x7f,0xe3,0x74} },
+{  16,0x082a,0,{0x7b,0xf0,0xa3,0x74,0x80,0xf0,0x90,0x7f,0xe2,0x74,0x40,0xf0,0x90,0x7f,0xe5,0xf0} },
+{  16,0x083a,0,{0x90,0x7f,0xe2,0x74,0x00,0xf0,0x02,0x08,0x18,0x05,0x86,0x90,0x7f,0xe2,0x74,0x80} },
+{  16,0x084a,0,{0xf0,0x90,0x79,0x65,0xe0,0xb4,0x01,0x03,0x02,0x08,0x9e,0xb4,0x02,0x03,0x02,0x08} },
+{  16,0x085a,0,{0x96,0xb4,0x03,0x03,0x02,0x08,0x8e,0xb4,0x04,0x03,0x02,0x08,0x86,0xb4,0x05,0x03} },
+{  16,0x086a,0,{0x02,0x08,0x7e,0xb4,0x06,0x03,0x02,0x08,0x76,0x02,0x08,0xf4,0x05,0x86,0x90,0x7f} },
+{  16,0x087a,0,{0x6c,0x02,0x08,0xe9,0x05,0x86,0x90,0x7f,0x6c,0x02,0x08,0xdd,0x05,0x86,0x90,0x7f} },
+{  16,0x088a,0,{0x6c,0x02,0x08,0xcf,0x05,0x86,0x90,0x7f,0x6c,0x02,0x08,0xc0,0x05,0x86,0x90,0x7f} },
+{  16,0x089a,0,{0x6c,0x02,0x08,0xb2,0x05,0x86,0x90,0x7f,0x6c,0xf0,0x00,0xf0,0x00,0xf0,0x00,0xf0} },
+{  16,0x08aa,0,{0x0d,0xed,0xb4,0x2d,0xf4,0x02,0x08,0xf4,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0d,0xed} },
+{  16,0x08ba,0,{0xb4,0x2d,0xf5,0x02,0x08,0xf4,0xf0,0x00,0xf0,0x00,0xf0,0x00,0xf0,0x0d,0xed,0xb4} },
+{  16,0x08ca,0,{0x31,0xf4,0x02,0x08,0xf4,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0d,0xed,0xb4,0x31,0xf5} },
+{  16,0x08da,0,{0x02,0x08,0xf4,0xf0,0xf0,0xf0,0xf0,0x0d,0xed,0xb4,0x61,0xf7,0x02,0x08,0xf4,0xf0} },
+{  16,0x08ea,0,{0xf0,0xf0,0xf0,0xf0,0xf0,0x0d,0xed,0xb4,0x61,0xf5,0x90,0x7f,0xe2,0x74,0x00,0xf0} },
+{  16,0x08fa,0,{0xd0,0x85,0xd0,0x84,0x05,0x86,0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xfc,0xd0,0xe0,0xfd} },
+{   5,0x090a,0,{0xd0,0xe0,0xfe,0xd0,0xe0} },
+{   6,0x090f,0,{0xff,0xd0,0xe0,0xd0,0xd0,0x22} },
+{  16,0x0915,0,{0xc0,0xd0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x90,0x7f,0x6f,0xe5,0x0c,0xf0,0xe5,0x0d} },
+{  13,0x0925,0,{0xf0,0xe5,0x0e,0xf0,0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xd0,0xd0,0x22} },
+{  16,0x0932,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0xc0,0x82,0xc0,0x83} },
+{  16,0x0942,0,{0x05,0x86,0xc0,0x84,0xc0,0x85,0x90,0x79,0x70,0xe0,0xff,0xbf,0x00,0x03,0x02,0x0a} },
+{  16,0x0952,0,{0xb8,0x90,0x7f,0x96,0xe0,0x44,0x80,0xf0,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f} },
+{  16,0x0962,0,{0x62,0xe0,0x05,0x86,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x96,0xe0,0x54,0x7f} },
+{  16,0x0972,0,{0xf0,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x79,0x88,0xe0,0xb4,0x01,0x03,0x02,0x09} },
+{  16,0x0982,0,{0xbe,0xb4,0x02,0x03,0x02,0x09,0xc3,0xb4,0x03,0x03,0x02,0x09,0xac,0xb4,0x04,0x03} },
+{  16,0x0992,0,{0x02,0x09,0x9a,0x05,0x86,0x02,0x0a,0xb2,0xef,0x54,0x03,0xfe,0xef,0x03,0x03,0x54} },
+{  16,0x09a2,0,{0x3f,0xff,0x90,0x7f,0x63,0x05,0x86,0x02,0x09,0xc9,0xef,0x54,0x03,0xfe,0xef,0x03} },
+{  16,0x09b2,0,{0x03,0x54,0x3f,0xff,0x90,0x7f,0x63,0x05,0x86,0x02,0x0a,0x36,0x05,0x86,0x02,0x0a} },
+{  16,0x09c2,0,{0xa5,0x05,0x86,0x02,0x0a,0x8e,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0} },
+{  16,0x09d2,0,{0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0x05,0x86} },
+{  16,0x09e2,0,{0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0} },
+{  16,0x09f2,0,{0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0x05,0x86,0xdf,0xca,0xee,0xb4,0x00,0x03} },
+{  16,0x0a02,0,{0x02,0x0a,0xb2,0xb4,0x01,0x03,0x02,0x0a,0x25,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05} },
+{  16,0x0a12,0,{0x86,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0} },
+{  16,0x0a22,0,{0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0x05,0x86} },
+{  16,0x0a32,0,{0x02,0x0a,0xb2,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0} },
+{  13,0x0a42,0,{0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0x05,0x86} },
+{  16,0x0a4f,0,{0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0xdf,0xd6} },
+{  16,0x0a5f,0,{0xee,0xb4,0x00,0x03,0x02,0x0a,0xb2,0xb4,0x01,0x03,0x02,0x0a,0x80,0xe0,0xe0,0xe0} },
+{  16,0x0a6f,0,{0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0x05} },
+{  16,0x0a7f,0,{0x86,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0x02,0x0a,0xb2,0xe0,0xe0} },
+{  16,0x0a8f,0,{0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0} },
+{  16,0x0a9f,0,{0xdf,0xec,0x02,0x0a,0xb2,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0} },
+{  16,0x0aaf,0,{0xe0,0xdf,0xf2,0x90,0x7f,0xe2,0x74,0x00,0xf0,0xd0,0x85,0xd0,0x84,0x05,0x86,0xd0} },
+{  14,0x0abf,0,{0x83,0xd0,0x82,0xd0,0xe0,0xfe,0xd0,0xe0,0xff,0xd0,0xe0,0xd0,0xd0,0x22} },
+{  16,0x0acd,0,{0xc0,0x82,0xc0,0x83,0xc0,0xe0,0xe8,0xc0,0xe0,0x78,0xd1,0xe8,0x14,0xf8,0x70,0xfb} },
+{  10,0x0add,0,{0xd0,0xe0,0xf8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0x22} },
+{  16,0x0ae7,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0x8d,0xe0,0xc0,0xe0} },
+{  16,0x0af7,0,{0x8c,0xe0,0xc0,0xe0,0x75,0x86,0x00,0xc0,0x82,0xc0,0x83,0x05,0x86,0xc0,0x84,0xc0} },
+{  16,0x0b07,0,{0x85,0x7e,0x00,0x90,0x79,0x8e,0xe0,0xb4,0x00,0x16,0x74,0x01,0xf0,0x90,0x06,0xca} },
+{  16,0x0b17,0,{0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xe0,0xff,0x90,0x79,0x8d,0xf0,0x02,0x0b,0x39} },
+{  16,0x0b27,0,{0x90,0x79,0x8d,0xe0,0xff,0x90,0x79,0x8f,0xe0,0xfd,0x90,0x79,0x90,0xe0,0xfc,0x02} },
+{  16,0x0b37,0,{0x0b,0x46,0x90,0x06,0xca,0x05,0x86,0x90,0x7f,0x00,0x05,0x86,0x02,0x0b,0x51,0x8d} },
+{  16,0x0b47,0,{0x84,0x8c,0x85,0x05,0x86,0x90,0x7f,0x00,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xa3} },
+{  16,0x0b57,0,{0x0e,0xee,0xb4,0x40,0x03,0x02,0x0b,0x6c,0x05,0x86,0xdf,0xee,0x90,0x79,0x8e,0x74} },
+{  16,0x0b67,0,{0x00,0xf0,0x02,0x0b,0x82,0x05,0x86,0xad,0x84,0xac,0x85,0x90,0x79,0x8f,0xed,0xf0} },
+{  16,0x0b77,0,{0x90,0x79,0x90,0xec,0xf0,0x90,0x79,0x8d,0x1f,0xef,0xf0,0x90,0x7f,0xb5,0xee,0xf0} },
+{  16,0x0b87,0,{0xd0,0x85,0xd0,0x84,0x05,0x86,0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xfc,0xd0,0xe0,0xfd} },
+{  11,0x0b97,0,{0xd0,0xe0,0xfe,0xd0,0xe0,0xff,0xd0,0xe0,0xd0,0xd0,0x22} },
+{  16,0x0ba2,0,{0xc0,0xd0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x90,0x7f,0xae,0xe0,0x54,0xe0,0xf0,0x90} },
+{  16,0x0bb2,0,{0x7f,0x96,0xe0,0x44,0x08,0x54,0xfb,0xf0,0x90,0x7f,0x97,0xe0,0x54,0xbf,0xf0,0x90} },
+{  16,0x0bc2,0,{0x7f,0xe3,0x74,0x7b,0xf0,0x90,0x7f,0xe4,0x74,0x40,0xf0,0x90,0x79,0x78,0xe0,0x90} },
+{  16,0x0bd2,0,{0x7b,0x40,0xf0,0x90,0x7f,0xe2,0x74,0x48,0xf0,0x90,0x7f,0xe5,0xe0,0x90,0x7f,0xe2} },
+{  16,0x0be2,0,{0x74,0x00,0xf0,0x90,0x7f,0x96,0xe0,0x54,0xf7,0x44,0x04,0xf0,0x90,0x7f,0xe3,0x74} },
+{  16,0x0bf2,0,{0x7b,0xf0,0x90,0x7f,0xe4,0x74,0x40,0xf0,0x90,0x79,0x79,0xe0,0x90,0x7b,0x40,0xf0} },
+{  16,0x0c02,0,{0x90,0x7f,0xe2,0x74,0x48,0xf0,0x90,0x7f,0xe5,0xe0,0x90,0x7f,0xe2,0x74,0x00,0xf0} },
+{  16,0x0c12,0,{0x90,0x7f,0x96,0xe0,0x54,0xf3,0xf0,0x90,0x7f,0xae,0xe0,0x44,0x1f,0xf0,0xd0,0x83} },
+{   7,0x0c22,0,{0xd0,0x82,0xd0,0xe0,0xd0,0xd0,0x22} },
+{  16,0x0c29,0,{0xc0,0xd0,0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x79,0x2f,0xe0,0x64,0xff,0xc3,0x24} },
+{  11,0x0c39,0,{0x01,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0xd0,0xd0,0x22} },
+{  16,0x0c44,0,{0xbb,0x01,0x06,0x89,0x82,0x8a,0x83,0xe0,0x22,0x50,0x02,0xe7,0x22,0xbb,0xfe,0x02} },
+{   9,0x0c54,0,{0xe3,0x22,0x89,0x82,0x8a,0x83,0xe4,0x93,0x22} },
+{  16,0x0c5d,0,{0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50} },
+{  16,0x0c6d,0,{0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22} },
+{  13,0x0c7d,0,{0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22} },
+{  16,0x0c8a,0,{0xbb,0x01,0x06,0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01} },
+{   2,0x0c9a,0,{0xf3,0x22} },
+{  16,0x0c9c,0,{0xf8,0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0} },
+{  16,0x0cac,0,{0x22,0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8} },
+{   2,0x0cbc,0,{0xf2,0x22} },
+{  16,0x0cbe,0,{0xc2,0xd5,0xec,0x30,0xe7,0x09,0xb2,0xd5,0xe4,0xc3,0x9d,0xfd,0xe4,0x9c,0xfc,0xee} },
+{  16,0x0cce,0,{0x30,0xe7,0x15,0xb2,0xd5,0xe4,0xc3,0x9f,0xff,0xe4,0x9e,0xfe,0x12,0x0e,0x40,0xc3} },
+{  16,0x0cde,0,{0xe4,0x9d,0xfd,0xe4,0x9c,0xfc,0x80,0x03,0x12,0x0e,0x40,0x30,0xd5,0x07,0xc3,0xe4} },
+{   6,0x0cee,0,{0x9f,0xff,0xe4,0x9e,0xfe,0x22} },
+{  16,0x0cf4,0,{0xc5,0xf0,0xf8,0xa3,0xe0,0x28,0xf0,0xc5,0xf0,0xf8,0xe5,0x82,0x15,0x82,0x70,0x02} },
+{   6,0x0d04,0,{0x15,0x83,0xe0,0x38,0xf0,0x22} },
+{  16,0x0d0a,0,{0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0xf5,0xf0} },
+{  16,0x0d1a,0,{0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8,0x86,0xf0,0x08,0xe6,0x22,0xbb,0xfe} },
+{  16,0x0d2a,0,{0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08,0xe2,0x22,0xe5,0x83,0x2a,0xf5,0x83} },
+{   8,0x0d3a,0,{0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22} },
+{  16,0x0d42,0,{0xe8,0x8f,0xf0,0xa4,0xcc,0x8b,0xf0,0xa4,0x2c,0xfc,0xe9,0x8e,0xf0,0xa4,0x2c,0xfc} },
+{  16,0x0d52,0,{0x8a,0xf0,0xed,0xa4,0x2c,0xfc,0xea,0x8e,0xf0,0xa4,0xcd,0xa8,0xf0,0x8b,0xf0,0xa4} },
+{  16,0x0d62,0,{0x2d,0xcc,0x38,0x25,0xf0,0xfd,0xe9,0x8f,0xf0,0xa4,0x2c,0xcd,0x35,0xf0,0xfc,0xeb} },
+{  16,0x0d72,0,{0x8e,0xf0,0xa4,0xfe,0xa9,0xf0,0xeb,0x8f,0xf0,0xa4,0xcf,0xc5,0xf0,0x2e,0xcd,0x39} },
+{  15,0x0d82,0,{0xfe,0xe4,0x3c,0xfc,0xea,0xa4,0x2d,0xce,0x35,0xf0,0xfd,0xe4,0x3c,0xfc,0x22} },
+{  16,0x0d91,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0} },
+{   1,0x0da1,0,{0x22} },
+{  16,0x0da2,0,{0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x0e,0xa1} },
+{  16,0x0db2,0,{0x50,0x07,0xe9,0x25,0x82,0xf8,0x02,0x0e,0x95,0xbb,0xfe,0x07,0xe9,0x25,0x82,0xf8} },
+{  16,0x0dc2,0,{0x02,0x0e,0xad,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x0e,0xb9} },
+{  16,0x0dd2,0,{0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x0e,0xd5} },
+{  16,0x0de2,0,{0x50,0x07,0xe9,0x25,0x82,0xf8,0x02,0x0e,0xc9,0xbb,0xfe,0x07,0xe9,0x25,0x82,0xf8} },
+{   4,0x0df2,0,{0x02,0x0e,0xe1,0x22} },
+{  16,0x0df6,0,{0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x0f,0x06} },
+{  16,0x0e06,0,{0x50,0x07,0xe9,0x25,0x82,0xf8,0x02,0x0e,0xed,0xbb,0xfe,0x07,0xe9,0x25,0x82,0xf8} },
+{   4,0x0e16,0,{0x02,0x0f,0x37,0x22} },
+{  16,0x0e1a,0,{0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3} },
+{  16,0x0e2a,0,{0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60} },
+{   6,0x0e3a,0,{0xef,0xa3,0xa3,0xa3,0x80,0xdf} },
+{  16,0x0e40,0,{0xbc,0x00,0x0b,0xbe,0x00,0x29,0xef,0x8d,0xf0,0x84,0xff,0xad,0xf0,0x22,0xe4,0xcc} },
+{  16,0x0e50,0,{0xf8,0x75,0xf0,0x08,0xef,0x2f,0xff,0xee,0x33,0xfe,0xec,0x33,0xfc,0xee,0x9d,0xec} },
+{  16,0x0e60,0,{0x98,0x40,0x05,0xfc,0xee,0x9d,0xfe,0x0f,0xd5,0xf0,0xe9,0xe4,0xce,0xfd,0x22,0xed} },
+{  16,0x0e70,0,{0xf8,0xf5,0xf0,0xee,0x84,0x20,0xd2,0x1c,0xfe,0xad,0xf0,0x75,0xf0,0x08,0xef,0x2f} },
+{  16,0x0e80,0,{0xff,0xed,0x33,0xfd,0x40,0x07,0x98,0x50,0x06,0xd5,0xf0,0xf2,0x22,0xc3,0x98,0xfd} },
+{   5,0x0e90,0,{0x0f,0xd5,0xf0,0xea,0x22} },
+{  12,0x0e95,0,{0xe6,0xfc,0x08,0xe6,0xfd,0x08,0xe6,0xfe,0x08,0xe6,0xff,0x22} },
+{  12,0x0ea1,0,{0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22} },
+{  12,0x0ead,0,{0xe2,0xfc,0x08,0xe2,0xfd,0x08,0xe2,0xfe,0x08,0xe2,0xff,0x22} },
+{  16,0x0eb9,0,{0xe4,0x93,0xfc,0xa3,0xe4,0x93,0xfd,0xa3,0xe4,0x93,0xfe,0xa3,0xe4,0x93,0xff,0x22} },
+{  12,0x0ec9,0,{0xec,0xf6,0x08,0xed,0xf6,0x08,0xee,0xf6,0x08,0xef,0xf6,0x22} },
+{  12,0x0ed5,0,{0xec,0xf0,0xa3,0xed,0xf0,0xa3,0xee,0xf0,0xa3,0xef,0xf0,0x22} },
+{  12,0x0ee1,0,{0xec,0xf2,0x08,0xed,0xf2,0x08,0xee,0xf2,0x08,0xef,0xf2,0x22} },
+{  16,0x0eed,0,{0xd0,0x83,0xd0,0x82,0xe4,0x93,0xf6,0x08,0x74,0x01,0x93,0xf6,0x08,0x74,0x02,0x93} },
+{   9,0x0efd,0,{0xf6,0x08,0x74,0x03,0x93,0xf6,0x74,0x04,0x73} },
+{  16,0x0f06,0,{0xa8,0x82,0x85,0x83,0xf0,0xd0,0x83,0xd0,0x82,0x12,0x0f,0x1d,0x12,0x0f,0x1d,0x12} },
+{  16,0x0f16,0,{0x0f,0x1d,0x12,0x0f,0x1d,0xe4,0x73,0xe4,0x93,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83} },
+{  16,0x0f26,0,{0xc8,0xc5,0x82,0xc8,0xf0,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83,0xc8,0xc5,0x82,0xc8} },
+{   1,0x0f36,0,{0x22} },
+{  16,0x0f37,0,{0xd0,0x83,0xd0,0x82,0xe4,0x93,0xf2,0x08,0x74,0x01,0x93,0xf2,0x08,0x74,0x02,0x93} },
+{   9,0x0f47,0,{0xf2,0x08,0x74,0x03,0x93,0xf2,0x74,0x04,0x73} },
+{  16,0x0f50,0,{0xc2,0xaf,0xd2,0x2c,0x90,0x7f,0x93,0x74,0x30,0xf0,0x90,0x7f,0x9c,0x74,0xbf,0xf0} },
+{  16,0x0f60,0,{0x90,0x7f,0x96,0xe0,0x54,0x30,0xf0,0x90,0x7f,0x94,0x74,0x30,0xf0,0x90,0x7f,0x9d} },
+{  16,0x0f70,0,{0x74,0xcf,0xf0,0x90,0x7f,0x97,0x74,0xa0,0xf0,0x90,0x7f,0x95,0x74,0xcc,0xf0,0xe4} },
+{  16,0x0f80,0,{0x90,0x7f,0x9e,0xf0,0xc2,0x2d,0xc2,0x2a,0xc2,0x2b,0xc2,0x2e,0x90,0x79,0x74,0x04} },
+{  16,0x0f90,0,{0xf0,0x12,0x2e,0x94,0x12,0x49,0xe2,0x12,0x4b,0xe6,0x12,0x32,0x0d,0x12,0x3b,0x0d} },
+{  16,0x0fa0,0,{0x12,0x41,0xfd,0x12,0x3e,0x99,0xe5,0x1f,0x70,0x18,0x75,0x1f,0x01,0x12,0x17,0xff} },
+{  16,0x0fb0,0,{0x12,0x2f,0xff,0x12,0x49,0xc8,0x12,0x4b,0xd8,0x12,0x4b,0xda,0x12,0x49,0x6f,0x12} },
+{  16,0x0fc0,0,{0x1b,0x40,0x12,0x39,0x8d,0x90,0x7f,0xaf,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xae,0xe0} },
+{  16,0x0fd0,0,{0x44,0x1f,0xf0,0x90,0x7f,0xac,0x74,0xff,0xf0,0x90,0x7f,0xad,0xf0,0x90,0x7f,0xde} },
+{  16,0x0fe0,0,{0xf0,0x90,0x7f,0xdf,0xf0,0x90,0x7f,0xab,0xf0,0x90,0x7f,0xa9,0xf0,0x90,0x7f,0xaa} },
+{  16,0x0ff0,0,{0xf0,0x53,0x91,0xef,0x43,0xd8,0x20,0xd2,0xe8,0x43,0xd8,0x20,0x43,0xa8,0x80,0x22} },
+{  16,0x1000,0,{0x90,0x79,0x63,0xe0,0x14,0x60,0x44,0x14,0x70,0x02,0x21,0xd0,0x14,0x70,0x02,0x41} },
+{  16,0x1010,0,{0xd9,0x14,0x70,0x02,0x61,0xd7,0x24,0x04,0x60,0x02,0x81,0x56,0xe4,0x90,0x79,0x78} },
+{  16,0x1020,0,{0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x54,0xfd,0xf0,0x90} },
+{  16,0x1030,0,{0x79,0x7b,0xf0,0xe4,0x90,0x79,0x88,0xf0,0xa2,0xaf,0x33,0xf5,0x12,0xc2,0xaf,0x12} },
+{  16,0x1040,0,{0x0b,0xa2,0xe5,0x12,0x70,0x02,0x81,0x56,0xd2,0xaf,0x22,0x90,0x79,0x2d,0xe0,0x64} },
+{  16,0x1050,0,{0x01,0x70,0x79,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x30,0xf0,0x90,0x7f,0xff} },
+{  16,0x1060,0,{0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0} },
+{  16,0x1070,0,{0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12} },
+{  16,0x1080,0,{0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90} },
+{  16,0x1090,0,{0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe} },
+{  16,0x10a0,0,{0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x54,0xfd} },
+{  16,0x10b0,0,{0xf0,0x54,0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x04} },
+{  16,0x10c0,0,{0xf0,0x90,0x79,0x88,0x14,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x2d,0xe0} },
+{  16,0x10d0,0,{0x64,0x02,0x70,0x79,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x34,0xf0,0x90,0x7f} },
+{  16,0x10e0,0,{0xff,0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79} },
+{  16,0x10f0,0,{0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5} },
+{  16,0x1100,0,{0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0} },
+{  16,0x1110,0,{0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54} },
+{  16,0x1120,0,{0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44} },
+{  16,0x1130,0,{0x02,0xf0,0x54,0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74} },
+{  16,0x1140,0,{0x04,0xf0,0x90,0x79,0x88,0x14,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x2d} },
+{  16,0x1150,0,{0xe0,0x64,0x03,0x60,0x02,0x81,0x56,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x64} },
+{  16,0x1160,0,{0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0} },
+{  16,0x1170,0,{0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf} },
+{  16,0x1180,0,{0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90} },
+{  16,0x1190,0,{0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79} },
+{  16,0x11a0,0,{0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79} },
+{  16,0x11b0,0,{0x79,0xe0,0x44,0x04,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74} },
+{  16,0x11c0,0,{0x04,0xf0,0x90,0x79,0x88,0x14,0xf0,0xe5,0x12,0x70,0x02,0x81,0x56,0xd2,0xaf,0x22} },
+{  16,0x11d0,0,{0x90,0x79,0x2d,0xe0,0x64,0x01,0x70,0x7a,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74} },
+{  16,0x11e0,0,{0x88,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b} },
+{  16,0x11f0,0,{0xe0,0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x54,0xfd,0xf0,0x90,0x79,0x7b,0xf0,0xa2} },
+{  16,0x1200,0,{0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0} },
+{  16,0x1210,0,{0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90} },
+{  16,0x1220,0,{0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90} },
+{  16,0x1230,0,{0x79,0x79,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2} },
+{  16,0x1240,0,{0x90,0x79,0x82,0x74,0x0c,0xf0,0x90,0x79,0x88,0x74,0x01,0xf0,0xe5,0x12,0x60,0x02} },
+{  16,0x1250,0,{0xd2,0xaf,0x90,0x79,0x2d,0xe0,0x64,0x02,0x60,0x02,0x81,0x56,0x90,0x7f,0xf2,0xf0} },
+{  16,0x1260,0,{0x90,0x7f,0xf3,0x74,0x94,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78} },
+{  16,0x1270,0,{0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x54,0xfd,0xf0,0x90} },
+{  16,0x1280,0,{0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79} },
+{  16,0x1290,0,{0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0} },
+{  16,0x12a0,0,{0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0} },
+{  16,0x12b0,0,{0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x02,0xf0,0x54,0xfb,0xf0,0x90,0x79,0x84} },
+{  16,0x12c0,0,{0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x0c,0xf0,0x90,0x79,0x88,0x74,0x01,0xf0} },
+{  16,0x12d0,0,{0xe5,0x12,0x70,0x02,0x81,0x56,0xd2,0xaf,0x22,0x90,0x79,0x2d,0xe0,0x64,0x01,0x70} },
+{  16,0x12e0,0,{0x77,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0xcc,0xf0,0x90,0x7f,0xff,0x74,0xfc} },
+{  16,0x12f0,0,{0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfc} },
+{  16,0x1300,0,{0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2} },
+{  16,0x1310,0,{0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79} },
+{  16,0x1320,0,{0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79} },
+{  16,0x1330,0,{0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0x90} },
+{  16,0x1340,0,{0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x12,0xf0,0x90,0x79,0x88,0x74} },
+{  16,0x1350,0,{0x02,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x2d,0xe0,0x64,0x02,0x70,0x77} },
+{  16,0x1360,0,{0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0xe0,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0} },
+{  16,0x1370,0,{0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfc,0xf0} },
+{  16,0x1380,0,{0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90} },
+{  16,0x1390,0,{0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f} },
+{  16,0x13a0,0,{0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79} },
+{  16,0x13b0,0,{0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x02,0xf0,0x54,0xfb,0xf0,0x90,0x79} },
+{  16,0x13c0,0,{0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x12,0xf0,0x90,0x79,0x88,0x74,0x02} },
+{  16,0x13d0,0,{0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x2d,0xe0,0x64,0x03,0x70,0x77,0x90} },
+{  16,0x13e0,0,{0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x94,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0xe4} },
+{  16,0x13f0,0,{0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfe,0xf0,0x44} },
+{  16,0x1400,0,{0x02,0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b} },
+{  16,0x1410,0,{0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90} },
+{  16,0x1420,0,{0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90} },
+{  16,0x1430,0,{0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x90,0x79,0x84} },
+{  16,0x1440,0,{0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x06,0xf0,0x90,0x79,0x88,0x74,0x04,0xf0} },
+{   7,0x1450,0,{0xe5,0x12,0x60,0x02,0xd2,0xaf,0x22} },
+{  16,0x1457,0,{0xc2,0x28,0xc2,0x29,0x90,0x7f,0xe8,0xe0,0x12,0x0e,0x1a,0x14,0x84,0x00,0x14,0xe0} },
+{  16,0x1467,0,{0x01,0x14,0xf6,0x02,0x16,0x7c,0x21,0x16,0xbe,0x22,0x15,0x91,0x80,0x15,0xd1,0x81} },
+{  16,0x1477,0,{0x16,0x2e,0x82,0x16,0xcf,0xa1,0x17,0x05,0xa2,0x00,0x00,0x17,0x0a,0x90,0x7f,0xe9} },
+{  16,0x1487,0,{0xe0,0x14,0x60,0x11,0x24,0xfe,0x60,0x28,0x24,0xfe,0x60,0x3b,0x24,0xfc,0x70,0x40} },
+{  16,0x1497,0,{0x12,0x4a,0x2a,0xe1,0x16,0x12,0x4b,0xe0,0x40,0x02,0xe1,0x16,0x90,0x7f,0xea,0xe0} },
+{  16,0x14a7,0,{0xb4,0x01,0x04,0xc2,0x2a,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16} },
+{  16,0x14b7,0,{0x12,0x4b,0xe2,0x90,0x7f,0xea,0xe0,0xb4,0x01,0x04,0xd2,0x2a,0xe1,0x16,0x90,0x7f} },
+{  16,0x14c7,0,{0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16} },
+{  16,0x14d7,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x24,0xf5,0x70} },
+{  16,0x14e7,0,{0x05,0x12,0x47,0x9c,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90} },
+{  16,0x14f7,0,{0x7f,0xe9,0xe0,0x24,0xfd,0x60,0x54,0x24,0x02,0x60,0x02,0xa1,0x88,0x12,0x4b,0xe0} },
+{  16,0x1507,0,{0x40,0x02,0xe1,0x16,0x90,0x7f,0xea,0xe0,0x70,0x38,0x90,0x7f,0xec,0xe0,0xf4,0x54} },
+{  16,0x1517,0,{0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4,0xf5,0x82} },
+{  16,0x1527,0,{0xe4,0x34,0x7f,0xf5,0x83,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0x54,0x80,0xff,0x13,0x13} },
+{  16,0x1537,0,{0x13,0x54,0x1f,0xff,0xe0,0x54,0x07,0x2f,0x90,0x7f,0xd7,0xf0,0xe0,0x44,0x20,0xf0} },
+{  16,0x1547,0,{0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x12,0x4b,0xe2,0x40,0x02} },
+{  16,0x1557,0,{0xe1,0x16,0x90,0x7f,0xea,0xe0,0x70,0x20,0x90,0x7f,0xec,0xe0,0xf4,0x54,0x80,0xff} },
+{  16,0x1567,0,{0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4,0xf5,0x82,0xe4,0x34} },
+{  16,0x1577,0,{0x7f,0xf5,0x83,0x74,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1} },
+{  16,0x1587,0,{0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x60,0x12} },
+{  16,0x1597,0,{0x24,0xf8,0x60,0x09,0x24,0x02,0x70,0x29,0x12,0x17,0x1e,0xe1,0x16,0x12,0x4b,0xa0} },
+{  16,0x15a7,0,{0xe1,0x16,0x12,0x4b,0xde,0xa2,0x2a,0xe4,0x33,0xff,0x25,0xe0,0xff,0xa2,0x2b,0xe4} },
+{  16,0x15b7,0,{0x33,0x4f,0x90,0x7f,0x00,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0xe1} },
+{  16,0x15c7,0,{0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x60,0x37} },
+{  16,0x15d7,0,{0x24,0xf6,0x60,0x2e,0x24,0x04,0x70,0x41,0x90,0x7f,0xeb,0xe0,0x24,0xde,0x60,0x0e} },
+{  16,0x15e7,0,{0x04,0x70,0x16,0xd2,0x29,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0xd2,0x29} },
+{  16,0x15f7,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{  16,0x1607,0,{0xe1,0x16,0x12,0x44,0x63,0xe1,0x16,0x12,0x4b,0xde,0xe4,0x90,0x7f,0x00,0xf0,0xa3} },
+{  16,0x1617,0,{0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0xe1,0x16,0x20,0x29,0x07,0x90,0x7f,0xb4,0xe0} },
+{  16,0x1627,0,{0x44,0x01,0xf0,0xc2,0x29,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x24,0xf4,0x60,0x34,0x24} },
+{  16,0x1637,0,{0x0c,0x70,0x39,0x12,0x4b,0xde,0x90,0x7f,0xec,0xe0,0xf4,0x54,0x80,0xff,0xc4,0x54} },
+{  16,0x1647,0,{0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4,0xf5,0x82,0xe4,0x34,0x7f,0xf5} },
+{  16,0x1657,0,{0x83,0xe0,0x54,0xfd,0x90,0x7f,0x00,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x02} },
+{  16,0x1667,0,{0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0} },
+{  16,0x1677,0,{0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x24,0xf6,0x60,0x12,0x14,0x60,0x1a} },
+{  16,0x1687,0,{0x24,0x02,0x70,0x1d,0xd2,0x28,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x12,0xd2} },
+{  16,0x1697,0,{0x28,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01} },
+{  16,0x16a7,0,{0xf0,0x20,0x28,0x0f,0x90,0x79,0x85,0x74,0x01,0xf0,0x12,0x49,0x6f,0x90,0x7f,0xc5} },
+{  16,0x16b7,0,{0x74,0x02,0xf0,0xc2,0x28,0x80,0x58,0x90,0x79,0x86,0x74,0x01,0xf0,0x12,0x49,0x6f} },
+{  16,0x16c7,0,{0x90,0x7f,0xc5,0x74,0x02,0xf0,0x80,0x47,0x90,0x7f,0xe9,0xe0,0x24,0xfe,0x60,0x12} },
+{  16,0x16d7,0,{0x14,0x60,0x1a,0x24,0x02,0x70,0x1d,0xd2,0x28,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{  16,0x16e7,0,{0x80,0x12,0xd2,0x28,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4} },
+{  16,0x16f7,0,{0xe0,0x44,0x01,0xf0,0x20,0x28,0x03,0x12,0x1a,0x7b,0xc2,0x28,0x80,0x11,0x12,0x2c} },
+{  16,0x1707,0,{0x2b,0x80,0x0c,0x12,0x4b,0xe4,0x50,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x90} },
+{   7,0x1717,0,{0x7f,0xb4,0xe0,0x44,0x02,0xf0,0x22} },
+{  16,0x171e,0,{0x12,0x4b,0xdc,0x40,0x02,0xe1,0xe3,0x90,0x7f,0xeb,0xe0,0x24,0xfe,0x60,0x1e,0x14} },
+{  16,0x172e,0,{0x60,0x46,0x14,0x60,0x6e,0x14,0x70,0x02,0xe1,0xd4,0x24,0x04,0x60,0x02,0xe1,0xdc} },
+{  16,0x173e,0,{0x74,0x05,0x90,0x7f,0xd4,0xf0,0x74,0x00,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f,0xea} },
+{  16,0x174e,0,{0xe0,0xff,0x12,0x3f,0xa2,0x8b,0x33,0x8a,0x34,0x89,0x35,0xea,0x49,0x60,0x11,0xce} },
+{  16,0x175e,0,{0xea,0xce,0xee,0x90,0x7f,0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22} },
+{  16,0x176e,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xff,0x12,0x48,0x00} },
+{  16,0x177e,0,{0x8b,0x33,0x8a,0x34,0x89,0x35,0xea,0x49,0x60,0x11,0xce,0xea,0xce,0xee,0x90,0x7f} },
+{  16,0x178e,0,{0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44} },
+{  16,0x179e,0,{0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xff,0x90,0x7e,0xc0,0xe0,0xfd,0xa3,0xe0,0xfb} },
+{  16,0x17ae,0,{0x12,0x44,0xd2,0x8b,0x33,0x8a,0x34,0x89,0x35,0xea,0x49,0x60,0x11,0xce,0xea,0xce} },
+{  16,0x17be,0,{0xee,0x90,0x7f,0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f} },
+{  16,0x17ce,0,{0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f} },
+{   5,0x17de,0,{0xb4,0xe0,0x44,0x01,0xf0} },
+{   1,0x17e3,0,{0x22} },
+{  16,0x17e4,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x7f,0xc4,0xe4,0xf0,0x53,0x91,0xef,0x90,0x7f} },
+{  11,0x17f4,0,{0xab,0x74,0x04,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{   1,0x17ff,0,{0x22} },
+{  16,0x1800,0,{0xe4,0x90,0x78,0x15,0xf0,0x7b,0x01,0x90,0x78,0x12,0x04,0xf0,0xa3,0x74,0x78,0xf0} },
+{  16,0x1810,0,{0xa3,0x74,0x58,0xf0,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} },
+{  16,0x1820,0,{0x00,0x01,0x12,0x0c,0x5d,0xff,0x90,0x79,0x9a,0xe0,0x6f,0x60,0x18,0x90,0x78,0x15} },
+{  16,0x1830,0,{0xe0,0xc3,0x94,0x06,0x50,0x0f,0xe0,0x04,0xf0,0x90,0x78,0x13,0xe4,0x75,0xf0,0x0f} },
+{  16,0x1840,0,{0x12,0x0c,0xf4,0x80,0xcf,0x90,0x78,0x15,0xe0,0xb4,0x06,0x08,0x90,0x7f,0xb4,0xe0} },
+{  16,0x1850,0,{0x44,0x01,0xf0,0x22,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12} },
+{  16,0x1860,0,{0x0c,0x44,0xff,0x24,0xbf,0x70,0x02,0x41,0x7a,0x24,0xe0,0x70,0x02,0x41,0x4c,0x24} },
+{  16,0x1870,0,{0x21,0x60,0x02,0x41,0x73,0x90,0x79,0x97,0xe0,0x24,0xfe,0x70,0x02,0x21,0x9a,0x14} },
+{  16,0x1880,0,{0x70,0x02,0x21,0xef,0x24,0x02,0x60,0x02,0x41,0x44,0x90,0x79,0x2d,0xe0,0xa3,0xf0} },
+{  16,0x1890,0,{0x90,0x79,0x23,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xfb,0xfa,0x79,0x01,0xf8,0x12,0x0d} },
+{  16,0x18a0,0,{0x42,0xc8,0xec,0xc8,0xc9,0xed,0xc9,0xca,0xee,0xca,0xcb,0xef,0xcb,0x90,0x79,0x22} },
+{  16,0x18b0,0,{0xe0,0xfe,0xe4,0xfc,0xfd,0x2b,0xfb,0xea,0x3e,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8} },
+{  16,0x18c0,0,{0x90,0x79,0x21,0xe0,0xff,0xe4,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd} },
+{  16,0x18d0,0,{0xec,0x38,0xfc,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} },
+{  16,0x18e0,0,{0x02,0x12,0x0d,0xd2,0x90,0x00,0x02,0x12,0x0d,0xa2,0x7b,0x44,0x7a,0xac,0x79,0x00} },
+{  16,0x18f0,0,{0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x05,0x90,0x79,0x2d,0x04,0xf0,0x90,0x78,0x12} },
+{  16,0x1900,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12,0x0d,0xa2,0x7b,0x80} },
+{  16,0x1910,0,{0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x06,0x90,0x79,0x2d,0x74} },
+{  16,0x1920,0,{0x02,0xf0,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02} },
+{  16,0x1930,0,{0x12,0x0d,0xa2,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70} },
+{  16,0x1940,0,{0x06,0x90,0x79,0x2d,0x74,0x03,0xf0,0x90,0x79,0x2d,0xe0,0xff,0xb4,0x01,0x09,0x75} },
+{  16,0x1950,0,{0x0c,0x67,0x75,0x0d,0x06,0x75,0x0e,0x0b,0xef,0xb4,0x02,0x08,0xe4,0xf5,0x0c,0xf5} },
+{  16,0x1960,0,{0x0d,0x75,0x0e,0x0c,0xef,0xb4,0x03,0x08,0xe4,0xf5,0x0c,0xf5,0x0d,0x75,0x0e,0x18} },
+{  16,0x1970,0,{0xef,0xb4,0x03,0x0d,0x90,0x79,0x2e,0xe0,0x64,0x03,0x60,0x05,0xd2,0x2f,0x12,0x3d} },
+{  16,0x1980,0,{0x79,0x90,0x79,0x2d,0xe0,0x64,0x03,0x60,0x0a,0xa3,0xe0,0xb4,0x03,0x05,0xc2,0x2f} },
+{  16,0x1990,0,{0x12,0x3d,0x79,0x12,0x10,0x00,0x12,0x28,0x01,0x22,0x90,0x79,0x23,0xe0,0xff,0xe4} },
+{  16,0x19a0,0,{0xfc,0xfd,0xfe,0xfb,0xfa,0x79,0x01,0xf8,0x12,0x0d,0x42,0xc8,0xec,0xc8,0xc9,0xed} },
+{  16,0x19b0,0,{0xc9,0xca,0xee,0xca,0xcb,0xef,0xcb,0x90,0x79,0x22,0xe0,0xfe,0xe4,0xfc,0xfd,0x2b} },
+{  16,0x19c0,0,{0xfb,0xea,0x3e,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8,0x90,0x79,0x21,0xe0,0xff,0xe4} },
+{  16,0x19d0,0,{0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x78,0x12} },
+{  16,0x19e0,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x06,0x12,0x0d,0xd2,0x22,0x90} },
+{  16,0x19f0,0,{0x79,0x23,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xfb,0xfa,0x79,0x01,0xf8,0x12,0x0d,0x42} },
+{  16,0x1a00,0,{0xc8,0xec,0xc8,0xc9,0xed,0xc9,0xca,0xee,0xca,0xcb,0xef,0xcb,0x90,0x79,0x22,0xe0} },
+{  16,0x1a10,0,{0xfe,0xe4,0xfc,0xfd,0x2b,0xfb,0xea,0x3e,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8,0x90} },
+{  16,0x1a20,0,{0x79,0x21,0xe0,0xff,0xe4,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec} },
+{  16,0x1a30,0,{0x38,0xfc,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x0a} },
+{  16,0x1a40,0,{0x12,0x0d,0xd2,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x97,0xe0} },
+{  16,0x1a50,0,{0x14,0x70,0x18,0x90,0x79,0x21,0xe0,0xff,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa} },
+{  16,0x1a60,0,{0xa3,0xe0,0xf9,0x90,0x00,0x0e,0xef,0x12,0x0c,0x9c,0x22,0x90,0x7f,0xb4,0xe0,0x44} },
+{  10,0x1a70,0,{0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{   1,0x1a7a,0,{0x22} },
+{  16,0x1a7b,0,{0xe4,0xff,0xfe,0x7b,0x01,0x90,0x78,0x0f,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74} },
+{  16,0x1a8b,0,{0x2b,0xf0,0x90,0x78,0x0f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02} },
+{  16,0x1a9b,0,{0x12,0x0c,0x5d,0xfd,0x90,0x7f,0xec,0xe0,0x6d,0x60,0x13,0xef,0xc3,0x94,0x05,0x50} },
+{  16,0x1aab,0,{0x0d,0x0f,0x90,0x78,0x10,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x80,0xd4,0x8d,0x33} },
+{  16,0x1abb,0,{0x90,0x78,0x0f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12,0x0c} },
+{  16,0x1acb,0,{0x5d,0xfd,0x90,0x7f,0xed,0xe0,0x6d,0x60,0x13,0xee,0xc3,0x94,0x0b,0x50,0x0d,0x0e} },
+{  16,0x1adb,0,{0x90,0x78,0x10,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x80,0xd4,0x90,0x7f,0xed,0xe0} },
+{  16,0x1aeb,0,{0xf5,0x34,0xef,0x64,0x05,0x60,0x03,0xbe,0x0b,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01} },
+{  16,0x1afb,0,{0xf0,0x22,0x90,0x78,0x0f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x0c,0x44} },
+{  16,0x1b0b,0,{0xff,0x24,0xf0,0x60,0x08,0x24,0x0f,0x70,0x0e,0x12,0x49,0x2a,0x22,0x12,0x4b,0x83} },
+{  14,0x1b1b,0,{0x90,0x79,0x20,0xe5,0x34,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{   1,0x1b29,0,{0x22} },
+{  15,0x1b2a,0,{0x90,0x7f,0xea,0xe0,0xb4,0xff,0x04,0x12,0x34,0x16,0x22,0x12,0x38,0x00,0x22} },
+{   7,0x1b39,0,{0x53,0x98,0xfe,0x53,0x98,0xfd,0x32} },
+{  16,0x1b40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1b50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1b60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1b70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1b80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1b90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1ba0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1bb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1bc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1bd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1be0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1bf0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1c90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1ca0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1cb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1cc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1cd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1ce0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1cf0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1d90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1da0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1db0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1dc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1dd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1de0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1df0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1e90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1ea0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  14,0x1eb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1ebe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1ece,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1ede,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1eee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1efe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1f0e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1f1e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1f2e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{   2,0x1f3e,0,{0x00,0x00} },
+{  16,0x1f40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1f50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1f60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1f70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1f80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1f90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1fa0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1fb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1fc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1fd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1fe0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x1ff0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2000,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2010,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2020,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2030,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2040,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2050,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2060,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2070,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2080,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2090,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x20a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x20b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x20c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x20d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x20e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x20f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2100,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2110,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2120,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2130,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2140,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2150,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2160,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2170,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2180,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2190,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x21a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x21b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x21c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x21d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x21e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x21f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2200,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2210,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2220,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2230,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2240,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2250,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2260,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2270,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2280,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2290,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x22a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x22b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x22c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x22d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x22e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x22f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2300,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2310,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2320,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2330,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2340,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2350,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x2360,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  14,0x2370,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x237e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x238e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x239e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x23ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x23be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x23ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x23de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x23ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x23fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x240e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x241e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x242e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x243e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x244e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x245e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x246e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x247e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x248e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x249e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x24ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x24be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x24ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x24de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x24ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x24fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x250e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x251e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x252e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x253e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x254e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x255e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x256e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x257e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x258e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x259e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x25ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x25be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x25ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x25de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x25ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x25fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x260e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x261e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x262e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x263e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x264e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x265e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x266e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x267e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x268e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x269e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x26ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x26be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x26ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x26de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  14,0x26ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x26fc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x270c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x271c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x272c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x273c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x274c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x275c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x276c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x277c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x278c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x279c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x27ac,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x27bc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x27cc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x27dc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{  16,0x27ec,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} },
+{   5,0x27fc,0,{0x00,0x00,0x00,0x00,0x22} },
+{  16,0x2801,0,{0x90,0x79,0x64,0xe0,0x14,0x60,0x46,0x14,0x70,0x02,0x41,0x3c,0x24,0x02,0x60,0x02} },
+{  16,0x2811,0,{0x81,0x2a,0x90,0x7f,0xfc,0x74,0xcc,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79} },
+{  16,0x2821,0,{0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfd,0xf0,0x44} },
+{  16,0x2831,0,{0x01,0xf0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b} },
+{  16,0x2841,0,{0xa2,0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x7a,0xf0,0x22,0x90,0x79,0x2d} },
+{  16,0x2851,0,{0xe0,0x64,0x01,0x60,0x02,0x01,0xf1,0x90,0x7f,0xfc,0x74,0xcc,0xf0,0x90,0x7f,0xff} },
+{  16,0x2861,0,{0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79} },
+{  16,0x2871,0,{0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01,0x09,0x90,0x79} },
+{  16,0x2881,0,{0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79} },
+{  16,0x2891,0,{0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b} },
+{  16,0x28a1,0,{0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90} },
+{  16,0x28b1,0,{0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90} },
+{  16,0x28c1,0,{0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0} },
+{  16,0x28d1,0,{0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x7a,0x74,0x01,0xf0,0x90,0x79,0x65} },
+{  16,0x28e1,0,{0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0} },
+{  16,0x28f1,0,{0x90,0x79,0x2d,0xe0,0x64,0x02,0x60,0x02,0x21,0x96,0x90,0x7f,0xfc,0x74,0xc8,0xf0} },
+{  16,0x2901,0,{0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0} },
+{  16,0x2911,0,{0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01} },
+{  16,0x2921,0,{0x09,0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb} },
+{  16,0x2931,0,{0xf0,0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2} },
+{  16,0x2941,0,{0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79} },
+{  16,0x2951,0,{0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0} },
+{  16,0x2961,0,{0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x02,0xf0} },
+{  16,0x2971,0,{0x54,0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x7a,0x74,0x01,0xf0} },
+{  16,0x2981,0,{0x90,0x79,0x65,0x74,0x03,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x8c} },
+{  16,0x2991,0,{0xf0,0x90,0x79,0x8b,0xf0,0x90,0x79,0x2d,0xe0,0x64,0x03,0x60,0x02,0x81,0x2a,0x90} },
+{  16,0x29a1,0,{0x7f,0xfc,0x74,0x98,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01} },
+{  16,0x29b1,0,{0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90} },
+{  16,0x29c1,0,{0x79,0x7e,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90} },
+{  16,0x29d1,0,{0x79,0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf} },
+{  16,0x29e1,0,{0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90} },
+{  16,0x29f1,0,{0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79} },
+{  16,0x2a01,0,{0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79} },
+{  16,0x2a11,0,{0x79,0xe0,0x54,0xfd,0xf0,0x44,0x04,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90} },
+{  16,0x2a21,0,{0x79,0x7a,0x74,0x01,0xf0,0x90,0x79,0x65,0x74,0x05,0xf0,0xe5,0x12,0x60,0x02,0xd2} },
+{  16,0x2a31,0,{0xaf,0xe4,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0,0x22,0x90,0x79,0x2d,0xe0,0x64} },
+{  16,0x2a41,0,{0x01,0x60,0x02,0x41,0xe0,0x90,0x7f,0xfc,0x74,0xb4,0xf0,0x90,0x7f,0xff,0x74,0xfc} },
+{  16,0x2a51,0,{0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x54} },
+{  16,0x2a61,0,{0xfe,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0} },
+{  16,0x2a71,0,{0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79,0x79,0xe0} },
+{  16,0x2a81,0,{0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90} },
+{  16,0x2a91,0,{0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f} },
+{  16,0x2aa1,0,{0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79} },
+{  16,0x2ab1,0,{0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0x90,0x79} },
+{  16,0x2ac1,0,{0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x7a,0x74,0x01,0xf0,0x90,0x79,0x65,0x04,0xf0} },
+{  16,0x2ad1,0,{0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0,0x90} },
+{  16,0x2ae1,0,{0x79,0x2d,0xe0,0x64,0x02,0x60,0x02,0x61,0x85,0x90,0x7f,0xfc,0x74,0xb0,0xf0,0x90} },
+{  16,0x2af1,0,{0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90} },
+{  16,0x2b01,0,{0x79,0x79,0xf0,0x54,0xfe,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01,0x09} },
+{  16,0x2b11,0,{0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0} },
+{  16,0x2b21,0,{0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf} },
+{  16,0x2b31,0,{0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79} },
+{  16,0x2b41,0,{0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80} },
+{  16,0x2b51,0,{0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x02,0xf0,0x54} },
+{  16,0x2b61,0,{0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x7a,0x74,0x01,0xf0,0x90} },
+{  16,0x2b71,0,{0x79,0x65,0x74,0x04,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x8c,0xf0} },
+{  16,0x2b81,0,{0x90,0x79,0x8b,0xf0,0x90,0x79,0x2d,0xe0,0x64,0x03,0x60,0x02,0x81,0x2a,0x90,0x7f} },
+{  16,0x2b91,0,{0xfc,0x74,0x68,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0} },
+{  16,0x2ba1,0,{0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfe,0xf0,0x44,0x02,0xf0,0x90,0x79} },
+{  16,0x2bb1,0,{0x7e,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79} },
+{  16,0x2bc1,0,{0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4} },
+{  16,0x2bd1,0,{0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79} },
+{  16,0x2be1,0,{0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79} },
+{  16,0x2bf1,0,{0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79} },
+{  16,0x2c01,0,{0xe0,0x54,0xfd,0xf0,0x44,0x04,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79} },
+{  16,0x2c11,0,{0x7a,0x74,0x01,0xf0,0x90,0x79,0x65,0x74,0x06,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf} },
+{  10,0x2c21,0,{0xe4,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0,0x22} },
+{  16,0x2c2b,0,{0xe4,0xff,0x7b,0x01,0x90,0x78,0x16,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0x58} },
+{  16,0x2c3b,0,{0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12} },
+{  16,0x2c4b,0,{0x0c,0x5d,0xfe,0x90,0x7f,0xec,0xe0,0x6e,0x60,0x13,0xef,0xc3,0x94,0x06,0x50,0x0d} },
+{  16,0x2c5b,0,{0x0f,0x90,0x78,0x17,0xe4,0x75,0xf0,0x0f,0x12,0x0c,0xf4,0x80,0xd4,0xbf,0x06,0x08} },
+{  16,0x2c6b,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa} },
+{  16,0x2c7b,0,{0xa3,0xe0,0xf9,0x12,0x0c,0x44,0xff,0x24,0x9f,0x70,0x02,0xc1,0x66,0x24,0x21,0x60} },
+{  16,0x2c8b,0,{0x02,0xc1,0x8c,0x90,0x7f,0xe9,0xe0,0x24,0x7e,0x70,0x02,0xa1,0x30,0x14,0x70,0x02} },
+{  16,0x2c9b,0,{0xa1,0xc8,0x24,0x02,0x60,0x02,0xc1,0x5e,0x90,0x00,0x02,0x12,0x0d,0xa2,0x7b,0x44} },
+{  16,0x2cab,0,{0x7a,0xac,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f,0x00,0x74} },
+{  16,0x2cbb,0,{0x44,0xf0,0xa3,0x74,0xac,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90} },
+{  16,0x2ccb,0,{0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12,0x0d,0xa2} },
+{  16,0x2cdb,0,{0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f} },
+{  16,0x2ceb,0,{0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03} },
+{  16,0x2cfb,0,{0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12} },
+{  16,0x2d0b,0,{0x0d,0xa2,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x0d,0x91,0x60,0x02} },
+{  16,0x2d1b,0,{0xc1,0x93,0x90,0x7f,0x00,0xf0,0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x7f} },
+{  16,0x2d2b,0,{0xb5,0x74,0x03,0xf0,0x22,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} },
+{  16,0x2d3b,0,{0x90,0x00,0x06,0x12,0x0d,0xa2,0x7b,0x44,0x7a,0xac,0x79,0x00,0x78,0x00,0xc3,0x12} },
+{  16,0x2d4b,0,{0x0d,0x91,0x70,0x13,0x90,0x7f,0x00,0x74,0x44,0xf0,0xa3,0x74,0xac,0xf0,0xe4,0xa3} },
+{  16,0x2d5b,0,{0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3} },
+{  16,0x2d6b,0,{0xe0,0xf9,0x90,0x00,0x06,0x12,0x0d,0xa2,0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00} },
+{  16,0x2d7b,0,{0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f,0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0} },
+{  16,0x2d8b,0,{0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0} },
+{  16,0x2d9b,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x06,0x12,0x0d,0xa2,0x7b,0x00,0x7a,0x77,0x79,0x01} },
+{  16,0x2dab,0,{0x78,0x00,0xc3,0x12,0x0d,0x91,0x60,0x02,0xc1,0x93,0x90,0x7f,0x00,0xf0,0xa3,0x74} },
+{  16,0x2dbb,0,{0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x22,0x90,0x78,0x16} },
+{  16,0x2dcb,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x0a,0x12,0x0d,0xa2,0x7b,0x44} },
+{  16,0x2ddb,0,{0x7a,0xac,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f,0x00,0x74} },
+{  16,0x2deb,0,{0x44,0xf0,0xa3,0x74,0xac,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90} },
+{  16,0x2dfb,0,{0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x0a,0x12,0x0d,0xa2} },
+{  16,0x2e0b,0,{0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f} },
+{  16,0x2e1b,0,{0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03} },
+{  16,0x2e2b,0,{0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x0a,0x12} },
+{  16,0x2e3b,0,{0x0d,0xa2,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x48} },
+{  16,0x2e4b,0,{0x90,0x7f,0x00,0xf0,0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x7f,0xb5,0x74} },
+{  16,0x2e5b,0,{0x03,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24} },
+{  16,0x2e6b,0,{0x7f,0x70,0x16,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} },
+{  16,0x2e7b,0,{0x0e,0x12,0x0c,0x5d,0x90,0x7f,0x00,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{   8,0x2e8b,0,{0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{   1,0x2e93,0,{0x22} },
+{  16,0x2e94,0,{0x75,0x36,0x25,0x75,0x37,0x24,0x90,0x79,0x74,0xe0,0x64,0x01,0x70,0x54,0xf0,0xf5} },
+{  16,0x2ea4,0,{0x35,0x75,0x22,0x01,0xe5,0x22,0x64,0x01,0x70,0x48,0x90,0x7f,0xa5,0xe0,0x44,0x80} },
+{  16,0x2eb4,0,{0xf0,0x90,0x7f,0xa6,0xe5,0x36,0xf0,0x12,0x46,0xc0,0x74,0x4f,0x25,0x35,0xf5,0x82} },
+{  16,0x2ec4,0,{0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0,0x74,0x35,0x25} },
+{  16,0x2ed4,0,{0x35,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0} },
+{  16,0x2ee4,0,{0x90,0x7f,0xa5,0x74,0x40,0xf0,0x12,0x0a,0xcd,0x05,0x35,0xe5,0x35,0xc3,0x94,0x0d} },
+{  16,0x2ef4,0,{0x40,0xb2,0x90,0x79,0x75,0xe0,0x64,0x01,0x60,0x02,0xe1,0xde,0xf0,0x90,0x79,0x20} },
+{  16,0x2f04,0,{0xe0,0x64,0x05,0x60,0x02,0xe1,0x8d,0x7b,0x01,0x90,0x79,0x5c,0x04,0xf0,0xa3,0x74} },
+{  16,0x2f14,0,{0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x75,0x33,0x07,0x90,0x79,0x5c,0xe0,0xfb,0xa3,0xe0} },
+{  16,0x2f24,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12,0x0c,0x5d,0x70,0x0f,0x90,0x00,0x04,0x12} },
+{  16,0x2f34,0,{0x0c,0x5d,0x90,0x79,0x2f,0xf0,0x12,0x0c,0x29,0x80,0x06,0x90,0x79,0x2f,0x74,0xff} },
+{  16,0x2f44,0,{0xf0,0xe4,0xf5,0x35,0x75,0x22,0x01,0x75,0x34,0x02,0xe5,0x22,0x64,0x01,0x70,0x39} },
+{  16,0x2f54,0,{0x90,0x7f,0xa5,0xe0,0x44,0x80,0xf0,0x90,0x7f,0xa6,0xe5,0x36,0xf0,0x12,0x46,0xc0} },
+{  16,0x2f64,0,{0xaf,0x34,0x05,0x34,0x90,0x7f,0xa6,0xef,0xf0,0x12,0x46,0xc0,0x90,0x79,0x2f,0xe0} },
+{  16,0x2f74,0,{0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0,0x90,0x7f,0xa5,0x74,0x40,0xf0,0x12,0x0a,0xcd} },
+{  16,0x2f84,0,{0x05,0x35,0xe5,0x35,0xc3,0x94,0x06,0x40,0xc1,0x90,0x79,0x20,0xe0,0x64,0x06,0x70} },
+{  16,0x2f94,0,{0x49,0x7b,0x01,0x90,0x79,0x5f,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0} },
+{  16,0x2fa4,0,{0x75,0x33,0x03,0x90,0x79,0x5f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} },
+{  16,0x2fb4,0,{0x01,0x12,0x0c,0x5d,0x70,0x1c,0x90,0x00,0x04,0x12,0x0c,0x5d,0x90,0x79,0x33,0xf0} },
+{  16,0x2fc4,0,{0x70,0x03,0x74,0xff,0xf0,0x90,0x79,0x33,0xe0,0x54,0x7f,0xff,0xf0,0x25,0xe0,0xf0} },
+{  10,0x2fd4,0,{0x80,0x05,0xe4,0x90,0x79,0x33,0xf0,0x12,0x47,0xdf} },
+{   1,0x2fde,0,{0x22} },
+{  16,0x2fdf,0,{0x90,0x79,0x78,0x74,0x03,0xf0,0x90,0x79,0x83,0xe0,0x90,0x79,0x79,0xf0,0xa2,0xaf} },
+{  16,0x2fef,0,{0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x22} },
+{   1,0x2fff,0,{0x22} },
+{  16,0x3000,0,{0xe4,0xfe,0x90,0x79,0x20,0xe0,0xfd,0xb4,0x05,0x11,0x90,0x78,0x25,0x74,0x01,0xf0} },
+{  16,0x3010,0,{0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x75,0x35,0x07,0xed,0xb4,0x06,0x11,0x90} },
+{  16,0x3020,0,{0x78,0x25,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0,0x75,0x35,0x03} },
+{  16,0x3030,0,{0x90,0x7f,0xeb,0xe0,0x14,0x60,0x11,0x14,0x60,0x5b,0x24,0x02,0x60,0x02,0x41,0x05} },
+{  16,0x3040,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0x7f,0x70,0x3d} },
+{  16,0x3050,0,{0xe4,0xff,0xef,0xc3,0x95,0x35,0x50,0x2f,0x90,0x78,0x25,0xe0,0xfb,0xa3,0xe0,0xfa} },
+{  16,0x3060,0,{0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00} },
+{  16,0x3070,0,{0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x78,0x26,0xe4,0x75,0xf0} },
+{  16,0x3080,0,{0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xcb,0x90,0x7f,0xb5,0xee,0xf0,0x22,0x90,0x7f,0xb4} },
+{  16,0x3090,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0x7e,0x60,0x64,0x14,0x70,0x02} },
+{  16,0x30a0,0,{0x21,0x55,0x14,0x70,0x02,0x21,0xa9,0x24,0x03,0x60,0x02,0x21,0xfd,0xe4,0xff,0xef} },
+{  16,0x30b0,0,{0xc3,0x95,0x35,0x50,0x46,0x90,0x78,0x25,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} },
+{  16,0x30c0,0,{0x90,0x00,0x03,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82} },
+{  16,0x30d0,0,{0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x00,0x04,0x12,0x0c,0x5d,0xfd,0xcc,0xee} },
+{  16,0x30e0,0,{0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x78} },
+{  16,0x30f0,0,{0x26,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0x90,0x7f,0xb5,0xee,0xf0} },
+{  16,0x3100,0,{0x22,0xe4,0xff,0xef,0xc3,0x95,0x35,0x50,0x46,0x90,0x78,0x25,0xe0,0xfb,0xa3,0xe0} },
+{  16,0x3110,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x05,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74} },
+{  16,0x3120,0,{0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x00,0x06,0x12,0x0c} },
+{  16,0x3130,0,{0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83} },
+{  16,0x3140,0,{0xed,0xf0,0x90,0x78,0x26,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0x90} },
+{  16,0x3150,0,{0x7f,0xb5,0xee,0xf0,0x22,0xe4,0xff,0xef,0xc3,0x95,0x35,0x50,0x46,0x90,0x78,0x25} },
+{  16,0x3160,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x07,0x12,0x0c,0x5d,0xfd,0xcc} },
+{  16,0x3170,0,{0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90} },
+{  16,0x3180,0,{0x00,0x08,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4} },
+{  16,0x3190,0,{0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x78,0x26,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4} },
+{  16,0x31a0,0,{0x0f,0x80,0xb4,0x90,0x7f,0xb5,0xee,0xf0,0x22,0xe4,0xff,0xef,0xc3,0x95,0x35,0x50} },
+{  16,0x31b0,0,{0x46,0x90,0x78,0x25,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x09,0x12} },
+{  16,0x31c0,0,{0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5} },
+{  16,0x31d0,0,{0x83,0xed,0xf0,0x90,0x00,0x0a,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00} },
+{  16,0x31e0,0,{0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x78,0x26,0xe4,0x75,0xf0} },
+{  16,0x31f0,0,{0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0x90,0x7f,0xb5,0xee,0xf0,0x22,0x90,0x7f,0xb4} },
+{  12,0x3200,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{   1,0x320c,0,{0x22} },
+{  16,0x320d,0,{0x7b,0x01,0x7a,0x78,0x79,0x2b,0x90,0x78,0x00,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9} },
+{  16,0x321d,0,{0xf0,0x74,0x01,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} },
+{  16,0x322d,0,{0xf9,0x90,0x00,0x01,0x74,0x01,0x12,0x0c,0x9c,0x90,0x00,0x02,0xe4,0x12,0x0c,0x9c} },
+{  16,0x323d,0,{0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3} },
+{  16,0x324d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x10,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3} },
+{  16,0x325d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x05,0x12,0x0c,0x9c,0x90,0x00,0x02} },
+{  16,0x326d,0,{0xe4,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78} },
+{  16,0x327d,0,{0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78} },
+{  16,0x328d,0,{0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x02,0x12,0x0c} },
+{  16,0x329d,0,{0x9c,0x90,0x00,0x02,0xe4,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12} },
+{  16,0x32ad,0,{0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x01,0x12} },
+{  16,0x32bd,0,{0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01} },
+{  16,0x32cd,0,{0x74,0x03,0x12,0x0c,0x9c,0x90,0x00,0x02,0xe4,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4} },
+{  16,0x32dd,0,{0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} },
+{  16,0x32ed,0,{0xf9,0x74,0x10,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} },
+{  16,0x32fd,0,{0xf9,0x90,0x00,0x01,0x74,0x06,0x12,0x0c,0x9c,0x90,0x00,0x02,0xe4,0x12,0x0c,0x9c} },
+{  16,0x330d,0,{0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3} },
+{  16,0x331d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3} },
+{  16,0x332d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x04,0x12,0x0c,0x9c,0x90,0x00,0x02} },
+{  16,0x333d,0,{0xe4,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78} },
+{  16,0x334d,0,{0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78} },
+{  16,0x335d,0,{0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x04,0x12,0x0c} },
+{  16,0x336d,0,{0x9c,0x90,0x00,0x02,0x74,0x04,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03} },
+{  16,0x337d,0,{0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02} },
+{  16,0x338d,0,{0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} },
+{  16,0x339d,0,{0x01,0x74,0x03,0x12,0x0c,0x9c,0x90,0x00,0x02,0x74,0x04,0x12,0x0c,0x9c,0x90,0x78} },
+{  16,0x33ad,0,{0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa} },
+{  16,0x33bd,0,{0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa} },
+{  16,0x33cd,0,{0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x02,0x12,0x0c,0x9c,0x90,0x00,0x02,0x74,0x04} },
+{  16,0x33dd,0,{0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00} },
+{  16,0x33ed,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78,0x00} },
+{  16,0x33fd,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x01,0x12,0x0c,0x9c} },
+{   8,0x340d,0,{0x90,0x00,0x02,0x74,0x04,0x12,0x0c,0x9c} },
+{   1,0x3415,0,{0x22} },
+{  16,0x3416,0,{0xe4,0xfe,0x90,0x79,0x20,0xe0,0xfd,0xb4,0x05,0x11,0x90,0x78,0x1f,0x74,0x01,0xf0} },
+{  16,0x3426,0,{0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x75,0x35,0x07,0xed,0xb4,0x06,0x11,0x90} },
+{  16,0x3436,0,{0x78,0x1f,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0,0x75,0x35,0x03} },
+{  16,0x3446,0,{0x90,0x79,0x99,0xe0,0x14,0x60,0x11,0x14,0x60,0x5b,0x24,0x02,0x60,0x02,0xc1,0x06} },
+{  16,0x3456,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x97,0xe0,0x14,0x70,0x3e,0xe4} },
+{  16,0x3466,0,{0xff,0xef,0xc3,0x95,0x35,0x50,0x2f,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82} },
+{  16,0x3476,0,{0xe4,0x34,0x79,0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3} },
+{  16,0x3486,0,{0xe0,0xf9,0x90,0x00,0x01,0xed,0x12,0x0c,0x9c,0x90,0x78,0x20,0xe4,0x75,0xf0,0x0b} },
+{  16,0x3496,0,{0x12,0x0c,0xf4,0x0f,0x80,0xcb,0x90,0x79,0x75,0x74,0x01,0xf0,0x22,0x90,0x7f,0xb4} },
+{  16,0x34a6,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x97,0xe0,0x24,0xfe,0x60,0x63,0x14,0x70,0x02} },
+{  16,0x34b6,0,{0xa1,0x64,0x14,0x70,0x02,0xa1,0xb2,0x24,0x03,0x60,0x02,0xa1,0xfe,0xe4,0xff,0xef} },
+{  16,0x34c6,0,{0xc3,0x95,0x35,0x50,0x44,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34} },
+{  16,0x34d6,0,{0x79,0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} },
+{  16,0x34e6,0,{0x90,0x00,0x03,0xed,0x12,0x0c,0x9c,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82} },
+{  16,0x34f6,0,{0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x00,0x04,0x12,0x0c,0x9c,0x90,0x78,0x20,0xe4} },
+{  16,0x3506,0,{0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb6,0x90,0x79,0x75,0x74,0x01,0xf0,0x22} },
+{  16,0x3516,0,{0xe4,0xff,0xef,0xc3,0x95,0x35,0x40,0x02,0xc1,0x0d,0xcd,0xee,0xcd,0x0e,0x74,0x21} },
+{  16,0x3526,0,{0x2d,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3} },
+{  16,0x3536,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x05,0xed,0x12,0x0c,0x9c,0xcd,0xee,0xcd,0x0e} },
+{  16,0x3546,0,{0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x00,0x06,0x12,0x0c} },
+{  16,0x3556,0,{0x9c,0x90,0x78,0x20,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0xe4,0xff} },
+{  16,0x3566,0,{0xef,0xc3,0x95,0x35,0x40,0x02,0xc1,0x0d,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5} },
+{  16,0x3576,0,{0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3,0xe0,0xfa} },
+{  16,0x3586,0,{0xa3,0xe0,0xf9,0x90,0x00,0x07,0xed,0x12,0x0c,0x9c,0xcd,0xee,0xcd,0x0e,0x74,0x21} },
+{  16,0x3596,0,{0x2d,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x00,0x08,0x12,0x0c,0x9c,0x90} },
+{  16,0x35a6,0,{0x78,0x20,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0xe4,0xff,0xef,0xc3} },
+{  16,0x35b6,0,{0x95,0x35,0x50,0x53,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0x79} },
+{  16,0x35c6,0,{0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} },
+{  16,0x35d6,0,{0x00,0x09,0xed,0x12,0x0c,0x9c,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82,0xe4} },
+{  16,0x35e6,0,{0x34,0x79,0xf5,0x83,0xe0,0x90,0x00,0x0a,0x12,0x0c,0x9c,0x90,0x78,0x20,0xe4,0x75} },
+{  16,0x35f6,0,{0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb6,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22} },
+{   7,0x3606,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{   1,0x360d,0,{0x22} },
+{  16,0x360e,0,{0xe4,0xfe,0x90,0x79,0x20,0xe0,0xfd,0xb4,0x05,0x10,0x90,0x78,0x28,0x74,0x01,0xf0} },
+{  16,0x361e,0,{0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x7f,0x07,0xed,0xb4,0x06,0x10,0x90,0x78} },
+{  16,0x362e,0,{0x28,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0,0x7f,0x03,0x90,0x78} },
+{  16,0x363e,0,{0x28,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x0c,0x44,0xfd,0x90,0x7f,0xea} },
+{  16,0x364e,0,{0xe0,0x6d,0x60,0x12,0xee,0xc3,0x9f,0x50,0x0d,0x90,0x78,0x29,0xe4,0x75,0xf0,0x0b} },
+{  16,0x365e,0,{0x12,0x0c,0xf4,0x0e,0x80,0xd8,0x90,0x7f,0xeb,0xe0,0x14,0x60,0x11,0x14,0x60,0x46} },
+{  16,0x366e,0,{0x24,0x02,0x60,0x02,0xe1,0x9a,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f} },
+{  16,0x367e,0,{0xe9,0xe0,0x24,0x7f,0x70,0x28,0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01} },
+{  16,0x368e,0,{0xf0,0x22,0x90,0x78,0x28,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01} },
+{  16,0x369e,0,{0x12,0x0c,0x5d,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x22,0x90,0x7f} },
+{  16,0x36ae,0,{0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0x7e,0x60,0x40,0x14,0x60} },
+{  16,0x36be,0,{0x6f,0x14,0x70,0x02,0xe1,0x60,0x24,0x03,0x60,0x02,0xe1,0x92,0xee,0x6f,0x70,0x08} },
+{  16,0x36ce,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x28,0xe0,0xfb,0xa3,0xe0,0xfa} },
+{  16,0x36de,0,{0xa3,0xe0,0xf9,0x90,0x00,0x03,0x12,0x0c,0x5d,0x90,0x7f,0x00,0xf0,0x90,0x00,0x04} },
+{  16,0x36ee,0,{0x12,0x0c,0x5d,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22,0xee,0x6f} },
+{  16,0x36fe,0,{0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x28,0xe0,0xfb,0xa3} },
+{  16,0x370e,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x05,0x12,0x0c,0x5d,0x90,0x7f,0x00,0xf0,0x90} },
+{  16,0x371e,0,{0x00,0x06,0x12,0x0c,0x5d,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22} },
+{  16,0x372e,0,{0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x28,0xe0} },
+{  16,0x373e,0,{0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x07,0x12,0x0c,0x5d,0x90,0x7f,0x00} },
+{  16,0x374e,0,{0xf0,0x90,0x00,0x08,0x12,0x0c,0x5d,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02} },
+{  16,0x375e,0,{0xf0,0x22,0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78} },
+{  16,0x376e,0,{0x28,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x09,0x12,0x0c,0x5d,0x90} },
+{  16,0x377e,0,{0x7f,0x00,0xf0,0x90,0x00,0x0a,0x12,0x0c,0x5d,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5} },
+{  16,0x378e,0,{0x74,0x02,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0} },
+{   3,0x379e,0,{0x44,0x01,0xf0} },
+{   1,0x37a1,0,{0x22} },
+{  16,0x37a2,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0} },
+{  16,0x37b2,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef} },
+{  16,0x37c2,0,{0xc0,0xe0,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0x90,0x79,0x83,0xe0,0x54} },
+{  16,0x37d2,0,{0xfd,0xf0,0x12,0x2f,0xdf,0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0} },
+{  16,0x37e2,0,{0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0} },
+{   8,0x37f2,0,{0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0,0x32} },
+{   6,0x37fa,0,{0x53,0x91,0xbf,0xd2,0x26,0x32} },
+{  16,0x3800,0,{0xe4,0xfe,0x90,0x79,0x20,0xe0,0xfd,0xb4,0x05,0x10,0x90,0x78,0x22,0x74,0x01,0xf0} },
+{  16,0x3810,0,{0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x7f,0x07,0xed,0xb4,0x06,0x10,0x90,0x78} },
+{  16,0x3820,0,{0x22,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0,0x7f,0x03,0x90,0x78} },
+{  16,0x3830,0,{0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x0c,0x44,0xfd,0x90,0x79,0x98} },
+{  16,0x3840,0,{0xe0,0x6d,0x60,0x12,0xee,0xc3,0x9f,0x50,0x0d,0x90,0x78,0x23,0xe4,0x75,0xf0,0x0b} },
+{  16,0x3850,0,{0x12,0x0c,0xf4,0x0e,0x80,0xd8,0x90,0x79,0x99,0xe0,0x14,0x60,0x11,0x14,0x60,0x48} },
+{  16,0x3860,0,{0x24,0x02,0x60,0x02,0x21,0x85,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79} },
+{  16,0x3870,0,{0x97,0xe0,0x14,0x70,0x2b,0xee,0x6f,0x70,0x09,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{  16,0x3880,0,{0x80,0x17,0x90,0x79,0x21,0xe0,0xfd,0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3} },
+{  16,0x3890,0,{0xe0,0xf9,0x90,0x00,0x01,0xed,0x12,0x0c,0x9c,0x90,0x79,0x75,0x74,0x01,0xf0,0x22} },
+{  16,0x38a0,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x97,0xe0,0x24,0xfe,0x60,0x43} },
+{  16,0x38b0,0,{0x14,0x60,0x6e,0x14,0x70,0x02,0x21,0x4f,0x24,0x03,0x60,0x02,0x21,0x7d,0xee,0x6f} },
+{  16,0x38c0,0,{0x70,0x09,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x21,0x90,0x79,0x21,0xe0,0xfd} },
+{  16,0x38d0,0,{0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x03,0xed,0x12} },
+{  16,0x38e0,0,{0x0c,0x9c,0x90,0x79,0x22,0xe0,0x90,0x00,0x04,0x12,0x0c,0x9c,0x90,0x79,0x75,0x74} },
+{  16,0x38f0,0,{0x01,0xf0,0x22,0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90} },
+{  16,0x3900,0,{0x79,0x21,0xe0,0xfd,0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} },
+{  16,0x3910,0,{0x00,0x05,0xed,0x12,0x0c,0x9c,0x90,0x79,0x22,0xe0,0x90,0x00,0x06,0x12,0x0c,0x9c} },
+{  16,0x3920,0,{0x22,0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x21} },
+{  16,0x3930,0,{0xe0,0xfd,0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x07} },
+{  16,0x3940,0,{0xed,0x12,0x0c,0x9c,0x90,0x79,0x22,0xe0,0x90,0x00,0x08,0x12,0x0c,0x9c,0x22,0xee} },
+{  16,0x3950,0,{0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x21,0xe0,0xfe} },
+{  16,0x3960,0,{0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x09,0xee,0x12} },
+{  16,0x3970,0,{0x0c,0x9c,0x90,0x79,0x22,0xe0,0x90,0x00,0x0a,0x12,0x0c,0x9c,0x22,0x90,0x7f,0xb4} },
+{  12,0x3980,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{   1,0x398c,0,{0x22} },
+{  16,0x398d,0,{0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xe4,0x90,0x79,0x83,0xf0,0x12,0x2f,0xdf,0x90,0x7f} },
+{  16,0x399d,0,{0xe0,0x74,0x90,0xf0,0x90,0x7f,0xe1,0x74,0x04,0xf0,0xe4,0x90,0x7f,0xdd,0xf0,0x90} },
+{  16,0x39ad,0,{0x7f,0xa1,0xf0,0x53,0x8e,0xf8,0x75,0x88,0x05,0x75,0xb8,0x20,0x75,0xf8,0x01,0x43} },
+{  16,0x39bd,0,{0x8e,0x30,0xf5,0xc8,0x75,0xca,0x7f,0x75,0xcb,0xf8,0x43,0xa8,0x20,0x90,0x79,0x74} },
+{  16,0x39cd,0,{0x04,0xf0,0xc2,0x22,0xe4,0xf5,0x0f,0x90,0x79,0x78,0xf0,0xa3,0xf0,0x90,0x79,0x62} },
+{  16,0x39dd,0,{0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x79,0x66,0xf0,0xa3,0xf0,0x90,0x79,0x7b,0xf0,0xa3} },
+{  16,0x39ed,0,{0xf0,0x90,0x79,0x84,0xf0,0x90,0x79,0x7d,0xf0,0x90,0x79,0x75,0xf0,0xa3,0xf0,0xa3} },
+{  16,0x39fd,0,{0xf0,0xc2,0x23,0xc2,0x24,0xc2,0x25,0xc2,0x26,0xc2,0x20,0x90,0x7f,0x9b,0xe0,0xf5} },
+{  16,0x3a0d,0,{0x0a,0x54,0x20,0xf5,0x0a,0x70,0x06,0x90,0x79,0x7e,0xf0,0x80,0x06,0x90,0x79,0x7e} },
+{  16,0x3a1d,0,{0x74,0x01,0xf0,0x90,0x7f,0x9b,0xe0,0xf5,0x0a,0x54,0x02,0xf5,0x0a,0x70,0x06,0x90} },
+{  16,0x3a2d,0,{0x79,0x7f,0xf0,0x80,0x06,0x90,0x79,0x7f,0x74,0x01,0xf0,0x90,0x79,0x78,0x74,0x02} },
+{  16,0x3a3d,0,{0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09} },
+{  16,0x3a4d,0,{0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0} },
+{  16,0x3a5d,0,{0x90,0x79,0x79,0xe0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x01} },
+{  16,0x3a6d,0,{0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01,0x09} },
+{  16,0x3a7d,0,{0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0} },
+{  16,0x3a8d,0,{0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0x12,0x0b,0xa2,0xe4,0x90,0x79,0x78,0xf0} },
+{  16,0x3a9d,0,{0xa3,0x04,0xf0,0xe4,0x90,0x79,0x88,0xf0,0x12,0x0b,0xa2,0x90,0x7f,0xfc,0x74,0xdd} },
+{  16,0x3aad,0,{0xf0,0x90,0x7f,0xff,0x74,0xff,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0xa3,0xf0,0x12} },
+{  16,0x3abd,0,{0x0b,0xa2,0xe4,0x90,0x79,0x7a,0xf0,0x90,0x79,0x83,0x04,0xf0,0x12,0x2f,0xdf,0xe4} },
+{  16,0x3acd,0,{0x90,0x79,0x30,0xf0,0x90,0x79,0x85,0xf0,0xa3,0xf0,0xa3,0xf0,0x12,0x2e,0x94,0x90} },
+{  16,0x3add,0,{0x79,0x2d,0x74,0x02,0xf0,0x90,0x79,0x88,0x14,0xf0,0xc2,0x2f,0xe4,0x90,0x79,0x68} },
+{  16,0x3aed,0,{0xf0,0x90,0x79,0x8a,0xf0,0x90,0x79,0x6a,0xf0,0xa3,0xf0,0x75,0x13,0x08,0x75,0x14} },
+{  16,0x3afd,0,{0x08,0xf5,0x16,0xf5,0x15,0xf5,0x17,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0,0x22} },
+{  16,0x3b0d,0,{0x7b,0x01,0x7a,0x78,0x79,0x58,0x90,0x78,0x03,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9} },
+{  16,0x3b1d,0,{0xf0,0x74,0x40,0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} },
+{  16,0x3b2d,0,{0xf9,0x90,0x00,0x01,0x74,0x0a,0x12,0x0c,0x9c,0x90,0x00,0x02,0x12,0x0d,0xf6,0x00} },
+{  16,0x3b3d,0,{0x00,0xbb,0x80,0x90,0x00,0x06,0x12,0x0d,0xf6,0x00,0x00,0xac,0x44,0x90,0x00,0x0a} },
+{  16,0x3b4d,0,{0x12,0x0d,0xf6,0x00,0x01,0x77,0x00,0x90,0x78,0x04,0xe4,0x75,0xf0,0x0f,0x12,0x0c} },
+{  16,0x3b5d,0,{0xf4,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x40,0x12,0x0c} },
+{  16,0x3b6d,0,{0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74} },
+{  16,0x3b7d,0,{0x8c,0x12,0x0c,0x9c,0x90,0x00,0x02,0x12,0x0d,0xf6,0x00,0x00,0xbb,0x80,0x90,0x00} },
+{  16,0x3b8d,0,{0x06,0x12,0x0d,0xf6,0x00,0x00,0xac,0x44,0x90,0x00,0x0a,0x12,0x0d,0xf6,0x00,0x01} },
+{  16,0x3b9d,0,{0x77,0x00,0x90,0x78,0x04,0xe4,0x75,0xf0,0x0f,0x12,0x0c,0xf4,0x90,0x78,0x03,0xe0} },
+{  16,0x3bad,0,{0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x40,0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0} },
+{  16,0x3bbd,0,{0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x8f,0x12,0x0c,0x9c,0x90} },
+{  16,0x3bcd,0,{0x78,0x04,0xe4,0x75,0xf0,0x0f,0x12,0x0c,0xf4,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0} },
+{  16,0x3bdd,0,{0xfa,0xa3,0xe0,0xf9,0x74,0x41,0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0} },
+{  16,0x3bed,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x84,0x12,0x0c,0x9c,0x90,0x78,0x04,0xe4} },
+{  16,0x3bfd,0,{0x75,0xf0,0x0f,0x12,0x0c,0xf4,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} },
+{  16,0x3c0d,0,{0xf9,0x74,0x61,0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} },
+{  16,0x3c1d,0,{0xf9,0x90,0x00,0x01,0x74,0x81,0x12,0x0c,0x9c,0x90,0x78,0x04,0xe4,0x75,0xf0,0x0f} },
+{  16,0x3c2d,0,{0x12,0x0c,0xf4,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x61} },
+{  16,0x3c3d,0,{0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} },
+{   6,0x3c4d,0,{0x01,0x74,0x01,0x12,0x0c,0x9c} },
+{   1,0x3c53,0,{0x22} },
+{  16,0x3c54,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0} },
+{  16,0x3c64,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef} },
+{   2,0x3c74,0,{0xc0,0xe0} },
+{  16,0x3c76,0,{0x90,0x7f,0xa2,0xe0,0xf5,0x0b,0x90,0x7f,0x74,0xe0,0x90,0x79,0x70,0xf0,0x90,0x7f} },
+{  16,0x3c86,0,{0x75,0xe0,0x90,0x79,0x71,0xf0,0x90,0x79,0x83,0xe0,0xff,0xfe,0x54,0x02,0xfe,0x70} },
+{  16,0x3c96,0,{0x0d,0xef,0x44,0x02,0xf0,0x12,0x2f,0xdf,0x90,0x79,0x74,0x74,0x01,0xf0,0xe5,0x0b} },
+{  16,0x3ca6,0,{0x20,0xe2,0x28,0x90,0x79,0x70,0xe0,0xfe,0xa3,0xe0,0x7c,0x00,0x24,0x00,0xf5,0x11} },
+{  16,0x3cb6,0,{0xec,0x3e,0xf5,0x10,0x90,0x79,0x82,0xe0,0xfd,0xae,0x10,0xaf,0x11,0x12,0x0c,0xbe} },
+{  16,0x3cc6,0,{0x90,0x79,0x70,0xef,0xf0,0x90,0x79,0x89,0x74,0x01,0xf0,0x12,0x48,0x43,0x12,0x48} },
+{  16,0x3cd6,0,{0x76,0x90,0x79,0x89,0xe0,0x64,0x01,0x70,0x32,0x12,0x41,0x08,0x90,0x79,0x89,0xe4} },
+{  16,0x3ce6,0,{0xf0,0x90,0x7f,0x98,0xe0,0x44,0x40,0xf0,0x90,0x7f,0x9e,0xe0,0x44,0x40,0xf0,0x90} },
+{  16,0x3cf6,0,{0x7f,0x95,0x74,0x80,0xf0,0x75,0xe8,0x01,0x12,0x09,0x32,0x75,0xe8,0x0d,0x90,0x7f} },
+{  16,0x3d06,0,{0x95,0x74,0xc0,0xf0,0x75,0xe8,0x0d,0xd2,0x20,0x80,0x05,0x75,0xe8,0x01,0xc2,0x20} },
+{  16,0x3d16,0,{0x20,0x20,0x2b,0x90,0x79,0x2d,0xe0,0xff,0xb4,0x01,0x09,0x75,0x0c,0x67,0x75,0x0d} },
+{  16,0x3d26,0,{0x06,0x75,0x0e,0x0b,0xef,0xb4,0x02,0x09,0x75,0x0c,0x00,0x75,0x0d,0x00,0x75,0x0e} },
+{  16,0x3d36,0,{0x0c,0xef,0xb4,0x03,0x09,0x75,0x0c,0x00,0x75,0x0d,0x00,0x75,0x0e,0x18,0x75,0xca} },
+{  16,0x3d46,0,{0x6f,0x75,0xcb,0xfe,0xd2,0xca,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xf0} },
+{  16,0x3d56,0,{0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0} },
+{  16,0x3d66,0,{0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xf0} },
+{   3,0x3d76,0,{0xd0,0xe0,0x32} },
+{  16,0x3d79,0,{0x75,0x33,0x25,0x75,0x34,0x24,0x90,0x79,0x5c,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0} },
+{  16,0x3d89,0,{0xa3,0x74,0xb2,0xf0,0x20,0x2f,0x02,0xc1,0x17,0xe4,0xf5,0x35,0x75,0x22,0x01,0x90} },
+{  16,0x3d99,0,{0x79,0x5c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x04,0x12,0x0c,0x5d} },
+{  16,0x3da9,0,{0xf5,0x36,0x75,0x35,0x06,0x74,0x42,0x25,0x35,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83} },
+{  16,0x3db9,0,{0xe5,0x36,0xf0,0x05,0x35,0xe5,0x35,0xb4,0x0c,0xeb,0xe5,0x35,0xc3,0x94,0x0d,0x40} },
+{  16,0x3dc9,0,{0x02,0xc1,0x98,0xe5,0x22,0x64,0x01,0x60,0x02,0xc1,0x98,0x90,0x7f,0xa5,0xe0,0x44} },
+{  16,0x3dd9,0,{0x80,0xf0,0x90,0x7f,0xa6,0xe5,0x33,0xf0,0x12,0x46,0xc0,0x74,0x4f,0x25,0x35,0xf5} },
+{  16,0x3de9,0,{0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0,0x74,0x42} },
+{  16,0x3df9,0,{0x25,0x35,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46} },
+{  16,0x3e09,0,{0xc0,0x90,0x7f,0xa5,0x74,0x40,0xf0,0x12,0x0a,0xcd,0x05,0x35,0x80,0xac,0xe4,0xf5} },
+{  16,0x3e19,0,{0x35,0x75,0x22,0x01,0x90,0x79,0x5c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} },
+{  16,0x3e29,0,{0x00,0x04,0x12,0x0c,0x5d,0xf5,0x36,0x75,0x35,0x06,0x74,0x35,0x25,0x35,0xf5,0x82} },
+{  16,0x3e39,0,{0xe4,0x34,0x79,0xf5,0x83,0xe5,0x36,0xf0,0x05,0x35,0xe5,0x35,0xb4,0x0c,0xeb,0xe5} },
+{  16,0x3e49,0,{0x35,0xc3,0x94,0x0d,0x50,0x49,0xe5,0x22,0x64,0x01,0x70,0x43,0x90,0x7f,0xa5,0xe0} },
+{  16,0x3e59,0,{0x44,0x80,0xf0,0x90,0x7f,0xa6,0xe5,0x33,0xf0,0x12,0x46,0xc0,0x74,0x4f,0x25,0x35} },
+{  16,0x3e69,0,{0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0,0x74} },
+{  16,0x3e79,0,{0x35,0x25,0x35,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12} },
+{  15,0x3e89,0,{0x46,0xc0,0x90,0x7f,0xa5,0x74,0x40,0xf0,0x12,0x0a,0xcd,0x05,0x35,0x80,0xb0} },
+{   1,0x3e98,0,{0x22} },
+{  16,0x3e99,0,{0x90,0x78,0x09,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0xe4,0xff} },
+{  16,0x3ea9,0,{0xfe,0x90,0x78,0x09,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xef,0x12,0x0c,0x8a} },
+{  16,0x3eb9,0,{0x90,0x78,0x09,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0xe4,0x12} },
+{  16,0x3ec9,0,{0x0c,0x9c,0x90,0x00,0x02,0x74,0x15,0x12,0x0c,0x9c,0x90,0x00,0x03,0xe4,0x12,0x0c} },
+{  16,0x3ed9,0,{0x9c,0x90,0x00,0x04,0x74,0xff,0x12,0x0c,0x9c,0x90,0x00,0x05,0xe4,0x12,0x0c,0x9c} },
+{  16,0x3ee9,0,{0x90,0x00,0x06,0x74,0xc3,0x12,0x0c,0x9c,0x90,0x00,0x07,0xe4,0x12,0x0c,0x9c,0x90} },
+{  16,0x3ef9,0,{0x00,0x08,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x09,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x0a} },
+{  16,0x3f09,0,{0x74,0x01,0x12,0x0c,0x9c,0x90,0x78,0x0a,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f} },
+{  16,0x3f19,0,{0x0e,0xbe,0x07,0x8d,0x90,0x78,0x09,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74} },
+{  16,0x3f29,0,{0xff,0xf0,0xe4,0xff,0xfe,0x90,0x78,0x09,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} },
+{  16,0x3f39,0,{0xef,0x12,0x0c,0x8a,0x90,0x78,0x09,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} },
+{  16,0x3f49,0,{0x00,0x01,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x02,0x74,0x15,0x12,0x0c,0x9c,0x90,0x00} },
+{  16,0x3f59,0,{0x03,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x04,0x74,0x80,0x12,0x0c,0x9c,0x90,0x00,0x05} },
+{  16,0x3f69,0,{0xe4,0x12,0x0c,0x9c,0x90,0x00,0x06,0x74,0xc3,0x12,0x0c,0x9c,0x90,0x00,0x07,0xe4} },
+{  16,0x3f79,0,{0x12,0x0c,0x9c,0x90,0x00,0x08,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x09,0xe4,0x12,0x0c} },
+{  16,0x3f89,0,{0x9c,0x90,0x00,0x0a,0x74,0x01,0x12,0x0c,0x9c,0x90,0x78,0x0a,0xe4,0x75,0xf0,0x0b} },
+{   8,0x3f99,0,{0x12,0x0c,0xf4,0x0f,0x0e,0xbe,0x03,0x8d} },
+{   1,0x3fa1,0,{0x22} },
+{  16,0x3fa2,0,{0xe4,0xfe,0x75,0x3d,0xff,0x75,0x3e,0x05,0x75,0x3f,0x12,0xab,0x3d,0xaa,0x3e,0xa9} },
+{  16,0x3fb2,0,{0x3f,0x90,0x00,0x01,0x12,0x0c,0x5d,0x64,0x02,0x70,0x2f,0xcd,0xee,0xcd,0x0e,0xed} },
+{  16,0x3fc2,0,{0x6f,0x70,0x01,0x22,0x90,0x00,0x02,0x12,0x0d,0x0a,0x85,0xf0,0x3b,0xf5,0x3c,0x62} },
+{  16,0x3fd2,0,{0x3b,0xe5,0x3b,0x62,0x3c,0xe5,0x3c,0x62,0x3b,0x29,0xfd,0xe5,0x3b,0x3a,0xc9,0xed} },
+{  16,0x3fe2,0,{0xc9,0x75,0x3d,0xff,0xf5,0x3e,0x89,0x3f,0x80,0xc1,0x7b,0x00,0x7a,0x00,0x79,0x00} },
+{   1,0x3ff2,0,{0x22} },
+{   9,0x3ff3,0,{0x53,0xd8,0xef,0x43,0xd8,0x20,0xc2,0x2d,0x32} },
+{   4,0x3ffc,0,{0x53,0x91,0xdf,0x32} },
+{  16,0x4000,0,{0x90,0x79,0x87,0xe0,0xb4,0x01,0x1d,0x90,0x79,0x85,0xe0,0xb4,0x01,0x03,0x12,0x42} },
+{  16,0x4010,0,{0xaa,0x90,0x79,0x86,0xe0,0xb4,0x01,0x03,0x12,0x18,0x00,0xe4,0x90,0x79,0x85,0xf0} },
+{  16,0x4020,0,{0xa3,0xf0,0xa3,0xf0,0x12,0x2e,0x94,0x90,0x7f,0x9b,0xe0,0xf5,0x0a,0x54,0x02,0xf5} },
+{  16,0x4030,0,{0x0a,0x70,0x04,0x90,0x79,0x7f,0xf0,0x90,0x7f,0x9b,0xe0,0xf5,0x0a,0x54,0x02,0xff} },
+{  16,0x4040,0,{0xf5,0x0a,0xbf,0x02,0x06,0x90,0x79,0x7f,0x74,0x01,0xf0,0x90,0x7f,0x9b,0xe0,0xf5} },
+{  16,0x4050,0,{0x0a,0x54,0x20,0xf5,0x0a,0x70,0x04,0x90,0x79,0x7e,0xf0,0x90,0x7f,0x9b,0xe0,0xf5} },
+{  16,0x4060,0,{0x0a,0x54,0x20,0xff,0xf5,0x0a,0xbf,0x20,0x06,0x90,0x79,0x7e,0x74,0x01,0xf0,0x90} },
+{  16,0x4070,0,{0x79,0x7f,0xe0,0xff,0x90,0x79,0x81,0xe0,0x6f,0x60,0x38,0x90,0x79,0x78,0x74,0x02} },
+{  16,0x4080,0,{0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0xef,0xb4,0x01,0x06,0xe0,0x54,0xfe} },
+{  16,0x4090,0,{0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x90,0x79} },
+{  16,0x40a0,0,{0x84,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0xe5,0x12,0x60} },
+{  16,0x40b0,0,{0x02,0xd2,0xaf,0x90,0x79,0x7e,0xe0,0xff,0x90,0x79,0x80,0xe0,0x6f,0x60,0x38,0x90} },
+{  16,0x40c0,0,{0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0xef,0xb4,0x01} },
+{  16,0x40d0,0,{0x06,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79} },
+{  16,0x40e0,0,{0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b} },
+{  16,0x40f0,0,{0xa2,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x7f,0xe0,0x90,0x79,0x81,0xf0,0x90} },
+{   8,0x4100,0,{0x79,0x7e,0xe0,0x90,0x79,0x80,0xf0,0x22} },
+{  16,0x4108,0,{0x90,0x79,0x2d,0xe0,0x64,0x01,0x70,0x35,0x90,0x79,0x70,0xe0,0xff,0xd3,0x94,0x2d} },
+{  16,0x4118,0,{0x40,0x2b,0x90,0x79,0x69,0x74,0x01,0xf0,0x90,0x79,0x68,0xe0,0x04,0xf0,0xe0,0xd3} },
+{  16,0x4128,0,{0x94,0x0f,0x40,0x19,0xe4,0xf0,0xef,0xd3,0x94,0x31,0x40,0x08,0x90,0x79,0x2d,0x74} },
+{  16,0x4138,0,{0x03,0xf0,0x80,0x06,0x90,0x79,0x2d,0x74,0x02,0xf0,0x12,0x10,0x00,0x90,0x79,0x2d} },
+{  16,0x4148,0,{0xe0,0xb4,0x02,0x2c,0x90,0x79,0x70,0xe0,0xff,0xc3,0x94,0x2f,0x50,0x22,0xef,0xd3} },
+{  16,0x4158,0,{0x94,0x2a,0x40,0x1c,0x90,0x79,0x69,0x74,0x01,0xf0,0x90,0x79,0x68,0xe0,0x04,0xf0} },
+{  16,0x4168,0,{0xe0,0xd3,0x94,0x0f,0x40,0x0a,0xe4,0xf0,0x90,0x79,0x2d,0x04,0xf0,0x12,0x10,0x00} },
+{  16,0x4178,0,{0x90,0x79,0x2d,0xe0,0xb4,0x02,0x26,0x90,0x79,0x70,0xe0,0xd3,0x94,0x31,0x40,0x1d} },
+{  16,0x4188,0,{0x90,0x79,0x69,0x74,0x01,0xf0,0x90,0x79,0x68,0xe0,0x04,0xf0,0xe0,0xd3,0x94,0x0f} },
+{  16,0x4198,0,{0x40,0x0b,0xe4,0xf0,0x90,0x79,0x2d,0x74,0x03,0xf0,0x12,0x10,0x00,0x90,0x79,0x2d} },
+{  16,0x41a8,0,{0xe0,0x64,0x03,0x70,0x3f,0x90,0x79,0x70,0xe0,0xff,0xc3,0x94,0x5f,0x50,0x35,0x90} },
+{  16,0x41b8,0,{0x79,0x69,0x74,0x01,0xf0,0x90,0x79,0x68,0xe0,0x04,0xf0,0xe0,0xd3,0x94,0x0f,0x40} },
+{  16,0x41c8,0,{0x23,0xe4,0xf0,0xef,0xc3,0x94,0x2f,0x50,0x0c,0xef,0xd3,0x94,0x2a,0x40,0x06,0x90} },
+{  16,0x41d8,0,{0x79,0x2d,0x74,0x01,0xf0,0xef,0xd3,0x94,0x2f,0x40,0x06,0x90,0x79,0x2d,0x74,0x02} },
+{  16,0x41e8,0,{0xf0,0x12,0x10,0x00,0x90,0x79,0x69,0xe0,0x70,0x05,0x90,0x79,0x68,0xf0,0x22,0xe4} },
+{   5,0x41f8,0,{0x90,0x79,0x69,0xf0,0x22} },
+{  16,0x41fd,0,{0x7b,0x01,0x7a,0x78,0x79,0x4c,0x90,0x78,0x06,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9} },
+{  16,0x420d,0,{0xf0,0xe4,0x12,0x0c,0x8a,0x90,0x78,0x06,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} },
+{  16,0x421d,0,{0x90,0x00,0x01,0x74,0x01,0x12,0x0c,0x9c,0x90,0x78,0x07,0xe4,0x75,0xf0,0x03,0x12} },
+{  16,0x422d,0,{0x0c,0xf4,0x90,0x78,0x06,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xe4,0x12,0x0c} },
+{  16,0x423d,0,{0x8a,0x90,0x78,0x06,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74} },
+{  16,0x424d,0,{0x02,0x12,0x0c,0x9c,0x90,0x78,0x07,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78} },
+{  16,0x425d,0,{0x06,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xe4,0x12,0x0c,0x8a,0x90,0x78,0x06} },
+{  16,0x426d,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x03,0x12,0x0c,0x9c} },
+{  16,0x427d,0,{0x90,0x78,0x07,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x06,0xe0,0xfb,0xa3} },
+{  16,0x428d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0xe4,0x12,0x0c,0x8a,0x90,0x78,0x06,0xe0,0xfb,0xa3,0xe0} },
+{  12,0x429d,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x04,0x12,0x0c,0x9c} },
+{   1,0x42a9,0,{0x22} },
+{  16,0x42aa,0,{0xe4,0xff,0xfe,0x7b,0x01,0x90,0x78,0x0c,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74} },
+{  16,0x42ba,0,{0x2b,0xf0,0x90,0x78,0x0c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02} },
+{  16,0x42ca,0,{0x12,0x0c,0x5d,0xfd,0x90,0x79,0x9a,0xe0,0x6d,0x60,0x13,0xef,0xc3,0x94,0x05,0x50} },
+{  16,0x42da,0,{0x0d,0x0f,0x90,0x78,0x0d,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x80,0xd4,0x8d,0x33} },
+{  16,0x42ea,0,{0x90,0x78,0x0c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12,0x0c} },
+{  16,0x42fa,0,{0x5d,0xfd,0x90,0x79,0x9b,0xe0,0xfc,0x6d,0x60,0x13,0xee,0xc3,0x94,0x0b,0x50,0x0d} },
+{  16,0x430a,0,{0x0e,0x90,0x78,0x0d,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x80,0xd3,0x8c,0x34,0xef} },
+{  16,0x431a,0,{0x64,0x05,0x60,0x03,0xbe,0x0b,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90} },
+{  16,0x432a,0,{0x78,0x0c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x0c,0x44,0xff,0x24,0xf0} },
+{  16,0x433a,0,{0x60,0x08,0x24,0x0e,0x70,0x0e,0x12,0x49,0x4d,0x22,0x90,0x79,0x20,0xe5,0x34,0xf0} },
+{  11,0x434a,0,{0x12,0x1b,0x2a,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} },
+{   1,0x4355,0,{0x22} },
+{  12,0x4356,0,{0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x3f,0x02,0x43,0x9d} },
+{  16,0x4362,0,{0x02,0x48,0xa9,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2} },
+{  16,0x4372,0,{0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33} },
+{  16,0x4382,0,{0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf} },
+{  16,0x4392,0,{0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x46,0x61,0xe4,0x7e} },
+{  16,0x43a2,0,{0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93} },
+{  16,0x43b2,0,{0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3} },
+{  16,0x43c2,0,{0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca} },
+{  16,0x43d2,0,{0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe} },
+{  16,0x43e2,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0} },
+{  16,0x43f2,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef} },
+{  16,0x4402,0,{0xc0,0xe0,0xc2,0xca,0xc2,0xcf,0x90,0x79,0x7a,0xe0,0xb4,0x01,0x1f,0x12,0x4b,0xae} },
+{  16,0x4412,0,{0x12,0x47,0x58,0x53,0xa8,0xa0,0x90,0x7f,0xae,0xe4,0xf0,0x12,0x07,0xaa,0x12,0x4b} },
+{  16,0x4422,0,{0xb7,0x90,0x7f,0xae,0x74,0x1f,0xf0,0x43,0xa8,0x05,0x80,0x03,0x53,0xa8,0xa0,0x53} },
+{  16,0x4432,0,{0xa8,0xfa,0x75,0xe8,0x01,0x12,0x09,0x15,0x75,0xe8,0x0d,0x43,0xa8,0x05,0xd0,0xe0} },
+{  16,0x4442,0,{0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa} },
+{  16,0x4452,0,{0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0} },
+{   1,0x4462,0,{0x32} },
+{  16,0x4463,0,{0x90,0x7f,0xec,0xe0,0xf5,0x09,0x14,0x60,0x1d,0x14,0x60,0x2a,0x14,0x60,0x37,0x14} },
+{  16,0x4473,0,{0x60,0x44,0x24,0x04,0x70,0x50,0x90,0x79,0x62,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} },
+{  16,0x4483,0,{0xb5,0x74,0x01,0xf0,0x80,0x47,0x90,0x79,0x63,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} },
+{  16,0x4493,0,{0xb5,0x74,0x01,0xf0,0x80,0x37,0x90,0x79,0x64,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} },
+{  16,0x44a3,0,{0xb5,0x74,0x01,0xf0,0x80,0x27,0x90,0x79,0x66,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} },
+{  16,0x44b3,0,{0xb5,0x74,0x01,0xf0,0x80,0x17,0x90,0x79,0x67,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} },
+{  15,0x44c3,0,{0xb5,0x74,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xd3,0x22} },
+{   4,0x44d2,0,{0x8d,0x36,0x8b,0x37} },
+{  16,0x44d6,0,{0x12,0x3f,0xa2,0xea,0x49,0x60,0x57,0x12,0x0c,0x44,0x7e,0x00,0x29,0xff,0xee,0x3a} },
+{  16,0x44e6,0,{0xc9,0xef,0xc9,0x75,0x38,0xff,0xf5,0x39,0x89,0x3a,0xab,0x38,0xaa,0x39,0xa9,0x3a} },
+{  16,0x44f6,0,{0x90,0x00,0x01,0x12,0x0c,0x5d,0xff,0x64,0x04,0x60,0x05,0xef,0x64,0x05,0x70,0x2e} },
+{  16,0x4506,0,{0xef,0xb4,0x04,0x15,0x90,0x00,0x02,0x12,0x0c,0x5d,0x65,0x36,0x70,0x0b,0x90,0x00} },
+{  16,0x4516,0,{0x03,0x12,0x0c,0x5d,0x65,0x37,0x70,0x01,0x22,0x12,0x0c,0x44,0x7e,0x00,0x29,0xff} },
+{  16,0x4526,0,{0xee,0x3a,0xc9,0xef,0xc9,0x75,0x38,0xff,0xf5,0x39,0x89,0x3a,0x80,0xbc,0x7b,0x00} },
+{   4,0x4536,0,{0x7a,0x00,0x79,0x00} },
+{   1,0x453a,0,{0x22} },
+{  16,0x453b,0,{0xe4,0xff,0x7b,0x01,0x90,0x78,0x1c,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0x4c} },
+{  16,0x454b,0,{0xf0,0x90,0x78,0x1c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12} },
+{  16,0x455b,0,{0x0c,0x5d,0xfe,0x90,0x7f,0xec,0xe0,0x6e,0x60,0x13,0xef,0xc3,0x94,0x04,0x50,0x0d} },
+{  16,0x456b,0,{0x90,0x78,0x1d,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x0f,0x80,0xd4,0xbf,0x04,0x09} },
+{  16,0x457b,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x14,0x90,0x79,0x21,0xe0,0xff,0x90,0x78} },
+{  16,0x458b,0,{0x1c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xef,0x12,0x0c,0x8a,0x90,0x7f,0xc5} },
+{   3,0x459b,0,{0x74,0x01,0xf0} },
+{   1,0x459e,0,{0x22} },
+{  14,0x459f,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xee,0xc0,0xe0,0xef,0xc0,0xe0} },
+{  16,0x45ad,0,{0x90,0x79,0x85,0xe0,0x64,0x01,0x60,0x05,0xa3,0xe0,0xb4,0x01,0x2d,0x90,0x79,0x87} },
+{  16,0x45bd,0,{0x74,0x01,0xf0,0xe4,0xff,0x90,0x7f,0xc5,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x1b,0x74} },
+{  16,0x45cd,0,{0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xfe,0x74,0x21,0x2f,0xf5,0x82} },
+{  16,0x45dd,0,{0xe4,0x34,0x79,0xf5,0x83,0xee,0xf0,0x0f,0x80,0xdb,0x53,0x91,0xef,0x90,0x7f,0xaa} },
+{   4,0x45ed,0,{0xe0,0x44,0x01,0xf0} },
+{  15,0x45f1,0,{0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4600,0,{0xe4,0xff,0x7b,0x01,0x90,0x78,0x19,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0x4c} },
+{  16,0x4610,0,{0xf0,0x90,0x78,0x19,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12} },
+{  16,0x4620,0,{0x0c,0x5d,0xfe,0x90,0x7f,0xec,0xe0,0x6e,0x60,0x13,0xef,0xc3,0x94,0x04,0x50,0x0d} },
+{  16,0x4630,0,{0x90,0x78,0x1a,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x0f,0x80,0xd4,0xbf,0x04,0x08} },
+{  16,0x4640,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x19,0xe0,0xfb,0xa3,0xe0,0xfa} },
+{  16,0x4650,0,{0xa3,0xe0,0xf9,0x12,0x0c,0x44,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} },
+{   1,0x4660,0,{0x22} },
+{  16,0x4661,0,{0x01,0x18,0x02,0x01,0x19,0x0a,0x01,0x1c,0x00,0xc1,0x28,0xc1,0x29,0x01,0x1f,0x01} },
+{  15,0x4671,0,{0x44,0x79,0x9f,0x00,0x00,0x00,0x00,0x41,0x79,0xa3,0x00,0x41,0x79,0xa4,0x00} },
+{   4,0x4680,0,{0x41,0x79,0x89,0x00} },
+{  16,0x4684,0,{0x01,0x22,0x01,0x41,0x79,0x31,0xff,0x41,0x79,0x34,0x00,0x4d,0x79,0x35,0x3f,0x3f} },
+{  16,0x4694,0,{0x00,0x08,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x4d,0x79,0x42,0x3f,0x3f} },
+{  16,0x46a4,0,{0x06,0x08,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x4d,0x79,0x4f,0x0a,0x0a} },
+{  11,0x46b4,0,{0x09,0x00,0x01,0x09,0x02,0x03,0x04,0x05,0x06,0x07,0x08} },
+{   1,0x46bf,0,{0x00} },
+{  16,0x46c0,0,{0x12,0x0a,0xcd,0x90,0x7f,0xa5,0xe0,0xf5,0x21,0xe5,0x21,0x54,0x01,0xf5,0x21,0x64} },
+{  16,0x46d0,0,{0x01,0x60,0x28,0xe5,0x22,0x64,0x01,0x70,0x22,0x90,0x7f,0xa5,0xe0,0xf5,0x21,0x54} },
+{  16,0x46e0,0,{0x02,0xf5,0x21,0x70,0x03,0x75,0x22,0x01,0x90,0x7f,0xa5,0xe0,0xf5,0x21,0x54,0x04} },
+{  12,0x46f0,0,{0xff,0xf5,0x21,0xbf,0x04,0xd3,0x75,0x22,0x01,0x80,0xce,0x22} },
+{   4,0x46fc,0,{0x53,0xd8,0xf7,0x32} },
+{  16,0x4700,0,{0x02,0x49,0xfa,0x00,0x02,0x3c,0x54,0x00,0x02,0x17,0xe4,0x00,0x02,0x4a,0x12,0x00} },
+{  16,0x4710,0,{0x02,0x37,0xa2,0x00,0x02,0x47,0xff,0x00,0x02,0x4a,0x41,0x00,0x02,0x45,0x9f,0x00} },
+{  16,0x4720,0,{0x02,0x49,0x8e,0x00,0x02,0x49,0xab,0x00,0x02,0x4a,0x58,0x00,0x02,0x4a,0x6f,0x00} },
+{  16,0x4730,0,{0x02,0x4a,0x86,0x00,0x02,0x4a,0x9d,0x00,0x02,0x4a,0xb4,0x00,0x02,0x4a,0xcb,0x00} },
+{  16,0x4740,0,{0x02,0x4a,0xe2,0x00,0x02,0x4a,0xf9,0x00,0x02,0x4b,0x10,0x00,0x02,0x4b,0x27,0x00} },
+{   8,0x4750,0,{0x02,0x4b,0x3e,0x00,0x02,0x4b,0x55,0x00} },
+{  16,0x4758,0,{0xe5,0x18,0x70,0x14,0x90,0x79,0x8c,0xe0,0x04,0xf0,0x90,0x79,0x8b,0xe0,0xc3,0x94} },
+{  16,0x4768,0,{0x00,0x40,0x15,0xe0,0x14,0xf0,0x80,0x10,0x90,0x79,0x8b,0xe0,0x04,0xf0,0xa3,0xe0} },
+{  16,0x4778,0,{0xc3,0x94,0x00,0x40,0x03,0xe0,0x14,0xf0,0x90,0x79,0x8b,0xe0,0xd3,0x94,0x14,0x40} },
+{  16,0x4788,0,{0x04,0xe4,0xf5,0x18,0xf0,0x90,0x79,0x8c,0xe0,0xd3,0x94,0x14,0x40,0x05,0x75,0x18} },
+{   4,0x4798,0,{0x01,0xe4,0xf0,0x22} },
+{  16,0x479c,0,{0x90,0x7f,0xd7,0xe0,0xf5,0x33,0x90,0x7f,0xec,0xe0,0xf5,0x09,0x14,0x60,0x11,0x14} },
+{  16,0x47ac,0,{0x60,0x1b,0x24,0x02,0x70,0x24,0x90,0x7f,0xea,0xe0,0x90,0x79,0x62,0xf0,0x80,0x21} },
+{  16,0x47bc,0,{0x90,0x7f,0xea,0xe0,0x90,0x79,0x63,0xf0,0x12,0x10,0x00,0x80,0x14,0x90,0x7f,0xea} },
+{  16,0x47cc,0,{0xe0,0x90,0x79,0x64,0xf0,0x12,0x28,0x01,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01} },
+{   2,0x47dc,0,{0xf0,0xd3} },
+{   1,0x47de,0,{0x22} },
+{  16,0x47df,0,{0x90,0x79,0x78,0x74,0x04,0xf0,0x90,0x79,0x33,0xe0,0x90,0x79,0x79,0xf0,0xa2,0xaf} },
+{  16,0x47ef,0,{0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x22} },
+{   1,0x47ff,0,{0x32} },
+{   2,0x4800,0,{0x8f,0x36} },
+{  16,0x4802,0,{0xe4,0xf5,0x37,0x75,0x38,0xff,0x75,0x39,0x07,0x75,0x3a,0x01,0xab,0x38,0xaa,0x39} },
+{  16,0x4812,0,{0xa9,0x3a,0x90,0x00,0x01,0x12,0x0c,0x5d,0xb4,0x03,0x1f,0xaf,0x37,0x05,0x37,0xef} },
+{  16,0x4822,0,{0x65,0x36,0x70,0x01,0x22,0x12,0x0c,0x44,0x7e,0x00,0x29,0xff,0xee,0x3a,0xc9,0xef} },
+{  16,0x4832,0,{0xc9,0x75,0x38,0xff,0xf5,0x39,0x89,0x3a,0x80,0xd2,0x7b,0x00,0x7a,0x00,0x79,0x00} },
+{   1,0x4842,0,{0x22} },
+{  16,0x4843,0,{0x30,0x26,0x2f,0xc2,0x26,0x90,0x79,0x2d,0xe0,0xff,0xb4,0x01,0x09,0xe4,0xf5,0x0c} },
+{  16,0x4853,0,{0x75,0x0d,0xf8,0x75,0x0e,0x0a,0xef,0xb4,0x02,0x09,0xe4,0xf5,0x0c,0x75,0x0d,0xf0} },
+{  16,0x4863,0,{0x75,0x0e,0x0b,0xef,0xb4,0x03,0x09,0xe4,0xf5,0x0c,0x75,0x0d,0xf8,0x75,0x0e,0x17} },
+{   3,0x4873,0,{0xd2,0x22,0x22} },
+{  16,0x4876,0,{0x30,0x25,0x2f,0xc2,0x25,0x90,0x79,0x2d,0xe0,0xff,0xb4,0x01,0x09,0x75,0x0c,0xc0} },
+{  16,0x4886,0,{0x75,0x0d,0x14,0x75,0x0e,0x0b,0xef,0xb4,0x02,0x09,0xe4,0xf5,0x0c,0x75,0x0d,0x10} },
+{  16,0x4896,0,{0x75,0x0e,0x0c,0xef,0xb4,0x03,0x09,0xe4,0xf5,0x0c,0x75,0x0d,0x18,0x75,0x0e,0x18} },
+{   3,0x48a6,0,{0xd2,0x22,0x22} },
+{  16,0x48a9,0,{0xe4,0xf5,0x32,0x12,0x0f,0x50,0x20,0x2e,0x10,0xe5,0x32,0xc3,0x94,0x02,0x50,0x09} },
+{  16,0x48b9,0,{0x05,0x32,0xd2,0x30,0x12,0x49,0x05,0x80,0xed,0x30,0x2e,0x05,0x12,0x14,0x57,0xc2} },
+{  15,0x48c9,0,{0x2e,0x30,0x2d,0x06,0x12,0x07,0x9a,0x12,0x48,0xd9,0x12,0x40,0x00,0x80,0xea} },
+{   1,0x48d8,0,{0x22} },
+{  16,0x48d9,0,{0x90,0x7f,0xd6,0xe0,0xf5,0x1d,0x54,0x80,0xf5,0x1d,0x64,0x80,0x70,0x1d,0xc2,0xaf} },
+{  16,0x48e9,0,{0xe0,0x44,0x80,0xf0,0xe0,0x44,0x01,0xf0,0x7f,0x0c,0x7e,0x00,0x12,0x4b,0x6c,0x90} },
+{  12,0x48f9,0,{0x7f,0xd6,0xe0,0x54,0xfe,0xf0,0x53,0x87,0xfe,0xd2,0xaf,0x22} },
+{  16,0x4905,0,{0x90,0x7f,0xd6,0xe0,0x54,0xfb,0xf0,0xe0,0x44,0x08,0xf0,0x30,0x30,0x04,0xe0,0x44} },
+{  16,0x4915,0,{0x02,0xf0,0x7f,0xdc,0x7e,0x05,0x12,0x4b,0x6c,0x90,0x7f,0xd6,0xe0,0x54,0xf7,0xf0} },
+{   5,0x4925,0,{0xe0,0x44,0x04,0xf0,0x22} },
+{  16,0x492a,0,{0x90,0x7f,0xeb,0xe0,0x14,0x70,0x14,0x90,0x7f,0xe9,0xe0,0x24,0x7f,0x70,0x04,0x12} },
+{  16,0x493a,0,{0x46,0x00,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44} },
+{   3,0x494a,0,{0x01,0xf0,0x22} },
+{  16,0x494d,0,{0x90,0x7f,0xeb,0xe0,0x14,0x70,0x13,0x90,0x7f,0xe9,0xe0,0x14,0x70,0x04,0x12,0x45} },
+{  16,0x495d,0,{0x3b,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01} },
+{   2,0x496d,0,{0xf0,0x22} },
+{  16,0x496f,0,{0xe4,0xff,0x74,0xe8,0x2f,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xe0,0xfe,0x74,0x96} },
+{  14,0x497f,0,{0x2f,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xee,0xf0,0x0f,0xbf,0x08,0xe4} },
+{   1,0x498d,0,{0x22} },
+{  16,0x498e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x02,0xf0} },
+{  13,0x499e,0,{0x90,0x7f,0xb7,0x74,0x03,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x49ab,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x02,0xf0} },
+{  13,0x49bb,0,{0x90,0x7f,0xc7,0x74,0x03,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x49c8,0,{0x90,0x7f,0xd6,0xe0,0x30,0xe7,0x12,0xe0,0x44,0x01,0xf0,0x7f,0x14,0x7e,0x00,0x12} },
+{  10,0x49d8,0,{0x4b,0x6c,0x90,0x7f,0xd6,0xe0,0x54,0xfe,0xf0,0x22} },
+{  16,0x49e2,0,{0xe4,0xf5,0x1a,0x75,0x1b,0x01,0x90,0x79,0x91,0x04,0xf0,0xa3,0xf0,0xe4,0xa3,0xf0} },
+{   8,0x49f2,0,{0xa3,0x74,0x0a,0xf0,0xe4,0xa3,0xf0,0x22} },
+{  16,0x49fa,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x2e,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01} },
+{   8,0x4a0a,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4a12,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x2d,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x08} },
+{   8,0x4a22,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4a2a,0,{0x90,0x7f,0xea,0xe0,0xf5,0x08,0xe4,0x90,0x79,0x62,0xf0,0xa3,0xf0,0xa3,0xf0,0x90} },
+{   7,0x4a3a,0,{0x79,0x66,0xf0,0xa3,0xf0,0xd3,0x22} },
+{  16,0x4a41,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x01,0xf0} },
+{   7,0x4a51,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4a58,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x04,0xf0} },
+{   7,0x4a68,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4a6f,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x04,0xf0} },
+{   7,0x4a7f,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4a86,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x08,0xf0} },
+{   7,0x4a96,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4a9d,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x08,0xf0} },
+{   7,0x4aad,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4ab4,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x10,0xf0} },
+{   7,0x4ac4,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4acb,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x10,0xf0} },
+{   7,0x4adb,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4ae2,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x20,0xf0} },
+{   7,0x4af2,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4af9,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x20,0xf0} },
+{   7,0x4b09,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4b10,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x40,0xf0} },
+{   7,0x4b20,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4b27,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x40,0xf0} },
+{   7,0x4b37,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4b3e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x80,0xf0} },
+{   7,0x4b4e,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4b55,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x80,0xf0} },
+{   7,0x4b65,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x4b6c,0,{0x8e,0x33,0x8f,0x34,0xe5,0x34,0x15,0x34,0xae,0x33,0x70,0x02,0x15,0x33,0x4e,0x60} },
+{   7,0x4b7c,0,{0x05,0x12,0x07,0x89,0x80,0xee,0x22} },
+{  15,0x4b83,0,{0x90,0x7f,0xea,0xe0,0xb4,0xff,0x04,0x12,0x30,0x00,0x22,0x12,0x36,0x0e,0x22} },
+{  14,0x4b92,0,{0xc0,0xe0,0xc2,0x8b,0xd2,0x24,0x30,0x23,0x02,0xc2,0x23,0xd0,0xe0,0x32} },
+{  14,0x4ba0,0,{0x90,0x7f,0x00,0xe5,0x08,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0xd3,0x22} },
+{   9,0x4bae,0,{0x30,0x24,0x05,0xc2,0x24,0x75,0x18,0x01,0x22} },
+{   9,0x4bb7,0,{0x30,0x23,0x05,0xc2,0x23,0xe4,0xf5,0x18,0x22} },
+{   7,0x4bc0,0,{0x53,0xc0,0xfe,0x53,0xc0,0xfd,0x32} },
+{   6,0x4bc7,0,{0x53,0x91,0x7f,0xd2,0x25,0x32} },
+{   5,0x4bcd,0,{0xc2,0x89,0xd2,0x23,0x32} },
+{   3,0x4bd2,0,{0xc2,0x8d,0x32} },
+{   3,0x4bd5,0,{0xc2,0x8f,0x32} },
+{   2,0x4bd8,0,{0xd3,0x22} },
+{   2,0x4bda,0,{0xd3,0x22} },
+{   2,0x4bdc,0,{0xd3,0x22} },
+{   2,0x4bde,0,{0xd3,0x22} },
+{   2,0x4be0,0,{0xd3,0x22} },
+{   2,0x4be2,0,{0xd3,0x22} },
+{   2,0x4be4,0,{0xc3,0x22} },
+{   1,0x4be6,0,{0x22} },
+{   0,0x0000,1,{0 }}
+};
+/*
+VERSION=1.0.2.916
+DATE=12.02.2002
+*/
+/*
+ * This firmware is for the Emagic EMI 2|6 Audio Interface
+ *
+ * The firmware contained herein is Copyright (c) 1999-2002 Emagic
+ * as an unpublished work. This notice does not imply unrestricted
+ * or public access to this firmware which is a trade secret of Emagic,
+ * and which may not be reproduced, used, sold or transferred to
+ * any third party without Emagic's written consent. All Rights Reserved.
+ *
+ * This firmware may not be modified and may only be used with the
+ * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of
+ * any driver which includes this firmware, in whole or in part,
+ * requires the inclusion of this statement.
+ */
+INTEL_HEX_RECORD g_Loader[] = {
+{   3,0x0000,0,{0x02,0x03,0x1c} },
+{   3,0x0043,0,{0x02,0x04,0x00} },
+{  16,0x0100,0,{0x90,0x7f,0xe9,0xe0,0x24,0x5b,0x60,0x60,0x24,0x02,0x60,0x03,0x02,0x01,0xbe,0x90} },
+{  16,0x0110,0,{0x7f,0xea,0xe0,0x75,0x0a,0x00,0xf5,0x0b,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x0a,0x90} },
+{  16,0x0120,0,{0x7f,0xee,0xe0,0x75,0x15,0x00,0xf5,0x16,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x15,0xe5} },
+{  16,0x0130,0,{0x16,0x45,0x15,0x70,0x03,0x02,0x01,0xbe,0xe4,0x90,0x7f,0xc5,0xf0,0x90,0x7f,0xb4} },
+{  16,0x0140,0,{0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xc5,0xe0,0xf5,0x0c,0x12,0x02,0x77,0xaf,0x0c,0x7e} },
+{  16,0x0150,0,{0x00,0xef,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5,0x0a,0xc3,0xe5,0x16,0x9f,0xf5} },
+{  16,0x0160,0,{0x16,0xe5,0x15,0x9e,0xf5,0x15,0x80,0xc7,0x90,0x7f,0xea,0xe0,0x75,0x0a,0x00,0xf5} },
+{  16,0x0170,0,{0x0b,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x0a,0x90,0x7f,0xee,0xe0,0x75,0x15,0x00,0xf5} },
+{  16,0x0180,0,{0x16,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x15,0xe5,0x16,0x45,0x15,0x60,0x30,0xe4,0x90} },
+{  16,0x0190,0,{0x7f,0xc5,0xf0,0x90,0x7f,0xb4,0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xc5,0xe0,0xf5,0x0c} },
+{  16,0x01a0,0,{0x12,0x02,0x8f,0xaf,0x0c,0x7e,0x00,0xef,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5} },
+{  15,0x01b0,0,{0x0a,0xc3,0xe5,0x16,0x9f,0xf5,0x16,0xe5,0x15,0x9e,0xf5,0x15,0x80,0xca,0xc3} },
+{   1,0x01bf,0,{0x22} },
+{  16,0x01c0,0,{0xc2,0x20,0xd2,0xe8,0x43,0xd8,0x20,0x90,0x7f,0xab,0x74,0xff,0xf0,0x90,0x7f,0xa9} },
+{  16,0x01d0,0,{0xf0,0x90,0x7f,0xaa,0xf0,0x53,0x91,0xef,0x90,0x7f,0x95,0xe0,0x44,0xc0,0xf0,0x90} },
+{  16,0x01e0,0,{0x7f,0x98,0xe0,0x44,0xc0,0xf0,0x90,0x7f,0x9e,0xe0,0x44,0xc0,0xf0,0xe4,0x90,0x7f} },
+{  16,0x01f0,0,{0x94,0xf0,0x90,0x7f,0x9d,0xe0,0x44,0x0f,0xf0,0x90,0x7f,0x97,0xe0,0x54,0xf0,0xf0} },
+{  16,0x0200,0,{0x90,0x7f,0xaf,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xae,0xe0,0x44,0x0d,0xf0,0xd2,0xaf} },
+{  16,0x0210,0,{0x90,0x7f,0x97,0xe0,0x54,0xf0,0xf0,0x20,0x20,0x42,0x75,0x14,0x00,0x75,0x13,0x00} },
+{  16,0x0220,0,{0x75,0x12,0x00,0x75,0x11,0x00,0x7f,0x48,0x7e,0x92,0x7d,0x00,0x7c,0x00,0xab,0x14} },
+{  16,0x0230,0,{0xaa,0x13,0xa9,0x12,0xa8,0x11,0xc3,0x12,0x04,0x9a,0x50,0xdb,0x20,0x20,0xd8,0x7a} },
+{  16,0x0240,0,{0x00,0x79,0x00,0x78,0x00,0xe5,0x14,0x24,0x01,0xf5,0x14,0xea,0x35,0x13,0xf5,0x13} },
+{  16,0x0250,0,{0xe9,0x35,0x12,0xf5,0x12,0xe8,0x35,0x11,0xf5,0x11,0x80,0xca,0x30,0x20,0xfd,0x12} },
+{  16,0x0260,0,{0x01,0x00,0x50,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xb4,0xe0,0x44} },
+{   6,0x0270,0,{0x02,0xf0,0xc2,0x20,0x80,0xe6} },
+{   1,0x0276,0,{0x22} },
+{  16,0x0277,0,{0xe5,0x0c,0xff,0xe5,0x0b,0xf5,0x82,0xe5,0x0a,0xf5,0x83,0x75,0x92,0x7e,0x74,0xc0} },
+{   8,0x0287,0,{0xf8,0xe2,0x08,0xf0,0xa3,0xdf,0xfa,0x22} },
+{  16,0x028f,0,{0x90,0x7f,0x96,0x85,0x83,0x92,0xa8,0x82,0x79,0x02,0x90,0x00,0x00,0xe0,0xb4,0x00} },
+{  16,0x029f,0,{0x37,0x74,0x01,0xf0,0x90,0x7f,0x93,0xe0,0x54,0xfc,0xf0,0x90,0x7f,0x96,0xe0,0x54} },
+{  16,0x02af,0,{0xfc,0xf0,0x90,0x7f,0x9c,0xe0,0x44,0x03,0xf0,0x90,0x7f,0x94,0xe0,0x54,0x7f,0xf0} },
+{  16,0x02bf,0,{0x90,0x7f,0x97,0xe0,0x44,0x80,0xf0,0x90,0x7f,0x9d,0xe0,0x44,0x80,0xf0,0x90,0x7f} },
+{  16,0x02cf,0,{0x97,0xe0,0x54,0x7f,0xf0,0x44,0x80,0xf0,0xe5,0x0c,0xff,0x90,0x7e,0xc0,0xe0,0xf5} },
+{  16,0x02df,0,{0x28,0xe4,0xa2,0x47,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x46,0x33,0xf2,0x69,0xf2,0xe4} },
+{  16,0x02ef,0,{0xa2,0x45,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x44,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x43} },
+{  16,0x02ff,0,{0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x42,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x41,0x33,0xf2} },
+{  13,0x030f,0,{0x69,0xf2,0xe4,0xa2,0x40,0x33,0xf2,0x69,0xf2,0xa3,0xdf,0xc2,0x22} },
+{  12,0x031c,0,{0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x29,0x02,0x03,0x63} },
+{  16,0x0328,0,{0x02,0x01,0xc0,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2} },
+{  16,0x0338,0,{0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33} },
+{  16,0x0348,0,{0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf} },
+{  16,0x0358,0,{0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x04,0x84,0xe4,0x7e} },
+{  16,0x0368,0,{0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93} },
+{  16,0x0378,0,{0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3} },
+{  16,0x0388,0,{0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca} },
+{  16,0x0398,0,{0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe} },
+{  16,0x03a8,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x7f,0xc4,0xe4,0xf0,0x53,0x91,0xef,0x90,0x7f} },
+{  11,0x03b8,0,{0xab,0x74,0x04,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x03c3,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x20,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01} },
+{   8,0x03d3,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x03db,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xd0} },
+{   6,0x03eb,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{   1,0x03f1,0,{0x32} },
+{   1,0x03f2,0,{0x32} },
+{   1,0x03f3,0,{0x32} },
+{   1,0x03f4,0,{0x32} },
+{   1,0x03f5,0,{0x32} },
+{   1,0x03f6,0,{0x32} },
+{   1,0x03f7,0,{0x32} },
+{   1,0x03f8,0,{0x32} },
+{   1,0x03f9,0,{0x32} },
+{   1,0x03fa,0,{0x32} },
+{   1,0x03fb,0,{0x32} },
+{   1,0x03fc,0,{0x32} },
+{   1,0x03fd,0,{0x32} },
+{   1,0x03fe,0,{0x32} },
+{   1,0x03ff,0,{0x32} },
+{  16,0x0400,0,{0x02,0x03,0xc3,0x00,0x02,0x03,0xdb,0x00,0x02,0x03,0xa8,0x00,0x02,0x04,0x6e,0x00} },
+{  16,0x0410,0,{0x02,0x04,0x58,0x00,0x02,0x03,0xf1,0x00,0x02,0x03,0xf2,0x00,0x02,0x03,0xf3,0x00} },
+{  16,0x0420,0,{0x02,0x03,0xf4,0x00,0x02,0x03,0xf5,0x00,0x02,0x03,0xf6,0x00,0x02,0x03,0xf7,0x00} },
+{  16,0x0430,0,{0x02,0x03,0xf8,0x00,0x02,0x03,0xf9,0x00,0x02,0x03,0xfa,0x00,0x02,0x03,0xfb,0x00} },
+{  16,0x0440,0,{0x02,0x03,0xfc,0x00,0x02,0x03,0xfd,0x00,0x02,0x03,0xfe,0x00,0x02,0x03,0xff,0x00} },
+{   8,0x0450,0,{0x02,0x04,0xab,0x00,0x02,0x04,0xac,0x00} },
+{  16,0x0458,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0xd0} },
+{   6,0x0468,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x046e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x08,0xf0,0xd0} },
+{   6,0x047e,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32} },
+{  16,0x0484,0,{0x02,0x0a,0x00,0x0f,0x01,0x0c,0x11,0x04,0x0d,0x00,0x00,0x00,0x00,0x41,0x00,0x00} },
+{   1,0x0494,0,{0x00} },
+{   4,0x0495,0,{0x02,0x17,0x00,0x00} },
+{   1,0x0499,0,{0x00} },
+{  16,0x049a,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0} },
+{   1,0x04aa,0,{0x22} },
+{   1,0x04ab,0,{0x32} },
+{   1,0x04ac,0,{0x32} },
+{  16,0x1100,0,{0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x40,0x6a,0x08,0x01,0x01,0x00,0x01,0x01,0x02} },
+{  16,0x1110,0,{0x00,0x01,0x09,0x02,0x20,0x00,0x01,0x01,0x03,0xa0,0x00,0x09,0x04,0x00,0x00,0x02} },
+{  16,0x1120,0,{0xff,0x00,0x00,0x04,0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40} },
+{  16,0x1130,0,{0x00,0x00,0x04,0x03,0x09,0x04,0x26,0x03,0x41,0x00,0x6e,0x00,0x63,0x00,0x68,0x00} },
+{  16,0x1140,0,{0x6f,0x00,0x72,0x00,0x20,0x00,0x43,0x00,0x68,0x00,0x69,0x00,0x70,0x00,0x73,0x00} },
+{  16,0x1150,0,{0x2c,0x00,0x20,0x00,0x49,0x00,0x6e,0x00,0x63,0x00,0x2e,0x00,0x28,0x03,0x46,0x00} },
+{  16,0x1160,0,{0x69,0x00,0x72,0x00,0x6d,0x00,0x77,0x00,0x61,0x00,0x72,0x00,0x65,0x00,0x20,0x00} },
+{  16,0x1170,0,{0x46,0x00,0x72,0x00,0x61,0x00,0x6d,0x00,0x65,0x00,0x57,0x00,0x6f,0x00,0x72,0x00} },
+{  16,0x1180,0,{0x6b,0x00,0x73,0x00,0x2a,0x03,0x43,0x00,0x6f,0x00,0x6e,0x00,0x66,0x00,0x69,0x00} },
+{  16,0x1190,0,{0x67,0x00,0x75,0x00,0x72,0x00,0x61,0x00,0x74,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00} },
+{  16,0x11a0,0,{0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x22,0x03} },
+{  16,0x11b0,0,{0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x66,0x00,0x61,0x00,0x63,0x00} },
+{  16,0x11c0,0,{0x65,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00} },
+{   2,0x11d0,0,{0x00,0x00} },
+{   0,0x0000,1,{0 }}
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/Config.in linux/drivers/usb/hcd/Config.in
--- linux.orig/drivers/usb/hcd/Config.in	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/Config.in	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,7 @@
+#
+# USB Host Controller Drivers
+#
+dep_tristate '  EHCI HCD (USB 2.0) support (EXPERIMENTAL)' CONFIG_USB_EHCI_HCD $CONFIG_USB $CONFIG_EXPERIMENTAL
+# dep_tristate '  OHCI HCD support (EXPERIMENTAL)' CONFIG_USB_OHCI_HCD $CONFIG_USB $CONFIG_EXPERIMENTAL
+# dep_tristate '  UHCI HCD (most Intel and VIA) support (EXPERIMENTAL)' CONFIG_USB_UHCI_HCD $CONFIG_USB $CONFIG_EXPERIMENTAL
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/Makefile linux/drivers/usb/hcd/Makefile
--- linux.orig/drivers/usb/hcd/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,27 @@
+#
+# Makefile for USB Host Controller Driver
+# framework and drivers
+#
+
+O_TARGET	:=
+
+obj-$(CONFIG_USB_EHCI_HCD)			+= ehci-hcd.o
+# obj-$(CONFIG_USB_OHCI_HCD)			+= ohci-hcd.o
+# obj-$(CONFIG_USB_UHCI_HCD)			+= uhci-hcd.o
+
+# Extract lists of the multi-part drivers.
+# The 'int-*' lists are the intermediate files used to build the multi's.
+multi-y		:= $(filter $(list-multi), $(obj-y))
+multi-m		:= $(filter $(list-multi), $(obj-m))
+int-y		:= $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
+int-m		:= $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
+
+# Take multi-part drivers out of obj-y and put components in.
+obj-y		:= $(filter-out $(list-multi), $(obj-y)) $(int-y)
+
+# Translate to Rules.make lists.
+OX_OBJS		:= $(obj-y)
+MX_OBJS		:= $(obj-m)
+MIX_OBJS	:= $(int-m)
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/ehci-dbg.c linux/drivers/usb/hcd/ehci-dbg.c
--- linux.orig/drivers/usb/hcd/ehci-dbg.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/ehci-dbg.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2001 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* this file is part of ehci-hcd.c */
+
+#ifdef EHCI_VERBOSE_DEBUG
+#	define vdbg dbg
+#else
+	static inline void vdbg (char *fmt, ...) { }
+#endif
+
+#ifdef	DEBUG
+
+/* check the values in the HCSPARAMS register - host controller structural parameters */
+/* see EHCI 0.95 Spec, Table 2-4 for each value */
+static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
+{
+	u32	params = readl (&ehci->caps->hcs_params);
+
+	dbg ("%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d",
+		label, params,
+		HCS_DEBUG_PORT (params),
+		HCS_INDICATOR (params) ? " ind" : "",
+		HCS_N_CC (params),
+		HCS_N_PCC (params),
+	        HCS_PORTROUTED (params) ? "" : " ordered",
+		HCS_PPC (params) ? "" : " !ppc",
+		HCS_N_PORTS (params)
+		);
+	/* Port routing, per EHCI 0.95 Spec, Section 2.2.5 */
+	if (HCS_PORTROUTED (params)) {
+		int i;
+		char buf [46], tmp [7], byte;
+
+		buf[0] = 0;
+		for (i = 0; i < HCS_N_PORTS (params); i++) {
+			byte = readb (&ehci->caps->portroute[(i>>1)]);
+			sprintf(tmp, "%d ", 
+				((i & 0x1) ? ((byte)&0xf) : ((byte>>4)&0xf)));
+			strcat(buf, tmp);
+		}
+		dbg ("%s: %s portroute %s", 
+			ehci->hcd.bus_name, label,
+			buf);
+	}
+}
+#else
+
+static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {}
+
+#endif
+
+#ifdef	DEBUG
+
+/* check the values in the HCCPARAMS register - host controller capability parameters */
+/* see EHCI 0.95 Spec, Table 2-5 for each value */
+static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
+{
+	u32	params = readl (&ehci->caps->hcc_params);
+
+	if (HCC_EXT_CAPS (params)) {
+		// EHCI 0.96 ... could interpret these (legacy?)
+		dbg ("%s extended capabilities at pci %d",
+			label, HCC_EXT_CAPS (params));
+	}
+	if (HCC_ISOC_CACHE (params)) {
+		dbg ("%s hcc_params 0x%04x caching frame %s%s%s",
+		     label, params,
+		     HCC_PGM_FRAMELISTLEN (params) ? "256/512/1024" : "1024",
+		     HCC_CANPARK (params) ? " park" : "",
+		     HCC_64BIT_ADDR (params) ? " 64 bit addr" : "");
+	} else {
+		dbg ("%s hcc_params 0x%04x caching %d uframes %s%s%s",
+		     label,
+		     params,
+		     HCC_ISOC_THRES (params),
+		     HCC_PGM_FRAMELISTLEN (params) ? "256/512/1024" : "1024",
+		     HCC_CANPARK (params) ? " park" : "",
+		     HCC_64BIT_ADDR (params) ? " 64 bit addr" : "");
+	}
+}
+#else
+
+static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {}
+
+#endif
+
+#ifdef	DEBUG
+
+#if 0
+static void dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+	dbg ("%s %p info1 %x info2 %x hw_curr %x qtd_next %x", label,
+		qh, qh->hw_info1, qh->hw_info2,
+		qh->hw_current, qh->hw_qtd_next);
+	dbg ("  alt+errs= %x, token= %x, page0= %x, page1= %x",
+		qh->hw_alt_next, qh->hw_token,
+		qh->hw_buf [0], qh->hw_buf [1]);
+	if (qh->hw_buf [2]) {
+		dbg ("  page2= %x, page3= %x, page4= %x",
+			qh->hw_buf [2], qh->hw_buf [3],
+			qh->hw_buf [4]);
+	}
+}
+#endif
+
+static const char *const fls_strings [] =
+    { "1024", "512", "256", "??" };
+
+#else
+#if 0
+static inline void dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) {}
+#endif
+#endif	/* DEBUG */
+
+/* functions have the "wrong" filename when they're output... */
+
+#define dbg_status(ehci, label, status) \
+	dbg ("%s status 0x%x%s%s%s%s%s%s%s%s%s%s", \
+		label, status, \
+		(status & STS_ASS) ? " Async" : "", \
+		(status & STS_PSS) ? " Periodic" : "", \
+		(status & STS_RECL) ? " Recl" : "", \
+		(status & STS_HALT) ? " Halt" : "", \
+		(status & STS_IAA) ? " IAA" : "", \
+		(status & STS_FATAL) ? " FATAL" : "", \
+		(status & STS_FLR) ? " FLR" : "", \
+		(status & STS_PCD) ? " PCD" : "", \
+		(status & STS_ERR) ? " ERR" : "", \
+		(status & STS_INT) ? " INT" : "" \
+		)
+
+#define dbg_cmd(ehci, label, command) \
+	dbg ("%s %x cmd %s=%d ithresh=%d%s%s%s%s period=%s%s %s", \
+		label, command, \
+		(command & CMD_PARK) ? "park" : "(park)", \
+		CMD_PARK_CNT (command), \
+		(command >> 16) & 0x3f, \
+		(command & CMD_LRESET) ? " LReset" : "", \
+		(command & CMD_IAAD) ? " IAAD" : "", \
+		(command & CMD_ASE) ? " Async" : "", \
+		(command & CMD_PSE) ? " Periodic" : "", \
+		fls_strings [(command >> 2) & 0x3], \
+		(command & CMD_RESET) ? " Reset" : "", \
+		(command & CMD_RUN) ? "RUN" : "HALT" \
+		)
+
+#define dbg_port(hcd, label, port, status) \
+	dbg ("%s port %d status 0x%x%s%s speed=%d%s%s%s%s%s%s%s%s%s", \
+		label, port, status, \
+		(status & PORT_OWNER) ? " OWNER" : "", \
+		(status & PORT_POWER) ? " POWER" : "", \
+		(status >> 10) & 3, \
+		(status & PORT_RESET) ? " RESET" : "", \
+		(status & PORT_SUSPEND) ? " SUSPEND" : "", \
+		(status & PORT_RESUME) ? " RESUME" : "", \
+		(status & PORT_OCC) ? " OCC" : "", \
+		(status & PORT_OC) ? " OC" : "", \
+		(status & PORT_PEC) ? " PEC" : "", \
+		(status & PORT_PE) ? " PE" : "", \
+		(status & PORT_CSC) ? " CSC" : "", \
+		(status & PORT_CONNECT) ? " CONNECT" : "" \
+	    )
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/ehci-hcd.c linux/drivers/usb/hcd/ehci-hcd.c
--- linux.orig/drivers/usb/hcd/ehci-hcd.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/ehci-hcd.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,763 @@
+/*
+ * Copyright (c) 2000-2002 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+
+#ifdef CONFIG_USB_DEBUG
+	#define DEBUG
+#else
+	#undef DEBUG
+#endif
+
+#include <linux/usb.h>
+#include "../hcd.h"
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+
+//#undef KERN_DEBUG
+//#define KERN_DEBUG ""
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI hc_driver implementation ... experimental, incomplete.
+ * Based on the final 1.0 register interface specification.
+ *
+ * There are lots of things to help out with here ... notably
+ * everything "periodic", and of course testing with all sorts
+ * of usb 2.0 devices and configurations.
+ *
+ * USB 2.0 shows up in upcoming www.pcmcia.org technology.
+ * First was PCMCIA, like ISA; then CardBus, which is PCI.
+ * Next comes "CardBay", using USB 2.0 signals.
+ *
+ * Contains additional contributions by:
+ *	Brad Hards
+ *	Rory Bolt
+ *	...
+ *
+ * HISTORY:
+ *
+ * 2002-05-07	Some error path cleanups to report better errors; wmb();
+ *	use non-CVS version id; better iso bandwidth claim.
+ * 2002-04-19	Control/bulk/interrupt submit no longer uses giveback() on
+ *	errors in submit path.  Bugfixes to interrupt scheduling/processing.
+ * 2002-03-05	Initial high-speed ISO support; reduce ITD memory; shift
+ *	more checking to generic hcd framework (db).  Make it work with
+ *	Philips EHCI; reduce PCI traffic; shorten IRQ path (Rory Bolt).
+ * 2002-01-14	Minor cleanup; version synch.
+ * 2002-01-08	Fix roothub handoff of FS/LS to companion controllers.
+ * 2002-01-04	Control/Bulk queuing behaves.
+ *
+ * 2001-12-12	Initial patch version for Linux 2.5.1 kernel.
+ * 2001-June	Works with usb-storage and NEC EHCI on 2.4
+ */
+
+#define DRIVER_VERSION "2002-May-07"
+#define DRIVER_AUTHOR "David Brownell"
+#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
+
+
+// #define EHCI_VERBOSE_DEBUG
+// #define have_split_iso
+
+/* magic numbers that can affect system performance */
+#define	EHCI_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */
+#define	EHCI_TUNE_RL_HS		0	/* nak throttle; see 4.9 */
+#define	EHCI_TUNE_RL_TT		0
+#define	EHCI_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
+#define	EHCI_TUNE_MULT_TT	1
+
+/* Initial IRQ latency:  lower than default */
+static int log2_irq_thresh = 0;		// 0 to 6
+MODULE_PARM (log2_irq_thresh, "i");
+MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
+
+#define	INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT)
+
+/*-------------------------------------------------------------------------*/
+
+#include "ehci.h"
+#include "ehci-dbg.c"
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * hc states include: unknown, halted, ready, running
+ * transitional states are messy just now
+ * trying to avoid "running" unless urbs are active
+ * a "ready" hc can be finishing prefetched work
+ */
+
+/* halt a non-running controller */
+static void ehci_reset (struct ehci_hcd *ehci)
+{
+	u32	command = readl (&ehci->regs->command);
+
+	command |= CMD_RESET;
+	dbg_cmd (ehci, "reset", command);
+	writel (command, &ehci->regs->command);
+	while (readl (&ehci->regs->command) & CMD_RESET)
+		continue;
+	ehci->hcd.state = USB_STATE_HALT;
+}
+
+/* idle the controller (from running) */
+static void ehci_ready (struct ehci_hcd *ehci)
+{
+	u32	command;
+
+#ifdef DEBUG
+	if (!HCD_IS_RUNNING (ehci->hcd.state))
+		BUG ();
+#endif
+
+	while (!(readl (&ehci->regs->status) & (STS_ASS | STS_PSS)))
+		udelay (100);
+	command = readl (&ehci->regs->command);
+	command &= ~(CMD_ASE | CMD_IAAD | CMD_PSE);
+	writel (command, &ehci->regs->command);
+
+	// hardware can take 16 microframes to turn off ...
+	ehci->hcd.state = USB_STATE_READY;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#include "ehci-hub.c"
+#include "ehci-mem.c"
+#include "ehci-q.c"
+#include "ehci-sched.c"
+
+/*-------------------------------------------------------------------------*/
+
+static void ehci_tasklet (unsigned long param);
+
+/* called by khubd or root hub init threads */
+
+static int ehci_start (struct usb_hcd *hcd)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+	u32			temp;
+	struct usb_device	*udev;
+	int			retval;
+	u32			hcc_params;
+	u8                      tempbyte;
+
+	// FIXME:  given EHCI 0.96 or later, and a controller with
+	// the USBLEGSUP/USBLEGCTLSTS extended capability, make sure
+	// the BIOS doesn't still own this controller.
+
+	spin_lock_init (&ehci->lock);
+
+	ehci->caps = (struct ehci_caps *) hcd->regs;
+	ehci->regs = (struct ehci_regs *) (hcd->regs + ehci->caps->length);
+	dbg_hcs_params (ehci, "ehci_start");
+	dbg_hcc_params (ehci, "ehci_start");
+
+	/* cache this readonly data; minimize PCI reads */
+	ehci->hcs_params = readl (&ehci->caps->hcs_params);
+
+	/*
+	 * hw default: 1K periodic list heads, one per frame.
+	 * periodic_size can shrink by USBCMD update if hcc_params allows.
+	 */
+	ehci->periodic_size = DEFAULT_I_TDPS;
+	if ((retval = ehci_mem_init (ehci, SLAB_KERNEL)) < 0)
+		return retval;
+	hcc_params = readl (&ehci->caps->hcc_params);
+
+	/* controllers may cache some of the periodic schedule ... */
+	if (HCC_ISOC_CACHE (hcc_params)) 	// full frame cache
+		ehci->i_thresh = 8;
+	else					// N microframes cached
+		ehci->i_thresh = 2 + HCC_ISOC_THRES (hcc_params);
+
+	ehci->async = 0;
+	ehci->reclaim = 0;
+	ehci->next_uframe = -1;
+
+	/* controller state:  unknown --> reset */
+
+	/* EHCI spec section 4.1 */
+	// FIXME require STS_HALT before reset...
+	ehci_reset (ehci);
+	writel (INTR_MASK, &ehci->regs->intr_enable);
+	writel (ehci->periodic_dma, &ehci->regs->frame_list);
+
+	/*
+	 * hcc_params controls whether ehci->regs->segment must (!!!)
+	 * be used; it constrains QH/ITD/SITD and QTD locations.
+	 * pci_pool consistent memory always uses segment zero.
+	 */
+	if (HCC_64BIT_ADDR (hcc_params)) {
+		writel (0, &ehci->regs->segment);
+		/*
+		 * FIXME Enlarge pci_set_dma_mask() when possible.  The DMA
+		 * mapping API spec now says that'll affect only single shot
+		 * mappings, and the pci_pool data will stay safe in seg 0.
+		 * That's what we want:  no extra copies for USB transfers.
+		 */
+		info ("restricting 64bit DMA mappings to segment 0 ...");
+	}
+
+	/* clear interrupt enables, set irq latency */
+	temp = readl (&ehci->regs->command) & 0xff;
+	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
+	    log2_irq_thresh = 0;
+	temp |= 1 << (16 + log2_irq_thresh);
+	// keeping default periodic framelist size
+	temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE),
+	// Philips, Intel, and maybe others need CMD_RUN before the
+	// root hub will detect new devices (why?); NEC doesn't
+	temp |= CMD_RUN;
+	writel (temp, &ehci->regs->command);
+	dbg_cmd (ehci, "init", temp);
+
+	/* set async sleep time = 10 us ... ? */
+
+	ehci->tasklet.func = ehci_tasklet;
+	ehci->tasklet.data = (unsigned long) ehci;
+
+	/* wire up the root hub */
+	hcd->bus->root_hub = udev = usb_alloc_dev (NULL, hcd->bus);
+	if (!udev) {
+done2:
+		ehci_mem_cleanup (ehci);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
+	 * are explicitly handed to companion controller(s), so no TT is
+	 * involved with the root hub.
+	 */
+	ehci->hcd.state = USB_STATE_READY;
+	writel (FLAG_CF, &ehci->regs->configured_flag);
+	readl (&ehci->regs->command);	/* unblock posted write */
+
+        /* PCI Serial Bus Release Number is at 0x60 offset */
+	pci_read_config_byte (hcd->pdev, 0x60, &tempbyte);
+	temp = readw (&ehci->caps->hci_version);
+	info ("USB %x.%x support enabled, EHCI rev %x.%2x",
+	      ((tempbyte & 0xf0)>>4),
+	      (tempbyte & 0x0f),
+	       temp >> 8,
+	       temp & 0xff);
+
+	/*
+	 * From here on, khubd concurrently accesses the root
+	 * hub; drivers will be talking to enumerated devices.
+	 *
+	 * Before this point the HC was idle/ready.  After, khubd
+	 * and device drivers may start it running.
+	 */
+	usb_connect (udev);
+	udev->speed = USB_SPEED_HIGH;
+	if (usb_new_device (udev) != 0) {
+		if (hcd->state == USB_STATE_RUNNING)
+			ehci_ready (ehci);
+		while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS))
+			udelay (100);
+		ehci_reset (ehci);
+		// usb_disconnect (udev); 
+		hcd->bus->root_hub = 0;
+		usb_free_dev (udev); 
+		retval = -ENODEV;
+		goto done2;
+	}
+
+	return 0;
+}
+
+/* always called by thread; normally rmmod */
+
+static void ehci_stop (struct usb_hcd *hcd)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+
+	dbg ("%s: stop", hcd->bus_name);
+
+	if (hcd->state == USB_STATE_RUNNING)
+		ehci_ready (ehci);
+	while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS))
+		udelay (100);
+	ehci_reset (ehci);
+
+	// root hub is shut down separately (first, when possible)
+	scan_async (ehci);
+	if (ehci->next_uframe != -1)
+		scan_periodic (ehci);
+	ehci_mem_cleanup (ehci);
+
+	dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));
+}
+
+static int ehci_get_frame (struct usb_hcd *hcd)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+	return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef	CONFIG_PM
+
+/* suspend/resume, section 4.3 */
+
+static int ehci_suspend (struct usb_hcd *hcd, u32 state)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+	int			ports;
+	int			i;
+
+	dbg ("%s: suspend to %d", hcd->bus_name, state);
+
+	ports = HCS_N_PORTS (ehci->hcs_params);
+
+	// FIXME:  This assumes what's probably a D3 level suspend...
+
+	// FIXME:  usb wakeup events on this bus should resume the machine.
+	// pci config register PORTWAKECAP controls which ports can do it;
+	// bios may have initted the register...
+
+	/* suspend each port, then stop the hc */
+	for (i = 0; i < ports; i++) {
+		int	temp = readl (&ehci->regs->port_status [i]);
+
+		if ((temp & PORT_PE) == 0
+				|| (temp & PORT_OWNER) != 0)
+			continue;
+dbg ("%s: suspend port %d", hcd->bus_name, i);
+		temp |= PORT_SUSPEND;
+		writel (temp, &ehci->regs->port_status [i]);
+	}
+
+	if (hcd->state == USB_STATE_RUNNING)
+		ehci_ready (ehci);
+	while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS))
+		udelay (100);
+	writel (readl (&ehci->regs->command) & ~CMD_RUN, &ehci->regs->command);
+
+// save pci FLADJ value
+
+	/* who tells PCI to reduce power consumption? */
+
+	return 0;
+}
+
+static int ehci_resume (struct usb_hcd *hcd)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+	int			ports;
+	int			i;
+
+	dbg ("%s: resume", hcd->bus_name);
+
+	ports = HCS_N_PORTS (ehci->hcs_params);
+
+	// FIXME:  if controller didn't retain state,
+	// return and let generic code clean it up
+	// test configured_flag ?
+
+	/* resume HC and each port */
+// restore pci FLADJ value
+	// khubd and drivers will set HC running, if needed;
+	hcd->state = USB_STATE_READY;
+	// FIXME Philips/Intel/... etc don't really have a "READY"
+	// state ... turn on CMD_RUN too
+	for (i = 0; i < ports; i++) {
+		int	temp = readl (&ehci->regs->port_status [i]);
+
+		if ((temp & PORT_PE) == 0
+				|| (temp & PORT_SUSPEND) != 0)
+			continue;
+dbg ("%s: resume port %d", hcd->bus_name, i);
+		temp |= PORT_RESUME;
+		writel (temp, &ehci->regs->port_status [i]);
+		readl (&ehci->regs->command);	/* unblock posted writes */
+
+		wait_ms (20);
+		temp &= ~PORT_RESUME;
+		writel (temp, &ehci->regs->port_status [i]);
+	}
+	readl (&ehci->regs->command);	/* unblock posted writes */
+	return 0;
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * tasklet scheduled by some interrupts and other events
+ * calls driver completion functions ... but not in_irq()
+ */
+static void ehci_tasklet (unsigned long param)
+{
+	struct ehci_hcd		*ehci = (struct ehci_hcd *) param;
+
+	if (ehci->reclaim_ready)
+		end_unlink_async (ehci);
+	scan_async (ehci);
+	if (ehci->next_uframe != -1)
+		scan_periodic (ehci);
+
+	// FIXME:  when nothing is connected to the root hub,
+	// turn off the RUN bit so the host can enter C3 "sleep" power
+	// saving mode; make root hub code scan memory less often.
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void ehci_irq (struct usb_hcd *hcd)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+	u32			status = readl (&ehci->regs->status);
+	int			bh;
+
+	status &= INTR_MASK;
+	if (!status)			/* irq sharing? */
+		return;
+
+	/* clear (just) interrupts */
+	writel (status, &ehci->regs->status);
+	readl (&ehci->regs->command);	/* unblock posted write */
+	bh = 0;
+
+#ifdef	EHCI_VERBOSE_DEBUG
+	/* unrequested/ignored: Port Change Detect, Frame List Rollover */
+	dbg_status (ehci, "irq", status);
+#endif
+
+	/* INT, ERR, and IAA interrupt rates can be throttled */
+
+	/* normal [4.15.1.2] or error [4.15.1.1] completion */
+	if (likely ((status & (STS_INT|STS_ERR)) != 0))
+		bh = 1;
+
+	/* complete the unlinking of some qh [4.15.2.3] */
+	if (status & STS_IAA) {
+		ehci->reclaim_ready = 1;
+		bh = 1;
+	}
+
+	/* PCI errors [4.15.2.4] */
+	if (unlikely ((status & STS_FATAL) != 0)) {
+		err ("%s: fatal error, state %x", hcd->bus_name, hcd->state);
+		ehci_reset (ehci);
+		// generic layer kills/unlinks all urbs
+		// then tasklet cleans up the rest
+		bh = 1;
+	}
+
+	/* most work doesn't need to be in_irq() */
+	if (likely (bh == 1))
+		tasklet_schedule (&ehci->tasklet);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * non-error returns are a promise to giveback() the urb later
+ * we drop ownership so next owner (or urb unlink) can get it
+ *
+ * urb + dev is in hcd_dev.urb_list
+ * we're queueing TDs onto software and hardware lists
+ *
+ * hcd-specific init for hcpriv hasn't been done yet
+ *
+ * NOTE:  EHCI queues control and bulk requests transparently, like OHCI.
+ */
+static int ehci_urb_enqueue (
+	struct usb_hcd	*hcd,
+	struct urb	*urb,
+	int		mem_flags
+) {
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+	struct list_head	qtd_list;
+
+	urb->transfer_flags &= ~EHCI_STATE_UNLINK;
+	INIT_LIST_HEAD (&qtd_list);
+	switch (usb_pipetype (urb->pipe)) {
+
+	case PIPE_CONTROL:
+	case PIPE_BULK:
+		if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
+			return -ENOMEM;
+		return submit_async (ehci, urb, &qtd_list, mem_flags);
+
+	case PIPE_INTERRUPT:
+		if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
+			return -ENOMEM;
+		return intr_submit (ehci, urb, &qtd_list, mem_flags);
+
+	case PIPE_ISOCHRONOUS:
+		if (urb->dev->speed == USB_SPEED_HIGH)
+			return itd_submit (ehci, urb, mem_flags);
+#ifdef have_split_iso
+		else
+			return sitd_submit (ehci, urb, mem_flags);
+#else
+		dbg ("no split iso support yet");
+		return -ENOSYS;
+#endif /* have_split_iso */
+
+	default:	/* can't happen */
+		return -ENOSYS;
+	}
+}
+
+/* remove from hardware lists
+ * completions normally happen asynchronously
+ */
+
+static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+	struct ehci_qh		*qh = (struct ehci_qh *) urb->hcpriv;
+	unsigned long		flags;
+
+	dbg ("%s urb_dequeue %p qh state %d",
+		hcd->bus_name, urb, qh->qh_state);
+
+	switch (usb_pipetype (urb->pipe)) {
+	case PIPE_CONTROL:
+	case PIPE_BULK:
+		spin_lock_irqsave (&ehci->lock, flags);
+		if (ehci->reclaim) {
+dbg ("dq: reclaim busy, %s", RUN_CONTEXT);
+			if (in_interrupt ()) {
+				spin_unlock_irqrestore (&ehci->lock, flags);
+				return -EAGAIN;
+			}
+			while (qh->qh_state == QH_STATE_LINKED
+					&& ehci->reclaim
+					&& ehci->hcd.state != USB_STATE_HALT
+					) {
+				spin_unlock_irqrestore (&ehci->lock, flags);
+// yeech ... this could spin for up to two frames!
+dbg ("wait for dequeue: state %d, reclaim %p, hcd state %d",
+    qh->qh_state, ehci->reclaim, ehci->hcd.state
+);
+				udelay (100);
+				spin_lock_irqsave (&ehci->lock, flags);
+			}
+		}
+		if (qh->qh_state == QH_STATE_LINKED)
+			start_unlink_async (ehci, qh);
+		spin_unlock_irqrestore (&ehci->lock, flags);
+		return 0;
+
+	case PIPE_INTERRUPT:
+		intr_deschedule (ehci, urb->start_frame, qh, urb->interval);
+		if (ehci->hcd.state == USB_STATE_HALT)
+			urb->status = -ESHUTDOWN;
+		qh_completions (ehci, qh, 1);
+		return 0;
+
+	case PIPE_ISOCHRONOUS:
+		// itd or sitd ...
+
+		// wait till next completion, do it then.
+		// completion irqs can wait up to 1024 msec,
+		urb->transfer_flags |= EHCI_STATE_UNLINK;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+/*-------------------------------------------------------------------------*/
+
+// bulk qh holds the data toggle
+
+static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
+{
+	struct hcd_dev		*dev = (struct hcd_dev *)udev->hcpriv;
+	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+	int			i;
+	unsigned long		flags;
+
+	/* ASSERT:  nobody can be submitting urbs for this any more */
+
+	dbg ("%s: free_config devnum %d", hcd->bus_name, udev->devnum);
+
+	spin_lock_irqsave (&ehci->lock, flags);
+	for (i = 0; i < 32; i++) {
+		if (dev->ep [i]) {
+			struct ehci_qh		*qh;
+
+			/* dev->ep never has ITDs or SITDs */
+			qh = (struct ehci_qh *) dev->ep [i];
+			vdbg ("free_config, ep 0x%02x qh %p", i, qh);
+			if (!list_empty (&qh->qtd_list)) {
+				dbg ("ep 0x%02x qh %p not empty!", i, qh);
+				BUG ();
+			}
+			dev->ep [i] = 0;
+
+			/* wait_ms() won't spin here -- we're a thread */
+			while (qh->qh_state == QH_STATE_LINKED
+					&& ehci->reclaim
+					&& ehci->hcd.state != USB_STATE_HALT
+					) {
+				spin_unlock_irqrestore (&ehci->lock, flags);
+				wait_ms (1);
+				spin_lock_irqsave (&ehci->lock, flags);
+			}
+			if (qh->qh_state == QH_STATE_LINKED) {
+				start_unlink_async (ehci, qh);
+				while (qh->qh_state != QH_STATE_IDLE) {
+					spin_unlock_irqrestore (&ehci->lock,
+						flags);
+					wait_ms (1);
+					spin_lock_irqsave (&ehci->lock, flags);
+				}
+			}
+			qh_put (ehci, qh);
+		}
+	}
+
+	spin_unlock_irqrestore (&ehci->lock, flags);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static const char	hcd_name [] = "ehci-hcd";
+
+static const struct hc_driver ehci_driver = {
+	description:		hcd_name,
+
+	/*
+	 * generic hardware linkage
+	 */
+	irq:			ehci_irq,
+	flags:			HCD_MEMORY | HCD_USB2,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	start:			ehci_start,
+#ifdef	CONFIG_PM
+	suspend:		ehci_suspend,
+	resume:			ehci_resume,
+#endif
+	stop:			ehci_stop,
+
+	/*
+	 * memory lifecycle (except per-request)
+	 */
+	hcd_alloc:		ehci_hcd_alloc,
+	hcd_free:		ehci_hcd_free,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	urb_enqueue:		ehci_urb_enqueue,
+	urb_dequeue:		ehci_urb_dequeue,
+	free_config:		ehci_free_config,
+
+	/*
+	 * scheduling support
+	 */
+	get_frame_number:	ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	hub_status_data:	ehci_hub_status_data,
+	hub_control:		ehci_hub_control,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* EHCI spec says PCI is required. */
+
+/* PCI driver selection metadata; PCI hotplugging uses this */
+static const struct pci_device_id __devinitdata pci_ids [] = { {
+
+	/* handle any USB 2.0 EHCI controller */
+
+	class: 		((PCI_CLASS_SERIAL_USB << 8) | 0x20),
+	class_mask: 	~0,
+	driver_data:	(unsigned long) &ehci_driver,
+
+	/* no matter who makes it */
+	vendor:		PCI_ANY_ID,
+	device:		PCI_ANY_ID,
+	subvendor:	PCI_ANY_ID,
+	subdevice:	PCI_ANY_ID,
+
+}, { /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE (pci, pci_ids);
+
+/* pci driver glue; this is a "new style" PCI driver module */
+static struct pci_driver ehci_pci_driver = {
+	name:		(char *) hcd_name,
+	id_table:	pci_ids,
+
+	probe:		usb_hcd_pci_probe,
+	remove:		usb_hcd_pci_remove,
+
+#ifdef	CONFIG_PM
+	suspend:	usb_hcd_pci_suspend,
+	resume:		usb_hcd_pci_resume,
+#endif
+};
+
+#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
+
+EXPORT_NO_SYMBOLS;
+MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_AUTHOR (DRIVER_AUTHOR);
+MODULE_LICENSE ("GPL");
+
+static int __init init (void) 
+{
+	dbg (DRIVER_INFO);
+	dbg ("block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd",
+		sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
+		sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
+
+	return pci_module_init (&ehci_pci_driver);
+}
+module_init (init);
+
+static void __exit cleanup (void) 
+{	
+	pci_unregister_driver (&ehci_pci_driver);
+}
+module_exit (cleanup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/ehci-hub.c linux/drivers/usb/hcd/ehci-hub.c
--- linux.orig/drivers/usb/hcd/ehci-hub.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/ehci-hub.c	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2001-2002 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* this file is part of ehci-hcd.c */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI Root Hub ... the nonsharable stuff
+ *
+ * Registers don't need cpu_to_le32, that happens transparently
+ */
+
+/*-------------------------------------------------------------------------*/
+
+static int check_reset_complete (
+	struct ehci_hcd	*ehci,
+	int		index,
+	int		port_status
+) {
+	if (!(port_status & PORT_CONNECT)) {
+		ehci->reset_done [index] = 0;
+		return port_status;
+	}
+
+	/* if reset finished and it's still not enabled -- handoff */
+	if (!(port_status & PORT_PE)) {
+		dbg ("%s port %d full speed, give to companion, 0x%x",
+			ehci->hcd.bus_name, index + 1, port_status);
+
+		// what happens if HCS_N_CC(params) == 0 ?
+		port_status |= PORT_OWNER;
+		writel (port_status, &ehci->regs->port_status [index]);
+
+	} else
+		dbg ("%s port %d high speed", ehci->hcd.bus_name, index + 1);
+
+	return port_status;
+}
+
+/*-------------------------------------------------------------------------*/
+
+
+/* build "status change" packet (one or two bytes) from HC registers */
+
+static int
+ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
+{
+	struct ehci_hcd	*ehci = hcd_to_ehci (hcd);
+	u32		temp, status = 0;
+	int		ports, i, retval = 1;
+	unsigned long	flags;
+
+	/* init status to no-changes */
+	buf [0] = 0;
+	ports = HCS_N_PORTS (ehci->hcs_params);
+	if (ports > 7) {
+		buf [1] = 0;
+		retval++;
+	}
+	
+	/* no hub change reports (bit 0) for now (power, ...) */
+
+	/* port N changes (bit N)? */
+	spin_lock_irqsave (&ehci->lock, flags);
+	for (i = 0; i < ports; i++) {
+		temp = readl (&ehci->regs->port_status [i]);
+		if (temp & PORT_OWNER) {
+			/* don't report this in GetPortStatus */
+			if (temp & PORT_CSC) {
+				temp &= ~PORT_CSC;
+				writel (temp, &ehci->regs->port_status [i]);
+			}
+			continue;
+		}
+		if (!(temp & PORT_CONNECT))
+			ehci->reset_done [i] = 0;
+		if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0) {
+			if (i < 7)
+			    buf [0] |= 1 << (i + 1);
+			else
+			    buf [1] |= 1 << (i - 7);
+			status = STS_PCD;
+		}
+	}
+	spin_unlock_irqrestore (&ehci->lock, flags);
+	return status ? retval : 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void
+ehci_hub_descriptor (
+	struct ehci_hcd			*ehci,
+	struct usb_hub_descriptor	*desc
+) {
+	int		ports = HCS_N_PORTS (ehci->hcs_params);
+	u16		temp;
+
+	desc->bDescriptorType = 0x29;
+	desc->bPwrOn2PwrGood = 0;	/* FIXME: f(system power) */
+	desc->bHubContrCurrent = 0;
+
+	desc->bNbrPorts = ports;
+	temp = 1 + (ports / 8);
+	desc->bDescLength = 7 + 2 * temp;
+
+	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
+	memset (&desc->bitmap [0], 0, temp);
+	memset (&desc->bitmap [temp], 0xff, temp);
+
+	temp = 0x0008;			/* per-port overcurrent reporting */
+	if (HCS_PPC (ehci->hcs_params))
+		temp |= 0x0001;		/* per-port power control */
+	if (HCS_INDICATOR (ehci->hcs_params))
+		temp |= 0x0080;		/* per-port indicators (LEDs) */
+	desc->wHubCharacteristics = cpu_to_le16 (temp);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int ehci_hub_control (
+	struct usb_hcd	*hcd,
+	u16		typeReq,
+	u16		wValue,
+	u16		wIndex,
+	char		*buf,
+	u16		wLength
+) {
+	struct ehci_hcd	*ehci = hcd_to_ehci (hcd);
+	int		ports = HCS_N_PORTS (ehci->hcs_params);
+	u32		temp, status;
+	unsigned long	flags;
+	int		retval = 0;
+
+	/*
+	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
+	 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
+	 * (track current state ourselves) ... blink for diagnostics,
+	 * power, "this is the one", etc.  EHCI spec supports this.
+	 */
+
+	spin_lock_irqsave (&ehci->lock, flags);
+	switch (typeReq) {
+	case ClearHubFeature:
+		switch (wValue) {
+		case C_HUB_LOCAL_POWER:
+		case C_HUB_OVER_CURRENT:
+			/* no hub-wide feature/status flags */
+			break;
+		default:
+			goto error;
+		}
+		break;
+	case ClearPortFeature:
+		if (!wIndex || wIndex > ports)
+			goto error;
+		wIndex--;
+		temp = readl (&ehci->regs->port_status [wIndex]);
+		if (temp & PORT_OWNER)
+			break;
+
+		switch (wValue) {
+		case USB_PORT_FEAT_ENABLE:
+			writel (temp & ~PORT_PE,
+				&ehci->regs->port_status [wIndex]);
+			break;
+		case USB_PORT_FEAT_C_ENABLE:
+			writel (temp | PORT_PEC,
+				&ehci->regs->port_status [wIndex]);
+			break;
+		case USB_PORT_FEAT_SUSPEND:
+		case USB_PORT_FEAT_C_SUSPEND:
+			/* ? */
+			break;
+		case USB_PORT_FEAT_POWER:
+			if (HCS_PPC (ehci->hcs_params))
+				writel (temp & ~PORT_POWER,
+					&ehci->regs->port_status [wIndex]);
+			break;
+		case USB_PORT_FEAT_C_CONNECTION:
+			writel (temp | PORT_CSC,
+				&ehci->regs->port_status [wIndex]);
+			break;
+		case USB_PORT_FEAT_C_OVER_CURRENT:
+			writel (temp | PORT_OCC,
+				&ehci->regs->port_status [wIndex]);
+			break;
+		case USB_PORT_FEAT_C_RESET:
+			/* GetPortStatus clears reset */
+			break;
+		default:
+			goto error;
+		}
+		readl (&ehci->regs->command);	/* unblock posted write */
+		break;
+	case GetHubDescriptor:
+		ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
+			buf);
+		break;
+	case GetHubStatus:
+		/* no hub-wide feature/status flags */
+		memset (buf, 0, 4);
+		//cpu_to_le32s ((u32 *) buf);
+		break;
+	case GetPortStatus:
+		if (!wIndex || wIndex > ports)
+			goto error;
+		wIndex--;
+		status = 0;
+		temp = readl (&ehci->regs->port_status [wIndex]);
+
+		// wPortChange bits
+		if (temp & PORT_CSC)
+			status |= 1 << USB_PORT_FEAT_C_CONNECTION;
+		if (temp & PORT_PEC)
+			status |= 1 << USB_PORT_FEAT_C_ENABLE;
+		// USB_PORT_FEAT_C_SUSPEND
+		if (temp & PORT_OCC)
+			status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
+
+		/* whoever resets must GetPortStatus to complete it!! */
+		if ((temp & PORT_RESET)
+				&& jiffies > ehci->reset_done [wIndex]) {
+			status |= 1 << USB_PORT_FEAT_C_RESET;
+
+			/* force reset to complete */
+			writel (temp & ~PORT_RESET,
+					&ehci->regs->port_status [wIndex]);
+			do {
+				temp = readl (
+					&ehci->regs->port_status [wIndex]);
+				udelay (10);
+			} while (temp & PORT_RESET);
+
+			/* see what we found out */
+			temp = check_reset_complete (ehci, wIndex, temp);
+		}
+
+		// don't show wPortStatus if it's owned by a companion hc
+		if (!(temp & PORT_OWNER)) {
+			if (temp & PORT_CONNECT) {
+				status |= 1 << USB_PORT_FEAT_CONNECTION;
+				status |= 1 << USB_PORT_FEAT_HIGHSPEED;
+			}
+			if (temp & PORT_PE)
+				status |= 1 << USB_PORT_FEAT_ENABLE;
+			if (temp & PORT_SUSPEND)
+				status |= 1 << USB_PORT_FEAT_SUSPEND;
+			if (temp & PORT_OC)
+				status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
+			if (temp & PORT_RESET)
+				status |= 1 << USB_PORT_FEAT_RESET;
+			if (temp & PORT_POWER)
+				status |= 1 << USB_PORT_FEAT_POWER;
+		}
+
+#ifndef	EHCI_VERBOSE_DEBUG
+	if (status & ~0xffff)	/* only if wPortChange is interesting */
+#endif
+		dbg_port (hcd, "GetStatus", wIndex + 1, temp);
+		// we "know" this alignment is good, caller used kmalloc()...
+		*((u32 *) buf) = cpu_to_le32 (status);
+		break;
+	case SetHubFeature:
+		switch (wValue) {
+		case C_HUB_LOCAL_POWER:
+		case C_HUB_OVER_CURRENT:
+			/* no hub-wide feature/status flags */
+			break;
+		default:
+			goto error;
+		}
+		break;
+	case SetPortFeature:
+		if (!wIndex || wIndex > ports)
+			goto error;
+		wIndex--;
+		temp = readl (&ehci->regs->port_status [wIndex]);
+		if (temp & PORT_OWNER)
+			break;
+
+		switch (wValue) {
+		case USB_PORT_FEAT_SUSPEND:
+			writel (temp | PORT_SUSPEND,
+				&ehci->regs->port_status [wIndex]);
+			break;
+		case USB_PORT_FEAT_POWER:
+			if (HCS_PPC (ehci->hcs_params))
+				writel (temp | PORT_POWER,
+					&ehci->regs->port_status [wIndex]);
+			break;
+		case USB_PORT_FEAT_RESET:
+			/* line status bits may report this as low speed */
+			if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
+					&& PORT_USB11 (temp)) {
+				dbg ("%s port %d low speed, give to companion",
+					hcd->bus_name, wIndex + 1);
+				temp |= PORT_OWNER;
+			} else {
+				vdbg ("%s port %d reset",
+					hcd->bus_name, wIndex + 1);
+				temp |= PORT_RESET;
+				temp &= ~PORT_PE;
+
+				/*
+				 * caller must wait, then call GetPortStatus
+				 * usb 2.0 spec says 50 ms resets on root
+				 */
+				ehci->reset_done [wIndex] = jiffies
+				    	+ ((50 /* msec */ * HZ) / 1000);
+			}
+			writel (temp, &ehci->regs->port_status [wIndex]);
+			break;
+		default:
+			goto error;
+		}
+		readl (&ehci->regs->command);	/* unblock posted writes */
+		break;
+
+	default:
+error:
+		/* "stall" on error */
+		retval = -EPIPE;
+	}
+	spin_unlock_irqrestore (&ehci->lock, flags);
+	return retval;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/ehci-mem.c linux/drivers/usb/hcd/ehci-mem.c
--- linux.orig/drivers/usb/hcd/ehci-mem.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/ehci-mem.c	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2001 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* this file is part of ehci-hcd.c */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * There's basically three types of memory:
+ *	- data used only by the HCD ... kmalloc is fine
+ *	- async and periodic schedules, shared by HC and HCD ... these
+ *	  need to use pci_pool or pci_alloc_consistent
+ *	- driver buffers, read/written by HC ... single shot DMA mapped 
+ *
+ * There's also PCI "register" data, which is memory mapped.
+ * No memory seen by this driver is pagable.
+ */
+
+/*-------------------------------------------------------------------------*/
+/* 
+ * Allocator / cleanup for the per device structure
+ * Called by hcd init / removal code
+ */
+static struct usb_hcd *ehci_hcd_alloc (void)
+{
+	struct ehci_hcd *ehci;
+
+	ehci = (struct ehci_hcd *)
+		kmalloc (sizeof (struct ehci_hcd), GFP_KERNEL);
+	if (ehci != 0) {
+		memset (ehci, 0, sizeof (struct ehci_hcd));
+		return &ehci->hcd;
+	}
+	return 0;
+}
+
+static void ehci_hcd_free (struct usb_hcd *hcd)
+{
+	kfree (hcd_to_ehci (hcd));
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Allocate the key transfer structures from the previously allocated pool */
+
+static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags)
+{
+	struct ehci_qtd		*qtd;
+	dma_addr_t		dma;
+
+	qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma);
+	if (qtd != 0) {
+		memset (qtd, 0, sizeof *qtd);
+		qtd->qtd_dma = dma;
+		qtd->hw_next = EHCI_LIST_END;
+		qtd->hw_alt_next = EHCI_LIST_END;
+		INIT_LIST_HEAD (&qtd->qtd_list);
+	}
+	return qtd;
+}
+
+static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
+{
+	pci_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma);
+}
+
+
+static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
+{
+	struct ehci_qh		*qh;
+	dma_addr_t		dma;
+
+	qh = (struct ehci_qh *)
+		pci_pool_alloc (ehci->qh_pool, flags, &dma);
+	if (qh) {
+		memset (qh, 0, sizeof *qh);
+		atomic_set (&qh->refcount, 1);
+		qh->qh_dma = dma;
+		// INIT_LIST_HEAD (&qh->qh_list);
+		INIT_LIST_HEAD (&qh->qtd_list);
+	}
+	return qh;
+}
+
+/* to share a qh (cpu threads, or hc) */
+static inline struct ehci_qh *qh_get (/* ehci, */ struct ehci_qh *qh)
+{
+	// dbg ("get %p (%d++)", qh, qh->refcount.counter);
+	atomic_inc (&qh->refcount);
+	return qh;
+}
+
+static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+	// dbg ("put %p (--%d)", qh, qh->refcount.counter);
+	if (!atomic_dec_and_test (&qh->refcount))
+		return;
+	/* clean qtds first, and know this is not linked */
+	if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
+		dbg ("unused qh not empty!");
+		BUG ();
+	}
+	pci_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* The queue heads and transfer descriptors are managed from pools tied 
+ * to each of the "per device" structures.
+ * This is the initialisation and cleanup code.
+ */
+
+static void ehci_mem_cleanup (struct ehci_hcd *ehci)
+{
+	/* PCI consistent memory and pools */
+	if (ehci->qtd_pool)
+		pci_pool_destroy (ehci->qtd_pool);
+	ehci->qtd_pool = 0;
+
+	if (ehci->qh_pool) {
+		pci_pool_destroy (ehci->qh_pool);
+		ehci->qh_pool = 0;
+	}
+
+	if (ehci->itd_pool)
+		pci_pool_destroy (ehci->itd_pool);
+	ehci->itd_pool = 0;
+
+	if (ehci->sitd_pool)
+		pci_pool_destroy (ehci->sitd_pool);
+	ehci->sitd_pool = 0;
+
+	if (ehci->periodic)
+		pci_free_consistent (ehci->hcd.pdev,
+			ehci->periodic_size * sizeof (u32),
+			ehci->periodic, ehci->periodic_dma);
+	ehci->periodic = 0;
+
+	/* shadow periodic table */
+	if (ehci->pshadow)
+		kfree (ehci->pshadow);
+	ehci->pshadow = 0;
+}
+
+/* remember to add cleanup code (above) if you add anything here */
+static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
+{
+	int i;
+
+	/* QTDs for control/bulk/intr transfers */
+	ehci->qtd_pool = pci_pool_create ("ehci_qtd", ehci->hcd.pdev,
+			sizeof (struct ehci_qtd),
+			32 /* byte alignment (for hw parts) */,
+			4096 /* can't cross 4K */,
+			flags);
+	if (!ehci->qtd_pool) {
+		dbg ("no qtd pool");
+		ehci_mem_cleanup (ehci);
+		return -ENOMEM;
+	}
+
+	/* QH for control/bulk/intr transfers */
+	ehci->qh_pool = pci_pool_create ("ehci_qh", ehci->hcd.pdev,
+			sizeof (struct ehci_qh),
+			32 /* byte alignment (for hw parts) */,
+			4096 /* can't cross 4K */,
+			flags);
+	if (!ehci->qh_pool) {
+		dbg ("no qh pool");
+		ehci_mem_cleanup (ehci);
+		return -ENOMEM;
+	}
+
+	/* ITD for high speed ISO transfers */
+	ehci->itd_pool = pci_pool_create ("ehci_itd", ehci->hcd.pdev,
+			sizeof (struct ehci_itd),
+			32 /* byte alignment (for hw parts) */,
+			4096 /* can't cross 4K */,
+			flags);
+	if (!ehci->itd_pool) {
+		dbg ("no itd pool");
+		ehci_mem_cleanup (ehci);
+		return -ENOMEM;
+	}
+
+	/* SITD for full/low speed split ISO transfers */
+	ehci->sitd_pool = pci_pool_create ("ehci_sitd", ehci->hcd.pdev,
+			sizeof (struct ehci_sitd),
+			32 /* byte alignment (for hw parts) */,
+			4096 /* can't cross 4K */,
+			flags);
+	if (!ehci->sitd_pool) {
+		dbg ("no sitd pool");
+		ehci_mem_cleanup (ehci);
+		return -ENOMEM;
+	}
+
+	/* Hardware periodic table */
+	ehci->periodic = (u32 *)
+		pci_alloc_consistent (ehci->hcd.pdev,
+			ehci->periodic_size * sizeof (u32),
+			&ehci->periodic_dma);
+	if (ehci->periodic == 0) {
+		dbg ("no hw periodic table");
+		ehci_mem_cleanup (ehci);
+		return -ENOMEM;
+	}
+	for (i = 0; i < ehci->periodic_size; i++)
+		ehci->periodic [i] = EHCI_LIST_END;
+
+	/* software shadow of hardware table */
+	ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags);
+	if (ehci->pshadow == 0) {
+		dbg ("no shadow periodic table");
+		ehci_mem_cleanup (ehci);
+		return -ENOMEM;
+	}
+	memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *));
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/ehci-q.c linux/drivers/usb/hcd/ehci-q.c
--- linux.orig/drivers/usb/hcd/ehci-q.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/ehci-q.c	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,1002 @@
+/*
+ * Copyright (c) 2001-2002 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* this file is part of ehci-hcd.c */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
+ *
+ * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
+ * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
+ * buffers needed for the larger number).  We use one QH per endpoint, queue
+ * multiple (bulk or control) urbs per endpoint.  URBs may need several qtds.
+ * A scheduled interrupt qh always (for now) has one qtd, one urb.
+ *
+ * ISO traffic uses "ISO TD" (itd, and sitd) records, and (along with
+ * interrupts) needs careful scheduling.  Performance improvements can be
+ * an ongoing challenge.  That's in "ehci-sched.c".
+ * 
+ * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
+ * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
+ * (b) special fields in qh entries or (c) split iso entries.  TTs will
+ * buffer low/full speed data so the host collects it at high speed.
+ */
+
+/*-------------------------------------------------------------------------*/
+
+/* fill a qtd, returning how much of the buffer we were able to queue up */
+
+static int
+qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token)
+{
+	int	i, count;
+
+	/* one buffer entry per 4K ... first might be short or unaligned */
+	qtd->hw_buf [0] = cpu_to_le32 (buf);
+	count = 0x1000 - (buf & 0x0fff);	/* rest of that page */
+	if (likely (len < count))		/* ... iff needed */
+		count = len;
+	else {
+		buf +=  0x1000;
+		buf &= ~0x0fff;
+
+		/* per-qtd limit: from 16K to 20K (best alignment) */
+		for (i = 1; count < len && i < 5; i++) {
+			u64	addr = buf;
+			qtd->hw_buf [i] = cpu_to_le32 ((u32)addr);
+			qtd->hw_buf_hi [i] = cpu_to_le32 ((u32)(addr >> 32));
+			buf += 0x1000;
+			if ((count + 0x1000) < len)
+				count += 0x1000;
+			else
+				count = len;
+		}
+	}
+	qtd->hw_token = cpu_to_le32 ((count << 16) | token);
+	qtd->length = count;
+
+#if 0
+	vdbg ("  qtd_fill %p, token %8x bytes %d dma %x",
+		qtd, le32_to_cpu (qtd->hw_token), count, qtd->hw_buf [0]);
+#endif
+
+	return count;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* update halted (but potentially linked) qh */
+
+static inline void qh_update (struct ehci_qh *qh, struct ehci_qtd *qtd)
+{
+	qh->hw_current = 0;
+	qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
+	qh->hw_alt_next = EHCI_LIST_END;
+
+	/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
+	wmb ();
+	qh->hw_token &= __constant_cpu_to_le32 (QTD_TOGGLE | QTD_STS_PING);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static inline void qtd_copy_status (struct urb *urb, size_t length, u32 token)
+{
+	/* count IN/OUT bytes, not SETUP (even short packets) */
+	if (likely (QTD_PID (token) != 2))
+		urb->actual_length += length - QTD_LENGTH (token);
+
+	/* don't modify error codes */
+	if (unlikely (urb->status == -EINPROGRESS && (token & QTD_STS_HALT))) {
+		if (token & QTD_STS_BABBLE) {
+			/* FIXME "must" disable babbling device's port too */
+			urb->status = -EOVERFLOW;
+		} else if (token & QTD_STS_MMF) {
+			/* fs/ls interrupt xfer missed the complete-split */
+			urb->status = -EPROTO;
+		} else if (token & QTD_STS_DBE) {
+			urb->status = (QTD_PID (token) == 1) /* IN ? */
+				? -ENOSR  /* hc couldn't read data */
+				: -ECOMM; /* hc couldn't write data */
+		} else if (token & QTD_STS_XACT) {
+			/* timeout, bad crc, wrong PID, etc; retried */
+			if (QTD_CERR (token))
+				urb->status = -EPIPE;
+			else {
+				dbg ("3strikes");
+				urb->status = -EPROTO;
+			}
+		/* CERR nonzero + no errors + halt --> stall */
+		} else if (QTD_CERR (token))
+			urb->status = -EPIPE;
+		else	/* unknown */
+			urb->status = -EPROTO;
+
+		dbg ("ep %d-%s qtd token %08x --> status %d",
+			/* devpath */
+			usb_pipeendpoint (urb->pipe),
+			usb_pipein (urb->pipe) ? "in" : "out",
+			token, urb->status);
+
+		/* stall indicates some recovery action is needed */
+		if (urb->status == -EPIPE) {
+			int	pipe = urb->pipe;
+
+			if (!usb_pipecontrol (pipe))
+				usb_endpoint_halt (urb->dev,
+					usb_pipeendpoint (pipe),
+					usb_pipeout (pipe));
+			if (urb->dev->tt && !usb_pipeint (pipe)) {
+err ("must CLEAR_TT_BUFFER, hub port %d%s addr %d ep %d",
+    urb->dev->ttport, /* devpath */
+    urb->dev->tt->multi ? "" : " (all-ports TT)",
+    urb->dev->devnum, usb_pipeendpoint (urb->pipe));
+				// FIXME something (khubd?) should make the hub
+				// CLEAR_TT_BUFFER ASAP, it's blocking other
+				// fs/ls requests... hub_tt_clear_buffer() ?
+			}
+		}
+	}
+}
+
+static void ehci_urb_complete (
+	struct ehci_hcd		*ehci,
+	dma_addr_t		addr,
+	struct urb		*urb
+) {
+	if (urb->transfer_buffer_length && usb_pipein (urb->pipe))
+		pci_dma_sync_single (ehci->hcd.pdev, addr,
+			urb->transfer_buffer_length,
+			PCI_DMA_FROMDEVICE);
+
+	/* cleanse status if we saw no error */
+	if (likely (urb->status == -EINPROGRESS)) {
+		if (urb->actual_length != urb->transfer_buffer_length
+				&& (urb->transfer_flags & USB_DISABLE_SPD))
+			urb->status = -EREMOTEIO;
+		else
+			urb->status = 0;
+	}
+
+	/* only report unlinks once */
+	if (likely (urb->status != -ENOENT && urb->status != -ENOTCONN))
+		urb->complete (urb);
+}
+
+/* urb->lock ignored from here on (hcd is done with urb) */
+
+static void ehci_urb_done (
+	struct ehci_hcd		*ehci,
+	dma_addr_t		addr,
+	struct urb		*urb
+) {
+	if (urb->transfer_buffer_length)
+		pci_unmap_single (ehci->hcd.pdev,
+			addr,
+			urb->transfer_buffer_length,
+			usb_pipein (urb->pipe)
+			    ? PCI_DMA_FROMDEVICE
+			    : PCI_DMA_TODEVICE);
+	if (likely (urb->hcpriv != 0)) {
+		qh_put (ehci, (struct ehci_qh *) urb->hcpriv);
+		urb->hcpriv = 0;
+	}
+
+	if (likely (urb->status == -EINPROGRESS)) {
+		if (urb->actual_length != urb->transfer_buffer_length
+				&& (urb->transfer_flags & USB_DISABLE_SPD))
+			urb->status = -EREMOTEIO;
+		else
+			urb->status = 0;
+	}
+
+	/* hand off urb ownership */
+	usb_hcd_giveback_urb (&ehci->hcd, urb);
+}
+
+
+/*
+ * Process completed qtds for a qh, issuing completions if needed.
+ * When freeing:  frees qtds, unmaps buf, returns URB to driver.
+ * When not freeing (queued periodic qh):  retain qtds, mapping, and urb.
+ * Races up to qh->hw_current; returns number of urb completions.
+ */
+static int
+qh_completions (
+	struct ehci_hcd		*ehci,
+	struct ehci_qh		*qh,
+	int			freeing
+) {
+	struct ehci_qtd		*qtd, *last;
+	struct list_head	*next, *qtd_list = &qh->qtd_list;
+	int			unlink = 0, halted = 0;
+	unsigned long		flags;
+	int			retval = 0;
+
+	spin_lock_irqsave (&ehci->lock, flags);
+	if (unlikely (list_empty (qtd_list))) {
+		spin_unlock_irqrestore (&ehci->lock, flags);
+		return retval;
+	}
+
+	/* scan QTDs till end of list, or we reach an active one */
+	for (qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list),
+			    	last = 0, next = 0;
+			next != qtd_list;
+			last = qtd, qtd = list_entry (next,
+						struct ehci_qtd, qtd_list)) {
+		struct urb	*urb = qtd->urb;
+		u32		token = 0;
+
+		/* clean up any state from previous QTD ...*/
+		if (last) {
+			if (likely (last->urb != urb)) {
+				/* complete() can reenter this HCD */
+				spin_unlock_irqrestore (&ehci->lock, flags);
+				if (likely (freeing != 0))
+					ehci_urb_done (ehci, last->buf_dma,
+						last->urb);
+				else
+					ehci_urb_complete (ehci, last->buf_dma,
+						last->urb);
+				spin_lock_irqsave (&ehci->lock, flags);
+				retval++;
+			}
+
+			/* qh overlays can have HC's old cached copies of
+			 * next qtd ptrs, if an URB was queued afterwards.
+			 */
+			if (cpu_to_le32 (last->qtd_dma) == qh->hw_current
+					&& last->hw_next != qh->hw_qtd_next) {
+				qh->hw_alt_next = last->hw_alt_next;
+				qh->hw_qtd_next = last->hw_next;
+			}
+
+			if (likely (freeing != 0))
+				ehci_qtd_free (ehci, last);
+			last = 0;
+		}
+		next = qtd->qtd_list.next;
+
+		/* QTDs at tail may be active if QH+HC are running,
+		 * or when unlinking some urbs queued to this QH
+		 */
+		token = le32_to_cpu (qtd->hw_token);
+		halted = halted
+			|| (__constant_cpu_to_le32 (QTD_STS_HALT)
+				& qh->hw_token) != 0
+			|| (ehci->hcd.state == USB_STATE_HALT)
+			|| (qh->qh_state == QH_STATE_IDLE);
+
+		/* fault: unlink the rest, since this qtd saw an error? */
+		if (unlikely ((token & QTD_STS_HALT) != 0)) {
+			freeing = unlink = 1;
+			/* status copied below */
+
+		/* QH halts only because of fault (above) or unlink (here). */
+		} else if (unlikely (halted != 0)) {
+
+			/* unlinking everything because of HC shutdown? */
+			if (ehci->hcd.state == USB_STATE_HALT) {
+				freeing = unlink = 1;
+
+			/* explicit unlink, maybe starting here? */
+			} else if (qh->qh_state == QH_STATE_IDLE
+					&& (urb->status == -ECONNRESET
+						|| urb->status == -ENOENT)) {
+				freeing = unlink = 1;
+
+			/* QH halted to unlink urbs _after_ this?  */
+			} else if (!unlink && (token & QTD_STS_ACTIVE) != 0) {
+				qtd = 0;
+				continue;
+			}
+
+			/* unlink the rest?  once we start unlinking, after
+			 * a fault or explicit unlink, we unlink all later
+			 * urbs.  usb spec requires that.
+			 */
+			if (unlink && urb->status == -EINPROGRESS)
+				urb->status = -ECONNRESET;
+
+		/* Else QH is active, so we must not modify QTDs
+		 * that HC may be working on.  No more qtds to check.
+		 */
+		} else if (unlikely ((token & QTD_STS_ACTIVE) != 0)) {
+			next = qtd_list;
+			qtd = 0;
+			continue;
+		}
+
+		spin_lock (&urb->lock);
+		qtd_copy_status (urb, qtd->length, token);
+		spin_unlock (&urb->lock);
+
+		/*
+		 * NOTE:  this won't work right with interrupt urbs that
+		 * need multiple qtds ... only the first scan of qh->qtd_list
+		 * starts at the right qtd, yet multiple scans could happen
+		 * for transfers that are scheduled across multiple uframes. 
+		 * (Such schedules are not currently allowed!)
+		 */
+		if (likely (freeing != 0))
+			list_del (&qtd->qtd_list);
+		else {
+			/* restore everything the HC could change
+			 * from an interrupt QTD
+			 */
+			qtd->hw_token = (qtd->hw_token
+					& __constant_cpu_to_le32 (0x8300))
+				| cpu_to_le32 (qtd->length << 16)
+				| __constant_cpu_to_le32 (QTD_STS_ACTIVE
+					| (EHCI_TUNE_CERR << 10));
+			qtd->hw_buf [0] &= ~__constant_cpu_to_le32 (0x0fff);
+
+			/* this offset, and the length above,
+			 * are likely wrong on QTDs #2..N
+			 */
+			qtd->hw_buf [0] |= cpu_to_le32 (0x0fff & qtd->buf_dma);
+		}
+
+#if 0
+		if (urb->status == -EINPROGRESS)
+			vdbg ("  qtd %p ok, urb %p, token %8x, len %d",
+				qtd, urb, token, urb->actual_length);
+		else
+			vdbg ("urb %p status %d, qtd %p, token %8x, len %d",
+				urb, urb->status, qtd, token,
+				urb->actual_length);
+#endif
+
+		/* SETUP for control urb? */
+		if (unlikely (QTD_PID (token) == 2))
+			pci_unmap_single (ehci->hcd.pdev,
+				qtd->buf_dma, sizeof (devrequest),
+				PCI_DMA_TODEVICE);
+	}
+
+	/* patch up list head? */
+	if (unlikely (halted && !list_empty (qtd_list))) {
+		qh_update (qh, list_entry (qtd_list->next,
+				struct ehci_qtd, qtd_list));
+	}
+	spin_unlock_irqrestore (&ehci->lock, flags);
+
+	/* last urb's completion might still need calling */
+	if (likely (last != 0)) {
+		if (likely (freeing != 0)) {
+			ehci_urb_done (ehci, last->buf_dma, last->urb);
+			ehci_qtd_free (ehci, last);
+		} else
+			ehci_urb_complete (ehci, last->buf_dma, last->urb);
+		retval++;
+	}
+	return retval;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * reverse of qh_urb_transaction:  free a list of TDs.
+ * used for cleanup after errors, before HC sees an URB's TDs.
+ */
+static void qtd_list_free (
+	struct ehci_hcd		*ehci,
+	struct urb		*urb,
+	struct list_head	*qtd_list
+) {
+	struct list_head	*entry, *temp;
+	int			unmapped = 0;
+
+	list_for_each_safe (entry, temp, qtd_list) {
+		struct ehci_qtd	*qtd;
+
+		qtd = list_entry (entry, struct ehci_qtd, qtd_list);
+		list_del (&qtd->qtd_list);
+		if (unmapped != 2) {
+			int	direction;
+			size_t	size;
+
+			/* for ctrl unmap twice: SETUP and DATA;
+			 * else (bulk, intr) just once: DATA
+			 */
+			if (!unmapped++ && usb_pipecontrol (urb->pipe)) {
+				direction = PCI_DMA_TODEVICE;
+				size = sizeof (devrequest);
+			} else {
+				direction = usb_pipein (urb->pipe)
+					? PCI_DMA_FROMDEVICE
+					: PCI_DMA_TODEVICE;
+				size = qtd->urb->transfer_buffer_length;
+				unmapped++;
+			}
+			if (qtd->buf_dma)
+				pci_unmap_single (ehci->hcd.pdev,
+					qtd->buf_dma,
+					size, direction);
+		}
+		ehci_qtd_free (ehci, qtd);
+	}
+}
+
+/*
+ * create a list of filled qtds for this URB; won't link into qh.
+ */
+static struct list_head *
+qh_urb_transaction (
+	struct ehci_hcd		*ehci,
+	struct urb		*urb,
+	struct list_head	*head,
+	int			flags
+) {
+	struct ehci_qtd		*qtd, *qtd_prev;
+	dma_addr_t		buf, map_buf;
+	int			len, maxpacket;
+	u32			token;
+
+	/*
+	 * URBs map to sequences of QTDs:  one logical transaction
+	 */
+	qtd = ehci_qtd_alloc (ehci, flags);
+	if (unlikely (!qtd))
+		return 0;
+	qtd_prev = 0;
+	list_add_tail (&qtd->qtd_list, head);
+	qtd->urb = urb;
+
+	token = QTD_STS_ACTIVE;
+	token |= (EHCI_TUNE_CERR << 10);
+	/* for split transactions, SplitXState initialized to zero */
+
+	if (usb_pipecontrol (urb->pipe)) {
+		/* control request data is passed in the "setup" pid */
+		qtd->buf_dma = pci_map_single (
+					ehci->hcd.pdev,
+					urb->setup_packet,
+					sizeof (devrequest),
+					PCI_DMA_TODEVICE);
+		if (unlikely (!qtd->buf_dma))
+			goto cleanup;
+
+		/* SETUP pid */
+		qtd_fill (qtd, qtd->buf_dma, sizeof (devrequest),
+			token | (2 /* "setup" */ << 8));
+
+		/* ... and always at least one more pid */
+		token ^= QTD_TOGGLE;
+		qtd_prev = qtd;
+		qtd = ehci_qtd_alloc (ehci, flags);
+		if (unlikely (!qtd))
+			goto cleanup;
+		qtd->urb = urb;
+		qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+		list_add_tail (&qtd->qtd_list, head);
+	} 
+
+	/*
+	 * data transfer stage:  buffer setup
+	 */
+	len = urb->transfer_buffer_length;
+	if (likely (len > 0)) {
+		buf = map_buf = pci_map_single (ehci->hcd.pdev,
+			urb->transfer_buffer, len,
+			usb_pipein (urb->pipe)
+			    ? PCI_DMA_FROMDEVICE
+			    : PCI_DMA_TODEVICE);
+		if (unlikely (!buf))
+			goto cleanup;
+	} else
+		buf = map_buf = 0;
+
+	if (!buf || usb_pipein (urb->pipe))
+		token |= (1 /* "in" */ << 8);
+	/* else it's already initted to "out" pid (0 << 8) */
+
+	maxpacket = usb_maxpacket (urb->dev, urb->pipe,
+			usb_pipeout (urb->pipe));
+
+	/*
+	 * buffer gets wrapped in one or more qtds;
+	 * last one may be "short" (including zero len)
+	 * and may serve as a control status ack
+	 */
+	for (;;) {
+		int this_qtd_len;
+
+		qtd->urb = urb;
+		qtd->buf_dma = map_buf;
+		this_qtd_len = qtd_fill (qtd, buf, len, token);
+		len -= this_qtd_len;
+		buf += this_qtd_len;
+
+		/* qh makes control packets use qtd toggle; maybe switch it */
+		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
+			token ^= QTD_TOGGLE;
+
+		if (likely (len <= 0))
+			break;
+
+		qtd_prev = qtd;
+		qtd = ehci_qtd_alloc (ehci, flags);
+		if (unlikely (!qtd))
+			goto cleanup;
+		qtd->urb = urb;
+		qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+		list_add_tail (&qtd->qtd_list, head);
+	}
+
+	/*
+	 * control requests may need a terminating data "status" ack;
+	 * bulk ones may need a terminating short packet (zero length).
+	 */
+	if (likely (buf != 0)) {
+		int	one_more = 0;
+
+		if (usb_pipecontrol (urb->pipe)) {
+			one_more = 1;
+			token ^= 0x0100;	/* "in" <--> "out"  */
+			token |= QTD_TOGGLE;	/* force DATA1 */
+		} else if (usb_pipebulk (urb->pipe)
+				&& (urb->transfer_flags & USB_ZERO_PACKET)
+				&& !(urb->transfer_buffer_length % maxpacket)) {
+			one_more = 1;
+		}
+		if (one_more) {
+			qtd_prev = qtd;
+			qtd = ehci_qtd_alloc (ehci, flags);
+			if (unlikely (!qtd))
+				goto cleanup;
+			qtd->urb = urb;
+			qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+			list_add_tail (&qtd->qtd_list, head);
+
+			/* never any data in such packets */
+			qtd_fill (qtd, 0, 0, token);
+		}
+	}
+
+	/* by default, enable interrupt on urb completion */
+	if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
+		qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC);
+	return head;
+
+cleanup:
+	qtd_list_free (ehci, urb, head);
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Hardware maintains data toggle (like OHCI) ... here we (re)initialize
+ * the hardware data toggle in the QH, and set the pseudo-toggle in udev
+ * so we can see if usb_clear_halt() was called.  NOP for control, since
+ * we set up qh->hw_info1 to always use the QTD toggle bits. 
+ */
+static inline void
+clear_toggle (struct usb_device *udev, int ep, int is_out, struct ehci_qh *qh)
+{
+	vdbg ("clear toggle, dev %d ep 0x%x-%s",
+		udev->devnum, ep, is_out ? "out" : "in");
+	qh->hw_token &= ~__constant_cpu_to_le32 (QTD_TOGGLE);
+	usb_settoggle (udev, ep, is_out, 1);
+}
+
+// Would be best to create all qh's from config descriptors,
+// when each interface/altsetting is established.  Unlink
+// any previous qh and cancel its urbs first; endpoints are
+// implicitly reset then (data toggle too).
+// That'd mean updating how usbcore talks to HCDs. (2.5?)
+
+
+/*
+ * Each QH holds a qtd list; a QH is used for everything except iso.
+ *
+ * For interrupt urbs, the scheduler must set the microframe scheduling
+ * mask(s) each time the QH gets scheduled.  For highspeed, that's
+ * just one microframe in the s-mask.  For split interrupt transactions
+ * there are additional complications: c-mask, maybe FSTNs.
+ */
+static struct ehci_qh *
+ehci_qh_make (
+	struct ehci_hcd		*ehci,
+	struct urb		*urb,
+	struct list_head	*qtd_list,
+	int			flags
+) {
+	struct ehci_qh		*qh = ehci_qh_alloc (ehci, flags);
+	u32			info1 = 0, info2 = 0;
+
+	if (!qh)
+		return qh;
+
+	/*
+	 * init endpoint/device data for this QH
+	 */
+	info1 |= usb_pipeendpoint (urb->pipe) << 8;
+	info1 |= usb_pipedevice (urb->pipe) << 0;
+
+	/* using TT? */
+	switch (urb->dev->speed) {
+	case USB_SPEED_LOW:
+		info1 |= (1 << 12);	/* EPS "low" */
+		/* FALL THROUGH */
+
+	case USB_SPEED_FULL:
+		/* EPS 0 means "full" */
+		info1 |= (EHCI_TUNE_RL_TT << 28);
+		if (usb_pipecontrol (urb->pipe)) {
+			info1 |= (1 << 27);	/* for TT */
+			info1 |= 1 << 14;	/* toggle from qtd */
+		}
+		info1 |= usb_maxpacket (urb->dev, urb->pipe,
+					usb_pipeout (urb->pipe)) << 16;
+
+		info2 |= (EHCI_TUNE_MULT_TT << 30);
+		info2 |= urb->dev->ttport << 23;
+		info2 |= urb->dev->tt->hub->devnum << 16;
+
+		/* NOTE:  if (usb_pipeint (urb->pipe)) { scheduler sets c-mask }
+		 * ... and a 0.96 scheduler might use FSTN nodes too
+		 */
+		break;
+
+	case USB_SPEED_HIGH:		/* no TT involved */
+		info1 |= (2 << 12);	/* EPS "high" */
+		info1 |= (EHCI_TUNE_RL_HS << 28);
+		if (usb_pipecontrol (urb->pipe)) {
+			info1 |= 64 << 16;	/* usb2 fixed maxpacket */
+			info1 |= 1 << 14;	/* toggle from qtd */
+			info2 |= (EHCI_TUNE_MULT_HS << 30);
+		} else if (usb_pipebulk (urb->pipe)) {
+			info1 |= 512 << 16;	/* usb2 fixed maxpacket */
+			info2 |= (EHCI_TUNE_MULT_HS << 30);
+		} else {
+			u32	temp;
+			temp = usb_maxpacket (urb->dev, urb->pipe,
+						usb_pipeout (urb->pipe));
+			info1 |= (temp & 0x3ff) << 16;	/* maxpacket */
+			/* HS intr can be "high bandwidth" */
+			temp = 1 + ((temp >> 11) & 0x03);
+			info2 |= temp << 30;		/* mult */
+		}
+		break;
+	default:
+#ifdef DEBUG
+		BUG ();
+#endif
+	}
+
+	/* NOTE:  if (usb_pipeint (urb->pipe)) { scheduler sets s-mask } */
+
+	qh->qh_state = QH_STATE_IDLE;
+	qh->hw_info1 = cpu_to_le32 (info1);
+	qh->hw_info2 = cpu_to_le32 (info2);
+
+	/* initialize sw and hw queues with these qtds */
+	list_splice (qtd_list, &qh->qtd_list);
+	qh_update (qh, list_entry (qtd_list->next, struct ehci_qtd, qtd_list));
+
+	/* initialize data toggle state */
+	if (!usb_pipecontrol (urb->pipe))
+		clear_toggle (urb->dev,
+			usb_pipeendpoint (urb->pipe),
+			usb_pipeout (urb->pipe),
+			qh);
+
+	return qh;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* move qh (and its qtds) onto async queue; maybe enable queue.  */
+
+static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+	u32		dma = QH_NEXT (qh->qh_dma);
+	struct ehci_qh	*q;
+
+	if (unlikely (!(q = ehci->async))) {
+		u32	cmd = readl (&ehci->regs->command);
+
+		/* in case a clear of CMD_ASE didn't take yet */
+		while (readl (&ehci->regs->status) & STS_ASS)
+			udelay (100);
+
+		qh->hw_info1 |= __constant_cpu_to_le32 (QH_HEAD); /* [4.8] */
+		qh->qh_next.qh = qh;
+		qh->hw_next = dma;
+		wmb ();
+		ehci->async = qh;
+		writel ((u32)qh->qh_dma, &ehci->regs->async_next);
+		cmd |= CMD_ASE | CMD_RUN;
+		writel (cmd, &ehci->regs->command);
+		ehci->hcd.state = USB_STATE_RUNNING;
+		/* posted write need not be known to HC yet ... */
+	} else {
+		/* splice right after "start" of ring */
+		qh->hw_info1 &= ~__constant_cpu_to_le32 (QH_HEAD); /* [4.8] */
+		qh->qh_next = q->qh_next;
+		qh->hw_next = q->hw_next;
+		wmb ();
+		q->qh_next.qh = qh;
+		q->hw_next = dma;
+	}
+	qh->qh_state = QH_STATE_LINKED;
+	/* qtd completions reported later by interrupt */
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int
+submit_async (
+	struct ehci_hcd		*ehci,
+	struct urb		*urb,
+	struct list_head	*qtd_list,
+	int			mem_flags
+) {
+	struct ehci_qtd		*qtd;
+	struct hcd_dev		*dev;
+	int			epnum;
+	unsigned long		flags;
+	struct ehci_qh		*qh = 0;
+
+	qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list);
+	dev = (struct hcd_dev *)urb->dev->hcpriv;
+	epnum = usb_pipeendpoint (urb->pipe);
+	if (usb_pipein (urb->pipe))
+		epnum |= 0x10;
+
+	vdbg ("%s: submit_async urb %p len %d ep %d-%s qtd %p [qh %p]",
+		ehci->hcd.bus_name, urb, urb->transfer_buffer_length,
+		epnum & 0x0f, (epnum & 0x10) ? "in" : "out",
+		qtd, dev ? dev->ep [epnum] : (void *)~0);
+
+	spin_lock_irqsave (&ehci->lock, flags);
+
+	qh = (struct ehci_qh *) dev->ep [epnum];
+	if (likely (qh != 0)) {
+		u32	hw_next = QTD_NEXT (qtd->qtd_dma);
+
+		/* maybe patch the qh used for set_address */
+		if (unlikely (epnum == 0
+				&& le32_to_cpu (qh->hw_info1 & 0x7f) == 0))
+			qh->hw_info1 |= cpu_to_le32 (usb_pipedevice(urb->pipe));
+
+		/* is an URB is queued to this qh already? */
+		if (unlikely (!list_empty (&qh->qtd_list))) {
+			struct ehci_qtd		*last_qtd;
+			int			short_rx = 0;
+
+			/* update the last qtd's "next" pointer */
+			// dbg_qh ("non-empty qh", ehci, qh);
+			last_qtd = list_entry (qh->qtd_list.prev,
+					struct ehci_qtd, qtd_list);
+			last_qtd->hw_next = hw_next;
+
+			/* previous urb allows short rx? maybe optimize. */
+			if (!(last_qtd->urb->transfer_flags & USB_DISABLE_SPD)
+					&& (epnum & 0x10)) {
+				// only the last QTD for now
+				last_qtd->hw_alt_next = hw_next;
+				short_rx = 1;
+			}
+
+			/* Adjust any old copies in qh overlay too.
+			 * Interrupt code must cope with case of HC having it
+			 * cached, and clobbering these updates.
+			 * ... complicates getting rid of extra interrupts!
+			 */
+			if (qh->hw_current == cpu_to_le32 (last_qtd->qtd_dma)) {
+				wmb ();
+				qh->hw_qtd_next = hw_next;
+				if (short_rx)
+					qh->hw_alt_next = hw_next
+				    		| (qh->hw_alt_next & 0x1e);
+				vdbg ("queue to qh %p, patch", qh);
+			}
+
+		/* no URB queued */
+		} else {
+			// dbg_qh ("empty qh", ehci, qh);
+
+// FIXME:  how handle usb_clear_halt() for an EP with queued URBs?
+// usbcore may not let us handle that cleanly...
+// likely must cancel them all first!
+
+			/* usb_clear_halt() means qh data toggle gets reset */
+			if (usb_pipebulk (urb->pipe)
+					&& unlikely (!usb_gettoggle (urb->dev,
+						(epnum & 0x0f),
+						!(epnum & 0x10)))) {
+				clear_toggle (urb->dev,
+					epnum & 0x0f, !(epnum & 0x10), qh);
+			}
+			qh_update (qh, qtd);
+		}
+		list_splice (qtd_list, qh->qtd_list.prev);
+
+	} else {
+		/* can't sleep here, we have ehci->lock... */
+		qh = ehci_qh_make (ehci, urb, qtd_list, SLAB_ATOMIC);
+		if (likely (qh != 0)) {
+			// dbg_qh ("new qh", ehci, qh);
+			dev->ep [epnum] = qh;
+		}
+	}
+
+	/* Control/bulk operations through TTs don't need scheduling,
+	 * the HC and TT handle it when the TT has a buffer ready.
+	 */
+	if (likely (qh != 0)) {
+		urb->hcpriv = qh_get (qh);
+		if (likely (qh->qh_state == QH_STATE_IDLE))
+			qh_link_async (ehci, qh_get (qh));
+	}
+	spin_unlock_irqrestore (&ehci->lock, flags);
+	if (unlikely (qh == 0)) {
+		qtd_list_free (ehci, urb, qtd_list);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* the async qh for the qtds being reclaimed are now unlinked from the HC */
+/* caller must not own ehci->lock */
+
+static void end_unlink_async (struct ehci_hcd *ehci)
+{
+	struct ehci_qh		*qh = ehci->reclaim;
+
+	qh->qh_state = QH_STATE_IDLE;
+	qh->qh_next.qh = 0;
+	qh_put (ehci, qh);			// refcount from reclaim 
+	ehci->reclaim = 0;
+	ehci->reclaim_ready = 0;
+
+	qh_completions (ehci, qh, 1);
+
+	// unlink any urb should now unlink all following urbs, so that
+	// relinking only happens for urbs before the unlinked ones.
+	if (!list_empty (&qh->qtd_list)
+			&& HCD_IS_RUNNING (ehci->hcd.state))
+		qh_link_async (ehci, qh);
+	else
+		qh_put (ehci, qh);		// refcount from async list
+}
+
+
+/* makes sure the async qh will become idle */
+/* caller must own ehci->lock */
+
+static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+	int		cmd = readl (&ehci->regs->command);
+	struct ehci_qh	*prev;
+
+#ifdef DEBUG
+	if (ehci->reclaim
+			|| !ehci->async
+			|| qh->qh_state != QH_STATE_LINKED
+#ifdef CONFIG_SMP
+// this macro lies except on SMP compiles
+			|| !spin_is_locked (&ehci->lock)
+#endif
+			)
+		BUG ();
+#endif
+
+	qh->qh_state = QH_STATE_UNLINK;
+	ehci->reclaim = qh = qh_get (qh);
+
+	// dbg_qh ("start unlink", ehci, qh);
+
+	/* Remove the last QH (qhead)?  Stop async schedule first. */
+	if (unlikely (qh == ehci->async && qh->qh_next.qh == qh)) {
+		/* can't get here without STS_ASS set */
+		if (ehci->hcd.state != USB_STATE_HALT) {
+			if (cmd & CMD_PSE)
+				writel (cmd & ~CMD_ASE, &ehci->regs->command);
+			else {
+				ehci_ready (ehci);
+				while (readl (&ehci->regs->status) & STS_ASS)
+					udelay (100);
+			}
+		}
+		qh->qh_next.qh = ehci->async = 0;
+
+		ehci->reclaim_ready = 1;
+		tasklet_schedule (&ehci->tasklet);
+		return;
+	} 
+
+	if (unlikely (ehci->hcd.state == USB_STATE_HALT)) {
+		ehci->reclaim_ready = 1;
+		tasklet_schedule (&ehci->tasklet);
+		return;
+	}
+
+	prev = ehci->async;
+	while (prev->qh_next.qh != qh && prev->qh_next.qh != ehci->async)
+		prev = prev->qh_next.qh;
+#ifdef DEBUG
+	if (prev->qh_next.qh != qh)
+		BUG ();
+#endif
+
+	if (qh->hw_info1 & __constant_cpu_to_le32 (QH_HEAD)) {
+		ehci->async = prev;
+		prev->hw_info1 |= __constant_cpu_to_le32 (QH_HEAD);
+	}
+	prev->hw_next = qh->hw_next;
+	prev->qh_next = qh->qh_next;
+	wmb ();
+
+	ehci->reclaim_ready = 0;
+	cmd |= CMD_IAAD;
+	writel (cmd, &ehci->regs->command);
+	/* posted write need not be known to HC yet ... */
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void scan_async (struct ehci_hcd *ehci)
+{
+	struct ehci_qh		*qh;
+	unsigned long		flags;
+
+	spin_lock_irqsave (&ehci->lock, flags);
+rescan:
+	qh = ehci->async;
+	if (likely (qh != 0)) {
+		do {
+			/* clean any finished work for this qh */
+			if (!list_empty (&qh->qtd_list)) {
+				// dbg_qh ("scan_async", ehci, qh);
+				qh = qh_get (qh);
+				spin_unlock_irqrestore (&ehci->lock, flags);
+
+				/* concurrent unlink could happen here */
+				qh_completions (ehci, qh, 1);
+
+				spin_lock_irqsave (&ehci->lock, flags);
+				qh_put (ehci, qh);
+			}
+
+			/* unlink idle entries (reduces PCI usage) */
+			if (list_empty (&qh->qtd_list) && !ehci->reclaim) {
+				if (qh->qh_next.qh != qh) {
+					// dbg ("irq/empty");
+					start_unlink_async (ehci, qh);
+				} else {
+					// FIXME:  arrange to stop
+					// after it's been idle a while.
+				}
+			}
+			qh = qh->qh_next.qh;
+			if (!qh)		/* unlinked? */
+				goto rescan;
+		} while (qh != ehci->async);
+	}
+
+	spin_unlock_irqrestore (&ehci->lock, flags);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/ehci-sched.c linux/drivers/usb/hcd/ehci-sched.c
--- linux.orig/drivers/usb/hcd/ehci-sched.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/ehci-sched.c	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,1262 @@
+/*
+ * Copyright (c) 2001-2002 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* this file is part of ehci-hcd.c */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI scheduled transaction support:  interrupt, iso, split iso
+ * These are called "periodic" transactions in the EHCI spec.
+ *
+ * Note that for interrupt transfers, the QH/QTD manipulation is shared
+ * with the "asynchronous" transaction support (control/bulk transfers).
+ * The only real difference is in how interrupt transfers are scheduled.
+ * We get some funky API restrictions from the current URB model, which
+ * works notably better for reading transfers than for writing.  (And
+ * which accordingly needs to change before it'll work inside devices,
+ * or with "USB On The Go" additions to USB 2.0 ...)
+ */
+
+/*
+ * Ceiling microseconds (typical) for that many bytes at high speed
+ * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
+ * to preallocate bandwidth)
+ */
+#define EHCI_HOST_DELAY	5	/* nsec, guess */
+#define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \
+	+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+	+ EHCI_HOST_DELAY)
+#define HS_USECS_ISO(bytes) NS_TO_US ( ((long)(38 * 8 * 2.083)) \
+	+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+	+ EHCI_HOST_DELAY)
+	
+static int ehci_get_frame (struct usb_hcd *hcd);
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * periodic_next_shadow - return "next" pointer on shadow list
+ * @periodic: host pointer to qh/itd/sitd
+ * @tag: hardware tag for type of this record
+ */
+static union ehci_shadow *
+periodic_next_shadow (union ehci_shadow *periodic, int tag)
+{
+	switch (tag) {
+	case Q_TYPE_QH:
+		return &periodic->qh->qh_next;
+	case Q_TYPE_FSTN:
+		return &periodic->fstn->fstn_next;
+	case Q_TYPE_ITD:
+		return &periodic->itd->itd_next;
+#ifdef have_split_iso
+	case Q_TYPE_SITD:
+		return &periodic->sitd->sitd_next;
+#endif /* have_split_iso */
+	}
+	dbg ("BAD shadow %p tag %d", periodic->ptr, tag);
+	// BUG ();
+	return 0;
+}
+
+/* returns true after successful unlink */
+/* caller must hold ehci->lock */
+static int periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
+{
+	union ehci_shadow	*prev_p = &ehci->pshadow [frame];
+	u32			*hw_p = &ehci->periodic [frame];
+	union ehci_shadow	here = *prev_p;
+	union ehci_shadow	*next_p;
+
+	/* find predecessor of "ptr"; hw and shadow lists are in sync */
+	while (here.ptr && here.ptr != ptr) {
+		prev_p = periodic_next_shadow (prev_p, Q_NEXT_TYPE (*hw_p));
+		hw_p = &here.qh->hw_next;
+		here = *prev_p;
+	}
+	/* an interrupt entry (at list end) could have been shared */
+	if (!here.ptr) {
+		dbg ("entry %p no longer on frame [%d]", ptr, frame);
+		return 0;
+	}
+	// vdbg ("periodic unlink %p from frame %d", ptr, frame);
+
+	/* update hardware list ... HC may still know the old structure, so
+	 * don't change hw_next until it'll have purged its cache
+	 */
+	next_p = periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p));
+	*hw_p = here.qh->hw_next;
+
+	/* unlink from shadow list; HCD won't see old structure again */
+	*prev_p = *next_p;
+	next_p->ptr = 0;
+
+	return 1;
+}
+
+/* how many of the uframe's 125 usecs are allocated? */
+static unsigned short
+periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
+{
+	u32			*hw_p = &ehci->periodic [frame];
+	union ehci_shadow	*q = &ehci->pshadow [frame];
+	unsigned		usecs = 0;
+
+	while (q->ptr) {
+		switch (Q_NEXT_TYPE (*hw_p)) {
+		case Q_TYPE_QH:
+			/* is it in the S-mask? */
+			if (q->qh->hw_info2 & cpu_to_le32 (1 << uframe))
+				usecs += q->qh->usecs;
+			q = &q->qh->qh_next;
+			break;
+		case Q_TYPE_FSTN:
+			/* for "save place" FSTNs, count the relevant INTR
+			 * bandwidth from the previous frame
+			 */
+			if (q->fstn->hw_prev != EHCI_LIST_END) {
+				dbg ("not counting FSTN bandwidth yet ...");
+			}
+			q = &q->fstn->fstn_next;
+			break;
+		case Q_TYPE_ITD:
+			/* NOTE the "one uframe per itd" policy */
+			if (q->itd->hw_transaction [uframe] != 0)
+				usecs += q->itd->usecs;
+			q = &q->itd->itd_next;
+			break;
+#ifdef have_split_iso
+		case Q_TYPE_SITD:
+			temp = q->sitd->hw_fullspeed_ep &
+				__constant_cpu_to_le32 (1 << 31);
+
+			// FIXME:  this doesn't count data bytes right...
+
+			/* is it in the S-mask?  (count SPLIT, DATA) */
+			if (q->sitd->hw_uframe & cpu_to_le32 (1 << uframe)) {
+				if (temp)
+					usecs += HS_USECS (188);
+				else
+					usecs += HS_USECS (1);
+			}
+
+			/* ... C-mask?  (count CSPLIT, DATA) */
+			if (q->sitd->hw_uframe &
+					cpu_to_le32 (1 << (8 + uframe))) {
+				if (temp)
+					usecs += HS_USECS (0);
+				else
+					usecs += HS_USECS (188);
+			}
+			q = &q->sitd->sitd_next;
+			break;
+#endif /* have_split_iso */
+		default:
+			BUG ();
+		}
+	}
+#ifdef	DEBUG
+	if (usecs > 100)
+		err ("overallocated uframe %d, periodic is %d usecs",
+			frame * 8 + uframe, usecs);
+#endif
+	return usecs;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void enable_periodic (struct ehci_hcd *ehci)
+{
+	u32	cmd;
+
+	/* did clearing PSE did take effect yet?
+	 * takes effect only at frame boundaries...
+	 */
+	while (readl (&ehci->regs->status) & STS_PSS)
+		udelay (20);
+
+	cmd = readl (&ehci->regs->command) | CMD_PSE;
+	writel (cmd, &ehci->regs->command);
+	/* posted write ... PSS happens later */
+	ehci->hcd.state = USB_STATE_RUNNING;
+
+	/* make sure tasklet scans these */
+	ehci->next_uframe = readl (&ehci->regs->frame_index)
+				% (ehci->periodic_size << 3);
+}
+
+static void disable_periodic (struct ehci_hcd *ehci)
+{
+	u32	cmd;
+
+	/* did setting PSE not take effect yet?
+	 * takes effect only at frame boundaries...
+	 */
+	while (!(readl (&ehci->regs->status) & STS_PSS))
+		udelay (20);
+
+	cmd = readl (&ehci->regs->command) & ~CMD_PSE;
+	writel (cmd, &ehci->regs->command);
+	/* posted write ... */
+
+	ehci->next_uframe = -1;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void intr_deschedule (
+	struct ehci_hcd	*ehci,
+	unsigned	frame,
+	struct ehci_qh	*qh,
+	unsigned	period
+) {
+	unsigned long	flags;
+
+	period >>= 3;		// FIXME microframe periods not handled yet
+
+	spin_lock_irqsave (&ehci->lock, flags);
+
+	do {
+		periodic_unlink (ehci, frame, qh);
+		qh_put (ehci, qh);
+		frame += period;
+	} while (frame < ehci->periodic_size);
+
+	qh->qh_state = QH_STATE_UNLINK;
+	qh->qh_next.ptr = 0;
+	ehci->periodic_urbs--;
+
+	/* maybe turn off periodic schedule */
+	if (!ehci->periodic_urbs)
+		disable_periodic (ehci);
+	else
+		vdbg ("periodic schedule still enabled");
+
+	spin_unlock_irqrestore (&ehci->lock, flags);
+
+	/*
+	 * If the hc may be looking at this qh, then delay a uframe
+	 * (yeech!) to be sure it's done.
+	 * No other threads may be mucking with this qh.
+	 */
+	if (((ehci_get_frame (&ehci->hcd) - frame) % period) == 0)
+		udelay (125);
+
+	qh->qh_state = QH_STATE_IDLE;
+	qh->hw_next = EHCI_LIST_END;
+
+	vdbg ("descheduled qh %p, per = %d frame = %d count = %d, urbs = %d",
+		qh, period, frame,
+		atomic_read (&qh->refcount), ehci->periodic_urbs);
+}
+
+static int check_period (
+	struct ehci_hcd *ehci, 
+	unsigned	frame,
+	int		uframe,
+	unsigned	period,
+	unsigned	usecs
+) {
+	/*
+	 * 80% periodic == 100 usec/uframe available
+	 * convert "usecs we need" to "max already claimed" 
+	 */
+	usecs = 100 - usecs;
+
+	do {
+		int	claimed;
+
+// FIXME delete when intr_submit handles non-empty queues
+// this gives us a one intr/frame limit (vs N/uframe)
+		if (ehci->pshadow [frame].ptr)
+			return 0;
+
+		claimed = periodic_usecs (ehci, frame, uframe);
+		if (claimed > usecs)
+			return 0;
+
+// FIXME update to handle sub-frame periods
+	} while ((frame += period) < ehci->periodic_size);
+
+	// success!
+	return 1;
+}
+
+static int intr_submit (
+	struct ehci_hcd		*ehci,
+	struct urb		*urb,
+	struct list_head	*qtd_list,
+	int			mem_flags
+) {
+	unsigned		epnum, period;
+	unsigned short		usecs;
+	unsigned long		flags;
+	struct ehci_qh		*qh;
+	struct hcd_dev		*dev;
+	int			status = 0;
+
+	/* get endpoint and transfer data */
+	epnum = usb_pipeendpoint (urb->pipe);
+	if (usb_pipein (urb->pipe))
+		epnum |= 0x10;
+	if (urb->dev->speed != USB_SPEED_HIGH) {
+		dbg ("no intr/tt scheduling yet"); 
+		status = -ENOSYS;
+		goto done;
+	}
+
+	/*
+	 * NOTE: current completion/restart logic doesn't handle more than
+	 * one qtd in a periodic qh ... 16-20 KB/urb is pretty big for this.
+	 * such big requests need many periods to transfer.
+	 *
+	 * FIXME want to change hcd core submit model to expect queuing
+	 * for all transfer types ... not just ISO and (with flag) BULK.
+	 * that means: getting rid of this check; handling the "interrupt
+	 * urb already queued" case below like bulk queuing is handled (no
+	 * errors possible!); and completly getting rid of that annoying
+	 * qh restart logic.  simpler/smaller overall, and more flexible.
+	 */
+	if (unlikely (qtd_list->next != qtd_list->prev)) {
+		dbg ("only one intr qtd per urb allowed"); 
+		status = -EINVAL;
+		goto done;
+	}
+
+	usecs = HS_USECS (urb->transfer_buffer_length);
+
+	/* FIXME handle HS periods of less than 1 frame. */
+	period = urb->interval >> 3;
+	if (period < 1) {
+		dbg ("intr period %d uframes, NYET!", urb->interval);
+		status = -EINVAL;
+		goto done;
+	}
+
+	spin_lock_irqsave (&ehci->lock, flags);
+
+	/* get the qh (must be empty and idle) */
+	dev = (struct hcd_dev *)urb->dev->hcpriv;
+	qh = (struct ehci_qh *) dev->ep [epnum];
+	if (qh) {
+		/* only allow one queued interrupt urb per EP */
+		if (unlikely (qh->qh_state != QH_STATE_IDLE
+				|| !list_empty (&qh->qtd_list))) {
+			dbg ("interrupt urb already queued");
+			status = -EBUSY;
+		} else {
+			/* maybe reset hardware's data toggle in the qh */
+			if (unlikely (!usb_gettoggle (urb->dev, epnum & 0x0f,
+					!(epnum & 0x10)))) {
+				qh->hw_token |=
+					__constant_cpu_to_le32 (QTD_TOGGLE);
+				usb_settoggle (urb->dev, epnum & 0x0f,
+					!(epnum & 0x10), 1);
+			}
+			/* trust the QH was set up as interrupt ... */
+			list_splice (qtd_list, &qh->qtd_list);
+			qh_update (qh, list_entry (qtd_list->next,
+						struct ehci_qtd, qtd_list));
+			qtd_list = &qh->qtd_list;
+		}
+	} else {
+		/* can't sleep here, we have ehci->lock... */
+		qh = ehci_qh_make (ehci, urb, qtd_list, SLAB_ATOMIC);
+		if (likely (qh != 0)) {
+			// dbg ("new INTR qh %p", qh);
+			dev->ep [epnum] = qh;
+			qtd_list = &qh->qtd_list;
+		} else
+			status = -ENOMEM;
+	}
+
+	/* Schedule this periodic QH. */
+	if (likely (status == 0)) {
+		unsigned	frame = period;
+
+		qh->hw_next = EHCI_LIST_END;
+		qh->usecs = usecs;
+
+		urb->hcpriv = qh_get (qh);
+		status = -ENOSPC;
+
+		/* pick a set of schedule slots, link the QH into them */
+		do {
+			int	uframe;
+
+			/* pick a set of slots such that all uframes have
+			 * enough periodic bandwidth available.
+			 *
+			 * FIXME for TT splits, need uframes for start and end.
+			 * FSTNs can put end into next frame (uframes 0 or 1).
+			 */
+			frame--;
+			for (uframe = 0; uframe < 8; uframe++) {
+				if (check_period (ehci, frame, uframe,
+						period, usecs) != 0)
+					break;
+			}
+			if (uframe == 8)
+				continue;
+
+			/* QH will run once each period, starting there  */
+			urb->start_frame = frame;
+			status = 0;
+
+			/* set S-frame mask */
+			qh->hw_info2 |= cpu_to_le32 (1 << uframe);
+			// dbg_qh ("Schedule INTR qh", ehci, qh);
+
+			/* stuff into the periodic schedule */
+			qh->qh_state = QH_STATE_LINKED;
+			vdbg ("qh %p usecs %d period %d starting %d.%d",
+				qh, qh->usecs, period, frame, uframe);
+			do {
+				if (unlikely (ehci->pshadow [frame].ptr != 0)) {
+// FIXME -- just link toward the end, before any qh with a shorter period,
+// AND handle it already being (implicitly) linked into this frame
+// AS WELL AS updating the check_period() logic
+					BUG ();
+				} else {
+					ehci->pshadow [frame].qh = qh_get (qh);
+					ehci->periodic [frame] =
+						QH_NEXT (qh->qh_dma);
+				}
+				wmb ();
+				frame += period;
+			} while (frame < ehci->periodic_size);
+
+			/* update bandwidth utilization records (for usbfs) */
+			usb_claim_bandwidth (urb->dev, urb, usecs/period, 0);
+
+			/* maybe enable periodic schedule processing */
+			if (!ehci->periodic_urbs++)
+				enable_periodic (ehci);
+			break;
+
+		} while (frame);
+	}
+	spin_unlock_irqrestore (&ehci->lock, flags);
+done:
+	if (status)
+		qtd_list_free (ehci, urb, qtd_list);
+
+	return status;
+}
+
+static unsigned long
+intr_complete (
+	struct ehci_hcd	*ehci,
+	unsigned	frame,
+	struct ehci_qh	*qh,
+	unsigned long	flags		/* caller owns ehci->lock ... */
+) {
+	struct ehci_qtd	*qtd;
+	struct urb	*urb;
+	int		unlinking;
+
+	/* nothing to report? */
+	if (likely ((qh->hw_token & __constant_cpu_to_le32 (QTD_STS_ACTIVE))
+			!= 0))
+		return flags;
+	if (unlikely (list_empty (&qh->qtd_list))) {
+		dbg ("intr qh %p no TDs?", qh);
+		return flags;
+	}
+	
+	qtd = list_entry (qh->qtd_list.next, struct ehci_qtd, qtd_list);
+	urb = qtd->urb;
+	unlinking = (urb->status == -ENOENT) || (urb->status == -ECONNRESET);
+
+	/* call any completions, after patching for reactivation */
+	spin_unlock_irqrestore (&ehci->lock, flags);
+	/* NOTE:  currently restricted to one qtd per qh! */
+	if (qh_completions (ehci, qh, 0) == 0)
+		urb = 0;
+	spin_lock_irqsave (&ehci->lock, flags);
+
+	/* never reactivate requests that were unlinked ... */
+	if (likely (urb != 0)) {
+		if (unlinking
+				|| urb->status == -ECONNRESET
+				|| urb->status == -ENOENT
+				// || (urb->dev == null)
+				|| ehci->hcd.state == USB_STATE_HALT)
+			urb = 0;
+		// FIXME look at all those unlink cases ... we always
+		// need exactly one completion that reports unlink.
+		// the one above might not have been it!
+	}
+
+	/* normally reactivate */
+	if (likely (urb != 0)) {
+		if (usb_pipeout (urb->pipe))
+			pci_dma_sync_single (ehci->hcd.pdev,
+				qtd->buf_dma,
+				urb->transfer_buffer_length,
+				PCI_DMA_TODEVICE);
+		urb->status = -EINPROGRESS;
+		urb->actual_length = 0;
+
+		/* patch qh and restart */
+		qh_update (qh, qtd);
+	}
+	return flags;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void
+itd_free_list (struct ehci_hcd *ehci, struct urb *urb)
+{
+	struct ehci_itd *first_itd = urb->hcpriv;
+
+	pci_unmap_single (ehci->hcd.pdev,
+		first_itd->buf_dma, urb->transfer_buffer_length,
+		usb_pipein (urb->pipe)
+		    ? PCI_DMA_FROMDEVICE
+		    : PCI_DMA_TODEVICE);
+	while (!list_empty (&first_itd->itd_list)) {
+		struct ehci_itd	*itd;
+
+		itd = list_entry (
+			first_itd->itd_list.next,
+			struct ehci_itd, itd_list);
+		list_del (&itd->itd_list);
+		pci_pool_free (ehci->itd_pool, itd, itd->itd_dma);
+	}
+	pci_pool_free (ehci->itd_pool, first_itd, first_itd->itd_dma);
+	urb->hcpriv = 0;
+}
+
+static int
+itd_fill (
+	struct ehci_hcd	*ehci,
+	struct ehci_itd	*itd,
+	struct urb	*urb,
+	unsigned	index,		// urb->iso_frame_desc [index]
+	dma_addr_t	dma		// mapped transfer buffer
+) {
+	u64		temp;
+	u32		buf1;
+	unsigned	i, epnum, maxp, multi;
+	unsigned	length;
+
+	itd->hw_next = EHCI_LIST_END;
+	itd->urb = urb;
+	itd->index = index;
+
+	/* tell itd about its transfer buffer, max 2 pages */
+	length = urb->iso_frame_desc [index].length;
+	dma += urb->iso_frame_desc [index].offset;
+	temp = dma & ~0x0fff;
+	for (i = 0; i < 2; i++) {
+		itd->hw_bufp [i] = cpu_to_le32 ((u32) temp);
+		itd->hw_bufp_hi [i] = cpu_to_le32 ((u32)(temp >> 32));
+		temp += 0x1000;
+	}
+	itd->buf_dma = dma;
+
+	/*
+	 * this might be a "high bandwidth" highspeed endpoint,
+	 * as encoded in the ep descriptor's maxpacket field
+	 */
+	epnum = usb_pipeendpoint (urb->pipe);
+	if (usb_pipein (urb->pipe)) {
+		maxp = urb->dev->epmaxpacketin [epnum];
+		buf1 = (1 << 11);
+	} else {
+		maxp = urb->dev->epmaxpacketout [epnum];
+		buf1 = 0;
+	}
+	buf1 |= (maxp & 0x03ff);
+	multi = 1;
+	multi += (maxp >> 11) & 0x03;
+	maxp &= 0x03ff;
+	maxp *= multi;
+
+	/* transfer can't fit in any uframe? */ 
+	if (length < 0 || maxp < length) {
+		dbg ("BAD iso packet: %d bytes, max %d, urb %p [%d] (of %d)",
+			length, maxp, urb, index,
+			urb->iso_frame_desc [index].length);
+		return -ENOSPC;
+	}
+	itd->usecs = HS_USECS_ISO (length);
+
+	/* "plus" info in low order bits of buffer pointers */
+	itd->hw_bufp [0] |= cpu_to_le32 ((epnum << 8) | urb->dev->devnum);
+	itd->hw_bufp [1] |= cpu_to_le32 (buf1);
+	itd->hw_bufp [2] |= cpu_to_le32 (multi);
+
+	/* figure hw_transaction[] value (it's scheduled later) */
+	itd->transaction = EHCI_ISOC_ACTIVE;
+	itd->transaction |= dma & 0x0fff;		/* offset; buffer=0 */
+	if ((index + 1) == urb->number_of_packets)
+		itd->transaction |= EHCI_ITD_IOC; 	/* end-of-urb irq */
+	itd->transaction |= length << 16;
+	cpu_to_le32s (&itd->transaction);
+
+	return 0;
+}
+
+static int
+itd_urb_transaction (
+	struct ehci_hcd		*ehci,
+	struct urb		*urb,
+	int			mem_flags
+) {
+	int			frame_index;
+	struct ehci_itd		*first_itd, *itd;
+	int			status;
+	dma_addr_t		buf_dma, itd_dma;
+
+	/* set up one dma mapping for this urb */
+	buf_dma = pci_map_single (ehci->hcd.pdev,
+		urb->transfer_buffer, urb->transfer_buffer_length,
+		usb_pipein (urb->pipe)
+		    ? PCI_DMA_FROMDEVICE
+		    : PCI_DMA_TODEVICE);
+	if (buf_dma == 0)
+		return -ENOMEM;
+
+	/* allocate/init ITDs */
+	for (frame_index = 0, first_itd = 0;
+			frame_index < urb->number_of_packets;
+			frame_index++) {
+		itd = pci_pool_alloc (ehci->itd_pool, mem_flags, &itd_dma);
+		if (!itd) {
+			status = -ENOMEM;
+			goto fail;
+		}
+		memset (itd, 0, sizeof *itd);
+		itd->itd_dma = itd_dma;
+
+		status = itd_fill (ehci, itd, urb, frame_index, buf_dma);
+		if (status != 0)
+			goto fail;
+
+		if (first_itd)
+			list_add_tail (&itd->itd_list,
+					&first_itd->itd_list);
+		else {
+			INIT_LIST_HEAD (&itd->itd_list);
+			urb->hcpriv = first_itd = itd;
+		}
+	}
+	urb->error_count = 0;
+	return 0;
+
+fail:
+	if (urb->hcpriv)
+		itd_free_list (ehci, urb);
+	return status;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static inline void
+itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
+{
+	/* always prepend ITD/SITD ... only QH tree is order-sensitive */
+	itd->itd_next = ehci->pshadow [frame];
+	itd->hw_next = ehci->periodic [frame];
+	ehci->pshadow [frame].itd = itd;
+	ehci->periodic [frame] = cpu_to_le32 (itd->itd_dma) | Q_TYPE_ITD;
+}
+
+/*
+ * return zero on success, else -errno
+ * - start holds first uframe to start scheduling into
+ * - max is the first uframe it's NOT (!) OK to start scheduling into
+ * math to be done modulo "mod" (ehci->periodic_size << 3)
+ */
+static int get_iso_range (
+	struct ehci_hcd		*ehci,
+	struct urb		*urb,
+	unsigned		*start,
+	unsigned		*max,
+	unsigned		mod
+) {
+	struct list_head	*lh;
+	struct hcd_dev		*dev = urb->dev->hcpriv;
+	int			last = -1;
+	unsigned		now, span, end;
+
+	span = urb->interval * urb->number_of_packets;
+
+	/* first see if we know when the next transfer SHOULD happen */
+	list_for_each (lh, &dev->urb_list) {
+		struct urb	*u;
+		struct ehci_itd	*itd;
+		unsigned	s;
+
+		u = list_entry (lh, struct urb, urb_list);
+		if (u == urb || u->pipe != urb->pipe)
+			continue;
+		if (u->interval != urb->interval) {	/* must not change! */ 
+			dbg ("urb %p interval %d ... != %p interval %d",
+				u, u->interval, urb, urb->interval);
+			return -EINVAL;
+		}
+		
+		/* URB for this endpoint... covers through when?  */
+		itd = urb->hcpriv;
+		s = itd->uframe + u->interval * u->number_of_packets;
+		if (last < 0)
+			last = s;
+		else {
+			/*
+			 * So far we can only queue two ISO URBs...
+			 *
+			 * FIXME do interval math, figure out whether
+			 * this URB is "before" or not ... also, handle
+			 * the case where the URB might have completed,
+			 * but hasn't yet been processed.
+			 */
+			dbg ("NYET: queue >2 URBs per ISO endpoint");
+			return -EDOM;
+		}
+	}
+
+	/* calculate the legal range [start,max) */
+	now = readl (&ehci->regs->frame_index) + 1;	/* next uframe */
+	if (!ehci->periodic_urbs)
+		now += 8;				/* startup delay */
+	now %= mod;
+	end = now + mod;
+	if (last < 0) {
+		*start = now + ehci->i_thresh + /* paranoia */ 1;
+		*max = end - span;
+		if (*max < *start + 1)
+			*max = *start + 1;
+	} else {
+		*start = last % mod;
+		*max = (last + 1) % mod;
+	}
+
+	/* explicit start frame? */
+	if (!(urb->transfer_flags & USB_ISO_ASAP)) {
+		unsigned	temp;
+
+		/* sanity check: must be in range */
+		urb->start_frame %= ehci->periodic_size;
+		temp = urb->start_frame << 3;
+		if (temp < *start)
+			temp += mod;
+		if (temp > *max)
+			return -EDOM;
+
+		/* use that explicit start frame */
+		*start = urb->start_frame << 3;
+		temp += 8;
+		if (temp < *max)
+			*max = temp;
+	}
+
+	// FIXME minimize wraparound to "now" ... insist max+span
+	// (and start+span) remains a few frames short of "end"
+
+	*max %= ehci->periodic_size;
+	if ((*start + span) < end)
+		return 0;
+	return -EFBIG;
+}
+
+static int
+itd_schedule (struct ehci_hcd *ehci, struct urb *urb)
+{
+	unsigned	start, max, i;
+	int		status;
+	unsigned	mod = ehci->periodic_size << 3;
+
+	for (i = 0; i < urb->number_of_packets; i++) {
+		urb->iso_frame_desc [i].status = -EINPROGRESS;
+		urb->iso_frame_desc [i].actual_length = 0;
+	}
+
+	if ((status = get_iso_range (ehci, urb, &start, &max, mod)) != 0)
+		return status;
+
+	do {
+		unsigned	uframe;
+		unsigned	usecs;
+		struct ehci_itd	*itd;
+
+		/* check schedule: enough space? */
+		itd = urb->hcpriv;
+		uframe = start;
+		for (i = 0, uframe = start;
+				i < urb->number_of_packets;
+				i++, uframe += urb->interval) {
+			uframe %= mod;
+
+			/* can't commit more than 80% periodic == 100 usec */
+			if (periodic_usecs (ehci, uframe >> 3, uframe & 0x7)
+					> (100 - itd->usecs)) {
+				itd = 0;
+				break;
+			}
+			itd = list_entry (itd->itd_list.next,
+				struct ehci_itd, itd_list);
+		}
+		if (!itd)
+			continue;
+		
+		/* that's where we'll schedule this! */
+		itd = urb->hcpriv;
+		urb->start_frame = start >> 3;
+		vdbg ("ISO urb %p (%d packets period %d) starting %d.%d",
+			urb, urb->number_of_packets, urb->interval,
+			urb->start_frame, start & 0x7);
+		for (i = 0, uframe = start, usecs = 0;
+				i < urb->number_of_packets;
+				i++, uframe += urb->interval) {
+			uframe %= mod;
+
+			itd->uframe = uframe;
+			itd->hw_transaction [uframe & 0x07] = itd->transaction;
+			itd_link (ehci, (uframe >> 3) % ehci->periodic_size,
+				itd);
+			wmb ();
+			usecs += itd->usecs;
+
+			itd = list_entry (itd->itd_list.next,
+				struct ehci_itd, itd_list);
+		}
+
+		/* update bandwidth utilization records (for usbfs)
+		 *
+		 * FIXME This claims each URB queued to an endpoint, as if
+		 * transfers were concurrent, not sequential.  So bandwidth
+		 * typically gets double-billed ... comes from tying it to
+		 * URBs rather than endpoints in the schedule.  Luckily we
+		 * don't use this usbfs data for serious decision making.
+		 */
+		usecs /= urb->number_of_packets;
+		usecs /= urb->interval;
+		usecs >>= 3;
+		if (usecs < 1)
+			usecs = 1;
+		usb_claim_bandwidth (urb->dev, urb, usecs, 1);
+
+		/* maybe enable periodic schedule processing */
+		if (!ehci->periodic_urbs++)
+			enable_periodic (ehci);
+
+		return 0;
+
+	} while ((start = ++start % mod) != max);
+
+	/* no room in the schedule */
+	dbg ("urb %p, CAN'T SCHEDULE", urb);
+	return -ENOSPC;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#define	ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)
+
+static unsigned long
+itd_complete (
+	struct ehci_hcd	*ehci,
+	struct ehci_itd	*itd,
+	unsigned	uframe,
+	unsigned long	flags
+) {
+	struct urb				*urb = itd->urb;
+	iso_packet_descriptor_t			*desc;
+	u32					t;
+
+	/* update status for this uframe's transfers */
+	desc = &urb->iso_frame_desc [itd->index];
+
+	t = itd->hw_transaction [uframe];
+	itd->hw_transaction [uframe] = 0;
+	if (t & EHCI_ISOC_ACTIVE)
+		desc->status = -EXDEV;
+	else if (t & ISO_ERRS) {
+		urb->error_count++;
+		if (t & EHCI_ISOC_BUF_ERR)
+			desc->status = usb_pipein (urb->pipe)
+				? -ENOSR  /* couldn't read */
+				: -ECOMM; /* couldn't write */
+		else if (t & EHCI_ISOC_BABBLE)
+			desc->status = -EOVERFLOW;
+		else /* (t & EHCI_ISOC_XACTERR) */
+			desc->status = -EPROTO;
+
+		/* HC need not update length with this error */
+		if (!(t & EHCI_ISOC_BABBLE))
+			desc->actual_length += EHCI_ITD_LENGTH (t);
+	} else {
+		desc->status = 0;
+		desc->actual_length += EHCI_ITD_LENGTH (t);
+	}
+
+	vdbg ("itd %p urb %p packet %d/%d trans %x status %d len %d",
+		itd, urb, itd->index + 1, urb->number_of_packets,
+		t, desc->status, desc->actual_length);
+
+	/* handle completion now? */
+	if ((itd->index + 1) != urb->number_of_packets)
+		return flags;
+
+	/*
+	 * For now, always give the urb back to the driver ... expect it
+	 * to submit a new urb (or resubmit this), and to have another
+	 * already queued when un-interrupted transfers are needed.
+	 * No, that's not what OHCI or UHCI are now doing.
+	 *
+	 * FIXME Revisit the ISO URB model.  It's cleaner not to have all
+	 * the special case magic, but it'd be faster to reuse existing
+	 * ITD/DMA setup and schedule state.  Easy to dma_sync/complete(),
+	 * then either reschedule or, if unlinking, free and giveback().
+	 * But we can't overcommit like the full and low speed HCs do, and
+	 * there's no clean way to report an error when rescheduling...
+	 *
+	 * NOTE that for now we don't accelerate ISO unlinks; they just
+	 * happen according to the current schedule.  Means a delay of
+	 * up to about a second (max).
+	 */
+	itd_free_list (ehci, urb);
+	if (urb->status == -EINPROGRESS)
+		urb->status = 0;
+
+	spin_unlock_irqrestore (&ehci->lock, flags);
+	usb_hcd_giveback_urb (&ehci->hcd, urb);
+	spin_lock_irqsave (&ehci->lock, flags);
+
+	/* defer stopping schedule; completion can submit */
+	ehci->periodic_urbs--;
+	if (!ehci->periodic_urbs)
+		disable_periodic (ehci);
+
+	return flags;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
+{
+	int		status;
+	unsigned long	flags;
+
+	dbg ("itd_submit urb %p", urb);
+
+	/* NOTE DMA mapping assumes this ... */
+	if (urb->iso_frame_desc [0].offset != 0)
+		return -EINVAL;
+	
+	/*
+	 * NOTE doing this for now, anticipating periodic URB models
+	 * get updated to be "explicit resubmit".
+	 */
+	if (urb->next) {
+		dbg ("use explicit resubmit for ISO");
+		return -EINVAL;
+	}
+
+	/* allocate ITDs w/o locking anything */
+	status = itd_urb_transaction (ehci, urb, mem_flags);
+	if (status < 0)
+		return status;
+
+	/* schedule ... need to lock */
+	spin_lock_irqsave (&ehci->lock, flags);
+	status = itd_schedule (ehci, urb);
+	spin_unlock_irqrestore (&ehci->lock, flags);
+	if (status < 0)
+		itd_free_list (ehci, urb);
+
+	return status;
+}
+
+#ifdef have_split_iso
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * "Split ISO TDs" ... used for USB 1.1 devices going through
+ * the TTs in USB 2.0 hubs.
+ */
+
+static void
+sitd_free (struct ehci_hcd *ehci, struct ehci_sitd *sitd)
+{
+	pci_pool_free (ehci->sitd_pool, sitd, sitd->sitd_dma);
+}
+
+static struct ehci_sitd *
+sitd_make (
+	struct ehci_hcd	*ehci,
+	struct urb	*urb,
+	unsigned	index,		// urb->iso_frame_desc [index]
+	unsigned	uframe,		// scheduled start
+	dma_addr_t	dma,		// mapped transfer buffer
+	int		mem_flags
+) {
+	struct ehci_sitd	*sitd;
+	unsigned		length;
+
+	sitd = pci_pool_alloc (ehci->sitd_pool, mem_flags, &dma);
+	if (!sitd)
+		return sitd;
+	sitd->urb = urb;
+	length = urb->iso_frame_desc [index].length;
+	dma += urb->iso_frame_desc [index].offset;
+
+#if 0
+	// FIXME:  do the rest!
+#else
+	sitd_free (ehci, sitd);
+	return 0;
+#endif
+
+}
+
+static void
+sitd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd)
+{
+	u32		ptr;
+
+	ptr = cpu_to_le32 (sitd->sitd_dma | 2);	// type 2 == sitd
+	if (ehci->pshadow [frame].ptr) {
+		if (!sitd->sitd_next.ptr) {
+			sitd->sitd_next = ehci->pshadow [frame];
+			sitd->hw_next = ehci->periodic [frame];
+		} else if (sitd->sitd_next.ptr != ehci->pshadow [frame].ptr) {
+			dbg ("frame %d sitd link goof", frame);
+			BUG ();
+		}
+	}
+	ehci->pshadow [frame].sitd = sitd;
+	ehci->periodic [frame] = ptr;
+}
+
+static unsigned long
+sitd_complete (
+	struct ehci_hcd *ehci,
+	struct ehci_sitd	*sitd,
+	unsigned long		flags
+) {
+	// FIXME -- implement!
+
+	dbg ("NYI -- sitd_complete");
+	return flags;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
+{
+	// struct ehci_sitd	*first_sitd = 0;
+	unsigned		frame_index;
+	dma_addr_t		dma;
+
+	dbg ("NYI -- sitd_submit");
+
+	// FIXME -- implement!
+
+	// FIXME:  setup one big dma mapping
+	dma = 0;
+
+	for (frame_index = 0;
+			frame_index < urb->number_of_packets;
+			frame_index++) {
+		struct ehci_sitd	*sitd;
+		unsigned		uframe;
+
+		// FIXME:  use real arguments, schedule this!
+		uframe = -1;
+
+		sitd = sitd_make (ehci, urb, frame_index,
+				uframe, dma, mem_flags);
+
+		if (sitd) {
+    /*
+			if (first_sitd)
+				list_add_tail (&sitd->sitd_list,
+						&first_sitd->sitd_list);
+			else
+				first_sitd = sitd;
+    */
+		} else {
+			// FIXME:  clean everything up
+		}
+	}
+
+	// if we have a first sitd, then
+		// store them all into the periodic schedule!
+		// urb->hcpriv = first sitd in sitd_list
+
+	return -ENOSYS;
+}
+#endif /* have_split_iso */
+
+/*-------------------------------------------------------------------------*/
+
+static void scan_periodic (struct ehci_hcd *ehci)
+{
+	unsigned	frame, clock, now_uframe, mod;
+	unsigned long	flags;
+
+	mod = ehci->periodic_size << 3;
+	spin_lock_irqsave (&ehci->lock, flags);
+
+	/*
+	 * When running, scan from last scan point up to "now"
+	 * else clean up by scanning everything that's left.
+	 * Touches as few pages as possible:  cache-friendly.
+	 * Don't scan ISO entries more than once, though.
+	 */
+	frame = ehci->next_uframe >> 3;
+	if (HCD_IS_RUNNING (ehci->hcd.state))
+		now_uframe = readl (&ehci->regs->frame_index);
+	else
+		now_uframe = (frame << 3) - 1;
+	now_uframe %= mod;
+	clock = now_uframe >> 3;
+
+	for (;;) {
+		union ehci_shadow	q, *q_p;
+		u32			type, *hw_p;
+		unsigned		uframes;
+
+restart:
+		/* scan schedule to _before_ current frame index */
+		if (frame == clock)
+			uframes = now_uframe & 0x07;
+		else
+			uframes = 8;
+
+		q_p = &ehci->pshadow [frame];
+		hw_p = &ehci->periodic [frame];
+		q.ptr = q_p->ptr;
+		type = Q_NEXT_TYPE (*hw_p);
+
+		/* scan each element in frame's queue for completions */
+		while (q.ptr != 0) {
+			int			last;
+			unsigned		uf;
+			union ehci_shadow	temp;
+
+			switch (type) {
+			case Q_TYPE_QH:
+				last = (q.qh->hw_next == EHCI_LIST_END);
+				temp = q.qh->qh_next;
+				type = Q_NEXT_TYPE (q.qh->hw_next);
+				flags = intr_complete (ehci, frame,
+						qh_get (q.qh), flags);
+				qh_put (ehci, q.qh);
+				q = temp;
+				break;
+			case Q_TYPE_FSTN:
+				last = (q.fstn->hw_next == EHCI_LIST_END);
+				/* for "save place" FSTNs, look at QH entries
+				 * in the previous frame for completions.
+				 */
+				if (q.fstn->hw_prev != EHCI_LIST_END) {
+					dbg ("ignoring completions from FSTNs");
+				}
+				type = Q_NEXT_TYPE (q.fstn->hw_next);
+				q = q.fstn->fstn_next;
+				break;
+			case Q_TYPE_ITD:
+				last = (q.itd->hw_next == EHCI_LIST_END);
+
+				/* Unlink each (S)ITD we see, since the ISO
+				 * URB model forces constant rescheduling.
+				 * That complicates sharing uframes in ITDs,
+				 * and means we need to skip uframes the HC
+				 * hasn't yet processed.
+				 */
+				for (uf = 0; uf < uframes; uf++) {
+					if (q.itd->hw_transaction [uf] != 0) {
+						temp = q;
+						*q_p = q.itd->itd_next;
+						*hw_p = q.itd->hw_next;
+						type = Q_NEXT_TYPE (*hw_p);
+
+						/* might free q.itd ... */
+						flags = itd_complete (ehci,
+							temp.itd, uf, flags);
+						break;
+					}
+				}
+				/* we might skip this ITD's uframe ... */
+				if (uf == uframes) {
+					q_p = &q.itd->itd_next;
+					hw_p = &q.itd->hw_next;
+					type = Q_NEXT_TYPE (q.itd->hw_next);
+				}
+
+				q = *q_p;
+				break;
+#ifdef have_split_iso
+			case Q_TYPE_SITD:
+				last = (q.sitd->hw_next == EHCI_LIST_END);
+				flags = sitd_complete (ehci, q.sitd, flags);
+				type = Q_NEXT_TYPE (q.sitd->hw_next);
+
+				// FIXME unlink SITD after split completes
+				q = q.sitd->sitd_next;
+				break;
+#endif /* have_split_iso */
+			default:
+				dbg ("corrupt type %d frame %d shadow %p",
+					type, frame, q.ptr);
+				// BUG ();
+				last = 1;
+				q.ptr = 0;
+			}
+
+			/* did completion remove an interior q entry? */
+			if (unlikely (q.ptr == 0 && !last))
+				goto restart;
+		}
+
+		/* stop when we catch up to the HC */
+
+		// FIXME:  this assumes we won't get lapped when
+		// latencies climb; that should be rare, but...
+		// detect it, and just go all the way around.
+		// FLR might help detect this case, so long as latencies
+		// don't exceed periodic_size msec (default 1.024 sec).
+
+		// FIXME:  likewise assumes HC doesn't halt mid-scan
+
+		if (frame == clock) {
+			unsigned	now;
+
+			if (!HCD_IS_RUNNING (ehci->hcd.state))
+				break;
+			ehci->next_uframe = now_uframe;
+			now = readl (&ehci->regs->frame_index) % mod;
+			if (now_uframe == now)
+				break;
+
+			/* rescan the rest of this frame, then ... */
+			now_uframe = now;
+			clock = now_uframe >> 3;
+		} else
+			frame = (frame + 1) % ehci->periodic_size;
+	} 
+	spin_unlock_irqrestore (&ehci->lock, flags);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd/ehci.h linux/drivers/usb/hcd/ehci.h
--- linux.orig/drivers/usb/hcd/ehci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd/ehci.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2001-2002 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LINUX_EHCI_HCD_H
+#define __LINUX_EHCI_HCD_H
+
+/* definitions used for the EHCI driver */
+
+/* ehci_hcd->lock guards shared data against other CPUs:
+ *   ehci_hcd:	async, reclaim, periodic (and shadow), ...
+ *   hcd_dev:	ep[]
+ *   ehci_qh:	qh_next, qtd_list
+ *   ehci_qtd:	qtd_list
+ *
+ * Also, hold this lock when talking to HC registers or
+ * when updating hw_* fields in shared qh/qtd/... structures.
+ */
+
+#define	EHCI_MAX_ROOT_PORTS	15		/* see HCS_N_PORTS */
+
+struct ehci_hcd {			/* one per controller */
+	spinlock_t		lock;
+
+	/* async schedule support */
+	struct ehci_qh		*async;
+	struct ehci_qh		*reclaim;
+	int			reclaim_ready;
+
+	/* periodic schedule support */
+#define	DEFAULT_I_TDPS		1024		/* some HCs can do less */
+	unsigned		periodic_size;
+	u32			*periodic;	/* hw periodic table */
+	dma_addr_t		periodic_dma;
+	unsigned		i_thresh;	/* uframes HC might cache */
+
+	union ehci_shadow	*pshadow;	/* mirror hw periodic table */
+	int			next_uframe;	/* scan periodic, start here */
+	unsigned		periodic_urbs;	/* how many urbs scheduled? */
+
+	/* deferred work from IRQ, etc */
+	struct tasklet_struct	tasklet;
+
+	/* per root hub port */
+	unsigned long		reset_done [EHCI_MAX_ROOT_PORTS];
+
+	/* glue to PCI and HCD framework */
+	struct usb_hcd		hcd;
+	struct ehci_caps	*caps;
+	struct ehci_regs	*regs;
+	u32			hcs_params;	/* cached register copy */
+
+	/* per-HC memory pools (could be per-PCI-bus, but ...) */
+	struct pci_pool		*qh_pool;	/* qh per active urb */
+	struct pci_pool		*qtd_pool;	/* one or more per qh */
+	struct pci_pool		*itd_pool;	/* itd per iso urb */
+	struct pci_pool		*sitd_pool;	/* sitd per split iso urb */
+};
+
+/* unwrap an HCD pointer to get an EHCI_HCD pointer */ 
+#define hcd_to_ehci(hcd_ptr) list_entry(hcd_ptr, struct ehci_hcd, hcd)
+
+/* NOTE:  urb->transfer_flags expected to not use this bit !!! */
+#define EHCI_STATE_UNLINK	0x8000		/* urb being unlinked */
+
+/*-------------------------------------------------------------------------*/
+
+/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
+
+/* Section 2.2 Host Controller Capability Registers */
+struct ehci_caps {
+	u8		length;		/* CAPLENGTH - size of this struct */
+	u8		reserved;       /* offset 0x1 */
+	u16		hci_version;    /* HCIVERSION - offset 0x2 */
+	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */
+#define HCS_DEBUG_PORT(p)	(((p)>>20)&0xf)	/* bits 23:20, debug port? */
+#define HCS_INDICATOR(p)	((p)&(1 << 16))	/* true: has port indicators */
+#define HCS_N_CC(p)		(((p)>>12)&0xf)	/* bits 15:12, #companion HCs */
+#define HCS_N_PCC(p)		(((p)>>8)&0xf)	/* bits 11:8, ports per CC */
+#define HCS_PORTROUTED(p)	((p)&(1 << 7))	/* true: port routing */ 
+#define HCS_PPC(p)		((p)&(1 << 4))	/* true: port power control */ 
+#define HCS_N_PORTS(p)		(((p)>>0)&0xf)	/* bits 3:0, ports on HC */
+
+	u32		hcc_params;      /* HCCPARAMS - offset 0x8 */
+#define HCC_EXT_CAPS(p)		(((p)>>8)&0xff)	/* for pci extended caps */
+#define HCC_ISOC_CACHE(p)       ((p)&(1 << 7))  /* true: can cache isoc frame */
+#define HCC_ISOC_THRES(p)       (((p)>>4)&0x7)  /* bits 6:4, uframes cached */
+#define HCC_CANPARK(p)		((p)&(1 << 2))  /* true: can park on async qh */
+#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/
+#define HCC_64BIT_ADDR(p)       ((p)&(1))       /* true: can use 64-bit addr */
+	u8		portroute [8];	 /* nibbles for routing - offset 0xC */
+} __attribute__ ((packed));
+
+
+/* Section 2.3 Host Controller Operational Registers */
+struct ehci_regs {
+
+	/* USBCMD: offset 0x00 */
+	u32		command;
+/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
+#define CMD_PARK	(1<<11)		/* enable "park" on async qh */
+#define CMD_PARK_CNT(c)	(((c)>>8)&3)	/* how many transfers to park for */
+#define CMD_LRESET	(1<<7)		/* partial reset (no ports, etc) */
+#define CMD_IAAD	(1<<6)		/* "doorbell" interrupt async advance */
+#define CMD_ASE		(1<<5)		/* async schedule enable */
+#define CMD_PSE  	(1<<4)		/* periodic schedule enable */
+/* 3:2 is periodic frame list size */
+#define CMD_RESET	(1<<1)		/* reset HC not bus */
+#define CMD_RUN		(1<<0)		/* start/stop HC */
+
+	/* USBSTS: offset 0x04 */
+	u32		status;
+#define STS_ASS		(1<<15)		/* Async Schedule Status */
+#define STS_PSS		(1<<14)		/* Periodic Schedule Status */
+#define STS_RECL	(1<<13)		/* Reclamation */
+#define STS_HALT	(1<<12)		/* Not running (any reason) */
+/* some bits reserved */
+	/* these STS_* flags are also intr_enable bits (USBINTR) */
+#define STS_IAA		(1<<5)		/* Interrupted on async advance */
+#define STS_FATAL	(1<<4)		/* such as some PCI access errors */
+#define STS_FLR		(1<<3)		/* frame list rolled over */
+#define STS_PCD		(1<<2)		/* port change detect */
+#define STS_ERR		(1<<1)		/* "error" completion (overflow, ...) */
+#define STS_INT		(1<<0)		/* "normal" completion (short, ...) */
+
+	/* USBINTR: offset 0x08 */
+	u32		intr_enable;
+
+	/* FRINDEX: offset 0x0C */
+	u32		frame_index;	/* current microframe number */
+	/* CTRLDSSEGMENT: offset 0x10 */
+	u32		segment; 	/* address bits 63:32 if needed */
+	/* PERIODICLISTBASE: offset 0x14 */
+	u32		frame_list; 	/* points to periodic list */
+	/* ASYNCICLISTADDR: offset 0x18 */
+	u32		async_next;	/* address of next async queue head */
+
+	u32		reserved [9];
+
+	/* CONFIGFLAG: offset 0x40 */
+	u32		configured_flag;
+#define FLAG_CF		(1<<0)		/* true: we'll support "high speed" */
+
+	/* PORTSC: offset 0x44 */
+	u32		port_status [0];	/* up to N_PORTS */
+/* 31:23 reserved */
+#define PORT_WKOC_E	(1<<22)		/* wake on overcurrent (enable) */
+#define PORT_WKDISC_E	(1<<21)		/* wake on disconnect (enable) */
+#define PORT_WKCONN_E	(1<<20)		/* wake on connect (enable) */
+/* 19:16 for port testing */
+/* 15:14 for using port indicator leds (if HCS_INDICATOR allows) */
+#define PORT_OWNER	(1<<13)		/* true: companion hc owns this port */
+#define PORT_POWER	(1<<12)		/* true: has power (see PPC) */
+#define PORT_USB11(x) (((x)&(3<<10))==(1<<10))	/* USB 1.1 device */
+/* 11:10 for detecting lowspeed devices (reset vs release ownership) */
+/* 9 reserved */
+#define PORT_RESET	(1<<8)		/* reset port */
+#define PORT_SUSPEND	(1<<7)		/* suspend port */
+#define PORT_RESUME	(1<<6)		/* resume it */
+#define PORT_OCC	(1<<5)		/* over current change */
+#define PORT_OC		(1<<4)		/* over current active */
+#define PORT_PEC	(1<<3)		/* port enable change */
+#define PORT_PE		(1<<2)		/* port enable */
+#define PORT_CSC	(1<<1)		/* connect status change */
+#define PORT_CONNECT	(1<<0)		/* device connected */
+} __attribute__ ((packed));
+
+
+/*-------------------------------------------------------------------------*/
+
+#define	QTD_NEXT(dma)	cpu_to_le32((u32)dma)
+
+/*
+ * EHCI Specification 0.95 Section 3.5
+ * QTD: describe data transfer components (buffer, direction, ...) 
+ * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
+ *
+ * These are associated only with "QH" (Queue Head) structures,
+ * used with control, bulk, and interrupt transfers.
+ */
+struct ehci_qtd {
+	/* first part defined by EHCI spec */
+	u32			hw_next;	  /* see EHCI 3.5.1 */
+	u32			hw_alt_next;      /* see EHCI 3.5.2 */
+	u32			hw_token;         /* see EHCI 3.5.3 */       
+#define	QTD_TOGGLE	(1 << 31)	/* data toggle */
+#define	QTD_LENGTH(tok)	(((tok)>>16) & 0x7fff)
+#define	QTD_IOC		(1 << 15)	/* interrupt on complete */
+#define	QTD_CERR(tok)	(((tok)>>10) & 0x3)
+#define	QTD_PID(tok)	(((tok)>>8) & 0x3)
+#define	QTD_STS_ACTIVE	(1 << 7)	/* HC may execute this */
+#define	QTD_STS_HALT	(1 << 6)	/* halted on error */
+#define	QTD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */
+#define	QTD_STS_BABBLE	(1 << 4)	/* device was babbling (qtd halted) */
+#define	QTD_STS_XACT	(1 << 3)	/* device gave illegal response */
+#define	QTD_STS_MMF	(1 << 2)	/* incomplete split transaction */
+#define	QTD_STS_STS	(1 << 1)	/* split transaction state */
+#define	QTD_STS_PING	(1 << 0)	/* issue PING? */
+	u32			hw_buf [5];        /* see EHCI 3.5.4 */
+	u32			hw_buf_hi [5];        /* Appendix B */
+
+	/* the rest is HCD-private */
+	dma_addr_t		qtd_dma;		/* qtd address */
+	struct list_head	qtd_list;		/* sw qtd list */
+
+	/* dma same in urb's qtds, except 1st control qtd (setup buffer) */
+	struct urb		*urb;			/* qtd's urb */
+	dma_addr_t		buf_dma;		/* buffer address */
+	size_t			length;			/* length of buffer */
+} __attribute__ ((aligned (32)));
+
+/*-------------------------------------------------------------------------*/
+
+/* type tag from {qh,itd,sitd,fstn}->hw_next */
+#define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1))
+
+/* values for that type tag */
+#define Q_TYPE_ITD	__constant_cpu_to_le32 (0 << 1)
+#define Q_TYPE_QH	__constant_cpu_to_le32 (1 << 1)
+#define Q_TYPE_SITD 	__constant_cpu_to_le32 (2 << 1)
+#define Q_TYPE_FSTN 	__constant_cpu_to_le32 (3 << 1)
+
+/* next async queue entry, or pointer to interrupt/periodic QH */
+#define	QH_NEXT(dma)	(cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH)
+
+/* for periodic/async schedules and qtd lists, mark end of list */
+#define	EHCI_LIST_END	__constant_cpu_to_le32(1) /* "null pointer" to hw */
+
+/*
+ * Entries in periodic shadow table are pointers to one of four kinds
+ * of data structure.  That's dictated by the hardware; a type tag is
+ * encoded in the low bits of the hardware's periodic schedule.  Use
+ * Q_NEXT_TYPE to get the tag.
+ *
+ * For entries in the async schedule, the type tag always says "qh".
+ */
+union ehci_shadow {
+	struct ehci_qh 		*qh;		/* Q_TYPE_QH */
+	struct ehci_itd		*itd;		/* Q_TYPE_ITD */
+	struct ehci_sitd	*sitd;		/* Q_TYPE_SITD */
+	struct ehci_fstn	*fstn;		/* Q_TYPE_FSTN */
+	void			*ptr;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI Specification 0.95 Section 3.6
+ * QH: describes control/bulk/interrupt endpoints
+ * See Fig 3-7 "Queue Head Structure Layout".
+ *
+ * These appear in both the async and (for interrupt) periodic schedules.
+ */
+
+struct ehci_qh {
+	/* first part defined by EHCI spec */
+	u32			hw_next;	 /* see EHCI 3.6.1 */
+	u32			hw_info1;        /* see EHCI 3.6.2 */
+#define	QH_HEAD		0x00008000
+	u32			hw_info2;        /* see EHCI 3.6.2 */
+	u32			hw_current;	 /* qtd list - see EHCI 3.6.4 */
+	
+	/* qtd overlay (hardware parts of a struct ehci_qtd) */
+	u32			hw_qtd_next;
+	u32			hw_alt_next;
+	u32			hw_token;
+	u32			hw_buf [5];
+	u32			hw_buf_hi [5];
+
+	/* the rest is HCD-private */
+	dma_addr_t		qh_dma;		/* address of qh */
+	union ehci_shadow	qh_next;	/* ptr to qh; or periodic */
+	struct list_head	qtd_list;	/* sw qtd list */
+
+	atomic_t		refcount;
+	unsigned short		usecs;		/* intr bandwidth */
+	short			qh_state;
+#define	QH_STATE_LINKED		1		/* HC sees this */
+#define	QH_STATE_UNLINK		2		/* HC may still see this */
+#define	QH_STATE_IDLE		3		/* HC doesn't see this */
+
+#ifdef EHCI_SOFT_RETRIES
+	int			retries;
+#endif
+} __attribute__ ((aligned (32)));
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI Specification 0.95 Section 3.3
+ * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
+ *
+ * Schedule records for high speed iso xfers
+ */
+struct ehci_itd {
+	/* first part defined by EHCI spec */
+	u32			hw_next;           /* see EHCI 3.3.1 */
+	u32			hw_transaction [8]; /* see EHCI 3.3.2 */
+#define EHCI_ISOC_ACTIVE        (1<<31)        /* activate transfer this slot */
+#define EHCI_ISOC_BUF_ERR       (1<<30)        /* Data buffer error */
+#define EHCI_ISOC_BABBLE        (1<<29)        /* babble detected */
+#define EHCI_ISOC_XACTERR       (1<<28)        /* XactErr - transaction error */
+#define	EHCI_ITD_LENGTH(tok)	(((tok)>>16) & 0x7fff)
+#define	EHCI_ITD_IOC		(1 << 15)	/* interrupt on complete */
+
+	u32			hw_bufp [7];	/* see EHCI 3.3.3 */ 
+	u32			hw_bufp_hi [7];	/* Appendix B */
+
+	/* the rest is HCD-private */
+	dma_addr_t		itd_dma;	/* for this itd */
+	union ehci_shadow	itd_next;	/* ptr to periodic q entry */
+
+	struct urb		*urb;
+	struct list_head	itd_list;	/* list of urb frames' itds */
+	dma_addr_t		buf_dma;	/* frame's buffer address */
+
+	/* for now, only one hw_transaction per itd */
+	u32			transaction;
+	u16			index;		/* in urb->iso_frame_desc */
+	u16			uframe;		/* in periodic schedule */
+	u16			usecs;
+} __attribute__ ((aligned (32)));
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI Specification 0.95 Section 3.4 
+ * siTD, aka split-transaction isochronous Transfer Descriptor
+ *       ... describe low/full speed iso xfers through TT in hubs
+ * see Figure 3-5 "Split-transaction Isochronous Transaction Descriptor (siTD)
+ */
+struct ehci_sitd {
+	/* first part defined by EHCI spec */
+	u32			hw_next;
+/* uses bit field macros above - see EHCI 0.95 Table 3-8 */
+	u32			hw_fullspeed_ep;  /* see EHCI table 3-9 */
+	u32                     hw_uframe;        /* see EHCI table 3-10 */
+        u32                     hw_tx_results1;   /* see EHCI table 3-11 */
+	u32                     hw_tx_results2;   /* see EHCI table 3-12 */
+	u32                     hw_tx_results3;   /* see EHCI table 3-12 */
+        u32                     hw_backpointer;   /* see EHCI table 3-13 */
+	u32			hw_buf_hi [2];	  /* Appendix B */
+
+	/* the rest is HCD-private */
+	dma_addr_t		sitd_dma;
+	union ehci_shadow	sitd_next;	/* ptr to periodic q entry */
+	struct urb		*urb;
+	dma_addr_t		buf_dma;	/* buffer address */
+} __attribute__ ((aligned (32)));
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI Specification 0.96 Section 3.7
+ * Periodic Frame Span Traversal Node (FSTN)
+ *
+ * Manages split interrupt transactions (using TT) that span frame boundaries
+ * into uframes 0/1; see 4.12.2.2.  In those uframes, a "save place" FSTN
+ * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
+ * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
+ */
+struct ehci_fstn {
+	u32			hw_next;	/* any periodic q entry */
+	u32			hw_prev;	/* qh or EHCI_LIST_END */
+
+	/* the rest is HCD-private */
+	dma_addr_t		fstn_dma;
+	union ehci_shadow	fstn_next;	/* ptr to periodic q entry */
+} __attribute__ ((aligned (32)));
+
+#endif /* __LINUX_EHCI_HCD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd.c linux/drivers/usb/hcd.c
--- linux.orig/drivers/usb/hcd.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,1469 @@
+/*
+ * Copyright (c) 2001-2002 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/uts.h>			/* for UTS_SYSNAME */
+
+
+#ifdef CONFIG_USB_DEBUG
+	#define DEBUG
+#else
+	#undef DEBUG
+#endif
+
+#include <linux/usb.h>
+#include "hcd.h"
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * USB Host Controller Driver framework
+ *
+ * Plugs into usbcore (usb_bus) and lets HCDs share code, minimizing
+ * HCD-specific behaviors/bugs.
+ *
+ * This does error checks, tracks devices and urbs, and delegates to a
+ * "hc_driver" only for code (and data) that really needs to know about
+ * hardware differences.  That includes root hub registers, i/o queues,
+ * and so on ... but as little else as possible.
+ *
+ * Shared code includes most of the "root hub" code (these are emulated,
+ * though each HC's hardware works differently) and PCI glue, plus request
+ * tracking overhead.  The HCD code should only block on spinlocks or on
+ * hardware handshaking; blocking on software events (such as other kernel
+ * threads releasing resources, or completing actions) is all generic.
+ *
+ * Happens the USB 2.0 spec says this would be invisible inside the "USBD",
+ * and includes mostly a "HCDI" (HCD Interface) along with some APIs used
+ * only by the hub driver ... and that neither should be seen or used by
+ * usb client device drivers.
+ *
+ * Contributors of ideas or unattributed patches include: David Brownell,
+ * Roman Weissgaerber, Rory Bolt, ...
+ *
+ * HISTORY:
+ * 2001-12-12	Initial patch version for Linux 2.5.1 kernel.
+ */
+
+/*-------------------------------------------------------------------------*/
+
+/* host controllers we manage */
+static LIST_HEAD (hcd_list);
+
+/* used when updating list of hcds */
+static DECLARE_MUTEX (hcd_list_lock);
+
+/* used when updating hcd data */
+static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
+
+static struct usb_operations hcd_operations;
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Sharable chunks of root hub code.
+ */
+
+/*-------------------------------------------------------------------------*/
+
+#define KERNEL_REL	((LINUX_VERSION_CODE >> 16) & 0x0ff)
+#define KERNEL_VER	((LINUX_VERSION_CODE >> 8) & 0x0ff)
+
+/* usb 2.0 root hub device descriptor */
+static const u8 usb2_rh_dev_descriptor [18] = {
+	0x12,       /*  __u8  bLength; */
+	0x01,       /*  __u8  bDescriptorType; Device */
+	0x00, 0x02, /*  __u16 bcdUSB; v2.0 */
+
+	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,	    /*  __u8  bDeviceSubClass; */
+	0x01,       /*  __u8  bDeviceProtocol; [ usb 2.0 single TT ]*/
+	0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
+
+	0x00, 0x00, /*  __u16 idVendor; */
+ 	0x00, 0x00, /*  __u16 idProduct; */
+	KERNEL_VER, KERNEL_REL, /*  __u16 bcdDevice */
+
+	0x03,       /*  __u8  iManufacturer; */
+	0x02,       /*  __u8  iProduct; */
+	0x01,       /*  __u8  iSerialNumber; */
+	0x01        /*  __u8  bNumConfigurations; */
+};
+
+/* no usb 2.0 root hub "device qualifier" descriptor: one speed only */
+
+/* usb 1.1 root hub device descriptor */
+static const u8 usb11_rh_dev_descriptor [18] = {
+	0x12,       /*  __u8  bLength; */
+	0x01,       /*  __u8  bDescriptorType; Device */
+	0x10, 0x01, /*  __u16 bcdUSB; v1.1 */
+
+	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,	    /*  __u8  bDeviceSubClass; */
+	0x00,       /*  __u8  bDeviceProtocol; [ low/full speeds only ] */
+	0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
+
+	0x00, 0x00, /*  __u16 idVendor; */
+ 	0x00, 0x00, /*  __u16 idProduct; */
+	KERNEL_VER, KERNEL_REL, /*  __u16 bcdDevice */
+
+	0x03,       /*  __u8  iManufacturer; */
+	0x02,       /*  __u8  iProduct; */
+	0x01,       /*  __u8  iSerialNumber; */
+	0x01        /*  __u8  bNumConfigurations; */
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Configuration descriptors for our root hubs */
+
+static const u8 fs_rh_config_descriptor [] = {
+
+	/* one configuration */
+	0x09,       /*  __u8  bLength; */
+	0x02,       /*  __u8  bDescriptorType; Configuration */
+	0x19, 0x00, /*  __u16 wTotalLength; */
+	0x01,       /*  __u8  bNumInterfaces; (1) */
+	0x01,       /*  __u8  bConfigurationValue; */
+	0x00,       /*  __u8  iConfiguration; */
+	0x40,       /*  __u8  bmAttributes; 
+				 Bit 7: Bus-powered,
+				     6: Self-powered,
+				     5 Remote-wakwup,
+				     4..0: resvd */
+	0x00,       /*  __u8  MaxPower; */
+      
+	/* USB 1.1:
+	 * USB 2.0, single TT organization (mandatory):
+	 *	one interface, protocol 0
+	 *
+	 * USB 2.0, multiple TT organization (optional):
+	 *	two interfaces, protocols 1 (like single TT)
+	 *	and 2 (multiple TT mode) ... config is
+	 *	sometimes settable
+	 *	NOT IMPLEMENTED
+	 */
+
+	/* one interface */
+	0x09,       /*  __u8  if_bLength; */
+	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	0x00,       /*  __u8  if_bInterfaceNumber; */
+	0x00,       /*  __u8  if_bAlternateSetting; */
+	0x01,       /*  __u8  if_bNumEndpoints; */
+	0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+	0x00,       /*  __u8  if_bInterfaceSubClass; */
+	0x00,       /*  __u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
+	0x00,       /*  __u8  if_iInterface; */
+     
+	/* one endpoint (status change endpoint) */
+	0x07,       /*  __u8  ep_bLength; */
+	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+ 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
+ 	0x02, 0x00, /*  __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
+	0xff        /*  __u8  ep_bInterval; (255ms -- usb 2.0 spec) */
+};
+
+static const u8 hs_rh_config_descriptor [] = {
+
+	/* one configuration */
+	0x09,       /*  __u8  bLength; */
+	0x02,       /*  __u8  bDescriptorType; Configuration */
+	0x19, 0x00, /*  __u16 wTotalLength; */
+	0x01,       /*  __u8  bNumInterfaces; (1) */
+	0x01,       /*  __u8  bConfigurationValue; */
+	0x00,       /*  __u8  iConfiguration; */
+	0x40,       /*  __u8  bmAttributes; 
+				 Bit 7: Bus-powered,
+				     6: Self-powered,
+				     5 Remote-wakwup,
+				     4..0: resvd */
+	0x00,       /*  __u8  MaxPower; */
+      
+	/* USB 1.1:
+	 * USB 2.0, single TT organization (mandatory):
+	 *	one interface, protocol 0
+	 *
+	 * USB 2.0, multiple TT organization (optional):
+	 *	two interfaces, protocols 1 (like single TT)
+	 *	and 2 (multiple TT mode) ... config is
+	 *	sometimes settable
+	 *	NOT IMPLEMENTED
+	 */
+
+	/* one interface */
+	0x09,       /*  __u8  if_bLength; */
+	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	0x00,       /*  __u8  if_bInterfaceNumber; */
+	0x00,       /*  __u8  if_bAlternateSetting; */
+	0x01,       /*  __u8  if_bNumEndpoints; */
+	0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+	0x00,       /*  __u8  if_bInterfaceSubClass; */
+	0x00,       /*  __u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
+	0x00,       /*  __u8  if_iInterface; */
+     
+	/* one endpoint (status change endpoint) */
+	0x07,       /*  __u8  ep_bLength; */
+	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+ 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
+ 	0x02, 0x00, /*  __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
+	0x0c        /*  __u8  ep_bInterval; (256ms -- usb 2.0 spec) */
+};
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * helper routine for returning string descriptors in UTF-16LE
+ * input can actually be ISO-8859-1; ASCII is its 7-bit subset
+ */
+static int ascii2utf (char *s, u8 *utf, int utfmax)
+{
+	int retval;
+
+	for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {
+		*utf++ = *s++;
+		*utf++ = 0;
+	}
+	return retval;
+}
+
+/*
+ * rh_string - provides manufacturer, product and serial strings for root hub
+ * @id: the string ID number (1: serial number, 2: product, 3: vendor)
+ * @pci_desc: PCI device descriptor for the relevant HC
+ * @type: string describing our driver 
+ * @data: return packet in UTF-16 LE
+ * @len: length of the return packet
+ *
+ * Produces either a manufacturer, product or serial number string for the
+ * virtual root hub device.
+ */
+static int rh_string (
+	int		id,
+	struct usb_hcd	*hcd,
+	u8		*data,
+	int		len
+) {
+	char buf [100];
+
+	// language ids
+	if (id == 0) {
+		*data++ = 4; *data++ = 3;	/* 4 bytes string data */
+		*data++ = 0; *data++ = 0;	/* some language id */
+		return 4;
+
+	// serial number
+	} else if (id == 1) {
+		strcpy (buf, hcd->bus_name);
+
+	// product description
+	} else if (id == 2) {
+                strcpy (buf, hcd->product_desc);
+
+ 	// id 3 == vendor description
+	} else if (id == 3) {
+                sprintf (buf, "%s %s %s", UTS_SYSNAME, UTS_RELEASE,
+			hcd->description);
+
+	// unsupported IDs --> "protocol stall"
+	} else
+	    return 0;
+
+	data [0] = 2 + ascii2utf (buf, data + 2, len - 2);
+	data [1] = 3;	/* type == string */
+	return data [0];
+}
+
+
+/* Root hub control transfers execute synchronously */
+static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
+{
+	devrequest	*cmd = (devrequest *) urb->setup_packet;
+ 	u16		typeReq, wValue, wIndex, wLength;
+	const u8	*bufp = 0;
+	u8		*ubuf = urb->transfer_buffer;
+	int		len = 0;
+
+	typeReq  = (cmd->requesttype << 8) | cmd->request;
+	wValue   = le16_to_cpu (cmd->value);
+	wIndex   = le16_to_cpu (cmd->index);
+	wLength  = le16_to_cpu (cmd->length);
+
+	if (wLength > urb->transfer_buffer_length)
+		goto error;
+
+	/* set up for success */
+	urb->status = 0;
+	urb->actual_length = wLength;
+	switch (typeReq) {
+
+	/* DEVICE REQUESTS */
+
+	case DeviceRequest | USB_REQ_GET_STATUS:
+		// DEVICE_REMOTE_WAKEUP
+		ubuf [0] = 1; // selfpowered
+		ubuf [1] = 0;
+			/* FALLTHROUGH */
+	case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
+	case DeviceOutRequest | USB_REQ_SET_FEATURE:
+		dbg ("no device features yet yet");
+		break;
+	case DeviceRequest | USB_REQ_GET_CONFIGURATION:
+		ubuf [0] = 1;
+			/* FALLTHROUGH */
+	case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
+		break;
+	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
+		switch (wValue & 0xff00) {
+		case USB_DT_DEVICE << 8:
+			if (hcd->driver->flags & HCD_USB2)
+				bufp = usb2_rh_dev_descriptor;
+			else if (hcd->driver->flags & HCD_USB11)
+				bufp = usb11_rh_dev_descriptor;
+			else
+				goto error;
+			len = 18;
+			break;
+		case USB_DT_CONFIG << 8:
+			if (hcd->driver->flags & HCD_USB2) {
+				bufp = hs_rh_config_descriptor;
+				len = sizeof hs_rh_config_descriptor;
+			} else {
+				bufp = fs_rh_config_descriptor;
+				len = sizeof fs_rh_config_descriptor;
+			}
+			break;
+		case USB_DT_STRING << 8:
+			urb->actual_length = rh_string (
+				wValue & 0xff, hcd,
+				ubuf, wLength);
+			break;
+		default:
+			goto error;
+		}
+		break;
+	case DeviceRequest | USB_REQ_GET_INTERFACE:
+		ubuf [0] = 0;
+			/* FALLTHROUGH */
+	case DeviceOutRequest | USB_REQ_SET_INTERFACE:
+		break;
+	case DeviceOutRequest | USB_REQ_SET_ADDRESS:
+		// wValue == urb->dev->devaddr
+		dbg ("%s root hub device address %d",
+			hcd->bus_name, wValue);
+		break;
+
+	/* INTERFACE REQUESTS (no defined feature/status flags) */
+
+	/* ENDPOINT REQUESTS */
+
+	case EndpointRequest | USB_REQ_GET_STATUS:
+		// ENDPOINT_HALT flag
+		ubuf [0] = 0;
+		ubuf [1] = 0;
+			/* FALLTHROUGH */
+	case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
+	case EndpointOutRequest | USB_REQ_SET_FEATURE:
+		dbg ("no endpoint features yet");
+		break;
+
+	/* CLASS REQUESTS (and errors) */
+
+	default:
+		/* non-generic request */
+		urb->status = hcd->driver->hub_control (hcd,
+			typeReq, wValue, wIndex,
+			ubuf, wLength);
+		break;
+error:
+		/* "protocol stall" on error */
+		urb->status = -EPIPE;
+		dbg ("unsupported hub control message (maxchild %d)",
+				urb->dev->maxchild);
+	}
+	if (urb->status) {
+		urb->actual_length = 0;
+		dbg ("CTRL: TypeReq=0x%x val=0x%x idx=0x%x len=%d ==> %d",
+			typeReq, wValue, wIndex, wLength, urb->status);
+	}
+	if (bufp) {
+		if (urb->transfer_buffer_length < len)
+			len = urb->transfer_buffer_length;
+		urb->actual_length = len;
+		// always USB_DIR_IN, toward host
+		memcpy (ubuf, bufp, len);
+	}
+
+	/* any errors get returned through the urb completion */
+	usb_hcd_giveback_urb (hcd, urb);
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Root Hub interrupt transfers are synthesized with a timer.
+ * Completions are called in_interrupt() but not in_irq().
+ */
+
+static void rh_report_status (unsigned long ptr);
+
+static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb) 
+{
+	int	len = 1 + (urb->dev->maxchild / 8);
+
+	/* rh_timer protected by hcd_data_lock */
+	if (timer_pending (&hcd->rh_timer)
+			|| urb->status != -EINPROGRESS
+			|| !HCD_IS_RUNNING (hcd->state)
+			|| urb->transfer_buffer_length < len) {
+		dbg ("not queuing status urb, stat %d", urb->status);
+		return -EINVAL;
+	}
+
+	urb->hcpriv = hcd;	/* nonzero to indicate it's queued */
+	init_timer (&hcd->rh_timer);
+	hcd->rh_timer.function = rh_report_status;
+	hcd->rh_timer.data = (unsigned long) urb;
+	/* USB 2.0 spec says 256msec; this is close enough */
+	hcd->rh_timer.expires = jiffies + HZ/4;
+	add_timer (&hcd->rh_timer);
+	return 0;
+}
+
+/* timer callback */
+
+static void rh_report_status (unsigned long ptr)
+{
+	struct urb	*urb;
+	struct usb_hcd	*hcd;
+	int		length;
+	unsigned long	flags;
+
+	urb = (struct urb *) ptr;
+	spin_lock_irqsave (&urb->lock, flags);
+	if (!urb->dev) {
+		spin_unlock_irqrestore (&urb->lock, flags);
+		return;
+	}
+
+	hcd = urb->dev->bus->hcpriv;
+	if (urb->status == -EINPROGRESS) {
+		if (HCD_IS_RUNNING (hcd->state)) {
+			length = hcd->driver->hub_status_data (hcd,
+					urb->transfer_buffer);
+			spin_unlock_irqrestore (&urb->lock, flags);
+			if (length > 0) {
+				urb->actual_length = length;
+				urb->status = 0;
+				urb->complete (urb);
+			}
+			spin_lock_irqsave (&hcd_data_lock, flags);
+			urb->status = -EINPROGRESS;
+			if (HCD_IS_RUNNING (hcd->state)
+					&& rh_status_urb (hcd, urb) != 0) {
+				/* another driver snuck in? */
+				dbg ("%s, can't resubmit roothub status urb?",
+					hcd->bus_name);
+				spin_unlock_irqrestore (&hcd_data_lock, flags);
+				BUG ();
+			}
+			spin_unlock_irqrestore (&hcd_data_lock, flags);
+		} else
+			spin_unlock_irqrestore (&urb->lock, flags);
+	} else {
+		/* this urb's been unlinked */
+		urb->hcpriv = 0;
+		spin_unlock_irqrestore (&urb->lock, flags);
+
+		usb_hcd_giveback_urb (hcd, urb);
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb)
+{
+	if (usb_pipeint (urb->pipe)) {
+		int		retval;
+		unsigned long	flags;
+
+		spin_lock_irqsave (&hcd_data_lock, flags);
+		retval = rh_status_urb (hcd, urb);
+		spin_unlock_irqrestore (&hcd_data_lock, flags);
+		return retval;
+	}
+	if (usb_pipecontrol (urb->pipe))
+		return rh_call_control (hcd, urb);
+	else
+		return -EINVAL;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb)
+{
+	unsigned long	flags;
+
+	spin_lock_irqsave (&hcd_data_lock, flags);
+	del_timer_sync (&hcd->rh_timer);
+	hcd->rh_timer.data = 0;
+	spin_unlock_irqrestore (&hcd_data_lock, flags);
+
+	/* we rely on RH callback code not unlinking its URB! */
+	usb_hcd_giveback_urb (hcd, urb);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_PCI
+
+/* PCI-based HCs are normal, but custom bus glue should be ok */
+
+static void hcd_irq (int irq, void *__hcd, struct pt_regs *r);
+static void hc_died (struct usb_hcd *hcd);
+
+/*-------------------------------------------------------------------------*/
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+/**
+ * usb_hcd_pci_probe - initialize PCI-based HCDs
+ * @dev: USB Host Controller being probed
+ * @id: pci hotplug id connecting controller to HCD framework
+ * Context: !in_interrupt()
+ *
+ * Allocates basic PCI resources for this USB host controller, and
+ * then invokes the start() method for the HCD associated with it
+ * through the hotplug entry's driver_data.
+ *
+ * Store this function in the HCD's struct pci_driver as probe().
+ */
+int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct hc_driver	*driver;
+	unsigned long		resource, len;
+	void			*base;
+	u8			latency, limit;
+	struct usb_bus		*bus;
+	struct usb_hcd		*hcd;
+	int			retval, region;
+	char			buf [8], *bufp = buf;
+
+	if (!id || !(driver = (struct hc_driver *) id->driver_data))
+		return -EINVAL;
+
+	if (pci_enable_device (dev) < 0)
+		return -ENODEV;
+	
+        if (!dev->irq) {
+        	err ("Found HC with no IRQ.  Check BIOS/PCI %s setup!",
+			dev->slot_name);
+   	        return -ENODEV;
+        }
+	
+	if (driver->flags & HCD_MEMORY) {	// EHCI, OHCI
+		region = 0;
+		resource = pci_resource_start (dev, 0);
+		len = pci_resource_len (dev, 0);
+		if (!request_mem_region (resource, len, driver->description)) {
+			dbg ("controller already in use");
+			return -EBUSY;
+		}
+		base = ioremap_nocache (resource, len);
+		if (base == NULL) {
+			dbg ("error mapping memory");
+			retval = -EFAULT;
+clean_1:
+			release_mem_region (resource, len);
+			err ("init %s fail, %d", dev->slot_name, retval);
+			return retval;
+		}
+
+	} else { 				// UHCI
+		resource = len = 0;
+		for (region = 0; region < PCI_ROM_RESOURCE; region++) {
+			if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
+				continue;
+
+			resource = pci_resource_start (dev, region);
+			len = pci_resource_len (dev, region);
+			if (request_region (resource, len,
+					driver->description))
+				break;
+		}
+		if (region == PCI_ROM_RESOURCE) {
+			dbg ("no i/o regions available");
+			return -EBUSY;
+		}
+		base = (void *) resource;
+	}
+
+	// driver->start(), later on, will transfer device from
+	// control by SMM/BIOS to control by Linux (if needed)
+
+	pci_set_master (dev);
+	hcd = driver->hcd_alloc ();
+	if (hcd == NULL){
+		dbg ("hcd alloc fail");
+		retval = -ENOMEM;
+clean_2:
+		if (driver->flags & HCD_MEMORY) {
+			iounmap (base);
+			goto clean_1;
+		} else {
+			release_region (resource, len);
+			err ("init %s fail, %d", dev->slot_name, retval);
+			return retval;
+		}
+	}
+	pci_set_drvdata(dev, hcd);
+	hcd->driver = driver;
+	hcd->description = driver->description;
+	hcd->pdev = dev;
+	info ("%s @ %s, %s", hcd->description,  dev->slot_name, dev->name);
+
+	pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
+	if (latency) {
+		pci_read_config_byte (dev, PCI_MAX_LAT, &limit);
+		if (limit && limit < latency) {
+			dbg ("PCI latency reduced to max %d", limit);
+			pci_write_config_byte (dev, PCI_LATENCY_TIMER, limit);
+		}
+	}
+
+#ifndef __sparc__
+	sprintf (buf, "%d", dev->irq);
+#else
+	bufp = __irq_itoa(dev->irq);
+#endif
+	if (request_irq (dev->irq, hcd_irq, SA_SHIRQ, hcd->description, hcd)
+			!= 0) {
+		err ("request interrupt %s failed", bufp);
+		retval = -EBUSY;
+clean_3:
+		driver->hcd_free (hcd);
+		goto clean_2;
+	}
+	hcd->irq = dev->irq;
+
+	hcd->regs = base;
+	hcd->region = region;
+	info ("irq %s, %s %p", bufp,
+		(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
+		base);
+
+// FIXME simpler: make "bus" be that data, not pointer to it.
+	bus = usb_alloc_bus (&hcd_operations);
+	if (bus == NULL) {
+		dbg ("usb_alloc_bus fail");
+		retval = -ENOMEM;
+		free_irq (dev->irq, hcd);
+		goto clean_3;
+	}
+	hcd->bus = bus;
+	hcd->bus_name = dev->slot_name;
+	hcd->product_desc = dev->name;
+	bus->hcpriv = (void *) hcd;
+
+	INIT_LIST_HEAD (&hcd->dev_list);
+	INIT_LIST_HEAD (&hcd->hcd_list);
+
+	down (&hcd_list_lock);
+	list_add (&hcd->hcd_list, &hcd_list);
+	up (&hcd_list_lock);
+
+	usb_register_bus (bus);
+
+	if ((retval = driver->start (hcd)) < 0)
+		usb_hcd_pci_remove (dev);
+
+	return retval;
+} 
+EXPORT_SYMBOL (usb_hcd_pci_probe);
+
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_pci_probe(), first invoking
+ * the HCD's stop() method.  It is always called from a thread
+ * context, normally "rmmod", "apmd", or something similar.
+ *
+ * Store this function in the HCD's struct pci_driver as remove().
+ */
+void usb_hcd_pci_remove (struct pci_dev *dev)
+{
+	struct usb_hcd		*hcd;
+	struct usb_device	*hub;
+
+	hcd = pci_get_drvdata(dev);
+	if (!hcd)
+		return;
+	info ("remove: %s, state %x", hcd->bus_name, hcd->state);
+
+	if (in_interrupt ()) BUG ();
+
+	hub = hcd->bus->root_hub;
+	hcd->state = USB_STATE_QUIESCING;
+
+	dbg ("%s: roothub graceful disconnect", hcd->bus_name);
+	usb_disconnect (&hub);
+	// usb_disconnect (&hcd->bus->root_hub);
+
+	hcd->driver->stop (hcd);
+	hcd->state = USB_STATE_HALT;
+
+	free_irq (hcd->irq, hcd);
+	if (hcd->driver->flags & HCD_MEMORY) {
+		iounmap (hcd->regs);
+		release_mem_region (pci_resource_start (dev, 0),
+			pci_resource_len (dev, 0));
+	} else {
+		release_region (pci_resource_start (dev, hcd->region),
+			pci_resource_len (dev, hcd->region));
+	}
+
+	down (&hcd_list_lock);
+	list_del (&hcd->hcd_list);
+	up (&hcd_list_lock);
+
+	usb_deregister_bus (hcd->bus);
+	usb_free_bus (hcd->bus);
+	hcd->bus = NULL;
+
+	hcd->driver->hcd_free (hcd);
+}
+EXPORT_SYMBOL (usb_hcd_pci_remove);
+
+
+#ifdef	CONFIG_PM
+
+/*
+ * Some "sleep" power levels imply updating struct usb_driver
+ * to include a callback asking hcds to do their bit by checking
+ * if all the drivers can suspend.  Gets involved with remote wakeup.
+ *
+ * If there are pending urbs, then HCs will need to access memory,
+ * causing extra power drain.  New sleep()/wakeup() PM calls might
+ * be needed, beyond PCI suspend()/resume().  The root hub timer
+ * still be accessing memory though ...
+ *
+ * FIXME:  USB should have some power budgeting support working with
+ * all kinds of hubs.
+ *
+ * FIXME:  This assumes only D0->D3 suspend and D3->D0 resume.
+ * D1 and D2 states should do something, yes?
+ *
+ * FIXME:  Should provide generic enable_wake(), calling pci_enable_wake()
+ * for all supported states, so that USB remote wakeup can work for any
+ * devices that support it (and are connected via powered hubs).
+ *
+ * FIXME:  resume doesn't seem to work right any more...
+ */
+
+
+// 2.4 kernels have issued concurrent resumes (w/APM)
+// we defend against that error; PCI doesn't yet.
+
+/**
+ * usb_hcd_pci_suspend - power management suspend of a PCI-based HCD
+ * @dev: USB Host Controller being suspended
+ *
+ * Store this function in the HCD's struct pci_driver as suspend().
+ */
+int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
+{
+	struct usb_hcd		*hcd;
+	int			retval;
+
+	hcd = pci_get_drvdata(dev);
+	info ("suspend %s to state %d", hcd->bus_name, state);
+
+	pci_save_state (dev, hcd->pci_state);
+
+	// FIXME for all connected devices, leaf-to-root:
+	// driver->suspend()
+	// proposed "new 2.5 driver model" will automate that
+
+	/* driver may want to disable DMA etc */
+	retval = hcd->driver->suspend (hcd, state);
+	hcd->state = USB_STATE_SUSPENDED;
+
+ 	pci_set_power_state (dev, state);
+	return retval;
+}
+EXPORT_SYMBOL (usb_hcd_pci_suspend);
+
+/**
+ * usb_hcd_pci_resume - power management resume of a PCI-based HCD
+ * @dev: USB Host Controller being resumed
+ *
+ * Store this function in the HCD's struct pci_driver as resume().
+ */
+int usb_hcd_pci_resume (struct pci_dev *dev)
+{
+	struct usb_hcd		*hcd;
+	int			retval;
+
+	hcd = pci_get_drvdata(dev);
+	info ("resume %s", hcd->bus_name);
+
+	/* guard against multiple resumes (APM bug?) */
+	atomic_inc (&hcd->resume_count);
+	if (atomic_read (&hcd->resume_count) != 1) {
+		err ("concurrent PCI resumes for %s", hcd->bus_name);
+		retval = 0;
+		goto done;
+	}
+
+	retval = -EBUSY;
+	if (hcd->state != USB_STATE_SUSPENDED) {
+		dbg ("can't resume, not suspended!");
+		goto done;
+	}
+	hcd->state = USB_STATE_RESUMING;
+
+	pci_set_power_state (dev, 0);
+	pci_restore_state (dev, hcd->pci_state);
+
+	retval = hcd->driver->resume (hcd);
+	if (!HCD_IS_RUNNING (hcd->state)) {
+		dbg ("resume %s failure, retval %d", hcd->bus_name, retval);
+		hc_died (hcd);
+// FIXME:  recover, reset etc.
+	} else {
+		// FIXME for all connected devices, root-to-leaf:
+		// driver->resume ();
+		// proposed "new 2.5 driver model" will automate that
+	}
+
+done:
+	atomic_dec (&hcd->resume_count);
+	return retval;
+}
+EXPORT_SYMBOL (usb_hcd_pci_resume);
+
+#endif	/* CONFIG_PM */
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Generic HC operations.
+ */
+
+/*-------------------------------------------------------------------------*/
+
+/* called from khubd, or root hub init threads for hcd-private init */
+static int hcd_alloc_dev (struct usb_device *udev)
+{
+	struct hcd_dev		*dev;
+	struct usb_hcd		*hcd;
+	unsigned long		flags;
+
+	if (!udev || udev->hcpriv)
+		return -EINVAL;
+	if (!udev->bus || !udev->bus->hcpriv)
+		return -ENODEV;
+	hcd = udev->bus->hcpriv;
+	if (hcd->state == USB_STATE_QUIESCING)
+		return -ENOLINK;
+
+	dev = (struct hcd_dev *) kmalloc (sizeof *dev, GFP_KERNEL);
+	if (dev == NULL)
+		return -ENOMEM;
+	memset (dev, 0, sizeof *dev);
+
+	INIT_LIST_HEAD (&dev->dev_list);
+	INIT_LIST_HEAD (&dev->urb_list);
+
+	spin_lock_irqsave (&hcd_data_lock, flags);
+	list_add (&dev->dev_list, &hcd->dev_list);
+	// refcount is implicit
+	udev->hcpriv = dev;
+	spin_unlock_irqrestore (&hcd_data_lock, flags);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void hc_died (struct usb_hcd *hcd)
+{
+	struct list_head	*devlist, *urblist;
+	struct hcd_dev		*dev;
+	struct urb		*urb;
+	unsigned long		flags;
+	
+	/* flag every pending urb as done */
+	spin_lock_irqsave (&hcd_data_lock, flags);
+	list_for_each (devlist, &hcd->dev_list) {
+		dev = list_entry (devlist, struct hcd_dev, dev_list);
+		list_for_each (urblist, &dev->urb_list) {
+			urb = list_entry (urblist, struct urb, urb_list);
+			dbg ("shutdown %s urb %p pipe %x, current status %d",
+				hcd->bus_name, urb, urb->pipe, urb->status);
+			if (urb->status == -EINPROGRESS)
+				urb->status = -ESHUTDOWN;
+		}
+	}
+	urb = (struct urb *) hcd->rh_timer.data;
+	if (urb)
+		urb->status = -ESHUTDOWN;
+	spin_unlock_irqrestore (&hcd_data_lock, flags);
+
+	if (urb)
+		rh_status_dequeue (hcd, urb);
+	hcd->driver->stop (hcd);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void urb_unlink (struct urb *urb)
+{
+	unsigned long		flags;
+	struct usb_device	*dev;
+
+	/* Release any periodic transfer bandwidth */
+	if (urb->bandwidth)
+		usb_release_bandwidth (urb->dev, urb,
+			usb_pipeisoc (urb->pipe));
+
+	/* clear all state linking urb to this dev (and hcd) */
+
+	spin_lock_irqsave (&hcd_data_lock, flags);
+	list_del_init (&urb->urb_list);
+	dev = urb->dev;
+	urb->dev = NULL;
+	usb_dec_dev_use (dev);
+	spin_unlock_irqrestore (&hcd_data_lock, flags);
+}
+
+
+/* may be called in any context with a valid urb->dev usecount */
+/* caller surrenders "ownership" of urb */
+
+static int hcd_submit_urb (struct urb *urb)
+{
+	int			status;
+	struct usb_hcd		*hcd;
+	struct hcd_dev		*dev;
+	unsigned long		flags;
+	int			pipe, temp, max;
+	int			mem_flags;
+
+	if (!urb || urb->hcpriv || !urb->complete)
+		return -EINVAL;
+
+	urb->status = -EINPROGRESS;
+	urb->actual_length = 0;
+	urb->bandwidth = 0;
+	INIT_LIST_HEAD (&urb->urb_list);
+
+	if (!urb->dev || !urb->dev->bus || urb->dev->devnum <= 0)
+		return -ENODEV;
+	hcd = urb->dev->bus->hcpriv;
+	dev = urb->dev->hcpriv;
+	if (!hcd || !dev)
+		return -ENODEV;
+
+	/* can't submit new urbs when quiescing, halted, ... */
+	if (hcd->state == USB_STATE_QUIESCING || !HCD_IS_RUNNING (hcd->state))
+		return -ESHUTDOWN;
+	pipe = urb->pipe;
+	temp = usb_pipetype (urb->pipe);
+	if (usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe),
+			usb_pipeout (pipe)))
+		return -EPIPE;
+
+	/* NOTE: 2.5 passes this value explicitly in submit() */
+	mem_flags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
+
+	/* FIXME there should be a sharable lock protecting us against
+	 * config/altsetting changes and disconnects, kicking in here.
+	 */
+
+	/* Sanity check, so HCDs can rely on clean data */
+	max = usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe));
+	if (max <= 0) {
+		err ("bogus endpoint (bad maxpacket)");
+		return -EINVAL;
+	}
+
+	/* "high bandwidth" mode, 1-3 packets/uframe? */
+	if (urb->dev->speed == USB_SPEED_HIGH) {
+		int	mult;
+		switch (temp) {
+		case PIPE_ISOCHRONOUS:
+		case PIPE_INTERRUPT:
+			mult = 1 + ((max >> 11) & 0x03);
+			max &= 0x03ff;
+			max *= mult;
+		}
+	}
+
+	/* periodic transfers limit size per frame/uframe */
+	switch (temp) {
+	case PIPE_ISOCHRONOUS: {
+		int	n, len;
+
+		if (urb->number_of_packets <= 0)		    
+			return -EINVAL;
+		for (n = 0; n < urb->number_of_packets; n++) {
+			len = urb->iso_frame_desc [n].length;
+			if (len < 0 || len > max) 
+				return -EINVAL;
+		}
+
+		}
+		break;
+	case PIPE_INTERRUPT:
+		if (urb->transfer_buffer_length > max)
+			return -EINVAL;
+	}
+
+	/* the I/O buffer must usually be mapped/unmapped */
+	if (urb->transfer_buffer_length < 0)
+		return -EINVAL;
+
+	if (urb->next) {
+		warn ("use explicit queuing not urb->next");
+		return -EINVAL;
+	}
+
+#ifdef DEBUG
+	/* stuff that drivers shouldn't do, but which shouldn't
+	 * cause problems in HCDs if they get it wrong.
+	 */
+	{
+	unsigned int	orig_flags = urb->transfer_flags;
+	unsigned int	allowed;
+
+	/* enforce simple/standard policy */
+	allowed = USB_ASYNC_UNLINK;	// affects later unlinks
+	allowed |= USB_NO_FSBR;		// only affects UHCI
+	switch (temp) {
+	case PIPE_CONTROL:
+		allowed |= USB_DISABLE_SPD;
+		break;
+	case PIPE_BULK:
+		allowed |= USB_DISABLE_SPD | USB_QUEUE_BULK
+				| USB_ZERO_PACKET | URB_NO_INTERRUPT;
+		break;
+	case PIPE_INTERRUPT:
+		allowed |= USB_DISABLE_SPD;
+		break;
+	case PIPE_ISOCHRONOUS:
+		allowed |= USB_ISO_ASAP;
+		break;
+	}
+	urb->transfer_flags &= allowed;
+
+	/* fail if submitter gave bogus flags */
+	if (urb->transfer_flags != orig_flags) {
+		err ("BOGUS urb flags, %x --> %x",
+			orig_flags, urb->transfer_flags);
+		return -EINVAL;
+	}
+	}
+#endif
+	/*
+	 * Force periodic transfer intervals to be legal values that are
+	 * a power of two (so HCDs don't need to).
+	 *
+	 * FIXME want bus->{intr,iso}_sched_horizon values here.  Each HC
+	 * supports different values... this uses EHCI/UHCI defaults (and
+	 * EHCI can use smaller non-default values).
+	 */
+	switch (temp) {
+	case PIPE_ISOCHRONOUS:
+	case PIPE_INTERRUPT:
+		/* too small? */
+		if (urb->interval <= 0)
+			return -EINVAL;
+		/* too big? */
+		switch (urb->dev->speed) {
+		case USB_SPEED_HIGH:	/* units are microframes */
+			// NOTE usb handles 2^15
+			if (urb->interval > (1024 * 8))
+				urb->interval = 1024 * 8;
+			temp = 1024 * 8;
+			break;
+		case USB_SPEED_FULL:	/* units are frames/msec */
+		case USB_SPEED_LOW:
+			if (temp == PIPE_INTERRUPT) {
+				if (urb->interval > 255)
+					return -EINVAL;
+				// NOTE ohci only handles up to 32
+				temp = 128;
+			} else {
+				if (urb->interval > 1024)
+					urb->interval = 1024;
+				// NOTE usb and ohci handle up to 2^15
+				temp = 1024;
+			}
+			break;
+		default:
+			return -EINVAL;
+		}
+		/* power of two? */
+		while (temp > urb->interval)
+			temp >>= 1;
+		urb->interval = temp;
+	}
+
+
+	/*
+	 * FIXME:  make urb timeouts be generic, keeping the HCD cores
+	 * as simple as possible.
+	 */
+
+	// NOTE:  a generic device/urb monitoring hook would go here.
+	// hcd_monitor_hook(MONITOR_URB_SUBMIT, urb)
+	// It would catch submission paths for all urbs.
+
+	/*
+	 * Atomically queue the urb,  first to our records, then to the HCD.
+	 * Access to urb->status is controlled by urb->lock ... changes on
+	 * i/o completion (normal or fault) or unlinking.
+	 */
+
+	// FIXME:  verify that quiescing hc works right (RH cleans up)
+
+	spin_lock_irqsave (&hcd_data_lock, flags);
+	if (HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_QUIESCING) {
+		usb_inc_dev_use (urb->dev);
+		list_add (&urb->urb_list, &dev->urb_list);
+		status = 0;
+	} else {
+		INIT_LIST_HEAD (&urb->urb_list);
+		status = -ESHUTDOWN;
+	}
+	spin_unlock_irqrestore (&hcd_data_lock, flags);
+	if (status)
+		return status;
+
+	if (urb->dev == hcd->bus->root_hub)
+		status = rh_urb_enqueue (hcd, urb);
+	else
+		status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
+	/* urb->dev got nulled if hcd called giveback for us
+	 * NOTE: ref to urb->dev is a race without (2.5) refcounting,
+	 * unless driver only returns status when it didn't giveback 
+	 */
+	if (status && urb->dev)
+		urb_unlink (urb);
+	return status;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* called in any context */
+static int hcd_get_frame_number (struct usb_device *udev)
+{
+	struct usb_hcd	*hcd = (struct usb_hcd *)udev->bus->hcpriv;
+	return hcd->driver->get_frame_number (hcd);
+}
+
+/*-------------------------------------------------------------------------*/
+
+struct completion_splice {		// modified urb context:
+	/* did we complete? */
+	struct completion	done;
+
+	/* original urb data */
+	void			(*complete)(struct urb *);
+	void			*context;
+};
+
+static void unlink_complete (struct urb *urb)
+{
+	struct completion_splice	*splice;
+
+	splice = (struct completion_splice *) urb->context;
+
+	/* issue original completion call */
+	urb->complete = splice->complete;
+	urb->context = splice->context;
+	urb->complete (urb);
+
+	/* then let the synchronous unlink call complete */
+	complete (&splice->done);
+}
+
+/*
+ * called in any context; note ASYNC_UNLINK restrictions
+ *
+ * caller guarantees urb won't be recycled till both unlink()
+ * and the urb's completion function return
+ */
+static int hcd_unlink_urb (struct urb *urb)
+{
+	struct hcd_dev			*dev;
+	struct usb_hcd			*hcd = 0;
+	unsigned long			flags;
+	struct completion_splice	splice;
+	int				retval;
+
+	if (!urb)
+		return -EINVAL;
+
+	/*
+	 * we contend for urb->status with the hcd core,
+	 * which changes it while returning the urb.
+	 *
+	 * Caller guaranteed that the urb pointer hasn't been freed, and
+	 * that it was submitted.  But as a rule it can't know whether or
+	 * not it's already been unlinked ... so we respect the reversed
+	 * lock sequence needed for the usb_hcd_giveback_urb() code paths
+	 * (urb lock, then hcd_data_lock) in case some other CPU is now
+	 * unlinking it.
+	 */
+	spin_lock_irqsave (&urb->lock, flags);
+	spin_lock (&hcd_data_lock);
+	if (!urb->hcpriv || urb->transfer_flags & USB_TIMEOUT_KILLED) {
+		retval = -EINVAL;
+		goto done;
+	}
+
+	if (!urb->dev || !urb->dev->bus) {
+		retval = -ENODEV;
+		goto done;
+	}
+
+	/* giveback clears dev; non-null means it's linked at this level */
+	dev = urb->dev->hcpriv;
+	hcd = urb->dev->bus->hcpriv;
+	if (!dev || !hcd) {
+		retval = -ENODEV;
+		goto done;
+	}
+
+	/* For non-periodic transfers, any status except -EINPROGRESS means
+	 * the HCD has already started to unlink this URB from the hardware.
+	 * In that case, there's no more work to do.
+	 *
+	 * For periodic transfers, this is the only way to trigger unlinking
+	 * from the hardware.  Since we (currently) overload urb->status to
+	 * tell the driver to unlink, error status might get clobbered ...
+	 * unless that transfer hasn't yet restarted.  One such case is when
+	 * the URB gets unlinked from its completion handler.
+	 *
+	 * FIXME use an URB_UNLINKED flag to match URB_TIMEOUT_KILLED
+	 */
+	switch (usb_pipetype (urb->pipe)) {
+	case PIPE_CONTROL:
+	case PIPE_BULK:
+		if (urb->status != -EINPROGRESS) {
+			retval = -EINVAL;
+			goto done;
+		}
+	}
+
+	/* maybe set up to block on completion notification */
+	if ((urb->transfer_flags & USB_TIMEOUT_KILLED))
+		urb->status = -ETIMEDOUT;
+	else if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) {
+		if (in_interrupt ()) {
+			dbg ("non-async unlink in_interrupt");
+			retval = -EWOULDBLOCK;
+			goto done;
+		}
+		/* synchronous unlink: block till we see the completion */
+		init_completion (&splice.done);
+		splice.complete = urb->complete;
+		splice.context = urb->context;
+		urb->complete = unlink_complete;
+		urb->context = &splice;
+		urb->status = -ENOENT;
+	} else {
+		/* asynchronous unlink */
+		urb->status = -ECONNRESET;
+	}
+	spin_unlock (&hcd_data_lock);
+	spin_unlock_irqrestore (&urb->lock, flags);
+
+	if (urb == (struct urb *) hcd->rh_timer.data) {
+		rh_status_dequeue (hcd, urb);
+		retval = 0;
+	} else {
+		retval = hcd->driver->urb_dequeue (hcd, urb);
+// FIXME:  if retval and we tried to splice, whoa!!
+if (retval && urb->status == -ENOENT) err ("whoa! retval %d", retval);
+	}
+
+    	/* block till giveback, if needed */
+	if (!(urb->transfer_flags & (USB_ASYNC_UNLINK|USB_TIMEOUT_KILLED))
+			&& HCD_IS_RUNNING (hcd->state)
+			&& !retval) {
+		dbg ("%s: wait for giveback urb %p",
+			hcd->bus_name, urb);
+		wait_for_completion (&splice.done);
+	} else if ((urb->transfer_flags & USB_ASYNC_UNLINK) && retval == 0) {
+		return -EINPROGRESS;
+	}
+	goto bye;
+done:
+	spin_unlock (&hcd_data_lock);
+	spin_unlock_irqrestore (&urb->lock, flags);
+bye:
+	if (retval)
+		dbg ("%s: hcd_unlink_urb fail %d",
+		    hcd ? hcd->bus_name : "(no bus?)",
+		    retval);
+	return retval;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* called by khubd, rmmod, apmd, or other thread for hcd-private cleanup */
+
+// FIXME:  likely best to have explicit per-setting (config+alt)
+// setup primitives in the usbcore-to-hcd driver API, so nothing
+// is implicit.  kernel 2.5 needs a bunch of config cleanup...
+
+static int hcd_free_dev (struct usb_device *udev)
+{
+	struct hcd_dev		*dev;
+	struct usb_hcd		*hcd;
+	unsigned long		flags;
+
+	if (!udev || !udev->hcpriv)
+		return -EINVAL;
+
+	if (!udev->bus || !udev->bus->hcpriv)
+		return -ENODEV;
+
+	// should udev->devnum == -1 ??
+
+	dev = udev->hcpriv;
+	hcd = udev->bus->hcpriv;
+
+	/* device driver problem with refcounts? */
+	if (!list_empty (&dev->urb_list)) {
+		dbg ("free busy dev, %s devnum %d (bug!)",
+			hcd->bus_name, udev->devnum);
+		return -EINVAL;
+	}
+
+	hcd->driver->free_config (hcd, udev);
+
+	spin_lock_irqsave (&hcd_data_lock, flags);
+	list_del (&dev->dev_list);
+	udev->hcpriv = NULL;
+	spin_unlock_irqrestore (&hcd_data_lock, flags);
+
+	kfree (dev);
+	return 0;
+}
+
+static struct usb_operations hcd_operations = {
+	allocate:		hcd_alloc_dev,
+	get_frame_number:	hcd_get_frame_number,
+	submit_urb:		hcd_submit_urb,
+	unlink_urb:		hcd_unlink_urb,
+	deallocate:		hcd_free_dev,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static void hcd_irq (int irq, void *__hcd, struct pt_regs * r)
+{
+	struct usb_hcd		*hcd = __hcd;
+	int			start = hcd->state;
+
+	if (unlikely (hcd->state == USB_STATE_HALT))	/* irq sharing? */
+		return;
+
+	hcd->driver->irq (hcd);
+	if (hcd->state != start && hcd->state == USB_STATE_HALT)
+		hc_died (hcd);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_hcd_giveback_urb - return URB from HCD to device driver
+ * @hcd: host controller returning the URB
+ * @urb: urb being returned to the USB device driver.
+ * Context: in_interrupt()
+ *
+ * This hands the URB from HCD to its USB device driver, using its
+ * completion function.  The HCD has freed all per-urb resources
+ * (and is done using urb->hcpriv).  It also released all HCD locks;
+ * the device driver won't cause deadlocks if it resubmits this URB,
+ * and won't confuse things by modifying and resubmitting this one.
+ * Bandwidth and other resources will be deallocated.
+ *
+ * HCDs must not use this for periodic URBs that are still scheduled
+ * and will be reissued.  They should just call their completion handlers
+ * until the urb is returned to the device driver by unlinking.
+ *
+ * NOTE that no urb->next processing is done, even for isochronous URBs.
+ * ISO streaming functionality can be achieved by having completion handlers
+ * re-queue URBs.  Such explicit queuing doesn't discard error reports.
+ */
+void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb)
+{
+	urb_unlink (urb);
+
+	// NOTE:  a generic device/urb monitoring hook would go here.
+	// hcd_monitor_hook(MONITOR_URB_FINISH, urb, dev)
+	// It would catch exit/unlink paths for all urbs, but non-exit
+	// completions for periodic urbs need hooks inside the HCD.
+	// hcd_monitor_hook(MONITOR_URB_UPDATE, urb, dev)
+
+	if (urb->status)
+		dbg ("giveback urb %p status %d len %d",
+			urb, urb->status, urb->actual_length);
+
+	/* pass ownership to the completion handler */
+	urb->complete (urb);
+}
+EXPORT_SYMBOL (usb_hcd_giveback_urb);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hcd.h linux/drivers/usb/hcd.h
--- linux.orig/drivers/usb/hcd.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/hcd.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2001 by David Brownell
+ * 
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * USB Host Controller Driver (usb_hcd) framework
+ *
+ * Since "struct usb_bus" is so thin, you can't share much code in it.
+ * This framework is a layer over that, and should be more sharable.
+ */
+
+/*-------------------------------------------------------------------------*/
+
+struct usb_hcd {	/* usb_bus.hcpriv points to this */
+
+	/*
+	 * housekeeping
+	 */
+	struct usb_bus		*bus;		/* hcd is-a bus */
+	struct list_head	hcd_list;
+
+	const char		*bus_name;
+	const char		*product_desc;
+	const char		*description;	/* "ehci-hcd" etc */
+
+	struct timer_list	rh_timer;	/* drives root hub */
+	struct list_head	dev_list;	/* devices on this bus */
+
+	/*
+	 * hardware info/state
+	 */
+	struct hc_driver	*driver;	/* hw-specific hooks */
+	int			irq;		/* irq allocated */
+	void			*regs;		/* device memory/io */
+
+#ifdef	CONFIG_PCI
+	/* a few non-PCI controllers exist, mostly for OHCI */
+	struct pci_dev		*pdev;		/* pci is typical */
+	int			region;		/* pci region for regs */
+	u32			pci_state [16];	/* for PM state save */
+	atomic_t		resume_count;	/* multiple resumes issue */
+#endif
+
+	int			state;
+#	define	__ACTIVE		0x01
+#	define	__SLEEPY		0x02
+#	define	__SUSPEND		0x04
+#	define	__TRANSIENT		0x80
+
+#	define	USB_STATE_HALT		0
+#	define	USB_STATE_RUNNING	(__ACTIVE)
+#	define	USB_STATE_READY		(__ACTIVE|__SLEEPY)
+#	define	USB_STATE_QUIESCING	(__SUSPEND|__TRANSIENT|__ACTIVE)
+#	define	USB_STATE_RESUMING	(__SUSPEND|__TRANSIENT)
+#	define	USB_STATE_SUSPENDED	(__SUSPEND)
+
+#define	HCD_IS_RUNNING(state) ((state) & __ACTIVE)
+#define	HCD_IS_SUSPENDED(state) ((state) & __SUSPEND)
+
+	/* more shared queuing code would be good; it should support
+	 * smarter scheduling, handle transaction translators, etc;
+	 * input size of periodic table to an interrupt scheduler. 
+	 * (ohci 32, uhci 1024, ehci 256/512/1024).
+	 */
+};
+
+struct hcd_dev {	/* usb_device.hcpriv points to this */
+	struct list_head	dev_list;	/* on this hcd */
+	struct list_head	urb_list;	/* pending on this dev */
+
+	/* per-configuration HC/HCD state, such as QH or ED */
+	void			*ep[32];
+};
+
+// urb.hcpriv is really hardware-specific
+
+struct hcd_timeout {	/* timeouts we allocate */
+	struct list_head	timeout_list;
+	struct timer_list	timer;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* each driver provides one of these, and hardware init support */
+
+struct hc_driver {
+	const char	*description;	/* "ehci-hcd" etc */
+
+	/* irq handler */
+	void	(*irq) (struct usb_hcd *hcd);
+
+	int	flags;
+#define	HCD_MEMORY	0x0001		/* HC regs use memory (else I/O) */
+#define	HCD_USB11	0x0010		/* USB 1.1 */
+#define	HCD_USB2	0x0020		/* USB 2.0 */
+
+	/* called to init HCD and root hub */
+	int	(*start) (struct usb_hcd *hcd);
+
+	/* called after all devices were suspended */
+	int	(*suspend) (struct usb_hcd *hcd, u32 state);
+
+	/* called before any devices get resumed */
+	int	(*resume) (struct usb_hcd *hcd);
+
+	/* cleanly make HCD stop writing memory and doing I/O */
+	void	(*stop) (struct usb_hcd *hcd);
+
+	/* return current frame number */
+	int	(*get_frame_number) (struct usb_hcd *hcd);
+
+// FIXME: rework generic-to-specific HCD linkage (specific contains generic)
+
+	/* memory lifecycle */
+	struct usb_hcd	*(*hcd_alloc) (void);
+	void		(*hcd_free) (struct usb_hcd *hcd);
+
+	/* manage i/o requests, device state */
+	int	(*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
+					int mem_flags);
+	int	(*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
+
+	// frees configuration resources -- allocated as needed during
+	// urb_enqueue, and not freed by urb_dequeue
+	void		(*free_config) (struct usb_hcd *hcd,
+				struct usb_device *dev);
+
+	/* root hub support */
+	int		(*hub_status_data) (struct usb_hcd *hcd, char *buf);
+	int		(*hub_control) (struct usb_hcd *hcd,
+				u16 typeReq, u16 wValue, u16 wIndex,
+				char *buf, u16 wLength);
+};
+
+extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb);
+
+#ifdef CONFIG_PCI
+
+extern int usb_hcd_pci_probe (struct pci_dev *dev,
+				const struct pci_device_id *id);
+extern void usb_hcd_pci_remove (struct pci_dev *dev);
+
+#ifdef CONFIG_PM
+// FIXME:  see Documentation/power/pci.txt (2.4.6 and later?)
+// extern int usb_hcd_pci_save_state (struct pci_dev *dev, u32 state);
+extern int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state);
+extern int usb_hcd_pci_resume (struct pci_dev *dev);
+// extern int usb_hcd_pci_enable_wake (struct pci_dev *dev, u32 state, int flg);
+#endif /* CONFIG_PM */
+
+#endif /* CONFIG_PCI */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * HCD Root Hub support
+ */
+
+#include "hub.h"
+
+/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
+#define DeviceRequest \
+	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
+#define DeviceOutRequest \
+	((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
+
+#define InterfaceRequest \
+	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+
+#define EndpointRequest \
+	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+#define EndpointOutRequest \
+	((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+
+/* table 9.6 standard features */
+#define DEVICE_REMOTE_WAKEUP	1
+#define ENDPOINT_HALT		0
+
+/* class requests from the USB 2.0 hub spec, table 11-15 */
+/* GetBusState and SetHubDescriptor are optional, omitted */
+#define ClearHubFeature		(0x2000 | USB_REQ_CLEAR_FEATURE)
+#define ClearPortFeature	(0x2300 | USB_REQ_CLEAR_FEATURE)
+#define GetHubDescriptor	(0xa000 | USB_REQ_GET_DESCRIPTOR)
+#define GetHubStatus		(0xa000 | USB_REQ_GET_STATUS)
+#define GetPortStatus		(0xa300 | USB_REQ_GET_STATUS)
+#define SetHubFeature		(0x2000 | USB_REQ_SET_FEATURE)
+#define SetPortFeature		(0x2300 | USB_REQ_SET_FEATURE)
+
+
+/*-------------------------------------------------------------------------*/
+
+/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
+// bleech -- resurfaced in 2.4.11 or 2.4.12
+#define bitmap 	DeviceRemovable
+
+
+/*-------------------------------------------------------------------------*/
+
+/* random stuff */
+
+#define	RUN_CONTEXT (in_irq () ? "in_irq" \
+		: (in_interrupt () ? "in_interrupt" : "can sleep"))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hid-core.c linux/drivers/usb/hid-core.c
--- linux.orig/drivers/usb/hid-core.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/usb/hid-core.c	2002-07-20 01:08:38.000000000 +0000
@@ -47,15 +47,13 @@
 #include <linux/usb.h>
 
 #include "hid.h"
-#ifdef CONFIG_USB_HIDDEV
 #include <linux/hiddev.h>
-#endif
 
 /*
  * Version Information
  */
 
-#define DRIVER_VERSION "v1.8"
+#define DRIVER_VERSION "v1.8.1"
 #define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik <vojtech@suse.cz>"
 #define DRIVER_DESC "USB HID support drivers"
 
@@ -204,17 +202,13 @@
 		return -1;
 	}
 
-	if (HID_MAIN_ITEM_VARIABLE & ~flags) { /* ARRAY */
-		if (parser->global.logical_maximum <= parser->global.logical_minimum) {
-			dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
-			return -1;
-		}
-		usages = parser->local.usage_index;
-		/* Hint: we can assume usages < MAX_USAGE here */
-	} else { /* VARIABLE */
-		usages = parser->global.report_count;
+	if (parser->global.logical_maximum <= parser->global.logical_minimum) {
+		dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
+		return -1;
 	}
 
+	usages = parser->local.usage_index;
+
 	offset = report->size;
 	report->size += parser->global.report_size * parser->global.report_count;
 
@@ -310,7 +304,10 @@
 			return 0;
 
 		case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
-			parser->global.logical_maximum = item_sdata(item);
+			if (parser->global.logical_minimum < 0)
+				parser->global.logical_maximum = item_sdata(item);
+			else
+				parser->global.logical_maximum = item_udata(item);
 			return 0;
 
 		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
@@ -318,7 +315,10 @@
 			return 0;
 
 		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
-			parser->global.physical_maximum = item_sdata(item);
+			if (parser->global.physical_minimum < 0)
+				parser->global.physical_maximum = item_sdata(item);
+			else
+				parser->global.physical_maximum = item_udata(item);
 			return 0;
 
 		case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
@@ -735,10 +735,8 @@
 	hid_dump_input(usage, value);
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_hid_event(hid, field, usage, value);
-#ifdef CONFIG_USB_HIDDEV
 	if (hid->claimed & HID_CLAIMED_HIDDEV)
 		hiddev_hid_event(hid, usage->hid, value);
-#endif
 }
 
 
@@ -897,6 +895,9 @@
 	u8 data[len];
 	int read;
 
+	if (hid->quirks & HID_QUIRK_NOGET)
+		return;
+
 	if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) {
 		dbg("reading report type %d id %d failed len %d read %d", report->type + 1, report->id, len, read);
 		return;
@@ -1073,19 +1074,47 @@
 }
 
 #define USB_VENDOR_ID_WACOM		0x056a
+#define USB_DEVICE_ID_WACOM_PENPARTNER	0x0000
 #define USB_DEVICE_ID_WACOM_GRAPHIRE	0x0010
 #define USB_DEVICE_ID_WACOM_INTUOS	0x0020
+#define USB_DEVICE_ID_WACOM_PL		0x0030
+#define USB_DEVICE_ID_WACOM_INTUOS2	0x0041
+
+#define USB_VENDOR_ID_ATEN		0x0557
+#define USB_DEVICE_ID_ATEN_UC100KM	0x2004
+#define USB_DEVICE_ID_ATEN_CS124U	0x2202
+#define USB_DEVICE_ID_ATEN_2PORTKVM	0x2204
+#define USB_DEVICE_ID_ATEN_4PORTKVM	0x2205
 
 struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
+	unsigned quirks;
 } hid_blacklist[] = {
-	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE },
-	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS },
-	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1},
-	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2},
-	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3},
-	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4},
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 2, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 1, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 2, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
 	{ 0, 0 }
 };
 
@@ -1094,13 +1123,17 @@
 	struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
 	struct hid_descriptor *hdesc;
 	struct hid_device *hid;
-	unsigned rsize = 0;
+	unsigned quirks = 0, rsize = 0;
 	char *buf;
 	int n;
 
 	for (n = 0; hid_blacklist[n].idVendor; n++)
 		if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) &&
-			(hid_blacklist[n].idProduct == dev->descriptor.idProduct)) return NULL;
+			(hid_blacklist[n].idProduct == dev->descriptor.idProduct))
+				quirks = hid_blacklist[n].quirks;
+
+	if (quirks & HID_QUIRK_IGNORE)
+		return NULL;
 
 	if (usb_get_extra_descriptor(interface, USB_DT_HID, &hdesc) && ((!interface->bNumEndpoints) ||
 		usb_get_extra_descriptor(&interface->endpoint[0], USB_DT_HID, &hdesc))) {
@@ -1138,6 +1171,8 @@
 		}
 	}
 
+	hid->quirks = quirks;
+
 	for (n = 0; n < interface->bNumEndpoints; n++) {
 
 		struct usb_endpoint_descriptor *endpoint = &interface->endpoint[n];
@@ -1221,10 +1256,8 @@
 
 	if (!hidinput_connect(hid))
 		hid->claimed |= HID_CLAIMED_INPUT;
-#ifdef CONFIG_USB_HIDDEV
 	if (!hiddev_connect(hid))
 		hid->claimed |= HID_CLAIMED_HIDDEV;
-#endif
 	printk(KERN_INFO);
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
@@ -1254,13 +1287,10 @@
 
 	dbg("cleanup called");
 	usb_unlink_urb(&hid->urb);
-
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_disconnect(hid);
-#ifdef CONFIG_USB_HIDDEV
 	if (hid->claimed & HID_CLAIMED_HIDDEV)
 		hiddev_disconnect(hid);
-#endif
 	hid_free_device(hid);
 }
 
@@ -1281,9 +1311,7 @@
 
 static int __init hid_init(void)
 {
-#ifdef CONFIG_USB_HIDDEV
 	hiddev_init();
-#endif
 	usb_register(&hid_driver);
 	info(DRIVER_VERSION " " DRIVER_AUTHOR);
 	info(DRIVER_DESC);
@@ -1293,9 +1321,7 @@
 
 static void __exit hid_exit(void)
 {
-#ifdef CONFIG_USB_HIDDEV
 	hiddev_exit();
-#endif
 	usb_deregister(&hid_driver);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hid.h linux/drivers/usb/hid.h
--- linux.orig/drivers/usb/hid.h	2001-11-14 01:45:27.000000000 +0000
+++ linux/drivers/usb/hid.h	2002-07-20 01:08:21.000000000 +0000
@@ -184,6 +184,8 @@
 
 #define HID_QUIRK_INVERT	0x01
 #define HID_QUIRK_NOTOUCH	0x02
+#define HID_QUIRK_IGNORE	0x04
+#define HID_QUIRK_NOGET		0x08
 
 /*
  * This is the global enviroment of the parser. This information is
@@ -350,9 +352,6 @@
 	struct hid_class_descriptor desc[1];
 } __attribute__ ((packed));
 
-void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
-int hidinput_connect(struct hid_device *);
-void hidinput_disconnect(struct hid_device *);
 
 #ifdef DEBUG
 #include "hid-debug.h"
@@ -363,7 +362,17 @@
 
 #endif
 
+#ifdef CONFIG_USB_HIDINPUT
 #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || ( a == 0x000c0001))
+extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
+extern int hidinput_connect(struct hid_device *);
+extern void hidinput_disconnect(struct hid_device *);
+#else
+#define IS_INPUT_APPLICATION(a) (0)
+static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { }
+static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; }
+static inline void hidinput_disconnect(struct hid_device *hid) { }
+#endif
 
 int hid_open(struct hid_device *);
 void hid_close(struct hid_device *);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hpusbscsi.c linux/drivers/usb/hpusbscsi.c
--- linux.orig/drivers/usb/hpusbscsi.c	2001-10-09 22:15:02.000000000 +0000
+++ linux/drivers/usb/hpusbscsi.c	2002-07-20 01:08:40.000000000 +0000
@@ -120,6 +120,9 @@
 	if (scsi_register_module (MODULE_SCSI_HA, &(new->ctempl)))
 		goto err_out;
 
+	new->sense_command[0] = REQUEST_SENSE;
+	new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH;
+
 	/* adding to list for module unload */
 	list_add (&hpusbscsi_devices, &new->lh);
 
@@ -141,6 +144,7 @@
 	{USB_DEVICE (0x03f0, 0x0701)},	/* HP 53xx */
 	{USB_DEVICE (0x03f0, 0x0801)},	/* HP 7400 */
 	{USB_DEVICE (0x0638, 0x026a)},	/*Scan Dual II */
+	{USB_DEVICE (0x0686, 0x4004)},  /*Minolta Elite II */
 	{}			/* Terminating entry */
 };
 
@@ -163,7 +167,6 @@
 	int result;
 
 	INIT_LIST_HEAD (&hpusbscsi_devices);
-	DEBUG ("Driver loaded\n");
 
 	if ((result = usb_register (&hpusbscsi_usb_driver)) < 0) {
 		printk (KERN_ERR "hpusbscsi: driver registration failed\n");
@@ -185,7 +188,8 @@
 		tmp = tmp->next;
 		o = (struct hpusbscsi *)old;
 		usb_unlink_urb(&o->controlurb);
-		scsi_unregister_module(MODULE_SCSI_HA,&o->ctempl);
+		if(scsi_unregister_module(MODULE_SCSI_HA,&o->ctempl)<0)
+			printk(KERN_CRIT"Deregistering failed!\n");
 		kfree(old);
 	}
 
@@ -270,7 +274,13 @@
 	/* Now we need to decide which callback to give to the urb we send the command with */
 
 	if (!srb->bufflen) {
-		usb_callback = simple_command_callback;
+		if (srb->cmnd[0] == REQUEST_SENSE){
+			/* the usual buffer is not used, needs a special case */
+			hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in);
+			usb_callback = request_sense_callback;
+		} else {
+			usb_callback = simple_command_callback;
+		}
 	} else {
         	if (srb->use_sg) {
 			usb_callback = scatter_gather_callback;
@@ -332,8 +342,8 @@
 	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
 
 	printk(KERN_DEBUG"SCSI reset requested.\n");
-	usb_reset_device(hpusbscsi->dev);
-	printk(KERN_DEBUG"SCSI reset completed.\n");
+	//usb_reset_device(hpusbscsi->dev);
+	//printk(KERN_DEBUG"SCSI reset completed.\n");
 	hpusbscsi->state = HP_STATE_FREE;
 
 	return 0;
@@ -342,10 +352,9 @@
 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb)
 {
 	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
-	printk(KERN_DEBUG"Requested is canceled.\n");
+	printk(KERN_DEBUG"Request is canceled.\n");
 
 	usb_unlink_urb(&hpusbscsi->dataurb);
-	usb_unlink_urb(&hpusbscsi->controlurb);
 	hpusbscsi->state = HP_STATE_FREE;
 
 	return SCSI_ABORT_PENDING;
@@ -365,6 +374,7 @@
 static void  control_interrupt_callback (struct urb *u)
 {
 	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+	u8 scsi_state;
 
 DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte);
 	if(u->status < 0) {
@@ -372,10 +382,23 @@
                         handle_usb_error(hpusbscsi);
 		return;
 	}
-	hpusbscsi->srb->result &= SCSI_ERR_MASK;
-	hpusbscsi->srb->result |= hpusbscsi->scsi_state_byte<<1;
 
-	if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT)
+	scsi_state = hpusbscsi->scsi_state_byte;
+        if (hpusbscsi->state != HP_STATE_ERROR) {
+                hpusbscsi->srb->result &= SCSI_ERR_MASK;
+                hpusbscsi->srb->result |= scsi_state;
+        }
+
+	if (scsi_state == CHECK_CONDITION << 1) {
+		if (hpusbscsi->state == HP_STATE_WAIT) {
+			issue_request_sense(hpusbscsi);
+		} else {
+			/* we request sense after an eventual data transfer */
+			hpusbscsi->state = HP_STATE_ERROR;
+		}
+	}
+
+	if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT && scsi_state != CHECK_CONDITION <<1)
 		/* we do a callback to the scsi layer if and only if all data has been transfered */
 		hpusbscsi->scallback(hpusbscsi->srb);
 
@@ -390,6 +413,8 @@
 		hpusbscsi->state = HP_STATE_PREMATURE;
 	TRACE_STATE;
 		break;
+	case HP_STATE_ERROR:
+		break;
 	default:
 		printk(KERN_ERR"hpusbscsi: Unexpected status report.\n");
 	TRACE_STATE;
@@ -453,7 +478,7 @@
 
         res = usb_submit_urb(u);
         if (res)
-                hpusbscsi->state = HP_STATE_ERROR;
+        	handle_usb_error(hpusbscsi);
 	TRACE_STATE;
 }
 
@@ -468,11 +493,16 @@
         DEBUG("Data transfer done\n");
 	TRACE_STATE;
 	if (hpusbscsi->state != HP_STATE_PREMATURE) {
-		if (u->status < 0)
-			hpusbscsi->state = HP_STATE_ERROR;
-		else
-			hpusbscsi->state = HP_STATE_WAIT;
+		if (u->status < 0) {
+			handle_usb_error(hpusbscsi);
+		} else {
+			if (hpusbscsi->state != HP_STATE_ERROR) {
+				hpusbscsi->state = HP_STATE_WAIT;
+			} else {
+				issue_request_sense(hpusbscsi);
+			}
 		TRACE_STATE;
+		}
 	} else {
 		if (hpusbscsi->scallback != NULL)
 			hpusbscsi->scallback(hpusbscsi->srb);
@@ -509,11 +539,52 @@
 	if (hpusbscsi->state != HP_STATE_PREMATURE) {
 		hpusbscsi->state = HP_STATE_WORKING;
 	TRACE_STATE;
-	} else {
-		if (hpusbscsi->scallback != NULL)
-			hpusbscsi->scallback(hpusbscsi->srb);
-		hpusbscsi->state = HP_STATE_FREE;
-	TRACE_STATE;
+	}
+}
+
+static void request_sense_callback (struct urb *u)
+{
+	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+
+	if (u->status<0) {
+                handle_usb_error(hpusbscsi);
+		return;
+        }
+
+	FILL_BULK_URB(
+		u,
+		hpusbscsi->dev,
+		hpusbscsi->current_data_pipe,
+		hpusbscsi->srb->sense_buffer,
+		SCSI_SENSE_BUFFERSIZE,
+		simple_done,
+		hpusbscsi
+	);
+
+	if (0 > usb_submit_urb(u)) {
+		handle_usb_error(hpusbscsi);
+		return;
+	}
+	if (hpusbscsi->state != HP_STATE_PREMATURE && hpusbscsi->state != HP_STATE_ERROR)
+		hpusbscsi->state = HP_STATE_WORKING;
+}
+
+static void issue_request_sense (struct hpusbscsi *hpusbscsi)
+{
+	FILL_BULK_URB(
+		&hpusbscsi->dataurb,
+		hpusbscsi->dev,
+		usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out),
+		&hpusbscsi->sense_command,
+		SENSE_COMMAND_SIZE,
+		request_sense_callback,
+		hpusbscsi
+	);
+
+	hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in);
+
+	if (0 > usb_submit_urb(&hpusbscsi->dataurb)) {
+		handle_usb_error(hpusbscsi);
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hpusbscsi.h linux/drivers/usb/hpusbscsi.h
--- linux.orig/drivers/usb/hpusbscsi.h	2001-10-05 19:04:51.000000000 +0000
+++ linux/drivers/usb/hpusbscsi.h	2002-07-20 01:08:25.000000000 +0000
@@ -4,9 +4,14 @@
 /* large parts based on or taken from code by John Fremlin and Matt Dharm */
 /* this file is licensed under the GPL */
 
+/* A big thanks to Jose for untiring testing */
+
 typedef void (*usb_urb_callback) (struct urb *);
 typedef void (*scsi_callback)(Scsi_Cmnd *);
 
+#define SENSE_COMMAND_SIZE 6
+#define HPUSBSCSI_SENSE_LENGTH 0x16
+
 struct hpusbscsi
 {
         struct list_head lh;
@@ -21,6 +26,7 @@
         int number;
        scsi_callback scallback;
        Scsi_Cmnd *srb;
+	u8 sense_command[SENSE_COMMAND_SIZE];
 
         int use_count;
         wait_queue_head_t pending;
@@ -51,11 +57,13 @@
 static void simple_command_callback(struct urb *u);
 static void scatter_gather_callback(struct urb *u);
 static void simple_payload_callback (struct urb *u);
-static void  control_interrupt_callback (struct urb *u);
+static void control_interrupt_callback (struct urb *u);
+static void request_sense_callback (struct urb *u);
 static void simple_done (struct urb *u);
 static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback);
 static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb);
 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
+static void issue_request_sense (struct hpusbscsi *hpusbscsi);
 
 static Scsi_Host_Template hpusbscsi_scsi_host_template = {
 	name:           "hpusbscsi",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hub.c linux/drivers/usb/hub.c
--- linux.orig/drivers/usb/hub.c	2001-11-12 17:34:16.000000000 +0000
+++ linux/drivers/usb/hub.c	2002-07-20 01:08:36.000000000 +0000
@@ -217,9 +217,12 @@
 			break;
 		case 1:
 			dbg("Single TT");
+			hub->tt.hub = dev;
 			break;
 		case 2:
-			dbg("Multiple TT");
+			dbg("TT per port");
+			hub->tt.hub = dev;
+			hub->tt.multi = 1;
 			break;
 		default:
 			dbg("Unrecognized hub protocol %d",
@@ -496,6 +499,29 @@
 	err("cannot disconnect hub %d", dev->devnum);
 }
 
+static int usb_hub_port_status(struct usb_device *hub, int port,
+			       u16 *status, u16 *change)
+{
+	struct usb_port_status *portsts;
+	int ret = -ENOMEM;
+
+	portsts = kmalloc(sizeof(*portsts), GFP_KERNEL);
+	if (portsts) {
+		ret = usb_get_port_status(hub, port + 1, portsts);
+		if (ret < 0)
+			err("%s (%d) failed (err = %d)", __FUNCTION__, hub->devnum, ret);
+		else {
+			*status = le16_to_cpu(portsts->wPortStatus);
+			*change = le16_to_cpu(portsts->wPortChange); 
+			dbg("port %d, portstatus %x, change %x, %s", port + 1,
+				*status, *change, portspeed(*status));
+			ret = 0;
+		}
+		kfree(portsts);
+	}
+	return ret;
+}
+
 #define HUB_RESET_TRIES		5
 #define HUB_PROBE_TRIES		2
 #define HUB_SHORT_RESET_TIME	10
@@ -507,24 +533,22 @@
 				struct usb_device *dev, unsigned int delay)
 {
 	int delay_time, ret;
-	struct usb_port_status portsts;
-	unsigned short portchange, portstatus;
+	u16 portstatus;
+	u16 portchange;
 
 	for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT; delay_time += delay) {
 		/* wait to give the device a chance to reset */
 		wait_ms(delay);
 
 		/* read and decode port status */
-		ret = usb_get_port_status(hub, port + 1, &portsts);
+		ret = usb_hub_port_status(hub, port, &portstatus, &portchange);
 		if (ret < 0) {
-			err("get_port_status(%d) failed (err = %d)", port + 1, ret);
 			return -1;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
-		dbg("port %d, portstatus %x, change %x, %s", port + 1,
-			portstatus, portchange, portspeed (portstatus));
+		/* Device went away? */
+		if (!(portstatus & USB_PORT_STAT_CONNECTION))
+			return 1;
 
 		/* bomb out completely if something weird happened */
 		if ((portchange & USB_PORT_STAT_C_CONNECTION))
@@ -592,17 +616,58 @@
 			port + 1, hub->devnum, ret);
 }
 
-static void usb_hub_port_connect_change(struct usb_device *hub, int port,
-					struct usb_port_status *portsts)
+/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
+ *
+ * Between connect detection and reset signaling there must be a delay
+ * of 100ms at least for debounce and power-settling. The corresponding
+ * timer shall restart whenever the downstream port detects a disconnect.
+ * 
+ * Apparently there are some bluetooth and irda-dongles and a number
+ * of low-speed devices which require longer delays of about 200-400ms.
+ * Not covered by the spec - but easy to deal with.
+ *
+ * This implementation uses 400ms minimum debounce timeout and checks
+ * every 100ms for transient disconnects to restart the delay.
+ */
+
+#define HUB_DEBOUNCE_TIMEOUT	400
+#define HUB_DEBOUNCE_STEP	100
+
+/* return: -1 on error, 0 on success, 1 on disconnect.  */
+static int usb_hub_port_debounce(struct usb_device *hub, int port)
 {
+	int ret;
+	unsigned delay_time;
+	u16 portchange, portstatus;
+
+	for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; /* empty */ ) {
+
+		/* wait debounce step increment */
+		wait_ms(HUB_DEBOUNCE_STEP);
+
+		ret = usb_hub_port_status(hub, port, &portstatus, &portchange);
+		if (ret < 0)
+			return -1;
+
+		if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
+			usb_clear_port_feature(hub, port+1, USB_PORT_FEAT_C_CONNECTION);
+			delay_time = 0;
+		}
+		else
+			delay_time += HUB_DEBOUNCE_STEP;
+	}
+	return ((portstatus&USB_PORT_STAT_CONNECTION)) ? 0 : 1;
+}
+
+static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
+					u16 portstatus, u16 portchange)
+{
+	struct usb_device *hub = hubstate->dev;
 	struct usb_device *dev;
-	unsigned short portstatus, portchange;
 	unsigned int delay = HUB_SHORT_RESET_TIME;
 	int i;
 	char *portstr, *tempstr;
 
-	portstatus = le16_to_cpu(portsts->wPortStatus);
-	portchange = le16_to_cpu(portsts->wPortChange);
 	dbg("port %d, portstatus %x, change %x, %s",
 		port + 1, portstatus, portchange, portspeed (portstatus));
 
@@ -621,11 +686,10 @@
 		return;
 	}
 
-	/* Some low speed devices have problems with the quick delay, so */
-	/*  be a bit pessimistic with those devices. RHbug #23670 */
-	if (portstatus & USB_PORT_STAT_LOW_SPEED) {
-		wait_ms(400);
-		delay = HUB_LONG_RESET_TIME;
+	if (usb_hub_port_debounce(hub, port)) {
+		err("connect-debounce failed, port %d disabled", port+1);
+		usb_hub_port_disable(hub, port);
+		return;
 	}
 
 	down(&usb_address0_sem);
@@ -654,6 +718,16 @@
 		/* Find a new device ID for it */
 		usb_connect(dev);
 
+		/* Set up TT records, if needed  */
+		if (hub->tt) {
+			dev->tt = hub->tt;
+			dev->ttport = hub->ttport;
+		} else if (dev->speed != USB_SPEED_HIGH
+				&& hub->speed == USB_SPEED_HIGH) {
+			dev->tt = &hubstate->tt;
+			dev->ttport = port + 1;
+		}
+
 		/* Create a readable topology string */
 		cdev = dev;
 		pdev = dev->parent;
@@ -709,7 +783,10 @@
 	struct usb_device *dev;
 	struct usb_hub *hub;
 	struct usb_hub_status hubsts;
-	unsigned short hubstatus, hubchange;
+	u16 hubstatus;
+	u16 hubchange;
+	u16 portstatus;
+	u16 portchange;
 	int i, ret;
 
 	/*
@@ -751,22 +828,15 @@
 		}
 
 		for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
-			struct usb_port_status portsts;
-			unsigned short portstatus, portchange;
-
-			ret = usb_get_port_status(dev, i + 1, &portsts);
+			ret = usb_hub_port_status(dev, i, &portstatus, &portchange);
 			if (ret < 0) {
-				err("get_port_status failed (err = %d)", ret);
 				continue;
 			}
 
-			portstatus = le16_to_cpu(portsts.wPortStatus);
-			portchange = le16_to_cpu(portsts.wPortChange);
-
 			if (portchange & USB_PORT_STAT_C_CONNECTION) {
 				dbg("port %d connection change", i + 1);
 
-				usb_hub_port_connect_change(dev, i, &portsts);
+				usb_hub_port_connect_change(hub, i, portstatus, portchange);
 			} else if (portchange & USB_PORT_STAT_C_ENABLE) {
 				dbg("port %d enable change, status %x", i + 1, portstatus);
 				usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE);
@@ -780,7 +850,7 @@
 				    (portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) {
 					err("already running port %i disabled by hub (EMI?), re-enabling...",
 						i + 1);
-					usb_hub_port_connect_change(dev, i, &portsts);
+					usb_hub_port_connect_change(hub, i, portstatus, portchange);
 				}
 			}
 
@@ -834,6 +904,7 @@
 	 */
 
 	daemonize();
+	reparent_to_init();
 
 	/* Setup a nice name */
 	strcpy(current->comm, "khubd");
@@ -841,7 +912,7 @@
 	/* Send me a signal to get me die (for debugging) */
 	do {
 		usb_hub_events();
-		interruptible_sleep_on(&khubd_wait);
+		wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
 	} while (!signal_pending(current));
 
 	dbg("usb_hub_thread exiting");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/hub.h linux/drivers/usb/hub.h
--- linux.orig/drivers/usb/hub.h	2001-11-22 19:49:52.000000000 +0000
+++ linux/drivers/usb/hub.h	2002-07-20 01:08:25.000000000 +0000
@@ -2,6 +2,7 @@
 #define __LINUX_HUB_H
 
 #include <linux/list.h>
+#include <linux/compiler.h>	/* likely()/unlikely() */
 
 /*
  * Hub request types
@@ -136,6 +137,7 @@
 	struct usb_hub_descriptor *descriptor;
 
 	struct semaphore khubd_sem;
+	struct usb_tt		tt;		/* Transaction Translator */
 };
 
 #endif /* __LINUX_HUB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/ibmcam.c linux/drivers/usb/ibmcam.c
--- linux.orig/drivers/usb/ibmcam.c	2001-10-05 19:04:51.000000000 +0000
+++ linux/drivers/usb/ibmcam.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,7 +1,8 @@
 /*
  * USB IBM C-It Video Camera driver
  *
- * Supports IBM C-It Video Camera.
+ * Supports Xirlink C-It Video Camera, IBM PC Camera,
+ * IBM NetCamera and Veo Stingray.
  *
  * This driver is based on earlier work of:
  *
@@ -33,9 +34,11 @@
 
 #include "usbvideo.h"
 
-#define	IBMCAM_VENDOR_ID	0x0545
-#define	IBMCAM_PRODUCT_ID	0x8080
+#define IBMCAM_VENDOR_ID	0x0545
+#define IBMCAM_PRODUCT_ID	0x8080
 #define NETCAM_PRODUCT_ID	0x8002	/* IBM NetCamera, close to model 2 */
+#define VEO_800C_PRODUCT_ID	0x800C	/* Veo Stingray, repackaged Model 2 */
+#define VEO_800D_PRODUCT_ID	0x800D	/* Veo Stingray, repackaged Model 4 */
 
 #define MAX_IBMCAM		4	/* How many devices we allow to connect */
 #define USES_IBMCAM_PUTPIXEL    0       /* 0=Fast/oops 1=Slow/secure */
@@ -3671,6 +3674,8 @@
 	if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID)
 		return NULL;
 	if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) &&
+	    (dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) &&
+	    (dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) &&
 	    (dev->descriptor.idProduct != NETCAM_PRODUCT_ID))
 		return NULL;
 
@@ -3684,7 +3689,8 @@
 	case 0x030A:
 		if (ifnum != 0)
 			return NULL;
-		if (dev->descriptor.idProduct == NETCAM_PRODUCT_ID)
+		if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) ||
+		    (dev->descriptor.idProduct == VEO_800D_PRODUCT_ID))
 			model = IBMCAM_MODEL_4;
 		else
 			model = IBMCAM_MODEL_2;
@@ -3699,8 +3705,28 @@
 			dev->descriptor.bcdDevice);
 		return NULL;
 	}
-	info("IBM USB camera found (model %d, rev. 0x%04x)",
-		model, dev->descriptor.bcdDevice);
+
+	/* Print detailed info on what we found so far */
+	do {
+		char *brand = NULL;
+		switch (dev->descriptor.idProduct) {
+		case NETCAM_PRODUCT_ID:
+			brand = "IBM NetCamera";
+			break;
+		case VEO_800C_PRODUCT_ID:
+			brand = "Veo Stingray [800C]";
+			break;
+		case VEO_800D_PRODUCT_ID:
+			brand = "Veo Stingray [800D]";
+			break;
+		case IBMCAM_PRODUCT_ID:
+		default:
+			brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */
+			break;
+		}
+		info("%s USB camera found (model %d, rev. 0x%04x)",
+		     brand, model, dev->descriptor.bcdDevice);
+	} while (0);
 
 	/* Validate found interface: must have one ISO endpoint */
 	nas = dev->actconfig->interface[ifnum].num_altsetting;
@@ -3908,18 +3934,16 @@
 	usbvideo_Deregister(&cams);
 }
 
-#if defined(usb_device_id_ver)
-
 static __devinitdata struct usb_device_id id_table[] = {
 	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) },	/* Model 1 */
 	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 2 */
 	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) },	/* Model 3 */
 	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 4 */
+	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 2 */
+	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 4 */
 	{ }  /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-#endif /* defined(usb_device_id_ver) */
-
 module_init(ibmcam_init);
 module_exit(ibmcam_cleanup);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/ibmcam.h linux/drivers/usb/ibmcam.h
--- linux.orig/drivers/usb/ibmcam.h	2000-12-11 21:17:55.000000000 +0000
+++ linux/drivers/usb/ibmcam.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,240 +0,0 @@
-/*
- * Header file for USB IBM C-It Video Camera driver.
- *
- * Supports IBM C-It Video Camera.
- *
- * This driver is based on earlier work of:
- *
- * (C) Copyright 1999 Johannes Erdfelt
- * (C) Copyright 1999 Randy Dunlap
- */
-
-#ifndef __LINUX_IBMCAM_H
-#define __LINUX_IBMCAM_H
-
-#include <linux/list.h>
-
-#define USES_IBMCAM_PUTPIXEL    0       /* 0=Fast/oops 1=Slow/secure */
-
-/* Video Size 384 x 288 x 3 bytes for RGB */
-/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */
-#define V4L_FRAME_WIDTH         384
-#define V4L_FRAME_WIDTH_USED	352
-#define V4L_FRAME_HEIGHT        288
-#define V4L_BYTES_PER_PIXEL     3
-#define MAX_FRAME_SIZE          (V4L_FRAME_WIDTH * V4L_FRAME_HEIGHT * V4L_BYTES_PER_PIXEL)
-
-/* Camera capabilities (maximum) */
-#define CAMERA_IMAGE_WIDTH      352
-#define CAMERA_IMAGE_HEIGHT     288
-#define CAMERA_IMAGE_LINE_SZ    ((CAMERA_IMAGE_WIDTH * 3) / 2) /* Bytes */
-#define CAMERA_URB_FRAMES       32
-#define CAMERA_MAX_ISO_PACKET   1023 /* 1022 actually sent by camera */
-
-#define IBMCAM_NUMFRAMES	2
-#define IBMCAM_NUMSBUF		2
-
-#define FRAMES_PER_DESC		(CAMERA_URB_FRAMES)
-#define FRAME_SIZE_PER_DESC	(CAMERA_MAX_ISO_PACKET)
-
-/* This macro restricts an int variable to an inclusive range */
-#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
-
-/*
- * This macro performs bounds checking - use it when working with
- * new formats, or else you may get oopses all over the place.
- * If pixel falls out of bounds then it gets shoved back (as close
- * to place of offence as possible) and is painted bright red.
- */
-#define IBMCAM_PUTPIXEL(fr, ix, iy, vr, vg, vb) { \
-	register unsigned char *pf; \
-	int limiter = 0, mx, my; \
-	mx = ix; \
-	my = iy; \
-	if (mx < 0) { \
-		mx=0; \
-		limiter++; \
-	} else if (mx >= 352) { \
-		mx=351; \
-		limiter++; \
-	} \
-	if (my < 0) { \
-		my = 0; \
-		limiter++; \
-	} else if (my >= V4L_FRAME_HEIGHT) { \
-		my = V4L_FRAME_HEIGHT - 1; \
-		limiter++; \
-	} \
-	pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*352 + (ix)); \
-	if (limiter) { \
-		*pf++ = 0; \
-		*pf++ = 0; \
-		*pf++ = 0xFF; \
-	} else { \
-		*pf++ = (vb); \
-		*pf++ = (vg); \
-		*pf++ = (vr); \
-	} \
-}
-
-/*
- * We use macros to do YUV -> RGB conversion because this is
- * very important for speed and totally unimportant for size.
- *
- * YUV -> RGB Conversion
- * ---------------------
- *
- * B = 1.164*(Y-16)		    + 2.018*(V-128)
- * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
- * R = 1.164*(Y-16) + 1.596*(U-128)
- *
- * If you fancy integer arithmetics (as you should), hear this:
- *
- * 65536*B = 76284*(Y-16)		  + 132252*(V-128)
- * 65536*G = 76284*(Y-16) -  53281*(U-128) -  25625*(V-128)
- * 65536*R = 76284*(Y-16) + 104595*(U-128)
- *
- * Make sure the output values are within [0..255] range.
- */
-#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
-#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
-    int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
-    mm_y = (my) - 16;  \
-    mm_u = (mu) - 128; \
-    mm_v = (mv) - 128; \
-    mm_yc= mm_y * 76284; \
-    mm_b = (mm_yc		+ 132252*mm_v	) >> 16; \
-    mm_g = (mm_yc -  53281*mm_u -  25625*mm_v	) >> 16; \
-    mm_r = (mm_yc + 104595*mm_u			) >> 16; \
-    mb = LIMIT_RGB(mm_b); \
-    mg = LIMIT_RGB(mm_g); \
-    mr = LIMIT_RGB(mm_r); \
-}
-
-/* Debugging aid */
-#define IBMCAM_SAY_AND_WAIT(what) { \
-	wait_queue_head_t wq; \
-	init_waitqueue_head(&wq); \
-	printk(KERN_INFO "Say: %s\n", what); \
-	interruptible_sleep_on_timeout (&wq, HZ*3); \
-}
-
-/*
- * This macro checks if ibmcam is still operational. The 'ibmcam'
- * pointer must be valid, ibmcam->dev must be valid, we are not
- * removing the device and the device has not erred on us.
- */
-#define IBMCAM_IS_OPERATIONAL(ibm_cam) (\
-	(ibm_cam != NULL) && \
-	((ibm_cam)->dev != NULL) && \
-	((ibm_cam)->last_error == 0) && \
-	(!(ibm_cam)->remove_pending))
-
-enum {
-	STATE_SCANNING,		/* Scanning for header */
-	STATE_LINES,		/* Parsing lines */
-};
-
-enum {
-	FRAME_UNUSED,		/* Unused (no MCAPTURE) */
-	FRAME_READY,		/* Ready to start grabbing */
-	FRAME_GRABBING,		/* In the process of being grabbed into */
-	FRAME_DONE,		/* Finished grabbing, but not been synced yet */
-	FRAME_ERROR,		/* Something bad happened while processing */
-};
-
-struct usb_device;
-
-struct ibmcam_sbuf {
-	char *data;
-	urb_t *urb;
-};
-
-struct ibmcam_frame {
-	char *data;		/* Frame buffer */
-	int order_uv;		/* True=UV False=VU */
-	int order_yc;		/* True=Yc False=cY ('c'=either U or V) */
-	unsigned char hdr_sig;	/* "00 FF 00 ??" where 'hdr_sig' is '??' */
-
-	int width;		/* Width application is expecting */
-	int height;		/* Height */
-
-	int frmwidth;		/* Width the frame actually is */
-	int frmheight;		/* Height */
-
-	volatile int grabstate;	/* State of grabbing */
-	int scanstate;		/* State of scanning */
-
-	int curline;		/* Line of frame we're working on */
-
-	long scanlength;	/* uncompressed, raw data length of frame */
-	long bytes_read;	/* amount of scanlength that has been read from *data */
-
-	wait_queue_head_t wq;	/* Processes waiting */
-};
-
-#define	IBMCAM_MODEL_1	1	/* XVP-501, 3 interfaces, rev. 0.02 */
-#define IBMCAM_MODEL_2	2	/* KSX-X9903, 2 interfaces, rev. 3.0a */
-
-struct usb_ibmcam {
-	struct video_device vdev;
-
-	/* Device structure */
-	struct usb_device *dev;
-
-	unsigned char iface;                            /* Video interface number */
-	unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */
-
-	struct semaphore lock;
-	int user;		/* user count for exclusive use */
-
-	int ibmcam_used;        /* Is this structure in use? */
-	int initialized;	/* Had we already sent init sequence? */
-	int camera_model;	/* What type of IBM camera we got? */
-	int streaming;		/* Are we streaming Isochronous? */
-	int grabbing;		/* Are we grabbing? */
-	int last_error;		/* What calamity struck us? */
-
-	int compress;		/* Should the next frame be compressed? */
-
-	char *fbuf;		/* Videodev buffer area */
-	int fbuf_size;		/* Videodev buffer size */
-
-	int curframe;
-	struct ibmcam_frame frame[IBMCAM_NUMFRAMES];	/* Double buffering */
-
-	int cursbuf;		/* Current receiving sbuf */
-	struct ibmcam_sbuf sbuf[IBMCAM_NUMSBUF];	/* Double buffering */
-	volatile int remove_pending;	/* If set then about to exit */
-
-        /*
-	 * Scratch space from the Isochronous pipe.
-	 * Scratch buffer should contain at least one pair of lines
-	 * (CAMERA_IMAGE_LINE_SZ). We set it to two pairs here.
-	 * This will be approximately 2 KB. HOWEVER in reality this
-	 * buffer must be as large as hundred of KB because otherwise
-	 * you'll get lots of overflows because V4L client may request
-	 * frames not as uniformly as USB sources them.
-	 */
-	unsigned char *scratch;
-	int scratchlen;
-
-	struct video_picture vpic, vpic_old;	/* Picture settings */
-	struct video_capability vcap;		/* Video capabilities */
-	struct video_channel vchan;	/* May be used for tuner support */
-	unsigned char video_endp;	/* 0x82 for IBM camera */
-        int has_hdr;
-        int frame_num;
-	int iso_packet_len;		/* Videomode-dependent, saves bus bandwidth */
-
-	/* Statistics that can be overlayed on screen */
-        unsigned long urb_count;        /* How many URBs we received so far */
-        unsigned long urb_length;       /* Length of last URB */
-        unsigned long data_count;       /* How many bytes we received */
-        unsigned long header_count;     /* How many frame headers we found */
-	unsigned long scratch_ovf_count;/* How many times we overflowed scratch */
-	unsigned long iso_skip_count;	/* How many empty ISO packets received */
-	unsigned long iso_err_count;	/* How many bad ISO packets received */
-};
-
-#endif /* __LINUX_IBMCAM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/inode.c linux/drivers/usb/inode.c
--- linux.orig/drivers/usb/inode.c	2001-10-21 02:13:11.000000000 +0000
+++ linux/drivers/usb/inode.c	2002-07-20 01:08:24.000000000 +0000
@@ -654,7 +654,13 @@
         return NULL;
 }
 
+/*
+ * The usbdevfs name is now deprecated (as of 2.4.19).
+ * It will be removed when the 2.7.x development cycle is started.
+ * You have been warned :)
+ */
 static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE);
+static DECLARE_FSTYPE(usbfs_type, "usbfs", usbdevfs_read_super, FS_SINGLE);
 
 /* --------------------------------------------------------------------- */
 
@@ -751,6 +757,11 @@
 		usb_deregister(&usbdevfs_driver);
 		return ret;
 	}
+	if ((ret = register_filesystem(&usbfs_type))) {
+		usb_deregister(&usbdevfs_driver);
+		unregister_filesystem(&usbdevice_fs_type);
+		return ret;
+	}
 #ifdef CONFIG_PROC_FS		
 	/* create mount point for usbdevfs */
 	usbdir = proc_mkdir("usb", proc_bus);
@@ -762,6 +773,7 @@
 {
 	usb_deregister(&usbdevfs_driver);
 	unregister_filesystem(&usbdevice_fs_type);
+	unregister_filesystem(&usbfs_type);
 #ifdef CONFIG_PROC_FS	
         if (usbdir)
                 remove_proc_entry("usb", proc_bus);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/kaweth.c linux/drivers/usb/kaweth.c
--- linux.orig/drivers/usb/kaweth.c	2001-11-13 17:19:41.000000000 +0000
+++ linux/drivers/usb/kaweth.c	2002-07-20 01:08:38.000000000 +0000
@@ -123,6 +123,7 @@
 	{ USB_DEVICE(0x0557, 0x2002) }, /* ATEN USB Ethernet */ 
 	{ USB_DEVICE(0x0557, 0x4000) }, /* D-Link DSB-650C */ 
 	{ USB_DEVICE(0x0565, 0x0002) }, /* Peracom Enet */
+	{ USB_DEVICE(0x0565, 0x0003) }, /* Optus@Home UEP1045A */
 	{ USB_DEVICE(0x0565, 0x0005) }, /* Peracom Enet2 */ 
 	{ USB_DEVICE(0x05e9, 0x0008) }, /* KLSI KL5KUSB101B */
 	{ USB_DEVICE(0x05e9, 0x0009) }, /* KLSI KL5KUSB101B (Board change) */
@@ -238,8 +239,7 @@
 		return -EBUSY;
 	}
 
-	dr = kmalloc(sizeof(devrequest), 
-                     in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+	dr = kmalloc(sizeof(devrequest), GFP_ATOMIC);
 
 	if(!dr)
 	{
@@ -587,14 +587,10 @@
 {
 	struct kaweth_device *kaweth = urb->context;
 
-	spin_lock(&kaweth->device_lock);
-
 	if (urb->status)
 		kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);
 
 	netif_wake_queue(kaweth->net);
-
-	spin_unlock(&kaweth->device_lock);
 }
 
 /****************************************************************
@@ -722,6 +718,7 @@
 	kaweth->stats.tx_errors++;
 	net->trans_start = jiffies;
 
+	kaweth->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;
 	usb_unlink_urb(kaweth->tx_urb);
 }
 
@@ -825,6 +822,7 @@
 
 		/* Device will now disappear for a moment...  */
 		kaweth_info("Firmware loaded.  I'll be back...");
+		kfree(kaweth);
 		return NULL;
 	}
 
@@ -927,6 +925,9 @@
 		return;
 	}
 
+	usb_unlink_urb(kaweth->rx_urb);
+	usb_unlink_urb(kaweth->tx_urb);
+
 	if(kaweth->net) {
 		if(kaweth->net->flags & IFF_UP) {
 			kaweth_dbg("Closing net device");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/ov511.c linux/drivers/usb/ov511.c
--- linux.orig/drivers/usb/ov511.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/ov511.c	2002-07-20 01:08:31.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * OmniVision OV511 Camera-to-USB Bridge Driver
  *
- * Copyright (c) 1999-2001 Mark W. McClelland
+ * Copyright (c) 1999-2002 Mark W. McClelland
  * Original decompression code Copyright 1998-2000 OmniVision Technologies
  * Many improvements by Bret Wallach <bwallac1@san.rr.com>
  * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
@@ -57,7 +57,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.48a for Linux 2.4"
+#define DRIVER_VERSION "v1.50 for Linux 2.4"
 #define EMAIL "mmcclell@bigfoot.com"
 #define DRIVER_AUTHOR "Mark McClelland <mmcclell@bigfoot.com> & Bret Wallach \
 	& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
@@ -308,7 +308,7 @@
 static inline int sensor_get_picture(struct usb_ov511 *, 
 				     struct video_picture *);
 static int sensor_get_exposure(struct usb_ov511 *, unsigned char *);
-static int ov511_control_ioctl(struct inode *, struct file *, unsigned int,
+static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int,
 			       unsigned long);
 
 /**********************************************************************
@@ -331,6 +331,7 @@
 	{ 100, "Lifeview RoboCam" },
 	{ 102, "AverMedia InterCam Elite" },
 	{ 112, "MediaForte MV300" },	/* or OV7110 evaluation kit */
+	{ 192, "Webeye 2000B" },
 	{  -1, NULL }
 };
 
@@ -493,7 +494,7 @@
 extern struct proc_dir_entry *video_proc_entry;
 
 static struct file_operations ov511_control_fops = {
-	ioctl:		ov511_control_ioctl,
+	ioctl:		ov51x_control_ioctl,
 };
 
 #define YES_NO(x) ((x) ? "yes" : "no")
@@ -505,29 +506,29 @@
 {
 	char *out = page;
 	int i, j, len;
-	struct usb_ov511 *ov511 = data;
+	struct usb_ov511 *ov = data;
 	struct video_picture p;
 	unsigned char exp;
 
-	if (!ov511 || !ov511->dev)
+	if (!ov || !ov->dev)
 		return -ENODEV;
 
-	sensor_get_picture(ov511, &p);
-	sensor_get_exposure(ov511, &exp);
+	sensor_get_picture(ov, &p);
+	sensor_get_exposure(ov, &exp);
 
 	/* IMPORTANT: This output MUST be kept under PAGE_SIZE
 	 *            or we need to get more sophisticated. */
 
 	out += sprintf(out, "driver_version  : %s\n", DRIVER_VERSION);
-	out += sprintf(out, "custom_id       : %d\n", ov511->customid);
-	out += sprintf(out, "model           : %s\n", ov511->desc ?
-		       clist[ov511->desc].description : "unknown");
-	out += sprintf(out, "streaming       : %s\n", YES_NO(ov511->streaming));
-	out += sprintf(out, "grabbing        : %s\n", YES_NO(ov511->grabbing));
-	out += sprintf(out, "compress        : %s\n", YES_NO(ov511->compress));
-	out += sprintf(out, "subcapture      : %s\n", YES_NO(ov511->sub_flag));
+	out += sprintf(out, "custom_id       : %d\n", ov->customid);
+	out += sprintf(out, "model           : %s\n", ov->desc ?
+		       clist[ov->desc].description : "unknown");
+	out += sprintf(out, "streaming       : %s\n", YES_NO(ov->streaming));
+	out += sprintf(out, "grabbing        : %s\n", YES_NO(ov->grabbing));
+	out += sprintf(out, "compress        : %s\n", YES_NO(ov->compress));
+	out += sprintf(out, "subcapture      : %s\n", YES_NO(ov->sub_flag));
 	out += sprintf(out, "sub_size        : %d %d %d %d\n",
-		       ov511->subx, ov511->suby, ov511->subw, ov511->subh);
+		       ov->subx, ov->suby, ov->subw, ov->subh);
 	out += sprintf(out, "data_format     : %s\n",
 		       force_rgb ? "RGB" : "BGR");
 	out += sprintf(out, "brightness      : %d\n", p.brightness >> 8);
@@ -539,12 +540,12 @@
 	for (i = 0; i < OV511_NUMFRAMES; i++) {
 		out += sprintf(out, "frame           : %d\n", i);
 		out += sprintf(out, "  depth         : %d\n",
-			       ov511->frame[i].depth);
+			       ov->frame[i].depth);
 		out += sprintf(out, "  size          : %d %d\n",
-			       ov511->frame[i].width, ov511->frame[i].height);
+			       ov->frame[i].width, ov->frame[i].height);
 		out += sprintf(out, "  format        : ");
 		for (j = 0; plist[j].num >= 0; j++) {
-			if (plist[j].num == ov511->frame[i].format) {
+			if (plist[j].num == ov->frame[i].format) {
 				out += sprintf(out, "%s\n", plist[j].name);
 				break;
 			}
@@ -552,29 +553,28 @@
 		if (plist[j].num < 0)
 			out += sprintf(out, "unknown\n");
 		out += sprintf(out, "  data_buffer   : 0x%p\n",
-			       ov511->frame[i].data);
+			       ov->frame[i].data);
 	}
-	out += sprintf(out, "snap_enabled    : %s\n",
-		       YES_NO(ov511->snap_enabled));
+	out += sprintf(out, "snap_enabled    : %s\n", YES_NO(ov->snap_enabled));
 	out += sprintf(out, "bridge          : %s\n",
-		       ov511->bridge == BRG_OV511 ? "OV511" :
-			ov511->bridge == BRG_OV511PLUS ? "OV511+" :
-			ov511->bridge == BRG_OV518 ? "OV518" :
-			ov511->bridge == BRG_OV518PLUS ? "OV518+" :
+		       ov->bridge == BRG_OV511 ? "OV511" :
+			ov->bridge == BRG_OV511PLUS ? "OV511+" :
+			ov->bridge == BRG_OV518 ? "OV518" :
+			ov->bridge == BRG_OV518PLUS ? "OV518+" :
 			"unknown");
 	out += sprintf(out, "sensor          : %s\n",
-		       ov511->sensor == SEN_OV6620 ? "OV6620" :
-			ov511->sensor == SEN_OV6630 ? "OV6630" :
-			ov511->sensor == SEN_OV7610 ? "OV7610" :
-			ov511->sensor == SEN_OV7620 ? "OV7620" :
-			ov511->sensor == SEN_OV7620AE ? "OV7620AE" :
-			ov511->sensor == SEN_OV8600 ? "OV8600" :
-			ov511->sensor == SEN_KS0127 ? "KS0127" :
-			ov511->sensor == SEN_KS0127B ? "KS0127B" :
-			ov511->sensor == SEN_SAA7111A ? "SAA7111A" :
+		       ov->sensor == SEN_OV6620 ? "OV6620" :
+			ov->sensor == SEN_OV6630 ? "OV6630" :
+			ov->sensor == SEN_OV7610 ? "OV7610" :
+			ov->sensor == SEN_OV7620 ? "OV7620" :
+			ov->sensor == SEN_OV7620AE ? "OV7620AE" :
+			ov->sensor == SEN_OV8600 ? "OV8600" :
+			ov->sensor == SEN_KS0127 ? "KS0127" :
+			ov->sensor == SEN_KS0127B ? "KS0127B" :
+			ov->sensor == SEN_SAA7111A ? "SAA7111A" :
 			"unknown");
-	out += sprintf(out, "packet_size     : %d\n", ov511->packet_size);
-	out += sprintf(out, "framebuffer     : 0x%p\n", ov511->fbuf);
+	out += sprintf(out, "packet_size     : %d\n", ov->packet_size);
+	out += sprintf(out, "framebuffer     : 0x%p\n", ov->fbuf);
 
 	len = out - page;
 	len -= off;
@@ -607,16 +607,16 @@
 {
 	char *out = page;
 	int len, status;
-	struct usb_ov511 *ov511 = data;
+	struct usb_ov511 *ov = data;
 
-	if (!ov511 || !ov511->dev)
+	if (!ov || !ov->dev)
 		return -ENODEV;
 
-	status = ov51x_check_snapshot(ov511);
+	status = ov51x_check_snapshot(ov);
 	out += sprintf(out, "%d", status);
 
 	if (status)
-		ov51x_clear_snapshot(ov511);
+		ov51x_clear_snapshot(ov);
 
 	len = out - page;
 	len -= off;
@@ -636,18 +636,19 @@
 static void 
 create_proc_ov511_cam(struct usb_ov511 *ov511)
 {
-	char dirname[4];
+	char dirname[10];
 
 	if (!ov511_proc_entry || !ov511)
 		return;
 
 	/* Create per-device directory */
-	sprintf(dirname, "%d", ov511->vdev.minor);
+	snprintf(dirname, 10, "%d", ov511->vdev.minor);
 	PDEBUG(4, "creating /proc/video/ov511/%s/", dirname);
 	ov511->proc_devdir = create_proc_entry(dirname, S_IFDIR,
 		ov511_proc_entry);
 	if (!ov511->proc_devdir)
 		return;
+	ov511->proc_devdir->owner = THIS_MODULE;
 
 	/* Create "info" entry (human readable device information) */
 	PDEBUG(4, "creating /proc/video/ov511/%s/info", dirname);
@@ -656,6 +657,7 @@
 		ov511_read_proc_info, ov511);
 	if (!ov511->proc_info)
 		return;
+	ov511->proc_info->owner = THIS_MODULE;
 
 	/* Don't create it if old snapshot mode on (would cause race cond.) */
 	if (!snapshot) {
@@ -667,6 +669,7 @@
 		if (!ov511->proc_button)
 			return;
 	}
+	ov511->proc_button->owner = THIS_MODULE;
 
 	/* Create "control" entry (ioctl() interface) */
 	PDEBUG(4, "creating /proc/video/ov511/%s/control", dirname);
@@ -677,6 +680,7 @@
 		unlock_kernel();
 		return;
 	}
+	ov511->proc_control->owner = THIS_MODULE;
 	ov511->proc_control->data = ov511;
 	ov511->proc_control->proc_fops = &ov511_control_fops;
 	unlock_kernel();
@@ -685,12 +689,12 @@
 static void 
 destroy_proc_ov511_cam(struct usb_ov511 *ov511)
 {
-	char dirname[4];
+	char dirname[10];
 	
 	if (!ov511 || !ov511->proc_devdir)
 		return;
 
-	sprintf(dirname, "%d", ov511->vdev.minor);
+	snprintf(dirname, 10, "%d", ov511->vdev.minor);
 
 	/* Destroy "control" entry */
 	if (ov511->proc_control) {
@@ -758,18 +762,22 @@
  *
  **********************************************************************/
 
+/* Write an OV51x register */
 static int 
-ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
+reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
 {
 	int rc;
 
 	PDEBUG(5, "0x%02X:0x%02X", reg, value);
 
-	rc = usb_control_msg(dev,
-			     usb_sndctrlpipe(dev, 0),
+	down(&ov->cbuf_lock);
+	ov->cbuf[0] = value;
+	rc = usb_control_msg(ov->dev,
+			     usb_sndctrlpipe(ov->dev, 0),
 			     2 /* REG_IO */,
 			     USB_TYPE_CLASS | USB_RECIP_DEVICE,
-			     0, (__u16)reg, &value, 1, HZ);	
+			     0, (__u16)reg, &ov->cbuf[0], 1, HZ);	
+	up(&ov->cbuf_lock);
 
 	if (rc < 0)
 		err("reg write: error %d", rc);
@@ -777,45 +785,48 @@
 	return rc;
 }
 
+/* Read from an OV51x register */
 /* returns: negative is error, pos or zero is data */
 static int 
-ov511_reg_read(struct usb_device *dev, unsigned char reg)
+reg_r(struct usb_ov511 *ov, unsigned char reg)
 {
 	int rc;
-	unsigned char buffer[1];
 
-	rc = usb_control_msg(dev,
-			     usb_rcvctrlpipe(dev, 0),
+	down(&ov->cbuf_lock);
+	rc = usb_control_msg(ov->dev,
+			     usb_rcvctrlpipe(ov->dev, 0),
 			     2 /* REG_IO */,
 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
-			     0, (__u16)reg, buffer, 1, HZ);
+			     0, (__u16)reg, &ov->cbuf[0], 1, HZ);
                                
-	PDEBUG(5, "0x%02X:0x%02X", reg, buffer[0]);
+	PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
 	
-	if (rc < 0) {
+	if (rc < 0)
 		err("reg read: error %d", rc);
-		return rc;
-	} else {
-		return buffer[0];	
-	}
+	else
+		rc = ov->cbuf[0];	
+
+	up(&ov->cbuf_lock);
+
+	return rc;
 }
 
 /*
- * Writes bits at positions specified by mask to a reg. Bits that are in
+ * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
  * the same position as 1's in "mask" are cleared and set to "value". Bits
  * that are in the same position as 0's in "mask" are preserved, regardless 
  * of their respective state in "value".
  */
 static int 
-ov511_reg_write_mask(struct usb_device *dev,
-		     unsigned char reg,
-		     unsigned char value,
-		     unsigned char mask)
+reg_w_mask(struct usb_ov511 *ov,
+	   unsigned char reg,
+	   unsigned char value,
+	   unsigned char mask)
 {
 	int ret;
 	unsigned char oldval, newval;
 
-	ret = ov511_reg_read(dev, reg);
+	ret = reg_r(ov, reg);
 	if (ret < 0)
 		return ret;
 
@@ -824,31 +835,30 @@
 	value &= mask;			/* Enforce mask on value */
 	newval = oldval | value;	/* Set the desired bits */
 
-	return (ov511_reg_write(dev, reg, newval));
+	return (reg_w(ov, reg, newval));
 }
 
-/* Writes multiple (n) values to a single register. Only valid with certain
- * registers (0x30 and 0xc4 - 0xce). Used for writing 16 and 24-bit values. */
+/* 
+ * Writes multiple (n) byte value to a single register. Only valid with certain
+ * registers (0x30 and 0xc4 - 0xce).
+ */
 static int 
-ov518_reg_write_multi(struct usb_device *dev,
-		      unsigned char reg,
-		      unsigned char *values,
-		      int n)
+ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
 {
 	int rc;
 
-	PDEBUG(5, "0x%02X:[multiple], n=%d", reg, n);  // FIXME
+	PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
 
-	if (values == NULL) {
-		err("reg write multiple: NULL buffer");
-		return -EINVAL;
-	}
+	down(&ov->cbuf_lock);
+
+	*((u32 *)ov->cbuf) = __cpu_to_le32(val);
 
-	rc = usb_control_msg(dev,
-			     usb_sndctrlpipe(dev, 0),
+	rc = usb_control_msg(ov->dev,
+			     usb_sndctrlpipe(ov->dev, 0),
 			     2 /* REG_IO */,
 			     USB_TYPE_CLASS | USB_RECIP_DEVICE,
-			     0, (__u16)reg, values, n, HZ);	
+			     0, (__u16)reg, ov->cbuf, n, HZ);
+	up(&ov->cbuf_lock);
 
 	if (rc < 0)
 		err("reg write multiple: error %d", rc);
@@ -857,12 +867,12 @@
 }
 
 static int 
-ov511_upload_quan_tables(struct usb_device *dev)
+ov511_upload_quan_tables(struct usb_ov511 *ov)
 {
 	unsigned char *pYTable = yQuanTable511;
 	unsigned char *pUVTable = uvQuanTable511;
 	unsigned char val0, val1;
-	int i, rc, reg = OV511_OMNICE_Y_LUT_BEGIN;
+	int i, rc, reg = R511_COMP_LUT_BEGIN;
 
 	PDEBUG(4, "Uploading quantization tables");
 
@@ -875,7 +885,7 @@
 			val0 &= 0x0f;
 			val1 &= 0x0f;
 			val0 |= val1 << 4;
-			rc = ov511_reg_write(dev, reg, val0);
+			rc = reg_w(ov, reg, val0);
 			if (rc < 0)
 				return rc;
 		}
@@ -887,8 +897,7 @@
 			val0 &= 0x0f;
 			val1 &= 0x0f;
 			val0 |= val1 << 4;
-			rc = ov511_reg_write(dev, reg + OV511_QUANTABLESIZE / 2,
-				val0);
+			rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0);
 			if (rc < 0)
 				return rc;
 		}
@@ -901,12 +910,12 @@
 
 /* OV518 quantization tables are 8x4 (instead of 8x8) */
 static int 
-ov518_upload_quan_tables(struct usb_device *dev)
+ov518_upload_quan_tables(struct usb_ov511 *ov)
 {
 	unsigned char *pYTable = yQuanTable518;
 	unsigned char *pUVTable = uvQuanTable518;
 	unsigned char val0, val1;
-	int i, rc, reg = OV511_OMNICE_Y_LUT_BEGIN;
+	int i, rc, reg = R511_COMP_LUT_BEGIN;
 
 	PDEBUG(4, "Uploading quantization tables");
 
@@ -919,7 +928,7 @@
 			val0 &= 0x0f;
 			val1 &= 0x0f;
 			val0 |= val1 << 4;
-			rc = ov511_reg_write(dev, reg, val0);
+			rc = reg_w(ov, reg, val0);
 			if (rc < 0)
 				return rc;
 		}
@@ -931,8 +940,7 @@
 			val0 &= 0x0f;
 			val1 &= 0x0f;
 			val0 |= val1 << 4;
-			rc = ov511_reg_write(dev, reg + OV518_QUANTABLESIZE / 2,
-				val0);
+			rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0);
 			if (rc < 0)
 				return rc;
 		}
@@ -943,13 +951,39 @@
 	return 0;
 }
 
+static int 
+ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type)
+{
+	int rc;
+		
+	/* Setting bit 0 not allowed on 518/518Plus */
+	if (ov->bclass == BCL_OV518)
+		reset_type &= 0xfe;
+
+	PDEBUG(4, "Reset: type=0x%X", reset_type);
+
+	rc = reg_w(ov, R51x_SYS_RESET, reset_type);
+	rc = reg_w(ov, R51x_SYS_RESET, 0);
+
+	if (rc < 0)
+		err("reset: command failed");
+
+	return rc;
+}
+
+/**********************************************************************
+ *
+ * I2C (sensor) I/O
+ *
+ **********************************************************************/
+
 /* NOTE: Do not call this function directly!
  * The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from ov51x_i2c_write(). Note that this function
+ * This is normally only called from i2c_w(). Note that this function
  * always succeeds regardless of whether the sensor is present and working.
  */
 static int 
-ov518_i2c_write_internal(struct usb_device *dev,
+ov518_i2c_write_internal(struct usb_ov511 *ov,
 			 unsigned char reg,
 			 unsigned char value)
 {
@@ -958,15 +992,15 @@
 	PDEBUG(5, "0x%02X:0x%02X", reg, value);
 
 	/* Select camera register */
-	rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE, reg);
+	rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
 	if (rc < 0) goto error;
 
 	/* Write "value" to I2C data port of OV511 */
-	rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);
+	rc = reg_w(ov, R51x_I2C_DATA, value);
 	if (rc < 0) goto error;
 
 	/* Initiate 3-byte write cycle */
-	rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x01);
+	rc = reg_w(ov, R518_I2C_CTL, 0x01);
 	if (rc < 0) goto error;
 
 	return 0;
@@ -978,7 +1012,7 @@
 
 /* NOTE: Do not call this function directly! */
 static int 
-ov511_i2c_write_internal(struct usb_device *dev,
+ov511_i2c_write_internal(struct usb_ov511 *ov,
 			 unsigned char reg,
 			 unsigned char value)
 {
@@ -989,19 +1023,18 @@
 	/* Three byte write cycle */
 	for (retries = OV511_I2C_RETRIES; ; ) {
 		/* Select camera register */
-		rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE,
-				     reg);
+		rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
 		if (rc < 0) goto error;
 
 		/* Write "value" to I2C data port of OV511 */
-		rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);	
+		rc = reg_w(ov, R51x_I2C_DATA, value);	
 		if (rc < 0) goto error;
 
 		/* Initiate 3-byte write cycle */
-		rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x01);
+		rc = reg_w(ov, R511_I2C_CTL, 0x01);
 		if (rc < 0) goto error;
 
-		do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+		do rc = reg_r(ov, R511_I2C_CTL);
 		while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
 		if (rc < 0) goto error;
 
@@ -1009,7 +1042,7 @@
 			break;
 #if 0
 		/* I2C abort */	
-		ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+		reg_w(ov, R511_I2C_CTL, 0x10);
 #endif
 		if (--retries < 0) {
 			err("i2c write retries exhausted");
@@ -1027,27 +1060,27 @@
 
 /* NOTE: Do not call this function directly!
  * The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from ov51x_i2c_read(). Note that this function
+ * This is normally only called from i2c_r(). Note that this function
  * always succeeds regardless of whether the sensor is present and working.
  */
 static int 
-ov518_i2c_read_internal(struct usb_device *dev, unsigned char reg)
+ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
 {
 	int rc, value;
 
 	/* Select camera register */
-	rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE, reg);
+	rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
 	if (rc < 0) goto error;
 
 	/* Initiate 2-byte write cycle */
-	rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x03);
+	rc = reg_w(ov, R518_I2C_CTL, 0x03);
 	if (rc < 0) goto error;
 
 	/* Initiate 2-byte read cycle */
-	rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x05);
+	rc = reg_w(ov, R518_I2C_CTL, 0x05);
 	if (rc < 0) goto error;
 
-	value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
+	value = reg_r(ov, R51x_I2C_DATA);
 
 	PDEBUG(5, "0x%02X:0x%02X", reg, value);
 
@@ -1061,22 +1094,21 @@
 /* NOTE: Do not call this function directly!
  * returns: negative is error, pos or zero is data */
 static int 
-ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
+ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
 {
 	int rc, value, retries;
 
 	/* Two byte write cycle */
 	for (retries = OV511_I2C_RETRIES; ; ) {
 		/* Select camera register */
-		rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE,
-				     reg);
+		rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
 		if (rc < 0) goto error;
 
 		/* Initiate 2-byte write cycle */
-		rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x03);
+		rc = reg_w(ov, R511_I2C_CTL, 0x03);
 		if (rc < 0) goto error;
 
-		do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+		do rc = reg_r(ov, R511_I2C_CTL);
 		while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
 		if (rc < 0) goto error;
 
@@ -1084,7 +1116,7 @@
 			break;
 
 		/* I2C abort */	
-		ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+		reg_w(ov, R511_I2C_CTL, 0x10);
 
 		if (--retries < 0) {
 			err("i2c write retries exhausted");
@@ -1096,10 +1128,10 @@
 	/* Two byte read cycle */
 	for (retries = OV511_I2C_RETRIES; ; ) {
 		/* Initiate 2-byte read cycle */
-		rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
+		rc = reg_w(ov, R511_I2C_CTL, 0x05);
 		if (rc < 0) goto error;
 
-		do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+		do rc = reg_r(ov, R511_I2C_CTL);
 		while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
 		if (rc < 0) goto error;
 
@@ -1107,7 +1139,7 @@
 			break;
 
 		/* I2C abort */	
-		rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+		rc = reg_w(ov, R511_I2C_CTL, 0x10);
 		if (rc < 0) goto error;
 
 		if (--retries < 0) {
@@ -1117,12 +1149,12 @@
 		}
 	}
 
-	value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
+	value = reg_r(ov, R51x_I2C_DATA);
 
 	PDEBUG(5, "0x%02X:0x%02X", reg, value);
 		
-	/* This is needed to make ov51x_i2c_write() work */
-	rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
+	/* This is needed to make i2c_w() work */
+	rc = reg_w(ov, R511_I2C_CTL, 0x05);
 	if (rc < 0)
 		goto error;
 	
@@ -1135,48 +1167,42 @@
 
 /* returns: negative is error, pos or zero is data */
 static int 
-ov51x_i2c_read(struct usb_ov511 *ov511, unsigned char reg)
+i2c_r(struct usb_ov511 *ov, unsigned char reg)
 {
 	int rc;
-	struct usb_device *dev = ov511->dev;
 
-	down(&ov511->i2c_lock);
+	down(&ov->i2c_lock);
 
-	if (dev->descriptor.idProduct == PROD_OV518 ||
-	    dev->descriptor.idProduct == PROD_OV518PLUS)
-		rc = ov518_i2c_read_internal(dev, reg);
+	if (ov->bclass == BCL_OV518)
+		rc = ov518_i2c_read_internal(ov, reg);
 	else
-		rc = ov511_i2c_read_internal(dev, reg);
+		rc = ov511_i2c_read_internal(ov, reg);
 
-	up(&ov511->i2c_lock);
+	up(&ov->i2c_lock);
 
 	return rc;
 }
 
 static int 
-ov51x_i2c_write(struct usb_ov511 *ov511,
-		unsigned char reg,
-		unsigned char value)
+i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
 {
 	int rc;
-	struct usb_device *dev = ov511->dev;
 
-	down(&ov511->i2c_lock);
+	down(&ov->i2c_lock);
 
-	if (dev->descriptor.idProduct == PROD_OV518 ||
-	    dev->descriptor.idProduct == PROD_OV518PLUS)
-		rc = ov518_i2c_write_internal(dev, reg, value);
+	if (ov->bclass == BCL_OV518)
+		rc = ov518_i2c_write_internal(ov, reg, value);
 	else
-		rc = ov511_i2c_write_internal(dev, reg, value);
+		rc = ov511_i2c_write_internal(ov, reg, value);
 
-	up(&ov511->i2c_lock);
+	up(&ov->i2c_lock);
 
 	return rc;
 }
 
 /* Do not call this function directly! */
 static int 
-ov51x_i2c_write_mask_internal(struct usb_device *dev,
+ov51x_i2c_write_mask_internal(struct usb_ov511 *ov,
 			      unsigned char reg,
 			      unsigned char value,
 			      unsigned char mask)
@@ -1187,11 +1213,10 @@
 	if (mask == 0xff) {
 		newval = value;
 	} else {
-		if (dev->descriptor.idProduct == PROD_OV518 ||
-		    dev->descriptor.idProduct == PROD_OV518PLUS)
-			rc = ov518_i2c_read_internal(dev, reg);
+		if (ov->bclass == BCL_OV518)
+			rc = ov518_i2c_read_internal(ov, reg);
 		else
-			rc = ov511_i2c_read_internal(dev, reg);
+			rc = ov511_i2c_read_internal(ov, reg);
 		if (rc < 0)
 			return rc;
 
@@ -1201,11 +1226,10 @@
 		newval = oldval | value;	/* Set the desired bits */
 	}
 
-	if (dev->descriptor.idProduct == PROD_OV518 ||
-	    dev->descriptor.idProduct == PROD_OV518PLUS)
-		return (ov518_i2c_write_internal(dev, reg, newval));
+	if (ov->bclass == BCL_OV518)
+		return (ov518_i2c_write_internal(ov, reg, newval));
 	else
-		return (ov511_i2c_write_internal(dev, reg, newval));
+		return (ov511_i2c_write_internal(ov, reg, newval));
 }
 
 /* Writes bits at positions specified by mask to an I2C reg. Bits that are in
@@ -1214,126 +1238,138 @@
  * of their respective state in "value".
  */
 static int 
-ov51x_i2c_write_mask(struct usb_ov511 *ov511,
-		     unsigned char reg,
-		     unsigned char value,
-		     unsigned char mask)
+i2c_w_mask(struct usb_ov511 *ov,
+	   unsigned char reg,
+	   unsigned char value,
+	   unsigned char mask)
 {
 	int rc;
-	struct usb_device *dev = ov511->dev;
 
-	down(&ov511->i2c_lock);
-	rc = ov51x_i2c_write_mask_internal(dev, reg, value, mask);
-	up(&ov511->i2c_lock);
+	down(&ov->i2c_lock);
+	rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
+	up(&ov->i2c_lock);
 
 	return rc;
 }
 
 /* Write to a specific I2C slave ID and register, using the specified mask */
 static int 
-ov51x_i2c_write_slave(struct usb_ov511 *ov511,
-		      unsigned char slave,
-		      unsigned char reg,
-		      unsigned char value,
-		      unsigned char mask)
+i2c_w_slave(struct usb_ov511 *ov,
+	    unsigned char slave,
+	    unsigned char reg,
+	    unsigned char value,
+	    unsigned char mask)
 {
 	int rc = 0;
-	struct usb_device *dev = ov511->dev;
 
-	down(&ov511->i2c_lock);
+	down(&ov->i2c_lock);
 
 	/* Set new slave IDs */
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+	if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
 		rc = -EIO;
 		goto out;
 	}
 
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+	if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
 		rc = -EIO;
 		goto out;
 	}
 
-	rc = ov51x_i2c_write_mask_internal(dev, reg, value, mask);
+	rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
 	/* Don't bail out yet if error; IDs must be restored */
 
 	/* Restore primary IDs */
-	slave = ov511->primary_i2c_slave;
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+	slave = ov->primary_i2c_slave;
+	if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
 		rc = -EIO;
 		goto out;
 	}
 
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+	if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
 		rc = -EIO;
 		goto out;
 	}
 
 out:
-	up(&ov511->i2c_lock);
+	up(&ov->i2c_lock);
 	return rc;
 }
 
 /* Read from a specific I2C slave ID and register */
 static int 
-ov51x_i2c_read_slave(struct usb_ov511 *ov511,
-		     unsigned char slave,
-		     unsigned char reg)
+i2c_r_slave(struct usb_ov511 *ov,
+	    unsigned char slave,
+	    unsigned char reg)
 {
 	int rc;
-	struct usb_device *dev = ov511->dev;
 
-	down(&ov511->i2c_lock);
+	down(&ov->i2c_lock);
 
 	/* Set new slave IDs */
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+	if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
 		rc = -EIO;
 		goto out;
 	}
 
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+	if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
 		rc = -EIO;
 		goto out;
 	}
 
-	if (dev->descriptor.idProduct == PROD_OV518 ||
-	    dev->descriptor.idProduct == PROD_OV518PLUS)
-		rc = ov518_i2c_read_internal(dev, reg);
+	if (ov->bclass == BCL_OV518)
+		rc = ov518_i2c_read_internal(ov, reg);
 	else
-		rc = ov511_i2c_read_internal(dev, reg);
+		rc = ov511_i2c_read_internal(ov, reg);
 	/* Don't bail out yet if error; IDs must be restored */
 
 	/* Restore primary IDs */
-	slave = ov511->primary_i2c_slave;
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+	slave = ov->primary_i2c_slave;
+	if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
 		rc = -EIO;
 		goto out;
 	}
 
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+	if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
 		rc = -EIO;
 		goto out;
 	}
 
 out:
-	up(&ov511->i2c_lock);
+	up(&ov->i2c_lock);
 	return rc;
 }
 
+/* Sets I2C read and write slave IDs. Returns <0 for error */
 static int 
-ov511_write_regvals(struct usb_ov511 *ov511,
-		    struct ov511_regvals * pRegvals)
+ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
+{
+	down(&ov->i2c_lock);
+
+	if (reg_w(ov, R51x_I2C_W_SID, sid) < 0)
+		return -EIO;
+
+	if (reg_w(ov, R51x_I2C_R_SID, sid + 1) < 0)
+		return -EIO;
+
+	if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
+		return -EIO;
+
+	up(&ov->i2c_lock);
+
+	return 0;
+}
+
+static int 
+write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
 {
 	int rc;
-	struct usb_device *dev = ov511->dev;
 
 	while (pRegvals->bus != OV511_DONE_BUS) {
 		if (pRegvals->bus == OV511_REG_BUS) {
-			if ((rc = ov511_reg_write(dev, pRegvals->reg,
-			                          pRegvals->val)) < 0)
+			if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0)
 				goto error;
 		} else if (pRegvals->bus == OV511_I2C_BUS) {
-			if ((rc = ov51x_i2c_write(ov511, pRegvals->reg, 
-			                          pRegvals->val)) < 0)
+			if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0)
 				goto error;
 		} else {
 			err("Bad regval array");
@@ -1351,57 +1387,60 @@
 
 #ifdef OV511_DEBUG 
 static void 
-ov511_dump_i2c_range(struct usb_ov511 *ov511, int reg1, int regn)
+dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn)
 {
 	int i;
 	int rc;
+
 	for (i = reg1; i <= regn; i++) {
-		rc = ov51x_i2c_read(ov511, i);
+		rc = i2c_r(ov, i);
 		info("OV7610[0x%X] = 0x%X", i, rc);
 	}
 }
 
 static void 
-ov51x_dump_i2c_regs(struct usb_ov511 *ov511)
+dump_i2c_regs(struct usb_ov511 *ov)
 {
 	info("I2C REGS");
-	ov511_dump_i2c_range(ov511, 0x00, 0x7C);
+	dump_i2c_range(ov, 0x00, 0x7C);
 }
 
 static void 
-ov511_dump_reg_range(struct usb_device *dev, int reg1, int regn)
+dump_reg_range(struct usb_ov511 *ov, int reg1, int regn)
 {
 	int i;
 	int rc;
+
 	for (i = reg1; i <= regn; i++) {
-	  rc = ov511_reg_read(dev, i);
-	  info("OV511[0x%X] = 0x%X", i, rc);
+		rc = reg_r(ov, i);
+		info("OV511[0x%X] = 0x%X", i, rc);
 	}
 }
 
+/* FIXME: Should there be an OV518 version of this? */
 static void 
-ov511_dump_regs(struct usb_device *dev)
+ov511_dump_regs(struct usb_ov511 *ov)
 {
 	info("CAMERA INTERFACE REGS");
-	ov511_dump_reg_range(dev, 0x10, 0x1f);
+	dump_reg_range(ov, 0x10, 0x1f);
 	info("DRAM INTERFACE REGS");
-	ov511_dump_reg_range(dev, 0x20, 0x23);
+	dump_reg_range(ov, 0x20, 0x23);
 	info("ISO FIFO REGS");
-	ov511_dump_reg_range(dev, 0x30, 0x31);
+	dump_reg_range(ov, 0x30, 0x31);
 	info("PIO REGS");
-	ov511_dump_reg_range(dev, 0x38, 0x39);
-	ov511_dump_reg_range(dev, 0x3e, 0x3e);
+	dump_reg_range(ov, 0x38, 0x39);
+	dump_reg_range(ov, 0x3e, 0x3e);
 	info("I2C REGS");
-	ov511_dump_reg_range(dev, 0x40, 0x49);
+	dump_reg_range(ov, 0x40, 0x49);
 	info("SYSTEM CONTROL REGS");
-	ov511_dump_reg_range(dev, 0x50, 0x55);
-	ov511_dump_reg_range(dev, 0x5e, 0x5f);
+	dump_reg_range(ov, 0x50, 0x55);
+	dump_reg_range(ov, 0x5e, 0x5f);
 	info("OmniCE REGS");
-	ov511_dump_reg_range(dev, 0x70, 0x79);
+	dump_reg_range(ov, 0x70, 0x79);
 	/* NOTE: Quantization tables are not readable. You will get the value
 	 * in reg. 0x79 for every table register */
-	ov511_dump_reg_range(dev, 0x80, 0x9f);
-	ov511_dump_reg_range(dev, 0xa0, 0xbf);
+	dump_reg_range(ov, 0x80, 0x9f);
+	dump_reg_range(ov, 0xa0, 0xbf);
 
 }
 #endif
@@ -1414,7 +1453,7 @@
 
 /* For as-yet unimplemented I2C interface */
 static void 
-call_i2c_clients(struct usb_ov511 *ov511, unsigned int cmd,
+call_i2c_clients(struct usb_ov511 *ov, unsigned int cmd,
 		 void *arg)
 {
 	/* Do nothing */
@@ -1422,59 +1461,33 @@
 
 /*****************************************************************************/
 
-static int 
-ov511_reset(struct usb_ov511 *ov511, unsigned char reset_type)
-{
-	int rc;
-		
-	/* Setting bit 0 not allowed on 518/518Plus */
-	if (ov511->bridge == BRG_OV518 ||
-	    ov511->bridge == BRG_OV518PLUS)
-		reset_type &= 0xfe;
-
-	PDEBUG(4, "Reset: type=0x%X", reset_type);
-
-	rc = ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, reset_type);
-	rc = ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, 0);
-
-	if (rc < 0)
-		err("reset: command failed");
-
-	return rc;
-}
-
 /* Temporarily stops OV511 from functioning. Must do this before changing
  * registers while the camera is streaming */
 static inline int 
-ov511_stop(struct usb_ov511 *ov511)
+ov51x_stop(struct usb_ov511 *ov)
 {
 	PDEBUG(4, "stopping");
-	ov511->stopped = 1;	
-	if (ov511->bridge == BRG_OV518 ||
-	    ov511->bridge == BRG_OV518PLUS)
-		return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
-					0x3a));
+	ov->stopped = 1;	
+	if (ov->bclass == BCL_OV518)
+		return (reg_w(ov, R51x_SYS_RESET, 0x3a));
 	else
-		return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
-					0x3d));
+		return (reg_w(ov, R51x_SYS_RESET, 0x3d));
 }
 
 /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
  * actually stopped (for performance). */
 static inline int 
-ov511_restart(struct usb_ov511 *ov511)
+ov51x_restart(struct usb_ov511 *ov)
 {
-	if (ov511->stopped) {
+	if (ov->stopped) {
 		PDEBUG(4, "restarting");
-		ov511->stopped = 0;	
+		ov->stopped = 0;	
 
 		/* Reinitialize the stream */
-		if (ov511->bridge == BRG_OV518 ||
-		    ov511->bridge == BRG_OV518PLUS)
-			ov511_reg_write(ov511->dev, 0x2f, 0x80);
+		if (ov->bclass == BCL_OV518)
+			reg_w(ov, 0x2f, 0x80);
 
-		return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
-					0x00));
+		return (reg_w(ov, R51x_SYS_RESET, 0x00));
 	}
 
 	return 0;
@@ -1482,14 +1495,13 @@
 
 /* Resets the hardware snapshot button */
 static void 
-ov51x_clear_snapshot(struct usb_ov511 *ov511)
+ov51x_clear_snapshot(struct usb_ov511 *ov)
 {
-	if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
-		ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
-		ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x03);
-		ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
-	} else if (ov511->bridge == BRG_OV518 ||
-		   ov511->bridge == BRG_OV518PLUS) {
+	if (ov->bclass == BCL_OV511) {
+		reg_w(ov, R51x_SYS_SNAP, 0x01);
+		reg_w(ov, R51x_SYS_SNAP, 0x03);
+		reg_w(ov, R51x_SYS_SNAP, 0x01);
+	} else if (ov->bclass == BCL_OV518) {
 		warn("snapshot reset not supported yet on OV518(+)");
 	} else {
 		err("clear snap: invalid bridge type");
@@ -1500,19 +1512,18 @@
 /* Checks the status of the snapshot button. Returns 1 if it was pressed since
  * it was last cleared, and zero in all other cases (including errors) */
 static int 
-ov51x_check_snapshot(struct usb_ov511 *ov511)
+ov51x_check_snapshot(struct usb_ov511 *ov)
 {
 	int ret, status = 0;
 
-	if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
-		ret = ov511_reg_read(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT);
+	if (ov->bclass == BCL_OV511) {
+		ret = reg_r(ov, R51x_SYS_SNAP);
 		if (ret < 0) {
 			err("Error checking snspshot status (%d)", ret);
 		} else if (ret & 0x08) {
 			status = 1;
 		}
-	} else if (ov511->bridge == BRG_OV518 ||
-		   ov511->bridge == BRG_OV518PLUS) {
+	} else if (ov->bclass == BCL_OV518) {
 		warn("snapshot check not supported yet on OV518(+)");
 	} else {
 		err("check snap: invalid bridge type");
@@ -1521,53 +1532,33 @@
 	return status;
 }
 
-/* Sets I2C read and write slave IDs. Returns <0 for error */
-static int 
-ov51x_set_slave_ids(struct usb_ov511 *ov511,
-		    unsigned char write_id,
-		    unsigned char read_id)
-{
-	struct usb_device *dev = ov511->dev;
-
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, write_id) < 0)
-		return -EIO;
-
-	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, read_id) < 0)
-		return -EIO;
-
-	if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
-		return -EIO;
-
-	return 0;
-}
-
 /* This does an initial reset of an OmniVision sensor and ensures that I2C
  * is synchronized. Returns <0 for failure.
  */
 static int 
-ov51x_init_ov_sensor(struct usb_ov511 *ov511)
+init_ov_sensor(struct usb_ov511 *ov)
 {
 	int i, success;
 
 	/* Reset the sensor */ 
-	if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -EIO;
+	if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
 
 	/* Wait for it to initialize */ 
 	schedule_timeout (1 + 150 * HZ / 1000);
 
 	for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
-		if ((ov51x_i2c_read(ov511, OV7610_REG_ID_HIGH) == 0x7F) &&
-		    (ov51x_i2c_read(ov511, OV7610_REG_ID_LOW) == 0xA2)) {
+		if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
+		    (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
 			success = 1;
 			continue;
 		}
 
 		/* Reset the sensor */ 
-		if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -EIO;
+		if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
 		/* Wait for it to initialize */ 
 		schedule_timeout(1 + 150 * HZ / 1000);
 		/* Dummy read to sync I2C */
-		if (ov51x_i2c_read(ov511, 0x00) < 0) return -EIO;
+		if (i2c_r(ov, 0x00) < 0) return -EIO;
 	}
 
 	if (!success)
@@ -1579,16 +1570,16 @@
 }
 
 static int 
-ov511_set_packet_size(struct usb_ov511 *ov511, int size)
+ov51x_set_packet_size(struct usb_ov511 *ov, int size)
 {
 	int alt, mult;
 
-	if (ov511_stop(ov511) < 0)
+	if (ov51x_stop(ov) < 0)
 		return -EIO;
 
 	mult = size >> 5;
 
-	if (ov511->bridge == BRG_OV511) {
+	if (ov->bridge == BRG_OV511) {
 		if (size == 0) alt = OV511_ALT_SIZE_0;
 		else if (size == 257) alt = OV511_ALT_SIZE_257;
 		else if (size == 513) alt = OV511_ALT_SIZE_513;
@@ -1598,7 +1589,7 @@
 			err("Set packet size: invalid size (%d)", size);
 			return -EINVAL;
 		}
-	} else if (ov511->bridge == BRG_OV511PLUS) {
+	} else if (ov->bridge == BRG_OV511PLUS) {
 		if (size == 0) alt = OV511PLUS_ALT_SIZE_0;
 		else if (size == 33) alt = OV511PLUS_ALT_SIZE_33;
 		else if (size == 129) alt = OV511PLUS_ALT_SIZE_129;
@@ -1611,8 +1602,7 @@
 			err("Set packet size: invalid size (%d)", size);
 			return -EINVAL;
 		}
-	} else if (ov511->bridge == BRG_OV518 ||
-		   ov511->bridge == BRG_OV518PLUS) {
+	} else if (ov->bclass == BCL_OV518) {
 		if (size == 0) alt = OV518_ALT_SIZE_0;
 		else if (size == 128) alt = OV518_ALT_SIZE_128;
 		else if (size == 256) alt = OV518_ALT_SIZE_256;
@@ -1633,32 +1623,30 @@
 	PDEBUG(3, "set packet size: %d, mult=%d, alt=%d", size, mult, alt);
 
 	// FIXME: Don't know how to do this on OV518 yet
-	if (ov511->bridge != BRG_OV518 &&
-	    ov511->bridge != BRG_OV518PLUS) {
-		if (ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE,
+	if (ov->bclass == BCL_OV511) {
+		if (reg_w(ov, R51x_FIFO_PSIZE,
 				    mult) < 0) {
 			return -EIO;
 		}
 	}
 	
-	if (usb_set_interface(ov511->dev, ov511->iface, alt) < 0) {
+	if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
 		err("Set packet size: set interface error");
 		return -EBUSY;
 	}
 
 	/* Initialize the stream */
-	if (ov511->bridge == BRG_OV518 ||
-	    ov511->bridge == BRG_OV518PLUS)
-		if (ov511_reg_write(ov511->dev, 0x2f, 0x80) < 0)
+	if (ov->bclass == BCL_OV518)
+		if (reg_w(ov, 0x2f, 0x80) < 0)
 			return -EIO;
 
 	// FIXME - Should we only reset the FIFO?
-	if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
+	if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
 		return -EIO;
 
-	ov511->packet_size = size;
+	ov->packet_size = size;
 
-	if (ov511_restart(ov511) < 0)
+	if (ov51x_restart(ov) < 0)
 		return -EIO;
 
 	return 0;
@@ -1666,51 +1654,49 @@
 
 /* Upload compression params and quantization tables. Returns 0 for success. */
 static int
-ov511_init_compression(struct usb_ov511 *ov511)
+ov511_init_compression(struct usb_ov511 *ov)
 {
-	struct usb_device *dev = ov511->dev;
 	int rc = 0;
 
-	if (!ov511->compress_inited) {
+	if (!ov->compress_inited) {
 
-		ov511_reg_write(dev, 0x70, phy);
-		ov511_reg_write(dev, 0x71, phuv);
-		ov511_reg_write(dev, 0x72, pvy);
-		ov511_reg_write(dev, 0x73, pvuv);
-		ov511_reg_write(dev, 0x74, qhy);
-		ov511_reg_write(dev, 0x75, qhuv);
-		ov511_reg_write(dev, 0x76, qvy);
-		ov511_reg_write(dev, 0x77, qvuv);
+		reg_w(ov, 0x70, phy);
+		reg_w(ov, 0x71, phuv);
+		reg_w(ov, 0x72, pvy);
+		reg_w(ov, 0x73, pvuv);
+		reg_w(ov, 0x74, qhy);
+		reg_w(ov, 0x75, qhuv);
+		reg_w(ov, 0x76, qvy);
+		reg_w(ov, 0x77, qvuv);
 
-		if (ov511_upload_quan_tables(dev) < 0) {
+		if (ov511_upload_quan_tables(ov) < 0) {
 			err("Error uploading quantization tables");
 			rc = -EIO;
 			goto out;
 		}
 	}
 
-	ov511->compress_inited = 1;
+	ov->compress_inited = 1;
 out:	
 	return rc;
 }
 
 /* Upload compression params and quantization tables. Returns 0 for success. */
 static int
-ov518_init_compression(struct usb_ov511 *ov511)
+ov518_init_compression(struct usb_ov511 *ov)
 {
-	struct usb_device *dev = ov511->dev;
 	int rc = 0;
 
-	if (!ov511->compress_inited) {
+	if (!ov->compress_inited) {
 
-		if (ov518_upload_quan_tables(dev) < 0) {
+		if (ov518_upload_quan_tables(ov) < 0) {
 			err("Error uploading quantization tables");
 			rc = -EIO;
 			goto out;
 		}
 	}
 
-	ov511->compress_inited = 1;
+	ov->compress_inited = 1;
 out:	
 	return rc;
 }
@@ -1719,22 +1705,22 @@
 
 /* Sets sensor's contrast setting to "val" */
 static int
-sensor_set_contrast(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_contrast(struct usb_ov511 *ov, unsigned short val)
 {
 	int rc;
 
 	PDEBUG(3, "%d", val);
 
-	if (ov511->stop_during_set)
-		if (ov511_stop(ov511) < 0)
+	if (ov->stop_during_set)
+		if (ov51x_stop(ov) < 0)
 			return -EIO;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV6620:
 	case SEN_OV6630:
 	{
-		rc = ov51x_i2c_write(ov511, OV7610_REG_CNT, val >> 8);
+		rc = i2c_w(ov, OV7610_REG_CNT, val >> 8);
 		if (rc < 0)
 			goto out;
 		break;
@@ -1747,14 +1733,14 @@
 		};
 
 		/* Use Y gamma control instead. Bit 0 enables it. */
-		rc = ov51x_i2c_write(ov511, 0x64, ctab[val>>12]);
+		rc = i2c_w(ov, 0x64, ctab[val>>12]);
 		if (rc < 0)
 			goto out;
 		break;
 	}
 	case SEN_SAA7111A:
 	{
-		rc = ov51x_i2c_write(ov511, 0x0b, val >> 9);
+		rc = i2c_w(ov, 0x0b, val >> 9);
 		if (rc < 0)
 			goto out;
 		break;
@@ -1768,9 +1754,9 @@
 	}
 
 	rc = 0;		/* Success */
-	ov511->contrast = val;
+	ov->contrast = val;
 out:
-	if (ov511_restart(ov511) < 0)
+	if (ov51x_restart(ov) < 0)
 		return -EIO;
 
 	return rc;
@@ -1778,15 +1764,15 @@
 
 /* Gets sensor's contrast setting */
 static int
-sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val)
 {
 	int rc;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV6620:
 	case SEN_OV6630:
-		rc = ov51x_i2c_read(ov511, OV7610_REG_CNT);
+		rc = i2c_r(ov, OV7610_REG_CNT);
 		if (rc < 0)
 			return rc;
 		else
@@ -1794,14 +1780,14 @@
 		break;
 	case SEN_OV7620:
 		/* Use Y gamma reg instead. Bit 0 is the enable bit. */
-		rc = ov51x_i2c_read(ov511, 0x64);
+		rc = i2c_r(ov, 0x64);
 		if (rc < 0)
 			return rc;
 		else
 			*val = (rc & 0xfe) << 8;
 		break;
 	case SEN_SAA7111A:
-		*val = ov511->contrast;
+		*val = ov->contrast;
 		break;
 	default:
 		PDEBUG(3, "Unsupported with this sensor");
@@ -1809,7 +1795,7 @@
 	}
 
 	PDEBUG(3, "%d", *val);
-	ov511->contrast = *val;
+	ov->contrast = *val;
 
 	return 0;
 }
@@ -1818,35 +1804,35 @@
 
 /* Sets sensor's brightness setting to "val" */
 static int
-sensor_set_brightness(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_brightness(struct usb_ov511 *ov, unsigned short val)
 {
 	int rc;
 
 	PDEBUG(4, "%d", val);
 
-	if (ov511->stop_during_set)
-		if (ov511_stop(ov511) < 0)
+	if (ov->stop_during_set)
+		if (ov51x_stop(ov) < 0)
 			return -EIO;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV7620AE:
 	case SEN_OV6620:
 	case SEN_OV6630:
-		rc = ov51x_i2c_write(ov511, OV7610_REG_BRT, val >> 8);
+		rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
 		if (rc < 0)
 			goto out;
 		break;
 	case SEN_OV7620:
 		/* 7620 doesn't like manual changes when in auto mode */
-		if (!ov511->auto_brt) {
-			rc = ov51x_i2c_write(ov511, OV7610_REG_BRT, val >> 8);
+		if (!ov->auto_brt) {
+			rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
 			if (rc < 0)
 				goto out;
 		}
 		break;
 	case SEN_SAA7111A:
-		rc = ov51x_i2c_write(ov511, 0x0a, val >> 8);
+		rc = i2c_w(ov, 0x0a, val >> 8);
 		if (rc < 0)
 			goto out;
 		break;
@@ -1857,9 +1843,9 @@
 	}
 
 	rc = 0;		/* Success */
-	ov511->brightness = val;
+	ov->brightness = val;
 out:
-	if (ov511_restart(ov511) < 0)
+	if (ov51x_restart(ov) < 0)
 		return -EIO;
 
 	return rc;
@@ -1867,24 +1853,24 @@
 
 /* Gets sensor's brightness setting */
 static int
-sensor_get_brightness(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val)
 {
 	int rc;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV7620AE:
 	case SEN_OV7620:
 	case SEN_OV6620:
 	case SEN_OV6630:
-		rc = ov51x_i2c_read(ov511, OV7610_REG_BRT);
+		rc = i2c_r(ov, OV7610_REG_BRT);
 		if (rc < 0)
 			return rc;
 		else
 			*val = rc << 8;
 		break;
 	case SEN_SAA7111A:
-		*val = ov511->brightness;
+		*val = ov->brightness;
 		break;
 	default:
 		PDEBUG(3, "Unsupported with this sensor");
@@ -1892,7 +1878,7 @@
 	}
 
 	PDEBUG(3, "%d", *val);
-	ov511->brightness = *val;
+	ov->brightness = *val;
 
 	return 0;
 }
@@ -1901,36 +1887,36 @@
 
 /* Sets sensor's saturation (color intensity) setting to "val" */
 static int
-sensor_set_saturation(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_saturation(struct usb_ov511 *ov, unsigned short val)
 {
 	int rc;
 
 	PDEBUG(3, "%d", val);
 
-	if (ov511->stop_during_set)
-		if (ov511_stop(ov511) < 0)
+	if (ov->stop_during_set)
+		if (ov51x_stop(ov) < 0)
 			return -EIO;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV7620AE:
 	case SEN_OV6620:
 	case SEN_OV6630:
-		rc = ov51x_i2c_write(ov511, OV7610_REG_SAT, val >> 8);
+		rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
 		if (rc < 0)
 			goto out;
 		break;
 	case SEN_OV7620:
 //		/* Use UV gamma control instead. Bits 0 & 7 are reserved. */
-//		rc = ov511_i2c_write(ov511->dev, 0x62, (val >> 9) & 0x7e);
+//		rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e);
 //		if (rc < 0)
 //			goto out;
-		rc = ov51x_i2c_write(ov511, OV7610_REG_SAT, val >> 8);
+		rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
 		if (rc < 0)
 			goto out;
 		break;
 	case SEN_SAA7111A:
-		rc = ov51x_i2c_write(ov511, 0x0c, val >> 9);
+		rc = i2c_w(ov, 0x0c, val >> 9);
 		if (rc < 0)
 			goto out;
 		break;
@@ -1941,9 +1927,9 @@
 	}
 
 	rc = 0;		/* Success */
-	ov511->colour = val;
+	ov->colour = val;
 out:
-	if (ov511_restart(ov511) < 0)
+	if (ov51x_restart(ov) < 0)
 		return -EIO;
 
 	return rc;
@@ -1951,16 +1937,16 @@
 
 /* Gets sensor's saturation (color intensity) setting */
 static int
-sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val)
 {
 	int rc;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV7620AE:
 	case SEN_OV6620:
 	case SEN_OV6630:
-		rc = ov51x_i2c_read(ov511, OV7610_REG_SAT);
+		rc = i2c_r(ov, OV7610_REG_SAT);
 		if (rc < 0)
 			return rc;
 		else
@@ -1968,19 +1954,19 @@
 		break;
 	case SEN_OV7620:
 //		/* Use UV gamma reg instead. Bits 0 & 7 are reserved. */
-//		rc = ov51x_i2c_read(ov511, 0x62);
+//		rc = i2c_r(ov, 0x62);
 //		if (rc < 0)
 //			return rc;
 //		else
 //			*val = (rc & 0x7e) << 9;
-		rc = ov51x_i2c_read(ov511, OV7610_REG_SAT);
+		rc = i2c_r(ov, OV7610_REG_SAT);
 		if (rc < 0)
 			return rc;
 		else
 			*val = rc << 8;
 		break;
 	case SEN_SAA7111A:
-		*val = ov511->colour;
+		*val = ov->colour;
 		break;
 	default:
 		PDEBUG(3, "Unsupported with this sensor");
@@ -1988,7 +1974,7 @@
 	}
 
 	PDEBUG(3, "%d", *val);
-	ov511->colour = *val;
+	ov->colour = *val;
 
 	return 0;
 }
@@ -1997,44 +1983,42 @@
 
 /* Sets sensor's hue (red/blue balance) setting to "val" */
 static int
-sensor_set_hue(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_hue(struct usb_ov511 *ov, unsigned short val)
 {
 	int rc;
 
 	PDEBUG(3, "%d", val);
 
-	if (ov511->stop_during_set)
-		if (ov511_stop(ov511) < 0)
+	if (ov->stop_during_set)
+		if (ov51x_stop(ov) < 0)
 			return -EIO;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV6620:
 	case SEN_OV6630:
-		rc = ov51x_i2c_write(ov511, OV7610_REG_RED, 0xFF - (val >> 8));
+		rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8));
 		if (rc < 0)
 			goto out;
 
-		rc = ov51x_i2c_write(ov511, OV7610_REG_BLUE, val >> 8);
+		rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8);
 		if (rc < 0)
 			goto out;
 		break;
 	case SEN_OV7620:
 // Hue control is causing problems. I will enable it once it's fixed.
 #if 0
-		rc = ov51x_i2c_write(ov511, 0x7a,
-				     (unsigned char)(val >> 8) + 0xb);
+		rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb);
 		if (rc < 0)
 			goto out;
 
-		rc = ov51x_i2c_write(ov511, 0x79, 
-				     (unsigned char)(val >> 8) + 0xb);
+		rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb);
 		if (rc < 0)
 			goto out;
 #endif
 		break;
 	case SEN_SAA7111A:
-		rc = ov51x_i2c_write(ov511, 0x0d, (val + 32768) >> 8);
+		rc = i2c_w(ov, 0x0d, (val + 32768) >> 8);
 		if (rc < 0)
 			goto out;
 		break;
@@ -2045,9 +2029,9 @@
 	}
 
 	rc = 0;		/* Success */
-	ov511->hue = val;
+	ov->hue = val;
 out:
-	if (ov511_restart(ov511) < 0)
+	if (ov51x_restart(ov) < 0)
 		return -EIO;
 
 	return rc;
@@ -2055,29 +2039,29 @@
 
 /* Gets sensor's hue (red/blue balance) setting */
 static int
-sensor_get_hue(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_hue(struct usb_ov511 *ov, unsigned short *val)
 {
 	int rc;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV6620:
 	case SEN_OV6630:
-		rc = ov51x_i2c_read(ov511, OV7610_REG_BLUE);
+		rc = i2c_r(ov, OV7610_REG_BLUE);
 		if (rc < 0)
 			return rc;
 		else
 			*val = rc << 8;
 		break;
 	case SEN_OV7620:
-		rc = ov51x_i2c_read(ov511, 0x7a);
+		rc = i2c_r(ov, 0x7a);
 		if (rc < 0)
 			return rc;
 		else
 			*val = rc << 8;
 		break;
 	case SEN_SAA7111A:
-		*val = ov511->hue;
+		*val = ov->hue;
 		break;
 	default:
 		PDEBUG(3, "Unsupported with this sensor");
@@ -2085,7 +2069,7 @@
 	}
 
 	PDEBUG(3, "%d", *val);
-	ov511->hue = *val;
+	ov->hue = *val;
 
 	return 0;
 }
@@ -2093,30 +2077,30 @@
 /* -------------------------------------------------------------------------- */
 
 static inline int
-sensor_set_picture(struct usb_ov511 *ov511, struct video_picture *p)
+sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
 {
 	int rc;
 
 	PDEBUG(4, "sensor_set_picture");
 
-	ov511->whiteness = p->whiteness;
+	ov->whiteness = p->whiteness;
 
 	/* Don't return error if a setting is unsupported, or rest of settings
          * will not be performed */
 
-	rc = sensor_set_contrast(ov511, p->contrast);
+	rc = sensor_set_contrast(ov, p->contrast);
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	rc = sensor_set_brightness(ov511, p->brightness);
+	rc = sensor_set_brightness(ov, p->brightness);
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	rc = sensor_set_saturation(ov511, p->colour);
+	rc = sensor_set_saturation(ov, p->colour);
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	rc = sensor_set_hue(ov511, p->hue);
+	rc = sensor_set_hue(ov, p->hue);
 	if (FATAL_ERROR(rc))
 		return rc;
 
@@ -2124,7 +2108,7 @@
 }
 
 static inline int
-sensor_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
+sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
 {
 	int rc;
 
@@ -2133,27 +2117,27 @@
 	/* Don't return error if a setting is unsupported, or rest of settings
          * will not be performed */
 
-	rc = sensor_get_contrast(ov511, &(p->contrast));
+	rc = sensor_get_contrast(ov, &(p->contrast));
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	rc = sensor_get_brightness(ov511, &(p->brightness));
+	rc = sensor_get_brightness(ov, &(p->brightness));
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	rc = sensor_get_saturation(ov511, &(p->colour));
+	rc = sensor_get_saturation(ov, &(p->colour));
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	rc = sensor_get_hue(ov511, &(p->hue));
+	rc = sensor_get_hue(ov, &(p->hue));
 	if (FATAL_ERROR(rc))
 		return rc;
 
 	p->whiteness = 105 << 8;
 
 	/* Can we get these from frame[0]? -claudio? */
-	p->depth = ov511->frame[0].depth;
-	p->palette = ov511->frame[0].format;
+	p->depth = ov->frame[0].depth;
+	p->palette = ov->frame[0].format;
 
 	return 0;
 }
@@ -2162,24 +2146,24 @@
 /* Sets current exposure for sensor. This only has an effect if auto-exposure
  * is off */
 static inline int
-sensor_set_exposure(struct usb_ov511 *ov511, unsigned char val)
+sensor_set_exposure(struct usb_ov511 *ov, unsigned char val)
 {
 	int rc;
 
 	PDEBUG(3, "%d", val);
 
-	if (ov511->stop_during_set)
-		if (ov511_stop(ov511) < 0)
+	if (ov->stop_during_set)
+		if (ov51x_stop(ov) < 0)
 			return -EIO;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV6620:
 	case SEN_OV6630:
 	case SEN_OV7610:
 	case SEN_OV7620:
 	case SEN_OV7620AE:
 	case SEN_OV8600:
-		rc = ov51x_i2c_write(ov511, 0x10, val);
+		rc = i2c_w(ov, 0x10, val);
 		if (rc < 0)
 			goto out;
 
@@ -2195,9 +2179,9 @@
 	}
 
 	rc = 0;		/* Success */
-	ov511->exposure = val;
+	ov->exposure = val;
 out:
-	if (ov511_restart(ov511) < 0)
+	if (ov51x_restart(ov) < 0)
 		return -EIO;
 
 	return rc;
@@ -2206,18 +2190,18 @@
 /* Gets current exposure level from sensor, regardless of whether it is under
  * manual control. */
 static int
-sensor_get_exposure(struct usb_ov511 *ov511, unsigned char *val)
+sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val)
 {
 	int rc;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV6620:
 	case SEN_OV6630:
 	case SEN_OV7620:
 	case SEN_OV7620AE:
 	case SEN_OV8600:
-		rc = ov51x_i2c_read(ov511, 0x10);
+		rc = i2c_r(ov, 0x10);
 		if (rc < 0)
 			return rc;
 		else
@@ -2235,24 +2219,22 @@
 	}
 
 	PDEBUG(3, "%d", *val);
-	ov511->exposure = *val;
+	ov->exposure = *val;
 
 	return 0;
 }
 
 /* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */
 static inline void 
-ov51x_led_control(struct usb_ov511 *ov511, int enable)
+ov51x_led_control(struct usb_ov511 *ov, int enable)
 {
 	PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
 
-	if (ov511->bridge == BRG_OV511PLUS)
-		ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_LED_CTL, 
-			        enable ? 1 : 0);
-	else if (ov511->bridge == BRG_OV518 ||
-		 ov511->bridge == BRG_OV518PLUS)
-		ov511_reg_write_mask(ov511->dev, OV518_REG_GPIO_OUT, 
-				     enable ? 0x02 : 0x00, 0x02);
+	if (ov->bridge == BRG_OV511PLUS)
+		reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0);
+	else if (ov->bclass == BCL_OV518)
+		reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02);
+
 	return;
 }
 
@@ -2266,7 +2248,7 @@
  * Returns: 0 for success
  */
 static int
-sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
+sensor_set_light_freq(struct usb_ov511 *ov, int freq)
 {
 	int sixty;
 
@@ -2281,24 +2263,24 @@
 		return -EINVAL;
 	}
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
-		ov51x_i2c_write_mask(ov511, 0x2a, sixty?0x00:0x80, 0x80);
-		ov51x_i2c_write(ov511, 0x2b, sixty?0x00:0xac);
-		ov51x_i2c_write_mask(ov511, 0x13, 0x10, 0x10);
-		ov51x_i2c_write_mask(ov511, 0x13, 0x00, 0x10);
+		i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
+		i2c_w(ov, 0x2b, sixty?0x00:0xac);
+		i2c_w_mask(ov, 0x13, 0x10, 0x10);
+		i2c_w_mask(ov, 0x13, 0x00, 0x10);
 		break;
 	case SEN_OV7620:
 	case SEN_OV7620AE:
 	case SEN_OV8600:
-		ov51x_i2c_write_mask(ov511, 0x2a, sixty?0x00:0x80, 0x80);
-		ov51x_i2c_write(ov511, 0x2b, sixty?0x00:0xac);
-		ov51x_i2c_write_mask(ov511, 0x76, 0x01, 0x01);
+		i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
+		i2c_w(ov, 0x2b, sixty?0x00:0xac);
+		i2c_w_mask(ov, 0x76, 0x01, 0x01);
 		break;		
 	case SEN_OV6620:
 	case SEN_OV6630:
-		ov51x_i2c_write(ov511, 0x2b, sixty?0xa8:0x28);
-		ov51x_i2c_write(ov511, 0x2a, sixty?0x84:0xa4);
+		i2c_w(ov, 0x2b, sixty?0xa8:0x28);
+		i2c_w(ov, 0x2a, sixty?0x84:0xa4);
 		break;
 	case SEN_KS0127:
 	case SEN_KS0127B:
@@ -2310,7 +2292,7 @@
 		return -EINVAL;
 	}
 
-	ov511->lightfreq = freq;
+	ov->lightfreq = freq;
 
 	return 0;
 }
@@ -2325,23 +2307,23 @@
  * Returns: 0 for success
  */
 static inline int
-sensor_set_banding_filter(struct usb_ov511 *ov511, int enable)
+sensor_set_banding_filter(struct usb_ov511 *ov, int enable)
 {
 	int rc;
 
 	PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
 
-	if (ov511->sensor == SEN_KS0127 || ov511->sensor == SEN_KS0127B
-		|| ov511->sensor == SEN_SAA7111A) {
+	if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
+		|| ov->sensor == SEN_SAA7111A) {
 		PDEBUG(5, "Unsupported with this sensor");
 		return -EPERM;
 	}
 
-	rc = ov51x_i2c_write_mask(ov511, 0x2d, enable?0x04:0x00, 0x04);
+	rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04);
 	if (rc < 0)
 		return rc;
 
-	ov511->bandfilt = enable;
+	ov->bandfilt = enable;
 
 	return 0;
 }
@@ -2353,23 +2335,23 @@
  * Returns: 0 for success
  */
 static inline int
-sensor_set_auto_brightness(struct usb_ov511 *ov511, int enable)
+sensor_set_auto_brightness(struct usb_ov511 *ov, int enable)
 {
 	int rc;
 
 	PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
 
-	if (ov511->sensor == SEN_KS0127 || ov511->sensor == SEN_KS0127B
-		|| ov511->sensor == SEN_SAA7111A) {
+	if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
+		|| ov->sensor == SEN_SAA7111A) {
 		PDEBUG(5, "Unsupported with this sensor");
 		return -EPERM;
 	}
 
-	rc = ov51x_i2c_write_mask(ov511, 0x2d, enable?0x10:0x00, 0x10);
+	rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10);
 	if (rc < 0)
 		return rc;
 
-	ov511->auto_brt = enable;
+	ov->auto_brt = enable;
 
 	return 0;
 }
@@ -2381,22 +2363,22 @@
  * Returns: 0 for success
  */
 static inline int
-sensor_set_auto_exposure(struct usb_ov511 *ov511, int enable)
+sensor_set_auto_exposure(struct usb_ov511 *ov, int enable)
 {	
 	PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
-		ov51x_i2c_write_mask(ov511, 0x29, enable?0x00:0x80, 0x80);
+		i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80);
 		break;
 	case SEN_OV6620:
 	case SEN_OV7620:
 	case SEN_OV7620AE:
 	case SEN_OV8600:
-		ov51x_i2c_write_mask(ov511, 0x13, enable?0x01:0x00, 0x01);
+		i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01);
 		break;		
 	case SEN_OV6630:
-		ov51x_i2c_write_mask(ov511, 0x28, enable?0x00:0x10, 0x10);
+		i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10);
 		break;
 	case SEN_KS0127:
 	case SEN_KS0127B:
@@ -2408,7 +2390,7 @@
 		return -EINVAL;
 	}
 
-	ov511->auto_exp = enable;
+	ov->auto_exp = enable;
 
 	return 0;
 }
@@ -2421,27 +2403,27 @@
  * Returns: 0 for success
  */
 static int
-sensor_set_backlight(struct usb_ov511 *ov511, int enable)
+sensor_set_backlight(struct usb_ov511 *ov, int enable)
 {
 
 	PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7620:
 	case SEN_OV8600:
-		ov51x_i2c_write_mask(ov511, 0x68, enable?0xe0:0xc0, 0xe0);
-		ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
-		ov51x_i2c_write_mask(ov511, 0x28, enable?0x02:0x00, 0x02);
+		i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0);
+		i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+		i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
 		break;		
 	case SEN_OV6620:
-		ov51x_i2c_write_mask(ov511, 0x4e, enable?0xe0:0xc0, 0xe0);
-		ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
-		ov51x_i2c_write_mask(ov511, 0x0e, enable?0x80:0x00, 0x80);
+		i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0);
+		i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+		i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80);
 		break;
 	case SEN_OV6630:
-		ov51x_i2c_write_mask(ov511, 0x4e, enable?0x80:0x60, 0xe0);
-		ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
-		ov51x_i2c_write_mask(ov511, 0x28, enable?0x02:0x00, 0x02);
+		i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0);
+		i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+		i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
 		break;
 	case SEN_OV7610:
 	case SEN_OV7620AE:
@@ -2455,7 +2437,7 @@
 		return -EINVAL;
 	}
 
-	ov511->backlight = enable;
+	ov->backlight = enable;
 
 	return 0;
 }
@@ -2464,7 +2446,7 @@
  * planar or not), or zero for unsupported format.
  */
 static inline int 
-ov511_get_depth(int palette)
+get_depth(int palette)
 {
 	switch (palette) {
 	case VIDEO_PALETTE_GREY:    return 8;
@@ -2487,55 +2469,55 @@
 		return 0;
 	else
 		return ((frame->width * frame->height
-			 * ov511_get_depth(frame->format)) >> 3);
+			 * get_depth(frame->format)) >> 3);
 }
 
 static int
-mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
+mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
 			 int mode, int sub_flag, int qvga)
 {
 	int clock;
 
 	/******** Mode (VGA/QVGA) and sensor specific regs ********/
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
-		ov51x_i2c_write(ov511, 0x14, qvga?0x24:0x04);
+		i2c_w(ov, 0x14, qvga?0x24:0x04);
 // FIXME: Does this improve the image quality or frame rate?
 #if 0
-		ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
-		ov51x_i2c_write(ov511, 0x24, 0x10);
-		ov51x_i2c_write(ov511, 0x25, qvga?0x40:0x8a);
-		ov51x_i2c_write(ov511, 0x2f, qvga?0x30:0xb0);
-		ov51x_i2c_write(ov511, 0x35, qvga?0x1c:0x9c);
+		i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+		i2c_w(ov, 0x24, 0x10);
+		i2c_w(ov, 0x25, qvga?0x40:0x8a);
+		i2c_w(ov, 0x2f, qvga?0x30:0xb0);
+		i2c_w(ov, 0x35, qvga?0x1c:0x9c);
 #endif
 		break;
 	case SEN_OV7620:
-//		ov51x_i2c_write(ov511, 0x2b, 0x00);
-		ov51x_i2c_write(ov511, 0x14, qvga?0xa4:0x84);
-		ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
-		ov51x_i2c_write(ov511, 0x24, qvga?0x20:0x3a);
-		ov51x_i2c_write(ov511, 0x25, qvga?0x30:0x60);
-		ov51x_i2c_write_mask(ov511, 0x2d, qvga?0x40:0x00, 0x40);
-		ov51x_i2c_write_mask(ov511, 0x67, qvga?0xf0:0x90, 0xf0);
-		ov51x_i2c_write_mask(ov511, 0x74, qvga?0x20:0x00, 0x20);
+//		i2c_w(ov, 0x2b, 0x00);
+		i2c_w(ov, 0x14, qvga?0xa4:0x84);
+		i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+		i2c_w(ov, 0x24, qvga?0x20:0x3a);
+		i2c_w(ov, 0x25, qvga?0x30:0x60);
+		i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
+		i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0);
+		i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
 		break;
 	case SEN_OV7620AE:
-//		ov51x_i2c_write(ov511, 0x2b, 0x00);
-		ov51x_i2c_write(ov511, 0x14, qvga?0xa4:0x84);
+//		i2c_w(ov, 0x2b, 0x00);
+		i2c_w(ov, 0x14, qvga?0xa4:0x84);
 // FIXME: Enable this once 7620AE uses 7620 initial settings
 #if 0
-		ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
-		ov51x_i2c_write(ov511, 0x24, qvga?0x20:0x3a);
-		ov51x_i2c_write(ov511, 0x25, qvga?0x30:0x60);
-		ov51x_i2c_write_mask(ov511, 0x2d, qvga?0x40:0x00, 0x40);
-		ov51x_i2c_write_mask(ov511, 0x67, qvga?0xb0:0x90, 0xf0);
-		ov51x_i2c_write_mask(ov511, 0x74, qvga?0x20:0x00, 0x20);
+		i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+		i2c_w(ov, 0x24, qvga?0x20:0x3a);
+		i2c_w(ov, 0x25, qvga?0x30:0x60);
+		i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
+		i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0);
+		i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
 #endif
 		break;
 	case SEN_OV6620:
 	case SEN_OV6630:
-		ov51x_i2c_write(ov511, 0x14, qvga?0x24:0x04);
+		i2c_w(ov, 0x14, qvga?0x24:0x04);
 		/* No special settings yet */
 		break;
 	default:
@@ -2546,19 +2528,17 @@
 	/******** Palette-specific regs ********/
 
 	if (mode == VIDEO_PALETTE_GREY) {
-		if (ov511->sensor == SEN_OV7610
-		    || ov511->sensor == SEN_OV7620AE) {
+		if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
 			/* these aren't valid on the OV6620/OV7620/6630? */
-			ov51x_i2c_write_mask(ov511, 0x0e, 0x40, 0x40);
+			i2c_w_mask(ov, 0x0e, 0x40, 0x40);
 		}
-		ov51x_i2c_write_mask(ov511, 0x13, 0x20, 0x20);
+		i2c_w_mask(ov, 0x13, 0x20, 0x20);
 	} else {
-		if (ov511->sensor == SEN_OV7610
-		    || ov511->sensor == SEN_OV7620AE) {
+		if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
 			/* not valid on the OV6620/OV7620/6630? */
-			ov51x_i2c_write_mask(ov511, 0x0e, 0x00, 0x40);
+			i2c_w_mask(ov, 0x0e, 0x00, 0x40);
 		}
-		ov51x_i2c_write_mask(ov511, 0x13, 0x00, 0x20);
+		i2c_w_mask(ov, 0x13, 0x00, 0x20);
 	}
 
 	/******** Clock programming ********/
@@ -2567,13 +2547,13 @@
 
 	/* The OV6620 needs special handling. This prevents the 
 	 * severe banding that normally occurs */
-	if (ov511->sensor == SEN_OV6620 || ov511->sensor == SEN_OV6630)
+	if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
 	{
 		/* Clock down */
 
-		ov51x_i2c_write(ov511, 0x2a, 0x04);
+		i2c_w(ov, 0x2a, 0x04);
 
-		if (ov511->compress) {
+		if (ov->compress) {
 //			clock = 0;    /* This ensures the highest frame rate */
 			clock = 3;
 		} else if (clockdiv == -1) {   /* If user didn't override it */
@@ -2584,21 +2564,21 @@
 
 		PDEBUG(4, "Setting clock divisor to %d", clock);
 
-		ov51x_i2c_write(ov511, 0x11, clock);
+		i2c_w(ov, 0x11, clock);
 
-		ov51x_i2c_write(ov511, 0x2a, 0x84);
+		i2c_w(ov, 0x2a, 0x84);
 		/* This next setting is critical. It seems to improve
 		 * the gain or the contrast. The "reserved" bits seem
 		 * to have some effect in this case. */
-		ov51x_i2c_write(ov511, 0x2d, 0x85);
+		i2c_w(ov, 0x2d, 0x85);
 	}
 	else
 	{
-		if (ov511->compress) {
+		if (ov->compress) {
 			clock = 1;    /* This ensures the highest frame rate */
 		} else if (clockdiv == -1) {   /* If user didn't override it */
 			/* Calculate and set the clock divisor */
-			clock = ((sub_flag ? ov511->subw * ov511->subh
+			clock = ((sub_flag ? ov->subw * ov->subh
 				  : width * height)
 				 * (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2)
 				 / 66000;
@@ -2608,45 +2588,44 @@
 
 		PDEBUG(4, "Setting clock divisor to %d", clock);
 
-		ov51x_i2c_write(ov511, 0x11, clock);
+		i2c_w(ov, 0x11, clock);
 	}
 
 	/******** Special Features ********/
 
 	if (framedrop >= 0)
-		ov51x_i2c_write(ov511, 0x16, framedrop);
+		i2c_w(ov, 0x16, framedrop);
 
 	/* We only have code to convert GBR -> RGB24 */
 	if ((mode == VIDEO_PALETTE_RGB24) && sensor_gbr)
-		ov51x_i2c_write_mask(ov511, 0x12, 0x08, 0x08);
+		i2c_w_mask(ov, 0x12, 0x08, 0x08);
 	else
-		ov51x_i2c_write_mask(ov511, 0x12, 0x00, 0x08);
+		i2c_w_mask(ov, 0x12, 0x00, 0x08);
 
 	/* Test Pattern */
-	ov51x_i2c_write_mask(ov511, 0x12, (testpat?0x02:0x00), 0x02);
+	i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02);
 
 	/* Auto white balance */
 //	if (awb)
-		ov51x_i2c_write_mask(ov511, 0x12, 0x04, 0x04);
+		i2c_w_mask(ov, 0x12, 0x04, 0x04);
 //	else
-//		ov51x_i2c_write_mask(ov511, 0x12, 0x00, 0x04);
+//		i2c_w_mask(ov, 0x12, 0x00, 0x04);
 
-	// This will go away as soon as ov511_mode_init_sensor_regs()
+	// This will go away as soon as ov51x_mode_init_sensor_regs()
 	// is fully tested.
 	/* 7620/6620/6630? don't have register 0x35, so play it safe */
-	if (ov511->sensor == SEN_OV7610 ||
-	    ov511->sensor == SEN_OV7620AE) {
+	if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
 		if (width == 640 && height == 480)
-			ov51x_i2c_write(ov511, 0x35, 0x9e);
+			i2c_w(ov, 0x35, 0x9e);
 		else
-			ov51x_i2c_write(ov511, 0x35, 0x1e);
+			i2c_w(ov, 0x35, 0x1e);
 	}
 
 	return 0;
 }
 
 static int
-set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
+set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode,
 		     int sub_flag)
 {
 	int ret;
@@ -2655,7 +2634,7 @@
 
 	/* The different sensor ICs handle setting up of window differently.
 	 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV7620AE:
 		hwsbase = 0x38;
@@ -2679,9 +2658,9 @@
 		return -EINVAL;
 	}
 
-	if (ov511->sensor == SEN_OV6620 || ov511->sensor == SEN_OV6630) {
+	if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) {
 		if (width > 176 && height > 144) {  /* CIF */
-			ret = mode_init_ov_sensor_regs(ov511, width, height,
+			ret = mode_init_ov_sensor_regs(ov, width, height,
 				mode, sub_flag, 0);
 			if (ret < 0)
 				return ret;
@@ -2693,7 +2672,7 @@
 			err("Illegal dimensions");
 			return -EINVAL;
 		} else {			    /* QCIF */
-			ret = mode_init_ov_sensor_regs(ov511, width, height,
+			ret = mode_init_ov_sensor_regs(ov, width, height,
 				mode, sub_flag, 1);
 			if (ret < 0)
 				return ret;
@@ -2702,7 +2681,7 @@
 		}
 	} else {
 		if (width > 320 && height > 240) {  /* VGA */
-			ret = mode_init_ov_sensor_regs(ov511, width, height,
+			ret = mode_init_ov_sensor_regs(ov, width, height,
 				mode, sub_flag, 0);
 			if (ret < 0)
 				return ret;
@@ -2714,7 +2693,7 @@
 			err("Illegal dimensions");
 			return -EINVAL;
 		} else {			    /* QVGA */
-			ret = mode_init_ov_sensor_regs(ov511, width, height,
+			ret = mode_init_ov_sensor_regs(ov, width, height,
 				mode, sub_flag, 1);
 			if (ret < 0)
 				return ret;
@@ -2730,24 +2709,20 @@
 
 	/* FIXME! - This needs to be changed to support 160x120 and 6620!!! */
 	if (sub_flag) {
-		ov51x_i2c_write(ov511, 0x17, hwsbase+(ov511->subx>>hwscale));
-		ov51x_i2c_write(ov511, 0x18,
-				hwebase+((ov511->subx+ov511->subw)>>hwscale));
-		ov51x_i2c_write(ov511, 0x19, vwsbase+(ov511->suby>>vwscale));
-		ov51x_i2c_write(ov511, 0x1a,
-				vwebase+((ov511->suby+ov511->subh)>>vwscale));
+		i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale));
+		i2c_w(ov, 0x18,	hwebase+((ov->subx+ov->subw)>>hwscale));
+		i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale));
+		i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale));
 	} else {
-		ov51x_i2c_write(ov511, 0x17, hwsbase + hoffset);
-		ov51x_i2c_write(ov511, 0x18,
-				hwebase + hoffset + (hwsize>>hwscale));
-		ov51x_i2c_write(ov511, 0x19, vwsbase + voffset);
-		ov51x_i2c_write(ov511, 0x1a,
-				vwebase + voffset + (vwsize>>vwscale));
+		i2c_w(ov, 0x17, hwsbase + hoffset);
+		i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale));
+		i2c_w(ov, 0x19, vwsbase + voffset);
+		i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale));
 	}
 
 #ifdef OV511_DEBUG
 	if (dump_sensor)
-		ov51x_dump_i2c_regs(ov511);
+		dump_i2c_regs(ov);
 #endif
 
 	return 0;
@@ -2758,18 +2733,14 @@
  * Do not put any sensor-specific code in here (including I2C I/O functions)
  */
 static int
-ov511_mode_init_regs(struct usb_ov511 *ov511,
+ov511_mode_init_regs(struct usb_ov511 *ov,
 		     int width, int height, int mode, int sub_flag)
 {
 	int lncnt, pxcnt, rc = 0;
-	struct usb_device *dev = ov511->dev;
-
-	if (!ov511 || !dev)
-		return -EFAULT;
 
 	if (sub_flag) {
-		width = ov511->subw;
-		height = ov511->subh;
+		width = ov->subw;
+		height = ov->subh;
 	}
 
 	PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
@@ -2777,7 +2748,7 @@
 
 	// FIXME: This should be moved to a 7111a-specific function once
 	// subcapture is dealt with properly
-	if (ov511->sensor == SEN_SAA7111A) {
+	if (ov->sensor == SEN_SAA7111A) {
 		if (width == 320 && height == 240) {
 			/* No need to do anything special */
 		} else if (width == 640 && height == 480) {
@@ -2796,26 +2767,22 @@
 		return -EINVAL;
 	}
 
-	if (width < ov511->minwidth || height < ov511->minheight) {
+	if (width < ov->minwidth || height < ov->minheight) {
 		err("Requested dimensions are too small");
 		return -EINVAL;
 	}
 
-	if (ov511_stop(ov511) < 0)
+	if (ov51x_stop(ov) < 0)
 		return -EIO;
 
 	if (mode == VIDEO_PALETTE_GREY) {
-		ov511_reg_write(dev, 0x16, 0x00);
-
-		/* For snapshot */
-		ov511_reg_write(dev, 0x1e, 0x00);
-		ov511_reg_write(dev, 0x1f, 0x01);
+		reg_w(ov, R511_CAM_UV_EN, 0x00);
+		reg_w(ov, R511_SNAP_UV_EN, 0x00);
+		reg_w(ov, R511_SNAP_OPTS, 0x01);
 	} else {
-		ov511_reg_write(dev, 0x16, 0x01);
-
-		/* For snapshot */
-		ov511_reg_write(dev, 0x1e, 0x01);
-		ov511_reg_write(dev, 0x1f, 0x03);
+		reg_w(ov, R511_CAM_UV_EN, 0x01);
+		reg_w(ov, R511_SNAP_UV_EN, 0x01);
+		reg_w(ov, R511_SNAP_OPTS, 0x03);
 	}
 
 	/* Here I'm assuming that snapshot size == image size.
@@ -2824,25 +2791,28 @@
 	pxcnt = (width >> 3) - 1;
 	lncnt = (height >> 3) - 1;
 
-	ov511_reg_write(dev, 0x12, pxcnt);
-	ov511_reg_write(dev, 0x13, lncnt);
-	ov511_reg_write(dev, 0x14, 0x00);
-	ov511_reg_write(dev, 0x15, 0x00);
-	ov511_reg_write(dev, 0x18, 0x03);	/* YUV420, low pass filer on */
+	reg_w(ov, R511_CAM_PXCNT, pxcnt);
+	reg_w(ov, R511_CAM_LNCNT, lncnt);
+	reg_w(ov, R511_CAM_PXDIV, 0x00);
+	reg_w(ov, R511_CAM_LNDIV, 0x00);
+
+	/* YUV420, low pass filer on */
+	reg_w(ov, R511_CAM_OPTS, 0x03);
 
 	/* Snapshot additions */
-	ov511_reg_write(dev, 0x1a, pxcnt);
-	ov511_reg_write(dev, 0x1b, lncnt);
-        ov511_reg_write(dev, 0x1c, 0x00);
-        ov511_reg_write(dev, 0x1d, 0x00);
-
-	if (ov511->compress) {
-		ov511_reg_write(dev, 0x78, 0x07); // Turn on Y & UV compression
-		ov511_reg_write(dev, 0x79, 0x03); // Enable LUTs
-		ov511_reset(ov511, OV511_RESET_OMNICE);
+	reg_w(ov, R511_SNAP_PXCNT, pxcnt);
+	reg_w(ov, R511_SNAP_LNCNT, lncnt);
+	reg_w(ov, R511_SNAP_PXDIV, 0x00);
+	reg_w(ov, R511_SNAP_LNDIV, 0x00);
+
+	if (ov->compress) {
+		/* Enable Y and UV quantization and compression */
+		reg_w(ov, R511_COMP_EN, 0x07);
+		reg_w(ov, R511_COMP_LUT_EN, 0x03);
+		ov51x_reset(ov, OV511_RESET_OMNICE);
 	}
 //out:
-	if (ov511_restart(ov511) < 0)
+	if (ov51x_restart(ov) < 0)
 		return -EIO;
 
 	return rc;
@@ -2866,17 +2836,15 @@
  * Do not put any sensor-specific code in here (including I2C I/O functions)
  */
 static int
-ov518_mode_init_regs(struct usb_ov511 *ov511,
+ov518_mode_init_regs(struct usb_ov511 *ov,
 		     int width, int height, int mode, int sub_flag)
 {
 	int i;
-	struct usb_device *dev = ov511->dev;
-	unsigned char b[3]; /* Multiple-value reg buffer */
 
 	PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
 	       width, height, mode, sub_flag);
 
-	if (ov511_stop(ov511) < 0)
+	if (ov51x_stop(ov) < 0)
 		return -EIO;
 
 	for (i = 0; mlist518[i].width; i++) {
@@ -2894,113 +2862,94 @@
 //		pxcnt = sub_flag ? (ov511->subw >> 3) - 1 : mlist[i].pxcnt;
 //		lncnt = sub_flag ? (ov511->subh >> 3) - 1 : mlist[i].lncnt;
 //
-//		ov511_reg_write(dev, 0x12, pxcnt);
-//		ov511_reg_write(dev, 0x13, lncnt);
+//		reg_w(ov511, 0x12, pxcnt);
+//		reg_w(ov511, 0x13, lncnt);
 
 		/******** Set the mode ********/		
 
 		/* Mode independent regs */
-		ov511_reg_write(dev, 0x2b, 0x00);
-		ov511_reg_write(dev, 0x2d, 0x00);
-		ov511_reg_write(dev, 0x3b, 0x00);
-		ov511_reg_write(dev, 0x3d, 0x00);
+		reg_w(ov, 0x2b, 0x00);
+		reg_w(ov, 0x2d, 0x00);
+		reg_w(ov, 0x3b, 0x00);
+		reg_w(ov, 0x3d, 0x00);
 
 		/* Mode dependent regs. Regs 38 - 3e are always the same as
 		 * regs 28 - 2e */
-		ov511_reg_write_mask(dev, 0x28, mlist518[i].reg28
+		reg_w_mask(ov, 0x28, mlist518[i].reg28
 			| (mode == VIDEO_PALETTE_GREY) ? 0x80:0x00, 0x8f);
-		ov511_reg_write(dev, 0x29, mlist518[i].reg29);
-		ov511_reg_write(dev, 0x2a, mlist518[i].reg2a);
-		ov511_reg_write(dev, 0x2c, mlist518[i].reg2c);
-		ov511_reg_write(dev, 0x2e, mlist518[i].reg2e);
-		ov511_reg_write_mask(dev, 0x38, mlist518[i].reg28 
+		reg_w(ov, 0x29, mlist518[i].reg29);
+		reg_w(ov, 0x2a, mlist518[i].reg2a);
+		reg_w(ov, 0x2c, mlist518[i].reg2c);
+		reg_w(ov, 0x2e, mlist518[i].reg2e);
+		reg_w_mask(ov, 0x38, mlist518[i].reg28 
 			| (mode == VIDEO_PALETTE_GREY) ? 0x80:0x00, 0x8f);
-		ov511_reg_write(dev, 0x39, mlist518[i].reg29);
-		ov511_reg_write(dev, 0x3a, mlist518[i].reg2a);
-		ov511_reg_write(dev, 0x3c, mlist518[i].reg2c);
-		ov511_reg_write(dev, 0x3e, mlist518[i].reg2e);
-		ov511_reg_write(dev, 0x24, mlist518[i].reg24);
-		ov511_reg_write(dev, 0x25, mlist518[i].reg25);
+		reg_w(ov, 0x39, mlist518[i].reg29);
+		reg_w(ov, 0x3a, mlist518[i].reg2a);
+		reg_w(ov, 0x3c, mlist518[i].reg2c);
+		reg_w(ov, 0x3e, mlist518[i].reg2e);
+		reg_w(ov, 0x24, mlist518[i].reg24);
+		reg_w(ov, 0x25, mlist518[i].reg25);
 
 		/* Windows driver does this here; who knows why */
-		ov511_reg_write(dev, 0x2f, 0x80);
+		reg_w(ov, 0x2f, 0x80);
 
 		/******** Set the framerate (to 15 FPS) ********/		
 
 		/* Mode independent, but framerate dependent, regs */
 		/* These are for 15 FPS only */
-		ov511_reg_write(dev, 0x51, 0x08);
-		ov511_reg_write(dev, 0x22, 0x18);
-		ov511_reg_write(dev, 0x23, 0xff);
-		ov511_reg_write(dev, 0x71, 0x19);  /* Compression-related? */
+		reg_w(ov, 0x51, 0x08);
+		reg_w(ov, 0x22, 0x18);
+		reg_w(ov, 0x23, 0xff);
+		reg_w(ov, 0x71, 0x19);  /* Compression-related? */
 
 		// FIXME: Sensor-specific
 		/* Bit 5 is what matters here. Of course, it is "reserved" */
-		ov51x_i2c_write(ov511, 0x54, 0x23);
+		i2c_w(ov, 0x54, 0x23);
 
-		ov511_reg_write(dev, 0x2f, 0x80);
+		reg_w(ov, 0x2f, 0x80);
 
 		/* Mode dependent regs */
 		if ((width == 352 && height == 288) ||
 		    (width == 320 && height == 240)) {
-			b[0]=0x80; b[1]=0x02;
-			ov518_reg_write_multi(dev, 0x30, b, 2);
-			b[0]=0x90; b[1]=0x01;
-			ov518_reg_write_multi(dev, 0xc4, b, 2);
-			b[0]=0xf4; b[1]=0x01;
-			ov518_reg_write_multi(dev, 0xc6, b, 2);
-			b[0]=0xf4; b[1]=0x01;
-			ov518_reg_write_multi(dev, 0xc7, b, 2);
-			b[0]=0x8e; b[1]=0x00;
-			ov518_reg_write_multi(dev, 0xc8, b, 2);
-			b[0]=0x1a; b[1]=0x00; b[2]=0x02;
-			ov518_reg_write_multi(dev, 0xca, b, 3);
-			b[0]=0x14; b[1]=0x02;
-			ov518_reg_write_multi(dev, 0xcb, b, 2);
-			b[0]=0xd0; b[1]=0x07;
-			ov518_reg_write_multi(dev, 0xcc, b, 2);
-			b[0]=0x20; b[1]=0x00;
-			ov518_reg_write_multi(dev, 0xcd, b, 2);
-			b[0]=0x60; b[1]=0x02;
-			ov518_reg_write_multi(dev, 0xce, b, 2);
-
+			/*  640 (280h) byte iso packets */
+			ov518_reg_w32(ov, 0x30,    640, 2);	/* 280h   */
+			ov518_reg_w32(ov, 0xc4,    400, 2);	/* 190h   */
+			ov518_reg_w32(ov, 0xc6,    500, 2);	/* 1f4h   */
+			ov518_reg_w32(ov, 0xc7,    500, 2);	/* 1f4h   */
+			ov518_reg_w32(ov, 0xc8,    142, 2);	/* 8eh    */
+			ov518_reg_w32(ov, 0xca, 131098, 3);	/* 2001ah */
+			ov518_reg_w32(ov, 0xcb,    532, 2);	/* 214h   */
+			ov518_reg_w32(ov, 0xcc,   2000, 2);	/* 7d0h   */
+			ov518_reg_w32(ov, 0xcd,     32, 2);	/* 20h    */
+			ov518_reg_w32(ov, 0xce,    608, 2);	/* 260h   */
 		} else if ((width == 176 && height == 144) ||
 			   (width == 160 && height == 120)) {
-			b[0]=0x80; b[1]=0x01;
-			ov518_reg_write_multi(dev, 0x30, b, 2);
-			b[0]=0xc8; b[1]=0x00;
-			ov518_reg_write_multi(dev, 0xc4, b, 2);
-			b[0]=0x40; b[1]=0x01;
-			ov518_reg_write_multi(dev, 0xc6, b, 2);
-			b[0]=0x40; b[1]=0x01;
-			ov518_reg_write_multi(dev, 0xc7, b, 2);
-			b[0]=0x60; b[1]=0x00;
-			ov518_reg_write_multi(dev, 0xc8, b, 2);
-			b[0]=0x0f; b[1]=0x33; b[2]=0x01;
-			ov518_reg_write_multi(dev, 0xca, b, 3);
-			b[0]=0x40; b[1]=0x01;
-			ov518_reg_write_multi(dev, 0xcb, b, 2);
-			b[0]=0xec; b[1]=0x04;
-			ov518_reg_write_multi(dev, 0xcc, b, 2);
-			b[0]=0x13; b[1]=0x00;
-			ov518_reg_write_multi(dev, 0xcd, b, 2);
-			b[0]=0x6d; b[1]=0x01;
-			ov518_reg_write_multi(dev, 0xce, b, 2);
+			/*  384 (180h) byte iso packets */
+			ov518_reg_w32(ov, 0x30,    384, 2);	/* 180h   */
+			ov518_reg_w32(ov, 0xc4,    200, 2);	/* c8h    */
+			ov518_reg_w32(ov, 0xc6,    320, 2);	/* 140h   */
+			ov518_reg_w32(ov, 0xc7,    320, 2);	/* 140h   */
+			ov518_reg_w32(ov, 0xc8,     96, 2);	/* 60h    */
+			ov518_reg_w32(ov, 0xca,  78607, 3);	/* 1330fh */
+			ov518_reg_w32(ov, 0xcb,    320, 2);	/* 140h   */
+			ov518_reg_w32(ov, 0xcc,   1260, 2);	/* 4ech   */
+			ov518_reg_w32(ov, 0xcd,     19, 2);	/* 13h    */
+			ov518_reg_w32(ov, 0xce,    365, 2);	/* 16dh   */
 		} else {
 			/* Can't happen, since we already handled this case */
 			err("ov518_mode_init_regs(): **** logic error ****");
 		}
 
-		ov511_reg_write(dev, 0x2f, 0x80);
+		reg_w(ov, 0x2f, 0x80);
 
 		break;
 	}
 
-	if (ov511_restart(ov511) < 0)
+	if (ov51x_restart(ov) < 0)
 		return -EIO;
 
 	/* Reset it just for good measure */
-	if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
+	if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
 		return -EIO;
 
 	if (mlist518[i].width == 0) {
@@ -3013,29 +2962,31 @@
 
 /* This is a wrapper around the OV511, OV518, and sensor specific functions */
 static int
-mode_init_regs(struct usb_ov511 *ov511,
+mode_init_regs(struct usb_ov511 *ov,
 	       int width, int height, int mode, int sub_flag)
 {
 	int rc = 0;
 
-	if (ov511->bridge == BRG_OV518 ||
-	    ov511->bridge == BRG_OV518PLUS) {
-		rc = ov518_mode_init_regs(ov511, width, height, mode, sub_flag);
+	if (!ov || !ov->dev)
+		return -EFAULT;
+
+	if (ov->bclass == BCL_OV518) {
+		rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag);
 	} else {
-		rc = ov511_mode_init_regs(ov511, width, height, mode, sub_flag);
+		rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag);
 	}
 
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_OV7610:
 	case SEN_OV7620:
 	case SEN_OV7620AE:
 	case SEN_OV8600:
 	case SEN_OV6620:
 	case SEN_OV6630:
-		rc = set_ov_sensor_window(ov511, width, height, mode, sub_flag);
+		rc = set_ov_sensor_window(ov, width, height, mode, sub_flag);
 		break;
 	case SEN_KS0127:
 	case SEN_KS0127B:
@@ -3043,10 +2994,10 @@
 		rc = -EINVAL;
 		break;
 	case SEN_SAA7111A:
-//		rc = mode_init_saa_sensor_regs(ov511, width, height, mode, 
+//		rc = mode_init_saa_sensor_regs(ov, width, height, mode, 
 //					       sub_flag);
 
-		PDEBUG(1, "SAA status = 0X%x", ov51x_i2c_read(ov511, 0x1f));
+		PDEBUG(1, "SAA status = 0X%x", i2c_r(ov, 0x1f));
 		break;
 	default:
 		err("Unknown sensor");
@@ -3057,25 +3008,25 @@
 		return rc;
 
 	/* Sensor-independent settings */
-	rc = sensor_set_auto_brightness(ov511, ov511->auto_brt);
+	rc = sensor_set_auto_brightness(ov, ov->auto_brt);
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	rc = sensor_set_auto_exposure(ov511, ov511->auto_exp);
+	rc = sensor_set_auto_exposure(ov, ov->auto_exp);
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	rc = sensor_set_banding_filter(ov511, bandingfilter);
+	rc = sensor_set_banding_filter(ov, bandingfilter);
 	if (FATAL_ERROR(rc))
 		return rc;
 
-	if (ov511->lightfreq) {
-		rc = sensor_set_light_freq(ov511, lightfreq);
+	if (ov->lightfreq) {
+		rc = sensor_set_light_freq(ov, lightfreq);
 		if (FATAL_ERROR(rc))
 			return rc;
 	}
 
-	rc = sensor_set_backlight(ov511, ov511->backlight);
+	rc = sensor_set_backlight(ov, ov->backlight);
 	if (FATAL_ERROR(rc))
 		return rc;
 
@@ -3086,28 +3037,28 @@
  * useful for apps that use read() and do not set these.
  */
 static int 
-ov51x_set_default_params(struct usb_ov511 *ov511)
+ov51x_set_default_params(struct usb_ov511 *ov)
 {
 	int i;
 
-	PDEBUG(3, "%dx%d, RGB24", ov511->maxwidth, ov511->maxheight);
+	PDEBUG(3, "%dx%d, RGB24", ov->maxwidth, ov->maxheight);
 
 	/* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used
 	 * (using read() instead). */
 	for (i = 0; i < OV511_NUMFRAMES; i++) {
-		ov511->frame[i].width = ov511->maxwidth;
-		ov511->frame[i].height = ov511->maxheight;
-		ov511->frame[i].bytes_read = 0;
+		ov->frame[i].width = ov->maxwidth;
+		ov->frame[i].height = ov->maxheight;
+		ov->frame[i].bytes_read = 0;
 		if (force_palette)
-			ov511->frame[i].format = force_palette;
+			ov->frame[i].format = force_palette;
 		else
-			ov511->frame[i].format = VIDEO_PALETTE_RGB24;
-		ov511->frame[i].depth = ov511_get_depth(ov511->frame[i].format);
+			ov->frame[i].format = VIDEO_PALETTE_RGB24;
+		ov->frame[i].depth = get_depth(ov->frame[i].format);
 	}
 
 	/* Initialize to max width/height, RGB24 */
-	if (mode_init_regs(ov511, ov511->maxwidth, ov511->maxheight,
-			   ov511->frame[0].format, 0) < 0)
+	if (mode_init_regs(ov, ov->maxwidth, ov->maxheight,
+			   ov->frame[0].format, 0) < 0)
 		return -EINVAL;
 
 	return 0;
@@ -3121,18 +3072,17 @@
 
 /* Set analog input port of decoder */
 static int 
-decoder_set_input(struct usb_ov511 *ov511, int input)
+decoder_set_input(struct usb_ov511 *ov, int input)
 {
 	PDEBUG(4, "port %d", input);
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_SAA7111A:
 	{
 		/* Select mode */
-		ov51x_i2c_write_mask(ov511, 0x02, input, 0x07);
+		i2c_w_mask(ov, 0x02, input, 0x07);
 		/* Bypass chrominance trap for modes 4..7 */
-		ov51x_i2c_write_mask(ov511, 0x09,
-				     (input > 3) ? 0x80:0x00, 0x80);
+		i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80);
 		break;
 	}
 	default:
@@ -3144,9 +3094,9 @@
 
 /* Get ASCII name of video input */
 static int 
-decoder_get_input_name(struct usb_ov511 *ov511, int input, char *name)
+decoder_get_input_name(struct usb_ov511 *ov, int input, char *name)
 {
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_SAA7111A:
 	{
 		if (input < 0 || input > 7)
@@ -3167,11 +3117,11 @@
 
 /* Set norm (NTSC, PAL, SECAM, AUTO) */
 static int 
-decoder_set_norm(struct usb_ov511 *ov511, int norm)
+decoder_set_norm(struct usb_ov511 *ov, int norm)
 {
 	PDEBUG(4, "%d", norm);
 
-	switch (ov511->sensor) {
+	switch (ov->sensor) {
 	case SEN_SAA7111A:
 	{
 		int reg_8, reg_e;
@@ -3192,8 +3142,8 @@
 			return -EINVAL;
 		}
 
-		ov51x_i2c_write_mask(ov511, 0x08, reg_8, 0xc0);
-		ov51x_i2c_write_mask(ov511, 0x0e, reg_e, 0x70);
+		i2c_w_mask(ov, 0x08, reg_8, 0xc0);
+		i2c_w_mask(ov, 0x0e, reg_e, 0x70);
 		break;
 	}
 	default:
@@ -3240,8 +3190,8 @@
 #define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
 
 static inline void
-ov511_move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v, 
-		     int rowPixels, unsigned char * rgb, int bits)
+move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v, 
+	       int rowPixels, unsigned char * rgb, int bits)
 {
 	const int rvScale = 91881;
 	const int guScale = -22553;
@@ -3311,10 +3261,10 @@
  **********************************************************************/
 
 /* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the
- * array at pOut is specified by w.
+ * image at pOut is specified by w.
  */
 static inline void 
-ov511_make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
+make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
 {
 	unsigned char *pOut1 = pOut;
 	int x, y;
@@ -3352,7 +3302,7 @@
 	for (y = 0; y < frame->rawheight - 1; y += 8) {
 		pOut = pOutLine;
 		for (x = 0; x < frame->rawwidth - 1; x += 8) {
-			ov511_make_8x8(pIn, pOut, frame->rawwidth);
+			make_8x8(pIn, pOut, frame->rawwidth);
 			pIn += 64;
 			pOut += 8;
 		}
@@ -3411,8 +3361,8 @@
 	for (y = 0; y < frame->rawheight - 1; y += 16) {
 		pOut = pOutLine;
 		for (x = 0; x < frame->rawwidth - 1; x += 16) {
-			ov511_make_8x8(pIn, pOut, w);
-			ov511_make_8x8(pIn + 64, pOut + a/4, w);
+			make_8x8(pIn, pOut, w);
+			make_8x8(pIn + 64, pOut + a/4, w);
 			pIn += 384;
 			pOut += 8;
 		}
@@ -3426,7 +3376,7 @@
 	for (y = 0; y < frame->rawheight - 1; y += 8) {
 		pOut = pOutLine;
 		for (x = 0; x < frame->rawwidth - 1; x += 8) {
-			ov511_make_8x8(pIn, pOut, frame->rawwidth);
+			make_8x8(pIn, pOut, frame->rawwidth);
 			pIn += 64;
 			pOut += 8;
 			if ((++k) > 3) {
@@ -3483,17 +3433,17 @@
  *
  **********************************************************************/
 
-/* Chooses a decompression module, locks it, and sets ov511->decomp_ops
+/* Chooses a decompression module, locks it, and sets ov->decomp_ops
  * accordingly. Returns -ENXIO if decompressor is not available, otherwise
  * returns 0 if no other error.
  */
 static int 
-ov51x_request_decompressor(struct usb_ov511 *ov511)
+request_decompressor(struct usb_ov511 *ov)
 {
-	if (!ov511)
+	if (!ov)
 		return -ENODEV;
 
-	if (ov511->decomp_ops) {
+	if (ov->decomp_ops) {
 		err("ERROR: Decompressor already requested!");
 		return -EINVAL;
 	}
@@ -3501,24 +3451,23 @@
 	lock_kernel();
 
 	/* Try to get MMX, and fall back on no-MMX if necessary */
-	if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
+	if (ov->bclass == BCL_OV511) {
 		if (ov511_mmx_decomp_ops) {
 			PDEBUG(3, "Using OV511 MMX decompressor");
-			ov511->decomp_ops = ov511_mmx_decomp_ops;
+			ov->decomp_ops = ov511_mmx_decomp_ops;
 		} else if (ov511_decomp_ops) {
 			PDEBUG(3, "Using OV511 decompressor");
-			ov511->decomp_ops = ov511_decomp_ops;
+			ov->decomp_ops = ov511_decomp_ops;
 		} else {
 			err("No decompressor available");
 		}
-	} else if (ov511->bridge == BRG_OV518 ||
-		   ov511->bridge == BRG_OV518PLUS) {
+	} else if (ov->bclass == BCL_OV518) {
 		if (ov518_mmx_decomp_ops) {
 			PDEBUG(3, "Using OV518 MMX decompressor");
-			ov511->decomp_ops = ov518_mmx_decomp_ops;
+			ov->decomp_ops = ov518_mmx_decomp_ops;
 		} else if (ov518_decomp_ops) {
 			PDEBUG(3, "Using OV518 decompressor");
-			ov511->decomp_ops = ov518_decomp_ops;
+			ov->decomp_ops = ov518_decomp_ops;
 		} else {
 			err("No decompressor available");
 		}
@@ -3526,13 +3475,13 @@
 		err("Unknown bridge");
 	}
 
-	if (ov511->decomp_ops) {
-		if (!ov511->decomp_ops->decomp_lock) {
-			ov511->decomp_ops = NULL;
+	if (ov->decomp_ops) {
+		if (!ov->decomp_ops->decomp_lock) {
+			ov->decomp_ops = NULL;
 			unlock_kernel();
 			return -ENOSYS;
 		}
-		ov511->decomp_ops->decomp_lock();
+		ov->decomp_ops->decomp_lock();
 		unlock_kernel();
 		return 0;
 	} else {
@@ -3541,25 +3490,25 @@
 	}
 }
 
-/* Unlocks decompression module and nulls ov511->decomp_ops. Safe to call even
- * if ov511->decomp_ops is NULL.
+/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even
+ * if ov->decomp_ops is NULL.
  */
 static void 
-ov51x_release_decompressor(struct usb_ov511 *ov511)
+release_decompressor(struct usb_ov511 *ov)
 {
 	int released = 0;	/* Did we actually do anything? */
 
-	if (!ov511)
+	if (!ov)
 		return;
 
 	lock_kernel();
 
-	if (ov511->decomp_ops && ov511->decomp_ops->decomp_unlock) {
-		ov511->decomp_ops->decomp_unlock();
+	if (ov->decomp_ops && ov->decomp_ops->decomp_unlock) {
+		ov->decomp_ops->decomp_unlock();
 		released = 1;
 	}
 
-	ov511->decomp_ops = NULL;
+	ov->decomp_ops = NULL;
 	
 	unlock_kernel();
 
@@ -3568,26 +3517,26 @@
 }
 
 static void 
-ov51x_decompress(struct usb_ov511 *ov511, struct ov511_frame *frame,
-		 unsigned char *pIn0, unsigned char *pOut0)
+decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
+	   unsigned char *pIn0, unsigned char *pOut0)
 {
-	if (!ov511->decomp_ops)
-		if (ov51x_request_decompressor(ov511))
+	if (!ov->decomp_ops)
+		if (request_decompressor(ov))
 			return;
 
 	PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd);
 
 	if (frame->format == VIDEO_PALETTE_GREY 
-	    && ov511->decomp_ops->decomp_400) {
-		int ret = ov511->decomp_ops->decomp_400(
+	    && ov->decomp_ops->decomp_400) {
+		int ret = ov->decomp_ops->decomp_400(
 			pIn0,
 			pOut0,
 			frame->rawwidth,
 			frame->rawheight,
 			frame->bytes_recvd);
 		PDEBUG(4, "DEBUG: decomp_400 returned %d", ret);
-	} else if (ov511->decomp_ops->decomp_420) {
-		int ret = ov511->decomp_ops->decomp_420(
+	} else if (ov->decomp_ops->decomp_420) {
+		int ret = ov->decomp_ops->decomp_420(
 			pIn0,
 			pOut0,
 			frame->rawwidth,
@@ -3627,8 +3576,8 @@
 			u = (*pU++) - 128;
 			v = (*pV++) - 128;
 
-			ov511_move_420_block(y00, y01, y10, y11, u, v,
-					     frame->width, pOut, bits);
+			move_420_block(y00, y01, y10, y11, u, v,
+				       frame->width, pOut, bits);
 	
 			pY += 2;
 			pOut += 2 * bytes;
@@ -3783,11 +3732,11 @@
  * 	4. Fix the RGB offset, if necessary
  */
 static void 
-ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
+ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
 {
 	if (dumppix) {
 		memset(frame->data, 0, 
-			MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
+			MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
 		PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd);
 		memmove(frame->data, frame->rawdata, frame->bytes_recvd);
 		return;
@@ -3796,9 +3745,9 @@
 	/* YUV400 must be handled separately */
 	if (frame->format == VIDEO_PALETTE_GREY) {
 		/* Deinterlace frame, if necessary */
-		if (ov511->sensor == SEN_SAA7111A && frame->rawheight == 480) {
+		if (ov->sensor == SEN_SAA7111A && frame->rawheight == 480) {
 			if (frame->compressed)
-				ov51x_decompress(ov511, frame, frame->rawdata,
+				decompress(ov, frame, frame->rawdata,
 						 frame->tempdata);
 			else
 				yuv400raw_to_yuv400p(frame, frame->rawdata,
@@ -3808,7 +3757,7 @@
 			            frame->data);
 		} else {
 			if (frame->compressed)
-				ov51x_decompress(ov511, frame, frame->rawdata,
+				decompress(ov, frame, frame->rawdata,
 						 frame->data);
 			else
 				yuv400raw_to_yuv400p(frame, frame->rawdata,
@@ -3820,12 +3769,12 @@
 
 	/* Process frame->data to frame->rawdata */
 	if (frame->compressed)
-		ov51x_decompress(ov511, frame, frame->rawdata, frame->tempdata);
+		decompress(ov, frame, frame->rawdata, frame->tempdata);
 	else
 		yuv420raw_to_yuv420p(frame, frame->rawdata, frame->tempdata);
 
 	/* Deinterlace frame, if necessary */
-	if (ov511->sensor == SEN_SAA7111A && frame->rawheight == 480) {
+	if (ov->sensor == SEN_SAA7111A && frame->rawheight == 480) {
 		memmove(frame->rawdata, frame->tempdata,
 			MAX_RAW_DATA_SIZE(frame->width, frame->height));
 		deinterlace(frame, RAWFMT_YUV420, frame->rawdata,
@@ -3879,7 +3828,7 @@
  **********************************************************************/
 
 static int 
-ov511_move_data(struct usb_ov511 *ov511, urb_t *urb)
+ov511_move_data(struct usb_ov511 *ov, struct urb *urb)
 {
 	unsigned char *cdata;
 	int data_size, num, offset, i, totlen = 0;
@@ -3889,7 +3838,7 @@
 
 	PDEBUG(5, "Moving %d packets", urb->number_of_packets);
 
-	data_size = ov511->packet_size - 1;
+	data_size = ov->packet_size - 1;
 
 	for (i = 0; i < urb->number_of_packets; i++) {
 		int n = urb->iso_frame_desc[i].actual_length;
@@ -3900,15 +3849,15 @@
 
 		cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 
-		aPackNum[i] = n ? cdata[ov511->packet_size - 1] : -1;
+		aPackNum[i] = n ? cdata[ov->packet_size - 1] : -1;
 
-		if (!n || ov511->curframe == -1)
+		if (!n || ov->curframe == -1)
 			continue;
 
 		if (st)
 			PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
 
-		frame = &ov511->frame[ov511->curframe];
+		frame = &ov->frame[ov->curframe];
 
 		/* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
 		 * byte non-zero. The EOF packet has image width/height in the
@@ -3926,7 +3875,7 @@
 
 		if (printph) {
 			info("packet header (%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
-				cdata[ov511->packet_size - 1],
+				cdata[ov->packet_size - 1],
 				cdata[0], cdata[1], cdata[2], cdata[3], cdata[4], cdata[5],
 				cdata[6], cdata[7], cdata[8], cdata[9], cdata[10], cdata[11]);
 		}
@@ -3940,7 +3889,7 @@
 		/* Frame end */
 		if (cdata[8] & 0x80) {
 			ts = (struct timeval *)(frame->data 
-			      + MAX_FRAME_SIZE(ov511->maxwidth, ov511->maxheight));
+			      + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
 			do_gettimeofday(ts);
 
 			/* Get the actual frame size from the EOF header */
@@ -3948,21 +3897,21 @@
 			frame->rawheight = ((int)(cdata[10]) + 1) * 8;
 
 	 		PDEBUG(4, "Frame end, curframe = %d, packnum=%d, hw=%d, vw=%d, recvd=%d",
-				ov511->curframe,
-				(int)(cdata[ov511->packet_size - 1]),
+				ov->curframe,
+				(int)(cdata[ov->packet_size - 1]),
 				frame->rawwidth,
 				frame->rawheight,
 				frame->bytes_recvd);
 
 			/* Validate the header data */
-			RESTRICT_TO_RANGE(frame->rawwidth, ov511->minwidth, ov511->maxwidth);
-			RESTRICT_TO_RANGE(frame->rawheight, ov511->minheight, ov511->maxheight);
+			RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
+			RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
 
 			/* Don't allow byte count to exceed buffer size */
 			RESTRICT_TO_RANGE(frame->bytes_recvd,
 					  8, 
-					  MAX_RAW_DATA_SIZE(ov511->maxwidth,
-					                    ov511->maxheight));
+					  MAX_RAW_DATA_SIZE(ov->maxwidth,
+					                    ov->maxheight));
 
 			if (frame->scanstate == STATE_LINES) {
 		    		int iFrameNext;
@@ -3976,20 +3925,20 @@
 
 				/* If next frame is ready or grabbing,
                                  * point to it */
-				iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
-				if (ov511->frame[iFrameNext].grabstate == FRAME_READY
-				    || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {
-					ov511->curframe = iFrameNext;
-					ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
+				iFrameNext = (ov->curframe + 1) % OV511_NUMFRAMES;
+				if (ov->frame[iFrameNext].grabstate == FRAME_READY
+				    || ov->frame[iFrameNext].grabstate == FRAME_GRABBING) {
+					ov->curframe = iFrameNext;
+					ov->frame[iFrameNext].scanstate = STATE_SCANNING;
 				} else {
 					if (frame->grabstate == FRAME_DONE) {
 						PDEBUG(4, "Frame done! congratulations");
 					} else {
 						PDEBUG(4, "Frame not ready? state = %d",
-							ov511->frame[iFrameNext].grabstate);
+							ov->frame[iFrameNext].grabstate);
 					}
 
-					ov511->curframe = -1;
+					ov->curframe = -1;
 				}
 			} else {
 				PDEBUG(5, "Frame done, but not scanning");
@@ -3999,7 +3948,7 @@
 			 */
 		} else {
 			/* Frame start */
-			PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
+			PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
 
 			/* Check to see if it's a snapshot frame */
 			/* FIXME?? Should the snapshot reset go here? Performance? */
@@ -4048,24 +3997,24 @@
 		/* Dump all data exactly as received */
 		if (dumppix == 2) {
 			frame->bytes_recvd += n - 1;
-			if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+			if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
 				memmove(frame->rawdata + frame->bytes_recvd - (n - 1),
 					&cdata[0], n - 1);
 			else
 				PDEBUG(3, "Raw data buffer overrun!! (%d)",
 					frame->bytes_recvd
-					- MAX_RAW_DATA_SIZE(ov511->maxwidth,
-							    ov511->maxheight));
+					- MAX_RAW_DATA_SIZE(ov->maxwidth,
+							    ov->maxheight));
 		} else if (!frame->compressed && !remove_zeros) {
 			frame->bytes_recvd += num;
-			if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+			if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
 				memmove(frame->rawdata + frame->bytes_recvd - num,
 					&cdata[offset], num);
 			else
 				PDEBUG(3, "Raw data buffer overrun!! (%d)",
 					frame->bytes_recvd
-					- MAX_RAW_DATA_SIZE(ov511->maxwidth,
-							    ov511->maxheight));
+					- MAX_RAW_DATA_SIZE(ov->maxwidth,
+							    ov->maxheight));
 		} else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */
 			int b, in = 0, allzero, copied=0;
 			if (offset) {
@@ -4088,7 +4037,7 @@
 					/* Don't copy it */
 				} else {
 					if (frame->bytes_recvd + copied + 32
-					    <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight)) {
+					    <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight)) {
 						memmove(frame->rawdata + frame->bytes_recvd + copied,
 							&cdata[in], 32);
 						copied += 32;
@@ -4112,7 +4061,7 @@
 }
 
 static int 
-ov518_move_data(struct usb_ov511 *ov511, urb_t *urb)
+ov518_move_data(struct usb_ov511 *ov, struct urb *urb)
 {
 	unsigned char *cdata;
 	int i, data_size, totlen = 0;
@@ -4122,7 +4071,7 @@
 	PDEBUG(5, "Moving %d packets", urb->number_of_packets);
 
 	/* OV518(+) has no packet numbering */
-	data_size = ov511->packet_size;
+	data_size = ov->packet_size;
 
 	for (i = 0; i < urb->number_of_packets; i++) {
 		int n = urb->iso_frame_desc[i].actual_length;
@@ -4138,7 +4087,7 @@
 			continue;
 		}
 
-		if (ov511->curframe == -1) {
+		if (ov->curframe == -1) {
 			PDEBUG(4, "No frame currently active");
 			continue;
 		}
@@ -4146,21 +4095,7 @@
 		if (st)
 			PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
 
-		frame = &ov511->frame[ov511->curframe];
-
-#if 0
-		{
-			int d;
-			/* Print all data */
-			for (d = 0; d <= data_size - 16; d += 16) {
-				info("%4x: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", d,
-					cdata[d], cdata[d+1], cdata[d+2], cdata[d+3],
-					cdata[d+4], cdata[d+5], cdata[d+6], cdata[d+7],
-					cdata[d+8], cdata[d+9], cdata[d+10], cdata[d+11],
-					cdata[d+12], cdata[d+13], cdata[d+14], cdata[d+15]);
-			}
-		}
-#endif
+		frame = &ov->frame[ov->curframe];
 
 		if (printph) {
 			info("packet header: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
@@ -4178,7 +4113,7 @@
 				goto eof;
 			} else { //scanstate == STATE_SCANNING
 				/* Frame start */
-				PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
+				PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
 				goto sof;
 			}
 		} else {
@@ -4187,11 +4122,11 @@
 	
 eof:
 		ts = (struct timeval *)(frame->data
-		      + MAX_FRAME_SIZE(ov511->maxwidth, ov511->maxheight));
+		      + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
 		do_gettimeofday(ts);
 
  		PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d",
-			ov511->curframe,
+			ov->curframe,
 			(int)(cdata[9]), (int)(cdata[10]), frame->bytes_recvd);
 
 		// FIXME: Since we don't know the header formats yet,
@@ -4200,13 +4135,13 @@
 		frame->rawheight = frame->height;
 
 		/* Validate the header data */
-		RESTRICT_TO_RANGE(frame->rawwidth, ov511->minwidth, ov511->maxwidth);
-		RESTRICT_TO_RANGE(frame->rawheight, ov511->minheight, ov511->maxheight);
+		RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
+		RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
 
 		/* Don't allow byte count to exceed buffer size */
 		RESTRICT_TO_RANGE(frame->bytes_recvd,
 				  8, 
-				  MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
+				  MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight));
 
 		if (frame->scanstate == STATE_LINES) {
 	    		int iFrameNext;
@@ -4220,21 +4155,21 @@
 
 			/* If next frame is ready or grabbing,
 			 * point to it */
-			iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
-			if (ov511->frame[iFrameNext].grabstate == FRAME_READY
-			    || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {
-				ov511->curframe = iFrameNext;
-				ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
-				frame = &ov511->frame[iFrameNext];
+			iFrameNext = (ov->curframe + 1) % OV511_NUMFRAMES;
+			if (ov->frame[iFrameNext].grabstate == FRAME_READY
+			    || ov->frame[iFrameNext].grabstate == FRAME_GRABBING) {
+				ov->curframe = iFrameNext;
+				ov->frame[iFrameNext].scanstate = STATE_SCANNING;
+				frame = &ov->frame[iFrameNext];
 			} else {
 				if (frame->grabstate == FRAME_DONE) {
 					PDEBUG(4, "Frame done! congratulations");
 				} else {
 					PDEBUG(4, "Frame not ready? state = %d",
-						ov511->frame[iFrameNext].grabstate);
+						ov->frame[iFrameNext].grabstate);
 				}
 
-				ov511->curframe = -1;
+				ov->curframe = -1;
 				PDEBUG(4, "SOF dropped (no active frame)");
 				continue;  /* Nowhere to store this frame */
 			}
@@ -4267,31 +4202,26 @@
 		/* Dump all data exactly as received */
 		if (dumppix == 2) {
 			frame->bytes_recvd += n;
-			if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+			if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
 				memmove(frame->rawdata + frame->bytes_recvd - n,
 					&cdata[0], n);
 			else
 				PDEBUG(3, "Raw data buffer overrun!! (%d)",
 					frame->bytes_recvd
-					- MAX_RAW_DATA_SIZE(ov511->maxwidth,
-							    ov511->maxheight));
+					- MAX_RAW_DATA_SIZE(ov->maxwidth,
+							    ov->maxheight));
 		} else {
 			/* All incoming data are divided into 8-byte segments. If the
 			 * segment contains all zero bytes, it must be skipped. These
 			 * zero-segments allow the OV518 to mainain a constant data rate
 			 * regardless of the effectiveness of the compression. Segments
 			 * are aligned relative to the beginning of each isochronous
-			 * packet. The first segment is a header.
+			 * packet. The first segment is a header (the decompressor
+			 * skips it later).
 			 */
 
 			int b, in = 0, allzero, copied=0;
 
-// Decompressor expects the header
-#if 0
-			if (frame->bytes_recvd == 0)
-				in += 8;  /* Skip header */
-#endif
-
 			while (in < n) {
 				allzero = 1;
 				for (b = 0; b < 8; b++) {
@@ -4305,7 +4235,7 @@
 				/* Don't copy it */
 				} else {
 					if (frame->bytes_recvd + copied + 8
-					    <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight)) {
+					    <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight)) {
 						memmove(frame->rawdata + frame->bytes_recvd + copied,
 							&cdata[in], 8);
 						copied += 8;
@@ -4323,43 +4253,41 @@
 }
 
 static void 
-ov511_isoc_irq(struct urb *urb)
+ov51x_isoc_irq(struct urb *urb)
 {
 	int len;
-	struct usb_ov511 *ov511;
+	struct usb_ov511 *ov;
 
 	if (!urb->context) {
 		PDEBUG(4, "no context");
 		return;
 	}
 
-	ov511 = (struct usb_ov511 *) urb->context;
+	ov = (struct usb_ov511 *) urb->context;
 
-	if (!ov511->dev || !ov511->user) {
+	if (!ov || !ov->dev || !ov->user) {
 		PDEBUG(4, "no device, or not open");
 		return;
 	}
 
-	if (!ov511->streaming) {
+	if (!ov->streaming) {
 		PDEBUG(4, "hmmm... not streaming, but got interrupt");
 		return;
 	}
 
 	/* Copy the data received into our frame buffer */
-	if (ov511->curframe >= 0) {
-		if (ov511->bridge == BRG_OV511 || 
-		    ov511->bridge == BRG_OV511PLUS)
-			len = ov511_move_data(ov511, urb);
-		else if (ov511->bridge == BRG_OV518 ||
-			 ov511->bridge == BRG_OV518PLUS)
-			len = ov518_move_data(ov511, urb);
+	if (ov->curframe >= 0) {
+		if (ov->bclass == BCL_OV511)
+			len = ov511_move_data(ov, urb);
+		else if (ov->bclass == BCL_OV518)
+			len = ov518_move_data(ov, urb);
 		else
-			err("Unknown bridge device (%d)", ov511->bridge);
-	} else if (waitqueue_active(&ov511->wq)) {
-		wake_up_interruptible(&ov511->wq);
+			err("Unknown bridge device (%d)", ov->bridge);
+	} else if (waitqueue_active(&ov->wq)) {
+		wake_up_interruptible(&ov->wq);
 	}
 
-	urb->dev = ov511->dev;
+	urb->dev = ov->dev;
 
 	return;
 }
@@ -4371,16 +4299,16 @@
  ***************************************************************************/
 
 static int 
-ov511_init_isoc(struct usb_ov511 *ov511)
+ov51x_init_isoc(struct usb_ov511 *ov)
 {
-	urb_t *urb;
+	struct urb *urb;
 	int fx, err, n, size;
 
 	PDEBUG(3, "*** Initializing capture ***");
 
-	ov511->curframe = -1;
+	ov->curframe = -1;
 
-	if (ov511->bridge == BRG_OV511) {
+	if (ov->bridge == BRG_OV511) {
 		if (cams == 1)				size = 993;
 		else if (cams == 2)			size = 513;
 		else if (cams == 3 || cams == 4)	size = 257;
@@ -4388,7 +4316,7 @@
 			err("\"cams\" parameter too high!");
 			return -1;
 		}
-	} else if (ov511->bridge == BRG_OV511PLUS) {
+	} else if (ov->bridge == BRG_OV511PLUS) {
 		if (cams == 1)				size = 961;
 		else if (cams == 2)			size = 513;
 		else if (cams == 3 || cams == 4)	size = 257;
@@ -4398,8 +4326,7 @@
 			err("\"cams\" parameter too high!");
 			return -1;
 		}
-	} else if (ov511->bridge == BRG_OV518 ||
-		   ov511->bridge == BRG_OV518PLUS) {
+	} else if (ov->bclass == BCL_OV518) {
 		if (cams == 1)				size = 896;
 		else if (cams == 2)			size = 512;
 		else if (cams == 3 || cams == 4)	size = 256;
@@ -4415,14 +4342,13 @@
 
 	if (packetsize == -1) {
 		// FIXME: OV518 is hardcoded to 15 FPS (alternate 5) for now
-		if (ov511->bridge == BRG_OV518 ||
-		    ov511->bridge == BRG_OV518PLUS)
-			ov511_set_packet_size(ov511, 640);
+		if (ov->bclass == BCL_OV518)
+			ov51x_set_packet_size(ov, 640);
 		else
-			ov511_set_packet_size(ov511, size);
+			ov51x_set_packet_size(ov, size);
 	} else {
 			info("Forcing packet size to %d", packetsize);
-			ov511_set_packet_size(ov511, packetsize);
+			ov51x_set_packet_size(ov, packetsize);
 	}
 
 	for (n = 0; n < OV511_NUMSBUF; n++) {
@@ -4432,32 +4358,30 @@
 			err("init isoc: usb_alloc_urb ret. NULL");
 			return -ENOMEM;
 		}
-		ov511->sbuf[n].urb = urb;
-		urb->dev = ov511->dev;
-		urb->context = ov511;
-		urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS);
+		ov->sbuf[n].urb = urb;
+		urb->dev = ov->dev;
+		urb->context = ov;
+		urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS);
 		urb->transfer_flags = USB_ISO_ASAP;
-		urb->transfer_buffer = ov511->sbuf[n].data;
-		urb->complete = ov511_isoc_irq;
+		urb->transfer_buffer = ov->sbuf[n].data;
+		urb->complete = ov51x_isoc_irq;
 		urb->number_of_packets = FRAMES_PER_DESC;
-		urb->transfer_buffer_length =
-		 ov511->packet_size * FRAMES_PER_DESC;
+		urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC;
 		for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
-			urb->iso_frame_desc[fx].offset = 
-			 ov511->packet_size * fx;
-			urb->iso_frame_desc[fx].length = ov511->packet_size;
+			urb->iso_frame_desc[fx].offset = ov->packet_size * fx;
+			urb->iso_frame_desc[fx].length = ov->packet_size;
 		}
 	}
 
-	ov511->streaming = 1;
+	ov->streaming = 1;
 
-	ov511->sbuf[OV511_NUMSBUF - 1].urb->next = ov511->sbuf[0].urb;
+	ov->sbuf[OV511_NUMSBUF - 1].urb->next = ov->sbuf[0].urb;
 	for (n = 0; n < OV511_NUMSBUF - 1; n++)
-		ov511->sbuf[n].urb->next = ov511->sbuf[n+1].urb;
+		ov->sbuf[n].urb->next = ov->sbuf[n+1].urb;
 
 	for (n = 0; n < OV511_NUMSBUF; n++) {
-		ov511->sbuf[n].urb->dev = ov511->dev;
-		err = usb_submit_urb(ov511->sbuf[n].urb);
+		ov->sbuf[n].urb->dev = ov->dev;
+		err = usb_submit_urb(ov->sbuf[n].urb);
 		if (err)
 			err("init isoc: usb_submit_urb(%d) ret %d", n, err);
 	}
@@ -4466,51 +4390,51 @@
 }
 
 static void 
-ov511_stop_isoc(struct usb_ov511 *ov511)
+ov51x_stop_isoc(struct usb_ov511 *ov)
 {
 	int n;
 
-	if (!ov511->streaming || !ov511->dev)
+	if (!ov->streaming || !ov->dev)
 		return;
 
 	PDEBUG(3, "*** Stopping capture ***");
 
-	ov511_set_packet_size(ov511, 0);
+	ov51x_set_packet_size(ov, 0);
 
-	ov511->streaming = 0;
+	ov->streaming = 0;
 
 	/* Unschedule all of the iso td's */
 	for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
-		if (ov511->sbuf[n].urb) {
-			ov511->sbuf[n].urb->next = NULL;
-			usb_unlink_urb(ov511->sbuf[n].urb);
-			usb_free_urb(ov511->sbuf[n].urb);
-			ov511->sbuf[n].urb = NULL;
+		if (ov->sbuf[n].urb) {
+			ov->sbuf[n].urb->next = NULL;
+			usb_unlink_urb(ov->sbuf[n].urb);
+			usb_free_urb(ov->sbuf[n].urb);
+			ov->sbuf[n].urb = NULL;
 		}
 	}
 }
 
 static int 
-ov511_new_frame(struct usb_ov511 *ov511, int framenum)
+ov51x_new_frame(struct usb_ov511 *ov, int framenum)
 {
 	struct ov511_frame *frame;
 	int newnum;
 
-	PDEBUG(4, "ov511->curframe = %d, framenum = %d", ov511->curframe,
-		framenum);
-	if (!ov511->dev)
+	PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum);
+
+	if (!ov->dev)
 		return -1;
 
 	/* If we're not grabbing a frame right now and the other frame is */
 	/* ready to be grabbed into, then use it instead */
-	if (ov511->curframe == -1) {
+	if (ov->curframe == -1) {
 		newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
-		if (ov511->frame[newnum].grabstate == FRAME_READY)
+		if (ov->frame[newnum].grabstate == FRAME_READY)
 			framenum = newnum;
 	} else
 		return 0;
 
-	frame = &ov511->frame[framenum];
+	frame = &ov->frame[framenum];
 
 	PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum, 
 	       frame->width, frame->height);
@@ -4519,16 +4443,16 @@
 	frame->scanstate = STATE_SCANNING;
 	frame->snapshot = 0;
 
-	ov511->curframe = framenum;
+	ov->curframe = framenum;
 
 	/* Make sure it's not too big */
-	if (frame->width > ov511->maxwidth)
-		frame->width = ov511->maxwidth;
+	if (frame->width > ov->maxwidth)
+		frame->width = ov->maxwidth;
 
 	frame->width &= ~7L;		/* Multiple of 8 */
 
-	if (frame->height > ov511->maxheight)
-		frame->height = ov511->maxheight;
+	if (frame->height > ov->maxheight)
+		frame->height = ov->maxheight;
 
 	frame->height &= ~3L;		/* Multiple of 4 */
 
@@ -4540,84 +4464,86 @@
  * Buffer management
  *
  ***************************************************************************/
+
 static int 
-ov511_alloc(struct usb_ov511 *ov511)
+ov51x_alloc(struct usb_ov511 *ov)
 {
 	int i;
-	int w = ov511->maxwidth;
-	int h = ov511->maxheight;
+	const int w = ov->maxwidth;
+	const int h = ov->maxheight;
+	const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h);
+	const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
 
 	PDEBUG(4, "entered");
-	down(&ov511->buf_lock);
+	down(&ov->buf_lock);
 
-	if (ov511->buf_state == BUF_PEND_DEALLOC) {
-		ov511->buf_state = BUF_ALLOCATED;
-		del_timer(&ov511->buf_timer);
+	if (ov->buf_state == BUF_PEND_DEALLOC) {
+		ov->buf_state = BUF_ALLOCATED;
+		del_timer(&ov->buf_timer);
 	}
 
-	if (ov511->buf_state == BUF_ALLOCATED)
+	if (ov->buf_state == BUF_ALLOCATED)
 		goto out;
 
-	ov511->fbuf = rvmalloc(OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
-	if (!ov511->fbuf)
+	ov->fbuf = rvmalloc(data_bufsize);
+	if (!ov->fbuf)
 		goto error;
 
-	ov511->rawfbuf = vmalloc(OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
-	if (!ov511->rawfbuf) {
-		rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
-		ov511->fbuf = NULL;
+	ov->rawfbuf = vmalloc(raw_bufsize);
+	if (!ov->rawfbuf) {
+		rvfree(ov->fbuf, data_bufsize);
+		ov->fbuf = NULL;
 		goto error;
 	}
-	memset(ov511->rawfbuf, 0, OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
+	memset(ov->rawfbuf, 0, raw_bufsize);
 
-	ov511->tempfbuf = vmalloc(OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
-	if (!ov511->tempfbuf) {
-		vfree(ov511->rawfbuf);
-		ov511->rawfbuf = NULL;
-		rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
-		ov511->fbuf = NULL;
+	ov->tempfbuf = vmalloc(raw_bufsize);
+	if (!ov->tempfbuf) {
+		vfree(ov->rawfbuf);
+		ov->rawfbuf = NULL;
+		rvfree(ov->fbuf, data_bufsize);
+		ov->fbuf = NULL;
 		goto error;
 	}
-	memset(ov511->tempfbuf, 0, OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
+	memset(ov->tempfbuf, 0, raw_bufsize);
 
 	for (i = 0; i < OV511_NUMSBUF; i++) {
-		ov511->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
+		ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
 			MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL);
-		if (!ov511->sbuf[i].data) {
+		if (!ov->sbuf[i].data) {
 			while (--i) {
-				kfree(ov511->sbuf[i].data);
-				ov511->sbuf[i].data = NULL;
+				kfree(ov->sbuf[i].data);
+				ov->sbuf[i].data = NULL;
 			}
-			vfree(ov511->tempfbuf);
-			ov511->tempfbuf = NULL;
-			vfree(ov511->rawfbuf);
-			ov511->rawfbuf = NULL;
-			rvfree(ov511->fbuf,
-			       OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
-			ov511->fbuf = NULL;
+			vfree(ov->tempfbuf);
+			ov->tempfbuf = NULL;
+			vfree(ov->rawfbuf);
+			ov->rawfbuf = NULL;
+			rvfree(ov->fbuf, data_bufsize);
+			ov->fbuf = NULL;
 
 			goto error;
 		}
-		PDEBUG(4, "sbuf[%d] @ %p", i, ov511->sbuf[i].data);
+		PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data);
 	}
 
 	for (i = 0; i < OV511_NUMFRAMES; i++) {
-		ov511->frame[i].data = ov511->fbuf + i * MAX_DATA_SIZE(w, h);
-		ov511->frame[i].rawdata = ov511->rawfbuf 
+		ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h);
+		ov->frame[i].rawdata = ov->rawfbuf 
 		 + i * MAX_RAW_DATA_SIZE(w, h);
-		ov511->frame[i].tempdata = ov511->tempfbuf 
+		ov->frame[i].tempdata = ov->tempfbuf 
 		 + i * MAX_RAW_DATA_SIZE(w, h);
-		PDEBUG(4, "frame[%d] @ %p", i, ov511->frame[i].data);
+		PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data);
 	}
 
-	ov511->buf_state = BUF_ALLOCATED;
+	ov->buf_state = BUF_ALLOCATED;
 out:
-	up(&ov511->buf_lock);
+	up(&ov->buf_lock);
 	PDEBUG(4, "leaving");
 	return 0;
 error:
-	ov511->buf_state = BUF_NOT_ALLOCATED;
-	up(&ov511->buf_lock);
+	ov->buf_state = BUF_NOT_ALLOCATED;
+	up(&ov->buf_lock);
 	PDEBUG(4, "errored");
 	return -ENOMEM;
 }
@@ -4628,206 +4554,212 @@
  *   them if you explicitly free them somewhere else!
  */
 static void 
-ov511_do_dealloc(struct usb_ov511 *ov511)
+ov51x_do_dealloc(struct usb_ov511 *ov)
 {
 	int i;
 	PDEBUG(4, "entered");
 
-	if (ov511->fbuf) {
-		rvfree(ov511->fbuf, OV511_NUMFRAMES
-		       * MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
-		ov511->fbuf = NULL;
+	if (ov->fbuf) {
+		rvfree(ov->fbuf, OV511_NUMFRAMES
+		       * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
+		ov->fbuf = NULL;
 	}
 
-	if (ov511->rawfbuf) {
-		vfree(ov511->rawfbuf);
-		ov511->rawfbuf = NULL;
+	if (ov->rawfbuf) {
+		vfree(ov->rawfbuf);
+		ov->rawfbuf = NULL;
 	}
 
-	if (ov511->tempfbuf) {
-		vfree(ov511->tempfbuf);
-		ov511->tempfbuf = NULL;
+	if (ov->tempfbuf) {
+		vfree(ov->tempfbuf);
+		ov->tempfbuf = NULL;
 	}
 
 	for (i = 0; i < OV511_NUMSBUF; i++) {
-		if (ov511->sbuf[i].data) {
-			kfree(ov511->sbuf[i].data);
-			ov511->sbuf[i].data = NULL;
+		if (ov->sbuf[i].data) {
+			kfree(ov->sbuf[i].data);
+			ov->sbuf[i].data = NULL;
 		}
 	}
 
 	for (i = 0; i < OV511_NUMFRAMES; i++) {
-		ov511->frame[i].data = NULL;
-		ov511->frame[i].rawdata = NULL;
-		ov511->frame[i].tempdata = NULL;
+		ov->frame[i].data = NULL;
+		ov->frame[i].rawdata = NULL;
+		ov->frame[i].tempdata = NULL;
 	}
 
 	PDEBUG(4, "buffer memory deallocated");
-	ov511->buf_state = BUF_NOT_ALLOCATED;
+	ov->buf_state = BUF_NOT_ALLOCATED;
 	PDEBUG(4, "leaving");
 }
 
 static void 
-ov511_buf_callback(unsigned long data)
+ov51x_buf_callback(unsigned long data)
 {
-	struct usb_ov511 *ov511 = (struct usb_ov511 *)data;
+	struct usb_ov511 *ov = (struct usb_ov511 *)data;
 	PDEBUG(4, "entered");
-	down(&ov511->buf_lock);
+	down(&ov->buf_lock);
 
-	if (ov511->buf_state == BUF_PEND_DEALLOC)
-		ov511_do_dealloc(ov511);
+	if (ov->buf_state == BUF_PEND_DEALLOC)
+		ov51x_do_dealloc(ov);
 
-	up(&ov511->buf_lock);
+	up(&ov->buf_lock);
 	PDEBUG(4, "leaving");
 }
 
 static void 
-ov511_dealloc(struct usb_ov511 *ov511, int now)
+ov51x_dealloc(struct usb_ov511 *ov, int now)
 {
-	struct timer_list *bt = &(ov511->buf_timer);
+	struct timer_list *bt = &(ov->buf_timer);
 	PDEBUG(4, "entered");
-	down(&ov511->buf_lock);
+	down(&ov->buf_lock);
 
 	PDEBUG(4, "deallocating buffer memory %s", now ? "now" : "later");
 
-	if (ov511->buf_state == BUF_PEND_DEALLOC) {
-		ov511->buf_state = BUF_ALLOCATED;
+	if (ov->buf_state == BUF_PEND_DEALLOC) {
+		ov->buf_state = BUF_ALLOCATED;
 		del_timer(bt);
 	}
 
 	if (now)
-		ov511_do_dealloc(ov511);
+		ov51x_do_dealloc(ov);
 	else {
-		ov511->buf_state = BUF_PEND_DEALLOC;
+		ov->buf_state = BUF_PEND_DEALLOC;
 		init_timer(bt);
-		bt->function = ov511_buf_callback;
-		bt->data = (unsigned long)ov511;
+		bt->function = ov51x_buf_callback;
+		bt->data = (unsigned long)ov;
 		bt->expires = jiffies + buf_timeout * HZ;
 		add_timer(bt);
 	}
-	up(&ov511->buf_lock);
+	up(&ov->buf_lock);
 	PDEBUG(4, "leaving");
 }
 
 /****************************************************************************
  *
- * V4L API
+ * V4L 1 API
  *
  ***************************************************************************/
 
 static int 
-ov511_open(struct video_device *vdev, int flags)
+ov51x_v4l1_open(struct video_device *vdev, int flags)
 {
-	struct usb_ov511 *ov511 = vdev->priv;
+	struct usb_ov511 *ov = vdev->priv;
 	int err, i;
 
 	PDEBUG(4, "opening");
 
-	down(&ov511->lock);
+	down(&ov->lock);
 
 	err = -EBUSY;
-	if (ov511->user) 
+	if (ov->user) 
 		goto out;
 
 	err = -ENOMEM;
-	if (ov511_alloc(ov511))
+	if (ov51x_alloc(ov))
 		goto out;
 
-	ov511->sub_flag = 0;
+	ov->sub_flag = 0;
 
 	/* In case app doesn't set them... */
-	if (ov51x_set_default_params(ov511) < 0)
+	if (ov51x_set_default_params(ov) < 0)
 		goto out;
 
 	/* Make sure frames are reset */
 	for (i = 0; i < OV511_NUMFRAMES; i++) {
-		ov511->frame[i].grabstate = FRAME_UNUSED;
-		ov511->frame[i].bytes_read = 0;
+		ov->frame[i].grabstate = FRAME_UNUSED;
+		ov->frame[i].bytes_read = 0;
 	}
 
 	/* If compression is on, make sure now that a 
 	 * decompressor can be loaded */
-	if (ov511->compress && !ov511->decomp_ops) {
-		err = ov51x_request_decompressor(ov511);
-		if (err)
+	if (ov->compress && !ov->decomp_ops) {
+		err = request_decompressor(ov);
+		if (err && !dumppix)
 			goto out;
 	}
 
-	err = ov511_init_isoc(ov511);
+	err = ov51x_init_isoc(ov);
 	if (err) {
-		ov511_dealloc(ov511, 0);
+		ov51x_dealloc(ov, 0);
 		goto out;
 	}
 
-	ov511->user++;
+	ov->user++;
 	
-	if (ov511->led_policy == LED_AUTO)
-		ov51x_led_control(ov511, 1);
+	if (ov->led_policy == LED_AUTO)
+		ov51x_led_control(ov, 1);
 
 out:
-	up(&ov511->lock);
+	up(&ov->lock);
 
 	return err;
 }
 
 static void 
-ov511_close(struct video_device *dev)
+ov51x_v4l1_close(struct video_device *vdev)
 {
-	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
+	struct usb_ov511 *ov = vdev->priv;
 
 	PDEBUG(4, "ov511_close");
 	
-	down(&ov511->lock);
+	down(&ov->lock);
 
-	ov511->user--;
-	ov511_stop_isoc(ov511);
+	ov->user--;
+	ov51x_stop_isoc(ov);
 
-	ov51x_release_decompressor(ov511);
+	release_decompressor(ov);
 
-	if (ov511->led_policy == LED_AUTO)
-		ov51x_led_control(ov511, 0);
+	if (ov->led_policy == LED_AUTO)
+		ov51x_led_control(ov, 0);
 
-	if (ov511->dev)
-		ov511_dealloc(ov511, 0);
+	if (ov->dev)
+		ov51x_dealloc(ov, 0);
 
-	up(&ov511->lock);
+	up(&ov->lock);
 
 	/* Device unplugged while open. Only a minimum of unregistration is done
 	 * here; the disconnect callback already did the rest. */
-	if (!ov511->dev) {
-		ov511_dealloc(ov511, 1);
-		video_unregister_device(&ov511->vdev);
-		kfree(ov511);
-		ov511 = NULL;
+	if (!ov->dev) {
+		down(&ov->cbuf_lock);
+		kfree(ov->cbuf);
+		ov->cbuf = NULL;
+		up(&ov->cbuf_lock);
+
+		ov51x_dealloc(ov, 1);
+		video_unregister_device(&ov->vdev);
+		kfree(ov);
+		ov = NULL;
 	}
 }
 
 static int 
-ov511_init_done(struct video_device *vdev)
+ov51x_v4l1_init_done(struct video_device *vdev)
 {
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
-	create_proc_ov511_cam((struct usb_ov511 *)vdev);
+	create_proc_ov511_cam(vdev->priv);
 #endif
 
 	return 0;
 }
 
 static long 
-ov511_write(struct video_device *vdev, const char *buf,
-	    unsigned long count, int noblock)
+ov51x_v4l1_write(struct video_device *vdev, const char *buf,
+		 unsigned long count, int noblock)
 {
 	return -EINVAL;
 }
 
 /* Do not call this function directly! */
 static int 
-ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
+ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
+			  void *arg)
 {
-	struct usb_ov511 *ov511 = (struct usb_ov511 *)vdev;
+	struct usb_ov511 *ov = vdev->priv;
 
 	PDEBUG(5, "IOCtl: 0x%X", cmd);
 
-	if (!ov511->dev)
+	if (!ov->dev)
 		return -EIO;	
 
 	switch (cmd) {
@@ -4839,20 +4771,20 @@
 
 		memset(&b, 0, sizeof(b));
 		sprintf(b.name, "%s USB Camera",
-			ov511->bridge == BRG_OV511 ? "OV511" :
-			ov511->bridge == BRG_OV511PLUS ? "OV511+" :
-			ov511->bridge == BRG_OV518 ? "OV518" :
-			ov511->bridge == BRG_OV518PLUS ? "OV518+" :
+			ov->bridge == BRG_OV511 ? "OV511" :
+			ov->bridge == BRG_OV511PLUS ? "OV511+" :
+			ov->bridge == BRG_OV518 ? "OV518" :
+			ov->bridge == BRG_OV518PLUS ? "OV518+" :
 			"unknown");
 		b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
-		if (ov511->has_tuner)
+		if (ov->has_tuner)
 			b.type |= VID_TYPE_TUNER;
-		b.channels = ov511->num_inputs;
-		b.audios = ov511->has_audio_proc ? 1:0;
-		b.maxwidth = ov511->maxwidth;
-		b.maxheight = ov511->maxheight;
-		b.minwidth = ov511->minwidth;
-		b.minheight = ov511->minheight;
+		b.channels = ov->num_inputs;
+		b.audios = ov->has_audio_proc ? 1:0;
+		b.maxwidth = ov->maxwidth;
+		b.maxheight = ov->maxheight;
+		b.minwidth = ov->minwidth;
+		b.minheight = ov->minheight;
 
 		if (copy_to_user(arg, &b, sizeof(b)))
 			return -EFAULT;
@@ -4868,18 +4800,18 @@
 		if (copy_from_user(&v, arg, sizeof(v)))
 			return -EFAULT;
 
-		if ((unsigned)(v.channel) >= ov511->num_inputs) {
+		if ((unsigned)(v.channel) >= ov->num_inputs) {
 			err("Invalid channel (%d)", v.channel);
 			return -EINVAL;
 		}
 
-		v.norm = ov511->norm;
-		v.type = (ov511->has_tuner) ? VIDEO_TYPE_TV : VIDEO_TYPE_CAMERA;
-		v.flags = (ov511->has_tuner) ? VIDEO_VC_TUNER : 0;
-		v.flags |= (ov511->has_audio_proc) ? VIDEO_VC_AUDIO : 0;
-//		v.flags |= (ov511->has_decoder) ? VIDEO_VC_NORM : 0;
-		v.tuners = (ov511->has_tuner) ? 1:0;
-		decoder_get_input_name(ov511, v.channel, v.name);
+		v.norm = ov->norm;
+		v.type = (ov->has_tuner) ? VIDEO_TYPE_TV : VIDEO_TYPE_CAMERA;
+		v.flags = (ov->has_tuner) ? VIDEO_VC_TUNER : 0;
+		v.flags |= (ov->has_audio_proc) ? VIDEO_VC_AUDIO : 0;
+//		v.flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0;
+		v.tuners = (ov->has_tuner) ? 1:0;
+		decoder_get_input_name(ov, v.channel, v.name);
 
 		if (copy_to_user(arg, &v, sizeof(v)))
 			return -EFAULT;
@@ -4897,7 +4829,7 @@
 			return -EFAULT;
 
 		/* Make sure it's not a camera */
-		if (!ov511->has_decoder) {
+		if (!ov->has_decoder) {
 			if (v.channel == 0)
 				return 0;
 			else
@@ -4912,16 +4844,16 @@
 			return -EINVAL;
 		}
 
-		if ((unsigned)(v.channel) >= ov511->num_inputs) {
+		if ((unsigned)(v.channel) >= ov->num_inputs) {
 			err("Invalid channel (%d)", v.channel);
 			return -EINVAL;
 		}
 
-		err = decoder_set_input(ov511, v.channel);
+		err = decoder_set_input(ov, v.channel);
 		if (err)
 			return err;
 
-		err = decoder_set_norm(ov511, v.norm);
+		err = decoder_set_norm(ov, v.norm);
 		if (err)
 			return err;
 
@@ -4935,7 +4867,7 @@
 
 		memset(&p, 0, sizeof(p));
 
-		if (sensor_get_picture(ov511, &p))
+		if (sensor_get_picture(ov, &p))
 			return -EIO;
 
 		if (copy_to_user(arg, &p, sizeof(p)))
@@ -4953,10 +4885,10 @@
 		if (copy_from_user(&p, arg, sizeof(p)))
 			return -EFAULT;
 
-		if (!ov511_get_depth(p.palette))
+		if (!get_depth(p.palette))
 			return -EINVAL;
 
-		if (sensor_set_picture(ov511, &p))
+		if (sensor_set_picture(ov, &p))
 			return -EIO;
 
 		if (force_palette && p.palette != force_palette) {
@@ -4965,23 +4897,22 @@
 		}
 
 		// FIXME: Format should be independent of frames
-		if (p.palette != ov511->frame[0].format) {
+		if (p.palette != ov->frame[0].format) {
 			PDEBUG(4, "Detected format change");
 
 			/* If we're collecting previous frame wait
 			   before changing modes */
-			interruptible_sleep_on(&ov511->wq);
+			interruptible_sleep_on(&ov->wq);
 			if (signal_pending(current)) return -EINTR;
 
-			mode_init_regs(ov511, ov511->frame[0].width,
-				ov511->frame[0].height,	p.palette,
-				ov511->sub_flag);
+			mode_init_regs(ov, ov->frame[0].width,
+				ov->frame[0].height, p.palette, ov->sub_flag);
 		}
 
 		PDEBUG(4, "Setting depth=%d, palette=%d", p.depth, p.palette);
 		for (i = 0; i < OV511_NUMFRAMES; i++) {
-			ov511->frame[i].depth = p.depth;
-			ov511->frame[i].format = p.palette;
+			ov->frame[i].depth = p.depth;
+			ov->frame[i].format = p.palette;
 		}
 
 		return 0;
@@ -4994,7 +4925,7 @@
 
 		if (copy_from_user(&vf, arg, sizeof(vf)))
 			return -EFAULT;
-		ov511->sub_flag = vf;
+		ov->sub_flag = vf;
 		return 0;
 	}
 	case VIDIOCSCAPTURE:
@@ -5022,10 +4953,10 @@
 		if (vc.height == 0)
 			vc.height = 16;
 
-		ov511->subx = vc.x;
-		ov511->suby = vc.y;
-		ov511->subw = vc.width;
-		ov511->subh = vc.height;
+		ov->subx = vc.x;
+		ov->suby = vc.y;
+		ov->subw = vc.width;
+		ov->subh = vc.height;
 
 		return 0;
 	}
@@ -5045,25 +4976,25 @@
 			return -EINVAL;
 		if (vw.clipcount)
 			return -EINVAL;
-		if (vw.height != ov511->maxheight)
+		if (vw.height != ov->maxheight)
 			return -EINVAL;
-		if (vw.width != ov511->maxwidth)
+		if (vw.width != ov->maxwidth)
 			return -EINVAL;
 #endif
 
 		/* If we're collecting previous frame wait
 		   before changing modes */
-		interruptible_sleep_on(&ov511->wq);
+		interruptible_sleep_on(&ov->wq);
 		if (signal_pending(current)) return -EINTR;
 
-		result = mode_init_regs(ov511, vw.width, vw.height,
-			ov511->frame[0].format, ov511->sub_flag);
+		result = mode_init_regs(ov, vw.width, vw.height,
+			ov->frame[0].format, ov->sub_flag);
 		if (result < 0)
 			return result;
 
 		for (i = 0; i < OV511_NUMFRAMES; i++) {
-			ov511->frame[i].width = vw.width;
-			ov511->frame[i].height = vw.height;
+			ov->frame[i].width = vw.width;
+			ov->frame[i].height = vw.height;
 		}
 
 		return 0;
@@ -5075,8 +5006,8 @@
 		memset(&vw, 0, sizeof(vw));
 		vw.x = 0;		/* FIXME */
 		vw.y = 0;
-		vw.width = ov511->frame[0].width;
-		vw.height = ov511->frame[0].height;
+		vw.width = ov->frame[0].width;
+		vw.height = ov->frame[0].height;
 		vw.flags = 30;
 
 		PDEBUG(4, "VIDIOCGWIN: %dx%d", vw.width, vw.height);
@@ -5095,13 +5026,13 @@
 
 		memset(&vm, 0, sizeof(vm));
 		vm.size = OV511_NUMFRAMES
-			* MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight);
+			* MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
 		vm.frames = OV511_NUMFRAMES;
 
 		vm.offsets[0] = 0;
 		for (i = 1; i < OV511_NUMFRAMES; i++) {
 			vm.offsets[i] = vm.offsets[i-1]
-			   + MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight);
+			   + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
 		}
 
 		if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
@@ -5121,7 +5052,7 @@
 		PDEBUG(4, "frame: %d, size: %dx%d, format: %d",
 			vm.frame, vm.width, vm.height, vm.format);
 
-		depth = ov511_get_depth(vm.format);
+		depth = get_depth(vm.format);
 		if (!depth) {
 			err("VIDIOCMCAPTURE: invalid format (%d)", vm.format);
 			return -EINVAL;
@@ -5132,13 +5063,13 @@
 			return -EINVAL;
 		}
 
-		if (vm.width > ov511->maxwidth 
-		    || vm.height > ov511->maxheight) {
+		if (vm.width > ov->maxwidth 
+		    || vm.height > ov->maxheight) {
 			err("VIDIOCMCAPTURE: requested dimensions too big");
 			return -EINVAL;
 		}
 
-		if (ov511->frame[vm.frame].grabstate == FRAME_GRABBING) {
+		if (ov->frame[vm.frame].grabstate == FRAME_GRABBING) {
 			PDEBUG(4, "VIDIOCMCAPTURE: already grabbing");
 			return -EBUSY;
 		}
@@ -5148,38 +5079,38 @@
 			return -EINVAL;
 		}
 
-		if ((ov511->frame[vm.frame].width != vm.width) ||
-		    (ov511->frame[vm.frame].height != vm.height) ||
-		    (ov511->frame[vm.frame].format != vm.format) ||
-		    (ov511->frame[vm.frame].sub_flag != ov511->sub_flag) ||
-		    (ov511->frame[vm.frame].depth != depth)) {
+		if ((ov->frame[vm.frame].width != vm.width) ||
+		    (ov->frame[vm.frame].height != vm.height) ||
+		    (ov->frame[vm.frame].format != vm.format) ||
+		    (ov->frame[vm.frame].sub_flag != ov->sub_flag) ||
+		    (ov->frame[vm.frame].depth != depth)) {
 			PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters");
 
 			/* If we're collecting previous frame wait
 			   before changing modes */
-			interruptible_sleep_on(&ov511->wq);
+			interruptible_sleep_on(&ov->wq);
 			if (signal_pending(current)) return -EINTR;
-			ret = mode_init_regs(ov511, vm.width, vm.height,
-				vm.format, ov511->sub_flag);
+			ret = mode_init_regs(ov, vm.width, vm.height,
+				vm.format, ov->sub_flag);
 #if 0
 			if (ret < 0) {
 				PDEBUG(1, "Got error while initializing regs ");
 				return ret;
 			}
 #endif
-			ov511->frame[vm.frame].width = vm.width;
-			ov511->frame[vm.frame].height = vm.height;
-			ov511->frame[vm.frame].format = vm.format;
-			ov511->frame[vm.frame].sub_flag = ov511->sub_flag;
-			ov511->frame[vm.frame].depth = depth;
+			ov->frame[vm.frame].width = vm.width;
+			ov->frame[vm.frame].height = vm.height;
+			ov->frame[vm.frame].format = vm.format;
+			ov->frame[vm.frame].sub_flag = ov->sub_flag;
+			ov->frame[vm.frame].depth = depth;
 		}
 
 		/* Mark it as ready */
-		ov511->frame[vm.frame].grabstate = FRAME_READY;
+		ov->frame[vm.frame].grabstate = FRAME_READY;
 
 		PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", vm.frame);
 
-		return ov511_new_frame(ov511, vm.frame);
+		return ov51x_new_frame(ov, vm.frame);
 	}
 	case VIDIOCSYNC:
 	{
@@ -5194,7 +5125,7 @@
 			return -EINVAL;
 		}
 
-		frame = &ov511->frame[fnum];
+		frame = &ov->frame[fnum];
 
 		PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum,
 		       frame->grabstate);
@@ -5206,7 +5137,7 @@
 		case FRAME_GRABBING:
 		case FRAME_ERROR:
 redo:
-			if (!ov511->dev)
+			if (!ov->dev)
 				return -EIO;
 
 			rc = wait_event_interruptible(frame->wq,
@@ -5219,15 +5150,15 @@
 			if (frame->grabstate == FRAME_ERROR) {
 				int ret;
 
-				if ((ret = ov511_new_frame(ov511, fnum)) < 0)
+				if ((ret = ov51x_new_frame(ov, fnum)) < 0)
 					return ret;
 				goto redo;
 			}
 			/* Fall through */			
 		case FRAME_DONE:
-			if (ov511->snap_enabled && !frame->snapshot) {
+			if (ov->snap_enabled && !frame->snapshot) {
 				int ret;
-				if ((ret = ov511_new_frame(ov511, fnum)) < 0)
+				if ((ret = ov51x_new_frame(ov, fnum)) < 0)
 					return ret;
 				goto redo;
 			}
@@ -5236,13 +5167,13 @@
 
 			/* Reset the hardware snapshot button */
 			/* FIXME - Is this the best place for this? */
-			if ((ov511->snap_enabled) && (frame->snapshot)) {
+			if ((ov->snap_enabled) && (frame->snapshot)) {
 				frame->snapshot = 0;
-				ov51x_clear_snapshot(ov511);
+				ov51x_clear_snapshot(ov);
 			}
 
 			/* Decompression, format conversion, etc... */
-			ov511_postprocess(ov511, frame);
+			ov51x_postprocess(ov, frame);
 
 			break;
 		} /* end switch */
@@ -5271,7 +5202,7 @@
 
 		memset(&vu, 0, sizeof(vu));
 
-		vu.video = ov511->vdev.minor;	/* Video minor */
+		vu.video = ov->vdev.minor;	/* Video minor */
 		vu.vbi = VIDEO_NO_UNIT;		/* VBI minor */
 		vu.radio = VIDEO_NO_UNIT;	/* Radio minor */
 		vu.audio = VIDEO_NO_UNIT;	/* Audio minor */
@@ -5291,7 +5222,7 @@
 		if (copy_from_user(&v, arg, sizeof(v)))
 			return -EFAULT;
 
-		if (!ov511->has_tuner || v.tuner)	// Only tuner 0
+		if (!ov->has_tuner || v.tuner)	// Only tuner 0
 			return -EINVAL;
 
 		strcpy(v.name, "Television");
@@ -5305,7 +5236,7 @@
 		v.mode = 0; 		/* FIXME:  Not sure what this is yet */
 		v.signal = 0xFFFF;	/* unknown */
 
-		call_i2c_clients(ov511, cmd, &v);
+		call_i2c_clients(ov, cmd, &v);
 
 		if (copy_to_user(arg, &v, sizeof(v)))
 			return -EFAULT;
@@ -5323,7 +5254,7 @@
 			return -EFAULT;
 
 		/* Only no or one tuner for now */
-		if (!ov511->has_tuner || v.tuner)
+		if (!ov->has_tuner || v.tuner)
 			return -EINVAL;
 
 		/* and it only has certain valid modes */
@@ -5332,21 +5263,21 @@
 		    v.mode != VIDEO_MODE_SECAM) return -EOPNOTSUPP;
 
 		/* Is this right/necessary? */
-		err = decoder_set_norm(ov511, v.mode);
+		err = decoder_set_norm(ov, v.mode);
 		if (err)
 			return err;
 
-		call_i2c_clients(ov511, cmd, &v);
+		call_i2c_clients(ov, cmd, &v);
 
 		return 0;
 	}
 	case VIDIOCGFREQ:
 	{
-		unsigned long v = ov511->freq;
+		unsigned long v = ov->freq;
 
 		PDEBUG(4, "VIDIOCGFREQ");
 
-		if (!ov511->has_tuner)
+		if (!ov->has_tuner)
 			return -EINVAL;
 #if 0
 		/* FIXME: this is necessary for testing */
@@ -5361,7 +5292,7 @@
 	{
 		unsigned long v;
 
-		if (!ov511->has_tuner)
+		if (!ov->has_tuner)
 			return -EINVAL;
 
 		if (copy_from_user(&v, arg, sizeof(v)))
@@ -5369,8 +5300,8 @@
 
 		PDEBUG(4, "VIDIOCSFREQ: %lx", v);
 
-		ov511->freq = v;
-		call_i2c_clients(ov511, cmd, &v);
+		ov->freq = v;
+		call_i2c_clients(ov, cmd, &v);
 
 		return 0;
 	}
@@ -5389,29 +5320,29 @@
 }
 
 static int 
-ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
+ov51x_v4l1_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
 {
 	int rc;
-	struct usb_ov511 *ov511 = vdev->priv;
+	struct usb_ov511 *ov = vdev->priv;
 
-	if (down_interruptible(&ov511->lock))
+	if (down_interruptible(&ov->lock))
 		return -EINTR;
 
-	rc = ov511_ioctl_internal(vdev, cmd, arg);
+	rc = ov51x_v4l1_ioctl_internal(vdev, cmd, arg);
 
-	up(&ov511->lock);
+	up(&ov->lock);
 	return rc;
 }
 
 static inline long 
-ov511_read(struct video_device *vdev, char *buf, unsigned long count,
-	   int noblock)
+ov51x_v4l1_read(struct video_device *vdev, char *buf, unsigned long count,
+		int noblock)
 {
-	struct usb_ov511 *ov511 = vdev->priv;
+	struct usb_ov511 *ov = vdev->priv;
 	int i, rc = 0, frmx = -1;
 	struct ov511_frame *frame;
 
-	if (down_interruptible(&ov511->lock))
+	if (down_interruptible(&ov->lock))
 		return -EINTR;
 
 	PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
@@ -5421,16 +5352,16 @@
 		goto error;
 	}
 
-	if (!ov511->dev) {
+	if (!ov->dev) {
 		rc = -EIO;
 		goto error;
 	}
 
 // FIXME: Only supports two frames
 	/* See if a frame is completed, then use it. */
-	if (ov511->frame[0].grabstate >= FRAME_DONE)	/* _DONE or _ERROR */
+	if (ov->frame[0].grabstate >= FRAME_DONE)	/* _DONE or _ERROR */
 		frmx = 0;
-	else if (ov511->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
+	else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
 		frmx = 1;
 
 	/* If nonblocking we return immediately */
@@ -5442,24 +5373,24 @@
 	/* If no FRAME_DONE, look for a FRAME_GRABBING state. */
 	/* See if a frame is in process (grabbing), then use it. */
 	if (frmx == -1) {
-		if (ov511->frame[0].grabstate == FRAME_GRABBING)
+		if (ov->frame[0].grabstate == FRAME_GRABBING)
 			frmx = 0;
-		else if (ov511->frame[1].grabstate == FRAME_GRABBING)
+		else if (ov->frame[1].grabstate == FRAME_GRABBING)
 			frmx = 1;
 	}
 
 	/* If no frame is active, start one. */
 	if (frmx == -1) {
-		if ((rc = ov511_new_frame(ov511, frmx = 0))) {
-			err("read: ov511_new_frame error");
+		if ((rc = ov51x_new_frame(ov, frmx = 0))) {
+			err("read: ov51x_new_frame error");
 			goto error;
 		}
 	}
 
-	frame = &ov511->frame[frmx];
+	frame = &ov->frame[frmx];
 
 restart:
-	if (!ov511->dev) {
+	if (!ov->dev) {
 		rc = -EIO;
 		goto error;
 	}
@@ -5478,9 +5409,9 @@
 
 	if (frame->grabstate == FRAME_ERROR) {
 		frame->bytes_read = 0;
-		err("** ick! ** Errored frame %d", ov511->curframe);
-		if (ov511_new_frame(ov511, frmx)) {
-			err("read: ov511_new_frame error");
+		err("** ick! ** Errored frame %d", ov->curframe);
+		if (ov51x_new_frame(ov, frmx)) {
+			err("read: ov51x_new_frame error");
 			goto error;
 		}
 		goto restart;
@@ -5488,25 +5419,25 @@
 
 
 	/* Repeat until we get a snapshot frame */
-	if (ov511->snap_enabled)
+	if (ov->snap_enabled)
 		PDEBUG(4, "Waiting snapshot frame");
-	if (ov511->snap_enabled && !frame->snapshot) {
+	if (ov->snap_enabled && !frame->snapshot) {
 		frame->bytes_read = 0;
-		if ((rc = ov511_new_frame(ov511, frmx))) {
-			err("read: ov511_new_frame error");
+		if ((rc = ov51x_new_frame(ov, frmx))) {
+			err("read: ov51x_new_frame error");
 			goto error;
 		}
 		goto restart;
 	}
 
 	/* Clear the snapshot */
-	if (ov511->snap_enabled && frame->snapshot) {
+	if (ov->snap_enabled && frame->snapshot) {
 		frame->snapshot = 0;
-		ov51x_clear_snapshot(ov511);
+		ov51x_clear_snapshot(ov);
 	}
 
 	/* Decompression, format conversion, etc... */
-	ov511_postprocess(ov511, frame);
+	ov51x_postprocess(ov, frame);
 
 	PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx,
 		frame->bytes_read,
@@ -5538,48 +5469,48 @@
 
 // FIXME: Only supports two frames
 		/* Mark it as available to be used again. */
-		ov511->frame[frmx].grabstate = FRAME_UNUSED;
-		if ((rc = ov511_new_frame(ov511, !frmx))) {
-			err("ov511_new_frame returned error");
+		ov->frame[frmx].grabstate = FRAME_UNUSED;
+		if ((rc = ov51x_new_frame(ov, !frmx))) {
+			err("ov51x_new_frame returned error");
 			goto error;
 		}
 	}
 
 	PDEBUG(4, "read finished, returning %ld (sweet)", count);
 
-	up(&ov511->lock);
+	up(&ov->lock);
 	return count;
 
 error:
-	up(&ov511->lock);
+	up(&ov->lock);
 	return rc;
 }
 
 static int 
-ov511_mmap(struct video_device *vdev, const char *adr, unsigned long size)
+ov51x_v4l1_mmap(struct video_device *vdev, const char *adr, unsigned long size)
 {
-	struct usb_ov511 *ov511 = vdev->priv;
+	struct usb_ov511 *ov = vdev->priv;
 	unsigned long start = (unsigned long)adr;
 	unsigned long page, pos;
 
-	if (ov511->dev == NULL)
+	if (ov->dev == NULL)
 		return -EIO;
 
 	PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
 
 	if (size > (((OV511_NUMFRAMES
-	              * MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight)
+	              * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
 	              + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
 		return -EINVAL;
 
-	if (down_interruptible(&ov511->lock))
+	if (down_interruptible(&ov->lock))
 		return -EINTR;
 
-	pos = (unsigned long)ov511->fbuf;
+	pos = (unsigned long)ov->fbuf;
 	while (size > 0) {
 		page = kvirt_to_pa(pos);
 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
-			up(&ov511->lock);
+			up(&ov->lock);
 			return -EAGAIN;
 		}
 		start += PAGE_SIZE;
@@ -5590,43 +5521,42 @@
 			size = 0;
 	}
 
-	up(&ov511->lock);
+	up(&ov->lock);
 	return 0;
 }
 
-static struct video_device ov511_template = {
+static struct video_device vdev_template = {
 	owner:		THIS_MODULE,
 	name:		"OV511 USB Camera",
 	type:		VID_TYPE_CAPTURE,
 	hardware:	VID_HARDWARE_OV511,
-	open:		ov511_open,
-	close:		ov511_close,
-	read:		ov511_read,
-	write:		ov511_write,
-	ioctl:		ov511_ioctl,
-	mmap:		ov511_mmap,
-	initialize:	ov511_init_done,
+	open:		ov51x_v4l1_open,
+	close:		ov51x_v4l1_close,
+	read:		ov51x_v4l1_read,
+	write:		ov51x_v4l1_write,
+	ioctl:		ov51x_v4l1_ioctl,
+	mmap:		ov51x_v4l1_mmap,
+	initialize:	ov51x_v4l1_init_done,
 };
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 static int 
-ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 		    unsigned long ularg)
 {
-	struct proc_dir_entry *pde;
-	struct usb_ov511 *ov511;
+	struct proc_dir_entry *pde = inode->u.generic_ip;
+	struct usb_ov511 *ov;
 	void *arg = (void *) ularg;
 	int rc;
 
-	pde = (struct proc_dir_entry *) inode->u.generic_ip;
 	if (!pde)
 		return -ENOENT;
 
-	ov511 = (struct usb_ov511 *) pde->data;
-	if (!ov511)
+	ov = pde->data;
+	if (!ov)
 		return -ENODEV;
 
-	if (!ov511->dev)
+	if (!ov->dev)
 		return -EIO;
 
 	/* Should we pass through standard V4L IOCTLs? */
@@ -5651,19 +5581,19 @@
 
 		switch (opt.optnum) {
 		case OV511_USOPT_BRIGHT:
-			rc = sensor_get_brightness(ov511, &(opt.val));
+			rc = sensor_get_brightness(ov, &(opt.val));
 			if (rc)	return rc;
 			break;
 		case OV511_USOPT_SAT:
-			rc = sensor_get_saturation(ov511, &(opt.val));
+			rc = sensor_get_saturation(ov, &(opt.val));
 			if (rc)	return rc;
 			break;
 		case OV511_USOPT_HUE:
-			rc = sensor_get_hue(ov511, &(opt.val));
+			rc = sensor_get_hue(ov, &(opt.val));
 			if (rc)	return rc;
 			break;
 		case OV511_USOPT_CONTRAST:
-			rc = sensor_get_contrast(ov511, &(opt.val));
+			rc = sensor_get_contrast(ov, &(opt.val));
 			if (rc)	return rc;
 			break;
 		default:
@@ -5685,19 +5615,19 @@
 
 		switch (opt.optnum) {
 		case OV511_USOPT_BRIGHT:
-			rc = sensor_set_brightness(ov511, opt.val);
+			rc = sensor_set_brightness(ov, opt.val);
 			if (rc)	return rc;
 			break;
 		case OV511_USOPT_SAT:
-			rc = sensor_set_saturation(ov511, opt.val);
+			rc = sensor_set_saturation(ov, opt.val);
 			if (rc)	return rc;
 			break;
 		case OV511_USOPT_HUE:
-			rc = sensor_set_hue(ov511, opt.val);
+			rc = sensor_set_hue(ov, opt.val);
 			if (rc)	return rc;
 			break;
 		case OV511_USOPT_CONTRAST:
-			rc = sensor_set_contrast(ov511, opt.val);
+			rc = sensor_set_contrast(ov, opt.val);
 			if (rc)	return rc;
 			break;
 		default:
@@ -5716,19 +5646,19 @@
 
 		switch (opt.optnum) {
 		case OV511_UIOPT_POWER_FREQ:
-			opt.val = ov511->lightfreq;
+			opt.val = ov->lightfreq;
 			break;
 		case OV511_UIOPT_BFILTER:
-			opt.val = ov511->bandfilt;
+			opt.val = ov->bandfilt;
 			break;
 		case OV511_UIOPT_LED:
-			opt.val = ov511->led_policy;
+			opt.val = ov->led_policy;
 			break;
 		case OV511_UIOPT_DEBUG:
 			opt.val = debug;
 			break;
 		case OV511_UIOPT_COMPRESS:
-			opt.val = ov511->compress;
+			opt.val = ov->compress;
 			break;
 		default:
 			err("Invalid get int option number");
@@ -5749,20 +5679,20 @@
 
 		switch (opt.optnum) {
 		case OV511_UIOPT_POWER_FREQ:
-			rc = sensor_set_light_freq(ov511, opt.val);
+			rc = sensor_set_light_freq(ov, opt.val);
 			if (rc)	return rc;
 			break;
 		case OV511_UIOPT_BFILTER:
-			rc = sensor_set_banding_filter(ov511, opt.val);
+			rc = sensor_set_banding_filter(ov, opt.val);
 			if (rc)	return rc;
 			break;
 		case OV511_UIOPT_LED:
 			if (opt.val <= 2) {
-				ov511->led_policy = opt.val;
-				if (ov511->led_policy == LED_OFF)
-					ov51x_led_control(ov511, 0);
-				else if (ov511->led_policy == LED_ON)
-					ov51x_led_control(ov511, 1);
+				ov->led_policy = opt.val;
+				if (ov->led_policy == LED_OFF)
+					ov51x_led_control(ov, 0);
+				else if (ov->led_policy == LED_ON)
+					ov51x_led_control(ov, 1);
 			} else {
 				return -EINVAL;
 			}
@@ -5774,14 +5704,12 @@
 				return -EINVAL;
 			break;
 		case OV511_UIOPT_COMPRESS:
-			ov511->compress = opt.val;
-			if (ov511->compress) {
-				if (ov511->bridge == BRG_OV511 ||
-				    ov511->bridge == BRG_OV511PLUS)
-					ov511_init_compression(ov511);
-				else if (ov511->bridge == BRG_OV518 ||
-					 ov511->bridge == BRG_OV518PLUS)
-					ov518_init_compression(ov511);
+			ov->compress = opt.val;
+			if (ov->compress) {
+				if (ov->bclass == BCL_OV511)
+					ov511_init_compression(ov);
+				else if (ov->bclass == BCL_OV518)
+					ov518_init_compression(ov);
 			}
 			break;
 		default:
@@ -5798,7 +5726,7 @@
 		if (copy_from_user(&w, arg, sizeof(w)))
 			return -EFAULT;
 
-		return ov51x_i2c_write_slave(ov511, w.slave, w.reg, w.value,
+		return i2c_w_slave(ov, w.slave, w.reg, w.value,
 			w.mask);
 	}
 	case OV511IOC_RI2C:
@@ -5808,7 +5736,7 @@
 		if (copy_from_user(&r, arg, sizeof(r)))
 			return -EFAULT;
 
-		rc = ov51x_i2c_read_slave(ov511, r.slave, r.reg);
+		rc = i2c_r_slave(ov, r.slave, r.reg);
 		if (rc < 0)
 			return rc;
 
@@ -5837,7 +5765,7 @@
  * the same register settings as the OV7610, since they are very similar.
  */
 static int 
-ov7xx0_configure(struct usb_ov511 *ov511)
+ov7xx0_configure(struct usb_ov511 *ov)
 {
 	int i, success;
 	int rc;
@@ -5954,16 +5882,15 @@
 	PDEBUG(4, "starting configuration");
 
 	/* This looks redundant, but is necessary for WebCam 3 */
-	ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
-	if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
-				OV7xx0_I2C_READ_ID) < 0)
+	ov->primary_i2c_slave = OV7xx0_SID;
+	if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
 		return -1;
 
-	if (ov51x_init_ov_sensor(ov511) >= 0) {
+	if (init_ov_sensor(ov) >= 0) {
 		PDEBUG(1, "OV7xx0 sensor initalized (method 1)");
 	} else {
 		/* Reset the 76xx */
-		if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -1;
+		if (i2c_w(ov, 0x12, 0x80) < 0) return -1;
 
 		/* Wait for it to initialize */
 		schedule_timeout(1 + 150 * HZ / 1000);
@@ -5971,10 +5898,8 @@
 		i = 0;
 		success = 0;
 		while (i <= i2c_detect_tries) {
-			if ((ov51x_i2c_read(ov511,
-					    OV7610_REG_ID_HIGH) == 0x7F) &&
-			    (ov51x_i2c_read(ov511,
-					    OV7610_REG_ID_LOW) == 0xA2)) {
+			if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
+			    (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
 				success = 1;
 				break;
 			} else {
@@ -5998,17 +5923,17 @@
 	}
 
 	/* Detect sensor (sub)type */
-	rc = ov51x_i2c_read(ov511, OV7610_REG_COM_I);
+	rc = i2c_r(ov, OV7610_REG_COM_I);
 
 	if (rc < 0) {
 		err("Error detecting sensor type");
 		return -1;
 	} else if ((rc & 3) == 3) {
 		info("Sensor is an OV7610");
-		ov511->sensor = SEN_OV7610;
+		ov->sensor = SEN_OV7610;
 	} else if ((rc & 3) == 1) {
 		/* I don't know what's different about the 76BE yet */
-		if (ov51x_i2c_read(ov511, 0x15) & 1)
+		if (i2c_r(ov, 0x15) & 1)
 			info("Sensor is an OV7620AE");
 		else
 			info("Sensor is an OV76BE");
@@ -6016,48 +5941,48 @@
 		/* OV511+ will return all zero isoc data unless we
 		 * configure the sensor as a 7620. Someone needs to
 		 * find the exact reg. setting that causes this. */
-		if (ov511->bridge == BRG_OV511PLUS) {
+		if (ov->bridge == BRG_OV511PLUS) {
 			info("Enabling 511+/7620AE workaround");
-			ov511->sensor = SEN_OV7620;
+			ov->sensor = SEN_OV7620;
 		} else {
-			ov511->sensor = SEN_OV7620AE;
+			ov->sensor = SEN_OV7620AE;
 		}
 	} else if ((rc & 3) == 0) {
 		info("Sensor is an OV7620");
-		ov511->sensor = SEN_OV7620;
+		ov->sensor = SEN_OV7620;
 	} else {
 		err("Unknown image sensor version: %d", rc & 3);
 		return -1;
 	}
 
-	if (ov511->sensor == SEN_OV7620) {
+	if (ov->sensor == SEN_OV7620) {
 		PDEBUG(4, "Writing 7620 registers");
-		if (ov511_write_regvals(ov511, aRegvalsNorm7620))
+		if (write_regvals(ov, aRegvalsNorm7620))
 			return -1;
 	} else {
 		PDEBUG(4, "Writing 7610 registers");
-		if (ov511_write_regvals(ov511, aRegvalsNorm7610))
+		if (write_regvals(ov, aRegvalsNorm7610))
 			return -1;
 	}
 
 	/* Set sensor-specific vars */
-	ov511->maxwidth = 640;
-	ov511->maxheight = 480;
-	ov511->minwidth = 64;
-	ov511->minheight = 48;
+	ov->maxwidth = 640;
+	ov->maxheight = 480;
+	ov->minwidth = 64;
+	ov->minheight = 48;
 
 	// FIXME: These do not match the actual settings yet
-	ov511->brightness = 0x80 << 8;
-	ov511->contrast = 0x80 << 8;
-	ov511->colour = 0x80 << 8;
-	ov511->hue = 0x80 << 8;
+	ov->brightness = 0x80 << 8;
+	ov->contrast = 0x80 << 8;
+	ov->colour = 0x80 << 8;
+	ov->hue = 0x80 << 8;
 
 	return 0;
 }
 
 /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
 static int 
-ov6xx0_configure(struct usb_ov511 *ov511)
+ov6xx0_configure(struct usb_ov511 *ov)
 {
 	int rc;
 
@@ -6183,7 +6108,7 @@
 
 	PDEBUG(4, "starting sensor configuration");
 	
-	if (ov51x_init_ov_sensor(ov511) < 0) {
+	if (init_ov_sensor(ov) < 0) {
 		err("Failed to read sensor ID. You might not have an OV6xx0,");
 		err("or it may be not responding. Report this to " EMAIL);
 		return -1;
@@ -6192,50 +6117,44 @@
 	}
 
 	/* Detect sensor (sub)type */
-	rc = ov51x_i2c_read(ov511, OV7610_REG_COM_I);
+	rc = i2c_r(ov, OV7610_REG_COM_I);
 
 	if (rc < 0) {
 		err("Error detecting sensor type");
 		return -1;
 	} else if ((rc & 3) == 0) {
 		info("Sensor is an OV6630");
-		ov511->sensor = SEN_OV6630;
+		ov->sensor = SEN_OV6630;
 	} else if ((rc & 3) == 1) {
 		info("Sensor is an OV6620");
-		ov511->sensor = SEN_OV6620;
+		ov->sensor = SEN_OV6620;
 	} else if ((rc & 3) == 2) {
 		info("Sensor is an OV6630AE");
-		ov511->sensor = SEN_OV6630;
+		ov->sensor = SEN_OV6630;
 	} else if ((rc & 3) == 3) {
 		info("Sensor is an OV6630AF");
-		ov511->sensor = SEN_OV6630;
+		ov->sensor = SEN_OV6630;
 	} 
 
 	/* Set sensor-specific vars */
-	if (ov511->sensor == SEN_OV6620) {
-		ov511->maxwidth = 352;
-		ov511->maxheight = 288;
-	} else {
-		/* 352x288 not working with OV518 yet */
-		ov511->maxwidth = 320;
-		ov511->maxheight = 240;
-	}
-	ov511->minwidth = 64;
-	ov511->minheight = 48;
+	ov->maxwidth = 352;
+	ov->maxheight = 288;
+	ov->minwidth = 64;
+	ov->minheight = 48;
 
 	// FIXME: These do not match the actual settings yet
-	ov511->brightness = 0x80 << 8;
-	ov511->contrast = 0x80 << 8;
-	ov511->colour = 0x80 << 8;
-	ov511->hue = 0x80 << 8;
+	ov->brightness = 0x80 << 8;
+	ov->contrast = 0x80 << 8;
+	ov->colour = 0x80 << 8;
+	ov->hue = 0x80 << 8;
 
-	if (ov511->sensor == SEN_OV6620) {
+	if (ov->sensor == SEN_OV6620) {
 		PDEBUG(4, "Writing 6x20 registers");
-		if (ov511_write_regvals(ov511, aRegvalsNorm6x20))
+		if (write_regvals(ov, aRegvalsNorm6x20))
 			return -1;
 	} else {
 		PDEBUG(4, "Writing 6x30 registers");
-		if (ov511_write_regvals(ov511, aRegvalsNorm6x30))
+		if (write_regvals(ov, aRegvalsNorm6x30))
 			return -1;
 	}
 	
@@ -6244,13 +6163,13 @@
 
 /* This initializes the KS0127 and KS0127B video decoders. */
 static int 
-ks0127_configure(struct usb_ov511 *ov511)
+ks0127_configure(struct usb_ov511 *ov)
 {
 	int rc;
 
 // FIXME: I don't know how to sync or reset it yet
 #if 0
-	if (ov51x_init_ks_sensor(ov511) < 0) {
+	if (ov51x_init_ks_sensor(ov) < 0) {
 		err("Failed to initialize the KS0127");
 		return -1;
 	} else {
@@ -6259,21 +6178,21 @@
 #endif
 
 	/* Detect decoder subtype */
-	rc = ov51x_i2c_read(ov511, 0x00);
+	rc = i2c_r(ov, 0x00);
 	if (rc < 0) {
 		err("Error detecting sensor type");
 		return -1;
 	} else if (rc & 0x08) {
-		rc = ov51x_i2c_read(ov511, 0x3d);
+		rc = i2c_r(ov, 0x3d);
 		if (rc < 0) {
 			err("Error detecting sensor type");
 			return -1;
 		} else if ((rc & 0x0f) == 0) {
 			info("Sensor is a KS0127");
-			ov511->sensor = SEN_KS0127;
+			ov->sensor = SEN_KS0127;
 		} else if ((rc & 0x0f) == 9) {
 			info("Sensor is a KS0127B Rev. A");
-			ov511->sensor = SEN_KS0127B;
+			ov->sensor = SEN_KS0127B;
 		}
 	} else {
 		err("Error: Sensor is an unsupported KS0122");
@@ -6281,16 +6200,16 @@
 	}
 
 	/* Set sensor-specific vars */
-	ov511->maxwidth = 640;
-	ov511->maxheight = 480;
-	ov511->minwidth = 64;
-	ov511->minheight = 48;
+	ov->maxwidth = 640;
+	ov->maxheight = 480;
+	ov->minwidth = 64;
+	ov->minheight = 48;
 
 	// FIXME: These do not match the actual settings yet
-	ov511->brightness = 0x80 << 8;
-	ov511->contrast = 0x80 << 8;
-	ov511->colour = 0x80 << 8;
-	ov511->hue = 0x80 << 8;
+	ov->brightness = 0x80 << 8;
+	ov->contrast = 0x80 << 8;
+	ov->colour = 0x80 << 8;
+	ov->hue = 0x80 << 8;
 
 	/* This device is not supported yet. Bail out now... */
 	err("This sensor is not supported yet.");
@@ -6303,7 +6222,6 @@
 static int 
 saa7111a_configure(struct usb_ov511 *ov511)
 {
-	struct usb_device *dev = ov511->dev;
 	int rc;
 
 	/* Since there is no register reset command, all registers must be
@@ -6338,7 +6256,7 @@
 
 // FIXME: I don't know how to sync or reset it yet
 #if 0
-	if (ov51x_init_saa_sensor(ov511) < 0) {
+	if (ov51x_init_saa_sensor(ov) < 0) {
 		err("Failed to initialize the SAA7111A");
 		return -1;
 	} else {
@@ -6365,12 +6283,12 @@
 	ov511->hue = 32768;
 
 	PDEBUG(4, "Writing SAA7111A registers");
-	if (ov511_write_regvals(ov511, aRegvalsNormSAA7111A))
+	if (write_regvals(ov511, aRegvalsNormSAA7111A))
 		return -1;
 
 	/* Detect version of decoder. This must be done after writing the
          * initial regs or the decoder will lock up. */
-	rc = ov51x_i2c_read(ov511, 0x00);
+	rc = i2c_r(ov511, 0x00);
 
 	if (rc < 0) {
 		err("Error detecting sensor version");
@@ -6383,8 +6301,8 @@
 	// FIXME: Fix this for OV518(+)
 	/* Latch to negative edge of clock. Otherwise, we get incorrect
 	 * colors and jitter in the digital signal. */
-	if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS)
-		ov511_reg_write(dev, 0x11, 0x00);
+	if (ov511->bclass == BCL_OV511)
+		reg_w(ov511, 0x11, 0x00);
 	else
 		warn("SAA7111A not yet supported with OV518/OV518+");
 
@@ -6393,144 +6311,138 @@
 
 /* This initializes the OV511/OV511+ and the sensor */
 static int 
-ov511_configure(struct usb_ov511 *ov511)
+ov511_configure(struct usb_ov511 *ov)
 {
-	struct usb_device *dev = ov511->dev;
 	int i;
 
 	static struct ov511_regvals aRegvalsInit511[] = {
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f },
-	 	{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
-	 	{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3f },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3d },
+		{ OV511_REG_BUS, R51x_SYS_RESET,	0x7f },
+	 	{ OV511_REG_BUS, R51x_SYS_INIT,		0x01 },
+	 	{ OV511_REG_BUS, R51x_SYS_RESET,	0x7f },
+		{ OV511_REG_BUS, R51x_SYS_INIT,		0x01 },
+		{ OV511_REG_BUS, R51x_SYS_RESET,	0x3f },
+		{ OV511_REG_BUS, R51x_SYS_INIT,		0x01 },
+		{ OV511_REG_BUS, R51x_SYS_RESET,	0x3d },
 		{ OV511_DONE_BUS, 0x0, 0x00},
 	};
 
 	static struct ov511_regvals aRegvalsNorm511[] = {
-		{ OV511_REG_BUS, OV511_REG_DRAM_ENABLE_FLOW_CONTROL, 0x01 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x03 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
-		{ OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0x1f },
-		{ OV511_REG_BUS, OV511_OMNICE_ENABLE, 0x00 },
-		{ OV511_REG_BUS, OV511_OMNICE_LUT_ENABLE, 0x03 },
+		{ OV511_REG_BUS, R511_DRAM_FLOW_CTL, 	0x01 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x03 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 },
+		{ OV511_REG_BUS, R511_FIFO_OPTS,	0x1f },
+		{ OV511_REG_BUS, R511_COMP_EN,		0x00 },
+		{ OV511_REG_BUS, R511_COMP_LUT_EN,	0x03 },
 		{ OV511_DONE_BUS, 0x0, 0x00 },
 	};
 
 	static struct ov511_regvals aRegvalsNorm511Plus[] = {
-		{ OV511_REG_BUS, OV511_REG_DRAM_ENABLE_FLOW_CONTROL, 0xff },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x03 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
-		{ OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0xff },
-		{ OV511_REG_BUS, OV511_OMNICE_ENABLE, 0x00 },
-		{ OV511_REG_BUS, OV511_OMNICE_LUT_ENABLE, 0x03 },
+		{ OV511_REG_BUS, R511_DRAM_FLOW_CTL,	0xff },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x03 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 },
+		{ OV511_REG_BUS, R511_FIFO_OPTS,	0xff },
+		{ OV511_REG_BUS, R511_COMP_EN,		0x00 },
+		{ OV511_REG_BUS, R511_COMP_LUT_EN,	0x03 },
 		{ OV511_DONE_BUS, 0x0, 0x00 },
 	};
 
 	PDEBUG(4, "");
 
-	ov511->customid = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);
-	if (ov511->customid < 0) {
+	ov->customid = reg_r(ov, R511_SYS_CUST_ID);
+	if (ov->customid < 0) {
 		err("Unable to read camera bridge registers");
 		goto error;
 	}
 
-	ov511->desc = -1;
-	PDEBUG (1, "CustomID = %d", ov511->customid);
+	ov->desc = -1;
+	PDEBUG (1, "CustomID = %d", ov->customid);
 	for (i = 0; clist[i].id >= 0; i++) {
-		if (ov511->customid == clist[i].id) {
+		if (ov->customid == clist[i].id) {
 			info("model: %s", clist[i].description);
-			ov511->desc = i;
+			ov->desc = i;
 			break;
 		}
 	}
 
 	if (clist[i].id == -1) {
-		err("Camera type (%d) not recognized", ov511->customid);
+		err("Camera type (%d) not recognized", ov->customid);
 		err("Please notify " EMAIL " of the name,");
 		err("manufacturer, model, and this number of your camera.");
 		err("Also include the output of the detection process.");
 	} 
 
 	if (clist[i].id == 6) {	/* USB Life TV (NTSC) */
-		ov511->tuner_type = 8;		/* Temic 4036FY5 3X 1981 */
+		ov->tuner_type = 8;		/* Temic 4036FY5 3X 1981 */
 	}
 
-	if (ov511_write_regvals(ov511, aRegvalsInit511)) goto error;
+	if (write_regvals(ov, aRegvalsInit511)) goto error;
 
-	if (ov511->led_policy == LED_OFF || ov511->led_policy == LED_AUTO)
-		ov51x_led_control(ov511, 0);
+	if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
+		ov51x_led_control(ov, 0);
 
 	/* The OV511+ has undocumented bits in the flow control register.
 	 * Setting it to 0xff fixes the corruption with moving objects. */
-	if (ov511->bridge == BRG_OV511) {
-		if (ov511_write_regvals(ov511, aRegvalsNorm511)) goto error;
-	} else if (ov511->bridge == BRG_OV511PLUS) {
-		if (ov511_write_regvals(ov511, aRegvalsNorm511Plus)) goto error;
+	if (ov->bridge == BRG_OV511) {
+		if (write_regvals(ov, aRegvalsNorm511)) goto error;
+	} else if (ov->bridge == BRG_OV511PLUS) {
+		if (write_regvals(ov, aRegvalsNorm511Plus)) goto error;
 	} else {
 		err("Invalid bridge");
 	}
 
-	if (ov511_init_compression(ov511)) goto error;
+	if (ov511_init_compression(ov)) goto error;
 
-	ov511_set_packet_size(ov511, 0);
+	ov51x_set_packet_size(ov, 0);
 
-	ov511->snap_enabled = snapshot;	
+	ov->snap_enabled = snapshot;	
 
 	/* Test for 7xx0 */
 	PDEBUG(3, "Testing for 0V7xx0");
-	ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
-	if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
-				OV7xx0_I2C_READ_ID) < 0)
+	ov->primary_i2c_slave = OV7xx0_SID;
+	if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
 		goto error;
 
-	if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+	if (i2c_w(ov, 0x12, 0x80) < 0) {
 		/* Test for 6xx0 */
 		PDEBUG(3, "Testing for 0V6xx0");
-		ov511->primary_i2c_slave = OV6xx0_I2C_WRITE_ID;
-		if (ov51x_set_slave_ids(ov511, OV6xx0_I2C_WRITE_ID,
-					OV6xx0_I2C_READ_ID) < 0)
+		ov->primary_i2c_slave = OV6xx0_SID;
+		if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
 			goto error;
 
-		if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+		if (i2c_w(ov, 0x12, 0x80) < 0) {
 			/* Test for 8xx0 */
 			PDEBUG(3, "Testing for 0V8xx0");
-			ov511->primary_i2c_slave = OV8xx0_I2C_WRITE_ID;
-			if (ov51x_set_slave_ids(ov511, OV8xx0_I2C_WRITE_ID,
-						OV8xx0_I2C_READ_ID))
+			ov->primary_i2c_slave = OV8xx0_SID;
+			if (ov51x_set_slave_ids(ov, OV8xx0_SID))
 				goto error;
 
-			if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+			if (i2c_w(ov, 0x12, 0x80) < 0) {
 				/* Test for SAA7111A */
 				PDEBUG(3, "Testing for SAA7111A");
-				ov511->primary_i2c_slave = SAA7111A_I2C_WRITE_ID;
-				if (ov51x_set_slave_ids(ov511, SAA7111A_I2C_WRITE_ID,
-							SAA7111A_I2C_READ_ID))
+				ov->primary_i2c_slave = SAA7111A_SID;
+				if (ov51x_set_slave_ids(ov, SAA7111A_SID))
 					goto error;
 
-				if (ov51x_i2c_write(ov511, 0x0d, 0x00) < 0) {
+				if (i2c_w(ov, 0x0d, 0x00) < 0) {
 					/* Test for KS0127 */
 					PDEBUG(3, "Testing for KS0127");
-					ov511->primary_i2c_slave = KS0127_I2C_WRITE_ID;
-					if (ov51x_set_slave_ids(ov511, KS0127_I2C_WRITE_ID,
-								KS0127_I2C_READ_ID))
+					ov->primary_i2c_slave = KS0127_SID;
+					if (ov51x_set_slave_ids(ov, KS0127_SID))
 						goto error;
 
-					if (ov51x_i2c_write(ov511, 0x10, 0x00) < 0) {
+					if (i2c_w(ov, 0x10, 0x00) < 0) {
 						err("Can't determine sensor slave IDs");
 		 				goto error;
 					} else {
-						if(ks0127_configure(ov511) < 0) {
+						if (ks0127_configure(ov) < 0) {
 							err("Failed to configure KS0127");
 	 						goto error;
 						}
 					}
 				} else {
-					if(saa7111a_configure(ov511) < 0) {
+					if (saa7111a_configure(ov) < 0) {
 						err("Failed to configure SAA7111A");
 	 					goto error;
 					}
@@ -6540,13 +6452,13 @@
 				goto error;
 			}
 		} else {
-			if(ov6xx0_configure(ov511) < 0) {
+			if (ov6xx0_configure(ov) < 0) {
 				err("Failed to configure OV6xx0");
  				goto error;
 			}
 		}
 	} else {
-		if(ov7xx0_configure(ov511) < 0) {
+		if (ov7xx0_configure(ov) < 0) {
 			err("Failed to configure OV7xx0");
 	 		goto error;
 		}
@@ -6562,96 +6474,90 @@
 
 /* This initializes the OV518/OV518+ and the sensor */
 static int 
-ov518_configure(struct usb_ov511 *ov511)
+ov518_configure(struct usb_ov511 *ov)
 {
-	struct usb_device *dev = ov511->dev;
-
 	static struct ov511_regvals aRegvalsInit518[] = {
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x40 },
-	 	{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
-	 	{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3e },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x00 },
-		{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
-		{ OV511_REG_BUS, 0x46, 0x00 }, 
-		{ OV511_REG_BUS, 0x5d, 0x03 },
+		{ OV511_REG_BUS, R51x_SYS_RESET,	0x40 },
+	 	{ OV511_REG_BUS, R51x_SYS_INIT,		0xe1 },
+	 	{ OV511_REG_BUS, R51x_SYS_RESET,	0x3e },
+		{ OV511_REG_BUS, R51x_SYS_INIT,		0xe1 },
+		{ OV511_REG_BUS, R51x_SYS_RESET,	0x00 },
+		{ OV511_REG_BUS, R51x_SYS_INIT,		0xe1 },
+		{ OV511_REG_BUS, 0x46,			0x00 }, 
+		{ OV511_REG_BUS, 0x5d,			0x03 },
 		{ OV511_DONE_BUS, 0x0, 0x00},
 	};
 
 	/* New values, based on Windows driver. Since what they do is not
 	 * known yet, this may be incorrect. */
 	static struct ov511_regvals aRegvalsNorm518[] = {
-		{ OV511_REG_BUS, 0x52, 0x02 }, /* Reset snapshot */
-		{ OV511_REG_BUS, 0x52, 0x01 }, /* Enable snapshot */
-		{ OV511_REG_BUS, 0x31, 0x0f },
-		{ OV511_REG_BUS, 0x5d, 0x03 },
-		{ OV511_REG_BUS, 0x24, 0x9f },
-		{ OV511_REG_BUS, 0x25, 0x90 },
-		{ OV511_REG_BUS, 0x20, 0x00 }, /* Was 0x08 */
-		{ OV511_REG_BUS, 0x51, 0x04 },
-		{ OV511_REG_BUS, 0x71, 0x19 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x02 }, /* Reset */
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 }, /* Enable */
+		{ OV511_REG_BUS, 0x31, 			0x0f },
+		{ OV511_REG_BUS, 0x5d,			0x03 },
+		{ OV511_REG_BUS, 0x24,			0x9f },
+		{ OV511_REG_BUS, 0x25,			0x90 },
+		{ OV511_REG_BUS, 0x20,			0x00 }, /* Was 0x08 */
+		{ OV511_REG_BUS, 0x51,			0x04 },
+		{ OV511_REG_BUS, 0x71,			0x19 },
 		{ OV511_DONE_BUS, 0x0, 0x00 },
 	};
 
 	PDEBUG(4, "");
 
 	/* First 5 bits of custom ID reg are a revision ID on OV518 */
-	info("Device revision %d",
-	     0x1F & ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID));
+	info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID));
 
-	if (ov511_write_regvals(ov511, aRegvalsInit518)) goto error;
+	if (write_regvals(ov, aRegvalsInit518)) goto error;
 
 	/* Set LED GPIO pin to output mode */
-	if (ov511_reg_write_mask(dev, 0x57,0x00, 0x02) < 0) goto error;
+	if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0) goto error;
 
 	/* LED is off by default with OV518; have to explicitly turn it on */
-	if (ov511->led_policy == LED_OFF || ov511->led_policy == LED_AUTO)
-		ov51x_led_control(ov511, 0);
+	if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
+		ov51x_led_control(ov, 0);
 	else
-		ov51x_led_control(ov511, 1);
+		ov51x_led_control(ov, 1);
 
 	/* Don't require compression if dumppix is enabled; otherwise it's
 	 * required. OV518 has no uncompressed mode, to save RAM. */
-	if (!dumppix && !ov511->compress) {
-		ov511->compress = 1;
+	if (!dumppix && !ov->compress) {
+		ov->compress = 1;
 		warn("Compression required with OV518...enabling");
 	}
 
-	if (ov511_write_regvals(ov511, aRegvalsNorm518)) goto error;
+	if (write_regvals(ov, aRegvalsNorm518)) goto error;
 
-	if (ov511_reg_write(dev, 0x2f,0x80) < 0) goto error;
+	if (reg_w(ov, 0x2f, 0x80) < 0) goto error;
 
-	if (ov518_init_compression(ov511)) goto error;
+	if (ov518_init_compression(ov)) goto error;
 
-	ov511_set_packet_size(ov511, 0);
+	ov51x_set_packet_size(ov, 0);
 
-	ov511->snap_enabled = snapshot;
+	ov->snap_enabled = snapshot;
 
 	/* Test for 76xx */
-	ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
-	if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
-				OV7xx0_I2C_READ_ID) < 0)
+	ov->primary_i2c_slave = OV7xx0_SID;
+	if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
 		goto error;
 
 	/* The OV518 must be more aggressive about sensor detection since
 	 * I2C write will never fail if the sensor is not present. We have
 	 * to try to initialize the sensor to detect its presence */
 
-	if (ov51x_init_ov_sensor(ov511) < 0) {
+	if (init_ov_sensor(ov) < 0) {
 		/* Test for 6xx0 */
-		ov511->primary_i2c_slave = OV6xx0_I2C_WRITE_ID;
-		if (ov51x_set_slave_ids(ov511, OV6xx0_I2C_WRITE_ID,
-					OV6xx0_I2C_READ_ID) < 0)
+		ov->primary_i2c_slave = OV6xx0_SID;
+		if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
 			goto error;
 
-		if (ov51x_init_ov_sensor(ov511) < 0) {
+		if (init_ov_sensor(ov) < 0) {
 			/* Test for 8xx0 */
-			ov511->primary_i2c_slave = OV8xx0_I2C_WRITE_ID;
-			if (ov51x_set_slave_ids(ov511, OV8xx0_I2C_WRITE_ID,
-						OV8xx0_I2C_READ_ID) < 0)
+			ov->primary_i2c_slave = OV8xx0_SID;
+			if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
 				goto error;
 
-			if (ov51x_init_ov_sensor(ov511) < 0) {
+			if (init_ov_sensor(ov) < 0) {
 				err("Can't determine sensor slave IDs");
  				goto error;
 			} else {
@@ -6659,21 +6565,25 @@
 				goto error;
 			}
 		} else {
-			if (ov6xx0_configure(ov511) < 0) {
+			if (ov6xx0_configure(ov) < 0) {
 				err("Failed to configure OV6xx0");
  				goto error;
 			}
 		}
 	} else {
-		if (ov7xx0_configure(ov511) < 0) {
+		if (ov7xx0_configure(ov) < 0) {
 			err("Failed to configure OV7xx0");
 	 		goto error;
 		}
 	}
 
+	// FIXME: Sizes > 320x240 are not working yet
+	ov->maxwidth = 320;
+	ov->maxheight = 240;
+
 	// The OV518 cannot go as low as the sensor can
-	ov511->minwidth = 160;
-	ov511->minheight = 120;
+	ov->minwidth = 160;
+	ov->minheight = 120;
 
 	return 0;
 
@@ -6695,7 +6605,7 @@
 	    const struct usb_device_id *id)
 {
 	struct usb_interface_descriptor *interface;
-	struct usb_ov511 *ov511;
+	struct usb_ov511 *ov;
 	int i;
 	int registered = 0;
 
@@ -6716,54 +6626,54 @@
 	/* Since code below may sleep, we use this as a lock */
 	MOD_INC_USE_COUNT;
 
-	if ((ov511 = kmalloc(sizeof(*ov511), GFP_KERNEL)) == NULL) {
-		err("couldn't kmalloc ov511 struct");
-		goto error_unlock;
-	}
-
-	memset(ov511, 0, sizeof(*ov511));
-
-	ov511->dev = dev;
-	ov511->iface = interface->bInterfaceNumber;
-	ov511->led_policy = led;
-	ov511->compress = compress;
-	ov511->lightfreq = lightfreq;
-	ov511->num_inputs = 1;	   /* Video decoder init functs. change this */
-	ov511->stop_during_set = !fastset;
-	ov511->tuner_type = tuner;
-	ov511->backlight = backlight;
-
-	ov511->auto_brt = autobright;
-	ov511->auto_gain = autogain;
-	ov511->auto_exp = autoexp;
+	if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
+		err("couldn't kmalloc ov struct");
+		goto error_out;
+	}
+
+	memset(ov, 0, sizeof(*ov));
+
+	ov->dev = dev;
+	ov->iface = interface->bInterfaceNumber;
+	ov->led_policy = led;
+	ov->compress = compress;
+	ov->lightfreq = lightfreq;
+	ov->num_inputs = 1;	   /* Video decoder init functs. change this */
+	ov->stop_during_set = !fastset;
+	ov->tuner_type = tuner;
+	ov->backlight = backlight;
+
+	ov->auto_brt = autobright;
+	ov->auto_gain = autogain;
+	ov->auto_exp = autoexp;
 
 	switch (dev->descriptor.idProduct) {
 	case PROD_OV511:
 		info("USB OV511 camera found");
-		ov511->bridge = BRG_OV511;
-		ov511->bclass = BCL_OV511;
+		ov->bridge = BRG_OV511;
+		ov->bclass = BCL_OV511;
 		break;
 	case PROD_OV511PLUS:
 		info("USB OV511+ camera found");
-		ov511->bridge = BRG_OV511PLUS;
-		ov511->bclass = BCL_OV511;
+		ov->bridge = BRG_OV511PLUS;
+		ov->bclass = BCL_OV511;
 		break;
 	case PROD_OV518:
 		info("USB OV518 camera found");
-		ov511->bridge = BRG_OV518;
-		ov511->bclass = BCL_OV518;
+		ov->bridge = BRG_OV518;
+		ov->bclass = BCL_OV518;
 		break;
 	case PROD_OV518PLUS:
 		info("USB OV518+ camera found");
-		ov511->bridge = BRG_OV518PLUS;
-		ov511->bclass = BCL_OV518;
+		ov->bridge = BRG_OV518PLUS;
+		ov->bclass = BCL_OV518;
 		break;
 	case PROD_ME2CAM:
 		if (dev->descriptor.idVendor != VEND_MATTEL)
 			goto error;
 		info("Intel Play Me2Cam (OV511+) found");
-		ov511->bridge = BRG_OV511PLUS;
-		ov511->bclass = BCL_OV511;
+		ov->bridge = BRG_OV511PLUS;
+		ov->bclass = BCL_OV511;
 		break;
 	default:
 		err("Unknown product ID 0x%x", dev->descriptor.idProduct);
@@ -6775,47 +6685,53 @@
 	if (force_rgb)
 		info("data format set to RGB");
 
-	init_waitqueue_head(&ov511->wq);
+	init_waitqueue_head(&ov->wq);
 
-	init_MUTEX(&ov511->lock);	/* to 1 == available */
-	init_MUTEX(&ov511->buf_lock);
-	init_MUTEX(&ov511->param_lock);
-	init_MUTEX(&ov511->i2c_lock);
-	ov511->buf_state = BUF_NOT_ALLOCATED;
-
-	if (ov511->bridge == BRG_OV518 ||
-	    ov511->bridge == BRG_OV518PLUS) {
-		if (ov518_configure(ov511) < 0)
+	init_MUTEX(&ov->lock);	/* to 1 == available */
+	init_MUTEX(&ov->buf_lock);
+	init_MUTEX(&ov->param_lock);
+	init_MUTEX(&ov->i2c_lock);
+	init_MUTEX(&ov->cbuf_lock);
+
+	ov->buf_state = BUF_NOT_ALLOCATED;
+
+	/* Must be kmalloc()'ed, for DMA accessibility */
+	ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
+	if (!ov->cbuf)
+		goto error;
+
+	if (ov->bclass == BCL_OV518) {
+		if (ov518_configure(ov) < 0)
 			goto error;
 	} else {
-		if (ov511_configure(ov511) < 0)
+		if (ov511_configure(ov) < 0)
 			goto error;
 	}
 
 	for (i = 0; i < OV511_NUMFRAMES; i++) {
-		ov511->frame[i].framenum = i;
-		init_waitqueue_head(&ov511->frame[i].wq);
+		ov->frame[i].framenum = i;
+		init_waitqueue_head(&ov->frame[i].wq);
 	}
 
 	/* Unnecessary? (This is done on open(). Need to make sure variables
 	 * are properly initialized without this before removing it, though). */
-	if (ov51x_set_default_params(ov511) < 0)
+	if (ov51x_set_default_params(ov) < 0)
 		goto error;
 
 #ifdef OV511_DEBUG
 	if (dump_bridge)
-		ov511_dump_regs(dev);
+		ov511_dump_regs(ov);
 #endif
 
-	memcpy(&ov511->vdev, &ov511_template, sizeof(ov511_template));
-	ov511->vdev.priv = ov511;
+	memcpy(&ov->vdev, &vdev_template, sizeof(vdev_template));
+	ov->vdev.priv = ov;
 
 	for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
 		/* Minor 0 cannot be specified; assume user wants autodetect */
 		if (unit_video[i] == 0)
 			break;
 
-		if (video_register_device(&ov511->vdev, VFL_TYPE_GRABBER,
+		if (video_register_device(&ov->vdev, VFL_TYPE_GRABBER,
 			unit_video[i]) >= 0) {
 			registered = 1;
 			break;
@@ -6824,34 +6740,41 @@
 
 	/* Use the next available one */
 	if (!registered &&
-	    video_register_device(&ov511->vdev, VFL_TYPE_GRABBER, -1) < 0) {
+	    video_register_device(&ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
 		err("video_register_device failed");
 		goto error;
 	}
 
-	info("Device registered on minor %d", ov511->vdev.minor);
+	info("Device registered on minor %d", ov->vdev.minor);
 
 	MOD_DEC_USE_COUNT;
-     	return ov511;
+     	return ov;
 
 error:
 	err("Camera initialization failed");
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 	/* Safe to call even if entry doesn't exist */
-	destroy_proc_ov511_cam(ov511);
+	destroy_proc_ov511_cam(ov);
 #endif
 
+	if (ov->cbuf) {
+		down(&ov->cbuf_lock);
+		kfree(ov->cbuf);
+		ov->cbuf = NULL;
+		up(&ov->cbuf_lock);
+	}
+
 	usb_driver_release_interface(&ov511_driver,
-		&dev->actconfig->interface[ov511->iface]);
+		&dev->actconfig->interface[ov->iface]);
 
 error_dealloc:
-	if (ov511) {
-		kfree(ov511);
-		ov511 = NULL;
+	if (ov) {
+		kfree(ov);
+		ov = NULL;
 	}
 
-error_unlock:
+error_out:
 	MOD_DEC_USE_COUNT;
 	return NULL;
 }
@@ -6860,7 +6783,7 @@
 static void
 ov51x_disconnect(struct usb_device *dev, void *ptr)
 {
-	struct usb_ov511 *ov511 = (struct usb_ov511 *) ptr;
+	struct usb_ov511 *ov = (struct usb_ov511 *) ptr;
 	int n;
 
 	MOD_INC_USE_COUNT;
@@ -6868,48 +6791,53 @@
 	PDEBUG(3, "");
 
 	/* We don't want people trying to open up the device */
-	if (!ov511->user)
-		video_unregister_device(&ov511->vdev);
+	if (!ov->user)
+		video_unregister_device(&ov->vdev);
 	else
 		PDEBUG(3, "Device open...deferring video_unregister_device");
 
 	for (n = 0; n < OV511_NUMFRAMES; n++)
-		ov511->frame[n].grabstate = FRAME_ERROR;
+		ov->frame[n].grabstate = FRAME_ERROR;
 
-	ov511->curframe = -1;
+	ov->curframe = -1;
 
 	/* This will cause the process to request another frame */
 	for (n = 0; n < OV511_NUMFRAMES; n++)
-		if (waitqueue_active(&ov511->frame[n].wq))
-			wake_up_interruptible(&ov511->frame[n].wq);
-	if (waitqueue_active(&ov511->wq))
-		wake_up_interruptible(&ov511->wq);
+		if (waitqueue_active(&ov->frame[n].wq))
+			wake_up_interruptible(&ov->frame[n].wq);
+	if (waitqueue_active(&ov->wq))
+		wake_up_interruptible(&ov->wq);
 
-	ov511->streaming = 0;
+	ov->streaming = 0;
 
 	/* Unschedule all of the iso td's */
 	for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
-		if (ov511->sbuf[n].urb) {
-			ov511->sbuf[n].urb->next = NULL;
-			usb_unlink_urb(ov511->sbuf[n].urb);
-			usb_free_urb(ov511->sbuf[n].urb);
-			ov511->sbuf[n].urb = NULL;
+		if (ov->sbuf[n].urb) {
+			ov->sbuf[n].urb->next = NULL;
+			usb_unlink_urb(ov->sbuf[n].urb);
+			usb_free_urb(ov->sbuf[n].urb);
+			ov->sbuf[n].urb = NULL;
 		}
 	}
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
-        destroy_proc_ov511_cam(ov511);
+        destroy_proc_ov511_cam(ov);
 #endif
 
 	usb_driver_release_interface(&ov511_driver,
-		&ov511->dev->actconfig->interface[ov511->iface]);
-	ov511->dev = NULL;
+		&ov->dev->actconfig->interface[ov->iface]);
+	ov->dev = NULL;
 
 	/* Free the memory */
-	if (ov511 && !ov511->user) {
-		ov511_dealloc(ov511, 1);
-		kfree(ov511);
-		ov511 = NULL;
+	if (ov && !ov->user) {
+		down(&ov->cbuf_lock);
+		kfree(ov->cbuf);
+		ov->cbuf = NULL;
+		up(&ov->cbuf_lock);
+
+		ov51x_dealloc(ov, 1);
+		kfree(ov);
+		ov = NULL;
 	}
 
 	MOD_DEC_USE_COUNT;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/ov511.h linux/drivers/usb/ov511.h
--- linux.orig/drivers/usb/ov511.h	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/ov511.h	2002-07-20 01:08:33.000000000 +0000
@@ -9,11 +9,11 @@
 #define OV511_DEBUG	/* Turn on debug messages */
 
 #ifdef OV511_DEBUG
-#  define PDEBUG(level, fmt, args...) \
-if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
-	## args)
+	#define PDEBUG(level, fmt, args...) \
+		if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt,\
+		__LINE__ , ## args)
 #else
-#  define PDEBUG(level, fmt, args...) do {} while(0)
+	#define PDEBUG(level, fmt, args...) do {} while(0)
 #endif
 
 /* This macro restricts an int variable to an inclusive range */
@@ -36,98 +36,105 @@
 #define VEND_MATTEL	0x0813
 #define PROD_ME2CAM	0x0002
 
+/* --------------------------------- */
+/*     OV51x REGISTER MNEMONICS      */
+/* --------------------------------- */
+
 /* Camera interface register numbers */
-#define OV511_REG_CAMERA_DELAY_MODE		0x10
-#define OV511_REG_CAMERA_EDGE_MODE		0x11
-#define OV511_REG_CAMERA_CLAMPED_PIXEL_NUM	0x12
-#define OV511_REG_CAMERA_CLAMPED_LINE_NUM	0x13
-#define OV511_REG_CAMERA_PIXEL_DIVISOR		0x14
-#define OV511_REG_CAMERA_LINE_DIVISOR		0x15
-#define OV511_REG_CAMERA_DATA_INPUT_SELECT	0x16
-#define OV511_REG_CAMERA_RESERVED_LINE_MODE	0x17
-#define OV511_REG_CAMERA_BITMASK		0x18
+#define R511_CAM_DELAY		0x10
+#define R511_CAM_EDGE		0x11
+#define R511_CAM_PXCNT		0x12
+#define R511_CAM_LNCNT		0x13
+#define R511_CAM_PXDIV		0x14
+#define R511_CAM_LNDIV		0x15
+#define R511_CAM_UV_EN		0x16
+#define R511_CAM_LINE_MODE	0x17
+#define R511_CAM_OPTS		0x18
 
 /* Snapshot mode camera interface register numbers */
-#define OV511_REG_SNAP_CAPTURED_FRAME		0x19
-#define OV511_REG_SNAP_CLAMPED_PIXEL_NUM	0x1A
-#define OV511_REG_SNAP_CLAMPED_LINE_NUM		0x1B
-#define OV511_REG_SNAP_PIXEL_DIVISOR		0x1C
-#define OV511_REG_SNAP_LINE_DIVISOR		0x1D
-#define OV511_REG_SNAP_DATA_INPUT_SELECT	0x1E
-#define OV511_REG_SNAP_BITMASK			0x1F
+#define R511_SNAP_FRAME		0x19
+#define R511_SNAP_PXCNT		0x1A
+#define R511_SNAP_LNCNT		0x1B
+#define R511_SNAP_PXDIV		0x1C
+#define R511_SNAP_LNDIV		0x1D
+#define R511_SNAP_UV_EN		0x1E
+#define R511_SNAP_OPTS		0x1F
 
 /* DRAM register numbers */
-#define OV511_REG_DRAM_ENABLE_FLOW_CONTROL	0x20
-#define OV511_REG_DRAM_READ_CYCLE_PREDICT	0x21
-#define OV511_REG_DRAM_MANUAL_READ_CYCLE	0x22
-#define OV511_REG_DRAM_REFRESH_COUNTER		0x23
+#define R511_DRAM_FLOW_CTL	0x20
+#define R511_DRAM_ARCP		0x21
+#define R511_DRAM_MRC		0x22
+#define R511_DRAM_RFC		0x23
 
 /* ISO FIFO register numbers */
-#define OV511_REG_FIFO_PACKET_SIZE		0x30
-#define OV511_REG_FIFO_BITMASK			0x31
+#define R51x_FIFO_PSIZE		0x30	/* 2 bytes wide w/ OV518(+) */
+#define R511_FIFO_OPTS		0x31
 
-/* PIO register numbers */
-#define OV511_REG_PIO_BITMASK			0x38
-#define OV511_REG_PIO_DATA_PORT			0x39
-#define OV511_REG_PIO_BIST			0x3E
-
-/* I2C register numbers */
-#define OV511_REG_I2C_CONTROL			0x40
-#define OV518_REG_I2C_CONTROL			0x47	/* OV518(+) only */
-#define OV511_REG_I2C_SLAVE_ID_WRITE		0x41
-#define OV511_REG_I2C_SUB_ADDRESS_3_BYTE	0x42
-#define OV511_REG_I2C_SUB_ADDRESS_2_BYTE	0x43
-#define OV511_REG_I2C_SLAVE_ID_READ		0x44
-#define OV511_REG_I2C_DATA_PORT			0x45
-#define OV511_REG_I2C_CLOCK_PRESCALER		0x46
-#define OV511_REG_I2C_TIME_OUT_COUNTER		0x47
-
-/* I2C snapshot register numbers */
-#define OV511_REG_I2C_SNAP_SUB_ADDRESS		0x48
-#define OV511_REG_I2C_SNAP_DATA_PORT		0x49
-
-/* System control register numbers */
-#define OV511_REG_SYSTEM_RESET			0x50
-#define 	OV511_RESET_UDC			0x01
-#define 	OV511_RESET_I2C			0x02
-#define 	OV511_RESET_FIFO		0x04
-#define 	OV511_RESET_OMNICE		0x08
-#define 	OV511_RESET_DRAM_INTF		0x10
-#define 	OV511_RESET_CAMERA_INTF		0x20
-#define 	OV511_RESET_OV511		0x40
-#define 	OV511_RESET_NOREGS		0x3F /* All but OV511 & regs */
-#define 	OV511_RESET_ALL			0x7F
-#define OV511_REG_SYSTEM_CLOCK_DIVISOR		0x51
-#define OV511_REG_SYSTEM_SNAPSHOT		0x52
-#define OV511_REG_SYSTEM_INIT         		0x53
-#define OV511_REG_SYSTEM_PWR_CLK		0x54 /* OV511+/OV518(+) only */
-#define OV511_REG_SYSTEM_LED_CTL		0x55	/* OV511+ only */
-#define OV518_REG_GPIO_IN			0x55	/* OV518(+) only */
-#define OV518_REG_GPIO_OUT			0x56	/* OV518(+) only */
-#define OV518_REG_GPIO_CTL			0x57	/* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_IN			0x58	/* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_CLEAR		0x59	/* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_POLARITY		0x5a	/* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_EN			0x5b	/* OV518(+) only */
-#define OV518_REG_GPIO_RESET			0x5c	/* OV518(+) only */
-#define OV511_REG_SYSTEM_USER_DEFINED		0x5E
-#define OV511_REG_SYSTEM_CUSTOM_ID		0x5F
-
-/* OmniCE register numbers */
-#define OV511_OMNICE_PREDICTION_HORIZ_Y		0x70
-#define OV511_OMNICE_PREDICTION_HORIZ_UV	0x71
-#define OV511_OMNICE_PREDICTION_VERT_Y		0x72
-#define OV511_OMNICE_PREDICTION_VERT_UV		0x73
-#define OV511_OMNICE_QUANTIZATION_HORIZ_Y	0x74
-#define OV511_OMNICE_QUANTIZATION_HORIZ_UV	0x75
-#define OV511_OMNICE_QUANTIZATION_VERT_Y	0x76
-#define OV511_OMNICE_QUANTIZATION_VERT_UV	0x77
-#define OV511_OMNICE_ENABLE			0x78
-#define OV511_OMNICE_LUT_ENABLE			0x79		
-#define OV511_OMNICE_Y_LUT_BEGIN		0x80
-#define OV511_OMNICE_Y_LUT_END			0x9F
-#define OV511_OMNICE_UV_LUT_BEGIN		0xA0
-#define OV511_OMNICE_UV_LUT_END			0xBF
+/* Parallel IO register numbers */
+#define R511_PIO_OPTS		0x38
+#define R511_PIO_DATA		0x39
+#define R511_PIO_BIST		0x3E
+#define R518_GPIO_IN		0x55	/* OV518(+) only */
+#define R518_GPIO_OUT		0x56	/* OV518(+) only */
+#define R518_GPIO_CTL		0x57	/* OV518(+) only */
+#define R518_GPIO_PULSE_IN	0x58	/* OV518(+) only */
+#define R518_GPIO_PULSE_CLEAR	0x59	/* OV518(+) only */
+#define R518_GPIO_PULSE_POL	0x5a	/* OV518(+) only */
+#define R518_GPIO_PULSE_EN	0x5b	/* OV518(+) only */
+#define R518_GPIO_RESET		0x5c	/* OV518(+) only */
+
+/* I2C registers */
+#define R511_I2C_CTL		0x40
+#define R518_I2C_CTL		0x47	/* OV518(+) only */
+#define R51x_I2C_W_SID		0x41
+#define R51x_I2C_SADDR_3	0x42
+#define R51x_I2C_SADDR_2	0x43
+#define R51x_I2C_R_SID		0x44
+#define R51x_I2C_DATA		0x45
+#define R51x_I2C_CLOCK		0x46
+#define R51x_I2C_TIMEOUT	0x47
+
+/* I2C snapshot registers */
+#define R511_SI2C_SADDR_3	0x48
+#define R511_SI2C_DATA		0x49
+
+/* System control registers */
+#define R51x_SYS_RESET		0x50
+		/* Reset type definitions */
+#define 	OV511_RESET_UDC		0x01
+#define 	OV511_RESET_I2C		0x02
+#define 	OV511_RESET_FIFO	0x04
+#define 	OV511_RESET_OMNICE	0x08
+#define 	OV511_RESET_DRAM	0x10
+#define 	OV511_RESET_CAM_INT	0x20
+#define 	OV511_RESET_OV511	0x40
+#define 	OV511_RESET_NOREGS	0x3F /* All but OV511 & regs */
+#define 	OV511_RESET_ALL		0x7F
+
+#define R511_SYS_CLOCK_DIV	0x51
+#define R51x_SYS_SNAP		0x52
+#define R51x_SYS_INIT         	0x53
+#define R511_SYS_PWR_CLK	0x54 /* OV511+/OV518(+) only */
+#define R511_SYS_LED_CTL	0x55 /* OV511+ only */
+#define R511_SYS_USER		0x5E
+#define R511_SYS_CUST_ID	0x5F
+
+/* OmniCE (compression) registers */
+#define R511_COMP_PHY		0x70
+#define R511_COMP_PHUV		0x71
+#define R511_COMP_PVY		0x72
+#define R511_COMP_PVUV		0x73
+#define R511_COMP_QHY		0x74
+#define R511_COMP_QHUV		0x75
+#define R511_COMP_QVY		0x76
+#define R511_COMP_QVUV		0x77
+#define R511_COMP_EN		0x78
+#define R511_COMP_LUT_EN	0x79		
+#define R511_COMP_LUT_BEGIN	0x80
+
+/* --------------------------------- */
+/*         ALTERNATE NUMBERS         */
+/* --------------------------------- */
 
 /* Alternate numbers for various max packet sizes (OV511 only) */
 #define OV511_ALT_SIZE_992	0
@@ -159,6 +166,10 @@
 #define OV518_ALT_SIZE_768	6
 #define OV518_ALT_SIZE_896	7
 
+/* --------------------------------- */
+/*     OV7610 REGISTER MNEMONICS     */
+/* --------------------------------- */
+
 /* OV7610 registers */
 #define OV7610_REG_GAIN          0x00	/* gain setting (5:0) */
 #define OV7610_REG_BLUE          0x01	/* blue channel balance */
@@ -210,26 +221,27 @@
 					/* 36-37 reserved */
 #define OV7610_REG_COM_K         0x38	/* misc registers */
 
+/* --------------------------------- */
+/*           I2C ADDRESSES           */
+/* --------------------------------- */
+
+#define OV7xx0_SID   0x42
+#define OV6xx0_SID   0xC0
+#define OV8xx0_SID   0xA0
+#define KS0127_SID   0xD8
+#define SAA7111A_SID 0x48
+
+/* --------------------------------- */
+/*       MISCELLANEOUS DEFINES       */
+/* --------------------------------- */
+
+#define I2C_CLOCK_PRESCALER 	0x03
+
 #define FRAMES_PER_DESC		10	/* FIXME - What should this be? */
-#define FRAME_SIZE_PER_DESC	993	/* FIXME - Deprecated */
 #define MAX_FRAME_SIZE_PER_DESC	993	/* For statically allocated stuff */
 #define PIXELS_PER_SEG		256	/* Pixels per segment */
 
-#define OV511_ENDPOINT_ADDRESS 1	/* Isoc endpoint number */
-
-/* I2C addresses */
-#define OV7xx0_I2C_WRITE_ID   0x42
-#define OV7xx0_I2C_READ_ID    0x43
-#define OV6xx0_I2C_WRITE_ID   0xC0
-#define OV6xx0_I2C_READ_ID    0xC1
-#define OV8xx0_I2C_WRITE_ID   0xA0
-#define OV8xx0_I2C_READ_ID    0xA1
-#define KS0127_I2C_WRITE_ID   0xD8
-#define KS0127_I2C_READ_ID    0xD9
-#define SAA7111A_I2C_WRITE_ID 0x48
-#define SAA7111A_I2C_READ_ID  0x49
-
-#define OV511_I2C_CLOCK_PRESCALER 0x03
+#define OV511_ENDPOINT_ADDRESS	1	/* Isoc endpoint number */
 
 /* Bridge types */
 enum {
@@ -366,7 +378,7 @@
 
 struct ov511_sbuf {
 	char *data;
-	urb_t *urb;
+	struct urb *urb;
 };
 
 enum {
@@ -429,11 +441,14 @@
 
 #define OV511_NUMFRAMES	2
 #if OV511_NUMFRAMES > VIDEO_MAX_FRAME
-#error "OV511_NUMFRAMES is too high"
+	#error "OV511_NUMFRAMES is too high"
 #endif
 
 #define OV511_NUMSBUF		2
 
+/* Control transfers use up to 4 bytes */
+#define OV511_CBUF_SIZE		4
+
 struct usb_ov511 {
 	struct video_device vdev;
 
@@ -535,6 +550,10 @@
 	/* I2C interface to kernel */
 	struct semaphore i2c_lock;	  /* Protect I2C controller regs */
 	unsigned char primary_i2c_slave;  /* I2C write id of sensor */
+
+	/* Control transaction stuff */
+	unsigned char *cbuf;		/* Buffer for payload */
+	struct semaphore cbuf_lock;
 };
 
 struct cam_list {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c
--- linux.orig/drivers/usb/pegasus.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/pegasus.c	2002-07-20 01:08:35.000000000 +0000
@@ -1,7 +1,7 @@
 /*
 **	Pegasus: USB 10/100Mbps/HomePNA (1Mbps) Controller
 **
-**	Copyright (c) 1999-2001 Petko Manolov (pmanolov@lnxw.com)
+**	Copyright (c) 1999-2002 Petko Manolov (petkan@users.sourceforge.net)
 **	
 **
 **	ChangeLog:
@@ -21,6 +21,7 @@
 **			TODO: suppressing HCD warnings spewage on disconnect.
 **		v0.4.13	Ethernet address is now set at probe(), not at open()
 **			time as this seems to break dhcpd. 
+**		v0.4.25	ethtool support added.
 */
 
 /*
@@ -46,23 +47,29 @@
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/module.h>
+#include <asm/uaccess.h>
 #include "pegasus.h"
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.4.22 (2001/12/07)"
-#define DRIVER_AUTHOR "Petko Manolov <pmanolov@lnxw.com>"
+#define DRIVER_VERSION "v0.4.26 (2002/03/21)"
+#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
 #define	PEGASUS_USE_INTR
 #define	PEGASUS_WRITE_EEPROM
+#define	BMSR_MEDIA	(BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \
+			BMSR_100FULL | BMSR_ANEGCAPABLE)
 
 static int loopback = 0;
-static int mii_mode = 0;
+static int mii_mode = 1;
 static int multicast_filter_limit = 32;
+static DECLARE_MUTEX(gsem);
 
 static struct usb_eth_dev usb_dev_id[] = {
 #define	PEGASUS_DEV(pn, vid, pid, flags)	\
@@ -94,7 +101,7 @@
 
 static int update_eth_regs_async( pegasus_t * );
 /* Aargh!!! I _really_ hate such tweaks */
-static void ctrl_callback( urb_t *urb )
+static void ctrl_callback( struct urb *urb )
 {
 	pegasus_t	*pegasus = urb->context;
 
@@ -102,7 +109,7 @@
 		return;
 
 	switch ( urb->status ) {
-		case USB_ST_NOERROR:
+		case 0:
 			if ( pegasus->flags & ETH_REGS_CHANGE ) {
 				pegasus->flags &= ~ETH_REGS_CHANGE;
 				pegasus->flags |= ETH_REGS_CHANGED;
@@ -110,12 +117,12 @@
 				return;
 			}
 			break;
-		case USB_ST_URB_PENDING:
+		case -EINPROGRESS:
 			return;
-		case USB_ST_URB_KILLED:
+		case -ENOENT:
 			break;
 		default:
-			warn( __FUNCTION__ " status %d", urb->status);
+			warn("%s: status %d", __FUNCTION__, urb->status);
 	}
 	pegasus->flags &= ~ETH_REGS_CHANGED;
 	wake_up(&pegasus->ctrl_wait );
@@ -147,9 +154,9 @@
 	pegasus->dr.value = cpu_to_le16 (0);
 	pegasus->dr.index = cpu_to_le16p(&indx);
 	pegasus->dr.length = cpu_to_le16p(&size);
-	pegasus->ctrl_urb.transfer_buffer_length = size;
+	pegasus->ctrl_urb->transfer_buffer_length = size;
 
-	FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+	FILL_CONTROL_URB( pegasus->ctrl_urb, pegasus->usb,
 			  usb_rcvctrlpipe(pegasus->usb,0),
 			  (char *)&pegasus->dr,
 			  buffer, size, ctrl_callback, pegasus );
@@ -157,8 +164,8 @@
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_UNINTERRUPTIBLE );
 
-	if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
-		err( __FUNCTION__ " BAD CTRLs %d", ret);
+	if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) {
+		err("%s: BAD CTRLs %d", __FUNCTION__, ret);
 		goto out;
 	}
 
@@ -197,9 +204,9 @@
 	pegasus->dr.value = cpu_to_le16 (0);
 	pegasus->dr.index = cpu_to_le16p( &indx );
 	pegasus->dr.length = cpu_to_le16p( &size );
-	pegasus->ctrl_urb.transfer_buffer_length = size;
+	pegasus->ctrl_urb->transfer_buffer_length = size;
 
-	FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+	FILL_CONTROL_URB( pegasus->ctrl_urb, pegasus->usb,
 			  usb_sndctrlpipe(pegasus->usb,0),
 			  (char *)&pegasus->dr,
 			  buffer, size, ctrl_callback, pegasus );
@@ -207,8 +214,8 @@
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_UNINTERRUPTIBLE );
 
-	if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
-		err( __FUNCTION__ " BAD CTRL %d", ret);
+	if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) {
+		err("%s: BAD CTRL %d", __FUNCTION__, ret);
 		goto out;
 	}
 	
@@ -247,9 +254,9 @@
 	pegasus->dr.value = cpu_to_le16p( &dat);
 	pegasus->dr.index = cpu_to_le16p( &indx );
 	pegasus->dr.length = cpu_to_le16( 1 );
-	pegasus->ctrl_urb.transfer_buffer_length = 1;
+	pegasus->ctrl_urb->transfer_buffer_length = 1;
 
-	FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+	FILL_CONTROL_URB( pegasus->ctrl_urb, pegasus->usb,
 			  usb_sndctrlpipe(pegasus->usb,0),
 			  (char *)&pegasus->dr,
 			  buffer, 1, ctrl_callback, pegasus );
@@ -257,8 +264,8 @@
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_UNINTERRUPTIBLE );
 
-	if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
-		err( __FUNCTION__ " BAD CTRL %d", ret);
+	if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) {
+		err("%s: BAD CTRL %d", __FUNCTION__, ret);
 		goto out;
 	}
 
@@ -280,15 +287,15 @@
 	pegasus->dr.value = 0;
 	pegasus->dr.index =  cpu_to_le16(EthCtrl0);
 	pegasus->dr.length = cpu_to_le16(3);
-	pegasus->ctrl_urb.transfer_buffer_length = 3;
+	pegasus->ctrl_urb->transfer_buffer_length = 3;
 
-	FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+	FILL_CONTROL_URB( pegasus->ctrl_urb, pegasus->usb,
 			  usb_sndctrlpipe(pegasus->usb,0),
 			  (char *)&pegasus->dr,
 			  pegasus->eth_regs, 3, ctrl_callback, pegasus );
 
-	if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
-		err( __FUNCTION__ " BAD CTRL %d, flags %x",ret,pegasus->flags );
+	if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) )
+		err("%s: BAD CTRL %d, flgs %x",__FUNCTION__,ret,pegasus->flags);
 
 	return	ret;
 }
@@ -313,7 +320,7 @@
 		*regd = le16_to_cpu(regdi);
 		return	0;
 	}
-	warn( __FUNCTION__ " failed" );
+	warn("%s: failed", __FUNCTION__);
 	
 	return 1;
 }
@@ -335,7 +342,7 @@
 	}
 	if ( i < REG_TIMEOUT )
 		return	0;
-	warn( __FUNCTION__ " failed" );
+	warn("%s: failed", __FUNCTION__);
 
 	return 1;
 }
@@ -361,7 +368,7 @@
 		*retdata = le16_to_cpu (retdatai);
 		return	0;
 	}
-	warn( __FUNCTION__ " failed" );
+	warn("%s: failed", __FUNCTION__);
 
 	return -1;
 }
@@ -405,7 +412,7 @@
 	disable_eprom_write( pegasus );
 	if ( i < REG_TIMEOUT )
 		return	0;
-	warn( __FUNCTION__ " failed" );
+	warn("%s: failed", __FUNCTION__);
 	return	-1;
 }
 #endif	/* PEGASUS_WRITE_EEPROM */
@@ -455,14 +462,18 @@
 	if ( i == REG_TIMEOUT )
 		return 1;
 
-	if ( usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
-	     usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK ) {
+	if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
+	    usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
 		__u16	auxmode;
 
-		read_mii_word( pegasus, 0, 0x1b, &auxmode );
-		write_mii_word( pegasus, 0, 0x1b, auxmode | 4 );
+		read_mii_word(pegasus, 1, 0x1b, &auxmode);
+		write_mii_word(pegasus, 1, 0x1b, auxmode | 4);
+	}
+	if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
+		__u16	auxmode;
+		read_mii_word(pegasus, 3, 0x1b, &auxmode);
+		write_mii_word(pegasus, 3, 0x1b, auxmode | 4);
 	}
-
 	return	0;
 }
 
@@ -473,22 +484,22 @@
 	__u8	data[4];
 	pegasus_t *pegasus = dev->priv;
 
-
-	if ( read_mii_word(pegasus, pegasus->phy, MII_BMSR, &bmsr) ) 
-		return 1;
-	if ( !(bmsr & 0x20) && !loopback ) 
+	/* read twice 'cos this is a latch bit */
+	read_mii_word(pegasus, pegasus->phy, MII_BMSR, &bmsr);
+	read_mii_word(pegasus, pegasus->phy, MII_BMSR, &bmsr);
+	if ( !(bmsr & 4) && !loopback ) 
 		warn( "%s: link NOT established (0x%x) - check the cable.",
 			dev->name, bmsr );
-	if ( read_mii_word(pegasus, pegasus->phy, MII_ANLPA, &linkpart) )
+	if ( read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart) )
 		return 2;
 	if ( !(linkpart & 1) )
 		warn( "link partner stat %x", linkpart );
 
 	data[0] = 0xc9;
 	data[1] = 0;
-	if ( linkpart & (ANLPA_100TX_FD | ANLPA_10T_FD) )
+	if ( linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL) )
 		data[1] |= 0x20; /* set full duplex */
-	if ( linkpart & (ANLPA_100TX_FD | ANLPA_100TX_HD) )
+	if ( linkpart & (ADVERTISE_100FULL | ADVERTISE_100HALF) )
 		data[1] |= 0x10; /* set 100 Mbps */
 	if ( mii_mode )
 		data[1] = 0;
@@ -526,9 +537,9 @@
 	pegasus->flags |= PEGASUS_RX_BUSY;
 
 	switch ( urb->status ) {
-		case USB_ST_NOERROR:
+		case 0:
 			break;
-		case USB_ST_NORESPONSE:
+		case -ETIMEDOUT:
 			dbg( "reset MAC" );
 			pegasus->flags &= ~PEGASUS_RX_BUSY;
 			break;
@@ -569,12 +580,12 @@
 	pegasus->stats.rx_bytes += pkt_len;
 
 goon:
-	FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb,
+	FILL_BULK_URB( pegasus->rx_urb, pegasus->usb,
 			usb_rcvbulkpipe(pegasus->usb, 1),
 			pegasus->rx_buff, PEGASUS_MAX_MTU, 
 			read_bulk_callback, pegasus );
-	if ( (res = usb_submit_urb(&pegasus->rx_urb)) )
-		warn( __FUNCTION__ " failed submint rx_urb %d", res);
+	if ( (res = usb_submit_urb(pegasus->rx_urb)) )
+		warn("%s: failed submint rx_urb %d", __FUNCTION__, res);
 	pegasus->flags &= ~PEGASUS_RX_BUSY;
 }
 
@@ -607,9 +618,9 @@
 		return;
 		
 	switch ( urb->status ) {
-		case USB_ST_NOERROR:
+		case 0:
 			break;
-		case USB_ST_URB_KILLED:
+		case -ENOENT:
 			return;
 		default:
 			info("intr status %d", urb->status);
@@ -639,8 +650,8 @@
 		return;
 		
 	warn("%s: Tx timed out.", net->name);
-	pegasus->tx_urb.transfer_flags |= USB_ASYNC_UNLINK;
-	usb_unlink_urb( &pegasus->tx_urb );
+	pegasus->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;
+	usb_unlink_urb( pegasus->tx_urb );
 	pegasus->stats.tx_errors++;
 }
 
@@ -656,12 +667,12 @@
 		
 	((__u16 *)pegasus->tx_buff)[0] = cpu_to_le16( l16 );
 	memcpy(pegasus->tx_buff+2, skb->data, skb->len);
-	FILL_BULK_URB( &pegasus->tx_urb, pegasus->usb,
+	FILL_BULK_URB( pegasus->tx_urb, pegasus->usb,
 			usb_sndbulkpipe(pegasus->usb, 2),
 			pegasus->tx_buff, PEGASUS_MAX_MTU, 
 			write_bulk_callback, pegasus );
-	pegasus->tx_urb.transfer_buffer_length = count;
-	if ((res = usb_submit_urb(&pegasus->tx_urb))) {
+	pegasus->tx_urb->transfer_buffer_length = count;
+	if ((res = usb_submit_urb(pegasus->tx_urb))) {
 		warn("failed tx_urb %d", res);
 		pegasus->stats.tx_errors++;
 		netif_start_queue( net );
@@ -708,33 +719,56 @@
 }
 
 
+static void set_carrier(struct net_device *net)
+{
+	pegasus_t	*pegasus;
+	short		tmp;
+
+	pegasus = net->priv;
+	read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp);
+	if (tmp & BMSR_LSTATUS)
+		netif_carrier_on(net);
+	else
+		netif_carrier_off(net);
+	
+}
+
+
 static int pegasus_open(struct net_device *net)
 {
 	pegasus_t *pegasus = (pegasus_t *)net->priv;
 	int	res;
 
-	if ( (res = enable_net_traffic(net, pegasus->usb)) ) {
-		err("can't enable_net_traffic() - %d", res);
-		return -EIO;
-	}
-	FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb,
+
+	down(&pegasus->sem);
+	FILL_BULK_URB( pegasus->rx_urb, pegasus->usb,
 			usb_rcvbulkpipe(pegasus->usb, 1),
 			pegasus->rx_buff, PEGASUS_MAX_MTU, 
 			read_bulk_callback, pegasus );
-	if ( (res = usb_submit_urb(&pegasus->rx_urb)) )
-		warn( __FUNCTION__ " failed rx_urb %d", res );
+	if ( (res = usb_submit_urb(pegasus->rx_urb)) )
+		warn("%s: failed rx_urb %d", __FUNCTION__, res);
 #ifdef	PEGASUS_USE_INTR
-	FILL_INT_URB( &pegasus->intr_urb, pegasus->usb,
+	FILL_INT_URB( pegasus->intr_urb, pegasus->usb,
 			usb_rcvintpipe(pegasus->usb, 3),
 			pegasus->intr_buff, sizeof(pegasus->intr_buff),
 			intr_callback, pegasus, pegasus->intr_interval );
-	if ( (res = usb_submit_urb(&pegasus->intr_urb)) )
-		warn( __FUNCTION__ " failed intr_urb %d", res);
+	if ( (res = usb_submit_urb(pegasus->intr_urb)) )
+		warn("%s: failed intr_urb %d", __FUNCTION__, res);
 #endif
 	netif_start_queue( net );
 	pegasus->flags |= PEGASUS_RUNNING;
+	if ( (res = enable_net_traffic(net, pegasus->usb)) ) {
+		err("can't enable_net_traffic() - %d", res);
+		res = -EIO;
+		goto exit;
+	}
 
-	return 0;
+	set_carrier(net);
+	res = 0;
+exit:
+	up(&pegasus->sem);
+	
+	return res;
 }
 
 
@@ -742,41 +776,132 @@
 {
 	pegasus_t	*pegasus = net->priv;
 
+	down(&pegasus->sem);
 	pegasus->flags &= ~PEGASUS_RUNNING;
 	netif_stop_queue( net );
 	if ( !(pegasus->flags & PEGASUS_UNPLUG) )
 		disable_net_traffic( pegasus );
 
-	usb_unlink_urb( &pegasus->rx_urb );
-	usb_unlink_urb( &pegasus->tx_urb );
-	usb_unlink_urb( &pegasus->ctrl_urb );
+	usb_unlink_urb( pegasus->rx_urb );
+	usb_unlink_urb( pegasus->tx_urb );
+	usb_unlink_urb( pegasus->ctrl_urb );
 #ifdef	PEGASUS_USE_INTR
-	usb_unlink_urb( &pegasus->intr_urb );
+	usb_unlink_urb( pegasus->intr_urb );
 #endif
-
+	up(&pegasus->sem);
+	
 	return 0;
 }
 
 
+static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
+{
+	pegasus_t	*pegasus;
+	int		cmd;
+	char		tmp[128];
+
+	pegasus = net->priv;
+	if (get_user(cmd, (int *)uaddr))
+		return -EFAULT;
+	switch (cmd) {
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
+		strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
+		sprintf(tmp, "usb%d:%d", pegasus->usb->bus->busnum,
+		        pegasus->usb->devnum);
+		strncpy(info.bus_info, tmp, ETHTOOL_BUSINFO_LEN);
+		if (copy_to_user(uaddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_GSET: {
+		struct ethtool_cmd ecmd;
+		short	lpa, bmcr;
+
+		if (copy_from_user(&ecmd, uaddr, sizeof(ecmd)))
+			return -EFAULT;
+		ecmd.supported = (SUPPORTED_10baseT_Half |
+		                 SUPPORTED_10baseT_Full |
+		                 SUPPORTED_100baseT_Half |
+		                 SUPPORTED_100baseT_Full |
+		                 SUPPORTED_Autoneg |
+		                 SUPPORTED_TP |
+		                 SUPPORTED_MII);
+		ecmd.port = PORT_TP;
+		ecmd.transceiver = XCVR_INTERNAL;
+		ecmd.phy_address = pegasus->phy;
+		read_mii_word(pegasus, pegasus->phy, MII_BMCR, &bmcr);
+		read_mii_word(pegasus, pegasus->phy, MII_LPA, &lpa);
+		if (bmcr & BMCR_ANENABLE) {
+			ecmd.autoneg = AUTONEG_ENABLE;
+			ecmd.speed = lpa & (LPA_100HALF|LPA_100FULL) ?
+		                     SPEED_100 : SPEED_10;
+			if (ecmd.speed == SPEED_100)
+				ecmd.duplex = lpa & LPA_100FULL ?
+				              DUPLEX_FULL : DUPLEX_HALF;
+			else
+				ecmd.duplex = lpa & LPA_10FULL ?
+				              DUPLEX_FULL : DUPLEX_HALF;
+		} else {
+			ecmd.autoneg = AUTONEG_DISABLE;
+			ecmd.speed = bmcr & BMCR_SPEED100 ? 
+			             SPEED_100 : SPEED_10;
+			ecmd.duplex = bmcr & BMCR_FULLDPLX ?
+			              DUPLEX_FULL : DUPLEX_HALF;
+		}
+		if (copy_to_user(uaddr, &ecmd, sizeof(ecmd)))
+			return -EFAULT;
+		
+		return 0;
+	}
+	case ETHTOOL_SSET: {
+		return -EOPNOTSUPP;
+	}
+	case ETHTOOL_GLINK: {
+		struct ethtool_value edata = {ETHTOOL_GLINK};
+		edata.data = netif_carrier_ok(net);
+		if (copy_to_user(uaddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+
 static int pegasus_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
 {
 	__u16 *data = (__u16 *)&rq->ifr_data;
 	pegasus_t	*pegasus = net->priv;
+	int	res;
 
+	down(&pegasus->sem);
 	switch(cmd) {
-		case SIOCDEVPRIVATE:
-			data[0] = pegasus->phy;
-		case SIOCDEVPRIVATE+1:
-			read_mii_word(pegasus, data[0], data[1]&0x1f, &data[3]);
-			return 0;
-		case SIOCDEVPRIVATE+2:
-			if ( !capable(CAP_NET_ADMIN) )
-				return -EPERM;
-			write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]);
-			return 0;
-		default:
-			return -EOPNOTSUPP;
+	case SIOCETHTOOL:
+		res = pegasus_ethtool_ioctl(net, rq->ifr_data);
+		break;
+	case SIOCDEVPRIVATE:
+		data[0] = pegasus->phy;
+	case SIOCDEVPRIVATE+1:
+		read_mii_word(pegasus, data[0], data[1]&0x1f, &data[3]);
+		res = 0;
+		break;
+	case SIOCDEVPRIVATE+2:
+		if ( !capable(CAP_NET_ADMIN) ) {
+			up(&pegasus->sem);
+			return -EPERM;
+		}
+		write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]);
+		res = 0;
+		break;
+	default:
+		res = -EOPNOTSUPP;
 	}
+	up(&pegasus->sem);
+
+	return res;
 }
 
 
@@ -800,7 +925,7 @@
 	}
 
 	pegasus->flags |= ETH_REGS_CHANGE;
-	ctrl_callback( &pegasus->ctrl_urb );
+	ctrl_callback( pegasus->ctrl_urb );
 
 	netif_wake_queue(net);
 }
@@ -846,9 +971,10 @@
 		return NULL;
 	}
 
+	down(&gsem);
 	if(!(pegasus = kmalloc(sizeof(struct pegasus), GFP_KERNEL))) {
 		err("out of memory allocating device structure");
-		return NULL;
+		goto exit;
 	}
 
 	usb_inc_dev_use( dev );
@@ -856,12 +982,48 @@
 	pegasus->dev_index = dev_index;
 	init_waitqueue_head( &pegasus->ctrl_wait );
 
+	pegasus->ctrl_urb = usb_alloc_urb(0);
+	if (!pegasus->ctrl_urb) {
+		kfree (pegasus);
+		pegasus = NULL;
+		goto exit;
+	}
+	pegasus->rx_urb = usb_alloc_urb(0);
+	if (!pegasus->rx_urb) {
+		usb_free_urb (pegasus->ctrl_urb);
+		kfree (pegasus);
+		pegasus = NULL;
+		goto exit;
+	}
+	pegasus->tx_urb = usb_alloc_urb(0);
+	if (!pegasus->tx_urb) {
+		usb_free_urb (pegasus->rx_urb);
+		usb_free_urb (pegasus->ctrl_urb);
+		kfree (pegasus);
+		pegasus = NULL;
+		goto exit;
+	}
+	pegasus->intr_urb = usb_alloc_urb(0);
+	if (!pegasus->intr_urb) {
+		usb_free_urb (pegasus->tx_urb);
+		usb_free_urb (pegasus->rx_urb);
+		usb_free_urb (pegasus->ctrl_urb);
+		kfree (pegasus);
+		pegasus = NULL;
+		goto exit;
+	}
+
 	net = init_etherdev( NULL, 0 );
 	if ( !net ) {
+		usb_free_urb (pegasus->tx_urb);
+		usb_free_urb (pegasus->rx_urb);
+		usb_free_urb (pegasus->ctrl_urb);
 		kfree( pegasus );
-		return	NULL;
+		return NULL;
 	}
-	
+
+	init_MUTEX(&pegasus->sem);
+	down(&pegasus->sem);
 	pegasus->usb = dev;
 	pegasus->net = net;
 	SET_MODULE_OWNER(net);
@@ -883,10 +1045,13 @@
 	if ( reset_mac(pegasus) ) {
 		err("can't reset MAC");
 		unregister_netdev( pegasus->net );
+		usb_free_urb (pegasus->tx_urb);
+		usb_free_urb (pegasus->rx_urb);
+		usb_free_urb (pegasus->ctrl_urb);
 		kfree(pegasus->net);
 		kfree(pegasus);
 		pegasus = NULL;
-		return NULL;
+		goto exit;
 	}
 
 	info( "%s: %s", net->name, usb_dev_id[dev_index].name );
@@ -904,6 +1069,8 @@
 		pegasus->phy = 1;
 	}
 
+exit:
+	up(&pegasus->sem);
 	return pegasus;
 }
 
@@ -920,6 +1087,14 @@
 	pegasus->flags |= PEGASUS_UNPLUG;
 	unregister_netdev( pegasus->net );
 	usb_dec_dev_use( dev );
+	usb_unlink_urb(pegasus->intr_urb);
+	usb_unlink_urb(pegasus->tx_urb);
+	usb_unlink_urb(pegasus->rx_urb);
+	usb_unlink_urb(pegasus->ctrl_urb);
+	usb_free_urb(pegasus->intr_urb);
+	usb_free_urb(pegasus->tx_urb);
+	usb_free_urb(pegasus->rx_urb);
+	usb_free_urb(pegasus->ctrl_urb);
 	kfree( pegasus->net );
 	kfree( pegasus );
 	pegasus = NULL;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h
--- linux.orig/drivers/usb/pegasus.h	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/usb/pegasus.h	2002-07-20 01:08:35.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 1999,2000 Petko Manolov - Petkan (pmanolov@lnxw.com)
+ * Copyright (c) 1999-2002 Petko Manolov - Petkan (petkan@users.sourceforge.net)
  *
  * 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
@@ -31,14 +31,6 @@
 #define	EPROM_WR_ENABLE		0x10
 #define	EPROM_LOAD		0x20
 
-#define	MII_BMCR		0x00
-#define	MII_BMSR		0x01
-#define	BMSR_MEDIA		0x7808
-#define	MII_ANLPA		0x05
-#define	ANLPA_100TX_FD		0x0100
-#define	ANLPA_100TX_HD		0x0080
-#define	ANLPA_10T_FD		0x0040
-#define	ANLPA_10T_HD		0x0020
 #define	PHY_DONE		0x80
 #define	PHY_READ		0x40
 #define	PHY_WRITE		0x20
@@ -74,7 +66,6 @@
 #define	PEGASUS_REQ_GET_REGS	0xf0
 #define	PEGASUS_REQ_SET_REGS	0xf1
 #define	PEGASUS_REQ_SET_REG	PEGASUS_REQ_SET_REGS
-#define	ALIGN(x)		x __attribute__((aligned(L1_CACHE_BYTES)))
 
 enum pegasus_registers {
 	EthCtrl0 = 0,
@@ -107,13 +98,13 @@
 	unsigned		features;
 	int			dev_index;
 	int			intr_interval;
-	struct urb		ctrl_urb, rx_urb, tx_urb, intr_urb;
+	struct urb		*ctrl_urb, *rx_urb, *tx_urb, *intr_urb;
 	devrequest		dr;
 	wait_queue_head_t	ctrl_wait;
-	struct semaphore	ctrl_sem;
-	unsigned char		ALIGN(rx_buff[PEGASUS_MAX_MTU]);
-	unsigned char		ALIGN(tx_buff[PEGASUS_MAX_MTU]);
-	unsigned char		ALIGN(intr_buff[8]);
+	struct semaphore	sem;
+	unsigned char		rx_buff[PEGASUS_MAX_MTU];
+	unsigned char		tx_buff[PEGASUS_MAX_MTU];
+	unsigned char		intr_buff[8];
 	__u8			eth_regs[4];
 	__u8			phy;
 	__u8			gpio_res;
@@ -134,9 +125,12 @@
 #define	VENDOR_ALLIEDTEL	0x07c9
 #define	VENDOR_BELKIN		0x050d
 #define	VENDOR_BILLIONTON	0x08dd
+#define	VENDOR_COMPAQ		0x049f
 #define	VENDOR_COREGA		0x07aa
 #define	VENDOR_DLINK		0x2001
+#define VENDOR_ELCON		0x0db7
 #define	VENDOR_ELSA		0x05cc
+#define	VENDOR_HAWKING		0x0e66
 #define	VENDOR_IODATA		0x04bb
 #define	VENDOR_KINGSTON		0x0951
 #define	VENDOR_LANEED		0x056e
@@ -145,7 +139,7 @@
 #define	VENDOR_SMARTBRIDGES	0x08d1
 #define	VENDOR_SMC		0x0707
 #define	VENDOR_SOHOWARE		0x15e8
-
+#define	VENDOR_SIEMENS		0x067c
 
 #else	/* PEGASUS_DEV */
 
@@ -173,12 +167,16 @@
 		DEFAULT_GPIO_RESET | PEGASUS_II ) 	
 PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
+		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
 		VENDOR_ADMTEK, 0x8511,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)",
 		VENDOR_ADMTEK, 0x0986,
 		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
+PEGASUS_DEV( "ADMtek AN986A USB MAC", VENDOR_ADMTEK, 0x1986,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121,
@@ -187,6 +185,8 @@
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
 		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
+PEGASUS_DEV( "iPAQ Networking 10/100 USB", VENDOR_COMPAQ, 0x8511,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
@@ -207,10 +207,16 @@
 		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
 PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "ELCON EPLC10Mi USB to Powerline Adapter", VENDOR_ELCON, 0x0002,
+		DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
 PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
 		DEFAULT_GPIO_RESET)
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
@@ -243,8 +249,13 @@
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
 		DEFAULT_GPIO_RESET )
-
+PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
+		DEFAULT_GPIO_RESET )
 
 #endif	/* PEGASUS_DEV */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/printer.c linux/drivers/usb/printer.c
--- linux.orig/drivers/usb/printer.c	2001-10-09 22:15:02.000000000 +0000
+++ linux/drivers/usb/printer.c	2002-07-20 01:08:27.000000000 +0000
@@ -1,10 +1,12 @@
 /*
- * printer.c  Version 0.8
+ * printer.c  Version 0.11
  *
  * Copyright (c) 1999 Michael Gee	<michael@linuxspecific.com>
  * Copyright (c) 1999 Pavel Machek	<pavel@suse.cz>
  * Copyright (c) 2000 Randy Dunlap	<randy.dunlap@intel.com>
  * Copyright (c) 2000 Vojtech Pavlik	<vojtech@suse.cz>
+ # Copyright (c) 2001 Pete Zaitcev	<zaitcev@redhat.com>
+ # Copyright (c) 2001 David Paschal	<paschal@rcsis.com>
  *
  * USB Printer Device Class driver for USB printers and printer cables
  *
@@ -17,9 +19,11 @@
  *	v0.4 - fixes in unidirectional mode
  *	v0.5 - add DEVICE_ID string support
  *	v0.6 - never time out
- *	v0.7 - fixed bulk-IN read and poll (David Paschal, paschal@rcsis.com)
+ *	v0.7 - fixed bulk-IN read and poll (David Paschal)
  *	v0.8 - add devfs support
  *	v0.9 - fix unplug-while-open paths
+ *	v0.10 - add proto_bias option (Pete Zaitcev)
+ *	v0.11 - add hpoj.sourceforge.net ioctls (David Paschal)
  */
 
 /*
@@ -54,16 +58,36 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.8"
-#define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap"
+#define DRIVER_VERSION "v0.11"
+#define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete Zaitcev, David Paschal"
 #define DRIVER_DESC "USB Printer Device Class driver"
 
 #define USBLP_BUF_SIZE		8192
 #define DEVICE_ID_SIZE		1024
 
-#define IOCNR_GET_DEVICE_ID	1
-#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)	/* get device_id string */
+/* ioctls: */
 #define LPGETSTATUS		0x060b		/* same as in drivers/char/lp.c */
+#define IOCNR_GET_DEVICE_ID		1
+#define IOCNR_GET_PROTOCOLS		2
+#define IOCNR_SET_PROTOCOL		3
+#define IOCNR_HP_SET_CHANNEL		4
+#define IOCNR_GET_BUS_ADDRESS		5
+#define IOCNR_GET_VID_PID		6
+/* Get device_id string: */
+#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
+/* The following ioctls were added for http://hpoj.sourceforge.net: */
+/* Get two-int array:
+ * [0]=current protocol (1=7/1/1, 2=7/1/2, 3=7/1/3),
+ * [1]=supported protocol mask (mask&(1<<n)!=0 means 7/1/n supported): */
+#define LPIOC_GET_PROTOCOLS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_PROTOCOLS, len)
+/* Set protocol (arg: 1=7/1/1, 2=7/1/2, 3=7/1/3): */
+#define LPIOC_SET_PROTOCOL _IOC(_IOC_WRITE, 'P', IOCNR_SET_PROTOCOL, 0)
+/* Set channel number (HP Vendor-specific command): */
+#define LPIOC_HP_SET_CHANNEL _IOC(_IOC_WRITE, 'P', IOCNR_HP_SET_CHANNEL, 0)
+/* Get two-int array: [0]=bus number, [1]=device address: */
+#define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len)
+/* Get two-int array: [0]=vendor ID, [1]=product ID: */
+#define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len)
 
 /*
  * A DEVICE_ID string may include the printer's serial number.
@@ -77,23 +101,37 @@
  * USB Printer Requests
  */
 
-#define USBLP_REQ_GET_ID	0x00
-#define USBLP_REQ_GET_STATUS	0x01
-#define USBLP_REQ_RESET		0x02
+#define USBLP_REQ_GET_ID			0x00
+#define USBLP_REQ_GET_STATUS			0x01
+#define USBLP_REQ_RESET				0x02
+#define USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST	0x00	/* HP Vendor-specific */
 
 #define USBLP_MINORS		16
 #define USBLP_MINOR_BASE	0
 
 #define USBLP_WRITE_TIMEOUT	(5*HZ)			/* 5 seconds */
 
+#define USBLP_FIRST_PROTOCOL	1
+#define USBLP_LAST_PROTOCOL	3
+#define USBLP_MAX_PROTOCOLS	(USBLP_LAST_PROTOCOL+1)
+
 struct usblp {
 	struct usb_device 	*dev;			/* USB device */
 	devfs_handle_t		devfs;			/* devfs device */
 	struct semaphore	sem;			/* locks this struct, especially "dev" */
+	char			*buf;		/* writeurb.transfer_buffer */
 	struct urb		readurb, writeurb;	/* The urbs */
 	wait_queue_head_t	wait;			/* Zzzzz ... */
 	int			readcount;		/* Counter for reads */
 	int			ifnum;			/* Interface number */
+	/* Alternate-setting numbers and endpoints for each protocol
+	 * (7/1/{index=1,2,3}) that the device supports: */
+	struct {
+		int				alt_setting;
+		struct usb_endpoint_descriptor	*epwrite;
+		struct usb_endpoint_descriptor	*epread;
+	}			protocol[USBLP_MAX_PROTOCOLS];
+	int			current_protocol;
 	int			minor;			/* minor number of device */
 	unsigned int		quirks;			/* quirks flags */
 	unsigned char		used;			/* True if open */
@@ -102,6 +140,33 @@
 							/* first 2 bytes are (big-endian) length */
 };
 
+#ifdef DEBUG
+static void usblp_dump(struct usblp *usblp) {
+	int p;
+
+	dbg("usblp=0x%p", usblp);
+	dbg("dev=0x%p", usblp->dev);
+	dbg("devfs=0x%p", usblp->devfs);
+	dbg("buf=0x%p", usblp->buf);
+	dbg("readcount=%d", usblp->readcount);
+	dbg("ifnum=%d", usblp->ifnum);
+    for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) {
+	dbg("protocol[%d].alt_setting=%d", p, usblp->protocol[p].alt_setting);
+	dbg("protocol[%d].epwrite=%p", p, usblp->protocol[p].epwrite);
+	dbg("protocol[%d].epread=%p", p, usblp->protocol[p].epread);
+    }
+	dbg("current_protocol=%d", usblp->current_protocol);
+	dbg("minor=%d", usblp->minor);
+	dbg("quirks=%d", usblp->quirks);
+	dbg("used=%d", usblp->used);
+	dbg("bidir=%d", usblp->bidir);
+	dbg("device_id_string=\"%s\"",
+		usblp->device_id_string ?
+			usblp->device_id_string + 2 :
+			(unsigned char *)"(null)");
+}
+#endif
+
 extern devfs_handle_t usb_devfs_handle;			/* /dev/usb dir. */
 
 static struct usblp *usblp_table[USBLP_MINORS];
@@ -123,29 +188,52 @@
 	{ 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */
 	{ 0x03f0, 0x0304, USBLP_QUIRK_BIDIR }, /* HP DeskJet 810C/812C */
 	{ 0x03f0, 0x0404, USBLP_QUIRK_BIDIR }, /* HP DeskJet 830C */
+	{ 0x03f0, 0x0504, USBLP_QUIRK_BIDIR }, /* HP DeskJet 885C */
+	{ 0x03f0, 0x0604, USBLP_QUIRK_BIDIR }, /* HP DeskJet 840C */   
+	{ 0x03f0, 0x0804, USBLP_QUIRK_BIDIR }, /* HP DeskJet 816C */   
+	{ 0x03f0, 0x1104, USBLP_QUIRK_BIDIR }, /* HP Deskjet 959C */
+	{ 0x0409, 0xefbe, USBLP_QUIRK_BIDIR }, /* NEC Picty900 (HP OEM) */
+	{ 0x0409, 0xbef4, USBLP_QUIRK_BIDIR }, /* NEC Picty760 (HP OEM) */
+	{ 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
+	{ 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
 	{ 0, 0 }
 };
 
+static int usblp_select_alts(struct usblp *usblp);
+static int usblp_set_protocol(struct usblp *usblp, int protocol);
+static int usblp_cache_device_id_string(struct usblp *usblp);
+
+
 /*
  * Functions for usblp control messages.
  */
 
-static int usblp_ctrl_msg(struct usblp *usblp, int request, int dir, int recip, int value, void *buf, int len)
+static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, int recip, int value, void *buf, int len)
 {
 	int retval = usb_control_msg(usblp->dev,
 		dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0),
-		request, USB_TYPE_CLASS | dir | recip, value, usblp->ifnum, buf, len, HZ * 5);
+		request, type | dir | recip, value, usblp->ifnum, buf, len, USBLP_WRITE_TIMEOUT);
 	dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d len: %#x result: %d",
 		request, !!dir, recip, value, len, retval);
 	return retval < 0 ? retval : 0;
 }
 
 #define usblp_read_status(usblp, status)\
-	usblp_ctrl_msg(usblp, USBLP_REQ_GET_STATUS, USB_DIR_IN, USB_RECIP_INTERFACE, 0, status, 1)
+	usblp_ctrl_msg(usblp, USBLP_REQ_GET_STATUS, USB_TYPE_CLASS, USB_DIR_IN, USB_RECIP_INTERFACE, 0, status, 1)
 #define usblp_get_id(usblp, config, id, maxlen)\
-	usblp_ctrl_msg(usblp, USBLP_REQ_GET_ID, USB_DIR_IN, USB_RECIP_INTERFACE, config, id, maxlen)
+	usblp_ctrl_msg(usblp, USBLP_REQ_GET_ID, USB_TYPE_CLASS, USB_DIR_IN, USB_RECIP_INTERFACE, config, id, maxlen)
 #define usblp_reset(usblp)\
-	usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)
+	usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)
+
+#define usblp_hp_channel_change_request(usblp, channel, buffer) \
+	usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1)
+
+/*
+ * See the description for usblp_select_alts() below for the usage
+ * explanation.  Look into your /proc/bus/usb/devices and dmesg in
+ * case of any trouble.
+ */
+static int proto_bias = -1;
 
 /*
  * URB callback.
@@ -257,13 +345,20 @@
 {
 	devfs_unregister (usblp->devfs);
 	usblp_table [usblp->minor] = NULL;
-	info ("usblp%d: removed", usblp->minor);
+	info("usblp%d: removed", usblp->minor);
 
 	kfree (usblp->writeurb.transfer_buffer);
 	kfree (usblp->device_id_string);
 	kfree (usblp);
 }
 
+static void usblp_unlink_urbs(struct usblp *usblp)
+{
+	usb_unlink_urb(&usblp->writeurb);
+	if (usblp->bidir)
+		usb_unlink_urb(&usblp->readurb);
+}
+
 static int usblp_release(struct inode *inode, struct file *file)
 {
 	struct usblp *usblp = file->private_data;
@@ -272,9 +367,7 @@
 	lock_kernel();
 	usblp->used = 0;
 	if (usblp->dev) {
-		if (usblp->bidir)
-			usb_unlink_urb(&usblp->readurb);
-		usb_unlink_urb(&usblp->writeurb);
+		usblp_unlink_urbs(usblp);
 		up(&usblp->sem);
 	} else 		/* finish cleanup from disconnect */
 		usblp_cleanup (usblp);
@@ -294,8 +387,9 @@
 static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct usblp *usblp = file->private_data;
-	int length, err;
-	unsigned char status;
+	int length, err, i;
+	unsigned char status, newChannel;
+	int twoints[2];
 	int retval = 0;
 
 	down (&usblp->sem);
@@ -314,32 +408,128 @@
 					goto done;
 				}
 
-				err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
+				length = usblp_cache_device_id_string(usblp);
+				if (length < 0) {
+					retval = length;
+					goto done;
+				}
+				if (length > _IOC_SIZE(cmd))
+					length = _IOC_SIZE(cmd); /* truncate */
+
+				if (copy_to_user((unsigned char *) arg,
+						usblp->device_id_string,
+						(unsigned long) length)) {
+					retval = -EFAULT;
+					goto done;
+				}
+
+				break;
+
+			case IOCNR_GET_PROTOCOLS:
+				if (_IOC_DIR(cmd) != _IOC_READ ||
+				    _IOC_SIZE(cmd) < sizeof(twoints)) {
+					retval = -EINVAL;
+					goto done;
+				}
+
+				twoints[0] = usblp->current_protocol;
+				twoints[1] = 0;
+				for (i = USBLP_FIRST_PROTOCOL;
+				     i <= USBLP_LAST_PROTOCOL; i++) {
+					if (usblp->protocol[i].alt_setting >= 0)
+						twoints[1] |= (1<<i);
+				}
+
+				if (copy_to_user((unsigned char *)arg,
+						(unsigned char *)twoints,
+						sizeof(twoints))) {
+					retval = -EFAULT;
+					goto done;
+				}
+
+				break;
+
+			case IOCNR_SET_PROTOCOL:
+				if (_IOC_DIR(cmd) != _IOC_WRITE) {
+					retval = -EINVAL;
+					goto done;
+				}
+
+#ifdef DEBUG
+				if (arg == -10) {
+					usblp_dump(usblp);
+					break;
+				}
+#endif
+
+				usblp_unlink_urbs(usblp);
+				retval = usblp_set_protocol(usblp, arg);
+				if (retval < 0) {
+					usblp_set_protocol(usblp,
+						usblp->current_protocol);
+				}
+				break;
+
+			case IOCNR_HP_SET_CHANNEL:
+				if (_IOC_DIR(cmd) != _IOC_WRITE ||
+				    usblp->dev->descriptor.idVendor != 0x03F0 ||
+				    usblp->quirks & USBLP_QUIRK_BIDIR) {
+					retval = -EINVAL;
+					goto done;
+				}
+
+				err = usblp_hp_channel_change_request(usblp,
+					arg, &newChannel);
 				if (err < 0) {
-					dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string",
+					err("usblp%d: error = %d setting "
+						"HP channel",
 						usblp->minor, err);
-					usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
 					retval = -EIO;
 					goto done;
 				}
 
-				length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
-				if (length < DEVICE_ID_SIZE)
-					usblp->device_id_string[length] = '\0';
-				else
-					usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0';
+				dbg("usblp%d requested/got HP channel %ld/%d",
+					usblp->minor, arg, newChannel);
+				break;
 
-				dbg ("usblp%d Device ID string [%d/max %d]='%s'",
-					usblp->minor, length, _IOC_SIZE(cmd), &usblp->device_id_string[2]);
+			case IOCNR_GET_BUS_ADDRESS:
+				if (_IOC_DIR(cmd) != _IOC_READ ||
+				    _IOC_SIZE(cmd) < sizeof(twoints)) {
+					retval = -EINVAL;
+					goto done;
+				}
 
-				if (length > _IOC_SIZE(cmd)) length = _IOC_SIZE(cmd); /* truncate */
+				twoints[0] = usblp->dev->bus->busnum;
+				twoints[1] = usblp->dev->devnum;
+				if (copy_to_user((unsigned char *)arg,
+						(unsigned char *)twoints,
+						sizeof(twoints))) {
+					retval = -EFAULT;
+					goto done;
+				}
 
-				if (copy_to_user((unsigned char *) arg,
-						usblp->device_id_string, (unsigned long) length)) {
+				dbg("usblp%d is bus=%d, device=%d",
+					usblp->minor, twoints[0], twoints[1]);
+				break;
+
+			case IOCNR_GET_VID_PID:
+				if (_IOC_DIR(cmd) != _IOC_READ ||
+				    _IOC_SIZE(cmd) < sizeof(twoints)) {
+					retval = -EINVAL;
+					goto done;
+				}
+
+				twoints[0] = usblp->dev->descriptor.idVendor;
+				twoints[1] = usblp->dev->descriptor.idProduct;
+				if (copy_to_user((unsigned char *)arg,
+						(unsigned char *)twoints,
+						sizeof(twoints))) {
 					retval = -EFAULT;
 					goto done;
 				}
 
+				dbg("usblp%d is VID=0x%4.4X, PID=0x%4.4X",
+					usblp->minor, twoints[0], twoints[1]);
 				break;
 
 			default:
@@ -545,137 +735,256 @@
 static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
 			 const struct usb_device_id *id)
 {
-	struct usb_interface_descriptor *interface;
-	struct usb_endpoint_descriptor *epread, *epwrite;
-	struct usblp *usblp;
-	int minor, i, bidir = 0, quirks;
-	int alts = dev->actconfig->interface[ifnum].act_altsetting;
-	int length, err;
-	char *buf;
+	struct usblp *usblp = 0;
+	int protocol;
 	char name[6];
 
-	/* If a bidirectional interface exists, use it. */
-	for (i = 0; i < dev->actconfig->interface[ifnum].num_altsetting; i++) {
-
-		interface = &dev->actconfig->interface[ifnum].altsetting[i];
-
-		if (interface->bInterfaceClass != 7 || interface->bInterfaceSubClass != 1 ||
-		    interface->bInterfaceProtocol < 1 || interface->bInterfaceProtocol > 3 ||
-		   (interface->bInterfaceProtocol > 1 && interface->bNumEndpoints < 2))
-			continue;
-
-		if (interface->bInterfaceProtocol > 1) {
-			bidir = 1;
-			alts = i;
-			break;
-		}
-	}
-
-	interface = &dev->actconfig->interface[ifnum].altsetting[alts];
-	if (usb_set_interface(dev, ifnum, alts))
-		err("can't set desired altsetting %d on interface %d", alts, ifnum);
-
-	epwrite = interface->endpoint + 0;
-	epread = bidir ? interface->endpoint + 1 : NULL;
-
-	if ((epwrite->bEndpointAddress & 0x80) == 0x80) {
-		if (interface->bNumEndpoints == 1)
-			return NULL;
-		epwrite = interface->endpoint + 1;
-		epread = bidir ? interface->endpoint + 0 : NULL;
-	}
-
-	if ((epwrite->bEndpointAddress & 0x80) == 0x80)
-		return NULL;
-
-	if (bidir && (epread->bEndpointAddress & 0x80) != 0x80)
-		return NULL;
-
-	for (minor = 0; minor < USBLP_MINORS && usblp_table[minor]; minor++);
-	if (usblp_table[minor]) {
-		err("no more free usblp devices");
-		return NULL;
-	}
-
+	/* Malloc and start initializing usblp structure so we can use it
+	 * directly. */
 	if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) {
-		err("out of memory");
-		return NULL;
+		err("out of memory for usblp");
+		goto abort;
 	}
 	memset(usblp, 0, sizeof(struct usblp));
-	init_MUTEX (&usblp->sem);
-
-	/* lookup quirks for this printer */
-	quirks = usblp_quirks(dev->descriptor.idVendor, dev->descriptor.idProduct);
-
-	if (bidir && (quirks & USBLP_QUIRK_BIDIR)) {
-		bidir = 0;
-		epread = NULL;
-		info ("Disabling reads from problem bidirectional printer on usblp%d",
-			minor);
-	}
-
 	usblp->dev = dev;
-	usblp->ifnum = ifnum;
-	usblp->minor = minor;
-	usblp->bidir = bidir;
-	usblp->quirks = quirks;
-
+	init_MUTEX (&usblp->sem);
 	init_waitqueue_head(&usblp->wait);
+	usblp->ifnum = ifnum;
 
-	if (!(buf = kmalloc(USBLP_BUF_SIZE * (bidir ? 2 : 1), GFP_KERNEL))) {
-		err("out of memory");
-		kfree(usblp);
-		return NULL;
+	/* Look for a free usblp_table entry. */
+	while (usblp_table[usblp->minor]) {
+		usblp->minor++;
+		if (usblp->minor >= USBLP_MINORS) {
+			err("no more free usblp devices");
+			goto abort;
+		}
 	}
 
+	/* Malloc device ID string buffer to the largest expected length,
+	 * since we can re-query it on an ioctl and a dynamic string
+	 * could change in length. */
 	if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) {
-		err("out of memory");
-		kfree(usblp);
-		kfree(buf);
-		return NULL;
+		err("out of memory for device_id_string");
+		goto abort;
 	}
 
-	FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
-		buf, 0, usblp_bulk, usblp);
+	/* Malloc write/read buffers in one chunk.  We somewhat wastefully
+	 * malloc both regardless of bidirectionality, because the
+	 * alternate setting can be changed later via an ioctl. */
+	if (!(usblp->buf = kmalloc(2 * USBLP_BUF_SIZE, GFP_KERNEL))) {
+		err("out of memory for buf");
+		goto abort;
+	}
+
+	/* Lookup quirks for this printer. */
+	usblp->quirks = usblp_quirks(
+		dev->descriptor.idVendor,
+		dev->descriptor.idProduct);
+
+	/* Analyze and pick initial alternate settings and endpoints. */
+	protocol = usblp_select_alts(usblp);
+	if (protocol < 0) {
+		dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
+			dev->descriptor.idVendor,
+			dev->descriptor.idProduct);
+		goto abort;
+	}
+
+	/* Setup the selected alternate setting and endpoints. */
+	if (usblp_set_protocol(usblp, protocol) < 0)
+		goto abort;
 
-	if (bidir)
-		FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
-			buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, usblp_bulk, usblp);
-
-	/* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */
-	err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
-	if (err >= 0) {
-		length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
-		if (length < DEVICE_ID_SIZE)
-			usblp->device_id_string[length] = '\0';
-		else
-			usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0';
-		dbg ("usblp%d Device ID string [%d]=%s",
-			minor, length, &usblp->device_id_string[2]);
-	}
-	else {
-		err ("usblp%d: error = %d reading IEEE-1284 Device ID string",
-			minor, err);
-		usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
-	}
+	/* Retrieve and store the device ID string. */
+	usblp_cache_device_id_string(usblp);
 
 #ifdef DEBUG
 	usblp_check_status(usblp, 0);
 #endif
 
-	sprintf(name, "lp%d", minor);
-
-	/* if we have devfs, create with perms=660 */
+	usblp_table[usblp->minor] = usblp;
+	/* If we have devfs, create with perms=660. */
+	sprintf(name, "lp%d", usblp->minor);
 	usblp->devfs = devfs_register(usb_devfs_handle, name,
 				      DEVFS_FL_DEFAULT, USB_MAJOR,
-				      USBLP_MINOR_BASE + minor,
+				      USBLP_MINOR_BASE + usblp->minor,
 				      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
 				      S_IWGRP, &usblp_fops, NULL);
 
-	info("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
-		minor, bidir ? "Bi" : "Uni", dev->devnum, ifnum, alts);
+	info("usblp%d: USB %sdirectional printer dev %d "
+		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
+		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, ifnum,
+		usblp->protocol[usblp->current_protocol].alt_setting,
+		usblp->current_protocol, usblp->dev->descriptor.idVendor,
+		usblp->dev->descriptor.idProduct);
+
+	return usblp;
+
+abort:
+	if (usblp) {
+		if (usblp->buf) kfree(usblp->buf);
+		if (usblp->device_id_string) kfree(usblp->device_id_string);
+		kfree(usblp);
+	}
+	return NULL;
+}
 
-	return usblp_table[minor] = usblp;
+/*
+ * We are a "new" style driver with usb_device_id table,
+ * but our requirements are too intricate for simple match to handle.
+ *
+ * The "proto_bias" option may be used to specify the preferred protocol
+ * for all USB printers (1=7/1/1, 2=7/1/2, 3=7/1/3).  If the device
+ * supports the preferred protocol, then we bind to it.
+ *
+ * The best interface for us is 7/1/2, because it is compatible
+ * with a stream of characters. If we find it, we bind to it.
+ *
+ * Note that the people from hpoj.sourceforge.net need to be able to
+ * bind to 7/1/3 (MLC/1284.4), so we provide them ioctls for this purpose.
+ *
+ * Failing 7/1/2, we look for 7/1/3, even though it's probably not
+ * stream-compatible, because this matches the behaviour of the old code.
+ *
+ * If nothing else, we bind to 7/1/1 - the unidirectional interface.
+ */
+static int usblp_select_alts(struct usblp *usblp)
+{
+	struct usb_interface *if_alt;
+	struct usb_interface_descriptor *ifd;
+	struct usb_endpoint_descriptor *epd, *epwrite, *epread;
+	int p, i, e;
+
+	if_alt = &usblp->dev->actconfig->interface[usblp->ifnum];
+
+	for (p = 0; p < USBLP_MAX_PROTOCOLS; p++)
+		usblp->protocol[p].alt_setting = -1;
+
+	/* Find out what we have. */
+	for (i = 0; i < if_alt->num_altsetting; i++) {
+		ifd = &if_alt->altsetting[i];
+
+		if (ifd->bInterfaceClass != 7 || ifd->bInterfaceSubClass != 1)
+			continue;
+
+		if (ifd->bInterfaceProtocol < USBLP_FIRST_PROTOCOL ||
+		    ifd->bInterfaceProtocol > USBLP_LAST_PROTOCOL)
+			continue;
+
+		/* Look for bulk OUT and IN endpoints. */
+		epwrite = epread = 0;
+		for (e = 0; e < ifd->bNumEndpoints; e++) {
+			epd = &ifd->endpoint[e];
+
+			if ((epd->bmAttributes&USB_ENDPOINT_XFERTYPE_MASK)!=
+			    USB_ENDPOINT_XFER_BULK)
+				continue;
+
+			if (!(epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK)) {
+				if (!epwrite) epwrite=epd;
+
+			} else {
+				if (!epread) epread=epd;
+			}
+		}
+
+		/* Ignore buggy hardware without the right endpoints. */
+		if (!epwrite || (ifd->bInterfaceProtocol > 1 && !epread))
+			continue;
+
+		/* Turn off reads for 7/1/1 (unidirectional) interfaces
+		 * and buggy bidirectional printers. */
+		if (ifd->bInterfaceProtocol == 1) {
+			epread = NULL;
+		} else if (usblp->quirks & USBLP_QUIRK_BIDIR) {
+			info("Disabling reads from problem bidirectional "
+				"printer on usblp%d", usblp->minor);
+			epread = NULL;
+		}
+
+		usblp->protocol[ifd->bInterfaceProtocol].alt_setting = i;
+		usblp->protocol[ifd->bInterfaceProtocol].epwrite = epwrite;
+		usblp->protocol[ifd->bInterfaceProtocol].epread = epread;
+	}
+
+	/* If our requested protocol is supported, then use it. */
+	if (proto_bias >= USBLP_FIRST_PROTOCOL &&
+	    proto_bias <= USBLP_LAST_PROTOCOL &&
+	    usblp->protocol[proto_bias].alt_setting != -1)
+		return proto_bias;
+
+	/* Ordering is important here. */
+	if (usblp->protocol[2].alt_setting != -1) return 2;
+	if (usblp->protocol[1].alt_setting != -1) return 1;
+	if (usblp->protocol[3].alt_setting != -1) return 3;
+
+	/* If nothing is available, then don't bind to this device. */
+	return -1;
+}
+
+static int usblp_set_protocol(struct usblp *usblp, int protocol)
+{
+	int r, alts;
+
+	if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
+		return -EINVAL;
+
+	alts = usblp->protocol[protocol].alt_setting;
+	if (alts < 0) return -EINVAL;
+	r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
+	if (r < 0) {
+		err("can't set desired altsetting %d on interface %d",
+			alts, usblp->ifnum);
+		return r;
+	}
+
+	FILL_BULK_URB(&usblp->writeurb, usblp->dev,
+		usb_sndbulkpipe(usblp->dev,
+		 usblp->protocol[protocol].epwrite->bEndpointAddress),
+		usblp->buf, 0,
+		usblp_bulk, usblp);
+
+	usblp->bidir = (usblp->protocol[protocol].epread != 0);
+	if (usblp->bidir)
+		FILL_BULK_URB(&usblp->readurb, usblp->dev,
+			usb_rcvbulkpipe(usblp->dev,
+			 usblp->protocol[protocol].epread->bEndpointAddress),
+			usblp->buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE,
+			usblp_bulk, usblp);
+
+	usblp->current_protocol = protocol;
+	dbg("usblp%d set protocol %d", usblp->minor, protocol);
+	return 0;
+}
+
+/* Retrieves and caches device ID string.
+ * Returns length, including length bytes but not null terminator.
+ * On error, returns a negative errno value. */
+static int usblp_cache_device_id_string(struct usblp *usblp)
+{
+	int err, length;
+
+	err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
+	if (err < 0) {
+		dbg("usblp%d: error = %d reading IEEE-1284 Device ID string",
+			usblp->minor, err);
+		usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
+		return -EIO;
+	}
+
+	/* First two bytes are length in big-endian.
+	 * They count themselves, and we copy them into
+	 * the user's buffer. */
+	length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1];
+	if (length < 2)
+		length = 2;
+	else if (length >= DEVICE_ID_SIZE)
+		length = DEVICE_ID_SIZE - 1;
+	usblp->device_id_string[length] = '\0';
+
+	dbg("usblp%d Device ID string [len=%d]=\"%s\"",
+		usblp->minor, length, &usblp->device_id_string[2]);
+
+	return length;
 }
 
 static void usblp_disconnect(struct usb_device *dev, void *ptr)
@@ -691,9 +1000,7 @@
 	lock_kernel();
 	usblp->dev = NULL;
 
-	usb_unlink_urb(&usblp->writeurb);
-	if (usblp->bidir)
-		usb_unlink_urb(&usblp->readurb);
+	usblp_unlink_urbs(usblp);
 
 	if (!usblp->used)
 		usblp_cleanup (usblp);
@@ -727,7 +1034,7 @@
 {
 	if (usb_register(&usblp_driver))
 		return -1;
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	info(DRIVER_VERSION ": " DRIVER_DESC);
 	return 0;
 }
 
@@ -741,5 +1048,6 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_PARM(proto_bias, "i");
+MODULE_PARM_DESC(proto_bias, "Favourite protocol number");
 MODULE_LICENSE("GPL");
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pwc-ctrl.c linux/drivers/usb/pwc-ctrl.c
--- linux.orig/drivers/usb/pwc-ctrl.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/pwc-ctrl.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,7 +1,7 @@
 /* Driver for Philips webcam
    Functions that send various control messages to the webcam, including
    video modes.
-   (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl)
+   (C) 1999-2002 Nemosoft Unv. (webcam@smcc.demon.nl)
 
    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
@@ -78,10 +78,12 @@
 #define READ_SHUTTER_FORMATTER			0x0600
 #define READ_RED_GAIN_FORMATTER			0x0700
 #define READ_BLUE_GAIN_FORMATTER		0x0800
+#define SENSOR_TYPE_FORMATTER1			0x0C00
 #define READ_RAW_Y_MEAN_FORMATTER		0x3100
 #define SET_POWER_SAVE_MODE_FORMATTER		0x3200
 #define MIRROR_IMAGE_FORMATTER			0x3300
 #define LED_FORMATTER				0x3400
+#define SENSOR_TYPE_FORMATTER2			0x3700
 
 /* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
 #define VIDEO_OUTPUT_CONTROL_FORMATTER		0x0100
@@ -162,6 +164,21 @@
 /****************************************************************************/
 
 
+#define SendControlMsg(request, value, buflen) \
+	usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
+		request, \
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
+		value, \
+		pdev->vcinterface, \
+		&buf, buflen, HZ / 2)
+
+#define RecvControlMsg(request, value, buflen) \
+	usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
+		request, \
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
+		value, \
+		pdev->vcinterface, \
+		&buf, buflen, HZ / 2)
 
 
 #if PWC_DEBUG
@@ -241,7 +258,7 @@
 	ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
 	if (ret < 0)
 		return ret;
-	if (pEntry->compressed)
+	if (pEntry->compressed && pdev->decompressor != NULL)
 		pdev->decompressor->init(pdev->release, buf, pdev->decompress_data);
 		
 	/* Set various parameters */
@@ -911,7 +928,7 @@
 	int ret;
 	
 	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
- 	        GET_STATUS_CTL, 
+ 	        GET_CHROM_CTL, 
 		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 	        PRESET_MANUAL_RED_GAIN_FORMATTER,
 		pdev->vcinterface,
@@ -950,7 +967,7 @@
 	int ret;
 	
 	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
-   	        GET_STATUS_CTL,
+   	        GET_CHROM_CTL,
 		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 		PRESET_MANUAL_BLUE_GAIN_FORMATTER,
 		pdev->vcinterface,
@@ -962,6 +979,7 @@
 	return (buf << 8);
 }
 
+
 /* The following two functions are different, since they only read the
    internal red/blue gains, which may be different from the manual 
    gains set or read above.
@@ -997,11 +1015,74 @@
 		&buf, 1, HZ / 2);
 
 	if (ret < 0)
-	    return ret;
+		return ret;
 	
 	return (buf << 8);
 }
 
+
+static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
+{
+	unsigned char buf;
+	
+	/* useful range is 0x01..0x20 */
+	buf = speed / 0x7f0;
+	return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_CHROM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AWB_CONTROL_SPEED_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+}
+
+static inline int pwc_get_wb_speed(struct pwc_device *pdev)
+{
+	unsigned char buf;
+	int ret;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_CHROM_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AWB_CONTROL_SPEED_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	return (buf * 0x7f0);
+}
+
+
+static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
+{
+	unsigned char buf;
+	
+	/* useful range is 0x01..0x3F */
+	buf = (delay >> 10);
+	return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_CHROM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AWB_CONTROL_DELAY_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+}
+
+static inline int pwc_get_wb_delay(struct pwc_device *pdev)
+{
+	unsigned char buf;
+	int ret;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_CHROM_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AWB_CONTROL_DELAY_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	return (buf << 10);
+}
+
+
 int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
 {
 	unsigned char buf[2];
@@ -1055,53 +1136,242 @@
 	return 0;
 }
 
+static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
+{
+	unsigned char buf;
+	int ret;
+	
+	if (contour < 0)
+		buf = 0xff; /* auto contour on */
+	else
+		buf = 0x0; /* auto contour off */
+	ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_LUM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AUTO_CONTOUR_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	
+	if (contour < 0)
+		return 0;
+	if (contour > 0xffff)
+		contour = 0xffff;
+	
+	buf = (contour >> 10); /* contour preset is [0..3f] */
+	ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_LUM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		PRESET_CONTOUR_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)	
+		return ret;	
+	return 0;
+}
+
+static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
+{
+	unsigned char buf;
+	int ret;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_LUM_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		AUTO_CONTOUR_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+
+	if (buf == 0) {
+		/* auto mode off, query current preset value */
+		ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+			GET_LUM_CTL,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			PRESET_CONTOUR_FORMATTER,
+			pdev->vcinterface,
+			&buf, 1, HZ / 2);
+		if (ret < 0)	
+			return ret;
+		*contour =  (buf << 10);
+	}
+	else
+		*contour = -1;
+	return 0;
+}
+
+
+static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
+{
+	unsigned char buf;
+	
+	if (backlight)
+		buf = 0xff;
+	else
+		buf = 0x0;
+	return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		SET_LUM_CTL,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		BACK_LIGHT_COMPENSATION_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+}
+
+static inline int pwc_get_backlight(struct pwc_device *pdev)
+{
+	int ret;
+	unsigned char buf;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_LUM_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		BACK_LIGHT_COMPENSATION_FORMATTER,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	return buf;
+}
+
+
+static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
+{
+	unsigned char buf;
+	
+	if (flicker)
+		buf = 0xff;
+	else
+		buf = 0x0;
+	return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+}
+
+static inline int pwc_get_flicker(struct pwc_device *pdev)
+{
+	int ret;
+	unsigned char buf;
+	
+	ret = RecvControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+	if (ret < 0)
+		return ret;
+	return buf;
+}
+
+
+static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
+{
+	unsigned char buf;
+
+	if (noise < 0)
+		noise = 0;
+	if (noise > 3)
+		noise = 3;
+	buf = noise;
+	return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+}
+
+static inline int pwc_get_dynamic_noise(struct pwc_device *pdev)
+{
+	int ret;
+	unsigned char buf;
+	
+	ret = RecvControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+	if (ret < 0)
+		return ret;
+Debug("pwc_get_dynamic_noise = %d\n", buf);
+	return buf;
+}
+
+
+int pwc_get_cmos_sensor(struct pwc_device *pdev)
+{
+	unsigned char buf;
+	int ret = -1, request;
+	
+	if (pdev->type < 675)
+		request = SENSOR_TYPE_FORMATTER1;
+	else if (pdev->type < 730)
+		return -1; /* The Vesta series doesn't have this call */
+	else
+		request = SENSOR_TYPE_FORMATTER2;
+	
+	ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		GET_STATUS_CTL,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		request,
+		pdev->vcinterface,
+		&buf, 1, HZ / 2);
+	if (ret < 0)
+		return ret;
+	if (pdev->type < 675)
+		return buf | 0x100;
+	else
+		return buf;
+}
+
+
  /* End of Add-Ons                                    */
  /* ************************************************* */
 
 int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
 {
+	int ret = 0;
+
 	switch(cmd) {
 	case VIDIOCPWCRUSER:
 	{
 		if (pwc_restore_user(pdev))
-			return -EINVAL;
+			ret = -EINVAL;
 		break;
 	}
 	
 	case VIDIOCPWCSUSER:
 	{
 		if (pwc_save_user(pdev))
-			return -EINVAL;
+			ret = -EINVAL;
 		break;
 	}
 		
 	case VIDIOCPWCFACTORY:
 	{
 		if (pwc_restore_factory(pdev))
-			return -EINVAL;
+			ret = -EINVAL;
 		break;
 	}
 	
 	case VIDIOCPWCSCQUAL:
 	{	
-		int qual, ret;
+		int qual;
 
 		if (copy_from_user(&qual, arg, sizeof(int)))
-			return -EFAULT;
-			
-		if (qual < 0 || qual > 3)
-			return -EINVAL;
-		ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, qual, pdev->vsnapshot);
-		if (ret < 0)
-			return ret;
-		pdev->vcompression = qual;
+			ret = -EFAULT;
+		else {
+			if (qual < 0 || qual > 3)
+				ret = -EINVAL;
+			else
+				ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, qual, pdev->vsnapshot);
+			if (ret >= 0)
+				pdev->vcompression = qual;
+		}
 		break;
 	}
 	
 	case VIDIOCPWCGCQUAL:
 	{
 		if (copy_to_user(arg, &pdev->vcompression, sizeof(int)))
-			return -EFAULT;
+			ret = -EFAULT;
+		break;
+	}
+
+	case VIDIOCPWCPROBE:
+	{
+		struct pwc_probe probe;
+		
+		strcpy(probe.name, pdev->vdev->name);
+		probe.type = pdev->type;
+		if (copy_to_user(arg, &probe, sizeof(probe)))
+			ret = -EFAULT;
 		break;
 	}
 
@@ -1110,10 +1380,10 @@
 		int agc;
 		
 		if (copy_from_user(&agc, arg, sizeof(agc)))
-			return -EFAULT;	
+			ret = -EFAULT;	
 		else {
 			if (pwc_set_agc(pdev, agc < 0 ? 1 : 0, agc))
-				return -EINVAL;
+				ret = -EINVAL;
 		}
 		break;
 	}
@@ -1123,42 +1393,36 @@
 		int agc;
 		
 		if (pwc_get_agc(pdev, &agc))
-			return -EINVAL;
-		if (copy_to_user(arg, &agc, sizeof(agc)))
-			return -EFAULT;
+			ret = -EINVAL;
+		else
+			if (copy_to_user(arg, &agc, sizeof(agc)))
+				ret = -EFAULT;
 		break;
 	}
 	
 	case VIDIOCPWCSSHUTTER:
 	{
-		int shutter_speed, ret;
+		int shutter_speed;
 
 		if (copy_from_user(&shutter_speed, arg, sizeof(shutter_speed)))
-			return -EFAULT;
-		else {
+			ret = -EFAULT;
+		else
 			ret = pwc_set_shutter_speed(pdev, shutter_speed < 0 ? 1 : 0, shutter_speed);
-			if (ret < 0)
-				return ret;
-		}
 		break;
 	}
 	
-
- /* ************************************************* */
- /* Begin of Add-Ons for color compensation           */
-
         case VIDIOCPWCSAWB:
 	{
 		struct pwc_whitebalance wb;
-		int ret;
 		
 		if (copy_from_user(&wb, arg, sizeof(wb)))
-			return -EFAULT;
-	
-		ret = pwc_set_awb(pdev, wb.mode);
-		if (ret >= 0 && wb.mode == PWC_WB_MANUAL) {
-			pwc_set_red_gain(pdev, wb.manual_red);
-			pwc_set_blue_gain(pdev, wb.manual_blue);
+			ret = -EFAULT;
+		else {
+			ret = pwc_set_awb(pdev, wb.mode);
+			if (ret >= 0 && wb.mode == PWC_WB_MANUAL) {
+				pwc_set_red_gain(pdev, wb.manual_red);
+				pwc_set_blue_gain(pdev, wb.manual_blue);
+			}
 		}
 		break;
 	}
@@ -1170,55 +1434,176 @@
 		memset(&wb, 0, sizeof(wb));
 		wb.mode = pwc_get_awb(pdev);
 		if (wb.mode < 0)
-			return -EINVAL;
-		wb.manual_red = pwc_get_red_gain(pdev);
-		wb.manual_blue = pwc_get_blue_gain(pdev);
-		if (wb.mode == PWC_WB_AUTO) {
-			wb.read_red = pwc_read_red_gain(pdev);
-			wb.read_blue = pwc_read_blue_gain(pdev);
+			ret = -EINVAL;
+		else {
+			if (wb.mode == PWC_WB_MANUAL) {
+				wb.manual_red = pwc_get_red_gain(pdev);
+				wb.manual_blue = pwc_get_blue_gain(pdev);
+			}
+			if (wb.mode == PWC_WB_AUTO) {
+				wb.read_red = pwc_read_red_gain(pdev);
+				wb.read_blue = pwc_read_blue_gain(pdev);
+			}
+			if (copy_to_user(arg, &wb, sizeof(wb)))
+				ret= -EFAULT;
 		}
-		if (copy_to_user(arg, &wb, sizeof(wb)))
-			return -EFAULT;
+		break;
+	}
+	
+	case VIDIOCPWCSAWBSPEED:
+	{
+		struct pwc_wb_speed wbs;
+		
+		if (copy_from_user(&wbs, arg, sizeof(wbs)))
+			ret = -EFAULT;
+		else {
+			if (wbs.control_speed > 0) {
+				ret = pwc_set_wb_speed(pdev, wbs.control_speed);
+			}
+			if (wbs.control_delay > 0) {
+				ret = pwc_set_wb_delay(pdev, wbs.control_delay);
+			}
+		}
+		break;
+	}
+	
+	case VIDIOCPWCGAWBSPEED:
+	{
+		struct pwc_wb_speed wbs;
+		
+		ret = pwc_get_wb_speed(pdev);
+		if (ret < 0)
+			break;
+		wbs.control_speed = ret;
+		ret = pwc_get_wb_delay(pdev);
+		if (ret < 0)
+			break;
+		wbs.control_delay = ret;
+		if (copy_to_user(arg, &wbs, sizeof(wbs)))
+			ret = -EFAULT;
 		break;
 	}
 
         case VIDIOCPWCSLED:
 	{
-		int ret;
 		struct pwc_leds leds;
 
 		if (copy_from_user(&leds, arg, sizeof(leds)))
-			return -EFAULT;
-
-		ret = pwc_set_leds(pdev, leds.led_on, leds.led_off);
-		if (ret<0)
-		    return ret;
-	    break;
+			ret = -EFAULT;
+		else
+			ret = pwc_set_leds(pdev, leds.led_on, leds.led_off);
+	    	break;
 	}
 
 
-
 	case VIDIOCPWCGLED:
 	{
-		int led;
 		struct pwc_leds leds;
 		
-		led = pwc_get_leds(pdev, &leds.led_on, &leds.led_off); 
-		if (led < 0)
-			return -EINVAL;
+		ret = pwc_get_leds(pdev, &leds.led_on, &leds.led_off); 
+		if (ret < 0)
+			break;
 		if (copy_to_user(arg, &leds, sizeof(leds)))
-			return -EFAULT;
+			ret = -EFAULT;
 		break;
 	}
 
- /* End of Add-Ons                                    */
- /* ************************************************* */
+	case VIDIOCPWCSCONTOUR:
+	{
+		int contour;
+		
+		if (copy_from_user(&contour, arg, sizeof(contour)))
+			ret = -EFAULT;
+		else
+			ret = pwc_set_contour(pdev, contour);
+		break;
+	}
+			
+	case VIDIOCPWCGCONTOUR:
+	{
+		int contour;
+		
+		ret = pwc_get_contour(pdev, &contour);
+		if (ret < 0)
+			break;
+			
+		if (copy_to_user(arg, &contour, sizeof(contour)))
+			ret = -EFAULT;
+		break;
+	}
+	
+	case VIDIOCPWCSBACKLIGHT:
+	{
+		int backlight;
+		
+		if (copy_from_user(&backlight, arg, sizeof(backlight)))
+			ret = -EFAULT;
+		else
+			ret = pwc_set_backlight(pdev, backlight);
+		break;
+	}
+
+	case VIDIOCPWCGBACKLIGHT:
+	{
+		ret = pwc_get_backlight(pdev);
+		if (ret < 0)
+			break;
+		if (copy_to_user(arg, &ret, sizeof(ret)))
+			ret = -EFAULT;
+		break;
+	}
+	
+	case VIDIOCPWCSFLICKER:
+	{
+		int flicker;
+		
+		if (copy_from_user(&flicker, arg, sizeof(flicker)))
+			ret = -EFAULT;
+		else
+			ret = pwc_set_flicker(pdev, flicker);
+		break;
+	}
+
+	case VIDIOCPWCGFLICKER:
+	{
+		ret = pwc_get_flicker(pdev);
+		if (ret < 0)
+			break;
+		if (copy_to_user(arg, &ret, sizeof(ret)))
+			ret = -EFAULT;
+		break;
+	}
+	
+	case VIDIOCPWCSDYNNOISE:
+	{
+		int dynnoise;
+		
+		if (copy_from_user(&dynnoise, arg, sizeof(dynnoise)))
+			ret = -EFAULT;
+		else
+			ret = pwc_set_dynamic_noise(pdev, dynnoise);
+		break;
+	}
+	
+	case VIDIOCPWCGDYNNOISE:
+	{
+		ret = pwc_get_dynamic_noise(pdev);
+		if (ret < 0)
+			break;
+		if (copy_to_user(arg, &ret, sizeof(ret)))
+			ret = -EFAULT;
+		break;
+	}
+	
 
 	default:
-		return -ENOIOCTLCMD;
+		ret = -ENOIOCTLCMD;
 		break;
 	}
-	return 0;
+	
+	if (ret > 0)
+		return 0;
+	return ret;
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pwc-if.c linux/drivers/usb/pwc-if.c
--- linux.orig/drivers/usb/pwc-if.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/pwc-if.c	2002-07-20 01:08:39.000000000 +0000
@@ -1,6 +1,6 @@
 /* Linux driver for Philips webcam 
    USB and Video4Linux interface part.
-   (C) 1999-2001 Nemosoft Unv.
+   (C) 1999-2002 Nemosoft Unv.
 
    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
@@ -66,7 +66,7 @@
 
 /* hotplug device table support */
 static __devinitdata struct usb_device_id pwc_device_table [] = {
-	{ USB_DEVICE(0x0471, 0x0302) },
+	{ USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
 	{ USB_DEVICE(0x0471, 0x0303) },
 	{ USB_DEVICE(0x0471, 0x0304) },
 	{ USB_DEVICE(0x0471, 0x0307) },
@@ -75,12 +75,14 @@
 	{ USB_DEVICE(0x0471, 0x0310) },
 	{ USB_DEVICE(0x0471, 0x0311) },
 	{ USB_DEVICE(0x0471, 0x0312) },
-	{ USB_DEVICE(0x069A, 0x0001) },
-	{ USB_DEVICE(0x046D, 0x08b0) },
-	{ USB_DEVICE(0x055D, 0x9000) },
+	{ USB_DEVICE(0x069A, 0x0001) }, /* Askey */
+	{ USB_DEVICE(0x046D, 0x08b0) }, /* Logitech */
+	{ USB_DEVICE(0x055D, 0x9000) }, /* Samsung */
 	{ USB_DEVICE(0x055D, 0x9001) },
-	{ USB_DEVICE(0x041E, 0x400C) },
-	{ USB_DEVICE(0x04CC, 0x8116) },
+	{ USB_DEVICE(0x041E, 0x400C) }, /* Creative */
+	{ USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
+	{ USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
+	{ USB_DEVICE(0x0d81, 0x1900) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, pwc_device_table);
@@ -105,7 +107,7 @@
 static int default_mbufs = 2;	/* Default number of mmap() buffers */
        int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
 static int power_save = 0;
-static int led_on = 1, led_off = 0; /* defaults to LED that is on while in use */
+static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */
        int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
 static struct {
 	int type;
@@ -163,7 +165,7 @@
    succeeded. The pwc_device struct links back to both structures.
 
    When a device is unplugged while in use it will be removed from the 
-   list of known USB devices; I also de-register as a V4L device, but 
+   list of known USB devices; I also de-register it as a V4L device, but 
    unfortunately I can't free the memory since the struct is still in use
    by the file descriptor. This free-ing is then deferend until the first
    opportunity. Crude, but it works.
@@ -351,6 +353,8 @@
 	for (; i < MAX_IMAGES; i++)
 		pdev->image_ptr[i] = NULL;
 
+	kbuf = NULL;
+	  
 	Trace(TRACE_MEMORY, "Leaving pwc_allocate_buffers().\n");
 	return 0;
 }
@@ -405,6 +409,7 @@
 		rvfree(pdev->image_data, default_mbufs * pdev->len_per_image);
 	}
 	pdev->image_data = NULL;
+	
 	Trace(TRACE_MEMORY, "Leaving free_buffers().\n");
 }
 
@@ -606,12 +611,10 @@
 	pdev->fill_image = (pdev->fill_image + 1) % default_mbufs;
 }
 
-/* 2001-10-14: The YUV420 is still there, but you can only set it from within 
-   a program (YUV420P being the default) */
+/* 2001-10-14: YUV420P is the only palette remaining. */
 static int pwc_set_palette(struct pwc_device *pdev, int pal)
 {
-	if (   pal == VIDEO_PALETTE_YUV420
-            || pal == VIDEO_PALETTE_YUV420P
+	if (   pal == VIDEO_PALETTE_YUV420P
 #if PWC_DEBUG
             || pal == VIDEO_PALETTE_RAW
 #endif
@@ -629,7 +632,7 @@
 /* This gets called for the Isochronous pipe (video). This is done in
  * interrupt time, so it has to be fast, not crash, and not stall. Neat.
  */
-static void pwc_isoc_handler(purb_t urb)
+static void pwc_isoc_handler(struct urb *urb)
 {
 	struct pwc_device *pdev;
 	int i, fst, flen;
@@ -791,7 +794,7 @@
 static int pwc_isoc_init(struct pwc_device *pdev)
 {
 	struct usb_device *udev;
-	purb_t urb;
+	struct urb *urb;
 	int i, j, ret;
 
 	struct usb_interface_descriptor *idesc;
@@ -905,7 +908,6 @@
 int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
 {
 	int ret;
-
 	/* Stop isoc stuff */
 	pwc_isoc_cleanup(pdev);
 	/* Reset parameters */
@@ -968,6 +970,29 @@
 		if (usb_set_interface(pdev->udev, 0, 0))
 			Info("Failed to set alternate interface to 0.\n");
 		pdev->usb_init = 1;
+		
+		if (pwc_trace & TRACE_OPEN) {
+			/* Query CMOS sensor type */
+			const char *sensor_type = NULL;
+
+			i = pwc_get_cmos_sensor(pdev);
+			switch(i) {
+			case -1: /* Unknown, show nothing */; break;
+			case 0x00:  sensor_type = "Hyundai CMOS sensor"; break;
+			case 0x20:  sensor_type = "Sony CCD sensor + TDA8787"; break;
+			case 0x2E:  sensor_type = "Sony CCD sensor + Exas 98L59"; break;
+			case 0x2F:  sensor_type = "Sony CCD sensor + ADI 9804"; break;
+			case 0x30:  sensor_type = "Sharp CCD sensor + TDA8787"; break;
+			case 0x3E:  sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
+			case 0x3F:  sensor_type = "Sharp CCD sensor + ADI 9804"; break;
+			case 0x40:  sensor_type = "UPA 1021 sensor"; break;
+			case 0x100: sensor_type = "VGA sensor"; break;
+			case 0x101: sensor_type = "PAL MR sensor"; break;
+			default:   sensor_type = "unknown type of sensor"; break;
+			}
+			if (sensor_type != NULL)
+				Info("Thes %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i);
+		}
 	}
 
 	/* Turn on camera */
@@ -1590,6 +1615,7 @@
 	pdev = vdev->priv;
 
 	/* FIXME - audit mmap during a read */		
+	/* Nemo: 9 months and 20 kernel revisions later I still don't know what you mean by this :-) */
 	pos = (unsigned long)pdev->image_data;
 	while (size > 0) {
 		page = kvirt_to_pa(pos);
@@ -1621,7 +1647,7 @@
 	int vendor_id, product_id, type_id;
 	int i, hint;
 	int video_nr = -1; /* default: use next available device */
-	char serial_number[30];
+	char serial_number[30], *name;
 
 	free_mem_leak();
 	
@@ -1642,38 +1668,47 @@
 		switch (product_id) {
 		case 0x0302:
 			Info("Philips PCA645VC USB webcam detected.\n");
+			name = "Philips 645 webcam";
 			type_id = 645;
 			break;
 		case 0x0303:
 			Info("Philips PCA646VC USB webcam detected.\n");
+			name = "Philips 646 webcam";
 			type_id = 646;
 			break;
 		case 0x0304:
 			Info("Askey VC010 type 2 USB webcam detected.\n");
+			name = "Askey VC010 webcam";
 			type_id = 646;
 			break;
 		case 0x0307:
 			Info("Philips PCVC675K (Vesta) USB webcam detected.\n");
+			name = "Philips 675 webcam";
 			type_id = 675;
 			break;
 		case 0x0308:
 			Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
+			name = "Philips 680 webcam";
 			type_id = 680;
 			break;
 		case 0x030C:
 			Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
+			name = "Philips 690 webcam";
 			type_id = 690;
 			break;
 		case 0x0310:
 			Info("Philips PCVC730K (ToUCam Fun) USB webcam detected.\n");
+			name = "Philips 730 webcam";
 			type_id = 730;
 			break;
 		case 0x0311:
 			Info("Philips PCVC740K (ToUCam Pro) USB webcam detected.\n");
+			name = "Philips 740 webcam";
 			type_id = 740;
 			break;
 		case 0x0312:
 			Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
+			name = "Philips 750 webcam";
 			type_id = 750;
 			break;
 		default:
@@ -1685,6 +1720,7 @@
 		switch(product_id) {
 		case 0x0001:
 			Info("Askey VC010 type 1 USB webcam detected.\n");
+			name = "Askey VC010 webcam";
 			type_id = 645;
 			break;
 		default:
@@ -1695,7 +1731,8 @@
 	else if (vendor_id == 0x046d) {
 		switch(product_id) {
 		case 0x08b0:
-			Info("Logitech QuickCam 3000 Pro detected.\n");
+			Info("Logitech QuickCam 3000 Pro USB webcam detected.\n");
+			name = "Logitech QuickCam 3000 Pro";
 			type_id = 730;
         		break;
         	default:
@@ -1711,10 +1748,12 @@
 		switch(product_id) {
 		case 0x9000:
 			Info("Samsung MPC-C10 USB webcam detected.\n");
+			name = "Samsung MPC-C10";
 			type_id = 675;
 			break;
 		case 0x9001:
 			Info("Samsung MPC-C30 USB webcam detected.\n");
+			name = "Samsung MPC-C30";
 			type_id = 675;
 			break;
 		default:
@@ -1726,6 +1765,7 @@
 		switch(product_id) {
 		case 0x400c:
 			Info("Creative Labs Webcam 5 detected.\n");
+			name = "Creative Labs Webcam 5";
 			type_id = 730;
 			break;
 		default:
@@ -1736,7 +1776,8 @@
 	else if (vendor_id == 0x04cc) { 
 		switch(product_id) {
 		case 0x8116:
-			Info("SOTEC CMS-001 USB webcam detected.\n");
+			Info("Sotec Afina Eye USB webcam detected.\n");
+			name = "Sotec Afina Eye";
 			type_id = 730;
 			break;  
 		default:
@@ -1744,7 +1785,25 @@
 			break;
 		}
 	}
-	else return NULL; /* Not Philips, Askey, Logitech, Samsung, Creative or SOTEC, for sure. */
+	else if (vendor_id == 0x0d81) {
+		switch(product_id) {
+		case 0x1900:
+			Info("Visionite VCS-UC300 USB webcam detected.\n");
+			name = "Visionite VCS-UC300";
+			type_id = 740; /* CCD sensor */
+			break;
+		case 0x1910:
+			Info("Visionite VCS-UM100 USB webcam detected.\n");
+			name = "Visionite VCS-UM100";
+			type_id = 730; /* CMOS sensor */
+			break;
+		default:
+			return NULL;
+			break;
+		}
+	}
+	else 
+		return NULL; /* Not any of the know types; but the list keeps growing. */
 
 	memset(serial_number, 0, 30);
 	usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
@@ -1778,7 +1837,7 @@
 		return NULL;
 	}
 	memcpy(vdev, &pwc_template, sizeof(pwc_template));
-	sprintf(vdev->name, "Philips %d webcam", pdev->type);
+	strcpy(vdev->name, name);
 	SET_MODULE_OWNER(vdev);
 	pdev->vdev = vdev;
 	vdev->priv = pdev;
@@ -1786,7 +1845,6 @@
 	pdev->release = udev->descriptor.bcdDevice;
 	Trace(TRACE_PROBE, "Release: %04x\n", pdev->release);
 
-
 	/* Now search device_hint[] table for a match, so we can hint a node number. */
 	for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
 		if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) &&
@@ -1951,11 +2009,12 @@
 	char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
 
 	Info("Philips PCA645/646 + PCVC675/680/690 + PCVC730/740/750 webcam module version " PWC_VERSION " loaded.\n");
-	Info("Also supports the Askey VC010, Logitech Quickcam 3000 Pro, Samsung MPC-C10 and MPC-C30, the Creative WebCam 5 and the SOTEC CMS-001.\n");
+	Info("Also supports the Askey VC010, Logitech Quickcam 3000 Pro, Samsung MPC-C10 and MPC-C30,\n");
+	Info("the Creative WebCam 5, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
 
 	if (fps) {
-		if (fps < 5 || fps > 30) {
-			Err("Framerate out of bounds (5-30).\n");
+		if (fps < 4 || fps > 30) {
+			Err("Framerate out of bounds (4-30).\n");
 			return -EINVAL;
 		}
 		default_fps = fps;
@@ -2007,9 +2066,9 @@
 	if (power_save)
 		Info("Enabling power save on open/close.\n");
 	if (leds[0] >= 0)
-		led_on = leds[0] / 100;
+		led_on = leds[0];
 	if (leds[1] >= 0)
-		led_off = leds[1] / 100;
+		led_off = leds[1];
 
 	/* Big device node whoopla. Basicly, it allows you to assign a 
 	   device node (/dev/videoX) to a camera, based on its type 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pwc-ioctl.h linux/drivers/usb/pwc-ioctl.h
--- linux.orig/drivers/usb/pwc-ioctl.h	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/pwc-ioctl.h	2002-07-20 01:08:35.000000000 +0000
@@ -1,7 +1,7 @@
 #ifndef PWC_IOCTL_H
 #define PWC_IOCTL_H
 
-/* (C) 2001 Nemosoft Unv.    webcam@smcc.demon.nl
+/* (C) 2001-2002 Nemosoft Unv.    webcam@smcc.demon.nl
    
    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
@@ -18,7 +18,9 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-/*
+/*         This is pwc-ioctl.h belonging to PWC 8.6                        */
+
+/* 
    Changes
    2001/08/03  Alvarado   Added ioctl constants to access methods for 
                           changing white balance and red/blue gains
@@ -52,6 +54,14 @@
 #define PWC_FPS_SNAPSHOT	0x00400000
 
 
+
+struct pwc_probe
+{
+	char name[32];
+	int type;
+};
+
+
 /* pwc_whitebalance.mode values */
 #define PWC_WB_INDOOR		0
 #define PWC_WB_OUTDOOR		1
@@ -63,9 +73,9 @@
    Set mode to one of the PWC_WB_* values above.
    *red and *blue are the respective gains of these colour components inside 
    the camera; range 0..65535
-   When mode == PWC_WB_MANUAL, manual_red and manual_blue are set or read; 
+   When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; 
    otherwise undefined.
-   read_red and read_blue are read-only.
+   'read_red' and 'read_blue' are read-only.
 */   
    
 struct pwc_whitebalance
@@ -75,6 +85,17 @@
 	int read_red, read_blue;	/* R/O */
 };
 
+/* 
+   'control_speed' and 'control_delay' are used in automatic whitebalance mode,
+   and tell the camera how fast it should react to changes in lighting, and 
+   with how much delay. Valid values are 0..65535.
+*/
+struct pwc_wb_speed
+{
+	int control_speed;
+	int control_delay;
+
+};
 
 /* Used with VIDIOCPWC[SG]LED */
 struct pwc_leds
@@ -104,6 +125,19 @@
  /* Get preferred compression quality */
 #define VIDIOCPWCGCQUAL		_IOR('v', 195, int)
 
+
+ /* This is a probe function; since so many devices are supported, it
+    becomes difficult to include all the names in programs that want to
+    check for the enhanced Philips stuff. So in stead, try this PROBE;
+    it returns a structure with the original name, and the corresponding 
+    Philips type.
+    To use, fill the structure with zeroes, call PROBE and if that succeeds,
+    compare the name with that returned from VIDIOCGCAP; they should be the
+    same. If so, you can be assured it is a Philips (OEM) cam and the type
+    is valid.
+ */    
+#define VIDIOCPWCPROBE		_IOR('v', 199, struct pwc_probe)
+
  /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
 #define VIDIOCPWCSAGC		_IOW('v', 200, int)
  /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
@@ -115,9 +149,28 @@
 #define VIDIOCPWCSAWB           _IOW('v', 202, struct pwc_whitebalance)
 #define VIDIOCPWCGAWB           _IOR('v', 202, struct pwc_whitebalance)
 
- /* Turn LED on/off ; int range 0..65535 */
+ /* Auto WB speed */
+#define VIDIOCPWCSAWBSPEED	_IOW('v', 203, struct pwc_wb_speed)
+#define VIDIOCPWCGAWBSPEED	_IOR('v', 203, struct pwc_wb_speed)
+
+ /* LEDs on/off/blink; int range 0..65535 */
 #define VIDIOCPWCSLED           _IOW('v', 205, struct pwc_leds)
- /* Get state of LED; int range 0..65535 */
 #define VIDIOCPWCGLED           _IOR('v', 205, struct pwc_leds)
 
+  /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
+#define VIDIOCPWCSCONTOUR	_IOW('v', 206, int)
+#define VIDIOCPWCGCONTOUR	_IOR('v', 206, int)
+
+  /* Backlight compensation; 0 = off, otherwise on */
+#define VIDIOCPWCSBACKLIGHT	_IOW('v', 207, int)
+#define VIDIOCPWCGBACKLIGHT	_IOR('v', 207, int)
+
+  /* Flickerless mode; = 0 off, otherwise on */
+#define VIDIOCPWCSFLICKER	_IOW('v', 208, int)
+#define VIDIOCPWCGFLICKER	_IOR('v', 208, int)  
+
+  /* Dynamic noise reduction; 0 off, 3 = high noise reduction */
+#define VIDIOCPWCSDYNNOISE	_IOW('v', 209, int)
+#define VIDIOCPWCGDYNNOISE	_IOR('v', 209, int)
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pwc-misc.c linux/drivers/usb/pwc-misc.c
--- linux.orig/drivers/usb/pwc-misc.c	2001-09-16 05:21:43.000000000 +0000
+++ linux/drivers/usb/pwc-misc.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,6 +1,6 @@
 /* Linux driver for Philips webcam 
    Various miscellaneous functions and tables.
-   (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl)
+   (C) 1999-2002 Nemosoft Unv. (webcam@smcc.demon.nl)
 
    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
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pwc-uncompress.c linux/drivers/usb/pwc-uncompress.c
--- linux.orig/drivers/usb/pwc-uncompress.c	2001-06-21 00:42:09.000000000 +0000
+++ linux/drivers/usb/pwc-uncompress.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,6 +1,6 @@
 /* Linux driver for Philips webcam 
    Decompression frontend.
-   (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl)
+   (C) 1999-2002 Nemosoft Unv. (webcam@smcc.demon.nl)
 
    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
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pwc-uncompress.h linux/drivers/usb/pwc-uncompress.h
--- linux.orig/drivers/usb/pwc-uncompress.h	2001-06-21 00:42:09.000000000 +0000
+++ linux/drivers/usb/pwc-uncompress.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,4 +1,4 @@
-/* (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl)
+/* (C) 1999-2002 Nemosoft Unv. (webcam@smcc.demon.nl)
 
    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
@@ -20,8 +20,8 @@
    significant change should be reflected by increasing the 
    pwc_decompressor_version major number.
  */
-#ifndef PWC_DEC_H
-#define PWC_DEC_H
+#ifndef PWC_UNCOMPRESS_H
+#define PWC_UNCOMPRESS_H
 
 #include <linux/config.h>
 #include <linux/list.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/pwc.h linux/drivers/usb/pwc.h
--- linux.orig/drivers/usb/pwc.h	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/pwc.h	2002-07-20 01:08:24.000000000 +0000
@@ -1,4 +1,4 @@
-/* (C) 1999-2001 Nemosoft Unv. (webcam@smcc.demon.nl)
+/* (C) 1999-2002 Nemosoft Unv. (webcam@smcc.demon.nl)
 
    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
@@ -60,8 +60,8 @@
 
 /* Version block */
 #define PWC_MAJOR	8
-#define PWC_MINOR	5
-#define PWC_VERSION 	"8.5"
+#define PWC_MINOR	6
+#define PWC_VERSION 	"8.6"
 #define PWC_NAME 	"pwc"
 
 /* Turn certain features on/off */
@@ -96,7 +96,7 @@
 	void *data;
 	int  length;
 	int  read;
-	purb_t urb;
+	struct urb *urb;
 };
 
 /* intermediate buffers with raw data from the USB cam */
@@ -247,6 +247,7 @@
 extern int pwc_set_saturation(struct pwc_device *pdev, int value);
 extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
 extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
+extern int pwc_get_cmos_sensor(struct pwc_device *pdev);
 
 /* Power down or up the camera; not supported by all models */
 extern int pwc_camera_power(struct pwc_device *pdev, int power);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/rtl8150.c linux/drivers/usb/rtl8150.c
--- linux.orig/drivers/usb/rtl8150.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/usb/rtl8150.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,763 @@
+/*
+ * Copyright (c) 2002 Petko Manolov (petkan@users.sourceforge.net)
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation; either version 2 of
+ *	the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/usb.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+
+
+
+/* Version Information */
+#define DRIVER_VERSION "v0.4.0 (2002/03/28)"
+#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
+#define DRIVER_DESC "rtl8150 based usb-ethernet driver"
+
+
+#define	IRD			0x0120
+#define	MAR			0x0126
+#define	CR			0x012e
+#define	TCR			0x012f
+#define	RCR			0x0130
+#define	TSR			0x0132
+#define	RSR			0x0133
+#define	CON0			0x0135
+#define	CON1			0x0136
+#define	MSR			0x0137
+#define	PHYADD			0x0138
+#define	PHYDAT			0x0139
+#define	PHYCNT			0x013b
+#define	GPPC			0x013d
+#define	BMCR			0x0140
+#define	BMSR			0x0142
+#define	ANAR			0x0144
+#define	ANLP			0x0146
+#define	AER			0x0148
+
+#define	PHY_READ		0
+#define	PHY_WRITE		0x20
+#define	PHY_GO			0x40
+
+#define	RTL8150_REQT_READ	0xc0
+#define	RTL8150_REQT_WRITE	0x40
+#define	RTL8150_REQ_GET_REGS	0x05
+#define	RTL8150_REQ_SET_REGS	0x05
+
+#define	RTL8150_MTU		1500
+#define	RTL8150_MAX_MTU		1536
+
+#define	RTL8150_TX_TIMEOUT	(HZ)
+
+/* rtl8150 flags */
+#define	RTL8150_FLAG_HWCRC	0
+#define	RX_REG_SET		1
+#define	RTL8150_UNPLUG		2
+
+
+/* Define these values to match your device */
+#define VENDOR_ID_REALTEK		0x0bda
+#define PRODUCT_ID_RTL8150		0x8150
+
+/* table of devices that work with this driver */
+static struct usb_device_id rtl8150_table [] = {
+	{ USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8150) },
+	{ }				
+};
+
+MODULE_DEVICE_TABLE (usb, rtl8150_table);
+
+
+struct rtl8150 {
+	unsigned long		flags;
+	struct usb_device	*udev;
+	struct usb_interface	*interface;
+	struct semaphore	sem;
+	struct net_device_stats	stats;
+	struct net_device	*netdev;
+	struct urb		*rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
+	devrequest		dr;
+	int			intr_interval;
+	u16			rx_creg;
+	u8			rx_buff[RTL8150_MAX_MTU];
+	u8			tx_buff[RTL8150_MAX_MTU];
+	u8			intr_buff[8];
+	u8			phy;
+};
+
+typedef	struct rtl8150	rtl8150_t;
+
+
+/* the global usb devfs handle */
+extern devfs_handle_t usb_devfs_handle;
+unsigned long multicast_filter_limit = 32;
+
+
+static void rtl8150_disconnect(struct usb_device *dev, void *ptr);
+static void * rtl8150_probe(struct usb_device *dev, unsigned int ifnum,
+			    const struct usb_device_id *id);
+
+
+static struct usb_driver rtl8150_driver = {
+	name:		"rtl8150",
+	probe:		rtl8150_probe,
+	disconnect:	rtl8150_disconnect,
+	id_table:	rtl8150_table,
+};
+
+
+
+/*
+**
+**	device related part of the code
+**
+*/
+static int get_registers(rtl8150_t *dev, u16 indx, u16 size, void *data)
+{
+	return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev,0),
+				RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
+				indx, 0, data, size, HZ/2);
+}
+
+
+static int set_registers(rtl8150_t *dev, u16 indx, u16 size, void *data)
+{
+	return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev,0),
+				RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
+				indx, 0, data, size, HZ/2);
+}
+
+
+static void ctrl_callback(struct urb *urb)
+{
+	rtl8150_t	*dev;
+	
+	switch (urb->status) {
+	case 0:
+		break;
+	case -EINPROGRESS:
+		break;
+	case -ENOENT:
+		break;
+	default:
+		warn("ctrl urb status %d", urb->status);
+	}
+	dev = urb->context;
+	clear_bit(RX_REG_SET, &dev->flags);
+}
+
+
+static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, void *data)
+{
+	int	ret;
+
+	if (test_bit(RX_REG_SET, &dev->flags))
+		return -EAGAIN;
+	
+	dev->dr.requesttype = RTL8150_REQT_WRITE;
+	dev->dr.request = RTL8150_REQ_SET_REGS;
+	dev->dr.value = cpu_to_le16(indx);
+	dev->dr.index = 0;
+	dev->dr.length = cpu_to_le16(2);
+	dev->ctrl_urb->transfer_buffer_length = 2;
+	FILL_CONTROL_URB(dev->ctrl_urb, dev->udev, usb_sndctrlpipe(dev->udev,0),
+	                 (char*)&dev->dr, &dev->rx_creg, 2, ctrl_callback, dev);
+	if ((ret = usb_submit_urb(dev->ctrl_urb)))
+		err("control request submission failed: %d", ret);
+	else
+		set_bit(RX_REG_SET, &dev->flags);
+
+	return ret;
+}
+
+
+static int read_mii_word(rtl8150_t *dev, u8 phy, __u8 indx, u16 *reg)
+{
+	int	i;
+	u8	data[3], tmp;
+
+	data[0] = phy;
+	data[1] = data[2] = 0;
+	tmp = indx | PHY_READ | PHY_GO;
+	i = 0;
+
+	set_registers(dev, PHYADD, sizeof(data), data);
+	set_registers(dev, PHYCNT, 1, &tmp);
+	do {
+		get_registers(dev, PHYCNT, 1, data);
+	} while ((data[0] & PHY_GO) && (i++ < HZ));
+
+	if (i < HZ) {
+		get_registers(dev, PHYDAT, 2, data);
+		*reg = le16_to_cpup(data);
+		return 0;
+	} else
+		return 1;
+}
+
+
+static int write_mii_word(rtl8150_t *dev, u8 phy, __u8 indx, u16 reg)
+{
+	int	i;
+	u8	data[3], tmp;
+
+	data[0] = phy;
+	*(data + 1) = cpu_to_le16p(&reg);
+	tmp = indx | PHY_WRITE | PHY_GO;
+	i = 0;
+
+	set_registers(dev, PHYADD, sizeof(data), data);
+	set_registers(dev, PHYCNT, 1, &tmp);
+	do {
+		get_registers(dev, PHYCNT, 1, data);
+	} while((data[0] & PHY_GO) && (i++ < HZ));
+
+	if (i < HZ)
+		return 0;
+	else
+		return 1;
+}
+
+
+static inline void set_ethernet_addr(rtl8150_t *dev)
+{
+	u8	node_id[6];
+
+	get_registers(dev, IRD, sizeof(node_id), node_id);
+	memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id));
+}
+
+
+static int rtl8150_reset(rtl8150_t *dev)
+{
+	u8	data=0x10;
+	int	i=HZ;
+
+	set_registers(dev, CR, 1, &data);
+	do {
+		get_registers(dev, CR, 1, &data);
+	} while ((data & 0x10) && --i);
+	
+	return (i > 0) ? 0 : -1;
+}
+
+
+static int alloc_all_urbs(rtl8150_t *dev)
+{
+	dev->rx_urb = usb_alloc_urb(0);
+	if (!dev->rx_urb)
+		return 0;
+	dev->tx_urb = usb_alloc_urb(0);
+	if (!dev->tx_urb) {
+		usb_free_urb(dev->rx_urb);
+		return 0;
+	}
+	dev->intr_urb = usb_alloc_urb(0);
+	if (!dev->intr_urb) {
+		usb_free_urb(dev->rx_urb);
+		usb_free_urb(dev->tx_urb);
+		return 0;
+	}
+	dev->ctrl_urb = usb_alloc_urb(0);
+	if (!dev->ctrl_urb) {
+		usb_free_urb(dev->rx_urb);
+		usb_free_urb(dev->tx_urb);
+		usb_free_urb(dev->intr_urb);
+		return 0;
+	}
+
+	return 1;
+}
+
+
+static void free_all_urbs(rtl8150_t *dev)
+{
+	usb_free_urb(dev->rx_urb);
+	usb_free_urb(dev->tx_urb);
+	usb_free_urb(dev->intr_urb);
+	usb_free_urb(dev->ctrl_urb);
+}
+
+
+static void unlink_all_urbs(rtl8150_t *dev)
+{
+	usb_unlink_urb(dev->rx_urb);
+	usb_unlink_urb(dev->tx_urb);
+	usb_unlink_urb(dev->intr_urb);
+	usb_unlink_urb(dev->ctrl_urb);
+}
+
+
+static void read_bulk_callback(struct urb *urb)
+{
+	rtl8150_t	*dev;
+	int		pkt_len, res;
+	struct sk_buff	*skb;
+	struct net_device *netdev;
+	u16		rx_stat;
+
+	dev = urb->context;
+	if (!dev) {
+		warn("!dev");
+		return;
+	}
+	netdev = dev->netdev;
+	if (!netif_device_present(netdev)) {
+		warn("netdev is not present");
+		return;
+	}
+	switch (urb->status) {
+	case 0:
+		break;
+	case -ENOENT:
+		return;
+	case -ETIMEDOUT:
+		warn("reset needed may be?..");
+		goto goon;
+	default:
+		warn("Rx status %d", urb->status);
+		goto goon;
+	}
+	
+	pkt_len = urb->actual_length - 4;
+	rx_stat = le16_to_cpu(*(u16 *)(dev->rx_buff + pkt_len));
+
+	if (!(skb = dev_alloc_skb(pkt_len + 2))) 
+		goto goon;
+	skb->dev = netdev;
+	skb_reserve(skb, 2);
+	eth_copy_and_sum(skb, dev->rx_buff, pkt_len, 0);
+	skb_put(skb, pkt_len);
+	skb->protocol = eth_type_trans(skb, netdev);
+	netif_rx(skb);
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += pkt_len;
+goon:
+	FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev,1),
+	              dev->rx_buff, RTL8150_MAX_MTU, read_bulk_callback, dev);
+	if ((res=usb_submit_urb(dev->rx_urb)))
+		warn("%s: Rx urb submission failed %d", netdev->name, res);
+}
+
+
+static void write_bulk_callback(struct urb *urb)
+{
+	rtl8150_t	*dev;
+
+	dev = urb->context;
+	if (!dev)
+		return;
+	if (!netif_device_present(dev->netdev))
+		return;
+	if (urb->status)
+		info("%s: Tx status %d", dev->netdev->name, urb->status);
+	dev->netdev->trans_start = jiffies;
+	netif_wake_queue(dev->netdev);
+}
+
+
+void intr_callback(struct urb *urb)
+{
+	rtl8150_t	*dev;
+
+	dev = urb->context;
+	if (!dev)
+		return;
+	switch (urb->status) {
+		case 0:
+			break;
+		case -ENOENT:
+			return;
+		default:
+			info("%s: intr status %d", dev->netdev->name,
+			     urb->status);
+	}
+}
+
+
+/*
+**
+**	network related part of the code
+**
+*/
+
+
+static int enable_net_traffic(rtl8150_t *dev)
+{
+	u8	cr, tcr, rcr, msr;
+
+	if (rtl8150_reset(dev)) {
+		warn("%s - device reset failed", __FUNCTION__);
+	}
+	dev->rx_creg = rcr = 0x9e;	/* bit7=1 attach Rx info at the end */
+	tcr = 0xd8;
+	cr = 0x0c;
+	set_registers(dev, RCR, 1, &rcr);
+	set_registers(dev, TCR, 1, &tcr);
+	set_registers(dev, CR, 1, &cr);
+	get_registers(dev, MSR, 1, &msr);
+
+	return 0;
+}
+
+
+static void disable_net_traffic(rtl8150_t *dev)
+{
+	u8	cr;
+
+	get_registers(dev, CR, 1, &cr);
+	cr &= 0xf3;
+	set_registers(dev, CR, 1, &cr);
+}
+
+
+static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev)
+{
+	return &((rtl8150_t *)dev->priv)->stats;
+}
+
+
+static void rtl8150_tx_timeout(struct net_device *netdev)
+{
+	rtl8150_t	*dev;
+
+	dev = netdev->priv;
+	if (!dev)
+		return;
+	warn("%s: Tx timeout.", netdev->name);
+	dev->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;
+	usb_unlink_urb(dev->tx_urb);
+	dev->stats.tx_errors++;
+}
+
+
+static void rtl8150_set_multicast(struct net_device *netdev)
+{
+	rtl8150_t	*dev;
+
+	dev = netdev->priv;
+	netif_stop_queue(netdev);
+	if (netdev->flags & IFF_PROMISC) {
+		dev->rx_creg |= 0x0001;
+		info("%s: promiscuous mode", netdev->name);
+	} else if ((netdev->mc_count > multicast_filter_limit) ||
+	           (netdev->flags & IFF_ALLMULTI)) {
+		dev->rx_creg &= 0xfffe;
+		dev->rx_creg |= 0x0002;
+		info("%s: allmulti set", netdev->name);
+	} else {
+		/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
+		dev->rx_creg &= 0x00fc;
+	}
+	async_set_registers(dev, RCR, 2, &dev->rx_creg);
+	netif_wake_queue(netdev);
+}
+
+
+static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	rtl8150_t	*dev;
+	int		count, res;
+
+	netif_stop_queue(netdev);
+	dev = netdev->priv;
+	count = (skb->len < 60) ? 60 : skb->len;
+	count = (count & 0x3f) ? count : count + 1;
+	memcpy(dev->tx_buff, skb->data, skb->len);
+	FILL_BULK_URB(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev,2),
+		      dev->tx_buff, RTL8150_MAX_MTU, write_bulk_callback, dev);
+	dev->tx_urb->transfer_buffer_length = count;
+
+	if ((res = usb_submit_urb(dev->tx_urb))) {
+		warn("failed tx_urb %d\n", res);
+		dev->stats.tx_errors++;
+		netif_start_queue(netdev);
+	} else {
+		dev->stats.tx_packets++;
+		dev->stats.tx_bytes += skb->len;
+		netdev->trans_start = jiffies;
+	}
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+
+static int rtl8150_open(struct net_device *netdev)
+{
+	rtl8150_t	*dev;
+	int		res;
+	
+	dev = netdev->priv;
+	if (dev == NULL) {
+		return -ENODEV;
+	}
+
+	down(&dev->sem);
+	FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev,1),
+			dev->rx_buff, RTL8150_MAX_MTU, read_bulk_callback, dev);
+	if ((res=usb_submit_urb(dev->rx_urb)))
+		warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
+	FILL_INT_URB(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev,3),
+			dev->intr_buff, sizeof(dev->intr_buff), intr_callback,
+			dev, dev->intr_interval);
+	if ((res=usb_submit_urb(dev->intr_urb)))
+		warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
+	netif_start_queue(netdev);
+	enable_net_traffic(dev);
+	up(&dev->sem);
+
+	return res;
+}
+
+
+static int rtl8150_close(struct net_device *netdev)
+{
+	rtl8150_t *dev;
+	int res = 0;
+
+	dev = netdev->priv;
+	if (!dev)
+		return -ENODEV;
+
+	down(&dev->sem);
+	if (!test_bit(RTL8150_UNPLUG, &dev->flags))
+		disable_net_traffic(dev);
+	unlink_all_urbs(dev);
+	netif_stop_queue(netdev);
+	up(&dev->sem);
+
+	return res;
+}
+
+
+static int rtl8150_ethtool_ioctl(struct net_device *netdev, void *uaddr)
+{
+	rtl8150_t	*dev;
+	int		cmd;
+	char		tmp[128];
+
+	dev = netdev->priv;
+	if (get_user(cmd, (int *)uaddr))
+		return -EFAULT;
+
+	switch (cmd) {
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		
+		strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
+		strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
+		sprintf(tmp, "usb%d:%d", dev->udev->bus->busnum,
+		        dev->udev->devnum);
+		strncpy(info.bus_info, tmp, ETHTOOL_BUSINFO_LEN);
+		if (copy_to_user(uaddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_GSET: {
+		struct ethtool_cmd ecmd;
+		short   lpa, bmcr;
+
+		if (copy_from_user(&ecmd, uaddr, sizeof(ecmd)))
+			return -EFAULT;
+		ecmd.supported = (SUPPORTED_10baseT_Half |
+		                  SUPPORTED_10baseT_Full |
+		                  SUPPORTED_100baseT_Half |
+		                  SUPPORTED_100baseT_Full |
+		                  SUPPORTED_Autoneg |
+		                  SUPPORTED_TP |
+		                  SUPPORTED_MII);
+		ecmd.port = PORT_TP;
+		ecmd.transceiver = XCVR_INTERNAL;
+		ecmd.phy_address = dev->phy;
+		get_registers(dev, BMCR, 2, &bmcr);
+		get_registers(dev, ANLP, 2, &lpa);
+		if (bmcr & BMCR_ANENABLE) {
+			ecmd.autoneg = AUTONEG_ENABLE;
+			ecmd.speed = (lpa & (LPA_100HALF | LPA_100FULL)) ?
+			             SPEED_100 : SPEED_10;
+			if (ecmd.speed == SPEED_100)
+				ecmd.duplex = (lpa & LPA_100FULL) ?
+				              DUPLEX_FULL : DUPLEX_HALF;
+			else
+				ecmd.duplex = (lpa & LPA_10FULL) ?
+				              DUPLEX_FULL : DUPLEX_HALF;
+		} else {
+			ecmd.autoneg = AUTONEG_DISABLE;
+			ecmd.speed = (bmcr & BMCR_SPEED100) ?
+			             SPEED_100 : SPEED_10;
+			ecmd.duplex = (bmcr & BMCR_FULLDPLX) ?
+			              DUPLEX_FULL : DUPLEX_HALF;
+		}
+		if (copy_to_user(uaddr, &ecmd, sizeof(ecmd)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SSET:
+		return -ENOTSUPP;
+	case ETHTOOL_GLINK: {
+		struct ethtool_value edata = {ETHTOOL_GLINK};
+
+		edata.data = netif_carrier_ok(netdev);
+		if (copy_to_user(uaddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+
+static int rtl8150_ioctl (struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	rtl8150_t *dev;
+	u16	*data;
+	int	res;
+
+	dev = netdev->priv;
+	data = (u16 *)&rq->ifr_data;
+	res = 0;
+
+	down(&dev->sem);
+	switch (cmd) {
+	case SIOCETHTOOL:
+		res = rtl8150_ethtool_ioctl(netdev, rq->ifr_data);
+		break;
+	case SIOCDEVPRIVATE:
+		data[0] = dev->phy;
+	case SIOCDEVPRIVATE+1:
+		read_mii_word(dev, dev->phy, (data[1] & 0x1f), &data[3]);
+		break;
+	case SIOCDEVPRIVATE+2:
+		if (!capable(CAP_NET_ADMIN)) {
+			up(&dev->sem);
+			return -EPERM;
+		}
+		write_mii_word(dev, dev->phy, (data[1] & 0x1f), data[2]);
+		break;
+	default:
+		res = -EOPNOTSUPP;
+	}
+	up(&dev->sem);
+
+	return res;
+}
+
+
+static void * rtl8150_probe(struct usb_device *udev, unsigned int ifnum,
+			    const struct usb_device_id *id)
+{
+	rtl8150_t *dev;
+	struct net_device *netdev;
+
+	udev->config[0].bConfigurationValue = 1;
+	if (usb_set_configuration(udev, udev->config[0].bConfigurationValue)) {
+		err("usb_set_configuration() failed");
+		return NULL;
+	}
+	if ((udev->descriptor.idVendor != VENDOR_ID_REALTEK) ||
+	    (udev->descriptor.idProduct != PRODUCT_ID_RTL8150)) {
+	    	err("Not the one we are interested about");
+		return NULL;
+	}
+	dev = kmalloc(sizeof(rtl8150_t), GFP_KERNEL);
+	if (!dev) {
+		err ("Out of memory");
+		goto exit;
+	} else
+		memset(dev, 0, sizeof(rtl8150_t));
+
+	netdev = init_etherdev(NULL, 0);
+	if (!netdev) {
+		kfree(dev);
+		err("Oh boy, out of memory again?!?");
+		dev = NULL;
+		goto exit;
+	}
+		
+	init_MUTEX(&dev->sem);
+	dev->udev = udev;
+	dev->netdev = netdev;
+	SET_MODULE_OWNER(netdev);
+	netdev->priv = dev;
+	netdev->open = rtl8150_open;
+	netdev->stop = rtl8150_close;
+	netdev->do_ioctl = rtl8150_ioctl;
+	netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
+	netdev->tx_timeout = rtl8150_tx_timeout;
+	netdev->hard_start_xmit = rtl8150_start_xmit;
+	netdev->set_multicast_list = rtl8150_set_multicast;
+	netdev->get_stats = rtl8150_netdev_stats;
+	netdev->mtu = RTL8150_MTU;
+	dev->intr_interval = 100;	/* 100ms */
+
+	if (rtl8150_reset(dev) || !alloc_all_urbs(dev)) {
+		err("couldn't reset the device");
+		free_all_urbs(dev);
+		unregister_netdev(dev->netdev);
+		kfree(netdev);
+		kfree(dev);
+		dev = NULL;
+		goto exit;
+	}
+
+	set_ethernet_addr(dev);
+	/* let's not be very nasty :-) */
+	info("%s: rtl8150 is detected", netdev->name);
+exit:
+	return dev;
+}
+
+
+static void rtl8150_disconnect(struct usb_device *udev, void *ptr)
+{
+	rtl8150_t *dev;
+
+	dev = ptr;
+	set_bit(RTL8150_UNPLUG, &dev->flags);
+	unregister_netdev(dev->netdev);
+	unlink_all_urbs(dev);
+	free_all_urbs(dev);
+	kfree(dev->netdev);
+	kfree(dev);
+	dev->netdev = NULL;
+	dev = NULL;
+}
+
+
+
+static int __init usb_rtl8150_init(void)
+{
+	info(DRIVER_DESC " " DRIVER_VERSION);
+	return usb_register(&rtl8150_driver);
+}
+
+
+static void __exit usb_rtl8150_exit(void)
+{
+	usb_deregister(&rtl8150_driver);
+}
+
+
+module_init(usb_rtl8150_init);
+module_exit(usb_rtl8150_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/se401.c linux/drivers/usb/se401.c
--- linux.orig/drivers/usb/se401.c	2001-09-14 21:27:10.000000000 +0000
+++ linux/drivers/usb/se401.c	2002-07-20 01:08:31.000000000 +0000
@@ -646,7 +646,7 @@
 	for (i=0; i<SE401_NUMSBUF; i++) {
 		urb=usb_alloc_urb(0);
 		if(!urb)
-			return ENOMEM;
+			return -ENOMEM;
 
 		FILL_BULK_URB(urb, se401->dev,
 			usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/Config.in linux/drivers/usb/serial/Config.in
--- linux.orig/drivers/usb/serial/Config.in	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/serial/Config.in	2002-07-20 01:08:22.000000000 +0000
@@ -15,7 +15,7 @@
 dep_tristate '  USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
 dep_tristate '  USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
 dep_tristate '  USB Handspring Visor / Palm m50x / Sony Clie Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
-dep_tristate '  USB Compaq iPAQ Driver' CONFIG_USB_SERIAL_IPAQ $CONFIG_USB_SERIAL
+dep_tristate '  USB Compaq iPAQ / HP Jornada / Casio EM500 Driver' CONFIG_USB_SERIAL_IPAQ $CONFIG_USB_SERIAL
 dep_tristate '  USB IR Dongle Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_IR $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
 dep_tristate '  USB Inside Out Edgeport Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EDGEPORT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
 dep_tristate '  USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c
--- linux.orig/drivers/usb/serial/cyberjack.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/usb/serial/cyberjack.c	2002-07-20 01:08:39.000000000 +0000
@@ -238,13 +238,16 @@
 	if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) {
 		/* To much data  for buffer. Reset buffer. */
 		priv->wrfilled=0;
+		up (&port->sem);
 		return (0);
 	}
 
 	/* Copy data */
 	if (from_user) {
-		if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count))
+		if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) {
+			up (&port->sem);
 			return -EFAULT;
+		}
 	} else {
 		memcpy (priv->wrbuf+priv->wrfilled, buf, count);
 	}  
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c
--- linux.orig/drivers/usb/serial/digi_acceleport.c	2001-10-11 06:42:47.000000000 +0000
+++ linux/drivers/usb/serial/digi_acceleport.c	2002-07-20 01:08:35.000000000 +0000
@@ -734,7 +734,7 @@
 	while( count > 0 && ret == 0 ) {
 
 		while( (port->write_urb->status == -EINPROGRESS
-		|| priv->dp_write_urb_in_use) && jiffies < timeout ) {
+		|| priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) {
 			cond_wait_interruptible_timeout_irqrestore(
 				&port->write_wait, DIGI_RETRY_TIMEOUT,
 				&priv->dp_port_lock, flags );
@@ -899,7 +899,7 @@
 
 	spin_lock_irqsave( &priv->dp_port_lock, flags );
 
-	while( jiffies < timeout && !priv->dp_transmit_idle ) {
+	while( time_before(jiffies, timeout) && !priv->dp_transmit_idle ) {
 		cond_wait_interruptible_timeout_irqrestore(
 			&priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT,
 			&priv->dp_port_lock, flags );
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- linux.orig/drivers/usb/serial/ftdi_sio.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/usb/serial/ftdi_sio.c	2002-07-20 01:08:29.000000000 +0000
@@ -138,6 +138,7 @@
    
 static __devinitdata struct usb_device_id id_table_8U232AM [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
+	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
 	{ }						/* Terminating entry */
 };
 
@@ -145,6 +146,7 @@
 static __devinitdata struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
+	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
 	{ }						/* Terminating entry */
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/ftdi_sio.h linux/drivers/usb/serial/ftdi_sio.h
--- linux.orig/drivers/usb/serial/ftdi_sio.h	2001-05-24 21:55:51.000000000 +0000
+++ linux/drivers/usb/serial/ftdi_sio.h	2002-07-20 01:08:31.000000000 +0000
@@ -22,6 +22,8 @@
 #define FTDI_VID	0x0403	/* Vendor Id */
 #define FTDI_SIO_PID	0x8372	/* Product Id SIO application of 8U100AX  */
 #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
+#define FTDI_NF_RIC_VID	0x0DCD	/* Vendor Id */
+#define FTDI_NF_RIC_PID	0x0001	/* Product Id */
 
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c
--- linux.orig/drivers/usb/serial/io_edgeport.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/usb/serial/io_edgeport.c	2002-07-20 01:08:24.000000000 +0000
@@ -2,7 +2,7 @@
  * Edgeport USB Serial Converter driver
  *
  * Copyright(c) 2000 Inside Out Networks, All rights reserved.
- * Copyright(c) 2001 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright(c) 2001-2002 Greg Kroah-Hartman <greg@kroah.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
@@ -25,6 +25,9 @@
  *
  * Version history:
  * 
+ * 2.3 2002_03_08 greg kroah-hartman
+ *	- fixed bug when multiple devices were attached at the same time.
+ *
  * 2.2 2001_11_14 greg kroah-hartman
  *	- fixed bug in edge_close that kept the port from being used more
  *	  than once.
@@ -1449,8 +1452,8 @@
 		edge_port->write_in_progress = FALSE;
 		return;
 	}
-	buffer[0] = IOSP_BUILD_DATA_HDR1 (edge_port->port->number, count);
-	buffer[1] = IOSP_BUILD_DATA_HDR2 (edge_port->port->number, count);
+	buffer[0] = IOSP_BUILD_DATA_HDR1 (edge_port->port->number - edge_port->port->serial->minor, count);
+	buffer[1] = IOSP_BUILD_DATA_HDR2 (edge_port->port->number - edge_port->port->serial->minor, count);
 
 	/* now copy our data */
 	bytesleft =  fifo->size - fifo->tail;
@@ -2447,7 +2450,9 @@
 
 	currentCommand = buffer;
 
-	MAKE_CMD_EXT_CMD( &currentCommand, &length, edge_port->port->number, command, param);
+	MAKE_CMD_EXT_CMD (&currentCommand, &length,
+			  edge_port->port->number - edge_port->port->serial->minor,
+			  command, param);
 
 	status = write_cmd_usb (edge_port, buffer, length);
 	if (status) {
@@ -2527,9 +2532,9 @@
 	int cmdLen = 0;
 	int divisor;
 	int status;
-	unsigned char number = edge_port->port->number;
+	unsigned char number = edge_port->port->number - edge_port->port->serial->minor;
 
-	dbg(__FUNCTION__" - port = %d, baud = %d", number, baudRate);
+	dbg(__FUNCTION__" - port = %d, baud = %d", edge_port->port->number, baudRate);
 
 	status = calc_baud_rate_divisor (baudRate, &divisor);
 	if (status) {
@@ -2632,7 +2637,9 @@
 	currCmd = cmdBuffer;
 
 	// Build a cmd in the buffer to write the given register
-	MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, edge_port->port->number, regNum, regValue);
+	MAKE_CMD_WRITE_REG (&currCmd, &cmdLen,
+			    edge_port->port->number - edge_port->port->serial->minor,
+			    regNum, regValue);
 
 	status = write_cmd_usb(edge_port, cmdBuffer, cmdLen);
 	if (status) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/io_tables.h linux/drivers/usb/serial/io_tables.h
--- linux.orig/drivers/usb/serial/io_tables.h	2001-11-14 01:45:27.000000000 +0000
+++ linux/drivers/usb/serial/io_tables.h	2002-07-20 01:08:24.000000000 +0000
@@ -25,6 +25,11 @@
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_421) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_21) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2_DIN) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_2) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_2I) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_421) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_21) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_2_DIN) },
 	{ }
 };
 
@@ -37,6 +42,11 @@
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4_DIN) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_COMPATIBLE) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_4) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_4T) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_4I) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_8_DUAL_CPU) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_4_DIN) },
 	{ }
 };
 
@@ -44,6 +54,9 @@
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8I) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_8) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_16_DUAL_CPU) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_8I) },
 	{ }
 };
 
@@ -66,6 +79,19 @@
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_EDGEPORT_COMPATIBLE) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_EDGEPORT_8I) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_2) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_2I) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_421) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_21) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_2_DIN) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_4) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_4T) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_4I) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_8_DUAL_CPU) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_4_DIN) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_8) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_16_DUAL_CPU) },
+	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BB_EDGEPORT_8I) },
 	{ }							/* Terminating entry */
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/io_usbvend.h linux/drivers/usb/serial/io_usbvend.h
--- linux.orig/drivers/usb/serial/io_usbvend.h	2001-11-14 01:45:27.000000000 +0000
+++ linux/drivers/usb/serial/io_usbvend.h	2002-07-20 01:08:28.000000000 +0000
@@ -92,6 +92,20 @@
 #define ION_DEVICE_ID_EDGEPORT_8I		0x014	// Edgeport/8 RS422 (single-CPU)
 #define ION_DEVICE_ID_MT4X56USB			0x1403	// OEM device
 
+// BlackBox OEM devices
+#define ION_DEVICE_ID_BB_EDGEPORT_4		0x001	// Edgeport/4 RS232
+#define ION_DEVICE_ID_BB_EDGEPORT_4T		0x004	// Edgeport/4 RS232 for Telxon (aka "Fleetport")
+#define ION_DEVICE_ID_BB_EDGEPORT_2		0x005	// Edgeport/2 RS232
+#define ION_DEVICE_ID_BB_EDGEPORT_4I		0x006	// Edgeport/4 RS422
+#define ION_DEVICE_ID_BB_EDGEPORT_2I		0x007	// Edgeport/2 RS422/RS485
+#define	ION_DEVICE_ID_BB_EDGEPORT_421		0x00C	// Edgeport/421 Hub+RS232+Parallel
+#define	ION_DEVICE_ID_BB_EDGEPORT_21		0x00D	// Edgeport/21  RS232+Parallel
+#define ION_DEVICE_ID_BB_EDGEPORT_8_DUAL_CPU	0x00E	// Half of an Edgeport/8 (the kind with 2 EP/4s on 1 PCB)
+#define ION_DEVICE_ID_BB_EDGEPORT_8		0x00F	// Edgeport/8 (single-CPU)
+#define ION_DEVICE_ID_BB_EDGEPORT_2_DIN		0x010	// Edgeport/2 RS232 with Apple DIN connector
+#define ION_DEVICE_ID_BB_EDGEPORT_4_DIN		0x011	// Edgeport/4 RS232 with Apple DIN connector
+#define ION_DEVICE_ID_BB_EDGEPORT_16_DUAL_CPU	0x012	// Half of an Edgeport/16 (the kind with 2 EP/8s)
+#define ION_DEVICE_ID_BB_EDGEPORT_8I		0x014	// Edgeport/8 RS422 (single-CPU)
 // These IDs are used by the Edgeport.exe program for uninstalling.
 // 
 #define EDGEPORT_DEVICE_IDS	{0x001, 0x003, 0x004, 0x005, 0x006, 0x007, 0x00B, \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/ipaq.c linux/drivers/usb/serial/ipaq.c
--- linux.orig/drivers/usb/serial/ipaq.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/serial/ipaq.c	2002-07-20 01:08:37.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * USB Compaq iPAQ driver
  *
- *	Copyright (C) 2001
+ *	Copyright (C) 2001 - 2002
  *	    Ganesh Varadarajan <ganesh@veritas.com>
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -9,6 +9,27 @@
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
  *
+ * (30/4/2002) ganesh
+ * 	Added support for the Casio EM500. Completely untested. Thanks
+ * 	to info from Nathan <wfilardo@fuse.net>
+ *
+ * (19/3/2002) ganesh
+ * 	Don't submit urbs while holding spinlocks. Thanks to Greg for pointing
+ * 	this out.
+ *
+ * (8/3/2002) ganesh
+ * 	The ipaq sometimes emits a '\0' before the CLIENT string. At this
+ * 	point of time, the ppp ldisc is not yet attached to the tty, so
+ * 	n_tty echoes "^ " to the ipaq, which messes up the chat. In 2.5.6-pre2
+ * 	this causes a panic because echo_char() tries to sleep in interrupt
+ * 	context.
+ * 	The fix is to tell the upper layers that this is a raw device so that
+ * 	echoing is suppressed. Thanks to Lyle Lindholm for a detailed bug
+ * 	report.
+ *
+ * (25/2/2002) ganesh
+ * 	Added support for the HP Jornada 548 and 568. Completely untested.
+ * 	Thanks to info from Heath Robinson and Arieh Davidoff.
  */
 
 #include <linux/config.h>
@@ -39,9 +60,9 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.1"
+#define DRIVER_VERSION "v0.2"
 #define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"
-#define DRIVER_DESC "USB Compaq iPAQ driver"
+#define DRIVER_DESC "USB Compaq iPAQ, HP Jornada, Casio EM500 driver"
 
 /* Function prototypes for an ipaq */
 static int  ipaq_open (struct usb_serial_port *port, struct file *filp);
@@ -52,7 +73,7 @@
 		       int count);
 static int ipaq_write_bulk(struct usb_serial_port *port, int from_user, const unsigned char *buf,
 			   int count);
-static int ipaq_write_flush(struct usb_serial_port *port);
+static void ipaq_write_gather(struct usb_serial_port *port);
 static void ipaq_read_bulk_callback (struct urb *urb);
 static void ipaq_write_bulk_callback(struct urb *urb);
 static int ipaq_write_room(struct usb_serial_port *port);
@@ -61,7 +82,10 @@
 
 
 static __devinitdata struct usb_device_id ipaq_id_table [] = {
-	{ USB_DEVICE(IPAQ_VENDOR_ID, IPAQ_PRODUCT_ID) },
+	{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) },
+	{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) },
+	{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) },
+	{ USB_DEVICE(CASIO_VENDOR_ID, CASIO_EM500_ID) },
 	{ }					/* Terminating entry */
 };
 
@@ -71,10 +95,10 @@
 struct usb_serial_device_type ipaq_device = {
 	name:			"Compaq iPAQ",
 	id_table:		ipaq_id_table,
-	needs_interrupt_in:	MUST_HAVE_NOT,
+	needs_interrupt_in:	DONT_CARE,
 	needs_bulk_in:		MUST_HAVE,
 	needs_bulk_out:		MUST_HAVE,
-	num_interrupt_in:	0,
+	num_interrupt_in:	NUM_DONT_CARE,
 	num_bulk_in:		1,
 	num_bulk_out:		1,
 	num_ports:		1,
@@ -149,6 +173,8 @@
 		 */
 
 		port->tty->low_latency = 1;
+		port->tty->raw = 1;
+		port->tty->real_raw = 1;
 
 		/*
 		 * Lose the small buffers usbserial provides. Make larger ones.
@@ -365,17 +391,23 @@
 	priv->queue_len += count;
 	if (priv->active == 0) {
 		priv->active = 1;
-		result = ipaq_write_flush(port);
+		ipaq_write_gather(port);
+		spin_unlock_irqrestore(&write_list_lock, flags);
+		result = usb_submit_urb(port->write_urb);
+		if (result) {
+			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+		}
+	} else {
+		spin_unlock_irqrestore(&write_list_lock, flags);
 	}
-	spin_unlock_irqrestore(&write_list_lock, flags);
 	return result;
 }
 
-static int ipaq_write_flush(struct usb_serial_port *port)
+static void ipaq_write_gather(struct usb_serial_port *port)
 {
 	struct ipaq_private	*priv = (struct ipaq_private *)port->private;
 	struct usb_serial	*serial = port->serial;
-	int			count, room, result;
+	int			count, room;
 	struct ipaq_packet	*pkt;
 	struct urb		*urb = port->write_urb;
 	struct list_head	*tmp;
@@ -383,7 +415,7 @@
 	if (urb->status == -EINPROGRESS) {
 		/* Should never happen */
 		err(__FUNCTION__ " - flushing while urb is active !");
-		return -EAGAIN;
+		return;
 	}
 	room = URBDATA_SIZE;
 	for (tmp = priv->queue.next; tmp != &priv->queue;) {
@@ -410,11 +442,7 @@
 		      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
 		      port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback,
 		      port);
-	result = usb_submit_urb(urb);
-	if (result) {
-		err(__FUNCTION__ " - failed submitting write urb, error %d", result);
-	}
-	return result;
+	return;
 }
 
 static void ipaq_write_bulk_callback(struct urb *urb)
@@ -422,6 +450,7 @@
 	struct usb_serial_port	*port = (struct usb_serial_port *)urb->context;
 	struct ipaq_private	*priv = (struct ipaq_private *)port->private;
 	unsigned long		flags;
+	int			result;
 
 	if (port_paranoia_check (port, __FUNCTION__)) {
 		return;
@@ -435,11 +464,16 @@
 
 	spin_lock_irqsave(&write_list_lock, flags);
 	if (!list_empty(&priv->queue)) {
-		ipaq_write_flush(port);
+		ipaq_write_gather(port);
+		spin_unlock_irqrestore(&write_list_lock, flags);
+		result = usb_submit_urb(port->write_urb);
+		if (result) {
+			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+		}
 	} else {
 		priv->active = 0;
+		spin_unlock_irqrestore(&write_list_lock, flags);
 	}
-	spin_unlock_irqrestore(&write_list_lock, flags);
 	queue_task(&port->tqueue, &tq_immediate);
 	mark_bh(IMMEDIATE_BH);
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/ipaq.h linux/drivers/usb/serial/ipaq.h
--- linux.orig/drivers/usb/serial/ipaq.h	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/serial/ipaq.h	2002-07-20 01:08:30.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * USB Compaq iPAQ driver
  *
- *	Copyright (C) 2001
+ *	Copyright (C) 2001 - 2002
  *	    Ganesh Varadarajan <ganesh@veritas.com>
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -16,8 +16,15 @@
 #define __LINUX_USB_SERIAL_IPAQ_H
 
 
-#define IPAQ_VENDOR_ID			0x049f
-#define IPAQ_PRODUCT_ID			0x0003
+#define COMPAQ_VENDOR_ID	0x049f
+#define COMPAQ_IPAQ_ID		0x0003
+
+#define HP_VENDOR_ID		0x003f
+#define HP_JORNADA_548_ID	0x1016
+#define HP_JORNADA_568_ID	0x1116
+
+#define CASIO_VENDOR_ID		0x07cf
+#define CASIO_EM500_ID		0x2002
 
 /*
  * Since we can't queue our bulk write urbs (don't know why - it just
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c
--- linux.orig/drivers/usb/serial/pl2303.c	2001-10-11 06:42:47.000000000 +0000
+++ linux/drivers/usb/serial/pl2303.c	2002-07-20 01:08:35.000000000 +0000
@@ -140,6 +140,7 @@
 
 struct pl2303_private { 
 	u8 line_control;
+	u8 termios_initialized;
 };
 
 
@@ -217,13 +218,19 @@
 	int baud;
 	int i;
 
-	dbg (__FUNCTION__ " -  port %d", port->number);
+	dbg (__FUNCTION__ " -  port %d, initialized = %d", port->number, 
+	     ((struct pl2303_private *) port->private)->termios_initialized);
 
 	if ((!port->tty) || (!port->tty->termios)) {
 		dbg(__FUNCTION__" - no tty structures");
 		return;
 	}
 
+	if (!(((struct pl2303_private *)port->private)->termios_initialized)) {
+		*(port->tty->termios) = tty_std_termios;
+		port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+		((struct pl2303_private *) port->private)->termios_initialized = 1;
+	}
 	cflag = port->tty->termios->c_cflag;
 	/* check that they really want us to change something */
 	if (old_termios) {
@@ -400,9 +407,6 @@
 		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 4);
 
 		/* Setup termios */
-		*(port->tty->termios) = tty_std_termios;
-		port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-
 		pl2303_set_termios (port, &tmp_termios);
 
 		//FIXME: need to assert RTS and DTR if CRTSCTS off
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
--- linux.orig/drivers/usb/serial/visor.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/serial/visor.c	2002-07-20 01:08:31.000000000 +0000
@@ -2,7 +2,7 @@
  * USB HandSpring Visor, Palm m50x, and Sony Clie driver
  * (supports all of the Palm OS USB devices)
  *
- *	Copyright (C) 1999 - 2001
+ *	Copyright (C) 1999 - 2002
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -11,7 +11,25 @@
  *	(at your option) any later version.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
- * 
+ *
+ * (04/03/2002) gkh
+ *	Added support for the Sony OS 4.1 devices.  Thanks to Hiroyuki ARAKI
+ *	<hiro@zob.ne.jp> for the information.
+ *
+ * (03/23/2002) gkh
+ *	Added support for the Palm i705 device, thanks to Thomas Riemer
+ *	<tom@netmech.com> for the information.
+ *
+ * (03/21/2002) gkh
+ *	Added support for the Palm m130 device, thanks to Udo Eisenbarth
+ *	<udo.eisenbarth@web.de> for the information.
+ *
+ * (02/21/2002) SilaS
+ *	Added support for the Palm m515 devices.
+ *
+ * (02/15/2002) gkh
+ *	Added support for the Clie S-360 device.
+ *
  * (12/18/2001) gkh
  *	Added better Clie support for 3.5 devices.  Thanks to Geoffrey Levand
  *	for the patch.
@@ -160,7 +178,10 @@
 static __devinitdata struct usb_device_id palm_4_0_id_table [] = {
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
 	{ }					/* Terminating entry */
 };
 
@@ -171,6 +192,8 @@
 
 static __devinitdata struct usb_device_id clie_id_4_0_table [] = {
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
+	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
+	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
 	{ }					/* Terminating entry */
 };
 
@@ -178,9 +201,14 @@
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
+	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
+	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
 	{ }					/* Terminating entry */
 };
 
@@ -268,7 +296,7 @@
 
 /* device info for the Sony Clie OS version 4.0 */
 static struct usb_serial_device_type clie_4_0_device = {
-	name:			"Sony Clié 4.0",
+	name:			"Sony Clié 4.x",
 	id_table:		clie_id_4_0_table,
 	needs_interrupt_in:	MUST_HAVE_NOT,		/* this device must not have an interrupt in endpoint */
 	needs_bulk_in:		MUST_HAVE,		/* this device must have a bulk in endpoint */
@@ -676,7 +704,8 @@
 	}
 
 	if ((serial->dev->descriptor.idVendor == PALM_VENDOR_ID) ||
-	    (serial->dev->descriptor.idVendor == SONY_VENDOR_ID)) {
+	    ((serial->dev->descriptor.idVendor == SONY_VENDOR_ID) &&
+	     (serial->dev->descriptor.idProduct != SONY_CLIE_4_1_ID))) {
 		/* Palm OS 4.0 Hack */
 		response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
 					    PALM_GET_SOME_UNKNOWN_INFORMATION,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/visor.h linux/drivers/usb/serial/visor.h
--- linux.orig/drivers/usb/serial/visor.h	2001-11-12 17:53:56.000000000 +0000
+++ linux/drivers/usb/serial/visor.h	2002-07-20 01:08:30.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * USB HandSpring Visor driver
  *
- *	Copyright (C) 1999 - 2001
+ *	Copyright (C) 1999 - 2002
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -23,11 +23,16 @@
 #define PALM_VENDOR_ID			0x0830
 #define PALM_M500_ID			0x0001
 #define PALM_M505_ID			0x0002
+#define PALM_M515_ID			0x0003
+#define PALM_I705_ID			0x0020
 #define PALM_M125_ID			0x0040
+#define PALM_M130_ID			0x0050
 
 #define SONY_VENDOR_ID			0x054C
 #define SONY_CLIE_3_5_ID		0x0038
 #define SONY_CLIE_4_0_ID		0x0066
+#define SONY_CLIE_S360_ID		0x0095
+#define SONY_CLIE_4_1_ID		0x009A
 
 /****************************************************************************
  * Handspring Visor Vendor specific request codes (bRequest values)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c
--- linux.orig/drivers/usb/serial/whiteheat.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/usb/serial/whiteheat.c	2002-07-20 01:08:32.000000000 +0000
@@ -88,7 +88,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.1"
+#define DRIVER_VERSION "v1.2"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
 
@@ -128,8 +128,9 @@
 static void whiteheat_set_termios	(struct usb_serial_port *port, struct termios * old);
 static void whiteheat_throttle		(struct usb_serial_port *port);
 static void whiteheat_unthrottle	(struct usb_serial_port *port);
-static int  whiteheat_startup		(struct usb_serial *serial);
-static void whiteheat_shutdown		(struct usb_serial *serial);
+static int  whiteheat_fake_startup	(struct usb_serial *serial);
+static int  whiteheat_real_startup	(struct usb_serial *serial);
+static void whiteheat_real_shutdown	(struct usb_serial *serial);
 
 static struct usb_serial_device_type whiteheat_fake_device = {
 	name:			"Connect Tech - WhiteHEAT - (prerenumeration)",
@@ -141,7 +142,7 @@
 	num_bulk_in:		NUM_DONT_CARE,
 	num_bulk_out:		NUM_DONT_CARE,
 	num_ports:		1,
-	startup:		whiteheat_startup	
+	startup:		whiteheat_fake_startup,
 };
 
 static struct usb_serial_device_type whiteheat_device = {
@@ -160,7 +161,8 @@
 	unthrottle:		whiteheat_unthrottle,
 	ioctl:			whiteheat_ioctl,
 	set_termios:		whiteheat_set_termios,
-	shutdown:		whiteheat_shutdown,
+	startup:		whiteheat_real_startup,
+	shutdown:		whiteheat_real_shutdown,
 };
 
 struct whiteheat_private {
@@ -539,7 +541,7 @@
  - device renumerated itself and comes up as new device id with all
    firmware download completed.
 */
-static int  whiteheat_startup (struct usb_serial *serial)
+static int  whiteheat_fake_startup (struct usb_serial *serial)
 {
 	int response;
 	const struct whiteheat_hex_record *record;
@@ -598,9 +600,68 @@
 }
 
 
-static void whiteheat_shutdown (struct usb_serial *serial)
+static int  whiteheat_real_startup (struct usb_serial *serial)
 {
-	struct usb_serial_port 		*command_port;
+	struct whiteheat_hw_info *hw_info;
+	int pipe;
+	int ret;
+	int alen;
+	__u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 };
+	__u8 result[sizeof(*hw_info) + 1];
+
+	pipe = usb_rcvbulkpipe (serial->dev, 7);
+	usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
+	/*
+	 * We ignore the return code. In the case where rmmod/insmod is
+	 * performed with a WhiteHEAT connected, the above times out
+	 * because the endpoint is already prepped, meaning the below succeeds
+	 * regardless. All other cases the above succeeds.
+	 */
+
+	pipe = usb_sndbulkpipe (serial->dev, 7);
+	ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, 2 * HZ);
+	if (ret) {
+		err("%s: Couldn't send command [%d]", serial->type->name, ret);
+		goto error_out;
+	} else if (alen != sizeof(command)) {
+		err("%s: Send command incomplete [%d]", serial->type->name, alen);
+		goto error_out;
+	}
+
+	pipe = usb_rcvbulkpipe (serial->dev, 7);
+	ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
+	if (ret) {
+		err("%s: Couldn't get results [%d]", serial->type->name, ret);
+		goto error_out;
+	} else if (alen != sizeof(result)) {
+		err("%s: Get results incomplete [%d]", serial->type->name, alen);
+		goto error_out;
+	} else if (result[0] != command[0]) {
+		err("%s: Command failed [%d]", serial->type->name, result[0]);
+		goto error_out;
+	}
+
+	hw_info = (struct whiteheat_hw_info *)&result[1];
+
+	info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,
+	     DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
+
+	return 0;
+
+error_out:
+	err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);
+	/*
+	 * Return that we've claimed the interface. A failure here may be
+	 * due to interception by the command_callback routine or other
+	 * causes that don't mean that the firmware isn't running. This may
+	 * change in the future. Probably should actually.
+	 */
+	return 0;
+}
+
+static void whiteheat_real_shutdown (struct usb_serial *serial)
+{
+	struct usb_serial_port *command_port;
 	int i;
 
 	dbg(__FUNCTION__);
@@ -623,8 +684,6 @@
 }
 
 
-
-
 static void set_command (struct usb_serial_port *port, unsigned char state, unsigned char command)
 {
 	struct whiteheat_rdb_set rdb_command;
@@ -660,7 +719,7 @@
 {
 	usb_serial_register (&whiteheat_fake_device);
 	usb_serial_register (&whiteheat_device);
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/serial/whiteheat_fw.h linux/drivers/usb/serial/whiteheat_fw.h
--- linux.orig/drivers/usb/serial/whiteheat_fw.h	2000-10-09 21:25:56.000000000 +0000
+++ linux/drivers/usb/serial/whiteheat_fw.h	2002-07-20 01:08:35.000000000 +0000
@@ -47,28 +47,28 @@
 };
 
 static const struct whiteheat_hex_record whiteheat_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x95, 0x09} },
+{ 0x0000,	3,	{0x02, 0x95, 0xe7} },
 { 0x0003,	3,	{0x02, 0x13, 0x12} },
-{ 0x000b,	3,	{0x02, 0x0a, 0x91} },
-{ 0x0033,	3,	{0x02, 0x08, 0x1b} },
+{ 0x000b,	3,	{0x02, 0x0b, 0xb5} },
+{ 0x0033,	3,	{0x02, 0x08, 0x18} },
 { 0x0043,	3,	{0x02, 0x0a, 0x00} },
-{ 0x005b,	3,	{0x02, 0x1a, 0xd2} },
+{ 0x005b,	3,	{0x02, 0x11, 0xdd} },
 { 0x0370,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x73, 0x14, 0x70, 0x03, 0x02, 0x04, 0xe7, 0x24} },
 { 0x0380,	16,	{0xfe, 0x70, 0x03, 0x02, 0x05, 0x4f, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x64, 0x14, 0x70, 0x03} },
 { 0x0390,	16,	{0x02, 0x04, 0x52, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x49, 0x24} },
 { 0x03a0,	16,	{0x05, 0x60, 0x03, 0x02, 0x05, 0x9e, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60} },
 { 0x03b0,	16,	{0x36, 0x24, 0x02, 0x70, 0x7b, 0x74, 0x12, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} },
-{ 0x03c0,	16,	{0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x81, 0xea, 0x49, 0x60, 0x0d} },
+{ 0x03c0,	16,	{0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x99, 0xea, 0x49, 0x60, 0x0d} },
 { 0x03d0,	16,	{0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} },
-{ 0x03e0,	16,	{0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x40, 0xea} },
-{ 0x03f0,	16,	{0x49, 0x60, 0x33, 0x12, 0x9f, 0x48, 0xf5, 0x4b, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4b, 0xd3} },
-{ 0x0400,	16,	{0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4b, 0x40} },
-{ 0x0410,	16,	{0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4b, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xb5} },
-{ 0x0420,	16,	{0xe5, 0x4b, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} },
+{ 0x03e0,	16,	{0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x58, 0xea} },
+{ 0x03f0,	16,	{0x49, 0x60, 0x33, 0x12, 0xa0, 0x3f, 0xf5, 0x4c, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4c, 0xd3} },
+{ 0x0400,	16,	{0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4c, 0x40} },
+{ 0x0410,	16,	{0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4c, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xb5} },
+{ 0x0420,	16,	{0xe5, 0x4c, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} },
 { 0x0430,	16,	{0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x21, 0xf0} },
 { 0x0440,	16,	{0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x21, 0x02} },
-{ 0x0450,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x31, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} },
-{ 0x0460,	16,	{0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x31, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} },
+{ 0x0450,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x32, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} },
+{ 0x0460,	16,	{0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x32, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} },
 { 0x0470,	16,	{0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02} },
 { 0x0480,	16,	{0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x05, 0xe4, 0x33, 0x4f, 0x90} },
 { 0x0490,	16,	{0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0xe4} },
@@ -79,8 +79,8 @@
 { 0x04e0,	16,	{0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24} },
 { 0x04f0,	16,	{0x02, 0x60, 0x03, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02} },
 { 0x0500,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0} },
-{ 0x0510,	16,	{0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4b, 0xef, 0x30, 0xe7, 0x03} },
-{ 0x0520,	16,	{0x43, 0x4b, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4b, 0xf0, 0xe5, 0x4b, 0x44, 0x20, 0xf0, 0xef, 0xf4} },
+{ 0x0510,	16,	{0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4c, 0xef, 0x30, 0xe7, 0x03} },
+{ 0x0520,	16,	{0x43, 0x4c, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4c, 0xf0, 0xe5, 0x4c, 0x44, 0x20, 0xf0, 0xef, 0xf4} },
 { 0x0530,	16,	{0x54, 0x80, 0xfd, 0xc4, 0x54, 0x0f, 0x2e, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} },
 { 0x0540,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90} },
 { 0x0550,	16,	{0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4} },
@@ -90,229 +90,226 @@
 { 0x0590,	16,	{0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f} },
 { 0x05a0,	12,	{0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
 { 0x05ac,	1,	{0x22} },
-{ 0x05ad,	16,	{0x75, 0x47, 0xff, 0x75, 0x46, 0xff, 0x75, 0x45, 0x0f, 0x75, 0x44, 0x00, 0xd2, 0x03, 0xc2, 0x06} },
+{ 0x05ad,	16,	{0x75, 0x48, 0xff, 0x75, 0x47, 0xff, 0x75, 0x46, 0x0f, 0x75, 0x45, 0x00, 0xd2, 0x03, 0xc2, 0x06} },
 { 0x05bd,	16,	{0xc2, 0x02, 0xc2, 0x00, 0xc2, 0x05, 0xc2, 0x01, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xe4, 0x90} },
 { 0x05cd,	16,	{0x01, 0xbc, 0xf0, 0xc2, 0x04, 0x90, 0x01, 0xc0, 0xf0, 0xa3, 0xf0, 0xc2, 0xaf, 0xc2, 0xa8, 0x12} },
-{ 0x05dd,	16,	{0x0b, 0x8d, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
+{ 0x05dd,	16,	{0x0c, 0x22, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
 { 0x05ed,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0x7e} },
-{ 0x05fd,	16,	{0x01, 0x7f, 0x00, 0x12, 0x10, 0x2c, 0x75, 0x49, 0x12, 0x75, 0x4a, 0x0a, 0x90, 0x01, 0x0b, 0xe0} },
-{ 0x060d,	16,	{0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
-{ 0x061d,	16,	{0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} },
-{ 0x062d,	16,	{0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} },
-{ 0x063d,	16,	{0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x064d,	16,	{0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} },
+{ 0x05fd,	16,	{0x01, 0x7f, 0x00, 0x12, 0x19, 0xc1, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0x0a, 0x90, 0x01, 0x0b, 0xe0} },
+{ 0x060d,	16,	{0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
+{ 0x061d,	16,	{0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} },
+{ 0x062d,	16,	{0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} },
+{ 0x063d,	16,	{0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x064d,	16,	{0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} },
 { 0x065d,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff, 0x74, 0x01, 0x93, 0x90} },
 { 0x066d,	16,	{0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff, 0xa3, 0xe0, 0xfe, 0xef} },
 { 0x067d,	16,	{0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0x6f} },
-{ 0x068d,	16,	{0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x4f, 0x10, 0x75, 0x50, 0x02, 0x75} },
-{ 0x069d,	16,	{0x51, 0x12, 0x75, 0x52, 0xac, 0x12, 0x91, 0x7a, 0x75, 0x49, 0x12, 0x75, 0x4a, 0xb2, 0x90, 0x01} },
-{ 0x06ad,	16,	{0x0d, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82} },
-{ 0x06bd,	16,	{0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} },
-{ 0x06cd,	16,	{0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} },
-{ 0x06dd,	16,	{0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} },
-{ 0x06ed,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4a, 0xe5, 0x4a, 0xae, 0x49, 0x70, 0x02, 0x05, 0x49} },
+{ 0x068d,	16,	{0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x50, 0x10, 0x75, 0x51, 0x02, 0x75} },
+{ 0x069d,	16,	{0x52, 0x12, 0x75, 0x53, 0xac, 0x12, 0x92, 0x2a, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0xb2, 0x90, 0x01} },
+{ 0x06ad,	16,	{0x0d, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82} },
+{ 0x06bd,	16,	{0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} },
+{ 0x06cd,	16,	{0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} },
+{ 0x06dd,	16,	{0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} },
+{ 0x06ed,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xae, 0x4a, 0x70, 0x02, 0x05, 0x4a} },
 { 0x06fd,	16,	{0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83, 0x01, 0xe0, 0xfc, 0xa3} },
-{ 0x070d,	16,	{0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa0, 0xfb, 0x7e, 0x01} },
-{ 0x071d,	16,	{0x7f, 0x18, 0x12, 0x85, 0x2f, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
-{ 0x072d,	16,	{0xa3, 0xe0, 0xff, 0x75, 0x4f, 0x0a, 0x75, 0x50, 0x06, 0x75, 0x51, 0x12, 0x75, 0x52, 0xb8, 0x12} },
-{ 0x073d,	16,	{0x91, 0x7a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} },
+{ 0x070d,	16,	{0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa1, 0xf2, 0x7e, 0x01} },
+{ 0x071d,	16,	{0x7f, 0x18, 0x12, 0x85, 0xcf, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
+{ 0x072d,	16,	{0xa3, 0xe0, 0xff, 0x75, 0x50, 0x0a, 0x75, 0x51, 0x06, 0x75, 0x52, 0x12, 0x75, 0x53, 0xb8, 0x12} },
+{ 0x073d,	16,	{0x92, 0x2a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} },
 { 0x074d,	16,	{0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x1f, 0xf0, 0xd2, 0xaf} },
-{ 0x075d,	16,	{0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xd0, 0x75, 0x43, 0x50} },
-{ 0x076d,	16,	{0x75, 0x42, 0x6d, 0x75, 0x41, 0x33, 0x75, 0x40, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} },
-{ 0x077d,	16,	{0x7d, 0xff, 0x7c, 0xff, 0x78, 0x40, 0x12, 0xa0, 0xe4, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} },
-{ 0x078d,	16,	{0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0d, 0x12, 0x09, 0xf5, 0x50} },
-{ 0x079d,	16,	{0x06, 0x12, 0x0b, 0x00, 0x12, 0x09, 0xfa, 0xc2, 0x06, 0x12, 0x93, 0x98, 0x90, 0x01, 0xbd, 0xe0} },
-{ 0x07ad,	16,	{0x60, 0x0c, 0x12, 0x8f, 0x55, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02} },
-{ 0x07bd,	16,	{0xaf, 0xe0, 0xb4, 0x0f, 0x03, 0x12, 0x96, 0xe2, 0x12, 0x9d, 0xa2, 0xe4, 0xff, 0x74, 0x01, 0xa8} },
-{ 0x07cd,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14} },
-{ 0x07dd,	16,	{0x74, 0x27, 0x2f, 0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00} },
-{ 0x07ed,	16,	{0x8e, 0x48, 0x80, 0x03, 0x75, 0x48, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5} },
-{ 0x07fd,	16,	{0x83, 0xe5, 0x48, 0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f} },
-{ 0x080d,	13,	{0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} },
-{ 0x081a,	1,	{0x22} },
-{ 0x081b,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x081f,	16,	{0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x7f, 0x0a, 0xfe, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0x74, 0x89} },
-{ 0x082f,	16,	{0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0x29, 0x90, 0x7f} },
-{ 0x083f,	16,	{0x96, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff} },
-{ 0x084f,	16,	{0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x02} },
-{ 0x085f,	16,	{0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} },
-{ 0x086f,	16,	{0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf} },
-{ 0x087f,	16,	{0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f} },
-{ 0x088f,	7,	{0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x22} },
-{ 0x0896,	16,	{0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} },
-{ 0x08a6,	16,	{0x09, 0x29, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29} },
-{ 0x08b6,	16,	{0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f} },
-{ 0x08c6,	16,	{0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} },
-{ 0x08d6,	16,	{0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01} },
-{ 0x08e6,	12,	{0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x12, 0x0b, 0x00, 0x22} },
-{ 0x08f2,	16,	{0x90, 0x95, 0xbe, 0xe4, 0x93, 0x70, 0x2f, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} },
-{ 0x0902,	16,	{0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x7f} },
-{ 0x0912,	16,	{0x9d, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12, 0xf0, 0x12, 0x08, 0x1f, 0x75, 0x82, 0xbe} },
-{ 0x0922,	7,	{0x75, 0x83, 0x95, 0x74, 0xff, 0xf0, 0x22} },
-{ 0x0929,	16,	{0x8e, 0x58, 0x8f, 0x59, 0xe5, 0x59, 0x15, 0x59, 0xae, 0x58, 0x70, 0x02, 0x15, 0x58, 0x4e, 0x60} },
-{ 0x0939,	7,	{0x05, 0x12, 0x0a, 0x58, 0x80, 0xee, 0x22} },
-{ 0x0940,	2,	{0x8f, 0x4c} },
-{ 0x0942,	16,	{0xe4, 0xf5, 0x4d, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x6a, 0xab, 0x4e, 0xaa, 0x4f} },
-{ 0x0952,	16,	{0xa9, 0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x03, 0x1d, 0xaf, 0x4d, 0x05, 0x4d, 0xef} },
-{ 0x0962,	16,	{0xb5, 0x4c, 0x01, 0x22, 0x12, 0x9f, 0x48, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x0972,	14,	{0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0980,	1,	{0x22} },
-{ 0x0981,	16,	{0xe4, 0xfe, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x12, 0xab, 0x4e, 0xaa, 0x4f, 0xa9} },
-{ 0x0991,	16,	{0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
-{ 0x09a1,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x9f, 0xba, 0x85, 0xf0, 0x4c, 0xf5, 0x4d, 0x62, 0x4c} },
-{ 0x09b1,	16,	{0xe5, 0x4c, 0x62, 0x4d, 0xe5, 0x4d, 0x62, 0x4c, 0x29, 0xfd, 0xe5, 0x4c, 0x3a, 0xa9, 0x05, 0x75} },
-{ 0x09c1,	14,	{0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x09cf,	1,	{0x22} },
-{ 0x09d0,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} },
-{ 0x09e0,	16,	{0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x09f0,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x09f5,	5,	{0x12, 0x08, 0x96, 0xd3, 0x22} },
-{ 0x09fa,	5,	{0x12, 0x08, 0x1f, 0xd3, 0x22} },
+{ 0x075d,	16,	{0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xc1, 0x75, 0x44, 0x50} },
+{ 0x076d,	16,	{0x75, 0x43, 0x6d, 0x75, 0x42, 0x33, 0x75, 0x41, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} },
+{ 0x077d,	16,	{0x7d, 0xff, 0x7c, 0xff, 0x78, 0x41, 0x12, 0xa1, 0xdb, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} },
+{ 0x078d,	16,	{0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0a, 0x12, 0x09, 0xf7, 0x50} },
+{ 0x079d,	16,	{0x03, 0x12, 0x0a, 0xe8, 0xc2, 0x06, 0x12, 0x94, 0x62, 0x90, 0x01, 0xbd, 0xe0, 0x60, 0x0c, 0x12} },
+{ 0x07ad,	16,	{0x90, 0x05, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02, 0xaf, 0xe0, 0xb4} },
+{ 0x07bd,	16,	{0x0f, 0x03, 0x12, 0x97, 0xbd, 0x12, 0x9e, 0x99, 0xe4, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80} },
+{ 0x07cd,	16,	{0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14, 0x74, 0x27, 0x2f} },
+{ 0x07dd,	16,	{0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0x8e, 0x49, 0x80} },
+{ 0x07ed,	16,	{0x03, 0x75, 0x49, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe5, 0x49} },
+{ 0x07fd,	16,	{0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f, 0x01, 0x80, 0x02} },
+{ 0x080d,	10,	{0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} },
+{ 0x0817,	1,	{0x22} },
+{ 0x0818,	4,	{0x53, 0xd8, 0xef, 0x32} },
+{ 0x081c,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x44, 0x30, 0xf0, 0x90, 0x7f} },
+{ 0x082c,	16,	{0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0} },
+{ 0x083c,	16,	{0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x08} },
+{ 0x084c,	16,	{0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfb, 0xf0, 0x7f} },
+{ 0x085c,	16,	{0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0x7d} },
+{ 0x086c,	16,	{0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44} },
+{ 0x087c,	16,	{0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96} },
+{ 0x088c,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54} },
+{ 0x089c,	16,	{0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0} },
+{ 0x08ac,	8,	{0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x22} },
+{ 0x08b4,	16,	{0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} },
+{ 0x08c4,	16,	{0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x82, 0xa8} },
+{ 0x08d4,	16,	{0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05} },
+{ 0x08e4,	16,	{0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00} },
+{ 0x08f4,	16,	{0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09} },
+{ 0x0904,	16,	{0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5} },
+{ 0x0914,	16,	{0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x54, 0xcf, 0xf0, 0x90, 0x7f, 0x95} },
+{ 0x0924,	8,	{0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x0b, 0x00, 0x22} },
+{ 0x092c,	16,	{0x90, 0x0a, 0xf0, 0xe4, 0x93, 0x70, 0x76, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} },
+{ 0x093c,	16,	{0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa} },
+{ 0x094c,	16,	{0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x08, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf} },
+{ 0x095c,	16,	{0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x20, 0x70, 0xe0, 0xff, 0xc4, 0x54, 0x0f} },
+{ 0x096c,	16,	{0xf5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x07, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x80, 0xf0, 0xe4, 0x90} },
+{ 0x097c,	16,	{0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0b} },
+{ 0x098c,	16,	{0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12} },
+{ 0x099c,	14,	{0xf0, 0x12, 0x08, 0x1c, 0x75, 0x82, 0xf0, 0x75, 0x83, 0x0a, 0x74, 0xff, 0xf0, 0x22} },
+{ 0x09aa,	16,	{0x8e, 0x5b, 0x8f, 0x5c, 0xe5, 0x5c, 0x15, 0x5c, 0xae, 0x5b, 0x70, 0x02, 0x15, 0x5b, 0x4e, 0x60} },
+{ 0x09ba,	7,	{0x05, 0x12, 0x09, 0xe6, 0x80, 0xee, 0x22} },
+{ 0x09c1,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} },
+{ 0x09d1,	16,	{0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
+{ 0x09e1,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
+{ 0x09e6,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
+{ 0x09f6,	1,	{0x22} },
+{ 0x09f7,	5,	{0x12, 0x08, 0xb4, 0xd3, 0x22} },
+{ 0x09fc,	1,	{0x32} },
+{ 0x09fd,	1,	{0x32} },
+{ 0x09fe,	1,	{0x32} },
 { 0x09ff,	1,	{0x32} },
-{ 0x0a00,	16,	{0x02, 0x0b, 0xaa, 0x00, 0x02, 0x0b, 0xdd, 0x00, 0x02, 0x0b, 0xc2, 0x00, 0x02, 0x0c, 0x1c, 0x00} },
-{ 0x0a10,	16,	{0x02, 0x0c, 0x06, 0x00, 0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xfe, 0x00, 0x02, 0x0a, 0xff, 0x00} },
-{ 0x0a20,	16,	{0x02, 0x0c, 0x37, 0x00, 0x02, 0x0d, 0x29, 0x00, 0x02, 0x0c, 0x73, 0x00, 0x02, 0x0d, 0x7d, 0x00} },
-{ 0x0a30,	16,	{0x02, 0x0c, 0xaf, 0x00, 0x02, 0x0d, 0xd1, 0x00, 0x02, 0x0c, 0xeb, 0x00, 0x02, 0x0e, 0x25, 0x00} },
-{ 0x0a40,	16,	{0x02, 0x0d, 0x27, 0x00, 0x02, 0x0e, 0x79, 0x00, 0x02, 0x0d, 0x28, 0x00, 0x02, 0x0e, 0x7a, 0x00} },
-{ 0x0a50,	8,	{0x02, 0x0e, 0x7b, 0x00, 0x02, 0x0e, 0x91, 0x00} },
-{ 0x0a58,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x0a68,	1,	{0x22} },
-{ 0x0a69,	16,	{0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} },
-{ 0x0a79,	16,	{0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} },
-{ 0x0a89,	7,	{0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} },
-{ 0x0a90,	1,	{0x22} },
-{ 0x0a91,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} },
-{ 0x0aa1,	1,	{0x07} },
-{ 0x0aa2,	16,	{0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} },
-{ 0x0ab2,	16,	{0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} },
-{ 0x0ac2,	16,	{0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} },
-{ 0x0ad2,	16,	{0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} },
-{ 0x0ae2,	13,	{0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} },
-{ 0x0aef,	15,	{0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0afe,	1,	{0x32} },
-{ 0x0aff,	1,	{0x32} },
+{ 0x0a00,	16,	{0x02, 0x0c, 0x4e, 0x00, 0x02, 0x0c, 0x81, 0x00, 0x02, 0x0c, 0x66, 0x00, 0x02, 0x0c, 0xc0, 0x00} },
+{ 0x0a10,	16,	{0x02, 0x0c, 0xaa, 0x00, 0x02, 0x09, 0xfc, 0x00, 0x02, 0x09, 0xfd, 0x00, 0x02, 0x09, 0xfe, 0x00} },
+{ 0x0a20,	16,	{0x02, 0x0c, 0xdb, 0x00, 0x02, 0x0d, 0xcb, 0x00, 0x02, 0x0d, 0x17, 0x00, 0x02, 0x0e, 0x1f, 0x00} },
+{ 0x0a30,	16,	{0x02, 0x0d, 0x53, 0x00, 0x02, 0x0e, 0x73, 0x00, 0x02, 0x0d, 0x8f, 0x00, 0x02, 0x0e, 0xc7, 0x00} },
+{ 0x0a40,	16,	{0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xee, 0x00, 0x02, 0x0a, 0xed, 0x00, 0x02, 0x0a, 0xef, 0x00} },
+{ 0x0a50,	8,	{0x02, 0x0f, 0x1b, 0x00, 0x02, 0x0f, 0x31, 0x00} },
+{ 0x0a58,	2,	{0x8f, 0x4d} },
+{ 0x0a5a,	16,	{0xe4, 0xf5, 0x4e, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x6a, 0xab, 0x4f, 0xaa, 0x50} },
+{ 0x0a6a,	16,	{0xa9, 0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x03, 0x1d, 0xaf, 0x4e, 0x05, 0x4e, 0xef} },
+{ 0x0a7a,	16,	{0xb5, 0x4d, 0x01, 0x22, 0x12, 0xa0, 0x3f, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
+{ 0x0a8a,	14,	{0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x0a98,	1,	{0x22} },
+{ 0x0a99,	16,	{0xe4, 0xfe, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x12, 0xab, 0x4f, 0xaa, 0x50, 0xa9} },
+{ 0x0aa9,	16,	{0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
+{ 0x0ab9,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0xa0, 0xb1, 0x85, 0xf0, 0x4d, 0xf5, 0x4e, 0x62, 0x4d} },
+{ 0x0ac9,	16,	{0xe5, 0x4d, 0x62, 0x4e, 0xe5, 0x4e, 0x62, 0x4d, 0x29, 0xfd, 0xe5, 0x4d, 0x3a, 0xa9, 0x05, 0x75} },
+{ 0x0ad9,	14,	{0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x0ae7,	1,	{0x22} },
+{ 0x0ae8,	5,	{0x12, 0x08, 0x1c, 0xd3, 0x22} },
+{ 0x0aed,	1,	{0x32} },
+{ 0x0aee,	1,	{0x32} },
+{ 0x0aef,	1,	{0x32} },
+{ 0x0af0,	3,	{0x00, 0x04, 0x00} },
 { 0x0b00,	9,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} },
 { 0x0b7d,	16,	{0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x0b8d,	16,	{0xd2, 0x00, 0x75, 0x8e, 0x10, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12, 0x08, 0xf2} },
-{ 0x0b9d,	13,	{0x12, 0x0e, 0xad, 0x12, 0x11, 0xe5, 0x12, 0x11, 0xc8, 0x12, 0x0a, 0x69, 0x22} },
-{ 0x0baa,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} },
-{ 0x0bba,	8,	{0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0bc2,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0bd2,	11,	{0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0bdd,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} },
-{ 0x0bed,	16,	{0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} },
-{ 0x0bfd,	9,	{0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c06,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} },
-{ 0x0c16,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c1c,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c2c,	11,	{0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c37,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c47,	16,	{0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x30, 0xe0, 0x13, 0xe5, 0x3b, 0x30, 0xe0, 0x07, 0x90, 0x20} },
-{ 0x0c57,	16,	{0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0c67,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c73,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c83,	16,	{0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x30, 0xe1, 0x13, 0xe5, 0x3b, 0x30, 0xe1, 0x07, 0x90, 0x20} },
-{ 0x0c93,	16,	{0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0ca3,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0caf,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0cbf,	16,	{0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x30, 0xe2, 0x13, 0xe5, 0x3b, 0x30, 0xe2, 0x07, 0x90, 0x20} },
-{ 0x0ccf,	16,	{0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0cdf,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0ceb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0cfb,	16,	{0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x30, 0xe3, 0x13, 0xe5, 0x3b, 0x30, 0xe3, 0x07, 0x90, 0x20} },
-{ 0x0d0b,	16,	{0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0d1b,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0d27,	1,	{0x32} },
-{ 0x0d28,	1,	{0x32} },
-{ 0x0d29,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0d39,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0d49,	16,	{0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} },
-{ 0x0d59,	16,	{0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0d69,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0d79,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0d7d,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0d8d,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0d9d,	16,	{0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} },
-{ 0x0dad,	16,	{0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0dbd,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0dcd,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0dd1,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0de1,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0df1,	16,	{0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} },
-{ 0x0e01,	16,	{0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0e11,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0e21,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e25,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0e35,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0e45,	16,	{0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} },
-{ 0x0e55,	16,	{0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0e65,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0e75,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e79,	1,	{0x32} },
-{ 0x0e7a,	1,	{0x32} },
-{ 0x0e7b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} },
-{ 0x0e8b,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e91,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} },
-{ 0x0ea1,	12,	{0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0ead,	16,	{0x90, 0x01, 0x20, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} },
-{ 0x0ebd,	16,	{0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} },
-{ 0x0ecd,	16,	{0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
-{ 0x0edd,	16,	{0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} },
-{ 0x0eed,	16,	{0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f} },
-{ 0x0efd,	16,	{0x1f, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0x17, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} },
-{ 0x0f0d,	16,	{0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
-{ 0x0f1d,	16,	{0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} },
-{ 0x0f2d,	16,	{0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} },
-{ 0x0f3d,	16,	{0xf5, 0x30, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0f4d,	16,	{0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
-{ 0x0f5d,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x83, 0xb7, 0x90, 0x01, 0x1e} },
-{ 0x0f6d,	16,	{0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3a, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0f7d,	16,	{0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x0f8d,	16,	{0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x36} },
-{ 0x0f9d,	16,	{0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x32, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} },
-{ 0x0fad,	16,	{0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0fbd,	16,	{0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4b, 0x60, 0x5e} },
-{ 0x0fcd,	4,	{0xe4, 0x90, 0x01, 0x1e} },
-{ 0x0fd1,	16,	{0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} },
-{ 0x0fe1,	16,	{0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4b, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} },
-{ 0x0ff1,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} },
-{ 0x1001,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} },
-{ 0x1011,	16,	{0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} },
-{ 0x1021,	11,	{0x83, 0x2d, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} },
-{ 0x102c,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x1030,	16,	{0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} },
-{ 0x1040,	16,	{0x4a, 0x70, 0x03, 0x02, 0x11, 0x74, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x11, 0x46, 0x90} },
-{ 0x1050,	16,	{0x10, 0x56, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x11, 0x24, 0x02, 0x10, 0xdc, 0x02, 0x10, 0xc5, 0x02} },
-{ 0x1060,	16,	{0x10, 0xab, 0x02, 0x10, 0x9a, 0x02, 0x10, 0x85, 0x02, 0x10, 0x6b, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x1070,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} },
-{ 0x1080,	16,	{0xf0, 0x19, 0x02, 0x11, 0x46, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} },
-{ 0x1090,	16,	{0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x11, 0x46, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
-{ 0x10a0,	16,	{0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x11, 0x46, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x10b0,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} },
-{ 0x10c0,	16,	{0xf0, 0x19, 0x02, 0x11, 0x46, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x10d0,	16,	{0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x54, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} },
-{ 0x10e0,	16,	{0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} },
-{ 0x10f0,	16,	{0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} },
-{ 0x1100,	16,	{0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
-{ 0x1110,	16,	{0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} },
-{ 0x1120,	16,	{0x9f, 0x8e, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} },
-{ 0x1130,	16,	{0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} },
-{ 0x1140,	16,	{0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x54, 0x30, 0xe0, 0xf7, 0x30} },
-{ 0x1150,	16,	{0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} },
-{ 0x1160,	16,	{0x10, 0x32, 0xe5, 0x54, 0x30, 0xe1, 0x03, 0x02, 0x10, 0x32, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} },
-{ 0x1170,	6,	{0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} },
-{ 0x1176,	1,	{0x22} },
-{ 0x1177,	2,	{0xae, 0x07} },
-{ 0x1179,	16,	{0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} },
-{ 0x1189,	16,	{0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} },
-{ 0x1199,	16,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} },
-{ 0x11a9,	16,	{0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} },
-{ 0x11b9,	14,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} },
-{ 0x11c7,	1,	{0x22} },
-{ 0x11c8,	16,	{0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x7f, 0x05} },
-{ 0x11d8,	13,	{0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x03, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x22} },
-{ 0x11e5,	16,	{0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} },
-{ 0x11f5,	10,	{0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0x0b8d,	16,	{0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} },
+{ 0x0b9d,	16,	{0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} },
+{ 0x0bad,	7,	{0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} },
+{ 0x0bb4,	1,	{0x22} },
+{ 0x0bb5,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} },
+{ 0x0bc5,	1,	{0x07} },
+{ 0x0bc6,	16,	{0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} },
+{ 0x0bd6,	16,	{0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} },
+{ 0x0be6,	16,	{0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} },
+{ 0x0bf6,	16,	{0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} },
+{ 0x0c06,	13,	{0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} },
+{ 0x0c13,	15,	{0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c22,	16,	{0xd2, 0x00, 0x75, 0x8e, 0x10, 0x12, 0x09, 0x2c, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x08, 0x90} },
+{ 0x0c32,	16,	{0x7f, 0x92, 0x74, 0x02, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12} },
+{ 0x0c42,	12,	{0x0f, 0x4d, 0x12, 0x92, 0xfb, 0x12, 0x1b, 0x0c, 0x12, 0x0b, 0x8d, 0x22} },
+{ 0x0c4e,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} },
+{ 0x0c5e,	8,	{0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c66,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0c76,	11,	{0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c81,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} },
+{ 0x0c91,	16,	{0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} },
+{ 0x0ca1,	9,	{0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0caa,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} },
+{ 0x0cba,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0cc0,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0cd0,	11,	{0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0cdb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0ceb,	16,	{0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x30, 0xe0, 0x13, 0xe5, 0x3c, 0x30, 0xe0, 0x07, 0x90, 0x20} },
+{ 0x0cfb,	16,	{0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d0b,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d17,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d27,	16,	{0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x30, 0xe1, 0x13, 0xe5, 0x3c, 0x30, 0xe1, 0x07, 0x90, 0x20} },
+{ 0x0d37,	16,	{0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d47,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d53,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d63,	16,	{0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x30, 0xe2, 0x13, 0xe5, 0x3c, 0x30, 0xe2, 0x07, 0x90, 0x20} },
+{ 0x0d73,	16,	{0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d83,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d8f,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d9f,	16,	{0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x30, 0xe3, 0x13, 0xe5, 0x3c, 0x30, 0xe3, 0x07, 0x90, 0x20} },
+{ 0x0daf,	16,	{0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0dbf,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0dcb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0ddb,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0deb,	16,	{0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} },
+{ 0x0dfb,	16,	{0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0e0b,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0e1b,	4,	{0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0e1f,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0e2f,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0e3f,	16,	{0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} },
+{ 0x0e4f,	16,	{0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0e5f,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0e6f,	4,	{0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0e73,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0e83,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0e93,	16,	{0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} },
+{ 0x0ea3,	16,	{0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0eb3,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0ec3,	4,	{0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0ec7,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0ed7,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0ee7,	16,	{0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} },
+{ 0x0ef7,	16,	{0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0f07,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0f17,	4,	{0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f1b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} },
+{ 0x0f2b,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f31,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} },
+{ 0x0f41,	12,	{0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f4d,	16,	{0x90, 0x01, 0x20, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} },
+{ 0x0f5d,	16,	{0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} },
+{ 0x0f6d,	16,	{0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
+{ 0x0f7d,	16,	{0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} },
+{ 0x0f8d,	16,	{0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0} },
+{ 0x0f9d,	16,	{0x16, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0xb7, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} },
+{ 0x0fad,	16,	{0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
+{ 0x0fbd,	16,	{0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} },
+{ 0x0fcd,	16,	{0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} },
+{ 0x0fdd,	16,	{0xf5, 0x31, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x0fed,	16,	{0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
+{ 0x0ffd,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x84, 0x08, 0x90, 0x01, 0x1e} },
+{ 0x100d,	16,	{0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3b, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x101d,	16,	{0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x102d,	16,	{0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x37} },
+{ 0x103d,	16,	{0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x33, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} },
+{ 0x104d,	16,	{0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x105d,	16,	{0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4c, 0x60, 0x5e} },
+{ 0x106d,	4,	{0xe4, 0x90, 0x01, 0x1e} },
+{ 0x1071,	16,	{0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} },
+{ 0x1081,	16,	{0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4c, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} },
+{ 0x1091,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} },
+{ 0x10a1,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} },
+{ 0x10b1,	16,	{0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} },
+{ 0x10c1,	11,	{0x83, 0x7e, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} },
+{ 0x10cc,	4,	{0x8e, 0x57, 0x8f, 0x58} },
+{ 0x10d0,	16,	{0x75, 0x59, 0x03, 0xe5, 0x58, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xfe} },
+{ 0x10e0,	16,	{0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x11, 0xda, 0xe5, 0x59, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} },
+{ 0x10f0,	16,	{0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x11, 0x7e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} },
+{ 0x1100,	16,	{0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} },
+{ 0x1110,	16,	{0x80, 0x6c, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} },
+{ 0x1120,	16,	{0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x59, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3} },
+{ 0x1130,	16,	{0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x58, 0x24, 0x06, 0xf5, 0x82} },
+{ 0x1140,	16,	{0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5} },
+{ 0x1150,	16,	{0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x58, 0x24} },
+{ 0x1160,	16,	{0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0xa0, 0x85, 0x85} },
+{ 0x1170,	16,	{0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x85, 0x90, 0x7f} },
+{ 0x1180,	16,	{0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} },
+{ 0x1190,	16,	{0x22, 0xe5, 0x5a, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} },
+{ 0x11a0,	16,	{0xe5, 0x59, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x11b0,	16,	{0x80, 0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} },
+{ 0x11c0,	16,	{0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} },
+{ 0x11d0,	12,	{0x59, 0x03, 0x02, 0x10, 0xd3, 0x15, 0x59, 0x02, 0x10, 0xd3, 0x7f, 0x08} },
+{ 0x11dc,	1,	{0x22} },
+{ 0x11dd,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} },
+{ 0x11ed,	15,	{0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x1200,	16,	{0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0x10, 0x07, 0x01, 0x80, 0x42, 0x00, 0x01, 0x02} },
 { 0x1210,	16,	{0x03, 0x01, 0x09, 0x02, 0x58, 0x00, 0x01, 0x01, 0x04, 0x80, 0x3c, 0x09, 0x04, 0x00, 0x00, 0x0a} },
 { 0x1220,	16,	{0xff, 0xff, 0xff, 0x05, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40} },
@@ -339,14 +336,14 @@
 { 0x1362,	16,	{0x75, 0x28, 0x14, 0x02, 0x15, 0x0d, 0xe5, 0x29, 0x70, 0x03, 0x75, 0x29, 0x14, 0x02, 0x16, 0x9e} },
 { 0x1372,	16,	{0xe5, 0x2a, 0x70, 0x03, 0x75, 0x2a, 0x14, 0x02, 0x18, 0x2f, 0x90, 0x20, 0x02, 0xe0, 0x54, 0x3f} },
 { 0x1382,	16,	{0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02, 0x13} },
-{ 0x1392,	16,	{0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x36, 0x02, 0x13, 0x43} },
+{ 0x1392,	16,	{0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13, 0x43} },
 { 0x13a2,	16,	{0x43, 0x82, 0x04, 0xe0, 0x43, 0x2c, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x05} },
-{ 0x13b2,	16,	{0xe0, 0x42, 0x32, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} },
-{ 0x13c2,	16,	{0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} },
+{ 0x13b2,	16,	{0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} },
+{ 0x13c2,	16,	{0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} },
 { 0x13d2,	16,	{0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x00, 0xf0, 0x90, 0x20} },
 { 0x13e2,	16,	{0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86} },
 { 0x13f2,	16,	{0x90, 0x7e, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f} },
-{ 0x1402,	16,	{0xe5, 0xe5, 0x3c, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1402,	16,	{0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x1412,	16,	{0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90} },
 { 0x1422,	16,	{0x7f, 0xb7, 0xed, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f, 0x40} },
 { 0x1432,	16,	{0x90, 0x7e, 0x80, 0x05, 0x86, 0x90, 0x20, 0x00, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d, 0x84} },
@@ -364,14 +361,14 @@
 { 0x14f2,	16,	{0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90, 0x20, 0x01} },
 { 0x1502,	16,	{0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20, 0x0a, 0xe0, 0x54} },
 { 0x1512,	16,	{0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02} },
-{ 0x1522,	16,	{0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13} },
+{ 0x1522,	16,	{0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x38, 0x02, 0x13} },
 { 0x1532,	16,	{0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2d, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82} },
-{ 0x1542,	16,	{0x05, 0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} },
-{ 0x1552,	16,	{0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} },
+{ 0x1542,	16,	{0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} },
+{ 0x1552,	16,	{0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} },
 { 0x1562,	16,	{0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x01, 0xf0, 0x90} },
 { 0x1572,	16,	{0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05} },
 { 0x1582,	16,	{0x86, 0x90, 0x7e, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90} },
-{ 0x1592,	16,	{0x7f, 0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1592,	16,	{0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x15a2,	16,	{0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} },
 { 0x15b2,	16,	{0x90, 0x7f, 0xb9, 0xed, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f} },
 { 0x15c2,	16,	{0x40, 0x90, 0x7e, 0x00, 0x05, 0x86, 0x90, 0x20, 0x08, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d} },
@@ -390,13 +387,13 @@
 { 0x1690,	16,	{0x90, 0x20, 0x09, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20} },
 { 0x16a0,	16,	{0x12, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14} },
 { 0x16b0,	16,	{0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x17, 0x87, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5} },
-{ 0x16c0,	16,	{0x38, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} },
-{ 0x16d0,	16,	{0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} },
-{ 0x16e0,	16,	{0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} },
+{ 0x16c0,	16,	{0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} },
+{ 0x16d0,	16,	{0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} },
+{ 0x16e0,	16,	{0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} },
 { 0x16f0,	16,	{0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74} },
 { 0x1700,	16,	{0x02, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90} },
 { 0x1710,	16,	{0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0} },
-{ 0x1720,	16,	{0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1720,	16,	{0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x1730,	16,	{0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58} },
 { 0x1740,	16,	{0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbb, 0xed, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfe, 0xf0, 0x02} },
 { 0x1750,	16,	{0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x80, 0x05, 0x86, 0x90, 0x20, 0x10, 0xe5, 0x84, 0xfe, 0x24} },
@@ -415,13 +412,13 @@
 { 0x1820,	16,	{0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x02, 0x13, 0x43, 0x90} },
 { 0x1830,	16,	{0x20, 0x1a, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5} },
 { 0x1840,	16,	{0x14, 0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x19, 0x18, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0} },
-{ 0x1850,	16,	{0xf5, 0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} },
-{ 0x1860,	16,	{0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} },
-{ 0x1870,	16,	{0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x53, 0x82} },
+{ 0x1850,	16,	{0xf5, 0x3a, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} },
+{ 0x1860,	16,	{0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x36, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} },
+{ 0x1870,	16,	{0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x53, 0x82} },
 { 0x1880,	16,	{0xf8, 0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50} },
 { 0x1890,	16,	{0x74, 0x03, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0} },
 { 0x18a0,	16,	{0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84} },
-{ 0x18b0,	16,	{0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} },
+{ 0x18b0,	16,	{0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x40, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} },
 { 0x18c0,	16,	{0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20} },
 { 0x18d0,	16,	{0x58, 0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbd, 0xed, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfe, 0xf0} },
 { 0x18e0,	16,	{0x02, 0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x00, 0x05, 0x86, 0x90, 0x20, 0x18, 0xe5, 0x84, 0xfe} },
@@ -439,63 +436,61 @@
 { 0x19a0,	16,	{0x80, 0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74} },
 { 0x19b0,	16,	{0x00, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x02, 0x13, 0x43} },
 { 0x19c0,	1,	{0x32} },
-{ 0x19c1,	4,	{0x8e, 0x54, 0x8f, 0x55} },
-{ 0x19c5,	16,	{0x75, 0x56, 0x03, 0xe5, 0x55, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe} },
-{ 0x19d5,	16,	{0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x1a, 0xcf, 0xe5, 0x56, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} },
-{ 0x19e5,	16,	{0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x1a, 0x73, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} },
-{ 0x19f5,	16,	{0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} },
-{ 0x1a05,	16,	{0x80, 0x6c, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} },
-{ 0x1a15,	16,	{0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x56, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} },
-{ 0x1a25,	16,	{0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x55, 0x24, 0x06, 0xf5, 0x82} },
-{ 0x1a35,	16,	{0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5} },
-{ 0x1a45,	16,	{0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x55, 0x24} },
-{ 0x1a55,	16,	{0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0x9f, 0x8e, 0x85} },
-{ 0x1a65,	16,	{0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0x8e, 0x90, 0x7f} },
-{ 0x1a75,	16,	{0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} },
-{ 0x1a85,	16,	{0x22, 0xe5, 0x57, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} },
-{ 0x1a95,	16,	{0xe5, 0x56, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x1aa5,	16,	{0x80, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} },
-{ 0x1ab5,	16,	{0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} },
-{ 0x1ac5,	12,	{0x56, 0x03, 0x02, 0x19, 0xc8, 0x15, 0x56, 0x02, 0x19, 0xc8, 0x7f, 0x08} },
-{ 0x1ad1,	1,	{0x22} },
-{ 0x1ad2,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} },
-{ 0x1ae2,	15,	{0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1af1,	4,	{0x8e, 0x54, 0x8f, 0x55} },
-{ 0x1af5,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x56, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x1b05,	16,	{0xe5, 0x56, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} },
-{ 0x1b15,	16,	{0x54, 0x03, 0x70, 0x24, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} },
-{ 0x1b25,	16,	{0x56, 0x7d, 0x02, 0x12, 0x83, 0x2d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe1} },
-{ 0x1b35,	10,	{0x07, 0xaf, 0x56, 0x7d, 0x04, 0x12, 0x83, 0x2d, 0x7f, 0x00} },
-{ 0x1b3f,	1,	{0x22} },
-{ 0x8000,	16,	{0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0xfd, 0x8b, 0x4d, 0x75} },
-{ 0x8010,	16,	{0x4e, 0x12, 0x75, 0x4f, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4b} },
-{ 0x8020,	16,	{0xf5, 0x4c, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} },
+{ 0x19c1,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x19c5,	16,	{0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} },
+{ 0x19d5,	16,	{0x4a, 0x70, 0x03, 0x02, 0x1b, 0x09, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x1a, 0xdb, 0x90} },
+{ 0x19e5,	16,	{0x19, 0xeb, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x1a, 0xb9, 0x02, 0x1a, 0x71, 0x02, 0x1a, 0x5a, 0x02} },
+{ 0x19f5,	16,	{0x1a, 0x40, 0x02, 0x1a, 0x2f, 0x02, 0x1a, 0x1a, 0x02, 0x1a, 0x00, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a05,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} },
+{ 0x1a15,	16,	{0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} },
+{ 0x1a25,	16,	{0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x1a, 0xdb, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
+{ 0x1a35,	16,	{0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a45,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} },
+{ 0x1a55,	16,	{0xf0, 0x19, 0x02, 0x1a, 0xdb, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a65,	16,	{0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x57, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} },
+{ 0x1a75,	16,	{0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} },
+{ 0x1a85,	16,	{0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} },
+{ 0x1a95,	16,	{0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
+{ 0x1aa5,	16,	{0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} },
+{ 0x1ab5,	16,	{0xa0, 0x85, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} },
+{ 0x1ac5,	16,	{0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} },
+{ 0x1ad5,	16,	{0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30} },
+{ 0x1ae5,	16,	{0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} },
+{ 0x1af5,	16,	{0x19, 0xc7, 0xe5, 0x57, 0x30, 0xe1, 0x03, 0x02, 0x19, 0xc7, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} },
+{ 0x1b05,	6,	{0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} },
+{ 0x1b0b,	1,	{0x22} },
+{ 0x1b0c,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x1c, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x02} },
+{ 0x1b1c,	16,	{0x7d, 0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x03, 0x7d, 0xff} },
+{ 0x1b2c,	4,	{0x12, 0x82, 0xa8, 0x22} },
+{ 0x8000,	16,	{0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0xfd, 0x8b, 0x4e, 0x75} },
+{ 0x8010,	16,	{0x4f, 0x12, 0x75, 0x50, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4c} },
+{ 0x8020,	16,	{0xf5, 0x4d, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} },
 { 0x8030,	16,	{0xa9, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0xe4, 0xfc, 0xec, 0x25, 0xe0, 0x24, 0xb4, 0xf5} },
 { 0x8040,	16,	{0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x0c, 0xbc, 0x10, 0xee, 0xe4, 0x90, 0x7f, 0xdd} },
-{ 0x8050,	16,	{0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4d, 0xaa, 0x4e, 0xa9, 0x4f} },
-{ 0x8060,	16,	{0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} },
-{ 0x8070,	16,	{0x12, 0x9f, 0x61, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61} },
+{ 0x8050,	16,	{0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4e, 0xaa, 0x4f, 0xa9, 0x50} },
+{ 0x8060,	16,	{0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} },
+{ 0x8070,	16,	{0x12, 0xa0, 0x58, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58} },
 { 0x8080,	16,	{0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x81, 0x16, 0xec, 0xc3, 0x94, 0x10} },
-{ 0x8090,	16,	{0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4c, 0xae, 0x4b, 0x78, 0x02, 0xce} },
+{ 0x8090,	16,	{0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4d, 0xae, 0x4c, 0x78, 0x02, 0xce} },
 { 0x80a0,	16,	{0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xf0, 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
 { 0x80b0,	16,	{0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe0, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01, 0xa8, 0x06} },
 { 0x80c0,	16,	{0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe0, 0xf0, 0x90, 0x02, 0xae, 0xe0} },
-{ 0x80d0,	16,	{0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4c, 0xae, 0x4b, 0x78} },
+{ 0x80d0,	16,	{0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4d, 0xae, 0x4c, 0x78} },
 { 0x80e0,	16,	{0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xe8, 0x2c, 0xf5, 0x82, 0xe4, 0x34} },
 { 0x80f0,	16,	{0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe1, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01} },
 { 0x8100,	16,	{0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x02} },
-{ 0x8110,	16,	{0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0x25} },
-{ 0x8120,	16,	{0x4c, 0xf5, 0x4c, 0xe4, 0x35, 0x4b, 0xf5, 0x4b, 0x90, 0x00, 0x05, 0x12, 0x9f, 0x61, 0xfe, 0xe4} },
-{ 0x8130,	16,	{0x25, 0x4c, 0xf5, 0x4c, 0xee, 0x35, 0x4b, 0xf5, 0x4b, 0x02, 0x81, 0xb8, 0xab, 0x4d, 0xaa, 0x4e} },
-{ 0x8140,	16,	{0xa9, 0x4f, 0x90, 0x00, 0x03, 0x12, 0x9f, 0x61, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} },
-{ 0x8150,	16,	{0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} },
+{ 0x8110,	16,	{0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0x25} },
+{ 0x8120,	16,	{0x4d, 0xf5, 0x4d, 0xe4, 0x35, 0x4c, 0xf5, 0x4c, 0x90, 0x00, 0x05, 0x12, 0xa0, 0x58, 0xfe, 0xe4} },
+{ 0x8130,	16,	{0x25, 0x4d, 0xf5, 0x4d, 0xee, 0x35, 0x4c, 0xf5, 0x4c, 0x02, 0x81, 0xb8, 0xab, 0x4e, 0xaa, 0x4f} },
+{ 0x8140,	16,	{0xa9, 0x50, 0x90, 0x00, 0x03, 0x12, 0xa0, 0x58, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} },
+{ 0x8150,	16,	{0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} },
 { 0x8160,	16,	{0x4e, 0xef, 0x30, 0xe7, 0x1e, 0x90, 0x7f, 0xde, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80} },
 { 0x8170,	16,	{0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x4e} },
 { 0x8180,	16,	{0xf0, 0x80, 0x35, 0x90, 0x7f, 0xdf, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80, 0x02, 0xc3} },
 { 0x8190,	16,	{0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xad, 0xe0, 0x4e, 0xf0, 0xec} },
 { 0x81a0,	16,	{0x25, 0xe0, 0x24, 0xc5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x09, 0x7f} },
-{ 0x81b0,	16,	{0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35} },
-{ 0x81c0,	16,	{0x4e, 0xf5, 0x4e, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} },
+{ 0x81b0,	16,	{0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x50, 0xf5, 0x50, 0xe4, 0x35} },
+{ 0x81c0,	16,	{0x4f, 0xf5, 0x4f, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} },
 { 0x81d0,	8,	{0x7f, 0xae, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x00} },
 { 0x81d8,	1,	{0x22} },
 { 0x81d9,	2,	{0xac, 0x07} },
@@ -513,549 +508,569 @@
 { 0x828b,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
 { 0x829b,	12,	{0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} },
 { 0x82a7,	1,	{0x22} },
-{ 0x82a8,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} },
-{ 0x82b8,	16,	{0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5e, 0x74, 0xbf} },
-{ 0x82c8,	16,	{0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
-{ 0x82d8,	16,	{0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} },
-{ 0x82e8,	16,	{0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} },
-{ 0x82f8,	16,	{0xef, 0x55, 0x3b, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
-{ 0x8308,	16,	{0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} },
-{ 0x8318,	16,	{0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5e, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} },
-{ 0x8328,	4,	{0x83, 0xa3, 0xe9, 0xf0} },
-{ 0x832c,	1,	{0x22} },
-{ 0x832d,	4,	{0x8f, 0x5e, 0x8d, 0x5f} },
-{ 0x8331,	16,	{0xe4, 0xf5, 0x60, 0x74, 0x3c, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
-{ 0x8341,	16,	{0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
-{ 0x8351,	16,	{0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x50} },
-{ 0x8361,	16,	{0x3c, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} },
-{ 0x8371,	16,	{0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} },
-{ 0x8381,	16,	{0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x40, 0x0c, 0x75, 0x60, 0x40, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76} },
-{ 0x8391,	16,	{0x10, 0x80, 0x0a, 0x75, 0x60, 0x80, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76, 0x38, 0xe5, 0x60, 0x45} },
-{ 0x83a1,	16,	{0x5f, 0x44, 0x01, 0xff, 0xe5, 0x5e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x83b1,	5,	{0x20, 0xf5, 0x83, 0xef, 0xf0} },
-{ 0x83b6,	1,	{0x22} },
-{ 0x83b7,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x83c7,	16,	{0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
-{ 0x83d7,	16,	{0x55, 0x8f, 0x56, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} },
-{ 0x83e7,	16,	{0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
-{ 0x83f7,	16,	{0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x54, 0xf8, 0xe4, 0xf6, 0xe5, 0x56, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x8407,	16,	{0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d} },
-{ 0x8417,	16,	{0xaf, 0x54, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xe0} },
-{ 0x8427,	16,	{0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83} },
-{ 0x8437,	16,	{0xe0, 0xe5, 0x56, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x54} },
-{ 0x8447,	16,	{0x7d, 0x06, 0x12, 0x83, 0x2d, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
-{ 0x8457,	16,	{0xe4, 0xf0, 0xe5, 0x54, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} },
-{ 0x8467,	16,	{0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xef} },
-{ 0x8477,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x54, 0x74, 0x01} },
-{ 0x8487,	13,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7f, 0x00} },
-{ 0x8494,	1,	{0x22} },
-{ 0x8495,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x84a5,	16,	{0xaf, 0x54, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
-{ 0x84b5,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x84c5,	16,	{0x20, 0xaf, 0x82, 0xf5, 0x56, 0x8f, 0x57, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
-{ 0x84d5,	16,	{0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0xe5} },
-{ 0x84e5,	16,	{0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x57} },
-{ 0x84f5,	16,	{0x82, 0x85, 0x56, 0x83, 0xe0, 0xf5, 0x55, 0xaf, 0x54, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
-{ 0x8505,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x30, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} },
-{ 0x8515,	16,	{0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} },
-{ 0x8525,	9,	{0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} },
-{ 0x852e,	1,	{0x22} },
-{ 0x852f,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} },
-{ 0x853f,	16,	{0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} },
-{ 0x854f,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} },
-{ 0x855f,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} },
-{ 0x856f,	16,	{0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} },
-{ 0x857f,	16,	{0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} },
-{ 0x858f,	16,	{0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} },
-{ 0x859f,	16,	{0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} },
-{ 0x85af,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} },
-{ 0x85bf,	3,	{0x83, 0xf0, 0x22} },
-{ 0x85c2,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x85c6,	16,	{0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} },
-{ 0x85d6,	16,	{0x22, 0x8c, 0x54, 0x8d, 0x55, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x85e6,	16,	{0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} },
-{ 0x85f6,	16,	{0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x55, 0xe5, 0x55, 0xaa, 0x54, 0x70, 0x02} },
-{ 0x8606,	16,	{0x05, 0x54, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x8616,	1,	{0x22} },
-{ 0x8617,	4,	{0x8e, 0x54, 0x8f, 0x55} },
-{ 0x861b,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5b, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x862b,	16,	{0xe5, 0x5b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
-{ 0x863b,	16,	{0x5c, 0x8f, 0x5d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
-{ 0x864b,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa0} },
-{ 0x865b,	16,	{0xc0, 0x40, 0x10, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x00} },
-{ 0x866b,	16,	{0x08, 0x80, 0x2e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
-{ 0x867b,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa0} },
-{ 0x868b,	16,	{0xc0, 0x50, 0x0e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x07, 0x08} },
-{ 0x869b,	16,	{0x00, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} },
-{ 0x86ab,	16,	{0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59} },
-{ 0x86bb,	16,	{0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0} },
-{ 0x86cb,	16,	{0x2e, 0xaf, 0x03, 0x8f, 0x5a, 0xaf, 0x59, 0xae, 0x58, 0xad, 0x57, 0xac, 0x56, 0x7b, 0x0a, 0x7a} },
-{ 0x86db,	16,	{0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59, 0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56} },
-{ 0x86eb,	16,	{0xe5, 0x5a, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x59, 0x24, 0x01, 0xf5, 0x59, 0xe4, 0x35, 0x58} },
-{ 0x86fb,	16,	{0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0xe4, 0x35, 0x56, 0xf5, 0x56, 0x85, 0x5d, 0x82, 0x85} },
-{ 0x870b,	16,	{0x5c, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} },
-{ 0x871b,	16,	{0x80, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xe5, 0x59, 0xf0, 0xaf, 0x59, 0xae, 0x58, 0xad} },
-{ 0x872b,	16,	{0x57, 0xac, 0x56, 0x78, 0x08, 0x12, 0xa0, 0xd1, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xef} },
-{ 0x873b,	16,	{0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} },
-{ 0x874b,	16,	{0x5a, 0xe5, 0x55, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} },
-{ 0x875b,	16,	{0x05, 0x43, 0x5a, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5a, 0x08, 0x80, 0x11, 0xef} },
-{ 0x876b,	16,	{0xb4, 0x74, 0x05, 0x43, 0x5a, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x877b,	16,	{0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} },
-{ 0x878b,	16,	{0x43, 0x5a, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5a, 0x40, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x879b,	16,	{0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
-{ 0x87ab,	16,	{0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5b, 0x74, 0x01} },
-{ 0x87bb,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0xe5, 0x5d, 0x24, 0x04, 0xf5} },
-{ 0x87cb,	16,	{0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5a, 0x80, 0x10, 0xaf} },
-{ 0x87db,	16,	{0x5b, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3b, 0x85} },
-{ 0x87eb,	16,	{0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} },
-{ 0x87fb,	16,	{0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5a, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x880b,	16,	{0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83} },
-{ 0x881b,	16,	{0xef, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
-{ 0x882b,	16,	{0x5d, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09} },
-{ 0x883b,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
-{ 0x884b,	16,	{0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5} },
-{ 0x885b,	16,	{0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0} },
-{ 0x886b,	16,	{0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} },
-{ 0x887b,	16,	{0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5b, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0x75, 0x5a, 0x08, 0xe5, 0x55} },
-{ 0x888b,	16,	{0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5a, 0x10, 0xe5} },
-{ 0x889b,	16,	{0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5a, 0xf0} },
-{ 0x88ab,	16,	{0xe5, 0x55, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} },
-{ 0x88bb,	16,	{0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x55, 0x24, 0x06, 0xf5} },
-{ 0x88cb,	16,	{0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} },
-{ 0x88db,	16,	{0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} },
-{ 0x88eb,	16,	{0xfb, 0x4f, 0xf5, 0x5a, 0xe5, 0x55, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0} },
-{ 0x88fb,	16,	{0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} },
-{ 0x890b,	16,	{0x70, 0x14, 0x43, 0x5a, 0x18, 0x80, 0x12, 0x43, 0x5a, 0x08, 0x80, 0x0d, 0x43, 0x5a, 0x38, 0x80} },
-{ 0x891b,	16,	{0x08, 0x43, 0x5a, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3} },
-{ 0x892b,	16,	{0xa3, 0xa3, 0xe5, 0x5a, 0xf0, 0xaf, 0x5b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0xaa, 0x54, 0xa9, 0x55} },
-{ 0x893b,	16,	{0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5b, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} },
-{ 0x894b,	15,	{0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f, 0x1f, 0x7f, 0x00} },
-{ 0x895a,	1,	{0x22} },
-{ 0x895b,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x896b,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} },
-{ 0x897b,	16,	{0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} },
-{ 0x898b,	16,	{0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} },
-{ 0x899b,	16,	{0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x89ab,	16,	{0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} },
-{ 0x89bb,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x54, 0x7f, 0x02, 0x12, 0x81, 0xd9} },
-{ 0x89cb,	16,	{0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xe5, 0x54, 0x5f, 0x90, 0x01, 0x32, 0xf0, 0x7e} },
-{ 0x89db,	10,	{0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12, 0x8e, 0xb4, 0x7f, 0x00} },
-{ 0x89e5,	1,	{0x22} },
-{ 0x89e6,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x89f6,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} },
-{ 0x8a06,	16,	{0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x8a16,	16,	{0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8e} },
-{ 0x8a26,	3,	{0xb4, 0x7f, 0x00} },
-{ 0x8a29,	1,	{0x22} },
-{ 0x8a2a,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8a2e,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8a3e,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8a4e,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
-{ 0x8a5e,	16,	{0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8a6e,	4,	{0xfd, 0xf0, 0x7f, 0x00} },
-{ 0x8a72,	1,	{0x22} },
-{ 0x8a73,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8a77,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8a87,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8a97,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
-{ 0x8aa7,	16,	{0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8ab7,	4,	{0xfe, 0xf0, 0x7f, 0x00} },
-{ 0x8abb,	1,	{0x22} },
-{ 0x8abc,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8ac0,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8ad0,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8ae0,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} },
-{ 0x8af0,	16,	{0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} },
-{ 0x8b00,	1,	{0x22} },
-{ 0x8b01,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} },
-{ 0x8b11,	16,	{0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3a, 0x7f, 0x00} },
-{ 0x8b21,	1,	{0x22} },
-{ 0x8b22,	4,	{0x8e, 0x54, 0x8f, 0x55} },
-{ 0x8b26,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x59, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x56, 0xc3} },
-{ 0x8b36,	16,	{0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} },
-{ 0x8b46,	16,	{0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x57, 0x7e, 0x75, 0x58} },
-{ 0x8b56,	16,	{0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x57, 0x7e, 0x75, 0x58, 0x00, 0x80, 0x16, 0x7e} },
-{ 0x8b66,	16,	{0x7d, 0x7f, 0x80, 0x75, 0x57, 0x7d, 0x75, 0x58, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} },
-{ 0x8b76,	16,	{0x57, 0x7d, 0x75, 0x58, 0x00, 0xe5, 0x59, 0x70, 0x1b, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0x74} },
-{ 0x8b86,	16,	{0xff, 0xf0, 0xe5, 0x56, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} },
-{ 0x8b96,	16,	{0x01, 0xf0, 0x80, 0x48, 0xe5, 0x55, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x54, 0xfe, 0xe5, 0x59, 0x60} },
-{ 0x8ba6,	16,	{0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} },
-{ 0x8bb6,	16,	{0x58, 0xe5, 0x58, 0xaa, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} },
-{ 0x8bc6,	16,	{0x15, 0x59, 0x80, 0xd9, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x56, 0x25} },
-{ 0x8bd6,	14,	{0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} },
-{ 0x8be4,	1,	{0x22} },
-{ 0x8be5,	16,	{0xef, 0x24, 0x05, 0xf5, 0x55, 0xe4, 0x3e, 0xf5, 0x54, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} },
-{ 0x8bf5,	16,	{0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} },
-{ 0x8c05,	16,	{0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x56, 0xf5, 0x57, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8c15,	16,	{0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8c, 0xc6} },
-{ 0x8c25,	16,	{0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0x12, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe} },
-{ 0x8c35,	16,	{0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x59, 0x74, 0x01, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59} },
-{ 0x8c45,	16,	{0x94, 0x40, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5} },
-{ 0x8c55,	16,	{0x57, 0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x50, 0x03, 0x02, 0x8d, 0x15, 0xae, 0x58, 0xaf, 0x59} },
-{ 0x8c65,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} },
-{ 0x8c75,	16,	{0x56, 0xf5, 0x57, 0x02, 0x8d, 0x15, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} },
-{ 0x8c85,	16,	{0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59, 0x94} },
-{ 0x8c95,	16,	{0x10, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x10, 0xd3, 0xe5, 0x57} },
-{ 0x8ca5,	16,	{0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x40, 0x68, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85} },
-{ 0x8cb5,	16,	{0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x80} },
-{ 0x8cc5,	16,	{0x4f, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} },
-{ 0x8cd5,	16,	{0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0x45, 0x59, 0x60, 0x0b, 0xd3, 0xe5, 0x59, 0x94, 0x40, 0xe5} },
-{ 0x8ce5,	16,	{0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5, 0x57, 0x95, 0x59} },
-{ 0x8cf5,	16,	{0xe5, 0x56, 0x95, 0x58, 0x40, 0x17, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8d05,	16,	{0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x7f, 0x01, 0x22} },
-{ 0x8d15,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8d, 0xd5, 0x24, 0xf9} },
-{ 0x8d25,	16,	{0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0x25, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8e, 0x69} },
-{ 0x8d35,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} },
-{ 0x8d45,	16,	{0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57} },
-{ 0x8d55,	16,	{0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xe0} },
-{ 0x8d65,	16,	{0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f} },
-{ 0x8d75,	16,	{0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8d85,	16,	{0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8e} },
-{ 0x8d95,	16,	{0x69, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x76} },
-{ 0x8da5,	16,	{0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02} },
-{ 0x8db5,	16,	{0x8e, 0x69, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
-{ 0x8dc5,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} },
-{ 0x8dd5,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} },
-{ 0x8de5,	16,	{0x94, 0x00, 0x50, 0x03, 0x02, 0x8e, 0x69, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} },
-{ 0x8df5,	16,	{0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e} },
-{ 0x8e05,	16,	{0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
-{ 0x8e15,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} },
-{ 0x8e25,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} },
-{ 0x8e35,	16,	{0xa3, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x60, 0x24} },
-{ 0x8e45,	16,	{0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} },
-{ 0x8e55,	16,	{0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
-{ 0x8e65,	16,	{0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3} },
-{ 0x8e75,	11,	{0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8e, 0xb4, 0x7f, 0x00} },
-{ 0x8e80,	1,	{0x22} },
-{ 0x8e81,	16,	{0x8e, 0x5f, 0x8f, 0x60, 0x8c, 0x61, 0x8d, 0x62, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x60} },
-{ 0x8e91,	16,	{0xe5, 0x60, 0xae, 0x5f, 0x70, 0x02, 0x05, 0x5f, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} },
-{ 0x8ea1,	16,	{0x62, 0xe5, 0x62, 0xac, 0x61, 0x70, 0x02, 0x05, 0x61, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x8eb1,	3,	{0x80, 0xd6, 0x22} },
-{ 0x8eb4,	6,	{0x8d, 0x5a, 0xab, 0x07, 0xaa, 0x06} },
-{ 0x8eba,	16,	{0x75, 0x5e, 0x40, 0x75, 0x5d, 0x0d, 0x75, 0x5c, 0x03, 0x75, 0x5b, 0x00, 0x90, 0x7f, 0xc2, 0xe0} },
-{ 0x8eca,	16,	{0x20, 0xe1, 0xf9, 0xaf, 0x5e, 0xae, 0x5d, 0xad, 0x5c, 0xac, 0x5b, 0xec, 0x4d, 0x4e, 0x4f, 0x70} },
-{ 0x8eda,	16,	{0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} },
-{ 0x8eea,	16,	{0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5a, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xc3} },
-{ 0x8efa,	8,	{0xe5, 0x5a, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x8f02,	1,	{0x22} },
-{ 0x8f03,	16,	{0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0x90, 0x20, 0x70, 0xe0, 0x54, 0xf0, 0xff, 0xc4, 0x54, 0x0f} },
-{ 0x8f13,	16,	{0x90, 0x01, 0x85, 0xf0, 0x90, 0x95, 0xbf, 0xe4, 0x93, 0x90, 0x01, 0x86, 0xf0, 0x90, 0x95, 0xc0} },
-{ 0x8f23,	16,	{0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
-{ 0x8f33,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e} },
-{ 0x8f43,	16,	{0x01, 0x7f, 0x7c, 0x12, 0x10, 0x2c, 0x7e, 0x01, 0x7f, 0x84, 0x7d, 0x14, 0x12, 0x8e, 0xb4, 0x7f} },
-{ 0x8f53,	1,	{0x00} },
-{ 0x8f54,	1,	{0x22} },
-{ 0x8f55,	16,	{0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4b, 0x7b, 0x75, 0x4c, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} },
-{ 0x8f65,	16,	{0x4b, 0x4e, 0x85, 0x4c, 0x4f, 0xe5, 0x4f, 0x24, 0x01, 0xf5, 0x53, 0xe4, 0x35, 0x4e, 0xf5, 0x52} },
-{ 0x8f75,	16,	{0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} },
-{ 0x8f85,	16,	{0x5b, 0x90, 0x8f, 0x8d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xb1, 0x02, 0x8f} },
-{ 0x8f95,	16,	{0xbb, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xd9, 0x02, 0x8f, 0xb1} },
-{ 0x8fa5,	16,	{0x02, 0x8f, 0xcf, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xe1, 0x02, 0x8f, 0xb1, 0xef, 0x64, 0x02, 0x60} },
-{ 0x8fb5,	16,	{0x2b, 0x75, 0x4d, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4d, 0xff, 0x80, 0x1c} },
-{ 0x8fc5,	16,	{0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4d, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} },
-{ 0x8fd5,	16,	{0x4d, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x60, 0x15} },
-{ 0x8fe5,	16,	{0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} },
-{ 0x8ff5,	16,	{0x8e, 0xb4, 0xaf, 0x4d, 0x22, 0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0x14} },
-{ 0x9005,	16,	{0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0x23, 0x90, 0x90, 0x14, 0xf8, 0x28, 0x28, 0x73, 0x02} },
-{ 0x9015,	16,	{0x90, 0x41, 0x02, 0x90, 0x4d, 0x02, 0x90, 0x59, 0x02, 0x90, 0xa7, 0x02, 0x90, 0xb2, 0x02, 0x90} },
-{ 0x9025,	16,	{0xbd, 0x02, 0x90, 0xc8, 0x02, 0x90, 0xd3, 0x02, 0x90, 0xde, 0x02, 0x90, 0xe9, 0x02, 0x90, 0xf4} },
-{ 0x9035,	16,	{0x02, 0x90, 0xfb, 0x02, 0x91, 0x23, 0x02, 0x91, 0x06, 0x02, 0x91, 0x11, 0xaf, 0x53, 0xae, 0x52} },
-{ 0x9045,	16,	{0x12, 0x83, 0xb7, 0x8f, 0x4d, 0x02, 0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x84, 0x95, 0x8f} },
-{ 0x9055,	16,	{0x4d, 0x02, 0x91, 0x26, 0x85, 0x52, 0x50, 0x85, 0x53, 0x51, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4} },
-{ 0x9065,	16,	{0x35, 0x50, 0xfe, 0x12, 0x85, 0x2f, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x85, 0xc2, 0x8f, 0x4d, 0xef} },
-{ 0x9075,	16,	{0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0x26, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x86, 0x17, 0x8f, 0x4d} },
-{ 0x9085,	16,	{0xe5, 0x4d, 0x70, 0x03, 0x02, 0x91, 0x26, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0x75, 0xf0} },
-{ 0x9095,	16,	{0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0x17, 0x02} },
-{ 0x90a5,	16,	{0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0x2a, 0x8f, 0x4d, 0x80, 0x74, 0xaf, 0x53, 0xae} },
-{ 0x90b5,	16,	{0x52, 0x12, 0x8a, 0x73, 0x8f, 0x4d, 0x80, 0x69, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0xbc, 0x8f} },
-{ 0x90c5,	16,	{0x4d, 0x80, 0x5e, 0xaf, 0x4c, 0xae, 0x4b, 0x12, 0x8b, 0xe5, 0x8f, 0x4d, 0x80, 0x53, 0xaf, 0x53} },
-{ 0x90d5,	16,	{0xae, 0x52, 0x12, 0x89, 0x5b, 0x8f, 0x4d, 0x80, 0x48, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x1a, 0xf1} },
-{ 0x90e5,	16,	{0x8f, 0x4d, 0x80, 0x3d, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x89, 0xe6, 0x8f, 0x4d, 0x80, 0x32, 0x12} },
-{ 0x90f5,	16,	{0x8f, 0x03, 0x8f, 0x4d, 0x80, 0x2b, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x01, 0x8f, 0x4d, 0x80} },
-{ 0x9105,	16,	{0x20, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x22, 0x8f, 0x4d, 0x80, 0x15, 0xaf, 0x4c, 0xae, 0x4b} },
-{ 0x9115,	16,	{0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8e, 0x81, 0xe4, 0xf5, 0x4d, 0x80, 0x03, 0x75, 0x4d} },
-{ 0x9125,	16,	{0xff, 0xe5, 0x4d, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e} },
-{ 0x9135,	16,	{0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8e, 0xb4, 0xaf} },
-{ 0x9145,	16,	{0x4d, 0x22, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} },
-{ 0x9155,	16,	{0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85} },
-{ 0x9165,	16,	{0x52, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8e, 0xb4} },
-{ 0x9175,	4,	{0x8f, 0x4d, 0xaf, 0x4d} },
-{ 0x9179,	1,	{0x22} },
-{ 0x917a,	8,	{0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b} },
-{ 0x9182,	16,	{0x75, 0x55, 0x01, 0x75, 0x56, 0x9c, 0xe4, 0xf5, 0x54, 0xaf, 0x50, 0x15, 0x50, 0xef, 0x70, 0x03} },
-{ 0x9192,	16,	{0x02, 0x92, 0x18, 0xaf, 0x4f, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4e} },
-{ 0x91a2,	16,	{0xae, 0x4d, 0xad, 0x4c, 0xac, 0x4b, 0x12, 0xa0, 0x2e, 0xaf, 0x03, 0x8f, 0x53, 0xaf, 0x4e, 0xae} },
-{ 0x91b2,	16,	{0x4d, 0xad, 0x4c, 0xac, 0x4b, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x4f, 0xe4} },
-{ 0x91c2,	16,	{0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} },
-{ 0x91d2,	16,	{0x12, 0xa0, 0x2e, 0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b, 0xe5, 0x53, 0x24, 0x30, 0xf5} },
-{ 0x91e2,	16,	{0x53, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x53, 0xf5, 0x53, 0x05, 0x56, 0xe5, 0x56} },
-{ 0x91f2,	16,	{0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x56, 0xe5} },
-{ 0x9202,	16,	{0x56, 0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x53, 0xf0, 0x05} },
-{ 0x9212,	16,	{0x54, 0x05, 0x54, 0x02, 0x91, 0x8b, 0xe5, 0x56, 0x15, 0x56, 0x70, 0x02, 0x15, 0x55, 0xaf, 0x54} },
-{ 0x9222,	16,	{0x15, 0x54, 0xef, 0x60, 0x23, 0xe5, 0x56, 0x15, 0x56, 0xae, 0x55, 0x70, 0x02, 0x15, 0x55, 0xf5} },
-{ 0x9232,	16,	{0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x52, 0xe5, 0x52, 0xac, 0x51, 0x70, 0x02, 0x05, 0x51, 0x14} },
-{ 0x9242,	8,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} },
-{ 0x924a,	1,	{0x22} },
-{ 0x924b,	16,	{0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} },
-{ 0x925b,	16,	{0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} },
-{ 0x926b,	16,	{0xe4, 0xef, 0x55, 0x30, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} },
-{ 0x927b,	16,	{0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
-{ 0x928b,	16,	{0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} },
-{ 0x929b,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
-{ 0x92ab,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x92bb,	1,	{0x22} },
-{ 0x92bc,	16,	{0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} },
-{ 0x92cc,	16,	{0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} },
-{ 0x92dc,	16,	{0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} },
-{ 0x92ec,	16,	{0x9f, 0x1f, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} },
-{ 0x92fc,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
-{ 0x930c,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x931c,	1,	{0x22} },
-{ 0x931d,	16,	{0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x50, 0x7b, 0x75, 0x51} },
-{ 0x932d,	16,	{0x80, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x50, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x52, 0xf5} },
-{ 0x933d,	16,	{0x53, 0x89, 0x54, 0xfe, 0x12, 0x92, 0xbc, 0xef, 0x60, 0x50, 0xab, 0x52, 0xaa, 0x53, 0xa9, 0x54} },
-{ 0x934d,	16,	{0x12, 0x9f, 0x48, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x02, 0x16, 0xc2, 0xaf} },
-{ 0x935d,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} },
-{ 0x936d,	16,	{0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} },
-{ 0x937d,	16,	{0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x30, 0x60, 0x0f, 0x85, 0x51, 0x82, 0x85, 0x50} },
-{ 0x938d,	10,	{0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} },
-{ 0x9397,	1,	{0x22} },
-{ 0x9398,	16,	{0x12, 0x93, 0x1d, 0xe4, 0xf5, 0x4b, 0x74, 0x36, 0x25, 0x4b, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4c} },
-{ 0x93a8,	16,	{0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4c, 0xff, 0xc4} },
-{ 0x93b8,	16,	{0x54, 0x0f, 0xf5, 0x4d, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} },
-{ 0x93c8,	16,	{0x83, 0xe5, 0x4c, 0xf0, 0xaf, 0x4b, 0x7d, 0x01, 0xe5, 0x4c, 0x45, 0x4d, 0xfb, 0x12, 0x92, 0x4b} },
-{ 0x93d8,	16,	{0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40} },
-{ 0x93e8,	16,	{0xb5, 0x12, 0x93, 0x1d, 0xe5, 0x3a, 0x60, 0x48, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} },
-{ 0x93f8,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x55, 0x3a, 0x60, 0x29, 0xe5, 0x4b} },
-{ 0x9408,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
-{ 0x9418,	16,	{0x16, 0xaf, 0x4b, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d} },
-{ 0x9428,	16,	{0x80, 0xef, 0xe5, 0x4c, 0xf4, 0x52, 0x3a, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xbb} },
-{ 0x9438,	16,	{0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0x05, 0x74, 0x19, 0xf0, 0x7f, 0x02, 0x12, 0x81} },
-{ 0x9448,	16,	{0xd9, 0x8e, 0x4e, 0x8f, 0x4f, 0xc3, 0xe5, 0x4e, 0x64, 0x80, 0x94, 0x80, 0x40, 0xee, 0x90, 0x01} },
-{ 0x9458,	16,	{0xbc, 0xe0, 0x65, 0x4f, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8, 0x07} },
-{ 0x9468,	16,	{0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xbc, 0xe0, 0x55, 0x4c, 0x60} },
-{ 0x9478,	16,	{0x14, 0xaf, 0x4b, 0x7d, 0x08, 0xe5, 0x4c, 0x55, 0x4f, 0xfb, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05} },
-{ 0x9488,	16,	{0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xcc, 0x90, 0x01} },
-{ 0x9498,	16,	{0xbc, 0xe5, 0x4f, 0xf0, 0xe4, 0xf5, 0x4b, 0xc2, 0xaf, 0x74, 0x32, 0x25, 0x4b, 0xf8, 0xe6, 0xf5} },
-{ 0x94a8,	16,	{0x4c, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4c, 0x1e, 0xe5, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x02} },
-{ 0x94b8,	16,	{0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0x2c, 0x25} },
-{ 0x94c8,	16,	{0x4b, 0xf8, 0xe6, 0xf5, 0x4c, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
-{ 0x94d8,	16,	{0xe0, 0x65, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x04, 0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70} },
-{ 0x94e8,	16,	{0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5} },
-{ 0x94f8,	16,	{0x83, 0xe5, 0x4c, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0x9a, 0x12, 0x93, 0x1d} },
-{ 0x9508,	1,	{0x22} },
-{ 0x9509,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x62, 0x02, 0x95, 0x50} },
-{ 0x9515,	16,	{0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x9525,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x9535,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x9545,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x95, 0x95, 0xe4, 0x7e} },
-{ 0x9555,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x9565,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x9575,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x9585,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x9595,	16,	{0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} },
-{ 0x95a5,	16,	{0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} },
-{ 0x95b5,	8,	{0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} },
-{ 0x95bd,	1,	{0x00} },
-{ 0x95be,	3,	{0x00, 0x03, 0x1d} },
-{ 0x95c1,	8,	{0x8b, 0x54, 0x8a, 0x55, 0x89, 0x56, 0x8d, 0x57} },
-{ 0x95c9,	16,	{0xe4, 0xf5, 0x58, 0xf5, 0x59, 0xaf, 0x57, 0x15, 0x57, 0xef, 0x60, 0x36, 0xab, 0x54, 0x05, 0x56} },
-{ 0x95d9,	16,	{0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf9, 0x12, 0x9f, 0x48, 0xff, 0xe5, 0x58} },
-{ 0x95e9,	16,	{0xe5, 0x59, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0xa2, 0x2f, 0xf5, 0x82, 0xee, 0x34} },
-{ 0x95f9,	16,	{0x9b, 0xf5, 0x83, 0xe5, 0x58, 0xff, 0xe4, 0x93, 0xf5, 0x58, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x59} },
-{ 0x9609,	6,	{0x80, 0xc3, 0xae, 0x58, 0xaf, 0x59} },
-{ 0x960f,	1,	{0x22} },
-{ 0x9610,	11,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} },
-{ 0x961b,	16,	{0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} },
-{ 0x962b,	16,	{0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} },
-{ 0x963b,	16,	{0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} },
-{ 0x964b,	10,	{0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} },
-{ 0x9655,	9,	{0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x965e,	2,	{0xa9, 0x03} },
-{ 0x9660,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} },
-{ 0x9670,	16,	{0x57, 0x45, 0x58, 0xf5, 0x59, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x9680,	16,	{0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} },
-{ 0x9690,	16,	{0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x59, 0xeb} },
-{ 0x96a0,	16,	{0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x59, 0xfc, 0xb5, 0x06, 0x03, 0xaf} },
-{ 0x96b0,	16,	{0x05, 0x22, 0xe5, 0x57, 0x5c, 0xfe, 0xe5, 0x58, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} },
-{ 0x96c0,	16,	{0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
-{ 0x96d0,	16,	{0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x57, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x58, 0x22, 0x7f} },
-{ 0x96e0,	1,	{0x00} },
-{ 0x96e1,	1,	{0x22} },
-{ 0x96e2,	16,	{0x75, 0x50, 0x02, 0x75, 0x51, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x51, 0x82, 0x85} },
-{ 0x96f2,	16,	{0x50, 0x83, 0xe0, 0xff, 0x90, 0x03, 0x36, 0xf0, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0} },
-{ 0x9702,	16,	{0x90, 0x03, 0x37, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0x75, 0x52, 0x03, 0x75, 0x53, 0x39, 0xef, 0x14} },
-{ 0x9712,	16,	{0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9b, 0x6a, 0x90, 0x97, 0x21, 0xf8, 0x28, 0x28, 0x73, 0x02} },
-{ 0x9722,	16,	{0x97, 0x42, 0x02, 0x97, 0xe1, 0x02, 0x98, 0xe6, 0x02, 0x99, 0x06, 0x02, 0x99, 0x06, 0x02, 0x99} },
-{ 0x9732,	16,	{0xa1, 0x02, 0x99, 0xdc, 0x02, 0x9a, 0x01, 0x02, 0x9a, 0xbf, 0x02, 0x9a, 0xef, 0x02, 0x9b, 0x1b} },
-{ 0x9742,	16,	{0xe4, 0xf5, 0x4b, 0xe5, 0x4b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20} },
-{ 0x9752,	16,	{0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74, 0x8a, 0x2e} },
-{ 0x9762,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4c, 0x80, 0x0d, 0x74, 0x8a, 0x2e} },
-{ 0x9772,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4c, 0xe5, 0x4f, 0x24, 0x07, 0xf5, 0x82} },
-{ 0x9782,	16,	{0xe4, 0x35, 0x4e, 0xf5, 0x83, 0xe5, 0x4c, 0xf0, 0xe0, 0xf5, 0x4d, 0x65, 0x4c, 0x60, 0x38, 0xe4} },
-{ 0x9792,	16,	{0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfd, 0x05, 0x53, 0xe5, 0x53, 0xaa, 0x52, 0x70, 0x02} },
-{ 0x97a2,	16,	{0x05, 0x52, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70} },
-{ 0x97b2,	16,	{0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4c, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x97c2,	16,	{0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64, 0x02, 0x70} },
-{ 0x97d2,	16,	{0x87, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60, 0x03, 0x02, 0x97, 0x45, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x97e2,	16,	{0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x05, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x03} },
-{ 0x97f2,	16,	{0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe4, 0xf5, 0x4d, 0x7e} },
-{ 0x9802,	16,	{0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} },
-{ 0x9812,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xc4, 0xf0, 0x90, 0x01} },
-{ 0x9822,	16,	{0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0x74, 0x02} },
-{ 0x9832,	16,	{0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4c, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0} },
-{ 0x9842,	16,	{0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52} },
-{ 0x9852,	16,	{0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x9862,	16,	{0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4d, 0xff, 0x90, 0x01, 0xc4, 0xe0} },
-{ 0x9872,	16,	{0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfe, 0x05, 0x53, 0xe5, 0x53} },
-{ 0x9882,	16,	{0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05, 0x53, 0xe5} },
-{ 0x9892,	16,	{0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53} },
-{ 0x98a2,	16,	{0x82, 0x85, 0x52, 0x83, 0xe5, 0x4c, 0xf0, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x70, 0x16, 0x74, 0x08} },
-{ 0x98b2,	16,	{0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35, 0x4e, 0xf5, 0x4e, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60} },
-{ 0x98c2,	16,	{0x03, 0x02, 0x98, 0x0d, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x05, 0x4b} },
-{ 0x98d2,	16,	{0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3, 0x74, 0x12} },
-{ 0x98e2,	16,	{0xf0, 0x02, 0x9b, 0x70, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0, 0x14, 0xff, 0x74, 0x01} },
-{ 0x98f2,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01, 0xc4} },
-{ 0x9902,	16,	{0xf0, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4, 0xf5} },
-{ 0x9912,	16,	{0x4d, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01, 0xc0} },
-{ 0x9922,	16,	{0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x9932,	16,	{0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4d, 0xe5, 0x4d, 0x60, 0x03, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0} },
-{ 0x9942,	16,	{0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7f} },
-{ 0x9952,	16,	{0x02, 0x12, 0x81, 0xd9, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xef, 0x54, 0x0f, 0xf5} },
-{ 0x9962,	16,	{0x4d, 0x90, 0x02, 0xf7, 0xe0, 0x55, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f} },
-{ 0x9972,	16,	{0x4c, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4c, 0x70, 0x04, 0x7f} },
-{ 0x9982,	16,	{0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4c, 0xe5, 0x4c, 0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90} },
-{ 0x9992,	16,	{0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x99a2,	16,	{0xff, 0xfd, 0x12, 0x82, 0xa8, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0x85} },
-{ 0x99b2,	16,	{0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x4f, 0x82, 0x85} },
-{ 0x99c2,	16,	{0x4e, 0x83, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3} },
-{ 0x99d2,	16,	{0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xd2, 0x04, 0x02, 0x9b, 0x70, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00} },
-{ 0x99e2,	16,	{0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xe5, 0x4f, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x4e, 0xf5} },
-{ 0x99f2,	16,	{0x83, 0xe0, 0x30, 0xe6, 0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x9a02,	16,	{0xf5, 0x4d, 0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0xe5, 0x4b, 0x75, 0xf0, 0x08} },
-{ 0x9a12,	16,	{0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xf5, 0x83} },
-{ 0x9a22,	16,	{0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf} },
-{ 0x9a32,	16,	{0x4b, 0x7d, 0x01, 0x7b, 0x01, 0x75, 0x57, 0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d} },
-{ 0x9a42,	16,	{0xe5, 0x4d, 0x70, 0x11, 0xaf, 0x4b, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20} },
-{ 0x9a52,	16,	{0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d, 0x01, 0xfb, 0x75, 0x57} },
-{ 0x9a62,	16,	{0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d} },
-{ 0x9a72,	16,	{0x02, 0xfb, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xaf, 0x4b, 0x7d} },
-{ 0x9a82,	16,	{0x01, 0x12, 0x82, 0xa8, 0xe5, 0x4d, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04} },
-{ 0x9a92,	16,	{0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
-{ 0x9aa2,	16,	{0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x05, 0x4b} },
-{ 0x9ab2,	16,	{0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x50, 0x03, 0x02, 0x9a, 0x06, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} },
-{ 0x9ac2,	16,	{0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74} },
-{ 0x9ad2,	16,	{0x9b, 0xf0, 0xa3, 0x74, 0x92, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08} },
-{ 0x9ae2,	16,	{0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} },
-{ 0x9af2,	16,	{0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5} },
-{ 0x9b02,	16,	{0x52, 0xf0, 0xa3, 0xe5, 0x53, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0x2c, 0xef, 0x64, 0x08} },
-{ 0x9b12,	16,	{0x60, 0x5c, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x51, 0x24, 0x02, 0xff, 0xe4, 0x35} },
-{ 0x9b22,	16,	{0x50, 0xfa, 0xa9, 0x07, 0x7b, 0x01, 0x7d, 0x10, 0x12, 0x95, 0xc1, 0xef, 0x4e, 0x70, 0x32, 0x90} },
-{ 0x9b32,	16,	{0x03, 0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5} },
-{ 0x9b42,	16,	{0x51, 0x24, 0x02, 0x90, 0x03, 0x60, 0xf0, 0xe4, 0x35, 0x50, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03} },
-{ 0x9b52,	16,	{0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80} },
-{ 0x9b62,	16,	{0x0d, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01} },
-{ 0x9b72,	16,	{0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70} },
-{ 0x9b82,	15,	{0xf6, 0x7e, 0x03, 0x7f, 0x35, 0x7d, 0x24, 0x12, 0x8e, 0xb4, 0xe4, 0x90, 0x02, 0xaf, 0xf0} },
-{ 0x9b91,	1,	{0x22} },
-{ 0x9b92,	16,	{0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} },
-{ 0x9ba2,	16,	{0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} },
-{ 0x9bb2,	16,	{0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} },
-{ 0x9bc2,	16,	{0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} },
-{ 0x9bd2,	16,	{0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} },
-{ 0x9be2,	16,	{0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} },
-{ 0x9bf2,	16,	{0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} },
-{ 0x9c02,	16,	{0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} },
-{ 0x9c12,	16,	{0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} },
-{ 0x9c22,	16,	{0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} },
-{ 0x9c32,	16,	{0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} },
-{ 0x9c42,	16,	{0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} },
-{ 0x9c52,	16,	{0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} },
-{ 0x9c62,	16,	{0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} },
-{ 0x9c72,	16,	{0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} },
-{ 0x9c82,	16,	{0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} },
-{ 0x9c92,	16,	{0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} },
-{ 0x9ca2,	16,	{0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} },
-{ 0x9cb2,	16,	{0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} },
-{ 0x9cc2,	16,	{0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} },
-{ 0x9cd2,	16,	{0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} },
-{ 0x9ce2,	16,	{0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} },
-{ 0x9cf2,	16,	{0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} },
-{ 0x9d02,	16,	{0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} },
-{ 0x9d12,	16,	{0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} },
-{ 0x9d22,	16,	{0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} },
-{ 0x9d32,	16,	{0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} },
-{ 0x9d42,	16,	{0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} },
-{ 0x9d52,	16,	{0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} },
-{ 0x9d62,	16,	{0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} },
-{ 0x9d72,	16,	{0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} },
-{ 0x9d82,	16,	{0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} },
-{ 0x9d92,	16,	{0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} },
-{ 0x9da2,	16,	{0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} },
-{ 0x9db2,	16,	{0x9e, 0x45, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9e, 0x45, 0xef, 0x75, 0xf0} },
-{ 0x9dc2,	16,	{0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} },
-{ 0x9dd2,	16,	{0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} },
-{ 0x9de2,	16,	{0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} },
-{ 0x9df2,	16,	{0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} },
-{ 0x9e02,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} },
-{ 0x9e12,	16,	{0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} },
-{ 0x9e22,	16,	{0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} },
-{ 0x9e32,	16,	{0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} },
-{ 0x9e42,	12,	{0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9d, 0xa4} },
-{ 0x9e4e,	1,	{0x22} },
-{ 0x9e4f,	16,	{0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} },
-{ 0x9e5f,	16,	{0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} },
-{ 0x9e6f,	16,	{0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} },
-{ 0x9e7f,	16,	{0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} },
-{ 0x9e8f,	16,	{0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} },
-{ 0x9e9f,	16,	{0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} },
-{ 0x9eaf,	16,	{0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} },
-{ 0x9ebf,	16,	{0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} },
-{ 0x9ecf,	16,	{0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} },
-{ 0x9edf,	16,	{0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} },
-{ 0x9eef,	16,	{0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} },
-{ 0x9eff,	16,	{0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} },
-{ 0x9f0f,	16,	{0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} },
-{ 0x9f1f,	16,	{0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} },
-{ 0x9f2f,	16,	{0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} },
-{ 0x9f3f,	9,	{0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9e, 0x9f, 0x73} },
-{ 0x9f48,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x9f58,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x9f61,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x9f71,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x9f81,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x9f8e,	16,	{0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} },
-{ 0x9f9e,	6,	{0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} },
-{ 0x9fa4,	16,	{0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} },
-{ 0x9fb4,	6,	{0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} },
-{ 0x9fba,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
-{ 0x9fca,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
-{ 0x9fda,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
-{ 0x9fea,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
-{ 0x9ff2,	16,	{0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} },
-{ 0xa002,	16,	{0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} },
-{ 0xa012,	16,	{0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} },
-{ 0xa022,	16,	{0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} },
-{ 0xa032,	16,	{0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} },
-{ 0xa042,	16,	{0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} },
-{ 0xa052,	16,	{0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} },
-{ 0xa062,	16,	{0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} },
-{ 0xa072,	16,	{0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} },
-{ 0xa082,	16,	{0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} },
-{ 0xa092,	16,	{0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} },
-{ 0xa0a2,	16,	{0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} },
-{ 0xa0b2,	14,	{0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} },
-{ 0xa0c0,	16,	{0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} },
-{ 0xa0d0,	1,	{0x22} },
-{ 0xa0d1,	16,	{0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} },
-{ 0xa0e1,	3,	{0xd8, 0xf1, 0x22} },
-{ 0xa0e4,	16,	{0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} },
-{ 0xa0f4,	7,	{0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} },
-{ 0xa0fb,	12,	{0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
-{ 0xa107,	16,	{0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0x12} },
-{ 0xa117,	16,	{0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} },
-{ 0xa127,	16,	{0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} },
-{ 0xa137,	1,	{0x22} },
+{ 0x82a8,	2,	{0xae, 0x07} },
+{ 0x82aa,	16,	{0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} },
+{ 0x82ba,	16,	{0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} },
+{ 0x82ca,	16,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} },
+{ 0x82da,	16,	{0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} },
+{ 0x82ea,	14,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} },
+{ 0x82f8,	1,	{0x22} },
+{ 0x82f9,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} },
+{ 0x8309,	16,	{0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5f, 0x74, 0xbf} },
+{ 0x8319,	16,	{0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
+{ 0x8329,	16,	{0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} },
+{ 0x8339,	16,	{0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} },
+{ 0x8349,	16,	{0xef, 0x55, 0x3c, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
+{ 0x8359,	16,	{0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} },
+{ 0x8369,	16,	{0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5f, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} },
+{ 0x8379,	4,	{0x83, 0xa3, 0xe9, 0xf0} },
+{ 0x837d,	1,	{0x22} },
+{ 0x837e,	4,	{0x8f, 0x5f, 0x8d, 0x60} },
+{ 0x8382,	16,	{0xe4, 0xf5, 0x61, 0x74, 0x3d, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
+{ 0x8392,	16,	{0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
+{ 0x83a2,	16,	{0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x50} },
+{ 0x83b2,	16,	{0x3c, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} },
+{ 0x83c2,	16,	{0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} },
+{ 0x83d2,	16,	{0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x40, 0x0c, 0x75, 0x61, 0x40, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76} },
+{ 0x83e2,	16,	{0x10, 0x80, 0x0a, 0x75, 0x61, 0x80, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76, 0x38, 0xe5, 0x61, 0x45} },
+{ 0x83f2,	16,	{0x60, 0x44, 0x01, 0xff, 0xe5, 0x5f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8402,	5,	{0x20, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x8407,	1,	{0x22} },
+{ 0x8408,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8418,	16,	{0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
+{ 0x8428,	16,	{0x56, 0x8f, 0x57, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} },
+{ 0x8438,	16,	{0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
+{ 0x8448,	16,	{0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x55, 0xf8, 0xe4, 0xf6, 0xe5, 0x57, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x8458,	16,	{0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e} },
+{ 0x8468,	16,	{0xaf, 0x55, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x85, 0x57, 0x82, 0x85, 0x56, 0x83, 0xa3, 0xa3, 0xe0} },
+{ 0x8478,	16,	{0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83} },
+{ 0x8488,	16,	{0xe0, 0xe5, 0x57, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x55} },
+{ 0x8498,	16,	{0x7d, 0x06, 0x12, 0x83, 0x7e, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
+{ 0x84a8,	16,	{0xe4, 0xf0, 0xe5, 0x55, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} },
+{ 0x84b8,	16,	{0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xef} },
+{ 0x84c8,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x55, 0x74, 0x01} },
+{ 0x84d8,	13,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7f, 0x00} },
+{ 0x84e5,	1,	{0x22} },
+{ 0x84e6,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x84f6,	16,	{0xaf, 0x55, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
+{ 0x8506,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8516,	16,	{0x20, 0xaf, 0x82, 0xf5, 0x57, 0x8f, 0x58, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
+{ 0x8526,	16,	{0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0xe5} },
+{ 0x8536,	16,	{0x58, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x58} },
+{ 0x8546,	16,	{0x82, 0x85, 0x57, 0x83, 0xe0, 0xf5, 0x56, 0xaf, 0x55, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
+{ 0x8556,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x31, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} },
+{ 0x8566,	16,	{0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} },
+{ 0x8576,	9,	{0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} },
+{ 0x857f,	1,	{0x22} },
+{ 0x8580,	4,	{0x8e, 0x55, 0x8f, 0x56} },
+{ 0x8584,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8594,	16,	{0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} },
+{ 0x85a4,	16,	{0x54, 0x03, 0x70, 0x24, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} },
+{ 0x85b4,	16,	{0x57, 0x7d, 0x02, 0x12, 0x83, 0x7e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe1} },
+{ 0x85c4,	10,	{0x07, 0xaf, 0x57, 0x7d, 0x04, 0x12, 0x83, 0x7e, 0x7f, 0x00} },
+{ 0x85ce,	1,	{0x22} },
+{ 0x85cf,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} },
+{ 0x85df,	16,	{0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} },
+{ 0x85ef,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} },
+{ 0x85ff,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} },
+{ 0x860f,	16,	{0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} },
+{ 0x861f,	16,	{0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} },
+{ 0x862f,	16,	{0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} },
+{ 0x863f,	16,	{0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} },
+{ 0x864f,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} },
+{ 0x865f,	3,	{0x83, 0xf0, 0x22} },
+{ 0x8662,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8666,	16,	{0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} },
+{ 0x8676,	16,	{0x22, 0x8c, 0x55, 0x8d, 0x56, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8686,	16,	{0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} },
+{ 0x8696,	16,	{0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02} },
+{ 0x86a6,	16,	{0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x86b6,	1,	{0x22} },
+{ 0x86b7,	4,	{0x8e, 0x55, 0x8f, 0x56} },
+{ 0x86bb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5c, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x86cb,	16,	{0xe5, 0x5c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
+{ 0x86db,	16,	{0x5d, 0x8f, 0x5e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
+{ 0x86eb,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa1} },
+{ 0x86fb,	16,	{0xb7, 0x40, 0x10, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x00} },
+{ 0x870b,	16,	{0x08, 0x80, 0x2e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
+{ 0x871b,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa1} },
+{ 0x872b,	16,	{0xb7, 0x50, 0x0e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x07, 0x08} },
+{ 0x873b,	16,	{0x00, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} },
+{ 0x874b,	16,	{0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a} },
+{ 0x875b,	16,	{0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1} },
+{ 0x876b,	16,	{0x25, 0xaf, 0x03, 0x8f, 0x5b, 0xaf, 0x5a, 0xae, 0x59, 0xad, 0x58, 0xac, 0x57, 0x7b, 0x0a, 0x7a} },
+{ 0x877b,	16,	{0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a, 0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57} },
+{ 0x878b,	16,	{0xe5, 0x5b, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x5a, 0x24, 0x01, 0xf5, 0x5a, 0xe4, 0x35, 0x59} },
+{ 0x879b,	16,	{0xf5, 0x59, 0xe4, 0x35, 0x58, 0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0x85, 0x5e, 0x82, 0x85} },
+{ 0x87ab,	16,	{0x5d, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} },
+{ 0x87bb,	16,	{0x80, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xe5, 0x5a, 0xf0, 0xaf, 0x5a, 0xae, 0x59, 0xad} },
+{ 0x87cb,	16,	{0x58, 0xac, 0x57, 0x78, 0x08, 0x12, 0xa1, 0xc8, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xef} },
+{ 0x87db,	16,	{0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} },
+{ 0x87eb,	16,	{0x5b, 0xe5, 0x56, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} },
+{ 0x87fb,	16,	{0x05, 0x43, 0x5b, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5b, 0x08, 0x80, 0x11, 0xef} },
+{ 0x880b,	16,	{0xb4, 0x74, 0x05, 0x43, 0x5b, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x881b,	16,	{0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} },
+{ 0x882b,	16,	{0x43, 0x5b, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5b, 0x40, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x883b,	16,	{0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
+{ 0x884b,	16,	{0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5c, 0x74, 0x01} },
+{ 0x885b,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3c, 0xe5, 0x5e, 0x24, 0x04, 0xf5} },
+{ 0x886b,	16,	{0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5b, 0x80, 0x10, 0xaf} },
+{ 0x887b,	16,	{0x5c, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3c, 0x85} },
+{ 0x888b,	16,	{0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} },
+{ 0x889b,	16,	{0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5b, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x88ab,	16,	{0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83} },
+{ 0x88bb,	16,	{0xef, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
+{ 0x88cb,	16,	{0x5e, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09} },
+{ 0x88db,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
+{ 0x88eb,	16,	{0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5} },
+{ 0x88fb,	16,	{0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x890b,	16,	{0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} },
+{ 0x891b,	16,	{0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5c, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0x75, 0x5b, 0x08, 0xe5, 0x56} },
+{ 0x892b,	16,	{0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5b, 0x10, 0xe5} },
+{ 0x893b,	16,	{0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5b, 0xf0} },
+{ 0x894b,	16,	{0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} },
+{ 0x895b,	16,	{0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0x06, 0xf5} },
+{ 0x896b,	16,	{0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} },
+{ 0x897b,	16,	{0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} },
+{ 0x898b,	16,	{0xfb, 0x4f, 0xf5, 0x5b, 0xe5, 0x56, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0} },
+{ 0x899b,	16,	{0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} },
+{ 0x89ab,	16,	{0x70, 0x14, 0x43, 0x5b, 0x18, 0x80, 0x12, 0x43, 0x5b, 0x08, 0x80, 0x0d, 0x43, 0x5b, 0x38, 0x80} },
+{ 0x89bb,	16,	{0x08, 0x43, 0x5b, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3} },
+{ 0x89cb,	16,	{0xa3, 0xa3, 0xe5, 0x5b, 0xf0, 0xaf, 0x5c, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0xaa, 0x55, 0xa9, 0x56} },
+{ 0x89db,	16,	{0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5c, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} },
+{ 0x89eb,	15,	{0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0, 0x16, 0x7f, 0x00} },
+{ 0x89fa,	1,	{0x22} },
+{ 0x89fb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8a0b,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} },
+{ 0x8a1b,	16,	{0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} },
+{ 0x8a2b,	16,	{0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} },
+{ 0x8a3b,	16,	{0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8a4b,	16,	{0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} },
+{ 0x8a5b,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x55, 0xe5, 0x30, 0xc3, 0x94, 0x01} },
+{ 0x8a6b,	16,	{0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x56, 0x00, 0xf5, 0x57, 0x80, 0x09, 0x7f} },
+{ 0x8a7b,	16,	{0x02, 0x12, 0x81, 0xd9, 0x8e, 0x56, 0x8f, 0x57, 0xc3, 0xe5, 0x56, 0x64, 0x80, 0x94, 0x80, 0x40} },
+{ 0x8a8b,	16,	{0xda, 0xe5, 0x55, 0x55, 0x57, 0x90, 0x01, 0x32, 0xf0, 0x7e, 0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12} },
+{ 0x8a9b,	4,	{0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x8a9f,	1,	{0x22} },
+{ 0x8aa0,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8ab0,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} },
+{ 0x8ac0,	16,	{0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x8ad0,	16,	{0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8f} },
+{ 0x8ae0,	3,	{0x6e, 0x7f, 0x00} },
+{ 0x8ae3,	1,	{0x22} },
+{ 0x8ae4,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8ae8,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8af8,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b08,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
+{ 0x8b18,	16,	{0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8b28,	4,	{0xfd, 0xf0, 0x7f, 0x00} },
+{ 0x8b2c,	1,	{0x22} },
+{ 0x8b2d,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8b31,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8b41,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b51,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
+{ 0x8b61,	16,	{0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8b71,	4,	{0xfe, 0xf0, 0x7f, 0x00} },
+{ 0x8b75,	1,	{0x22} },
+{ 0x8b76,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8b7a,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8b8a,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b9a,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} },
+{ 0x8baa,	16,	{0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} },
+{ 0x8bba,	1,	{0x22} },
+{ 0x8bbb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} },
+{ 0x8bcb,	16,	{0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0x7f, 0x00} },
+{ 0x8bdb,	1,	{0x22} },
+{ 0x8bdc,	4,	{0x8e, 0x55, 0x8f, 0x56} },
+{ 0x8be0,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x5a, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xd3} },
+{ 0x8bf0,	16,	{0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x57, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} },
+{ 0x8c00,	16,	{0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x58, 0x7e, 0x75, 0x59} },
+{ 0x8c10,	16,	{0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x58, 0x7e, 0x75, 0x59, 0x00, 0x80, 0x16, 0x7e} },
+{ 0x8c20,	16,	{0x7d, 0x7f, 0x80, 0x75, 0x58, 0x7d, 0x75, 0x59, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} },
+{ 0x8c30,	16,	{0x58, 0x7d, 0x75, 0x59, 0x00, 0xe5, 0x5a, 0x70, 0x1b, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0x74} },
+{ 0x8c40,	16,	{0xff, 0xf0, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} },
+{ 0x8c50,	16,	{0x01, 0xf0, 0x80, 0x48, 0xe5, 0x56, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x55, 0xfe, 0xe5, 0x5a, 0x60} },
+{ 0x8c60,	16,	{0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} },
+{ 0x8c70,	16,	{0x59, 0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} },
+{ 0x8c80,	16,	{0x15, 0x5a, 0x80, 0xd9, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x57, 0x25} },
+{ 0x8c90,	14,	{0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} },
+{ 0x8c9e,	1,	{0x22} },
+{ 0x8c9f,	16,	{0xef, 0x24, 0x05, 0xf5, 0x56, 0xe4, 0x3e, 0xf5, 0x55, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} },
+{ 0x8caf,	16,	{0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3} },
+{ 0x8cbf,	16,	{0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x57, 0xf5, 0x58, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8ccf,	16,	{0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8d, 0x80} },
+{ 0x8cdf,	16,	{0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0xcc, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe} },
+{ 0x8cef,	16,	{0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x5a, 0x74, 0x01, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a} },
+{ 0x8cff,	16,	{0x94, 0x40, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5} },
+{ 0x8d0f,	16,	{0x58, 0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x50, 0x03, 0x02, 0x8d, 0xcf, 0xae, 0x59, 0xaf, 0x5a} },
+{ 0x8d1f,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} },
+{ 0x8d2f,	16,	{0x57, 0xf5, 0x58, 0x02, 0x8d, 0xcf, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} },
+{ 0x8d3f,	16,	{0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a, 0x94} },
+{ 0x8d4f,	16,	{0x10, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x10, 0xd3, 0xe5, 0x58} },
+{ 0x8d5f,	16,	{0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x40, 0x68, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85} },
+{ 0x8d6f,	16,	{0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x80} },
+{ 0x8d7f,	16,	{0x4f, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} },
+{ 0x8d8f,	16,	{0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0x45, 0x5a, 0x60, 0x0b, 0xd3, 0xe5, 0x5a, 0x94, 0x40, 0xe5} },
+{ 0x8d9f,	16,	{0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5, 0x58, 0x95, 0x5a} },
+{ 0x8daf,	16,	{0xe5, 0x57, 0x95, 0x59, 0x40, 0x17, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8dbf,	16,	{0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x7f, 0x01, 0x22} },
+{ 0x8dcf,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8e, 0x8f, 0x24, 0xf9} },
+{ 0x8ddf,	16,	{0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0xdf, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8f, 0x23} },
+{ 0x8def,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} },
+{ 0x8dff,	16,	{0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58} },
+{ 0x8e0f,	16,	{0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xe0} },
+{ 0x8e1f,	16,	{0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0} },
+{ 0x8e2f,	16,	{0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8e3f,	16,	{0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8f} },
+{ 0x8e4f,	16,	{0x23, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x76} },
+{ 0x8e5f,	16,	{0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02} },
+{ 0x8e6f,	16,	{0x8f, 0x23, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
+{ 0x8e7f,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} },
+{ 0x8e8f,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} },
+{ 0x8e9f,	16,	{0x94, 0x00, 0x50, 0x03, 0x02, 0x8f, 0x23, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} },
+{ 0x8eaf,	16,	{0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e} },
+{ 0x8ebf,	16,	{0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
+{ 0x8ecf,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} },
+{ 0x8edf,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} },
+{ 0x8eef,	16,	{0xa3, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x60, 0x24} },
+{ 0x8eff,	16,	{0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} },
+{ 0x8f0f,	16,	{0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
+{ 0x8f1f,	16,	{0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3} },
+{ 0x8f2f,	11,	{0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x8f3a,	1,	{0x22} },
+{ 0x8f3b,	16,	{0x8e, 0x60, 0x8f, 0x61, 0x8c, 0x62, 0x8d, 0x63, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x61} },
+{ 0x8f4b,	16,	{0xe5, 0x61, 0xae, 0x60, 0x70, 0x02, 0x05, 0x60, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} },
+{ 0x8f5b,	16,	{0x63, 0xe5, 0x63, 0xac, 0x62, 0x70, 0x02, 0x05, 0x62, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x8f6b,	3,	{0x80, 0xd6, 0x22} },
+{ 0x8f6e,	6,	{0x8d, 0x5b, 0xab, 0x07, 0xaa, 0x06} },
+{ 0x8f74,	16,	{0x75, 0x5f, 0x40, 0x75, 0x5e, 0x0d, 0x75, 0x5d, 0x03, 0x75, 0x5c, 0x00, 0x90, 0x7f, 0xc2, 0xe0} },
+{ 0x8f84,	16,	{0x20, 0xe1, 0xf9, 0xaf, 0x5f, 0xae, 0x5e, 0xad, 0x5d, 0xac, 0x5c, 0xec, 0x4d, 0x4e, 0x4f, 0x70} },
+{ 0x8f94,	16,	{0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} },
+{ 0x8fa4,	16,	{0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5b, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xc3} },
+{ 0x8fb4,	8,	{0xe5, 0x5b, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x8fbc,	1,	{0x22} },
+{ 0x8fbd,	16,	{0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0xa3, 0xe5, 0x30, 0xf0, 0x90, 0x0a, 0xf1, 0xe4, 0x93, 0x90} },
+{ 0x8fcd,	16,	{0x01, 0x86, 0xf0, 0x90, 0x0a, 0xf2, 0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c} },
+{ 0x8fdd,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01} },
+{ 0x8fed,	16,	{0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e, 0x01, 0x7f, 0x7c, 0x12, 0x19, 0xc1, 0x7e, 0x01, 0x7f, 0x84} },
+{ 0x8ffd,	7,	{0x7d, 0x14, 0x12, 0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x9004,	1,	{0x22} },
+{ 0x9005,	16,	{0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4c, 0x7b, 0x75, 0x4d, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} },
+{ 0x9015,	16,	{0x4c, 0x4f, 0x85, 0x4d, 0x50, 0xe5, 0x50, 0x24, 0x01, 0xf5, 0x54, 0xe4, 0x35, 0x4f, 0xf5, 0x53} },
+{ 0x9025,	16,	{0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} },
+{ 0x9035,	16,	{0x5b, 0x90, 0x90, 0x3d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x90, 0x61, 0x02, 0x90, 0x61, 0x02, 0x90} },
+{ 0x9045,	16,	{0x6b, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x89, 0x02, 0x90, 0x61} },
+{ 0x9055,	16,	{0x02, 0x90, 0x7f, 0x02, 0x90, 0x61, 0x02, 0x90, 0x91, 0x02, 0x90, 0x61, 0xef, 0x64, 0x02, 0x60} },
+{ 0x9065,	16,	{0x2b, 0x75, 0x4e, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4e, 0xff, 0x80, 0x1c} },
+{ 0x9075,	16,	{0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4e, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} },
+{ 0x9085,	16,	{0x4e, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x60, 0x15} },
+{ 0x9095,	16,	{0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} },
+{ 0x90a5,	16,	{0x8f, 0x6e, 0xaf, 0x4e, 0x22, 0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0x14} },
+{ 0x90b5,	16,	{0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0xd3, 0x90, 0x90, 0xc4, 0xf8, 0x28, 0x28, 0x73, 0x02} },
+{ 0x90c5,	16,	{0x90, 0xf1, 0x02, 0x90, 0xfd, 0x02, 0x91, 0x09, 0x02, 0x91, 0x57, 0x02, 0x91, 0x62, 0x02, 0x91} },
+{ 0x90d5,	16,	{0x6d, 0x02, 0x91, 0x78, 0x02, 0x91, 0x83, 0x02, 0x91, 0x8e, 0x02, 0x91, 0x99, 0x02, 0x91, 0xa4} },
+{ 0x90e5,	16,	{0x02, 0x91, 0xab, 0x02, 0x91, 0xd3, 0x02, 0x91, 0xb6, 0x02, 0x91, 0xc1, 0xaf, 0x54, 0xae, 0x53} },
+{ 0x90f5,	16,	{0x12, 0x84, 0x08, 0x8f, 0x4e, 0x02, 0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x84, 0xe6, 0x8f} },
+{ 0x9105,	16,	{0x4e, 0x02, 0x91, 0xd6, 0x85, 0x53, 0x51, 0x85, 0x54, 0x52, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4} },
+{ 0x9115,	16,	{0x35, 0x51, 0xfe, 0x12, 0x85, 0xcf, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0x62, 0x8f, 0x4e, 0xef} },
+{ 0x9125,	16,	{0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0xd6, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0xb7, 0x8f, 0x4e} },
+{ 0x9135,	16,	{0xe5, 0x4e, 0x70, 0x03, 0x02, 0x91, 0xd6, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0x75, 0xf0} },
+{ 0x9145,	16,	{0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0xb7, 0x02} },
+{ 0x9155,	16,	{0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xe4, 0x8f, 0x4e, 0x80, 0x74, 0xaf, 0x54, 0xae} },
+{ 0x9165,	16,	{0x53, 0x12, 0x8b, 0x2d, 0x8f, 0x4e, 0x80, 0x69, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0x76, 0x8f} },
+{ 0x9175,	16,	{0x4e, 0x80, 0x5e, 0xaf, 0x4d, 0xae, 0x4c, 0x12, 0x8c, 0x9f, 0x8f, 0x4e, 0x80, 0x53, 0xaf, 0x54} },
+{ 0x9185,	16,	{0xae, 0x53, 0x12, 0x89, 0xfb, 0x8f, 0x4e, 0x80, 0x48, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x85, 0x80} },
+{ 0x9195,	16,	{0x8f, 0x4e, 0x80, 0x3d, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xa0, 0x8f, 0x4e, 0x80, 0x32, 0x12} },
+{ 0x91a5,	16,	{0x8f, 0xbd, 0x8f, 0x4e, 0x80, 0x2b, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xbb, 0x8f, 0x4e, 0x80} },
+{ 0x91b5,	16,	{0x20, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xdc, 0x8f, 0x4e, 0x80, 0x15, 0xaf, 0x4d, 0xae, 0x4c} },
+{ 0x91c5,	16,	{0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8f, 0x3b, 0xe4, 0xf5, 0x4e, 0x80, 0x03, 0x75, 0x4e} },
+{ 0x91d5,	16,	{0xff, 0xe5, 0x4e, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x50, 0x82, 0x85, 0x4f} },
+{ 0x91e5,	16,	{0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8f, 0x6e, 0xaf} },
+{ 0x91f5,	16,	{0x4e, 0x22, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} },
+{ 0x9205,	16,	{0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x54, 0x82, 0x85} },
+{ 0x9215,	16,	{0x53, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8f, 0x6e} },
+{ 0x9225,	4,	{0x8f, 0x4e, 0xaf, 0x4e} },
+{ 0x9229,	1,	{0x22} },
+{ 0x922a,	8,	{0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c} },
+{ 0x9232,	16,	{0x75, 0x56, 0x01, 0x75, 0x57, 0x9c, 0xe4, 0xf5, 0x55, 0xaf, 0x51, 0x15, 0x51, 0xef, 0x70, 0x03} },
+{ 0x9242,	16,	{0x02, 0x92, 0xc8, 0xaf, 0x50, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4f} },
+{ 0x9252,	16,	{0xae, 0x4e, 0xad, 0x4d, 0xac, 0x4c, 0x12, 0xa1, 0x25, 0xaf, 0x03, 0x8f, 0x54, 0xaf, 0x4f, 0xae} },
+{ 0x9262,	16,	{0x4e, 0xad, 0x4d, 0xac, 0x4c, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x50, 0xe4} },
+{ 0x9272,	16,	{0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} },
+{ 0x9282,	16,	{0x12, 0xa1, 0x25, 0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c, 0xe5, 0x54, 0x24, 0x30, 0xf5} },
+{ 0x9292,	16,	{0x54, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x54, 0xf5, 0x54, 0x05, 0x57, 0xe5, 0x57} },
+{ 0x92a2,	16,	{0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x57, 0xe5} },
+{ 0x92b2,	16,	{0x57, 0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x54, 0xf0, 0x05} },
+{ 0x92c2,	16,	{0x55, 0x05, 0x55, 0x02, 0x92, 0x3b, 0xe5, 0x57, 0x15, 0x57, 0x70, 0x02, 0x15, 0x56, 0xaf, 0x55} },
+{ 0x92d2,	16,	{0x15, 0x55, 0xef, 0x60, 0x23, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0xf5} },
+{ 0x92e2,	16,	{0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14} },
+{ 0x92f2,	8,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} },
+{ 0x92fa,	1,	{0x22} },
+{ 0x92fb,	16,	{0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} },
+{ 0x930b,	10,	{0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0x9315,	16,	{0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} },
+{ 0x9325,	16,	{0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} },
+{ 0x9335,	16,	{0xe4, 0xef, 0x55, 0x31, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x9345,	16,	{0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
+{ 0x9355,	16,	{0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} },
+{ 0x9365,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
+{ 0x9375,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x9385,	1,	{0x22} },
+{ 0x9386,	16,	{0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x9396,	16,	{0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} },
+{ 0x93a6,	16,	{0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} },
+{ 0x93b6,	16,	{0xa0, 0x16, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} },
+{ 0x93c6,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
+{ 0x93d6,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x93e6,	1,	{0x22} },
+{ 0x93e7,	16,	{0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x51, 0x7b, 0x75, 0x52} },
+{ 0x93f7,	16,	{0x80, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x51, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x53, 0xf5} },
+{ 0x9407,	16,	{0x54, 0x89, 0x55, 0xfe, 0x12, 0x93, 0x86, 0xef, 0x60, 0x50, 0xab, 0x53, 0xaa, 0x54, 0xa9, 0x55} },
+{ 0x9417,	16,	{0x12, 0xa0, 0x3f, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x02, 0x16, 0xc2, 0xaf} },
+{ 0x9427,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} },
+{ 0x9437,	16,	{0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} },
+{ 0x9447,	16,	{0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x31, 0x60, 0x0f, 0x85, 0x52, 0x82, 0x85, 0x51} },
+{ 0x9457,	10,	{0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} },
+{ 0x9461,	1,	{0x22} },
+{ 0x9462,	16,	{0x12, 0x93, 0xe7, 0xe4, 0xf5, 0x4c, 0x74, 0x37, 0x25, 0x4c, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4d} },
+{ 0x9472,	16,	{0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0xff, 0xc4} },
+{ 0x9482,	16,	{0x54, 0x0f, 0xf5, 0x4e, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} },
+{ 0x9492,	16,	{0x83, 0xe5, 0x4d, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0xe5, 0x4d, 0x45, 0x4e, 0xfb, 0x12, 0x93, 0x15} },
+{ 0x94a2,	16,	{0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} },
+{ 0x94b2,	16,	{0xb5, 0x12, 0x93, 0xe7, 0xe5, 0x3b, 0x60, 0x48, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x74, 0x01, 0xa8} },
+{ 0x94c2,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x55, 0x3b, 0x60, 0x29, 0xe5, 0x4c} },
+{ 0x94d2,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
+{ 0x94e2,	16,	{0x16, 0xaf, 0x4c, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7} },
+{ 0x94f2,	16,	{0x80, 0xef, 0xe5, 0x4d, 0xf4, 0x52, 0x3b, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40, 0xbb} },
+{ 0x9502,	16,	{0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0xe3, 0x74, 0x19, 0xf0, 0xe5, 0x30, 0xc3, 0x94} },
+{ 0x9512,	16,	{0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00, 0xf5, 0x50, 0x80, 0x09} },
+{ 0x9522,	16,	{0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f, 0x64, 0x80, 0x94, 0x80} },
+{ 0x9532,	16,	{0x40, 0xda, 0x90, 0x01, 0xbc, 0xe0, 0x65, 0x50, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c} },
+{ 0x9542,	16,	{0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xbc} },
+{ 0x9552,	16,	{0xe0, 0x55, 0x4d, 0x60, 0x14, 0xaf, 0x4c, 0x7d, 0x08, 0xe5, 0x4d, 0x55, 0x50, 0xfb, 0x12, 0x93} },
+{ 0x9562,	16,	{0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04} },
+{ 0x9572,	16,	{0x40, 0xcc, 0x90, 0x01, 0xbc, 0xe5, 0x50, 0xf0, 0xe4, 0xf5, 0x4c, 0xc2, 0xaf, 0x74, 0x33, 0x25} },
+{ 0x9582,	16,	{0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4d, 0x1e, 0xe5, 0x4d, 0x60, 0x11} },
+{ 0x9592,	16,	{0xaf, 0x4c, 0x7d, 0x02, 0xab, 0x4d, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80} },
+{ 0x95a2,	16,	{0xef, 0x74, 0x2c, 0x25, 0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82, 0xe4} },
+{ 0x95b2,	16,	{0x34, 0x02, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0x60, 0x11, 0xaf, 0x4c, 0x7d, 0x04, 0xab, 0x4d, 0x12} },
+{ 0x95c2,	16,	{0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82} },
+{ 0x95d2,	16,	{0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} },
+{ 0x95e2,	4,	{0x9a, 0x12, 0x93, 0xe7} },
+{ 0x95e6,	1,	{0x22} },
+{ 0x95e7,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x63, 0x02, 0x96, 0x2e} },
+{ 0x95f3,	16,	{0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
+{ 0x9603,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
+{ 0x9613,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
+{ 0x9623,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x96, 0x73, 0xe4, 0x7e} },
+{ 0x9633,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
+{ 0x9643,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
+{ 0x9653,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
+{ 0x9663,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
+{ 0x9673,	16,	{0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} },
+{ 0x9683,	16,	{0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} },
+{ 0x9693,	8,	{0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} },
+{ 0x969b,	1,	{0x00} },
+{ 0x969c,	8,	{0x8b, 0x57, 0x8a, 0x58, 0x89, 0x59, 0x8d, 0x5a} },
+{ 0x96a4,	16,	{0xe4, 0xf5, 0x5b, 0xf5, 0x5c, 0xaf, 0x5a, 0x15, 0x5a, 0xef, 0x60, 0x36, 0xab, 0x57, 0x05, 0x59} },
+{ 0x96b4,	16,	{0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf9, 0x12, 0xa0, 0x3f, 0xff, 0xe5, 0x5b} },
+{ 0x96c4,	16,	{0xe5, 0x5c, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0x99, 0x2f, 0xf5, 0x82, 0xee, 0x34} },
+{ 0x96d4,	16,	{0x9c, 0xf5, 0x83, 0xe5, 0x5b, 0xff, 0xe4, 0x93, 0xf5, 0x5b, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x5c} },
+{ 0x96e4,	6,	{0x80, 0xc3, 0xae, 0x5b, 0xaf, 0x5c} },
+{ 0x96ea,	1,	{0x22} },
+{ 0x96eb,	11,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} },
+{ 0x96f6,	16,	{0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} },
+{ 0x9706,	16,	{0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} },
+{ 0x9716,	16,	{0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} },
+{ 0x9726,	10,	{0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} },
+{ 0x9730,	9,	{0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x9739,	2,	{0xa9, 0x03} },
+{ 0x973b,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} },
+{ 0x974b,	16,	{0x5a, 0x45, 0x5b, 0xf5, 0x5c, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x975b,	16,	{0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} },
+{ 0x976b,	16,	{0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x5c, 0xeb} },
+{ 0x977b,	16,	{0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x5c, 0xfc, 0xb5, 0x06, 0x03, 0xaf} },
+{ 0x978b,	16,	{0x05, 0x22, 0xe5, 0x5a, 0x5c, 0xfe, 0xe5, 0x5b, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} },
+{ 0x979b,	16,	{0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
+{ 0x97ab,	16,	{0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x5a, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x5b, 0x22, 0x7f} },
+{ 0x97bb,	1,	{0x00} },
+{ 0x97bc,	1,	{0x22} },
+{ 0x97bd,	16,	{0x75, 0x53, 0x02, 0x75, 0x54, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x54, 0x82, 0x85} },
+{ 0x97cd,	16,	{0x53, 0x83, 0xa3, 0xe0, 0xff, 0x90, 0x03, 0x37, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0} },
+{ 0x97dd,	16,	{0x90, 0x03, 0x36, 0xf0, 0x90, 0x03, 0x38, 0x74, 0xff, 0xf0, 0x75, 0x55, 0x03, 0x75, 0x56, 0x39} },
+{ 0x97ed,	16,	{0xef, 0x14, 0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9c, 0x61, 0x90, 0x97, 0xfe, 0xf8, 0x28, 0x28} },
+{ 0x97fd,	16,	{0x73, 0x02, 0x98, 0x1f, 0x02, 0x98, 0xbe, 0x02, 0x99, 0xc3, 0x02, 0x99, 0xe2, 0x02, 0x99, 0xe2} },
+{ 0x980d,	16,	{0x02, 0x9a, 0x98, 0x02, 0x9a, 0xd3, 0x02, 0x9a, 0xf8, 0x02, 0x9b, 0xb6, 0x02, 0x9b, 0xe6, 0x02} },
+{ 0x981d,	16,	{0x9c, 0x12, 0xe4, 0xf5, 0x4c, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4} },
+{ 0x982d,	16,	{0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74} },
+{ 0x983d,	16,	{0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4d, 0x80, 0x0d, 0x74} },
+{ 0x984d,	16,	{0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4d, 0xe5, 0x52, 0x24, 0x07} },
+{ 0x985d,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0xe0, 0xf5, 0x4e, 0x65, 0x4d, 0x60} },
+{ 0x986d,	16,	{0x38, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55} },
+{ 0x987d,	16,	{0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x56, 0xe5, 0x56, 0xac} },
+{ 0x988d,	16,	{0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4d, 0xf0, 0x85, 0x56, 0x82} },
+{ 0x989d,	16,	{0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64} },
+{ 0x98ad,	16,	{0x02, 0x70, 0x87, 0x05, 0x4c, 0xe5, 0x4c, 0x64, 0x04, 0x60, 0x03, 0x02, 0x98, 0x22, 0x02, 0x9c} },
+{ 0x98bd,	16,	{0x67, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x05, 0x4c, 0xe5, 0x4c, 0xd3} },
+{ 0x98cd,	16,	{0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0xeb, 0xf0, 0xe4, 0xf5} },
+{ 0x98dd,	16,	{0x4e, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0xf5, 0x4c, 0xaf, 0x4c, 0x74} },
+{ 0x98ed,	16,	{0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xc4, 0xf0} },
+{ 0x98fd,	16,	{0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3} },
+{ 0x990d,	16,	{0x74, 0x02, 0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4d, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02} },
+{ 0x991d,	16,	{0xa3, 0xe0, 0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5, 0x56} },
+{ 0x992d,	16,	{0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56, 0x82} },
+{ 0x993d,	16,	{0x85, 0x55, 0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4e, 0xff, 0x90, 0x01} },
+{ 0x994d,	16,	{0xc4, 0xe0, 0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfe, 0x05, 0x56} },
+{ 0x995d,	16,	{0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05} },
+{ 0x996d,	16,	{0x56, 0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x997d,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4d, 0xf0, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x70, 0x16} },
+{ 0x998d,	16,	{0x74, 0x08, 0x25, 0x52, 0xf5, 0x52, 0xe4, 0x35, 0x51, 0xf5, 0x51, 0x05, 0x4c, 0xe5, 0x4c, 0x64} },
+{ 0x999d,	16,	{0x04, 0x60, 0x03, 0x02, 0x98, 0xea, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} },
+{ 0x99ad,	16,	{0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3} },
+{ 0x99bd,	16,	{0x74, 0x12, 0xf0, 0x02, 0x9c, 0x67, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0, 0x14, 0xff, 0x74} },
+{ 0x99cd,	16,	{0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01} },
+{ 0x99dd,	16,	{0xc4, 0xf0, 0x02, 0x9c, 0x67, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4} },
+{ 0x99ed,	16,	{0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01} },
+{ 0x99fd,	16,	{0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x56, 0x82, 0x85} },
+{ 0x9a0d,	16,	{0x55, 0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4e, 0xe5, 0x4e, 0x60, 0x03, 0x02, 0x9c, 0x67, 0x90, 0x01} },
+{ 0x9a1d,	16,	{0xc0, 0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6} },
+{ 0x9a2d,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00} },
+{ 0x9a3d,	16,	{0xf5, 0x50, 0x80, 0x09, 0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f} },
+{ 0x9a4d,	16,	{0x64, 0x80, 0x94, 0x80, 0x40, 0xda, 0xe5, 0x50, 0x54, 0x0f, 0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0} },
+{ 0x9a5d,	16,	{0x55, 0x4e, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4d, 0x85, 0x54, 0x82, 0x85} },
+{ 0x9a6d,	16,	{0x53, 0x83, 0xa3, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
+{ 0x9a7d,	16,	{0x00, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x03, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x85} },
+{ 0x9a8d,	16,	{0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0xff, 0xfd, 0x12, 0x82} },
+{ 0x9a9d,	16,	{0xf9, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0x85, 0x52, 0x82, 0x85, 0x51} },
+{ 0x9aad,	16,	{0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0x74, 0x01} },
+{ 0x9abd,	16,	{0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f} },
+{ 0x9acd,	16,	{0xf0, 0xd2, 0x04, 0x02, 0x9c, 0x67, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75} },
+{ 0x9add,	16,	{0x52, 0x00, 0xe5, 0x52, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
+{ 0x9aed,	16,	{0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x02, 0x9c, 0x67, 0xe4, 0xf5, 0x4e, 0xf5, 0x4c} },
+{ 0x9afd,	16,	{0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5} },
+{ 0x9b0d,	16,	{0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04} },
+{ 0x9b1d,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0x7b} },
+{ 0x9b2d,	16,	{0x01, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x11} },
+{ 0x9b3d,	16,	{0xaf, 0x4c, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x5a, 0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f} },
+{ 0x9b4d,	16,	{0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x01, 0xfb, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40} },
+{ 0x9b5d,	16,	{0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x02, 0xfb, 0x75, 0x5a} },
+{ 0x9b6d,	16,	{0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} },
+{ 0x9b7d,	16,	{0xe5, 0x4e, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5} },
+{ 0x9b8d,	16,	{0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56} },
+{ 0x9b9d,	16,	{0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94} },
+{ 0x9bad,	16,	{0x03, 0x50, 0x03, 0x02, 0x9a, 0xfd, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
+{ 0x9bbd,	16,	{0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x9c, 0xf0, 0xa3, 0x74} },
+{ 0x9bcd,	16,	{0x89, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0xcc, 0xef, 0x64, 0x08, 0x70, 0x03, 0x02, 0x9c} },
+{ 0x9bdd,	16,	{0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
+{ 0x9bed,	16,	{0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5, 0x55, 0xf0, 0xa3, 0xe5} },
+{ 0x9bfd,	16,	{0x56, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x5c, 0xe4, 0x90} },
+{ 0x9c0d,	16,	{0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x54, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x53, 0xfa, 0xa9, 0x07} },
+{ 0x9c1d,	16,	{0x7b, 0x01, 0x7d, 0x10, 0x12, 0x96, 0x9c, 0xef, 0x4e, 0x70, 0x32, 0x90, 0x03, 0x59, 0xf0, 0xa3} },
+{ 0x9c2d,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5, 0x54, 0x24, 0x02, 0x90} },
+{ 0x9c3d,	16,	{0x03, 0x60, 0xf0, 0xe4, 0x35, 0x53, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10} },
+{ 0x9c4d,	16,	{0xcc, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x0d, 0xe4, 0x90, 0x03} },
+{ 0x9c5d,	16,	{0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3} },
+{ 0x9c6d,	16,	{0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7e, 0x03, 0x7f} },
+{ 0x9c7d,	11,	{0x35, 0x7d, 0x24, 0x12, 0x8f, 0x6e, 0xe4, 0x90, 0x02, 0xaf, 0xf0} },
+{ 0x9c88,	1,	{0x22} },
+{ 0x9c89,	16,	{0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} },
+{ 0x9c99,	16,	{0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} },
+{ 0x9ca9,	16,	{0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} },
+{ 0x9cb9,	16,	{0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} },
+{ 0x9cc9,	16,	{0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} },
+{ 0x9cd9,	16,	{0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} },
+{ 0x9ce9,	16,	{0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} },
+{ 0x9cf9,	16,	{0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} },
+{ 0x9d09,	16,	{0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} },
+{ 0x9d19,	16,	{0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} },
+{ 0x9d29,	16,	{0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} },
+{ 0x9d39,	16,	{0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} },
+{ 0x9d49,	16,	{0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} },
+{ 0x9d59,	16,	{0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} },
+{ 0x9d69,	16,	{0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} },
+{ 0x9d79,	16,	{0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} },
+{ 0x9d89,	16,	{0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} },
+{ 0x9d99,	16,	{0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} },
+{ 0x9da9,	16,	{0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} },
+{ 0x9db9,	16,	{0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} },
+{ 0x9dc9,	16,	{0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} },
+{ 0x9dd9,	16,	{0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} },
+{ 0x9de9,	16,	{0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} },
+{ 0x9df9,	16,	{0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} },
+{ 0x9e09,	16,	{0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} },
+{ 0x9e19,	16,	{0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} },
+{ 0x9e29,	16,	{0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} },
+{ 0x9e39,	16,	{0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} },
+{ 0x9e49,	16,	{0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} },
+{ 0x9e59,	16,	{0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} },
+{ 0x9e69,	16,	{0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} },
+{ 0x9e79,	16,	{0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} },
+{ 0x9e89,	16,	{0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} },
+{ 0x9e99,	16,	{0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} },
+{ 0x9ea9,	16,	{0x9f, 0x3c, 0x74, 0x37, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9f, 0x3c, 0xef, 0x75, 0xf0} },
+{ 0x9eb9,	16,	{0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} },
+{ 0x9ec9,	16,	{0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} },
+{ 0x9ed9,	16,	{0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} },
+{ 0x9ee9,	16,	{0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} },
+{ 0x9ef9,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} },
+{ 0x9f09,	16,	{0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} },
+{ 0x9f19,	16,	{0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} },
+{ 0x9f29,	16,	{0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} },
+{ 0x9f39,	12,	{0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9e, 0x9b} },
+{ 0x9f45,	1,	{0x22} },
+{ 0x9f46,	16,	{0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} },
+{ 0x9f56,	16,	{0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} },
+{ 0x9f66,	16,	{0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} },
+{ 0x9f76,	16,	{0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} },
+{ 0x9f86,	16,	{0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} },
+{ 0x9f96,	16,	{0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} },
+{ 0x9fa6,	16,	{0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} },
+{ 0x9fb6,	16,	{0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} },
+{ 0x9fc6,	16,	{0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} },
+{ 0x9fd6,	16,	{0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} },
+{ 0x9fe6,	16,	{0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} },
+{ 0x9ff6,	16,	{0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} },
+{ 0xa006,	16,	{0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} },
+{ 0xa016,	16,	{0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} },
+{ 0xa026,	16,	{0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} },
+{ 0xa036,	9,	{0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9f, 0x96, 0x73} },
+{ 0xa03f,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
+{ 0xa04f,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
+{ 0xa058,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
+{ 0xa068,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
+{ 0xa078,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
+{ 0xa085,	16,	{0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} },
+{ 0xa095,	6,	{0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} },
+{ 0xa09b,	16,	{0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} },
+{ 0xa0ab,	6,	{0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} },
+{ 0xa0b1,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
+{ 0xa0c1,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
+{ 0xa0d1,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
+{ 0xa0e1,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
+{ 0xa0e9,	16,	{0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} },
+{ 0xa0f9,	16,	{0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} },
+{ 0xa109,	16,	{0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} },
+{ 0xa119,	16,	{0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} },
+{ 0xa129,	16,	{0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} },
+{ 0xa139,	16,	{0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} },
+{ 0xa149,	16,	{0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} },
+{ 0xa159,	16,	{0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} },
+{ 0xa169,	16,	{0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} },
+{ 0xa179,	16,	{0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} },
+{ 0xa189,	16,	{0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} },
+{ 0xa199,	16,	{0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} },
+{ 0xa1a9,	14,	{0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} },
+{ 0xa1b7,	16,	{0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} },
+{ 0xa1c7,	1,	{0x22} },
+{ 0xa1c8,	16,	{0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} },
+{ 0xa1d8,	3,	{0xd8, 0xf1, 0x22} },
+{ 0xa1db,	16,	{0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} },
+{ 0xa1eb,	7,	{0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} },
+{ 0xa1f2,	12,	{0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0xa1fe,	16,	{0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa2, 0x15, 0x12, 0xa2, 0x15, 0x12} },
+{ 0xa20e,	16,	{0xa2, 0x15, 0x12, 0xa2, 0x15, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} },
+{ 0xa21e,	16,	{0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} },
+{ 0xa22e,	1,	{0x22} },
 { 0xffff,	0,	{0x00} }
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/Makefile linux/drivers/usb/storage/Makefile
--- linux.orig/drivers/usb/storage/Makefile	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/Makefile	2002-07-20 01:08:38.000000000 +0000
@@ -16,8 +16,6 @@
 usb-storage-obj-$(CONFIG_USB_STORAGE_HP8200e)	+= shuttle_usbat.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09)	+= sddr09.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM)	+= freecom.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SHUTTLE_SMARTMEDIA)   += shuttle_sm.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SHUTTLE_COMPACTFLASH) += shuttle_cf.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM)	+= dpcm.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200)	+= isd200.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB)   += datafab.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/datafab.c linux/drivers/usb/storage/datafab.c
--- linux.orig/drivers/usb/storage/datafab.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/datafab.c	2002-07-20 01:08:40.000000000 +0000
@@ -1,16 +1,25 @@
 /* Driver for Datafab USB Compact Flash reader
  *
+ * $Id: datafab.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $
+ *
  * datafab driver v0.1:
  *
  * First release
  *
  * Current development and maintenance by:
  *   (c) 2000 Jimmie Mayfield (mayfield+datafab@sackheads.org)
- *   many thanks to Robert Baruch for the SanDisk SmartMedia reader driver
+ *
+ *   Many thanks to Robert Baruch for the SanDisk SmartMedia reader driver
  *   which I used as a template for this driver.
+ *
  *   Some bugfixes and scatter-gather code by Gregory P. Smith 
  *   (greg-usb@electricrain.com)
  *
+ *   Fix for media change by Joerg Schneider (js@joergschneider.com)
+ *
+ * Other contributors:
+ *   (c) 2002 Alan Stern <stern@rowland.org>
+ *
  * 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, or (at your option) any
@@ -102,7 +111,7 @@
 	if (result == -EPIPE) {
 		US_DEBUGP("datafab_raw_bulk: EPIPE. clearing endpoint halt for"
 			  " pipe 0x%x, stalled at %d bytes\n", pipe, act_len);
-		usb_clear_halt(us->pusb_dev, pipe);
+		usb_stor_clear_halt(us, pipe);
 	}
 
 	if (result) {
@@ -801,6 +810,23 @@
 		return USB_STOR_TRANSPORT_GOOD;
 	}
 
+	if (srb->cmnd[0] == START_STOP) {
+		/* this is used by sd.c'check_scsidisk_media_change to detect
+		   media change */
+		US_DEBUGP("datafab_transport:  START_STOP.\n");
+		/* the first datafab_id_device after a media change returns
+		   an error (determined experimentally) */
+		rc = datafab_id_device(us, info);
+		if (rc == USB_STOR_TRANSPORT_GOOD) {
+			info->sense_key = NO_SENSE;
+			srb->result = SUCCESS;
+		} else {
+			info->sense_key = UNIT_ATTENTION;
+			srb->result = CHECK_CONDITION;
+		}
+		return rc;
+        }
+
 	US_DEBUGP("datafab_transport:  Gah! Unknown command: %d (0x%x)\n", srb->cmnd[0], srb->cmnd[0]);
 	return USB_STOR_TRANSPORT_ERROR;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/debug.c linux/drivers/usb/storage/debug.c
--- linux.orig/drivers/usb/storage/debug.c	2001-07-30 04:11:50.000000000 +0000
+++ linux/drivers/usb/storage/debug.c	2002-07-20 01:08:25.000000000 +0000
@@ -1,10 +1,13 @@
 /* Driver for USB Mass Storage compliant devices
  * Debugging Functions Source Code File
  *
- * $Id: debug.c,v 1.5 2001/06/27 23:20:45 mdharm Exp $
+ * $Id: debug.c,v 1.8 2002/02/25 00:40:13 mdharm Exp $
  *
  * Current development and maintenance by:
- *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ *
+ * Developed with the assistance of:
+ *   (c) 2002 Alan Stern <stern@rowland.org>
  *
  * Initial work by:
  *   (c) 1999 Michael Gee (michael@linuxspecific.com)
@@ -300,9 +303,11 @@
 	case 0x1902: what="defect list error in primary list"; break;
 	case 0x1903: what="defect list error in grown list"; break;
 	case 0x1C00: what="defect list not found"; break;
+	case 0x2000: what="invalid command operation code"; break;
 	case 0x2400: what="invalid field in CDB"; break;
 	case 0x2703: what="associated write protect"; break;
 	case 0x2800: what="not ready to ready transition"; break;
+	case 0x2900: what="device reset occurred"; break;
 	case 0x2903: what="bus device reset function occurred"; break;
 	case 0x2904: what="device internal reset"; break;
 	case 0x2B00: what="copy can't execute / host can't disconnect"; break;
@@ -325,6 +330,7 @@
 	case 0x3502: what="enclosure services unavailable"; break;
 	case 0x3503: what="enclosure services transfer failure"; break;
 	case 0x3504: what="enclosure services transfer refused"; break;
+	case 0x3A00: what="media not present"; break;
 	case 0x3B0F: what="end of medium reached"; break;
 	case 0x3F02: what="changed operating definition"; break;
 	case 0x4100: what="data path failure (should use 40 NN)"; break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/isd200.c linux/drivers/usb/storage/isd200.c
--- linux.orig/drivers/usb/storage/isd200.c	2001-11-13 17:19:41.000000000 +0000
+++ linux/drivers/usb/storage/isd200.c	2002-07-20 01:08:36.000000000 +0000
@@ -1,9 +1,15 @@
 /* Transport & Protocol Driver for In-System Design, Inc. ISD200 ASIC
  *
- * First release
+ * $Id: isd200.c,v 1.14 2002/02/25 00:40:13 mdharm Exp $
  *
- * Current development and maintenance by:
- *   (c) 2000 In-System Design, Inc. (support@in-system.com)
+ * Current development and maintenance:
+ *   (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
+ *
+ * Developed with the assistance of:
+ *   (C) 2002 Alan Stern <stern@rowland.org>
+ *
+ * Initial work:
+ *   (C) 2000 In-System Design, Inc. (support@in-system.com)
  *
  * The ISD200 ASIC does not natively support ATA devices.  The chip
  * does implement an interface, the ATA Command Block (ATACB) which provides
@@ -27,6 +33,10 @@
  *
  *  2001-02-24: Removed lots of duplicate code and simplified the structure.
  *              (bjorn@haxx.se)
+ *  2002-01-16: Fixed endianness bug so it works on the ppc arch.
+ *              (Luc Saillard <luc@saillard.org>)
+ *  2002-01-17: All bitfields removed.
+ *              (bjorn@haxx.se)
  */
 
 
@@ -45,15 +55,6 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 
-/*
- * Inquiry defines. Used to interpret data returned from target as result
- * of inquiry command.
- *
- * DeviceType field
- */
-
-#define DIRECT_ACCESS_DEVICE            0x00    /* disks */
-
 /* Timeout defines (in Seconds) */
 
 #define ISD200_ENUM_BSY_TIMEOUT         35
@@ -88,6 +89,19 @@
 #define ACTION_SELECT_6             0x40
 #define ACTION_SELECT_7             0x80
 
+/* Register Select bits */
+#define REG_ALTERNATE_STATUS 0x01
+#define REG_DEVICE_CONTROL   0x01
+#define REG_ERROR            0x02
+#define REG_FEATURES         0x02
+#define REG_SECTOR_COUNT     0x04
+#define REG_SECTOR_NUMBER    0x08
+#define REG_CYLINDER_LOW     0x10
+#define REG_CYLINDER_HIGH    0x20
+#define REG_DEVICE_HEAD      0x40
+#define REG_STATUS           0x80
+#define REG_COMMAND          0x80
+
 /* ATA error definitions not in <linux/hdreg.h> */
 #define ATA_ERROR_MEDIA_CHANGE       0x20
 
@@ -152,20 +166,8 @@
 	struct {
 		unsigned char SignatureByte0;
 		unsigned char SignatureByte1;
-		unsigned char ReadRegisterAccessBit : 1;
-		unsigned char NoDeviceSelectionBit : 1;
-		unsigned char NoBSYPollBit : 1;
-		unsigned char IgnorePhaseErrorBit : 1;
-		unsigned char IgnoreDeviceErrorBit : 1;
-		unsigned char Reserved0Bit : 3;
-		unsigned char SelectAlternateStatus : 1;
-		unsigned char SelectError : 1;
-		unsigned char SelectSectorCount : 1;
-		unsigned char SelectSectorNumber : 1;
-		unsigned char SelectCylinderLow : 1;
-		unsigned char SelectCylinderHigh : 1;
-		unsigned char SelectDeviceHead : 1;
-		unsigned char SelectStatus : 1;
+		unsigned char ActionSelect;
+		unsigned char RegisterSelect;
 		unsigned char TransferBlockSize;
 		unsigned char AlternateStatusByte;
 		unsigned char ErrorByte;
@@ -181,20 +183,8 @@
         struct {
 		unsigned char SignatureByte0;
 		unsigned char SignatureByte1;
-		unsigned char ReadRegisterAccessBit : 1;
-		unsigned char NoDeviceSelectionBit : 1;
-		unsigned char NoBSYPollBit : 1;
-		unsigned char IgnorePhaseErrorBit : 1;
-		unsigned char IgnoreDeviceErrorBit : 1;
-		unsigned char Reserved0Bit : 3;
-		unsigned char SelectDeviceControl : 1;
-		unsigned char SelectFeatures : 1;
-		unsigned char SelectSectorCount : 1;
-		unsigned char SelectSectorNumber : 1;
-		unsigned char SelectCylinderLow : 1;
-		unsigned char SelectCylinderHigh : 1;
-		unsigned char SelectDeviceHead : 1;
-		unsigned char SelectCommand : 1;
+		unsigned char ActionSelect;
+		unsigned char RegisterSelect;
 		unsigned char TransferBlockSize;
 		unsigned char DeviceControlByte;
 		unsigned char FeaturesByte;
@@ -218,27 +208,20 @@
  * includes fields through ProductRevisionLevel.
  */
 
+/*
+ * DeviceType field
+ */
+#define DIRECT_ACCESS_DEVICE            0x00    /* disks */
+#define DEVICE_REMOVABLE                0x80
+
 struct inquiry_data {
-	unsigned char DeviceType : 5;
-	unsigned char DeviceTypeQualifier : 3;
-	unsigned char DeviceTypeModifier : 7;
-	unsigned char RemovableMedia : 1;
+   	unsigned char DeviceType;
+	unsigned char DeviceTypeModifier;
 	unsigned char Versions;
-	unsigned char ResponseDataFormat : 4;
-	unsigned char HiSupport : 1;
-	unsigned char NormACA : 1;
-	unsigned char ReservedBit : 1;
-	unsigned char AERC : 1;
+	unsigned char Format; 
 	unsigned char AdditionalLength;
 	unsigned char Reserved[2];
-	unsigned char SoftReset : 1;
-	unsigned char CommandQueue : 1;
-	unsigned char Reserved2 : 1;
-	unsigned char LinkedCommands : 1;
-	unsigned char Synchronous : 1;
-	unsigned char Wide16Bit : 1;
-	unsigned char Wide32Bit : 1;
-	unsigned char RelativeAddressing : 1;
+	unsigned char Capability;
 	unsigned char VendorId[8];
 	unsigned char ProductId[16];
 	unsigned char ProductRevisionLevel[4];
@@ -257,25 +240,30 @@
  * ISD200 CONFIG data struct
  */
 
+#define ATACFG_TIMING          0x0f
+#define ATACFG_ATAPI_RESET     0x10
+#define ATACFG_MASTER          0x20
+#define ATACFG_BLOCKSIZE       0xa0
+
+#define ATACFGE_LAST_LUN       0x07
+#define ATACFGE_DESC_OVERRIDE  0x08
+#define ATACFGE_STATE_SUSPEND  0x10
+#define ATACFGE_SKIP_BOOT      0x20
+#define ATACFGE_CONF_DESC2     0x40
+#define ATACFGE_INIT_STATUS    0x80
+
+#define CFG_CAPABILITY_SRST    0x01
+
 struct isd200_config {
         unsigned char EventNotification;
         unsigned char ExternalClock;
         unsigned char ATAInitTimeout;
-        unsigned char ATATiming : 4;
-        unsigned char ATAPIReset : 1;
-        unsigned char MasterSlaveSelection : 1;
-        unsigned char ATAPICommandBlockSize : 2;
+	unsigned char ATAConfig;
         unsigned char ATAMajorCommand;
         unsigned char ATAMinorCommand;
-        unsigned char LastLUNIdentifier : 3;
-        unsigned char DescriptOverride : 1;
-        unsigned char ATA3StateSuspend : 1;
-        unsigned char SkipDeviceBoot : 1;
-        unsigned char ConfigDescriptor2 : 1;
-        unsigned char InitStatus : 1;
-        unsigned char SRSTEnable : 1;
-        unsigned char Reserved0 : 7;
-};
+	unsigned char ATAExtraConfig;
+	unsigned char Capability;
+}__attribute__ ((packed));
 
 
 /*
@@ -321,15 +309,16 @@
  * Sense Data Format
  */
 
+#define SENSE_ERRCODE           0x7f
+#define SENSE_ERRCODE_VALID     0x80
+#define SENSE_FLAG_SENSE_KEY    0x0f
+#define SENSE_FLAG_BAD_LENGTH   0x20
+#define SENSE_FLAG_END_OF_MEDIA 0x40
+#define SENSE_FLAG_FILE_MARK    0x80
 struct sense_data {
-        unsigned char ErrorCode:7;
-        unsigned char Valid:1;
-        unsigned char SegmentNumber;
-        unsigned char SenseKey:4;
-        unsigned char Reserved:1;
-        unsigned char IncorrectLength:1;
-        unsigned char EndOfMedia:1;
-        unsigned char FileMark:1;
+	unsigned char ErrorCode;
+	unsigned char SegmentNumber;
+	unsigned char Flags;
         unsigned char Information[4];
         unsigned char AdditionalSenseLength;
         unsigned char CommandSpecificInformation[4];
@@ -349,7 +338,6 @@
  * Helper routines
  ***********************************************************************/
 
-
 /**************************************************************************
  * isd200_build_sense
  *                                                                         
@@ -366,38 +354,33 @@
         unsigned char error = info->ATARegs[IDE_ERROR_OFFSET];
 
 	if(error & ATA_ERROR_MEDIA_CHANGE) {
-		buf->ErrorCode = 0x70;
-		buf->Valid     = 1;
+		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
-		buf->SenseKey =  UNIT_ATTENTION;
+		buf->Flags = UNIT_ATTENTION;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
         } else if(error & MCR_ERR) {
-		buf->ErrorCode = 0x70;
-		buf->Valid     = 1;
+		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
-		buf->SenseKey =  UNIT_ATTENTION;
+		buf->Flags =  UNIT_ATTENTION;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
         } else if(error & TRK0_ERR) {
-		buf->ErrorCode = 0x70;
-		buf->Valid     = 1;
+		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
-		buf->SenseKey =  NOT_READY;
+		buf->Flags =  NOT_READY;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
         } else if(error & ECC_ERR) {
-		buf->ErrorCode = 0x70;
-		buf->Valid     = 1;
+		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
-		buf->SenseKey =  DATA_PROTECT;
+		buf->Flags =  DATA_PROTECT;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
         } else {
 		buf->ErrorCode = 0;
-		buf->Valid     = 0;
 		buf->AdditionalSenseLength = 0;
-		buf->SenseKey =  0;
+		buf->Flags =  0;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
         }
@@ -442,7 +425,7 @@
         /* if we stall, we need to clear it before we go on */
         if (result == -EPIPE) {
                 US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
-                usb_stor_clear_halt(us->pusb_dev, pipe);
+                usb_stor_clear_halt(us, pipe);
         }
     
         /* did we send all the data? */
@@ -593,7 +576,7 @@
         US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
                   le32_to_cpu(bcb.Signature), bcb.Tag,
                   (bcb.Lun >> 4), (bcb.Lun & 0xFF), 
-                  bcb.DataTransferLength, bcb.Flags, bcb.Length);
+                  le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length);
         result = usb_stor_bulk_msg(us, &bcb, pipe, US_BULK_CB_WRAP_LEN, 
 				   &partial);
         US_DEBUGP("Bulk command transfer result=%d\n", result);
@@ -603,7 +586,7 @@
 	else if (result == -EPIPE) {
 		/* if we stall, we need to clear it before we go on */
                 US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
-                usb_stor_clear_halt(us->pusb_dev, pipe);
+                usb_stor_clear_halt(us, pipe);
 	} else if (result)  
                 return ISD200_TRANSPORT_ERROR;
     
@@ -633,7 +616,7 @@
         /* did the attempt to read the CSW fail? */
         if (result == -EPIPE) {
                 US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
-                usb_stor_clear_halt(us->pusb_dev, pipe);
+                usb_stor_clear_halt(us, pipe);
            
                 /* get the status again */
                 US_DEBUGP("Attempting to get CSW (2nd try)...\n");
@@ -647,7 +630,7 @@
                 /* if it fails again, we need a reset and return an error*/
                 if (result == -EPIPE) {
                         US_DEBUGP("clearing halt for pipe 0x%x\n", pipe);
-                        usb_stor_clear_halt(us->pusb_dev, pipe);
+                        usb_stor_clear_halt(us, pipe);
                         return ISD200_TRANSPORT_ERROR;
                 }
         }
@@ -716,10 +699,9 @@
 	case ACTION_READ_STATUS:
 		US_DEBUGP("   isd200_action(READ_STATUS)\n");
 		ata.generic.ActionSelect = ACTION_SELECT_0|ACTION_SELECT_2;
-		ata.read.SelectStatus = 1;
-		ata.read.SelectError = 1;
-		ata.read.SelectCylinderHigh = 1;
-		ata.read.SelectCylinderLow = 1;
+		ata.generic.RegisterSelect =
+		  REG_CYLINDER_LOW | REG_CYLINDER_HIGH |
+		  REG_STATUS | REG_ERROR;
 		srb.sc_data_direction = SCSI_DATA_READ;
 		srb.request_buffer = pointer;
 		srb.request_bufflen = value;
@@ -730,7 +712,7 @@
 		ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
 			                   ACTION_SELECT_3|ACTION_SELECT_4|
 		                           ACTION_SELECT_5;
-		ata.write.SelectDeviceHead = 1;
+		ata.generic.RegisterSelect = REG_DEVICE_HEAD;
 		ata.write.DeviceHeadByte = value;
 		srb.sc_data_direction = SCSI_DATA_NONE;
 		break;
@@ -739,7 +721,7 @@
 		US_DEBUGP("   isd200_action(RESET)\n");
 		ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
 			                   ACTION_SELECT_3|ACTION_SELECT_4;
-		ata.write.SelectDeviceControl = 1;
+		ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
 		ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER;
 		srb.sc_data_direction = SCSI_DATA_NONE;
 		break;
@@ -748,7 +730,7 @@
 		US_DEBUGP("   isd200_action(REENABLE)\n");
 		ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
 			                   ACTION_SELECT_3|ACTION_SELECT_4;
-		ata.write.SelectDeviceControl = 1;
+		ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
 		ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER;
 		srb.sc_data_direction = SCSI_DATA_NONE;
 		break;
@@ -756,16 +738,15 @@
 	case ACTION_SOFT_RESET:
 		US_DEBUGP("   isd200_action(SOFT_RESET)\n");
 		ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_5;
-		ata.write.SelectDeviceHead = 1;
+		ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND;
 		ata.write.DeviceHeadByte = info->DeviceHead;
-		ata.write.SelectCommand = 1;
 		ata.write.CommandByte = WIN_SRST;
 		srb.sc_data_direction = SCSI_DATA_NONE;
 		break;
 
 	case ACTION_IDENTIFY:
 		US_DEBUGP("   isd200_action(IDENTIFY)\n");
-		ata.write.SelectCommand = 1;
+		ata.generic.RegisterSelect = REG_COMMAND;
 		ata.write.CommandByte = WIN_IDENTIFY;
 		srb.sc_data_direction = SCSI_DATA_READ;
 		srb.request_buffer = (void *)&info->drive;
@@ -821,7 +802,7 @@
  * Invoke the transport and basic error-handling/recovery methods
  *
  * This is used by the protocol layers to actually send the message to
- * the device and recieve the response.
+ * the device and receive the response.
  */
 void isd200_invoke_transport( struct us_data *us, 
 			      Scsi_Cmnd *srb, 
@@ -886,6 +867,43 @@
 		srb->result = CHECK_CONDITION;
 }
 
+#ifdef CONFIG_USB_STORAGE_DEBUG
+static void isd200_log_config( struct isd200_info* info )
+{
+	US_DEBUGP("      Event Notification: 0x%x\n", 
+		  info->ConfigData.EventNotification);
+	US_DEBUGP("      External Clock: 0x%x\n", 
+		  info->ConfigData.ExternalClock);
+	US_DEBUGP("      ATA Init Timeout: 0x%x\n", 
+		  info->ConfigData.ATAInitTimeout);
+	US_DEBUGP("      ATAPI Command Block Size: 0x%x\n", 
+		  (info->ConfigData.ATAConfig & ATACFG_BLOCKSIZE) >> 6);
+	US_DEBUGP("      Master/Slave Selection: 0x%x\n", 
+		  info->ConfigData.ATAConfig & ATACFG_MASTER);
+	US_DEBUGP("      ATAPI Reset: 0x%x\n",
+		  info->ConfigData.ATAConfig & ATACFG_ATAPI_RESET);
+	US_DEBUGP("      ATA Timing: 0x%x\n",
+		  info->ConfigData.ATAConfig & ATACFG_TIMING);
+	US_DEBUGP("      ATA Major Command: 0x%x\n", 
+		  info->ConfigData.ATAMajorCommand);
+	US_DEBUGP("      ATA Minor Command: 0x%x\n", 
+		  info->ConfigData.ATAMinorCommand);
+	US_DEBUGP("      Init Status: 0x%x\n", 
+		  info->ConfigData.ATAExtraConfig & ATACFGE_INIT_STATUS);
+	US_DEBUGP("      Config Descriptor 2: 0x%x\n", 
+		  info->ConfigData.ATAExtraConfig & ATACFGE_CONF_DESC2);
+	US_DEBUGP("      Skip Device Boot: 0x%x\n",
+		  info->ConfigData.ATAExtraConfig & ATACFGE_SKIP_BOOT);
+	US_DEBUGP("      ATA 3 State Supsend: 0x%x\n",
+		  info->ConfigData.ATAExtraConfig & ATACFGE_STATE_SUSPEND);
+	US_DEBUGP("      Descriptor Override: 0x%x\n", 
+		  info->ConfigData.ATAExtraConfig & ATACFGE_DESC_OVERRIDE);
+	US_DEBUGP("      Last LUN Identifier: 0x%x\n",
+		  info->ConfigData.ATAExtraConfig & ATACFGE_LAST_LUN);
+	US_DEBUGP("      SRST Enable: 0x%x\n", 
+		  info->ConfigData.ATAExtraConfig & CFG_CAPABILITY_SRST);
+}
+#endif
 
 /**************************************************************************
  * isd200_write_config
@@ -901,26 +919,11 @@
 	int retStatus = ISD200_GOOD;
 	int result;
 
-
+#ifdef CONFIG_USB_STORAGE_DEBUG
 	US_DEBUGP("Entering isd200_write_config\n");
-
 	US_DEBUGP("   Writing the following ISD200 Config Data:\n");
-	US_DEBUGP("      Event Notification: 0x%x\n", info->ConfigData.EventNotification);
-	US_DEBUGP("      External Clock: 0x%x\n", info->ConfigData.ExternalClock);
-	US_DEBUGP("      ATA Init Timeout: 0x%x\n", info->ConfigData.ATAInitTimeout);
-	US_DEBUGP("      ATAPI Command Block Size: 0x%x\n", info->ConfigData.ATAPICommandBlockSize);
-	US_DEBUGP("      Master/Slave Selection: 0x%x\n", info->ConfigData.MasterSlaveSelection);
-	US_DEBUGP("      ATAPI Reset: 0x%x\n", info->ConfigData.ATAPIReset);
-	US_DEBUGP("      ATA Timing: 0x%x\n", info->ConfigData.ATATiming);
-	US_DEBUGP("      ATA Major Command: 0x%x\n", info->ConfigData.ATAMajorCommand);
-	US_DEBUGP("      ATA Minor Command: 0x%x\n", info->ConfigData.ATAMinorCommand);
-	US_DEBUGP("      Init Status: 0x%x\n", info->ConfigData.InitStatus);
-	US_DEBUGP("      Config Descriptor 2: 0x%x\n", info->ConfigData.ConfigDescriptor2);
-	US_DEBUGP("      Skip Device Boot: 0x%x\n", info->ConfigData.SkipDeviceBoot);
-	US_DEBUGP("      ATA 3 State Supsend: 0x%x\n", info->ConfigData.ATA3StateSuspend);
-	US_DEBUGP("      Descriptor Override: 0x%x\n", info->ConfigData.DescriptOverride);
-	US_DEBUGP("      Last LUN Identifier: 0x%x\n", info->ConfigData.LastLUNIdentifier);
-	US_DEBUGP("      SRST Enable: 0x%x\n", info->ConfigData.SRSTEnable);
+	isd200_log_config(info);
+#endif
 
 	/* let's send the command via the control pipe */
 	result = usb_stor_control_msg(
@@ -941,8 +944,8 @@
 		/* STALL must be cleared when they are detected */
 		if (result == -EPIPE) {
 			US_DEBUGP("-- Stall on control pipe. Clearing\n");
-			result = usb_stor_clear_halt(us->pusb_dev,
-						     usb_sndctrlpipe(us->pusb_dev, 0));
+			result = usb_stor_clear_halt(us,
+					usb_sndctrlpipe(us->pusb_dev, 0));
 			US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result);
 
 		}
@@ -986,30 +989,17 @@
 
 	if (result >= 0) {
 		US_DEBUGP("   Retrieved the following ISD200 Config Data:\n");
-		US_DEBUGP("      Event Notification: 0x%x\n", info->ConfigData.EventNotification);
-		US_DEBUGP("      External Clock: 0x%x\n", info->ConfigData.ExternalClock);
-		US_DEBUGP("      ATA Init Timeout: 0x%x\n", info->ConfigData.ATAInitTimeout);
-		US_DEBUGP("      ATAPI Command Block Size: 0x%x\n", info->ConfigData.ATAPICommandBlockSize);
-		US_DEBUGP("      Master/Slave Selection: 0x%x\n", info->ConfigData.MasterSlaveSelection);
-		US_DEBUGP("      ATAPI Reset: 0x%x\n", info->ConfigData.ATAPIReset);
-		US_DEBUGP("      ATA Timing: 0x%x\n", info->ConfigData.ATATiming);
-		US_DEBUGP("      ATA Major Command: 0x%x\n", info->ConfigData.ATAMajorCommand);
-		US_DEBUGP("      ATA Minor Command: 0x%x\n", info->ConfigData.ATAMinorCommand);
-		US_DEBUGP("      Init Status: 0x%x\n", info->ConfigData.InitStatus);
-		US_DEBUGP("      Config Descriptor 2: 0x%x\n", info->ConfigData.ConfigDescriptor2);
-		US_DEBUGP("      Skip Device Boot: 0x%x\n", info->ConfigData.SkipDeviceBoot);
-		US_DEBUGP("      ATA 3 State Supsend: 0x%x\n", info->ConfigData.ATA3StateSuspend);
-		US_DEBUGP("      Descriptor Override: 0x%x\n", info->ConfigData.DescriptOverride);
-		US_DEBUGP("      Last LUN Identifier: 0x%x\n", info->ConfigData.LastLUNIdentifier);
-		US_DEBUGP("      SRST Enable: 0x%x\n", info->ConfigData.SRSTEnable);
+#ifdef CONFIG_USB_STORAGE_DEBUG
+		isd200_log_config(info);
+#endif
         } else {
 		US_DEBUGP("   Request to get ISD200 Config Data failed!\n");
 
 		/* STALL must be cleared when they are detected */
 		if (result == -EPIPE) {
 			US_DEBUGP("-- Stall on control pipe. Clearing\n");
-			result = usb_stor_clear_halt(us->pusb_dev,   
-						     usb_sndctrlpipe(us->pusb_dev, 0));
+			result = usb_stor_clear_halt(us,   
+					usb_sndctrlpipe(us->pusb_dev, 0));
 			US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result);
 
 		}
@@ -1175,11 +1165,12 @@
 				break;
 			}
 		} else {
-			US_DEBUGP("   Not ATA, not ATAPI. Weird.\n");
+ 			US_DEBUGP("   Not ATA, not ATAPI. Weird.\n");
+			break;
 		}
 
 		/* check for timeout on this request */
-		if (jiffies >= endTime) {
+		if (time_after_eq(jiffies, endTime)) {
 			if (!detect)
 				US_DEBUGP("   BSY check timeout, just continue with next operation...\n");
 			else
@@ -1223,9 +1214,10 @@
 		}
 
 		isslave = (info->DeviceHead & ATA_ADDRESS_DEVHEAD_SLAVE) ? 1 : 0;
-		if (info->ConfigData.MasterSlaveSelection != isslave) {
+		if (!(info->ConfigData.ATAConfig & ATACFG_MASTER)) {
 			US_DEBUGP("   Setting Master/Slave selection to %d\n", isslave);
-			info->ConfigData.MasterSlaveSelection = isslave;
+			info->ConfigData.ATAConfig &= 0x3f;
+			info->ConfigData.ATAConfig |= (isslave<<6);
 			retStatus = isd200_write_config(us);
 		}
 	}
@@ -1272,6 +1264,8 @@
 			} else {
 				/* ATA Command Identify successful */
 				int i;
+				__u16 *src, *dest;
+				ide_fix_driveid(&info->drive);
 
 				US_DEBUGP("   Identify Data Structure:\n");
 				US_DEBUGP("      config = 0x%x\n", info->drive.config);
@@ -1317,31 +1311,25 @@
 
 				if (info->drive.command_set_1 & COMMANDSET_MEDIA_STATUS) {
 					/* set the removable bit */
-					info->InquiryData.RemovableMedia = 1;
+					info->InquiryData.DeviceTypeModifier = DEVICE_REMOVABLE;
 					info->DeviceFlags |= DF_REMOVABLE_MEDIA;
 				}
 
 				/* Fill in vendor identification fields */
-				for (i = 0; i < 20; i += 2) {
-					info->InquiryData.VendorId[i] = 
-						info->drive.model[i + 1];
-					info->InquiryData.VendorId[i+1] = 
-						info->drive.model[i];
-				}
-
-				/* Initialize unused portion of product id */
-				for (i = 0; i < 4; i++) {
-					info->InquiryData.ProductId[12+i] = ' ';
-				}
-
-				/* Move firmware revision from IDENTIFY data to */
-				/* product revision in INQUIRY data             */
-				for (i = 0; i < 4; i += 2) {
-					info->InquiryData.ProductRevisionLevel[i] =
-						info->drive.fw_rev[i+1];
-					info->InquiryData.ProductRevisionLevel[i+1] =
-						info->drive.fw_rev[i];
-				}
+				src = (__u16*)info->drive.model;
+				dest = (__u16*)info->InquiryData.VendorId;
+				for (i=0;i<4;i++)
+					dest[i] = be16_to_cpu(src[i]);
+
+				src = (__u16*)(info->drive.model+8);
+				dest = (__u16*)info->InquiryData.ProductId;
+				for (i=0;i<8;i++)
+					dest[i] = be16_to_cpu(src[i]);
+
+				src = (__u16*)info->drive.fw_rev;
+				dest = (__u16*)info->InquiryData.ProductRevisionLevel;
+				for (i=0;i<2;i++)
+					dest[i] = be16_to_cpu(src[i]);
 
 				/* determine if it supports Media Status Notification */
 				if (info->drive.command_set_2 & COMMANDSET_MEDIA_STATUS) {
@@ -1483,7 +1471,7 @@
 			ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 			ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
 			ataCdb->generic.TransferBlockSize = 1;
-			ataCdb->write.SelectCommand = 1;
+			ataCdb->generic.RegisterSelect = REG_COMMAND;
 			ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
 			srb->request_bufflen = 0;
 		} else {
@@ -1504,7 +1492,7 @@
 			ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 			ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
 			ataCdb->generic.TransferBlockSize = 1;
-			ataCdb->write.SelectCommand = 1;
+			ataCdb->generic.RegisterSelect = REG_COMMAND;
 			ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
 			srb->request_bufflen = 0;
 		} else {
@@ -1561,17 +1549,15 @@
 		ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 		ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
 		ataCdb->generic.TransferBlockSize = 1;
-		ataCdb->write.SelectSectorCount = 1;
+		ataCdb->generic.RegisterSelect =
+		  REG_SECTOR_COUNT | REG_SECTOR_NUMBER |
+		  REG_CYLINDER_LOW | REG_CYLINDER_HIGH |
+		  REG_DEVICE_HEAD  | REG_COMMAND;
 		ataCdb->write.SectorCountByte = (unsigned char)blockCount;
-		ataCdb->write.SelectSectorNumber = 1;
 		ataCdb->write.SectorNumberByte = sectnum;
-		ataCdb->write.SelectCylinderHigh = 1;
 		ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
-		ataCdb->write.SelectCylinderLow = 1;
 		ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
-		ataCdb->write.SelectDeviceHead = 1;
 		ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
-		ataCdb->write.SelectCommand = 1;
 		ataCdb->write.CommandByte = WIN_READ;
 		break;
 
@@ -1594,17 +1580,15 @@
 		ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 		ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
 		ataCdb->generic.TransferBlockSize = 1;
-		ataCdb->write.SelectSectorCount = 1;
+		ataCdb->generic.RegisterSelect =
+		  REG_SECTOR_COUNT | REG_SECTOR_NUMBER |
+		  REG_CYLINDER_LOW | REG_CYLINDER_HIGH |
+		  REG_DEVICE_HEAD  | REG_COMMAND;
 		ataCdb->write.SectorCountByte = (unsigned char)blockCount;
-		ataCdb->write.SelectSectorNumber = 1;
 		ataCdb->write.SectorNumberByte = sectnum;
-		ataCdb->write.SelectCylinderHigh = 1;
 		ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
-		ataCdb->write.SelectCylinderLow = 1;
 		ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
-		ataCdb->write.SelectDeviceHead = 1;
 		ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
-		ataCdb->write.SelectCommand = 1;
 		ataCdb->write.CommandByte = WIN_WRITE;
 		break;
 
@@ -1617,7 +1601,7 @@
 			ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 			ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
 			ataCdb->generic.TransferBlockSize = 1;
-			ataCdb->write.SelectCommand = 1;
+			ataCdb->generic.RegisterSelect = REG_COMMAND;
 			ataCdb->write.CommandByte = (srb->cmnd[4] & 0x1) ?
 				WIN_DOORLOCK : WIN_DOORUNLOCK;
 			srb->request_bufflen = 0;
@@ -1640,14 +1624,14 @@
 			ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 			ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
 			ataCdb->generic.TransferBlockSize = 0;
-			ataCdb->write.SelectCommand = 1;
+			ataCdb->generic.RegisterSelect = REG_COMMAND;
 			ataCdb->write.CommandByte = ATA_COMMAND_MEDIA_EJECT;
 		} else if ((srb->cmnd[4] & 0x3) == 0x1) {
 			US_DEBUGP("   Get Media Status\n");
 			ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 			ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
 			ataCdb->generic.TransferBlockSize = 1;
-			ataCdb->write.SelectCommand = 1;
+			ataCdb->generic.RegisterSelect = REG_COMMAND;
 			ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
 			srb->request_bufflen = 0;
 		} else {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/jumpshot.c linux/drivers/usb/storage/jumpshot.c
--- linux.orig/drivers/usb/storage/jumpshot.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/jumpshot.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,16 +1,26 @@
 /* Driver for Lexar "Jumpshot" Compact Flash reader
  *
+ * $Id: jumpshot.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $
+ *
  * jumpshot driver v0.1:
  *
  * First release
  *
  * Current development and maintenance by:
  *   (c) 2000 Jimmie Mayfield (mayfield+usb@sackheads.org)
- *   many thanks to Robert Baruch for the SanDisk SmartMedia reader driver
+ *
+ *   Many thanks to Robert Baruch for the SanDisk SmartMedia reader driver
  *   which I used as a template for this driver.
+ *
  *   Some bugfixes and scatter-gather code by Gregory P. Smith 
  *   (greg-usb@electricrain.com)
  *
+ *   Fix for media change by Joerg Schneider (js@joergschneider.com)
+ *
+ * Developed with the assistance of:
+ *
+ *   (C) 2002 Alan Stern <stern@rowland.org>
+ *
  * 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, or (at your option) any
@@ -128,8 +138,8 @@
 		/* a stall is a fatal condition from the device */
 		if (result == -EPIPE) {
 			US_DEBUGP("jumpshot_send_control:  -- Stall on control pipe. Clearing\n");
-			result = usb_clear_halt(us->pusb_dev, pipe);
-			US_DEBUGP("jumpshot_send_control:  -- usb_clear_halt() returns %d\n", result);
+			result = usb_stor_clear_halt(us, pipe);
+			US_DEBUGP("jumpshot_send_control:  -- usb_stor_clear_halt() returns %d\n", result);
 			return USB_STOR_TRANSPORT_FAILED;
 		}
 
@@ -161,7 +171,7 @@
 	if (result == -EPIPE) {
 		US_DEBUGP("jumpshot_raw_bulk:  EPIPE. clearing endpoint halt for"
 			  " pipe 0x%x, stalled at %d bytes\n", pipe, act_len);
-		usb_clear_halt(us->pusb_dev, pipe);
+		usb_stor_clear_halt(us, pipe);
 	}
 
 	if (result) {
@@ -798,6 +808,23 @@
 		//
 		return USB_STOR_TRANSPORT_GOOD;
 	}
+	
+	if (srb->cmnd[0] == START_STOP) {
+		/* this is used by sd.c'check_scsidisk_media_change to detect
+		   media change */
+		US_DEBUGP("jumpshot_transport:  START_STOP.\n");
+		/* the first jumpshot_id_device after a media change returns
+		   an error (determined experimentally) */
+		rc = jumpshot_id_device(us, info);
+		if (rc == USB_STOR_TRANSPORT_GOOD) {
+			info->sense_key = NO_SENSE;
+			srb->result = SUCCESS;
+		} else {
+			info->sense_key = UNIT_ATTENTION;
+			srb->result = CHECK_CONDITION;
+		}
+		return rc;
+        }
 
 	US_DEBUGP("jumpshot_transport:  Gah! Unknown command: %d (0x%x)\n", srb->cmnd[0], srb->cmnd[0]);
 	return USB_STOR_TRANSPORT_ERROR;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/protocol.c linux/drivers/usb/storage/protocol.c
--- linux.orig/drivers/usb/storage/protocol.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/protocol.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,12 +1,13 @@
 /* Driver for USB Mass Storage compliant devices
  *
- * $Id: protocol.c,v 1.11 2002/01/13 06:40:25 mdharm Exp $
+ * $Id: protocol.c,v 1.13 2002/02/25 00:34:56 mdharm Exp $
  *
  * Current development and maintenance by:
- *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
  * Developed with the assistance of:
  *   (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
+ *   (c) 2002 Alan Stern (stern@rowland.org)
  *
  * Initial work by:
  *   (c) 1999 Michael Gee (michael@linuxspecific.com)
@@ -97,9 +98,11 @@
 
 	/* send the command to the transport layer */
 	usb_stor_invoke_transport(srb, us);
+	if (srb->result == GOOD << 1) {
 
-	/* fix the INQUIRY data if necessary */
-	fix_inquiry_data(srb);
+		/* fix the INQUIRY data if necessary */
+		fix_inquiry_data(srb);
+	}
 }
 
 void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us)
@@ -168,13 +171,15 @@
 
 	/* send the command to the transport layer */
 	usb_stor_invoke_transport(srb, us);
+	if (srb->result == GOOD << 1) {
 
-	/* Fix the MODE_SENSE data if we translated the command */
-	if ((old_cmnd == MODE_SENSE) && (status_byte(srb->result) == GOOD))
-		usb_stor_scsiSense10to6(srb);
-
-	/* fix the INQUIRY data if necessary */
-	fix_inquiry_data(srb);
+		/* Fix the MODE_SENSE data if we translated the command */
+		if (old_cmnd == MODE_SENSE)
+			usb_stor_scsiSense10to6(srb);
+
+		/* fix the INQUIRY data if necessary */
+		fix_inquiry_data(srb);
+	}
 }
 
 
@@ -263,13 +268,15 @@
 
 	/* send the command to the transport layer */
 	usb_stor_invoke_transport(srb, us);
+	if (srb->result == GOOD << 1) {
 
-	/* Fix the MODE_SENSE data if we translated the command */
-	if ((old_cmnd == MODE_SENSE) && (status_byte(srb->result) == GOOD))
-		usb_stor_scsiSense10to6(srb);
-
-	/* Fix the data for an INQUIRY, if necessary */
-	fix_inquiry_data(srb);
+		/* Fix the MODE_SENSE data if we translated the command */
+		if (old_cmnd == MODE_SENSE)
+			usb_stor_scsiSense10to6(srb);
+
+		/* Fix the data for an INQUIRY, if necessary */
+		fix_inquiry_data(srb);
+	}
 }
 
 void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
@@ -330,13 +337,14 @@
 
 	/* send the command to the transport layer */
 	usb_stor_invoke_transport(srb, us);
+	if (srb->result == GOOD << 1) {
 
-	/* Fix the MODE_SENSE data if we translated the command */
-	if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SENSE)
-			&& (status_byte(srb->result) == GOOD))
-		usb_stor_scsiSense10to6(srb);
-
-	/* fix the INQUIRY data if necessary */
-	fix_inquiry_data(srb);
+		/* Fix the MODE_SENSE data if we translated the command */
+		if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SENSE))
+			usb_stor_scsiSense10to6(srb);
+
+		/* fix the INQUIRY data if necessary */
+		fix_inquiry_data(srb);
+	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/sddr09.c linux/drivers/usb/storage/sddr09.c
--- linux.orig/drivers/usb/storage/sddr09.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/sddr09.c	2002-07-20 01:08:39.000000000 +0000
@@ -1,6 +1,6 @@
 /* Driver for SanDisk SDDR-09 SmartMedia reader
  *
- * $Id: sddr09.c,v 1.22 2001/12/08 23:32:48 mdharm Exp $
+ * $Id: sddr09.c,v 1.23 2002/02/25 00:40:13 mdharm Exp $
  *
  * SDDR09 driver v0.1:
  *
@@ -9,6 +9,9 @@
  * Current development and maintenance by:
  *   (c) 2000, 2001 Robert Baruch (autophile@starband.net)
  *
+ * Developed with the assistance of:
+ *   (c) 2002 Alan Stern <stern@rowland.org>
+ *
  * The SanDisk SDDR-09 SmartMedia reader uses the Shuttle EUSB-01 chip.
  * This chip is a programmable USB controller. In the SDDR-09, it has
  * been programmed to obey a certain limited set of SCSI commands. This
@@ -113,8 +116,8 @@
 		/* a stall is a fatal condition from the device */
 		if (result == -EPIPE) {
 			US_DEBUGP("-- Stall on control pipe. Clearing\n");
-			result = usb_clear_halt(us->pusb_dev, pipe);
-			US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
+			result = usb_stor_clear_halt(us, pipe);
+			US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result);
 			return USB_STOR_TRANSPORT_FAILED;
 		}
 
@@ -146,7 +149,7 @@
        	        US_DEBUGP("EPIPE: clearing endpoint halt for"
 			" pipe 0x%x, stalled at %d bytes\n",
 			pipe, act_len);
-               	usb_clear_halt(us->pusb_dev, pipe);
+               	usb_stor_clear_halt(us, pipe);
         }
 
 	if (result) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/shuttle_usbat.c linux/drivers/usb/storage/shuttle_usbat.c
--- linux.orig/drivers/usb/storage/shuttle_usbat.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/shuttle_usbat.c	2002-07-20 01:08:22.000000000 +0000
@@ -1,10 +1,13 @@
 /* Driver for SCM Microsystems USB-ATAPI cable
  *
- * $Id: shuttle_usbat.c,v 1.15 2001/12/08 23:32:48 mdharm Exp $
+ * $Id: shuttle_usbat.c,v 1.16 2002/02/25 00:40:13 mdharm Exp $
  *
  * Current development and maintenance by:
  *   (c) 2000, 2001 Robert Baruch (autophile@starband.net)
  *
+ * Developed with the assistance of:
+ *   (c) 2002 Alan Stern <stern@rowland.org>
+ *
  * Many originally ATAPI devices were slightly modified to meet the USB
  * market by using some kind of translation from ATAPI to USB on the host,
  * and the peripheral would translate from USB back to ATAPI.
@@ -107,8 +110,8 @@
 		/* a stall is a fatal condition from the device */
 		if (result == -EPIPE) {
 			US_DEBUGP("-- Stall on control pipe. Clearing\n");
-			result = usb_clear_halt(us->pusb_dev, pipe);
-			US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
+			result = usb_stor_clear_halt(us, pipe);
+			US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result);
 			return USB_STOR_TRANSPORT_FAILED;
 		}
 
@@ -140,7 +143,7 @@
        	        US_DEBUGP("EPIPE: clearing endpoint halt for"
 			" pipe 0x%x, stalled at %d bytes\n",
 			pipe, act_len);
-               	usb_clear_halt(us->pusb_dev, pipe);
+               	usb_stor_clear_halt(us, pipe);
         }
 
 	if (result) {
@@ -515,7 +518,7 @@
 			 */
 
 			if (direction==SCSI_DATA_READ && i==0)
-				usb_clear_halt(us->pusb_dev,
+				usb_stor_clear_halt(us,
 					usb_sndbulkpipe(us->pusb_dev,
 					  us->ep_out));
 			/*
@@ -675,9 +678,15 @@
 		len = short_pack(data[7+9], data[7+8]);
 		len <<= 16;
 		len |= data[7+7];
+		US_DEBUGP("handle_read10: GPCMD_READ_CD: len %d\n", len);
 		srb->transfersize = srb->request_bufflen/len;
 	}
 
+	if (!srb->transfersize)  {
+		srb->transfersize = 2048; /* A guess */
+		US_DEBUGP("handle_read10: transfersize 0, forcing %d\n",
+			srb->transfersize);
+	}
 
 	len = (65535/srb->transfersize) * srb->transfersize;
 	US_DEBUGP("Max read is %d bytes\n", len);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/transport.c linux/drivers/usb/storage/transport.c
--- linux.orig/drivers/usb/storage/transport.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/transport.c	2002-07-20 01:08:33.000000000 +0000
@@ -1,13 +1,14 @@
 /* Driver for USB Mass Storage compliant devices
  *
- * $Id: transport.c,v 1.42 2001/12/08 23:32:48 mdharm Exp $
+ * $Id: transport.c,v 1.44 2002/02/25 00:43:41 mdharm Exp $
  *
  * Current development and maintenance by:
- *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
  * Developed with the assistance of:
  *   (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
  *   (c) 2000 Stephen J. Gowdy (SGowdy@lbl.gov)
+ *   (c) 2002 Alan Stern <stern@rowland.org>
  *
  * Initial work by:
  *   (c) 1999 Michael Gee (michael@linuxspecific.com)
@@ -335,31 +336,7 @@
 			   len = srb->request_bufflen;
 	   }
 
-return len;
-}
-
-/* This is a version of usb_clear_halt() that doesn't read the status from
- * the device -- this is because some devices crash their internal firmware
- * when the status is requested after a halt
- */
-int usb_stor_clear_halt(struct usb_device *dev, int pipe)
-{
-	int result;
-	int endp = usb_pipeendpoint(pipe) | (usb_pipein(pipe) << 7);
-
-	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-				 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0,
-				 endp, NULL, 0, HZ * 3);
-
-	/* this is a failure case */
-	if (result < 0)
-		return result;
-
-	/* reset the toggles and endpoint flags */
-	usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
-	usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
-
-	return 0;
+	return len;
 }
 
 /***********************************************************************
@@ -481,6 +458,34 @@
 	return us->current_urb->status;
 }
 
+/* This is a version of usb_clear_halt() that doesn't read the status from
+ * the device -- this is because some devices crash their internal firmware
+ * when the status is requested after a halt
+ */
+int usb_stor_clear_halt(struct us_data *us, int pipe)
+{
+	int result;
+	int endp = usb_pipeendpoint(pipe) | (usb_pipein(pipe) << 7);
+
+	result = usb_stor_control_msg(us,
+		usb_sndctrlpipe(us->pusb_dev, 0),
+		USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0,
+		endp, NULL, 0);		/* note: no 3*HZ timeout */
+	US_DEBUGP("usb_stor_clear_halt: result=%d\n", result);
+
+	/* this is a failure case */
+	if (result < 0)
+		return result;
+
+	/* reset the toggles and endpoint flags */
+	usb_endpoint_running(us->pusb_dev, usb_pipeendpoint(pipe),
+		usb_pipeout(pipe));
+	usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
+		usb_pipeout(pipe), 0);
+
+	return 0;
+}
+
 /*
  * Transfer one SCSI scatter-gather buffer via bulk transfer
  *
@@ -513,7 +518,13 @@
 	/* if we stall, we need to clear it before we go on */
 	if (result == -EPIPE) {
 		US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
-		usb_stor_clear_halt(us->pusb_dev, pipe);
+		usb_stor_clear_halt(us, pipe);
+	}
+
+	/* did we abort this command? */
+	if (result == -ENOENT) {
+		US_DEBUGP("usb_stor_transfer_partial(): transfer aborted\n");
+		return US_BULK_TRANSFER_ABORTED;
 	}
 
 	/* did we send all the data? */
@@ -522,21 +533,14 @@
 		return US_BULK_TRANSFER_GOOD;
 	}
 
-	/* uh oh... we have an error code, so something went wrong. */
-	if (result) {
-		/* NAK - that means we've retried a few times already */
-		if (result == -ETIMEDOUT) {
-			US_DEBUGP("usb_stor_transfer_partial(): device NAKed\n");
-			return US_BULK_TRANSFER_FAILED;
-		}
-
-		/* -ENOENT -- we canceled this transfer */
-		if (result == -ENOENT) {
-			US_DEBUGP("usb_stor_transfer_partial(): transfer aborted\n");
-			return US_BULK_TRANSFER_ABORTED;
-		}
+	/* NAK - that means we've retried a few times already */
+	if (result == -ETIMEDOUT) {
+		US_DEBUGP("usb_stor_transfer_partial(): device NAKed\n");
+		return US_BULK_TRANSFER_FAILED;
+	}
 
-		/* the catch-all case */
+	/* the catch-all error case */
+	if (result) {
 		US_DEBUGP("usb_stor_transfer_partial(): unknown error\n");
 		return US_BULK_TRANSFER_FAILED;
 	}
@@ -550,7 +554,7 @@
  * Transfer an entire SCSI command's worth of data payload over the bulk
  * pipe.
  *
- * Note that this uses usb_stor_transfer_partial to achieve it's goals -- this
+ * Note that this uses usb_stor_transfer_partial to achieve its goals -- this
  * function simply determines if we're going to use scatter-gather or not,
  * and acts appropriately.  For now, it also re-interprets the error codes.
  */
@@ -612,7 +616,7 @@
 /* Invoke the transport and basic error-handling/recovery methods
  *
  * This is used by the protocol layers to actually send the message to
- * the device and recieve the response.
+ * the device and receive the response.
  */
 void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
 {
@@ -631,6 +635,14 @@
 		return;
 	}
 
+	/* if there is a transport error, reset and don't auto-sense */
+	if (result == USB_STOR_TRANSPORT_ERROR) {
+		US_DEBUGP("-- transport indicates error, resetting\n");
+		us->transport_reset(us);
+		srb->result = DID_ERROR << 16;
+		return;
+	}
+
 	/* Determine if we need to auto-sense
 	 *
 	 * I normally don't use a flag like this, but it's almost impossible
@@ -660,7 +672,7 @@
 	}
 
 	/*
-	 * If we have an error, we're going to do a REQUEST_SENSE 
+	 * If we have a failure, we're going to do a REQUEST_SENSE 
 	 * automatically.  Note that we differentiate between a command
 	 * "failure" and an "error" in the transport mechanism.
 	 */
@@ -668,13 +680,6 @@
 		US_DEBUGP("-- transport indicates command failure\n");
 		need_auto_sense = 1;
 	}
-	if (result == USB_STOR_TRANSPORT_ERROR) {
-		us->transport_reset(us);
-		US_DEBUGP("-- transport indicates transport failure\n");
-		need_auto_sense = 0;
-		srb->result = DID_ERROR << 16;
-		return;
-	}
 
 	/*
 	 * Also, if we have a short transfer on a command that can't have
@@ -730,6 +735,19 @@
 
 		/* issue the auto-sense command */
 		temp_result = us->transport(us->srb, us);
+
+		/* let's clean up right away */
+		srb->request_buffer = old_request_buffer;
+		srb->request_bufflen = old_request_bufflen;
+		srb->use_sg = old_sg;
+		srb->sc_data_direction = old_sc_data_direction;
+		memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
+
+		if (temp_result == USB_STOR_TRANSPORT_ABORTED) {
+			US_DEBUGP("-- auto-sense aborted\n");
+			srb->result = DID_ABORT << 16;
+			return;
+		}
 		if (temp_result != USB_STOR_TRANSPORT_GOOD) {
 			US_DEBUGP("-- auto-sense failure\n");
 
@@ -760,13 +778,6 @@
 		/* set the result so the higher layers expect this data */
 		srb->result = CHECK_CONDITION << 1;
 
-		/* we're done here, let's clean up */
-		srb->request_buffer = old_request_buffer;
-		srb->request_bufflen = old_request_bufflen;
-		srb->use_sg = old_sg;
-		srb->sc_data_direction = old_sc_data_direction;
-		memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
-
 		/* If things are really okay, then let's show that */
 		if ((srb->sense_buffer[2] & 0xf) == 0x0)
 			srb->result = GOOD << 1;
@@ -798,7 +809,7 @@
 {
 	struct us_data *us = (struct us_data *)urb->context;
 
-	US_DEBUGP("USB IRQ recieved for device on host %d\n", us->host_no);
+	US_DEBUGP("USB IRQ received for device on host %d\n", us->host_no);
 	US_DEBUGP("-- IRQ data length is %d\n", urb->actual_length);
 	US_DEBUGP("-- IRQ state is %d\n", urb->status);
 	US_DEBUGP("-- Interrupt Status (0x%x, 0x%x)\n",
@@ -864,21 +875,25 @@
 	if (result < 0) {
 		/* Reset flag for status notification */
 		atomic_set(us->ip_wanted, 0);
+	}
+
+	/* if the command was aborted, indicate that */
+	if (result == -ENOENT)
+		return USB_STOR_TRANSPORT_ABORTED;
+
+	/* STALL must be cleared when it is detected */
+	if (result == -EPIPE) {
+		US_DEBUGP("-- Stall on control pipe. Clearing\n");
+		result = usb_stor_clear_halt(us,	
+			usb_sndctrlpipe(us->pusb_dev, 0));
 
 		/* if the command was aborted, indicate that */
 		if (result == -ENOENT)
 			return USB_STOR_TRANSPORT_ABORTED;
+		return USB_STOR_TRANSPORT_FAILED;
+	}
 
-		/* STALL must be cleared when they are detected */
-		if (result == -EPIPE) {
-			US_DEBUGP("-- Stall on control pipe. Clearing\n");
-			result = usb_stor_clear_halt(us->pusb_dev,	
-					    usb_sndctrlpipe(us->pusb_dev,
-							    0));
-			US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result);
-			return USB_STOR_TRANSPORT_FAILED;
-		}
-
+	if (result < 0) {
 		/* Uh oh... serious problem here */
 		return USB_STOR_TRANSPORT_ERROR;
 	}
@@ -887,12 +902,18 @@
 	/* transfer the data payload for this command, if one exists*/
 	if (usb_stor_transfer_length(srb)) {
 		usb_stor_transfer(srb, us);
-		US_DEBUGP("CBI data stage result is 0x%x\n", srb->result);
+		result = srb->result;
+		US_DEBUGP("CBI data stage result is 0x%x\n", result);
 
-		/* if it was aborted, we need to indicate that */
-		if (srb->result == USB_STOR_TRANSPORT_ABORTED) {
+		/* report any errors */
+		if (result == US_BULK_TRANSFER_ABORTED) {
+			atomic_set(us->ip_wanted, 0);
 			return USB_STOR_TRANSPORT_ABORTED;
 		}
+		if (result == US_BULK_TRANSFER_FAILED) {
+			atomic_set(us->ip_wanted, 0);
+			return USB_STOR_TRANSPORT_FAILED;
+		}
 	}
 
 	/* STATUS STAGE */
@@ -976,10 +997,12 @@
 		/* a stall is a fatal condition from the device */
 		if (result == -EPIPE) {
 			US_DEBUGP("-- Stall on control pipe. Clearing\n");
-			result = usb_stor_clear_halt(us->pusb_dev, 
-					    usb_sndctrlpipe(us->pusb_dev,
-							    0));
-			US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result);
+			result = usb_stor_clear_halt(us,
+				usb_sndctrlpipe(us->pusb_dev, 0));
+
+			/* if the command was aborted, indicate that */
+			if (result == -ENOENT)
+				return USB_STOR_TRANSPORT_ABORTED;
 			return USB_STOR_TRANSPORT_FAILED;
 		}
 
@@ -991,11 +1014,16 @@
 	/* transfer the data payload for this command, if one exists*/
 	if (usb_stor_transfer_length(srb)) {
 		usb_stor_transfer(srb, us);
-		US_DEBUGP("CB data stage result is 0x%x\n", srb->result);
+		result = srb->result;
+		US_DEBUGP("CB data stage result is 0x%x\n", result);
 
-		/* if it was aborted, we need to indicate that */
-		if (srb->result == USB_STOR_TRANSPORT_ABORTED)
+		/* report any errors */
+		if (result == US_BULK_TRANSFER_ABORTED) {
 			return USB_STOR_TRANSPORT_ABORTED;
+		}
+		if (result == US_BULK_TRANSFER_FAILED) {
+			return USB_STOR_TRANSPORT_FAILED;
+		}
 	}
 
 	/* STATUS STAGE */
@@ -1016,7 +1044,8 @@
 	int result;
 	int pipe;
 
-	/* issue the command */
+	/* issue the command -- use usb_control_msg() because
+	 *  the state machine is not yet alive */
 	pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
 	result = usb_control_msg(us->pusb_dev, pipe,
 				 US_BULK_GET_MAX_LUN, 
@@ -1034,7 +1063,10 @@
 	/* if we get a STALL, clear the stall */
 	if (result == -EPIPE) {
 		US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
-		usb_stor_clear_halt(us->pusb_dev, pipe);
+
+		/* Use usb_clear_halt() because the state machine
+		 *  is not yet alive */
+		usb_clear_halt(us->pusb_dev, pipe);
 	}
 
 	/* return the default -- no LUNs */
@@ -1051,10 +1083,6 @@
 	int pipe;
 	int partial;
 
-	/* if the device was removed, then we're already reset */
-	if (!us->pusb_dev)
-		return SUCCESS;
-
 	/* set up the command wrapper */
 	bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
 	bcb.DataTransferLength = cpu_to_le32(usb_stor_transfer_length(srb));
@@ -1088,7 +1116,12 @@
 	/* if we stall, we need to clear it before we go on */
 	if (result == -EPIPE) {
 		US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
-		usb_stor_clear_halt(us->pusb_dev, pipe);
+		result = usb_stor_clear_halt(us, pipe);
+
+		/* if the command was aborted, indicate that */
+		if (result == -ENOENT)
+			return USB_STOR_TRANSPORT_ABORTED;
+		result = -EPIPE;
 	} else if (result) {
 		/* unknown error -- we've got a problem */
 		return USB_STOR_TRANSPORT_ERROR;
@@ -1099,11 +1132,11 @@
 		/* send/receive data payload, if there is any */
 		if (bcb.DataTransferLength) {
 			usb_stor_transfer(srb, us);
-			US_DEBUGP("Bulk data transfer result 0x%x\n", 
-				  srb->result);
+			result = srb->result;
+			US_DEBUGP("Bulk data transfer result 0x%x\n", result);
 
 			/* if it was aborted, we need to indicate that */
-			if (srb->result == USB_STOR_TRANSPORT_ABORTED)
+			if (result == US_BULK_TRANSFER_ABORTED)
 				return USB_STOR_TRANSPORT_ABORTED;
 		}
 	}
@@ -1127,8 +1160,12 @@
 	/* did the attempt to read the CSW fail? */
 	if (result == -EPIPE) {
 		US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
-		usb_stor_clear_halt(us->pusb_dev, pipe);
-	       
+		result = usb_stor_clear_halt(us, pipe);
+
+		/* if the command was aborted, indicate that */
+		if (result == -ENOENT)
+			return USB_STOR_TRANSPORT_ABORTED;
+
 		/* get the status again */
 		US_DEBUGP("Attempting to get CSW (2nd try)...\n");
 		result = usb_stor_bulk_msg(us, &bcs, pipe,
@@ -1141,7 +1178,11 @@
 		/* if it fails again, we need a reset and return an error*/
 		if (result == -EPIPE) {
 			US_DEBUGP("clearing halt for pipe 0x%x\n", pipe);
-			usb_stor_clear_halt(us->pusb_dev, pipe);
+			result = usb_stor_clear_halt(us, pipe);
+
+			/* if the command was aborted, indicate that */
+			if (result == -ENOENT)
+				return USB_STOR_TRANSPORT_ABORTED;
 			return USB_STOR_TRANSPORT_ERROR;
 		}
 	}
@@ -1220,10 +1261,10 @@
 	set_current_state(TASK_RUNNING);
 
 	US_DEBUGP("CB_reset: clearing endpoint halt\n");
-	usb_stor_clear_halt(us->pusb_dev, 
-			    usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
-	usb_stor_clear_halt(us->pusb_dev, 
-			    usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
+	usb_stor_clear_halt(us,
+			usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
+	usb_stor_clear_halt(us,
+			usb_sndbulkpipe(us->pusb_dev, us->ep_out));
 
 	US_DEBUGP("CB_reset done\n");
 	/* return a result code based on the result of the control message */
@@ -1259,10 +1300,10 @@
 	schedule_timeout(HZ*6);
 	set_current_state(TASK_RUNNING);
 
-	usb_stor_clear_halt(us->pusb_dev, 
-			    usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
-	usb_stor_clear_halt(us->pusb_dev, 
-			    usb_sndbulkpipe(us->pusb_dev, us->ep_out));
+	usb_stor_clear_halt(us,
+			usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
+	usb_stor_clear_halt(us,
+			usb_sndbulkpipe(us->pusb_dev, us->ep_out));
 	US_DEBUGP("Bulk soft reset completed\n");
 	return SUCCESS;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/transport.h linux/drivers/usb/storage/transport.h
--- linux.orig/drivers/usb/storage/transport.h	2001-11-22 19:49:34.000000000 +0000
+++ linux/drivers/usb/storage/transport.h	2002-07-20 01:08:33.000000000 +0000
@@ -1,7 +1,7 @@
 /* Driver for USB Mass Storage compliant devices
  * Transport Functions Header File
  *
- * $Id: transport.h,v 1.15 2001/03/17 20:06:23 jrmayfield Exp $
+ * $Id: transport.h,v 1.17 2002/02/25 00:43:41 mdharm Exp $
  *
  * Current development and maintenance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -112,7 +112,7 @@
 #define US_BULK_GET_MAX_LUN	0xfe
 
 /*
- * us_bulk_transfer() return codes
+ * usb_stor_transfer() return codes
  */
 #define US_BULK_TRANSFER_GOOD		0  /* good transfer                 */
 #define US_BULK_TRANSFER_SHORT		1  /* transfered less than expected */
@@ -151,6 +151,6 @@
 		unsigned int*);
 extern int usb_stor_control_msg(struct us_data*, unsigned int, u8, u8,
 		u16, u16, void*, u16);
+extern int usb_stor_clear_halt(struct us_data*, int );
 extern void usb_stor_transfer(Scsi_Cmnd*, struct us_data*);
-extern int usb_stor_clear_halt(struct usb_device*, int );
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/unusual_devs.h linux/drivers/usb/storage/unusual_devs.h
--- linux.orig/drivers/usb/storage/unusual_devs.h	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/unusual_devs.h	2002-07-20 01:08:29.000000000 +0000
@@ -1,10 +1,10 @@
 /* Driver for USB Mass Storage compliant devices
  * Ununsual Devices File
  *
- * $Id: unusual_devs.h,v 1.25 2002/01/13 06:39:17 mdharm Exp $
+ * $Id: unusual_devs.h,v 1.32 2002/02/25 02:41:24 mdharm Exp $
  *
  * Current development and maintenance by:
- *   (c) 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ *   (c) 2000-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
  * Initial work by:
  *   (c) 2000 Adam J. Richter (adam@yggdrasil.com), Yggdrasil Computing, Inc.
@@ -198,7 +198,7 @@
 /* This entry is needed because the device reports Sub=ff */
 UNUSUAL_DEV(  0x054c, 0x0010, 0x0106, 0x0422, 
 		"Sony",
-		"DSC-S30/S70/S75/505V/F505", 
+		"DSC-S30/S70/S75/505V/F505/F707", 
 		US_SC_SCSI, US_PR_CB, NULL,
 		US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE ),
 
@@ -289,9 +289,30 @@
 		"Lexar",
 		"Jumpshot USB CF Reader",
 		US_SC_SCSI, US_PR_JUMPSHOT, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP ),
+		US_FL_MODE_XLATE ),
 #endif
 
+/* Reported by Carlos Villegas <cav@uniscope.co.jp>
+ * This device needs an INQUIRY of exactly 36-bytes to function.
+ * That is the only reason this entry is needed.
+ */
+UNUSUAL_DEV(  0x05e3, 0x0700, 0x0000, 0xffff,
+		"SIIG",
+		"CompactFlash Card Reader",
+		US_SC_SCSI, US_PR_BULK, NULL,
+		US_FL_FIX_INQUIRY ),
+
+/* Reported by Peter Marks <peter.marks@turner.com>
+ * Like the SIIG unit above, this unit needs an INQUIRY to ask for exactly
+ * 36 bytes of data.  No more, no less. That is the only reason this entry
+ * is needed.
+ */
+UNUSUAL_DEV(  0x05e3, 0x0702, 0x0000, 0xffff,
+		"EagleTec",
+		"External Hard Disk",
+		US_SC_SCSI, US_PR_BULK, NULL,
+		US_FL_FIX_INQUIRY ),
+
 UNUSUAL_DEV(  0x0644, 0x0000, 0x0100, 0x0100, 
 		"TEAC",
 		"Floppy Drive",
@@ -305,6 +326,14 @@
 		US_FL_SINGLE_LUN | US_FL_START_STOP ),
 #endif
 
+/* Submitted by kedar@centillium
+ * Needed for START_STOP flag, but that is unconfirmed */
+UNUSUAL_DEV( 0x0686, 0x4006, 0x0001, 0x0001,
+                "Minolta",
+                "Dimage S304",
+                US_SC_SCSI, US_PR_BULK, NULL,
+                US_FL_START_STOP ),
+
 /* Submitted by f.brugmans@hccnet.nl
  * Needed for START_STOP flag */
 UNUSUAL_DEV( 0x0686, 0x4007, 0x0001, 0x0001,
@@ -381,7 +410,7 @@
 		"Datafab",
 		"MDCFE-B USB CF Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP ),
+		US_FL_MODE_XLATE ),
 
 	/*
 	 * The following Datafab-based devices may or may not work
@@ -398,38 +427,38 @@
 		"SIIG/Datafab",
 		"SIIG/Datafab Memory Stick+CF Reader/Writer",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP ),
+		US_FL_MODE_XLATE ),
 
 UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
 		"Datafab/Unknown",
 		"Datafab-based Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP ),
+		US_FL_MODE_XLATE ),
 
 UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
 		"Datafab/Unknown",
 		"Datafab-based Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP ),
+		US_FL_MODE_XLATE ),
 
 UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
 		"PNY/Datafab",
 		"PNY/Datafab CF+SM Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP ),
+		US_FL_MODE_XLATE ),
 
 UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
 		"Simple Tech/Datafab",
 		"Simple Tech/Datafab CF+SM Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP ),
+		US_FL_MODE_XLATE ),
 
 /* Submitted by Olaf Hering <olh@suse.de> */
 UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
 		"Datafab Systems, Inc.",
 		"USB to CF + SM Combo (LC1)",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP ),
+		US_FL_MODE_XLATE ),
 #endif
 
 /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
@@ -469,6 +498,8 @@
 
 /* Reported by Dan Pilone <pilone@slac.com>
  * The device needs the flags only.
+ * Also reported by Brian Hall <brihall@bigfoot.com>, again for flags.
+ * I also suspect this device may have a broken serial number.
  */
 UNUSUAL_DEV(  0x1065, 0x2136, 0x0000, 0x9999,
 		"CCYU TECHNOLOGY",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/storage/usb.c linux/drivers/usb/storage/usb.c
--- linux.orig/drivers/usb/storage/usb.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/storage/usb.c	2002-07-20 01:08:29.000000000 +0000
@@ -1,9 +1,9 @@
 /* Driver for USB Mass Storage compliant devices
  *
- * $Id: usb.c,v 1.70 2002/01/06 07:14:12 mdharm Exp $
+ * $Id: usb.c,v 1.73 2002/01/27 09:02:15 mdharm Exp $
  *
  * Current development and maintenance by:
- *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
  * Developed with the assistance of:
  *   (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
@@ -318,6 +318,7 @@
 	current->files = init_task.files;
 	atomic_inc(&current->files->count);
 	daemonize();
+	reparent_to_init();
 
 	/* avoid getting signals */
 	spin_lock_irq(&current->sigmask_lock);
@@ -958,6 +959,7 @@
 			ss->protocol_name = "Unknown";
 			kfree(ss->current_urb);
 			kfree(ss);
+			usb_dec_dev_use(dev);
 			return NULL;
 			break;
 		}
@@ -965,6 +967,8 @@
 
 		/* allocate an IRQ callback if one is needed */
 		if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) {
+			kfree(ss->current_urb);
+			kfree(ss);
 			usb_dec_dev_use(dev);
 			return NULL;
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/stv680.c linux/drivers/usb/stv680.c
--- linux.orig/drivers/usb/stv680.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/stv680.c	2002-07-20 01:08:28.000000000 +0000
@@ -50,6 +50,12 @@
  *                         improve quality. Got rid of green line around 
  *                         frame. Fix brightness reset when changing size 
  *                         bug. Adjusted gamma filters slightly.
+ *
+ * ver 0.25 Jan, 2002 (kjs)
+ *			   Fixed a bug in which the driver sometimes attempted
+ *			   to set to a non-supported size. This allowed
+ *			   gnomemeeting to work.
+ *			   Fixed proc entry removal bug.
  */
 
 #include <linux/config.h>
@@ -87,7 +93,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.24"
+#define DRIVER_VERSION "v0.25"
 #define DRIVER_AUTHOR "Kevin Sisson <kjsisson@bellsouth.net>"
 #define DRIVER_DESC "STV0680 USB Camera Driver"
 
@@ -659,7 +665,7 @@
 	if (stv680_proc_entry == NULL)
 		return;
 
-	remove_proc_entry ("stv", video_proc_entry);
+	remove_proc_entry ("stv680", video_proc_entry);
 }
 #endif				/* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
 
@@ -800,7 +806,7 @@
 	for (i = 0; i < STV680_NUMSBUF; i++) {
 		urb = usb_alloc_urb (0);
 		if (!urb)
-			return ENOMEM;
+			return -ENOMEM;
 
 		/* sbuf is urb->transfer_buffer, later gets memcpyed to scratch */
 		usb_fill_bulk_urb (urb, stv680->udev,
@@ -862,20 +868,23 @@
 	if ((width < (stv680->maxwidth / 2)) || (height < (stv680->maxheight / 2))) {
 		width = stv680->maxwidth / 2;
 		height = stv680->maxheight / 2;
-	} else if ((width >= 158) && (width <= 166)) {
+	} else if ((width >= 158) && (width <= 166) && (stv680->QVGA == 1)) {
 		width = 160;
 		height = 120;
-	} else if ((width >= 172) && (width <= 180)) {
+	} else if ((width >= 172) && (width <= 180) && (stv680->CIF == 1)) {
 		width = 176;
 		height = 144;
-	} else if ((width >= 318) && (width <= 350)) {
+	} else if ((width >= 318) && (width <= 350) && (stv680->QVGA == 1)) {
 		width = 320;
 		height = 240;
-	} else if ((width >= 350) && (width <= 358)) {
+	} else if ((width >= 350) && (width <= 358) && (stv680->CIF == 1)) {
 		width = 352;
 		height = 288;
+	} else {
+		PDEBUG (1, "STV(e): request for non-supported size: request: v.width = %i, v.height = %i  actual: stv.width = %i, stv.height = %i", width, height, stv680->vwidth, stv680->vheight);
+		return 1;
 	}
-
+	
 	/* Stop a current stream and start it again at the new size */
 	if (wasstreaming)
 		stv680_stop_stream (stv680);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- linux.orig/drivers/usb/uhci.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/uhci.c	2002-07-20 01:08:29.000000000 +0000
@@ -4,7 +4,7 @@
  * Maintainer: Johannes Erdfelt <johannes@erdfelt.com>
  *
  * (C) Copyright 1999 Linus Torvalds
- * (C) Copyright 1999-2001 Johannes Erdfelt, johannes@erdfelt.com
+ * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com
  * (C) Copyright 1999 Randy Dunlap
  * (C) Copyright 1999 Georg Acher, acher@in.tum.de
  * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de
@@ -57,7 +57,6 @@
 
 #include <linux/pm.h>
 
-
 /*
  * Version Information
  */
@@ -65,7 +64,6 @@
 #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber"
 #define DRIVER_DESC "USB Universal Host Controller Interface driver"
 
-
 /*
  * debug = 0, no debugging messages
  * debug = 1, dump failed URB's except for stalls
@@ -100,6 +98,7 @@
 
 /* If a transfer is still active after this much time, turn off FSBR */
 #define IDLE_TIMEOUT	(HZ / 20)	/* 50 ms */
+#define FSBR_DELAY	(HZ / 20)	/* 50 ms */
 
 #define MAX_URB_LOOP	2048		/* Maximum number of linked URB's */
 
@@ -240,10 +239,10 @@
 	unsigned long flags;
 
 	/* If it's not inserted, don't remove it */
+	spin_lock_irqsave(&uhci->frame_list_lock, flags);
 	if (td->frame == -1 && list_empty(&td->fl_list))
-		return;
+		goto out;
 
-	spin_lock_irqsave(&uhci->frame_list_lock, flags);
 	if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) {
 		if (list_empty(&td->fl_list)) {
 			uhci->fl->frame[td->frame] = td->link;
@@ -268,6 +267,7 @@
 	list_del_init(&td->fl_list);
 	td->frame = -1;
 
+out:
 	spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
 }
 
@@ -336,6 +336,7 @@
 	qh->link = UHCI_PTR_TERM;
 
 	qh->dev = dev;
+	qh->urbp = NULL;
 
 	INIT_LIST_HEAD(&qh->list);
 	INIT_LIST_HEAD(&qh->remove_list);
@@ -358,6 +359,9 @@
 	pci_pool_free(uhci->qh_pool, qh, qh->dma_handle);
 }
 
+/*
+ * MUST be called with uhci->frame_list_lock acquired
+ */
 static void _uhci_insert_qh(struct uhci *uhci, struct uhci_qh *skelqh, struct urb *urb)
 {
 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
@@ -407,21 +411,19 @@
 	spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
 }
 
-static void uhci_remove_qh(struct uhci *uhci, struct urb *urb)
+static void uhci_remove_qh(struct uhci *uhci, struct uhci_qh *qh)
 {
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 	unsigned long flags;
-	struct uhci_qh *qh = urbp->qh, *pqh;
+	struct uhci_qh *pqh;
 
 	if (!qh)
 		return;
 
+	qh->urbp = NULL;
+
 	/* Only go through the hoops if it's actually linked in */
+	spin_lock_irqsave(&uhci->frame_list_lock, flags);
 	if (!list_empty(&qh->list)) {
-		qh->urbp = NULL;
-
-		spin_lock_irqsave(&uhci->frame_list_lock, flags);
-
 		pqh = list_entry(qh->list.prev, struct uhci_qh, list);
 
 		if (pqh->urbp) {
@@ -444,9 +446,8 @@
 		qh->element = qh->link = UHCI_PTR_TERM;
 
 		list_del_init(&qh->list);
-
-		spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
 	}
+	spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
 
 	spin_lock_irqsave(&uhci->qh_remove_list_lock, flags);
 
@@ -617,7 +618,7 @@
 {
 	struct urb_priv *urbp;
 
-	urbp = kmem_cache_alloc(uhci_up_cachep, in_interrupt() ? SLAB_ATOMIC : SLAB_KERNEL);
+	urbp = kmem_cache_alloc(uhci_up_cachep, SLAB_ATOMIC);
 	if (!urbp) {
 		err("uhci_alloc_urb_priv: couldn't allocate memory for urb_priv\n");
 		return NULL;
@@ -658,6 +659,9 @@
 	return urbp;
 }
 
+/*
+ * MUST be called with urb->lock acquired
+ */
 static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td)
 {
 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
@@ -667,6 +671,9 @@
 	list_add_tail(&td->list, &urbp->td_list);
 }
 
+/*
+ * MUST be called with urb->lock acquired
+ */
 static void uhci_remove_td_from_urb(struct uhci_td *td)
 {
 	if (list_empty(&td->list))
@@ -677,22 +684,22 @@
 	td->urb = NULL;
 }
 
+/*
+ * MUST be called with urb->lock acquired
+ */
 static void uhci_destroy_urb_priv(struct urb *urb)
 {
 	struct list_head *head, *tmp;
 	struct urb_priv *urbp;
 	struct uhci *uhci;
-	unsigned long flags;
-
-	spin_lock_irqsave(&urb->lock, flags);
 
 	urbp = (struct urb_priv *)urb->hcpriv;
 	if (!urbp)
-		goto out;
+		return;
 
 	if (!urbp->dev || !urbp->dev->bus || !urbp->dev->bus->hcpriv) {
 		warn("uhci_destroy_urb_priv: urb %p belongs to disconnected device or bus?", urb);
-		goto out;
+		return;
 	}
 
 	if (!list_empty(&urb->urb_list))
@@ -715,20 +722,21 @@
 		uhci_free_td(uhci, td);
 	}
 
-	if (urbp->setup_packet_dma_handle)
+	if (urbp->setup_packet_dma_handle) {
 		pci_unmap_single(uhci->dev, urbp->setup_packet_dma_handle,
 			sizeof(devrequest), PCI_DMA_TODEVICE);
+		urbp->setup_packet_dma_handle = 0;
+	}
 
-	if (urbp->transfer_buffer_dma_handle)
+	if (urbp->transfer_buffer_dma_handle) {
 		pci_unmap_single(uhci->dev, urbp->transfer_buffer_dma_handle,
 			urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
 			PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+		urbp->transfer_buffer_dma_handle = 0;
+	}
 
 	urb->hcpriv = NULL;
 	kmem_cache_free(uhci_up_cachep, urbp);
-
-out:
-	spin_unlock_irqrestore(&urb->lock, flags);
 }
 
 static void uhci_inc_fsbr(struct uhci *uhci, struct urb *urb)
@@ -740,7 +748,7 @@
 
 	if ((!(urb->transfer_flags & USB_NO_FSBR)) && !urbp->fsbr) {
 		urbp->fsbr = 1;
-		if (!uhci->fsbr++)
+		if (!uhci->fsbr++ && !uhci->fsbrtimeout)
 			uhci->skel_term_qh->link = uhci->skel_hs_control_qh->dma_handle | UHCI_PTR_QH;
 	}
 
@@ -757,7 +765,7 @@
 	if ((!(urb->transfer_flags & USB_NO_FSBR)) && urbp->fsbr) {
 		urbp->fsbr = 0;
 		if (!--uhci->fsbr)
-			uhci->skel_term_qh->link = UHCI_PTR_TERM;
+			uhci->fsbrtimeout = jiffies + FSBR_DELAY;
 	}
 
 	spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
@@ -870,7 +878,7 @@
 	 * It's IN if the pipe is an output pipe or we're not expecting
 	 * data back.
 	 */
-	destination &= ~TD_PID;
+	destination &= ~TD_TOKEN_PID_MASK;
 	if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length)
 		destination |= USB_PID_IN;
 	else
@@ -1032,7 +1040,7 @@
 	urbp->short_control_packet = 1;
 
 	/* Create a new QH to avoid pointer overwriting problems */
-	uhci_remove_qh(uhci, urb);
+	uhci_remove_qh(uhci, urbp->qh);
 
 	/* Delete all of the TD's except for the status TD at the end */
 	head = &urbp->td_list;
@@ -1251,20 +1259,29 @@
 			data);
 
 		data += pktsze;
-		len -= pktsze;
+		len -= maxsze;
 
 		usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			usb_pipeout(urb->pipe));
 	} while (len > 0);
 
+	/*
+	 * USB_ZERO_PACKET means adding a 0-length packet, if
+	 * direction is OUT and the transfer_length was an
+	 * exact multiple of maxsze, hence
+	 * (len = transfer_length - N * maxsze) == 0
+	 * however, if transfer_length == 0, the zero packet
+	 * was already prepared above.
+	 */
 	if (usb_pipeout(urb->pipe) && (urb->transfer_flags & USB_ZERO_PACKET) &&
-	   urb->transfer_buffer_length) {
+	   !len && urb->transfer_buffer_length) {
 		td = uhci_alloc_td(uhci, urb->dev);
 		if (!td)
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | UHCI_NULL_DATA_SIZE |
+		uhci_fill_td(td, status, destination |
+			(UHCI_NULL_DATA_SIZE << 21) |
 			(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE),
 			data);
@@ -1308,9 +1325,7 @@
 	struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
 	struct list_head *tmp, *head;
 	int ret = 0;
-	unsigned long flags;
 
-	spin_lock_irqsave(&uhci->urb_list_lock, flags);
 	head = &uhci->urb_list;
 	tmp = head->next;
 	while (tmp != head) {
@@ -1333,8 +1348,6 @@
 	} else
 		ret = -1;	/* no previous urb found */
 
-	spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
-
 	return ret;
 }
 
@@ -1442,34 +1455,30 @@
 	return ret;
 }
 
+/*
+ * MUST be called with uhci->urb_list_lock acquired
+ */
 static struct urb *uhci_find_urb_ep(struct uhci *uhci, struct urb *urb)
 {
 	struct list_head *tmp, *head;
-	unsigned long flags;
-	struct urb *u = NULL;
 
 	/* We don't match Isoc transfers since they are special */
 	if (usb_pipeisoc(urb->pipe))
 		return NULL;
 
-	spin_lock_irqsave(&uhci->urb_list_lock, flags);
 	head = &uhci->urb_list;
 	tmp = head->next;
 	while (tmp != head) {
-		u = list_entry(tmp, struct urb, urb_list);
+		struct urb *u = list_entry(tmp, struct urb, urb_list);
 
 		tmp = tmp->next;
 
 		if (u->dev == urb->dev && u->pipe == urb->pipe &&
 		    u->status == -EINPROGRESS)
-			goto out;
+			return u;
 	}
-	u = NULL;
 
-out:
-	spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
-
-	return u;
+	return NULL;
 }
 
 static int uhci_submit_urb(struct urb *urb)
@@ -1493,13 +1502,15 @@
 	INIT_LIST_HEAD(&urb->urb_list);
 	usb_inc_dev_use(urb->dev);
 
-	spin_lock_irqsave(&urb->lock, flags);
+	spin_lock_irqsave(&uhci->urb_list_lock, flags);
+	spin_lock(&urb->lock);
 
 	if (urb->status == -EINPROGRESS || urb->status == -ECONNRESET ||
 	    urb->status == -ECONNABORTED) {
 		dbg("uhci_submit_urb: urb not available to submit (status = %d)", urb->status);
 		/* Since we can have problems on the out path */
-		spin_unlock_irqrestore(&urb->lock, flags);
+		spin_unlock(&urb->lock);
+		spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
 		usb_dec_dev_use(urb->dev);
 
 		return ret;
@@ -1568,19 +1579,24 @@
 out:
 	urb->status = ret;
 
-	spin_unlock_irqrestore(&urb->lock, flags);
-
 	if (ret == -EINPROGRESS) {
-		spin_lock_irqsave(&uhci->urb_list_lock, flags);
 		/* We use _tail to make find_urb_ep more efficient */
 		list_add_tail(&urb->urb_list, &uhci->urb_list);
+
+		spin_unlock(&urb->lock);
 		spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
 
 		return 0;
 	}
 
 	uhci_unlink_generic(uhci, urb);
-	uhci_call_completion(urb);
+
+	spin_unlock(&urb->lock);
+	spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
+	/* Only call completion if it was successful */
+	if (!ret)
+		uhci_call_completion(urb);
 
 	return ret;
 }
@@ -1588,7 +1604,7 @@
 /*
  * Return the result of a transfer
  *
- * Must be called with urb_list_lock acquired
+ * MUST be called with urb_list_lock acquired
  */
 static void uhci_transfer_result(struct uhci *uhci, struct urb *urb)
 {
@@ -1606,8 +1622,7 @@
 
 	if (urb->status != -EINPROGRESS) {
 		info("uhci_transfer_result: called for URB %p not in flight?", urb);
-		spin_unlock_irqrestore(&urb->lock, flags);
-		return;
+		goto out;
 	}
 
 	switch (usb_pipetype(urb->pipe)) {
@@ -1627,10 +1642,8 @@
 
 	urbp->status = ret;
 
-	spin_unlock_irqrestore(&urb->lock, flags);
-
 	if (ret == -EINPROGRESS)
-		return;
+		goto out;
 
 	switch (usb_pipetype(urb->pipe)) {
 	case PIPE_CONTROL:
@@ -1644,10 +1657,8 @@
 		break;
 	case PIPE_INTERRUPT:
 		/* Interrupts are an exception */
-		if (urb->interval) {
-			uhci_add_complete(urb);
-			return;		/* <-- note return */
-		}
+		if (urb->interval)
+			goto out_complete;
 
 		/* Release bandwidth for Interrupt or Isoc. transfers */
 		/* Spinlock needed ? */
@@ -1660,15 +1671,24 @@
 			usb_pipetype(urb->pipe), urb);
 	}
 
+	/* Remove it from uhci->urb_list */
 	list_del_init(&urb->urb_list);
 
+out_complete:
 	uhci_add_complete(urb);
+
+out:
+	spin_unlock_irqrestore(&urb->lock, flags);
 }
 
+/*
+ * MUST be called with urb->lock acquired
+ */
 static void uhci_unlink_generic(struct uhci *uhci, struct urb *urb)
 {
 	struct list_head *head, *tmp;
 	struct urb_priv *urbp = urb->hcpriv;
+	int prevactive = 1;
 
 	/* We can get called when urbp allocation fails, so check */
 	if (!urbp)
@@ -1676,6 +1696,19 @@
 
 	uhci_dec_fsbr(uhci, urb);	/* Safe since it checks */
 
+	/*
+	 * Now we need to find out what the last successful toggle was
+	 * so we can update the local data toggle for the next transfer
+	 *
+	 * There's 3 way's the last successful completed TD is found:
+	 *
+	 * 1) The TD is NOT active and the actual length < expected length
+	 * 2) The TD is NOT active and it's the last TD in the chain
+	 * 3) The TD is active and the previous TD is NOT active
+	 *
+	 * Control and Isochronous ignore the toggle, so this is safe
+	 * for all types
+	 */
 	head = &urbp->td_list;
 	tmp = head->next;
 	while (tmp != head) {
@@ -1683,21 +1716,25 @@
 
 		tmp = tmp->next;
 
-		/* Control and Isochronous ignore the toggle, so this */
-		/* is safe for all types */
-		if ((!(td->status & TD_CTRL_ACTIVE) &&
-		    (uhci_actual_length(td->status) < uhci_expected_length(td->info)) ||
-		    tmp == head)) {
+		if (!(td->status & TD_CTRL_ACTIVE) &&
+		    (uhci_actual_length(td->status) < uhci_expected_length(td->info) ||
+		    tmp == head))
 			usb_settoggle(urb->dev, uhci_endpoint(td->info),
 				uhci_packetout(td->info),
 				uhci_toggle(td->info) ^ 1);
-		}
+		else if ((td->status & TD_CTRL_ACTIVE) && !prevactive)
+			usb_settoggle(urb->dev, uhci_endpoint(td->info),
+				uhci_packetout(td->info),
+				uhci_toggle(td->info));
+
+		prevactive = td->status & TD_CTRL_ACTIVE;
 	}
 
 	uhci_delete_queued_urb(uhci, urb);
 
 	/* The interrupt loop will reclaim the QH's */
-	uhci_remove_qh(uhci, urb);
+	uhci_remove_qh(uhci, urbp->qh);
+	urbp->qh = NULL;
 }
 
 static int uhci_unlink_urb(struct urb *urb)
@@ -1714,6 +1751,9 @@
 
 	uhci = (struct uhci *)urb->dev->bus->hcpriv;
 
+	spin_lock_irqsave(&uhci->urb_list_lock, flags);
+	spin_lock(&urb->lock);
+
 	/* Release bandwidth for Interrupt or Isoc. transfers */
 	/* Spinlock needed ? */
 	if (urb->bandwidth) {
@@ -1729,38 +1769,47 @@
 		}
 	}
 
-	if (urb->status != -EINPROGRESS)
+	if (urb->status != -EINPROGRESS) {
+		spin_unlock(&urb->lock);
+		spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
 		return 0;
+	}
 
-	spin_lock_irqsave(&uhci->urb_list_lock, flags);
 	list_del_init(&urb->urb_list);
-	spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
 
 	uhci_unlink_generic(uhci, urb);
 
 	/* Short circuit the virtual root hub */
 	if (urb->dev == uhci->rh.dev) {
 		rh_unlink_urb(urb);
+
+		spin_unlock(&urb->lock);
+		spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
 		uhci_call_completion(urb);
 	} else {
 		if (urb->transfer_flags & USB_ASYNC_UNLINK) {
-			/* urb_list is available now since we called */
-			/*  uhci_unlink_generic already */
-
 			urbp->status = urb->status = -ECONNABORTED;
 
-			spin_lock_irqsave(&uhci->urb_remove_list_lock, flags);
+			spin_lock(&uhci->urb_remove_list_lock);
 
-			/* Check to see if the remove list is empty */
+			/* If we're the first, set the next interrupt bit */
 			if (list_empty(&uhci->urb_remove_list))
 				uhci_set_next_interrupt(uhci);
 			
 			list_add(&urb->urb_list, &uhci->urb_remove_list);
 
-			spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
+			spin_unlock(&uhci->urb_remove_list_lock);
+
+			spin_unlock(&urb->lock);
+			spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
 		} else {
 			urb->status = -ENOENT;
 
+			spin_unlock(&urb->lock);
+			spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
 			if (in_interrupt()) {	/* wait at least 1 frame */
 				static int errorcount = 10;
 
@@ -1784,10 +1833,6 @@
 
 	uhci_dec_fsbr(uhci, urb);
 
-	/* There is a race with updating IOC in here, but it's not worth */
-	/*  trying to fix since this is merely an optimization. The only */
-	/*  time we'd lose is if the status of the packet got updated */
-	/*  and we'd be turning on FSBR next frame anyway, so it's a wash */
 	urbp->fsbr_timeout = 1;
 
 	head = &urbp->td_list;
@@ -1903,12 +1948,14 @@
 /* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */
 static int rh_send_irq(struct urb *urb)
 {
-	int i, len = 1;
 	struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
+	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 	unsigned int io_addr = uhci->io_addr;
+	unsigned long flags;
+	int i, len = 1;
 	__u16 data = 0;
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 
+	spin_lock_irqsave(&urb->lock, flags);
 	for (i = 0; i < uhci->rh.numports; i++) {
 		data |= ((inw(io_addr + USBPORTSC1 + i * 2) & 0xa) > 0 ? (1 << (i + 1)) : 0);
 		len = (i + 1) / 8 + 1;
@@ -1918,6 +1965,8 @@
 	urb->actual_length = len;
 	urbp->status = 0;
 
+	spin_unlock_irqrestore(&urb->lock, flags);
+
 	if ((data > 0) && (uhci->rh.send != 0)) {
 		dbg("root-hub INT complete: port1: %x port2: %x data: %x",
 			inw(io_addr + USBPORTSC1), inw(io_addr + USBPORTSC2), data);
@@ -1944,23 +1993,26 @@
 
 	spin_lock_irqsave(&uhci->urb_list_lock, flags);
 	head = &uhci->urb_list;
-
 	tmp = head->next;
 	while (tmp != head) {
 		struct urb *u = list_entry(tmp, struct urb, urb_list);
-		struct urb_priv *urbp = (struct urb_priv *)u->hcpriv;
+		struct urb_priv *up = (struct urb_priv *)u->hcpriv;
 
 		tmp = tmp->next;
 
+		spin_lock(&u->lock);
+
 		/* Check if the FSBR timed out */
-		if (urbp->fsbr && !urbp->fsbr_timeout && time_after_eq(jiffies, urbp->fsbrtime + IDLE_TIMEOUT))
+		if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT))
 			uhci_fsbr_timeout(uhci, u);
 
 		/* Check if the URB timed out */
-		if (u->timeout && time_after_eq(jiffies, urbp->inserttime + u->timeout)) {
+		if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout)) {
 			list_del(&u->urb_list);
 			list_add_tail(&u->urb_list, &list);
 		}
+
+		spin_unlock(&u->lock);
 	}
 	spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
 
@@ -1975,6 +2027,12 @@
 		uhci_unlink_urb(u);
 	}
 
+	/* Really disable FSBR */
+	if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
+		uhci->fsbrtimeout = 0;
+		uhci->skel_term_qh->link = UHCI_PTR_TERM;
+	}
+
 	/* enter global suspend if nothing connected */
 	if (!uhci->is_suspended && !ports_active(uhci))
 		suspend_hc(uhci);
@@ -2127,12 +2185,12 @@
 			OK(0);
 		case RH_PORT_RESET:
 			SET_RH_PORTSTAT(USBPORTSC_PR);
-			wait_ms(50);	/* USB v1.1 7.1.7.3 */
+			mdelay(50);	/* USB v1.1 7.1.7.3 */
 			uhci->rh.c_p_r[wIndex - 1] = 1;
 			CLR_RH_PORTSTAT(USBPORTSC_PR);
 			udelay(10);
 			SET_RH_PORTSTAT(USBPORTSC_PE);
-			wait_ms(10);
+			mdelay(10);
 			SET_RH_PORTSTAT(0xa);
 			OK(0);
 		case RH_PORT_POWER:
@@ -2194,6 +2252,9 @@
 	return stat;
 }
 
+/*
+ * MUST be called with urb->lock acquired
+ */
 static int rh_unlink_urb(struct urb *urb)
 {
 	struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
@@ -2229,16 +2290,25 @@
 
 static void uhci_call_completion(struct urb *urb)
 {
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
+	struct urb_priv *urbp;
 	struct usb_device *dev = urb->dev;
 	struct uhci *uhci = (struct uhci *)dev->bus->hcpriv;
 	int is_ring = 0, killed, resubmit_interrupt, status;
 	struct urb *nurb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&urb->lock, flags);
+
+	urbp = (struct urb_priv *)urb->hcpriv;
+	if (!urbp || !urb->dev) {
+		spin_unlock_irqrestore(&urb->lock, flags);
+		return;
+	}
 
 	killed = (urb->status == -ENOENT || urb->status == -ECONNABORTED ||
 			urb->status == -ECONNRESET);
 	resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT &&
-			urb->interval && !killed);
+			urb->interval);
 
 	nurb = urb->next;
 	if (nurb && !killed) {
@@ -2263,14 +2333,6 @@
 		is_ring = (nurb == urb);
 	}
 
-	status = urbp->status;
-	if (!resubmit_interrupt)
-		/* We don't need urb_priv anymore */
-		uhci_destroy_urb_priv(urb);
-
-	if (!killed)
-		urb->status = status;
-
 	if (urbp->transfer_buffer_dma_handle)
 		pci_dma_sync_single(uhci->dev, urbp->transfer_buffer_dma_handle,
 			urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
@@ -2280,11 +2342,28 @@
 		pci_dma_sync_single(uhci->dev, urbp->setup_packet_dma_handle,
 			sizeof(devrequest), PCI_DMA_TODEVICE);
 
+	status = urbp->status;
+	if (!resubmit_interrupt || killed)
+		/* We don't need urb_priv anymore */
+		uhci_destroy_urb_priv(urb);
+
+	if (!killed)
+		urb->status = status;
+
 	urb->dev = NULL;
+	spin_unlock_irqrestore(&urb->lock, flags);
+
 	if (urb->complete)
 		urb->complete(urb);
 
-	if (resubmit_interrupt) {
+	if (resubmit_interrupt)
+		/* Recheck the status. The completion handler may have */
+		/*  unlinked the resubmitting interrupt URB */
+		killed = (urb->status == -ENOENT ||
+			  urb->status == -ECONNABORTED ||
+			  urb->status == -ECONNRESET);
+
+	if (resubmit_interrupt && !killed) {
 		urb->dev = dev;
 		uhci_reset_interrupt(urb);
 	} else {
@@ -2311,11 +2390,14 @@
 		struct urb_priv *urbp = list_entry(tmp, struct urb_priv, complete_list);
 		struct urb *urb = urbp->urb;
 
-		tmp = tmp->next;
-
 		list_del_init(&urbp->complete_list);
+		spin_unlock_irqrestore(&uhci->complete_list_lock, flags);
 
 		uhci_call_completion(urb);
+
+		spin_lock_irqsave(&uhci->complete_list_lock, flags);
+		head = &uhci->complete_list;
+		tmp = head->next;
 	}
 	spin_unlock_irqrestore(&uhci->complete_list_lock, flags);
 }
@@ -2337,7 +2419,8 @@
 		list_del_init(&urb->urb_list);
 
 		urbp->status = urb->status = -ECONNRESET;
-		uhci_call_completion(urb);
+
+		uhci_add_complete(urb);
 	}
 	spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
 }
@@ -2623,6 +2706,7 @@
 	}
 
 	uhci->dev = dev;
+	uhci->irq = dev->irq;
 	uhci->io_addr = io_addr;
 	uhci->io_size = io_size;
 	pci_set_drvdata(dev, uhci);
@@ -2649,6 +2733,11 @@
 	/*  or broken setup */
 	reset_hc(uhci);
 
+	uhci->fsbr = 0;
+	uhci->fsbrtimeout = 0;
+
+	uhci->is_suspended = 0;
+
 	spin_lock_init(&uhci->qh_remove_list_lock);
 	INIT_LIST_HEAD(&uhci->qh_remove_list);
 
@@ -2831,8 +2920,6 @@
 	if (request_irq(dev->irq, uhci_interrupt, SA_SHIRQ, "usb-uhci", uhci))
 		goto err_request_irq;
 
-	uhci->irq = dev->irq;
-
 	/* disable legacy emulation */
 	pci_write_config_word(uhci->dev, USBLEGSUP, USBLEGSUP_DEFAULT);
 
@@ -3070,3 +3157,4 @@
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/uhci.h linux/drivers/usb/uhci.h
--- linux.orig/drivers/usb/uhci.h	2001-11-22 19:49:52.000000000 +0000
+++ linux/drivers/usb/uhci.h	2002-07-20 01:08:26.000000000 +0000
@@ -121,15 +121,16 @@
  * for TD <info>: (a.k.a. Token)
  */
 #define TD_TOKEN_TOGGLE		19
-#define TD_PID			0xFF
+#define TD_TOKEN_PID_MASK	0xFF
+#define TD_TOKEN_EXPLEN_MASK	0x7FF		/* expected length, encoded as n - 1 */
 
 #define uhci_maxlen(token)	((token) >> 21)
-#define uhci_expected_length(info) (((info >> 21) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
+#define uhci_expected_length(info) (((info >> 21) + 1) & TD_TOKEN_EXPLEN_MASK) /* 1-based */
 #define uhci_toggle(token)	(((token) >> TD_TOKEN_TOGGLE) & 1)
 #define uhci_endpoint(token)	(((token) >> 15) & 0xf)
 #define uhci_devaddr(token)	(((token) >> 8) & 0x7f)
 #define uhci_devep(token)	(((token) >> 8) & 0x7ff)
-#define uhci_packetid(token)	((token) & 0xff)
+#define uhci_packetid(token)	((token) & TD_TOKEN_PID_MASK)
 #define uhci_packetout(token)	(uhci_packetid(token) != USB_PID_IN)
 #define uhci_packetin(token)	(uhci_packetid(token) == USB_PID_IN)
 
@@ -163,7 +164,7 @@
 	struct list_head list;		/* P: urb->lock */
 
 	int frame;
-	struct list_head fl_list;	/* P: frame_list_lock */
+	struct list_head fl_list;	/* P: uhci->frame_list_lock */
 } __attribute__((aligned(16)));
 
 /*
@@ -286,17 +287,17 @@
 struct uhci {
 	struct pci_dev *dev;
 
+#ifdef CONFIG_PROC_FS
 	/* procfs */
 	int num;
 	struct proc_dir_entry *proc_entry;
+#endif
 
 	/* Grabbed from PCI */
 	int irq;
 	unsigned int io_addr;
 	unsigned int io_size;
 
-	struct list_head uhci_list;
-
 	struct pci_pool *qh_pool;
 	struct pci_pool *td_pool;
 
@@ -306,21 +307,26 @@
 	struct uhci_qh *skelqh[UHCI_NUM_SKELQH];	/* Skeleton QH's */
 
 	spinlock_t frame_list_lock;
-	struct uhci_frame_list *fl;		/* Frame list */
+	struct uhci_frame_list *fl;		/* P: uhci->frame_list_lock */
 	int fsbr;				/* Full speed bandwidth reclamation */
+	unsigned long fsbrtimeout;		/* FSBR delay */
 	int is_suspended;
 
+	/* Main list of URB's currently controlled by this HC */
+	spinlock_t urb_list_lock;
+	struct list_head urb_list;		/* P: uhci->urb_list_lock */
+
+	/* List of QH's that are done, but waiting to be unlinked (race) */
 	spinlock_t qh_remove_list_lock;
-	struct list_head qh_remove_list;
+	struct list_head qh_remove_list;	/* P: uhci->qh_remove_list_lock */
 
+	/* List of asynchronously unlinked URB's */
 	spinlock_t urb_remove_list_lock;
-	struct list_head urb_remove_list;
-
-	spinlock_t urb_list_lock;
-	struct list_head urb_list;
+	struct list_head urb_remove_list;	/* P: uhci->urb_remove_list_lock */
 
+	/* List of URB's awaiting completion callback */
 	spinlock_t complete_list_lock;
-	struct list_head complete_list;
+	struct list_head complete_list;		/* P: uhci->complete_list_lock */
 
 	struct virt_root_hub rh;	/* private data of the virtual root hub */
 };
@@ -333,7 +339,7 @@
 	dma_addr_t transfer_buffer_dma_handle;
 
 	struct uhci_qh *qh;		/* QH for this URB */
-	struct list_head td_list;
+	struct list_head td_list;	/* P: urb->lock */
 
 	int fsbr : 1;			/* URB turned on FSBR */
 	int fsbr_timeout : 1;		/* URB timed out on FSBR */
@@ -345,12 +351,37 @@
 	int status;			/* Final status */
 
 	unsigned long inserttime;	/* In jiffies */
-	unsigned long fsbrtime;	/* In jiffies */
+	unsigned long fsbrtime;		/* In jiffies */
 
-	struct list_head queue_list;
-	struct list_head complete_list;
+	struct list_head queue_list;	/* P: uhci->frame_list_lock */
+	struct list_head complete_list;	/* P: uhci->complete_list_lock */
 };
 
+/*
+ * Locking in uhci.c
+ *
+ * spinlocks are used extensively to protect the many lists and data
+ * structures we have. It's not that pretty, but it's necessary. We
+ * need to be done with all of the locks (except complete_list_lock) when
+ * we call urb->complete. I've tried to make it simple enough so I don't
+ * have to spend hours racking my brain trying to figure out if the
+ * locking is safe.
+ *
+ * Here's the safe locking order to prevent deadlocks:
+ *
+ * #1 uhci->urb_list_lock
+ * #2 urb->lock
+ * #3 uhci->urb_remove_list_lock, uhci->frame_list_lock, 
+ *   uhci->qh_remove_list_lock
+ * #4 uhci->complete_list_lock
+ *
+ * If you're going to grab 2 or more locks at once, ALWAYS grab the lock
+ * at the lowest level FIRST and NEVER grab locks at the same level at the
+ * same time.
+ * 
+ * So, if you need uhci->urb_list_lock, grab it before you grab urb->lock
+ */
+
 /* -------------------------------------------------------------------------
    Virtual Root HUB
    ------------------------------------------------------------------------- */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
--- linux.orig/drivers/usb/usb-ohci.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/usb-ohci.c	2002-07-20 01:08:28.000000000 +0000
@@ -11,7 +11,11 @@
  * 
  * 
  * History:
- * 
+ *
+ * 2002/03/08 interrupt unlink fix (Matt Hughes), better cleanup on
+ *	load failure (Matthew Frederickson)
+ * 2002/01/20 async unlink fixes:  return -EINPROGRESS (per spec) and
+ *	make interrupt unlink-in-completion work (db)
  * 2001/09/19 USB_ZERO_PACKET support (Jean Tourrilhes)
  * 2001/07/17 power management and pmac cleanup (Benjamin Herrenschmidt)
  * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam);
@@ -486,9 +490,8 @@
 
 			/* implicitly requeued */
   			urb->actual_length = 0;
-  			urb->status = USB_ST_URB_PENDING;
-  			if (urb_priv->state != URB_DEL)
-  				td_submit_urb (urb);
+			urb->status = -EINPROGRESS;
+			td_submit_urb (urb);
   			break;
   			
 		case PIPE_ISOCHRONOUS:
@@ -790,6 +793,7 @@
 				/* usb_dec_dev_use done in dl_del_list() */
 				urb->status = -EINPROGRESS;
 				spin_unlock_irqrestore (&usb_ed_lock, flags);
+				return -EINPROGRESS;
 			}
 		} else {
 			urb_rm_priv (urb);
@@ -1073,6 +1077,28 @@
 
 /*-------------------------------------------------------------------------*/
 
+/* scan the periodic table to find and unlink this ED */
+static void periodic_unlink (
+	struct ohci	*ohci,
+	struct ed	*ed,
+	unsigned	index,
+	unsigned	period
+) {
+	for (; index < NUM_INTS; index += period) {
+		__u32	*ed_p = &ohci->hcca->int_table [index];
+
+		/* ED might have been unlinked through another path */
+		while (*ed_p != 0) {
+			if ((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) {
+				*ed_p = ed->hwNextED;		
+				break;
+			}
+			ed_p = & ((dma_to_ed (ohci,
+				le32_to_cpup (ed_p)))->hwNextED);
+		}
+	}	
+}
+
 /* unlink an ed from one of the HC chains. 
  * just the link to the ed is unlinked.
  * the link from the ed still points to another operational ed or 0
@@ -1080,11 +1106,7 @@
 
 static int ep_unlink (ohci_t * ohci, ed_t * ed) 
 {
-	int int_branch;
 	int i;
-	int inter;
-	int interval;
-	__u32 * ed_p;
 
 	ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP);
 
@@ -1124,21 +1146,8 @@
 		break;
       
 	case PIPE_INTERRUPT:
-		int_branch = ed->int_branch;
-		interval = ed->int_interval;
-
-		for (i = 0; i < ep_rev (6, interval); i += inter) {
-			for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]), inter = 1; 
-				(*ed_p != 0) && (*ed_p != ed->hwNextED); 
-				ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED), 
-				inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval)) {				
-					if((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) {
-			  			*ed_p = ed->hwNextED;		
-			  			break;
-			  		}
-			  }
-		}
-		for (i = int_branch; i < 32; i += interval)
+		periodic_unlink (ohci, ed, 0, 1);
+		for (i = ed->int_branch; i < 32; i += ed->int_interval)
 		    ohci->ohci_int_load[i] -= ed->int_load;
 #ifdef DEBUG
 		ep_print_int_eds (ohci, "UNLINK_INT");
@@ -1149,23 +1158,13 @@
 		if (ohci->ed_isotail == ed)
 			ohci->ed_isotail = ed->ed_prev;
 		if (ed->hwNextED != 0) 
-		    (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
+		    (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))
+		    	->ed_prev = ed->ed_prev;
 				    
-		if (ed->ed_prev != NULL) {
+		if (ed->ed_prev != NULL)
 			ed->ed_prev->hwNextED = ed->hwNextED;
-		} else {
-			for (i = 0; i < 32; i++) {
-				for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i)]); 
-						*ed_p != 0; 
-						ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED)) {
-					// inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval);
-					if((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) {
-						*ed_p = ed->hwNextED;		
-						break;
-					}
-				}
-			}	
-		}	
+		else
+			periodic_unlink (ohci, ed, 0, 1);
 #ifdef DEBUG
 		ep_print_int_eds (ohci, "UNLINK_ISO");
 #endif
@@ -1337,6 +1336,7 @@
 	td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000);
 
 	/* append to queue */
+	wmb();
 	td->ed->hwTailP = td->hwNextTD;
 }
 
@@ -1400,8 +1400,10 @@
 				cnt++;
 			}
 
-			if (!ohci->sleeping)
+			if (!ohci->sleeping) {
+				wmb();
 				writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
+			}
 			break;
 
 		case PIPE_INTERRUPT:
@@ -1426,8 +1428,10 @@
 			info = usb_pipeout (urb->pipe)? 
  				TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
 			td_fill (ohci, info, data, 0, urb, cnt++);
-			if (!ohci->sleeping)
+			if (!ohci->sleeping) {
+				wmb();
 				writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
+			}
 			break;
 
 		case PIPE_ISOCHRONOUS:
@@ -2351,7 +2355,6 @@
 static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base)
 {
 	ohci_t * ohci;
-	struct usb_bus * bus;
 
 	ohci = (ohci_t *) kmalloc (sizeof *ohci, GFP_KERNEL);
 	if (!ohci)
@@ -2380,14 +2383,15 @@
 
 	INIT_LIST_HEAD (&ohci->timeout_list);
 
-	bus = usb_alloc_bus (&sohci_device_operations);
-	if (!bus) {
+	ohci->bus = usb_alloc_bus (&sohci_device_operations);
+	if (!ohci->bus) {
+		pci_set_drvdata (dev, NULL);
+		pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
+				ohci->hcca, ohci->hcca_dma);
 		kfree (ohci);
 		return NULL;
 	}
-
-	ohci->bus = bus;
-	bus->hcpriv = (void *) ohci;
+	ohci->bus->hcpriv = (void *) ohci;
 
 	return ohci;
 } 
@@ -2413,9 +2417,11 @@
 		ohci->irq = -1;
 	}
 	pci_set_drvdata(ohci->ohci_dev, NULL);
-
-	usb_deregister_bus (ohci->bus);
-	usb_free_bus (ohci->bus);
+	if (ohci->bus) {
+		if (ohci->bus->busnum)
+			usb_deregister_bus (ohci->bus);
+		usb_free_bus (ohci->bus);
+	}
 
 	list_del (&ohci->ohci_hcd_list);
 	INIT_LIST_HEAD (&ohci->ohci_hcd_list);
@@ -2563,12 +2569,14 @@
 {
 	unsigned long mem_resource, mem_len;
 	void *mem_base;
+	int status;
 
 	if (pci_enable_device(dev) < 0)
 		return -ENODEV;
 
         if (!dev->irq) {
         	err("found OHCI device with no IRQ assigned. check BIOS settings!");
+		pci_disable_device (dev);
    	        return -ENODEV;
         }
 	
@@ -2577,19 +2585,28 @@
 	mem_len = pci_resource_len(dev, 0);
 	if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
 		dbg ("controller already in use");
+		pci_disable_device (dev);
 		return -EBUSY;
 	}
 
 	mem_base = ioremap_nocache (mem_resource, mem_len);
 	if (!mem_base) {
 		err("Error mapping OHCI memory");
+		release_mem_region (mem_resource, mem_len);
+		pci_disable_device (dev);
 		return -EFAULT;
 	}
 
 	/* controller writes into our memory */
 	pci_set_master (dev);
 
-	return hc_found_ohci (dev, dev->irq, mem_base, id);
+	status = hc_found_ohci (dev, dev->irq, mem_base, id);
+	if (status < 0) {
+		iounmap (mem_base);
+		release_mem_region (mem_resource, mem_len);
+		pci_disable_device (dev);
+	}
+	return status;
 } 
 
 /*-------------------------------------------------------------------------*/
@@ -2627,6 +2644,7 @@
 	hc_release_ohci (ohci);
 
 	release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
+	pci_disable_device (dev);
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/usb-ohci.h linux/drivers/usb/usb-ohci.h
--- linux.orig/drivers/usb/usb-ohci.h	2001-10-24 15:26:12.000000000 +0000
+++ linux/drivers/usb/usb-ohci.h	2002-07-20 01:08:28.000000000 +0000
@@ -439,7 +439,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL)
+#define ALLOC_FLAGS (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_KERNEL)
 
 #ifdef DEBUG
 #	define OHCI_MEM_FLAGS	SLAB_POISON
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/usb-skeleton.c linux/drivers/usb/usb-skeleton.c
--- linux.orig/drivers/usb/usb-skeleton.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/usb-skeleton.c	2002-07-20 01:08:35.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * USB Skeleton driver - 0.6
+ * USB Skeleton driver - 0.7
  *
  * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
  *
@@ -22,6 +22,9 @@
  *
  * History:
  *
+ * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do
+ *			not have both a bulk in and bulk out endpoint.
+ *			Thanks to Holger Waechtler for the fix.
  * 2001_11_05 - 0.6 - fix minor locking problem in skel_disconnect.
  *			Thanks to Pete Zaitcev for the fix.
  * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux
@@ -540,6 +543,7 @@
 		err ("Out of memory");
 		goto exit;
 	}
+	memset (dev, 0x00, sizeof (*dev));
 	minor_table[minor] = dev;
 
 	interface = &udev->actconfig->interface[ifnum];
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/usb-uhci.c linux/drivers/usb/usb-uhci.c
--- linux.orig/drivers/usb/usb-uhci.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/usb-uhci.c	2002-07-20 01:08:35.000000000 +0000
@@ -86,8 +86,8 @@
 	static kmem_cache_t *urb_priv_kmem;
 #endif
 
-#define SLAB_FLAG     (in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL)
-#define KMALLOC_FLAG  (in_interrupt ()? GFP_ATOMIC : GFP_KERNEL)
+#define SLAB_FLAG     (in_interrupt () || current->state != TASK_RUNNING ? SLAB_ATOMIC : SLAB_KERNEL)
+#define KMALLOC_FLAG  (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_KERNEL)
 
 /* CONFIG_USB_UHCI_HIGH_BANDWITH turns on Full Speed Bandwidth
  * Reclamation: feature that puts loop on descriptor loop when
@@ -95,7 +95,7 @@
  * is optimal, but PCI can be slowed down up-to 5 times, slowing down
  * system performance (eg. framebuffer devices).
  */
-#define CONFIG_USB_UHCI_HIGH_BANDWIDTH 
+#define CONFIG_USB_UHCI_HIGH_BANDWIDTH
 
 /* *_DEPTH_FIRST puts descriptor in depth-first mode. This has
  * somehow similar effect to FSBR (higher speed), but does not
@@ -143,7 +143,7 @@
 	q=s->free_desc.prev;
 
 	while (q != &s->free_desc && (force || n<100)) {
-		qh = list_entry (q, uhci_desc_t, horizontal);		
+		qh = list_entry (q, uhci_desc_t, horizontal);
 		q=qh->horizontal.prev;
 
 		if ((qh->last_used!=now) || force)
@@ -170,7 +170,7 @@
 #ifdef CONFIG_USB_UHCI_HIGH_BANDWIDTH
 _static void enable_desc_loop(uhci_t *s, urb_t *urb)
 {
-	int flags;
+	unsigned long flags;
 
 	if (urb->transfer_flags & USB_NO_FSBR)
 		return;
@@ -185,7 +185,7 @@
 /*-------------------------------------------------------------------*/
 _static void disable_desc_loop(uhci_t *s, urb_t *urb)
 {
-	int flags;
+	unsigned long flags;
 
 	if (urb->transfer_flags & USB_NO_FSBR)
 		return;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/usb-uhci.h linux/drivers/usb/usb-uhci.h
--- linux.orig/drivers/usb/usb-uhci.h	2001-08-28 18:21:02.000000000 +0000
+++ linux/drivers/usb/usb-uhci.h	2002-07-20 01:08:24.000000000 +0000
@@ -11,7 +11,7 @@
 {
 	if(!in_interrupt())
 	{
-		current->state = TASK_UNINTERRUPTIBLE;
+		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1 + ms * HZ / 1000);
 	}
 	else
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/usb.c linux/drivers/usb/usb.c
--- linux.orig/drivers/usb/usb.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/usb.c	2002-07-20 01:08:37.000000000 +0000
@@ -1955,7 +1955,7 @@
 	/* 9.4.10 says devices don't need this, if the interface
 	   only has one alternate setting */
 	if (iface->num_altsetting == 1) {
-		warn("ignoring set_interface for dev %d, iface %d, alt %d",
+		dbg("ignoring set_interface for dev %d, iface %d, alt %d",
 			dev->devnum, interface, alternate);
 		return 0;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/usbmouse.c linux/drivers/usb/usbmouse.c
--- linux.orig/drivers/usb/usbmouse.c	2001-09-14 21:04:07.000000000 +0000
+++ linux/drivers/usb/usbmouse.c	2002-07-20 01:08:33.000000000 +0000
@@ -114,7 +114,9 @@
 	endpoint = interface->endpoint + 0;
 	if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
 	if ((endpoint->bmAttributes & 3) != 3) return NULL;
-
+	/* wacom tablets match... */
+ 	if (dev->descriptor.idVendor == 0x056a) return NULL;
+	
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/usbnet.c linux/drivers/usb/usbnet.c
--- linux.orig/drivers/usb/usbnet.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/usbnet.c	2002-07-20 01:08:21.000000000 +0000
@@ -518,25 +518,25 @@
 
 		// allocate the skb for the individual packet
 		gl_skb = alloc_skb (size, GFP_ATOMIC);
-		if (gl_skb == 0)
-			return 0;
+		if (gl_skb) {
 
-		// copy the packet data to the new skb
-		memcpy (gl_skb->data, packet->packet_data, size);
+			// copy the packet data to the new skb
+			memcpy (gl_skb->data, packet->packet_data, size);
 
-		// set skb data size
-		gl_skb->len = size;
-		gl_skb->dev = &dev->net;
+			// set skb data size
+			gl_skb->len = size;
+			gl_skb->dev = &dev->net;
 
-		// determine the packet's protocol ID
-		gl_skb->protocol = eth_type_trans (gl_skb, &dev->net);
+			// determine the packet's protocol ID
+			gl_skb->protocol = eth_type_trans (gl_skb, &dev->net);
 
-		// update the status
-		dev->stats.rx_packets++;
-		dev->stats.rx_bytes += size;
+			// update the status
+			dev->stats.rx_packets++;
+			dev->stats.rx_bytes += size;
 
-		// notify os of the received packet
-		status = netif_rx (gl_skb);
+			// notify os of the received packet
+			status = netif_rx (gl_skb);
+		}
 
 		// advance to the next packet
 		packet = (struct gl_packet *)
@@ -989,9 +989,8 @@
 			|| skb->len > FRAMED_SIZE (dev->net.mtu)) {
 		dev->stats.rx_frame_errors++;
 		dbg ("rx framesize %d range %d..%d mtu %d", skb->len,
-			MIN_FRAMED, FRAMED_SIZE (dev->net.mtu),
-			dev->net.mtu
-			);
+			(int)MIN_FRAMED, (int)FRAMED_SIZE (dev->net.mtu),
+			dev->net.mtu);
 		return 0;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/vicam.c linux/drivers/usb/vicam.c
--- linux.orig/drivers/usb/vicam.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/usb/vicam.c	2002-07-20 01:08:27.000000000 +0000
@@ -79,7 +79,7 @@
 static struct usb_driver vicam_driver;
 
 static char *buf, *buf2;
-static int change_pending = 0; 
+static volatile int change_pending = 0; 
 
 static int vicam_parameters(struct usb_vicam *vicam);
 
@@ -330,8 +330,14 @@
 
 static void synchronize(struct usb_vicam *vicam)
 {
+	DECLARE_WAITQUEUE(wait, current);
 	change_pending = 1;
-	interruptible_sleep_on(&vicam->wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	add_wait_queue(&vicam->wait, &wait);
+	if (change_pending)
+		schedule();
+	remove_wait_queue(&vicam->wait, &wait);
+	set_current_state(TASK_RUNNING);
 	vicam_sndctrl(1, vicam, VICAM_REQ_CAMERA_POWER, 0x00, NULL, 0);
 	mdelay(10);
 	vicam_sndctrl(1, vicam, VICAM_REQ_LED_CONTROL, 0x00, NULL, 0);
@@ -890,13 +896,16 @@
 	vicam->win.contrast = 10;
 
 	/* FIXME */
-	if (vicam_init(vicam))
+	if (vicam_init(vicam)) {
+		kfree(vicam);
 		return NULL;
+	}
 	memcpy(&vicam->vdev, &vicam_template, sizeof(vicam_template));
 	memcpy(vicam->vdev.name, vicam->camera_name, strlen(vicam->camera_name));
 	
 	if (video_register_device(&vicam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
 		err("video_register_device");
+		kfree(vicam);
 		return NULL;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/usb/wacom.c linux/drivers/usb/wacom.c
--- linux.orig/drivers/usb/wacom.c	2001-09-18 05:52:35.000000000 +0000
+++ linux/drivers/usb/wacom.c	2002-07-20 01:08:24.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: wacom.c,v 1.22 2001/04/26 11:26:09 vojtech Exp $
+ * $Id: wacom.c,v 1.23 2001/05/29 12:57:18 vojtech Exp $
  *
  *  Copyright (c) 2000-2001 Vojtech Pavlik	<vojtech@suse.cz>
  *  Copyright (c) 2000 Andreas Bach Aaen	<abach@stofanet.dk>
@@ -39,6 +39,13 @@
  *	v1.21 (vp) - Removed protocol descriptions
  *		   - Added MISC_SERIAL for tool serial numbers
  *	      (gb) - Identify version on module load.
+ *    v1.21.1 (fl) - added Graphire2 support
+ *    v1.21.2 (fl) - added Intuos2 support
+ *                 - added all the PL ids
+ *    v1.21.3 (fl) - added another eraser id from Neil Okamoto
+ *                 - added smooth filter for Graphire from Peri Hankey
+ *                 - added PenPartner support from Olaf van Es
+ *                 - new tool ids from Ole Martin Bjoerndalen
  */
 
 /*
@@ -71,7 +78,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.21"
+#define DRIVER_VERSION "v1.21.3"
 #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
 #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
 
@@ -117,9 +124,11 @@
 
 	if (urb->status) return;
 
-	if (data[0] != 2)
-		dbg("received unknown report #%d", data[0]);
-
+	if (data[0] != 2) {
+		printk(KERN_ERR "wacom_pl_irq: received unknown report #%d\n", data[0]);
+		return;
+	}
+	
 	prox = data[1] & 0x20;
 	
 	input_report_key(dev, BTN_TOOL_PEN, prox);
@@ -138,6 +147,33 @@
 	input_event(dev, EV_MSC, MSC_SERIAL, 0);
 }
 
+static void wacom_penpartner_irq(struct urb *urb)
+{
+	struct wacom *wacom = urb->context;
+	unsigned char *data = wacom->data;
+	struct input_dev *dev = &wacom->dev;
+	int x, y; 
+	char pressure; 
+	int leftmb;
+
+	if (urb->status) return;
+
+	x = data[2] << 8 | data[1];
+	y = data[4] << 8 | data[3];
+	pressure = data[6];
+	leftmb = ((pressure > -80) && !(data[5] &20));
+
+	input_report_key(dev, BTN_TOOL_PEN, 1);
+
+	input_report_abs(dev, ABS_X, x);
+	input_report_abs(dev, ABS_Y, y);
+	input_report_abs(dev, ABS_PRESSURE, pressure+127);
+	input_report_key(dev, BTN_LEFT, leftmb);
+	input_report_key(dev, BTN_RIGHT, (data[5] & 0x40));
+	
+	input_event(dev, EV_MSC, MSC_SERIAL, leftmb);
+}
+
 static void wacom_graphire_irq(struct urb *urb)
 {
 	struct wacom *wacom = urb->context;
@@ -147,9 +183,11 @@
 
 	if (urb->status) return;
 
-	if (data[0] != 2)
-		dbg("received unknown report #%d", data[0]);
-
+	if (data[0] != 2) {
+		printk(KERN_ERR "wacom_graphire_irq: received unknown report #%d\n", data[0]);
+		return;
+	}
+	
 	x = data[2] | ((__u32)data[3] << 8);
 	y = data[4] | ((__u32)data[5] << 8);
 
@@ -171,8 +209,8 @@
 			input_report_abs(dev, ABS_DISTANCE, data[7]);
 			input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
 
-			input_report_abs(dev, ABS_X, x);
-			input_report_abs(dev, ABS_Y, y);
+			input_report_abs(dev, ABS_X, wacom->x = x);
+			input_report_abs(dev, ABS_Y, wacom->y = y);
 
 			input_event(dev, EV_MSC, MSC_SERIAL, data[1] & 0x01);
 			return;
@@ -198,12 +236,15 @@
 	struct input_dev *dev = &wacom->dev;
 	unsigned int t;
 	int idx;
+	int x, y; 
 
 	if (urb->status) return;
 
-	if (data[0] != 2)
-		dbg("received unknown report #%d", data[0]);
-
+	if (data[0] != 2) {
+		printk(KERN_ERR "wacom_intuos_irq: received unknown report #%d\n", data[0]);
+		return;
+	}
+	
 	/* tool number */
 	idx = data[1] & 0x01;
 
@@ -217,18 +258,21 @@
 			case 0x832:
 			case 0x012: wacom->tool[idx] = BTN_TOOL_PENCIL;		break;	/* Inking pen */
 			case 0x822:
+		        case 0x852:
 			case 0x022: wacom->tool[idx] = BTN_TOOL_PEN;		break;	/* Pen */
 			case 0x812:
 			case 0x032: wacom->tool[idx] = BTN_TOOL_BRUSH;		break;	/* Stroke pen */
 		        case 0x09c:
+		        case 0x007:
 			case 0x094: wacom->tool[idx] = BTN_TOOL_MOUSE;		break;	/* Mouse 4D */
 			case 0x096: wacom->tool[idx] = BTN_TOOL_LENS;		break;	/* Lens cursor */
 			case 0x82a:
+		        case 0x85a:
 		        case 0x91a:
 			case 0x0fa: wacom->tool[idx] = BTN_TOOL_RUBBER;		break;	/* Eraser */
 			case 0x112: wacom->tool[idx] = BTN_TOOL_AIRBRUSH;	break;	/* Airbrush */
 			default:    wacom->tool[idx] = BTN_TOOL_PEN;		break;	/* Unknown tool */
-		}	
+		}
 
 		input_report_key(dev, wacom->tool[idx], 1);
 		input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
@@ -241,10 +285,13 @@
 		return;
 	}
 
-	input_report_abs(dev, ABS_X, ((__u32)data[2] << 8) | data[3]);
-	input_report_abs(dev, ABS_Y, ((__u32)data[4] << 8) | data[5]);
+	x = ((__u32)data[2] << 8) | data[3];
+	y = ((__u32)data[4] << 8) | data[5];
+	
+	input_report_abs(dev, ABS_X, wacom->x);
+	input_report_abs(dev, ABS_Y, wacom->y);
 	input_report_abs(dev, ABS_DISTANCE, data[9] >> 4);
-
+	
 	if ((data[1] & 0xb8) == 0xa0) {						/* general pen packet */
 		input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
 		input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7));
@@ -298,8 +345,14 @@
 #define WACOM_INTUOS_ABS	(BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE))
 
 struct wacom_features wacom_features[] = {
+	{ "Wacom Penpartner",	 7,  5040,  3780,  255, 32, wacom_penpartner_irq,
+		0, 0, 0, 0 },
 	{ "Wacom Graphire",      8, 10206,  7422,  511, 32, wacom_graphire_irq,
 		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
+	{ "Wacom Graphire2 4x5",     8, 10206,  7422,  511, 32, wacom_graphire_irq,
+		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
+	{ "Wacom Graphire2 5x7",     8, 10206,  7422,  511, 32, wacom_graphire_irq,
+		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
 	{ "Wacom Intuos 4x5",   10, 12700, 10360, 1023, 15, wacom_intuos_irq,
 		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
 	{ "Wacom Intuos 6x8",   10, 20320, 15040, 1023, 15, wacom_intuos_irq,
@@ -310,19 +363,52 @@
 		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
 	{ "Wacom Intuos 12x18", 10, 47720, 30480, 1023, 15, wacom_intuos_irq,
 		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom PL400",        8,  12328, 9256,   511, 32, wacom_pl_irq,
+		0,  0, 0, 0 },
 	{ "Wacom PL500",        8,  12328, 9256,   511, 32, wacom_pl_irq,
 		0,  0, 0, 0 },
+	{ "Wacom PL600",        8,  12328, 9256,   511, 32, wacom_pl_irq,
+		0,  0, 0, 0 },
+	{ "Wacom PL600SX",        8,  12328, 9256,   511, 32, wacom_pl_irq,
+		0,  0, 0, 0 },
+	{ "Wacom PL550",        8,  12328, 9256,   511, 32, wacom_pl_irq,
+		0,  0, 0, 0 },
+	{ "Wacom PL800",        8,  12328, 9256,   511, 32, wacom_pl_irq,
+		0,  0, 0, 0 },
+	{ "Wacom Intuos2 4x5",   10, 12700, 10360, 1023, 15, wacom_intuos_irq,
+		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos2 6x8",   10, 20320, 15040, 1023, 15, wacom_intuos_irq,
+		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos2 9x12",  10, 30480, 23060, 1023, 15, wacom_intuos_irq,
+		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos2 12x12", 10, 30480, 30480, 1023, 15, wacom_intuos_irq,
+		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos2 12x18", 10, 47720, 30480, 1023, 15, wacom_intuos_irq,
+		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
 	{ NULL , 0 }
 };
 
 struct usb_device_id wacom_ids[] = {
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10), driver_info: 0 },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20), driver_info: 1 },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21), driver_info: 2 },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22), driver_info: 3 },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23), driver_info: 4 },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24), driver_info: 5 },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31), driver_info: 6 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00), driver_info: 0 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10), driver_info: 1 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11), driver_info: 2 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12), driver_info: 3 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20), driver_info: 4 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21), driver_info: 5 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22), driver_info: 6 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23), driver_info: 7 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24), driver_info: 8 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30), driver_info: 9 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31), driver_info: 10 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32), driver_info: 11 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33), driver_info: 12 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34), driver_info: 13 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35), driver_info: 14 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41), driver_info: 15 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42), driver_info: 16 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43), driver_info: 17 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44), driver_info: 18 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45), driver_info: 19 },
 	{ }
 };
 
@@ -331,7 +417,7 @@
 static int wacom_open(struct input_dev *dev)
 {
 	struct wacom *wacom = dev->private;
-
+	
 	if (wacom->open++)
 		return 0;
 
@@ -354,7 +440,8 @@
 {
 	struct usb_endpoint_descriptor *endpoint;
 	struct wacom *wacom;
-
+	char rep_data[2] = {0x02, 0x02};
+	
 	if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return NULL;
 	memset(wacom, 0, sizeof(struct wacom));
 
@@ -397,13 +484,20 @@
 
 	endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
 
+	usb_set_idle(dev, dev->config[0].interface[ifnum].altsetting[0].bInterfaceNumber, 0, 0);
+
 	FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
 		     wacom->data, wacom->features->pktlen, wacom->features->irq, wacom, endpoint->bInterval);
 
 	input_register_device(&wacom->dev);
 
+	/* ask the tablet to report tablet data */
+	usb_set_report(dev, ifnum, 3, 2, rep_data, 2);
+	usb_set_report(dev, ifnum, 3, 5, rep_data, 0);
+	usb_set_report(dev, ifnum, 3, 6, rep_data, 0);
+	
 	printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
-		 wacom->dev.number, wacom->features->name, dev->bus->busnum, dev->devnum, ifnum);
+	       wacom->dev.number, wacom->features->name, dev->bus->busnum, dev->devnum, ifnum);
 
 	return wacom;
 }
@@ -426,7 +520,8 @@
 static int __init wacom_init(void)
 {
 	usb_register(&wacom_driver);
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	info(DRIVER_VERSION " " DRIVER_AUTHOR);
+	info(DRIVER_DESC);
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/Config.in linux/drivers/video/Config.in
--- linux.orig/drivers/video/Config.in	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/Config.in	2002-07-20 01:08:37.000000000 +0000
@@ -26,6 +26,9 @@
 	    fi
 	 fi
       fi
+      if [ "$CONFIG_PCI" = "y" ]; then
+         tristate '  Permedia3 support (EXPERIMENTAL)' CONFIG_FB_PM3
+      fi
    fi
    if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
       bool '  Acorn VIDC support' CONFIG_FB_ACORN
@@ -128,7 +131,7 @@
 	          dep_tristate '      G400 second head support' CONFIG_FB_MATROX_MAVEN $CONFIG_FB_MATROX_I2C
 	       fi
             fi
-            dep_tristate '      G450/G550 second head support' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100
+            dep_tristate '      G450/G550 second head support (mandatory for G550)' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100
 	    bool '    Multihead support' CONFIG_FB_MATROX_MULTIHEAD
 	 fi
 	 tristate '  ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY
@@ -143,6 +146,7 @@
 	    bool '    SIS 630/540/730 support' CONFIG_FB_SIS_300
 	    bool '    SIS 315H/315 support' CONFIG_FB_SIS_315
 	 fi
+	 tristate '  NeoMagic display support (EXPERIMENTAL)' CONFIG_FB_NEOMAGIC
 	 tristate '  3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX
 	 tristate '  3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)' CONFIG_FB_VOODOO1
 	 tristate '  Trident support (EXPERIMENTAL)' CONFIG_FB_TRIDENT
@@ -263,13 +267,14 @@
 	   "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
            "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
 	   "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
+           "$CONFIG_FB_PM3" = "y" -o \
 	   "$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
 	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
 	   "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
 	   "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \
 	   "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \
 	   "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
-	   "$CONFIG_FB_SIS" = "y" ]; then
+	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB8 y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
@@ -283,13 +288,14 @@
 	      "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
               "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
 	      "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
+              "$CONFIG_FB_PM3" = "m" -o \
 	      "$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
 	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
 	      "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
 	      "$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \
 	      "$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
-	      "$CONFIG_FB_TX3912" = "m" ]; then
+	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB8 m
 	 fi
       fi
@@ -302,10 +308,12 @@
 	   "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
 	   "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
 	   "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
+           "$CONFIG_FB_PM3" = "y" -o \
 	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
 	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y"  -o \
 	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
-	   "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" ]; then
+	   "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
+	   "$CONFIG_FB_NEOMAGIC" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB16 y
       else
 	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
@@ -317,10 +325,12 @@
 	      "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
 	      "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
 	      "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
+              "$CONFIG_FB_PM3" = "m" -o \
 	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
 	      "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
-	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" ]; then
+	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
+	      "$CONFIG_FB_NEOMAGIC" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB16 m
 	 fi
       fi
@@ -329,7 +339,7 @@
 	   "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
            "$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
 	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
-	   "$CONFIG_FB_VOODOO1" = "y" ]; then
+	   "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB24 y
       else
 	 if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
@@ -337,7 +347,7 @@
 	      "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
 	      "$CONFIG_FB_ATY128" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
-	      "$CONFIG_FB_VOODOO1" = "m" ]; then
+	      "$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB24 m
 	 fi
       fi
@@ -346,11 +356,12 @@
 	   "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
 	   "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
 	   "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
+           "$CONFIG_FB_PM3" = "y" -o \
 	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
 	   "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
 	   "$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
 	   "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_SIS" = "y" -o \
-	   "$CONFIG_FB_VOODOO1" = "y" ]; then
+	   "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB32 y
       else
 	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
@@ -358,10 +369,12 @@
 	      "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
 	      "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
 	      "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
+              "$CONFIG_FB_PM3" = "m" -o \
 	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
 	      "$CONFIG_FB_3DFX" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
-	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" ]; then
+	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
+	      "$CONFIG_FB_CYBER2000" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB32 m
 	 fi
       fi
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/Makefile linux/drivers/video/Makefile
--- linux.orig/drivers/video/Makefile	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/Makefile	2002-07-20 01:08:25.000000000 +0000
@@ -15,7 +15,7 @@
 		  fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
 		  fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
 		  fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
-		  cyber2000fb.o sa1100fb.o fbcon-hga.o
+		  cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
 
 # Each configuration option enables a list of files.
 
@@ -44,11 +44,13 @@
 obj-$(CONFIG_FB_ACORN)            += acornfb.o
 obj-$(CONFIG_FB_AMIGA)            += amifb.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o fbgen.o
+obj-$(CONFIG_FB_PM3)              += pm3fb.o fbgen.o
 obj-$(CONFIG_FB_APOLLO)           += dnfb.o
 obj-$(CONFIG_FB_Q40)              += q40fb.o
 obj-$(CONFIG_FB_ATARI)            += atafb.o
 obj-$(CONFIG_FB_ATY128)           += aty128fb.o
 obj-$(CONFIG_FB_RADEON)		  += radeonfb.o
+obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o
 obj-$(CONFIG_FB_IGA)              += igafb.o
 obj-$(CONFIG_FB_CONTROL)          += controlfb.o
 obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/acornfb.c linux/drivers/video/acornfb.c
--- linux.orig/drivers/video/acornfb.c	2001-11-14 22:52:20.000000000 +0000
+++ linux/drivers/video/acornfb.c	2002-07-20 01:08:34.000000000 +0000
@@ -1139,9 +1139,6 @@
 	off += start;
 	vma->vm_pgoff = off >> PAGE_SHIFT;
 
-	/* This is an IO map - tell maydump to skip this VMA */
-	vma->vm_flags |= VM_IO;
-
 #ifdef CONFIG_CPU_32
 	pgprot_val(vma->vm_page_prot) &= ~L_PTE_CACHEABLE;
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/amifb.c linux/drivers/video/amifb.c
--- linux.orig/drivers/video/amifb.c	2001-11-14 22:52:20.000000000 +0000
+++ linux/drivers/video/amifb.c	2002-07-20 01:08:31.000000000 +0000
@@ -61,7 +61,6 @@
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
 #include <asm/setup.h>
-#include <asm/io.h>
 
 #include <video/fbcon.h>
 #include <video/fbcon-afb.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/aty/atyfb_base.c linux/drivers/video/aty/atyfb_base.c
--- linux.orig/drivers/video/aty/atyfb_base.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/aty/atyfb_base.c	2002-07-20 01:08:26.000000000 +0000
@@ -304,7 +304,7 @@
 static char m64n_mob_a[] __initdata = "3D RAGE Mobility (AGP)";
 #endif /* CONFIG_FB_ATY_CT */
 
-static const struct {
+static struct {
     u16 pci_id, chip_type;
     u8 rev_mask, rev_val;
     const char *name;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/aty/mach64_accel.c linux/drivers/video/aty/mach64_accel.c
--- linux.orig/drivers/video/aty/mach64_accel.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/aty/mach64_accel.c	2002-07-20 01:08:22.000000000 +0000
@@ -3,6 +3,7 @@
  *  ATI Mach64 Hardware Acceleration
  */
 
+#include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/aty/mach64_gx.c linux/drivers/video/aty/mach64_gx.c
--- linux.orig/drivers/video/aty/mach64_gx.c	2001-07-31 21:43:29.000000000 +0000
+++ linux/drivers/video/aty/mach64_gx.c	2002-07-20 01:08:27.000000000 +0000
@@ -5,6 +5,7 @@
 
 #include <linux/delay.h>
 #include <linux/fb.h>
+#include <linux/sched.h>
 
 #include <asm/io.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/aty128fb.c linux/drivers/video/aty128fb.c
--- linux.orig/drivers/video/aty128fb.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/aty128fb.c	2002-07-20 01:08:36.000000000 +0000
@@ -164,6 +164,7 @@
     {"Rage128 Pro PF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_PF, rage_128_pro},
     {"Rage128 Pro PR (PCI)", PCI_DEVICE_ID_ATI_RAGE128_PR, rage_128_pro},
     {"Rage128 Pro TR (AGP)", PCI_DEVICE_ID_ATI_RAGE128_U3, rage_128_pro},
+    {"Rage128 Pro TF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_U1, rage_128_pro},
     {"Rage Mobility M3 (PCI)", PCI_DEVICE_ID_ATI_RAGE128_LE, rage_M3},
     {"Rage Mobility M3 (AGP)", PCI_DEVICE_ID_ATI_RAGE128_LF, rage_M3},
     {NULL, 0, rage_128}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/chipsfb.c linux/drivers/video/chipsfb.c
--- linux.orig/drivers/video/chipsfb.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/video/chipsfb.c	2002-07-20 01:08:35.000000000 +0000
@@ -79,7 +79,7 @@
 } while (0)
 #define read_ind(num, var, ap, dp)	do { \
 	outb((num), (ap)); var = inb((dp)); \
-} while (0);
+} while (0)
 
 /* extension registers */
 #define write_xr(num, val)	write_ind(num, val, 0x3d6, 0x3d7)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/clgenfb.c linux/drivers/video/clgenfb.c
--- linux.orig/drivers/video/clgenfb.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/clgenfb.c	2002-07-20 01:08:31.000000000 +0000
@@ -415,8 +415,6 @@
 static unsigned clgen_def_mode = 1;
 static int noaccel = 0;
 
-static int release_io_ports = 0;
-
 
 
 /*
@@ -2413,6 +2411,8 @@
 
 
 #ifdef CONFIG_PCI
+static int release_io_ports = 0;
+
 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
@@ -2635,11 +2635,11 @@
 	release_mem_region(info->board_addr, info->board_size);
 
 	if (info->btype == BT_PICASSO4) {
-		iounmap (info->board_addr);
-		iounmap (info->fbmem_phys);
+		iounmap ((void *)info->board_addr);
+		iounmap ((void *)info->fbmem_phys);
 	} else {
 		if (info->board_addr > 0x01000000)
-			iounmap (info->board_addr);
+			iounmap ((void *)info->board_addr);
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/cyber2000fb.c linux/drivers/video/cyber2000fb.c
--- linux.orig/drivers/video/cyber2000fb.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/video/cyber2000fb.c	2002-07-20 01:08:28.000000000 +0000
@@ -6,11 +6,14 @@
  *  MIPS and 50xx clock support
  *  Copyright (C) 2001 Bradley D. LaRonde <brad@ltc.com>
  *
+ *  32 bit support, text color and panning fixes for modes != 8 bit
+ *  Copyright (C) 2002 Denis Oliver Kropp <dok@directfb.org>
+ *
  * 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.
  *
- * Integraphics CyberPro 2000, 2010 and 5000 frame buffer device
+ * Intergraphics CyberPro 2000, 2010 and 5000 frame buffer device
  *
  * Based on cyberfb.c.
  *
@@ -50,6 +53,7 @@
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
 
 /*
  * Define this if you don't want RGB565, but RGB555 for 16bpp displays.
@@ -249,6 +253,11 @@
 		cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
 		bgx = ((u32 *)p->dispsw_data)[bgx];
 		break;
+
+	case 32:
+		bgx = ((u32 *)p->dispsw_data)[bgx];
+		cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
+		break;
 	}
 
 	cyber2000fb_writel(bgx, CO_REG_FOREGROUND, cfb);
@@ -313,12 +322,15 @@
 {
 	struct cfb_info *cfb = (struct cfb_info *)info;
 
+	u_int alpha = transp ^ 0xFFFF;
+
 	if (regno >= NR_PALETTE)
 		return 1;
 
 	red   >>= 8;
 	green >>= 8;
 	blue  >>= 8;
+	alpha >>= 8;
 
 	cfb->palette[regno].red   = red;
 	cfb->palette[regno].green = green;
@@ -355,7 +367,9 @@
 
 		if (regno < 16)
 			((u16 *)cfb->fb.pseudo_palette)[regno] =
-				regno | regno << 5 | regno << 11;
+				((red   << 8) & 0xf800) |
+				((green << 3) & 0x07e0) |
+				((blue  >> 3));
 		break;
 #endif
 
@@ -368,7 +382,9 @@
 		}
 		if (regno < 16)
 			((u16 *)cfb->fb.pseudo_palette)[regno] =
-				regno | regno << 5 | regno << 10;
+				((red   << 7) & 0x7c00) |
+				((green << 2) & 0x03e0) |
+				((blue  >> 3));
 		break;
 
 #endif
@@ -382,7 +398,20 @@
 
 		if (regno < 16)
 			((u32 *)cfb->fb.pseudo_palette)[regno] =
-				regno | regno << 8 | regno << 16;
+				(red << 16) | (green << 8) | blue;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		cyber2000fb_writeb(regno, 0x3c8, cfb);
+		cyber2000fb_writeb(red,   0x3c9, cfb);
+		cyber2000fb_writeb(green, 0x3c9, cfb);
+		cyber2000fb_writeb(blue,  0x3c9, cfb);
+
+		if (regno < 16)
+			((u32 *)cfb->fb.pseudo_palette)[regno] =
+				(alpha << 24) | (red << 16) | (green << 8) | blue;
 		break;
 #endif
 
@@ -523,6 +552,10 @@
 
 	base = var->yoffset * var->xres_virtual + var->xoffset;
 
+	/* have to be careful, because bits_per_pixel might be 15
+	   in this version of the driver -- dok@directfb.org 2002/06/13 */
+	base *= (var->bits_per_pixel + 7) >> 3;
+
 	base >>= 2;
 
 	if (base >= 1 << 20)
@@ -808,6 +841,14 @@
 		hw->palette_ctrl	|= 0x10;
 		break;
 #endif
+#ifdef FBCON_HAS_CFB32
+	case 32:/* TRUECOLOUR, 16m */
+		hw->pixformat		= PIXFORMAT_32BPP;
+		hw->visualid		= VISUALID_16M_32;
+		hw->pitch		= hw->width >> 1;
+		hw->palette_ctrl	|= 0x10;
+		break;
+#endif
 	default:
 		return -EINVAL;
 	}
@@ -902,7 +943,6 @@
 #ifdef FBCON_HAS_CFB16
 	case 16:/* DIRECTCOLOUR, 64k */
 #ifndef CFB16_IS_CFB15
-		var->bits_per_pixel	= 15;
 		var->red.offset		= 11;
 		var->red.length		= 5;
 		var->green.offset	= 5;
@@ -946,6 +986,23 @@
 		display->next_line	= var->xres_virtual * 3;
 		break;
 #endif
+#ifdef FBCON_HAS_CFB32
+	case 32:/* TRUECOLOUR, 16m */
+		var->transp.offset	= 24;
+		var->transp.length	= 8;
+		var->red.offset		= 16;
+		var->red.length		= 8;
+		var->green.offset	= 8;
+		var->green.length	= 8;
+		var->blue.offset	= 0;
+		var->blue.length	= 8;
+
+		cfb->fb.fix.visual	= FB_VISUAL_TRUECOLOR;
+		cfb->dispsw		= &fbcon_cfb32;
+		display->dispsw_data	= cfb->fb.pseudo_palette;
+		display->next_line	= var->xres_virtual * 4;
+		break;
+#endif
 	default:/* in theory this should never happen */
 		printk(KERN_WARNING "%s: no support for %dbpp\n",
 		       cfb->fb.fix.id, var->bits_per_pixel);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/cyber2000fb.h linux/drivers/video/cyber2000fb.h
--- linux.orig/drivers/video/cyber2000fb.h	2001-10-11 16:43:30.000000000 +0000
+++ linux/drivers/video/cyber2000fb.h	2002-07-20 01:08:29.000000000 +0000
@@ -39,9 +39,11 @@
 #define PIXFORMAT_8BPP		0
 #define PIXFORMAT_16BPP		1
 #define PIXFORMAT_24BPP		2
+#define PIXFORMAT_32BPP		3
 
 #define VISUALID_256		1
 #define VISUALID_64K		2
+#define VISUALID_16M_32		3
 #define VISUALID_16M		4
 #define VISUALID_32K		6
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/fbcon-cfb24.c linux/drivers/video/fbcon-cfb24.c
--- linux.orig/drivers/video/fbcon-cfb24.c	2001-10-15 20:47:13.000000000 +0000
+++ linux/drivers/video/fbcon-cfb24.c	2002-07-20 01:08:29.000000000 +0000
@@ -76,14 +76,14 @@
 	out1 = (in1<<8)  | (in2>>16); \
 	out2 = (in2<<16) | (in3>>8); \
 	out3 = (in3<<24) | in4; \
-    } while (0);
+    } while (0)
 #elif defined(__LITTLE_ENDIAN)
 #define convert4to3(in1, in2, in3, in4, out1, out2, out3) \
     do { \
 	out1 = in1       | (in2<<24); \
 	out2 = (in2>> 8) | (in3<<16); \
 	out3 = (in3>>16) | (in4<< 8); \
-    } while (0);
+    } while (0)
 #else
 #error FIXME: No endianness??
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/fbgen.c linux/drivers/video/fbgen.c
--- linux.orig/drivers/video/fbgen.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/video/fbgen.c	2002-07-20 01:08:37.000000000 +0000
@@ -106,6 +106,7 @@
     struct fb_info_gen *info2 = (struct fb_info_gen *)info;
     int err;
     int oldxres, oldyres, oldbpp, oldxres_virtual, oldyres_virtual, oldyoffset;
+    struct fb_bitfield oldred, oldgreen, oldblue;
 
     if ((err = fbgen_do_set_var(var, con == currcon, info2)))
 	return err;
@@ -115,12 +116,18 @@
 	oldxres_virtual = fb_display[con].var.xres_virtual;
 	oldyres_virtual = fb_display[con].var.yres_virtual;
 	oldbpp = fb_display[con].var.bits_per_pixel;
+	oldred = fb_display[con].var.red;
+	oldgreen = fb_display[con].var.green;
+	oldblue = fb_display[con].var.blue;
 	oldyoffset = fb_display[con].var.yoffset;
 	fb_display[con].var = *var;
 	if (oldxres != var->xres || oldyres != var->yres ||
 	    oldxres_virtual != var->xres_virtual ||
 	    oldyres_virtual != var->yres_virtual ||
 	    oldbpp != var->bits_per_pixel ||
+	    (!(memcmp(&oldred, &(var->red), sizeof(struct fb_bitfield)))) || 
+	    (!(memcmp(&oldgreen, &(var->green), sizeof(struct fb_bitfield)))) ||
+	    (!(memcmp(&oldblue, &(var->blue), sizeof(struct fb_bitfield)))) ||
 	    oldyoffset != var->yoffset) {
 	    fbgen_set_disp(con, info2);
 	    if (info->changevar)
@@ -441,3 +448,21 @@
 	fbgen_install_cmap(currcon, info2);
 }
 MODULE_LICENSE("GPL");
+
+
+    /*
+     *  Visible symbols for modules
+     */
+
+EXPORT_SYMBOL(fbgen_get_var);
+EXPORT_SYMBOL(fbgen_get_cmap);
+EXPORT_SYMBOL(fbgen_get_fix);
+EXPORT_SYMBOL(fbgen_set_var);
+EXPORT_SYMBOL(fbgen_set_cmap);
+EXPORT_SYMBOL(fbgen_set_disp);
+EXPORT_SYMBOL(fbgen_install_cmap);
+EXPORT_SYMBOL(fbgen_pan_display);
+EXPORT_SYMBOL(fbgen_update_var);
+EXPORT_SYMBOL(fbgen_do_set_var);
+EXPORT_SYMBOL(fbgen_switch);
+EXPORT_SYMBOL(fbgen_blank);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux.orig/drivers/video/fbmem.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/fbmem.c	2002-07-20 01:08:21.000000000 +0000
@@ -59,6 +59,8 @@
 extern int cyberfb_setup(char*);
 extern int pm2fb_init(void);
 extern int pm2fb_setup(char*);
+extern int pm3fb_init(void);
+extern int pm3fb_setup(char*);
 extern int cyber2000fb_init(void);
 extern int retz3fb_init(void);
 extern int retz3fb_setup(char*);
@@ -72,6 +74,8 @@
 extern int atyfb_setup(char*);
 extern int aty128fb_init(void);
 extern int aty128fb_setup(char*);
+extern int neofb_init(void);
+extern int neofb_setup(char*);
 extern int igafb_init(void);
 extern int igafb_setup(char*);
 extern int imsttfb_init(void);
@@ -120,6 +124,10 @@
 extern int sisfb_setup(char*);
 extern int stifb_init(void);
 extern int stifb_setup(char*);
+extern int pmagbafb_init(void);
+extern int pmagbbfb_init(void);
+extern void maxinefb_init(void);
+extern int tx3912fb_init(void);
 extern int radeonfb_init(void);
 extern int radeonfb_setup(char*);
 extern int e1355fb_init(void);
@@ -162,6 +170,9 @@
 #ifdef CONFIG_FB_PM2
 	{ "pm2fb", pm2fb_init, pm2fb_setup },
 #endif
+#ifdef CONFIG_FB_PM3
+	{ "pm3fb", pm3fb_init, pm3fb_setup },
+#endif
 #ifdef CONFIG_FB_CLGEN
 	{ "clgen", clgenfb_init, clgenfb_setup },
 #endif
@@ -174,6 +185,9 @@
 #ifdef CONFIG_FB_ATY128
 	{ "aty128fb", aty128fb_init, aty128fb_setup },
 #endif
+#ifdef CONFIG_FB_NEOMAGIC
+	{ "neo", neofb_init, neofb_setup },
+#endif
 #ifdef CONFIG_FB_VIRGE
 	{ "virge", virgefb_init, virgefb_setup },
 #endif
@@ -210,6 +224,9 @@
 #ifdef CONFIG_FB_TRIDENT
 	{ "trident", tridentfb_init, tridentfb_setup },
 #endif
+#ifdef CONFIG_FB_VOODOO1
+	{ "sst", sstfb_init, sstfb_setup },
+#endif
 
 	/*
 	 * Generic drivers that are used as fallbacks
@@ -275,15 +292,26 @@
 #ifdef CONFIG_FB_HIT
 	{ "hitfb", hitfb_init, NULL },
 #endif
+#ifdef CONFIG_FB_TX3912
+	{ "tx3912", tx3912fb_init, NULL },
+#endif
 #ifdef CONFIG_FB_E1355
 	{ "e1355fb", e1355fb_init, e1355fb_setup },
 #endif
 #ifdef CONFIG_FB_PVR2
 	{ "pvr2", pvr2fb_init, pvr2fb_setup },
 #endif
-#ifdef CONFIG_FB_VOODOO1
-	{ "sst", sstfb_init, sstfb_setup },
+#ifdef CONFIG_FB_PMAG_BA
+	{ "pmagbafb", pmagbafb_init, NULL },
+#endif
+#ifdef CONFIG_FB_PMAGB_B
+	{ "pmagbbfb", pmagbbfb_init, NULL },
 #endif
+#ifdef CONFIG_FB_MAXINE
+	{ "maxinefb", maxinefb_init, NULL },
+#endif
+
+
 	/*
 	 * Generic drivers that don't use resource management (yet)
 	 */
@@ -548,6 +576,8 @@
 		lock_kernel();
 		res = fb->fb_mmap(info, file, vma);
 		unlock_kernel();
+		/* This is an IO map - tell maydump to skip this VMA */
+		vma->vm_flags |= VM_IO;
 		return res;
 	}
 
@@ -581,12 +611,13 @@
 		return -EINVAL;
 	off += start;
 	vma->vm_pgoff = off >> PAGE_SHIFT;
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
 #if defined(__sparc_v9__)
 	vma->vm_flags |= (VM_SHM | VM_LOCKED);
 	if (io_remap_page_range(vma->vm_start, off,
 				vma->vm_end - vma->vm_start, vma->vm_page_prot, 0))
 		return -EAGAIN;
-	vma->vm_flags |= VM_IO;
 #else
 #if defined(__mc68000__)
 #if defined(CONFIG_SUN3)
@@ -607,15 +638,12 @@
 #elif defined(__i386__) || defined(__x86_64__)
 	if (boot_cpu_data.x86 > 3)
 		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-#elif defined(__mips__)
-	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
-	pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
-#elif defined(__arm__)
+#elif defined(__arm__) || defined(__mips__)
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-	/* This is an IO map - tell maydump to skip this VMA */
-	vma->vm_flags |= VM_IO;
 #elif defined(__sh__)
 	pgprot_val(vma->vm_page_prot) &= ~_PAGE_CACHABLE;
+#elif defined(__ia64__)
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 #else
 #warning What do we have to do here??
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/igafb.c linux/drivers/video/igafb.c
--- linux.orig/drivers/video/igafb.c	2001-11-14 22:52:20.000000000 +0000
+++ linux/drivers/video/igafb.c	2002-07-20 01:08:22.000000000 +0000
@@ -293,8 +293,6 @@
 	if (!map_size)
 		return -EINVAL;
 
-	vma->vm_flags |= VM_IO;
-
 	if (!fb->mmaped) {
 		int lastconsole = 0;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/Makefile linux/drivers/video/matrox/Makefile
--- linux.orig/drivers/video/matrox/Makefile	2000-12-29 22:07:23.000000000 +0000
+++ linux/drivers/video/matrox/Makefile	2002-07-20 01:08:29.000000000 +0000
@@ -7,11 +7,13 @@
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
-export-objs    :=  matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o
+export-objs    :=  matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o g450_pll.o
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_FB_MATROX)           += matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o
+my-obj-$(CONFIG_FB_MATROX_G100)	  := g450_pll.o
+
+obj-$(CONFIG_FB_MATROX)           += matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o $(my-obj-y)
 obj-$(CONFIG_FB_MATROX_I2C)       += i2c-matroxfb.o
 obj-$(CONFIG_FB_MATROX_MAVEN)     += matroxfb_maven.o matroxfb_crtc2.o
 obj-$(CONFIG_FB_MATROX_G450)	  += matroxfb_g450.o matroxfb_crtc2.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/g450_pll.c linux/drivers/video/matrox/g450_pll.c
--- linux.orig/drivers/video/matrox/g450_pll.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/video/matrox/g450_pll.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,472 @@
+/*
+ *
+ * Hardware accelerated Matrox PCI cards - G450/G550 PLL control.
+ *
+ * (c) 2001 Petr Vandrovec <vandrove@vc.cvut.cz>
+ *
+ * Portions Copyright (c) 2001 Matrox Graphics Inc.
+ *
+ * Version: 1.62 2001/11/29
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ */
+
+#include "g450_pll.h"
+#include "matroxfb_DAC1064.h"
+
+static inline unsigned int g450_vco2f(unsigned char p, unsigned int fvco) {
+	return (p & 0x40) ? fvco : fvco >> ((p & 3) + 1);
+}
+
+static inline unsigned int g450_f2vco(unsigned char p, unsigned int fin) {
+	return (p & 0x40) ? fin : fin << ((p & 3) + 1);
+}
+
+static unsigned int g450_mnp2vco(CPMINFO unsigned int mnp) {
+	unsigned int m, n;
+
+	m = ((mnp >> 16) & 0x0FF) + 1;
+	n = ((mnp >>  7) & 0x1FE) + 4;
+	return (ACCESS_FBINFO(features).pll.ref_freq * n + (m >> 1)) / m;
+}
+
+static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) {
+	if (f2 < f1) {
+    		f2 = f1 - f2;
+	} else {
+		f2 = f2 - f1;
+	}
+	return f2;
+}
+
+#define NO_MORE_MNP	0x01FFFFFF
+#define G450_MNP_FREQBITS	(0xFFFFFF43)	/* do not mask high byte so we'll catch NO_MORE_MNP */
+
+static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, unsigned int* fvco, unsigned int mnp) {
+	unsigned int m, n, p;
+	unsigned int tvco = *fvco;
+
+	m = (mnp >> 16) & 0xFF;
+	p = mnp & 0xFF;
+
+	if (m == 0 || m == 0xFF) {
+		if (m == 0) {
+			if (p & 0x40) {
+				return NO_MORE_MNP;
+			}
+		        if (p & 3) {
+				p--;
+			} else {
+				p = 0x40;
+			}
+			tvco >>= 1;
+			if (tvco < pi->vcomin) {
+				return NO_MORE_MNP;
+			}
+			*fvco = tvco;
+		}
+
+		p &= 0x43;
+		if (tvco < 550000) {
+/*			p |= 0x00; */
+		} else if (tvco < 700000) {
+			p |= 0x08;
+		} else if (tvco < 1000000) {
+			p |= 0x10;
+		} else if (tvco < 1150000) {
+			p |= 0x18;
+		} else {
+			p |= 0x20;
+		}
+		m = 9;
+	} else {
+		m--;
+	}
+        n = ((tvco * (m+1) + ACCESS_FBINFO(features).pll.ref_freq) / (ACCESS_FBINFO(features).pll.ref_freq * 2)) - 2;
+	return (m << 16) | (n << 8) | p;
+}
+
+static unsigned int g450_firstpll(CPMINFO const struct matrox_pll_limits* pi, unsigned int* vco, unsigned int fout) {
+	unsigned int p;
+	unsigned int vcomax;
+
+	vcomax = pi->vcomax;
+	if (fout > (vcomax / 2)) {
+		if (fout > vcomax) {
+			*vco = vcomax;
+		} else {
+			*vco = fout;
+		}
+		p = 0x40;
+	} else {
+		unsigned int tvco;
+
+		p = 3;
+		tvco = g450_f2vco(p, fout);
+		while (p && (tvco > vcomax)) {
+			p--;
+			tvco >>= 1;
+		}
+		if (tvco < pi->vcomin) {
+			tvco = pi->vcomin;
+		}
+		*vco = tvco;
+	}
+	return g450_nextpll(PMINFO pi, vco, 0xFF0000 | p);
+}
+
+static inline unsigned int g450_setpll(CPMINFO unsigned int mnp, unsigned int pll) {
+	switch (pll) {
+		case M_PIXEL_PLL_A:
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLAM, mnp >> 16);
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLAN, mnp >> 8);
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLAP, mnp);
+			return M1064_XPIXPLLSTAT;
+
+		case M_PIXEL_PLL_B:
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLBM, mnp >> 16);
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLBN, mnp >> 8);
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLBP, mnp);
+			return M1064_XPIXPLLSTAT;
+
+		case M_PIXEL_PLL_C:
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLCM, mnp >> 16);
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLCN, mnp >> 8);
+			matroxfb_DAC_out(PMINFO M1064_XPIXPLLCP, mnp);
+			return M1064_XPIXPLLSTAT;
+
+		case M_SYSTEM_PLL:
+			matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLM, mnp >> 16);
+			matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLN, mnp >> 8);
+			matroxfb_DAC_out(PMINFO DAC1064_XSYSPLLP, mnp);
+			return DAC1064_XSYSPLLSTAT;
+
+		case M_VIDEO_PLL:
+			matroxfb_DAC_out(PMINFO M1064_XVIDPLLM, mnp >> 16);
+			matroxfb_DAC_out(PMINFO M1064_XVIDPLLN, mnp >> 8);
+			matroxfb_DAC_out(PMINFO M1064_XVIDPLLP, mnp);
+			return M1064_XVIDPLLSTAT;
+	}
+	return 0;
+}
+
+static inline unsigned int g450_cmppll(CPMINFO unsigned int mnp, unsigned int pll) {
+	unsigned char m = mnp >> 16;
+	unsigned char n = mnp >> 8;
+	unsigned char p = mnp;
+
+	switch (pll) {
+		case M_PIXEL_PLL_A:
+			return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLAM) != m ||
+				matroxfb_DAC_in(PMINFO M1064_XPIXPLLAN) != n ||
+				matroxfb_DAC_in(PMINFO M1064_XPIXPLLAP) != p);
+
+		case M_PIXEL_PLL_B:
+			return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLBM) != m ||
+				matroxfb_DAC_in(PMINFO M1064_XPIXPLLBN) != n ||
+				matroxfb_DAC_in(PMINFO M1064_XPIXPLLBP) != p);
+
+		case M_PIXEL_PLL_C:
+			return (matroxfb_DAC_in(PMINFO M1064_XPIXPLLCM) != m ||
+				matroxfb_DAC_in(PMINFO M1064_XPIXPLLCN) != n ||
+				matroxfb_DAC_in(PMINFO M1064_XPIXPLLCP) != p);
+
+		case M_SYSTEM_PLL:
+			return (matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLM) != m ||
+				matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLN) != n ||
+				matroxfb_DAC_in(PMINFO DAC1064_XSYSPLLP) != p);
+
+		case M_VIDEO_PLL:
+			return (matroxfb_DAC_in(PMINFO M1064_XVIDPLLM) != m ||
+				matroxfb_DAC_in(PMINFO M1064_XVIDPLLN) != n ||
+				matroxfb_DAC_in(PMINFO M1064_XVIDPLLP) != p);
+	}
+	return 1;
+}
+
+static inline int g450_isplllocked(CPMINFO unsigned int regidx) {
+	unsigned int j;
+
+	for (j = 0; j < 1000; j++) {
+		if (matroxfb_DAC_in(PMINFO regidx) & 0x40) {
+			unsigned int r = 0;
+			int i;
+
+			for (i = 0; i < 100; i++) {
+				r += matroxfb_DAC_in(PMINFO regidx) & 0x40;
+			}
+			return r >= (90 * 0x40);
+		}
+		/* udelay(1)... but DAC_in is much slower... */
+	}
+	return 0;
+}
+
+static int g450_testpll(CPMINFO unsigned int mnp, unsigned int pll) {
+	return g450_isplllocked(PMINFO g450_setpll(PMINFO mnp, pll));
+}
+
+static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsigned int pll) {
+	switch (pll) {
+		case M_SYSTEM_PLL:
+			hw->DACclk[3] = mnp >> 16;
+			hw->DACclk[4] = mnp >> 8;
+			hw->DACclk[5] = mnp;
+			break;
+	}
+}
+
+static inline void g450_setpll_cond(WPMINFO unsigned int mnp, unsigned int pll) {
+	if (g450_cmppll(PMINFO mnp, pll)) {
+		g450_setpll(PMINFO mnp, pll);
+	}
+}
+
+static inline unsigned int g450_findworkingpll(WPMINFO unsigned int pll, unsigned int* mnparray, unsigned int mnpcount) {
+	unsigned int found = 0;
+	unsigned int idx;
+	unsigned int mnpfound = mnparray[0];
+		
+	for (idx = 0; idx < mnpcount; idx++) {
+		unsigned int sarray[3];
+		unsigned int *sptr;
+		{
+			unsigned int mnp;
+		
+			sptr = sarray;
+			mnp = mnparray[idx];
+			if (mnp & 0x38) {
+				*sptr++ = mnp - 8;
+			}
+			if ((mnp & 0x38) != 0x38) {
+				*sptr++ = mnp + 8;
+			}
+			*sptr = mnp;
+		}
+		while (sptr >= sarray) {
+			unsigned int mnp = *sptr--;
+		
+			if (g450_testpll(PMINFO mnp - 0x0300, pll) &&
+			    g450_testpll(PMINFO mnp + 0x0300, pll) &&
+			    g450_testpll(PMINFO mnp - 0x0200, pll) &&
+			    g450_testpll(PMINFO mnp + 0x0200, pll) &&
+			    g450_testpll(PMINFO mnp - 0x0100, pll) &&
+			    g450_testpll(PMINFO mnp + 0x0100, pll)) {
+				if (g450_testpll(PMINFO mnp, pll)) {
+					return mnp;
+				}
+			} else if (!found && g450_testpll(PMINFO mnp, pll)) {
+				mnpfound = mnp;
+				found = 1;
+			}
+		}
+	}
+	g450_setpll(PMINFO mnpfound, pll);
+	return mnpfound;
+}
+
+static void g450_addcache(struct matrox_pll_cache* ci, unsigned int mnp_key, unsigned int mnp_value) {
+	if (++ci->valid > ARRAY_SIZE(ci->data)) {
+		ci->valid = ARRAY_SIZE(ci->data);
+	}
+	memmove(ci->data + 1, ci->data, (ci->valid - 1) * sizeof(*ci->data));
+	ci->data[0].mnp_key = mnp_key & G450_MNP_FREQBITS;
+	ci->data[0].mnp_value = mnp_value;
+}
+
+static int g450_checkcache(WPMINFO struct matrox_pll_cache* ci, unsigned int mnp_key) {
+	unsigned int i;
+	
+	mnp_key &= G450_MNP_FREQBITS;
+	for (i = 0; i < ci->valid; i++) {
+		if (ci->data[i].mnp_key == mnp_key) {
+			unsigned int mnp;
+			
+			mnp = ci->data[i].mnp_value;
+			if (i) {
+				memmove(ci->data + 1, ci->data, i * sizeof(*ci->data));
+				ci->data[0].mnp_key = mnp_key;
+				ci->data[0].mnp_value = mnp;
+			}
+			return mnp;
+		}
+	}
+	return NO_MORE_MNP;
+}
+
+static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, 
+		unsigned int* mnparray, unsigned int* deltaarray) {
+	unsigned int mnpcount;
+	unsigned int pixel_vco;
+	const struct matrox_pll_limits* pi;
+	struct matrox_pll_cache* ci;
+
+	pixel_vco = 0;
+	switch (pll) {
+		case M_PIXEL_PLL_A:
+		case M_PIXEL_PLL_B:
+		case M_PIXEL_PLL_C:
+			{
+				u_int8_t tmp;
+				unsigned long flags;
+				
+				matroxfb_DAC_lock_irqsave(flags);
+				tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL);
+				if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) {
+					matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp | M1064_XPIXCLKCTRL_PLL_UP);
+				}
+				matroxfb_DAC_unlock_irqrestore(flags);
+			}
+			{
+				u_int8_t misc;
+		
+				misc = mga_inb(M_MISC_REG_READ) & ~0x0C;
+				switch (pll) {
+					case M_PIXEL_PLL_A:
+						break;
+					case M_PIXEL_PLL_B:
+						misc |=  0x04;
+						break;
+					default:
+						misc |=  0x0C;
+						break;
+				}
+				mga_outb(M_MISC_REG, misc);
+			}
+			pi = &ACCESS_FBINFO(limits.pixel);
+			ci = &ACCESS_FBINFO(cache.pixel);
+			break;
+		case M_SYSTEM_PLL:
+			{
+				u_int32_t opt;
+
+				pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &opt);
+				if (!(opt & 0x20)) {
+					pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, opt | 0x20);
+				}
+			}
+			pi = &ACCESS_FBINFO(limits.system);
+			ci = &ACCESS_FBINFO(cache.system);
+			break;
+		case M_VIDEO_PLL:
+			{
+				u_int8_t tmp;
+				unsigned int mnp;
+				unsigned long flags;
+				
+				matroxfb_DAC_lock_irqsave(flags);
+				tmp = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL);
+				if (!(tmp & 2)) {
+					matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, tmp | 2);
+				}
+				
+				mnp = matroxfb_DAC_in(PMINFO M1064_XPIXPLLCM) << 16;
+				mnp |= matroxfb_DAC_in(PMINFO M1064_XPIXPLLCN) << 8;
+				pixel_vco = g450_mnp2vco(PMINFO mnp);
+				matroxfb_DAC_unlock_irqrestore(flags);
+			}
+			pi = &ACCESS_FBINFO(limits.video);
+			ci = &ACCESS_FBINFO(cache.video);
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	mnpcount = 0;
+	{
+		unsigned int mnp;
+		unsigned int xvco;
+
+		for(mnp = g450_firstpll(PMINFO pi, &xvco, fout); mnp != NO_MORE_MNP; mnp = g450_nextpll(PMINFO pi, &xvco, mnp)) {
+			unsigned int idx;
+			unsigned int vco;
+			unsigned int delta;
+
+			if ((mnp & 0xFF00) < 0x0300 || (mnp & 0xFF00) > 0x7A00) {
+				continue;
+			}
+			vco = g450_mnp2vco(PMINFO mnp);
+			if (pll == M_VIDEO_PLL) {
+				unsigned int big, small;
+
+				if (vco < pixel_vco) {
+					small = vco;
+					big = pixel_vco;
+				} else {
+					small = pixel_vco;
+					big = vco;
+				}
+				while (big > small) {
+					big >>= 1;
+				}
+				if (big == small) {
+					continue;
+				}
+			}
+			delta = pll_freq_delta(fout, g450_vco2f(mnp, vco));
+			for (idx = mnpcount; idx > 0; idx--) {
+				/* == is important; due to nextpll algorithm we get
+				   sorted equally good frequencies from lower VCO 
+				   frequency to higher - with <= lowest wins, while
+				   with < highest one wins */
+				if (delta <= deltaarray[idx-1]) {
+					mnparray[idx] = mnparray[idx-1];
+					deltaarray[idx] = deltaarray[idx-1];
+				} else {
+					break;
+				}
+			}
+			mnparray[idx] = mnp;
+			deltaarray[idx] = delta;
+			mnpcount++;
+		}
+	}
+	/* VideoPLL and PixelPLL matched: do nothing... In all other cases we should get at least one frequency */
+	if (!mnpcount) {
+		return 1;
+	}
+	{
+		unsigned long flags;
+		unsigned int mnp;
+		
+		matroxfb_DAC_lock_irqsave(flags);
+		mnp = g450_checkcache(PMINFO ci, mnparray[0]);
+		if (mnp != NO_MORE_MNP) {
+			g450_setpll_cond(PMINFO mnp, pll);
+		} else {
+			mnp = g450_findworkingpll(PMINFO pll, mnparray, mnpcount);
+			g450_addcache(ci, mnparray[0], mnp);
+		}
+		updatehwstate_clk(&ACCESS_FBINFO(hw), mnp, pll);
+		matroxfb_DAC_unlock_irqrestore(flags);
+	}
+	return 0;
+}
+
+/* It must be greater than number of possible PLL values.
+ * Currently there is 5(p) * 10(m) = 50 possible values. */
+#define MNP_TABLE_SIZE  64
+
+int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll) {
+	unsigned int* arr;
+	
+	arr = kmalloc(sizeof(*arr) * MNP_TABLE_SIZE * 2, GFP_KERNEL);
+	if (arr) {
+		int r;
+
+		r = __g450_setclk(PMINFO fout, pll, arr, arr + MNP_TABLE_SIZE);
+		kfree(arr);
+		return r;
+	}
+	return -ENOMEM;
+}
+
+EXPORT_SYMBOL(matroxfb_g450_setclk);
+
+MODULE_AUTHOR("(c) 2001 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Matrox G450/G550 PLL driver");
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/g450_pll.h linux/drivers/video/matrox/g450_pll.h
--- linux.orig/drivers/video/matrox/g450_pll.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/video/matrox/g450_pll.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,8 @@
+#ifndef __G450_PLL_H__
+#define __G450_PLL_H__
+
+#include "matroxfb_base.h"
+
+int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll);
+
+#endif	/* __G450_PLL_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_DAC1064.c linux/drivers/video/matrox/matroxfb_DAC1064.c
--- linux.orig/drivers/video/matrox/matroxfb_DAC1064.c	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_DAC1064.c	2002-07-20 01:08:35.000000000 +0000
@@ -4,7 +4,9 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.54 2001/09/09
+ * Portions Copyright (c) 2001 Matrox Graphics Inc.
+ *
+ * Version: 1.62 2001/11/29
  *
  * See matroxfb_base.c for contributors.
  *
@@ -16,6 +18,7 @@
 #include "matroxfb_DAC1064.h"
 #include "matroxfb_misc.h"
 #include "matroxfb_accel.h"
+#include "g450_pll.h"
 #include <linux/matroxfb.h>
 
 #ifdef NEED_DAC1064
@@ -217,19 +220,20 @@
 		0x00,
 		0x00, 0x00, 0xFF, 0xFF};
 
-static void DAC1064_setpclk(CPMINFO struct matrox_hw_state* hw, unsigned long fout) {
+static void DAC1064_setpclk(WPMINFO unsigned long fout) {
 	unsigned int m, n, p;
 
 	DBG("DAC1064_setpclk")
 
 	DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
-	hw->DACclk[0] = m;
-	hw->DACclk[1] = n;
-	hw->DACclk[2] = p;
+	ACCESS_FBINFO(hw).DACclk[0] = m;
+	ACCESS_FBINFO(hw).DACclk[1] = n;
+	ACCESS_FBINFO(hw).DACclk[2] = p;
 }
 
-static void DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem){
+static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
 	u_int32_t mx;
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
 	DBG("DAC1064_setmclk")
 
@@ -289,7 +293,9 @@
 	hw->MXoptionReg = mx;
 }
 
-void DAC1064_global_init(CPMINFO struct matrox_hw_state* hw) {
+void DAC1064_global_init(WPMINFO2) {
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
+
 	hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
 	hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
 	hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
@@ -314,7 +320,9 @@
 		hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
 }
 
-void DAC1064_global_restore(CPMINFO const struct matrox_hw_state* hw) {
+void DAC1064_global_restore(WPMINFO2) {
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
+
 	outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
 	outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
 	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
@@ -328,7 +336,9 @@
 	}
 }
 
-static int DAC1064_init_1(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display *p) {
+static int DAC1064_init_1(WPMINFO struct my_timming* m, struct display *p) {
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
+
 	DBG("DAC1064_init_1")
 
 	memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
@@ -359,7 +369,7 @@
 		}
 	}
 
-	DAC1064_global_init(PMINFO hw);
+	DAC1064_global_init(PMINFO2);
 	hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl);
 	hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
 	hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
@@ -368,7 +378,8 @@
 	return 0;
 }
 
-static int DAC1064_init_2(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+static int DAC1064_init_2(WPMINFO struct my_timming* m, struct display* p) {
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
 	DBG("DAC1064_init_2")
 
@@ -409,21 +420,22 @@
 	return 0;
 }
 
-static void DAC1064_restore_1(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw) {
+static void DAC1064_restore_1(WPMINFO2) {
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
+
 	CRITFLAGS
 
 	DBG("DAC1064_restore_1")
 
 	CRITBEGIN
 
-	outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
-	outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
-	outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
-	/*
-	 * We must ALWAYS reprogram hardware due to broken XF4 matrox drivers...
-	 *
-	 * if (!oldhw || memcmp(hw->DACreg, oldhw->DACreg, sizeof(MGA1064_DAC_regs))) 
-	 */
+	if ((inDAC1064(PMINFO DAC1064_XSYSPLLM) != hw->DACclk[3]) ||
+	    (inDAC1064(PMINFO DAC1064_XSYSPLLN) != hw->DACclk[4]) ||
+	    (inDAC1064(PMINFO DAC1064_XSYSPLLP) != hw->DACclk[5])) {
+		outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
+		outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
+		outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
+	}
 	{
 		unsigned int i;
 
@@ -433,12 +445,12 @@
 		}
 	}
 
-	DAC1064_global_restore(PMINFO hw);
+	DAC1064_global_restore(PMINFO2);
 
 	CRITEND
 };
 
-static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw, struct display* p) {
+static void DAC1064_restore_2(WPMINFO struct display* p) {
 #ifdef DEBUG
 	unsigned int i;
 #endif
@@ -449,48 +461,54 @@
 #ifdef DEBUG
 	dprintk(KERN_DEBUG "DAC1064regs ");
 	for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
-		dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], hw->DACreg[i]);
+		dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]);
 		if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
 	}
 	dprintk("\n" KERN_DEBUG "DAC1064clk ");
 	for (i = 0; i < 6; i++)
-		dprintk("C%02X=%02X ", i, hw->DACclk[i]);
+		dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]);
 	dprintk("\n");
 #endif
 }
 
-static int m1064_compute(void* outdev, struct my_timming* m, struct matrox_hw_state* hw) {
-#define minfo ((struct matrox_fb_info*)outdev)
-	DAC1064_setpclk(PMINFO hw, m->pixclock);
-#undef minfo
-	return 0;
-}
-
-static int m1064_program(void* outdev, const struct matrox_hw_state* hw) {
+static int m1064_compute(void* outdev, struct my_timming* m) {
 #define minfo ((struct matrox_fb_info*)outdev)
-	int i;
-	int tmout;
-	CRITFLAGS
+#ifdef CONFIG_FB_MATROX_G450
+	if (ACCESS_FBINFO(devflags.g450dac)) {
+		matroxfb_g450_setclk(PMINFO m->pixclock, M_PIXEL_PLL_C);
+	} else 
+#endif
+	{
+		int i;
+		int tmout;
+		CRITFLAGS
 
-	CRITBEGIN
+		DAC1064_setpclk(PMINFO m->pixclock);
 
-	for (i = 0; i < 3; i++)
-		outDAC1064(PMINFO M1064_XPIXPLLCM + i, hw->DACclk[i]);
-	for (tmout = 500000; tmout; tmout--) {
-		if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
-			break;
-		udelay(10);
-	};
+		CRITBEGIN
 
-	CRITEND
+		for (i = 0; i < 3; i++)
+			outDAC1064(PMINFO M1064_XPIXPLLCM + i, ACCESS_FBINFO(hw).DACclk[i]);
+		for (tmout = 500000; tmout; tmout--) {
+			if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
+				break;
+			udelay(10);
+		};
 
-	if (!tmout)
-		printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
+		CRITEND
 
+		if (!tmout)
+			printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
+	}
 #undef minfo
 	return 0;
 }
 
+static int m1064_program(void* outdev) {
+	/* nothing, hardware is set in m1064_compute */
+	return 0;
+}
+
 static int m1064_start(void* outdev) {
 	/* nothing */
 	return 0;
@@ -522,12 +540,13 @@
 #endif /* NEED_DAC1064 */
 
 #ifdef CONFIG_FB_MATROX_MYSTIQUE
-static int MGA1064_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+static int MGA1064_init(WPMINFO struct my_timming* m, struct display* p) {
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
 	DBG("MGA1064_init")
 
-	if (DAC1064_init_1(PMINFO hw, m, p)) return 1;
-	if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1;
+	if (DAC1064_init_1(PMINFO m, p)) return 1;
+	if (matroxfb_vgaHWinit(PMINFO m, p)) return 1;
 
 	hw->MiscOutReg = 0xCB;
 	if (m->sync & FB_SYNC_HOR_HIGH_ACT)
@@ -537,19 +556,20 @@
 	if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
 		hw->CRTCEXT[3] |= 0x40;
 
-	if (DAC1064_init_2(PMINFO hw, m, p)) return 1;
+	if (DAC1064_init_2(PMINFO m, p)) return 1;
 	return 0;
 }
 #endif
 
 #ifdef CONFIG_FB_MATROX_G100
-static int MGAG100_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+static int MGAG100_init(WPMINFO struct my_timming* m, struct display* p) {
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
 	DBG("MGAG100_init")
 
-	if (DAC1064_init_1(PMINFO hw, m, p)) return 1;
+	if (DAC1064_init_1(PMINFO m, p)) return 1;
 	hw->MXoptionReg &= ~0x2000;
-	if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1;
+	if (matroxfb_vgaHWinit(PMINFO m, p)) return 1;
 
 	hw->MiscOutReg = 0xEF;
 	if (m->sync & FB_SYNC_HOR_HIGH_ACT)
@@ -559,13 +579,13 @@
 	if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
 		hw->CRTCEXT[3] |= 0x40;
 
-	if (DAC1064_init_2(PMINFO hw, m, p)) return 1;
+	if (DAC1064_init_2(PMINFO m, p)) return 1;
 	return 0;
 }
 #endif	/* G100 */
 
 #ifdef CONFIG_FB_MATROX_MYSTIQUE
-static void MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw){
+static void MGA1064_ramdac_init(WPMINFO2) {
 
 	DBG("MGA1064_ramdac_init");
 
@@ -579,7 +599,7 @@
 	ACCESS_FBINFO(features.pll.post_shift_max) = 3;
 	ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL;
 	/* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
-	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
+	DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
 }
 #endif
 
@@ -591,7 +611,7 @@
 static int def50 = 0;	/* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
 #endif
 
-static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p){
+static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p) {
 	int reg;
 	int selClk;
 	int clk;
@@ -635,7 +655,7 @@
 	outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
 }
 
-static void MGAG100_setPixClock(CPMINFO int flags, int freq){
+static void MGAG100_setPixClock(CPMINFO int flags, int freq) {
 	unsigned int m, n, p;
 
 	DBG("MGAG100_setPixClock")
@@ -646,10 +666,12 @@
 #endif
 
 #ifdef CONFIG_FB_MATROX_MYSTIQUE
-static int MGA1064_preinit(WPMINFO struct matrox_hw_state* hw){
+static int MGA1064_preinit(WPMINFO2) {
 	static const int vxres_mystique[] = { 512,        640, 768,  800,  832,  960,
 					     1024, 1152, 1280,      1600, 1664, 1920,
 					     2048,    0};
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
+
 	DBG("MGA1064_preinit")
 
 	/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
@@ -680,7 +702,7 @@
 	return 0;
 }
 
-static void MGA1064_reset(WPMINFO struct matrox_hw_state* hw){
+static void MGA1064_reset(WPMINFO2) {
 
 	DBG("MGA1064_reset");
 
@@ -688,15 +710,130 @@
 	if (ACCESS_FBINFO(devflags.hwcursor))
 		ACCESS_FBINFO(video.len_usable) -= 1024;
 	matroxfb_fastfont_init(MINFO);
-	MGA1064_ramdac_init(PMINFO hw);
+	MGA1064_ramdac_init(PMINFO2);
 }
 #endif
 
 #ifdef CONFIG_FB_MATROX_G100
-static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw){
+static void g450_mclk_init(WPMINFO2) {
+	/* switch all clocks to PCI source */
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3 & ~0x00300C03);
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
+	
+	if (((ACCESS_FBINFO(values).reg.opt3 & 0x000003) == 0x000003) ||
+	    ((ACCESS_FBINFO(values).reg.opt3 & 0x000C00) == 0x000C00) ||
+	    ((ACCESS_FBINFO(values).reg.opt3 & 0x300000) == 0x300000)) {
+		matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.video), M_VIDEO_PLL);
+	} else {
+		/* slow down video clocks... */
+		matroxfb_g450_setclk(PMINFO 0, M_VIDEO_PLL);
+	}
+	matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.system), M_SYSTEM_PLL);
+	
+	/* switch clocks to their real PLL source(s) */
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3);
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
+
+}
+
+static void g450_memory_init(WPMINFO2) {
+	/* disable memory refresh */
+	ACCESS_FBINFO(hw).MXoptionReg &= ~0x001F8000;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
+	
+	/* set memory interface parameters */
+	ACCESS_FBINFO(hw).MXoptionReg &= ~0x00207E00;
+	ACCESS_FBINFO(hw).MXoptionReg |= 0x00207E00 & ACCESS_FBINFO(values).reg.opt;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ACCESS_FBINFO(values).reg.opt2);
+	
+	mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
+	
+	/* first set up memory interface with disabled memory interface clocks */
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc & ~0x80000000U);
+	mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
+	mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess);
+	/* start memory clocks */
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc | 0x80000000U);
+
+	udelay(200);
+	
+	if (ACCESS_FBINFO(values).memory.ddr && (!ACCESS_FBINFO(values).memory.emrswen || !ACCESS_FBINFO(values).memory.dll)) {
+		mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk & ~0x1000);
+	}
+	mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess | 0x8000);
+	
+	udelay(200);
+	
+	ACCESS_FBINFO(hw).MXoptionReg |= 0x001F8000 & ACCESS_FBINFO(values).reg.opt;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
+	
+	/* value is written to memory chips only if old != new */
+	mga_outl(M_PLNWT, 0);
+	mga_outl(M_PLNWT, ~0);
+	
+	if (ACCESS_FBINFO(values).reg.mctlwtst != ACCESS_FBINFO(values).reg.mctlwtst_core) {
+		mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst_core);
+	}
+	
+}
+
+static void g450_preinit(WPMINFO2) {
+	u_int32_t c2ctl;
+	u_int8_t curctl;
+	u_int8_t c1ctl;
+	
+	/* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */
+	ACCESS_FBINFO(hw).MXoptionReg &= 0xC0000100;
+	ACCESS_FBINFO(hw).MXoptionReg |= 0x00000020;
+	if (ACCESS_FBINFO(devflags.novga))
+		ACCESS_FBINFO(hw).MXoptionReg &= ~0x00000100;
+	if (ACCESS_FBINFO(devflags.nobios))
+		ACCESS_FBINFO(hw).MXoptionReg &= ~0x40000000;
+	if (ACCESS_FBINFO(devflags.nopciretry))
+		ACCESS_FBINFO(hw).MXoptionReg |=  0x20000000;
+	ACCESS_FBINFO(hw).MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x03400040;
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
+
+	/* Init system clocks */
+		
+	/* stop crtc2 */
+	c2ctl = mga_inl(M_C2CTL);
+	mga_outl(M_C2CTL, c2ctl & ~1);
+	/* stop cursor */
+	curctl = inDAC1064(PMINFO M1064_XCURCTRL);
+	outDAC1064(PMINFO M1064_XCURCTRL, 0);
+	/* stop crtc1 */
+	c1ctl = mga_readr(M_SEQ_INDEX, 1);
+	mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20);
+
+	g450_mclk_init(PMINFO2);
+	g450_memory_init(PMINFO2);
+	
+	/* set legacy VGA clock sources for DOSEmu or VMware... */
+	matroxfb_g450_setclk(PMINFO 25175, M_PIXEL_PLL_A);
+	matroxfb_g450_setclk(PMINFO 28322, M_PIXEL_PLL_B);
+
+	/* restore crtc1 */
+	mga_setr(M_SEQ_INDEX, 1, c1ctl);
+	
+	/* restore cursor */
+	outDAC1064(PMINFO M1064_XCURCTRL, curctl);
+
+	/* restore crtc2 */
+	mga_outl(M_C2CTL, c2ctl);
+	
+	return;
+}
+
+static int MGAG100_preinit(WPMINFO2) {
 	static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
                                           1024, 1152, 1280,      1600, 1664, 1920,
                                           2048, 0};
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
+
         u_int32_t reg50;
 #if 0
 	u_int32_t q;
@@ -710,7 +847,9 @@
 	} else {
 		ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
 	}
-	ACCESS_FBINFO(features.pll.ref_freq)	 = 27000;
+	if (!ACCESS_FBINFO(features.pll.ref_freq)) {
+		ACCESS_FBINFO(features.pll.ref_freq)	 = 27000;
+	}
 	ACCESS_FBINFO(features.pll.feed_div_min) = 7;
 	ACCESS_FBINFO(features.pll.feed_div_max) = 127;
 	ACCESS_FBINFO(features.pll.in_div_min)	 = 1;
@@ -734,6 +873,10 @@
 	}
 	if (ACCESS_FBINFO(devflags.noinit))
 		return 0;
+	if (ACCESS_FBINFO(devflags.g450dac)) {
+		g450_preinit(PMINFO2);
+		return 0;
+	}
 	hw->MXoptionReg &= 0xC0000100;
 	hw->MXoptionReg |= 0x00000020;
 	if (ACCESS_FBINFO(devflags.novga))
@@ -743,12 +886,12 @@
 	if (ACCESS_FBINFO(devflags.nopciretry))
 		hw->MXoptionReg |=  0x20000000;
 	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
-	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
+	DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
 
 	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
-		pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
+		pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
 		reg50 &= ~0x3000;
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
 
 		hw->MXoptionReg |= 0x1080;
 		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
@@ -763,7 +906,7 @@
 		udelay(100);
 		reg50 &= ~0xFF;
 		reg50 |=  0x07;
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
 		/* it should help with G100 */
 		mga_outb(M_GRAPHICS_INDEX, 6);
 		mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
@@ -778,29 +921,30 @@
 		}
 #endif
 		hw->MXoptionReg |= 0x00078020;
-	} else 	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) {
-		pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
+	} else if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) {
+		pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
 		reg50 &= ~0x3000;
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
 
 		if (ACCESS_FBINFO(devflags.memtype) == -1)
-			ACCESS_FBINFO(devflags.memtype) = 3;
-		hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
+			hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
+		else
+			hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
 		if (ACCESS_FBINFO(devflags.sgram))
 			hw->MXoptionReg |= 0x4000;
-		mga_outl(M_CTLWTST, 0x042450A1);
-		mga_outl(M_MEMRDBK, 0x00000108);
+		mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
+		mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
 		udelay(200);
 		mga_outl(M_MACCESS, 0x00000000);
 		mga_outl(M_MACCESS, 0x00008000);
 		udelay(100);
-		mga_outw(M_MEMRDBK, 0x00000108);
+		mga_outw(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
 		hw->MXoptionReg |= 0x00078020;
 	} else {
-		pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
+		pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
 		reg50 &= ~0x00000100;
 		reg50 |=  0x00000000;
-		pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
+		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
 
 		if (ACCESS_FBINFO(devflags.memtype) == -1)
 			ACCESS_FBINFO(devflags.memtype) = 0;
@@ -820,8 +964,9 @@
 	return 0;
 }
 
-static void MGAG100_reset(WPMINFO struct matrox_hw_state* hw){
+static void MGAG100_reset(WPMINFO2) {
 	u_int8_t b;
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
 	DBG("MGAG100_reset")
 
@@ -845,13 +990,20 @@
 #endif
 		if (!ACCESS_FBINFO(devflags.noinit)) {
 			if (x7AF4 & 8) {
-				hw->MXoptionReg |= 0x40;
+				hw->MXoptionReg |= 0x40;	/* FIXME... */
 				pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
 			}
 			mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
 		}
 	}
-	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
+	if (ACCESS_FBINFO(devflags.g450dac)) {
+		/* either leave MCLK as is... or they were set in preinit */
+		hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
+		hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
+		hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
+	} else {
+		DAC1064_setmclk(PMINFO DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
+	}
 	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
 		if (ACCESS_FBINFO(devflags.dfp_type) == -1) {
 			ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F);
@@ -859,20 +1011,25 @@
 	}
 	if (ACCESS_FBINFO(devflags.noinit))
 		return;
-	MGAG100_setPixClock(PMINFO 4, 25175);
-	MGAG100_setPixClock(PMINFO 5, 28322);
-	if (x7AF4 & 0x10) {
-		b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
-		outDAC1064(PMINFO M1064_XGENIODATA, b);
-		b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
-		outDAC1064(PMINFO M1064_XGENIOCTRL, b);
+	if (ACCESS_FBINFO(devflags.g450dac)) {
+	} else {
+		MGAG100_setPixClock(PMINFO 4, 25175);
+		MGAG100_setPixClock(PMINFO 5, 28322);
+		if (x7AF4 & 0x10) {
+			b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
+			outDAC1064(PMINFO M1064_XGENIODATA, b);
+			b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
+			outDAC1064(PMINFO M1064_XGENIOCTRL, b);
+		}
 	}
 }
 #endif
 
 #ifdef CONFIG_FB_MATROX_MYSTIQUE
-static void MGA1064_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
+static void MGA1064_restore(WPMINFO struct display* p) {
 	int i;
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
+
 	CRITFLAGS
 
 	DBG("MGA1064_restore")
@@ -885,17 +1042,19 @@
 
 	CRITEND
 
-	DAC1064_restore_1(PMINFO hw, oldhw);
-	matroxfb_vgaHWrestore(PMINFO hw, oldhw);
+	DAC1064_restore_1(PMINFO2);
+	matroxfb_vgaHWrestore(PMINFO2);
 	for (i = 0; i < 6; i++)
 		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
-	DAC1064_restore_2(PMINFO hw, oldhw, p);
+	DAC1064_restore_2(PMINFO p);
 }
 #endif
 
 #ifdef CONFIG_FB_MATROX_G100
-static void MGAG100_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
+static void MGAG100_restore(WPMINFO struct display* p) {
 	int i;
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
+
 	CRITFLAGS
 
 	DBG("MGAG100_restore")
@@ -905,15 +1064,15 @@
 	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
 	CRITEND
 
-	DAC1064_restore_1(PMINFO hw, oldhw);
-	matroxfb_vgaHWrestore(PMINFO hw, oldhw);
+	DAC1064_restore_1(PMINFO2);
+	matroxfb_vgaHWrestore(PMINFO2);
 #ifdef CONFIG_FB_MATROX_32MB
 	if (ACCESS_FBINFO(devflags.support32MB))
 		mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
 #endif
 	for (i = 0; i < 6; i++)
 		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
-	DAC1064_restore_2(PMINFO hw, oldhw, p);
+	DAC1064_restore_2(PMINFO p);
 }
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_DAC1064.h linux/drivers/video/matrox/matroxfb_DAC1064.h
--- linux.orig/drivers/video/matrox/matroxfb_DAC1064.h	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_DAC1064.h	2002-07-20 01:08:35.000000000 +0000
@@ -13,8 +13,8 @@
 extern struct matrox_switch matrox_G100;
 #endif
 #ifdef NEED_DAC1064
-void DAC1064_global_init(CPMINFO struct matrox_hw_state*);
-void DAC1064_global_restore(CPMINFO const struct matrox_hw_state*);
+void DAC1064_global_init(WPMINFO2);
+void DAC1064_global_restore(WPMINFO2);
 #endif
 
 #define M1064_INDEX	0x00
@@ -139,10 +139,10 @@
 
 #define M1064_XOUTPUTCONN	0x8A
 #define M1064_XSYNCCTRL		0x8B
-#define M1064_XPIXPLL2STAT	0x8C
-#define M1064_XPIXPLL2P		0x8D
-#define M1064_XPIXPLL2N		0x8E
-#define M1064_XPIXPLL2M		0x8F
+#define M1064_XVIDPLLSTAT	0x8C
+#define M1064_XVIDPLLP		0x8D
+#define M1064_XVIDPLLM		0x8E
+#define M1064_XVIDPLLN		0x8F
 
 #define M1064_XPWRCTRL		0xA0
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_Ti3026.c linux/drivers/video/matrox/matroxfb_Ti3026.c
--- linux.orig/drivers/video/matrox/matroxfb_Ti3026.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_Ti3026.c	2002-07-20 01:08:22.000000000 +0000
@@ -4,7 +4,9 @@
  *
  * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.50 2000/08/10
+ * Portions Copyright (c) 2001 Matrox Graphics Inc.
+ *
+ * Version: 1.62 2000/11/29
  *
  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  *
@@ -357,7 +359,7 @@
 			del_timer_sync(&ACCESS_FBINFO(cursor.timer));
 			matroxfb_DAC_lock_irqsave(flags);
 			ACCESS_FBINFO(cursor.state) = CM_ERASE;
-			outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]));
+			outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(hw.DACreg[POS3026_XCURCTRL]));
 			matroxfb_DAC_unlock_irqrestore(flags);
 		}
 		return;
@@ -377,7 +379,7 @@
 		ACCESS_FBINFO(cursor.y) = y;
 		x += 64;
 		y += 64;
-		outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]));
+		outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(hw.DACreg[POS3026_XCURCTRL]));
 		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSXL, x);
 		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSXH, x >> 8);
 		mga_outb(M_RAMDAC_BASE+TVP3026_CURPOSYL, y);
@@ -386,7 +388,7 @@
 	ACCESS_FBINFO(cursor.state) = CM_DRAW;
 	if (ACCESS_FBINFO(devflags.blink))
 		mod_timer(&ACCESS_FBINFO(cursor.timer), jiffies + HZ/2);
-	outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(currenthw->DACreg[POS3026_XCURCTRL]) | TVP3026_XCURCTRL_XGA);
+	outTi3026(PMINFO TVP3026_XCURCTRL, ACCESS_FBINFO(hw.DACreg[POS3026_XCURCTRL]) | TVP3026_XCURCTRL_XGA);
 	matroxfb_DAC_unlock_irqrestore(flags);
 }
 
@@ -418,9 +420,10 @@
 	return fvco;
 }
 
-static int Ti3026_setpclk(CPMINFO struct matrox_hw_state* hw, int clk, struct display* p) {
+static int Ti3026_setpclk(WPMINFO int clk, struct display* p) {
 	unsigned int f_pll;
 	unsigned int pixfeed, pixin, pixpost;
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
 	DBG("Ti3026_setpclk")
 
@@ -491,8 +494,9 @@
 	return 0;
 }
 
-static int Ti3026_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+static int Ti3026_init(WPMINFO struct my_timming* m, struct display* p) {
 	u_int8_t muxctrl = isInterleave(MINFO) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT;
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
 	DBG("Ti3026_init")
 
@@ -538,7 +542,7 @@
 			return 1;	/* TODO: failed */
 		}
 	}
-	if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1;
+	if (matroxfb_vgaHWinit(PMINFO m, p)) return 1;
 
 	/* set SYNC */
 	hw->MiscOutReg = 0xCB;
@@ -567,11 +571,11 @@
 	if ((p->type != FB_TYPE_TEXT) && isInterleave(MINFO)) hw->MXoptionReg |= 0x00001000;
 
 	/* set DAC */
-	Ti3026_setpclk(PMINFO hw, m->pixclock, p);
+	Ti3026_setpclk(PMINFO m->pixclock, p);
 	return 0;
 }
 
-static void ti3026_setMCLK(CPMINFO struct matrox_hw_state* hw, int fout){
+static void ti3026_setMCLK(WPMINFO int fout){
 	unsigned int f_pll;
 	unsigned int pclk_m, pclk_n, pclk_p;
 	unsigned int mclk_m, mclk_n, mclk_p;
@@ -643,8 +647,8 @@
 		if (rfhcnt > 15)
 			rfhcnt = 0;
 	}
-	hw->MXoptionReg = (hw->MXoptionReg & ~0x000F0000) | (rfhcnt << 16);
-	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+	ACCESS_FBINFO(hw).MXoptionReg = (ACCESS_FBINFO(hw).MXoptionReg & ~0x000F0000) | (rfhcnt << 16);
+	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
 
 	/* output MCLK to MCLK pin */
 	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
@@ -670,7 +674,7 @@
 		printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
 }
 
-static void ti3026_ramdac_init(WPMINFO struct matrox_hw_state* hw){
+static void ti3026_ramdac_init(WPMINFO2) {
 
 	DBG("ti3026_ramdac_init")
 
@@ -683,11 +687,13 @@
 	ACCESS_FBINFO(features.pll.post_shift_max) = 3;
 	if (ACCESS_FBINFO(devflags.noinit))
 		return;
-	ti3026_setMCLK(PMINFO hw, 60000);
+	ti3026_setMCLK(PMINFO 60000);
 }
 
-static void Ti3026_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
+static void Ti3026_restore(WPMINFO struct display* p) {
 	int i;
+	unsigned char progdac[6];
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 	CRITFLAGS
 
 	DBG("Ti3026_restore")
@@ -705,7 +711,7 @@
 
 	CRITEND
 
-	matroxfb_vgaHWrestore(PMINFO hw, oldhw);
+	matroxfb_vgaHWrestore(PMINFO2);
 
 	CRITBEGIN
 
@@ -715,19 +721,19 @@
 	for (i = 0; i < 21; i++) {
 		outTi3026(PMINFO DACseq[i], hw->DACreg[i]);
 	}
-	if (oldhw) {
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
-		oldhw->DACclk[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-		oldhw->DACclk[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x15);
-		oldhw->DACclk[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-		oldhw->DACclk[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
-		outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
-		oldhw->DACclk[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
-		oldhw->DACclk[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
-	}
+
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
+	progdac[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+	progdac[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0x15);
+	progdac[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+	progdac[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+	outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
+	progdac[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+	progdac[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+
 	CRITEND
-	if (!oldhw || memcmp(hw->DACclk, oldhw->DACclk, 6)) {
+	if (memcmp(hw->DACclk, progdac, 6)) {
 		/* agrhh... setting up PLL is very slow on Millennium... */
 		/* Mystique PLL is locked in few ms, but Millennium PLL lock takes about 0.15 s... */
 		/* Maybe even we should call schedule() ? */
@@ -796,22 +802,23 @@
 #endif
 }
 
-static void Ti3026_reset(WPMINFO struct matrox_hw_state* hw){
+static void Ti3026_reset(WPMINFO2) {
 
 	DBG("Ti3026_reset")
 
 	matroxfb_fastfont_init(MINFO);
 
-	ti3026_ramdac_init(PMINFO hw);
+	ti3026_ramdac_init(PMINFO2);
 }
 
-static int Ti3026_preinit(WPMINFO struct matrox_hw_state* hw){
+static int Ti3026_preinit(WPMINFO2) {
 	static const int vxres_mill2[] = { 512,        640, 768,  800,  832,  960,
 					  1024, 1152, 1280,      1600, 1664, 1920,
 					  2048, 0};
 	static const int vxres_mill1[] = {             640, 768,  800,        960,
 					  1024, 1152, 1280,      1600,       1920,
 					  2048, 0};
+	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
 	DBG("Ti3026_preinit")
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c
--- linux.orig/drivers/video/matrox/matroxfb_base.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_base.c	2002-07-20 01:08:26.000000000 +0000
@@ -4,7 +4,9 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.54 2001/09/09
+ * Portions Copyright (c) 2001 Matrox Graphics Inc.
+ *
+ * Version: 1.62 2001/11/29
  *
  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  *
@@ -108,7 +110,6 @@
 #endif
 
 static void matroxfb_unregister_device(struct matrox_fb_info* minfo);
-int matroxfb_switch(int con, struct fb_info *info);
 
 /* --------------------------------------------------------------------- */
 
@@ -162,11 +163,11 @@
 		pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32;
 		pos += ACCESS_FBINFO(curr.ydstorg.chunks);
 	}
-	p0 = ACCESS_FBINFO(currenthw)->CRTC[0x0D] = pos & 0xFF;
-	p1 = ACCESS_FBINFO(currenthw)->CRTC[0x0C] = (pos & 0xFF00) >> 8;
-	p2 = ACCESS_FBINFO(currenthw)->CRTCEXT[0] = (ACCESS_FBINFO(currenthw)->CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
+	p0 = ACCESS_FBINFO(hw).CRTC[0x0D] = pos & 0xFF;
+	p1 = ACCESS_FBINFO(hw).CRTC[0x0C] = (pos & 0xFF00) >> 8;
+	p2 = ACCESS_FBINFO(hw).CRTCEXT[0] = (ACCESS_FBINFO(hw).CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
 #ifdef CONFIG_FB_MATROX_32MB
-	p3 = ACCESS_FBINFO(currenthw)->CRTCEXT[8] = pos >> 21;
+	p3 = ACCESS_FBINFO(hw).CRTCEXT[8] = pos >> 21;
 #endif
 
 	CRITBEGIN
@@ -815,7 +816,6 @@
 
 		{	struct my_timming mt;
 			struct matrox_hw_state* hw;
-			struct matrox_hw_state* ohw;
 
 			matroxfb_var2my(var, &mt);
 			/* CRTC1 delays */
@@ -827,16 +827,12 @@
 				default:	mt.delay = 31 + 8; break;
 			}
 
-			hw = ACCESS_FBINFO(newhw);
-			ohw = ACCESS_FBINFO(currenthw);
-
-			/* copy last setting... */
-			memcpy(hw, ohw, sizeof(*hw));
+			hw = &ACCESS_FBINFO(hw);
 
 			del_timer_sync(&ACCESS_FBINFO(cursor.timer));
 			ACCESS_FBINFO(cursor.state) = CM_ERASE;
 
-			ACCESS_FBINFO(hw_switch->init(PMINFO hw, &mt, display));
+			ACCESS_FBINFO(hw_switch->init(PMINFO &mt, display));
 			if (display->type == FB_TYPE_TEXT) {
 				if (fontheight(display))
 					pos = var->yoffset / fontheight(display) * display->next_line / ACCESS_FBINFO(devflags.textstep) + var->xoffset / (fontwidth(display)?fontwidth(display):8);
@@ -853,28 +849,26 @@
 			hw->CRTCEXT[8] = pos >> 21;
 			if (ACCESS_FBINFO(output.ph) & (MATROXFB_OUTPUT_CONN_PRIMARY | MATROXFB_OUTPUT_CONN_DFP)) {
 				if (ACCESS_FBINFO(primout))
-					ACCESS_FBINFO(primout)->compute(MINFO, &mt, hw);
+					ACCESS_FBINFO(primout)->compute(MINFO, &mt);
 			}
 			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {
 				down_read(&ACCESS_FBINFO(altout.lock));
 				if (ACCESS_FBINFO(altout.output))
-					ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt, hw);
+					ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt);
 				up_read(&ACCESS_FBINFO(altout.lock));
 			}
-			ACCESS_FBINFO(hw_switch->restore(PMINFO hw, ohw, display));
+			ACCESS_FBINFO(hw_switch->restore(PMINFO display));
 			if (ACCESS_FBINFO(output.ph) & (MATROXFB_OUTPUT_CONN_PRIMARY | MATROXFB_OUTPUT_CONN_DFP)) {
 				if (ACCESS_FBINFO(primout))
-					ACCESS_FBINFO(primout)->program(MINFO, hw);
+					ACCESS_FBINFO(primout)->program(MINFO);
 			}
 			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {
 				down_read(&ACCESS_FBINFO(altout.lock));
 				if (ACCESS_FBINFO(altout.output))
-					ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device), hw);
+					ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device));
 				up_read(&ACCESS_FBINFO(altout.lock));
 			}
 			ACCESS_FBINFO(cursor.redraw) = 1;
-			ACCESS_FBINFO(currenthw) = hw;
-			ACCESS_FBINFO(newhw) = ohw;
 			if (ACCESS_FBINFO(output.ph) & (MATROXFB_OUTPUT_CONN_PRIMARY | MATROXFB_OUTPUT_CONN_DFP)) {
 				if (ACCESS_FBINFO(primout))
 					ACCESS_FBINFO(primout)->start(MINFO);
@@ -1005,7 +999,7 @@
 		vblank->flags |= FB_VBLANK_HBLANKING;
 	if (sts1 & 8)
 		vblank->flags |= FB_VBLANK_VSYNCING;
-	if (vblank->count >= ACCESS_FBINFO(currcon_display)->var.yres)
+	if (vblank->vcount >= ACCESS_FBINFO(currcon_display)->var.yres)
 		vblank->flags |= FB_VBLANK_VBLANKING;
 	vblank->hcount = 0;
 	vblank->count = 0;
@@ -1417,7 +1411,7 @@
 #define DEVF_CROSS4MB		0x0010
 #define DEVF_TEXT4B		0x0020
 #define DEVF_DDC_8_2		0x0040
-#define DEVF_G550DAC		0x0080
+/* #define DEVF_recycled	0x0080	*/
 #define DEVF_SUPPORT32MB	0x0100
 #define DEVF_ANY_VXRES		0x0200
 #define DEVF_TEXT16B		0x0400
@@ -1433,12 +1427,13 @@
 #define DEVF_G400	(DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2)
 /* if you'll find how to drive DFP... */
 #define DEVF_G450	(DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG)
-#define DEVF_G550	(DEVF_G450 | DEVF_G550DAC | DEVF_BOTHDACS)
+#define DEVF_G550	(DEVF_G450 | DEVF_BOTHDACS)
 
 static struct board {
 	unsigned short vendor, device, rev, svid, sid;
 	unsigned int flags;
 	unsigned int maxclk;
+	enum mga_chip chip;
 	struct video_board* base;
 	const char* name;
 		} dev_list[] = {
@@ -1447,18 +1442,21 @@
 		0,			0,
 		DEVF_TEXT4B,
 		230000,
+		MGA_2064,
 		&vbMillennium,
 		"Millennium (PCI)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2,	0xFF,
 		0,			0,
 		DEVF_SWAPS,
 		220000,
+		MGA_2164,
 		&vbMillennium2,
 		"Millennium II (PCI)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2_AGP,	0xFF,
 		0,			0,
 		DEVF_SWAPS,
 		250000,
+		MGA_2164,
 		&vbMillennium2A,
 		"Millennium II (AGP)"},
 #endif
@@ -1467,122 +1465,107 @@
 		0,			0,
 		DEVF_VIDEO64BIT | DEVF_CROSS4MB,
 		180000,
+		MGA_1064,
 		&vbMystique,
 		"Mystique (PCI)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,	0xFF,
 		0,			0,
 		DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
 		220000,
+		MGA_1164,
 		&vbMystique,
 		"Mystique 220 (PCI)"},
 #endif
 #ifdef CONFIG_FB_MATROX_G100
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_MM,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MGA_G100_PCI,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"MGA-G100 (PCI)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_MM,	0xFF,
 		0,			0,
 		DEVF_G100,
 		230000,
+		MGA_G100,
 		&vbG100,
-		"unknown G100 (PCI)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_GENERIC,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"MGA-G100 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MGA_G100_AGP,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"MGA-G100 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_SIEMENS_NIXDORF,	PCI_SS_ID_SIEMENS_MGA_G100_AGP,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"MGA-G100 (AGP)"},
-	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
-		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP,
-		DEVF_G100,
-		230000,
-		&vbG100,
-		"Productiva G100 (AGP)"},
+		"MGA-G100 (PCI)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,	0xFF,
 		0,			0,
 		DEVF_G100,
 		230000,
+		MGA_G100,
 		&vbG100,
-		"unknown G100 (AGP)"},
+		"MGA-G100 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_PCI,	0xFF,
 		0,			0,
 		DEVF_G200,
 		250000,
+		MGA_G200,
 		&vbG200,
-		"unknown G200 (PCI)"},
+		"MGA-G200 (PCI)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
 		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_GENERIC,
 		DEVF_G200,
 		220000,
+		MGA_G200,
 		&vbG200,
 		"MGA-G200 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
 		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP,
 		DEVF_G200,
 		230000,
+		MGA_G200,
 		&vbG200,
 		"Mystique G200 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
 		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MILLENIUM_G200_AGP,
 		DEVF_G200,
 		250000,
+		MGA_G200,
 		&vbG200,
 		"Millennium G200 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
 		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MARVEL_G200_AGP,
 		DEVF_G200,
 		230000,
+		MGA_G200,
 		&vbG200,
 		"Marvel G200 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
 		PCI_SS_VENDOR_ID_SIEMENS_NIXDORF,	PCI_SS_ID_SIEMENS_MGA_G200_AGP,
 		DEVF_G200,
 		230000,
+		MGA_G200,
 		&vbG200,
 		"MGA-G200 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
 		0,			0,
 		DEVF_G200,
 		230000,
+		MGA_G200,
 		&vbG200,
 		"G200 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400,	0x80,
 		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP,
 		DEVF_G400,
 		360000,
+		MGA_G400,
 		&vbG400,
 		"Millennium G400 MAX (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400,	0x80,
 		0,			0,
 		DEVF_G400,
 		300000,
+		MGA_G400,
 		&vbG400,
 		"G400 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400,	0xFF,
 		0,			0,
 		DEVF_G450,
-		500000,		/* ??? vco goes up to 900MHz... */
+		360000,
+		MGA_G450,
 		&vbG400,
 		"G450"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G550,	0xFF,
 		0,			0,
 		DEVF_G550,
-		500000,
+		360000,
+		MGA_G550,
 		&vbG400,
 		"G550"},
 #endif
@@ -1590,6 +1573,7 @@
 		0,			0,
 		0,
 		0,
+		0,
 		NULL,
 		NULL}};
 
@@ -1607,7 +1591,6 @@
 	unsigned long ctrlptr_phys = 0;
 	unsigned long video_base_phys = 0;
 	unsigned int memsize;
-	struct matrox_hw_state* hw = ACCESS_FBINFO(currenthw);
 	int err;
 
 	DBG("initMatrox2")
@@ -1621,6 +1604,7 @@
 
 	printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name);
 	ACCESS_FBINFO(capable.plnwt) = 1;
+	ACCESS_FBINFO(chip) = b->chip;
 	ACCESS_FBINFO(capable.srcorg) = b->flags & DEVF_SRCORG;
 	ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT;
 	if (b->flags & DEVF_TEXT4B) {
@@ -1658,7 +1642,6 @@
 	}
 	ACCESS_FBINFO(devflags.dfp_type) = dfp_type;
 	ACCESS_FBINFO(devflags.g450dac) = b->flags & DEVF_G450DAC;
-	ACCESS_FBINFO(devflags.g550dac) = b->flags & DEVF_G550DAC;
 	ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode);
 	ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode);
 
@@ -1667,9 +1650,11 @@
 	if (b->flags & DEVF_SWAPS) {
 		ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1);
 		video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0);
+		ACCESS_FBINFO(devflags.fbResource) = PCI_BASE_ADDRESS_0;
 	} else {
 		ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0);
 		video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1);
+		ACCESS_FBINFO(devflags.fbResource) = PCI_BASE_ADDRESS_1;
 	}
 	err = -EINVAL;
 	if (!ctrlptr_phys) {
@@ -1726,7 +1711,7 @@
 		}
 		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, cmd);
 		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mga_option);
-		hw->MXoptionReg = mga_option;
+		ACCESS_FBINFO(hw).MXoptionReg = mga_option;
 
 		/* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */
 		/* maybe preinit() candidate, but it is same... for all devices... at this time... */
@@ -1734,7 +1719,8 @@
 	}
 
 	err = -ENXIO;
-	if (ACCESS_FBINFO(hw_switch)->preinit(PMINFO hw)) {
+	matroxfb_read_pins(PMINFO2);
+	if (ACCESS_FBINFO(hw_switch)->preinit(PMINFO2)) {
 		goto failVideoIO;
 	}
 
@@ -1747,13 +1733,7 @@
 
 	ACCESS_FBINFO(currcon) = -1;
 	ACCESS_FBINFO(currcon_display) = d;
-	mga_iounmap(ACCESS_FBINFO(video.vbase));
 	ACCESS_FBINFO(video.base) = video_base_phys;
-	if (mga_ioremap(video_base_phys, ACCESS_FBINFO(video.len), MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) {
-		printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n",
-			video_base_phys, ACCESS_FBINFO(video.len));
-		goto failCtrlIO;
-	}
 	ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len);
 	if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable)
 		ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable;
@@ -1767,7 +1747,7 @@
 
 	if (!ACCESS_FBINFO(devflags.novga))
 		request_region(0x3C0, 32, "matrox");
-	ACCESS_FBINFO(hw_switch->reset(PMINFO hw));
+	ACCESS_FBINFO(hw_switch->reset(PMINFO2));
 
 	ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0;
 	ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh;
@@ -1790,7 +1770,7 @@
 
 	strcpy(ACCESS_FBINFO(fbcon.modename), "MATROX VGA");
 	ACCESS_FBINFO(fbcon.changevar) = NULL;
-	ACCESS_FBINFO(fbcon.node) = -1;
+	ACCESS_FBINFO(fbcon.node) = NODEV;
 	ACCESS_FBINFO(fbcon.fbops) = &matroxfb_ops;
 	ACCESS_FBINFO(fbcon.disp) = d;
 	ACCESS_FBINFO(fbcon.switch_con) = &matroxfb_switch;
@@ -1849,9 +1829,9 @@
 			          + vesafb_defined.right_margin + vesafb_defined.hsync_len);
 			if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
 		}
-		maxclk = (maxclk + 499) / 500;
-		if (maxclk) {
-			tmp = (2000000000 + maxclk) / maxclk;
+		tmp = (maxclk + 499) / 500;
+		if (tmp) {
+			tmp = (2000000000 + tmp) / tmp;
 			if (tmp > pixclock) pixclock = tmp;
 		}
 	}
@@ -2071,8 +2051,6 @@
 	memset(MINFO, 0, sizeof(*MINFO));
 	memset(d, 0, sizeof(*d));
 
-	ACCESS_FBINFO(currenthw) = &ACCESS_FBINFO(hw1);
-	ACCESS_FBINFO(newhw) = &ACCESS_FBINFO(hw2);
 	ACCESS_FBINFO(pcidev) = pdev;
 	ACCESS_FBINFO(dead) = 0;
 	ACCESS_FBINFO(usecount) = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_base.h linux/drivers/video/matrox/matroxfb_base.h
--- linux.orig/drivers/video/matrox/matroxfb_base.h	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_base.h	2002-07-20 01:08:37.000000000 +0000
@@ -124,10 +124,6 @@
 #endif
 #endif
 
-#ifdef __sparc__
-#error "Sorry, I have no idea how to do this on sparc... There is mapioaddr... With bus_type parameter..."
-#endif
-
 #if defined(__m68k__)
 #define MAP_BUSTOVIRT
 #else
@@ -166,7 +162,7 @@
 
 #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
 
-/* G100, G200 and Mystique have (almost) same DAC */
+/* G-series and Mystique have (almost) same DAC */
 #undef NEED_DAC1064
 #if defined(CONFIG_FB_MATROX_MYSTIQUE) || defined(CONFIG_FB_MATROX_G100)
 #define NEED_DAC1064 1
@@ -309,6 +305,21 @@
 	unsigned int delay;	/* CRTC delay */
 };
 
+enum { M_SYSTEM_PLL, M_PIXEL_PLL_A, M_PIXEL_PLL_B, M_PIXEL_PLL_C, M_VIDEO_PLL };
+
+struct matrox_pll_cache {
+	unsigned int	valid;
+	struct {
+		unsigned int	mnp_key;
+		unsigned int	mnp_value;
+		      } data[4];
+};
+
+struct matrox_pll_limits {
+	unsigned int	vcomin;
+	unsigned int	vcomax;
+};
+
 struct matrox_pll_features {
 	unsigned int	vco_freq_min;
 	unsigned int	ref_freq;
@@ -375,6 +386,8 @@
 
 	/* CRTC2 only */
 	/* u_int32_t	TBD */
+
+	unsigned int	vidclk;
 };
 
 struct matrox_accel_data {
@@ -386,8 +399,8 @@
 };
 
 struct matrox_altout {
-	int		(*compute)(void* altout_dev, struct my_timming* input, struct matrox_hw_state* state);
-	int		(*program)(void* altout_dev, const struct matrox_hw_state* state);
+	int		(*compute)(void* altout_dev, struct my_timming* input);
+	int		(*program)(void* altout_dev);
 	int		(*start)(void* altout_dev);
 	void		(*incuse)(void* altout_dev);
 	void		(*decuse)(void* altout_dev);
@@ -395,6 +408,20 @@
 	int		(*getmode)(void* altout_dev, u_int32_t* mode);
 };
 
+enum mga_chip { MGA_2064, MGA_2164, MGA_1064, MGA_1164, MGA_G100, MGA_G200, MGA_G400, MGA_G450, MGA_G550 };
+
+struct matrox_bios {
+	unsigned int	bios_valid : 1;
+	unsigned int	pins_len;
+	unsigned char	pins[128];
+	struct {
+		unsigned char vMaj, vMin, vRev;
+		      } version;
+	struct {
+		unsigned char state, tvout;
+		      } output;
+};
+
 struct matrox_switch;
 struct matroxfb_driver;
 
@@ -408,10 +435,7 @@
 	unsigned int		usecount;
 
 	struct matroxfb_par	curr;
-	struct matrox_hw_state	hw1;
-	struct matrox_hw_state	hw2;
-	struct matrox_hw_state*	newhw;
-	struct matrox_hw_state*	currenthw;
+	struct matrox_hw_state	hw;
 
 	struct matrox_accel_data accel;
 
@@ -468,6 +492,8 @@
 		spinlock_t	accel;
 			      } lock;
 
+	enum mga_chip		chip;
+
 	int			interleave;
 	int			millenium;
 	int			milleniumII;
@@ -518,8 +544,8 @@
 						/* 0 except for 6MB Millenium */
 		int		memtype;
 		int		g450dac;
-		int		g550dac;
 		int		dfp_type;
+		unsigned int	fbResource;
 			      } devflags;
 	struct display_switch	dispsw;
 	struct {
@@ -533,6 +559,38 @@
 		int		redraw;
 		struct timer_list timer;
 			      } cursor;
+	struct matrox_bios	bios;
+	struct {
+		struct matrox_pll_limits	pixel;
+		struct matrox_pll_limits	system;
+		struct matrox_pll_limits	video;
+			      } limits;
+	struct {
+		struct matrox_pll_cache	pixel;
+		struct matrox_pll_cache	system;
+		struct matrox_pll_cache	video;
+				      } cache;
+	struct {
+		struct {
+			unsigned int	video;
+			unsigned int	system;
+				      } pll;
+		struct {
+			u_int32_t	opt;
+			u_int32_t	opt2;
+			u_int32_t	opt3;
+			u_int32_t	mctlwtst;
+			u_int32_t	mctlwtst_core;
+			u_int32_t	memmisc;
+			u_int32_t	memrdbk;
+			u_int32_t	maccess;
+				      } reg;
+		struct {
+			unsigned int	ddr:1,
+			                emrswen:1,
+					dll:1;
+				      } memory;
+			      } values;
 	struct { unsigned red, green, blue, transp; } palette[256];
 #if defined(CONFIG_FB_COMPAT_XPMAC)
 	char	matrox_name[32];
@@ -603,10 +661,10 @@
 #endif
 
 struct matrox_switch {
-	int	(*preinit)(WPMINFO struct matrox_hw_state*);
-	void	(*reset)(WPMINFO struct matrox_hw_state*);
-	int	(*init)(CPMINFO struct matrox_hw_state*, struct my_timming*, struct display*);
-	void	(*restore)(WPMINFO struct matrox_hw_state*, struct matrox_hw_state*, struct display*);
+	int	(*preinit)(WPMINFO2);
+	void	(*reset)(WPMINFO2);
+	int	(*init)(WPMINFO struct my_timming*, struct display*);
+	void	(*restore)(WPMINFO struct display*);
 	int	(*selhwcursor)(WPMINFO struct display*);
 };
 
@@ -621,8 +679,13 @@
 void matroxfb_unregister_driver(struct matroxfb_driver* drv);
 
 #define PCI_OPTION_REG	0x40
+#define   PCI_OPTION_ENABLE_ROM		0x40000000
+
 #define PCI_MGA_INDEX	0x44
 #define PCI_MGA_DATA	0x48
+#define PCI_OPTION2_REG	0x50
+#define PCI_OPTION3_REG	0x54
+#define PCI_MEMMISC_REG	0x58
 
 #define M_DWGCTL	0x1C00
 #define M_MACCESS	0x1C04
@@ -741,6 +804,8 @@
 #define DAC_XGENIOCTRL		0x2A
 #define DAC_XGENIODATA		0x2B
 
+#define M_C2CTL		0x3E10
+
 #ifdef __LITTLE_ENDIAN
 #define MX_OPTION_BSWAP		0x00000000
 
@@ -798,6 +863,7 @@
 extern int matroxfb_DAC_in(CPMINFO int reg);
 extern struct list_head matroxfb_list;
 extern void matroxfb_var2my(struct fb_var_screeninfo* fvsi, struct my_timming* mt);
+extern int matroxfb_switch(int con, struct fb_info *);
 
 #ifdef MATROXFB_USE_SPINLOCKS
 #define CRITBEGIN  spin_lock_irqsave(&ACCESS_FBINFO(lock.accel), critflags);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_crtc2.c linux/drivers/video/matrox/matroxfb_crtc2.c
--- linux.orig/drivers/video/matrox/matroxfb_crtc2.c	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_crtc2.c	2002-07-20 01:08:30.000000000 +0000
@@ -4,7 +4,9 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.52 2001/05/25
+ * Portions Copyright (c) 2001 Matrox Graphics Inc.
+ *
+ * Version: 1.62 2001/11/29
  *
  */
 
@@ -402,43 +404,35 @@
 		info->changevar(con);
 	if (con == m2info->currcon) {
 		struct my_timming mt;
-		struct matrox_hw_state* hw;
-		struct matrox_hw_state* ohw;
 		unsigned int pos;
 
 		matroxfb_var2my(var, &mt);
 		/* CRTC2 delay */
 		mt.delay = 34;
 
-		hw = ACCESS_FBINFO(newhw);
-		ohw = ACCESS_FBINFO(currenthw);
-
-		/* copy last setting... */
-		memcpy(hw, ohw, sizeof(*hw));
-
 		pos = (var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel >> 3;
 		pos += m2info->video.offbase;
-		DAC1064_global_init(PMINFO hw);
+		DAC1064_global_init(PMINFO2);
 		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
 			if (ACCESS_FBINFO(primout))
-				ACCESS_FBINFO(primout)->compute(MINFO, &mt, hw);
+				ACCESS_FBINFO(primout)->compute(MINFO, &mt);
 		}
 		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
 			down_read(&ACCESS_FBINFO(altout.lock));
 			if (ACCESS_FBINFO(altout.output))
-				ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt, hw);
+				ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt);
 			up_read(&ACCESS_FBINFO(altout.lock));
 		}
 		matroxfb_dh_restore(m2info, &mt, p, mode, pos);
-		DAC1064_global_restore(PMINFO hw);
+		DAC1064_global_restore(PMINFO2);
 		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
 			if (ACCESS_FBINFO(primout))
-				ACCESS_FBINFO(primout)->program(MINFO, hw);
+				ACCESS_FBINFO(primout)->program(MINFO);
 		}
 		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
 			down_read(&ACCESS_FBINFO(altout.lock));
 			if (ACCESS_FBINFO(altout.output))
-				ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device), hw);
+				ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device));
 			up_read(&ACCESS_FBINFO(altout.lock));
 		}
 		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
@@ -693,7 +687,7 @@
 
 	strcpy(m2info->fbcon.modename, "MATROX CRTC2");
 	m2info->fbcon.changevar = NULL;
-	m2info->fbcon.node = -1;
+	m2info->fbcon.node = NODEV;
 	m2info->fbcon.fbops = &matroxfb_dh_ops;
 	m2info->fbcon.disp = d;
 	m2info->fbcon.switch_con = &matroxfb_dh_switch;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_g450.c linux/drivers/video/matrox/matroxfb_g450.c
--- linux.orig/drivers/video/matrox/matroxfb_g450.c	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_g450.c	2002-07-20 01:08:30.000000000 +0000
@@ -4,7 +4,9 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.51 2001/01/19
+ * Portions Copyright (c) 2001 Matrox Graphics Inc.
+ *
+ * Version: 1.62 2001/11/29
  *
  * See matroxfb_base.c for contributors.
  *
@@ -13,119 +15,28 @@
 #include "matroxfb_g450.h"
 #include "matroxfb_misc.h"
 #include "matroxfb_DAC1064.h"
+#include "g450_pll.h"
 #include <linux/matroxfb.h>
 #include <asm/uaccess.h>
 
-static int matroxfb_g450_get_reg(WPMINFO int reg) {
-	int val;
-	unsigned long flags;
-
-	matroxfb_DAC_lock_irqsave(flags);
-	val = matroxfb_DAC_in(PMINFO reg);
-	matroxfb_DAC_unlock_irqrestore(flags);
-	return val;
-}
-
-static int matroxfb_g450_set_reg(WPMINFO int reg, int val) {
-	unsigned long flags;
-
-	matroxfb_DAC_lock_irqsave(flags);
-	matroxfb_DAC_out(PMINFO reg, val);
-	matroxfb_DAC_unlock_irqrestore(flags);
-	return 0;
-}
-
-static const struct matrox_pll_features maven_pll = {
-	110000,
-	27000,
-	4, 127,
-	2, 31,
-	3
-};
-
-static const struct matrox_pll_features g550_pll = {
-	135000,
-	27000,
-	4, 127,
-	0, 9,
-	3
-};
-
-static void DAC1064_calcclock(unsigned int freq, unsigned int fmax,
-		unsigned int* in, unsigned int* feed, unsigned int* post,
-		unsigned int timmings) {
-	unsigned int fvco;
-	unsigned int p;
-
-	switch (timmings) {
-		default:
-			fvco = matroxfb_PLL_calcclock(&maven_pll, freq, fmax, in, feed, &p);
-			/* 0 => 100 ... 275 MHz
-		           1 => 243 ... 367 MHz
-		           2 => 320 ... 475 MHz
-		           3 => 453 ... 556 MHz
-		           4 => 540 ... 594 MHz
-		           5 => 588 ... 621 MHz
-		           6 => 626 ... 637 MHz
-		           7 => 631 ... 642 MHz
-
-		           As you can see, never choose frequency > 621 MHz, there is unavailable gap...
-		           Just to be sure, currently driver uses 110 ... 500 MHz range.
-		         */
-			if (fvco <= 260000)
-				;
-			else if (fvco <= 350000)
-				p |= 0x08;
-			else if (fvco <= 460000)
-				p |= 0x10;
-			else if (fvco <= 550000)
-				p |= 0x18;
-			else if (fvco <= 590000)
-				p |= 0x20;
-			else
-				p |= 0x28;
-			break;
-		case 1:
-			fvco = matroxfb_PLL_calcclock(&g550_pll, freq, fmax, in, feed, &p);
-			/* p |= 0x00; */
-			break;
-	}
-	*post = p;
-	return;
-}
-
-static inline int matroxfb_g450_compute_timming(struct matroxfb_g450_info* m2info,
-		struct my_timming* mt,
-		struct mavenregs* m) {
-	unsigned int a, b, c;
-
-	DAC1064_calcclock(mt->pixclock, 300000, &a, &b, &c, m2info->timmings);
-	m->regs[0x80] = a;
-	m->regs[0x81] = b;
-	m->regs[0x82] = c;
-	printk(KERN_DEBUG "PLL: %02X %02X %02X\n", a, b, c);
+static int matroxfb_g450_compute(void* md, struct my_timming* mt) {
+#define m2info ((struct matroxfb_g450_info*)md)
+#define minfo (m2info->primary_dev)
+	ACCESS_FBINFO(hw).vidclk = mt->pixclock;
+#undef minfo
+#undef m2info
 	return 0;
 }
 
-static inline int matroxfb_g450_program_timming(struct matroxfb_g450_info* m2info, const struct mavenregs* m) {
-	MINFO_FROM(m2info->primary_dev);
-
-	matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2M, m->regs[0x81]);
-	matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2N, m->regs[0x80]);
-	matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2P, m->regs[0x82]);
+static int matroxfb_g450_program(void* md) {
+#define m2info ((struct matroxfb_g450_info*)md)
+#define minfo (m2info->primary_dev)
+	matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(hw).vidclk, M_VIDEO_PLL);
+#undef minfo
+#undef m2info	
 	return 0;
 }
 
-/******************************************************/
-
-static int matroxfb_g450_compute(void* md, struct my_timming* mt, struct matrox_hw_state* mr) {
-	return matroxfb_g450_compute_timming(md, mt, &mr->maven);
-}
-
-static int matroxfb_g450_program(void* md, const struct matrox_hw_state* mr) {
-	return matroxfb_g450_program_timming(md, &mr->maven);
-}
-
 static int matroxfb_g450_start(void* md) {
 	return 0;
 }
@@ -191,7 +102,7 @@
 static void* matroxfb_g450_probe(struct matrox_fb_info* minfo) {
 	struct matroxfb_g450_info* m2info;
 
-	/* hardware is not G450 incapable... */
+	/* hardware is not G450... */
 	if (!ACCESS_FBINFO(devflags.g450dac))
 		return NULL;
 	m2info = (struct matroxfb_g450_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);
@@ -201,11 +112,6 @@
 	}
 	memset(m2info, 0, sizeof(*m2info));
 	m2info->primary_dev = MINFO;
-	if (ACCESS_FBINFO(devflags.g550dac)) {
-		m2info->timmings = 1;
-	} else {
-		m2info->timmings = 0;
-	}
 	if (matroxfb_g450_connect(m2info)) {
 		kfree(m2info);
 		printk(KERN_ERR "matroxfb_g450: G450 DAC failed to initialize\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_maven.c linux/drivers/video/matrox/matroxfb_maven.c
--- linux.orig/drivers/video/matrox/matroxfb_maven.c	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_maven.c	2002-07-20 01:08:22.000000000 +0000
@@ -4,7 +4,9 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.51 2001/01/19
+ * Portions Copyright (c) 2001 Matrox Graphics Inc.
+ *
+ * Version: 1.62 2001/11/29
  *
  * See matroxfb_base.c for contributors.
  *
@@ -25,10 +27,14 @@
 #define MODE_TV(x)	(((x) == MODE_PAL) || ((x) == MODE_NTSC))
 #define MODE_MONITOR	MATROXFB_OUTPUT_MODE_MONITOR
 
+#define MGATVO_B	1
+#define MGATVO_C	2
+
 struct maven_data {
 	struct matrox_fb_info*		primary_head;
 	struct i2c_client*		client;
 	int				mode;
+	int				version;
 };
 
 static int maven_get_reg(struct i2c_client* c, char reg) {
@@ -623,8 +629,13 @@
 		m->regs[0xA2] = mt->VTotal - mt->VSyncStart - 1;	/* stop vblanking */
 		m->regs[0xA3] = (mt->VTotal - mt->VSyncStart - 1) >> 8;
 		/* something end... [A6]+1..[A8] */
-		m->regs[0xA4] = 0x01;
-		m->regs[0xA5] = 0x00;
+		if (md->version == MGATVO_B) {
+			m->regs[0xA4] = 0x04;
+			m->regs[0xA5] = 0x00;
+		} else {
+			m->regs[0xA4] = 0x01;
+			m->regs[0xA5] = 0x00;
+		}
 		/* something start... 0..[A4]-1 */
 		m->regs[0xA6] = 0x00;
 		m->regs[0xA7] = 0x00;
@@ -862,12 +873,20 @@
 
 /******************************************************/
 
-static int maven_out_compute(void* md, struct my_timming* mt, struct matrox_hw_state* mr) {
-	return maven_compute_timming(md, mt, &mr->maven);
+static int maven_out_compute(void* md, struct my_timming* mt) {
+#define mdinfo ((struct maven_data*)md)
+#define minfo (mdinfo->primary_head)
+	return maven_compute_timming(md, mt, &ACCESS_FBINFO(hw).maven);
+#undef minfo
+#undef mdinfo
 }
 
-static int maven_out_program(void* md, const struct matrox_hw_state* mr) {
-	return maven_program_timming(md, &mr->maven);
+static int maven_out_program(void* md) {
+#define mdinfo ((struct maven_data*)md)
+#define minfo (mdinfo->primary_head)
+	return maven_program_timming(md, &ACCESS_FBINFO(hw).maven);
+#undef minfo
+#undef mdinfo
 }
 
 static int maven_out_start(void* md) {
@@ -916,6 +935,11 @@
 	ACCESS_FBINFO(altout.output) = &maven_altout;
 	up_write(&ACCESS_FBINFO(altout.lock));
 	ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY;
+	if (maven_get_reg(clnt, 0xB2) < 0x14) {
+		md->version = MGATVO_B;
+	} else {
+		md->version = MGATVO_C;
+	}
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_misc.c linux/drivers/video/matrox/matroxfb_misc.c
--- linux.orig/drivers/video/matrox/matroxfb_misc.c	2001-11-09 22:07:41.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_misc.c	2002-07-20 01:08:25.000000000 +0000
@@ -2,9 +2,11 @@
  *
  * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
  *
- * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ * (c) 1998,1999,2000,2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.54 2001/09/09
+ * Portions Copyright (c) 2001 Matrox Graphics Inc.
+ *
+ * Version: 1.62 2001/11/29
  *
  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  *
@@ -218,7 +220,7 @@
 	return bestvco;
 }
 
-int matroxfb_vgaHWinit(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
+int matroxfb_vgaHWinit(WPMINFO struct my_timming* m, struct display* p) {
 	unsigned int hd, hs, he, hbe, ht;
 	unsigned int vd, vs, ve, vt;
 	unsigned int wd;
@@ -226,6 +228,7 @@
 	int i;
 	int text = p->type == FB_TYPE_TEXT;
 	int fwidth;
+	struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw);
 
 	if (text) {
 		fwidth = fontwidth(p);
@@ -416,8 +419,9 @@
 	return 0;
 };
 
-void matroxfb_vgaHWrestore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw) {
+void matroxfb_vgaHWrestore(WPMINFO2) {
 	int i;
+	struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw);
 	CRITFLAGS
 
 	DBG("vgaHWrestore")
@@ -643,6 +647,354 @@
 	return 1;
 }
 
+static void get_pins(unsigned char* pins, struct matrox_bios* bd) {
+	unsigned int b0 = readb(pins);
+	
+	if (b0 == 0x2E && readb(pins+1) == 0x41) {
+		unsigned int pins_len = readb(pins+2);
+		unsigned int i;
+		unsigned char cksum;
+		unsigned char* dst = bd->pins;
+
+		if (pins_len < 3 || pins_len > 128) {
+			return;
+		}
+		*dst++ = 0x2E;
+		*dst++ = 0x41;
+		*dst++ = pins_len;
+		cksum = 0x2E + 0x41 + pins_len;
+		for (i = 3; i < pins_len; i++) {
+			cksum += *dst++ = readb(pins+i);
+		}
+		if (cksum) {
+			return;
+		}
+		bd->pins_len = pins_len;
+	} else if (b0 == 0x40 && readb(pins+1) == 0x00) {
+		unsigned int i;
+		unsigned char* dst = bd->pins;
+
+		*dst++ = 0x40;
+		*dst++ = 0;
+		for (i = 2; i < 0x40; i++) {
+			*dst++ = readb(pins+i);
+		}
+		bd->pins_len = 0x40;
+	}
+}
+
+static void get_bios_version(unsigned char* vbios, struct matrox_bios* bd) {
+	unsigned int pcir_offset;
+	
+	pcir_offset = readb(vbios + 24) | (readb(vbios + 25) << 8);
+	if (pcir_offset >= 26 && pcir_offset < 0xFFE0 &&
+	    readb(vbios + pcir_offset    ) == 'P' &&
+	    readb(vbios + pcir_offset + 1) == 'C' &&
+	    readb(vbios + pcir_offset + 2) == 'I' &&
+	    readb(vbios + pcir_offset + 3) == 'R') {
+		unsigned char h;
+
+		h = readb(vbios + pcir_offset + 0x12);
+		bd->version.vMaj = (h >> 4) & 0xF;
+		bd->version.vMin = h & 0xF;
+		bd->version.vRev = readb(vbios + pcir_offset + 0x13);
+	} else {
+		unsigned char h;
+
+		h = readb(vbios + 5);
+		bd->version.vMaj = (h >> 4) & 0xF;
+		bd->version.vMin = h & 0xF;
+		bd->version.vRev = 0;
+	}
+}
+
+static void get_bios_output(unsigned char* vbios, struct matrox_bios* bd) {
+	unsigned char b;
+	
+	b = readb(vbios + 0x7FF1);
+	if (b == 0xFF) {
+		b = 0;
+	}
+	bd->output.state = b;
+}
+
+static void get_bios_tvout(unsigned char* vbios, struct matrox_bios* bd) {
+	unsigned int i;
+	
+	/* Check for 'IBM .*(V....TVO' string - it means TVO BIOS */
+	bd->output.tvout = 0;
+	if (readb(vbios + 0x1D) != 'I' ||
+	    readb(vbios + 0x1E) != 'B' ||
+	    readb(vbios + 0x1F) != 'M' ||
+	    readb(vbios + 0x20) != ' ') {
+	    	return;
+	}
+	for (i = 0x2D; i < 0x2D + 128; i++) {
+		unsigned char b = readb(vbios + i);
+		
+		if (b == '(' && readb(vbios + i + 1) == 'V') {
+			if (readb(vbios + i + 6) == 'T' &&
+			    readb(vbios + i + 7) == 'V' &&
+			    readb(vbios + i + 8) == 'O') {
+				bd->output.tvout = 1;
+			}
+			return;
+		}
+		if (b == 0)
+			break;
+	}
+}
+
+static void parse_bios(unsigned char* vbios, struct matrox_bios* bd) {
+	unsigned int pins_offset;
+	
+	if (readb(vbios) != 0x55 || readb(vbios + 1) != 0xAA) {
+		return;
+	}
+	bd->bios_valid = 1;
+	get_bios_version(vbios, bd);
+	get_bios_output(vbios, bd);
+	get_bios_tvout(vbios, bd);
+	pins_offset = readb(vbios + 0x7FFC) | (readb(vbios + 0x7FFD) << 8);
+	if (pins_offset <= 0xFF80) {
+		get_pins(vbios + pins_offset, bd);
+	}
+}
+
+#define get_u16(x) (le16_to_cpu(get_unaligned((__u16*)(x))))
+#define get_u32(x) (le32_to_cpu(get_unaligned((__u32*)(x))))
+static int parse_pins1(WPMINFO const struct matrox_bios* bd) {
+	unsigned int maxdac;
+
+	switch (bd->pins[22]) {
+		case 0:		maxdac = 175000; break;
+		case 1:		maxdac = 220000; break;
+		default:	maxdac = 240000; break;
+	}
+	if (get_u16(bd->pins + 24)) {
+		maxdac = get_u16(bd->pins + 24) * 10;
+	}
+	MINFO->limits.pixel.vcomax = maxdac;
+	MINFO->values.pll.system = get_u16(bd->pins + 28) ? get_u16(bd->pins + 28) * 10 : 50000;
+	/* ignore 4MB, 8MB, module clocks */
+	MINFO->features.pll.ref_freq = 14318;
+	MINFO->values.reg.mctlwtst	= 0x00030101;
+	return 0;
+}
+
+static void default_pins1(WPMINFO2) {
+	/* Millennium */
+	MINFO->limits.pixel.vcomax	= 220000;
+	MINFO->values.pll.system	=  50000;
+	MINFO->features.pll.ref_freq	=  14318;
+	MINFO->values.reg.mctlwtst	= 0x00030101;
+}
+
+static int parse_pins2(WPMINFO const struct matrox_bios* bd) {
+	MINFO->limits.pixel.vcomax	=
+	MINFO->limits.system.vcomax	= (bd->pins[41] == 0xFF) ? 230000 : ((bd->pins[41] + 100) * 1000);
+	MINFO->values.reg.mctlwtst	= ((bd->pins[51] & 0x01) ? 0x00000001 : 0) |
+					  ((bd->pins[51] & 0x02) ? 0x00000100 : 0) |
+					  ((bd->pins[51] & 0x04) ? 0x00010000 : 0) |
+					  ((bd->pins[51] & 0x08) ? 0x00020000 : 0);
+	MINFO->values.pll.system	= (bd->pins[43] == 0xFF) ? 50000 : ((bd->pins[43] + 100) * 1000);
+	MINFO->features.pll.ref_freq	= 14318;
+	return 0;
+}
+
+static void default_pins2(WPMINFO2) {
+	/* Millennium II, Mystique */
+	MINFO->limits.pixel.vcomax	=
+	MINFO->limits.system.vcomax	= 230000;
+	MINFO->values.reg.mctlwtst	= 0x00030101;
+	MINFO->values.pll.system	=  50000;
+	MINFO->features.pll.ref_freq	=  14318;
+}
+
+static int parse_pins3(WPMINFO const struct matrox_bios* bd) {
+	MINFO->limits.pixel.vcomax	=
+	MINFO->limits.system.vcomax	= (bd->pins[36] == 0xFF) ? 230000			: ((bd->pins[36] + 100) * 1000);
+	MINFO->values.reg.mctlwtst	= get_u32(bd->pins + 48) == 0xFFFFFFFF ? 0x01250A21	: get_u32(bd->pins + 48);
+	/* memory config */
+	MINFO->values.reg.memrdbk	= ((bd->pins[57] << 21) & 0x1E000000) |
+					  ((bd->pins[57] << 22) & 0x00C00000) |
+					  ((bd->pins[56] <<  1) & 0x000001E0) |
+					  ( bd->pins[56]        & 0x0000000F);
+	MINFO->values.reg.opt		= (bd->pins[54] & 7) << 10;
+	MINFO->values.reg.opt2		= bd->pins[58] << 12;
+	MINFO->features.pll.ref_freq	= (bd->pins[52] & 0x20) ? 14318 : 27000;
+	return 0;
+}
+
+static void default_pins3(WPMINFO2) {
+	/* G100, G200 */
+	MINFO->limits.pixel.vcomax	=
+	MINFO->limits.system.vcomax	= 230000;
+	MINFO->values.reg.mctlwtst	= 0x01250A21;
+	MINFO->values.reg.memrdbk	= 0x00000000;
+	MINFO->values.reg.opt		= 0x00000C00;
+	MINFO->values.reg.opt2		= 0x00000000;
+	MINFO->features.pll.ref_freq	=  27000;
+}
+
+static int parse_pins4(WPMINFO const struct matrox_bios* bd) {
+	MINFO->limits.pixel.vcomax	= (bd->pins[ 39] == 0xFF) ? 230000			: bd->pins[ 39] * 4000;
+	MINFO->limits.system.vcomax	= (bd->pins[ 38] == 0xFF) ? MINFO->limits.pixel.vcomax	: bd->pins[ 38] * 4000;
+	MINFO->values.reg.mctlwtst	= get_u32(bd->pins + 71);
+	MINFO->values.reg.memrdbk	= ((bd->pins[87] << 21) & 0x1E000000) |
+					  ((bd->pins[87] << 22) & 0x00C00000) |
+					  ((bd->pins[86] <<  1) & 0x000001E0) |
+					  ( bd->pins[86]        & 0x0000000F);
+	MINFO->values.reg.opt		= ((bd->pins[53] << 15) & 0x00400000) |
+					  ((bd->pins[53] << 22) & 0x10000000) |
+					  ((bd->pins[53] << 10) & 0x00001C00);
+	MINFO->values.reg.opt3		= get_u32(bd->pins + 67);
+	MINFO->values.pll.system	= (bd->pins[ 65] == 0xFF) ? 200000 			: bd->pins[ 65] * 4000;
+	MINFO->features.pll.ref_freq	= (bd->pins[ 92] & 0x01) ? 14318 : 27000;
+	return 0;
+}
+
+static void default_pins4(WPMINFO2) {
+	/* G400 */
+	MINFO->limits.pixel.vcomax	=
+	MINFO->limits.system.vcomax	= 252000;
+	MINFO->values.reg.mctlwtst	= 0x04A450A1;
+	MINFO->values.reg.memrdbk	= 0x000000E7;
+	MINFO->values.reg.opt		= 0x10000400;
+	MINFO->values.reg.opt3		= 0x0190A419;
+	MINFO->values.pll.system	= 200000;
+	MINFO->features.pll.ref_freq	= 27000;
+}
+
+static int parse_pins5(WPMINFO const struct matrox_bios* bd) {
+	unsigned int mult;
+	
+	mult = bd->pins[4]?8000:6000;
+	
+	MINFO->limits.pixel.vcomax	= (bd->pins[ 38] == 0xFF) ? 600000			: bd->pins[ 38] * mult;
+	MINFO->limits.system.vcomax	= (bd->pins[ 36] == 0xFF) ? MINFO->limits.pixel.vcomax	: bd->pins[ 39] * mult;
+	MINFO->limits.video.vcomax	= (bd->pins[ 37] == 0xFF) ? MINFO->limits.system.vcomax	: bd->pins[ 37] * mult;
+	MINFO->limits.pixel.vcomin	= (bd->pins[123] == 0xFF) ? 256000			: bd->pins[123] * mult;
+	MINFO->limits.system.vcomin	= (bd->pins[121] == 0xFF) ? MINFO->limits.pixel.vcomin	: bd->pins[121] * mult;
+	MINFO->limits.video.vcomin	= (bd->pins[122] == 0xFF) ? MINFO->limits.system.vcomin	: bd->pins[122] * mult;
+	MINFO->values.pll.system	=
+	MINFO->values.pll.video		= (bd->pins[ 92] == 0xFF) ? 284000			: bd->pins[ 92] * 4000;
+	MINFO->values.reg.opt		= get_u32(bd->pins+ 48);
+	MINFO->values.reg.opt2		= get_u32(bd->pins+ 52);
+	MINFO->values.reg.opt3		= get_u32(bd->pins+ 94);
+	MINFO->values.reg.mctlwtst	= get_u32(bd->pins+ 98);
+	MINFO->values.reg.memmisc	= get_u32(bd->pins+102);
+	MINFO->values.reg.memrdbk	= get_u32(bd->pins+106);
+	MINFO->features.pll.ref_freq	= (bd->pins[110] & 0x01) ? 14318 : 27000;
+	MINFO->values.memory.ddr	= (bd->pins[114] & 0x60) == 0x20;
+	MINFO->values.memory.dll	= (bd->pins[115] & 0x02) != 0;
+	MINFO->values.memory.emrswen	= (bd->pins[115] & 0x01) != 0;
+	MINFO->values.reg.maccess	= MINFO->values.memory.emrswen ? 0x00004000 : 0x00000000;
+	if (bd->pins[115] & 4) {
+		MINFO->values.reg.mctlwtst_core = MINFO->values.reg.mctlwtst;
+	} else {
+		u_int32_t wtst_xlat[] = { 0, 1, 5, 6, 7, 5, 2, 3 };
+		MINFO->values.reg.mctlwtst_core = (MINFO->values.reg.mctlwtst & ~7) |
+		                                  wtst_xlat[MINFO->values.reg.mctlwtst & 7];
+	}
+	return 0;
+}
+
+static void default_pins5(WPMINFO2) {
+	/* Mine 16MB G450 with SDRAM DDR */
+	MINFO->limits.pixel.vcomax	=
+	MINFO->limits.system.vcomax	=
+	MINFO->limits.video.vcomax	= 600000;
+	MINFO->limits.pixel.vcomin	=
+	MINFO->limits.system.vcomin	=
+	MINFO->limits.video.vcomin	= 256000;
+	MINFO->values.pll.system	=
+	MINFO->values.pll.video		= 284000;
+	MINFO->values.reg.opt		= 0x404A1160;
+	MINFO->values.reg.opt2		= 0x0000AC00;
+	MINFO->values.reg.opt3		= 0x0090A409;
+	MINFO->values.reg.mctlwtst_core	=
+	MINFO->values.reg.mctlwtst	= 0x0C81462B;
+	MINFO->values.reg.memmisc	= 0x80000004;
+	MINFO->values.reg.memrdbk	= 0x01001103;
+	MINFO->features.pll.ref_freq	= 27000;
+	MINFO->values.memory.ddr	= 1;
+	MINFO->values.memory.dll	= 1;
+	MINFO->values.memory.emrswen	= 1;
+	MINFO->values.reg.maccess	= 0x00004000;
+}
+
+static int matroxfb_set_limits(WPMINFO const struct matrox_bios* bd) {
+	unsigned int pins_version;
+	static const unsigned int pinslen[] = { 64, 64, 64, 128, 128 };
+
+	switch (ACCESS_FBINFO(chip)) {
+		case MGA_2064:	default_pins1(PMINFO2); break;
+		case MGA_2164:
+		case MGA_1064:
+		case MGA_1164:	default_pins2(PMINFO2); break;
+		case MGA_G100:
+		case MGA_G200:	default_pins3(PMINFO2); break;
+		case MGA_G400:	default_pins4(PMINFO2); break;
+		case MGA_G450:
+		case MGA_G550:	default_pins5(PMINFO2); break;
+	}
+	if (!bd->bios_valid) {
+		printk(KERN_INFO "matroxfb: Your Matrox device does not have BIOS\n");
+		return -1;
+	}
+	if (bd->pins_len < 64) {
+		printk(KERN_INFO "matroxfb: BIOS on your Matrox device does not contain powerup info\n");
+		return -1;
+	}
+	if (bd->pins[0] == 0x2E && bd->pins[1] == 0x41) {
+		pins_version = bd->pins[5];
+		if (pins_version < 2 || pins_version > 5) {
+			printk(KERN_INFO "matroxfb: Unknown version (%u) of powerup info\n", pins_version);
+			return -1;
+		}
+	} else {
+		pins_version = 1;
+	}
+	if (bd->pins_len != pinslen[pins_version - 1]) {
+		printk(KERN_INFO "matroxfb: Invalid powerup info\n");
+		return -1;
+	}
+	switch (pins_version) {
+		case 1:
+			return parse_pins1(PMINFO bd);
+		case 2:
+			return parse_pins2(PMINFO bd);
+		case 3:
+			return parse_pins3(PMINFO bd);
+		case 4:
+			return parse_pins4(PMINFO bd);
+		case 5:
+			return parse_pins5(PMINFO bd);
+		default:
+			printk(KERN_DEBUG "matroxfb: Powerup info version %u is not yet supported\n", pins_version);
+			return -1;
+	}
+}
+
+void matroxfb_read_pins(WPMINFO2) {
+	u32 opt;
+	u32 biosbase;
+	u32 fbbase;
+	struct pci_dev* pdev = ACCESS_FBINFO(pcidev);
+	
+	memset(&ACCESS_FBINFO(bios), 0, sizeof(ACCESS_FBINFO(bios)));
+	pci_read_config_dword(pdev, PCI_OPTION_REG, &opt);
+	pci_write_config_dword(pdev, PCI_OPTION_REG, opt | PCI_OPTION_ENABLE_ROM);
+	pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &biosbase);
+	pci_read_config_dword(pdev, ACCESS_FBINFO(devflags.fbResource), &fbbase);
+	pci_write_config_dword(pdev, PCI_ROM_ADDRESS, (fbbase & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
+	parse_bios(vaddr_va(ACCESS_FBINFO(video).vbase), &ACCESS_FBINFO(bios));
+	pci_write_config_dword(pdev, PCI_ROM_ADDRESS, biosbase);
+	pci_write_config_dword(pdev, PCI_OPTION_REG, opt);
+	matroxfb_set_limits(PMINFO &ACCESS_FBINFO(bios));
+}
+
 EXPORT_SYMBOL(matroxfb_DAC_in);
 EXPORT_SYMBOL(matroxfb_DAC_out);
 EXPORT_SYMBOL(matroxfb_var2my);
@@ -657,6 +1009,7 @@
 EXPORT_SYMBOL(matroxfb_fastfont_init);		/* DAC1064, Ti3026 */
 EXPORT_SYMBOL(matroxfb_vgaHWinit);		/* DAC1064, Ti3026 */
 EXPORT_SYMBOL(matroxfb_vgaHWrestore);		/* DAC1064, Ti3026 */
+EXPORT_SYMBOL(matroxfb_read_pins);
 
 MODULE_AUTHOR("(c) 1999-2001 Petr Vandrovec <vandrove@vc.cvut.cz>");
 MODULE_DESCRIPTION("Miscellaneous support for Matrox video cards");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/matrox/matroxfb_misc.h linux/drivers/video/matrox/matroxfb_misc.h
--- linux.orig/drivers/video/matrox/matroxfb_misc.h	2000-12-11 21:16:53.000000000 +0000
+++ linux/drivers/video/matrox/matroxfb_misc.h	2002-07-20 01:08:24.000000000 +0000
@@ -12,10 +12,11 @@
 }
 
 void matroxfb_createcursorshape(WPMINFO struct display* p, int vmode);
-int matroxfb_vgaHWinit(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p);
-void matroxfb_vgaHWrestore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw);
+int matroxfb_vgaHWinit(WPMINFO struct my_timming* m, struct display* p);
+void matroxfb_vgaHWrestore(WPMINFO2);
 void matroxfb_fastfont_init(struct matrox_fb_info* minfo);
 int matrox_text_loadfont(WPMINFO struct display* p);
 int matroxfb_fastfont_tryset(WPMINFO struct display* p);
+void matroxfb_read_pins(WPMINFO2);
 
 #endif	/* __MATROXFB_MISC_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/maxinefb.c linux/drivers/video/maxinefb.c
--- linux.orig/drivers/video/maxinefb.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/video/maxinefb.c	2002-07-20 01:08:29.000000000 +0000
@@ -79,7 +79,7 @@
 };
 
 static int currcon = 0;
-struct maxinefb_par current_par;
+static struct maxinefb_par current_par;
 
 /* Reference to machine type set in arch/mips/dec/prom/identify.c, KM */
 extern unsigned long mips_machtype;
@@ -301,7 +301,7 @@
 	display->next_line = fix.line_length;
 	display->can_soft_blank = 0;
 	display->inverse = 0;
-
+	display->scrollmode = SCROLL_YREDRAW;
 	display->dispsw = &fbcon_cfb8;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/neofb.c linux/drivers/video/neofb.c
--- linux.orig/drivers/video/neofb.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/video/neofb.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,2423 @@
+/*
+ * linux/drivers/video/neofb.c -- NeoMagic Framebuffer Driver
+ *
+ * Copyright (c) 2001  Denis Oliver Kropp <dok@convergence.de>
+ *
+ *
+ * Card specific code is based on XFree86's neomagic driver.
+ * Framebuffer framework code is based on code of cyber2000fb.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ *
+ * 0.3.2
+ *  - got rid of all floating point (dok)
+ *
+ * 0.3.1
+ *  - added module license (dok)
+ *
+ * 0.3
+ *  - hardware accelerated clear and move for 2200 and above (dok)
+ *  - maximum allowed dotclock is handled now (dok)
+ *
+ * 0.2.1
+ *  - correct panning after X usage (dok)
+ *  - added module and kernel parameters (dok)
+ *  - no stretching if external display is enabled (dok)
+ *
+ * 0.2
+ *  - initial version (dok)
+ *
+ *
+ * TODO
+ * - ioctl for internal/external switching
+ * - blanking
+ * - 32bit depth support, maybe impossible
+ * - disable pan-on-sync, need specs
+ *
+ * BUGS
+ * - white margin on bootup like with tdfxfb (colormap problem?)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#include "neofb.h"
+
+
+#define NEOFB_VERSION "0.3.2"
+
+/* --------------------------------------------------------------------- */
+
+static int disabled   = 0;
+static int internal   = 0;
+static int external   = 0;
+static int nostretch  = 0;
+static int nopciburst = 0;
+
+
+#ifdef MODULE
+
+MODULE_AUTHOR("(c) 2001-2002  Denis Oliver Kropp <dok@convergence.de>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("FBDev driver for NeoMagic PCI Chips");
+MODULE_PARM(disabled, "i");
+MODULE_PARM_DESC(disabled, "Disable this driver's initialization.");
+MODULE_PARM(internal, "i");
+MODULE_PARM_DESC(internal, "Enable output on internal LCD Display.");
+MODULE_PARM(external, "i");
+MODULE_PARM_DESC(external, "Enable output on external CRT.");
+MODULE_PARM(nostretch, "i");
+MODULE_PARM_DESC(nostretch, "Disable stretching of modes smaller than LCD.");
+MODULE_PARM(nopciburst, "i");
+MODULE_PARM_DESC(nopciburst, "Disable PCI burst mode.");
+
+#endif
+
+
+/* --------------------------------------------------------------------- */
+
+static biosMode bios8[] = {	
+    { 320, 240, 0x40 },
+    { 300, 400, 0x42 },    
+    { 640, 400, 0x20 },
+    { 640, 480, 0x21 },
+    { 800, 600, 0x23 },
+    { 1024, 768, 0x25 },
+};
+
+static biosMode bios16[] = {
+    { 320, 200, 0x2e },
+    { 320, 240, 0x41 },
+    { 300, 400, 0x43 },
+    { 640, 480, 0x31 },
+    { 800, 600, 0x34 },
+    { 1024, 768, 0x37 },
+};
+
+static biosMode bios24[] = {
+    { 640, 480, 0x32 },
+    { 800, 600, 0x35 },
+    { 1024, 768, 0x38 }
+};
+
+#ifdef NO_32BIT_SUPPORT_YET
+/* FIXME: guessed values, wrong */
+static biosMode bios32[] = {
+    { 640, 480, 0x33 },
+    { 800, 600, 0x36 },
+    { 1024, 768, 0x39 }
+    };
+#endif
+
+static int neoFindMode (int xres, int yres, int depth)
+{
+  int xres_s;
+  int i, size;
+  biosMode *mode;
+
+  switch (depth)
+    {
+    case 8:
+      size = sizeof(bios8) / sizeof(biosMode);
+      mode = bios8;
+      break;
+    case 16:
+      size = sizeof(bios16) / sizeof(biosMode);
+      mode = bios16;
+      break;
+    case 24:
+      size = sizeof(bios24) / sizeof(biosMode);
+      mode = bios24;
+      break;
+#ifdef NO_32BIT_SUPPORT_YET
+    case 32:
+      size = sizeof(bios32) / sizeof(biosMode);
+      mode = bios32;
+      break;
+#endif
+    default:
+      return 0;
+    }
+
+  for (i = 0; i < size; i++)
+    {
+      if (xres <= mode[i].x_res)
+	{
+	  xres_s = mode[i].x_res;
+	  for (; i < size; i++)
+	    {
+	      if (mode[i].x_res != xres_s)
+		return mode[i-1].mode;
+	      if (yres <= mode[i].y_res)
+		return mode[i].mode;
+	    }
+	}
+    }
+  return mode[size - 1].mode;
+}
+
+/* -------------------- Hardware specific routines ------------------------- */
+
+/*
+ * Hardware Acceleration for Neo2200+
+ */
+static inline void neo2200_wait_idle (struct neofb_info *fb)
+{
+  int waitcycles;
+
+  while (fb->neo2200->bltStat & 1)
+    waitcycles++;
+}
+
+static inline void neo2200_wait_fifo (struct neofb_info *fb,
+                                      int requested_fifo_space)
+{
+  //  ndev->neo.waitfifo_calls++;
+  //  ndev->neo.waitfifo_sum += requested_fifo_space;
+
+  /* FIXME: does not work
+  if (neo_fifo_space < requested_fifo_space)
+    {
+      neo_fifo_waitcycles++;
+
+      while (1)
+    {
+      neo_fifo_space = (neo2200->bltStat >> 8);
+      if (neo_fifo_space >= requested_fifo_space)
+        break;
+    }
+    }
+  else
+    {
+      neo_fifo_cache_hits++;
+    }
+
+  neo_fifo_space -= requested_fifo_space;
+  */
+
+  neo2200_wait_idle (fb);
+}
+
+static inline void neo2200_accel_init (struct neofb_info        *fb,
+				       struct fb_var_screeninfo *var)
+{
+  Neo2200 *neo2200 = fb->neo2200;
+  u32 bltMod, pitch;
+
+  neo2200_wait_idle (fb);
+
+  switch (var->bits_per_pixel)
+    {
+    case 8:
+      bltMod = NEO_MODE1_DEPTH8;
+      pitch  = var->xres_virtual;
+      break;
+    case 15:
+    case 16:
+      bltMod = NEO_MODE1_DEPTH16;
+      pitch  = var->xres_virtual * 2;
+      break;
+    default:
+      printk( KERN_ERR "neofb: neo2200_accel_init: unexpected bits per pixel!\n" );
+      return;
+    }
+
+  neo2200->bltStat = bltMod << 16;
+  neo2200->pitch   = (pitch << 16) | pitch;
+}
+
+static void neo2200_accel_setup (struct display *p)
+{
+  struct neofb_info        *fb  = (struct neofb_info *)p->fb_info;
+  struct fb_var_screeninfo *var = &p->fb_info->var;
+
+  fb->dispsw->setup(p);
+
+  neo2200_accel_init (fb, var);
+}
+
+static void
+neo2200_accel_bmove (struct display *p, int sy, int sx, int dy, int dx,
+		     int height, int width)
+{
+  struct neofb_info *fb = (struct neofb_info *)p->fb_info;
+  struct fb_var_screeninfo *var = &p->fb_info->var;
+  Neo2200 *neo2200 = fb->neo2200;
+  u_long src, dst;
+  int bpp, pitch, inc_y;
+  u_int fh, fw;
+
+  if (sx != dx)
+    {
+      neo2200_wait_idle (fb);
+      fb->dispsw->bmove(p, sy, sx, dy, dx, height, width);
+      return;
+    }
+
+  bpp    = (var->bits_per_pixel+7) / 8;
+  pitch  = var->xres_virtual * bpp;
+
+  fw     = fontwidth(p);
+  sx    *= fw * bpp;
+  dx    *= fw * bpp;
+  width *= fw;
+
+  fh     = fontheight(p);
+  sy    *= fh;
+  dy    *= fh;
+
+  if (sy > dy)
+    inc_y = fh;
+  else
+    {
+      inc_y  = -fh;
+      sy    += (height - 1) * fh;
+      dy    += (height - 1) * fh;
+    }
+
+  neo2200_wait_fifo (fb, 1);
+
+  /* set blt control */
+  neo2200->bltCntl = NEO_BC3_FIFO_EN      |
+                     NEO_BC3_SKIP_MAPPING |  0x0c0000;
+
+  while (height--)
+    {
+      src = sx + sy * pitch;
+      dst = dx + dy * pitch;
+
+      neo2200_wait_fifo (fb, 3);
+
+      neo2200->srcStart = src;
+      neo2200->dstStart = dst;
+      neo2200->xyExt = (fh << 16) | (width & 0xffff);
+
+      sy += inc_y;
+      dy += inc_y;
+    }
+}
+
+static void
+neo2200_accel_clear (struct vc_data *conp, struct display *p, int sy, int sx,
+		     int height, int width)
+{
+  struct neofb_info *fb = (struct neofb_info *)p->fb_info;
+  struct fb_var_screeninfo *var = &p->fb_info->var;
+  Neo2200 *neo2200 = fb->neo2200;
+  u_long dst;
+  u_int fw, fh;
+  u32 bgx = attr_bgcol_ec(p, conp);
+
+  fw = fontwidth(p);
+  fh = fontheight(p);
+
+  dst    = sx * fw + sy * var->xres_virtual * fh;
+  width  = width * fw;
+  height = height * fh;
+
+  neo2200_wait_fifo (fb, 4);
+
+  /* set blt control */
+  neo2200->bltCntl  = NEO_BC3_FIFO_EN      |
+                      NEO_BC0_SRC_IS_FG    |
+                      NEO_BC3_SKIP_MAPPING |  0x0c0000;
+
+  switch (var->bits_per_pixel)
+    {
+    case 8:
+      neo2200->fgColor = bgx;
+      break;
+    case 16:
+      neo2200->fgColor = ((u16 *)(p->fb_info)->pseudo_palette)[bgx];
+      break;
+    }
+
+  neo2200->dstStart = dst * ((var->bits_per_pixel+7) / 8);
+
+  neo2200->xyExt    = (height << 16) | (width & 0xffff);
+}
+
+static void
+neo2200_accel_putc (struct vc_data *conp, struct display *p, int c,
+		    int yy, int xx)
+{
+  struct neofb_info *fb = (struct neofb_info *)p->fb_info;
+
+  neo2200_wait_idle (fb);
+  fb->dispsw->putc(conp, p, c, yy, xx);
+}
+
+static void
+neo2200_accel_putcs (struct vc_data *conp, struct display *p,
+		     const unsigned short *s, int count, int yy, int xx)
+{
+  struct neofb_info *fb = (struct neofb_info *)p->fb_info;
+
+  neo2200_wait_idle (fb);
+  fb->dispsw->putcs(conp, p, s, count, yy, xx);
+}
+
+static void neo2200_accel_revc (struct display *p, int xx, int yy)
+{
+  struct neofb_info *fb = (struct neofb_info *)p->fb_info;
+	
+  neo2200_wait_idle (fb);
+  fb->dispsw->revc (p, xx, yy);
+}
+
+static void
+neo2200_accel_clear_margins (struct vc_data *conp, struct display *p,
+			     int bottom_only)
+{
+  struct neofb_info *fb = (struct neofb_info *)p->fb_info;
+
+  fb->dispsw->clear_margins (conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_neo2200_accel = {
+  setup:		neo2200_accel_setup,
+  bmove:		neo2200_accel_bmove,
+  clear:		neo2200_accel_clear,
+  putc:			neo2200_accel_putc,
+  putcs:		neo2200_accel_putcs,
+  revc:			neo2200_accel_revc,
+  clear_margins:	neo2200_accel_clear_margins,
+  fontwidthmask:	FONTWIDTH(8)|FONTWIDTH(16)
+};
+
+
+/* --------------------------------------------------------------------- */
+
+/*
+ *    Set a single color register. Return != 0 for invalid regno.
+ */
+static int neo_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			 u_int transp, struct fb_info *fb)
+{
+  struct neofb_info *info = (struct neofb_info *)fb;
+
+  if (regno >= NR_PALETTE)
+    return -EINVAL;
+
+  info->palette[regno].red    = red;
+  info->palette[regno].green  = green;
+  info->palette[regno].blue   = blue;
+  info->palette[regno].transp = transp;
+
+  switch (fb->var.bits_per_pixel)
+    {
+#ifdef FBCON_HAS_CFB8
+    case 8:
+      outb(regno, 0x3c8);
+
+      outb(red   >> 10, 0x3c9);
+      outb(green >> 10, 0x3c9);
+      outb(blue  >> 10, 0x3c9);
+      break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+    case 16:
+      if (regno < 16)
+	((u16 *)fb->pseudo_palette)[regno] = ((red   & 0xf800)      ) |
+	                                     ((green & 0xfc00) >>  5) |
+                                             ((blue  & 0xf800) >> 11);
+      break;
+#endif
+
+#ifdef FBCON_HAS_CFB24
+    case 24:
+      if (regno < 16)
+	((u32 *)fb->pseudo_palette)[regno] = ((red   & 0xff00) << 8) |
+                                             ((green & 0xff00)     ) |
+	                                     ((blue  & 0xff00) >> 8);
+      break;
+#endif
+
+#ifdef NO_32BIT_SUPPORT_YET
+#ifdef FBCON_HAS_CFB32
+    case 32:
+      if (regno < 16)
+	((u32 *)fb->pseudo_palette)[regno] = ((transp & 0xff00) << 16) |
+	                                     ((red    & 0xff00) <<  8) |
+                                             ((green  & 0xff00)      ) |
+	                                     ((blue   & 0xff00) >>  8);
+      break;
+#endif
+#endif
+
+    default:
+      return 1;
+    }
+
+  return 0;
+}
+
+static void vgaHWLock (void)
+{
+  /* Protect CRTC[0-7] */
+  VGAwCR (0x11, VGArCR (0x11) | 0x80);
+}
+
+static void vgaHWUnlock (void)
+{
+  /* Unprotect CRTC[0-7] */
+  VGAwCR (0x11, VGArCR (0x11) & ~0x80);
+}
+
+static void neoLock (void)
+{
+  VGAwGR (0x09, 0x00);
+  vgaHWLock();
+}
+
+static void neoUnlock (void)
+{
+  vgaHWUnlock();
+  VGAwGR (0x09, 0x26);
+}
+
+/*
+ * vgaHWSeqReset
+ *      perform a sequencer reset.
+ */
+void
+vgaHWSeqReset(int start)
+{
+  if (start)
+    VGAwSEQ (0x00, 0x01);		/* Synchronous Reset */
+  else
+    VGAwSEQ (0x00, 0x03);		/* End Reset */
+}
+
+void
+vgaHWProtect(int on)
+{
+  unsigned char tmp;
+  
+  if (on)
+    {
+      /*
+       * Turn off screen and disable sequencer.
+       */
+      tmp = VGArSEQ (0x01);
+
+      vgaHWSeqReset (1);			/* start synchronous reset */
+      VGAwSEQ (0x01, tmp | 0x20);	/* disable the display */
+
+      VGAenablePalette();
+    }
+  else
+    {
+      /*
+       * Reenable sequencer, then turn on screen.
+       */
+  
+      tmp = VGArSEQ (0x01);
+
+      VGAwSEQ (0x01, tmp & ~0x20);	/* reenable display */
+      vgaHWSeqReset (0);		/* clear synchronousreset */
+
+      VGAdisablePalette();
+    }
+}
+
+static void vgaHWRestore (const struct neofb_info *info,
+			  const struct neofb_par  *par)
+{
+  int i;
+
+  VGAwMISC (par->MiscOutReg);
+
+  for (i = 1; i < 5; i++)
+    VGAwSEQ (i, par->Sequencer[i]);
+  
+  /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
+  VGAwCR (17, par->CRTC[17] & ~0x80);
+
+  for (i = 0; i < 25; i++)
+    VGAwCR (i, par->CRTC[i]);
+
+  for (i = 0; i < 9; i++)
+    VGAwGR (i, par->Graphics[i]);
+
+  VGAenablePalette();
+
+  for (i = 0; i < 21; i++)
+    VGAwATTR (i, par->Attribute[i]);
+
+  VGAdisablePalette();
+}
+
+static void neofb_set_par (struct neofb_info       *info,
+			   const struct neofb_par  *par)
+{
+  unsigned char temp;
+  int i;
+  int clock_hi = 0;
+    
+  DBG("neofb_set_par");
+
+  neoUnlock();
+
+  vgaHWProtect (1);		/* Blank the screen */
+
+  /* linear colormap for non palettized modes */
+  switch (par->depth)
+    {
+    case 8:
+      break;
+    case 16:
+      for (i=0; i<64; i++)
+	{
+	  outb(i, 0x3c8);
+	  
+	  outb(i << 1, 0x3c9);
+	  outb(i, 0x3c9);
+	  outb(i << 1, 0x3c9);
+	}
+      break;
+    case 24:
+#ifdef NO_32BIT_SUPPORT_YET
+    case 32:
+#endif
+      for (i=0; i<256; i++)
+	{
+	  outb(i, 0x3c8);
+	  
+	  outb(i, 0x3c9);
+	  outb(i, 0x3c9);
+	  outb(i, 0x3c9);
+	}
+      break;
+    }
+    
+  /* alread unlocked above */
+  /* BOGUS  VGAwGR (0x09, 0x26);*/
+    
+  /* don't know what this is, but it's 0 from bootup anyway */
+  VGAwGR (0x15, 0x00);
+
+  /* was set to 0x01 by my bios in text and vesa modes */
+  VGAwGR (0x0A, par->GeneralLockReg);
+
+  /*
+   * The color mode needs to be set before calling vgaHWRestore
+   * to ensure the DAC is initialized properly.
+   *
+   * NOTE: Make sure we don't change bits make sure we don't change
+   * any reserved bits.
+   */
+  temp = VGArGR(0x90);
+  switch (info->accel)
+    {
+    case FB_ACCEL_NEOMAGIC_NM2070:
+      temp &= 0xF0; /* Save bits 7:4 */
+      temp |= (par->ExtColorModeSelect & ~0xF0);
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2090:
+    case FB_ACCEL_NEOMAGIC_NM2093:
+    case FB_ACCEL_NEOMAGIC_NM2097:
+    case FB_ACCEL_NEOMAGIC_NM2160:
+    case FB_ACCEL_NEOMAGIC_NM2200:
+    case FB_ACCEL_NEOMAGIC_NM2230:
+    case FB_ACCEL_NEOMAGIC_NM2360:
+    case FB_ACCEL_NEOMAGIC_NM2380:
+      temp &= 0x70; /* Save bits 6:4 */
+      temp |= (par->ExtColorModeSelect & ~0x70);
+      break;
+    }
+
+  VGAwGR(0x90,temp);
+
+  /*
+   * In some rare cases a lockup might occur if we don't delay
+   * here. (Reported by Miles Lane)
+   */
+  //mdelay(200);
+
+  /*
+   * Disable horizontal and vertical graphics and text expansions so
+   * that vgaHWRestore works properly.
+   */
+  temp = VGArGR(0x25);
+  temp &= 0x39;
+  VGAwGR (0x25, temp);
+
+  /*
+   * Sleep for 200ms to make sure that the two operations above have
+   * had time to take effect.
+   */
+  mdelay(200);
+
+  /*
+   * This function handles restoring the generic VGA registers.  */
+  vgaHWRestore (info, par);
+
+
+  VGAwGR(0x0E, par->ExtCRTDispAddr);
+  VGAwGR(0x0F, par->ExtCRTOffset);
+  temp = VGArGR(0x10);
+  temp &= 0x0F; /* Save bits 3:0 */
+  temp |= (par->SysIfaceCntl1 & ~0x0F); /* VESA Bios sets bit 1! */
+  VGAwGR(0x10, temp);
+
+  VGAwGR(0x11, par->SysIfaceCntl2);
+  VGAwGR(0x15, 0 /*par->SingleAddrPage*/);
+  VGAwGR(0x16, 0 /*par->DualAddrPage*/);
+
+  temp = VGArGR(0x20);
+  switch (info->accel)
+    {
+    case FB_ACCEL_NEOMAGIC_NM2070:
+      temp &= 0xFC; /* Save bits 7:2 */
+      temp |= (par->PanelDispCntlReg1 & ~0xFC);
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2090:
+    case FB_ACCEL_NEOMAGIC_NM2093:
+    case FB_ACCEL_NEOMAGIC_NM2097:
+    case FB_ACCEL_NEOMAGIC_NM2160:
+      temp &= 0xDC; /* Save bits 7:6,4:2 */
+      temp |= (par->PanelDispCntlReg1 & ~0xDC);
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2200:
+    case FB_ACCEL_NEOMAGIC_NM2230:
+    case FB_ACCEL_NEOMAGIC_NM2360:
+    case FB_ACCEL_NEOMAGIC_NM2380:
+      temp &= 0x98; /* Save bits 7,4:3 */
+      temp |= (par->PanelDispCntlReg1 & ~0x98);
+      break;
+    }
+  VGAwGR(0x20, temp);
+
+  temp = VGArGR(0x25);
+  temp &= 0x38; /* Save bits 5:3 */
+  temp |= (par->PanelDispCntlReg2 & ~0x38);
+  VGAwGR(0x25, temp);
+
+  if (info->accel != FB_ACCEL_NEOMAGIC_NM2070)
+    {
+      temp = VGArGR(0x30);
+      temp &= 0xEF; /* Save bits 7:5 and bits 3:0 */
+      temp |= (par->PanelDispCntlReg3 & ~0xEF);
+      VGAwGR(0x30, temp);
+    }
+
+  VGAwGR(0x28, par->PanelVertCenterReg1);
+  VGAwGR(0x29, par->PanelVertCenterReg2);
+  VGAwGR(0x2a, par->PanelVertCenterReg3);
+
+  if (info->accel != FB_ACCEL_NEOMAGIC_NM2070)
+    {
+      VGAwGR(0x32, par->PanelVertCenterReg4);
+      VGAwGR(0x33, par->PanelHorizCenterReg1);
+      VGAwGR(0x34, par->PanelHorizCenterReg2);
+      VGAwGR(0x35, par->PanelHorizCenterReg3);
+    }
+
+  if (info->accel == FB_ACCEL_NEOMAGIC_NM2160)
+    VGAwGR(0x36, par->PanelHorizCenterReg4);
+
+  if (info->accel == FB_ACCEL_NEOMAGIC_NM2200 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2230 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2360 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2380)
+    {
+      VGAwGR(0x36, par->PanelHorizCenterReg4);
+      VGAwGR(0x37, par->PanelVertCenterReg5);
+      VGAwGR(0x38, par->PanelHorizCenterReg5);
+
+      clock_hi = 1;
+    }
+
+  /* Program VCLK3 if needed. */
+  if (par->ProgramVCLK
+      && ((VGArGR(0x9B) != par->VCLK3NumeratorLow)
+	  || (VGArGR(0x9F) !=  par->VCLK3Denominator)
+	  || (clock_hi && ((VGArGR(0x8F) & ~0x0f)
+			   != (par->VCLK3NumeratorHigh & ~0x0F)))))
+    {
+      VGAwGR(0x9B, par->VCLK3NumeratorLow);
+      if (clock_hi)
+	{
+	  temp = VGArGR(0x8F);
+	  temp &= 0x0F; /* Save bits 3:0 */
+	  temp |= (par->VCLK3NumeratorHigh & ~0x0F);
+	  VGAwGR(0x8F, temp);
+	}
+      VGAwGR(0x9F, par->VCLK3Denominator);
+    }
+
+  if (par->biosMode)
+    VGAwCR(0x23, par->biosMode);
+    
+  VGAwGR (0x93, 0xc0); /* Gives 5x faster framebuffer writes !!! */
+
+  /* Program vertical extension register */
+  if (info->accel == FB_ACCEL_NEOMAGIC_NM2200 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2230 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2360 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2380)
+    {
+      VGAwCR(0x70, par->VerticalExt);
+    }
+
+
+  vgaHWProtect (0);		/* Turn on screen */
+
+  /* Calling this also locks offset registers required in update_start */
+  neoLock();
+}
+
+static void neofb_update_start (struct neofb_info *info, struct fb_var_screeninfo *var)
+{
+  int oldExtCRTDispAddr;
+  int Base; 
+
+  DBG("neofb_update_start");
+
+  Base = (var->yoffset * var->xres_virtual + var->xoffset) >> 2;
+  Base *= (var->bits_per_pixel + 7) / 8;
+
+  neoUnlock();
+
+  /*
+   * These are the generic starting address registers.
+   */
+  VGAwCR(0x0C, (Base & 0x00FF00) >> 8);
+  VGAwCR(0x0D, (Base & 0x00FF));
+
+  /*
+   * Make sure we don't clobber some other bits that might already
+   * have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
+   * be needed.
+   */
+  oldExtCRTDispAddr = VGArGR(0x0E);
+  VGAwGR(0x0E,(((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
+
+  neoLock();
+}
+
+/*
+ * Set the Colormap
+ */
+static int neofb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *fb)
+{
+  struct neofb_info *info = (struct neofb_info *)fb;
+  struct display* disp = (con < 0) ? fb->disp : (fb_display + con);
+  struct fb_cmap *dcmap = &disp->cmap;
+  int err = 0;
+
+  /* no colormap allocated? */
+  if (!dcmap->len)
+    {
+      int size;
+
+      if (fb->var.bits_per_pixel == 8)
+	size = NR_PALETTE;
+      else
+	size = 32;
+
+      err = fb_alloc_cmap (dcmap, size, 0);
+    }
+
+  /*
+   * we should be able to remove this test once fbcon has been
+   * "improved" --rmk
+   */
+  if (!err && con == info->currcon)
+    {
+      err = fb_set_cmap (cmap, kspc, neo_setcolreg, fb);
+      dcmap = &fb->cmap;
+    }
+
+  if (!err)
+    fb_copy_cmap (cmap, dcmap, kspc ? 0 : 1);
+
+  return err;
+}
+
+/*
+ * neoCalcVCLK --
+ *
+ * Determine the closest clock frequency to the one requested.
+ */
+#define REF_FREQ 0xe517  /* 14.31818 in 20.12 fixed point */
+#define MAX_N 127
+#define MAX_D 31
+#define MAX_F 1
+
+static void neoCalcVCLK (const struct neofb_info *info, struct neofb_par *par, long freq)
+{
+  int n, d, f;
+  int n_best = 0, d_best = 0, f_best = 0;
+  long f_best_diff = (0x7ffff << 12); /* 20.12 */
+  long f_target = (freq << 12) / 1000; /* 20.12 */
+
+  for (f = 0; f <= MAX_F; f++)
+    for (n = 0; n <= MAX_N; n++)
+      for (d = 0; d <= MAX_D; d++)
+	{
+          long f_out;  /* 20.12 */
+          long f_diff; /* 20.12 */
+
+	  f_out = ((((n+1) << 12)  /  ((d+1)*(1<<f))) >> 12)  *  REF_FREQ;
+	  f_diff = abs(f_out-f_target);
+	  if (f_diff < f_best_diff)
+	    {
+	      f_best_diff = f_diff;
+	      n_best = n;
+	      d_best = d;
+	      f_best = f;
+	    }
+	}
+
+  if (info->accel == FB_ACCEL_NEOMAGIC_NM2200 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2230 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2360 ||
+      info->accel == FB_ACCEL_NEOMAGIC_NM2380)
+    {
+      /* NOT_DONE:  We are trying the full range of the 2200 clock.
+	 We should be able to try n up to 2047 */
+      par->VCLK3NumeratorLow  = n_best;
+      par->VCLK3NumeratorHigh = (f_best << 7);
+    }
+  else
+    par->VCLK3NumeratorLow  = n_best | (f_best << 7);
+
+  par->VCLK3Denominator = d_best;
+
+#ifdef NEOFB_DEBUG
+  printk ("neoVCLK: f:%d NumLow=%d NumHi=%d Den=%d Df=%d\n",
+	  f_target >> 12,
+	  par->VCLK3NumeratorLow,
+	  par->VCLK3NumeratorHigh,
+	  par->VCLK3Denominator,
+	  f_best_diff >> 12);
+#endif
+}
+
+/*
+ * vgaHWInit --
+ *      Handle the initialization, etc. of a screen.
+ *      Return FALSE on failure.
+ */
+
+static int vgaHWInit (const struct fb_var_screeninfo *var,
+		      const struct neofb_info        *info,
+		      struct neofb_par               *par,
+		      struct xtimings                *timings)
+{
+  par->MiscOutReg = 0x23;
+
+  if (!(timings->sync & FB_SYNC_HOR_HIGH_ACT))
+    par->MiscOutReg |= 0x40;
+
+  if (!(timings->sync & FB_SYNC_VERT_HIGH_ACT))
+    par->MiscOutReg |= 0x80;
+    
+  /*
+   * Time Sequencer
+   */
+  par->Sequencer[0] = 0x00;
+  par->Sequencer[1] = 0x01;
+  par->Sequencer[2] = 0x0F;
+  par->Sequencer[3] = 0x00;                             /* Font select */
+  par->Sequencer[4] = 0x0E;                             /* Misc */
+
+  /*
+   * CRTC Controller
+   */
+  par->CRTC[0]  = (timings->HTotal >> 3) - 5;
+  par->CRTC[1]  = (timings->HDisplay >> 3) - 1;
+  par->CRTC[2]  = (timings->HDisplay >> 3) - 1;
+  par->CRTC[3]  = (((timings->HTotal >> 3) - 1) & 0x1F) | 0x80;
+  par->CRTC[4]  = (timings->HSyncStart >> 3);
+  par->CRTC[5]  = ((((timings->HTotal >> 3) - 1) & 0x20) << 2)
+    | (((timings->HSyncEnd >> 3)) & 0x1F);
+  par->CRTC[6]  = (timings->VTotal - 2) & 0xFF;
+  par->CRTC[7]  = (((timings->VTotal - 2) & 0x100) >> 8)
+    | (((timings->VDisplay - 1) & 0x100) >> 7)
+    | ((timings->VSyncStart & 0x100) >> 6)
+    | (((timings->VDisplay - 1) & 0x100) >> 5)
+    | 0x10
+    | (((timings->VTotal - 2) & 0x200)   >> 4)
+    | (((timings->VDisplay - 1) & 0x200) >> 3)
+    | ((timings->VSyncStart & 0x200) >> 2);
+  par->CRTC[8]  = 0x00;
+  par->CRTC[9]  = (((timings->VDisplay - 1) & 0x200) >> 4) | 0x40;
+
+  if (timings->dblscan)
+    par->CRTC[9] |= 0x80;
+
+  par->CRTC[10] = 0x00;
+  par->CRTC[11] = 0x00;
+  par->CRTC[12] = 0x00;
+  par->CRTC[13] = 0x00;
+  par->CRTC[14] = 0x00;
+  par->CRTC[15] = 0x00;
+  par->CRTC[16] = timings->VSyncStart & 0xFF;
+  par->CRTC[17] = (timings->VSyncEnd & 0x0F) | 0x20;
+  par->CRTC[18] = (timings->VDisplay - 1) & 0xFF;
+  par->CRTC[19] = var->xres_virtual >> 4;
+  par->CRTC[20] = 0x00;
+  par->CRTC[21] = (timings->VDisplay - 1) & 0xFF; 
+  par->CRTC[22] = (timings->VTotal - 1) & 0xFF;
+  par->CRTC[23] = 0xC3;
+  par->CRTC[24] = 0xFF;
+
+  /*
+   * are these unnecessary?
+   * vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
+   * vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
+   */
+
+  /*
+   * Graphics Display Controller
+   */
+  par->Graphics[0] = 0x00;
+  par->Graphics[1] = 0x00;
+  par->Graphics[2] = 0x00;
+  par->Graphics[3] = 0x00;
+  par->Graphics[4] = 0x00;
+  par->Graphics[5] = 0x40;
+  par->Graphics[6] = 0x05;   /* only map 64k VGA memory !!!! */
+  par->Graphics[7] = 0x0F;
+  par->Graphics[8] = 0xFF;
+  
+
+  par->Attribute[0]  = 0x00; /* standard colormap translation */
+  par->Attribute[1]  = 0x01;
+  par->Attribute[2]  = 0x02;
+  par->Attribute[3]  = 0x03;
+  par->Attribute[4]  = 0x04;
+  par->Attribute[5]  = 0x05;
+  par->Attribute[6]  = 0x06;
+  par->Attribute[7]  = 0x07;
+  par->Attribute[8]  = 0x08;
+  par->Attribute[9]  = 0x09;
+  par->Attribute[10] = 0x0A;
+  par->Attribute[11] = 0x0B;
+  par->Attribute[12] = 0x0C;
+  par->Attribute[13] = 0x0D;
+  par->Attribute[14] = 0x0E;
+  par->Attribute[15] = 0x0F;
+  par->Attribute[16] = 0x41;
+  par->Attribute[17] = 0xFF;
+  par->Attribute[18] = 0x0F;
+  par->Attribute[19] = 0x00;
+  par->Attribute[20] = 0x00;
+
+  return 0;
+}
+
+static int neofb_decode_var (struct fb_var_screeninfo        *var,
+                             const struct neofb_info         *info,
+                             struct neofb_par                *par)
+{
+  struct xtimings timings;
+  int lcd_stretch;
+  int hoffset, voffset;
+  int memlen, vramlen;
+  int mode_ok = 0;
+  unsigned int pixclock = var->pixclock;
+
+  DBG("neofb_decode_var");
+
+  if (!pixclock) pixclock = 10000;	/* 10ns = 100MHz */
+  timings.pixclock = 1000000000 / pixclock;
+  if (timings.pixclock < 1) timings.pixclock = 1;
+  timings.dblscan = var->vmode & FB_VMODE_DOUBLE;
+  timings.interlaced = var->vmode & FB_VMODE_INTERLACED;
+  timings.HDisplay = var->xres;
+  timings.HSyncStart = timings.HDisplay + var->right_margin;
+  timings.HSyncEnd = timings.HSyncStart + var->hsync_len;
+  timings.HTotal = timings.HSyncEnd + var->left_margin;
+  timings.VDisplay = var->yres;
+  timings.VSyncStart = timings.VDisplay + var->lower_margin;
+  timings.VSyncEnd = timings.VSyncStart + var->vsync_len;
+  timings.VTotal = timings.VSyncEnd + var->upper_margin;
+  timings.sync = var->sync;
+
+  if (timings.pixclock > info->maxClock)
+    return -EINVAL;
+
+  /* Is the mode larger than the LCD panel? */
+  if ((var->xres > info->NeoPanelWidth) ||
+      (var->yres > info->NeoPanelHeight))
+    {
+      printk (KERN_INFO "Mode (%dx%d) larger than the LCD panel (%dx%d)\n",
+	      var->xres,
+	      var->yres,
+	      info->NeoPanelWidth,
+	      info->NeoPanelHeight);
+      return -EINVAL;
+    }
+
+  /* Is the mode one of the acceptable sizes? */
+  switch (var->xres)
+    {
+    case 1280:
+      if (var->yres == 1024)
+	mode_ok = 1;
+      break;
+    case 1024:
+      if (var->yres == 768)
+	mode_ok = 1;
+      break;
+    case  800:
+      if (var->yres == 600)
+	mode_ok = 1;
+      break;
+    case  640:
+      if (var->yres == 480)
+	mode_ok = 1;
+      break;
+    }
+
+  if (!mode_ok)
+    {
+      printk (KERN_INFO "Mode (%dx%d) won't display properly on LCD\n",
+	      var->xres, var->yres);
+      return -EINVAL;
+    }
+
+
+  switch (var->bits_per_pixel)
+    {
+#ifdef FBCON_HAS_CFB8
+    case 8:
+      break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+    case 16:
+      break;
+#endif
+
+#ifdef FBCON_HAS_CFB24
+    case 24:
+      break;
+#endif
+
+#ifdef NO_32BIT_SUPPORT_YET
+# ifdef FBCON_HAS_CFB32
+    case 32:
+      break;
+# endif
+#endif
+
+    default:
+      return -EINVAL;
+    }
+
+  par->depth = var->bits_per_pixel;
+
+  vramlen = info->video.len;
+  if (vramlen > 4*1024*1024)
+    vramlen = 4*1024*1024;
+
+  if (var->yres_virtual < var->yres)
+    var->yres_virtual = var->yres;
+  if (var->xres_virtual < var->xres)
+    var->xres_virtual = var->xres;
+
+  memlen = var->xres_virtual * var->bits_per_pixel * var->yres_virtual / 8;
+  if (memlen > vramlen)
+    {
+      var->yres_virtual = vramlen * 8 / (var->xres_virtual * var->bits_per_pixel);
+      memlen = var->xres_virtual * var->bits_per_pixel * var->yres_virtual / 8;
+    }
+
+  /* we must round yres/xres down, we already rounded y/xres_virtual up
+     if it was possible. We should return -EINVAL, but I disagree */
+  if (var->yres_virtual < var->yres)
+    var->yres = var->yres_virtual;
+  if (var->xres_virtual < var->xres)
+    var->xres = var->xres_virtual;
+  if (var->xoffset + var->xres > var->xres_virtual)
+    var->xoffset = var->xres_virtual - var->xres;
+  if (var->yoffset + var->yres > var->yres_virtual)
+    var->yoffset = var->yres_virtual - var->yres;
+
+
+  /*
+   * This will allocate the datastructure and initialize all of the
+   * generic VGA registers.
+   */
+
+  if (vgaHWInit (var, info, par, &timings))
+    return -EINVAL;
+
+  /*
+   * The default value assigned by vgaHW.c is 0x41, but this does
+   * not work for NeoMagic.
+   */
+  par->Attribute[16] = 0x01;
+
+  switch (var->bits_per_pixel)
+    {
+    case  8:
+      par->CRTC[0x13]   = var->xres_virtual >> 3;
+      par->ExtCRTOffset = var->xres_virtual >> 11;
+      par->ExtColorModeSelect = 0x11;
+      break;
+    case 16:
+      par->CRTC[0x13]   = var->xres_virtual >> 2;
+      par->ExtCRTOffset = var->xres_virtual >> 10;
+      par->ExtColorModeSelect = 0x13;
+      break;
+    case 24:
+      par->CRTC[0x13]   = (var->xres_virtual * 3) >> 3;
+      par->ExtCRTOffset = (var->xres_virtual * 3) >> 11;
+      par->ExtColorModeSelect = 0x14;
+      break;
+#ifdef NO_32BIT_SUPPORT_YET
+    case 32: /* FIXME: guessed values */
+      par->CRTC[0x13]   = var->xres_virtual >> 1;
+      par->ExtCRTOffset = var->xres_virtual >> 9;
+      par->ExtColorModeSelect = 0x15;
+      break;
+#endif
+    default:
+      break;
+    }
+	
+  par->ExtCRTDispAddr = 0x10;
+
+  /* Vertical Extension */
+  par->VerticalExt = (((timings.VTotal -2) & 0x400) >> 10 )
+    | (((timings.VDisplay -1) & 0x400) >> 9 )
+    | (((timings.VSyncStart) & 0x400) >> 8 )
+    | (((timings.VSyncStart) & 0x400) >> 7 );
+
+  /* Fast write bursts on unless disabled. */
+  if (info->pci_burst)
+    par->SysIfaceCntl1 = 0x30; 
+  else
+    par->SysIfaceCntl1 = 0x00; 
+
+  par->SysIfaceCntl2 = 0xc0; /* VESA Bios sets this to 0x80! */
+
+  /* Enable any user specified display devices. */
+  par->PanelDispCntlReg1 = 0x00;
+  if (info->internal_display)
+    par->PanelDispCntlReg1 |= 0x02;
+  if (info->external_display)
+    par->PanelDispCntlReg1 |= 0x01;
+
+  /* If the user did not specify any display devices, then... */
+  if (par->PanelDispCntlReg1 == 0x00) {
+    /* Default to internal (i.e., LCD) only. */
+    par->PanelDispCntlReg1 |= 0x02;
+  }
+
+  /* If we are using a fixed mode, then tell the chip we are. */
+  switch (var->xres)
+    {
+    case 1280:
+      par->PanelDispCntlReg1 |= 0x60;
+      break;
+    case 1024:
+      par->PanelDispCntlReg1 |= 0x40;
+      break;
+    case 800:
+      par->PanelDispCntlReg1 |= 0x20;
+      break;
+    case 640:
+    default:
+      break;
+    }
+  
+  /* Setup shadow register locking. */
+  switch (par->PanelDispCntlReg1 & 0x03)
+    {
+    case 0x01: /* External CRT only mode: */
+      par->GeneralLockReg = 0x00;
+      /* We need to program the VCLK for external display only mode. */
+      par->ProgramVCLK = 1;
+      break;
+    case 0x02: /* Internal LCD only mode: */
+    case 0x03: /* Simultaneous internal/external (LCD/CRT) mode: */
+      par->GeneralLockReg = 0x01;
+      /* Don't program the VCLK when using the LCD. */
+      par->ProgramVCLK = 0;
+      break;
+    }
+
+  /*
+   * If the screen is to be stretched, turn on stretching for the
+   * various modes.
+   *
+   * OPTION_LCD_STRETCH means stretching should be turned off!
+   */
+  par->PanelDispCntlReg2 = 0x00;
+  par->PanelDispCntlReg3 = 0x00;
+
+  if (info->lcd_stretch &&
+      (par->PanelDispCntlReg1 == 0x02) &&  /* LCD only */
+      (var->xres != info->NeoPanelWidth))
+    {
+      switch (var->xres)
+	{
+	case  320: /* Needs testing.  KEM -- 24 May 98 */
+	case  400: /* Needs testing.  KEM -- 24 May 98 */
+	case  640:
+	case  800:
+	case 1024:
+	  lcd_stretch = 1;
+	  par->PanelDispCntlReg2 |= 0xC6;
+	  break;
+	default:
+	  lcd_stretch = 0;
+	  /* No stretching in these modes. */
+	}
+    }
+  else
+    lcd_stretch = 0;
+
+  /*
+   * If the screen is to be centerd, turn on the centering for the
+   * various modes.
+   */
+  par->PanelVertCenterReg1  = 0x00;
+  par->PanelVertCenterReg2  = 0x00;
+  par->PanelVertCenterReg3  = 0x00;
+  par->PanelVertCenterReg4  = 0x00;
+  par->PanelVertCenterReg5  = 0x00;
+  par->PanelHorizCenterReg1 = 0x00;
+  par->PanelHorizCenterReg2 = 0x00;
+  par->PanelHorizCenterReg3 = 0x00;
+  par->PanelHorizCenterReg4 = 0x00;
+  par->PanelHorizCenterReg5 = 0x00;
+
+
+  if (par->PanelDispCntlReg1 & 0x02)
+    {
+      if (var->xres == info->NeoPanelWidth)
+	{
+	  /*
+	   * No centering required when the requested display width
+	   * equals the panel width.
+	   */
+	}
+      else
+	{
+	  par->PanelDispCntlReg2 |= 0x01;
+	  par->PanelDispCntlReg3 |= 0x10;
+
+	  /* Calculate the horizontal and vertical offsets. */
+	  if (!lcd_stretch)
+	    {
+	      hoffset = ((info->NeoPanelWidth - var->xres) >> 4) - 1;
+	      voffset = ((info->NeoPanelHeight - var->yres) >> 1) - 2;
+	    }
+	  else
+	    {
+	      /* Stretched modes cannot be centered. */
+	      hoffset = 0;
+	      voffset = 0;
+	    }
+
+	  switch (var->xres)
+	    {
+	    case  320: /* Needs testing.  KEM -- 24 May 98 */
+	      par->PanelHorizCenterReg3 = hoffset;
+	      par->PanelVertCenterReg2  = voffset;
+	      break;
+	    case  400: /* Needs testing.  KEM -- 24 May 98 */
+	      par->PanelHorizCenterReg4 = hoffset;
+	      par->PanelVertCenterReg1  = voffset;
+	      break;
+	    case  640:
+	      par->PanelHorizCenterReg1 = hoffset;
+	      par->PanelVertCenterReg3  = voffset;
+	      break;
+	    case  800:
+	      par->PanelHorizCenterReg2 = hoffset;
+	      par->PanelVertCenterReg4  = voffset;
+	      break;
+	    case 1024:
+	      par->PanelHorizCenterReg5 = hoffset;
+	      par->PanelVertCenterReg5  = voffset;
+	      break;
+	    case 1280:
+	    default:
+	      /* No centering in these modes. */
+	      break;
+	    }
+	}
+    }
+
+  par->biosMode = neoFindMode (var->xres, var->yres, var->bits_per_pixel);
+    
+  /*
+   * Calculate the VCLK that most closely matches the requested dot
+   * clock.
+   */
+  neoCalcVCLK (info, par, timings.pixclock);
+
+  /* Since we program the clocks ourselves, always use VCLK3. */
+  par->MiscOutReg |= 0x0C;
+
+  return 0;
+}
+
+static int neofb_set_var (struct fb_var_screeninfo *var, int con,
+                          struct fb_info *fb)
+{
+  struct neofb_info *info = (struct neofb_info *)fb;
+  struct display *display;
+  struct neofb_par par;
+  int err, chgvar = 0;
+
+  DBG("neofb_set_var");
+
+  err = neofb_decode_var (var, info, &par);
+  if (err)
+    return err;
+
+  if (var->activate & FB_ACTIVATE_TEST)
+    return 0;
+
+  if (con < 0)
+    {
+      display = fb->disp;
+      chgvar = 0;
+    }
+  else
+    {
+      display = fb_display + con;
+
+      if (fb->var.xres != var->xres)
+	chgvar = 1;
+      if (fb->var.yres != var->yres)
+	chgvar = 1;
+      if (fb->var.xres_virtual != var->xres_virtual)
+	chgvar = 1;
+      if (fb->var.yres_virtual != var->yres_virtual)
+	chgvar = 1;
+      if (fb->var.bits_per_pixel != var->bits_per_pixel)
+	chgvar = 1;
+    }
+
+  if (!info->neo2200)
+    var->accel_flags &= ~FB_ACCELF_TEXT;
+
+  var->red.msb_right	= 0;
+  var->green.msb_right	= 0;
+  var->blue.msb_right	= 0;
+
+  switch (var->bits_per_pixel)
+    {
+#ifdef FBCON_HAS_CFB8
+    case 8:	/* PSEUDOCOLOUR, 256 */
+      var->transp.offset   = 0;
+      var->transp.length   = 0;
+      var->red.offset      = 0;
+      var->red.length      = 8;
+      var->green.offset	   = 0;
+      var->green.length	   = 8;
+      var->blue.offset	   = 0;
+      var->blue.length	   = 8;
+      
+      fb->fix.visual       = FB_VISUAL_PSEUDOCOLOR;
+      info->dispsw         = &fbcon_cfb8;
+      display->dispsw_data = NULL;
+      display->next_line   = var->xres_virtual;
+      break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+    case 16: /* DIRECTCOLOUR, 64k */
+      var->transp.offset   = 0;
+      var->transp.length   = 0;
+      var->red.offset      = 11;
+      var->red.length      = 5;
+      var->green.offset    = 5;
+      var->green.length    = 6;
+      var->blue.offset     = 0;
+      var->blue.length     = 5;
+
+      fb->fix.visual       = FB_VISUAL_DIRECTCOLOR;
+      info->dispsw         = &fbcon_cfb16;
+      display->dispsw_data = fb->pseudo_palette;
+      display->next_line   = var->xres_virtual * 2;
+      break;
+#endif
+
+#ifdef FBCON_HAS_CFB24
+    case 24: /* TRUECOLOUR, 16m */
+      var->transp.offset   = 0;
+      var->transp.length   = 0;
+      var->red.offset      = 16;
+      var->red.length      = 8;
+      var->green.offset    = 8;
+      var->green.length    = 8;
+      var->blue.offset     = 0;
+      var->blue.length     = 8;
+
+      fb->fix.visual       = FB_VISUAL_TRUECOLOR;
+      info->dispsw         = &fbcon_cfb24;
+      display->dispsw_data = fb->pseudo_palette;
+      display->next_line   = var->xres_virtual * 3;
+
+      var->accel_flags    &= ~FB_ACCELF_TEXT;
+      break;
+#endif
+
+#ifdef NO_32BIT_SUPPORT_YET
+# ifdef FBCON_HAS_CFB32
+    case 32: /* TRUECOLOUR, 16m */
+      var->transp.offset   = 24;
+      var->transp.length   = 8;
+      var->red.offset      = 16;
+      var->red.length      = 8;
+      var->green.offset    = 8;
+      var->green.length    = 8;
+      var->blue.offset     = 0;
+      var->blue.length     = 8;
+
+      fb->fix.visual       = FB_VISUAL_TRUECOLOR;
+      info->dispsw         = &fbcon_cfb32;
+      display->dispsw_data = fb->pseudo_palette;
+      display->next_line   = var->xres_virtual * 4;
+
+      var->accel_flags    &= ~FB_ACCELF_TEXT;
+      break;
+# endif
+#endif
+
+    default:
+      printk (KERN_WARNING "neofb: no support for %dbpp\n", var->bits_per_pixel);
+      info->dispsw      = &fbcon_dummy;
+      var->accel_flags &= ~FB_ACCELF_TEXT;
+      break;
+    }
+
+  if (var->accel_flags & FB_ACCELF_TEXT)
+    display->dispsw = &fbcon_neo2200_accel;
+  else
+    display->dispsw = info->dispsw;
+
+  fb->fix.line_length = display->next_line;
+
+  display->screen_base    = fb->screen_base;
+  display->line_length    = fb->fix.line_length;
+  display->visual         = fb->fix.visual;
+  display->type	          = fb->fix.type;
+  display->type_aux       = fb->fix.type_aux;
+  display->ypanstep       = fb->fix.ypanstep;
+  display->ywrapstep      = fb->fix.ywrapstep;
+  display->can_soft_blank = 1;
+  display->inverse        = 0;
+
+  fb->var = *var;
+  fb->var.activate &= ~FB_ACTIVATE_ALL;
+
+  /*
+   * Update the old var.  The fbcon drivers still use this.
+   * Once they are using cfb->fb.var, this can be dropped.
+   *					--rmk
+   */
+  display->var = fb->var;
+
+  /*
+   * If we are setting all the virtual consoles, also set the
+   * defaults used to create new consoles.
+   */
+  if (var->activate & FB_ACTIVATE_ALL)
+    fb->disp->var = fb->var;
+
+  if (chgvar && fb && fb->changevar)
+    fb->changevar (con);
+
+  if (con == info->currcon)
+    {
+      if (chgvar || con < 0)
+        neofb_set_par (info, &par);
+
+      neofb_update_start (info, var);
+      fb_set_cmap (&fb->cmap, 1, neo_setcolreg, fb);
+
+      if (var->accel_flags & FB_ACCELF_TEXT)
+	neo2200_accel_init (info, var);
+    }
+
+  return 0;
+}
+
+/*
+ *    Pan or Wrap the Display
+ */
+static int neofb_pan_display (struct fb_var_screeninfo *var, int con,
+			      struct fb_info *fb)
+{
+  struct neofb_info *info = (struct neofb_info *)fb;
+  u_int y_bottom;
+
+  y_bottom = var->yoffset;
+
+  if (!(var->vmode & FB_VMODE_YWRAP))
+    y_bottom += var->yres;
+
+  if (var->xoffset > (var->xres_virtual - var->xres))
+    return -EINVAL;
+  if (y_bottom > fb->var.yres_virtual)
+    return -EINVAL;
+
+  neofb_update_start (info, var);
+
+  fb->var.xoffset = var->xoffset;
+  fb->var.yoffset = var->yoffset;
+
+  if (var->vmode & FB_VMODE_YWRAP)
+    fb->var.vmode |= FB_VMODE_YWRAP;
+  else
+    fb->var.vmode &= ~FB_VMODE_YWRAP;
+
+  return 0;
+}
+
+
+/*
+ *    Update the `var' structure (called by fbcon.c)
+ *
+ *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
+ *    Since it's called by a kernel driver, no range checking is done.
+ */
+static int neofb_updatevar (int con, struct fb_info *fb)
+{
+  struct neofb_info *info = (struct neofb_info *)fb;
+
+  neofb_update_start (info, &fb_display[con].var);
+
+  return 0;
+}
+
+static int neofb_switch (int con, struct fb_info *fb)
+{
+  struct neofb_info *info = (struct neofb_info *)fb;
+  struct display *disp;
+  struct fb_cmap *cmap;
+
+  if (info->currcon >= 0)
+    {
+      disp = fb_display + info->currcon;
+
+      /*
+       * Save the old colormap and video mode.
+       */
+      disp->var = fb->var;
+      if (disp->cmap.len)
+	fb_copy_cmap(&fb->cmap, &disp->cmap, 0);
+    }
+
+  info->currcon = con;
+  disp = fb_display + con;
+
+  /*
+   * Install the new colormap and change the video mode.  By default,
+   * fbcon sets all the colormaps and video modes to the default
+   * values at bootup.
+   *
+   * Really, we want to set the colourmap size depending on the
+   * depth of the new video mode.  For now, we leave it at its
+   * default 256 entry.
+   */
+  if (disp->cmap.len)
+    cmap = &disp->cmap;
+  else
+    cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
+
+  fb_copy_cmap(cmap, &fb->cmap, 0);
+
+  disp->var.activate = FB_ACTIVATE_NOW;
+  neofb_set_var(&disp->var, con, fb);
+
+  return 0;
+}
+
+/*
+ *    (Un)Blank the display.
+ */
+static void neofb_blank (int blank, struct fb_info *fb)
+{
+  //  struct neofb_info *info = (struct neofb_info *)fb;
+
+  /*
+   *  Blank the screen if blank_mode != 0, else unblank. If
+   *  blank == NULL then the caller blanks by setting the CLUT
+   *  (Color Look Up Table) to all black. Return 0 if blanking
+   *  succeeded, != 0 if un-/blanking failed due to e.g. a
+   *  video mode which doesn't support it. Implements VESA
+   *  suspend and powerdown modes on hardware that supports
+   *  disabling hsync/vsync:
+   *    blank_mode == 2: suspend vsync
+   *    blank_mode == 3: suspend hsync
+   *    blank_mode == 4: powerdown
+   *
+   *  wms...Enable VESA DMPS compatible powerdown mode
+   *  run "setterm -powersave powerdown" to take advantage
+   */
+     
+  switch (blank)
+    {
+    case 4:	/* powerdown - both sync lines down */
+      break;	
+    case 3:	/* hsync off */
+      break;	
+    case 2:	/* vsync off */
+      break;	
+    case 1:	/* just software blanking of screen */
+      break;
+    default: /* case 0, or anything else: unblank */
+      break;
+    }
+}
+
+/*
+ * Get the currently displayed virtual consoles colormap.
+ */
+static int gen_get_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *fb)
+{
+  fb_copy_cmap (&fb->cmap, cmap, kspc ? 0 : 2);
+  return 0;
+}
+
+/*
+ * Get the currently displayed virtual consoles fixed part of the display.
+ */
+static int gen_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *fb)
+{
+  *fix = fb->fix;
+  return 0;
+}
+
+/*
+ * Get the current user defined part of the display.
+ */
+static int gen_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *fb)
+{
+  *var = fb->var;
+  return 0;
+}
+
+static struct fb_ops neofb_ops = {
+  owner:          THIS_MODULE,
+  fb_set_var:     neofb_set_var,
+  fb_set_cmap:    neofb_set_cmap,
+  fb_pan_display: neofb_pan_display,
+  fb_get_fix:     gen_get_fix,
+  fb_get_var:     gen_get_var,
+  fb_get_cmap:    gen_get_cmap,
+};
+
+/* --------------------------------------------------------------------- */
+
+static struct fb_var_screeninfo __devinitdata neofb_var640x480x8 = {
+	accel_flags:	FB_ACCELF_TEXT,
+	xres:		640,
+	yres:		480,
+	xres_virtual:   640,
+	yres_virtual:   30000,
+	bits_per_pixel: 8,
+	pixclock:	39722,
+	left_margin:	48,
+	right_margin:	16,
+	upper_margin:	33,
+	lower_margin:	10,
+	hsync_len:	96,
+	vsync_len:	2,
+	sync:		0,
+	vmode:		FB_VMODE_NONINTERLACED
+};
+
+static struct fb_var_screeninfo __devinitdata neofb_var800x600x8 = {
+	accel_flags:	FB_ACCELF_TEXT,
+	xres:		800,
+	yres:		600,
+	xres_virtual:   800,
+	yres_virtual:   30000,
+	bits_per_pixel: 8,
+	pixclock:	25000,
+	left_margin:	88,
+	right_margin:	40,
+	upper_margin:	23,
+	lower_margin:	1,
+	hsync_len:	128,
+	vsync_len:	4,
+	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	vmode:		FB_VMODE_NONINTERLACED
+};
+
+static struct fb_var_screeninfo __devinitdata neofb_var1024x768x8 = {
+	accel_flags:	FB_ACCELF_TEXT,
+	xres:		1024,
+	yres:		768,
+	xres_virtual:   1024,
+	yres_virtual:   30000,
+	bits_per_pixel: 8,
+	pixclock:	15385,
+	left_margin:	160,
+	right_margin:	24,
+	upper_margin:	29,
+	lower_margin:	3,
+	hsync_len:	136,
+	vsync_len:	6,
+	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	vmode:		FB_VMODE_NONINTERLACED
+};
+
+#ifdef NOT_DONE
+static struct fb_var_screeninfo __devinitdata neofb_var1280x1024x8 = {
+	accel_flags:	FB_ACCELF_TEXT,
+	xres:		1280,
+	yres:		1024,
+	xres_virtual:   1280,
+	yres_virtual:   30000,
+	bits_per_pixel: 8,
+	pixclock:	9260,
+	left_margin:	248,
+	right_margin:	48,
+	upper_margin:	38,
+	lower_margin:	1,
+	hsync_len:	112,
+	vsync_len:	3,
+	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	vmode:		FB_VMODE_NONINTERLACED
+};
+#endif
+
+static struct fb_var_screeninfo *neofb_var = NULL;
+
+
+static int __devinit neo_map_mmio (struct neofb_info *info)
+{
+  DBG("neo_map_mmio");
+
+  info->mmio.pbase = pci_resource_start (info->pcidev, 1);
+  info->mmio.len   = MMIO_SIZE;
+
+  if (!request_mem_region (info->mmio.pbase, MMIO_SIZE, "memory mapped I/O"))
+    {
+      printk ("neofb: memory mapped IO in use\n");
+      return -EBUSY;
+    }
+
+  info->mmio.vbase = ioremap (info->mmio.pbase, MMIO_SIZE);
+  if (!info->mmio.vbase)
+    {
+      printk ("neofb: unable to map memory mapped IO\n");
+      release_mem_region (info->mmio.pbase, info->mmio.len);
+      return -ENOMEM;
+    }
+  else
+    printk (KERN_INFO "neofb: mapped io at %p\n", info->mmio.vbase);
+
+  info->fb.fix.mmio_start = info->mmio.pbase;
+  info->fb.fix.mmio_len   = info->mmio.len;
+
+  return 0;
+}
+
+static void __devinit neo_unmap_mmio (struct neofb_info *info)
+{
+  DBG("neo_unmap_mmio");
+
+  if (info->mmio.vbase)
+    {
+      iounmap (info->mmio.vbase);
+      info->mmio.vbase = NULL;
+
+      release_mem_region (info->mmio.pbase, info->mmio.len);
+    }
+}
+
+static int __devinit neo_map_video (struct neofb_info *info, int video_len)
+{
+  DBG("neo_map_video");
+
+  info->video.pbase = pci_resource_start (info->pcidev, 0);
+  info->video.len   = video_len;
+
+  if (!request_mem_region (info->video.pbase, info->video.len, "frame buffer"))
+    {
+      printk ("neofb: frame buffer in use\n");
+      return -EBUSY;
+    }
+
+  info->video.vbase = ioremap (info->video.pbase, info->video.len);
+  if (!info->video.vbase)
+    {
+      printk ("neofb: unable to map screen memory\n");
+      release_mem_region (info->video.pbase, info->video.len);
+      return -ENOMEM;
+    }
+  else
+    printk (KERN_INFO "neofb: mapped framebuffer at %p\n", info->video.vbase);
+
+  info->fb.fix.smem_start = info->video.pbase;
+  info->fb.fix.smem_len   = info->video.len;
+  info->fb.screen_base    = info->video.vbase;
+
+#ifdef CONFIG_MTRR
+  info->video.mtrr = mtrr_add (info->video.pbase, pci_resource_len (info->pcidev, 0), MTRR_TYPE_WRCOMB, 1);
+#endif
+
+  /* Clear framebuffer, it's all white in memory after boot */
+  memset (info->video.vbase, 0, info->video.len);
+
+  return 0;
+}
+
+static void __devinit neo_unmap_video (struct neofb_info *info)
+{
+  DBG("neo_unmap_video");
+
+  if (info->video.vbase)
+    {
+#ifdef CONFIG_MTRR
+      mtrr_del (info->video.mtrr, info->video.pbase, info->video.len);
+#endif
+
+      iounmap (info->video.vbase);
+      info->video.vbase = NULL;
+      info->fb.screen_base = NULL;
+
+      release_mem_region (info->video.pbase, info->video.len);
+    }
+}
+
+static int __devinit neo_init_hw (struct neofb_info *info)
+{
+  int videoRam = 896;
+  int maxClock = 65000;
+  int CursorMem = 1024;
+  int CursorOff = 0x100;
+  int linearSize = 1024;
+  int maxWidth = 1024;
+  int maxHeight = 1024;
+  unsigned char type, display;
+  int w;
+    
+  DBG("neo_init_hw");
+
+  neoUnlock();
+
+#if 0
+  printk (KERN_DEBUG "--- Neo extended register dump ---\n");
+  for (w=0; w<0x85; w++)
+    printk (KERN_DEBUG "CR %p: %p\n", (void*)w, (void*)VGArCR (w));
+  for (w=0; w<0xC7; w++)
+    printk (KERN_DEBUG "GR %p: %p\n", (void*)w, (void*)VGArGR (w));
+#endif
+
+  /* Determine the panel type */
+  VGAwGR(0x09,0x26);
+  type = VGArGR(0x21);
+  display = VGArGR(0x20);
+    
+  /* Determine panel width -- used in NeoValidMode. */
+  w = VGArGR(0x20);
+  VGAwGR(0x09,0x00);
+  switch ((w & 0x18) >> 3)
+    {
+    case 0x00:
+      info->NeoPanelWidth  = 640;
+      info->NeoPanelHeight = 480;
+      neofb_var = &neofb_var640x480x8;
+      break;
+    case 0x01:
+      info->NeoPanelWidth  = 800;
+      info->NeoPanelHeight = 600;
+      neofb_var = &neofb_var800x600x8;
+      break;
+    case 0x02:
+      info->NeoPanelWidth  = 1024;
+      info->NeoPanelHeight = 768;
+      neofb_var = &neofb_var1024x768x8;
+      break;
+    case 0x03:
+      /* 1280x1024 panel support needs to be added */
+#ifdef NOT_DONE
+      info->NeoPanelWidth  = 1280;
+      info->NeoPanelHeight = 1024;
+      neofb_var = &neofb_var1280x1024x8;
+      break;
+#else
+      printk (KERN_ERR "neofb: Only 640x480, 800x600 and 1024x768 panels are currently supported\n");
+      return -1;
+#endif
+    default:
+      info->NeoPanelWidth  = 640;
+      info->NeoPanelHeight = 480;
+      neofb_var = &neofb_var640x480x8;
+      break;
+    }
+
+  printk (KERN_INFO "Panel is a %dx%d %s %s display\n",
+	  info->NeoPanelWidth,
+	  info->NeoPanelHeight,
+	  (type & 0x02) ? "color" : "monochrome",
+	  (type & 0x10) ? "TFT" : "dual scan");
+
+  switch (info->accel)
+    {
+    case FB_ACCEL_NEOMAGIC_NM2070:
+      videoRam   = 896;
+      maxClock   = 65000;
+      CursorMem  = 2048;
+      CursorOff  = 0x100;
+      linearSize = 1024;
+      maxWidth   = 1024;
+      maxHeight  = 1024;
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2090:
+    case FB_ACCEL_NEOMAGIC_NM2093:
+      videoRam   = 1152;
+      maxClock   = 80000;
+      CursorMem  = 2048;
+      CursorOff  = 0x100;
+      linearSize = 2048;
+      maxWidth   = 1024;
+      maxHeight  = 1024;
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2097:
+      videoRam   = 1152;
+      maxClock   = 80000;
+      CursorMem  = 1024;
+      CursorOff  = 0x100;
+      linearSize = 2048;
+      maxWidth   = 1024;
+      maxHeight  = 1024;
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2160:
+      videoRam   = 2048;
+      maxClock   = 90000;
+      CursorMem  = 1024;
+      CursorOff  = 0x100;
+      linearSize = 2048;
+      maxWidth   = 1024;
+      maxHeight  = 1024;
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2200:
+      videoRam   = 2560;
+      maxClock   = 110000;
+      CursorMem  = 1024;
+      CursorOff  = 0x1000;
+      linearSize = 4096;
+      maxWidth   = 1280;
+      maxHeight  = 1024;  /* ???? */
+
+      info->neo2200 = (Neo2200*) info->mmio.vbase;
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2230:
+      videoRam   = 3008;
+      maxClock   = 110000;
+      CursorMem  = 1024;
+      CursorOff  = 0x1000;
+      linearSize = 4096;
+      maxWidth   = 1280;
+      maxHeight  = 1024;  /* ???? */
+
+      info->neo2200 = (Neo2200*) info->mmio.vbase;
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2360:
+      videoRam   = 4096;
+      maxClock   = 110000;
+      CursorMem  = 1024;
+      CursorOff  = 0x1000;
+      linearSize = 4096;
+      maxWidth   = 1280;
+      maxHeight  = 1024;  /* ???? */
+
+      info->neo2200 = (Neo2200*) info->mmio.vbase;
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2380:
+      videoRam   = 6144;
+      maxClock   = 110000;
+      CursorMem  = 1024;
+      CursorOff  = 0x1000;
+      linearSize = 8192;
+      maxWidth   = 1280;
+      maxHeight  = 1024;  /* ???? */
+
+      info->neo2200 = (Neo2200*) info->mmio.vbase;
+      break;
+    }
+
+  info->maxClock = maxClock;
+
+  return videoRam * 1024;
+}
+
+
+static struct neofb_info * __devinit neo_alloc_fb_info (struct pci_dev *dev,
+							const struct pci_device_id *id)
+{
+  struct neofb_info *info;
+
+  info = kmalloc (sizeof(struct neofb_info) + sizeof(struct display) +
+		  sizeof(u32) * 16, GFP_KERNEL);
+
+  if (!info)
+    return NULL;
+
+  memset (info, 0, sizeof(struct neofb_info) + sizeof(struct display));
+
+  info->currcon = -1;
+  info->pcidev  = dev;
+  info->accel   = id->driver_data;
+
+  info->pci_burst   = !nopciburst;
+  info->lcd_stretch = !nostretch;
+
+  if (!internal && !external)
+    {
+      info->internal_display = 1;
+      info->external_display = 0;
+    }
+  else
+    {
+      info->internal_display = internal;
+      info->external_display = external;
+    }
+
+  switch (info->accel)
+    {
+    case FB_ACCEL_NEOMAGIC_NM2070:
+      sprintf (info->fb.fix.id, "MagicGraph 128");
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2090:
+      sprintf (info->fb.fix.id, "MagicGraph 128V");
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2093:
+      sprintf (info->fb.fix.id, "MagicGraph 128ZV");
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2097:
+      sprintf (info->fb.fix.id, "MagicGraph 128ZV+");
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2160:
+      sprintf (info->fb.fix.id, "MagicGraph 128XD");
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2200:
+      sprintf (info->fb.fix.id, "MagicGraph 256AV");
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2230:
+      sprintf (info->fb.fix.id, "MagicGraph 256AV+");
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2360:
+      sprintf (info->fb.fix.id, "MagicGraph 256ZX");
+      break;
+    case FB_ACCEL_NEOMAGIC_NM2380:
+      sprintf (info->fb.fix.id, "MagicGraph 256XL+");
+      break;
+    }
+
+  info->fb.fix.type	   = FB_TYPE_PACKED_PIXELS;
+  info->fb.fix.type_aux	   = 0;
+  info->fb.fix.xpanstep	   = 0;
+  info->fb.fix.ypanstep	   = 4;
+  info->fb.fix.ywrapstep   = 0;
+  info->fb.fix.accel       = id->driver_data;
+
+  info->fb.var.nonstd      = 0;
+  info->fb.var.activate    = FB_ACTIVATE_NOW;
+  info->fb.var.height      = -1;
+  info->fb.var.width       = -1;
+  info->fb.var.accel_flags = 0;
+
+  strcpy (info->fb.modename, info->fb.fix.id);
+
+  info->fb.fbops          = &neofb_ops;
+  info->fb.changevar      = NULL;
+  info->fb.switch_con     = neofb_switch;
+  info->fb.updatevar      = neofb_updatevar;
+  info->fb.blank          = neofb_blank;
+  info->fb.flags          = FBINFO_FLAG_DEFAULT;
+  info->fb.disp           = (struct display *)(info + 1);
+  info->fb.pseudo_palette = (void *)(info->fb.disp + 1);
+
+  fb_alloc_cmap (&info->fb.cmap, NR_PALETTE, 0);
+
+  return info;
+}
+
+static void __devinit neo_free_fb_info (struct neofb_info *info)
+{
+  if (info)
+    {
+      /*
+       * Free the colourmap
+       */
+      fb_alloc_cmap (&info->fb.cmap, 0, 0);
+
+      kfree (info);
+    }
+}
+
+/* --------------------------------------------------------------------- */
+
+static int __devinit neofb_probe (struct pci_dev* dev, const struct pci_device_id* id)
+{
+  struct neofb_info *info;
+  u_int h_sync, v_sync;
+  int err;
+  int video_len;
+
+  DBG("neofb_probe");
+
+  err = pci_enable_device (dev);
+  if (err)
+    return err;
+
+  err = -ENOMEM;
+  info = neo_alloc_fb_info (dev, id);
+  if (!info)
+    goto failed;
+
+  err = neo_map_mmio (info);
+  if (err)
+    goto failed;
+
+  video_len = neo_init_hw (info);
+  if (video_len < 0)
+    {
+      err = video_len;
+      goto failed;
+    }
+
+  err = neo_map_video (info, video_len);
+  if (err)
+    goto failed;
+
+  neofb_set_var (neofb_var, -1, &info->fb);
+
+  /*
+   * Calculate the hsync and vsync frequencies.  Note that
+   * we split the 1e12 constant up so that we can preserve
+   * the precision and fit the results into 32-bit registers.
+   *  (1953125000 * 512 = 1e12)
+   */
+  h_sync = 1953125000 / info->fb.var.pixclock;
+  h_sync = h_sync * 512 / (info->fb.var.xres + info->fb.var.left_margin +
+			   info->fb.var.right_margin + info->fb.var.hsync_len);
+  v_sync = h_sync / (info->fb.var.yres + info->fb.var.upper_margin +
+		     info->fb.var.lower_margin + info->fb.var.vsync_len);
+
+  printk(KERN_INFO "neofb v" NEOFB_VERSION ": %dkB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
+	 info->fb.fix.smem_len >> 10,
+	 info->fb.var.xres, info->fb.var.yres,
+	 h_sync / 1000, h_sync % 1000, v_sync);
+
+
+  err = register_framebuffer (&info->fb);
+  if (err < 0)
+    goto failed;
+
+  printk (KERN_INFO "fb%d: %s frame buffer device\n",
+	  GET_FB_IDX(info->fb.node), info->fb.modename);
+
+  /*
+   * Our driver data
+   */
+  dev->driver_data = info;
+
+  return 0;
+
+failed:
+  neo_unmap_video (info);
+  neo_unmap_mmio (info);
+  neo_free_fb_info (info);
+
+  return err;
+}
+
+static void __devexit neofb_remove (struct pci_dev *dev)
+{
+  struct neofb_info *info = (struct neofb_info *)dev->driver_data;
+
+  DBG("neofb_remove");
+
+  if (info)
+    {
+      /*
+       * If unregister_framebuffer fails, then
+       * we will be leaving hooks that could cause
+       * oopsen laying around.
+       */
+      if (unregister_framebuffer (&info->fb))
+	printk (KERN_WARNING "neofb: danger danger!  Oopsen imminent!\n");
+
+      neo_unmap_video (info);
+      neo_unmap_mmio (info);
+      neo_free_fb_info (info);
+
+      /*
+       * Ensure that the driver data is no longer
+       * valid.
+       */
+      dev->driver_data = NULL;
+    }
+}
+
+static struct pci_device_id neofb_devices[] __devinitdata = {
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2070,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2070},
+
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2090,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2090},
+
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2093,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2093},
+
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2097,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2097},
+
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2160,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2160},
+
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2200,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2200},
+
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2230,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2230},
+
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2360,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2360},
+
+  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2380,
+   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2380},
+
+  {0, 0, 0, 0, 0, 0, 0}
+};
+
+MODULE_DEVICE_TABLE(pci, neofb_devices);
+
+static struct pci_driver neofb_driver = {
+  name:      "neofb",
+  id_table:  neofb_devices,
+  probe:     neofb_probe,
+  remove:    __devexit_p(neofb_remove)
+};
+
+/* **************************** init-time only **************************** */
+
+static void __init neo_init (void)
+{
+  DBG("neo_init");
+  pci_register_driver (&neofb_driver);
+}
+
+/* **************************** exit-time only **************************** */
+
+static void __exit neo_done (void)
+{
+  DBG("neo_done");
+  pci_unregister_driver (&neofb_driver);
+}
+
+
+#ifndef MODULE
+
+/* ************************* init in-kernel code ************************** */
+
+int __init neofb_setup (char *options)
+{
+  char *this_opt;
+
+  DBG("neofb_setup");
+
+  if (!options || !*options)
+    return 0;
+
+  for (this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,","))
+    {
+      if (!*this_opt) continue;
+
+      if (!strncmp(this_opt, "disabled", 8))
+	disabled = 1;
+      if (!strncmp(this_opt, "internal", 8))
+	internal = 1;
+      if (!strncmp(this_opt, "external", 8))
+	external = 1;
+      if (!strncmp(this_opt, "nostretch", 9))
+	nostretch = 1;
+      if (!strncmp(this_opt, "nopciburst", 10))
+	nopciburst = 1;
+    }
+
+  return 0;
+}
+
+static int __initdata initialized = 0;
+
+int __init neofb_init(void)
+{
+  DBG("neofb_init");
+
+  if (disabled)
+    return -ENXIO;
+
+  if (!initialized)
+    {
+      initialized = 1;
+      neo_init();
+    }
+
+  /* never return failure, user can hotplug card later... */
+  return 0;
+}
+
+#else
+
+/* *************************** init module code **************************** */
+
+int __init init_module(void)
+{
+  DBG("init_module");
+
+  if (disabled)
+    return -ENXIO;
+
+  neo_init();
+
+  /* never return failure; user can hotplug card later... */
+  return 0;
+}
+
+#endif	/* MODULE */
+
+module_exit(neo_done);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/neofb.h linux/drivers/video/neofb.h
--- linux.orig/drivers/video/neofb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/video/neofb.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,294 @@
+/*
+ * linux/drivers/video/neofb.h -- NeoMagic Framebuffer Driver
+ *
+ * Copyright (c) 2001  Denis Oliver Kropp <dok@convergence.de>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+
+#ifdef NEOFB_DEBUG
+# define DBG(x)		printk (KERN_DEBUG "neofb: %s\n", (x));
+#else
+# define DBG(x)
+#endif
+
+
+#define PCI_CHIP_NM2070 0x0001
+#define PCI_CHIP_NM2090 0x0002
+#define PCI_CHIP_NM2093 0x0003
+#define PCI_CHIP_NM2097 0x0083
+#define PCI_CHIP_NM2160 0x0004
+#define PCI_CHIP_NM2200 0x0005
+#define PCI_CHIP_NM2230 0x0025
+#define PCI_CHIP_NM2360 0x0006
+#define PCI_CHIP_NM2380 0x0016
+
+
+struct xtimings {
+  unsigned int pixclock;
+  unsigned int HDisplay;
+  unsigned int HSyncStart;
+  unsigned int HSyncEnd;
+  unsigned int HTotal;
+  unsigned int VDisplay;
+  unsigned int VSyncStart;
+  unsigned int VSyncEnd;
+  unsigned int VTotal;
+  unsigned int sync;
+  int	       dblscan;
+  int	       interlaced;
+};
+
+
+/* --------------------------------------------------------------------- */
+
+typedef volatile struct {
+  __u32 bltStat;
+  __u32 bltCntl;
+  __u32 xpColor;
+  __u32 fgColor;
+  __u32 bgColor;
+  __u32 pitch;
+  __u32 clipLT;
+  __u32 clipRB;
+  __u32 srcBitOffset;
+  __u32 srcStart;
+  __u32 reserved0;
+  __u32 dstStart;
+  __u32 xyExt;
+
+  __u32 reserved1[19];
+
+  __u32 pageCntl;
+  __u32 pageBase;
+  __u32 postBase;
+  __u32 postPtr;
+  __u32 dataPtr;
+} Neo2200;
+
+#define NR_PALETTE	256
+
+#define MMIO_SIZE 0x200000
+
+#define NEO_EXT_CR_MAX 0x85
+#define NEO_EXT_GR_MAX 0xC7
+
+struct neofb_par {
+
+  int depth;
+
+  unsigned char MiscOutReg;     /* Misc */
+  unsigned char CRTC[25];       /* Crtc Controller */
+  unsigned char Sequencer[5];   /* Video Sequencer */
+  unsigned char Graphics[9];    /* Video Graphics */
+  unsigned char Attribute[21];  /* Video Atribute */
+
+  unsigned char GeneralLockReg;
+  unsigned char ExtCRTDispAddr;
+  unsigned char ExtCRTOffset;
+  unsigned char SysIfaceCntl1;
+  unsigned char SysIfaceCntl2;
+  unsigned char ExtColorModeSelect;
+  unsigned char biosMode;
+
+  unsigned char PanelDispCntlReg1;
+  unsigned char PanelDispCntlReg2;
+  unsigned char PanelDispCntlReg3;
+  unsigned char PanelVertCenterReg1;
+  unsigned char PanelVertCenterReg2;
+  unsigned char PanelVertCenterReg3;
+  unsigned char PanelVertCenterReg4;
+  unsigned char PanelVertCenterReg5;
+  unsigned char PanelHorizCenterReg1;
+  unsigned char PanelHorizCenterReg2;
+  unsigned char PanelHorizCenterReg3;
+  unsigned char PanelHorizCenterReg4;
+  unsigned char PanelHorizCenterReg5;
+
+  int           ProgramVCLK;
+  unsigned char VCLK3NumeratorLow;
+  unsigned char VCLK3NumeratorHigh;
+  unsigned char VCLK3Denominator;
+  unsigned char VerticalExt;
+};
+
+struct neofb_info {
+
+  struct fb_info  fb;
+  struct display_switch	*dispsw;
+
+  struct pci_dev *pcidev;
+
+  int   currcon;
+
+  int   accel;
+  char *name;
+
+  struct {
+    u8    *vbase;
+    u32    pbase;
+    u32    len;
+#ifdef CONFIG_MTRR
+    int    mtrr;
+#endif
+  } video;
+
+  struct {
+    u8    *vbase;
+    u32    pbase;
+    u32    len;
+  } mmio;
+
+  Neo2200 *neo2200;
+
+  /* Panels size */
+  int NeoPanelWidth;
+  int NeoPanelHeight;
+
+  int maxClock;
+
+  int pci_burst;
+  int lcd_stretch;
+  int internal_display;
+  int external_display;
+
+  struct {
+    u16 red, green, blue, transp;
+  } palette[NR_PALETTE];
+};
+
+
+typedef struct {
+    int x_res;
+    int y_res;
+    int mode;
+} biosMode;
+
+
+/* vga IO functions */
+static inline u8 VGArCR (u8 index)
+{
+  outb (index, 0x3d4);
+  return inb (0x3d5);
+}
+
+static inline void VGAwCR (u8 index, u8 val)
+{
+  outb (index, 0x3d4);
+  outb (val, 0x3d5);
+}
+
+static inline u8 VGArGR (u8 index)
+{
+  outb (index, 0x3ce);
+  return inb (0x3cf);
+}
+
+static inline void VGAwGR (u8 index, u8 val)
+{
+  outb (index, 0x3ce);
+  outb (val, 0x3cf);
+}
+
+static inline u8 VGArSEQ (u8 index)
+{
+  outb (index, 0x3c4);
+  return inb (0x3c5);
+}
+
+static inline void VGAwSEQ (u8 index, u8 val)
+{
+  outb (index, 0x3c4);
+  outb (val, 0x3c5);
+}
+
+
+static int paletteEnabled = 0;
+
+static inline void VGAenablePalette (void)
+{
+  u8 tmp;
+
+  tmp = inb (0x3da);
+  outb (0x00, 0x3c0);
+  paletteEnabled = 1;
+}
+
+static inline void VGAdisablePalette (void)
+{
+  u8 tmp;
+
+  tmp = inb (0x3da);
+  outb (0x20, 0x3c0);
+  paletteEnabled = 0;
+}
+
+static inline void VGAwATTR (u8 index, u8 value)
+{
+  u8 tmp;
+
+  if (paletteEnabled)
+    index &= ~0x20;
+  else
+    index |= 0x20;
+
+  tmp = inb (0x3da);
+  outb (index, 0x3c0);
+  outb (value, 0x3c0);
+}
+
+static inline void VGAwMISC (u8 value)
+{
+  outb (value, 0x3c2);
+}
+
+
+#define NEO_BS0_BLT_BUSY        0x00000001
+#define NEO_BS0_FIFO_AVAIL      0x00000002
+#define NEO_BS0_FIFO_PEND       0x00000004
+
+#define NEO_BC0_DST_Y_DEC       0x00000001
+#define NEO_BC0_X_DEC           0x00000002
+#define NEO_BC0_SRC_TRANS       0x00000004
+#define NEO_BC0_SRC_IS_FG       0x00000008
+#define NEO_BC0_SRC_Y_DEC       0x00000010
+#define NEO_BC0_FILL_PAT        0x00000020
+#define NEO_BC0_SRC_MONO        0x00000040
+#define NEO_BC0_SYS_TO_VID      0x00000080
+
+#define NEO_BC1_DEPTH8          0x00000100
+#define NEO_BC1_DEPTH16         0x00000200
+#define NEO_BC1_X_320           0x00000400
+#define NEO_BC1_X_640           0x00000800
+#define NEO_BC1_X_800           0x00000c00
+#define NEO_BC1_X_1024          0x00001000
+#define NEO_BC1_X_1152          0x00001400
+#define NEO_BC1_X_1280          0x00001800
+#define NEO_BC1_X_1600          0x00001c00
+#define NEO_BC1_DST_TRANS       0x00002000
+#define NEO_BC1_MSTR_BLT        0x00004000
+#define NEO_BC1_FILTER_Z        0x00008000
+
+#define NEO_BC2_WR_TR_DST       0x00800000
+
+#define NEO_BC3_SRC_XY_ADDR     0x01000000
+#define NEO_BC3_DST_XY_ADDR     0x02000000
+#define NEO_BC3_CLIP_ON         0x04000000
+#define NEO_BC3_FIFO_EN         0x08000000
+#define NEO_BC3_BLT_ON_ADDR     0x10000000
+#define NEO_BC3_SKIP_MAPPING    0x80000000
+
+#define NEO_MODE1_DEPTH8        0x0100
+#define NEO_MODE1_DEPTH16       0x0200
+#define NEO_MODE1_DEPTH24       0x0300
+#define NEO_MODE1_X_320         0x0400
+#define NEO_MODE1_X_640         0x0800
+#define NEO_MODE1_X_800         0x0c00
+#define NEO_MODE1_X_1024        0x1000
+#define NEO_MODE1_X_1152        0x1400
+#define NEO_MODE1_X_1280        0x1800
+#define NEO_MODE1_X_1600        0x1c00
+#define NEO_MODE1_BLT_ON_ADDR   0x2000
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/pm2fb.c linux/drivers/video/pm2fb.c
--- linux.orig/drivers/video/pm2fb.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/drivers/video/pm2fb.c	2002-07-20 01:08:40.000000000 +0000
@@ -129,7 +129,7 @@
 
 static char curblink __initdata = 1;
 
-static const struct {
+static struct {
 	char name[16];
 	struct pm2fb_par par;
 } user_mode[] __initdata = {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/pm3fb.c linux/drivers/video/pm3fb.c
--- linux.orig/drivers/video/pm3fb.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/video/pm3fb.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,3848 @@
+/*
+ *  linux/drivers/video/pm3fb.c -- 3DLabs Permedia3 frame buffer device
+ *  
+ *  Copyright (C) 2001 Romain Dolbeau <dolbeau@irisa.fr>
+ *  Based on code written by:
+ *           Sven Luther, <luther@dpt-info.u-strasbg.fr>
+ *           Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *           Russel King, <rmk@arm.linux.org.uk>
+ *  Based on linux/drivers/video/skeletonfb.c:
+ *	Copyright (C) 1997 Geert Uytterhoeven
+ *  Based on linux/driver/video/pm2fb.c:
+ *      Copyright (C) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
+ *      Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ *
+ *  $Header: /cvsroot/linux/drivers/video/pm3fb.c,v 1.1 2002/02/25 19:11:06 marcelo Exp $
+ *
+ *  CHANGELOG:
+ *  Mon Feb 11 10:35:48 MET 2002, v 1.4.11B: Cosmetic update.
+ *  Wed Jan 23 14:16:59 MET 2002, v 1.4.11: Preliminary 2.5.x support, patch for 2.5.2.
+ *  Wed Nov 28 11:08:29 MET 2001, v 1.4.10: potential bug fix for SDRAM-based board, patch for 2.4.16.
+ *  Thu Sep 20 10:24:42 MET DST 2001, v 1.4.9: sync bug fix, preliminary flatpanel support, better timings.
+ *  Tue Aug 28 10:13:01 MET DST 2001, v 1.4.8: memory timings check, minor bug fixes.
+ *  Wed Jul 18 19:06:14 CEST 2001, v 1.4.7: Mode fix (800x600-100, 1024x768-100 changed), using HW panning + accel bug fix.
+ *  Mon Jun 25 10:33:56 MET DST 2001, v 1.4.6: Depth 12 fix, chip reset ioctl, moved memory erase ioctl to DEBUG.
+ *  Wed Jun 20 11:13:08 MET DST 2001, v 1.4.5: Fixed missing blinking cursor in 8bpp, code cleaning, memory erase IOCTL.
+ *  Mon Jun 18 16:00:27 CEST 2001, v 1.4.4: Depth 12 (RGBA 4444) support, code cleaning.
+ *  Fri Jun 15 13:53:01 CEST 2001, v 1.4.3: Removed warnings, depth 15 support, add 'depth' option.
+ *  Thu Jun 14 10:13:52 MET DST 2001, v 1.4.2: Fixed depth switching bug, preliminary 15bpp (RGB5551) support.
+ *  Thu Apr 12 11:16:45 MET DST 2001, v 1.4.1B: Doc updates.
+ *  Fri Apr  6 11:12:53 MET DST 2001, v 1.4.1: Configure.help, minor cleanup
+ *  Thu Mar 29 10:56:50 MET DST 2001, v 1.4.0: Module & module options support (note: linux patch changed, 2.2.19 added).
+ *  Thu Mar 15 15:30:31 MET 2001, v 1.3.2: Fixed mirroring bug on little-endian.
+ *  Wed Mar 14 21:25:54 CET 2001, v 1.3.1: Fixed bug in BlockMove (_bmov).
+ *  Tue Mar 13 10:53:19 MET 2001, v 1.3.0: Character drawing hardware support (in all width between 1 and 16), fixes.
+ *  Thu Mar  8 10:20:16 MET 2001, v 1.2.2: Better J2000 support, "font:" option.
+ *  Tue Mar  6 21:25:04 CET 2001, v 1.2.1: Better acceleration support.
+ *  Mon Mar  5 21:54:17 CET 2001, v 1.2.0: Partial acceleration support (clear & bmove)
+ *  Mon Mar  5 12:52:15 CET 2001, v 1.1.3: Big pan_display fix.
+ *  Sun Mar  4 22:21:50 CET 2001, v 1.1.2: (numerous) bug fixes.
+ *  Fri Mar  2 15:54:07 CET 2001, v 1.1.1: Might have Appian J2000 support, resource mangement in 2.4
+ *  Wed Feb 28 18:21:35 CET 2001, v 1.1.0: Might have multiple boards support (added, but not yest tested)
+ *  Tue Feb 27 17:31:12 CET 2001, v 1.0.6: fixes boot-time mode select, add more default mode
+ *  Tue Feb 27 14:01:36 CET 2001, v 1.0.5: fixes (1.0.4 was broken for 2.2), cleaning up
+ *  Mon Feb 26 23:17:36 CET 2001, v 1.0.4: preliminary 2.4.x support, dropped (useless on pm3) partial product, more OF fix
+ *  Mon Feb 26 20:59:05 CET 2001, v 1.0.3: No more shadow register (and wasted memory), endianess fix, use OF-preset resolution by default
+ *  Wed Feb 21 22:09:30 CET 2001, v 1.0.2: Code cleaning for future multiboard support, better OF support, bugs fix
+ *  Wed Feb 21 19:58:56 CET 2001, v 1.0.1: OpenFirmware support, fixed memory detection, better debug support, code cleaning
+ *  Wed Feb 21 14:47:06 CET 2001, v 1.0.0: First working version
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_FB_OF
+#include <asm/prom.h>
+#endif
+
+#include "pm3fb.h"
+
+/* ************************************* */
+/* ***** The various "global" data ***** */
+/* ************************************* */
+
+/* those will need a rework for multiple board support */
+/* Driver name */
+static const char permedia3_name[16] = "Permedia3";
+
+/* the fb_par struct, mandatory */
+struct pm3fb_par {
+	u32 pixclock;		/* pixclock in KHz */
+
+	u32 width;		/* width of virtual screen */
+	u32 height;		/* height of virtual screen */
+
+	u32 hsstart;		/* horiz. sync start */
+	u32 hsend;		/* horiz. sync end */
+	u32 hbend;		/* horiz. blank end (also gate end) */
+	u32 htotal;		/* total width (w/ sync & blank) */
+
+	u32 vsstart;		/* vert. sync start */
+	u32 vsend;		/* vert. sync end */
+	u32 vbend;		/* vert. blank end */
+	u32 vtotal;		/* total height (w/ sync & blank) */
+
+	u32 stride;		/* screen stride */
+	u32 base;		/* screen base (xoffset+yoffset) in 128 bits unit */
+	/* NOTE : unlike other pm3 stuff above, stored *after* shiftbpp. don't ask */
+	u32 depth;		/* screen depth (8, 12, 15, 16 or 32) */
+	u32 video;		/* video control (hsync,vsync) */
+};
+
+/* memory timings */
+struct pm3fb_timings
+{
+	unsigned long caps;
+	unsigned long timings;
+	unsigned long control;
+	unsigned long refresh;
+	unsigned long powerdown;
+};
+typedef enum pm3fb_timing_result { pm3fb_timing_ok, pm3fb_timing_problem, pm3fb_timing_retry } pm3fb_timing_result;
+#define PM3FB_UNKNOWN_TIMING_VALUE ((unsigned long)-1)
+#define PM3FB_UNKNOWN_TIMINGS { PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE }
+
+/* the fb_info struct, mandatory */
+struct pm3fb_info {
+	struct fb_info_gen gen;
+	unsigned long board_num; /* internal board number */
+	unsigned long use_current;
+	struct pm3fb_par *current_par;
+	struct pci_dev *dev;    /* PCI device */
+#ifdef SUPPORT_FB_OF
+	struct device_node *dn; /* OF node for the PCI device */
+#endif /* SUPPORT_FB_OF */
+	unsigned long board_type; /* index in the cardbase */
+	unsigned char *fb_base;	/* framebuffer memory base */
+	u32 fb_size;		/* framebuffer memory size */
+	unsigned char *p_fb;	/* physical address of frame buffer */
+	unsigned char *v_fb;	/* virtual address of frame buffer */
+	unsigned char *pIOBase;	/* physical address of registers region, must be rg_base or rg_base+PM2_REGS_SIZE depending on the host endianness */
+	unsigned char *vIOBase;	/* address of registers after ioremap() */
+	struct {
+		u8 transp;
+		u8 red;
+		u8 green;
+		u8 blue;
+	} palette[256];
+	union {
+#ifdef FBCON_HAS_CFB16
+		u16 cmap12[16]; /* RGBA 4444 */
+		u16 cmap15[16]; /* RGBA 5551 */
+		u16 cmap16[16]; /* RGBA 5650 */
+#endif
+#ifdef FBCON_HAS_CFB32
+		u32 cmap32[16];
+#endif
+	} cmap;
+	struct pm3fb_timings memt;
+};
+
+/* regular resolution database*/
+static struct {
+	char name[16];
+	struct pm3fb_par user_mode;
+} mode_base[] __initdata = {
+	{
+		"default-800x600", {
+	49500, 800, 600, 16, 96, 256, 1056, 1, 4, 25, 625,
+			    800, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}}, {
+		"1024x768-74", {
+	78752, 1024, 768, 32, 128, 304, 1328, 1, 4, 38,
+			    806, 1024, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}}, {
+		"1024x768-74-32", {
+			78752, 1024, 768, 32, 128, 304, 1328, 1, 4, 38,
+			806, 1024, 0, 32,
+			PM3VideoControl_ENABLE |
+			PM3VideoControl_HSYNC_ACTIVE_HIGH
+			|
+			PM3VideoControl_VSYNC_ACTIVE_HIGH
+			| PM3VideoControl_PIXELSIZE_32BIT}},
+/* Generated mode : "1600x1024", for the SGI 1600SW flat panel*/
+	{
+		"SGI1600SW", {
+			108000, 1600, 1024, 16, 56, 104, 1704, 3, 6, 32,
+			1056, 1600, 0, 8,
+			PM3VideoControl_ENABLE|
+			PM3VideoControl_HSYNC_ACTIVE_LOW|PM3VideoControl_VSYNC_ACTIVE_LOW|
+			PM3VideoControl_PIXELSIZE_32BIT}}, 
+/* ##### auto-generated mode, by fbtimings2pm3 */
+/* Generated mode : "640x480-60" */
+	{
+		"640x480-60", {
+	25174, 640, 480, 16, 112, 160, 800, 10, 12, 45,
+			    525, 640, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "640x480-72" */
+	{
+		"640x480-72", {
+	31199, 640, 480, 24, 64, 192, 832, 9, 12, 40, 520,
+			    640, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "640x480-75" */
+	{
+		"640x480-75", {
+	31499, 640, 480, 16, 80, 200, 840, 1, 4, 20, 500,
+			    640, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "640x480-90" */
+	{
+		"640x480-90", {
+	39909, 640, 480, 32, 72, 192, 832, 25, 39, 53, 533,
+			    640, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "640x480-100" */
+	{
+		"640x480-100", {
+	44899, 640, 480, 32, 160, 208, 848, 22, 34, 51,
+			    531, 640, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "800x600-48-lace" */
+/* INTERLACED NOT SUPPORTED
+  {"800x600-48-lace", {35999, 800, 600, 80, 208, 264, 1064, 11, 23, 102, 702, 800, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}}, 
+   INTERLACED NOT SUPPORTED */
+/* Generated mode : "800x600-56" */
+	{
+		"800x600-56", {
+	35999, 800, 600, 24, 96, 224, 1024, 1, 3, 25, 625,
+			    800, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "800x600-60" */
+	{
+		"800x600-60", {
+	40000, 800, 600, 40, 168, 256, 1056, 1, 5, 28, 628,
+			    800, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "800x600-70" */
+	{
+		"800x600-70", {
+	44899, 800, 600, 24, 168, 208, 1008, 9, 21, 36,
+			    636, 800, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "800x600-72" */
+	{
+		"800x600-72", {
+	50000, 800, 600, 56, 176, 240, 1040, 37, 43, 66,
+			    666, 800, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "800x600-75" */
+	{
+		"800x600-75", {
+	49497, 800, 600, 16, 96, 256, 1056, 1, 4, 25, 625,
+			    800, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "800x600-90" */
+	{
+		"800x600-90", {
+	56637, 800, 600, 8, 72, 192, 992, 8, 19, 35, 635,
+			    800, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "800x600-100", from /etc/fb.modes */
+/* DISABLED, hsstart == 0
+	{
+		"800x600-100", {
+	67499, 800, 600, 0, 64, 280, 1080, 7, 11, 25, 625,
+			    800, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+*/
+/* Generated mode : "800x600-100", from ??? */
+	{
+		"800x600-100", {
+			69650, 800, 600, 64, 128, 288, 1088, 4, 10, 40, 640, 800, 0, 8,
+			PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_LOW|
+			PM3VideoControl_VSYNC_ACTIVE_LOW|PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1024x768-43-lace" */
+/* INTERLACED NOT SUPPORTED
+  {"1024x768-43-lace", {44899, 1024, 768, 8, 184, 240, 1264, 1, 9, 49, 817, 1024, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}}, 
+   INTERLACED NOT SUPPORTED */
+/* Generated mode : "1024x768-60" */
+	{
+		"1024x768-60", {
+	64998, 1024, 768, 24, 160, 320, 1344, 3, 9, 38,
+			    806, 1024, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1024x768-70" */
+	{
+		"1024x768-70", {
+	74996, 1024, 768, 24, 160, 304, 1328, 3, 9, 38,
+			    806, 1024, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1024x768-72" */
+	{
+		"1024x768-72", {
+	74996, 10224, 768, 24, 160, 264, 10488, 3, 9, 38,
+			    806, 10224, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1024x768-75" */
+	{
+		"1024x768-75", {
+	78746, 1024, 768, 16, 112, 288, 1312, 1, 4, 32,
+			    800, 1024, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1024x768-90" */
+	{
+		"1024x768-90", {
+	100000, 1024, 768, 0, 96, 288, 1312, 21, 36, 77,
+			    845, 1024, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1024x768-100", from /etc/fb.modes */
+/* DISABLED, vsstart == 0
+	{
+		"1024x768-100", {
+	109998, 1024, 768, 0, 88, 368, 1392, 0, 8, 24, 792,
+			    1024, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+*/
+/* Generated mode : "1024x768-100", from ??? */
+	{
+		"1024x768-100", {
+			115500, 1024, 768, 32, 224, 416, 1440, 3, 13, 34, 802, 1024, 0, 8,
+			PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_LOW|
+			PM3VideoControl_VSYNC_ACTIVE_LOW|PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1152x864-43-lace" */
+/* INTERLACED NOT SUPPORTED
+  {"1152x864-43-lace", {64998, 1152, 864, 72, 200, 264, 1416, 78, 87, 191, 1055, 1152, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}}, 
+   INTERLACED NOT SUPPORTED */
+/* Generated mode : "1152x864-47-lace" */
+/* INTERLACED NOT SUPPORTED
+  {"1152x864-47-lace", {64998, 1152, 864, 88, 216, 296, 1448, 30, 39, 83, 947, 1152, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}}, 
+   INTERLACED NOT SUPPORTED */
+/* Generated mode : "1152x864-60" */
+	{
+		"1152x864-60", {
+	80000, 1152, 864, 64, 176, 304, 1456, 6, 11, 52,
+			    916, 1152, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1152x864-70" */
+	{
+		"1152x864-70", {
+	100000, 1152, 864, 40, 192, 360, 1512, 13, 24, 81,
+			    945, 1152, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1152x864-75" */
+	{
+		"1152x864-75", {
+	109998, 1152, 864, 24, 168, 312, 1464, 45, 53, 138,
+			    1002, 1152, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1152x864-80" */
+	{
+		"1152x864-80", {
+	109998, 1152, 864, 16, 128, 288, 1440, 30, 37, 94,
+			    958, 1152, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1280x1024-43-lace" */
+/* INTERLACED NOT SUPPORTED
+  {"1280x1024-43-lace", {80000, 1024, 1024, 80, 160, 320, 1344, 50, 60, 125, 1149, 1024, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}}, 
+   INTERLACED NOT SUPPORTED */
+/* Generated mode : "1280x1024-47-lace" */
+/* INTERLACED NOT SUPPORTED
+  {"1280x1024-47-lace", {80000, 1280, 1024, 80, 160, 320, 1600, 1, 11, 29, 1053, 1280, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}}, 
+   INTERLACED NOT SUPPORTED */
+/* Generated mode : "1280x1024-60" */
+	{
+		"1280x1024-60", {
+	107991, 1280, 1024, 48, 160, 408, 1688, 1, 4, 42,
+			    1066, 1280, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1280x1024-70" */
+	{
+		"1280x1024-70", {
+	125992, 1280, 1024, 80, 192, 408, 1688, 1, 6, 42,
+			    1066, 1280, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1280x1024-74" */
+	{
+		"1280x1024-74", {
+	134989, 1280, 1024, 32, 176, 432, 1712, 0, 30, 40,
+			    1064, 1280, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1280x1024-75" */
+	{
+		"1280x1024-75", {
+	134989, 1280, 1024, 16, 160, 408, 1688, 1, 4, 42,
+			    1066, 1280, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_HIGH
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_HIGH
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1600x1200-60" */
+	{
+		"1600x1200-60", {
+	155981, 1600, 1200, 32, 192, 448, 2048, 10, 18, 70,
+			    1270, 1600, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1600x1200-66" */
+	{
+		"1600x1200-66", {
+	171998, 1600, 1200, 40, 176, 480, 2080, 3, 6, 53,
+			    1253, 1600, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* Generated mode : "1600x1200-76" */
+	{
+		"1600x1200-76", {
+	197980, 1600, 1200, 40, 176, 480, 2080, 3, 8, 50,
+			    1250, 1600, 0, 8,
+			    PM3VideoControl_ENABLE |
+			    PM3VideoControl_HSYNC_ACTIVE_LOW
+			    |
+			    PM3VideoControl_VSYNC_ACTIVE_LOW
+			    | PM3VideoControl_PIXELSIZE_8BIT}},
+/* ##### end of auto-generated mode */
+	{
+	"\0",}
+};
+
+/* more mandatory stuff (see skeletonfb.c + framebuffer driver HOWTO */
+static struct pm3fb_info fb_info[PM3_MAX_BOARD];
+static struct pm3fb_par current_par[PM3_MAX_BOARD];
+static int current_par_valid[PM3_MAX_BOARD];
+/* to allow explicit filtering of board */
+short bus[PM3_MAX_BOARD];
+short slot[PM3_MAX_BOARD];
+short func[PM3_MAX_BOARD];
+short disable[PM3_MAX_BOARD];
+short noaccel[PM3_MAX_BOARD];
+char fontn[PM3_MAX_BOARD][PM3_FONTNAME_SIZE];
+short depth[PM3_MAX_BOARD];
+short flatpanel[PM3_MAX_BOARD];
+static struct display disp[PM3_MAX_BOARD];
+static char g_options[PM3_OPTIONS_SIZE] __initdata = "pm3fb,dummy";
+short printtimings = 0;
+short forcesize[PM3_MAX_BOARD];
+
+/* ********************* */
+/* ***** prototype ***** */
+/* ********************* */
+/* card-specific */
+static void pm3fb_j2000_setup(struct pm3fb_info *l_fb_info);
+/* permedia3-specific */
+static pm3fb_timing_result pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info);
+static pm3fb_timing_result pm3fb_try_memory_timings(struct pm3fb_info *l_fb_info);
+static void pm3fb_write_memory_timings(struct pm3fb_info *l_fb_info);
+static unsigned long pm3fb_read_dac_reg(struct pm3fb_info *l_fb_info,
+					unsigned long r);
+static unsigned long pm3fb_CalculateClock(struct pm3fb_info *l_fb_info, unsigned long reqclock,	/* In kHz units */
+					  unsigned long refclock,	/* In kHz units */
+					  unsigned char *prescale,	/* ClkPreScale */
+					  unsigned char *feedback,	/* ClkFeedBackScale */
+					  unsigned char *postscale
+					  /* ClkPostScale */ );
+static void pm3fb_clear_memory(struct pm3fb_info *l_fb_info, u32 cc);
+static void pm3fb_clear_colormap(struct pm3fb_info *l_fb_info, unsigned char r, unsigned char g, unsigned char b);
+static void pm3fb_common_init(struct pm3fb_info *l_fb_info);
+static int pm3fb_Shiftbpp(struct pm3fb_info *l_fb_info,
+			  unsigned long depth, int v);
+static int pm3fb_Unshiftbpp(struct pm3fb_info *l_fb_info,
+			    unsigned long depth, int v);
+static void pm3fb_mapIO(struct pm3fb_info *l_fb_info);
+static void pm3fb_unmapIO(struct pm3fb_info *l_fb_info);
+#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)
+static void pm3fb_show_cur_mode(struct pm3fb_info *l_fb_info);
+#endif
+static void pm3fb_show_cur_timing(struct pm3fb_info *l_fb_info);
+static void pm3fb_write_mode(struct pm3fb_info *l_fb_info);
+static void pm3fb_read_mode(struct pm3fb_info *l_fb_info,
+			    struct pm3fb_par *curpar);
+static unsigned long pm3fb_size_memory(struct pm3fb_info *l_fb_info);
+/* accelerated permedia3-specific */
+#ifdef PM3FB_USE_ACCEL
+static void pm3fb_wait_pm3(struct pm3fb_info *l_fb_info);
+static void pm3fb_init_engine(struct pm3fb_info *l_fb_info);
+#ifdef FBCON_HAS_CFB32
+static void pm3fb_cfb32_clear(struct vc_data *conp,
+			      struct display *p,
+			      int sy, int sx, int height, int width);
+static void pm3fb_cfb32_clear_margins(struct vc_data *conp,
+				      struct display *p, int bottom_only);
+#endif /* FBCON_HAS_CFB32 */
+#ifdef FBCON_HAS_CFB16
+static void pm3fb_cfb16_clear(struct vc_data *conp,
+			      struct display *p,
+			      int sy, int sx, int height, int width);
+static void pm3fb_cfb16_clear_margins(struct vc_data *conp,
+				      struct display *p, int bottom_only);
+#endif /* FBCON_HAS_CFB16 */
+#ifdef FBCON_HAS_CFB8
+static void pm3fb_cfb8_clear(struct vc_data *conp,
+			     struct display *p,
+			     int sy, int sx, int height, int width);
+static void pm3fb_cfb8_clear_margins(struct vc_data *conp,
+				     struct display *p, int bottom_only);
+#endif /* FBCON_HAS_CFB8 */
+#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
+static void pm3fb_cfbX_bmove(struct display *p,
+			     int sy, int sx,
+			     int dy, int dx, int height, int width);
+static void pm3fb_cfbX_putc(struct vc_data *conp, struct display *p,
+			    int c, int yy, int xx);
+static void pm3fb_cfbX_putcs(struct vc_data *conp, struct display *p,
+			     const unsigned short *s, int count, int yy,
+			     int xx);
+static void pm3fb_cfbX_revc(struct display *p, int xx, int yy);
+#endif /* FBCON_HAS_CFB8 || FBCON_HAS_CFB16 || FBCON_HAS_CFB32 */
+#endif /* PM3FB_USE_ACCEL */
+/* pre-init */
+static void pm3fb_mode_setup(char *mode, unsigned long board_num);
+static void pm3fb_pciid_setup(char *pciid, unsigned long board_num);
+static char *pm3fb_boardnum_setup(char *options, unsigned long *bn);
+static void pm3fb_real_setup(char *options);
+/* fbdev */
+static int pm3fb_open(struct fb_info *info, int user);
+static int pm3fb_release(struct fb_info *info, int user);
+static int pm3fb_encode_fix(struct fb_fix_screeninfo *fix,
+			    const void *par, struct fb_info_gen *info);
+static int pm3fb_decode_var(const struct fb_var_screeninfo *var,
+			    void *par, struct fb_info_gen *info);
+static void pm3fb_encode_depth(struct fb_var_screeninfo *var, long d);
+static int pm3fb_encode_var(struct fb_var_screeninfo *var,
+			    const void *par, struct fb_info_gen *info);
+static void pm3fb_get_par(void *par, struct fb_info_gen *info);
+static void pm3fb_set_par(const void *par, struct fb_info_gen *info);
+static void pm3fb_set_color(struct pm3fb_info *l_fb_info,
+			    unsigned char regno, unsigned char r,
+			    unsigned char g, unsigned char b);
+static int pm3fb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			   unsigned *blue, unsigned *transp,
+			   struct fb_info *info);
+static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info);
+static int pm3fb_blank(int blank_mode, struct fb_info_gen *info);
+static void pm3fb_set_disp(const void *par, struct display *disp,
+			   struct fb_info_gen *info);
+static void pm3fb_detect(void);
+static int pm3fb_pan_display(const struct fb_var_screeninfo *var,
+			     struct fb_info_gen *info);
+static int pm3fb_ioctl(struct inode *inode, struct file *file,
+                       u_int cmd, u_long arg, int con,
+		       struct fb_info *info);
+
+
+/* the struct that hold them together */
+#ifdef KERNEL_2_2
+struct fbgen_hwswitch pm3fb_switch = {
+	pm3fb_detect, pm3fb_encode_fix, pm3fb_decode_var, pm3fb_encode_var,
+	pm3fb_get_par, pm3fb_set_par, pm3fb_getcolreg, pm3fb_setcolreg,
+	pm3fb_pan_display, pm3fb_blank, pm3fb_set_disp
+};
+
+static struct fb_ops pm3fb_ops = {
+	pm3fb_open, pm3fb_release,
+	fbgen_get_fix, fbgen_get_var, fbgen_set_var,
+	fbgen_get_cmap, fbgen_set_cmap, fbgen_pan_display, pm3fb_ioctl,
+	    NULL, NULL
+};
+#endif /* KERNEL_2_2 */
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+struct fbgen_hwswitch pm3fb_switch = {
+	pm3fb_detect, pm3fb_encode_fix, pm3fb_decode_var, pm3fb_encode_var,
+	pm3fb_get_par, pm3fb_set_par, pm3fb_getcolreg, pm3fb_setcolreg,
+	pm3fb_pan_display, pm3fb_blank, pm3fb_set_disp
+};
+
+static struct fb_ops pm3fb_ops = {
+	THIS_MODULE,
+	pm3fb_open, pm3fb_release,
+	fbgen_get_fix, fbgen_get_var, fbgen_set_var,
+	fbgen_get_cmap, fbgen_set_cmap, fbgen_pan_display, pm3fb_ioctl, NULL, NULL
+};
+#endif /* KERNEL_2_4 or KERNEL_2_5 */
+#ifdef PM3FB_USE_ACCEL
+#ifdef FBCON_HAS_CFB32
+static struct display_switch pm3fb_cfb32 = {
+	fbcon_cfb32_setup, pm3fb_cfbX_bmove, pm3fb_cfb32_clear,
+	pm3fb_cfbX_putc, pm3fb_cfbX_putcs, pm3fb_cfbX_revc,
+	NULL /* cursor() */ , NULL /* set_font() */ ,
+	pm3fb_cfb32_clear_margins,
+	FONTWIDTHRANGE(1, 16)	/* true only if accelerated... */
+};
+#endif /* FBCON_HAS_CFB32 */
+#ifdef FBCON_HAS_CFB16
+static struct display_switch pm3fb_cfb16 = {
+	fbcon_cfb16_setup, pm3fb_cfbX_bmove, pm3fb_cfb16_clear,
+	pm3fb_cfbX_putc, pm3fb_cfbX_putcs, pm3fb_cfbX_revc,
+	NULL /* cursor() */ , NULL /* set_font() */ ,
+	pm3fb_cfb16_clear_margins,
+	FONTWIDTHRANGE(1, 16)	/* true only if accelerated... */
+};
+#endif /* FBCON_HAS_CFB16 */
+#ifdef FBCON_HAS_CFB8
+static struct display_switch pm3fb_cfb8 = {
+	fbcon_cfb8_setup, pm3fb_cfbX_bmove, pm3fb_cfb8_clear,
+	pm3fb_cfbX_putc, pm3fb_cfbX_putcs, pm3fb_cfbX_revc,
+	NULL /* cursor() */ , NULL /* set_font() */ ,
+	pm3fb_cfb8_clear_margins,
+	FONTWIDTHRANGE(1, 16)	/* true only if accelerated... */
+};
+#endif /* FBCON_HAS_CFB8 */
+#endif /* PM3FB_USE_ACCEL */
+
+/* ****************************** */
+/* ***** card-specific data ***** */
+/* ****************************** */
+struct pm3fb_card_timings {
+	unsigned long memsize; /* 0 for last value (i.e. default) */
+	struct pm3fb_timings memt;
+};
+
+static struct pm3fb_card_timings t_FormacProFormance3[] = {
+	{ 16, { 0x02e311b8, 0x06100205, 0x08000002, 0x00000079, 0x00000000} },
+	{ 0, { 0x02e311b8, 0x06100205, 0x08000002, 0x00000079, 0x00000000} } /* from 16 MB PF3 */
+};
+
+static struct pm3fb_card_timings t_AppianJeronimo2000[] = {
+	{ 32, { 0x02e311B8, 0x07424905, 0x0c000003, 0x00000061, 0x00000000} },
+	{ 0, { 0x02e311B8, 0x07424905, 0x0c000003, 0x00000061, 0x00000000} } /* from 32MB J2000 */
+};
+
+static struct pm3fb_card_timings t_3DLabsOxygenVX1[] = {
+	{ 32, { 0x30e311b8, 0x08501204, 0x08000002, 0x0000006b, 0x00000000} },
+	{ 0, { 0x30e311b8, 0x08501204, 0x08000002, 0x0000006b, 0x00000000} } /* from 32MB VX1 */
+};
+
+static struct {
+		char cardname[32]; /* recognized card name */
+		u16 subvendor; /* subvendor of the card */
+		u16 subdevice; /* subdevice of the card */
+		u8  func; /* function of the card to which the extra init apply */
+		void (*specific_setup)(struct pm3fb_info *l_fb_info); /* card/func specific setup, done before _any_ FB access */
+	struct pm3fb_card_timings *c_memt; /* defauls timings for the boards */
+} cardbase[] = {
+	{ "Unknown Permedia3 board", 0xFFFF, 0xFFFF, 0xFF, NULL, NULL },
+	{ "Appian Jeronimo 2000 head 1", 0x1097, 0x3d32, 1, NULL,
+	  t_AppianJeronimo2000
+	},
+	{ "Appian Jeronimo 2000 head 2", 0x1097, 0x3d32, 2, pm3fb_j2000_setup,
+	  t_AppianJeronimo2000
+	},
+	{ "Formac ProFormance 3", PCI_VENDOR_ID_3DLABS, 0x000a, 0, NULL, /* Formac use 3DLabs ID ?!? */
+	  t_FormacProFormance3
+	},
+	{ "3DLabs Permedia3 Create!", PCI_VENDOR_ID_3DLABS, 0x0127, 0, NULL, NULL },
+	{ "3DLabs Oxygen VX1 PCI", PCI_VENDOR_ID_3DLABS, 0x0121, 0, NULL,
+	  t_3DLabsOxygenVX1
+	},
+	{ "3DLabs Oxygen VX1 AGP", PCI_VENDOR_ID_3DLABS, 0x0125, 0, NULL, NULL },
+	{ "3DLabs Oxygen VX1-16 AGP", PCI_VENDOR_ID_3DLABS, 0x0140, 0, NULL, NULL },
+	{ "3DLabs Oxygen VX1-1600SW PCI", PCI_VENDOR_ID_3DLABS, 0x0800, 0, NULL, NULL },
+	{ "\0", 0x0, 0x0, 0, NULL, NULL }
+};
+
+/* ********************************** */
+/* ***** card-specific function ***** */
+/* ********************************** */
+static void pm3fb_j2000_setup(struct pm3fb_info *l_fb_info)
+{       /* the appian j2000 require more initialization of the second head */
+	/* l_fb_info must point to the _second_ head of the J2000 */
+	
+	DTRACE;
+
+	l_fb_info->memt = t_AppianJeronimo2000[0].memt; /* 32 MB, first and only j2000 ? */
+	
+	pm3fb_write_memory_timings(l_fb_info);
+}
+
+/* *************************************** */
+/* ***** permedia3-specific function ***** */
+/* *************************************** */
+static pm3fb_timing_result pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info)
+{
+	l_fb_info->memt.caps = PM3_READ_REG(PM3LocalMemCaps);
+	l_fb_info->memt.timings = PM3_READ_REG(PM3LocalMemTimings);
+	l_fb_info->memt.control = PM3_READ_REG(PM3LocalMemControl);
+	l_fb_info->memt.refresh = PM3_READ_REG(PM3LocalMemRefresh);
+	l_fb_info->memt.powerdown = PM3_READ_REG(PM3LocalMemPowerDown);
+
+	if ((l_fb_info->memt.caps == PM3FB_UNKNOWN_TIMING_VALUE) ||
+	    (l_fb_info->memt.timings == PM3FB_UNKNOWN_TIMING_VALUE) ||
+	    (l_fb_info->memt.control == PM3FB_UNKNOWN_TIMING_VALUE) ||
+	    (l_fb_info->memt.refresh == PM3FB_UNKNOWN_TIMING_VALUE) ||
+	    (l_fb_info->memt.powerdown == PM3FB_UNKNOWN_TIMING_VALUE))
+	{
+		printk(KERN_ERR "pm3fb: invalid memory timings in permedia3 board #%ld\n", l_fb_info->board_num);
+		return(pm3fb_try_memory_timings(l_fb_info));
+	}
+	return(pm3fb_timing_ok);
+}
+
+static pm3fb_timing_result pm3fb_try_memory_timings(struct pm3fb_info *l_fb_info)
+{
+	if (cardbase[l_fb_info->board_type].c_memt)
+	{
+		int i = 0, done = 0;
+		while (!done)
+		{
+			if ((cardbase[l_fb_info->board_type].c_memt[i].memsize == l_fb_info->fb_size)
+			    || !(cardbase[l_fb_info->board_type].c_memt[i].memsize))
+			{ /* will use the 0-sized timings by default */
+				done = 1;
+				l_fb_info->memt = cardbase[l_fb_info->board_type].c_memt[i].memt;
+				printk(KERN_WARNING  "pm3fb: trying to use predefined memory timings for permedia3 board #%ld (%s, %ld MB)\n",
+				       l_fb_info->board_num,
+				       cardbase[l_fb_info->board_type].cardname,
+				       cardbase[l_fb_info->board_type].c_memt[i].memsize);
+				pm3fb_write_memory_timings(l_fb_info);
+				return(pm3fb_timing_retry);
+			}
+			i++;
+		}
+	} else
+		return(pm3fb_timing_problem);
+	return(pm3fb_timing_ok);
+}
+
+static void pm3fb_write_memory_timings(struct pm3fb_info *l_fb_info)
+{
+	unsigned char m, n, p;
+	unsigned long clockused;
+	
+	PM3_SLOW_WRITE_REG(PM3LocalMemCaps, l_fb_info->memt.caps);
+	PM3_SLOW_WRITE_REG(PM3LocalMemTimings, l_fb_info->memt.timings);
+	PM3_SLOW_WRITE_REG(PM3LocalMemControl, l_fb_info->memt.control);
+	PM3_SLOW_WRITE_REG(PM3LocalMemRefresh, l_fb_info->memt.refresh);
+	PM3_SLOW_WRITE_REG(PM3LocalMemPowerDown, l_fb_info->memt.powerdown);
+
+	clockused =
+	    pm3fb_CalculateClock(l_fb_info, 2 * 105000, PM3_REF_CLOCK, &m,
+				 &n, &p);
+
+	PM3_WRITE_DAC_REG(PM3RD_KClkPreScale, m);
+	PM3_WRITE_DAC_REG(PM3RD_KClkFeedbackScale, n);
+	PM3_WRITE_DAC_REG(PM3RD_KClkPostScale, p);
+	PM3_WRITE_DAC_REG(PM3RD_KClkControl,
+			  PM3RD_KClkControl_STATE_RUN |
+			  PM3RD_KClkControl_SOURCE_PLL |
+			  PM3RD_KClkControl_ENABLE);
+	PM3_WRITE_DAC_REG(PM3RD_MClkControl,
+			  PM3RD_MClkControl_STATE_RUN |
+			  PM3RD_MClkControl_SOURCE_KCLK |
+			  PM3RD_MClkControl_ENABLE);
+	PM3_WRITE_DAC_REG(PM3RD_SClkControl,
+			  PM3RD_SClkControl_STATE_RUN |
+			  PM3RD_SClkControl_SOURCE_PCLK |
+			  PM3RD_SClkControl_ENABLE);
+}
+
+static unsigned long pm3fb_read_dac_reg(struct pm3fb_info *l_fb_info,
+					unsigned long r)
+{
+	DASSERT((l_fb_info->vIOBase != (unsigned char *) (-1)),
+		"l_fb_info->vIOBase mapped in read dac reg\n");
+	PM3_SET_INDEX(r);
+	mb();
+	return (PM3_READ_REG(PM3RD_IndexedData));
+}
+
+/* Calculating various clock parameter */
+static unsigned long pm3fb_CalculateClock(struct pm3fb_info *l_fb_info, unsigned long reqclock,	/* In kHz units */
+					  unsigned long refclock,	/* In kHz units */
+					  unsigned char *prescale,	/* ClkPreScale */
+					  unsigned char *feedback,	/* ClkFeedBackScale */
+					  unsigned char *postscale
+					  /* ClkPostScale */ )
+{
+	int f, pre, post;
+	unsigned long freq;
+	long freqerr = 1000;
+	unsigned long actualclock = 0;
+
+	DTRACE;
+
+	for (f = 1; f < 256; f++) {
+		for (pre = 1; pre < 256; pre++) {
+			for (post = 0; post < 5; post++) {
+				freq =
+				    ((2 * refclock * f) /
+				     (pre * (1 << post)));
+				if ((reqclock > freq - freqerr)
+				    && (reqclock < freq + freqerr)) {
+					freqerr =
+					    (reqclock >
+					     freq) ? reqclock -
+					    freq : freq - reqclock;
+					*feedback = f;
+					*prescale = pre;
+					*postscale = post;
+					actualclock = freq;
+				}
+			}
+		}
+	}
+
+	return (actualclock);
+}
+
+static int pm3fb_Shiftbpp(struct pm3fb_info *l_fb_info,
+			  unsigned long depth, int v)
+{
+	DTRACE;
+	
+	switch (depth) {
+	case 8:
+		return (v >> 4);
+	case 12:
+	case 15:
+	case 16:
+		return (v >> 3);
+	case 32:
+		return (v >> 2);
+	}
+	DPRINTK(1, "Unsupported depth %ld\n", depth);
+	return (0);
+}
+
+static int pm3fb_Unshiftbpp(struct pm3fb_info *l_fb_info,
+			    unsigned long depth, int v)
+{
+	DTRACE;
+
+	switch (depth) {
+	case 8:
+		return (v << 4);
+	case 12:	
+	case 15:
+	case 16:
+		return (v << 3);
+	case 32:
+		return (v << 2);
+	}
+	DPRINTK(1, "Unsupported depth %ld\n", depth);
+	return (0);
+}
+
+static void pm3fb_mapIO(struct pm3fb_info *l_fb_info)
+{
+	DTRACE;
+
+	l_fb_info->vIOBase =
+	    ioremap((unsigned long) l_fb_info->pIOBase, PM3_REGS_SIZE);
+	l_fb_info->v_fb =
+	    ioremap((unsigned long) l_fb_info->p_fb, l_fb_info->fb_size);
+	DPRINTK(2, "IO mapping : IOBase %lx / %lx, fb %lx / %lx\n",
+		(unsigned long) l_fb_info->pIOBase,
+		(unsigned long) l_fb_info->vIOBase,
+		(unsigned long) l_fb_info->p_fb,
+		(unsigned long) l_fb_info->v_fb);
+}
+
+static void pm3fb_unmapIO(struct pm3fb_info *l_fb_info)
+{
+	DTRACE;
+
+	iounmap(l_fb_info->vIOBase);
+	iounmap(l_fb_info->v_fb);
+	l_fb_info->vIOBase = (unsigned char *) -1;
+	l_fb_info->v_fb = (unsigned char *) -1;
+}
+
+#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)
+static void pm3fb_show_cur_mode(struct pm3fb_info *l_fb_info)
+{
+	DPRINTK(2, "PM3Aperture0: 0x%08x\n", PM3_READ_REG(PM3Aperture0));
+	DPRINTK(2, "PM3Aperture1: 0x%08x\n", PM3_READ_REG(PM3Aperture1));
+	DPRINTK(2, "PM3ByAperture1Mode: 0x%08x\n",
+		PM3_READ_REG(PM3ByAperture1Mode));
+	DPRINTK(2, "PM3ByAperture2Mode: 0x%08x\n",
+		PM3_READ_REG(PM3ByAperture2Mode));
+	DPRINTK(2, "PM3ChipConfig: 0x%08x\n", PM3_READ_REG(PM3ChipConfig));
+	DPRINTK(2, "PM3FIFODis: 0x%08x\n", PM3_READ_REG(PM3FIFODis));
+	DPRINTK(2, "PM3HTotal: 0x%08x\n", PM3_READ_REG(PM3HTotal));
+	DPRINTK(2, "PM3HbEnd: 0x%08x\n", PM3_READ_REG(PM3HbEnd));
+	DPRINTK(2, "PM3HgEnd: 0x%08x\n", PM3_READ_REG(PM3HgEnd));
+	DPRINTK(2, "PM3HsEnd: 0x%08x\n", PM3_READ_REG(PM3HsEnd));
+	DPRINTK(2, "PM3HsStart: 0x%08x\n", PM3_READ_REG(PM3HsStart));
+	DPRINTK(2, "PM3MemBypassWriteMask: 0x%08x\n",
+		PM3_READ_REG(PM3MemBypassWriteMask));
+	DPRINTK(2, "PM3RD_IndexControl: 0x%08x\n",
+		PM3_READ_REG(PM3RD_IndexControl));
+	DPRINTK(2, "PM3ScreenBase: 0x%08x\n", PM3_READ_REG(PM3ScreenBase));
+	DPRINTK(2, "PM3ScreenStride: 0x%08x\n",
+		PM3_READ_REG(PM3ScreenStride));
+	DPRINTK(2, "PM3VClkCtl: 0x%08x\n", PM3_READ_REG(PM3VClkCtl));
+	DPRINTK(2, "PM3VTotal: 0x%08x\n", PM3_READ_REG(PM3VTotal));
+	DPRINTK(2, "PM3VbEnd: 0x%08x\n", PM3_READ_REG(PM3VbEnd));
+	DPRINTK(2, "PM3VideoControl: 0x%08x\n",
+		PM3_READ_REG(PM3VideoControl));
+	DPRINTK(2, "PM3VsEnd: 0x%08x\n", PM3_READ_REG(PM3VsEnd));
+	DPRINTK(2, "PM3VsStart: 0x%08x\n", PM3_READ_REG(PM3VsStart));
+
+	DPRINTK(2, "PM3RD_ColorFormat: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_ColorFormat));
+	DPRINTK(2, "PM3RD_DACControl: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_DACControl));
+	DPRINTK(2, "PM3RD_DClk0FeedbackScale: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_DClk0FeedbackScale));
+	DPRINTK(2, "PM3RD_DClk0PostScale: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_DClk0PostScale));
+	DPRINTK(2, "PM3RD_DClk0PreScale: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_DClk0PreScale));
+	DPRINTK(2, "[not set] PM3RD_IndexControl: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_IndexControl));
+	DPRINTK(2, "PM3RD_MiscControl: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_MiscControl));
+	DPRINTK(2, "PM3RD_PixelSize: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_PixelSize));
+	DPRINTK(2, "PM3RD_SyncControl: %ld\n",
+		PM3_READ_DAC_REG(PM3RD_SyncControl));
+}
+
+#endif /* defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2) */
+static void pm3fb_show_cur_timing(struct pm3fb_info *l_fb_info)
+{
+	u16 subvendor, subdevice;
+
+	if ((!pci_read_config_word
+	     (l_fb_info->dev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor))
+	    &&
+	    (!pci_read_config_word
+	     (l_fb_info->dev, PCI_SUBSYSTEM_ID, &subdevice))) {
+		/* well, nothing... */
+	} else {
+		subvendor = subdevice = (u16)-1;
+	}
+
+	printk(KERN_INFO "pm3fb: memory timings for board #%ld (subvendor: 0x%hx, subdevice: 0x%hx)\n", l_fb_info->board_num, subvendor, subdevice);
+	printk(KERN_INFO " PM3LocalMemCaps: 0x%08x\n",
+	       PM3_READ_REG(PM3LocalMemCaps));
+	printk(KERN_INFO " PM3LocalMemTimings: 0x%08x\n",
+	       PM3_READ_REG(PM3LocalMemTimings));
+	printk(KERN_INFO " PM3LocalMemControl: 0x%08x\n",
+	       PM3_READ_REG(PM3LocalMemControl));
+	printk(KERN_INFO " PM3LocalMemRefresh: 0x%08x\n",
+	       PM3_READ_REG(PM3LocalMemRefresh));
+	printk(KERN_INFO " PM3LocalMemPowerDown: 0x%08x\n",
+	       PM3_READ_REG(PM3LocalMemPowerDown));
+}
+
+/* write the mode to registers */
+static void pm3fb_write_mode(struct pm3fb_info *l_fb_info)
+{
+	char tempsync = 0x00, tempmisc = 0x00;
+	DTRACE;
+
+	PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xffffffff);
+	PM3_SLOW_WRITE_REG(PM3Aperture0, 0x00000000);
+	PM3_SLOW_WRITE_REG(PM3Aperture1, 0x00000000);
+	PM3_SLOW_WRITE_REG(PM3FIFODis, 0x00000007);
+
+	PM3_SLOW_WRITE_REG(PM3HTotal,
+			   pm3fb_Shiftbpp(l_fb_info,
+					  l_fb_info->current_par->depth,
+					  l_fb_info->current_par->htotal -
+					  1));
+	PM3_SLOW_WRITE_REG(PM3HsEnd,
+			   pm3fb_Shiftbpp(l_fb_info,
+					  l_fb_info->current_par->depth,
+					  l_fb_info->current_par->hsend));
+	PM3_SLOW_WRITE_REG(PM3HsStart,
+			   pm3fb_Shiftbpp(l_fb_info,
+					  l_fb_info->current_par->depth,
+					  l_fb_info->current_par->
+					  hsstart));
+	PM3_SLOW_WRITE_REG(PM3HbEnd,
+			   pm3fb_Shiftbpp(l_fb_info,
+					  l_fb_info->current_par->depth,
+					  l_fb_info->current_par->hbend));
+	PM3_SLOW_WRITE_REG(PM3HgEnd,
+			   pm3fb_Shiftbpp(l_fb_info,
+					  l_fb_info->current_par->depth,
+					  l_fb_info->current_par->hbend));
+	PM3_SLOW_WRITE_REG(PM3ScreenStride,
+			   pm3fb_Shiftbpp(l_fb_info,
+					  l_fb_info->current_par->depth,
+					  l_fb_info->current_par->stride));
+	PM3_SLOW_WRITE_REG(PM3VTotal, l_fb_info->current_par->vtotal - 1);
+	PM3_SLOW_WRITE_REG(PM3VsEnd, l_fb_info->current_par->vsend - 1);
+	PM3_SLOW_WRITE_REG(PM3VsStart,
+			   l_fb_info->current_par->vsstart - 1);
+	PM3_SLOW_WRITE_REG(PM3VbEnd, l_fb_info->current_par->vbend);
+
+	switch (l_fb_info->current_par->depth) {
+	case 8:
+		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+				   PM3ByApertureMode_PIXELSIZE_8BIT);
+		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+				   PM3ByApertureMode_PIXELSIZE_8BIT);
+		break;
+
+	case 12:
+	case 15:
+	case 16:
+#ifndef __BIG_ENDIAN
+		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+				   PM3ByApertureMode_PIXELSIZE_16BIT);
+		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+				   PM3ByApertureMode_PIXELSIZE_16BIT);
+#else
+		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+				   PM3ByApertureMode_PIXELSIZE_16BIT |
+				   PM3ByApertureMode_BYTESWAP_BADC);
+		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+				   PM3ByApertureMode_PIXELSIZE_16BIT |
+				   PM3ByApertureMode_BYTESWAP_BADC);
+#endif /* ! __BIG_ENDIAN */
+		break;
+
+	case 32:
+#ifndef __BIG_ENDIAN
+		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+				   PM3ByApertureMode_PIXELSIZE_32BIT);
+		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+				   PM3ByApertureMode_PIXELSIZE_32BIT);
+#else
+		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+				   PM3ByApertureMode_PIXELSIZE_32BIT |
+				   PM3ByApertureMode_BYTESWAP_DCBA);
+		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+				   PM3ByApertureMode_PIXELSIZE_32BIT |
+				   PM3ByApertureMode_BYTESWAP_DCBA);
+#endif /* ! __BIG_ENDIAN */
+		break;
+
+	default:
+		DPRINTK(1, "Unsupported depth %d\n",
+			l_fb_info->current_par->depth);
+		break;
+	}
+
+	/*
+	 * Oxygen VX1 - it appears that setting PM3VideoControl and
+	 * then PM3RD_SyncControl to the same SYNC settings undoes
+	 * any net change - they seem to xor together.  Only set the
+	 * sync options in PM3RD_SyncControl.  --rmk
+	 */
+	{
+		unsigned int video = l_fb_info->current_par->video;
+
+		video &= ~(PM3VideoControl_HSYNC_MASK |
+			   PM3VideoControl_VSYNC_MASK);
+		video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
+			 PM3VideoControl_VSYNC_ACTIVE_HIGH;
+		PM3_SLOW_WRITE_REG(PM3VideoControl, video);
+	}
+	PM3_SLOW_WRITE_REG(PM3VClkCtl,
+			   (PM3_READ_REG(PM3VClkCtl) & 0xFFFFFFFC));
+	PM3_SLOW_WRITE_REG(PM3ScreenBase, l_fb_info->current_par->base);
+	PM3_SLOW_WRITE_REG(PM3ChipConfig,
+			   (PM3_READ_REG(PM3ChipConfig) & 0xFFFFFFFD));
+
+	{
+		unsigned char m;	/* ClkPreScale */
+		unsigned char n;	/* ClkFeedBackScale */
+		unsigned char p;	/* ClkPostScale */
+		(void)pm3fb_CalculateClock(l_fb_info, l_fb_info->current_par->pixclock, PM3_REF_CLOCK, &m, &n, &p);
+
+		DPRINTK(2,
+			"Pixclock: %d, Pre: %d, Feedback: %d, Post: %d\n",
+			l_fb_info->current_par->pixclock, (int) m, (int) n,
+			(int) p);
+
+		PM3_WRITE_DAC_REG(PM3RD_DClk0PreScale, m);
+		PM3_WRITE_DAC_REG(PM3RD_DClk0FeedbackScale, n);
+		PM3_WRITE_DAC_REG(PM3RD_DClk0PostScale, p);
+	}
+	/*
+	   PM3_WRITE_DAC_REG(PM3RD_IndexControl, 0x00);
+	 */
+	/*
+	   PM3_SLOW_WRITE_REG(PM3RD_IndexControl, 0x00);
+	 */
+	if ((l_fb_info->current_par->video & PM3VideoControl_HSYNC_MASK) ==
+	    PM3VideoControl_HSYNC_ACTIVE_HIGH)
+		tempsync |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH;
+	if ((l_fb_info->current_par->video & PM3VideoControl_VSYNC_MASK) ==
+	    PM3VideoControl_VSYNC_ACTIVE_HIGH)
+		tempsync |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH;
+	
+	PM3_WRITE_DAC_REG(PM3RD_SyncControl, tempsync);
+	DPRINTK(2, "PM3RD_SyncControl: %d\n", tempsync);
+	
+	if (flatpanel[l_fb_info->board_num])
+	{
+		PM3_WRITE_DAC_REG(PM3RD_DACControl, PM3RD_DACControl_BLANK_PEDESTAL_ENABLE);
+		PM3_WAIT(2);
+		PM3_WRITE_REG(PM3VSConfiguration, 0x06);
+		PM3_WRITE_REG(0x5a00, 1 << 14); /* black magic... */
+		tempmisc = PM3RD_MiscControl_VSB_OUTPUT_ENABLE;
+	}
+	else
+		PM3_WRITE_DAC_REG(PM3RD_DACControl, 0x00);
+
+	switch (l_fb_info->current_par->depth) {
+	case 8:
+		PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+				  PM3RD_PixelSize_8_BIT_PIXELS);
+		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+				  PM3RD_ColorFormat_CI8_COLOR |
+				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW);
+		tempmisc |= PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
+		break;
+	case 12:
+		PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+				  PM3RD_PixelSize_16_BIT_PIXELS);
+		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+				  PM3RD_ColorFormat_4444_COLOR |
+				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
+				  PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
+		tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
+			PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
+		break;		
+	case 15:
+		PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+				  PM3RD_PixelSize_16_BIT_PIXELS);
+		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+				  PM3RD_ColorFormat_5551_FRONT_COLOR |
+				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
+				  PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
+		tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
+			PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
+		break;		
+	case 16:
+		PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+				  PM3RD_PixelSize_16_BIT_PIXELS);
+		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+				  PM3RD_ColorFormat_565_FRONT_COLOR |
+				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
+				  PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
+		tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
+			PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
+		break;
+	case 32:
+		PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+				  PM3RD_PixelSize_32_BIT_PIXELS);
+		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+				  PM3RD_ColorFormat_8888_COLOR |
+				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW);
+		tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
+			PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
+		break;
+	}
+	PM3_WRITE_DAC_REG(PM3RD_MiscControl, tempmisc);
+	
+	PM3_SHOW_CUR_MODE;
+}
+
+static void pm3fb_read_mode(struct pm3fb_info *l_fb_info,
+			    struct pm3fb_par *curpar)
+{
+	unsigned long pixsize1, pixsize2, clockused;
+	unsigned long pre, feedback, post;
+
+	DTRACE;
+
+	clockused = PM3_READ_REG(PM3VClkCtl);
+
+	switch (clockused) {
+	case 3:
+		pre = PM3_READ_DAC_REG(PM3RD_DClk3PreScale);
+		feedback = PM3_READ_DAC_REG(PM3RD_DClk3FeedbackScale);
+		post = PM3_READ_DAC_REG(PM3RD_DClk3PostScale);
+
+		DPRINTK(2,
+			"DClk3 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",
+			pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,
+								feedback,
+								post));
+		break;
+	case 2:
+		pre = PM3_READ_DAC_REG(PM3RD_DClk2PreScale);
+		feedback = PM3_READ_DAC_REG(PM3RD_DClk2FeedbackScale);
+		post = PM3_READ_DAC_REG(PM3RD_DClk2PostScale);
+
+		DPRINTK(2,
+			"DClk2 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",
+			pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,
+								feedback,
+								post));
+		break;
+	case 1:
+		pre = PM3_READ_DAC_REG(PM3RD_DClk1PreScale);
+		feedback = PM3_READ_DAC_REG(PM3RD_DClk1FeedbackScale);
+		post = PM3_READ_DAC_REG(PM3RD_DClk1PostScale);
+
+		DPRINTK(2,
+			"DClk1 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",
+			pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,
+								feedback,
+								post));
+		break;
+	case 0:
+		pre = PM3_READ_DAC_REG(PM3RD_DClk0PreScale);
+		feedback = PM3_READ_DAC_REG(PM3RD_DClk0FeedbackScale);
+		post = PM3_READ_DAC_REG(PM3RD_DClk0PostScale);
+
+		DPRINTK(2,
+			"DClk0 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",
+			pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,
+								feedback,
+								post));
+		break;
+	default:
+		pre = feedback = post = 0;
+		DPRINTK(1, "Unknowk D clock used : %ld\n", clockused);
+		break;
+	}
+
+	curpar->pixclock = PM3_SCALE_TO_CLOCK(pre, feedback, post);
+
+	pixsize1 =
+	    PM3ByApertureMode_PIXELSIZE_MASK &
+	    (PM3_READ_REG(PM3ByAperture1Mode));
+	pixsize2 =
+	    PM3ByApertureMode_PIXELSIZE_MASK &
+	    (PM3_READ_REG(PM3ByAperture2Mode));
+
+	DASSERT((pixsize1 == pixsize2),
+		"pixsize the same in both aperture\n");
+
+	if (pixsize1 & PM3ByApertureMode_PIXELSIZE_32BIT)
+		curpar->depth = 32;
+	else if (pixsize1 & PM3ByApertureMode_PIXELSIZE_16BIT)
+	{
+		curpar->depth = 16;
+	}
+	else
+		curpar->depth = 8;
+
+	/* not sure if I need to add one on the next ; it give better result with */
+	curpar->htotal =
+	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
+			     1 + PM3_READ_REG(PM3HTotal));
+	curpar->hsend =
+	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
+			     PM3_READ_REG(PM3HsEnd));
+	curpar->hsstart =
+	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
+			     PM3_READ_REG(PM3HsStart));
+	curpar->hbend =
+	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
+			     PM3_READ_REG(PM3HbEnd));
+
+	curpar->stride =
+	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
+			     PM3_READ_REG(PM3ScreenStride));
+
+	curpar->vtotal = 1 + PM3_READ_REG(PM3VTotal);
+	curpar->vsend = 1 + PM3_READ_REG(PM3VsEnd);
+	curpar->vsstart = 1 + PM3_READ_REG(PM3VsStart);
+	curpar->vbend = PM3_READ_REG(PM3VbEnd);
+
+	curpar->video = PM3_READ_REG(PM3VideoControl);
+
+	curpar->base = PM3_READ_REG(PM3ScreenBase);
+	curpar->width = curpar->htotal - curpar->hbend; /* make virtual == displayed resolution */
+	curpar->height = curpar->vtotal - curpar->vbend;
+
+	DPRINTK(2, "Found : %d * %d, %d Khz, stride is %08x\n",
+		curpar->width, curpar->height, curpar->pixclock,
+		curpar->stride);
+}
+
+static unsigned long pm3fb_size_memory(struct pm3fb_info *l_fb_info)
+{
+	unsigned long memsize = 0, tempBypass, i, temp1, temp2;
+	u16 subvendor, subdevice;
+	pm3fb_timing_result ptr;
+
+	DTRACE;
+
+	l_fb_info->fb_size = 64 * 1024 * 1024;	/* pm3 aperture always 64 MB */
+	pm3fb_mapIO(l_fb_info);	/* temporary map IO */
+
+	DASSERT((l_fb_info->vIOBase != NULL),
+		"IO successfully mapped before mem detect\n");
+	DASSERT((l_fb_info->v_fb != NULL),
+		"FB successfully mapped before mem detect\n");
+
+	/* card-specific stuff, *before* accessing *any* FB memory */
+	if ((!pci_read_config_word
+	     (l_fb_info->dev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor))
+	    &&
+	    (!pci_read_config_word
+	     (l_fb_info->dev, PCI_SUBSYSTEM_ID, &subdevice))) {
+		i = 0; l_fb_info->board_type = 0;
+		while ((cardbase[i].cardname[0]) && !(l_fb_info->board_type)) {
+			if ((cardbase[i].subvendor == subvendor) &&
+			    (cardbase[i].subdevice == subdevice) &&
+			    (cardbase[i].func == PCI_FUNC(l_fb_info->dev->devfn))) {
+				DPRINTK(2, "Card #%ld is an %s\n",
+					l_fb_info->board_num,
+					cardbase[i].cardname);
+				if (cardbase[i].specific_setup)
+					cardbase[i].specific_setup(l_fb_info);
+				l_fb_info->board_type = i;
+			}
+			i++;
+		}
+		if (!l_fb_info->board_type) {
+			DPRINTK(1, "Card #%ld is an unknown 0x%04x / 0x%04x\n",
+				l_fb_info->board_num, subvendor, subdevice);
+		}
+	} else {
+		printk(KERN_ERR "pm3fb: Error: pci_read_config_word failed, board #%ld\n",
+		       l_fb_info->board_num);
+	}
+
+	if (printtimings)
+		pm3fb_show_cur_timing(l_fb_info);
+	
+	/* card-specific setup is done, we preserve the final
+           memory timing for future reference */
+	if ((ptr = pm3fb_preserve_memory_timings(l_fb_info)) == pm3fb_timing_problem) { /* memory timings were wrong ! oops.... */
+		return(0);
+	}
+	
+	tempBypass = PM3_READ_REG(PM3MemBypassWriteMask);
+
+	DPRINTK(2, "PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);
+
+	PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xFFFFFFFF);
+
+	/* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
+	for (i = 0; i < 32; i++) {
+#ifdef KERNEL_2_2
+#ifdef MUST_BYTESWAP
+		writel(__swab32(i * 0x00345678),
+		       (l_fb_info->v_fb + (i * 1048576)));
+#else
+		writel(i * 0x00345678, (l_fb_info->v_fb + (i * 1048576)));
+#endif
+		mb();
+#ifdef MUST_BYTESWAP
+		temp1 = __swab32(readl((l_fb_info->v_fb + (i * 1048576))));
+#else
+		temp1 = readl((l_fb_info->v_fb + (i * 1048576)));
+#endif
+#endif	/* KERNEL_2_2 */
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+		fb_writel(i * 0x00345678,
+			  (l_fb_info->v_fb + (i * 1048576)));
+		mb();
+		temp1 = fb_readl((l_fb_info->v_fb + (i * 1048576)));
+#endif /* KERNEL_2_4 or KERNEL_2_5 */
+		/* Let's check for wrapover, write will fail at 16MB boundary */
+		if (temp1 == (i * 0x00345678))
+			memsize = i;
+		else
+			break;
+	}
+
+	DPRINTK(2, "First detect pass already got %ld MB\n", memsize + 1);
+
+	if (memsize == i) {
+		for (i = 0; i < 32; i++) {
+			/* Clear first 32MB ; 0 is 0, no need to byteswap */
+			writel(0x0000000,
+			       (l_fb_info->v_fb + (i * 1048576)));
+			mb();
+		}
+
+		for (i = 32; i < 64; i++) {
+#ifdef KERNEL_2_2
+#ifdef MUST_BYTESWAP
+			writel(__swab32(i * 0x00345678),
+			       (l_fb_info->v_fb + (i * 1048576)));
+#else
+			writel(i * 0x00345678,
+			       (l_fb_info->v_fb + (i * 1048576)));
+#endif
+			mb();
+#ifdef MUST_BYTESWAP
+			temp1 =
+			    __swab32(readl
+				     ((l_fb_info->v_fb + (i * 1048576))));
+			temp2 =
+			    __swab32(readl
+				     ((l_fb_info->v_fb +
+				       ((i - 32) * 1048576))));
+#else
+			temp1 = readl((l_fb_info->v_fb + (i * 1048576)));
+			temp2 =
+			    readl((l_fb_info->v_fb +
+				   ((i - 32) * 1048576)));
+#endif
+#endif /* KERNEL_2_2 */
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+			fb_writel(i * 0x00345678,
+				  (l_fb_info->v_fb + (i * 1048576)));
+			mb();
+			temp1 =
+			    fb_readl((l_fb_info->v_fb + (i * 1048576)));
+			temp2 =
+			    fb_readl((l_fb_info->v_fb +
+				      ((i - 32) * 1048576)));
+#endif /* KERNEL_2_4 or KERNEL_2_5 */
+			if ((temp1 == (i * 0x00345678)) && (temp2 == 0))	/* different value, different RAM... */
+				memsize = i;
+			else
+				break;
+		}
+	}
+
+	DPRINTK(2, "Second detect pass got %ld MB\n", memsize + 1);
+
+	PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, tempBypass);
+
+	pm3fb_unmapIO(l_fb_info);
+	memsize = 1048576 * (memsize + 1);
+
+	DPRINTK(2, "Returning 0x%08lx bytes\n", memsize);
+
+	if (forcesize[l_fb_info->board_num] && ((forcesize[l_fb_info->board_num] * 1048576) != memsize))
+	{
+		printk(KERN_WARNING "pm3fb: mismatch between probed (%ld MB) and specified (%hd MB) memory size, using SPECIFIED !\n", memsize, forcesize[l_fb_info->board_num]);
+		memsize = 1048576 * forcesize[l_fb_info->board_num];
+	}
+	
+	l_fb_info->fb_size = memsize;
+	
+	if (ptr == pm3fb_timing_retry)
+	{
+		printk(KERN_WARNING "pm3fb: retrying memory timings check");
+		if (pm3fb_try_memory_timings(l_fb_info) == pm3fb_timing_problem)
+			return(0);
+	}
+	
+	return (memsize);
+}
+
+static void pm3fb_clear_memory(struct pm3fb_info *l_fb_info, u32 cc)
+{
+	int i;
+
+	DTRACE;
+
+	for (i = 0; i < (l_fb_info->fb_size / sizeof(u32)) ; i++) /* clear entire FB memory to black */
+	{
+#ifdef KERNEL_2_2
+#ifdef MUST_BYTESWAP
+		writel(__swab32(cc), (l_fb_info->v_fb + (i * sizeof(u32))));
+#else
+		writel(cc, (l_fb_info->v_fb + (i * sizeof(u32))));
+#endif
+#endif
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+		fb_writel(cc, (l_fb_info->v_fb + (i * sizeof(u32))));
+#endif
+	}
+}
+
+static void pm3fb_clear_colormap(struct pm3fb_info *l_fb_info, unsigned char r, unsigned char g, unsigned char b)
+{
+	int i;
+
+	DTRACE;
+
+	for (i = 0; i < 256 ; i++) /* fill color map with white */
+		pm3fb_set_color(l_fb_info, i, r, g, b);
+
+}
+
+/* common initialisation */
+static void pm3fb_common_init(struct pm3fb_info *l_fb_info)
+{
+	DTRACE;
+
+	DPRINTK(2, "Initializing board #%ld @ %lx\n", l_fb_info->board_num,
+		(unsigned long) l_fb_info);
+
+	strcpy(l_fb_info->gen.info.modename, permedia3_name);
+	disp[l_fb_info->board_num].scrollmode = 0;	/* SCROLL_YNOMOVE; *//* 0 means "let fbcon choose" */
+	l_fb_info->gen.parsize = sizeof(struct pm3fb_par);
+	l_fb_info->gen.info.changevar = NULL;
+	l_fb_info->gen.info.node = B_FREE;
+	l_fb_info->gen.info.fbops = &pm3fb_ops;
+	l_fb_info->gen.info.disp = &(disp[l_fb_info->board_num]);
+	if (fontn[l_fb_info->board_num][0])
+		strcpy(l_fb_info->gen.info.fontname,
+		       fontn[l_fb_info->board_num]);
+	l_fb_info->gen.info.switch_con = &fbgen_switch;
+	l_fb_info->gen.info.updatevar = &fbgen_update_var;	/* */
+	l_fb_info->gen.info.blank = &fbgen_blank;	/* */
+	l_fb_info->gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+	pm3fb_mapIO(l_fb_info);
+
+	pm3fb_clear_memory(l_fb_info, 0);
+	pm3fb_clear_colormap(l_fb_info, 0, 0, 0);
+
+	(void) fbgen_get_var(&(disp[l_fb_info->board_num]).var, -1,
+			     &l_fb_info->gen.info);
+
+	if (depth[l_fb_info->board_num]) /* override mode-defined depth */
+	{
+		pm3fb_encode_depth(&(disp[l_fb_info->board_num]).var, depth[l_fb_info->board_num]);
+		(disp[l_fb_info->board_num]).var.bits_per_pixel = depth2bpp(depth[l_fb_info->board_num]);
+	}
+
+	(void) fbgen_do_set_var(&(disp[l_fb_info->board_num]).var, 1,
+				&l_fb_info->gen);
+
+	fbgen_set_disp(-1, &l_fb_info->gen);
+
+	fbgen_install_cmap(0, &l_fb_info->gen);
+
+	if (register_framebuffer(&l_fb_info->gen.info) < 0) {
+		DPRINTK(1, "Couldn't register framebuffer\n");
+		return;
+	}
+
+	PM3_WRITE_DAC_REG(PM3RD_CursorMode,
+			  PM3RD_CursorMode_CURSOR_DISABLE);
+	
+	PM3_SHOW_CUR_MODE;
+	
+	pm3fb_write_mode(l_fb_info);
+	
+	printk("fb%d: %s, using %uK of video memory (%s)\n",
+	       GET_FB_IDX(l_fb_info->gen.info.node),
+	       permedia3_name, (u32) (l_fb_info->fb_size >> 10),
+	       cardbase[l_fb_info->board_type].cardname);
+}
+
+/* **************************************************** */
+/* ***** accelerated permedia3-specific functions ***** */
+/* **************************************************** */
+#ifdef PM3FB_USE_ACCEL
+static void pm3fb_wait_pm3(struct pm3fb_info *l_fb_info)
+{
+	DTRACE;
+
+	PM3_SLOW_WRITE_REG(PM3FilterMode, PM3FilterModeSync);
+	PM3_SLOW_WRITE_REG(PM3Sync, 0);
+	mb();
+	do {
+		while ((PM3_READ_REG(PM3OutFIFOWords)) == 0);
+		rmb();
+	} while ((PM3_READ_REG(PM3OutputFifo)) != PM3Sync_Tag);
+}
+
+static void pm3fb_init_engine(struct pm3fb_info *l_fb_info)
+{
+	PM3_SLOW_WRITE_REG(PM3FilterMode, PM3FilterModeSync);
+	PM3_SLOW_WRITE_REG(PM3StatisticMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3DeltaMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3RasterizerMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3ScissorMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3LineStippleMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3AreaStippleMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3GIDMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3DepthMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3StencilMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3StencilData, 0x0);
+	PM3_SLOW_WRITE_REG(PM3ColorDDAMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureCoordMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureIndexMode0, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureIndexMode1, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureReadMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3LUTMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureFilterMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureCompositeMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureApplicationMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureCompositeColorMode1, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureCompositeAlphaMode1, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureCompositeColorMode0, 0x0);
+	PM3_SLOW_WRITE_REG(PM3TextureCompositeAlphaMode0, 0x0);
+	PM3_SLOW_WRITE_REG(PM3FogMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3ChromaTestMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3AlphaTestMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3AntialiasMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3YUVMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3AlphaBlendColorMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3AlphaBlendAlphaMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3DitherMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3LogicalOpMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3RouterMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3Window, 0x0);
+
+	PM3_SLOW_WRITE_REG(PM3Config2D, 0x0);
+
+	PM3_SLOW_WRITE_REG(PM3SpanColorMask, 0xffffffff);
+
+	PM3_SLOW_WRITE_REG(PM3XBias, 0x0);
+	PM3_SLOW_WRITE_REG(PM3YBias, 0x0);
+	PM3_SLOW_WRITE_REG(PM3DeltaControl, 0x0);
+
+	PM3_SLOW_WRITE_REG(PM3BitMaskPattern, 0xffffffff);
+
+	PM3_SLOW_WRITE_REG(PM3FBDestReadEnables,
+			   PM3FBDestReadEnables_E(0xff) |
+			   PM3FBDestReadEnables_R(0xff) |
+			   PM3FBDestReadEnables_ReferenceAlpha(0xff));
+	PM3_SLOW_WRITE_REG(PM3FBDestReadBufferAddr0, 0x0);
+	PM3_SLOW_WRITE_REG(PM3FBDestReadBufferOffset0, 0x0);
+	PM3_SLOW_WRITE_REG(PM3FBDestReadBufferWidth0,
+			   PM3FBDestReadBufferWidth_Width(l_fb_info->
+							  current_par->
+							  width));
+
+	PM3_SLOW_WRITE_REG(PM3FBDestReadMode,
+			   PM3FBDestReadMode_ReadEnable |
+			   PM3FBDestReadMode_Enable0);
+	PM3_SLOW_WRITE_REG(PM3FBSourceReadBufferAddr, 0x0);
+	PM3_SLOW_WRITE_REG(PM3FBSourceReadBufferOffset, 0x0);
+	PM3_SLOW_WRITE_REG(PM3FBSourceReadBufferWidth,
+			   PM3FBSourceReadBufferWidth_Width(l_fb_info->
+							    current_par->
+							    width));
+	PM3_SLOW_WRITE_REG(PM3FBSourceReadMode,
+			   PM3FBSourceReadMode_Blocking |
+			   PM3FBSourceReadMode_ReadEnable);
+
+	{
+		unsigned long rm = 1;
+		switch (l_fb_info->current_par->depth) {
+		case 8:
+			PM3_SLOW_WRITE_REG(PM3PixelSize,
+					   PM3PixelSize_GLOBAL_8BIT);
+			break;
+		case 12:
+		case 15:
+		case 16:
+			PM3_SLOW_WRITE_REG(PM3PixelSize,
+					   PM3PixelSize_GLOBAL_16BIT);
+			break;
+		case 32:
+			PM3_SLOW_WRITE_REG(PM3PixelSize,
+					   PM3PixelSize_GLOBAL_32BIT);
+			break;
+		default:
+			DPRINTK(1, "Unsupported depth %d\n",
+				l_fb_info->current_par->depth);
+			break;
+		}
+		PM3_SLOW_WRITE_REG(PM3RasterizerMode, rm);
+	}
+
+	PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0xffffffff);
+	PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0xffffffff);
+	PM3_SLOW_WRITE_REG(PM3FBWriteMode,
+			   PM3FBWriteMode_WriteEnable |
+			   PM3FBWriteMode_OpaqueSpan |
+			   PM3FBWriteMode_Enable0);
+	PM3_SLOW_WRITE_REG(PM3FBWriteBufferAddr0, 0x0);
+	PM3_SLOW_WRITE_REG(PM3FBWriteBufferOffset0, 0x0);
+	PM3_SLOW_WRITE_REG(PM3FBWriteBufferWidth0,
+			   PM3FBWriteBufferWidth_Width(l_fb_info->
+						       current_par->
+						       width));
+
+	PM3_SLOW_WRITE_REG(PM3SizeOfFramebuffer, 0x0);
+	{
+		unsigned long sofb = (8UL * l_fb_info->fb_size) /
+			((depth2bpp(l_fb_info->current_par->depth))
+			 * l_fb_info->current_par->width);	/* size in lines of FB */
+		if (sofb > 4095)
+			PM3_SLOW_WRITE_REG(PM3SizeOfFramebuffer, 4095);
+		else
+			PM3_SLOW_WRITE_REG(PM3SizeOfFramebuffer, sofb);
+		
+		switch (l_fb_info->current_par->depth) {
+		case 8:
+			PM3_SLOW_WRITE_REG(PM3DitherMode,
+					   (1 << 10) | (2 << 3));
+			break;
+		case 12:
+		case 15:
+		case 16:
+			PM3_SLOW_WRITE_REG(PM3DitherMode,
+					   (1 << 10) | (1 << 3));
+			break;
+		case 32:
+			PM3_SLOW_WRITE_REG(PM3DitherMode,
+					   (1 << 10) | (0 << 3));
+			break;
+		default:
+			DPRINTK(1, "Unsupported depth %d\n",
+				l_fb_info->current_par->depth);
+			break;
+		}
+	}
+
+	PM3_SLOW_WRITE_REG(PM3dXDom, 0x0);
+	PM3_SLOW_WRITE_REG(PM3dXSub, 0x0);
+	PM3_SLOW_WRITE_REG(PM3dY, (1 << 16));
+	PM3_SLOW_WRITE_REG(PM3StartXDom, 0x0);
+	PM3_SLOW_WRITE_REG(PM3StartXSub, 0x0);
+	PM3_SLOW_WRITE_REG(PM3StartY, 0x0);
+	PM3_SLOW_WRITE_REG(PM3Count, 0x0);
+	
+/* Disable LocalBuffer. better safe than sorry */
+	PM3_SLOW_WRITE_REG(PM3LBDestReadMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3LBDestReadEnables, 0x0);
+	PM3_SLOW_WRITE_REG(PM3LBSourceReadMode, 0x0);
+	PM3_SLOW_WRITE_REG(PM3LBWriteMode, 0x0);
+	
+	pm3fb_wait_pm3(l_fb_info);
+}
+
+#ifdef FBCON_HAS_CFB32
+static void pm3fb_cfb32_clear(struct vc_data *conp,
+			      struct display *p,
+			      int sy, int sx, int height, int width)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	u32 c;
+
+	DTRACE;
+
+	sx = sx * fontwidth(p);
+	width = width * fontwidth(p);
+	sy = sy * fontheight(p);
+	height = height * fontheight(p);
+	c = ((u32 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
+
+	/* block fills in 32bpp are hard, but in low res (width <= 1600 :-)
+	   we can use 16bpp operations, but not if NoWriteMask is on (SDRAM)  */
+	if ((l_fb_info->current_par->width > 1600) ||
+	    (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)) {
+		PM3_WAIT(4);
+
+		PM3_WRITE_REG(PM3Config2D,
+					  PM3Config2D_UseConstantSource |
+					  PM3Config2D_ForegroundROPEnable |
+					  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+					  PM3Config2D_FBWriteEnable);
+
+		PM3_WRITE_REG(PM3ForegroundColor, c);
+
+		PM3_WRITE_REG(PM3RectanglePosition,
+			      (PM3RectanglePosition_XOffset(sx)) |
+			      (PM3RectanglePosition_YOffset(sy)));
+
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      PM3Render2D_SpanOperation |
+			      (PM3Render2D_Width(width)) |
+			      (PM3Render2D_Height(height)));
+	} else {
+		PM3_WAIT(8);
+
+		PM3_WRITE_REG(PM3FBBlockColor, c);
+
+		PM3_WRITE_REG(PM3PixelSize, PM3PixelSize_GLOBAL_16BIT);
+
+		PM3_WRITE_REG(PM3FBWriteBufferWidth0,
+			      PM3FBWriteBufferWidth_Width(l_fb_info->
+							  current_par->
+							  width << 1));
+
+		PM3_WRITE_REG(PM3Config2D,
+					  PM3Config2D_UseConstantSource |
+					  PM3Config2D_ForegroundROPEnable |
+					  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+					  PM3Config2D_FBWriteEnable);
+
+		PM3_WRITE_REG(PM3RectanglePosition,
+			      (PM3RectanglePosition_XOffset(sx << 1)) |
+			      (PM3RectanglePosition_YOffset(sy)));
+
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      (PM3Render2D_Width(width << 1)) |
+			      (PM3Render2D_Height(height)));
+
+		PM3_WRITE_REG(PM3FBWriteBufferWidth0,
+			      PM3FBWriteBufferWidth_Width(l_fb_info->
+							  current_par->
+							  width));
+
+		PM3_WRITE_REG(PM3PixelSize, PM3PixelSize_GLOBAL_32BIT);
+	}
+
+	pm3fb_wait_pm3(l_fb_info);
+}
+
+static void pm3fb_cfb32_clear_margins(struct vc_data *conp,
+				      struct display *p, int bottom_only)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	int sx, sy;
+	u32 c;
+
+	DTRACE;
+
+	sx = conp->vc_cols * fontwidth(p);	/* right margin */
+	sy = conp->vc_rows * fontheight(p);	/* bottom margin */
+	c = ((u32 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
+
+	if (!bottom_only) {	/* right margin top->bottom */
+		PM3_WAIT(4);
+
+		PM3_WRITE_REG(PM3Config2D,
+					  PM3Config2D_UseConstantSource |
+					  PM3Config2D_ForegroundROPEnable |
+					  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+					  PM3Config2D_FBWriteEnable);
+
+		PM3_WRITE_REG(PM3ForegroundColor, c);
+
+		PM3_WRITE_REG(PM3RectanglePosition,
+			      (PM3RectanglePosition_XOffset
+			       (p->var.xoffset +
+				sx)) | (PM3RectanglePosition_YOffset(p->
+								     var.
+								     yoffset)));
+
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      PM3Render2D_SpanOperation |
+			      (PM3Render2D_Width(p->var.xres - sx)) |
+			      (PM3Render2D_Height(p->var.yres)));
+	}
+
+	/* bottom margin left -> right */
+	PM3_WAIT(4);
+
+	PM3_WRITE_REG(PM3Config2D,
+				  PM3Config2D_UseConstantSource |
+				  PM3Config2D_ForegroundROPEnable |
+				  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+				  PM3Config2D_FBWriteEnable);
+
+	PM3_WRITE_REG(PM3ForegroundColor, c);
+
+	PM3_WRITE_REG(PM3RectanglePosition,
+		      (PM3RectanglePosition_XOffset(p->var.xoffset)) |
+		      (PM3RectanglePosition_YOffset(p->var.yoffset + sy)));
+
+	PM3_WRITE_REG(PM3Render2D,
+		      PM3Render2D_XPositive |
+		      PM3Render2D_YPositive |
+		      PM3Render2D_Operation_Normal |
+		      PM3Render2D_SpanOperation |
+		      (PM3Render2D_Width(p->var.xres)) |
+		      (PM3Render2D_Height(p->var.yres - sy)));
+
+	pm3fb_wait_pm3(l_fb_info);
+}
+#endif /* FBCON_HAS_CFB32 */
+#ifdef FBCON_HAS_CFB16
+static void pm3fb_cfb16_clear(struct vc_data *conp,
+			      struct display *p,
+			      int sy, int sx, int height, int width)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	u32 c;
+
+	DTRACE;
+
+	sx = sx * fontwidth(p);
+	width = width * fontwidth(p);
+	sy = sy * fontheight(p);
+	height = height * fontheight(p);
+	c = ((u16 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
+	c = c | (c << 16);
+
+	PM3_WAIT(4);
+
+	if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
+		PM3_WRITE_REG(PM3ForegroundColor, c);
+	else
+		PM3_WRITE_REG(PM3FBBlockColor, c);
+
+	PM3_WRITE_REG(PM3Config2D,
+				  PM3Config2D_UseConstantSource |
+				  PM3Config2D_ForegroundROPEnable |
+				  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+				  PM3Config2D_FBWriteEnable);
+
+	PM3_WRITE_REG(PM3RectanglePosition,
+		      (PM3RectanglePosition_XOffset(sx)) |
+		      (PM3RectanglePosition_YOffset(sy)));
+	
+	if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      PM3Render2D_SpanOperation |
+			      (PM3Render2D_Width(width)) |
+			      (PM3Render2D_Height(height)));
+	else
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      (PM3Render2D_Width(width)) |
+			      (PM3Render2D_Height(height)));
+	
+	pm3fb_wait_pm3(l_fb_info);
+}
+
+static void pm3fb_cfb16_clear_margins(struct vc_data *conp,
+				      struct display *p, int bottom_only)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	int sx, sy;
+	u32 c;
+
+	DTRACE;
+
+	sx = conp->vc_cols * fontwidth(p);	/* right margin */
+	sy = conp->vc_rows * fontheight(p);	/* bottom margin */
+	c = ((u16 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
+	c = c | (c << 16);
+
+	if (!bottom_only) {	/* right margin top->bottom */
+		PM3_WAIT(4);
+
+		PM3_WRITE_REG(PM3Config2D,
+					  PM3Config2D_UseConstantSource |
+					  PM3Config2D_ForegroundROPEnable |
+					  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+					  PM3Config2D_FBWriteEnable);
+		
+		if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
+			PM3_WRITE_REG(PM3ForegroundColor, c);
+		else
+			PM3_WRITE_REG(PM3FBBlockColor, c);
+		
+		PM3_WRITE_REG(PM3RectanglePosition,
+			      (PM3RectanglePosition_XOffset
+			       (p->var.xoffset +
+				sx)) | (PM3RectanglePosition_YOffset(p->
+								     var.
+								     yoffset)));
+		if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
+			PM3_WRITE_REG(PM3Render2D,
+				      PM3Render2D_XPositive |
+				      PM3Render2D_YPositive |
+				      PM3Render2D_Operation_Normal |
+				      PM3Render2D_SpanOperation |
+				      (PM3Render2D_Width(p->var.xres - sx)) |
+				      (PM3Render2D_Height(p->var.yres)));
+		else
+			PM3_WRITE_REG(PM3Render2D,
+				      PM3Render2D_XPositive |
+				      PM3Render2D_YPositive |
+				      PM3Render2D_Operation_Normal |
+				      (PM3Render2D_Width(p->var.xres - sx)) |
+				      (PM3Render2D_Height(p->var.yres)));
+	}
+	
+	/* bottom margin left -> right */
+	PM3_WAIT(4);
+	
+	PM3_WRITE_REG(PM3Config2D,
+		      PM3Config2D_UseConstantSource |
+		      PM3Config2D_ForegroundROPEnable |
+		      (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+		      PM3Config2D_FBWriteEnable);
+	
+	if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
+		PM3_WRITE_REG(PM3ForegroundColor, c);
+	else
+		PM3_WRITE_REG(PM3FBBlockColor, c);
+	
+	
+	PM3_WRITE_REG(PM3RectanglePosition,
+		      (PM3RectanglePosition_XOffset(p->var.xoffset)) |
+		      (PM3RectanglePosition_YOffset(p->var.yoffset + sy)));
+	
+	if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      PM3Render2D_SpanOperation |
+			      (PM3Render2D_Width(p->var.xres)) |
+			      (PM3Render2D_Height(p->var.yres - sy)));
+	else
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      (PM3Render2D_Width(p->var.xres)) |
+			      (PM3Render2D_Height(p->var.yres - sy)));
+
+	pm3fb_wait_pm3(l_fb_info);
+}
+#endif /* FBCON_HAS_CFB16 */
+#ifdef FBCON_HAS_CFB8
+static void pm3fb_cfb8_clear(struct vc_data *conp,
+			     struct display *p,
+			     int sy, int sx, int height, int width)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	u32 c;
+
+	DTRACE;
+
+	sx = sx * fontwidth(p);
+	width = width * fontwidth(p);
+	sy = sy * fontheight(p);
+	height = height * fontheight(p);
+
+	c = attr_bgcol_ec(p, conp);
+	c |= c << 8;
+	c |= c << 16;
+
+	PM3_WAIT(4);
+
+	PM3_WRITE_REG(PM3Config2D,
+				  PM3Config2D_UseConstantSource |
+				  PM3Config2D_ForegroundROPEnable |
+				  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+				  PM3Config2D_FBWriteEnable);
+
+	PM3_WRITE_REG(PM3ForegroundColor, c);
+
+	PM3_WRITE_REG(PM3RectanglePosition,
+		      (PM3RectanglePosition_XOffset(sx)) |
+		      (PM3RectanglePosition_YOffset(sy)));
+
+	PM3_WRITE_REG(PM3Render2D,
+		      PM3Render2D_XPositive |
+		      PM3Render2D_YPositive |
+		      PM3Render2D_Operation_Normal |
+		      PM3Render2D_SpanOperation |
+		      (PM3Render2D_Width(width)) |
+		      (PM3Render2D_Height(height)));
+
+	pm3fb_wait_pm3(l_fb_info);
+}
+
+static void pm3fb_cfb8_clear_margins(struct vc_data *conp,
+				     struct display *p, int bottom_only)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	int sx, sy;
+	u32 c;
+
+	DTRACE;
+
+	sx = conp->vc_cols * fontwidth(p);	/* right margin */
+	sy = conp->vc_rows * fontheight(p);	/* bottom margin */
+	c = attr_bgcol_ec(p, conp);
+	c |= c << 8;
+	c |= c << 16;
+
+	if (!bottom_only) {	/* right margin top->bottom */
+		PM3_WAIT(4);
+
+		PM3_WRITE_REG(PM3Config2D,
+					  PM3Config2D_UseConstantSource |
+					  PM3Config2D_ForegroundROPEnable |
+					  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+					  PM3Config2D_FBWriteEnable);
+
+		PM3_WRITE_REG(PM3ForegroundColor, c);
+
+		PM3_WRITE_REG(PM3RectanglePosition,
+			      (PM3RectanglePosition_XOffset
+			       (p->var.xoffset +
+				sx)) | (PM3RectanglePosition_YOffset(p->
+								     var.
+								     yoffset)));
+
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      PM3Render2D_SpanOperation |
+			      (PM3Render2D_Width(p->var.xres - sx)) |
+			      (PM3Render2D_Height(p->var.yres)));
+	}
+
+	/* bottom margin left -> right */
+	PM3_WAIT(4);
+
+	PM3_WRITE_REG(PM3Config2D,
+				  PM3Config2D_UseConstantSource |
+				  PM3Config2D_ForegroundROPEnable |
+				  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+				  PM3Config2D_FBWriteEnable);
+
+	PM3_WRITE_REG(PM3ForegroundColor, c);
+
+	PM3_WRITE_REG(PM3RectanglePosition,
+		      (PM3RectanglePosition_XOffset(p->var.xoffset)) |
+		      (PM3RectanglePosition_YOffset(p->var.yoffset + sy)));
+
+	PM3_WRITE_REG(PM3Render2D,
+		      PM3Render2D_XPositive |
+		      PM3Render2D_YPositive |
+		      PM3Render2D_Operation_Normal |
+		      PM3Render2D_SpanOperation |
+		      (PM3Render2D_Width(p->var.xres)) |
+		      (PM3Render2D_Height(p->var.yres - sy)));
+
+	pm3fb_wait_pm3(l_fb_info);
+}
+#endif /* FBCON_HAS_CFB8 */
+#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
+static void pm3fb_cfbX_bmove(struct display *p,
+			     int sy, int sx,
+			     int dy, int dx, int height, int width)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	int x_align, o_x, o_y;
+
+	DTRACE;
+
+	sx = sx * fontwidth(p);
+	dx = dx * fontwidth(p);
+	width = width * fontwidth(p);
+	sy = sy * fontheight(p);
+	dy = dy * fontheight(p);
+	height = height * fontheight(p);
+
+	o_x = sx - dx;		/*(sx > dx ) ? (sx - dx) : (dx - sx); */
+	o_y = sy - dy;		/*(sy > dy ) ? (sy - dy) : (dy - sy); */
+
+	x_align = (sx & 0x1f);
+
+	PM3_WAIT(6);
+
+	PM3_WRITE_REG(PM3Config2D,
+				  PM3Config2D_UserScissorEnable |
+				  PM3Config2D_ForegroundROPEnable |
+				  PM3Config2D_Blocking |
+				  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+				  PM3Config2D_FBWriteEnable);
+
+	PM3_WRITE_REG(PM3ScissorMinXY,
+		      ((dy & 0x0fff) << 16) | (dx & 0x0fff));
+	PM3_WRITE_REG(PM3ScissorMaxXY,
+				  (((dy + height) & 0x0fff) << 16) |
+				  ((dx + width) & 0x0fff));
+
+	PM3_WRITE_REG(PM3FBSourceReadBufferOffset,
+		      PM3FBSourceReadBufferOffset_XOffset(o_x) |
+		      PM3FBSourceReadBufferOffset_YOffset(o_y));
+
+	PM3_WRITE_REG(PM3RectanglePosition,
+		      (PM3RectanglePosition_XOffset(dx - x_align)) |
+		      (PM3RectanglePosition_YOffset(dy)));
+
+	PM3_WRITE_REG(PM3Render2D,
+		      ((sx > dx) ? PM3Render2D_XPositive : 0) |
+		      ((sy > dy) ? PM3Render2D_YPositive : 0) |
+		      PM3Render2D_Operation_Normal |
+		      PM3Render2D_SpanOperation |
+		      PM3Render2D_FBSourceReadEnable |
+		      (PM3Render2D_Width(width + x_align)) |
+		      (PM3Render2D_Height(height)));
+
+	pm3fb_wait_pm3(l_fb_info);
+}
+
+static void pm3fb_cfbX_putc(struct vc_data *conp, struct display *p,
+			    int c, int yy, int xx)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	u8 *cdat, asx = 0, asy = 0, o_x = 0, o_y = 0;
+	u32 fgx, bgx, ldat;
+	int sx, sy, i;
+
+	DTRACE;
+
+	if (l_fb_info->current_par->depth == 8)
+		fgx = attr_fgcol(p, c);
+	else if (depth2bpp(l_fb_info->current_par->depth) == 16)
+		fgx = ((u16 *) p->dispsw_data)[attr_fgcol(p, c)];
+	else
+		fgx = ((u32 *) p->dispsw_data)[attr_fgcol(p, c)];
+
+	PM3_COLOR(fgx);
+
+	if (l_fb_info->current_par->depth == 8)
+		bgx = attr_bgcol(p, c);
+	else if (depth2bpp(l_fb_info->current_par->depth) == 16)
+		bgx = ((u16 *) p->dispsw_data)[attr_bgcol(p, c)];
+	else
+		bgx = ((u32 *) p->dispsw_data)[attr_bgcol(p, c)];
+
+	PM3_COLOR(bgx);
+
+	PM3_WAIT(4);
+
+	PM3_WRITE_REG(PM3Config2D,
+				  PM3Config2D_UseConstantSource |
+				  PM3Config2D_ForegroundROPEnable |
+				  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+				  PM3Config2D_FBWriteEnable | PM3Config2D_OpaqueSpan);
+
+	PM3_WRITE_REG(PM3ForegroundColor, fgx);
+	PM3_WRITE_REG(PM3FillBackgroundColor, bgx);
+
+	/* WARNING : adress select X need to specify 8 bits for fontwidth <= 8 */
+	/* and 16 bits for fontwidth <= 16 */
+	/* same in _putcs, same for Y and fontheight */
+	if (fontwidth(p) <= 8)
+		asx = 2;
+	else if (fontwidth(p) <= 16)
+		asx = 3;	/* look OK */
+	if (fontheight(p) <= 8)
+		asy = 2;
+	else if (fontheight(p) <= 16)
+		asy = 3;	/* look OK */
+	else if (fontheight(p) <= 32)
+		asy = 4;	/* look OK */
+
+	sx = xx * fontwidth(p);
+	sy = yy * fontheight(p);
+
+	if (fontwidth(p) <= 8)
+		o_x = (8 - (sx & 0x7)) & 0x7;
+	else if (fontwidth(p) <= 16)
+		o_x = (16 - (sx & 0xF)) & 0xF;
+	if (fontheight(p) <= 8)
+		o_y = (8 - (sy & 0x7)) & 0x7;
+	else if (fontheight(p) <= 16)
+		o_y = (16 - (sy & 0xF)) & 0xF;
+	else if (fontheight(p) <= 32)
+		o_y = (32 - (sy & 0x1F)) & 0x1F;
+
+	PM3_WRITE_REG(PM3AreaStippleMode, (o_x << 7) | (o_y << 12) |	/* x_offset, y_offset in pattern */
+		      (1 << 18) |	/* BE */
+		      1 | (asx << 1) | (asy << 4) |	/* address select x/y */
+		      (1 << 20));	/* OpaqueSpan */
+
+	if (fontwidth(p) <= 8) {
+		cdat = p->fontdata + (c & p->charmask) * fontheight(p);
+	} else {
+		cdat =
+		    p->fontdata +
+		    ((c & p->charmask) * (fontheight(p) << 1));
+	}
+
+	PM3_WAIT(2 + fontheight(p));
+
+	for (i = 0; i < fontheight(p); i++) {	/* assume fontheight <= 32 */
+		if (fontwidth(p) <= 8) {
+			ldat = *cdat++;
+		} else {	/* assume fontwidth <= 16 ATM */
+
+			ldat = ((*cdat++) << 8);
+			ldat |= *cdat++;
+		}
+		PM3_WRITE_REG(AreaStipplePattern_indexed(i), ldat);
+	}
+
+	PM3_WRITE_REG(PM3RectanglePosition,
+		      (PM3RectanglePosition_XOffset(sx)) |
+		      (PM3RectanglePosition_YOffset(sy)));
+
+	PM3_WRITE_REG(PM3Render2D,
+		      PM3Render2D_AreaStippleEnable |
+		      PM3Render2D_XPositive |
+		      PM3Render2D_YPositive |
+		      PM3Render2D_Operation_Normal |
+		      PM3Render2D_SpanOperation |
+		      (PM3Render2D_Width(fontwidth(p))) |
+		      (PM3Render2D_Height(fontheight(p))));
+
+	pm3fb_wait_pm3(l_fb_info);
+}
+
+static void pm3fb_cfbX_putcs(struct vc_data *conp, struct display *p,
+			     const unsigned short *s, int count, int yy,
+			     int xx)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+	u8 *cdat, asx = 0, asy = 0, o_x = 0, o_y = 0;
+	u32 fgx, bgx, ldat;
+	int sx, sy, i, j;
+	u16 sc;
+
+	DTRACE;
+
+	sc = scr_readw(s);
+	if (l_fb_info->current_par->depth == 8)
+		fgx = attr_fgcol(p, sc);
+	else if (depth2bpp(l_fb_info->current_par->depth) == 16)
+		fgx = ((u16 *) p->dispsw_data)[attr_fgcol(p, sc)];
+	else
+		fgx = ((u32 *) p->dispsw_data)[attr_fgcol(p, sc)];
+	
+	PM3_COLOR(fgx);
+	
+	if (l_fb_info->current_par->depth == 8)
+		bgx = attr_bgcol(p, sc);
+	else if (depth2bpp(l_fb_info->current_par->depth) == 16)
+		bgx = ((u16 *) p->dispsw_data)[attr_bgcol(p, sc)];
+	else
+		bgx = ((u32 *) p->dispsw_data)[attr_bgcol(p, sc)];
+	
+	PM3_COLOR(bgx);
+
+	PM3_WAIT(4);
+
+	PM3_WRITE_REG(PM3Config2D,
+				  PM3Config2D_UseConstantSource |
+				  PM3Config2D_ForegroundROPEnable |
+				  (PM3Config2D_ForegroundROP(0x3)) |	/* Ox3 is GXcopy */
+				  PM3Config2D_FBWriteEnable |
+				  PM3Config2D_OpaqueSpan);
+
+	PM3_WRITE_REG(PM3ForegroundColor, fgx);
+	PM3_WRITE_REG(PM3FillBackgroundColor, bgx);
+
+	/* WARNING : adress select X need to specify 8 bits for fontwidth <= 8 */
+	/* and 16 bits for fontwidth <= 16 */
+	/* same in _putc, same for Y and fontheight */
+	if (fontwidth(p) <= 8)
+		asx = 2;
+	else if (fontwidth(p) <= 16)
+		asx = 3;	/* look OK */
+	if (fontheight(p) <= 8)
+		asy = 2;
+	else if (fontheight(p) <= 16)
+		asy = 3;	/* look OK */
+	else if (fontheight(p) <= 32)
+		asy = 4;	/* look OK */
+
+	sy = yy * fontheight(p);
+
+	if (fontheight(p) <= 8)
+		o_y = (8 - (sy & 0x7)) & 0x7;
+	else if (fontheight(p) <= 16)
+		o_y = (16 - (sy & 0xF)) & 0xF;
+	else if (fontheight(p) <= 32)
+		o_y = (32 - (sy & 0x1F)) & 0x1F;
+
+	for (j = 0; j < count; j++) {
+		sc = scr_readw(s + j);
+		if (fontwidth(p) <= 8)
+			cdat = p->fontdata +
+				(sc & p->charmask) * fontheight(p);
+		else
+			cdat = p->fontdata +
+				((sc & p->charmask) * fontheight(p) << 1);
+		
+		sx = (xx + j) * fontwidth(p);
+
+		if (fontwidth(p) <= 8)
+			o_x = (8 - (sx & 0x7)) & 0x7;
+		else if (fontwidth(p) <= 16)
+			o_x = (16 - (sx & 0xF)) & 0xF;
+
+		PM3_WAIT(3 + fontheight(p));
+
+		PM3_WRITE_REG(PM3AreaStippleMode, (o_x << 7) | (o_y << 12) | /* x_offset, y_offset in pattern */
+			      (1 << 18) | /* BE */
+			      1 | (asx << 1) | (asy << 4) | /* address select x/y */
+			      (1 << 20)); /* OpaqueSpan */
+
+		for (i = 0; i < fontheight(p); i++) { /* assume fontheight <= 32 */
+			if (fontwidth(p) <= 8) {
+				ldat = *cdat++;
+			} else { /* assume fontwidth <= 16 ATM */
+				ldat = ((*cdat++) << 8);
+				ldat |= *cdat++;
+			}
+			PM3_WRITE_REG(AreaStipplePattern_indexed(i), ldat);
+		}
+
+		PM3_WRITE_REG(PM3RectanglePosition,
+			      (PM3RectanglePosition_XOffset(sx)) |
+			      (PM3RectanglePosition_YOffset(sy)));
+
+		PM3_WRITE_REG(PM3Render2D,
+			      PM3Render2D_AreaStippleEnable |
+			      PM3Render2D_XPositive |
+			      PM3Render2D_YPositive |
+			      PM3Render2D_Operation_Normal |
+			      PM3Render2D_SpanOperation |
+			      (PM3Render2D_Width(fontwidth(p))) |
+			      (PM3Render2D_Height(fontheight(p))));
+	}
+	pm3fb_wait_pm3(l_fb_info);
+}
+
+static void pm3fb_cfbX_revc(struct display *p, int xx, int yy)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
+
+	xx = xx * fontwidth(p);
+	yy = yy * fontheight(p);
+
+	if (l_fb_info->current_par->depth == 8)
+	{
+		if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
+			PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0x0F0F0F0F);
+		else
+			PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0x0F0F0F0F);
+	}
+
+	PM3_WAIT(3);
+
+	PM3_WRITE_REG(PM3Config2D,
+				  PM3Config2D_UseConstantSource |
+				  PM3Config2D_ForegroundROPEnable |
+				  (PM3Config2D_ForegroundROP(0xa)) |	/* Oxa is GXinvert */
+				  PM3Config2D_FBDestReadEnable |
+				  PM3Config2D_FBWriteEnable);
+
+	PM3_WRITE_REG(PM3RectanglePosition,
+		      (PM3RectanglePosition_XOffset(xx)) |
+		      (PM3RectanglePosition_YOffset(yy)));
+
+	PM3_WRITE_REG(PM3Render2D,
+		      PM3Render2D_XPositive |
+		      PM3Render2D_YPositive |
+		      PM3Render2D_Operation_Normal |
+		      PM3Render2D_SpanOperation |
+		      (PM3Render2D_Width(fontwidth(p))) |
+		      (PM3Render2D_Height(fontheight(p))));
+
+	pm3fb_wait_pm3(l_fb_info);
+
+	if (l_fb_info->current_par->depth == 8)
+	{
+		if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
+			PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0xFFFFFFFF);
+		else
+			PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0xFFFFFFFF);
+	}
+}
+
+#endif /* FBCON_HAS_CFB8 || FBCON_HAS_CFB16 || FBCON_HAS_CFB32 */
+#endif /* PM3FB_USE_ACCEL */
+/* *********************************** */
+/* ***** pre-init board(s) setup ***** */
+/* *********************************** */
+
+static void pm3fb_mode_setup(char *mode, unsigned long board_num)
+{
+	struct pm3fb_info *l_fb_info = &(fb_info[board_num]);
+	struct pm3fb_par *l_fb_par = &(current_par[board_num]);
+	unsigned long i = 0;
+
+	current_par_valid[board_num] = 0;
+
+	if (!strncmp(mode, "current", 7)) {
+		l_fb_info->use_current = 1;	/* default w/ OpenFirmware */
+	} else {
+		while ((mode_base[i].name[0])
+		       && (!current_par_valid[board_num])) {
+			if (!
+			    (strncmp
+			     (mode, mode_base[i].name,
+			      strlen(mode_base[i].name)))) {
+				memcpy(l_fb_par, &(mode_base[i].user_mode),
+				       sizeof(struct pm3fb_par));
+				current_par_valid[board_num] = 1;
+				DPRINTK(2, "Mode set to %s\n",
+					mode_base[i].name);
+			}
+			i++;
+		}
+		DASSERT(current_par_valid[board_num],
+			"Valid mode on command line\n");
+	}
+}
+
+static void pm3fb_pciid_setup(char *pciid, unsigned long board_num)
+{
+	short l_bus = -1, l_slot = -1, l_func = -1;
+	char *next;
+
+	if (pciid) {
+		l_bus = simple_strtoul(pciid, &next, 10);
+		if (next && (next[0] == ':')) {
+			pciid = next + 1;
+			l_slot = simple_strtoul(pciid, &next, 10);
+			if (next && (next[0] == ':')) {
+				pciid = next + 1;
+				l_func =
+				    simple_strtoul(pciid, (char **) NULL,
+						   10);
+			}
+		}
+	} else
+		return;
+
+	if ((l_bus >= 0) && (l_slot >= 0) && (l_func >= 0)) {
+		bus[board_num] = l_bus;
+		slot[board_num] = l_slot;
+		func[board_num] = l_func;
+		DPRINTK(2, "Board #%ld will be PciId: %hd:%hd:%hd\n",
+			board_num, l_bus, l_slot, l_func);
+	} else {
+		DPRINTK(1, "Invalid PciId: %hd:%hd:%hd for board #%ld\n",
+			l_bus, l_slot, l_func, board_num);
+	}
+}
+
+static void pm3fb_font_setup(char *lf, unsigned long board_num)
+{
+	unsigned long lfs = strlen(lf);
+
+	if (lfs > (PM3_FONTNAME_SIZE - 1)) {
+		DPRINTK(1, "Fontname %s too long\n", lf);
+		return;
+	}
+	strncpy(fontn[board_num], lf, lfs);
+	fontn[board_num][lfs] = '\0';
+}
+
+static void pm3fb_bootdepth_setup(char *bds, unsigned long board_num)
+{
+	unsigned long bd = simple_strtoul(bds, (char **) NULL, 10);
+
+	if (!(depth_supported(bd))) {
+		printk(KERN_WARNING "pm3fb: ignoring invalid depth %s for board #%ld\n",
+		       bds, board_num);
+		return;
+	}
+	depth[board_num] = bd;
+}
+
+static void pm3fb_forcesize_setup(char *bds, unsigned long board_num)
+{
+	unsigned long bd = simple_strtoul(bds, (char **) NULL, 10);
+
+	if (bd > 64) {
+		printk(KERN_WARNING "pm3fb: ignoring invalid memory size %s for board #%ld\n",
+		       bds, board_num);
+		return;
+	}
+	forcesize[board_num] = bd;
+}
+
+static char *pm3fb_boardnum_setup(char *options, unsigned long *bn)
+{
+	char *next;
+
+	if (!(CHAR_IS_NUM(options[0]))) {
+		(*bn) = 0;
+		return (options);
+	}
+
+	(*bn) = simple_strtoul(options, &next, 10);
+
+	if (next && (next[0] == ':') && ((*bn) >= 0)
+	    && ((*bn) <= PM3_MAX_BOARD)) {
+		DPRINTK(2, "Board_num seen as %ld\n", (*bn));
+		return (next + 1);
+	} else {
+		(*bn) = 0;
+		DPRINTK(2, "Board_num default to %ld\n", (*bn));
+		return (options);
+	}
+}
+
+static void pm3fb_real_setup(char *options)
+{
+	char *next;
+	unsigned long i, bn;
+	struct pm3fb_info *l_fb_info;
+
+	DTRACE;
+
+	DPRINTK(2, "Options : %s\n", options);
+
+	for (i = 0; i < PM3_MAX_BOARD; i++) {
+		l_fb_info = &(fb_info[i]);
+		memset(l_fb_info, 0, sizeof(struct pm3fb_info));
+		l_fb_info->gen.fbhw = &pm3fb_switch;
+		l_fb_info->board_num = i;
+		current_par_valid[i] = 0;
+		slot[i] = -1;
+		func[i] = -1;
+		bus[i] = -1;
+		disable[i] = 0;
+		noaccel[i] = 0;
+		fontn[i][0] = '\0';
+		depth[i] = 0;
+		l_fb_info->current_par = &(current_par[i]);
+	}
+
+	/* eat up prefix pm3fb and whatever is used as separator i.e. :,= */
+	if (!strncmp(options, "pm3fb", 5)) {
+		options += 5;
+		while (((*options) == ',') || ((*options) == ':')
+		       || ((*options) == '='))
+			options++;
+	}
+
+	while (options) {
+		bn = 0;
+		if ((next = strchr(options, ','))) {
+			(*next) = '\0';
+			next++;
+		}
+
+		if (!strncmp(options, "mode:", 5)) {
+			options = pm3fb_boardnum_setup(options + 5, &bn);
+			DPRINTK(2, "Setting mode for board #%ld\n", bn);
+			pm3fb_mode_setup(options, bn);
+		} else if (!strncmp(options, "off:", 4)) {
+			options = pm3fb_boardnum_setup(options + 4, &bn);
+			DPRINTK(2, "Disabling board #%ld\n", bn);
+			disable[bn] = 1;
+		} else if (!strncmp(options, "off", 3)) {	/* disable everything */
+			for (i = 0; i < PM3_MAX_BOARD; i++)
+				disable[i] = 1;
+		} else if (!strncmp(options, "disable:", 8)) {
+			options = pm3fb_boardnum_setup(options + 8, &bn);
+			DPRINTK(2, "Disabling board #%ld\n", bn);
+			disable[bn] = 1;
+		} else if (!strncmp(options, "pciid:", 6)) {
+			options = pm3fb_boardnum_setup(options + 6, &bn);
+			DPRINTK(2, "Setting PciID for board #%ld\n", bn);
+			pm3fb_pciid_setup(options, bn);
+		} else if (!strncmp(options, "noaccel:", 8)) {
+			options = pm3fb_boardnum_setup(options + 8, &bn);
+			noaccel[bn] = 1;
+		} else if (!strncmp(options, "font:", 5)) {
+			options = pm3fb_boardnum_setup(options + 5, &bn);
+			pm3fb_font_setup(options, bn);
+		} else if (!strncmp(options, "depth:", 6)) {
+			options = pm3fb_boardnum_setup(options + 6, &bn);
+			pm3fb_bootdepth_setup(options, bn);
+		} else if (!strncmp(options, "printtimings", 12)) {
+			printtimings = 1;
+		} else if (!strncmp(options, "flatpanel:", 10)) {
+			options = pm3fb_boardnum_setup(options + 10, &bn);
+			flatpanel[bn] = 1;
+		} else if (!strncmp(options, "forcesize:", 10)) {
+			options = pm3fb_boardnum_setup(options + 10, &bn);
+			pm3fb_forcesize_setup(options, bn);
+		}
+		options = next;
+	}
+}
+
+/* ********************************************** */
+/* ***** framebuffer API standard functions ***** */
+/* ********************************************** */
+
+static int pm3fb_open(struct fb_info *info, int user)
+{
+	DTRACE;
+
+	MOD_INC_USE_COUNT;
+
+	return (0);
+}
+
+static int pm3fb_release(struct fb_info *info, int user)
+{
+	DTRACE;
+
+	MOD_DEC_USE_COUNT;
+
+	return (0);
+}
+
+static int pm3fb_encode_fix(struct fb_fix_screeninfo *fix,
+			    const void *par, struct fb_info_gen *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+	struct pm3fb_par *p = (struct pm3fb_par *) par;
+
+	DTRACE;
+
+	strcpy(fix->id, permedia3_name);
+	fix->smem_start = (unsigned long)l_fb_info->p_fb;
+	fix->smem_len = l_fb_info->fb_size;
+	fix->mmio_start = (unsigned long)l_fb_info->pIOBase;
+	fix->mmio_len = PM3_REGS_SIZE;
+#ifdef PM3FB_USE_ACCEL
+	if (!(noaccel[l_fb_info->board_num]))
+		fix->accel = FB_ACCEL_3DLABS_PERMEDIA3;
+	else
+#endif /* PM3FB_USE_ACCEL */
+		fix->accel = FB_ACCEL_NONE;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->visual =
+	    (p->depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+	if (current_par_valid[l_fb_info->board_num])
+		fix->line_length =
+			l_fb_info->current_par->width *
+			depth2ByPP(l_fb_info->current_par->depth);
+	else
+		fix->line_length = 0;
+	fix->xpanstep = 64 / depth2bpp(p->depth);
+	fix->ypanstep = 1;
+	fix->ywrapstep = 0;
+	return (0);
+}
+
+static int pm3fb_decode_var(const struct fb_var_screeninfo *var,
+			    void *par, struct fb_info_gen *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+	struct pm3fb_par *p = (struct pm3fb_par *) par;
+	struct pm3fb_par temp_p;
+	u32 xres;
+
+	DTRACE;
+
+	DASSERT((var != NULL), "fb_var_screeninfo* not NULL");
+	DASSERT((p != NULL), "pm3fb_par* not NULL");
+	DASSERT((l_fb_info != NULL), "pm3fb_info* not NULL");
+
+	memset(&temp_p, 0, sizeof(struct pm3fb_par));
+	temp_p.width = (var->xres_virtual + 7) & ~7;
+	temp_p.height = var->yres_virtual;
+
+	if (!(depth_supported(var->bits_per_pixel))) /* round unsupported up to a multiple of 8 */
+		temp_p.depth = depth2bpp(var->bits_per_pixel);
+	else
+		temp_p.depth = var->bits_per_pixel;
+
+	temp_p.depth = (temp_p.depth > 32) ? 32 : temp_p.depth; /* max 32 */
+	temp_p.depth = (temp_p.depth == 24) ? 32 : temp_p.depth; /* 24 unsupported, round-up to 32 */
+
+	if ((temp_p.depth == 16) && (var->red.length == 5) && (var->green.length == 5) && (var->blue.length == 5))
+		temp_p.depth = 15; /* RGBA 5551 is stored as depth 15 */
+
+	if ((temp_p.depth == 16) && (var->red.length == 4) && (var->green.length == 4) && (var->blue.length == 4))
+		temp_p.depth = 12; /* RGBA 4444  is stored as depth 12 */
+
+
+	DPRINTK(2,
+		"xres: %d, yres: %d, vxres: %d, vyres: %d ; xoffset:%d, yoffset: %d\n",
+		var->xres, var->yres, var->xres_virtual, var->yres_virtual,
+		var->xoffset, var->yoffset);
+
+	xres = (var->xres + 31) & ~31;
+	if (temp_p.width < xres + var->xoffset)
+		temp_p.width = xres + var->xoffset;
+	if (temp_p.height < var->yres + var->yoffset)
+		temp_p.height = var->yres + var->yoffset;
+
+	if (temp_p.width > 2048) {
+		DPRINTK(1, "virtual width not supported: %u\n",
+			temp_p.width);
+		return (-EINVAL);
+	}
+	if (var->yres < 200) {
+		DPRINTK(1, "height not supported: %u\n", (u32) var->yres);
+		return (-EINVAL);
+	}
+	if (temp_p.height < 200 || temp_p.height > 4095) {
+		DPRINTK(1, "virtual height not supported: %u\n",
+			temp_p.height);
+		return (-EINVAL);
+	}
+	if (!(depth_supported(temp_p.depth))) {
+		DPRINTK(1, "depth not supported: %u\n", temp_p.depth);
+		return (-EINVAL);
+	}
+	if ((temp_p.width * temp_p.height * depth2ByPP(temp_p.depth)) >
+	    l_fb_info->fb_size) {
+		DPRINTK(1, "no memory for screen (%ux%ux%u)\n",
+			temp_p.width, temp_p.height, temp_p.depth);
+		return (-EINVAL);
+	}
+
+	if ((!var->pixclock) ||
+	    (!var->right_margin) ||
+	    (!var->hsync_len) ||
+	    (!var->left_margin) ||
+	    (!var->lower_margin) ||
+	    (!var->vsync_len) || (!var->upper_margin)
+	    ) {
+		unsigned long i = 0, done = 0;
+		printk(KERN_WARNING "pm3fb: refusing to use a likely wrong timing\n");
+
+		while ((mode_base[i].user_mode.width) && !done) {
+			if ((mode_base[i].user_mode.width == temp_p.width)
+			    && (mode_base[i].user_mode.height ==
+				temp_p.height)) {
+				printk(KERN_NOTICE "pm3fb: using close match %s\n",
+				       mode_base[i].name);
+				temp_p = mode_base[i].user_mode;
+				done = 1;
+			}
+			i++;
+		}
+		if (!done)
+			return (-EINVAL);
+	} else {
+		temp_p.pixclock = PICOS2KHZ(var->pixclock);
+		if (temp_p.pixclock > PM3_MAX_PIXCLOCK) {
+			DPRINTK(1, "pixclock too high (%uKHz)\n",
+				temp_p.pixclock);
+			return (-EINVAL);
+		}
+
+		temp_p.hsstart = var->right_margin;
+		temp_p.hsend = var->right_margin + var->hsync_len;
+		temp_p.hbend =
+		    var->right_margin + var->hsync_len + var->left_margin;
+		temp_p.htotal = xres + temp_p.hbend;
+
+		temp_p.vsstart = var->lower_margin;
+		temp_p.vsend = var->lower_margin + var->vsync_len;
+		temp_p.vbend =
+		    var->lower_margin + var->vsync_len + var->upper_margin;
+		temp_p.vtotal = var->yres + temp_p.vbend;
+
+		temp_p.stride = temp_p.width;
+
+		DPRINTK(2, "Using %d * %d, %d Khz, stride is %08x\n",
+			temp_p.width, temp_p.height, temp_p.pixclock,
+			temp_p.stride);
+
+		temp_p.base =
+		    pm3fb_Shiftbpp(l_fb_info, temp_p.depth,
+				   (var->yoffset * xres) + var->xoffset);
+
+		temp_p.video = 0;
+
+		if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+			temp_p.video |= PM3VideoControl_HSYNC_ACTIVE_HIGH;
+		else
+			temp_p.video |= PM3VideoControl_HSYNC_ACTIVE_LOW;
+
+		if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+			temp_p.video |= PM3VideoControl_VSYNC_ACTIVE_HIGH;
+		else
+			temp_p.video |= PM3VideoControl_VSYNC_ACTIVE_LOW;
+
+		if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+			DPRINTK(1, "Interlaced mode not supported\n\n");
+			return (-EINVAL);
+		}
+
+		if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
+			temp_p.video |= PM3VideoControl_LINE_DOUBLE_ON;
+		else
+			temp_p.video |= PM3VideoControl_LINE_DOUBLE_OFF;
+
+		if (var->activate == FB_ACTIVATE_NOW)
+			temp_p.video |= PM3VideoControl_ENABLE;
+		else {
+			temp_p.video |= PM3VideoControl_DISABLE;
+			DPRINTK(2, "PM3Video disabled\n");
+		}
+
+		switch (temp_p.depth) {
+		case 8:
+			temp_p.video |= PM3VideoControl_PIXELSIZE_8BIT;
+			break;
+		case 12:
+		case 15:
+		case 16:
+			temp_p.video |= PM3VideoControl_PIXELSIZE_16BIT;
+			break;
+		case 32:
+			temp_p.video |= PM3VideoControl_PIXELSIZE_32BIT;
+			break;
+		default:
+			DPRINTK(1, "Unsupported depth\n");
+			break;
+		}
+	}
+	(*p) = temp_p;
+
+#ifdef PM3FB_USE_ACCEL
+	if (var->accel_flags & FB_ACCELF_TEXT)
+		noaccel[l_fb_info->board_num] = 0;
+	else
+		noaccel[l_fb_info->board_num] = 1;
+#endif /* PM3FB_USE_ACCEL */
+
+	return (0);
+}
+
+static void pm3fb_encode_depth(struct fb_var_screeninfo *var, long d)
+{
+	switch (d) {
+	case 8:
+		var->red.length = var->green.length = var->blue.length = 8;
+		var->red.offset = var->green.offset = var->blue.offset = 0;
+		var->transp.offset = var->transp.length = 0;
+		break;
+
+	case 12:
+		var->red.offset = 8;
+		var->red.length = 4;
+		var->green.offset = 4;
+		var->green.length = 4;
+		var->blue.offset = 0;
+		var->blue.length = 4;
+		var->transp.offset = 12;
+		var->transp.length = 4;
+		break;
+
+	case 15:
+		var->red.offset = 10;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 5;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 15;
+		var->transp.length = 1;
+		break;
+
+	case 16:
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = var->transp.length = 0;
+		break;
+
+	case 32:
+		var->transp.offset = 24;
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length = var->green.length =
+			var->blue.length = var->transp.length = 8;
+		break;
+
+	default:
+		DPRINTK(1, "Unsupported depth %ld\n", d);
+		break;
+	}
+}
+
+static int pm3fb_encode_var(struct fb_var_screeninfo *var,
+			    const void *par, struct fb_info_gen *info)
+{
+	struct pm3fb_par *p = (struct pm3fb_par *) par;
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+
+	u32 base;
+
+	DTRACE;
+
+	DASSERT((var != NULL), "fb_var_screeninfo* not NULL");
+	DASSERT((p != NULL), "pm3fb_par* not NULL");
+	DASSERT((info != NULL), "fb_info_gen* not NULL");
+
+	memset(var, 0, sizeof(struct fb_var_screeninfo));
+
+#ifdef PM3FB_USE_ACCEL
+	if (!(noaccel[l_fb_info->board_num]))
+		var->accel_flags |= FB_ACCELF_TEXT;
+#endif /* PM3FB_USE_ACCEL */
+
+	var->xres_virtual = p->width;
+	var->yres_virtual = p->height;
+	var->xres = p->htotal - p->hbend;
+	var->yres = p->vtotal - p->vbend;
+
+	DPRINTK(2, "xres = %d, yres : %d\n", var->xres, var->yres);
+
+	var->right_margin = p->hsstart;
+	var->hsync_len = p->hsend - p->hsstart;
+	var->left_margin = p->hbend - p->hsend;
+	var->lower_margin = p->vsstart;
+	var->vsync_len = p->vsend - p->vsstart;
+	var->upper_margin = p->vbend - p->vsend;
+	var->bits_per_pixel = depth2bpp(p->depth);
+	
+	pm3fb_encode_depth(var, p->depth);
+
+	base = pm3fb_Unshiftbpp(l_fb_info, p->depth, p->base);
+
+	var->xoffset = base % var->xres;
+	var->yoffset = base / var->xres;
+
+	var->height = var->width = -1;
+
+	var->pixclock = KHZ2PICOS(p->pixclock);
+
+	if ((p->video & PM3VideoControl_HSYNC_MASK) ==
+	    PM3VideoControl_HSYNC_ACTIVE_HIGH)
+		var->sync |= FB_SYNC_HOR_HIGH_ACT;
+	if ((p->video & PM3VideoControl_VSYNC_MASK) ==
+	    PM3VideoControl_VSYNC_ACTIVE_HIGH)
+		var->sync |= FB_SYNC_VERT_HIGH_ACT;
+	if (p->video & PM3VideoControl_LINE_DOUBLE_ON)
+		var->vmode = FB_VMODE_DOUBLE;
+
+	return (0);
+}
+
+static void pm3fb_get_par(void *par, struct fb_info_gen *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+
+	DTRACE;
+
+	if (!current_par_valid[l_fb_info->board_num]) {
+		if (l_fb_info->use_current)
+			pm3fb_read_mode(l_fb_info, l_fb_info->current_par);
+		else
+			memcpy(l_fb_info->current_par,
+			       &(mode_base[0].user_mode),
+			       sizeof(struct pm3fb_par));
+		current_par_valid[l_fb_info->board_num] = 1;
+	}
+	*((struct pm3fb_par *) par) = *(l_fb_info->current_par);
+}
+
+static void pm3fb_set_par(const void *par, struct fb_info_gen *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+
+	DTRACE;
+
+	*(l_fb_info->current_par) = *((struct pm3fb_par *) par);
+	current_par_valid[l_fb_info->board_num] = 1;
+
+	pm3fb_write_mode(l_fb_info);
+
+#ifdef PM3FB_USE_ACCEL
+	pm3fb_init_engine(l_fb_info);
+#endif /* PM3FB_USE_ACCEL */
+}
+
+static void pm3fb_set_color(struct pm3fb_info *l_fb_info,
+			    unsigned char regno, unsigned char r,
+			    unsigned char g, unsigned char b)
+{
+	DTRACE;
+
+	PM3_SLOW_WRITE_REG(PM3RD_PaletteWriteAddress, regno);
+	PM3_SLOW_WRITE_REG(PM3RD_PaletteData, r);
+	PM3_SLOW_WRITE_REG(PM3RD_PaletteData, g);
+	PM3_SLOW_WRITE_REG(PM3RD_PaletteData, b);
+}
+
+static int pm3fb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			   unsigned *blue, unsigned *transp,
+			   struct fb_info *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+
+	DTRACE;
+
+	if (regno < 256) {
+		*red =
+		    l_fb_info->palette[regno].red << 8 | l_fb_info->
+		    palette[regno].red;
+		*green =
+		    l_fb_info->palette[regno].green << 8 | l_fb_info->
+		    palette[regno].green;
+		*blue =
+		    l_fb_info->palette[regno].blue << 8 | l_fb_info->
+		    palette[regno].blue;
+		*transp =
+		    l_fb_info->palette[regno].transp << 8 | l_fb_info->
+		    palette[regno].transp;
+	}
+	return (regno > 255);
+}
+
+static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+
+	DTRACE;
+
+	if (regno < 16) {
+		switch (l_fb_info->current_par->depth) {
+#ifdef FBCON_HAS_CFB8
+		case 8:
+			break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 12:
+			l_fb_info->cmap.cmap12[regno] =
+				(((u32) red & 0xf000) >> 4) |
+				(((u32) green & 0xf000) >> 8) |
+				(((u32) blue & 0xf000) >> 12);
+			break;
+
+		case 15:
+			l_fb_info->cmap.cmap15[regno] =
+				(((u32) red & 0xf800) >> 1) |
+				(((u32) green & 0xf800) >> 6) |
+				(((u32) blue & 0xf800) >> 11);
+			break;
+
+		case 16:
+			l_fb_info->cmap.cmap16[regno] =
+			    ((u32) red & 0xf800) |
+			    (((u32) green & 0xfc00) >> 5) |
+			    (((u32) blue & 0xf800) >> 11);
+			break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			l_fb_info->cmap.cmap32[regno] =
+			    (((u32) transp & 0xff00) << 16) |
+			    (((u32) red & 0xff00) << 8) |
+			    (((u32) green & 0xff00)) |
+			    (((u32) blue & 0xff00) >> 8);
+			break;
+#endif
+		default:
+			DPRINTK(1, "bad depth %u\n",
+				l_fb_info->current_par->depth);
+			break;
+		}
+	}
+	if (regno < 256) {
+		l_fb_info->palette[regno].red = red >> 8;
+		l_fb_info->palette[regno].green = green >> 8;
+		l_fb_info->palette[regno].blue = blue >> 8;
+		l_fb_info->palette[regno].transp = transp >> 8;
+		if (l_fb_info->current_par->depth == 8)
+			pm3fb_set_color(l_fb_info, regno, red >> 8,
+					green >> 8, blue >> 8);
+	}
+	return (regno > 255);
+}
+
+static int pm3fb_blank(int blank_mode, struct fb_info_gen *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+	u32 video;
+
+	DTRACE;
+
+	if (!current_par_valid[l_fb_info->board_num])
+		return (1);
+
+	video = l_fb_info->current_par->video;
+
+	/*
+	 * Oxygen VX1 - it appears that setting PM3VideoControl and
+	 * then PM3RD_SyncControl to the same SYNC settings undoes
+	 * any net change - they seem to xor together.  Only set the
+	 * sync options in PM3RD_SyncControl.  --rmk
+	 */
+	video &= ~(PM3VideoControl_HSYNC_MASK |
+		   PM3VideoControl_VSYNC_MASK);
+	video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
+		 PM3VideoControl_VSYNC_ACTIVE_HIGH;
+
+	if (blank_mode > 0) {
+		switch (blank_mode - 1) {
+
+		case VESA_NO_BLANKING:	/* FIXME */
+			video = video & ~(PM3VideoControl_ENABLE);
+			break;
+
+		case VESA_HSYNC_SUSPEND:
+			video = video & ~(PM3VideoControl_HSYNC_MASK |
+					  PM3VideoControl_BLANK_ACTIVE_LOW);
+			break;
+		case VESA_VSYNC_SUSPEND:
+			video = video & ~(PM3VideoControl_VSYNC_MASK |
+					  PM3VideoControl_BLANK_ACTIVE_LOW);
+			break;
+		case VESA_POWERDOWN:
+			video = video & ~(PM3VideoControl_HSYNC_MASK |
+					  PM3VideoControl_VSYNC_MASK |
+					  PM3VideoControl_BLANK_ACTIVE_LOW);
+			break;
+		default:
+			DPRINTK(1, "Unsupported blanking %d\n",
+				blank_mode);
+			return (1);
+			break;
+		}
+	}
+
+	PM3_SLOW_WRITE_REG(PM3VideoControl, video);
+
+	return (0);
+}
+
+static void pm3fb_set_disp(const void *par, struct display *disp,
+			   struct fb_info_gen *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+	struct pm3fb_par *p = (struct pm3fb_par *) par;
+	u32 flags;
+
+	DTRACE;
+
+	save_flags(flags);
+	cli();
+	disp->screen_base = l_fb_info->v_fb;
+	switch (p->depth) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+#ifdef PM3FB_USE_ACCEL
+		if (!(noaccel[l_fb_info->board_num]))
+			disp->dispsw = &pm3fb_cfb8;
+		else
+#endif /* PM3FB_USE_ACCEL */
+			disp->dispsw = &fbcon_cfb8;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 12:
+#ifdef PM3FB_USE_ACCEL
+		if (!(noaccel[l_fb_info->board_num]))
+			disp->dispsw = &pm3fb_cfb16;
+		else
+#endif /* PM3FB_USE_ACCEL */
+			disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = l_fb_info->cmap.cmap12;
+		break;
+	case 15:
+#ifdef PM3FB_USE_ACCEL
+		if (!(noaccel[l_fb_info->board_num]))
+			disp->dispsw = &pm3fb_cfb16;
+		else
+#endif /* PM3FB_USE_ACCEL */
+			disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = l_fb_info->cmap.cmap15;
+		break;
+	case 16:
+#ifdef PM3FB_USE_ACCEL
+		if (!(noaccel[l_fb_info->board_num]))
+			disp->dispsw = &pm3fb_cfb16;
+		else
+#endif /* PM3FB_USE_ACCEL */
+			disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = l_fb_info->cmap.cmap16;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 32:
+#ifdef PM3FB_USE_ACCEL
+		if (!(noaccel[l_fb_info->board_num]))
+			disp->dispsw = &pm3fb_cfb32;
+		else
+#endif /* PM3FB_USE_ACCEL */
+			disp->dispsw = &fbcon_cfb32;
+		disp->dispsw_data = l_fb_info->cmap.cmap32;
+		break;
+#endif /* FBCON_HAS_CFB32 */
+	default:
+		disp->dispsw = &fbcon_dummy;
+		DPRINTK(1, "Invalid depth, using fbcon_dummy\n");
+		break;
+	}
+	restore_flags(flags);
+}
+
+/* */
+static void pm3fb_detect(void)
+{
+	struct pci_dev *dev_array[PM3_MAX_BOARD];
+	struct pci_dev *dev = NULL;
+	struct pm3fb_info *l_fb_info = &(fb_info[0]);
+	unsigned long i, j, done;
+
+	DTRACE;
+
+	for (i = 0; i < PM3_MAX_BOARD; i++) {
+		dev_array[i] = NULL;
+		fb_info[i].dev = NULL;
+	}
+
+	dev =
+	    pci_find_device(PCI_VENDOR_ID_3DLABS,
+			    PCI_DEVICE_ID_3DLABS_PERMEDIA3, dev);
+
+	for (i = 0; ((i < PM3_MAX_BOARD) && dev); i++) {
+		dev_array[i] = dev;
+		dev =
+		    pci_find_device(PCI_VENDOR_ID_3DLABS,
+				    PCI_DEVICE_ID_3DLABS_PERMEDIA3, dev);
+	}
+
+	if (dev) {		/* more than PM3_MAX_BOARD */
+		printk(KERN_WARNING "pm3fb: Warning: more than %d boards found\n",
+		       PM3_MAX_BOARD);
+	}
+
+	if (!dev_array[0]) {	/* not a single board, abort */
+		return;
+	}
+
+	/* allocate user-defined boards */
+	for (i = 0; i < PM3_MAX_BOARD; i++) {
+		if ((bus[i] >= 0) && (slot[i] >= 0) && (func[i] >= 0)) {
+			for (j = 0; j < PM3_MAX_BOARD; j++) {
+				if ((dev_array[j] != NULL) &&
+				    (dev_array[j]->bus->number == bus[i])
+				    && (PCI_SLOT(dev_array[j]->devfn) ==
+					slot[i])
+				    && (PCI_FUNC(dev_array[j]->devfn) ==
+					func[i])) {
+					fb_info[i].dev = dev_array[j];
+					dev_array[j] = NULL;
+				}
+			}
+		}
+	}
+	/* allocate remaining boards */
+	for (i = 0; i < PM3_MAX_BOARD; i++) {
+		if (fb_info[i].dev == NULL) {
+			done = 0;
+			for (j = 0; ((j < PM3_MAX_BOARD) && (!done)); j++) {
+				if (dev_array[j] != NULL) {
+					fb_info[i].dev = dev_array[j];
+					dev_array[j] = NULL;
+					done = 1;
+				}
+			}
+		}
+	}
+
+	/* at that point, all PCI Permedia3 are detected and allocated */
+	/* now, initialize... or not */
+	for (i = 0; i < PM3_MAX_BOARD; i++) {
+		l_fb_info = &(fb_info[i]);
+		if ((l_fb_info->dev) && (!disable[i])) {	/* PCI device was found and not disabled by user */
+#ifdef SUPPORT_FB_OF
+			struct device_node *dp =
+			    find_pci_device_OFnode(l_fb_info->dev->bus->
+						   number,
+						   l_fb_info->dev->devfn);
+
+			if ((dp) && (!strncmp(dp->name, "formacGA12", 10))) {
+				/* do nothing, init of board is done in pm3fb_of_init */
+			} else {
+#endif
+				DPRINTK(2,
+					"found @%lx Vendor %lx Device %lx ; base @ : %lx - %lx - %lx - %lx - %lx - %lx, irq %ld\n",
+					(unsigned long) l_fb_info->dev,
+					(unsigned long) l_fb_info->dev->
+					vendor,
+					(unsigned long) l_fb_info->dev->
+					device,
+					(unsigned long)
+					pci_resource_start(l_fb_info->dev,
+							   0),
+					(unsigned long)
+					pci_resource_start(l_fb_info->dev,
+							   1),
+					(unsigned long)
+					pci_resource_start(l_fb_info->dev,
+							   2),
+					(unsigned long)
+					pci_resource_start(l_fb_info->dev,
+							   3),
+					(unsigned long)
+					pci_resource_start(l_fb_info->dev,
+							   4),
+					(unsigned long)
+					pci_resource_start(l_fb_info->dev,
+							   5),
+					(unsigned long) l_fb_info->dev->
+					irq);
+
+				l_fb_info->pIOBase =
+				    (unsigned char *)
+				    pci_resource_start(l_fb_info->dev, 0);
+#ifdef __BIG_ENDIAN
+				l_fb_info->pIOBase += PM3_REGS_SIZE;
+#endif
+				l_fb_info->vIOBase = (unsigned char *) -1;
+				l_fb_info->p_fb =
+				    (unsigned char *)
+				    pci_resource_start(l_fb_info->dev, 1);
+				l_fb_info->v_fb = (unsigned char *) -1;
+
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5) 	/* full resource management, new in linux-2.4.x */
+				if (!request_mem_region
+				    ((unsigned long)l_fb_info->p_fb, 64 * 1024 * 1024, /* request full aperture size */
+				     "pm3fb")) {
+					printk
+					    (KERN_ERR "pm3fb: Error: couldn't request framebuffer memory, board #%ld\n",
+					     l_fb_info->board_num);
+					continue;
+				}
+				if (!request_mem_region
+				    ((unsigned long)l_fb_info->pIOBase, PM3_REGS_SIZE,
+				     "pm3fb I/O regs")) {
+					printk
+					    (KERN_ERR "pm3fb: Error: couldn't request IObase memory, board #%ld\n",
+					     l_fb_info->board_num);
+					continue;
+				}
+#endif /* KERNEL_2_4 or KERNEL_2_5 */
+				if (forcesize[l_fb_info->board_num])
+					l_fb_info->fb_size = forcesize[l_fb_info->board_num];
+				
+				l_fb_info->fb_size =
+				    pm3fb_size_memory(l_fb_info);
+
+				if (l_fb_info->fb_size) {
+					(void) pci_enable_device(l_fb_info->dev);
+					pm3fb_common_init(l_fb_info);
+				} else
+					printk(KERN_ERR "pm3fb: memory problem, not enabling board #%ld\n", l_fb_info->board_num);
+				
+#ifdef SUPPORT_FB_OF
+			}
+#endif /* SUPPORT_FB_OF */
+		}
+	}
+}
+
+static int pm3fb_pan_display(const struct fb_var_screeninfo *var,
+			     struct fb_info_gen *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+
+	DTRACE;
+
+	if (!current_par_valid[l_fb_info->board_num])
+		return -EINVAL;
+
+	l_fb_info->current_par->base =	/* in 128 bits chunk - i.e. AFTER Shiftbpp */
+	    pm3fb_Shiftbpp(l_fb_info,
+			   l_fb_info->current_par->depth,
+			   (var->yoffset * l_fb_info->current_par->width) +
+			   var->xoffset);
+	PM3_SLOW_WRITE_REG(PM3ScreenBase, l_fb_info->current_par->base);
+	return 0;
+}
+
+static int pm3fb_ioctl(struct inode *inode, struct file *file,
+                       u_int cmd, u_long arg, int con,
+		       struct fb_info *info)
+{
+	struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+	u32 cm, i;
+#ifdef PM3FB_MASTER_DEBUG
+	char cc[3];
+#endif /* PM3FB_MASTER_DEBUG */
+
+	switch(cmd)
+	{
+#ifdef PM3FB_MASTER_DEBUG
+	case PM3FBIO_CLEARMEMORY:
+		if (copy_from_user(&cm, (void *)arg, sizeof(u32)))
+			return(-EFAULT);
+		pm3fb_clear_memory(l_fb_info, cm);
+		return(0);
+		break;
+
+	case PM3FBIO_CLEARCMAP:
+		if (copy_from_user(cc, (void*)arg, 3 * sizeof(char)))
+			return(-EFAULT);
+		pm3fb_clear_colormap(l_fb_info, cc[0], cc[1], cc[2]);
+		return(0);
+		break;
+#endif /* PM3FB_MASTER_DEBUG */
+
+	case PM3FBIO_RESETCHIP:
+		cm = 1;
+		PM3_SLOW_WRITE_REG(PM3ResetStatus, 1);
+		for (i = 0 ; (i < 10000) && cm ; i++)
+		{
+			PM3_DELAY(10);
+			cm = PM3_READ_REG(PM3ResetStatus);
+		}
+		if (cm)
+		{
+			printk(KERN_ERR "pm3fb: chip reset failed with status 0x%x\n", cm);
+			return(-EIO);
+		}
+		/* first thing first, reload memory timings */
+		pm3fb_write_memory_timings(l_fb_info);
+#ifdef PM3FB_USE_ACCEL
+		pm3fb_init_engine(l_fb_info);
+#endif /* PM3FB_USE_ACCEL */
+		pm3fb_write_mode(l_fb_info);
+		return(0);
+		break;
+
+	default:
+		DPRINTK(2, "unknown ioctl: %d (%x)\n", cmd, cmd);
+		return(-EINVAL);
+	}
+}
+
+/* ****************************************** */
+/* ***** standard FB API init functions ***** */
+/* ****************************************** */
+
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+int __init pm3fb_setup(char *options)
+#endif
+#ifdef KERNEL_2_2
+__initfunc(void pm3fb_setup(char *options, int *ints))
+#endif
+{
+	long opsi = strlen(options);
+
+	DTRACE;
+
+	memcpy(g_options, options,
+	       ((opsi + 1) >
+		PM3_OPTIONS_SIZE) ? PM3_OPTIONS_SIZE : (opsi + 1));
+	g_options[PM3_OPTIONS_SIZE - 1] = 0;
+
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+	return (0);
+#endif
+}
+
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+int __init pm3fb_init(void)
+#endif
+#ifdef KERNEL_2_2
+__initfunc(void pm3fb_init(void))
+#endif
+{
+	DTRACE;
+
+	DPRINTK(2, "This is pm3fb.c, CVS version: $Header: /cvsroot/linux/drivers/video/pm3fb.c,v 1.1 2002/02/25 19:11:06 marcelo Exp $");
+
+	pm3fb_real_setup(g_options);
+
+	pm3fb_detect();
+
+	if (!fb_info[0].dev) {	/* not even one board ??? */
+		DPRINTK(1, "No PCI Permedia3 board detected\n");
+	}
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+	return (0);
+#endif
+}
+
+#ifdef SUPPORT_FB_OF		/* linux-2.2.x only */
+__initfunc(void pm3fb_of_init(struct device_node *dp))
+{
+	struct pm3fb_info *l_fb_info = NULL;
+	unsigned long i;
+	long bn = -1;
+	struct device_node *dn;
+
+	DTRACE;
+
+	DPRINTK(2, "OpenFirmware board : %s\n", dp->full_name);
+
+	for (i = 0; i < dp->n_addrs; i++) {
+		DPRINTK(2, "MemRange : 0x%08x - 0x%x\n",
+			dp->addrs[i].address, dp->addrs[i].size);
+	}
+
+	for (i = 0; i < PM3_MAX_BOARD; i++) {	/* find which PCI board is the OF device */
+		if (fb_info[i].dev) {
+			dn = find_pci_device_OFnode(fb_info[i].dev->bus->
+						    number,
+						    fb_info[i].dev->devfn);
+			if (dn == dp) {
+				if (bn == -1)
+					bn = i;
+				else {
+					DPRINTK(1,
+						"Error: Multiple PCI device for a single OpenFirmware node\n");
+				}
+			}
+		}
+	}
+
+	if (bn == -1) {
+		DPRINTK(1, "Warning: non-PCI Permedia3 found\n");
+		i = 0;
+		while (fb_info[i].dev && (i < PM3_MAX_BOARD))
+			i++;
+		if (i < PM3_MAX_BOARD)
+			bn = i;
+		else {
+			printk
+			    (KERN_ERR "pm3fb: Error: Couldn't find room for OpenFirmware device");
+			return;
+		}
+	}
+
+	l_fb_info = &(fb_info[bn]);
+
+	l_fb_info->dn = dp;
+
+	l_fb_info->pIOBase = (unsigned char *) dp->addrs[3].address;
+#ifdef __BIG_ENDIAN
+	l_fb_info->pIOBase += PM3_REGS_SIZE;
+#endif
+	l_fb_info->vIOBase = (unsigned char *) -1;
+	l_fb_info->p_fb = (unsigned char *) dp->addrs[1].address;
+	l_fb_info->v_fb = (unsigned char *) -1;
+
+	l_fb_info->fb_size = pm3fb_size_memory(l_fb_info);	/* (unsigned long)dp->addrs[1].size; *//* OF is a liar ! it claims 256 Mb */
+
+	DPRINTK(2,
+		"OpenFirmware board (#%ld) : IOBase 0x%08lx, p_fb 0x%08lx, fb_size %d KB\n",
+		bn, (unsigned long) l_fb_info->pIOBase,
+		(unsigned long) l_fb_info->p_fb, l_fb_info->fb_size >> 10);
+
+	l_fb_info->use_current = 1;	/* will use current mode by default */
+
+	pm3fb_common_init(l_fb_info);
+}
+#endif /* SUPPORT_FB_OF */
+
+/* ************************* */
+/* **** Module support ***** */
+/* ************************* */
+
+#ifdef MODULE
+MODULE_AUTHOR("Romain Dolbeau");
+MODULE_DESCRIPTION("Permedia3 framebuffer device driver");
+static char *mode[PM3_MAX_BOARD];
+MODULE_PARM(mode,PM3_MAX_BOARD_MODULE_ARRAY_STRING);
+MODULE_PARM_DESC(mode,"video mode");
+MODULE_PARM(disable,PM3_MAX_BOARD_MODULE_ARRAY_SHORT);
+MODULE_PARM_DESC(disable,"disable board");
+static short off[PM3_MAX_BOARD];
+MODULE_PARM(off,PM3_MAX_BOARD_MODULE_ARRAY_SHORT);
+MODULE_PARM_DESC(off,"disable board");
+static char *pciid[PM3_MAX_BOARD];
+MODULE_PARM(pciid,PM3_MAX_BOARD_MODULE_ARRAY_STRING);
+MODULE_PARM_DESC(pciid,"board PCI Id");
+MODULE_PARM(noaccel,PM3_MAX_BOARD_MODULE_ARRAY_SHORT);
+MODULE_PARM_DESC(noaccel,"disable accel");
+static char *font[PM3_MAX_BOARD];
+MODULE_PARM(font,PM3_MAX_BOARD_MODULE_ARRAY_STRING);
+MODULE_PARM_DESC(font,"choose font");
+MODULE_PARM(depth,PM3_MAX_BOARD_MODULE_ARRAY_SHORT);
+MODULE_PARM_DESC(depth,"boot-time depth");
+MODULE_PARM(printtimings, "h");
+MODULE_PARM_DESC(printtimings, "print the memory timings of the card(s)");
+MODULE_PARM(forcesize, PM3_MAX_BOARD_MODULE_ARRAY_SHORT);
+MODULE_PARM_DESC(forcesize, "force specified memory size");
+/*
+MODULE_SUPPORTED_DEVICE("Permedia3 PCI boards")
+MODULE_GENERIC_TABLE(gtype,name)
+MODULE_DEVICE_TABLE(type,name)
+*/
+
+void pm3fb_build_options(void)
+{
+	int i;
+	char ts[128];
+
+	strcpy(g_options, "pm3fb");
+	for (i = 0; i < PM3_MAX_BOARD ; i++)
+	{
+		if (mode[i])
+		{
+			sprintf(ts, ",mode:%d:%s", i, mode[i]);
+			strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
+		}
+		if (disable[i] || off[i])
+		{
+			sprintf(ts, ",disable:%d:", i);
+			strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
+		}
+		if (pciid[i])
+		{
+			sprintf(ts, ",pciid:%d:%s", i, pciid[i]);
+			strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
+		}
+		if (noaccel[i])
+		{
+			sprintf(ts, ",noaccel:%d:", i);
+			strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
+		}
+		if (font[i])
+		{
+			sprintf(ts, ",font:%d:%s", i, font[i]);
+			strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
+		}
+		if (depth[i])
+		{
+			sprintf(ts, ",depth:%d:%d", i, depth[i]);
+			strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
+		}
+	}
+	g_options[PM3_OPTIONS_SIZE - 1] = '\0';
+	DPRINTK(1, "pm3fb use options: %s\n", g_options);
+}
+
+int init_module(void)
+{
+	DTRACE;
+
+	pm3fb_build_options();
+
+	pm3fb_init();
+
+	return (0);
+}
+
+void cleanup_module(void)
+{
+	DTRACE;
+	{
+		unsigned long i;
+		struct pm3fb_info *l_fb_info;
+		for (i = 0; i < PM3_MAX_BOARD; i++) {
+			l_fb_info = &(fb_info[i]);
+			if ((l_fb_info->dev != NULL)
+			    && (!(disable[l_fb_info->board_num]))) {
+				if (l_fb_info->vIOBase !=
+				    (unsigned char *) -1) {
+					pm3fb_unmapIO(l_fb_info);
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
+					release_mem_region(l_fb_info->p_fb,
+							   l_fb_info->
+							   fb_size);
+					release_mem_region(l_fb_info->
+							   pIOBase,
+							   PM3_REGS_SIZE);
+#endif /* KERNEL_2_4 or KERNEL_2_5 */
+				}
+				unregister_framebuffer(&l_fb_info->gen.
+						       info);
+			}
+		}
+	}
+	return;
+}
+#endif /* MODULE */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/pm3fb.h linux/drivers/video/pm3fb.h
--- linux.orig/drivers/video/pm3fb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/video/pm3fb.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,1286 @@
+/*
+ *  linux/drivers/video/pm3fb.h -- 3DLabs Permedia3 frame buffer device
+ *  
+ *  Copyright (C) 2001 Romain Dolbeau <dolbeau@irisa.fr>
+ *  Copyright (C) 2001 Sven Luther, <luther@dpt-info.u-strasbg.fr>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ *
+ *  $Header: /cvsroot/linux/drivers/video/pm3fb.h,v 1.1 2002/02/25 19:11:06 marcelo Exp $
+ *
+ */
+
+#ifndef PM3FB_H
+#define PM3FB_H
+
+/**********************************************
+*  GLINT Permedia3 Control Status registers   *
+***********************************************/
+/* Control Status Registers */
+#define PM3ResetStatus						0x0000
+#define PM3IntEnable						0x0008
+#define PM3IntFlags						0x0010
+#define PM3InFIFOSpace						0x0018
+#define PM3OutFIFOWords						0x0020
+#define PM3DMAAddress						0x0028
+#define PM3DMACount						0x0030
+#define PM3ErrorFlags						0x0038
+#define PM3VClkCtl						0x0040
+#define PM3TestRegister						0x0048
+#define PM3Aperture0						0x0050
+#define PM3Aperture1						0x0058
+#define PM3DMAControl						0x0060
+#define PM3FIFODis						0x0068
+#define PM3ChipConfig						0x0070
+#define PM3AGPControl						0x0078
+
+#define PM3GPOutDMAAddress					0x0080
+#define PM3PCIFeedbackCount					0x0088
+#define PM3PCIAbortStatus					0x0090
+#define PM3PCIAbortAddress					0x0098
+
+#define PM3PCIPLLStatus						0x00f0
+
+#define PM3HostTextureAddress					0x0100
+#define PM3TextureDownloadControl				0x0108
+#define PM3TextureOperation					0x0110
+#define PM3LogicalTexturePage					0x0118
+#define PM3TexDMAAddress					0x0120
+#define PM3TexFIFOSpace						0x0128
+
+/**********************************************
+*  GLINT Permedia3 Region 0 Bypass Controls   *
+***********************************************/
+#define PM3ByAperture1Mode					0x0300
+	#define PM3ByApertureMode_BYTESWAP_ABCD			(0<<0)
+	#define PM3ByApertureMode_BYTESWAP_BADC			(1<<0)
+	#define PM3ByApertureMode_BYTESWAP_CDAB			(2<<0)
+	#define PM3ByApertureMode_BYTESWAP_DCBA			(3<<0)
+	#define PM3ByApertureMode_PATCH_DISABLE			(0<<2)
+	#define PM3ByApertureMode_PATCH_ENABLE			(1<<2)
+	#define PM3ByApertureMode_FORMAT_RAW			(0<<3)
+	#define PM3ByApertureMode_FORMAT_YUYV			(1<<3)
+	#define PM3ByApertureMode_FORMAT_UYVY			(2<<3)
+	#define PM3ByApertureMode_PIXELSIZE_8BIT		(0<<5)
+	#define PM3ByApertureMode_PIXELSIZE_16BIT		(1<<5)
+	#define PM3ByApertureMode_PIXELSIZE_32BIT		(2<<5)
+                #define PM3ByApertureMode_PIXELSIZE_MASK        (3<<5)
+	#define PM3ByApertureMode_EFFECTIVE_STRIDE_1024		(0<<7)
+	#define PM3ByApertureMode_EFFECTIVE_STRIDE_2048		(1<<7)
+	#define PM3ByApertureMode_EFFECTIVE_STRIDE_4096		(2<<7)
+	#define PM3ByApertureMode_EFFECTIVE_STRIDE_8192		(3<<7)
+	#define PM3ByApertureMode_PATCH_OFFSET_X(off)	(((off)&7f)<<9)
+	#define PM3ByApertureMode_PATCH_OFFSET_Y(off)	(((off)&7f)<<16)
+	#define PM3ByApertureMode_FRAMEBUFFER			(0<<21)
+	#define PM3ByApertureMode_LOCALBUFFER			(1<<21)
+	#define PM3ByApertureMode_DOUBLE_WRITE_OFF		(0<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_1MB		(1<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_2MB		(2<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_4MB		(3<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_8MB		(4<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_16MB		(5<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_32MB		(6<<22)
+
+#define PM3ByAperture2Mode					0x0328
+	
+/**********************************************
+*  GLINT Permedia3 Memory Control (0x1000)    *
+***********************************************/
+#define PM3MemCounter						0x1000
+#define PM3MemBypassWriteMask					0x1008
+#define PM3MemScratch						0x1010
+#define PM3LocalMemCaps						0x1018
+        #define PM3LocalMemCaps_NoWriteMask                     (1 << 28)
+#define PM3LocalMemTimings					0x1020
+#define PM3LocalMemControl					0x1028
+#define PM3LocalMemRefresh					0x1030
+#define PM3LocalMemPowerDown					0x1038
+#define PM3RemoteMemControl					0x1100
+
+/**********************************************
+*  GLINT Permedia3 Video Control (0x3000)     *
+***********************************************/
+
+#define PM3ScreenBase						0x3000
+#define PM3ScreenStride						0x3008
+#define PM3HTotal						0x3010
+#define PM3HgEnd						0x3018
+#define PM3HbEnd						0x3020
+#define PM3HsStart						0x3028
+#define PM3HsEnd						0x3030
+#define PM3VTotal						0x3038
+#define PM3VbEnd						0x3040
+#define PM3VsStart						0x3048
+#define PM3VsEnd						0x3050
+#define PM3VideoControl						0x3058
+	#define PM3VideoControl_DISABLE				(0<<0)
+	#define PM3VideoControl_ENABLE				(1<<0)
+	#define PM3VideoControl_BLANK_ACTIVE_HIGH		(0<<1)
+	#define PM3VideoControl_BLANK_ACTIVE_LOW		(1<<1)
+	#define PM3VideoControl_LINE_DOUBLE_OFF			(0<<2)
+	#define PM3VideoControl_LINE_DOUBLE_ON			(1<<2)
+	#define PM3VideoControl_HSYNC_FORCE_HIGH		(0<<3)
+	#define PM3VideoControl_HSYNC_ACTIVE_HIGH		(1<<3)
+	#define PM3VideoControl_HSYNC_FORCE_LOW			(2<<3)
+	#define PM3VideoControl_HSYNC_ACTIVE_LOW		(3<<3)
+        #define PM3VideoControl_HSYNC_MASK          (3<<3)
+	#define PM3VideoControl_VSYNC_FORCE_HIGH		(0<<5)
+	#define PM3VideoControl_VSYNC_ACTIVE_HIGH		(1<<5)
+	#define PM3VideoControl_VSYNC_FORCE_LOW			(2<<5)
+	#define PM3VideoControl_VSYNC_ACTIVE_LOW		(3<<5)
+        #define PM3VideoControl_VSYNC_MASK          (3<<5)
+	#define PM3VideoControl_BYTE_DOUBLE_OFF			(0<<7)
+	#define PM3VideoControl_BYTE_DOUBLE_ON			(1<<7)
+	#define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK	(0<<9)
+	#define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING	(1<<9)
+	#define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE	(2<<9)
+	#define PM3VideoControl_STEREO_DISABLE			(0<<11)
+	#define PM3VideoControl_STEREO_ENABLE			(1<<11)
+	#define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH		(0<<12)
+	#define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW		(1<<12)
+	#define PM3VideoControl_VIDEO_EXT_LOW			(0<<14)
+	#define PM3VideoControl_VIDEO_EXT_HIGH			(1<<14)
+	#define PM3VideoControl_SYNC_MODE_INDEPENDENT		(0<<16)
+	#define PM3VideoControl_SYNC_MODE_SYNCTO_VSA		(1<<16)
+	#define PM3VideoControl_SYNC_MODE_SYNCTO_VSB		(2<<16)
+	#define PM3VideoControl_PATCH_DISABLE			(0<<18)
+	#define PM3VideoControl_PATCH_ENABLE			(1<<18)
+	#define PM3VideoControl_PIXELSIZE_8BIT			(0<<19)
+	#define PM3VideoControl_PIXELSIZE_16BIT			(1<<19)
+	#define PM3VideoControl_PIXELSIZE_32BIT			(2<<19)
+	#define PM3VideoControl_DISPLAY_DISABLE			(0<<21)
+	#define PM3VideoControl_DISPLAY_ENABLE			(1<<21)
+	#define PM3VideoControl_PATCH_OFFSET_X(off)	(((off)&0x3f)<<22)
+	#define PM3VideoControl_PATCH_OFFSET_Y(off)	(((off)&0x3f)<<28)
+#define PM3InterruptLine					0x3060
+#define PM3DisplayData						0x3068
+#define PM3VerticalLineCount					0x3070
+#define PM3FifoControl						0x3078
+#define PM3ScreenBaseRight					0x3080
+#define PM3MiscControl						0x3088
+
+#define PM3VideoOverlayUpdate					0x3100
+        #define PM3VideoOverlayUpdate_DISABLE                   (0<<0)
+        #define PM3VideoOverlayUpdate_ENABLE                    (1<<0)
+#define PM3VideoOverlayMode					0x3108
+	#define PM3VideoOverlayMode_DISABLE			(0<<0)
+	#define PM3VideoOverlayMode_ENABLE			(1<<0)
+        #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL           (0<<1)
+        #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA     (1<<1)
+        #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB     (2<<1)
+        #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL        (0<<4)
+        #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT        (1<<4)
+        #define PM3VideoOverlayMode_PIXELSIZE_8BIT              (0<<5)
+        #define PM3VideoOverlayMode_PIXELSIZE_16BIT             (1<<5)
+        #define PM3VideoOverlayMode_PIXELSIZE_32BIT             (2<<5)
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB565  ((3<<7)|(1<<12)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB332  ((4<<7)|(1<<12)|(0<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR565  ((3<<7)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR332  ((4<<7)|(0<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_CI8     ((5<<7)|(1<<12)|(0<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_VUY444  ((2<<10)|(1<<12)|(2<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_YUV444  ((2<<10)|(2<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_VUY422  ((1<<10)|(1<<12)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_YUV422  ((1<<10)|(1<<5))
+        #define PM3VideoOverlayMode_COLORORDER_BGR              (0<<12)
+        #define PM3VideoOverlayMode_COLORORDER_RGB              (1<<12)
+        #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF          (0<<13)
+        #define PM3VideoOverlayMode_LINEARCOLOREXT_ON           (1<<13)
+        #define PM3VideoOverlayMode_FILTER_MASK                 (3<<14)
+        #define PM3VideoOverlayMode_FILTER_OFF                  (0<<14)
+        #define PM3VideoOverlayMode_FILTER_FULL                 (1<<14)
+        #define PM3VideoOverlayMode_FILTER_PARTIAL              (2<<14)
+        #define PM3VideoOverlayMode_DEINTERLACE_OFF             (0<<16)
+        #define PM3VideoOverlayMode_DEINTERLACE_BOB             (1<<16)
+        #define PM3VideoOverlayMode_PATCHMODE_OFF               (0<<18)
+        #define PM3VideoOverlayMode_PATCHMODE_ON                (1<<18)
+        #define PM3VideoOverlayMode_FLIP_VIDEO                  (0<<20)
+        #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA           (1<<20)
+        #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB           (2<<20)
+        #define PM3VideoOverlayMode_MIRROR_MASK                 (3<<23)
+        #define PM3VideoOverlayMode_MIRRORX_OFF                 (0<<23)
+        #define PM3VideoOverlayMode_MIRRORX_ON                  (1<<23)
+        #define PM3VideoOverlayMode_MIRRORY_OFF                 (0<<24)
+        #define PM3VideoOverlayMode_MIRRORY_ON                  (1<<24)
+#define PM3VideoOverlayFifoControl				0x3110
+#define PM3VideoOverlayIndex					0x3118
+#define PM3VideoOverlayBase0					0x3120
+#define PM3VideoOverlayBase1					0x3128
+#define PM3VideoOverlayBase2					0x3130
+#define PM3VideoOverlayStride					0x3138
+        #define PM3VideoOverlayStride_STRIDE(s)         (((s)&0xfff)<<0)
+#define PM3VideoOverlayWidth                                    0x3140
+        #define PM3VideoOverlayWidth_WIDTH(w)           (((w)&0xfff)<<0)
+#define PM3VideoOverlayHeight                                   0x3148
+        #define PM3VideoOverlayHeight_HEIGHT(h)         (((h)&0xfff)<<0)
+#define PM3VideoOverlayOrigin                                   0x3150
+        #define PM3VideoOverlayOrigin_XORIGIN(x)        (((x)&0xfff)<<0)
+        #define PM3VideoOverlayOrigin_YORIGIN(y)        (((y)&0xfff)<<16)
+#define PM3VideoOverlayShrinkXDelta                             0x3158
+        #define PM3VideoOverlayShrinkXDelta_NONE                (1<<16)
+        #define PM3VideoOverlayShrinkXDelta_DELTA(s,d)          \
+                ((((s)<<16)/(d))&0x0ffffff0)
+#define PM3VideoOverlayZoomXDelta                               0x3160
+        #define PM3VideoOverlayZoomXDelta_NONE                  (1<<16)
+        #define PM3VideoOverlayZoomXDelta_DELTA(s,d)            \
+                ((((s)<<16)/(d))&0x0001fff0)
+#define PM3VideoOverlayYDelta                                   0x3168
+        #define PM3VideoOverlayYDelta_NONE                      (1<<16)
+        #define PM3VideoOverlayYDelta_DELTA(s,d)                        \
+                ((((s)<<16)/(d))&0x0ffffff0)
+#define PM3VideoOverlayFieldOffset				0x3170
+#define PM3VideoOverlayStatus					0x3178
+
+/**********************************************
+*  GLINT Permedia3 RAMDAC Registers (0x4000)  *
+***********************************************/
+/* Direct Registers */
+#define PM3RD_PaletteWriteAddress				0x4000
+#define PM3RD_PaletteData					0x4008
+#define PM3RD_PixelMask						0x4010
+#define PM3RD_PaletteReadAddress				0x4018
+
+#define PM3RD_IndexLow						0x4020
+#define PM3RD_IndexHigh						0x4028
+#define PM3RD_IndexedData					0x4030
+#define PM3RD_IndexControl					0x4038
+	#define PM3RD_IndexControl_AUTOINCREMENT_ENABLE		(1<<0)
+	#define PM3RD_IndexControl_AUTOINCREMENT_DISABLE	(0<<0)
+
+/* Indirect Registers */
+#define PM3RD_MiscControl					0x000
+	#define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE		(0<<0)
+	#define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE		(1<<0)
+	#define PM3RD_MiscControl_PIXELDOUBLE_DISABLE		(0<<1)
+	#define PM3RD_MiscControl_PIXELDOUBLE_ENABLE		(1<<1)
+	#define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE		(0<<2)
+	#define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE		(1<<2)
+	#define PM3RD_MiscControl_DIRECTCOLOR_DISABLE		(0<<3)
+	#define PM3RD_MiscControl_DIRECTCOLOR_ENABLE		(1<<3)
+	#define PM3RD_MiscControl_OVERLAY_DISABLE		(0<<4)
+	#define PM3RD_MiscControl_OVERLAY_ENABLE		(1<<4)
+	#define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE	(0<<5)
+	#define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE	(1<<5)
+	#define PM3RD_MiscControl_VSB_OUTPUT_DISABLE		(0<<6)
+	#define PM3RD_MiscControl_VSB_OUTPUT_ENABLE		(1<<6)
+	#define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE	(0<<7)
+	#define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE	(1<<7)
+#define PM3RD_SyncControl					0x001
+	#define PM3RD_SyncControl_HSYNC_ACTIVE_LOW		(0<<0)
+	#define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH		(1<<0)
+	#define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE		(3<<0)
+	#define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE		(4<<0)
+	#define PM3RD_SyncControl_HSYNC_TRI_STATE		(2<<0)
+	#define PM3RD_SyncControl_VSYNC_ACTIVE_LOW		(0<<3)
+	#define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH		(1<<3)
+	#define PM3RD_SyncControl_VSYNC_TRI_STATE		(2<<3)
+	#define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE		(3<<3)
+	#define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE		(4<<3)
+	#define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC	(0<<6)
+	#define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH	(1<<6)
+	#define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC	(0<<7)
+	#define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH	(1<<7)
+#define PM3RD_DACControl					0x002
+	#define PM3RD_DACControl_DAC_POWER_ON			(0<<0)
+	#define PM3RD_DACControl_DAC_POWER_OFF			(1<<0)
+	#define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE		(0<<3)
+	#define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE		(1<<3)
+	#define PM3RD_DACControl_BLANK_RED_DAC_DISABLE		(0<<4)
+	#define PM3RD_DACControl_BLANK_RED_DAC_ENABLE		(1<<4)
+	#define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE	(0<<5)
+	#define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE		(1<<5)
+	#define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE		(0<<6)
+	#define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE		(1<<6)
+	#define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE		(0<<7)
+	#define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE		(1<<7)
+#define PM3RD_PixelSize						0x003
+	#define PM3RD_PixelSize_24_BIT_PIXELS			(4<<0)
+	#define PM3RD_PixelSize_32_BIT_PIXELS			(2<<0)
+	#define PM3RD_PixelSize_16_BIT_PIXELS			(1<<0)
+	#define PM3RD_PixelSize_8_BIT_PIXELS			(0<<0)
+#define PM3RD_ColorFormat					0x004
+	#define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE	(1<<6)
+	#define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE	(0<<6)
+	#define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW		(1<<5)
+	#define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW		(0<<5)
+	#define PM3RD_ColorFormat_COLOR_FORMAT_MASK		(0x1f<<0)
+	#define PM3RD_ColorFormat_8888_COLOR			(0<<0)
+	#define PM3RD_ColorFormat_5551_FRONT_COLOR		(1<<0)
+	#define PM3RD_ColorFormat_4444_COLOR			(2<<0)
+	#define PM3RD_ColorFormat_332_FRONT_COLOR		(5<<0)
+	#define PM3RD_ColorFormat_332_BACK_COLOR		(6<<0)
+	#define PM3RD_ColorFormat_2321_FRONT_COLOR		(9<<0)
+	#define PM3RD_ColorFormat_2321_BACK_COLOR		(10<<0)
+	#define PM3RD_ColorFormat_232_FRONTOFF_COLOR		(11<<0)
+	#define PM3RD_ColorFormat_232_BACKOFF_COLOR		(12<<0)
+	#define PM3RD_ColorFormat_5551_BACK_COLOR		(13<<0)
+	#define PM3RD_ColorFormat_CI8_COLOR			(14<<0)
+	#define PM3RD_ColorFormat_565_FRONT_COLOR		(16<<0)
+	#define PM3RD_ColorFormat_565_BACK_COLOR		(17<<0)
+#define PM3RD_CursorMode					0x005
+	#define PM3RD_CursorMode_CURSOR_DISABLE			(0<<0)
+	#define PM3RD_CursorMode_CURSOR_ENABLE			(1<<0)
+	#define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123	(0<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0		(1<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1		(2<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2		(3<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3		(4<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01		(5<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23		(6<<2)
+	#define PM3RD_CursorMode_TYPE_MS			(0<<4)
+	#define PM3RD_CursorMode_TYPE_X				(1<<4)
+	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE	(0<<6)
+	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE	(1<<6)
+	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR	(2<<6)
+	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR	(3<<6)
+#define PM3RD_CursorControl					0x006
+	#define PM3RD_CursorControl_DOUBLE_X_DISABLED		(0<<0)
+	#define PM3RD_CursorControl_DOUBLE_X_ENABLED		(1<<0)
+	#define PM3RD_CursorControl_DOUBLE_Y_DISABLED		(0<<1)
+	#define PM3RD_CursorControl_DOUBLE_Y_ENABLED		(1<<1)
+	#define PM3RD_CursorControl_READBACK_POS_DISABLED	(0<<2)
+	#define PM3RD_CursorControl_READBACK_POS_ENABLED	(1<<2)
+
+#define PM3RD_CursorXLow					0x007
+#define PM3RD_CursorXHigh					0x008
+#define PM3RD_CursorYLow					0x009
+#define PM3RD_CursorYHigh					0x00a
+#define PM3RD_CursorHotSpotX					0x00b
+#define PM3RD_CursorHotSpotY					0x00c
+#define PM3RD_OverlayKey					0x00d
+#define PM3RD_Pan						0x00e
+	#define PM3RD_Pan_DISABLE				(0<<0)
+	#define PM3RD_Pan_ENABLE				(1<<0)
+	#define PM3RD_Pan_GATE_DISABLE				(0<<1)
+	#define PM3RD_Pan_GATE_ENABLE				(1<<1)
+#define PM3RD_Sense						0x00f
+
+#define PM3RD_CheckControl					0x018
+	#define PM3RD_CheckControl_PIXEL_DISABLED		(0<<0)
+	#define PM3RD_CheckControl_PIXEL_ENABLED		(1<<0)
+	#define PM3RD_CheckControl_LUT_DISABLED			(0<<1)
+	#define PM3RD_CheckControl_LUT_ENABLED			(1<<1)
+#define PM3RD_CheckPixelRed					0x019
+#define PM3RD_CheckPixelGreen					0x01a
+#define PM3RD_CheckPixelBlue					0x01b
+#define PM3RD_CheckLUTRed					0x01c
+#define PM3RD_CheckLUTGreen					0x01d
+#define PM3RD_CheckLUTBlue					0x01e
+#define PM3RD_Scratch						0x01f
+
+#define PM3RD_VideoOverlayControl				0x020
+        #define PM3RD_VideoOverlayControl_DISABLE               (0<<0)
+        #define PM3RD_VideoOverlayControl_ENABLE                (1<<0)
+        #define PM3RD_VideoOverlayControl_MODE_MASK             (3<<1)
+        #define PM3RD_VideoOverlayControl_MODE_MAINKEY          (0<<1)
+        #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY       (1<<1)
+        #define PM3RD_VideoOverlayControl_MODE_ALWAYS           (2<<1)
+        #define PM3RD_VideoOverlayControl_MODE_BLEND            (3<<1)
+        #define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED  (0<<3)
+        #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED   (1<<3)
+        #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN         (0<<4)
+        #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER     (1<<4)
+        #define PM3RD_VideoOverlayControl_KEY_COLOR             (0<<5)
+        #define PM3RD_VideoOverlayControl_KEY_ALPHA             (1<<5)
+#define PM3RD_VideoOverlayXStartLow				0x021
+#define PM3RD_VideoOverlayXStartHigh				0x022
+#define PM3RD_VideoOverlayYStartLow				0x023
+#define PM3RD_VideoOverlayYStartHigh				0x024
+#define PM3RD_VideoOverlayXEndLow				0x025
+#define PM3RD_VideoOverlayXEndHigh				0x026
+#define PM3RD_VideoOverlayYEndLow				0x027
+#define PM3RD_VideoOverlayYEndHigh				0x028
+#define PM3RD_VideoOverlayKeyR					0x029
+#define PM3RD_VideoOverlayKeyG					0x02a
+#define PM3RD_VideoOverlayKeyB					0x02b
+#define PM3RD_VideoOverlayBlend					0x02c
+        #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT        (0<<6)
+        #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT       (1<<6)
+        #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT       (2<<6)
+        #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT      (3<<6)
+
+#define PM3RD_DClkSetup1					0x1f0
+#define PM3RD_DClkSetup2					0x1f1
+#define PM3RD_KClkSetup1					0x1f2
+#define PM3RD_KClkSetup2					0x1f3
+
+#define PM3RD_DClkControl					0x200
+	#define PM3RD_DClkControl_SOURCE_PLL			(0<<4)
+	#define PM3RD_DClkControl_SOURCE_VSA			(1<<4)
+	#define PM3RD_DClkControl_SOURCE_VSB			(2<<4)
+	#define PM3RD_DClkControl_SOURCE_EXT			(3<<4)
+	#define PM3RD_DClkControl_STATE_RUN			(2<<2)
+	#define PM3RD_DClkControl_STATE_HIGH			(1<<2)
+	#define PM3RD_DClkControl_STATE_LOW			(0<<2)
+	#define PM3RD_DClkControl_LOCKED			(1<<1)
+	#define PM3RD_DClkControl_NOT_LOCKED			(0<<1)
+	#define PM3RD_DClkControl_ENABLE			(1<<0)
+	#define PM3RD_DClkControl_DISABLE			(0<<0)
+#define PM3RD_DClk0PreScale					0x201
+#define PM3RD_DClk0FeedbackScale				0x202
+#define PM3RD_DClk0PostScale					0x203
+        #define PM3_REF_CLOCK                                   14318
+#define PM3RD_DClk1PreScale					0x204
+#define PM3RD_DClk1FeedbackScale				0x205
+#define PM3RD_DClk1PostScale					0x206
+#define PM3RD_DClk2PreScale					0x207
+#define PM3RD_DClk2FeedbackScale				0x208
+#define PM3RD_DClk2PostScale					0x209
+#define PM3RD_DClk3PreScale					0x20a
+#define PM3RD_DClk3FeedbackScale				0x20b
+#define PM3RD_DClk3PostScale					0x20c
+#define PM3RD_KClkControl					0x20d
+	#define PM3RD_KClkControl_DISABLE			(0<<0)
+	#define PM3RD_KClkControl_ENABLE			(1<<0)
+	#define PM3RD_KClkControl_NOT_LOCKED			(0<<1)
+	#define PM3RD_KClkControl_LOCKED			(1<<1)
+	#define PM3RD_KClkControl_STATE_LOW			(0<<2)
+	#define PM3RD_KClkControl_STATE_HIGH			(1<<2)
+	#define PM3RD_KClkControl_STATE_RUN			(2<<2)
+	#define PM3RD_KClkControl_STATE_LOW_POWER		(3<<2)
+	#define PM3RD_KClkControl_SOURCE_PCLK			(0<<4)
+	#define PM3RD_KClkControl_SOURCE_HALF_PCLK		(1<<4)
+	#define PM3RD_KClkControl_SOURCE_PLL			(2<<4)
+#define PM3RD_KClkPreScale					0x20e
+#define PM3RD_KClkFeedbackScale					0x20f
+#define PM3RD_KClkPostScale					0x210
+#define PM3RD_MClkControl					0x211
+	#define PM3RD_MClkControl_DISABLE			(0<<0)
+	#define PM3RD_MClkControl_ENABLE			(1<<0)
+	#define PM3RD_MClkControl_NOT_LOCKED			(0<<1)
+	#define PM3RD_MClkControl_LOCKED			(1<<1)
+	#define PM3RD_MClkControl_STATE_LOW			(0<<2)
+	#define PM3RD_MClkControl_STATE_HIGH			(1<<2)
+	#define PM3RD_MClkControl_STATE_RUN			(2<<2)
+	#define PM3RD_MClkControl_STATE_LOW_POWER		(3<<2)
+	#define PM3RD_MClkControl_SOURCE_PCLK			(0<<4)
+	#define PM3RD_MClkControl_SOURCE_HALF_PCLK		(1<<4)
+	#define PM3RD_MClkControl_SOURCE_HALF_EXT		(3<<4)
+	#define PM3RD_MClkControl_SOURCE_EXT			(4<<4)
+	#define PM3RD_MClkControl_SOURCE_HALF_KCLK		(5<<4)
+	#define PM3RD_MClkControl_SOURCE_KCLK			(6<<4)
+#define PM3RD_MClkPreScale					0x212
+#define PM3RD_MClkFeedbackScale					0x213
+#define PM3RD_MClkPostScale					0x214
+#define PM3RD_SClkControl					0x215
+	#define PM3RD_SClkControl_DISABLE			(0<<0)
+	#define PM3RD_SClkControl_ENABLE			(1<<0)
+	#define PM3RD_SClkControl_NOT_LOCKED			(0<<1)
+	#define PM3RD_SClkControl_LOCKED			(1<<1)
+	#define PM3RD_SClkControl_STATE_LOW			(0<<2)
+	#define PM3RD_SClkControl_STATE_HIGH			(1<<2)
+	#define PM3RD_SClkControl_STATE_RUN			(2<<2)
+	#define PM3RD_SClkControl_STATE_LOW_POWER		(3<<2)
+	#define PM3RD_SClkControl_SOURCE_PCLK			(0<<4)
+	#define PM3RD_SClkControl_SOURCE_HALF_PCLK		(1<<4)
+	#define PM3RD_SClkControl_SOURCE_HALF_EXT		(3<<4)
+	#define PM3RD_SClkControl_SOURCE_EXT			(4<<4)
+	#define PM3RD_SClkControl_SOURCE_HALF_KCLK		(5<<4)
+	#define PM3RD_SClkControl_SOURCE_KCLK			(6<<4)
+#define PM3RD_SClkPreScale					0x216
+#define PM3RD_SClkFeedbackScale					0x217
+#define PM3RD_SClkPostScale					0x218
+
+#define PM3RD_CursorPalette(p)					(0x303+(p))
+#define PM3RD_CursorPattern(p)					(0x400+(p))
+/******************************************************
+*  GLINT Permedia3 Video Streaming Registers (0x5000) *
+*******************************************************/
+
+#define PM3VSConfiguration					0x5800
+
+/**********************************************
+*  GLINT Permedia3 Core Registers (0x8000+)   *
+***********************************************/
+#define PM3AALineWidth						0x94c0
+#define PM3AAPointsize						0x94a0
+#define PM3AlphaBlendAlphaMode					0xafa8
+#define PM3AlphaBlendAlphaModeAnd				0xad30
+#define PM3AlphaBlendAlphaModeOr				0xad38
+#define PM3AlphaBlendColorMode					0xafa0
+#define PM3AlphaBlendColorModeAnd				0xacb0
+#define PM3AlphaBlendColorModeOr				0xacb8
+#define PM3AlphaDestColor					0xaf88
+#define PM3AlphaSourceColor					0xaf80
+#define PM3AlphaTestMode					0x8800
+#define PM3AlphaTestModeAnd					0xabf0
+#define PM3AlphaTestModeOr					0xabf8
+#define PM3AntialiasMode					0x8808
+#define PM3AntialiasModeAnd					0xac00
+#define PM3AntialiasModeOr					0xac08
+/* ... */
+#define PM3BackgroundColor					0xb0c8
+/* ... */
+#define PM3ColorDDAMode						0x87e0
+#define PM3ColorDDAModeAnd					0xabe0
+#define PM3ColorDDAModeOr					0xabe8
+#define PM3CommandInterrupt					0xa990
+#define PM3ConstantColorDDA					0xafb0
+	#define PM3ConstantColorDDA_R(r)		((r)&0xff)
+	#define PM3ConstantColorDDA_G(g)		(((g)&0xff)<<8)
+	#define PM3ConstantColorDDA_B(b)		(((b)&0xff)<<16)
+	#define PM3ConstantColorDDA_A(a)		(((a)&0xff)<<24)
+#define PM3ContextData						0x8dd0
+#define PM3ContextDump						0x8dc0
+#define PM3ContextRestore					0x8dc8
+#define PM3Continue						0x8058
+#define PM3ContinueNewDom					0x8048
+#define PM3ContinueNewLine					0x8040
+#define PM3ContinueNewSub					0x8050
+#define PM3Count						0x8030
+/* ... */
+#define PM3DeltaControl						0x9350
+#define PM3DeltaControlAnd					0xab20
+#define PM3DeltaControlOr					0xab28
+#define PM3DeltaMode						0x9300
+#define PM3DeltaModeAnd						0xaad0
+#define PM3DeltaModeOr						0xaad8
+/* ... */
+#define PM3DitherMode						0x8818
+#define PM3DitherModeAnd					0xacd0
+#define PM3DitherModeOr						0xacd8
+/* ... */
+#define PM3dXDom						0x8008
+#define PM3dXSub						0x8018
+#define PM3dY							0x8028
+/* ... */
+#define PM3FBBlockColor						0x8ac8
+#define PM3FBBlockColor0					0xb060
+#define PM3FBBlockColor1					0xb068
+#define PM3FBBlockColor2					0xb070
+#define PM3FBBlockColor3					0xb078
+#define PM3FBBlockColorBack					0xb0a0
+#define PM3FBBlockColorBack0					0xb080
+#define PM3FBBlockColorBack1					0xb088
+#define PM3FBBlockColorBack2					0xb090
+#define PM3FBBlockColorBack3					0xb098
+#define PM3FBColor						0x8a98
+#define PM3FBDestReadBufferAddr0				0xae80
+#define PM3FBDestReadBufferAddr1				0xae88
+#define PM3FBDestReadBufferAddr2				0xae90
+#define PM3FBDestReadBufferAddr3				0xae98
+#define PM3FBDestReadBufferOffset0				0xaea0
+#define PM3FBDestReadBufferOffset1				0xaea8
+#define PM3FBDestReadBufferOffset2				0xaeb0
+#define PM3FBDestReadBufferOffset3				0xaeb8
+	#define PM3FBDestReadBufferOffset_XOffset(x)	((x)&0xffff)
+	#define PM3FBDestReadBufferOffset_YOffset(y)	(((y)&0xffff)<<16)
+#define PM3FBDestReadBufferWidth0				0xaec0
+#define PM3FBDestReadBufferWidth1				0xaec8
+#define PM3FBDestReadBufferWidth2				0xaed0
+#define PM3FBDestReadBufferWidth3				0xaed8
+	#define PM3FBDestReadBufferWidth_Width(w)	((w)&0x0fff)
+
+#define PM3FBDestReadEnables					0xaee8
+#define PM3FBDestReadEnablesAnd					0xad20
+#define PM3FBDestReadEnablesOr					0xad28
+	#define PM3FBDestReadEnables_E(e)		((e)&0xff)
+	#define PM3FBDestReadEnables_E0				1<<0
+	#define PM3FBDestReadEnables_E1				1<<1
+	#define PM3FBDestReadEnables_E2				1<<2
+	#define PM3FBDestReadEnables_E3				1<<3
+	#define PM3FBDestReadEnables_E4				1<<4
+	#define PM3FBDestReadEnables_E5				1<<5
+	#define PM3FBDestReadEnables_E6				1<<6
+	#define PM3FBDestReadEnables_E7				1<<7
+	#define PM3FBDestReadEnables_R(r)		(((r)&0xff)<<8)
+	#define PM3FBDestReadEnables_R0				1<<8
+	#define PM3FBDestReadEnables_R1				1<<9
+	#define PM3FBDestReadEnables_R2				1<<10
+	#define PM3FBDestReadEnables_R3				1<<11
+	#define PM3FBDestReadEnables_R4				1<<12
+	#define PM3FBDestReadEnables_R5				1<<13
+	#define PM3FBDestReadEnables_R6				1<<14
+	#define PM3FBDestReadEnables_R7				1<<15
+	#define PM3FBDestReadEnables_ReferenceAlpha(a)	(((a)&0xff)<<24)
+
+#define PM3FBDestReadMode					0xaee0
+#define PM3FBDestReadModeAnd					0xac90
+#define PM3FBDestReadModeOr					0xac98
+	#define PM3FBDestReadMode_ReadDisable			0<<0
+	#define PM3FBDestReadMode_ReadEnable			1<<0
+	#define PM3FBDestReadMode_StripePitch(sp)	(((sp)&0x7)<<2
+	#define PM3FBDestReadMode_StripeHeight(sh)	(((sh)&0x7)<<7
+	#define PM3FBDestReadMode_Enable0			1<<8
+	#define PM3FBDestReadMode_Enable1			1<<9
+	#define PM3FBDestReadMode_Enable2			1<<10
+	#define PM3FBDestReadMode_Enable3			1<<11
+	#define PM3FBDestReadMode_Layout0(l)		(((l)&0x3)<<12
+	#define PM3FBDestReadMode_Layout1(l)		(((l)&0x3)<<14
+	#define PM3FBDestReadMode_Layout2(l)		(((l)&0x3)<<16
+	#define PM3FBDestReadMode_Layout3(l)		(((l)&0x3)<<18
+	#define PM3FBDestReadMode_Origin0			1<<20
+	#define PM3FBDestReadMode_Origin1			1<<21
+	#define PM3FBDestReadMode_Origin2			1<<22
+	#define PM3FBDestReadMode_Origin3			1<<23
+	#define PM3FBDestReadMode_Blocking			1<<24
+	#define PM3FBDestReadMode_UseReadEnabled		1<<26
+	#define PM3FBDestReadMode_AlphaFiltering		1<<27
+
+#define PM3FBHardwareWriteMask					0x8ac0
+#define PM3FBSoftwareWriteMask					0x8820
+#define PM3FBData						0x8aa0
+#define PM3FBSourceData						0x8aa8
+#define PM3FBSourceReadBufferAddr				0xaf08
+#define PM3FBSourceReadBufferOffset				0xaf10
+	#define PM3FBSourceReadBufferOffset_XOffset(x)	((x)&0xffff)
+	#define PM3FBSourceReadBufferOffset_YOffset(y)	(((y)&0xffff)<<16)
+#define PM3FBSourceReadBufferWidth				0xaf18
+	#define PM3FBSourceReadBufferWidth_Width(w)	((w)&0x0fff)
+#define PM3FBSourceReadMode					0xaf00
+#define PM3FBSourceReadModeAnd					0xaca0
+#define PM3FBSourceReadModeOr					0xaca8
+	#define PM3FBSourceReadMode_ReadDisable			(0<<0)
+	#define PM3FBSourceReadMode_ReadEnable			(1<<0)
+	#define PM3FBSourceReadMode_StripePitch(sp)	(((sp)&0x7)<<2
+	#define PM3FBSourceReadMode_StripeHeight(sh)	(((sh)&0x7)<<7
+	#define PM3FBSourceReadMode_Layout(l)		(((l)&0x3)<<8
+	#define PM3FBSourceReadMode_Origin			1<<10
+	#define PM3FBSourceReadMode_Blocking			1<<11
+	#define PM3FBSourceReadMode_UserTexelCoord		1<<13
+	#define PM3FBSourceReadMode_WrapXEnable			1<<14
+	#define PM3FBSourceReadMode_WrapYEnable			1<<15
+	#define PM3FBSourceReadMode_WrapX(w)		(((w)&0xf)<<16
+	#define PM3FBSourceReadMode_WrapY(w)		(((w)&0xf)<<20
+	#define PM3FBSourceReadMode_ExternalSourceData		1<<24
+#define PM3FBWriteBufferAddr0                                   0xb000
+#define PM3FBWriteBufferAddr1                                   0xb008
+#define PM3FBWriteBufferAddr2                                   0xb010
+#define PM3FBWriteBufferAddr3                                   0xb018
+
+#define PM3FBWriteBufferOffset0                                 0xb020
+#define PM3FBWriteBufferOffset1                                 0xb028
+#define PM3FBWriteBufferOffset2                                 0xb030
+#define PM3FBWriteBufferOffset3                                 0xb038
+	#define PM3FBWriteBufferOffset_XOffset(x)		((x)&0xffff)
+	#define PM3FBWriteBufferOffset_YOffset(y)		(((y)&0xffff)<<16)
+
+#define PM3FBWriteBufferWidth0                                  0xb040
+#define PM3FBWriteBufferWidth1                                  0xb048
+#define PM3FBWriteBufferWidth2                                  0xb050
+#define PM3FBWriteBufferWidth3                                  0xb058
+	#define PM3FBWriteBufferWidth_Width(w)			((w)&0x0fff)
+
+#define PM3FBWriteMode                                          0x8ab8
+#define PM3FBWriteModeAnd                                       0xacf0
+#define PM3FBWriteModeOr                                        0xacf8
+	#define PM3FBWriteMode_WriteDisable                     0<<0
+	#define PM3FBWriteMode_WriteEnable                      1<<0
+	#define PM3FBWriteMode_Replicate                        1<<4
+	#define PM3FBWriteMode_OpaqueSpan                       1<<5
+	#define PM3FBWriteMode_StripePitch(p)            (((p)&0x7)<<6)
+	#define PM3FBWriteMode_StripeHeight(h)           (((h)&0x7)<<9)
+	#define PM3FBWriteMode_Enable0                          1<<12
+	#define PM3FBWriteMode_Enable1                          1<<13
+	#define PM3FBWriteMode_Enable2                          1<<14
+	#define PM3FBWriteMode_Enable3                          1<<15
+	#define PM3FBWriteMode_Layout0(l)               (((l)&0x3)<<16)
+	#define PM3FBWriteMode_Layout1(l)               (((l)&0x3)<<18)
+	#define PM3FBWriteMode_Layout2(l)               (((l)&0x3)<<20)
+	#define PM3FBWriteMode_Layout3(l)               (((l)&0x3)<<22)
+	#define PM3FBWriteMode_Origin0                          1<<24
+	#define PM3FBWriteMode_Origin1                          1<<25
+	#define PM3FBWriteMode_Origin2                          1<<26
+	#define PM3FBWriteMode_Origin3                          1<<27
+#define PM3ForegroundColor					0xb0c0
+/* ... */
+#define PM3GIDMode						0xb538
+#define PM3GIDModeAnd						0xb5b0
+#define PM3GIDModeOr						0xb5b8
+/* ... */
+#define PM3LBDestReadBufferAddr					0xb510
+#define PM3LBDestReadBufferOffset				0xb518
+#define PM3LBDestReadEnables					0xb508
+#define PM3LBDestReadEnablesAnd					0xb590
+#define PM3LBDestReadEnablesOr					0xb598
+#define PM3LBDestReadMode					0xb500
+#define PM3LBDestReadModeAnd					0xb580
+#define PM3LBDestReadModeOr					0xb588
+	#define PM3LBDestReadMode_Disable			0<<0
+	#define PM3LBDestReadMode_Enable			1<<0
+	#define PM3LBDestReadMode_StripePitch(p)		(((p)&0x7)<<2)
+	#define PM3LBDestReadMode_StripeHeight(h)		(((h)&0x7)<<5)
+	#define PM3LBDestReadMode_Layout			1<<8
+	#define PM3LBDestReadMode_Origin			1<<9
+	#define PM3LBDestReadMode_UserReadEnables		1<<10
+	#define PM3LBDestReadMode_Packed16			1<<11
+	#define PM3LBDestReadMode_Width(w)			(((w)&0xfff)<<12)
+#define PM3LBReadFormat						0x8888
+	#define PM3LBReadFormat_DepthWidth(w)			(((w)&0x3)<<0)
+	#define PM3LBReadFormat_StencilWidth(w)			(((w)&0xf)<<2)
+	#define PM3LBReadFormat_StencilPosition(p)		(((p)&0x1f)<<6)
+	#define PM3LBReadFormat_FCPWidth(w)			(((w)&0xf)<<11)
+	#define PM3LBReadFormat_FCPPosition(p)			(((p)&0x1f)<<15)
+	#define PM3LBReadFormat_GIDWidth(w)			(((w)&0x7)<<20)
+	#define PM3LBReadFormat_GIDPosition(p)			(((p)&0x1f)<<23)
+#define PM3LBSourceReadBufferAddr				0xb528
+#define PM3LBSourceReadBufferOffset				0xb530
+#define PM3LBSourceReadMode					0xb520
+#define PM3LBSourceReadModeAnd					0xb5a0
+#define PM3LBSourceReadModeOr					0xb5a8
+	#define PM3LBSourceReadMode_Enable			1<<0
+	#define PM3LBSourceReadMode_StripePitch(p)		(((p)&0x7)<<2)
+	#define PM3LBSourceReadMode_StripeHeight(h)		(((h)&0x7)<<5)
+	#define PM3LBSourceReadMode_Layout			1<<8
+	#define PM3LBSourceReadMode_Origin			1<<9
+	#define PM3LBSourceReadMode_Packed16			1<<10
+	#define PM3LBSourceReadMode_Width(w)			(((w)&0xfff)<<11)
+#define PM3LBStencil						0x88a8
+#define PM3LBWriteBufferAddr					0xb540
+#define PM3LBWriteBufferOffset					0xb548
+#define PM3LBWriteFormat					0x88c8
+	#define PM3LBWriteFormat_DepthWidth(w)			(((w)&0x3)<<0)
+	#define PM3LBWriteFormat_StencilWidth(w)		(((w)&0xf)<<2)
+	#define PM3LBWriteFormat_StencilPosition(p)		(((p)&0x1f)<<6)
+	#define PM3LBWriteFormat_GIDWidth(w)			(((w)&0x7)<<20)
+	#define PM3LBWriteFormat_GIDPosition(p)			(((p)&0x1f)<<23)
+#define PM3LBWriteMode						0x88c0
+#define PM3LBWriteModeAnd					0xac80
+#define PM3LBWriteModeOr					0xac88
+	#define PM3LBWriteMode_WriteDisable			0<<0
+	#define PM3LBWriteMode_WriteEnable			1<<0
+	#define PM3LBWriteMode_StripePitch(p)			(((p)&0x7)<<3)
+	#define PM3LBWriteMode_StripeHeight(h)			(((h)&0x7)<<6)
+	#define PM3LBWriteMode_Layout				1<<9
+	#define PM3LBWriteMode_Origin				1<<10
+	#define PM3LBWriteMode_Packed16				1<<11
+	#define PM3LBWriteMode_Width(w)				(((w)&0xfff)<<12)
+/* ... */
+#define PM3LineStippleMode					0x81a8
+#define PM3LineStippleModeAnd					0xabc0
+#define PM3LineStippleModeOr					0xabc8
+#define PM3LoadLineStippleCounters				0x81b0
+/* ... */
+#define PM3LogicalOpMode					0x8828
+#define PM3LogicalOpModeAnd					0xace0
+#define PM3LogicalOpModeOr					0xace8
+	#define PM3LogicalOpMode_Disable			(0<<0)
+	#define PM3LogicalOpMode_Enable				(1<<0)
+	#define PM3LogicalOpMode_LogicOp(op)			(((op)&0xf)<<1)
+	#define PM3LogicalOpMode_UseConstantWriteData_Disable	(0<<5)
+	#define PM3LogicalOpMode_UseConstantWriteData_Enable	(1<<5)
+	#define PM3LogicalOpMode_Background_Disable		(0<<6)
+	#define PM3LogicalOpMode_Background_Enable		(1<<6)
+	#define PM3LogicalOpMode_Background_LogicOp(op)		(((op)&0xf)<<7)
+	#define PM3LogicalOpMode_UseConstantSource_Disable	(0<<11)
+	#define PM3LogicalOpMode_UseConstantSource_Enable	(1<<11)
+
+/* ... */
+#define PM3LUT							0x8e80
+/* ... */
+#define PM3LUT							0x8e80
+#define PM3LUTAddress						0x84d0
+#define PM3LUTData						0x84c8
+#define PM3LUTIndex						0x84c0
+#define PM3LUTMode						0xb378
+#define PM3LUTModeAnd						0xad70
+#define PM3LUTModeOr						0xad78
+#define PM3LUTTransfer						0x84d8
+/* ... */
+#define PM3PixelSize						0x80c0
+	#define PM3PixelSize_GLOBAL_32BIT			(0<<0)
+	#define PM3PixelSize_GLOBAL_16BIT			(1<<0)
+	#define PM3PixelSize_GLOBAL_8BIT			(2<<0)
+	#define PM3PixelSize_RASTERIZER_32BIT			(0<<2)
+	#define PM3PixelSize_RASTERIZER_16BIT			(1<<2)
+	#define PM3PixelSize_RASTERIZER_8BIT			(2<<2)
+	#define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT		(0<<4)
+	#define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT		(1<<4)
+	#define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT		(2<<4)
+	#define PM3PixelSize_TEXTURE_32BIT			(0<<6)
+	#define PM3PixelSize_TEXTURE_16BIT			(1<<6)
+	#define PM3PixelSize_TEXTURE_8BIT			(2<<6)
+	#define PM3PixelSize_LUT_32BIT				(0<<8)
+	#define PM3PixelSize_LUT_16BIT				(1<<8)
+	#define PM3PixelSize_LUT_8BIT				(2<<8)
+	#define PM3PixelSize_FRAMEBUFFER_32BIT			(0<<10)
+	#define PM3PixelSize_FRAMEBUFFER_16BIT			(1<<10)
+	#define PM3PixelSize_FRAMEBUFFER_8BIT			(2<<10)
+	#define PM3PixelSize_LOGICAL_OP_32BIT			(0<<12)
+	#define PM3PixelSize_LOGICAL_OP_16BIT			(1<<12)
+	#define PM3PixelSize_LOGICAL_OP_8BIT			(2<<12)
+	#define PM3PixelSize_LOCALBUFFER_32BIT			(0<<14)
+	#define PM3PixelSize_LOCALBUFFER_16BIT			(1<<14)
+	#define PM3PixelSize_LOCALBUFFER_8BIT			(2<<14)
+	#define PM3PixelSize_SETUP_32BIT			(0<<16)
+	#define PM3PixelSize_SETUP_16BIT			(1<<16)
+	#define PM3PixelSize_SETUP_8BIT				(2<<16)
+	#define PM3PixelSize_GLOBAL				(0<<31)
+	#define PM3PixelSize_INDIVIDUAL				(1<<31)
+/* ... */
+#define PM3Render						0x8038
+	#define PM3Render_AreaStipple_Disable			(0<<0)
+	#define PM3Render_AreaStipple_Enable			(1<<0)
+	#define PM3Render_LineStipple_Disable			(0<<1)
+	#define PM3Render_LineStipple_Enable			(1<<1)
+	#define PM3Render_ResetLine_Disable			(0<<2)
+	#define PM3Render_ResetLine_Enable			(1<<2)
+	#define PM3Render_FastFill_Disable			(0<<3)
+	#define PM3Render_FastFill_Enable			(1<<3)
+	#define PM3Render_Primitive_Line			(0<<6)
+	#define PM3Render_Primitive_Trapezoid			(1<<6)
+	#define PM3Render_Primitive_Point			(2<<6)
+	#define PM3Render_Antialias_Disable			(0<<8)
+	#define PM3Render_Antialias_Enable			(1<<8)
+	#define PM3Render_Antialias_SubPixelRes_4x4		(0<<9)
+	#define PM3Render_Antialias_SubPixelRes_8x8		(1<<9)
+	#define PM3Render_UsePointTable_Disable			(0<<10)
+	#define PM3Render_UsePointTable_Enable			(1<<10)
+	#define PM3Render_SyncOnbitMask_Disable			(0<<11)
+	#define PM3Render_SyncOnBitMask_Enable			(1<<11)
+	#define PM3Render_SyncOnHostData_Disable		(0<<12)
+	#define PM3Render_SyncOnHostData_Enable			(1<<12)
+	#define PM3Render_Texture_Disable			(0<<13)
+	#define PM3Render_Texture_Enable			(1<<13)
+	#define PM3Render_Fog_Disable				(0<<14)
+	#define PM3Render_Fog_Enable				(1<<14)
+	#define PM3Render_Coverage_Disable			(0<<15)
+	#define PM3Render_Coverage_Enable			(1<<15)
+	#define PM3Render_SubPixelCorrection_Disable		(0<<16)
+	#define PM3Render_SubPixelCorrection_Enable		(1<<16)
+	#define PM3Render_SpanOperation_Disable			(0<<18)
+	#define PM3Render_SpanOperation_Enable			(1<<18)
+	#define PM3Render_FBSourceRead_Disable			(0<<27)
+	#define PM3Render_FBSourceRead_Enable			(1<<27)
+#define PM3RasterizerMode					0x80a0
+#define PM3RasterizerModeAnd					0xaba0
+#define PM3RasterizerModeOr					0xabb8
+#define PM3RectangleHeight					0x94e0
+#define PM3Render						0x8038
+#define PM3RepeatLine						0x9328
+#define PM3ResetPickResult					0x8c20
+#define PM3RLEMask						0x8c48
+#define PM3RouterMode						0x8840
+#define PM3RStart						0x8780
+#define PM3S1Start						0x8400
+#define PM3aveLineStippleCounters				0x81c0
+#define PM3ScissorMaxXY						0x8190
+#define PM3ScissorMinXY						0x8188
+#define PM3ScissorMode						0x8180
+#define PM3ScissorModeAnd					0xabb0
+#define PM3ScissorModeOr					0xabb8
+#define PM3ScreenSize						0x8198
+#define PM3Security						0x8908
+#define PM3SetLogicalTexturePage				0xb360
+#define PM3SizeOfFramebuffer					0xb0a8
+#define PM3SStart						0x8388
+#define PM3StartXDom						0x8000
+#define PM3StartXSub						0x8010
+#define PM3StartY						0x8020
+/* ... */
+#define PM3SpanColorMask					0x8168
+/* ... */
+#define PM3TextureApplicationMode				0x8680
+#define PM3TextureApplicationModeAnd				0xac50
+#define PM3TextureApplicationModeOr				0xac58
+#define PM3TextureBaseAddr					0x8500
+#define PM3TextureCacheControl					0x8490
+#define PM3TextureChromaLower0					0x84f0
+#define PM3TextureChromaLower1					0x8608
+#define PM3TextureChromaUpper0					0x84e8
+#define PM3TextureChromaUpper1					0x8600
+#define PM3TextureCompositeAlphaMode0				0xb310
+#define PM3TextureCompositeAlphaMode0And			0xb390
+#define PM3TextureCompositeAlphaMode0Or				0xb398
+#define PM3TextureCompositeAlphaMode1				0xb320
+#define PM3TextureCompositeAlphaMode1And			0xb3b0
+#define PM3TextureCompositeAlphaMode1Or				0xb3b8
+#define PM3TextureCompositeColorMode0				0xb308
+#define PM3TextureCompositeColorMode0And			0xb380
+#define PM3TextureCompositeColorMode0Or				0xb388
+#define PM3TextureCompositeColorMode1				0xb318
+#define PM3TextureCompositeColorMode1And			0xb3a0
+#define PM3TextureCompositeColorMode1Or				0xb3a8
+#define PM3TextureCompositeFactor0				0xb328
+#define PM3TextureCompositeFactor1				0xb330
+#define PM3TextureCompositeMode					0xb300
+#define PM3TextureCoordMode					0x8380
+#define PM3TextureCoordModeAnd					0xac20
+#define PM3TextureCoordModeOr					0xac28
+#define PM3TextureData						0x88e8
+/*
+#define PM3TextureDownloadControl				0x0108
+*/
+#define PM3TextureDownloadOffset				0x88f0
+#define PM3TextureEnvColor					0x8688
+#define PM3TextureFilterMode					0x84e0
+#define PM3TextureFilterModeAnd					0xad50
+#define PM3TextureFilterModeOr					0xad58
+#define PM3TextureIndexMode0					0xb338
+#define PM3TextureIndexMode0And					0xb3c0
+#define PM3TextureIndexMode0Or					0xb3c8
+#define PM3TextureIndexMode1					0xb340
+#define PM3TextureIndexMode1And					0xb3d0
+#define PM3TextureIndexMode1Or					0xb3d8
+/* ... */
+#define PM3TextureMapSize                                       0xb428
+#define PM3TextureMapWidth0                                     0x8580
+#define PM3TextureMapWidth1                                     0x8588
+        #define PM3TextureMapWidth_Width(w)             ((w&0xfff)<<0)
+        #define PM3TextureMapWidth_BorderLayout                 (1<<12)
+        #define PM3TextureMapWidth_Layout_Linear                (0<<13)
+        #define PM3TextureMapWidth_Layout_Patch64               (1<<13)
+        #define PM3TextureMapWidth_Layout_Patch32_2             (2<<13)
+        #define PM3TextureMapWidth_Layout_Patch2                (3<<13)
+        #define PM3TextureMapWidth_HostTexture                  (1<<15)
+#define PM3TextureReadMode0                                     0xb400
+#define PM3TextureReadMode0And                                  0xac30
+#define PM3TextureReadMode0Or                                   0xac38
+#define PM3TextureReadMode1                                     0xb408
+#define PM3TextureReadMode1And                                  0xad40
+#define PM3TextureReadMode1Or                                   0xad48
+/* ... */
+#define PM3WaitForCompletion					0x80b8
+#define PM3Window						0x8980
+	#define PM3Window_ForceLBUpdate				1<<3
+	#define PM3Window_LBUpdateSource			1<<4
+	#define PM3Window_FrameCount(c)				(((c)&0xff)<<9
+	#define PM3Window_StencilFCP				1<<17
+	#define PM3Window_DepthFCP				1<<18
+	#define PM3Window_OverrideWriteFiltering		1<<19
+#define PM3WindowAnd						0xab80
+#define PM3WindowOr						0xab88
+#define PM3WindowOrigin						0x81c8
+#define PM3XBias						0x9480
+#define PM3YBias						0x9488
+#define PM3YLimits						0x80a8
+#define PM3UVMode						0x8f00
+#define PM3ZFogBias						0x86b8
+#define PM3ZStart						0xadd8
+#define PM3ZStartL						0x89b8
+#define PM3ZStartU						0x89b0
+
+
+/**********************************************
+*  GLINT Permedia3 2D setup Unit              *
+***********************************************/
+#define PM3Config2D						0xb618
+	#define PM3Config2D_OpaqueSpan				1<<0
+	#define PM3Config2D_MultiRXBlit				1<<1
+	#define PM3Config2D_UserScissorEnable			1<<2
+	#define PM3Config2D_FBDestReadEnable			1<<3
+	#define PM3Config2D_AlphaBlendEnable			1<<4
+	#define PM3Config2D_DitherEnable			1<<5
+	#define PM3Config2D_ForegroundROPEnable			1<<6
+	#define PM3Config2D_ForegroundROP(rop)		(((rop)&0xf)<<7)
+	#define PM3Config2D_BackgroundROPEnable			1<<11
+	#define PM3Config2D_BackgroundROP(rop)		(((rop)&0xf)<<12)
+	#define PM3Config2D_UseConstantSource			1<<16
+	#define PM3Config2D_FBWriteEnable			1<<17
+	#define PM3Config2D_Blocking				1<<18
+	#define PM3Config2D_ExternalSourceData			1<<19
+	#define PM3Config2D_LUTModeEnable			1<<20
+#define PM3DownloadGlyphwidth					0xb658
+	#define PM3DownloadGlyphwidth_GlyphWidth(gw)	((gw)&0xffff)
+#define PM3DownloadTarget					0xb650
+	#define PM3DownloadTarget_TagName(tag)		((tag)&0x1fff)
+#define PM3GlyphData						0xb660
+#define PM3GlyphPosition					0xb608
+	#define PM3GlyphPosition_XOffset(x)		((x)&0xffff)
+	#define PM3GlyphPosition_YOffset(y)		(((y)&0xffff)<<16)
+#define PM3Packed4Pixels					0xb668
+#define PM3Packed8Pixels					0xb630
+#define PM3Packed16Pixels					0xb638
+#define PM3RectanglePosition					0xb600
+	#define PM3RectanglePosition_XOffset(x)		((x)&0xffff)
+	#define PM3RectanglePosition_YOffset(y)		(((y)&0xffff)<<16)
+#define PM3Render2D						0xb640
+	#define PM3Render2D_Width(w)			((w)&0x0fff)
+	#define PM3Render2D_Operation_Normal			0<<12
+	#define PM3Render2D_Operation_SyncOnHostData		1<<12
+	#define PM3Render2D_Operation_SyncOnBitMask		2<<12
+	#define PM3Render2D_Operation_PatchOrderRendering	3<<12
+	#define PM3Render2D_FBSourceReadEnable			1<<14
+	#define PM3Render2D_SpanOperation			1<<15
+	#define PM3Render2D_Height(h)			(((h)&0x0fff)<<16)
+	#define PM3Render2D_XPositive				1<<28
+	#define PM3Render2D_YPositive				1<<29
+	#define PM3Render2D_AreaStippleEnable			1<<30
+	#define PM3Render2D_TextureEnable			1<<31
+#define PM3Render2DGlyph					0xb648
+	#define PM3Render2DGlyph_Width(w)		((w)&0x7f)
+	#define PM3Render2DGlyph_Height(h)		(((h)&0x7f)<<7)
+	#define PM3Render2DGlyph_XOffset(x)		(((x)&0x1ff)<<14)
+	#define PM3Render2DGlyph_YOffset(y)		(((y)&0x1ff)<<23)
+#define PM3RenderPatchOffset					0xb610
+	#define PM3RenderPatchOffset_XOffset(x)		((x)&0xffff)
+	#define PM3RenderPatchOffset_YOffset(y)		(((y)&0xffff)<<16)
+#define PM3RLCount						0xb678
+	#define PM3RLCount_Count(c)			((c)&0x0fff)
+#define PM3RLData						0xb670
+
+/**********************************************
+*  GLINT Permedia3 Alias Register             *
+***********************************************/
+#define PM3FillBackgroundColor                                  0x8330
+#define PM3FillConfig2D0                                        0x8338
+#define PM3FillConfig2D1                                        0x8360
+	#define PM3FillConfig2D_OpaqueSpan                      1<<0
+	#define PM3FillConfig2D_MultiRXBlit                     1<<1
+	#define PM3FillConfig2D_UserScissorEnable               1<<2
+	#define PM3FillConfig2D_FBDestReadEnable                1<<3
+	#define PM3FillConfig2D_AlphaBlendEnable                1<<4
+	#define PM3FillConfig2D_DitherEnable                    1<<5
+	#define PM3FillConfig2D_ForegroundROPEnable             1<<6
+	#define PM3FillConfig2D_ForegroundROP(rop)              (((rop)&0xf)<<7)
+	#define PM3FillConfig2D_BackgroundROPEnable             1<<11
+	#define PM3FillConfig2D_BackgroundROP(rop)              (((rop)&0xf)<<12)
+	#define PM3FillConfig2D_UseConstantSource               1<<16
+	#define PM3FillConfig2D_FBWriteEnable                   1<<17
+	#define PM3FillConfig2D_Blocking                        1<<18
+	#define PM3FillConfig2D_ExternalSourceData              1<<19
+	#define PM3FillConfig2D_LUTModeEnable                   1<<20
+#define PM3FillFBDestReadBufferAddr                             0x8310
+#define PM3FillFBSourceReadBufferAddr                           0x8308
+#define PM3FillFBSourceReadBufferOffset                         0x8340
+	#define PM3FillFBSourceReadBufferOffset_XOffset(x)     ((x)&0xffff)
+	#define PM3FillFBSourceReadBufferOffset_YOffset(y)      (((y)&0xffff)<<16)
+#define PM3FillFBWriteBufferAddr                                0x8300
+#define PM3FillForegroundColor0                                 0x8328
+#define PM3FillForegroundColor1                                 0x8358
+#define PM3FillGlyphPosition                                    0x8368
+        #define PM3FillGlyphPosition_XOffset(x)                        ((x)&0xffff)
+	#define PM3FillGlyphPosition_YOffset(y)                        (((y)&0xffff)<<16)
+#define PM3FillRectanglePosition                                0x8348
+	#define PM3FillRectanglePosition_XOffset(x)            ((x)&0xffff)
+	#define PM3FillRectanglePosition_YOffset(y)            (((y)&0xffff)<<16)
+
+#define PM3_REGS_SIZE           0x10000
+#define PM3_MAX_PIXCLOCK        300000
+/* a few more useful registers & regs value... */
+#define PM3Sync 0x8c40
+        #define PM3Sync_Tag 0x188
+#define PM3FilterMode 0x8c00
+        #define PM3FilterModeSync 0x400
+#define PM3OutputFifo 0x2000
+#define PM3StatisticMode 0x8c08
+#define PM3AreaStippleMode 0x81a0
+        #define AreaStipplePattern0					(0x8200)
+        #define AreaStipplePattern1					(0x8208)
+        #define AreaStipplePattern2					(0x8210)
+        #define AreaStipplePattern3					(0x8218)
+        #define AreaStipplePattern4					(0x8220)
+        #define AreaStipplePattern5					(0x8228)
+        #define AreaStipplePattern6					(0x8230)
+        #define AreaStipplePattern7					(0x8238)
+        #define AreaStipplePattern8					(0x8240)
+        #define AreaStipplePattern9					(0x8248)
+        #define AreaStipplePattern10					(0x8250)
+        #define AreaStipplePattern11					(0x8258)
+        #define AreaStipplePattern12					(0x8260)
+        #define AreaStipplePattern13					(0x8268)
+        #define AreaStipplePattern14					(0x8270)
+        #define AreaStipplePattern15					(0x8278)
+        #define AreaStipplePattern16					(0x8280)
+        #define AreaStipplePattern17					(0x8288)
+        #define AreaStipplePattern18					(0x8290)
+        #define AreaStipplePattern19					(0x8298)
+        #define AreaStipplePattern20					(0x82a0)
+        #define AreaStipplePattern21					(0x82a8)
+        #define AreaStipplePattern22					(0x82b0)
+        #define AreaStipplePattern23					(0x82b8)
+        #define AreaStipplePattern24					(0x82c0)
+        #define AreaStipplePattern25					(0x82c8)
+        #define AreaStipplePattern26					(0x82d0)
+        #define AreaStipplePattern27					(0x82d8)
+        #define AreaStipplePattern28					(0x82eo)
+        #define AreaStipplePattern29					(0x82e8)
+        #define AreaStipplePattern30					(0x82f0)
+        #define AreaStipplePattern31					(0x82f8)
+        #define AreaStipplePattern_indexed(i)             (0x8200 + ((i) * 0x8))
+
+#define PM3DepthMode 0x89a0
+#define PM3StencilMode 0x8988
+#define PM3StencilData 0x8990
+#define PM3TextureReadMode 0x8670
+#define PM3FogMode 0x8690
+#define PM3ChromaTestMode 0x8f18
+#define PM3YUVMode 0x8f00
+#define PM3BitMaskPattern 0x8068
+
+/* ***************************** */
+/* ***** pm3fb IOCTL const ***** */
+/* ***************************** */
+/* debug-only IOCTL */
+#define PM3FBIO_CLEARMEMORY 0x504D3300 /* 'PM3\000' */
+#define PM3FBIO_CLEARCMAP   0x504D3301 /* 'PM3\001' */
+/* common use IOCTL */
+#define PM3FBIO_RESETCHIP   0x504D33FF /* 'PM3\377' */
+
+/* ***************************************** */
+/* ***** pm3fb useful define and macro ***** */
+/* ***************************************** */
+
+/* kernel -specific definitions */
+/* what kernel is this ? */
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)))
+#define KERNEL_2_5
+#endif
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)))
+#define KERNEL_2_4
+#endif
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))) 
+#define KERNEL_2_2
+/* pci_resource_start, available in 2.2.18 */
+#include <linux/kcomp.h>
+#ifdef CONFIG_FB_OF
+#define SUPPORT_FB_OF
+#endif
+#endif
+
+#if (!defined(KERNEL_2_2)) && (!defined(KERNEL_2_4)) && (!defined(KERNEL_2_5))
+#error "Only kernel 2.2.x, kernel 2.4.y and kernel 2.5.z might work"
+#endif
+
+/* not sure if/why it's needed. doesn't work without on my PowerMac... */
+#ifdef __BIG_ENDIAN
+#define MUST_BYTESWAP
+#endif
+
+/* for compatibility between 2.5, 2.4 and 2.2 */
+#ifndef B_FREE
+#define B_FREE   -1
+#endif
+
+/* permedia3 -specific definitions */
+#define PM3_SCALE_TO_CLOCK(pr, fe, po) ((2 * PM3_REF_CLOCK * fe) / (pr * (1 << (po))))
+#define PICOS2KHZ(a) (1000000000UL/(a))
+#define KHZ2PICOS(a) (1000000000UL/(a))
+
+/* in case it's not in linux/pci.h */
+#ifndef PCI_DEVICE_ID_3DLABS_PERMEDIA3
+#define PCI_DEVICE_ID_3DLABS_PERMEDIA3 0x000a
+#endif
+
+/* max number of simultaneous board */
+/* warning : make sure module array def's are coherent with PM3_MAX_BOARD */
+#define PM3_MAX_BOARD 4
+#define PM3_MAX_BOARD_MODULE_ARRAY_SHORT "1-4h"
+#define PM3_MAX_BOARD_MODULE_ARRAY_STRING "1-4s"
+
+/* max size of options */
+#define PM3_OPTIONS_SIZE 256
+
+/* max size of font name */
+#define PM3_FONTNAME_SIZE 40
+
+/* do we want accelerated console  */
+#define PM3FB_USE_ACCEL 1
+
+/* useful ? */
+#define CHAR_IS_NUM(a)  ((((a) >= '0') && ((a) <= '9')) ? 1 : 0)
+
+/* for driver debugging ONLY */
+/* 0 = assert only, 1 = error, 2 = info, 3+ = verbose */
+/* define PM3FB_MASTER_DEBUG 1 */
+#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 3)
+#define PM3FB_TRACE
+#endif /* defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 3) */
+
+#ifdef PM3FB_MASTER_DEBUG
+#define DPRINTK(l,a,b...) do { if ((l) <= PM3FB_MASTER_DEBUG) printk("pm3fb: %s: " a, __FUNCTION__ , ## b); } while (0)
+#define DASSERT(t,a,b...) do { if (!(t)) printk("pm3fb: _assert failed: %s: " a, __FUNCTION__ , ## b); } while (0)
+#ifdef PM3FB_TRACE
+#define DTRACE printk("pm3fb: _enter %s\n", __FUNCTION__)
+#else /* PM3FB_TRACE */
+#define DTRACE
+#endif /* PM3FB_TRACE */
+#else /* PM3FB_MASTER_DEBUG */
+#define DPRINTK(l,a,b...)
+#define DASSERT(t,a,b...)
+#define DTRACE
+#endif /* PM3FB_MASTER_DEBUG */
+
+#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)
+#define PM3_SHOW_CUR_MODE pm3fb_show_cur_mode(l_fb_info)
+#else
+#define PM3_SHOW_CUR_MODE /* pm3fb_show_cur_mode() */
+#endif
+
+/* ******************************************** */
+/* ***** A bunch of register-access macro ***** */
+/* ******************************************** */
+#ifdef KERNEL_2_2
+#ifdef MUST_BYTESWAP /* we are writing big_endian to big_endian through a little_endian macro */
+#define PM3_READ_REG(r) __swab32(readl((l_fb_info->vIOBase + r)))
+#define PM3_WRITE_REG(r, v) writel(__swab32(v), (l_fb_info->vIOBase + r))
+#else /* MUST_BYTESWAP */
+#define PM3_WRITE_REG(r, v) writel(v, (l_fb_info->vIOBase + r))
+#define PM3_READ_REG(r) readl((l_fb_info->vIOBase + r))
+#endif /* MUST_BYTESWAP */
+#endif /* KERNEL_2_2 */
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5) /* native-endian access */
+#define PM3_WRITE_REG(r, v) fb_writel(v, (l_fb_info->vIOBase + r))
+#define PM3_READ_REG(r) fb_readl((l_fb_info->vIOBase + r))
+#endif /* KERNEL_2_4 or KERNEL_2_5 */
+
+
+#define depth2bpp(d) ((d + 7L) & ~7L)
+#define depth2ByPP(d) (depth2bpp(d) / 8)
+
+#define depth_supported(d) ((d == 8) || (d == 12) || (d == 15) || (d == 16) || (d==32))
+
+
+#define PM3_WAIT(n) \
+do{ \
+	while(PM3_READ_REG(PM3InFIFOSpace)<(n)); \
+} while(0)
+
+#define PM3_DELAY(x) do { \
+        int delay = x; \
+        unsigned char tmp; \
+        while(delay--){tmp = PM3_READ_REG(PM3InFIFOSpace);}; \
+} while(0)
+
+#define PM3_SLOW_WRITE_REG(r,v)	\
+do{                             \
+    DASSERT((l_fb_info->vIOBase != (unsigned char*)(-1)), "l_fb_info->vIOBase mapped in slow write\n"); \
+	mb();                   \
+	PM3_WAIT(1);            \
+	mb();                   \
+    PM3_WRITE_REG(r,v);     \
+} while(0)
+
+#define PM3_SET_INDEX(index) \
+do{ \
+	PM3_SLOW_WRITE_REG(PM3RD_IndexHigh,(((index)>>8)&0xff)); \
+	PM3_SLOW_WRITE_REG(PM3RD_IndexLow,((index)&0xff)); \
+} while(0)
+
+#define PM3_WRITE_DAC_REG(r, v) \
+do { \
+     DASSERT((l_fb_info->vIOBase != (unsigned char*)(-1)), "l_fb_info->vIOBase mapped in write dac reg\n"); \
+     PM3_SET_INDEX(r); \
+     mb(); \
+     PM3_WRITE_REG(PM3RD_IndexedData, v); \
+} while (0)
+
+/* next one is really a function, added as a macro to be consistent */
+#define PM3_READ_DAC_REG(r) pm3fb_read_dac_reg(l_fb_info, r)
+
+
+#define PM3_COLOR(c) \
+do { \
+  if (l_fb_info->current_par->depth == 8) \
+    { \
+      c = (c & 0xFF); \
+      c = c | (c << 8); \
+    } \
+  if ((l_fb_info->current_par->depth == 8) || (depth2bpp(l_fb_info->current_par->depth) == 16)) \
+    { \
+      c = (c & 0xFFFF); \
+      c = c | (c << 16); \
+    } \
+} while (0)
+
+#endif PM3FB_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/pmag-ba-fb.c linux/drivers/video/pmag-ba-fb.c
--- linux.orig/drivers/video/pmag-ba-fb.c	2001-09-14 21:04:07.000000000 +0000
+++ linux/drivers/video/pmag-ba-fb.c	2002-07-20 01:08:40.000000000 +0000
@@ -91,7 +91,7 @@
 };
 
 static int currcon = 0;
-struct pmagbafb_par current_par;
+static struct pmagbafb_par current_par;
 
 static void pmagbafb_encode_var(struct fb_var_screeninfo *var,
 				struct pmagbafb_par *par)
@@ -324,7 +324,7 @@
 	display->next_line = fix.line_length;
 	display->can_soft_blank = 0;
 	display->inverse = 0;
-
+	display->scrollmode = SCROLL_YREDRAW;
 	display->dispsw = &fbcon_cfb8;
 }
 
@@ -425,9 +425,4 @@
 	}
 }
 
-int __init pmagbafb_setup(char *options)
-{
-	return 0;
-}
-
 MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/pmagb-b-fb.c linux/drivers/video/pmagb-b-fb.c
--- linux.orig/drivers/video/pmagb-b-fb.c	2001-09-14 21:04:07.000000000 +0000
+++ linux/drivers/video/pmagb-b-fb.c	2002-07-20 01:08:23.000000000 +0000
@@ -94,7 +94,7 @@
 };
 
 static int currcon = 0;
-struct pmagbbfb_par current_par;
+static struct pmagbbfb_par current_par;
 
 static void pmagbbfb_encode_var(struct fb_var_screeninfo *var,
 				struct pmagbbfb_par *par)
@@ -327,7 +327,7 @@
 	display->next_line = fix.line_length;
 	display->can_soft_blank = 0;
 	display->inverse = 0;
-
+	display->scrollmode = SCROLL_YREDRAW;
 	display->dispsw = &fbcon_cfb8;
 }
 
@@ -428,9 +428,4 @@
 	}
 }
 
-int __init pmagbbfb_setup(char *options)
-{
-	return 0;
-}
-
 MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/radeonfb.c linux/drivers/video/radeonfb.c
--- linux.orig/drivers/video/radeonfb.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/radeonfb.c	2002-07-20 01:08:40.000000000 +0000
@@ -1778,7 +1778,7 @@
                 
         /* use highest possible virtual resolution */
         if (v->xres_virtual == -1 && v->yres_virtual == -1) {
-                printk("radeonfb: using max availabe virtual resolution\n");
+                printk("radeonfb: using max available virtual resolution\n");
                 for (i=0; modes[i].xres != -1; i++) {
                         if (modes[i].xres * nom / den * modes[i].yres <
                             rinfo->video_ram / 2)
@@ -1855,7 +1855,7 @@
 	if (noaccel)
 	        fix->accel = FB_ACCEL_NONE;
 	else
-		fix->accel = 40;	/* XXX */
+		fix->accel = FB_ACCEL_ATI_RADEON;
         
         return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/riva/accel.c linux/drivers/video/riva/accel.c
--- linux.orig/drivers/video/riva/accel.c	2001-10-15 20:47:13.000000000 +0000
+++ linux/drivers/video/riva/accel.c	2002-07-20 01:08:37.000000000 +0000
@@ -67,6 +67,8 @@
 	rinfo->riva.Blt->TopLeftSrc  = (sy << 16) | sx;
 	rinfo->riva.Blt->TopLeftDst  = (dy << 16) | dx;
 	rinfo->riva.Blt->WidthHeight = (height  << 16) | width;
+
+	wait_for_idle(rinfo);
 }
 
 static void riva_clear_margins(struct vc_data *conp, struct display *p,
@@ -108,9 +110,9 @@
 static inline void fbcon_reverse_order(u32 *l)
 {
 	u8 *a = (u8 *)l;
-	*a++ = byte_rev[*a];
-/*	*a++ = byte_rev[*a];
-	*a++ = byte_rev[*a];*/
+	*a = byte_rev[*a], a++;
+/*	*a = byte_rev[*a], a++;
+	*a = byte_rev[*a], a++;*/
 	*a = byte_rev[*a];
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/riva/fbdev.c linux/drivers/video/riva/fbdev.c
--- linux.orig/drivers/video/riva/fbdev.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/riva/fbdev.c	2002-07-20 01:08:27.000000000 +0000
@@ -55,7 +55,7 @@
 
 
 /* version number of this driver */
-#define RIVAFB_VERSION "0.9.2a"
+#define RIVAFB_VERSION "0.9.3"
 
 
 
@@ -1309,9 +1309,6 @@
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 	sprintf(fix->id, "nVidia %s", rivainfo->drvr_name);
 
-	fix->smem_start = rivainfo->fb_base_phys;
-	fix->smem_len = rivainfo->ram_amount;
-
 	fix->type = p->type;
 	fix->type_aux = p->type_aux;
 	fix->visual = p->visual;
@@ -1325,7 +1322,7 @@
 	fix->mmio_start = rivainfo->ctrl_base_phys;
 	fix->mmio_len = rivainfo->base0_region_size;
 	fix->smem_start = rivainfo->fb_base_phys;
-	fix->smem_len = rivainfo->base1_region_size;
+	fix->smem_len = rivainfo->ram_amount;
 
 	switch (rivainfo->riva.Architecture) {
 	case NV_ARCH_03:
@@ -1883,9 +1880,6 @@
 	rinfo->base0_region_size = pci_resource_len(pd, 0);
 	rinfo->base1_region_size = pci_resource_len(pd, 1);
 
-	assert(rinfo->base0_region_size >= 0x00800000);	/* from GGI */
-	assert(rinfo->base1_region_size >= 0x01000000);	/* from GGI */
-
 	rinfo->ctrl_base_phys = pci_resource_start(rinfo->pd, 0);
 	rinfo->fb_base_phys = pci_resource_start(rinfo->pd, 1);
 
@@ -1895,12 +1889,6 @@
 		goto err_out_kfree;
 	}
 
-	if (!request_mem_region(rinfo->fb_base_phys,
-				rinfo->base1_region_size, "rivafb")) {
-		printk(KERN_ERR PFX "cannot reserve FB region\n");
-		goto err_out_free_base0;
-	}
-	
 	rinfo->ctrl_base = ioremap(rinfo->ctrl_base_phys,
 				   rinfo->base0_region_size);
 	if (!rinfo->ctrl_base) {
@@ -1908,27 +1896,6 @@
 		goto err_out_free_base1;
 	}
 	
-	rinfo->fb_base = ioremap(rinfo->fb_base_phys,
-				 rinfo->base1_region_size);
-	if (!rinfo->fb_base) {
-		printk(KERN_ERR PFX "cannot ioremap FB base\n");
-		goto err_out_iounmap_ctrl;
-	}
-	
-#ifdef CONFIG_MTRR
-	if (!nomtrr) {
-		rinfo->mtrr.vram = mtrr_add(rinfo->fb_base_phys,
-					    rinfo->base1_region_size, MTRR_TYPE_WRCOMB, 1);
-		if (rinfo->mtrr.vram < 0) {
-			printk(KERN_ERR PFX "unable to setup MTRR\n");
-		} else {
-			rinfo->mtrr.vram_valid = 1;
-			/* let there be speed */
-			printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
-		}
-	}
-#endif /* CONFIG_MTRR */
-
 	rinfo->riva.EnableIRQ = 0;
 	rinfo->riva.PRAMDAC = (unsigned *)(rinfo->ctrl_base + 0x00680000);
 	rinfo->riva.PFB = (unsigned *)(rinfo->ctrl_base + 0x00100000);
@@ -1945,6 +1912,26 @@
 
 	rinfo->riva.IO = (MISCin(rinfo) & 0x01) ? 0x3D0 : 0x3B0;
 
+	if (rinfo->riva.Architecture == NV_ARCH_03) {
+		/*
+		 * We have to map the full BASE_1 aperture for Riva128's
+		 * because they use the PRAMIN set in "framebuffer" space
+		 */
+		if (!request_mem_region(rinfo->fb_base_phys,
+					rinfo->base1_region_size, "rivafb")) {
+			printk(KERN_ERR PFX "cannot reserve FB region\n");
+			goto err_out_free_base0;
+		}
+	
+		rinfo->fb_base = ioremap(rinfo->fb_base_phys,
+					 rinfo->base1_region_size);
+		if (!rinfo->fb_base) {
+			printk(KERN_ERR PFX "cannot ioremap FB base\n");
+			goto err_out_iounmap_ctrl;
+		}
+	}
+
+
 	switch (rinfo->riva.Architecture) {
 	case NV_ARCH_03:
 		rinfo->riva.PRAMIN = (unsigned *)(rinfo->fb_base + 0x00C00000);
@@ -1959,9 +1946,42 @@
 
 	RivaGetConfig(&rinfo->riva);
 
-	/* back to normal */
+	rinfo->ram_amount = rinfo->riva.RamAmountKBytes * 1024;
+	rinfo->dclk_max = rinfo->riva.MaxVClockFreqKHz * 1000;
 
-	assert(rinfo->pd != NULL);
+	if (rinfo->riva.Architecture != NV_ARCH_03) {
+		/*
+		 * Now the _normal_ chipsets can just map the amount of
+		 * real physical ram instead of the whole aperture
+		 */
+		if (!request_mem_region(rinfo->fb_base_phys,
+					rinfo->ram_amount, "rivafb")) {
+			printk(KERN_ERR PFX "cannot reserve FB region\n");
+			goto err_out_free_base0;
+		}
+	
+		rinfo->fb_base = ioremap(rinfo->fb_base_phys,
+					 rinfo->ram_amount);
+		if (!rinfo->fb_base) {
+			printk(KERN_ERR PFX "cannot ioremap FB base\n");
+			goto err_out_iounmap_ctrl;
+		}
+	}
+
+#ifdef CONFIG_MTRR
+	if (!nomtrr) {
+		rinfo->mtrr.vram = mtrr_add(rinfo->fb_base_phys,
+					    rinfo->ram_amount,
+					    MTRR_TYPE_WRCOMB, 1);
+		if (rinfo->mtrr.vram < 0) {
+			printk(KERN_ERR PFX "unable to setup MTRR\n");
+		} else {
+			rinfo->mtrr.vram_valid = 1;
+			/* let there be speed */
+			printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
+		}
+	}
+#endif /* CONFIG_MTRR */
 
 	/* unlock io */
 	CRTCout(rinfo, 0x11, 0xFF);	/* vgaHWunlock() + riva unlock (0x7F) */
@@ -1969,9 +1989,6 @@
 
 	riva_save_state(rinfo, &rinfo->initial_state);
 
-	rinfo->ram_amount = rinfo->riva.RamAmountKBytes * 1024;
-	rinfo->dclk_max = rinfo->riva.MaxVClockFreqKHz * 1000;
-
 	if (!nohwcursor) rinfo->cursor = rivafb_init_cursor(rinfo);
 
 	if (riva_set_fbinfo(rinfo) < 0) {
@@ -1990,7 +2007,7 @@
 	pci_set_drvdata(pd, rinfo);
 
 	printk(KERN_INFO PFX
-		"PCI nVidia NV%d framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
+		"PCI nVidia NV%x framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
 		rinfo->riva.Architecture,
 		RIVAFB_VERSION,
 		rinfo->drvr_name,
@@ -2035,7 +2052,7 @@
 #ifdef CONFIG_MTRR
 	if (board->mtrr.vram_valid)
 		mtrr_del(board->mtrr.vram, board->fb_base_phys,
-			 board->base1_region_size);
+			 board->ram_amount);
 #endif /* CONFIG_MTRR */
 
 	iounmap(board->ctrl_base);
@@ -2044,7 +2061,7 @@
 	release_mem_region(board->ctrl_base_phys,
 			   board->base0_region_size);
 	release_mem_region(board->fb_base_phys,
-			   board->base1_region_size);
+			   board->ram_amount);
 
 	kfree(board);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sgivwfb.c linux/drivers/video/sgivwfb.c
--- linux.orig/drivers/video/sgivwfb.c	2001-11-14 22:52:20.000000000 +0000
+++ linux/drivers/video/sgivwfb.c	2002-07-20 01:08:36.000000000 +0000
@@ -846,7 +846,6 @@
     return -EINVAL;
   offset += sgivwfb_mem_phys;
   pgprot_val(vma->vm_page_prot) = pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
-  vma->vm_flags |= VM_IO;
   if (remap_page_range(vma->vm_start, offset, size, vma->vm_page_prot))
     return -EAGAIN;
   vma->vm_file = file;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/300vtbl.h linux/drivers/video/sis/300vtbl.h
--- linux.orig/drivers/video/sis/300vtbl.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/300vtbl.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,4 +1,8 @@
-typedef struct _SiS300_StStruct {
+
+/* Comments and changes marked with "TW" by Thomas Winischhofer <thomas@winischhofer.net> */
+
+typedef struct _SiS300_StStruct
+{
 	UCHAR St_ModeID;
 	USHORT St_ModeFlag;
 	UCHAR St_StTableIndex;
@@ -8,32 +12,33 @@
 	UCHAR VB_StTVEdgeIndex;
 	UCHAR VB_StTVYFilterIndex;
 } SiS300_StStruct;
-
-SiS300_StStruct SiS300_SModeIDTable[] =
+SiS300_StStruct  SiS300_SModeIDTable[]=
 {
-	{0x01, 0x9208, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x01, 0x1210, 0x14, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0x01, 0x1010, 0x17, 0x02, 0x02, 0x00, 0x00, 0x00},
-	{0x03, 0x8208, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x03, 0x0210, 0x16, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0x03, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x00, 0x00},
-	{0x05, 0x9209, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x06, 0x8209, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x07, 0x0000, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00},
-	{0x07, 0x0000, 0x19, 0x02, 0x02, 0x00, 0x00, 0x00},
-	{0x0d, 0x920a, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x0e, 0x820a, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x0f, 0x0202, 0x11, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0x10, 0x0212, 0x12, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0x11, 0x0212, 0x1a, 0x04, 0x04, 0x00, 0x00, 0x00},
-	{0x12, 0x0212, 0x1b, 0x04, 0x04, 0x00, 0x00, 0x00},
-	{0x13, 0x021b, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x12, 0x0210, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x12, 0x0210, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00},
-	{0xff, 0, 0, 0, 0, 0, 0, 0}
+	{0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00},
+	{0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00},
+	{0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00},
+	{0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00},
+	{0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
+	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00},
+	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00},
+	{0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00},
+	{0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00},
+	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00},
+	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00},
+	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00},
+	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00},
+	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00},
+	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00},
+	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00},
+	/* {0x12,0x0210,0x18,0x00,0x00,0x00,0x00,0x00}, */  /* <--- Different in BIOS */
+	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
+	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00},
+	{0xff,0,0,0,0,0,0,0}
 };
 
-typedef struct _SiS300_StandTableStruct {
+typedef struct _SiS300_StandTableStruct
+{
 	UCHAR CRT_COLS;
 	UCHAR ROWS;
 	UCHAR CHAR_HEIGHT;
@@ -45,362 +50,364 @@
 	UCHAR GRC[9];
 } SiS300_StandTableStruct;
 
-SiS300_StandTableStruct SiS300_StandTable[] = {
-	{0x28, 0x18, 0x08, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x28, 0x18, 0x08, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x50, 0x18, 0x08, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x50, 0x18, 0x08, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x28, 0x18, 0x08, 0x4000,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
-	  0xff},
-	 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x03, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00,
-	  0xff}},
-	{0x28, 0x18, 0x08, 0x4000,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
-	  0xff},
-	 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x03, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00,
-	  0xff}},
-	{0x50, 0x18, 0x08, 0x4000,
-	 {0x01, 0x01, 0x00, 0x06},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
-	  0xff},
-	 {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-	  0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-	  0x01, 0x00, 0x01, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
-	  0xff}},
-	{0x50, 0x18, 0x0e, 0x1000,
-	 {0x00, 0x03, 0x00, 0x03},
-	 0xa6,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x0d, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	  0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	  0x0e, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
-	  0xff}},
+SiS300_StandTableStruct  SiS300_StandTable[]=
+{ /* TW: @ 0x38d4 in BIOS */
+ {0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff} },
+ {0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff} },
+ {0x50,0x18,0x08,0x4000,
+  {0x01,0x01,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+   0xff},
+  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x01,0x00,0x01,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+   0xff} },
+ {0x50,0x18,0x0e,0x1000,
+  {0x00,0x03,0x00,0x03},
+  0xa6,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff} },
 /* MDA_DAC*/
-	{0x00, 0x00, 0x00, 0x0000,
-	 {0x00, 0x00, 0x00, 0x15},
-	 0x15,
-	 {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f,
-	  0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x00,
-	  0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15},
-	 {0x15, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x3f}},
+ {0x00,0x00,0x00,0x0000,
+  {0x00,0x00,0x00,0x15},
+  0x15,
+  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15},
+  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f} },
 /* CGA_DAC*/
-	{0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x09, 0x15, 0x00},
-	 0x10,
-	 {0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a,
-	  0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x2a, 0x3a,
-	  0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x10,
-	  0x04},
-	 {0x14, 0x01, 0x11, 0x09, 0x15, 0x00, 0x10, 0x04,
-	  0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a, 0x2e,
-	  0x3e, 0x2b, 0x3b, 0x2f},
-	 {0x3f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f,
-	  0x3f}},
+ {0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x00},
+  0x10,
+  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+   0x04},
+  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+   0x3e,0x2b,0x3b,0x2f},
+  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f} },
 /* EGA_DAC*/
-	{0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x05, 0x15, 0x20},
-	 0x30,
-	 {0x24, 0x34, 0x21, 0x31, 0x25, 0x35, 0x08, 0x18,
-	  0x0c, 0x1c, 0x09, 0x19, 0x0d, 0x1d, 0x28, 0x38,
-	  0x2c, 0x3c, 0x29, 0x39, 0x2d, 0x3d, 0x02, 0x12,
-	  0x06},
-	 {0x16, 0x03, 0x13, 0x07, 0x17, 0x22, 0x32, 0x26,
-	  0x36, 0x23, 0x33, 0x27, 0x37, 0x0a, 0x1a, 0x0e,
-	  0x1e, 0x0b, 0x1b, 0x0f},
-	 {0x1f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f,
-	  0x3f}},
+ {0x00,0x10,0x04,0x0114,
+  {0x11,0x05,0x15,0x20},
+  0x30,
+  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+   0x06},
+  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+   0x1e,0x0b,0x1b,0x0f},
+  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f} },
 /* VGA_DAC*/
-	{0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x09, 0x15, 0x2a},
-	 0x3a,
-	 {0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x05,
-	  0x08, 0x0b, 0x0e, 0x11, 0x14, 0x18, 0x1c, 0x20,
-	  0x24, 0x28, 0x2d, 0x32, 0x38, 0x3f, 0x00, 0x10,
-	  0x1f},
-	 {0x2f, 0x3f, 0x1f, 0x27, 0x2f, 0x37, 0x3f, 0x2d,
-	  0x31, 0x36, 0x3a, 0x3f, 0x00, 0x07, 0x0e, 0x15,
-	  0x1c, 0x0e, 0x11, 0x15},
-	 {0x18, 0x1c, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x00,
-	  0x04}},
-	{0x08, 0x0c, 0x10, 0x0a08,
-	 {0x0c, 0x0e, 0x10, 0x0b},
-	 0x0c,
-	 {0x0d, 0x0f, 0x10, 0x10, 0x01, 0x08, 0x00, 0x00,
-	  0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x00,
-	  0x04, 0x04, 0x01, 0x00, 0x05, 0x02, 0x05, 0x00,
-	  0x06},
-	 {0x01, 0x06, 0x05, 0x06, 0x00, 0x08, 0x01, 0x08,
-	  0x00, 0x07, 0x02, 0x07, 0x06, 0x07, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00}},
-	{0x28, 0x18, 0x08, 0x2000,
-	 {0x09, 0x0f, 0x00, 0x06},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}},
-	{0x50, 0x18, 0x08, 0x4000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}},
-	{0x00, 0x00, 0x00, 0x0000,
-	 {0x01, 0x0f, 0x00, 0x0e},
-	 0x23,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-	  0x01, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
-	  0xff}},
-	{0x4a, 0x36, 0x00, 0x00c0,
-	 {0x00, 0x00, 0x00, 0x00},
-	 0x00,
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3a,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x1a, 0x00, 0x57, 0x39, 0x00, 0xc0,
-	  0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00}},
-	{0x50, 0x18, 0x0e, 0x8000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xa2,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
-	  0xff},
-	 {0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
-	  0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
-	  0x0b, 0x00, 0x05, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05,
-	  0xff}},
-	{0x50, 0x18, 0x0e, 0x8000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}},
-	{0x28, 0x18, 0x0e, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x28, 0x18, 0x0e, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x50, 0x18, 0x0e, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x50, 0x18, 0x0e, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x28, 0x18, 0x10, 0x0800,
-	 {0x08, 0x03, 0x00, 0x02},
-	 0x67,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x0c, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x50, 0x18, 0x10, 0x1000,
-	 {0x00, 0x03, 0x00, 0x02},
-	 0x67,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x0c, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}},
-	{0x50, 0x18, 0x10, 0x1000,
-	 {0x00, 0x03, 0x00, 0x02},
-	 0x66,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	  0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	  0x0e, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
-	  0xff}},
-	{0x50, 0x1d, 0x10, 0xa000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xe3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3,
-	  0xff},
-	 {0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01,
-	  0xff}},
-	{0x50, 0x1d, 0x10, 0xa000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xe3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}},
-	{0x28, 0x18, 0x08, 0x2000,
-	 {0x01, 0x0f, 0x00, 0x0e},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
-	  0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-	  0x41, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
-	  0xff}}
+ {0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x2a},
+  0x3a,
+  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+   0x1f},
+  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+   0x1c,0x0e,0x11,0x15},
+  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+   0x04} },
+ {0x08,0x0c,0x10,0x0a08,
+  {0x0c,0x0e,0x10,0x0b},
+  0x0c,
+  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+   0x06},
+  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00} },
+ {0x28,0x18,0x08,0x2000,
+  {0x09,0x0f,0x00,0x06},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff} },
+ {0x50,0x18,0x08,0x4000,
+  {0x01,0x0f,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff} },
+ {0x00,0x00,0x00,0x0000,	/* TW: Standtable for VGA modes */
+  {0x01,0x0f,0x00,0x0e},	/*    (identical to BIOS) */
+  0x23,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x01,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff} },
+ {0x4a,0x36,0x00,0x00c0,
+  {0x00,0x00,0x00,0x00},
+  0x00,
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00} },
+ {0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa2,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+   0xff},
+  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+   0x0b,0x00,0x05,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+   0xff} },
+ {0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff} },
+ {0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x28,0x18,0x10,0x0800,
+  {0x08,0x03,0x00,0x02},
+  0x67,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x67,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff} },
+ {0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x66,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff} },
+ {0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+   0xff},
+  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+   0xff} },
+ {0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff} },
+ {0x28,0x18,0x08,0x2000,
+  {0x01,0x0f,0x00,0x0e},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x41,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff} }
 };
 
-typedef struct _SiS300_ExtStruct {
+typedef struct _SiS300_ExtStruct
+{
 	UCHAR Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
@@ -413,502 +420,566 @@
 	UCHAR VB_ExtTVYFilterIndex;
 	UCHAR REFindex;
 } SiS300_ExtStruct;
-SiS300_ExtStruct SiS300_EModeIDTable[] = {
-	{0x6a, 0x2212, 0x47, 0x3563, 0x0102, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{0x2e, 0x0a1b, 0x36, 0x3539, 0x0101, 0x08, 0x06, 0x00, 0x00, 0x00, 0x08},
-	{0x2f, 0x021b, 0x35, 0x3532, 0x0100, 0x08, 0x05, 0x00, 0x00, 0x00, 0x10},
-	{0x30, 0x2a1b, 0x47, 0x3563, 0x0103, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{0x31, 0x0a1b, 0xad, 0x3630, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x11},
-	{0x32, 0x2a1b, 0xae, 0x3637, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x00, 0x12},
-	{0x33, 0x0a1d, 0xad, 0x3630, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x11},
-	{0x34, 0x2a1d, 0xae, 0x3637, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x00, 0x12},
-	{0x35, 0x0a1f, 0xad, 0x3630, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x11},
-	{0x36, 0x2a1f, 0xae, 0x3637, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x00, 0x12},
-	{0x37, 0x0212, 0x58, 0x358d, 0x0104, 0x08, 0x08, 0x00, 0x00, 0x00, 0x13},
-	{0x38, 0x0a1b, 0x58, 0x358d, 0x0105, 0x08, 0x08, 0x00, 0x00, 0x00, 0x13},
-	{0x3a, 0x0e3b, 0x69, 0x35be, 0x0107, 0x08, 0x09, 0x00, 0x00, 0x00, 0x1a},
-	{0x3c, 0x063b, 0x7a, 0x35d4, 0x0130, 0x08, 0x0a, 0x00, 0x00, 0x00, 0x1e},
-	{0x3d, 0x067d, 0x7a, 0x35d4, 0x0131, 0x08, 0x0a, 0x00, 0x00, 0x00, 0x1e},
-	{0x40, 0x921c, 0x00, 0x3516, 0x010d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x23},
-	{0x41, 0x921d, 0x00, 0x3516, 0x010e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x23},
-	{0x43, 0x0a1c, 0x36, 0x3539, 0x0110, 0x08, 0x06, 0x00, 0x00, 0x00, 0x08},
-	{0x44, 0x0a1d, 0x36, 0x3539, 0x0111, 0x08, 0x06, 0x00, 0x00, 0x00, 0x08},
-	{0x46, 0x2a1c, 0x47, 0x3563, 0x0113, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{0x47, 0x2a1d, 0x47, 0x3563, 0x0114, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{0x49, 0x0a3c, 0x58, 0x358d, 0x0116, 0x08, 0x08, 0x00, 0x00, 0x00, 0x13},
-	{0x4a, 0x0a3d, 0x58, 0x358d, 0x0117, 0x08, 0x08, 0x00, 0x00, 0x00, 0x13},
-	{0x4c, 0x0e7c, 0x69, 0x35be, 0x0119, 0x08, 0x09, 0x00, 0x00, 0x00, 0x1a},
-	{0x4d, 0x0e7d, 0x69, 0x35be, 0x011a, 0x08, 0x09, 0x00, 0x00, 0x00, 0x1a},
-	{0x50, 0x921b, 0x01, 0x351d, 0x0132, 0x08, 0x01, 0x00, 0x00, 0x00, 0x24},
-	{0x51, 0x921b, 0x13, 0x3524, 0x0133, 0x08, 0x03, 0x00, 0x00, 0x00, 0x25},
-	{0x52, 0x921b, 0x24, 0x352b, 0x0134, 0x08, 0x04, 0x00, 0x00, 0x00, 0x26},
-	{0x56, 0x921d, 0x01, 0x351d, 0x0135, 0x08, 0x01, 0x00, 0x00, 0x00, 0x24},
-	{0x57, 0x921d, 0x13, 0x3524, 0x0136, 0x08, 0x03, 0x00, 0x00, 0x00, 0x25},
-	{0x58, 0x921d, 0x24, 0x352b, 0x0137, 0x08, 0x04, 0x00, 0x00, 0x00, 0x26},
-	{0x59, 0x921b, 0x00, 0x3516, 0x0138, 0x08, 0x00, 0x00, 0x00, 0x00, 0x23},
-	{0x5d, 0x021d, 0x35, 0x3532, 0x0139, 0x08, 0x05, 0x00, 0x00, 0x00, 0x10},
-	{0x62, 0x0a3f, 0x36, 0x3539, 0x013a, 0x08, 0x06, 0x00, 0x00, 0x00, 0x08},
-	{0x63, 0x2a3f, 0x47, 0x3563, 0x013b, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00},
-	{0x64, 0x0a7f, 0x58, 0x358d, 0x013c, 0x08, 0x08, 0x00, 0x00, 0x00, 0x13},
-	{0x65, 0x0eff, 0x69, 0x35be, 0x013d, 0x08, 0x09, 0x00, 0x00, 0x00, 0x1a},
-	{0x66, 0x06ff, 0x7a, 0x35d4, 0x013e, 0x08, 0x0a, 0x00, 0x00, 0x00, 0x1e},
-	{0x68, 0x067b, 0x8b, 0x35ef, 0x013f, 0x08, 0x0b, 0x00, 0x00, 0x00, 0x27},
-	{0x69, 0x06fd, 0x8b, 0x35ef, 0x0140, 0x08, 0x0b, 0x00, 0x00, 0x00, 0x27},
-	{0x6b, 0x07ff, 0x8b, 0x35ef, 0x0000, 0x10, 0x0b, 0x00, 0x00, 0x00, 0x27},
-	{0x6c, 0x067b, 0x9c, 0x35f6, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x28},
-	{0x6d, 0x06fd, 0x9c, 0x35f6, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x28},
-	{0x6e, 0x0e3b, 0x6f, 0x35b2, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x29},
-	{0x6f, 0x0e7d, 0x6f, 0x35b2, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x29},
-	{0x7b, 0x0eff, 0x6f, 0x35b2, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x29},
-	{0x7c, 0x221b, 0xb3, 0x363e, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x2b},
-	{0x7d, 0x221d, 0xb3, 0x363e, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x2b},
-	{0x7e, 0x223f, 0xb3, 0x363e, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x2b},
-	{0xff, 0x0000, 0x00, 0x0000, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+SiS300_ExtStruct  SiS300_EModeIDTable[]=
+{ /* TW: Table is identical to BIOS */		/* TW: BIOS offset to Ext2Struct: */
+ {0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
+ {0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */ /* 8bpp bug? */
+ /* {0x2e,0x021b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},  */ /* 37c3 */
+ {0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10},  /* 37bc */
+ {0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */ /* 8bpp bug? */
+ /* {0x30,0x221b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00}, */ /* 37ed */
+ {0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */
+ {0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */
+ {0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */
+ {0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */
+ {0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */
+ {0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */
+ {0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
+ {0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */ /* 8bpp bug? */
+ /* {0x38,0x021b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13}, */ /* 3817 */
+ {0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */ /* 8bpp bug? */
+ /* {0x3a,0x063b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, */ /* 3848 */
+ {0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
+ {0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
+ {0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
+ {0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
+ {0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
+ {0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
+ {0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
+ {0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
+ {0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
+ {0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
+ {0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
+ {0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
+ {0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},  /* 37a7 */
+ {0x51,0x921b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25},  /* 37ae */
+ {0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},  /* 37b5 */
+ {0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},  /* 37a7 */
+ {0x57,0x921d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25},  /* 37ae */
+ {0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},  /* 37b5 */
+ {0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
+ {0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10},  /* 37bc */
+ {0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
+ {0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
+ {0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
+ {0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
+ {0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
+ {0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
+ {0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
+ {0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
+ {0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x0c,0x00,0x00,0x00,0x28},  /* 3880 */
+ {0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x0c,0x00,0x00,0x00,0x28},  /* 3880 */
+ {0x6e,0x0e3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */
+ {0x6f,0x0e7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */
+ {0x7b,0x0eff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */
+ {0x7c,0x221b,0xb3,0x363e,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},  /* 38c8 */
+ {0x7d,0x221d,0xb3,0x363e,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},  /* 38c8 */
+ {0x7e,0x223f,0xb3,0x363e,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},  /* 38c8 */
+ {0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS300_Ext2Struct {
+typedef struct _SiS300_Ext2Struct
+{
 	USHORT Ext_InfoFlag;
-	UCHAR Ext_CRT1CRTC;
+	UCHAR Ext_CRT1CRTC;  /* TW: Index in SiS300_CRT1Table */
 	UCHAR Ext_CRTVCLK;
-	UCHAR Ext_CRT2CRTC;
-	UCHAR ModeID;
+	UCHAR Ext_CRT2CRTC;  /* TW: Index in LCD Paneltype arrays (&3f) */
+	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
 	USHORT ROM_OFFSET;
 } SiS300_Ext2Struct;
-SiS300_Ext2Struct SiS300_RefIndex[] = {
-	{0x085f, 0x0d, 0x03, 0x05, 0x6a, 800, 600, 0x3563},
-	{0x0467, 0x0e, 0x44, 0x05, 0x6a, 800, 600, 0x3568},
-	{0x0067, 0x4f, 0x07, 0x48, 0x6a, 800, 600, 0x356d},
-	{0x0067, 0x10, 0x06, 0x8b, 0x6a, 800, 600, 0x3572},
-	{0x0147, 0x11, 0x08, 0x00, 0x6a, 800, 600, 0x3577},
-	{0x0147, 0x12, 0x0c, 0x00, 0x6a, 800, 600, 0x357c},
-	{0x0047, 0x51, 0x4e, 0x00, 0x6a, 800, 600, 0x3581},
-	{0x0047, 0x11, 0x13, 0x00, 0x6a, 800, 600, 0x3586},
-	{0xc85f, 0x05, 0x00, 0x04, 0x2e, 640, 480, 0x3539},
-	{0xc067, 0x06, 0x02, 0x04, 0x2e, 640, 480, 0x353e},
-	{0xc067, 0x07, 0x02, 0x47, 0x2e, 640, 480, 0x3543},
-	{0xc067, 0x08, 0x03, 0x8a, 0x2e, 640, 480, 0x3548},
-	{0xc047, 0x09, 0x05, 0x00, 0x2e, 640, 480, 0x354d},
-	{0xc047, 0x0a, 0x08, 0x00, 0x2e, 640, 480, 0x3552},
-	{0xc047, 0x0b, 0x0a, 0x00, 0x2e, 640, 480, 0x3557},
-	{0xc047, 0x0c, 0x10, 0x00, 0x2e, 640, 480, 0x355c},
-	{0x487f, 0x04, 0x00, 0x00, 0x2f, 640, 400, 0x3532},
-	{0xc00f, 0x31, 0x01, 0x06, 0x31, 2048, 1536, 0x3630},
-	{0x000f, 0x32, 0x03, 0x06, 0x32, 720, 480, 0x3637},
-	{0x0187, 0x15, 0x05, 0x00, 0x37, 1024, 768, 0x358d},
-	{0xc877, 0x16, 0x09, 0x06, 0x37, 1024, 768, 0x3592},
-	{0xc067, 0x97, 0x0b, 0x49, 0x37, 1024, 768, 0x3597},
-	{0x0267, 0x18, 0x0d, 0x00, 0x37, 1024, 768, 0x359c},
-	{0x0047, 0x59, 0x11, 0x8c, 0x37, 1024, 768, 0x35a1},
-	{0x0047, 0x1a, 0x52, 0x00, 0x37, 1024, 768, 0x35a6},
-	{0x0047, 0x5b, 0x16, 0x00, 0x37, 1024, 768, 0x35ab},
-	{0x0387, 0x5c, 0x4d, 0x00, 0x3a, 1280, 1024, 0x35be},
-	{0x0077, 0x1d, 0x14, 0x07, 0x3a, 1280, 1024, 0x35c3},
-	{0x0047, 0x1e, 0x17, 0x00, 0x3a, 1280, 1024, 0x35c8},
-	{0x0007, 0x1f, 0x98, 0x00, 0x3a, 1280, 1024, 0x35cd},
-	{0x0007, 0x60, 0x59, 0x00, 0x3c, 1600, 1200, 0x35d4},
-	{0x0007, 0x21, 0x5a, 0x00, 0x3c, 1600, 1200, 0x35d9},
-	{0x0007, 0x22, 0x1b, 0x00, 0x3c, 1600, 1200, 0x35de},
-	{0x0007, 0x63, 0x1d, 0x00, 0x3c, 1600, 1200, 0x35e3},
-	{0x0007, 0x24, 0x1e, 0x00, 0x3c, 1600, 1200, 0x35e8},
-	{0x407f, 0x00, 0x00, 0x00, 0x40, 320, 200, 0x3516},
-	{0xc07f, 0x01, 0x00, 0x04, 0x50, 320, 240, 0x351d},
-	{0x0077, 0x02, 0x04, 0x05, 0x51, 400, 300, 0x3524},
-	{0xc077, 0x03, 0x09, 0x06, 0x52, 512, 384, 0x352b},
-	{0x8207, 0x25, 0x1f, 0x00, 0x68, 1920, 1440, 0x35ef},
-	{0x0007, 0x26, 0x20, 0x00, 0x6c, 2048, 1536, 0x35f6},
-	{0x0027, 0x27, 0x14, 0x08, 0x6e, 720, 576, 0x35b2},
-	{0x0027, 0x27, 0x14, 0x08, 0x6e, 720, 576, 0x35b7},
-	{0x00df, 0x33, 0x28, 0x00, 0x7c, 1280, 960, 0x363e},
-	{0xc05f, 0x34, 0x28, 0x00, 0x7c, 1280, 960, 0x3643},
-	{0xffff, 0, 0, 0, 0, 0, 0, 0}
-};
+
+SiS300_Ext2Struct  SiS300_RefIndex[]=
+{ /* TW: Don't ever insert anything here, table is indexed */
+ {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563},
+ {0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568},
+ {0x0067,0x4f,0x07,0x48,0x6a, 800, 600,0x356d},
+ {0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572},
+ {0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577},
+ {0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c},
+ {0x0047,0x51,0x4e,0x00,0x6a, 800, 600,0x3581},
+ {0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586},
+ {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539},
+ {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e},
+ {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543},
+ {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548},
+ {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d},
+ {0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552},
+ {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557},
+ {0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c},
+ {0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532},
+ {0xc00f,0x31,0x01,0x06,0x31,2048,1536,0x3630},
+ {0x000f,0x32,0x03,0x06,0x32, 720, 480,0x3637},
+ {0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d},
+ /* {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, <--- different in BIOS */
+ {0xc077,0x16,0x09,0x06,0x37,1024, 768,0x3592},
+ {0xc067,0x97,0x0b,0x49,0x37,1024, 768,0x3597},
+ {0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c},
+ {0x0047,0x59,0x11,0x8c,0x37,1024, 768,0x35a1},
+ {0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6},
+ {0x0047,0x5b,0x16,0x00,0x37,1024, 768,0x35ab},
+ {0x0387,0x5c,0x4d,0x00,0x3a,1280,1024,0x35be},
+ {0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3},
+ {0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8},
+ {0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd},
+ {0x0007,0x60,0x59,0x00,0x3c,1600,1200,0x35d4},
+ {0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9},
+ {0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de},
+ {0x0007,0x63,0x1d,0x00,0x3c,1600,1200,0x35e3},
+ {0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8},
+ /* TW: No 1600x1200 LCD mode? */
+ {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516},
+ {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d},
+ {0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524},
+ {0xc077,0x03,0x09,0x06,0x52, 512, 384,0x352b},
+ {0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef},
+ {0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6},
+ {0x0027,0x27,0x14,0x08,0x6e, 720, 576,0x35b2},
+ {0x0027,0x27,0x14,0x08,0x6e, 720, 576,0x35b7},
+ /* TW: 1280x960 identical to BIOS */
+ /* TW:              v--- I doubt this - no CRT2? */
+ {0x00df,0x33,0x28,0x00,0x7c,1280, 960,0x363e},
+ {0xc05f,0x34,0x28,0x00,0x7c,1280, 960,0x3643},
+#if 0
+ /* TW: The LCD modes for 1280x960 are missing! */
+ /*     Values guessed! */
+ {0x00a7,0x33,0x28,0x08,0x7c,1280, 960,0xDEAD},  /* Do we need an interlace mode? */
+ {0xc027,0x34,0x28,0x08,0x7c,1280, 960,0xBEEF},
+ /* TW:    |         |---- This is either 0x07 or 0x08  */
+#endif /*  +---- Same as for the non-interlace mode */
+ {0xffff,0,0,0,0,0,0,0}
+};
+
+/* TW: These entries are contained in the BIOS but missing in table above: (resolution unknown) */
+#if 0
+ /* at 0x3887: (not indexed by EModeIDTable in BIOS either) */
+ {0x0057,0x28,0x27,0x08,... }
+ {0x0047,0x29,0x06,0x08,... }
+ {0x0047,0x2a,0x08,0x08,... } /* table end */
+ /* at 0x3898: (not indexed by EModeIDTable in BIOS either)*/
+ {0x0057,0x2b,0x09,0x09,... }
+ {0x0047,0x2c,0x0d,0x09,... }
+ {0x0047,0x2d,0x11,0x09,... } /* table end */
+ /* at 0x38a9: (not indexed by EModeIDTable in BIOS either) */
+ {0x0057,0x2e,0x14,0x0a,... }
+ {0x0047,0x2f,0x17,0x0a,... }
+ {0x0047,0x30,0x18,0x0a,... } /* table end */
+#endif
 
 /*add for 300 oem util*/
-typedef struct _SiS_VBModeIDTableStruct {
-	UCHAR ModeID;
-	UCHAR VB_TVDelayIndex;
-	UCHAR VB_TVFlickerIndex;
-	UCHAR VB_TVPhaseIndex;
-	UCHAR VB_TVYFilterIndex;
-	UCHAR VB_LCDDelayIndex;
-	UCHAR _VB_LCDHIndex;
-	UCHAR _VB_LCDVIndex;
-} SiS_VBModeIDTableStruct;
-SiS_VBModeIDTableStruct SiS300_VBModeIDTable[] = {
-	{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-	{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
-	{0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02},
-	{0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00},
-	{0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01},
-	{0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x02},
-	{0x05, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00},
-	{0x06, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x00},
-	{0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x01},
-	{0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x02},
-	{0x0d, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00},
-	{0x0e, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x00},
-	{0x0f, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x01},
-	{0x10, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x01},
-	{0x11, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x03},
-	{0x12, 0x00, 0x00, 0x01, 0x05, 0x00, 0x02, 0x03},
-	{0x13, 0x00, 0x00, 0x01, 0x04, 0x00, 0x04, 0x00},
-	{0x6a, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x2e, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x08},
-	{0x2f, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x06},
-	{0x30, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x31, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00},
-	{0x32, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00},
-	{0x37, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x38, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x3a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x40, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x05},
-	{0x41, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x05},
-	{0x43, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x08},
-	{0x44, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x08},
-	{0x46, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x47, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x49, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x4a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x4c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x4d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x50, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x07},
-	{0x51, 0x00, 0x00, 0x01, 0x07, 0x00, 0x07, 0x09},
-	{0x52, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x0b},
-	{0x56, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x07},
-	{0x57, 0x00, 0x00, 0x01, 0x07, 0x00, 0x07, 0x09},
-	{0x58, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x0b},
-	{0x59, 0x00, 0x00, 0x01, 0x04, 0x00, 0x05, 0x05},
-	{0x5d, 0x00, 0x00, 0x01, 0x07, 0x00, 0x06, 0x06},
-	{0x62, 0x00, 0x00, 0x01, 0x05, 0x00, 0x06, 0x08},
-	{0x63, 0x00, 0x00, 0x01, 0x07, 0x00, 0x08, 0x0a},
-	{0x64, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0c},
-	{0x65, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x6e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x6f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d},
-	{0x7b, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0d}
+typedef struct _SiS_VBModeIDTableStruct
+{
+	UCHAR  ModeID;
+	UCHAR  VB_TVDelayIndex;
+	UCHAR  VB_TVFlickerIndex;
+	UCHAR  VB_TVPhaseIndex;
+	UCHAR  VB_TVYFilterIndex;
+	UCHAR  VB_LCDDelayIndex;
+	UCHAR  _VB_LCDHIndex;
+	UCHAR  _VB_LCDVIndex;
+}SiS_VBModeIDTableStruct;
+
+SiS_VBModeIDTableStruct  SiS300_VBModeIDTable[]=
+{
+	{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+	{0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x02},
+	{0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x00},
+	{0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x01},
+	{0x03,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
+	{0x05,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
+	{0x06,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
+	{0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x01},
+	{0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
+	{0x0d,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
+	{0x0e,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
+	{0x0f,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
+	{0x10,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
+	{0x11,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
+	{0x12,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
+	{0x13,0x00,0x00,0x01,0x04,0x00,0x04,0x00},
+	{0x6a,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x2e,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+	{0x2f,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
+	{0x30,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x31,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x32,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x37,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x38,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x3a,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x40,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+	{0x41,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+	{0x43,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+	{0x44,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+	{0x46,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x47,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x49,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x4a,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x4c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x4d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x50,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
+	{0x51,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
+	{0x52,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
+	{0x56,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
+	{0x57,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
+	{0x58,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
+	{0x59,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+	{0x5d,0x00,0x00,0x01,0x07,0x00,0x06,0x06},
+	{0x62,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+	{0x63,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+	{0x64,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+	{0x65,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}
 };
 /*end*/
 
-typedef struct _SiS300_CRT1TableStruct {
+/* TW: The following table is (now) identical to BIOS */
+typedef struct _SiS300_CRT1TableStruct
+{
 	UCHAR CR[17];
 } SiS300_CRT1TableStruct;
-SiS300_CRT1TableStruct SiS300_CRT1Table[] = {
-	{{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x04,
-	  0x00}},
-	{{0x3d, 0x31, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x05,
-	  0x01}},
-	{{0x4f, 0x3f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}},
-	{{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x63, 0x4f, 0x50, 0x86, 0x56, 0x9b, 0x06, 0x3e,
-	  0xe8, 0x8b, 0xdf, 0xe7, 0xff, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x64, 0x4f, 0x4f, 0x88, 0x55, 0x9d, 0xf2, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xf3, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x4f, 0x87, 0x5a, 0x81, 0xfb, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x66, 0x4f, 0x4f, 0x86, 0x56, 0x9e, 0x03, 0x3e,
-	  0xe4, 0x87, 0xdf, 0xdf, 0x04, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x6c, 0x4f, 0x4f, 0x83, 0x59, 0x9e, 0x00, 0x3e,
-	  0xe5, 0x8d, 0xdf, 0xdf, 0x01, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9d, 0xfb, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x65, 0x4f, 0x4f, 0x89, 0x57, 0x9f, 0xfb, 0x1f,
-	  0xe6, 0x8a, 0xe5, 0xe5, 0xfc, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	  0x58, 0x8a, 0x57, 0x57, 0x70, 0x20, 0x00, 0x05,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x7d, 0x63, 0x63, 0x81, 0x6e, 0x1d, 0x98, 0xf0,
-	  0x7c, 0x82, 0x57, 0x57, 0x99, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x70, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x7e, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x8c, 0x63, 0x63, 0x87, 0x72, 0x16, 0x7e, 0xf0,
-	  0x59, 0x8d, 0x57, 0x57, 0x7f, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0x7e, 0x63, 0x63, 0x82, 0x6c, 0x14, 0x75, 0xe0,
-	  0x58, 0x0b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x7e, 0x63, 0x63, 0x82, 0x6c, 0x14, 0x75, 0xe0,
-	  0x58, 0x0b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	  0x01}},
-	{{0x99, 0x7f, 0x7f, 0x9d, 0x84, 0x1a, 0x96, 0x1f,
-	  0x7f, 0x83, 0x7f, 0x7f, 0x97, 0x10, 0x00, 0x02,
-	  0x00}},
-	{{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0xa1, 0x7f, 0x7f, 0x85, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0xa7, 0x7f, 0x7f, 0x8b, 0x89, 0x95, 0x26, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x27, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x83, 0x93, 0x1e, 0xf5,
-	  0x00, 0x84, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0xa2, 0x7f, 0x7f, 0x86, 0x84, 0x94, 0x37, 0xf5,
-	  0x0b, 0x82, 0xff, 0xff, 0x38, 0x10, 0x00, 0x02,
-	  0x01}},
-	{{0xcf, 0x9f, 0x9f, 0x93, 0xb2, 0x01, 0x14, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x15, 0x00, 0x00, 0x03,
-	  0x00}},
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	  0x01}},
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	  0x01}},
-	{{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x2f, 0x09, 0x00, 0x07,
-	  0x01}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},
-	{{0x3f, 0xef, 0xef, 0x83, 0xfd, 0x1a, 0xda, 0x1f,
-	  0xa0, 0x84, 0x9f, 0x9f, 0xdb, 0x1f, 0x01, 0x01,
-	  0x00}},
-	{{0x55, 0xff, 0xff, 0x99, 0x0d, 0x0c, 0x3e, 0xba,
-	  0x00, 0x84, 0xff, 0xff, 0x3f, 0x0f, 0x41, 0x05,
-	  0x00}},
-	{{0xdc, 0x9f, 0x9f, 0x00, 0xab, 0x19, 0xe6, 0xef,
-	  0xc0, 0xc3, 0xbf, 0xbf, 0xe7, 0x10, 0x00, 0x07,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xba,
-	  0x27, 0x8b, 0xdf, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xba,
-	  0x26, 0x89, 0xdf, 0xdf, 0x6f, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0x7f, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xba,
-	  0x29, 0x8c, 0xdf, 0xdf, 0x75, 0x00, 0x00, 0x06,
-	  0x01}},
-	{{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf1,
-	  0xaf, 0x85, 0x3f, 0x3f, 0x25, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf1,
-	  0xad, 0x81, 0x3f, 0x3f, 0x1f, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0xa7, 0x7f, 0x7f, 0x88, 0x89, 0x15, 0x26, 0xf1,
-	  0xb1, 0x85, 0x3f, 0x3f, 0x27, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0xc4,
-	  0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	  0x01}},
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0xd4,
-	  0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	  0x01}},
-	{{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0xd4,
-	  0x7d, 0x81, 0xcf, 0xcf, 0x2f, 0x21, 0x00, 0x07,
-	  0x01}},
-	{{0x6b, 0x59, 0x59, 0x8f, 0x5e, 0x8c, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x7b, 0x59, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	  0x58, 0x8a, 0x3f, 0x57, 0x70, 0x20, 0x00, 0x05,
-	  0x01}},
-	{{0x86, 0x6a, 0x6a, 0x8a, 0x74, 0x06, 0x8c, 0x15,
-	  0x4f, 0x83, 0xef, 0xef, 0x8d, 0x30, 0x00, 0x02,
-	  0x00}},
-	{{0x81, 0x6a, 0x6a, 0x85, 0x70, 0x00, 0x0f, 0x3e,
-	  0xeb, 0x8e, 0xdf, 0xdf, 0x10, 0x00, 0x00, 0x02,
-	  0x00}}
+
+SiS300_CRT1TableStruct  SiS300_CRT1Table[]=
+{ /* at 0x4014 in BIOS */
+ {{0x2d,0x27,0x28,0x90,/*0x2b*/ 0x2c,0x80,0xbf,0x1f,  /* <--- was different to BIOS */
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+  0x00}},
+ {{0x2d,0x27,0x28,0x90,/*0x2b*/ 0x2c,0x80,0x0b,0x3e,  /* <--- was different to BIOS */
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+  0x00}},
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+  0x01}},
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+  0x01}},
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+  0x00}},
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}},
+ {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
+  0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
+  0x00}},
+ {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+  0x00}},
+ {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+  0x00}},
+ {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e,
+  0xe4,0x87,0xdf,0xdf,0x04,0x00,0x00,0x01,
+  0x00}},
+ {{0x6c,0x4f,0x4f,0x83,0x59,0x9e,0x00,0x3e,    /* 10 */
+  0xe5,0x8d,0xdf,0xdf,0x01,0x00,0x00,0x01,
+  0x00}},
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9d,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01,
+  0x00}},
+ {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+  0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
+  0x00}},
+ {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+  0x01}},
+ {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+  0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+  0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+  0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+  0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}},
+ {{0x8c,0x63,0x63,0x87,0x72,0x16,0x7e,0xf0,
+  0x59,0x8d,0x57,0x57,0x7f,0x00,0x00,0x06,
+  0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0,
+  0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0,   /* 20 */
+  0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}},
+ {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+  0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+  0x00}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}},
+ {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+  0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+  0x01}},
+ {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+  0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+  0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x83,0x93,0x1e,0xf5,
+  0x00,0x84,0xff,0xff,0x1f,0x10,0x00,0x02,
+  0x01}},
+ {{0xa2,0x7f,0x7f,0x86,0x84,0x94,0x37,0xf5,
+  0x0b,0x82,0xff,0xff,0x38,0x10,0x00,0x02,
+  0x01}},
+ {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+  0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+  0x00}},
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,  /* 30 */
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}},
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+  0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+  0x01}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,  /* 36: 1600x1200x85Hz */
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}},
+ {{0x3f,0xef,0xef,0x83,0xfd,0x1a,0xda,0x1f,  /* 37: 1920x1440x60Hz */
+  0xa0,0x84,0x9f,0x9f,0xdb,0x1f,0x01,0x01,
+  0x00}},  /* TW: TEST, should be 0x30? */
+ {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+  0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+  0x00}},
+ {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
+  0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
+  0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+  0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+  0x01}},
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+  0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+  0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+  0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+  0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+  0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+  0x01}},
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
+  0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+  0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}},
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+  0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+  0x01}},
+ {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}},
+ {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+  0x01}},
+ {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,	/* 1280x960 */
+  0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
+  0x00}},
+ {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,	/* 1280x960 */
+  0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
+  0x00}}
+  /* end @ 0x4399 */
 };
 
-typedef struct _SiS300_MCLKDataStruct {
-	UCHAR SR28, SR29, SR2A;
+typedef struct _SiS300_MCLKDataStruct
+{
+	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS300_MCLKDataStruct;
-SiS300_MCLKDataStruct SiS300_MCLKData[] = {
-	{0x5a, 0x64, 0x80, 66},
-	{0xb3, 0x45, 0x80, 83},
-	{0x37, 0x61, 0x80, 100},
-	{0x37, 0x22, 0x80, 133},
-	{0x37, 0x61, 0x80, 100},
-	{0x37, 0x61, 0x80, 100},
-	{0x37, 0x61, 0x80, 100},
-	{0x37, 0x61, 0x80, 100}
+
+SiS300_MCLKDataStruct  SiS300_MCLKData[]=
+{ /* TW: at 0x54 in BIOS */
+	{ 0x5a,0x64,0x80, 66},
+	{ 0xb3,0x45,0x80, 83},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x22,0x80,133},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100}
 };
 
-typedef struct _SiS300_ECLKDataStruct {
-	UCHAR SR2E, SR2F, SR30;
+typedef struct _SiS300_ECLKDataStruct
+{
+	UCHAR SR2E,SR2F,SR30;
 	USHORT CLOCK;
 } SiS300_ECLKDataStruct;
-SiS300_ECLKDataStruct SiS300_ECLKData[] = {
-	{0x54, 0x43, 0x80, 100},
-	{0x53, 0x43, 0x80, 100},
-	{0x55, 0x43, 0x80, 100},
-	{0x52, 0x43, 0x80, 100},
-	{0x3f, 0x42, 0x80, 100},
-	{0x54, 0x43, 0x80, 100},
-	{0x54, 0x43, 0x80, 100},
-	{0x54, 0x43, 0x80, 100}
+
+SiS300_ECLKDataStruct  SiS300_ECLKData[]=
+{ /* TW: at 0x7c in BIOS */
+	{ 0x54,0x43,0x80,100},
+	{ 0x53,0x43,0x80,100},
+	{ 0x55,0x43,0x80,100},
+	{ 0x52,0x43,0x80,100},
+	{ 0x3f,0x42,0x80,100},
+	{ 0x54,0x43,0x80,100},
+	{ 0x54,0x43,0x80,100},
+	{ 0x54,0x43,0x80,100}
 };
 
-typedef struct _SiS300_VCLKDataStruct {
-	UCHAR SR2B, SR2C;
+typedef struct _SiS300_VCLKDataStruct
+{
+	UCHAR SR2B,SR2C;
 	USHORT CLOCK;
 } SiS300_VCLKDataStruct;
-SiS300_VCLKDataStruct SiS300_VCLKData[] = {
-	{0x1b, 0xe1, 25},
-	{0x4e, 0xe4, 28},
-	{0x57, 0xe4, 32},
-	{0xc3, 0xc8, 36},
-	{0x42, 0xc3, 40},
-	{0x5d, 0xc4, 45},
-	{0x52, 0x65, 50},
-	{0x53, 0x65, 50},
-	{0x6d, 0x66, 56},
-	{0x5a, 0x64, 65},
-	{0x46, 0x44, 68},
-	{0x3e, 0x43, 75},
-	{0x6d, 0x46, 76},
-	{0x41, 0x43, 79},
-	{0x31, 0x42, 79},
-	{0x46, 0x25, 85},
-	{0x78, 0x29, 87},
-	{0x62, 0x44, 95},
-	{0x2b, 0x22, 105},
-	{0x49, 0x24, 106},
-	{0xc3, 0x28, 108},
-	{0x3c, 0x23, 109},
-	{0xf7, 0x2c, 132},
-	{0xd4, 0x28, 136},
-	{0x41, 0x05, 158},
-	{0x43, 0x05, 162},
-	{0xe1, 0x0f, 175},
-	{0xfc, 0x12, 189},
-	{0xde, 0x26, 194},
-	{0x54, 0x05, 203},
-	{0x3f, 0x03, 230},
-	{0x30, 0x02, 234},
-	{0x24, 0x01, 266},
-	{0x52, 0x2a, 54},
-	{0x52, 0x6a, 27},
-	{0x62, 0x24, 70},
-	{0x62, 0x64, 70},
-	{0xa8, 0x4c, 30},
-	{0x20, 0x26, 33},
-	{0x31, 0xc2, 39},
-	{0xbf, 0xc8, 35},
-	{0x60, 0x36, 30},
-	{0x40, 0x4a, 28},
-	{0x9f, 0x46, 44},
-	{0x97, 0x2c, 26},
-	{0x44, 0xe4, 25},
-	{0x7e, 0x32, 47},
-	{0x8a, 0x24, 31},
-	{0x97, 0x2c, 26},
-	{0xce, 0x3c, 39},
-	{0x52, 0x4a, 36},
-	{0x34, 0x61, 95},
-	{0x78, 0x27, 108},
-	{0xff, 0x1b, 6625}
-};
-
-UCHAR SiS300_ScreenOffset[] =
-    { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35,
-	    0xff };
 
-typedef struct _SiS300_StResInfoStruct {
+SiS300_VCLKDataStruct  SiS300_VCLKData[]=
+{ /* TW: At 0x484e in BIOS */
+	{ 0x1b,0xe1, 25},
+	{ 0x4e,0xe4, 28},
+	{ 0x57,0xe4, 32},
+	{ 0xc3,0xc8, 36},
+	{ 0x42,0xc3, 40},
+	{ 0x5d,0xc4, 45},
+	{ 0x52,0x65, 50},
+	{ 0x53,0x65, 50},
+	{ 0x6d,0x66, 56},
+	{ 0x5a,0x64, 65},
+	{ 0x46,0x44, 68},
+	{ 0x3e,0x43, 75},
+	{ 0x6d,0x46, 76},
+	{ 0x41,0x43, 79},
+	{ 0x31,0x42, 79},
+	{ 0x46,0x25, 85},
+	{ 0x78,0x29, 87},
+	{ 0x62,0x44, 95},
+	{ 0x2b,0x22,105},
+	{ 0x49,0x24,106},
+	{ 0xc3,0x28,108},
+	{ 0x3c,0x23,109},
+	{ 0xf7,0x2c,132},
+	{ 0xd4,0x28,136},
+	{ 0x41,0x05,158},
+	{ 0x43,0x05,162},
+	{ 0xe1,0x0f,175},
+	{ 0xfc,0x12,189},
+	{ 0xde,0x26,194},
+	{ 0x54,0x05,203},
+	{ 0x3f,0x03,230},
+	{ 0x30,0x02,234},  /* 0x1f - 1920x1440 */
+	{ 0x24,0x01,266},  /* 0x20 - 2048x1536 */
+	{ 0x52,0x2a, 54},
+	{ 0x52,0x6a, 27},
+	{ 0x62,0x24, 70},
+	{ 0x62,0x64, 70},
+	{ 0xa8,0x4c, 30},
+	{ 0x20,0x26, 33},
+	{ 0x31,0xc2, 39},
+	{ 0xbf,0xc8, 35},  /* 0x28 - 1280x960 ??? that can't be right */
+	{ 0x60,0x36, 30},
+	{ 0x40,0x4a, 28},
+	{ 0x9f,0x46, 44},
+	{ 0x97,0x2c, 26},
+	{ 0x44,0xe4, 25},
+	{ 0x7e,0x32, 47},
+	{ 0x8a,0x24, 31},
+	{ 0x97,0x2c, 26},
+	{ 0xce,0x3c, 39},
+	{ 0x52,0x4a, 36},
+	{ 0x34,0x61, 95},
+	{ 0x78,0x27,108},
+	{ 0xce,0x25,189},  /* TW: This was missing */
+	{ 0xff,0x1b,6625}
+};
+
+/* TW: at 0x377d in BIOS */
+UCHAR SiS300_ScreenOffset[]=
+{
+	0x14,0x19,0x20,0x28,0x32,0x40,0x50,
+        0x64,0x78,0x80,0x2d,0x35,0xff
+};
+
+typedef struct _SiS300_StResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
 } SiS300_StResInfoStruct;
-SiS300_StResInfoStruct SiS300_StResInfo[] = {
-	{640, 400},
-	{640, 350},
-	{720, 400},
-	{720, 350},
-	{640, 480}
+
+SiS300_StResInfoStruct  SiS300_StResInfo[]=
+{
+	{ 640,400},
+	{ 640,350},
+	{ 720,400},
+	{ 720,350},
+	{ 640,480}
 };
 
-typedef struct _SiS300_ModeResInfoStruct {
+typedef struct _SiS300_ModeResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
-	UCHAR XChar;
-	UCHAR YChar;
+	UCHAR  XChar;
+	UCHAR  YChar;
 } SiS300_ModeResInfoStruct;
-SiS300_ModeResInfoStruct SiS300_ModeResInfo[] = {
-	{320, 200, 8, 8},
-	{320, 240, 8, 8},
-	{320, 400, 8, 8},
-	{400, 300, 8, 8},
-	{512, 384, 8, 8},
-	{640, 400, 8, 16},
-	{640, 480, 8, 16},
-	{800, 600, 8, 16},
-	{1024, 768, 8, 16},
-	{1280, 1024, 8, 16},
-	{1600, 1200, 8, 16},
-	{1920, 1440, 8, 16},
-	{720, 480, 8, 16},
-	{720, 576, 8, 16},
-	{1280, 960, 8, 16}
+
+SiS300_ModeResInfoStruct  SiS300_ModeResInfo[]=
+{ /* TW: At 0x5957 in BIOS */
+	{  320, 200, 8, 8},
+	{  320, 240, 8, 8},
+	{  320, 400, 8, 8},
+	{  400, 300, 8, 8},
+	{  512, 384, 8, 8},
+	{  640, 400, 8,16},
+	{  640, 480, 8,16},
+	{  800, 600, 8,16},
+	{ 1024, 768, 8,16},
+	{ 1280,1024, 8,16},
+	{ 1600,1200, 8,16},
+	{ 1920,1440, 8,16},
+	{ 2048,1536, 8,16},   /* TW: this was missing here, wasn't it? (not in BIOS) */
+	{  720, 480, 8,16},   /*     (otherwise RESINFO index is wrong!) */
+	{  720, 576, 8,16},
+	{ 1280, 960, 8,16}
 };
 
-UCHAR SiS300_OutputSelect = 0x40;
+UCHAR SiS300_OutputSelect =0x40;
 UCHAR SiS300_SoftSetting = 30;
-UCHAR SiS300_SR07 = 0x10;
-UCHAR SiS300_SR15[8][4] = {
-	{0x1, 0x9, 0xa3, 0x0},
-	{0x43, 0x43, 0x43, 0x0},
-	{0x1e, 0x1e, 0x1e, 0x0},
-	{0x2a, 0x2a, 0x2a, 0x0},
-	{0x6, 0x6, 0x6, 0x0},
-	{0x0, 0x0, 0x0, 0x0},
-	{0x0, 0x0, 0x0, 0x0},
-	{0x0, 0x0, 0x0, 0x0}
-};
-UCHAR SiS300_SR1F = 0x0;
-UCHAR SiS300_SR21 = 0x16;
-UCHAR SiS300_SR22 = 0xb2;
-UCHAR SiS300_SR23 = 0xf6;
-UCHAR SiS300_SR24 = 0xd;
-UCHAR SiS300_SR25[] = { 0x0, 0x0 };
-UCHAR SiS300_SR31 = 0x0;
-UCHAR SiS300_SR32 = 0x11;
-UCHAR SiS300_SR33 = 0x0;
+UCHAR SiS300_SR07=0x10;
+UCHAR SiS300_SR15[8][4]={
+	{0x1,0x9,0xa3,0x0},
+	{0x43,0x43,0x43,0x0},
+	{0x1e,0x1e,0x1e,0x0},
+	{0x2a,0x2a,0x2a,0x0},
+	{0x6,0x6,0x6,0x0},
+	{0x0,0x0,0x0,0x0},
+	{0x0,0x0,0x0,0x0},
+	{0x0,0x0,0x0,0x0}
+};
+UCHAR SiS300_SR1F=0x0;
+UCHAR SiS300_SR21=0x16;
+UCHAR SiS300_SR22=0xb2;
+UCHAR SiS300_SR23=0xf6;
+UCHAR SiS300_SR24=0xd;
+UCHAR SiS300_SR25[]={0x0,0x0};
+UCHAR SiS300_SR31=0x0;
+UCHAR SiS300_SR32=0x11;
+UCHAR SiS300_SR33=0x0;
 UCHAR SiS300_CRT2Data_1_2 = 0x40;
 UCHAR SiS300_CRT2Data_4_D = 0x0;
 UCHAR SiS300_CRT2Data_4_E = 0x0;
@@ -916,42 +987,46 @@
 USHORT SiS300_RGBSenseData = 0xd1;
 USHORT SiS300_VideoSenseData = 0xb3;
 USHORT SiS300_YCSenseData = 0xb9;
-USHORT SiS300_RGBSenseData2 = 0x0190;	/*301b */
+USHORT SiS300_RGBSenseData2 = 0x0190;     /*301b*/
 USHORT SiS300_VideoSenseData2 = 0x0174;
 USHORT SiS300_YCSenseData2 = 0x016b;
 
 UCHAR SiS300_CR40[5][4];
 UCHAR SiS300_CR49[2];
-UCHAR SiS300_NTSCPhase[] = { 0x21, 0xed, 0x8a, 0x8 };
-UCHAR SiS300_PALPhase[] = { 0x2a, 0x5, 0xd3, 0x0 };
-UCHAR SiS300_NTSCPhase2[] = { 0x21, 0xF0, 0x7B, 0xD6 };	/*301b */
-UCHAR SiS300_PALPhase2[] = { 0x2a, 0x09, 0x86, 0xe9 };
-UCHAR SiS300_PALMPhase[] = { 0x21, 0xE4, 0x2E, 0x9B };	/*palmn */
-UCHAR SiS300_PALNPhase[] = { 0x21, 0xF4, 0x3E, 0xBA };
+UCHAR SiS300_NTSCPhase[]  = {0x21,0xed,0x8a,0x08};
+UCHAR SiS300_PALPhase[]   = {0x2a,0x05,0xd3,0x00};
+UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};/*301b*/
+UCHAR SiS300_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};
+UCHAR SiS300_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B};   /*palmn*/
+UCHAR SiS300_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA};
 
-typedef struct _SiS300_PanelDelayTblStruct {
+typedef struct _SiS300_PanelDelayTblStruct
+{
 	UCHAR timer[2];
 } SiS300_PanelDelayTblStruct;
-SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] = {
-	{{0x05, 0xaa}},
-	{{0x05, 0x14}},
-	{{0x05, 0x36}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x90}},
-	{{0x05, 0x90}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x64}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}},
-	{{0x05, 0x14}}
+
+SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[]=
+{
+	{{0x05,0xaa}},
+	{{0x05,0x14}},
+	{{0x05,0x36}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x90}},
+	{{0x05,0x90}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x64}},
+	{{0x05,0x14}},
+	{{0x05,0x14}},
+	{{0x05,0x14}}
 };
 
-typedef struct _SiS300_LCDDataStruct {
+typedef struct _SiS300_LCDDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -959,99 +1034,109 @@
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS300_LCDDataStruct;
-SiS300_LCDDataStruct SiS300_StLCD1024x768Data[] = {
-	{66, 31, 992, 510, 1320, 816},
-	{66, 31, 992, 510, 1320, 816},
-	{176, 75, 900, 510, 1320, 816},
-	{176, 75, 900, 510, 1320, 816},
-	{66, 31, 992, 510, 1320, 816},
-	{27, 16, 1024, 650, 1350, 832},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS300_LCDDataStruct SiS300_ExtLCD1024x768Data[] = {
-	{12, 5, 896, 512, 1344, 806},
-	{12, 5, 896, 510, 1344, 806},
-	{32, 15, 1008, 505, 1344, 806},
-	{32, 15, 1008, 514, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS300_LCDDataStruct SiS300_St2LCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS300_LCDDataStruct SiS300_StLCD1280x1024Data[] = {
-	{4, 1, 880, 510, 1650, 1088},
-	{4, 1, 880, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{4, 1, 880, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS300_LCDDataStruct SiS300_ExtLCD1280x1024Data[] = {
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 500, 1688, 1066},
-	{211, 75, 1024, 625, 1688, 1066},
-	{211, 120, 1280, 798, 1688, 1066},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS300_LCDDataStruct SiS300_St2LCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS300_LCDDataStruct SiS300_NoScaleData[] = {
-	{1, 1, 800, 449, 800, 449},
-	{1, 1, 800, 449, 800, 449},
-	{1, 1, 900, 449, 900, 449},
-	{1, 1, 900, 449, 900, 449},
-	{1, 1, 800, 525, 800, 525},
-	{1, 1, 1056, 628, 1056, 628},
-	{1, 1, 1344, 806, 1344, 806},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS300_LCDDataStruct SiS300_LCD1280x960Data[] = {
-	{9, 2, 800, 500, 1800, 1000},
-	{9, 2, 800, 500, 1800, 1000},
-	{4, 1, 900, 500, 1800, 1000},
-	{4, 1, 900, 500, 1800, 1000},
-	{9, 2, 800, 500, 1800, 1000},
-	{30, 11, 1056, 625, 1800, 1000},
-	{5, 3, 1350, 800, 1800, 1000},
-	{1, 1, 1576, 1050, 1576, 1050},
-	{1, 1, 1800, 1000, 1800, 1000}
+
+SiS300_LCDDataStruct  SiS300_StLCD1024x768Data[]=
+{
+	{   66,  31, 992, 510,1320, 816},
+	{   66,  31, 992, 510,1320, 816},
+	{  176,  75, 900, 510,1320, 816},
+	{  176,  75, 900, 510,1320, 816},
+	{   66,  31, 992, 510,1320, 816},
+	{   27,  16,1024, 650,1350, 832},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS300_LCDDataStruct  SiS300_ExtLCD1024x768Data[]=
+{
+	{   12,   5, 896, 512,1344, 806},
+	{   12,   5, 896, 510,1344, 806},
+	{   32,  15,1008, 505,1344, 806},
+	{   32,  15,1008, 514,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS300_LCDDataStruct  SiS300_St2LCD1024x768Data[]=
+{
+	{   62,  25, 800, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{  104,  45, 945, 496,1344, 806},
+	{   62,  25, 800, 546,1344, 806},
+	{   31,  18,1008, 624,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
 };
 
-typedef struct _SiS300_TVDataStruct {
+SiS300_LCDDataStruct  SiS300_StLCD1280x1024Data[]=
+{
+	{    4,   1, 880, 510,1650,1088},
+	{    4,   1, 880, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{    4,   1, 880, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS300_LCDDataStruct  SiS300_ExtLCD1280x1024Data[]=
+{
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 500,1688,1066},
+	{  211,  75,1024, 625,1688,1066},
+	{  211, 120,1280, 798,1688,1066},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS300_LCDDataStruct  SiS300_St2LCD1280x1024Data[]=
+{
+	{   22,   5, 800, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS300_LCDDataStruct  SiS300_NoScaleData[]=
+{
+	{    1,   1, 800, 449, 800, 449},
+	{    1,   1, 800, 449, 800, 449},
+	{    1,   1, 900, 449, 900, 449},
+	{    1,   1, 900, 449, 900, 449},
+	{    1,   1, 800, 525, 800, 525},
+	{    1,   1,1056, 628,1056, 628},
+	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS300_LCDDataStruct  SiS300_LCD1280x960Data[]=
+{
+	{    9,   2, 800, 500,1800,1000},
+	{    9,   2, 800, 500,1800,1000},
+	{    4,   1, 900, 500,1800,1000},
+	{    4,   1, 900, 500,1800,1000},
+	{    9,   2, 800, 500,1800,1000},
+	{   30,  11,1056, 625,1800,1000},
+	{    5,   3,1350, 800,1800,1000},
+	{    1,   1,1576,1050,1576,1050},
+	{    1,   1,1800,1000,1800,1000}
+};
+
+typedef struct _SiS300_TVDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -1066,457 +1151,1172 @@
 	UCHAR RY3COE;
 	UCHAR RY4COE;
 } SiS300_TVDataStruct;
-SiS300_TVDataStruct SiS300_StPALData[] = {
-	{1, 1, 864, 525, 1270, 400, 100, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 350, 100, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 400, 0, 0, 720, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 864, 525, 1270, 350, 0, 0, 720, 0xf4, 0x0b, 0x1c, 0x0a},
-	{1, 1, 864, 525, 1270, 480, 50, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 600, 50, 0, 0, 0xf4, 0xff, 0x1c, 0x22}
-};
-
-SiS300_TVDataStruct SiS300_ExtPALData[] = {
-	{27, 10, 848, 448, 1270, 530, 50, 0, 50, 0xf4, 0xff, 0x1c, 0x22},
-	{108, 35, 848, 398, 1270, 530, 50, 0, 50, 0xf4, 0xff, 0x1c, 0x22},
-	{12, 5, 954, 448, 1270, 530, 50, 0, 50, 0xf1, 0x04, 0x1f, 0x18},
-	{9, 4, 960, 463, 1644, 438, 50, 0, 50, 0xf4, 0x0b, 0x1c, 0x0a},
-	{9, 4, 848, 528, 1270, 530, 0, 0, 50, 0xf5, 0xfb, 0x1b, 0x2a},
-	{36, 25, 1060, 648, 1316, 530, 438, 0, 438, 0xeb, 0x05, 0x25, 0x16},
-	{3, 2, 1080, 619, 1270, 540, 438, 0, 438, 0xf3, 0x00, 0x1d, 0x20},
-	{1, 1, 1170, 821, 1270, 520, 686, 0, 686, 0xF3, 0x00, 0x1D, 0x20}	/*301b */
+
+SiS300_TVDataStruct  SiS300_StPALData[]=
+{
+	{    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+	{    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+	{    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+	{    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+	{    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
+	{    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
+};
+
+SiS300_TVDataStruct  SiS300_ExtPALData[]=
+{
+	{   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+	{  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+	{   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
+	{    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
+	{    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
+	{   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
+	{    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
+	{    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}     /*301b*/
 
 };
 
-SiS300_TVDataStruct SiS300_StNTSCData[] = {
-	{1, 1, 858, 525, 1270, 400, 50, 0, 760, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 350, 50, 0, 640, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 400, 0, 0, 720, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 350, 0, 0, 720, 0xf4, 0x0b, 0x1c, 0x0a},
-	{1, 1, 858, 525, 1270, 480, 0, 0, 760, 0xf1, 0x04, 0x1f, 0x18}
-};
-
-SiS300_TVDataStruct SiS300_ExtNTSCData[] = {
-	{143, 65, 858, 443, 1270, 440, 171, 0, 171, 0xf1, 0x04, 0x1f, 0x18},
-	{88, 35, 858, 393, 1270, 440, 171, 0, 171, 0xf1, 0x04, 0x1f, 0x18},
-	{143, 70, 924, 443, 1270, 440, 92, 0, 92, 0xf1, 0x04, 0x1f, 0x18},
-	{143, 70, 924, 393, 1270, 440, 92, 0, 92, 0xf4, 0x0b, 0x1c, 0x0a},
-	{143, 76, 836, 523, 1270, 440, 224, 0, 0, 0xf1, 0x05, 0x1f, 0x16},
-	{143, 120, 1056, 643, 1270, 440, 0, 128, 0, 0xf4, 0x10, 0x1c, 0x00},
-	{143, 76, 836, 523, 1270, 440, 0, 128, 0, 0xee, 0x0c, 0x22, 0x08},
-	{65, 64, 1056, 791, 1270, 480, 638, 0, 0, 0xf1, 0x04, 0x1f, 0x18}	/*301b */
-};
-
-SiS_TVDataStruct SiS300_St1HiTVData[] = {
-	
-	    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00, 0x00}
-};
-
-SiS_TVDataStruct SiS300_St2HiTVData[] = {
-	
-	    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00, 0x00}
-};
-
-SiS_TVDataStruct SiS300_ExtHiTVData[] = {
-	
-	    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00, 0x00}
+SiS300_TVDataStruct  SiS300_StNTSCData[]=
+{
+	{    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
+	{    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
+	{    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+	{    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+	{    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
+};
+
+SiS300_TVDataStruct  SiS300_ExtNTSCData[]=
+{
+	{  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+	{   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+	{  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+	{  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+	{  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
+	{  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
+	{  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
+	{   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18} /*301b*/
+};
+
+SiS_TVDataStruct  SiS300_St1HiTVData[]=
+{
+ 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+SiS_TVDataStruct  SiS300_St2HiTVData[]=
+{
+ 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+SiS_TVDataStruct  SiS300_ExtHiTVData[]=
+{
+ 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
 UCHAR SiS300_NTSCTiming[] = {
-	0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
-	0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
-	0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
-	0x0c, 0x50, 0x00, 0x97, 0x00, 0xda, 0x4a, 0x17,
-	0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
-	0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
-	0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x50,
-	0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
+	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
+	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
 };
 
 UCHAR SiS300_PALTiming[] = {
-	0x19, 0x52, 0x35, 0x6e, 0x04, 0x38, 0x3d, 0x70,
-	0x94, 0x49, 0x01, 0x12, 0x06, 0x3e, 0x35, 0x6d,
-	0x06, 0x14, 0x3e, 0x35, 0x6d, 0x00, 0x45, 0x2b,
-	0x70, 0x50, 0x00, 0x9b, 0x00, 0xd9, 0x5d, 0x17,
-	0x7d, 0x05, 0x45, 0x00, 0x00, 0xe8, 0x00, 0x02,
-	0x0d, 0x00, 0x68, 0xb0, 0x0b, 0x92, 0x8f, 0x40,
-	0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x63,
-	0x00, 0x40, 0x3e, 0x00, 0xe1, 0x02, 0x28, 0x00
+	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
+	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
 };
 
-UCHAR SiS300_HiTVExtTiming[] = { 0x00 };
+UCHAR SiS300_HiTVExtTiming[] = {0x00};
 
-UCHAR SiS300_HiTVSt1Timing[] = { 0x00 };
+UCHAR SiS300_HiTVSt1Timing[] = {0x00};
 
-UCHAR SiS300_HiTVSt2Timing[] = { 0x00 };
+UCHAR SiS300_HiTVSt2Timing[] = {0x00};
 
-UCHAR SiS300_HiTVTextTiming[] = { 0x00 };
+UCHAR SiS300_HiTVTextTiming[] = {0x00};
 
-UCHAR SiS300_HiTVGroup3Data[] = { 0x00 };
+UCHAR SiS300_HiTVGroup3Data[] = {0x00};
 
-UCHAR SiS300_HiTVGroup3Simu[] = { 0x00 };
+UCHAR SiS300_HiTVGroup3Simu[] = {0x00};
 
-UCHAR SiS300_HiTVGroup3Text[] = { 0x00 };
+UCHAR SiS300_HiTVGroup3Text[] = {0x00};
 
-typedef struct _SiS300_LVDSDataStruct {
+typedef struct _SiS300_LVDSDataStruct
+{
 	USHORT VGAHT;
 	USHORT VGAVT;
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS300_LVDSDataStruct;
-SiS300_LVDSDataStruct SiS300_LVDS800x600Data_1[] = {
-	{0x00, 0x00, 0x00, 0x00}
+
+SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_1[]=
+{
+	{848, 433,1060, 629},
+	{848, 389,1060, 629},
+	{848, 433,1060, 629},
+	{848, 389,1060, 629},
+	{848, 518,1060, 629},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{800, 449,1000, 644},
+	{800, 525,1000, 635}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS800x600Data_2[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_2[]=
+{
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{800, 449,1000, 644},
+	{800, 525,1000, 635}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_1[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_1[]=
+{
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_2[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_1[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_1[]=
+{
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_2[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct SiS300_LVDS640x480Data_1[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_LVDS640x480Data_1[]=
+{
+	{800, 449, 800, 449},
+	{800, 449, 800, 449},
+	{800, 449, 800, 449},
+	{800, 449, 800, 449},
+	{800, 525, 800, 525},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628}
 };
 
-SiS300_LVDSDataStruct SiS300_CHTVUNTSCData[] = {
-	{0x00, 0x00, 0x00, 0x00}
+/* TW: New: */
+SiS300_LVDSDataStruct  SiS300_CHTVUNTSCData[]=
+{
+	{840, 600, 840, 600},
+	{840, 600, 840, 600},
+	{840, 600, 840, 600},
+	{840, 600, 840, 600},
+	{784, 600, 784, 600},
+	{1064, 750,1064, 750}
 };
 
-SiS300_LVDSDataStruct SiS300_CHTVONTSCData[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_CHTVONTSCData[]=
+{
+	{840, 525, 840, 525},
+	{840, 525, 840, 525},
+	{840, 525, 840, 525},
+	{840, 525, 840, 525},
+	{784, 525, 784, 525},
+	{1040, 700,1040, 700}
 };
 
-SiS300_LVDSDataStruct SiS300_CHTVUPALData[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_CHTVUPALData[]=
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{840, 750, 840, 750},
+	{936, 836, 936, 836}
 };
 
-SiS300_LVDSDataStruct SiS300_CHTVOPALData[] = {
-	{0x00, 0x00, 0x00, 0x00}
+SiS300_LVDSDataStruct  SiS300_CHTVOPALData[]=
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{840, 625, 840, 625},
+	{960, 750, 960, 750}
 };
+/* TW: new end */
 
-typedef struct _SiS300_LVDSDesStruct {
+typedef struct _SiS300_LVDSDesStruct
+{
 	USHORT LCDHDES;
 	USHORT LCDVDES;
 } SiS300_LVDSDesStruct;
-SiS300_LVDSDesStruct SiS300_PanelType00_1[] = {
-	{0x00, 0x00}
+
+SiS300_LVDSDesStruct  SiS300_PanelType00_1[]=
+{
+	{0, 626},
+	{0, 624},
+	{0, 626},
+	{0, 624},
+	{0, 624},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType01_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType01_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType02_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType02_1[]=
+{
+	{0, 626},
+	{0, 624},
+	{0, 626},
+	{0, 624},
+	{0, 624},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType03_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType03_1[]=
+{
+	{ 8, 436},
+	{ 8, 440},
+	{ 8, 436},
+	{ 8, 440},
+	{ 8, 512},
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType04_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType04_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType05_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType05_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType06_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType06_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType07_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType07_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType08_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType08_1[]=
+{
+	{1059, 626},
+	{1059, 624},
+	{1059, 626},
+	{1059, 624},
+	{1059, 624},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType09_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType09_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0a_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0a_1[]=
+{
+	{1059, 626},
+	{1059, 624},
+	{1059, 626},
+	{1059, 624},
+	{1059, 624},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0b_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0b_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0c_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0c_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0d_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0d_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0e_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0e_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0f_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0f_1[]=
+{
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType00_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType00_2[]=
+{
+	{976, 527},
+	{976, 502},
+	{976, 527},
+	{976, 502},
+	{976, 567},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType01_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType01_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType02_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType02_2[]=
+{
+	{976, 527},
+	{976, 502},
+	{976, 527},
+	{976, 502},
+	{976, 567},
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType03_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType03_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{1152, 622},
+	{1152, 597}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType04_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType04_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType05_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType05_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType06_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType06_2[]=
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType07_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType07_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType08_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType08_2[]=
+{
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 567},
+ 	{  0, 627},
+ 	{  0, 627},
+ 	{  0,   0},
+ 	{  0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType09_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType09_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0a_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0a_2[]=
+{
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 567},
+ 	{  0, 627},
+ 	{  0, 627},
+ 	{  0,   0},
+ 	{  0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0b_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0b_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0c_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0c_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0d_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0d_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0e_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0e_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType0f_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_PanelType0f_2[]=
+{
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 622},
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+ 	{   0, 805},
+ 	{   0, 794},
+ 	{   0,   0}
 };
 
 /*301b*/
-SiS300_LVDSDesStruct SiS300_PanelType1076_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct SiS300_PanelType1076_1[]=
+{
+	{0x00,0x00}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1210_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct SiS300_PanelType1210_1[]=
+{
+	{0x00,0x00}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1296_1[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct SiS300_PanelType1296_1[]=
+{
+	{0x00,0x00}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1076_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct SiS300_PanelType1076_2[]=
+{
+	{0x00,0x00}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1210_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct SiS300_PanelType1210_2[]=
+{
+	{0x00,0x00}
 };
-SiS300_LVDSDesStruct SiS300_PanelType1296_2[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct SiS300_PanelType1296_2[]=
+{
+	{0x00,0x00}
 };
 /*end 301b*/
 
-SiS300_LVDSDesStruct SiS300_CHTVUNTSCDesData[] = {
-	{0x00, 0x00}
+/* TW: New */
+SiS300_LVDSDesStruct  SiS300_CHTVUNTSCDesData[]=
+{
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_CHTVONTSCDesData[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_CHTVONTSCDesData[]=
+{
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0},
+ 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_CHTVUPALDesData[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_CHTVUPALDesData[]=
+{
+ 	{256,   0},
+ 	{256,   0},
+ 	{256,   0},
+ 	{256,   0},
+ 	{  0,   0},
+ 	{  0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_CHTVOPALDesData[] = {
-	{0x00, 0x00}
+SiS300_LVDSDesStruct  SiS300_CHTVOPALDesData[]=
+{
+ 	{256,   0},
+ 	{256,   0},
+ 	{256,   0},
+ 	{256,   0},
+ 	{  0,   0},
+ 	{  0,   0}
 };
+/* TW: New end */
 
-typedef struct _SiS300_LVDSCRT1DataStruct {
-	UCHAR CR[15];
+typedef struct _SiS300_LVDSCRT1DataStruct
+{
+UCHAR CR[15];
 } SiS300_LVDSCRT1DataStruct;
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
-};
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1[]=
+{
+	{{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
+	  0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+	  0x00 }},
+	{{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+	  0x00 }},
+	{{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
+	  0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+	  0x00 }},
+	{{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+	  0x00 }},
+	{{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+	  0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+	  0x00 }},
+	{{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+	  0x01 }}
+};
+
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[]=
+{ 
+	{{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00}},
+	{{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00}},
+	{{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00}},
+	{{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00}},
+	{{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+	  0x00}},
+	{{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+	  0x01}},
+	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01} }
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[]=
+{
+	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+	  0x01 }},
+	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[]=
+{
+	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+	  0x00 }},
+	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+	  0x00 }},
+	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
+	  0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[]=
+{
+	{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00 }},
+	{{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+	  0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
+	  0x00}},
+	{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+	{{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+	  0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
+	  0x00}},
+	{{0x37,0x27,0x9B,0x2b,0x94,0x04,0x3e,
+	  0xE2,0x89,0xDf,0x05,0x00,0x00,0x44,
+	  0x00}},
+	{{0x41,0x31,0x85,0x35,0x1d,0x7c,0xf0,
+	  0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
+	  0x01}},
+	{{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+	  0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[]=
+{
+	{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+	  0x00 }},
+	{{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+	  0x00 }},
+	{{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
+	  0x00 }},
+	{{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+	  0x01 }},
+	{{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2[]=
+{
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
+	  0x00 }},
+	{{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[]=
+{
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+	  0x01 }},
+	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[]=
+{
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+	  0x01 }},
+	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[]=
+{
+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
+	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[]=
+{
+	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+	  0x01 }},
+	{{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[]=
+{
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+	  0x01 }},
+	{{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+/* TW: New */
+SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[]=
+{
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
+	  0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
+	  0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[]=
+{
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+	  0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+	  0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
+	  0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
+	  0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[]=
+{
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
+	  0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
+	  0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
+	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] = {
-	
-	    {
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00}}
+SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[]=
+{
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
+	  0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
+	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+	  0x01 }}
 };
+/* TW: New end */
 
-typedef struct _SiS300_CHTVRegDataStruct {
+/* TW: New */
+typedef struct _SiS300_CHTVRegDataStruct
+{
 	UCHAR Reg[5];
 } SiS300_CHTVRegDataStruct;
+
 SiS300_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] = {
-	{{0x00, 0x00, 0x00, 0x00, 0x00}}
+	{{0x4a,0x94,0x00,0x48,0xfe}},
+	{{0x4a,0x94,0x00,0x48,0xfe}},
+	{{0x4a,0x94,0x00,0x48,0xfe}},
+	{{0x4a,0x94,0x00,0x48,0xfe}},
+	{{0x6a,0x6a,0x00,0x2d,0xfa}}, /* Mode 17: 640x480 NTSC 7/8  */
+	{{0x8d,0xc4,0x00,0x3b,0xfb}}  /* Mode 24: 800x600 NTSC 7/10 */
 };
 
 SiS300_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] = {
-	{{0x00, 0x00, 0x00, 0x00, 0x00}}
+	{{0x49,0x94,0x00,0x34,0xfe}},
+	{{0x49,0x94,0x00,0x34,0xfe}},
+	{{0x49,0x94,0x00,0x34,0xfe}},
+	{{0x49,0x94,0x00,0x34,0xfe}},
+	{{0x69,0x6a,0x00,0x1e,0xfd}}, /* Mode 16: 640x480 NTSC 1/1 */
+	{{0x8c,0xb4,0x00,0x32,0xf9}}  /* Mode 23: 800x600 NTSC 3/4 */
 };
 
 SiS300_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] = {
-	{{0x00, 0x00, 0x00, 0x00, 0x00}}
+	{{0x41,0x12,0x01,0x50,0x34}},
+	{{0x41,0x12,0x00,0x50,0x00}},
+	{{0x41,0x12,0x01,0x50,0x34}},
+	{{0x41,0x12,0x00,0x50,0x00}},
+	{{0x63,0x94,0x01,0x50,0x30}}, /* Mode 15: 640x480 PAL 5/6 */
+	/* TW: For 800x600, 3/4 is VERY underscan */
+	{{0x84,0x64,0x01,0x4e,0x2f}}  /* Mode 21: 800x600 PAL 3/4 */
+	/* TW: Mode 20 is still underscan, use it instead? */
+	/* {{0x83,0x76,0x01,0x40,0x31}} */ /* Mode 20: 800x600 PAL 5/6 */
 };
 
 SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] = {
-	{{0x00, 0x00, 0x00, 0x00, 0x00}}
+	{{0x41,0x12,0x01,0x50,0x34}}, /* Mode 9: 640x400 PAL 1/1 */
+	{{0x41,0x12,0x00,0x50,0x00}},
+	{{0x41,0x12,0x01,0x50,0x34}},
+	{{0x41,0x12,0x00,0x50,0x00}},
+	{{0x61,0x94,0x01,0x36,0x30}}, /* Mode 14: 640x480 PAL 1/1 */
+	{{0x83,0x76,0x01,0x40,0x31}}  /* Mode 20: 800x600 PAL 5/6 */
+	/* {{0x81,0x12,0x01,0x50,0x34}}  */ /* TW: (test) Mode 19: 800x600 PAL 1/1 */
 };
+/* TW: New end */
+
+/* TW: New */
+UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+
+UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
 
-UCHAR SiS300_CHTVVCLKUNTSC[] = { 0x00 };
+UCHAR SiS300_CHTVVCLKUPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31};
 
-UCHAR SiS300_CHTVVCLKONTSC[] = { 0x00 };
+UCHAR SiS300_CHTVVCLKOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+/* TW: New end */
 
-UCHAR SiS300_CHTVVCLKUPAL[] = { 0x00 };
 
-UCHAR SiS300_CHTVVCLKOPAL[] = { 0x00 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/310vtbl.h linux/drivers/video/sis/310vtbl.h
--- linux.orig/drivers/video/sis/310vtbl.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/310vtbl.h	2002-07-20 01:08:23.000000000 +0000
@@ -1,4 +1,5 @@
-typedef struct _SiS310_StStruct {
+typedef struct _SiS310_StStruct
+{
 	UCHAR St_ModeID;
 	USHORT St_ModeFlag;
 	UCHAR St_StTableIndex;
@@ -9,31 +10,32 @@
 	UCHAR VB_StTVYFilterIndex;
 } SiS310_StStruct;
 
-SiS310_StStruct SiS310_SModeIDTable[] =
+SiS310_StStruct SiS310_SModeIDTable[]=
 {
-	{0x01, 0x9208, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
-	{0x01, 0x1210, 0x14, 0x01, 0x01, 0x00, 0x01, 0x00},
-	{0x01, 0x1010, 0x17, 0x02, 0x02, 0x00, 0x01, 0x01},
-	{0x03, 0x8208, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02},
-	{0x03, 0x0210, 0x16, 0x01, 0x01, 0x00, 0x01, 0x02},
-	{0x03, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x01, 0x03},
-	{0x05, 0x9209, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x06, 0x8209, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05},
-	{0x07, 0x0000, 0x07, 0x03, 0x03, 0x00, 0x01, 0x03},
-	{0x07, 0x0000, 0x19, 0x02, 0x02, 0x00, 0x01, 0x03},
-	{0x0d, 0x920a, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x0e, 0x820a, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x05},
-	{0x0f, 0x0202, 0x11, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0x10, 0x0212, 0x12, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0x11, 0x0212, 0x1a, 0x04, 0x04, 0x00, 0x00, 0x05},
-	{0x12, 0x0212, 0x1b, 0x04, 0x04, 0x00, 0x00, 0x05},
-	{0x13, 0x021b, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x12, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x00, 0x05},
-	{0x12, 0x0210, 0x18, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+	{0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00},
+	{0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00},
+	{0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01},
+	{0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02},
+	{0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02},
+	{0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03},
+	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04},
+	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05},
+	{0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03},
+	{0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03},
+	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04},
+	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05},
+	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05},
+	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05},
+	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05},
+	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05},
+	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04},
+	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05},
+	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05},
+	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS310_StandTableStruct {
+typedef struct _SiS310_StandTableStruct
+{
 	UCHAR CRT_COLS;
 	UCHAR ROWS;
 	UCHAR CHAR_HEIGHT;
@@ -45,444 +47,446 @@
 	UCHAR GRC[9];
 } SiS310_StandTableStruct;
 
-SiS310_StandTableStruct SiS310_StandTable[] = {
+SiS310_StandTableStruct SiS310_StandTable[]=
+{
 /* MD_0_200 */
-	{
-	 0x28, 0x18, 0x08, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_1_200 */
-	{
-	 0x28, 0x18, 0x08, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_2_200 */
-	{
-	 0x50, 0x18, 0x08, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_3_200 */
-	{
-	 0x50, 0x18, 0x08, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_4 */
-	{
-	 0x28, 0x18, 0x08, 0x4000,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
-	  0xff},
-	 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x03, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff}
+ },
 /* MD_5 */
-	{
-	 0x28, 0x18, 0x08, 0x4000,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
-	  0xff},
-	 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x03, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff}
+ },
 /* MD_6 */
-	{
-	 0x50, 0x18, 0x08, 0x4000,
-	 {0x01, 0x01, 0x00, 0x06},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
-	  0xff},
-	 {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-	  0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-	  0x01, 0x00, 0x01, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x08,0x4000,
+  {0x01,0x01,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+   0xff},
+  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x01,0x00,0x01,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+   0xff}
+ },
 /* MD_7 */
-	{
-	 0x50, 0x18, 0x0e, 0x1000,
-	 {0x00, 0x03, 0x00, 0x03},
-	 0xa6,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x0d, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	  0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	  0x0e, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x00,0x03,0x00,0x03},
+  0xa6,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff}
+ },
 /* MDA_DAC */
-	{
-	 0x00, 0x00, 0x00, 0x0000,
-	 {0x00, 0x00, 0x00, 0x15},
-	 0x15,
-	 {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f,
-	  0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x00,
-	  0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15},
-	 {0x15, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x3f}
-	 },
+ {
+  0x00,0x00,0x00,0x0000,
+  {0x00,0x00,0x00,0x15},
+  0x15,
+  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15},
+  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f}
+ },
 /* CGA_DAC */
-	{
-	 0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x09, 0x15, 0x00},
-	 0x10,
-	 {0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a,
-	  0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x2a, 0x3a,
-	  0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x10,
-	  0x04},
-	 {0x14, 0x01, 0x11, 0x09, 0x15, 0x00, 0x10, 0x04,
-	  0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a, 0x2e,
-	  0x3e, 0x2b, 0x3b, 0x2f},
-	 {0x3f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f,
-	  0x3f}
-	 },
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x00},
+  0x10,
+  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+   0x04},
+  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+   0x3e,0x2b,0x3b,0x2f},
+  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f}
+ },
 /* EGA_DAC */
-	{
-	 0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x05, 0x15, 0x20},
-	 0x30,
-	 {0x24, 0x34, 0x21, 0x31, 0x25, 0x35, 0x08, 0x18,
-	  0x0c, 0x1c, 0x09, 0x19, 0x0d, 0x1d, 0x28, 0x38,
-	  0x2c, 0x3c, 0x29, 0x39, 0x2d, 0x3d, 0x02, 0x12,
-	  0x06},
-	 {0x16, 0x03, 0x13, 0x07, 0x17, 0x22, 0x32, 0x26,
-	  0x36, 0x23, 0x33, 0x27, 0x37, 0x0a, 0x1a, 0x0e,
-	  0x1e, 0x0b, 0x1b, 0x0f},
-	 {0x1f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f,
-	  0x3f}
-	 },
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x05,0x15,0x20},
+  0x30,
+  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+   0x06},
+  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+   0x1e,0x0b,0x1b,0x0f},
+  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f}
+ },
 /* VGA_DAC */
-	{
-	 0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x09, 0x15, 0x2a},
-	 0x3a,
-	 {0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x05,
-	  0x08, 0x0b, 0x0e, 0x11, 0x14, 0x18, 0x1c, 0x20,
-	  0x24, 0x28, 0x2d, 0x32, 0x38, 0x3f, 0x00, 0x10,
-	  0x1f},
-	 {0x2f, 0x3f, 0x1f, 0x27, 0x2f, 0x37, 0x3f, 0x2d,
-	  0x31, 0x36, 0x3a, 0x3f, 0x00, 0x07, 0x0e, 0x15,
-	  0x1c, 0x0e, 0x11, 0x15},
-	 {0x18, 0x1c, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x00,
-	  0x04}
-	 },
-	{
-	 0x08, 0x0c, 0x10, 0x0a08,
-	 {0x0c, 0x0e, 0x10, 0x0b},
-	 0x0c,
-	 {0x0d, 0x0f, 0x10, 0x10, 0x01, 0x08, 0x00, 0x00,
-	  0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x00,
-	  0x04, 0x04, 0x01, 0x00, 0x05, 0x02, 0x05, 0x00,
-	  0x06},
-	 {0x01, 0x06, 0x05, 0x06, 0x00, 0x08, 0x01, 0x08,
-	  0x00, 0x07, 0x02, 0x07, 0x06, 0x07, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00}
-	 },
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x2a},
+  0x3a,
+  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+   0x1f},
+  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+   0x1c,0x0e,0x11,0x15},
+  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+   0x04}
+ },
+ {
+  0x08,0x0c,0x10,0x0a08,
+  {0x0c,0x0e,0x10,0x0b},
+  0x0c,
+  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+   0x06},
+  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}
+ },
 /* MD_D */
-	{
-	 0x28, 0x18, 0x08, 0x2000,
-	 {0x09, 0x0f, 0x00, 0x06},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x2000,
+  {0x09,0x0f,0x00,0x06},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
 /* MD_E */
-	{
-	 0x50, 0x18, 0x08, 0x4000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x08,0x4000,
+  {0x01,0x0f,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
 /* ExtVGATable */
-	{
-	 0x00, 0x00, 0x00, 0x0000,
-	 {0x01, 0x0f, 0x00, 0x0e},
-	 0x23,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-	  0x01, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x00,0x00,0x00,0x0000,
+  {0x01,0x0f,0x00,0x0e},
+  0x23,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x01,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff}
+ },
 /* ROM_SAVEPTR */
-	{
-	 0x9f, 0x3b, 0x00, 0x00c0,
-	 {0x00, 0x00, 0x00, 0x00},
-	 0x00,
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x3f,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x1a, 0x00, 0xac, 0x3e, 0x00, 0xc0,
-	  0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00}
-	 },
+ {
+  0x9f,0x3b,0x00,0x00c0,
+  {0x00,0x00,0x00,0x00},
+  0x00,
+  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}
+ },
 /* MD_F */
-	{
-	 0x50, 0x18, 0x0e, 0x8000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xa2,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
-	  0xff},
-	 {0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
-	  0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
-	  0x0b, 0x00, 0x05, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa2,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+   0xff},
+  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+   0x0b,0x00,0x05,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+   0xff}
+ },
 /* MD_10 */
-	{
-	 0x50, 0x18, 0x0e, 0x8000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
 /* MD_0_350 */
-	{
-	 0x28, 0x18, 0x0e, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_1_350 */
-	{
-	 0x28, 0x18, 0x0e, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_2_350 */
-	{
-	 0x50, 0x18, 0x0e, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_3_350 */
-	{
-	 0x50, 0x18, 0x0e, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_0_1_400 */
-	{
-	 0x28, 0x18, 0x10, 0x0800,
-	 {0x08, 0x03, 0x00, 0x02},
-	 0x67,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x0c, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x10,0x0800,
+  {0x08,0x03,0x00,0x02},
+  0x67,
+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_2_3_400 */
-	{
-	 0x50, 0x18, 0x10, 0x1000,
-	 {0x00, 0x03, 0x00, 0x02},
-	 0x67,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x0c, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x67,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_7_400 */
-	{
-	 0x50, 0x18, 0x10, 0x1000,
-	 {0x00, 0x03, 0x00, 0x02},
-	 0x66,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	  0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	  0x0e, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x66,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff}
+ },
 /* MD_11 */
-	{
-	 0x50, 0x1d, 0x10, 0xa000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xe3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3,
-	  0xff},
-	 {0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01,
-	  0xff}
-	 },
+ {
+  0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+   0xff},
+  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+   0xff}
+ },
 /* ExtEGATable */
-	{
-	 0x50, 0x1d, 0x10, 0xa000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xe3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
 /* MD_13 */
-	{
-	 0x28, 0x18, 0x08, 0x2000,
-	 {0x01, 0x0f, 0x00, 0x0e},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-	  0x41, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
-	  0xff}
-	 }
+ {
+  0x28,0x18,0x08,0x2000,
+  {0x01,0x0f,0x00,0x0e},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x41,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff}
+ }
 };
 
-typedef struct _SiS310_ExtStruct {
+typedef struct _SiS310_ExtStruct
+{
 	UCHAR Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
@@ -495,633 +499,615 @@
 	UCHAR VB_ExtTVYFilterIndex;
 	UCHAR REFindex;
 } SiS310_ExtStruct;
-SiS310_ExtStruct SiS310_EModeIDTable[] = {
-	
-	    {0x6a, 0x2212, 0x0407, 0x3a81, 0x0102, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x2e, 0x0a1b, 0x0306, 0x3a57, 0x0101, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x2f, 0x0a1b, 0x0305, 0x3a50, 0x0100, 0x08, 0x05, 0x00, 0x00, 0x05,
-	 0x10},
-	{0x30, 0x2a1b, 0x0407, 0x3a81, 0x0103, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x31, 0x0a1b, 0x030d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x32, 0x0a1b, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x33, 0x0a1d, 0x0a0d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x34, 0x2a1d, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x35, 0x0a1f, 0x0a0d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x36, 0x2a1f, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x37, 0x0212, 0x0508, 0x3aab, 0x0104, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x38, 0x0a1b, 0x0508, 0x3aab, 0x0105, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x3a, 0x0e3b, 0x0609, 0x3adc, 0x0107, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x3c, 0x063b, 0x070a, 0x3af2, 0x0130, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x3d, 0x067d, 0x070a, 0x3af2, 0x0131, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x40, 0x9a1c, 0x0000, 0x3a34, 0x010d, 0x08, 0x00, 0x00, 0x00, 0x04,
-	 0x25},
-	{0x41, 0x9a1d, 0x0000, 0x3a34, 0x010e, 0x08, 0x00, 0x00, 0x00, 0x04,
-	 0x25},
-	{0x43, 0x0a1c, 0x0306, 0x3a57, 0x0110, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x44, 0x0a1d, 0x0306, 0x3a57, 0x0111, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x46, 0x2a1c, 0x0407, 0x3a81, 0x0113, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x47, 0x2a1d, 0x0407, 0x3a81, 0x0114, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x49, 0x0a3c, 0x0508, 0x3aab, 0x0116, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x4a, 0x0a3d, 0x0508, 0x3aab, 0x0117, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x4c, 0x0e7c, 0x0609, 0x3adc, 0x0119, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x4d, 0x0e7d, 0x0609, 0x3adc, 0x011a, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x50, 0x9a1b, 0x0001, 0x3a3b, 0x0132, 0x08, 0x01, 0x00, 0x00, 0x04,
-	 0x26},
-	{0x51, 0xba1b, 0x0103, 0x3a42, 0x0133, 0x08, 0x03, 0x00, 0x00, 0x07,
-	 0x27},
-	{0x52, 0x9a1b, 0x0204, 0x3a49, 0x0134, 0x08, 0x04, 0x00, 0x00, 0x00,
-	 0x28},
-	{0x56, 0x9a1d, 0x0001, 0x3a3b, 0x0135, 0x08, 0x01, 0x00, 0x00, 0x04,
-	 0x26},
-	{0x57, 0xba1d, 0x0103, 0x3a42, 0x0136, 0x08, 0x03, 0x00, 0x00, 0x07,
-	 0x27},
-	{0x58, 0x9a1d, 0x0204, 0x3a49, 0x0137, 0x08, 0x04, 0x00, 0x00, 0x00,
-	 0x28},
-	{0x59, 0x9a1b, 0x0000, 0x3a34, 0x0138, 0x08, 0x00, 0x00, 0x00, 0x04,
-	 0x25},
-	{0x5d, 0x0a1d, 0x0305, 0x3a50, 0x0139, 0x08, 0x05, 0x00, 0x00, 0x07,
-	 0x10},
-	{0x62, 0x0a3f, 0x0306, 0x3a57, 0x013a, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x63, 0x2a3f, 0x0407, 0x3a81, 0x013b, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x64, 0x0a7f, 0x0508, 0x3aab, 0x013c, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x65, 0x0eff, 0x0609, 0x3adc, 0x013d, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x66, 0x06ff, 0x070a, 0x3af2, 0x013e, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x68, 0x067b, 0x080b, 0x3b17, 0x013f, 0x08, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x69, 0x06fd, 0x080b, 0x3b17, 0x0140, 0x08, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x6b, 0x07ff, 0x080b, 0x3b17, 0x0141, 0x10, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x6c, 0x067b, 0x090c, 0x3b37, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x6d, 0x06fd, 0x090c, 0x3b37, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x6e, 0x07ff, 0x090c, 0x3b37, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x70, 0x2a1b, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x71, 0x0a1b, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x74, 0x0a1d, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x75, 0x0a3d, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x76, 0x2a1f, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x77, 0x0a1f, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x78, 0x0a3f, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x79, 0x0a3b, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x7a, 0x2a1d, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x7b, 0x0e3b, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0x7c, 0x0e7d, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0x7d, 0x0eff, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0xff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00}
+
+SiS310_ExtStruct  SiS310_EModeIDTable[]=
+{
+	{0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},
+	{0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},
+	{0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},
+	{0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},
+	{0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+	{0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+	{0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+	{0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+	{0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+	{0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+	{0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},
+	{0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},
+	{0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},
+	{0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
+	{0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
+	{0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
+	{0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
+	{0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
+	{0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08},
+	{0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
+	{0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},
+	{0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+	{0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
+	{0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+	{0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
+	{0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},
+	{0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
+	{0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},
+	{0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
+	{0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
+	{0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},
+	{0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},
+	{0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f}, /*fstn add new mode*/
+	{0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f}, /*fstn add new mode*/
+	{0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
+	{0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},
+	{0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},
+	{0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
+	{0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
+	{0x66,0x06ff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
+	{0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},
+	{0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},
+	{0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},
+	{0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},
+	{0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
+	{0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
+	{0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+	{0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+	{0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+	{0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+	{0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+	{0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+	{0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+	{0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+	{0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+	{0x7b,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+	{0x7c,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+	{0x7d,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+	{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS310_Ext2Struct {
+typedef struct _SiS310_Ext2Struct
+{
 	USHORT Ext_InfoFlag;
 	UCHAR Ext_CRT1CRTC;
 	UCHAR Ext_CRTVCLK;
 	UCHAR Ext_CRT2CRTC;
-	UCHAR ModeID;
+	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
 	USHORT ROM_OFFSET;
 } SiS310_Ext2Struct;
-SiS310_Ext2Struct SiS310_RefIndex[] = {
-	{0x005f, 0x0d, 0x03, 0x05, 0x6a, 800, 600, 0x3a81},	/* 0x0 */
-	{0x0467, 0x0e, 0x04, 0x05, 0x6a, 800, 600, 0x3a86},	/* 0x1 */
-	{0x0067, 0x0f, 0x08, 0x48, 0x6a, 800, 600, 0x3a8b},	/* 0x2 */
-	{0x0067, 0x10, 0x07, 0x8b, 0x6a, 800, 600, 0x3a90},	/* 0x3 */
-	{0x0147, 0x11, 0x0a, 0x00, 0x6a, 800, 600, 0x3a95},	/* 0x4 */
-	{0x4147, 0x12, 0x0d, 0x00, 0x6a, 800, 600, 0x3a9a},	/* 0x5 */
-	{0x4047, 0x13, 0x13, 0x00, 0x6a, 800, 600, 0x3a9f},	/* 0x6 */
-	{0x4047, 0x14, 0x1c, 0x00, 0x6a, 800, 600, 0x3aa4},	/* 0x7 */
-	{0xc05f, 0x05, 0x00, 0x04, 0x2e, 640, 480, 0x3a57},	/* 0x8 */
-	{0xc067, 0x06, 0x02, 0x04, 0x2e, 640, 480, 0x3a5c},	/* 0x9 */
-	{0xc067, 0x07, 0x02, 0x47, 0x2e, 640, 480, 0x3a61},	/* 0xa */
-	{0xc067, 0x08, 0x03, 0x8a, 0x2e, 640, 480, 0x3a66},	/* 0xb */
-	{0x4047, 0x09, 0x05, 0x00, 0x2e, 640, 480, 0x3a6b},	/* 0xc */
-	{0x4047, 0x0a, 0x09, 0x00, 0x2e, 640, 480, 0x3a70},	/* 0xd */
-	{0x4047, 0x0b, 0x0e, 0x00, 0x2e, 640, 480, 0x3a75},	/* 0xe */
-	{0xc047, 0x0c, 0x15, 0x00, 0x2e, 640, 480, 0x3a7a},	/* 0xf */
-	{0x407f, 0x04, 0x00, 0x00, 0x2f, 640, 400, 0x3a50},	/* 0x10 */
-	{0xc00f, 0x3c, 0x01, 0x06, 0x31, 720, 480, 0x3b85},	/* 0x11 */
-	{0x000f, 0x3d, 0x03, 0x06, 0x32, 720, 576, 0x3b8c},	/* 0x12 */
-	{0x0187, 0x15, 0x06, 0x00, 0x37, 1024, 768, 0x3aab},	/* 0x13 */
-	{0xc877, 0x16, 0x0b, 0x06, 0x37, 1024, 768, 0x3ab0},	/* 0x14 301b TV1024x768 */
-	{0xc067, 0x17, 0x0f, 0x49, 0x37, 1024, 768, 0x3ab5},	/* 0x15 */
-	{0x0267, 0x18, 0x11, 0x00, 0x37, 1024, 768, 0x3aba},	/* 0x16 */
-	{0x0047, 0x19, 0x16, 0x8c, 0x37, 1024, 768, 0x3abf},	/* 0x17 */
-	{0x4047, 0x1a, 0x1b, 0x00, 0x37, 1024, 768, 0x3ac4},	/* 0x18 */
-	{0x4047, 0x1b, 0x1f, 0x00, 0x37, 1024, 768, 0x3ac9},	/* 0x19 */
-	{0x0387, 0x1c, 0x11, 0x00, 0x3a, 1280, 1024, 0x3adc},	/* 0x1a */
-	{0x0077, 0x1d, 0x19, 0x07, 0x3a, 1280, 1024, 0x3ae1},	/* 0x1b */
-	{0x0047, 0x1e, 0x1e, 0x00, 0x3a, 1280, 1024, 0x3ae6},	/* 0x1c */
-	{0x0007, 0x1f, 0x20, 0x00, 0x3a, 1280, 1024, 0x3aeb},	/* 0x1d */
-	{0x0007, 0x20, 0x21, 0x00, 0x3c, 1600, 1200, 0x3af2},	/* 0x1e */
-	{0x0007, 0x21, 0x22, 0x00, 0x3c, 1600, 1200, 0x3af7},	/* 0x1f */
-	{0x0007, 0x22, 0x23, 0x00, 0x3c, 1600, 1200, 0x3afc},	/* 0x20 */
-	{0x0007, 0x23, 0x25, 0x00, 0x3c, 1600, 1200, 0x3b01},	/* 0x21 */
-	{0x0007, 0x24, 0x26, 0x00, 0x3c, 1600, 1200, 0x3b06},	/* 0x22 */
-	{0x0007, 0x25, 0x2c, 0x00, 0x3c, 1600, 1200, 0x3b0b},	/* 0x23 */
-	{0x0007, 0x26, 0x34, 0x00, 0x3c, 1600, 1200, 0x3b10},	/* 0x24 */
-	{0x407f, 0x00, 0x00, 0x00, 0x40, 320, 200, 0x3a34},	/* 0x25 */
-	{0xc07f, 0x01, 0x00, 0x04, 0x50, 320, 240, 0x3a3b},	/* 0x26 */
-	{0x007f, 0x02, 0x04, 0x05, 0x51, 400, 300, 0x3a42},	/* 0x27 */
-	{0xc077, 0x03, 0x0b, 0x06, 0x52, 512, 384, 0x3a49},	/* 0x28 */
-	{0x8007, 0x27, 0x27, 0x00, 0x68, 1920, 1440, 0x3b17},	/* 0x29 */
-	{0x4007, 0x28, 0x29, 0x00, 0x68, 1920, 1440, 0x3b1c},	/* 0x2a */
-	{0x4007, 0x29, 0x2e, 0x00, 0x68, 1920, 1440, 0x3b21},	/* 0x2b */
-	{0x4007, 0x2a, 0x30, 0x00, 0x68, 1920, 1440, 0x3b26},	/* 0x2c */
-	{0x4007, 0x2b, 0x35, 0x00, 0x68, 1920, 1440, 0x3b2b},	/* 0x2d */
-	{0x4005, 0x2c, 0x39, 0x00, 0x68, 1920, 1440, 0x3b30},	/* 0x2e */
-	{0x4007, 0x2d, 0x2b, 0x00, 0x6c, 2048, 1536, 0x3b37},	/* 0x2f */
-	{0x4007, 0x2e, 0x31, 0x00, 0x6c, 2048, 1536, 0x3b3c},	/* 0x30 */
-	{0x4007, 0x2f, 0x33, 0x00, 0x6c, 2048, 1536, 0x3b41},	/* 0x31 */
-	{0x4007, 0x30, 0x37, 0x00, 0x6c, 2048, 1536, 0x3b46},	/* 0x32 */
-	{0x4005, 0x31, 0x38, 0x00, 0x6c, 2048, 1536, 0x3b4b},	/* 0x33 */
-	{0x0057, 0x32, 0x40, 0x08, 0x70, 800, 480, 0x3b52},	/* 0x34 */
-	{0x0047, 0x33, 0x07, 0x08, 0x70, 800, 480, 0x3b57},	/* 0x35 */
-	{0x0047, 0x34, 0x0a, 0x08, 0x70, 800, 480, 0x3b5c},	/* 0x36 */
-	{0x0057, 0x35, 0x0b, 0x09, 0x71, 1024, 576, 0x3b63},	/* 0x37 */
-	{0x0047, 0x36, 0x11, 0x09, 0x71, 1024, 576, 0x3b68},	/* 0x38 */
-	{0x0047, 0x37, 0x16, 0x09, 0x71, 1024, 576, 0x3b6d},	/* 0x39 */
-	{0x0057, 0x38, 0x19, 0x0a, 0x75, 1280, 720, 0x3b74},	/* 0x3a */
-	{0x0047, 0x39, 0x1e, 0x0a, 0x75, 1280, 720, 0x3b79},	/* 0x3b */
-	{0x0047, 0x3a, 0x20, 0x0a, 0x75, 1280, 720, 0x3b7e},	/* 0x3c */
-	{0x0027, 0x3b, 0x19, 0x08, 0x7b, 1280, 960, 0x3ad0},	/* 0x3d */
-	{0x0027, 0x3b, 0x19, 0x08, 0x7b, 1280, 960, 0x3ad5},	/* 0x3e */
-	{0xffff, 0x00, 0x00, 0x00, 0x00, 0000, 0000, 0x0000}
+
+SiS310_Ext2Struct SiS310_RefIndex[]=
+{
+	{0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
+	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
+	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
+	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
+	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
+	{0x4147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 */
+	{0x4047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 */
+	{0x4047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 */
+	{0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
+	{0x4047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc */
+	{0x4047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd */
+	{0x4047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe */
+	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
+	{0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
+	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
+	{0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
+	{0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
+	{0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 301b TV1024x768*/
+	{0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
+	{0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
+	{0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
+	{0x4047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 */
+	{0x4047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 */
+	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
+	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
+	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
+	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
+	{0x0007,0x20,0x21,0x00,0x3c,1600,1200,0x3af2}, /* 0x1e */
+	{0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
+	{0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
+	{0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
+	{0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
+	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
+	{0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
+	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
+	{0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
+	{0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
+	{0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
+	{0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
+	{0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
+	{0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
+	{0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
+	{0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
+	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
+	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
+	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
+	{0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
+	{0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
+	{0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
+	{0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
+	{0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
+	{0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
+	{0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
+	{0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
+	{0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
+	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
+	{0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
+	{0x0027,0x3b,0x19,0x08,0x7b,1280, 960,0x3ad0}, /* 0x3d */
+	{0x0027,0x3b,0x19,0x08,0x7b,1280, 960,0x3ad5}, /* 0x3e */
+	{0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */    /*fstn add new mode */
+	{0xffff,0x00,0x00,0x00,0x00,0000,0000,0x0000}
 };
 
-typedef struct _SiS310_CRT1TableStruct {
-	UCHAR CR[17];
+typedef struct _SiS310_CRT1TableStruct
+{
+ 	UCHAR CR[17];
 } SiS310_CRT1TableStruct;
-
-SiS310_CRT1TableStruct SiS310_CRT1Table[] = {
-	{{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x00,
-	  0x00}},		/* 0x0 */
-	{{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x00,
-	  0x00}},		/* 0x1 */
-	{{0x3d, 0x31, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x05,
-	  0x01}},		/* 0x2 */
-	{{0x4f, 0x3f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}},		/* 0x3 */
-	{{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x05,
-	  0x00}},		/* 0x4 */
-	{{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	  0x00}},		/* 0x5 */
-	{{0x63, 0x4f, 0x50, 0x86, 0x56, 0x9b, 0x06, 0x3e,
-	  0xe8, 0x8b, 0xdf, 0xe7, 0xff, 0x10, 0x00, 0x01,
-	  0x00}},		/* 0x6 */
-	{{0x64, 0x4f, 0x4f, 0x88, 0x55, 0x9d, 0xf2, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xf3, 0x10, 0x00, 0x01,
-	  0x00}},		/* 0x7 */
-	{{0x63, 0x4f, 0x4f, 0x87, 0x5a, 0x81, 0xfb, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05,
-	  0x00}},		/* 0x8 */
-	{{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0xfb, 0x1f,
-	  0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x00, 0x00, 0x05,
-	  0x61}},		/* 0x9 */
-	{{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0x01, 0x3e,
-	  0xe0, 0x83, 0xdf, 0xdf, 0x02, 0x00, 0x00, 0x05,
-	  0x61}},		/* 0xa */
-	{{0x67, 0x4f, 0x4f, 0x8b, 0x58, 0x81, 0x0d, 0x3e,
-	  0xe0, 0x83, 0xdf, 0xdf, 0x0e, 0x10, 0x00, 0x05,
-	  0x61}},		/* 0xb */
-	{{0x65, 0x4f, 0x4f, 0x89, 0x57, 0x9f, 0xfb, 0x1f,
-	  0xe6, 0x8a, 0xe5, 0xe5, 0xfc, 0x00, 0x00, 0x01,
-	  0x00}},		/* 0xc */
-	{{0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	  0x58, 0x8a, 0x57, 0x57, 0x70, 0x20, 0x00, 0x05,
-	  0x01}},		/* 0xd */
-	{{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}},		/* 0xe */
-	{{0x7d, 0x63, 0x63, 0x81, 0x6e, 0x1d, 0x98, 0xf0,
-	  0x7c, 0x82, 0x57, 0x57, 0x99, 0x00, 0x00, 0x06,
-	  0x01}},		/* 0xf */
-	{{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x70, 0x20, 0x00, 0x06,
-	  0x01}},		/* 0x10 */
-	{{0x7e, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	  0x01}},		/* 0x11 */
-	{{0x81, 0x63, 0x63, 0x85, 0x6d, 0x18, 0x7a, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x7b, 0x20, 0x00, 0x06,
-	  0x61}},		/* 0x12 */
-	{{0x83, 0x63, 0x63, 0x87, 0x6e, 0x19, 0x81, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x82, 0x20, 0x00, 0x06,
-	  0x61}},		/* 0x13 */
-	{{0x85, 0x63, 0x63, 0x89, 0x6f, 0x1a, 0x91, 0xf0,
-	  0x58, 0x8b, 0x57, 0x57, 0x92, 0x20, 0x00, 0x06,
-	  0x61}},		/* 0x14 */
-	{{0x99, 0x7f, 0x7f, 0x9d, 0x84, 0x1a, 0x96, 0x1f,
-	  0x7f, 0x83, 0x7f, 0x7f, 0x97, 0x10, 0x00, 0x02,
-	  0x00}},		/* 0x15 */
-	{{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}},		/* 0x16 */
-	{{0xa1, 0x7f, 0x7f, 0x85, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}},		/* 0x17 */
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02,
-	  0x01}},		/* 0x18 */
-	{{0xa7, 0x7f, 0x7f, 0x8b, 0x89, 0x95, 0x26, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x27, 0x10, 0x00, 0x02,
-	  0x01}},		/* 0x19 */
-	{{0xa9, 0x7f, 0x7f, 0x8d, 0x8c, 0x9a, 0x2c, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x2d, 0x14, 0x00, 0x02,
-	  0x62}},		/* 0x1a */
-	{{0xab, 0x7f, 0x7f, 0x8f, 0x8d, 0x9b, 0x35, 0xf5,
-	  0x00, 0x83, 0xff, 0xff, 0x36, 0x14, 0x00, 0x02,
-	  0x62}},		/* 0x1b */
-	{{0xcf, 0x9f, 0x9f, 0x93, 0xb2, 0x01, 0x14, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x15, 0x00, 0x00, 0x03,
-	  0x00}},		/* 0x1c */
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	  0x01}},		/* 0x1d */
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	  0x01}},		/* 0x1e */
-	{{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0x5a,
-	  0x00, 0x83, 0xff, 0xff, 0x2f, 0x09, 0x00, 0x07,
-	  0x01}},		/* 0x1f */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x20 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x21 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x22 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x23 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x24 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x25 */
-	{{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	  0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	  0x00}},		/* 0x26 */
-	{{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	  0x00}},		/* 0x27 */
-	{{0x43, 0xef, 0xef, 0x87, 0x06, 0x00, 0xd4, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xd5, 0x1f, 0x41, 0x05,
-	  0x63}},		/* 0x28 */
-	{{0x45, 0xef, 0xef, 0x89, 0x07, 0x01, 0xd9, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xda, 0x1f, 0x41, 0x05,
-	  0x63}},		/* 0x29 */
-	{{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	  0x00}},		/* 0x2a */
-	{{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	  0x00}},		/* 0x2b */
-	{{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	  0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	  0x00}},		/* 0x2c */
-	{{0x59, 0xff, 0xff, 0x9d, 0x17, 0x13, 0x33, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x34, 0x0f, 0x41, 0x05,
-	  0x44}},		/* 0x2d */
-	{{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x38, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x39, 0x0f, 0x41, 0x05,
-	  0x44}},		/* 0x2e */
-	{{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x3d, 0xba,
-	  0x00, 0x83, 0xff, 0xff, 0x3e, 0x0f, 0x41, 0x05,
-	  0x44}},		/* 0x2f */
-	{{0x5d, 0xff, 0xff, 0x81, 0x19, 0x95, 0x41, 0xba,
-	  0x00, 0x84, 0xff, 0xff, 0x42, 0x0f, 0x41, 0x05,
-	  0x44}},		/* 0x30 */
-	{{0x55, 0xff, 0xff, 0x99, 0x0d, 0x0c, 0x3e, 0xba,
-	  0x00, 0x84, 0xff, 0xff, 0x3f, 0x0f, 0x41, 0x05,
-	  0x00}},		/* 0x31 */
-	{{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xba,
-	  0x27, 0x8b, 0xdf, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	  0x01}},		/* 0x32 */
-	{{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xba,
-	  0x26, 0x89, 0xdf, 0xdf, 0x6f, 0x00, 0x00, 0x06,
-	  0x01}},		/* 0x33 */
-	{{0x7f, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xba,
-	  0x29, 0x8c, 0xdf, 0xdf, 0x75, 0x00, 0x00, 0x06,
-	  0x01}},		/* 0x34 */
-	{{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf1,
-	  0xaf, 0x85, 0x3f, 0x3f, 0x25, 0x30, 0x00, 0x02,
-	  0x01}},		/* 0x35 */
-	{{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf1,
-	  0xad, 0x81, 0x3f, 0x3f, 0x1f, 0x30, 0x00, 0x02,
-	  0x01}},		/* 0x36 */
-	{{0xa7, 0x7f, 0x7f, 0x88, 0x89, 0x15, 0x26, 0xf1,
-	  0xb1, 0x85, 0x3f, 0x3f, 0x27, 0x30, 0x00, 0x02,
-	  0x01}},		/* 0x37 */
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0xc4,
-	  0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	  0x01}},		/* 0x38 */
-	{{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0xd4,
-	  0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	  0x01}},		/* 0x39 */
-	{{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0xd4,
-	  0x7d, 0x81, 0xcf, 0xcf, 0x2f, 0x21, 0x00, 0x07,
-	  0x01}},		/* 0x3a */
-	{{0xdc, 0x9f, 0x9f, 0x00, 0xab, 0x19, 0xe6, 0xef,
-	  0xc0, 0xc3, 0xbf, 0xbf, 0xe7, 0x10, 0x00, 0x07,
-	  0x01}},		/* 0x3b */
-	{{0x6b, 0x59, 0x59, 0x8f, 0x5e, 0x8c, 0x0b, 0x3e,
-	  0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	  0x00}},		/* 0x3c */
-	{{0x7b, 0x59, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	  0x58, 0x8a, 0x3f, 0x57, 0x70, 0x20, 0x00, 0x05,
-	  0x01}}		/* 0x3d */
+SiS310_CRT1TableStruct SiS310_CRT1Table[]=
+{
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+  0x00}}, /* 0x0 */
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+  0x00}}, /* 0x1 */
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+  0x01}}, /* 0x2 */
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+  0x01}}, /* 0x3 */
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+  0x00}}, /* 0x4 */
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}}, /* 0x5 */
+ {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
+  0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
+  0x00}}, /* 0x6 */
+ {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+  0x00}}, /* 0x7 */
+ {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+  0x00}}, /* 0x8 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x00,0x00,0x05,
+  0x61}}, /* 0x9 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
+  0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
+  0x61}}, /* 0xa */
+ {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
+  0xe0,0x83,0xdf,0xdf,0x0e,0x10,0x00,0x05,
+  0x61}}, /* 0xb */
+ {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+  0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
+  0x00}}, /* 0xc */
+ {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+  0x01}}, /* 0xd */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+  0x01}}, /* 0xe */
+ {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+  0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+  0x01}}, /* 0xf */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+  0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+  0x01}}, /* 0x10 */
+ {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+  0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}}, /* 0x11 */
+ {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
+  0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
+  0x61}}, /* 0x12 */
+ {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
+  0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
+  0x61}}, /* 0x13 */
+ {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
+  0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
+  0x61}}, /* 0x14 */
+ {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+  0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+  0x00}}, /* 0x15 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}}, /* 0x16 */
+ {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}}, /* 0x17 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+  0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+  0x01}}, /* 0x18 */
+ {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+  0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+  0x01}}, /* 0x19 */
+ {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
+  0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
+  0x62}}, /* 0x1a */
+ {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
+  0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
+  0x62}}, /* 0x1b */
+ {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+  0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+  0x00}}, /* 0x1c */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}}, /* 0x1d */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}}, /* 0x1e */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+  0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+  0x01}}, /* 0x1f */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}}, /* 0x20 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}}, /* 0x21 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}}, /* 0x22 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}}, /* 0x23 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}}, /* 0x24 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}}, /* 0x25 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}}, /* 0x26 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}}, /* 0x27 */
+ {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
+  0x63}}, /* 0x28 */
+ {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
+  0x63}}, /* 0x29 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}}, /* 0x2a */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}}, /* 0x2b */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}}, /* 0x2c */
+ {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
+  0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
+  0x44}}, /* 0x2d */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
+  0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
+  0x44}}, /* 0x2e */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
+  0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
+  0x44}}, /* 0x2f */
+ {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
+  0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
+  0x44}}, /* 0x30 */
+ {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+  0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+  0x00}}, /* 0x31 */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
+  0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+  0x01}}, /* 0x32 */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+  0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+  0x01}}, /* 0x33 */
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+  0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+  0x01}}, /* 0x34 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+  0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+  0x01}}, /* 0x35 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+  0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+  0x01}}, /* 0x36 */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
+  0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+  0x01}}, /* 0x37 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}}, /* 0x38 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}}, /* 0x39 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+  0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+  0x01}}, /* 0x3a */
+ {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
+  0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+  0x01}}, /* 0x3b */
+ {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}}, /* 0x3c */
+ {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+  0x01}}, /* 0x3d */
+ {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
+  0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
+  0x00}},/*3e*/
+  {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
+  0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
+  0x00}} ,/*3f*/
+  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+  0x00}}/*40*/ 
 };
 
-typedef struct _SiS310_MCLKDataStruct {
-	UCHAR SR28, SR29, SR2A;
+typedef struct _SiS310_MCLKDataStruct
+{
+	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS310_MCLKDataStruct;
-SiS310_MCLKDataStruct SiS310_MCLKData[] = {
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166}
+
+SiS310_MCLKDataStruct SiS310_MCLKData[]=
+{
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166}
 };
 
-typedef struct _SiS310_ECLKDataStruct {
-	UCHAR SR2E, SR2F, SR30;
-	USHORT CLOCK;
+typedef struct _SiS310_ECLKDataStruct
+{
+ 	UCHAR SR2E,SR2F,SR30;
+ 	USHORT CLOCK;
 } SiS310_ECLKDataStruct;
-SiS310_ECLKDataStruct SiS310_ECLKData[] = {
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166}
+SiS310_ECLKDataStruct SiS310_ECLKData[]=
+{
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166}
 };
 
-typedef struct _SiS310_VCLKDataStruct {
-	UCHAR SR2B, SR2C;
+typedef struct _SiS310_VCLKDataStruct
+{
+	UCHAR SR2B,SR2C;
 	USHORT CLOCK;
 } SiS310_VCLKDataStruct;
-SiS310_VCLKDataStruct SiS310_VCLKData[] = {
-	{0x1b, 0xe1, 25},	/* 0x0 */
-	{0x4e, 0xe4, 28},	/* 0x1 */
-	{0x57, 0xe4, 31},	/* 0x2 */
-	{0xc3, 0xc8, 36},	/* 0x3 */
-	{0x42, 0xe2, 40},	/* 0x4 */
-	{0xfe, 0xcd, 43},	/* 0x5 */
-	{0x5d, 0xc4, 44},	/* 0x6 */
-	{0x52, 0xe2, 49},	/* 0x7 */
-	{0x53, 0xe2, 50},	/* 0x8 */
-	{0x74, 0x67, 52},	/* 0x9 */
-	{0x6d, 0x66, 56},	/* 0xa */
-	{0x6c, 0xc3, 65},	/* 0xb */
-	{0x46, 0x44, 67},	/* 0xc */
-	{0xb1, 0x46, 68},	/* 0xd */
-	{0xd3, 0x4a, 72},	/* 0xe */
-	{0x29, 0x61, 75},	/* 0xf */
-	{0x6e, 0x46, 76},	/* 0x10 */
-	{0x2b, 0x61, 78},	/* 0x11 */
-	{0x31, 0x42, 79},	/* 0x12 */
-	{0xab, 0x44, 83},	/* 0x13 */
-	{0x46, 0x25, 84},	/* 0x14 */
-	{0x78, 0x29, 86},	/* 0x15 */
-	{0x62, 0x44, 94},	/* 0x16 */
-	{0x2b, 0x41, 104},	/* 0x17 */
-	{0x3a, 0x23, 105},	/* 0x18 */
-	{0x70, 0x44, 108},	/* 0x19 */
-	{0x3c, 0x23, 109},	/* 0x1a */
-	{0x5e, 0x43, 113},	/* 0x1b */
-	{0xbc, 0x44, 116},	/* 0x1c */
-	{0xe0, 0x46, 132},	/* 0x1d */
-	{0x54, 0x42, 135},	/* 0x1e */
-	{0xea, 0x2a, 139},	/* 0x1f */
-	{0x41, 0x22, 157},	/* 0x20 */
-	{0x70, 0x24, 162},	/* 0x21 */
-	{0x30, 0x21, 175},	/* 0x22 */
-	{0x4e, 0x22, 189},	/* 0x23 */
-	{0xde, 0x26, 194},	/* 0x24 */
-	{0x62, 0x06, 202},	/* 0x25 */
-	{0x3f, 0x03, 229},	/* 0x26 */
-	{0xb8, 0x06, 234},	/* 0x27 */
-	{0x34, 0x02, 253},	/* 0x28 */
-	{0x58, 0x04, 255},	/* 0x29 */
-	{0x24, 0x01, 265},	/* 0x2a */
-	{0x9b, 0x02, 267},	/* 0x2b */
-	{0x70, 0x05, 270},	/* 0x2c */
-	{0x25, 0x01, 272},	/* 0x2d */
-	{0x9c, 0x02, 277},	/* 0x2e */
-	{0x27, 0x01, 286},	/* 0x2f */
-	{0x3c, 0x02, 291},	/* 0x30 */
-	{0xef, 0x0a, 292},	/* 0x31 */
-	{0xf6, 0x0a, 310},	/* 0x32 */
-	{0x95, 0x01, 315},	/* 0x33 */
-	{0xf0, 0x09, 324},	/* 0x34 */
-	{0xfe, 0x0a, 331},	/* 0x35 */
-	{0xf3, 0x09, 332},	/* 0x36 */
-	{0xea, 0x08, 340},	/* 0x37 */
-	{0xe8, 0x07, 376},	/* 0x38 */
-	{0xde, 0x06, 389},	/* 0x39 */
-	{0x52, 0x2a, 54},	/* 0x3a */
-	{0x52, 0x6a, 27},	/* 0x3b */
-	{0x62, 0x24, 70},	/* 0x3c */
-	{0x62, 0x64, 70},	/* 0x3d */
-	{0xa8, 0x4c, 30},	/* 0x3e */
-	{0x20, 0x26, 33},	/* 0x3f */
-	{0x31, 0xc2, 39}	/* 0x40 */
+
+SiS310_VCLKDataStruct SiS310_VCLKData[]=
+{
+	{ 0x1b,0xe1, 25}, /* 0x0 */
+	{ 0x4e,0xe4, 28}, /* 0x1 */
+	{ 0x57,0xe4, 31}, /* 0x2 */
+	{ 0xc3,0xc8, 36}, /* 0x3 */
+	{ 0x42,0xe2, 40}, /* 0x4 */
+	{ 0xfe,0xcd, 43}, /* 0x5 */
+	{ 0x5d,0xc4, 44}, /* 0x6 */
+	{ 0x52,0xe2, 49}, /* 0x7 */
+	{ 0x53,0xe2, 50}, /* 0x8 */
+	{ 0x74,0x67, 52}, /* 0x9 */
+	{ 0x6d,0x66, 56}, /* 0xa */
+	{ 0x6c,0xc3, 65}, /* 0xb */
+	{ 0x46,0x44, 67}, /* 0xc */
+	{ 0xb1,0x46, 68}, /* 0xd */
+	{ 0xd3,0x4a, 72}, /* 0xe */
+	{ 0x29,0x61, 75}, /* 0xf */
+	{ 0x6e,0x46, 76}, /* 0x10 */
+	{ 0x2b,0x61, 78}, /* 0x11 */
+	{ 0x31,0x42, 79}, /* 0x12 */
+	{ 0xab,0x44, 83}, /* 0x13 */
+	{ 0x46,0x25, 84}, /* 0x14 */
+	{ 0x78,0x29, 86}, /* 0x15 */
+	{ 0x62,0x44, 94}, /* 0x16 */
+	{ 0x2b,0x41,104}, /* 0x17 */
+	{ 0x3a,0x23,105}, /* 0x18 */
+	{ 0x70,0x44,108}, /* 0x19 */
+	{ 0x3c,0x23,109}, /* 0x1a */
+	{ 0x5e,0x43,113}, /* 0x1b */
+	{ 0xbc,0x44,116}, /* 0x1c */
+	{ 0xe0,0x46,132}, /* 0x1d */
+	{ 0x54,0x42,135}, /* 0x1e */
+	{ 0xea,0x2a,139}, /* 0x1f */
+	{ 0x41,0x22,157}, /* 0x20 */
+	{ 0x70,0x24,162}, /* 0x21 */
+	{ 0x30,0x21,175}, /* 0x22 */
+	{ 0x4e,0x22,189}, /* 0x23 */
+	{ 0xde,0x26,194}, /* 0x24 */
+	{ 0x62,0x06,202}, /* 0x25 */
+	{ 0x3f,0x03,229}, /* 0x26 */
+	{ 0xb8,0x06,234}, /* 0x27 */
+	{ 0x34,0x02,253}, /* 0x28 */
+	{ 0x58,0x04,255}, /* 0x29 */
+	{ 0x24,0x01,265}, /* 0x2a */
+	{ 0x9b,0x02,267}, /* 0x2b */
+	{ 0x70,0x05,270}, /* 0x2c */
+	{ 0x25,0x01,272}, /* 0x2d */
+	{ 0x9c,0x02,277}, /* 0x2e */
+	{ 0x27,0x01,286}, /* 0x2f */
+	{ 0x3c,0x02,291}, /* 0x30 */
+	{ 0xef,0x0a,292}, /* 0x31 */
+	{ 0xf6,0x0a,310}, /* 0x32 */
+	{ 0x95,0x01,315}, /* 0x33 */
+	{ 0xf0,0x09,324}, /* 0x34 */
+	{ 0xfe,0x0a,331}, /* 0x35 */
+	{ 0xf3,0x09,332}, /* 0x36 */
+	{ 0xea,0x08,340}, /* 0x37 */
+	{ 0xe8,0x07,376}, /* 0x38 */
+	{ 0xde,0x06,389}, /* 0x39 */
+	{ 0x52,0x2a, 54}, /* 0x3a */
+	{ 0x52,0x6a, 27}, /* 0x3b */
+	{ 0x62,0x24, 70}, /* 0x3c */
+	{ 0x62,0x64, 70}, /* 0x3d */
+	{ 0xa8,0x4c, 30}, /* 0x3e */
+	{ 0x20,0x26, 33}, /* 0x3f */
+	{ 0x31,0xc2, 39}  /* 0x40 */
 };
 
-typedef struct _SiS310_VBVCLKDataStruct {
-	UCHAR Part4_A, Part4_B;
+typedef struct _SiS310_VBVCLKDataStruct
+{
+	UCHAR Part4_A,Part4_B;
 	USHORT CLOCK;
 } SiS310_VBVCLKDataStruct;
-SiS310_VBVCLKDataStruct SiS310_VBVCLKData[] = {
-	{0x1b, 0xe1, 25},	/* 0x0 */
-	{0x4e, 0xe4, 28},	/* 0x1 */
-	{0x57, 0xe4, 31},	/* 0x2 */
-	{0xc3, 0xc8, 36},	/* 0x3 */
-	{0x42, 0x47, 40},	/* 0x4 */
-	{0xfe, 0xcd, 43},	/* 0x5 */
-	{0x5d, 0xc4, 44},	/* 0x6 */
-	{0x52, 0x47, 49},	/* 0x7 */
-	{0x53, 0x47, 50},	/* 0x8 */
-	{0x74, 0x67, 52},	/* 0x9 */
-	{0x6d, 0x66, 56},	/* 0xa */
-	{0x5a, 0x64, 65},	/* 0xb */
-	{0x46, 0x44, 67},	/* 0xc */
-	{0xb1, 0x46, 68},	/* 0xd */
-	{0xd3, 0x4a, 72},	/* 0xe */
-	{0x29, 0x61, 75},	/* 0xf */
-	{0x6d, 0x46, 75},	/* 0x10 */
-	{0x41, 0x43, 78},	/* 0x11 */
-	{0x31, 0x42, 79},	/* 0x12 */
-	{0xab, 0x44, 83},	/* 0x13 */
-	{0x46, 0x25, 84},	/* 0x14 */
-	{0x78, 0x29, 86},	/* 0x15 */
-	{0x62, 0x44, 94},	/* 0x16 */
-	{0x2b, 0x22, 104},	/* 0x17 */
-	{0x49, 0x24, 105},	/* 0x18 */
-	{0xf8, 0x2f, 108},	/* 0x19 */
-	{0x3c, 0x23, 109},	/* 0x1a */
-	{0x5e, 0x43, 113},	/* 0x1b */
-	{0xbc, 0x44, 116},	/* 0x1c */
-	{0xe0, 0x46, 132},	/* 0x1d */
-	{0xd4, 0x28, 135},	/* 0x1e */
-	{0xea, 0x2a, 139},	/* 0x1f */
-	{0x41, 0x22, 157},	/* 0x20 */
-	{0x70, 0x24, 162},	/* 0x21 */
-	{0x30, 0x21, 175},	/* 0x22 */
-	{0x4e, 0x22, 189},	/* 0x23 */
-	{0xde, 0x26, 194},	/* 0x24 */
-	{0x70, 0x07, 202},	/* 0x25 */
-	{0x3f, 0x03, 229},	/* 0x26 */
-	{0xb8, 0x06, 234},	/* 0x27 */
-	{0x34, 0x02, 253},	/* 0x28 */
-	{0x58, 0x04, 255},	/* 0x29 */
-	{0x24, 0x01, 265},	/* 0x2a */
-	{0x9b, 0x02, 267},	/* 0x2b */
-	{0x70, 0x05, 270},	/* 0x2c */
-	{0x25, 0x01, 272},	/* 0x2d */
-	{0x9c, 0x02, 277},	/* 0x2e */
-	{0x27, 0x01, 286},	/* 0x2f */
-	{0x3c, 0x02, 291},	/* 0x30 */
-	{0xef, 0x0a, 292},	/* 0x31 */
-	{0xf6, 0x0a, 310},	/* 0x32 */
-	{0x95, 0x01, 315},	/* 0x33 */
-	{0xf0, 0x09, 324},	/* 0x34 */
-	{0xfe, 0x0a, 331},	/* 0x35 */
-	{0xf3, 0x09, 332},	/* 0x36 */
-	{0xea, 0x08, 340},	/* 0x37 */
-	{0xe8, 0x07, 376},	/* 0x38 */
-	{0xde, 0x06, 389},	/* 0x39 */
-	{0x52, 0x2a, 54},	/* 0x3a */
-	{0x52, 0x6a, 27},	/* 0x3b */
-	{0x62, 0x24, 70},	/* 0x3c */
-	{0x62, 0x64, 70},	/* 0x3d */
-	{0xa8, 0x4c, 30},	/* 0x3e */
-	{0x20, 0x26, 33},	/* 0x3f */
-	{0x31, 0xc2, 39}	/* 0x40 */
+
+SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+{
+	{ 0x1b,0xe1, 25}, /* 0x0 */
+	{ 0x4e,0xe4, 28}, /* 0x1 */
+	{ 0x57,0xe4, 31}, /* 0x2 */
+	{ 0xc3,0xc8, 36}, /* 0x3 */
+	{ 0x42,0x47, 40}, /* 0x4 */
+	{ 0xfe,0xcd, 43}, /* 0x5 */
+	{ 0x5d,0xc4, 44}, /* 0x6 */
+	{ 0x52,0x47, 49}, /* 0x7 */
+	{ 0x53,0x47, 50}, /* 0x8 */
+	{ 0x74,0x67, 52}, /* 0x9 */
+	{ 0x6d,0x66, 56}, /* 0xa */
+	{ 0x5a,0x64, 65}, /* 0xb */
+	{ 0x46,0x44, 67}, /* 0xc */
+	{ 0xb1,0x46, 68}, /* 0xd */
+	{ 0xd3,0x4a, 72}, /* 0xe */
+	{ 0x29,0x61, 75}, /* 0xf */
+	{ 0x6d,0x46, 75}, /* 0x10 */
+	{ 0x41,0x43, 78}, /* 0x11 */
+	{ 0x31,0x42, 79}, /* 0x12 */
+	{ 0xab,0x44, 83}, /* 0x13 */
+	{ 0x46,0x25, 84}, /* 0x14 */
+	{ 0x78,0x29, 86}, /* 0x15 */
+	{ 0x62,0x44, 94}, /* 0x16 */
+	{ 0x2b,0x22,104}, /* 0x17 */
+	{ 0x49,0x24,105}, /* 0x18 */
+	{ 0xf8,0x2f,108}, /* 0x19 */
+	{ 0x3c,0x23,109}, /* 0x1a */
+	{ 0x5e,0x43,113}, /* 0x1b */
+	{ 0xbc,0x44,116}, /* 0x1c */
+	{ 0xe0,0x46,132}, /* 0x1d */
+	{ 0xd4,0x28,135}, /* 0x1e */
+	{ 0xea,0x2a,139}, /* 0x1f */
+	{ 0x41,0x22,157}, /* 0x20 */
+	{ 0x70,0x24,162}, /* 0x21 */
+	{ 0x30,0x21,175}, /* 0x22 */
+	{ 0x4e,0x22,189}, /* 0x23 */
+	{ 0xde,0x26,194}, /* 0x24 */
+	{ 0x70,0x07,202}, /* 0x25 */
+	{ 0x3f,0x03,229}, /* 0x26 */
+	{ 0xb8,0x06,234}, /* 0x27 */
+	{ 0x34,0x02,253}, /* 0x28 */
+	{ 0x58,0x04,255}, /* 0x29 */
+	{ 0x24,0x01,265}, /* 0x2a */
+	{ 0x9b,0x02,267}, /* 0x2b */
+	{ 0x70,0x05,270}, /* 0x2c */
+	{ 0x25,0x01,272}, /* 0x2d */
+	{ 0x9c,0x02,277}, /* 0x2e */
+	{ 0x27,0x01,286}, /* 0x2f */
+	{ 0x3c,0x02,291}, /* 0x30 */
+	{ 0xef,0x0a,292}, /* 0x31 */
+	{ 0xf6,0x0a,310}, /* 0x32 */
+	{ 0x95,0x01,315}, /* 0x33 */
+	{ 0xf0,0x09,324}, /* 0x34 */
+	{ 0xfe,0x0a,331}, /* 0x35 */
+	{ 0xf3,0x09,332}, /* 0x36 */
+	{ 0xea,0x08,340}, /* 0x37 */
+	{ 0xe8,0x07,376}, /* 0x38 */
+	{ 0xde,0x06,389}, /* 0x39 */
+	{ 0x52,0x2a, 54}, /* 0x3a */
+	{ 0x52,0x6a, 27}, /* 0x3b */
+	{ 0x62,0x24, 70}, /* 0x3c */
+	{ 0x62,0x64, 70}, /* 0x3d */
+	{ 0xa8,0x4c, 30}, /* 0x3e */
+	{ 0x20,0x26, 33}, /* 0x3f */
+	{ 0x31,0xc2, 39}  /* 0x40 */
 };
 
-UCHAR SiS310_ScreenOffset[] =
-    { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35 };
+UCHAR SiS310_ScreenOffset[]= { 0x14,0x19,0x20,0x28,0x32,0x40,
+                               0x50,0x64,0x78,0x80,0x2d,0x35};
 
-typedef struct _SiS310_StResInfoStruct {
+typedef struct _SiS310_StResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
 } SiS310_StResInfoStruct;
-SiS310_StResInfoStruct SiS310_StResInfo[] = {
-	{640, 400},
-	{640, 350},
-	{720, 400},
-	{720, 350},
-	{640, 480}
+
+SiS310_StResInfoStruct SiS310_StResInfo[]=
+{
+	{ 640,400},
+	{ 640,350},
+	{ 720,400},
+	{ 720,350},
+	{ 640,480}
 };
 
-typedef struct _SiS310_ModeResInfoStruct {
+typedef struct _SiS310_ModeResInfoStruct
+{
 	USHORT HTotal;
 	USHORT VTotal;
-	UCHAR XChar;
-	UCHAR YChar;
+	UCHAR  XChar;
+	UCHAR  YChar;
 } SiS310_ModeResInfoStruct;
-SiS310_ModeResInfoStruct SiS310_ModeResInfo[] = {
-	{320, 200, 8, 8},
-	{320, 240, 8, 8},
-	{320, 400, 8, 8},
-	{400, 300, 8, 8},
-	{512, 384, 8, 8},
-	{640, 400, 8, 16},
-	{640, 480, 8, 16},
-	{800, 600, 8, 16},
-	{1024, 768, 8, 16},
-	{1280, 1024, 8, 16},
-	{1600, 1200, 8, 16},
-	{1920, 1440, 8, 16},
-	{2048, 1536, 8, 16},
-	{720, 480, 8, 16},
-	{720, 576, 8, 16},
-	{1280, 960, 8, 16},
-	{800, 480, 8, 16},
-	{1024, 576, 8, 16},
-	{1280, 720, 8, 16}
+
+SiS310_ModeResInfoStruct SiS310_ModeResInfo[]=
+{
+	{  320, 200, 8, 8},
+	{  320, 240, 8, 8},
+	{  320, 400, 8, 8},
+	{  400, 300, 8, 8},
+	{  512, 384, 8, 8},
+	{  640, 400, 8,16},
+	{  640, 480, 8,16},
+	{  800, 600, 8,16},
+	{ 1024, 768, 8,16},
+	{ 1280,1024, 8,16},
+	{ 1600,1200, 8,16},
+	{ 1920,1440, 8,16},
+	{ 2048,1536, 8,16},
+	{  720, 480, 8,16},
+	{  720, 576, 8,16},
+	{ 1280, 960, 8,16},
+	{  800, 480, 8,16},
+	{ 1024, 576, 8,16},
+	{ 1280, 720, 8,16}
 };
 
-UCHAR SiS310_OutputSelect = 0x40;
+UCHAR SiS310_OutputSelect =0x40;
+
 UCHAR SiS310_SoftSetting = 30;
-UCHAR SiS310_SR07 = 0x18;
-UCHAR SiS310_SR15[8][4] = {
-	{0x0, 0x4, 0x60, 0x60},
-	{0xf, 0xf, 0xf, 0xf},
-	{0xba, 0xba, 0xba, 0xba},
-	{0xa9, 0xa9, 0xac, 0xac},
-	{0xa0, 0xa0, 0xa0, 0xa8},
-	{0x0, 0x0, 0x2, 0x2},
-	{0x30, 0x30, 0x40, 0x40},
-	{0x0, 0xa5, 0xfb, 0xf6}
-};
-UCHAR SiS310_CR40[5][4] = {
-	{0x77, 0x77, 0x33, 0x33},
-	{0x77, 0x77, 0x33, 0x33},
-	{0x0, 0x0, 0x0, 0x0},
-	{0x5b, 0x5b, 0x3, 0x3},
-	{0x0, 0x0, 0xf0, 0xf8}
-};
-UCHAR SiS310_CR49[] = { 0xaa, 0x88 };
-UCHAR SiS310_SR1F = 0x0;
-UCHAR SiS310_SR21 = 0xa5;
-UCHAR SiS310_SR22 = 0xfb;
-UCHAR SiS310_SR23 = 0xf6;
-UCHAR SiS310_SR24 = 0xd;
-UCHAR SiS310_SR25[] = { 0x33, 0x3 };
-UCHAR SiS310_SR31 = 0x0;
-UCHAR SiS310_SR32 = 0x11;
-UCHAR SiS310_SR33 = 0x0;
+
+UCHAR SiS310_SR07=0x18;
+
+UCHAR SiS310_SR15[8][4]={
+	{0x00,0x04,0x60,0x60},
+	{0x0f,0x0f,0x0f,0x0f},
+	{0xba,0xba,0xba,0xba},
+	{0xa9,0xa9,0xac,0xac},
+	{0xa0,0xa0,0xa0,0xa8},
+	{0x00,0x00,0x02,0x02},
+	{0x30,0x30,0x40,0x40},
+	{0x00,0xa5,0xfb,0xf6}
+};
+
+UCHAR SiS310_CR40[5][4]={
+	{0x77,0x77,0x33,0x33},
+	{0x77,0x77,0x33,0x33},
+	{0x00,0x00,0x00,0x00},
+	{0x5b,0x5b,0x03,0x03},
+	{0x00,0x00,0xf0,0xf8}
+};
+
+UCHAR SiS310_CR49[]={0xaa,0x88};
+UCHAR SiS310_SR1F=0x0;
+UCHAR SiS310_SR21=0xa5;
+UCHAR SiS310_SR22=0xfb;
+UCHAR SiS310_SR23=0xf6;
+UCHAR SiS310_SR24=0xd;
+UCHAR SiS310_SR25[]={0x33,0x3};
+UCHAR SiS310_SR31=0x0;
+UCHAR SiS310_SR32=0x11;
+UCHAR SiS310_SR33=0x0;
 UCHAR SiS310_CRT2Data_1_2 = 0x0;
 UCHAR SiS310_CRT2Data_4_D = 0x0;
 UCHAR SiS310_CRT2Data_4_E = 0x0;
@@ -1129,17 +1115,18 @@
 USHORT SiS310_RGBSenseData = 0xd1;
 USHORT SiS310_VideoSenseData = 0xb9;
 USHORT SiS310_YCSenseData = 0xb3;
-USHORT SiS310_RGBSenseData2 = 0x0190;	/*301b */
+USHORT SiS310_RGBSenseData2 = 0x0190;     /*301b*/
 USHORT SiS310_VideoSenseData2 = 0x0174;
 USHORT SiS310_YCSenseData2 = 0x016b;
-UCHAR SiS310_NTSCPhase[] = { 0x21, 0xed, 0x8a, 0x8 };
-UCHAR SiS310_PALPhase[] = { 0x2a, 0x5, 0xd3, 0x0 };
-UCHAR SiS310_NTSCPhase2[] = { 0x21, 0xF0, 0x7B, 0xD6 };	/*301b */
-UCHAR SiS310_PALPhase2[] = { 0x2a, 0x09, 0x86, 0xe9 };
-UCHAR SiS310_PALMPhase[] = { 0x21, 0xE4, 0x2E, 0x9B };	/*palmn */
-UCHAR SiS310_PALNPhase[] = { 0x21, 0xF4, 0x3E, 0xBA };
+UCHAR SiS310_NTSCPhase[] = {0x21,0xed,0x8a,0x8};
+UCHAR SiS310_PALPhase[] = {0x2a,0x5,0xd3,0x0};
+UCHAR SiS310_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};/*301b*/
+UCHAR SiS310_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
+UCHAR SiS310_PALMPhase[] = {0x21,0xE4,0x2E,0x9B};   /*palmn*/
+UCHAR SiS310_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
 
-typedef struct _SiS310_LCDDataStruct {
+typedef struct _SiS310_LCDDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -1147,99 +1134,109 @@
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS310_LCDDataStruct;
-SiS310_LCDDataStruct SiS310_StLCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] = {
-	{12, 5, 896, 512, 1344, 806},
-	{12, 5, 896, 510, 1344, 806},
-	{32, 15, 1008, 505, 1344, 806},
-	{32, 15, 1008, 514, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS310_LCDDataStruct SiS310_StLCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = {
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 500, 1688, 1066},
-	{211, 75, 1024, 625, 1688, 1066},
-	{211, 120, 1280, 798, 1688, 1066},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_NoScaleData[] = {
-	{1, 1, 800, 449, 800, 449},
-	{1, 1, 800, 449, 800, 449},
-	{1, 1, 900, 449, 900, 449},
-	{1, 1, 900, 449, 900, 449},
-	{1, 1, 800, 525, 800, 525},
-	{1, 1, 1056, 628, 1056, 628},
-	{1, 1, 1344, 806, 1344, 806},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_LCD1280x960Data[] = {
-	{9, 2, 800, 500, 1800, 1000},
-	{9, 2, 800, 500, 1800, 1000},
-	{4, 1, 900, 500, 1800, 1000},
-	{4, 1, 900, 500, 1800, 1000},
-	{9, 2, 800, 500, 1800, 1000},
-	{30, 11, 1056, 625, 1800, 1000},
-	{5, 3, 1350, 800, 1800, 1000},
-	{1, 1, 1576, 1050, 1576, 1050},
-	{1, 1, 1800, 1000, 1800, 1000}
+
+SiS310_LCDDataStruct  SiS310_StLCD1024x768Data[]=
+{
+	{   62,  25, 800, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{  104,  45, 945, 496,1344, 806},
+	{   62,  25, 800, 546,1344, 806},
+	{   31,  18,1008, 624,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[]=
+{
+	{   12,   5, 896, 512,1344, 806},
+	{   12,   5, 896, 510,1344, 806},
+	{   32,  15,1008, 505,1344, 806},
+	{   32,  15,1008, 514,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_St2LCD1024x768Data[]=
+{
+	{   62,  25, 800, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{   32,  15, 930, 546,1344, 806},
+	{  104,  45, 945, 496,1344, 806},
+	{   62,  25, 800, 546,1344, 806},
+	{   31,  18,1008, 624,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[]=
+{
+	{   22,   5, 800, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[]=
+{
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 500,1688,1066},
+	{  211,  75,1024, 625,1688,1066},
+	{  211, 120,1280, 798,1688,1066},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_St2LCD1280x1024Data[]=
+{
+	{   22,   5, 800, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{  176,  45, 900, 510,1650,1088},
+	{   22,   5, 800, 510,1650,1088},
+	{   13,   5,1024, 675,1560,1152},
+	{   16,   9,1266, 804,1688,1072},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_NoScaleData[]=
+{
+	{    1,   1, 800, 449, 800, 449},
+	{    1,   1, 800, 449, 800, 449},
+	{    1,   1, 900, 449, 900, 449},
+	{    1,   1, 900, 449, 900, 449},
+	{    1,   1, 800, 525, 800, 525},
+	{    1,   1,1056, 628,1056, 628},
+	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_LCD1280x960Data[]=
+{
+	{    9,   2, 800, 500,1800,1000},
+	{    9,   2, 800, 500,1800,1000},
+	{    4,   1, 900, 500,1800,1000},
+	{    4,   1, 900, 500,1800,1000},
+	{    9,   2, 800, 500,1800,1000},
+	{   30,  11,1056, 625,1800,1000},
+	{    5,   3,1350, 800,1800,1000},
+	{    1,   1,1576,1050,1576,1050},
+	{    1,   1,1800,1000,1800,1000}
 };
 
-typedef struct _SiS310_TVDataStruct {
+typedef struct _SiS310_TVDataStruct
+{
 	USHORT RVBHCMAX;
 	USHORT RVBHCFACT;
 	USHORT VGAHT;
@@ -1254,1351 +1251,1491 @@
 	UCHAR RY3COE;
 	UCHAR RY4COE;
 } SiS310_TVDataStruct;
-SiS310_TVDataStruct SiS310_StPALData[] = {
-	{1, 1, 864, 525, 1270, 400, 100, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 350, 100, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 400, 0, 0, 720, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 864, 525, 1270, 350, 0, 0, 720, 0xf4, 0x0b, 0x1c, 0x0a},
-	{1, 1, 864, 525, 1270, 480, 50, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 600, 50, 0, 0, 0xf4, 0xff, 0x1c, 0x22}
-};
-
-SiS310_TVDataStruct SiS310_ExtPALData[] = {
-	{27, 10, 848, 448, 1270, 530, 50, 0, 50, 0xf4, 0xff, 0x1c, 0x22},
-	{108, 35, 848, 398, 1270, 530, 50, 0, 50, 0xf4, 0xff, 0x1c, 0x22},
-	{12, 5, 954, 448, 1270, 530, 50, 0, 50, 0xf1, 0x04, 0x1f, 0x18},
-	{9, 4, 960, 463, 1644, 438, 50, 0, 50, 0xf4, 0x0b, 0x1c, 0x0a},
-	{9, 4, 848, 528, 1270, 530, 0, 0, 50, 0xf5, 0xfb, 0x1b, 0x2a},
-	{36, 25, 1060, 648, 1316, 530, 438, 0, 438, 0xeb, 0x05, 0x25, 0x16},
-	{3, 2, 1080, 619, 1270, 540, 438, 0, 438, 0xf3, 0x00, 0x1d, 0x20},
-	{1, 1, 1170, 821, 1270, 520, 686, 0, 686, 0xF3, 0x00, 0x1D, 0x20}	/*301b */
-};
-
-SiS310_TVDataStruct SiS310_StNTSCData[] = {
-	{1, 1, 858, 525, 1270, 400, 50, 0, 760, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 350, 50, 0, 640, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 400, 0, 0, 720, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 350, 0, 0, 720, 0xf4, 0x0b, 0x1c, 0x0a},
-	{1, 1, 858, 525, 1270, 480, 0, 0, 760, 0xf1, 0x04, 0x1f, 0x18}
-};
-
-SiS310_TVDataStruct SiS310_ExtNTSCData[] = {
-	{143, 65, 858, 443, 1270, 440, 171, 0, 171, 0xf1, 0x04, 0x1f, 0x18},
-	{88, 35, 858, 393, 1270, 440, 171, 0, 171, 0xf1, 0x04, 0x1f, 0x18},
-	{143, 70, 924, 443, 1270, 440, 92, 0, 92, 0xf1, 0x04, 0x1f, 0x18},
-	{143, 70, 924, 393, 1270, 440, 92, 0, 92, 0xf4, 0x0b, 0x1c, 0x0a},
-	{143, 76, 836, 523, 1270, 440, 224, 0, 0, 0xf1, 0x05, 0x1f, 0x16},
-	{143, 120, 1056, 643, 1270, 440, 0, 128, 0, 0xf4, 0x10, 0x1c, 0x00},
-	{2, 1, 858, 503, 1270, 480, 0, 128, 0, 0xee, 0x0c, 0x22, 0x08},
-	{65, 64, 1056, 791, 1270, 480, 638, 0, 0, 0xEE, 0x0C, 0x22, 0x08}	/*301b */
+
+SiS310_TVDataStruct  SiS310_StPALData[]=
+{
+ {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
+};
+
+SiS310_TVDataStruct  SiS310_ExtPALData[]=
+{
+ {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+ {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+ {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
+ {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
+ {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
+ {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
+ {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}     /*301b*/
 };
 
-SiS310_TVDataStruct SiS310_St1HiTVData[] = {
+SiS310_TVDataStruct  SiS310_StNTSCData[]=
+{
+ {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
+};
+
+SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
+{
+ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
+ {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},
+ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} /*301b*/     
+};
+
+SiS310_TVDataStruct  SiS310_St1HiTVData[]=
+{
 	{0x00}
 };
 
-SiS310_TVDataStruct SiS310_St2HiTVData[] = {
+SiS310_TVDataStruct  SiS310_St2HiTVData[]=
+{
 	{0x00}
 };
 
-SiS310_TVDataStruct SiS310_ExtHiTVData[] = {
+SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
+{
 	{0x00}
 };
 
 UCHAR SiS310_NTSCTiming[] = {
-	0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
-	0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
-	0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
-	0x0c, 0x50, 0x00, 0x97, 0x00, 0xda, 0x4a, 0x17,
-	0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
-	0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
-	0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x50,
-	0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
+	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
+	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
 };
 
 UCHAR SiS310_PALTiming[] = {
-	0x19, 0x52, 0x35, 0x6e, 0x04, 0x38, 0x3d, 0x70,
-	0x94, 0x49, 0x01, 0x12, 0x06, 0x3e, 0x35, 0x6d,
-	0x06, 0x14, 0x3e, 0x35, 0x6d, 0x00, 0x45, 0x2b,
-	0x70, 0x50, 0x00, 0x9b, 0x00, 0xd9, 0x5d, 0x17,
-	0x7d, 0x05, 0x45, 0x00, 0x00, 0xe8, 0x00, 0x02,
-	0x0d, 0x00, 0x68, 0xb0, 0x0b, 0x92, 0x8f, 0x40,
-	0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x63,
-	0x00, 0x40, 0x3e, 0x00, 0xe1, 0x02, 0x28, 0x00
+	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
+	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
 };
 
-UCHAR SiS310_HiTVExtTiming[] = { 0x00 };
+UCHAR SiS310_HiTVExtTiming[] = {0x00};
 
-UCHAR SiS310_HiTVSt1Timing[] = { 0x00 };
+UCHAR SiS310_HiTVSt1Timing[] = {0x00};
 
-UCHAR SiS310_HiTVSt2Timing[] = { 0x00 };
+UCHAR SiS310_HiTVSt2Timing[] = {0x00};
 
-UCHAR SiS310_HiTVTextTiming[] = { 0x00 };
+UCHAR SiS310_HiTVTextTiming[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Data[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Data[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Simu[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Simu[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Text[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Text[] = {0x00};
 
-typedef struct _SiS310_PanelDelayTblStruct {
-	UCHAR timer[2];
+typedef struct _SiS310_PanelDelayTblStruct
+{
+ 	UCHAR timer[2];
 } SiS310_PanelDelayTblStruct;
-SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[] = {
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}},
-	{{0x00, 0x00}}
+
+SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+{
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}},
+	{{0x00,0x00}}
 };
 
-typedef struct _SiS310_LVDSDataStruct {
+typedef struct _SiS310_LVDSDataStruct
+{
 	USHORT VGAHT;
 	USHORT VGAVT;
 	USHORT LCDHT;
 	USHORT LCDVT;
 } SiS310_LVDSDataStruct;
-SiS310_LVDSDataStruct SiS310_LVDS800x600Data_1[] = {
-	{848, 433, 1060, 629},
-	{848, 389, 1060, 629},
-	{848, 433, 1060, 629},
-	{848, 389, 1060, 629},
-	{848, 518, 1060, 629},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{800, 449, 1000, 644},
-	{800, 525, 1000, 635}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS800x600Data_2[] = {
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{800, 449, 1000, 644},
-	{800, 525, 1000, 635}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_1[] = {
-	{840, 438, 1344, 806},
-	{840, 409, 1344, 806},
-	{840, 438, 1344, 806},
-	{840, 409, 1344, 806},
-	{840, 518, 1344, 806},
-	{1050, 638, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_2[] = {
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_1[] = {
-	{840, 438, 1344, 806},
-	{840, 409, 1344, 806},
-	{840, 438, 1344, 806},
-	{840, 409, 1344, 806},
-	{840, 518, 1344, 806},
-	{1050, 638, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_2[] = {
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
+
+SiS310_LVDSDataStruct  SiS310_LVDS320x480Data_1[]=
+{
+	{848, 433,400,525},
+	{848, 389,400,525},
+	{848, 433,400,525},
+	{848, 389,400,525},
+	{848, 518,400, 525},
+	{1056, 628,400,525},
+	{400, 525,400,525},
+	{800, 449,1000, 644},
+	{800, 525,1000, 635}
+};
+SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]=
+{
+	{848, 433,1060, 629},
+	{848, 389,1060, 629},
+	{848, 433,1060, 629},
+	{848, 389,1060, 629},
+	{848, 518,1060, 629},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{800, 449,1000, 644},
+	{800, 525,1000, 635}
 };
 
-SiS310_LVDSDataStruct SiS310_LVDS640x480Data_1[] = {
+SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=
+{
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{800, 449,1000, 644},
+	{800, 525,1000, 635}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=
+{
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=
+{
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=
+{
 	{800, 449, 800, 449},
 	{800, 449, 800, 449},
 	{800, 449, 800, 449},
 	{800, 449, 800, 449},
 	{800, 525, 800, 525},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628}
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628}
 };
 
-SiS310_LVDSDataStruct SiS310_CHTVUNTSCData[] = {
+SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=
+{
 	{840, 600, 840, 600},
 	{840, 600, 840, 600},
 	{840, 600, 840, 600},
 	{840, 600, 840, 600},
 	{784, 600, 784, 600},
-	{1064, 750, 1064, 750}
+	{1064, 750,1064, 750}
 };
 
-SiS310_LVDSDataStruct SiS310_CHTVONTSCData[] = {
+SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=
+{
 	{840, 525, 840, 525},
 	{840, 525, 840, 525},
 	{840, 525, 840, 525},
 	{840, 525, 840, 525},
 	{784, 525, 784, 525},
-	{1040, 700, 1040, 700}
+	{1040, 700,1040, 700}
 };
 
-SiS310_LVDSDataStruct SiS310_CHTVUPALData[] = {
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
+SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
 	{840, 750, 840, 750},
 	{936, 836, 936, 836}
 };
 
-SiS310_LVDSDataStruct SiS310_CHTVOPALData[] = {
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
+SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]=
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
 	{840, 625, 840, 625},
 	{960, 750, 960, 750}
 };
 
-typedef struct _SiS310_LVDSDesStruct {
+typedef struct _SiS310_LVDSDesStruct
+{
 	USHORT LCDHDES;
 	USHORT LCDVDES;
 } SiS310_LVDSDesStruct;
-SiS310_LVDSDesStruct SiS310_PanelType00_1[] = {
+
+SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=
+{
 	{0, 626},
 	{0, 624},
 	{0, 626},
 	{0, 624},
 	{0, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType01_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType02_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=
+{
 	{0, 626},
 	{0, 624},
 	{0, 626},
 	{0, 624},
 	{0, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 8, 523},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType03_1[] = {
-	{8, 436},
-	{8, 440},
-	{8, 436},
-	{8, 440},
-	{8, 512},
+
+SiS310_LVDSDesStruct  SiS310_PanelType03_1[]=
+{
+	{ 8, 436},
+	{ 8, 440},
+	{ 8, 436},
+	{ 8, 440},
+	{ 8, 512},
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType04_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType05_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType05_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType06_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType07_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType07_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType08_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=
+{
 	{1059, 626},
 	{1059, 624},
 	{1059, 626},
 	{1059, 624},
 	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType09_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0a_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=
+{
 	{1059, 626},
 	{1059, 624},
 	{1059, 626},
 	{1059, 624},
 	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0b_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0c_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0d_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0e_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0f_1[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=
+{
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType00_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=
+{
 	{976, 527},
 	{976, 502},
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType01_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType01_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType02_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType02_2[]=
+{
 	{976, 527},
 	{976, 502},
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType03_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
+	{ 0, 805},
 	{1152, 622},
 	{1152, 597}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType04_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType05_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType06_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType07_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType08_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=
+{
 	{976, 527},
 	{976, 502},
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType09_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType09_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+ 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0a_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=
+{
 	{976, 527},
 	{976, 502},
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
+	{ 0, 627},
+	{ 0, 627},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0b_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0c_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0d_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0e_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = {
+SiS310_LVDSDesStruct  SiS310_PanelType0f_2[]=
+{
 	{1152, 622},
 	{1152, 597},
 	{1152, 622},
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 /*301b*/
-SiS310_LVDSDesStruct SiS310_PanelType1076_1[] = {
-	{0x00, 0x00}
+SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=
+{
+	{0x00,0x00}
 };
-SiS310_LVDSDesStruct SiS310_PanelType1210_1[] = {
-	{0x00, 0x00}
+SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=
+{
+	{0x00,0x00}
 };
-SiS310_LVDSDesStruct SiS310_PanelType1296_1[] = {
-	{0x00, 0x00}
+SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=
+{
+	{0x00,0x00}
 };
-SiS310_LVDSDesStruct SiS310_PanelType1076_2[] = {
-	{0x00, 0x00}
+SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=
+{
+	{0x00,0x00}
 };
-SiS310_LVDSDesStruct SiS310_PanelType1210_2[] = {
-	{0x00, 0x00}
+SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=
+{
+	{0x00,0x00}
 };
-SiS310_LVDSDesStruct SiS310_PanelType1296_2[] = {
-	{0x00, 0x00}
+SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=
+{
+	{0x00,0x00}
 };
 /*end 301b*/
 
-SiS310_LVDSDesStruct SiS310_CHTVUNTSCDesData[] = {
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVONTSCDesData[] = {
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVUPALDesData[] = {
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVOPALDesData[] = {
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{0, 0},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
+{
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
+{
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
 /*add for LCDA*/
-typedef struct _SiS310_LCDACRT1DataStruct {
-	UCHAR CR[17];
-} SiS310_LCDACRT1DataStruct;
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1[] = {
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 0x1f,
-	  0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0x83, 0x1f,
-	  0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 0x1f,
-	  0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0x83, 0x1f,
-	  0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0x04, 0x3e,
-	  0xe0, 0x85, 0xdf, 0xfb, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1[] = {
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
-	  0x60, 0x87, 0x5d, 0x5d, 0x83, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
-	  0x60, 0x87, 0x5d, 0x5d, 0x83, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x04, 0x3e,
-	  0xE2, 0x89, 0xDf, 0xDf, 0x05, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x87, 0x63, 0x63, 0x8B, 0x69, 0x1A, 0x7c, 0xf0,
-	  0x5A, 0x8F, 0x57, 0x57, 0x7D, 0x20, 0x00, 0x26,
-	  0x01}},
-	{{0xA3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xFf, 0xFf, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1[] = {
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x04, 0x3e,
-	  0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x7e, 0x63, 0x82, 0x68, 0x15, 0x7c, 0xf0,
-	  0x5a, 0x8f, 0x57, 0x7d, 0x20, 0x00, 0x26,
-	  0x01}},
-	{{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1_H[] = {
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0xaf, 0x1f,
-	  0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0x83, 0x1f,
-	  0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0xaf, 0x1f,
-	  0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0x83, 0x1f,
-	  0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0x04, 0x3e,
-	  0xe0, 0x85, 0xdf, 0xfb, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x3d, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x05,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1_H[] = {
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
-	  0x60, 0x87, 0x5D, 0x5D, 0x83, 0x01, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
-	  0x60, 0x87, 0x5D, 0x5D, 0x83, 0x01, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x04, 0x3e,
-	  0xE2, 0x89, 0xDf, 0xDf, 0x05, 0x00, 0x00, 0x44,
-	  0x00}},
-	{{0x41, 0x31, 0x31, 0x85, 0x35, 0x1d, 0x7c, 0xf0,
-	  0x5A, 0x8F, 0x57, 0x57, 0x7D, 0x20, 0x00, 0x55,
-	  0x01}},
-	{{0x4f, 0x3F, 0x3F, 0x93, 0x45, 0x0D, 0x24, 0xf5,
-	  0x02, 0x88, 0xFf, 0xFf, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1_H[] = {
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x04, 0x3e,
-	  0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x04,
-	  0x00}},
-	{{0x3c, 0x31, 0x80, 0x35, 0x1c, 0x7c, 0xf0,
-	  0x5a, 0x8f, 0x57, 0x7d, 0x20, 0x00, 0x55,
-	  0x01}},
-	{{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2[] = {
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0xba,
-	  0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2[] = {
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x63, 0x87, 0x78, 0x89, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2[] = {
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x63, 0x87, 0x78, 0x89, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2_H[] = {
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x3a, 0x1a, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0xba,
-	  0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x05,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2_H[] = {
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x31, 0x93, 0x3e, 0x06, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x01,
-	  0x01}},
-	{{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
-};
-
-SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2_H[] = {
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x31, 0x93, 0x3e, 0x86, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x01,
-	  0x01}},
-	{{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
+typedef struct _SiS310_LCDACRT1DataStruct
+{
+ 	UCHAR CR[17];
+}SiS310_LCDACRT1DataStruct;
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1[]=
+{
+{{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
+{
+{{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
+   0x00}},
+ {{0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
+   0x01}},
+ {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
+{
+{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00}},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+   0x00}},
+ {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00}},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+   0x00}},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
+   0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+   0x00}},
+ {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+   0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1_H[]=
+{
+{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+   0x00}},
+ {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+   0x00}},
+ {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+   0x00}},
+ {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+   0x00}},
+ {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
+   0x00}},
+ {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+   0x01}}
 };
 
-typedef struct _SiS310_LVDSCRT1DataStruct {
-	UCHAR CR[15];
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
+{
+{{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x44,
+   0x00}},
+ {{0x41,0x31,0x31,0x85,0x35,0x1d,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
+   0x01}},
+ {{0x4f,0x3F,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
+{
+{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00}},
+{{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+   0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
+   0x00}},
+ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+   0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2[]=
+{ 
+{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00}},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00}},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00}},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00}},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+   0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
+{ 
+{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
+{
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2_H[]=
+{ 
+{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+   0x00}},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+   0x00}},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+   0x00}},
+ {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+   0x00}},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
+   0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+   0x00}},
+ {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+   0x01}}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
+{ 
+{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+   0x01 }},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01 }}
+};
+
+SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
+{ 
+{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+   0x01 }},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01 }}
+};
+
+typedef struct _SiS310_LVDSCRT1DataStruct
+{
+ 	UCHAR CR[15];
 } SiS310_LVDSCRT1DataStruct;
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] = {
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 0x1f,
-	  0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0x83, 0x1f,
-	  0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 0x1f,
-	  0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0x83, 0x1f,
-	  0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x65, 0x4f, 0x89, 0x56, 0x83, 0x04, 0x3e,
-	  0xe0, 0x85, 0xdf, 0xfb, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] = {
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x4f, 0x97, 0x55, 0x86, 0x04, 0x3e,
-	  0xE2, 0x89, 0xDf, 0x05, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x87, 0x63, 0x8B, 0x69, 0x1A, 0x7c, 0xf0,
-	  0x5A, 0x8F, 0x57, 0x7D, 0x20, 0x00, 0x26,
-	  0x01}},
-	{{0xA3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xFf, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] = {
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x01,
-	  0x00}},
-	{{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x04, 0x3e,
-	  0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x7e, 0x63, 0x82, 0x68, 0x15, 0x7c, 0xf0,
-	  0x5a, 0x8f, 0x57, 0x7d, 0x20, 0x00, 0x26,
-	  0x01}},
-	{{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] = {
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0xaf, 0x1f,
-	  0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0x83, 0x1f,
-	  0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0xaf, 0x1f,
-	  0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0x83, 0x1f,
-	  0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x30, 0x27, 0x94, 0x2c, 0x92, 0x04, 0x3e,
-	  0xe0, 0x85, 0xdf, 0xfb, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x3d, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x05,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] = {
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
-	  0x60, 0x87, 0x5D, 0x83, 0x01, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
-	  0x60, 0x87, 0x5D, 0x83, 0x01, 0x00, 0x44,
-	  0x00}},
-	{{0x37, 0x27, 0x9B, 0x2b, 0x94, 0x04, 0x3e,
-	  0xE2, 0x89, 0xDf, 0x05, 0x00, 0x00, 0x44,
-	  0x00}},
-	{{0x41, 0x31, 0x85, 0x35, 0x1d, 0x7c, 0xf0,
-	  0x5A, 0x8F, 0x57, 0x7D, 0x20, 0x00, 0x55,
-	  0x01}},
-	{{0x4f, 0x3F, 0x93, 0x45, 0x0D, 0x24, 0xf5,
-	  0x02, 0x88, 0xFf, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] = {
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-	  0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
-	  0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
-	  0x00}},
-	{{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x04, 0x3e,
-	  0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x04,
-	  0x00}},
-	{{0x3c, 0x31, 0x80, 0x35, 0x1c, 0x7c, 0xf0,
-	  0x5a, 0x8f, 0x57, 0x7d, 0x20, 0x00, 0x55,
-	  0x01}},
-	{{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[] = {
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0xba,
-	  0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	  0x00}},
-	{{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] = {
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x63, 0x87, 0x78, 0x89, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] = {
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x06,
-	  0x00}},
-	{{0xa3, 0x63, 0x87, 0x78, 0x89, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x02,
-	  0x01}},
-	{{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] = {
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-	  0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x3a, 0x1a, 0x72, 0x3e,
-	  0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0xba,
-	  0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x3d, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	  0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x05,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] = {
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x31, 0x93, 0x3e, 0x06, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x01,
-	  0x01}},
-	{{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] = {
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-	  0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
-	  0x00}},
-	{{0x4f, 0x31, 0x93, 0x3e, 0x86, 0x24, 0xf1,
-	  0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x01,
-	  0x01}},
-	{{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	  0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] = {
-	{{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-	  0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-	  0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-	  0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-	  0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x5d, 0x4f, 0x81, 0x53, 0x9c, 0x56, 0xba,
-	  0x18, 0x84, 0xdf, 0x57, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x80, 0x63, 0x84, 0x6c, 0x17, 0xec, 0xf0,
-	  0x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x06,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] = {
-	{{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-	  0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-	  0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-	  0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-	  0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x5d, 0x4f, 0x81, 0x56, 0x9c, 0x0b, 0x3e,
-	  0xe8, 0x84, 0xdf, 0x0c, 0x00, 0x00, 0x01,
-	  0x00}},
-	{{0x7d, 0x63, 0x81, 0x6a, 0x16, 0xba, 0xf0,
-	  0x7f, 0x86, 0x57, 0xbb, 0x00, 0x00, 0x06,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] = {
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x55, 0x80, 0xec, 0xba,
-	  0x50, 0x84, 0xdf, 0xed, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x70, 0x63, 0x94, 0x68, 0x8d, 0x42, 0xf1,
-	  0xc8, 0x8c, 0x57, 0xe9, 0x20, 0x00, 0x05,
-	  0x01}}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] = {
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-	  0x00}},
-	{{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x64, 0x4f, 0x88, 0x55, 0x80, 0x6f, 0xba,
-	  0x20, 0x83, 0xdf, 0x70, 0x00, 0x00, 0x05,
-	  0x00}},
-	{{0x73, 0x63, 0x97, 0x69, 0x8e, 0xec, 0xf0,
-	  0x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x05,
-	  0x01}}
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1320x480_1[]=
+{
+{{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }},
+{{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00 }}
+};
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[]=
+{
+{{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[]=
+{
+{{0x73,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x97,0x55,0x86,0x04,0x3e,
+   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
+   0x00}},
+ {{0x87,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x7D,0x20,0x00,0x26,
+   0x01}},
+ {{0xA3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xFf,0x25,0x10,0x00,0x02,
+   0x01}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[]=
+{
+{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
+   0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+   0x00 }},
+ {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+   0x01 }},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[]=
+{
+{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+   0x00 }},
+ {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+   0x00 }},
+ {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+   0x00 }},
+ {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+   0x00 }},
+ {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
+   0x00 }},
+ {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[]=
+{
+{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+   0x00 }},
+ {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
+   0x00}},
+ {{0x37,0x27,0x9B,0x2b,0x94,0x04,0x3e,
+   0xE2,0x89,0xDf,0x05,0x00,0x00,0x44,
+   0x00}},
+ {{0x41,0x31,0x85,0x35,0x1d,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
+   0x01}},
+ {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+   0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[]=
+{
+{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00 }},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00 }},
+ {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00 }},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00 }},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+   0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
+   0x00 }},
+ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+   0x01 }},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
+{ 
+{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+   0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
+   0x00 }},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[]=
+{ 
+{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+   0x01 }},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[]=
+{ 
+{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+   0x01 }},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[]=
+{ 
+{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+   0x00 }},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+   0x00 }},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+   0x00 }},
+ {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+   0x00 }},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
+   0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+   0x00 }},
+ {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[]=
+{ 
+{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+   0x01 }},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[]=
+{ 
+{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+   0x01 }},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01}}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[]=
+{ 
+{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
+   0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
+   0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[]=
+{ 
+{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
+   0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
+   0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[]=
+{ 
+{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
+   0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
+   0x00 }},
+ {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
+   0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
+   0x01 }}
+};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[]=
+{ 
+{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
+   0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
+   0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+   0x01 }}
 };
 
-typedef struct _SiS310_CHTVRegDataStruct {
-	UCHAR Reg[5];
+typedef struct _SiS310_CHTVRegDataStruct
+{
+ 	UCHAR Reg[5];
 } SiS310_CHTVRegDataStruct;
+
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] = {
 	{{0x00}}
-};
+ };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] = {
 	{{0x00}}
-};
+ };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] = {
 	{{0x00}}
-};
+ };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] = {
 	{{0x00}}
-};
+ };
+
+UCHAR SiS310_CHTVVCLKUNTSC[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKUNTSC[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKONTSC[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKONTSC[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKUPAL[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKUPAL[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKOPAL[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKOPAL[] = { 0x00 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/325vtbl.h linux/drivers/video/sis/325vtbl.h
--- linux.orig/drivers/video/sis/325vtbl.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/325vtbl.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,1125 +1,1085 @@
-typedef struct _SiS310_StStruct {
-	UCHAR St_ModeID;
-	USHORT St_ModeFlag;
-	UCHAR St_StTableIndex;
-	UCHAR St_CRT2CRTC;
-	UCHAR St_ResInfo;
-	UCHAR VB_StTVFlickerIndex;
-	UCHAR VB_StTVEdgeIndex;
-	UCHAR VB_StTVYFilterIndex;
+typedef struct _SiS310_StStruct
+{
+ UCHAR St_ModeID;
+ USHORT St_ModeFlag;
+ UCHAR St_StTableIndex;
+ UCHAR St_CRT2CRTC;
+ UCHAR St_ResInfo;
+ UCHAR VB_StTVFlickerIndex;
+ UCHAR VB_StTVEdgeIndex;
+ UCHAR VB_StTVYFilterIndex;
 } SiS310_StStruct;
-SiS310_StStruct SiS310_SModeIDTable[] =
-{ 
-	{0x01, 0x9208, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
-	{0x01, 0x1210, 0x14, 0x01, 0x01, 0x00, 0x01, 0x00},
-	{0x01, 0x1010, 0x17, 0x02, 0x02, 0x00, 0x01, 0x01},
-	{0x03, 0x8208, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02},
-	{0x03, 0x0210, 0x16, 0x01, 0x01, 0x00, 0x01, 0x02},
-	{0x03, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x01, 0x03},
-	{0x05, 0x9209, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x06, 0x8209, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05},
-	{0x07, 0x0000, 0x07, 0x03, 0x03, 0x00, 0x01, 0x03},
-	{0x07, 0x0000, 0x19, 0x02, 0x02, 0x00, 0x01, 0x03},
-	{0x0d, 0x920a, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x0e, 0x820a, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x05},
-	{0x0f, 0x0202, 0x11, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0x10, 0x0212, 0x12, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0x11, 0x0212, 0x1a, 0x04, 0x04, 0x00, 0x00, 0x05},
-	{0x12, 0x0212, 0x1b, 0x04, 0x04, 0x00, 0x00, 0x05},
-	{0x13, 0x021b, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04},
-	{0x12, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x00, 0x05},
-	{0x12, 0x0210, 0x18, 0x01, 0x01, 0x00, 0x00, 0x05},
-	{0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-};
-
-typedef struct _SiS310_StandTableStruct {
-	UCHAR CRT_COLS;
-	UCHAR ROWS;
-	UCHAR CHAR_HEIGHT;
-	USHORT CRT_LEN;
-	UCHAR SR[4];
-	UCHAR MISC;
-	UCHAR CRTC[0x19];
-	UCHAR ATTR[0x14];
-	UCHAR GRC[9];
+SiS310_StStruct SiS310_SModeIDTable[]=
+{ {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00},
+ {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00},
+ {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01},
+ {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02},
+ {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02},
+ {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03},
+ {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04},
+ {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05},
+ {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03},
+ {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03},
+ {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04},
+ {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05},
+ {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05},
+ {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05},
+ {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05},
+ {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05},
+ {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04},
+ {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05},
+ {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05},
+ {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+typedef struct _SiS310_StandTableStruct
+{
+ UCHAR CRT_COLS;
+ UCHAR ROWS;
+ UCHAR CHAR_HEIGHT;
+ USHORT CRT_LEN;
+ UCHAR SR[4];
+ UCHAR MISC;
+ UCHAR CRTC[0x19];
+ UCHAR ATTR[0x14];
+ UCHAR GRC[9];
 } SiS310_StandTableStruct;
-
-SiS310_StandTableStruct SiS310_StandTable[] = {
+SiS310_StandTableStruct SiS310_StandTable[]=
+{
 /* MD_0_200 */
-	{
-	 0x28, 0x18, 0x08, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_1_200 */
-	{
-	 0x28, 0x18, 0x08, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_2_200 */
-	{
-	 0x50, 0x18, 0x08, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_3_200 */
-	{
-	 0x50, 0x18, 0x08, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_4 */
-	{
-	 0x28, 0x18, 0x08, 0x4000,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
-	  0xff},
-	 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x03, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff}
+ },
 /* MD_5 */
-	{
-	 0x28, 0x18, 0x08, 0x4000,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
-	  0xff},
-	 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x03, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff}
+ },
 /* MD_6 */
-	{
-	 0x50, 0x18, 0x08, 0x4000,
-	 {0x01, 0x01, 0x00, 0x06},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
-	  0xff},
-	 {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-	  0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-	  0x01, 0x00, 0x01, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x08,0x4000,
+  {0x01,0x01,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+   0xff},
+  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x01,0x00,0x01,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+   0xff}
+ },
 /* MD_7 */
-	{
-	 0x50, 0x18, 0x0e, 0x1000,
-	 {0x00, 0x03, 0x00, 0x03},
-	 0xa6,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x0d, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	  0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	  0x0e, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x00,0x03,0x00,0x03},
+  0xa6,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff}
+ },
 /* MDA_DAC */
-	{
-	 0x00, 0x00, 0x00, 0x0000,
-	 {0x00, 0x00, 0x00, 0x15},
-	 0x15,
-	 {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f,
-	  0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x00,
-	  0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	  0x15, 0x15, 0x15, 0x15},
-	 {0x15, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x3f}
-	 },
+ {
+  0x00,0x00,0x00,0x0000,
+  {0x00,0x00,0x00,0x15},
+  0x15,
+  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15},
+  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f}
+ },
 /* CGA_DAC */
-	{
-	 0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x09, 0x15, 0x00},
-	 0x10,
-	 {0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a,
-	  0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x2a, 0x3a,
-	  0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x10,
-	  0x04},
-	 {0x14, 0x01, 0x11, 0x09, 0x15, 0x00, 0x10, 0x04,
-	  0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a, 0x2e,
-	  0x3e, 0x2b, 0x3b, 0x2f},
-	 {0x3f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f,
-	  0x3f}
-	 },
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x00},
+  0x10,
+  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+   0x04},
+  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+   0x3e,0x2b,0x3b,0x2f},
+  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f}
+ },
 /* EGA_DAC */
-	{
-	 0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x05, 0x15, 0x20},
-	 0x30,
-	 {0x24, 0x34, 0x21, 0x31, 0x25, 0x35, 0x08, 0x18,
-	  0x0c, 0x1c, 0x09, 0x19, 0x0d, 0x1d, 0x28, 0x38,
-	  0x2c, 0x3c, 0x29, 0x39, 0x2d, 0x3d, 0x02, 0x12,
-	  0x06},
-	 {0x16, 0x03, 0x13, 0x07, 0x17, 0x22, 0x32, 0x26,
-	  0x36, 0x23, 0x33, 0x27, 0x37, 0x0a, 0x1a, 0x0e,
-	  0x1e, 0x0b, 0x1b, 0x0f},
-	 {0x1f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f,
-	  0x3f}
-	 },
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x05,0x15,0x20},
+  0x30,
+  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+   0x06},
+  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+   0x1e,0x0b,0x1b,0x0f},
+  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f}
+ },
 /* VGA_DAC */
-	{
-	 0x00, 0x10, 0x04, 0x0114,
-	 {0x11, 0x09, 0x15, 0x2a},
-	 0x3a,
-	 {0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x05,
-	  0x08, 0x0b, 0x0e, 0x11, 0x14, 0x18, 0x1c, 0x20,
-	  0x24, 0x28, 0x2d, 0x32, 0x38, 0x3f, 0x00, 0x10,
-	  0x1f},
-	 {0x2f, 0x3f, 0x1f, 0x27, 0x2f, 0x37, 0x3f, 0x2d,
-	  0x31, 0x36, 0x3a, 0x3f, 0x00, 0x07, 0x0e, 0x15,
-	  0x1c, 0x0e, 0x11, 0x15},
-	 {0x18, 0x1c, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x00,
-	  0x04}
-	 },
-	{
-	 0x08, 0x0c, 0x10, 0x0a08,
-	 {0x0c, 0x0e, 0x10, 0x0b},
-	 0x0c,
-	 {0x0d, 0x0f, 0x10, 0x10, 0x01, 0x08, 0x00, 0x00,
-	  0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x00,
-	  0x04, 0x04, 0x01, 0x00, 0x05, 0x02, 0x05, 0x00,
-	  0x06},
-	 {0x01, 0x06, 0x05, 0x06, 0x00, 0x08, 0x01, 0x08,
-	  0x00, 0x07, 0x02, 0x07, 0x06, 0x07, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00}
-	 },
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x2a},
+  0x3a,
+  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+   0x1f},
+  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+   0x1c,0x0e,0x11,0x15},
+  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+   0x04}
+ },
+ {
+  0x08,0x0c,0x10,0x0a08,
+  {0x0c,0x0e,0x10,0x0b},
+  0x0c,
+  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+   0x06},
+  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}
+ },
 /* MD_D */
-	{
-	 0x28, 0x18, 0x08, 0x2000,
-	 {0x09, 0x0f, 0x00, 0x06},
-	 0x63,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x08,0x2000,
+  {0x09,0x0f,0x00,0x06},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
 /* MD_E */
-	{
-	 0x50, 0x18, 0x08, 0x4000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x08,0x4000,
+  {0x01,0x0f,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
 /* ExtVGATable */
-	{
-	 0x00, 0x00, 0x00, 0x0000,
-	 {0x01, 0x0f, 0x00, 0x0e},
-	 0x23,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-	  0x01, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x00,0x00,0x00,0x0000,
+  {0x01,0x0f,0x00,0x0e},
+  0x23,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x01,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff}
+ },
 /* ROM_SAVEPTR */
-	{
-	 0x9f, 0x3b, 0x00, 0x00c0,
-	 {0x00, 0x00, 0x00, 0x00},
-	 0x00,
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x3f,
-	  0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x1a, 0x00, 0xac, 0x3e, 0x00, 0xc0,
-	  0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00}
-	 },
+ {
+  0x9f,0x3b,0x00,0x00c0,
+  {0x00,0x00,0x00,0x00},
+  0x00,
+  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}
+ },
 /* MD_F */
-	{
-	 0x50, 0x18, 0x0e, 0x8000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xa2,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
-	  0xff},
-	 {0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
-	  0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
-	  0x0b, 0x00, 0x05, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa2,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+   0xff},
+  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+   0x0b,0x00,0x05,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+   0xff}
+ },
 /* MD_10 */
-	{
-	 0x50, 0x18, 0x0e, 0x8000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
 /* MD_0_350 */
-	{
-	 0x28, 0x18, 0x0e, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_1_350 */
-	{
-	 0x28, 0x18, 0x0e, 0x0800,
-	 {0x09, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_2_350 */
-	{
-	 0x50, 0x18, 0x0e, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_3_350 */
-	{
-	 0x50, 0x18, 0x0e, 0x1000,
-	 {0x01, 0x03, 0x00, 0x02},
-	 0xa3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
-	  0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x08, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_0_1_400 */
-	{
-	 0x28, 0x18, 0x10, 0x0800,
-	 {0x08, 0x03, 0x00, 0x02},
-	 0x67,
-	 {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x0c, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x28,0x18,0x10,0x0800,
+  {0x08,0x03,0x00,0x02},
+  0x67,
+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_2_3_400 */
-	{
-	 0x50, 0x18, 0x10, 0x1000,
-	 {0x00, 0x03, 0x00, 0x02},
-	 0x67,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x0c, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x67,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
 /* MD_7_400 */
-	{
-	 0x50, 0x18, 0x10, 0x1000,
-	 {0x00, 0x03, 0x00, 0x02},
-	 0x66,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	  0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	  0x0e, 0x00, 0x0f, 0x08},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
-	  0xff}
-	 },
+ {
+  0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x66,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff}
+ },
 /* MD_11 */
-	{
-	 0x50, 0x1d, 0x10, 0xa000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xe3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3,
-	  0xff},
-	 {0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01,
-	  0xff}
-	 },
+ {
+  0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+   0xff},
+  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+   0xff}
+ },
 /* ExtEGATable */
-	{
-	 0x50, 0x1d, 0x10, 0xa000,
-	 {0x01, 0x0f, 0x00, 0x06},
-	 0xe3,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
-	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-	  0x01, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
-	  0xff}
-	 },
+ {
+  0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
 /* MD_13 */
-	{
-	 0x28, 0x18, 0x08, 0x2000,
-	 {0x01, 0x0f, 0x00, 0x0e},
-	 0x63,
-	 {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	  0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
-	  0xff},
-	 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-	  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-	  0x41, 0x00, 0x0f, 0x00},
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
-	  0xff}
-	 }
-};
-
-typedef struct _SiS310_ExtStruct {
-	UCHAR Ext_ModeID;
-	USHORT Ext_ModeFlag;
-	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;
-	USHORT Ext_VESAID;
-	UCHAR Ext_VESAMEMSize;
-	UCHAR Ext_RESINFO;
-	UCHAR VB_ExtTVFlickerIndex;
-	UCHAR VB_ExtTVEdgeIndex;
-	UCHAR VB_ExtTVYFilterIndex;
-	UCHAR REFindex;
+ {
+  0x28,0x18,0x08,0x2000,
+  {0x01,0x0f,0x00,0x0e},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x41,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff}
+ }
+};
+
+typedef struct _SiS310_ExtStruct
+{
+ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_ModeInfo;
+ USHORT Ext_Point;
+ USHORT Ext_VESAID;
+ UCHAR Ext_VESAMEMSize;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+ UCHAR VB_ExtTVYFilterIndex;
+ UCHAR REFindex;
 } SiS310_ExtStruct;
-SiS310_ExtStruct SiS310_EModeIDTable[] = {
-	
-	    {0x6a, 0x2212, 0x0407, 0x3a81, 0x0102, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x2e, 0x0a1b, 0x0306, 0x3a57, 0x0101, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x2f, 0x0a1b, 0x0305, 0x3a50, 0x0100, 0x08, 0x05, 0x00, 0x00, 0x05,
-	 0x10},
-	{0x30, 0x2a1b, 0x0407, 0x3a81, 0x0103, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x31, 0x0a1b, 0x030d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x32, 0x0a1b, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x33, 0x0a1d, 0x0a0d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x34, 0x2a1d, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x35, 0x0a1f, 0x0a0d, 0x3b85, 0x0000, 0x08, 0x0d, 0x00, 0x00, 0x06,
-	 0x11},
-	{0x36, 0x2a1f, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06,
-	 0x12},
-	{0x37, 0x0212, 0x0508, 0x3aab, 0x0104, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x38, 0x0a1b, 0x0508, 0x3aab, 0x0105, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x3a, 0x0e3b, 0x0609, 0x3adc, 0x0107, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x3c, 0x063b, 0x070a, 0x3af2, 0x0130, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x3d, 0x067d, 0x070a, 0x3af2, 0x0131, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x40, 0x9a1c, 0x0000, 0x3a34, 0x010d, 0x08, 0x00, 0x00, 0x00, 0x04,
-	 0x25},
-	{0x41, 0x9a1d, 0x0000, 0x3a34, 0x010e, 0x08, 0x00, 0x00, 0x00, 0x04,
-	 0x25},
-	{0x43, 0x0a1c, 0x0306, 0x3a57, 0x0110, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x44, 0x0a1d, 0x0306, 0x3a57, 0x0111, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x46, 0x2a1c, 0x0407, 0x3a81, 0x0113, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x47, 0x2a1d, 0x0407, 0x3a81, 0x0114, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x49, 0x0a3c, 0x0508, 0x3aab, 0x0116, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x4a, 0x0a3d, 0x0508, 0x3aab, 0x0117, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x4c, 0x0e7c, 0x0609, 0x3adc, 0x0119, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x4d, 0x0e7d, 0x0609, 0x3adc, 0x011a, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x50, 0x9a1b, 0x0001, 0x3a3b, 0x0132, 0x08, 0x01, 0x00, 0x00, 0x04,
-	 0x26},
-	{0x51, 0xba1b, 0x0103, 0x3a42, 0x0133, 0x08, 0x03, 0x00, 0x00, 0x07,
-	 0x27},
-	{0x52, 0x9a1b, 0x0204, 0x3a49, 0x0134, 0x08, 0x04, 0x00, 0x00, 0x00,
-	 0x28},
-	{0x56, 0x9a1d, 0x0001, 0x3a3b, 0x0135, 0x08, 0x01, 0x00, 0x00, 0x04,
-	 0x26},
-	{0x57, 0xba1d, 0x0103, 0x3a42, 0x0136, 0x08, 0x03, 0x00, 0x00, 0x07,
-	 0x27},
-	{0x58, 0x9a1d, 0x0204, 0x3a49, 0x0137, 0x08, 0x04, 0x00, 0x00, 0x00,
-	 0x28},
-	{0x59, 0x9a1b, 0x0000, 0x3a34, 0x0138, 0x08, 0x00, 0x00, 0x00, 0x04,
-	 0x25},
-	{0x5d, 0x0a1d, 0x0305, 0x3a50, 0x0139, 0x08, 0x05, 0x00, 0x00, 0x07,
-	 0x10},
-	{0x62, 0x0a3f, 0x0306, 0x3a57, 0x013a, 0x08, 0x06, 0x00, 0x00, 0x05,
-	 0x08},
-	{0x63, 0x2a3f, 0x0407, 0x3a81, 0x013b, 0x08, 0x07, 0x00, 0x00, 0x07,
-	 0x00},
-	{0x64, 0x0a7f, 0x0508, 0x3aab, 0x013c, 0x08, 0x08, 0x00, 0x00, 0x00,
-	 0x13},
-	{0x65, 0x0eff, 0x0609, 0x3adc, 0x013d, 0x08, 0x09, 0x00, 0x00, 0x00,
-	 0x1a},
-	{0x66, 0x06ff, 0x070a, 0x3af2, 0x013e, 0x08, 0x0a, 0x00, 0x00, 0x00,
-	 0x1e},
-	{0x68, 0x067b, 0x080b, 0x3b17, 0x013f, 0x08, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x69, 0x06fd, 0x080b, 0x3b17, 0x0140, 0x08, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x6b, 0x07ff, 0x080b, 0x3b17, 0x0141, 0x10, 0x0b, 0x00, 0x00, 0x00,
-	 0x29},
-	{0x6c, 0x067b, 0x090c, 0x3b37, 0x0000, 0x08, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x6d, 0x06fd, 0x090c, 0x3b37, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x6e, 0x07ff, 0x090c, 0x3b37, 0x0000, 0x10, 0x0c, 0x00, 0x00, 0x00,
-	 0x2f},
-	{0x70, 0x2a1b, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x71, 0x0a1b, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x74, 0x0a1d, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x75, 0x0a3d, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x76, 0x2a1f, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x77, 0x0a1f, 0x0511, 0x3b63, 0x0000, 0x08, 0x11, 0x00, 0x00, 0x00,
-	 0x37},
-	{0x78, 0x0a3f, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x79, 0x0a3b, 0x0612, 0x3b74, 0x0000, 0x08, 0x12, 0x00, 0x00, 0x00,
-	 0x3a},
-	{0x7a, 0x2a1d, 0x0410, 0x3b52, 0x0000, 0x08, 0x10, 0x00, 0x00, 0x07,
-	 0x34},
-	{0x7b, 0x0e3b, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0x7c, 0x0e7d, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0x7d, 0x0eff, 0x060f, 0x3ad0, 0x0000, 0x08, 0x0f, 0x00, 0x00, 0x00,
-	 0x3d},
-	{0xff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00,
-	 0x00}
-};
-
-typedef struct _SiS310_Ext2Struct {
-	USHORT Ext_InfoFlag;
-	UCHAR Ext_CRT1CRTC;
-	UCHAR Ext_CRTVCLK;
-	UCHAR Ext_CRT2CRTC;
-	UCHAR ModeID;
-	USHORT XRes;
-	USHORT YRes;
-	USHORT ROM_OFFSET;
+SiS310_ExtStruct  SiS310_EModeIDTable[]=
+{
+ {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},
+ {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},
+ {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+ {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+ {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+ {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+ {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
+ {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
+ {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
+ {0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
+ {0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
+ {0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08},
+ {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},
+ {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
+ {0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},
+ {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
+ {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
+ {0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},
+ {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},
+ {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
+ {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},
+ {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x66,0x06ff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},
+ {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},
+ {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},
+ {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},
+ {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
+ {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
+ {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+ {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+ {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+ {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+ {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+ {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
+ {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+ {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
+ {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
+ {0x7b,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+ {0x7c,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+ {0x7d,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
+ {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+typedef struct _SiS310_Ext2Struct
+{
+ USHORT Ext_InfoFlag;
+ UCHAR Ext_CRT1CRTC;
+ UCHAR Ext_CRTVCLK;
+ UCHAR Ext_CRT2CRTC;
+ UCHAR  ModeID;
+ USHORT XRes;
+ USHORT YRes;
+ USHORT ROM_OFFSET;
 } SiS310_Ext2Struct;
-SiS310_Ext2Struct SiS310_RefIndex[] = {
-	{0x005f, 0x0d, 0x03, 0x05, 0x6a, 800, 600, 0x3a81},	/* 0x0 */
-	{0x0467, 0x0e, 0x04, 0x05, 0x6a, 800, 600, 0x3a86},	/* 0x1 */
-	{0x0067, 0x0f, 0x08, 0x48, 0x6a, 800, 600, 0x3a8b},	/* 0x2 */
-	{0x0067, 0x10, 0x07, 0x8b, 0x6a, 800, 600, 0x3a90},	/* 0x3 */
-	{0x0147, 0x11, 0x0a, 0x00, 0x6a, 800, 600, 0x3a95},	/* 0x4 */
-	{0x4147, 0x12, 0x0d, 0x00, 0x6a, 800, 600, 0x3a9a},	/* 0x5 */
-	{0x4047, 0x13, 0x13, 0x00, 0x6a, 800, 600, 0x3a9f},	/* 0x6 */
-	{0x4047, 0x14, 0x1c, 0x00, 0x6a, 800, 600, 0x3aa4},	/* 0x7 */
-	{0xc05f, 0x05, 0x00, 0x04, 0x2e, 640, 480, 0x3a57},	/* 0x8 */
-	{0xc067, 0x06, 0x02, 0x04, 0x2e, 640, 480, 0x3a5c},	/* 0x9 */
-	{0xc067, 0x07, 0x02, 0x47, 0x2e, 640, 480, 0x3a61},	/* 0xa */
-	{0xc067, 0x08, 0x03, 0x8a, 0x2e, 640, 480, 0x3a66},	/* 0xb */
-	{0x4047, 0x09, 0x05, 0x00, 0x2e, 640, 480, 0x3a6b},	/* 0xc */
-	{0x4047, 0x0a, 0x09, 0x00, 0x2e, 640, 480, 0x3a70},	/* 0xd */
-	{0x4047, 0x0b, 0x0e, 0x00, 0x2e, 640, 480, 0x3a75},	/* 0xe */
-	{0xc047, 0x0c, 0x15, 0x00, 0x2e, 640, 480, 0x3a7a},	/* 0xf */
-	{0x407f, 0x04, 0x00, 0x00, 0x2f, 640, 400, 0x3a50},	/* 0x10 */
-	{0xc00f, 0x3c, 0x01, 0x06, 0x31, 720, 480, 0x3b85},	/* 0x11 */
-	{0x000f, 0x3d, 0x03, 0x06, 0x32, 720, 576, 0x3b8c},	/* 0x12 */
-	{0x0187, 0x15, 0x06, 0x00, 0x37, 1024, 768, 0x3aab},	/* 0x13 */
-	{0xc877, 0x16, 0x0b, 0x06, 0x37, 1024, 768, 0x3ab0},	/* 0x14 301b TV1024x768 */
-	{0xc067, 0x17, 0x0f, 0x49, 0x37, 1024, 768, 0x3ab5},	/* 0x15 */
-	{0x0267, 0x18, 0x11, 0x00, 0x37, 1024, 768, 0x3aba},	/* 0x16 */
-	{0x0047, 0x19, 0x16, 0x8c, 0x37, 1024, 768, 0x3abf},	/* 0x17 */
-	{0x4047, 0x1a, 0x1b, 0x00, 0x37, 1024, 768, 0x3ac4},	/* 0x18 */
-	{0x4047, 0x1b, 0x1f, 0x00, 0x37, 1024, 768, 0x3ac9},	/* 0x19 */
-	{0x0387, 0x1c, 0x11, 0x00, 0x3a, 1280, 1024, 0x3adc},	/* 0x1a */
-	{0x0077, 0x1d, 0x19, 0x07, 0x3a, 1280, 1024, 0x3ae1},	/* 0x1b */
-	{0x0047, 0x1e, 0x1e, 0x00, 0x3a, 1280, 1024, 0x3ae6},	/* 0x1c */
-	{0x0007, 0x1f, 0x20, 0x00, 0x3a, 1280, 1024, 0x3aeb},	/* 0x1d */
-	{0x0007, 0x20, 0x21, 0x00, 0x3c, 1600, 1200, 0x3af2},	/* 0x1e */
-	{0x0007, 0x21, 0x22, 0x00, 0x3c, 1600, 1200, 0x3af7},	/* 0x1f */
-	{0x0007, 0x22, 0x23, 0x00, 0x3c, 1600, 1200, 0x3afc},	/* 0x20 */
-	{0x0007, 0x23, 0x25, 0x00, 0x3c, 1600, 1200, 0x3b01},	/* 0x21 */
-	{0x0007, 0x24, 0x26, 0x00, 0x3c, 1600, 1200, 0x3b06},	/* 0x22 */
-	{0x0007, 0x25, 0x2c, 0x00, 0x3c, 1600, 1200, 0x3b0b},	/* 0x23 */
-	{0x0007, 0x26, 0x34, 0x00, 0x3c, 1600, 1200, 0x3b10},	/* 0x24 */
-	{0x407f, 0x00, 0x00, 0x00, 0x40, 320, 200, 0x3a34},	/* 0x25 */
-	{0xc07f, 0x01, 0x00, 0x04, 0x50, 320, 240, 0x3a3b},	/* 0x26 */
-	{0x007f, 0x02, 0x04, 0x05, 0x51, 400, 300, 0x3a42},	/* 0x27 */
-	{0xc077, 0x03, 0x0b, 0x06, 0x52, 512, 384, 0x3a49},	/* 0x28 */
-	{0x8007, 0x27, 0x27, 0x00, 0x68, 1920, 1440, 0x3b17},	/* 0x29 */
-	{0x4007, 0x28, 0x29, 0x00, 0x68, 1920, 1440, 0x3b1c},	/* 0x2a */
-	{0x4007, 0x29, 0x2e, 0x00, 0x68, 1920, 1440, 0x3b21},	/* 0x2b */
-	{0x4007, 0x2a, 0x30, 0x00, 0x68, 1920, 1440, 0x3b26},	/* 0x2c */
-	{0x4007, 0x2b, 0x35, 0x00, 0x68, 1920, 1440, 0x3b2b},	/* 0x2d */
-	{0x4005, 0x2c, 0x39, 0x00, 0x68, 1920, 1440, 0x3b30},	/* 0x2e */
-	{0x4007, 0x2d, 0x2b, 0x00, 0x6c, 2048, 1536, 0x3b37},	/* 0x2f */
-	{0x4007, 0x2e, 0x31, 0x00, 0x6c, 2048, 1536, 0x3b3c},	/* 0x30 */
-	{0x4007, 0x2f, 0x33, 0x00, 0x6c, 2048, 1536, 0x3b41},	/* 0x31 */
-	{0x4007, 0x30, 0x37, 0x00, 0x6c, 2048, 1536, 0x3b46},	/* 0x32 */
-	{0x4005, 0x31, 0x38, 0x00, 0x6c, 2048, 1536, 0x3b4b},	/* 0x33 */
-	{0x0057, 0x32, 0x40, 0x08, 0x70, 800, 480, 0x3b52},	/* 0x34 */
-	{0x0047, 0x33, 0x07, 0x08, 0x70, 800, 480, 0x3b57},	/* 0x35 */
-	{0x0047, 0x34, 0x0a, 0x08, 0x70, 800, 480, 0x3b5c},	/* 0x36 */
-	{0x0057, 0x35, 0x0b, 0x09, 0x71, 1024, 576, 0x3b63},	/* 0x37 */
-	{0x0047, 0x36, 0x11, 0x09, 0x71, 1024, 576, 0x3b68},	/* 0x38 */
-	{0x0047, 0x37, 0x16, 0x09, 0x71, 1024, 576, 0x3b6d},	/* 0x39 */
-	{0x0057, 0x38, 0x19, 0x0a, 0x75, 1280, 720, 0x3b74},	/* 0x3a */
-	{0x0047, 0x39, 0x1e, 0x0a, 0x75, 1280, 720, 0x3b79},	/* 0x3b */
-	{0x0047, 0x3a, 0x20, 0x0a, 0x75, 1280, 720, 0x3b7e},	/* 0x3c */
-	{0x0027, 0x3b, 0x19, 0x08, 0x7b, 1280, 960, 0x3ad0},	/* 0x3d */
-	{0x0027, 0x3b, 0x19, 0x08, 0x7b, 1280, 960, 0x3ad5},	/* 0x3e */
-	{0xffff, 0x00, 0x00, 0x00, 0x00, 0000, 0000, 0x0000}
-};
-
-typedef struct _SiS310_CRT1TableStruct {
-	UCHAR CR[17];
+SiS310_Ext2Struct SiS310_RefIndex[]=
+{
+ {0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
+ {0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
+ {0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
+ {0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
+ {0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
+ {0x4147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 */
+ {0x4047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 */
+ {0x4047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 */
+ {0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
+ {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
+ {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
+ {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
+ {0x4047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc */
+ {0x4047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd */
+ {0x4047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe */
+ {0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
+ {0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
+ {0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
+ {0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
+ {0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
+ {0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 301b TV1024x768*/
+ {0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
+ {0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
+ {0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
+ {0x4047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 */
+ {0x4047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 */
+ {0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
+ {0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
+ {0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
+ {0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
+ {0x0007,0x20,0x21,0x00,0x3c,1600,1200,0x3af2}, /* 0x1e */
+ {0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
+ {0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
+ {0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
+ {0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
+ {0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
+ {0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
+ {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
+ {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
+ {0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
+ {0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
+ {0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
+ {0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
+ {0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
+ {0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
+ {0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
+ {0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
+ {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
+ {0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
+ {0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
+ {0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
+ {0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
+ {0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
+ {0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
+ {0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
+ {0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
+ {0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
+ {0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
+ {0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
+ {0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
+ {0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
+ {0x0027,0x3b,0x19,0x08,0x7b,1280, 960,0x3ad0}, /* 0x3d */
+ {0x0027,0x3b,0x19,0x08,0x7b,1280, 960,0x3ad5}, /* 0x3e */
+ {0xffff,0x00,0x00,0x00,0x00,0000,0000,0x0000}
+};
+
+typedef struct _SiS310_CRT1TableStruct
+{
+ UCHAR CR[17];
 } SiS310_CRT1TableStruct;
-SiS310_CRT1TableStruct SiS310_CRT1Table[] = {
-	{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
-	 0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x00,
-	 0x00},			/* 0x0 */
-	{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e,
-	 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x00,
-	 0x00},			/* 0x1 */
-	{0x3d, 0x31, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
-	 0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x05,
-	 0x01},			/* 0x2 */
-	{0x4f, 0x3f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
-	 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x01,
-	 0x01},			/* 0x3 */
-	{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
-	 0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x05,
-	 0x00},			/* 0x4 */
-	{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
-	 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	 0x00},			/* 0x5 */
-	{0x63, 0x4f, 0x50, 0x86, 0x56, 0x9b, 0x06, 0x3e,
-	 0xe8, 0x8b, 0xdf, 0xe7, 0xff, 0x10, 0x00, 0x01,
-	 0x00},			/* 0x6 */
-	{0x64, 0x4f, 0x4f, 0x88, 0x55, 0x9d, 0xf2, 0x1f,
-	 0xe0, 0x83, 0xdf, 0xdf, 0xf3, 0x10, 0x00, 0x01,
-	 0x00},			/* 0x7 */
-	{0x63, 0x4f, 0x4f, 0x87, 0x5a, 0x81, 0xfb, 0x1f,
-	 0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05,
-	 0x00},			/* 0x8 */
-	{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0xfb, 0x1f,
-	 0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x00, 0x00, 0x05,
-	 0x61},			/* 0x9 */
-	{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0x01, 0x3e,
-	 0xe0, 0x83, 0xdf, 0xdf, 0x02, 0x00, 0x00, 0x05,
-	 0x61},			/* 0xa */
-	{0x67, 0x4f, 0x4f, 0x8b, 0x58, 0x81, 0x0d, 0x3e,
-	 0xe0, 0x83, 0xdf, 0xdf, 0x0e, 0x10, 0x00, 0x05,
-	 0x61},			/* 0xb */
-	{0x65, 0x4f, 0x4f, 0x89, 0x57, 0x9f, 0xfb, 0x1f,
-	 0xe6, 0x8a, 0xe5, 0xe5, 0xfc, 0x00, 0x00, 0x01,
-	 0x00},			/* 0xc */
-	{0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	 0x58, 0x8a, 0x57, 0x57, 0x70, 0x20, 0x00, 0x05,
-	 0x01},			/* 0xd */
-	{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
-	 0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x06,
-	 0x01},			/* 0xe */
-	{0x7d, 0x63, 0x63, 0x81, 0x6e, 0x1d, 0x98, 0xf0,
-	 0x7c, 0x82, 0x57, 0x57, 0x99, 0x00, 0x00, 0x06,
-	 0x01},			/* 0xf */
-	{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x70, 0x20, 0x00, 0x06,
-	 0x01},			/* 0x10 */
-	{0x7e, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06,
-	 0x01},			/* 0x11 */
-	{0x81, 0x63, 0x63, 0x85, 0x6d, 0x18, 0x7a, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x7b, 0x20, 0x00, 0x06,
-	 0x61},			/* 0x12 */
-	{0x83, 0x63, 0x63, 0x87, 0x6e, 0x19, 0x81, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x82, 0x20, 0x00, 0x06,
-	 0x61},			/* 0x13 */
-	{0x85, 0x63, 0x63, 0x89, 0x6f, 0x1a, 0x91, 0xf0,
-	 0x58, 0x8b, 0x57, 0x57, 0x92, 0x20, 0x00, 0x06,
-	 0x61},			/* 0x14 */
-	{0x99, 0x7f, 0x7f, 0x9d, 0x84, 0x1a, 0x96, 0x1f,
-	 0x7f, 0x83, 0x7f, 0x7f, 0x97, 0x10, 0x00, 0x02,
-	 0x00},			/* 0x15 */
-	{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
-	 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	 0x01},			/* 0x16 */
-	{0xa1, 0x7f, 0x7f, 0x85, 0x86, 0x97, 0x24, 0xf5,
-	 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02,
-	 0x01},			/* 0x17 */
-	{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf5,
-	 0x00, 0x83, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02,
-	 0x01},			/* 0x18 */
-	{0xa7, 0x7f, 0x7f, 0x8b, 0x89, 0x95, 0x26, 0xf5,
-	 0x00, 0x83, 0xff, 0xff, 0x27, 0x10, 0x00, 0x02,
-	 0x01},			/* 0x19 */
-	{0xa9, 0x7f, 0x7f, 0x8d, 0x8c, 0x9a, 0x2c, 0xf5,
-	 0x00, 0x83, 0xff, 0xff, 0x2d, 0x14, 0x00, 0x02,
-	 0x62},			/* 0x1a */
-	{0xab, 0x7f, 0x7f, 0x8f, 0x8d, 0x9b, 0x35, 0xf5,
-	 0x00, 0x83, 0xff, 0xff, 0x36, 0x14, 0x00, 0x02,
-	 0x62},			/* 0x1b */
-	{0xcf, 0x9f, 0x9f, 0x93, 0xb2, 0x01, 0x14, 0xba,
-	 0x00, 0x83, 0xff, 0xff, 0x15, 0x00, 0x00, 0x03,
-	 0x00},			/* 0x1c */
-	{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0x5a,
-	 0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	 0x01},			/* 0x1d */
-	{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0x5a,
-	 0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07,
-	 0x01},			/* 0x1e */
-	{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0x5a,
-	 0x00, 0x83, 0xff, 0xff, 0x2f, 0x09, 0x00, 0x07,
-	 0x01},			/* 0x1f */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x20 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x21 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x22 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x23 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x24 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x25 */
-	{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10,
-	 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04,
-	 0x00},			/* 0x26 */
-	{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	 0x00},			/* 0x27 */
-	{0x43, 0xef, 0xef, 0x87, 0x06, 0x00, 0xd4, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xd5, 0x1f, 0x41, 0x05,
-	 0x63},			/* 0x28 */
-	{0x45, 0xef, 0xef, 0x89, 0x07, 0x01, 0xd9, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xda, 0x1f, 0x41, 0x05,
-	 0x63},			/* 0x29 */
-	{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	 0x00},			/* 0x2a */
-	{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	 0x00},			/* 0x2b */
-	{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f,
-	 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01,
-	 0x00},			/* 0x2c */
-	{0x59, 0xff, 0xff, 0x9d, 0x17, 0x13, 0x33, 0xba,
-	 0x00, 0x83, 0xff, 0xff, 0x34, 0x0f, 0x41, 0x05,
-	 0x44},			/* 0x2d */
-	{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x38, 0xba,
-	 0x00, 0x83, 0xff, 0xff, 0x39, 0x0f, 0x41, 0x05,
-	 0x44},			/* 0x2e */
-	{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x3d, 0xba,
-	 0x00, 0x83, 0xff, 0xff, 0x3e, 0x0f, 0x41, 0x05,
-	 0x44},			/* 0x2f */
-	{0x5d, 0xff, 0xff, 0x81, 0x19, 0x95, 0x41, 0xba,
-	 0x00, 0x84, 0xff, 0xff, 0x42, 0x0f, 0x41, 0x05,
-	 0x44},			/* 0x30 */
-	{0x55, 0xff, 0xff, 0x99, 0x0d, 0x0c, 0x3e, 0xba,
-	 0x00, 0x84, 0xff, 0xff, 0x3f, 0x0f, 0x41, 0x05,
-	 0x00},			/* 0x31 */
-	{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xba,
-	 0x27, 0x8b, 0xdf, 0xdf, 0x73, 0x00, 0x00, 0x06,
-	 0x01},			/* 0x32 */
-	{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xba,
-	 0x26, 0x89, 0xdf, 0xdf, 0x6f, 0x00, 0x00, 0x06,
-	 0x01},			/* 0x33 */
-	{0x7f, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xba,
-	 0x29, 0x8c, 0xdf, 0xdf, 0x75, 0x00, 0x00, 0x06,
-	 0x01},			/* 0x34 */
-	{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf1,
-	 0xaf, 0x85, 0x3f, 0x3f, 0x25, 0x30, 0x00, 0x02,
-	 0x01},			/* 0x35 */
-	{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf1,
-	 0xad, 0x81, 0x3f, 0x3f, 0x1f, 0x30, 0x00, 0x02,
-	 0x01},			/* 0x36 */
-	{0xa7, 0x7f, 0x7f, 0x88, 0x89, 0x15, 0x26, 0xf1,
-	 0xb1, 0x85, 0x3f, 0x3f, 0x27, 0x30, 0x00, 0x02,
-	 0x01},			/* 0x37 */
-	{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0xc4,
-	 0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	 0x01},			/* 0x38 */
-	{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0xd4,
-	 0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07,
-	 0x01},			/* 0x39 */
-	{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0xd4,
-	 0x7d, 0x81, 0xcf, 0xcf, 0x2f, 0x21, 0x00, 0x07,
-	 0x01},			/* 0x3a */
-	{0xdc, 0x9f, 0x9f, 0x00, 0xab, 0x19, 0xe6, 0xef,
-	 0xc0, 0xc3, 0xbf, 0xbf, 0xe7, 0x10, 0x00, 0x07,
-	 0x01},			/* 0x3b */
-	{0x6b, 0x59, 0x59, 0x8f, 0x5e, 0x8c, 0x0b, 0x3e,
-	 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05,
-	 0x00},			/* 0x3c */
-	{0x7b, 0x59, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0,
-	 0x58, 0x8a, 0x3f, 0x57, 0x70, 0x20, 0x00, 0x05,
-	 0x01}			/* 0x3d */
-};
-
-typedef struct _SiS310_MCLKDataStruct {
-	UCHAR SR28, SR29, SR2A;
-	USHORT CLOCK;
+SiS310_CRT1TableStruct SiS310_CRT1Table[]=
+{
+ {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+  0x00}, /* 0x0 */
+ {0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+  0x00}, /* 0x1 */
+ {0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+  0x01}, /* 0x2 */
+ {0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+  0x01}, /* 0x3 */
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+  0x00}, /* 0x4 */
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}, /* 0x5 */
+ {0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
+  0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
+  0x00}, /* 0x6 */
+ {0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+  0x00}, /* 0x7 */
+ {0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+  0x00}, /* 0x8 */
+ {0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
+  0xe0,0x83,0xdf,0xdf,0xfc,0x00,0x00,0x05,
+  0x61}, /* 0x9 */
+ {0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
+  0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
+  0x61}, /* 0xa */
+ {0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
+  0xe0,0x83,0xdf,0xdf,0x0e,0x10,0x00,0x05,
+  0x61}, /* 0xb */
+ {0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+  0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
+  0x00}, /* 0xc */
+ {0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+  0x01}, /* 0xd */
+ {0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+  0x01}, /* 0xe */
+ {0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+  0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+  0x01}, /* 0xf */
+ {0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+  0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+  0x01}, /* 0x10 */
+ {0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+  0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+  0x01}, /* 0x11 */
+ {0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
+  0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
+  0x61}, /* 0x12 */
+ {0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
+  0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
+  0x61}, /* 0x13 */
+ {0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
+  0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
+  0x61}, /* 0x14 */
+ {0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+  0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+  0x00}, /* 0x15 */
+ {0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}, /* 0x16 */
+ {0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}, /* 0x17 */
+ {0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+  0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+  0x01}, /* 0x18 */
+ {0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+  0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+  0x01}, /* 0x19 */
+ {0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
+  0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
+  0x62}, /* 0x1a */
+ {0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
+  0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
+  0x62}, /* 0x1b */
+ {0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+  0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+  0x00}, /* 0x1c */
+ {0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}, /* 0x1d */
+ {0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
+  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+  0x01}, /* 0x1e */
+ {0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+  0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+  0x01}, /* 0x1f */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x20 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x21 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x22 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x23 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x24 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x25 */
+ {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+  0x00}, /* 0x26 */
+ {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}, /* 0x27 */
+ {0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
+  0x63}, /* 0x28 */
+ {0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
+  0x63}, /* 0x29 */
+ {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}, /* 0x2a */
+ {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}, /* 0x2b */
+ {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+  0x00}, /* 0x2c */
+ {0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
+  0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
+  0x44}, /* 0x2d */
+ {0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
+  0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
+  0x44}, /* 0x2e */
+ {0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
+  0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
+  0x44}, /* 0x2f */
+ {0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
+  0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
+  0x44}, /* 0x30 */
+ {0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+  0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+  0x00}, /* 0x31 */
+ {0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
+  0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+  0x01}, /* 0x32 */
+ {0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+  0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+  0x01}, /* 0x33 */
+ {0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+  0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+  0x01}, /* 0x34 */
+ {0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+  0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+  0x01}, /* 0x35 */
+ {0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+  0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+  0x01}, /* 0x36 */
+ {0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
+  0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+  0x01}, /* 0x37 */
+ {0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}, /* 0x38 */
+ {0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+  0x01}, /* 0x39 */
+ {0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+  0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+  0x01}, /* 0x3a */
+ {0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
+  0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+  0x01}, /* 0x3b */
+ {0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+  0x00}, /* 0x3c */
+ {0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+  0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+  0x01} /* 0x3d */
+};
+
+typedef struct _SiS310_MCLKDataStruct
+{
+ UCHAR SR28,SR29,SR2A;
+ USHORT CLOCK;
 } SiS310_MCLKDataStruct;
-SiS310_MCLKDataStruct SiS310_MCLKData[] = {
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166}
+SiS310_MCLKDataStruct SiS310_MCLKData[]=
+{
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166}
 };
 
-typedef struct _SiS310_ECLKDataStruct {
-	UCHAR SR2E, SR2F, SR30;
-	USHORT CLOCK;
+typedef struct _SiS310_ECLKDataStruct
+{
+ UCHAR SR2E,SR2F,SR30;
+ USHORT CLOCK;
 } SiS310_ECLKDataStruct;
-SiS310_ECLKDataStruct SiS310_ECLKData[] = {
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166},
-	{0x5c, 0x23, 0x01, 166}
+SiS310_ECLKDataStruct SiS310_ECLKData[]=
+{
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166}
 };
 
-typedef struct _SiS310_VCLKDataStruct {
-	UCHAR SR2B, SR2C;
-	USHORT CLOCK;
+typedef struct _SiS310_VCLKDataStruct
+{
+ UCHAR SR2B,SR2C;
+ USHORT CLOCK;
 } SiS310_VCLKDataStruct;
-SiS310_VCLKDataStruct SiS310_VCLKData[] = {
-	{0x1b, 0xe1, 25},	/* 0x0 */
-	{0x4e, 0xe4, 28},	/* 0x1 */
-	{0x57, 0xe4, 31},	/* 0x2 */
-	{0xc3, 0xc8, 36},	/* 0x3 */
-	{0x42, 0xe2, 40},	/* 0x4 */
-	{0xfe, 0xcd, 43},	/* 0x5 */
-	{0x5d, 0xc4, 44},	/* 0x6 */
-	{0x52, 0xe2, 49},	/* 0x7 */
-	{0x53, 0xe2, 50},	/* 0x8 */
-	{0x74, 0x67, 52},	/* 0x9 */
-	{0x6d, 0x66, 56},	/* 0xa */
-	{0x6c, 0xc3, 65},	/* 0xb */
-	{0x46, 0x44, 67},	/* 0xc */
-	{0xb1, 0x46, 68},	/* 0xd */
-	{0xd3, 0x4a, 72},	/* 0xe */
-	{0x29, 0x61, 75},	/* 0xf */
-	{0x6e, 0x46, 76},	/* 0x10 */
-	{0x2b, 0x61, 78},	/* 0x11 */
-	{0x31, 0x42, 79},	/* 0x12 */
-	{0xab, 0x44, 83},	/* 0x13 */
-	{0x46, 0x25, 84},	/* 0x14 */
-	{0x78, 0x29, 86},	/* 0x15 */
-	{0x62, 0x44, 94},	/* 0x16 */
-	{0x2b, 0x41, 104},	/* 0x17 */
-	{0x3a, 0x23, 105},	/* 0x18 */
-	{0x70, 0x44, 108},	/* 0x19 */
-	{0x3c, 0x23, 109},	/* 0x1a */
-	{0x5e, 0x43, 113},	/* 0x1b */
-	{0xbc, 0x44, 116},	/* 0x1c */
-	{0xe0, 0x46, 132},	/* 0x1d */
-	{0x54, 0x42, 135},	/* 0x1e */
-	{0xea, 0x2a, 139},	/* 0x1f */
-	{0x41, 0x22, 157},	/* 0x20 */
-	{0x70, 0x24, 162},	/* 0x21 */
-	{0x30, 0x21, 175},	/* 0x22 */
-	{0x4e, 0x22, 189},	/* 0x23 */
-	{0xde, 0x26, 194},	/* 0x24 */
-	{0x62, 0x06, 202},	/* 0x25 */
-	{0x3f, 0x03, 229},	/* 0x26 */
-	{0xb8, 0x06, 234},	/* 0x27 */
-	{0x34, 0x02, 253},	/* 0x28 */
-	{0x58, 0x04, 255},	/* 0x29 */
-	{0x24, 0x01, 265},	/* 0x2a */
-	{0x9b, 0x02, 267},	/* 0x2b */
-	{0x70, 0x05, 270},	/* 0x2c */
-	{0x25, 0x01, 272},	/* 0x2d */
-	{0x9c, 0x02, 277},	/* 0x2e */
-	{0x27, 0x01, 286},	/* 0x2f */
-	{0x3c, 0x02, 291},	/* 0x30 */
-	{0xef, 0x0a, 292},	/* 0x31 */
-	{0xf6, 0x0a, 310},	/* 0x32 */
-	{0x95, 0x01, 315},	/* 0x33 */
-	{0xf0, 0x09, 324},	/* 0x34 */
-	{0xfe, 0x0a, 331},	/* 0x35 */
-	{0xf3, 0x09, 332},	/* 0x36 */
-	{0xea, 0x08, 340},	/* 0x37 */
-	{0xe8, 0x07, 376},	/* 0x38 */
-	{0xde, 0x06, 389},	/* 0x39 */
-	{0x52, 0x2a, 54},	/* 0x3a */
-	{0x52, 0x6a, 27},	/* 0x3b */
-	{0x62, 0x24, 70},	/* 0x3c */
-	{0x62, 0x64, 70},	/* 0x3d */
-	{0xa8, 0x4c, 30},	/* 0x3e */
-	{0x20, 0x26, 33},	/* 0x3f */
-	{0x31, 0xc2, 39}	/* 0x40 */
-};
-
-typedef struct _SiS310_VBVCLKDataStruct {
-	UCHAR Part4_A, Part4_B;
-	USHORT CLOCK;
+SiS310_VCLKDataStruct SiS310_VCLKData[]=
+{
+ { 0x1b,0xe1, 25}, /* 0x0 */
+ { 0x4e,0xe4, 28}, /* 0x1 */
+ { 0x57,0xe4, 31}, /* 0x2 */
+ { 0xc3,0xc8, 36}, /* 0x3 */
+ { 0x42,0xe2, 40}, /* 0x4 */
+ { 0xfe,0xcd, 43}, /* 0x5 */
+ { 0x5d,0xc4, 44}, /* 0x6 */
+ { 0x52,0xe2, 49}, /* 0x7 */
+ { 0x53,0xe2, 50}, /* 0x8 */
+ { 0x74,0x67, 52}, /* 0x9 */
+ { 0x6d,0x66, 56}, /* 0xa */
+ { 0x6c,0xc3, 65}, /* 0xb */
+ { 0x46,0x44, 67}, /* 0xc */
+ { 0xb1,0x46, 68}, /* 0xd */
+ { 0xd3,0x4a, 72}, /* 0xe */
+ { 0x29,0x61, 75}, /* 0xf */
+ { 0x6e,0x46, 76}, /* 0x10 */
+ { 0x2b,0x61, 78}, /* 0x11 */
+ { 0x31,0x42, 79}, /* 0x12 */
+ { 0xab,0x44, 83}, /* 0x13 */
+ { 0x46,0x25, 84}, /* 0x14 */
+ { 0x78,0x29, 86}, /* 0x15 */
+ { 0x62,0x44, 94}, /* 0x16 */
+ { 0x2b,0x41,104}, /* 0x17 */
+ { 0x3a,0x23,105}, /* 0x18 */
+ { 0x70,0x44,108}, /* 0x19 */
+ { 0x3c,0x23,109}, /* 0x1a */
+ { 0x5e,0x43,113}, /* 0x1b */
+ { 0xbc,0x44,116}, /* 0x1c */
+ { 0xe0,0x46,132}, /* 0x1d */
+ { 0x54,0x42,135}, /* 0x1e */
+ { 0xea,0x2a,139}, /* 0x1f */
+ { 0x41,0x22,157}, /* 0x20 */
+ { 0x70,0x24,162}, /* 0x21 */
+ { 0x30,0x21,175}, /* 0x22 */
+ { 0x4e,0x22,189}, /* 0x23 */
+ { 0xde,0x26,194}, /* 0x24 */
+ { 0x62,0x06,202}, /* 0x25 */
+ { 0x3f,0x03,229}, /* 0x26 */
+ { 0xb8,0x06,234}, /* 0x27 */
+ { 0x34,0x02,253}, /* 0x28 */
+ { 0x58,0x04,255}, /* 0x29 */
+ { 0x24,0x01,265}, /* 0x2a */
+ { 0x9b,0x02,267}, /* 0x2b */
+ { 0x70,0x05,270}, /* 0x2c */
+ { 0x25,0x01,272}, /* 0x2d */
+ { 0x9c,0x02,277}, /* 0x2e */
+ { 0x27,0x01,286}, /* 0x2f */
+ { 0x3c,0x02,291}, /* 0x30 */
+ { 0xef,0x0a,292}, /* 0x31 */
+ { 0xf6,0x0a,310}, /* 0x32 */
+ { 0x95,0x01,315}, /* 0x33 */
+ { 0xf0,0x09,324}, /* 0x34 */
+ { 0xfe,0x0a,331}, /* 0x35 */
+ { 0xf3,0x09,332}, /* 0x36 */
+ { 0xea,0x08,340}, /* 0x37 */
+ { 0xe8,0x07,376}, /* 0x38 */
+ { 0xde,0x06,389}, /* 0x39 */
+ { 0x52,0x2a, 54}, /* 0x3a */
+ { 0x52,0x6a, 27}, /* 0x3b */
+ { 0x62,0x24, 70}, /* 0x3c */
+ { 0x62,0x64, 70}, /* 0x3d */
+ { 0xa8,0x4c, 30}, /* 0x3e */
+ { 0x20,0x26, 33}, /* 0x3f */
+ { 0x31,0xc2, 39} /* 0x40 */
+};
+
+typedef struct _SiS310_VBVCLKDataStruct
+{
+ UCHAR Part4_A,Part4_B;
+ USHORT CLOCK;
 } SiS310_VBVCLKDataStruct;
-SiS310_VBVCLKDataStruct SiS310_VBVCLKData[] = {
-	{0x1b, 0xe1, 25},	/* 0x0 */
-	{0x4e, 0xe4, 28},	/* 0x1 */
-	{0x57, 0xe4, 31},	/* 0x2 */
-	{0xc3, 0xc8, 36},	/* 0x3 */
-	{0x42, 0x47, 40},	/* 0x4 */
-	{0xfe, 0xcd, 43},	/* 0x5 */
-	{0x5d, 0xc4, 44},	/* 0x6 */
-	{0x52, 0x47, 49},	/* 0x7 */
-	{0x53, 0x47, 50},	/* 0x8 */
-	{0x74, 0x67, 52},	/* 0x9 */
-	{0x6d, 0x66, 56},	/* 0xa */
-	{0x5a, 0x64, 65},	/* 0xb */
-	{0x46, 0x44, 67},	/* 0xc */
-	{0xb1, 0x46, 68},	/* 0xd */
-	{0xd3, 0x4a, 72},	/* 0xe */
-	{0x29, 0x61, 75},	/* 0xf */
-	{0x6d, 0x46, 75},	/* 0x10 */
-	{0x41, 0x43, 78},	/* 0x11 */
-	{0x31, 0x42, 79},	/* 0x12 */
-	{0xab, 0x44, 83},	/* 0x13 */
-	{0x46, 0x25, 84},	/* 0x14 */
-	{0x78, 0x29, 86},	/* 0x15 */
-	{0x62, 0x44, 94},	/* 0x16 */
-	{0x2b, 0x22, 104},	/* 0x17 */
-	{0x49, 0x24, 105},	/* 0x18 */
-	{0xf8, 0x2f, 108},	/* 0x19 */
-	{0x3c, 0x23, 109},	/* 0x1a */
-	{0x5e, 0x43, 113},	/* 0x1b */
-	{0xbc, 0x44, 116},	/* 0x1c */
-	{0xe0, 0x46, 132},	/* 0x1d */
-	{0xd4, 0x28, 135},	/* 0x1e */
-	{0xea, 0x2a, 139},	/* 0x1f */
-	{0x41, 0x22, 157},	/* 0x20 */
-	{0x70, 0x24, 162},	/* 0x21 */
-	{0x30, 0x21, 175},	/* 0x22 */
-	{0x4e, 0x22, 189},	/* 0x23 */
-	{0xde, 0x26, 194},	/* 0x24 */
-	{0x70, 0x07, 202},	/* 0x25 */
-	{0x3f, 0x03, 229},	/* 0x26 */
-	{0xb8, 0x06, 234},	/* 0x27 */
-	{0x34, 0x02, 253},	/* 0x28 */
-	{0x58, 0x04, 255},	/* 0x29 */
-	{0x24, 0x01, 265},	/* 0x2a */
-	{0x9b, 0x02, 267},	/* 0x2b */
-	{0x70, 0x05, 270},	/* 0x2c */
-	{0x25, 0x01, 272},	/* 0x2d */
-	{0x9c, 0x02, 277},	/* 0x2e */
-	{0x27, 0x01, 286},	/* 0x2f */
-	{0x3c, 0x02, 291},	/* 0x30 */
-	{0xef, 0x0a, 292},	/* 0x31 */
-	{0xf6, 0x0a, 310},	/* 0x32 */
-	{0x95, 0x01, 315},	/* 0x33 */
-	{0xf0, 0x09, 324},	/* 0x34 */
-	{0xfe, 0x0a, 331},	/* 0x35 */
-	{0xf3, 0x09, 332},	/* 0x36 */
-	{0xea, 0x08, 340},	/* 0x37 */
-	{0xe8, 0x07, 376},	/* 0x38 */
-	{0xde, 0x06, 389},	/* 0x39 */
-	{0x52, 0x2a, 54},	/* 0x3a */
-	{0x52, 0x6a, 27},	/* 0x3b */
-	{0x62, 0x24, 70},	/* 0x3c */
-	{0x62, 0x64, 70},	/* 0x3d */
-	{0xa8, 0x4c, 30},	/* 0x3e */
-	{0x20, 0x26, 33},	/* 0x3f */
-	{0x31, 0xc2, 39}	/* 0x40 */
-};
-
-UCHAR SiS310_ScreenOffset[] =
-    { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35 };
-
-typedef struct _SiS310_StResInfoStruct {
-	USHORT HTotal;
-	USHORT VTotal;
+SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+{
+ { 0x1b,0xe1, 25}, /* 0x0 */
+ { 0x4e,0xe4, 28}, /* 0x1 */
+ { 0x57,0xe4, 31}, /* 0x2 */
+ { 0xc3,0xc8, 36}, /* 0x3 */
+ { 0x42,0x47, 40}, /* 0x4 */
+ { 0xfe,0xcd, 43}, /* 0x5 */
+ { 0x5d,0xc4, 44}, /* 0x6 */
+ { 0x52,0x47, 49}, /* 0x7 */
+ { 0x53,0x47, 50}, /* 0x8 */
+ { 0x74,0x67, 52}, /* 0x9 */
+ { 0x6d,0x66, 56}, /* 0xa */
+ { 0x5a,0x64, 65}, /* 0xb */
+ { 0x46,0x44, 67}, /* 0xc */
+ { 0xb1,0x46, 68}, /* 0xd */
+ { 0xd3,0x4a, 72}, /* 0xe */
+ { 0x29,0x61, 75}, /* 0xf */
+ { 0x6d,0x46, 75}, /* 0x10 */
+ { 0x41,0x43, 78}, /* 0x11 */
+ { 0x31,0x42, 79}, /* 0x12 */
+ { 0xab,0x44, 83}, /* 0x13 */
+ { 0x46,0x25, 84}, /* 0x14 */
+ { 0x78,0x29, 86}, /* 0x15 */
+ { 0x62,0x44, 94}, /* 0x16 */
+ { 0x2b,0x22,104}, /* 0x17 */
+ { 0x49,0x24,105}, /* 0x18 */
+ { 0xf8,0x2f,108}, /* 0x19 */
+ { 0x3c,0x23,109}, /* 0x1a */
+ { 0x5e,0x43,113}, /* 0x1b */
+ { 0xbc,0x44,116}, /* 0x1c */
+ { 0xe0,0x46,132}, /* 0x1d */
+ { 0xd4,0x28,135}, /* 0x1e */
+ { 0xea,0x2a,139}, /* 0x1f */
+ { 0x41,0x22,157}, /* 0x20 */
+ { 0x70,0x24,162}, /* 0x21 */
+ { 0x30,0x21,175}, /* 0x22 */
+ { 0x4e,0x22,189}, /* 0x23 */
+ { 0xde,0x26,194}, /* 0x24 */
+ { 0x70,0x07,202}, /* 0x25 */
+ { 0x3f,0x03,229}, /* 0x26 */
+ { 0xb8,0x06,234}, /* 0x27 */
+ { 0x34,0x02,253}, /* 0x28 */
+ { 0x58,0x04,255}, /* 0x29 */
+ { 0x24,0x01,265}, /* 0x2a */
+ { 0x9b,0x02,267}, /* 0x2b */
+ { 0x70,0x05,270}, /* 0x2c */
+ { 0x25,0x01,272}, /* 0x2d */
+ { 0x9c,0x02,277}, /* 0x2e */
+ { 0x27,0x01,286}, /* 0x2f */
+ { 0x3c,0x02,291}, /* 0x30 */
+ { 0xef,0x0a,292}, /* 0x31 */
+ { 0xf6,0x0a,310}, /* 0x32 */
+ { 0x95,0x01,315}, /* 0x33 */
+ { 0xf0,0x09,324}, /* 0x34 */
+ { 0xfe,0x0a,331}, /* 0x35 */
+ { 0xf3,0x09,332}, /* 0x36 */
+ { 0xea,0x08,340}, /* 0x37 */
+ { 0xe8,0x07,376}, /* 0x38 */
+ { 0xde,0x06,389}, /* 0x39 */
+ { 0x52,0x2a, 54}, /* 0x3a */
+ { 0x52,0x6a, 27}, /* 0x3b */
+ { 0x62,0x24, 70}, /* 0x3c */
+ { 0x62,0x64, 70}, /* 0x3d */
+ { 0xa8,0x4c, 30}, /* 0x3e */
+ { 0x20,0x26, 33}, /* 0x3f */
+ { 0x31,0xc2, 39} /* 0x40 */
+};
+
+UCHAR SiS310_ScreenOffset[]={ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,0x78,0x80,0x2d,0x35 };
+
+typedef struct _SiS310_StResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
 } SiS310_StResInfoStruct;
-SiS310_StResInfoStruct SiS310_StResInfo[] = {
-	{640, 400},
-	{640, 350},
-	{720, 400},
-	{720, 350},
-	{640, 480}
+SiS310_StResInfoStruct SiS310_StResInfo[]=
+{
+ { 640,400},
+ { 640,350},
+ { 720,400},
+ { 720,350},
+ { 640,480}
 };
 
-typedef struct _SiS310_ModeResInfoStruct {
-	USHORT HTotal;
-	USHORT VTotal;
-	UCHAR XChar;
-	UCHAR YChar;
+typedef struct _SiS310_ModeResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+ UCHAR  XChar;
+ UCHAR  YChar;
 } SiS310_ModeResInfoStruct;
-SiS310_ModeResInfoStruct SiS310_ModeResInfo[] = {
-	{320, 200, 8, 8},
-	{320, 240, 8, 8},
-	{320, 400, 8, 8},
-	{400, 300, 8, 8},
-	{512, 384, 8, 8},
-	{640, 400, 8, 16},
-	{640, 480, 8, 16},
-	{800, 600, 8, 16},
-	{1024, 768, 8, 16},
-	{1280, 1024, 8, 16},
-	{1600, 1200, 8, 16},
-	{1920, 1440, 8, 16},
-	{2048, 1536, 8, 16},
-	{720, 480, 8, 16},
-	{720, 576, 8, 16},
-	{1280, 960, 8, 16},
-	{800, 480, 8, 16},
-	{1024, 576, 8, 16},
-	{1280, 720, 8, 16}
+SiS310_ModeResInfoStruct SiS310_ModeResInfo[]=
+{
+ {  320, 200, 8, 8},
+ {  320, 240, 8, 8},
+ {  320, 400, 8, 8},
+ {  400, 300, 8, 8},
+ {  512, 384, 8, 8},
+ {  640, 400, 8,16},
+ {  640, 480, 8,16},
+ {  800, 600, 8,16},
+ { 1024, 768, 8,16},
+ { 1280,1024, 8,16},
+ { 1600,1200, 8,16},
+ { 1920,1440, 8,16},
+ { 2048,1536, 8,16},
+ {  720, 480, 8,16},
+ {  720, 576, 8,16},
+ { 1280, 960, 8,16},
+ {  800, 480, 8,16},
+ { 1024, 576, 8,16},
+ { 1280, 720, 8,16}
 };
 
 UCHAR SiS310_OutputSelect = 0;
 UCHAR SiS310_SoftSetting = 30;
-UCHAR SiS310_SR07 = 0x18;
-UCHAR SiS310_SR15[8][4] = {
-	{0x0, 0x4, 0x60, 0x60},
-	{0xf, 0xf, 0xf, 0xf},
-	{0xba, 0xba, 0xba, 0xba},
-	{0xa9, 0xa9, 0xac, 0xac},
-	{0xa0, 0xa0, 0xa0, 0xa8},
-	{0x0, 0x0, 0x2, 0x2},
-	{0x30, 0x30, 0x40, 0x40},
-	{0x0, 0xa5, 0xfb, 0xf6}
-};
-UCHAR SiS310_CR40[5][4] = {
-	{0x77, 0x77, 0x33, 0x33},
-	{0x77, 0x77, 0x33, 0x33},
-	{0x0, 0x0, 0x0, 0x0},
-	{0x5b, 0x5b, 0x3, 0x3},
-	{0x0, 0x0, 0xf0, 0xf8}
-};
-UCHAR SiS310_CR49[] = { 0xaa, 0x88 };
-UCHAR SiS310_SR1F = 0x0;
-UCHAR SiS310_SR21 = 0xa5;
-UCHAR SiS310_SR22 = 0xfb;
-UCHAR SiS310_SR23 = 0xf6;
-UCHAR SiS310_SR24 = 0xd;
-UCHAR SiS310_SR25[] = { 0x33, 0x3 };
-UCHAR SiS310_SR31 = 0x0;
-UCHAR SiS310_SR32 = 0x11;
-UCHAR SiS310_SR33 = 0x0;
+UCHAR SiS310_SR07=0x18;
+UCHAR SiS310_SR15[8][4]={
+{0x0,0x4,0x60,0x60},
+{0xf,0xf,0xf,0xf},
+{0xba,0xba,0xba,0xba},
+{0xa9,0xa9,0xac,0xac},
+{0xa0,0xa0,0xa0,0xa8},
+{0x0,0x0,0x2,0x2},
+{0x30,0x30,0x40,0x40},
+{0x0,0xa5,0xfb,0xf6}
+};
+UCHAR SiS310_CR40[5][4]={
+{0x77,0x77,0x33,0x33},
+{0x77,0x77,0x33,0x33},
+{0x0,0x0,0x0,0x0},
+{0x5b,0x5b,0x3,0x3},
+{0x0,0x0,0xf0,0xf8}
+};
+UCHAR SiS310_CR49[]={0xaa,0x88};
+UCHAR SiS310_SR1F=0x0;
+UCHAR SiS310_SR21=0xa5;
+UCHAR SiS310_SR22=0xfb;
+UCHAR SiS310_SR23=0xf6;
+UCHAR SiS310_SR24=0xd;
+UCHAR SiS310_SR25[]={0x33,0x3};
+UCHAR SiS310_SR31=0x0;
+UCHAR SiS310_SR32=0x11;
+UCHAR SiS310_SR33=0x0;
 UCHAR SiS310_CRT2Data_1_2 = 0x0;
 UCHAR SiS310_CRT2Data_4_D = 0x0;
 UCHAR SiS310_CRT2Data_4_E = 0x0;
@@ -1127,1192 +1087,1237 @@
 USHORT SiS310_RGBSenseData = 0xd1;
 USHORT SiS310_VideoSenseData = 0xb9;
 USHORT SiS310_YCSenseData = 0xb3;
-USHORT SiS310_RGBSenseData2 = 0x0190;	/*301b */
+USHORT SiS310_RGBSenseData2 = 0x0190;     /*301b*/
 USHORT SiS310_VideoSenseData2 = 0x0174;
 USHORT SiS310_YCSenseData2 = 0x016b;
-UCHAR SiS310_NTSCPhase[] = { 0x21, 0xed, 0x8a, 0x8 };
+UCHAR SiS310_NTSCPhase[] = {0x21,0xed,0x8a,0x8};
 
-UCHAR SiS310_PALPhase[] = { 0x2a, 0x5, 0xd3, 0x0 };
+UCHAR SiS310_PALPhase[] = {0x2a,0x5,0xd3,0x0};
 
-typedef struct _SiS310_LCDDataStruct {
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT LCDHT;
-	USHORT LCDVT;
+typedef struct _SiS310_LCDDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
 } SiS310_LCDDataStruct;
-SiS310_LCDDataStruct SiS310_StLCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] = {
-	{12, 5, 896, 512, 1344, 806},
-	{12, 5, 896, 510, 1344, 806},
-	{32, 15, 1008, 505, 1344, 806},
-	{32, 15, 1008, 514, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806},
-	{12, 5, 896, 500, 1344, 806},
-	{42, 25, 1024, 625, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] = {
-	{62, 25, 800, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{32, 15, 930, 546, 1344, 806},
-	{104, 45, 945, 496, 1344, 806},
-	{62, 25, 800, 546, 1344, 806},
-	{31, 18, 1008, 624, 1344, 806},
-	{1, 1, 1344, 806, 1344, 806}
-};
-
-SiS310_LCDDataStruct SiS310_StLCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = {
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 501, 1688, 1066},
-	{211, 60, 1024, 508, 1688, 1066},
-	{211, 60, 1024, 500, 1688, 1066},
-	{211, 75, 1024, 625, 1688, 1066},
-	{211, 120, 1280, 798, 1688, 1066},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] = {
-	{22, 5, 800, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{176, 45, 900, 510, 1650, 1088},
-	{22, 5, 800, 510, 1650, 1088},
-	{13, 5, 1024, 675, 1560, 1152},
-	{16, 9, 1266, 804, 1688, 1072},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_NoScaleData[] = {
-	{1, 1, 800, 449, 800, 449},
-	{1, 1, 800, 449, 800, 449},
-	{1, 1, 900, 449, 900, 449},
-	{1, 1, 900, 449, 900, 449},
-	{1, 1, 800, 525, 800, 525},
-	{1, 1, 1056, 628, 1056, 628},
-	{1, 1, 1344, 806, 1344, 806},
-	{1, 1, 1688, 1066, 1688, 1066}
-};
-
-SiS310_LCDDataStruct SiS310_LCD1280x960Data[] = {
-	{9, 2, 800, 500, 1800, 1000},
-	{9, 2, 800, 500, 1800, 1000},
-	{4, 1, 900, 500, 1800, 1000},
-	{4, 1, 900, 500, 1800, 1000},
-	{9, 2, 800, 500, 1800, 1000},
-	{30, 11, 1056, 625, 1800, 1000},
-	{5, 3, 1350, 800, 1800, 1000},
-	{1, 1, 1576, 1050, 1576, 1050},
-	{1, 1, 1800, 1000, 1800, 1000}
-};
-
-typedef struct _SiS310_TVDataStruct {
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT TVHDE;
-	USHORT TVVDE;
-	USHORT RVBHRS;
-	UCHAR FlickerMode;
-	USHORT HALFRVBHRS;
-	UCHAR RY1COE;
-	UCHAR RY2COE;
-	UCHAR RY3COE;
-	UCHAR RY4COE;
+SiS310_LCDDataStruct  SiS310_StLCD1024x768Data[]=
+{
+ {   62,  25, 800, 546,1344, 806},
+ {   32,  15, 930, 546,1344, 806},
+ {   32,  15, 930, 546,1344, 806},
+ {  104,  45, 945, 496,1344, 806},
+ {   62,  25, 800, 546,1344, 806},
+ {   31,  18,1008, 624,1344, 806},
+ {    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[]=
+{
+ {   12,   5, 896, 512,1344, 806},
+ {   12,   5, 896, 510,1344, 806},
+ {   32,  15,1008, 505,1344, 806},
+ {   32,  15,1008, 514,1344, 806},
+ {   12,   5, 896, 500,1344, 806},
+ {   42,  25,1024, 625,1344, 806},
+ {    1,   1,1344, 806,1344, 806},
+ {   12,   5, 896, 500,1344, 806},
+ {   42,  25,1024, 625,1344, 806},
+ {    1,   1,1344, 806,1344, 806},
+ {   12,   5, 896, 500,1344, 806},
+ {   42,  25,1024, 625,1344, 806},
+ {    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_St2LCD1024x768Data[]=
+{
+ {   62,  25, 800, 546,1344, 806},
+ {   32,  15, 930, 546,1344, 806},
+ {   32,  15, 930, 546,1344, 806},
+ {  104,  45, 945, 496,1344, 806},
+ {   62,  25, 800, 546,1344, 806},
+ {   31,  18,1008, 624,1344, 806},
+ {    1,   1,1344, 806,1344, 806}
+};
+
+SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[]=
+{
+ {   22,   5, 800, 510,1650,1088},
+ {   22,   5, 800, 510,1650,1088},
+ {  176,  45, 900, 510,1650,1088},
+ {  176,  45, 900, 510,1650,1088},
+ {   22,   5, 800, 510,1650,1088},
+ {   13,   5,1024, 675,1560,1152},
+ {   16,   9,1266, 804,1688,1072},
+ {    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[]=
+{
+ {  211,  60,1024, 501,1688,1066},
+ {  211,  60,1024, 508,1688,1066},
+ {  211,  60,1024, 501,1688,1066},
+ {  211,  60,1024, 508,1688,1066},
+ {  211,  60,1024, 500,1688,1066},
+ {  211,  75,1024, 625,1688,1066},
+ {  211, 120,1280, 798,1688,1066},
+ {    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_St2LCD1280x1024Data[]=
+{
+ {   22,   5, 800, 510,1650,1088},
+ {   22,   5, 800, 510,1650,1088},
+ {  176,  45, 900, 510,1650,1088},
+ {  176,  45, 900, 510,1650,1088},
+ {   22,   5, 800, 510,1650,1088},
+ {   13,   5,1024, 675,1560,1152},
+ {   16,   9,1266, 804,1688,1072},
+ {    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_NoScaleData[]=
+{
+ {    1,   1, 800, 449, 800, 449},
+ {    1,   1, 800, 449, 800, 449},
+ {    1,   1, 900, 449, 900, 449},
+ {    1,   1, 900, 449, 900, 449},
+ {    1,   1, 800, 525, 800, 525},
+ {    1,   1,1056, 628,1056, 628},
+ {    1,   1,1344, 806,1344, 806},
+ {    1,   1,1688,1066,1688,1066}
+};
+
+SiS310_LCDDataStruct  SiS310_LCD1280x960Data[]=
+{
+ {    9,   2, 800, 500,1800,1000},
+ {    9,   2, 800, 500,1800,1000},
+ {    4,   1, 900, 500,1800,1000},
+ {    4,   1, 900, 500,1800,1000},
+ {    9,   2, 800, 500,1800,1000},
+ {   30,  11,1056, 625,1800,1000},
+ {    5,   3,1350, 800,1800,1000},
+ {    1,   1,1576,1050,1576,1050},
+ {    1,   1,1800,1000,1800,1000}
+};
+
+typedef struct _SiS310_TVDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT TVHDE;
+ USHORT TVVDE;
+ USHORT RVBHRS;
+ UCHAR FlickerMode;
+ USHORT HALFRVBHRS;
+ UCHAR RY1COE;
+ UCHAR RY2COE;
+ UCHAR RY3COE;
+ UCHAR RY4COE;
 } SiS310_TVDataStruct;
-SiS310_TVDataStruct SiS310_StPALData[] = {
-	{1, 1, 864, 525, 1270, 400, 100, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 350, 100, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 400, 0, 0, 720, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 864, 525, 1270, 350, 0, 0, 720, 0xf4, 0x0b, 0x1c, 0x0a},
-	{1, 1, 864, 525, 1270, 480, 50, 0, 760, 0xf4, 0xff, 0x1c, 0x22},
-	{1, 1, 864, 525, 1270, 600, 50, 0, 0, 0xf4, 0xff, 0x1c, 0x22}
-};
-
-SiS310_TVDataStruct SiS310_ExtPALData[] = {
-	{27, 10, 848, 448, 1270, 530, 50, 0, 50, 0xf4, 0xff, 0x1c, 0x22},
-	{108, 35, 848, 398, 1270, 530, 50, 0, 50, 0xf4, 0xff, 0x1c, 0x22},
-	{12, 5, 954, 448, 1270, 530, 50, 0, 50, 0xf1, 0x04, 0x1f, 0x18},
-	{9, 4, 960, 463, 1644, 438, 50, 0, 50, 0xf4, 0x0b, 0x1c, 0x0a},
-	{9, 4, 848, 528, 1270, 530, 0, 0, 50, 0xf5, 0xfb, 0x1b, 0x2a},
-	{36, 25, 1060, 648, 1316, 530, 438, 0, 438, 0xeb, 0x05, 0x25, 0x16},
-	{3, 2, 1080, 619, 1270, 540, 438, 0, 438, 0xf3, 0x00, 0x1d, 0x20},
-	{1, 1, 1170, 821, 1270, 520, 686, 0, 686, 0xF3, 0x00, 0x1D, 0x20}	/*301b */
-};
-
-SiS310_TVDataStruct SiS310_StNTSCData[] = {
-	{1, 1, 858, 525, 1270, 400, 50, 0, 760, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 350, 50, 0, 640, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 400, 0, 0, 720, 0xf1, 0x04, 0x1f, 0x18},
-	{1, 1, 858, 525, 1270, 350, 0, 0, 720, 0xf4, 0x0b, 0x1c, 0x0a},
-	{1, 1, 858, 525, 1270, 480, 0, 0, 760, 0xf1, 0x04, 0x1f, 0x18}
-};
-
-SiS310_TVDataStruct SiS310_ExtNTSCData[] = {
-	{143, 65, 858, 443, 1270, 440, 171, 0, 171, 0xf1, 0x04, 0x1f, 0x18},
-	{88, 35, 858, 393, 1270, 440, 171, 0, 171, 0xf1, 0x04, 0x1f, 0x18},
-	{143, 70, 924, 443, 1270, 440, 92, 0, 92, 0xf1, 0x04, 0x1f, 0x18},
-	{143, 70, 924, 393, 1270, 440, 92, 0, 92, 0xf4, 0x0b, 0x1c, 0x0a},
-	{143, 76, 836, 523, 1270, 440, 224, 0, 0, 0xf1, 0x05, 0x1f, 0x16},
-	{143, 120, 1056, 643, 1288, 440, 0, 128, 0, 0xf4, 0x10, 0x1c, 0x00},
-	{2, 1, 858, 503, 1270, 480, 0, 128, 0, 0xee, 0x0c, 0x22, 0x08},
-	{65, 64, 1056, 791, 1270, 480, 638, 0, 0, 0xEE, 0x0C, 0x22, 0x08}	/*301b */
-};
-
-SiS310_TVDataStruct SiS310_St1HiTVData[] = {
-	0x00
-};
-
-SiS310_TVDataStruct SiS310_St2HiTVData[] = {
-	0x00
-};
-
-SiS310_TVDataStruct SiS310_ExtHiTVData[] = {
-	0x00
-};
+SiS310_TVDataStruct  SiS310_StPALData[]=
+{
+ {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
+};
+
+SiS310_TVDataStruct  SiS310_ExtPALData[]=
+{
+ {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+ {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+ {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
+ {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
+ {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
+ {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
+ {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}     /*301b*/
+};
+
+SiS310_TVDataStruct  SiS310_StNTSCData[]=
+{
+ {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
+};
+
+SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
+{
+ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
+ {  143, 120,1056, 643,1288, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
+ {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},
+ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} /*301b*/     
+};
+
+SiS310_TVDataStruct  SiS310_St1HiTVData[]=
+{
+0x00};
+
+SiS310_TVDataStruct  SiS310_St2HiTVData[]=
+{
+0x00};
+
+SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
+{
+0x00};
 
 UCHAR SiS310_NTSCTiming[] = {
-	0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
-	0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
-	0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
-	0x0c, 0x50, 0x00, 0x97, 0x00, 0xda, 0x4a, 0x17,
-	0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
-	0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
-	0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x50,
-	0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
-};
+  0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+  0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+  0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+  0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
+  0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+  0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+  0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+  0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00};
 
 UCHAR SiS310_PALTiming[] = {
-	0x19, 0x52, 0x35, 0x6e, 0x04, 0x38, 0x3d, 0x70,
-	0x94, 0x49, 0x01, 0x12, 0x06, 0x3e, 0x35, 0x6d,
-	0x06, 0x14, 0x3e, 0x35, 0x6d, 0x00, 0x45, 0x2b,
-	0x70, 0x50, 0x00, 0x9b, 0x00, 0xd9, 0x5d, 0x17,
-	0x7d, 0x05, 0x45, 0x00, 0x00, 0xe8, 0x00, 0x02,
-	0x0d, 0x00, 0x68, 0xb0, 0x0b, 0x92, 0x8f, 0x40,
-	0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x63,
-	0x00, 0x40, 0x3e, 0x00, 0xe1, 0x02, 0x28, 0x00
-};
+  0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+  0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+  0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+  0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
+  0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+  0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+  0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+  0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00};
 
-UCHAR SiS310_HiTVExtTiming[] = { 0x00 };
+UCHAR SiS310_HiTVExtTiming[] = {0x00};
 
-UCHAR SiS310_HiTVSt1Timing[] = { 0x00 };
+UCHAR SiS310_HiTVSt1Timing[] = {0x00};
 
-UCHAR SiS310_HiTVSt2Timing[] = { 0x00 };
+UCHAR SiS310_HiTVSt2Timing[] = {0x00};
 
-UCHAR SiS310_HiTVTextTiming[] = { 0x00 };
+UCHAR SiS310_HiTVTextTiming[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Data[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Data[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Simu[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Simu[] = {0x00};
 
-UCHAR SiS310_HiTVGroup3Text[] = { 0x00 };
+UCHAR SiS310_HiTVGroup3Text[] = {0x00};
 
-typedef struct _SiS310_PanelDelayTblStruct {
-	UCHAR timer[2];
+typedef struct _SiS310_PanelDelayTblStruct
+{
+ UCHAR timer[2];
 } SiS310_PanelDelayTblStruct;
-SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[] = { {0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00},
-{0x00, 0x00}
-};
-
-typedef struct _SiS310_LVDSDataStruct {
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT LCDHT;
-	USHORT LCDVT;
+SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+{{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00},
+{0x00,0x00}};
+
+typedef struct _SiS310_LVDSDataStruct
+{
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
 } SiS310_LVDSDataStruct;
-SiS310_LVDSDataStruct SiS310_LVDS800x600Data_1[] = {
-	{848, 433, 1060, 629},
-	{848, 389, 1060, 629},
-	{848, 433, 1060, 629},
-	{848, 389, 1060, 629},
-	{848, 518, 1060, 629},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{800, 449, 1000, 644},
-	{800, 525, 1000, 635}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS800x600Data_2[] = {
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{800, 449, 1000, 644},
-	{800, 525, 1000, 635}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_1[] = {
-	{840, 438, 1344, 806},
-	{840, 409, 1344, 806},
-	{840, 438, 1344, 806},
-	{840, 409, 1344, 806},
-	{840, 518, 1344, 806},
-	{1050, 638, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_2[] = {
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_1[] = {
-	{840, 438, 1344, 806},
-	{840, 409, 1344, 806},
-	{840, 438, 1344, 806},
-	{840, 409, 1344, 806},
-	{840, 518, 1344, 806},
-	{1050, 638, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_2[] = {
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{800, 449, 1280, 801},
-	{800, 525, 1280, 813}
-};
-
-SiS310_LVDSDataStruct SiS310_LVDS640x480Data_1[] = {
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 525, 800, 525},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628},
-	{1056, 628, 1056, 628}
-};
-
-SiS310_LVDSDataStruct SiS310_CHTVUNTSCData[] = {
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{784, 600, 784, 600},
-	{1064, 750, 1064, 750}
-};
-
-SiS310_LVDSDataStruct SiS310_CHTVONTSCData[] = {
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{784, 525, 784, 525},
-	{1040, 700, 1040, 700}
-};
-
-SiS310_LVDSDataStruct SiS310_CHTVUPALData[] = {
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{840, 750, 840, 750},
-	{936, 836, 936, 836}
-};
-
-SiS310_LVDSDataStruct SiS310_CHTVOPALData[] = {
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{1008, 625, 1008, 625},
-	{840, 625, 840, 625},
-	{960, 750, 960, 750}
-};
-
-typedef struct _SiS310_LVDSDesStruct {
-	USHORT LCDHDES;
-	USHORT LCDVDES;
+SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]=
+{
+ {848, 433,1060, 629},
+ {848, 389,1060, 629},
+ {848, 433,1060, 629},
+ {848, 389,1060, 629},
+ {848, 518,1060, 629},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {800, 449,1000, 644},
+ {800, 525,1000, 635}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=
+{
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {800, 449,1000, 644},
+ {800, 525,1000, 635}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]=
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=
+{
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 525, 800, 525},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628}
+};
+
+SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=
+{
+ {840, 600, 840, 600},
+ {840, 600, 840, 600},
+ {840, 600, 840, 600},
+ {840, 600, 840, 600},
+ {784, 600, 784, 600},
+ {1064, 750,1064, 750}
+};
+
+SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=
+{
+ {840, 525, 840, 525},
+ {840, 525, 840, 525},
+ {840, 525, 840, 525},
+ {840, 525, 840, 525},
+ {784, 525, 784, 525},
+ {1040, 700,1040, 700}
+};
+
+SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {840, 750, 840, 750},
+ {936, 836, 936, 836}
+};
+
+SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]=
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {840, 625, 840, 625},
+ {960, 750, 960, 750}
+};
+
+typedef struct _SiS310_LVDSDesStruct
+{
+ USHORT LCDHDES;
+ USHORT LCDVDES;
 } SiS310_LVDSDesStruct;
-SiS310_LVDSDesStruct SiS310_PanelType00_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType01_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType02_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType03_1[] = {
-	{8, 436},
-	{8, 440},
-	{8, 436},
-	{8, 440},
-	{8, 512},
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType04_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType05_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType06_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType07_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType08_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType09_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0a_1[] = {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0b_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0c_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0d_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0e_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0f_1[] = {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343, 0},
-	{1343, 0},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType00_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType01_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType02_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType03_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{1152, 622},
-	{1152, 597}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType04_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType05_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType06_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType07_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType08_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType09_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0a_2[] = {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{0, 627},
-	{0, 627},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0b_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0c_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0d_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0e_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{0, 805},
-	{0, 794},
-	{0, 0}
+SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType03_1[]=
+{
+ { 8, 436},
+ { 8, 440},
+ { 8, 436},
+ { 8, 440},
+ { 8, 512},
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType05_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType07_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343,   0},
+ {1343,   0},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType01_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType02_2[]=
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ {1152, 622},
+ {1152, 597}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType09_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_PanelType0f_2[]=
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0,   0}
 };
 /*301b*/
-SiS310_LVDSDesStruct SiS310_PanelType1076_1[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1210_1[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1296_1[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1076_2[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1210_2[] = {
-	0x00, 0x00
-};
-SiS310_LVDSDesStruct SiS310_PanelType1296_2[] = {
-	0x00, 0x00
-};
+SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=
+{
+0x00,0x00};
+SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=
+{
+0x00,0x00};
 /*end 301b*/
 
-SiS310_LVDSDesStruct SiS310_CHTVUNTSCDesData[] = {
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVONTSCDesData[] = {
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVUPALDesData[] = {
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{0, 0},
-	{0, 0}
-};
-
-SiS310_LVDSDesStruct SiS310_CHTVOPALDesData[] = {
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{256, 0},
-	{0, 0},
-	{0, 0}
-};
-
-typedef struct _SiS310_LVDSCRT1DataStruct {
-	UCHAR CR[17];
+SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
+{
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
+{
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
+{
+ {256,   0},
+ {256,   0},
+ {256,   0},
+ {256,   0},
+ { 0,   0},
+ { 0,   0}
+};
+
+SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
+{
+ {256,   0},
+ {256,   0},
+ {256,   0},
+ {256,   0},
+ { 0,   0},
+ { 0,   0}
+};
+
+typedef struct _SiS310_LVDSCRT1DataStruct
+{
+ UCHAR CR[17];
 } SiS310_LVDSCRT1DataStruct;
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
-    { {0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 0x1f,
-       0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x05,
-       0x00},
-{0x65, 0x4f, 0x89, 0x56, 0x83, 0x83, 0x1f,
- 0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x05,
- 0x00},
-{0x65, 0x4f, 0x89, 0x56, 0x83, 0xaf, 0x1f,
- 0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x05,
- 0x00},
-{0x65, 0x4f, 0x89, 0x56, 0x83, 0x83, 0x1f,
- 0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x05,
- 0x00},
-{0x65, 0x4f, 0x89, 0x56, 0x83, 0x04, 0x3e,
- 0xe0, 0x85, 0xdf, 0xfb, 0x10, 0x00, 0x05,
- 0x00},
-{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
- 0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] =
-    { {0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
-       0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x05,
-       0x00},
-{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
- 0x60, 0x87, 0x5d, 0x5d, 0x83, 0x10, 0x00, 0x05,
- 0x00},
-{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0xc4, 0x1f,
- 0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x05,
- 0x00},
-{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x97, 0x1f,
- 0x60, 0x87, 0x5d, 0x5d, 0x83, 0x10, 0x00, 0x05,
- 0x00},
-{0x73, 0x4f, 0x4f, 0x97, 0x55, 0x86, 0x04, 0x3e,
- 0xE2, 0x89, 0xDf, 0xDf, 0x05, 0x00, 0x00, 0x05,
- 0x00},
-{0x87, 0x63, 0x63, 0x8B, 0x69, 0x1A, 0x7c, 0xf0,
- 0x5A, 0x8F, 0x57, 0x57, 0x7D, 0x20, 0x00, 0x26,
- 0x01},
-{0xA3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
- 0x02, 0x88, 0xFf, 0xFf, 0x25, 0x10, 0x00, 0x02,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] =
-    { {0x63, 0x4f, 0x87, 0x54, 0x9f, 0xb4, 0x1f,
-       0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x01,
-       0x00},
-{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x82, 0x1f,
- 0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x01,
- 0x00},
-{0x63, 0x4f, 0x87, 0x54, 0x9f, 0xb4, 0x1f,
- 0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x01,
- 0x00},
-{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x82, 0x1f,
- 0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x01,
- 0x00},
-{0x63, 0x4f, 0x87, 0x54, 0x9f, 0x04, 0x3e,
- 0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x01,
- 0x00},
-{0x7e, 0x63, 0x82, 0x68, 0x15, 0x7c, 0xf0,
- 0x5a, 0x8f, 0x57, 0x7d, 0x20, 0x00, 0x26,
- 0x01},
-{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
- 0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] =
-    { {0x30, 0x27, 0x94, 0x2c, 0x92, 0xaf, 0x1f,
-       0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x04,
-       0x00},
-{0x30, 0x27, 0x94, 0x2c, 0x92, 0x83, 0x1f,
- 0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x04,
- 0x00},
-{0x30, 0x27, 0x94, 0x2c, 0x92, 0xaf, 0x1f,
- 0x90, 0x85, 0x8f, 0xab, 0x30, 0x00, 0x04,
- 0x00},
-{0x30, 0x27, 0x94, 0x2c, 0x92, 0x83, 0x1f,
- 0x5e, 0x83, 0x5d, 0x79, 0x10, 0x00, 0x04,
- 0x00},
-{0x30, 0x27, 0x94, 0x2c, 0x92, 0x04, 0x3e,
- 0xe0, 0x85, 0xdf, 0xfb, 0x10, 0x00, 0x04,
- 0x00},
-{0x3d, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
- 0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x05,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] =
-    { {0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
-       0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x44,
-       0x00},
-{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
- 0x60, 0x87, 0x5D, 0x5D, 0x83, 0x01, 0x00, 0x44,
- 0x00},
-{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0xc4, 0x1f,
- 0x92, 0x89, 0x8f, 0x8f, 0xb5, 0x30, 0x00, 0x44,
- 0x00},
-{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x97, 0x1f,
- 0x60, 0x87, 0x5D, 0x5D, 0x83, 0x01, 0x00, 0x44,
- 0x00},
-{0x37, 0x27, 0x27, 0x9B, 0x2b, 0x94, 0x04, 0x3e,
- 0xE2, 0x89, 0xDf, 0xDf, 0x05, 0x00, 0x00, 0x44,
- 0x00},
-{0x41, 0x31, 0x31, 0x85, 0x35, 0x1d, 0x7c, 0xf0,
- 0x5A, 0x8F, 0x57, 0x57, 0x7D, 0x20, 0x00, 0x55,
- 0x01},
-{0x4f, 0x3F, 0x3F, 0x93, 0x45, 0x0D, 0x24, 0xf5,
- 0x02, 0x88, 0xFf, 0xFf, 0x25, 0x10, 0x00, 0x01,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] =
-    { {0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
-       0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
-       0x00},
-{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
- 0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
- 0x00},
-{0x2f, 0x27, 0x93, 0x2b, 0x90, 0xb4, 0x1f,
- 0x92, 0x89, 0x8f, 0xb5, 0x30, 0x00, 0x04,
- 0x00},
-{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x82, 0x1f,
- 0x60, 0x87, 0x5d, 0x83, 0x10, 0x00, 0x04,
- 0x00},
-{0x2f, 0x27, 0x93, 0x2b, 0x90, 0x04, 0x3e,
- 0xe2, 0x89, 0xdf, 0x05, 0x00, 0x00, 0x04,
- 0x00},
-{0x3c, 0x31, 0x80, 0x35, 0x1c, 0x7c, 0xf0,
- 0x5a, 0x8f, 0x57, 0x7d, 0x20, 0x00, 0x55,
- 0x01},
-{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
- 0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[] =
-    { {0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
-       0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
-       0x00},
-{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
- 0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
- 0x00},
-{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
- 0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x06,
- 0x00},
-{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0x3e,
- 0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x06,
- 0x00},
-{0x7f, 0x4f, 0x83, 0x62, 0x12, 0x72, 0xba,
- 0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x06,
- 0x00},
-{0x7f, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0,
- 0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x06,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] =
-    { {0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-       0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-       0x00},
-{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
- 0x00},
-{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
- 0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
- 0x00},
-{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
- 0x00},
-{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
- 0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x06,
- 0x00},
-{0xa3, 0x63, 0x87, 0x78, 0x89, 0x24, 0xf1,
- 0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x02,
- 0x01},
-{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
- 0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] =
-    { {0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
-       0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
-       0x00},
-{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
- 0x00},
-{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
- 0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x06,
- 0x00},
-{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x06,
- 0x00},
-{0xa3, 0x4f, 0x87, 0x6e, 0x9f, 0x24, 0xbb,
- 0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x06,
- 0x00},
-{0xa3, 0x63, 0x87, 0x78, 0x89, 0x24, 0xf1,
- 0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x02,
- 0x01},
-{0xa3, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5,
- 0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x02,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] =
-    { {0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
-       0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x05,
-       0x00},
-{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
- 0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x05,
- 0x00},
-{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0x3e,
- 0xf4, 0x88, 0x8f, 0x73, 0x20, 0x00, 0x05,
- 0x00},
-{0x3d, 0x27, 0x81, 0x3a, 0x1a, 0x72, 0x3e,
- 0xdb, 0x8f, 0x5d, 0x73, 0x20, 0x00, 0x05,
- 0x00},
-{0x3d, 0x27, 0x81, 0x32, 0x1a, 0x72, 0xba,
- 0x1c, 0x80, 0xdf, 0x73, 0x00, 0x00, 0x05,
- 0x00},
-{0x3d, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0,
- 0x58, 0x8c, 0x57, 0x73, 0x20, 0x00, 0x05,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] =
-    { {0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
-       0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-       0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
- 0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x01, 0x24, 0xbb,
- 0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x31, 0x93, 0x3e, 0x06, 0x24, 0xf1,
- 0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x01,
- 0x01},
-{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
- 0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] =
-    { {0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
-       0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
-       0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
- 0x4a, 0x80, 0x8f, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
- 0x31, 0x87, 0x5d, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x27, 0x93, 0x39, 0x81, 0x24, 0xbb,
- 0x72, 0x88, 0xdf, 0x25, 0x30, 0x00, 0x01,
- 0x00},
-{0x4f, 0x31, 0x93, 0x3e, 0x86, 0x24, 0xf1,
- 0xae, 0x84, 0x57, 0x25, 0x30, 0x00, 0x01,
- 0x01},
-{0x4f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5,
- 0x02, 0x88, 0xff, 0x25, 0x10, 0x00, 0x01,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] =
-    { {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
-       0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01,
-       0x00},
-{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
- 0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01,
- 0x00},
-{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
- 0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01,
- 0x00},
-{0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
- 0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01,
- 0x00},
-{0x5d, 0x4f, 0x81, 0x53, 0x9c, 0x56, 0xba,
- 0x18, 0x84, 0xdf, 0x57, 0x00, 0x00, 0x01,
- 0x00},
-{0x80, 0x63, 0x84, 0x6c, 0x17, 0xec, 0xf0,
- 0x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x06,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] =
-    { {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
-       0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01,
-       0x00},
-{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
- 0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01,
- 0x00},
-{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
- 0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01,
- 0x00},
-{0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
- 0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01,
- 0x00},
-{0x5d, 0x4f, 0x81, 0x56, 0x9c, 0x0b, 0x3e,
- 0xe8, 0x84, 0xdf, 0x0c, 0x00, 0x00, 0x01,
- 0x00},
-{0x7d, 0x63, 0x81, 0x6a, 0x16, 0xba, 0xf0,
- 0x7f, 0x86, 0x57, 0xbb, 0x00, 0x00, 0x06,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] =
-    { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-       0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-       0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
- 0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x64, 0x4f, 0x88, 0x55, 0x80, 0xec, 0xba,
- 0x50, 0x84, 0xdf, 0xed, 0x00, 0x00, 0x05,
- 0x00},
-{0x70, 0x63, 0x94, 0x68, 0x8d, 0x42, 0xf1,
- 0xc8, 0x8c, 0x57, 0xe9, 0x20, 0x00, 0x05,
- 0x01}
-};
-
-SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] =
-    { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
-       0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
-       0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05,
- 0x00},
-{0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
- 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x64, 0x4f, 0x88, 0x55, 0x80, 0x6f, 0xba,
- 0x20, 0x83, 0xdf, 0x70, 0x00, 0x00, 0x05,
- 0x00},
-{0x73, 0x63, 0x97, 0x69, 0x8e, 0xec, 0xf0,
- 0x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x05,
- 0x01}
-};
-
-typedef struct _SiS310_CHTVRegDataStruct {
-	UCHAR Reg[5];
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[]=
+{{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 },
+ {0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 },
+ {0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 },
+ {0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 },
+ {0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 },
+ {0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[]=
+{{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00 },
+ {0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00 },
+ {0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00},
+ {0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00 },
+ {0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
+   0x00},
+ {0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
+   0x01},
+ {0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[]=
+{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00 },
+ {0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+   0x00 },
+ {0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00 },
+ {0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+   0x00 },
+ {0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
+   0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+   0x00 },
+ {0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+   0x01 },
+ {0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[]=
+{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+   0x00 },
+ {0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+   0x00 },
+ {0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+   0x00 },
+ {0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+   0x00 },
+ {0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
+   0x00 },
+ {0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[]=
+{{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00 },
+ {0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00},
+ {0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00},
+ {0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00},
+ {0x37,0x27,0x27,0x9B,0x2b,0x94,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x44,
+   0x00},
+ {0x41,0x31,0x31,0x85,0x35,0x1d,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
+   0x01},
+ {0x4f,0x3F,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[]=
+{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00 },
+ {0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00 },
+ {0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
+   0x00 },
+ {0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+   0x00 },
+ {0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+   0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
+   0x00 },
+ {0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+   0x01 },
+ {0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
+{ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00 },
+ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00 },
+ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+   0x00 },
+ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+   0x00 },
+ {0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+   0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
+   0x00 },
+ {0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[]=
+{ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+   0x01 },
+ {0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[]=
+{ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+   0x00 },
+ {0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+   0x01 },
+ {0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[]=
+{ {0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+   0x00 },
+ {0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+   0x00 },
+ {0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+   0x00 },
+ {0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
+   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+   0x00 },
+ {0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
+   0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+   0x00 },
+ {0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[]=
+{ {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+   0x01 },
+ {0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[]=
+{ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+   0x00 },
+ {0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
+   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+   0x01 },
+ {0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[]=
+{ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 },
+ {0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
+   0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
+   0x00 },
+ {0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
+   0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[]=
+{ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 },
+ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 },
+ {0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
+   0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+   0x00 },
+ {0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
+   0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[]=
+{ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
+   0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
+   0x00 },
+ {0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
+   0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
+   0x01 }};
+
+SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[]=
+{ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 },
+ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
+   0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
+   0x00 },
+ {0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
+   0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+   0x01 }};
+
+typedef struct _SiS310_CHTVRegDataStruct
+{
+ UCHAR Reg[5];
 } SiS310_CHTVRegDataStruct;
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] = {
-	0x00
-};
+0x00 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] = {
-	0x00
-};
+0x00 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] = {
-	0x00
-};
+0x00 };
 
 SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] = {
-	0x00
-};
+0x00 };
+
+UCHAR SiS310_CHTVVCLKUNTSC[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKUNTSC[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKONTSC[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKONTSC[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKUPAL[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKUPAL[] = { 0x00 };
+UCHAR SiS310_CHTVVCLKOPAL[]={0x00 };
 
-UCHAR SiS310_CHTVVCLKOPAL[] = { 0x00 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/init.c linux/drivers/video/sis/init.c
--- linux.orig/drivers/video/sis/init.c	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/init.c	2002-07-20 01:08:30.000000000 +0000
@@ -1,809 +1,856 @@
-/* Function: Support NT X.0  MM function  */
-/* Version : V 0.80      [ynlai] 04/12/98 */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2000/12/02 01:16:16 dawes Exp $ */
+/*
+ * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740
+ * (Universal module for Linux kernel framebuffer, XFree86 4.x)
+ *
+ * Comments and changes marked with "TW" by Thomas Winischhofer <thomer@winischhofer.net>
+ *
+ * (Version : V 0.80      [ynlai] 04/12/98)
+ */
 
+/*
+#ifdef WINCE_HEADER
+*/
+/*
+#include "precomp.h"
+*/
+/*
+#endif
+*/
 #include "init.h"
-#ifdef CONFIG_FB_SIS_300
+
+#ifdef TC
+#include <stdio.h>
+#include <string.h>
+#include <conio.h>
+#include <dos.h>
+#endif
+
+#ifdef WIN2000
+#include <miniport.h>
+#include "dderror.h"
+#include "devioctl.h"
+#include "miniport.h"
+#include "ntddvdeo.h"
+#include "video.h"
+#include "sisv.h"
+#include "tools.h"
+#endif
+
+#ifdef SIS300
 #include "300vtbl.h"
 #endif
-#ifdef CONFIG_FB_SIS_315
+#ifdef SIS315H
 #include "310vtbl.h"
 #endif
 
-BOOLEAN SiSInit (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN SiSSetMode (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
+#ifdef LINUX_XF86
+BOOLEAN SiSBIOSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                       ScrnInfoPtr pScrn, DisplayModePtr mode);
+#ifdef SISDUALHEAD /* TW: For dual head */
+BOOLEAN SiSBIOSSetModeCRT1(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                       ScrnInfoPtr pScrn, DisplayModePtr mode);
+BOOLEAN SiSBIOSSetModeCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                       ScrnInfoPtr pScrn, DisplayModePtr mode);
+#endif /* dual head */
+#endif /* linux_xf86 */
+
+#ifndef LINUX_XF86
+BOOLEAN SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+
+#ifdef LINUX_XF86
+BOOLEAN SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                   ScrnInfoPtr pScrn,USHORT ModeNo);
+#else
+BOOLEAN SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
+#endif
 
 #if defined(ALLOC_PRAGMA)
 #pragma alloc_text(PAGE,SiSSetMode)
 #pragma alloc_text(PAGE,SiSInit)
 #endif
 
-void SiS_SetReg1 (USHORT, USHORT, USHORT);
-void SiS_SetReg2 (USHORT, USHORT, USHORT);
-void SiS_SetReg3 (USHORT, USHORT);
-void SiS_SetReg4 (USHORT, ULONG);
-UCHAR SiS_GetReg1 (USHORT, USHORT);
-UCHAR SiS_GetReg2 (USHORT);
-ULONG SiS_GetReg3 (USHORT);
-void SiS_ClearDAC (ULONG);
-
-#ifdef CONFIG_FB_SIS_300
-void
-InitTo300Pointer (void)
-{
-	SiS_SModeIDTable = (SiS_StStruct *) SiS300_SModeIDTable;
-	SiS_VBModeIDTable = (SiS_VBModeStruct *) SiS300_VBModeIDTable;	/*add for 300 oem util */
-	SiS_StandTable = (SiS_StandTableStruct *) SiS300_StandTable;
-	SiS_EModeIDTable = (SiS_ExtStruct *) SiS300_EModeIDTable;
-	SiS_RefIndex = (SiS_Ext2Struct *) SiS300_RefIndex;
-	SiS_CRT1Table = (SiS_CRT1TableStruct *) SiS300_CRT1Table;
-	SiS_MCLKData = (SiS_MCLKDataStruct *) SiS300_MCLKData;
-	SiS_ECLKData = (SiS_ECLKDataStruct *) SiS300_ECLKData;
-	SiS_VCLKData = (SiS_VCLKDataStruct *) SiS300_VCLKData;
-	SiS_VBVCLKData = (SiS_VBVCLKDataStruct *) SiS300_VCLKData;
-	SiS_ScreenOffset = SiS300_ScreenOffset;
-	SiS_StResInfo = (SiS_StResInfoStruct *) SiS300_StResInfo;
-	SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS300_ModeResInfo;
-
-	pSiS_OutputSelect = &SiS300_OutputSelect;
-	pSiS_SoftSetting = &SiS300_SoftSetting;
-	pSiS_SR07 = &SiS300_SR07;
-	SiS_SR15 = SiS300_SR15;
-	SiS_CR40 = SiS300_CR40;
-	SiS_CR49 = SiS300_CR49;
-	pSiS_SR1F = &SiS300_SR1F;
-	pSiS_SR21 = &SiS300_SR21;
-	pSiS_SR22 = &SiS300_SR22;
-	pSiS_SR23 = &SiS300_SR23;
-	pSiS_SR24 = &SiS300_SR24;
-	SiS_SR25 = SiS300_SR25;
-	pSiS_SR31 = &SiS300_SR31;
-	pSiS_SR32 = &SiS300_SR32;
-	pSiS_SR33 = &SiS300_SR33;
-	pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2;
-	pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D;
-	pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E;
-	pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
-	pSiS_RGBSenseData = &SiS300_RGBSenseData;
-	pSiS_VideoSenseData = &SiS300_VideoSenseData;
-	pSiS_YCSenseData = &SiS300_YCSenseData;
-	pSiS_RGBSenseData2 = &SiS300_RGBSenseData2;
-	pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
-	pSiS_YCSenseData2 = &SiS300_YCSenseData2;
-
-	SiS_NTSCPhase = SiS300_NTSCPhase;
-	SiS_PALPhase = SiS300_PALPhase;
-	SiS_NTSCPhase2 = SiS300_NTSCPhase2;
-	SiS_PALPhase2 = SiS300_PALPhase2;
-	SiS_PALMPhase = SiS300_PALMPhase;	/*add for PALMN */
-	SiS_PALNPhase = SiS300_PALNPhase;
-
-	SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS300_StLCD1024x768Data;
-	SiS_ExtLCD1024x768Data =
-	    (SiS_LCDDataStruct *) SiS300_ExtLCD1024x768Data;
-	SiS_St2LCD1024x768Data =
-	    (SiS_LCDDataStruct *) SiS300_St2LCD1024x768Data;
-	SiS_StLCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS300_StLCD1280x1024Data;
-	SiS_ExtLCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS300_ExtLCD1280x1024Data;
-	SiS_St2LCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS300_St2LCD1280x1024Data;
-	SiS_NoScaleData = (SiS_LCDDataStruct *) SiS300_NoScaleData;
-	SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS300_LCD1280x960Data;
-	SiS_StPALData = (SiS_TVDataStruct *) SiS300_StPALData;
-	SiS_ExtPALData = (SiS_TVDataStruct *) SiS300_ExtPALData;
-	SiS_StNTSCData = (SiS_TVDataStruct *) SiS300_StNTSCData;
-	SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS300_ExtNTSCData;
-	SiS_St1HiTVData = (SiS_TVDataStruct *) SiS300_St1HiTVData;
-	SiS_St2HiTVData = (SiS_TVDataStruct *) SiS300_St2HiTVData;
-	SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS300_ExtHiTVData;
-	SiS_NTSCTiming = SiS300_NTSCTiming;
-	SiS_PALTiming = SiS300_PALTiming;
-	SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing;
-	SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing;
-	SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
-	SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
-	SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
-	SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
-
-	SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS300_PanelDelayTbl;
-	SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_1;
-	SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_2;
-	SiS_LVDS1024x768Data_1 =
-	    (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_1;
-	SiS_LVDS1024x768Data_2 =
-	    (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_2;
-	SiS_LVDS1280x1024Data_1 =
-	    (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_1;
-	SiS_LVDS1280x1024Data_2 =
-	    (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_2;
-	SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS640x480Data_1;
-	SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVUNTSCData;
-	SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVONTSCData;
-	SiS_CHTVUPALData = (SiS_LVDSDataStruct *) SiS300_CHTVUPALData;
-	SiS_CHTVOPALData = (SiS_LVDSDataStruct *) SiS300_CHTVOPALData;
-	SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS300_PanelType00_1;
-	SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS300_PanelType01_1;
-	SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS300_PanelType02_1;
-	SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS300_PanelType03_1;
-	SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS300_PanelType04_1;
-	SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS300_PanelType05_1;
-	SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS300_PanelType06_1;
-	SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS300_PanelType07_1;
-	SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS300_PanelType08_1;
-	SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS300_PanelType09_1;
-	SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_1;
-	SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_1;
-	SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_1;
-	SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_1;
-	SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_1;
-	SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_1;
-	SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS300_PanelType00_2;
-	SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS300_PanelType01_2;
-	SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS300_PanelType02_2;
-	SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS300_PanelType03_2;
-	SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS300_PanelType04_2;
-	SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS300_PanelType05_2;
-	SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS300_PanelType06_2;
-	SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS300_PanelType07_2;
-	SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS300_PanelType08_2;
-	SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS300_PanelType09_2;
-	SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_2;
-	SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_2;
-	SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_2;
-	SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_2;
-	SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_2;
-	SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_2;
-	SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUNTSCDesData;
-	SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVONTSCDesData;
-	SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUPALDesData;
-	SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVOPALDesData;
-	SiS_LVDSCRT1800x600_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1;
-	SiS_LVDSCRT11024x768_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1;
-	SiS_LVDSCRT11280x1024_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1;
-	SiS_LVDSCRT1800x600_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1_H;
-	SiS_LVDSCRT11024x768_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1_H;
-	SiS_LVDSCRT11280x1024_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1_H;
-	SiS_LVDSCRT1800x600_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2;
-	SiS_LVDSCRT11024x768_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2;
-	SiS_LVDSCRT11280x1024_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2;
-	SiS_LVDSCRT1800x600_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2_H;
-	SiS_LVDSCRT11024x768_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2_H;
-	SiS_LVDSCRT11280x1024_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2_H;
-	SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UNTSC;
-	SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1ONTSC;
-	SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UPAL;
-	SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1OPAL;
-	SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UNTSC;
-	SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_ONTSC;
-	SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UPAL;
-	SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_OPAL;
-	SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
-	SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
-	SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
-	SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
-	/* 300 customization related */
-}
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-void
-InitTo310Pointer (void)
-{
-	SiS_SModeIDTable = (SiS_StStruct *) SiS310_SModeIDTable;
-	SiS_StandTable = (SiS_StandTableStruct *) SiS310_StandTable;
-	SiS_EModeIDTable = (SiS_ExtStruct *) SiS310_EModeIDTable;
-	SiS_RefIndex = (SiS_Ext2Struct *) SiS310_RefIndex;
-	SiS_CRT1Table = (SiS_CRT1TableStruct *) SiS310_CRT1Table;
-	SiS_MCLKData = (SiS_MCLKDataStruct *) SiS310_MCLKData;
-	SiS_ECLKData = (SiS_ECLKDataStruct *) SiS310_ECLKData;
-	SiS_VCLKData = (SiS_VCLKDataStruct *) SiS310_VCLKData;
-	SiS_VBVCLKData = (SiS_VBVCLKDataStruct *) SiS310_VBVCLKData;
-	SiS_ScreenOffset = SiS310_ScreenOffset;
-	SiS_StResInfo = (SiS_StResInfoStruct *) SiS310_StResInfo;
-	SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS310_ModeResInfo;
-
-	pSiS_OutputSelect = &SiS310_OutputSelect;
-	pSiS_SoftSetting = &SiS310_SoftSetting;
-	pSiS_SR07 = &SiS310_SR07;
-	SiS_SR15 = SiS310_SR15;
-	SiS_CR40 = SiS310_CR40;
-	SiS_CR49 = SiS310_CR49;
-	pSiS_SR1F = &SiS310_SR1F;
-	pSiS_SR21 = &SiS310_SR21;
-	pSiS_SR22 = &SiS310_SR22;
-	pSiS_SR23 = &SiS310_SR23;
-	pSiS_SR24 = &SiS310_SR24;
-	SiS_SR25 = SiS310_SR25;
-	pSiS_SR31 = &SiS310_SR31;
-	pSiS_SR32 = &SiS310_SR32;
-	pSiS_SR33 = &SiS310_SR33;
-	pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2;
-	pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D;
-	pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E;
-	pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
-	pSiS_RGBSenseData = &SiS310_RGBSenseData;
-	pSiS_VideoSenseData = &SiS310_VideoSenseData;
-	pSiS_YCSenseData = &SiS310_YCSenseData;
-	pSiS_RGBSenseData2 = &SiS310_RGBSenseData2;
-	pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
-	pSiS_YCSenseData2 = &SiS310_YCSenseData2;
-	SiS_NTSCPhase = SiS310_NTSCPhase;
-	SiS_PALPhase = SiS310_PALPhase;
-	SiS_NTSCPhase2 = SiS310_NTSCPhase2;
-	SiS_PALPhase2 = SiS310_PALPhase2;
-	SiS_PALMPhase = SiS310_PALMPhase;	/*add for PALMN */
-	SiS_PALNPhase = SiS310_PALNPhase;
-
-	SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS310_StLCD1024x768Data;
-	SiS_ExtLCD1024x768Data =
-	    (SiS_LCDDataStruct *) SiS310_ExtLCD1024x768Data;
-	SiS_St2LCD1024x768Data =
-	    (SiS_LCDDataStruct *) SiS310_St2LCD1024x768Data;
-	SiS_StLCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS310_StLCD1280x1024Data;
-	SiS_ExtLCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS310_ExtLCD1280x1024Data;
-	SiS_St2LCD1280x1024Data =
-	    (SiS_LCDDataStruct *) SiS310_St2LCD1280x1024Data;
-	SiS_NoScaleData = (SiS_LCDDataStruct *) SiS310_NoScaleData;
-	SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS310_LCD1280x960Data;
-	SiS_StPALData = (SiS_TVDataStruct *) SiS310_StPALData;
-	SiS_ExtPALData = (SiS_TVDataStruct *) SiS310_ExtPALData;
-	SiS_StNTSCData = (SiS_TVDataStruct *) SiS310_StNTSCData;
-	SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS310_ExtNTSCData;
-	SiS_St1HiTVData = (SiS_TVDataStruct *) SiS310_St1HiTVData;
-	SiS_St2HiTVData = (SiS_TVDataStruct *) SiS310_St2HiTVData;
-	SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS310_ExtHiTVData;
-	SiS_NTSCTiming = SiS310_NTSCTiming;
-	SiS_PALTiming = SiS310_PALTiming;
-	SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing;
-	SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing;
-	SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
-	SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
-	SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
-	SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
-
-	SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS310_PanelDelayTbl;
-	SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_1;
-	SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_2;
-	SiS_LVDS1024x768Data_1 =
-	    (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_1;
-	SiS_LVDS1024x768Data_2 =
-	    (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_2;
-	SiS_LVDS1280x1024Data_1 =
-	    (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_1;
-	SiS_LVDS1280x1024Data_2 =
-	    (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_2;
-	SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS640x480Data_1;
-	SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVUNTSCData;
-	SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVONTSCData;
-	SiS_CHTVUPALData = (SiS_LVDSDataStruct *) SiS310_CHTVUPALData;
-	SiS_CHTVOPALData = (SiS_LVDSDataStruct *) SiS310_CHTVOPALData;
-	SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS310_PanelType00_1;
-	SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS310_PanelType01_1;
-	SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS310_PanelType02_1;
-	SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS310_PanelType03_1;
-	SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS310_PanelType04_1;
-	SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS310_PanelType05_1;
-	SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS310_PanelType06_1;
-	SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS310_PanelType07_1;
-	SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS310_PanelType08_1;
-	SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS310_PanelType09_1;
-	SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_1;
-	SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_1;
-	SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_1;
-	SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_1;
-	SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_1;
-	SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_1;
-	SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS310_PanelType00_2;
-	SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS310_PanelType01_2;
-	SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS310_PanelType02_2;
-	SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS310_PanelType03_2;
-	SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS310_PanelType04_2;
-	SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS310_PanelType05_2;
-	SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS310_PanelType06_2;
-	SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS310_PanelType07_2;
-	SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS310_PanelType08_2;
-	SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS310_PanelType09_2;
-	SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_2;
-	SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_2;
-	SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_2;
-	SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_2;
-	SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_2;
-	SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_2;
-	/*301b */
-	LVDS1024x768Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1076_1;
-	LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1210_1;
-	LVDS1280x960Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1296_1;
-	LVDS1024x768Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1076_2;
-	LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1210_2;
-	LVDS1280x960Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1296_2;
-	/*end 301b */
-
-	SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVUNTSCDesData;
-	SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVONTSCDesData;
-	SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *) SiS310_CHTVUPALDesData;
-	SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *) SiS310_CHTVOPALDesData;
-	SiS_LVDSCRT1800x600_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1;
-	SiS_LVDSCRT11024x768_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1;
-	SiS_LVDSCRT11280x1024_1 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1;
-	SiS_LVDSCRT1800x600_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1_H;
-	SiS_LVDSCRT11024x768_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1_H;
-	SiS_LVDSCRT11280x1024_1_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1_H;
-	SiS_LVDSCRT1800x600_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2;
-	SiS_LVDSCRT11024x768_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2;
-	SiS_LVDSCRT11280x1024_2 =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2;
-	SiS_LVDSCRT1800x600_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2_H;
-	SiS_LVDSCRT11024x768_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2_H;
-	SiS_LVDSCRT11280x1024_2_H =
-	    (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2_H;
-	SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UNTSC;
-	SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1ONTSC;
-	SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UPAL;
-	SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1OPAL;
-	SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UNTSC;
-	SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_ONTSC;
-	SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UPAL;
-	SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_OPAL;
-	/*add for LCDA */
-	SiS_LCDACRT1800x600_1 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1;
-	SiS_LCDACRT11024x768_1 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1;
-	SiS_LCDACRT11280x1024_1 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1;
-	SiS_LCDACRT1800x600_1_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1_H;
-	SiS_LCDACRT11024x768_1_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1_H;
-	SiS_LCDACRT11280x1024_1_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1_H;
-	SiS_LCDACRT1800x600_2 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2;
-	SiS_LCDACRT11024x768_2 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2;
-	SiS_LCDACRT11280x1024_2 =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2;
-	SiS_LCDACRT1800x600_2_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2_H;
-	SiS_LCDACRT11024x768_2_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2_H;
-	SiS_LCDACRT11280x1024_2_H =
-	    (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2_H;
-	/*end for 301b */
-
-	SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
-	SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
-	SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL;
-	SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL;
-	/* 310 customization related */
+void SiS_SetReg1(USHORT, USHORT, USHORT);
+void SiS_SetReg2(USHORT, USHORT, USHORT);
+void SiS_SetReg3(USHORT, USHORT);
+void SiS_SetReg4(USHORT, ULONG);
+UCHAR SiS_GetReg1(USHORT, USHORT);
+UCHAR SiS_GetReg2(USHORT);
+ULONG SiS_GetReg3(USHORT);
+void SiS_ClearDAC(ULONG);
+
+void DelaySeconds(int seconds);
+void DebugCode(UCHAR code);
+
+#ifdef LINUX_XF86
+/* TW: Mode table for X driver */
+UShort  ModeIndex_640x480[]   = {0x2E, 0x44, 0x45, 0x62};
+UShort  ModeIndex_720x480[]   = {0x31, 0x33, 0x00, 0x35};
+UShort  ModeIndex_720x576[]   = {0x32, 0x34, 0x00, 0x36};
+UShort  ModeIndex_800x600[]   = {0x30, 0x47, 0x48, 0x63};
+UShort  ModeIndex_1024x768[]  = {0x38, 0x4A, 0x4B, 0x64};
+UShort  ModeIndex_1280x1024[] = {0x3A, 0x4D, 0x4E, 0x65};
+UShort  ModeIndex_1280x960[]  = {0x7C, 0x7D, 0x00, 0x7E};
+UShort  ModeIndex_1600x1200[] = {0x3C, 0x3D, 0x3E, 0x66};
+UShort  ModeIndex_1920x1440[] = {0x68, 0x69, 0x6A, 0x6B};
+#endif
+
+void
+DelaySeconds(int seconds)
+{
+  int i;
+#ifdef WIN2000
+  int j;
+#endif
 
+  for (i=0;i<seconds;i++)
+  {
+#ifdef TC
+    delay(1000);
+#endif
+
+#ifdef WIN2000
+    for (j=0;j<20000;j++)
+      VideoPortStallExecution(50);
+#endif
+
+#ifdef WINCE_HEADER
+#endif
+
+#ifdef LINUX_KERNEL
+#endif
+  }
+}
+
+void
+DebugCode(UCHAR code)
+{
+  OutPortByte ( 0x80, code);
+  /*OutPortByte ( 0x300, code);*/
+  DelaySeconds(0x3);
+}
+
+#ifdef SIS300
+void
+InitTo300Pointer(void)
+{
+   SiS_SModeIDTable = (SiS_StStruct *) SiS300_SModeIDTable;
+   SiS_VBModeIDTable = (SiS_VBModeStruct *) SiS300_VBModeIDTable;	/*add for 300 oem util*/
+   SiS_StandTable = (SiS_StandTableStruct *) SiS300_StandTable;
+   SiS_EModeIDTable = (SiS_ExtStruct *) SiS300_EModeIDTable;
+   SiS_RefIndex = (SiS_Ext2Struct *) SiS300_RefIndex;
+   SiS_CRT1Table = (SiS_CRT1TableStruct *) SiS300_CRT1Table;
+   SiS_MCLKData = (SiS_MCLKDataStruct *) SiS300_MCLKData;
+   SiS_ECLKData = (SiS_ECLKDataStruct *) SiS300_ECLKData;
+   SiS_VCLKData = (SiS_VCLKDataStruct *) SiS300_VCLKData;
+   SiS_VBVCLKData = (SiS_VBVCLKDataStruct *) SiS300_VCLKData;
+   SiS_ScreenOffset = SiS300_ScreenOffset;
+   SiS_StResInfo = (SiS_StResInfoStruct *) SiS300_StResInfo;
+   SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS300_ModeResInfo;
+
+   pSiS_OutputSelect = &SiS300_OutputSelect;
+   pSiS_SoftSetting = &SiS300_SoftSetting;
+   pSiS_SR07 = &SiS300_SR07;
+   SiS_SR15 = SiS300_SR15;
+   SiS_CR40 = SiS300_CR40;
+   SiS_CR49 = SiS300_CR49;
+   pSiS_SR1F = &SiS300_SR1F;
+   pSiS_SR21 = &SiS300_SR21;
+   pSiS_SR22 = &SiS300_SR22;
+   pSiS_SR23 = &SiS300_SR23;
+   pSiS_SR24 = &SiS300_SR24;
+   SiS_SR25 = SiS300_SR25;
+   pSiS_SR31 = &SiS300_SR31;
+   pSiS_SR32 = &SiS300_SR32;
+   pSiS_SR33 = &SiS300_SR33;
+   pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2;
+   pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D;
+   pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E;
+   pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
+   pSiS_RGBSenseData = &SiS300_RGBSenseData;
+   pSiS_VideoSenseData = &SiS300_VideoSenseData;
+   pSiS_YCSenseData = &SiS300_YCSenseData;
+   pSiS_RGBSenseData2 = &SiS300_RGBSenseData2;
+   pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
+   pSiS_YCSenseData2 = &SiS300_YCSenseData2;
+
+   SiS_NTSCPhase = SiS300_NTSCPhase;
+   SiS_PALPhase = SiS300_PALPhase;
+   SiS_NTSCPhase2 = SiS300_NTSCPhase2;
+   SiS_PALPhase2 = SiS300_PALPhase2;
+   SiS_PALMPhase = SiS300_PALMPhase;  /*add for PALMN*/
+   SiS_PALNPhase = SiS300_PALNPhase;
+   
+   SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS300_StLCD1024x768Data;
+   SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *) SiS300_ExtLCD1024x768Data;
+   SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *) SiS300_St2LCD1024x768Data;
+   SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_StLCD1280x1024Data;
+   SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_ExtLCD1280x1024Data;
+   SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_St2LCD1280x1024Data;
+   SiS_NoScaleData = (SiS_LCDDataStruct *) SiS300_NoScaleData;
+   SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS300_LCD1280x960Data;
+   SiS_StPALData = (SiS_TVDataStruct *) SiS300_StPALData;
+   SiS_ExtPALData = (SiS_TVDataStruct *) SiS300_ExtPALData;
+   SiS_StNTSCData = (SiS_TVDataStruct *) SiS300_StNTSCData;
+   SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS300_ExtNTSCData;
+   SiS_St1HiTVData = (SiS_TVDataStruct *) SiS300_St1HiTVData;
+   SiS_St2HiTVData = (SiS_TVDataStruct *) SiS300_St2HiTVData;
+   SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS300_ExtHiTVData;
+   SiS_NTSCTiming = SiS300_NTSCTiming;
+   SiS_PALTiming = SiS300_PALTiming;
+   SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing;
+   SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing;
+   SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
+   SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
+   SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
+   SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
+
+   SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS300_PanelDelayTbl;
+   SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_1;
+   SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_2;
+   SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_1;
+   SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_2;
+   SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_1;
+   SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_2;
+   SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS640x480Data_1;
+   SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVUNTSCData;
+   SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVONTSCData;
+   SiS_CHTVUPALData = (SiS_LVDSDataStruct *) SiS300_CHTVUPALData;
+   SiS_CHTVOPALData = (SiS_LVDSDataStruct *) SiS300_CHTVOPALData;
+   SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS300_PanelType00_1;
+   SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS300_PanelType01_1;
+   SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS300_PanelType02_1;
+   SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS300_PanelType03_1;
+   SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS300_PanelType04_1;
+   SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS300_PanelType05_1;
+   SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS300_PanelType06_1;
+   SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS300_PanelType07_1;
+   SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS300_PanelType08_1;
+   SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS300_PanelType09_1;
+   SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_1;
+   SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_1;
+   SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_1;
+   SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_1;
+   SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_1;
+   SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_1;
+   SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS300_PanelType00_2;
+   SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS300_PanelType01_2;
+   SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS300_PanelType02_2;
+   SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS300_PanelType03_2;
+   SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS300_PanelType04_2;
+   SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS300_PanelType05_2;
+   SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS300_PanelType06_2;
+   SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS300_PanelType07_2;
+   SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS300_PanelType08_2;
+   SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS300_PanelType09_2;
+   SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_2;
+   SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_2;
+   SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_2;
+   SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_2;
+   SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_2;
+   SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_2;
+   SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUNTSCDesData;
+   SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVONTSCDesData;
+   SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUPALDesData;
+   SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVOPALDesData;
+   SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1;
+   SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1;
+   SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1;
+   SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1_H;
+   SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1_H;
+   SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1_H;
+   SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2;
+   SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2;
+   SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2;
+   SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2_H;
+   SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2_H;
+   SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2_H;
+   SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UNTSC;
+   SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1ONTSC;
+   SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UPAL;
+   SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1OPAL;
+   SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UNTSC;
+   SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_ONTSC;
+   SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UPAL;
+   SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_OPAL;
+   SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
+   SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
+   SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
+   SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
+   /* 300 customization related */
+}
+#endif
+
+#ifdef SIS315H
+void
+InitTo310Pointer(void)
+{
+   SiS_SModeIDTable = (SiS_StStruct *) SiS310_SModeIDTable;
+   SiS_StandTable = (SiS_StandTableStruct *) SiS310_StandTable;
+   SiS_EModeIDTable = (SiS_ExtStruct *) SiS310_EModeIDTable;
+   SiS_RefIndex = (SiS_Ext2Struct *) SiS310_RefIndex;
+   SiS_CRT1Table = (SiS_CRT1TableStruct *) SiS310_CRT1Table;
+   SiS_MCLKData = (SiS_MCLKDataStruct *) SiS310_MCLKData;
+   SiS_ECLKData = (SiS_ECLKDataStruct *) SiS310_ECLKData;
+   SiS_VCLKData = (SiS_VCLKDataStruct *) SiS310_VCLKData;
+   SiS_VBVCLKData = (SiS_VBVCLKDataStruct *) SiS310_VBVCLKData;
+   SiS_ScreenOffset = SiS310_ScreenOffset;
+   SiS_StResInfo = (SiS_StResInfoStruct *) SiS310_StResInfo;
+   SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS310_ModeResInfo;
+
+   pSiS_OutputSelect = &SiS310_OutputSelect;
+   pSiS_SoftSetting = &SiS310_SoftSetting;
+   pSiS_SR07 = &SiS310_SR07;
+   SiS_SR15 = SiS310_SR15;
+   SiS_CR40 = SiS310_CR40;
+   SiS_CR49 = SiS310_CR49;
+   pSiS_SR1F = &SiS310_SR1F;
+   pSiS_SR21 = &SiS310_SR21;
+   pSiS_SR22 = &SiS310_SR22;
+   pSiS_SR23 = &SiS310_SR23;
+   pSiS_SR24 = &SiS310_SR24;
+   SiS_SR25 = SiS310_SR25;
+   pSiS_SR31 = &SiS310_SR31;
+   pSiS_SR32 = &SiS310_SR32;
+   pSiS_SR33 = &SiS310_SR33;
+   pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2;
+   pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D;
+   pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E;
+   pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
+   pSiS_RGBSenseData = &SiS310_RGBSenseData;
+   pSiS_VideoSenseData = &SiS310_VideoSenseData;
+   pSiS_YCSenseData = &SiS310_YCSenseData;
+   pSiS_RGBSenseData2 = &SiS310_RGBSenseData2;
+   pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
+   pSiS_YCSenseData2 = &SiS310_YCSenseData2;
+   SiS_NTSCPhase = SiS310_NTSCPhase;
+   SiS_PALPhase = SiS310_PALPhase;
+   SiS_NTSCPhase2 = SiS310_NTSCPhase2;
+   SiS_PALPhase2 = SiS310_PALPhase2;
+   SiS_PALMPhase = SiS310_PALMPhase;  /*add for PALMN*/
+   SiS_PALNPhase = SiS310_PALNPhase;
+
+   SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS310_StLCD1024x768Data;
+   SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *) SiS310_ExtLCD1024x768Data;
+   SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *) SiS310_St2LCD1024x768Data;
+   SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_StLCD1280x1024Data;
+   SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_ExtLCD1280x1024Data;
+   SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_St2LCD1280x1024Data;
+   SiS_NoScaleData = (SiS_LCDDataStruct *) SiS310_NoScaleData;
+   SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS310_LCD1280x960Data;
+   SiS_StPALData = (SiS_TVDataStruct *) SiS310_StPALData;
+   SiS_ExtPALData = (SiS_TVDataStruct *) SiS310_ExtPALData;
+   SiS_StNTSCData = (SiS_TVDataStruct *) SiS310_StNTSCData;
+   SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS310_ExtNTSCData;
+   SiS_St1HiTVData = (SiS_TVDataStruct *) SiS310_St1HiTVData;
+   SiS_St2HiTVData = (SiS_TVDataStruct *) SiS310_St2HiTVData;
+   SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS310_ExtHiTVData;
+   SiS_NTSCTiming = SiS310_NTSCTiming;
+   SiS_PALTiming = SiS310_PALTiming;
+   SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing;
+   SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing;
+   SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
+   SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
+   SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
+   SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
+
+   SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS310_PanelDelayTbl;
+   SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS320x480Data_1;
+   SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_1;
+   SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_2;
+   SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_1;
+   SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_2;
+   SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_1;
+   SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_2;
+   SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS640x480Data_1;
+   SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVUNTSCData;
+   SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVONTSCData;
+   SiS_CHTVUPALData = (SiS_LVDSDataStruct *) SiS310_CHTVUPALData;
+   SiS_CHTVOPALData = (SiS_LVDSDataStruct *) SiS310_CHTVOPALData;
+   SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS310_PanelType00_1;
+   SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS310_PanelType01_1;
+   SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS310_PanelType02_1;
+   SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS310_PanelType03_1;
+   SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS310_PanelType04_1;
+   SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS310_PanelType05_1;
+   SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS310_PanelType06_1;
+   SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS310_PanelType07_1;
+   SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS310_PanelType08_1;
+   SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS310_PanelType09_1;
+   SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_1;
+   SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_1;
+   SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_1;
+   SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_1;
+   SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_1;
+   SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_1;
+   SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS310_PanelType00_2;
+   SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS310_PanelType01_2;
+   SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS310_PanelType02_2;
+   SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS310_PanelType03_2;
+   SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS310_PanelType04_2;
+   SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS310_PanelType05_2;
+   SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS310_PanelType06_2;
+   SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS310_PanelType07_2;
+   SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS310_PanelType08_2;
+   SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS310_PanelType09_2;
+   SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_2;
+   SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_2;
+   SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_2;
+   SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_2;
+   SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_2;
+   SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_2;
+   /*301b*/
+   LVDS1024x768Des_1= (SiS_LVDSDesStruct *) SiS310_PanelType1076_1;
+   LVDS1280x1024Des_1= (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
+   LVDS1280x960Des_1= (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
+   LVDS1024x768Des_2= (SiS_LVDSDesStruct *) SiS310_PanelType1076_2;
+   LVDS1280x1024Des_2= (SiS_LVDSDesStruct *) SiS310_PanelType1210_2;
+   LVDS1280x960Des_2= (SiS_LVDSDesStruct *) SiS310_PanelType1296_2;
+   /*end 301b*/
+   
+   SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVUNTSCDesData;
+   SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVONTSCDesData;
+   SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *) SiS310_CHTVUPALDesData;
+   SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *) SiS310_CHTVOPALDesData;
+   SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1;
+   SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1;
+   SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1;
+   SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1_H;
+   SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1_H;
+   SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1_H;
+   SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2;
+   SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2;
+   SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2;
+   SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2_H;
+   SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2_H;
+   SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2_H;
+   SiS_LVDSCRT1320x480_1 = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1320x480_1;   /*fstn*/
+   SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UNTSC;
+   SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1ONTSC;
+   SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UPAL;
+   SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1OPAL;
+   SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UNTSC;
+   SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_ONTSC;
+   SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UPAL;
+   SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_OPAL;
+   /*add for LCDA*/
+   SiS_LCDACRT1800x600_1 = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1;
+   SiS_LCDACRT11024x768_1 = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1;
+   SiS_LCDACRT11280x1024_1 = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1;
+   SiS_LCDACRT1800x600_1_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1_H;
+   SiS_LCDACRT11024x768_1_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1_H;
+   SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1_H;
+   SiS_LCDACRT1800x600_2 = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2;
+   SiS_LCDACRT11024x768_2 = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2;
+   SiS_LCDACRT11280x1024_2 = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2;
+   SiS_LCDACRT1800x600_2_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2_H;
+   SiS_LCDACRT11024x768_2_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2_H;
+   SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2_H;
+   /*end for 301b*/
+
+   SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
+   SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
+   SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL;
+   SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL;
+   /* 310 customization related */
 }
 #endif
 
+#ifndef LINUX_XF86
+/* -------------- SiSInit -----------------*/
 BOOLEAN
-SiSInit (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	ULONG ROMAddr = (ULONG) HwDeviceExtension->pjVirtualRomBase;
-	ULONG FBAddr = (ULONG) HwDeviceExtension->pjVideoMemoryAddress;
-	USHORT BaseAddr = (USHORT) HwDeviceExtension->ulIOAddress;
-	UCHAR i, temp = 0;
-	UCHAR SR11, temp1;
-	ULONG base;
-	UCHAR SR12 = 0, SR13 = 0, SR14 = 0, SR16 = 0, SR17 = 0, SR18 = 0, SR19 =
-	    0, SR1A = 0;
-#ifdef CONFIG_FB_SIS_315
-	/* ULONG   j, k;   */
-	UCHAR CR39 = 0, CR3A = 0, CR3B = 0, CR3C = 0, CR3D = 0, CR3E = 0, CR3F =
-	    0;
-	UCHAR CR79 = 0, CR7A = 0, CR7B = 0, CR7C = 0;
-	PSIS_DSReg pSR;
-	ULONG Temp;
-#endif
-	UCHAR VBIOSVersion[5];
-
-/* if(ROMAddr==0)   return (FALSE);*/
-	if (FBAddr == 0)
-		return (FALSE);
-	if (BaseAddr == 0)
-		return (FALSE);
-
-	SiS_SetReg3 ((USHORT) (BaseAddr + 0x12), 0x67);	/* 3c2 <- 67 ,ynlai */
-#ifdef CONFIG_FB_SIS_315
-	/*if(HwDeviceExtension->jChipType > SIS_315H) */
-	if (HwDeviceExtension->jChipType > SIS_315PRO) {
-		if (!HwDeviceExtension->bIntegratedMMEnabled)
-			return (FALSE);	/* alan  */
-	}
-#endif
-
-	SiS_MemoryCopy (VBIOSVersion, HwDeviceExtension->szVBIOSVer, 4);
-
-	VBIOSVersion[4] = 0x0;
-	/* 09/07/99 modify by domao */
-
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||	/* 05/02/01 ynlai for 550 */
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740))	/* 09/03/01 chiawen for 650 */
-		InitTo310Pointer ();
-#endif
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ||
-	    (HwDeviceExtension->jChipType == SIS_300))
-		InitTo300Pointer ();
-#endif
-
-	SiS_P3c4 = BaseAddr + 0x14;
-	SiS_P3d4 = BaseAddr + 0x24;
-	SiS_P3c0 = BaseAddr + 0x10;
-	SiS_P3ce = BaseAddr + 0x1e;
-	SiS_P3c2 = BaseAddr + 0x12;
-	SiS_P3ca = BaseAddr + 0x1a;
-	SiS_P3c6 = BaseAddr + 0x16;
-	SiS_P3c7 = BaseAddr + 0x17;
-	SiS_P3c8 = BaseAddr + 0x18;
-	SiS_P3c9 = BaseAddr + 0x19;
-	SiS_P3da = BaseAddr + 0x2A;
-	SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
-	SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
-	SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
-	SiS_Set_LVDS_TRUMPION (HwDeviceExtension);	/*2/29/00 by Mars Wen for LVDS and Trumpion  */
+   ULONG   ROMAddr  = (ULONG)HwDeviceExtension->pjVirtualRomBase;
+   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+   UCHAR   i,temp=0;
+   UCHAR   SR11;
+#ifdef LINUX_KERNEL
+   UCHAR   temp1;
+   ULONG   base;
+#endif
+   UCHAR   SR12=0,SR13=0,SR14=0,SR16=0,SR17=0,SR18=0,SR19=0,SR1A=0;
+
+#ifdef SIS315H
+   UCHAR   CR37=0,CR38=0,CR79=0,CR7A=0,CR7B=0,CR7C=0;
+   UCHAR   SR1B=0,SR15=0;
+   PSIS_DSReg  pSR;
+   ULONG   Temp;
+#endif
+   UCHAR   VBIOSVersion[5];
 
-	SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);	/* 1.Openkey  */
+   if(FBAddr==0)    return (FALSE);
+   if(BaseAddr==0)  return (FALSE);
+
+   SiS_SetReg3((USHORT)(BaseAddr+0x12),  0x67);  /* 3c2 <- 67 ,ynlai */
+
+#ifdef SIS315H
+   /*if(HwDeviceExtension->jChipType > SIS_315H)*/
+   if(HwDeviceExtension->jChipType > SIS_315PRO) {
+     if(!HwDeviceExtension->bIntegratedMMEnabled)
+     	return (FALSE);  /* alan  */
+   }
+#endif
+
+   SiS_MemoryCopy(VBIOSVersion,HwDeviceExtension->szVBIOSVer,4);
+   VBIOSVersion[4]= 0x0;
+   /* 09/07/99 modify by domao */
+
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315PRO)||
+      (HwDeviceExtension->jChipType == SIS_550)||   /* 05/02/01 ynlai for 550 */
+      (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_650))    /* 09/03/01 chiawen for 650 */
+     InitTo310Pointer();
+#endif
+
+#ifdef SIS300
+   if ((HwDeviceExtension->jChipType == SIS_540)||
+       (HwDeviceExtension->jChipType == SIS_630)||
+       (HwDeviceExtension->jChipType == SIS_730)||
+       (HwDeviceExtension->jChipType == SIS_300))
+     InitTo300Pointer();
+#endif
+
+   /* TW: Set SiS Register globals */
+   SiSRegInit(BaseAddr);
+
+   /* TW: Determine LVDS/CH7005/TRUMPION */
+   SiS_Set_LVDS_TRUMPION(HwDeviceExtension);
+
+   SiS_SetReg1(SiS_P3c4,0x05,0x86);                     /* 1.Openkey - unlock registers */
 
 #ifdef LINUX_KERNEL
-#ifdef CONFIG_FB_SIS_300	/* add to set SR14 */
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		base = 0x80000060;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 >> (16 + 8 + 4);
-		temp1 = temp1 & (0x07);
-		temp1 = temp1 + 1;
-		temp1 = 1 << temp1;
-		SR14 = temp1 - 1;
-		base = 0x80000064;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 & (0x00000020);
-		if (temp1)
-			SR14 = (0x10000000) | SR14;
-		else
-			SR14 = (0x01000000) | SR14;
-	}
-#endif
-
-#ifdef CONFIG_FB_SIS_315	/* add to set SR14 */
-	if ((HwDeviceExtension->jChipType == SIS_550)) {
-		base = 0x80000060;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 >> (16 + 8 + 4);
-		temp1 = temp1 & (0x07);
-		temp1 = temp1 + 1;
-		temp1 = 1 << temp1;
-		SR14 = temp1 - 1;
-		base = 0x80000064;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 & (0x00000020);
-		if (temp1)
-			SR14 = (0x10000000) | SR14;
-		else
-			SR14 = (0x01000000) | SR14;
-	}
-
-	if ((HwDeviceExtension->jChipType == SIS_640)
-	    || (HwDeviceExtension->jChipType == SIS_740)) {
-		base = 0x80000064;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp >> 4;
-		temp1 = temp1 & (0x07);
-		if (temp1 > 2) {
-			temp = temp1;
-			switch (temp) {
-			case 3:
-				temp1 = 0x07;
-				break;
-			case 4:
-				temp1 = 0x0F;
-				break;
-			case 5:
-				temp1 = 0x1F;
-				break;
-			case 6:
-				temp1 = 0x05;
-				break;
-			case 7:
-				temp1 = 0x17;
-				break;
-			case 8:
-				break;
-			case 9:
-				break;
-			}
-		}
-		SR14 = temp1;
-		base = 0x8000007C;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 & (0x00000020);
-		if (temp1)
-			SR14 = (0x10000000) | SR14;
-	}
-#endif
-
-#endif
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		SR12 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x12);
-		SR13 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x13);
-		SR14 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x14);
-		SR16 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x16);
-		SR17 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x17);
-		SR18 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x18);
-		SR19 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x19);
-		SR1A = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x1A);
-	} else {
-		SR13 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x13);
-		SR14 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x14);
-	}
-#endif
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_550)) {
-		CR39 = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x39);
-		CR3A = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3A);
-		CR3B = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3B);
-		CR3C = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3C);
-		CR3D = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3D);
-		CR3E = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3E);
-		CR3F = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x3F);
-		CR79 = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x79);
-		CR7A = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x7A);
-		CR7B = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x7B);
-		CR7C = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x7C);
-	} else if ((HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-		   (HwDeviceExtension->jChipType == SIS_740)) {
-		SR12 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x12);
-		SR13 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x13);
-		SR14 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x14);
-		SR16 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x16);
-		SR17 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x17);
-		SR18 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x18);
-		SR19 = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x19);
-		SR1A = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x1A);
-	}
-#endif
-/* ResetExtReg begin */
-	for (i = 0x06; i < 0x20; i++)
-		SiS_SetReg1 (SiS_P3c4, i, 0);	/* 2.Reset Extended register */
-	for (i = 0x21; i <= 0x27; i++)
-		SiS_SetReg1 (SiS_P3c4, i, 0);	/*   Reset Extended register */
-	for (i = 0x31; i <= 0x3D; i++)
-		SiS_SetReg1 (SiS_P3c4, i, 0);
-
-#ifdef CONFIG_FB_SIS_300H
-	for (i = 0x38; i <= 0x3F; i++)
-		SiS_SetReg1 (SiS_P3d4, i, 0);
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-	for (i = 0x37; i <= 0x3F; i++)
-		SiS_SetReg1 (SiS_P3d4, i, 0);
-	for (i = 0x79; i <= 0x7C; i++)
-		SiS_SetReg1 (SiS_P3d4, i, 0);
+
+#ifdef SIS300                                         	/* add to set SR14*/
+   if((HwDeviceExtension->jChipType==SIS_540)||
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)) {
+     base=0x80000060;
+     OutPortLong(base,0xcf8);
+     temp1=InPortLong(0xcfc);
+     temp1=temp1>>(16+8+4);
+     temp1=temp1&(0x07);
+     temp1=temp1+1;
+     temp1=1<<temp1;
+     SR14=temp1-1;
+     base=0x80000064;
+     OutPortLong(base,0xcf8);
+     temp1=InPortLong(0xcfc);
+     temp1=temp1&(0x00000020);
+     if(temp1)
+      	SR14=(0x10000000)|SR14;
+     else
+      	SR14=(0x01000000)|SR14;
+   }
+#endif
+
+#ifdef SIS315H                                         /* add to set SR14*/
+   if(HwDeviceExtension->jChipType==SIS_550) {
+     base=0x80000060;
+     OutPortLong(base,0xcf8);
+     temp1=InPortLong(0xcfc);
+     temp1=temp1>>(16+8+4);
+     temp1=temp1&(0x07);
+     temp1=temp1+1;
+     temp1=1<<temp1;
+     SR14=temp1-1;
+     base=0x80000064;
+     OutPortLong(base,0xcf8);
+     temp1=InPortLong(0xcfc);
+     temp1=temp1&(0x00000020);
+     if(temp1)
+      SR14=(0x10000000)|SR14;
+     else
+      SR14=(0x01000000)|SR14;
+   }
+
+   if((HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_650)) {  /* 09/03/01 chiawen for 650 */
+     base=0x80000064;
+     OutPortLong(base,0xcf8);
+     temp1=InPortLong(0xcfc);
+     temp1=temp>>4;
+     temp1=temp1&(0x07);
+     if(temp1 > 2 ) {
+       temp = temp1;
+       switch(temp) {
+        case 3: temp1=0x07;  break;
+        case 4: temp1=0x0F;  break;
+        case 5: temp1=0x1F;  break;
+        case 6: temp1=0x05;  break;
+        case 7: temp1=0x17;  break;
+        case 8: break;
+        case 9: break;
+       }
+     }
+     SR14=temp1;
+     base=0x8000007C;
+     OutPortLong(base,0xcf8);
+     temp1=InPortLong(0xcfc);
+     temp1=temp1&(0x00000020);
+     if(temp1)
+       SR14=(0x10000000)|SR14;
+   }
+#endif
+
+#endif  /* Linux kernel */
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)) {
+     SR12 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x12);
+     SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
+     SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
+     SR16 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
+     SR17 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x17);
+     SR18 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x18);
+     SR19 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x19);
+     SR1A = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+   } else if(HwDeviceExtension->jChipType == SIS_300){
+     SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
+     SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
+   }
+#endif
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_650)) {  /* 09/03/01 chiawen for 650 */
+     SR19 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x19);
+     SR19 = (SR19)||0x01;  /* TW: ??? || ??? */
+     if(SR19==0x00) {
+     	SR13 = 0x22;
+     	SR14 = 0x00;
+    	SR15 = 0x01;
+     	SR16 = 0x00;
+     	SR17 = 0x00;
+     	SR1A = 0x00;
+     	SR1B = 0x00;
+     	CR37 = 0x00;
+     	CR38 = 0x00;
+     	CR79 = 0x00;
+     	CR7A = 0x00;
+     	CR7B = 0x00;
+     	CR7C = 0x00;
+     } else {
+     	SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
+     	SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
+     	SR15 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
+     	SR16 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
+     	SR17 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x17);
+     	SR1A = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+     	SR1B = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1B);
+     	CR37 = 0x02;/*(UCHAR)SiS_GetReg1(SiS_P3d4,0x37);*/
+     	CR38 = (UCHAR)SiS_GetReg1(SiS_P3d4,0x38);
+     	CR79 = (UCHAR)SiS_GetReg1(SiS_P3d4,0x79);
+     	CR7A = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7A);
+     	CR7B = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7B);
+     	CR7C = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7C);
+     }
+   }
+#endif
+
+/* ResetExtReg begin: Reset extended registers */
+
+   for(i=0x06;i< 0x20;i++) SiS_SetReg1(SiS_P3c4,i,0);   /* 2.Reset Extended register */
+   for(i=0x21;i<=0x27;i++) SiS_SetReg1(SiS_P3c4,i,0);   /*   Reset Extended register */
+   for(i=0x31;i<=0x3D;i++) SiS_SetReg1(SiS_P3c4,i,0);
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)||
+      (HwDeviceExtension->jChipType == SIS_300)) {
+     	for(i=0x38;i<=0x3F;i++) SiS_SetReg1(SiS_P3d4,i,0);
+   }
+#endif
+
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315PRO)||
+      (HwDeviceExtension->jChipType == SIS_550)||   /* 05/02/01 ynlai for 550 */
+      (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_650)) {
+   	for(i=0x12;i<=0x1B;i++) SiS_SetReg1(SiS_P3c4,i,0);
+   	for(i=0x79;i<=0x7C;i++) SiS_SetReg1(SiS_P3d4,i,0);
+   }
 #endif
 /* ResetExtReg end */
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		SiS_SetReg1 (SiS_P3c4, 0x12, SR12);
-		SiS_SetReg1 (SiS_P3c4, 0x13, SR13);
-		SiS_SetReg1 (SiS_P3c4, 0x14, SR14);
-		SiS_SetReg1 (SiS_P3c4, 0x16, SR16);
-		SiS_SetReg1 (SiS_P3c4, 0x17, SR17);
-		SiS_SetReg1 (SiS_P3c4, 0x18, SR18);
-		SiS_SetReg1 (SiS_P3c4, 0x19, SR19);
-		SiS_SetReg1 (SiS_P3c4, 0x1A, SR1A);
-	}
-#endif
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_550)) {
-		SiS_SetReg1 (SiS_P3d4, 0x39, CR39);
-		SiS_SetReg1 (SiS_P3d4, 0x3A, CR3A);
-		SiS_SetReg1 (SiS_P3d4, 0x3B, CR3B);
-		SiS_SetReg1 (SiS_P3d4, 0x3C, CR3C);
-		SiS_SetReg1 (SiS_P3d4, 0x3D, CR3D);
-		SiS_SetReg1 (SiS_P3d4, 0x3E, CR3E);
-		SiS_SetReg1 (SiS_P3d4, 0x3F, CR3F);
-		SiS_SetReg1 (SiS_P3d4, 0x79, CR79);
-		SiS_SetReg1 (SiS_P3d4, 0x7A, CR7A);
-		SiS_SetReg1 (SiS_P3d4, 0x7B, CR7B);
-		SiS_SetReg1 (SiS_P3d4, 0x7C, CR7C);
-	} else if ((HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-		   (HwDeviceExtension->jChipType == SIS_740)) {
-		SiS_SetReg1 (SiS_P3c4, 0x12, SR12);
-		SiS_SetReg1 (SiS_P3c4, 0x13, SR13);
-		SiS_SetReg1 (SiS_P3c4, 0x14, SR14);
-		SiS_SetReg1 (SiS_P3c4, 0x16, SR16);
-		SiS_SetReg1 (SiS_P3c4, 0x17, SR17);
-		SiS_SetReg1 (SiS_P3c4, 0x18, SR18);
-		SiS_SetReg1 (SiS_P3c4, 0x19, SR19);
-		SiS_SetReg1 (SiS_P3c4, 0x1A, SR1A);
-	}
-#endif
-
-/* detect ExtChip Type */
-	SiS_Set_LVDS_TRUMPION (HwDeviceExtension);	/*2/29/00 by Mars Wen for LVDS and Trumpion  */
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		temp = (UCHAR) SR1A;
-	} else
-#endif
-	{
-		if ((*pSiS_SoftSetting & SoftDRAMType) == 0) {
-			temp = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x3A);
-		}
-	}
-
-	SiS_RAMType = temp & 0x03;
-	SiS_SetMemoryClock (ROMAddr);
-
-/* SetDefExt1Regs  begin */
-	SiS_SetReg1 (SiS_P3c4, 0x07, *pSiS_SR07);
-	if ((HwDeviceExtension->jChipType != SIS_540) &&
-	    (HwDeviceExtension->jChipType != SIS_630) &&
-	    (HwDeviceExtension->jChipType != SIS_730)) {
-		for (i = 0x15; i < 0x1C; i++) {
-			SiS_SetReg1 (SiS_P3c4, i,
-				     SiS_SR15[i - 0x15][SiS_RAMType]);
-		}
-	}
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO)) {
-		for (i = 0x40; i <= 0x44; i++) {
-			SiS_SetReg1 (SiS_P3d4, i,
-				     SiS_CR40[i - 0x40][SiS_RAMType]);
-		}
-		SiS_SetReg1 (SiS_P3d4, 0x48, 0x23);
-		SiS_SetReg1 (SiS_P3d4, 0x49, SiS_CR49[0]);
-		/* /SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[0]);  */
-	}
-#endif
-
-	SiS_SetReg1 (SiS_P3c4, 0x1F, *pSiS_SR1F);
-	/*SiS_SetReg1(SiS_P3c4,0x20,0x20); */
-	SiS_SetReg1 (SiS_P3c4, 0x20, 0xA0);	/* alan, 2001/6/26 Frame buffer can read/write */
-	SiS_SetReg1 (SiS_P3c4, 0x23, *pSiS_SR23);
-	SiS_SetReg1 (SiS_P3c4, 0x24, *pSiS_SR24);
-	SiS_SetReg1 (SiS_P3c4, 0x25, SiS_SR25[0]);
-#ifdef CONFIG_FB_SIS_300
-	if (HwDeviceExtension->jChipType == SIS_300) {
-		SiS_SetReg1 (SiS_P3c4, 0x21, 0x84);
-		SiS_SetReg1 (SiS_P3c4, 0x22, 0x00);
-	}
-#endif
-	SR11 = 0x0F;
-	SiS_SetReg1 (SiS_P3c4, 0x11, SR11);
-
-	SiS_UnLockCRT2 (HwDeviceExtension, BaseAddr);
-	SiS_SetReg1 (SiS_Part1Port, 0x00, 0x00);
-	SiS_SetReg1 (SiS_Part1Port, 0x02, *pSiS_CRT2Data_1_2);
-#ifdef CONFIG_FB_SIS_315	/* 05/02/01 ynlai  for sis550 */
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740))
-		/* 09/03/01 chiawen for 650 */
-		SiS_SetReg1 (SiS_Part1Port, 0x2E, 0x08);	/* use VB */
-#endif
-
-	temp = *pSiS_SR32;
-	if (SiS_BridgeIsOn (BaseAddr)) {
-		temp = temp & 0xEF;
-	}
-	SiS_SetReg1 (SiS_P3c4, 0x32, temp);
-
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO)) {
-		HwDeviceExtension->pQueryVGAConfigSpace (HwDeviceExtension,
-							 0x50, 0, &Temp);	/* Get */
-
-		Temp >>= 20;
-		Temp &= 0xF;
-		if (Temp != 1) {
-			SiS_SetReg1 (SiS_P3c4, 0x25, SiS_SR25[1]);
-			SiS_SetReg1 (SiS_P3d4, 0x49, SiS_CR49[1]);
-		}
-
-		SiS_SetReg1 (SiS_P3c4, 0x27, 0x1F);
-
-		SiS_SetReg1 (SiS_P3c4, 0x31, *pSiS_SR31);
-		SiS_SetReg1 (SiS_P3c4, 0x32, *pSiS_SR32);
-		SiS_SetReg1 (SiS_P3c4, 0x33, *pSiS_SR33);
-	}
-#endif
-
-	if (SiS_BridgeIsOn (BaseAddr) == 1) {
-		if (SiS_IF_DEF_LVDS == 0) {
-			SiS_SetReg1 (SiS_Part2Port, 0x00, 0x1C);
-			SiS_SetReg1 (SiS_Part4Port, 0x0D, *pSiS_CRT2Data_4_D);
-			SiS_SetReg1 (SiS_Part4Port, 0x0E, *pSiS_CRT2Data_4_E);
-			SiS_SetReg1 (SiS_Part4Port, 0x10, *pSiS_CRT2Data_4_10);
-			SiS_SetReg1 (SiS_Part4Port, 0x0F, 0x3F);
-		}
-		SiS_LockCRT2 (HwDeviceExtension, BaseAddr);
-	}
-	SiS_SetReg1 (SiS_P3d4, 0x83, 0x00);
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)) {
+     SiS_SetReg1(SiS_P3c4,0x12,SR12);
+     SiS_SetReg1(SiS_P3c4,0x13,SR13);
+     SiS_SetReg1(SiS_P3c4,0x14,SR14);
+     SiS_SetReg1(SiS_P3c4,0x16,SR16);
+     SiS_SetReg1(SiS_P3c4,0x17,SR17);
+     SiS_SetReg1(SiS_P3c4,0x18,SR18);
+     SiS_SetReg1(SiS_P3c4,0x19,SR19);
+     SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
+   }
+#endif
+
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_650)) {  /* 09/03/01 chiawen for 650 */
+     SiS_SetReg1(SiS_P3c4,0x13,SR13);
+     SiS_SetReg1(SiS_P3c4,0x14,SR14);
+     SiS_SetReg1(SiS_P3c4,0x15,SR15);
+     SiS_SetReg1(SiS_P3c4,0x16,SR16);
+     SiS_SetReg1(SiS_P3c4,0x17,SR17);
+     SiS_SetReg1(SiS_P3c4,0x19,SR19);
+     SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
+     SiS_SetReg1(SiS_P3c4,0x1B,SR1B);
+     SiS_SetReg1(SiS_P3d4,0x37,CR37);
+     SiS_SetReg1(SiS_P3d4,0x38,CR38);
+     SiS_SetReg1(SiS_P3d4,0x79,CR79);
+     SiS_SetReg1(SiS_P3d4,0x7A,CR7A);
+     SiS_SetReg1(SiS_P3d4,0x7B,CR7B);
+     SiS_SetReg1(SiS_P3d4,0x7C,CR7C);
+   }
+#endif
+
+#ifdef SIS300
+   if((HwDeviceExtension->jChipType==SIS_540)||
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)) {
+     	temp=(UCHAR)SR1A;
+   } else if(HwDeviceExtension->jChipType==SIS_300) {
+        /* TW: Nothing */
+   } else
+#endif
+   {
+      	if((*pSiS_SoftSetting&SoftDRAMType)==0){
+          	temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x3A);
+        }
+   }
+
+   SiS_RAMType=temp&0x03;
+   SiS_SetMemoryClock(ROMAddr);
+
+/* SetDefExt1Regs begin: Set default register contents */
+
+   SiS_SetReg1(SiS_P3c4,0x07,*pSiS_SR07); 		/* DAC speed */
+   if((HwDeviceExtension->jChipType != SIS_540)&&
+      (HwDeviceExtension->jChipType != SIS_630)&&
+      (HwDeviceExtension->jChipType != SIS_730)){
+     	for(i=0x15;i<0x1C;i++) {
+       		SiS_SetReg1(SiS_P3c4,i,SiS_SR15[i-0x15][SiS_RAMType]);
+     	}
+   }
+
+#ifdef SIS315H
+   if ((HwDeviceExtension->jChipType == SIS_315H )||
+       (HwDeviceExtension->jChipType == SIS_315PRO)) {
+     	for(i=0x40;i<=0x44;i++) {
+       		SiS_SetReg1(SiS_P3d4,i,SiS_CR40[i-0x40][SiS_RAMType]);
+     	}
+     	SiS_SetReg1(SiS_P3d4,0x48,0x23);
+     	SiS_SetReg1(SiS_P3d4,0x49,SiS_CR49[0]);
+    	/* /SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[0]);  */
+   }
+#endif
+
+   SiS_SetReg1(SiS_P3c4,0x1F,*pSiS_SR1F); 	/* DAC pedestal */
+   /*SiS_SetReg1(SiS_P3c4,0x20,0x20);*/
+   SiS_SetReg1(SiS_P3c4,0x20,0xA0); /* alan, 2001/6/26 Frame buffer can read/write*/
+   SiS_SetReg1(SiS_P3c4,0x23,*pSiS_SR23);
+   SiS_SetReg1(SiS_P3c4,0x24,*pSiS_SR24);
+   SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[0]);
+
+#ifdef SIS300
+   if(HwDeviceExtension->jChipType==SIS_300) {
+     	SiS_SetReg1(SiS_P3c4,0x21,0x84);
+     	SiS_SetReg1(SiS_P3c4,0x22,0x00);
+   }
+#endif
+
+   SR11=0x0F;
+   SiS_SetReg1(SiS_P3c4,0x11,SR11);	/* Power Management */
+
+   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+   SiS_SetReg1(SiS_Part1Port,0x00,0x00);
+   SiS_SetReg1(SiS_Part1Port,0x02,*pSiS_CRT2Data_1_2);
+
+#ifdef SIS315H                            /* 05/02/01 ynlai  for sis550 */
+   if((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_650))    /* 09/03/01 chiawen for 650 */
+     	SiS_SetReg1(SiS_Part1Port,0x2E,0x08); /* use VB */
+#endif
+
+   temp=*pSiS_SR32;
+   if(!SiS_BridgeIsOn(BaseAddr)) {
+     	temp=temp&0xEF;
+   }
+   SiS_SetReg1(SiS_P3c4,0x32,temp);
+
+#ifdef SIS315H
+   if ((HwDeviceExtension->jChipType == SIS_315H) ||
+       (HwDeviceExtension->jChipType == SIS_315PRO)) {
+     HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,0x50,0,&Temp);  /* Get */
+     Temp >>= 20;
+     Temp &= 0xF;
+     if (Temp!=1) {
+     	SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[1]);
+     	SiS_SetReg1(SiS_P3d4,0x49,SiS_CR49[1]);
+     }
+
+     SiS_SetReg1(SiS_P3c4,0x27,0x1F);
+
+     SiS_SetReg1(SiS_P3c4,0x31,*pSiS_SR31);
+     SiS_SetReg1(SiS_P3c4,0x32,*pSiS_SR32);
+     SiS_SetReg1(SiS_P3c4,0x33,*pSiS_SR33);
+   }
+#endif
+
+   if (SiS_BridgeIsOn(BaseAddr)==1) {
+     	if(SiS_IF_DEF_LVDS==0) {
+       		SiS_SetReg1(SiS_Part2Port,0x00,0x1C);
+       		SiS_SetReg1(SiS_Part4Port,0x0D,*pSiS_CRT2Data_4_D);
+       		SiS_SetReg1(SiS_Part4Port,0x0E,*pSiS_CRT2Data_4_E);
+       		SiS_SetReg1(SiS_Part4Port,0x10,*pSiS_CRT2Data_4_10);
+       		SiS_SetReg1(SiS_Part4Port,0x0F,0x3F);
+     	}
+     	SiS_LockCRT2(HwDeviceExtension, BaseAddr);
+   }
+   SiS_SetReg1(SiS_P3d4,0x83,0x00);
 /*   SetDefExt1Regs end */
 
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO)
-	    ) {			/* 05/02/01 ynlai */
-		/* For SiS 300,310 Chip  */
-		if (HwDeviceExtension->bSkipDramSizing == TRUE) {
-			SiS_SetDRAMModeRegister (ROMAddr);
-			pSR = HwDeviceExtension->pSR;
-			if (pSR != NULL) {
-				while (pSR->jIdx != 0xFF) {
-					SiS_SetReg1 (SiS_P3c4, pSR->jIdx,
-						     pSR->jVal);
-					pSR++;
-				}
-			}
-		} else
-			SiS_SetDRAMSize_310 (HwDeviceExtension);
-	}
-#endif
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_550)) {	/* 05/02/01 ynlai For SiS 550 */
-		/* SetDRAMConfig begin */
+#ifdef SIS315H
+   if ((HwDeviceExtension->jChipType==SIS_315H)||
+       (HwDeviceExtension->jChipType==SIS_315PRO)) { /* 05/02/01 ynlai */
+       	if (HwDeviceExtension->bSkipDramSizing==TRUE) {
+         	SiS_SetDRAMModeRegister(ROMAddr);
+         	pSR = HwDeviceExtension->pSR;
+         	if (pSR!=NULL) {
+           		while (pSR->jIdx!=0xFF) {
+             			SiS_SetReg1(SiS_P3c4,pSR->jIdx,pSR->jVal);
+             			pSR++;
+           		}
+         	}
+       } else SiS_SetDRAMSize_310(HwDeviceExtension);
+   }
+#endif
+
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType==SIS_550)){ /* 05/02/01 ynlai For SiS 550 */
+       /* SetDRAMConfig begin */
 /*     SiS_SetReg1(SiS_P3c4,0x12,SR12);
        SiS_SetReg1(SiS_P3c4,0x13,SR13);
        SiS_SetReg1(SiS_P3c4,0x14,SR14);
@@ -812,2973 +859,3156 @@
        SiS_SetReg1(SiS_P3c4,0x18,SR18);
        SiS_SetReg1(SiS_P3c4,0x19,SR19);
        SiS_SetReg1(SiS_P3c4,0x1A,SR1A);   */
-		/* SetDRAMConfig end */
-	}
+       /* SetDRAMConfig end */
+   }
 #endif
-#ifdef CONFIG_FB_SIS_300
-	if (HwDeviceExtension->jChipType == SIS_300) {	/* For SiS 300 Chip  */
-		if (HwDeviceExtension->bSkipDramSizing == TRUE) {
-/*       SiS_SetDRAMModeRegister(ROMAddr);
-         temp = (HwDeviceExtension->pSR)->jVal;
-         SiS_SetReg1(SiS_P3c4,0x13,temp);
-         temp = (HwDeviceExtension->pSR)->jVal;
-         SiS_SetReg1(SiS_P3c4,0x14,temp);   */
-		} else {
+
+#ifdef SIS300
+   if( HwDeviceExtension->jChipType==SIS_300) {       /* For SiS 300 Chip  */
+       	if (HwDeviceExtension->bSkipDramSizing==TRUE) {
+/*       	SiS_SetDRAMModeRegister(ROMAddr);
+         	temp = (HwDeviceExtension->pSR)->jVal;
+         	SiS_SetReg1(SiS_P3c4,0x13,temp);
+         	temp = (HwDeviceExtension->pSR)->jVal;
+         	SiS_SetReg1(SiS_P3c4,0x14,temp);   */
+       } else {
 #ifdef TC
-			SiS_SetReg1 (SiS_P3c4, 0x13, SR13);
-			SiS_SetReg1 (SiS_P3c4, 0x14, SR14);
-			SiS_SetRegANDOR (SiS_P3c4, 0x15, 0xFF, 0x04);
+         	SiS_SetReg1(SiS_P3c4,0x13,SR13);
+         	SiS_SetReg1(SiS_P3c4,0x14,SR14);
+         	SiS_SetRegANDOR(SiS_P3c4,0x15,0xFF,0x04);
 #else
-			SiS_SetDRAMSize_300 (HwDeviceExtension);
-			SiS_SetDRAMSize_300 (HwDeviceExtension);
+         	SiS_SetDRAMSize_300(HwDeviceExtension);
+         	SiS_SetDRAMSize_300(HwDeviceExtension);
 #endif
-		}
-	}
-	if ((HwDeviceExtension->jChipType == SIS_540) ||	/* For SiS 630/540/730 Chip  */
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		/* SetDRAMConfig begin */
-/*     SiS_SetReg1(SiS_P3c4,0x12,SR12);
-       SiS_SetReg1(SiS_P3c4,0x13,SR13);
-       SiS_SetReg1(SiS_P3c4,0x14,SR14);
-       SiS_SetReg1(SiS_P3c4,0x16,SR16);
-       SiS_SetReg1(SiS_P3c4,0x17,SR17);
-       SiS_SetReg1(SiS_P3c4,0x18,SR18);
-       SiS_SetReg1(SiS_P3c4,0x19,SR19);
-       SiS_SetReg1(SiS_P3c4,0x1A,SR1A);    */
-		/* SetDRAMConfig end */
-	}
-/* SetDRAMSize end */
+       }
+   }
+   if((HwDeviceExtension->jChipType==SIS_540)||       /* For SiS 630/540/730 Chip  */
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)){
+       	/* SetDRAMConfig begin */
+#if 0
+     	SiS_SetReg1(SiS_P3c4,0x12,SR12);
+       	SiS_SetReg1(SiS_P3c4,0x13,SR13);
+       	SiS_SetReg1(SiS_P3c4,0x14,SR14);
+       	SiS_SetReg1(SiS_P3c4,0x16,SR16);
+       	SiS_SetReg1(SiS_P3c4,0x17,SR17);
+       	SiS_SetReg1(SiS_P3c4,0x18,SR18);
+       	SiS_SetReg1(SiS_P3c4,0x19,SR19);
+       	SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
 #endif
+       	/* SetDRAMConfig end */
+   }
+/* SetDRAMSize end */
+#endif /* SIS300 */
 
 /*   SetDefExt2Regs begin  */
-/* AGP=1;
+#if 0
+   AGP=1;
    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x3A);
    temp=temp&0x30;
    if(temp==0x30) AGP=0;
    if(AGP==0) *pSiS_SR21=*pSiS_SR21&0xEF;
    SiS_SetReg1(SiS_P3c4,0x21,*pSiS_SR21);
    if(AGP==1) *pSiS_SR22=*pSiS_SR22&0x20;
-   SiS_SetReg1(SiS_P3c4,0x22,*pSiS_SR22);  */
-
-	SiS_SetReg1 (SiS_P3c4, 0x21, *pSiS_SR21);
-	SiS_SetReg1 (SiS_P3c4, 0x22, *pSiS_SR22);
+   SiS_SetReg1(SiS_P3c4,0x22,*pSiS_SR22);
+#endif
+   SiS_SetReg1(SiS_P3c4,0x21,*pSiS_SR21);
+   SiS_SetReg1(SiS_P3c4,0x22,*pSiS_SR22);
 /*   SetDefExt2Regs end  */
 
-/* SiS_SetReg3(SiS_P3c6,0xff);
-   SiS_ClearDAC(SiS_P3c8);        [ynlai] 05/22/01            */
+#if 0
+   SiS_SetReg3(SiS_P3c6,0xff);
+   SiS_ClearDAC(SiS_P3c8);        /* [ynlai] 05/22/01 */
+#endif
 
-	SiS_DetectMonitor (HwDeviceExtension, BaseAddr);
-	SiS_GetSenseStatus (HwDeviceExtension, ROMAddr);	/* sense CRT2 */
+   SiS_DetectMonitor(HwDeviceExtension,BaseAddr);
+   SiS_GetSenseStatus(HwDeviceExtension,ROMAddr);      /* sense CRT2 */
 
-	return (TRUE);
+   return(TRUE);
 }
 
 void
-SiS_Set_LVDS_TRUMPION (PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT temp;
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		temp = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x1A);
-		temp = (temp & 0xE0) >> 4;
-		SiS_SetRegANDOR (SiS_P3d4, 0x37, 0xF1, temp);
-		temp = temp >> 1;
-		if ((temp == 0) || (temp == 1)) {	/* for 301 */
-			SiS_IF_DEF_LVDS = 0;
-			SiS_IF_DEF_CH7005 = 0;
-			SiS_IF_DEF_TRUMPION = 0;
-		}
-		if ((temp >= 2) && (temp <= 5)) {
-			SiS_IF_DEF_LVDS = 1;
-		}
-		if (temp == 3)
-			SiS_IF_DEF_TRUMPION = 1;
-		if ((temp == 4) || (temp == 5))
-			SiS_IF_DEF_CH7005 = 1;
-	} else {
-		SiS_IF_DEF_LVDS = 0;
-		SiS_IF_DEF_TRUMPION = 0;
-		SiS_IF_DEF_CH7005 = 0;
-	}
-#else
-	if ((HwDeviceExtension->jChipType == SIS_550) ||
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740))
-	 {			/* 09/03/01 chiawen for 650 */
-		SiS_IF_DEF_LVDS = 0;
-		SiS_IF_DEF_TRUMPION = 0;
-		SiS_IF_DEF_CH7005 = 0;
-	}
+SiS_Set_LVDS_TRUMPION(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT temp=0;
+
+#ifdef SiS300
+  if ((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)) {
+        /* TW: Read POWER_ON_TRAP and copy to CR37 */
+    	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+    	temp=(temp&0xE0)>>4;
+   	SiS_SetRegANDOR(SiS_P3d4,0x37,0xF1,temp);
+   }
 #endif
+
+   /* Set globals SiS_IF_DEF... */
+   SiSSetLVDSetc(HwDeviceExtension, 0);
 }
 
 /* ===============  for 300 dram sizing begin  =============== */
-#ifdef CONFIG_FB_SIS_300
+#ifdef SIS300
 void
-SiS_SetDRAMSize_300 (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetDRAMSize_300(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	/*ULONG   ROMAddr  = (ULONG)HwDeviceExtension->pjVirtualRomBase; */
-	ULONG FBAddr = (ULONG) HwDeviceExtension->pjVideoMemoryAddress;
-	/*USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; */
-	USHORT SR13, SR14 = 0, buswidth, Done;
-	SHORT i, j, k;
-	USHORT data, TotalCapacity, PhysicalAdrOtherPage = 0;
-	ULONG Addr;
-	UCHAR temp;
-
-	int PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
-	int RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
-	/*int PageCapacity,PhysicalAdrHigh,PhysicalAdrHalfPage,PhysicalAdrAnotherPage; */
-	int PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage;
-
-	SiSSetMode (HwDeviceExtension, 0x2e);
-	data = SiS_GetReg1 (SiS_P3c4, 0x1);
-	data = data | 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x01, data);	/* Turn OFF Display  */
-
-	SiS_SetReg1 (SiS_P3c4, 0x13, 0x00);
-	SiS_SetReg1 (SiS_P3c4, 0x14, 0xBF);
-	buswidth = SiS_ChkBUSWidth_300 (FBAddr);
-
-	MB2Bank = 16;
-	Done = 0;
-	for (i = 6; i >= 0; i--) {
-		if (Done == 1)
-			break;
-		PseudoRankCapacity = 1 << i;
-		for (j = 4; j >= 1; j--) {
-			if (Done == 1)
-				break;
-			PseudoTotalCapacity = PseudoRankCapacity * j;
-			PseudoAdrPinCount = 15 - j;
-			if (PseudoTotalCapacity <= 64) {
-				for (k = 0; k <= 16; k++) {
-					if (Done == 1)
-						break;
-					RankCapacity =
-					    buswidth * SiS_DRAMType[k][3];
-					AdrPinCount =
-					    SiS_DRAMType[k][2] +
-					    SiS_DRAMType[k][0];
-					if (RankCapacity == PseudoRankCapacity)
-						if (AdrPinCount <=
-						    PseudoAdrPinCount) {
-							if (j == 3) {	/* Rank No */
-								BankNumHigh =
-								    RankCapacity
-								    * MB2Bank *
-								    3 - 1;
-								BankNumMid =
-								    RankCapacity
-								    * MB2Bank *
-								    1 - 1;
-							} else {
-								BankNumHigh =
-								    RankCapacity
-								    * MB2Bank *
-								    j - 1;
-								BankNumMid =
-								    RankCapacity
-								    * MB2Bank *
-								    j / 2 - 1;
-							}
-							PageCapacity =
-							    (1 <<
-							     SiS_DRAMType[k][1])
-							    * buswidth * 4;
-							PhysicalAdrHigh =
-							    BankNumHigh;
-							PhysicalAdrHalfPage =
-							    (PageCapacity / 2 +
-							     PhysicalAdrHigh) %
-							    PageCapacity;
-							PhysicalAdrOtherPage =
-							    PageCapacity *
-							    SiS_DRAMType[k][2] +
-							    PhysicalAdrHigh;
-							/* Write data */
-							/*Test */
-							temp =
-							    (UCHAR)
-							    SiS_GetReg1
-							    (SiS_P3c4, 0x15);
-							SiS_SetReg1 (SiS_P3c4,
-								     0x15,
-								     (USHORT)
-								     (temp &
-								      0xFB));
-
-							temp =
-							    (UCHAR)
-							    SiS_GetReg1
-							    (SiS_P3c4, 0x15);
-							SiS_SetReg1 (SiS_P3c4,
-								     0x15,
-								     (USHORT)
-								     (temp |
-								      0x04));
-							/*Test */
-							TotalCapacity =
-							    SiS_DRAMType[k][3] *
-							    buswidth;
-							SR13 =
-							    SiS_DRAMType[k][4];
-							if (buswidth == 4)
-								SR14 =
-								    (TotalCapacity
-								     -
-								     1) | 0x80;
-							if (buswidth == 2)
-								SR14 =
-								    (TotalCapacity
-								     -
-								     1) | 0x40;
-							if (buswidth == 1)
-								SR14 =
-								    (TotalCapacity
-								     -
-								     1) | 0x00;
-							SiS_SetReg1 (SiS_P3c4,
-								     0x13,
-								     SR13);
-							SiS_SetReg1 (SiS_P3c4,
-								     0x14,
-								     SR14);
-
-							Addr =
-							    FBAddr +
-							    (BankNumHigh) * 64 *
-							    1024 +
-							    PhysicalAdrHigh;
-							*((USHORT *) (Addr)) =
-							    (USHORT)
-							    PhysicalAdrHigh;
-							Addr =
-							    FBAddr +
-							    (BankNumMid) * 64 *
-							    1024 +
-							    PhysicalAdrHigh;
-							*((USHORT *) (Addr)) =
-							    (USHORT) BankNumMid;
-							Addr =
-							    FBAddr +
-							    (BankNumHigh) * 64 *
-							    1024 +
-							    PhysicalAdrHalfPage;
-							*((USHORT *) (Addr)) =
-							    (USHORT)
-							    PhysicalAdrHalfPage;
-							Addr =
-							    FBAddr +
-							    (BankNumHigh) * 64 *
-							    1024 +
-							    PhysicalAdrOtherPage;
-							*((USHORT *) (Addr)) =
-							    PhysicalAdrOtherPage;
-
-							/* Read data */
-							Addr =
-							    FBAddr +
-							    (BankNumHigh) * 64 *
-							    1024 +
-							    PhysicalAdrHigh;
-							data =
-							    *((USHORT *)
-							      (Addr));
-							if (data ==
-							    PhysicalAdrHigh)
-								    Done = 1;
-						}	/* if struct */
-				}	/* for loop (k) */
-			}	/* if struct */
-		}		/* for loop (j) */
-	}			/* for loop (i) */
+   /*ULONG   ROMAddr  = (ULONG)HwDeviceExtension->pjVirtualRomBase;*/
+   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+   /*USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;*/
+   USHORT  SR13,SR14=0,buswidth,Done;
+   SHORT   i,j,k;
+   USHORT  data, TotalCapacity, PhysicalAdrOtherPage=0;
+   ULONG   Addr;
+   UCHAR   temp;
+
+   int PseudoRankCapacity,PseudoTotalCapacity,PseudoAdrPinCount;
+   int RankCapacity,AdrPinCount,BankNumHigh,BankNumMid,MB2Bank;
+   /*int PageCapacity,PhysicalAdrHigh,PhysicalAdrHalfPage,PhysicalAdrAnotherPage;*/
+   int PageCapacity,PhysicalAdrHigh,PhysicalAdrHalfPage;
+
+   SiSSetMode(HwDeviceExtension,0x2e);
+
+   data=SiS_GetReg1(SiS_P3c4,0x1);
+   data=data|0x20;
+   SiS_SetReg1(SiS_P3c4,0x01,data);                    /* Turn OFF Display  */
+
+   SiS_SetReg1(SiS_P3c4,0x13,0x00);
+   SiS_SetReg1(SiS_P3c4,0x14,0xBF);
+   buswidth=SiS_ChkBUSWidth_300(FBAddr);
+
+   MB2Bank=16;
+   Done=0;
+   for(i=6;i>=0;i--) {
+      if(Done==1) break;
+      PseudoRankCapacity=1<<i;
+      for(j=4;j>=1;j--) {
+         if(Done==1) break;
+         PseudoTotalCapacity=PseudoRankCapacity*j;
+         PseudoAdrPinCount=15-j;
+         if(PseudoTotalCapacity <= 64) {
+            for(k=0;k<=16;k++) {
+               if(Done==1) break;
+               RankCapacity=buswidth*SiS_DRAMType[k][3];
+               AdrPinCount=SiS_DRAMType[k][2]+SiS_DRAMType[k][0];
+               if(RankCapacity==PseudoRankCapacity)
+                 if(AdrPinCount<=PseudoAdrPinCount) {
+                    if(j==3) {             /* Rank No */
+                       BankNumHigh=RankCapacity*MB2Bank*3-1;
+                       BankNumMid=RankCapacity*MB2Bank*1-1;
+                    }
+                    else {
+                       BankNumHigh=RankCapacity*MB2Bank*j-1;
+                       BankNumMid=RankCapacity*MB2Bank*j/2-1;
+                    }
+                    PageCapacity=(1<<SiS_DRAMType[k][1])*buswidth*4;
+                    PhysicalAdrHigh =BankNumHigh;
+                    PhysicalAdrHalfPage=(PageCapacity/2+PhysicalAdrHigh)%PageCapacity;
+                    PhysicalAdrOtherPage=PageCapacity*SiS_DRAMType[k][2]+PhysicalAdrHigh;
+                    /* Write data */
+                    /*Test */
+                    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
+                    SiS_SetReg1(SiS_P3c4,0x15,(USHORT)(temp&0xFB));
+
+                    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
+                    SiS_SetReg1(SiS_P3c4,0x15,(USHORT)(temp|0x04));
+                    /*Test */
+                    TotalCapacity=SiS_DRAMType[k][3]*buswidth;
+                    SR13=SiS_DRAMType[k][4];
+                    if(buswidth==4) SR14=(TotalCapacity-1)|0x80;
+                    if(buswidth==2) SR14=(TotalCapacity-1)|0x40;
+                    if(buswidth==1) SR14=(TotalCapacity-1)|0x00;
+                    SiS_SetReg1(SiS_P3c4,0x13,SR13);
+                    SiS_SetReg1(SiS_P3c4,0x14,SR14);
+
+                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHigh;
+                    *((USHORT *)(Addr)) = (USHORT) PhysicalAdrHigh;
+                    Addr=FBAddr+(BankNumMid)*64*1024+PhysicalAdrHigh;
+                    *((USHORT *)(Addr)) = (USHORT) BankNumMid;
+                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHalfPage;
+                    *((USHORT *)(Addr)) = (USHORT) PhysicalAdrHalfPage;
+                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrOtherPage;
+                    *((USHORT *)(Addr))=PhysicalAdrOtherPage;
+
+                    /* Read data */
+                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHigh;
+                    data=*((USHORT *)(Addr));
+                    if(data==PhysicalAdrHigh) Done=1;
+                 }  /* if struct */
+            }  /* for loop (k) */
+         }  /* if struct */
+      }  /* for loop (j) */
+   }  /* for loop (i) */
 }
 
 USHORT
-SiS_ChkBUSWidth_300 (ULONG FBAddress)
+SiS_ChkBUSWidth_300(ULONG FBAddress)
 {
-	/*USHORT  data; */
-	PULONG pVideoMemory;
+   /*USHORT  data;*/
+   PULONG  pVideoMemory;
 
-	pVideoMemory = (PULONG) FBAddress;
+   pVideoMemory = (PULONG) FBAddress;
 
-	pVideoMemory[0] = 0x01234567L;
-	pVideoMemory[1] = 0x456789ABL;
-	pVideoMemory[2] = 0x89ABCDEFL;
-	pVideoMemory[3] = 0xCDEF0123L;
-	if (pVideoMemory[3] == 0xCDEF0123L) {	/*ChannelA128Bit */
-		return (4);
-	}
-	if (pVideoMemory[1] == 0x456789ABL) {	/*ChannelB64Bit */
-		return (2);
-	}
-	return (1);
+   pVideoMemory[0] = 0x01234567L;
+   pVideoMemory[1] = 0x456789ABL;
+   pVideoMemory[2] = 0x89ABCDEFL;
+   pVideoMemory[3] = 0xCDEF0123L;
+   if (pVideoMemory[3]==0xCDEF0123L) { /*ChannelA128Bit */
+     return(4);
+   }
+   if (pVideoMemory[1]==0x456789ABL) {  /*ChannelB64Bit */
+     return(2);
+   }
+   return(1);
 }
 #endif
 
 /* ===============  for 300 dram sizing end    =============== */
 
-/* ============== alan ====================== */
-#ifdef CONFIG_FB_SIS_315
-UCHAR
-SiS_Get310DRAMType (ULONG ROMAddr)
-{
-	UCHAR data;
+/* ===============  310 dram sizing begin ==================== */
+#ifdef SIS315H
 
-	/* 
-	   index=SiS_GetReg1(SiS_P3c4,0x1A);
-	   index=index&07;
-	 */
-	if (*pSiS_SoftSetting & SoftDRAMType)
-		data = *pSiS_SoftSetting & 0x03;
-	else
-		data = SiS_GetReg1 (SiS_P3c4, 0x3a) & 0x03;
+/* TW: Moved Get310DRAMType further down */
 
-	return data;
+void
+SiS_Delay15us(ULONG ulMicrsoSec)
+{
 }
 
 void
-SiS_Delay15us (ULONG ulMicrsoSec)
+SiS_SDR_MRS(void)
+{
+   USHORT  data;
+
+   data=SiS_GetReg1(SiS_P3c4,0x16);
+   data=data & 0x3F;          /*/ SR16 D7=0,D6=0 */
+   SiS_SetReg1(SiS_P3c4,0x16,data);   /*/ enable mode register set(MRS) low */
+   SiS_Delay15us(0x100);
+   data=data | 0x80;          /*/ SR16 D7=1,D6=0 */
+   SiS_SetReg1(SiS_P3c4,0x16,data);   /*/ enable mode register set(MRS) high */
+   SiS_Delay15us(0x100);
+}
+
+void
+SiS_DDR_MRS(void)
+{
+   USHORT  data;
+
+   /* SR16 <- 1F,DF,2F,AF */
+
+   /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
+   data=SiS_GetReg1(SiS_P3c4,0x16);
+   data &= 0x0F;
+   data |= 0x10;
+   SiS_SetReg1(SiS_P3c4,0x16,data);
+
+   if (!(SiS_SR15[1][SiS_RAMType] & 0x10))
+   {
+     data &= 0x0F;
+   }
+   /* SR16 D7=1,D6=1 */
+   data |= 0xC0;
+   SiS_SetReg1(SiS_P3c4,0x16,data);
+   
+   /* SR16 D7=1,D6=0,D5=1,D4=0 */
+   data &= 0x0F;
+   data |= 0x20;
+   SiS_SetReg1(SiS_P3c4,0x16,data);
+   if (!(SiS_SR15[1][SiS_RAMType] & 0x10)) {
+     data &= 0x0F;
+   }
+   /* SR16 D7=1 */
+   data |= 0x80;
+   SiS_SetReg1(SiS_P3c4,0x16,data);
+}
+
+void
+SiS_SetDRAMModeRegister(ULONG ROMAddr)
+{
+
+    if (SiS_Get310DRAMType(ROMAddr)<2) {
+      SiS_SDR_MRS();
+    } else {
+      /* SR16 <- 0F,CF,0F,8F */
+      SiS_DDR_MRS();
+    }
+}
+
+void
+SiS_DisableRefresh(void)
+{
+   USHORT  data;
+
+   data=SiS_GetReg1(SiS_P3c4,0x17);
+   data &= 0xF8;
+   SiS_SetReg1(SiS_P3c4,0x17,data);
+
+   data=SiS_GetReg1(SiS_P3c4,0x19);
+   data |= 0x03;
+   SiS_SetReg1(SiS_P3c4,0x19,data);
+
+}
+
+void
+SiS_EnableRefresh(ULONG ROMAddr)
+{
+   SiS_SetReg1(SiS_P3c4,0x17,SiS_SR15[2][SiS_RAMType]);  /* SR17 */
+   SiS_SetReg1(SiS_P3c4,0x19,SiS_SR15[4][SiS_RAMType]);  /* SR19 */
+}
+
+void
+SiS_DisableChannelInterleaving(int index,USHORT SiS_DDRDRAM_TYPE[][5])
+{
+   USHORT  data;
+
+   data=SiS_GetReg1(SiS_P3c4,0x15);
+   data &= 0x1F;
+   switch (SiS_DDRDRAM_TYPE[index][3])
+   {
+     case 64: data |= 0;
+              break;
+     case 32: data |= 0x20;
+              break;
+     case 16: data |= 0x40;
+              break;
+     case 4:  data |= 0x60;
+              break;
+   }
+   SiS_SetReg1(SiS_P3c4,0x15,data);
+}
+
+void
+SiS_SetDRAMSizingType(int index,USHORT DRAMTYPE_TABLE[][5])
+{
+   USHORT  data;
+
+   data = DRAMTYPE_TABLE[index][4];
+   SiS_SetReg1(SiS_P3c4,0x13,data);
+
+   /* should delay 50 ns */
+}
+
+void
+SiS_CheckBusWidth_310(ULONG ROMAddress,ULONG FBAddress)
+{
+   USHORT  data;
+   PULONG volatile pVideoMemory;
+
+   pVideoMemory = (PULONG) FBAddress;
+   if (SiS_Get310DRAMType(ROMAddress)<2) {
+
+     SiS_SetReg1(SiS_P3c4,0x13,0x00);
+     SiS_SetReg1(SiS_P3c4,0x14,0x12);
+     /* should delay */
+     SiS_SDR_MRS();
+
+     SiS_ChannelAB = 0;
+     SiS_DataBusWidth = 128;
+     pVideoMemory[0] = 0x01234567L;
+     pVideoMemory[1] = 0x456789ABL;
+     pVideoMemory[2] = 0x89ABCDEFL;
+     pVideoMemory[3] = 0xCDEF0123L;
+     pVideoMemory[4] = 0x55555555L;
+     pVideoMemory[5] = 0x55555555L;
+     pVideoMemory[6] = 0xFFFFFFFFL;
+     pVideoMemory[7] = 0xFFFFFFFFL;
+     if ((pVideoMemory[3]!=0xCDEF0123L) || (pVideoMemory[2] != 0x89ABCDEFL)) {
+       /*ChannelA64Bit */
+       SiS_DataBusWidth = 64;
+       SiS_ChannelAB = 0;
+       data=SiS_GetReg1(SiS_P3c4,0x14);
+       SiS_SetReg1(SiS_P3c4,  0x14, (USHORT) (data & 0xFD));
+     }
+
+     if ((pVideoMemory[1]!=0x456789ABL) || (pVideoMemory[0] != 0x01234567L)) {
+       /*ChannelB64Bit */
+       SiS_DataBusWidth = 64;
+       SiS_ChannelAB = 1;
+       data=SiS_GetReg1(SiS_P3c4,0x14);
+       SiS_SetReg1(SiS_P3c4,0x14,(USHORT)((data&0xFD)|0x01));
+     }
+     return;
+
+   } else {
+     /* DDR Dual channel */
+     SiS_SetReg1(SiS_P3c4,0x13,0x00);
+     SiS_SetReg1(SiS_P3c4,0x14,0x02); /* Channel A, 64bit */
+     /* should delay */
+     SiS_DDR_MRS();
+
+     SiS_ChannelAB = 0;
+     SiS_DataBusWidth = 64;
+     pVideoMemory[0] = 0x01234567L;
+     pVideoMemory[1] = 0x456789ABL;
+     pVideoMemory[2] = 0x89ABCDEFL;
+     pVideoMemory[3] = 0xCDEF0123L;
+     pVideoMemory[4] = 0x55555555L;
+     pVideoMemory[5] = 0x55555555L;
+     pVideoMemory[6] = 0xAAAAAAAAL;
+     pVideoMemory[7] = 0xAAAAAAAAL;
+
+     if (pVideoMemory[1] == 0x456789ABL) {
+       if (pVideoMemory[0] == 0x01234567L) {
+         /* Channel A 64bit */
+         return;
+       }
+     } else {
+       if (pVideoMemory[0] == 0x01234567L) {
+         /* Channel A 32bit */
+         SiS_DataBusWidth = 32;
+         SiS_SetReg1(SiS_P3c4,0x14,0x00);
+         return;
+       }
+     }
+
+     SiS_SetReg1(SiS_P3c4,0x14,0x03); /* Channel B, 64bit */
+     SiS_DDR_MRS();
+
+     SiS_ChannelAB = 1;
+     SiS_DataBusWidth = 64;
+     pVideoMemory[0] = 0x01234567L;
+     pVideoMemory[1] = 0x456789ABL;
+     pVideoMemory[2] = 0x89ABCDEFL;
+     pVideoMemory[3] = 0xCDEF0123L;
+     pVideoMemory[4] = 0x55555555L;
+     pVideoMemory[5] = 0x55555555L;
+     pVideoMemory[6] = 0xAAAAAAAAL;
+     pVideoMemory[7] = 0xAAAAAAAAL;
+     if (pVideoMemory[1] == 0x456789ABL) {
+       /* Channel B 64 */
+       if (pVideoMemory[0] == 0x01234567L) {
+         /* Channel B 64bit */
+         return;
+       } else {
+         /* error */
+       }
+     } else {
+       if (pVideoMemory[0] == 0x01234567L) {
+         /* Channel B 32 */
+         SiS_DataBusWidth = 32;
+         SiS_SetReg1(SiS_P3c4,0x14,0x01);
+       } else {
+         /* error */
+       }
+     }
+   }
+}
+
+int
+SiS_SetRank(int index,UCHAR RankNo,UCHAR SiS_ChannelAB,USHORT DRAMTYPE_TABLE[][5])
 {
+  USHORT  data;
+  int RankSize;
+
+  if ((RankNo==2)&&(DRAMTYPE_TABLE[index][0]==2))
+         return 0;
+
+  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_DataBusWidth/32;
+
+  if (RankNo*RankSize<=128) {
+    data = 0;
+    while ((RankSize>>=1)>0) {
+      data+=0x10;
+    }
+    data |= (RankNo-1)<<2;
+    data |= (SiS_DataBusWidth/64)&2;
+    data |= SiS_ChannelAB;
+    SiS_SetReg1(SiS_P3c4,0x14,data);
+    /* should delay */
+    SiS_SDR_MRS();
+    return 1;
+  } else
+    return 0;
 }
 
-void
-SiS_SDR_MRS (void)
+int
+SiS_SetDDRChannel(int index,UCHAR ChannelNo,UCHAR SiS_ChannelAB,
+                  USHORT DRAMTYPE_TABLE[][5])
 {
-	USHORT data;
+  USHORT  data;
+  int RankSize;
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x16);
-	data = data & 0x3F;	/*/ SR16 D7=0,D6=0 */
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);	/*/ enable mode register set(MRS) low */
-	SiS_Delay15us (0x100);
-	data = data | 0x80;	/*/ SR16 D7=1,D6=0 */
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);	/*/ enable mode register set(MRS) high */
-	SiS_Delay15us (0x100);
+  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_DataBusWidth/32;
+  /* RankSize = DRAMTYPE_TABLE[index][3]; */
+  if (ChannelNo*RankSize<=128) {
+    data = 0;
+    while ((RankSize>>=1)>0) {
+      data+=0x10;
+    }
+    if (ChannelNo==2)
+      data |= 0x0C;
+
+    data |= (SiS_DataBusWidth/32)&2;
+    data |= SiS_ChannelAB;
+    SiS_SetReg1(SiS_P3c4,0x14,data);
+    /* should delay */
+    SiS_DDR_MRS();
+    return 1;
+  } else
+    return 0;
 }
 
-void
-SiS_DDR_MRS (void)
+int
+SiS_CheckColumn(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
-	USHORT data;
+  int i;
+  ULONG Increment,Position;
 
-	/* SR16 <- 1F,DF,2F,AF */
+  /*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 1); */
+  Increment = 1<<(10 + SiS_DataBusWidth / 64);
 
-	/* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
-	data = SiS_GetReg1 (SiS_P3c4, 0x16);
-	data &= 0x0F;
-	data |= 0x10;
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);
+  for (i=0,Position=0;i<2;i++) {
+         *((PULONG)(FBAddress+Position))=Position;
+         Position += Increment;
+  }
 
-	if (!(SiS_SR15[1][SiS_RAMType] & 0x10)) {
-		data &= 0x0F;
-	}
-	/* SR16 D7=1,D6=1 */
-	data |= 0xC0;
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);
+  for (i=0,Position=0;i<2;i++) {
+/*    if (FBAddress[Position]!=Position) */
+         if ( (*(PULONG) (FBAddress + Position)) !=Position)
+                return 0;
+         Position += Increment;
+  }
+  return 1;
+}
 
-	/* SR16 D7=1,D6=0,D5=1,D4=0 */
-	data &= 0x0F;
-	data |= 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);
-	if (!(SiS_SR15[1][SiS_RAMType] & 0x10)) {
-		data &= 0x0F;
-	}
-	/* SR16 D7=1 */
-	data |= 0x80;
-	SiS_SetReg1 (SiS_P3c4, 0x16, data);
+int
+SiS_CheckBanks(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+{
+  int i;
+  ULONG Increment,Position;
+  Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 2);
+
+  for (i=0,Position=0;i<4;i++) {
+/*    FBAddress[Position]=Position; */
+    *((PULONG)(FBAddress+Position))=Position;
+    Position += Increment;
+  }
+
+  for (i=0,Position=0;i<4;i++) {
+/*    if (FBAddress[Position]!=Position) */
+    if ( (*(PULONG) (FBAddress + Position)) !=Position)
+      return 0;
+    Position += Increment;
+  }
+  return 1;
 }
 
-void
-SiS_SetDRAMModeRegister (ULONG ROMAddr)
+int
+SiS_CheckRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
+  int i;
+  ULONG Increment,Position;
+  Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
+                  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 + RankNo);
 
-	if (SiS_Get310DRAMType (ROMAddr) < 2) {
-		SiS_SDR_MRS ();
-	} else {
-		/* SR16 <- 0F,CF,0F,8F */
-		SiS_DDR_MRS ();
-	}
+  for (i=0,Position=0;i<2;i++) {
+/*    FBAddress[Position]=Position; */
+    *((PULONG)(FBAddress+Position))=Position;
+    /* *((PULONG)(FBAddress))=Position; */
+    Position += Increment;
+  }
+
+  for (i=0,Position=0;i<2;i++) {
+/*    if (FBAddress[Position]!=Position) */
+         if ( (*(PULONG) (FBAddress + Position)) !=Position)
+    /*if ( (*(PULONG) (FBAddress )) !=Position) */
+      return 0;
+    Position += Increment;
+  }
+  return 1;
 }
 
-void
-SiS_DisableRefresh (void)
+int
+SiS_CheckDDRRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
-	USHORT data;
+  ULONG Increment,Position;
+  USHORT  data;
+  
+  Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
+                  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 + RankNo);
+
+  Increment += Increment/2;
+  
+  Position =0;
+  *((PULONG)(FBAddress+Position+0))=0x01234567;
+  *((PULONG)(FBAddress+Position+1))=0x456789AB;
+  *((PULONG)(FBAddress+Position+2))=0x55555555;
+  *((PULONG)(FBAddress+Position+3))=0x55555555;
+  *((PULONG)(FBAddress+Position+4))=0xAAAAAAAA;
+  *((PULONG)(FBAddress+Position+5))=0xAAAAAAAA;
+
+  if ( (*(PULONG) (FBAddress + 1))==0x456789AB)
+    return 1;
+
+  if ( (*(PULONG) (FBAddress + 0))==0x01234567)
+    return 0;
+
+  data=SiS_GetReg1(SiS_P3c4,0x14);
+  data &= 0xF3;
+  data |= 0x08;
+  SiS_SetReg1(SiS_P3c4,0x14,data);
+  data=SiS_GetReg1(SiS_P3c4,0x15);
+  data += 0x20;
+  SiS_SetReg1(SiS_P3c4,0x15,data);
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x17);
-	data &= 0xF8;
-	SiS_SetReg1 (SiS_P3c4, 0x17, data);
+  return 1;
+}
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x19);
-	data |= 0x03;
-	SiS_SetReg1 (SiS_P3c4, 0x19, data);
+int
+SiS_CheckRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+{
+  int r;
 
+  for (r=RankNo;r>=1;r--) {
+    if (!SiS_CheckRank(r,index,DRAMTYPE_TABLE,FBAddress))
+      return 0;
+  }
+  if (!SiS_CheckBanks(index,DRAMTYPE_TABLE,FBAddress))
+    return 0;
+
+  if (!SiS_CheckColumn(index,DRAMTYPE_TABLE,FBAddress))
+    return 0;
+  return 1;
 }
 
-void
-SiS_EnableRefresh (ULONG ROMAddr)
+int
+SiS_CheckDDRRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
+  int r;
 
-	SiS_SetReg1 (SiS_P3c4, 0x17, SiS_SR15[2][SiS_RAMType]);	/* SR17 */
+  for (r=RankNo;r>=1;r--) {
+    if (!SiS_CheckDDRRank(r,index,DRAMTYPE_TABLE,FBAddress))
+      return 0;
+  }
+  if (!SiS_CheckBanks(index,DRAMTYPE_TABLE,FBAddress))
+    return 0;
+
+  if (!SiS_CheckColumn(index,DRAMTYPE_TABLE,FBAddress))
+    return 0;
+  return 1;
+}
 
-	SiS_SetReg1 (SiS_P3c4, 0x19, SiS_SR15[4][SiS_RAMType]);	/* SR19 */
+int
+SiS_SDRSizing(ULONG FBAddress)
+{
+  int    i;
+  UCHAR  j;
 
+  for (i=0;i<13;i++) {
+    SiS_SetDRAMSizingType(i, SiS_SDRDRAM_TYPE);
+    for (j=2;j>0;j--) {
+      if (!SiS_SetRank(i,(UCHAR) j, SiS_ChannelAB,SiS_SDRDRAM_TYPE))
+        continue;
+      else {
+        if (SiS_CheckRanks(j,i,SiS_SDRDRAM_TYPE, FBAddress))
+          return 1;
+      }
+    }
+  }
+  return 0;
 }
 
-void
-SiS_DisableChannelInterleaving (int index, USHORT SiS_DDRDRAM_TYPE[][5])
+int
+SiS_DDRSizing(ULONG FBAddress)
 {
-	USHORT data;
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x15);
-	data &= 0x1F;
-	switch (SiS_DDRDRAM_TYPE[index][3]) {
-	case 64:
-		data |= 0;
-		break;
-	case 32:
-		data |= 0x20;
-		break;
-	case 16:
-		data |= 0x40;
-		break;
-	case 4:
-		data |= 0x60;
-		break;
-	}
-	SiS_SetReg1 (SiS_P3c4, 0x15, data);
+  int    i;
+  UCHAR  j;
 
+  for (i=0;i<4;i++){
+    SiS_SetDRAMSizingType(i,SiS_DDRDRAM_TYPE);
+    SiS_DisableChannelInterleaving(i,SiS_DDRDRAM_TYPE);
+    for (j=2;j>0;j--) {
+      SiS_SetDDRChannel(i, j, SiS_ChannelAB, SiS_DDRDRAM_TYPE);
+      if (!SiS_SetRank(i,(UCHAR) j, SiS_ChannelAB,SiS_DDRDRAM_TYPE))
+        continue;
+      else {
+        if (SiS_CheckDDRRanks(j,i,SiS_DDRDRAM_TYPE, FBAddress))
+          return 1;
+      }
+    }
+  }
+  return 0;
 }
 
+/*
+ check if read cache pointer is correct
+*/
 void
-SiS_SetDRAMSizingType (int index, USHORT DRAMTYPE_TABLE[][5])
+SiS_VerifyMclk(ULONG FBAddr)
 {
-	USHORT data;
-
-	data = DRAMTYPE_TABLE[index][4];
-	SiS_SetReg1 (SiS_P3c4, 0x13, data);
-
-	/* should delay 50 ns */
+   PUCHAR  pVideoMemory = (PUCHAR) FBAddr;
+   UCHAR i,j;
+   USHORT Temp,SR21;
+
+
+   pVideoMemory[0]=0xaa; /* alan */
+   pVideoMemory[16]=0x55; /* note: PCI read cache is off */
+
+   if ((pVideoMemory[0]!=0xaa)||(pVideoMemory[16]!=0x55)) {
+     for (i=0,j=16;i<2;i++,j+=16)  {
+       SR21 = SiS_GetReg1(SiS_P3c4, 0x21);
+       Temp = SR21 & 0xFB;     /* disable PCI post write buffer empty gating */
+       SiS_SetReg1(SiS_P3c4, 0x21, Temp);
+
+       Temp = SiS_GetReg1(SiS_P3c4, 0x3C);
+       Temp = Temp | 0x01;                 /*MCLK reset */
+       SiS_SetReg1(SiS_P3c4, 0x3C, Temp);
+       Temp = SiS_GetReg1(SiS_P3c4, 0x3C);
+       Temp = Temp & 0xFE;                 /* MCLK normal operation */
+       SiS_SetReg1(SiS_P3c4, 0x3C, Temp);
+       SiS_SetReg1(SiS_P3c4, 0x21, SR21);
+
+       pVideoMemory[16+j] = j;
+       if (pVideoMemory[16+j]==j)  {
+         pVideoMemory[j] = j;
+         break;
+       }
+     }
+   }
+}
 
+/* TW: Is this a 315E? */
+int
+Is315E(void)
+{
+   USHORT  data;
+  	
+   data=SiS_GetReg1(SiS_P3d4,0x5F);
+   if (data&0x10) return 1;
+   else return 0;
 }
 
+/* TW: For 315 only */
 void
-SiS_CheckBusWidth_310 (ULONG ROMAddress, ULONG FBAddress)
+SiS_SetDRAMSize_310(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT data;
-	PULONG volatile pVideoMemory;
-
-	pVideoMemory = (PULONG) FBAddress;
-	if (SiS_Get310DRAMType (ROMAddress) < 2) {
+   ULONG   ROMAddr  = (ULONG)HwDeviceExtension->pjVirtualRomBase;
+   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+   /*USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;*/
+   USHORT  data;
 
-		SiS_SetReg1 (SiS_P3c4, 0x13, 0x00);
-		SiS_SetReg1 (SiS_P3c4, 0x14, 0x12);
-		/* should delay */
-		SiS_SDR_MRS ();
+#ifdef SIS301	/* TW: SIS301 ??? */
+   /*SiS_SetReg1(SiS_P3d4,0x30,0x40);   */
+#endif
+#ifdef SIS302   /* TW: SIS302 ??? */
+   SiS_SetReg1(SiS_P3d4,0x30,0x4D);  /* alan,should change value */
+   SiS_SetReg1(SiS_P3d4,0x31,0xc0);  /* alan,should change value */
+   SiS_SetReg1(SiS_P3d4,0x34,0x3F);  /* alan,should change value */
+#endif
 
-		SiS_ChannelAB = 0;
-		SiS_DataBusWidth = 128;
-		pVideoMemory[0] = 0x01234567L;
-		pVideoMemory[1] = 0x456789ABL;
-		pVideoMemory[2] = 0x89ABCDEFL;
-		pVideoMemory[3] = 0xCDEF0123L;
-		pVideoMemory[4] = 0x55555555L;
-		pVideoMemory[5] = 0x55555555L;
-		pVideoMemory[6] = 0xFFFFFFFFL;
-		pVideoMemory[7] = 0xFFFFFFFFL;
-		if ((pVideoMemory[3] != 0xCDEF0123L)
-		    || (pVideoMemory[2] != 0x89ABCDEFL)) {
-			/*ChannelA64Bit */
-			SiS_DataBusWidth = 64;
-			SiS_ChannelAB = 0;
-			data = SiS_GetReg1 (SiS_P3c4, 0x14);
-			SiS_SetReg1 (SiS_P3c4, 0x14, (USHORT) (data & 0xFD));
-		}
+   SiSSetMode(HwDeviceExtension,0x2e);
 
-		if ((pVideoMemory[1] != 0x456789ABL)
-		    || (pVideoMemory[0] != 0x01234567L)) {
-			/*ChannelB64Bit */
-			SiS_DataBusWidth = 64;
-			SiS_ChannelAB = 1;
-			data = SiS_GetReg1 (SiS_P3c4, 0x14);
-			SiS_SetReg1 (SiS_P3c4, 0x14,
-				     (USHORT) ((data & 0xFD) | 0x01));
-		}
-		return;
+   data=SiS_GetReg1(SiS_P3c4,0x21);
+   SiS_SetReg1(SiS_P3c4,0x21,(USHORT) (data&0xDF));      /* disable read cache */
 
-	} else {
-		/* DDR Dual channel */
-		SiS_SetReg1 (SiS_P3c4, 0x13, 0x00);
-		SiS_SetReg1 (SiS_P3c4, 0x14, 0x02);	/* Channel A, 64bit */
-		/* should delay */
-		SiS_DDR_MRS ();
+   data=SiS_GetReg1(SiS_P3c4,0x1);
+   data=data|0x20;
+   SiS_SetReg1(SiS_P3c4,0x01,data);                    /* Turn OFF Display */
 
-		SiS_ChannelAB = 0;
-		SiS_DataBusWidth = 64;
-		pVideoMemory[0] = 0x01234567L;
-		pVideoMemory[1] = 0x456789ABL;
-		pVideoMemory[2] = 0x89ABCDEFL;
-		pVideoMemory[3] = 0xCDEF0123L;
-		pVideoMemory[4] = 0x55555555L;
-		pVideoMemory[5] = 0x55555555L;
-		pVideoMemory[6] = 0xAAAAAAAAL;
-		pVideoMemory[7] = 0xAAAAAAAAL;
+   data=SiS_GetReg1(SiS_P3c4,0x16);
+   SiS_SetReg1(SiS_P3c4,0x16,(USHORT) (data|0x0F));      /* assume lowest speed DRAM */
 
-		if (pVideoMemory[1] == 0x456789ABL) {
-			if (pVideoMemory[0] == 0x01234567L) {
-				/* Channel A 64bit */
-				return;
-			}
-		} else {
-			if (pVideoMemory[0] == 0x01234567L) {
-				/* Channel A 32bit */
-				SiS_DataBusWidth = 32;
-				SiS_SetReg1 (SiS_P3c4, 0x14, 0x00);
-				return;
-			}
+   SiS_SetDRAMModeRegister(ROMAddr);
+   SiS_DisableRefresh();
+   SiS_CheckBusWidth_310(ROMAddr,FBAddr);
 
-		}
+   SiS_VerifyMclk(FBAddr); /* alan 2000/7/3 */
 
-		SiS_SetReg1 (SiS_P3c4, 0x14, 0x03);	/* Channel B, 64bit */
-		SiS_DDR_MRS ();
+   if (SiS_Get310DRAMType(ROMAddr)<2) {
+     SiS_SDRSizing(FBAddr);
+   } else {
+     SiS_DDRSizing(FBAddr);
+   }
+   
+   if (Is315E()) {
+     data=SiS_GetReg1(SiS_P3c4,0x14);
+     if ((data&0x0C)==0x0C) /* dual channel */
+     {
+     	if ((data&0xF0)>0x40)
+     	  data = (data & 0x0F) | 0x40;
+     } else { /* single channel */
+     	if ((data&0xF0)>0x50)
+     	  data = (data & 0x0F) | 0x50;
+     }
+   }
+   
+   SiS_SetReg1(SiS_P3c4,0x16,SiS_SR15[1][SiS_RAMType]);  /* restore SR16 */
 
-		SiS_ChannelAB = 1;
-		SiS_DataBusWidth = 64;
-		pVideoMemory[0] = 0x01234567L;
-		pVideoMemory[1] = 0x456789ABL;
-		pVideoMemory[2] = 0x89ABCDEFL;
-		pVideoMemory[3] = 0xCDEF0123L;
-		pVideoMemory[4] = 0x55555555L;
-		pVideoMemory[5] = 0x55555555L;
-		pVideoMemory[6] = 0xAAAAAAAAL;
-		pVideoMemory[7] = 0xAAAAAAAAL;
-		if (pVideoMemory[1] == 0x456789ABL) {
-			/* Channel B 64 */
-			if (pVideoMemory[0] == 0x01234567L) {
-				/* Channel B 64bit */
-				return;
-			} else {
-				/* error */
-			}
-		} else {
-			if (pVideoMemory[0] == 0x01234567L) {
-				/* Channel B 32 */
-				SiS_DataBusWidth = 32;
-				SiS_SetReg1 (SiS_P3c4, 0x14, 0x01);
-			} else {
-				/* error */
-			}
-		}
-	}
+   SiS_EnableRefresh(ROMAddr);
+   data=SiS_GetReg1(SiS_P3c4,0x21);
+   SiS_SetReg1(SiS_P3c4,0x21,(USHORT) (data|0x20));      /* enable read cache */
 }
+#endif
 
-int
-SiS_SetRank (int index, UCHAR RankNo, UCHAR SiS_ChannelAB,
-	     USHORT DRAMTYPE_TABLE[][5])
+void
+SiS_SetMemoryClock(ULONG ROMAddr)
 {
-	USHORT data;
-	int RankSize;
-
-	if ((RankNo == 2) && (DRAMTYPE_TABLE[index][0] == 2))
-		return 0;
-
-	RankSize = DRAMTYPE_TABLE[index][3] / 2 * SiS_DataBusWidth / 32;
-
-	if (RankNo * RankSize <= 128) {
-		data = 0;
-		while ((RankSize >>= 1) > 0) {
-			data += 0x10;
-		}
-		data |= (RankNo - 1) << 2;
-		data |= (SiS_DataBusWidth / 64) & 2;
-		data |= SiS_ChannelAB;
-		SiS_SetReg1 (SiS_P3c4, 0x14, data);
-		/* should delay */
-		SiS_SDR_MRS ();
-		return 1;
-	} else
-		return 0;
+   SiS_SetReg1(SiS_P3c4,0x28,SiS_MCLKData[SiS_RAMType].SR28);
+   SiS_SetReg1(SiS_P3c4,0x29,SiS_MCLKData[SiS_RAMType].SR29);
+   SiS_SetReg1(SiS_P3c4,0x2A,SiS_MCLKData[SiS_RAMType].SR2A);
+   SiS_SetReg1(SiS_P3c4,0x2E,SiS_ECLKData[SiS_RAMType].SR2E);
+   SiS_SetReg1(SiS_P3c4,0x2F,SiS_ECLKData[SiS_RAMType].SR2F);
+   SiS_SetReg1(SiS_P3c4,0x30,SiS_ECLKData[SiS_RAMType].SR30);
 
+#ifdef SIS315H
+   if (Is315E()) {
+     SiS_SetReg1(SiS_P3c4,0x28,0x3B); /* 143 */
+     SiS_SetReg1(SiS_P3c4,0x29,0x22);
+     SiS_SetReg1(SiS_P3c4,0x2E,0x3B); /* 143 */
+     SiS_SetReg1(SiS_P3c4,0x2F,0x22);
+   }
+#endif
 }
 
-int
-SiS_SetDDRChannel (int index, UCHAR ChannelNo, UCHAR SiS_ChannelAB,
-		   USHORT DRAMTYPE_TABLE[][5])
-{
-	USHORT data;
-	int RankSize;
+#endif /* ifndef LINUX_XF86 */
 
-	RankSize = DRAMTYPE_TABLE[index][3] / 2 * SiS_DataBusWidth / 32;
-	/* RankSize = DRAMTYPE_TABLE[index][3]; */
-	if (ChannelNo * RankSize <= 128) {
-		data = 0;
-		while ((RankSize >>= 1) > 0) {
-			data += 0x10;
-		}
-		if (ChannelNo == 2)
-			data |= 0x0C;
-
-		data |= (SiS_DataBusWidth / 32) & 2;
-		data |= SiS_ChannelAB;
-		SiS_SetReg1 (SiS_P3c4, 0x14, data);
-		/* should delay */
-		SiS_DDR_MRS ();
-		return 1;
-	} else
-		return 0;
+#ifdef SIS315H
+UCHAR
+SiS_Get310DRAMType(ULONG   ROMAddr)
+{
+   UCHAR   data;
 
+   /*
+   index=SiS_GetReg1(SiS_P3c4,0x1A);
+   index=index&07;
+   */
+   if (*pSiS_SoftSetting&SoftDRAMType)
+     data = *pSiS_SoftSetting & 0x03;
+   else
+     data=SiS_GetReg1(SiS_P3c4,0x3a) & 0x03;
+
+   return data;
+}
+#endif
+
+/* SiSInit END */
+
+/* ----------------------------------------- */
+
+void SiSRegInit(USHORT BaseAddr)
+{
+   SiS_P3c4=BaseAddr+0x14;
+   SiS_P3d4=BaseAddr+0x24;
+   SiS_P3c0=BaseAddr+0x10;
+   SiS_P3ce=BaseAddr+0x1e;
+   SiS_P3c2=BaseAddr+0x12;
+   SiS_P3ca=BaseAddr+0x1a;
+   SiS_P3c6=BaseAddr+0x16;
+   SiS_P3c7=BaseAddr+0x17;
+   SiS_P3c8=BaseAddr+0x18;
+   SiS_P3c9=BaseAddr+0x19;
+   SiS_P3da=BaseAddr+0x2A;
+   SiS_Part1Port=BaseAddr+SIS_CRT2_PORT_04;
+   SiS_Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+   SiS_Part3Port=BaseAddr+SIS_CRT2_PORT_12;
+   SiS_Part4Port=BaseAddr+SIS_CRT2_PORT_14;
+   SiS_Part5Port=BaseAddr+SIS_CRT2_PORT_14+2;
+   SiS_DDC_Port=BaseAddr+0x14;  /* 0x3c4; */
+}
+
+void
+SiSInitPCIetc(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+#ifdef LINUX_XF86
+   if ((HwDeviceExtension->jChipType == SIS_540)||
+       (HwDeviceExtension->jChipType == SIS_630)||
+       (HwDeviceExtension->jChipType == SIS_730)||
+       (HwDeviceExtension->jChipType == SIS_300)) {
+       /* TW: Set - PCI LINEAR ADDRESSING ENABLE (0x80)
+		  - PCI IO ENABLE  (0x20)
+		  - MMIO ENABLE (0x1)
+  	*/
+       SiS_SetReg1(SiS_P3c4,0x20,0xa1);
+       /* TW: Enable 2D (0x42) & 3D accelerator (0x18) */
+       SiS_SetReg1(SiS_P3c4,0x1E,0x5A);
+   }
+   if((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315PRO)||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||
+      (HwDeviceExtension->jChipType == SIS_740)||
+      (HwDeviceExtension->jChipType == SIS_650)) {
+      /* TW: This seems to be done the same way on these chipsets */
+      SiS_SetReg1(SiS_P3c4,0x20,0xa1);
+      SiS_SetReg1(SiS_P3c4,0x1E,0x5A);
+   }
+#endif
+}
+
+void
+SiSSetLVDSetc(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+{
+   ULONG   temp;
+
+   SiS_IF_DEF_LVDS=0;
+   SiS_IF_DEF_CH7005=0;
+   SiS_IF_DEF_HiVision=0;
+   SiS_IF_DEF_DSTN=0;
+   SiS_IF_DEF_FSTN=0;
+   if((ModeNo==0x5a)||(ModeNo==0x5b)) {
+   	SiS_IF_DEF_DSTN=1;   /* for 550 dstn */
+   	SiS_IF_DEF_FSTN=1;   /* for fstn */
+   }
+   if((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_650))    /* 09/03/01 chiawen for 650 */
+    {
+      	if (SiS_IF_DEF_FSTN) {                               /*fstn setCR37=0x04;*/
+        	SiS_SetReg1(SiS_P3d4,0x37,0x04);
+      	}
+      	temp=SiS_GetReg1(SiS_P3d4,0x37);
+      	temp=(temp&0x0E)>>1;
+      	if((temp==0)||(temp==1)) {   /* for 301 */
+        	SiS_IF_DEF_LVDS=0;
+        	SiS_IF_DEF_CH7005=0;
+        	SiS_IF_DEF_TRUMPION=0;
+      	}
+      	if((temp>=2)&&(temp<=5)) SiS_IF_DEF_LVDS=1;
+      	if(temp==3) SiS_IF_DEF_TRUMPION=1;
+      	if((temp==4)||(temp==5)) {
+		/* TW: Save power status */
+		SiS_Backup7005 = SiS_GetCH7005(0x0e);
+		SiS_IF_DEF_CH7005=1;
+        }
+   }
+}
+
+void
+SiSInitPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+#ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_315H)||  /* 05/02/01 ynlai for sis550 */
+      (HwDeviceExtension->jChipType == SIS_315PRO)||
+      (HwDeviceExtension->jChipType == SIS_550)||
+      (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+      (HwDeviceExtension->jChipType == SIS_650))    /* 09/03/01 chiawen for 650 */
+     InitTo310Pointer();
+#endif
+
+#ifdef SIS300
+   if ((HwDeviceExtension->jChipType == SIS_540)||
+       (HwDeviceExtension->jChipType == SIS_630)||
+       (HwDeviceExtension->jChipType == SIS_730)||
+       (HwDeviceExtension->jChipType == SIS_300))
+     InitTo300Pointer();
+#endif
 }
 
-int
-SiS_CheckColumn (int index, USHORT DRAMTYPE_TABLE[][5], ULONG FBAddress)
+/*
+ 	=========================================
+ 	======== SiS SetMode Function  ==========
+ 	=========================================
+*/
+#ifdef LINUX_XF86
+/* TW: This is used for non-Dual-Head mode from X */
+BOOLEAN
+SiSBIOSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+               DisplayModePtr mode)
 {
-	int i;
-	ULONG Increment, Position;
+   UShort  ModeNo=0;
 
-	/*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 1); */
-	Increment = 1 << (10 + SiS_DataBusWidth / 64);
+   ModeNo = SiS_CalcModeIndex(pScrn, mode);
+   if (!ModeNo) return FALSE;
 
-	for (i = 0, Position = 0; i < 2; i++) {
-		*((PULONG) (FBAddress + Position)) = Position;
-		Position += Increment;
-	}
+   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x\n", ModeNo);
 
-	for (i = 0, Position = 0; i < 2; i++) {
-/*    if (FBAddress[Position]!=Position) */
-		if ((*(PULONG) (FBAddress + Position)) != Position)
-			return 0;
-		Position += Increment;
-	}
-	return 1;
+   return(SiSSetMode(HwDeviceExtension, pScrn, ModeNo));
 }
 
-int
-SiS_CheckBanks (int index, USHORT DRAMTYPE_TABLE[][5], ULONG FBAddress)
+#ifdef SISDUALHEAD
+/* TW: Set CRT1 mode (used for dual head) */
+BOOLEAN
+SiSBIOSSetModeCRT1(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+               DisplayModePtr mode)
 {
-	int i;
-	ULONG Increment, Position;
-	Increment = 1 << (DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 2);
+   ULONG   temp;
+   USHORT  ModeIdIndex,KeepLockReg;
+   ULONG   ROMAddr  = (ULONG)HwDeviceExtension->pjVirtualRomBase;
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+   SISPtr  pSiS = SISPTR(pScrn);
+   SISEntPtr pSiSEnt = pSiS->entityPrivate;
 
-	for (i = 0, Position = 0; i < 4; i++) {
-/*    FBAddress[Position]=Position; */
-		*((PULONG) (FBAddress + Position)) = Position;
-		Position += Increment;
-	}
+   UShort  ModeNo=0;
 
-	for (i = 0, Position = 0; i < 4; i++) {
-/*    if (FBAddress[Position]!=Position) */
-		if ((*(PULONG) (FBAddress + Position)) != Position)
-			return 0;
-		Position += Increment;
-	}
-	return 1;
-}
+   ModeNo = SiS_CalcModeIndex(pScrn, mode);
+   if (!ModeNo) return FALSE;
 
-int
-SiS_CheckRank (int RankNo, int index, USHORT DRAMTYPE_TABLE[][5],
-	       ULONG FBAddress)
-{
-	int i;
-	ULONG Increment, Position;
-	Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
-			  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 +
-			  RankNo);
+   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x on CRT1\n", ModeNo);
 
-	for (i = 0, Position = 0; i < 2; i++) {
-/*    FBAddress[Position]=Position; */
-		*((PULONG) (FBAddress + Position)) = Position;
-		/* *((PULONG)(FBAddress))=Position; */
-		Position += Increment;
-	}
+   SiSInitPtr(HwDeviceExtension);
 
-	for (i = 0, Position = 0; i < 2; i++) {
-/*    if (FBAddress[Position]!=Position) */
-		if ((*(PULONG) (FBAddress + Position)) != Position)
-			/*if ( (*(PULONG) (FBAddress )) !=Position) */
-			return 0;
-		Position += Increment;
-	}
-	return 1;
+   SiSRegInit(BaseAddr);
 
-}
+   SiSInitPCIetc(HwDeviceExtension);
 
-int
-SiS_CheckDDRRank (int RankNo, int index, USHORT DRAMTYPE_TABLE[][5],
-		  ULONG FBAddress)
-{
-	ULONG Increment, Position;
-	USHORT data;
+   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
 
-	Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
-			  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 +
-			  RankNo);
-
-	Increment += Increment / 2;
-
-	Position = 0;
-	*((PULONG) (FBAddress + Position + 0)) = 0x01234567;
-	*((PULONG) (FBAddress + Position + 1)) = 0x456789AB;
-	*((PULONG) (FBAddress + Position + 2)) = 0x55555555;
-	*((PULONG) (FBAddress + Position + 3)) = 0x55555555;
-	*((PULONG) (FBAddress + Position + 4)) = 0xAAAAAAAA;
-	*((PULONG) (FBAddress + Position + 5)) = 0xAAAAAAAA;
-
-	if ((*(PULONG) (FBAddress + 1)) == 0x456789AB)
-		return 1;
-
-	if ((*(PULONG) (FBAddress + 0)) == 0x01234567)
-		return 0;
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x14);
-	data &= 0xF3;
-	data |= 0x08;
-	SiS_SetReg1 (SiS_P3c4, 0x14, data);
-	data = SiS_GetReg1 (SiS_P3c4, 0x15);
-	data += 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x15, data);
+   /* TW: We don't clear the buffer under X */
+   flag_clearbuffer=0;
 
-	return 1;
+   /* SiS_PresetScratchregister(SiS_P3d4,HwDeviceExtension);  */      		/* add for CRT2  */
+   KeepLockReg = SiS_GetReg1(SiS_P3c4,0x05);
+   SiS_SetReg1(SiS_P3c4,0x05,0x86);                             		/* 1.Openkey */
 
-}
+   temp = SiS_SearchModeID(ROMAddr,ModeNo,&ModeIdIndex);        		/* 2.Get ModeID Table  */
+   if(temp==0)  return(0);
 
-int
-SiS_CheckRanks (int RankNo, int index, USHORT DRAMTYPE_TABLE[][5],
-		ULONG FBAddress)
-{
-	int r;
+   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+   SiS_GetVBType(BaseAddr);
 
-	for (r = RankNo; r >= 1; r--) {
-		if (!SiS_CheckRank (r, index, DRAMTYPE_TABLE, FBAddress))
-			return 0;
-	}
-	if (!SiS_CheckBanks (index, DRAMTYPE_TABLE, FBAddress))
-		return 0;
-
-	if (!SiS_CheckColumn (index, DRAMTYPE_TABLE, FBAddress))
-		return 0;
-	return 1;
+   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);   	/*add for CRT2 */
+   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex);   		/*add for CRT2 */
 
-}
+   SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
 
-int
-SiS_CheckDDRRanks (int RankNo, int index, USHORT DRAMTYPE_TABLE[][5],
-		   ULONG FBAddress)
-{
-	int r;
+   pSiSEnt->CRT1ModeNo = ModeNo;
+   pSiSEnt->CRT1DMode = mode;
+
+   /* TW: SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT1(pScrn, BaseAddr);
+
+   /* We have to reset CRT2 if changing mode on CRT1 */
+   if (pSiSEnt->CRT2ModeNo != -1) {
+        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(Re-)Setting mode 0x%x on CRT2\n",
+				pSiSEnt->CRT2ModeNo);
+	SiSBIOSSetModeCRT2(HwDeviceExtension, pSiSEnt->pScrn_1,
+				pSiSEnt->CRT2DMode);
+   }
+
+   /* Backup/Set ModeNo in MMIO */
+   /* SiS_GetSetModeID(pScrn,ModeNo); */
 
-	for (r = RankNo; r >= 1; r--) {
-		if (!SiS_CheckDDRRank (r, index, DRAMTYPE_TABLE, FBAddress))
-			return 0;
-	}
-	if (!SiS_CheckBanks (index, DRAMTYPE_TABLE, FBAddress))
-		return 0;
-
-	if (!SiS_CheckColumn (index, DRAMTYPE_TABLE, FBAddress))
-		return 0;
-	return 1;
+   if(KeepLockReg==0xA1) SiS_SetReg1(SiS_P3c4,0x05,0x86); /* 05/02/01 ynlai */
+   else SiS_SetReg1(SiS_P3c4,0x05,0x00);
 
+   return TRUE;
 }
 
-int
-SiS_SDRSizing (ULONG FBAddress)
+/* TW: Set CRT2 mode (used for dual head) */
+BOOLEAN
+SiSBIOSSetModeCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+               DisplayModePtr mode)
 {
-	int i;
-	UCHAR j;
+   ULONG   temp;
+   USHORT  ModeIdIndex,KeepLockReg;
+   ULONG   ROMAddr  = (ULONG)HwDeviceExtension->pjVirtualRomBase;
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+   UShort  ModeNo=0;
+   SISPtr  pSiS = SISPTR(pScrn);
+   SISEntPtr pSiSEnt = pSiS->entityPrivate;
+
+   ModeNo = SiS_CalcModeIndex(pScrn, mode);
+   if (!ModeNo) return FALSE;
+
+   SiSInitPtr(HwDeviceExtension);
+
+   SiSRegInit(BaseAddr);
+
+   SiSInitPCIetc(HwDeviceExtension);
+
+   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
+
+   /* TW: We don't clear the buffer under X */
+   flag_clearbuffer=0;
+
+   /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
+   pSiSEnt->CRT2ModeNo = ModeNo;
+   pSiSEnt->CRT2DMode = mode;
+
+   /* TW: We can't set CRT2 mode before CRT1 mode is set */
+   if (pSiSEnt->CRT1ModeNo == -1) {
+   	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
+   	return TRUE;
+   }
+
+   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x on CRT2\n", ModeNo);
+
+   /* SiS_PresetScratchregister(SiS_P3d4,HwDeviceExtension);      */  		/* add for CRT2  */
+   KeepLockReg = SiS_GetReg1(SiS_P3c4,0x05);
+   SiS_SetReg1(SiS_P3c4,0x05,0x86);                             		/* 1.Openkey */
+
+   temp = SiS_SearchModeID(ROMAddr,ModeNo,&ModeIdIndex);        		/* 2.Get ModeID Table  */
+   if(temp==0)  return(0);
+
+   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+   SiS_GetVBType(BaseAddr);
+
+   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);   	/*add for CRT2 */
+   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex);   		/*add for CRT2 */
+
+   switch (HwDeviceExtension->ujVBChipID) {
+     case VB_CHIP_301:
+     case VB_CHIP_301B:    /*for Linux & WinCE to open*/
+        SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);         /*add for CRT2 */
+        break;
+     case VB_CHIP_302:
+        SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        break;
+     case VB_CHIP_303:
+/*      SetCRT2Group302(BaseAddr,ROMAddr,ModeNo, HwDeviceExtension);            add for CRT2   */
+        break;
+     case VB_CHIP_UNKNOWN:                                                                                                 /*add for lvds ch7005*/
+        temp=SiS_GetReg1(SiS_P3d4,0x37);
+        if(temp&(ExtChipLVDS|ExtChipTrumpion|ExtChipCH7005)){
+             	SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        }
+        break;
+   }
+
+   /* TW: SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT2(pScrn, BaseAddr);
+
+   /* Backup/Set ModeNo in MMIO */
+   /* SiS_GetSetModeID(pScrn,ModeNo); */
+
+   if(KeepLockReg==0xA1) SiS_SetReg1(SiS_P3c4,0x05,0x86); /* 05/02/01 ynlai */
+   else SiS_SetReg1(SiS_P3c4,0x05,0x00);
 
-	for (i = 0; i < 13; i++) {
-		SiS_SetDRAMSizingType (i, SiS_SDRDRAM_TYPE);
-		for (j = 2; j > 0; j--) {
-
-			if (!SiS_SetRank
-			    (i, (UCHAR) j, SiS_ChannelAB,
-			     SiS_SDRDRAM_TYPE)) continue;
-			else {
-				if (SiS_CheckRanks
-				    (j, i, SiS_SDRDRAM_TYPE,
-				     FBAddress)) return 1;
-			}
-		}
-	}
-	return 0;
+   return TRUE;
 }
+#endif /* Dualhead */
+#endif /* Linux_XF86 */
 
-int
-SiS_DDRSizing (ULONG FBAddress)
+#ifdef LINUX_XF86
+/* TW: We need pScrn for setting the pitch correctly */
+BOOLEAN
+SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,ScrnInfoPtr pScrn,USHORT ModeNo)
+#else
+BOOLEAN
+SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+#endif
 {
+   ULONG   temp;
+   USHORT  ModeIdIndex,KeepLockReg;
+   ULONG   ROMAddr  = (ULONG)HwDeviceExtension->pjVirtualRomBase;
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
 
-	int i;
-	UCHAR j;
+   SiSInitPtr(HwDeviceExtension);
 
-	for (i = 0; i < 4; i++) {
-		SiS_SetDRAMSizingType (i, SiS_DDRDRAM_TYPE);
-		SiS_DisableChannelInterleaving (i, SiS_DDRDRAM_TYPE);
-		for (j = 2; j > 0; j--) {
-			SiS_SetDDRChannel (i, j, SiS_ChannelAB,
-					   SiS_DDRDRAM_TYPE);
-			if (!SiS_SetRank
-			    (i, (UCHAR) j, SiS_ChannelAB,
-			     SiS_DDRDRAM_TYPE)) continue;
-			else {
-				if (SiS_CheckDDRRanks
-				    (j, i, SiS_DDRDRAM_TYPE,
-				     FBAddress)) return 1;
-			}
-		}
-	}
-	return 0;
-}
+   SiSRegInit(BaseAddr);
 
-/*
+   SiSInitPCIetc(HwDeviceExtension);
 
- check if read cache pointer is correct
+   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
 
-*/
-void
-SiS_VerifyMclk (ULONG FBAddr)
-{
-	PUCHAR pVideoMemory = (PUCHAR) FBAddr;
-	UCHAR i, j;
-	USHORT Temp, SR21;
-
-	pVideoMemory[0] = 0xaa;	/* alan */
-	pVideoMemory[16] = 0x55;	/* note: PCI read cache is off */
-
-	if ((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) {
-		for (i = 0, j = 16; i < 2; i++, j += 16) {
-			SR21 = SiS_GetReg1 (SiS_P3c4, 0x21);
-			Temp = SR21 & 0xFB;	/* disable PCI post write buffer empty gating */
-			SiS_SetReg1 (SiS_P3c4, 0x21, Temp);
-
-			Temp = SiS_GetReg1 (SiS_P3c4, 0x3C);
-			Temp = Temp | 0x01;	/*MCLK reset */
-			SiS_SetReg1 (SiS_P3c4, 0x3C, Temp);
-			Temp = SiS_GetReg1 (SiS_P3c4, 0x3C);
-			Temp = Temp & 0xFE;	/* MCLK normal operation */
-			SiS_SetReg1 (SiS_P3c4, 0x3C, Temp);
-			SiS_SetReg1 (SiS_P3c4, 0x21, SR21);
-
-			pVideoMemory[16 + j] = j;
-			if (pVideoMemory[16 + j] == j) {
-				pVideoMemory[j] = j;
-				break;
-			}
-		}
-	}
+#ifdef LINUX_XF86
+   /* TW: We don't clear the buffer under X */
+   ModeNo |= 0x80;
+#endif
 
-}
+   if(ModeNo&0x80) {
+     	ModeNo=ModeNo&0x7F;
+     	flag_clearbuffer=0;
+   } else {
+     	flag_clearbuffer=1;
+   }
 
-int
-Is315E (void)
-{
-	USHORT data;
+   SiS_PresetScratchregister(SiS_P3d4,HwDeviceExtension);       		/* add for CRT2  */
+   KeepLockReg = SiS_GetReg1(SiS_P3c4,0x05);
+   SiS_SetReg1(SiS_P3c4,0x05,0x86);                             		/* 1.Openkey */
 
-	data = SiS_GetReg1 (SiS_P3d4, 0x5F);
-	if (data & 0x10)
-		return 1;
-	else
-		return 0;
-}
+   temp = SiS_SearchModeID(ROMAddr,ModeNo,&ModeIdIndex);        		/* 2.Get ModeID Table  */
+   if(temp==0)  return(0);
 
-void
-SiS_SetDRAMSize_310 (PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	ULONG ROMAddr = (ULONG) HwDeviceExtension->pjVirtualRomBase;
-	ULONG FBAddr = (ULONG) HwDeviceExtension->pjVideoMemoryAddress;
-	/*USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; */
-	USHORT data;
+   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+   SiS_GetVBType(BaseAddr);
 
-#ifdef SIS301
-	/*SiS_SetReg1(SiS_P3d4,0x30,0x40);   */
-#endif
-#ifdef SIS302
-	SiS_SetReg1 (SiS_P3d4, 0x30, 0x4D);	/* alan,should change value */
-	SiS_SetReg1 (SiS_P3d4, 0x31, 0xc0);	/* alan,should change value */
-	SiS_SetReg1 (SiS_P3d4, 0x34, 0x3F);	/* alan,should change value */
+   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);   	/*add for CRT2 */
+   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex);   		/*add for CRT2 */
+
+   temp=SiS_CheckMemorySize(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);    	/*3.Check memory size */
+   if(temp==0) return(0);
+   if(SiS_VBInfo&(SetSimuScanMode|SetCRT2ToLCDA)) {				/*301b*/
+   	SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
+   } else {
+     if(!(SiS_VBInfo&SwitchToCRT2)) {
+       	SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
+     }
+   }
+
+   if(SiS_VBInfo&(SetSimuScanMode|SwitchToCRT2|SetCRT2ToLCDA)) {		/*301b*/
+     switch (HwDeviceExtension->ujVBChipID) {
+     case VB_CHIP_301:
+     case VB_CHIP_301B:    /*for Linux & WinCE to open*/
+        SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);        /*add for CRT2 */
+        break;
+     case VB_CHIP_302:
+        SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        break;
+     case VB_CHIP_303:
+/*      SetCRT2Group302(BaseAddr,ROMAddr,ModeNo, HwDeviceExtension);             add for CRT2   */
+        break;
+     case VB_CHIP_UNKNOWN:                                                                                                 /*add for lvds ch7005*/
+        temp=SiS_GetReg1(SiS_P3d4,0x37);
+        if(temp&(ExtChipLVDS|ExtChipTrumpion|ExtChipCH7005)){
+             	SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        }
+        break;
+     }
+   }
+
+#ifdef LINUX_XF86
+   /* TW: SetPitch: Adapt to virtual size & position */
+   SiS_SetPitch(pScrn, BaseAddr);
+   /* Backup/Set ModeNo in MMIO */
+   SiS_GetSetModeID(pScrn,ModeNo);
 #endif
 
-	SiSSetMode (HwDeviceExtension, 0x2e);
+#ifndef LINUX_XF86  /* TW: We never lock registers in XF86 */
+   if(KeepLockReg==0xA1) SiS_SetReg1(SiS_P3c4,0x05,0x86);
+   else SiS_SetReg1(SiS_P3c4,0x05,0x00);
+#endif
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x21);
-	SiS_SetReg1 (SiS_P3c4, 0x21, (USHORT) (data & 0xDF));	/* disable read cache */
+   return TRUE;
+}
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x1);
-	data = data | 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x01, data);	/* Turn OFF Display */
+void
+SetEnableDstn()		/* TW: Called from sis_main.c */
+{
+   SiS_IF_DEF_DSTN=1;   /*for 550 dstn*/
+}
 
-	data = SiS_GetReg1 (SiS_P3c4, 0x16);
-	SiS_SetReg1 (SiS_P3c4, 0x16, (USHORT) (data | 0x0F));	/* assume lowest speed DRAM */
+void
+SiS_SetCRT1Group(ULONG ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                 USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT  StandTableIndex,RefreshRateTableIndex;
+  USHORT  temp;
 
-	SiS_SetDRAMModeRegister (ROMAddr);
-	SiS_DisableRefresh ();
-	SiS_CheckBusWidth_310 (ROMAddr, FBAddr);
+  /*SiS_SetReg1(SiS_P3d4,0x34,ModeNo);*/
+  SiS_CRT1Mode = ModeNo;
+  /* set CR34->CRT1 ModeNo for CRT2 FIFO */
+  StandTableIndex = SiS_GetModePtr(ROMAddr,ModeNo,ModeIdIndex); /* 4.GetModePtr  */
+  SiS_SetSeqRegs(ROMAddr,StandTableIndex);                      /* 5.SetSeqRegs  */
+  SiS_SetMiscRegs(ROMAddr,StandTableIndex);                     /* 6.SetMiscRegs */
+  SiS_SetCRTCRegs(ROMAddr,HwDeviceExtension,StandTableIndex);   /* 7.SetCRTCRegs */
+  SiS_SetATTRegs(ROMAddr,StandTableIndex);                      /* 8.SetATTRegs  */
+  SiS_SetGRCRegs(ROMAddr,StandTableIndex);                      /* 9.SetGRCRegs  */
+  SiS_ClearExt1Regs();                                          /* 10.Clear Ext1Regs */
+  temp=~ProgrammingCRT2;                                        /* 11.GetRatePtr  */
+  SiS_SetFlag=SiS_SetFlag&temp;
+  SiS_SelectCRT2Rate=0;
 
-	SiS_VerifyMclk (FBAddr);	/* alan 2000/7/3 */
+#ifdef LINUX_XF86
+  xf86DrvMsg(0, X_INFO, "VBType = %x, LVDS=%d, VBInfo=%x\n",
+                    SiS_VBType, SiS_IF_DEF_LVDS, SiS_VBInfo);
+#endif
 
-	if (SiS_Get310DRAMType (ROMAddr) < 2) {
-		SiS_SDRSizing (FBAddr);
-	} else {
-		SiS_DDRSizing (FBAddr);
-	}
+  /*301b*/
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))) {
+      if(SiS_VBInfo&SetCRT2ToLCDA) {
+	 SiS_SetFlag=SiS_SetFlag|ProgrammingCRT2;
+      }
+  }
+  /*end 301b*/
 
-	if (Is315E ()) {
-		data = SiS_GetReg1 (SiS_P3c4, 0x14);
-		if ((data & 0x0C) == 0x0C) {	/* dual channel */
-			if ((data & 0xF0) > 0x40)
-				data = (data & 0x0F) | 0x40;
-		} else {	/* single channel */
+  RefreshRateTableIndex=SiS_GetRatePtrCRT2(ROMAddr,ModeNo,ModeIdIndex);   /* 11.GetRatePtr */
 
-			if ((data & 0xF0) > 0x50)
-				data = (data & 0x0F) | 0x50;
-		}
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))) {
+      if(!(SiS_VBInfo&SetCRT2ToLCDA)) {
+	 SiS_SetFlag=SiS_SetFlag&(~ProgrammingCRT2);
+      }
+  }
 
-	}
+  if (RefreshRateTableIndex!=0xFFFF) {
+    SiS_SetSync(ROMAddr,RefreshRateTableIndex);                          /* 12.SetSync */
+    SiS_SetCRT1CRTC(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);   /* 13.SetCRT1CRTC  */
+    SiS_SetCRT1Offset(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);   /* 14.SetCRT1Offset */
+    SiS_SetCRT1VCLK(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex);     /* 15.SetCRT1VCLK  */
+  }
+#ifdef SIS300
+  if((HwDeviceExtension->jChipType == SIS_630)||
+     (HwDeviceExtension->jChipType == SIS_540)) {
+     	SiS_SetCRT1FIFO2(ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
+  }
+#endif
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     	SiS_SetCRT1FIFO(ROMAddr,ModeNo,HwDeviceExtension);
+  }
+#endif
+  SiS_SetCRT1ModeRegs(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+  SiS_SetVCLKState(ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex);
+#ifdef SIS315H
+  if(HwDeviceExtension->jChipType > SIS_315H) {
+    if (RefreshRateTableIndex!=0xFFFF)
+      	SiS_SetInterlace(ROMAddr,ModeNo,RefreshRateTableIndex);
+  }
+#endif
+  SiS_LoadDAC(ROMAddr,ModeNo,ModeIdIndex);
+  if(flag_clearbuffer) SiS_ClearBuffer(HwDeviceExtension,ModeNo);
 
-	SiS_SetReg1 (SiS_P3c4, 0x16, SiS_SR15[1][SiS_RAMType]);	/* restore SR16 */
+  if(!(SiS_VBInfo&(SetSimuScanMode|SwitchToCRT2|SetCRT2ToLCDA))) {   /*301b*/
+    SiS_LongWait();
+    SiS_DisplayOn();
+  }
+}
 
-	SiS_EnableRefresh (ROMAddr);
-	data = SiS_GetReg1 (SiS_P3c4, 0x21);
-	SiS_SetReg1 (SiS_P3c4, 0x21, (USHORT) (data | 0x20));	/* enable read cache */
+#ifdef LINUX_XF86
+void
+SiS_SetPitch(ScrnInfoPtr pScrn, UShort BaseAddr)
+{
+   SISPtr pSiS = SISPTR(pScrn);
 
+   if (pSiS->VBFlags & DISPTYPE_DISP1) {
+   	SiS_SetPitchCRT1(pScrn, BaseAddr);
+   }
+   if (pSiS->VBFlags & DISPTYPE_DISP2) {
+   	SiS_SetPitchCRT2(pScrn, BaseAddr);
+   }
 }
-#endif
 
 void
-SiS_SetMemoryClock (ULONG ROMAddr)
+SiS_SetPitchCRT1(ScrnInfoPtr pScrn, UShort BaseAddr)
 {
-	SiS_SetReg1 (SiS_P3c4, 0x28, SiS_MCLKData[SiS_RAMType].SR28);
-	SiS_SetReg1 (SiS_P3c4, 0x29, SiS_MCLKData[SiS_RAMType].SR29);
-	SiS_SetReg1 (SiS_P3c4, 0x2A, SiS_MCLKData[SiS_RAMType].SR2A);
-	SiS_SetReg1 (SiS_P3c4, 0x2E, SiS_ECLKData[SiS_RAMType].SR2E);
-	SiS_SetReg1 (SiS_P3c4, 0x2F, SiS_ECLKData[SiS_RAMType].SR2F);
-	SiS_SetReg1 (SiS_P3c4, 0x30, SiS_ECLKData[SiS_RAMType].SR30);
+    SISPtr pSiS = SISPTR(pScrn);
+    ULong  HDisplay,temp;
 
-#ifdef CONFIG_FB_SIS_315
-	if (Is315E ()) {
-		SiS_SetReg1 (SiS_P3c4, 0x28, 0x3B);	/* 143 */
-		SiS_SetReg1 (SiS_P3c4, 0x29, 0x22);
-		SiS_SetReg1 (SiS_P3c4, 0x2E, 0x3B);	/* 143 */
-		SiS_SetReg1 (SiS_P3c4, 0x2F, 0x22);
-	}
-#endif
+    HDisplay = pSiS->scrnOffset / 8;
+    SiS_SetReg1(SiS_P3d4, 0x13, (HDisplay & 0xFF));
+    temp = (SiS_GetReg1(SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
+    SiS_SetReg1(SiS_P3c4, 0x0E, temp);
+}
 
+void
+SiS_SetPitchCRT2(ScrnInfoPtr pScrn, UShort BaseAddr)
+{
+    SISPtr pSiS = SISPTR(pScrn);
+    ULong  HDisplay,temp;
+
+    HDisplay = pSiS->scrnOffset / 8;
+    SiS_SetReg1(SiS_Part1Port, 0x24, 1);
+    SiS_SetReg1(SiS_Part1Port, 0x07, HDisplay);
+    temp = (SiS_GetReg1(SiS_Part1Port, 0x09) & 0xF0) | (HDisplay>>8);
+    SiS_SetReg1(SiS_Part1Port, 0x09, temp);
 }
+#endif
 
-/*
-=========================================
- ======== SiS SetMode Function  ==========
-=========================================
-*/
-BOOLEAN
-SiSSetMode (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo)
+void
+SiS_GetVBType(USHORT BaseAddr)
 {
-	ULONG temp;
-	USHORT ModeIdIndex, KeepLockReg;
-	ULONG ROMAddr = (ULONG) HwDeviceExtension->pjVirtualRomBase;
-	/*ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress; */
-	USHORT BaseAddr = (USHORT) HwDeviceExtension->ulIOAddress;
-
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||	/* 05/02/01 ynlai for sis550 */
-	    (HwDeviceExtension->jChipType == SIS_315PRO) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740))	/* 09/03/01 chiawen for 650 */
-		InitTo310Pointer ();
-#endif
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ||
-	    (HwDeviceExtension->jChipType == SIS_300))
-		InitTo300Pointer ();
-#endif
-
-	SiS_P3c4 = BaseAddr + 0x14;
-	SiS_P3d4 = BaseAddr + 0x24;
-	SiS_P3c0 = BaseAddr + 0x10;
-	SiS_P3ce = BaseAddr + 0x1e;
-	SiS_P3c2 = BaseAddr + 0x12;
-	SiS_P3ca = BaseAddr + 0x1a;
-	SiS_P3c6 = BaseAddr + 0x16;
-	SiS_P3c7 = BaseAddr + 0x17;
-	SiS_P3c8 = BaseAddr + 0x18;
-	SiS_P3c9 = BaseAddr + 0x19;
-	SiS_P3da = BaseAddr + 0x2A;
-	SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
-	SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
-	SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
-
-	SiS_IF_DEF_LVDS = 0;
-	SiS_IF_DEF_CH7005 = 0;
-	SiS_IF_DEF_HiVision = 0;
-	SiS_IF_DEF_DSTN = 0;	/*for 550 dstn */
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740)) {	/* 09/03/01 chiawen for 650 */
-		temp = SiS_GetReg1 (SiS_P3d4, 0x37);
-		temp = (temp & 0x0E) >> 1;
-		if ((temp == 0) || (temp == 1)) {	/* for 301 */
-			SiS_IF_DEF_LVDS = 0;
-			SiS_IF_DEF_CH7005 = 0;
-			SiS_IF_DEF_TRUMPION = 0;
-		}
-		if ((temp >= 2) && (temp <= 5)) {
-			SiS_IF_DEF_LVDS = 1;
-		}
-		if (temp == 3)
-			SiS_IF_DEF_TRUMPION = 1;
-		if ((temp == 4) || (temp == 5))
-			SiS_IF_DEF_CH7005 = 1;
-	} else {
-		SiS_IF_DEF_LVDS = 0;
-		SiS_IF_DEF_TRUMPION = 0;
-		SiS_IF_DEF_CH7005 = 0;
-	}
-
-	if (ModeNo & 0x80) {
-		ModeNo = ModeNo & 0x7F;
-		flag_clearbuffer = 0;
-	} else {
-		flag_clearbuffer = 1;
-	}
-
-	SiS_PresetScratchregister (SiS_P3d4, HwDeviceExtension);	/*add for CRT2  */
-	KeepLockReg = SiS_GetReg1 (SiS_P3c4, 0x05);
-	SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);	/* 1.Openkey */
-	temp = SiS_SearchModeID (ROMAddr, ModeNo, &ModeIdIndex);	/* 2.Get ModeID Table  */
-	if (temp == 0)
-		return (0);
-	/*301b */
-	SiS_GetVBType (BaseAddr);
-	/*end 301b */
-	SiS_GetVBInfo301 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex, HwDeviceExtension);	/*add for CRT2 */
-	SiS_GetLCDResInfo301 (ROMAddr, SiS_P3d4, ModeNo, ModeIdIndex);	/*add for CRT2 */
-
-	temp = SiS_CheckMemorySize (ROMAddr, HwDeviceExtension, ModeNo, ModeIdIndex);	/*3.Check memory size */
-	if (temp == 0)
-		return (0);
-	if (SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {	/*301b */
-		SiS_SetCRT1Group (ROMAddr, HwDeviceExtension, ModeNo,
-				  ModeIdIndex);
-	} else {
-		if (!(SiS_VBInfo & SwitchToCRT2)) {
-			SiS_SetCRT1Group (ROMAddr, HwDeviceExtension, ModeNo,
-					  ModeIdIndex);
-		}
-	}
-
-	if (SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {	/*301b */
-		switch (HwDeviceExtension->ujVBChipID) {
-/*karl*/
-		case VB_CHIP_301:
-		case VB_CHIP_301B:
-			SiS_SetCRT2Group301 (BaseAddr, ROMAddr, ModeNo, HwDeviceExtension);	/*add for CRT2 */
-			break;
-		case VB_CHIP_302:
-			SiS_SetCRT2Group301 (BaseAddr, ROMAddr, ModeNo,
-					     HwDeviceExtension);
-			break;
-		case VB_CHIP_303:
-/*        SetCRT2Group302(BaseAddr,ROMAddr,ModeNo, HwDeviceExtension);                       add for CRT2   */
-			break;
-		case VB_CHIP_UNKNOWN:	/*add for lvds ch7005 */
-			temp = SiS_GetReg1 (SiS_P3d4, 0x37);
-			if (temp &
-			    (ExtChipLVDS | ExtChipTrumpion | ExtChipCH7005)) {
-				SiS_SetCRT2Group301 (BaseAddr, ROMAddr, ModeNo,
-						     HwDeviceExtension);
-			}
-			break;
-		}
-	}
-	if (KeepLockReg == 0xA1)
-		SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);	/* 05/02/01 ynlai */
-	else
-		SiS_SetReg1 (SiS_P3c4, 0x05, 0x00);
-	return TRUE;
-}
-
-void
-SiS_SetCRT1Group (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		  USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT StandTableIndex, RefreshRateTableIndex;
-	USHORT temp;
-
-	/*SiS_SetReg1(SiS_P3d4,0x34,ModeNo); */
-	SiS_CRT1Mode = ModeNo;
-	/* set CR34->CRT1 ModeNofor CRT2 FIFO */
-	StandTableIndex = SiS_GetModePtr (ROMAddr, ModeNo, ModeIdIndex);	/* 4.GetModePtr  */
-	SiS_SetSeqRegs (ROMAddr, StandTableIndex);	/* 5.SetSeqRegs  */
-	SiS_SetMiscRegs (ROMAddr, StandTableIndex);	/* 6.SetMiscRegs */
-	SiS_SetCRTCRegs (ROMAddr, HwDeviceExtension, StandTableIndex);	/* 7.SetCRTCRegs */
-	SiS_SetATTRegs (ROMAddr, StandTableIndex);	/* 8.SetATTRegs  */
-	SiS_SetGRCRegs (ROMAddr, StandTableIndex);	/* 9.SetGRCRegs  */
-	SiS_ClearExt1Regs ();	/* 10.Clear Ext1Regs */
-	temp = ~ProgrammingCRT2;	/*       11.GetRatePtr  */
-	SiS_SetFlag = SiS_SetFlag & temp;
-	SiS_SelectCRT2Rate = 0;
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (SiS_VBInfo & SetCRT2ToLCDA) {
-			SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-			/*   SiS_SelectCRT2Rate=4; */
-		}
-	}
-	/*end 301b */
-
-	RefreshRateTableIndex = SiS_GetRatePtrCRT2 (ROMAddr, ModeNo, ModeIdIndex);	/* 11.GetRatePtr */
-
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (!(SiS_VBInfo & SetCRT2ToLCDA)) {
-			SiS_SetFlag = SiS_SetFlag & (~ProgrammingCRT2);
-		}
-	}
-	/*end 301b */
-
-	if (RefreshRateTableIndex != 0xFFFF) {
-		SiS_SetSync (ROMAddr, RefreshRateTableIndex);	/* 12.SetSync */
-		SiS_SetCRT1CRTC (ROMAddr, ModeNo, ModeIdIndex, RefreshRateTableIndex);	/* 13.SetCRT1CRTC  */
-		SiS_SetCRT1Offset (ROMAddr, ModeNo, ModeIdIndex,
-				   RefreshRateTableIndex, HwDeviceExtension);	/* 14.SetCRT1Offset */
-		SiS_SetCRT1VCLK (ROMAddr, ModeNo, ModeIdIndex,
-				 HwDeviceExtension, RefreshRateTableIndex);	/* 15.SetCRT1VCLK  */
-	}
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_540)) {
-		SiS_SetCRT1FIFO2 (ROMAddr, ModeNo, HwDeviceExtension,
-				  RefreshRateTableIndex);
-	}
-#endif
-#ifdef CONFIG_FB_SIS_315
-	if (HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetCRT1FIFO (ROMAddr, ModeNo, HwDeviceExtension);
-	}
-#endif
-	SiS_SetCRT1ModeRegs (ROMAddr, HwDeviceExtension, ModeNo, ModeIdIndex,
-			     RefreshRateTableIndex);
-	SiS_SetVCLKState (ROMAddr, HwDeviceExtension, ModeNo,
-			  RefreshRateTableIndex);
-#ifdef CONFIG_FB_SIS_315
-	if (HwDeviceExtension->jChipType > SIS_315H)
-		SiS_SetInterlace (ROMAddr, ModeNo, RefreshRateTableIndex);
-#endif
-	SiS_LoadDAC (ROMAddr, ModeNo, ModeIdIndex);
-	if (flag_clearbuffer)
-		SiS_ClearBuffer (HwDeviceExtension, ModeNo);
-
-	if (!(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {	/*301b */
-		SiS_LongWait ();
-		SiS_DisplayOn ();
-	}
-}
-
-void
-SiS_GetVBType (USHORT BaseAddr)
-{
-	USHORT flag;
-
-	flag = SiS_GetReg1 (SiS_Part4Port, 0x00);
-	if (flag >= 2)
-		SiS_VBType = VB_SIS302B;
-	else {
-		flag = SiS_GetReg1 (SiS_Part4Port, 0x01);
-		if (flag >= 0xB0)
-			SiS_VBType = VB_SIS301B;
-		else
-			SiS_VBType = VB_SIS301;
-
-		flag = SiS_GetReg1 (SiS_Part4Port, 0x23);	/*301dlvds */
-		if (!(flag & 0x02))
-			SiS_VBType = SiS_VBType | VB_NoLCD;
-	}
+  USHORT flag;
 
+  flag=SiS_GetReg1(SiS_Part4Port,0x00);
+  /* TW: On pure LVDS, Part4 is not assigned and returns 0xff */
+  if (flag >= 4) return;
+  /* TW end */
+  if (flag >= 2) {
+  	flag=SiS_GetReg1(SiS_Part4Port,0x01);
+        if(flag>=0xB0){
+            	SiS_VBType=VB_SIS302B;
+            	if(flag>=0xD0)
+               		SiS_VBType=VB_SIS302LV;
+        }
+  } else {
+        flag=SiS_GetReg1(SiS_Part4Port,0x01);
+        if(flag>=0xB0){
+            	SiS_VBType=VB_SIS301B;
+            	if(flag>=0xD0)
+               		SiS_VBType=VB_SIS301LV;
+        } else
+            SiS_VBType=VB_SIS301;
+  }
+  flag=SiS_GetReg1(SiS_Part4Port,0x23);       /*301dlvds*/
+  if(!(flag&0x02))
+      	SiS_VBType=SiS_VBType|VB_NoLCD;
 }
 
 /* win2000 MM adapter not support standard mode  */
 BOOLEAN
-SiS_SearchModeID (ULONG ROMAddr, USHORT ModeNo, USHORT * ModeIdIndex)
+SiS_SearchModeID(ULONG ROMAddr, USHORT ModeNo,USHORT  *ModeIdIndex)
 {
-	PUCHAR VGA_INFO = "\0x11";
-
-	if (ModeNo <= 5)
-		ModeNo |= 1;
-	if (ModeNo <= 0x13) {
-		/* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(SiS_SModeIDTable)/sizeof(SiS_StStruct);(*ModeIdIndex)++) */
-		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
-			if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
-				break;
-			if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
-				return FALSE;
-		}
-
+#ifndef LINUX_XF86
+   PUCHAR VGA_INFO="\0x11";
+#endif
+   
+   if (ModeNo<=5) ModeNo |= 1;
+   if (ModeNo<=0x13) {
+     /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(SiS_SModeIDTable)/sizeof(SiS_StStruct);(*ModeIdIndex)++) */
+     for (*ModeIdIndex=0;;(*ModeIdIndex)++)
+     {
+       if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID==ModeNo) break;
+       if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID==0xFF)  return FALSE;
+     }
+#ifndef LINUX_XF86
 #ifdef TC
-		VGA_INFO = (PUCHAR) MK_FP (0, 0x489);
+     VGA_INFO = (PUCHAR) MK_FP(0,0x489);
 #endif
-		if (ModeNo == 0x07) {
-			if ((*VGA_INFO & 0x10) != 0)
-				(*ModeIdIndex)++;	/* 400 lines */
-			/* else 350 lines */
-		}
-		if (ModeNo <= 3) {
-			if ((*VGA_INFO & 0x80) == 0) {
-				(*ModeIdIndex)++;
-				if ((*VGA_INFO & 0x10) != 0)
-					(*ModeIdIndex)++;;	/* 400 lines  */
-				/* else 350 lines  */
-			}
-			/* else 200 lines  */
-		}
-	} else {
-		/* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(SiS_EModeIDTable)/sizeof(SiS_ExtStruct);(*ModeIdIndex)++) */
-		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
-			if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
-				break;
-			if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
-				return FALSE;
-		}
-	}
-	return TRUE;
+     if (ModeNo==0x07) {
+        if ((*VGA_INFO&0x10)!=0) (*ModeIdIndex)++; /* 400 lines */
+        /* else 350 lines */
+     }
+     if (ModeNo<=3) {
+       if ((*VGA_INFO&0x80)==0) {
+         (*ModeIdIndex)++;
+         if ((*VGA_INFO&0x10)!=0)
+           (*ModeIdIndex)++;; /* 400 lines  */
+         /* else 350 lines  */
+       }
+       /* else 200 lines  */
+     }
+#endif  /* NOT X86 */
+   }
+   else 
+   {
+     /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(SiS_EModeIDTable)/sizeof(SiS_ExtStruct);(*ModeIdIndex)++) */
+     for (*ModeIdIndex=0;;(*ModeIdIndex)++)
+     {
+       if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID==ModeNo) break;
+       if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID==0xFF) return FALSE;
+     }
+   }
+   return TRUE;
 }
 
 /*add for 300 oem util for search VBModeID*/
 BOOLEAN
-SiS_SearchVBModeID (ULONG ROMAddr, USHORT ModeNo)
+SiS_SearchVBModeID(ULONG ROMAddr, USHORT ModeNo)
 {
-	USHORT ModeIdIndex;
-
-	// PUCHAR VGA_INFO;
-
-	if (ModeNo <= 5)
-		ModeNo |= 1;
-	/* for (ModeIdIndex=0;ModeIdIndex<sizeof(SiS_SModeIDTable)/sizeof(SiS_StStruct);(*ModeIdIndex)++) */
-	for (ModeIdIndex = 0;; (ModeIdIndex)++) {
-		if (SiS_VBModeIDTable[ModeIdIndex].ModeID == ModeNo)
-			break;
-		if (SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)
-			return FALSE;
-	}
+   USHORT ModeIdIndex;
+#ifdef TC
+   PUCHAR VGA_INFO;
+#endif
+   
+   if (ModeNo<=5) ModeNo |= 1;
+    /* for (ModeIdIndex=0;ModeIdIndex<sizeof(SiS_SModeIDTable)/sizeof(SiS_StStruct);(*ModeIdIndex)++) */
+     for (ModeIdIndex=0;;(ModeIdIndex)++)
+     {
+       if (SiS_VBModeIDTable[ModeIdIndex].ModeID==ModeNo) break;
+       if (SiS_VBModeIDTable[ModeIdIndex].ModeID==0xFF)  return FALSE;
+     }
 #ifdef TC
-	VGA_INFO = (PUCHAR) MK_FP (0, 0x489);
-	if (ModeNo == 0x07) {
-		if ((*VGA_INFO & 0x10) != 0)
-			(ModeIdIndex)++;	/* 400 lines */
-		/* else 350 lines */
-	}
-	if (ModeNo <= 3) {
-		if ((*VGA_INFO & 0x80) == 0) {
-			(ModeIdIndex)++;
-			if ((*VGA_INFO & 0x10) != 0)
-				(ModeIdIndex)++;;	/* 400 lines  */
-			/* else 350 lines  */
-		}
-		/* else 200 lines  */
-	}
+     VGA_INFO = (PUCHAR) MK_FP(0,0x489);
+     if (ModeNo==0x07) {
+	if ((*VGA_INFO&0x10)!=0) (ModeIdIndex)++; /* 400 lines */
+	/* else 350 lines */
+     }
+     if (ModeNo<=3) {
+       if ((*VGA_INFO&0x80)==0) {
+	 (ModeIdIndex)++;
+         if ((*VGA_INFO&0x10)!=0)
+	   (ModeIdIndex)++;; /* 400 lines  */
+	 /* else 350 lines  */
+       }
+       /* else 200 lines  */
+     }
 #endif
-	return ((BOOLEAN) ModeIdIndex);
+  return ((BOOLEAN)ModeIdIndex);
 }
-
-/*end*/
-
-/* win2000 MM adapter not support standard mode!  */
+/*end oem util */
 
 BOOLEAN
-SiS_CheckMemorySize (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		     USHORT ModeNo, USHORT ModeIdIndex)
+SiS_CheckMemorySize(ULONG ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                    USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT memorysize;
-	USHORT modeflag;
-	USHORT temp;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-
-/*  ModeType=modeflag&ModeInfoFlag;                           Get mode type  */
-
-	memorysize = modeflag & MemoryInfoFlag;
-	memorysize = memorysize > MemorySizeShift;
-	memorysize++;		/* Get memory size */
-
-	temp = SiS_GetReg1 (SiS_P3c4, 0x14);	/* Get DRAM Size    */
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||
-	    (HwDeviceExtension->jChipType == SIS_315PRO)) {
-		temp = 1 << ((temp & 0x0F0) >> 4);
-		if ((temp & 0x0c) == 0x08) {	/* DDR asymetric */
-			temp += temp / 2;
-		} else {
-			if ((temp & 0x0c) != 0) {
-				temp <<= 1;
-			}
-		}
-	} else {		/* 300, 540 , 630 */
-
-		temp = temp & 0x3F;
-		temp++;
-		/*  temp=1 << ((temp&0x0F0)>>4); */
-	}
-
-	if ((HwDeviceExtension->jChipType == SIS_550) ||	/* 05/02/01 ynlai for sis550 */
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740)) {	/* 09/03/01 chiawen for 650 */
-		return (TRUE);
-	}
-
-	if (temp < memorysize)
-		return (FALSE);
-	else
-		return (TRUE);
+  USHORT memorysize,modeflag,temp;
+
+  if((HwDeviceExtension->jChipType == SIS_550)||   /* 05/02/01 ynlai for sis550 */
+     (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+     (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+     (HwDeviceExtension->jChipType == SIS_650))    /* 09/03/01 chiawen for 650 */
+    return(TRUE);
+
+  if (ModeNo<=0x13) {
+    modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+    modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+/*  ModeType=modeflag&ModeInfoFlag;                           	   Get mode type  */
+
+  memorysize=modeflag&MemoryInfoFlag;
+  memorysize=memorysize>MemorySizeShift;
+  memorysize++;                                        		/* Get memory size */
+
+  temp=SiS_GetReg1(SiS_P3c4,0x14);                             	/* Get DRAM Size    */
+  if((HwDeviceExtension->jChipType == SIS_315H)||
+     (HwDeviceExtension->jChipType == SIS_315PRO)) {
+    temp= 1 << ((temp&0x0F0)>>4);				/* 315 */
+    if ((temp&0x0c)==0x08) { /* DDR asymetric */
+      temp += temp/2;
+    } else {
+      if ((temp&0x0c)!=0) temp <<= 1;
+    }
+  } else { 							/* 300, 540, 630, 730 */
+    temp=temp&0x3F;
+    temp++;
+  }
+
+  if(temp<memorysize) return(FALSE);
+  else return(TRUE);
 }
 
 UCHAR
-SiS_GetModePtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetModePtr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	UCHAR index;
+   UCHAR index;
 
-	if (ModeNo <= 0x13) {
-		index = SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
-	} else {
-		if (SiS_ModeType <= 0x02)
-			index = 0x1B;	/* 02 -> ModeEGA  */
-		else
-			index = 0x0F;
-	}
-
-	return index;		/* Get SiS_StandTable index  */
-}
-
-void
-SiS_SetSeqRegs (ULONG ROMAddr, USHORT StandTableIndex)
-{
-	UCHAR SRdata;
-	USHORT i;
-
-	SiS_SetReg1 (SiS_P3c4, 0x00, 0x03);	/* Set SR0  */
-	SRdata = SiS_StandTable[StandTableIndex].SR[0];
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (SiS_VBInfo & SetCRT2ToLCDA) {
-			SRdata = SRdata | 0x01;
-		}
-	}
-
-	/*end 301b */
-
-	if (SiS_IF_DEF_LVDS == 1) {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				if (SiS_VBInfo & SetInSlaveMode) {
-					SRdata = SRdata | 0x01;	/* 8 dot clock  */
-				}
-			}
-		}
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			if (SiS_VBInfo & SetInSlaveMode) {
-				SRdata = SRdata | 0x01;	/* 8 dot clock  */
-			}
-		}
-	}
-
-	SRdata = SRdata | 0x20;	/* screen off  */
-	SiS_SetReg1 (SiS_P3c4, 0x01, SRdata);	/* Set SR1 */
-	for (i = 02; i <= 04; i++) {
-		SRdata = SiS_StandTable[StandTableIndex].SR[i - 1];	/* Get SR2,3,4 from file */
-		SiS_SetReg1 (SiS_P3c4, i, SRdata);	/* Set SR2 3 4 */
-	}
-}
-
-void
-SiS_SetMiscRegs (ULONG ROMAddr, USHORT StandTableIndex)
-{
-	UCHAR Miscdata;
-
-	Miscdata = SiS_StandTable[StandTableIndex].MISC;	/* Get Misc from file */
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (SiS_VBInfo & SetCRT2ToLCDA) {
-			Miscdata = Miscdata | 0x0C;
-		}
-	}
-	/*end 301b */
-	SiS_SetReg3 (SiS_P3c2, Miscdata);	/* Set Misc(3c2) */
-}
-
-void
-SiS_SetCRTCRegs (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		 USHORT StandTableIndex)
-{
-	UCHAR CRTCdata;
-	USHORT i;
-
-	CRTCdata = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);
-	CRTCdata = CRTCdata & 0x7f;
-	SiS_SetReg1 (SiS_P3d4, 0x11, CRTCdata);	/* Unlock CRTC */
-
-	for (i = 0; i <= 0x18; i++) {
-		CRTCdata = SiS_StandTable[StandTableIndex].CRTC[i];	/* Get CRTC from file */
-		SiS_SetReg1 (SiS_P3d4, i, CRTCdata);	/* Set CRTC(3d4) */
-	}
-	if ((HwDeviceExtension->jChipType == SIS_630) &&
-	    (HwDeviceExtension->jChipRevision == 0x30)) {	/* for 630S0 */
-		if (SiS_VBInfo & SetInSlaveMode) {
-			if (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-				SiS_SetReg1 (SiS_P3d4, 0x18, 0xFE);
-			}
-		}
-	}
-}
-
-void
-SiS_SetATTRegs (ULONG ROMAddr, USHORT StandTableIndex)
-{
-	UCHAR ARdata;
-	USHORT i;
-
-	for (i = 0; i <= 0x13; i++) {
-		ARdata = SiS_StandTable[StandTableIndex].ATTR[i];	/* Get AR for file  */
-		/*301b */
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-			if (SiS_VBInfo & SetCRT2ToLCDA) {
-				if (i == 0x13) {
-					ARdata = 0;
-				}
-			}
-		}
-		/*end 301b */
-		if (SiS_IF_DEF_LVDS == 1) {	/*for LVDS  */
-			if (SiS_IF_DEF_CH7005 == 1) {
-				if (SiS_VBInfo & SetCRT2ToTV) {
-					if (SiS_VBInfo & SetInSlaveMode) {
-						if (i == 0x13) {
-							ARdata = 0;
-						}
-					}
-				}
-			}
-			if (SiS_VBInfo & SetCRT2ToLCD) {
-				if (SiS_VBInfo & SetInSlaveMode) {
-					if (SiS_LCDInfo & LCDNonExpanding) {
-						if (i == 0x13) {
-							ARdata = 0;
-						}
-					}
-				}
-			}
-		}
-		SiS_GetReg2 (SiS_P3da);	/* reset 3da  */
-		SiS_SetReg3 (SiS_P3c0, i);	/* set index  */
-		SiS_SetReg3 (SiS_P3c0, ARdata);	/* set data   */
-	}
-	SiS_GetReg2 (SiS_P3da);	/* reset 3da  */
-	SiS_SetReg3 (SiS_P3c0, 0x14);	/* set index  */
-	SiS_SetReg3 (SiS_P3c0, 0x00);	/* set data   */
-
-	SiS_GetReg2 (SiS_P3da);	/* Enable Attribute  */
-	SiS_SetReg3 (SiS_P3c0, 0x20);
-}
-
-void
-SiS_SetGRCRegs (ULONG ROMAddr, USHORT StandTableIndex)
-{
-	UCHAR GRdata;
-	USHORT i;
-
-	for (i = 0; i <= 0x08; i++) {
-		GRdata = SiS_StandTable[StandTableIndex].GRC[i];	/* Get GR from file */
-		SiS_SetReg1 (SiS_P3ce, i, GRdata);	/* Set GR(3ce) */
-	}
-
-	if (SiS_ModeType > ModeVGA) {
-		GRdata = (UCHAR) SiS_GetReg1 (SiS_P3ce, 0x05);
-		GRdata = GRdata & 0xBF;	/* 256 color disable */
-		SiS_SetReg1 (SiS_P3ce, 0x05, GRdata);
-	}
-}
-
-void
-SiS_ClearExt1Regs ()
-{
-	USHORT i;
-
-	for (i = 0x0A; i <= 0x0E; i++)
-		SiS_SetReg1 (SiS_P3c4, i, 0x00);	/* Clear SR0A-SR0E */
-}
-
-void
-SiS_SetSync (ULONG ROMAddr, USHORT RefreshRateTableIndex)
-{
-	USHORT sync;
-	USHORT temp;
-
-	sync = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;	/* di+0x00 */
-
-	sync = sync & 0xC0;
-	temp = 0x2F;
-	temp = temp | sync;
-	SiS_SetReg3 (SiS_P3c2, temp);	/* Set Misc(3c2) */
-}
-
-void
-SiS_SetCRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex)
-{
-	UCHAR index;
-	UCHAR data;
-	USHORT temp, tempah, i, modeflag, j;
-	USHORT ResInfo, DisplayType;
-	SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
-	if ((SiS_VBType & VB_SIS302B) && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		/*add crt1ptr */
-		if (ModeNo <= 0x13) {
-			modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		} else {
-			modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		}
-		temp =
-		    SiS_GetLCDACRT1Ptr (ROMAddr, ModeNo, ModeIdIndex,
-					RefreshRateTableIndex, &ResInfo,
-					&DisplayType);
-
-		switch (DisplayType) {
-		case 0:
-			LCDACRT1Ptr = SiS_LCDACRT1800x600_1;
-			break;
-		case 1:
-			LCDACRT1Ptr = SiS_LCDACRT11024x768_1;
-			break;
-		case 2:
-			LCDACRT1Ptr = SiS_LCDACRT11280x1024_1;
-			break;
-		case 3:
-			LCDACRT1Ptr = SiS_LCDACRT1800x600_1_H;
-			break;
-		case 4:
-			LCDACRT1Ptr = SiS_LCDACRT11024x768_1_H;
-			break;
-		case 5:
-			LCDACRT1Ptr = SiS_LCDACRT11280x1024_1_H;
-			break;
-		case 6:
-			LCDACRT1Ptr = SiS_LCDACRT1800x600_2;
-			break;
-		case 7:
-			LCDACRT1Ptr = SiS_LCDACRT11024x768_2;
-			break;
-		case 8:
-			LCDACRT1Ptr = SiS_LCDACRT11280x1024_2;
-			break;
-		case 9:
-			LCDACRT1Ptr = SiS_LCDACRT1800x600_2_H;
-			break;
-		case 10:
-			LCDACRT1Ptr = SiS_LCDACRT11024x768_2_H;
-			break;
-		case 11:
-			LCDACRT1Ptr = SiS_LCDACRT11280x1024_2_H;
-			break;
-			/*case 12: LCDACRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
-			   case 13: LCDACRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
-			   case 14: LCDACRT1Ptr = SiS_CHTVCRT1UPAL;                break;
-			   case 15: LCDACRT1Ptr = SiS_CHTVCRT1OPAL;                break; */
-		}
-
-		tempah = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);	/*unlock cr0-7  */
-		tempah = tempah & 0x7F;
-		SiS_SetReg1 (SiS_P3d4, 0x11, tempah);
-		tempah = (LCDACRT1Ptr + ResInfo)->CR[0];
-		SiS_SetReg1 (SiS_P3d4, 0x0, tempah);
-		for (i = 0x01, j = 1; i <= 0x07; i++, j++) {
-			tempah = (LCDACRT1Ptr + ResInfo)->CR[j];
-			SiS_SetReg1 (SiS_P3d4, i, tempah);
-		}
-/* for(i=0x06,j=5;i<=0x07;i++,j++){
-   tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
-  }*/
-		for (i = 0x10, j = 8; i <= 0x12; i++, j++) {
-			tempah = (LCDACRT1Ptr + ResInfo)->CR[j];
-			SiS_SetReg1 (SiS_P3d4, i, tempah);
-		}
-		for (i = 0x15, j = 11; i <= 0x16; i++, j++) {
-			tempah = (LCDACRT1Ptr + ResInfo)->CR[j];
-			SiS_SetReg1 (SiS_P3d4, i, tempah);
-		}
-
-		for (i = 0x0A, j = 13; i <= 0x0C; i++, j++) {
-			tempah = (LCDACRT1Ptr + ResInfo)->CR[j];
-			SiS_SetReg1 (SiS_P3c4, i, tempah);
-		}
-
-		tempah = (LCDACRT1Ptr + ResInfo)->CR[16];
-		tempah = tempah & 0x0E0;
-		SiS_SetReg1 (SiS_P3c4, 0x0E, tempah);
-
-		tempah = (LCDACRT1Ptr + ResInfo)->CR[16];
-		tempah = tempah & 0x01;
-		tempah = tempah << 5;
-		if (modeflag & DoubleScanMode) {
-			tempah = tempah | 0x080;
-		}
-		SiS_SetRegANDOR (SiS_P3d4, 0x09, ~0x020, tempah);
-		if (SiS_ModeType > 0x03)
-			SiS_SetReg1 (SiS_P3d4, 0x14, 0x4F);
-/*end 301b*/
-	} else {
-		index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;	/* Get index */
-		index = index & 0x3F;
-
-		data = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);
-		data = data & 0x7F;
-		SiS_SetReg1 (SiS_P3d4, 0x11, data);	/* Unlock CRTC */
-
-		for (i = 0, j = 0; i <= 07; i++, j++) {
-			data = SiS_CRT1Table[index].CR[i];
-			SiS_SetReg1 (SiS_P3d4, j, data);
-		}
-		for (j = 0x10; i <= 10; i++, j++) {
-			data = SiS_CRT1Table[index].CR[i];
-			SiS_SetReg1 (SiS_P3d4, j, data);
-		}
-		for (j = 0x15; i <= 12; i++, j++) {
-			data = SiS_CRT1Table[index].CR[i];
-			SiS_SetReg1 (SiS_P3d4, j, data);
-		}
-		for (j = 0x0A; i <= 15; i++, j++) {
-			data = SiS_CRT1Table[index].CR[i];
-			SiS_SetReg1 (SiS_P3c4, j, data);
-		}
-
-		data = SiS_CRT1Table[index].CR[16];
-		data = data & 0xE0;
-		SiS_SetReg1 (SiS_P3c4, 0x0E, data);
-
-		data = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x09);
-		data = data & 0xDF;	/* clear CR9 D[5] */
-		i = SiS_CRT1Table[index].CR[16];
-		i = i & 0x01;
-		i = i << 5;
-		data = data | i;
-
-		if (ModeNo <= 0x13)
-			i = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-		else
-			i = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
-		i = i & DoubleScanMode;
-		if (i)
-			data = data | 0x80;
-		SiS_SetReg1 (SiS_P3d4, 0x09, data);
-
-		if (SiS_ModeType > 0x03)
-			SiS_SetReg1 (SiS_P3d4, 0x14, 0x4F);
-	}
-}
-void
-SiS_SetCRT1Offset (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT temp, ah, al;
-	USHORT temp2, i;
-	USHORT DisplayUnit;
-
-	/* Alan */
-	temp = SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-	if (HwDeviceExtension->jChipType >= SIS_315H) {
-		temp = temp >> 8;	/* sis310 *//* index */
-	} else {
-		temp = temp >> 4;	/* sis300 *//* index */
-	}
-	temp = SiS_ScreenOffset[temp];
-	if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
-		temp = 0x6B;
-		temp2 = ModeNo - 0x7C;
-	} else {
-		temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-		temp2 = temp2 & InterlaceMode;
-		if (temp2)
-			temp = temp << 1;
-		temp2 = SiS_ModeType - ModeEGA;
-	}
-	switch (temp2) {
-	case 0:
-		temp2 = 1;
-		break;
-	case 1:
-		temp2 = 2;
-		break;
-	case 2:
-		temp2 = 4;
-		break;
-	case 3:
-		temp2 = 4;
-		break;
-	case 4:
-		temp2 = 6;
-		break;
-	case 5:
-		temp2 = 8;
-		break;
-	}
-	temp = temp * temp2;
-	DisplayUnit = temp;
-
-	temp2 = temp;
-	temp = temp >> 8;	/* ah */
-	temp = temp & 0x0F;
-	i = SiS_GetReg1 (SiS_P3c4, 0x0E);
-	i = i & 0xF0;
-	i = i | temp;
-	SiS_SetReg1 (SiS_P3c4, 0x0E, i);
-
-	temp = (UCHAR) temp2;
-	temp = temp & 0xFF;	/* al */
-	SiS_SetReg1 (SiS_P3d4, 0x13, temp);
-
-	temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	temp2 = temp2 & InterlaceMode;
-	if (temp2)
-		DisplayUnit >>= 1;
-
-	DisplayUnit = DisplayUnit << 5;
-	ah = (DisplayUnit & 0xff00) >> 8;
-	al = DisplayUnit & 0x00ff;
-	if (al == 0)
-		ah = ah + 1;
-	else
-		ah = ah + 2;
-	SiS_SetReg1 (SiS_P3c4, 0x10, ah);
-}
-
-void
-SiS_SetCRT1VCLK (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		 USHORT RefreshRateTableIndex)
-{
-	UCHAR index, data;
-	USHORT vclkindex;
-	if (SiS_IF_DEF_LVDS == 1) {
-		vclkindex =
-		    SiS_GetVCLK2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				     RefreshRateTableIndex, HwDeviceExtension);
-		data = SiS_GetReg1 (SiS_P3c4, 0x31) & 0xCF;
-		SiS_SetReg1 (SiS_P3c4, 0x31, data);
-
-		data = SiS_VCLKData[vclkindex].SR2B;
-		SiS_SetReg1 (SiS_P3c4, 0x2B, data);
-		data = SiS_VCLKData[vclkindex].SR2C;
-		SiS_SetReg1 (SiS_P3c4, 0x2C, data);
-
-		if (HwDeviceExtension->jChipType < SIS_315H)
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x80);
-		else
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x01);
-
-	}
-		else
-	    if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-		&& (SiS_VBInfo & SetCRT2ToLCDA) && (SiS_IF_DEF_LVDS == 0)) {
-		vclkindex =
-		    SiS_GetVCLK2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				     RefreshRateTableIndex, HwDeviceExtension);
-		data = SiS_GetReg1 (SiS_P3c4, 0x31) & 0xCF;
-		SiS_SetReg1 (SiS_P3c4, 0x31, data);
-
-		data = SiS_VBVCLKData[vclkindex].Part4_A;
-		SiS_SetReg1 (SiS_P3c4, 0x2B, data);
-		data = SiS_VBVCLKData[vclkindex].Part4_B;
-		SiS_SetReg1 (SiS_P3c4, 0x2C, data);
-
-		if (HwDeviceExtension->jChipType < SIS_315H)
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x80);	/* for300 series */
-		else
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x01);
-
-	} else {
-		index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-		/*if(HwDeviceExtension->jChipType < SIS_315H) { */
-		index = index & 0x3F;
-		/*} */
-		data = SiS_GetReg1 (SiS_P3c4, 0x31) & 0xCF;
-/*SiS_SetReg1(SiS_P3c4,0x31,0x00); *//* for300 */
-		SiS_SetReg1 (SiS_P3c4, 0x31, data);
-		SiS_SetReg1 (SiS_P3c4, 0x2B, SiS_VCLKData[index].SR2B);
-		SiS_SetReg1 (SiS_P3c4, 0x2C, SiS_VCLKData[index].SR2C);
-		if (HwDeviceExtension->jChipType < SIS_315H)
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x80);	/* for300 series */
-		else
-			SiS_SetReg1 (SiS_P3c4, 0x2D, 0x01);	/* for310 series */
-	}
-}
-void
-SiS_IsLowResolution (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT data;
-	USHORT ModeFlag;
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x0F);
-	data = data & 0x7F;
-	SiS_SetReg1 (SiS_P3c4, 0x0F, data);
-
-	if (ModeNo > 0x13) {
-		ModeFlag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
-			data = SiS_GetReg1 (SiS_P3c4, 0x0F);
-			data = data | 0x80;
-			SiS_SetReg1 (SiS_P3c4, 0x0F, data);
-			data = SiS_GetReg1 (SiS_P3c4, 0x01);
-			data = data & 0xF7;
-			SiS_SetReg1 (SiS_P3c4, 0x01, data);
-		}
-	}
-}
-
-void
-SiS_SetCRT1ModeRegs (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		     USHORT ModeNo, USHORT ModeIdIndex,
-		     USHORT RefreshRateTableIndex)
-{
-	USHORT data, data2, data3;
-	USHORT infoflag = 0, modeflag;
-	USHORT resindex, xres;
-
-	if (ModeNo > 0x13) {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	} else {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ModeFlag */
-	}
-	SiS_SetRegANDOR (SiS_P3c4, 0x1F, 0x3F, 0x00);
-	if (ModeNo > 0x13)
-		data = infoflag;
-	else
-		data = 0;
-	data2 = 0;
-	if (ModeNo > 0x13) {
-		if (SiS_ModeType > 0x02) {
-			data2 = data2 | 0x02;
-			data3 = SiS_ModeType - ModeVGA;
-			data3 = data3 << 2;
-			data2 = data2 | data3;
-		}
-	}
-	data = data & InterlaceMode;
-	if (data)
-		data2 = data2 | 0x20;
-	SiS_SetReg1 (SiS_P3c4, 0x06, data2);
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		resindex = SiS_GetResInfo (ROMAddr, ModeNo, ModeIdIndex);
-		if (ModeNo <= 0x13) {
-			xres = SiS_StResInfo[resindex].HTotal;
-		} else {
-			xres = SiS_ModeResInfo[resindex].HTotal;	/* xres->ax */
-		}
-		data = 0x0000;
-		if (infoflag & InterlaceMode) {
-			if (xres == 1024)
-				data = 0x0035;
-			if (xres == 1280)
-				data = 0x0048;
-		}
-		data2 = data & 0x00FF;
-		SiS_SetRegANDOR (SiS_P3d4, 0x19, 0xFF, data2);
-		data2 = (data & 0xFF00) >> 8;
-		SiS_SetRegANDOR (SiS_P3d4, 0x19, 0xFC, data2);
-	}
-	if (modeflag & HalfDCLK) {
-		SiS_SetRegANDOR (SiS_P3c4, 0x01, 0xFF, 0x01);
-	}
-
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-	} else {
-		if (modeflag & LineCompareOff) {
-			SiS_SetRegANDOR (SiS_P3c4, 0x0F, 0xF7, 0x08);
-		} else {
-			SiS_SetRegANDOR (SiS_P3c4, 0x0F, 0xF7, 0x00);
-		}
-	}
-
-	data = 0x60;
-	if (SiS_ModeType != ModeText) {
-		data = data ^ 0x60;
-		if (SiS_ModeType != ModeEGA) {
-			data = data ^ 0xA0;
-		}
-	}
-	SiS_SetRegANDOR (SiS_P3c4, 0x21, 0x1F, data);
-}
-
-void
-SiS_SetVCLKState (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		  USHORT ModeNo, USHORT RefreshRateTableIndex)
-{
-	USHORT data, data2 = 0;
-	USHORT VCLK;
-	UCHAR index;
-
-	if (ModeNo <= 0x13)
-		VCLK = 0;
-	else {
-		index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-		/*if(HwDeviceExtension->jChipType < SIS_315H) { */
-		index = index & 0x3F;
-		/*} */
-		VCLK = SiS_VCLKData[index].CLOCK;
-	}
-
-	if (HwDeviceExtension->jChipType < SIS_315H) {
-		data2 = 0x00;
-		if (VCLK > 150)
-			data2 = data2 | 0x80;
-		SiS_SetRegANDOR (SiS_P3c4, 0x07, 0x7B, data2);
-
-		data2 = 0x00;
-		if (VCLK >= 150)
-			data2 = data2 | 0x08;	/* VCLK > 150 */
-		SiS_SetRegANDOR (SiS_P3c4, 0x32, 0xF7, data2);
-	} else {		/* 310 series */
-
-		data = SiS_GetReg1 (SiS_P3c4, 0x32);
-		data = data & 0xf3;
-		if (VCLK >= 200)
-			data = data | 0x0c;	/* VCLK > 200 */
-		SiS_SetReg1 (SiS_P3c4, 0x32, data);
-		data = SiS_GetReg1 (SiS_P3c4, 0x1F);
-		data &= 0xE7;
-		if (VCLK < 200)
-			data |= 0x10;
-		SiS_SetReg1 (SiS_P3c4, 0x1F, data);
-	}
-
-	if ((VCLK >= 0) && (VCLK < 135))
-		data2 = 0x03;
-	if ((VCLK >= 135) && (VCLK < 160))
-		data2 = 0x02;
-	if ((VCLK >= 160) && (VCLK < 260))
-		data2 = 0x01;
-	if (VCLK > 260)
-		data2 = 0x00;
-	/* disable 24bit palette RAM gamma correction  */
-
-	if (HwDeviceExtension->jChipType == SIS_540) {
-		if ((VCLK == 203) || (VCLK < 234))
-			data2 = 0x02;
-	}
-	SiS_SetRegANDOR (SiS_P3c4, 0x07, 0xFC, data2);
-}
-
-void
-SiS_LoadDAC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT data, data2;
-	USHORT time, i, j, k;
-	USHORT m, n, o;
-	USHORT si, di, bx, dl;
-	USHORT al, ah, dh;
-	USHORT *table = NULL;
-
-	if (ModeNo <= 0x13)
-		data = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	else
-		data = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
-	data = data & DACInfoFlag;
-	time = 64;
-	if (data == 0x00)
-		table = SiS_MDA_DAC;
-	if (data == 0x08)
-		table = SiS_CGA_DAC;
-	if (data == 0x10)
-		table = SiS_EGA_DAC;
-	if (data == 0x18) {
-		time = 256;
-		table = SiS_VGA_DAC;
-	}
-	if (time == 256)
-		j = 16;
-	else
-		j = time;
-
-	SiS_SetReg3 (SiS_P3c6, 0xFF);
-	SiS_SetReg3 (SiS_P3c8, 0x00);
-
-	for (i = 0; i < j; i++) {
-		data = table[i];
-		for (k = 0; k < 3; k++) {
-			data2 = 0;
-			if (data & 0x01)
-				data2 = 0x2A;
-			if (data & 0x02)
-				data2 = data2 + 0x15;
-			SiS_SetReg3 (SiS_P3c9, data2);
-			data = data >> 2;
-		}
-	}
-
-	if (time == 256) {
-		for (i = 16; i < 32; i++) {
-			data = table[i];
-			for (k = 0; k < 3; k++)
-				SiS_SetReg3 (SiS_P3c9, data);
-		}
-		si = 32;
-		for (m = 0; m < 9; m++) {
-			di = si;
-			bx = si + 0x04;
-			dl = 0;
-			for (n = 0; n < 3; n++) {
-				for (o = 0; o < 5; o++) {
-					dh = table[si];
-					ah = table[di];
-					al = table[bx];
-					si++;
-					SiS_WriteDAC (dl, ah, al, dh);
-				}	/* for 5 */
-				si = si - 2;
-				for (o = 0; o < 3; o++) {
-					dh = table[bx];
-					ah = table[di];
-					al = table[si];
-					si--;
-					SiS_WriteDAC (dl, ah, al, dh);
-				}	/* for 3 */
-				dl++;
-			}	/* for 3 */
-			si = si + 5;
-		}		/* for 9 */
-	}
-}
-
-void
-SiS_WriteDAC (USHORT dl, USHORT ah, USHORT al, USHORT dh)
-{
-	USHORT temp;
-	USHORT bh, bl;
-
-	bh = ah;
-	bl = al;
-	if (dl != 0) {
-		temp = bh;
-		bh = dh;
-		dh = temp;
-		if (dl == 1) {
-			temp = bl;
-			bl = dh;
-			dh = temp;
-		} else {
-			temp = bl;
-			bl = bh;
-			bh = temp;
-		}
-	}
-	SiS_SetReg3 (SiS_P3c9, (USHORT) dh);
-	SiS_SetReg3 (SiS_P3c9, (USHORT) bh);
-	SiS_SetReg3 (SiS_P3c9, (USHORT) bl);
-}
-
-void
-SiS_ClearBuffer (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo)
-{
-	PVOID VideoMemoryAddress =
-	    (PVOID) HwDeviceExtension->pjVideoMemoryAddress;
-	ULONG AdapterMemorySize = (ULONG) HwDeviceExtension->ulVideoMemorySize;
-	PUSHORT pBuffer;
-	int i;
-
-	if (SiS_ModeType >= ModeEGA) {
-		if (ModeNo > 0x13) {
-			SiS_SetMemory (VideoMemoryAddress, AdapterMemorySize,
-				       0);
-		} else {
-			pBuffer = VideoMemoryAddress;
-			for (i = 0; i < 0x4000; i++)
-				pBuffer[i] = 0x0000;
-		}
-	} else {
-		pBuffer = VideoMemoryAddress;
-		if (SiS_ModeType == ModeCGA) {
-			for (i = 0; i < 0x4000; i++)
-				pBuffer[i] = 0x0720;
-		} else {
-			for (i = 0; i < 0x4000; i++)
-				pBuffer[i] = 0x0000;
-		}
-	}
-}
-
-void
-SiS_DisplayOn (void)
-{
+   if(ModeNo<=0x13) {
+     	index = SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
+   } else {
+     	if(SiS_ModeType <= 0x02) index=0x1B;    /* 02 -> ModeEGA  */
+     	else index=0x0F;
+   }
+   return index;       /* Get SiS_StandTable index  */
+}
+
+void
+SiS_SetSeqRegs(ULONG ROMAddr,USHORT StandTableIndex)
+{
+   UCHAR SRdata;
+   USHORT i;
+
+   SiS_SetReg1(SiS_P3c4,0x00,0x03);           /* Set SR0  */
+   SRdata=SiS_StandTable[StandTableIndex].SR[0];
+
+   if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+      	if(SiS_VBInfo&SetCRT2ToLCDA) {
+        	SRdata=SRdata|0x01;
+        }
+   }
+
+   if(SiS_IF_DEF_LVDS==1) {
+     if(SiS_IF_DEF_CH7005==1) {
+       if(SiS_VBInfo&SetCRT2ToTV) {
+         if(SiS_VBInfo&SetInSlaveMode) {
+           SRdata=SRdata|0x01;        					/* 8 dot clock  */
+         }
+       }
+     }
+     if(SiS_VBInfo&SetCRT2ToLCD) {
+       if(SiS_VBInfo&SetInSlaveMode) {
+         SRdata=SRdata|0x01;          					/* 8 dot clock  */
+       }
+     }
+   }
+
+   SRdata=SRdata|0x20;                					/* screen off  */
+   SiS_SetReg1(SiS_P3c4,0x01,SRdata);         				/* Set SR1 */
+   for(i=02;i<=04;i++) {
+     	SRdata=SiS_StandTable[StandTableIndex].SR[i-1];   		/* Get SR2,3,4 from file */
+     	SiS_SetReg1(SiS_P3c4,i,SRdata);                       		/* Set SR2 3 4 */
+   }
+}
+
+void
+SiS_SetMiscRegs(ULONG ROMAddr,USHORT StandTableIndex)
+{
+   UCHAR Miscdata;
+
+   Miscdata = SiS_StandTable[StandTableIndex].MISC;    /* Get Misc from file */
+   if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))) {
+      if(SiS_VBInfo&SetCRT2ToLCDA) {
+        Miscdata=Miscdata|0x0C;
+      }
+    }
+   SiS_SetReg3(SiS_P3c2,Miscdata);                         /* Set Misc(3c2) */
+}
+
+void
+SiS_SetCRTCRegs(ULONG ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                USHORT StandTableIndex)
+{
+  UCHAR CRTCdata;
+  USHORT i;
+
+  CRTCdata=(UCHAR)SiS_GetReg1(SiS_P3d4,0x11);
+  CRTCdata=CRTCdata&0x7f;
+  SiS_SetReg1(SiS_P3d4,0x11,CRTCdata);                     /* Unlock CRTC */
+
+  for(i=0;i<=0x18;i++) {
+     CRTCdata=SiS_StandTable[StandTableIndex].CRTC[i];     /* Get CRTC from file */
+     SiS_SetReg1(SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
+  }
+  if((HwDeviceExtension->jChipType==SIS_630)&&
+     (HwDeviceExtension->jChipRevision==0x30)) {           /* for 630S0 */
+    if(SiS_VBInfo&SetInSlaveMode) {
+      if(SiS_VBInfo&(SetCRT2ToLCD|SetCRT2ToTV)) {
+        SiS_SetReg1(SiS_P3d4,0x18,0xFE);
+      }
+    }
+  }
+}
+
+void
+SiS_SetATTRegs(ULONG ROMAddr,USHORT StandTableIndex)
+{
+   UCHAR ARdata;
+   USHORT i;
+
+   for(i=0;i<=0x13;i++) {
+    ARdata = SiS_StandTable[StandTableIndex].ATTR[i];     /* Get AR for file  */
+    if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+      if(SiS_VBInfo&SetCRT2ToLCDA) {
+         if(i==0x13) ARdata=0;
+      }
+    }
+    if (SiS_IF_DEF_LVDS==1) {                             /*for LVDS  */
+       if(SiS_IF_DEF_CH7005==1) {
+         if(SiS_VBInfo&SetCRT2ToTV) {
+           if(SiS_VBInfo&SetInSlaveMode) {
+             if(i==0x13) ARdata=0;
+           }
+         }
+       }
+       if(SiS_VBInfo&SetCRT2ToLCD) {
+         if(SiS_VBInfo&SetInSlaveMode) {
+           if(SiS_LCDInfo&LCDNonExpanding) {
+             if(i==0x13) ARdata=0;
+           }
+         }
+       }
+     }
+     SiS_GetReg2(SiS_P3da);                              /* reset 3da  */
+     SiS_SetReg3(SiS_P3c0,i);                            /* set index  */
+     SiS_SetReg3(SiS_P3c0,ARdata);                       /* set data   */
+   }
+   SiS_GetReg2(SiS_P3da);                                /* reset 3da  */
+   SiS_SetReg3(SiS_P3c0,0x14);                           /* set index  */
+   SiS_SetReg3(SiS_P3c0,0x00);                           /* set data   */
+
+   SiS_GetReg2(SiS_P3da);                                /* Enable Attribute  */
+   SiS_SetReg3(SiS_P3c0,0x20);
+}
+
+void
+SiS_SetGRCRegs(ULONG ROMAddr,USHORT StandTableIndex)
+{
+   UCHAR GRdata;
+   USHORT i;
+
+   for(i=0;i<=0x08;i++) {
+     GRdata = SiS_StandTable[StandTableIndex].GRC[i]; 	  /* Get GR from file */
+     SiS_SetReg1(SiS_P3ce,i,GRdata);                      /* Set GR(3ce) */
+   }
+
+   if(SiS_ModeType>ModeVGA) {
+     GRdata=(UCHAR)SiS_GetReg1(SiS_P3ce,0x05);
+     GRdata=GRdata&0xBF;                                  /* 256 color disable */
+     SiS_SetReg1(SiS_P3ce,0x05,GRdata);
+   }
+}
+
+void
+SiS_ClearExt1Regs()
+{
+  USHORT i;
+
+  for(i=0x0A;i<=0x0E;i++) SiS_SetReg1(SiS_P3c4,i,0x00);      /* Clear SR0A-SR0E */
+}
+
+void
+SiS_SetSync(ULONG ROMAddr,USHORT RefreshRateTableIndex)
+{
+  USHORT sync;
+  USHORT temp;
+
+  sync = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;  /* di+0x00 */
+
+  sync=sync&0xC0;
+  temp=0x2F;
+  temp=temp|sync;
+  SiS_SetReg3(SiS_P3c2,temp);                                 /* Set Misc(3c2) */
+}
+
+void
+SiS_SetCRT1CRTC(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex)
+{
+  UCHAR  index;
+  UCHAR  data;
+  USHORT temp,tempah,i,modeflag,j;
+  USHORT ResInfo,DisplayType;
+  SiS_LCDACRT1DataStruct *LCDACRT1Ptr=NULL;
+
+  if((SiS_VBType&VB_SIS302B)&&(SiS_VBInfo&SetCRT2ToLCDA)
+  	&& (SiS_IF_DEF_LVDS==0) ) { /* TW: Added LVDS check */
+     /*add crt1ptr*/
+     if(ModeNo<=0x13) {
+       modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+     } else {
+       modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+     }
+     temp= SiS_GetLCDACRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                       &ResInfo,&DisplayType);
+  
+     switch(DisplayType) {
+      case 0 : LCDACRT1Ptr = SiS_LCDACRT1800x600_1;           break;
+      case 1 : LCDACRT1Ptr = SiS_LCDACRT11024x768_1;          break;
+      case 2 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_1;         break;
+      case 3 : LCDACRT1Ptr = SiS_LCDACRT1800x600_1_H;         break;
+      case 4 : LCDACRT1Ptr = SiS_LCDACRT11024x768_1_H;        break;
+      case 5 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_1_H;       break;
+      case 6 : LCDACRT1Ptr = SiS_LCDACRT1800x600_2;           break;
+      case 7 : LCDACRT1Ptr = SiS_LCDACRT11024x768_2;          break;
+      case 8 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_2;         break;
+      case 9 : LCDACRT1Ptr = SiS_LCDACRT1800x600_2_H;         break;
+      case 10: LCDACRT1Ptr = SiS_LCDACRT11024x768_2_H;        break;
+      case 11: LCDACRT1Ptr = SiS_LCDACRT11280x1024_2_H;       break;
+      /*case 12: LCDACRT1Ptr = SiS_CHTVCRT1UNTSC;             break;
+      case 13: LCDACRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
+      case 14: LCDACRT1Ptr = SiS_CHTVCRT1UPAL;                break;
+      case 15: LCDACRT1Ptr = SiS_CHTVCRT1OPAL;                break;*/
+     }
+
+     tempah=(UCHAR)SiS_GetReg1(SiS_P3d4,0x11);                        /*unlock cr0-7  */
+     tempah=tempah&0x7F;
+     SiS_SetReg1(SiS_P3d4,0x11,tempah);
+     tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
+     SiS_SetReg1(SiS_P3d4,0x0,tempah);
+     for(i=0x01,j=1;i<=0x07;i++,j++){
+       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3d4,i,tempah);
+     }
+     /* for(i=0x06,j=5;i<=0x07;i++,j++){
+       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3d4,i,tempah);
+     }*/
+     for(i=0x10,j=8;i<=0x12;i++,j++){
+       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3d4,i,tempah);
+     }
+     for(i=0x15,j=11;i<=0x16;i++,j++){
+       tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3d4,i,tempah);
+     }
+     for(i=0x0A,j=13;i<=0x0C;i++,j++){
+       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+       SiS_SetReg1(SiS_P3c4,i,tempah);
+     }
+  
+     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
+     tempah=tempah&0x0E0;
+     SiS_SetReg1(SiS_P3c4,0x0E,tempah);
+  
+     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
+     tempah=tempah&0x01;
+     tempah=tempah<<5;
+     if(modeflag&DoubleScanMode){
+       tempah=tempah|0x080;
+     }
+     SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
+     if(SiS_ModeType>0x03) SiS_SetReg1(SiS_P3d4,0x14,0x4F);
+  /*end 301b*/
+  }
+  else {  /* LVDS */
+     index=SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;  		/* Get index */
+     index=index&0x3F;
+
+     if(SiS_IF_DEF_FSTN) {						/*fstn*/
+        index=index&0x7F;	/* TW: First AND it with 3F, now with 7F ??? */
+     }
+     data=(UCHAR)SiS_GetReg1(SiS_P3d4,0x11);
+     data=data&0x7F;
+     SiS_SetReg1(SiS_P3d4,0x11,data);                             	/* Unlock CRTC */
+
+     for(i=0,j=0;i<=07;i++,j++) {
+       data=SiS_CRT1Table[index].CR[i];
+       SiS_SetReg1(SiS_P3d4,j,data);
+     }
+     for(j=0x10;i<=10;i++,j++) {
+       data=SiS_CRT1Table[index].CR[i];
+       SiS_SetReg1(SiS_P3d4,j,data);
+     }
+     for(j=0x15;i<=12;i++,j++) {
+       data=SiS_CRT1Table[index].CR[i];
+       SiS_SetReg1(SiS_P3d4,j,data);
+     }
+     for(j=0x0A;i<=15;i++,j++) {
+       data=SiS_CRT1Table[index].CR[i];
+       SiS_SetReg1(SiS_P3c4,j,data);
+     }
+
+     data=SiS_CRT1Table[index].CR[16];
+     data=data&0xE0;
+     SiS_SetReg1(SiS_P3c4,0x0E,data);
+
+     data=(UCHAR)SiS_GetReg1(SiS_P3d4,0x09);
+     data=data&0xDF;                                      /* clear CR9 D[5] */
+     i=SiS_CRT1Table[index].CR[16];
+     i=i&0x01;
+     i=i<<5;
+     data=data|i;
+
+     if (ModeNo<=0x13)
+       i = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     else
+       i = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+     i=i&DoubleScanMode;
+     if(i) data=data|0x80;
+     SiS_SetReg1(SiS_P3d4,0x09,data);
+
+     if(SiS_ModeType>0x03) SiS_SetReg1(SiS_P3d4,0x14,0x4F);
+  }
+}
+
+/* TW: Set offset ("pitch") - overruled by SetPitch in XF86 */
+void
+SiS_SetCRT1Offset(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                  USHORT RefreshRateTableIndex,
+		  PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+   USHORT temp,ah,al;
+   USHORT temp2,i;
+   USHORT DisplayUnit;
+
+   /* Alan */
+   temp = SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+     temp=temp>>8;         /* sis310 */
+   } else {
+     temp=temp>>4;         /* sis300 */
+   }
+   temp=SiS_ScreenOffset[temp];
+
+   if((ModeNo>=0x7C)&&(ModeNo<=0x7E)) {
+     /* TW: 1280x960 */
+     temp=0x6B;  /* TW: Why? Offset for 1280 is normally 0x50! */
+     temp2=ModeNo-0x7C;
+     /* TW: SiS_ModeType-ModeEGA (below) is 1,3 or 5, not 0,1,or 2 */
+     temp2=(temp2*2)+1; /* TW: Maybe this is more correct? */
+   }
+   else {
+     temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+     temp2=temp2&InterlaceMode;
+     if(temp2) temp=temp<<1;
+     temp2=SiS_ModeType-ModeEGA;
+   }
+
+   switch (temp2) {
+     case 0 : temp2=1; break;
+     case 1 : temp2=2; break;
+     case 2 : temp2=4; break;
+     case 3 : temp2=4; break;
+     case 4 : temp2=6; break;
+     case 5 : temp2=8; break;
+   }
+   temp=temp*temp2;
+   DisplayUnit=temp;
+
+   temp2=temp;
+   temp=temp>>8;                                         /* ah */
+   temp=temp&0x0F;
+   i=SiS_GetReg1(SiS_P3c4,0x0E);
+   i=i&0xF0;
+   i=i|temp;
+   SiS_SetReg1(SiS_P3c4,0x0E,i);
+
+   temp=(UCHAR)temp2;
+   temp=temp&0xFF;                                        /* al */
+   SiS_SetReg1(SiS_P3d4,0x13,temp);
+
+   temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+   temp2=temp2&InterlaceMode;
+   if(temp2) DisplayUnit>>=1;
+
+   DisplayUnit=DisplayUnit<<5;
+   ah=(DisplayUnit&0xff00)>>8;
+   al=DisplayUnit&0x00ff;
+   if(al==0) ah=ah+1;
+   else ah=ah+2;
+   SiS_SetReg1(SiS_P3c4,0x10,ah);
+}
+
+void
+SiS_SetCRT1VCLK(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                PSIS_HW_DEVICE_INFO HwDeviceExtension,
+		USHORT RefreshRateTableIndex)
+{
+  UCHAR  index,data;
+  USHORT vclkindex;
+
+  /* TW: Now I'm confused. Is IF_DEF_LVDS 1 even for 301B/302B/301LV/302lV?
+   *     This functions could make one believe that LVDS is 0 for these. But
+   *     in this case SetGroup1_LVDS doesn't make sense (see init301.c)
+   *     So my conclusion is that LVDS = 1 for some of the SiS bridges as
+   *     well, i just don't know which ones...
+   */
+
+  if(SiS_IF_DEF_LVDS==1) {
+
+        /* TW: Do this if IF_DEF_LVDS is 1 */
+
+    	index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+
+    	/*if(HwDeviceExtension->jChipType < SIS_315H) { */
+    	index=index&0x3F;
+    	/*}*/
+    	data = SiS_GetReg1(SiS_P3c4,0x31) & 0xCF;
+	SiS_SetReg1(SiS_P3c4,0x31,data);
+	/* SiS_SetReg1(SiS_P3c4,0x31,0x00); 	     */                 /* for300 */
+
+    	SiS_SetReg1(SiS_P3c4,0x2B,SiS_VCLKData[index].SR2B);
+    	SiS_SetReg1(SiS_P3c4,0x2C,SiS_VCLKData[index].SR2C);
+	
+    	if(HwDeviceExtension->jChipType < SIS_315H)
+      		SiS_SetReg1(SiS_P3c4,0x2D,0x80);                        /* for300 series */
+   	else
+      		SiS_SetReg1(SiS_P3c4,0x2D,0x01);                        /* for310 series */
+  }
+
+  else if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+               && (SiS_VBInfo&SetCRT2ToLCDA)
+	       && (SiS_IF_DEF_LVDS==0) ){  /* TW: I did NOT include this here */
+
+        /* TW: Do this if bridge type is 301B/302B/301LV/302LV
+	 *     (This can only be called if LVDS is 0...)
+	 */
+	 
+    	vclkindex = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+	                     RefreshRateTableIndex,HwDeviceExtension);
+    	data = SiS_GetReg1(SiS_P3c4,0x31) & 0xCF;
+    	SiS_SetReg1(SiS_P3c4,0x31,data);
+
+    	data = SiS_VBVCLKData[vclkindex].Part4_A;
+    	SiS_SetReg1(SiS_P3c4,0x2B,data);
+    	data = SiS_VBVCLKData[vclkindex].Part4_B;
+    	SiS_SetReg1(SiS_P3c4,0x2C,data);
+
+    	if(HwDeviceExtension->jChipType < SIS_315H)
+    		SiS_SetReg1(SiS_P3c4,0x2D,0x80);                        /* for300 series */
+    	else
+    		SiS_SetReg1(SiS_P3c4,0x2D,0x01);
+  }
+  else {
+
+	/* TW: Do this if LVDS is 0 and the brigde type is NOT
+	 *     301B/302B/301LV/302LV. This leaves only 301...
+	 *     (or 301B/.. if not LCDA)
+	 */
 
-	SiS_SetRegANDOR (SiS_P3c4, 0x01, 0xDF, 0x00);
+    	index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+    	/*if(HwDeviceExtension->jChipType < SIS_315H) { */
+    	index=index&0x3F;
+    	/*}*/
+    	data = SiS_GetReg1(SiS_P3c4,0x31) & 0xCF;
+	SiS_SetReg1(SiS_P3c4,0x31,data);
+	/*SiS_SetReg1(SiS_P3c4,0x31,0x00); */                       	/* for300 */
+
+    	SiS_SetReg1(SiS_P3c4,0x2B,SiS_VCLKData[index].SR2B);
+    	SiS_SetReg1(SiS_P3c4,0x2C,SiS_VCLKData[index].SR2C);
+    	if(HwDeviceExtension->jChipType < SIS_315H)
+      		SiS_SetReg1(SiS_P3c4,0x2D,0x80);                        /* for300 series */
+    	else
+      		SiS_SetReg1(SiS_P3c4,0x2D,0x01);                        /* for310 series */
+  }
+}
+
+void
+SiS_IsLowResolution(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT data;
+  USHORT ModeFlag;
+
+  data = SiS_GetReg1(SiS_P3c4,0x0F);
+  data = data&0x7F;
+  SiS_SetReg1(SiS_P3c4,0x0F,data);
+
+  if (ModeNo>0x13) {
+    ModeFlag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
+      data = SiS_GetReg1(SiS_P3c4,0x0F);
+      data = data|0x80;
+      SiS_SetReg1(SiS_P3c4,0x0F,data);
+      data = SiS_GetReg1(SiS_P3c4,0x01);
+      data = data&0xF7;
+      SiS_SetReg1(SiS_P3c4,0x01,data);
+    }
+  }
+}
+
+void
+SiS_SetCRT1ModeRegs(ULONG ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                    USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
+{
+  USHORT data,data2,data3;
+  USHORT infoflag=0,modeflag;
+  USHORT resindex,xres;
+
+  if (ModeNo>0x13) {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  } else {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;    /* si+St_ModeFlag */
+  }
+
+  SiS_SetRegANDOR(SiS_P3c4,0x1F,0x3F,0x00); 	/* DAC pedestal */
+
+  if(ModeNo>0x13) data=infoflag;
+  else data=0;
+  data2=SiS_GetReg1(SiS_P3c4,0x06) & 0xC0;  /* TW: Preserve Xv display mode!!! */
+  if(ModeNo>0x13) {
+    if(SiS_ModeType>0x02) {
+       data2=data2|0x02;
+       data3=SiS_ModeType-ModeVGA;
+       data3=data3<<2;
+       data2=data2|data3;
+    }
+  }
+  data=data&InterlaceMode;
+  if(data) data2=data2|0x20;
+  SiS_SetReg1(SiS_P3c4,0x06,data2);
+
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_540)||
+     (HwDeviceExtension->jChipType==SIS_730)) {
+    resindex=SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
+    if(ModeNo<=0x13)
+      	xres=SiS_StResInfo[resindex].HTotal;
+    else
+      	xres=SiS_ModeResInfo[resindex].HTotal;                         /* xres->ax */
+    data=0x0000;
+    if(infoflag&InterlaceMode) {
+      if(xres==1024) data=0x0035;
+      if(xres==1280) data=0x0048;
+    }
+    data2=data&0x00FF;
+    SiS_SetRegANDOR(SiS_P3d4,0x19,0xFF,data2);
+    data2=(data&0xFF00)>>8;
+    SiS_SetRegANDOR(SiS_P3d4,0x19,0xFC,data2);
+  }
+
+  if(modeflag&HalfDCLK) {
+    SiS_SetRegANDOR(SiS_P3c4,0x01,0xFF,0x01);
+  }
+
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_540)||
+     (HwDeviceExtension->jChipType==SIS_730)){
+     /* TW: This was missing here for modes > 1024x768: */
+    if(modeflag&LineCompareOff) {
+      SiS_SetRegANDOR(SiS_P3c4,0x0F,0xF7,0x08);
+    } else {
+      SiS_SetRegANDOR(SiS_P3c4,0x0F,0xF7,0x00);
+    }
+  } else {
+    if(modeflag&LineCompareOff) {
+      SiS_SetRegANDOR(SiS_P3c4,0x0F,0xF7,0x08);
+    } else {
+      SiS_SetRegANDOR(SiS_P3c4,0x0F,0xF7,0x00);
+    }
+  }
+
+  data=0x60;
+  if(SiS_ModeType!=ModeText) {
+      data=data^0x60;
+      if(SiS_ModeType!=ModeEGA) {
+        data=data^0xA0;
+      }
+  }
+  SiS_SetRegANDOR(SiS_P3c4,0x21,0x1F,data);
+}
+
+void
+SiS_SetVCLKState(ULONG ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                 USHORT ModeNo,USHORT RefreshRateTableIndex)
+{
+   USHORT data,data2=0;
+   USHORT VCLK;
+   UCHAR  index=0;
+
+  if (ModeNo<=0x13) VCLK=0;
+  else {
+    index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+    /*if(HwDeviceExtension->jChipType < SIS_315H) { */
+    index=index&0x3F;
+    /*}*/
+    VCLK = SiS_VCLKData[index].CLOCK;
+  }
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+    data2=0x00;
+    if(VCLK>150) data2=data2|0x80;
+    SiS_SetRegANDOR(SiS_P3c4,0x07,0x7B,data2); 	/* DAC speed */
+
+    data2=0x00;
+    if(VCLK>=150) data2=data2|0x08;       	/* VCLK > 150 */
+    SiS_SetRegANDOR(SiS_P3c4,0x32,0xF7,data2);
+  } else { /* 310 series */
+    data=SiS_GetReg1(SiS_P3c4,0x32);
+    data=data&0xf3;
+    if(VCLK>=200) data=data|0x0c;         	/* VCLK > 200 */
+    SiS_SetReg1(SiS_P3c4,0x32,data);
+    data=SiS_GetReg1(SiS_P3c4,0x1F);	  	/* DAC pedestal */
+    data &= 0xE7;
+    if(VCLK<200) data |= 0x10;
+    SiS_SetReg1(SiS_P3c4,0x1F,data);	  	/* DAC pedestal */
+  }
+
+  if(VCLK<135) data2=0x03;
+  if((VCLK>=135)&&(VCLK<160)) data2=0x02;
+  if((VCLK>=160)&&(VCLK<260)) data2=0x01;
+  if(VCLK>260) data2=0x00;
+  /* disable 24bit palette RAM gamma correction  */
+  if(HwDeviceExtension->jChipType==SIS_540) {
+    	if((VCLK==203)||(VCLK<234)) data2=0x02;
+  }
+  SiS_SetRegANDOR(SiS_P3c4,0x07,0xFC,data2);  	/* DAC speed */
+}
+
+void
+SiS_LoadDAC(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+   USHORT data,data2;
+   USHORT time,i,j,k;
+   USHORT m,n,o;
+   USHORT si,di,bx,dl;
+   USHORT al,ah,dh;
+   USHORT *table=NULL;
+
+   if (ModeNo<=0x13)
+        data = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   else
+        data = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+   data=data&DACInfoFlag;
+   time=64;
+   if(data==0x00) table=SiS_MDA_DAC;
+   if(data==0x08) table=SiS_CGA_DAC;
+   if(data==0x10) table=SiS_EGA_DAC;
+   if(data==0x18) {
+     time=256;
+     table=SiS_VGA_DAC;
+   }
+   if(time==256) j=16;
+   else j=time;
+
+   SiS_SetReg3(SiS_P3c6,0xFF);
+   SiS_SetReg3(SiS_P3c8,0x00);
+
+   for(i=0;i<j;i++) {
+      data=table[i];
+      for(k=0;k<3;k++) {
+        data2=0;
+        if(data&0x01) data2=0x2A;
+        if(data&0x02) data2=data2+0x15;
+        SiS_SetReg3(SiS_P3c9,data2);
+        data=data>>2;
+      }
+   }
+
+   if(time==256) {
+      for(i=16;i<32;i++) {
+         data=table[i];
+         for(k=0;k<3;k++) SiS_SetReg3(SiS_P3c9,data);
+      }
+      si=32;
+      for(m=0;m<9;m++) {
+         di=si;
+         bx=si+0x04;
+         dl=0;
+         for(n=0;n<3;n++) {
+            for(o=0;o<5;o++) {
+              dh=table[si];
+              ah=table[di];
+              al=table[bx];
+              si++;
+              SiS_WriteDAC(dl,ah,al,dh);
+            }         /* for 5 */
+            si=si-2;
+            for(o=0;o<3;o++) {
+              dh=table[bx];
+              ah=table[di];
+              al=table[si];
+              si--;
+              SiS_WriteDAC(dl,ah,al,dh);
+            }         /* for 3 */
+            dl++;
+         }            /* for 3 */
+         si=si+5;
+      }               /* for 9 */
+   }
+}
+
+void
+SiS_WriteDAC(USHORT dl, USHORT ah, USHORT al, USHORT dh)
+{
+  USHORT temp;
+  USHORT bh,bl;
+
+  bh=ah;
+  bl=al;
+  if(dl!=0) {
+    temp=bh;
+    bh=dh;
+    dh=temp;
+    if(dl==1) {
+       temp=bl;
+       bl=dh;
+       dh=temp;
+    } else {
+       temp=bl;
+       bl=bh;
+       bh=temp;
+    }
+  }
+  SiS_SetReg3(SiS_P3c9,(USHORT)dh);
+  SiS_SetReg3(SiS_P3c9,(USHORT)bh);
+  SiS_SetReg3(SiS_P3c9,(USHORT)bl);
+}
+
+ULONG
+GetDRAMSize(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  ULONG   AdapterMemorySize=0;
+#ifdef SIS315H
+  USHORT  counter;
+#endif
+  
+#ifdef SIS315H
+  if ((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315PRO)) {
+    	counter = SiS_GetReg1(SiS_P3c4,0x14)&0xF0; 	/*get memory size*/
+    	counter >>= 4;
+    	AdapterMemorySize= 1 << counter;
+    	AdapterMemorySize *= 1024*1024;
+  } else {
+    	if ((HwDeviceExtension->jChipType == SIS_550)||
+            (HwDeviceExtension->jChipType == SIS_640)||
+            (HwDeviceExtension->jChipType == SIS_740)||
+            (HwDeviceExtension->jChipType == SIS_650)) {
+      		counter = SiS_GetReg1(SiS_P3c4,0x14)&0x3F; /*get memory size*/
+      		counter++;
+      		AdapterMemorySize = counter * 4;
+      		AdapterMemorySize *= 1024*1024;
+		/* TW: FIXME: Some 550 BIOSes don't set up SR14 correctly. We
+		 * will have to read PCI configuration for a correct memory
+		 * size. (However, this is checked in framebuffer driver;
+		 * X does not use this function but if it ever will, this will
+		 * become an issue.)
+		 */
+    	}
+  }
+#endif
+
+#ifdef SIS300
+  if ((HwDeviceExtension->jChipType==SIS_300)||
+      (HwDeviceExtension->jChipType==SIS_540)||
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)) {
+      	AdapterMemorySize = SiS_GetReg1(SiS_P3c4,0x14); /*get memory size*/
+      	AdapterMemorySize = AdapterMemorySize&0x3F;
+      	AdapterMemorySize++;
+      	AdapterMemorySize *= 1024*1024;
+  }
+#endif
+
+  return AdapterMemorySize;
+}
+
+void
+SiS_ClearBuffer(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+{
+  PVOID   VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress;
+  ULONG   AdapterMemorySize  = (ULONG)HwDeviceExtension->ulVideoMemorySize;
+  PUSHORT pBuffer;
+  int i;
+
+  if (SiS_ModeType>=ModeEGA) {
+    if (ModeNo>0x13) {
+      AdapterMemorySize=GetDRAMSize(HwDeviceExtension);
+      SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
+    } else {
+      pBuffer = VideoMemoryAddress;
+      for (i=0;i<0x4000;i++)
+        pBuffer[i]=0x0000;
+    }
+  } else {
+    pBuffer = VideoMemoryAddress;
+    if (SiS_ModeType<ModeCGA) {
+      for (i=0;i<0x4000;i++)
+        pBuffer[i]=0x0720;
+    } else {
+      SiS_SetMemory(VideoMemoryAddress,0x8000,0);
+    }
+  }
+}
+
+void
+SiS_DisplayOn(void)
+{
+   SiS_SetRegANDOR(SiS_P3c4,0x01,0xDF,0x00);
 }
 
 void
-SiS_DisplayOff (void)
+SiS_DisplayOff(void)
 {
-
-	SiS_SetRegANDOR (SiS_P3c4, 0x01, 0xDF, 0x20);
+   SiS_SetRegANDOR(SiS_P3c4,0x01,0xDF,0x20);
 }
 
+
 /* ========================================== */
 /*  SR CRTC GR */
 void
-SiS_SetReg1 (USHORT port, USHORT index, USHORT data)
-{
-	OutPortByte (port, index);
-	OutPortByte (port + 1, data);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      
-	   mov      ax, index                     
-	   mov      bx, data                      
-	   out      dx, al
-	   mov      ax, bx
-	   inc      dx
-	   out      dx, al
-	   }
-	 */
+SiS_SetReg1(
+   USHORT  port,
+   USHORT  index,
+   USHORT  data
+   )
+{
+   OutPortByte(port,index);
+   OutPortByte(port+1,data);
+   
+   /*
+   _asm
+   {
+         mov      dx, port                      
+         mov      ax, index                     
+         mov      bx, data                      
+         out      dx, al
+         mov      ax, bx
+         inc      dx
+         out      dx, al
+   }
+   */
 
 }
 
 /* ========================================== */
 /*  AR(3C0) */
 void
-SiS_SetReg2 (USHORT port, USHORT index, USHORT data)
-{
-
-	InPortByte (port + 0x3da - 0x3c0);
-	OutPortByte (SiS_P3c0, index);
-	OutPortByte (SiS_P3c0, data);
-	OutPortByte (SiS_P3c0, 0x20);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      
-	   mov      cx, index                     
-	   mov      bx, data                      
-
-	   add      dx, 3dah-3c0h
-	   in       al, dx
-
-	   mov      ax, cx
-	   mov      dx, 3c0h
-	   out      dx, al
-	   mov      ax, bx
-	   out      dx, al
-
-	   mov      ax, 20h
-	   out      dx, al
-	   }
-	 */
+SiS_SetReg2(
+   USHORT  port,
+   USHORT  index,
+   USHORT  data
+   )
+{
+
+   InPortByte(port+0x3da-0x3c0);
+   OutPortByte(SiS_P3c0,index);
+   OutPortByte(SiS_P3c0,data);
+   OutPortByte(SiS_P3c0,0x20);
+
+   /*
+   _asm
+   {
+         mov      dx, port                      
+         mov      cx, index                     
+         mov      bx, data                      
+
+         add      dx, 3dah-3c0h
+         in       al, dx
+
+         mov      ax, cx
+         mov      dx, 3c0h
+         out      dx, al
+         mov      ax, bx
+         out      dx, al
+
+         mov      ax, 20h
+         out      dx, al
+   }
+   */
 
 }
 
 /* ========================================== */
 void
-SiS_SetReg3 (USHORT port, USHORT data)
-{
-
-	OutPortByte (port, data);
+SiS_SetReg3(
+   USHORT  port,
+   USHORT  data
+   )
+{
+
+   OutPortByte(port,data);
+   
+   /*
+   _asm
+   {
+         mov      dx, port                      
+         mov      ax, data                      
+         out      dx, al
 
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      
-	   mov      ax, data                      
-	   out      dx, al
-
-	   }
-	 */
+   }
+   */
 
 }
 
 /* ========================================== */
 void
-SiS_SetReg4 (USHORT port, ULONG data)
-{
+SiS_SetReg4(
+   USHORT  port,
+   ULONG   data
+   )
+{
+
+   OutPortLong(port,data);
+
+   /*
+   _asm
+   {
+         mov      dx, port                      ;; port
+         mov      eax, data                      ;; data
+         out      dx, eax
 
-	OutPortLong (port, data);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      ;; port
-	   mov      eax, data                      ;; data
-	   out      dx, eax
-
-	   }
-	 */
+   }
+   */
 }
 
 /* ========================================= */
-UCHAR SiS_GetReg1 (USHORT port, USHORT index)
-{
-	UCHAR data;
-
-	OutPortByte (port, index);
-	data = InPortByte (port + 1);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      ;; port
-	   mov      ax, index                     ;; index
-
-	   out      dx, al
-	   mov      ax, bx
-	   inc      dx
-	   xor      eax, eax
-	   in       al, dx
-	   mov      data, al
-	   }
-	 */
-	return (data);
+UCHAR
+SiS_GetReg1(
+   USHORT  port,
+   USHORT  index
+   )
+{
+   UCHAR   data;
+
+
+   OutPortByte(port,index);
+   data = InPortByte(port+1);
+
+   /*
+   _asm
+   {
+         mov      dx, port                      ;; port
+         mov      ax, index                     ;; index
+
+         out      dx, al
+         mov      ax, bx
+         inc      dx
+         xor      eax, eax
+         in       al, dx
+         mov      data, al
+   }
+   */
+   return(data);
 }
-
 /* ========================================== */
-UCHAR SiS_GetReg2 (USHORT port)
-{
-	UCHAR data;
-
-	data = InPortByte (port);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      ;; port
-	   xor      eax, eax
-	   in       al, dx
-	   mov      data, al
-	   }
-	 */
-	return (data);
+UCHAR
+SiS_GetReg2(
+   USHORT  port
+   )
+{
+   UCHAR   data;
+
+   data= InPortByte(port);
+
+   /*
+   _asm
+   {
+         mov      dx, port                      ;; port
+         xor      eax, eax
+         in       al, dx
+         mov      data, al
+   }
+   */
+   return(data);
 }
 
 /* ========================================== */
-ULONG SiS_GetReg3 (USHORT port)
-{
-	ULONG data;
-
-	data = InPortLong (port);
-
-	/*
-	   _asm
-	   {
-	   mov      dx, port                      ;; port
-	   xor      eax, eax
-	   in       eax, dx
-	   mov      data, eax
-	   }
-	 */
-	return (data);
+ULONG
+SiS_GetReg3(
+   USHORT  port
+   )
+{
+   ULONG   data;
+
+
+   data = InPortLong(port);
+
+   /*
+   _asm
+   {
+         mov      dx, port                      ;; port
+         xor      eax, eax
+         in       eax, dx
+         mov      data, eax
+   }
+   */
+   return(data);
 }
 
 /* ========================================== */
 void
-SiS_ClearDAC (ULONG port)
+SiS_ClearDAC(ULONG   port)
 {
-	int i;
+   int i;
 
-	OutPortByte (port, 0);
-	port++;
-	for (i = 0; i < 256 * 3; i++) {
-		OutPortByte (port, 0);
-	}
+   OutPortByte(port, 0);
+   port++;
+   for (i=0;i<256*3;i++) {
+      OutPortByte(port, 0);
+   }
 
 }
-
-/*========================================== */
+/* ========================================== */
 
 void
-SiS_SetInterlace (ULONG ROMAddr, USHORT ModeNo, USHORT RefreshRateTableIndex)
+SiS_SetInterlace(ULONG ROMAddr, USHORT ModeNo,USHORT RefreshRateTableIndex)
 {
-	ULONG Temp;
-	USHORT data, Temp2;
-
-	Temp = (ULONG) SiS_GetReg1 (SiS_P3d4, 0x01);
-	Temp++;
-	Temp = Temp * 8;
+  ULONG Temp;
+  USHORT data,Temp2;
 
-	if (Temp == 1024)
-		data = 0x0035;
-	else if (Temp == 1280)
-		data = 0x0048;
-	else
-		data = 0x0000;
-
-	Temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	Temp2 &= InterlaceMode;
-	if (Temp2 == 0)
-		data = 0x0000;
-
-	SiS_SetReg1 (SiS_P3d4, 0x19, data);
-
-	Temp = (ULONG) SiS_GetReg1 (SiS_P3d4, 0x1A);
-	Temp2 = (USHORT) (Temp & 0xFC);
-	SiS_SetReg1 (SiS_P3d4, 0x1A, (USHORT) Temp);
-
-	Temp = (ULONG) SiS_GetReg1 (SiS_P3c4, 0x0f);
-	Temp2 = (USHORT) Temp & 0xBF;
-	if (ModeNo == 0x37)
-		Temp2 = Temp2 | 0x40;
-	SiS_SetReg1 (SiS_P3d4, 0x1A, (USHORT) Temp2);
+  if (ModeNo<=0x13) return;
+  Temp = (ULONG)SiS_GetReg1(SiS_P3d4, 0x01);
+  Temp++;
+  Temp=Temp*8;
+
+  if(Temp==1024) data=0x0035;
+  else if(Temp==1280) data=0x0048;
+  else data=0x0000;
+
+  Temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  Temp2 &= InterlaceMode;
+  if(Temp2 == 0) data=0x0000;
+
+  SiS_SetReg1(SiS_P3d4,0x19,data);
+
+  Temp = (ULONG)SiS_GetReg1(SiS_P3d4, 0x1A);
+  Temp2= (USHORT)(Temp & 0xFC);
+  SiS_SetReg1(SiS_P3d4,0x1A,(USHORT)Temp);
+
+  Temp = (ULONG)SiS_GetReg1(SiS_P3c4, 0x0f);
+  Temp2= (USHORT)Temp & 0xBF;
+  if(ModeNo==0x37) Temp2=Temp2|0x40;
+  SiS_SetReg1(SiS_P3d4,0x1A,(USHORT)Temp2);
 }
 
 void
-SiS_SetCRT1FIFO (ULONG ROMAddr, USHORT ModeNo,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-
-	USHORT data;
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x3D);
-	data &= 0xfe;
-	SiS_SetReg1 (SiS_P3c4, 0x3D, data);	/* diable auto-threshold */
-	if (ModeNo > 0x13) {
-		SiS_SetReg1 (SiS_P3c4, 0x08, 0x34);
-		data = SiS_GetReg1 (SiS_P3c4, 0x09);
-		data &= 0xF0;
-		SiS_SetReg1 (SiS_P3c4, 0x09, data);
-
-		data = SiS_GetReg1 (SiS_P3c4, 0x3D);
-		data |= 0x01;
-		SiS_SetReg1 (SiS_P3c4, 0x3D, data);
-	} else {
-		SiS_SetReg1 (SiS_P3c4, 0x08, 0xAE);
-		data = SiS_GetReg1 (SiS_P3c4, 0x09);
-		data &= 0xF0;
-		SiS_SetReg1 (SiS_P3c4, 0x09, data);
-	}
-
+SiS_SetCRT1FIFO(ULONG ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT  data;
+
+  data=SiS_GetReg1(SiS_P3c4,0x3D);
+  data &= 0xfe;
+  SiS_SetReg1(SiS_P3c4,0x3D,data);  /* diable auto-threshold */
+  if (ModeNo>0x13) {
+    SiS_SetReg1(SiS_P3c4,0x08,0x34);
+    data=SiS_GetReg1(SiS_P3c4,0x09);
+    data &= 0xF0;
+    SiS_SetReg1(SiS_P3c4,0x09,data);
+
+    data=SiS_GetReg1(SiS_P3c4,0x3D);
+    data |= 0x01;
+    SiS_SetReg1(SiS_P3c4,0x3D,data);
+  } else {
+    SiS_SetReg1(SiS_P3c4,0x08,0xAE);
+    data=SiS_GetReg1(SiS_P3c4,0x09);
+    data &= 0xF0;
+    SiS_SetReg1(SiS_P3c4,0x09,data);
+  }
 }
 
 USHORT
-SiS_CalcDelay (ULONG ROMAddr, USHORT key)
+SiS_CalcDelay(ULONG ROMAddr,USHORT key)
 {
-	USHORT data, data2, temp0, temp1;
-	UCHAR ThLowA[] = { 61, 3, 52, 5, 68, 7, 100, 11,
-		43, 3, 42, 5, 54, 7, 78, 11,
-		34, 3, 37, 5, 47, 7, 67, 11
-	};
-	UCHAR ThLowB[] = { 81, 4, 72, 6, 88, 8, 120, 12,
-		55, 4, 54, 6, 66, 8, 90, 12,
-		42, 4, 45, 6, 55, 8, 75, 12
-	};
-	UCHAR ThTiming[] = { 1, 2, 2, 3, 0, 1, 1, 2 };
-
-	data = SiS_GetReg1 (SiS_P3c4, 0x16);
-	data = data >> 6;
-	data2 = SiS_GetReg1 (SiS_P3c4, 0x14);
-	data2 = (data2 >> 4) & 0x0C;
-	data = data | data2;
-	data = data < 1;
-	if (key == 0) {
-		temp0 = (USHORT) ThLowA[data];
-		temp1 = (USHORT) ThLowA[data + 1];
-	} else {
-		temp0 = (USHORT) ThLowB[data];
-		temp1 = (USHORT) ThLowB[data + 1];
-	}
-
-	data2 = 0;
-	data = SiS_GetReg1 (SiS_P3c4, 0x18);
-	if (data & 0x02)
-		data2 = data2 | 0x01;
-	if (data & 0x20)
-		data2 = data2 | 0x02;
-	if (data & 0x40)
-		data2 = data2 | 0x04;
-
-	data = temp1 * ThTiming[data2] + temp0;
-	return (data);
-}
-
-void
-SiS_SetCRT1FIFO2 (ULONG ROMAddr, USHORT ModeNo,
-		  PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		  USHORT RefreshRateTableIndex)
-{
-	USHORT i, index, data, VCLK, data2, MCLK, colorth = 0;
-	USHORT ah, bl, B;
-	ULONG eax;
-	USHORT ThresholdLow = 0;
-	UCHAR FQBQData[] = { 0x01, 0x21, 0x41, 0x61, 0x81,
-		0x31, 0x51, 0x71, 0x91, 0xb1,
-		0x00, 0x20, 0x40, 0x60, 0x80,
-		0x30, 0x50, 0x70, 0x90, 0xb0, 0xFF
-	};
-
-	if (ModeNo >= 0x13) {
-		index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-		if (HwDeviceExtension->jChipType < SIS_315H) {	/* for300 serial */
-			index = index & 0x3F;
-		}
-		VCLK = SiS_VCLKData[index].CLOCK;	/* Get VCLK  */
-		index = SiS_GetReg1 (SiS_P3c4, 0x1A);
-		index = index & 07;
-		MCLK = SiS_MCLKData[index].CLOCK;	/* Get MCLK  */
-		data2 = SiS_ModeType - 0x02;
-		switch (data2) {
-		case 0:
-			colorth = 1;
-			break;
-		case 1:
-			colorth = 2;
-			break;
-		case 2:
-			colorth = 4;
-			break;
-		case 3:
-			colorth = 4;
-			break;
-		case 4:
-			colorth = 6;
-			break;
-		case 5:
-			colorth = 8;
-			break;
-		}
-
-		i = 0;
-		do {
-			B =
-			    (SiS_CalcDelay2 (ROMAddr, FQBQData[i]) * VCLK *
-			     colorth);
-			bl = B / (16 * MCLK);
-			if (B == bl * 16 * MCLK) {
-				bl = bl + 1;
-			} else {
-				bl = bl + 1;
-			}
-
-			if (bl > 0x13) {
-				if (FQBQData[i + 1] == 0xFF) {
-					ThresholdLow = 0x13;
-					break;
-				}
-				i++;
-			} else {
-				ThresholdLow = bl;
-				break;
-			}
-		} while (FQBQData[i] != 0xFF);
-	} else {
-		ThresholdLow = 0x02;
-	}
-
-	data2 = FQBQData[i];
-	data2 = (data2 & 0xf0) >> 4;
-	data2 = data2 << 24;
-
-	SiS_SetReg4 (0xcf8, 0x80000050);
-	eax = SiS_GetReg3 (0xcfc);
-	eax = eax & 0x0f0ffffff;
-	eax = eax | data2;
-	SiS_SetReg4 (0xcfc, eax);
-
-	ah = ThresholdLow;
-	ah = ah << 4;
-	ah = ah | 0x0f;
-	SiS_SetReg1 (SiS_P3c4, 0x08, ah);
-
-	data = ThresholdLow;
-	data = data & 0x10;
-	data = data << 1;
-	SiS_SetRegANDOR (SiS_P3c4, 0x0F, 0xDF, data);
-	SiS_SetReg1 (SiS_P3c4, 0x3B, 0x09);
-
-	data = ThresholdLow + 3;
-	if (data > 0x0f)
-		data = 0x0f;
-	SiS_SetRegANDOR (SiS_P3c4, 0x09, 0x80, data);
+  USHORT data,data2,temp0,temp1;
+  UCHAR   ThLowA[]=   {61,3,52,5,68,7,100,11,
+                       43,3,42,5,54,7, 78,11,
+                       34,3,37,5,47,7, 67,11};
+  UCHAR   ThLowB[]=   {81,4,72,6,88,8,120,12,
+                       55,4,54,6,66,8, 90,12,
+                       42,4,45,6,55,8, 75,12};
+  UCHAR   ThTiming[]= {1,2,2,3,0,1,1,2};
+
+  data=SiS_GetReg1(SiS_P3c4,0x16);
+  data=data>>6;
+  data2=SiS_GetReg1(SiS_P3c4,0x14);
+  data2=(data2>>4)&0x0C;
+  data=data|data2;
+  data=data<1;
+  if(key==0) {
+    temp0=(USHORT)ThLowA[data];
+    temp1=(USHORT)ThLowA[data+1];
+  } else {
+    temp0=(USHORT)ThLowB[data];
+    temp1=(USHORT)ThLowB[data+1];
+  }
+
+  data2=0;
+  data=SiS_GetReg1(SiS_P3c4,0x18);
+  if(data&0x02) data2=data2|0x01;
+  if(data&0x20) data2=data2|0x02;
+  if(data&0x40) data2=data2|0x04;
+
+  data=temp1*ThTiming[data2]+temp0;
+  return(data);
+}
+
+void
+SiS_SetCRT1FIFO2(ULONG ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                 USHORT RefreshRateTableIndex)
+{
+  USHORT  i,index,data,VCLK,data2,MCLK,colorth=0;
+  ULONG   B,eax,ah,bl;
+  USHORT  ThresholdLow=0;
+  UCHAR   FQBQData[]= { 0x01,0x21,0x41,0x61,0x81,  /* TW: in BIOS at 0xf85 - identical */
+                        0x31,0x51,0x71,0x91,0xb1,
+                        0x00,0x20,0x40,0x60,0x80,
+                        0x30,0x50,0x70,0x90,0xb0,0xFF};
+
+  if(ModeNo>=0x13) {
+    index=SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+    if(HwDeviceExtension->jChipType < SIS_315H) { /* for300 series */
+      index=index&0x3F;
+    }
+    VCLK=SiS_VCLKData[index].CLOCK;           /* Get VCLK  */
+    index=SiS_GetReg1(SiS_P3c4,0x1A);
+    index=index&07;
+    MCLK=SiS_MCLKData[index].CLOCK;           /* Get MCLK  */
+
+    data2=SiS_ModeType-0x02;
+      switch (data2) {
+        case 0 : colorth=1; break;  /* 1 */
+        case 1 : colorth=1; break;  /* 2 */
+        case 2 : colorth=2; break;  /* 4 */
+        case 3 : colorth=2; break;  /* 4 */
+        case 4 : colorth=3; break;  /* 6 */
+        case 5 : colorth=4; break;  /* 8 */
+      }
+
+    i=0;
+    do{
+       B=(SiS_CalcDelay2(ROMAddr,FQBQData[i])*VCLK*colorth);
+
+       bl=B/(16*MCLK);
+       if (B==bl*16*MCLK) {
+         bl=bl+1;
+       } else {
+         bl=bl+2;  /* TW: was +1 */
+       }
+
+       if(bl>0x13) {
+          if(FQBQData[i+1]==0xFF) {
+             ThresholdLow=0x13;
+             break;
+          }
+          i++;
+       } else {
+          ThresholdLow=bl;
+          break;
+       }
+    } while(FQBQData[i]!=0xFF);
+  }
+  else {
+    ThresholdLow=0x02;
+  }
+
+  data2=FQBQData[i];
+  data2=(data2&0xf0)>>4;
+  data2=data2<<24;
+
+  SiS_SetReg4(0xcf8,0x80000050);
+  eax=SiS_GetReg3(0xcfc);
+  eax=eax&0xf0ffffff;
+  eax=eax|data2;
+  SiS_SetReg4(0xcfc,eax);
+
+  ah=ThresholdLow;
+  ah=ah<<4;
+  ah=ah|0x0f;
+  SiS_SetReg1(SiS_P3c4,0x08,ah);
+
+  data=ThresholdLow;
+  data=data&0x10;
+  data=data<<1;
+  SiS_SetRegANDOR(SiS_P3c4,0x0F,0xDF,data);
+
+  SiS_SetReg1(SiS_P3c4,0x3B,0x09);
+
+  data=ThresholdLow+3;
+  if(data>0x0f) data=0x0f;
+  SiS_SetRegANDOR(SiS_P3c4,0x09,0x80,data);
 }
 
 USHORT
-SiS_CalcDelay2 (ULONG ROMAddr, UCHAR key)
+SiS_CalcDelay2(ULONG ROMAddr,UCHAR key)
 {
-	USHORT data, index;
-	UCHAR LatencyFactor[] = { 97, 88, 86, 79, 77, 00,	/*; 64  bit    BQ=2   */
-		00, 87, 85, 78, 76, 54,	/*; 64  bit    BQ=1   */
-		97, 88, 86, 79, 77, 00,	/*; 128 bit    BQ=2   */
-		00, 79, 77, 70, 68, 48,	/*; 128 bit    BQ=1   */
-		80, 72, 69, 63, 61, 00,	/*; 64  bit    BQ=2   */
-		00, 70, 68, 61, 59, 37,	/*; 64  bit    BQ=1   */
-		86, 77, 75, 68, 66, 00,	/*; 128 bit    BQ=2   */
-		00, 68, 66, 59, 57, 37
-	};			/*; 128 bit    BQ=1   */
-
-	index = (key & 0xE0) >> 5;
-	if (key & 0x10)
-		index = index + 6;
-	if (!(key & 0x01))
-		index = index + 24;
-	data = SiS_GetReg1 (SiS_P3c4, 0x14);
-	if (data & 0x0080)
-		index = index + 12;
-
-	data = LatencyFactor[index];
-	return (data);
+  USHORT data,index;	   /* TW: in BIOS at 0x1029 - identical */
+  UCHAR  LatencyFactor[] ={ 97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
+                            00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
+                            97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
+                            00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
+                            80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
+                            00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
+                            86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
+                            00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
+
+  index=(key&0xE0)>>5;
+  if(key&0x10) index=index+6;
+  if(!(key&0x01)) index=index+24;
+  data=SiS_GetReg1(SiS_P3c4,0x14);
+  if(data&0x0080) index=index+12;
+
+  data=LatencyFactor[index];
+  return(data);
 }
 
 void
-SiS_CRT2AutoThreshold (USHORT BaseAddr)
-{
-	USHORT temp1;
-	USHORT Part1Port;
-	Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	temp1 = SiS_GetReg1 (SiS_Part1Port, 0x1);
-	temp1 |= 0x40;
-	SiS_SetReg1 (SiS_Part1Port, 0x1, temp1);
+SiS_CRT2AutoThreshold(USHORT  BaseAddr)
+{
+  USHORT  temp1;
+  USHORT  Part1Port;
+  Part1Port=BaseAddr+SIS_CRT2_PORT_04;
+  temp1=SiS_GetReg1(SiS_Part1Port,0x01);
+  temp1 |= 0x40;
+  SiS_SetReg1(SiS_Part1Port,0x01,temp1);
 }
 
 /* =============  ynlai ============== */
 void
-SiS_DetectMonitor (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_DetectMonitor(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
-	UCHAR DAC_TEST_PARMS[] = { 0x0F, 0x0F, 0x0F };
-	UCHAR DAC_CLR_PARMS[] = { 0x00, 0x00, 0x00 };
-	USHORT SR1F;
-
-	SR1F = SiS_GetReg1 (SiS_P3c4, 0x1F);
-	SiS_SetRegANDOR (SiS_P3c4, 0x1F, 0xFF, 0x04);
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_BridgeIsOn (BaseAddr)) {
-			SiS_SetReg1 (SiS_P3d4, 0x30, 0x41);
-		}
-	}
-	SiSSetMode (HwDeviceExtension, 0x03);	/* InitMode */
-	SiS_SetReg3 (SiS_P3c6, 0xff);
-	SiS_ClearDAC (SiS_P3c8);
-	SiS_LongWait ();
-	SiS_LongWait ();
-	SiS_SetRegANDOR (SiS_P3d4, 0x32, 0xDF, 0x00);
-	if (SiS_TestMonitorType
-	    (DAC_TEST_PARMS[0], DAC_TEST_PARMS[1], DAC_TEST_PARMS[2])) {
-		SiS_SetRegANDOR (SiS_P3d4, 0x32, 0xDF, 0x20);
-	}
-	if (SiS_TestMonitorType
-	    (DAC_TEST_PARMS[0], DAC_TEST_PARMS[1], DAC_TEST_PARMS[2])) {
-		SiS_SetRegANDOR (SiS_P3d4, 0x32, 0xDF, 0x20);
-	}
-	SiS_TestMonitorType (DAC_CLR_PARMS[0], DAC_CLR_PARMS[1],
-			     DAC_CLR_PARMS[2]);
-	SiS_SetReg1 (SiS_P3c4, 0x1F, SR1F);
+  UCHAR  DAC_TEST_PARMS[]={0x0F,0x0F,0x0F};
+  UCHAR  DAC_CLR_PARMS[]={0x00,0x00,0x00};
+  USHORT SR1F;
+
+  SR1F=SiS_GetReg1(SiS_P3c4,0x1F);		/* DAC pedestal */
+  SiS_SetRegANDOR(SiS_P3c4,0x1F,0xFF,0x04);
+  if(SiS_IF_DEF_LVDS==0) {
+    if(SiS_BridgeIsOn(BaseAddr)) {
+      SiS_SetReg1(SiS_P3d4,0x30,0x41);
+    }
+  }
+  /*SiSSetMode(HwDeviceExtension,0x03);  */ /* ynlai InitMode */
+
+#ifdef LINUX_XF86
+  SiSSetMode(HwDeviceExtension,NULL,0x2E); 
+#else
+  SiSSetMode(HwDeviceExtension,0x2E);   /* alan */
+#endif
+  SiS_SetReg3(SiS_P3c6,0xff);
+  SiS_ClearDAC(SiS_P3c8);
+  SiS_LongWait();
+  SiS_LongWait();
+  SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x00);
+  if(SiS_TestMonitorType(DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
+    SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x20);
+  }
+  if(SiS_TestMonitorType(DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
+    SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x20);
+  }
+  SiS_TestMonitorType(DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]);
+  SiS_SetReg1(SiS_P3c4,0x1F,SR1F);
 }
 
 USHORT
-SiS_TestMonitorType (UCHAR R_DAC, UCHAR G_DAC, UCHAR B_DAC)
+SiS_TestMonitorType(UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC)
 {
-	USHORT temp, tempbx;
+   USHORT temp,tempbx;
 
-	tempbx = R_DAC * 0x4d + G_DAC * 0x97 + B_DAC * 0x1c;
-	if (tempbx > 0x80)
-		tempbx = tempbx + 0x100;
-	tempbx = (tempbx & 0xFF00) >> 8;
-	R_DAC = (UCHAR) tempbx;
-	G_DAC = (UCHAR) tempbx;
-	B_DAC = (UCHAR) tempbx;
-
-	SiS_SetReg3 (SiS_P3c8, 0x00);
-	SiS_SetReg3 (SiS_P3c9, R_DAC);
-	SiS_SetReg3 (SiS_P3c9, G_DAC);
-	SiS_SetReg3 (SiS_P3c9, B_DAC);
-	SiS_LongWait ();
-	temp = SiS_GetReg2 (SiS_P3c2);
-	if (temp & 0x10)
-		return (1);
-	else
-		return (0);
+   tempbx=R_DAC*0x4d+G_DAC*0x97+B_DAC*0x1c;
+   if(tempbx>0x80) tempbx=tempbx+0x100;
+   tempbx = (tempbx&0xFF00)>>8;
+   R_DAC = (UCHAR) tempbx;
+   G_DAC = (UCHAR) tempbx;
+   B_DAC = (UCHAR) tempbx;
+
+   SiS_SetReg3(SiS_P3c8,0x00);
+   SiS_SetReg3(SiS_P3c9,R_DAC);
+   SiS_SetReg3(SiS_P3c9,G_DAC);
+   SiS_SetReg3(SiS_P3c9,B_DAC);
+   SiS_LongWait();
+   temp=SiS_GetReg2(SiS_P3c2);
+   if(temp&0x10) return(1);
+   else return(0);
 }
 
 /* ---- test ----- */
 void
-SiS_GetSenseStatus (PSIS_HW_DEVICE_INFO HwDeviceExtension, ULONG ROMAddr)
+SiS_GetSenseStatus(PSIS_HW_DEVICE_INFO HwDeviceExtension,ULONG ROMAddr)
 {
-	USHORT tempax = 0, tempbx, tempcx, temp;
-	USHORT P2reg0 = 0, SenseModeNo = 0, OutputSelect = *pSiS_OutputSelect;
-	USHORT ModeIdIndex, i;
-	USHORT BaseAddr = (USHORT) HwDeviceExtension->ulIOAddress;
-
-	if (SiS_IF_DEF_LVDS == 1) {
-		SiS_GetPanelID ();
-		temp = LCDSense;
-		temp = temp | SiS_SenseCHTV ();
-		tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense);
-		SiS_SetRegANDOR (SiS_P3d4, 0x32, tempbx, temp);
-	} else {		/* for 301 */
-		if (SiS_IF_DEF_HiVision == 1) {	/* for HiVision */
-			tempax = SiS_GetReg1 (SiS_P3c4, 0x38);
-			temp = tempax & 0x01;
-			tempax = SiS_GetReg1 (SiS_P3c4, 0x3A);
-			temp = temp | (tempax & 0x02);
-			SiS_SetRegANDOR (SiS_P3d4, 0x32, 0xA0, temp);
-		} else {
-			if (SiS_BridgeIsOn (BaseAddr)) {
-				P2reg0 = SiS_GetReg1 (SiS_Part2Port, 0x00);
-				if (!SiS_BridgeIsEnable
-				    (BaseAddr, HwDeviceExtension)) {
-					SenseModeNo = 0x2e;
-					temp =
-					    SiS_SearchModeID (ROMAddr,
-							      SenseModeNo,
-							      &ModeIdIndex);
-					SiS_SetFlag = 0x00;
-					SiS_ModeType = ModeVGA;
-					SiS_VBInfo =
-					    SetCRT2ToRAMDAC | LoadDACFlag |
-					    SetInSlaveMode;
-					SiS_SetCRT2Group301 (BaseAddr, ROMAddr,
-							     SenseModeNo,
-							     HwDeviceExtension);
-					for (i = 0; i < 20; i++) {
-						SiS_LongWait ();
-					}
-				}
-				SiS_SetReg1 (SiS_Part2Port, 0x00, 0x1c);
-				tempax = 0;
-				tempbx = *pSiS_RGBSenseData;
-				/*301b */
-				if (!(SiS_Is301B (BaseAddr))) {
-					tempbx = *pSiS_RGBSenseData2;
-				}
-				/*end 301b */
-				tempcx = 0x0E08;
-				if (SiS_Sense (SiS_Part4Port, tempbx, tempcx)) {
-					if (SiS_Sense
-					    (SiS_Part4Port, tempbx, tempcx)) {
-						tempax = tempax | Monitor2Sense;
-					}
-				}
-
-				tempbx = *pSiS_YCSenseData;
-				/*301b */
-				if (!(SiS_Is301B (BaseAddr))) {
-					tempbx = *pSiS_YCSenseData2;
-				}
-				/*301b */
-				tempcx = 0x0604;
-				if (SiS_Sense (SiS_Part4Port, tempbx, tempcx)) {
-					if (SiS_Sense
-					    (SiS_Part4Port, tempbx, tempcx)) {
-						tempax = tempax | SVIDEOSense;
-					}
-				}
-
-				if (OutputSelect & BoardTVType) {
-					tempbx = *pSiS_VideoSenseData;
-					/*301b */
-					if (!(SiS_Is301B (BaseAddr))) {
-						tempbx = *pSiS_VideoSenseData2;
-					}
-					/*end 301b */
-					tempcx = 0x0804;
-					if (SiS_Sense
-					    (SiS_Part4Port, tempbx, tempcx)) {
-						if (SiS_Sense
-						    (SiS_Part4Port, tempbx,
-						     tempcx)) {
-							tempax =
-							    tempax |
-							    AVIDEOSense;
-						}
-					}
-				} else {
-					if (!(tempax & SVIDEOSense)) {
-						tempbx = *pSiS_VideoSenseData;
-						/*301b */
-						if (!(SiS_Is301B (BaseAddr))) {
-							tempbx =
-							    *pSiS_VideoSenseData2;
-						}
-						/*end 301b */
-						tempcx = 0x0804;
-						if (SiS_Sense
-						    (SiS_Part4Port, tempbx,
-						     tempcx)) {
-							if (SiS_Sense
-							    (SiS_Part4Port,
-							     tempbx, tempcx)) {
-								tempax =
-								    tempax |
-								    AVIDEOSense;
-							}
-						}
-					}
-				}
-			}
-
-			if (SiS_SenseLCD (HwDeviceExtension)) {
-				tempax = tempax | LCDSense;
-			}
-
-			tempbx = 0;
-			tempcx = 0;
-			SiS_Sense (SiS_Part4Port, tempbx, tempcx);
-
-			SiS_SetRegANDOR (SiS_P3d4, 0x32, ~0xDF, tempax);
-			SiS_SetReg1 (SiS_Part2Port, 0x00, P2reg0);
-			if (!(P2reg0 & 0x20)) {
-				SiS_VBInfo = DisableCRT2Display;
-				SiS_SetCRT2Group301 (BaseAddr, ROMAddr,
-						     SenseModeNo,
-						     HwDeviceExtension);
-			}
-		}
-	}
+  USHORT tempax=0,tempbx,tempcx,temp;
+  USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*pSiS_OutputSelect;
+  USHORT ModeIdIndex,i;
+  USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+  if(SiS_IF_DEF_LVDS==1){
+    SiS_GetPanelID();
+    temp=LCDSense;
+    temp=temp|SiS_SenseCHTV();
+    tempbx=~(LCDSense|AVIDEOSense|SVIDEOSense);
+    SiS_SetRegANDOR(SiS_P3d4,0x32,tempbx,temp);
+  } else {       /* for 301 */
+    if(SiS_IF_DEF_HiVision==1) {  /* for HiVision */
+      tempax=SiS_GetReg1(SiS_P3c4,0x38);
+      temp=tempax&0x01;
+      tempax=SiS_GetReg1(SiS_P3c4,0x3A);
+      temp=temp|(tempax&0x02);
+      SiS_SetRegANDOR(SiS_P3d4,0x32,0xA0,temp);
+    } else {
+      if(SiS_BridgeIsOn(BaseAddr)) {
+        P2reg0 = SiS_GetReg1(SiS_Part2Port,0x00);
+        if(!SiS_BridgeIsEnable(BaseAddr,HwDeviceExtension)) {
+          SenseModeNo=0x2e;
+          temp = SiS_SearchModeID(ROMAddr,SenseModeNo,&ModeIdIndex);
+          SiS_SetFlag = 0x00;
+          SiS_ModeType = ModeVGA;
+          SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
+          SiS_SetCRT2Group301(BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+          for(i=0;i<20;i++) {
+            SiS_LongWait();
+          }
+        }
+        SiS_SetReg1(SiS_Part2Port,0x00,0x1c);
+        tempax=0;
+        tempbx=*pSiS_RGBSenseData;
+        /*301b*/
+	if(!(SiS_Is301B(BaseAddr))){
+                tempbx=*pSiS_RGBSenseData2;
+        }
+        /*end 301b*/	
+        tempcx=0x0E08;
+        if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+            tempax=tempax|Monitor2Sense;
+          }
+        }
+
+        tempbx=*pSiS_YCSenseData;
+         /*301b*/
+        if(!(SiS_Is301B(BaseAddr))){
+               tempbx=*pSiS_YCSenseData2;  
+        }
+        /*301b*/
+        tempcx=0x0604;
+        if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+            tempax=tempax|SVIDEOSense;
+          }
+        }
+
+        if(OutputSelect&BoardTVType){
+          tempbx=*pSiS_VideoSenseData;
+        /*301b*/
+        if(!(SiS_Is301B(BaseAddr))){
+             tempbx=*pSiS_VideoSenseData2;
+        }
+        /*end 301b*/
+          tempcx=0x0804;
+          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+            if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+              tempax=tempax|AVIDEOSense;
+            }
+          }
+        } else {
+          if(!(tempax&SVIDEOSense)){
+            tempbx=*pSiS_VideoSenseData;
+            /*301b*/
+            if(!(SiS_Is301B(BaseAddr))){
+              tempbx=*pSiS_VideoSenseData2;
+            }
+            /*end 301b*/
+            tempcx=0x0804;
+            if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+              if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+                tempax=tempax|AVIDEOSense;
+              }
+            }
+          }
+        }
+      }
+
+      if(SiS_SenseLCD(HwDeviceExtension)){
+        tempax=tempax|LCDSense;
+      }
+
+      tempbx=0;
+      tempcx=0;
+      SiS_Sense(SiS_Part4Port,tempbx,tempcx);
+  
+      if((SiS_VBType&VB_SIS301LV)||(SiS_VBType&VB_SIS302LV)){
+         tempax=tempax&0x00ef;   				/* 301lv to disable CRT2*/
+      }
+      SiS_SetRegANDOR(SiS_P3d4,0x32,~0xDF,tempax);
+      SiS_SetReg1(SiS_Part2Port,0x00,P2reg0);
+      if(!(P2reg0&0x20)) {
+        SiS_VBInfo = DisableCRT2Display;
+        SiS_SetCRT2Group301(BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+      }
+    }
+  }
 }
 
 BOOLEAN
-SiS_Sense (USHORT Part4Port, USHORT tempbx, USHORT tempcx)
+SiS_Sense(USHORT Part4Port,USHORT tempbx,USHORT tempcx)
 {
-	USHORT temp, i, tempch;
+  USHORT temp,i,tempch;
 
-	temp = tempbx & 0xFF;
-	SiS_SetReg1 (SiS_Part4Port, 0x11, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp | (tempcx & 0x00FF);
-	SiS_SetRegANDOR (SiS_Part4Port, 0x10, ~0x1F, temp);
-
-	for (i = 0; i < 10; i++)
-		SiS_LongWait ();
-
-	tempch = (tempcx & 0x7F00) >> 8;	/*   ynlai [05/22/2001]  */
-	temp = SiS_GetReg1 (SiS_Part4Port, 0x03);
-	temp = temp ^ (0x0E);
-	temp = temp & tempch;	/*   ynlai [05/22/2001]  */
-	if (temp > 0)
-		return 1;
-	else
-		return 0;
+  temp=tempbx&0xFF;
+  SiS_SetReg1(SiS_Part4Port,0x11,temp);
+  temp=(tempbx&0xFF00)>>8;
+  temp=temp|(tempcx&0x00FF);
+  SiS_SetRegANDOR(SiS_Part4Port,0x10,~0x1F,temp);
+
+  for(i=0;i<10;i++) SiS_LongWait();
+
+  tempch=(tempcx&0x7F00)>>8;      /*   ynlai [05/22/2001]  */
+  temp=SiS_GetReg1(SiS_Part4Port,0x03);
+  temp=temp^(0x0E);
+  temp=temp&tempch;               /*   ynlai [05/22/2001]  */
+  if(temp>0) return 1;
+  else return 0;
 }
 
 USHORT
-SiS_SenseLCD (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SenseLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
 /*  USHORT SoftSetting; */
-	USHORT temp;
+  USHORT temp;
 
-	temp = SiS_GetPanelID ();
-	if (!temp)
-		temp = SiS_GetLCDDDCInfo (HwDeviceExtension);
-	return (temp);
+  temp=SiS_GetPanelID();
+  if(!temp)  temp=SiS_GetLCDDDCInfo(HwDeviceExtension);
+  return(temp);
 }
 
 BOOLEAN
-SiS_GetLCDDDCInfo (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT temp;
-	//add lcd sense
-	if (HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN)
-		return 0;
-	else {
-		temp = (USHORT) HwDeviceExtension->ulCRT2LCDType;
-		SiS_SetReg1 (SiS_P3d4, 0x36, temp);
-		return 1;
-	}
+  USHORT temp;
+  /*add lcd sense*/
+  if(HwDeviceExtension->ulCRT2LCDType==LCD_UNKNOWN)
+    	return 0;
+  else{
+     	temp=(USHORT)HwDeviceExtension->ulCRT2LCDType;
+     	SiS_SetReg1(SiS_P3d4,0x36,temp);
+  	return 1;
+  }
 }
 
 BOOLEAN
-SiS_GetPanelID (void)
+SiS_GetPanelID(void)
 {
-	USHORT PanelTypeTable[16] =
-	    { SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType00,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01,
-		SyncPP | PanelRGB18Bit | Panel800x600 | _PanelType02,
-		SyncNN | PanelRGB18Bit | Panel640x480 | _PanelType03,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06,
-		SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07,
-		SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType08,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09,
-		SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType0A,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C,
-		SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E,
-		SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F
-	};
-	USHORT tempax, tempbx, temp;
+  USHORT PanelTypeTable[16]={ SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType00,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01,
+                              SyncPP | PanelRGB18Bit | Panel800x600  | _PanelType02,
+                              SyncNN | PanelRGB18Bit | Panel640x480  | _PanelType03,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06,
+                              SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07,
+                              SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType08,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09,
+                              SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType0A,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C,
+                              SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E,
+                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F
+                              };
+  USHORT tempax,tempbx,temp;
 /*  USHORT return_flag; */
 
-	tempax = SiS_GetReg1 (SiS_P3c4, 0x18);
-	tempbx = tempax & 0x0F;
-	if (!(tempax & 0x10)) {
-		if (SiS_IF_DEF_LVDS == 1) {
-			tempbx = 0;
-			temp = SiS_GetReg1 (SiS_P3c4, 0x38);
-			if (temp & 0x40)
-				tempbx = tempbx | 0x08;
-			if (temp & 0x20)
-				tempbx = tempbx | 0x02;
-			if (temp & 0x01)
-				tempbx = tempbx | 0x01;
-			temp = SiS_GetReg1 (SiS_P3c4, 0x39);
-			if (temp & 0x80)
-				tempbx = tempbx | 0x04;
-		} else {
-			return 0;
-		}
-	}
-
-	tempbx = tempbx << 1;
-	tempbx = PanelTypeTable[tempbx];
-	tempbx = tempbx | LCDSync;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_P3d4, 0x36, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	SiS_SetRegANDOR (SiS_P3d4, 0x37, ~(LCDSyncBit | LCDRGB18Bit), temp);
-	return 1;
+  tempax=SiS_GetReg1(SiS_P3c4,0x18);
+  tempbx=tempax&0x0F;
+  if(!(tempax&0x10)){
+    if(SiS_IF_DEF_LVDS==1){
+      tempbx=0;
+      temp=SiS_GetReg1(SiS_P3c4,0x38);
+      if(temp&0x40) tempbx=tempbx|0x08;
+      if(temp&0x20) tempbx=tempbx|0x02;
+      if(temp&0x01) tempbx=tempbx|0x01;
+      temp=SiS_GetReg1(SiS_P3c4,0x39);
+      if(temp&0x80) tempbx=tempbx|0x04;
+    }else{
+      return 0;
+    }
+  }
+
+  tempbx=tempbx<<1;
+  tempbx=PanelTypeTable[tempbx];
+  tempbx=tempbx|LCDSync;
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_P3d4,0x36,temp);
+  temp=(tempbx&0xFF00)>>8;
+  SiS_SetRegANDOR(SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
+  return 1;
 }
 
 USHORT
-SiS_SenseCHTV (void)
+SiS_SenseCHTV(void)
 {
-	USHORT temp, push0e, status;
+  USHORT temp,push0e,status;
 
-	status = 0;
-	push0e = SiS_GetCH7005 (0x0e);
-	push0e = (push0e << 8) | 0x0e;
-	SiS_SetCH7005 (0x0b0e);
-	SiS_SetCH7005 (0x0110);
-	SiS_SetCH7005 (0x0010);
-	temp = SiS_GetCH7005 (0x10);
-	if (temp & 0x08)
-		status = status | SVIDEOSense;
-	if (temp & 0x02)
-		status = status | AVIDEOSense;
-	SiS_SetCH7005 (push0e);
-	return (status);
+  status=0;
+  push0e=SiS_GetCH7005(0x0e);
+  push0e=(push0e<<8)|0x0e;
+  SiS_SetCH7005(0x0b0e);
+  SiS_SetCH7005(0x0110);
+  SiS_SetCH7005(0x0010);
+  temp=SiS_GetCH7005(0x10);
+  if(temp&0x08) status=status|SVIDEOSense;
+  if(temp&0x02) status=status|AVIDEOSense;
+  SiS_SetCH7005(push0e);
+  return(status);
 }
 
-/*  ==========================================  */
+/*  ================for TC only =================  */
 #ifdef TC
 
 int
-INT1AReturnCode (union REGS regs)
+INT1AReturnCode(union REGS regs)
 {
-	if (regs.x.cflag) {
-		/*printf("Error to find pci device!\n"); */
-		return 1;
-	}
-
-	switch (regs.h.ah) {
-	case 0:
-		return 0;
-		break;
-	case 0x81:
-		printf ("Function not support\n");
-		break;
-	case 0x83:
-		printf ("bad vendor id\n");
-		break;
-	case 0x86:
-		printf ("device not found\n");
-		break;
-	case 0x87:
-		printf ("bad register number\n");
-		break;
-	case 0x88:
-		printf ("set failed\n");
-		break;
-	case 0x89:
-		printf ("buffer too small");
-		break;
-	}
-	return 1;
+  if (regs.x.cflag)
+  {
+    /*printf("Error to find pci device!\n"); */
+    return 1;
+  }
+
+  switch(regs.h.ah)
+  {
+    case 0: return 0;
+            break;
+    case 0x81: printf("Function not support\n");
+               break;
+    case 0x83: printf("bad vendor id\n");
+               break;
+    case 0x86: printf("device not found\n");
+               break;
+    case 0x87: printf("bad register number\n");
+               break;
+    case 0x88: printf("set failed\n");
+               break;
+    case 0x89: printf("buffer too small");
+               break;
+  }
+  return 1;
 }
 
 unsigned
-FindPCIIOBase (unsigned index, unsigned deviceid)
+FindPCIIOBase(unsigned index,unsigned deviceid)
 {
-	union REGS regs;
+  union REGS regs;
 
-	regs.h.ah = 0xb1;	/*PCI_FUNCTION_ID */
-	regs.h.al = 0x02;	/*FIND_PCI_DEVICE */
-	regs.x.cx = deviceid;
-	regs.x.dx = 0x1039;
-	regs.x.si = index;	/* find n-th device */
+  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
+  regs.h.al = 0x02;  /*FIND_PCI_DEVICE */
+  regs.x.cx = deviceid;
+  regs.x.dx = 0x1039;
+  regs.x.si = index;  /* find n-th device */
 
-	int86 (0x1A, &regs, &regs);
+  int86(0x1A, &regs, &regs);
 
-	if (INT1AReturnCode (regs) != 0)
-		return 0;
+  if (INT1AReturnCode(regs)!=0)
+    return 0;
 
-/* regs.h.bh *//* bus number */
-/* regs.h.bl *//* device number */
-	regs.h.ah = 0xb1;	/*PCI_FUNCTION_ID */
-	regs.h.al = 0x09;	/*READ_CONFIG_WORD */
-	regs.x.cx = deviceid;
-	regs.x.dx = 0x1039;
-	regs.x.di = 0x18;	/* register number */
-	int86 (0x1A, &regs, &regs);
+  /* regs.h.bh *//* bus number */
+  /* regs.h.bl *//* device number */
+  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
+  regs.h.al = 0x09;  /*READ_CONFIG_WORD */
+  regs.x.cx = deviceid;
+  regs.x.dx = 0x1039;
+  regs.x.di = 0x18;  /* register number */
+  int86(0x1A, &regs, &regs);
 
-	if (INT1AReturnCode (regs) != 0)
-		return 0;
-	return regs.x.cx;
+  if (INT1AReturnCode(regs)!=0)
+    return 0;
+  return regs.x.cx;
 }
 
+
 void
-main (int argc, char *argv[])
-/* void main() */
+main(int argc, char *argv[])
 {
-	SIS_HW_DEVICE_INFO HwDeviceExtension;
-	USHORT temp;
-	USHORT ModeNo;
+  SIS_HW_DEVICE_INFO  HwDeviceExtension;
+  USHORT temp;
+  USHORT ModeNo;
 
-	/*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
-	/*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0); */
-#ifdef CONFIG_FB_SIS_300
-	HwDeviceExtension.ulIOAddress =
-	    (FindPCIIOBase (0, 0x6300) & 0xFF80) + 0x30;
-	HwDeviceExtension.jChipType = SIS_630;
+  /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
+  /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
+
+#ifdef SIS300  
+  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
+  HwDeviceExtension.jChipType = SIS_630;
 #endif
 
-#ifdef CONFIG_FB_SIS_315
+#ifdef SIS315H  
 //  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
 //  HwDeviceExtension.jChipType = SIS_550;
-	HwDeviceExtension.ulIOAddress =
-	    (FindPCIIOBase (0, 0x325) & 0xFF80) + 0x30;
-	HwDeviceExtension.jChipType = SIS_315H;
-#endif
-	HwDeviceExtension.ujVBChipID = VB_CHIP_301;
-	strcpy (HwDeviceExtension.szVBIOSVer, "0.84");
-	HwDeviceExtension.bSkipDramSizing = FALSE;
-	HwDeviceExtension.ulVideoMemorySize = 0;
-	if (argc == 2) {
-		ModeNo = atoi (argv[1]);
-	} else {
-		ModeNo = 0x2e;
-		/*ModeNo=0x37;  1024x768x 4bpp */
-		/*ModeNo=0x38;  1024x768x 8bpp */
-		/*ModeNo=0x4A;  1024x768x 16bpp */
-		/*ModeNo=0x47;  800x600x 16bpp */
-	}
-	// SiSInit(&HwDeviceExtension);
-	SiSSetMode (&HwDeviceExtension, ModeNo);
+  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
+  HwDeviceExtension.jChipType = SIS_315H;
+#endif
 
+  HwDeviceExtension.ujVBChipID = VB_CHIP_301;
+  strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
+  HwDeviceExtension.bSkipDramSizing = FALSE;
+  HwDeviceExtension.ulVideoMemorySize = 0;
+  if(argc==2) {
+    ModeNo=atoi(argv[1]);
+  }
+  else {
+    ModeNo=0x2e;
+    /*ModeNo=0x37; */ /* 1024x768x 4bpp */
+    /*ModeNo=0x38; *//* 1024x768x 8bpp */
+    /*ModeNo=0x4A; *//* 1024x768x 16bpp */
+    /*ModeNo=0x47;*/ /* 800x600x 16bpp */
+  }
+ /* SiSInit(&HwDeviceExtension);*/
+#ifdef LINUX_XF86
+  SiSSetMode(&HwDeviceExtension,NULL, ModeNo);
+#else
+  SiSSetMode(&HwDeviceExtension,ModeNo);
+#endif
+}
+#endif /* TC */
+
+/* TW: New for Linux XF86 */
+#ifdef LINUX_XF86
+USHORT
+SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+   UShort i = (pScrn->bitsPerPixel+7)/8 - 1;
+   UShort ModeIndex = 0;
+   switch(mode->HDisplay)
+   {
+     case 640:
+          ModeIndex = ModeIndex_640x480[i];
+          break;
+     case 720:
+          if(mode->VDisplay == 480)
+            ModeIndex = ModeIndex_720x480[i];
+          else
+            ModeIndex = ModeIndex_720x576[i];
+          break;
+     case 800:
+          ModeIndex = ModeIndex_800x600[i];
+          break;
+     case 1024:
+          ModeIndex = ModeIndex_1024x768[i];
+          break;
+     case 1280:
+          if(mode->VDisplay == 960)
+            ModeIndex = ModeIndex_1280x960[i];
+          else
+            ModeIndex = ModeIndex_1280x1024[i];
+          break;
+     case 1600:
+          ModeIndex = ModeIndex_1600x1200[i];
+          break;
+     case 1920:
+          ModeIndex = ModeIndex_1920x1440[i];
+          break;
+   }
+
+   return(ModeIndex);
+}
+
+#define MODEID_OFF 0x449
+
+unsigned char
+SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
+{
+    unsigned char ret;
+
+    unsigned char* base = xf86MapVidMem(pScrn->scrnIndex,
+					VIDMEM_MMIO, 0, 0x2000);
+    ret = *(base + MODEID_OFF);
+
+    /* id != 0xff means: set mode */
+    if (id != 0xff)
+	*(base + MODEID_OFF) = id;
+    xf86UnMapVidMem(pScrn->scrnIndex,base,0x2000);
+
+    return ret;
 }
 #endif
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/init.h linux/drivers/video/sis/init.h
--- linux.orig/drivers/video/sis/init.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/init.h	2002-07-20 01:08:30.000000000 +0000
@@ -6,222 +6,275 @@
 #include "vgatypes.h"
 #include "vstruct.h"
 
+#ifdef TC
+#include <stdio.h>
+#include <string.h>
+#include <conio.h>
+#include <dos.h>
+#include <stdlib.h>
+#endif
+
+#ifdef LINUX_XF86
+#include "xf86.h"
+#include "xf86PciInfo.h"
+#include "xf86_OSproc.h"
+#include "sis.h"
+#include "sis_regs.h"
+#endif
+
+#ifdef LINUX_KERNEL
 #include <linux/types.h>
 #include <asm/io.h>
 #include <linux/sisfb.h>
+#endif
 
+#ifdef WIN2000
+#include <stdio.h>
+#include <string.h>
+#include <miniport.h>
+#include "dderror.h"
+#include "devioctl.h"
+#include "miniport.h"
+
+#include "ntddvdeo.h"
+#include "video.h"
+#include "sisv.h"
+#endif
 
-USHORT SiS_DRAMType[17][5] = { 
-	{0x0C, 0x0A, 0x02, 0x40, 0x39},
-	{0x0D, 0x0A, 0x01, 0x40, 0x48},
-	{0x0C, 0x09, 0x02, 0x20, 0x35},
-	{0x0D, 0x09, 0x01, 0x20, 0x44},
-	{0x0C, 0x08, 0x02, 0x10, 0x31},
-	{0x0D, 0x08, 0x01, 0x10, 0x40},
-	{0x0C, 0x0A, 0x01, 0x20, 0x34},
-	{0x0C, 0x09, 0x01, 0x08, 0x32},
-	{0x0B, 0x08, 0x02, 0x08, 0x21},
-	{0x0C, 0x08, 0x01, 0x08, 0x30},
-	{0x0A, 0x08, 0x02, 0x04, 0x11},
-	{0x0B, 0x0A, 0x01, 0x10, 0x28},
-	{0x09, 0x08, 0x02, 0x02, 0x01},
-	{0x0B, 0x09, 0x01, 0x08, 0x24},
-	{0x0B, 0x08, 0x01, 0x04, 0x20},
-	{0x0A, 0x08, 0x01, 0x02, 0x10},
-	{0x09, 0x08, 0x01, 0x01, 0x00}
+USHORT SiS_DRAMType[17][5]={{0x0C,0x0A,0x02,0x40,0x39},{0x0D,0x0A,0x01,0x40,0x48},
+                     {0x0C,0x09,0x02,0x20,0x35},{0x0D,0x09,0x01,0x20,0x44},
+                     {0x0C,0x08,0x02,0x10,0x31},{0x0D,0x08,0x01,0x10,0x40},
+                     {0x0C,0x0A,0x01,0x20,0x34},{0x0C,0x09,0x01,0x08,0x32},
+                     {0x0B,0x08,0x02,0x08,0x21},{0x0C,0x08,0x01,0x08,0x30},
+                     {0x0A,0x08,0x02,0x04,0x11},{0x0B,0x0A,0x01,0x10,0x28},
+                     {0x09,0x08,0x02,0x02,0x01},{0x0B,0x09,0x01,0x08,0x24},
+                     {0x0B,0x08,0x01,0x04,0x20},{0x0A,0x08,0x01,0x02,0x10},
+                     {0x09,0x08,0x01,0x01,0x00}};
+
+USHORT SiS_SDRDRAM_TYPE[13][5]=
+{
+{ 2,12, 9,64,0x35},
+{ 1,13, 9,64,0x44},
+{ 2,12, 8,32,0x31},
+{ 2,11, 9,32,0x25},
+{ 1,12, 9,32,0x34},
+{ 1,13, 8,32,0x40},
+{ 2,11, 8,16,0x21},
+{ 1,12, 8,16,0x30},
+{ 1,11, 9,16,0x24},
+{ 1,11, 8, 8,0x20},
+{ 2, 9, 8, 4,0x01},
+{ 1,10, 8, 4,0x10},
+{ 1, 9, 8, 2,0x00}
 };
 
-USHORT SiS_SDRDRAM_TYPE[13][5] = {
-	{2, 12, 9, 64, 0x35},
-	{1, 13, 9, 64, 0x44},
-	{2, 12, 8, 32, 0x31},
-	{2, 11, 9, 32, 0x25},
-	{1, 12, 9, 32, 0x34},
-	{1, 13, 8, 32, 0x40},
-	{2, 11, 8, 16, 0x21},
-	{1, 12, 8, 16, 0x30},
-	{1, 11, 9, 16, 0x24},
-	{1, 11, 8, 8, 0x20},
-	{2, 9, 8, 4, 0x01},
-	{1, 10, 8, 4, 0x10},
-	{1, 9, 8, 2, 0x00}
+USHORT SiS_DDRDRAM_TYPE[4][5]=
+{
+{ 2,12, 9,64,0x35},
+{ 2,12, 8,32,0x31},
+{ 2,11, 8,16,0x21},
+{ 2, 9, 8, 4,0x01}
 };
 
-USHORT SiS_DDRDRAM_TYPE[4][5] = {
-	{2, 12, 9, 64, 0x35},
-	{2, 12, 8, 32, 0x31},
-	{2, 11, 8, 16, 0x21},
-	{2, 9, 8, 4, 0x01}
-};
+UCHAR SiS_ChannelAB,SiS_DataBusWidth;
 
-UCHAR SiS_ChannelAB, SiS_DataBusWidth;
 
-USHORT SiS_MDA_DAC[] = { 
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
-};
+USHORT SiS_MDA_DAC[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+               0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+               0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+               0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+               0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+               0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+               0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F};
+
+USHORT SiS_CGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+               0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+               0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+               0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F};
+
+USHORT SiS_EGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
+               0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
+               0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D,
+               0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D,
+               0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17,
+               0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37,
+               0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F,
+               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F};
+
+USHORT SiS_VGA_DAC[]={0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+               0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+               0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18,
+               0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F,
+
+               0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F,
+               0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00,
+               0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18,
+               0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04,
+               0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10,
+               0x0B,0x0C,0x0D,0x0F,0x10};
+
+USHORT      SiS_P3c4,SiS_P3d4,SiS_P3c0,SiS_P3ce,SiS_P3c2;
+USHORT      SiS_P3ca,SiS_P3c6,SiS_P3c7,SiS_P3c8,SiS_P3c9,SiS_P3da;
+USHORT      SiS_Part1Port,SiS_Part2Port;
+USHORT      SiS_Part3Port,SiS_Part4Port,SiS_Part5Port;
+USHORT      SiS_CRT1Mode;
+
+USHORT   flag_clearbuffer;         /*0: no clear frame buffer 1:clear frame buffer  */
+int      SiS_RAMType;              /*int      ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
+USHORT   SiS_ModeType;
+USHORT   SiS_IF_DEF_LVDS,SiS_IF_DEF_TRUMPION,SiS_IF_DEF_DSTN,SiS_IF_DEF_FSTN;    /*add for dstn*/
+USHORT   SiS_IF_DEF_CH7005,SiS_IF_DEF_HiVision;
+USHORT	 SiS_Backup7005=0xff;	/* TW: Backup for power-status */
+USHORT   SiS_VBInfo,SiS_LCDResInfo,SiS_LCDTypeInfo,SiS_LCDInfo, SiS_VBType;/*301b*/
+USHORT   SiS_VBExtInfo;  /*301lv*/
+USHORT   SiS_SelectCRT2Rate;
+
+extern   USHORT   SiS_SetFlag;
+extern   USHORT   SiS_DDC_Port;
+
+void     SiS_SetMemoryClock(ULONG ROMAddr);
+void     SiS_SetDRAMModeRegister(ULONG   ROMAddr);
+void     SiS_SetDRAMSize_310(PSIS_HW_DEVICE_INFO);
+void     SiS_SetDRAMSize_300(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_ChkBUSWidth_300(ULONG FBAddress);
+UCHAR    SiS_Get310DRAMType(ULONG   ROMAddr);
+
+BOOLEAN SiS_SearchVBModeID(ULONG ROMAddr, USHORT ModeNo);
+void SiS_IsLowResolution(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+ULONG GetDRAMSize(PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
-USHORT SiS_CGA_DAC[] = { 
-	0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
-	0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
-	0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
-	0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
-	0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
-	0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
-	0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
-	0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
-};
+#ifdef SIS300
+void InitTo300Pointer(void);
+#endif
+#ifdef SIS315H
+void InitTo310Pointer(void);
+#endif
 
-USHORT SiS_EGA_DAC[] = { 
-	0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
-	0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
-	0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
-	0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
-	0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17,
-	0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37,
-	0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
-	0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
-};
+#ifdef SIS315H
+void SiS_DDR_MRS(void);
+void SiS_SDR_MRS(void);
+void SiS_DisableRefresh(void);
+void SiS_EnableRefresh(ULONG ROMAddr);
+void SiS_DisableChannelInterleaving(int index,USHORT SiS_DDRDRAM_TYPE[][5]);
+void SiS_SetDRAMSizingType(int index,USHORT DRAMTYPE_TABLE[][5]);
+void SiS_CheckBusWidth_310(ULONG ROMAddress,ULONG FBAddress);
+int  SiS_SetRank(int index,UCHAR RankNo,UCHAR SiS_ChannelAB,USHORT DRAMTYPE_TABLE[][5]);
+int  SiS_SetDDRChannel(int index,UCHAR ChannelNo,UCHAR SiS_ChannelAB,USHORT DRAMTYPE_TABLE[][5]);
+int  SiS_CheckColumn(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int  SiS_CheckBanks(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int  SiS_CheckRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int  SiS_CheckDDRRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int  SiS_CheckRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int  SiS_CheckDDRRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int  SiS_SDRSizing(ULONG FBAddress);
+int  SiS_DDRSizing(ULONG FBAddress);
+int  Is315E(void);
+void SiS_VerifyMclk(ULONG FBAddr);
+#endif
 
-USHORT SiS_VGA_DAC[] = { 
-	0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
-	0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
-	0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
-	0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
-
-	0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
-	0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
-	0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
-	0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
-	0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
-	0x0B, 0x0C, 0x0D, 0x0F, 0x10
-};
+/*int    init300(int,int,int);  */
+/*extern      "C"    int     ChkBUSWidth(int);  */
+/*int    setmode(int,int,int,int);  */
+extern void SetEnableDstn(void);
+void     SiS_Delay15us(ULONG);
+BOOLEAN  SiS_SearchModeID(ULONG ROMAddr, USHORT ModeNo,USHORT  *ModeIdIndex);
+BOOLEAN  SiS_CheckMemorySize(ULONG ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                             USHORT ModeNo,USHORT ModeIdIndex);
+UCHAR    SiS_GetModePtr(ULONG ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_SetSeqRegs(ULONG,USHORT StandTableIndex);
+void     SiS_SetMiscRegs(ULONG,USHORT StandTableIndex);
+void     SiS_SetCRTCRegs(ULONG,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT StandTableIndex);
+void     SiS_SetATTRegs(ULONG,USHORT StandTableIndex);
+void     SiS_SetGRCRegs(ULONG,USHORT StandTableIndex);
+void     SiS_ClearExt1Regs(void);
+void     SiS_SetSync(ULONG ROMAddr,USHORT RefreshRateTableIndex);
+void     SiS_SetCRT1CRTC(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_SetCRT1VCLK(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO,
+                         USHORT RefreshRateTableIndex);
+void     SiS_SetVCLKState(ULONG ROMAddr,PSIS_HW_DEVICE_INFO, USHORT ModeNo,USHORT RefreshRateTableIndex);
+void     SiS_LoadDAC(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_DisplayOn(void);
+void 	 SiS_DisplayOff(void);
+void     SiS_SetCRT1ModeRegs(ULONG ROMAddr,PSIS_HW_DEVICE_INFO,USHORT ModeNo,
+                             USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_WriteDAC(USHORT, USHORT, USHORT, USHORT);
+void     SiS_GetVBType(USHORT BaseAddr);/*301b*/
+USHORT   SiS_ChkBUSWidth(ULONG);
+USHORT   SiS_GetModeIDLength(ULONG, USHORT);
+USHORT   SiS_GetRefindexLength(ULONG, USHORT);
+void     SiS_SetInterlace(ULONG ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex);
+USHORT   SiS_CalcDelay2(ULONG ,UCHAR);
+USHORT   SiS_CalcDelay(ULONG ,USHORT);
+void     SiS_Set_LVDS_TRUMPION(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT1Offset(ULONG,USHORT,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
+void     SiS_SetCRT1FIFO(ULONG,USHORT,PSIS_HW_DEVICE_INFO);
+void     SiS_SetCRT1FIFO2(ULONG,USHORT ModeNo,PSIS_HW_DEVICE_INFO,USHORT RefreshRateTableIndex);
+void     SiS_CRT2AutoThreshold(USHORT  BaseAddr);
+void     SiS_ClearBuffer(PSIS_HW_DEVICE_INFO,USHORT ModeNo);
+void     SiS_SetCRT1Group(ULONG ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                          USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_DetectMonitor(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+void     SiS_GetSenseStatus(PSIS_HW_DEVICE_INFO HwDeviceExtension,ULONG ROMAddr);
+USHORT   SiS_TestMonitorType(UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC);
+USHORT   SiS_SenseCHTV(VOID);
+BOOLEAN  SiS_Sense(USHORT Part4Port,USHORT tempbx,USHORT tempcx);
+BOOLEAN  SiS_GetPanelID(VOID);
+BOOLEAN  SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO);
+USHORT   SiS_SenseLCD(PSIS_HW_DEVICE_INFO);
+void     SiSRegInit(USHORT BaseAddr);
+void     SiSInitPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiSSetLVDSetc(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
+void     SiSInitPCIetc(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+#ifdef LINUX_XF86
+USHORT  	SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void    	SiS_SetPitch(ScrnInfoPtr pScrn, UShort BaseAddr);
+void    	SiS_SetPitchCRT1(ScrnInfoPtr pScrn, UShort BaseAddr);
+void    	SiS_SetPitchCRT2(ScrnInfoPtr pScrn, UShort BaseAddr);
+unsigned char 	SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+#endif
 
-USHORT SiS_P3c4, SiS_P3d4, SiS_P3c0, SiS_P3ce, SiS_P3c2;
-USHORT SiS_P3ca, SiS_P3c6, SiS_P3c7, SiS_P3c8, SiS_P3c9, SiS_P3da;
-USHORT SiS_Part1Port, SiS_Part2Port;
-USHORT SiS_Part3Port, SiS_Part4Port, SiS_Part5Port;
-USHORT SiS_CRT1Mode;
-
-USHORT flag_clearbuffer;	/*0: no clear frame buffer 1:clear frame buffer  */
-int SiS_RAMType;		/*int      ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex; */
-USHORT SiS_ModeType;
-USHORT SiS_IF_DEF_LVDS, SiS_IF_DEF_TRUMPION, SiS_IF_DEF_DSTN;	/*add for dstn */
-USHORT SiS_IF_DEF_CH7005, SiS_IF_DEF_HiVision;
-USHORT SiS_VBInfo, SiS_LCDResInfo, SiS_LCDTypeInfo, SiS_LCDInfo, SiS_VBType;	/*301b */
-USHORT SiS_SelectCRT2Rate;
-
-extern USHORT SiS_SetFlag;
-
-void SiS_SetMemoryClock (ULONG ROMAddr);
-void SiS_SetDRAMModeRegister (ULONG ROMAddr);
-void SiS_SetDRAMSize_310 (PSIS_HW_DEVICE_INFO);
-void SiS_SetDRAMSize_300 (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT SiS_ChkBUSWidth_300 (ULONG FBAddress);
-UCHAR SiS_Get310DRAMType (ULONG ROMAddr);
-
-void SiS_Delay15us (ULONG);
-BOOLEAN SiS_SearchModeID (ULONG ROMAddr, USHORT ModeNo, USHORT * ModeIdIndex);
-BOOLEAN SiS_CheckMemorySize (ULONG ROMAddr,
-			     PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			     USHORT ModeNo, USHORT ModeIdIndex);
-UCHAR SiS_GetModePtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_SetSeqRegs (ULONG, USHORT StandTableIndex);
-void SiS_SetMiscRegs (ULONG, USHORT StandTableIndex);
-void SiS_SetCRTCRegs (ULONG, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		      USHORT StandTableIndex);
-void SiS_SetATTRegs (ULONG, USHORT StandTableIndex);
-void SiS_SetGRCRegs (ULONG, USHORT StandTableIndex);
-void SiS_ClearExt1Regs (void);
-void SiS_SetSync (ULONG ROMAddr, USHORT RefreshRateTableIndex);
-void SiS_SetCRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex);
-void SiS_SetCRT1VCLK (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      PSIS_HW_DEVICE_INFO, USHORT RefreshRateTableIndex);
-void SiS_SetVCLKState (ULONG ROMAddr, PSIS_HW_DEVICE_INFO, USHORT ModeNo,
-		       USHORT RefreshRateTableIndex);
-void SiS_LoadDAC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_DisplayOn (void);
-void SiS_SetCRT1ModeRegs (ULONG ROMAddr, PSIS_HW_DEVICE_INFO, USHORT ModeNo,
-			  USHORT ModeIdIndex, USHORT RefreshRateTableIndex);
-void SiS_WriteDAC (USHORT, USHORT, USHORT, USHORT);
-void SiS_GetVBType (USHORT BaseAddr);	/*301b */
-USHORT SiS_ChkBUSWidth (ULONG);
-USHORT SiS_GetModeIDLength (ULONG, USHORT);
-USHORT SiS_GetRefindexLength (ULONG, USHORT);
-void SiS_SetInterlace (ULONG ROMAddr, USHORT ModeNo,
-		       USHORT RefreshRateTableIndex);
-USHORT SiS_CalcDelay2 (ULONG, UCHAR);
-USHORT SiS_CalcDelay (ULONG, USHORT);
-void SiS_Set_LVDS_TRUMPION (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetCRT1Offset (ULONG, USHORT, USHORT, USHORT, PSIS_HW_DEVICE_INFO);
-void SiS_SetCRT1FIFO (ULONG, USHORT, PSIS_HW_DEVICE_INFO);
-void SiS_SetCRT1FIFO2 (ULONG, USHORT ModeNo, PSIS_HW_DEVICE_INFO,
-		       USHORT RefreshRateTableIndex);
-void SiS_CRT2AutoThreshold (USHORT BaseAddr);
-void SiS_ClearBuffer (PSIS_HW_DEVICE_INFO, USHORT ModeNo);
-void SiS_SetCRT1Group (ULONG ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		       USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_DetectMonitor (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void SiS_GetSenseStatus (PSIS_HW_DEVICE_INFO HwDeviceExtension, ULONG ROMAddr);
-USHORT SiS_TestMonitorType (UCHAR R_DAC, UCHAR G_DAC, UCHAR B_DAC);
-USHORT SiS_SenseCHTV (VOID);
-BOOLEAN SiS_Sense (USHORT Part4Port, USHORT tempbx, USHORT tempcx);
-BOOLEAN SiS_GetPanelID (VOID);
-BOOLEAN SiS_GetLCDDDCInfo (PSIS_HW_DEVICE_INFO);
-USHORT SiS_SenseLCD (PSIS_HW_DEVICE_INFO);
-
-extern BOOLEAN SiS_SetCRT2Group301 (USHORT BaseAddr, ULONG ROMAddr,
-				    USHORT ModeNo,
-				    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_PresetScratchregister (USHORT SiS_P3d4,
-				       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_UnLockCRT2 (PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			    USHORT BaseAddr);
-extern void SiS_LockCRT2 (PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			  USHORT BaseAddr);
-extern BOOLEAN SiS_BridgeIsOn (USHORT BaseAddr);
-extern BOOLEAN SiS_BridgeIsEnable (USHORT BaseAddr, PSIS_HW_DEVICE_INFO);
-extern void SiS_SetTVSystem301 (VOID);
-extern BOOLEAN SiS_GetLCDDDCInfo301 (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN SiS_GetSenseStatus301 (PSIS_HW_DEVICE_INFO HwDeviceExtension,
-				      USHORT BaseAddr, ULONG ROMAddr);
-extern USHORT SiS_GetVCLKLen (ULONG ROMAddr,
-			      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN SiS_SetCRT2Group302 (USHORT BaseAddr, ULONG ROMAddr,
-				    USHORT ModeNo,
-				    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_GetVBInfo301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			      USHORT ModeIdIndex,
-			      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN SiS_GetLCDResInfo301 (ULONG ROMAddr, USHORT P3d4, USHORT ModeNo,
-				     USHORT ModeIdIndex);
-extern USHORT SiS_VBInfo, LCDResInfo, LCDTypeInfo, LCDInfo;
-extern USHORT SiS_GetRatePtrCRT2 (ULONG ROMAddr, USHORT ModeNo,
-				  USHORT ModeIdIndex);
-extern void SiS_LongWait (VOID);
-extern void SiS_SetRegANDOR (USHORT Port, USHORT Index, USHORT DataAND,
-			     USHORT DataOR);
-extern USHORT SiS_GetResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-extern void SiS_SetCH7005 (USHORT tempax);
-extern USHORT SiS_GetCH7005 (USHORT tempax);
-extern BOOLEAN SiS_GetLVDSCRT1Ptr (ULONG ROMAddr, USHORT ModeNo,
-				   USHORT ModeIdIndex,
-				   USHORT RefreshRateTableIndex,
-				   USHORT * ResInfo, USHORT * DisplayType);
-extern BOOLEAN SiS_GetLCDACRT1Ptr (ULONG ROMAddr, USHORT ModeNo,
-				   USHORT ModeIdIndex,
-				   USHORT RefreshRateTableIndex,
-				   USHORT * ResInfo, USHORT * DisplayType);
-extern USHORT SiS_GetVCLK2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			       USHORT RefreshRateTableIndex,
-			       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN SiS_Is301B (USHORT BaseAddr);	/*301b */
+extern BOOLEAN   SiS_SetCRT2Group301(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_PresetScratchregister(USHORT SiS_P3d4,
+                                           PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+extern void      SiS_LockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+extern BOOLEAN   SiS_BridgeIsOn(USHORT BaseAddr);
+extern BOOLEAN   SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
+extern void      SiS_SetTVSystem301(VOID);
+extern BOOLEAN   SiS_GetLCDDDCInfo301(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_GetSenseStatus301(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                                       USHORT BaseAddr,ULONG ROMAddr);
+extern USHORT    SiS_GetVCLKLen(ULONG ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_SetCRT2Group302(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_GetVBInfo301(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+                                  USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_GetLCDResInfo301(ULONG ROMAddr,USHORT P3d4,USHORT ModeNo,
+                                      USHORT ModeIdIndex);
+/* extern USHORT  SiS_VBInfo,LCDResInfo,LCDTypeInfo,LCDInfo; */  /* TW: redundant */
+extern USHORT    SiS_GetRatePtrCRT2(ULONG ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+extern void      SiS_LongWait(VOID);
+extern void      SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+extern USHORT    SiS_GetResInfo(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+extern void      SiS_SetCH7005(USHORT tempax);
+extern USHORT    SiS_GetCH7005(USHORT tempax);
+extern BOOLEAN   SiS_GetLVDSCRT1Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                                    USHORT RefreshRateTableIndex,
+		                    USHORT *ResInfo,USHORT *DisplayType);
+extern BOOLEAN   SiS_GetLCDACRT1Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                                    USHORT RefreshRateTableIndex,
+		                    USHORT *ResInfo,USHORT *DisplayType);
+extern USHORT    SiS_GetVCLK2Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                                 USHORT RefreshRateTableIndex,
+				 PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_Is301B(USHORT BaseAddr);/*301b*/
 
 #endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/init301.c linux/drivers/video/sis/init301.c
--- linux.orig/drivers/video/sis/init301.c	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/init301.c	2002-07-20 01:08:23.000000000 +0000
@@ -1,5406 +1,5195 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2000/12/02 01:16:16 dawes Exp $ */
 
+/*
+ * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740
+ * (Universal module for Linux kernel framebuffer, XFree86 4.x)
+ *
+ * Comments and changes marked with "TW" by Thomas Winischhofer <thomer@winischhofer.net>
+ *
+ */
+
+/* DEBUG: GetVCLK2Ptr (Mitac bug) - reverted */
+
+/*
+#ifdef WINCE_HEADER
+#include "precomp.h"
+#endif
+*/
+/*#include "precomp.h"*/
+
 #include "init301.h"
-#ifdef CONFIG_FB_SIS_300
+#ifdef SIS300
 #include "oem300.h"
 #endif
-#ifdef CONFIG_FB_SIS_315
+#ifdef SIS315H
 #include "oem310.h"
 #endif
 
 BOOLEAN
-SiS_SetCRT2Group301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		     PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetCRT2Group301(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT ModeIdIndex;
-	USHORT RefreshRateTableIndex;
-
-	SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-	SiS_SearchModeID (ROMAddr, ModeNo, &ModeIdIndex);
-	SiS_SelectCRT2Rate = 4;
-	RefreshRateTableIndex =
-	    SiS_GetRatePtrCRT2 (ROMAddr, ModeNo, ModeIdIndex);
-	SiS_SaveCRT2Info (ModeNo);
-	SiS_DisableBridge (HwDeviceExtension, BaseAddr);
-	SiS_UnLockCRT2 (HwDeviceExtension, BaseAddr);
-	SiS_SetCRT2ModeRegs (BaseAddr, ModeNo, HwDeviceExtension);
-	if (SiS_VBInfo & DisableCRT2Display) {
-		SiS_LockCRT2 (HwDeviceExtension, BaseAddr);
-		SiS_DisplayOn ();
-		return (FALSE);
-	}
-/* SetDefCRT2ExtRegs(BaseAddr);   */
-	SiS_GetCRT2Data (ROMAddr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		SiS_GetLVDSDesData (ROMAddr, ModeNo, ModeIdIndex,
-				    RefreshRateTableIndex);
-	}
-	/*end 301b */
-	if (SiS_IF_DEF_LVDS == 1) {
-		SiS_GetLVDSDesData (ROMAddr, ModeNo, ModeIdIndex,
-				    RefreshRateTableIndex);
-	}
-
-	SiS_SetGroup1 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-		       HwDeviceExtension, RefreshRateTableIndex);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA) && (SiS_IF_DEF_LVDS == 0)) {
-	} else if (SiS_IF_DEF_LVDS == 0 && (!(SiS_VBInfo & SetCRT2ToLCDA))) {
-		SiS_SetGroup2 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-			       RefreshRateTableIndex, HwDeviceExtension);
-		SiS_SetGroup3 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-			       HwDeviceExtension);
-		SiS_SetGroup4 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-			       RefreshRateTableIndex, HwDeviceExtension);
-		SiS_SetGroup5 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex);
-	} else {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			SiS_SetCHTVReg (ROMAddr, ModeNo, ModeIdIndex,
-					RefreshRateTableIndex);
-		}
-		SiS_ModCRT1CRTC (ROMAddr, ModeNo, ModeIdIndex,
-				 RefreshRateTableIndex);
-		SiS_SetCRT2ECLK (ROMAddr, ModeNo, ModeIdIndex,
-				 RefreshRateTableIndex, HwDeviceExtension);
-	}
-
-#ifdef CONFIG_FB_SIS_300
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ||
-	    (HwDeviceExtension->jChipType == SIS_300))
-		SiS_OEM300Setting (HwDeviceExtension, BaseAddr, ROMAddr,
-				   ModeNo);
+   USHORT ModeIdIndex;
+   USHORT RefreshRateTableIndex;
 
+   SiS_SetFlag=SiS_SetFlag|ProgrammingCRT2;
+   SiS_SearchModeID(ROMAddr,ModeNo,&ModeIdIndex);
+   SiS_SelectCRT2Rate=4;
+   RefreshRateTableIndex = SiS_GetRatePtrCRT2(ROMAddr,ModeNo,ModeIdIndex);
+   SiS_SaveCRT2Info(ModeNo);
+   SiS_DisableBridge(HwDeviceExtension,BaseAddr);
+   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+   SiS_SetCRT2ModeRegs(BaseAddr,ModeNo,HwDeviceExtension);
+   if(SiS_VBInfo&DisableCRT2Display) {
+     SiS_LockCRT2(HwDeviceExtension, BaseAddr);
+     SiS_DisplayOn();
+     return(FALSE);
+   }
+   /* SetDefCRT2ExtRegs(BaseAddr);   */
+   SiS_GetCRT2Data(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+   /*301b*/
+   if( ((SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS301LV))
+           && (SiS_VBInfo&SetCRT2ToLCDA)) ){
+	SiS_GetLVDSDesData(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+   }
+   /*end 301b*/
+   if(SiS_IF_DEF_LVDS==1) {
+   	SiS_GetLVDSDesData(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+   }
+
+   SiS_SetGroup1(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+                 HwDeviceExtension,RefreshRateTableIndex);
+
+   /*301b*/
+   if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS301LV))
+   		&& (SiS_VBInfo&SetCRT2ToLCDA)
+		&& (SiS_IF_DEF_LVDS == 0) ) {
+     	if( (SiS_VBType&(VB_SIS301LV|VB_SIS302LV)) && (SiS_VBInfo&SetCRT2ToLCDA) ){
+             	SiS_SetReg1(SiS_Part4Port,0x24,0x0e);
+    	}
+   /* end 301b */
+   } else if((SiS_IF_DEF_LVDS==0) && (!(SiS_VBInfo&SetCRT2ToLCDA))) {
+      	SiS_SetGroup2(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	              RefreshRateTableIndex,HwDeviceExtension);
+      	SiS_SetGroup3(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	              HwDeviceExtension);
+      	SiS_SetGroup4(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	              RefreshRateTableIndex,HwDeviceExtension);
+      	SiS_SetGroup5(BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+   } else {
+     	if(SiS_IF_DEF_CH7005==1) {
+	    if(SiS_VBInfo&SetCRT2ToTV)
+	        /* TW: Set Chrontel registers only if CRT2 is TV */
+       		SiS_SetCHTVReg(ROMAddr,ModeNo,ModeIdIndex,
+		               RefreshRateTableIndex);
+     	}
+     	if(!(SiS_LCDResInfo==Panel640x480)){
+    	 	SiS_ModCRT1CRTC(ROMAddr,ModeNo,ModeIdIndex,
+		                RefreshRateTableIndex);
+         	if(!SiS_IF_DEF_FSTN)  /*fstn*/
+     	     		SiS_SetCRT2ECLK(ROMAddr,ModeNo,ModeIdIndex,
+			          RefreshRateTableIndex,HwDeviceExtension);
+     	}
+   }
+
+#ifdef SIS300
+   if ( (HwDeviceExtension->jChipType==SIS_540)||
+        (HwDeviceExtension->jChipType==SIS_630)||
+        (HwDeviceExtension->jChipType==SIS_730)||
+        (HwDeviceExtension->jChipType==SIS_300) )
+     	SiS_OEM300Setting(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
 #endif
 
-#ifdef CONFIG_FB_SIS_315
-	if ((HwDeviceExtension->jChipType == SIS_315H) ||	/* 05/02/01 ynlai for sis550 */
-	    (HwDeviceExtension->jChipType == SIS_315PRO) ||
-	    (HwDeviceExtension->jChipType == SIS_550) ||	/* 05/02/01 ynlai for 550 */
-	    (HwDeviceExtension->jChipType == SIS_640) ||	/* 08/20/01 chiawen for 640/740 */
-	    (HwDeviceExtension->jChipType == SIS_740)) {	/* 09/03/01 chiawen for 640/740 */
-		SiS_OEM310Setting (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo,
-				   ModeIdIndex);
-		SiS_CRT2AutoThreshold (BaseAddr);
-	}
+#ifdef SIS315H
+   if ( (HwDeviceExtension->jChipType==SIS_315H)||   /* 05/02/01 ynlai for sis550 */
+        (HwDeviceExtension->jChipType==SIS_315PRO)||
+        (HwDeviceExtension->jChipType==SIS_550) ||   /* 05/02/01 ynlai for 550 */
+        (HwDeviceExtension->jChipType==SIS_640) ||   /* 08/20/01 chiawen for 640/740 */
+        (HwDeviceExtension->jChipType==SIS_740) ||   /* 09/03/01 chiawen for 640/740 */
+        (HwDeviceExtension->jChipType==SIS_650))     /* 09/03/01 chiawen for 650 */
+   {
+        SiS_OEM310Setting(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+        SiS_CRT2AutoThreshold(BaseAddr);
+   }
 #endif
 
-	SiS_EnableBridge (HwDeviceExtension, BaseAddr);
-	SiS_DisplayOn ();
-	SiS_LockCRT2 (HwDeviceExtension, BaseAddr);
-	return 1;
-}
-
-void
-SiS_SetGroup1 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-	       USHORT RefreshRateTableIndex)
-{
-	USHORT temp = 0, tempax = 0, tempbx = 0, tempcx = 0;
-	USHORT pushbx = 0, CRT1Index = 0;
-	USHORT modeflag, resinfo = 0;
-
-	if (ModeNo <= 0x13) {
-	} else {
-		CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index = CRT1Index & 0x3F;
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
-
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-	} else {
-		SiS_SetCRT2Offset (SiS_Part1Port, ROMAddr, ModeNo, ModeIdIndex,
-				   RefreshRateTableIndex, HwDeviceExtension);
-		if (HwDeviceExtension->jChipType < SIS_315H)	/* 300 series */
-			SiS_SetCRT2FIFO (SiS_Part1Port, ROMAddr, ModeNo,
-					 HwDeviceExtension);
-		else		/* 310 series */
-			SiS_SetCRT2FIFO2 (SiS_Part1Port, ROMAddr, ModeNo,
-					  HwDeviceExtension);
-
-		SiS_SetCRT2Sync (BaseAddr, ROMAddr, ModeNo,
-				 RefreshRateTableIndex);
-	}
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		SiS_SetGroup1_LCDA (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-				    HwDeviceExtension, RefreshRateTableIndex);
-	}
-	/*end 301b */
-	else if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-		temp = (SiS_VGAHT - 1) & 0x0FF;	/* BTVGA2HT 0x08,0x09 */
-		SiS_SetReg1 (SiS_Part1Port, 0x08, temp);
-		temp = (((SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x09, ~0x0F0, temp);
-
-		temp = (SiS_VGAHDE + 12) & 0x0FF;	/* BTVGA2HDEE 0x0A,0x0C */
-		SiS_SetReg1 (SiS_Part1Port, 0x0A, temp);
-
-		pushbx = SiS_VGAHDE + 12;	/* bx  BTVGA@HRS 0x0B,0x0C */
-		tempcx = (SiS_VGAHT - SiS_VGAHDE) >> 2;	/* cx */
-		tempbx = pushbx + tempcx;
-		tempcx = tempcx << 1;
-		tempcx = tempcx + tempbx;
-
-		if (SiS_IF_DEF_LVDS == 0) {
-			if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-				tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-				tempbx =
-				    tempbx |
-				    ((SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) <<
-				     2);
-				tempbx = (tempbx - 1) << 3;
-				tempcx = SiS_CRT1Table[CRT1Index].CR[5];
-				tempcx = tempcx & 0x1F;
-				temp = SiS_CRT1Table[CRT1Index].CR[15];
-				temp = (temp & 0x04) << (6 - 2);
-				tempcx = ((tempcx | temp) - 1) << 3;
-			}
-		}
-		/*add for hardware request */
-		if ((SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)) {
-			if (SiS_VBInfo & SetPALTV) {
-				tempbx = 1040;
-				tempcx = 1042;
-			} else {
-				tempbx = 1040;
-				tempcx = 1042;
-			}
-		}
-
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x0B, temp);
-
-	} else {		/* 310 series */
-
-		if (modeflag & HalfDCLK) {	/* for low resolution mode */
-			temp = (SiS_VGAHT / 2 - 1) & 0x0FF;	/* BTVGA2HT 0x08,0x09 */
-			SiS_SetReg1 (SiS_Part1Port, 0x08, temp);
-			temp = (((SiS_VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
-			SiS_SetRegANDOR (SiS_Part1Port, 0x09, ~0x0F0, temp);
-			temp = (SiS_VGAHDE / 2 + 16) & 0x0FF;	/* BTVGA2HDEE 0x0A,0x0C */
-			SiS_SetReg1 (SiS_Part1Port, 0x0A, temp);
-
-			pushbx = SiS_VGAHDE / 2 + 16;
-			tempcx = ((SiS_VGAHT - SiS_VGAHDE) / 2) >> 2;	/* cx */
-			tempbx = pushbx + tempcx;	/* bx  BTVGA@HRS 0x0B,0x0C */
-			tempcx = tempcx + tempbx;
-
-			if (SiS_IF_DEF_LVDS == 0) {
-				if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-					tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-					tempbx =
-					    tempbx |
-					    ((SiS_CRT1Table
-					      [CRT1Index].CR[14] & 0xC0) << 2);
-					tempbx = (tempbx - 3) << 3;	/*(VGAHRS-3)*8 */
-					tempcx = SiS_CRT1Table[CRT1Index].CR[5];
-					tempcx = tempcx & 0x1F;
-					temp = SiS_CRT1Table[CRT1Index].CR[15];
-					temp = (temp & 0x04) << (5 - 2);	/*VGAHRE D[5] */
-					tempcx = ((tempcx | temp) - 3) << 3;	/* (VGAHRE-3)*8 */
-				}
-			}
-			tempbx += 4;
-			tempcx += 4;
-			if (tempcx > (SiS_VGAHT / 2))
-				tempcx = SiS_VGAHT / 2;
-			temp = tempbx & 0x00FF;
-			SiS_SetReg1 (SiS_Part1Port, 0x0B, temp);
-
-		} else {
-			temp = (SiS_VGAHT - 1) & 0x0FF;	/* BTVGA2HT 0x08,0x09 */
-			SiS_SetReg1 (SiS_Part1Port, 0x08, temp);
-			temp = (((SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-			SiS_SetRegANDOR (SiS_Part1Port, 0x09, ~0x0F0, temp);
-			temp = (SiS_VGAHDE + 16) & 0x0FF;	/* BTVGA2HDEE 0x0A,0x0C */
-			SiS_SetReg1 (SiS_Part1Port, 0x0A, temp);
-
-			pushbx = SiS_VGAHDE + 16;
-			tempcx = (SiS_VGAHT - SiS_VGAHDE) >> 2;	/* cx */
-			tempbx = pushbx + tempcx;	/* bx  BTVGA@HRS 0x0B,0x0C */
-			tempcx = tempcx + tempbx;
-
-			if (SiS_IF_DEF_LVDS == 0) {
-				if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-					tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-					tempbx =
-					    tempbx |
-					    ((SiS_CRT1Table
-					      [CRT1Index].CR[14] & 0xC0) << 2);
-					tempbx = (tempbx - 3) << 3;	/*(VGAHRS-3)*8 */
-					tempcx = SiS_CRT1Table[CRT1Index].CR[5];
-					tempcx = tempcx & 0x1F;
-					temp = SiS_CRT1Table[CRT1Index].CR[15];
-					temp = (temp & 0x04) << (5 - 2);	/*VGAHRE D[5] */
-					tempcx = ((tempcx | temp) - 3) << 3;	/* (VGAHRE-3)*8 */
-					tempbx += 16;
-					tempcx += 16;
-
-				}
-			}
-			if (tempcx > SiS_VGAHT)
-				tempcx = SiS_VGAHT;
-			/*add for hardware request */
-			if ((SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)) {
-				if (SiS_VBInfo & SetPALTV) {
-					tempbx = 1040;
-					tempcx = 1042;
-				} else {
-					tempbx = 1040;
-					tempcx = 1042;
-				}
-			}
-			temp = tempbx & 0x00FF;
-			SiS_SetReg1 (SiS_Part1Port, 0x0B, temp);
-		}
-
-	}
-
-	tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
-	tempbx = pushbx;
-	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
-	tempax = tempax | (tempbx & 0xFF00);
-	temp = (tempax & 0xFF00) >> 8;
-	SiS_SetReg1 (SiS_Part1Port, 0x0C, temp);
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x0D, temp);
-	tempcx = (SiS_VGAVT - 1);
-	temp = tempcx & 0x00FF;
-	if (SiS_IF_DEF_CH7005 == 1) {
-		if (SiS_VBInfo & 0x0C) {
-			temp--;
-		}
-	}
-	SiS_SetReg1 (SiS_Part1Port, 0x0E, temp);
-	tempbx = SiS_VGAVDE - 1;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x0F, temp);
-	temp = ((tempbx & 0xFF00) << 3) >> 8;
-	temp = temp | ((tempcx & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x12, temp);
-
-	tempax = SiS_VGAVDE;
-	tempbx = SiS_VGAVDE;
-	tempcx = SiS_VGAVT;
-	tempbx = (SiS_VGAVT + SiS_VGAVDE) >> 1;	/*      BTVGA2VRS     0x10,0x11   */
-	tempcx = ((SiS_VGAVT - SiS_VGAVDE) >> 4) + tempbx + 1;	/*      BTVGA2VRE     0x11        */
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-			tempbx = SiS_CRT1Table[CRT1Index].CR[8];
-			temp = SiS_CRT1Table[CRT1Index].CR[7];
-			if (temp & 0x04)
-				tempbx = tempbx | 0x0100;
-			if (temp & 0x080)
-				tempbx = tempbx | 0x0200;
-			temp = SiS_CRT1Table[CRT1Index].CR[13];
-			if (temp & 0x08)
-				tempbx = tempbx | 0x0400;
-			temp = SiS_CRT1Table[CRT1Index].CR[9];
-			tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
-		}
-	}
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x10, temp);
-	temp = ((tempbx & 0xFF00) >> 8) << 4;
-	temp = ((tempcx & 0x000F) | (temp));
-	SiS_SetReg1 (SiS_Part1Port, 0x11, temp);
-	if (SiS_IF_DEF_LVDS == 0) {
-		temp = 0x20;
-		if (SiS_LCDResInfo == Panel1280x1024)
-			temp = 0x20;
-		if (SiS_LCDResInfo == Panel1280x960)
-			temp = 0x24;
-		if (SiS_VBInfo & SetCRT2ToTV)
-			temp = 0x08;
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-			if (SiS_VBInfo & SetInSlaveMode)
-				temp = 0x2c;
-			else
-				temp = 0x20;
-		}
-	} else {
-		temp = 0x20;
-	}
-	if (HwDeviceExtension->jChipType < SIS_315H)	/* 300 series */
-		SiS_SetRegANDOR (SiS_Part1Port, 0x13, ~0x03C, temp);
-	else {			/* 310 series */
-
-		temp >>= 2;
-		temp = 0x11;	/*  ynlai 05/30/2001 for delay compenation  */
-		SiS_SetReg1 (SiS_Part1Port, 0x2D, temp);
-		/*SiS_SetRegANDOR(SiS_Part1Port,0x2D,~0x00F,temp); */
-		SiS_SetRegAND (SiS_Part1Port, 0x13, 0xEF);	/* BDirectLCD=0 for lcd ?? */
-		tempax = 0;
-
-		if (modeflag & DoubleScanMode)
-			tempax |= 0x80;
-		if (modeflag & HalfDCLK)
-			tempax |= 0x40;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x2C, ~0x0C0, tempax);
-
-	}
-
-	if (SiS_IF_DEF_LVDS == 0) {	/*  301  */
-		SiS_SetGroup1_301 (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-				   HwDeviceExtension, RefreshRateTableIndex);
-	} else {		/*  LVDS  */
-		SiS_SetGroup1_LVDS (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-				    HwDeviceExtension, RefreshRateTableIndex);
-	}
-}
-
-void
-SiS_SetGroup1_301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		   USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		   USHORT RefreshRateTableIndex)
-{
-	USHORT push1, push2;
-	USHORT tempax, tempbx, tempcx, temp;
-	USHORT resinfo, modeflag;
-	USHORT CRT1Index;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index = CRT1Index & 0x3F;
-	}
-
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		return;
-	}
-	tempax = 0xFFFF;
-	if (!(SiS_VBInfo & SetCRT2ToTV)) {
-		tempax = SiS_GetVGAHT2 ();
-	}
-	if (modeflag & Charx8Dot)
-		tempcx = 0x08;
-	else
-		tempcx = 0x09;
-	if (tempax >= SiS_VGAHT) {
-		tempax = SiS_VGAHT;
-	}
-	if (modeflag & HalfDCLK) {
-		tempax = tempax >> 1;
-	}
-	tempax = (tempax / tempcx) - 5;
-	tempbx = tempax;
-	temp = 0xFF;		/* set MAX HT */
-	SiS_SetReg1 (SiS_Part1Port, 0x03, temp);
-
-	tempax = SiS_VGAHDE;	/* 0x04 Horizontal Display End */
-	if (modeflag & HalfDCLK)
-		tempax = tempax >> 1;
-	tempax = (tempax / tempcx) - 1;
-	tempbx = tempbx | ((tempax & 0x00FF) << 8);
-	temp = tempax & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x04, temp);
-
-	temp = (tempbx & 0xFF00) >> 8;
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		temp = temp + 2;
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-			if (resinfo == 7)
-				temp = temp - 2;
-		}
-	}
-	SiS_SetReg1 (SiS_Part1Port, 0x05, temp);	/* 0x05 Horizontal Display Start */
-	SiS_SetReg1 (SiS_Part1Port, 0x06, 0x03);	/* 0x06 Horizontal Blank end     */
-	/* 0x07 horizontal Retrace Start */
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		temp = (tempbx & 0x00FF) - 1;
-		if (!(modeflag & HalfDCLK)) {
-			temp = temp - 6;
-			if (SiS_SetFlag & TVSimuMode) {
-				temp = temp - 4;
-				if (ModeNo > 0x13)
-					temp = temp - 10;
-			}
-		}
-	} else {
-		tempcx = tempbx & 0x00FF;
-		tempbx = (tempbx & 0xFF00) >> 8;
-		tempcx = (tempcx + tempbx) >> 1;
-		temp = (tempcx & 0x00FF) + 2;
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = temp - 1;
-			if (!(modeflag & HalfDCLK)) {
-				if ((modeflag & Charx8Dot)) {
-					temp = temp + 4;
-					if (SiS_VGAHDE >= 800) {
-						temp = temp - 6;
-					}
-				}
-			}
-		} else {
-			if (!(modeflag & HalfDCLK)) {
-				temp = temp - 4;
-				if (SiS_LCDResInfo != Panel1280x960) {
-					if (SiS_VGAHDE >= 800) {
-						temp = temp - 7;
-						if (SiS_ModeType == ModeEGA) {
-							if (SiS_VGAVDE == 1024) {
-								temp =
-								    temp + 15;
-								if
-								    (SiS_LCDResInfo
-								     !=
-								     Panel1280x1024)
-								{
-									temp =
-									    temp
-									    + 7;
-								}
-							}
-						}
-						if (SiS_VGAHDE >= 1280) {
-							if (SiS_LCDResInfo !=
-							    Panel1280x960) {
-								if (SiS_LCDInfo
-								    &
-								    LCDNonExpanding)
-								{
-									temp =
-									    temp
-									    +
-									    28;
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-
-	SiS_SetReg1 (SiS_Part1Port, 0x07, temp);	/* 0x07 Horizontal Retrace Start */
-	SiS_SetReg1 (SiS_Part1Port, 0x08, 0);	/* 0x08 Horizontal Retrace End   */
-
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		if (SiS_SetFlag & TVSimuMode) {
-			if ((ModeNo == 0x06) || (ModeNo == 0x10)
-			    || (ModeNo == 0x11) || (ModeNo == 0x13)
-			    || (ModeNo == 0x0F)) {
-				SiS_SetReg1 (SiS_Part1Port, 0x07, 0x5b);
-				SiS_SetReg1 (SiS_Part1Port, 0x08, 0x03);
-			}
-			if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
-				if (SiS_VBInfo & SetNTSCTV) {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x2A);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x61);
-				} else {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x2A);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x41);
-					SiS_SetReg1 (SiS_Part1Port, 0x0C, 0xF0);
-				}
-			}
-			if ((ModeNo == 0x02) || (ModeNo == 0x03)
-			    || (ModeNo == 0x07)) {
-				if (SiS_VBInfo & SetNTSCTV) {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x54);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x00);
-				} else {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x55);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x00);
-					SiS_SetReg1 (SiS_Part1Port, 0x0C, 0xF0);
-				}
-			}
-			if ((ModeNo == 0x04) || (ModeNo == 0x05)
-			    || (ModeNo == 0x0D) || (ModeNo == 0x50)) {
-				if (SiS_VBInfo & SetNTSCTV) {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x30);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x03);
-				} else {
-					SiS_SetReg1 (SiS_Part1Port, 0x07, 0x2f);
-					SiS_SetReg1 (SiS_Part1Port, 0x08, 0x02);
-				}
-			}
-		}
-	}
-
-	SiS_SetReg1 (SiS_Part1Port, 0x18, 0x03);	/* 0x18 SR08                     */
-	SiS_SetRegANDOR (SiS_Part1Port, 0x19, 0xF0, 0x00);
-	SiS_SetReg1 (SiS_Part1Port, 0x09, 0xFF);	/* 0x09 Set Max VT               */
-
-	tempbx = SiS_VGAVT;
-	push1 = tempbx;
-	tempcx = 0x121;
-	tempbx = SiS_VGAVDE;	/* 0x0E Virtical Display End */
-	if (tempbx == 357)
-		tempbx = 350;
-	if (tempbx == 360)
-		tempbx = 350;
-	if (tempbx == 375)
-		tempbx = 350;
-	if (tempbx == 405)
-		tempbx = 400;
-	if (tempbx == 420)
-		tempbx = 400;
-	if (tempbx == 525)
-		tempbx = 480;
-	push2 = tempbx;
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		if (SiS_LCDResInfo == Panel1024x768) {
-			if (!(SiS_SetFlag & LCDVESATiming)) {
-				if (tempbx == 350)
-					tempbx = tempbx + 5;
-				if (tempbx == 480)
-					tempbx = tempbx + 5;
-			}
-		}
-	}
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x10, temp);	/* 0x10 vertical Blank Start */
-	tempbx = push2;
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x0E, temp);
-	if (tempbx & 0x0100) {
-		tempcx = tempcx | 0x0002;
-	}
-	tempax = 0x000B;
-	if (modeflag & DoubleScanMode) {
-		tempax = tempax | 0x08000;
-	}
-	if (tempbx & 0x0200) {
-		tempcx = tempcx | 0x0040;
-	}
-
-	temp = (tempax & 0xFF00) >> 8;
-	SiS_SetReg1 (SiS_Part1Port, 0x0B, temp);
-	if (tempbx & 0x0400) {
-		tempcx = tempcx | 0x0600;
-	}
-	SiS_SetReg1 (SiS_Part1Port, 0x11, 0x00);	/* 0x11 Vertival Blank End */
-
-	tempax = push1;
-	tempax = tempax - tempbx;	/* 0x0C Vertical Retrace Start */
-	tempax = tempax >> 2;
-	push1 = tempax;		/* push ax */
-
-	if (resinfo != 0x09) {
-		tempax = tempax << 1;
-		tempbx = tempax + tempbx;
-	}
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempbx = tempbx - 10;
-	} else {
-		if (SiS_SetFlag & TVSimuMode) {
-			if (SiS_VBInfo & SetPALTV) {
-				tempbx = tempbx + 40;
-			}
-		}
-	}
-	tempax = push1;
-	tempax = tempax >> 2;
-	tempax++;
-	tempax = tempax + tempbx;
-	push1 = tempax;		/* push ax  */
-	if ((SiS_VBInfo & SetPALTV)) {
-		if (tempbx <= 513) {
-			if (tempax >= 513) {
-				tempbx = 513;
-			}
-		}
-	}
-	temp = (tempbx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x0C, temp);
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x10, temp);
-	if (tempbx & 0x0100) {
-		tempcx = tempcx | 0x0008;
-	}
-	if (tempbx & 0x0200) {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x0B, 0x0FF, 0x20);
-	}
-	tempbx++;
-	if (tempbx & 0x0100) {
-		tempcx = tempcx | 0x0004;
-	}
-	if (tempbx & 0x0200) {
-		tempcx = tempcx | 0x0080;
-	}
-	if (tempbx & 0x0400) {
-		tempcx = tempcx | 0x0C00;
-	}
-
-	tempbx = push1;		/* pop ax */
-	temp = tempbx & 0x00FF;
-	temp = temp & 0x0F;
-	SiS_SetReg1 (SiS_Part1Port, 0x0D, temp);	/* 0x0D vertical Retrace End */
-	if (tempbx & 0x0010) {
-		tempcx = tempcx | 0x2000;
-	}
-
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x0A, temp);	/* 0x0A CR07 */
-	temp = (tempcx & 0x0FF00) >> 8;
-	SiS_SetReg1 (SiS_Part1Port, 0x17, temp);	/* 0x17 SR0A */
-	tempax = modeflag;
-	temp = (tempax & 0xFF00) >> 8;
-
-	temp = (temp >> 1) & 0x09;
-	SiS_SetReg1 (SiS_Part1Port, 0x16, temp);	/* 0x16 SR01 */
-	SiS_SetReg1 (SiS_Part1Port, 0x0F, 0);	/* 0x0F CR14 */
-	SiS_SetReg1 (SiS_Part1Port, 0x12, 0);	/* 0x12 CR17 */
-	if (SiS_LCDInfo & LCDRGB18Bit)
-		temp = 0x80;
-	else
-		temp = 0x00;
-	SiS_SetReg1 (SiS_Part1Port, 0x1A, temp);	/* 0x1A SR0E */
-	return;
-}
-
-void
-SiS_SetGroup1_LVDS (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		    USHORT RefreshRateTableIndex)
-{
-	USHORT modeflag, resinfo;
-	USHORT push1, push2, tempax, tempbx, tempcx, temp, pushcx;
-	ULONG tempeax = 0, tempebx, tempecx, tempvcfact = 0;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
-
-	tempax = SiS_LCDHDES;
-	tempbx = SiS_HDE;
-	tempcx = SiS_HT;
-	tempcx = tempcx - tempbx;	/* HT-HDE  */
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		if (SiS_LCDResInfo == Panel800x600)
-			tempbx = 800;
-		if (SiS_LCDResInfo == Panel1024x768)
-			tempbx = 1024;
-	}
-	push1 = tempax;
-	tempax = tempax + tempbx;	/* lcdhdee  */
-	tempbx = SiS_HT;
-	if (tempax >= tempbx) {
-		tempax = tempax - tempbx;
-	}
-	push2 = tempax;
-	/* push ax   lcdhdee  */
-	tempcx = tempcx >> 2;	/* temp  */
-	tempcx = tempcx + tempax;	/* lcdhrs  */
-	if (tempcx >= tempbx) {
-		tempcx = tempcx - tempbx;
-	}
-	/* v ah,cl  */
-	tempax = tempcx;
-	tempax = tempax >> 3;	/* BPLHRS */
-	temp = tempax & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x14, temp);	/* Part1_14h  */
-	temp = (tempax & 0x00FF) + 10;
-	temp = temp & 0x01F;
-	temp = temp | (((tempcx & 0x00ff) & 0x07) << 5);
-	SiS_SetReg1 (SiS_Part1Port, 0x15, temp);	/* Part1_15h  */
-	tempbx = push2;		/* lcdhdee  */
-	tempcx = push1;		/* lcdhdes  */
-	temp = (tempcx & 0x00FF);
-	temp = temp & 0x07;	/* BPLHDESKEW  */
-	SiS_SetReg1 (SiS_Part1Port, 0x1A, temp);	/* Part1_1Ah  */
-	tempcx = tempcx >> 3;	/* BPLHDES */
-	temp = (tempcx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x16, temp);	/* Part1_16h  */
-	if (tempbx & 0x07)
-		tempbx = tempbx + 8;
-	tempbx = tempbx >> 3;	/* BPLHDEE  */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x17, temp);	/* Part1_17h  */
-
-	tempcx = SiS_VGAVT;
-	tempbx = SiS_VGAVDE;
-	tempcx = tempcx - tempbx;	/* GAVT-VGAVDE  */
-	tempbx = SiS_LCDVDES;	/* VGAVDES  */
-	push1 = tempbx;		/* push bx temppush1 */
-	if (SiS_IF_DEF_TRUMPION == 0) {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				tempax = SiS_VGAVDE;
-			}
-		}
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			if (SiS_LCDResInfo == Panel800x600)
-				tempax = 600;
-			if (SiS_LCDResInfo == Panel1024x768)
-				tempax = 768;
-		}
-	} else
-		tempax = SiS_VGAVDE;
-	tempbx = tempbx + tempax;
-	tempax = SiS_VT;	/* VT  */
-	if (tempbx >= SiS_VT) {
-		tempbx = tempbx - tempax;
-	}
-	push2 = tempbx;		/* push bx  temppush2  */
-	tempcx = tempcx >> 1;
-	tempbx = tempbx + tempcx;
-	tempbx++;		/* BPLVRS  */
-	if (tempbx >= tempax) {
-		tempbx = tempbx - tempax;
-	}
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x18, temp);	/* Part1_18h  */
-	tempcx = tempcx >> 3;
-	tempcx = tempcx + tempbx;
-	tempcx++;		/* BPLVRE  */
-	temp = tempcx & 0x00FF;
-	temp = temp & 0x0F;
-	SiS_SetRegANDOR (SiS_Part1Port, 0x19, ~0x00F, temp);	/* Part1_19h  */
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp & 0x07;
-	temp = temp << 3;	/* BPLDESKEW =0 */
-	tempbx = SiS_VGAVDE;
-	if (tempbx != SiS_VDE) {
-		temp = temp | 0x40;
-	}
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		temp = temp | 0x40;
-	}
-	if (SiS_LCDInfo & LCDRGB18Bit) {
-		temp = temp | 0x80;
-	}
-	SiS_SetRegANDOR (SiS_Part1Port, 0x1A, 0x07, temp);	/* Part1_1Ah */
-
-	tempecx = SiS_VGAVT;
-	tempebx = SiS_VDE;
-	tempeax = SiS_VGAVDE;
-	tempecx = tempecx - tempeax;	/* VGAVT-VGAVDE  */
-	tempeax = tempeax << 6;
-	temp = (USHORT) (tempeax % tempebx);
-	tempeax = tempeax / tempebx;
-	if (temp != 0) {
-		tempeax++;
-	}
-	tempebx = tempeax;	/* BPLVCFACT  */
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		tempebx = tempebx & 0x003F;
-	}
-	temp = (USHORT) (tempebx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x1E, temp);	/* Part1_1Eh */
-
-	/*add for 301b different 301 */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		tempecx = SiS_VGAVT;
-		tempebx = SiS_VDE;
-		tempeax = SiS_VGAVDE;
-		tempecx = tempecx - tempeax;	/* VGAVT-VGAVDE  */
-		tempeax = tempeax << 18;
-		temp = (USHORT) (tempeax % tempebx);
-		tempeax = tempeax / tempebx;
-		if (temp != 0) {
-			tempeax++;
-		}
-		tempebx = tempeax;	/* BPLVCFACT  */
-		tempvcfact = tempeax;	/*301b */
-		temp = (USHORT) (tempebx & 0x00FF);
-		SiS_SetReg1 (SiS_Part1Port, 0x37, temp);
-		temp = (USHORT) ((tempebx & 0x00FF00) >> 8);
-		SiS_SetReg1 (SiS_Part1Port, 0x36, temp);
-		temp = (USHORT) ((tempebx & 0x00030000) >> 16);
-		if (SiS_VDE == SiS_VGAVDE) {
-			temp = temp | 0x04;
-		}
-
-		SiS_SetReg1 (SiS_Part1Port, 0x35, temp);
-	}
-	/*end for 301b */
-
-	tempbx = push2;		/* p bx temppush2 BPLVDEE  */
-	tempcx = push1;		/* pop cx temppush1 NPLVDES */
-	push1 = (USHORT) (tempeax & 0xFFFF);
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		if (SiS_LCDResInfo == Panel800x600) {
-			if (resinfo == 7)
-				tempcx++;
-		} else {
-			if (SiS_LCDResInfo == Panel1024x768) {
-				if (resinfo == 8)
-					tempcx++;
-			}
-		}
-	}
+   SiS_EnableBridge(HwDeviceExtension,BaseAddr);
+   if(SiS_IF_DEF_CH7005==1) {
+	if(SiS_VBInfo&SetCRT2ToTV) {
+	     /* TW: Disable LCD panel when using TV */
+	     SiS_SetRegANDOR(SiS_P3c4,0x11,0xFF,0x0C);
+	} else {
+	     /* TW: Disable TV when using LCD */
+	     SiS_SetCHTVRegANDOR(0x010E,0xF8);
+	}
+   }
+   SiS_DisplayOn();
+   SiS_LockCRT2(HwDeviceExtension, BaseAddr);
+   return 1;
+}
+
+void
+SiS_SetGroup1(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+              PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+{
+  USHORT  temp=0,tempax=0,tempbx=0,tempcx=0;
+  USHORT  pushbx=0,CRT1Index=0;
+  USHORT  modeflag,resinfo=0;
+
+  if(ModeNo<=0x13) {
+  	/* TW: Do nothing for std modes */
+  } else {
+    	CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+    	CRT1Index=CRT1Index&0x3F;
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+  /*301b*/ 
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+         && (SiS_VBInfo&SetCRT2ToLCDA) ) {
+	   /* TW: Do nothing for these bridge types here */
+  } else {
+     SiS_SetCRT2Offset(SiS_Part1Port,ROMAddr,ModeNo,ModeIdIndex,
+      		       RefreshRateTableIndex,HwDeviceExtension);
+     if (HwDeviceExtension->jChipType < SIS_315H ) /* 300 series */
+    	   SiS_SetCRT2FIFO(SiS_Part1Port,ROMAddr,ModeNo,
+	                   HwDeviceExtension);
+     else 					   /* 310 series */
+           SiS_SetCRT2FIFO2(SiS_Part1Port,ROMAddr,ModeNo,
+	                   HwDeviceExtension);
+
+     SiS_SetCRT2Sync(BaseAddr,ROMAddr,ModeNo,
+                     RefreshRateTableIndex);
+  }
+
+  if (ModeNo<=0x13)
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+  /*301b*/
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+   					&& (SiS_VBInfo&SetCRT2ToLCDA) ) {
+     	SiS_SetGroup1_LCDA(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+     	                   HwDeviceExtension,RefreshRateTableIndex);
+  /*end 301b*/
+  } else if (HwDeviceExtension->jChipType < SIS_315H ) {
+    /* ------------- 300 series --------------*/
+    temp=(SiS_VGAHT-1)&0x0FF;   					/* BTVGA2HT 0x08,0x09 */
+    SiS_SetReg1(SiS_Part1Port,0x08,temp);
+    temp=(((SiS_VGAHT-1)&0xFF00)>>8)<<4;
+    SiS_SetRegANDOR(SiS_Part1Port,0x09,~0x0F0,temp); 	/* <------------------- */
+
+    temp=(SiS_VGAHDE+12)&0x0FF;                               		/* BTVGA2HDEE 0x0A,0x0C */
+    SiS_SetReg1(SiS_Part1Port,0x0A,temp); 		/* <------------------- */
+        
+    pushbx=SiS_VGAHDE+12;                                     		/* bx  BTVGA@HRS 0x0B,0x0C */
+    tempcx=(SiS_VGAHT-SiS_VGAHDE)>>2;                           	/* cx */
+    tempbx=pushbx+tempcx;
+    tempcx=tempcx<<1;
+    tempcx=tempcx+tempbx;
+    
+    if(SiS_IF_DEF_LVDS==0) {
+      if(SiS_VBInfo&SetCRT2ToRAMDAC){
+        tempbx = SiS_CRT1Table[CRT1Index].CR[4];
+        tempbx = tempbx|((SiS_CRT1Table[CRT1Index].CR[14]&0xC0)<<2);
+        tempbx = (tempbx-1)<<3;
+        tempcx = SiS_CRT1Table[CRT1Index].CR[5];
+        tempcx = tempcx&0x1F;
+        temp = SiS_CRT1Table[CRT1Index].CR[15];
+        temp = (temp&0x04)<<(6-2);
+        tempcx=((tempcx|temp)-1)<<3;
+      }
+    }
+   /*add for hardware request*/
+    if((SiS_VBInfo&SetCRT2ToTV)&&(resinfo==0x08)){
+        if(SiS_VBInfo&SetPALTV){
+      		tempbx=1040;
+      		tempcx=1042;
+      	} else {
+      		tempbx=1040;
+      		tempcx=1042;
+      	}
+    }
+
+    temp=tempbx&0x00FF;
+    SiS_SetReg1(SiS_Part1Port,0x0B,temp); 		/* <------------------- */
+    
+  } else {
+     /* ---------------------- 310 series ------------------*/
+     if (modeflag&HalfDCLK) { /* for low resolution mode */
+         temp=(SiS_VGAHT/2-1)&0x0FF;                             /* BTVGA2HT 0x08,0x09 */
+         SiS_SetReg1(SiS_Part1Port,0x08,temp);
+         temp=(((SiS_VGAHT/2-1)&0xFF00)>>8)<<4;
+         SiS_SetRegANDOR(SiS_Part1Port,0x09,~0x0F0,temp);
+         temp=(SiS_VGAHDE/2+16)&0x0FF;                           /* BTVGA2HDEE 0x0A,0x0C */
+         SiS_SetReg1(SiS_Part1Port,0x0A,temp);
+
+         pushbx=SiS_VGAHDE/2+16;
+         tempcx=((SiS_VGAHT-SiS_VGAHDE)/2)>>2;                   /* cx */
+         tempbx=pushbx+tempcx;                                   /* bx  BTVGA@HRS 0x0B,0x0C */
+         tempcx=tempcx+tempbx;
+
+         if(SiS_IF_DEF_LVDS==0) {
+             if(SiS_VBInfo&SetCRT2ToRAMDAC){
+                tempbx = SiS_CRT1Table[CRT1Index].CR[4];
+                tempbx = tempbx|((SiS_CRT1Table[CRT1Index].CR[14]&0xC0)<<2);
+                tempbx = (tempbx-3)<<3;         		/*(VGAHRS-3)*8 */
+                tempcx = SiS_CRT1Table[CRT1Index].CR[5];
+                tempcx = tempcx&0x1F;
+                temp = SiS_CRT1Table[CRT1Index].CR[15];
+                temp = (temp&0x04)<<(5-2);      		/*VGAHRE D[5]*/
+                tempcx=((tempcx|temp)-3)<<3;    		/* (VGAHRE-3)*8 */
+             }
+         }
+         tempbx += 4;
+         tempcx += 4;
+         if (tempcx>(SiS_VGAHT/2))
+              tempcx = SiS_VGAHT/2;
+         temp=tempbx&0x00FF;
+         SiS_SetReg1(SiS_Part1Port,0x0B,temp);
+    } else {
+         temp=(SiS_VGAHT-1)&0x0FF;                             	/* BTVGA2HT 0x08,0x09 */
+         SiS_SetReg1(SiS_Part1Port,0x08,temp);
+         temp=(((SiS_VGAHT-1)&0xFF00)>>8)<<4;
+         SiS_SetRegANDOR(SiS_Part1Port,0x09,~0x0F0,temp);
+         temp=(SiS_VGAHDE+16)&0x0FF;                            /* BTVGA2HDEE 0x0A,0x0C */
+         SiS_SetReg1(SiS_Part1Port,0x0A,temp);
+
+         pushbx=SiS_VGAHDE+16;
+         tempcx=(SiS_VGAHT-SiS_VGAHDE)>>2;                      /* cx */
+         tempbx=pushbx+tempcx;                                  /* bx  BTVGA@HRS 0x0B,0x0C */
+         tempcx=tempcx+tempbx;
+      
+         if(SiS_IF_DEF_LVDS==0) {
+             if(SiS_VBInfo&SetCRT2ToRAMDAC){
+                tempbx = SiS_CRT1Table[CRT1Index].CR[4];
+                tempbx = tempbx|((SiS_CRT1Table[CRT1Index].CR[14]&0xC0)<<2);
+                tempbx = (tempbx-3)<<3;         		/*(VGAHRS-3)*8 */
+                tempcx = SiS_CRT1Table[CRT1Index].CR[5];
+                tempcx = tempcx&0x1F;
+                temp = SiS_CRT1Table[CRT1Index].CR[15];
+                temp = (temp&0x04)<<(5-2);      		/*VGAHRE D[5]*/
+                tempcx=((tempcx|temp)-3)<<3;    		/* (VGAHRE-3)*8 */
+                tempbx += 16;
+                tempcx += 16;
+             }
+         }
+         if (tempcx>SiS_VGAHT)
+        	tempcx = SiS_VGAHT;
+        /*add for hardware request*/
+         if((SiS_VBInfo&SetCRT2ToTV)&&(resinfo==0x08)){
+             if(SiS_VBInfo&SetPALTV){
+      		 tempbx=1040;
+      		 tempcx=1042;
+      	     } else {
+      		 tempbx=1040;
+      		 tempcx=1042;
+      	     }
+         }
+         temp=tempbx&0x00FF;
+         SiS_SetReg1(SiS_Part1Port,0x0B,temp);
+     }
+  }
 
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp & 0x07;
-	temp = temp << 3;
-	temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
-	SiS_SetReg1 (SiS_Part1Port, 0x1D, temp);	/* Part1_1Dh */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x1C, temp);	/* Part1_1Ch  */
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x1B, temp);	/* Part1_1Bh  */
-
-	tempecx = SiS_VGAHDE;
-	tempebx = SiS_HDE;
-	tempeax = tempecx;
-	tempeax = tempeax << 6;
-	tempeax = tempeax << 10;
-	tempeax = tempeax / tempebx;
-	if (tempebx == tempecx) {
-		tempeax = 65535;
-	}
-	tempecx = tempeax;
-	tempeax = SiS_VGAHDE;	/*change VGAHT->VGAHDE */
-	tempeax = tempeax << 6;
-	tempeax = tempeax << 10;
-	tempeax = tempeax / tempecx;
-	tempecx = tempecx << 16;
-	tempeax = tempeax - 1;
-	tempecx = tempecx | (tempeax & 0x00FFFF);
-	temp = (USHORT) (tempecx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x1F, temp);	/* Part1_1Fh  */
-
-	tempeax = SiS_VGAVDE;
-	tempeax = tempeax << 18;	/*301b */
-	tempeax = tempeax / tempvcfact;
-	tempbx = (USHORT) (tempeax & 0x0FFFF);
-	if (SiS_LCDResInfo == Panel1024x768)
-		tempbx--;
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		tempbx = 1;
-	}
-	temp = ((tempbx & 0xFF00) >> 8) << 3;
-	temp = temp | (USHORT) (((tempecx & 0x0000FF00) >> 8) & 0x07);
-	SiS_SetReg1 (SiS_Part1Port, 0x20, temp);	/* Part1_20h */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x21, temp);	/* Part1_21h */
-	tempecx = tempecx >> 16;	/* BPLHCFACT  */
-	if (modeflag & HalfDCLK) {
-		tempecx = tempecx >> 1;
-	}
-	temp = (USHORT) ((tempecx & 0x0000FF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x22, temp);	/* Part1_22h */
-	temp = (USHORT) (tempecx & 0x000000FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x23, temp);
-	/*add dstn new register */
-	if (SiS_IF_DEF_DSTN) {
-		SiS_SetReg1 (SiS_Part1Port, 0x1E, 0x01);
-		SiS_SetReg1 (SiS_Part1Port, 0x25, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x26, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x27, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x28, 0x87);
-		SiS_SetReg1 (SiS_Part1Port, 0x29, 0x5A);
-		SiS_SetReg1 (SiS_Part1Port, 0x2A, 0x4B);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x44, ~0x007, 0x03);
-		tempbx = SiS_HDE;	/*Blps=lcdhdee(lcdhdes+HDE) +64 */
-		tempbx = tempbx + 64;
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x38, temp);
-		temp = ((tempbx & 0xFF00) >> 8) << 3;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x35, ~0x078, temp);
-		tempbx = tempbx + 32;	/*Blpe=lBlps+32 */
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x39, temp);
-		SiS_SetReg1 (SiS_Part1Port, 0x3A, 0x00);	/*Bflml=0 */
-		SiS_SetRegANDOR (SiS_Part1Port, 0x3C, ~0x007, 0x00);
-		tempbx = SiS_VDE;
-		tempbx = tempbx / 2;
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x3B, temp);
-		temp = ((tempbx & 0xFF00) >> 8) << 3;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x3C, ~0x038, temp);
-		tempeax = SiS_HDE;	/* BDxFIFOSTOP= (HDE*4)/128 */
-		tempeax = tempeax * 4;
-		tempebx = 128;
-		temp = (USHORT) (tempeax % tempebx);
-		tempeax = tempeax / tempebx;
-		if (temp != 0) {
-			tempeax++;
-		}
-		temp = (USHORT) (tempeax & 0x0000003F);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x45, ~0x0FF, temp);
-		SiS_SetReg1 (SiS_Part1Port, 0x3F, 0x00);	/*BDxWadrst0 */
-		SiS_SetReg1 (SiS_Part1Port, 0x3E, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x3D, 0x10);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x3C, ~0x040, 0x00);
-		tempax = SiS_HDE;
-		tempax = tempax >> 4;	/*BDxWadroff = HDE*4/8/8  */
-		pushcx = tempax;
-		temp = tempax & 0x00FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x43, temp);
-		temp = ((tempax & 0xFF00) >> 8) << 3;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x44, ~0x0F8, temp);
-		tempax = SiS_VDE;	/*BDxWadrst1 = BDxWadrst0+BDxWadroff*VDE */
-		tempeax = (tempax * pushcx);
-		tempebx = 0x00100000 + tempeax;
-		temp = (USHORT) tempebx & 0x000000FF;
-		SiS_SetReg1 (SiS_Part1Port, 0x42, temp);
-		temp = (USHORT) ((tempebx & 0x0000FF00) >> 8);
-		SiS_SetReg1 (SiS_Part1Port, 0x41, temp);
-		temp = (USHORT) ((tempebx & 0x00FF0000) >> 16);
-		SiS_SetReg1 (SiS_Part1Port, 0x40, temp);
-		temp = (USHORT) ((tempebx & 0x01000000) >> 24);
-		temp = temp << 7;
-		SiS_SetRegANDOR (SiS_Part1Port, 0x3C, ~0x080, temp);
-		SiS_SetReg1 (SiS_Part1Port, 0x2F, 0x03);
-		SiS_SetReg1 (SiS_Part1Port, 0x03, 0x50);
-		SiS_SetReg1 (SiS_Part1Port, 0x04, 0x00);
-		SiS_SetReg1 (SiS_Part1Port, 0x2F, 0x01);
-		SiS_SetReg1 (SiS_Part1Port, 0x13, 0x00);
-		SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);
-		SiS_SetReg1 (SiS_P3c4, 0x1e, 0x62);
-		SiS_SetReg1 (SiS_Part1Port, 0x19, 0x38);
-		SiS_SetReg1 (SiS_Part1Port, 0x1e, 0x7d);
-	}
-	/*end add dstn */
+  /* TW: The following is done for all bridge/chip types/series */
 
-	return;
+#if 1
+  tempax = (tempax&0x00FF)|(tempbx&0xFF00); /* TW: tempax not used above!!!*/
+  tempbx=pushbx;
+  tempbx=(tempbx&0x00FF)|((tempbx&0xFF00)<<4);
+  tempax=tempax|(tempbx&0xFF00);
+  temp=(tempax&0xFF00)>>8;
+#endif
+#if 0
+  /* TW: new code: */
+  tempax=(tempbx&0xFF00)>>8;
+  tempbx=(((pushbx&0xFF00)>>8)<<4)&0xFF;
+  temp=tempax|tempbx;
+#endif
+  SiS_SetReg1(SiS_Part1Port,0x0C,temp); 		/* <------------------- */
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x0D,temp); 		/* <------------------- */
+  tempcx=SiS_VGAVT-1;
+  temp=tempcx&0x00FF;
+  if(SiS_IF_DEF_CH7005==1) {
+    	if(SiS_VBInfo&SetCRT2ToTV) {
+      		temp--;
+    	}
+  }
+  SiS_SetReg1(SiS_Part1Port,0x0E,temp); 		/* <------------------- */
+  tempbx=SiS_VGAVDE-1;
+  temp=tempbx&0x00FF;
+  /* [Do the same if CH7005==1 as above?] */
+  SiS_SetReg1(SiS_Part1Port,0x0F,temp); 		/* <------------------- */
+  temp=((tempbx&0xFF00)<<3)>>8;
+  temp=temp|((tempcx&0xFF00)>>8);
+  SiS_SetReg1(SiS_Part1Port,0x12,temp); 		/* <------------------- */
+
+  tempax=SiS_VGAVDE;
+  tempbx=SiS_VGAVDE;
+  tempcx=SiS_VGAVT;
+  tempbx=(SiS_VGAVT+SiS_VGAVDE)>>1;                     	/*  BTVGA2VRS     0x10,0x11   */
+  tempcx=((SiS_VGAVT-SiS_VGAVDE)>>4)+tempbx+1;          	/*  BTVGA2VRE     0x11        */
+  if(SiS_IF_DEF_LVDS==0) {
+    	if(SiS_VBInfo & SetCRT2ToRAMDAC){
+      		tempbx = SiS_CRT1Table[CRT1Index].CR[8];
+      		temp = SiS_CRT1Table[CRT1Index].CR[7];
+      		if(temp&0x04) tempbx=tempbx|0x0100;
+      		if(temp&0x80) tempbx=tempbx|0x0200;
+      		temp = SiS_CRT1Table[CRT1Index].CR[13];
+      		if(temp&0x08) tempbx=tempbx|0x0400;
+      		temp = SiS_CRT1Table[CRT1Index].CR[9];
+      		tempcx=(tempcx&0xFF00)|(temp&0x00FF);
+    	}
+  }
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x10,temp); 		/* <------------------- */
+  temp=((tempbx&0xFF00)>>8)<<4;
+  temp=((tempcx&0x000F)|(temp));
+  SiS_SetReg1(SiS_Part1Port,0x11,temp); 		/* <------------------- */
+  if(SiS_IF_DEF_LVDS==0) {
+    	temp=0x20;
+    	if(SiS_LCDResInfo==Panel1280x1024) temp=0x20;
+    	if(SiS_LCDResInfo==Panel1280x960) temp=0x24;
+    	if(SiS_VBInfo&SetCRT2ToTV) temp=0x08;
+    	if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+      		if(SiS_VBInfo&SetInSlaveMode) temp=0x2c;
+      		else temp=0x20;
+    	}
+  } else {
+    	temp=0x20;
+  }
+
+  if (HwDeviceExtension->jChipType < SIS_315H ) {
+    /* ---------- 300 series -------------- */
+
+    SiS_SetRegANDOR(SiS_Part1Port,0x13,~0x03C,temp); 	/* <----------------- */
+	/* TW: This register will be adapted according to LCD
+	 *     panel type later in the OEM setup functions.
+	 *     (Various panel types require a different delay
+	 *     such as Clevo 2202; however, on most panels,
+	 *     0x20 does nicely.)
+	 */
+
+  } else {
+    /* ----------- 310 series ---------------*/
+    temp >>=2;    /* TW: This is typical SiS code: First calulate temp, then overwrite it... */
+    temp = 0x11;    						/*  ynlai 05/30/2001 for delay compenation  */
+    SiS_SetReg1(SiS_Part1Port,0x2D,temp);
+    /*SiS_SetRegANDOR(SiS_Part1Port,0x2D,~0x00F,temp);*/
+    SiS_SetRegAND(SiS_Part1Port,0x13,0xEF);  			/* BDirectLCD=0 for lcd ?? */
+    tempax=0;
+
+    if (modeflag&DoubleScanMode) tempax |= 0x80;
+    if (modeflag&HalfDCLK) tempax |= 0x40;
+    SiS_SetRegANDOR(SiS_Part1Port,0x2C,~0x0C0,tempax);
+  }
+
+  if(SiS_IF_DEF_LVDS==0) {
+    	SiS_SetGroup1_301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                  HwDeviceExtension,RefreshRateTableIndex);
+  } else {
+    	SiS_SetGroup1_LVDS(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                   HwDeviceExtension,RefreshRateTableIndex);
+  }
+}
+
+void
+SiS_SetGroup1_301(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                  PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+{
+  USHORT  push1,push2;
+  USHORT  tempax,tempbx,tempcx,temp;
+  USHORT  resinfo,modeflag;
+  USHORT  CRT1Index;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+    	CRT1Index = CRT1Index &0x3F;
+  }
+
+  if(!(SiS_VBInfo&SetInSlaveMode))  return;
+
+  tempax=0xFFFF;
+  if(!(SiS_VBInfo&SetCRT2ToTV)) {
+    	tempax=SiS_GetVGAHT2();
+  }
+  if(modeflag&Charx8Dot) tempcx=0x08;
+  else tempcx=0x09;
+  if(tempax>=SiS_VGAHT) {
+    	tempax=SiS_VGAHT;
+  }
+  if(modeflag&HalfDCLK) {
+    	tempax=tempax>>1;
+  }
+  tempax=(tempax/tempcx)-5;
+  tempbx=tempax;
+  temp=0xFF;                                            	/* set MAX HT */
+  SiS_SetReg1(SiS_Part1Port,0x03,temp);
+
+  tempax=SiS_VGAHDE;                                           	/* 0x04 Horizontal Display End */
+  if(modeflag&HalfDCLK) tempax=tempax>>1;
+  tempax=(tempax/tempcx)-1;
+  tempbx=tempbx|((tempax&0x00FF)<<8);
+  temp=tempax&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x04,temp);
+
+  temp=(tempbx&0xFF00)>>8;
+  if(SiS_VBInfo&SetCRT2ToTV){
+    	temp=temp+2;
+    	if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+      		if(resinfo==7) temp=temp-2;
+    	}
+  }
+  SiS_SetReg1(SiS_Part1Port,0x05,temp);                         /* 0x05 Horizontal Display Start */
+  SiS_SetReg1(SiS_Part1Port,0x06,0x03);                       	/* 0x06 Horizontal Blank end     */
+                                                           	/* 0x07 horizontal Retrace Start */
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+    temp=(tempbx&0x00FF)-1;
+    if(!(modeflag&HalfDCLK)) {
+      temp=temp-6;
+      if(SiS_SetFlag&TVSimuMode) {
+        temp=temp-4;
+        if(ModeNo>0x13) temp=temp-10;
+      }
+    }
+  } else {
+    tempcx=tempbx&0x00FF;
+    tempbx=(tempbx&0xFF00)>>8;
+    tempcx=(tempcx+tempbx)>>1;
+    temp=(tempcx&0x00FF)+2;
+    if(SiS_VBInfo&SetCRT2ToTV){
+       temp=temp-1;
+       if(!(modeflag&HalfDCLK)){
+          if((modeflag&Charx8Dot)){
+            temp=temp+4;
+            if(SiS_VGAHDE>=800){
+              temp=temp-6;
+            }
+          }
+        }
+    } else {
+       if(!(modeflag&HalfDCLK)){
+         temp=temp-4;
+         if(SiS_LCDResInfo!=Panel1280x960) {
+           if(SiS_VGAHDE>=800){
+             temp=temp-7;
+             if(SiS_ModeType==ModeEGA){
+               if(SiS_VGAVDE==1024){
+                 temp=temp+15;
+                 if(SiS_LCDResInfo!=Panel1280x1024){
+                    temp=temp+7;
+                 }
+               }
+             }
+             if(SiS_VGAHDE>=1280){
+               if(SiS_LCDResInfo!=Panel1280x960) {
+                 if(SiS_LCDInfo&LCDNonExpanding) {
+                   temp=temp+28;
+                 }
+               }
+             }
+           }
+         }
+       }
+    }
+  }
+ 
+  SiS_SetReg1(SiS_Part1Port,0x07,temp);                       	/* 0x07 Horizontal Retrace Start */
+  SiS_SetReg1(SiS_Part1Port,0x08,0);                            /* 0x08 Horizontal Retrace End   */
+  
+  if(SiS_VBInfo&SetCRT2ToTV) {
+        if(SiS_SetFlag&TVSimuMode) {
+            if((ModeNo==0x06)||(ModeNo==0x10)||(ModeNo==0x11)||(ModeNo==0x13)||(ModeNo==0x0F)){
+             	SiS_SetReg1(SiS_Part1Port,0x07,0x5b);
+             	SiS_SetReg1(SiS_Part1Port,0x08,0x03);
+            }
+            if((ModeNo==0x00)||(ModeNo==0x01)) {
+             	if(SiS_VBInfo&SetNTSCTV) {
+             		SiS_SetReg1(SiS_Part1Port,0x07,0x2A);
+             		SiS_SetReg1(SiS_Part1Port,0x08,0x61);
+              	} else {
+             		SiS_SetReg1(SiS_Part1Port,0x07,0x2A);
+             		SiS_SetReg1(SiS_Part1Port,0x08,0x41);
+             		SiS_SetReg1(SiS_Part1Port,0x0C,0xF0);
+            	}
+           }
+           if((ModeNo==0x02)||(ModeNo==0x03)||(ModeNo==0x07)){
+            	if(SiS_VBInfo&SetNTSCTV) {
+           		SiS_SetReg1(SiS_Part1Port,0x07,0x54);
+           		SiS_SetReg1(SiS_Part1Port,0x08,0x00);
+            	} else {
+           		SiS_SetReg1(SiS_Part1Port,0x07,0x55);
+           		SiS_SetReg1(SiS_Part1Port,0x08,0x00);
+           		SiS_SetReg1(SiS_Part1Port,0x0C,0xF0);
+           	}
+           }
+           if((ModeNo==0x04)||(ModeNo==0x05)||(ModeNo==0x0D)||(ModeNo==0x50)){
+            	if(SiS_VBInfo&SetNTSCTV) {
+            		SiS_SetReg1(SiS_Part1Port,0x07,0x30);
+            		SiS_SetReg1(SiS_Part1Port,0x08,0x03);
+            	} else {
+           		SiS_SetReg1(SiS_Part1Port,0x07,0x2f);
+           		SiS_SetReg1(SiS_Part1Port,0x08,0x02);
+                }
+           }
+       } 
+  }
+  
+  SiS_SetReg1(SiS_Part1Port,0x18,0x03);                         	/* 0x18 SR08    */
+  SiS_SetRegANDOR(SiS_Part1Port,0x19,0xF0,0x00);
+  SiS_SetReg1(SiS_Part1Port,0x09,0xFF);                         	/* 0x09 Set Max VT    */
+
+  tempbx=SiS_VGAVT;
+  push1=tempbx;
+  tempcx=0x121;
+  tempbx=SiS_VGAVDE;                                        		/* 0x0E Virtical Display End */
+  if(tempbx==357) tempbx=350;
+  if(tempbx==360) tempbx=350;
+  if(tempbx==375) tempbx=350;
+  if(tempbx==405) tempbx=400;
+  if(tempbx==420) tempbx=400;
+  if(tempbx==525) tempbx=480;
+  push2=tempbx;
+  if(SiS_VBInfo&SetCRT2ToLCD) {
+    	if(SiS_LCDResInfo==Panel1024x768) {
+      		if(!(SiS_SetFlag&LCDVESATiming)) {
+        		if(tempbx==350) tempbx=tempbx+5;
+        		if(tempbx==480) tempbx=tempbx+5;
+      		}
+    	}
+  }
+  tempbx--;
+  temp=tempbx&0x00FF;
+  tempbx--;
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x10,temp);                    		/* 0x10 vertical Blank Start */
+  tempbx=push2;
+  tempbx--;
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x0E,temp);
+  if(tempbx&0x0100){
+    	tempcx=tempcx|0x0002;
+  }
+  tempax=0x000B;
+  if(modeflag&DoubleScanMode){
+    	tempax=tempax|0x08000;
+  }
+  if(tempbx&0x0200){
+    	tempcx=tempcx|0x0040;
+  }
+
+  temp=(tempax&0xFF00)>>8;
+  SiS_SetReg1(SiS_Part1Port,0x0B,temp);
+  if(tempbx&0x0400){
+    	tempcx=tempcx|0x0600;
+  }
+  SiS_SetReg1(SiS_Part1Port,0x11,0x00);                         	/* 0x11 Vertival Blank End */
+
+  tempax=push1;
+  tempax=tempax-tempbx;                              			/* 0x0C Vertical Retrace Start */
+  tempax=tempax>>2;
+  push1=tempax;
+
+  if(resinfo!=0x09) {
+    	tempax=tempax<<1;
+    	tempbx=tempax+tempbx;
+  }
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+    	tempbx=tempbx-10;
+  } else {
+    	if(SiS_SetFlag&TVSimuMode) {
+      		if(SiS_VBInfo&SetPALTV) {
+        		tempbx=tempbx+40;
+      		}
+    	}
+  }
+  tempax=push1;
+  tempax=tempax>>2;
+  tempax++;
+  tempax=tempax+tempbx;
+  push1=tempax;
+  if((SiS_VBInfo&SetPALTV)) {
+    	if(tempbx<=513)  {
+      		if(tempax>=513) {
+        		tempbx=513;
+      		}
+    	}
+  }
+  temp=(tempbx&0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x0C,temp);
+  tempbx--;
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x10,temp);
+  if(tempbx&0x0100){
+    	tempcx=tempcx|0x0008;
+  }
+  if(tempbx&0x0200){
+    	SiS_SetRegANDOR(SiS_Part1Port,0x0B,0x0FF,0x20);
+  }
+  tempbx++;
+  if(tempbx&0x0100){
+    	tempcx=tempcx|0x0004;
+  }
+  if(tempbx&0x0200){
+    	tempcx=tempcx|0x0080;
+  }
+  if(tempbx&0x0400){
+    	tempcx=tempcx|0x0C00;
+  }
+  tempbx=push1;
+  temp=tempbx&0x00FF;
+  temp=temp&0x0F;
+  SiS_SetReg1(SiS_Part1Port,0x0D,temp);                    		/* 0x0D vertical Retrace End */
+  if(tempbx&0x0010) {
+    	tempcx=tempcx|0x2000;
+  }
+
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x0A,temp);                    		/* 0x0A CR07 */
+  temp=(tempcx&0x0FF00)>>8;
+  SiS_SetReg1(SiS_Part1Port,0x17,temp);                    		/* 0x17 SR0A */
+  tempax=modeflag;
+  temp=(tempax&0xFF00)>>8;
+
+  temp=(temp>>1)&0x09;
+  SiS_SetReg1(SiS_Part1Port,0x16,temp);                    		/* 0x16 SR01 */
+  SiS_SetReg1(SiS_Part1Port,0x0F,0);                         		/* 0x0F CR14 */
+  SiS_SetReg1(SiS_Part1Port,0x12,0);                         		/* 0x12 CR17 */
+  if(SiS_LCDInfo&LCDRGB18Bit) temp=0x80;
+  else temp=0x00;
+  SiS_SetReg1(SiS_Part1Port,0x1A,temp);                         	/* 0x1A SR0E */
+  return;
+}
+
+/* TW: This seems to be for some of 301B/302B/301LV/302LV as well
+ *     which confuses me. In init.c, there is code for these bridges
+ *     which is executed ONLY if IF_DEF_LVDS is 0. The following
+ *     is being called only if IF_DEF_LVDS is NOT 0, and it contains
+ *     code for 301B et al as well. Is IF_DEF_LVDS now 0 or 1 on
+ *     301B/302B/301LV/302LV?
+ */
+void SiS_SetGroup1_LVDS(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+		        USHORT ModeIdIndex,
+                        PSIS_HW_DEVICE_INFO HwDeviceExtension,
+			USHORT RefreshRateTableIndex)
+{
+  USHORT modeflag,resinfo;
+  USHORT push1,push2,tempax,tempbx,tempcx,temp,pushcx;
+  ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      	/* si+St_ResInfo */
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     	/* si+Ext_ResInfo */
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+  tempax=SiS_LCDHDES;
+  tempbx=SiS_HDE;
+  tempcx=SiS_HT;
+
+  tempcx=tempcx-tempbx;                                    		/* HT-HDE  */
+  if(SiS_LCDInfo&LCDNonExpanding) {
+    	if(SiS_LCDResInfo==Panel640x480)  tempbx=640;
+    	if(SiS_LCDResInfo==Panel800x600)  tempbx=800;
+    	if(SiS_LCDResInfo==Panel1024x768) tempbx=1024;
+  }
+  push1=tempax;
+  tempax=tempax+tempbx;                                    		/* lcdhdee  */
+  tempbx=SiS_HT;
+  if(tempax>=tempbx){
+    	tempax=tempax-tempbx;
+  }
+  push2=tempax;	                                                       	/* push ax   lcdhdee  */
+  tempcx=tempcx>>2;                                        		/* temp  */
+  tempcx=tempcx+tempax;                                    		/* lcdhrs  */
+  if(tempcx>=tempbx){
+    	tempcx=tempcx-tempbx;
+  }									/* v ah,cl  */
+  tempax=tempcx;
+  tempax=tempax>>3;                                        		/* BPLHRS */
+  temp=tempax&0x00FF;
+  if(SiS_LCDResInfo==Panel640x480){                         		/*adjust for panel 640x480*/
+      	temp=temp-4;
+  }
+  SiS_SetReg1(SiS_Part1Port,0x14,temp);		/* <------------------ */ 	/* Part1_14h  */
+  temp=(tempax&0x00FF)+10;
+  temp=temp&0x01F;
+  temp=temp|(((tempcx&0x00ff)&0x07)<<5);
+  /*fstn*/
+  if(SiS_IF_DEF_FSTN){
+      	temp=0x20;
+  }
+  SiS_SetReg1(SiS_Part1Port,0x15,temp);    	/* <------------------- */      /* Part1_15h  */
+  tempbx=push2;                                          			/* lcdhdee  */
+  tempcx=push1;                                         			/* lcdhdes  */
+  temp=(tempcx&0x00FF);
+  temp=temp&0x07;                                      				/* BPLHDESKEW  */
+  SiS_SetReg1(SiS_Part1Port,0x1A,temp);   	/* <------------------- */      /* Part1_1Ah  */
+  tempcx=tempcx>>3;                                        			/* BPLHDES */
+  temp=(tempcx&0x00FF);
+  if(ModeNo==0x5b){                            					/*fix fstn mode=5b*/
+      	temp--;
+  }
+  SiS_SetReg1(SiS_Part1Port,0x16,temp);    	/* <------------------- */      /* Part1_16h  */
+  if(tempbx&0x07) tempbx=tempbx+8;
+  tempbx=tempbx>>3;                                        			/* BPLHDEE  */
+  temp=tempbx&0x00FF;
+  if(ModeNo==0x5b){                            					/*fix fstn mode=5b*/
+      	temp--;
+  }
+  SiS_SetReg1(SiS_Part1Port,0x17,temp);   	/* <------------------- */      /* Part1_17h  */
+
+  tempcx=SiS_VGAVT;
+  tempbx=SiS_VGAVDE;
+  tempcx=tempcx-tempbx;                                    			/* GAVT-VGAVDE  */
+  tempbx=SiS_LCDVDES;			                    			/* VGAVDES  */
+
+  push1=tempbx;                                        				/* push bx temppush1 */
+  if(SiS_IF_DEF_TRUMPION==0){
+    	if(SiS_IF_DEF_CH7005==1) {
+      		if(SiS_VBInfo&SetCRT2ToTV) {
+        		tempax=SiS_VGAVDE;
+      		}
+    	}
+    	if(SiS_VBInfo&SetCRT2ToLCD) {
+      		if(SiS_LCDResInfo==Panel640x480)  tempax=480;
+      		if(SiS_LCDResInfo==Panel800x600)  tempax=600;
+      		if(SiS_LCDResInfo==Panel1024x768) tempax=768;
+      		if(SiS_LCDResInfo==Panel320x480)  tempax=480;
+    	}
+  } else tempax=SiS_VGAVDE;
+
+  tempbx=tempbx+tempax;
+  tempax=SiS_VT;                                               			/* VT  */
+  if(tempbx>=SiS_VT){
+    	tempbx=tempbx-tempax;
+  }
+  push2=tempbx;                                        				/* push bx  temppush2  */
+  tempcx=tempcx>>1;
+  tempbx=tempbx+tempcx;
+  tempbx++;                                                			/* BPLVRS  */
+  if(tempbx>=tempax){
+    	tempbx=tempbx-tempax;
+  }
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x18,temp);       	/* <------------------- */      /* Part1_18h  */
+  tempcx=tempcx>>3;
+  tempcx=tempcx+tempbx;
+  tempcx++;                                                			/* BPLVRE  */
+  temp=tempcx&0x00FF;
+  temp=temp&0x0F;
+  SiS_SetRegANDOR(SiS_Part1Port,0x19,~0x00F,temp);   /* <-------------- */      /* Part1_19h  */
+
+  temp=(tempbx&0xFF00)>>8;
+  temp=temp&0x07;
+  temp=temp<<3;                                 				/* BPLDESKEW =0 */
+  tempbx=SiS_VGAVDE;
+  if(tempbx!=SiS_VDE){
+    	temp=temp|0x40;
+  }
+  if(SiS_SetFlag&EnableLVDSDDA) {
+    	temp=temp|0x40;
+  }
+  if(SiS_LCDInfo&LCDRGB18Bit) {
+    	temp=temp|0x80;
+  }
+  SiS_SetRegANDOR(SiS_Part1Port,0x1A,0x07,temp);  /* <----------------- */    	/* Part1_1Ah */
+
+  tempecx=SiS_VGAVT;
+  tempebx=SiS_VDE;
+  tempeax=SiS_VGAVDE;
+  tempecx=tempecx-tempeax;                                 			/* VGAVT-VGAVDE  */
+  tempeax=tempeax<<6;
+  temp=(USHORT)(tempeax%tempebx);
+  tempeax=tempeax/tempebx;
+  if(temp!=0){
+    	tempeax++;
+  }
+  tempebx=tempeax;                                        			/* BPLVCFACT  */
+
+  /* TW: Modified according to info from SiS - might be wrong */
+  /* if (!(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))) { */
+  if ((HwDeviceExtension->jChipType == SIS_540)||
+      (HwDeviceExtension->jChipType == SIS_630)||
+      (HwDeviceExtension->jChipType == SIS_730)||
+      (HwDeviceExtension->jChipType == SIS_300)) {
+
+  	if(SiS_SetFlag&EnableLVDSDDA) {
+    		tempebx=tempebx&0x003F;
+  	}
+  	temp=(USHORT)(tempebx&0x00FF);
+  	SiS_SetReg1(SiS_Part1Port,0x1E,temp);                       		/* Part1_1Eh */
+
+  }
+  /*add for 301b different 301*/
+  else if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+    	tempecx=SiS_VGAVT;
+    	tempebx=SiS_VDE;
+    	tempeax=SiS_VGAVDE;
+    	tempecx=tempecx-tempeax;                                 		/* VGAVT-VGAVDE  */
+    	tempeax=tempeax<<18;
+    	temp=(USHORT)(tempeax%tempebx);
+    	tempeax=tempeax/tempebx;
+    	if(temp!=0) tempeax++;
+    	tempebx=tempeax;                                        		/* BPLVCFACT  */
+    	tempvcfact=tempeax;       /*301b*/
+    	temp=(USHORT)(tempebx&0x00FF);
+    	SiS_SetReg1(SiS_Part1Port,0x37,temp);
+    	temp=(USHORT)((tempebx&0x00FF00)>>8);
+    	SiS_SetReg1(SiS_Part1Port,0x36,temp);
+    	temp=(USHORT)((tempebx&0x00030000)>>16);
+    	if(SiS_VDE==SiS_VGAVDE)	temp=temp|0x04;
+    	SiS_SetReg1(SiS_Part1Port,0x35,temp);
+  }
+  /*end for 301b*/
+  
+  tempbx=push2;                                        				/* p bx temppush2 BPLVDEE  */
+  tempcx=push1;			/* pop cx temppush1 NPLVDES */
+  push1=(USHORT)(tempeax&0xFFFF);
+  if(!(SiS_VBInfo&SetInSlaveMode)) {
+   	if(!SiS_IF_DEF_DSTN){
+    		if(SiS_LCDResInfo==Panel800x600) {
+      			if(resinfo==7) tempcx++;
+    		} else {
+      			if(SiS_LCDResInfo==Panel1024x768) {
+        			if(resinfo==8) tempcx++;
+       			}
+     		}
+   	}
+  }
+  temp=(tempbx&0xFF00)>>8;
+  temp=temp&0x07;
+  temp=temp<<3;
+  temp=temp|(((tempcx&0xFF00)>>8)&0x07);
+  SiS_SetReg1(SiS_Part1Port,0x1D,temp);     	/* <------------------- */     	/* Part1_1Dh */
+  temp=tempbx&0x00FF;
+  /*fstn*/
+  if(SiS_IF_DEF_FSTN){
+      	temp=temp+1;
+  }
+  SiS_SetReg1(SiS_Part1Port,0x1C,temp);      	/* <------------------- */   	/* Part1_1Ch  */
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x1B,temp);      	/* <------------------- */     	/* Part1_1Bh  */
+
+  tempecx=SiS_VGAHDE;
+  tempebx=SiS_HDE;
+  tempeax=tempecx;
+  tempeax=tempeax<<16;
+  tempeax=tempeax/tempebx;
+  if(tempebx==tempecx){
+    	tempeax=0xFFFF;
+  }
+  tempecx=tempeax;
+  tempeax=SiS_VGAHT; /* TW: Was SiS_VGAHDE;  - WRONG! - old (wrong) comment: "change VGAHT->VGAHDE"*/
+  tempeax=tempeax<<16;
+  tempeax=tempeax/tempecx;
+  tempecx=tempecx<<16;
+  tempeax=tempeax-1;
+  tempecx=tempecx|(tempeax&0x00FFFF);
+  temp=(USHORT)(tempecx&0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x1F,temp);  	/* <------------------- */    	/* Part1_1Fh  */
+
+  tempbx = SiS_VDE; /* TW: added this and if statement */
+  if (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+  	tempeax=SiS_VGAVDE;
+  	tempeax=tempeax<<18;          /*301b*/
+  	tempeax=tempeax/tempvcfact;
+  	tempbx=(USHORT) (tempeax&0x0FFFF);
+  }
+
+  if(SiS_LCDResInfo==Panel1024x768) tempbx--;
+
+  if(SiS_SetFlag&EnableLVDSDDA) tempbx=1;
+
+  temp=((tempbx&0xFF00)>>8)<<3;
+  temp=temp|(USHORT)(((tempecx&0x0000FF00)>>8)&0x07);
+  SiS_SetReg1(SiS_Part1Port,0x20,temp);  	/* <------------------- */    	/* Part1_20h */
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x21,temp);  	/* <------------------- */     	/* Part1_21h */
+  tempecx=tempecx>>16;                                     			/* BPLHCFACT  */
+  if(modeflag&HalfDCLK) {
+    	tempecx=tempecx>>1;
+  }
+  temp=(USHORT)((tempecx&0x0000FF00)>>8);
+  SiS_SetReg1(SiS_Part1Port,0x22,temp);     	/* <------------------- */      /* Part1_22h */
+  temp=(USHORT)(tempecx&0x000000FF);
+  SiS_SetReg1(SiS_Part1Port,0x23,temp); 	/* <------------------- */
+ /*add dstn new register*/
+  if(SiS_IF_DEF_DSTN){
+     	SiS_SetReg1(SiS_Part1Port,0x1E,0x01);
+     	SiS_SetReg1(SiS_Part1Port,0x25,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x26,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x27,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x28,0x87);
+     	SiS_SetReg1(SiS_Part1Port,0x29,0x5A);
+     	SiS_SetReg1(SiS_Part1Port,0x2A,0x4B);
+     	SiS_SetRegANDOR(SiS_Part1Port,0x44,~0x007,0x03);
+     	tempbx=SiS_HDE;                              				/*Blps=lcdhdee(lcdhdes+HDE) +64*/
+     	tempbx=tempbx+64;
+     	temp=tempbx&0x00FF;
+     	SiS_SetReg1(SiS_Part1Port,0x38,temp);
+     	temp=((tempbx&0xFF00)>>8)<<3;
+     	SiS_SetRegANDOR(SiS_Part1Port,0x35,~0x078,temp);
+     	tempbx=tempbx+32;		       					/*Blpe=lBlps+32*/
+     	temp=tempbx&0x00FF;
+     	/*fstn*/
+     	if(SiS_IF_DEF_FSTN){
+         	temp=0;
+     	}
+     	SiS_SetReg1(SiS_Part1Port,0x39,temp);
+     	SiS_SetReg1(SiS_Part1Port,0x3A,0x00);  /*Bflml=0*/
+     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x007,0x00);
+     	tempbx=SiS_VDE;
+     	tempbx=tempbx/2;
+     	temp=tempbx&0x00FF;
+     	SiS_SetReg1(SiS_Part1Port,0x3B,temp);
+     	temp=((tempbx&0xFF00)>>8)<<3;
+     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x038,temp);
+     	tempeax=SiS_HDE;                       					/* BDxFIFOSTOP= (HDE*4)/128 */
+     	tempeax=tempeax*4;
+     	tempebx=128;
+     	temp=(USHORT)(tempeax%tempebx);
+     	tempeax=tempeax/tempebx;
+     	if(temp!=0){
+      		tempeax++;
+     	}
+     	temp=(USHORT)(tempeax&0x0000003F);
+     	SiS_SetRegANDOR(SiS_Part1Port,0x45,~0x0FF,temp);
+     	SiS_SetReg1(SiS_Part1Port,0x3F,0x00);           			/*BDxWadrst0*/
+     	SiS_SetReg1(SiS_Part1Port,0x3E,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x3D,0x10);
+     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x040,0x00);
+     	tempax=SiS_HDE;
+     	tempax=tempax>>4;                                			/*BDxWadroff = HDE*4/8/8  */
+     	pushcx=tempax;
+     	temp=tempax&0x00FF;
+     	SiS_SetReg1(SiS_Part1Port,0x43,temp);
+     	temp=((tempax&0xFF00)>>8)<<3;
+     	SiS_SetRegANDOR(SiS_Part1Port,0x44,~0x0F8,temp);
+     	tempax=SiS_VDE;                        					/*BDxWadrst1 = BDxWadrst0+BDxWadroff*VDE*/
+     	tempeax=(tempax*pushcx);
+     	tempebx=0x00100000+tempeax;
+     	temp=(USHORT)tempebx&0x000000FF;
+     	SiS_SetReg1(SiS_Part1Port,0x42,temp);
+     	temp=(USHORT)((tempebx&0x0000FF00)>>8);
+     	SiS_SetReg1(SiS_Part1Port,0x41,temp);
+     	temp=(USHORT)((tempebx&0x00FF0000)>>16);
+     	SiS_SetReg1(SiS_Part1Port,0x40,temp);
+     	temp=(USHORT)((tempebx&0x01000000)>>24);
+     	temp=temp<<7;
+     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x080,temp);
+     	SiS_SetReg1(SiS_Part1Port,0x2F,0x03);
+     	SiS_SetReg1(SiS_Part1Port,0x03,0x50);
+     	SiS_SetReg1(SiS_Part1Port,0x04,0x00);
+     	SiS_SetReg1(SiS_Part1Port,0x2F,0x01);
+     	SiS_SetReg1(SiS_Part1Port,0x13,0x00);
+     	SiS_SetReg1(SiS_P3c4,0x05,0x86);
+     	SiS_SetReg1(SiS_P3c4,0x1e,0x62);
+     	/*fstn*/
+     	if(SiS_IF_DEF_FSTN){
+         	SiS_SetReg1(SiS_P3c4,0x2b,0x1b);
+         	SiS_SetReg1(SiS_P3c4,0x2c,0xe3);
+         	SiS_SetReg1(SiS_P3c4,0x1e,0x62);
+         	SiS_SetReg1(SiS_P3c4,0x2e,0x04);
+         	SiS_SetReg1(SiS_P3c4,0x2f,0x42);
+         	SiS_SetReg1(SiS_P3c4,0x32,0x01);
+         	SiS_SetReg1(SiS_Part1Port,0x2b,0x02);
+         	SiS_SetReg1(SiS_Part1Port,0x2c,0x00);
+         	SiS_SetReg1(SiS_Part1Port,0x2d,0x00);
+     	}
+     	/*end add fstn*/
+     	SiS_SetRegANDOR(SiS_Part1Port,0x19,0x00f,0x30);
+     	SiS_SetReg1(SiS_Part1Port,0x1e,0x7d);
+     	SiS_SetReg1(SiS_Part1Port,0x2e,0xe0);
+  }
+  /*end add dstn*/
+  return;
 }
 
 /*301b*/
 void
-SiS_SetGroup1_LCDA (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		    USHORT RefreshRateTableIndex)
-{
-	USHORT modeflag, resinfo;
-	USHORT push1, push2, tempax, tempbx, tempcx, temp;
-	ULONG tempeax = 0, tempebx, tempecx, tempvcfact;	/*301b */
-	SiS_SetRegOR (SiS_Part1Port, 0x2D, 0x20);
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
-
-	tempax = SiS_LCDHDES;
-	tempbx = SiS_HDE;
-	tempcx = SiS_HT;
-
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		if (SiS_LCDResInfo == Panel1280x1024)
-			tempbx = 1280;
-		if (SiS_LCDResInfo == Panel1024x768)
-			tempbx = 1024;
-	}
-	tempcx = tempcx - tempbx;	/* HT-HDE  */
-	push1 = tempax;
-	tempax = tempax + tempbx;	/* lcdhdee  */
-	tempbx = SiS_HT;
-	if (tempax >= tempbx) {
-		tempax = tempax - tempbx;
-	}
-	push2 = tempax;
-	/* push ax   lcdhdee  */
-	tempcx = tempcx >> 2;	/* temp  */
-	tempcx = tempcx + tempax;	/* lcdhrs  */
-	if (tempcx >= tempbx) {
-		tempcx = tempcx - tempbx;
-	}
-	/* v ah,cl  */
-	tempax = tempcx;
-	tempax = tempax >> 3;	/* BPLHRS */
-	temp = tempax & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x14, temp);	/* Part1_14h  */
-	temp = (tempax & 0x00FF) + 10;
-	temp = temp & 0x01F;
-	temp = temp | (((tempcx & 0x00ff) & 0x07) << 5);
-	SiS_SetReg1 (SiS_Part1Port, 0x15, temp);	/* Part1_15h  */
-	tempbx = push2;		/* lcdhdee  */
-	tempcx = push1;		/* lcdhdes  */
-	temp = (tempcx & 0x00FF);
-	temp = temp & 0x07;	/* BPLHDESKEW  */
-	SiS_SetReg1 (SiS_Part1Port, 0x1A, temp);	/* Part1_1Ah  */
-	tempcx = tempcx >> 3;	/* BPLHDES */
-	temp = (tempcx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x16, temp);	/* Part1_16h  */
-	if (tempbx & 0x07)
-		tempbx = tempbx + 8;
-	tempbx = tempbx >> 3;	/* BPLHDEE  */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x17, temp);	/* Part1_17h  */
-
-	tempcx = SiS_VGAVT;
-	tempbx = SiS_VGAVDE;
-	tempcx = tempcx - tempbx;	/* GAVT-VGAVDE  */
-	tempbx = SiS_LCDVDES;	/* VGAVDES  */
-	push1 = tempbx;		/* push bx temppush1 */
-	if (SiS_IF_DEF_TRUMPION == 0) {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				tempax = SiS_VGAVDE;
-			}
-		}
-
-		if (SiS_LCDResInfo == Panel1024x768)
-			tempax = 768;
-		if (SiS_LCDResInfo == Panel1280x1024)
-			tempax = 1024;
-
-	} else
-		tempax = SiS_VGAVDE;
-	tempbx = tempbx + tempax;
-	tempax = SiS_VT;	/* VT  */
-	if (tempbx >= SiS_VT) {
-		tempbx = tempbx - tempax;
-	}
-	push2 = tempbx;		/* push bx  temppush2  */
-	tempcx = tempcx >> 1;
-	tempbx = tempbx + tempcx;
-	tempbx++;		/* BPLVRS  */
-	if (tempbx >= tempax) {
-		tempbx = tempbx - tempax;
-	}
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x18, temp);	/* Part1_18h  */
-	tempcx = tempcx >> 3;
-	tempcx = tempcx + tempbx;
-	tempcx++;		/* BPLVRE  */
-	temp = tempcx & 0x00FF;
-	temp = temp & 0x0F;
-	SiS_SetRegANDOR (SiS_Part1Port, 0x19, ~0x00F, temp);	/* Part1_19h  */
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp & 0x07;
-	temp = temp << 3;	/* BPLDESKEW =0 */
-	tempbx = SiS_VGAVDE;
-	if (tempbx != SiS_VDE) {
-		temp = temp | 0x40;
-	}
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		temp = temp | 0x40;
-	}
-	if (SiS_LCDInfo & LCDRGB18Bit) {
-		temp = temp | 0x80;
-	}
-	SiS_SetRegANDOR (SiS_Part1Port, 0x1A, 0x07, temp);	/* Part1_1Ah */
-
-	tempbx = push2;		/* p bx temppush2 BPLVDEE  */
-	tempcx = push1;		/* pop cx temppush1 NPLVDES */
-	push1 = (USHORT) (tempeax & 0xFFFF);
-
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		if (SiS_LCDResInfo == Panel800x600) {
-			if (resinfo == 7)
-				tempcx++;
-		} else {
-			if (SiS_LCDResInfo == Panel1024x768) {
-				if (resinfo == 8)
-					tempcx++;
-			}
-		}
-	}
-
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp & 0x07;
-	temp = temp << 3;
-	temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
-	SiS_SetReg1 (SiS_Part1Port, 0x1D, temp);	/* Part1_1Dh */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x1C, temp);	/* Part1_1Ch  */
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x1B, temp);	/* Part1_1Bh  */
-
-	tempecx = SiS_VGAVT;
-	tempebx = SiS_VDE;
-	tempeax = SiS_VGAVDE;
-	tempecx = tempecx - tempeax;	/* VGAVT-VGAVDE  */
-	tempeax = tempeax << 18;
-	temp = (USHORT) (tempeax % tempebx);
-	tempeax = tempeax / tempebx;
-	if (temp != 0) {
-		tempeax++;
-	}
-	tempebx = tempeax;	/* BPLVCFACT  */
-	tempvcfact = tempeax;	/*301b */
-	temp = (USHORT) (tempebx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x37, temp);
-	temp = (USHORT) ((tempebx & 0x00FF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x36, temp);
-	temp = (USHORT) ((tempebx & 0x00030000) >> 16);
-	if (SiS_VDE == SiS_VGAVDE) {
-		temp = temp | 0x04;
-	}
-
-	SiS_SetReg1 (SiS_Part1Port, 0x35, temp);
-
-	tempecx = SiS_VGAHDE;
-	tempebx = SiS_HDE;
-	tempeax = tempecx;
-	tempeax = tempeax << 6;
-	tempeax = tempeax << 10;
-	tempeax = tempeax / tempebx;
-	if (tempebx == tempecx) {
-		tempeax = 65535;
-	}
-	tempecx = tempeax;
-	tempeax = SiS_VGAHDE;	/*301b to change HT->HDE */
-	tempeax = tempeax << 6;
-	tempeax = tempeax << 10;
-	tempeax = tempeax / tempecx;
-	tempecx = tempecx << 16;
-	tempeax = tempeax - 1;
-	tempecx = tempecx | (tempeax & 0x00FFFF);
-	temp = (USHORT) (tempecx & 0x00FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x1F, temp);	/* Part1_1Fh  */
-
-	tempeax = SiS_VGAVDE;
-	tempeax = tempeax << 18;	/*301b */
-	tempeax = tempeax / tempvcfact;
-	tempbx = (USHORT) (tempeax & 0x0FFFF);
-	if (SiS_LCDResInfo == Panel1024x768)
-		tempbx--;
-	if (SiS_SetFlag & EnableLVDSDDA) {
-		tempbx = 1;
-	}
-	temp = ((tempbx & 0xFF00) >> 8) << 3;
-	temp = temp | (USHORT) (((tempecx & 0x0000FF00) >> 8) & 0x07);
-	SiS_SetReg1 (SiS_Part1Port, 0x20, temp);	/* Part1_20h */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part1Port, 0x21, temp);	/* Part1_21h */
-	tempecx = tempecx >> 16;	/* BPLHCFACT  */
-
-	temp = (USHORT) ((tempecx & 0x0000FF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x22, temp);	/* Part1_22h */
-	temp = (USHORT) (tempecx & 0x000000FF);
-	SiS_SetReg1 (SiS_Part1Port, 0x23, temp);
-	return;
+SiS_SetGroup1_LCDA(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+{
+  USHORT modeflag,resinfo;
+  USHORT push1,push2,tempax,tempbx,tempcx,temp;
+  ULONG tempeax=0,tempebx,tempecx,tempvcfact;/*301b*/
+
+  SiS_SetRegOR(SiS_Part1Port,0x2D,0x20);
+  
+  if(ModeNo<=0x13) {
+    modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+  tempax=SiS_LCDHDES;
+  tempbx=SiS_HDE;
+  tempcx=SiS_HT;
+  
+  if(SiS_LCDInfo&LCDNonExpanding) {
+    	if(SiS_LCDResInfo==Panel1280x1024) tempbx=1280;
+    	if(SiS_LCDResInfo==Panel1024x768) tempbx=1024;
+  }
+  tempcx=tempcx-tempbx;                                    	/* HT-HDE  */
+  push1=tempax;
+  tempax=tempax+tempbx;                                    	/* lcdhdee  */
+  tempbx=SiS_HT;
+  if(tempax>=tempbx){
+   	tempax=tempax-tempbx;
+  }
+  push2=tempax;
+                                                           	/* push ax   lcdhdee  */
+  tempcx=tempcx>>2;                                        	/* temp  */
+  tempcx=tempcx+tempax;                                    	/* lcdhrs  */
+  if(tempcx>=tempbx){
+    	tempcx=tempcx-tempbx;
+  }
+                                                           	/* v ah,cl  */
+  tempax=tempcx;
+  tempax=tempax>>3;                                        	/* BPLHRS */
+  temp=tempax&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x14,temp);                         /* Part1_14h  */
+  temp=(tempax&0x00FF)+10;
+  temp=temp&0x01F;
+  temp=temp|(((tempcx&0x00ff)&0x07)<<5);
+  SiS_SetReg1(SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
+  tempbx=push2;                                          	/* lcdhdee  */
+  tempcx=push1;                                          	/* lcdhdes  */
+  temp=(tempcx&0x00FF);
+  temp=temp&0x07;                                      		/* BPLHDESKEW  */
+  SiS_SetReg1(SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
+  tempcx=tempcx>>3;                                        	/* BPLHDES */
+  temp=(tempcx&0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
+  if(tempbx&0x07) tempbx=tempbx+8;
+  tempbx=tempbx>>3;                                        	/* BPLHDEE  */
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x17,temp);                        	/* Part1_17h  */
+
+  tempcx=SiS_VGAVT;
+  tempbx=SiS_VGAVDE;
+  tempcx=tempcx-tempbx;                                    	/* GAVT-VGAVDE  */
+  tempbx=SiS_LCDVDES;                                          	/* VGAVDES  */
+  push1=tempbx;                                        		/* push bx temppush1 */
+  if(SiS_IF_DEF_TRUMPION==0){
+    if(SiS_IF_DEF_CH7005==1) {
+      if(SiS_VBInfo&SetCRT2ToTV) {
+        tempax=SiS_VGAVDE;
+      }
+    }
+    if(SiS_LCDResInfo==Panel1024x768) tempax=768;
+    if(SiS_LCDResInfo==Panel1280x1024)  tempax=1024;
+  }
+  else tempax=SiS_VGAVDE;
+  tempbx=tempbx+tempax;
+  tempax=SiS_VT;                                               	/* VT  */
+  if(tempbx>=SiS_VT){
+    tempbx=tempbx-tempax;
+  }
+  push2=tempbx;                                        		/* push bx  temppush2  */
+  tempcx=tempcx>>1;
+  tempbx=tempbx+tempcx;
+  tempbx++;                                                	/* BPLVRS  */
+  if(tempbx>=tempax){
+    tempbx=tempbx-tempax;
+  }
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x18,temp);                         /* Part1_18h  */
+  tempcx=tempcx>>3;
+  tempcx=tempcx+tempbx;
+  tempcx++;                                                	/* BPLVRE  */
+  temp=tempcx&0x00FF;
+  temp=temp&0x0F;
+  SiS_SetRegANDOR(SiS_Part1Port,0x19,~0x00F,temp);               /* Part1_19h  */
+  temp=(tempbx&0xFF00)>>8;
+  temp=temp&0x07;
+  temp=temp<<3;                                 		/* BPLDESKEW =0 */
+  tempbx=SiS_VGAVDE;
+  if(tempbx!=SiS_VDE){
+    temp=temp|0x40;
+  }
+  if(SiS_SetFlag&EnableLVDSDDA) {
+    temp=temp|0x40;
+  }
+  if(SiS_LCDInfo&LCDRGB18Bit) {
+    temp=temp|0x80;
+  }
+  SiS_SetRegANDOR(SiS_Part1Port,0x1A,0x07,temp);             	/* Part1_1Ah */
+  
+  tempbx=push2;                                        		/* p bx temppush2 BPLVDEE  */
+  tempcx=push1;                                        		/* pop cx temppush1 NPLVDES */
+  push1=(USHORT)(tempeax&0xFFFF);
+    
+  if(!(SiS_VBInfo&SetInSlaveMode)) {
+    if(SiS_LCDResInfo==Panel800x600) {
+      if(resinfo==7) tempcx++;
+    } else {
+      if(SiS_LCDResInfo==Panel1024x768) {
+        if(resinfo==8) tempcx++;
+      }
+    }
+  }
+
+  temp=(tempbx&0xFF00)>>8;
+  temp=temp&0x07;
+  temp=temp<<3;
+  temp=temp|(((tempcx&0xFF00)>>8)&0x07);
+  SiS_SetReg1(SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */ 
+
+  tempecx=SiS_VGAVT;
+  tempebx=SiS_VDE;
+  tempeax=SiS_VGAVDE;
+  tempecx=tempecx-tempeax;                                 	/* VGAVT-VGAVDE  */
+  tempeax=tempeax<<18;
+  temp=(USHORT)(tempeax%tempebx);
+  tempeax=tempeax/tempebx;
+  if(temp!=0){
+    tempeax++;
+  }
+  tempebx=tempeax;                                        	/* BPLVCFACT  */
+  tempvcfact=tempeax;       /*301b*/
+  temp=(USHORT)(tempebx&0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x37,temp);   
+  temp=(USHORT)((tempebx&0x00FF00)>>8);
+  SiS_SetReg1(SiS_Part1Port,0x36,temp);   
+  temp=(USHORT)((tempebx&0x00030000)>>16);
+  if(SiS_VDE==SiS_VGAVDE) {
+      temp=temp|0x04;
+  }
+  
+  SiS_SetReg1(SiS_Part1Port,0x35,temp);   
+  
+  tempecx=SiS_VGAHDE;
+  tempebx=SiS_HDE;
+  tempeax=tempecx;
+  tempeax=tempeax<<6;
+  tempeax=tempeax<<10;
+  tempeax=tempeax/tempebx;
+  if(tempebx==tempecx){
+    	tempeax=0xFFFF;
+  }
+  tempecx=tempeax;
+  tempeax=SiS_VGAHDE;  /*301b to change HT->HDE*/
+  tempeax=tempeax<<6;
+  tempeax=tempeax<<10;
+  tempeax=tempeax/tempecx;
+  tempecx=tempecx<<16;
+  tempeax=tempeax-1;
+  tempecx=tempecx|(tempeax&0x00FFFF);
+  temp=(USHORT)(tempecx&0x00FF);
+  SiS_SetReg1(SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
+
+  tempeax=SiS_VGAVDE;
+  tempeax=tempeax<<18;          /*301b*/
+  tempeax=tempeax/tempvcfact;
+  tempbx=(USHORT) (tempeax&0x0FFFF);
+  if(SiS_LCDResInfo==Panel1024x768) tempbx--;
+  if(SiS_SetFlag&EnableLVDSDDA){
+    	tempbx=1;
+  }
+  temp=((tempbx&0xFF00)>>8)<<3;
+  temp=temp|(USHORT)(((tempecx&0x0000FF00)>>8)&0x07);
+  SiS_SetReg1(SiS_Part1Port,0x20,temp);                         /* Part1_20h */
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part1Port,0x21,temp);                         /* Part1_21h */
+  tempecx=tempecx>>16;                                     	/* BPLHCFACT  */
+ 
+  temp=(USHORT)((tempecx&0x0000FF00)>>8);
+  SiS_SetReg1(SiS_Part1Port,0x22,temp);                         /* Part1_22h */
+  temp=(USHORT)(tempecx&0x000000FF);
+  SiS_SetReg1(SiS_Part1Port,0x23,temp);
+  
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+  	SiS_SetReg1(SiS_Part1Port,0x1e,0x20);  /* for 650 & 550 lvds part */
+  }
+  return;
 }
-
 /*end 301b*/
-void
-SiS_SetTPData ()
+
+void SiS_SetTPData()
 {
-	return;
+  return;
 }
 
-void
-SiS_SetCRT2Offset (USHORT SiS_Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		   USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
+void SiS_SetCRT2Offset(USHORT SiS_Part1Port,ULONG ROMAddr,USHORT ModeNo,
+                       USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
+		       PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT offset;
-	UCHAR temp;
+  USHORT offset;
+  UCHAR temp;
 
-	if (SiS_VBInfo & SetInSlaveMode) {
-		return;
-	}
-	offset =
-	    SiS_GetOffset (ROMAddr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-			   HwDeviceExtension);
-	temp = (UCHAR) (offset & 0xFF);
-	SiS_SetReg1 (SiS_Part1Port, 0x07, temp);
-	temp = (UCHAR) ((offset & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part1Port, 0x09, temp);
-	temp = (UCHAR) (((offset >> 3) & 0xFF) + 1);
-	SiS_SetReg1 (SiS_Part1Port, 0x03, temp);
+  if(SiS_VBInfo&SetInSlaveMode) return;
+
+  offset=SiS_GetOffset(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                       HwDeviceExtension);
+  temp=(UCHAR)(offset&0xFF);
+  SiS_SetReg1(SiS_Part1Port,0x07,temp);
+  temp=(UCHAR)((offset&0xFF00)>>8);
+  SiS_SetReg1(SiS_Part1Port,0x09,temp);
+  temp=(UCHAR)(((offset>>3)&0xFF)+1);
+  SiS_SetReg1(SiS_Part1Port,0x03,temp);
 }
 
 USHORT
-SiS_GetOffset (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-	       USHORT RefreshRateTableIndex,
-	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT temp, colordepth;
-	USHORT modeinfo, index, infoflag;
-	USHORT ColorDepth[] = { 0x01, 0x02, 0x04 };
-
-	modeinfo = SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-	infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-		index = (modeinfo >> 4) & 0xFF;
-	} else {		/* 310 series */
-
-		index = (modeinfo >> 8) & 0xFF;
-	}
-	temp = SiS_ScreenOffset[index];
-	if (infoflag & InterlaceMode) {
-		temp = temp << 1;
-	}
-	colordepth = SiS_GetColorDepth (ROMAddr, ModeNo, ModeIdIndex);
-
-	if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
-		temp = ModeNo - 0x7C;
-		colordepth = ColorDepth[temp];
-		temp = 0x6B;
-		if (infoflag & InterlaceMode) {
-			temp = temp << 1;
-		}
-		return (temp * colordepth);
-	} else
-		return (temp * colordepth);
+SiS_GetOffset(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+              USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT temp,colordepth;
+  USHORT modeinfo,index,infoflag;
+  USHORT ColorDepth[]={0x02,0x04,0x08};  /* TW: Was 1,2,4 */
+
+  modeinfo = SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+  infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  if (HwDeviceExtension->jChipType < SIS_315H ) {
+  	/* 300 series */
+    	index=(modeinfo>>4)&0xFF;
+  } else {
+  	/* 310 series */
+    	index=(modeinfo>>8)&0xFF;
+  }
+  temp=SiS_ScreenOffset[index];
+  if(infoflag&InterlaceMode){
+    	temp=temp<<1;
+  }
+  colordepth=SiS_GetColorDepth(ROMAddr,ModeNo,ModeIdIndex);
+
+  if((ModeNo>=0x7C)&&(ModeNo<=0x7E)) {
+  	/* TW: For 1280x960 */
+    	temp=ModeNo-0x7C;
+    	colordepth=ColorDepth[temp];
+    	temp=0x6B;
+    	if(infoflag&InterlaceMode){
+      		temp=temp<<1;
+    	}
+   	return(temp*colordepth);
+  }
+  else return(temp*colordepth);
 }
 
 USHORT
-SiS_GetColorDepth (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetColorDepth(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
-	SHORT index;
-	USHORT modeflag;
+  USHORT ColorDepth[6]={1,2,4,4,6,8};
+  SHORT  index;
+  USHORT modeflag;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+  index=(modeflag&ModeInfoFlag)-ModeEGA;
+  if(index<0) index=0;
+  return(ColorDepth[index]);
+}
+
+void
+SiS_SetCRT2Sync(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+                USHORT RefreshRateTableIndex)
+{
+  USHORT tempah=0,infoflag,flag;
+
+  flag=0;
+  infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  if(SiS_IF_DEF_LVDS==1){
+    if(SiS_VBInfo&SetCRT2ToLCD){
+      tempah=SiS_LCDInfo;
+      if(tempah&LCDSync){
+        flag=1;
+      }
+    }
+  }
+  if(flag!=1) tempah=infoflag>>8;
+  tempah=tempah&0xC0;
+  tempah=tempah|0x20;
+  if(!(SiS_LCDInfo&LCDRGB18Bit)) tempah=tempah|0x10;
+  if(SiS_IF_DEF_CH7005==1) tempah=tempah|0xC0;
+  SiS_SetRegANDOR(SiS_Part1Port,0x19,0x3F,tempah);
+}
+
+void
+SiS_SetCRT2FIFO(USHORT  SiS_Part1Port,ULONG ROMAddr,USHORT ModeNo,
+                PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT temp,index;
+  USHORT modeidindex,refreshratetableindex;
+  USHORT VCLK,MCLK,colorth=0,data2;
+  ULONG  data,eax;
+  UCHAR  LatencyFactor[] ={
+  	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
+        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
+        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
+        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
+        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
+        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
+        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
+        00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
+
+  SiS_SearchModeID(ROMAddr,ModeNo,&modeidindex);
+  SiS_SetFlag=SiS_SetFlag&(~ProgrammingCRT2);
+  SiS_SelectCRT2Rate=0;
+  refreshratetableindex=SiS_GetRatePtrCRT2(ROMAddr,ModeNo,modeidindex);   /* 11.GetRatePtr */
+  if(ModeNo>=0x13) {
+    index=SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+    index=index&0x3F;
+    VCLK=SiS_VCLKData[index].CLOCK;           /* Get VCLK  */
+    index=SiS_GetReg1(SiS_P3c4,0x1A);
+    index=index&07;
+    MCLK=SiS_MCLKData[index].CLOCK;           /* Get MCLK  */
+    data2=SiS_ModeType-0x02;
+    switch (data2) {
+      case 0 : 	colorth=1; break;
+      case 1 : 	colorth=1; break;
+      case 2 : 	colorth=2; break;
+      case 3 : 	colorth=2; break;
+      case 4 : 	colorth=3; break;
+      case 5 : 	colorth=4; break;
+    }
+    /* data2=(data2*VCLK)/MCLK;   */  /*  bx */
+    data2=(colorth*VCLK)/MCLK;  /* TW */
+
+    temp = SiS_GetReg1(SiS_P3c4,0x14);
+    temp = ((temp&0x00FF)>>6)<<1;
+    if(temp==0) temp=1;
+    temp=temp<<2;
+
+    data2=temp-data2;
+
+/*  if(data2%(28*16)) {		 TW: WRONG
+      	data2=data2/(28*16);
+      	data2++;
+    } else {
+      	data2=data2/(28*16);
+    } */
+    if((28*16)%data2) {		/* TW */
+      	data2=(28*16)/data2;
+      	data2++;
+    } else {
+      	data2=(28*16)/data2;
+    }
+
+    index=0;
+    temp = SiS_GetReg1(SiS_P3c4,0x14);
+    if(temp&0x0080) index=index+12;
+
+    SiS_SetReg4(0xcf8,0x800000A0);
+    eax=SiS_GetReg3(0xcfc);
+    temp=(USHORT)(eax>>24);
+    if(!(temp&0x01)) index=index+24;
+
+    SiS_SetReg4(0xcf8,0x80000050);
+    eax=SiS_GetReg3(0xcfc);
+    temp=(USHORT)(eax>>24);
+    if(temp&0x01) index=index+6;
+
+    temp=(temp&0x0F)>>1;
+    index=index+temp;
+    data=LatencyFactor[index];
+    data=data+15;
+    temp = SiS_GetReg1(SiS_P3c4,0x14);
+    if(!(temp&0x80)) data=data+5;
+
+    data=data+data2;
+
+    SiS_SetFlag=SiS_SetFlag|ProgrammingCRT2;
+    data=data*VCLK*colorth;
+    if(data%(MCLK<<4)) {
+      	data=data/(MCLK<<4);
+      	data++;
+    } else {
+      	data=data/(MCLK<<4);
+    }
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-	index = (modeflag & ModeInfoFlag) - ModeEGA;
-	if (index < 0)
-		index = 0;
-	return (ColorDepth[index]);
-}
+/* TW: The following made all the calculations above void... */
 
-void
-SiS_SetCRT2Sync (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		 USHORT RefreshRateTableIndex)
-{
-	USHORT tempah = 0, infoflag, flag;
-
-	flag = 0;
-	infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	if (SiS_IF_DEF_LVDS == 1) {
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			tempah = SiS_LCDInfo;
-			if (tempah & LCDSync) {
-				flag = 1;
-			}
-		}
-	}
-	if (flag != 1)
-		tempah = infoflag >> 8;
-	tempah = tempah & 0xC0;
-	tempah = tempah | 0x20;
-	if (!(SiS_LCDInfo & LCDRGB18Bit))
-		tempah = tempah | 0x10;
-	if (SiS_IF_DEF_CH7005 == 1)
-		tempah = tempah | 0xC0;
-
-	SiS_SetRegANDOR (SiS_Part1Port, 0x19, 0x3F, tempah);
-}
-
-void
-SiS_SetCRT2FIFO (USHORT SiS_Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT temp, index;
-	USHORT modeidindex, refreshratetableindex;
-	USHORT VCLK, MCLK, colorth = 0, data, data2;
-	ULONG eax;
-	UCHAR LatencyFactor[] = { 97, 88, 86, 79, 77, 00,	/*; 64  bit    BQ=2   */
-		00, 87, 85, 78, 76, 54,	/*; 64  bit    BQ=1   */
-		97, 88, 86, 79, 77, 00,	/*; 128 bit    BQ=2   */
-		00, 79, 77, 70, 68, 48,	/*; 128 bit    BQ=1   */
-		80, 72, 69, 63, 61, 00,	/*; 64  bit    BQ=2   */
-		00, 70, 68, 61, 59, 37,	/*; 64  bit    BQ=1   */
-		86, 77, 75, 68, 66, 00,	/*; 128 bit    BQ=2   */
-		00, 68, 66, 59, 57, 37
-	};			/*; 128 bit    BQ=1   */
-
-	SiS_SearchModeID (ROMAddr, ModeNo, &modeidindex);
-	SiS_SetFlag = SiS_SetFlag & (~ProgrammingCRT2);
-	SiS_SelectCRT2Rate = 0;
-	refreshratetableindex = SiS_GetRatePtrCRT2 (ROMAddr, ModeNo, modeidindex);	/* 11.GetRatePtr */
-	if (ModeNo >= 0x13) {
-		index = SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
-		index = index & 0x3F;
-		VCLK = SiS_VCLKData[index].CLOCK;	/* Get VCLK  */
-		index = SiS_GetReg1 (SiS_P3c4, 0x1A);
-		index = index & 07;
-		MCLK = SiS_MCLKData[index].CLOCK;	/* Get MCLK  */
-		data2 = SiS_ModeType - 0x02;
-		switch (data2) {
-		case 0:
-			colorth = 1;
-			break;
-		case 1:
-			colorth = 1;
-			break;
-		case 2:
-			colorth = 2;
-			break;
-		case 3:
-			colorth = 2;
-			break;
-		case 4:
-			colorth = 3;
-			break;
-		case 5:
-			colorth = 4;
-			break;
-		}
-		data2 = (data2 * VCLK) / MCLK;	/*  bx */
-
-		temp = SiS_GetReg1 (SiS_P3c4, 0x14);
-		temp = ((temp & 0x00FF) >> 6) << 1;
-		if (temp == 0)
-			temp = 1;
-		temp = temp << 2;
-
-		data2 = temp - data2;
-		if (data2 % (28 * 16)) {
-			data2 = data2 / (28 * 16);
-			data2++;
-		} else {
-			data2 = data2 / (28 * 16);
-		}
-
-		index = 0;
-		temp = SiS_GetReg1 (SiS_P3c4, 0x14);
-		if (temp & 0x0080)
-			index = index + 12;
-		SiS_SetReg4 (0xcf8, 0x800000A0);
-		eax = SiS_GetReg3 (0xcfc);
-		temp = (USHORT) (eax >> 24);
-		if (!(temp & 0x01))
-			index = index + 24;
-
-		SiS_SetReg4 (0xcf8, 0x80000050);
-		eax = SiS_GetReg3 (0xcfc);
-		temp = (USHORT) (eax >> 24);
-		if (temp & 0x01)
-			index = index + 6;
-		temp = (temp & 0x0F) >> 1;
-		index = index + temp;
-		data = LatencyFactor[index];
-		data = data + 15;
-		temp = SiS_GetReg1 (SiS_P3c4, 0x14);
-		if (!(temp & 0x80))
-			data = data + 5;
-		data = data + data2;
-
-		SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-		data = data * VCLK * colorth;
-		if (data % (MCLK << 4)) {
-			data = data / (MCLK << 4);
-			data++;
-		} else {
-			data = data / (MCLK << 4);
-		}
-		temp = 0x16;
+#if 0
+    temp=0x16;
 /*  Revision ID  */
-		temp = 0x13;
+    temp=0x13;
 /*  Revision ID  */
-		SiS_SetRegANDOR (SiS_Part1Port, 0x01, ~0x01F, temp);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x02, ~0x01F, temp);
-	}
-}
-
-void
-SiS_SetCRT2FIFO2 (USHORT SiS_Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		  PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-#ifdef CONFIG_FB_SIS_315
-	UCHAR CombCode[] = { 1, 1, 1, 4, 3, 1, 3, 4, 4, 1, 4, 4, 5, 1, 5, 4 };
-	UCHAR CRT2ThLow[] =
-	    { 39, 63, 55, 79, 78, 102, 90, 114, 55, 87, 84, 116, 103, 135, 119,
-		    151 };
-#endif
-	USHORT temp, temp1, temp2, temp3;
-	USHORT index;
-	USHORT CRT1ModeNo, CRT2ModeNo;
-	USHORT ModeIdIndex;
-	USHORT RefreshRateTableIndex;
-
-	SiS_SetReg1 (SiS_Part1Port, 0x1, 0x3B);
-/* CRT1ModeNo=(UCHAR)SiS_GetReg1(SiS_P3d4,0x34); *//* get CRT1 ModeNo */
-	CRT1ModeNo = SiS_CRT1Mode;
-	/* CRT1ModeNo =ModeNo; */
-	SiS_SearchModeID (ROMAddr, CRT1ModeNo, &ModeIdIndex);	/* Get ModeID Table */
-	SiS_SetFlag = SiS_SetFlag & (~ProgrammingCRT2);
-
-	RefreshRateTableIndex = SiS_GetRatePtrCRT2 (ROMAddr, CRT1ModeNo, ModeIdIndex);	/* Set REFIndex-> for crt1 refreshrate */
-	index =
-	    SiS_GetVCLK2Ptr (ROMAddr, CRT1ModeNo, ModeIdIndex,
-			     RefreshRateTableIndex, HwDeviceExtension);
-	temp1 = SiS_VCLKData[index].CLOCK;	/* Get VCLK  */
-
-	temp2 = SiS_GetColorDepth (ROMAddr, CRT1ModeNo, ModeIdIndex);
-#ifdef CONFIG_FB_SIS_315
-	index = SiS_Get310DRAMType (ROMAddr);
-#endif
-	temp3 = SiS_MCLKData[index].CLOCK;	/* Get MCLK  */
-
-	temp = SiS_GetReg1 (SiS_P3c4, 0x14);
-	if (temp & 0x02)
-		temp = 16;
-	else
-		temp = 8;
-
-	temp = temp - temp1 * temp2 / temp3;	/* 16-DRamBus - DCLK*BytePerPixel/MCLK */
-
-	if ((52 * 16 % temp) == 0)
-		temp = 52 * 16 / temp + 40;
-	else
-		temp = 52 * 16 / temp + 40 + 1;
-
-	/* get DRAM latency */
-	temp1 = (SiS_GetReg1 (SiS_P3c4, 0x17) >> 3) & 0x7;	/* SR17[5:3] DRAM Queue depth */
-	temp2 = (SiS_GetReg1 (SiS_P3c4, 0x17) >> 6) & 0x3;	/* SR17[7:6] DRAM Grant length */
-
-#ifdef CONFIG_FB_SIS_315
-	if (SiS_Get310DRAMType (ROMAddr) < 2) {
-		for (temp3 = 0; temp3 < 16; temp3 += 2) {
-			if ((CombCode[temp3] == temp1)
-			    && (CombCode[temp3 + 1] == temp2)) {
-				temp3 = CRT2ThLow[temp3 >> 1];
-			}
-		}
-	} else {
-		for (temp3 = 0; temp3 < 16; temp3 += 2) {
-			if ((CombCode[temp3] == temp1)
-			    && (CombCode[temp3 + 1] == temp2)) {
-				temp3 = CRT2ThLow[8 + (temp3 >> 1)];
-			}
-		}
-	}
+    SiS_SetRegANDOR(SiS_Part1Port,0x01,~0x01F,temp);
+    SiS_SetRegANDOR(SiS_Part1Port,0x02,~0x01F,temp);
 #endif
 
-	temp += temp3;		/* CRT1 Request Period */
-
-	CRT2ModeNo = ModeNo;	/* get CRT2 ModeNo */
-	SiS_SearchModeID (ROMAddr, CRT2ModeNo, &ModeIdIndex);	/* Get ModeID Table */
-	SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-	RefreshRateTableIndex = SiS_GetRatePtrCRT2 (ROMAddr, CRT1ModeNo, ModeIdIndex);	/* Set REFIndex-> for crt1 refreshrate */
-	index =
-	    SiS_GetVCLK2Ptr (ROMAddr, CRT2ModeNo, ModeIdIndex,
-			     RefreshRateTableIndex, HwDeviceExtension);
-	temp1 = SiS_VCLKData[index].CLOCK;	/* Get VCLK  */
-
-	temp2 = SiS_GetColorDepth (ROMAddr, CRT2ModeNo, ModeIdIndex);
-#ifdef CONFIG_FB_SIS_315
-	index = SiS_Get310DRAMType (ROMAddr);
-#endif
-	temp3 = SiS_MCLKData[index].CLOCK;	/* Get MCLK  */
-
-	if ((temp * temp1 * temp2) % (16 * temp3) == 0)
-		temp = temp * temp1 * temp2 / (16 * temp3);	/* CRT1 Request period * TCLK*BytePerPixel/(MCLK*16) */
-	else
-		temp = temp * temp1 * temp2 / (16 * temp3) + 1;	/* CRT1 Request period * TCLK*BytePerPixel/(MCLK*16) */
-
-	if (temp > 0x37)
-		temp = 0x37;
-
-	SiS_SetRegANDOR (SiS_Part1Port, 0x02, ~0x3F, temp);
+   /* TW: We do this instead: */
 
+   temp = SiS_GetReg1(SiS_Part1Port,0x01);
+   if( (HwDeviceExtension->jChipType == SIS_630 ) &&
+	    ((HwDeviceExtension->jChipRevision & 0xf0) == 0x30) ) /* 630s */
+   {
+	temp = (temp & (~0x1F)) | 0x1b;  	/* TW: VESA sets 1b, prev. 0x19 */
+   } else {
+	temp = (temp & (~0x1F)) | 0x16;
+   }
+   SiS_SetReg1(SiS_Part1Port,0x01,temp);  	/* FIFO HIGH? */
+
+   if(data <= 6) data = 6;
+   if(data > 0x14) data = 0x14;
+   if (SiS_IF_DEF_LVDS==1) {			/* TW: LVDS doesn't like 0x14 */
+	if(data > 0x13) data = 0x13;
+   }
+   SiS_SetRegANDOR(SiS_Part1Port,0x02,~0x01F,data);  /* FIFO LOW? */
+  /* TW end */
+  }
 }
 
 void
-SiS_GetLVDSDesData (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex)
-{
-
-	USHORT modeflag;
-	USHORT PanelIndex, ResIndex;
-	SiS_LVDSDesStruct *PanelDesPtr = NULL;
-	if ((SiS_IF_DEF_LVDS == 0)
-	    && ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {	/*301b *//*for test */
-		SiS_GetLVDSDesPtrA (ROMAddr, ModeNo, ModeIdIndex,
-				    RefreshRateTableIndex, &PanelIndex,
-				    &ResIndex);
-		switch (PanelIndex) {
-		case 0:
-			PanelDesPtr = LVDS1024x768Des_1;
-			break;
-		case 1:
-			PanelDesPtr = LVDS1280x1024Des_1;
-			break;
-		case 2:
-			PanelDesPtr = LVDS1280x960Des_1;
-			break;
-		case 3:
-			PanelDesPtr = LVDS1024x768Des_2;
-			break;
-		case 4:
-			PanelDesPtr = LVDS1280x1024Des_2;
-			break;
-		case 5:
-			PanelDesPtr = LVDS1280x960Des_2;
-			break;
-		}
-	} else {
-		SiS_GetLVDSDesPtr (ROMAddr, ModeNo, ModeIdIndex,
-				   RefreshRateTableIndex, &PanelIndex,
-				   &ResIndex);
-		switch (PanelIndex) {
-		case 0:
-			PanelDesPtr = SiS_PanelType00_1;
-			break;
-		case 1:
-			PanelDesPtr = SiS_PanelType01_1;
-			break;
-		case 2:
-			PanelDesPtr = SiS_PanelType02_1;
-			break;
-		case 3:
-			PanelDesPtr = SiS_PanelType03_1;
-			break;
-		case 4:
-			PanelDesPtr = SiS_PanelType04_1;
-			break;
-		case 5:
-			PanelDesPtr = SiS_PanelType05_1;
-			break;
-		case 6:
-			PanelDesPtr = SiS_PanelType06_1;
-			break;
-		case 7:
-			PanelDesPtr = SiS_PanelType07_1;
-			break;
-		case 8:
-			PanelDesPtr = SiS_PanelType08_1;
-			break;
-		case 9:
-			PanelDesPtr = SiS_PanelType09_1;
-			break;
-		case 10:
-			PanelDesPtr = SiS_PanelType0a_1;
-			break;
-		case 11:
-			PanelDesPtr = SiS_PanelType0b_1;
-			break;
-		case 12:
-			PanelDesPtr = SiS_PanelType0c_1;
-			break;
-		case 13:
-			PanelDesPtr = SiS_PanelType0d_1;
-			break;
-		case 14:
-			PanelDesPtr = SiS_PanelType0e_1;
-			break;
-		case 15:
-			PanelDesPtr = SiS_PanelType0f_1;
-			break;
-		case 16:
-			PanelDesPtr = SiS_PanelType00_2;
-			break;
-		case 17:
-			PanelDesPtr = SiS_PanelType01_2;
-			break;
-		case 18:
-			PanelDesPtr = SiS_PanelType02_2;
-			break;
-		case 19:
-			PanelDesPtr = SiS_PanelType03_2;
-			break;
-		case 20:
-			PanelDesPtr = SiS_PanelType04_2;
-			break;
-		case 21:
-			PanelDesPtr = SiS_PanelType05_2;
-			break;
-		case 22:
-			PanelDesPtr = SiS_PanelType06_2;
-			break;
-		case 23:
-			PanelDesPtr = SiS_PanelType07_2;
-			break;
-		case 24:
-			PanelDesPtr = SiS_PanelType08_2;
-			break;
-		case 25:
-			PanelDesPtr = SiS_PanelType09_2;
-			break;
-		case 26:
-			PanelDesPtr = SiS_PanelType0a_2;
-			break;
-		case 27:
-			PanelDesPtr = SiS_PanelType0b_2;
-			break;
-		case 28:
-			PanelDesPtr = SiS_PanelType0c_2;
-			break;
-		case 29:
-			PanelDesPtr = SiS_PanelType0d_2;
-			break;
-		case 30:
-			PanelDesPtr = SiS_PanelType0e_2;
-			break;
-		case 31:
-			PanelDesPtr = SiS_PanelType0f_2;
-			break;
-		case 32:
-			PanelDesPtr = SiS_CHTVUNTSCDesData;
-			break;
-		case 33:
-			PanelDesPtr = SiS_CHTVONTSCDesData;
-			break;
-		case 34:
-			PanelDesPtr = SiS_CHTVUPALDesData;
-			break;
-		case 35:
-			PanelDesPtr = SiS_CHTVOPALDesData;
-			break;
-		}
-	}
-	SiS_LCDHDES = (PanelDesPtr + ResIndex)->LCDHDES;
-	SiS_LCDVDES = (PanelDesPtr + ResIndex)->LCDVDES;
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		if (SiS_LCDResInfo >= Panel1024x768) {
-			if (ModeNo <= 0x13) {
-				modeflag =
-				    SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-				if (!(modeflag & HalfDCLK)) {
-					SiS_LCDHDES = 320;
-				}
-			}
-		}
-	}
-	return;
+SiS_SetCRT2FIFO2(USHORT SiS_Part1Port,ULONG ROMAddr,USHORT ModeNo,
+                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+#ifdef SIS315H
+ UCHAR CombCode[]={1,1,1,4,3,1,3,4,4,1,4,4,5,1,5,4};
+ UCHAR CRT2ThLow[]={39,63,55,79,78,102,90,114,55,87,84,116,103,135,119,151};
+#endif
+  USHORT temp,temp1,temp2,temp3;
+  USHORT index;
+  USHORT CRT1ModeNo,CRT2ModeNo;
+  USHORT ModeIdIndex;
+  USHORT RefreshRateTableIndex;
+
+  SiS_SetReg1(SiS_Part1Port,0x1,0x3B);
+  /* CRT1ModeNo=(UCHAR)SiS_GetReg1(SiS_P3d4,0x34); *//* get CRT1 ModeNo */
+  CRT1ModeNo = SiS_CRT1Mode;
+  /* CRT1ModeNo =ModeNo; */
+  SiS_SearchModeID(ROMAddr,CRT1ModeNo,&ModeIdIndex);    /* Get ModeID Table */
+  SiS_SetFlag=SiS_SetFlag& (~ProgrammingCRT2);
+
+  RefreshRateTableIndex=SiS_GetRatePtrCRT2(ROMAddr,CRT1ModeNo,
+                            ModeIdIndex); /* Set REFIndex-> for crt1 refreshrate */
+  index = SiS_GetVCLK2Ptr(ROMAddr,CRT1ModeNo,ModeIdIndex,
+                          RefreshRateTableIndex,HwDeviceExtension);
+  temp1=SiS_VCLKData[index].CLOCK;           /* Get VCLK  */
+
+  temp2= SiS_GetColorDepth(ROMAddr,CRT1ModeNo,ModeIdIndex);
+#ifdef SIS315H
+  index = SiS_Get310DRAMType(ROMAddr);
+#endif
+  temp3=SiS_MCLKData[index].CLOCK;           /* Get MCLK  */
 
-}
+  temp=SiS_GetReg1(SiS_P3c4,0x14);
+  if (temp&0x02)
+   	temp=16;
+  else
+    	temp=8;
+
+  temp = temp - temp1*temp2/temp3; /* 16-DRamBus - DCLK*BytePerPixel/MCLK */
+
+  if ((52*16 % temp)==0)
+    	temp = 52*16/temp +40;
+  else
+    	temp = 52*16/temp +40 + 1;
+
+  /* get DRAM latency */
+  temp1=(SiS_GetReg1(SiS_P3c4,0x17)>>3)&0x7; /* SR17[5:3] DRAM Queue depth */
+  temp2=(SiS_GetReg1(SiS_P3c4,0x17)>>6)&0x3; /* SR17[7:6] DRAM Grant length */
+
+#ifdef SIS315H
+  if (SiS_Get310DRAMType(ROMAddr)<2)
+  {
+    for (temp3=0;temp3<16;temp3+=2)
+    {
+      if ((CombCode[temp3]==temp1) && (CombCode[temp3+1]==temp2))
+      {
+        temp3 = CRT2ThLow[temp3>>1];
+      }
+    }
+  }
+  else
+  {
+    for (temp3=0;temp3<16;temp3+=2)
+    {
+      if ((CombCode[temp3]==temp1) && (CombCode[temp3+1]==temp2))
+      {
+        temp3 = CRT2ThLow[8+(temp3>>1)];
+      }
+    }
+  }
+#endif
 
-void
-SiS_GetLVDSDesPtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex, USHORT * PanelIndex,
-		   USHORT * ResIndex)
-{
-	USHORT tempbx, tempal;
+  temp +=  temp3; /* CRT1 Request Period */
 
-	tempbx = 0;
-	if (SiS_IF_DEF_CH7005 == 1) {
-		if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-			tempbx = 32;
-			if (SiS_VBInfo & SetPALTV)
-				tempbx = tempbx + 2;
-			if (SiS_VBInfo & SetCHTVOverScan)
-				tempbx = tempbx + 1;
-		}
-	}
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		tempbx = SiS_LCDTypeInfo;
-		if (SiS_LCDInfo & LCDNonExpanding) {
-			tempbx = tempbx + 16;
-		}
-	}
-	if (ModeNo <= 0x13) {
-		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	tempal = tempal & 0x1F;
-	*PanelIndex = tempbx;
-	*ResIndex = tempal;
-}
+  CRT2ModeNo = ModeNo; /* get CRT2 ModeNo */
+  SiS_SearchModeID(ROMAddr,CRT2ModeNo,&ModeIdIndex);    /* Get ModeID Table */
+  SiS_SetFlag=SiS_SetFlag|ProgrammingCRT2;
+  RefreshRateTableIndex=SiS_GetRatePtrCRT2(ROMAddr,CRT1ModeNo,
+                        ModeIdIndex);/* Set REFIndex-> for crt1 refreshrate */
+  index = SiS_GetVCLK2Ptr(ROMAddr,CRT2ModeNo,ModeIdIndex,
+                          RefreshRateTableIndex,HwDeviceExtension);
+  temp1=SiS_VCLKData[index].CLOCK;           /* Get VCLK  */
+
+  temp2= SiS_GetColorDepth(ROMAddr,CRT2ModeNo,ModeIdIndex);
+#ifdef SIS315H
+  index = SiS_Get310DRAMType(ROMAddr);
+#endif
+  temp3=SiS_MCLKData[index].CLOCK;           /* Get MCLK  */
+ 
+  if ((temp*temp1*temp2)%(16*temp3)==0)
+    temp = temp*temp1*temp2/(16*temp3);   /* CRT1 Request period * TCLK*BytePerPixel/(MCLK*16) */
+  else 
+    temp = temp*temp1*temp2/(16*temp3)+1; /* CRT1 Request period * TCLK*BytePerPixel/(MCLK*16) */
 
-/*301b*/
-void
-SiS_GetLVDSDesPtrA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex, USHORT * PanelIndex,
-		    USHORT * ResIndex)
-{
-	USHORT tempbx, tempal;
-
-	tempbx = 0;
-	tempbx = SiS_LCDResInfo;
-	tempbx = tempbx - Panel1024x768;
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		tempbx = tempbx + 3;
-	}
+  if (temp>0x37)
+    temp = 0x37;
 
-	if (ModeNo <= 0x13) {
-		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	tempal = tempal & 0x1F;
-	*PanelIndex = tempbx;
-	*ResIndex = tempal;
+  SiS_SetRegANDOR(SiS_Part1Port,0x02,~0x3F,temp);
 }
 
-/*end 301b*/
-
 void
-SiS_SetCRT2ModeRegs (USHORT BaseAddr, USHORT ModeNo,
-		     PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetLVDSDesData(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex)
 {
-	USHORT i, j;
-	USHORT tempcl, tempah;
-/*301b*/
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x00, ~0x050, 0x40);
-		SiS_SetRegAND (SiS_Part1Port, 0x2E, 0xF7);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x13, 0xFB, 0x04);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x2c, 0xCF, 0x30);
-		SiS_SetRegANDOR (SiS_Part4Port, 0x21, 0x3F, 0xC0);
-		SiS_SetRegANDOR (SiS_Part4Port, 0x23, 0x7F, 0x00);
-	}
-	/*end 301b */
-	else {
-		for (i = 0, j = 4; i < 3; i++, j++)
-			SiS_SetReg1 (SiS_Part1Port, j, 0);
-
-		tempcl = SiS_ModeType;
-		if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-			if (ModeNo > 0x13) {
-				tempcl = tempcl - ModeVGA;
-				if ((tempcl > 0) || (tempcl == 0)) {
-					tempah = ((0x010 >> tempcl) | 0x080);
-				}
-			} else {
-				tempah = 0x080;
-			}
-			if (SiS_VBInfo & SetInSlaveMode) {
-				tempah = (tempah ^ 0x0A0);
-			}
-		} else {	/* 310 series */
-
-			if (ModeNo > 0x13) {
-				tempcl = tempcl - ModeVGA;
-				if ((tempcl > 0) || (tempcl == 0)) {
-					tempah = (0x008 >> tempcl);
-					if (tempah == 0)
-						tempah = 1;
-					tempah |= 0x040;
-				}
-			} else {
-				tempah = 0x040;
-			}
-
-			if (SiS_VBInfo & SetInSlaveMode) {
-				tempah = (tempah ^ 0x050);
-			}
-
-		}
-
-		if (SiS_VBInfo & CRT2DisplayFlag) {
-			tempah = 0;
-		}
-		SiS_SetReg1 (SiS_Part1Port, 0x00, tempah);
-
-		if (SiS_IF_DEF_LVDS == 0) {	/* ifdef 301 */
-			tempah = 0x01;
-			if (!(SiS_VBInfo & SetInSlaveMode)) {
-				tempah = (tempah | 0x02);
-			}
-			if (!(SiS_VBInfo & SetCRT2ToRAMDAC)) {
-				tempah = (tempah ^ 0x05);
-				if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-					tempah = (tempah ^ 0x01);
-				}
-			}
-
-			tempcl = tempah;	/* 05/03/01 ynlai for TV display bug */
-
-			if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-				tempah = (tempah << 5) & 0xFF;
-				if (SiS_VBInfo & CRT2DisplayFlag) {
-					tempah = 0;
-				}
-				SiS_SetReg1 (SiS_Part1Port, 0x01, tempah);
-
-				tempah = tempah >> 5;
-			} else {	/* 310 series */
-
-				if (SiS_VBInfo & CRT2DisplayFlag) {
-					tempah = 0;
-				}
-				tempah =
-				    (SiS_GetReg1 (SiS_Part1Port, 0x2E) & 0xF8) |
-				    tempah;
-				SiS_SetReg1 (SiS_Part1Port, 0x2E, tempah);
-				tempah = tempcl;
-			}
-
-			if ((SiS_ModeType == ModeVGA)
-			    && (!(SiS_VBInfo & SetInSlaveMode))) {
-				tempah = tempah | 0x010;
-			}
-
-			if (SiS_LCDResInfo == Panel1024x768)
-				tempah = tempah | 0x080;
-
-			if ((SiS_LCDResInfo == Panel1280x1024)
-			    || (SiS_LCDResInfo == Panel1280x960)) {
-				tempah = tempah | 0x080;
-			}
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				if (SiS_VBInfo & SetInSlaveMode) {
-					if (
-					    ((SiS_VBType & VB_SIS301B)
-					     || (SiS_VBType & VB_SIS302B))) {	/*301b */
-						if (SiS_SetFlag & TVSimuMode)
-							tempah = tempah | 0x020;
-					} else
-						tempah = tempah | 0x020;
-				}
-			}
-			SiS_SetRegANDOR (SiS_Part4Port, 0x0D, ~0x0BF, tempah);
-			tempah = 0;
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				if (SiS_VBInfo & SetInSlaveMode) {
-					if (
-					    ((SiS_VBType & VB_SIS301B)
-					     || (SiS_VBType & VB_SIS302B))) {	/*301b */
-						{
-							SiS_SetFlag =
-							    SiS_SetFlag |
-							    RPLLDIV2XO;
-							tempah = tempah | 0x40;
-						}
-					} else {
-						if (!(SiS_SetFlag & TVSimuMode)) {
-							if (!
-							    (SiS_VBInfo &
-							     SetCRT2ToHiVisionTV))
-							{
-								SiS_SetFlag =
-								    SiS_SetFlag
-								    |
-								    RPLLDIV2XO;
-								tempah =
-								    tempah |
-								    0x40;
-							}
-						}
-					}
-				} else {
-					SiS_SetFlag = SiS_SetFlag | RPLLDIV2XO;
-					tempah = tempah | 0x40;
-				}
-			}
-			if (SiS_LCDResInfo == Panel1280x1024)
-				tempah = tempah | 0x80;
-			if (SiS_LCDResInfo == Panel1280x960)
-				tempah = tempah | 0x80;
-			SiS_SetReg1 (SiS_Part4Port, 0x0C, tempah);
-		} else {
-			/*LVDS*/ tempah = 0;
-			if (!(SiS_VBInfo & SetInSlaveMode)) {
-				tempah = tempah | 0x02;
-			}
-			SiS_SetRegANDOR (SiS_Part1Port, 0x2e, 0xF0, tempah);
-		}
-	}
-/*301b*/
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (!(SiS_VBInfo & SetCRT2ToLCDA))) {
-		if (SiS_IsDualEdge (BaseAddr))
-			SiS_SetRegANDOR (SiS_Part1Port, 0x13, 0xFB, 0x00);
-		else
-			SiS_SetRegANDOR (SiS_Part1Port, 0x13, 0xFF, 0x00);
-		if (SiS_IsDualEdge (BaseAddr))
-			SiS_SetRegANDOR (SiS_Part1Port, 0x2c, 0xCF, 0x00);
-		else
-			SiS_SetRegANDOR (SiS_Part1Port, 0x2c, 0xFF, 0x00);
-		if (SiS_IsDualEdge (BaseAddr))
-			SiS_SetRegANDOR (SiS_Part4Port, 0x21, 0x3F, 0x00);
-		else
-			SiS_SetRegANDOR (SiS_Part4Port, 0x21, 0xFF, 0x00);
-
-		if (SiS_IsDualEdge (BaseAddr))
-			SiS_SetRegANDOR (SiS_Part4Port, 0x23, 0xFF, 0x80);
-		else
-			SiS_SetRegANDOR (SiS_Part4Port, 0x23, 0xFF, 0x00);
-	}
+  USHORT modeflag;
+  USHORT PanelIndex,ResIndex;
+  SiS_LVDSDesStruct  *PanelDesPtr=NULL;
 
-/*end 301b*/
-}
-void
-SiS_GetCRT2Data (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex)
-{
-	if (SiS_IF_DEF_LVDS == 0) {	/*301  */
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-			if (SiS_VBInfo & SetCRT2ToLCDA)
-				SiS_GetCRT2DataLVDS (ROMAddr, ModeNo,
-						     ModeIdIndex,
-						     RefreshRateTableIndex);
-			else
-				SiS_GetCRT2Data301 (ROMAddr, ModeNo,
-						    ModeIdIndex,
-						    RefreshRateTableIndex);
-		} else
-			SiS_GetCRT2Data301 (ROMAddr, ModeNo, ModeIdIndex,
-					    RefreshRateTableIndex);
-		return;
-	} else {		/*LVDS */
-		SiS_GetCRT2DataLVDS (ROMAddr, ModeNo, ModeIdIndex,
-				     RefreshRateTableIndex);
-		return;
-	}
+  if((SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+       && (SiS_IF_DEF_LVDS == 0) ) {  /*301b*//*for test*/
+     SiS_GetLVDSDesPtrA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                        &PanelIndex,&ResIndex);
+     switch (PanelIndex)
+     {
+     	case  0: PanelDesPtr = LVDS1024x768Des_1;   break;
+     	case  1: PanelDesPtr = LVDS1280x1024Des_1;  break;
+     	case  2: PanelDesPtr = LVDS1280x960Des_1;   break;
+     	case  3: PanelDesPtr = LVDS1024x768Des_2;   break;
+     	case  4: PanelDesPtr = LVDS1280x1024Des_2;  break;
+     	case  5: PanelDesPtr = LVDS1280x960Des_2;   break;
+     }
+  } else {
+     SiS_GetLVDSDesPtr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                       &PanelIndex,&ResIndex);
+#ifdef LINUX_KERNEL
+     if (PanelIndex < 32)	/* >=32 = TV */
+         printk(KERN_INFO "sisfb: LVDS-LCD panel type %d (Resindex %d)\n", PanelIndex, ResIndex);
+#endif
+     switch (PanelIndex)
+     {
+     	case  0: PanelDesPtr = SiS_PanelType00_1;   break;
+     	case  1: PanelDesPtr = SiS_PanelType01_1;   break;
+     	case  2: PanelDesPtr = SiS_PanelType02_1;   break;
+     	case  3: PanelDesPtr = SiS_PanelType03_1;   break;
+     	case  4: PanelDesPtr = SiS_PanelType04_1;   break;
+     	case  5: PanelDesPtr = SiS_PanelType05_1;   break;
+     	case  6: PanelDesPtr = SiS_PanelType06_1;   break;
+     	case  7: PanelDesPtr = SiS_PanelType07_1;   break;
+     	case  8: PanelDesPtr = SiS_PanelType08_1;   break;
+     	case  9: PanelDesPtr = SiS_PanelType09_1;   break;
+     	case 10: PanelDesPtr = SiS_PanelType0a_1;   break;
+     	case 11: PanelDesPtr = SiS_PanelType0b_1;   break;
+     	case 12: PanelDesPtr = SiS_PanelType0c_1;   break;	/* TW: Clevo 2202   */
+     	case 13: PanelDesPtr = SiS_PanelType0d_1;   break;
+     	case 14: PanelDesPtr = SiS_PanelType0e_1;   break;	/* TW: Uniwill N271S2 */
+     	case 15: PanelDesPtr = SiS_PanelType0f_1;   break;
+     	case 16: PanelDesPtr = SiS_PanelType00_2;   break;
+     	case 17: PanelDesPtr = SiS_PanelType01_2;   break;
+     	case 18: PanelDesPtr = SiS_PanelType02_2;   break;
+     	case 19: PanelDesPtr = SiS_PanelType03_2;   break;
+     	case 20: PanelDesPtr = SiS_PanelType04_2;   break;
+     	case 21: PanelDesPtr = SiS_PanelType05_2;   break;
+     	case 22: PanelDesPtr = SiS_PanelType06_2;   break;
+     	case 23: PanelDesPtr = SiS_PanelType07_2;   break;
+     	case 24: PanelDesPtr = SiS_PanelType08_2;   break;
+     	case 25: PanelDesPtr = SiS_PanelType09_2;   break;
+     	case 26: PanelDesPtr = SiS_PanelType0a_2;   break;
+     	case 27: PanelDesPtr = SiS_PanelType0b_2;   break;
+     	case 28: PanelDesPtr = SiS_PanelType0c_2;   break;
+     	case 29: PanelDesPtr = SiS_PanelType0d_2;   break;
+     	case 30: PanelDesPtr = SiS_PanelType0e_2;   break;
+     	case 31: PanelDesPtr = SiS_PanelType0f_2;   break;
+     	case 32: PanelDesPtr = SiS_CHTVUNTSCDesData;   break;
+     	case 33: PanelDesPtr = SiS_CHTVONTSCDesData;   break;
+     	case 34: PanelDesPtr = SiS_CHTVUPALDesData;    break;
+     	case 35: PanelDesPtr = SiS_CHTVOPALDesData;    break;
+     }
+  }
+  SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+  SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+
+  if(SiS_LCDInfo&LCDNonExpanding){
+    if(SiS_LCDResInfo>=Panel1024x768){
+      if(ModeNo<=0x13){
+        modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+        if(!(modeflag&HalfDCLK)) {
+          SiS_LCDHDES=320;
+        }
+      }
+    }
+  }
+  return;
 }
 
 void
-SiS_GetCRT2DataLVDS (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		     USHORT RefreshRateTableIndex)
-{
-	USHORT tempax, tempbx;
-	USHORT CRT2Index, ResIndex;
-	SiS_LVDSDataStruct *LVDSData = NULL;
-
-	SiS_GetCRT2ResInfo (ROMAddr, ModeNo, ModeIdIndex);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		SiS_GetCRT2PtrA (ROMAddr, ModeNo, ModeIdIndex,
-				 RefreshRateTableIndex, &CRT2Index, &ResIndex);
-		switch (CRT2Index) {
-		case 0:
-			LVDSData = SiS_LVDS1024x768Data_1;
-			break;
-		case 1:
-			LVDSData = SiS_LVDS1280x1024Data_1;
-			break;
-		case 2:
-			LVDSData = SiS_LVDS1280x1024Data_1;
-			break;
-			/*  case  2:  LVDSData=SiS_LVDS1280x960Data_1;  break; */
-		case 3:
-			LVDSData = SiS_LVDS1024x768Data_2;
-			break;
-		case 4:
-			LVDSData = SiS_LVDS1280x1024Data_2;
-			break;
-		case 5:
-			LVDSData = SiS_LVDS1280x1024Data_2;
-			break;
-			/*  case  5:  LVDSData=SiS_LVDS1280x960Data_2;  break; */
-		}
-	}
+SiS_GetLVDSDesPtr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                  USHORT RefreshRateTableIndex,USHORT *PanelIndex,
+		  USHORT *ResIndex)
+{
+  USHORT tempbx,tempal;
+
+  tempbx=0;
+  if(SiS_IF_DEF_CH7005==1) {
+    if(!(SiS_VBInfo&SetCRT2ToLCD)) {
+      tempbx=32;
+      if(SiS_VBInfo&SetPALTV) tempbx=tempbx+2;
+      if(SiS_VBInfo&SetCHTVOverScan) tempbx=tempbx+1;
+    }
+  } 
+  if(SiS_VBInfo&SetCRT2ToLCD) {
+    tempbx=SiS_LCDTypeInfo;
+    if(SiS_LCDInfo&LCDNonExpanding){
+      tempbx=tempbx+16;
+    }
+  }
+  if(ModeNo<=0x13){
+    	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  }else{
+    	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+  tempal=tempal&0x1F;
+  *PanelIndex=tempbx;
+  *ResIndex=tempal;
+}
 
-	else {
-		SiS_GetCRT2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &CRT2Index, &ResIndex);
-		switch (CRT2Index) {
-		case 0:
-			LVDSData = SiS_LVDS800x600Data_1;
-			break;
-		case 1:
-			LVDSData = SiS_LVDS1024x768Data_1;
-			break;
-		case 2:
-			LVDSData = SiS_LVDS1280x1024Data_1;
-			break;
-		case 3:
-			LVDSData = SiS_LVDS800x600Data_2;
-			break;
-		case 4:
-			LVDSData = SiS_LVDS1024x768Data_2;
-			break;
-		case 5:
-			LVDSData = SiS_LVDS1280x1024Data_2;
-			break;
-		case 6:
-			LVDSData = SiS_LVDS640x480Data_1;
-			break;
-		case 7:
-			LVDSData = SiS_CHTVUNTSCData;
-			break;
-		case 8:
-			LVDSData = SiS_CHTVONTSCData;
-			break;
-		case 9:
-			LVDSData = SiS_CHTVUPALData;
-			break;
-		case 10:
-			LVDSData = SiS_CHTVOPALData;
-			break;
-		}
-	}
-	SiS_VGAHT = (LVDSData + ResIndex)->VGAHT;
-	SiS_VGAVT = (LVDSData + ResIndex)->VGAVT;
-	SiS_HT = (LVDSData + ResIndex)->LCDHT;
-	SiS_VT = (LVDSData + ResIndex)->LCDVT;
 /*301b*/
-	if ((SiS_IF_DEF_LVDS == 0)
-	    && ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {	/*for test */
-		if (!(SiS_LCDInfo & LCDNonExpanding)) {
-			if (SiS_LCDResInfo == Panel1024x768) {
-				tempax = 1024;
-				tempbx = 768;
-			} else {
-				tempax = 1280;
-				tempbx = 1024;
-			}
-			SiS_HDE = tempax;
-			SiS_VDE = tempbx;
-		}
-	} else {
-		if (SiS_IF_DEF_TRUMPION == 0) {
-			if (SiS_VBInfo & SetCRT2ToLCD) {
-				if (!(SiS_LCDInfo & LCDNonExpanding)) {
-					if (SiS_LCDResInfo == Panel800x600) {
-						tempax = 800;
-						tempbx = 600;
-					} else if (SiS_LCDResInfo ==
-						   Panel1024x768) {
-						tempax = 1024;
-						tempbx = 768;
-					} else {
-						tempax = 1280;
-						tempbx = 1024;
-					}
-					SiS_HDE = tempax;
-					SiS_VDE = tempbx;
-				}
-			}
-		}
-	}
-	return;
+void
+SiS_GetLVDSDesPtrA(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,USHORT *PanelIndex,
+		   USHORT *ResIndex)
+{
+  USHORT tempbx=0,tempal;
+
+  tempbx=SiS_LCDResInfo-Panel1024x768;
+  if(SiS_LCDInfo&LCDNonExpanding){
+      tempbx=tempbx+3;
+  }
+
+  if(ModeNo<=0x13){
+    	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+  tempal=tempal&0x1F;
+  *PanelIndex=tempbx;
+  *ResIndex=tempal;
 }
+/*end 301b*/
 
 void
-SiS_GetCRT2Data301 (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex)
+SiS_SetCRT2ModeRegs(USHORT BaseAddr,USHORT ModeNo,
+                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT tempax, tempbx, modeflag;
-	USHORT resinfo;
-	USHORT CRT2Index, ResIndex;
-	SiS_LCDDataStruct *LCDPtr = NULL;
-	SiS_TVDataStruct *TVPtr = NULL;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
-	SiS_NewFlickerMode = 0;
-	SiS_RVBHRS = 50;
-	SiS_RY1COE = 0;
-	SiS_RY2COE = 0;
-	SiS_RY3COE = 0;
-	SiS_RY4COE = 0;
-
-	SiS_GetCRT2ResInfo (ROMAddr, ModeNo, ModeIdIndex);
-	if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-		SiS_GetRAMDAC2DATA (ROMAddr, ModeNo, ModeIdIndex,
-				    RefreshRateTableIndex);
-		return;
-	}
+  USHORT i,j;
+  USHORT tempcl,tempah;
 
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		SiS_GetCRT2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &CRT2Index, &ResIndex);
-		switch (CRT2Index) {
-		case 2:
-			TVPtr = SiS_ExtHiTVData;
-			break;
-		case 3:
-			TVPtr = SiS_ExtPALData;
-			break;
-		case 4:
-			TVPtr = SiS_ExtNTSCData;
-			break;
-		case 7:
-			TVPtr = SiS_St1HiTVData;
-			break;
-		case 8:
-			TVPtr = SiS_StPALData;
-			break;
-		case 9:
-			TVPtr = SiS_StNTSCData;
-			break;
-		case 12:
-			TVPtr = SiS_St2HiTVData;
-			break;
-		}
-
-		SiS_RVBHCMAX = (TVPtr + ResIndex)->RVBHCMAX;
-		SiS_RVBHCFACT = (TVPtr + ResIndex)->RVBHCFACT;
-		SiS_VGAHT = (TVPtr + ResIndex)->VGAHT;
-		SiS_VGAVT = (TVPtr + ResIndex)->VGAVT;
-		SiS_HDE = (TVPtr + ResIndex)->TVHDE;
-		SiS_VDE = (TVPtr + ResIndex)->TVVDE;
-		SiS_RVBHRS = (TVPtr + ResIndex)->RVBHRS;
-		SiS_NewFlickerMode = (TVPtr + ResIndex)->FlickerMode;
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-			if (resinfo == 0x08)
-				SiS_NewFlickerMode = 0x40;
-			if (resinfo == 0x09)
-				SiS_NewFlickerMode = 0x40;
-			if (resinfo == 0x10)
-				SiS_NewFlickerMode = 0x40;
-		}
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-			if (SiS_VGAVDE == 350)
-				SiS_SetFlag = SiS_SetFlag | TVSimuMode;
-			tempax = ExtHiTVHT;
-			tempbx = ExtHiTVVT;
-			if (SiS_VBInfo & SetInSlaveMode) {
-				if (SiS_SetFlag & TVSimuMode) {
-					tempax = StHiTVHT;
-					tempbx = StHiTVVT;
-					if (!(modeflag & Charx8Dot)) {
-						tempax = StHiTextTVHT;
-						tempbx = StHiTextTVVT;
-					}
-				}
-			}
-		}
-		if (!(SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-			SiS_RY1COE = (TVPtr + ResIndex)->RY1COE;
-			SiS_RY2COE = (TVPtr + ResIndex)->RY2COE;
-			if (modeflag & HalfDCLK) {
-				SiS_RY1COE = 0x00;
-				SiS_RY2COE = 0xf4;
-			}
-			SiS_RY3COE = (TVPtr + ResIndex)->RY3COE;
-			SiS_RY4COE = (TVPtr + ResIndex)->RY4COE;
-			if (modeflag & HalfDCLK) {
-				SiS_RY3COE = 0x10;
-				SiS_RY4COE = 0x38;
-			}
-			if (!(SiS_VBInfo & SetPALTV)) {
-				tempax = NTSCHT;
-				tempbx = NTSCVT;
-			} else {
-				tempax = PALHT;
-				tempbx = PALVT;
-			}
-		}
-		SiS_HT = tempax;
-		SiS_VT = tempbx;
-		return;
-	}
+  SiS_SetReg1(SiS_Part1Port,0x03,0x00);   /*fix write part1 index 0  BTDRAM bit Bug*/
 
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		SiS_GetCRT2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &CRT2Index, &ResIndex);
-		switch (CRT2Index) {
-		case 0:
-			LCDPtr = SiS_ExtLCD1024x768Data;
-			break;
-		case 1:
-			LCDPtr = SiS_ExtLCD1280x1024Data;
-			break;
-		case 5:
-			LCDPtr = SiS_StLCD1024x768Data;
-			break;
-		case 6:
-			LCDPtr = SiS_StLCD1280x1024Data;
-			break;
-		case 10:
-			LCDPtr = SiS_St2LCD1024x768Data;
-			break;
-		case 11:
-			LCDPtr = SiS_St2LCD1280x1024Data;
-			break;
-		case 13:
-			LCDPtr = SiS_NoScaleData;
-			break;
-		case 14:
-			LCDPtr = SiS_LCD1280x960Data;
-			break;
-		}
-
-		SiS_RVBHCMAX = (LCDPtr + ResIndex)->RVBHCMAX;
-		SiS_RVBHCFACT = (LCDPtr + ResIndex)->RVBHCFACT;
-		SiS_VGAHT = (LCDPtr + ResIndex)->VGAHT;
-		SiS_VGAVT = (LCDPtr + ResIndex)->VGAVT;
-		SiS_HT = (LCDPtr + ResIndex)->LCDHT;
-		SiS_VT = (LCDPtr + ResIndex)->LCDVT;
-		tempax = 1024;
-		if (SiS_SetFlag & LCDVESATiming) {
-			if (SiS_VGAVDE == 350)
-				tempbx = 560;
-			else if (SiS_VGAVDE == 400)
-				tempbx = 640;
-			else
-				tempbx = 768;
-		} else {
-			if (SiS_VGAVDE == 357)
-				tempbx = 527;
-			else if (SiS_VGAVDE == 420)
-				tempbx = 620;
-			else if (SiS_VGAVDE == 525)
-				tempbx = 775;
-			else if (SiS_VGAVDE == 600)
-				tempbx = 775;
-			else if (SiS_VGAVDE == 350)
-				tempbx = 560;
-			else if (SiS_VGAVDE == 400)
-				tempbx = 640;
-			else
-				tempbx = 768;
-		}
-		if (SiS_LCDResInfo == Panel1280x1024) {
-			tempax = 1280;
-			if (SiS_VGAVDE == 360)
-				tempbx = 768;
-			else if (SiS_VGAVDE == 375)
-				tempbx = 800;
-			else if (SiS_VGAVDE == 405)
-				tempbx = 864;
-			else
-				tempbx = 1024;
-		}
-		if (SiS_LCDResInfo == Panel1280x960) {
-			tempax = 1280;
-			if (SiS_VGAVDE == 350)
-				tempbx = 700;
-			else if (SiS_VGAVDE == 400)
-				tempbx = 800;
-			else if (SiS_VGAVDE == 1024)
-				tempbx = 960;
-			else
-				tempbx = 960;
-		}
-		if (SiS_LCDInfo & LCDNonExpanding) {
-			tempax = SiS_VGAHDE;
-			tempbx = SiS_VGAVDE;
-		}
-		SiS_HDE = tempax;
-		SiS_VDE = tempbx;
-		return;
-	}
+  /*301b*/
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+  				&& (SiS_VBInfo&SetCRT2ToLCDA) ) {
+
+	/* TW:   1. for 301B/302B/301LV/302LV (on some of which
+	 *          IF_DEF_LVDS seems to be 1 as well)
+	 */
+
+      SiS_SetRegANDOR(SiS_Part1Port,0x00,~0x050,0x40); /* FUNCTION CONTROL */
+      SiS_SetRegAND(SiS_Part1Port,0x2E,0xF7);
+      SiS_SetRegANDOR(SiS_Part1Port,0x13,0xFB,0x04);
+      SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xCF,0x30);
+      SiS_SetRegANDOR(SiS_Part4Port,0x21,0x3F,0xC0);
+      SiS_SetRegANDOR(SiS_Part4Port,0x23,0x7F,0x00);
+  /*end 301b*/
+  } else {
+    for(i=0,j=4;i<3;i++,j++) SiS_SetReg1(SiS_Part1Port,j,0);
+
+    tempcl=SiS_ModeType;
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+      /* ---- 300 series ---- */
+      if(ModeNo>0x13){
+        tempcl=tempcl-ModeVGA;
+        if((tempcl>0)||(tempcl==0)){
+           tempah=((0x010>>tempcl)|0x080);
+        }
+      } else {
+        tempah=0x080;
+      }
+      if(SiS_VBInfo&SetInSlaveMode){
+         tempah=(tempah^0x0A0);
+      }
+    } else {
+    /* ---- 310 series ---- */
+      if(ModeNo>0x13) {
+        tempcl=tempcl-ModeVGA;
+        if((tempcl>0)||(tempcl==0)){
+           tempah=(0x008>>tempcl);
+           if (tempah==0) tempah=1;
+              tempah |= 0x040;
+        }
+      } else {
+       tempah=0x040;
+      }
+  
+      if(SiS_VBInfo&SetInSlaveMode){
+          tempah=(tempah^0x050);
+      }
+    }
+
+    if(SiS_VBInfo&CRT2DisplayFlag){
+      	tempah=0;
+    }
+    SiS_SetReg1(SiS_Part1Port,0x00,tempah);  /* FUNCTION CONTROL */
+
+    if(SiS_IF_DEF_LVDS==0) {    /* ifdef 301*/
+
+	/* TW:   2. for 301 */
+
+    	tempah=0x01;
+    	if(!(SiS_VBInfo&SetInSlaveMode)) {
+      		tempah=(tempah|0x02);
+    	}
+    	if(!(SiS_VBInfo&SetCRT2ToRAMDAC)) {
+      		tempah=(tempah^0x05);
+      		if(!(SiS_VBInfo&SetCRT2ToLCD)) {
+        		tempah=(tempah^0x01);
+      		}
+    	}
+
+    	tempcl=tempah;     /* 05/03/01 ynlai for TV display bug */
+
+    	if(HwDeviceExtension->jChipType < SIS_315H) {
+      		/* 300 series */
+      		tempah=(tempah<<5)&0xFF;
+      		if(SiS_VBInfo&CRT2DisplayFlag){
+        		tempah=0;
+      		}
+      		SiS_SetReg1(SiS_Part1Port,0x01,tempah);
+
+      		tempah=tempah>>5;
+    	} else {
+      		/* 310 series */
+      		if(SiS_VBInfo&CRT2DisplayFlag){
+        		tempah=0;
+      		}
+      		tempah = (SiS_GetReg1(SiS_Part1Port,0x2E)&0xF8)|tempah;
+      		SiS_SetReg1(SiS_Part1Port,0x2E,tempah);
+      		tempah=tempcl;
+    	}
+
+    	if((SiS_ModeType==ModeVGA)&&(!(SiS_VBInfo&SetInSlaveMode))){
+      		tempah=tempah|0x010;
+    	}
+      
+     	if(SiS_LCDResInfo==Panel1024x768)
+         	tempah=tempah|0x080;
+  
+    	if((SiS_LCDResInfo==Panel1280x1024)||(SiS_LCDResInfo==Panel1280x960)){
+      		tempah=tempah|0x080;
+    	}
+    	if(SiS_VBInfo&SetCRT2ToTV){
+      		if(SiS_VBInfo&SetInSlaveMode){
+        		if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {   /*301b*/
+          			if(SiS_SetFlag&TVSimuMode)
+                			tempah=tempah|0x020;
+        		} else
+          			tempah=tempah|0x020;
+      		}
+    	}
+    	SiS_SetRegANDOR(SiS_Part4Port,0x0D,~0x0BF,tempah);
+    	tempah=0;
+    	if(SiS_VBInfo&SetCRT2ToTV) {
+      		if(SiS_VBInfo&SetInSlaveMode) {
+       			if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) { /*301b*/
+           		{
+            			SiS_SetFlag=SiS_SetFlag|RPLLDIV2XO;
+            			tempah=tempah|0x40;
+          		}
+       			} else {
+        			if(!(SiS_SetFlag&TVSimuMode)) {
+          				if(!(SiS_VBInfo&SetCRT2ToHiVisionTV)) {
+            					SiS_SetFlag=SiS_SetFlag|RPLLDIV2XO;
+            					tempah=tempah|0x40;
+          				}
+        			}
+      			}
+     		}
+      		else {
+        		SiS_SetFlag=SiS_SetFlag|RPLLDIV2XO;
+        		tempah=tempah|0x40;
+      		}
+    	}
+    	if(SiS_LCDResInfo==Panel1280x1024) tempah=tempah|0x80;
+    	if(SiS_LCDResInfo==Panel1280x960) tempah=tempah|0x80;
+    	SiS_SetReg1(SiS_Part4Port,0x0C,tempah);
+    } else {
+
+    	/* TW: 3. for LVDS, _not_ 301B/302B/301LV/302LV */
+
+    	tempah=0;
+
+    	if((!(SiS_VBInfo&SetInSlaveMode)) &&
+          	    (ModeNo!=0x2e)&&(ModeNo!=0x30)&&(ModeNo!=0x38)&&(ModeNo!=0x3A)) {
+      			tempah=tempah|0x02;
+    	}
+    	SiS_SetRegANDOR(SiS_Part1Port,0x2e,0xF0,tempah); /* <------------------- */
+    }
+  }
+
+  /*301b*/
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+ 				&& (!(SiS_VBInfo&SetCRT2ToLCDA))){
+      if(SiS_IsDualEdge(BaseAddr))
+         SiS_SetRegANDOR(SiS_Part1Port,0x13,0xFB,0x00);
+      else
+         SiS_SetRegANDOR(SiS_Part1Port,0x13,0xFF,0x00);
+      if(SiS_IsDualEdge(BaseAddr))
+         SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xCF,0x00);
+      else
+         SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xFF,0x00);
+      if(SiS_IsDualEdge(BaseAddr))
+         SiS_SetRegANDOR(SiS_Part4Port,0x21,0x3F,0x00);
+      else
+         SiS_SetRegANDOR(SiS_Part4Port,0x21,0xFF,0x00);
+
+      if(SiS_IsDualEdge(BaseAddr))
+         SiS_SetRegANDOR(SiS_Part4Port,0x23,0xFF,0x80);
+       else
+         SiS_SetRegANDOR(SiS_Part4Port,0x23,0xFF,0x00);     
+  }
+  /*end 301b*/
+}
+
+void
+SiS_GetCRT2Data(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex)
+{
+  if(SiS_IF_DEF_LVDS==0) { /* 301  */
+     if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+        if(SiS_VBInfo&SetCRT2ToLCDA)
+          SiS_GetCRT2DataLVDS(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+        else
+          SiS_GetCRT2Data301(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+     } else
+     	SiS_GetCRT2Data301(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+     return;
+  } else {  /* LVDS */
+     SiS_GetCRT2DataLVDS(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+     return;
+  }
+}
+
+void
+SiS_GetCRT2DataLVDS(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                    USHORT RefreshRateTableIndex)
+{
+   USHORT tempax,tempbx;
+   USHORT CRT2Index,ResIndex;
+   SiS_LVDSDataStruct *LVDSData=NULL;
+
+   SiS_GetCRT2ResInfo(ROMAddr,ModeNo,ModeIdIndex);
+   /*301b*/
+   if((SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+   	 && (SiS_VBInfo&SetCRT2ToLCDA)) {
+      SiS_GetCRT2PtrA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                      &CRT2Index,&ResIndex);
+      switch (CRT2Index) {
+      	case  0:  LVDSData=SiS_LVDS1024x768Data_1;    break;
+      	case  1:  LVDSData=SiS_LVDS1280x1024Data_1;   break;
+      	case  2:  LVDSData=SiS_LVDS1280x1024Data_1;   break;
+    	/*  case  2:  LVDSData=SiS_LVDS1280x960Data_1;  break;*/
+      	case  3:  LVDSData=SiS_LVDS1024x768Data_2;    break;
+      	case  4:  LVDSData=SiS_LVDS1280x1024Data_2;   break;
+      	case  5:  LVDSData=SiS_LVDS1280x1024Data_2;   break;
+    	/*  case  5:  LVDSData=SiS_LVDS1280x960Data_2;  break; */
+       }    
+   } else {
+      SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,&CRT2Index,&ResIndex);
+      switch (CRT2Index) {
+      	case  0:  LVDSData=SiS_LVDS800x600Data_1;    break;
+      	case  1:  LVDSData=SiS_LVDS1024x768Data_1;   break;
+      	case  2:  LVDSData=SiS_LVDS1280x1024Data_1;  break;
+      	case  3:  LVDSData=SiS_LVDS800x600Data_2;    break;
+      	case  4:  LVDSData=SiS_LVDS1024x768Data_2;   break;
+      	case  5:  LVDSData=SiS_LVDS1280x1024Data_2;  break;
+      	case  6:  LVDSData=SiS_LVDS640x480Data_1;    break;
+      	case  7:  LVDSData=SiS_CHTVUNTSCData;        break;
+      	case  8:  LVDSData=SiS_CHTVONTSCData;        break;
+      	case  9:  LVDSData=SiS_CHTVUPALData;         break;
+      	case 10:  LVDSData=SiS_CHTVOPALData;         break;
+      	case 11:  LVDSData=SiS_LVDS320x480Data_1;    break;
+     }
+   }
+   SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
+   SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
+   SiS_HT = (LVDSData+ResIndex)->LCDHT;
+   SiS_VT = (LVDSData+ResIndex)->LCDVT;
+
+  /*301b*/ /* TW: I have NOT added LVDS check here */
+  if( (SiS_IF_DEF_LVDS==0) &&
+      (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))) {/*for test*/
+    if(!(SiS_LCDInfo&LCDNonExpanding)){
+         if(SiS_LCDResInfo==Panel1024x768){
+           tempax=1024;
+           tempbx=768;
+         } else {
+           tempax=1280;
+           tempbx=1024;
+         }
+         SiS_HDE=tempax;
+         SiS_VDE=tempbx;
+    }
+  } else {
+   if(SiS_IF_DEF_TRUMPION==0){
+     if(SiS_VBInfo&SetCRT2ToLCD){
+       if(!(SiS_LCDInfo&LCDNonExpanding)){
+         if(SiS_LCDResInfo==Panel640x480){
+           tempax=640;
+           tempbx=480;
+         } else if(SiS_LCDResInfo==Panel800x600){
+           tempax=800;
+           tempbx=600;
+         } else if(SiS_LCDResInfo==Panel1024x768){
+           tempax=1024;
+           tempbx=768;
+         } else {
+           tempax=1280;
+           tempbx=1024;
+         }
+         if(SiS_IF_DEF_FSTN){           /*fstn*/
+           tempax=320;
+           tempbx=480;
+         }
+         SiS_HDE=tempax;
+         SiS_VDE=tempbx;
+       }
+     }
+   }
+  } 
+  return;
+}
+
+void
+SiS_GetCRT2Data301(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                        USHORT RefreshRateTableIndex)
+{
+  USHORT tempax,tempbx,modeflag;
+  USHORT resinfo;
+  USHORT CRT2Index,ResIndex;
+  SiS_LCDDataStruct *LCDPtr=NULL;
+  SiS_TVDataStruct  *TVPtr=NULL;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+  SiS_NewFlickerMode=0;
+  SiS_RVBHRS=50;
+  SiS_RY1COE=0;
+  SiS_RY2COE=0;
+  SiS_RY3COE=0;
+  SiS_RY4COE=0;
+
+  SiS_GetCRT2ResInfo(ROMAddr,ModeNo,ModeIdIndex);
+  if(SiS_VBInfo&SetCRT2ToRAMDAC){
+    	SiS_GetRAMDAC2DATA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+    	return;
+  }
+
+  if(SiS_VBInfo&SetCRT2ToTV){
+    SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                   &CRT2Index,&ResIndex);
+    switch (CRT2Index) {
+      case  2:  TVPtr=SiS_ExtHiTVData;   break;
+      case  3:  TVPtr=SiS_ExtPALData;    break;
+      case  4:  TVPtr=SiS_ExtNTSCData;   break;
+      case  7:  TVPtr=SiS_St1HiTVData;   break;
+      case  8:  TVPtr=SiS_StPALData;     break;
+      case  9:  TVPtr=SiS_StNTSCData;    break;
+      case 12:  TVPtr=SiS_St2HiTVData;   break;
+      default:  TVPtr=SiS_StPALData;     break;  /* TW: Just to avoid a crash */
+    }
+
+    SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
+    SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
+    SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
+    SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
+    SiS_HDE = (TVPtr+ResIndex)->TVHDE;
+    SiS_VDE = (TVPtr+ResIndex)->TVVDE;
+    SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
+    SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+    if(SiS_VBInfo&SetCRT2ToHiVisionTV ) {
+      	if(resinfo==0x08) SiS_NewFlickerMode=0x40;
+      	if(resinfo==0x09) SiS_NewFlickerMode=0x40;
+	if(resinfo==0x10) SiS_NewFlickerMode=0x40;
+    }
+    if(SiS_VBInfo&SetCRT2ToHiVisionTV ) {
+      if(SiS_VGAVDE==350) SiS_SetFlag=SiS_SetFlag|TVSimuMode;
+      tempax=ExtHiTVHT;
+      tempbx=ExtHiTVVT;
+      if(SiS_VBInfo&SetInSlaveMode) {
+        if(SiS_SetFlag&TVSimuMode) {
+          tempax=StHiTVHT;
+          tempbx=StHiTVVT;
+          if(!(modeflag&Charx8Dot)){
+            tempax=StHiTextTVHT;
+            tempbx=StHiTextTVVT;
+          }
+        }
+      }
+    }
+    if(!(SiS_VBInfo&SetCRT2ToHiVisionTV)) {
+      SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+      SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+      if(modeflag&HalfDCLK) {
+        SiS_RY1COE = 0x00;
+        SiS_RY2COE = 0xf4;
+      }
+      SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+      SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+      if(modeflag&HalfDCLK) {
+        SiS_RY3COE = 0x10;
+        SiS_RY4COE = 0x38;
+      }
+      if(!(SiS_VBInfo&SetPALTV)){
+        tempax=NTSCHT;
+        tempbx=NTSCVT;
+      }
+      else{
+        tempax=PALHT;
+        tempbx=PALVT;
+      }
+    }
+    SiS_HT=tempax;
+    SiS_VT=tempbx;
+    return;
+  }
+
+  if(SiS_VBInfo&SetCRT2ToLCD){
+    SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                   &CRT2Index,&ResIndex);
+    switch (CRT2Index) {
+      case  0: LCDPtr = SiS_ExtLCD1024x768Data;        break;
+      case  1: LCDPtr = SiS_ExtLCD1280x1024Data;       break;
+      case  5: LCDPtr = SiS_StLCD1024x768Data;         break;
+      case  6: LCDPtr = SiS_StLCD1280x1024Data;        break;
+      case 10: LCDPtr = SiS_St2LCD1024x768Data;        break;
+      case 11: LCDPtr = SiS_St2LCD1280x1024Data;       break;
+      case 13: LCDPtr = SiS_NoScaleData;               break;
+      case 14: LCDPtr = SiS_LCD1280x960Data;           break;
+      default: LCDPtr = SiS_ExtLCD1024x768Data;	       break; /* TW: Just to avoid a crash */
+    }
+
+    SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
+    SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+    SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
+    SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
+    SiS_HT = (LCDPtr+ResIndex)->LCDHT;
+    SiS_VT = (LCDPtr+ResIndex)->LCDVT;
+    tempax=1024;
+    if(SiS_SetFlag&LCDVESATiming) {
+      if(SiS_VGAVDE==350) tempbx=560;
+      else if(SiS_VGAVDE==400) tempbx=640;
+      else tempbx=768;
+    }
+    else {
+      if(SiS_VGAVDE==357) tempbx=527;
+      else if(SiS_VGAVDE==420) tempbx=620;
+      else if(SiS_VGAVDE==525) tempbx=775;
+      else if(SiS_VGAVDE==600) tempbx=775;
+      else if(SiS_VGAVDE==350) tempbx=560;
+      else if(SiS_VGAVDE==400) tempbx=640;
+      else tempbx=768;
+    }
+    if(SiS_LCDResInfo==Panel1280x1024){
+      tempax=1280;
+      if(SiS_VGAVDE==360) tempbx=768;
+      else if(SiS_VGAVDE==375) tempbx=800;
+           else if(SiS_VGAVDE==405) tempbx=864;
+                else tempbx=1024;
+    }
+    if(SiS_LCDResInfo==Panel1280x960){
+      tempax=1280;
+      if(SiS_VGAVDE==350) tempbx=700;
+      else if(SiS_VGAVDE==400) tempbx=800;
+           else if(SiS_VGAVDE==1024) tempbx=960;
+                else tempbx=960;
+    }
+    if(SiS_LCDInfo&LCDNonExpanding) {
+       tempax=SiS_VGAHDE;
+       tempbx=SiS_VGAVDE;
+    }
+    SiS_HDE=tempax;
+    SiS_VDE=tempbx;
+    return;
+  }
 }
 
 USHORT
-SiS_GetResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT resindex;
-
-	if (ModeNo <= 0x13) {
-		resindex = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;	/* si+St_ResInfo */
-	} else {
-		resindex = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;	/* si+Ext_ResInfo */
-	}
-	return (resindex);
-}
-
-void
-SiS_GetCRT2ResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetResInfo(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT xres, yres, modeflag, resindex;
+  USHORT resindex;
 
-	resindex = SiS_GetResInfo (ROMAddr, ModeNo, ModeIdIndex);
-	if (ModeNo <= 0x13) {
-		xres = SiS_StResInfo[resindex].HTotal;
-		yres = SiS_StResInfo[resindex].VTotal;
-	} else {
-		xres = SiS_ModeResInfo[resindex].HTotal;	/* xres->ax */
-		yres = SiS_ModeResInfo[resindex].VTotal;	/* yres->bx */
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+St_ModeFlag */
-		if (modeflag & HalfDCLK) {
-			xres = xres * 2;
-		}
-		if (modeflag & DoubleScanMode) {
-			yres = yres * 2;
-		}
-	}
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_LCDResInfo == Panel1280x1024) {
-			if (yres == 400)
-				yres = 405;
-			if (yres == 350)
-				yres = 360;
-			if (SiS_SetFlag & LCDVESATiming) {
-				if (yres == 360)
-					yres = 375;
-			}
-		}
-		if (SiS_LCDResInfo == Panel1024x768) {
-			if (!(SiS_SetFlag & LCDVESATiming)) {
-				if (!(SiS_LCDInfo & LCDNonExpanding)) {
-					if (yres == 350)
-						yres = 357;
-					if (yres == 400)
-						yres = 420;
-/*          if(!OldBios)             */
-					if (yres == 480)
-						yres = 525;
-				}
-			}
-		}
-	} else {
-		if (xres == 720)
-			xres = 640;
-	}
-	SiS_VGAHDE = xres;
-	SiS_HDE = xres;
-	SiS_VGAVDE = yres;
-	SiS_VDE = yres;
-}
-
-void
-SiS_GetCRT2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		USHORT RefreshRateTableIndex, USHORT * CRT2Index,
-		USHORT * ResIndex)
-{
-	USHORT tempbx, tempal;
-	USHORT Flag;
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_VBInfo & SetCRT2ToLCD) {	/* LCD */
-			tempbx = SiS_LCDResInfo;
-			tempbx = tempbx - Panel1024x768;
-			if (!(SiS_SetFlag & LCDVESATiming)) {
-				tempbx += 5;
-/*      GetRevisionID();  */
-				tempbx += 5;
-			}
-		} else {
-			if (SiS_VBInfo & SetCRT2ToHiVisionTV) {	/* TV */
-				if (SiS_VGAVDE > 480)
-					SiS_SetFlag =
-					    SiS_SetFlag & (!TVSimuMode);
-				tempbx = 2;
-				if (SiS_VBInfo & SetInSlaveMode) {
-					if (!(SiS_SetFlag & TVSimuMode))
-						tempbx = 10;
-				}
-			} else {
-				if (SiS_VBInfo & SetPALTV) {
-					tempbx = 3;
-				} else {
-					tempbx = 4;
-				}
-				if (SiS_SetFlag & TVSimuMode) {
-					tempbx = tempbx + 5;
-				}
-			}
-		}
-		if (ModeNo <= 0x13) {
-			tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-		} else {
-			tempal =
-			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		}
-		tempal = tempal & 0x3F;
-		/*301b */
-		if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-		    && (SiS_VBInfo & SetCRT2ToTV)) {
-			/*look */
-			if (tempal == 0x06)
-				tempal = 0x07;
-
-		}
-		/*end 301b */
-		if ((0x31 <= ModeNo) && (ModeNo <= 0x35))
-			tempal = 6;
-		if (SiS_LCDInfo & LCDNonExpanding)
-			tempbx = 0x0D;
-		if (SiS_LCDResInfo == Panel1280x960)
-			tempbx = 0x0E;
-		*CRT2Index = tempbx;
-		*ResIndex = tempal;
-	} else {		/* LVDS */
-		Flag = 1;
-		tempbx = 0;
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-				Flag = 0;
-				tempbx = 7;
-				if (SiS_VBInfo & SetPALTV)
-					tempbx = tempbx + 2;
-				if (SiS_VBInfo & SetCHTVOverScan)
-					tempbx = tempbx + 1;
-			}
-		}
-		if (Flag == 1) {
-			tempbx = SiS_LCDResInfo - Panel800x600;
-			if (SiS_LCDInfo & LCDNonExpanding) {
-				tempbx = tempbx + 3;
-			}
-		}
-		if (ModeNo <= 0x13) {
-			tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-		} else {
-			tempal =
-			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		}
-		tempal = tempal & 0x1F;
-		*CRT2Index = tempbx;
-		*ResIndex = tempal;
-	}
+  if(ModeNo<=0x13){
+    	resindex=SiS_SModeIDTable[ModeIdIndex].St_ResInfo;              /* si+St_ResInfo */
+  } else {
+    	resindex=SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;            	/* si+Ext_ResInfo */
+  }
+  return(resindex);
+}
+
+void
+SiS_GetCRT2ResInfo(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT xres,yres,modeflag,resindex;
+
+  resindex=SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
+  if(ModeNo<=0x13){
+    	xres=SiS_StResInfo[resindex].HTotal;
+    	yres=SiS_StResInfo[resindex].VTotal;
+  } else {
+    	xres=SiS_ModeResInfo[resindex].HTotal;                         		/* xres->ax */
+    	yres=SiS_ModeResInfo[resindex].VTotal;                         		/* yres->bx */
+    	modeflag=SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;      		/* si+St_ModeFlag */
+    	if(SiS_IF_DEF_FSTN){							/*fstn*/
+       		xres=xres*2;
+       		yres=yres*2;
+    	} else {
+      		if(modeflag&HalfDCLK) { xres=xres*2;}
+      		if(modeflag&DoubleScanMode) {yres=yres*2;}
+    	}
+  }
+  if(SiS_IF_DEF_LVDS==0) {
+    	if(SiS_LCDResInfo==Panel1280x1024) {
+      		if(yres==400) yres=405;
+      		if(yres==350) yres=360;
+      		if(SiS_SetFlag&LCDVESATiming) {
+        		if(yres==360) yres=375;
+      		}
+   	 }
+    	if(SiS_LCDResInfo==Panel1024x768){
+      		if(!(SiS_SetFlag&LCDVESATiming)) {
+        		if(!(SiS_LCDInfo&LCDNonExpanding)) {
+          			if(yres==350) yres=357;
+          			if(yres==400) yres=420;
+/*          			if(!OldBios)             */
+            			if(yres==480) yres=525;
+        		}
+      		}
+    	}
+  } else { /* LVDS - does not support 720x??? */
+    	if(xres==720) xres=640;
+  }
+  SiS_VGAHDE=xres;
+  SiS_HDE=xres;
+  SiS_VGAVDE=yres;
+  SiS_VDE=yres;
+}
+
+void
+SiS_GetCRT2Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+	       USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex)
+{
+  USHORT tempbx,tempal=0;
+  USHORT Flag;
+  if(SiS_IF_DEF_LVDS==0) {
+    	if(SiS_VBInfo&SetCRT2ToLCD){              /* LCD */
+      		tempbx=SiS_LCDResInfo;
+      		tempbx=tempbx-Panel1024x768;
+      		if(!(SiS_SetFlag&LCDVESATiming)) {
+        		tempbx+=5;
+/*      		GetRevisionID();  */
+        		tempbx+=5;
+       		}
+     	} else {
+       		if(SiS_VBInfo&SetCRT2ToHiVisionTV){              /* TV */
+         		if(SiS_VGAVDE>480) SiS_SetFlag=SiS_SetFlag&(!TVSimuMode);
+         		tempbx=2;
+         		if(SiS_VBInfo&SetInSlaveMode) {
+            			if(!(SiS_SetFlag&TVSimuMode)) tempbx=10;
+         		}
+       		} else {
+         		if(SiS_VBInfo&SetPALTV){
+           			tempbx=3;
+         		} else {
+           			tempbx=4;
+         		}
+         		if(SiS_SetFlag&TVSimuMode){
+           			tempbx=tempbx+5;
+         		}
+       		}
+     	}
+
+     	if(ModeNo<=0x13){
+       		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     	} else {
+       		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     	}
+     	tempal=tempal&0x3F;
+     	/*301b*/
+      	if((SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+       					&& (SiS_VBInfo&SetCRT2ToTV)) {
+        	/*look*/
+      		if(tempal==0x06) tempal=0x07;
+        }
+   	/*end 301b*/
+     	if((0x31<=ModeNo)&&(ModeNo<=0x35)) tempal=6;
+     	if(SiS_LCDInfo&LCDNonExpanding) tempbx=0x0D;
+     	if(SiS_LCDResInfo==Panel1280x960) tempbx=0x0E;	/* TW !!!! */
+     	*CRT2Index=tempbx;
+     	*ResIndex=tempal;
+  } else {   /* LVDS */
+    	Flag=1;
+    	tempbx=0;
+    	if(SiS_IF_DEF_CH7005==1) {
+      		if(!(SiS_VBInfo&SetCRT2ToLCD)) {
+        		Flag=0;
+        		tempbx=7;
+        		if(SiS_VBInfo&SetPALTV) tempbx=tempbx+2;
+        		if(SiS_VBInfo&SetCHTVOverScan) tempbx=tempbx+1;
+      		}
+    	}
+    	if(Flag==1) {
+      		tempbx=SiS_LCDResInfo-Panel800x600;
+      		if(SiS_LCDInfo&LCDNonExpanding){
+        		tempbx=tempbx+3;
+      		}
+    	}
+     	if(SiS_LCDResInfo==Panel640x480){
+        	tempbx=6;
+      	}
+     	/*fstn*/
+     	if(SiS_IF_DEF_FSTN){
+       	 	if(SiS_LCDResInfo==Panel320x480){
+         		tempbx=11;                        /* not same with asmber code */
+         		tempal=6;	/* TW: That can't work - is being overwritten below... */
+        	}
+    	}
+
+	else 				/* TW: .... unless I place an "else" here */
+     
+    	if(ModeNo<=0x13){
+      		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+    	} else {
+      		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+    	}
+    	tempal=tempal&0x1F;
+    	*CRT2Index=tempbx;
+    	*ResIndex=tempal;
+  }
+}
+
+void
+SiS_GetCRT2PtrA(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+		USHORT *ResIndex)
+{
+  USHORT tempbx,tempal;
+
+  tempbx=SiS_LCDResInfo-Panel1024x768;
+  if(SiS_LCDInfo&LCDNonExpanding){
+        tempbx=tempbx+3;
+  }
+  if(ModeNo<=0x13){
+      	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+      	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+  tempal=tempal&0x1F;
+  *CRT2Index=tempbx;
+  *ResIndex=tempal;
 }
-
-void
-SiS_GetCRT2PtrA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex, USHORT * CRT2Index,
-		 USHORT * ResIndex)
-{
-	USHORT tempbx, tempal;
-
-	tempbx = SiS_LCDResInfo - Panel1024x768;
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		tempbx = tempbx + 3;
-	}
-	if (ModeNo <= 0x13) {
-		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	tempal = tempal & 0x1F;
-	*CRT2Index = tempbx;
-	*ResIndex = tempal;
-}
-
 /*end 301b*/
 
 USHORT
-SiS_GetRatePtrCRT2 (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetRatePtrCRT2(ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
 {
-	SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 };
-	SHORT LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01 };
-	USHORT RefreshRateTableIndex, i;
-	USHORT modeflag, index, temp;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-
-	if (SiS_IF_DEF_CH7005 == 1) {
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			if (modeflag & HalfDCLK)
-				return (0);
-		}
-	}
-	if (ModeNo < 0x14)
-		return (0xFFFF);
-	index = SiS_GetReg1 (SiS_P3d4, 0x33);
-	index = index >> SiS_SelectCRT2Rate;
-	index = index & 0x0F;
-	if (SiS_LCDInfo & LCDNonExpanding)
-		index = 0;
-	if (index > 0)
-		index--;
-
-	if (SiS_SetFlag & ProgrammingCRT2) {
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				index = 0;
-			}
-		}
-		if (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			if (SiS_IF_DEF_LVDS == 0) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) temp =
-					    LCDARefreshIndex[SiS_LCDResInfo];	/*301b */
-				else
-					temp = LCDRefreshIndex[SiS_LCDResInfo];
-				if (index > temp) {
-					index = temp;
-				}
-			} else {
-				index = 0;
-			}
-		}
-	}
-
-	RefreshRateTableIndex = SiS_EModeIDTable[ModeIdIndex].REFindex;
-	ModeNo = SiS_RefIndex[RefreshRateTableIndex].ModeID;
-	i = 0;
-	do {
-		if (SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo)
-			break;
-		temp = SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
-		temp = temp & ModeInfoFlag;
-		if (temp < SiS_ModeType)
-			break;
-
-		i++;
-		index--;
-	} while (index != 0xFFFF);
-
-	if (!(SiS_VBInfo & SetCRT2ToRAMDAC)) {
-		if (SiS_VBInfo & SetInSlaveMode) {
-			temp =
-			    SiS_RefIndex[RefreshRateTableIndex + i -
-					 1].Ext_InfoFlag;
-			if (temp & InterlaceMode) {
-				i++;
-			}
-		}
+  /* TW: These tables are being indexed with SiS_LCDResInfo.
+   *     This is equal to the Panel???x??? constants in initdef.h
+   *     and is eg. 2 for 1024x768; these tables were each one
+   *     value too short!
+   */
+  SHORT  LCDRefreshIndex[]  = {0x00,0x00,0x03,0x01,0x01};
+  SHORT  LCDARefreshIndex[] = {0x00,0x00,0x03,0x01,0x01,0x01,0x01,0x01};
+  USHORT RefreshRateTableIndex,i,backup_i;
+  USHORT modeflag,index,temp;
+
+  if (ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  }else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  if(SiS_IF_DEF_CH7005==1) {
+    	if(SiS_VBInfo&SetCRT2ToTV) {
+      		if(modeflag&HalfDCLK) return(0);
+    	}
+  }
+
+  if(ModeNo<0x14) return(0xFFFF);
+
+ /* TW: CR33 holds refresh rate index for CRT1 (0-3) and CRT2 (4-7).
+  *     On LVDS machines, CRT2 index is always 0 and will be
+  *     set to 0 by the following code; this causes the function
+  *     to take the first non-interlaced mode in SiS300_Ext2Struct
+  *     (which is the second 1024x768 mode in case the resolution
+  *     is 1024x768; the first mode in the list is interlaced and
+  *     therefore skipped).
+  */
+
+  index=SiS_GetReg1(SiS_P3d4,0x33);
+  index=index>>SiS_SelectCRT2Rate;
+  index=index&0x0F;
+  if(SiS_LCDInfo&LCDNonExpanding) index=0;
+  if(index>0) index--;
+
+  if(SiS_SetFlag & ProgrammingCRT2) {
+    	if(SiS_IF_DEF_CH7005==1) {
+      		if(SiS_VBInfo&SetCRT2ToTV) {
+        		index=0;
+      		}
+    	}
+    	if(SiS_VBInfo&(SetCRT2ToLCD|SetCRT2ToLCDA)) {
+      		if(SiS_IF_DEF_LVDS==0) {
+        		if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+           			temp=LCDARefreshIndex[SiS_LCDResInfo];     /* 301b */
+        		else
+           			temp=LCDRefreshIndex[SiS_LCDResInfo];	   /* 301  */
+        		if(index>temp){
+          			index=temp;
+        		}
+      		} else {  						   /* LVDS */
+        		index=0;
+      		}
+    	}
+  }
+
+  RefreshRateTableIndex = SiS_EModeIDTable[ModeIdIndex].REFindex;
+  ModeNo = SiS_RefIndex[RefreshRateTableIndex].ModeID;
+
+  i=0;
+  do {
+    	if (SiS_RefIndex[RefreshRateTableIndex+i].ModeID!=ModeNo) break;
+    	temp = SiS_RefIndex[RefreshRateTableIndex+i].Ext_InfoFlag;
+    	temp=temp&ModeInfoFlag;
+    	if(temp<SiS_ModeType) break;
+    	i++;
+    	index--;
+  } while(index!=0xFFFF);
+
+  if(!(SiS_VBInfo&SetCRT2ToRAMDAC)) {
+    	if(SiS_VBInfo&SetInSlaveMode) {
+      		temp=SiS_RefIndex[RefreshRateTableIndex+i-1].Ext_InfoFlag;
+      			if(temp&InterlaceMode) {
+        			i++;
+      			}
+    	}
+  }
+  i--;
+
+  if((SiS_SetFlag & ProgrammingCRT2) && (!(SiS_VBInfo & DisableCRT2Display))) {
+    	backup_i = i;
+    	if (!(SiS_AdjustCRT2Rate(ROMAddr,ModeNo,ModeIdIndex,
+	                             RefreshRateTableIndex,&i))) {
+		/* TW: This is for avoiding random data to be used; i is
+		 *     in an undefined state if no matching CRT2 mode is
+		 *     found.
+		 */
+		i = backup_i;
+#ifdef LINUX_KERNEL
+		printk("sisfb: WARNING: No matching CRT2 mode found\n");
+#endif
 	}
+  }
 
-	i--;
-	if ((SiS_SetFlag & ProgrammingCRT2)) {
-		temp =
-		    SiS_AjustCRT2Rate (ROMAddr, ModeNo, ModeIdIndex,
-				       RefreshRateTableIndex, &i);
-	}
-	return (RefreshRateTableIndex + i);	/*return(0x01|(temp1<<1));   */
+  return(RefreshRateTableIndex+i);                			/*return(0x01|(temp1<<1));   */
 }
 
 BOOLEAN
-SiS_AjustCRT2Rate (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex, USHORT * i)
+SiS_AdjustCRT2Rate(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,USHORT *i)
 {
-	USHORT tempax, tempbx, resinfo;
-	USHORT modeflag, infoflag;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ModeFlag */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-
-	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	tempbx = SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
-	tempax = 0;
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-			tempax = tempax | SupportRAMDAC2;
-		}
-		if (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {	/*301b */
-			tempax = tempax | SupportLCD;
-			if (SiS_LCDResInfo != Panel1280x1024) {
-				if (SiS_LCDResInfo != Panel1280x960) {
-					if (SiS_LCDInfo & LCDNonExpanding) {
-						if (resinfo >= 9) {
-							tempax = 0;
-							return (0);
-						}
-					}
-				}
-			}
-		}
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV) {	/* for HiTV */
-			tempax = tempax | SupportHiVisionTV;
-			if (SiS_VBInfo & SetInSlaveMode) {
-				if (resinfo == 4)
-					return (0);
-				if (resinfo == 3) {
-					if (SiS_SetFlag & TVSimuMode)
-						return (0);
-				}
-				if (resinfo > 7)
-					return (0);
-			}
-		} else {
-			if (SiS_VBInfo &
-			    (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO |
-			     SetCRT2ToSCART)) {
-				tempax = tempax | SupportTV;
-				/*301b */
-				if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {	/*301b */
-
-					tempax = tempax | SupportTV1024;
-
-				}
-				/*end 301b */
-
-				if (!(SiS_VBInfo & SetPALTV)) {
-					if (modeflag & NoSupportSimuTV) {
-						if (SiS_VBInfo & SetInSlaveMode) {
-							if (!
-							    (SiS_VBInfo &
-							     SetNotSimuMode)) {
-								return 0;
-							}
-						}
-					}
-				}
-			}
-		}
-	} else {		/* for LVDS */
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				tempax = tempax | SupportCHTV;
-			}
-		}
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			tempax = tempax | SupportLCD;
-			if (resinfo > 0x08)
-				return (0);	/*1024x768  */
-			if (SiS_LCDResInfo < Panel1024x768) {
-				if (resinfo > 0x07)
-					return (0);	/*800x600  */
-				if (resinfo == 0x04)
-					return (0);	/*512x384  */
-			}
-		}
-	}
-
-	for (; SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx;
-	     (*i)--) {
-		infoflag =
-		    SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-		if (infoflag & tempax) {
-			return (1);
-		}
-		if ((*i) == 0)
-			break;
-	}
+  USHORT tempax,tempbx,resinfo;
+  USHORT modeflag,infoflag;
 
-	for ((*i) = 0;; (*i)++) {
-		infoflag =
-		    SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-		if (SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
-			return (0);
-		}
-		if (infoflag & tempax) {
-			return (1);
-		}
-	}
-	return (1);
-}
-
-void
-SiS_SaveCRT2Info (USHORT ModeNo)
-{
-	USHORT temp1, temp2;
-
-	SiS_SetReg1 (SiS_P3d4, 0x34, ModeNo);	/* reserve CR34 for CRT1 Mode No */
-	temp1 = (SiS_VBInfo & SetInSlaveMode) >> 8;
-	temp2 = ~(SetInSlaveMode >> 8);
-	SiS_SetRegANDOR (SiS_P3d4, 0x31, temp2, temp1);
-}
-
-void
-SiS_GetVBInfo301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		  USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT tempax, tempbx, temp;
-	USHORT modeflag;
-	UCHAR OutputSelect = *pSiS_OutputSelect;
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-	SiS_SetFlag = 0;
-
-	SiS_ModeType = modeflag & ModeInfoFlag;
-	tempbx = 0;
-	if (SiS_BridgeIsOn (BaseAddr)) {
-		temp = SiS_GetReg1 (SiS_P3d4, 0x30);
-		tempbx = tempbx | temp;
-		temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-		tempax = temp << 8;
-		tempbx = tempbx | tempax;
-		temp = SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display;	/* ynlai */
-		temp = 0xFFFF ^ temp;
-		tempbx = tempbx & temp;
-#ifdef CONFIG_FB_SIS_315
-		/*301b */
-		if ((SiS_VBType & VB_SIS302B)) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x38);
-			if (temp == 0x03)
-				tempbx = tempbx | (SetCRT2ToLCDA);
-		}
-		/*end301b */
-#endif
-		if (SiS_IF_DEF_LVDS == 0) {
-			if (SiS_IF_DEF_HiVision)
-				temp = 0x80FC;
-			else
-				temp = 0x807C;
-		} else {
-			if (SiS_IF_DEF_CH7005 == 1) {
-				temp = SetCRT2ToTV | SetCRT2ToLCD;
-			} else {
-				temp = SetCRT2ToLCD;
-			}
-		}
-		if (!(tempbx & temp)) {
-			tempax = tempax | DisableCRT2Display;
-			tempbx = 0;
-		}
-
-		if (SiS_IF_DEF_LVDS == 0) {
-			if (tempbx & SetCRT2ToLCDA) {	/*301b */
-				tempbx =
-				    tempbx & (0xFF00 | SwitchToCRT2 |
-					      SetSimuScanMode);
-			} else if (tempbx & SetCRT2ToRAMDAC) {
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToRAMDAC |
-					      SwitchToCRT2 | SetSimuScanMode);
-			} else if ((tempbx & SetCRT2ToLCD) && (!(SiS_VBType & VB_NoLCD))) {	/*301dlvds */
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToLCD |
-					      SwitchToCRT2 | SetSimuScanMode);
-			} else if (tempbx & SetCRT2ToSCART) {
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToSCART |
-					      SwitchToCRT2 | SetSimuScanMode);
-				tempbx = tempbx | SetPALTV;
-			} else if (tempbx & SetCRT2ToHiVisionTV) {
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToHiVisionTV |
-					      SwitchToCRT2 | SetSimuScanMode);
-				/* ynlai begin */
-				tempbx = tempbx | SetPALTV;
-				/* ynlai end */
-			}
-		} else {
-			if (SiS_IF_DEF_CH7005 == 1) {
-				if (tempbx & SetCRT2ToTV)
-					tempbx =
-					    tempbx & (0xFF00 | SetCRT2ToTV |
-						      SwitchToCRT2 |
-						      SetSimuScanMode);
-			}
-			if (tempbx & SetCRT2ToLCD)
-				tempbx =
-				    tempbx & (0xFF00 | SetCRT2ToLCD |
-					      SwitchToCRT2 | SetSimuScanMode);
-		}
-		if (tempax & DisableCRT2Display) {
-			if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
-				tempbx = SetSimuScanMode | DisableCRT2Display;
-			}
-		}
-		if (!(tempbx & DriverMode)) {
-			tempbx = tempbx | SetSimuScanMode;
-		}
-		if (!(tempbx & SetSimuScanMode)) {
-			if (tempbx & SwitchToCRT2) {
-				if (!(modeflag & CRT2Mode)) {
-					tempbx = tempbx | SetSimuScanMode;
-				}
-			} else {
-				if (!
-				    (SiS_BridgeIsEnable
-				     (BaseAddr, HwDeviceExtension))) {
-					if (!(tempbx & DriverMode)) {
-						if (SiS_BridgeInSlave ()) {
-							tempbx =
-							    tempbx |
-							    SetInSlaveMode;
-						}
-					}
-				}
-			}
-		}
-		if (!(tempbx & DisableCRT2Display)) {
-			if (tempbx & DriverMode) {
-				if (tempbx & SetSimuScanMode) {
-					if (!(modeflag & CRT2Mode)) {
-						tempbx =
-						    tempbx | SetInSlaveMode;
-						if (SiS_IF_DEF_LVDS == 0) {
-							if (tempbx &
-							    SetCRT2ToTV) {
-								if (!
-								    (tempbx &
-								     SetNotSimuMode))
-								   SiS_SetFlag =
-									    SiS_SetFlag
-									    |
-									    TVSimuMode;
-							}
-						}
-					}
-				}
-			} else {
-				tempbx = tempbx | SetInSlaveMode;
-				if (SiS_IF_DEF_LVDS == 0) {
-					if (tempbx & SetCRT2ToTV) {
-						if (!(tempbx & SetNotSimuMode))
-							SiS_SetFlag =
-							    SiS_SetFlag |
-							    TVSimuMode;
-					}
-				}
-			}
-		}
-		if (SiS_IF_DEF_CH7005 == 1) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x35);
-			if (temp & TVOverScan)
-				tempbx = tempbx | SetCHTVOverScan;
-		}
-	}
-#ifdef CONFIG_FB_SIS_300
-	/*add PALMN */
-	if (SiS_IF_DEF_LVDS == 0) {
-		if ((HwDeviceExtension->jChipType == SIS_630) ||
-		    (HwDeviceExtension->jChipType == SIS_730)) {
-			if (!(OutputSelect & EnablePALMN))
-				SiS_SetRegAND (SiS_P3d4, 0x35, 0x3F);
-			if (tempbx & SetCRT2ToTV) {
-				if (tempbx & SetPALTV) {
-					temp = SiS_GetReg1 (SiS_P3d4, 0x35);
-					temp = temp & 0xC0;
-					if (temp == 0x40)
-						tempbx = tempbx & (~SetPALTV);
-				}
-			}
-		}
-	}
-	/*end add */
+  if (ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;    	/* si+St_ModeFlag */
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  tempbx = SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID;
+  tempax=0;
+  if(SiS_IF_DEF_LVDS==0) {
+  	/* TW: For 301 (and which ones of 301B, 302B, 301LV, 302LV ?) */
+    	if(SiS_VBInfo&SetCRT2ToRAMDAC) {
+      		tempax=tempax|SupportRAMDAC2;
+    	}
+    	if(SiS_VBInfo&(SetCRT2ToLCD|SetCRT2ToLCDA)) {        /* 301b */
+      		tempax=tempax|SupportLCD;
+      		if(SiS_LCDResInfo!=Panel1280x1024) {
+        		if(SiS_LCDResInfo!=Panel1280x960) {
+           			if(SiS_LCDInfo&LCDNonExpanding) {
+             				if(resinfo>=9) {
+               					tempax=0;
+               					return(0);
+             				}
+           			}
+        		}
+      		}
+    	}
+    	if(SiS_VBInfo&SetCRT2ToHiVisionTV) {    /* for HiTV */
+      		tempax=tempax|SupportHiVisionTV;
+      		if(SiS_VBInfo&SetInSlaveMode){
+        		if(resinfo==4) return(0);
+        		if(resinfo==3) {
+          			if(SiS_SetFlag&TVSimuMode) return(0);
+        		}
+        		if(resinfo>7) return(0);
+      		}
+    	} else {
+      		if(SiS_VBInfo&(SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+        		tempax=tempax|SupportTV;
+       			/*301b*/
+         		if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+             			tempax=tempax|SupportTV1024;
+         		}
+        		/*end 301b*/
+       
+        		if(!(SiS_VBInfo&SetPALTV)) {
+          			if(modeflag&NoSupportSimuTV) {
+            				if(SiS_VBInfo&SetInSlaveMode) {
+              					if(!(SiS_VBInfo&SetNotSimuMode)) {
+                					return 0;
+              					}
+            				}
+          			}
+        		}
+      		}
+    	}
+  } else {
+  	/* TW: for LVDS (and which ones of the SiS bridges?) */
+    	if(SiS_IF_DEF_CH7005==1) {
+      		if(SiS_VBInfo&SetCRT2ToTV) {
+        		tempax=tempax|SupportCHTV;
+      		}
+    	}
+    	if(SiS_VBInfo&SetCRT2ToLCD) {
+      		tempax=tempax|SupportLCD;
+      		if(resinfo>0x08) return(0);       	  /* 1024x768  */
+      		if(SiS_LCDResInfo<Panel1024x768) {
+        		if(resinfo>0x07) return(0);       /*  800x600  */
+        		if(resinfo==0x04) return(0);      /*  512x384  */
+      		}
+    	}
+  }
+  /* TW: Look backwards in table for matching CRT2 mode */
+  for(;SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID==tempbx;(*i)--) {
+     	infoflag = SiS_RefIndex[RefreshRateTableIndex+(*i)].Ext_InfoFlag;
+     	if(infoflag&tempax) {
+       		return(1);
+     	}
+     	if ((*i)==0) break;
+  }
+  /* TW: Look through the whole mode-section of the table from the beginning
+   *     for a matching CRT2 mode if no mode was found yet.
+   */
+  for((*i)=0;;(*i)++) {
+     	infoflag = SiS_RefIndex[RefreshRateTableIndex+(*i)].Ext_InfoFlag;
+     	if(SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID!=tempbx) {
+       		return(0);
+     	}
+     	if(infoflag&tempax) {
+       		return(1);
+     	}
+  }
+  return(1);
+}
+
+void
+SiS_SaveCRT2Info(USHORT ModeNo)
+{
+  USHORT temp1,temp2;
+
+  SiS_SetReg1(SiS_P3d4,0x34,ModeNo);  /* reserve CR34 for CRT1 Mode No */
+  temp1=(SiS_VBInfo&SetInSlaveMode)>>8;
+  temp2=~(SetInSlaveMode>>8);
+  SiS_SetRegANDOR(SiS_P3d4,0x31,temp2,temp1);
+}
+
+void
+SiS_GetVBInfo301(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+                 USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempax,tempbx,temp;
+  USHORT modeflag;
+  UCHAR  OutputSelect=*pSiS_OutputSelect;
+
+  if (ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+   	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+  SiS_SetFlag=0;
+
+  SiS_ModeType=modeflag&ModeInfoFlag;
+  
+  tempbx=0;
+  if(SiS_BridgeIsOn(BaseAddr)) {
+    	temp=SiS_GetReg1(SiS_P3d4,0x30);
+    	if((SiS_IF_DEF_LVDS==0) && (SiS_VBType&(VB_SIS301LV|VB_SIS302LV))) {
+       		temp=temp&0xbf;                                        	/*301lvds disable CRT2*/
+    	}
+    	if(SiS_IF_DEF_FSTN){                             		/*fstn must set CR30=0x21 */
+       		temp=0x21;
+       		SiS_SetReg1(SiS_P3d4,0x30,temp);
+    	}
+    	tempbx=tempbx|temp;
+    	temp=SiS_GetReg1(SiS_P3d4,0x31);
+    	tempax=temp<<8;
+    	tempbx=tempbx|tempax;
+    	temp=SetCHTVOverScan|SetInSlaveMode|DisableCRT2Display;  	/* ynlai */
+   	temp=0xFFFF^temp;
+    	tempbx=tempbx&temp;
+#ifdef SIS315H
+     	/*301b*/
+    	if((SiS_IF_DEF_LVDS==0) && (SiS_VBType&(VB_SIS302B|VB_SIS302LV))){
+       		temp=SiS_GetReg1(SiS_P3d4,0x38);
+       		if(temp==0x03)
+          		tempbx=tempbx|(SetCRT2ToLCDA);
+    	}
+    	/*end301b*/
 #endif
-#ifdef CONFIG_FB_SIS_315
-	/*add PALMN */
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (!(OutputSelect & EnablePALMN))
-			SiS_SetRegAND (SiS_P3d4, 0x38, 0x3F);
-		if (tempbx & SetCRT2ToTV) {
-			if (tempbx & SetPALTV) {
-				temp = SiS_GetReg1 (SiS_P3d4, 0x38);
-				temp = temp & 0xC0;
-				if (temp == 0x40)
-					tempbx = tempbx & (~SetPALTV);
-			}
-		}
-	}
-	/*end add */
+    	if(SiS_IF_DEF_LVDS==0) {
+      		if(SiS_IF_DEF_HiVision) temp=0x80FC;
+      		else temp=0x807C;
+    	} else {
+      		if(SiS_IF_DEF_CH7005==1) {
+        		temp = SetCRT2ToTV|SetCRT2ToLCD;
+      		} else {
+        		temp = SetCRT2ToLCD;
+      		}
+    	}
+    	if(!(tempbx&temp)) {
+      		tempax=tempax|DisableCRT2Display;
+      		tempbx=0;
+    	}
+   
+   	if(SiS_IF_DEF_LVDS==0) {
+      		if(tempbx&SetCRT2ToLCDA) {                                    /*301b*/
+        		tempbx=tempbx&(0xFF00|SwitchToCRT2|SetSimuScanMode);
+      		} else if(tempbx&SetCRT2ToRAMDAC) {
+        		tempbx=tempbx&(0xFF00|SetCRT2ToRAMDAC|SwitchToCRT2|SetSimuScanMode);
+      		} else if((tempbx&SetCRT2ToLCD)&&(!(SiS_VBType&VB_NoLCD)) ){              /*301dlvds*/
+        		tempbx=tempbx&(0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
+      		} else if(tempbx&SetCRT2ToSCART){
+        		tempbx=tempbx&(0xFF00|SetCRT2ToSCART|SwitchToCRT2|SetSimuScanMode);
+        		tempbx=tempbx|SetPALTV;
+      		} else if(tempbx&SetCRT2ToHiVisionTV){
+        		tempbx=tempbx&(0xFF00|SetCRT2ToHiVisionTV|SwitchToCRT2|SetSimuScanMode);
+  			/* ynlai begin */
+        		tempbx=tempbx|SetPALTV;
+  			/* ynlai end */
+      		}
+   	} else { /* LVDS */
+      		if(SiS_IF_DEF_CH7005==1) {
+        		if(tempbx&SetCRT2ToTV)
+          			tempbx=tempbx&(0xFF00|SetCRT2ToTV|SwitchToCRT2|SetSimuScanMode);
+      		}
+      		if(tempbx&SetCRT2ToLCD)
+        		tempbx=tempbx&(0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
+	}
+    	if(tempax&DisableCRT2Display) {
+      		if(!(tempbx&(SwitchToCRT2|SetSimuScanMode))) {
+        		tempbx=SetSimuScanMode|DisableCRT2Display;
+      		}
+    	}
+    	if(!(tempbx&DriverMode)){
+      		tempbx=tempbx|SetSimuScanMode;
+    	}
+	/* TW: LVDS bridge can only be slave in 8bpp modes */
+	if ((SiS_IF_DEF_LVDS==1) &&
+		(ModeNo == 0x2e || ModeNo == 0x30 ||
+			ModeNo == 0x38 || ModeNo == 0x3a)) {
+		tempbx=tempbx|SetSimuScanMode|SetInSlaveMode;
+	}
+	/* TW end */
+    	if(!(tempbx&SetSimuScanMode)){
+      		if(tempbx&SwitchToCRT2) {
+        		if(!(modeflag&CRT2Mode)) {
+            			tempbx=tempbx|SetSimuScanMode;
+        		}
+
+      		} else {
+        		if(!(SiS_BridgeIsEnable(BaseAddr,HwDeviceExtension))) {
+          			if(!(tempbx&DriverMode)) {
+            				if(SiS_BridgeInSlave()) {
+              					tempbx=tempbx|SetInSlaveMode;
+            				}
+          			}
+        		}
+      		}
+    	}
+    	if(!(tempbx&DisableCRT2Display)) {
+     		 if(tempbx&DriverMode) {
+        		if(tempbx&SetSimuScanMode) {
+          			if(!(modeflag&CRT2Mode)) {
+            				tempbx=tempbx|SetInSlaveMode;
+            				if(SiS_IF_DEF_LVDS==0) {
+              					if(tempbx&SetCRT2ToTV) {
+                					if(!(tempbx&SetNotSimuMode))
+								SiS_SetFlag=SiS_SetFlag|TVSimuMode;
+              					}
+            				}
+          			}
+        		}
+      		} else {
+        		tempbx=tempbx|SetInSlaveMode;
+        		if(SiS_IF_DEF_LVDS==0) {
+          			if(tempbx&SetCRT2ToTV) {
+            				if(!(tempbx&SetNotSimuMode))
+						SiS_SetFlag=SiS_SetFlag|TVSimuMode;
+          			}
+        		}
+      		}
+    	}
+    	if(SiS_IF_DEF_CH7005==1) {
+      		temp=SiS_GetReg1(SiS_P3d4,0x35);
+      		if(temp&TVOverScan) tempbx=tempbx|SetCHTVOverScan;
+    	}
+  }
+  /*add PALMN*/
+  if(SiS_IF_DEF_LVDS==0) {
+#ifdef SIS300
+     	if((HwDeviceExtension->jChipType==SIS_630)||
+           (HwDeviceExtension->jChipType==SIS_730)) {
+           	if(!(OutputSelect&EnablePALMN))
+             		SiS_SetRegAND(SiS_P3d4,0x35,0x3F);
+           	if(tempbx&SetCRT2ToTV) {
+              		if(tempbx&SetPALTV) {
+                  		temp=SiS_GetReg1(SiS_P3d4,0x35);
+                  		temp=temp&0xC0;
+                  		if(temp==0x40)
+                    			tempbx=tempbx&(~SetPALTV);
+             		}
+          	}
+      	}
+#endif
+#ifdef SIS315H
+     	if((HwDeviceExtension->jChipType == SIS_315H)||
+           (HwDeviceExtension->jChipType == SIS_315PRO)||
+           (HwDeviceExtension->jChipType == SIS_550)||   /* 05/02/01 ynlai for 550 */
+           (HwDeviceExtension->jChipType == SIS_640)||   /* 08/20/01 chiawen for 640/740 */
+           (HwDeviceExtension->jChipType == SIS_740)||   /* 09/03/01 chiawen for 640/740 */
+           (HwDeviceExtension->jChipType == SIS_650)) {
+		if(!(OutputSelect&EnablePALMN))
+        		SiS_SetRegAND(SiS_P3d4,0x38,0x3F);
+   		if(tempbx&SetCRT2ToTV) {
+    			if(tempbx&SetPALTV) {
+               			temp=SiS_GetReg1(SiS_P3d4,0x38);
+               			temp=temp&0xC0;
+               			if(temp==0x40)
+               				tempbx=tempbx&(~SetPALTV);
+              		}
+        	}
+  	}
+#endif
+ /*end add*/
+  }
+  SiS_VBInfo=tempbx;
+#ifdef LINUX_KERNEL
+  printk(KERN_INFO "sisfb: (VBInfo = %x)\n", SiS_VBInfo);
+#endif
+#ifdef LINUX_XF86
+  xf86DrvMsg(0, X_INFO, "(init301.c: VBInfo = %x)\n", SiS_VBInfo);
 #endif
-	SiS_VBInfo = tempbx;
-}
-
-void
-SiS_GetRAMDAC2DATA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex)
-{
-	USHORT tempax, tempbx, temp;
-	USHORT temp1, temp2, modeflag = 0, tempcx;
-
-	USHORT StandTableIndex, CRT1Index;
-	USHORT ResInfo, DisplayType;
-	SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
-
-	SiS_RVBHCMAX = 1;
-	SiS_RVBHCFACT = 1;
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-		StandTableIndex = SiS_GetModePtr (ROMAddr, ModeNo, ModeIdIndex);
-		tempax = SiS_StandTable[StandTableIndex].CRTC[0];
-		tempbx = SiS_StandTable[StandTableIndex].CRTC[6];
-		temp1 = SiS_StandTable[StandTableIndex].CRTC[7];
-	} else {
-		if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-		    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-			/*add crt1ptr */
-			temp =
-			    SiS_GetLVDSCRT1Ptr (ROMAddr, ModeNo, ModeIdIndex,
-						RefreshRateTableIndex, &ResInfo,
-						&DisplayType);
-			if (temp == 0) {
-				return;
-			}
-			switch (DisplayType) {
-			case 0:
-				LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;
-				break;
-			case 1:
-				LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;
-				break;
-			case 2:
-				LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;
-				break;
-			case 3:
-				LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;
-				break;
-			case 4:
-				LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;
-				break;
-			case 5:
-				LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;
-				break;
-			case 6:
-				LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;
-				break;
-			case 7:
-				LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;
-				break;
-			case 8:
-				LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;
-				break;
-			case 9:
-				LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;
-				break;
-			case 10:
-				LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;
-				break;
-			case 11:
-				LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;
-				break;
-			case 12:
-				LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;
-				break;
-			case 13:
-				LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;
-				break;
-			case 14:
-				LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;
-				break;
-			case 15:
-				LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;
-				break;
-			}
-			temp1 = (LVDSCRT1Ptr + ResInfo)->CR[0];
-			temp2 = (LVDSCRT1Ptr + ResInfo)->CR[14];
-			tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
-			tempbx = (LVDSCRT1Ptr + ResInfo)->CR[6];
-			tempcx = (LVDSCRT1Ptr + ResInfo)->CR[13] << 8;
-			tempcx = tempcx & 0x0100;
-			tempcx = tempcx << 2;
-			tempbx = tempbx | tempcx;
-			temp1 = (LVDSCRT1Ptr + ResInfo)->CR[7];
-		} /*add 301b */
-		else {
-			modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-			CRT1Index =
-			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-			CRT1Index = CRT1Index & 0x3F;
-			temp1 = (USHORT) SiS_CRT1Table[CRT1Index].CR[0];
-			temp2 = (USHORT) SiS_CRT1Table[CRT1Index].CR[14];
-			tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
-			tempbx = (USHORT) SiS_CRT1Table[CRT1Index].CR[6];
-			tempcx = (USHORT) SiS_CRT1Table[CRT1Index].CR[13] << 8;
-			tempcx = tempcx & 0x0100;
-			tempcx = tempcx << 2;
-			tempbx = tempbx | tempcx;
-			temp1 = (USHORT) SiS_CRT1Table[CRT1Index].CR[7];
-		}
-	}
-	if (temp1 & 0x01)
-		tempbx = tempbx | 0x0100;
-	if (temp1 & 0x20)
-		tempbx = tempbx | 0x0200;
-	tempax = tempax + 5;
-	if (modeflag & Charx8Dot)
-		tempax = tempax * 8;
-	else
-		tempax = tempax * 9;
-
-	SiS_VGAHT = tempax;
-	SiS_HT = tempax;
-	tempbx++;
-	SiS_VGAVT = tempbx;
-	SiS_VT = tempbx;
-}
-
-void
-SiS_UnLockCRT2 (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-	if (HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x2f, 0xFF, 0x01);
-	} else {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x24, 0xFF, 0x01);
-	}
-}
-
-void
-SiS_LockCRT2 (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-	if (HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x2F, 0xFE, 0x00);
-	} else {
-		SiS_SetRegANDOR (SiS_Part1Port, 0x24, 0xFE, 0x00);
-	}
-}
-
-void
-SiS_EnableCRT2 ()
-{
-	SiS_SetRegANDOR (SiS_P3c4, 0x1E, 0xFF, 0x20);
 }
 
 void
-SiS_DisableBridge (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_GetRAMDAC2DATA(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex)
 {
-
-	USHORT temp1, tempah, temp;
-	SiS_SetRegANDOR (SiS_P3c4, 0x11, 0xF7, 0x08);
-/*SetPanelDelay(1);  */
-	temp1 = 0x01;
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {	/*301b */
-		if ((SiS_IsVAMode (BaseAddr)))
-			temp1 = 0x00;	/*no disable vb */
-	}
-
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (!temp1) {	/*301b */
-			SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0x0DF, 0x00);	/* disable VB */
-			SiS_DisplayOff ();
-			if (HwDeviceExtension->jChipType >= SIS_315H) {	/* 310 series */
-				SiS_SetRegOR (SiS_Part1Port, 0x00, 0x80);	/* alan,BScreenOff */
-			}
-			SiS_SetRegANDOR (SiS_P3c4, 0x32, 0xDF, 0x00);
-
-			temp = SiS_GetReg1 (SiS_Part1Port, 0);
-			SiS_SetRegOR (SiS_Part1Port, 0x00, 0x10);	/* alan,BScreenOff */
+  USHORT tempax,tempbx,temp;
+  USHORT temp1,temp2,modeflag=0,tempcx;
+  USHORT StandTableIndex,CRT1Index;
+  USHORT ResInfo,DisplayType;
+  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+  SiS_RVBHCMAX=1;
+  SiS_RVBHCFACT=1;
+  if(ModeNo<=0x13){
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	StandTableIndex = SiS_GetModePtr(ROMAddr,ModeNo,ModeIdIndex);
+    	tempax = SiS_StandTable[StandTableIndex].CRTC[0];
+    	tempbx = SiS_StandTable[StandTableIndex].CRTC[6];
+    	temp1=SiS_StandTable[StandTableIndex].CRTC[7];
+  } else {
+    if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+        			&& (SiS_VBInfo&SetCRT2ToLCDA) ) {
+    	/*add crt1ptr*/
+    	temp=SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,
+			RefreshRateTableIndex,&ResInfo,&DisplayType);
+    	if(temp==0){
+    		return;
+    	}
+    	switch(DisplayType) {
+    		case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;		break;
+    		case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
+    		case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
+    		case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
+    		case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
+    		case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
+    		case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
+    		case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
+    		case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
+    		case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
+    		case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
+    		case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
+    		case 12: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
+    		case 13: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
+    		case 14: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
+    		case 15: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
+    		case 16: LVDSCRT1Ptr = SiS_LVDSCRT1320x480_1;           break;
+    	}
+    	temp1=(LVDSCRT1Ptr+ResInfo)->CR[0];
+    	temp2=(LVDSCRT1Ptr+ResInfo)->CR[14];
+    	tempax=(temp1&0xFF)|((temp2&0x03)<<8);
+    	tempbx=(LVDSCRT1Ptr+ResInfo)->CR[6];
+    	tempcx=(LVDSCRT1Ptr+ResInfo)->CR[13]<<8;
+    	tempcx = tempcx&0x0100;
+    	tempcx = tempcx << 2;
+    	tempbx = tempbx | tempcx;
+    	temp1=(LVDSCRT1Ptr+ResInfo)->CR[7];
+    	/*add 301b*/
+    } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+    	CRT1Index=CRT1Index&0x3F;
+    	temp1 = (USHORT)SiS_CRT1Table[CRT1Index].CR[0];
+    	temp2 = (USHORT)SiS_CRT1Table[CRT1Index].CR[14];
+    	tempax=(temp1&0xFF)|((temp2&0x03)<<8);
+    	tempbx = (USHORT)SiS_CRT1Table[CRT1Index].CR[6];
+    	tempcx = (USHORT)SiS_CRT1Table[CRT1Index].CR[13]<<8;
+    	tempcx = tempcx&0x0100;
+    	tempcx = tempcx << 2;
+    	tempbx = tempbx | tempcx;
+    	temp1 = (USHORT)SiS_CRT1Table[CRT1Index].CR[7];
+   }
+  }
+  if(temp1&0x01) tempbx=tempbx|0x0100;
+  if(temp1&0x20) tempbx=tempbx|0x0200;
+  tempax=tempax+5;
+  if(modeflag&Charx8Dot) tempax=tempax*8;
+  else tempax=tempax*9;
+
+  SiS_VGAHT=tempax;
+  SiS_HT=tempax;
+  tempbx++;
+  SiS_VGAVT=tempbx;
+  SiS_VT=tempbx;
+}
+
+void
+SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+    	SiS_SetRegANDOR(SiS_Part1Port,0x2f,0xFF,0x01);
+  } else {
+    	SiS_SetRegANDOR(SiS_Part1Port,0x24,0xFF,0x01);
+  }
+}
+
+void
+SiS_LockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+    	SiS_SetRegANDOR(SiS_Part1Port,0x2F,0xFE,0x00);
+  } else {
+     	SiS_SetRegANDOR(SiS_Part1Port,0x24,0xFE,0x00);
+  }
+}
+
+void
+SiS_EnableCRT2()
+{
+  SiS_SetRegANDOR(SiS_P3c4,0x1E,0xFF,0x20);
+}
+
+void
+SiS_DisableBridge(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT  BaseAddr)
+{
+  USHORT temp1,tempah,temp;
+
+  SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x08);
+
+  /*SetPanelDelay(1); */
+  temp1=0x01;
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)))  {  /*301b*/
+    	if((SiS_IsVAMode(BaseAddr)))
+       		temp1=0x00;			/*no disable vb*/
+  }
+
+  if(SiS_IF_DEF_LVDS==0) {
+   if(!(temp1)){              /*301b*/
+    SiS_SetRegANDOR(SiS_Part2Port,0x00,0x0DF,0x00);   /* disable VB */
+    SiS_DisplayOff();
+    if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+      SiS_SetRegOR(SiS_Part1Port,0x00,0x80);  /* FUNCTION CTRL | alan,BScreenOff */
+    }
+    SiS_SetRegANDOR(SiS_P3c4,0x32,0xDF,0x00);
+    
+    temp = SiS_GetReg1(SiS_Part1Port,0); 
+    SiS_SetRegOR(SiS_Part1Port,0x00,0x10);  /* FUNCTION CTRL | alan,BScreenOff */
 /*
-     if(HwDeviceExtension->jChipType >= SIS_315H) 
+     if(HwDeviceExtension->jChipType >= SIS_315H)
      {
-      SiS_SetRegAND(SiS_Part1Port,0x2E,0x7F);  
+      	SiS_SetRegAND(SiS_Part1Port,0x2E,0x7F);
      }
-     */
-			SiS_SetRegANDOR (SiS_P3c4, 0x1E, 0xDF, 0x00);
-			SiS_SetReg1 (SiS_Part1Port, 0, temp);
-		} else {
-			if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {	/*301b */
-				if (!(SiS_Is301B (BaseAddr))) {
-					SiS_SetRegAND (SiS_P3c4, 0x32, 0xDF);
-					if ((!(SiS_IsDualEdge (BaseAddr)))
-					    && (!(SiS_IsVAMode (BaseAddr))))
-						tempah = 0x7F;
-					else if ((!(SiS_IsDualEdge (BaseAddr)))
-						 && (SiS_IsVAMode (BaseAddr)))
-						tempah = 0xBF;
-					else
-						tempah = 0x3F;
-					SiS_SetRegAND (SiS_Part4Port, 0x1F,
-						       tempah);
-				}
-			}
-		}
-	} else {
-		if (SiS_IF_DEF_CH7005) {
-			SiS_SetCH7005 (0x090E);
-		}
-		SiS_DisplayOff ();
-		SiS_SetRegANDOR (SiS_P3c4, 0x32, 0xDF, 0x00);
-		SiS_SetRegANDOR (SiS_P3c4, 0x1E, 0xDF, 0x00);
-		SiS_UnLockCRT2 (HwDeviceExtension, BaseAddr);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x01, 0xFF, 0x80);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x02, 0xFF, 0x40);
-	}
-/*SetPanelDelay(0);  */
-	SiS_SetRegANDOR (SiS_P3c4, 0x11, 0xFB, 0x04);
-}
-
-void
-SiS_EnableBridge (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-	USHORT temp, tempah;
-
-	SiS_SetRegANDOR (SiS_P3c4, 0x11, 0xFB, 0x00);
-/*SetPanelDelay(0);        */
-	if (SiS_IF_DEF_LVDS == 0) {
-		if ((!(SiS_IsVAMode (BaseAddr)))
-		    && ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-			SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0x1F, 0x20);
-		} else {
-			temp = SiS_GetReg1 (SiS_P3c4, 0x32);
-			temp = temp & 0xDF;
-			if (SiS_BridgeInSlave ()) {
-				tempah = SiS_GetReg1 (SiS_P3d4, 0x30);
-				if (!(tempah & SetCRT2ToRAMDAC)) {
-					temp = temp | 0x20;
-				}
-			}
-			SiS_SetReg1 (SiS_P3c4, 0x32, temp);
-			SiS_SetRegANDOR (SiS_P3c4, 0x1E, 0xFF, 0x20);
-			if (HwDeviceExtension->jChipType >= SIS_315H) {	/* 310 series */
-				temp = SiS_GetReg1 (SiS_Part1Port, 0x2E);
-				if (!(temp & 0x80))
-					SiS_SetRegOR (SiS_Part1Port, 0x2E, 0x80);	/* by alan,BVBDOENABLE=1 */
-
-			}
-			SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0x1F, 0x20);
-
-			if (HwDeviceExtension->jChipType >= SIS_315H) {	/* 310 series */
-				temp = SiS_GetReg1 (SiS_Part1Port, 0x2E);
-				if (!(temp & 0x80))
-					SiS_SetRegOR (SiS_Part1Port, 0x2E, 0x80);	/* by alan,BVBDOENABLE=1 */
-			}
-
-			SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0x1F, 0x20);
-			SiS_VBLongWait ();
-			SiS_DisplayOn ();
-			SiS_VBLongWait ();
-		}
-		/*add301b */
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-			if (!(SiS_Is301B (BaseAddr))) {
-				temp = SiS_GetReg1 (SiS_Part1Port, 0x2E);
-				if (!(temp & 0x80))
-					SiS_SetRegOR (SiS_Part1Port, 0x2E,
-						      0x80);
-				if ((!(SiS_IsDualEdge (BaseAddr)))
-				    && (!(SiS_IsVAMode (BaseAddr))))
-					tempah = 0x80;
-				else if ((!(SiS_IsDualEdge (BaseAddr)))
-					 && (SiS_IsVAMode (BaseAddr)))
-					tempah = 0x40;
-				else
-					tempah = 0xC0;
-				SiS_SetRegOR (SiS_Part4Port, 0x1F, tempah);
-			}
-		}
-		/*end 301b */
-	} else {
-		/*LVDS*/ SiS_EnableCRT2 ();
-		SiS_DisplayOn ();
-		SiS_UnLockCRT2 (HwDeviceExtension, BaseAddr);
-		SiS_SetRegANDOR (SiS_Part1Port, 0x02, 0xBF, 0x00);
-		if (SiS_BridgeInSlave ()) {
-			SiS_SetRegANDOR (SiS_Part1Port, 0x01, 0x1F, 0x00);
-		} else {
-			SiS_SetRegANDOR (SiS_Part1Port, 0x01, 0x1F, 0x40);
-		}
-		if (SiS_IF_DEF_CH7005) {
-			SiS_SetCH7005 (0x0B0E);
-		}
-	}
-/*SetPanelDelay(1);  */
-	SiS_SetRegANDOR (SiS_P3c4, 0x11, 0xF7, 0x00);
-}
-
-void
-SiS_SetPanelDelay (USHORT DelayTime)
-{
-	USHORT PanelID;
-
-	PanelID = SiS_GetReg1 (SiS_P3d4, 0x36);
-	PanelID = PanelID >> 4;
-
-	if (DelayTime == 0)
-		SiS_LCD_Wait_Time (SiS_PanelDelayTbl[PanelID].timer[0]);
-	else
-		SiS_LCD_Wait_Time (SiS_PanelDelayTbl[PanelID].timer[1]);
-}
-
-void
-SiS_LCD_Wait_Time (UCHAR DelayTime)
-{
-	USHORT i, j;
-	ULONG temp, flag;
-
-	flag = 0;
-	for (i = 0; i < DelayTime; i++) {
-		for (j = 0; j < 66; j++) {
-			temp = SiS_GetReg3 (0x61);
-			temp = temp & 0x10;
-			if (temp == flag)
-				continue;
-			flag = temp;
-		}
-	}
+*/
+     SiS_SetRegANDOR(SiS_P3c4,0x1E,0xDF,0x00);
+     SiS_SetReg1(SiS_Part1Port,0,temp);
+    }
+    else {
+    if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))  /*301b*/
+      {
+        if(!(SiS_Is301B(BaseAddr))) {
+          SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
+          if((!(SiS_IsDualEdge(BaseAddr)))&&(!(SiS_IsVAMode(BaseAddr))))
+            tempah=0x7F;
+          else if((!(SiS_IsDualEdge(BaseAddr)))&&(SiS_IsVAMode(BaseAddr)))
+            tempah=0xBF;
+          else
+            tempah=0x3F;
+          SiS_SetRegAND(SiS_Part4Port,0x1F,tempah);
+        }
+      }
+    }
+  }
+  else { /* LVDS */
+    if(SiS_IF_DEF_CH7005==1) {
+      SiS_Backup7005 = SiS_GetCH7005(0x0e);
+      SiS_SetCH7005(0x090E);
+    }
+    SiS_DisplayOff();
+    SiS_SetRegANDOR(SiS_P3c4,0x32,0xDF,0x00);
+    SiS_SetRegANDOR(SiS_P3c4,0x1E,0xDF,0x00);
+    SiS_UnLockCRT2(HwDeviceExtension,BaseAddr);
+    SiS_SetRegANDOR(SiS_Part1Port,0x01,0xFF,0x80);
+    SiS_SetRegANDOR(SiS_Part1Port,0x02,0xFF,0x40);
+  }
+  /*SetPanelDelay(0);  */
+  SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x04);
+}
+
+void
+SiS_EnableBridge(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT  BaseAddr)
+{
+  USHORT temp,tempah;
+
+  SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x00);
+
+  /*SetPanelDelay(0);        */
+  if(SiS_IF_DEF_LVDS==0) {
+    if( (!(SiS_IsVAMode(BaseAddr))) &&
+        (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))) {
+    		SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);
+    } else {
+      temp=SiS_GetReg1(SiS_P3c4,0x32);
+      temp=temp&0xDF;
+      if(SiS_BridgeInSlave()) {
+        tempah=SiS_GetReg1(SiS_P3d4,0x30);
+        if(!(tempah&SetCRT2ToRAMDAC)) {
+         temp=temp|0x20;
+        }
+      }
+      SiS_SetReg1(SiS_P3c4,0x32,temp);
+      SiS_SetRegANDOR(SiS_P3c4,0x1E,0xFF,0x20);
+
+      if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+        temp=SiS_GetReg1(SiS_Part1Port,0x2E);
+        if (!(temp&0x80))
+          SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);          /* by alan,BVBDOENABLE=1 */
+      }
+
+      SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);
+
+      if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+      	temp=SiS_GetReg1(SiS_Part1Port,0x2E);
+     	if (!(temp&0x80))
+            SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);          /* by alan,BVBDOENABLE=1 */
+      }
+   
+      SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);
+      SiS_VBLongWait();
+      SiS_DisplayOn();
+      SiS_VBLongWait();
+    }  
+  /*add301b*/
+    if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+      if(!(SiS_Is301B(BaseAddr))){  
+        temp=SiS_GetReg1(SiS_Part1Port,0x2E);
+        if(!(temp&0x80))
+           SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);
+        if((!(SiS_IsDualEdge(BaseAddr)))&&(!(SiS_IsVAMode(BaseAddr))))
+           tempah=0x80;
+        else if((!(SiS_IsDualEdge(BaseAddr)))&&(SiS_IsVAMode(BaseAddr)))
+           tempah=0x40;
+        else
+           tempah=0xC0;
+        SiS_SetRegOR(SiS_Part4Port,0x1F,tempah);
+      }
+     }  
+  /*end 301b*/
+  } else {                /*LVDS*/
+    SiS_EnableCRT2();
+    SiS_DisplayOn();
+    SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+    SiS_SetRegANDOR(SiS_Part1Port,0x02,0xBF,0x00);
+    if(SiS_BridgeInSlave()) {
+      	SiS_SetRegANDOR(SiS_Part1Port,0x01,0x1F,0x00);
+    } else {
+      	SiS_SetRegANDOR(SiS_Part1Port,0x01,0x1F,0x40);
+    }
+    if(SiS_IF_DEF_CH7005) {
+        if (SiS_Backup7005 != 0xff) {
+		SiS_SetCH7005(((SiS_Backup7005<<8)|0x0E));
+		SiS_Backup7005 = 0xff;
+	} else SiS_SetCH7005(0x0B0E);
+    }
+  }
+  /*SetPanelDelay(1);  */
+  SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x00);
+}
+
+void
+SiS_SetPanelDelay(USHORT DelayTime)
+{
+  USHORT PanelID;
+
+  PanelID=SiS_GetReg1(SiS_P3d4,0x36);
+  PanelID=PanelID>>4;
+
+  if(DelayTime==0) SiS_LCD_Wait_Time(SiS_PanelDelayTbl[PanelID].timer[0]);
+  else SiS_LCD_Wait_Time(SiS_PanelDelayTbl[PanelID].timer[1]);
+}
+
+void
+SiS_LCD_Wait_Time(UCHAR DelayTime)
+{
+  USHORT i,j;
+  ULONG  temp,flag;
+
+  flag=0;
+  for(i=0;i<DelayTime;i++) {
+    for(j=0;j<66;j++) {
+      temp=SiS_GetReg3(0x61);
+      temp=temp&0x10;
+      if(temp==flag) continue;
+      flag=temp;
+    }
+  }
 }
 
 /*301b*/
-
-BOOLEAN
-SiS_Is301B (USHORT BaseAddr)
-{
-	USHORT flag;
-	flag = SiS_GetReg1 (SiS_Part4Port, 0x01);
-	if (flag > (0x0B0))
-		return (0);	/*301b */
-	else
-		return (1);
-}
-
-BOOLEAN
-SiS_IsDualEdge (USHORT BaseAddr)
-{
-#ifdef CONFIG_FB_SIS_315
-	USHORT flag;
-	flag = SiS_GetReg1 (SiS_P3d4, 0x38);
-	if (flag & EnableDualEdge)
-		return (0);
-	else
-		return (1);
-#endif
-	return (1);
-}
-
-BOOLEAN
-SiS_IsVAMode (USHORT BaseAddr)
-{
-	USHORT flag;
-	flag = SiS_GetReg1 (SiS_P3d4, 0x38);
-#ifdef CONFIG_FB_SIS_315
-	if ((flag & EnableDualEdge) && (flag & SetToLCDA))
-		return (0);
-	else
-		return (1);
-#endif
-	return (1);
-}
-
-BOOLEAN
-SiS_IsDisableCRT2 (USHORT BaseAddr)
-{
-	USHORT flag;
-	flag = SiS_GetReg1 (SiS_P3d4, 0x30);
-	if (flag & 0x20)
-		return (0);	/*301b */
-	else
-		return (1);
-}
-
-/*end 301b*/
-
 BOOLEAN
-SiS_BridgeIsOn (USHORT BaseAddr)
+SiS_Is301B(USHORT BaseAddr)
 {
-	USHORT flag;
+  USHORT flag;
 
-	if (SiS_IF_DEF_LVDS == 1) {
-		return (1);
-	} else {
-		flag = SiS_GetReg1 (SiS_Part4Port, 0x00);
-		if ((flag == 1) || (flag == 2))
-			return (1);	/*301b */
-		else
-			return (0);
-	}
-}
-
-BOOLEAN
-SiS_BridgeIsEnable (USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT flag;
-
-	if (SiS_BridgeIsOn (BaseAddr) == 0) {
-		flag = SiS_GetReg1 (SiS_Part1Port, 0x0);
-		if (HwDeviceExtension->jChipType < SIS_315H) {	/* 300 series */
-			if (flag & 0x0a0) {
-				return 1;
-			} else {
-				return 0;
-			}
-		} else {	/* 310 series */
-
-			if (flag & 0x050) {
-				return 1;
-			} else {
-				return 0;
-			}
-
-		}
-	}
-	return 0;
-}
-
-BOOLEAN
-SiS_BridgeInSlave ()
-{
-	USHORT flag1;
-
-	flag1 = SiS_GetReg1 (SiS_P3d4, 0x31);
-	if (flag1 & (SetInSlaveMode >> 8)) {
-		return 1;
-	} else {
-		return 0;
-	}
-}
+    flag=SiS_GetReg1(SiS_Part4Port,0x01);
+    if(flag>(0x0B0)) return(0); /*301b*/
+    else return(1);
+ }
 
 BOOLEAN
-SiS_GetLCDResInfo301 (ULONG ROMAddr, USHORT SiS_P3d4, USHORT ModeNo,
-		      USHORT ModeIdIndex)
+SiS_IsDualEdge(USHORT BaseAddr)
 {
-	USHORT temp, modeflag, resinfo = 0;
-
-	SiS_LCDResInfo = 0;
-	SiS_LCDTypeInfo = 0;
-	SiS_LCDInfo = 0;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ModeFlag  */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;	/*si+Ext_ResInfo */
-	}
+#ifdef SIS315H
+    USHORT flag;
 
-	if (!(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
-		return 0;
-	}
-	if (!(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) {
-		return 0;
-	}
-	temp = SiS_GetReg1 (SiS_P3d4, 0x36);
-	SiS_LCDTypeInfo = temp >> 4;
-	SiS_LCDResInfo = temp & 0x0F;
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_LCDResInfo < Panel1024x768)
-			SiS_LCDResInfo = Panel1024x768;
-	} else {
-		if (SiS_LCDResInfo < Panel800x600)
-			SiS_LCDResInfo = Panel800x600;
-	}
-	if (SiS_LCDResInfo > Panel640x480)
-		SiS_LCDResInfo = Panel1024x768;
-
-	temp = SiS_GetReg1 (SiS_P3d4, 0x37);
-	SiS_LCDInfo = temp;
-
-	if (SiS_IF_DEF_LVDS == 1) {
-		if (modeflag & HalfDCLK) {
-			if (SiS_IF_DEF_TRUMPION == 0) {
-				if (!(SiS_LCDInfo & LCDNonExpanding)) {
-					if (ModeNo > 0x13) {
-						if (SiS_LCDResInfo ==
-						    Panel1024x768) {
-							if (resinfo == 4) {	/* 512x384  */
-								SiS_SetFlag =
-								    SiS_SetFlag
-								    |
-								    EnableLVDSDDA;
-							}
-						} else {
-							if (SiS_LCDResInfo ==
-							    Panel800x600) {
-								if (resinfo == 3) {	/*400x300  */
-									SiS_SetFlag
-									    =
-									    SiS_SetFlag
-									    |
-									    EnableLVDSDDA;
-								}
-							}
-						}
-					}
-				} else {
-					SiS_SetFlag =
-					    SiS_SetFlag | EnableLVDSDDA;
-				}
-			} else {
-				SiS_SetFlag = SiS_SetFlag | EnableLVDSDDA;
-			}
-		}
-	}
-
-	if (SiS_VBInfo & SetInSlaveMode) {
-		if (SiS_VBInfo & SetNotSimuMode) {
-			SiS_SetFlag = SiS_SetFlag | LCDVESATiming;
-		}
-	} else {
-		SiS_SetFlag = SiS_SetFlag | LCDVESATiming;
-	}
-	return 1;
-}
-
-void
-SiS_PresetScratchregister (USHORT SiS_P3d4,
-			   PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	/*SiS_SetReg1(SiS_P3d4,0x30,0x21);  */
-	/*SiS_SetReg1(SiS_P3d4,0x31,0x41);  */
-	/*SiS_SetReg1(SiS_P3d4,0x32,0x28);  */
-	/*SiS_SetReg1(SiS_P3d4,0x33,0x22);  */
-	/*SiS_SetReg1(SiS_P3d4,0x35,0x43);  */
-	/*SiS_SetReg1(SiS_P3d4,0x36,0x01);  */
-	/*SiS_SetReg1(SiS_P3d4,0x37,0x00);  */
-}
-
-void
-SiS_LongWait ()
-{
-	USHORT i;
-
-	i = SiS_GetReg1 (SiS_P3c4, 0x1F);
-	if (!(i & 0xC0)) {
-
-		for (i = 0; i < 0xFFFF; i++) {
-			if (!(SiS_GetReg2 (SiS_P3da) & 0x08))
-				break;
-		}
-		for (i = 0; i < 0xFFFF; i++) {
-			if ((SiS_GetReg2 (SiS_P3da) & 0x08))
-				break;
-		}
-	}
-}
-
-void
-SiS_VBLongWait ()
-{
-	USHORT tempal, temp, i, j;
-
-	if (!(SiS_VBInfo & SetCRT2ToTV)) {
-		temp = 0;
-		for (i = 0; i < 3; i++) {
-			for (j = 0; j < 100; j++) {
-				tempal = SiS_GetReg2 (SiS_P3da);
-				if (temp & 0x01) {	/* VBWaitMode2  */
-					if ((tempal & 0x08)) {
-						continue;
-					}
-					if (!(tempal & 0x08)) {
-						break;
-					}
-				} else {	/* VBWaitMode1  */
-					if (!(tempal & 0x08)) {
-						continue;
-					}
-					if ((tempal & 0x08)) {
-						break;
-					}
-				}
-			}
-			temp = temp ^ 0x01;
-		}
-	} else {
-		SiS_LongWait ();
-	}
-	return;
+     flag=SiS_GetReg1(SiS_P3d4,0x38);
+      if(flag&EnableDualEdge)
+        return (0);
+      else
+#endif
+      	return(1);
 }
 
 BOOLEAN
-SiS_WaitVBRetrace (USHORT BaseAddr)
-{
-	USHORT temp;
-
-	return 0;
-
-	temp = SiS_GetReg1 (SiS_Part1Port, 0x00);
-	if (!(temp & 0x80)) {
-		return 0;
-	}
-
-	for (temp = 0; temp == 0;) {
-		temp = SiS_GetReg1 (SiS_Part1Port, 0x25);
-		temp = temp & 0x01;
-	}
-	for (; temp > 0;) {
-		temp = SiS_GetReg1 (SiS_Part1Port, 0x25);
-		temp = temp & 0x01;
-	}
-	return 1;
-}
-
-void
-SiS_SetRegANDOR (USHORT Port, USHORT Index, USHORT DataAND, USHORT DataOR)
-{
-	USHORT temp;
-
-	temp = SiS_GetReg1 (Port, Index);	/* SiS_Part1Port index 02 */
-	temp = (temp & (DataAND)) | DataOR;
-	SiS_SetReg1 (Port, Index, temp);
-}
-
-void
-SiS_SetRegAND (USHORT Port, USHORT Index, USHORT DataAND)
-{
-	USHORT temp;
-
-	temp = SiS_GetReg1 (Port, Index);	/* SiS_Part1Port index 02 */
-	temp = temp & DataAND;
-	SiS_SetReg1 (Port, Index, temp);
-}
-
-void
-SiS_SetRegOR (USHORT Port, USHORT Index, USHORT DataOR)
-{
-	USHORT temp;
-
-	temp = SiS_GetReg1 (Port, Index);	/* SiS_Part1Port index 02 */
-	temp = temp | DataOR;
-	SiS_SetReg1 (Port, Index, temp);
-}
-
-void
-SiS_SetGroup2 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT i, j, tempax, tempbx, tempcx, temp, temp3;
-	USHORT push1, push2, temp1;
-	UCHAR *PhasePoint;
-	UCHAR *TimingPoint;
-	USHORT modeflag, resinfo, crt2crtc, resindex, xres;
-	ULONG longtemp, tempeax, tempebx, temp2, tempecx;
-	USHORT SiS_RY1COE = 0, SiS_RY2COE = 0, SiS_RY3COE = 0, SiS_RY4COE =
-	    0, SiS_RY5COE = 0, SiS_RY6COE = 0, SiS_RY7COE = 0;
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-		crt2crtc = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		crt2crtc = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-
-	tempcx = SiS_VBInfo;
-	tempax = (tempcx & 0x00FF) << 8;
-	tempbx = (tempcx & 0x00FF) | ((tempcx & 0x00FF) << 8);
-	tempbx = tempbx & 0x0410;
-	temp = (tempax & 0x0800) >> 8;
-	temp = temp >> 1;
-	temp = temp | (((tempbx & 0xFF00) >> 8) << 1);
-	temp = temp | ((tempbx & 0x00FF) >> 3);
-	temp = temp ^ 0x0C;
-
-	PhasePoint = SiS_PALPhase;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {	/* PALPhase */
-		temp = temp ^ 0x01;
-		if (SiS_VBInfo & SetInSlaveMode) {
-			TimingPoint = SiS_HiTVSt2Timing;
-			if (SiS_SetFlag & TVSimuMode) {
-				if (modeflag & Charx8Dot)
-					TimingPoint = SiS_HiTVSt1Timing;
-				else
-					TimingPoint = SiS_HiTVTextTiming;
-			}
-		} else
-			TimingPoint = SiS_HiTVExtTiming;
-	} else {
-		if (SiS_VBInfo & SetPALTV) {
-			if ((SiS_VBType & VB_SIS301B)
-			    || (SiS_VBType & VB_SIS302B)) PhasePoint = SiS_PALPhase2;	/* PALPhase */
-			else
-				PhasePoint = SiS_PALPhase;
-
-			TimingPoint = SiS_PALTiming;
-		} else {
-			temp = temp | 0x10;
-			if ((SiS_VBType & VB_SIS301B)
-			    || (SiS_VBType & VB_SIS302B)) PhasePoint = SiS_NTSCPhase2;	/* PALPhase */
-			else
-				PhasePoint = SiS_NTSCPhase;
-
-			TimingPoint = SiS_NTSCTiming;
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x0, temp);
-
-#ifdef CONFIG_FB_SIS_300
-	/*add PALMN */
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-			temp = temp & 0x01;
-			if (temp) {
-				temp1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-				temp1 = temp1 & 0x40;
-				if (temp1)
-					PhasePoint = SiS_PALMPhase;
-				temp1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-				temp1 = temp1 & 0x80;
-				if (temp1)
-					PhasePoint = SiS_PALNPhase;
-			}
-		}
-	}
-/*end add*/
-#endif
-#ifdef CONFIG_FB_SIS_315
-	/*add PALMN */
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp = temp & 0x01;
-		if (temp) {
-			temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-			temp1 = temp1 & 0x40;
-			if (temp1)
-				PhasePoint = SiS_PALMPhase;
-			temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-			temp1 = temp1 & 0x80;
-			if (temp1)
-				PhasePoint = SiS_PALNPhase;
-		}
-	}
-	/*end add */
-#endif
-	for (i = 0x31, j = 0; i <= 0x34; i++, j++) {
-		SiS_SetReg1 (SiS_Part2Port, i, PhasePoint[j]);
-	}
-	for (i = 0x01, j = 0; i <= 0x2D; i++, j++) {
-		SiS_SetReg1 (SiS_Part2Port, i, TimingPoint[j]);
-	}
-	for (i = 0x39; i <= 0x45; i++, j++) {
-		SiS_SetReg1 (SiS_Part2Port, i, TimingPoint[j]);	/* di->temp2[j] */
-	}
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		SiS_SetRegANDOR (SiS_Part2Port, 0x3A, 0x1F, 0x00);
-	}
-	temp = SiS_NewFlickerMode;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x0A, 0xFF, temp);
-
-	SiS_SetReg1 (SiS_Part2Port, 0x35, 0x00);	/*301b */
-	SiS_SetReg1 (SiS_Part2Port, 0x36, 0x00);
-	SiS_SetReg1 (SiS_Part2Port, 0x37, 0x00);
-	SiS_SetReg1 (SiS_Part2Port, 0x38, SiS_RY1COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x48, SiS_RY2COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x49, SiS_RY3COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x4a, SiS_RY4COE);
-/*add to change 630+301b filter*/
-
-	resindex = SiS_GetResInfo (ROMAddr, ModeNo, ModeIdIndex);
-	if (ModeNo <= 0x13) {
-		xres = SiS_StResInfo[resindex].HTotal;
-	} else {
-		xres = SiS_ModeResInfo[resindex].HTotal;	/* xres->ax */
-	}
-	if (xres == 640) {
-		SiS_RY1COE = 0xFF;
-		SiS_RY2COE = 0x03;
-		SiS_RY3COE = 0x02;
-		SiS_RY4COE = 0xF6;
-		SiS_RY5COE = 0xFC;
-		SiS_RY6COE = 0x27;
-		SiS_RY7COE = 0x46;
-	}
-	if (xres == 800) {
-		SiS_RY1COE = 0x01;
-		SiS_RY2COE = 0x01;
-		SiS_RY3COE = 0xFC;
-		SiS_RY4COE = 0xF8;
-		SiS_RY5COE = 0x08;
-		SiS_RY6COE = 0x26;
-		SiS_RY7COE = 0x38;
-	}
-	if (xres == 1024) {
-		SiS_RY1COE = 0xFF;
-		SiS_RY2COE = 0xFF;
-		SiS_RY3COE = 0xFC;
-		SiS_RY4COE = 0x00;
-		SiS_RY5COE = 0x0F;
-		SiS_RY6COE = 0x22;
-		SiS_RY7COE = 0x28;
-	}
-	if (xres == 720) {
-		SiS_RY1COE = 0x01;
-		SiS_RY2COE = 0x02;
-		SiS_RY3COE = 0xFE;
-		SiS_RY4COE = 0xF7;
-		SiS_RY5COE = 0x03;
-		SiS_RY6COE = 0x27;
-		SiS_RY7COE = 0x3c;
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x35, SiS_RY1COE);	/*301b */
-	SiS_SetReg1 (SiS_Part2Port, 0x36, SiS_RY2COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x37, SiS_RY3COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x38, SiS_RY4COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x48, SiS_RY5COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x49, SiS_RY6COE);
-	SiS_SetReg1 (SiS_Part2Port, 0x4a, SiS_RY7COE);
-
-/*end add*/
-
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV)
-		tempax = 950;
-	else {
-		if (SiS_VBInfo & SetPALTV)
-			tempax = 520;
-		else
-			tempax = 440;
-	}
-	if (SiS_VDE <= tempax) {
-		tempax = tempax - SiS_VDE;
-		tempax = tempax >> 2;
-		tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
-		push1 = tempax;
-		temp = (tempax & 0xFF00) >> 8;
-		temp = temp + (USHORT) TimingPoint[0];
-		SiS_SetReg1 (SiS_Part2Port, 0x01, temp);
-		tempax = push1;
-		temp = (tempax & 0xFF00) >> 8;
-		temp = temp + TimingPoint[1];
-		SiS_SetReg1 (SiS_Part2Port, 0x02, temp);
-	}
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToTV) && (SiS_VGAHDE == 1024)) {
-		if (SiS_VBInfo & SetPALTV) {
-			SiS_SetReg1 (SiS_Part2Port, 0x01, 0x19);
-			SiS_SetReg1 (SiS_Part2Port, 0x02, 0x52);
-		} else {
-			SiS_SetReg1 (SiS_Part2Port, 0x01, 0x0B);
-			SiS_SetReg1 (SiS_Part2Port, 0x02, 0x11);
-		}
-	}
-
-	tempcx = SiS_HT - 1;
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		tempcx = tempcx - 1;
-	}
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x1B, temp);
-	temp = (tempcx & 0xFF00) >> 8;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x1D, ~0x0F, temp);
-
-	tempcx = SiS_HT >> 1;
-	push1 = tempcx;		/* push cx */
-	tempcx = tempcx + 7;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempcx = tempcx - 4;
-	}
-	temp = (tempcx & 0x00FF);
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x22, 0x0F, temp);
-
-	tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
-	tempbx = tempbx + tempcx;
-	push2 = tempbx;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x24, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x25, 0x0F, temp);
-
-	tempbx = push2;
-	tempbx = tempbx + 8;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempbx = tempbx - 4;
-		tempcx = tempbx;
-	}
-	temp = (tempbx & 0x00FF) << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x29, 0x0F, temp);
-
-	j = j + 2;
-	tempcx = tempcx + (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x27, temp);
-	temp = ((tempcx & 0xFF00) >> 8) << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x28, 0x0F, temp);
-
-	tempcx = tempcx + 8;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempcx = tempcx - 4;
-	}
-	temp = tempcx & 0xFF;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x2A, 0x0F, temp);
-
-	tempcx = push1;		/* pop cx */
-	j = j + 2;
-	temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
-	tempcx = tempcx - temp;
-	temp = tempcx & 0x00FF;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x2D, 0x0F, temp);
-
-	tempcx = tempcx - 11;
-	if (!(SiS_VBInfo & SetCRT2ToTV)) {
-		tempax = SiS_GetVGAHT2 ();
-		tempcx = tempax - 1;
-	}
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x2E, temp);
-
-	tempbx = SiS_VDE;
-	if (SiS_VGAVDE == 360)
-		tempbx = 746;
-	if (SiS_VGAVDE == 375)
-		tempbx = 746;
-	if (SiS_VGAVDE == 405)
-		tempbx = 853;
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		tempbx = tempbx >> 1;
-	}
-	tempbx = tempbx - 2;
-	temp = tempbx & 0x00FF;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		if (SiS_VBInfo & SetInSlaveMode) {
-			if (ModeNo == 0x2f)
-				temp = temp + 1;
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x2F, temp);
-
-	temp = (tempcx & 0xFF00) >> 8;
-	temp = temp | (((tempbx & 0xFF00) >> 8) << 6);
-	if (!(SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-		temp = temp | 0x10;
-		if (!(SiS_VBInfo & SetCRT2ToSVIDEO)) {
-			temp = temp | 0x20;
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x30, temp);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {	/*tv gatingno */
-		tempbx = SiS_VDE;
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			tempbx = tempbx >> 1;
-		}
-		temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
-		SiS_SetReg1 (SiS_Part2Port, 0x46, temp);
-		temp = (tempbx - 3) & 0x00FF;
-		SiS_SetReg1 (SiS_Part2Port, 0x47, temp);
-	}
-/*end 301b*/
-
-	tempbx = tempbx & 0x00FF;
-	if (!(modeflag & HalfDCLK)) {
-		tempcx = SiS_VGAHDE;
-		if (tempcx >= SiS_HDE) {
-			tempbx = tempbx | 0x2000;
-			tempax = tempax & 0x00FF;
-		}
-	}
-	tempcx = 0x0101;
-
-	if (SiS_VBInfo & (SetCRT2ToHiVisionTV | SetCRT2ToTV)) {	/*301b */
-		if (SiS_VGAHDE >= 1024) {
-			tempcx = 0x1920;
-			if (SiS_VGAHDE >= 1280) {
-				tempcx = 0x1420;
-				tempbx = tempbx & 0xDFFF;
-			}
-		}
-	}
-	if (!(tempbx & 0x2000)) {
-		if (modeflag & HalfDCLK) {
-			tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
-		}
-		push1 = tempbx;
-		tempeax = SiS_VGAHDE;
-		tempebx = (tempcx & 0xFF00) >> 8;
-		longtemp = tempeax * tempebx;
-		tempecx = tempcx & 0x00FF;
-		longtemp = longtemp / tempecx;
-		/*301b */
-		tempecx = 8 * 1024;
-		if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-			tempecx = tempecx * 8;
-		}
-		longtemp = longtemp * tempecx;
-		tempecx = SiS_HDE;
-		temp2 = longtemp % tempecx;
-		tempeax = longtemp / tempecx;
-		if (temp2 != 0) {
-			tempeax = tempeax + 1;
-		}
-		tempax = (USHORT) tempeax;
-		/*301b */
-		if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-			tempcx = ((tempax & 0xFF00) >> 5) >> 8;
-		}
-		/*end 301b */
-		tempbx = push1;
-		tempbx =
-		    (USHORT) (((tempeax & 0x0000FF00) & 0x1F00) |
-			      (tempbx & 0x00FF));
-		tempax =
-		    (USHORT) (((tempeax & 0x000000FF) << 8) |
-			      (tempax & 0x00FF));
-		temp = (tempax & 0xFF00) >> 8;
-	} else {
-		temp = (tempax & 0x00FF) >> 8;
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x44, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x45, ~0x03F, temp);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		if ((tempcx & 0x00FF) == 0x01)
-			tempcx = 0x00;
-		SiS_SetRegANDOR (SiS_Part2Port, 0x46, ~0x007, tempcx);
-		SiS_SetRegOR (SiS_Part2Port, 0x46, 0x18);
-		if (SiS_VBInfo & SetPALTV) {
-			tempbx = 0x0364;
-			tempcx = 0x009c;
-		} else {
-			tempbx = 0x0346;
-			tempcx = 0x0078;
-		}
-		temp = (tempbx & 0x00FF);
-		SiS_SetReg1 (SiS_Part2Port, 0x4B, temp);
-		temp = (tempcx & 0x00FF);
-		SiS_SetReg1 (SiS_Part2Port, 0x4C, temp);
-		tempbx = (tempbx & 0x0300);
-		temp = (tempcx & 0xFF00) >> 8;
-		temp = (temp & 0x0003) << 2;
-		temp = temp | (tempbx >> 8);
-		SiS_SetReg1 (SiS_Part2Port, 0x4D, temp);
-		temp = SiS_GetReg1 (SiS_Part2Port, 0x43);
-		SiS_SetReg1 (SiS_Part2Port, 0x43, temp - 3);
-	}
-/*end 301b*/
-
-#ifdef CONFIG_FB_SIS_300
-/*add PALMN*/
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-			temp = temp & 0x01;
-			if (temp) {
-				temp1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-				temp1 = temp1 & 0x40;
-				if (temp1) {
-					SiS_SetRegANDOR (SiS_Part2Port, 0x00,
-							 0xEF, 0x00);
-					temp3 =
-					    SiS_GetReg1 (SiS_Part2Port, 0x01);
-					temp3 = temp3 - 1;
-					SiS_SetReg1 (SiS_Part2Port, 0x01,
-						     temp3);
-				}
-			}
-		}
-	}
-	/*end add */
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-/*add PALMN*/
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp = temp & 0x01;
-		if (temp) {
-			temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-			temp1 = temp1 & 0x40;
-			if (temp1) {
-				SiS_SetRegANDOR (SiS_Part2Port, 0x00, 0xEF,
-						 0x00);
-				temp3 = SiS_GetReg1 (SiS_Part2Port, 0x01);
-				temp3 = temp3 - 1;
-				SiS_SetReg1 (SiS_Part2Port, 0x01, temp3);
-			}
-		}
-	}
-	/*end add */
-#endif
-
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		if (!(SiS_VBInfo & SetInSlaveMode)) {
-			SiS_SetReg1 (SiS_Part2Port, 0x0B, 0x00);
-		}
-	}
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		return;
-	}
-
-	tempbx = SiS_HDE - 1;	/* RHACTE=HDE-1 */
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x2C, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x2B, 0x0F, temp);
-	temp = 0x01;
-	if (SiS_LCDResInfo == Panel1280x1024) {
-		if (SiS_ModeType == ModeEGA) {
-			if (SiS_VGAHDE >= 1024) {
-				temp = 0x02;
-				if (SiS_SetFlag & LCDVESATiming)
-					temp = 0x01;
-			}
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x0B, temp);
-
-	tempbx = SiS_VDE;	/* RTVACTEO=(VDE-1)&0xFF */
-	push1 = tempbx;
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part2Port, 0x03, temp);
-	temp = ((tempbx & 0xFF00) >> 8) & 0x07;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x0C, ~0x07, temp);
-
-	tempcx = SiS_VT - 1;
-	push2 = tempcx + 1;
-	temp = tempcx & 0x00FF;	/* RVTVT=VT-1 */
-	SiS_SetReg1 (SiS_Part2Port, 0x19, temp);
-	temp = (tempcx & 0xFF00) >> 8;
-	temp = temp << 5;
-	if (SiS_LCDInfo & LCDRGB18Bit) {
-		temp = temp | 0x10;
-	}
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		tempbx = (tempbx & 0xFF00) | (SiS_LCDInfo & 0x0FF);
-		if (tempbx & LCDSync) {
-			tempbx = tempbx & LCDSyncBit;
-			tempbx =
-			    (tempbx & 0xFF00) | ((tempbx & 0x00FF) >>
-						 LCDSyncShift);
-			temp = temp | (tempbx & 0x00FF);
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x1A, temp);
-
-	tempcx++;
-	tempbx = 768;
-	if (SiS_LCDResInfo != Panel1024x768) {
-		tempbx = 1024;
-		if (SiS_LCDResInfo != Panel1280x1024) {
-			tempbx = 1200;	/*301b */
-			if (SiS_LCDResInfo != Panel1600x1200) {
-				if (tempbx != SiS_VDE) {
-					tempbx = 960;
-				}
-			}
-		}
-	}
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		tempbx = SiS_VDE;
-		tempbx--;
-		tempcx--;
-	}
-	tempax = 1;
-	if (!(SiS_LCDInfo & LCDNonExpanding)) {
-		if (tempbx != SiS_VDE) {
-			tempax = tempbx;
-			if (tempax < SiS_VDE) {
-				tempax = 0;
-				tempcx = 0;
-			} else {
-				tempax = tempax - SiS_VDE;
-			}
-			tempax = tempax >> 1;
-		}
-		tempcx = tempcx - tempax;	/* lcdvdes */
-		tempbx = tempbx - tempax;	/* lcdvdee */
-	} else {
-		tempax = tempax >> 1;
-		tempcx = tempcx - tempax;	/* lcdvdes */
-		tempbx = tempbx - tempax;	/* lcdvdee */
-	}
-
-	temp = tempcx & 0x00FF;	/* RVEQ1EQ=lcdvdes */
-	SiS_SetReg1 (SiS_Part2Port, 0x05, temp);
-	temp = tempbx & 0x00FF;	/* RVEQ2EQ=lcdvdee */
-	SiS_SetReg1 (SiS_Part2Port, 0x06, temp);
-
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 3;
-	temp = temp | ((tempcx & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part2Port, 0x02, temp);
-
-	tempbx = push2;
-	tempax = push1;
-	tempcx = tempbx;
-	tempcx = tempcx - tempax;
-	tempcx = tempcx >> 4;
-	tempbx = tempbx + tempax;
-	tempbx = tempbx >> 1;
-	if (SiS_LCDInfo & LCDNonExpanding) {
-		tempbx = tempbx - 10;
-	}
-	temp = tempbx & 0x00FF;	/* RTVACTEE=lcdvrs */
-	SiS_SetReg1 (SiS_Part2Port, 0x04, temp);
-
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	tempbx = tempbx + tempcx + 1;
-	temp = temp | (tempbx & 0x000F);
-	SiS_SetReg1 (SiS_Part2Port, 0x01, temp);
-
-	if (SiS_LCDResInfo == Panel1024x768) {
-		if (!(SiS_SetFlag & LCDVESATiming)) {
-			if (!(SiS_LCDInfo & LCDNonExpanding)) {
-				if (ModeNo == 0x13) {
-					SiS_SetReg1 (SiS_Part2Port, 0x04, 0xB9);
-					SiS_SetReg1 (SiS_Part2Port, 0x05, 0xCC);
-					SiS_SetReg1 (SiS_Part2Port, 0x06, 0xA6);
-				} else {
-					temp = crt2crtc & 0x3F;
-					if (temp == 4) {
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x01, 0x2B);
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x02, 0x13);
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x04, 0xE5);
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x05, 0x08);
-						SiS_SetReg1 (SiS_Part2Port,
-							     0x06, 0xE2);
-					}
-				}
-			}
-		}
-	}
-
-	SiS_SetRegANDOR (SiS_Part2Port, 0x09, 0xF0, 0x00);
-	SiS_SetRegANDOR (SiS_Part2Port, 0x0A, 0xF0, 0x00);
+SiS_IsVAMode(USHORT BaseAddr)
+{
+  USHORT flag;
+         flag=SiS_GetReg1(SiS_P3d4,0x38);
+#ifdef SIS315H
+      if((flag&EnableDualEdge)&&(flag&SetToLCDA))
+        return (0);
+      else
+#endif
+      	return(1);
+ }
 
-	tempcx = (SiS_HT - SiS_HDE) >> 2;	/* (HT-HDE)>>2     */
-	tempbx = (SiS_HDE + 7);	/* lcdhdee         */
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		tempbx = tempbx + 2;
-	}
-	push1 = tempbx;
-	temp = tempbx & 0x00FF;	/* RHEQPLE=lcdhdee */
-	SiS_SetReg1 (SiS_Part2Port, 0x23, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x25, ~0x0F, temp);
-	/*301b */
-	temp = 7;
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		temp = temp + 2;
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x1F, temp);	/* RHBLKE=lcdhdes */
-	SiS_SetRegANDOR (SiS_Part2Port, 0x20, 0x0F, 0x00);
+BOOLEAN
+SiS_IsDisableCRT2(USHORT BaseAddr)
+{
+  USHORT flag;
 
-	tempbx = tempbx + tempcx;
-	push2 = tempbx;
-	temp = tempbx & 0xFF;	/* RHBURSTS=lcdhrs */
-	if (SiS_LCDResInfo == Panel1280x1024) {
-		if (!(SiS_LCDInfo & LCDNonExpanding)) {
-			if (SiS_HDE == 1280) {
-				temp = 0x47;
-			}
-		}
-	}
-	SiS_SetReg1 (SiS_Part2Port, 0x1C, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	SiS_SetRegANDOR (SiS_Part2Port, 0x1D, ~0x0F0, temp);
-
-	tempbx = push2;
-	tempcx = tempcx << 1;
-	tempbx = tempbx + tempcx;
-	temp = tempbx & 0x00FF;	/* RHSYEXP2S=lcdhre */
-	SiS_SetReg1 (SiS_Part2Port, 0x21, temp);
-
-	SiS_SetRegANDOR (SiS_Part2Port, 0x17, 0xFB, 0x00);
-	SiS_SetRegANDOR (SiS_Part2Port, 0x18, 0xDF, 0x00);
-
-	if (!(SiS_SetFlag & LCDVESATiming)) {
-		if (SiS_VGAVDE == 525) {
-			if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {	/*301b */
-				temp = 0xC6;
-			} else
-				temp = 0xC4;
-			SiS_SetReg1 (SiS_Part2Port, 0x2f, temp);
-			SiS_SetReg1 (SiS_Part2Port, 0x30, 0xB3);
-		}
-		if (SiS_VGAVDE == 420) {
-			if (
-			    ((SiS_VBType & VB_SIS301B)
-			     || (SiS_VBType & VB_SIS302B))) {
-				temp = 0x4F;
-			} else
-				temp = 0x4E;
-			SiS_SetReg1 (SiS_Part2Port, 0x2f, temp);
-		}
-	}
+  flag=SiS_GetReg1(SiS_P3d4,0x30);
+  if(flag&0x20) return(0); /*301b*/
+  else return(1);
 }
+/*end 301b*/
 
-USHORT
-SiS_GetVGAHT2 ()
+BOOLEAN
+SiS_BridgeIsOn(USHORT BaseAddr)
 {
-	ULONG tempax, tempbx;
+  USHORT flag;
 
-	tempbx = ((SiS_VGAVT - SiS_VGAVDE) * SiS_RVBHCMAX) & 0xFFFF;
-	tempax = (SiS_VT - SiS_VDE) * SiS_RVBHCFACT;
-	tempax = (tempax * SiS_HT) / tempbx;
-	return ((USHORT) tempax);
+  if(SiS_IF_DEF_LVDS==1){
+    return(1);
+  }
+  else {
+    flag=SiS_GetReg1(SiS_Part4Port,0x00);
+      if((flag==1)||(flag==2)) return(1); /*301b*/
+    else return(0);
+  }
 }
 
-void
-SiS_SetGroup3 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT i;
-	UCHAR *tempdi;
-	USHORT modeflag, temp, temp1;
 
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
+BOOLEAN
+SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT flag;
 
-	SiS_SetReg1 (SiS_Part3Port, 0x00, 0x00);
-	if (SiS_VBInfo & SetPALTV) {
-		SiS_SetReg1 (SiS_Part3Port, 0x13, 0xFA);
-		SiS_SetReg1 (SiS_Part3Port, 0x14, 0xC8);
-	} else {
-		SiS_SetReg1 (SiS_Part3Port, 0x13, 0xF6);
-		SiS_SetReg1 (SiS_Part3Port, 0x14, 0xBF);
-	}
-#ifdef CONFIG_FB_SIS_300
-	/*add PALMN */
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-			temp = temp & 0x01;
-			if (temp) {
-				temp1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-				temp1 = temp1 & 0x40;
-				if (temp1) {
-					SiS_SetReg1 (SiS_Part3Port, 0x13, 0xFA);
-					SiS_SetReg1 (SiS_Part3Port, 0x14, 0xC8);
-					SiS_SetReg1 (SiS_Part3Port, 0x3D, 0xA8);
-				}
-			}
-		}
-	}
-	/*end add */
-#endif
-#ifdef CONFIG_FB_SIS_315
-/*add PALMN*/
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		temp = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp = temp & 0x01;
-		if (temp) {
-			temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-			temp1 = temp1 & 0x40;
-			if (temp1) {
-				SiS_SetReg1 (SiS_Part3Port, 0x13, 0xFA);
-				SiS_SetReg1 (SiS_Part3Port, 0x14, 0xC8);
-				SiS_SetReg1 (SiS_Part3Port, 0x3D, 0xA8);
-			}
-		}
-	}
-	/*end add */
-#endif
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		tempdi = SiS_HiTVGroup3Data;
-		if (SiS_SetFlag & TVSimuMode) {
-			tempdi = SiS_HiTVGroup3Simu;
-			if (!(modeflag & Charx8Dot)) {
-				tempdi = SiS_HiTVGroup3Text;
-			}
-		}
-		for (i = 0; i <= 0x3E; i++) {
-			SiS_SetReg1 (SiS_Part3Port, i, tempdi[i]);
-		}
-	}
-	return;
+  if(SiS_BridgeIsOn(BaseAddr)==0) 
+  {
+    flag=SiS_GetReg1(SiS_Part1Port,0x0);
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+      /* 300 series */
+      if(flag&0x0a0) return 1;
+      else	     return 0;
+    } else {
+      /* 310 series */
+      if(flag&0x050) return 1;
+      else           return 0;
+    }
+  }
+  return 0;
 }
 
-void
-SiS_SetGroup4 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
+BOOLEAN
+SiS_BridgeInSlave()
 {
-	USHORT tempax, tempcx, tempbx, modeflag, temp, temp2, push1;
-	ULONG tempebx, tempeax, templong;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
-	temp = SiS_RVBHCFACT;
-	SiS_SetReg1 (SiS_Part4Port, 0x13, temp);
+  USHORT flag1;
 
-	tempbx = SiS_RVBHCMAX;
-	temp = tempbx & 0x00FF;
-	SiS_SetReg1 (SiS_Part4Port, 0x14, temp);
-	temp2 = ((tempbx & 0xFF00) >> 8) << 7;
-
-	tempcx = SiS_VGAHT - 1;
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part4Port, 0x16, temp);
-	temp = ((tempcx & 0xFF00) >> 8) << 3;
-	temp2 = temp | temp2;
-
-	tempcx = SiS_VGAVT - 1;
-	if (!(SiS_VBInfo & SetCRT2ToTV)) {
-		tempcx = tempcx - 5;
-	}
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part4Port, 0x17, temp);
-	temp = temp2 | ((tempcx & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part4Port, 0x15, temp);
-
-	tempcx = SiS_VBInfo;
-	tempbx = SiS_VGAHDE;
-	if (modeflag & HalfDCLK) {
-		tempbx = tempbx >> 1;
-	}
-	if (tempcx & SetCRT2ToHiVisionTV) {
-		temp = 0xA0;
-		if (tempbx != 1024) {
-			temp = 0xC0;
-			if (tempbx != 1280)
-				temp = 0;
-		}
-	} else if ((tempcx & SetCRT2ToTV) && (SiS_VGAHDE == 1024)) {	/*301b */
-		temp = 0xA0;
-	} else {
-		temp = 0x80;
-		if (SiS_VBInfo & SetCRT2ToLCD) {
-			temp = 0;
-			if (tempbx > 800)
-				temp = 0x60;
-		}
-	}
-	if (SiS_LCDResInfo != Panel1280x1024)
-		temp = temp | 0x0A;
-	SiS_SetRegANDOR (SiS_Part4Port, 0x0E, ~0xEF, temp);
-
-	tempebx = SiS_VDE;
-	if (tempcx & SetCRT2ToHiVisionTV) {
-		/* if(!(tempax&0xE000)) tempbx=tempbx>>1; */
-		if (!(temp & 0xE000))
-			tempbx = tempbx >> 1;	/* alan ???? */
+  flag1=SiS_GetReg1(SiS_P3d4,0x31);
+  if(flag1&(SetInSlaveMode>>8)) return 1;
+  else  return 0;
+}
 
-	}
+BOOLEAN
+SiS_GetLCDResInfo301(ULONG ROMAddr,USHORT SiS_P3d4,
+                     USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT temp,modeflag,resinfo=0;
 
-	tempcx = SiS_RVBHRS;
-	temp = tempcx & 0x00FF;
-	SiS_SetReg1 (SiS_Part4Port, 0x18, temp);
-
-	tempebx = tempebx;
-	tempeax = SiS_VGAVDE;
-	tempcx = tempcx | 0x04000;
-/*tempeax=tempeax-tempebx;  */
-	if (tempeax <= tempebx) {
-		tempcx = ((tempcx & 0xFF00) ^ 0x4000) | (tempcx & 0x00ff);
-		tempeax = SiS_VGAVDE;
-	}
+  SiS_LCDResInfo=0;
+  SiS_LCDTypeInfo=0;
+  SiS_LCDInfo=0;
+
+  if (ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;  	/* si+St_ModeFlag  */
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 	/*si+Ext_ResInfo*/
+  }
+
+  if(!(SiS_VBInfo&(SetCRT2ToLCD|SetCRT2ToLCDA))){
+    	return 0;
+  }
+  if(!(SiS_VBInfo&(SetSimuScanMode|SwitchToCRT2))) {
+    	return 0;
+  }
+  temp=SiS_GetReg1(SiS_P3d4,0x36);
+  /*fstn*/
+  if(SiS_IF_DEF_FSTN){
+   	temp=0x27;
+   	SiS_SetReg1(SiS_P3d4,0x36,temp);
+  } 
+  SiS_LCDTypeInfo=temp>>4;
+  SiS_LCDResInfo=temp&0x0F;
+  if(SiS_IF_DEF_LVDS==0) {
+    	if(SiS_LCDResInfo<Panel1024x768) SiS_LCDResInfo=Panel1024x768;
+  } else {
+    	if(SiS_LCDResInfo<Panel800x600) SiS_LCDResInfo=Panel800x600;
+  }
+#if 0
+  /* TW: No 1600x1200 panels? Don't think so... */
+  if(SiS_LCDResInfo>Panel640x480) SiS_LCDResInfo=Panel1024x768;
+#endif
+  if(SiS_LCDResInfo>Panel1600x1200) SiS_LCDResInfo=Panel1024x768;
+  /*fstn*/
+  if(SiS_IF_DEF_FSTN){
+       	SiS_LCDResInfo=Panel320x480;
+  }
+  temp=SiS_GetReg1(SiS_P3d4,0x37);
+  if(SiS_IF_DEF_FSTN){
+      	temp=0x04;
+      	SiS_SetReg1(SiS_P3d4,0x37,temp);
+  }
+  SiS_LCDInfo=temp;
+
+#ifdef LINUX_KERNEL
+  printk(KERN_INFO "sisfb: (LCDInfo = 0x%x LCDResInfo = 0x%x LCDTypeInfo = 0x%x)\n",
+                   SiS_LCDInfo, SiS_LCDResInfo, SiS_LCDTypeInfo);
+#endif
+#ifdef LINUX_XF86
+  xf86DrvMsg(0, X_INFO, "(init301.c: LCDInfo = 0x%x LCDResInfo = 0x%x LCDTypeInfo = 0x%x)\n",
+			SiS_LCDInfo, SiS_LCDResInfo, SiS_LCDTypeInfo);
+#endif
 
-	else {
-		tempeax = tempeax - tempebx;
-	}
+  if(SiS_IF_DEF_LVDS==1){
+     if(modeflag&HalfDCLK){
+        if(SiS_IF_DEF_TRUMPION==0){
+            if(!(SiS_LCDInfo&LCDNonExpanding)){
+               if(ModeNo>0x13) {
+                  if(SiS_LCDResInfo==Panel1024x768){
+                      if(resinfo==4){                                /* 512x384  */
+                           SiS_SetFlag=SiS_SetFlag|EnableLVDSDDA;
+                      }
+                  } else {
+                      if(SiS_LCDResInfo==Panel800x600){
+                           if(resinfo==3){                             /*400x300  */
+                                SiS_SetFlag=SiS_SetFlag|EnableLVDSDDA;
+                           }
+                      }
+                  }
+               }
+           } else { /* NonExpanding */
+              SiS_SetFlag=SiS_SetFlag|EnableLVDSDDA;
+           }
+        } else { /* TRUMPION */
+          SiS_SetFlag=SiS_SetFlag|EnableLVDSDDA;
+        }
+     }
+  }
 
-	push1 = tempcx;
-	templong = (tempeax * 256 * 1024) % tempebx;
-	tempeax = (tempeax * 256 * 1024) / tempebx;
-	tempebx = tempeax;
-	if (templong != 0) {
-		tempebx++;
-	}
-	tempcx = push1;
-	temp = (USHORT) (tempebx & 0x000000FF);
-	SiS_SetReg1 (SiS_Part4Port, 0x1B, temp);
-	temp = (USHORT) ((tempebx & 0x0000FF00) >> 8);
-	SiS_SetReg1 (SiS_Part4Port, 0x1A, temp);
-	tempbx = (USHORT) (tempebx >> 16);
-	temp = tempbx & 0x00FF;
-	temp = temp << 4;
-	temp = temp | ((tempcx & 0xFF00) >> 8);
-	SiS_SetReg1 (SiS_Part4Port, 0x19, temp);
-	/*301b */
-
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		temp = 0x0028;
-		SiS_SetReg1 (SiS_Part4Port, 0x1C, temp);
-		tempax = SiS_VGAHDE;
-		if (modeflag & HalfDCLK) {
-			tempax = tempax >> 1;
-		}
-		if (SiS_VBInfo & (SetCRT2ToLCD)) {
-			if (tempax > 800)
-				tempax = tempax - 800;
-		}
-		tempax = tempax - 1;
-
-		if (SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
-			if (SiS_VGAHDE > 800) {
-				if (SiS_VGAHDE == 1024)
-					tempax = (tempax * 25 / 32) - 1;
-				else
-					tempax = (tempax * 20 / 32) - 1;
-			}
-		}
-		temp = (tempax & 0xFF00) >> 8;
-		temp = ((temp & 0x0003) << 4);
-		SiS_SetReg1 (SiS_Part4Port, 0x1E, temp);
-		temp = (tempax & 0x00FF);
-		SiS_SetReg1 (SiS_Part4Port, 0x1D, temp);
-
-		if (SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
-			if (SiS_VGAHDE > 800) {
-				SiS_SetRegOR (SiS_Part4Port, 0x1E, 0x08);
-			}
-		}
-		temp = 0x0036;
-		if (SiS_VBInfo & SetCRT2ToTV) {
-			temp = temp | 0x0001;
-		}
-		SiS_SetRegANDOR (SiS_Part4Port, 0x1F, 0x00C0, temp);
-		tempbx = (SiS_HT / 2) - 2;
-		temp = ((tempbx & 0x0700) >> 8) << 3;
-		SiS_SetRegANDOR (SiS_Part4Port, 0x21, 0x00C0, temp);
-		temp = tempbx & 0x00FF;
-		SiS_SetReg1 (SiS_Part4Port, 0x22, temp);
-	}
-/*end 301b*/
-	SiS_SetCRT2VCLK (BaseAddr, ROMAddr, ModeNo, ModeIdIndex,
-			 RefreshRateTableIndex, HwDeviceExtension);
+  if(SiS_VBInfo&SetInSlaveMode){
+    	if(SiS_VBInfo&SetNotSimuMode){
+      		SiS_SetFlag=SiS_SetFlag|LCDVESATiming;
+    	}
+  } else {
+    	SiS_SetFlag=SiS_SetFlag|LCDVESATiming;
+  }
+  return 1;
+}
+
+void
+SiS_PresetScratchregister(USHORT SiS_P3d4,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  /*SiS_SetReg1(SiS_P3d4,0x30,0x21);  */
+  /*SiS_SetReg1(SiS_P3d4,0x31,0x41);  */
+  /*SiS_SetReg1(SiS_P3d4,0x32,0x28);  */
+  /*SiS_SetReg1(SiS_P3d4,0x33,0x22);  */
+  /*SiS_SetReg1(SiS_P3d4,0x35,0x43);  */
+  /*SiS_SetReg1(SiS_P3d4,0x36,0x01);  */
+  /*SiS_SetReg1(SiS_P3d4,0x37,0x00);  */
+}
+
+void
+SiS_LongWait()
+{
+  USHORT i;
+
+  i=SiS_GetReg1(SiS_P3c4,0x1F);
+  if(!(i&0xC0)) {
+
+    for(i=0; i<0xFFFF; i++) {
+       if(!(SiS_GetReg2(SiS_P3da) & 0x08))
+         break;
+    }
+    for(i=0; i<0xFFFF; i++) {
+       if((SiS_GetReg2(SiS_P3da) & 0x08))
+         break;
+    }
+  }
+}
+
+void
+SiS_VBLongWait()
+{
+  USHORT tempal,temp,i,j;
+
+  if(!(SiS_VBInfo&SetCRT2ToTV)) {
+    temp=0;
+    for(i=0;i<3;i++) {
+      for(j=0;j<100;j++) {
+        tempal=SiS_GetReg2(SiS_P3da);
+        if(temp&0x01) {        /* VBWaitMode2  */
+          if((tempal&0x08)) {
+            continue;
+          }
+          if(!(tempal&0x08)) {
+            break;
+          }
+        } else {                 /* VBWaitMode1  */
+          if(!(tempal&0x08)) {
+            continue;
+          }
+          if((tempal&0x08)) {
+            break;
+          }
+        }
+      }
+      temp=temp^0x01;
+    }
+  } else {
+    SiS_LongWait();
+  }
+  return;
 }
 
-void
-SiS_SetCRT2VCLK (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		 USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT vclkindex;
-	USHORT tempah, temp1;
-
-	vclkindex =
-	    SiS_GetVCLK2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-			     RefreshRateTableIndex, HwDeviceExtension);
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))) {
-		tempah = SiS_VBVCLKData[vclkindex].Part4_A;
-		SiS_SetReg1 (SiS_Part4Port, 0x0A, tempah);
-		tempah = SiS_VBVCLKData[vclkindex].Part4_B;
-		SiS_SetReg1 (SiS_Part4Port, 0x0B, tempah);
-	} else {
-		SiS_SetReg1 (SiS_Part4Port, 0x0A, 0x01);
-		tempah = SiS_VBVCLKData[vclkindex].Part4_B;
-		SiS_SetReg1 (SiS_Part4Port, 0x0B, tempah);
-		tempah = SiS_VBVCLKData[vclkindex].Part4_A;
-		SiS_SetReg1 (SiS_Part4Port, 0x0A, tempah);
+BOOLEAN
+SiS_WaitVBRetrace(USHORT  BaseAddr)
+{
+  USHORT temp;
 
-	}
-	SiS_SetReg1 (SiS_Part4Port, 0x12, 0x00);
-	tempah = 0x08;
-	if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-		tempah = tempah | 0x020;
-	}
-	temp1 = SiS_GetReg1 (SiS_Part4Port, 0x12);
-	tempah = tempah | temp1;
-	SiS_SetReg1 (SiS_Part4Port, 0x12, tempah);
-}
+return 0;
 
-USHORT
-SiS_GetVCLK2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT tempbx;
-#ifdef CONFIG_FB_SIS_300
-	USHORT LCDXlat1VCLK[4] = { VCLK65, VCLK65, VCLK65, VCLK65 };
-	USHORT LCDXlat2VCLK[4] = { VCLK108_2, VCLK108_2, VCLK108_2, VCLK108_2 };
-	USHORT LVDSXlat2VCLK[4] = { VCLK65, VCLK65, VCLK65, VCLK65 };
-	USHORT LVDSXlat3VCLK[4] = { VCLK65, VCLK65, VCLK65, VCLK65 };
-#else				/* SIS315H */
-	USHORT LCDXlat1VCLK[4] =
-	    { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, VCLK65 + 2 };
-	USHORT LCDXlat2VCLK[4] =
-	    { VCLK108_2 + 5, VCLK108_2 + 5, VCLK108_2 + 5, VCLK108_2 + 5 };
-	USHORT LVDSXlat2VCLK[4] =
-	    { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, VCLK65 + 2 };
-	USHORT LVDSXlat3VCLK[4] =
-	    { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, VCLK65 + 2 };
-#endif
-	USHORT LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
-	USHORT CRT2Index, VCLKIndex;
-	USHORT modeflag, resinfo;
-	UCHAR *CHTVVCLKPtr = NULL;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-		CRT2Index = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT2Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
+  temp=SiS_GetReg1(SiS_Part1Port,0x00); /* FUNCTION CTRL */
+  if(!(temp&0x80)){
+    return 0;
+  }
 
-	if (SiS_IF_DEF_LVDS == 0) {
-		CRT2Index = CRT2Index >> 6;	/*  for LCD */
-		if ((SiS_VBInfo & SetCRT2ToLCD) || (SiS_VBInfo & SetCRT2ToLCDA)) {	/*301b */
-			if (SiS_LCDResInfo != Panel1024x768) {
-				VCLKIndex = LCDXlat2VCLK[CRT2Index];
-			} else {
-				VCLKIndex = LCDXlat1VCLK[CRT2Index];
-			}
-		} else {	/* for TV */
-			if (SiS_VBInfo & SetCRT2ToTV) {
-				if (SiS_IF_DEF_HiVision == 1) {
-					if (SiS_SetFlag & RPLLDIV2XO) {
-						VCLKIndex = HiTVVCLKDIV2;
-						if (HwDeviceExtension->
-						    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-							VCLKIndex += 25;	/* for chip315  */
-						}
-					} else {
-						VCLKIndex = HiTVVCLK;
-						if (HwDeviceExtension->
-						    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-							VCLKIndex += 25;	/* for chip315  */
-						}
-					}
-					if (SiS_SetFlag & TVSimuMode) {
-						if (modeflag & Charx8Dot) {
-							VCLKIndex =
-							    HiTVSimuVCLK;
-							if (HwDeviceExtension->
-							    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-								VCLKIndex += 25;	/* for chip315  */
-							}
-						} else {
-							VCLKIndex =
-							    HiTVTextVCLK;
-							if (HwDeviceExtension->
-							    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-								VCLKIndex += 25;	/* for chip315  */
-							}
-						}
-					}
-				} else {
-					if (SiS_VBInfo & SetCRT2ToTV) {
-						if (SiS_SetFlag & RPLLDIV2XO) {
-							VCLKIndex = TVVCLKDIV2;
-							if (HwDeviceExtension->
-							    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-								VCLKIndex += 25;	/* for chip315  */
-							}
-						} else {
-							VCLKIndex = TVVCLK;
-							if (HwDeviceExtension->
-							    jChipType >= SIS_315H) {	/* 310 series */
-/*            VCLKIndex += 11;    for chip310  0x2E */
-								VCLKIndex += 25;	/* for chip315  */
-							}
-						}
-					}
-				}
-			} else {	/* for CRT2 */
-				VCLKIndex =
-				    (UCHAR) SiS_GetReg2 ((USHORT) (SiS_P3ca + 0x02));	/*  Port 3cch */
-				VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-				if (ModeNo > 0x13) {
-					VCLKIndex =
-					    SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;	/* di+Ext_CRTVCLK */
-					VCLKIndex = VCLKIndex & 0x3f;
-				}
-			}
-		}
-	} else {		/*   LVDS  */
-		if (ModeNo <= 0x13)
-			VCLKIndex = CRT2Index;
-		else
-			VCLKIndex = CRT2Index;
-		if (SiS_IF_DEF_CH7005 == 1) {
-			if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-				VCLKIndex = VCLKIndex & 0x1f;
-				tempbx = 0;
-				if (SiS_VBInfo & SetPALTV)
-					tempbx = tempbx + 2;
-				if (SiS_VBInfo & SetCHTVOverScan)
-					tempbx = tempbx + 1;
-				switch (tempbx) {
-				case 0:
-					CHTVVCLKPtr = SiS_CHTVVCLKUNTSC;
-					break;
-				case 1:
-					CHTVVCLKPtr = SiS_CHTVVCLKONTSC;
-					break;
-				case 2:
-					CHTVVCLKPtr = SiS_CHTVVCLKUPAL;
-					break;
-				case 3:
-					CHTVVCLKPtr = SiS_CHTVVCLKOPAL;
-					break;
-				}
-				VCLKIndex = CHTVVCLKPtr[VCLKIndex];
-			}
-		} else {
-			VCLKIndex = VCLKIndex >> 6;
-			if (SiS_LCDResInfo == Panel800x600)
-				VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-			else if (SiS_LCDResInfo == Panel1024x768)
-				VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
-			else
-				VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
-		}
-	}
-/*VCLKIndex=VCLKIndex&0x3F;   */
-	if (HwDeviceExtension->jChipType < SIS_315H) {	/* for300 serial */
-		VCLKIndex = VCLKIndex & 0x3F;
-	}
-	return (VCLKIndex);
+  for(temp=0;temp==0;){
+     temp=SiS_GetReg1(SiS_Part1Port,0x25);
+     temp=temp&0x01;
+  }
+  for(;temp>0;){
+     temp=SiS_GetReg1(SiS_Part1Port,0x25);
+     temp=temp&0x01;
+  }
+  return 1;
 }
 
 void
-SiS_SetGroup5 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-	       USHORT ModeIdIndex)
+SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR)
 {
-	USHORT Pindex, Pdata;
+  USHORT temp;
 
-	Pindex = SiS_Part5Port;
-	Pdata = SiS_Part5Port + 1;
-	if (SiS_ModeType == ModeVGA) {
-		if (!
-		    (SiS_VBInfo &
-		     (SetInSlaveMode | LoadDACFlag | CRT2DisplayFlag))) {
-			SiS_EnableCRT2 ();
-/*    LoadDAC2(ROMAddr,SiS_Part5Port,ModeNo,ModeIdIndex);  */
-		}
-	}
-	return;
+  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
+  temp=(temp&(DataAND))|DataOR;
+  SiS_SetReg1(Port,Index,temp);
 }
 
 void
-SiS_LoadDAC2 (ULONG ROMAddr, USHORT SiS_Part5Port, USHORT ModeNo,
-	      USHORT ModeIdIndex)
+SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND)
 {
-	USHORT data, data2;
-	USHORT time, i, j, k;
-	USHORT m, n, o;
-	USHORT si, di, bx, dl;
-	USHORT al, ah, dh;
-	USHORT *table = 0;
-	USHORT Pindex, Pdata, modeflag;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
-
-	Pindex = SiS_Part5Port;
-	Pdata = SiS_Part5Port + 1;
-	data = modeflag & DACInfoFlag;
-	time = 64;
-	if (data == 0x00)
-		table = SiS_MDA_DAC;
-	if (data == 0x08)
-		table = SiS_CGA_DAC;
-	if (data == 0x10)
-		table = SiS_EGA_DAC;
-	if (data == 0x18) {
-		time = 256;
-		table = SiS_VGA_DAC;
-	}
-	if (time == 256)
-		j = 16;
-	else
-		j = time;
-
-	SiS_SetReg3 (Pindex, 0x00);
-
-	for (i = 0; i < j; i++) {
-		data = table[i];
-		for (k = 0; k < 3; k++) {
-			data2 = 0;
-			if (data & 0x01)
-				data2 = 0x2A;
-			if (data & 0x02)
-				data2 = data2 + 0x15;
-			SiS_SetReg3 (Pdata, data2);
-			data = data >> 2;
-		}
-	}
+  USHORT temp;
 
-	if (time == 256) {
-		for (i = 16; i < 32; i++) {
-			data = table[i];
-			for (k = 0; k < 3; k++)
-				SiS_SetReg3 (Pdata, data);
-		}
-		si = 32;
-		for (m = 0; m < 9; m++) {
-			di = si;
-			bx = si + 0x04;
-			dl = 0;
-			for (n = 0; n < 3; n++) {
-				for (o = 0; o < 5; o++) {
-					dh = table[si];
-					ah = table[di];
-					al = table[bx];
-					si++;
-					SiS_WriteDAC2 (Pdata, dl, ah, al, dh);
-				}	/* for 5 */
-				si = si - 2;
-				for (o = 0; o < 3; o++) {
-					dh = table[bx];
-					ah = table[di];
-					al = table[si];
-					si--;
-					SiS_WriteDAC2 (Pdata, dl, ah, al, dh);
-				}	/* for 3 */
-				dl++;
-			}	/* for 3 */
-			si = si + 5;
-		}		/* for 9 */
-	}
+  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
+  temp=temp&DataAND;
+  SiS_SetReg1(Port,Index,temp);
 }
 
-void
-SiS_WriteDAC2 (USHORT Pdata, USHORT dl, USHORT ah, USHORT al, USHORT dh)
+void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR)
 {
-	USHORT temp;
-	USHORT bh, bl;
+  USHORT temp;
 
-	bh = ah;
-	bl = al;
-	if (dl != 0) {
-		temp = bh;
-		bh = dh;
-		dh = temp;
-		if (dl == 1) {
-			temp = bl;
-			bl = dh;
-			dh = temp;
-		} else {
-			temp = bl;
-			bl = bh;
-			bh = temp;
-		}
-	}
-	SiS_SetReg3 (Pdata, (USHORT) dh);
-	SiS_SetReg3 (Pdata, (USHORT) bh);
-	SiS_SetReg3 (Pdata, (USHORT) bl);
+  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
+  temp=temp|DataOR;
+  SiS_SetReg1(Port,Index,temp);
 }
 
 void
-SiS_SetCHTVReg (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		USHORT RefreshRateTableIndex)
+SiS_SetGroup2(USHORT BaseAddr,ULONG ROMAddr, USHORT ModeNo,
+                   USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT temp, tempbx, tempcl;
-/*  USHORT CRT2CRTC; */
-	USHORT TVType, resindex;
-	SiS_CHTVRegDataStruct *CHTVRegData = NULL;
+  USHORT i,j,tempax,tempbx,tempcx,temp,temp3;
+  USHORT push1,push2,temp1;
+  UCHAR *PhasePoint;
+  UCHAR *TimingPoint;
+  USHORT  modeflag,resinfo,crt2crtc,resindex,xres;
+  ULONG longtemp,tempeax,tempebx,temp2,tempecx;
+  USHORT  SiS_RY1COE=0,SiS_RY2COE=0,SiS_RY3COE=0,SiS_RY4COE=0;
+  USHORT  SiS_RY5COE=0,SiS_RY6COE=0,SiS_RY7COE=0;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+    	crt2crtc = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	crt2crtc = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+
+  tempcx=SiS_VBInfo;
+  tempax=(tempcx&0x00FF)<<8;
+  tempbx=(tempcx&0x00FF)|((tempcx&0x00FF)<<8);
+  tempbx=tempbx&0x0410;
+  temp=(tempax&0x0800)>>8;
+  temp=temp>>1;
+  temp=temp|(((tempbx&0xFF00)>>8)<<1);
+  temp=temp|((tempbx&0x00FF)>>3);
+  temp=temp^0x0C;
+
+  PhasePoint = SiS_PALPhase;
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {        /* PALPhase */
+    temp=temp^0x01;
+    if(SiS_VBInfo&SetInSlaveMode) {
+      TimingPoint = SiS_HiTVSt2Timing;
+      if(SiS_SetFlag&TVSimuMode) {
+        if(modeflag&Charx8Dot) TimingPoint = SiS_HiTVSt1Timing;
+        else TimingPoint = SiS_HiTVTextTiming;
+      }
+    } else TimingPoint = SiS_HiTVExtTiming;
+  } else {
+    if(SiS_VBInfo&SetPALTV){
+      if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+         PhasePoint = SiS_PALPhase2;              /* PALPhase */
+      else 
+         PhasePoint = SiS_PALPhase;  
+     
+         TimingPoint = SiS_PALTiming;
+    } else {
+        temp=temp|0x10;
+        if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+        	PhasePoint = SiS_NTSCPhase2;             /* PALPhase */
+        else
+        	PhasePoint = SiS_NTSCPhase;
+      
+        TimingPoint = SiS_NTSCTiming;
+    }
+  }
+  SiS_SetReg1(SiS_Part2Port,0x00,temp);
+
+#ifdef SIS300
+  /*add PALMN*/
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_730)) {
+     	if(SiS_VBInfo&SetCRT2ToTV) {
+             temp=SiS_GetReg1(SiS_P3d4,0x31);   
+             temp=temp&0x01; 
+             if(temp) {
+                  temp1=SiS_GetReg1(SiS_P3d4,0x35);        
+                  temp1=temp1&0x40; 
+                  if(temp1)
+                     	PhasePoint = SiS_PALMPhase;
+                  temp1=SiS_GetReg1(SiS_P3d4,0x35);        
+                  temp1=temp1&0x80;
+                  if(temp1)
+                     	PhasePoint = SiS_PALNPhase;
+             }
+        }
+  }
+  /*end add*/
+#endif
 
-	if (ModeNo <= 0x13) {
-		tempcl = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		tempcl = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	TVType = 0;
-	if (SiS_VBInfo & SetPALTV)
-		TVType = TVType + 2;
-	if (SiS_VBInfo & SetCHTVOverScan)
-		TVType = TVType + 1;
-	switch (TVType) {
-	case 0:
-		CHTVRegData = SiS_CHTVReg_UNTSC;
-		break;
-	case 1:
-		CHTVRegData = SiS_CHTVReg_ONTSC;
-		break;
-	case 2:
-		CHTVRegData = SiS_CHTVReg_UPAL;
-		break;
-	case 3:
-		CHTVRegData = SiS_CHTVReg_OPAL;
-		break;
-	}
-	resindex = tempcl & 0x3F;
+#ifdef SIS315H
+  /*add PALMN*/
+  if ( (HwDeviceExtension->jChipType==SIS_315H)||
+       (HwDeviceExtension->jChipType==SIS_315PRO)||
+       (HwDeviceExtension->jChipType==SIS_550) ||
+       (HwDeviceExtension->jChipType==SIS_640) ||
+       (HwDeviceExtension->jChipType==SIS_740) ||
+       (HwDeviceExtension->jChipType==SIS_650)) {
+           if(SiS_VBInfo&SetCRT2ToTV) {
+              temp=SiS_GetReg1(SiS_P3d4,0x31);
+              temp=temp&0x01;
+              if(temp) {
+                  temp1=SiS_GetReg1(SiS_P3d4,0x38);
+                  temp1=temp1&0x40;
+                  if(temp1)
+                     PhasePoint = SiS_PALMPhase;
+                  temp1=SiS_GetReg1(SiS_P3d4,0x38);
+                  temp1=temp1&0x80;
+                  if(temp1)
+                     PhasePoint = SiS_PALNPhase;
+              }
+           }
+  }
+  /*end add*/
+#endif
 
-	if (SiS_VBInfo & SetPALTV) {
-		SiS_SetCH7005 (0x4304);
-		SiS_SetCH7005 (0x6909);
-	} else {
-		SiS_SetCH7005 (0x0304);
-		SiS_SetCH7005 (0x7109);
-	}
+  for(i=0x31,j=0;i<=0x34;i++,j++){
+     SiS_SetReg1(SiS_Part2Port,i,PhasePoint[j]);
+  }
+  for(i=0x01,j=0;i<=0x2D;i++,j++){
+     SiS_SetReg1(SiS_Part2Port,i,TimingPoint[j]);
+  }
+  for(i=0x39;i<=0x45;i++,j++){
+     SiS_SetReg1(SiS_Part2Port,i,TimingPoint[j]);      /* di->temp2[j] */
+  }
+  if(SiS_VBInfo&SetCRT2ToTV) {
+    SiS_SetRegANDOR(SiS_Part2Port,0x3A,0x1F,0x00);
+  }
+  temp=SiS_NewFlickerMode;
+  SiS_SetRegANDOR(SiS_Part2Port,0x0A,0xFF,temp);
+
+  SiS_SetReg1(SiS_Part2Port,0x35,0x00); /*301b*/
+  SiS_SetReg1(SiS_Part2Port,0x36,0x00);
+  SiS_SetReg1(SiS_Part2Port,0x37,0x00);
+  SiS_SetReg1(SiS_Part2Port,0x38,SiS_RY1COE);
+  SiS_SetReg1(SiS_Part2Port,0x48,SiS_RY2COE);
+  SiS_SetReg1(SiS_Part2Port,0x49,SiS_RY3COE);
+  SiS_SetReg1(SiS_Part2Port,0x4a,SiS_RY4COE);
+
+  /*add to change 630+301b filter*/
+  resindex=SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
+  if(ModeNo<=0x13) {
+      xres=SiS_StResInfo[resindex].HTotal;
+  } else {
+      xres=SiS_ModeResInfo[resindex].HTotal;                         /* xres->ax */
+  }
+  if(xres==640){SiS_RY1COE=0xFF;SiS_RY2COE=0x03;SiS_RY3COE=0x02;SiS_RY4COE=0xF6;
+                         SiS_RY5COE=0xFC;SiS_RY6COE=0x27;SiS_RY7COE=0x46;}
+  if(xres==800){SiS_RY1COE=0x01;SiS_RY2COE=0x01;SiS_RY3COE=0xFC;SiS_RY4COE=0xF8;
+                         SiS_RY5COE=0x08;SiS_RY6COE=0x26;SiS_RY7COE=0x38;}                        
+  if(xres==1024){SiS_RY1COE=0xFF;SiS_RY2COE=0xFF;SiS_RY3COE=0xFC;SiS_RY4COE=0x00;
+                         SiS_RY5COE=0x0F;SiS_RY6COE=0x22;SiS_RY7COE=0x28;}
+  if(xres==720){SiS_RY1COE=0x01;SiS_RY2COE=0x02;SiS_RY3COE=0xFE;SiS_RY4COE=0xF7;
+                         SiS_RY5COE=0x03;SiS_RY6COE=0x27;SiS_RY7COE=0x3c;}
+  SiS_SetReg1(SiS_Part2Port,0x35,SiS_RY1COE); /*301b*/
+  SiS_SetReg1(SiS_Part2Port,0x36,SiS_RY2COE);
+  SiS_SetReg1(SiS_Part2Port,0x37,SiS_RY3COE);
+  SiS_SetReg1(SiS_Part2Port,0x38,SiS_RY4COE);
+  SiS_SetReg1(SiS_Part2Port,0x48,SiS_RY5COE);
+  SiS_SetReg1(SiS_Part2Port,0x49,SiS_RY6COE);
+  SiS_SetReg1(SiS_Part2Port,0x4a,SiS_RY7COE);
+  /*end add*/
+
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) tempax=950;
+  else {
+    if(SiS_VBInfo&SetPALTV) tempax=520;
+    else tempax=440;
+  }
+  if(SiS_VDE<=tempax) {
+    tempax=tempax-SiS_VDE;
+    tempax=tempax>>2;
+    tempax=(tempax&0x00FF)|((tempax&0x00FF)<<8);
+    push1=tempax;
+    temp=(tempax&0xFF00)>>8;
+    temp=temp+(USHORT)TimingPoint[0];
+    SiS_SetReg1(SiS_Part2Port,0x01,temp);
+    tempax=push1;
+    temp=(tempax&0xFF00)>>8;
+    temp=temp+TimingPoint[1];
+    SiS_SetReg1(SiS_Part2Port,0x02,temp);
+  }
+  /*301b*/
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+        && (SiS_VBInfo&SetCRT2ToTV) && (SiS_VGAHDE==1024) ) {
+      if(SiS_VBInfo&SetPALTV) {
+       SiS_SetReg1(SiS_Part2Port,0x01,0x19);
+       SiS_SetReg1(SiS_Part2Port,0x02,0x52);
+      } else {
+       SiS_SetReg1(SiS_Part2Port,0x01,0x0B);
+       SiS_SetReg1(SiS_Part2Port,0x02,0x11);
+      } 
+    }
+    
+  tempcx=SiS_HT-1;
+  /*301b*/
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+     tempcx=tempcx-1;   
+  }
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x1B,temp);
+  temp=(tempcx&0xFF00)>>8;
+  SiS_SetRegANDOR(SiS_Part2Port,0x1D,~0x0F,temp);
+
+  tempcx=SiS_HT>>1;
+  push1=tempcx;                           /* push cx */
+  tempcx=tempcx+7;
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+    tempcx=tempcx-4;
+  }
+  temp=(tempcx&0x00FF);
+  temp=temp<<4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x22,0x0F,temp);
+
+  tempbx=TimingPoint[j]|((TimingPoint[j+1])<<8);
+  tempbx=tempbx+tempcx;
+  push2=tempbx;
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x24,temp);
+  temp=(tempbx&0xFF00)>>8;
+  temp=temp<<4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x25,0x0F,temp);
+
+  tempbx=push2;
+  tempbx=tempbx+8;
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+    tempbx=tempbx-4;
+    tempcx=tempbx;
+  }
+  temp=(tempbx&0x00FF)<<4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x29,0x0F,temp);
+
+  j=j+2;
+  tempcx=tempcx+(TimingPoint[j]|((TimingPoint[j+1])<<8));
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x27,temp);
+  temp=((tempcx&0xFF00)>>8)<<4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x28,0x0F,temp);
+
+  tempcx=tempcx+8;
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+    tempcx=tempcx-4;
+  }
+  temp=tempcx&0xFF;
+  temp=temp<<4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x2A,0x0F,temp);
+
+  tempcx=push1;                                       /* pop cx */
+  j=j+2;
+  temp=TimingPoint[j]|((TimingPoint[j+1])<<8);
+  tempcx=tempcx-temp;
+  temp=tempcx&0x00FF;
+  temp=temp<<4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x2D,0x0F,temp);
+
+  tempcx=tempcx-11;
+  if(!(SiS_VBInfo&SetCRT2ToTV)){
+    tempax=SiS_GetVGAHT2();
+    tempcx=tempax-1;
+  }
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x2E,temp);	/* TW: BIOS 0x48, here 0x3f @@@ */
+
+  tempbx=SiS_VDE;
+  if(SiS_VGAVDE==360) tempbx=746;
+  if(SiS_VGAVDE==375) tempbx=746;
+  if(SiS_VGAVDE==405) tempbx=853;
+  if(SiS_VBInfo&SetCRT2ToTV) {
+    tempbx=tempbx>>1;
+  }
+  tempbx=tempbx-2;
+  temp=tempbx&0x00FF;
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+    if(SiS_VBInfo&SetInSlaveMode) {
+      if(ModeNo==0x2f) temp=temp+1;
+    }
+  }
+  SiS_SetReg1(SiS_Part2Port,0x2F,temp);
+
+  temp=(tempcx&0xFF00)>>8;
+  temp=temp|(((tempbx&0xFF00)>>8)<<6);
+  if(!(SiS_VBInfo&SetCRT2ToHiVisionTV)) {
+    temp=temp|0x10;
+    if(!(SiS_VBInfo&SetCRT2ToSVIDEO)){
+      temp=temp|0x20;
+    }
+  }
+  SiS_SetReg1(SiS_Part2Port,0x30,temp);  /* TW: BIOS sets 0xb8, here (or somewhere else) 0xb5 */
+
+  /*301b*/
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {      /*tv gatingno*/
+    tempbx=SiS_VDE;
+    if(SiS_VBInfo&SetCRT2ToTV) {
+       tempbx=tempbx>>1;
+    }
+    temp=(((tempbx-3)&0x0300)>>8)<<5;
+    SiS_SetReg1(SiS_Part2Port,0x46,temp);
+    temp=(tempbx-3)&0x00FF;
+    SiS_SetReg1(SiS_Part2Port,0x47,temp);
+  }
+  /*end 301b*/
+
+  tempbx=tempbx&0x00FF;
+  if(!(modeflag&HalfDCLK)){
+    tempcx=SiS_VGAHDE;
+    if(tempcx>=SiS_HDE){
+      tempbx=tempbx|0x2000;
+      tempax=tempax&0x00FF;
+    }
+  }
+  tempcx=0x0101;
+
+  if(SiS_VBInfo&(SetCRT2ToHiVisionTV|SetCRT2ToTV)) { /*301b*/
+    if(SiS_VGAHDE>=1024) {
+      tempcx=0x1920;
+      if(SiS_VGAHDE>=1280) {
+        tempcx=0x1420;
+        tempbx=tempbx&0xDFFF;
+      }
+    }
+  }
+  if(!(tempbx&0x2000)){
+    if(modeflag&HalfDCLK){
+      tempcx=(tempcx&0xFF00)|((tempcx&0x00FF)<<1);
+    }
+    push1=tempbx;
+    tempeax=SiS_VGAHDE;
+    tempebx=(tempcx&0xFF00)>>8;
+    longtemp=tempeax*tempebx;
+    tempecx=tempcx&0x00FF;
+    longtemp=longtemp/tempecx;
+    /*301b*/
+    tempecx=8*1024;
+    if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+     	tempecx=tempecx*8;
+    }
+    longtemp=longtemp*tempecx;
+    tempecx=SiS_HDE;
+    temp2=longtemp%tempecx;
+    tempeax=longtemp/tempecx;
+    if(temp2!=0){
+      tempeax=tempeax+1;
+    }
+    tempax=(USHORT)tempeax;
+    /*301b*/
+    if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+     	tempcx=((tempax&0xFF00)>>5)>>8;
+    }
+    /*end 301b*/
+    tempbx=push1;
+    tempbx=(USHORT) ( ((tempeax&0x0000FF00)&0x1F00)|(tempbx&0x00FF) );
+    tempax=(USHORT) ( ((tempeax&0x000000FF)<<8)|(tempax&0x00FF) );
+    temp=(tempax&0xFF00)>>8;
+  } else {
+    temp=(tempax&0x00FF)>>8;
+  }
+  SiS_SetReg1(SiS_Part2Port,0x44,temp);
+  temp=(tempbx&0xFF00)>>8;
+  SiS_SetRegANDOR(SiS_Part2Port,0x45,~0x03F,temp);
+  /*301b*/
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+       if((tempcx&0x00FF)==0x01)
+    		tempcx=0x00;
+       SiS_SetRegANDOR(SiS_Part2Port,0x46,~0x007,tempcx);
+       SiS_SetRegOR(SiS_Part2Port,0x46,0x18);
+               if(SiS_VBInfo&SetPALTV) {
+                   tempbx=0x0364;
+                   tempcx=0x009c;
+               } else {
+                   tempbx=0x0346;
+                   tempcx=0x0078;
+               }
+       temp=(tempbx&0x00FF) ;
+       SiS_SetReg1(SiS_Part2Port,0x4B,temp);
+       temp=(tempcx&0x00FF) ;
+       SiS_SetReg1(SiS_Part2Port,0x4C,temp);
+       tempbx=(tempbx&0x0300);
+       temp=(tempcx&0xFF00)>>8 ;
+       temp=(temp&0x0003)<<2;
+       temp=temp|(tempbx>>8);
+       SiS_SetReg1(SiS_Part2Port,0x4D,temp);
+
+       temp=SiS_GetReg1(SiS_Part2Port,0x43); /*301b change */
+       SiS_SetReg1(SiS_Part2Port,0x43,(USHORT)(temp-3));
+  }
+  /*end 301b*/
+
+#ifdef SIS300
+  /*add PALMN*/
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_730)) {
+          if(SiS_VBInfo&SetCRT2ToTV) {
+             temp=SiS_GetReg1(SiS_P3d4,0x31);
+             temp=temp&0x01;
+             if(temp) {
+                  temp1=SiS_GetReg1(SiS_P3d4,0x35);
+                  temp1=temp1&0x40;
+                  if(temp1){
+                           SiS_SetRegANDOR(SiS_Part2Port,0x00,0xEF,0x00);
+                           temp3=SiS_GetReg1(SiS_Part2Port,0x01);
+                           temp3=temp3-1;
+                           SiS_SetReg1(SiS_Part2Port,0x01,temp3);
+                  }
+             }
+          }
+  }
+  /*end add*/
+#endif
 
-	temp = CHTVRegData[resindex].Reg[0];
-	tempbx = ((temp & 0x00FF) << 8) | 0x00;
-	SiS_SetCH7005 (tempbx);
-	temp = CHTVRegData[resindex].Reg[1];
-	tempbx = ((temp & 0x00FF) << 8) | 0x07;
-	SiS_SetCH7005 (tempbx);
-	temp = CHTVRegData[resindex].Reg[2];
-	tempbx = ((temp & 0x00FF) << 8) | 0x08;
-	SiS_SetCH7005 (tempbx);
-	temp = CHTVRegData[resindex].Reg[3];
-	tempbx = ((temp & 0x00FF) << 8) | 0x0A;
-	SiS_SetCH7005 (tempbx);
-	temp = CHTVRegData[resindex].Reg[4];
-	tempbx = ((temp & 0x00FF) << 8) | 0x0B;
-	SiS_SetCH7005 (tempbx);
-
-	SiS_SetCH7005 (0x2801);
-	SiS_SetCH7005 (0x3103);
-	SiS_SetCH7005 (0x003D);
-	SiS_SetCHTVRegANDOR (0x0010, 0x1F);
-	SiS_SetCHTVRegANDOR (0x0211, 0xF8);
-	SiS_SetCHTVRegANDOR (0x001C, 0xEF);
-
-	if (!(SiS_VBInfo & SetPALTV)) {
-		/* tempcl=CRT2CRTC; */
-		tempcl = tempcl & 0x3F;
-		if (SiS_VBInfo & SetCHTVOverScan) {
-			if (tempcl == 0x04) {	/* 640x480   underscan */
-				SiS_SetCHTVRegANDOR (0x0020, 0xEF);
-				SiS_SetCHTVRegANDOR (0x0121, 0xFE);
-			} else {
-				if (tempcl == 0x05) {	/* 800x600  underscan */
-					SiS_SetCHTVRegANDOR (0x0118, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0C19, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001A, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001B, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001C, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001D, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001E, 0xF0);
-					SiS_SetCHTVRegANDOR (0x001F, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0120, 0xEF);
-					SiS_SetCHTVRegANDOR (0x0021, 0xFE);
-				}
-			}
-		} else {
-			if (tempcl == 0x04) {	/* 640x480   overscan  */
-				SiS_SetCHTVRegANDOR (0x0020, 0xEF);
-				SiS_SetCHTVRegANDOR (0x0121, 0xFE);
-			} else {
-				if (tempcl == 0x05) {	/* 800x600   overscan */
-					SiS_SetCHTVRegANDOR (0x0118, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0F19, 0xF0);
-					SiS_SetCHTVRegANDOR (0x011A, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0C1B, 0xF0);
-					SiS_SetCHTVRegANDOR (0x071C, 0xF0);
-					SiS_SetCHTVRegANDOR (0x011D, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0C1E, 0xF0);
-					SiS_SetCHTVRegANDOR (0x071F, 0xF0);
-					SiS_SetCHTVRegANDOR (0x0120, 0xEF);
-					SiS_SetCHTVRegANDOR (0x0021, 0xFE);
-				}
-			}
-		}
-	}
+#ifdef SIS315H
+  /*add PALMN*/
+  if ( (HwDeviceExtension->jChipType==SIS_315H)||
+       (HwDeviceExtension->jChipType==SIS_315PRO)||
+       (HwDeviceExtension->jChipType==SIS_550) ||
+       (HwDeviceExtension->jChipType==SIS_640) ||
+       (HwDeviceExtension->jChipType==SIS_740) ||
+       (HwDeviceExtension->jChipType==SIS_650)) {
+        	if(SiS_VBInfo&SetCRT2ToTV) {
+             		temp=SiS_GetReg1(SiS_P3d4,0x31);
+            		temp=temp&0x01;
+              		if(temp) {
+                  		temp1=SiS_GetReg1(SiS_P3d4,0x38);
+                 		temp1=temp1&0x40;
+                   		if(temp1){
+                           		SiS_SetRegANDOR(SiS_Part2Port,0x00,0xEF,0x00);
+                           		temp3=SiS_GetReg1(SiS_Part2Port,0x01);
+                           		temp3=temp3-1;
+                           		SiS_SetReg1(SiS_Part2Port,0x01,temp3);
+                		}
+             		}
+          	}
+  }
+  /*end add*/
+#endif
+
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+    if(!(SiS_VBInfo&SetInSlaveMode)) {
+      SiS_SetReg1(SiS_Part2Port,0x0B,0x00);
+    }
+  }
+  if(SiS_VBInfo&SetCRT2ToTV){
+    return;
+  }
+
+  /* TW: From here: LCD Part2 group */
+
+  tempbx=SiS_HDE-1;         /* RHACTE=HDE-1 */
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x2C,temp);
+  temp=(tempbx&0xFF00)>>8;
+  temp=temp<<4;
+  SiS_SetRegANDOR(SiS_Part2Port,0x2B,0x0F,temp);
+  temp=0x01;
+  if(SiS_LCDResInfo==Panel1280x1024) {
+    if(SiS_ModeType==ModeEGA) {
+      if(SiS_VGAHDE>=1024) {
+        temp=0x02;
+        if (SiS_SetFlag&LCDVESATiming)
+          temp=0x01;
+      }
+    }
+  }
+  SiS_SetReg1(SiS_Part2Port,0x0B,temp);
+
+  tempbx=SiS_VDE;         /* RTVACTEO=(VDE-1)&0xFF */
+  push1=tempbx;
+  tempbx--;
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part2Port,0x03,temp);
+  temp=((tempbx&0xFF00)>>8)&0x07;
+  SiS_SetRegANDOR(SiS_Part2Port,0x0C,~0x07,temp);
+
+  tempcx=SiS_VT-1;
+  push2=tempcx+1;
+  temp=tempcx&0x00FF;   /* RVTVT=VT-1 */
+  SiS_SetReg1(SiS_Part2Port,0x19,temp);
+  temp=(tempcx&0xFF00)>>8;
+  temp=temp<<5;
+  if(SiS_LCDInfo&LCDRGB18Bit){
+    temp=temp|0x10;
+  }
+  if(SiS_VBInfo&SetCRT2ToLCD) {
+    tempbx=(tempbx&0xFF00)|(SiS_LCDInfo&0x0FF);
+    if(tempbx&LCDSync) {
+      tempbx=tempbx&LCDSyncBit;
+      tempbx=(tempbx&0xFF00)|((tempbx&0x00FF)>>LCDSyncShift);
+      temp=temp|(tempbx&0x00FF);
+    }
+  }
+  SiS_SetReg1(SiS_Part2Port,0x1A,temp);
+
+  tempcx++;
+  tempbx=768;
+  if(SiS_LCDResInfo!=Panel1024x768) {
+    tempbx=1024;
+    if(SiS_LCDResInfo!=Panel1280x1024) {
+         tempbx=1200;     /*301b */
+         if(SiS_LCDResInfo!=Panel1600x1200) {
+            if(tempbx!=SiS_VDE) {
+               tempbx=960;
+            }
+         }
+    }
+  }
+  if(SiS_LCDInfo&LCDNonExpanding) {
+    tempbx=SiS_VDE;
+    tempbx--;
+    tempcx--;
+  }
+  tempax=1;
+  if(!(SiS_LCDInfo&LCDNonExpanding)) {
+    if(tempbx!=SiS_VDE){
+      tempax=tempbx;
+      if(tempax<SiS_VDE) {
+        tempax=0;
+        tempcx=0;
+      } else {
+        tempax=tempax-SiS_VDE;
+      }
+      tempax=tempax>>1;
+    }
+    tempcx=tempcx-tempax; /* lcdvdes */
+    tempbx=tempbx-tempax; /* lcdvdee */
+  } else {
+    tempax=tempax>>1;
+    tempcx=tempcx-tempax; /* lcdvdes */
+    tempbx=tempbx-tempax; /* lcdvdee */
+  }
+
+  temp=tempcx&0x00FF;   /* RVEQ1EQ=lcdvdes */
+  SiS_SetReg1(SiS_Part2Port,0x05,temp);
+  temp=tempbx&0x00FF;   /* RVEQ2EQ=lcdvdee */
+  SiS_SetReg1(SiS_Part2Port,0x06,temp);
+
+  /* TW new @@@ */
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+        /* TW: BIOS sets Part2 0x02 to 0x18. The old caluculation (in else statement)
+	 *     resulted in 0x13. Do it this way for 301B?
+	 */
+        temp=(((tempcx&0xFF00)>>8)<<3);   /* 0x325 & ff00 = 300 >> 8 = 3 << 3 = 0x18 */
+	SiS_SetReg1(SiS_Part2Port,0x02,temp);
+  } else {
+  /* TW end */
+  	temp=(tempbx&0xFF00)>>8;
+  	temp=temp<<3;
+  	temp=temp|((tempcx&0xFF00)>>8);
+  	SiS_SetReg1(SiS_Part2Port,0x02,temp);
+  }
+
+  tempbx=push2;  	/* SiS_VT = 0x326  - - - (TW DEBUG REMARKS)*/
+  tempax=push1;  	/* SiS_VDE = 0x300 */
+  tempcx=tempbx;
+  tempcx=tempcx-tempax; /* -> 0x26 */
+  tempcx=tempcx>>4;     /* -> 0x02 */
+  tempbx=tempbx+tempax; /* -> 0x626 */
+  tempbx=tempbx>>1;     /* -> 0x313 */
+  if(SiS_LCDInfo&LCDNonExpanding) {
+     tempbx=tempbx-10;
+  }
+  /* TW new @@@ */
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+  	/* TW: BIOS sets Part2 0x04 to 0x02. The old caluculation (in else statement)
+	 *     resulted in 0x13. Do it this way for 301B?
+	 */
+        temp=tempcx&0x00FF;
+	SiS_SetReg1(SiS_Part2Port,0x04,temp);
+  } else {
+  /* TW end */
+    	temp=tempbx&0x00FF;   		/* RTVACTEE=lcdvrs */
+  	SiS_SetReg1(SiS_Part2Port,0x04,temp);   /* TW: BIOS: 0x02, here 0x13 */
+  }
+
+ temp=(tempbx&0xFF00)>>8;
+ temp=temp<<4;
+ tempbx=tempbx+tempcx+1;
+ temp=temp|(tempbx&0x000F);
+ SiS_SetReg1(SiS_Part2Port,0x01,temp);
+
+ if(SiS_LCDResInfo==Panel1024x768) {
+   if(!(SiS_SetFlag&LCDVESATiming)) {
+     if(!(SiS_LCDInfo&LCDNonExpanding)) {
+       if(ModeNo==0x13) {
+         SiS_SetReg1(SiS_Part2Port,0x04,0xB9);
+         SiS_SetReg1(SiS_Part2Port,0x05,0xCC);
+         SiS_SetReg1(SiS_Part2Port,0x06,0xA6);
+       } else {
+         temp=crt2crtc&0x3F;
+         if(temp==4) {
+           SiS_SetReg1(SiS_Part2Port,0x01,0x2B);
+           SiS_SetReg1(SiS_Part2Port,0x02,0x13);
+           SiS_SetReg1(SiS_Part2Port,0x04,0xE5);
+           SiS_SetReg1(SiS_Part2Port,0x05,0x08);
+           SiS_SetReg1(SiS_Part2Port,0x06,0xE2);
+         }
+       }
+     }
+   }
+ }
+
+ SiS_SetRegANDOR(SiS_Part2Port,0x09,0xF0,0x00);
+ SiS_SetRegANDOR(SiS_Part2Port,0x0A,0xF0,0x00);
+
+ tempcx=(SiS_HT-SiS_HDE)>>2;    		/* (HT-HDE)>>2     */
+ tempbx=(SiS_HDE+7);            		/* lcdhdee         */
+ /*301b*/
+ if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+    tempbx=tempbx+2;
+ }
+ push1=tempbx;
+ temp=tempbx&0x00FF;    			/* RHEQPLE=lcdhdee */
+ SiS_SetReg1(SiS_Part2Port,0x23,temp);
+ temp=(tempbx&0xFF00)>>8;
+ SiS_SetRegANDOR(SiS_Part2Port,0x25,~0x0F,temp);
+ /*301b*/
+ temp=7;
+ if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+    temp=temp+2;
+ }
+ SiS_SetReg1(SiS_Part2Port,0x1F,temp);  	/* RHBLKE=lcdhdes */
+ SiS_SetRegANDOR(SiS_Part2Port,0x20,0x0F,0x00);
+
+ tempbx=tempbx+tempcx;
+ push2=tempbx;
+ temp=tempbx&0xFF;            			/* RHBURSTS=lcdhrs */
+ if(SiS_LCDResInfo==Panel1280x1024) {
+   if(!(SiS_LCDInfo&LCDNonExpanding)) {
+     if(SiS_HDE==1280) {
+       temp=0x47;
+     }
+   }
+ }
+ SiS_SetReg1(SiS_Part2Port,0x1C,temp);
+ temp=(tempbx&0xFF00)>>8;
+ temp=temp<<4;
+ SiS_SetRegANDOR(SiS_Part2Port,0x1D,~0x0F0,temp);
+
+ tempbx=push2;
+ tempcx=tempcx<<1;
+ tempbx=tempbx+tempcx;
+ temp=tempbx&0x00FF;            		/* RHSYEXP2S=lcdhre */
+ SiS_SetReg1(SiS_Part2Port,0x21,temp);
+
+ SiS_SetRegANDOR(SiS_Part2Port,0x17,0xFB,0x00);
+ SiS_SetRegANDOR(SiS_Part2Port,0x18,0xDF,0x00);
+
+ if(!(SiS_SetFlag&LCDVESATiming)) {
+   if(SiS_VGAVDE==525) {
+     if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))   /*301b*/
+    	temp=0xC6;
+     else
+       	temp=0xC4;
+     SiS_SetReg1(SiS_Part2Port,0x2f,temp);
+     SiS_SetReg1(SiS_Part2Port,0x30,0xB3);
+   }
+   if(SiS_VGAVDE==420) {
+     if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+    	temp=0x4F;
+     else
+       	temp=0x4E;
+     SiS_SetReg1(SiS_Part2Port,0x2f,temp);
+   }
+ }
 }
 
-void
-SiS_SetCHTVRegANDOR (USHORT tempax, USHORT tempbh)
+USHORT
+SiS_GetVGAHT2()
 {
-	USHORT tempal, tempah, tempbl;
+  ULONG tempax,tempbx;
 
-	tempal = tempax & 0x00FF;
-	tempah = (tempax >> 8) & 0x00FF;
-	tempbl = SiS_GetCH7005 (tempal);
-	tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
-	SiS_SetCH7005 (tempbl);
+  tempbx=((SiS_VGAVT-SiS_VGAVDE)*SiS_RVBHCMAX)&0xFFFF;
+  tempax=(SiS_VT-SiS_VDE)*SiS_RVBHCFACT;
+  tempax=(tempax*SiS_HT)/tempbx;
+  return((USHORT) tempax);
 }
 
 void
-SiS_SetCH7005 (USHORT tempbx)
-{
-	USHORT tempah, temp;
-
-	SiS_DDC_Port = 0x3c4;
-	SiS_DDC_Index = 0x11;
-	SiS_DDC_DataShift = 0x00;
-	SiS_DDC_DeviceAddr = 0xEA;
-
-	temp = 1;
-	for (; temp != 0;) {
-		SiS_SetSwitchDDC2 ();
-		SiS_SetStart ();
-		tempah = SiS_DDC_DeviceAddr;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		tempah = tempbx & 0x00FF;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		tempah = (tempbx & 0xFF00) >> 8;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		SiS_SetStop ();
-	}
+SiS_SetGroup3(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT i;
+  UCHAR *tempdi;
+  USHORT  modeflag,temp,temp1;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+  }
+
+  SiS_SetReg1(SiS_Part3Port,0x00,0x00);
+  if(SiS_VBInfo&SetPALTV) {
+    SiS_SetReg1(SiS_Part3Port,0x13,0xFA);
+    SiS_SetReg1(SiS_Part3Port,0x14,0xC8);
+  } else {
+    SiS_SetReg1(SiS_Part3Port,0x13,0xF6);
+    SiS_SetReg1(SiS_Part3Port,0x14,0xBF);
+  }
+#ifdef SIS300
+  /*add PALMN*/
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_730)) {
+           if(SiS_VBInfo&SetCRT2ToTV) {
+              temp=SiS_GetReg1(SiS_P3d4,0x31);
+              temp=temp&0x01;
+              if(temp) {
+                  temp1=SiS_GetReg1(SiS_P3d4,0x35);
+                  temp1=temp1&0x40;
+                   if(temp1){
+                          SiS_SetReg1(SiS_Part3Port,0x13,0xFA);
+                          SiS_SetReg1(SiS_Part3Port,0x14,0xC8);
+                          SiS_SetReg1(SiS_Part3Port,0x3D,0xA8);
+                }
+             }
+          } 
+      }	
+    /*end add*/
+#endif
+#ifdef SIS315H
+/*add PALMN*/
+  if ( (HwDeviceExtension->jChipType==SIS_315H)||
+       (HwDeviceExtension->jChipType==SIS_315PRO)||
+       (HwDeviceExtension->jChipType==SIS_550) ||
+       (HwDeviceExtension->jChipType==SIS_640) ||
+       (HwDeviceExtension->jChipType==SIS_740) ||
+       (HwDeviceExtension->jChipType==SIS_650)) {
+         if(SiS_VBInfo&SetCRT2ToTV) {
+             temp=SiS_GetReg1(SiS_P3d4,0x31);   
+             temp=temp&0x01; 
+              if(temp) {
+                  temp1=SiS_GetReg1(SiS_P3d4,0x38);        
+                  temp1=temp1&0x40; 
+                   if(temp1){
+                          SiS_SetReg1(SiS_Part3Port,0x13,0xFA); 
+                          SiS_SetReg1(SiS_Part3Port,0x14,0xC8); 
+                          SiS_SetReg1(SiS_Part3Port,0x3D,0xA8);
+                   }
+              }
+         }
+  }
+ /*end add*/
+#endif
+  if(SiS_VBInfo&SetCRT2ToHiVisionTV) {
+    tempdi=SiS_HiTVGroup3Data;
+    if(SiS_SetFlag&TVSimuMode) {
+      tempdi=SiS_HiTVGroup3Simu;
+      if(!(modeflag&Charx8Dot)) {
+        tempdi=SiS_HiTVGroup3Text;
+      }
+    }
+    for(i=0;i<=0x3E;i++){
+       SiS_SetReg1(SiS_Part3Port,i,tempdi[i]);
+    }
+  }
+  return;
+}
+
+void
+SiS_SetGroup4(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+              USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,push1;
+  ULONG tempebx,tempeax,templong;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+  }
+  temp=SiS_RVBHCFACT;
+  SiS_SetReg1(SiS_Part4Port,0x13,temp);
+
+  tempbx=SiS_RVBHCMAX;
+  temp=tempbx&0x00FF;
+  SiS_SetReg1(SiS_Part4Port,0x14,temp);
+  temp2=((tempbx&0xFF00)>>8)<<7;
+  
+  tempcx=SiS_VGAHT-1;
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part4Port,0x16,temp);
+  temp=((tempcx&0xFF00)>>8)<<3;
+  temp2=temp|temp2;
+
+  tempcx=SiS_VGAVT-1;
+  if(!(SiS_VBInfo&SetCRT2ToTV)){
+    tempcx=tempcx-5;
+  }
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part4Port,0x17,temp);
+  temp=temp2|((tempcx&0xFF00)>>8);
+  SiS_SetReg1(SiS_Part4Port,0x15,temp);
+
+  tempcx=SiS_VBInfo;
+  tempbx=SiS_VGAHDE;
+  if(modeflag&HalfDCLK){
+    tempbx=tempbx>>1;
+  }
+  if(tempcx&SetCRT2ToHiVisionTV) {
+       temp=0xA0;
+       if(tempbx!=1024) {
+           temp=0xC0;
+           if(tempbx!=1280) temp=0;
+       }
+  } else if((tempcx&SetCRT2ToTV)&&(SiS_VGAHDE==1024)) {       /*301b*/
+       temp=0xA0;
+  } else {
+       temp=0x80;
+       if(SiS_VBInfo&SetCRT2ToLCD){
+          temp=0;
+          if(tempbx>800) temp=0x60;
+       }
+  }
+  if(SiS_LCDResInfo!=Panel1280x1024) temp=temp|0x0A;
+  SiS_SetRegANDOR(SiS_Part4Port,0x0E,~0xEF,temp);
+
+  tempebx=SiS_VDE;
+  if(tempcx&SetCRT2ToHiVisionTV) {
+    /* if(!(tempax&0xE000)) tempbx=tempbx>>1; */
+    if(!(temp&0xE000)) tempbx=tempbx>>1;               /* alan ???? */
+
+  }
+
+  tempcx=SiS_RVBHRS;
+  temp=tempcx&0x00FF;
+  SiS_SetReg1(SiS_Part4Port,0x18,temp);
+
+  tempebx=tempebx;
+  tempeax=SiS_VGAVDE;
+  tempcx=tempcx|0x04000;
+/*tempeax=tempeax-tempebx;  */
+  if(tempeax<=tempebx){
+    tempcx=((tempcx&0xFF00)^0x4000)|(tempcx&0x00ff);
+    tempeax=SiS_VGAVDE;
+  }
+
+  else {
+    tempeax=tempeax-tempebx;
+  }
+
+  push1=tempcx;
+  templong=(tempeax*256*1024)%tempebx;
+  tempeax=(tempeax*256*1024)/tempebx;
+  tempebx=tempeax;
+  if(templong!=0){
+    tempebx++;
+  }
+  tempcx=push1;
+  temp=(USHORT)(tempebx&0x000000FF);
+  SiS_SetReg1(SiS_Part4Port,0x1B,temp);
+  temp=(USHORT)((tempebx&0x0000FF00)>>8);
+  SiS_SetReg1(SiS_Part4Port,0x1A,temp);
+  tempbx=(USHORT) (tempebx>>16);
+  temp=tempbx&0x00FF;
+  temp=temp<<4;
+  temp=temp|((tempcx&0xFF00)>>8);
+  SiS_SetReg1(SiS_Part4Port,0x19,temp);
+
+  /*301b*/
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+         temp=0x0028;
+         SiS_SetReg1(SiS_Part4Port,0x1C,temp);
+         tempax=SiS_VGAHDE;
+          if(modeflag&HalfDCLK){
+           tempax=tempax>>1;
+           }
+          if(SiS_VBInfo&(SetCRT2ToLCD)) {
+             if(tempax>800)
+                tempax=tempax-800;
+          }
+          tempax=tempax-1;                
+                 
+         if(SiS_VBInfo&(SetCRT2ToTV|SetCRT2ToHiVisionTV)) {
+          if(SiS_VGAHDE>800)
+            {
+              if(SiS_VGAHDE==1024)
+                tempax=(tempax*25/32)-1;
+              else
+                  tempax=(tempax*20/32)-1;          
+            }
+         }
+         temp=(tempax&0xFF00)>>8;
+         temp=((temp&0x0003)<<4);
+         SiS_SetReg1(SiS_Part4Port,0x1E,temp);
+         temp=(tempax&0x00FF);
+         SiS_SetReg1(SiS_Part4Port,0x1D,temp);
+   
+         if(SiS_VBInfo&(SetCRT2ToTV|SetCRT2ToHiVisionTV)) {
+            if(SiS_VGAHDE>800){
+               SiS_SetRegOR(SiS_Part4Port,0x1E,0x08);
+            }
+         }
+         temp=0x0036;
+         if(SiS_VBInfo&SetCRT2ToTV) {
+             temp=temp|0x0001;
+         }
+         SiS_SetRegANDOR(SiS_Part4Port,0x1F,0x00C0,temp);
+         tempbx=(SiS_HT/2)-2;
+         temp=((tempbx&0x0700)>>8)<<3;
+         SiS_SetRegANDOR(SiS_Part4Port,0x21,0x00C0,temp);
+         temp=tempbx&0x00FF;
+         SiS_SetReg1(SiS_Part4Port,0x22,temp);
+         if( (SiS_VBType&(VB_SIS301LV|VB_SIS302LV)) && (SiS_VBInfo&SetCRT2ToLCD) ) {
+             SiS_SetReg1(SiS_Part4Port,0x24,0x0e);
+	 }
+  }
+  /*end 301b*/
+
+  SiS_SetCRT2VCLK(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+}
+
+void
+SiS_SetCRT2VCLK(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT vclkindex;
+  USHORT tempah,temp1;
+
+  vclkindex = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+  /*301b*/
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+   	tempah = SiS_VBVCLKData[vclkindex].Part4_A;
+   	SiS_SetReg1(SiS_Part4Port,0x0A,tempah);
+   	tempah = SiS_VBVCLKData[vclkindex].Part4_B;
+   	SiS_SetReg1(SiS_Part4Port,0x0B,tempah);
+  } else {
+   	SiS_SetReg1(SiS_Part4Port,0x0A,0x01);
+   	tempah = SiS_VBVCLKData[vclkindex].Part4_B;
+   	SiS_SetReg1(SiS_Part4Port,0x0B,tempah);
+   	tempah = SiS_VBVCLKData[vclkindex].Part4_A;
+   	SiS_SetReg1(SiS_Part4Port,0x0A,tempah);
+  }
+  SiS_SetReg1(SiS_Part4Port,0x12,0x00);
+  tempah=0x08;
+  if(SiS_VBInfo&SetCRT2ToRAMDAC){
+    	tempah=tempah|0x020;
+  }
+  temp1=SiS_GetReg1(SiS_Part4Port,0x12);
+  tempah=tempah|temp1;
+  SiS_SetReg1(SiS_Part4Port,0x12,tempah);
 }
 
 USHORT
-SiS_GetCH7005 (USHORT tempbx)
+SiS_GetVCLK2Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT tempah, temp;
+  USHORT tempbx;
+#ifdef SIS300
+  USHORT LCDXlat1VCLK300[4] = {VCLK65,VCLK65,VCLK65,VCLK65};
+  USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
+  USHORT LVDSXlat2VCLK300[4]= {VCLK65,VCLK65,VCLK65,VCLK65};
+  USHORT LVDSXlat3VCLK300[4]= {VCLK65,VCLK65,VCLK65,VCLK65};
+#endif
+#ifdef SIS315H
+  USHORT LCDXlat1VCLK310[4] = {VCLK65+2,VCLK65+2,VCLK65+2,VCLK65+2};
+  USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+  USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,VCLK65+2,VCLK65+2,VCLK65+2};
+  USHORT LVDSXlat3VCLK310[4]= {VCLK65+2,VCLK65+2,VCLK65+2,VCLK65+2};
+#endif
+  USHORT LVDSXlat1VCLK[4]   = {VCLK40,VCLK40,VCLK40,VCLK40};
+  USHORT CRT2Index,VCLKIndex;
+  USHORT modeflag,resinfo;
+  UCHAR *CHTVVCLKPtr=NULL;
+  USHORT *LCDXlatVCLK1=NULL;
+  USHORT *LCDXlatVCLK2=NULL;
+  USHORT *LVDSXlatVCLK2=NULL;
+  USHORT *LVDSXlatVCLK3=NULL;
+
+#ifdef SIS315H
+  if ( (HwDeviceExtension->jChipType==SIS_315H)||   
+       (HwDeviceExtension->jChipType==SIS_315PRO)||
+       (HwDeviceExtension->jChipType==SIS_550) ||
+       (HwDeviceExtension->jChipType==SIS_640) ||
+       (HwDeviceExtension->jChipType==SIS_740) ||
+       (HwDeviceExtension->jChipType==SIS_650)) {
+		LCDXlatVCLK1 = LCDXlat1VCLK310;
+		LCDXlatVCLK2 = LCDXlat2VCLK310;
+		LVDSXlatVCLK2 = LVDSXlat2VCLK310;
+		LVDSXlatVCLK3 = LVDSXlat3VCLK310;
+  } else {
+#endif
+#ifdef SIS300
+		LCDXlatVCLK1 = LCDXlat1VCLK300;
+		LCDXlatVCLK2 = LCDXlat2VCLK300;
+		LVDSXlatVCLK2 = LVDSXlat2VCLK300;
+		LVDSXlatVCLK3 = LVDSXlat3VCLK300;
+#endif
+#ifdef SIS315H
+  }
+#endif
 
-	SiS_DDC_Port = 0x3c4;
-	SiS_DDC_Index = 0x11;
-	SiS_DDC_DataShift = 0x00;
-	SiS_DDC_DeviceAddr = 0xEA;
-	SiS_DDC_ReadAddr = tempbx;
-
-	for (;;) {
-		SiS_SetSwitchDDC2 ();
-		SiS_SetStart ();
-		tempah = SiS_DDC_DeviceAddr;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		tempah = SiS_DDC_ReadAddr;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-
-		SiS_SetStart ();
-		tempah = SiS_DDC_DeviceAddr;
-		tempah = tempah | 0x01;
-		temp = SiS_WriteDDC2Data (tempah);
-		if (temp)
-			continue;
-		tempah = SiS_ReadDDC2Data (tempah);
-		SiS_SetStop ();
-		return (tempah);
-	}
-}
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+    	CRT2Index = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	CRT2Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+
+  if(SiS_IF_DEF_LVDS==0) {
+     CRT2Index = CRT2Index>>6;        /*  for LCD */
+     if((SiS_VBInfo&SetCRT2ToLCD)||(SiS_VBInfo&SetCRT2ToLCDA)){   /*301b*/
+      	if(SiS_LCDResInfo!=Panel1024x768){
+        	VCLKIndex = LCDXlatVCLK2[CRT2Index];
+      	} else {
+        	VCLKIndex = LCDXlatVCLK1[CRT2Index];
+      	}
+     } else {        /* for TV */
+      	if(SiS_VBInfo&SetCRT2ToTV) {
+        	if(SiS_IF_DEF_HiVision==1) {
+          		if(SiS_SetFlag&RPLLDIV2XO) {
+            			VCLKIndex=HiTVVCLKDIV2;
+            			if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+					/* VCLKIndex += 11;    for chip310  0x2E */
+              				VCLKIndex += 25;    /* for chip315  */
+            			}
+     			} else {
+            			VCLKIndex=HiTVVCLK;
+            			if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+					/*  VCLKIndex += 11;    for chip310  0x2E */
+              				VCLKIndex += 25;    /* for chip315  */
+            			}
+          		}
+          		if(SiS_SetFlag&TVSimuMode) {
+            			if(modeflag&Charx8Dot) {
+              				VCLKIndex=HiTVSimuVCLK;
+              					if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+							/*  VCLKIndex += 11;    for chip310  0x2E */
+              						VCLKIndex += 25;    /* for chip315  */
+              					}
+            			} else {
+              				VCLKIndex=HiTVTextVCLK;
+              				if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+						/*  VCLKIndex += 11;    for chip310  0x2E */
+              					VCLKIndex += 25;    /* for chip315  */
+              				}
+            			}
+          		}
+        	} else {
+          		if(SiS_VBInfo&SetCRT2ToTV) {
+            			if(SiS_SetFlag&RPLLDIV2XO) {
+              				VCLKIndex=TVVCLKDIV2;
+              					if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+							/* VCLKIndex += 11;    for chip310  0x2E */
+              						VCLKIndex += 25;    /* for chip315  */
+              					}
+            			} else {
+              				VCLKIndex=TVVCLK;
+              				if(HwDeviceExtension->jChipType >= SIS_315H) { /* 310 series */
+						/* VCLKIndex += 11;    for chip310  0x2E */
+              					VCLKIndex += 25;    /* for chip315  */
+              				}
+            			}
+          		}
+        	}
+      } else {    /* for CRT2 */
+        	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));      /*  Port 3cch */
+        	VCLKIndex =((VCLKIndex>>2)&0x03);
+        	if(ModeNo>0x13) {
+          		VCLKIndex =
+			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;    /* di+Ext_CRTVCLK */
+          		VCLKIndex = VCLKIndex&0x3f;
+        	}
+      }
+    }
+  } else {       /*   LVDS  */
+    	if(ModeNo<=0x13) VCLKIndex = CRT2Index;
+    	else VCLKIndex = CRT2Index;
+#ifdef LINUX_XF86
+	xf86DrvMsg(0, X_INFO, "CRT2Index = %d\n", CRT2Index);
+#endif
+	/* TW: This does not make sense: If CH7005 is there but CRT2 is set to
+	 *     LCD, VCLKindex is returned untouched...
+	 *     (Inserted SlaveMode check for 8bpp modes later)
+	 */
+
+#if 1
+    	if((SiS_IF_DEF_CH7005==1) && (!(SiS_VBInfo&SetInSlaveMode))) {
+      		if(!(SiS_VBInfo&SetCRT2ToLCD)) {
+#else
 
-void
-SiS_SetSwitchDDC2 (void)
-{
-	USHORT i;
+/* 	TW: If we do it this way instead, some machines (MITAC) have problems 		*/
+	if((SiS_IF_DEF_CH7005==1) && (SiS_VBInfo&SetCRT2ToTV)) {
+#endif
 
-	SiS_SetSCLKHigh ();
-	for (i = 0; i < 1000; i++) {
-		SiS_GetReg1 (SiS_DDC_Port, 0x05);
-	}
-	SiS_SetSCLKLow ();
-	for (i = 0; i < 1000; i++) {
-		SiS_GetReg1 (SiS_DDC_Port, 0x05);
-	}
+        		VCLKIndex = VCLKIndex&0x1f;
+        		tempbx=0;
+        		if(SiS_VBInfo&SetPALTV) tempbx=tempbx+2;
+        		if(SiS_VBInfo&SetCHTVOverScan) tempbx=tempbx+1;
+       			switch(tempbx) {
+          			case 0: CHTVVCLKPtr=SiS_CHTVVCLKUNTSC;
+					break;
+          			case 1: CHTVVCLKPtr=SiS_CHTVVCLKONTSC;
+					break;
+          			case 2: CHTVVCLKPtr=SiS_CHTVVCLKUPAL;
+					break;
+          			case 3: CHTVVCLKPtr=SiS_CHTVVCLKOPAL;
+					break;
+        		}
+        		VCLKIndex=CHTVVCLKPtr[VCLKIndex];
+      		}  
+    	} else {
+     		VCLKIndex = VCLKIndex>>6;
+     		if((SiS_LCDResInfo==Panel800x600)||(SiS_LCDResInfo==Panel320x480))
+     			VCLKIndex = LVDSXlat1VCLK[VCLKIndex]; /*fstn*/
+     		else if(SiS_LCDResInfo==Panel1024x768)
+     			VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+     		else 	VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
+    	}
+  }
+  if(HwDeviceExtension->jChipType < SIS_315H) { /* for300 serial*/
+    	VCLKIndex=VCLKIndex&0x3F;
+  }
+  return (VCLKIndex);
 }
 
 void
-SiS_SetStart (void)
-{
-
-	SiS_SetSCLKLow ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x02);	/*  SetSDA(0x01); */
-	SiS_SetSCLKHigh ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x00);	/* SetSDA(0x00); */
-	SiS_SetSCLKHigh ();
+SiS_SetGroup5(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,
+              USHORT ModeIdIndex)
+{
+  USHORT Pindex,Pdata;
+
+  Pindex=SiS_Part5Port;
+  Pdata=SiS_Part5Port+1;
+  if(SiS_ModeType==ModeVGA){
+    if(!(SiS_VBInfo&(SetInSlaveMode|LoadDACFlag|CRT2DisplayFlag))){
+      SiS_EnableCRT2();
+/*    LoadDAC2(ROMAddr,SiS_Part5Port,ModeNo,ModeIdIndex);  */
+    }
+  }
+  return;
+}
+
+void
+SiS_LoadDAC2(ULONG ROMAddr,USHORT SiS_Part5Port,
+             USHORT ModeNo,USHORT ModeIdIndex)
+{
+   USHORT data,data2;
+   USHORT time,i,j,k;
+   USHORT m,n,o;
+   USHORT si,di,bx,dl;
+   USHORT al,ah,dh;
+   USHORT *table=0;
+   USHORT Pindex,Pdata,modeflag;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+  }
+
+   Pindex=SiS_Part5Port;
+   Pdata=SiS_Part5Port+1;
+   data=modeflag&DACInfoFlag;
+   time=64;
+   if(data==0x00) table=SiS_MDA_DAC;
+   if(data==0x08) table=SiS_CGA_DAC;
+   if(data==0x10) table=SiS_EGA_DAC;
+   if(data==0x18) {
+     time=256;
+     table=SiS_VGA_DAC;
+   }
+   if(time==256) j=16;
+   else j=time;
+
+   SiS_SetReg3(Pindex,0x00);
+
+   for(i=0;i<j;i++) {
+      data=table[i];
+      for(k=0;k<3;k++) {
+        data2=0;
+        if(data&0x01) data2=0x2A;
+        if(data&0x02) data2=data2+0x15;
+        SiS_SetReg3(Pdata,data2);
+        data=data>>2;
+      }
+   }
+
+   if(time==256) {
+      for(i=16;i<32;i++) {
+         data=table[i];
+         for(k=0;k<3;k++) SiS_SetReg3(Pdata,data);
+      }
+      si=32;
+      for(m=0;m<9;m++) {
+         di=si;
+         bx=si+0x04;
+         dl=0;
+         for(n=0;n<3;n++) {
+            for(o=0;o<5;o++) {
+              dh=table[si];
+              ah=table[di];
+              al=table[bx];
+              si++;
+              SiS_WriteDAC2(Pdata,dl,ah,al,dh);
+            }         /* for 5 */
+            si=si-2;
+            for(o=0;o<3;o++) {
+              dh=table[bx];
+              ah=table[di];
+              al=table[si];
+              si--;
+              SiS_WriteDAC2(Pdata,dl,ah,al,dh);
+            }         /* for 3 */
+            dl++;
+         }            /* for 3 */
+         si=si+5;
+      }               /* for 9 */
+   }
+}
+
+void
+SiS_WriteDAC2(USHORT Pdata,USHORT dl, USHORT ah, USHORT al, USHORT dh)
+{
+  USHORT temp;
+  USHORT bh,bl;
+
+  bh=ah;
+  bl=al;
+  if(dl!=0) {
+    temp=bh;
+    bh=dh;
+    dh=temp;
+    if(dl==1) {
+       temp=bl;
+       bl=dh;
+       dh=temp;
+    }
+    else {
+       temp=bl;
+       bl=bh;
+       bh=temp;
+    }
+  }
+  SiS_SetReg3(Pdata,(USHORT)dh);
+  SiS_SetReg3(Pdata,(USHORT)bh);
+  SiS_SetReg3(Pdata,(USHORT)bl);
 }
 
+/* TW: Start of Chrontel 7005 functions ---------------------------- */
+
 void
-SiS_SetStop (void)
+SiS_SetCHTVReg(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+               USHORT RefreshRateTableIndex)
 {
-	SiS_SetSCLKLow ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x00);	/*  SetSDA(0x00); */
-	SiS_SetSCLKHigh ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x02);	/* SetSDA(0x01); */
-	SiS_SetSCLKHigh ();
+  USHORT temp,tempbx,tempcl;
+/*  USHORT CRT2CRTC; */
+  USHORT TVType,resindex;
+  SiS_CHTVRegDataStruct *CHTVRegData=NULL;
+
+  if(ModeNo<=0x13){
+    	tempcl = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  }else{
+    	tempcl = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+  TVType = 0;
+  if(SiS_VBInfo&SetPALTV) TVType=TVType+2;
+  if(SiS_VBInfo&SetCHTVOverScan) TVType=TVType+1;
+  switch(TVType) {
+    	case 0: CHTVRegData = SiS_CHTVReg_UNTSC; break;
+    	case 1: CHTVRegData = SiS_CHTVReg_ONTSC; break;
+    	case 2: CHTVRegData = SiS_CHTVReg_UPAL;  break;
+    	case 3: CHTVRegData = SiS_CHTVReg_OPAL;  break;
+  }
+  resindex=tempcl&0x3F;
+
+  /* TW: We don't support modes >800x600 */
+  if (resindex > 5) return;
+
+  if(SiS_VBInfo&SetPALTV) {
+    	SiS_SetCH7005(0x4304);  /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+    	SiS_SetCH7005(0x6909);	/* TW: Black level for PAL (105)*/
+  } else {
+    	SiS_SetCH7005(0x0304);  /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+    	SiS_SetCH7005(0x7109);	/* TW: Black level for NTSC (113)*/
+  }
+
+  temp = CHTVRegData[resindex].Reg[0];
+  tempbx=((temp&0x00FF)<<8)|0x00;	/* TW: Mode register */
+  SiS_SetCH7005(tempbx);
+  temp = CHTVRegData[resindex].Reg[1];
+  tempbx=((temp&0x00FF)<<8)|0x07;	/* TW: Start active video register */
+  SiS_SetCH7005(tempbx);
+  temp = CHTVRegData[resindex].Reg[2];
+  tempbx=((temp&0x00FF)<<8)|0x08;	/* TW: Position overflow register */
+  SiS_SetCH7005(tempbx);
+  temp = CHTVRegData[resindex].Reg[3];
+  tempbx=((temp&0x00FF)<<8)|0x0A;	/* TW: Horiz Position register */
+  SiS_SetCH7005(tempbx);
+  temp = CHTVRegData[resindex].Reg[4];
+  tempbx=((temp&0x00FF)<<8)|0x0B;	/* TW: Vertical Position register */
+  SiS_SetCH7005(tempbx);
+
+  /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
+             minimum text enhancement (S3-2=10),
+	     maximum flicker filter for Chroma channel (S5-4=10)
+	     =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
+   */
+  SiS_SetCH7005(0x2801);
+
+  /* TW: Set video bandwidth
+         High bandwith Luma composite video filter(S0=1)
+         low bandwith Luma S-video filter (S2-1=00)
+	 disable peak filter in S-video channel (S3=0)
+	 high bandwidth Chroma Filter (S5-4=11)
+	 =00110001=0x31
+  */
+  SiS_SetCH7005(0xb103);       /* old: 3103 */
+
+  /* TW: Register 0x3D does not exist in non-macrovision register map
+         (Maybe this is a macrovision register?)
+   */
+  /* SiS_SetCH7005(0x003D); */
+
+  /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
+         all other bits a read-only. Macrovision?
+   */
+  SiS_SetCHTVRegANDOR(0x0010,0x1F);
+
+  /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
+         contrast enhancement (set to 010 -> gain 2 Yout = 9/8*(Yin-57) )
+   */
+  SiS_SetCHTVRegANDOR(0x0211,0xF8);
+
+  /* TW: Clear DSEN
+   */
+  SiS_SetCHTVRegANDOR(0x001C,0xEF);
+
+  if(!(SiS_VBInfo&SetPALTV)) {		/* ---- NTSC ---- */
+    tempcl=tempcl&0x3F;
+    if(SiS_VBInfo&SetCHTVOverScan) {
+      if(tempcl==0x04) {   			/* 640x480 overscan: Mode 16 */
+      	SiS_SetCHTVRegANDOR(0x0020,0xEF);   	/* loop filter off */
+        SiS_SetCHTVRegANDOR(0x0121,0xFE);       /* ACIV on, no need to set FSCI */
+      } else {
+        if(tempcl==0x05) {    			/* 800x600 overscan: Mode 23 */
+          SiS_SetCHTVRegANDOR(0x0118,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
+          SiS_SetCHTVRegANDOR(0x0C19,0xF0);
+          SiS_SetCHTVRegANDOR(0x001A,0xF0);
+          SiS_SetCHTVRegANDOR(0x001B,0xF0);
+          SiS_SetCHTVRegANDOR(0x001C,0xF0);
+          SiS_SetCHTVRegANDOR(0x001D,0xF0);
+          SiS_SetCHTVRegANDOR(0x001E,0xF0);
+          SiS_SetCHTVRegANDOR(0x001F,0xF0);
+          SiS_SetCHTVRegANDOR(0x1020,0xEF);     /* Loop filter on for mode 23 */
+          SiS_SetCHTVRegANDOR(0x0021,0xFE);     /* ACIV off, need to set FSCI */
+        }
+      }
+    } else {
+      if(tempcl==0x04) {     			/* ----- 640x480 underscan; Mode 17 */
+        SiS_SetCHTVRegANDOR(0x0020,0xEF); 	/* loop filter off */
+        SiS_SetCHTVRegANDOR(0x0121,0xFE);
+      } else {
+        if(tempcl==0x05) {   			/* ----- 800x600 underscan: Mode 24 */
+          SiS_SetCHTVRegANDOR(0x0118,0xF0);     /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
+          SiS_SetCHTVRegANDOR(0x0919,0xF0);	/* FSCI for mode 24 is 428,554,851 */
+          SiS_SetCHTVRegANDOR(0x081A,0xF0);
+          SiS_SetCHTVRegANDOR(0x0b1B,0xF0);
+          SiS_SetCHTVRegANDOR(0x031C,0xF0);
+          SiS_SetCHTVRegANDOR(0x0a1D,0xF0);
+          SiS_SetCHTVRegANDOR(0x061E,0xF0);
+          SiS_SetCHTVRegANDOR(0x031F,0xF0);
+          SiS_SetCHTVRegANDOR(0x0020,0xEF);     /* loop filter off for mode 24 */
+          SiS_SetCHTVRegANDOR(0x0021,0xFE);	/* ACIV off, need to set FSCI */
+        }
+      }
+    }
+  } else {				/* ---- PAL ---- */
+        /* TW: We don't play around with FSCI in PAL mode */
+      if (tempcl==0x04) {
+        SiS_SetCHTVRegANDOR(0x0020,0xEF); 	/* loop filter off */
+        SiS_SetCHTVRegANDOR(0x0121,0xFE);       /* ACIV on */
+      } else {
+        SiS_SetCHTVRegANDOR(0x0020,0xEF); 	/* loop filter off */
+        SiS_SetCHTVRegANDOR(0x0121,0xFE);       /* ACIV on */
+      }
+  }
+}
+
+void
+SiS_SetCHTVRegANDOR(USHORT tempax,USHORT tempbh)
+{
+  USHORT tempal,tempah,tempbl;
+
+  tempal=tempax&0x00FF;
+  tempah=(tempax>>8)&0x00FF;
+  tempbl=SiS_GetCH7005(tempal);
+  tempbl=(((tempbl&tempbh)|tempah)<<8|tempal);  
+  SiS_SetCH7005(tempbl);
+}
+
+/* TW: Write to Chrontel 7005 */
+/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+void
+SiS_SetCH7005(USHORT tempbx)
+{
+  USHORT tempah,temp,i;
+
+  /* TW: This has to be relative to BaseAddr */
+  /* SiS_DDC_Port=0x3c4; */
+  SiS_DDC_Index=0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_DDC_DataShift=0x00;
+  SiS_DDC_DeviceAddr=0xEA;  		/* TW: DAB (Device Address Byte) */
+
+  for(i=0;i<50;i++) {	/* TW: Do only 50 attempts to write */
+    SiS_SetSwitchDDC2();
+    SiS_SetStart();			/* TW: Set start condition */
+    tempah=SiS_DDC_DeviceAddr;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    tempah=tempbx&0x00FF;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write RAB */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    tempah=(tempbx&0xFF00)>>8;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write data */
+    if(temp) continue;			/* TW:    (ERROR: no ack) */
+    SiS_SetStop();			/* TW: Set stop condition */
+    return;
+  }
 }
 
 USHORT
-SiS_WriteDDC2Data (USHORT tempax)
+SiS_GetCH7005(USHORT tempbx)
 {
-	USHORT i, flag, temp;
+  USHORT tempah,temp,i;
 
-	flag = 0x80;
-	for (i = 0; i < 8; i++) {
-		SiS_SetSCLKLow ();
-		if (tempax & flag) {
-			SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD,
-					 0x02);
-		} else {
-			SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD,
-					 0x00);
-		}
-		SiS_SetSCLKHigh ();
-		flag = flag >> 1;
-	}
-	temp = SiS_CheckACK ();
-	return (temp);
+  /* TW: This has to be relative to BaseAddr, set by RegInit */
+  /* SiS_DDC_Port=0x3c4; */
+  SiS_DDC_Index=0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_DDC_DataShift=0x00;
+  SiS_DDC_DeviceAddr=0xEA;		/* TW: DAB */
+  SiS_DDC_ReadAddr=tempbx;
+
+  for(i=0;i<50;i++) {	/* TW: Do only 50 attempts to write */
+    SiS_SetSwitchDDC2();
+    SiS_SetStart();			/* TW: Set start condition */
+    tempah=SiS_DDC_DeviceAddr;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    tempah=SiS_DDC_ReadAddr;		/* TW: Write RAB */
+    temp=SiS_WriteDDC2Data(tempah);
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    SiS_SetStart();			/* TW: Re-start */
+    tempah=SiS_DDC_DeviceAddr;
+    tempah=tempah|0x01;
+    temp=SiS_WriteDDC2Data(tempah);	/* TW: DAB (S0=1=read) */
+    if(temp) continue;			/* TW:        (ERROR: no ack) */
+    tempah=SiS_ReadDDC2Data(tempah);	/* TW: Read byte */
+    SiS_SetStop();			/* TW: Stop condition */
+    return(tempah);
+  }
+  return(tempah);
+}
+
+void
+SiS_SetSwitchDDC2(void)
+{
+  USHORT i;
+
+  SiS_SetSCLKHigh();
+  for(i=0;i<1000;i++) {
+    SiS_GetReg1(SiS_DDC_Port,0x05);
+  }
+  SiS_SetSCLKLow();
+  for(i=0;i<1000;i++) {
+    SiS_GetReg1(SiS_DDC_Port,0x05);
+  }
+}
+
+/* TW: Set Chrontel 7005 start condition */
+/* TW: This is done by a SD high-to-low transition while SC is high */
+void
+SiS_SetStart(void)
+{
+  SiS_SetSCLKLow();					  /* TW: (SC->low)  */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFD,0x02);  /* TW: SD->high */
+  SiS_SetSCLKHigh();					  /* TW: SC->high */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFD,0x00);  /* TW: SD->low = start condition */
+  SiS_SetSCLKHigh();					  /* TW: (SC->low) */
+}
+
+/* TW: Set Chrontel 7005 stop condition */
+/* TW: This is done by a SD low-to-high transition while SC is high */
+void
+SiS_SetStop(void)
+{
+  SiS_SetSCLKLow();					  /* TW: (SC->low) */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFD,0x00);  /* TW: SD->low   */
+  SiS_SetSCLKHigh();					  /* TW: SC->high  */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFD,0x02);  /* TW: SD->high = stop condition */   
+  SiS_SetSCLKHigh();					  /* TW: (SC->high) */
 }
 
+/* TW: Write 8 bits of data */
 USHORT
-SiS_ReadDDC2Data (USHORT tempax)
+SiS_WriteDDC2Data(USHORT tempax)
 {
-	USHORT i, temp, getdata;
+  USHORT i,flag,temp;
 
-	getdata = 0;
-	for (i = 0; i < 8; i++) {
-		getdata = getdata << 1;
-		SiS_SetSCLKLow ();
-		SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x02);
-		SiS_SetSCLKHigh ();
-		temp = SiS_GetReg1 (SiS_DDC_Port, SiS_DDC_Index);
-		if (temp & 0x02)
-			getdata = getdata | 0x01;
-	}
-	return (getdata);
+  flag=0x80;
+  for(i=0;i<8;i++) {
+    SiS_SetSCLKLow();					     /* TW: SC->low */
+    if(tempax&flag) {
+      SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFD,0x02); /* TW: Write bit (1) to SD */
+    } else {
+      SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFD,0x00); /* TW: Write bit (0) to SD */
+    }
+    SiS_SetSCLKHigh();					     /* TW: SC->high */
+    flag=flag>>1;
+  }
+  temp=SiS_CheckACK();					     /* TW: Check acknowledge */
+  return(temp);
 }
 
-void
-SiS_SetSCLKLow (void)
+USHORT
+SiS_ReadDDC2Data(USHORT tempax)
 {
-	USHORT temp;
+  USHORT i,temp,getdata;
 
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFE, 0x00);	/* SetSCLKLow()  */
-	do {
-		temp = SiS_GetReg1 (SiS_DDC_Port, SiS_DDC_Index);
-	} while (temp & 0x01);
-	SiS_DDC2Delay ();
+  getdata=0;
+  for(i=0;i<8;i++) {
+    getdata=getdata<<1;
+    SiS_SetSCLKLow();
+    SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFD,0x02);
+    SiS_SetSCLKHigh();
+    temp=SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
+    if(temp&0x02) getdata=getdata|0x01;
+  }
+  return(getdata);
 }
 
 void
-SiS_SetSCLKHigh (void)
+SiS_SetSCLKLow(void)
 {
-	USHORT temp;
+    USHORT temp;
 
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFE, 0x01);	/* SetSCLKHigh()  */
-	do {
-		temp = SiS_GetReg1 (SiS_DDC_Port, SiS_DDC_Index);
-	} while (!(temp & 0x01));
-	SiS_DDC2Delay ();
+    SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFE,0x00);      /* SetSCLKLow()  */
+    do {
+      temp=SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
+    } while(temp&0x01);
+    SiS_DDC2Delay();
 }
 
 void
-SiS_DDC2Delay (void)
+SiS_SetSCLKHigh(void)
 {
-	USHORT i;
+  USHORT temp;
 
-	for (i = 0; i < DDC2DelayTime; i++) {
-		SiS_GetReg1 (SiS_P3c4, 0x05);
-	}
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFE,0x01);      /* SetSCLKHigh()  */
+  do {
+    temp=SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
+  } while(!(temp&0x01));
+  SiS_DDC2Delay();
 }
 
-USHORT
-SiS_CheckACK (void)
+void
+SiS_DDC2Delay(void)
 {
-	USHORT tempah;
+  USHORT i;
 
-	SiS_SetSCLKLow ();
-	SiS_SetRegANDOR (SiS_DDC_Port, SiS_DDC_Index, 0xFD, 0x02);
-	SiS_SetSCLKHigh ();
-	tempah = SiS_GetReg1 (SiS_DDC_Port, SiS_DDC_Index);
-	SiS_SetSCLKLow ();
-	if (tempah & 0x02)
-		return (1);
-	else
-		return (0);
+   for(i=0;i<DDC2DelayTime;i++) {
+    SiS_GetReg1(SiS_P3c4,0x05);
+  }
 }
 
-void
-SiS_ModCRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex)
+/* TW: Check acknowledge */
+/* Returns 0 if ack ok, non-0 if ack not ok */
+USHORT
+SiS_CheckACK(void)
 {
-	USHORT temp, tempah, i, modeflag, j;
-	USHORT ResInfo, DisplayType;
-	SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
-
-	temp =
-	    SiS_GetLVDSCRT1Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &ResInfo, &DisplayType);
-	if (temp == 0) {
-		return;
-	}
-
-	switch (DisplayType) {
-	case 0:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;
-		break;
-	case 1:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;
-		break;
-	case 2:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;
-		break;
-	case 3:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;
-		break;
-	case 4:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;
-		break;
-	case 5:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;
-		break;
-	case 6:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;
-		break;
-	case 7:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;
-		break;
-	case 8:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;
-		break;
-	case 9:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;
-		break;
-	case 10:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;
-		break;
-	case 11:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;
-		break;
-	case 12:
-		LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;
-		break;
-	case 13:
-		LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;
-		break;
-	case 14:
-		LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;
-		break;
-	case 15:
-		LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;
-		break;
-	}
-
-	tempah = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);	/*unlock cr0-7  */
-	tempah = tempah & 0x7F;
-	SiS_SetReg1 (SiS_P3d4, 0x11, tempah);
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[0];
-	SiS_SetReg1 (SiS_P3d4, 0x0, tempah);
-	for (i = 0x02, j = 1; i <= 0x05; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x06, j = 5; i <= 0x07; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x10, j = 7; i <= 0x11; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x15, j = 9; i <= 0x16; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-
-	for (i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3c4, i, tempah);
-	}
+  USHORT tempah;
 
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[14];
-	tempah = tempah & 0x0E0;
-	SiS_SetReg1 (SiS_P3c4, 0x0E, tempah);
-
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[14];
-	tempah = tempah & 0x01;
-	tempah = tempah << 5;
-	if (modeflag & DoubleScanMode) {
-		tempah = tempah | 0x080;
-	}
-	SiS_SetRegANDOR (SiS_P3d4, 0x09, ~0x020, tempah);
-	return;
+  SiS_SetSCLKLow();					  /* TW: (SC->low) */
+  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,0xFD,0x02);  /* TW: (SD->high) */
+  SiS_SetSCLKHigh();					  /* TW: SC->high = clock impulse for ack */
+  tempah=SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);	  /* TW: Read SD */
+  SiS_SetSCLKLow();					  /* TW: SC->low = end of clock impulse */
+  if(tempah&0x02) return(1);				  /* TW: Ack OK if bit = 0 */
+  else return(0);
+}
+
+/* TW: End of Chrontel 7005 functions ---------------------------- */
+
+void
+SiS_ModCRT1CRTC(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex)
+{
+  USHORT temp,tempah,i,modeflag,j;
+  USHORT ResInfo,DisplayType;
+  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+  }
+
+  temp= SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                       &ResInfo,&DisplayType);
+  if(temp==0){
+    return;
+  }
+
+  switch(DisplayType) {
+    case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;           break;
+    case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
+    case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
+    case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
+    case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
+    case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
+    case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
+    case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
+    case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
+    case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
+    case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
+    case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
+    case 12: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
+    case 13: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
+    case 14: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
+    case 15: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
+    case 16: LVDSCRT1Ptr = SiS_LVDSCRT1320x480_1;           break;
+  }
+
+  tempah=(UCHAR)SiS_GetReg1(SiS_P3d4,0x11);                        /*unlock cr0-7  */
+  tempah=tempah&0x7F;
+  SiS_SetReg1(SiS_P3d4,0x11,tempah);
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
+  SiS_SetReg1(SiS_P3d4,0x0,tempah);
+  for(i=0x02,j=1;i<=0x05;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x06,j=5;i<=0x07;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x10,j=7;i<=0x11;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x15,j=9;i<=0x16;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x0A,j=11;i<=0x0C;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3c4,i,tempah);
+  }
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah=tempah&0x0E0;
+  SiS_SetReg1(SiS_P3c4,0x0E,tempah);
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah=tempah&0x01;
+  tempah=tempah<<5;
+  if(modeflag&DoubleScanMode){
+    	tempah=tempah|0x080;
+  }
+  SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
+  return;
 }
 
 /*301b*/
 void
-SiS_CHACRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex)
+SiS_CHACRT1CRTC(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex)
 {
-	USHORT temp, tempah, i, modeflag, j;
-	USHORT ResInfo, DisplayType;
-	SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-	}
-
-	temp =
-	    SiS_GetLVDSCRT1Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &ResInfo, &DisplayType);
-	if (temp == 0) {
-		return;
-	}
-
-	switch (DisplayType) {
-	case 0:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;
-		break;
-	case 1:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;
-		break;
-	case 2:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;
-		break;
-	case 3:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;
-		break;
-	case 4:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;
-		break;
-	case 5:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;
-		break;
-	case 6:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;
-		break;
-	case 7:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;
-		break;
-	case 8:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;
-		break;
-	case 9:
-		LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;
-		break;
-	case 10:
-		LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;
-		break;
-	case 11:
-		LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;
-		break;
-	case 12:
-		LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;
-		break;
-	case 13:
-		LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;
-		break;
-	case 14:
-		LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;
-		break;
-	case 15:
-		LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;
-		break;
-	}
-
-	tempah = (UCHAR) SiS_GetReg1 (SiS_P3d4, 0x11);	/*unlock cr0-7  */
-	tempah = tempah & 0x7F;
-	SiS_SetReg1 (SiS_P3d4, 0x11, tempah);
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[0];
-	SiS_SetReg1 (SiS_P3d4, 0x0, tempah);
-	for (i = 0x02, j = 1; i <= 0x05; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x06, j = 5; i <= 0x07; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x10, j = 7; i <= 0x11; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-	for (i = 0x15, j = 9; i <= 0x16; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3d4, i, tempah);
-	}
-
-	for (i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
-		tempah = (LVDSCRT1Ptr + ResInfo)->CR[j];
-		SiS_SetReg1 (SiS_P3c4, i, tempah);
-	}
-
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[14];
-	tempah = tempah & 0x0E0;
-	SiS_SetReg1 (SiS_P3c4, 0x0E, tempah);
-
-	tempah = (LVDSCRT1Ptr + ResInfo)->CR[14];
-	tempah = tempah & 0x01;
-	tempah = tempah << 5;
-	if (modeflag & DoubleScanMode) {
-		tempah = tempah | 0x080;
-	}
-	SiS_SetRegANDOR (SiS_P3d4, 0x09, ~0x020, tempah);
-	return;
+  USHORT temp,tempah,i,modeflag,j;
+  USHORT ResInfo,DisplayType;
+  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+  }
+
+  temp= SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                       &ResInfo,&DisplayType);
+  if(temp==0){
+    return;
+  }
+
+  switch(DisplayType) {
+    case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;           break;
+    case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
+    case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
+    case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
+    case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
+    case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
+    case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
+    case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
+    case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
+    case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
+    case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
+    case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
+    case 12: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
+    case 13: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
+    case 14: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
+    case 15: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
+  }
+
+  tempah=(UCHAR)SiS_GetReg1(SiS_P3d4,0x11);                        /*unlock cr0-7  */
+  tempah=tempah&0x7F;
+  SiS_SetReg1(SiS_P3d4,0x11,tempah);
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
+  SiS_SetReg1(SiS_P3d4,0x0,tempah);
+  for(i=0x02,j=1;i<=0x05;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x06,j=5;i<=0x07;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x10,j=7;i<=0x11;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+  for(i=0x15,j=9;i<=0x16;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3d4,i,tempah);
+  }
+
+  for(i=0x0A,j=11;i<=0x0C;i++,j++){
+    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+    SiS_SetReg1(SiS_P3c4,i,tempah);
+  }
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah=tempah&0x0E0;
+  SiS_SetReg1(SiS_P3c4,0x0E,tempah);
+
+  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah=tempah&0x01;
+  tempah=tempah<<5;
+  if(modeflag&DoubleScanMode){
+    	tempah=tempah|0x080;
+  }
+  SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
+  return;
 }
-
 /*add for LCDA*/
 
 BOOLEAN
-SiS_GetLCDACRT1Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex, USHORT * ResInfo,
-		    USHORT * DisplayType)
-{
-	USHORT tempbx = 0, modeflag = 0;
-	USHORT CRT2CRTC = 0;
-	/*301b */
-	if (((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-	    && (SiS_VBInfo & SetCRT2ToLCDA)) {
-		tempbx = SiS_LCDResInfo;
-		tempbx -= Panel800x600;
-		if (SiS_LCDInfo & LCDNonExpanding)
-			tempbx += 6;
-		if (modeflag & HalfDCLK)
-			tempbx += +3;
-		if (ModeNo <= 0x13) {
-			modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-			CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-		} else {
-			modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-			CRT2CRTC =
-			    SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		}
-	}
-	*ResInfo = CRT2CRTC & 0x3F;
-	*DisplayType = tempbx;
-	return 1;
+SiS_GetLCDACRT1Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
+		   USHORT *DisplayType)
+ {
+  USHORT tempbx=0,modeflag=0;
+  USHORT CRT2CRTC=0;
+ /*301b*/
+  if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+                    &&(SiS_VBInfo&SetCRT2ToLCDA) ) {
+    	tempbx = SiS_LCDResInfo;
+    	tempbx -= Panel800x600;
+    	if(SiS_LCDInfo&LCDNonExpanding) tempbx +=6;
+#if 0   /* TW: That can't work - test modeflag BEFORE reading it? */
+    	if(modeflag&HalfDCLK) tempbx +=+3;
+#endif
+    	if(ModeNo<=0x13) {
+    		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    		CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  	} else {
+    		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    		CRT2CRTC = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  	}
+	/* TW: This belongs here I assume */
+	if(modeflag&HalfDCLK) tempbx +=+3;
+  }
+  *ResInfo = CRT2CRTC&0x3F;
+  *DisplayType = tempbx;
+  return 1;
 }
-
 /*end for 301b*/
 
 BOOLEAN
-SiS_GetLVDSCRT1Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex, USHORT * ResInfo,
-		    USHORT * DisplayType)
-{
-	USHORT tempbx, modeflag = 0;
-	USHORT Flag, CRT2CRTC;
-
-	if (ModeNo <= 0x13) {
-		modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;	/* si+St_ResInfo */
-		CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;	/* si+Ext_ResInfo */
-		CRT2CRTC = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		return 0;
-	}
-	Flag = 1;
-	tempbx = 0;
-	if (SiS_IF_DEF_CH7005 == 1) {
-		if (!(SiS_VBInfo & SetCRT2ToLCD)) {
-			Flag = 0;
-			tempbx = 12;
-			if (SiS_VBInfo & SetPALTV)
-				tempbx += 2;
-			if (SiS_VBInfo & SetCHTVOverScan)
-				tempbx += 1;
-		}
-	}
-	if (Flag) {
-		tempbx = SiS_LCDResInfo;
-		tempbx -= Panel800x600;
-		if (SiS_LCDInfo & LCDNonExpanding)
-			tempbx += 6;
-		if (modeflag & HalfDCLK)
-			tempbx += +3;
-	}
-
-	*ResInfo = CRT2CRTC & 0x3F;
-	*DisplayType = tempbx;
-	return 1;
+SiS_GetLVDSCRT1Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType)
+ {
+  USHORT tempbx,modeflag=0;
+  USHORT Flag,CRT2CRTC;
+ 
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    	CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    	CRT2CRTC = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+  if(!(SiS_VBInfo&SetInSlaveMode)){
+     return 0;
+  }
+  Flag=1;
+  tempbx=0;
+  if(SiS_IF_DEF_CH7005==1) {
+    if(!(SiS_VBInfo&SetCRT2ToLCD)) {
+      Flag=0;
+      tempbx =12;
+      if(SiS_VBInfo&SetPALTV) tempbx +=2;
+      if(SiS_VBInfo&SetCHTVOverScan) tempbx +=1;
+    }
+  }
+  if(Flag) {
+    tempbx =SiS_LCDResInfo;
+    tempbx -=Panel800x600;
+    if(SiS_LCDInfo&LCDNonExpanding) tempbx +=6;
+    if(modeflag&HalfDCLK) tempbx +=+3;
+  }
+  /*fstn*/
+   if(SiS_IF_DEF_FSTN){
+     if(SiS_LCDResInfo==Panel320x480){
+       tempbx=0x10;         /*not same with asmber code */
+     }
+   }
+  *ResInfo = CRT2CRTC&0x3F;
+  *DisplayType = tempbx;
+  return 1;
 }
 
 void
-SiS_SetCRT2ECLK (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		 USHORT RefreshRateTableIndex,
-		 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-	USHORT tempah, tempal;
-	USHORT P3cc = SiS_P3c9 + 3;
-	USHORT vclkindex = 0;
-
-	if (SiS_IF_DEF_TRUMPION == 0) {	/*no trumpion  */
-		tempal = SiS_GetReg2 (P3cc);
-		tempal = tempal & 0x0C;
-		vclkindex =
-		    SiS_GetVCLK2Ptr (ROMAddr, ModeNo, ModeIdIndex,
-				     RefreshRateTableIndex, HwDeviceExtension);
-	} else {		/*trumpion  */
-		SiS_SetFlag = SiS_SetFlag & (~ProgrammingCRT2);
-/*  tempal=*((UCHAR *)(ROMAddr+SiS_RefIndex+0x03));     &di+Ext_CRTVCLK  */
-		tempal = tempal & 0x03F;
-		if (tempal == 0x02) {	/*31.5MHz  */
-/*      SiS_RefIndex=SiS_RefIndex-Ext2StructSize;   */
-		}
-/*    SiS_RefIndex=GetVCLKPtr(ROMAddr,ModeNo);  */
-		SiS_SetFlag = SiS_SetFlag | ProgrammingCRT2;
-	}
-	tempal = 0x02B;
-	if (!(SiS_VBInfo & SetInSlaveMode)) {
-		tempal = tempal + 3;
-	}
-	SiS_SetReg1 (SiS_P3c4, 0x05, 0x86);
-	tempah = SiS_VCLKData[vclkindex].SR2B;
-	SiS_SetReg1 (SiS_P3c4, tempal, tempah);
-	tempal++;
-	tempah = SiS_VCLKData[vclkindex].SR2C;
-	SiS_SetReg1 (SiS_P3c4, tempal, tempah);
-	tempal++;
-	SiS_SetReg1 (SiS_P3c4, tempal, 0x80);
-	return;
+SiS_SetCRT2ECLK(ULONG ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+           USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempah,tempal;
+  USHORT P3cc=SiS_P3c9+3;
+  USHORT vclkindex=0;
+
+  if(SiS_IF_DEF_TRUMPION==0){  /*no trumpion  */
+    	tempal=SiS_GetReg2(P3cc);
+    	tempal=tempal&0x0C;
+    	vclkindex=SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+                               RefreshRateTableIndex,HwDeviceExtension);
+  } else {  			/*trumpion  */
+    	SiS_SetFlag=SiS_SetFlag&(~ProgrammingCRT2);
+/*  	tempal=*((UCHAR *)(ROMAddr+SiS_RefIndex+0x03));     &di+Ext_CRTVCLK  */
+    	tempal=tempal&0x03F;
+    	if(tempal==0x02){ /*31.5MHz  */
+/*      	SiS_RefIndex=SiS_RefIndex-Ext2StructSize;   */
+    	}
+/*    	SiS_RefIndex=GetVCLKPtr(ROMAddr,ModeNo);  */
+    	SiS_SetFlag=SiS_SetFlag|ProgrammingCRT2;
+  }
+  tempal=0x02B;
+  if(!(SiS_VBInfo&SetInSlaveMode)){
+    	tempal=tempal+3;
+  }
+  SiS_SetReg1(SiS_P3c4,0x05,0x86);
+  tempah = SiS_VCLKData[vclkindex].SR2B;
+  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  tempal++;
+  tempah = SiS_VCLKData[vclkindex].SR2C;
+  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  tempal++;
+  SiS_SetReg1(SiS_P3c4,tempal,0x80);
+  return;
 }
 
 void
-SiS_SetDefCRT2ExtRegs (USHORT BaseAddr)
-{
-	USHORT temp;
-
-	if (SiS_IF_DEF_LVDS == 0) {
-		SiS_SetReg1 (SiS_Part1Port, 0x02, 0x40);
-		SiS_SetReg1 (SiS_Part4Port, 0x10, 0x80);
-		temp = (UCHAR) SiS_GetReg1 (SiS_P3c4, 0x16);
-		temp = temp & 0xC3;
-		SiS_SetReg1 (SiS_P3d4, 0x35, temp);
-	} else {
-		SiS_SetReg1 (SiS_P3d4, 0x32, 0x02);
-		SiS_SetReg1 (SiS_Part1Port, 0x02, 0x00);
-	}
+SiS_SetDefCRT2ExtRegs(USHORT BaseAddr)
+{
+  USHORT  temp;
+
+  if(SiS_IF_DEF_LVDS==0) {
+    SiS_SetReg1(SiS_Part1Port,0x02,0x40);
+    SiS_SetReg1(SiS_Part4Port,0x10,0x80);
+    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
+    temp=temp&0xC3;
+    SiS_SetReg1(SiS_P3d4,0x35,temp);
+  }
+  else {
+    SiS_SetReg1(SiS_P3d4,0x32,0x02);
+    SiS_SetReg1(SiS_Part1Port,0x02,0x00);
+  }
 }
 
-#ifdef CONFIG_FB_SIS_315
+#ifdef SIS315H
 /*
     for SIS310 O.E.M.
 */
@@ -5421,19 +5210,21 @@
 USHORT
 GetLCDPtrIndex (void)
 {
-	USHORT index;
+   USHORT index;
 
-	index = (SiS_LCDResInfo & 0x0F) - 1;
-	index *= 3;
-	if (SiS_LCDInfo & LCDNonExpanding)
-		index += 2;
-	else {
-		if (!(SiS_LCDInfo & LCDVESATiming))
-			index++;
-	}
+   index = (SiS_LCDResInfo & 0x0F)-1;
+   index *= 3;
+   if (SiS_LCDInfo&LCDNonExpanding)
+      index += 2;
+   else
+   {
+     if (!(SiS_LCDInfo&LCDVESATiming))
+       index++;
+   }
+
+  return index;
+ }
 
-	return index;
-}
 
 /*
 ---------------------------------------------------------
@@ -5447,555 +5238,573 @@
 ---------------------------------------------------------
 */
 USHORT
-GetTVPtrIndex (void)
+GetTVPtrIndex(void)
 {
-	USHORT index;
+  USHORT index;
 
-	index = 0;
-	if (SiS_VBInfo & SetPALTV)
-		index++;
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV)	/* Hivision TV use PAL */
-		index++;
-	index *= 2;
-
-	if ((SiS_VBInfo & SetInSlaveMode) && (SiS_SetFlag & TVSimuMode))
-		index++;
-
-	return index;
+  index = 0;
+  if (SiS_VBInfo&SetPALTV)
+    index++;
+  if (SiS_VBInfo&SetCRT2ToHiVisionTV)  /* Hivision TV use PAL */
+    index++;
+  index *= 2;
+
+  if ((SiS_VBInfo&SetInSlaveMode)&&(SiS_SetFlag&TVSimuMode))
+    index++;
+
+  return index;
 }
 
 void
-SetDelayComp (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	      ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part1Port;
-	USHORT delay, index;
-
-	if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-		delay = SiS310_CRT2DelayCompensation1;
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-			delay = SiS310_CRT2DelayCompensation2;
-	} else if (SiS_VBInfo & SetCRT2ToLCD) {
-		index = GetLCDPtrIndex ();
-		delay = SiS310_LCDDelayCompensation1[index];
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-			delay = SiS310_LCDDelayCompensation2[index];
-	} else {
-		index = GetTVPtrIndex ();
-		delay = SiS310_TVDelayCompensation1[index];
-		if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B))
-			delay = SiS310_TVDelayCompensation2[index];
-	}
-
-	Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	SiS_SetRegANDOR (Part1Port, 0x2D, ~0x0F, delay);	/* index 2D D[3:0] */
-
+SetDelayComp(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             ULONG ROMAddr,USHORT ModeNo)
+{
+  USHORT Part1Port;
+  USHORT delay,index;
+
+  if (SiS_VBInfo&SetCRT2ToRAMDAC)
+  {
+     delay = SiS310_CRT2DelayCompensation1;
+     if (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+       delay = SiS310_CRT2DelayCompensation2;
+  }
+  else
+    if (SiS_VBInfo&SetCRT2ToLCD)
+    {
+       index = GetLCDPtrIndex();
+       delay = SiS310_LCDDelayCompensation1[index];
+       if (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+         delay = SiS310_LCDDelayCompensation2[index];
+    }
+    else
+    {
+       index = GetTVPtrIndex();
+       delay = SiS310_TVDelayCompensation1[index];
+       if (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+         delay = SiS310_TVDelayCompensation2[index];
+    }
+  Part1Port=BaseAddr+SIS_CRT2_PORT_04;
+  SiS_SetRegANDOR(Part1Port,0x2D,~0x0F,delay);  /* index 2D D[3:0] */
 }
 
 /*
 */
 void
-SetAntiFlicker (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT Part2Port;
-	USHORT index, temp;
-
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	temp = GetTVPtrIndex ();
-	temp = (temp >> 1);	/* 0: NTSC, 1 :PAL, 2:HiTV */
-	if (ModeNo <= 0x13) {
-		index = SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
-	} else {
-		index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
-	}
-	temp = SiS310_TVAntiFlick1[temp][index];
-	temp <<= 4;
-
-	SiS_SetRegANDOR (Part2Port, 0x0A, ~0x70, temp);	/* index 0A D[6:4] */
-
-}
-
-void
-SetEdgeEnhance (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	USHORT Part2Port;
-	USHORT index, temp;
-
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	temp = GetTVPtrIndex ();
-	temp = (temp >> 1);	/* 0: NTSC, 1 :PAL, 2:HiTV */
-	if (ModeNo <= 0x13) {
-		index = SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;	/* si+VB_StTVEdgeIndex */
-	} else {
-		index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;	/* si+VB_ExtTVEdgeIndex */
-	}
-	temp = SiS310_TVEdge1[temp][index];
-	temp <<= 5;
-
-	SiS_SetRegANDOR (Part2Port, 0x3A, ~0xE0, temp);	/* index 0A D[7:5] */
-
-}
-
-void
-SetYFilter (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	    ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SetAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-	USHORT Part2Port, temp1, temp2;
-	USHORT index, temp, i, index1;
-	UCHAR OutputSelect = *pSiS_OutputSelect;
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	temp = GetTVPtrIndex ();
-	temp >>= 1;		/* 0: NTSC, 1 :PAL, 2:HiTV */
-
-	if (ModeNo <= 0x13) {
-		index = SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
-	} else {
-		index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
-	}
-
-	if (SiS_VBInfo & SetCRT2ToHiVisionTV)	/* Hivision TV use PAL */
-		temp = 0;
+  USHORT Part2Port;
+  USHORT index,temp;
 
-	/*301b */
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		for (i = 0x35; i <= 0x38; i++) {
-			SiS_SetReg1 (Part2Port, i,
-				     SiS310_TVYFilter2[temp][index][i - 0x35]);
-		}
-		for (i = 0x48; i <= 0x4A; i++) {
-			SiS_SetReg1 (Part2Port, i,
-				     SiS310_TVYFilter2[temp][index][(i - 0x48) +
-								    0x04]);
-		}
-	}
-	/*end 301b */
-	else {
-		for (i = 0x35; i <= 0x38; i++) {
-			SiS_SetReg1 (Part2Port, i,
-				     SiS310_TVYFilter1[temp][index][i - 0x35]);
-		}
-	}
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+  temp = GetTVPtrIndex();
+  temp = (temp>>1);  /* 0: NTSC, 1 :PAL, 2:HiTV */
+  if (ModeNo<=0x13)
+  {
+    index = SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
+  }
+  else
+  {
+    index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
+  }
+  temp = SiS310_TVAntiFlick1[temp][index];
+  temp  <<= 4;
+
+  SiS_SetRegANDOR(Part2Port,0x0A,~0x70,temp);  /* index 0A D[6:4] */
+
+}
+
+void
+SetEdgeEnhance (PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT Part2Port;
+  USHORT index,temp;
+
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+  temp = GetTVPtrIndex();
+  temp = (temp>>1);   /* 0: NTSC, 1 :PAL, 2:HiTV */
+  if (ModeNo<=0x13)
+  {
+    index = SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;   /* si+VB_StTVEdgeIndex */
+  }
+  else
+  {
+    index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;  /* si+VB_ExtTVEdgeIndex */
+  }
+  temp = SiS310_TVEdge1[temp][index];
+  temp  <<= 5;
+
+  SiS_SetRegANDOR(Part2Port,0x3A,~0xE0,temp);  /* index 0A D[7:5] */
+
+}
+
+void
+SetYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+           ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT Part2Port,temp1,temp2;
+  USHORT index,temp,i,index1;
+  UCHAR  OutputSelect=*pSiS_OutputSelect;
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+  temp = GetTVPtrIndex();
+  temp >>= 1;  /* 0: NTSC, 1 :PAL, 2:HiTV */
+
+  if (ModeNo<=0x13)
+  {
+    index =  SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+  }
+  else
+  {
+    index =  SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+  }
+
+  if (SiS_VBInfo&SetCRT2ToHiVisionTV)  /* Hivision TV use PAL */
+   temp = 0;
+
+  /*301b*/
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+    for(i=0x35;i<=0x38;i++)
+   {
+     SiS_SetReg1(Part2Port,i,SiS310_TVYFilter2[temp][index][i-0x35]);
+   }
+   for(i=0x48;i<=0x4A;i++)
+   {
+     SiS_SetReg1(Part2Port,i,SiS310_TVYFilter2[temp][index][(i-0x48)+0x04]);
+   }
+  }
+      /*end 301b*/
+  else{
+   for(i=0x35;i<=0x38;i++)
+   {
+     SiS_SetReg1(Part2Port,i,SiS310_TVYFilter1[temp][index][i-0x35]);
+   }
+  }
 /*add PALMN*/
-	if (OutputSelect & EnablePALMN) {
-		index1 = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp1 = index1 & 0x01;
-		index1 = SiS_GetReg1 (SiS_P3d4, 0x38);
-		temp2 = index1 & 0xC0;
-		if (temp1) {
-			if (temp2 == 0x40) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) {
-					for (i = 0x35; i <= 0x38; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALMFilter2
-							     [index][i - 0x35]);
-					}
-					for (i = 0x48; i <= 0x4A; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALMFilter2
-							     [index][(i - 0x48)
-								     + 0x04]);
-					}
-				} else {
-					for (i = 0x35; i <= 0x38; i++)
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALMFilter
-							     [index][i - 0x35]);
-				}
-			}
-			if (temp2 == 0x80) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) {
-					for (i = 0x35; i <= 0x38; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALNFilter2
-							     [index][i - 0x35]);
-					}
-					for (i = 0x48; i <= 0x4A; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALNFilter2
-							     [index][(i - 0x48)
-								     + 0x04]);
-					}
-				} else {
-					for (i = 0x35; i <= 0x38; i++)
-						SiS_SetReg1 (Part2Port, i,
-							     SiS310_PALNFilter
-							     [index][i - 0x35]);
-				}
-			}
-		}
-	}
-	/*end PALMN */
-}
-
-void
-SetPhaseIncr (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	      ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part2Port;
-	USHORT index, temp, temp1, i;
-
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	temp = GetTVPtrIndex ();
-	/* 0: NTSC Graphics, 1: NTSC Text, 2 :PAL Graphics, 3 :PAL Text, 4:HiTV Graphics 5:HiTV Text */
-	index = temp % 2;
-	temp >>= 1;		/* 0: NTSC, 1 :PAL, 2:HiTV */
-	temp1 = SiS_GetReg1 (SiS_P3d4, 0x38);	/*if PALMN Not Set */
-	temp1 = temp1 & 0xC0;
-	if (!temp1) {
-		for (i = 0x31; i <= 0x34; i++) {
-			if ((SiS_VBType & VB_SIS301B)
-			    || (SiS_VBType & VB_SIS302B))
-				    SiS_SetReg1 (Part2Port, i,
-						 SiS310_TVPhaseIncr2[temp]
-						 [index][i - 0x31]);
-			else
-				SiS_SetReg1 (Part2Port, i,
-					     SiS310_TVPhaseIncr1[temp][index][i
-									      -
-									      0x31]);
-		}
-	}
-}
-void
-SiS_OEM310Setting (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		   ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-{
-	SetDelayComp (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		SetAntiFlicker (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo,
-				ModeIdIndex);
-		SetPhaseIncr (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-		SetYFilter (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo,
-			    ModeIdIndex);
-		SetEdgeEnhance (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo,
-				ModeIdIndex);
-	}
+    if(OutputSelect&EnablePALMN) {                  
+      index1=SiS_GetReg1(SiS_P3d4,0x31);
+      temp1=index1&0x01;
+      index1=SiS_GetReg1(SiS_P3d4,0x38);
+      temp2=index1&0xC0;
+      if(temp1){
+         if(temp2==0x40){
+              if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+                 for(i=0x35;i<=0x38;i++){
+                      SiS_SetReg1(Part2Port,i,SiS310_PALMFilter2[index][i-0x35]);
+                     }
+                 for(i=0x48;i<=0x4A;i++) {
+                       SiS_SetReg1(Part2Port,i,SiS310_PALMFilter2[index][(i-0x48)+0x04]);
+                     }
+                }
+              else{ 
+                 for(i=0x35;i<=0x38;i++)
+                 SiS_SetReg1(Part2Port,i,SiS310_PALMFilter[index][i-0x35]);
+                 } 
+             }
+         if(temp2==0x80){ 
+              if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+                 for(i=0x35;i<=0x38;i++){
+                      SiS_SetReg1(Part2Port,i,SiS310_PALNFilter2[index][i-0x35]);
+                     }
+                 for(i=0x48;i<=0x4A;i++) {
+                       SiS_SetReg1(Part2Port,i,SiS310_PALNFilter2[index][(i-0x48)+0x04]);
+                     }
+             }
+              else{
+                 for(i=0x35;i<=0x38;i++)
+                 SiS_SetReg1(Part2Port,i,SiS310_PALNFilter[index][i-0x35]);
+                }
+          }
+      }
+    }
+    /*end PALMN*/
+}
+
+void
+SetPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             ULONG ROMAddr,USHORT ModeNo)
+{
+  USHORT Part2Port;
+  USHORT index,temp,temp1,i;
+
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+  temp = GetTVPtrIndex();
+  /* 0: NTSC Graphics, 1: NTSC Text, 2 :PAL Graphics, 3 :PAL Text, 4:HiTV Graphics 5:HiTV Text */
+  index = temp % 2;
+  temp >>= 1;   /* 0: NTSC, 1 :PAL, 2:HiTV */
+  temp1=SiS_GetReg1(SiS_P3d4,0x38);        /*if PALMN Not Set*/
+  temp1=temp1&0xC0; 
+  if(!temp1){
+  	for(i=0x31;i<=0x34;i++)
+  	{
+    		if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+     			SiS_SetReg1(Part2Port,i,SiS310_TVPhaseIncr2[temp][index][i-0x31]);
+    		else
+     			SiS_SetReg1(Part2Port,i,SiS310_TVPhaseIncr1[temp][index][i-0x31]);
+  	}
+  }
+}
+
+void
+SiS_OEM310Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                  ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+   SetDelayComp(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+   if (SiS_VBInfo&SetCRT2ToTV) {
+       SetAntiFlicker(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetPhaseIncr(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+       SetYFilter(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetEdgeEnhance(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+   }
 }
 
 #endif
 
-#ifdef CONFIG_FB_SIS_300
+#ifdef SIS300
 /*
     for SIS300 O.E.M.
 */
 
 USHORT
-GetRevisionID (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+GetRevisionID(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-#ifdef CONFIG_FB_SIS_300
-	ULONG temp1, base;
-	USHORT temp2 = 0;
-	/* add to set SR14 */
-	if ((HwDeviceExtension->jChipType == SIS_540) ||
-	    (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		base = 0x80000008;
-		OutPortLong (base, 0xcf8);
-		temp1 = InPortLong (0xcfc);
-		temp1 = temp1 & 0x000000FF;
-		temp2 = (USHORT) (temp1);
-		return temp2;
-	}
-#endif
+   ULONG temp1,base;
+   USHORT temp2=0; 
+   
+   if((HwDeviceExtension->jChipType==SIS_540)||
+      (HwDeviceExtension->jChipType==SIS_630)||
+      (HwDeviceExtension->jChipType==SIS_730)) {
+     	base=0x80000008;
+     	OutPortLong(base,0xcf8);
+     	temp1=InPortLong(0xcfc);
+     	temp1=temp1&0x000000FF;
+     	temp2=(USHORT)(temp1);
+    	return temp2;
+   }
+   return 0;
 }
 
 USHORT
-GetOEMLCDPtr (PSIS_HW_DEVICE_INFO HwDeviceExtension)
+GetOEMTVPtr(void)
 {
-	USHORT temp, tempbx = 0, tempax;
+  USHORT index;
 
-	if (SiS_IF_DEF_LVDS == 0) {
-		if (SiS_VBInfo & SetCRT2ToLCD) {	/* LCD */
-			tempax = SiS_LCDResInfo;
-			tempbx = SiS_LCDResInfo;
-			tempbx = tempbx - Panel1024x768;
-			if (!(SiS_SetFlag & LCDVESATiming)) {
-				tempbx += 4;
-				temp = GetRevisionID (HwDeviceExtension);
-				if ((HwDeviceExtension->jChipType == SIS_540)
-				    && (temp < 1))
-					tempbx += 4;
-				if ((HwDeviceExtension->jChipType == SIS_630)
-				    && (temp < 3))
-					tempbx += 4;
-			}
-			if ((tempax == Panel1024x768)
-			    && (SiS_LCDInfo == LCDNonExpanding)) {
-				tempbx = tempbx + 3;
-			}
-			/*add OEMLCDPanelIDSupport */
-			tempbx = SiS_LCDTypeInfo;
-			tempbx = tempbx << 1;
-			if (!(SiS_SetFlag & LCDVESATiming))
-				tempbx = tempbx + 1;
-		}
-	}
-	tempbx *= 2;
-	return tempbx;
+  index = 0;
+  if (!(SiS_VBInfo&SetInSlaveMode))
+      	index=index+4;
+  
+  if (SiS_VBInfo&SetCRT2ToSCART){
+      	index=index+2;
+  } else {
+     	if (SiS_VBInfo&SetCRT2ToHiVisionTV)
+       		index=index+3;
+     	else {
+          	if(SiS_VBInfo&SetPALTV)
+          		index=index+1;
+        }
+  }
+  return index;
+}
+
+/* TW: This is not for LVDS/Chrontel */
+void
+SetOEMTVDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              ULONG ROMAddr,USHORT ModeNo)
+{
+  USHORT Part1Port;
+  USHORT index,temp,ModeIdIndex;
+
+  Part1Port=BaseAddr+SIS_CRT2_PORT_04;
+  ModeIdIndex=SiS_SearchVBModeID(ROMAddr,ModeNo);
+  temp = GetOEMTVPtr();
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
+  temp = SiS300_OEMTVDelay[temp][index];
+  temp=temp&0x3c;
+  SiS_SetRegANDOR(Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
 }
 
 USHORT
-GetOEMTVPtr (void)
+GetOEMLCDPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-	USHORT index;
+  /* USHORT temp,tempax; */
+  USHORT tempbx=0;
 
-	index = 0;
-	if (!(SiS_VBInfo & SetInSlaveMode))
-		index = index + 4;
+  if(SiS_IF_DEF_LVDS==0) {
+#if 0
+  	tempax=tempbx=SiS_LCDResInfo;
+      	tempbx=tempbx-Panel1024x768;
+     	if(!(SiS_SetFlag&LCDVESATiming)) {
+        	tempbx+=4;
+        	temp=GetRevisionID(HwDeviceExtension);
+        	if((HwDeviceExtension->jChipType == SIS_540)&&(temp<1))
+        		tempbx+=4;
+        	if((HwDeviceExtension->jChipType == SIS_630)&&(temp<3))
+        		tempbx+=4;
+       	}
+     	if((tempax==Panel1024x768)&&(SiS_LCDInfo&LCDNonExpanding)){
+        	tempbx=tempbx+3;
+       	}
+#endif
 
-	if (SiS_VBInfo & SetCRT2ToSCART) {
-		index = index + 2;
-	} else {
-		if (SiS_VBInfo & SetCRT2ToHiVisionTV)
-			index = index + 3;
-		else {
-			if (SiS_VBInfo & SetPALTV)
-				index = index + 1;
-		}
-	}
-	return index;
+	/* TW: This is total bullshit. First, we calculate tempbx, now
+	 *     we overwrite it?! (Therefore commented code above)
+	 */
+
+     	/*add OEMLCDPanelIDSupport*/
+        tempbx=SiS_LCDTypeInfo;
+
+#if 0   /* TW: Commented for DEBUG: */
+        tempbx=tempbx<<1;
+        if(!(SiS_SetFlag&LCDVESATiming))
+        	tempbx=tempbx+1;
+	tempbx*=2;
+	/* TW: The above code results in eg. 0xc * 2 * 2 = 48, but Delay2 table has
+	 *     only 32 entries. Thus, this can't work */
+#endif
+        /* TW: Don't think that 301(B) bridges need different LCD delay... */
+  	tempbx = SiS_LCDTypeInfo;
+	if(SiS_LCDInfo&LCDNonExpanding){
+      		tempbx=tempbx+16;
+	}
+  } else {  /* TW: Added LVDS code */
+  	tempbx = SiS_LCDTypeInfo;
+	if(SiS_LCDInfo&LCDNonExpanding){
+      		tempbx=tempbx+16;
+	}
+  }
+  return tempbx;
+}
+
+#if 0
+/* TW: Original code - can't work (eg. exceeds arrays by re-using temp,
+       writes to Part2(!)Port unlike TVDelay, etc...) */
+void
+SetOEMLCDDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               ULONG ROMAddr,USHORT ModeNo)
+{
+  USHORT Part2Port;
+  USHORT index,temp,ModeIdIndex;
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+  ModeIdIndex=SiS_SearchVBModeID(ROMAddr,ModeNo);
+  temp = GetOEMLCDPtr(HwDeviceExtension);
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
+  temp = SiS300_OEMLCDDelay1[temp][index];
+   /*add OEMLCDPanelIDSupport*/
+  temp = SiS300_OEMLCDDelay2[temp][index];
+  temp=temp&0x3c;
+  SiS_SetRegANDOR(Part2Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
 }
+#endif
 
-void
-SetOEMTVDelay (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	       ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part1Port;
-	USHORT index, temp, ModeIdIndex;
-	Part1Port = BaseAddr + SIS_CRT2_PORT_04;
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	temp = GetOEMTVPtr ();
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
-	temp = SiS300_OEMTVDelay[temp][index];
-	temp = temp & 0x3c;
-	SiS_SetRegANDOR (Part1Port, 0x13, ~0x3C, temp);	/* index 0A D[6:4] */
-}
+/* TW: Although I assume that the code above does not work correctly,
+ *     I won't change it for non-LVDS machines until someone tells me so.
+ */
+void
+SetOEMLCDDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               ULONG ROMAddr,USHORT ModeNo)
+{
+  USHORT Part1Port, Part2Port;
+  USHORT index,temp,ModeIdIndex;
+
+  Part1Port=BaseAddr+SIS_CRT2_PORT_04;
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+
+  ModeIdIndex=SiS_SearchVBModeID(ROMAddr,ModeNo);
+  temp = GetOEMLCDPtr(HwDeviceExtension);
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex; /* TW: Always zero... */
+  if (SiS_IF_DEF_LVDS == 1) {
+  	/* TW: Added for LVDS: Assuming Part_1!!!_Port to be the correct one */
+    	temp = SiS300_OEMLCDDelay3[temp][index];
+	temp=temp&0x3c;
+  	SiS_SetRegANDOR(Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
+  } else {
+        /* temp = SiS300_OEMLCDDelay1[temp][index];  */
+	/*  TW: This must be wrong: temp is eg. 48 and
+		thus exceeds array size of Delay2 table! */
 
-void
-SetOEMLCDDelay (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part2Port;
-	USHORT index, temp, ModeIdIndex;
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	temp = GetOEMLCDPtr (HwDeviceExtension);
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
-	temp = SiS300_OEMLCDDelay1[temp][index];
-	/*add OEMLCDPanelIDSupport */
+        /*add OEMLCDPanelIDSupport*/
+
+#if 0  /* TW: Commented for DEBUG */
 	temp = SiS300_OEMLCDDelay2[temp][index];
-	temp = temp & 0x3c;
-	SiS_SetRegANDOR (Part2Port, 0x13, ~0x3C, temp);	/* index 0A D[6:4] */
+	temp=temp&0x3c;
+  	SiS_SetRegANDOR(Part2Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
+#endif
+
+        /* TW: 301B reported not working. Maybe because of the above bullshit? */
+	/*     Do it like for LVDS now. 0x13 seems to be the LCD delay anyway */
+        temp = SiS300_OEMLCDDelay3[temp][index];
+	temp=temp&0x3c;
+  	SiS_SetRegANDOR(Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
+  }
 }
 
 /*
 */
 void
-SetOEMAntiFlicker (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		   ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part2Port;
-	USHORT index, temp;
-	USHORT ModeIdIndex;
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	temp = GetOEMTVPtr ();
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
-	temp = SiS300_OEMTVFlicker[temp][index];
-	temp = temp & 0x70;
-	SiS_SetRegANDOR (Part2Port, 0x0A, ~0x70, temp);	/* index 0A D[6:4] */
-
-}
-
-void
-SetOEMPhaseIncr (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		 ULONG ROMAddr, USHORT ModeNo)
-{
-	USHORT Part2Port;
-	USHORT index, i, ModeIdIndex;
-
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	// temp = GetTVPtrIndex();
-	/* 0: NTSC Graphics, 1: NTSC Text, 2 :PAL Graphics, 3 :PAL Text, 4:HiTV Graphics 5:HiTV Text */
-	// index = temp % 2;
-	// temp >>= 1;   /* 0: NTSC, 1 :PAL, 2:HiTV */
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
-	if (SiS_VBInfo & SetInSlaveMode) {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StPALPhase[index][i -
-								      0x31]);
-		} else {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StNTSCPhase[index][i -
-								       0x31]);
-		}
-		if (SiS_VBInfo & SetCRT2ToSCART) {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StSCARTPhase[index][i -
-									0x31]);
-		}
-	} else {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtPALPhase[index][i -
-								       0x31]);
-		} else {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtNTSCPhase[index][i -
-									0x31]);
-		}
-		if (SiS_VBInfo & SetCRT2ToSCART) {
-			for (i = 0x31; i <= 0x34; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtSCARTPhase[index][i -
-									 0x31]);
-		}
-	}
-}
-
-void
-SetOEMYFilter (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-	       ULONG ROMAddr, USHORT ModeNo)
+SetOEMAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                  USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo)
 {
-	USHORT Part2Port;
-	USHORT index, temp1, temp2, i, ModeIdIndex, index1;
-	Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-	/*301b */
-	ModeIdIndex = SiS_SearchVBModeID (ROMAddr, ModeNo);
-	index = SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
-	if (SiS_VBInfo & SetInSlaveMode) {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x35; i <= 0x38; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StPALFilter[index][i -
-								       0x35]);
-		} else {
-			for (i = 0x35; i <= 0x38; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_StNTSCFilter[index][i -
-									0x35]);
-		}
-	} else {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x35; i <= 0x38; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtPALFilter[index][i -
-									0x35]);
-		} else {
-			for (i = 0x35; i <= 0x38; i++)
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_ExtNTSCFilter[index][i -
-									 0x35]);
-		}
-	}
-
-	if ((SiS_VBType & VB_SIS301B) || (SiS_VBType & VB_SIS302B)) {
-		if (SiS_VBInfo & SetPALTV) {
-			for (i = 0x35; i <= 0x38; i++) {
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_PALFilter2[index][i -
-								      0x35]);
-			}
-			for (i = 0x48; i <= 0x4A; i++) {
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_PALFilter2[index][(i - 0x48)
-								      + 0x04]);
-			}
-		} else {
-			for (i = 0x35; i <= 0x38; i++) {
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_NTSCFilter2[index][i -
-								       0x35]);
-			}
-			for (i = 0x48; i <= 0x4A; i++) {
-				SiS_SetReg1 (Part2Port, i,
-					     SiS300_NTSCFilter2[index][
-								       (i -
-									0x48) +
-								       0x04]);
-			}
-		}
-	}
+  USHORT Part2Port;
+  USHORT index,temp;
+  USHORT ModeIdIndex;
+
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+  ModeIdIndex=SiS_SearchVBModeID(ROMAddr,ModeNo);
+  temp = GetOEMTVPtr();
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
+  temp = SiS300_OEMTVFlicker[temp][index];
+  temp=temp&0x70;
+  SiS_SetRegANDOR(Part2Port,0x0A,~0x70,temp);  /* index 0A D[6:4] */
+}
+
+void
+SetOEMPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                ULONG ROMAddr,USHORT ModeNo)
+{
+  USHORT Part2Port;
+  USHORT index,i,ModeIdIndex;
+
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+  /* temp = GetTVPtrIndex();*/
+  /* 0: NTSC Graphics, 1: NTSC Text, 2 :PAL Graphics, 3 :PAL Text, 4:HiTV Graphics 5:HiTV Text */
+  /* index = temp % 2;*/
+  /* temp >>= 1;   0: NTSC, 1 :PAL, 2:HiTV */
+  ModeIdIndex=SiS_SearchVBModeID(ROMAddr,ModeNo);
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
+  if (SiS_VBInfo&SetInSlaveMode){
+      if(SiS_VBInfo&SetPALTV){  
+         for(i=0x31;i<=0x34;i++)
+        	SiS_SetReg1(Part2Port,i,SiS300_StPALPhase[index][i-0x31]);
+      } else {
+          for(i=0x31;i<=0x34;i++)
+        	SiS_SetReg1(Part2Port,i,SiS300_StNTSCPhase[index][i-0x31]);
+      }
+      if(SiS_VBInfo&SetCRT2ToSCART){
+          for(i=0x31;i<=0x34;i++)
+        	SiS_SetReg1(Part2Port,i,SiS300_StSCARTPhase[index][i-0x31]);
+      }
+  } else {
+       if(SiS_VBInfo&SetPALTV){  
+          for(i=0x31;i<=0x34;i++)
+        	SiS_SetReg1(Part2Port,i,SiS300_ExtPALPhase[index][i-0x31]);
+       } else {
+          for(i=0x31;i<=0x34;i++)
+        	SiS_SetReg1(Part2Port,i,SiS300_ExtNTSCPhase[index][i-0x31]);
+       }
+       if(SiS_VBInfo&SetCRT2ToSCART){
+          for(i=0x31;i<=0x34;i++)
+        	SiS_SetReg1(Part2Port,i,SiS300_ExtSCARTPhase[index][i-0x31]);
+       }
+  }
+}
+
+void
+SetOEMYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              ULONG ROMAddr,USHORT ModeNo)
+{
+  USHORT Part2Port;
+  USHORT index,temp1,temp2,i,ModeIdIndex,index1;
+  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+    /*301b*/
+  ModeIdIndex=SiS_SearchVBModeID(ROMAddr,ModeNo);
+  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
+  if (SiS_VBInfo&SetInSlaveMode){
+      if(SiS_VBInfo&SetPALTV){  
+        	for(i=0x35;i<=0x38;i++)
+        		SiS_SetReg1(Part2Port,i,SiS300_StPALFilter[index][i-0x35]);
+      } else {
+         	 for(i=0x35;i<=0x38;i++)
+        		SiS_SetReg1(Part2Port,i,SiS300_StNTSCFilter[index][i-0x35]);
+      }
+  } else{
+      if(SiS_VBInfo&SetPALTV) {
+         for(i=0x35;i<=0x38;i++)
+        	SiS_SetReg1(Part2Port,i,SiS300_ExtPALFilter[index][i-0x35]);
+      } else{
+          for(i=0x35;i<=0x38;i++)
+        	SiS_SetReg1(Part2Port,i,SiS300_ExtNTSCFilter[index][i-0x35]);
+      }
+  }
+
+  if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+    if(SiS_VBInfo&SetPALTV){  
+    	for(i=0x35;i<=0x38;i++)
+    	{
+     		SiS_SetReg1(Part2Port,i,SiS300_PALFilter2[index][i-0x35]);
+    	}
+   	for(i=0x48;i<=0x4A;i++)
+    	{
+     		SiS_SetReg1(Part2Port,i,SiS300_PALFilter2[index][(i-0x48)+0x04]);
+    	}
+    } else {
+  	for(i=0x35;i<=0x38;i++)
+    	{
+     		SiS_SetReg1(Part2Port,i,SiS300_NTSCFilter2[index][i-0x35]);
+     	}
+   	for(i=0x48;i<=0x4A;i++)
+    	{
+     		SiS_SetReg1(Part2Port,i,SiS300_NTSCFilter2[index][(i-0x48)+0x04]);
+    	}
+    }
+  }
 
 /*add PALMN*/
-	if ((HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730)) {
-		index1 = SiS_GetReg1 (SiS_P3d4, 0x31);
-		temp1 = index1 & 0x01;
-		index1 = SiS_GetReg1 (SiS_P3d4, 0x35);
-		temp2 = index1 & 0xC0;
-		if (temp1) {
-			if (temp2 == 0x40) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) {
-					for (i = 0x35; i <= 0x38; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALMFilter2
-							     [index][i - 0x35]);
-					}
-					for (i = 0x48; i <= 0x4A; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALMFilter2
-							     [index][(i - 0x48)
-								     + 0x04]);
-					}
-				} else {
-					for (i = 0x35; i <= 0x38; i++)
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALMFilter
-							     [index][i - 0x35]);
-				}
-			}
-			if (temp2 == 0x80) {
-				if ((SiS_VBType & VB_SIS301B)
-				    || (SiS_VBType & VB_SIS302B)) {
-					for (i = 0x35; i <= 0x38; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALNFilter2
-							     [index][i - 0x35]);
-					}
-					for (i = 0x48; i <= 0x4A; i++) {
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALNFilter2
-							     [index][(i - 0x48)
-								     + 0x04]);
-					}
-				} else {
-					for (i = 0x35; i <= 0x38; i++)
-						SiS_SetReg1 (Part2Port, i,
-							     SiS300_PALNFilter
-							     [index][i - 0x35]);
-				}
-			}
-		}
-	}
-	/*end PALMN */
+  if((HwDeviceExtension->jChipType==SIS_630)||
+     (HwDeviceExtension->jChipType==SIS_730)) {
+      index1=SiS_GetReg1(SiS_P3d4,0x31);
+      temp1=index1&0x01;
+      index1=SiS_GetReg1(SiS_P3d4,0x35);
+      temp2=index1&0xC0;
+      if(temp1){
+         if(temp2==0x40){
+              if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+                 for(i=0x35;i<=0x38;i++){
+                      SiS_SetReg1(Part2Port,i,SiS300_PALMFilter2[index][i-0x35]);
+                 }
+                 for(i=0x48;i<=0x4A;i++) {
+                       SiS_SetReg1(Part2Port,i,SiS300_PALMFilter2[index][(i-0x48)+0x04]);
+                 }
+              } else {
+                 for(i=0x35;i<=0x38;i++)
+                 	SiS_SetReg1(Part2Port,i,SiS300_PALMFilter[index][i-0x35]);
+              }
+         }
+         if(temp2==0x80){ 
+              if(SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)) {
+                 for(i=0x35;i<=0x38;i++){
+                      SiS_SetReg1(Part2Port,i,SiS300_PALNFilter2[index][i-0x35]);
+                 }
+                 for(i=0x48;i<=0x4A;i++) {
+                       SiS_SetReg1(Part2Port,i,SiS300_PALNFilter2[index][(i-0x48)+0x04]);
+                 }
+             } else {
+                 for(i=0x35;i<=0x38;i++)
+                 	SiS_SetReg1(Part2Port,i,SiS300_PALNFilter[index][i-0x35]);
+             }
+          }
+      }
+   }
+  /*end PALMN*/
 }
 
 void
-SiS_OEM300Setting (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-		   ULONG ROMAddr, USHORT ModeNo)
-{
-	if (SiS_VBInfo & SetCRT2ToLCD) {
-		SetOEMLCDDelay (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-	}
-	if (SiS_VBInfo & SetCRT2ToTV) {
-		SetOEMTVDelay (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-		SetOEMAntiFlicker (HwDeviceExtension, BaseAddr, ROMAddr,
-				   ModeNo);
-		/* SetOEMPhaseIncr(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo); */
-		SetOEMYFilter (HwDeviceExtension, BaseAddr, ROMAddr, ModeNo);
-	}
+SiS_OEM300Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+		  USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo)
+{
+  if (SiS_VBInfo & SetCRT2ToLCD) {
+       SetOEMLCDDelay(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+  }
+  if (SiS_VBInfo & SetCRT2ToTV) {
+       /* TW: (Added LVDS check) - done this way now because LVDS
+        * seems to be 1 for some of the SiS bridges as well
+	*/
+       if( (SiS_VBType&(VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV))
+       						|| (SiS_IF_DEF_LVDS==0))  {
+	        SetOEMTVDelay(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+       		SetOEMAntiFlicker(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+    		/* SetOEMPhaseIncr(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);*/
+       		SetOEMYFilter(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+       }
+    }
 }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/init301.h linux/drivers/video/sis/init301.h
--- linux.orig/drivers/video/sis/init301.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/init301.h	2002-07-20 01:08:36.000000000 +0000
@@ -7,217 +7,230 @@
 #include "vgatypes.h"
 #include "vstruct.h"
 
+#ifdef TC
+#include <stdio.h>
+#include <string.h>
+#include <conio.h>
+#include <dos.h>
+#include <stdlib.h>
+#endif
+
+#ifdef LINUX_XF86
+#include "xf86.h"
+#include "xf86PciInfo.h"
+#include "sis.h"
+#include "sis_regs.h"
+#endif
+
+#ifdef LINUX_KERNEL
 #include <asm/io.h>
 #include <linux/types.h>
 #include <linux/sisfb.h>
+#endif
+
+#ifdef WIN2000
+#include <stdio.h>
+#include <string.h>
+#include <miniport.h>
+#include "dderror.h"
+#include "devioctl.h"
+#include "miniport.h"
+
+#include "ntddvdeo.h"
+#include "video.h"
+#include "sisv.h"
+#endif
 
-USHORT SiS_SetFlag;
-USHORT SiS_RVBHCFACT, SiS_RVBHCMAX, SiS_RVBHRS;
-USHORT SiS_VGAVT, SiS_VGAHT;
-USHORT SiS_VT, SiS_HT;
-USHORT SiS_VGAVDE, SiS_VGAHDE;
-USHORT SiS_VDE, SiS_HDE;
-USHORT SiS_NewFlickerMode, SiS_RY1COE, SiS_RY2COE, SiS_RY3COE, SiS_RY4COE;
-USHORT SiS_LCDHDES, SiS_LCDVDES;
-USHORT SiS_DDC_Port;
-USHORT SiS_DDC_Index;
-USHORT SiS_DDC_DataShift;
-USHORT SiS_DDC_DeviceAddr;
-USHORT SiS_DDC_Flag;
-USHORT SiS_DDC_ReadAddr;
-USHORT SiS_DDC_Buffer;
+USHORT   SiS_SetFlag;
+USHORT   SiS_RVBHCFACT,SiS_RVBHCMAX,SiS_RVBHRS;
+USHORT   SiS_VGAVT,SiS_VGAHT;
+USHORT   SiS_VT,SiS_HT;
+USHORT   SiS_VGAVDE,SiS_VGAHDE;
+USHORT   SiS_VDE,SiS_HDE;
+USHORT   SiS_NewFlickerMode,SiS_RY1COE,SiS_RY2COE,SiS_RY3COE,SiS_RY4COE;
+USHORT   SiS_LCDHDES,SiS_LCDVDES;
+USHORT   SiS_DDC_Port;
+USHORT   SiS_DDC_Index;
+USHORT   SiS_DDC_DataShift;
+USHORT   SiS_DDC_DeviceAddr;
+USHORT   SiS_DDC_Flag;
+USHORT   SiS_DDC_ReadAddr;
+USHORT   SiS_DDC_Buffer;
 
-extern USHORT SiS_CRT1Mode;
-extern USHORT SiS_P3c4, SiS_P3d4;
+extern   USHORT   SiS_CRT1Mode;
+extern   USHORT   SiS_P3c4,SiS_P3d4;
 /*extern   USHORT      SiS_P3c0,SiS_P3ce,SiS_P3c2;*/
-extern USHORT SiS_P3ca;
+extern   USHORT   SiS_P3ca;
 /*extern   USHORT      SiS_P3c6,SiS_P3c7,SiS_P3c8;*/
-extern USHORT SiS_P3c9;
-extern USHORT SiS_P3da;
-extern USHORT SiS_Part1Port, SiS_Part2Port;
-extern USHORT SiS_Part3Port, SiS_Part4Port, SiS_Part5Port;
-extern USHORT SiS_MDA_DAC[];
-extern USHORT SiS_CGA_DAC[];
-extern USHORT SiS_EGA_DAC[];
-extern USHORT SiS_VGA_DAC[];
-extern USHORT SiS_ModeType;
-extern USHORT SiS_SelectCRT2Rate;
-extern USHORT SiS_IF_DEF_LVDS;
-extern USHORT SiS_IF_DEF_TRUMPION;
-extern USHORT SiS_IF_DEF_CH7005;
-extern USHORT SiS_IF_DEF_HiVision;
-extern USHORT SiS_IF_DEF_DSTN;	/*add for dstn */
-extern USHORT SiS_VBInfo;
-extern USHORT SiS_VBType;	/*301b */
-extern USHORT SiS_LCDResInfo;
-extern USHORT SiS_LCDTypeInfo;
-extern USHORT SiS_LCDInfo;
-extern BOOLEAN SiS_SearchVBModeID (ULONG, USHORT);
-extern BOOLEAN SiS_Is301B (USHORT BaseAddr);	/*301b */
-extern BOOLEAN SiS_IsDisableCRT2 (USHORT BaseAddr);
-extern BOOLEAN SiS_IsVAMode (USHORT BaseAddr);
-extern BOOLEAN SiS_IsDualEdge (USHORT BaseAddr);
+extern   USHORT   SiS_P3c9;
+extern   USHORT   SiS_P3da;
+extern   USHORT   SiS_Part1Port,SiS_Part2Port;
+extern   USHORT   SiS_Part3Port,SiS_Part4Port,SiS_Part5Port;
+extern   USHORT   SiS_MDA_DAC[];
+extern   USHORT   SiS_CGA_DAC[];
+extern   USHORT   SiS_EGA_DAC[];
+extern   USHORT   SiS_VGA_DAC[];
+extern   USHORT   SiS_ModeType;
+extern   USHORT   SiS_SelectCRT2Rate;
+extern   USHORT   SiS_IF_DEF_LVDS;
+extern   USHORT   SiS_IF_DEF_TRUMPION;
+extern   USHORT   SiS_IF_DEF_CH7005;
+extern   USHORT   SiS_Backup7005;
+extern   USHORT   SiS_IF_DEF_HiVision;
+extern   USHORT   SiS_IF_DEF_DSTN;   /*add for dstn*/
+extern   USHORT   SiS_IF_DEF_FSTN;   /*add for fstn*/
+extern   USHORT   SiS_VBInfo;
+extern   USHORT   SiS_VBType;        /*301b*/
+extern   USHORT   SiS_VBExtInfo; /*301lv*/
+extern   USHORT   SiS_LCDResInfo;
+extern   USHORT   SiS_LCDTypeInfo;
+extern   USHORT   SiS_LCDInfo;
+extern   BOOLEAN  SiS_SearchVBModeID(ULONG, USHORT);
+extern   BOOLEAN  SiS_Is301B(USHORT BaseAddr);/*301b*/
+extern   BOOLEAN  SiS_IsDisableCRT2(USHORT BaseAddr);
+extern   BOOLEAN  SiS_IsVAMode(USHORT BaseAddr);
+extern   BOOLEAN  SiS_IsDualEdge(USHORT BaseAddr);
 /*end 301b*/
 
-void SiS_SetDefCRT2ExtRegs (USHORT BaseAddr);
-USHORT SiS_GetRatePtrCRT2 (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-BOOLEAN SiS_AjustCRT2Rate (ULONG ROMAddr, USHORT ModeNo, USHORT MODEIdIndex,
-			   USHORT RefreshRateTableIndex, USHORT * i);
-void SiS_SaveCRT2Info (USHORT ModeNo);
-void SiS_GetCRT2Data (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex);
-void SiS_GetCRT2DataLVDS (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			  USHORT RefreshRateTableIndex);
-void SiS_GetCRT2PtrA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex, USHORT * CRT2Index, USHORT * ResIndex);	/*301b */
-void SiS_GetCRT2Data301 (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			 USHORT RefreshRateTableIndex);
-USHORT SiS_GetResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_GetCRT2ResInfo (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_GetRAMDAC2DATA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			 USHORT RefreshRateTableIndex);
-void SiS_GetCRT2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		     USHORT RefreshRateTableIndex, USHORT * CRT2Index,
-		     USHORT * ResIndex);
-void SiS_SetCRT2ModeRegs (USHORT BaseAddr, USHORT ModeNo, PSIS_HW_DEVICE_INFO);
-
-void SiS_GetLVDSDesData (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			 USHORT RefreshRateTableIndex);
-void SiS_SetCRT2Offset (USHORT Part1Port, ULONG ROMAddr, USHORT ModeNo,
-			USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-			PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT SiS_GetOffset (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex,
-		      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT SiS_GetColorDepth (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-USHORT SiS_GetVCLK (ULONG ROMAddr, USHORT ModeNo);
-USHORT SiS_GetVCLKPtr (ULONG ROMAddr, USHORT ModeNo);
-USHORT SiS_GetColorTh (ULONG ROMAddr);
-USHORT SiS_GetMCLK (ULONG ROMAddr);
-USHORT SiS_GetMCLKPtr (ULONG ROMAddr);
-USHORT SiS_GetDRAMType (ULONG ROMAddr);
-USHORT SiS_CalcDelayVB (void);
-extern USHORT SiS_GetVCLK2Ptr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			       USHORT RefreshRateTableIndex,
-			       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetCRT2Sync (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		      USHORT RefreshRateTableIndex);
-void SiS_SetRegANDOR (USHORT Port, USHORT Index, USHORT DataAND, USHORT DataOR);
-void SiS_SetRegOR (USHORT Port, USHORT Index, USHORT DataOR);
-void SiS_SetRegAND (USHORT Port, USHORT Index, USHORT DataAND);
-USHORT SiS_GetVGAHT2 (void);
-void SiS_SetGroup2 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetGroup3 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetGroup4 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetGroup5 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex);
-void SiS_SetCRT2VCLK (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		      USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-		      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_EnableCRT2 (void);
-void SiS_LoadDAC2 (ULONG ROMAddr, USHORT Part5Port, USHORT ModeNo,
-		   USHORT ModeIdIndex);
-void SiS_WriteDAC2 (USHORT Pdata, USHORT dl, USHORT ah, USHORT al, USHORT dh);
-void SiS_GetVBInfo301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		       USHORT ModeIdIndex,
-		       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN SiS_GetLCDResInfo (ULONG ROMAddr, USHORT P3d4, USHORT ModeNo,
-			   USHORT ModeIdIndex);
-BOOLEAN SiS_BridgeIsOn (USHORT BaseAddr);
-BOOLEAN SiS_BridgeIsEnable (USHORT BaseAddr, PSIS_HW_DEVICE_INFO);
-BOOLEAN SiS_BridgeInSlave (void);
+void     SiS_SetDefCRT2ExtRegs(USHORT BaseAddr);
+USHORT   SiS_GetRatePtrCRT2(ULONG ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+BOOLEAN  SiS_AdjustCRT2Rate(ULONG ROMAddr,USHORT ModeNo,USHORT MODEIdIndex,USHORT RefreshRateTableIndex,USHORT *i);
+void     SiS_SaveCRT2Info(USHORT ModeNo);
+void     SiS_GetCRT2Data(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_GetCRT2DataLVDS(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_GetCRT2PtrA(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex, USHORT *CRT2Index,USHORT *ResIndex);/*301b*/
+void     SiS_GetCRT2Data301(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+USHORT   SiS_GetResInfo(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_GetCRT2ResInfo(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_GetRAMDAC2DATA(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_GetCRT2Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+		USHORT *CRT2Index,USHORT *ResIndex);
+void     SiS_SetCRT2ModeRegs(USHORT BaseAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO );
+
+
+void     SiS_GetLVDSDesData(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_SetCRT2Offset(USHORT Part1Port,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_GetOffset(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_GetColorDepth(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+USHORT   SiS_GetVCLK(ULONG ROMAddr,USHORT ModeNo);
+USHORT   SiS_GetVCLKPtr(ULONG ROMAddr,USHORT ModeNo);
+USHORT   SiS_GetColorTh(ULONG ROMAddr);
+USHORT   SiS_GetMCLK(ULONG ROMAddr);
+USHORT   SiS_GetMCLKPtr(ULONG ROMAddr);
+USHORT   SiS_GetDRAMType(ULONG ROMAddr);
+USHORT   SiS_CalcDelayVB(void);
+extern USHORT   SiS_GetVCLK2Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2Sync(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex);
+void     SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+void     SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
+void     SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
+USHORT   SiS_GetVGAHT2(void);
+void     SiS_SetGroup2(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGroup3(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGroup4(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGroup5(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_SetCRT2VCLK(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_EnableCRT2(void);
+void     SiS_LoadDAC2(ULONG ROMAddr,USHORT Part5Port,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_WriteDAC2(USHORT Pdata,USHORT dl, USHORT ah, USHORT al, USHORT dh);
+void     SiS_GetVBInfo301(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_GetLCDResInfo(ULONG ROMAddr,USHORT P3d4,USHORT ModeNo,USHORT ModeIdIndex);
+BOOLEAN  SiS_BridgeIsOn(USHORT BaseAddr);
+BOOLEAN  SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
+BOOLEAN  SiS_BridgeInSlave(void);
 /*void     SiS_PresetScratchregister(USHORT P3d4);*/
-void SiS_PresetScratchregister (USHORT SiS_P3d4,
-				PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetTVSystem (VOID);
-void SiS_LongWait (VOID);
-USHORT SiS_GetQueueConfig (VOID);
-void SiS_VBLongWait (VOID);
-USHORT SiS_GetVCLKLen (ULONG ROMAddr);
-BOOLEAN SiS_WaitVBRetrace (USHORT BaseAddr);
-void SiS_SetCRT2ECLK (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex,
-		      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_GetLVDSDesPtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			USHORT RefreshRateTableIndex, USHORT * PanelIndex,
-			USHORT * ResIndex);
-void SiS_GetLVDSDesPtrA (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			 USHORT RefreshRateTableIndex, USHORT * PanelIndex,
-			 USHORT * ResIndex);	/*301b */
-void SiS_SetTPData (VOID);
-void SiS_ModCRT1CRTC (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		      USHORT RefreshRateTableIndex);
-extern BOOLEAN SiS_GetLVDSCRT1Ptr (ULONG ROMAddr, USHORT ModeNo,
-				   USHORT ModeIdIndex,
-				   USHORT RefreshRateTableIndex,
-				   USHORT * ResInfo, USHORT * DisplayType);
-void SiS_SetCHTVReg (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-		     USHORT RefreshRateTableIndex);
-void SiS_SetCHTVRegANDOR (USHORT tempax, USHORT tempbh);
-void SiS_GetCHTVRegPtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-			USHORT RefreshRateTableIndex);
-void SiS_SetCH7005 (USHORT tempax);
-USHORT SiS_GetCH7005 (USHORT tempax);
-void SiS_SetSwitchDDC2 (void);
-void SiS_SetStart (void);
-void SiS_SetStop (void);
-void SiS_DDC2Delay (void);
-void SiS_SetSCLKLow (void);
-void SiS_SetSCLKHigh (void);
-USHORT SiS_ReadDDC2Data (USHORT tempax);
-USHORT SiS_WriteDDC2Data (USHORT tempax);
-USHORT SiS_CheckACK (void);
-void SiS_OEM310Setting (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-			ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_OEM300Setting (PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-			ULONG ROMAddr, USHORT ModeNo);
-USHORT GetRevisionID (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_SetReg1 (USHORT, USHORT, USHORT);
-extern void SiS_SetReg3 (USHORT, USHORT);
-extern UCHAR SiS_GetReg1 (USHORT, USHORT);
-extern UCHAR SiS_GetReg2 (USHORT);
-extern BOOLEAN SiS_SearchModeID (ULONG ROMAddr, USHORT ModeNo,
-				 USHORT * ModeIdIndex);
-extern BOOLEAN SiS_GetRatePtr (ULONG, USHORT);
-extern void SiS_SetReg4 (USHORT, ULONG);
-extern ULONG SiS_GetReg3 (USHORT);
-extern void SiS_DisplayOff (void);
-extern void SiS_CRT2AutoThreshold (USHORT BaseAddr);
-extern void SiS_DisplayOn (void);
-extern UCHAR SiS_GetModePtr (ULONG ROMAddr, USHORT ModeNo, USHORT ModeIdIndex);
-extern UCHAR SiS_Get310DRAMType (ULONG ROMAddr);
-
-BOOLEAN SiS_SetCRT2Group301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			     PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetGroup1 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-		    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		    USHORT RefreshRateTableIndex);
-void SiS_SetGroup1_LVDS (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			 USHORT ModeIdIndex,
-			 PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			 USHORT RefreshRateTableIndex);
-void SiS_SetGroup1_LCDA (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			 USHORT ModeIdIndex,
-			 PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT RefreshRateTableIndex);	/*301b */
-void SiS_SetGroup1_301 (USHORT BaseAddr, ULONG ROMAddr, USHORT ModeNo,
-			USHORT ModeIdIndex,
-			PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			USHORT RefreshRateTableIndex);
-void SiS_SetCRT2FIFO (USHORT Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_SetCRT2FIFO2 (USHORT Part1Port, ULONG ROMAddr, USHORT ModeNo,
-		       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN SiS_GetLCDDDCInfo (PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void SiS_UnLockCRT2 (PSIS_HW_DEVICE_INFO, USHORT BaseAddr);
-void SiS_LockCRT2 (PSIS_HW_DEVICE_INFO, USHORT BaseAddr);
-void SiS_DisableBridge (PSIS_HW_DEVICE_INFO, USHORT BaseAddr);
-void SiS_EnableBridge (PSIS_HW_DEVICE_INFO, USHORT BaseAddr);
-void SiS_SetPanelDelay (USHORT DelayTime);
-void SiS_LCD_Wait_Time (UCHAR DelayTime);
+void     SiS_PresetScratchregister(USHORT SiS_P3d4,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetTVSystem(VOID);
+void     SiS_LongWait(VOID);
+USHORT   SiS_GetQueueConfig(VOID);
+void     SiS_VBLongWait(VOID);
+USHORT   SiS_GetVCLKLen(ULONG ROMAddr);
+BOOLEAN  SiS_WaitVBRetrace(USHORT  BaseAddr);
+void     SiS_SetCRT2ECLK(ULONG ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetLVDSDesPtr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);
+void     SiS_GetLVDSDesPtrA(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);/*301b*/
+void     SiS_SetTPData(VOID);
+void     SiS_ModCRT1CRTC(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+extern BOOLEAN  SiS_GetLVDSCRT1Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+		       USHORT *ResInfo,USHORT *DisplayType);
+void     SiS_SetCHTVReg(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_SetCHTVRegANDOR(USHORT tempax,USHORT tempbh);
+void     SiS_GetCHTVRegPtr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void     SiS_SetCH7005(USHORT tempax);
+USHORT   SiS_GetCH7005(USHORT tempax);
+void     SiS_SetSwitchDDC2(void);
+void     SiS_SetStart(void);
+void     SiS_SetStop(void);
+void     SiS_DDC2Delay(void);
+void     SiS_SetSCLKLow(void);
+void     SiS_SetSCLKHigh(void);
+USHORT   SiS_ReadDDC2Data(USHORT tempax);
+USHORT   SiS_WriteDDC2Data(USHORT tempax);
+USHORT   SiS_CheckACK(void);
+void     SiS_OEM310Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_OEM300Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo);
+USHORT GetRevisionID(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+BOOLEAN SiS_GetLCDResInfo301(ULONG ROMAddr,USHORT SiS_P3d4, USHORT ModeNo,USHORT ModeIdIndex);
+void    SiS_CHACRT1CRTC(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                        USHORT RefreshRateTableIndex);
+BOOLEAN SiS_GetLCDACRT1Ptr(ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
+		   USHORT *DisplayType);
+USHORT  GetTVPtrIndex(void);
+USHORT 	GetLCDPtrIndex (void);
+void    SetDelayComp(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             	ULONG ROMAddr,USHORT ModeNo);
+void    SetAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               	ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void    SetEdgeEnhance (PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void    SetYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+           	ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void	SetPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             	ULONG ROMAddr,USHORT ModeNo);
+USHORT 	GetOEMLCDPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT 	GetOEMTVPtr(void);
+void	SetOEMTVDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              	ULONG ROMAddr,USHORT ModeNo);
+void	SetOEMLCDDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               	ULONG ROMAddr,USHORT ModeNo);
+void	SetOEMAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo);
+void  	SetOEMPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                ULONG ROMAddr,USHORT ModeNo);
+void	SetOEMYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              	ULONG ROMAddr,USHORT ModeNo);
+
+
+extern   void     SiS_SetReg1(USHORT, USHORT, USHORT);
+extern   void     SiS_SetReg3(USHORT, USHORT);
+extern   UCHAR    SiS_GetReg1(USHORT, USHORT);
+extern   UCHAR    SiS_GetReg2(USHORT);
+extern   BOOLEAN  SiS_SearchModeID(ULONG ROMAddr, USHORT ModeNo,USHORT  *ModeIdIndex);
+extern   BOOLEAN  SiS_GetRatePtr(ULONG, USHORT);
+extern   void     SiS_SetReg4(USHORT, ULONG);
+extern   ULONG    SiS_GetReg3(USHORT);
+extern   void     SiS_DisplayOff(void);
+extern   void     SiS_CRT2AutoThreshold(USHORT  BaseAddr);
+extern   void     SiS_DisplayOn(void);
+extern   UCHAR    SiS_GetModePtr(ULONG ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+extern   UCHAR    SiS_Get310DRAMType(ULONG   ROMAddr);
+
+
+BOOLEAN  SiS_SetCRT2Group301(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetGroup1(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+void     SiS_SetGroup1_LVDS(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+void     SiS_SetGroup1_LCDA(USHORT  BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);/*301b*/
+void     SiS_SetGroup1_301(USHORT BaseAddr,ULONG ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+void     SiS_SetCRT2FIFO(USHORT Part1Port,ULONG ROMAddr,USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2FIFO2(USHORT Part1Port,ULONG ROMAddr,USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_LockCRT2(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_DisableBridge(PSIS_HW_DEVICE_INFO,USHORT  BaseAddr);
+void     SiS_EnableBridge(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_SetPanelDelay(USHORT DelayTime);
+void     SiS_LCD_Wait_Time(UCHAR DelayTime);
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/initdef.h linux/drivers/video/sis/initdef.h
--- linux.orig/drivers/video/sis/initdef.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/initdef.h	2002-07-20 01:08:24.000000000 +0000
@@ -1,4 +1,7 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
+
+/* Comments and changes marked with "TW" by Thomas Winischhofer <thomas@winischhofer.net> */
+
 #ifndef _INITDEF_
 #define _INITDEF_
 
@@ -6,12 +9,17 @@
 #define SiS540                  0x5300
 #define SiS630                  0x6300
 #define SiS730                  0x6300
-#define VB_SIS301		0x0001	/*301b */
-#define VB_SIS301B		0x0002
-#define VB_SIS302B		0x0004
-#define  VB_NoLCD		0x8000
 
+/*301b*/
+/* VBType */
+#define VB_SIS301	      	0x0001
+#define VB_SIS301B        	0x0002
+#define VB_SIS302B        	0x0004
+#define VB_SIS301LV     	0x0008 /*301lv*/
+#define VB_SIS302LV     	0x0010
+#define VB_NoLCD        	0x8000
 /*end 301b*/
+
 #define CRT1Len                 17
 #define LVDSCRT1Len             15
 #define CHTVRegDataLen          5
@@ -38,16 +46,17 @@
 #define NoSupportSimuTV         0x2000
 #define DoubleScanMode          0x8000
 
+/* Infoflag */
 #define SupportAllCRT2          0x0078
 #define SupportTV               0x0008
 #define SupportHiVisionTV       0x0010
 #define SupportLCD              0x0020
-#define SupportRAMDAC2          0x0040
+#define SupportRAMDAC2          0x0040  
 #define NoSupportTV             0x0070
 #define NoSupportHiVisionTV     0x0060
 #define NoSupportLCD            0x0058
 #define SupportCHTV 		0x0800
-#define SupportTV1024           0x0800	/*301b */
+#define SupportTV1024           0x0800  /*301b*/            
 #define InterlaceMode           0x0080
 #define SyncPP                  0x0000
 #define SyncPN                  0x4000
@@ -59,6 +68,7 @@
 #define ECLKindex3              0x0300
 #define ECLKindex4              0x0400
 
+/* VBInfo */
 #define SetSimuScanMode         0x0001
 #define SwitchToCRT2            0x0002
 #define SetCRT2ToTV             0x009C
@@ -79,19 +89,21 @@
 #define DriverMode              0x4000
 #define HotKeySwitch            0x8000
 #define SetCHTVOverScan  	0x8000
-#define SetCRT2ToLCDA		0x8000	/*301b */
+#define SetCRT2ToLCDA           0x8000/*301b*/
 #define PanelRGB18Bit           0x0100
 #define PanelRGB24Bit           0x0000
 
 #define TVOverScan              0x10
 #define TVOverScanShift         4
 #define ClearBufferFlag         0x20
-#define EnableDualEdge 		0x01	/*301b */
+#define EnableDualEdge 		0x01		/*301b*/	
 #define SetToLCDA		0x02
 
 #define SetSCARTOutput          0x01
 #define BoardTVType             0x02
-#define  EnablePALMN		0x40
+#define EnablePALMN             0x40
+
+/* SetFlag */
 #define ProgrammingCRT2         0x01
 #define TVSimuMode              0x02
 #define RPLLDIV2XO              0x04
@@ -101,26 +113,32 @@
 #define CheckWinDos             0x40
 #define SetJDOSMode             0x80
 
+/* LCDResInfo */
 #define Panel800x600            0x01
 #define Panel1024x768           0x02
 #define Panel1280x1024          0x03
 #define Panel1280x960           0x04
 #define Panel640x480            0x05
-#define Panel1600x1200          0x06	/*301b */
-#define LCDRGB18Bit             0x01
+#define Panel1600x1200          0x06 /*301b*/
+#define Panel320x480            0x07 /*fstn*/
+
 #define ExtChipType             0x0e
 #define ExtChip301              0x02
 #define ExtChipLVDS             0x04
 #define ExtChipTrumpion         0x06
 #define ExtChipCH7005           0x08
 #define ExtChipMitacTV          0x0a
+
+/* LCDInfo */
+#define LCDRGB18Bit             0x01
 #define LCDNonExpanding         0x10
+
 #define LCDNonExpandingShift    4
 #define LCDSync                 0x20
 #define LCDSyncBit              0xe0
 #define LCDSyncShift            6
 
-#define DDC2DelayTime           300
+#define DDC2DelayTime           300     
 
 #define CRT2DisplayFlag         0x2000
 #define LCDDataLen              8
@@ -198,25 +216,25 @@
 #define ModeSettingAddr         0x53
 
 #define SelectCRT1Rate          0x4
+        
+#define _PanelType00             0x00
+#define _PanelType01             0x08
+#define _PanelType02             0x10
+#define _PanelType03             0x18
+#define _PanelType04             0x20
+#define _PanelType05             0x28
+#define _PanelType06             0x30
+#define _PanelType07             0x38
+#define _PanelType08             0x40
+#define _PanelType09             0x48
+#define _PanelType0A             0x50
+#define _PanelType0B             0x58
+#define _PanelType0C             0x60
+#define _PanelType0D             0x68
+#define _PanelType0E             0x70
+#define _PanelType0F             0x78
 
-#define _PanelType00            0x00
-#define _PanelType01            0x08
-#define _PanelType02            0x10
-#define _PanelType03            0x18
-#define _PanelType04            0x20
-#define _PanelType05            0x28
-#define _PanelType06            0x30
-#define _PanelType07            0x38
-#define _PanelType08            0x40
-#define _PanelType09            0x48
-#define _PanelType0A            0x50
-#define _PanelType0B            0x58
-#define _PanelType0C            0x60
-#define _PanelType0D            0x68
-#define _PanelType0E            0x70
-#define _PanelType0F            0x78
-
-#define PRIMARY_VGA		0	/* 1: SiS is primary vga 0:SiS is secondary vga */
+#define PRIMARY_VGA       	0     /* 1: SiS is primary vga 0:SiS is secondary vga */
 #define BIOSIDCodeAddr          0x235
 #define OEMUtilIDCodeAddr       0x237
 #define VBModeIDTableAddr       0x239
@@ -259,54 +277,54 @@
 #define OEMLCDPanelIDSupport    0x0080
 
 /* =============================================================
-   for 310
+   			for 310
 ============================================================== */
-#define SoftDRAMType      	0x80
-#define SoftSetting_OFFSET	0x52
-#define SR07_OFFSET		0x7C
-#define SR15_OFFSET		0x7D
-#define SR16_OFFSET		0x81
-#define SR17_OFFSET		0x85
-#define SR19_OFFSET		0x8D
-#define SR1F_OFFSET		0x99
-#define SR21_OFFSET		0x9A
-#define SR22_OFFSET		0x9B
-#define SR23_OFFSET		0x9C
-#define SR24_OFFSET		0x9D
-#define SR25_OFFSET		0x9E
-#define SR31_OFFSET		0x9F
-#define SR32_OFFSET		0xA0
-#define SR33_OFFSET		0xA1
-
-#define CR40_OFFSET		0xA2
-#define SR25_1_OFFSET		0xF6
-#define CR49_OFFSET		0xF7
-
-#define VB310Data_1_2_Offset	0xB6
-#define VB310Data_4_D_Offset	0xB7
-#define VB310Data_4_E_Offset	0xB8
-#define VB310Data_4_10_Offset	0xBB
-
-#define RGBSenseDataOffset	0xBD
-#define YCSenseDataOffset	0xBF
-#define VideoSenseDataOffset	0xC1
-#define OutputSelectOffset	0xF3
-
-#define ECLK_MCLK_DISTANCE	0x14
-#define VBIOSTablePointerStart	0x100
-#define StandTablePtrOffset	VBIOSTablePointerStart+0x02
-#define EModeIDTablePtrOffset	VBIOSTablePointerStart+0x04
-#define CRT1TablePtrOffset	VBIOSTablePointerStart+0x06
-#define ScreenOffsetPtrOffset	VBIOSTablePointerStart+0x08
-#define VCLKDataPtrOffset	VBIOSTablePointerStart+0x0A
-#define MCLKDataPtrOffset	VBIOSTablePointerStart+0x0E
-#define CRT2PtrDataPtrOffset	VBIOSTablePointerStart+0x10
-#define TVAntiFlickPtrOffset	VBIOSTablePointerStart+0x12
-#define TVDelayPtr1Offset	VBIOSTablePointerStart+0x14
-#define TVPhaseIncrPtr1Offset	VBIOSTablePointerStart+0x16
-#define TVYFilterPtr1Offset	VBIOSTablePointerStart+0x18
-#define LCDDelayPtr1Offset	VBIOSTablePointerStart+0x20
-#define TVEdgePtr1Offset	VBIOSTablePointerStart+0x24
-#define CRT2Delay1Offset	VBIOSTablePointerStart+0x28
+#define SoftDRAMType        0x80
+#define SoftSetting_OFFSET  0x52
+#define SR07_OFFSET  0x7C
+#define SR15_OFFSET  0x7D
+#define SR16_OFFSET  0x81
+#define SR17_OFFSET  0x85
+#define SR19_OFFSET  0x8D
+#define SR1F_OFFSET  0x99
+#define SR21_OFFSET  0x9A
+#define SR22_OFFSET  0x9B
+#define SR23_OFFSET  0x9C
+#define SR24_OFFSET  0x9D
+#define SR25_OFFSET  0x9E
+#define SR31_OFFSET  0x9F
+#define SR32_OFFSET  0xA0
+#define SR33_OFFSET  0xA1
+
+#define CR40_OFFSET  0xA2
+#define SR25_1_OFFSET  0xF6
+#define CR49_OFFSET  0xF7
+
+#define VB310Data_1_2_Offset  0xB6
+#define VB310Data_4_D_Offset  0xB7
+#define VB310Data_4_E_Offset  0xB8
+#define VB310Data_4_10_Offset 0xBB
+
+#define RGBSenseDataOffset    0xBD
+#define YCSenseDataOffset     0xBF
+#define VideoSenseDataOffset  0xC1
+#define OutputSelectOffset    0xF3
+
+#define ECLK_MCLK_DISTANCE  0x14
+#define VBIOSTablePointerStart    0x100
+#define StandTablePtrOffset       VBIOSTablePointerStart+0x02
+#define EModeIDTablePtrOffset     VBIOSTablePointerStart+0x04
+#define CRT1TablePtrOffset        VBIOSTablePointerStart+0x06
+#define ScreenOffsetPtrOffset     VBIOSTablePointerStart+0x08
+#define VCLKDataPtrOffset         VBIOSTablePointerStart+0x0A
+#define MCLKDataPtrOffset         VBIOSTablePointerStart+0x0E
+#define CRT2PtrDataPtrOffset      VBIOSTablePointerStart+0x10
+#define TVAntiFlickPtrOffset      VBIOSTablePointerStart+0x12
+#define TVDelayPtr1Offset         VBIOSTablePointerStart+0x14
+#define TVPhaseIncrPtr1Offset     VBIOSTablePointerStart+0x16
+#define TVYFilterPtr1Offset       VBIOSTablePointerStart+0x18
+#define LCDDelayPtr1Offset        VBIOSTablePointerStart+0x20
+#define TVEdgePtr1Offset          VBIOSTablePointerStart+0x24
+#define CRT2Delay1Offset          VBIOSTablePointerStart+0x28
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/oem300.h linux/drivers/video/sis/oem300.h
--- linux.orig/drivers/video/sis/oem300.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/oem300.h	2002-07-20 01:08:30.000000000 +0000
@@ -1,397 +1,531 @@
-UCHAR SiS300_TVEdge1[3][2] = {
-	{0x0, 0x4},
-	{0x0, 0x4},
-	{0x0, 0x0}
-};
-
-UCHAR SiS300_OEMTVDelay[8][4] = {
-	{0x08, 0x08, 0x08, 0x08},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x2c, 0x2c, 0x2c, 0x2c},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x08, 0x08, 0x08, 0x08},
-	{0x20, 0x20, 0x20, 0x20}
-};
-
-UCHAR SiS300_OEMTVFlicker[8][4] = {
-	{0x00, 0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00, 0x00},
-	{0x00, 0x00, 0x00, 0x00}
-};
-
-UCHAR SiS300_OEMLCDDelay1[12][4] = {
-	{0x2c, 0x2c, 0x2c, 0x2c},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x2c, 0x2c, 0x2c, 0x2c},
-	{0x2c, 0x2c, 0x2c, 0x2c},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x24, 0x24, 0x24, 0x24},
-	{0x24, 0x24, 0x24, 0x24},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x24, 0x24, 0x24, 0x24}
-};
-
-UCHAR SiS300_OEMLCDDelay2[32][4] = {
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20},
-	{0x20, 0x20, 0x20, 0x20}
-};
-
-UCHAR SiS300_StNTSCPhase[6][4] = {
-	{0x21, 0xed, 0x00, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StPALPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StSCARTPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StHiTVPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtNTSCPhase[6][4] = {
-	{0x21, 0xed, 0x00, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0x21, 0xed, 0x8a, 0x08},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtPALPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtSCARTPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtHiTVPhase[6][4] = {
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0x2a, 0x05, 0xd3, 0x00},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StNTSCFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StPALFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StSCARTFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_StHiTVFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtNTSCFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtPALFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtSCARTFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_ExtHiTVFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x10, 0x32},
-	{0xf3, 0x00, 0x1d, 0x20},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xfc, 0xfb, 0x14, 0x2a},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xf1, 0xf7, 0x1f, 0x32},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_NTSCFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-UCHAR SiS300_PALFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-UCHAR SiS300_PALMFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_PALNFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS300_PALMFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-UCHAR SiS300_PALNFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
+
+UCHAR SiS300_OEMTVDelay[8][4]={
+	{0x08,0x08,0x08,0x08},
+	{0x08,0x08,0x08,0x08},
+	{0x08,0x08,0x08,0x08},
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x08,0x08,0x08,0x08},
+	{0x08,0x08,0x08,0x08},
+	{0x08,0x08,0x08,0x08},
+	{0x20,0x20,0x20,0x20}
+};
+
+UCHAR SiS300_OEMTVFlicker[8][4]={
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00}
+};
+
+UCHAR SiS300_OEMLCDDelay1[12][4]={
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x24,0x24,0x24,0x24},
+	{0x24,0x24,0x24,0x24},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x24,0x24,0x24,0x24}
+};
+
+
+UCHAR SiS300_OEMLCDDelay2[32][4]={
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20}
+};
+
+/* TW: Added for LVDS */
+UCHAR SiS300_OEMLCDDelay3[32][4]={
+	{0x20,0x20,0x20,0x20},  /* --- Expanding panels */
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x04,0x04,0x04,0x04},		/* Clevo 2202, Mitac (PanelType 12)*/
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},  	/* Uniwill N241S2 (PanelType 14)*/
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},  /* ---- NonExpanding panels */
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20}
+};
+
+/*
+UCHAR SiS300_StNTSCDelay[]={0x08,0x08,0x08,0x08,0xff};
+UCHAR SiS300_StPALDelay[]={0x08,0x08,0x08,0x08,0xff};
+UCHAR SiS300_StSCARTDelay[]={0x08,0x08,0x08,0x08,0xff};
+UCHAR SiS300_StHiTVDelay[]={0x2c,0x2c,0x2c,0x2c,0xff};
+UCHAR SiS300_ExtNTSCDelay[]={0x08,0x08,0x08,0x08,0xff};
+UCHAR SiS300_ExtPALDelay[]={0x08,0x08,0x08,0x08,0xff};
+UCHAR SiS300_ExtSCARTDelay[]={0x08,0x08,0x08,0x08,0xff};
+UCHAR SiS300_ExtHiTVDelay[]={0x20,0x20,0x20,0x20,0xff};
+UCHAR SiS300_StNTSCFlicker[]={0x00,0x00,0x00,0x00,0xff};
+UCHAR SiS300_StPALFlicker[]={0x00,0x00,0x00,0x00,0xff};
+UCHAR SiS300_StSCARTFlicker[]={0x00,0x00,0x00,0x00,0xff};
+UCHAR SiS300_StHiTVFlicker[]={0x00,0x00,0x00,0x00,0xff};
+UCHAR SiS300_ExtNTSCFlicker[]={0x00,0x00,0x00,0x00,0xff};
+UCHAR SiS300_ExtPALFlicker[]={0x00,0x00,0x00,0x00,0xff};
+UCHAR SiS300_ExtSCARTFlicker[]={0x00,0x00,0x00,0x00,0xff};
+UCHAR SiS300_ExtHiTVFlicker[]={0x00,0x00,0x00,0x00,0xff};
+*/
+
+#if 0
+//typedef struct _SiS_OEMTVPhasestruct  {
+//UCHAR Index[4];
+//} SiS_OEMTVPhasestruct;
+//SiS_OEMTVPhasestruct
+#endif
+
+UCHAR SiS300_StNTSCPhase[6][4]={
+	{0x21,0xed,0x00,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVPhasestruct
+#endif
+
+UCHAR SiS300_StPALPhase[6][4]={
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVPhasestruct
+#endif
+
+UCHAR SiS300_StSCARTPhase[6][4]={
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVPhasestruct
+#endif
+
+UCHAR SiS300_StHiTVPhase[6][4]={
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVPhasestruct
+#endif
+
+UCHAR SiS300_ExtNTSCPhase[6][4]={
+	{0x21,0xed,0x00,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0x21,0xed,0x8a,0x08},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVPhasestruct
+#endif
+
+UCHAR SiS300_ExtPALPhase[6][4]={
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVPhasestruct
+#endif
+
+UCHAR SiS300_ExtSCARTPhase[6][4]={
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVPhasestruct
+#endif
+
+UCHAR SiS300_ExtHiTVPhase[6][4]={
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0x2a,0x05,0xd3,0x00},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//typedef struct _SiS_OEMTVFilterstruct{
+//UCHAR Index[4];
+//} SiS_OEMTVFilterstruct;
+//SiS_OEMTVFilterstruct
+#endif
+
+UCHAR SiS300_StNTSCFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVFilterstruct
+#endif
+
+UCHAR SiS300_StPALFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVFilterstruct
+#endif
+
+UCHAR SiS300_StSCARTFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVFilterstruct
+#endif
+
+UCHAR SiS300_StHiTVFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVFilterstruct
+#endif
+
+UCHAR SiS300_ExtNTSCFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVFilterstruct
+#endif
+
+UCHAR SiS300_ExtPALFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVFilterstruct
+#endif
+
+UCHAR SiS300_ExtSCARTFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//SiS_OEMTVFilterstruct
+#endif
+
+UCHAR SiS300_ExtHiTVFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x10,0x32},
+	{0xf3,0x00,0x1d,0x20},
+	{0x00,0xf4,0x10,0x38},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xfc,0xfb,0x14,0x2a},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xf1,0xf7,0x1f,0x32},
+	{0xff,0xff,0xff,0xff}
+};
+
+#if 0
+//typedef struct _SiS_OEMTVFilter2struct{
+//UCHAR Index[7];
+//} SiS_OEMTVFilter2struct;
+//SiS_OEMTVFilter2struct
+#endif
+
+UCHAR SiS300_NTSCFilter2[9][7]={
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+};
+
+#if 0
+//SiS_OEMTVFilter2struct
+#endif
+
+UCHAR SiS300_PALFilter2[9][7]={
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+};
+
+UCHAR SiS300_PALMFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+};
+
+UCHAR SiS300_PALNFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+};
+
+
+UCHAR SiS300_PALMFilter2[9][7]={
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+};
+
+UCHAR SiS300_PALNFilter2[9][7]={
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
 };
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/oem310.h linux/drivers/video/sis/oem310.h
--- linux.orig/drivers/video/sis/oem310.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/oem310.h	2002-07-20 01:08:21.000000000 +0000
@@ -1,204 +1,185 @@
-UCHAR SiS310_CRT2DelayCompensation1 = 0x4;	/* 301A */
 
-UCHAR SiS310_LCDDelayCompensation1[] = { 
-	0x0, 0x0, 0x0, 0xb, 0xb, 0xb, 0x8, 0x8, 
-	0x8, 0x8, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 
-	0x0, 0x0, 0x0, 0x0, 0x0 
-};
-	
-UCHAR SiS310_TVDelayCompensation1[] = { 0x2, 0x2, 0x2, 0x2, 0x8, 0xb };
-UCHAR SiS310_CRT2DelayCompensation2 = 0xC;	/* 301B */
-UCHAR SiS310_LCDDelayCompensation2[] = {
-	0x0, 0x0, 0x0, 0x0C, 0x0C, 0x0C, 0x0C, 
-	0x0C, 0x0C, 0x8, 0x8, 0x8, 0x0, 0x0, 
-	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
-};
-
-UCHAR SiS310_TVDelayCompensation2[] = { 0x3, 0x3, 0x3, 0x3, 0x8, 0xb };
-
-UCHAR SiS310_TVAntiFlick1[3][2] = {
-	{0x4, 0x0},
-	{0x4, 0x8},
-	{0x0, 0x0}
-};
-
-UCHAR SiS310_TVEdge1[3][2] = {
-	{0x0, 0x4},
-	{0x0, 0x4},
-	{0x0, 0x0}
-};
-
-UCHAR SiS310_TVYFilter1[3][8][4] = {
-	{
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xeb, 0x4, 0x25, 0x18},
-	 {0xf7, 0x6, 0x19, 0x14},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xeb, 0x4, 0x25, 0x18},
-	 {0xee, 0xc, 0x22, 0x8},
-	 {0xeb, 0x15, 0x25, 0xf6}
-	 }
-	,
-	{
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xf1, 0xf7, 0x1f, 0x32},
-	 {0xf3, 0x0, 0x1d, 0x20},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xf1, 0xf7, 0x1f, 0x32},
-	 {0xf3, 0x0, 0x1d, 0x20},
-	 {0xfc, 0xfb, 0x14, 0x2a}
-	}
-	,
-	{
-	 {0x0, 0x0, 0x0, 0x0},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xeb, 0x4, 0x25, 0x18},
-	 {0xf7, 0x6, 0x19, 0x14},
-	 {0x0, 0xf4, 0x10, 0x38},
-	 {0xeb, 0x4, 0x25, 0x18},
-	 {0xee, 0xc, 0x22, 0x8}
-	}
+UCHAR SiS310_CRT2DelayCompensation1=0x4; /* 301A */
+UCHAR SiS310_LCDDelayCompensation1[]=
+		{0x0,0x0,0x0,0xb,0xb,0xb,0x8,0x8,0x8,0x8,0x8,0x8,
+		 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
+UCHAR SiS310_TVDelayCompensation1[]={0x2,0x2,0x2,0x2,0x8,0xb};
+UCHAR SiS310_CRT2DelayCompensation2=0xC; /* 301B */
+UCHAR SiS310_LCDDelayCompensation2[]=
+		{0x0,0x0,0x0,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x8,
+		 0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
+UCHAR SiS310_TVDelayCompensation2[]={0x3,0x3,0x3,0x3,0x8,0xb};
+UCHAR SiS310_TVAntiFlick1[3][2]={{0x4,0x0},{0x4,0x8},{0x0,0x0}};
+
+UCHAR SiS310_TVEdge1[3][2]={{0x0,0x4},{0x0,0x4},{0x0,0x0}};
+
+UCHAR SiS310_TVYFilter1[3][8][4]=
+{
+ {
+  {0x0,0xf4,0x10,0x38},
+  {0x0,0xf4,0x10,0x38},
+  {0xeb,0x4,0x25,0x18},
+  {0xf7,0x6,0x19,0x14},
+  {0x0,0xf4,0x10,0x38},
+  {0xeb,0x4,0x25,0x18},
+  {0xee,0xc,0x22,0x8},
+  {0xeb,0x15,0x25,0xf6}
+ },
+ {
+  {0x0,0xf4,0x10,0x38},
+  {0x0,0xf4,0x10,0x38},
+  {0xf1,0xf7,0x1f,0x32},
+  {0xf3,0x0,0x1d,0x20},
+  {0x0,0xf4,0x10,0x38},
+  {0xf1,0xf7,0x1f,0x32},
+  {0xf3,0x0,0x1d,0x20},
+  {0xfc,0xfb,0x14,0x2a}
+ },
+ {
+  {0x0,0x0,0x0,0x0},
+  {0x0,0xf4,0x10,0x38},
+  {0x0,0xf4,0x10,0x38},
+  {0xeb,0x4,0x25,0x18},
+  {0xf7,0x6,0x19,0x14},
+  {0x0,0xf4,0x10,0x38},
+  {0xeb,0x4,0x25,0x18},
+  {0xee,0xc,0x22,0x8}
+ }
 };
-
 /*301b*/
-UCHAR SiS310_TVYFilter2[3][9][7] = {
-	{
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	 {0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-	 }
-	,
-	{
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	 {0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	 {0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	 {0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-	}
-	,
-	{
-
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22},
-	 {0x0, 0x0, 0x0, 0xF4, 0xFF, 0x1C, 0x22}
-	}
+UCHAR SiS310_TVYFilter2[3][9][7]=
+{
+ {
+  {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+  {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+  {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+  {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+  {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+  {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+  {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+  {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+  {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+ },
+ {
+  {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+  {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+  {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+  {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+  {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+  {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+  {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+  {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+  {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+ },
+ {
+  
+  {0x0,0x0,0x0,0xF4,0xFF,0x1C,0x22},
+  {0x0,0x0,0x0,0xF4,0xFF,0x1C,0x22},
+  {0x0,0x0,0x0,0xF4,0xFF,0x1C,0x22},
+  {0x0,0x0,0x0,0xF4,0xFF,0x1C,0x22},
+  {0x0,0x0,0x0,0xF4,0xFF,0x1C,0x22},
+  {0x0,0x0,0x0,0xF4,0xFF,0x1C,0x22},
+  {0x0,0x0,0x0,0xF4,0xFF,0x1C,0x22},
+  {0x0,0x0,0x0,0xF4,0xFF,0x1C,0x22}
+ }
 };
 /*end 301b*/
+
 /*add PALMN*/
+UCHAR SiS310_PALMFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+};
+
+UCHAR SiS310_PALNFilter[17][4]={
+	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xff,0xff,0xff,0xff}
+};
+
 
-UCHAR SiS310_PALMFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS310_PALNFilter[17][4] = {
-	{0x00, 0xf4, 0x10, 0x38},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x10, 0x18},
-	{0xf7, 0x06, 0x19, 0x14},
-	{0x00, 0xf4, 0x10, 0x38},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x15, 0x25, 0xf6},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xeb, 0x04, 0x25, 0x18},
-	{0xff, 0xff, 0xff, 0xff}
-};
-
-UCHAR SiS310_PALMFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
-};
-
-UCHAR SiS310_PALNFilter2[9][7] = {
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46},
-	{0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C},
-	{0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38},
-	{0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28}
+UCHAR SiS310_PALMFilter2[9][7]={
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+};
+
+UCHAR SiS310_PALNFilter2[9][7]={
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
 };
 
 /*end PALMN*/
-UCHAR SiS310_TVPhaseIncr1[3][2][4] = {
-	{
-	 {0x21, 0xed, 0x8a, 0x8},
-	 {0x21, 0xed, 0x8a, 0x8}
-	 }
-	,
-	{
-	 {0x2a, 0x5, 0xd3, 0x0},
-	 {0x2a, 0x5, 0xd3, 0x0}
-	 }
-	,
-	{
-	 {0x2a, 0x5, 0xd3, 0x0},
-	 {0x2a, 0x5, 0xd3, 0x0}
-	 }
-};
-
-UCHAR SiS310_TVPhaseIncr2[3][2][4] = {
-	{
-	 {0x21, 0xF0, 0x7b, 0xd6},
-	 {0x21, 0xF0, 0x7b, 0xd6}
-	 }
-	,
-	{
-	 {0x2a, 0x09, 0x86, 0xe9},
-	 {0x2a, 0x09, 0x86, 0xe9}
-	 }
-	,
-	{
-	 {0x2a, 0x5, 0xd3, 0x0},
-	 {0x2a, 0x5, 0xd3, 0x0}
-	 }
+UCHAR SiS310_TVPhaseIncr1[3][2][4]=
+{
+ {
+  {0x21,0xed,0x8a,0x8},
+  {0x21,0xed,0x8a,0x8}
+ },
+ {
+  {0x2a,0x5,0xd3,0x0},
+  {0x2a,0x5,0xd3,0x0}
+ },
+ {
+  {0x2a,0x5,0xd3,0x0},
+  {0x2a,0x5,0xd3,0x0}
+ }
+};
+
+UCHAR SiS310_TVPhaseIncr2[3][2][4]=
+{
+ {
+  {0x21,0xF0,0x7b,0xd6},
+  {0x21,0xF0,0x7b,0xd6}
+ },
+ {
+  {0x2a,0x09,0x86,0xe9},
+  {0x2a,0x09,0x86,0xe9}
+ },
+ {
+  {0x2a,0x5,0xd3,0x0},
+  {0x2a,0x5,0xd3,0x0}
+ }
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/osdef.h linux/drivers/video/sis/osdef.h
--- linux.orig/drivers/video/sis/osdef.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/osdef.h	2002-07-20 01:08:21.000000000 +0000
@@ -1,37 +1,159 @@
-#define LINUX_KERNEL
+/* #define WINCE_HEADER */
+/* #define WIN2000 */
+/* #define TC */
+#define LINUX_KERNEL	   /* Kernel framebuffer */
+/* #define LINUX_XF86 */   /* XFree86 */
 
+/**********************************************************************/
+#ifdef LINUX_KERNEL
+	#include <linux/config.h>
+	#ifdef CONFIG_FB_SIS_300
+ 		#define SIS300
+	#endif
+
+	#ifdef CONFIG_FB_SIS_315
+		#define SIS315H
+	#endif
+#else
+/*	#define SIS300*/
+	#define SIS315H
+#endif
+#ifdef LINUX_XF86
+	#define SIS300
+	/* #define SIS315H */ /* TW: done above */
+#endif
+
+/**********************************************************************/
+#ifdef TC
+#endif
+#ifdef WIN2000
+#endif
+#ifdef WINCE_HEADER
+#endif
+#ifdef LINUX_XF86
+#endif
+#ifdef LINUX_KERNEL
+#endif
+/**********************************************************************/
+#ifdef TC
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+#endif
+#ifdef WIN2000
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
+#endif
+#ifdef WINCE_HEADER
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+#endif
+#ifdef LINUX_XF86
 #define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+#endif
+#ifdef LINUX_KERNEL
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+#endif
+/**********************************************************************/
+
+/**********************************************************************/
+
+#ifdef TC
+#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
+#endif
+#ifdef WIN2000
+#define SiS_MemoryCopy(Destination,Soruce,Length)  /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
+#endif
+#ifdef WINCE_HEADER
+#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
+#endif
+#ifdef LINUX_XF86
 #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+#endif
+#ifdef LINUX_KERNEL
+#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+#endif
 
 /**********************************************************************/
 
 #ifdef OutPortByte
 #undef OutPortByte
-#endif				/* OutPortByte */
+#endif /* OutPortByte */
 
 #ifdef OutPortWord
 #undef OutPortWord
-#endif				/* OutPortWord */
+#endif /* OutPortWord */
 
 #ifdef OutPortLong
 #undef OutPortLong
-#endif				/* OutPortLong */
+#endif /* OutPortLong */
 
 #ifdef InPortByte
 #undef InPortByte
-#endif				/* InPortByte */
+#endif /* InPortByte */
 
 #ifdef InPortWord
 #undef InPortWord
-#endif				/* InPortWord */
+#endif /* InPortWord */
 
 #ifdef InPortLong
 #undef InPortLong
-#endif				/* InPortLong */
+#endif /* InPortLong */
+
+/**********************************************************************/
+/*  TC                                                                */
+/**********************************************************************/
+
+#ifdef TC
+#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
+#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
+#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
+#define InPortByte(p)    inp((unsigned short)(p))
+#define InPortWord(p)    inp((unsigned short)(p))
+#define InPortLong(p)    ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
+#endif
 
+/**********************************************************************/
+/*  LINUX XF86                                                        */
+/**********************************************************************/
+
+#ifdef LINUX_XF86
+#define OutPortByte(p,v) outb((CARD16)(p),(CARD8)(v))
+#define OutPortWord(p,v) outw((CARD16)(p),(CARD16)(v))
+#define OutPortLong(p,v) outl((CARD16)(p),(CARD32)(v))
+#define InPortByte(p)    inb((CARD16)(p))
+#define InPortWord(p)    inw((CARD16)(p))
+#define InPortLong(p)    inl((CARD16)(p))
+#endif
+
+#ifdef LINUX_KERNEL
 #define OutPortByte(p,v) outb((u8)(v),(u16)(p))
 #define OutPortWord(p,v) outw((u16)(v),(u16)(p))
 #define OutPortLong(p,v) outl((u32)(v),(u16)(p))
 #define InPortByte(p)    inb((u16)(p))
 #define InPortWord(p)    inw((u16)(p))
 #define InPortLong(p)    inl((u16)(p))
+#endif
+
+/**********************************************************************/
+/*  WIN 2000                                                          */
+/**********************************************************************/
+
+#ifdef WIN2000
+#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
+#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
+#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
+#define InPortByte(p)    VideoPortReadPortUchar  ((PUCHAR) (p))
+#define InPortWord(p)    VideoPortReadPortUshort ((PUSHORT) (p))
+#define InPortLong(p)    VideoPortReadPortUlong  ((PULONG) (p))
+#endif
+
+
+/**********************************************************************/
+/*  WIN CE                                                          */
+/**********************************************************************/
+
+#ifdef WINCE_HEADER
+#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
+#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
+#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
+#define InPortByte(p)    READ_PORT_UCHAR  ((PUCHAR) (p))
+#define InPortWord(p)    READ_PORT_USHORT ((PUSHORT) (p))
+#define InPortLong(p)    READ_PORT_ULONG  ((PULONG) (p))
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/sis_main.c linux/drivers/video/sis/sis_main.c
--- linux.orig/drivers/video/sis/sis_main.c	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/sis_main.c	2002-07-20 01:08:26.000000000 +0000
@@ -1,16 +1,23 @@
 /*
- * SiS 300/630/540/315H/315 frame buffer device For Kernal 2.4.x
+ * SiS 300/630/730/540/315/550/650/740 frame buffer device
+ * for Linux kernels 2.4.x and 2.5.x
  *
- * This driver is partly based on the VBE 2.0 compliant graphic 
- * boards framebuffer driver, which is 
- * 
- * (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ * Partly based on the VBE 2.0 compliant graphic boards framebuffer driver,
+ * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
  *
+ * Authors:   	SiS (www.sis.com.tw)
+ *		(Various others)
+ *		Thomas Winischhofer <thomas@winischhofer.net>:
+ *			- many fixes and enhancements for 630 & 310 series,
+ *			- extended bridge handling, TV output for Chrontel
+ *			- memory queue handling enhancements,
+ *			- everything marked with "TW"
+ *			(see http://www.winischhofer.net/linuxsis630.shtml
+ *			for more information and updates)
  */
 
-//#undef SISFBDEBUG
-
 #include <linux/config.h>
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -29,6 +36,7 @@
 #include <linux/capability.h>
 #include <linux/fs.h>
 #include <linux/agp_backend.h>
+
 #include <linux/types.h>
 #include <linux/sisfb.h>
 
@@ -44,9 +52,13 @@
 #include "osdef.h"
 #include "vgatypes.h"
 #include "sis_main.h"
+//#ifdef LINUXBIOS
+//#include "bios.h"
+//#endif
 
 /* -------------------- Macro definitions ---------------------------- */
-
+// #define SISFBDEBUG
+#undef SISFBDEBUG /* TW */
 #ifdef SISFBDEBUG
 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
 #else
@@ -64,71 +76,88 @@
 
 /* --------------- Hardware Access Routines -------------------------- */
 
-void sisfb_set_reg1 (u16 port, u16 index, u16 data)
+void sisfb_set_reg1(u16 port, u16 index, u16 data)
 {
-	outb ((u8) (index & 0xff), port);
+	outb((u8) (index & 0xff), port);
 	port++;
-	outb ((u8) (data & 0xff), port);
+	outb((u8) (data & 0xff), port);
 }
 
-void sisfb_set_reg3 (u16 port, u16 data)
+void sisfb_set_reg3(u16 port, u16 data)
 {
-	outb ((u8) (data & 0xff), port);
+	outb((u8) (data & 0xff), port);
 }
 
-void sisfb_set_reg4 (u16 port, unsigned long data)
+void sisfb_set_reg4(u16 port, unsigned long data)
 {
-	outl ((u32) (data & 0xffffffff), port);
+	outl((u32) (data & 0xffffffff), port);
 }
 
-u8 sisfb_get_reg1 (u16 port, u16 index)
+u8 sisfb_get_reg1(u16 port, u16 index)
 {
 	u8 data;
 
-	outb ((u8) (index & 0xff), port);
+	outb((u8) (index & 0xff), port);
 	port += 1;
-	data = inb (port);
+	data = inb(port);
 	return (data);
 }
 
-u8 sisfb_get_reg2 (u16 port)
+u8 sisfb_get_reg2(u16 port)
 {
 	u8 data;
 
-	data = inb (port);
-
+	data = inb(port);
 	return (data);
 }
 
-u32 sisfb_get_reg3 (u16 port)
+u32 sisfb_get_reg3(u16 port)
 {
 	u32 data;
 
-	data = inl (port);
+	data = inl(port);
 	return (data);
 }
 
+// Eden Chen
+//void sisfb_clear_DAC(u16 port)
+//{
+//	int i,j;
+//
+//	vgawb(DAC_ADR, 0x00);
+//	for(i=0; i<256; i++)
+//		for(j=0; j<3; j++)
+//			vgawb(DAC_DATA, 0);
+//}
+
+//void sisfb_clear_buffer(PHW_DEVICE_EXTENSION psishw_ext)
+//{
+//	memset((char *) ivideo.video_vbase, 0,
+//		video_linelength * ivideo.video_height);
+//}
+// ~Eden Chen
+
 /* --------------- Interface to BIOS code ---------------------------- */
 
-BOOLEAN sisfb_query_VGA_config_space (PSIS_HW_DEVICE_INFO psishw_ext,
-			      unsigned long offset, unsigned long set,
-			      unsigned long *value)
+BOOLEAN
+sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext,
+	unsigned long offset, unsigned long set, unsigned long *value)
 {
 	static struct pci_dev *pdev = NULL;
 	static unsigned char init = 0, valid_pdev = 0;
 
 	if (!set)
-		DPRINTK ("Get VGA offset 0x%lx\n", offset);
+		DPRINTK("sisfb: Get VGA offset 0x%lx\n", offset);
 	else
-		DPRINTK ("Set offset 0x%lx to 0x%lx\n", offset, *value);
+		DPRINTK("sisfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
 
 	if (!init) {
 		init = TRUE;
-		pci_for_each_dev (pdev) {
-			DPRINTK ("Current: 0x%x, target: 0x%x\n", pdev->device,
-				 ivideo.chip_id);
+		pci_for_each_dev(pdev) {
+			DPRINTK("sisfb: Current: 0x%x, target: 0x%x\n",
+			         pdev->device, ivideo.chip_id);
 			if ((pdev->vendor == PCI_VENDOR_ID_SI)
-			    && (pdev->device == ivideo.chip_id)) {
+			           && (pdev->device == ivideo.chip_id)) {
 				valid_pdev = TRUE;
 				break;
 			}
@@ -136,22 +165,21 @@
 	}
 
 	if (!valid_pdev) {
-		printk (KERN_DEBUG "Can't find SiS %d VGA device.\n",
-			ivideo.chip_id);
+		printk(KERN_DEBUG "sisfb: Can't find SiS %d VGA device.\n",
+				ivideo.chip_id);
 		return FALSE;
 	}
 
 	if (set == 0)
-		pci_read_config_dword (pdev, offset, (u32 *) value);
+		pci_read_config_dword(pdev, offset, (u32 *)value);
 	else
-		pci_write_config_dword (pdev, offset, (u32) (*value));
+		pci_write_config_dword(pdev, offset, (u32)(*value));
 
 	return TRUE;
 }
 
-BOOLEAN sisfb_query_north_bridge_space (PSIS_HW_DEVICE_INFO psishw_ext,
-				unsigned long offset, unsigned long set,
-				unsigned long *value)
+BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext, 
+	unsigned long offset, unsigned long set, unsigned long *value)
 {
 	static struct pci_dev *pdev = NULL;
 	static unsigned char init = 0, valid_pdev = 0;
@@ -172,16 +200,19 @@
 		case SIS_550:
 			nbridge_id = PCI_DEVICE_ID_SI_550;
 			break;
+		case SIS_650:
+			nbridge_id = PCI_DEVICE_ID_SI_650;
+			break;
 		default:
 			nbridge_id = 0;
 			break;
 		}
 
-		pci_for_each_dev (pdev) {
-			DPRINTK ("Current: 0x%x, target: 0x%x\n", pdev->device,
-				 ivideo.chip_id);
+		pci_for_each_dev(pdev) {
+			DPRINTK("Current: 0x%x, target: 0x%x\n",
+					pdev->device, ivideo.chip_id);
 			if ((pdev->vendor == PCI_VENDOR_ID_SI)
-			    && (pdev->device == nbridge_id)) {
+					&& (pdev->device == nbridge_id)) {
 				valid_pdev = TRUE;
 				break;
 			}
@@ -189,22 +220,22 @@
 	}
 
 	if (!valid_pdev) {
-		printk (KERN_DEBUG "Can't find SiS %d North Bridge device.\n",
-			nbridge_id);
+		printk(KERN_DEBUG "sisfb: Can't find SiS %d North Bridge device.\n",
+				nbridge_id);
 		return FALSE;
 	}
 
 	if (set == 0)
-		pci_read_config_dword (pdev, offset, (u32 *) value);
+		pci_read_config_dword(pdev, offset, (u32 *)value);
 	else
-		pci_write_config_dword (pdev, offset, (u32) (*value));
+		pci_write_config_dword(pdev, offset, (u32)(*value));
 
 	return TRUE;
 }
 
 /* -------------------- Export functions ----------------------------- */
 
-static void sis_get_glyph (SIS_GLYINFO * gly)
+static void sis_get_glyph(SIS_GLYINFO *gly)
 {
 	struct display *p = &fb_display[currcon];
 	u16 c;
@@ -213,44 +244,45 @@
 	u8 *gbuf = gly->gmask;
 	int size;
 
-	gly->fontheight = fontheight (p);
-	gly->fontwidth = fontwidth (p);
-	widthb = (fontwidth (p) + 7) / 8;
+
+	gly->fontheight = fontheight(p);
+	gly->fontwidth = fontwidth(p);
+	widthb = (fontwidth(p) + 7) / 8;
 
 	c = gly->ch & p->charmask;
-	if (fontwidth (p) <= 8)
-		cdat = p->fontdata + c * fontheight (p);
+	if (fontwidth(p) <= 8)
+		cdat = p->fontdata + c * fontheight(p);
 	else
-		cdat = p->fontdata + (c * fontheight (p) << 1);
+		cdat = p->fontdata + (c * fontheight(p) << 1);
 
-	size = fontheight (p) * widthb;
-	memcpy (gbuf, cdat, size);
+	size = fontheight(p) * widthb;
+	memcpy(gbuf, cdat, size);
 	gly->ngmask = size;
 }
 
-void sis_dispinfo (struct ap_data *rec)
+void sis_dispinfo(struct ap_data *rec)
 {
-	rec->minfo.bpp = ivideo.video_bpp;
-	rec->minfo.xres = ivideo.video_width;
-	rec->minfo.yres = ivideo.video_height;
+	rec->minfo.bpp    = ivideo.video_bpp;
+	rec->minfo.xres   = ivideo.video_width;
+	rec->minfo.yres   = ivideo.video_height;
 	rec->minfo.v_xres = ivideo.video_vwidth;
 	rec->minfo.v_yres = ivideo.video_vheight;
-	rec->minfo.org_x = ivideo.org_x;
-	rec->minfo.org_y = ivideo.org_y;
-	rec->minfo.vrate = ivideo.refresh_rate;
-	rec->iobase = ivideo.vga_base - 0x30;
-	rec->mem_size = ivideo.video_size;
-	rec->disp_state = ivideo.disp_state;
-	rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
-	rec->hasVB = ivideo.hasVB;
-	rec->TV_type = ivideo.TV_type;
-	rec->TV_plug = ivideo.TV_plug;
-	rec->chip = ivideo.chip;
+	rec->minfo.org_x  = ivideo.org_x;
+	rec->minfo.org_y  = ivideo.org_y;
+	rec->minfo.vrate  = ivideo.refresh_rate;
+	rec->iobase       = ivideo.vga_base - 0x30;
+	rec->mem_size     = ivideo.video_size;
+	rec->disp_state   = ivideo.disp_state; 
+	rec->version      = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL; 
+	rec->hasVB        = ivideo.hasVB; 
+	rec->TV_type      = ivideo.TV_type; 
+	rec->TV_plug      = ivideo.TV_plug; 
+	rec->chip         = ivideo.chip;
 }
 
 /* ------------------ Internal Routines ------------------------------ */
 
-static void sisfb_search_mode (const char *name)
+static void sisfb_search_mode(const char *name)
 {
 	int i = 0;
 
@@ -258,23 +290,21 @@
 		return;
 
 	while (sisbios_mode[i].mode_no != 0) {
-		if (!strcmp (name, sisbios_mode[i].name)) {
+		if (!strcmp(name, sisbios_mode[i].name)) {
 			sisfb_mode_idx = i;
 			break;
 		}
 		i++;
 	}
-
 	if (sisfb_mode_idx < 0)
-		DPRINTK ("Invalid user mode : %s\n", name);
+		printk(KERN_INFO "sisfb: Invalid mode '%s'\n", name);
 }
 
-static void sisfb_validate_mode (void)
+static void sisfb_validate_mode(void)
 {
 	switch (ivideo.disp_state & DISPTYPE_DISP2) {
 	case DISPTYPE_LCD:
-// Eden Chen
-		switch (sishw_ext.ulCRT2LCDType) {
+	    switch (sishw_ext.ulCRT2LCDType) {
 		case LCD_1024x768:
 			if (sisbios_mode[sisfb_mode_idx].xres > 1024)
 				sisfb_mode_idx = -1;
@@ -304,16 +334,18 @@
 			if (sisbios_mode[sisfb_mode_idx].xres > 640)
 				sisfb_mode_idx = -1;
 			break;
+		case LCD_320x480:	/* TW: FSTN */
+			if (sisbios_mode[sisfb_mode_idx].xres > 320)
+				sisfb_mode_idx = -1;
+			break;
 		default:
 			sisfb_mode_idx = -1;
 		}
-// ~Eden Chen
-
 		if (sisbios_mode[sisfb_mode_idx].xres == 720)
 			sisfb_mode_idx = -1;
 		break;
 	case DISPTYPE_TV:
-		switch (sisbios_mode[sisfb_mode_idx].xres) {
+	    switch (sisbios_mode[sisfb_mode_idx].xres) {
 		case 800:
 		case 640:
 			break;
@@ -325,13 +357,23 @@
 				if (sisbios_mode[sisfb_mode_idx].yres != 576)
 					sisfb_mode_idx = -1;
 			}
+			/* TW: LVDS/CHRONTEL only supports 640 and 800 */
+			if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+						ivideo.hasVB == HASVB_CHRONTEL)
+					sisfb_mode_idx = -1;
 			break;
-			/*karl */
 		case 1024:
 			if (ivideo.TV_type == TVMODE_NTSC) {
-				if (sisbios_mode[sisfb_mode_idx].bpp == 32)
-					sisfb_mode_idx -= 1;
+				if(sisbios_mode[sisfb_mode_idx].bpp == 32)
+				       sisfb_mode_idx = -1; /* TW; was -= 1 */
+				       /* TW: Should this mean a switch-back to
+				        *     16bpp or simply 'illegal mode'?
+					*/
 			}
+			/* TW: LVDS/CHRONTEL only supports 640 and 800 */
+			if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+						ivideo.hasVB == HASVB_CHRONTEL)
+					sisfb_mode_idx = -1;
 			break;
 		default:
 			sisfb_mode_idx = -1;
@@ -340,7 +382,43 @@
 	}
 }
 
-static u8 sisfb_search_refresh_rate (unsigned int rate)
+static void sisfb_search_crt2type(const char *name)
+{
+	int i = 0;
+
+	if (name == NULL)
+		return;
+
+	while (sis_crt2type[i].type_no != -1) {
+		if (!strcmp(name, sis_crt2type[i].name)) {
+			sisfb_crt2type = sis_crt2type[i].type_no;
+			break;
+		}
+		i++;
+	}
+	if (sisfb_crt2type < 0)
+		printk(KERN_INFO "sisfb: Invalid CRT2 type: %s\n", name);
+}
+
+static void sisfb_search_queuemode(const char *name)
+{
+	int i = 0;
+
+	if (name == NULL)
+		return;
+
+	while (sis_queuemode[i].type_no != -1) {
+		if (!strcmp(name, sis_queuemode[i].name)) {
+			sisfb_queuemode = sis_queuemode[i].type_no;
+			break;
+		}
+		i++;
+	}
+	if (sisfb_queuemode < 0)
+		printk(KERN_INFO "sisfb: Invalid queuemode type: %s\n", name);
+}
+
+static u8 sisfb_search_refresh_rate(unsigned int rate)
 {
 	u16 xres, yres;
 	int i = 0;
@@ -350,44 +428,39 @@
 
 	sisfb_rate_idx = 0;
 	while ((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
-		if ((sisfb_vrate[i].xres == xres)
-		    && (sisfb_vrate[i].yres == yres)) {
+		if ((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
 			if (sisfb_vrate[i].refresh == rate) {
 				sisfb_rate_idx = sisfb_vrate[i].idx;
 				break;
 			} else if (sisfb_vrate[i].refresh > rate) {
 				if ((sisfb_vrate[i].refresh - rate) <= 2) {
-					DPRINTK
-					    ("Adjust rate from %d up to %d\n",
-					     rate, sisfb_vrate[i].refresh);
+					DPRINTK("sisfb: Adjusting rate from %d up to %d\n",
+						rate, sisfb_vrate[i].refresh);
 					sisfb_rate_idx = sisfb_vrate[i].idx;
-					ivideo.refresh_rate =
-					    sisfb_vrate[i].refresh;
-				} else if (((rate - sisfb_vrate[i - 1].refresh) <=  2) 
-				    	&& (sisfb_vrate[i].idx != 1)) {
-					DPRINTK("Adjust rate from %d down to %d\n",
-					     rate, sisfb_vrate[i - 1].refresh);
-					sisfb_rate_idx = sisfb_vrate[i - 1].idx;
-					ivideo.refresh_rate = sisfb_vrate[i - 1].refresh;
+					ivideo.refresh_rate = sisfb_vrate[i].refresh;
+				} else if (((rate - sisfb_vrate[i-1].refresh) <= 2)
+						&& (sisfb_vrate[i].idx != 1)) {
+					DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
+						rate, sisfb_vrate[i-1].refresh);
+					sisfb_rate_idx = sisfb_vrate[i-1].idx;
+					ivideo.refresh_rate = sisfb_vrate[i-1].refresh;
 				}
 				break;
 			}
 		}
 		i++;
 	}
-
 	if (sisfb_rate_idx > 0) {
 		return sisfb_rate_idx;
 	} else {
-		DPRINTK ("Unsupported rate %d for %dx%d mode\n", rate, xres,
-			 yres);
+		printk(KERN_INFO
+			"sisfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
 		return 0;
 	}
-
 }
 
-static int sis_getcolreg (unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
-	       unsigned *transp, struct fb_info *fb_info)
+static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+			 unsigned *transp, struct fb_info *fb_info)
 {
 	if (regno >= video_cmap_len)
 		return 1;
@@ -399,10 +472,9 @@
 	return 0;
 }
 
-static int sis_setcolreg (unsigned regno, unsigned red, unsigned green, unsigned blue,
-	       unsigned transp, struct fb_info *fb_info)
+static int sis_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+			 unsigned transp, struct fb_info *fb_info)
 {
-
 	if (regno >= video_cmap_len)
 		return 1;
 
@@ -413,17 +485,16 @@
 	switch (ivideo.video_bpp) {
 #ifdef FBCON_HAS_CFB8
 	case 8:
-		vgawb (DAC_ADR, regno);
-		vgawb (DAC_DATA, red >> 10);
-		vgawb (DAC_DATA, green >> 10);
-		vgawb (DAC_DATA, blue >> 10);
+		vgawb(DAC_ADR, regno);
+		vgawb(DAC_DATA, red >> 10);
+		vgawb(DAC_DATA, green >> 10);
+		vgawb(DAC_DATA, blue >> 10);
 		if (ivideo.disp_state & DISPTYPE_DISP2) {
-			vgawb (DAC2_ADR, regno);
-			vgawb (DAC2_DATA, red >> 8);
-			vgawb (DAC2_DATA, green >> 8);
-			vgawb (DAC2_DATA, blue >> 8);
+		 	vgawb(DAC2_ADR,  regno);
+			vgawb(DAC2_DATA, red >> 8);
+			vgawb(DAC2_DATA, green >> 8);
+			vgawb(DAC2_DATA, blue >> 8);
 		}
-
 		break;
 #endif
 #ifdef FBCON_HAS_CFB16
@@ -439,7 +510,8 @@
 		red >>= 8;
 		green >>= 8;
 		blue >>= 8;
-		fbcon_cmap.cfb24[regno] = (red << 16) | (green << 8) | (blue);
+		fbcon_cmap.cfb24[regno] =
+		    (red << 16) | (green << 8) | (blue);
 		break;
 #endif
 #ifdef FBCON_HAS_CFB32
@@ -447,33 +519,44 @@
 		red >>= 8;
 		green >>= 8;
 		blue >>= 8;
-		fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
+		fbcon_cmap.cfb32[regno] =
+		    (red << 16) | (green << 8) | (blue);
 		break;
 #endif
 	}
 	return 0;
 }
 
-static int sisfb_do_set_var (struct fb_var_screeninfo *var, int isactive,
-		  struct fb_info *info)
+static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
+		      struct fb_info *info)
 {
 	unsigned int htotal =
-	    var->left_margin + var->xres + var->right_margin + var->hsync_len;
-	unsigned int vtotal =
-	    var->upper_margin + var->yres + var->lower_margin + var->vsync_len;
+		var->left_margin + var->xres + var->right_margin +
+		var->hsync_len;
+	unsigned int vtotal = 0; /* TW */
+	/*	var->upper_margin + var->yres + var->lower_margin +
+		var->vsync_len;     */
 	double drate = 0, hrate = 0;
 	int found_mode = 0;
 	int old_mode;
 
-	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
+	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+		vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;   /* TW */
 		vtotal <<= 1;
-	else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
+	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;   /* TW */
 		vtotal <<= 2;
-	else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
-		var->yres <<= 1;
+	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
+		         var->vsync_len;   /* TW */
+		/* var->yres <<= 1; */ /* TW */
+	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;
 
-	if (!htotal || !vtotal) {
-		DPRINTK ("Invalid 'var' Information!\n");
+	if (!(htotal) || !(vtotal)) {
+		DPRINTK("sisfb: Invalid 'var' information\n");
 		return -EINVAL;
 	}
 
@@ -481,9 +564,8 @@
 	hrate = drate / htotal;
 	ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
 
-	DPRINTK ("Chagne mode to %dx%dx%d-%dMHz\n",
-		 var->xres, var->yres, var->bits_per_pixel,
-		 ivideo.refresh_rate);
+	DPRINTK("sisfb: Change mode to %dx%dx%d-%dMHz\n",
+		var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
 
 	old_mode = sisfb_mode_idx;
 	sisfb_mode_idx = 0;
@@ -492,8 +574,7 @@
 	       && (sisbios_mode[sisfb_mode_idx].xres <= var->xres)) {
 		if ((sisbios_mode[sisfb_mode_idx].xres == var->xres)
 		    && (sisbios_mode[sisfb_mode_idx].yres == var->yres)
-		    && (sisbios_mode[sisfb_mode_idx].bpp ==
-			var->bits_per_pixel)) {
+		    && (sisbios_mode[sisfb_mode_idx].bpp == var->bits_per_pixel)) {
 			sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
 			found_mode = 1;
 			break;
@@ -502,70 +583,51 @@
 	}
 
 	if (found_mode)
-		sisfb_validate_mode ();
+		sisfb_validate_mode();
 	else
 		sisfb_mode_idx = -1;
 
-	if (sisfb_mode_idx < 0) {
-		DPRINTK ("sisfb does not support mode %dx%d-%d\n", var->xres,
-			 var->yres, var->bits_per_pixel);
+       	if (sisfb_mode_idx < 0) {
+		DPRINTK("sisfb: sisfb does not support mode %dx%d-%d\n", var->xres,
+		       var->yres, var->bits_per_pixel);
 		sisfb_mode_idx = old_mode;
 		return -EINVAL;
 	}
 
-	if (sisfb_search_refresh_rate (ivideo.refresh_rate) == 0) {
+	if (sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {
 		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
 		ivideo.refresh_rate = 60;
 	}
 
 	if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
-		sisfb_pre_setmode ();
 
-// Eden Chen
-/*
-#ifdef CONFIG_FB_SIS_300
-		if (SiSSetMode(&sishw_ext, sisfb_mode_no)) {
-			DPRINTK("set mode[0x%x]: failed\n", sisfb_mode_no);
-			return -1;
-		}
-#endif
+		sisfb_pre_setmode();
 
-#ifdef CONFIG_FB_SIS_315
-		if (SiSSetMode310(&sishw_ext, sisfb_mode_no)) {
-			DPRINTK("set mode[0x%x]: failed\n", sisfb_mode_no);
+		if (SiSSetMode(&sishw_ext, sisfb_mode_no) == 0) {
+			DPRINTK("sisfb: Setting mode[0x%x]: failed\n", sisfb_mode_no);
 			return -1;
 		}
 
-#endif
-*/
-		if (SiSSetMode (&sishw_ext, sisfb_mode_no) == 0) {
-			DPRINTK ("set mode[0x%x]: failed\n", sisfb_mode_no);
-			return -1;
-		}
+		vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+		vgawb(SEQ_DATA, SIS_PASSWORD);
 
-		vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-		vgawb (SEQ_DATA, SIS_PASSWORD);
-// ~Eden Chen
-		sisfb_post_setmode ();
+		sisfb_post_setmode();
 
-		DPRINTK ("Set New Mode : %dx%dx%d-%d \n",
-			 sisbios_mode[sisfb_mode_idx].xres,
-			 sisbios_mode[sisfb_mode_idx].yres,
-			 sisbios_mode[sisfb_mode_idx].bpp, ivideo.refresh_rate);
+		DPRINTK("sisfb: Set new mode: %dx%dx%d-%d \n", sisbios_mode[sisfb_mode_idx].xres,
+			sisbios_mode[sisfb_mode_idx].yres, sisbios_mode[sisfb_mode_idx].bpp,
+			ivideo.refresh_rate);
 
 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
-		ivideo.video_vwidth = ivideo.video_width =
-		    sisbios_mode[sisfb_mode_idx].xres;
-		ivideo.video_vheight = ivideo.video_height =
-		    sisbios_mode[sisfb_mode_idx].yres;
+		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
+		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
 		ivideo.org_x = ivideo.org_y = 0;
-		video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
-
+		video_linelength =
+		    ivideo.video_width * (ivideo.video_bpp >> 3);
 	}
 	return 0;
 }
 
-static void sisfb_set_disp (int con, struct fb_var_screeninfo *var)
+static void sisfb_set_disp(int con, struct fb_var_screeninfo *var)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
@@ -575,9 +637,9 @@
 	if (con >= 0)
 		display = &fb_display[con];
 	else
-		display = &disp;
+		display = &disp;	
 
-	sisfb_get_fix (&fix, con, 0);
+	sisfb_get_fix(&fix, con, 0);
 
 	display->screen_base = ivideo.video_vbase;
 	display->visual = fix.visual;
@@ -591,140 +653,136 @@
 	display->inverse = sisfb_inverse;
 	display->var = *var;
 
-	save_flags (flags);
+	save_flags(flags);
 	switch (ivideo.video_bpp) {
 #ifdef FBCON_HAS_CFB8
-	case 8:
+	   case 8:
 		sw = &fbcon_cfb8;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB16
-	case 15:
-	case 16:
+	   case 15:
+	   case 16:
 		sw = &fbcon_cfb16;
 		display->dispsw_data = fbcon_cmap.cfb16;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB24
-	case 24:
+	   case 24:
 		sw = &fbcon_cfb24;
 		display->dispsw_data = fbcon_cmap.cfb24;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB32
-	case 32:
+	   case 32:
 		sw = &fbcon_cfb32;
 		display->dispsw_data = fbcon_cmap.cfb32;
 		break;
 #endif
-	default:
+	   default:
 		sw = &fbcon_dummy;
 		return;
 	}
-	memcpy (&sisfb_sw, sw, sizeof (*sw));
+	memcpy(&sisfb_sw, sw, sizeof(*sw));
 	display->dispsw = &sisfb_sw;
-	restore_flags (flags);
+	restore_flags(flags);
 
 	display->scrollmode = SCROLL_YREDRAW;
 	sisfb_sw.bmove = fbcon_redraw_bmove;
 }
 
-static void sisfb_do_install_cmap (int con, struct fb_info *info)
+static void sisfb_do_install_cmap(int con, struct fb_info *info)
 {
 	if (con != currcon)
 		return;
 
 	if (fb_display[con].cmap.len)
-		fb_set_cmap (&fb_display[con].cmap, 1, sis_setcolreg, info);
+		fb_set_cmap(&fb_display[con].cmap, 1, sis_setcolreg, info);
 	else
-		fb_set_cmap (fb_default_cmap (video_cmap_len), 1,
-			     sis_setcolreg, info);
+		fb_set_cmap(fb_default_cmap(video_cmap_len), 1,
+			    sis_setcolreg, info);
 }
 
+
 /* --------------- Chip-dependent Routines --------------------------- */
 
-#ifdef CONFIG_FB_SIS_300	/* for SiS 300/630/540/730 */
-static int sisfb_get_dram_size_300 (void)
+#ifdef CONFIG_FB_SIS_300 /* for SiS 300/630/540/730 */
+static int sisfb_get_dram_size_300(void)
 {
 	struct pci_dev *pdev = NULL;
 	int pdev_valid = 0;
-	u8 pci_data, reg;
+	u8  pci_data, reg;
 	u16 nbridge_id;
 
 	switch (ivideo.chip) {
-	case SIS_540:
+	   case SIS_540:
 		nbridge_id = PCI_DEVICE_ID_SI_540;
 		break;
-	case SIS_630:
+	   case SIS_630:
 		nbridge_id = PCI_DEVICE_ID_SI_630;
 		break;
-	case SIS_730:
+	   case SIS_730:
 		nbridge_id = PCI_DEVICE_ID_SI_730;
 		break;
-	default:
+	   default:
 		nbridge_id = 0;
 		break;
 	}
 
-	if (nbridge_id == 0) {
-		vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
+	if (nbridge_id == 0) {  /* 300 */
+		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
 		ivideo.video_size =
-		    ((unsigned
-		      int) ((vgarb (SEQ_DATA) & SIS_DRAM_SIZE_MASK) + 1) << 20);
-	} else {
-		pci_for_each_dev (pdev) {
-			if ((pdev->vendor == PCI_VENDOR_ID_SI)
-			    && (pdev->device == nbridge_id)) {
-				//&& (pdev->device == PCI_DEVICE_ID_SI_630)) {
-				pci_read_config_byte (pdev, IND_BRI_DRAM_STATUS,
-						      &pci_data);
+		        ((unsigned int) ((vgarb(SEQ_DATA) & SIS_DRAM_SIZE_MASK) + 1) << 20);
+	} else {		/* 540, 630, 730 */
+		pci_for_each_dev(pdev) {
+			if ((pdev->vendor == PCI_VENDOR_ID_SI) 
+				&& (pdev->device == nbridge_id)) {
+				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
-				ivideo.video_size =
-				    (unsigned int) (1 << (pci_data + 21));
+				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
 				pdev_valid = 1;
-
+	
 				reg = SIS_DATA_BUS_64 << 6;
-				vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
+				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
 				switch (pci_data) {
-				case BRI_DRAM_SIZE_2MB:
+				   case BRI_DRAM_SIZE_2MB:
 					reg |= SIS_DRAM_SIZE_2MB;
 					break;
-				case BRI_DRAM_SIZE_4MB:
+				   case BRI_DRAM_SIZE_4MB:
 					reg |= SIS_DRAM_SIZE_4MB;
 					break;
-				case BRI_DRAM_SIZE_8MB:
+				   case BRI_DRAM_SIZE_8MB:
 					reg |= SIS_DRAM_SIZE_8MB;
 					break;
-				case BRI_DRAM_SIZE_16MB:
+				   case BRI_DRAM_SIZE_16MB:
 					reg |= SIS_DRAM_SIZE_16MB;
 					break;
-				case BRI_DRAM_SIZE_32MB:
+				   case BRI_DRAM_SIZE_32MB:
 					reg |= SIS_DRAM_SIZE_32MB;
 					break;
-				case BRI_DRAM_SIZE_64MB:
+				   case BRI_DRAM_SIZE_64MB:
 					reg |= SIS_DRAM_SIZE_64MB;
 					break;
 				}
-				vgawb (SEQ_DATA, reg);
+				vgawb(SEQ_DATA, reg);
 				break;
-			}
-		}
-
+			}  
+		}   
+	
 		if (!pdev_valid)
 			return -1;
 	}
-
 	return 0;
 }
 
-static void sisfb_detect_VB_connect_300(void)
+static void sisfb_detect_VB_connect_300()
 {
 	u8 sr16, sr17, cr32, temp;
 
-	vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_17);
-	sr17 = vgarb (SEQ_DATA);
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
-	cr32 = vgarb (CRTC_DATA);
+	vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
+	sr17 = vgarb(SEQ_DATA);
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
+	cr32 = vgarb(CRTC_DATA);
 
 	ivideo.TV_plug = ivideo.TV_type = 0;
 	if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
@@ -737,25 +795,29 @@
 				sisfb_crt1off = 0;
 		}
 
-		if (sr17 & 0x08)
+		if (sisfb_crt2type != -1)
+			/* TW: override detected CRT2 type */
+			ivideo.disp_state = sisfb_crt2type;
+		else if (sr17 & 0x08 )
 			ivideo.disp_state = DISPTYPE_CRT2;
 		else if (sr17 & 0x02)
 			ivideo.disp_state = DISPTYPE_LCD;
-		else if (sr17 & 0x04) {
+		else if (sr17 & 0x04)
 			ivideo.disp_state = DISPTYPE_TV;
-			if (sr17 & 0x20)
-				ivideo.TV_plug = TVPLUG_SVIDEO;
-			else if (sr17 & 0x10)
-				ivideo.TV_plug = TVPLUG_COMPOSITE;
-
-			vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_16);
-			sr16 = vgarb (SEQ_DATA);
-			if (sr16 & 0x20)
-				ivideo.TV_type = TVMODE_PAL;
-			else
-				ivideo.TV_type = TVMODE_NTSC;
-		} else
+		else
 			ivideo.disp_state = 0;
+
+		if (sr17 & 0x20)
+			ivideo.TV_plug = TVPLUG_SVIDEO;
+		else if (sr17 & 0x10)
+			ivideo.TV_plug = TVPLUG_COMPOSITE;
+
+		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_16);
+		sr16 = vgarb(SEQ_DATA);
+		if (sr16 & 0x20)
+			ivideo.TV_type = TVMODE_PAL;
+		else
+			ivideo.TV_type = TVMODE_NTSC;
 	} else {
 		if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
 			sisfb_crt1off = 0;
@@ -766,79 +828,98 @@
 				sisfb_crt1off = 0;
 		}
 
-		if (cr32 & SIS_VB_CRT2)
+		if (sisfb_crt2type != -1)
+			/* TW: override detected CRT2 type */
+			ivideo.disp_state = sisfb_crt2type;
+		else if (cr32 & SIS_VB_CRT2)
 			ivideo.disp_state = DISPTYPE_CRT2;
 		else if (cr32 & SIS_VB_LCD)
 			ivideo.disp_state = DISPTYPE_LCD;
-		else if (cr32 & SIS_VB_TV) {
+		else if (cr32 & SIS_VB_TV)
 			ivideo.disp_state = DISPTYPE_TV;
-			if (cr32 & SIS_VB_HIVISION) {
-				ivideo.TV_type = TVMODE_HIVISION;
-				ivideo.TV_plug = TVPLUG_SVIDEO;
-			} else if (cr32 & SIS_VB_SVIDEO)
-				ivideo.TV_plug = TVPLUG_SVIDEO;
-			else if (cr32 & SIS_VB_COMPOSITE)
-				ivideo.TV_plug = TVPLUG_COMPOSITE;
-			else if (cr32 & SIS_VB_SCART)
-				ivideo.TV_plug = TVPLUG_SCART;
+		else
+			ivideo.disp_state = 0;
 
-			if (ivideo.TV_type == 0) {
-				// Eden Chen
-				//temp = *((u8 *)(sishw_ext.VirtualRomBase+0x52));
-				//if (temp&0x40) {
-				//      temp=*((u8 *)(sishw_ext.VirtualRomBase+0x53));
+		/* TW: Detect TV plug & type anyway */
+		if (cr32 & SIS_VB_HIVISION) {
+			ivideo.TV_type = TVMODE_HIVISION;
+			ivideo.TV_plug = TVPLUG_SVIDEO;
+		}
+		else if (cr32 & SIS_VB_SVIDEO)
+			ivideo.TV_plug = TVPLUG_SVIDEO;
+		else if (cr32 & SIS_VB_COMPOSITE)
+			ivideo.TV_plug = TVPLUG_COMPOSITE;
+		else if (cr32 & SIS_VB_SCART)
+			ivideo.TV_plug = TVPLUG_SCART;
+
+		if (ivideo.TV_type == 0) {
+			// Eden Chen
+			//temp = *((u8 *)(sishw_ext.VirtualRomBase+0x52));
+			//if (temp&0x40) {
+			//	temp=*((u8 *)(sishw_ext.VirtualRomBase+0x53));
 				//} else {
-				vgawb (SEQ_ADR, IND_SIS_POWER_ON_TRAP);
-				temp = vgarb (SEQ_DATA);
-				//}
-				// ~Eden Chen
-				if (temp & 0x01)
-					ivideo.TV_type = TVMODE_PAL;
-				else
-					ivideo.TV_type = TVMODE_NTSC;
-			}
-		} else
-			ivideo.disp_state = 0;
+			vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP);
+			temp = vgarb(SEQ_DATA);
+			//}
+			// ~Eden Chen
+			if (temp & 0x01)
+				ivideo.TV_type = TVMODE_PAL;
+			else
+				ivideo.TV_type = TVMODE_NTSC;
+		}
 	}
+
+	/* TW: Copy forceCRT1 option to CRT1off if option is given */
+    	if (sisfb_forcecrt1 != -1) {
+		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
+    		sr17 = vgarb(SEQ_DATA);
+    		if (sisfb_forcecrt1) {
+			sisfb_crt1off=0;
+			sr17 |= 0x80;
+		} else {
+			sisfb_crt1off=1;
+			sr17 &= ~0x80;
+		}
+		vgawb(SEQ_DATA, sr17);
+    	}
 }
 
-static void sisfb_get_VB_type_300 (void)
+static void sisfb_get_VB_type_300(void)
 {
 	u8 reg;
 
 	if (ivideo.chip != SIS_300) {
-		if (!sisfb_has_VB_300 ()) {
-			vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR37);
-			reg = vgarb (CRTC_DATA);
+		if (!sisfb_has_VB_300()) {
+			vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR37);
+			reg = vgarb(CRTC_DATA);
 
 			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
-			case SIS_EXTERNAL_CHIP_SIS301:
+			   case SIS_EXTERNAL_CHIP_SIS301:
 				ivideo.hasVB = HASVB_301;
 				break;
-			case SIS_EXTERNAL_CHIP_LVDS:
+			   case SIS_EXTERNAL_CHIP_LVDS:
 				ivideo.hasVB = HASVB_LVDS;
 				break;
-			case SIS_EXTERNAL_CHIP_TRUMPION:
+			   case SIS_EXTERNAL_CHIP_TRUMPION:
 				ivideo.hasVB = HASVB_TRUMPION;
 				break;
-			case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
 				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
 				break;
-			case SIS_EXTERNAL_CHIP_CHRONTEL:
+			   case SIS_EXTERNAL_CHIP_CHRONTEL:
 				ivideo.hasVB = HASVB_CHRONTEL;
 				break;
-			default:
+			   default:
 				break;
 			}
 		}
 	} else {
-		sisfb_has_VB_300 ();
+		sisfb_has_VB_300();
 	}
-
 	//sishw_ext.hasVB = ivideo.hasVB;
 }
 
-static int sisfb_has_VB_300 (void)
+static int sisfb_has_VB_300(void)
 {
 	// Eden Chen
 	//u8 sr38, sr39, vb_chipid;
@@ -848,146 +929,204 @@
 	//sr38 = vgarb(SEQ_DATA);
 	//vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP2);
 	//sr39 = vgarb(SEQ_DATA);
-	vgawb (VB_PART4_ADR, 0x0);
-	vb_chipid = vgarb (VB_PART4_DATA);
-
+	vgawb(VB_PART4_ADR, 0x0);
+	vb_chipid = vgarb(VB_PART4_DATA);
+        
 	switch (vb_chipid) {
-	case 0x01:
+	   case 0x01:
 		ivideo.hasVB = HASVB_301;
 		break;
-	case 0x02:
+	   case 0x02:
 		ivideo.hasVB = HASVB_302;
 		break;
-	case 0x03:
+	   case 0x03:
 		ivideo.hasVB = HASVB_303;
 		break;
-	default:
+	   default:
 		ivideo.hasVB = HASVB_NONE;
 		return FALSE;
 	}
 	return TRUE;
-}
 
-#endif				/* CONFIG_FB_SIS_300 */
+	//if (
+	//	( (ivideo.chip == SIS_300) && (sr38 & 0x20) )
+	//	||
+	//	( (ivideo.chip == SIS_540) && (sr38 & 0x20) && (!(sr39 & 0x80)) )
+	//	||
+	//	( (ivideo.chip == SIS_630 ) && (sr38 & 0x20) && (!(sr39 & 0x80)) && 
+	//		((ivideo.revision_id & 0xf0) < 0x30) && (vb_chipid == 1) ) 
+	//	||
+	//	( (ivideo.chip == SIS_630 ) && ((ivideo.revision_id & 0xf0) >= 0x30) && 
+	//		(vb_chipid == 1) ) 
+	//	||
+	//	( (ivideo.chip == SIS_730) && (vb_chipid == 1) ) /* 730 */
+	//) {
+	//	ivideo.hasVB = HASVB_301;
+	//	return TRUE;
+	//} else {
+	//	ivideo.hasVB = HASVB_NONE;
+	//	return FALSE;
+	//}
 
-#ifdef CONFIG_FB_SIS_315	/* for SiS 315H/315 */
-static int sisfb_get_dram_size_315 (void)
+	// ~Eden Chen
+}
+#endif  /* CONFIG_FB_SIS_300 */
+
+#ifdef CONFIG_FB_SIS_315    /* for SiS 315H/315PRO/550/650/740 */
+static int sisfb_get_dram_size_315(void)
 {
-#ifdef LINUXBIOS
 	struct pci_dev *pdev = NULL;
 	int pdev_valid = 0;
-	u8 pci_data;
-#endif
-	u8 reg = 0;
+	u8  pci_data;
+	u8  reg = 0;
 
-	if (ivideo.chip == SIS_550) {
+	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {
 #ifdef LINUXBIOS
-		pci_for_each_dev (pdev) {
-			if ((pdev->vendor == PCI_VENDOR_ID_SI)
-			    && (pdev->device == PCI_DEVICE_ID_SI_550)) {
-				pci_read_config_byte (pdev, IND_BRI_DRAM_STATUS,
-						      &pci_data);
+		pci_for_each_dev(pdev) {
+			if ( (pdev->vendor == PCI_VENDOR_ID_SI)
+				&& ( (pdev->device == PCI_DEVICE_ID_SI_550)
+				  || (pdev->device == PCI_DEVICE_ID_SI_650))) {
+				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
+				                     &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
 				ivideo.video_size =
-				    (unsigned int) (1 << (pci_data + 21));
+				    (unsigned int)(1 << (pci_data+21));
 				pdev_valid = 1;
 
-				vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
-				reg = vgarb (SEQ_DATA) & 0xC0;
+				/* TW: Initialize SR14 "by hand" */
+				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+				reg = vgarb(SEQ_DATA) & 0xC0;
 
 				switch (pci_data) {
-					//case BRI_DRAM_SIZE_2MB:
-					//      reg |= (SIS315_DRAM_SIZE_2MB << 4); break;
-				case BRI_DRAM_SIZE_4MB:
+				//case BRI_DRAM_SIZE_2MB:
+				//	reg |= (SIS315_DRAM_SIZE_2MB << 4); break;
+				   case BRI_DRAM_SIZE_4MB:
 					reg |= SIS550_DRAM_SIZE_4MB;
 					break;
-				case BRI_DRAM_SIZE_8MB:
+				   case BRI_DRAM_SIZE_8MB:
 					reg |= SIS550_DRAM_SIZE_8MB;
 					break;
-				case BRI_DRAM_SIZE_16MB:
+				   case BRI_DRAM_SIZE_16MB:
 					reg |= SIS550_DRAM_SIZE_16MB;
 					break;
-				case BRI_DRAM_SIZE_32MB:
+				   case BRI_DRAM_SIZE_32MB:
 					reg |= SIS550_DRAM_SIZE_32MB;
 					break;
-				case BRI_DRAM_SIZE_64MB:
+				   case BRI_DRAM_SIZE_64MB:
 					reg |= SIS550_DRAM_SIZE_64MB;
 					break;
-					/* case BRI_DRAM_SIZE_128MB:
-					   reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */
+				   /* case BRI_DRAM_SIZE_128MB:
+					reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */
 				}
 
-				/* TODO : set Dual channel and bus width bits here */
+			        /* TODO : set Dual channel and bus width bits here */
 
-				vgawb (SEQ_DATA, reg);
+				vgawb(SEQ_DATA, reg);
 				break;
-			}
+			}  
 		}
-
+	
 		if (!pdev_valid)
 			return -1;
 #else
-		vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
-		reg = vgarb (SEQ_DATA);
+		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+		reg = vgarb(SEQ_DATA);
 		switch (reg & SIS550_DRAM_SIZE_MASK) {
-		case SIS550_DRAM_SIZE_4MB:
-			ivideo.video_size = 0x400000;
-			break;
-		case SIS550_DRAM_SIZE_8MB:
-			ivideo.video_size = 0x800000;
-			break;
-		case SIS550_DRAM_SIZE_16MB:
-			ivideo.video_size = 0x1000000;
-			break;
-		case SIS550_DRAM_SIZE_24MB:
-			ivideo.video_size = 0x1800000;
-			break;
-		case SIS550_DRAM_SIZE_32MB:
-			ivideo.video_size = 0x2000000;
-			break;
-		case SIS550_DRAM_SIZE_64MB:
-			ivideo.video_size = 0x4000000;
-			break;
-		case SIS550_DRAM_SIZE_96MB:
-			ivideo.video_size = 0x6000000;
-			break;
-		case SIS550_DRAM_SIZE_128MB:
-			ivideo.video_size = 0x8000000;
-			break;
-		case SIS550_DRAM_SIZE_256MB:
-			ivideo.video_size = 0x10000000;
-			break;
-		default:
-			return -1;
+		   case SIS550_DRAM_SIZE_4MB:
+			ivideo.video_size = 0x400000;   break;
+		   case SIS550_DRAM_SIZE_8MB:
+			ivideo.video_size = 0x800000;   break;
+		   case SIS550_DRAM_SIZE_16MB:
+			ivideo.video_size = 0x1000000;  break;
+		   case SIS550_DRAM_SIZE_24MB:
+			ivideo.video_size = 0x1800000;  break;
+		   case SIS550_DRAM_SIZE_32MB:
+			ivideo.video_size = 0x2000000;	break;
+		   case SIS550_DRAM_SIZE_64MB:
+			ivideo.video_size = 0x4000000;	break;
+		   case SIS550_DRAM_SIZE_96MB:
+			ivideo.video_size = 0x6000000;	break;
+		   case SIS550_DRAM_SIZE_128MB:
+			ivideo.video_size = 0x8000000;	break;
+		   case SIS550_DRAM_SIZE_256MB:
+			ivideo.video_size = 0x10000000;	break;
+		   default:
+		        /* TW: Some 550 BIOSes don't seem to initialize SR14 correctly (if at all),
+			 *     do it the hard way ourselves in this case. Unfortunately, we don't
+			 *     support 24, 48, 96 and other "odd" amounts here. I don't know if
+			 *     this work-around is required for 650/740 as well, but do it in case
+			 *     for now.
+			 */
+		        printk(KERN_INFO
+			       "sisfb: Warning: Could not determine memory size, "
+			       "now reading from PCI config\n");
+			pdev_valid = 0;
+			pci_for_each_dev(pdev) {
+			   if ( (pdev->vendor == PCI_VENDOR_ID_SI)
+			         && (    (pdev->device == PCI_DEVICE_ID_SI_550)
+				      || (pdev->device == PCI_DEVICE_ID_SI_650) ) ) {
+				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
+				                     &pci_data);
+				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
+				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
+				pdev_valid = 1;
+				/* TW: Initialize SR14=IND_SIS_DRAM_SIZE */
+				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+				reg = vgarb(SEQ_DATA) & 0xC0;
+				switch (pci_data) {
+				   case BRI_DRAM_SIZE_4MB:
+					reg |= SIS550_DRAM_SIZE_4MB;  break;
+				   case BRI_DRAM_SIZE_8MB:
+					reg |= SIS550_DRAM_SIZE_8MB;  break;
+				   case BRI_DRAM_SIZE_16MB:
+					reg |= SIS550_DRAM_SIZE_16MB; break;
+				   case BRI_DRAM_SIZE_32MB:
+					reg |= SIS550_DRAM_SIZE_32MB; break;
+				   case BRI_DRAM_SIZE_64MB:
+					reg |= SIS550_DRAM_SIZE_64MB; break;
+				   /* case BRI_DRAM_SIZE_128MB:
+					reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */
+				   default:
+				   	printk(KERN_INFO "sisfb: Unable to determine memory size, giving up.\n");
+					return -1;
+				}
+				vgawb(SEQ_DATA, reg);
+			   }
+			}
+			if (!pdev_valid) {
+				printk(KERN_INFO "sisfb: Total confusion - No SiS PCI VGA device found?!\n");
+				return -1;
+			}
+			return 0;
 		}
 #endif
 		return 0;
-	} else {
-		vgawb (SEQ_ADR, IND_SIS_DRAM_SIZE);
-		reg = vgarb (SEQ_DATA);
+	} else {	/* 315 */
+		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+		reg = vgarb(SEQ_DATA);
 		switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {
-		case SIS315_DRAM_SIZE_2MB:
+		   case SIS315_DRAM_SIZE_2MB:
 			ivideo.video_size = 0x200000;
 			break;
-		case SIS315_DRAM_SIZE_4MB:
+		   case SIS315_DRAM_SIZE_4MB:
 			ivideo.video_size = 0x400000;
 			break;
-		case SIS315_DRAM_SIZE_8MB:
+		   case SIS315_DRAM_SIZE_8MB:
 			ivideo.video_size = 0x800000;
 			break;
-		case SIS315_DRAM_SIZE_16MB:
+		   case SIS315_DRAM_SIZE_16MB:
 			ivideo.video_size = 0x1000000;
 			break;
-		case SIS315_DRAM_SIZE_32MB:
+		   case SIS315_DRAM_SIZE_32MB:
 			ivideo.video_size = 0x2000000;
 			break;
-		case SIS315_DRAM_SIZE_64MB:
+		   case SIS315_DRAM_SIZE_64MB:
 			ivideo.video_size = 0x4000000;
 			break;
-		case SIS315_DRAM_SIZE_128MB:
+		   case SIS315_DRAM_SIZE_128MB:
 			ivideo.video_size = 0x8000000;
 			break;
-		default:
+		   default:
 			return -1;
 		}
 	}
@@ -995,209 +1134,314 @@
 	reg &= SIS315_DUAL_CHANNEL_MASK;
 	reg >>= 2;
 	switch (reg) {
-	case SIS315_SINGLE_CHANNEL_2_RANK:
+	   case SIS315_SINGLE_CHANNEL_2_RANK:
 		ivideo.video_size <<= 1;
 		break;
-	case SIS315_DUAL_CHANNEL_1_RANK:
+	   case SIS315_DUAL_CHANNEL_1_RANK:
 		ivideo.video_size <<= 1;
 		break;
+	   case SIS315_ASYM_DDR:		/* TW: DDR asymentric */
+		ivideo.video_size += ivideo.video_size/2;
+		break;
 	}
 
 	return 0;
 }
 
-static void sisfb_detect_VB_connect_315 (void)
+static void sisfb_detect_VB_connect_315(void)
 {
-	u8 cr32, temp;
+	u8 sr17, cr32, temp;
 
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
-	cr32 = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
+	cr32 = vgarb(CRTC_DATA);
 
 	ivideo.TV_plug = ivideo.TV_type = 0;
 	if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
 		sisfb_crt1off = 0;
 	else {
-		if (cr32 & 0x5F)
+		if (cr32 & 0x5F)   
 			sisfb_crt1off = 1;
 		else
 			sisfb_crt1off = 0;
 	}
 
-	if (cr32 & SIS_VB_CRT2)
+	if (sisfb_crt2type != -1)
+		/* TW: Override with option */
+		ivideo.disp_state = sisfb_crt2type;
+	else if (cr32 & SIS_VB_CRT2)
 		ivideo.disp_state = DISPTYPE_CRT2;
 	else if (cr32 & SIS_VB_LCD)
 		ivideo.disp_state = DISPTYPE_LCD;
-	else if (cr32 & SIS_VB_TV) {
+	else if (cr32 & SIS_VB_TV)
 		ivideo.disp_state = DISPTYPE_TV;
+	else
+		ivideo.disp_state = 0;
 
-		if (cr32 & SIS_VB_HIVISION) {
-			ivideo.TV_type = TVMODE_HIVISION;
-			ivideo.TV_plug = TVPLUG_SVIDEO;
-		} else if (cr32 & SIS_VB_SVIDEO)
-			ivideo.TV_plug = TVPLUG_SVIDEO;
-		else if (cr32 & SIS_VB_COMPOSITE)
-			ivideo.TV_plug = TVPLUG_COMPOSITE;
-		else if (cr32 & SIS_VB_SCART)
-			ivideo.TV_plug = TVPLUG_SCART;
+	if (cr32 & SIS_VB_HIVISION) {
+		ivideo.TV_type = TVMODE_HIVISION;
+		ivideo.TV_plug = TVPLUG_SVIDEO;
+	} else if (cr32 & SIS_VB_SVIDEO)
+		ivideo.TV_plug = TVPLUG_SVIDEO;
+	else if (cr32 & SIS_VB_COMPOSITE)
+		ivideo.TV_plug = TVPLUG_COMPOSITE;
+	else if (cr32 & SIS_VB_SCART)
+		ivideo.TV_plug = TVPLUG_SCART;
+
+	if (ivideo.TV_type == 0) {
+		vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP);
+		temp = vgarb(SEQ_DATA);
+		if (temp & 0x01)
+			ivideo.TV_type = TVMODE_PAL;
+		else
+			ivideo.TV_type = TVMODE_NTSC;
+	}
 
-		if (ivideo.TV_type == 0) {
-			vgawb (SEQ_ADR, IND_SIS_POWER_ON_TRAP);
-			temp = vgarb (SEQ_DATA);
+	/* TW: Copy forceCRT1 option to CRT1off if option is given */
+    	if (sisfb_forcecrt1 != -1) {
+		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
+    		sr17 = vgarb(SEQ_DATA);
+    		if (sisfb_forcecrt1) {
+			sisfb_crt1off=0;
+			sr17 |= 0x80;
+		} else {
+			sisfb_crt1off=1;
+			sr17 &= ~0x80;
+		}
+		vgawb(SEQ_DATA, sr17);
+    	}
+}
 
-			if (temp & 0x01)
-				ivideo.TV_type = TVMODE_PAL;
-			else
-				ivideo.TV_type = TVMODE_NTSC;
+static void sisfb_get_VB_type_315(void)
+{
+	u8 reg;
+
+	/* 550 has LVDS-like FSTN bridge (?) */
+	if (ivideo.chip == SIS_550) {
+		if (!sisfb_has_VB_315()) {
+			vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR37);
+			reg = vgarb(CRTC_DATA);
+
+			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+			   case SIS_EXTERNAL_CHIP_SIS301:
+				ivideo.hasVB = HASVB_301;
+				break;
+			   case SIS_EXTERNAL_CHIP_LVDS:
+				ivideo.hasVB = HASVB_LVDS;
+				break;
+			   case SIS_EXTERNAL_CHIP_TRUMPION:
+				ivideo.hasVB = HASVB_TRUMPION;
+				break;
+			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+				break;
+			   case SIS_EXTERNAL_CHIP_CHRONTEL:
+				ivideo.hasVB = HASVB_CHRONTEL;
+				break;
+			   default:
+				break;
+			}
 		}
-	} else
-		ivideo.disp_state = 0;
+	} else {
+		sisfb_has_VB_315();
+	}
 }
 
-static void sisfb_get_VB_type_315 (void)
+static int sisfb_has_VB_315(void)
 {
 	u8 vb_chipid;
 
-	vgawb (VB_PART4_ADR, 0x0);
-	vb_chipid = vgarb (VB_PART4_DATA);
+	vgawb(VB_PART4_ADR, 0x0);
+	vb_chipid = vgarb(VB_PART4_DATA);
 
 	switch (vb_chipid) {
-	case 0x01:
+	   case 0x01:
 		ivideo.hasVB = HASVB_301;
 		break;
-	case 0x02:
+	   case 0x02:
 		ivideo.hasVB = HASVB_302;
 		break;
-	case 0x03:
+	   case 0x03:
 		ivideo.hasVB = HASVB_303;
 		break;
-	default:
+	   default:
 		ivideo.hasVB = HASVB_NONE;
+		return FALSE;
 	}
 	// Eden Chen
 	//sishw_ext.hasVB = ivideo.hasVB;
 	// ~Eden Chen
+	return TRUE;
 }
-#endif				/* CONFIG_FB_SIS_315 */
+#endif   /* CONFIG_FB_SIS_315 */
 
 /* --------------------- Heap Routines ------------------------------- */
 
-static int sisfb_heap_init (void)
+static int sisfb_heap_init(void)
 {
 	SIS_OH *poh;
-	u8 temp = 0;
+	u8 temp=0;
 #ifdef CONFIG_FB_SIS_315
-	int agp_enabled = 1;
-	u32 agp_size;
+	int            agp_enabled = 1;
+	u32            agp_size;
 	unsigned long *cmdq_baseport = 0;
 	unsigned long *read_port = 0;
 	unsigned long *write_port = 0;
-	SIS_CMDTYPE cmd_type;
+	SIS_CMDTYPE    cmd_type;
 #ifndef AGPOFF
-	agp_kern_info *agp_info;
-	agp_memory *agp;
-	u32 agp_phys;
+	agp_kern_info  *agp_info;
+	agp_memory     *agp;
+	u32            agp_phys;
 #endif
 #endif
-	/*karl:10/01/2001 */
-	if (!sisfb_mem) {
-
-		if (ivideo.video_size > 0x800000)
-			sisfb_heap_start =
-			    (unsigned long) ivideo.video_vbase + 0x800000;
-		else
-			sisfb_heap_start =
-			    (unsigned long) ivideo.video_vbase + 0x400000;
-	} else
+/* TW: If more than 8MB videoRAM detected, let our heap start at 8MB. If
+ *     there is less RAM available, let it start at 4MB. This can be overruled
+ *     by mem parameter.
+ *     This is for avoiding a clash with X driver which uses the beginning
+ *     of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
+ *     in XF86Config-4.
+ *     The heap start can also be specified by parameter "mem" when starting the sisfb
+ *     driver. sisfb mem=1024 lets heap starts at 1MB, etc.
+ */
+      /*karl:10/01/2001*/
+      if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
+	if (ivideo.video_size > 0x800000) {
 		sisfb_heap_start =
-		    (unsigned long) (ivideo.video_vbase + sisfb_mem * 0x100000);
+		    (unsigned long) ivideo.video_vbase + 0x800000;
+		printk(KERN_INFO "sisfb: Memory heap starting at 8192K\n");
+	} else {
+		sisfb_heap_start =
+		    (unsigned long) ivideo.video_vbase + 0x400000;
+		printk(KERN_INFO "sisfb: Memory heap starting at 4096K\n");
+	}
+     } else {
+   	   sisfb_heap_start =
+	       (unsigned long) (ivideo.video_vbase + (sisfb_mem * 1024));
+	   printk(KERN_INFO "sisfb: Memory heap starting at %dK\n", sisfb_mem);
+     }
 
-	sisfb_heap_end = (unsigned long) ivideo.video_vbase + ivideo.video_size;
-	sisfb_heap_size = sisfb_heap_end - sisfb_heap_start;
+     sisfb_heap_end = (unsigned long) ivideo.video_vbase + ivideo.video_size;
+     sisfb_heap_size = sisfb_heap_end - sisfb_heap_start;
 
 #ifdef CONFIG_FB_SIS_315
+     if (sisvga_engine == SIS_315_VGA) {
+        /* TW: Now initlalize the 310 series' command queue mode.
+	 * On 310, there are three queue modes available which
+	 *     are chosen by setting bits 7:5 in SR26:
+	 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
+	 *    track of the queue, the FIFO, command parsing and so
+	 *    on. This is the one comparable to the 300 series.
+	 * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
+	 *    have to do queue management himself. Register 0x85c4 will
+	 *    hold the location of the next free queue slot, 0x85c8
+	 *    is the "queue read pointer" whose way of working is
+	 *    unknown to me. Anyway, this mode would require a
+	 *    translation of the MMIO commands to some kind of
+	 *    accelerator assembly and writing these commands
+	 *    to the memory location pointed to by 0x85c4.
+	 *    We will not use this, as nobody knows how this
+	 *    "assembly" works, and as it would require a complete
+	 *    re-write of the accelerator code.
+	 * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
+	 *    queue in AGP memory space.
+	 *
+	 * SR26 bit 4 is called "Bypass H/W queue".
+	 * SR26 bit 1 is called "Enable Command Queue Auto Correction"
+	 * SR26 bit 0 resets the queue
+	 * Size of queue memory is encoded in bits 3:2 like this:
+	 *    00  (0x00)  512K
+	 *    01  (0x04)  1M
+	 *    10  (0x08)  2M
+	 *    11  (0x0C)  4M
+	 * The queue location is to be written to 0x85C0.
+	 *
+         */
+	cmdq_baseport = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_PHYBASE);
+	write_port    = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_WRITEPORT);
+	read_port     = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_READPORT);
 
-	cmdq_baseport =
-	    (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_PHYBASE);
-	write_port =
-	    (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_WRITEPORT);
-	read_port = (unsigned long *) (ivideo.mmio_vbase + MMIO_QUEUE_READPORT);
-
-	DPRINTK ("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport,
-		 read_port, write_port);
+	DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
 
-	agp_size = COMMAND_QUEUE_AREA_SIZE;
+	agp_size  = COMMAND_QUEUE_AREA_SIZE;
 
 #ifndef AGPOFF
-
-	agp_info = vmalloc (sizeof (agp_kern_info));
-	memset ((void *) agp_info, 0x00, sizeof (agp_kern_info));
-	agp_copy_info (agp_info);
-
-	agp_backend_acquire ();
-
-	agp =
-	    agp_allocate_memory (COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,
-				 AGP_NORMAL_MEMORY);
-	if (agp == NULL) {
-		DPRINTK ("Allocate AGP buffer failed.\n");
-		agp_enabled = 0;
-	} else {
-		if (agp_bind_memory (agp, agp->pg_start) != 0) {
-			DPRINTK ("AGP : can not bind memory\n");
+	if (sisfb_queuemode == AGP_CMD_QUEUE) {
+		agp_info = vmalloc(sizeof(agp_kern_info));
+		memset((void*)agp_info, 0x00, sizeof(agp_kern_info));
+		agp_copy_info(agp_info);
+
+		agp_backend_acquire();
+
+		agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE/PAGE_SIZE,
+					  AGP_NORMAL_MEMORY);
+		if (agp == NULL) {
+			DPRINTK("sisfb: Allocating AGP buffer failed.\n");
 			agp_enabled = 0;
 		} else {
-			agp_enable (0);
+			if (agp_bind_memory(agp, agp->pg_start) != 0) {
+				DPRINTK("sisfb: AGP: Failed to bind memory\n");
+				/* TODO: Free AGP memory here */
+				agp_enabled = 0;
+			} else {
+				agp_enable(0);
+			}
 		}
 	}
-
 #else
-	agp_enabled = 0;
+	agp_enabled= 0;
 #endif
-	if (agp_enabled)
+
+	/* TW: Now select the queue mode */
+
+	if ((agp_enabled) && (sisfb_queuemode == AGP_CMD_QUEUE)) {
 		cmd_type = AGP_CMD_QUEUE;
-	else if (sisfb_heap_size >= COMMAND_QUEUE_AREA_SIZE)
+		printk(KERN_INFO "sisfb: Using AGP queue mode\n");
+/*	} else if (sisfb_heap_size >= COMMAND_QUEUE_AREA_SIZE)  */
+        } else if (sisfb_queuemode == VM_CMD_QUEUE) {
 		cmd_type = VM_CMD_QUEUE;
-	else
+		printk(KERN_INFO "sisfb: Using VRAM queue mode\n");
+	} else {
+		printk(KERN_INFO "sisfb: Using MMIO queue mode\n");
 		cmd_type = MMIO_CMD;
+	}
 
 	switch (agp_size) {
-	case 0x80000:
+	   case 0x80000:
 		temp = SIS_CMD_QUEUE_SIZE_512k;
 		break;
-	case 0x100000:
+	   case 0x100000:
 		temp = SIS_CMD_QUEUE_SIZE_1M;
 		break;
-	case 0x200000:
+	   case 0x200000:
 		temp = SIS_CMD_QUEUE_SIZE_2M;
 		break;
-	case 0x400000:
+	   case 0x400000:
 		temp = SIS_CMD_QUEUE_SIZE_4M;
 		break;
 	}
 
 	switch (cmd_type) {
-	case AGP_CMD_QUEUE:
+	   case AGP_CMD_QUEUE:
 #ifndef AGPOFF
-		DPRINTK ("AGP buffer base:0x%lx, offset:0x%x, size is %dK\n",
-			 agp_info->aper_base, agp->physical, agp_size / 1024);
+		DPRINTK("sisfb: AGP buffer base:0x%lx, offset:0x%x, size: %dK\n",
+			agp_info->aper_base, agp->physical, agp_size/1024);
 
 		agp_phys = agp_info->aper_base + agp->physical;
 
-		vgawb (CRTC_ADR, IND_SIS_AGP_IO_PAD);
-		vgawb (CRTC_DATA, 0);
-		vgawb (CRTC_DATA, SIS_AGP_2X);
+		vgawb(CRTC_ADR, IND_SIS_AGP_IO_PAD);
+		vgawb(CRTC_DATA, 0);
+		vgawb(CRTC_DATA, SIS_AGP_2X);
 
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
-		vgawb (SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
+		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
 
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, SIS_CMD_QUEUE_RESET);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
 
 		*write_port = *read_port;
 
 		temp |= SIS_AGP_CMDQUEUE_ENABLE;
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, temp);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, temp);
 
 		*cmdq_baseport = agp_phys;
 
@@ -1205,94 +1449,124 @@
 #endif
 		break;
 
-	case VM_CMD_QUEUE:
+	   case VM_CMD_QUEUE:
 		sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
 		sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
 
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
-		vgawb (SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
+		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
 
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, SIS_CMD_QUEUE_RESET);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
 
 		*write_port = *read_port;
 
 		temp |= SIS_VRAM_CMDQUEUE_ENABLE;
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, temp);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, temp);
 
 		*cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
 
 		sisfb_caps |= VM_CMD_QUEUE_CAP;
 
-		DPRINTK ("VM Cmd Queue offset = 0x%lx, size is %dK\n",
-			 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE / 1024);
+		DPRINTK("sisfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
+			*cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
 		break;
-	default:
-		vgawb (SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb (SEQ_DATA, SIS_MMIO_CMD_ENABLE);
+
+	   default:  /* MMIO */
+	   	/* TW: This previously only wrote SIS_MMIO_CMD_ENABLE
+		 * to IND_SIS_CMDQUEUE_SET. I doubt that this is
+		 * enough. Reserve memory in any way.
+		 */
+	   	sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
+		sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
+
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
+		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
+
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
+
+		*write_port = *read_port;
+
+		/* TW: Set Auto_Correction bit; this works in sisfb lite,
+		 * so why not.
+		 */
+		temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
+		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
+		vgawb(SEQ_DATA, temp);
+
+		*cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
+
+		DPRINTK("sisfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n",
+			*cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
 		break;
 	}
-
+     } /* sisvga_engine = 315 */
 #endif
 
 #ifdef CONFIG_FB_SIS_300
-	if (sisfb_heap_size >= TURBO_QUEUE_AREA_SIZE) {
-		unsigned int tqueue_pos;
+     if (sisvga_engine == SIS_300_VGA) {
+  	    /* TW: Now initialize TurboQueue. TB is always located at the very
+	     * top of the video RAM. */
+	    if (sisfb_heap_size >= TURBO_QUEUE_AREA_SIZE) {
+		unsigned int  tqueue_pos;
 		u8 tq_state;
 
-		tqueue_pos =
-		    (ivideo.video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
+		tqueue_pos = (ivideo.video_size -
+		       TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
 		temp = (u8) (tqueue_pos & 0xff);
-		vgawb (SEQ_ADR, IND_SIS_TURBOQUEUE_SET);
-		tq_state = vgarb (SEQ_DATA);
+		vgawb(SEQ_ADR, IND_SIS_TURBOQUEUE_SET);
+		tq_state = vgarb(SEQ_DATA);
 		tq_state |= 0xf0;
 		tq_state &= 0xfc;
 		tq_state |= (u8) (tqueue_pos >> 8);
-		vgawb (SEQ_DATA, tq_state);
-		vgawb (SEQ_ADR, IND_SIS_TURBOQUEUE_ADR);
-		vgawb (SEQ_DATA, temp);
+		vgawb(SEQ_DATA, tq_state);
+		vgawb(SEQ_ADR, IND_SIS_TURBOQUEUE_ADR);
+		vgawb(SEQ_DATA, temp);
 
 		sisfb_caps |= TURBO_QUEUE_CAP;
 
 		sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
 		sisfb_heap_size -= TURBO_QUEUE_AREA_SIZE;
-		DPRINTK ("Turbo Queue: start at 0x%lx, size is %dK\n",
-			 sisfb_heap_end, TURBO_QUEUE_AREA_SIZE / 1024);
-	}
-#endif
-
-	if (sisfb_heap_size >= HW_CURSOR_AREA_SIZE) {
-		sisfb_heap_end -= HW_CURSOR_AREA_SIZE;
-		sisfb_heap_size -= HW_CURSOR_AREA_SIZE;
+		DPRINTK("sisfb: TurboQueue start at 0x%lx, size is %dK\n",
+			sisfb_heap_end, TURBO_QUEUE_AREA_SIZE/1024);
+	    }
+     }
+#endif
+        /* TW: Now reserve memory for the HWCursor. It is always located at the very
+               top of the videoRAM, right below the TB memory area (if used). */
+	if (sisfb_heap_size >= sisfb_hwcursor_size) {
+		sisfb_heap_end -= sisfb_hwcursor_size;
+		sisfb_heap_size -= sisfb_hwcursor_size;
 		sisfb_hwcursor_vbase = sisfb_heap_end;
 
 		sisfb_caps |= HW_CURSOR_CAP;
 
-		DPRINTK ("Hardware Cursor: start at 0x%lx, size is %dK\n",
-			 sisfb_heap_end, HW_CURSOR_AREA_SIZE / 1024);
+		DPRINTK("sisfb: Hardware Cursor start at 0x%lx, size is %dK\n",
+			sisfb_heap_end, sisfb_hwcursor_size/1024);
 	}
 
 	sisfb_heap.poha_chain = NULL;
 	sisfb_heap.poh_freelist = NULL;
 
-	poh = sisfb_poh_new_node ();
+	poh = sisfb_poh_new_node();
 
 	if (poh == NULL)
 		return 1;
-
+	
 	poh->poh_next = &sisfb_heap.oh_free;
 	poh->poh_prev = &sisfb_heap.oh_free;
 	poh->size = sisfb_heap_end - sisfb_heap_start + 1;
 	poh->offset = sisfb_heap_start - (unsigned long) ivideo.video_vbase;
 
-	DPRINTK ("sisfb:Heap start:0x%p, end:0x%p, len=%dk\n",
-		 (char *) sisfb_heap_start, (char *) sisfb_heap_end,
-		 (unsigned int) poh->size / 1024);
-
-	DPRINTK ("sisfb:First Node offset:0x%x, size:%dk\n",
-		 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
+	DPRINTK("sisfb: Heap start:0x%p, end:0x%p, len=%dk\n",
+		(char *) sisfb_heap_start, (char *) sisfb_heap_end,
+		(unsigned int) poh->size / 1024);
 
+	DPRINTK("sisfb: First Node offset:0x%x, size:%dk\n",
+		(unsigned int) poh->offset, (unsigned int) poh->size / 1024);
+	
 	sisfb_heap.oh_free.poh_next = poh;
 	sisfb_heap.oh_free.poh_prev = poh;
 	sisfb_heap.oh_free.size = 0;
@@ -1305,7 +1579,7 @@
 	return 0;
 }
 
-static SIS_OH *sisfb_poh_new_node (void)
+static SIS_OH *sisfb_poh_new_node(void)
 {
 	int i;
 	unsigned long cOhs;
@@ -1313,14 +1587,14 @@
 	SIS_OH *poh;
 
 	if (sisfb_heap.poh_freelist == NULL) {
-		poha = kmalloc (OH_ALLOC_SIZE, GFP_KERNEL);
+		poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
 
 		poha->poha_next = sisfb_heap.poha_chain;
 		sisfb_heap.poha_chain = poha;
 
 		cOhs =
 		    (OH_ALLOC_SIZE -
-		     sizeof (SIS_OHALLOC)) / sizeof (SIS_OH) + 1;
+		     sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
 
 		poh = &poha->aoh[0];
 		for (i = cOhs - 1; i != 0; i--) {
@@ -1338,15 +1612,15 @@
 	return (poh);
 }
 
-static SIS_OH *sisfb_poh_allocate (unsigned long size)
+static SIS_OH *sisfb_poh_allocate(unsigned long size)
 {
 	SIS_OH *pohThis;
 	SIS_OH *pohRoot;
 	int bAllocated = 0;
 
 	if (size > sisfb_heap.max_freesize) {
-		DPRINTK ("sisfb: Can't allocate %dk size on offscreen\n",
-			 (unsigned int) size / 1024);
+		DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
+			(unsigned int) size / 1024);
 		return (NULL);
 	}
 
@@ -1361,16 +1635,16 @@
 	}
 
 	if (!bAllocated) {
-		DPRINTK ("sisfb: Can't allocate %dk size on offscreen\n",
-			 (unsigned int) size / 1024);
+		DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
+			(unsigned int) size / 1024);
 		return (NULL);
 	}
 
 	if (size == pohThis->size) {
 		pohRoot = pohThis;
-		sisfb_delete_node (pohThis);
+		sisfb_delete_node(pohThis);
 	} else {
-		pohRoot = sisfb_poh_new_node ();
+		pohRoot = sisfb_poh_new_node();
 
 		if (pohRoot == NULL) {
 			return (NULL);
@@ -1386,16 +1660,17 @@
 	sisfb_heap.max_freesize -= size;
 
 	pohThis = &sisfb_heap.oh_used;
-	sisfb_insert_node (pohThis, pohRoot);
+	sisfb_insert_node(pohThis, pohRoot);
 
 	return (pohRoot);
 }
 
-static void sisfb_delete_node (SIS_OH * poh)
+static void sisfb_delete_node(SIS_OH *poh)
 {
 	SIS_OH *poh_prev;
 	SIS_OH *poh_next;
 
+
 	poh_prev = poh->poh_prev;
 	poh_next = poh->poh_next;
 
@@ -1405,7 +1680,7 @@
 	return;
 }
 
-static void sisfb_insert_node (SIS_OH * pohList, SIS_OH * poh)
+static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
 {
 	SIS_OH *pohTemp;
 
@@ -1418,9 +1693,8 @@
 	poh->poh_next = pohTemp;
 }
 
-static SIS_OH *sisfb_poh_free (unsigned long base)
+static SIS_OH *sisfb_poh_free(unsigned long base)
 {
-
 	SIS_OH *pohThis;
 	SIS_OH *poh_freed;
 	SIS_OH *poh_prev;
@@ -1454,41 +1728,43 @@
 	while (pohThis != &sisfb_heap.oh_free) {
 		if (pohThis->offset == ulUpper) {
 			poh_next = pohThis;
-		} else if ((pohThis->offset + pohThis->size) == ulLower) {
+		}
+			else if ((pohThis->offset + pohThis->size) ==
+				 ulLower) {
 			poh_prev = pohThis;
 		}
 		pohThis = pohThis->poh_next;
 	}
 
-	sisfb_delete_node (poh_freed);
+	sisfb_delete_node(poh_freed);
 
 	if (poh_prev && poh_next) {
 		poh_prev->size += (poh_freed->size + poh_next->size);
-		sisfb_delete_node (poh_next);
-		sisfb_free_node (poh_freed);
-		sisfb_free_node (poh_next);
+		sisfb_delete_node(poh_next);
+		sisfb_free_node(poh_freed);
+		sisfb_free_node(poh_next);
 		return (poh_prev);
 	}
 
 	if (poh_prev) {
 		poh_prev->size += poh_freed->size;
-		sisfb_free_node (poh_freed);
+		sisfb_free_node(poh_freed);
 		return (poh_prev);
 	}
 
 	if (poh_next) {
 		poh_next->size += poh_freed->size;
 		poh_next->offset = poh_freed->offset;
-		sisfb_free_node (poh_freed);
+		sisfb_free_node(poh_freed);
 		return (poh_next);
 	}
 
-	sisfb_insert_node (&sisfb_heap.oh_free, poh_freed);
+	sisfb_insert_node(&sisfb_heap.oh_free, poh_freed);
 
 	return (poh_freed);
 }
 
-static void sisfb_free_node (SIS_OH * poh)
+static void sisfb_free_node(SIS_OH *poh)
 {
 	if (poh == NULL) {
 		return;
@@ -1500,20 +1776,20 @@
 	return;
 }
 
-void sis_malloc (struct sis_memreq *req)
+void sis_malloc(struct sis_memreq *req)
 {
 	SIS_OH *poh;
 
-	poh = sisfb_poh_allocate (req->size);
+	poh = sisfb_poh_allocate(req->size);
 
 	if (poh == NULL) {
 		req->offset = 0;
 		req->size = 0;
-		DPRINTK ("sisfb: VMEM Allocation Failed\n");
+		DPRINTK("sisfb: Video RAM allocation failed\n");
 	} else {
-		DPRINTK ("sisfb: VMEM Allocation Successed : 0x%p\n",
-			 (char *) (poh->offset +
-				   (unsigned long) ivideo.video_vbase));
+		DPRINTK("sisfb: Video RAM allocation succeeded: 0x%p\n",
+			(char *) (poh->offset +
+				  (unsigned long) ivideo.video_vbase));
 
 		req->offset = poh->offset;
 		req->size = poh->size;
@@ -1521,280 +1797,319 @@
 
 }
 
-void sis_free (unsigned long base)
+void sis_free(unsigned long base)
 {
 	SIS_OH *poh;
 
-	poh = sisfb_poh_free (base);
+	poh = sisfb_poh_free(base);
 
 	if (poh == NULL) {
-		DPRINTK ("sisfb: sisfb_poh_free() failed at base 0x%x\n",
-			 (unsigned int) base);
+		DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
+			(unsigned int) base);
 	}
 }
 
 /* ------------------ SetMode Routines ------------------------------- */
 
-static void sisfb_pre_setmode (void)
+static void sisfb_pre_setmode(void)
 {
 	u8 cr30 = 0, cr31 = 0;
 
-	vgawb (CRTC_ADR, 0x31);
-	cr31 = vgarb (CRTC_DATA) & ~0x60;
+	vgawb(CRTC_ADR, 0x31);
+	cr31 = vgarb(CRTC_DATA) & ~0x60;
 
 	switch (ivideo.disp_state & DISPTYPE_DISP2) {
-	case DISPTYPE_CRT2:
+	   case DISPTYPE_CRT2:
+		printk(KERN_INFO "sisfb: CRT2 type is VGA\n");
 		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
 		break;
-	case DISPTYPE_LCD:
-		cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
+	   case DISPTYPE_LCD:
+		printk(KERN_INFO "sisfb: CRT2 type is LCD\n");
+		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
 		break;
-	case DISPTYPE_TV:
+	   case DISPTYPE_TV:
+		printk(KERN_INFO "sisfb: CRT2 type is TV\n");
 		if (ivideo.TV_type == TVMODE_HIVISION)
-			cr30 =
-			    (SIS_VB_OUTPUT_HIVISION |
-			     SIS_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (ivideo.TV_plug == TVPLUG_SVIDEO)
-			cr30 =
-			    (SIS_VB_OUTPUT_SVIDEO |
-			     SIS_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (ivideo.TV_plug == TVPLUG_COMPOSITE)
-			cr30 =
-			    (SIS_VB_OUTPUT_COMPOSITE |
-			     SIS_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (ivideo.TV_plug == TVPLUG_SCART)
-			cr30 =
-			    (SIS_VB_OUTPUT_SCART |
-			     SIS_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
-
-		/*karl */
-		if (sisfb_tvmode == 1)
+		cr31 &= ~0x04; /* TW: No Slavemode by default  */
+                /*karl*/
+	        if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL)
 			cr31 |= 0x1;
-		if (sisfb_tvmode == 2)
-			cr31 &= ~0x1;
-
+                if (sisfb_tvmode == 2 || ivideo.TV_type == TVMODE_NTSC)
+                        cr31 &= ~0x1;
 		break;
-	default:
+	   default:	/* CRT2 disable */
+		printk(KERN_INFO "sisfb: CRT2 is disabled\n");
 		cr30 = 0x00;
 		cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
 	}
 
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR30);
-	vgawb (CRTC_DATA, cr30);
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR31);
-	vgawb (CRTC_DATA, cr31);
-	vgawb (CRTC_ADR, IND_SIS_SCRATCH_REG_CR33);
-	vgawb (CRTC_DATA, sisfb_rate_idx & 0x0F);
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR30);
+	vgawb(CRTC_DATA, cr30);
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR31);
+	vgawb(CRTC_DATA, cr31);
+	/* printk(KERN_INFO "sisfb: 0x30=%x 0x31=%x\n", cr30, cr31); */
+	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR33);
+/*
+	if (ivideo.disp_state & DISPTYPE_CRT2) {
+		sisfb_rate_idx &= 0x0F;
+		sisfb_rate_idx |= (sisfb_rate_idx << 4);
+		vgawb(CRTC_DATA, sisfb_rate_idx);
+	} else {
+		vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);
+	}
+*/
+	vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);
 }
 
-static void sisfb_post_setmode (void)
+static void sisfb_post_setmode(void)
 {
 	u8 reg;
 
-	vgawb (CRTC_ADR, 0x17);
-	reg = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x17);
+	reg = vgarb(CRTC_DATA);
 
-	if ((ivideo.hasVB == HASVB_LVDS)
-	    || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) if (ivideo.video_bpp == 8)
+	if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL))
+		if (ivideo.video_bpp == 8)   
 			sisfb_crt1off = 0;
 
-	if (sisfb_crt1off)
+	if (sisfb_crt1off)	  
 		reg &= ~0x80;
-	else
+	else 	      
 		reg |= 0x80;
-	vgawb (CRTC_DATA, reg);
-
-	vgawb (SEQ_ADR, IND_SIS_RAMDAC_CONTROL);
-	reg = vgarb (SEQ_DATA);
+	vgawb(CRTC_DATA, reg);
+	
+	vgawb(SEQ_ADR, IND_SIS_RAMDAC_CONTROL);
+	reg = vgarb(SEQ_DATA);
 	reg &= ~0x04;
-	vgawb (SEQ_DATA, reg);
+	vgawb(SEQ_DATA, reg);
 
 	if ((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {
-		/*karl */
-		vgawb (VB_PART4_ADR, 0x01);
-		reg = vgarb (VB_PART4_DATA);
+		/*karl*/
+		vgawb(VB_PART4_ADR,0x01);
+		reg = vgarb(VB_PART4_DATA);
+		
+	   if ((reg != 0xB1) && (reg != 0xB0)) /*301B Revision ID*/
+           {	
+		// Eden Chen
+		switch (ivideo.video_width) {
+		   case 320:
+			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
+			break;
+		   case 640:
+			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;
+			break;
+		   case 720:
+			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;
+			break;
+		   case 800:
+			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;
+			break;
+		   default:
+			filter = -1;
+			break;
+		}
+		// ~Eden Chen
 
-		if ((reg != 0xB1) && (reg != 0xB0)) {	/*301B Revision ID */
-			// Eden Chen
-			switch (ivideo.video_width) {
-			case 320:
-				filter_tb =
-				    (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
-				break;
-			case 640:
-				filter_tb =
-				    (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;
-				break;
-			case 720:
-				filter_tb =
-				    (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;
-				break;
-			case 800:
-				filter_tb =
-				    (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;
-				break;
-			default:
-				filter = -1;
-				break;
+		// Eden Chen
+		//vgawb(VB_PART1_ADR,  0x24);
+		vgawb(VB_PART1_ADR,  sisfb_CRT2_write_enable);
+		// ~Eden Chen
+		vgawb(VB_PART1_DATA, 0x1);
+		
+		// Eden Chen for Debug
+/*
+		if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {
+			vgawb(VB_PART1_ADR,  0x2D);
+			vgawb(VB_PART1_DATA, 0x11);
+
+			if (sisfb_mode_no == 0x63) {
+				vgawb(VB_PART2_ADR,  0x15);
+				vgawb(VB_PART2_DATA, 0x0A);
+				vgawb(VB_PART2_ADR,  0x28);
+				vgawb(VB_PART2_DATA, 0x62);
+				vgawb(VB_PART2_ADR,  0x2D);
+				vgawb(VB_PART2_DATA, 0xF8);
+				vgawb(VB_PART2_ADR,  0x2E);
+				vgawb(VB_PART2_DATA, 0x14);
+				vgawb(VB_PART2_ADR,  0x33);
+				vgawb(VB_PART2_DATA, 0x8A);
+
+				vgawb(VB_PART2_ADR,  0x35);
+				vgawb(VB_PART2_DATA, 0xF4);
+				vgawb(VB_PART2_ADR,  0x36);
+				vgawb(VB_PART2_DATA, 0x10);
+				vgawb(VB_PART2_ADR,  0x37);
+				vgawb(VB_PART2_DATA, 0x1C);
+				vgawb(VB_PART2_ADR,  0x38);
+				vgawb(VB_PART2_DATA, 0x00);
+				vgawb(VB_PART2_ADR,  0x44);
+				vgawb(VB_PART2_DATA, 0x29);
+				vgawb(VB_PART2_ADR,  0x45);
+				vgawb(VB_PART2_DATA, 0x54);
+
+				vgawb(VB_PART4_ADR,  0x0D);
+				vgawb(VB_PART4_DATA, 0x0F);
+				vgawb(VB_PART4_ADR,  0x0F);
+				vgawb(VB_PART4_DATA, 0x0F);
+				vgawb(VB_PART4_ADR,  0x10);
+				vgawb(VB_PART4_DATA, 0x83);
+				vgawb(VB_PART4_ADR,  0x11);
+				vgawb(VB_PART4_DATA, 0xFF);
+				vgawb(VB_PART4_ADR,  0x18);
+				vgawb(VB_PART4_DATA, 0x20);
+				vgawb(VB_PART4_ADR,  0x19);
+				vgawb(VB_PART4_DATA, 0x52);
 			}
-			// ~Eden Chen
-
-			// Eden Chen
-			//vgawb(VB_PART1_ADR,  0x24);
-			vgawb (VB_PART1_ADR, IND_SIS_CRT2_WRITE_ENABLE);
-			// ~Eden Chen
-			vgawb (VB_PART1_DATA, 0x1);
-
-			// Eden Chen for Debug
-			// ~Eden Chen
+		}
+*/
+		// ~Eden Chen
 
-			if (ivideo.TV_type == TVMODE_NTSC) {
-				vgawb (VB_PART2_ADR, 0x3A);
-				reg = vgarb (VB_PART2_DATA);
-				reg &= 0x1F;
-				vgawb (VB_PART2_DATA, reg);
-
-				if (ivideo.TV_plug == TVPLUG_SVIDEO) {
-					vgawb (VB_PART2_ADR, 0x30);
-					reg = vgarb (VB_PART2_DATA);
-					reg &= 0xDF;
-					vgawb (VB_PART2_DATA, reg);
-				} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
-					vgawb (VB_PART2_ADR, 0x30);
-					reg = vgarb (VB_PART2_DATA);
-					reg |= 0x20;
-					vgawb (VB_PART2_DATA, reg);
-
-					switch (ivideo.video_width) {
-					case 640:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xEB);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0x04);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x25);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x18);
-						break;
-					case 720:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xEE);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0x0C);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x22);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x08);
-						break;
-					case 800:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xEB);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0x15);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x25);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0xF6);
-						break;
-					}
-				}
-			} else if (ivideo.TV_type == TVMODE_PAL) {
-				vgawb (VB_PART2_ADR, 0x3A);
-				reg = vgarb (VB_PART2_DATA);
-				reg &= 0x1F;
-				vgawb (VB_PART2_DATA, reg);
-
-				if (ivideo.TV_plug == TVPLUG_SVIDEO) {
-					vgawb (VB_PART2_ADR, 0x30);
-					reg = vgarb (VB_PART2_DATA);
-					reg &= 0xDF;
-					vgawb (VB_PART2_DATA, reg);
-				} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
-					vgawb (VB_PART2_ADR, 0x30);
-					reg = vgarb (VB_PART2_DATA);
-					reg |= 0x20;
-					vgawb (VB_PART2_DATA, reg);
-
-					switch (ivideo.video_width) {
-					case 640:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xF1);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0xF7);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x1F);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x32);
-						break;
-					case 720:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xF3);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0x00);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x1D);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x20);
-						break;
-					case 800:
-						vgawb (VB_PART2_ADR, 0x35);
-						vgawb (VB_PART2_DATA, 0xFC);
-						vgawb (VB_PART2_ADR, 0x36);
-						vgawb (VB_PART2_DATA, 0xFB);
-						vgawb (VB_PART2_ADR, 0x37);
-						vgawb (VB_PART2_DATA, 0x14);
-						vgawb (VB_PART2_ADR, 0x38);
-						vgawb (VB_PART2_DATA, 0x2A);
-						break;
-					}
+		if (ivideo.TV_type == TVMODE_NTSC) {
+			vgawb(VB_PART2_ADR, 0x3A);
+			reg = vgarb(VB_PART2_DATA);
+			reg &= 0x1F;
+			vgawb(VB_PART2_DATA, reg);
+
+			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
+				vgawb(VB_PART2_ADR, 0x30);
+				reg = vgarb(VB_PART2_DATA);
+				reg &= 0xDF;
+				vgawb(VB_PART2_DATA, reg);
+			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
+				vgawb(VB_PART2_ADR, 0x30);
+				reg = vgarb(VB_PART2_DATA);
+				reg |= 0x20;
+				vgawb(VB_PART2_DATA, reg);
+
+				switch (ivideo.video_width) {
+				case 640:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xEB);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0x04);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x25);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x18);
+					break;
+				case 720:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xEE);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0x0C);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x22);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x08);
+					break;
+				case 800:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xEB);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0x15);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x25);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0xF6);
+					break;
 				}
 			}
-			// Eden 
-			if ((filter >= 0) && (filter <= 7)) {
-				DPRINTK
-				    ("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
-				     filter_tb, filter,
-				     sis_TV_filter[filter_tb].filter[filter][0],
-				     sis_TV_filter[filter_tb].filter[filter][1],
-				     sis_TV_filter[filter_tb].filter[filter][2],
-				     sis_TV_filter[filter_tb].filter[filter][3]
-				    );
-				vgawb (VB_PART2_ADR, 0x35);
-				vgawb (VB_PART2_DATA,
-				       sis_TV_filter[filter_tb].
-				       filter[filter][0]);
-				vgawb (VB_PART2_ADR, 0x36);
-				vgawb (VB_PART2_DATA,
-				       sis_TV_filter[filter_tb].
-				       filter[filter][1]);
-				vgawb (VB_PART2_ADR, 0x37);
-				vgawb (VB_PART2_DATA,
-				       sis_TV_filter[filter_tb].
-				       filter[filter][2]);
-				vgawb (VB_PART2_ADR, 0x38);
-				vgawb (VB_PART2_DATA,
-				       sis_TV_filter[filter_tb].
-				       filter[filter][3]);
+		} else if (ivideo.TV_type == TVMODE_PAL) {
+			vgawb(VB_PART2_ADR, 0x3A);
+			reg = vgarb(VB_PART2_DATA);
+			reg &= 0x1F;
+			vgawb(VB_PART2_DATA, reg);
+
+			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
+				vgawb(VB_PART2_ADR, 0x30);
+				reg = vgarb(VB_PART2_DATA);
+				reg &= 0xDF;
+				vgawb(VB_PART2_DATA, reg);
+			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
+				vgawb(VB_PART2_ADR, 0x30);
+				reg = vgarb(VB_PART2_DATA);
+				reg |= 0x20;
+				vgawb(VB_PART2_DATA, reg);
+
+				switch (ivideo.video_width) {
+				case 640:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xF1);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0xF7);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x1F);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x32);
+					break;
+				case 720:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xF3);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0x00);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x1D);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x20);
+					break;
+				case 800:
+					vgawb(VB_PART2_ADR,  0x35);
+					vgawb(VB_PART2_DATA, 0xFC);
+					vgawb(VB_PART2_ADR,  0x36);
+					vgawb(VB_PART2_DATA, 0xFB);
+					vgawb(VB_PART2_ADR,  0x37);
+					vgawb(VB_PART2_DATA, 0x14);
+					vgawb(VB_PART2_ADR,  0x38);
+					vgawb(VB_PART2_DATA, 0x2A);
+					break;
+				}
 			}
-			// ~Eden 
 		}
+
+		// Eden 
+		if ((filter >= 0) && (filter <=7)) {
+			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter, 
+				sis_TV_filter[filter_tb].filter[filter][0],
+				sis_TV_filter[filter_tb].filter[filter][1],
+				sis_TV_filter[filter_tb].filter[filter][2],
+				sis_TV_filter[filter_tb].filter[filter][3]
+			);
+			vgawb(VB_PART2_ADR,  0x35);
+			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][0]);
+			vgawb(VB_PART2_ADR,  0x36);
+			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][1]);
+			vgawb(VB_PART2_ADR,  0x37);
+			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][2]);
+			vgawb(VB_PART2_ADR,  0x38);
+			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][3]);
+		}
+		// ~Eden 
+	     } /*karl:endif (reg != 0xB1)*/
+	  
 	}
 
 }
 
-static void sisfb_crtc_to_var (struct fb_var_screeninfo *var)
+static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
 {
 	u16 VRE, VBE, VRS, VBS, VDE, VT;
 	u16 HRE, HBE, HRS, HBS, HDE, HT;
-	u8 sr_data, cr_data, cr_data2, cr_data3, mr_data;
+	u8  sr_data, cr_data, cr_data2, cr_data3, mr_data;
 	int A, B, C, D, E, F, temp;
 	double hrate, drate;
 
-	vgawb (SEQ_ADR, IND_SIS_COLOR_MODE);
-	sr_data = vgarb (SEQ_DATA);
+	vgawb(SEQ_ADR, IND_SIS_COLOR_MODE);
+	sr_data = vgarb(SEQ_DATA);
 
 	if (sr_data & SIS_INTERLACED_MODE)
 		var->vmode = FB_VMODE_INTERLACED;
@@ -1802,25 +2117,25 @@
 		var->vmode = FB_VMODE_NONINTERLACED;
 
 	switch ((sr_data & 0x1C) >> 2) {
-	case SIS_8BPP_COLOR_MODE:
+	   case SIS_8BPP_COLOR_MODE:
 		var->bits_per_pixel = 8;
 		break;
-	case SIS_16BPP_COLOR_MODE:
+	   case SIS_16BPP_COLOR_MODE:
 		var->bits_per_pixel = 16;
 		break;
-	case SIS_32BPP_COLOR_MODE:
+	   case SIS_32BPP_COLOR_MODE:
 		var->bits_per_pixel = 32;
 		break;
 	}
 
 	switch (var->bits_per_pixel) {
-	case 8:
+	   case 8:
 		var->red.length = 6;
 		var->green.length = 6;
 		var->blue.length = 6;
 		video_cmap_len = 256;
 		break;
-	case 16:
+	   case 16:
 		var->red.offset = 11;
 		var->red.length = 5;
 		var->green.offset = 5;
@@ -1830,9 +2145,8 @@
 		var->transp.offset = 0;
 		var->transp.length = 0;
 		video_cmap_len = 16;
-
 		break;
-	case 24:
+	   case 24:
 		var->red.offset = 16;
 		var->red.length = 8;
 		var->green.offset = 8;
@@ -1843,7 +2157,7 @@
 		var->transp.length = 0;
 		video_cmap_len = 16;
 		break;
-	case 32:
+	   case 32:
 		var->red.offset = 16;
 		var->red.length = 8;
 		var->green.offset = 8;
@@ -1856,47 +2170,45 @@
 		break;
 	}
 
-	vgawb (SEQ_ADR, 0xA);
-	sr_data = vgarb (SEQ_DATA);
+	vgawb(SEQ_ADR, 0xA);
+	sr_data = vgarb(SEQ_DATA);
 
-	vgawb (CRTC_ADR, 0x6);
-	cr_data = vgarb (CRTC_DATA);
-	vgawb (CRTC_ADR, 0x7);
-	cr_data2 = vgarb (CRTC_DATA);
-	VT =
-	    (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |
-	    ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) << 10);
+	vgawb(CRTC_ADR, 0x6);
+	cr_data = vgarb(CRTC_DATA);
+	vgawb(CRTC_ADR, 0x7);
+	cr_data2 = vgarb(CRTC_DATA);
+	VT = (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |
+	     ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) <<
+					      10);
 	A = VT + 2;
 
-	vgawb (CRTC_ADR, 0x12);
-	cr_data = vgarb (CRTC_DATA);
-	VDE =
-	    (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |
-	    ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);
+	vgawb(CRTC_ADR, 0x12);
+	cr_data = vgarb(CRTC_DATA);
+	VDE = (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |
+	      ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);
 	E = VDE + 1;
 
-	vgawb (CRTC_ADR, 0x10);
-	cr_data = vgarb (CRTC_DATA);
-	VRS =
-	    (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |
-	    ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);
+	vgawb(CRTC_ADR, 0x10);
+	cr_data = vgarb(CRTC_DATA);
+	VRS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |
+	      ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);
 	F = VRS + 1 - E;
 
-	vgawb (CRTC_ADR, 0x15);
-	cr_data = vgarb (CRTC_DATA);
-	vgawb (CRTC_ADR, 0x9);
-	cr_data3 = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x15);
+	cr_data = vgarb(CRTC_DATA);
+	vgawb(CRTC_ADR, 0x9);
+	cr_data3 = vgarb(CRTC_DATA);
 	VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
-	    ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
+	      ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
 
-	vgawb (CRTC_ADR, 0x16);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x16);
+	cr_data = vgarb(CRTC_DATA);
 	VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);
 	temp = VBE - ((E - 1) & 511);
 	B = (temp > 0) ? temp : (temp + 512);
 
-	vgawb (CRTC_ADR, 0x11);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x11);
+	cr_data = vgarb(CRTC_DATA);
 	VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
 	temp = VRE - ((E + F - 1) & 31);
 	C = (temp > 0) ? temp : (temp + 32);
@@ -1904,41 +2216,46 @@
 	D = B - F - C;
 
 	var->yres = var->yres_virtual = E;
+	/* TW: We have to report the physical dimension to the console! */
+	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		var->yres <<= 1;
+		var->yres_virtual <<=1;
+	}
+	/* TW end */
 	var->upper_margin = D;
 	var->lower_margin = F;
 	var->vsync_len = C;
 
-	vgawb (SEQ_ADR, 0xb);
-	sr_data = vgarb (SEQ_DATA);
+	vgawb(SEQ_ADR, 0xb);
+	sr_data = vgarb(SEQ_DATA);
 
-	vgawb (CRTC_ADR, 0x0);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x0);
+	cr_data = vgarb(CRTC_DATA);
 	HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
 	A = HT + 5;
 
-	vgawb (CRTC_ADR, 0x1);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x1);
+	cr_data = vgarb(CRTC_DATA);
 	HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);
 	E = HDE + 1;
 
-	vgawb (CRTC_ADR, 0x4);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x4);
+	cr_data = vgarb(CRTC_DATA);
 	HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);
 	F = HRS - E - 3;
 
-	vgawb (CRTC_ADR, 0x2);
-	cr_data = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x2);
+	cr_data = vgarb(CRTC_DATA);
 	HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
 
-	vgawb (SEQ_ADR, 0xc);
-	sr_data = vgarb (SEQ_DATA);
-	vgawb (CRTC_ADR, 0x3);
-	cr_data = vgarb (CRTC_DATA);
-	vgawb (CRTC_ADR, 0x5);
-	cr_data2 = vgarb (CRTC_DATA);
-	HBE =
-	    (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |
-	    ((u16) (sr_data & 0x03) << 6);
+	vgawb(SEQ_ADR, 0xc);
+	sr_data = vgarb(SEQ_DATA);
+	vgawb(CRTC_ADR, 0x3);
+	cr_data = vgarb(CRTC_DATA);
+	vgawb(CRTC_ADR, 0x5);
+	cr_data2 = vgarb(CRTC_DATA);
+	HBE = (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |
+	      ((u16) (sr_data & 0x03) << 6);
 	HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
 
 	temp = HBE - ((E - 1) & 255);
@@ -1958,7 +2275,7 @@
 
 	var->sync = 0;
 
-	mr_data = vgarb (0x1C);
+	mr_data = vgarb(0x1C);
 	if (mr_data & 0x80)
 		var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
 	else
@@ -1980,21 +2297,22 @@
 
 /* ------------------ Public Routines -------------------------------- */
 
-static int sisfb_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
 {
-	memset (fix, 0, sizeof (struct fb_fix_screeninfo));
-	strcpy (fix->id, fb_info.modename);
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, fb_info.modename);
 
 	fix->smem_start = ivideo.video_base;
-
-	/*karl:10/01/2001 */
-	if (!sisfb_mem) {
-		if (ivideo.video_size > 0x800000)
-			fix->smem_len = 0x800000;
-		else
-			fix->smem_len = 0x400000;
-	} else
-		fix->smem_len = sisfb_mem * 0x100000;
+        
+        /*karl:10/01/2001*/ /* TW */
+        if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
+	    if (ivideo.video_size > 0x800000)
+		fix->smem_len = 0x800000;
+	    else
+		fix->smem_len = 0x400000;
+        } else
+		fix->smem_len = sisfb_mem * 1024;
 
 	fix->type = video_type;
 	fix->type_aux = 0;
@@ -2011,101 +2329,107 @@
 	fix->accel = FB_ACCEL_SIS_GLAMOUR;
 	fix->reserved[0] = ivideo.video_size & 0xFFFF;
 	fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
-	fix->reserved[2] = sisfb_caps;
+	fix->reserved[2] = sisfb_caps;	
 
 	return 0;
-
 }
 
-static int sisfb_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *info)
+static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
 {
 	if (con == -1)
-		memcpy (var, &default_var, sizeof (struct fb_var_screeninfo));
+		memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
 	else
 		*var = fb_display[con].var;
 
+	/* JennyLee 2001126: for FSTN */
+	if (var->xres == 320 && var->yres == 480)
+		var->yres = 240;
+	/* ~JennyLee */
+
 	return 0;
 }
 
-static int sisfb_set_var (struct fb_var_screeninfo *var, int con, struct fb_info *info)
+static int sisfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
 {
 	int err;
 	unsigned int cols, rows;
 
 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
-
-	if (sisfb_do_set_var (var, con == currcon, info)) {
-		sisfb_crtc_to_var (var);
+	if (sisfb_do_set_var(var, con == currcon, info)) {
+		sisfb_crtc_to_var(var);	
 		return -EINVAL;
 	}
-
-	sisfb_crtc_to_var (var);
-
-	sisfb_set_disp (con, var);
+	
+	sisfb_crtc_to_var(var);
+	
+	sisfb_set_disp(con, var);
 
 	if (info->changevar)
 		(*info->changevar) (con);
 
-	if ((err = fb_alloc_cmap (&fb_display[con].cmap, 0, 0)))
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
 		return err;
 
-	sisfb_do_install_cmap (con, info);
-
+	sisfb_do_install_cmap(con, info);
+	
 	cols = sisbios_mode[sisfb_mode_idx].cols;
 	rows = sisbios_mode[sisfb_mode_idx].rows;
-	vc_resize_con (rows, cols, fb_display[con].conp->vc_num);
+	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
 
 	return 0;
-
 }
 
-static int sisfb_get_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
+static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
 {
 	if (con == currcon)
-		return fb_get_cmap (cmap, kspc, sis_getcolreg, info);
-	else if (fb_display[con].cmap.len)
-		fb_copy_cmap (&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+		return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
+	else if (fb_display[con].cmap.len)	
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 	else
-		fb_copy_cmap (fb_default_cmap (video_cmap_len), cmap,
-			      kspc ? 0 : 2);
+		fb_copy_cmap(fb_default_cmap(video_cmap_len), cmap, kspc ? 0 : 2);
 
 	return 0;
 }
 
-static int sisfb_set_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
+static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
 {
 	int err;
 
-	if (!fb_display[con].cmap.len) {
-		err = fb_alloc_cmap (&fb_display[con].cmap, video_cmap_len, 0);
+	if (!fb_display[con].cmap.len) {	
+		err = fb_alloc_cmap(&fb_display[con].cmap, video_cmap_len, 0);
 		if (err)
 			return err;
 	}
-	if (con == currcon)
-		return fb_set_cmap (cmap, kspc, sis_setcolreg, info);
+	if (con == currcon)	
+		return fb_set_cmap(cmap, kspc, sis_setcolreg, info);
 	else
-		fb_copy_cmap (cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return 0;
 }
 
-static int sisfb_ioctl (struct inode *inode, struct file *file,
-	     unsigned int cmd, unsigned long arg, int con, struct fb_info *info)
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, int con,
+		       struct fb_info *info)
 {
 	switch (cmd) {
-	case FBIO_ALLOC:
-		if (!capable (CAP_SYS_RAWIO))
+	   case FBIO_ALLOC:
+		if (!capable(CAP_SYS_RAWIO))
 			return -EPERM;
-		sis_malloc ((struct sis_memreq *) arg);
+		sis_malloc((struct sis_memreq *) arg);
 		break;
-	case FBIO_FREE:
-		if (!capable (CAP_SYS_RAWIO))
+	   case FBIO_FREE:
+		if (!capable(CAP_SYS_RAWIO))
 			return -EPERM;
-		sis_free (*(unsigned long *) arg);
+		sis_free(*(unsigned long *) arg);
 		break;
-	case FBIOGET_GLYPH:
-		sis_get_glyph ((SIS_GLYINFO *) arg);
+	   case FBIOGET_GLYPH:
+		sis_get_glyph((SIS_GLYINFO *) arg);
 		break;
-	case FBIOGET_HWCINFO:
+	   case FBIOGET_HWCINFO:
 		{
 			unsigned long *hwc_offset = (unsigned long *) arg;
 
@@ -2117,32 +2441,33 @@
 
 			break;
 		}
-	case FBIOPUT_MODEINFO:
+	   case FBIOPUT_MODEINFO:
 		{
-			struct mode_info *x = (struct mode_info *) arg;
-
-			ivideo.video_bpp = x->bpp;
-			ivideo.video_width = x->xres;
-			ivideo.video_height = x->yres;
-			ivideo.video_vwidth = x->v_xres;
-			ivideo.video_vheight = x->v_yres;
-			ivideo.org_x = x->org_x;
-			ivideo.org_y = x->org_y;
-			ivideo.refresh_rate = x->vrate;
-
+			struct mode_info *x = (struct mode_info *)arg;
+			
+			ivideo.video_bpp      = x->bpp;
+			ivideo.video_width    = x->xres;
+			ivideo.video_height   = x->yres;
+			ivideo.video_vwidth   = x->v_xres;
+			ivideo.video_vheight  = x->v_yres;
+			ivideo.org_x          = x->org_x;
+			ivideo.org_y          = x->org_y;
+			ivideo.refresh_rate   = x->vrate;
+			
 			break;
 		}
-	case FBIOGET_DISPINFO:
-		sis_dispinfo ((struct ap_data *) arg);
+	   case FBIOGET_DISPINFO:
+		sis_dispinfo((struct ap_data *)arg);
 		break;
-	default:
+	   default:
 		return -EINVAL;
 	}
 	return 0;
 
 }
 
-static int sisfb_mmap (struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int sisfb_mmap(struct fb_info *info, struct file *file,
+		      struct vm_area_struct *vma)
 {
 	struct fb_var_screeninfo var;
 	unsigned long start;
@@ -2152,17 +2477,17 @@
 	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
 		return -EINVAL;
 	off = vma->vm_pgoff << PAGE_SHIFT;
-
+	
 	start = (unsigned long) ivideo.video_base;
-	len = PAGE_ALIGN ((start & ~PAGE_MASK) + ivideo.video_size);
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
 
 	if (off >= len) {
 		off -= len;
-		sisfb_get_var (&var, currcon, info);
+		sisfb_get_var(&var, currcon, info);
 		if (var.accel_flags)
 			return -EINVAL;
 		start = (unsigned long) ivideo.mmio_base;
-		len = PAGE_ALIGN ((start & ~PAGE_MASK) + sisfb_mmio_size);
+		len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
 	}
 
 	start &= PAGE_MASK;
@@ -2173,81 +2498,87 @@
 
 #if defined(__i386__)
 	if (boot_cpu_data.x86 > 3)
-		pgprot_val (vma->vm_page_prot) |= _PAGE_PCD;
+		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+#else	/* TW: 2.5 API */
+	if (io_remap_page_range(vma, vma->vm_start, off, vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
 #endif
-	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start, vma->vm_page_prot)) 
 		return -EAGAIN;
 	return 0;
 
 }
 
 static struct fb_ops sisfb_ops = {
-	owner:THIS_MODULE,
-	fb_get_fix:sisfb_get_fix,
-	fb_get_var:sisfb_get_var,
-	fb_set_var:sisfb_set_var,
-	fb_get_cmap:sisfb_get_cmap,
-	fb_set_cmap:sisfb_set_cmap,
-	fb_ioctl:sisfb_ioctl,
-	fb_mmap:sisfb_mmap,
+	owner:		THIS_MODULE,
+	fb_get_fix:	sisfb_get_fix,
+	fb_get_var:	sisfb_get_var,
+	fb_set_var:	sisfb_set_var,
+	fb_get_cmap:	sisfb_get_cmap,
+	fb_set_cmap:	sisfb_set_cmap,
+	fb_ioctl:	sisfb_ioctl,
+	fb_mmap:	sisfb_mmap,
 };
 
 /* ------------ Interface to the low level console driver -------------*/
 
-static int sisfb_update_var (int con, struct fb_info *info)
+static int sisfb_update_var(int con, struct fb_info *info)
 {
 	return 0;
 }
 
-static int sisfb_switch (int con, struct fb_info *info)
+static int sisfb_switch(int con, struct fb_info *info)
 {
 	int cols, rows;
 
 	if (fb_display[currcon].cmap.len)
-		fb_get_cmap (&fb_display[currcon].cmap, 1, sis_getcolreg, info);
+		fb_get_cmap(&fb_display[currcon].cmap, 1, sis_getcolreg, info);
 
 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
 
-	if (!memcmp(&fb_display[con].var, &fb_display[currcon].var, sizeof (struct fb_var_screeninfo))) {
+	if (!memcmp(&fb_display[con].var, &fb_display[currcon].var,
+	                           sizeof(struct fb_var_screeninfo))) {
 		currcon = con;
 		return 1;
 	}
 
 	currcon = con;
 
-	sisfb_do_set_var (&fb_display[con].var, 1, info);
-
-	sisfb_set_disp (con, &fb_display[con].var);
+	sisfb_do_set_var(&fb_display[con].var, 1, info);
 
-	sisfb_do_install_cmap (con, info);
+	sisfb_set_disp(con, &fb_display[con].var);
+	
+	sisfb_do_install_cmap(con, info);
 
 	cols = sisbios_mode[sisfb_mode_idx].cols;
 	rows = sisbios_mode[sisfb_mode_idx].rows;
-	vc_resize_con (rows, cols, fb_display[con].conp->vc_num);
+	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
 
-	sisfb_update_var (con, info);
+	sisfb_update_var(con, info);
 
 	return 1;
-
 }
 
-static void sisfb_blank (int blank, struct fb_info *info)
+static void sisfb_blank(int blank, struct fb_info *info)
 {
 	u8 reg;
 
-	vgawb (CRTC_ADR, 0x17);
-	reg = vgarb (CRTC_DATA);
+	vgawb(CRTC_ADR, 0x17);
+	reg = vgarb(CRTC_DATA);
 
-	if (blank > 0)
+	if (blank > 0)		
 		reg &= 0x7f;
-	else
+	else			
 		reg |= 0x80;
 
-	vgawb (CRTC_ADR, 0x17);
-	vgawb (CRTC_DATA, reg);
+	vgawb(CRTC_ADR, 0x17);
+	vgawb(CRTC_DATA, reg);
 }
 
-int sisfb_setup (char *options)
+int sisfb_setup(char *options)
 {
 	char *this_opt;
 
@@ -2257,47 +2588,64 @@
 	if (!options || !*options)
 		return 0;
 
-	for (this_opt = strtok (options, ","); this_opt;
-	     this_opt = strtok (NULL, ",")) {
+#if 0	/* TW (Alex Tribble): Change for 2.5 series */
+	for (this_opt = strtok(options, ","); this_opt;
+	     this_opt = strtok(NULL, ",")) {
+#endif
+	while((this_opt = strsep(&options, ","))) {
 		if (!*this_opt)
 			continue;
 
-		if (!strcmp (this_opt, "inverse")) {
+		if (!strcmp(this_opt, "inverse")) {
 			sisfb_inverse = 1;
-			fb_invert_cmaps ();
-		} else if (!strncmp (this_opt, "font:", 5)) {
-			strcpy (fb_info.fontname, this_opt + 5);
-		} else if (!strncmp (this_opt, "mode:", 5)) {
-			sisfb_search_mode (this_opt + 5);
-		} else if (!strncmp (this_opt, "vrate:", 6)) {
+			fb_invert_cmaps();
+		} else if (!strncmp(this_opt, "font:", 5)) {
+			strcpy(fb_info.fontname, this_opt + 5);
+		} else if (!strncmp(this_opt, "mode:", 5)) {
+			sisfb_search_mode(this_opt + 5);
+		} else if (!strncmp(this_opt, "vrate:", 6)) {
+			ivideo.refresh_rate =
+			    simple_strtoul(this_opt + 6, NULL, 0);
+		} else if (!strncmp(this_opt, "rate:", 5)) {
 			ivideo.refresh_rate =
-			    simple_strtoul (this_opt + 6, NULL, 0);
-		} else if (!strncmp (this_opt, "off", 3)) {
+			    simple_strtoul(this_opt + 5, NULL, 0);
+		} else if (!strncmp(this_opt, "off", 3)) {
 			sisfb_off = 1;
-		} else if (!strncmp (this_opt, "crt1off", 7)) {
+		} else if (!strncmp(this_opt, "crt1off", 7)) {
 			sisfb_crt1off = 1;
-		} else if (!strncmp (this_opt, "filter:", 7)) {
-			filter = (int) simple_strtoul (this_opt + 7, NULL, 0);
+		} else if (!strncmp(this_opt, "filter:", 7)) {
+			filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
+		} else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
+			sisfb_search_crt2type(this_opt + 14);
+		} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
+			sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
+                  /*karl*/
+                } else if (!strncmp(this_opt, "tvmode:",7)) {
+                        if (!strncmp(this_opt + 7, "pal",3))
+                         	sisfb_tvmode = 1;
+                        if (!strncmp(this_opt + 7, "ntsc",4))
+                         	sisfb_tvmode = 2;
+                }
+                 /*karl:10/01/2001*/ 
+                else if (!strncmp(this_opt, "mem:",4)) {
+		        sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
+                }
+		/* JennyLee 20011211 */
+		else if (!strncmp(this_opt, "dstn:", 5)) {
+			enable_dstn = simple_strtoul(this_opt + 5, NULL, 0);
+		}
+		/* ~JennyLee 20011211 */
+		else if (!strncmp(this_opt, "queuemode:", 10)) {
+			sisfb_search_queuemode(this_opt + 10);
 		}
-		/*karl */
-		else if (!strncmp (this_opt, "tvmode:", 7)) {
-			if (!strncmp (this_opt + 7, "pal", 3))
-				sisfb_tvmode = 1;
-			if (!strncmp (this_opt + 7, "ntsc", 4))
-				sisfb_tvmode = 2;
-		}
-		/*karl:10/01/2001 */
-		else if (!strncmp (this_opt, "mem:", 4)) {
-
-			sisfb_mem = simple_strtoul (this_opt + 4, NULL, 0);
 
-		} else
-			DPRINTK ("invalid parameter %s\n", this_opt);
+		else
+			printk(KERN_INFO "sisfb: Invalid parameter %s\n", this_opt);
 	}
 	return 0;
 }
 
-int __init sisfb_init (void)
+int __init sisfb_init(void)
 {
 	struct pci_dev *pdev = NULL;
 	struct board *b;
@@ -2305,25 +2653,37 @@
 	//unsigned long rom_vbase;
 	u32 reg32;
 	u16 reg16;
-	u8 reg;
-	int nRes;
+	u8  reg;
+	int temp1, temp2;
+
+	outb(0x77, 0x80);
 
-	outb (0x77, 0x80);
+#if 0 	
+	/* for DOC VB */
+	sisfb_set_reg4(0xcf8,0x800000e0);
+	reg32 = sisfb_get_reg3(0xcfc);
+	reg32 = reg32 | 0x00001000;
+	sisfb_set_reg4(0xcfc,reg32);
+	}
+#endif
 
 	if (sisfb_off)
 		return -ENXIO;
 
-	pci_for_each_dev (pdev)
-	{
+//	printk("20011213:enable_dstn=%d \n", enable_dstn);
+	if (enable_dstn)
+		SetEnableDstn();
+
+	pci_for_each_dev(pdev) {
 		for (b = sisdev_list; b->vendor; b++) {
 			if ((b->vendor == pdev->vendor)
 			    && (b->device == pdev->device)) {
 				pdev_valid = 1;
-				strcpy (fb_info.modename, b->name);
+				strcpy(fb_info.modename, b->name);
 				ivideo.chip_id = pdev->device;
-				pci_read_config_byte (pdev, PCI_REVISION_ID,
-						      &ivideo.revision_id);
-				pci_read_config_word (pdev, PCI_COMMAND, &reg16);
+				pci_read_config_byte(pdev, PCI_REVISION_ID,
+				                     &ivideo.revision_id);
+				pci_read_config_word(pdev, PCI_COMMAND, &reg16);
 				// Eden Chen
 				//sishw_ext.uRevisionID = ivideo.revision_id;
 				sishw_ext.jChipRevision = ivideo.revision_id;
@@ -2332,148 +2692,181 @@
 				break;
 			}
 		}
-	
+
 		if (pdev_valid)
 			break;
 	}
-	
+
 	if (!pdev_valid)
 		return -1;
-	
-	// Eden Chen
+
+// Eden Chen
 	switch (ivideo.chip_id) {
-	case PCI_DEVICE_ID_SI_300:
+	   case PCI_DEVICE_ID_SI_300:
 		ivideo.chip = SIS_300;
 		sisvga_engine = SIS_300_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
 		break;
-	case PCI_DEVICE_ID_SI_630_VGA:
-	{
-		sisfb_set_reg4 (0xCF8, 0x80000000);
-		reg32 = sisfb_get_reg3 (0xCFC);
-		if (reg32 == 0x07301039) {
-			ivideo.chip = SIS_730;
-			strcpy (fb_info.modename, "SIS 730");
-		} else
-			ivideo.chip = SIS_630;
-
-		sisvga_engine = SIS_300_VGA;
-		break;
-	}
-	case PCI_DEVICE_ID_SI_540_VGA:
+	   case PCI_DEVICE_ID_SI_630_VGA:
+		{
+			sisfb_set_reg4(0xCF8, 0x80000000);
+			reg32 = sisfb_get_reg3(0xCFC);
+			if (reg32 == 0x07301039) {
+				ivideo.chip = SIS_730;
+				strcpy(fb_info.modename, "SIS 730");
+			} else
+				ivideo.chip = SIS_630;
+
+			sisvga_engine = SIS_300_VGA;
+			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+			sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
+			break;
+		}
+	   case PCI_DEVICE_ID_SI_540_VGA:
 		ivideo.chip = SIS_540;
 		sisvga_engine = SIS_300_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
 		break;
-	case PCI_DEVICE_ID_SI_315H:
+	   case PCI_DEVICE_ID_SI_315H:
 		ivideo.chip = SIS_315H;
 		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
-	case PCI_DEVICE_ID_SI_315:
+	   case PCI_DEVICE_ID_SI_315:
 		ivideo.chip = SIS_315;
 		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
-	case PCI_DEVICE_ID_SI_315PRO:
+	   case PCI_DEVICE_ID_SI_315PRO:
 		ivideo.chip = SIS_315PRO;
 		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
-	case PCI_DEVICE_ID_SI_550_VGA:
+	   case PCI_DEVICE_ID_SI_550_VGA:
 		ivideo.chip = SIS_550;
 		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+		break;
+	   case PCI_DEVICE_ID_SI_650_VGA:
+		ivideo.chip = SIS_650;
+		sisvga_engine = SIS_315_VGA;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
 	}
-
 	// Eden Chen
 	//sishw_ext.jChipID = ivideo.chip;
 	sishw_ext.jChipType = ivideo.chip;
 	// for Debug
-	if ((sishw_ext.jChipType == SIS_315PRO)
-	    || (sishw_ext.jChipType == SIS_315))
+	if ((sishw_ext.jChipType == SIS_315PRO) 
+	   || (sishw_ext.jChipType == SIS_315) )
 		sishw_ext.jChipType = SIS_315H;
-		// ~Eden Chen
+	// ~Eden Chen
 
-	DPRINTK ("%s is used as %s device(VGA Engine %d).\n",
-		 fb_info.modename, sisvga_enabled ? "primary" : "secondary",
-		 sisvga_engine);
-	
-	ivideo.video_base = pci_resource_start (pdev, 0);
-	ivideo.mmio_base = pci_resource_start (pdev, 1);
+	DPRINTK("%s is used as %s device(VGA Engine %d).\n", 
+		fb_info.modename, sisvga_enabled ? "primary" : "secondary", sisvga_engine);
+
+	ivideo.video_base = pci_resource_start(pdev, 0);
+	ivideo.mmio_base = pci_resource_start(pdev, 1);
 	// Eden Chen
 	//sishw_ext.IOAddress = (unsigned short) ivideo.vga_base 
-	//      = pci_resource_start(pdev, 2) + 0x30;
-	sishw_ext.ulIOAddress = (unsigned short) ivideo.vga_base = pci_resource_start (pdev, 2) + 0x30;
+	//	= pci_resource_start(pdev, 2) + 0x30;
+	sishw_ext.ulIOAddress = (unsigned short) ivideo.vga_base
+		= pci_resource_start(pdev, 2) + 0x30;
 	// ~Eden Chen
 
-	sisfb_mmio_size = pci_resource_len (pdev, 1);
+	sisfb_mmio_size =  pci_resource_len(pdev, 1);
 
 	if (!sisvga_enabled)
-		if (pci_enable_device (pdev))
-			return -EIO;
+		if (pci_enable_device(pdev))   return -EIO;
+
+// Eden Eden
+//#ifdef LINUXBIOS
+//	sishw_ext.VirtualRomBase = rom_vbase = (unsigned long) rom_data;
+//#else
+//	{
+//	unsigned long rom_base  = 0x000C0000;
+//
+//	request_region(rom_base, 32, "sisfb");
+//	sishw_ext.VirtualRomBase = rom_vbase 
+//		= (unsigned long) ioremap(rom_base, MAX_ROM_SCAN);
+//	}
+//#endif
+// ~Eden Chen
 	
-	vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-	vgawb (SEQ_DATA, SIS_PASSWORD);
+	vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+	vgawb(SEQ_DATA, SIS_PASSWORD);
 
 #ifdef LINUXBIOS
 #ifdef CONFIG_FB_SIS_300
-	if (sisvga_engine == SIS_300_VGA)
-	{
-		vgawb (SEQ_ADR, 0x28);
-		vgawb (SEQ_DATA, 0x37);
+	if (sisvga_engine == SIS_300_VGA) {
+		vgawb(SEQ_ADR, 0x28);
+		vgawb(SEQ_DATA, 0x37);
 
-		vgawb (SEQ_ADR, 0x29);
-		vgawb (SEQ_DATA, 0x61);
+		vgawb(SEQ_ADR, 0x29);
+		vgawb(SEQ_DATA, 0x61);
 
-		vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
-		reg = vgarb (SEQ_DATA);
+		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
+		reg = vgarb(SEQ_DATA);
 		reg |= SIS_SCRATCH_REG_1A_MASK;
-		vgawb (SEQ_DATA, reg);
+		vgawb(SEQ_DATA, reg);
 	}
 #endif
 #ifdef CONFIG_FB_SIS_315
-	if (ivideo.chip == SIS_550) {
-		vgawb (SEQ_ADR, 0x28);
-		vgawb (SEQ_DATA, 0x5A);
-	
-		vgawb (SEQ_ADR, 0x29);
-		vgawb (SEQ_DATA, 0x64);
+	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {
+		vgawb(SEQ_ADR,  0x28);
+		vgawb(SEQ_DATA, 0x5A);
+
+		vgawb(SEQ_ADR,  0x29);
+		vgawb(SEQ_DATA, 0x64);
 
-		vgawb (CRTC_ADR, 0x3A);
-		vgawb (CRTC_DATA, 0x00);
+		vgawb(CRTC_ADR,  0x3A);
+		vgawb(CRTC_DATA, 0x00);
 	}
 #endif
-#endif
+#endif /* LinuxBIOS */
 
 	if (sisvga_engine == SIS_315_VGA) {
 		switch (ivideo.chip) {
-		case SIS_315H:
-		case SIS_315:
+		   case SIS_315H:
+		   case SIS_315:
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 			break;
-		case SIS_550:
+		   case SIS_550:
+		   case SIS_650:
 			// Eden Chen
 			//vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
 			//reg = vgarb(SEQ_DATA);
 			//if (reg & SIS_SCRATCH_REG_1A_MASK)
-			//      sishw_ext.bIntegratedMMEnabled = TRUE;
+			//	sishw_ext.bIntegratedMMEnabled = TRUE;
 			//else
-			//      sishw_ext.bIntegratedMMEnabled = FALSE;
+			//	sishw_ext.bIntegratedMMEnabled = FALSE;
 			//for Debug
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 			// ~Eden Chen
 			break;
-		default:
+		   default:
 			break;
 		}
 	} else if (sisvga_engine == SIS_300_VGA) {
 		if (ivideo.chip == SIS_300) {
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 		} else {
-			vgawb (SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
-			reg = vgarb (SEQ_DATA);
+			vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
+			reg = vgarb(SEQ_DATA);
 			if (reg & SIS_SCRATCH_REG_1A_MASK)
 				sishw_ext.bIntegratedMMEnabled = TRUE;
 			else
 				sishw_ext.bIntegratedMMEnabled = FALSE;
 		}
 	}
+
 	// Eden Chen
 	sishw_ext.pDevice = NULL;
 	sishw_ext.pjVirtualRomBase = NULL;
@@ -2481,316 +2874,427 @@
 	sishw_ext.bSkipDramSizing = 0;
 	sishw_ext.pQueryVGAConfigSpace = &sisfb_query_VGA_config_space;
 	sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
-	strcpy (sishw_ext.szVBIOSVer, "0.84");
+	strcpy(sishw_ext.szVBIOSVer, "0.84");
 
-	sishw_ext.pSR = vmalloc (sizeof (SIS_DSReg) * SR_BUFFER_SIZE);
-	if (sishw_ext.pSR == NULL)
-		printk (KERN_DEBUG "Allocated SRReg space fail.\n");
+	sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
+	if (sishw_ext.pSR == NULL) {
+		printk(KERN_INFO "sisfb: Fatal error: Allocating SRReg space failed.\n");
+		return -ENODEV;
+	}
 	sishw_ext.pSR[0].jIdx = sishw_ext.pSR[0].jVal = 0xFF;
 
-	sishw_ext.pCR = vmalloc (sizeof (SIS_DSReg) * CR_BUFFER_SIZE);
-	if (sishw_ext.pCR == NULL)
-		printk (KERN_DEBUG "Allocated CRReg space fail.\n");
+	sishw_ext.pCR = vmalloc(sizeof(SIS_DSReg) * CR_BUFFER_SIZE);
+	if (sishw_ext.pCR == NULL) {
+		printk(KERN_INFO "sisfb: Fatal error: Allocating CRReg space failed.\n");
+		return -ENODEV;
+	}
 	sishw_ext.pCR[0].jIdx = sishw_ext.pCR[0].jVal = 0xFF;
 	// ~Eden Chen
 
-	#ifdef CONFIG_FB_SIS_300
+#ifdef CONFIG_FB_SIS_300
 	if (sisvga_engine == SIS_300_VGA) {
 		if (!sisvga_enabled) {
 			// Eden Chen
-			sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x2000000);
-			//SiSInit300(&sishw_ext);
-			SiSInit (&sishw_ext);
-			vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-			vgawb (SEQ_DATA, SIS_PASSWORD);
-			// ~Eden Chen
+			sishw_ext.pjVideoMemoryAddress 
+				= ioremap(ivideo.video_base, 0x2000000);
+			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+				//SiSInit300(&sishw_ext);
+				SiSInit(&sishw_ext);
+				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+				vgawb(SEQ_DATA, SIS_PASSWORD);
+				// ~Eden Chen
+			}
 		}
 #ifdef LINUXBIOS
 		else {
-			// Eden Chen
 			sishw_ext.pjVideoMemoryAddress
-			    = ioremap (ivideo.video_base, 0x2000000);
-			//SiSInit300(&sishw_ext);
-			SiSInit (&sishw_ext);
-			vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-			vgawb (SEQ_DATA, SIS_PASSWORD);
-			// ~Eden Chen
+				= ioremap(ivideo.video_base, 0x2000000);
+			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+				SiSInit(&sishw_ext);
+				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+				vgawb(SEQ_DATA, SIS_PASSWORD);
+			}
+		}
+		if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+			vgawb(SEQ_ADR, 0x7);
+			reg = vgarb(SEQ_DATA);
+			reg |= 0x10;
+			vgawb(SEQ_DATA, reg);
 		}
-		vgawb (SEQ_ADR, 0x7);
-		reg = vgarb (SEQ_DATA);
-		reg |= 0x10;
-		vgawb (SEQ_DATA, reg);
 #endif
-		sisfb_get_dram_size_300 ();
+		if (sisfb_get_dram_size_300()) {
+			printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size\n");
+			return -ENODEV;
+		}
 	}
 #endif
 
-	#ifdef CONFIG_FB_SIS_315
+#ifdef CONFIG_FB_SIS_315
 	if (sisvga_engine == SIS_315_VGA) {
 		if (!sisvga_enabled) {
 			/* Mapping Max FB Size for 315 Init */
 			// Eden Chen
 			//sishw_ext.VirtualVideoMemoryAddress 
-			sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x8000000);
-			//SiSInit310(&sishw_ext);
-			SiSInit (&sishw_ext);
-	
-			vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-			vgawb (SEQ_DATA, SIS_PASSWORD);
-	
-			sishw_ext.bSkipDramSizing = TRUE;
-			vgawb (SEQ_ADR, 0x13);
-			sishw_ext.pSR[0].jIdx = 0x13;
-			sishw_ext.pSR[0].jVal = vgarb (SEQ_DATA);
-			vgawb (SEQ_ADR, 0x14);
-			sishw_ext.pSR[1].jIdx = 0x14;
-			sishw_ext.pSR[1].jVal = vgarb (SEQ_DATA);
-			sishw_ext.pSR[2].jIdx = 0xFF;
-			sishw_ext.pSR[2].jVal = 0xFF;
-			// Eden Chen
+			sishw_ext.pjVideoMemoryAddress 
+				= ioremap(ivideo.video_base, 0x8000000);
+			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+				SiSInit(&sishw_ext);
+
+				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+				vgawb(SEQ_DATA, SIS_PASSWORD);
+
+				sishw_ext.bSkipDramSizing = TRUE;
+				vgawb(SEQ_ADR, 0x13);
+				sishw_ext.pSR[0].jIdx = 0x13;
+				sishw_ext.pSR[0].jVal = vgarb(SEQ_DATA);
+				vgawb(SEQ_ADR, 0x14);
+				sishw_ext.pSR[1].jIdx = 0x14;
+				sishw_ext.pSR[1].jVal = vgarb(SEQ_DATA);
+				sishw_ext.pSR[2].jIdx = 0xFF;
+				sishw_ext.pSR[2].jVal = 0xFF;
+			}
 		}
 #ifdef LINUXBIOS
 		else {
-			sishw_ext.pjVideoMemoryAddress = ioremap (ivideo.video_base, 0x8000000);
-			SiSInit (&sishw_ext);
-			vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-			vgawb (SEQ_DATA, SIS_PASSWORD);
-	
-			sishw_ext.bSkipDramSizing = TRUE;
-			vgawb (SEQ_ADR, 0x13);
-			sishw_ext.pSR[0].jIdx = 0x13;
-			sishw_ext.pSR[0].jVal = vgarb (SEQ_DATA);
-			vgawb (SEQ_ADR, 0x14);
-			sishw_ext.pSR[1].jIdx = 0x14;
-			sishw_ext.pSR[1].jVal = vgarb (SEQ_DATA);
-			sishw_ext.pSR[2].jIdx = 0xFF;
-			sishw_ext.pSR[2].jVal = 0xFF;
-		}
-#endif
-		sisfb_get_dram_size_315 ();
-	}
-#endif
-	//Eden Chen 
-	vgawb (SEQ_ADR, IND_SIS_PCI_ADDRESS_SET);
-	reg = vgarb (SEQ_DATA);
-	reg |= SIS_PCI_ADDR_ENABLE;
-	reg |= SIS_MEM_MAP_IO_ENABLE;
-	vgawb (SEQ_DATA, reg);
-
-	vgawb (SEQ_ADR, IND_SIS_MODULE_ENABLE);
-	reg = vgarb (SEQ_DATA);
-	reg |= SIS_ENABLE_2D;
-	vgawb (SEQ_DATA, reg);
-	//~Eden Chen
+			sishw_ext.pjVideoMemoryAddress
+				= ioremap(ivideo.video_base, 0x8000000);
+			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+				SiSInit(&sishw_ext);
+				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+				vgawb(SEQ_DATA, SIS_PASSWORD);
+
+				sishw_ext.bSkipDramSizing = TRUE;
+				vgawb(SEQ_ADR, 0x13);
+				sishw_ext.pSR[0].jIdx = 0x13;
+				sishw_ext.pSR[0].jVal = vgarb(SEQ_DATA);
+				vgawb(SEQ_ADR, 0x14);
+				sishw_ext.pSR[1].jIdx = 0x14;
+				sishw_ext.pSR[1].jVal = vgarb(SEQ_DATA);
+				sishw_ext.pSR[2].jIdx = 0xFF;
+				sishw_ext.pSR[2].jVal = 0xFF;
+			}
+		}
+#endif
+		if (sisfb_get_dram_size_315()) {
+			printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
+			return -ENODEV;
+		}
+	}
+#endif
+	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+		//Eden Chen
+		vgawb(SEQ_ADR, IND_SIS_PCI_ADDRESS_SET);
+		reg = vgarb(SEQ_DATA);
+		reg |= SIS_PCI_ADDR_ENABLE;    	/* Enable PCI_LINEAR_ADDRESSING */
+		reg |= SIS_MEM_MAP_IO_ENABLE;  	/* Enable MMIO_ENABLE */
+		vgawb(SEQ_DATA, reg);
+
+		vgawb(SEQ_ADR, IND_SIS_MODULE_ENABLE);
+		reg = vgarb(SEQ_DATA);
+		reg |= SIS_ENABLE_2D;		/* Enable 2D accelerator engine */
+		vgawb(SEQ_DATA, reg);
+		//~Eden Chen
+	}
 
 	// Eden Chen
 	sishw_ext.ulVideoMemorySize = ivideo.video_size;
 	// ~Eden Chen
-	if (!request_mem_region (ivideo.video_base, ivideo.video_size, "sisfb FB")) {
-		printk (KERN_ERR "sisfb: cannot reserve frame buffer memory\n");
+	if (!request_mem_region(ivideo.video_base, ivideo.video_size, "sisfb FB")) {
+		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
 		return -ENODEV;
 	}
 
-	if (!request_mem_region (ivideo.mmio_base, sisfb_mmio_size, "sisfb MMIO")) {
-		printk (KERN_ERR "sisfb: cannot reserve MMIO region\n");
-		release_mem_region (ivideo.video_base, ivideo.video_size);
+	if (!request_mem_region(ivideo.mmio_base, sisfb_mmio_size, "sisfb MMIO")) {
+		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
+		release_mem_region(ivideo.video_base, ivideo.video_size);
 		return -ENODEV;
 	}
 	// Eden Chen
 	//sishw_ext.VirtualVideoMemoryAddress = ivideo.video_vbase 
-	sishw_ext.pjVideoMemoryAddress = ivideo.video_vbase = ioremap (ivideo.video_base, ivideo.video_size);
+	sishw_ext.pjVideoMemoryAddress = ivideo.video_vbase 
+		= ioremap(ivideo.video_base, ivideo.video_size);
 	// Eden Chen
-	ivideo.mmio_vbase = ioremap (ivideo.mmio_base, sisfb_mmio_size);
+	ivideo.mmio_vbase = ioremap(ivideo.mmio_base, sisfb_mmio_size);
 
-	printk (KERN_INFO
-		"sisfb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
-		ivideo.video_base, ivideo.video_vbase, ivideo.video_size / 1024);
+	printk(KERN_INFO
+	       "sisfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
+	       ivideo.video_base, ivideo.video_vbase,
+	       ivideo.video_size / 1024);
+
+	printk(KERN_INFO
+	       "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
+	       ivideo.mmio_base, ivideo.mmio_vbase,
+	       sisfb_mmio_size / 1024);
 
-	printk (KERN_INFO
-		"sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
-		ivideo.mmio_base, ivideo.mmio_vbase, sisfb_mmio_size / 1024);
+	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
 
-	#ifdef CONFIG_FB_SIS_300
-	if (sisvga_engine == SIS_300_VGA) {
-		sisfb_get_VB_type_300 ();
-		if (ivideo.hasVB != HASVB_NONE) {
-			sisfb_detect_VB_connect_300 ();
+#ifdef CONFIG_FB_SIS_300
+		if (sisvga_engine == SIS_300_VGA) {
+			sisfb_get_VB_type_300();
+			if (ivideo.hasVB != HASVB_NONE) {
+				sisfb_detect_VB_connect_300();
+			}
 		}
-	}
 #endif
 
 #ifdef CONFIG_FB_SIS_315
-	if (sisvga_engine == SIS_315_VGA) {
-		sisfb_get_VB_type_315 ();
-		if (ivideo.hasVB != HASVB_NONE) {
-			sisfb_detect_VB_connect_315 ();
+		if (sisvga_engine == SIS_315_VGA) {
+			sisfb_get_VB_type_315();
+			if (ivideo.hasVB != HASVB_NONE) {
+				sisfb_detect_VB_connect_315();
+			}
 		}
-	}
 #endif
 
-	// Eden Chen
-sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
-sishw_ext.usExternalChip = 0;
-
-	switch (ivideo.hasVB) {
-	case HASVB_301:
-		/*karl */
-		vgawb (VB_PART4_ADR, 0x01);
-		reg = vgarb (VB_PART4_DATA);
-		if ((reg != 0xB1) && (reg != 0xB0))
-			sishw_ext.ujVBChipID = VB_CHIP_301;
-		else
-			sishw_ext.ujVBChipID = VB_CHIP_301B;
-		break;
-	case HASVB_302:
-		sishw_ext.ujVBChipID = VB_CHIP_302;
-		break;
-	case HASVB_303:
-		sishw_ext.ujVBChipID = VB_CHIP_303;
-		break;
-	case HASVB_LVDS:
-		sishw_ext.usExternalChip = 0x1;
-		break;
-	case HASVB_TRUMPION:
-		sishw_ext.usExternalChip = 0x2;
-		break;
-	case HASVB_CHRONTEL:
-		sishw_ext.usExternalChip = 0x4;
-		break;
-	case HASVB_LVDS_CHRONTEL:
-		sishw_ext.usExternalChip = 0x5;
-		break;
-	default:
-		break;
-	}
+		// Eden Chen
+		sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
+		sishw_ext.usExternalChip = 0;
 
-	// ~Eden Chen
+		switch (ivideo.hasVB) {
 
-	if (ivideo.disp_state & DISPTYPE_DISP2) {
-		if (sisfb_crt1off)
-			ivideo.disp_state |= DISPMODE_SINGLE;
-		else
-			ivideo.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
-	} else
-		ivideo.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
-
-	if (ivideo.disp_state & DISPTYPE_LCD) {
-		vgawb (CRTC_ADR, IND_SIS_LCD_PANEL);
-		reg = vgarb (CRTC_DATA);
-		// Eden Chen
-		switch (reg) {
-		case SIS_LCD_PANEL_800X600:
-			sishw_ext.ulCRT2LCDType = LCD_800x600;
-			break;
-		case SIS_LCD_PANEL_1024X768:
-			sishw_ext.ulCRT2LCDType = LCD_1024x768;
-			break;
-		case SIS_LCD_PANEL_1280X1024:
-			sishw_ext.ulCRT2LCDType = LCD_1280x1024;
+		case HASVB_301:
+			/*karl*/
+			vgawb(VB_PART4_ADR,0x01);
+			reg = vgarb(VB_PART4_DATA);
+			if (reg >= 0xD0) {
+				sishw_ext.ujVBChipID = VB_CHIP_301B;
+				printk(KERN_INFO "sisfb: SiS301LV bridge detected\n");
+	  		} else if (reg >= 0xB0) {
+				sishw_ext.ujVBChipID = VB_CHIP_301B;
+				printk(KERN_INFO "sisfb: SiS301B bridge detected\n");
+			} else {
+				sishw_ext.ujVBChipID = VB_CHIP_301;
+				printk(KERN_INFO "sisfb: SiS301 bridge detected\n");
+			}
 			break;
-		case SIS_LCD_PANEL_640X480:
-			sishw_ext.ulCRT2LCDType = LCD_640x480;
+		case HASVB_302:
+			vgawb(VB_PART4_ADR,0x01);
+			reg = vgarb(VB_PART4_DATA);
+			sishw_ext.ujVBChipID = VB_CHIP_302;
+			if (reg >= 0xD0) {
+				printk(KERN_INFO "sisfb: SiS302LV bridge detected\n");
+	  		} else if (reg >= 0xB0) {
+				printk(KERN_INFO "sisfb: SiS302B bridge detected\n");
+			} else {
+				printk(KERN_INFO "sisfb: SiS302 bridge detected\n");
+			}
 			break;
-		case SIS_LCD_PANEL_1280X960:
-			sishw_ext.ulCRT2LCDType = LCD_1280x960;
+		case HASVB_303:
+			sishw_ext.ujVBChipID = VB_CHIP_303;
+			printk(KERN_INFO "sisfb: SiS303 bridge detected (not supported)\n");
+			break;
+		case HASVB_LVDS:
+			sishw_ext.usExternalChip = 0x1;
+			printk(KERN_INFO "sisfb: LVDS bridge detected\n");
+			break;
+		case HASVB_TRUMPION:
+			sishw_ext.usExternalChip = 0x2;
+			printk(KERN_INFO "sisfb: TRUMPION TV converter detected\n");
+			break;
+		case HASVB_CHRONTEL:
+			sishw_ext.usExternalChip = 0x4;
+			printk(KERN_INFO "sisfb: Chrontel TV converter detected\n");
+			break;
+		case HASVB_LVDS_CHRONTEL:
+			sishw_ext.usExternalChip = 0x5;
+			printk(KERN_INFO "sisfb: LVDS bridge and Chrontel TV converter detected\n");
 			break;
 		default:
-			sishw_ext.ulCRT2LCDType = LCD_1024x768;
+			printk(KERN_INFO "sisfb: No or unknown bridge type detected\n");
 			break;
 		}
-	// ~Eden Chen
-	}
+		// ~Eden Chen
 
-	if (sisfb_mode_idx >= 0)
-		sisfb_validate_mode ();
-	
-	if (sisfb_mode_idx < 0) {
-		switch (ivideo.disp_state & DISPTYPE_DISP2) {
-		case DISPTYPE_LCD:
-			sisfb_mode_idx = DEFAULT_LCDMODE;
-			break;
-		case DISPTYPE_TV:
-			sisfb_mode_idx = DEFAULT_TVMODE;
-			break;
-		default:
-			sisfb_mode_idx = DEFAULT_MODE;
-			break;
+		/* TW: Determine and detect attached TV's on Chrontel */
+		if (sishw_ext.usExternalChip == 0x04 || sishw_ext.usExternalChip == 0x05) {
+		    SiSRegInit(sishw_ext.ulIOAddress);
+		    temp1=SiS_GetCH7005(0x25);
+		    if ((temp1 >= 50) && (temp1 <= 100)) {
+	    		/* TW: Read power status */
+	    		temp1 = SiS_GetCH7005(0x0e);
+	    		if ((temp1&0x03)!=0x03) {
+		        	/* TW: Power all outputs */
+	        		SiS_SetCHTVRegANDOR(0x030E,0xF8);
+	    		}
+			/* TW: Sense connected TV devices */
+	    		SiS_SetCH7005(0x0110);
+	    		SiS_SetCH7005(0x0010);
+	    		temp1 = SiS_GetCH7005(0x10);
+	    		if (!(temp1 & 0x08)) {
+				/* TW: So we can be sure that there IS a SVHS output */
+				printk(KERN_INFO
+				   "sisfb: Chrontel: Detected TV connected to SVHS output\n");
+				ivideo.TV_plug = TVPLUG_SVIDEO;
+				vgawb(CRTC_ADR, 0x32);
+				temp2 = vgarb(CRTC_DATA) | 0x02;
+				vgawb(CRTC_DATA, temp2);
+			} else if (!(temp1 & 0x02)) {
+				/* TW: So we can be sure that there IS a CVBS output */
+				printk(KERN_INFO
+				   "sisfb: Chrontel: Detected TV connected to CVBS output\n");
+				ivideo.TV_plug = TVPLUG_COMPOSITE;
+				vgawb(CRTC_ADR, 0x32);
+				temp2 = vgarb(CRTC_DATA) | 0x01;
+				vgawb(CRTC_DATA, temp2);
+	    		} else {
+		    		SiS_SetCHTVRegANDOR(0x010E,0xF8);
+	    		}
+		    } else if (temp1==0) {
+	    		        SiS_SetCHTVRegANDOR(0x010E,0xF8);
+	    	    }
+	    	}
+
+		if (ivideo.disp_state & DISPTYPE_DISP2) {
+			if (sisfb_crt1off)
+				ivideo.disp_state |= DISPMODE_SINGLE;
+			else
+				ivideo.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
+		} else
+			ivideo.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
+
+		if (ivideo.disp_state & DISPTYPE_LCD) {
+			vgawb(CRTC_ADR, IND_SIS_LCD_PANEL);
+			reg = vgarb(CRTC_DATA);
+			// Eden Chen
+			switch (reg) {
+			   case SIS_LCD_PANEL_800X600:
+				sishw_ext.ulCRT2LCDType = LCD_800x600;
+				break;
+			   case SIS_LCD_PANEL_1024X768:
+				sishw_ext.ulCRT2LCDType = LCD_1024x768;
+				break;
+			   case SIS_LCD_PANEL_1280X1024:
+				sishw_ext.ulCRT2LCDType = LCD_1280x1024;
+				break;
+			   case SIS_LCD_PANEL_640X480:
+				sishw_ext.ulCRT2LCDType = LCD_640x480;
+				break;
+			   case SIS_LCD_PANEL_1280X960:
+				sishw_ext.ulCRT2LCDType = LCD_1280x960;
+				break;
+			   case SIS_LCD_PANEL_1600x1200: /* TW */
+				sishw_ext.ulCRT2LCDType = LCD_1600x1200;
+				break;
+			   case SIS_LCD_PANEL_320x480:   /* TW: FSTN */
+				sishw_ext.ulCRT2LCDType = LCD_320x480;
+				break;
+			   default:
+				sishw_ext.ulCRT2LCDType = LCD_1024x768;
+				break;
+			}
+			// ~Eden Chen
 		}
-	}
-	
-	sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
-	
-	if (ivideo.refresh_rate != 0)
-		sisfb_search_refresh_rate (ivideo.refresh_rate);
 
-	if (sisfb_rate_idx == 0) {
-		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
-		ivideo.refresh_rate = 60;
-	}
+		if (sisfb_mode_idx >= 0)
+			sisfb_validate_mode();
 
-	ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
-	ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
-	ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
-	ivideo.org_x = ivideo.org_y = 0;
-	video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
-
-	printk (KERN_INFO "sisfb: mode is %dx%dx%d, linelength=%d\n",
-		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
-		video_linelength);
+		if (sisfb_mode_idx < 0) {
+			switch (ivideo.disp_state & DISPTYPE_DISP2) {
+			   case DISPTYPE_LCD:
+				sisfb_mode_idx = DEFAULT_LCDMODE;
+				break;
+			   case DISPTYPE_TV:
+				sisfb_mode_idx = DEFAULT_TVMODE;
+				break;
+			   default:
+				sisfb_mode_idx = DEFAULT_MODE;
+				break;
+			}
+		}
 
-	// Eden Chen
-	// Check interface correction  For Debug
-	DPRINTK ("VM Adr=0x%p\n", sishw_ext.pjVideoMemoryAddress);
-	DPRINTK ("VM Size=%ldK\n", sishw_ext.ulVideoMemorySize / 1024);
-	DPRINTK ("IO Adr=0x%lx\n", sishw_ext.ulIOAddress);
-	DPRINTK ("Chip=%d\n", sishw_ext.jChipType);
-	DPRINTK ("ChipRevision=%d\n", sishw_ext.jChipRevision);
-	DPRINTK ("VBChip=%d\n", sishw_ext.ujVBChipID);
-	DPRINTK ("ExtVB=%d\n", sishw_ext.usExternalChip);
-	DPRINTK ("LCD=%ld\n", sishw_ext.ulCRT2LCDType);
-	DPRINTK ("bIntegratedMMEnabled=%d\n", sishw_ext.bIntegratedMMEnabled);
-	// ~Eden Chen
+		sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
 
-	sisfb_pre_setmode ();
+		if (ivideo.refresh_rate != 0)
+			sisfb_search_refresh_rate(ivideo.refresh_rate);
 
-	if (SiSSetMode (&sishw_ext, sisfb_mode_no) == 0) {
-		DPRINTK ("set mode[0x%x]: failed\n", sisfb_mode_no);
-		return -1;
-	}
-	vgawb (SEQ_ADR, IND_SIS_PASSWORD);
-	vgawb (SEQ_DATA, SIS_PASSWORD);
-	// Eden Chen
+		if (sisfb_rate_idx == 0) {
+			sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
+			ivideo.refresh_rate = 60;
+		}
 
-	sisfb_post_setmode ();
+		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
+		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
+		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
+		ivideo.org_x = ivideo.org_y = 0;
+		video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
 
-	sisfb_crtc_to_var (&default_var);
+		printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz), linelength=%d\n",
+	       		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
+			ivideo.refresh_rate, video_linelength);
 
-	fb_info.changevar = NULL;
-	fb_info.node = -1;
-	fb_info.fbops = &sisfb_ops;
-	fb_info.disp = &disp;
-	fb_info.switch_con = &sisfb_switch;
-	fb_info.updatevar = &sisfb_update_var;
-	fb_info.blank = &sisfb_blank;
-	fb_info.flags = FBINFO_FLAG_DEFAULT;
+		// Eden Chen
+		// Check interface correction  For Debug
+		DPRINTK("VM Adr=0x%p\n", sishw_ext.pjVideoMemoryAddress);
+		DPRINTK("VM Size=%ldK\n", sishw_ext.ulVideoMemorySize/1024);
+		DPRINTK("IO Adr=0x%lx\n", sishw_ext.ulIOAddress);
+		DPRINTK("Chip=%d\n", sishw_ext.jChipType);
+		DPRINTK("ChipRevision=%d\n", sishw_ext.jChipRevision);
+		DPRINTK("VBChip=%d\n", sishw_ext.ujVBChipID);
+		DPRINTK("ExtVB=%d\n", sishw_ext.usExternalChip);
+		DPRINTK("LCD=%ld\n", sishw_ext.ulCRT2LCDType);
+		DPRINTK("bIntegratedMMEnabled=%d\n", sishw_ext.bIntegratedMMEnabled);
+		// ~Eden Chen
 
-	sisfb_set_disp (-1, &default_var);
+		sisfb_pre_setmode();
 
-	if (sisfb_heap_init ()) {
-		DPRINTK ("sisfb: Failed to enable offscreen heap\n");
-	}
-	
-	/*H.C. */
-	nRes = 	mtrr_add ((unsigned int) ivideo.video_base, (unsigned int) ivideo.video_size,  MTRR_TYPE_WRCOMB, 1);
-	vc_resize_con (1, 1, 0);
+		if (SiSSetMode(&sishw_ext, sisfb_mode_no) == 0) {
+			DPRINTK("set mode[0x%x]: failed\n", sisfb_mode_no);
+			return -1;
+		}
 
-	if (register_framebuffer (&fb_info) < 0)
-		return -EINVAL;
+		vgawb(SEQ_ADR, IND_SIS_PASSWORD);
+		vgawb(SEQ_DATA, SIS_PASSWORD);
 
-	printk (KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-		GET_FB_IDX (fb_info.node), fb_info.modename, VER_MAJOR, VER_MINOR,
-		VER_LEVEL);
+		sisfb_post_setmode();
 
+		sisfb_crtc_to_var(&default_var);
+
+		fb_info.changevar = NULL;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+		fb_info.node = -1;
+#else
+		fb_info.node = NODEV;
+#endif
+		fb_info.fbops = &sisfb_ops;
+		fb_info.disp = &disp;
+		fb_info.switch_con = &sisfb_switch;
+		fb_info.updatevar = &sisfb_update_var;
+		fb_info.blank = &sisfb_blank;
+		fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+		sisfb_set_disp(-1, &default_var);
+
+	} /* TW: if mode = "none" */
+
+	if (sisfb_heap_init()) {
+		printk("sisfb: Failed to initialize offscreen memory heap\n");
+	}
+
+        ivideo.mtrr = (unsigned int) 0;
+	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+         	/*H.C.*/
+		ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
+				(unsigned int) ivideo.video_size,
+				MTRR_TYPE_WRCOMB, 1);
+      		/*
+			if (ivideo.mtrr >= 0) {
+           		printk(KERN_INFO "Succeed to turn on Write-Combining on VideoMemory %08XH, Size: %08XH\n",
+					ivideo.video_base, ivideo.video_size);
+      			} else	{
+           		printk(KERN_INFO "Fail to turn on Write-Combining on Video Memory 0x%08X, Size: 0x%08X\n",
+					ivideo.video_base, ivideo.video_size);
+      			}
+        	*/
+		vc_resize_con(1, 1, 0);
+
+		if (register_framebuffer(&fb_info) < 0)
+			return -EINVAL;
+
+		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
+	       		GET_FB_IDX(fb_info.node), fb_info.modename, VER_MAJOR, VER_MINOR,
+	       		VER_LEVEL);
+
+	}	/* TW: if mode = "none" */
 	return 0;
 }
 
@@ -2798,38 +3302,131 @@
 
 static char *mode = NULL;
 static unsigned int rate = 0;
-static unsigned int crt1 = 1;
-
-MODULE_PARM (mode, "s");
-MODULE_PARM (rate, "i");
-MODULE_PARM (crt1, "i");
-MODULE_PARM (filter, "i");
+static unsigned int crt1off = 1;
+static unsigned int mem = 0;
+static unsigned int dstn = 0;
+static char *forcecrt2type = NULL;
+static int forcecrt1 = -1;
+static char *queuemode = NULL;
+
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740 framebuffer driver");
+MODULE_LICENSE("GPL");    /* TW (Code is officially open says SiS) */
+MODULE_AUTHOR("Various; SiS; Some parts by Thomas Winischhofer <thomas@winischhofer.net>");
+
+MODULE_PARM(mode, "s");
+MODULE_PARM_DESC(mode,
+       "Selects the desired display mode in the format [X]x[Y]x[Depth], eg. 800x600x16 "
+       "(default: none; this leaves the console untouched and the driver will only do "
+       "the video memory management for eg. DRM/DRI)");
+
+MODULE_PARM(rate, "i");
+MODULE_PARM_DESC(rate,
+	"Selects the desired vertical refresh rate for CRT1 (external VGA) in Hz. "
+	"(default: 60)");
+
+MODULE_PARM(crt1off,   "i");
+MODULE_PARM_DESC(crt1off,
+	"If this option is set, the driver will switch off CRT1 (external VGA). "
+	"(Deprecated, please use forcecrt1)");
+
+MODULE_PARM(filter, "i");
+MODULE_PARM_DESC(filter,
+	"Selects TV flicker filter type (only for SiS30x video bridges). "
+	"(Possible values 0-7, default: [no filter])");
+
+MODULE_PARM(dstn,   "i"); /* JennyLee 20011211 */
+MODULE_PARM_DESC(dstn,
+	"Selects DSTN display mode (1=ON, 0=OFF) (default: 0)");
+
+MODULE_PARM(queuemode,   "s");
+MODULE_PARM_DESC(queuemode,
+	"Selects the queue mode on 315/550/650/740. Possible choices are AGP, VRAM "
+	"or MMIO. AGP is only available if the kernel has AGP support. "
+	"The queue mode is important to programs using the 2D/3D accelerator of "
+	"the SiS chip. The modes require a totally different way of programming "
+	"the engines. On 300/540/630/730, this option is ignored. (default: MMIO)");
+
+/* TW: "Import" the options from the X driver */
+MODULE_PARM(mem,    "i");
+MODULE_PARM_DESC(mem,
+	"Determines the beginning of the video memory heap in KB. This heap is used for "
+	"video RAM management for eg. DRM/DRI. The default depends on the amount of video "
+	"memory available. If 8MB of video RAM or less is available, "
+	"the heap starts at 4096KB, otherwise at 8192KB. The value is to be specified "
+	"without 'KB' and should match MaxXFBMem setting for XFree 4.x (x>=2). "
+	"See http://www.winischhofer.net/linuxsis630.shtml for a closer description.");
+
+MODULE_PARM(forcecrt2type, "s");
+MODULE_PARM_DESC(forcecrt2type,
+	"If this option is omitted, the driver autodetects CRT2 output devices, such as LCD, "
+	"TV or secondary VGA (in this order; so if eg. an LCD is there, it will be used regardless "
+	"of a connected TV set). With this option, this autodetection can be overridden. "
+	"Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2 and makes it "
+	"possible to use higher resolutions on CRT1 than eg. your LCD panel supports. TV "
+	"selects TV output (only resolutions 640x480 and 800x600 are supported for TV!). "
+	"VGA refers to _secondary_ VGA which is unlikely to be available; the VGA plug found "
+	"on most machines is CRT1. (default: [autodetected])");
+
+MODULE_PARM(forcecrt1, "i");
+MODULE_PARM_DESC(forcecrt1,
+	"Normally, the driver autodetects whether or not CRT1 (external VGA) is connected. "
+	"With this option, the detection can be overridden (1=CRT1 ON, 0=CRT1 off) "
+	"(default: [autodetected])");
 
-int init_module (void)
+int init_module(void)
 {
 	if (mode)
-		sisfb_search_mode (mode);
+		sisfb_search_mode(mode);
+	else  /* TW: set mode=none if no mode parameter is given */
+		sisfb_mode_idx = MODE_INDEX_NONE;
 
 	ivideo.refresh_rate = rate;
 
-	if (crt1 == 0)
+	if (forcecrt2type)
+		sisfb_search_crt2type(forcecrt2type);
+
+	if (crt1off == 0)
 		sisfb_crt1off = 1;
 	else
 		sisfb_crt1off = 0;
 
-	sisfb_init ();
+	sisfb_forcecrt1 = forcecrt1;
+	if (forcecrt1 == 1)
+		sisfb_crt1off = 0;
+	else if (forcecrt1 == 0)
+		sisfb_crt1off = 1;
+
+	if (mem)
+		sisfb_mem = mem;
+
+	enable_dstn = dstn; /* JennyLee 20011211 */
+
+	if (queuemode)
+		sisfb_search_queuemode(queuemode);
+
+	sisfb_init();
 
 	return 0;
 }
 
-void cleanup_module (void)
+void cleanup_module(void)
 {
-	unregister_framebuffer (&fb_info);
+	/* TW: Release mem regions */
+	release_mem_region(ivideo.video_base, ivideo.video_size);
+	release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+	/* TW: Release MTRR region */
+	if (ivideo.mtrr) mtrr_del(ivideo.mtrr, 
+			      (unsigned int)ivideo.video_base,
+	                      (unsigned int)ivideo.video_size);
+	/* Unregister the framebuffer */
+	unregister_framebuffer(&fb_info);
+	printk(KERN_INFO "sisfb: Module unloaded\n");
 }
 #endif
 
-EXPORT_SYMBOL (sis_malloc);
-EXPORT_SYMBOL (sis_free);
-EXPORT_SYMBOL (sis_dispinfo);
+EXPORT_SYMBOL(sis_malloc);
+EXPORT_SYMBOL(sis_free);
+EXPORT_SYMBOL(sis_dispinfo);
 
-EXPORT_SYMBOL (ivideo);
+EXPORT_SYMBOL(ivideo);
+                                                                                           
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/sis_main.h linux/drivers/video/sis/sis_main.h
--- linux.orig/drivers/video/sis/sis_main.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/sis_main.h	2002-07-20 01:08:29.000000000 +0000
@@ -1,18 +1,30 @@
 #ifndef _SISFB_MAIN
 #define _SISFB_MAIN
 
+/* Comments and changes marked with "TW" by Thomas Winischhofer <tw@webit.com> */
+
 /* ------------------- Constant Definitions ------------------------- */
 
-#undef LINUXBIOS		/* turn on when use LINUXBIOS */
-#define AGPOFF			/* default is turn off AGP */
+#undef LINUXBIOS   /* turn on when use LINUXBIOS */
+#define AGPOFF     /* default is turn off AGP */
 
 #define VER_MAJOR                 1
 #define VER_MINOR                 3
-#define VER_LEVEL                 9
+#define VER_LEVEL                 13 
+
+/* TW: To be included in pci_ids.h */
+#ifndef PCI_DEVICE_ID_SI_650_VGA
+#define PCI_DEVICE_ID_SI_650_VGA  0x6325
+#endif
+#ifndef PCI_DEVICE_ID_SI_650
+#define PCI_DEVICE_ID_SI_650      0x0650
+#endif
+/* TW end */
 
-#define DEFAULT_MODE              0
-#define DEFAULT_LCDMODE           9
-#define DEFAULT_TVMODE            9
+#define DEFAULT_MODE              3
+#define DEFAULT_LCDMODE           12
+#define DEFAULT_TVMODE            12
+#define MODE_INDEX_NONE           0 /* TW: index for mode=none */
 
 #define MAX_ROM_SCAN              0x10000
 
@@ -23,17 +35,19 @@
 
 /* For 300 series */
 #ifdef CONFIG_FB_SIS_300
-#define TURBO_QUEUE_AREA_SIZE     0x80000	/* 512K */
-#define HW_CURSOR_AREA_SIZE       0x1000	/* 4K */
+#define TURBO_QUEUE_AREA_SIZE     0x80000 /* 512K */
 #endif
 
 /* For 315 series */
 #ifdef CONFIG_FB_SIS_315
-#define COMMAND_QUEUE_AREA_SIZE   0x80000	/* 512K */
-#define HW_CURSOR_AREA_SIZE       0x4000	/* 16K */
+#define COMMAND_QUEUE_AREA_SIZE   0x80000 /* 512K */
 #define COMMAND_QUEUE_THRESHOLD   0x1F
 #endif
 
+/* TW */
+#define HW_CURSOR_AREA_SIZE_315   0x4000  /* 16K */
+#define HW_CURSOR_AREA_SIZE_300   0x1000  /* 4K */
+
 #define OH_ALLOC_SIZE             4000
 #define SENTINEL                  0x7fffffff
 
@@ -54,7 +68,7 @@
 #define VB_PART4_ADR              (0x14-0x30)
 #define VB_PART4_DATA             (0x15-0x30)
 
-#define IND_SIS_PASSWORD          0x05	/* SRs */
+#define IND_SIS_PASSWORD          0x05  /* SRs */
 #define IND_SIS_COLOR_MODE        0x06
 #define IND_SIS_RAMDAC_CONTROL    0x07
 #define IND_SIS_DRAM_SIZE         0x14
@@ -70,7 +84,7 @@
 #define IND_SIS_CMDQUEUE_SET      0x26
 #define IND_SIS_CMDQUEUE_THRESHOLD  0x27
 
-#define IND_SIS_SCRATCH_REG_CR30  0x30	/* CRs */
+#define IND_SIS_SCRATCH_REG_CR30  0x30  /* CRs */
 #define IND_SIS_SCRATCH_REG_CR31  0x31
 #define IND_SIS_SCRATCH_REG_CR32  0x32
 #define IND_SIS_SCRATCH_REG_CR33  0x33
@@ -78,28 +92,24 @@
 #define IND_SIS_SCRATCH_REG_CR37  0x37
 #define IND_SIS_AGP_IO_PAD        0x48
 
-#define IND_BRI_DRAM_STATUS       0x63
+#define IND_BRI_DRAM_STATUS       0x63 /* PCI memory size offset */
 
 #define MMIO_QUEUE_PHYBASE        0x85C0
 #define MMIO_QUEUE_WRITEPORT      0x85C4
 #define MMIO_QUEUE_READPORT       0x85C8
 
-// Eden Chen
-#ifdef CONFIG_FB_SIS_300
-#define IND_SIS_CRT2_WRITE_ENABLE 0x24
-#endif
-#ifdef CONFIG_FB_SIS_315
-#define IND_SIS_CRT2_WRITE_ENABLE 0x2F
-#endif
-// ~Eden Chen
-
-#define SIS_PASSWORD              0x86	/* SR05 */
-#define SIS_INTERLACED_MODE       0x20	/* SR06 */
-#define SIS_8BPP_COLOR_MODE       0x0
-#define SIS_15BPP_COLOR_MODE      0x1
-#define SIS_16BPP_COLOR_MODE      0x2
-#define SIS_32BPP_COLOR_MODE      0x4
-#define SIS_DRAM_SIZE_MASK        0x3F	/* SR14 */
+/* Eden Chen; TW */
+#define IND_SIS_CRT2_WRITE_ENABLE_300 0x24
+#define IND_SIS_CRT2_WRITE_ENABLE_315 0x2F
+/* ~Eden Chen; TW */
+
+#define SIS_PASSWORD              0x86  /* SR05 */
+#define SIS_INTERLACED_MODE       0x20  /* SR06 */
+#define SIS_8BPP_COLOR_MODE       0x0 
+#define SIS_15BPP_COLOR_MODE      0x1 
+#define SIS_16BPP_COLOR_MODE      0x2 
+#define SIS_32BPP_COLOR_MODE      0x4 
+#define SIS_DRAM_SIZE_MASK        0x3F  /* SR14 */
 #define SIS_DRAM_SIZE_1MB         0x00
 #define SIS_DRAM_SIZE_2MB         0x01
 #define SIS_DRAM_SIZE_4MB         0x03
@@ -111,7 +121,8 @@
 #define SIS_DATA_BUS_32           0x00
 #define SIS_DATA_BUS_64           0x01
 #define SIS_DATA_BUS_128          0x02
-#define SIS315_DRAM_SIZE_MASK     0xF0	/* 315 SR14 */
+
+#define SIS315_DRAM_SIZE_MASK     0xF0  /* 315/640?/740? SR14 */
 #define SIS315_DRAM_SIZE_2MB      0x01
 #define SIS315_DRAM_SIZE_4MB      0x02
 #define SIS315_DRAM_SIZE_8MB      0x03
@@ -123,10 +134,12 @@
 #define SIS315_DATA_BUS_64        0x00
 #define SIS315_DATA_BUS_128       0x01
 #define SIS315_DUAL_CHANNEL_MASK  0x0C
-#define SIS315_SINGLE_CHANNEL_1_RANK  0x0
-#define SIS315_SINGLE_CHANNEL_2_RANK  0x1
-#define SIS315_DUAL_CHANNEL_1_RANK    0x3
-#define SIS550_DRAM_SIZE_MASK     0x3F	/* 550 SR14 */
+#define SIS315_SINGLE_CHANNEL_1_RANK  	0x0
+#define SIS315_SINGLE_CHANNEL_2_RANK  	0x1
+#define SIS315_ASYM_DDR		  	0x02
+#define SIS315_DUAL_CHANNEL_1_RANK    	0x3
+
+#define SIS550_DRAM_SIZE_MASK     0x3F  /* 550/650 SR14 */
 #define SIS550_DRAM_SIZE_4MB      0x00
 #define SIS550_DRAM_SIZE_8MB      0x01
 #define SIS550_DRAM_SIZE_16MB     0x03
@@ -138,10 +151,13 @@
 #define SIS550_DRAM_SIZE_256MB    0x3F
 
 #define SIS_SCRATCH_REG_1A_MASK   0x10
-#define SIS_ENABLE_2D             0x40	/* SR1E */
-#define SIS_MEM_MAP_IO_ENABLE     0x01	/* SR20 */
+
+#define SIS_ENABLE_2D             0x40  /* SR1E */
+
+#define SIS_MEM_MAP_IO_ENABLE     0x01  /* SR20 */
 #define SIS_PCI_ADDR_ENABLE       0x80
-#define SIS_AGP_CMDQUEUE_ENABLE   0x80	/* 315 SR26 */
+
+#define SIS_AGP_CMDQUEUE_ENABLE   0x80  /* 315 SR26 */
 #define SIS_VRAM_CMDQUEUE_ENABLE  0x40
 #define SIS_MMIO_CMD_ENABLE       0x20
 #define SIS_CMD_QUEUE_SIZE_512k   0x00
@@ -149,7 +165,9 @@
 #define SIS_CMD_QUEUE_SIZE_2M     0x08
 #define SIS_CMD_QUEUE_SIZE_4M     0x0C
 #define SIS_CMD_QUEUE_RESET       0x01
-#define SIS_SIMULTANEOUS_VIEW_ENABLE  0x01	/* CR30 */
+#define SIS_CMD_AUTO_CORR	  0x02
+
+#define SIS_SIMULTANEOUS_VIEW_ENABLE  0x01  /* CR30 */
 #define SIS_MODE_SELECT_CRT2      0x02
 #define SIS_VB_OUTPUT_COMPOSITE   0x04
 #define SIS_VB_OUTPUT_SVIDEO      0x08
@@ -157,9 +175,9 @@
 #define SIS_VB_OUTPUT_LCD         0x20
 #define SIS_VB_OUTPUT_CRT2        0x40
 #define SIS_VB_OUTPUT_HIVISION    0x80
-#define SIS_VB_OUTPUT_DISABLE     0x20	/* CR31 */
+#define SIS_VB_OUTPUT_DISABLE     0x20  /* CR31 */
 #define SIS_DRIVER_MODE           0x40
-#define SIS_VB_COMPOSITE          0x01	/* CR32 */
+#define SIS_VB_COMPOSITE          0x01  /* CR32 */
 #define SIS_VB_SVIDEO             0x02
 #define SIS_VB_SCART              0x04
 #define SIS_VB_LCD                0x08
@@ -168,20 +186,22 @@
 #define SIS_VB_HIVISION           0x40
 #define SIS_VB_DVI                0x80
 #define SIS_VB_TV                 (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | SIS_VB_SCART | SIS_VB_HIVISION)
-#define SIS_LCD_PANEL_800X600     0x1	/* CR36 */
+#define SIS_LCD_PANEL_800X600     0x1   /* CR36 */
 #define SIS_LCD_PANEL_1024X768    0x2
 #define SIS_LCD_PANEL_1280X1024   0x3
 #define SIS_LCD_PANEL_1280X960    0x4
 #define SIS_LCD_PANEL_640X480     0x5
-#define SIS_EXTERNAL_CHIP_MASK    0x0E	/* CR37 */
+#define SIS_LCD_PANEL_1600x1200   0x6  /* TW */
+#define SIS_LCD_PANEL_320x480	  0x7  /* TW: FSTN */
+#define SIS_EXTERNAL_CHIP_MASK    0x0E  /* CR37 */
 #define SIS_EXTERNAL_CHIP_SIS301        0x01
-#define SIS_EXTERNAL_CHIP_LVDS          0x02
+#define SIS_EXTERNAL_CHIP_LVDS          0x02  
 #define SIS_EXTERNAL_CHIP_TRUMPION      0x03
 #define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
 #define SIS_EXTERNAL_CHIP_CHRONTEL      0x05
-#define SIS_AGP_2X                0x20	/* CR48 */
+#define SIS_AGP_2X                0x20  /* CR48 */
 
-#define BRI_DRAM_SIZE_MASK        0x70	/* PCI bridge */
+#define BRI_DRAM_SIZE_MASK        0x70  /* PCI bridge */
 #define BRI_DRAM_SIZE_2MB         0x00
 #define BRI_DRAM_SIZE_4MB         0x01
 #define BRI_DRAM_SIZE_8MB         0x02
@@ -190,13 +210,15 @@
 #define BRI_DRAM_SIZE_64MB        0x05
 
 // Eden Chen
-#define HW_DEVICE_EXTENSION	    SIS_HW_DEVICE_INFO
+#define HW_DEVICE_EXTENSION	  SIS_HW_DEVICE_INFO
 #define PHW_DEVICE_EXTENSION      PSIS_HW_DEVICE_INFO
 
 #define SR_BUFFER_SIZE            5
 #define CR_BUFFER_SIZE            5
 // ~Eden Chen
 
+int enable_dstn = 0;
+
 /* ------------------- Global Variables ----------------------------- */
 
 /* Fbcon variables */
@@ -240,6 +262,7 @@
 /* display status */
 static int sisfb_off = 0;
 static int sisfb_crt1off = 0;
+static int sisfb_forcecrt1 = -1;
 static int sisfb_inverse = 0;
 static int sisvga_enabled = 0;
 static int currcon = 0;
@@ -253,10 +276,18 @@
 	SIS_315_VGA,
 } sisvga_engine = UNKNOWN_VGA;
 
+/* TW: These are to adapted to VGA_ENGINE type */
+static int sisfb_hwcursor_size = 0;
+static int sisfb_CRT2_write_enable = 0;
+
 /* mode-related variables */
-int sisfb_mode_idx = -1;
-u8 sisfb_mode_no = 0;
-u8 sisfb_rate_idx = 0;
+int sisfb_mode_idx = MODE_INDEX_NONE;  /* (TW) was -1 */
+u8  sisfb_mode_no = 0;
+u8  sisfb_rate_idx = 0;
+
+int sisfb_crt2type = -1;	/* TW: CRT2 type (for overriding autodetection) */
+
+int sisfb_queuemode = -1; 	/* TW: Use MMIO queue mode by default (310 series only) */
 
 /* data for sis components*/
 struct video_info ivideo;
@@ -285,15 +316,15 @@
 	u16 vendor, device;
 	const char *name;
 } sisdev_list[] = {
-	{
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, "SIS 300"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H, "SIS 315H"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315, "SIS 315"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO, "SIS 315Pro"}, {
-	PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550"}, {
-	0, 0, NULL}
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300,     "SIS 300"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H,    "SIS 315H"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315,     "SIS 315"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO,  "SIS 315Pro"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650 VGA"},
+	{0, 0, NULL}
 };
 
 /* mode table */
@@ -307,32 +338,75 @@
 	u16 cols;
 	u16 rows;
 } sisbios_mode[] = {
-	{
-	"640x480x8", 0x2E, 640, 480, 8, 1, 80, 30}, {
-	"640x480x16", 0x44, 640, 480, 16, 1, 80, 30}, {
-	"640x480x32", 0x62, 640, 480, 32, 1, 80, 30}, {
-	"720x480x8", 0x31, 720, 480, 8, 1, 90, 30}, {
-	"720x480x16", 0x33, 720, 480, 16, 1, 90, 30}, {
-	"720x480x32", 0x35, 720, 480, 32, 1, 90, 30}, {
-	"720x576x8", 0x32, 720, 576, 8, 1, 90, 36}, {
-	"720x576x16", 0x34, 720, 576, 16, 1, 90, 36}, {
-	"720x576x32", 0x36, 720, 576, 32, 1, 90, 36}, {
-	"800x600x8", 0x30, 800, 600, 8, 2, 100, 37}, {
-	"800x600x16", 0x47, 800, 600, 16, 2, 100, 37}, {
-	"800x600x32", 0x63, 800, 600, 32, 2, 100, 37}, {
-	"1024x768x8", 0x38, 1024, 768, 8, 2, 128, 48}, {
-	"1024x768x16", 0x4A, 1024, 768, 16, 2, 128, 48}, {
-	"1024x768x32", 0x64, 1024, 768, 32, 2, 128, 48}, {
-	"1280x1024x8", 0x3A, 1280, 1024, 8, 2, 160, 64}, {
-	"1280x1024x16", 0x4D, 1280, 1024, 16, 2, 160, 64}, {
-	"1280x1024x32", 0x65, 1280, 1024, 32, 2, 160, 64}, {
-	"1600x1200x8", 0x3C, 1600, 1200, 8, 1, 200, 75}, {
-	"1600x1200x16", 0x3D, 1600, 1200, 16, 1, 200, 75}, {
-	"1600x1200x32", 0x66, 1600, 1200, 32, 1, 200, 75}, {
-	"1920x1440x8", 0x68, 1920, 1440, 8, 1, 240, 75}, {
-	"1920x1440x16", 0x69, 1920, 1440, 16, 1, 240, 75}, {
-	"1920x1440x32", 0x6B, 1920, 1440, 32, 1, 240, 75}, {
-	"\0", 0x00, 0, 0, 0, 0, 0, 0}
+	{"none", 0xFF, 0, 0, 0, 0, 0, 0}, 		    /* TW: for mode "none" */
+	{"320x240x16",   0x56,  320,  240, 16, 1,  40, 15},
+	{"320x480x8",    0x5A,  320,  480,  8, 1,  40, 30},
+	{"320x480x16",   0x5B,  320,  480, 16, 1,  40, 30},
+	{"640x480x8",    0x2E,  640,  480,  8, 1,  80, 30},
+	{"640x480x16",   0x44,  640,  480, 16, 1,  80, 30},
+	{"640x480x24",   0x62,  640,  480, 32, 1,  80, 30}, /* TW: That's for people who mix up color- and fb depth */
+	{"640x480x32",   0x62,  640,  480, 32, 1,  80, 30},
+	{"720x480x8",    0x31,  720,  480,  8, 1,  90, 30},
+	{"720x480x16",   0x33,  720,  480, 16, 1,  90, 30},
+	{"720x480x24",   0x35,  720,  480, 32, 1,  90, 30}, /* TW */
+	{"720x480x32",   0x35,  720,  480, 32, 1,  90, 30},
+	{"720x576x8",    0x32,  720,  576,  8, 1,  90, 36},
+	{"720x576x16",   0x34,  720,  576, 16, 1,  90, 36},
+	{"720x576x24",   0x36,  720,  576, 32, 1,  90, 36}, /* TW */
+	{"720x576x32",   0x36,  720,  576, 32, 1,  90, 36},
+	{"800x600x8",    0x30,  800,  600,  8, 2, 100, 37},
+	{"800x600x16",   0x47,  800,  600, 16, 2, 100, 37},
+	{"800x600x24",   0x63,  800,  600, 32, 2, 100, 37}, /* TW */
+	{"800x600x32",   0x63,  800,  600, 32, 2, 100, 37},
+	{"1024x768x8",   0x38, 1024,  768,  8, 2, 128, 48},
+	{"1024x768x16",  0x4A, 1024,  768, 16, 2, 128, 48},
+	{"1024x768x24",  0x64, 1024,  768, 32, 2, 128, 48}, /* TW */
+	{"1024x768x32",  0x64, 1024,  768, 32, 2, 128, 48},
+	{"1280x960x8",   0x7C, 1280,  960,  8, 1, 160, 60}, /* TW */
+	{"1280x960x16",  0x7D, 1280,  960, 16, 1, 160, 60}, /* TW */
+	{"1280x960x24",  0x7E, 1280,  960, 32, 1, 160, 60}, /* TW */
+	{"1280x960x32",  0x7E, 1280,  960, 32, 1, 160, 60}, /* TW */
+	{"1280x1024x8",  0x3A, 1280, 1024,  8, 2, 160, 64},
+	{"1280x1024x16", 0x4D, 1280, 1024, 16, 2, 160, 64},
+	{"1280x1024x24", 0x65, 1280, 1024, 32, 2, 160, 64}, /* TW */
+	{"1280x1024x32", 0x65, 1280, 1024, 32, 2, 160, 64},
+	{"1600x1200x8",  0x3C, 1600, 1200,  8, 1, 200, 75},
+	{"1600x1200x16", 0x3D, 1600, 1200, 16, 1, 200, 75},
+	{"1600x1200x24", 0x66, 1600, 1200, 32, 1, 200, 75}, /* TW */
+	{"1600x1200x32", 0x66, 1600, 1200, 32, 1, 200, 75},
+	{"1920x1440x8",  0x68, 1920, 1440,  8, 1, 240, 75},
+	{"1920x1440x16", 0x69, 1920, 1440, 16, 1, 240, 75},
+	{"1920x1440x24", 0x6B, 1920, 1440, 32, 1, 240, 75}, /* TW */
+	{"1920x1440x32", 0x6B, 1920, 1440, 32, 1, 240, 75},
+	{"\0", 0x00, 0, 0, 0, 0, 0, 0}
+};
+
+static const struct _sis_crt2type {
+	char name[6];
+	int type_no;
+} sis_crt2type[] = {
+	{"NONE", 0},
+	{"LCD",  DISPTYPE_LCD},
+	{"TV",   DISPTYPE_TV},
+	{"VGA",  DISPTYPE_CRT2},
+	{"none", 0},	/* TW: make it fool-proof */
+	{"lcd",  DISPTYPE_LCD},
+	{"tv",   DISPTYPE_TV},
+	{"vga",  DISPTYPE_CRT2},
+	{"\0",  -1}
+};
+
+static const struct _sis_queuemode {
+	char name[6];
+	int type_no;
+} sis_queuemode[] = {
+	{"AGP",  AGP_CMD_QUEUE},
+	{"VRAM", VM_CMD_QUEUE},
+	{"MMIO", MMIO_CMD},
+	{"agp",  AGP_CMD_QUEUE},
+	{"vram", VM_CMD_QUEUE},
+	{"mmio", MMIO_CMD},
+	{"\0",  -1}
 };
 
 static struct _sis_vrate {
@@ -341,43 +415,21 @@
 	u16 yres;
 	u16 refresh;
 } sisfb_vrate[] = {
-	{
-	1, 640, 480, 60}, {
-	2, 640, 480, 72}, {
-	3, 640, 480, 75}, {
-	4, 640, 480, 85}, {
-	5, 640, 480, 100}, {
-	6, 640, 480, 120}, {
-	7, 640, 480, 160}, {
-	8, 640, 480, 200}, {
-	1, 720, 480, 60}, {
-	1, 720, 576, 50}, {
-	1, 800, 600, 56}, {
-	2, 800, 600, 60}, {
-	3, 800, 600, 72}, {
-	4, 800, 600, 75}, {
-	5, 800, 600, 85}, {
-	6, 800, 600, 100}, {
-	7, 800, 600, 120}, {
-	8, 800, 600, 160}, {
-	1, 1024, 768, 43}, {
-	2, 1024, 768, 60}, {
-	3, 1024, 768, 70}, {
-	4, 1024, 768, 75}, {
-	5, 1024, 768, 85}, {
-	6, 1024, 768, 100}, {
-	7, 1024, 768, 120}, {
-	1, 1280, 1024, 43}, {
-	2, 1280, 1024, 60}, {
-	3, 1280, 1024, 75}, {
-	4, 1280, 1024, 85}, {
-	1, 1600, 1200, 60}, {
-	2, 1600, 1200, 65}, {
-	3, 1600, 1200, 70}, {
-	4, 1600, 1200, 75}, {
-	5, 1600, 1200, 85}, {
-	1, 1920, 1440, 60}, {
-	0, 0, 0, 0}
+	{1,  640,  480,  60}, {2,  640, 480,  72}, {3,  640, 480,  75}, {4,  640, 480,  85},
+	{5,  640,  480, 100}, {6,  640, 480, 120}, {7,  640, 480, 160}, {8,  640, 480, 200},
+	{1,  720,  480,  60},
+	{1,  720,  576,  50},
+	{1,  800,  600,  56}, {2,  800, 600,  60}, {3,  800, 600,  72}, {4,  800, 600,  75},
+	{5,  800,  600,  85}, {6,  800, 600, 100}, {7,  800, 600, 120}, {8,  800, 600, 160},
+	{1, 1024,  768,  43}, {2, 1024, 768,  60}, {3, 1024, 768,  70}, {4, 1024, 768,  75},
+	{5, 1024,  768,  85}, {6, 1024, 768, 100}, {7, 1024, 768, 120},
+	{1, 1280, 1024,  43}, {2, 1280, 1024, 60}, {3, 1280, 1024, 75}, {4, 1280, 1024, 85},
+	/* TW: Values for 1280x960 guessed */
+	{1, 1280,  960,  43},  /* {1, 1280,  960, 60}, */
+	{1, 1600, 1200,  60}, {2, 1600, 1200, 65}, {3, 1600, 1200, 70}, {4, 1600, 1200, 75},
+	{5, 1600, 1200,  85},
+	{1, 1920, 1440,  60},
+	{0, 0, 0, 0}
 };
 
 /* Offscreen layout */
@@ -420,167 +472,150 @@
 static struct _sis_TV_filter {
 	u8 filter[9][4];
 } sis_TV_filter[] = {
-	{ { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_0 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_1 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_2 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xEB, 0x04, 0x25, 0x18}, {
-	0xF1, 0x05, 0x1F, 0x16}, {
-	0xF6, 0x06, 0x1A, 0x14}, {
-	0xFA, 0x06, 0x16, 0x14}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_3 */
-	{
-	0xF1, 0x04, 0x1F, 0x18}, {
-	0xEE, 0x0D, 0x22, 0x06}, {
-	0xF7, 0x06, 0x19, 0x14}, {
-	0xF4, 0x0B, 0x1C, 0x0A}, {
-	0xFA, 0x07, 0x16, 0x12}, {
-	0xF9, 0x0A, 0x17, 0x0C}, {
-	0x00, 0x07, 0x10, 0x12}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_4 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_5 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xEB, 0x04, 0x25, 0x18}, {
-	0xF1, 0x05, 0x1F, 0x16}, {
-	0xF6, 0x06, 0x1A, 0x14}, {
-	0xFA, 0x06, 0x16, 0x14}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_6 */
-	{
-	0xEB, 0x04, 0x25, 0x18}, {
-	0xE7, 0x0E, 0x29, 0x04}, {
-	0xEE, 0x0C, 0x22, 0x08}, {
-	0xF6, 0x0B, 0x1A, 0x0A}, {
-	0xF9, 0x0A, 0x17, 0x0C}, {
-	0xFC, 0x0A, 0x14, 0x0C}, {
-	0x00, 0x08, 0x10, 0x10}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* NTSCFilter_7 */
-	{
-	0xEC, 0x02, 0x24, 0x1C}, {
-	0xF2, 0x04, 0x1E, 0x18}, {
-	0xEB, 0x15, 0x25, 0xF6}, {
-	0xF4, 0x10, 0x1C, 0x00}, {
-	0xF8, 0x0F, 0x18, 0x02}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0x01, 0x06, 0x0F, 0x14}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_0 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_1 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_2 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xF1, 0xF7, 0x01, 0x32}, {
-	0xF5, 0xFB, 0x1B, 0x2A}, {
-	0xF9, 0xFF, 0x17, 0x22}, {
-	0xFB, 0x01, 0x15, 0x1E}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_3 */
-	{
-	0xF5, 0xFB, 0x1B, 0x2A}, {
-	0xEE, 0xFE, 0x22, 0x24}, {
-	0xF3, 0x00, 0x1D, 0x20}, {
-	0xF9, 0x03, 0x17, 0x1A}, {
-	0xFB, 0x02, 0x14, 0x1E}, {
-	0xFB, 0x04, 0x15, 0x18}, {
-	0x00, 0x06, 0x10, 0x14}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_4 */
-	{
-	0x00, 0xE0, 0x10, 0x60}, {
-	0x00, 0xEE, 0x10, 0x44}, {
-	0x00, 0xF4, 0x10, 0x38}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0x00, 0x00, 0x10, 0x20}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_5 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xF1, 0xF7, 0x1F, 0x32}, {
-	0xF5, 0xFB, 0x1B, 0x2A}, {
-	0xF9, 0xFF, 0x17, 0x22}, {
-	0xFB, 0x01, 0x15, 0x1E}, {
-	0x00, 0x04, 0x10, 0x18}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_6 */
-	{
-	0xF5, 0xEE, 0x1B, 0x2A}, {
-	0xEE, 0xFE, 0x22, 0x24}, {
-	0xF3, 0x00, 0x1D, 0x20}, {
-	0xF9, 0x03, 0x17, 0x1A}, {
-	0xFB, 0x02, 0x14, 0x1E}, {
-	0xFB, 0x04, 0x15, 0x18}, {
-	0x00, 0x06, 0x10, 0x14}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}, { { {
-	0x00, 0x00, 0x00, 0x40},	/* PALFilter_7 */
-	{
-	0xF5, 0xEE, 0x1B, 0x44}, {
-	0xF8, 0xF4, 0x18, 0x38}, {
-	0xFC, 0xFB, 0x14, 0x2A}, {
-	0xEB, 0x05, 0x25, 0x16}, {
-	0xF1, 0x05, 0x1F, 0x16}, {
-	0xFA, 0x07, 0x16, 0x12}, {
-	0x00, 0x07, 0x10, 0x12}, {
-	0xFF, 0xFF, 0xFF, 0xFF}}}
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_0 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_1 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_2 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xEB,0x04,0x25,0x18},
+	   {0xF1,0x05,0x1F,0x16},
+	   {0xF6,0x06,0x1A,0x14},
+	   {0xFA,0x06,0x16,0x14},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_3 */
+	   {0xF1,0x04,0x1F,0x18},
+	   {0xEE,0x0D,0x22,0x06},
+	   {0xF7,0x06,0x19,0x14},
+	   {0xF4,0x0B,0x1C,0x0A},
+	   {0xFA,0x07,0x16,0x12},
+	   {0xF9,0x0A,0x17,0x0C},
+	   {0x00,0x07,0x10,0x12}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_4 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_5 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xEB,0x04,0x25,0x18},
+	   {0xF1,0x05,0x1F,0x16},
+	   {0xF6,0x06,0x1A,0x14},
+	   {0xFA,0x06,0x16,0x14},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_6 */
+	   {0xEB,0x04,0x25,0x18},
+	   {0xE7,0x0E,0x29,0x04},
+	   {0xEE,0x0C,0x22,0x08},
+	   {0xF6,0x0B,0x1A,0x0A},
+	   {0xF9,0x0A,0x17,0x0C},
+	   {0xFC,0x0A,0x14,0x0C},
+	   {0x00,0x08,0x10,0x10}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_7 */
+	   {0xEC,0x02,0x24,0x1C},
+	   {0xF2,0x04,0x1E,0x18},
+	   {0xEB,0x15,0x25,0xF6},
+	   {0xF4,0x10,0x1C,0x00},
+	   {0xF8,0x0F,0x18,0x02},
+	   {0x00,0x04,0x10,0x18},
+	   {0x01,0x06,0x0F,0x14}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_0 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_1 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_2 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xF1,0xF7,0x01,0x32},
+	   {0xF5,0xFB,0x1B,0x2A},
+	   {0xF9,0xFF,0x17,0x22},
+	   {0xFB,0x01,0x15,0x1E},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_3 */
+	   {0xF5,0xFB,0x1B,0x2A},
+	   {0xEE,0xFE,0x22,0x24},
+	   {0xF3,0x00,0x1D,0x20},
+	   {0xF9,0x03,0x17,0x1A},
+	   {0xFB,0x02,0x14,0x1E},
+	   {0xFB,0x04,0x15,0x18},
+	   {0x00,0x06,0x10,0x14}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_4 */
+	   {0x00,0xE0,0x10,0x60},
+	   {0x00,0xEE,0x10,0x44},
+	   {0x00,0xF4,0x10,0x38},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0x00,0x00,0x10,0x20},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_5 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xF1,0xF7,0x1F,0x32},
+	   {0xF5,0xFB,0x1B,0x2A},
+	   {0xF9,0xFF,0x17,0x22},
+	   {0xFB,0x01,0x15,0x1E},
+	   {0x00,0x04,0x10,0x18}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_6 */
+	   {0xF5,0xEE,0x1B,0x2A},
+	   {0xEE,0xFE,0x22,0x24},
+	   {0xF3,0x00,0x1D,0x20},
+	   {0xF9,0x03,0x17,0x1A},
+	   {0xFB,0x02,0x14,0x1E},
+	   {0xFB,0x04,0x15,0x18},
+	   {0x00,0x06,0x10,0x14}, 
+	   {0xFF,0xFF,0xFF,0xFF} }},
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_7 */
+	   {0xF5,0xEE,0x1B,0x44},
+	   {0xF8,0xF4,0x18,0x38},
+	   {0xFC,0xFB,0x14,0x2A},
+	   {0xEB,0x05,0x25,0x16},
+	   {0xF1,0x05,0x1F,0x16},
+	   {0xFA,0x07,0x16,0x12},
+	   {0x00,0x07,0x10,0x12}, 
+	   {0xFF,0xFF,0xFF,0xFF} }}
 };
 
 static int filter = -1;
@@ -590,104 +625,108 @@
 /* ---------------------- Routine Prototype ------------------------- */
 
 /* Interface used by the world */
-int sisfb_setup (char *options);
-static int sisfb_get_fix (struct fb_fix_screeninfo *fix, int con,
-			  struct fb_info *info);
-static int sisfb_get_var (struct fb_var_screeninfo *var, int con,
+int sisfb_setup(char *options);
+static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info);
+static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+static int sisfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
 			  struct fb_info *info);
-static int sisfb_set_var (struct fb_var_screeninfo *var, int con,
+static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 			  struct fb_info *info);
-static int sisfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
-			   struct fb_info *info);
-static int sisfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
-			   struct fb_info *info);
-static int sisfb_ioctl (struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg, int con,
-			struct fb_info *info);
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, int con,
+		       struct fb_info *info);
 
 /* Interface to the low level console driver */
-int sisfb_init (void);
-static int sisfb_update_var (int con, struct fb_info *info);
-static int sisfb_switch (int con, struct fb_info *info);
-static void sisfb_blank (int blank, struct fb_info *info);
+int sisfb_init(void);
+static int sisfb_update_var(int con, struct fb_info *info);
+static int sisfb_switch(int con, struct fb_info *info);
+static void sisfb_blank(int blank, struct fb_info *info);
 
 /* hardware access routines */
-void sisfb_set_reg1 (u16 port, u16 index, u16 data);
-void sisfb_set_reg3 (u16 port, u16 data);
-void sisfb_set_reg4 (u16 port, unsigned long data);
-u8 sisfb_get_reg1 (u16 port, u16 index);
-u8 sisfb_get_reg2 (u16 port);
-u32 sisfb_get_reg3 (u16 port);
+void sisfb_set_reg1(u16 port, u16 index, u16 data);
+void sisfb_set_reg3(u16 port, u16 data);
+void sisfb_set_reg4(u16 port, unsigned long data);
+u8   sisfb_get_reg1(u16 port, u16 index);
+u8   sisfb_get_reg2(u16 port);
+u32  sisfb_get_reg3(u16 port);
 // Eden Chen
 //void sisfb_clear_DAC(u16 port);
 //void sisfb_clear_buffer(PHW_DEVICE_EXTENSION psishw_ext);
 // ~Eden Chen
 
 /* Internal routines */
-static void sisfb_search_mode (const char *name);
-static void sisfb_validate_mode (void);
-static u8 sisfb_search_refresh_rate (unsigned int rate);
-static int sis_getcolreg (unsigned regno, unsigned *red, unsigned *green,
-			  unsigned *blue, unsigned *transp,
-			  struct fb_info *fb_info);
-static int sis_setcolreg (unsigned regno, unsigned red, unsigned green,
-			  unsigned blue, unsigned transp,
-			  struct fb_info *fb_info);
-static int sisfb_do_set_var (struct fb_var_screeninfo *var, int isactive,
-			     struct fb_info *info);
-static void sisfb_set_disp (int con, struct fb_var_screeninfo *var);
-static void sisfb_do_install_cmap (int con, struct fb_info *info);
+static void sisfb_search_mode(const char *name);
+static void sisfb_validate_mode(void);
+static u8   sisfb_search_refresh_rate(unsigned int rate);
+static int  sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 struct fb_info *fb_info);
+static int  sis_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 struct fb_info *fb_info);
+static int  sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
+		      struct fb_info *info);
+static void sisfb_set_disp(int con, struct fb_var_screeninfo *var);
+static void sisfb_do_install_cmap(int con, struct fb_info *info);
 
 /* Chip-dependent Routines */
 #ifdef CONFIG_FB_SIS_300
-static int sisfb_get_dram_size_300 (void);
+static int sisfb_get_dram_size_300(void);
 //extern BOOLEAN SiSInit300(PHW_DEVICE_EXTENSION HwDeviceExtension);
-static void sisfb_detect_VB_connect_300 (void);
-static void sisfb_get_VB_type_300 (void);
-static int sisfb_has_VB_300 (void);
+static void sisfb_detect_VB_connect_300(void);
+static void sisfb_get_VB_type_300(void);
+static int sisfb_has_VB_300(void);
 //extern BOOLEAN SiSSetMode(PHW_DEVICE_EXTENSION HwDeviceExtension,USHORT ModeNo);
 #endif
 #ifdef CONFIG_FB_SIS_315
-static int sisfb_get_dram_size_315 (void);
+static int sisfb_get_dram_size_315(void);
 //extern BOOLEAN SiSInit310(PHW_DEVICE_EXTENSION HwDeviceExtension);
-static void sisfb_detect_VB_connect_315 (void);
-static void sisfb_get_VB_type_315 (void);
+static void sisfb_detect_VB_connect_315(void);
+static void sisfb_get_VB_type_315(void);
+static int sisfb_has_VB_315(void);
 //extern BOOLEAN SiSSetMode310(PHW_DEVICE_EXTENSION HwDeviceExtension, USHORT ModeNo);
 #endif
 
 /* SetMode routines */
 
 // Eden Chen
-extern BOOLEAN SiSSetMode (PSIS_HW_DEVICE_INFO HwDeviceExtension,
-			   USHORT ModeNo);
-extern BOOLEAN SiSInit (PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
+extern BOOLEAN SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void SetEnableDstn(void);
 // ~Eden Chen
 
-static void sisfb_pre_setmode (void);
-static void sisfb_post_setmode (void);
-static void sisfb_crtc_to_var (struct fb_var_screeninfo *var);
+extern void 	SiSRegInit(USHORT BaseAddr);
+extern USHORT 	SiS_GetCH7005(USHORT tempbx);
+extern void 	SiS_SetCH7005(USHORT tempbx);
+extern void     SiS_SetCHTVRegANDOR(USHORT tempax,USHORT tempbh);
+
+static void sisfb_pre_setmode(void);
+static void sisfb_post_setmode(void);
+static void sisfb_crtc_to_var(struct fb_var_screeninfo *var);
 
 /* Export functions  */
-static void sis_get_glyph (SIS_GLYINFO * gly);
-void sis_dispinfo (struct ap_data *rec);
-void sis_malloc (struct sis_memreq *req);
-void sis_free (unsigned long base);
+static void sis_get_glyph(SIS_GLYINFO *gly);
+void sis_dispinfo(struct ap_data *rec);
+void sis_malloc(struct sis_memreq *req);
+void sis_free(unsigned long base);
 
 /* heap routines */
-static int sisfb_heap_init (void);
-static SIS_OH *sisfb_poh_new_node (void);
-static SIS_OH *sisfb_poh_allocate (unsigned long size);
-static void sisfb_delete_node (SIS_OH * poh);
-static void sisfb_insert_node (SIS_OH * pohList, SIS_OH * poh);
-static SIS_OH *sisfb_poh_free (unsigned long base);
-static void sisfb_free_node (SIS_OH * poh);
+static int sisfb_heap_init(void);
+static SIS_OH *sisfb_poh_new_node(void);
+static SIS_OH *sisfb_poh_allocate(unsigned long size);
+static void sisfb_delete_node(SIS_OH *poh);
+static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
+static SIS_OH *sisfb_poh_free(unsigned long base);
+static void sisfb_free_node(SIS_OH *poh);
 
 /* routines to access PCI configuration space */
-BOOLEAN sisfb_query_VGA_config_space (PSIS_HW_DEVICE_INFO psishw_ext,
-				      unsigned long offset, unsigned long set,
-				      unsigned long *value);
-BOOLEAN sisfb_query_north_bridge_space (PSIS_HW_DEVICE_INFO psishw_ext,
-					unsigned long offset, unsigned long set,
-					unsigned long *value);
+BOOLEAN sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext, 
+	unsigned long offset, unsigned long set, unsigned long *value);
+BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext, 
+	unsigned long offset, unsigned long set, unsigned long *value);
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/vgatypes.h linux/drivers/video/sis/vgatypes.h
--- linux.orig/drivers/video/sis/vgatypes.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/vgatypes.h	2002-07-20 01:08:21.000000000 +0000
@@ -1,10 +1,12 @@
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
+
 #ifndef TC
 #define far
 #endif
 
+
 #ifndef FALSE
 #define FALSE   0
 #endif
@@ -17,7 +19,7 @@
 #define NULL    0
 #endif
 
-#ifndef CHAR
+#ifndef CHAR 
 typedef char CHAR;
 #endif
 
@@ -26,7 +28,7 @@
 #endif
 
 #ifndef LONG
-typedef long LONG;
+typedef long  LONG;
 #endif
 
 #ifndef UCHAR
@@ -41,6 +43,7 @@
 typedef unsigned long ULONG;
 #endif
 
+
 #ifndef PUCHAR
 typedef UCHAR far *PUCHAR;
 #endif
@@ -68,27 +71,54 @@
 #ifndef bool
 typedef UCHAR bool;
 #endif
-#endif	/* WINCE_HEADER */
+#endif /*WINCE_HEADER*/
 
 #ifndef VBIOS_VER_MAX_LENGTH
 #define VBIOS_VER_MAX_LENGTH         4
 #endif
 
+#ifndef LINUX_KERNEL
+#ifndef WIN2000
+#ifndef SIS_CHIP_TYPE
+typedef enum _SIS_CHIP_TYPE {
+    SIS_VGALegacy = 0,
+#ifdef LINUX_XF86
+    SIS_530,	/* TW */
+    SIS_OLD,	/* TW */
+#endif
+    SIS_300,
+    SIS_630,
+    SIS_730,
+    SIS_540,
+    SIS_315H,   /* SiS 310 */
+    SIS_315,
+    SIS_315PRO, /* SiS 325 */
+    SIS_550,
+    SIS_640,
+    SIS_740,
+    SIS_650,
+    SIS_330, 
+    MAX_SIS_CHIP
+} SIS_CHIP_TYPE;
+#endif
+#endif
+#endif
+
 #ifndef WIN2000
 #ifndef SIS_VB_CHIP_TYPE
 typedef enum _SIS_VB_CHIP_TYPE {
-	VB_CHIP_Legacy = 0,
-	VB_CHIP_301,
-	VB_CHIP_301B,
-	VB_CHIP_301BLCD,
-	VB_CHIP_301BTV,
-	VB_CHIP_302,
-	VB_CHIP_302B,
-	VB_CHIP_302BLCD,
-	VB_CHIP_302BTV,
-	VB_CHIP_303,
-	VB_CHIP_UNKNOWN,	/* other video bridge or no video bridge */
-	MAX_VB_CHIP
+    VB_CHIP_Legacy = 0,
+    VB_CHIP_301,
+    VB_CHIP_301B,
+    VB_CHIP_301BLCD,
+    VB_CHIP_301BTV,
+    VB_CHIP_302,
+    VB_CHIP_302B,
+    VB_CHIP_302BLCD,
+    VB_CHIP_302BTV, 
+    VB_CHIP_303,
+    VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
+    MAX_VB_CHIP
 } SIS_VB_CHIP_TYPE;
 #endif
 #endif
@@ -96,125 +126,130 @@
 #ifndef WIN2000
 #ifndef SIS_LCD_TYPE
 typedef enum _SIS_LCD_TYPE {
-	LCD_INVALID = 0,
-	LCD_800x600,
-	LCD_1024x768,
-	LCD_1280x1024,
-	LCD_1280x960,
-	LCD_640x480,
-	LCD_1600x1200,
-	LCD_1920x1440,
-	LCD_2048x1536,
-	LCD_UNKNOWN
+    LCD_INVALID = 0,
+    LCD_800x600,
+    LCD_1024x768,
+    LCD_1280x1024,
+    LCD_1280x960,
+    LCD_640x480,
+    LCD_1600x1200,
+    LCD_1920x1440,
+    LCD_2048x1536,
+    LCD_320x480,    /* TW: FSTN */
+    LCD_UNKNOWN
 } SIS_LCD_TYPE;
 #endif
 #endif
 
-#ifndef WIN2000			/* mark by Paul ,Move definition to sisv.h */
+#ifndef WIN2000 /* mark by Paul ,Move definition to sisv.h*/
 #ifndef PSIS_DSReg
-typedef struct _SIS_DSReg {
-	UCHAR jIdx;
-	UCHAR jVal;
+typedef struct _SIS_DSReg
+{
+  UCHAR  jIdx;
+  UCHAR  jVal;
 } SIS_DSReg, *PSIS_DSReg;
 #endif
 
 #ifndef SIS_HW_DEVICE_INFO
 
-typedef struct _SIS_HW_DEVICE_INFO SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO;
+typedef struct _SIS_HW_DEVICE_INFO  SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO;
 
-typedef BOOLEAN (*PSIS_QUERYSPACE) (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
+typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
 
-struct _SIS_HW_DEVICE_INFO {
-	PVOID pDevice;		/* The pointer to the physical device data structure 
-				   in each OS or NULL for unused. */
-	UCHAR *pjVirtualRomBase;	/* Only for NT, NULL for WinCE & Linux. */
-	/* base virtual address of VBIOS ROM Space */
-	/* or base virtual address of ROM image file. */
-	/* if NULL, then read from pjROMImage; */
-	/* Note:ROM image file is the file of VBIOS ROM */
-
-	UCHAR *pjCustomizedROMImage;	/* base virtual address of ROM image file. */
-	/* wincE:ROM image file is the file for OEM */
-	/*       customized table */
-	/* Linux: not used */
-	/* NT   : not used  */
-	/* Note : pjCustomizedROMImage=NULL if no ROM image file */
-
-	UCHAR *pjVideoMemoryAddress;	/* base virtual memory address */
-	/* of Linear VGA memory */
-
-	ULONG ulVideoMemorySize;	/* size, in bytes, of the memory on the board */
-	ULONG ulIOAddress;	/* base I/O address of VGA ports (0x3B0) */
-	UCHAR jChipType;	/* Used to Identify SiS Graphics Chip */
-	/* defined in the data structure type  */
-	/* "SIS_CHIP_TYPE" */
-
-	UCHAR jChipRevision;	/* Used to Identify SiS Graphics Chip Revision */
-	UCHAR ujVBChipID;	/* the ID of video bridge */
-	/* defined in the data structure type */
-	/* "SIS_VB_CHIP_TYPE" */
-
-	USHORT usExternalChip;	/* NO VB or other video bridge(not  */
-	/* SiS video bridge) */
-	/* if ujVBChipID = VB_CHIP_UNKNOWN, */
-	/* then bit0=1 : LVDS,bit1=1 : trumpion, */
-	/* bit2=1 : CH7005 & no video bridge if */
-	/* usExternalChip = 0. */
-	/* Note: CR37[3:1]: */
-	/*             001:SiS 301 */
-	/*             010:LVDS */
-	/*             011:Trumpion LVDS Scaling Chip */
-	/*             100:LVDS(LCD-out)+Chrontel 7005 */
-	/*             101:Single Chrontel 7005 */
-
-	ULONG ulCRT2LCDType;	/* defined in the data structure type */
-	/* "SIS_LCD_TYPE" */
-
-	BOOLEAN bIntegratedMMEnabled;	/* supporting integration MM enable */
-
-	BOOLEAN bSkipDramSizing;	/* True: Skip video memory sizing. */
-	PSIS_DSReg pSR;		/* restore SR registers in initial function. */
-	/* end data :(idx, val) =  (FF, FF). */
-	/* Note : restore SR registers if  */
-	/* bSkipDramSizing = TRUE */
-
-	PSIS_DSReg pCR;		/* restore CR registers in initial function. */
-	/* end data :(idx, val) =  (FF, FF) */
-	/* Note : restore cR registers if  */
-	/* bSkipDramSizing = TRUE */
 
-	PSIS_QUERYSPACE pQueryVGAConfigSpace;	/* Get/Set VGA Configuration  */
-	/* space */
+struct _SIS_HW_DEVICE_INFO
+{   
+    PVOID  pDevice;              /* The pointer to the physical device data structure
+                                    in each OS or NULL for unused. */
+    UCHAR  *pjVirtualRomBase;    /* Only for NT, NULL for WinCE & Linux. */
+                                 /* base virtual address of VBIOS ROM Space */
+                                 /* or base virtual address of ROM image file. */
+                                 /* if NULL, then read from pjROMImage; */
+                                 /* Note:ROM image file is the file of VBIOS ROM */
+
+ 
+    UCHAR  *pjCustomizedROMImage;/* base virtual address of ROM image file. */
+                                 /* wincE:ROM image file is the file for OEM */
+                                 /*       customized table */
+                                 /* Linux: not used */
+                                 /* NT   : not used  */
+                                 /* Note : pjCustomizedROMImage=NULL if no ROM image file */
+
+    UCHAR  *pjVideoMemoryAddress;/* base virtual memory address */
+                                 /* of Linear VGA memory */
+
+    ULONG  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
+    ULONG  ulIOAddress;          /* base I/O address of VGA ports (0x3B0) */
+    UCHAR  jChipType;            /* Used to Identify SiS Graphics Chip */
+                                 /* defined in the data structure type  */
+                                 /* "SIS_CHIP_TYPE" */
+
+    UCHAR  jChipRevision;        /* Used to Identify SiS Graphics Chip Revision */
+    UCHAR  ujVBChipID;           /* the ID of video bridge */
+                                 /* defined in the data structure type */
+                                 /* "SIS_VB_CHIP_TYPE" */
+
+    USHORT usExternalChip;       /* NO VB or other video bridge(not  */
+                                 /* SiS video bridge) */
+                                 /* if ujVBChipID = VB_CHIP_UNKNOWN, */
+                                 /* then bit0=1 : LVDS,bit1=1 : trumpion, */
+                                 /* bit2=1 : CH7005 & no video bridge if */
+                                 /* usExternalChip = 0. */
+                                 /* Note: CR37[3:1]: */
+                                 /*             001:SiS 301 */
+                                 /*             010:LVDS */
+                                 /*             011:Trumpion LVDS Scaling Chip */
+                                 /*             100:LVDS(LCD-out)+Chrontel 7005 */
+                                 /*             101:Single Chrontel 7005 */
+
+    ULONG  ulCRT2LCDType;        /* defined in the data structure type */
+                                 /* "SIS_LCD_TYPE" */
+                                     
+    BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
+                                      
+    BOOLEAN bSkipDramSizing;     /* True: Skip video memory sizing. */
+    PSIS_DSReg  pSR;             /* restore SR registers in initial function. */
+                                 /* end data :(idx, val) =  (FF, FF). */
+                                 /* Note : restore SR registers if  */
+                                 /* bSkipDramSizing = TRUE */
+
+    PSIS_DSReg  pCR;             /* restore CR registers in initial function. */
+                                 /* end data :(idx, val) =  (FF, FF) */
+                                 /* Note : restore cR registers if  */
+                                 /* bSkipDramSizing = TRUE */
+    
+    PSIS_QUERYSPACE  pQueryVGAConfigSpace; /* Get/Set VGA Configuration  */
+                                           /* space */
+ 
+    PSIS_QUERYSPACE  pQueryNorthBridgeSpace;/* Get/Set North Bridge  */
+                                            /* space  */
 
-	PSIS_QUERYSPACE pQueryNorthBridgeSpace;	/* Get/Set North Bridge  */
-	/* space  */
-
-	UCHAR szVBIOSVer[VBIOS_VER_MAX_LENGTH];
+    UCHAR  szVBIOSVer[VBIOS_VER_MAX_LENGTH];
 
 };
 #endif
-#endif				/*~ mark by Paul ,Move definition to sisv.h */
+#endif/*~ mark by Paul ,Move definition to sisv.h*/
 
 #ifndef WIN2000
 #ifndef WINCE_HEADER
 #ifndef BUS_DATA_TYPE
 typedef enum _BUS_DATA_TYPE {
-	ConfigurationSpaceUndefined = -1,
-	Cmos,
-	EisaConfiguration,
-	Pos,
-	CbusConfiguration,
-	PCIConfiguration,
-	VMEConfiguration,
-	NuBusConfiguration,
-	PCMCIAConfiguration,
-	MPIConfiguration,
-	MPSAConfiguration,
-	PNPISAConfiguration,
-	MaximumBusDataType
+    ConfigurationSpaceUndefined = -1,
+    Cmos,
+    EisaConfiguration,
+    Pos,
+    CbusConfiguration,
+    PCIConfiguration,
+    VMEConfiguration,
+    NuBusConfiguration,
+    PCMCIAConfiguration,
+    MPIConfiguration,
+    MPSAConfiguration,
+    PNPISAConfiguration,
+    MaximumBusDataType
 } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
 #endif
-#endif				/* WINCE_HEADER */
+#endif /* WINCE_HEADER */
 
 #ifndef PCI_TYPE0_ADDRESSES
 #define PCI_TYPE0_ADDRESSES             6
@@ -227,41 +262,42 @@
 #ifndef WINCE_HEADER
 #ifndef PCI_COMMON_CONFIG
 typedef struct _PCI_COMMON_CONFIG {
-	USHORT VendorID;	/* (ro)                 */
-	USHORT DeviceID;	/* (ro)                 */
-	USHORT Command;		/* Device control       */
-	USHORT Status;
-	UCHAR RevisionID;	/* (ro)                 */
-	UCHAR ProgIf;		/* (ro)                 */
-	UCHAR SubClass;		/* (ro)                 */
-	UCHAR BaseClass;	/* (ro)                 */
-	UCHAR CacheLineSize;	/* (ro+)                */
-	UCHAR LatencyTimer;	/* (ro+)                */
-	UCHAR HeaderType;	/* (ro)                 */
-	UCHAR BIST;		/* Built in self test   */
-
-	union {
-		struct _PCI_HEADER_TYPE_0 {
-			ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];
-			ULONG CIS;
-			USHORT SubVendorID;
-			USHORT SubSystemID;
-			ULONG ROMBaseAddress;
-			ULONG Reserved2[2];
-
-			UCHAR InterruptLine;	/*                    */
-			UCHAR InterruptPin;	/* (ro)               */
-			UCHAR MinimumGrant;	/* (ro)               */
-			UCHAR MaximumLatency;	/* (ro)               */
-		} type0;
+    USHORT  VendorID;                   /* (ro)                 */
+    USHORT  DeviceID;                   /* (ro)                 */
+    USHORT  Command;                    /* Device control       */
+    USHORT  Status;
+    UCHAR   RevisionID;                 /* (ro)                 */
+    UCHAR   ProgIf;                     /* (ro)                 */
+    UCHAR   SubClass;                   /* (ro)                 */
+    UCHAR   BaseClass;                  /* (ro)                 */
+    UCHAR   CacheLineSize;              /* (ro+)                */
+    UCHAR   LatencyTimer;               /* (ro+)                */
+    UCHAR   HeaderType;                 /* (ro)                 */
+    UCHAR   BIST;                       /* Built in self test   */
+
+    union {
+        struct _PCI_HEADER_TYPE_0 {
+            ULONG   BaseAddresses[PCI_TYPE0_ADDRESSES];
+            ULONG   CIS;
+            USHORT  SubVendorID;
+            USHORT  SubSystemID;
+            ULONG   ROMBaseAddress;
+            ULONG   Reserved2[2];
+
+            UCHAR   InterruptLine;      /*                    */
+            UCHAR   InterruptPin;       /* (ro)               */
+            UCHAR   MinimumGrant;       /* (ro)               */
+            UCHAR   MaximumLatency;     /* (ro)               */
+        } type0;
+
 
-	} u;
+    } u;
 
-	UCHAR DeviceSpecific[192];
+    UCHAR   DeviceSpecific[192];
 
 } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
 #endif
-#endif				/* WINCE_HEADER */
+#endif /* WINCE_HEADER */
 
 #ifndef FIELD_OFFSET
 #define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sis/vstruct.h linux/drivers/video/sis/vstruct.h
--- linux.orig/drivers/video/sis/vstruct.h	2001-11-09 22:11:14.000000000 +0000
+++ linux/drivers/video/sis/vstruct.h	2002-07-20 01:08:26.000000000 +0000
@@ -2,169 +2,189 @@
 #define EXTERN
 #else
 #define EXTERN extern
-#endif				/* _INIT_ */
+#endif /* _INIT_ */
 
-typedef struct _SiS_PanelDelayTblStruct {
-	UCHAR timer[2];
+typedef struct _SiS_PanelDelayTblStruct
+{
+ UCHAR timer[2];
 } SiS_PanelDelayTblStruct;
 
-typedef struct _SiS_LCDDataStruct {
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT LCDHT;
-	USHORT LCDVT;
+typedef struct _SiS_LCDDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
 } SiS_LCDDataStruct;
 
-typedef struct _SiS_TVDataStruct {
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT TVHDE;
-	USHORT TVVDE;
-	USHORT RVBHRS;
-	UCHAR FlickerMode;
-	USHORT HALFRVBHRS;
-	UCHAR RY1COE;
-	UCHAR RY2COE;
-	UCHAR RY3COE;
-	UCHAR RY4COE;
+typedef struct _SiS_TVDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT TVHDE;
+ USHORT TVVDE;
+ USHORT RVBHRS;
+ UCHAR FlickerMode;
+ USHORT HALFRVBHRS;
+ UCHAR RY1COE;
+ UCHAR RY2COE;
+ UCHAR RY3COE;
+ UCHAR RY4COE;
 } SiS_TVDataStruct;
 
-typedef struct _SiS_LVDSDataStruct {
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT LCDHT;
-	USHORT LCDVT;
+typedef struct _SiS_LVDSDataStruct
+{
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
 } SiS_LVDSDataStruct;
 
-typedef struct _SiS_LVDSDesStruct {
-	USHORT LCDHDES;
-	USHORT LCDVDES;
+typedef struct _SiS_LVDSDesStruct
+{
+ USHORT LCDHDES;
+ USHORT LCDVDES;
 } SiS_LVDSDesStruct;
 
-typedef struct _SiS_LVDSCRT1DataStruct {
-	UCHAR CR[15];
+typedef struct _SiS_LVDSCRT1DataStruct
+{
+ UCHAR CR[15];
 } SiS_LVDSCRT1DataStruct;
 
 /*add for LCDA*/
-typedef struct _SiS_LCDACRT1DataStruct {
-	UCHAR CR[17];
+typedef struct _SiS_LCDACRT1DataStruct
+{
+ UCHAR CR[17];
 } SiS_LCDACRT1DataStruct;
 
-typedef struct _SiS_CHTVRegDataStruct {
-	UCHAR Reg[5];
+typedef struct _SiS_CHTVRegDataStruct
+{
+ UCHAR Reg[5];
 } SiS_CHTVRegDataStruct;
 
-typedef struct _SiS_StStruct {
-	UCHAR St_ModeID;
-	USHORT St_ModeFlag;
-	UCHAR St_StTableIndex;
-	UCHAR St_CRT2CRTC;
-	UCHAR St_ResInfo;
-	UCHAR VB_StTVFlickerIndex;
-	UCHAR VB_StTVEdgeIndex;
-	UCHAR VB_StTVYFilterIndex;
+typedef struct _SiS_StStruct
+{
+ UCHAR St_ModeID;
+ USHORT St_ModeFlag;
+ UCHAR St_StTableIndex;
+ UCHAR St_CRT2CRTC;
+ UCHAR St_ResInfo;
+ UCHAR VB_StTVFlickerIndex;
+ UCHAR VB_StTVEdgeIndex;
+ UCHAR VB_StTVYFilterIndex;
 } SiS_StStruct;
 
-typedef struct _SiS_VBModeStruct {
-	UCHAR ModeID;
-	UCHAR VB_TVDelayIndex;
-	UCHAR VB_TVFlickerIndex;
-	UCHAR VB_TVPhaseIndex;
-	UCHAR VB_TVYFilterIndex;
-	UCHAR VB_LCDDelayIndex;
-	UCHAR _VB_LCDHIndex;
-	UCHAR _VB_LCDVIndex;
+typedef struct _SiS_VBModeStruct
+{
+UCHAR  ModeID;
+UCHAR  VB_TVDelayIndex;
+UCHAR  VB_TVFlickerIndex;
+UCHAR  VB_TVPhaseIndex;
+UCHAR  VB_TVYFilterIndex;
+UCHAR  VB_LCDDelayIndex;
+UCHAR  _VB_LCDHIndex;
+UCHAR  _VB_LCDVIndex;
 } SiS_VBModeStruct;
 
-typedef struct _SiS_StandTableStruct {
-	UCHAR CRT_COLS;
-	UCHAR ROWS;
-	UCHAR CHAR_HEIGHT;
-	USHORT CRT_LEN;
-	UCHAR SR[4];
-	UCHAR MISC;
-	UCHAR CRTC[0x19];
-	UCHAR ATTR[0x14];
-	UCHAR GRC[9];
+typedef struct _SiS_StandTableStruct
+{
+ UCHAR CRT_COLS;
+ UCHAR ROWS;
+ UCHAR CHAR_HEIGHT;
+ USHORT CRT_LEN;
+ UCHAR SR[4];
+ UCHAR MISC;
+ UCHAR CRTC[0x19];
+ UCHAR ATTR[0x14];
+ UCHAR GRC[9];
 } SiS_StandTableStruct;
 
-typedef struct _SiS_ExtStruct {
-	UCHAR Ext_ModeID;
-	USHORT Ext_ModeFlag;
-	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;
-	USHORT Ext_VESAID;
-	UCHAR Ext_VESAMEMSize;
-	UCHAR Ext_RESINFO;
-	UCHAR VB_ExtTVFlickerIndex;
-	UCHAR VB_ExtTVEdgeIndex;
-	UCHAR VB_ExtTVYFilterIndex;
-	UCHAR REFindex;
+typedef struct _SiS_ExtStruct
+{
+ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_ModeInfo;
+ USHORT Ext_Point;
+ USHORT Ext_VESAID;
+ UCHAR Ext_VESAMEMSize;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+ UCHAR VB_ExtTVYFilterIndex;
+ UCHAR REFindex;
 } SiS_ExtStruct;
 
-typedef struct _SiS_Ext2Struct {
-	USHORT Ext_InfoFlag;
-	UCHAR Ext_CRT1CRTC;
-	UCHAR Ext_CRTVCLK;
-	UCHAR Ext_CRT2CRTC;
-	UCHAR ModeID;
-	USHORT XRes;
-	USHORT YRes;
-	USHORT ROM_OFFSET;
+typedef struct _SiS_Ext2Struct
+{
+ USHORT Ext_InfoFlag;
+ UCHAR Ext_CRT1CRTC;
+ UCHAR Ext_CRTVCLK;
+ UCHAR Ext_CRT2CRTC;
+ UCHAR  ModeID;
+ USHORT XRes;
+ USHORT YRes;
+ USHORT ROM_OFFSET;
 } SiS_Ext2Struct;
 
-typedef struct _SiS_CRT1TableStruct {
-	UCHAR CR[17];
+typedef struct _SiS_CRT1TableStruct
+{
+ UCHAR CR[17];
 } SiS_CRT1TableStruct;
 
-typedef struct _SiS_MCLKDataStruct {
-	UCHAR SR28, SR29, SR2A;
-	USHORT CLOCK;
+typedef struct _SiS_MCLKDataStruct
+{
+ UCHAR SR28,SR29,SR2A;
+ USHORT CLOCK;
 } SiS_MCLKDataStruct;
 
-typedef struct _SiS_ECLKDataStruct {
-	UCHAR SR2E, SR2F, SR30;
-	USHORT CLOCK;
+typedef struct _SiS_ECLKDataStruct
+{
+ UCHAR SR2E,SR2F,SR30;
+ USHORT CLOCK;
 } SiS_ECLKDataStruct;
 
-typedef struct _SiS_VCLKDataStruct {
-	UCHAR SR2B, SR2C;
-	USHORT CLOCK;
+typedef struct _SiS_VCLKDataStruct
+{
+ UCHAR SR2B,SR2C;
+ USHORT CLOCK;
 } SiS_VCLKDataStruct;
 
-typedef struct _SiS_VBVCLKDataStruct {
-	UCHAR Part4_A, Part4_B;
-	USHORT CLOCK;
+typedef struct _SiS_VBVCLKDataStruct
+{
+ UCHAR Part4_A,Part4_B;
+ USHORT CLOCK;
 } SiS_VBVCLKDataStruct;
 
-typedef struct _SiS_StResInfoStruct {
-	USHORT HTotal;
-	USHORT VTotal;
+typedef struct _SiS_StResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
 } SiS_StResInfoStruct;
 
-typedef struct _SiS_ModeResInfoStruct {
-	USHORT HTotal;
-	USHORT VTotal;
-	UCHAR XChar;
-	UCHAR YChar;
+typedef struct _SiS_ModeResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+ UCHAR  XChar;
+ UCHAR  YChar;
 } SiS_ModeResInfoStruct;
 
 EXTERN SiS_StStruct *SiS_SModeIDTable;
 EXTERN SiS_StandTableStruct *SiS_StandTable;
-EXTERN SiS_ExtStruct *SiS_EModeIDTable;
-EXTERN SiS_Ext2Struct *SiS_RefIndex;
+EXTERN SiS_ExtStruct  *SiS_EModeIDTable;
+EXTERN SiS_Ext2Struct  *SiS_RefIndex;
 EXTERN SiS_VBModeStruct *SiS_VBModeIDTable;
-EXTERN SiS_CRT1TableStruct *SiS_CRT1Table;
-EXTERN SiS_MCLKDataStruct *SiS_MCLKData;
-EXTERN SiS_ECLKDataStruct *SiS_ECLKData;
-EXTERN SiS_VCLKDataStruct *SiS_VCLKData;
-EXTERN SiS_VBVCLKDataStruct *SiS_VBVCLKData;
-EXTERN SiS_StResInfoStruct *SiS_StResInfo;
-EXTERN SiS_ModeResInfoStruct *SiS_ModeResInfo;
+EXTERN SiS_CRT1TableStruct  *SiS_CRT1Table;
+EXTERN SiS_MCLKDataStruct  *SiS_MCLKData;
+EXTERN SiS_ECLKDataStruct  *SiS_ECLKData;
+EXTERN SiS_VCLKDataStruct  *SiS_VCLKData;
+EXTERN SiS_VBVCLKDataStruct  *SiS_VBVCLKData;
+EXTERN SiS_StResInfoStruct  *SiS_StResInfo;
+EXTERN SiS_ModeResInfoStruct  *SiS_ModeResInfo;
 EXTERN UCHAR *SiS_ScreenOffset;
 
 EXTERN UCHAR *pSiS_OutputSelect;
@@ -172,8 +192,8 @@
 EXTERN UCHAR *pSiS_SR07;
 
 typedef UCHAR DRAM4Type[4];
-EXTERN DRAM4Type *SiS_SR15;	/* pointer : point to array */
-EXTERN DRAM4Type *SiS_CR40;	/* pointer : point to array */
+EXTERN DRAM4Type *SiS_SR15; /* pointer : point to array */
+EXTERN DRAM4Type *SiS_CR40; /* pointer : point to array */
 EXTERN UCHAR *SiS_CR49;
 EXTERN UCHAR *SiS_SR25;
 
@@ -192,7 +212,7 @@
 EXTERN USHORT *pSiS_RGBSenseData;
 EXTERN USHORT *pSiS_VideoSenseData;
 EXTERN USHORT *pSiS_YCSenseData;
-EXTERN USHORT *pSiS_RGBSenseData2;	/*301b */
+EXTERN USHORT *pSiS_RGBSenseData2; /*301b*/
 EXTERN USHORT *pSiS_VideoSenseData2;
 EXTERN USHORT *pSiS_YCSenseData2;
 
@@ -202,21 +222,21 @@
 EXTERN UCHAR *SiS_PALPhase2;
 EXTERN UCHAR *SiS_PALMPhase;
 EXTERN UCHAR *SiS_PALNPhase;
-EXTERN SiS_LCDDataStruct *SiS_StLCD1024x768Data;
-EXTERN SiS_LCDDataStruct *SiS_ExtLCD1024x768Data;
-EXTERN SiS_LCDDataStruct *SiS_St2LCD1024x768Data;
-EXTERN SiS_LCDDataStruct *SiS_StLCD1280x1024Data;
-EXTERN SiS_LCDDataStruct *SiS_ExtLCD1280x1024Data;
-EXTERN SiS_LCDDataStruct *SiS_St2LCD1280x1024Data;
-EXTERN SiS_LCDDataStruct *SiS_NoScaleData;
-EXTERN SiS_LCDDataStruct *SiS_LCD1280x960Data;
-EXTERN SiS_TVDataStruct *SiS_StPALData;
-EXTERN SiS_TVDataStruct *SiS_ExtPALData;
-EXTERN SiS_TVDataStruct *SiS_StNTSCData;
-EXTERN SiS_TVDataStruct *SiS_ExtNTSCData;
-EXTERN SiS_TVDataStruct *SiS_St1HiTVData;
-EXTERN SiS_TVDataStruct *SiS_St2HiTVData;
-EXTERN SiS_TVDataStruct *SiS_ExtHiTVData;
+EXTERN SiS_LCDDataStruct  *SiS_StLCD1024x768Data;
+EXTERN SiS_LCDDataStruct  *SiS_ExtLCD1024x768Data;
+EXTERN SiS_LCDDataStruct  *SiS_St2LCD1024x768Data;
+EXTERN SiS_LCDDataStruct  *SiS_StLCD1280x1024Data;
+EXTERN SiS_LCDDataStruct  *SiS_ExtLCD1280x1024Data;
+EXTERN SiS_LCDDataStruct  *SiS_St2LCD1280x1024Data;
+EXTERN SiS_LCDDataStruct  *SiS_NoScaleData;
+EXTERN SiS_LCDDataStruct  *SiS_LCD1280x960Data;
+EXTERN SiS_TVDataStruct   *SiS_StPALData;
+EXTERN SiS_TVDataStruct   *SiS_ExtPALData;
+EXTERN SiS_TVDataStruct   *SiS_StNTSCData;
+EXTERN SiS_TVDataStruct   *SiS_ExtNTSCData;
+EXTERN SiS_TVDataStruct   *SiS_St1HiTVData;
+EXTERN SiS_TVDataStruct   *SiS_St2HiTVData;
+EXTERN SiS_TVDataStruct   *SiS_ExtHiTVData;
 EXTERN UCHAR *SiS_NTSCTiming;
 EXTERN UCHAR *SiS_PALTiming;
 EXTERN UCHAR *SiS_HiTVExtTiming;
@@ -228,90 +248,93 @@
 EXTERN UCHAR *SiS_HiTVGroup3Text;
 
 EXTERN SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS800x600Data_1;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS800x600Data_2;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS1024x768Data_1;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS1024x768Data_2;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_1;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_2;
-EXTERN SiS_LVDSDataStruct *SiS_LVDS640x480Data_1;
-EXTERN SiS_LVDSDataStruct *SiS_CHTVUNTSCData;
-EXTERN SiS_LVDSDataStruct *SiS_CHTVONTSCData;
-EXTERN SiS_LVDSDataStruct *SiS_CHTVUPALData;
-EXTERN SiS_LVDSDataStruct *SiS_CHTVOPALData;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType00_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType01_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType02_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType03_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType04_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType05_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType06_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType07_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType08_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType09_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0a_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0b_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0c_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0d_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0e_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0f_1;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType00_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType01_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType02_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType03_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType04_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType05_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType06_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType07_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType08_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType09_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0a_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0b_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0c_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0d_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0e_2;
-EXTERN SiS_LVDSDesStruct *SiS_PanelType0f_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS800x600Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS800x600Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_2;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
+EXTERN SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;  /*fstn*/
+EXTERN SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
+EXTERN SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
+EXTERN SiS_LVDSDataStruct  *SiS_CHTVUPALData;
+EXTERN SiS_LVDSDataStruct  *SiS_CHTVOPALData;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType00_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType01_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType02_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType03_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType04_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType05_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType06_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType07_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType08_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType09_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0a_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0b_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0c_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0d_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0e_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0f_1;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType00_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType01_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType02_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType03_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType04_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType05_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType06_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType07_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType08_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType09_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0a_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0b_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0c_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0d_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0e_2;
+EXTERN SiS_LVDSDesStruct  *SiS_PanelType0f_2;
 /*301b*/
-EXTERN SiS_LVDSDesStruct *LVDS1024x768Des_1;
-EXTERN SiS_LVDSDesStruct *LVDS1280x1024Des_1;
-EXTERN SiS_LVDSDesStruct *LVDS1280x960Des_1;
-EXTERN SiS_LVDSDesStruct *LVDS1024x768Des_2;
-EXTERN SiS_LVDSDesStruct *LVDS1280x1024Des_2;
-EXTERN SiS_LVDSDesStruct *LVDS1280x960Des_2;
+EXTERN SiS_LVDSDesStruct  *LVDS1024x768Des_1;
+EXTERN SiS_LVDSDesStruct  *LVDS1280x1024Des_1;
+EXTERN SiS_LVDSDesStruct  *LVDS1280x960Des_1;
+EXTERN SiS_LVDSDesStruct  *LVDS1024x768Des_2;
+EXTERN SiS_LVDSDesStruct  *LVDS1280x1024Des_2;
+EXTERN SiS_LVDSDesStruct  *LVDS1280x960Des_2;
 /*end 301b*/
-EXTERN SiS_LVDSDesStruct *SiS_CHTVUNTSCDesData;
-EXTERN SiS_LVDSDesStruct *SiS_CHTVONTSCDesData;
-EXTERN SiS_LVDSDesStruct *SiS_CHTVUPALDesData;
-EXTERN SiS_LVDSDesStruct *SiS_CHTVOPALDesData;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2_H;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL;
-EXTERN SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1OPAL;
+EXTERN SiS_LVDSDesStruct  *SiS_CHTVUNTSCDesData;
+EXTERN SiS_LVDSDesStruct  *SiS_CHTVONTSCDesData;
+EXTERN SiS_LVDSDesStruct  *SiS_CHTVUPALDesData;
+EXTERN SiS_LVDSDesStruct  *SiS_CHTVOPALDesData;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2_H;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1OPAL;
+/*fstn*/
+EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1320x480_1;
 /*add for  LCDA*/
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_1;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_1_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_2;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_2_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2_H;
-EXTERN SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2_H;
+EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2_H;
 /*end 301b*/
 
 EXTERN SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sstfb.c linux/drivers/video/sstfb.c
--- linux.orig/drivers/video/sstfb.c	2001-11-14 22:52:20.000000000 +0000
+++ linux/drivers/video/sstfb.c	2002-07-20 01:08:38.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/video/sstfb.c -- voodoo graphics frame buffer
  *
- *     Copyright (c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>
+ *     Copyright (c) 2000-2002 Ghozlane Toumi <gtoumi@laposte.net>
  *
  *     Created 15 Jan 2000 by Ghozlane Toumi
  *
@@ -9,8 +9,8 @@
  *
  * 03/2001 James Simmons   <jsimmons@linux-fbdev.org>
  * 04/2001 Paul Mundt      <lethal@chaoticdreams.org>
- * 05/2001 Urs Ganse       <urs.ganse@t-online.de>
- *     (initial work on voodoo2 port)
+ * 05/2001 Urs Ganse       <ursg@uni.de>
+ *     (initial work on voodoo2 port, interlace)
  *
  *
  * $Id: sstfb.c,v 1.26.4.1 2001/08/29 01:30:37 ghoz Exp $
@@ -27,38 +27,22 @@
  * misc notes, TODOs, toASKs, and deep thoughts
 
 -TODO: at one time or another test that the mode is acceptable by the monitor
--ASK: I can choose different ordering for the color bitfields (rgba argb ...) 
-      wich one should i use ? is there any preferred one ? It seems ARGB is 
+-ASK: I can choose different ordering for the color bitfields (rgba argb ...)
+      wich one should i use ? is there any preferred one ? It seems ARGB is
       the one ...
 -ASK: later: how to cope with endianness ? the fbi chip has builtin functions
       to do byte swizling /swapping, maybe use that ...
--TODO: check the error paths . if something get wrong, the error doesn't seem 
-      to be very well handled...if handled at all.. not good. 
--ASK: ioremap ou ioremap_nocache ? : nocache is safe
+-TODO: check the error paths . if something get wrong, the error doesn't seem
+      to be very well handled...if handled at all.. not good.
 -TODO: in  set_var check the validity of timings (hsync vsync)...
--FIXME: I'm not sure i like all the functions with no parameters.. change them 
-        to use a sstfb_par or sstfb_info or something like that.
--TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via 
-       a nop command . so it's ok as long as the commands we pass don't go 
-       through the fifo. warning: issuing a nop command seems to need pci_fifo 
-       enabled
--ASK: the 24 bits mode is NOT packed . how do i differenciate from a packed mode ?
-      set a pseudo alpha value not used ?
--ASK: how does the 32 bpp work ? should i enable the pipeline so alpha values 
-      are used ?
--TODO: check how the voodoo graphics can cope with 24/32 bpp (engine is 16bpp 
-       only)
--ASK: Do i ioremap the complete area devoted to the lfb (4Mb), or check the 
-      real size, then unmap and remap to the real size of the lfb ? 
-      ... map all the area.
--FIXME: in case of failure in the init sequence, be sure we return to a safe 
+-TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via
+       a nop command . so it's ok as long as the commands we pass don't go
+       through the fifo. warning: issuing a nop command seems to need pci_fifo
+-FIXME: in case of failure in the init sequence, be sure we return to a safe
         state.
 -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
 -ASK: I stole "inverse" but seems it doesn't work... check what it realy does...
-Notes
 -TODO: change struct sst_info fb_info from static to array/dynamic
-  TTT comments is for code i've put there for debuging the "weird peinguin 
-  	syndrome", it should disapear soon
 
  *
  */
@@ -119,6 +103,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/ioctl.h>
@@ -132,52 +117,11 @@
 
 #include "sstfb.h"
 
-/* void Dump_regs(void); */
-
-/* sst default init registers */
-#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
-
-#define FBIINIT1_DEFAULT 	\
-	(			\
-	  FAST_PCI_WRITES	\
-/*	  SLOW_PCI_WRITES*/	\
-	| VIDEO_RESET		\
-	| 10 << TILES_IN_X_SHIFT\
-	| SEL_SOURCE_VCLK_2X_SEL\
-	| EN_LFB_READ		\
-	)
-
-#define FBIINIT2_DEFAULT	\
-	(			\
-	 SWAP_DACVSYNC		\
-	| EN_DRAM_OE		\
-	| DRAM_REFRESH_16	\
-	| EN_DRAM_REFRESH	\
-	| EN_FAST_RAS_READ	\
-	| EN_RD_AHEAD_FIFO	\
-	| EN_FAST_RD_AHEAD_WR	\
-	)
-
-#define FBIINIT3_DEFAULT 	\
-	( DISABLE_TEXTURE )
-
-#define FBIINIT4_DEFAULT	\
-	(			\
-	  FAST_PCI_READS	\
-/*	  SLOW_PCI_READS*/	\
-	| LFB_READ_AHEAD	\
-	)
-/* Careful with this one : writing back the data just read will trash the DAC
-   reading some fields give logic value on pins, but setting this field will
-   set the source signal driving the pin. conclusion : just use the default
-   as a base before writing back .
-*/
-#define FBIINIT6_DEFAULT	(0x0)
+/* void __Dump_regs(struct sstfb_info *);
+#define Dump_regs __Dump_regs(sst_info) */
 
 /********/
 
-int currcon; /* =0 */
-int num_sst; /* =0*/		/* number of initialized boards */
 
 /* initialized by setup */
 static int inverse; /* =0 */	/* invert colormap */
@@ -186,31 +130,17 @@
 static int clipping = 1;	/* use clipping (slower, safer) */
 static int gfxclk;  /* =0 */	/* force FBI freq in Mhz . Dangerous */
 static int slowpci; /* =0 */	/* slow PCI settings */
-static int dev = -1;		/* specify device (0..n) */
-static char * mode_option ;
+static int dev = -2;		/* specify device (0..n) -2=all -1=none*/
 
+static char * mode_option ;
 
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
-union {
-#  ifdef FBCON_HAS_CFB16
-	u16 cfb16[16];
-#  endif
-#ifdef EN_24_32_BPP
-#  if defined (FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
-	u32 cfb32[16];
-#  endif
-#endif
-	} fbcon_cmap;
-#endif
-static struct { u_int red, green, blue, transp; } palette[16];
-static struct sstfb_info fb_info;
-static struct display disp;
 
 /********/
 
-/* Interface to ze oueurld  */
 int sstfb_init(void);
 int sstfb_setup(char *options);
+static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id);
+static void __devexit sstfb_remove(struct pci_dev *pdev);
 
 
 /* Framebuffer API */
@@ -260,21 +190,20 @@
 #endif
 
 /* Low level routines */
-static int sst_get_memsize(u_long *memsize);
-static int sst_wait_idle(void);
-static int sst_detect_dactype(void);
-static int sst_detect_att(void);
-static int sst_detect_ti(void);
-static int sst_detect_ics(void);
+static int sst_get_memsize(struct sstfb_info *sst_info, u_long *memsize);
+static int __sst_wait_idle(u_long vbase);
+#define sst_wait_idle()	 __sst_wait_idle(sst_info->mmio.vbase)
+static int sst_detect_dactype(struct sstfb_info *sst_info);
+static int sst_detect_att(struct sstfb_info *sst_info);
+static int sst_detect_ti(struct sstfb_info *sst_info);
+static int sst_detect_ics(struct sstfb_info *sst_info);
 static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t);
-static int sst_set_pll_att_ti(const struct pll_timing *t, const int clock);
-static int sst_set_pll_ics(const struct pll_timing *t, const int clock);
-static void sst_set_vidmod_att_ti(const int bpp);
-static void sst_set_vidmod_ics(const int bpp);
-static int sst_init(void);
-#ifdef MODULE
-static void sst_shutdown(void);
-#endif
+static int sst_set_pll_att_ti(struct sstfb_info *sst_info, const struct pll_timing *t, const int clock);
+static int sst_set_pll_ics(struct sstfb_info *sst_info, const struct pll_timing *t, const int clock);
+static void sst_set_vidmod_att_ti(struct sstfb_info *sst_info, const int bpp);
+static void sst_set_vidmod_ics(struct sstfb_info *sst_info, const int bpp);
+static int sst_init(struct sstfb_info *sst_info);
+static void sst_shutdown(struct sstfb_info *sst_info);
 
 static struct fb_ops sstfb_ops = {
 	owner : THIS_MODULE,
@@ -289,9 +218,37 @@
 	fb_ioctl:	sstfb_ioctl,
 };
 
-#ifndef DEFAULT_MODE
-#  define DEFAULT_MODE 0
-#endif
+enum {
+	ID_VOODOO1 = 0,
+	ID_VOODOO2 = 1,
+};
+
+#define IS_VOODOO2(info) ((info)->type == ID_VOODOO2 )
+
+static struct sst_spec voodoo_spec[] __devinitdata = {
+	{ name : "Voodoo Graphics",
+	default_gfx_clock : 50000,
+	max_gfxclk : 60, },
+	{ name : "Voodoo2",
+	default_gfx_clock : 75000,
+	max_gfxclk : 85, },
+};
+
+static struct pci_device_id sstfb_id_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO1 },
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO2 },
+	{ 0 },
+};
+
+static struct pci_driver sstfb_driver = {
+	name:		"sstfb",
+	id_table:	sstfb_id_tbl,
+	probe:          sstfb_probe,
+	remove:		__devexit_p(sstfb_remove),
+};
+
 static struct fb_var_screeninfo	sstfb_default =
 #if ( DEFAULT_MODE == 0 )
     { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */
@@ -326,7 +283,7 @@
     0, FB_VMODE_NONINTERLACED };
 #endif
 
-static struct dac_switch dacs[] = {
+static struct dac_switch dacs[] __devinitdata = {
 	{	name:		"TI TVP3409",
 		detect:		sst_detect_ti,
 		set_pll:	sst_set_pll_att_ti,
@@ -342,17 +299,6 @@
 		set_vidmod:	sst_set_vidmod_ics },
 };
 
-static struct sst_spec voodoo1_spec = {
-	name : "Voodoo Graphics",
-	default_gfx_clock : 50000,
-	max_gfxclk : 60,
-};
-
-static struct sst_spec voodoo2_spec = {
-	name : "Voodoo2",
-	default_gfx_clock : 75000,
-	max_gfxclk : 85,
-};
 
 /*
  *
@@ -384,8 +330,8 @@
 }
 #endif /* (SST_DEBUG_VAR > 0) */
 
+#if (SST_DEBUG_REG > 0)
 static void sst_dbg_print_read_reg (u32 reg, u32 val) {
-#if (SST_DEBUG_REG > 0) /* i need the init registers :) */
 	char * regname =NULL;
 	switch (reg) {
 	case FBIINIT0: regname="FbiInit0"; break;
@@ -393,17 +339,16 @@
 	case FBIINIT2: regname="FbiInit2"; break;
 	case FBIINIT3: regname="FbiInit3"; break;
 	case FBIINIT4: regname="FbiInit4"; break;
+	case FBIINIT5: regname="FbiInit5"; break;
 	case FBIINIT6: regname="FbiInit6"; break;
 	}
 	if (regname == NULL)
 		r_ddprintk("sst_read(%#x): %#x\n", reg, val);
 	else
 		r_dprintk(" sst_read(%s): %#x\n", regname, val);
-#endif /*  (SST_DEBUG_REG > 0) */
 }
 
 static void sst_dbg_print_write_reg (u32 reg, u32 val) {
-#if (SST_DEBUG_REG > 0) /* i need the init registers :) */
 	char * regname = NULL;
 
 	switch (reg) {
@@ -412,92 +357,104 @@
 	case FBIINIT2: regname="FbiInit2"; break;
 	case FBIINIT3: regname="FbiInit3"; break;
 	case FBIINIT4: regname="FbiInit4"; break;
+	case FBIINIT5: regname="FbiInit5"; break;
 	case FBIINIT6: regname="FbiInit6"; break;
 	}
 	if (regname == NULL)
 		r_ddprintk("sst_write(%#x, %#x)\n", reg, val);
 	else
 		r_dprintk(" sst_write(%s, %#x)\n", regname, val);
-#endif /*  (SST_DEBUG_REG > 0) */
 }
+#else /*  (SST_DEBUG_REG > 0) */
+#  define sst_dbg_print_read_reg(reg, val)	do {}while(0)
+#  define sst_dbg_print_write_reg(reg, val)	do {}while(0)
+#endif /*  (SST_DEBUG_REG > 0) */
 
 /* register access */
-static inline u32 sst_read(u32 reg)
+#define sst_read(reg)		__sst_read(sst_info->mmio.vbase, reg)
+#define sst_write(reg,val)	__sst_write(sst_info->mmio.vbase, reg, val)
+#define sst_set_bits(reg,val)	__sst_set_bits(sst_info->mmio.vbase, reg, val)
+#define sst_unset_bits(reg,val)	__sst_unset_bits(sst_info->mmio.vbase, reg, val)
+#define sst_dac_read(reg)	__sst_dac_read(sst_info->mmio.vbase, reg)
+#define sst_dac_write(reg,val)	__sst_dac_write(sst_info->mmio.vbase, reg, val)
+#define dac_i_read(reg)		__dac_i_read(sst_info->mmio.vbase, reg)
+#define dac_i_write(reg,val)	__dac_i_write(sst_info->mmio.vbase, reg, val)
+
+static inline u32 __sst_read(u_long vbase, u32 reg)
 {
 	u32 ret;
 
-	ret = readl(fb_info.mmio.vbase + reg);
+	ret = readl(vbase + reg);
 	sst_dbg_print_read_reg(reg, ret);
 	return ret;
 }
 
-static inline void sst_write(u32 reg, u32 val)
+static inline void __sst_write(u_long vbase, u32 reg, u32 val)
 {
 	sst_dbg_print_write_reg(reg, val);
-	writel(val, fb_info.mmio.vbase + reg);
+	writel(val, vbase + reg);
 }
 
-static inline void sst_set_bits(u32 reg, u32 val)
+static inline void __sst_set_bits(u_long vbase, u32 reg, u32 val)
 {
 	r_dprintk("sst_set_bits(%#x, %#x)\n", reg, val);
-	sst_write(reg, sst_read(reg) | val);
+	__sst_write(vbase, reg, __sst_read(vbase, reg) | val);
 }
 
-static inline void sst_unset_bits(u32 reg, u32 val)
+static inline void __sst_unset_bits(u_long vbase, u32 reg, u32 val)
 {
 	r_dprintk("sst_unset_bits(%#x, %#x)\n", reg, val);
-	sst_write(reg, sst_read(reg) & ~val);
+	__sst_write(vbase, reg, __sst_read(vbase, reg) & ~val);
 }
 
 /* dac access */
 /* dac_read should be remaped to FbiInit2 (via the pci reg init_enable) */
-static u8 sst_dac_read(u8 reg)
+static u8 __sst_dac_read(u_long vbase, u8 reg)
 {
 	u8 ret;
 
 #ifdef SST_DEBUG
 	if ((reg & 0x07) != reg) {
-		dprintk("bug line %d: register adress '%d' is to high\n",
+		dprintk("bug line %d: register adress '%d' is too high\n",
 		         __LINE__,reg);
 	}
 #endif
 	reg &= 0x07;
-	sst_write(DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
-	sst_wait_idle();
+	__sst_write(vbase, DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
+	__sst_wait_idle(vbase);
 	/*udelay(10);*/
-	ret=(sst_read(DAC_READ) & 0xff);
+	ret=(__sst_read(vbase, DAC_READ) & 0xff);
 	r_dprintk("sst_dac_read(%#x): %#x\n", reg, ret);
 	return (u8)ret;
 }
 
-static void sst_dac_write(u8 reg, u8 val)
+static void __sst_dac_write(u_long vbase, u8 reg, u8 val)
 {
 	r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);
 #ifdef SST_DEBUG
 	if ((reg & 0x07) != reg)
-		dprintk("bug line %d: register adress '%d' is to high\n",
+		dprintk("bug line %d: register adress '%d' is too high\n",
 		         __LINE__,reg);
 #endif
 	reg &= 0x07;
-	sst_write(DAC_DATA,(((u32)reg << 8)) | (u32)val);
+	__sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val);
 }
 
 /* indexed access to ti/att dacs */
-static inline u32 dac_i_read(u8 reg)
+static u32 __dac_i_read(u_long vbase, u8 reg)
 {
 	u32 ret;
 
-	sst_dac_write(DACREG_ADDR_I, reg);
-	ret = sst_dac_read(DACREG_DATA_I);
+	__sst_dac_write(vbase, DACREG_ADDR_I, reg);
+	ret = __sst_dac_read(vbase, DACREG_DATA_I);
 	r_dprintk("sst_dac_read_i(%#x): %#x\n", reg, ret);
 	return ret;
 }
-
-static inline void dac_i_write(u8 reg,u8 val)
+static void __dac_i_write(u_long vbase, u8 reg,u8 val)
 {
 	r_dprintk("sst_dac_write_i(%#x, %#x)\n", reg, val);
-	sst_dac_write(DACREG_ADDR_I, reg);
-	sst_dac_write(DACREG_DATA_I, val);
+	__sst_dac_write(vbase, DACREG_ADDR_I, reg);
+	__sst_dac_write(vbase, DACREG_DATA_I, val);
 }
 
 /*
@@ -508,9 +465,10 @@
 
 static void sstfb_install_cmap(int con, struct fb_info *info)
 {
+#define sst_info	((struct sstfb_info *) info)
 	f_dprintk("sstfb_install_cmap(con: %d)\n",con);
-	f_ddprintk("currcon: %d\n", currcon);
-	if (con != currcon)
+	f_ddprintk("currcon: %d\n", sst_info->currcon);
+	if (con != sst_info->currcon)
 		return;
 	if (fb_display[con].cmap.len)
 		fb_set_cmap(&fb_display[con].cmap, 1, sstfb_setcolreg, info);
@@ -518,71 +476,80 @@
 		fb_set_cmap(
 			fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 			1, sstfb_setcolreg, info);
+#undef sst_info
 }
 
 static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
                            u_int *transp, struct fb_info *info)
 {
-	f_ddprintk("sstfb_getcolreg\n");
+#define sst_info	((struct sstfb_info *) info)
+	f_dddprintk("sstfb_getcolreg\n");
 	if (regno >= 16) return 1;
 
-	*red    = palette[regno].red;
-	*green  = palette[regno].green;
-	*blue   = palette[regno].blue;
-	*transp = palette[regno].transp;
+	*red    = sst_info->palette[regno].red;
+	*green  = sst_info->palette[regno].green;
+	*blue   = sst_info->palette[regno].blue;
+	*transp = sst_info->palette[regno].transp;
 	f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",
 	            regno,*red, *green, *blue, *transp);
 	return 0;
+#undef sst_info
 }
 
 static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                            u_int transp, struct fb_info *info)
 {
+#define sst_info	((struct sstfb_info *) info)
 	u32 col;
+	struct display * disp;
 
-	f_ddprintk("sstfb_setcolreg\n");
+	f_dddprintk("sstfb_setcolreg\n");
 	f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",
 	            regno, red, green, blue, transp);
 	if (regno >= 16) return 1;
-	palette[regno].red   = red;
-	palette[regno].green = green;
-	palette[regno].blue  = blue;
-
-	red    >>= (16 - disp.var.red.length);
-	green  >>= (16 - disp.var.green.length);
-	blue   >>= (16 - disp.var.blue.length);
-	transp >>= (16 - disp.var.transp.length);
-	col = (red << disp.var.red.offset)
-		| (green << disp.var.green.offset)
-		| (blue  << disp.var.blue.offset)
-		| (transp << disp.var.transp.offset);
 
-	switch(disp.var.bits_per_pixel) {
+	sst_info->palette[regno].red   = red;
+	sst_info->palette[regno].green = green;
+	sst_info->palette[regno].blue  = blue;
+	sst_info->palette[regno].transp= transp;
+
+	disp=&sst_info->disp;
+	red    >>= (16 - disp->var.red.length);
+	green  >>= (16 - disp->var.green.length);
+	blue   >>= (16 - disp->var.blue.length);
+	transp >>= (16 - disp->var.transp.length);
+	col = (red << disp->var.red.offset)
+	    | (green << disp->var.green.offset)
+	    | (blue  << disp->var.blue.offset)
+	    | (transp << disp->var.transp.offset);
+
+	switch(disp->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB16
 	case 16:
-		fbcon_cmap.cfb16[regno]=(u16)col;
+		sst_info->fbcon_cmap.cfb16[regno]=(u16)col;
 		break;
 #endif
 #ifdef EN_24_32_BPP
 #ifdef FBCON_HAS_CFB24
 	case 24:
-		fbcon_cmap.cfb32[regno]=col;
+		sst_info->fbcon_cmap.cfb32[regno]=col;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB32
 	case 32:
-		fbcon_cmap.cfb32[regno]=col;
+		sst_info->fbcon_cmap.cfb32[regno]=col;
 		break;
 #endif
 #endif
 	default:
 		eprintk("bug line %d: bad depth '%u'\n",__LINE__,
-			disp.var.bits_per_pixel);
+			disp->var.bits_per_pixel);
 		break;
 	}
 	f_dddprintk("bpp: %d . encoded color: %#x\n",
-	            disp.var.bits_per_pixel, col);
+	            disp->var.bits_per_pixel, col);
 	return 0;
+#undef sst_info
 }
 
 /* set par according to var ( checks var ) */
@@ -594,17 +561,7 @@
 
 	f_dprintk("sstfb_decode_var\n");
 	/* Check var validity */
-	if ((var->xres > 1024) || (!var->xres) || (!var->xres)) {
-		eprintk ("Unsupported resolution %dx%d\n",
-		         var->xres, var->yres);
-		return -EINVAL;
-	}
-	if ((var->vmode & FB_VMODE_MASK) !=  FB_VMODE_NONINTERLACED) {
-		eprintk("Interlace non supported %#x\n",
-			(var->vmode & FB_VMODE_MASK));
-		return -EINVAL;
-	}
-
+	par->valid=0;
 
 	memset(par, 0, sizeof(par));
 	par->xDim       = var->xres;
@@ -616,6 +573,24 @@
 	par->vSyncOff   = var->yres + var->lower_margin + var->upper_margin;
 	par->vBackPorch = var->upper_margin;
 
+	if(sst_calc_pll (PS2KHZ(var->pixclock), &par->freq, &par->pll)) {
+		eprintk("Pixclock %d out of range\n", var->pixclock);
+		return -EINVAL; //XXX
+	}
+
+	par->sync=var->sync & (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
+	par->vmode=var->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE);
+
+	/* in laced mode, vBackPorch should be even. odd -> funky display */
+	if (par->vmode & FB_VMODE_INTERLACED)
+		par->vBackPorch += (par->vBackPorch % 2);
+	if (par->vmode & FB_VMODE_DOUBLE) {
+		par->vBackPorch <<= 1;
+		par->yDim <<=1;
+		par->vSyncOn <<=1;
+		par->vSyncOff <<=1;
+	}
+
 	switch (var->bits_per_pixel) {
 	case 0 ... 16 :
 		par->bpp = 16;
@@ -634,7 +609,7 @@
 		break;
 	}
 
-	if (sst_info->is_voodoo2) {
+	if (IS_VOODOO2(sst_info)) {
 		/* voodoo2 has 32 pixel wide tiles , BUT stange things
 		 happen with odd number of tiles */
 		par->tiles_in_X= (par->xDim + 63 ) / 64 * 2;
@@ -643,23 +618,68 @@
 		par->tiles_in_X= (par->xDim + 63 ) / 64;
 	}
 
-	/*
-	 *  mem check
-	 */
+	/* validity tests */
+	if((par->xDim <= 1) || (par->yDim <= 0 )
+	   || (par->hSyncOn <= 1)
+	   || (par->hSyncOff <= 1)
+	   || (par->hBackPorch <= 2)
+	   || (par->vSyncOn <= 0)
+	   || (par->vSyncOff <= 0)
+	   || (par->vBackPorch <= 0)
+	   || (par->tiles_in_X <= 0)) {
+		return -EINVAL;
+	}
+	if (IS_VOODOO2(sst_info)) {
+		/* Voodoo 2 limits */
+		if(((par->xDim-1) >= POW2(11)) || (par->yDim >= POW2(11))) {
+			eprintk ("Unsupported resolution %dx%d\n",
+			         var->xres, var->yres);
+			return -EINVAL;
+		}
+		if (((par->hSyncOn-1) >= POW2(9))
+		   || ((par->hSyncOff-1) >= POW2(11))
+		   || ((par->hBackPorch-2) >= POW2(9))
+		   || (par->vSyncOn >= POW2(13))
+		   || (par->vSyncOff >= POW2(13))
+		   || (par->vBackPorch >= POW2(9))
+		   || (par->tiles_in_X >= POW2(6))) {
+			eprintk ("Unsupported Timing\n");
+			return -EINVAL;
+		}
+	} else {
+		/* Voodoo limits */
+		if (par->vmode) {
+			eprintk("Interlace/Doublescan not supported %#x\n",
+				par->vmode);
+			return -EINVAL;
+		}
+		if(((par->xDim-1) >= POW2(10)) || (par->yDim >= POW2(10))) {
+			eprintk ("Unsupported resolution %dx%d\n",
+			         var->xres, var->yres);
+			return -EINVAL;
+		}
+		if (((par->hSyncOn-1) >= POW2(8))
+		   || ((par->hSyncOff-1) >= POW2(10))
+		   || ((par->hBackPorch-2) >= POW2(8))
+		   || (par->vSyncOn >= POW2(12))
+		   || (par->vSyncOff >= POW2(12))
+		   || (par->vBackPorch >= POW2(8))
+		   || (par->tiles_in_X >= POW2(4))) {
+			eprintk ("Unsupported Timings\n");
+			return -EINVAL;
+		}
+	}
+
 	/* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem*/
 	/* FIXME: i don't like this... looks wrong*/
-	real_length = par->tiles_in_X  * (sst_info->is_voodoo2 ? 32 : 64 )
+	real_length = par->tiles_in_X  * (IS_VOODOO2(sst_info) ? 32 : 64 )
 	              * ((par->bpp == 16) ? 2 : 4);
-/*shoud this function change var ? for instance with yvirt > yres  ?*/
 
-	if ((real_length * var->yres) > fb_info.video.len) {
+	if ((real_length * var->yres) > sst_info->video.len) {
 		eprintk ("Not enough video memory\n");
 		return -ENOMEM;
 	}
-
-	par->freq = PS2KHZ(var->pixclock);
-	
-	/* TODO add checks for timings */
+	par->valid=1;
 	return 0;
 }
 
@@ -685,7 +705,15 @@
 	var->lower_margin   = par->vSyncOff - par->yDim - par->vBackPorch;
 	var->hsync_len      = par->hSyncOn;
 	var->vsync_len      = par->vSyncOn;
-	var->vmode          = FB_VMODE_NONINTERLACED;
+	var->sync           = par->sync;
+	var->vmode          = par->vmode;
+	if (var->vmode & FB_VMODE_DOUBLE) {
+		var->yres           >>=1;
+		var->yres_virtual   >>=1;
+		var->vsync_len      >>=1;
+		var->upper_margin   >>=1;
+		var->lower_margin   >>=1;
+	}
 
 	/*
 	 * correct the color bit fields
@@ -732,14 +760,12 @@
 static int sstfb_open(struct fb_info *info, int user)
 {
 	f_dprintk("sstfb_open(user: %d)\n",user);
-	MOD_INC_USE_COUNT;
 	return 0;
 }
 
 static int sstfb_release(struct fb_info *info, int user)
 {
 	f_dprintk("sstfb_release(user: %d)\n",user);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -752,7 +778,7 @@
 
 	f_dprintk("sstfb_get_fix(con: %d)\n",con);
 	if (con == -1)
-		var = &sstfb_default;
+		sstfb_encode_var(var, &sst_info->current_par, sst_info);
 	else
 		var = &fb_display[con].var;
 
@@ -775,21 +801,23 @@
 static int sstfb_get_var(struct fb_var_screeninfo *var,
                          int con, struct fb_info *info)
 {
+#define sst_info	((struct sstfb_info *) info)
 	f_dprintk("sstfb_get_var(con: %d)\n",con);
 	if (con == -1)
-		*var = sstfb_default;
+		sstfb_encode_var(var, &sst_info->current_par, sst_info);
 	else
 		*var = fb_display[con].var;
 	print_var(var, "var");
 	return 0;
+#undef sst_info
  }
 
 static int sstfb_set_var(struct fb_var_screeninfo *var,
                          int con, struct fb_info *info)
 {
-#define sst_info	((struct sstfb_info *) info)	
+#define sst_info	((struct sstfb_info *) info)
 
-	struct sstfb_par par;	
+	struct sstfb_par par;
 	struct display *display;
 	int err;
 	int old_bpp,old_xres,old_yres;
@@ -800,15 +828,14 @@
 		 var->xres,var->yres,var->xres_virtual,var->yres_virtual,
 		 var->bits_per_pixel,var->activate);
 	if (con < 0)
-		display = &disp;
+		display = &sst_info->disp;
 	else
 		display = &fb_display[con];
 
-	err = sstfb_decode_var(var, &par, sst_info);
-	if (err)
+	if ((err = sstfb_decode_var(var, &par, sst_info)))
 		return err;
 	sstfb_encode_var (var, &par, sst_info);
-	
+
 	switch (var->activate & FB_ACTIVATE_MASK) {
 		case FB_ACTIVATE_TEST:
 			return 0;
@@ -838,7 +865,7 @@
 #ifdef FBCON_HAS_CFB16
 		case 16:
 			display->dispsw = &fbcon_cfb16;
-			display->dispsw_data = fbcon_cmap.cfb16;
+			display->dispsw_data = sst_info->fbcon_cmap.cfb16;
 			break;
 #endif
 #ifdef EN_24_32_BPP
@@ -846,7 +873,7 @@
 		case 24: /*24bpp non packed <=> 32 bpp */
 		case 32:
 			display->dispsw = &fbcon_cfb32;
-			display->dispsw_data = fbcon_cmap.cfb32;
+			display->dispsw_data = sst_info->fbcon_cmap.cfb32;
 			break;
 #endif
 #endif
@@ -864,7 +891,7 @@
 		}
 	}
 
-	if ((con <0) || (con==currcon)) {
+	if ((con == -1) || (con==sst_info->currcon)) {
 		sstfb_set_par (&par, sst_info);
 	}
 	print_var(var, "var");
@@ -884,34 +911,37 @@
 static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
                           int con, struct fb_info *info)
 {
+#define sst_info	((struct sstfb_info *) info)
 	struct display *d = (con<0) ? info->disp : fb_display + con;
 
 	f_dprintk("sstfb_set_cmap\n");
 	f_ddprintk("con: %d, currcon: %d, d->cmap.len %d\n",
-		 con, currcon, d->cmap.len);
+		 con, sst_info->currcon, d->cmap.len);
 
 	if (d->cmap.len != 16 ) {	/* or test if cmap.len == 0 ? */
 		int err;
 		err = fb_alloc_cmap(&d->cmap, 16, 0); /* cmap size=16 */
 		if (err) return err;
 	}
-	if (con == currcon) {
+	if (con == sst_info->currcon) {
 		return fb_set_cmap(cmap, kspc, sstfb_setcolreg, info);
 	} else {
 		fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);
 	}
 	return 0;
+#undef sst_info
 }
 
 static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
                           int con, struct fb_info *info)
 {
+#define sst_info	((struct sstfb_info *) info)
 	f_dprintk("sstfb_get_cmap\n");
 	f_ddprintk("con %d, curcon %d, cmap.len %d\n",
-		 con, currcon, fb_display[con].cmap.len);
+		 con, sst_info->currcon, fb_display[con].cmap.len);
 
 	/* FIXME: check if con = -1 ? cf sstfb_set_cmap...  */
-	if (con == currcon)
+	if (con == sst_info->currcon)
 		return fb_get_cmap(cmap, kspc, sstfb_getcolreg, info);
 	else if (fb_display[con].cmap.len)
 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
@@ -920,6 +950,7 @@
 			fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 			cmap, kspc ? 0 : 2);
 	return 0;
+#undef sst_info
 }
 
 /* TODO */
@@ -934,7 +965,7 @@
                        u_int cmd, u_long arg, int con,
                        struct fb_info *info)
 {
-#define sst_info	((struct sstfb_info *) info)	
+#define sst_info	((struct sstfb_info *) info)
 #if (SST_DEBUG_IOCTL >0)
 	int i;
 	u_long p;
@@ -981,11 +1012,10 @@
 		return 0;
 	case _IO('F', 0xde):		/* 0x46de */
 		f_dprintk("test color display\n");
-		f_ddprintk("currcon: %d, bpp %d\n",
-			  currcon, fb_display[currcon].var.bits_per_pixel);
+		f_ddprintk("currcon: %d, bpp %d\n", sst_info->currcon,
+			  sst_info->current_par.bpp);
 		memset_io(sst_info->video.vbase, 0, sst_info->video.len);
-	switch (fb_display[currcon].var.bits_per_pixel) {
-/* FIXME broken : if we call this ioctl from a tty not bound to the fb, we use its depth and not the current one ... */
+	switch (sst_info->current_par.bpp) {
 	       	case 16:
 			sstfb_test16(sst_info);
 			break;
@@ -997,7 +1027,7 @@
 #  endif
 		default:
 			dprintk("bug line %d: bad depth '%u'\n", __LINE__,
-			        fb_display[currcon].var.bits_per_pixel);
+			        sst_info->current_par.bpp);
 			}
 		return 0;
 	}
@@ -1013,9 +1043,9 @@
 
 /* get lfb size */
 
-static int sst_get_memsize(u_long *memsize)
+static int __devinit sst_get_memsize(struct sstfb_info *sst_info, u_long *memsize)
 {
-	u32 fbbase_virt = fb_info.video.vbase;
+	u_long fbbase_virt = sst_info->video.vbase;
 	f_dprintk("sst_get_memsize\n");
 
 	/* force memsize */
@@ -1058,13 +1088,13 @@
  * in a row a "idle" answer to our requests
  */
 
-static int sst_wait_idle(void)
+static int __sst_wait_idle(u_long vbase)
 {
 	int count = 0;
 
 	f_ddprintk("sst_wait_idle\n");
 	while(1) {
-		if (sst_read(STATUS) & STATUS_FBI_BUSY) {
+		if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) {
 			f_dddprintk("status: busy\n");
 /* FIXME basicaly, this is a busy wait. maybe not that good. oh well; this is a small loop after all ...*/
 			count = 0;
@@ -1073,6 +1103,7 @@
 			f_dddprintk("status: idle(%d)\n", count);
 		}
 		if (count >= 5) return 1;
+//XXX  do something to avoid hanging the machine if the voodoo is out
 	}
 }
 
@@ -1082,25 +1113,25 @@
  * dram refresh disabled, FbiInit remaped.
  * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ...
  */
-static int __init sst_detect_dactype(void)
+static int __devinit sst_detect_dactype(struct sstfb_info * sst_info)
 {
 	int ret=0,i;
 	f_dprintk("sst_detect_dactype\n");
 	for (i=0; i< sizeof(dacs)/sizeof(dacs[0]) ; i++) {
-		ret = dacs[i].detect();
+		ret = dacs[i].detect(sst_info);
 		if (ret) break;
 	}
 	if (!ret)
 		return 0;
 	f_dprintk("found %s\n", dacs[i].name);
-	fb_info.dac_sw=&dacs[i];
+	sst_info->dac_sw=dacs[i];
 	return 1;
 }
 
 /* fbi should be idle, and fifo emty and mem disabled */
 /* supposed to detect AT&T ATT20C409 and Ti TVP3409 ramdacs */
 
-static int __init (sst_detect_att(void))
+static int __devinit sst_detect_att(struct sstfb_info * sst_info)
 {
 	int i, mir, dir;
 
@@ -1125,7 +1156,7 @@
 	return 0;
 }
 
-static int __init (sst_detect_ti(void))
+static int __devinit sst_detect_ti(struct sstfb_info * sst_info)
 {
 	int i, mir, dir;
 
@@ -1161,7 +1192,7 @@
  * touched...
  * is it realy safe ? how can i reset this ramdac ? geee...
  */
-static int __init sst_detect_ics(void)
+static int __devinit sst_detect_ics(struct sstfb_info * sst_info)
 {
 	int i;
 	int m_clk0_1, m_clk0_7, m_clk1_b;
@@ -1247,7 +1278,7 @@
  * see detect_dac
  */
 
-static int sst_set_pll_att_ti(const struct pll_timing *t, const int clock)
+static int sst_set_pll_att_ti(struct sstfb_info * sst_info, const struct pll_timing *t, const int clock)
 {
 	u8 cr0, cc;
 	f_dprintk("sst_set_pll_att_ti\n");
@@ -1301,7 +1332,7 @@
 	return 1;
 }
 
-static int sst_set_pll_ics(const struct pll_timing *t, const int clock)
+static int sst_set_pll_ics(struct sstfb_info * sst_info, const struct pll_timing *t, const int clock)
 {
 	u8 pll_ctrl;
 
@@ -1341,11 +1372,9 @@
 
 static int sstfb_set_par(const struct sstfb_par * par, struct sstfb_info * sst_info)
 {
-	u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit6=0;
+	u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0;
 	int ntiles;
-	struct pll_timing pll;
-	int fout;
-	struct pci_dev  * sst_dev = sst_info->dev;
+	struct pci_dev * sst_dev = sst_info->dev;
 
 	f_dprintk("sst_set_par(%dx%d)\n", par->xDim, par->yDim);
 	f_ddprintk("hSyncOn hSyncOff vSyncOn vSyncOff\n");
@@ -1357,9 +1386,10 @@
 	           par->hBackPorch, par->vBackPorch,
 	           par->xDim, par->yDim, par->freq);
 
-
-	sst_calc_pll (par->freq, &fout, &pll);
-
+	if (!par->valid) {
+		BUG();
+		return -1;
+	}
 	sst_write(NOPCMD, 0);
 	sst_wait_idle();
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
@@ -1370,10 +1400,10 @@
 
 	/*sst_unset_bits (FBIINIT0, FBI_RESET); / reenable FBI ? */
 
-	sst_write(BACKPORCH,       par->vBackPorch << 16 | (par->hBackPorch-2));
-	sst_write(VIDEODIMENSIONS, (par->yDim - 1) << 16 | (par->xDim - 1));
-	sst_write(HSYNC,         (par->hSyncOff-1) << 16 | (par->hSyncOn-1));
-	sst_write(VSYNC,             par->vSyncOff << 16 | par->vSyncOn);
+	sst_write(BACKPORCH, par->vBackPorch << 16 | (par->hBackPorch - 2));
+	sst_write(VIDEODIMENSIONS, par->yDim << 16 | (par->xDim - 1));
+	sst_write(HSYNC, (par->hSyncOff - 1) << 16 | (par->hSyncOn - 1));
+	sst_write(VSYNC,       par->vSyncOff << 16 | par->vSyncOn);
 
 	fbiinit2=sst_read(FBIINIT2);
 	fbiinit3=sst_read(FBIINIT3);
@@ -1382,12 +1412,15 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                       PCI_EN_INIT_WR | PCI_REMAP_DAC );
 
-	sst_info->dac_sw->set_vidmod(par->bpp);
+	sst_info->dac_sw.set_vidmod(sst_info, par->bpp);
+
 	/* set video clock */
-	sst_info->dac_sw->set_pll(&pll, VID_CLOCK);
+	sst_info->dac_sw.set_pll(sst_info, &par->pll, VID_CLOCK);
+
 	/* disable fbiinit2/3 remap */
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                       PCI_EN_INIT_WR);
+
 	/* restore fbiinit2/3 */
 	sst_write(FBIINIT2,fbiinit2);
 	sst_write(FBIINIT3,fbiinit3);
@@ -1410,7 +1443,7 @@
 */
 
 	ntiles = par->tiles_in_X;
-	if (sst_info->is_voodoo2) {
+	if (IS_VOODOO2(sst_info)) {
 		fbiinit1 |= ((ntiles & 0x20) >> 5) << TILES_IN_X_MSB_SHIFT
 		            | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT ;
 /* as the only value of importance for us in fbiinit6 is tiles in X (lsb),
@@ -1440,8 +1473,19 @@
 		break;
 	}
 	sst_write(FBIINIT1, fbiinit1);
-	if (sst_info->is_voodoo2)
+	if (IS_VOODOO2(sst_info)) {
 		sst_write(FBIINIT6, fbiinit6);
+		fbiinit5=sst_read(FBIINIT5) & FBIINIT5_MASK ;
+		if (par->vmode & FB_VMODE_INTERLACED)
+			fbiinit5 |= INTERLACE;
+		if (par->vmode & FB_VMODE_DOUBLE )
+			fbiinit5 |= VDOUBLESCAN;
+		if (par->sync & FB_SYNC_HOR_HIGH_ACT)
+			fbiinit5 |= HSYNC_HIGH;
+		if (par->sync & FB_SYNC_VERT_HIGH_ACT)
+			fbiinit5 |= VSYNC_HIGH;
+		sst_write(FBIINIT5, fbiinit5);
+	}
 	sst_wait_idle();
 	sst_unset_bits(FBIINIT1, VIDEO_RESET);
 	sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
@@ -1484,9 +1528,6 @@
 		f_ddprintk("setting clipping dimensions 0..%d, 0..%d\n",
 		            par->xDim-1, par->yDim-1);
 
-/* warning the fields are 9bits wide on voodoo1 , 11 (or 10) on voodoo2,
-   make sure we check the values before playing with the registers.. */
-
 		sst_write(CLIP_LEFT_RIGHT, par->xDim );
 		sst_write(CLIP_LOWY_HIGHY, par->yDim );
 		sst_set_bits(FBZMODE, EN_CLIPPING | EN_RGB_WRITE);
@@ -1499,7 +1540,7 @@
 	return 1;
 }
 
-static void sst_set_vidmod_att_ti(const int bpp)
+static void sst_set_vidmod_att_ti(struct sstfb_info * sst_info, const int bpp)
 {
 	u8 cr0;
 
@@ -1535,7 +1576,7 @@
 	}
 }
 
-static void sst_set_vidmod_ics(const int bpp)
+static void sst_set_vidmod_ics(struct sstfb_info * sst_info, const int bpp)
 {
 	f_dprintk("sst_set_vidmod_ics(bpp: %d)\n", bpp);
 	switch(bpp) {
@@ -1554,14 +1595,15 @@
 	}
 }
 
-static int __init sst_init(void)
+static int __devinit sst_init(struct sstfb_info *sst_info)
 {
 	struct pll_timing gfx_timings;
+	struct sst_spec * spec;
+	struct pci_dev * sst_dev = sst_info->dev;
 	int Fout;
-	int dac_ok;
 	u32 fbiinit0, fbiinit1, fbiinit4;
-	struct pci_dev * sst_dev = fb_info.dev; /* or define a macro ?*/
 
+	spec = &voodoo_spec[sst_info->type];
 	f_dprintk("sst_init\n");
 	f_ddprintk(" fbiinit0   fbiinit1   fbiinit2   fbiinit3   fbiinit4  "
 	           " fbiinit6\n");
@@ -1594,25 +1636,24 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                               PCI_EN_INIT_WR | PCI_REMAP_DAC );
 	/* detect dac type */
-	dac_ok = sst_detect_dactype();
-	if (!dac_ok) {
+	if (!sst_detect_dactype(sst_info)) {
 		eprintk("Unknown dac type\n");
+		//FIXME watch it : we are not in a safe state , bad bad bad .
 		return 0;
 	}
 
 	/* set graphic clock */
-	if (dac_ok) {
-		fb_info.gfx_clock = fb_info.spec->default_gfx_clock;
-		if ((gfxclk >10 ) && (gfxclk < fb_info.spec->max_gfxclk)) {
-			iprintk ("Using supplied graphic freq : %dMHz\n", gfxclk);
-			 fb_info.gfx_clock = gfxclk *1000;
-		} else if (gfxclk) {
-			wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk);
-		}
-
-		sst_calc_pll(fb_info.gfx_clock, &Fout, &gfx_timings);
-		fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);
+	sst_info->gfx_clock = spec->default_gfx_clock;
+	if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
+		iprintk ("Using supplied graphic freq : %dMHz\n", gfxclk);
+		 sst_info->gfx_clock = gfxclk *1000;
+	} else if (gfxclk) {
+		wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk);
 	}
+
+	sst_calc_pll(sst_info->gfx_clock, &Fout, &gfx_timings);
+	sst_info->dac_sw.set_pll(sst_info, &gfx_timings, GFX_CLOCK);
+
 	/* disable fbiinit remap */
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                       PCI_EN_INIT_WR| PCI_EN_FIFO_WR );
@@ -1642,7 +1683,7 @@
 	sst_wait_idle();
 	sst_write(FBIINIT4, fbiinit4);
 	sst_wait_idle();
-	if (fb_info.is_voodoo2) {
+	if (IS_VOODOO2(sst_info)) {
 		sst_write(FBIINIT6, FBIINIT6_DEFAULT);
 		sst_wait_idle();
 	}
@@ -1650,16 +1691,14 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR );
 	pci_write_config_dword(sst_dev, PCI_VCLK_ENABLE, 0);
 
-	return dac_ok;
+	return 1;
 }
 
-#ifdef MODULE
-
-static void  __exit sst_shutdown(void)
+static void  __devexit sst_shutdown(struct sstfb_info *sst_info)
 {
+	struct pci_dev * sst_dev = sst_info->dev;
 	struct pll_timing gfx_timings;
 	int Fout;
-	struct pci_dev * sst_dev = fb_info.dev;
 
 	f_dprintk("sst_shutdown\n");
 	/* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */
@@ -1672,7 +1711,7 @@
 	                       PCI_EN_INIT_WR | PCI_REMAP_DAC );
 	/*set 20Mhz gfx clock */
 	sst_calc_pll(20000, &Fout, &gfx_timings);
-	fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);
+	sst_info->dac_sw.set_pll(sst_info, &gfx_timings, GFX_CLOCK);
 	/* TODO maybe shutdown the dac, vrefresh and so on... */
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 	                       PCI_EN_INIT_WR);
@@ -1682,7 +1721,6 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 0);
 
 }
-#endif /* MODULE */
 
 /*
  * Interface to the world
@@ -1697,7 +1735,9 @@
 	if (!options || !*options)
 		return 0;
 
-	while ((this_opt = strsep(&options, ",")) != NULL) {
+	for(this_opt = strtok(options, ","); this_opt;
+		this_opt = strtok(NULL, ",")) { //XXX
+//XXX	while ((this_opt = strsep(&options, ",")) != NULL) {
 		if (!*this_opt) continue;
 
 		f_ddprintk("option %s\n", this_opt);
@@ -1730,116 +1770,173 @@
 	return 0;
 }
 
-int __init sstfb_init(void)
+int __devinit sstfb_init(void)
 {
-	struct pci_dev * pdev;
-	struct fb_var_screeninfo var;
-#define sst_dev	(fb_info.dev)
 	f_dprintk("sstfb_init\n");
 	dprintk("Compile date: "__DATE__" "__TIME__"\n");
+	return pci_module_init(&sstfb_driver);
+}
 
-	memset (&fb_info, 0, sizeof(fb_info));
-	pci_for_each_dev(pdev) {
-		if (pdev->vendor != PCI_VENDOR_ID_3DFX) continue;
-		if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO) {
-			fb_info.is_voodoo2=0;
-			fb_info.spec=&voodoo1_spec;
-		}
-		else if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO2) {
-			fb_info.is_voodoo2=1;
-			fb_info.spec=&voodoo2_spec;
-		}
-		else
-			continue;
-		if (dev > 0) {
-			dev--;
-			continue;
-		}
-		f_ddprintk("found device : %s\n", fb_info.spec->name);
-		fb_info.dev = pdev;
-		fb_info.mmio.base = sst_dev->resource[0].start;
-		pci_read_config_byte(sst_dev,
-		                     PCI_REVISION_ID, &fb_info.revision);
-
-		fb_info.mmio.vbase = (u32) ioremap_nocache(fb_info.mmio.base, 0x400000);
-		if (!fb_info.mmio.vbase) {
-			eprintk("cannot remap register area %#lx\n",
-			        fb_info.mmio.base);
-			return -ENXIO;
-		}
-		fb_info.video.base = fb_info.mmio.base+0x400000;
-		fb_info.video.vbase = (u32) ioremap_nocache(fb_info.video.base,
-					            0x400000);
-		if (!fb_info.video.vbase) {
-			eprintk("cannot remap framebuffer %#lx\n",
-			        fb_info.video.base);
-			iounmap((void*) fb_info.mmio.vbase);
-			return -ENXIO;
-		}
-		if(!sst_init()) {
-			eprintk("Init failed\n");
-			iounmap((void*)fb_info.mmio.vbase);
-			iounmap((void*)fb_info.video.vbase);
-			return -ENXIO;
-		}
-		sst_get_memsize(&fb_info.video.len);
-		fb_info.configured = 1;
-		strncpy(fb_info.info.modename, fb_info.spec->name, 16);
-
-		iprintk("%s with %s dac\n", fb_info.info.modename, fb_info.dac_sw->name);
-		iprintk("framebuffer at %#lx, mapped to %#lx,"
-		        " size %ldMb\n",
-		        fb_info.video.base, fb_info.video.vbase,
-		        fb_info.video.len >> 20);
-
-		f_ddprintk("revision: %d\n", fb_info.revision);
-		f_ddprintk("regbase_virt: %#lx\n", fb_info.mmio.vbase);
-		f_ddprintk("membase_phys: %#lx\n", fb_info.video.base);
-		f_ddprintk("fbbase_virt: %#lx\n", fb_info.video.vbase);
-
-		fb_info.info.node       = -1 ;
-		fb_info.info.flags      = FBINFO_FLAG_DEFAULT;
-		fb_info.info.fbops      = &sstfb_ops;
-		fb_info.info.disp       = &disp;
-		fb_info.info.changevar  = NULL;
-		fb_info.info.switch_con = &sstfbcon_switch;
-		fb_info.info.updatevar  = &sstfbcon_updatevar;
-		fb_info.info.blank      = &sstfbcon_blank;
-		if ( !mode_option &&
-	             !fb_find_mode(&var, &fb_info.info, mode_option,
-		                   NULL, 0, NULL, 16)) {
-			var = sstfb_default;
-		}
-		if (sstfb_set_var(&var, -1, &fb_info.info)) {
+void __devexit sstfb_exit(void)
+{
+	f_dprintk("sstfb_exit\n");
+	pci_unregister_driver(&sstfb_driver);
+}
+
+#ifdef MODULE
+module_init(sstfb_init);
+module_exit(sstfb_exit);
+#endif
+
+static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct fb_var_screeninfo var;
+	struct sstfb_info * sst_info;
+	struct sst_spec * spec;
+	int tmp,err;
+	f_dprintk("sstfb_probe\n");
+
+	/* dev >  0  the device is not the one asked for.   skip */
+	/* dev == 0  this is the device the user asked.     init */
+	/* dev == -1 we already inited the asked device.    skip */
+	/* dev < -1  init all devices. including this one.  init */
+	if ((dev == -1 ) || (dev-- > 0))
+		return -1;
+
+	if ((err=pci_enable_device(pdev))) {
+		eprintk("cannot enable device\n");
+		return err;
+	}
+
+	sst_info = (struct sstfb_info*)kmalloc(sizeof(*sst_info), GFP_KERNEL);
+	if (!sst_info)
+		goto fail_kmalloc;
+	pci_set_drvdata(pdev, sst_info);
+	sst_info->type = id->driver_data;
+	spec = &voodoo_spec[sst_info->type];
+	f_ddprintk("found device : %s\n", spec->name);
+
+	sst_info->dev = pdev;
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &sst_info->revision);
+
+	sst_info->mmio.base = pci_resource_start(pdev,0);
+	sst_info->video.base = sst_info->mmio.base+0x400000;
+
+	if (!request_mem_region(sst_info->mmio.base,0x400000,"sstfb MMIO")) {
+		eprintk ("cannot reserve mmio memory\n");
+		goto fail_mmio_mem;
+	}
+
+	if (!request_mem_region(sst_info->video.base,0x400000,"sstfb FB")) {
+		eprintk ("cannot reserve fb memory\n");
+		goto fail_fb_mem;
+	}
+
+	sst_info->mmio.vbase = (u_long) ioremap_nocache(sst_info->mmio.base, 0x400000);
+	if (!sst_info->mmio.vbase) {
+		eprintk("cannot remap register area %#lx\n",
+		        sst_info->mmio.base);
+		goto fail_mmio_remap;
+	}
+	sst_info->video.vbase = (u_long) ioremap_nocache(sst_info->video.base, 0x400000);
+	if (!sst_info->video.vbase) {
+		eprintk("cannot remap framebuffer %#lx\n",
+		        sst_info->video.base);
+		goto fail_fb_remap;
+	}
+
+	if(!sst_init(sst_info)) {
+		eprintk("Init failed\n");
+		goto fail;
+	}
+	sst_get_memsize(sst_info, &sst_info->video.len);
+	strncpy(sst_info->info.modename, spec->name, 16);
+
+	iprintk("%s with %s dac\n", sst_info->info.modename, sst_info->dac_sw.name);
+	iprintk("framebuffer at %#lx, mapped to %#lx,"
+	        " size %ldMb\n",
+	        sst_info->video.base, sst_info->video.vbase,
+	        sst_info->video.len >> 20);
+
+	f_ddprintk("revision: %d\n", sst_info->revision);
+	f_ddprintk("regbase_virt: %#lx\n", sst_info->mmio.vbase);
+	f_ddprintk("membase_phys: %#lx\n", sst_info->video.base);
+	f_ddprintk("fbbase_virt: %#lx\n", sst_info->video.vbase);
+
+	sst_info->info.node       = -1 ;
+	sst_info->info.flags      = FBINFO_FLAG_DEFAULT;
+	sst_info->info.fbops      = &sstfb_ops;
+	sst_info->info.disp       = &sst_info->disp;
+	sst_info->info.changevar  = NULL;
+	sst_info->info.switch_con = &sstfbcon_switch;
+	sst_info->info.updatevar  = &sstfbcon_updatevar;
+	sst_info->info.blank      = &sstfbcon_blank;
+
+	tmp=0;
+	var = sstfb_default;
+	if ( mode_option  &&
+	     fb_find_mode(&var, &sst_info->info, mode_option,
+	                   NULL, 0, NULL, 16)) {
+		if (sstfb_set_var(&var, -1, &sst_info->info)) {
 			eprintk("can't set supplied video mode. Using default\n");
 			var = sstfb_default;
-			if (sstfb_set_var(&var, -1, &fb_info.info)) {
-				eprintk("can't set default video mode.\n");
-				return -ENXIO;
-			}
-		}
-		/*clear fb */
-		memset_io(fb_info.video.vbase, 0, fb_info.video.len);
-		/* print some squares ... */
-		sstfb_test16(&fb_info); /* FIXME this is only for 16bpp */
-
-		/* register fb */
-		if (register_framebuffer(&fb_info.info) < 0) {
-			eprintk("can't register framebuffer.\n");
-			return -ENXIO;
+		} else {
+			/* set the new default */
+			sstfb_default = var;
+			tmp=1;  /* no need to set the mode. */
 		}
-		printk(KERN_INFO "fb%d: %s frame buffer device\n",
-		       GET_FB_IDX(fb_info.info.node),fb_info.info.modename);
+	}
 
-		num_sst++;
+	if (!tmp && sstfb_set_var(&var, -1, &sst_info->info)) {
+		eprintk("can't set default video mode.\n");
+		goto fail;
+	}
+	/*clear fb */
+	memset_io(sst_info->video.vbase, 0, sst_info->video.len);
+	/* print some squares ... */
+	sstfb_test16(sst_info); /* FIXME this is only for 16bpp */
 
-		if (dev <= 0)	/* we use the first card only for now (==0) */
-			return 0;
+	/* register fb */
+	if (register_framebuffer(&sst_info->info) < 0) {
+		eprintk("can't register framebuffer.\n");
+		goto fail;
 	}
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+	       GET_FB_IDX(sst_info->info.node),sst_info->info.modename);
+
+	return 0;
+
+fail:
+	iounmap((void *)sst_info->video.base);
+fail_fb_remap:
+	iounmap((void *)sst_info->mmio.base);
+fail_mmio_remap:
+	release_mem_region(sst_info->video.base,0x400000);
+fail_fb_mem:
+	release_mem_region(sst_info->mmio.base,0x400000);
+fail_mmio_mem:
+	kfree(sst_info);
+fail_kmalloc:
 	return -ENXIO; 	/* no voodoo detected */
-#undef sst_dev
 }
 
+static void __devexit sstfb_remove(struct pci_dev *pdev)
+{
+	struct sstfb_info * sst_info;
+
+	f_dprintk("sstfb_remove\n");
+	sst_info=pci_get_drvdata(pdev);
+	sst_shutdown(sst_info);
+
+	unregister_framebuffer(&sst_info->info);
+	iounmap((void*)sst_info->video.vbase);
+	iounmap((void*)sst_info->mmio.vbase);
+	release_mem_region(sst_info->video.base,0x400000);
+	release_mem_region(sst_info->mmio.base,0x400000);
+	kfree(sst_info);
+}
+
+
 /*
  * console driver
  */
@@ -1849,15 +1946,15 @@
 	struct sstfb_par par;
 
 	f_dprintk("sstfbcon_switch(con: %d)\n",con);
-	f_ddprintk("currcon: %d\n", currcon);
-	v_dprintk("currcon: %d\n", currcon);
+	f_ddprintk("currcon: %d\n", sst_info->currcon);
+	v_dprintk("currcon: %d\n", sst_info->currcon);
 
-	if (currcon >=  0) {
-		if (fb_display[currcon].cmap.len)
-			fb_get_cmap(&fb_display[currcon].cmap, 1,
+	if (sst_info->currcon >=  0) {
+		if (fb_display[sst_info->currcon].cmap.len)
+			fb_get_cmap(&fb_display[sst_info->currcon].cmap, 1,
 			            sstfb_getcolreg, info);
 	}
-	currcon = con;
+	sst_info->currcon = con;
 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
 
 	print_var(&fb_display[con].var, "&fb_display[con: %d].var",con);
@@ -1930,7 +2027,7 @@
 {
 	int i,j;
 	u_long p;
-	u32 fbbase_virt = sst_info->video.vbase;
+	u_long fbbase_virt = sst_info->video.vbase;
 
 	f_dprintk("sstfb_test32\n");
 	/* rect blanc 20x100+200+0 */
@@ -1968,31 +2065,7 @@
 }
 #endif /* EN_24_32_BPP */
 
-#ifdef MODULE
-
-int init_module(void)
-{
-	f_dprintk("init_module\n");
-	sstfb_init();
-	if (num_sst == 0 )
-		return -ENXIO;
-	return 0;
-}
-
-void cleanup_module(void)
-{
-	f_dprintk("cleanup_module\n");
-	f_ddprintk("conf %d\n",fb_info.configured);
-
-	if (fb_info.configured) {
-		sst_shutdown();
-		iounmap((void*)fb_info.mmio.vbase);
-		iounmap((void*)fb_info.video.vbase);
-		unregister_framebuffer(&fb_info.info);
-	}
-}
-
-MODULE_AUTHOR("(c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>");
+MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");
 MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
 MODULE_LICENSE("GPL");
 
@@ -2010,7 +2083,6 @@
 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
 MODULE_PARM(dev,"i");
 MODULE_PARM_DESC(dev , "Attach to device ID (0..n) (default=1st device)");
-#endif	/* MODULE */
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
@@ -2021,12 +2093,12 @@
  */
 
 #if 0
-void Dump_regs ( void)
+void __Dump_regs (struct sstfb_info * sst_info)
 {
 	struct { u32 reg ; char * reg_name;}  pci_regs [] =  {
 		{ PCI_INIT_ENABLE, "initenable"},
-		{ PCI_VCLK_ENABLE, "enable vclk"}, 
-		{ PCI_VCLK_DISABLE, "disable vclk"}, 
+		{ PCI_VCLK_ENABLE, "enable vclk"},
+		{ PCI_VCLK_DISABLE, "disable vclk"},
 	};
 
 	struct { u32 reg ; char * reg_name;}  sst_regs [] =  {
@@ -2041,25 +2113,27 @@
 		{LFBMODE,"lfbmode"},
 		{FBZMODE,"fbzmode"},
 	};
-	u32 pci_res[sizeof(pci_regs)/sizeof(pci_regs[0])];
-	u32 sst_res[sizeof(sst_regs)/sizeof(sst_regs[0])];
+	int pci_s = sizeof(pci_regs)/sizeof(*pci_regs);
+	int sst_s = sizeof(sst_regs)/sizeof(*sst_regs);
+	u32 pci_res[pci_s];
+	u32 sst_res[sst_s];
 
-	struct pci_dev * dev = fb_info.dev;
+	struct pci_dev * dev = sst_info->dev;
 
 	int i;
 
-	for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {
+	for (i=0; i < pci_s ; i++ ) {
 		pci_read_config_dword ( dev, pci_regs[i].reg , &pci_res[i]) ;
 	}
-	for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {
+	for (i=0; i < sst_s ; i++ ) {
 		sst_res[i]=sst_read(sst_regs[i].reg);
 	}
 
 	dprintk ("Dump regs\n");
-	for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {
+	for (i=0; i < pci_s ; i++ ) {
 		dprintk("%s = %0#10x\n", pci_regs[i].reg_name , pci_res[i]) ;
 	}
-	for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {
+	for (i=0; i < sst_s ; i++ ) {
 		dprintk("%s = %0#10x\n", sst_regs[i].reg_name , sst_res[i]) ;
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/sstfb.h linux/drivers/video/sstfb.h
--- linux.orig/drivers/video/sstfb.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/video/sstfb.h	2002-07-20 01:08:25.000000000 +0000
@@ -11,7 +11,7 @@
 
 #ifndef _SSTFB_H_
 #define _SSTFB_H_
- 
+
 /*
  *
  *  Debug Stuff
@@ -72,9 +72,10 @@
 #define iprintk(X...)	printk(KERN_INFO "sstfb: " X)
 #define wprintk(X...)	printk(KERN_WARNING "sstfb: " X)
 
-#define BIT(x)		(1ul << (x))
+#define BIT(x)		(1ul<<(x))
 #define PS2KHZ(a)	(1000000000UL/(a))	/* picoseconds to KHz */
 #define KHZ2PS(a)	(1000000000UL/(a))
+#define POW2(x)		(1ul<<(x))
 
 #ifndef ABS
 # define ABS(x)		(((x)<0)?-(x):(x))
@@ -170,9 +171,15 @@
 #define DAC_DATA		0x022c
 #  define DAC_READ_CMD		  BIT(11)	/* set read dacreg mode */
 #define FBIINIT5		0x0244		/* v2 specific */
+#  define FBIINIT5_MASK		  0xfa40ffff    /* mask video bits*/
+#  define HDOUBLESCAN		  BIT(20)
+#  define VDOUBLESCAN		  BIT(21)
+#  define HSYNC_HIGH 		  BIT(23)
+#  define VSYNC_HIGH 		  BIT(24)
+#  define INTERLACE		  BIT(26)
 #define FBIINIT6		0x0248		/* v2 specific */
-#define FBIINIT7		0x024c		/* v2 specific */
 #  define TILES_IN_X_LSB_SHIFT	  30		/* v2 */
+#define FBIINIT7		0x024c		/* v2 specific */
 
 /* Dac Registers */
 #define DACREG_WMA		0x0	/* pixel write mode address */
@@ -275,30 +282,32 @@
  */
 
 /* used to know witch clock to set */
-#define VID_CLOCK	0
-#define GFX_CLOCK	1
+enum {
+	VID_CLOCK=0,
+	GFX_CLOCK=1,
+};
 
 /* freq max */
 #define DAC_FREF	14318	/* DAC reference freq (Khz) */
 #define VCO_MAX		260000
 
 /*
- *
- *  Declarations
- *
+ *  driver structs
  */
 
 struct pll_timing {
-	u8 m;
-	u8 n;
-	u8 p;
+	unsigned int m;
+	unsigned int n;
+	unsigned int p;
 };
 
+struct sstfb_info;
+
 struct dac_switch {
 	char * name;
-	int (*detect) (void);
-	int (*set_pll) (const struct pll_timing *t, const int clock);
-	void (*set_vidmod) (const int bpp);
+	int (*detect) (struct sstfb_info *sst_info);
+	int (*set_pll) (struct sstfb_info *sst_info, const struct pll_timing *t, const int clock);
+	void (*set_vidmod) (struct sstfb_info *sst_info, const int bpp);
 };
 
 struct sst_spec {
@@ -317,8 +326,12 @@
 	unsigned int vSyncOn;
 	unsigned int vSyncOff;
 	unsigned int vBackPorch;
-	unsigned int freq;	/* freq in picoseconds */
-	unsigned int tiles_in_X; /* num of tiles in X res */
+	unsigned int freq;	/* freq in kHz */
+	struct pll_timing pll;
+	unsigned int tiles_in_X;/* num of tiles in X res */
+	unsigned int vmode;     /* doublescan/interlaced */
+	unsigned int sync;      /* H/V sync polarity */
+	unsigned int valid;	/* par is correct (fool proof) */
 };
 
 struct sstfb_info {
@@ -336,18 +349,34 @@
 		unsigned long	vbase;
 	} mmio;				/* registers memory info */
 
-	struct dac_switch *	dac_sw;	/* dac specific functions */
-	struct sst_spec *	spec;
+	struct dac_switch 	dac_sw;	/* dac specific functions */
 
-	int	is_voodoo2;
+	int	type;
 	u8	revision;
 
 	/* status */
-	int	configured;
-/*	int	indexed_mode;
+/*XXX	int	configured;
+	int	indexed_mode;
 	int	vgapass;
 	int	clipping; */
 	int	gfx_clock;
+
+	int	currcon;
+	struct display  	disp; /* current display */
+	struct { u_int red, green, blue, transp; } palette[16];
+
+	union {
+#ifdef FBCON_HAS_CFB16
+		u16 cfb16[16];
+#endif
+#ifdef EN_24_32_BPP
+#if defined (FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
+		u32 cfb32[16];
+#endif
+#endif
+	} fbcon_cmap;
+
 };
 
+
 #endif /* _SSTFB_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/tridentfb.c linux/drivers/video/tridentfb.c
--- linux.orig/drivers/video/tridentfb.c	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/tridentfb.c	2002-07-20 01:08:36.000000000 +0000
@@ -1,24 +1,18 @@
 /*
  * Frame buffer driver for Trident Blade and Image series
  *
- * Copyright 2001,2002 - Jani Monoses   <jani@astechnix.ro>
+ * Copyright 2001,2002 - Jani Monoses   <jani@iv.ro>
  *
- * $Id: tridentfb.c,v 1.2 2002/02/13 17:44:14 marcelo Exp $
  *
  * CREDITS:(in order of appearance)
  * 	skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
  * 	Special thanks ;) to Mattia Crivellini <tia@mclink.it>
- * 	much inspired by the XFree86 4.1.0 Trident driver sources by Alan Hourihane
+ * 	much inspired by the XFree86 4.x Trident driver sources by Alan Hourihane
  * 	the FreeVGA project
  *	Francesco Salvestrini <salvestrini@users.sf.net> XP support,code,suggestions
- * NOTES:
- * 	Tested on Compaq Presario 12XL300 with CyberBladei1
- * 	Tested on Toshiba 1800-514 with CyberBladeXPAi1
- * 	No monitors were harmed during the writing of this driver
  * TODO:
  * 	timing value tweaking so it looks good on every monitor in every mode
- * 	test text acceleration for the Image series
- *	test DPMS stuff
+ *	TGUI acceleration	
  */
 
 #include <linux/config.h>
@@ -35,7 +29,7 @@
 
 #include "tridentfb.h"
 
-#define VERSION		"0.6.8"
+#define VERSION		"0.7.5"
 
 struct tridentfb_par {
 	struct fb_var_screeninfo var;
@@ -69,6 +63,7 @@
 	unsigned int io_virt;		//iospace virtual memory address
 	unsigned int nativex;		//flat panel xres
 	struct tridentfb_par currentmode;
+	unsigned char eng_oper;		//engine operation...
 };
 
 static struct fb_ops tridentfb_ops;
@@ -82,15 +77,13 @@
 
 static char * tridentfb_name = "Trident";
 
-static int family;
-static int pci_id;
+static int chip_id;
 
 static int defaultaccel;
 static int displaytype;
 
 static int pseudo_pal[16];
 
-
 /* defaults which are normally overriden by user values */
 
 /* video mode */
@@ -98,7 +91,6 @@
 static int bpp = 8;
 
 static int noaccel;
-static int accel;
 
 static int center;
 static int stretch;
@@ -116,14 +108,25 @@
 MODULE_PARM(center,"i");
 MODULE_PARM(stretch,"i");
 MODULE_PARM(noaccel,"i");
-MODULE_PARM(accel,"i");
 MODULE_PARM(memsize,"i");
 MODULE_PARM(memdiff,"i");
 MODULE_PARM(nativex,"i");
 MODULE_PARM(fp,"i");
 MODULE_PARM(crt,"i");
 
-
+static int chip3D;
+int is3Dchip(int id)
+{
+	return 	((id == BLADE3D) || (id == CYBERBLADEE4) ||
+		 (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
+		 (id == CYBER9397) || (id == CYBER9397DVD) ||
+		 (id == CYBER9520) || (id == CYBER9525DVD) ||
+		 (id == IMAGE975) || (id == IMAGE985) ||
+		 (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) ||
+		 (id ==	CYBERBLADEAi1) || (id == CYBERBLADEAi1D) ||
+		 (id ==	CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) ||
+		 (id ==	CYBERBLADEXPAi1));
+}
 
 #define CRT 0x3D0		//CRTC registers offset for color display
 
@@ -150,9 +153,10 @@
 #define writemmr(r,v)	writel(v, fb_info.io_virt + r)
 #define readmmr(r)	readl(fb_info.io_virt + r)
 
+
+
 /*
- * Blade specific acceleration.Not XP's though those are
- * unaccelerated.
+ * Blade specific acceleration.
  */
 
 #define point(x,y) ((y)<<16|(x))
@@ -215,7 +219,7 @@
 	d1 = point(x2,y2);
 	d2 = point(x2+w-1,y2+h-1);
 
-	if ((y1 > y2) || ((y1 == y2) && (x1 >x2)))
+	if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
 			direction = 0;
 
 
@@ -235,6 +239,130 @@
 	blade_copy_rect,
 };
 
+
+/*
+ * BladeXP specific acceleration functions
+ */
+
+#define ROP_P 0xF0
+#define masked_point(x,y) ((y & 0xffff)<<16|(x & 0xffff))
+
+static void xp_init_accel(int pitch,int bpp)
+{
+	int tmp = 0,v1;
+	unsigned char x = 0;
+
+	switch (bpp) {
+		case 8:  x = 0; break;
+		case 16: x = 1; break;
+		case 24: x = 3; break;
+		case 32: x = 2; break;
+	}
+
+	switch (pitch << (bpp >> 3)) {
+		case 8192:
+		case 512:  x |= 0x00; break;
+		case 1024: x |= 0x04; break;
+		case 2048: x |= 0x08; break;
+		case 4096: x |= 0x0C; break;
+	}
+
+	t_outb(x,0x2125);
+
+	fb_info.eng_oper = x | 0x40;
+
+	switch (bpp) {
+		case 8:  tmp = 18; break;
+		case 15:
+		case 16: tmp = 19; break;
+		case 24:
+		case 32: tmp = 20; break;
+	}
+
+	v1 = pitch << tmp;
+
+	writemmr(0x2154,v1);
+	writemmr(0x2150,v1);
+	t_outb(3,0x2126);
+}
+
+static void xp_wait_engine(void)
+{
+	int busy;
+	int count, timeout;
+
+	count = 0;
+	timeout = 0;
+	for (;;) {
+		busy = t_inb(STA) & 0x80;
+		if (busy != 0x80)
+			return;
+		count++;
+		if (count == 10000000) {
+			/* Timeout */
+			count = 9990000;
+			timeout++;
+			if (timeout == 8) {
+				/* Reset engine */
+				t_outb(0x00, 0x2120);
+				return;
+			}
+		}
+	}
+}
+
+static void xp_fill_rect(int x,int y,int w,int h,int c)
+{
+	writemmr(0x2127,ROP_P);
+	writemmr(0x2158,c);
+	writemmr(0x2128,0x4000);
+	writemmr(0x2140,masked_point(h,w));
+	writemmr(0x2138,masked_point(y,x));
+	t_outb(0x01,0x2124);
+        t_outb(fb_info.eng_oper,0x2125);
+}
+
+static void xp_copy_rect(int x1,int y1,int x2,int y2,int w,int h)
+{
+	int direction;
+	int x1_tmp, x2_tmp, y1_tmp, y2_tmp;
+
+	direction = 0x0004;
+	
+	if ((x1 < x2) && (y1 == y2)) {
+		direction |= 0x0200;
+		x1_tmp = x1 + w - 1;
+		x2_tmp = x2 + w - 1;
+	} else {
+		x1_tmp = x1;
+		x2_tmp = x2;
+	}
+  
+	if (y1 < y2) {
+		direction |= 0x0100;
+		y1_tmp = y1 + h - 1;
+		y2_tmp = y2 + h - 1;
+  	} else {
+		y1_tmp = y1;
+		y2_tmp = y2;
+	}
+
+	writemmr(0x2128,direction);	
+	t_outb(ROP_S,0x2127);
+	writemmr(0x213C,masked_point(y1_tmp,x1_tmp));
+	writemmr(0x2138,masked_point(y2_tmp,x2_tmp));
+	writemmr(0x2140,masked_point(h,w));
+	t_outb(0x01,0x2124);
+}
+
+static struct accel_switch accel_xp = {
+  	xp_init_accel,
+	xp_wait_engine,
+	xp_fill_rect,
+	xp_copy_rect,
+};
+
+
 /*
  * Image specific acceleration functions
  */
@@ -255,7 +383,7 @@
 	writemmr(0x2148, 0x00000000);
 	writemmr(0x2150, 0x00000000);
 	writemmr(0x2154, 0x00000000);
-	writemmr(0x2120, 0x60000000 |(pitch<<16) |pitch);
+	writemmr(0x2120, 0x60000000|(pitch<<16) |pitch);
 	writemmr(0x216C, 0x00000000);
 	writemmr(0x2170, 0x00000000);
 	writemmr(0x217C, 0x00000000);
@@ -457,11 +585,30 @@
 	t_outb(val, 0x3CF);
 }
 
-#define unprotect_all()	write3C4(Protection, 0x92);unprotect()
-#define unprotect()	write3C4(NewMode1,0xC2)
 #define bios_reg(reg) 	write3CE(BiosReg, reg)
-#define enable_mmio()	outb(PCIReg, 0x3D4); \
-			outb(inb(0x3D5) | 0x01, 0x3D5)
+#if 0
+static inline void unprotect_all(void)
+{
+	outb(Protection, 0x3C4);
+	outb(0x92, 0x3C5);
+}
+#endif
+static inline void enable_mmio(void)
+{
+	/* Goto New Mode */
+	outb(0x0B, 0x3C4);
+	inb(0x3C5);
+
+	/* Unprotect registers */
+	outb(NewMode1, 0x3C4);
+	outb(0x80, 0x3C5);
+  
+	/* Enable MMIO */
+	outb(PCIReg, 0x3D4); 
+	outb(inb(0x3D5) | 0x01, 0x3D5);
+}
+
+
 #define crtc_unlock()	write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
 
 /*  Return flat panel's maximum x resolution */
@@ -474,15 +621,13 @@
 
        	tmp = (read3CE(VertStretch) >> 4) & 3;
 
-	/* detection broken on XPAi ??? misdetects 1024 for 800 */
-	if (pci_id == CYBERBLADEXPAi1 && tmp == 3)
-		tmp = 2;
-
 	switch (tmp) {
-		case 0:x = 1280;y = 1024;break;
-		case 1:x = 640;y = 480;break;
-		case 2:x = 1024;y = 768;break;
-		default:x = 800;y = 600;break;
+		case 0: x = 1280; y = 1024; break;
+		case 2: x = 1024; y = 768;  break;
+		case 3: x = 800;  y = 600;  break; 
+		case 4: x = 1400; y = 1050; break;
+		case 1: 
+		default:x = 640;  y = 480;  break;
 	}
 
 	output("%dx%d flat panel found\n", x, y);
@@ -515,14 +660,13 @@
 static void set_screen_start(int base)
 {
 	write3X4(StartAddrLow, base & 0xFF);
-	write3X4(StartAddrHigh, (base & 0xFF00) >>8);
-	write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >>11));
-	write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | (base & 0xE0000) >> 17);
+	write3X4(StartAddrHigh, (base & 0xFF00) >> 8);
+	write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11));
+	write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
 }
 
-
-#error "Floating point maths. This needs fixing before the driver is safe"
-#define calc_freq(n,m,k) ((NTSC * (n+8))/((m+2)*(1<<k)))
+/* Use 20.12 fixed-point for NTSC value and frequency calculation */
+#define calc_freq(n,m,k)  ( ((unsigned long)0xE517 * (n+8) / ((m+2)*(1<<k))) >> 12 )
 
 /* Set dotclock frequency */
 static void set_vclk(int freq)
@@ -543,8 +687,13 @@
 			hi = (k<<6) | m;
 		}
 	}
-	write3C4(ClockHigh,hi);
-	write3C4(ClockLow,lo);
+	if (chip3D) {
+		write3C4(ClockHigh,hi);
+		write3C4(ClockLow,lo);
+	} else {
+		outb(lo,0x43C8);
+		outb(hi,0x43C9);
+	}
 	debug("VCLK = %X %X\n",hi,lo);
 }
 
@@ -577,26 +726,42 @@
 /* Try detecting the video memory size */
 static unsigned int __init get_memsize(void)
 {
-	unsigned char tmp;
+	unsigned char tmp, tmp2;
 	unsigned int k;
 
 	/* If memory size provided by user */
 	if (memsize)
 		k = memsize * Kb;
 	else
-	switch (pci_id) {
-		case CYBER9525DVD:k = 2560 * Kb;break;
-		case CYBERBLADEXPAi1:k = 16 * Mb;break;
-		case CYBERBLADEXPm16:k = 16 * Mb;break;
-		case CYBERBLADEXPm8:k = 8 * Mb;break;
+	switch (chip_id) {
+		case CYBER9525DVD:    k = 2560 * Kb; break;
 		default:
 			tmp = read3X4(SPR) & 0x0F;
 			switch (tmp) {
-				case 3:k = 1 * Mb;break;
-				case 7:k = 2 * Mb;break;
-				case 15:k = 4 * Mb;break;
-				case 4:k = 8 * Mb;break;
-				default:k = 1 * Mb;
+
+				case 0x01: k = 512;     break;
+				case 0x02: k = 6 * Mb;  break; /* XP */
+				case 0x03: k = 1 * Mb;  break;
+				case 0x04: k = 8 * Mb;  break;
+				case 0x06: k = 10 * Mb; break; /* XP */
+				case 0x07: k = 2 * Mb;  break;
+				case 0x08: k = 12 * Mb; break; /* XP */
+				case 0x0A: k = 14 * Mb; break; /* XP */
+				case 0x0C: k = 16 * Mb; break; /* XP */
+				case 0x0E:                     /* XP */
+  
+					tmp2 = read3C4(0xC1);
+					switch (tmp2) {
+						case 0x00: k = 20 * Mb; break;
+						case 0x01: k = 24 * Mb; break;
+						case 0x10: k = 28 * Mb; break;
+						case 0x11: k = 32 * Mb; break;
+						default:   k = 1 * Mb;  break;
+					}
+				break;
+	
+				case 0x0F: k = 4 * Mb; break;
+				default:   k = 1 * Mb;
 			}
 	}
 
@@ -605,7 +770,6 @@
 	return k;
 }
 
-
 /* Fill in fix */
 static int trident_encode_fix(struct fb_fix_screeninfo *fix,
 				  const void *par,
@@ -794,9 +958,8 @@
 	debug("enter\n");
 
 	i->currentmode = *p;
-	unprotect_all();
-	crtc_unlock();
 	enable_mmio();
+	crtc_unlock();
 
 	write3CE(CyberControl,8);
 	if (flatpanel && p->hres < i->nativex) {
@@ -807,7 +970,7 @@
 		 */
 		t_outb(0xEB,0x3C2);
 		write3CE(CyberControl,0x81);
-		if (center) //|| (p->bpp==32 && pci_id == CYBERBLADEi1D))
+		if (center) 
 			screen_center();
 		else if (stretch)
 			screen_stretch();
@@ -1036,8 +1199,8 @@
     	}
 
 	write3CE(PowerStatus,DPMSCont);
-    	t_outb(4,0x83C8);
-    	t_outb(PMCont,0x83C6);
+	t_outb(4,0x83C8);
+	t_outb(PMCont,0x83C6);
 
 	debug("exit\n");
 	return 0;
@@ -1098,82 +1261,76 @@
 	trident_set_disp
 };
 
-/* List of boards that we are trying to support */
-static struct almost_supported_board {
-	int pci_id;
-	int family;
-	struct accel_switch * acc;
-	char* board_name;
-	int accel;
-} asb[] __initdata = {
-	{ BLADE3D,		BLADE,	&accel_blade, "Blade3D",	ACCEL	},
-	{ CYBERBLADEi7,	BLADE,	&accel_blade, "CyberBladei7",	ACCEL	},
-	{ CYBERBLADEi7D,	BLADE,	&accel_blade, "CyberBladei7D",	ACCEL	},
-	{ CYBERBLADEi1,	BLADE,	&accel_blade, "CyberBladei1",	ACCEL	},
-	{ CYBERBLADEi1D,	BLADE,	&accel_blade, "CyberBladei1D",	ACCEL	},
-	{ CYBERBLADEAi1,	BLADE,	&accel_blade, "CyberBladeAi1",	ACCEL	},
-	{ CYBERBLADEAi1D,	BLADE,	&accel_blade, "CyberBladeAi1D",	ACCEL	},
-	{ CYBERBLADEE4,	BLADE,	&accel_blade, "CyberBladeE4",	ACCEL	},
-
-	{ IMAGE975,	IMAGE,	&accel_image,	"IMAGE975",	NOACCEL	},
-	{ IMAGE985,	IMAGE,	&accel_image,	"IMAGE985",	NOACCEL	},
-	{ CYBER9320,	IMAGE,	&accel_image,	"Cyber9320",	NOACCEL	},
-	{ CYBER9388,	IMAGE,	&accel_image,	"Cyber9388",	NOACCEL	},
-	{ CYBER9520,	IMAGE,	&accel_image,	"Cyber9520",	NOACCEL	},
-	{ CYBER9525DVD,	IMAGE,	&accel_image,	"Cyber9525DVD",	NOACCEL	},
-	{ CYBER9397,	IMAGE,	&accel_image,	"Cyber9397",	NOACCEL	},
-	{ CYBER9397DVD,	IMAGE,	&accel_image,	"Cyber9397DVD",	NOACCEL	},
-
-	{ CYBERBLADEXPAi1,	XP,	&accel_blade,	"CyberBladeXPAi1",	NOACCEL },
-	{ CYBERBLADEXPm8,	XP,	&accel_blade,	"CyberBladeXPm8",	NOACCEL },
-	{ CYBERBLADEXPm16,	XP,	&accel_blade,	"CyberBladeXPm16",	NOACCEL },
-};
+static int trident_iosize;
 
-static __init int trident_find_board(void)
+static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_device_id * id)
 {
-	int i;
-	struct pci_dev * board;
+	int err;
+	unsigned char revision;
 
-	for (i = 0;i < ARRAY_SIZE(asb);i++) {
-      		if ((board = pci_find_device(PCI_VENDOR_ID_TRIDENT,
-				   asb[i].pci_id,
-				   NULL))) {
-	 		family = asb[i].family;
-	 		acc = asb[i].acc;
-	 		pci_id = asb[i].pci_id;
-	 		defaultaccel = asb[i].accel;
-
-			fb_info.io = pci_resource_start(board,1);
-			fb_info.fbmem = pci_resource_start(board,0);
-	 		output("%s board found\n", asb[i].board_name);
-	 		return 1;
-      		}
-   	}
-	output("No Trident board found\n");
-	return 0;
-}
+	err = pci_enable_device(dev);
+	if (err)
+		return err;
+
+	chip_id = id->device;
+
+	/* If PCI id is 0x9660 then further detect chip type */
+	
+	if (chip_id == TGUI9660) {
+		outb(RevisionID,0x3C4);
+		revision = inb(0x3C5);	
+	
+		switch (revision) {
+			case 0x22:
+			case 0x23: chip_id = CYBER9397;break;
+			case 0x2A: chip_id = CYBER9397DVD;break;
+			case 0x30:
+			case 0x33:
+			case 0x34:
+			case 0x35:
+			case 0x38:
+			case 0x3A:
+			case 0xB3: chip_id = CYBER9385;break;
+			case 0x40 ... 0x43: chip_id = CYBER9382;break;
+			case 0x4A: chip_id = CYBER9388;break;
+			default:break;	
+		}
+	}
 
-int __init tridentfb_init(void)
-{
+	chip3D = is3Dchip(chip_id);
+
+	if (is_xp(chip_id)) {
+		acc = &accel_xp;
+	} else 
+	if (is_blade(chip_id)) {
+		acc = &accel_blade;
+	} else {
+		acc = &accel_image;
+	}
+
+	/* acceleration is on by default for 3D chips */
+	defaultaccel = chip3D && !noaccel;
 
-	output("Trident framebuffer  %s initializing\n", VERSION);
+	fb_info.io = pci_resource_start(dev,1);
+	fb_info.fbmem = pci_resource_start(dev,0);
 
-	if (!trident_find_board())
-     		return -1;
+	trident_iosize = chip3D ? 0x20000:0x10000;
 
-	if (!request_mem_region(fb_info.io, TRIDENT_IOSIZE, "tridentfb")) {
+	if (!request_mem_region(fb_info.io, trident_iosize, "tridentfb")) {
 		debug("request_region failed!\n");
 		return -1;
-	};
+	}
 
-	fb_info.io_virt = (unsigned int)ioremap_nocache(fb_info.io, TRIDENT_IOSIZE);
+	fb_info.io_virt = (unsigned int)ioremap_nocache(fb_info.io, trident_iosize);
 
 	if (!fb_info.io_virt) {
-		release_region(fb_info.io, TRIDENT_IOSIZE);
+		release_region(fb_info.io, trident_iosize);
 		debug("ioremap failed\n");
 		return -1;
 	}
 
+	enable_mmio();
+
 	fb_info.memsize = get_memsize();
 	if (!request_mem_region(fb_info.fbmem, fb_info.memsize, "tridentfb")) {
 		debug("request_mem_region failed!\n");
@@ -1188,6 +1345,7 @@
 		return -1;
 	}
 
+	output("%s board found\n", dev->name);
 	debug("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n",
 		fb_info.fbmem, fb_info.io, fb_info.fbmem_virt, fb_info.io_virt);
 
@@ -1196,8 +1354,10 @@
 
 	strcpy(fb_info.gen.info.modename, tridentfb_name);
 	displaytype = get_displaytype();
+
 	if(flatpanel)
 		fb_info.nativex = get_nativex();
+
 	fb_info.gen.info.changevar = NULL;
 	fb_info.gen.info.node = NODEV;
 	fb_info.gen.info.fbops = &tridentfb_ops;
@@ -1213,16 +1373,8 @@
 
 	/* This should give a reasonable default video mode */
 	fb_find_mode(&default_var,&fb_info.gen.info,mode,NULL,0,NULL,bpp);
-	/*
-	 * Unless user explicitly requires accel/noaccel use
-	 * per chip defaults.Accel has priority over noaccel.
-	 */
-	if (accel)
-		defaultaccel = ACCEL;
-	else if (noaccel)
-		defaultaccel = NOACCEL;
 
-	if (defaultaccel == ACCEL)
+	if (defaultaccel && acc)
 		default_var.accel_flags |= FB_ACCELF_TEXT;
 	else
 		default_var.accel_flags &= ~FB_ACCELF_TEXT;
@@ -1243,13 +1395,61 @@
 	return 0;
 }
 
-void __exit tridentfb_exit(void)
+static void __devexit trident_pci_remove(struct pci_dev * dev)
 {
 	unregister_framebuffer(&fb_info.gen.info);
 	iounmap((void *)fb_info.io_virt);
 	iounmap((void *)fb_info.fbmem_virt);
+	release_mem_region(fb_info.fbmem, fb_info.memsize);
+	release_region(fb_info.io, trident_iosize);
+}
+
+/* List of boards that we are trying to support */
+static struct pci_device_id trident_devices[] __devinitdata = {
+	{PCI_VENDOR_ID_TRIDENT,	BLADE3D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi7, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi7D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEAi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEE4, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	TGUI9660, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	IMAGE975, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	IMAGE985, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9320, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9388, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9520, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9525DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9397, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9397DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPm8, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPm16, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{0,}
+};	
+	
+MODULE_DEVICE_TABLE(pci,trident_devices); 
+
+static struct pci_driver tridentfb_pci_driver = {
+	name:"tridentfb",
+	id_table:trident_devices,
+	probe:trident_pci_probe,
+	remove:__devexit_p(trident_pci_remove),
+};
+
+int __init tridentfb_init(void)
+{
+	output("Trident framebuffer %s initializing\n", VERSION);
+	return pci_module_init(&tridentfb_pci_driver);
 }
 
+void __exit tridentfb_exit(void)
+{
+	pci_unregister_driver(&tridentfb_pci_driver);
+}
+
+
 /*
  * Parse user specified options (`video=trident:')
  * example:
@@ -1260,12 +1460,10 @@
 	char * opt;
 	if (!options || !*options)
 		return 0;
-	for(opt = strtok(options,",");opt;opt = strtok(NULL,",")){
-		if (!opt) continue;
+	while((opt = strsep(&options,",")) != NULL ) {
+		if (!*opt) continue;
 		if (!strncmp(opt,"noaccel",7))
 			noaccel = 1;
-		else if (!strncmp(opt,"accel",5))
-			accel = 1;
 		else if (!strncmp(opt,"fp",2))
 			displaytype = DISPLAY_FP;
 		else if (!strncmp(opt,"crt",3))
@@ -1302,6 +1500,7 @@
 #endif
 module_exit(tridentfb_exit);
 
-MODULE_AUTHOR("Jani Monoses <jani@astechnix.ro>");
+MODULE_AUTHOR("Jani Monoses <jani@iv.ro>");
 MODULE_DESCRIPTION("Framebuffer driver for Trident cards");
 MODULE_LICENSE("GPL");
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/tridentfb.h linux/drivers/video/tridentfb.h
--- linux.orig/drivers/video/tridentfb.h	2002-02-25 19:38:07.000000000 +0000
+++ linux/drivers/video/tridentfb.h	2002-07-20 01:08:38.000000000 +0000
@@ -18,10 +18,13 @@
 
 #define CYBER9320	0x9320
 #define CYBER9388	0x9388
+#define CYBER9382	0x9382		/* the real PCI id for this is 9660 */
+#define CYBER9385	0x9385		/* ditto */		
 #define CYBER9397	0x9397
 #define CYBER9397DVD	0x939A
 #define CYBER9520	0x9520
 #define CYBER9525DVD	0x9525
+#define TGUI9660	0x9660
 #define IMAGE975	0x9750
 #define IMAGE985	0x9850
 #define BLADE3D		0x9880
@@ -41,9 +44,19 @@
 #define BLADE	1
 #define XP	2
 
-#define is_image()	(family == IMAGE)
-#define is_blade()	(family == BLADE)
-#define is_xp()		(family == XP)
+#define is_image(id)	
+#define is_xp(id)	((id == CYBERBLADEXPAi1) ||\
+			 (id == CYBERBLADEXPm8) ||\
+			 (id == CYBERBLADEXPm16)) 
+
+#define is_blade(id)	((id == BLADE3D) ||\
+			 (id == CYBERBLADEE4) ||\
+			 (id == CYBERBLADEi7) ||\
+			 (id == CYBERBLADEi7D) ||\
+			 (id == CYBERBLADEi1) ||\
+			 (id == CYBERBLADEi1D) ||\
+			 (id ==	CYBERBLADEAi1) ||\
+			 (id ==	CYBERBLADEAi1D))
 
 /* these defines are for 'lcd' variable */
 #define LCD_STRETCH	0
@@ -55,20 +68,13 @@
 #define DISPLAY_FP	1
 
 #define flatpanel (displaytype == DISPLAY_FP)
-/* these are for defaultaccel variable */
-#define ACCEL	1
-#define NOACCEL	0
-
-#define TRIDENT_IOSIZE	0x20000
-#define NTSC 14.31818
-#define PAL  17.73448
 
 /* General Registers */
 #define SPR	0x1F		/* Software Programming Register (videoram) */
 
 /* 3C4 */
 #define RevisionID 0x09
-#define OldOrNew 0x0B
+#define OldOrNew 0x0B	
 #define ConfPort1 0x0C
 #define ConfPort2 0x0C
 #define NewMode2 0x0D
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/tx3912fb.c linux/drivers/video/tx3912fb.c
--- linux.orig/drivers/video/tx3912fb.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/video/tx3912fb.c	2002-07-20 01:08:38.000000000 +0000
@@ -1,14 +1,14 @@
 /*
- * linux/drivers/video/tx3912fb.c
+ *  drivers/video/tx3912fb.c
  *
- * Copyright (C) 1999 Harald Koerfgen
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License. See the file COPYING in the main directory of this archive for
  * more details.
  *
- * Framebuffer for LCD controller in TMPR3912/05 and PR31700 processors
+ *  Framebuffer for LCD controller in TMPR3912/05 and PR31700 processors
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -20,13 +20,15 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/fb.h>
-#include <asm/bootinfo.h>
-#include <asm/uaccess.h>
 #include <video/fbcon.h>
 #include <video/fbcon-mfb.h>
 #include <video/fbcon-cfb2.h>
 #include <video/fbcon-cfb4.h>
 #include <video/fbcon-cfb8.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/uaccess.h>
+#include <asm/tx3912.h>
 #include "tx3912fb.h"
 
 /*
@@ -34,6 +36,9 @@
  */
 static struct fb_info fb_info;
 static struct { u_char red, green, blue, pad; } palette[256];
+#ifdef FBCON_HAS_CFB8
+static union { u16 cfb8[16]; } fbcon_cmap;
+#endif
 static struct display global_disp;
 static int currcon = 0;
 
@@ -343,49 +348,60 @@
  */
 int __init tx3912fb_init(void)
 {
-	/* Stop the video logic when frame completes */
-	VidCtrl1 |= ENFREEZEFRAME;
-	IntClear1 |= INT1_LCDINT;
-	while (!(IntStatus1 & INT1_LCDINT));
-
 	/* Disable the video logic */
-	VidCtrl1 &= ~(ENVID | DISPON);
+	outl(inl(TX3912_VIDEO_CTRL1) &
+		~(TX3912_VIDEO_CTRL1_ENVID | TX3912_VIDEO_CTRL1_DISPON),
+		TX3912_VIDEO_CTRL1);
 	udelay(200);
 
 	/* Set start address for DMA transfer */
-	VidCtrl3 = tx3912fb_paddr &
-		(TX3912_VIDCTRL3_VIDBANK_MASK | TX3912_VIDCTRL3_VIDBASEHI_MASK);
+	outl(tx3912fb_paddr, TX3912_VIDEO_CTRL3);
 
 	/* Set end address for DMA transfer */
-	VidCtrl4 = (tx3912fb_paddr + tx3912fb_size + 1) &
-		TX3912_VIDCTRL4_VIDBASELO_MASK;
+	outl((tx3912fb_paddr + tx3912fb_size + 1), TX3912_VIDEO_CTRL4);
 
 	/* Set the pixel depth */
 	switch (tx3912fb_info.bits_per_pixel) {
 	case 1:
 		/* Monochrome */
-		VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+		outl(inl(TX3912_VIDEO_CTRL1) & ~TX3912_VIDEO_CTRL1_BITSEL_MASK,
+			TX3912_VIDEO_CTRL1);
 		break;
 	case 4:
 		/* 4-bit gray */
-		VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
-		VidCtrl1 |= TX3912_VIDCTRL1_4BIT_GRAY;
+		outl(inl(TX3912_VIDEO_CTRL1) & ~TX3912_VIDEO_CTRL1_BITSEL_MASK,
+			TX3912_VIDEO_CTRL1);
+		outl(inl(TX3912_VIDEO_CTRL1) |
+			TX3912_VIDEO_CTRL1_BITSEL_4BIT_GRAY,
+			TX3912_VIDEO_CTRL1);
 		break;
 	case 8:
 		/* 8-bit color */
-		VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
-		VidCtrl1 |= TX3912_VIDCTRL1_8BIT_COLOR;
+		outl(inl(TX3912_VIDEO_CTRL1) & ~TX3912_VIDEO_CTRL1_BITSEL_MASK,
+			TX3912_VIDEO_CTRL1);
+		outl(inl(TX3912_VIDEO_CTRL1) |
+			TX3912_VIDEO_CTRL1_BITSEL_8BIT_COLOR,
+			TX3912_VIDEO_CTRL1);
 		break;
 	case 2:
 	default:
 		/* 2-bit gray */
-		VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
-		VidCtrl1 |= TX3912_VIDCTRL1_2BIT_GRAY;
+		outl(inl(TX3912_VIDEO_CTRL1) & ~TX3912_VIDEO_CTRL1_BITSEL_MASK,
+			TX3912_VIDEO_CTRL1);
+		outl(inl(TX3912_VIDEO_CTRL1) |
+			TX3912_VIDEO_CTRL1_BITSEL_2BIT_GRAY,
+			TX3912_VIDEO_CTRL1);
 		break;
 	}
 
+	/* Enable the video clock */
+	outl(inl(TX3912_CLK_CTRL) | TX3912_CLK_CTRL_ENVIDCLK,
+		TX3912_CLK_CTRL);
+
 	/* Unfreeze video logic and enable DF toggle */
-	VidCtrl1 &= ~(ENFREEZEFRAME | DFMODE);
+	outl(inl(TX3912_VIDEO_CTRL1) &
+		~(TX3912_VIDEO_CTRL1_ENFREEZEFRAME | TX3912_VIDEO_CTRL1_DFMODE),
+		TX3912_VIDEO_CTRL1);
 	udelay(200);
 
 	/* Clear the framebuffer */
@@ -393,7 +409,9 @@
 	udelay(200);
 
 	/* Enable the video logic */
-	VidCtrl1 |= (DISPON | ENVID);
+	outl(inl(TX3912_VIDEO_CTRL1) |
+		(TX3912_VIDEO_CTRL1_ENVID | TX3912_VIDEO_CTRL1_DISPON),
+		TX3912_VIDEO_CTRL1);
 
 	strcpy(fb_info.modename, TX3912FB_NAME);
 	fb_info.changevar = NULL;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/tx3912fb.h linux/drivers/video/tx3912fb.h
--- linux.orig/drivers/video/tx3912fb.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/drivers/video/tx3912fb.h	2002-07-20 01:08:24.000000000 +0000
@@ -1,66 +1,14 @@
 /*
- * linux/drivers/video/tx3912fb.h
+ *  drivers/video/tx3912fb.h
  *
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ *  Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License. See the file COPYING in the main directory of this archive for
  * more details.
  *
- * Includes for TMPR3912/05 and PR31700 LCD controller registers
+ *  Includes for TMPR3912/05 and PR31700 LCD controller registers
  */
-#include <asm/tx3912.h>
-
-#define VidCtrl1        REG_AT(0x028)
-#define VidCtrl2        REG_AT(0x02C)
-#define VidCtrl3        REG_AT(0x030)
-#define VidCtrl4        REG_AT(0x034)
-#define VidCtrl5        REG_AT(0x038)
-#define VidCtrl6        REG_AT(0x03C)
-#define VidCtrl7        REG_AT(0x040)
-#define VidCtrl8        REG_AT(0x044)
-#define VidCtrl9        REG_AT(0x048)
-#define VidCtrl10       REG_AT(0x04C)
-#define VidCtrl11       REG_AT(0x050)
-#define VidCtrl12       REG_AT(0x054)
-#define VidCtrl13       REG_AT(0x058)
-#define VidCtrl14       REG_AT(0x05C)
-
-/* Video Control 1 Register */
-#define LINECNT         0xffc00000
-#define LINECNT_SHIFT   22
-#define LOADDLY         BIT(21)
-#define BAUDVAL         (BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16))
-#define BAUDVAL_SHIFT   16
-#define VIDDONEVAL      (BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9))
-#define VIDDONEVAL_SHIFT  9
-#define ENFREEZEFRAME   BIT(8)
-#define TX3912_VIDCTRL1_BITSEL_MASK	0x000000c0
-#define TX3912_VIDCTRL1_2BIT_GRAY	0x00000040
-#define TX3912_VIDCTRL1_4BIT_GRAY	0x00000080
-#define TX3912_VIDCTRL1_8BIT_COLOR	0x000000c0
-#define BITSEL_SHIFT    6
-#define DISPSPLIT       BIT(5)
-#define DISP8           BIT(4)
-#define DFMODE          BIT(3)
-#define INVVID          BIT(2)
-#define DISPON          BIT(1)
-#define ENVID           BIT(0)
-
-/* Video Control 2 Register */
-#define VIDRATE_MASK    0xffc00000
-#define VIDRATE_SHIFT   22
-#define HORZVAL_MASK    0x001ff000
-#define HORZVAL_SHIFT   12
-#define LINEVAL_MASK    0x000001ff
-
-/* Video Control 3 Register */
-#define TX3912_VIDCTRL3_VIDBANK_MASK    0xfff00000
-#define TX3912_VIDCTRL3_VIDBASEHI_MASK  0x000ffff0
-
-/* Video Control 4 Register */
-#define TX3912_VIDCTRL4_VIDBASELO_MASK  0x000ffff0
-
 
 /*
  * Begin platform specific configurations
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/vgacon.c linux/drivers/video/vgacon.c
--- linux.orig/drivers/video/vgacon.c	2001-10-15 20:47:13.000000000 +0000
+++ linux/drivers/video/vgacon.c	2002-07-20 01:08:35.000000000 +0000
@@ -109,14 +109,7 @@
 static unsigned int    vga_default_font_height;	/* Height of default screen font */
 static unsigned char   vga_video_type;		/* Card type */
 static unsigned char   vga_hardscroll_enabled;
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-/*
- * SoftSDV doesn't have hardware assist VGA scrolling 
- */
-static unsigned char   vga_hardscroll_user_enable = 0;
-#else
 static unsigned char   vga_hardscroll_user_enable = 1;
-#endif
 static unsigned char   vga_font_is_default = 1;
 static int	       vga_vesa_blanked;
 static int	       vga_palette_blanked;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/virgefb.c linux/drivers/video/virgefb.c
--- linux.orig/drivers/video/virgefb.c	2001-11-14 22:52:20.000000000 +0000
+++ linux/drivers/video/virgefb.c	2002-07-20 01:08:30.000000000 +0000
@@ -9,12 +9,30 @@
  *    Copyright (C) 1996 Martin Apel
  *                       Geert Uytterhoeven
  *
+ * Zorro II additions :
+ *
+ *    Copyright (C) 1998-2000 Christian T. Steigies
+ *
+ * Initialization additions :
+ *
+ *    Copyright (C) 1998-2000 Ken Tyler
+ *
+ * Parts of the Initialization code are based on Cyberfb.c by Allan Bair,
+ * and on the NetBSD CyberVision64 frame buffer driver by Michael Teske who gave
+ * permission for its use.
+ *
+ * Many thanks to Frank Mariak for his assistance with ZORRO 2 access and other
+ * mysteries.
+ *
+ *
+ *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive
  * for more details.
  */
 
 #undef VIRGEFBDEBUG
+#undef VIRGEFBDUMP
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -29,16 +47,15 @@
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
 #include <asm/amigahw.h>
 #include <asm/io.h>
-
-#include <video/s3blit.h>
+#include <asm/irq.h>
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb32.h>
 
+#include "virgefb.h"
 
 #ifdef VIRGEFBDEBUG
 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
@@ -46,63 +63,163 @@
 #define DPRINTK(fmt, args...)
 #endif
 
-#if 1
-#define vgawb_3d(reg,dat) \
-	if (cv3d_on_zorro2) { \
-	*((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x04)) = \
-	(0x01 & 0xffff); asm volatile ("nop"); \
-	} \
-	(*((unsigned char *)(CyberVGARegs + (reg ^ 3))) = dat); \
-	if (cv3d_on_zorro2) { \
-	*((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x04)) = \
-	(0x02 & 0xffff); asm volatile ("nop"); \
-	}
-#define vgaww_3d(reg,dat) \
-                (*((unsigned word *)(CyberVGARegs + (reg ^ 2))) = swab16(dat))
-#define vgawl_3d(reg,dat) \
-                (*((unsigned long *)(CyberVGARegs + reg)) = swab32(dat))
+#ifdef VIRGEFBDUMP
+static void cv64_dump(void);
+#define DUMP cv64_dump()
 #else
-     /*
-      * Dunno why this doesn't work at the moment - we'll have to look at
-      * it later.
-      */
-#define vgawb_3d(reg,dat) \
-                (*((unsigned char *)(CyberRegs + 0x8000 + reg)) = dat)
-#define vgaww_3d(reg,dat) \
-                (*((unsigned word *)(CyberRegs + 0x8000 + reg)) = dat)
-#define vgawl_3d(reg,dat) \
-                (*((unsigned long *)(CyberRegs + 0x8000 + reg)) = dat)
-#endif
-
-     /*
-      * We asume P5 mapped the big-endian version of these registers.
-      */
-#define wb_3d(reg,dat) \
-                (*((unsigned char volatile *)(CyberRegs + reg)) = dat)
-#define ww_3d(reg,dat) \
-                (*((unsigned word volatile *)(CyberRegs + reg)) = dat)
-#define wl_3d(reg,dat) \
-                (*((unsigned long volatile *)(CyberRegs + reg)) = dat)
-#define rl_3d(reg) \
-                (*((unsigned long volatile *)(CyberRegs + reg)))
+#define DUMP
+#endif
 
-#define Select_Zorro2_FrameBuffer(flag) \
-	do { \
-		*((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x08)) = \
-		((flag * 0x40) & 0xffff); asm volatile ("nop"); \
-	} while (0)
 /*
- *	may be needed when we initialize the board?
- *	8bit: flag = 2, 16 bit: flag = 1, 24/32bit: flag = 0 
- *	_when_ the board is initialized, depth doesnt matter, we allways write
- *	to the same address, aperture seems not to matter on Z2.
+ *	Macros for register access and zorro control
  */
 
+static inline void mb_inline(void) { mb(); }	/* for use in comma expressions */
+
+/* Set zorro 2 map */
+
+#define SelectIO \
+	mb(); \
+	if (on_zorro2) { \
+		(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x01); \
+		mb(); \
+	}
+
+#define	SelectMMIO \
+	mb(); \
+	if (on_zorro2) { \
+		(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x02); \
+		mb(); \
+	}
+
+#define	SelectCFG \
+	mb(); \
+	if (on_zorro2) { \
+		(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x03); \
+		mb(); \
+	}
+
+/* Set pass through, 0 = amiga, !=0 = cv64/3d */
+
+#define SetVSwitch(x) \
+	mb(); \
+	(*(volatile u16 *)((u8 *)(vcode_switch_base)) = \
+	(u16)(x ? 0 : 1)); \
+	mb();
+
+/* Zorro2 endian 'aperture' */
+
+#define ENDIAN_BYTE	2
+#define ENDIAN_WORD	1
+#define ENDIAN_LONG	0
+
+#define Select_Zorro2_FrameBuffer(x) \
+	do { \
+		if (on_zorro2) { \
+			mb(); \
+			(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x08)) = \
+			(x * 0x40)); \
+			mb(); \
+		} \
+	} while (0)
+
+/* SetPortVal - only used for interrupt enable (not yet implemented) */
+
+#if 0
+#define SetPortVal(x) \
+	mb(); \
+	(*(volatile u16 *)((u8 *)(vcode_switch_base + 0x0c)) = \
+	(u16)x); \
+	mb();
+#endif
+
+/* IO access */
+
+#define byte_access_io(x)	(((x) & 0x3ffc) | (((x) & 3)^3) | (((x) & 3) <<14))
+#define byte_access_mmio(x)	(((x) & 0xfffc) | (((x) & 3)^3))
+
+/* Write 8 bit VGA register - used once for chip wakeup */
+
+#define wb_vgaio(reg, dat) \
+	SelectIO; \
+	(*(volatile u8 *)(vgaio_regs + ((u32)byte_access_io(reg) & 0xffff)) = \
+	(dat & 0xff)); \
+	SelectMMIO;
+
+/* Read 8 bit VGA register - only used in dump (SelectIO not needed on read ?) */
+
+#ifdef VIRGEFBDUMP
+#define rb_vgaio(reg) \
+	({ \
+	u8 __zzyzx; \
+	SelectIO; \
+	__zzyzx = (*(volatile u8 *)((vgaio_regs)+(u32)byte_access_io(reg))); \
+	SelectMMIO; \
+	__zzyzx; \
+	})
+#endif
+
+/* MMIO access */
+
+/* Read 8 bit MMIO register */
+
+#define rb_mmio(reg) \
+	(mb_inline(), \
+	(*(volatile u8 *)(mmio_regs + 0x8000 + (u32)byte_access_mmio(reg))))
+
+/* Write 8 bit MMIO register */
+
+#define wb_mmio(reg,dat) \
+	mb(); \
+	(*(volatile u8 *)(mmio_regs + 0x8000 + (byte_access_mmio((reg) & 0xffff))) = \
+	(dat & 0xff)); \
+	mb();
+
+/* Read 32 bit MMIO register */
+
+#define rl_mmio(reg) \
+	(mb_inline(), \
+	(*((volatile u32 *)((u8 *)((mmio_regs + (on_zorro2 ? 0x20000 : 0)) + (reg))))))
+
+/* Write 32 bit MMIO register */
+
+#define wl_mmio(reg,dat) \
+	mb(); \
+	((*(volatile u32 *)((u8 *)((mmio_regs + (on_zorro2 ? 0x20000 : 0)) + (reg)))) = \
+	(u32)(dat)); \
+	mb();
+
+/* Write to virge graphics register */
+
+#define wgfx(reg, dat)	do { wb_mmio(GCT_ADDRESS, (reg)); wb_mmio(GCT_ADDRESS_W, (dat)); } while (0)
+
+/* Write to virge sequencer register */
+
+#define wseq(reg, dat)	do { wb_mmio(SEQ_ADDRESS, (reg)); wb_mmio(SEQ_ADDRESS_W, (dat)); } while (0)
+
+/* Write to virge CRT controller register */
+
+#define wcrt(reg, dat)	do { wb_mmio(CRT_ADDRESS, (reg)); wb_mmio(CRT_ADDRESS_W, (dat)); } while (0)
+
+/* Write to virge attribute register */
+
+#define watr(reg, dat) \
+	do { \
+		volatile unsigned char watr_tmp; \
+		watr_tmp = rb_mmio(ACT_ADDRESS_RESET); \
+		wb_mmio(ACT_ADDRESS_W, (reg)); \
+		wb_mmio(ACT_ADDRESS_W, (dat)); \
+		udelay(10); \
+	} while (0)
+
+/* end of macros */
+
 struct virgefb_par {
-   int xres;
-   int yres;
-   int bpp;
-   int accel;
+   struct fb_var_screeninfo var;
+   __u32 type;
+   __u32 type_aux;
+   __u32 visual;
+   __u32 line_length;
 };
 
 static struct virgefb_par current_par;
@@ -117,6 +234,9 @@
 #ifdef FBCON_HAS_CFB16
     u16 cfb16[16];
 #endif
+#ifdef FBCON_HAS_CFB32
+    u32 cfb32[16];
+#endif
 } fbcon_cmap;
 
 /*
@@ -141,43 +261,48 @@
    void (*blank)(int blank);
 } *fbhw;
 
-static int blit_maybe_busy = 0;
+static unsigned char blit_maybe_busy = 0;
 
 /*
  *    Frame Buffer Name
  */
 
-static char virgefb_name[16] = "Cybervision/3D";
-
+static char virgefb_name[16] = "CyberVision/3D";
 
 /*
- *    Cybervision Graphics Board
+ *    CyberVision64/3d Graphics Board
  */
 
-#define VIRGE8_WIDTH 1152
-#define VIRGE8_HEIGHT 886
-#define VIRGE8_PIXCLOCK 12500    /* ++Geert: Just a guess */
+static unsigned char virgefb_colour_table [256][3];
+static unsigned long v_ram;
+static unsigned long v_ram_size;
+static volatile unsigned char *mmio_regs;
+static volatile unsigned char *vgaio_regs;
+
+static unsigned long v_ram_phys;
+static unsigned long mmio_regs_phys;
+static unsigned long vcode_switch_base;
+static unsigned char on_zorro2;
+
+/*
+ * Offsets from start of video ram to appropriate ZIII aperture
+ */
 
-#if 1
-#define VIRGE16_WIDTH 800
-#define VIRGE16_HEIGHT 600
+#ifdef FBCON_HAS_CFB8
+#define CYBMEM_OFFSET_8  0x800000	/* BGRX */
+#endif
+#ifdef FBCON_HAS_CFB16
+#define CYBMEM_OFFSET_16 0x400000	/* GBXR */
+#endif
+#ifdef FBCON_HAS_CFB32
+#define CYBMEM_OFFSET_32 0x000000	/* XRGB */
 #endif
-#define VIRGE16_PIXCLOCK 25000   /* ++Geert: Just a guess */
 
+/*
+ *    MEMCLOCK was 32MHz, 64MHz works, 72MHz doesn't (on my board)
+ */
 
-static unsigned char Cyber_colour_table [256][3];
-static unsigned long CyberMem;
-static unsigned long CyberSize;
-static volatile char *CyberRegs;
-static volatile unsigned long CyberVGARegs; /* ++Andre: for CV64/3D, see macros at the beginning */
-static unsigned long CyberMem_phys;
-static unsigned long CyberRegs_phys;
-static unsigned long Cyber_register_base;
-static unsigned long Cyber_vcode_switch_base;
-static unsigned char cv3d_on_zorro2;
- 
-#define CYBMEM_OFFSET_8  0x800000	/* offsets from start of video - */ 
-#define CYBMEM_OFFSET_16 0x400000	/* ram to appropriate aperture */
+#define MEMCLOCK 50000000
 
 /*
  *    Predefined Video Modes
@@ -187,136 +312,354 @@
     const char *name;
     struct fb_var_screeninfo var;
 } virgefb_predefined[] __initdata = {
+#ifdef FBCON_HAS_CFB8
     {
 	"640x480-8", {		/* Cybervision 8 bpp */
 	    640, 480, 640, 480, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 160, 136, 82, 61, 88, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"768x576-8", {		/* Cybervision 8 bpp */
+	    768, 576, 768, 576, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
 	"800x600-8", {		/* Cybervision 8 bpp */
 	    800, 600, 800, 600, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
+  #if 0 
 	"1024x768-8", {		/* Cybervision 8 bpp */
 	    1024, 768, 1024, 768, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+  #else
+	"1024x768-8", {
+	    1024, 768, 1024, 768, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+   #if 0
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 12500, 184, 40, 40, 2, 96, 1,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    }
+    #else
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 12699, 176, 16, 28, 1, 96, 3,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	    }
+    #endif
+  #endif
     }, {
 	"1152x886-8", {		/* Cybervision 8 bpp */
 	    1152, 886, 1152, 886, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
-	"1280x1024-8", {	/* Cybervision 8 bpp */
+	"1280x1024-8", { 	/* Cybervision 8 bpp */
 	    1280, 1024, 1280, 1024, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+  #if 0
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    }
+  #else
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 7414, 232, 64, 38, 1, 112, 3,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    }
+  #endif
     }, {
-	"1600x1200-8", {	/* Cybervision 8 bpp */
+	"1600x1200-8", { 	/* Cybervision 8 bpp */
 	    1600, 1200, 1600, 1200, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+  #if 0
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+  #else
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 6411, 256, 32, 52, 10, 160, 8,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
-    }, {
+	    }
+  #endif
+    },
+#endif
+
+#ifdef FBCON_HAS_CFB16
+    {
 	"640x480-16", {		/* Cybervision 16 bpp */
 	    640, 480, 640, 480, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 152, 144, 82, 61, 88, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"768x576-16", {		/* Cybervision 16 bpp */
+	    768, 576, 768, 576, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
 	"800x600-16", {		/* Cybervision 16 bpp */
 	    800, 600, 800, 600, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	}
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
-	"1024x768-16", {         /* Cybervision 16 bpp */
+#if 0
+	"1024x768-16", { 	/* Cybervision 16 bpp */
 	    1024, 768, 1024, 768, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-       }
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+#else
+         "1024x768-16", {
+             1024, 768, 1024, 768, 0, 0, 16, 0,
+             {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+             0, 0, -1, -1, FB_ACCELF_TEXT, 12500, 184, 40, 40, 2, 96, 1,
+             FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+         }
+#endif
     }, {
-	"1152x886-16", {         /* Cybervision 16 bpp */
+	"1152x886-16", { 	/* Cybervision 16 bpp */
 	    1152, 886, 1152, 886, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-       }
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
-	"1280x1024-16", {         /* Cybervision 16 bpp */
+	"1280x1024-16", { 	/* Cybervision 16 bpp */
 	    1280, 1024, 1280, 1024, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-       }
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
     }, {
-	"1600x1200-16", {         /* Cybervision 16 bpp */
+	"1600x1200-16", { 	/* Cybervision 16 bpp */
 	    1600, 1200, 1600, 1200, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-       }
-    }
-};
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    },
+#endif
+
+#ifdef FBCON_HAS_CFB32
+    {
+	"640x480-32", {		/* Cybervision 32 bpp */
+	    640, 480, 640, 480, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 160, 136, 82, 61, 88, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+     }, {
+	"768x576-32", {		/* Cybervision 32 bpp */
+	    768, 576, 768, 576, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+     }, {
+	"800x600-32", {		/* Cybervision 32 bpp */
+	    800, 600, 800, 600, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+  	    0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+     }, {
+	"1024x768-32", {	/* Cybervision 32 bpp */
+	    1024, 768, 1024, 768, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"1152x886-32", {	/* Cybervision 32 bpp */
+	    1152, 886, 1152, 886, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"1280x1024-32", {	/* Cybervision 32 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    }, {
+	"1600x1200-32", {	/* Cybervision 32 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_NONINTERLACED
+	    }
+    },
+#endif
+
+/* interlaced modes */
+
+#ifdef FBCON_HAS_CFB8
+    {
+	"1024x768-8i", {	/* Cybervision 8 bpp */
+	    1024, 768, 1024, 768, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1280x1024-8i", {	/* Cybervision 8 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1600x1200-8i", {	/* Cybervision 8 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    },
+#endif
+
+#ifdef FBCON_HAS_CFB16
+    {
+	"1024x768-16i", {	/* Cybervision 16 bpp */
+	    1024, 768, 1024, 768, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1280x1024-16i", {	/* Cybervision 16 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1600x1200-16i", {	/* Cybervision 16 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    },
+#endif
+
+#ifdef FBCON_HAS_CFB32
+    {
+	"1024x768-32i", {	/* Cybervision 32 bpp */
+	    1024, 768, 1024, 768, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 22222, 216, 144, 39, 2, 72, 1,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1280x1024-32i", {	/* Cybervision 32 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {23, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    }, {
+	"1600x1200-32i", {	/* Cybervision 32 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
+	    0, FB_VMODE_INTERLACED
+	    }
+    },
+#endif
+
+/* doublescan modes */
 
+#ifdef FBCON_HAS_CFB8
+    {
+	"320x240-8d", {		/* Cybervision 8 bpp */
+	    320, 240, 320, 240, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
+	    0, FB_VMODE_DOUBLE
+	    }
+    },
+#endif
 
-#define NUM_TOTAL_MODES    ARRAY_SIZE(virgefb_predefined)
+#ifdef FBCON_HAS_CFB16
+    {
+	"320x240-16d", {	/* Cybervision 16 bpp */
+	    320, 240, 320, 240, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
+	    0, FB_VMODE_DOUBLE
+	    }
+    },
+#endif
 
+#ifdef FBCON_HAS_CFB32
+    {
+	"320x240-32d", {	/* Cybervision 32 bpp */
+	    320, 240, 320, 240, 0, 0, 32, 0,
+	    {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
+	    0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
+	    0, FB_VMODE_DOUBLE
+	    }
+    },
+#endif
+};
 
-static int Cyberfb_inverse = 0;
+#define arraysize(x)	(sizeof(x)/sizeof(*(x)))
+#define NUM_TOTAL_MODES	arraysize(virgefb_predefined)
 
 /*
- *    Some default modes
+ *    Default to 800x600 for video=virge8:, virge16: or virge32:
  */
 
-#define VIRGE8_DEFMODE     (1)
-#define VIRGE16_DEFMODE    (7)
+#ifdef FBCON_HAS_CFB8
+#define VIRGE8_DEFMODE	(2)
+#endif
 
-static struct fb_var_screeninfo virgefb_default;
+#ifdef FBCON_HAS_CFB16
+#define VIRGE16_DEFMODE	(9)
+#endif
 
+#ifdef FBCON_HAS_CFB32
+#define VIRGE32_DEFMODE	(16)
+#endif
+
+static struct fb_var_screeninfo virgefb_default;
+static int virgefb_inverse = 0;
 
 /*
  *    Interface used by the world
  */
 
 int virgefb_setup(char*);
-
-static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con, struct
-fb_info *info);
-static int virgefb_get_var(struct fb_var_screeninfo *var, int con, struct
-fb_info *info);
-static int virgefb_set_var(struct fb_var_screeninfo *var, int con, struct
-fb_info *info);
-static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info);
-static int virgefb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info);
-
+static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info);
+static int virgefb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+static int virgefb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);
+static int virgefb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);
 
 /*
  *    Interface to the low level console driver
  */
 
 int virgefb_init(void);
-static int Cyberfb_switch(int con, struct fb_info *info);
-static int Cyberfb_updatevar(int con, struct fb_info *info);
-static void Cyberfb_blank(int blank, struct fb_info *info);
-
+static int virgefb_switch(int con, struct fb_info *info);
+static int virgefb_updatevar(int con, struct fb_info *info);
+static void virgefb_blank(int blank, struct fb_info *info);
 
 /*
  *    Text console acceleration
@@ -330,23 +673,31 @@
 static struct display_switch fbcon_virge16;
 #endif
 
+#ifdef FBCON_HAS_CFB32
+static struct display_switch fbcon_virge32;
+#endif
+
 /*
  *   Hardware Specific Routines
  */
 
 static int Cyber_init(void);
-static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct virgefb_par *par);
-static int Cyber_decode_var(struct fb_var_screeninfo *var,
-                          struct virgefb_par *par);
-static int Cyber_encode_var(struct fb_var_screeninfo *var,
-                          struct virgefb_par *par);
-static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp, struct fb_info *info);
-static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp, struct fb_info *info);
-static void Cyber_blank(int blank);
-
+static int virgefb_encode_fix(struct fb_fix_screeninfo *fix,
+				struct virgefb_par *par);
+static int virgefb_decode_var(struct fb_var_screeninfo *var,
+				struct virgefb_par *par);
+static int virgefb_encode_var(struct fb_var_screeninfo *var,
+				struct virgefb_par *par);
+static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+				u_int *transp, struct fb_info *info);
+static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+				u_int transp, struct fb_info *info);
+static void virgefb_gfx_on_off(int blank);
+static inline void virgefb_wait_for_idle(void);
+static void virgefb_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
+		u_short width, u_short height, u_short stride, u_short depth);
+static void virgefb_RectFill(u_short x, u_short y, u_short width, u_short height,
+		u_short color, u_short stride, u_short depth);
 
 /*
  *    Internal routines
@@ -354,70 +705,250 @@
 
 static void virgefb_get_par(struct virgefb_par *par);
 static void virgefb_set_par(struct virgefb_par *par);
-static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static void do_install_cmap(int con, struct fb_info *info);
+static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
+static void virgefb_do_install_cmap(int con, struct fb_info *info);
 static void virgefb_set_disp(int con, struct fb_info *info);
-static int get_video_mode(const char *name);
+static int virgefb_get_video_mode(const char *name);
+static void virgefb_set_video(struct fb_var_screeninfo *var);
+
+/*
+ *    Additions for Initialization
+ */
 
+static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode);
+static int cv3d_has_4mb(void);
+static unsigned short virgefb_compute_clock(unsigned long freq);
+static inline unsigned char rattr(short);
+static inline unsigned char rseq(short);
+static inline unsigned char rcrt(short);
+static inline unsigned char rgfx(short);
+static inline void gfx_on_off(int toggle);
+static void virgefb_pci_init(void);
 
 /* -------------------- Hardware specific routines ------------------------- */
 
+/*
+ *	Functions for register access
+ */
+
+/* Read attribute controller register */
+
+static inline unsigned char rattr(short idx)
+{
+	volatile unsigned char rattr_tmp;
+
+	rattr_tmp = rb_mmio(ACT_ADDRESS_RESET);
+	wb_mmio(ACT_ADDRESS_W, idx);
+	return (rb_mmio(ACT_ADDRESS_R));
+}
+
+/* Read sequencer register */
+
+static inline unsigned char rseq(short idx)
+{
+	wb_mmio(SEQ_ADDRESS, idx);
+	return (rb_mmio(SEQ_ADDRESS_R));
+}
+
+/* Read CRT controller register */
+
+static inline unsigned char rcrt(short idx)
+{
+	wb_mmio(CRT_ADDRESS, idx);
+	return (rb_mmio(CRT_ADDRESS_R));
+}
+
+/* Read graphics controller register */
+
+static inline unsigned char rgfx(short idx)
+{
+	wb_mmio(GCT_ADDRESS, idx);
+	return (rb_mmio(GCT_ADDRESS_R));
+}
+
 
 /*
- *    Initialization
- *
- *    Set the default video mode for this chipset. If a video mode was
- *    specified on the command line, it will override the default mode.
+ *	Initialization
  */
 
+/* PCI init */
+
+void virgefb_pci_init(void) {
+
+	DPRINTK("ENTER\n");
+
+	SelectCFG;
+
+	if (on_zorro2) {
+		*((short *)(vgaio_regs + 0x00000010)) = 0;
+		*((long  *)(vgaio_regs + 0x00000004)) = 0x02000003;
+	} else {
+		*((short *)(vgaio_regs + 0x000e0010)) = 0;
+		*((long  *)(vgaio_regs + 0x000e0004)) = 0x02000003;
+	}
+
+	/* SelectIO is in wb_vgaio macro */
+	wb_vgaio(SREG_VIDEO_SUBS_ENABLE, 0x01);
+	/* SelectMMIO is in wb_vgaio macro */
+
+	DPRINTK("EXIT\n");
+
+	return;
+}
+
+/* 
+ * Initalize all mode independent regs, find mem size and clear mem
+*/
+
 static int Cyber_init(void)
 {
 	int i;
+	unsigned char tmp;
+
+	DPRINTK("ENTER\n");
 
-	for (i = 0; i < 256; i++)
-	{
-		Cyber_colour_table [i][0] = i;
-		Cyber_colour_table [i][1] = i;
-		Cyber_colour_table [i][2] = i;
-	}
-
-	/*
-	 * Just clear the thing for the biggest mode.
-	 *
-	 * ++Andre, TODO: determine size first, then clear all memory
-	 *                (the 3D penguin might need texture memory :-) )
-	 */
+	virgefb_pci_init();
 
-	if (cv3d_on_zorro2) {
-		CyberSize = 0x00380000; /* 3.5 MB , we need some space for the registers? */
+	wb_mmio(GREG_MISC_OUTPUT_W, 0x07);	/* colour, ram enable, clk sel */
+
+	wseq(SEQ_ID_UNLOCK_EXT, 0x06);		/* unlock extensions */
+	tmp = rb_mmio(GREG_MISC_OUTPUT_R);
+	wcrt(CRT_ID_REGISTER_LOCK_1, 0x48);	/* unlock CR2D to CR3F */
+
+	wcrt(CRT_ID_BACKWAD_COMP_1, 0x00);	/* irq disable */
+
+	wcrt(CRT_ID_REGISTER_LOCK_2, 0xa5);	/* unlock CR40 to CRFF and more */
+	wcrt(CRT_ID_REGISTER_LOCK,0x00);	/* unlock h and v timing */
+	wcrt(CRT_ID_SYSTEM_CONFIG, 0x01);	/* unlock enhanced programming registers */
+
+	wb_mmio(GREG_FEATURE_CONTROL_W, 0x00);
+
+	wcrt(CRT_ID_EXT_MISC_CNTL, 0x00);	/* b2 = 0 to allow VDAC mmio access */
+#if 0
+	/* write strap options ... ? */
+	wcrt(CRT_ID_CONFIG_1, 0x08);
+	wcrt(CRT_ID_CONFIG_2, 0xff);		/* 0x0x2 bit needs to be set ?? */
+	wcrt(CRT_ID_CONFIG_3, 0x0f);
+	wcrt(CRT_ID_CONFIG_4, 0x1a);
+#endif
+	wcrt(CRT_ID_EXT_MISC_CNTL_1, 0x82);	 /* PCI DE and software reset S3D engine */
+	/* EXT_MISC_CNTL_1, CR66 bit 0 should be the same as bit 0 MR_ADVANCED_FUNCTION_CONTROL - check */
+	wl_mmio(MR_ADVANCED_FUNCTION_CONTROL, 0x00000011); /* enhanced mode, linear addressing */
+
+/* crtc registers */
+
+	wcrt(CRT_ID_PRESET_ROW_SCAN, 0x00);
+
+	/* Disable h/w cursor */
+
+	wcrt(CRT_ID_CURSOR_START, 0x00);
+	wcrt(CRT_ID_CURSOR_END, 0x00);
+	wcrt(CRT_ID_START_ADDR_HIGH, 0x00);
+	wcrt(CRT_ID_START_ADDR_LOW, 0x00);
+	wcrt(CRT_ID_CURSOR_LOC_HIGH, 0x00);
+	wcrt(CRT_ID_CURSOR_LOC_LOW, 0x00);
+	wcrt(CRT_ID_EXT_MODE, 0x00);
+	wcrt(CRT_ID_HWGC_MODE, 0x00);
+	wcrt(CRT_ID_HWGC_ORIGIN_X_HI, 0x00);
+	wcrt(CRT_ID_HWGC_ORIGIN_X_LO, 0x00);
+	wcrt(CRT_ID_HWGC_ORIGIN_Y_HI, 0x00);
+	wcrt(CRT_ID_HWGC_ORIGIN_Y_LO, 0x00);
+	i = rcrt(CRT_ID_HWGC_MODE);
+	wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
+	wcrt(CRT_ID_HWGC_START_AD_HI, 0x00);
+	wcrt(CRT_ID_HWGC_START_AD_LO, 0x00);
+	wcrt(CRT_ID_HWGC_DSTART_X, 0x00);
+	wcrt(CRT_ID_HWGC_DSTART_Y, 0x00);
+
+	wcrt(CRT_ID_UNDERLINE_LOC, 0x00);
+
+	wcrt(CRT_ID_MODE_CONTROL, 0xe3);
+	wcrt(CRT_ID_BACKWAD_COMP_2, 0x22);	/* blank bdr bit 5 blanking only on 8 bit */
+
+	wcrt(CRT_ID_EX_SYNC_1, 0x00);
+
+	/* memory */
+
+	wcrt(CRT_ID_EXT_SYS_CNTL_3, 0x00);
+	wcrt(CRT_ID_MEMORY_CONF, 0x08);		/* config enhanced map */
+	wcrt(CRT_ID_EXT_MEM_CNTL_1, 0x08);	/* MMIO Select (0x0c works as well)*/
+	wcrt(CRT_ID_EXT_MEM_CNTL_2, 0x02);	/* why 02 big endian 00 works ? */
+	wcrt(CRT_ID_EXT_MEM_CNTL_4, 0x9f);	/* config big endian - 0x00 ?  */
+	wcrt(CRT_ID_LAW_POS_HI, 0x00);
+	wcrt(CRT_ID_LAW_POS_LO, 0x00);
+	wcrt(CRT_ID_EXT_MISC_CNTL_1, 0x81);
+	wcrt(CRT_ID_MISC_1, 0x90);		/* must follow CRT_ID_EXT_MISC_CNTL_1 */
+	wcrt(CRT_ID_LAW_CNTL, 0x13);		/* force 4 Meg for test */
+	if (cv3d_has_4mb()) {
+		v_ram_size = 0x00400000;
+		wcrt(CRT_ID_LAW_CNTL, 0x13);	/* 4 MB */
 	} else {
-		CyberSize = 0x00400000; /* 4 MB */
+		v_ram_size = 0x00200000;
+		wcrt(CRT_ID_LAW_CNTL, 0x12); 	/* 2 MB */
+	}
+
+	if (on_zorro2)
+		v_ram_size -= 0x60000;		/* we need some space for the registers */
+
+	wcrt(CRT_ID_EXT_SYS_CNTL_4, 0x00);
+	wcrt(CRT_ID_EXT_DAC_CNTL, 0x00);	/* 0x10 for X11 cursor mode */
+
+/* sequencer registers */
+
+	wseq(SEQ_ID_CLOCKING_MODE, 0x01);	/* 8 dot clock */
+	wseq(SEQ_ID_MAP_MASK, 0xff);
+	wseq(SEQ_ID_CHAR_MAP_SELECT, 0x00);
+	wseq(SEQ_ID_MEMORY_MODE, 0x02);
+	wseq(SEQ_ID_RAMDAC_CNTL, 0x00);
+	wseq(SEQ_ID_SIGNAL_SELECT, 0x00);
+	wseq(SEQ_ID_EXT_SEQ_REG9, 0x00);	/* MMIO and PIO reg access enabled */
+	wseq(SEQ_ID_EXT_MISC_SEQ, 0x00);
+	wseq(SEQ_ID_CLKSYN_CNTL_1, 0x00);
+	wseq(SEQ_ID_EXT_SEQ, 0x00);
+
+/* graphic registers */
+
+	wgfx(GCT_ID_SET_RESET, 0x00);
+	wgfx(GCT_ID_ENABLE_SET_RESET, 0x00);
+	wgfx(GCT_ID_COLOR_COMPARE, 0x00);
+	wgfx(GCT_ID_DATA_ROTATE, 0x00);
+	wgfx(GCT_ID_READ_MAP_SELECT, 0x00);
+	wgfx(GCT_ID_GRAPHICS_MODE, 0x40);
+	wgfx(GCT_ID_MISC, 0x01);
+	wgfx(GCT_ID_COLOR_XCARE, 0x0f);
+	wgfx(GCT_ID_BITMASK, 0xff);
+
+/* attribute  registers */
+
+	for(i = 0; i <= 15; i++)
+		watr(ACT_ID_PALETTE0 + i, i);
+	watr(ACT_ID_ATTR_MODE_CNTL, 0x41);
+	watr(ACT_ID_OVERSCAN_COLOR, 0xff);
+	watr(ACT_ID_COLOR_PLANE_ENA, 0x0f);
+	watr(ACT_ID_HOR_PEL_PANNING, 0x00);
+	watr(ACT_ID_COLOR_SELECT, 0x00);
+
+	wb_mmio(VDAC_MASK, 0xff);
+
+/* init local cmap as greyscale levels */
+
+	for (i = 0; i < 256; i++) {
+		virgefb_colour_table [i][0] = i;
+		virgefb_colour_table [i][1] = i;
+		virgefb_colour_table [i][2] = i;
 	}
 
-	memset ((char*)CyberMem, 0, CyberSize);
+/* clear framebuffer memory */
 
-	/* Disable hardware cursor */
-	vgawb_3d(0x3c8, 255);
-	vgawb_3d(0x3c9, 56);
-	vgawb_3d(0x3c9, 100);
-	vgawb_3d(0x3c9, 160);
-
-	vgawb_3d(0x3c8, 254);
-	vgawb_3d(0x3c9, 0);
-	vgawb_3d(0x3c9, 0);
-	vgawb_3d(0x3c9, 0);
-
-	/* Disable hardware cursor */
-	vgawb_3d(S3_CRTC_ADR, S3_REG_LOCK2);
-	vgawb_3d(S3_CRTC_DATA, 0xa0);
-	vgawb_3d(S3_CRTC_ADR, S3_HGC_MODE);
-	vgawb_3d(S3_CRTC_DATA, 0x00);
-	vgawb_3d(S3_CRTC_ADR, S3_HWGC_DX);
-	vgawb_3d(S3_CRTC_DATA, 0x00);
-	vgawb_3d(S3_CRTC_ADR, S3_HWGC_DY);
-	vgawb_3d(S3_CRTC_DATA, 0x00);
+	memset((char*)v_ram, 0x00, v_ram_size);
 
-	return 0; /* TODO: hardware cursor for CV64/3D */
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -426,30 +957,49 @@
  *    values in the `par' structure.
  */
 
-static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
+static int virgefb_encode_fix(struct fb_fix_screeninfo *fix,
 			    struct virgefb_par *par)
 {
+	DPRINTK("ENTER set video phys addr\n");
+
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 	strcpy(fix->id, virgefb_name);
-	if (cv3d_on_zorro2) {
-		fix->smem_start = CyberMem_phys;
-	} else {
-		switch (par->bpp) {
-			case 8:
-				fix->smem_start = (CyberMem_phys + CYBMEM_OFFSET_8);
-				break;
-			case 16:
-				fix->smem_start = (CyberMem_phys + CYBMEM_OFFSET_16);
-				break;
-		}
+	if (on_zorro2)
+		fix->smem_start = v_ram_phys;
+	switch (par->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+		case 8:
+			if (on_zorro2)
+				Select_Zorro2_FrameBuffer(ENDIAN_BYTE);
+			else
+				fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_8);
+			break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			if (on_zorro2)
+				Select_Zorro2_FrameBuffer(ENDIAN_WORD);
+			else
+				fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_16);
+			break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			if (on_zorro2)
+				Select_Zorro2_FrameBuffer(ENDIAN_LONG);
+			else
+				fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_32);
+			break;
+#endif
 	}
-	fix->smem_len = CyberSize;
-	fix->mmio_start = CyberRegs_phys;
+
+	fix->smem_len = v_ram_size;
+	fix->mmio_start = mmio_regs_phys;
 	fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
 
 	fix->type = FB_TYPE_PACKED_PIXELS;
 	fix->type_aux = 0;
-	if (par->bpp == 8)
+	if (par->var.bits_per_pixel == 8)
 		fix->visual = FB_VISUAL_PSEUDOCOLOR;
 	else
 		fix->visual = FB_VISUAL_TRUECOLOR;
@@ -457,142 +1007,146 @@
 	fix->xpanstep = 0;
 	fix->ypanstep = 0;
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->var.xres_virtual*par->var.bits_per_pixel/8;
 	fix->accel = FB_ACCEL_S3_VIRGE;
-	return(0);
+	DPRINTK("EXIT v_ram_phys = 0x%8.8lx\n", (unsigned long)fix->smem_start);
+	return 0;
 }
 
 
 /*
- *    Get the video params out of `var'. If a value doesn't fit, round
- *    it up, if it's too big, return -EINVAL.
+ *	Fill the `par' structure based on the values in `var'.
+ *	TODO: Verify and adjust values, return -EINVAL if bad.
  */
 
-static int Cyber_decode_var(struct fb_var_screeninfo *var,
+static int virgefb_decode_var(struct fb_var_screeninfo *var,
 			    struct virgefb_par *par)
 {
-#if 1
-	par->xres = var->xres;
-	par->yres = var->yres;
-	par->bpp = var->bits_per_pixel;
-	if (var->accel_flags & FB_ACCELF_TEXT)
-	    par->accel = FB_ACCELF_TEXT;
+	DPRINTK("ENTER\n");
+	par->var.xres = var->xres;
+	par->var.yres = var->yres;
+	par->var.xres_virtual = var->xres_virtual;
+	par->var.yres_virtual = var->yres_virtual;
+	/* roundup and validate */
+	par->var.xres = (par->var.xres+7) & ~7;
+	par->var.xres_virtual = (par->var.xres_virtual+7) & ~7;
+	if (par->var.xres_virtual < par->var.xres)
+		par->var.xres_virtual = par->var.xres;
+	if (par->var.yres_virtual < par->var.yres)
+		par->var.yres_virtual = par->var.yres;
+	par->var.xoffset = var->xoffset;
+	par->var.yoffset = var->yoffset;
+	par->var.bits_per_pixel = var->bits_per_pixel;
+	if (par->var.bits_per_pixel <= 8)
+		par->var.bits_per_pixel = 8;
+	else if (par->var.bits_per_pixel <= 16)
+		par->var.bits_per_pixel = 16;
 	else
-	    par->accel = 0;
-#else
-	if (Cyberfb_Cyber8) {
-		par->xres = VIRGE8_WIDTH;
-		par->yres = VIRGE8_HEIGHT;
-		par->bpp = 8;
+		par->var.bits_per_pixel = 32;
+#ifndef FBCON_HAS_CFB32
+	if (par->var.bits_per_pixel == 32)
+		par->var.bits_per_pixel = 16;
+#endif
+#ifndef FBCON_HAS_CFB16
+	if (par->var.bits_per_pixel == 16)
+		par->var.bits_per_pixel = 8;
+#endif
+	par->var.grayscale = var->grayscale;
+	par->var.red = var->red;
+	par->var.green = var->green;
+	par->var.blue = var->blue;
+	par->var.transp = var->transp;
+	par->var.nonstd = var->nonstd;
+	par->var.activate = var->activate;
+	par->var.height = var->height;
+	par->var.width = var->width;
+	if (var->accel_flags & FB_ACCELF_TEXT) {
+		par->var.accel_flags = FB_ACCELF_TEXT;
 	} else {
-		par->xres = VIRGE16_WIDTH;
-		par->yres = VIRGE16_HEIGHT;
-		par->bpp = 16;
+		par->var.accel_flags = 0;
 	}
-#endif
-	return(0);
+	par->var.pixclock = var->pixclock;
+	par->var.left_margin = var->left_margin;
+	par->var.right_margin = var->right_margin;
+	par->var.upper_margin = var->upper_margin;
+	par->var.lower_margin = var->lower_margin;
+	par->var.hsync_len = var->hsync_len;
+	par->var.vsync_len = var->vsync_len;
+	par->var.sync = var->sync;
+	par->var.vmode = var->vmode;
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
-
 /*
- *    Fill the `var' structure based on the values in `par' and maybe
- *    other values read out of the hardware.
+ *	Fill the `var' structure based on the values in `par' and maybe
+ *	other values read out of the hardware.
  */
 
-static int Cyber_encode_var(struct fb_var_screeninfo *var,
-			    struct virgefb_par *par)
+static int virgefb_encode_var(struct fb_var_screeninfo *var,
+				struct virgefb_par *par)
 {
-	memset(var, 0, sizeof(struct fb_var_screeninfo));
-	var->xres = par->xres;
-	var->yres = par->yres;
-	var->xres_virtual = par->xres;
-	var->yres_virtual = par->yres;
-	var->xoffset = 0;
-	var->yoffset = 0;
-
-	var->bits_per_pixel = par->bpp;
-	var->grayscale = 0;
-
-	switch (var->bits_per_pixel) {
-		case 8:		/* CLUT */
-			var->red.offset = 0;
-			var->red.length = 6;
-			var->red.msb_right = 0;
-			var->blue = var->green = var->red;
-			break;
-		case 16:	/* RGB 565 */
-			var->red.offset = 11;
-			var->red.length = 5;
-			var->green.offset = 5;
-			var->green.length = 6;
-			var->blue.offset = 0;
-			var->blue.length = 5;
-			var->transp.offset = 0;
-			var->transp.length = 0;
-			break;
-	}
-	var->red.msb_right = 0;
-	var->green.msb_right = 0;
-	var->blue.msb_right = 0;
-	var->transp.msb_right = 0;
-
-	var->nonstd = 0;
-	var->activate = 0;
-
-	var->height = -1;
-	var->width = -1;
-
- 	var->accel_flags = (par->accel &&
-		((par->bpp == 8) || (par->bpp == 16))) ? FB_ACCELF_TEXT : 0;
-
-/*	printk("CV64/3D : %s\n",(var->accel_flags ? "accel" : "no accel")); */
-
-	var->vmode = FB_VMODE_NONINTERLACED;
-
-	/* Dummy values */
-
-	if (par->bpp == 8)
-		var->pixclock = VIRGE8_PIXCLOCK;
-	else
-		var->pixclock = VIRGE16_PIXCLOCK;
-	var->sync = 0;
-	var->left_margin = 64;
-	var->right_margin = 96;
-	var->upper_margin = 35;
-	var->lower_margin = 12;
-	var->hsync_len = 112;
-	var->vsync_len = 2;
-
-	return(0);
+	DPRINTK("ENTER\n");
+	memset(var, 0, sizeof(struct fb_var_screeninfo));	/* need this ? */
+	var->xres = par->var.xres;
+	var->yres = par->var.yres;
+	var->xres_virtual = par->var.xres_virtual;
+	var->yres_virtual = par->var.yres_virtual;
+	var->xoffset = par->var.xoffset;
+	var->yoffset = par->var.yoffset;
+	var->bits_per_pixel = par->var.bits_per_pixel;
+	var->grayscale = par->var.grayscale;
+	var->red = par->var.red;
+	var->green = par->var.green;
+	var->blue = par->var.blue;
+	var->transp = par->var.transp;
+	var->nonstd = par->var.nonstd;
+	var->activate = par->var.activate;
+	var->height = par->var.height;
+	var->width = par->var.width;
+	var->accel_flags = par->var.accel_flags;
+	var->pixclock = par->var.pixclock;
+	var->left_margin = par->var.left_margin;
+	var->right_margin = par->var.right_margin;
+	var->upper_margin = par->var.upper_margin;
+	var->lower_margin = par->var.lower_margin;
+	var->hsync_len = par->var.hsync_len;
+	var->vsync_len = par->var.vsync_len;
+	var->sync = par->var.sync;
+	var->vmode = par->var.vmode;
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
-
 /*
  *    Set a single color register. The values supplied are already
  *    rounded down to the hardware's capabilities (according to the
  *    entries in the var structure). Return != 0 for invalid regno.
  */
 
-static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 			   u_int transp, struct fb_info *info)
 {
-	if (((current_par.bpp==8) && (regno>255)) ||
-		((current_par.bpp!=8) && (regno>15)))
-			return (1);
-
-	if (((current_par.bpp==8) && (regno<256)) || ((current_par.bpp==16) &&(regno<16))) {
-		Cyber_colour_table [regno][0] = red >> 10;
-		Cyber_colour_table [regno][1] = green >> 10;
-		Cyber_colour_table [regno][2] = blue >> 10;
+	DPRINTK("ENTER\n");
+	if (((current_par.var.bits_per_pixel==8) && (regno>255)) ||
+		((current_par.var.bits_per_pixel!=8) && (regno>15))) {
+			DPRINTK("EXIT\n");
+			return 1;
+	}
+	if (((current_par.var.bits_per_pixel==8) && (regno<256)) ||
+			((current_par.var.bits_per_pixel!=8) && (regno<16))) {
+		virgefb_colour_table [regno][0] = red >> 10;
+		virgefb_colour_table [regno][1] = green >> 10;
+		virgefb_colour_table [regno][2] = blue >> 10;
 	}
 
-	switch (current_par.bpp) {
+	switch (current_par.var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
 		case 8:
-			vgawb_3d(0x3c8, (unsigned char) regno);
-			vgawb_3d(0x3c9, ((unsigned char) (red >> 10)));
-			vgawb_3d(0x3c9, ((unsigned char) (green >> 10)));
-			vgawb_3d(0x3c9, ((unsigned char) (blue >> 10)));
+			wb_mmio(VDAC_ADDRESS_W, (unsigned char)regno);
+			wb_mmio(VDAC_DATA, ((unsigned char)(red >> 10)));
+			wb_mmio(VDAC_DATA, ((unsigned char)(green >> 10)));
+			wb_mmio(VDAC_DATA, ((unsigned char)(blue >> 10)));
 			break;
 #endif
 #ifdef FBCON_HAS_CFB16
@@ -603,8 +1157,18 @@
 				((blue  & 0xf800) >> 11));
 			break;
 #endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			fbcon_cmap.cfb32[regno] =
+				/* transp = 0's or 1's  ? */
+				(((red  & 0xff00) << 8) |
+				((green & 0xff00) >> 0) |
+				((blue  & 0xff00) >> 8));
+			break;
+#endif
 	}
-	return (0);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -613,25 +1177,29 @@
  *    colors/transparent. Return != 0 for invalid regno.
  */
 
-static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
 			   u_int *transp, struct fb_info *info)
 {
 	int t;
 
-	if (regno > 255)
-		return (1);
-
-	if (((current_par.bpp==8) && (regno<256)) || ((current_par.bpp==16) && (regno<16))) {
-
-		t = Cyber_colour_table [regno][0];
-		*red    = (t<<10) | (t<<4) | (t>>2);
-		t = Cyber_colour_table [regno][1];
-		*green  = (t<<10) | (t<<4) | (t>>2);
-		t = Cyber_colour_table [regno][2];
-		*blue   = (t<<10) | (t<<4) | (t>>2);
+	DPRINTK("ENTER\n");
+	if (regno > 255) {
+		DPRINTK("EXIT\n");
+		return 1;
+	}
+	if (((current_par.var.bits_per_pixel==8) && (regno<256)) ||
+			((current_par.var.bits_per_pixel!=8) && (regno<16))) {
+
+		t = virgefb_colour_table [regno][0];
+		*red = (t<<10) | (t<<4) | (t>>2);
+		t = virgefb_colour_table [regno][1];
+		*green = (t<<10) | (t<<4) | (t>>2);
+		t = virgefb_colour_table [regno][2];
+		*blue = (t<<10) | (t<<4) | (t>>2);
 	}
 	*transp = 0;
-	return (0);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -639,75 +1207,37 @@
  *    (Un)Blank the screen
  */
 
-void Cyber_blank(int blank)
+static void virgefb_gfx_on_off(int blank)
 {
-	int i;
-
-	if (blank)
-	{
-		for (i = 0; i < 256; i++)
-		{
-			vgawb_3d(0x3c8, (unsigned char) i);
-			vgawb_3d(0x3c9, 0);
-			vgawb_3d(0x3c9, 0);
-			vgawb_3d(0x3c9, 0);
-		}
-	}
-	else
-	{
-		for (i = 0; i < 256; i++)
-		{
-			vgawb_3d(0x3c8, (unsigned char) i);
-			vgawb_3d(0x3c9, Cyber_colour_table[i][0]);
-			vgawb_3d(0x3c9, Cyber_colour_table[i][1]);
-			vgawb_3d(0x3c9, Cyber_colour_table[i][2]);
-		}
-	}
+	DPRINTK("ENTER\n");
+	gfx_on_off(blank);
+	DPRINTK("EXIT\n");
 }
 
 /*
  * CV3D low-level support
  */
 
-#define Cyber3D_WaitQueue(v) \
-{ \
-	 do { \
-		while ((rl_3d(0x8504) & 0x1f00) < (((v)+2) << 8)); \
-	 } \
-	while (0); \
-}
 
-static inline void Cyber3D_WaitBusy(void)
+static inline void wait_3d_fifo_slots(int n)	/* WaitQueue */
 {
-unsigned long status;
-
 	do {
 		mb();
-		status = rl_3d(0x8504);
-	} while (!(status & (1 << 13)));
-	blit_maybe_busy = 0;
+	} while (((rl_mmio(MR_SUBSYSTEM_STATUS_R) >> 8) & 0x1f) < (n + 2));
 }
 
-#define S3V_BITBLT	(0x0 << 27)
-#define S3V_RECTFILL	(0x2 << 27)
-#define S3V_AUTOEXE	0x01
-#define S3V_HWCLIP	0x02
-#define S3V_DRAW	0x20
-#define S3V_DST_8BPP	0x00
-#define S3V_DST_16BPP	0x04
-#define S3V_DST_24BPP	0x08
-#define S3V_MONO_PAT	0x100
-
-#define S3V_BLT_COPY	(0xcc<<17)
-#define S3V_BLT_CLEAR	(0x00<<17)
-#define S3V_BLT_SET	(0xff<<17)
+static inline void virgefb_wait_for_idle(void)	/* WaitIdle */
+{
+	while(!(rl_mmio(MR_SUBSYSTEM_STATUS_R) & 0x2000)) ;
+	blit_maybe_busy = 0;
+}
 
  /*
   * BitBLT - Through the Plane
   */
 
-static void Cyber3D_BitBLT(u_short curx, u_short cury, u_short destx,
-			   u_short desty, u_short width, u_short height, u_short depth)
+static void virgefb_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
+			u_short width, u_short height, u_short stride, u_short depth)
 {
 	unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_BLT_COPY;
 
@@ -722,61 +1252,56 @@
 			blitcmd |= S3V_DST_16BPP;
 			break;
 #endif
+#ifdef FBCON_HAS_CFB32
+		case 32 :
+			/* 32 bit uses 2 by 16 bit values, see fbcon_virge32_bmove */
+			blitcmd |= S3V_DST_16BPP;
+			break;
+#endif
 	}
 
 	/* Set drawing direction */
 	/* -Y, X maj, -X (default) */
-	if (curx > destx)
-	{
+	if (curx > destx) {
 		blitcmd |= (1 << 25);  /* Drawing direction +X */
-	}
-	else
-	{
+	} else {
 		curx  += (width - 1);
 		destx += (width - 1);
 	}
 
-	if (cury > desty)
-	{
+	if (cury > desty) {
 		blitcmd |= (1 << 26);  /* Drawing direction +Y */
-	}
-	else
-	{
+	} else {
 		cury  += (height - 1);
 		desty += (height - 1);
 	}
 
-	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
-	blit_maybe_busy = 1;
-
-	wl_3d(0xa4f4, 1); /* pattern fb color */
+	wait_3d_fifo_slots(8);		/* wait on fifo slots for 8 writes */
 
-	wl_3d(0xa4e8, ~0); /* mono pat 0 */
-	wl_3d(0xa4ec, ~0); /* mono pat 1 */
-
-	wl_3d(0xa504, ((width << 16) | height));	/* rwidth_height */
-	wl_3d(0xa508, ((curx << 16)  | cury));		/* rsrc_xy */
-	wl_3d(0xa50c, ((destx << 16) | desty));		/* rdest_xy */
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	blit_maybe_busy = 1;
 
-	wl_3d(0xa500, blitcmd);				/* GO! */
+	wl_mmio(BLT_PATTERN_COLOR, 1);	/* pattern fb color */
+	wl_mmio(BLT_MONO_PATTERN_0, ~0);
+	wl_mmio(BLT_MONO_PATTERN_1, ~0);
+	wl_mmio(BLT_SIZE_X_Y, ((width << 16) | height));
+	wl_mmio(BLT_SRC_X_Y, ((curx << 16)  | cury));
+	wl_mmio(BLT_DEST_X_Y, ((destx << 16) | desty));
+	wl_mmio(BLT_SRC_DEST_STRIDE, (((stride << 16) | stride) /* & 0x0ff80ff8 */)); /* why is this needed now ? */
+	wl_mmio(BLT_COMMAND_SET, blitcmd);
 }
 
 /*
  * Rectangle Fill Solid
  */
 
-static void Cyber3D_RectFill(u_short x, u_short y, u_short width,
-			     u_short height, u_short color, u_short depth)
+static void virgefb_RectFill(u_short x, u_short y, u_short width, u_short height,
+			u_short color,  u_short stride, u_short depth)
 {
-	unsigned int tmp;
 	unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW |
 		S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25);
 
-	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
-	blit_maybe_busy = 1;
-
 	switch (depth) {
 #ifdef FBCON_HAS_CFB8
 		case 8 :
@@ -788,36 +1313,44 @@
 			blitcmd |= S3V_DST_16BPP;
 			break;
 #endif
+#ifdef FBCON_HAS_CFB32
+		case 32 :
+			/* 32 bit uses 2 times 16 bit values, see fbcon_virge32_clear */
+			blitcmd |= S3V_DST_16BPP;
+			break;
+#endif
 	}
 
-	tmp = color & 0xff;
-	wl_3d(0xa4f4, tmp);
+	wait_3d_fifo_slots(5);		/* wait on fifo slots for 5 writes */
 
-	wl_3d(0xa504, ((width << 16) | height));	/* rwidth_height */
-	wl_3d(0xa50c, ((x << 16) | y));			/* rdest_xy */
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	blit_maybe_busy = 1;
 
-	wl_3d(0xa500, blitcmd);				/* GO! */
+	wl_mmio(BLT_PATTERN_COLOR, (color & 0xff));
+	wl_mmio(BLT_SIZE_X_Y, ((width << 16) | height));
+	wl_mmio(BLT_DEST_X_Y, ((x << 16) | y));
+	wl_mmio(BLT_SRC_DEST_STRIDE, (((stride << 16) | stride) /* & 0x0ff80ff8 */));
+	wl_mmio(BLT_COMMAND_SET, blitcmd);
 }
 
-
-/**************************************************************
+/*
  * Move cursor to x, y
  */
 
 #if 0
-static void Cyber_MoveCursor (u_short x, u_short y)
+static void virgefb_move_cursor(u_short x, u_short y)
 {
-	printk(KERN_DEBUG "Yuck .... MoveCursor on a 3D\n");
-	return;
+	DPRINTK("Yuck .... MoveCursor on a 3D\n");
+	return 0;
 }
 #endif
 
 /* -------------------- Interfaces to hardware functions -------------------- */
 
-
-static struct fb_hwswitch Cyber_switch = {
-	Cyber_init, Cyber_encode_fix, Cyber_decode_var, Cyber_encode_var,
-	Cyber_getcolreg, Cyber_setcolreg, Cyber_blank
+static struct fb_hwswitch virgefb_hw_switch = {
+	Cyber_init, virgefb_encode_fix, virgefb_decode_var, virgefb_encode_var,
+	virgefb_getcolreg, virgefb_setcolreg, virgefb_gfx_on_off
 };
 
 
@@ -830,66 +1363,95 @@
 
 static void virgefb_get_par(struct virgefb_par *par)
 {
-	if (current_par_valid)
-	{
+	DPRINTK("ENTER\n");
+	if (current_par_valid) {
 		*par = current_par;
-	}
-	else
-	{
+	} else {
 		fbhw->decode_var(&virgefb_default, par);
 	}
+	DPRINTK("EXIT\n");
 }
 
 
 static void virgefb_set_par(struct virgefb_par *par)
 {
+	DPRINTK("ENTER\n");
 	current_par = *par;
 	current_par_valid = 1;
+	DPRINTK("EXIT\n");
 }
 
 
-static void virge_set_video(struct fb_var_screeninfo *var)
+static void virgefb_set_video(struct fb_var_screeninfo *var)
 {
-	/* Set clipping rectangle to current screen size */
- 
+/* Set clipping rectangle to current screen size */
+
 	unsigned int clip;
 
+	DPRINTK("ENTER\n");
+	wait_3d_fifo_slots(4);
 	clip = ((0 << 16) | (var->xres - 1));
-	wl_3d(0xa4dc, clip);
+	wl_mmio(BLT_CLIP_LEFT_RIGHT, clip);
 	clip = ((0 << 16) | (var->yres - 1));
-	wl_3d(0xa4e0, clip);
+	wl_mmio(BLT_CLIP_TOP_BOTTOM, clip);
+	wl_mmio(BLT_SRC_BASE, 0);		/* seems we need to clear these two */
+	wl_mmio(BLT_DEST_BASE, 0);
+
+/* Load the video mode defined by the 'var' data */
+
+	virgefb_load_video_mode(var);
+	DPRINTK("EXIT\n");
 }
 
+/*
+Merge these two functions, Geert's suggestion.
+static int virgefb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
+*/
 
-static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
+static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
 {
 	int err, activate;
 	struct virgefb_par par;
 
-	if ((err = fbhw->decode_var(var, &par)))
-		return(err);
+	DPRINTK("ENTER\n");
+	if ((err = fbhw->decode_var(var, &par))) {
+		DPRINTK("EXIT\n");
+		return (err);
+	}
+
 	activate = var->activate;
 	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
 		virgefb_set_par(&par);
 	fbhw->encode_var(var, &par);
 	var->activate = activate;
-
-	virge_set_video(var);
+        if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
+		virgefb_set_video(var);
+	DPRINTK("EXIT\n");
 	return 0;
 }
 
 
-static void do_install_cmap(int con, struct fb_info *info)
+static void virgefb_do_install_cmap(int con, struct fb_info *info)
 {
-	if (con != currcon)
+	DPRINTK("ENTER\n");
+	if (con != currcon) {
+		DPRINTK("EXIT - Not current console\n");
 		return;
-	if (fb_display[con].cmap.len)
+	}
+	if (fb_display[con].cmap.len) {
+		DPRINTK("Use console cmap\n");
 		fb_set_cmap(&fb_display[con].cmap, 1, fbhw->setcolreg, info);
-	else
-		fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+	} else {
+		DPRINTK("Use default cmap\n");
+		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel==8 ? 256 : 16),
 			    1, fbhw->setcolreg, info);
+	}
+	DPRINTK("EXIT\n");
+	return;
 }
 
+
 /*
  *    Get the Fixed Part of the Display
  */
@@ -900,11 +1462,16 @@
 	struct virgefb_par par;
 	int error = 0;
 
+	DPRINTK("ENTER\n");
 	if (con == -1)
 		virgefb_get_par(&par);
 	else
 		error = fbhw->decode_var(&fb_display[con].var, &par);
-	return(error ? error : fbhw->encode_fix(fix, &par));
+
+	if (!error)
+		error = fbhw->encode_fix(fix, &par);
+	DPRINTK("EXIT\n");
+	return(error);
 }
 
 
@@ -918,26 +1485,24 @@
 	struct virgefb_par par;
 	int error = 0;
 
-	if (con == -1)
-	{
+	DPRINTK("ENTER\n");
+	if (con == -1) {
 		virgefb_get_par(&par);
 		error = fbhw->encode_var(var, &par);
 		disp.var = *var;   /* ++Andre: don't know if this is the right place */
-	}
-	else
-	{
+	} else {
 		*var = fb_display[con].var;
 	}
-
+	DPRINTK("EXIT\n");
 	return(error);
 }
 
-
 static void virgefb_set_disp(int con, struct fb_info *info)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
 
+	DPRINTK("ENTER\n");
 	if (con >= 0)
 		display = &fb_display[con];
 	else
@@ -946,16 +1511,25 @@
 	virgefb_get_fix(&fix, con, info);
 	if (con == -1)
 		con = 0;
-	if (cv3d_on_zorro2) {
-		display->screen_base = (char*) CyberMem;
+	if(on_zorro2) {
+		display->screen_base = (char*)v_ram;
 	} else {
 	        switch (display->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
 			case 8:
-				display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_8);
+				display->screen_base = (char*)(v_ram + CYBMEM_OFFSET_8);
 				break;
+#endif
+#ifdef FBCON_HAS_CFB16
 			case 16:
-				display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_16);
+				display->screen_base = (char*)(v_ram + CYBMEM_OFFSET_16);
+				break;
+#endif
+#ifdef FBCON_HAS_CFB32
+			case 32:
+				display->screen_base = (char*)(v_ram + CYBMEM_OFFSET_32);
 				break;
+#endif
 		}
 	}
 	display->visual = fix.visual;
@@ -964,7 +1538,10 @@
 	display->ypanstep = fix.ypanstep;
 	display->ywrapstep = fix.ywrapstep;
 	display->can_soft_blank = 1;
-	display->inverse = Cyberfb_inverse;
+	display->inverse = virgefb_inverse;
+	display->line_length = display->var.xres_virtual*
+			       display->var.bits_per_pixel/8;
+
 	switch (display->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
 		case 8:
@@ -984,10 +1561,20 @@
 			display->dispsw_data = &fbcon_cmap.cfb16;
 			break;
 #endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			if (display->var.accel_flags & FB_ACCELF_TEXT) {
+				display->dispsw = &fbcon_virge32;
+			} else
+				display->dispsw = &fbcon_cfb32;
+			display->dispsw_data = &fbcon_cmap.cfb32;
+			break;
+#endif
 		default:
 			display->dispsw = &fbcon_dummy;
 			break;
 	}
+	DPRINTK("EXIT v_ram virt = 0x%8.8lx\n",(unsigned long)display->screen_base);
 }
 
 
@@ -1000,8 +1587,12 @@
 {
 	int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
 
-	if ((err = do_fb_set_var(var, con == currcon)))
+	DPRINTK("ENTER\n");
+
+	if ((err = virgefb_do_fb_set_var(var, con == currcon))) {
+		DPRINTK("EXIT\n");
 		return(err);
+	}
 	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
 		oldxres = fb_display[con].var.xres;
 		oldyres = fb_display[con].var.yres;
@@ -1016,13 +1607,15 @@
 		    oldbpp != var->bits_per_pixel ||
 		    oldaccel != var->accel_flags) {
 			virgefb_set_disp(con, info);
-			(*fb_info.changevar)(con);
+			if (fb_info.changevar)
+				(*fb_info.changevar)(con);
 			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
-			do_install_cmap(con, info);
+			virgefb_do_install_cmap(con, info);
 		}
 	}
 	var->activate = 0;
-	return(0);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -1033,14 +1626,20 @@
 static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
 			    struct fb_info *info)
 {
-	if (con == currcon) /* current console? */
+	DPRINTK("ENTER\n");
+	if (con == currcon) { /* current console? */
+		DPRINTK("EXIT - console is current console, fb_get_cmap\n");
 		return(fb_get_cmap(cmap, kspc, fbhw->getcolreg, info));
-	else if (fb_display[con].cmap.len) /* non default colormap? */
+	} else if (fb_display[con].cmap.len) { /* non default colormap? */
+		DPRINTK("Use console cmap\n");
 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+	} else {
+		DPRINTK("Use default cmap\n");
+		fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel==8 ? 256 : 16),
 			     cmap, kspc ? 0 : 2);
-	return(0);
+	}
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -1053,16 +1652,23 @@
 {
 	int err;
 
+	DPRINTK("ENTER\n");
 	if (!fb_display[con].cmap.len) {       /* no colormap allocated? */
 		if ((err = fb_alloc_cmap(&fb_display[con].cmap,
-				1<<fb_display[con].var.bits_per_pixel, 0)))
+				(fb_display[con].var.bits_per_pixel==8 ? 256 : 16), 0))) {
+			DPRINTK("EXIT - fb_alloc_cmap failed\n");
 			return(err);
+		}
 	}
-	if (con == currcon)		 /* current console? */
+	if (con == currcon) {		 /* current console? */
+		DPRINTK("EXIT - Current console, fb_set_cmap()\n");
 		return(fb_set_cmap(cmap, kspc, fbhw->setcolreg, info));
-	else
+	} else {
+		DPRINTK("       Not current console, fb_copy_cmap()\n");
 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
-	return(0);
+	}
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -1079,141 +1685,195 @@
 int __init virgefb_setup(char *options)
 {
 	char *this_opt;
-
 	fb_info.fontname[0] = '\0';
 
-	if (!options || !*options)
+	DPRINTK("ENTER\n");
+	if (!options || !*options) {
+		DPRINTK("EXIT\n");
 		return 0;
+	}
 
 	while ((this_opt = strsep(&options, ",")) != NULL) {
 		if (!*this_opt)
 			continue;
 		if (!strcmp(this_opt, "inverse")) {
-			Cyberfb_inverse = 1;
+			virgefb_inverse = 1;
 			fb_invert_cmaps();
 		} else if (!strncmp(this_opt, "font:", 5))
 			strcpy(fb_info.fontname, this_opt+5);
+#ifdef FBCON_HAS_CFB8
 		else if (!strcmp (this_opt, "virge8")){
 			virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var;
 		}
+#endif
+#ifdef FBCON_HAS_CFB16
 		else if (!strcmp (this_opt, "virge16")){
 			virgefb_default = virgefb_predefined[VIRGE16_DEFMODE].var;
 		}
+#endif
+#ifdef FBCON_HAS_CFB32
+		else if (!strcmp (this_opt, "virge32")){
+			virgefb_default = virgefb_predefined[VIRGE32_DEFMODE].var;
+		}
+#endif
 		else
-			get_video_mode(this_opt);
+			virgefb_get_video_mode(this_opt);
 	}
 
-	DPRINTK("default mode: xres=%d, yres=%d, bpp=%d\n",virgefb_default.xres,
-                                                           virgefb_default.yres,
-		                                           virgefb_default.bits_per_pixel);
+	printk(KERN_INFO "mode : xres=%d, yres=%d, bpp=%d\n", virgefb_default.xres,
+			virgefb_default.yres, virgefb_default.bits_per_pixel);
+	DPRINTK("EXIT\n");
 	return 0;
 }
 
 
 /*
+ *    Get a Video Mode
+ */
+
+static int __init virgefb_get_video_mode(const char *name)
+{
+	int i;
+
+	DPRINTK("ENTER\n");
+	for (i = 0; i < NUM_TOTAL_MODES; i++) {
+		if (!strcmp(name, virgefb_predefined[i].name)) {
+			virgefb_default = virgefb_predefined[i].var;
+			DPRINTK("EXIT\n");
+			return(i);
+		}
+	}
+	/* ++Andre: set virgefb default mode */
+
+/* prefer 16 bit depth, 8 if no 16, if no 8 or 16 use 32 */
+
+#ifdef FBCON_HAS_CFB32
+	virgefb_default = virgefb_predefined[VIRGE32_DEFMODE].var;
+#endif
+#ifdef FBCON_HAS_CFB8
+	virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var;
+#endif
+#ifdef FBCON_HAS_CFB16
+	virgefb_default = virgefb_predefined[VIRGE16_DEFMODE].var;
+#endif
+	DPRINTK("EXIT\n");
+	return 0;
+}
+
+/*
  *    Initialization
  */
 
 int __init virgefb_init(void)
 {
 	struct virgefb_par par;
-	unsigned long board_addr, ramsize;
+	unsigned long board_addr, board_size;
 	struct zorro_dev *z = NULL;
 
-	while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64_3D, z))) {
-	    board_addr = z->resource.start;
-	    if (board_addr < 0x01000000) {
-		/*
-		 * Ok we got the board running in Z2 space.
-		 */
-		 CyberRegs_phys = (unsigned long)(board_addr + 0x003e0000);
-		 CyberMem_phys = board_addr;
-		 ramsize = 0x00380000;
-	    } else {
-		CyberRegs_phys = board_addr + 0x05000000;
-		CyberMem_phys  = board_addr + 0x04000000;	/* was 0x04800000 */
-		ramsize = 0x00400000;
-	    }
-	    if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 ViRGE"))
-		continue;
-	    if (!request_mem_region(CyberMem_phys, ramsize, "RAM")) {
-		release_mem_region(CyberRegs_phys, 0x10000);
-		continue;
-	    }
-
-	    if (board_addr < 0x01000000) {
-		/*
-		 * Ok we got the board running in Z2 space.
-		 */
-
-		CyberMem = ZTWO_VADDR(CyberMem_phys);
-		CyberVGARegs = (unsigned long) \
-			ZTWO_VADDR(board_addr + 0x003c0000);
-		CyberRegs = (unsigned char *)ZTWO_VADDR(CyberRegs_phys);
-		Cyber_register_base = (unsigned long) \
-			ZTWO_VADDR(board_addr + 0x003c8000);
-		Cyber_vcode_switch_base = (unsigned long) \
-			ZTWO_VADDR(board_addr + 0x003a0000);
-		cv3d_on_zorro2 = 1;
+	DPRINTK("ENTER\n");
+
+	z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64_3D, NULL);
+	if (!z)
+		return -ENODEV;
+
+	board_addr = z->resource.start;
+	if (board_addr < 0x01000000) {
+
+		/* board running in Z2 space. This includes the video memory
+		    as well as the S3 register set */
+
+		on_zorro2 = 1;
+		board_size = 0x00400000;
+
+		if (!request_mem_region(board_addr, board_size, "S3 ViRGE"))
+			return -ENOMEM;
+
+		v_ram_phys = board_addr;
+		v_ram = ZTWO_VADDR(v_ram_phys);
+		mmio_regs_phys = (unsigned long)(board_addr + 0x003c0000);
+		vgaio_regs = (unsigned char *) ZTWO_VADDR(board_addr + 0x003c0000);
+		mmio_regs = (unsigned char *)ZTWO_VADDR(mmio_regs_phys);
+		vcode_switch_base = (unsigned long) ZTWO_VADDR(board_addr + 0x003a0000);
 		printk(KERN_INFO "CV3D detected running in Z2 mode.\n");
-	    } else {
-		CyberVGARegs = (unsigned long)ioremap(board_addr+0x0c000000, 0x00010000);
-		CyberRegs = ioremap(CyberRegs_phys, 0x00010000);
-		CyberMem = (unsigned long)ioremap(CyberMem_phys, 0x01000000);	/* was 0x00400000 */
-		cv3d_on_zorro2 = 0;
-		printk(KERN_INFO "CV3D detected running in Z3 mode.\n");
-	    }
-
-	    fbhw = &Cyber_switch;
-
-	    strcpy(fb_info.modename, virgefb_name);
-	    fb_info.changevar = NULL;
-	    fb_info.node = -1;
-	    fb_info.fbops = &virgefb_ops;
-	    fb_info.disp = &disp;
-	    fb_info.switch_con = &Cyberfb_switch;
-	    fb_info.updatevar = &Cyberfb_updatevar;
-	    fb_info.blank = &Cyberfb_blank;
-	    fb_info.flags = FBINFO_FLAG_DEFAULT;
-
-	    fbhw->init();
-	    fbhw->decode_var(&virgefb_default, &par);
-	    fbhw->encode_var(&virgefb_default, &par);
-
-	    do_fb_set_var(&virgefb_default, 1);
-	    virgefb_get_var(&fb_display[0].var, -1, &fb_info);
-	    virgefb_set_disp(-1, &fb_info);
-	    do_install_cmap(0, &fb_info);
 
-	    if (register_framebuffer(&fb_info) < 0) {
+	} else {
+
+		/* board running in Z3 space. Seperate video memory (3 apertures)
+		   and S3 register set */
+
+		on_zorro2 = 0;
+		board_size = 0x01000000;
+
+		if (!request_mem_region(board_addr, board_size, "S3 ViRGE"))
+			return -ENOMEM;
+
+		v_ram_phys  = board_addr + 0x04000000;
+		v_ram = (unsigned long)ioremap(v_ram_phys, 0x01000000);
+		mmio_regs_phys = board_addr + 0x05000000;
+		vgaio_regs = (unsigned char *)ioremap(board_addr +0x0c000000, 0x00100000); /* includes PCI regs */
+		mmio_regs = ioremap(mmio_regs_phys, 0x00010000);
+		vcode_switch_base = (unsigned long)ioremap(board_addr + 0x08000000, 0x1000);
+		printk(KERN_INFO "CV3D detected running in Z3 mode\n");
+	}
+
+#if defined (VIRGEFBDEBUG)
+	DPRINTK("board_addr     : 0x%8.8lx\n",board_addr);
+	DPRINTK("board_size     : 0x%8.8lx\n",board_size);
+	DPRINTK("mmio_regs_phy  : 0x%8.8lx\n",mmio_regs_phys);
+	DPRINTK("v_ram_phys     : 0x%8.8lx\n",v_ram_phys);
+	DPRINTK("vgaio_regs     : 0x%8.8lx\n",(unsigned long)vgaio_regs);
+	DPRINTK("mmio_regs      : 0x%8.8lx\n",(unsigned long)mmio_regs);
+	DPRINTK("v_ram          : 0x%8.8lx\n",v_ram);
+	DPRINTK("vcode sw base  : 0x%8.8lx\n",vcode_switch_base);
+#endif
+	fbhw = &virgefb_hw_switch;
+	strcpy(fb_info.modename, virgefb_name);
+	fb_info.changevar = NULL;
+	fb_info.node = -1;
+	fb_info.fbops = &virgefb_ops;
+	fb_info.disp = &disp;
+	fb_info.switch_con = &virgefb_switch;
+	fb_info.updatevar = &virgefb_updatevar;
+	fb_info.blank = &virgefb_blank;
+	fb_info.flags = FBINFO_FLAG_DEFAULT;
+	fbhw->init();
+	fbhw->decode_var(&virgefb_default, &par);
+	fbhw->encode_var(&virgefb_default, &par);
+	virgefb_do_fb_set_var(&virgefb_default, 1);
+	virgefb_get_var(&fb_display[0].var, -1, &fb_info);
+	virgefb_set_disp(-1, &fb_info);
+	virgefb_do_install_cmap(0, &fb_info);
+
+	if (register_framebuffer(&fb_info) < 0) {
+		#warning release resources
 		printk(KERN_ERR "virgefb.c: register_framebuffer failed\n");
+		DPRINTK("EXIT\n");
 		return -EINVAL;
-	    }
+	}
 
-	    printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
-		   "video memory\n", GET_FB_IDX(fb_info.node),
-		   fb_info.modename, CyberSize>>10);
+	printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
+	       GET_FB_IDX(fb_info.node), fb_info.modename, v_ram_size>>10);
 
-	    /* TODO: This driver cannot be unloaded yet */
-	    MOD_INC_USE_COUNT;
-	    return 0;
-	}
-	return -ENODEV;
+	/* TODO: This driver cannot be unloaded yet */
+
+	MOD_INC_USE_COUNT;
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
-static int Cyberfb_switch(int con, struct fb_info *info)
+static int virgefb_switch(int con, struct fb_info *info)
 {
+	DPRINTK("ENTER\n");
 	/* Do we have to save the colormap? */
 	if (fb_display[currcon].cmap.len)
-		fb_get_cmap(&fb_display[currcon].cmap, 1, fbhw->getcolreg,
-			    info);
-
-	do_fb_set_var(&fb_display[con].var, 1);
+		fb_get_cmap(&fb_display[currcon].cmap, 1, fbhw->getcolreg, info);
+	virgefb_do_fb_set_var(&fb_display[con].var, 1);
 	currcon = con;
 	/* Install new colormap */
-	do_install_cmap(con, info);
-	return(0);
+	virgefb_do_install_cmap(con, info);
+	DPRINTK("EXIT\n");
+	return 0;
 }
 
 
@@ -1224,39 +1884,22 @@
  *    Since it's called by a kernel driver, no range checking is done.
  */
 
-static int Cyberfb_updatevar(int con, struct fb_info *info)
+static int virgefb_updatevar(int con, struct fb_info *info)
 {
-	return(0);
+	DPRINTK("ENTER\n");
+	return 0;
+	DPRINTK("EXIT\n");
 }
 
-
 /*
  *    Blank the display.
  */
 
-static void Cyberfb_blank(int blank, struct fb_info *info)
+static void virgefb_blank(int blank, struct fb_info *info)
 {
+	DPRINTK("ENTER\n");
 	fbhw->blank(blank);
-}
-
-
-/*
- *    Get a Video Mode
- */
-
-static int __init get_video_mode(const char *name)
-{
-	int i;
-
-	for (i = 0; i < NUM_TOTAL_MODES; i++) {
-		if (!strcmp(name, virgefb_predefined[i].name)) {
-			virgefb_default = virgefb_predefined[i].var;
-			return(i);
-		}
-	}
-	/* ++Andre: set virgefb default mode */
-	virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var;
-	return(0);
+	DPRINTK("EXIT\n");
 }
 
 
@@ -1269,9 +1912,9 @@
 			       int dx, int height, int width)
 {
         sx *= 8; dx *= 8; width *= 8;
-        Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
+        virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
                        (u_short)(dy*fontheight(p)), (u_short)width,
-                       (u_short)(height*fontheight(p)), 8);
+                       (u_short)(height*fontheight(p)), (u_short)p->next_line, 8);
 }
 
 static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
@@ -1281,16 +1924,16 @@
 
         sx *= 8; width *= 8;
         bg = attr_bgcol_ec(p,conp);
-        Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
+        virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
                          (u_short)width, (u_short)(height*fontheight(p)),
-                         (u_short)bg, 8);
+                         (u_short)bg, (u_short)p->next_line, 8);
 }
 
 static void fbcon_virge8_putc(struct vc_data *conp, struct display *p, int c, int yy,
                               int xx)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb8_putc(conp, p, c, yy, xx);
 }
 
@@ -1298,14 +1941,14 @@
                       const unsigned short *s, int count, int yy, int xx)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
 }
 
 static void fbcon_virge8_revc(struct display *p, int xx, int yy)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb8_revc(p, xx, yy);
 }
 
@@ -1313,19 +1956,19 @@
                               int bottom_only)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb8_clear_margins(conp, p, bottom_only);
 }
 
 static struct display_switch fbcon_virge8 = {
-   setup:		fbcon_cfb8_setup,
-   bmove:		fbcon_virge8_bmove,
-   clear:		fbcon_virge8_clear,
-   putc:		fbcon_virge8_putc,
-   putcs:		fbcon_virge8_putcs,
-   revc:		fbcon_virge8_revc,
-   clear_margins:	fbcon_virge8_clear_margins,
-   fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	setup:		fbcon_cfb8_setup,
+	bmove:		fbcon_virge8_bmove,
+	clear:		fbcon_virge8_clear,
+	putc:		fbcon_virge8_putc,
+	putcs:		fbcon_virge8_putcs,
+	revc:		fbcon_virge8_revc,
+	clear_margins:	fbcon_virge8_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 
@@ -1334,28 +1977,28 @@
                                int dx, int height, int width)
 {
         sx *= 8; dx *= 8; width *= 8;
-        Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
+        virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
                        (u_short)(dy*fontheight(p)), (u_short)width,
-                       (u_short)(height*fontheight(p)), 16);
+                       (u_short)(height*fontheight(p)), (u_short)p->next_line, 16);
 }
-                
+
 static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy,
                                int sx, int height, int width)
 {
-        unsigned char bg;   
-                
+        unsigned char bg;
+
         sx *= 8; width *= 8;
         bg = attr_bgcol_ec(p,conp);
-        Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
+        virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
                          (u_short)width, (u_short)(height*fontheight(p)),
-                         (u_short)bg, 16);
+                         (u_short)bg, (u_short)p->next_line, 16);
 }
-   
+
 static void fbcon_virge16_putc(struct vc_data *conp, struct display *p, int c, int yy,
                               int xx)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb16_putc(conp, p, c, yy, xx);
 }
 
@@ -1363,14 +2006,14 @@
                       const unsigned short *s, int count, int yy, int xx)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
 }
 
 static void fbcon_virge16_revc(struct display *p, int xx, int yy)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb16_revc(p, xx, yy);
 }
 
@@ -1378,19 +2021,84 @@
                               int bottom_only)
 {
 	if (blit_maybe_busy)
-		Cyber3D_WaitBusy();
+		virgefb_wait_for_idle();
 	fbcon_cfb16_clear_margins(conp, p, bottom_only);
 }
 
 static struct display_switch fbcon_virge16 = {
-   setup:		fbcon_cfb16_setup,
-   bmove:		fbcon_virge16_bmove,
-   clear:		fbcon_virge16_clear,
-   putc:		fbcon_virge16_putc,
-   putcs:		fbcon_virge16_putcs,
-   revc:		fbcon_virge16_revc,
-   clear_margins:	fbcon_virge16_clear_margins,
-   fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	setup:		fbcon_cfb16_setup,
+	bmove:		fbcon_virge16_bmove,
+	clear:		fbcon_virge16_clear,
+	putc:		fbcon_virge16_putc,
+	putcs:		fbcon_virge16_putcs,
+	revc:		fbcon_virge16_revc,
+	clear_margins:	fbcon_virge16_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static void fbcon_virge32_bmove(struct display *p, int sy, int sx, int dy,
+			       int dx, int height, int width)
+{
+        sx *= 16; dx *= 16; width *= 16;	/* doubled these values to do 32 bit blit */
+        virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
+                       (u_short)(dy*fontheight(p)), (u_short)width,
+                       (u_short)(height*fontheight(p)), (u_short)p->next_line, 16);
+}
+
+static void fbcon_virge32_clear(struct vc_data *conp, struct display *p, int sy,
+			       int sx, int height, int width)
+{
+        unsigned char bg;
+
+        sx *= 16; width *= 16;			/* doubled these values to do 32 bit blit */
+        bg = attr_bgcol_ec(p,conp);
+        virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
+                         (u_short)width, (u_short)(height*fontheight(p)),
+                         (u_short)bg, (u_short)p->next_line, 16);
+}
+
+static void fbcon_virge32_putc(struct vc_data *conp, struct display *p, int c, int yy,
+                              int xx)
+{
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	fbcon_cfb32_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_virge32_putcs(struct vc_data *conp, struct display *p,
+                      const unsigned short *s, int count, int yy, int xx)
+{
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
+}
+
+static void fbcon_virge32_revc(struct display *p, int xx, int yy)
+{
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	fbcon_cfb32_revc(p, xx, yy);
+}
+
+static void fbcon_virge32_clear_margins(struct vc_data *conp, struct display *p,
+                              int bottom_only)
+{
+	if (blit_maybe_busy)
+		virgefb_wait_for_idle();
+	fbcon_cfb32_clear_margins(conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_virge32 = {
+	setup:		fbcon_cfb32_setup,
+	bmove:		fbcon_virge32_bmove,
+	clear:		fbcon_virge32_clear,
+	putc:		fbcon_virge32_putc,
+	putcs:		fbcon_virge32_putcs,
+	revc:		fbcon_virge32_revc,
+	clear_margins:	fbcon_virge32_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 
@@ -1410,3 +2118,450 @@
 	/* TODO: clean up ... */
 }
 #endif /* MODULE */
+
+static int cv3d_has_4mb(void)
+{
+	/* cyberfb version didn't work, neither does this (not reliably)
+	forced to return 4MB */
+#if 0
+	volatile unsigned long *t0, *t2;
+#endif
+	DPRINTK("ENTER\n");
+#if 0
+	/* write patterns in memory and test if they can be read */
+	t0 = (volatile unsigned long *)v_ram;
+	t2 = (volatile unsigned long *)(v_ram + 0x00200000);
+	*t0 = 0x87654321;
+	*t2 = 0x12345678;
+
+	if (*t0 != 0x87654321) {
+		/* read of first location failed */
+		DPRINTK("EXIT - 0MB !\n");
+		return 0;
+	}
+
+	if (*t2 == 0x87654321) {
+		/* should read 0x12345678 if 4MB */
+		DPRINTK("EXIT - 2MB(a) \n");
+		return 0;
+	}
+
+	if (*t2 != 0x12345678) {
+		/* upper 2MB read back match failed */
+		DPRINTK("EXIT - 2MB(b)\n");
+		return 0;
+	}
+
+	/* may have 4MB */
+
+	*t2 = 0xAAAAAAAA;
+
+	if(*t2 != 0xAAAAAAAA) {
+		/* upper 2MB read back match failed */
+		DPRINTK("EXIT - 2MB(c)\n");
+		return 0;
+	}
+
+	*t2 = 0x55555555;
+
+	if(*t2 != 0x55555555) {
+		/* upper 2MB read back match failed */
+		DPRINTK("EXIT - 2MB(d)\n");
+		return 0;
+	}
+
+#endif
+	DPRINTK("EXIT - 4MB\n");
+	return 1;
+}
+
+
+/*
+ * Computes M, N, and R pll params for freq arg.
+ * Returns 16 bits - hi 0MMMMMM lo 0RRNNNNN
+ */
+
+#define REFCLOCK 14318000
+
+static unsigned short virgefb_compute_clock(unsigned long freq)
+{
+
+	unsigned char m, n, r, rpwr;
+	unsigned long diff, ftry, save = ~0UL;
+	unsigned short mnr;
+
+	DPRINTK("ENTER\n");
+
+	for (r = 0, rpwr = 1 ; r < 4 ; r++, rpwr *= 2) {
+		if ((135000000 <= (rpwr * freq)) && ((rpwr * freq) <= 270000000)) {
+			for (n = 1 ; n < 32 ; n++) {
+				m = ((freq * (n + 2) * rpwr)/REFCLOCK) - 2;
+				if (m == 0 || m >127)
+					break;
+				ftry = ((REFCLOCK / (n + 2)) * (m + 2)) / rpwr;
+				if (ftry > freq)
+					diff = ftry - freq;
+				else
+					diff = freq - ftry;
+				if (diff < save) {
+					save = diff;
+					mnr =  (m << 8) | (r<<5) | (n & 0x7f);
+				}
+			}
+		}
+	}
+	if (save == ~0UL)
+		printk("Can't compute clock PLL values for %ld Hz clock\n", freq);
+	DPRINTK("EXIT\n");
+	return(mnr);
+}
+
+static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode)
+{
+	unsigned char lace, dblscan, tmp;
+	unsigned short mnr;
+	unsigned short HT, HDE, HBS, HBW, HSS, HSW;
+	unsigned short VT, VDE, VBS, VBW, VSS, VSW;
+	unsigned short SCO;
+	int cr11;
+	int cr67;
+	int hmul;
+	int xres, xres_virtual, hfront, hsync, hback;
+	int yres, vfront, vsync, vback;
+	int bpp;
+	int i;
+	long freq;
+
+	DPRINTK("ENTER : %dx%d-%d\n",video_mode->xres, video_mode->yres,
+				video_mode->bits_per_pixel);
+
+	bpp = video_mode->bits_per_pixel;
+	xres = video_mode->xres;
+	xres_virtual = video_mode->xres_virtual;
+	hfront = video_mode->right_margin;
+	hsync = video_mode->hsync_len;
+	hback = video_mode->left_margin;
+
+	lace = 0;
+	dblscan = 0;
+
+	if (video_mode->vmode & FB_VMODE_DOUBLE) {
+		yres = video_mode->yres * 2;
+		vfront = video_mode->lower_margin * 2;
+		vsync = video_mode->vsync_len * 2;
+		vback = video_mode->upper_margin * 2;
+		dblscan = 1;
+	} else if (video_mode->vmode & FB_VMODE_INTERLACED) {
+		yres = (video_mode->yres + 1) / 2;
+		vfront = (video_mode->lower_margin + 1) / 2;
+		vsync = (video_mode->vsync_len + 1) / 2;
+		vback = (video_mode->upper_margin + 1) / 2;
+		lace = 1;
+	} else {
+		yres = video_mode->yres;
+		vfront = video_mode->lower_margin;
+		vsync = video_mode->vsync_len;
+		vback = video_mode->upper_margin;
+	}
+
+	switch (bpp) {
+		case 8:
+			video_mode->red.offset = 0;
+			video_mode->green.offset = 0;
+			video_mode->blue.offset = 0;
+			video_mode->transp.offset = 0;
+			video_mode->red.length = 8;
+			video_mode->green.length = 8;
+			video_mode->blue.length = 8;
+			video_mode->transp.length = 0;
+			hmul = 1;
+			cr67 = 0x00;
+			SCO = xres_virtual / 8;
+			break;
+		case 16:
+			video_mode->red.offset = 11;
+			video_mode->green.offset = 5;
+			video_mode->blue.offset = 0;
+			video_mode->transp.offset = 0;
+			video_mode->red.length = 5;
+			video_mode->green.length = 6;
+			video_mode->blue.length = 5;
+			video_mode->transp.length = 0;
+			hmul = 2;
+			cr67 = 0x50;
+			SCO = xres_virtual / 4;
+			break;
+		case 32:
+			video_mode->red.offset = 16;
+			video_mode->green.offset = 8;
+			video_mode->blue.offset = 0;
+			video_mode->transp.offset = 24;
+			video_mode->red.length = 8;
+			video_mode->green.length = 8;
+			video_mode->blue.length = 8;
+			video_mode->transp.length = 8;
+			hmul = 1;
+			cr67 = 0xd0;
+			SCO = xres_virtual / 2;
+			break;
+	}
+
+	HT  = (((xres + hfront + hsync + hback) / 8) * hmul) - 5;
+	HDE = ((xres / 8) * hmul) - 1;
+	HBS = (xres / 8) * hmul;
+	HSS = ((xres + hfront) / 8) * hmul;
+	HSW = (hsync / 8) * hmul;
+	HBW = (((hfront + hsync + hback) / 8) * hmul) - 2;
+
+	VT  = yres + vfront + vsync + vback - 2;
+	VDE = yres - 1;
+	VBS = yres - 1;
+	VSS = yres + vfront;
+	VSW = vsync;
+	VBW = vfront + vsync + vback - 2;
+
+#ifdef VIRGEFBDEBUG
+	DPRINTK("HDE       : 0x%4.4x, %4.4d\n", HDE, HDE);
+	DPRINTK("HBS       : 0x%4.4x, %4.4d\n", HBS, HBS);
+	DPRINTK("HSS       : 0x%4.4x, %4.4d\n", HSS, HSS);
+	DPRINTK("HSW       : 0x%4.4x, %4.4d\n", HSW, HSW);
+	DPRINTK("HBW       : 0x%4.4x, %4.4d\n", HBW, HBW);
+	DPRINTK("HSS + HSW : 0x%4.4x, %4.4d\n", HSS+HSW, HSS+HSW);
+	DPRINTK("HBS + HBW : 0x%4.4x, %4.4d\n", HBS+HBW, HBS+HBW);
+	DPRINTK("HT        : 0x%4.4x, %4.4d\n", HT, HT);
+	DPRINTK("VDE       : 0x%4.4x, %4.4d\n", VDE, VDE);
+	DPRINTK("VBS       : 0x%4.4x, %4.4d\n", VBS, VBS);
+	DPRINTK("VSS       : 0x%4.4x, %4.4d\n", VSS, VSS);
+	DPRINTK("VSW       : 0x%4.4x, %4.4d\n", VSW, VSW);
+	DPRINTK("VBW       : 0x%4.4x, %4.4d\n", VBW, VBW);
+	DPRINTK("VT        : 0x%4.4x, %4.4d\n", VT, VT);
+#endif
+
+/* turn gfx off, don't mess up the display */
+
+ 	gfx_on_off(1);
+
+/* H and V sync polarity */
+
+	tmp = rb_mmio(GREG_MISC_OUTPUT_R) & 0x2f;		/* colour, ram enable, clk sr12/s13 sel */
+	if (!(video_mode->sync & FB_SYNC_HOR_HIGH_ACT))
+		tmp |= 0x40;					/* neg H sync polarity */
+	if (!(video_mode->sync & FB_SYNC_VERT_HIGH_ACT))
+		tmp |= 0x80;					/* neg V sync polarity */
+	tmp |= 0x0c;						/* clk from sr12/sr13 */
+	wb_mmio(GREG_MISC_OUTPUT_W, tmp);
+
+/* clocks */
+
+	wseq(SEQ_ID_BUS_REQ_CNTL, 0xc0);			/* 2 clk mem wr and /RAS1 */
+	wseq(SEQ_ID_CLKSYN_CNTL_2, 0x80);			/* b7 is 2 mem clk wr */
+	mnr = virgefb_compute_clock(MEMCLOCK);
+	DPRINTK("mem clock %d, m %d, n %d, r %d.\n", MEMCLOCK, ((mnr>>8)&0x7f), (mnr&0x1f), ((mnr >> 5)&0x03));
+	wseq(SEQ_ID_MCLK_LO, (mnr & 0x7f));
+	wseq(SEQ_ID_MCLK_HI, ((mnr & 0x7f00) >> 8));
+	freq = (1000000000 / video_mode->pixclock) * 1000;	/* pixclock is in ps ... convert to Hz */
+	mnr = virgefb_compute_clock(freq);
+	DPRINTK("dot clock %ld, m %d, n %d, r %d.\n", freq, ((mnr>>8)&0x7f), (mnr&0x1f), ((mnr>>5)&0x03));
+	wseq(SEQ_ID_DCLK_LO, (mnr & 0x7f));
+	wseq(SEQ_ID_DCLK_HI, ((mnr & 0x7f00) >> 8));
+	wseq(SEQ_ID_CLKSYN_CNTL_2, 0xa0);
+	wseq(SEQ_ID_CLKSYN_CNTL_2, 0x80);
+	udelay(100);
+
+/* load display parameters into board */
+
+	/* not sure about sync and blanking extensions bits in cr5d and cr5 */
+
+	wcrt(CRT_ID_EXT_HOR_OVF,			/* 0x5d */
+		((HT & 0x100) ?         0x01 : 0x00) |
+		((HDE & 0x100) ?        0x02 : 0x00) |
+		((HBS & 0x100) ?        0x04 : 0x00) |
+	/*	(((HBS + HBW) & 0x40) ? 0x08 : 0x00) |	*/
+		((HSS & 0x100) ?        0x10 : 0x00) |
+	/*	(((HSS + HSW) & 0x20) ? 0x20 : 0x00) |	*/
+		((HSW >= 0x20) ?        0x20 : 0x00) |
+		(((HT-5) & 0x100) ?     0x40 : 0x00));
+
+	wcrt(CRT_ID_EXT_VER_OVF,			/* 0x5e */
+		((VT & 0x400) ? 0x01 : 0x00) |
+		((VDE & 0x400) ? 0x02 : 0x00) |
+		((VBS & 0x400) ? 0x04 : 0x00) |
+		((VSS & 0x400) ? 0x10 : 0x00) |
+		0x40);					/* line compare */
+
+	wcrt(CRT_ID_START_VER_RETR, VSS);
+	cr11 = rcrt(CRT_ID_END_VER_RETR) | 0x20;	/* vert interrupt flag */
+	wcrt(CRT_ID_END_VER_RETR, ((cr11 & 0x20) | ((VSS + VSW) & 0x0f)));	/* keeps vert irq enable state, also has unlock bit cr0 to 7 */
+	wcrt(CRT_ID_VER_DISP_ENA_END, VDE);
+	wcrt(CRT_ID_START_VER_BLANK, VBS);
+	wcrt(CRT_ID_END_VER_BLANK, VBS + VBW);		/* might be +/- 1 out */
+	wcrt(CRT_ID_HOR_TOTAL, HT);
+	wcrt(CRT_ID_DISPLAY_FIFO, HT - 5);
+	wcrt(CRT_ID_BACKWAD_COMP_3, 0x10);		/* enable display fifo */
+	wcrt(CRT_ID_HOR_DISP_ENA_END, HDE);
+	wcrt(CRT_ID_START_HOR_BLANK , HBS);
+	wcrt(CRT_ID_END_HOR_BLANK, (HBS + HBW) & 0x1f);
+	wcrt(CRT_ID_START_HOR_RETR, HSS);
+	wcrt(CRT_ID_END_HOR_RETR,			/* cr5 */
+		((HSS + HSW) & 0x1f) |
+		(((HBS + HBW) & 0x20) ? 0x80 : 0x00));
+	wcrt(CRT_ID_VER_TOTAL, VT);
+	wcrt(CRT_ID_OVERFLOW,
+		((VT & 0x100) ? 0x01 : 0x00) |
+		((VDE & 0x100) ? 0x02 : 0x00) |
+		((VSS & 0x100) ? 0x04 : 0x00) |
+		((VBS & 0x100) ? 0x08 : 0x00) |
+		0x10 |
+		((VT & 0x200) ? 0x20 : 0x00) |
+		((VDE & 0x200) ? 0x40 : 0x00) |
+		((VSS & 0x200) ? 0x80 : 0x00));
+	wcrt(CRT_ID_MAX_SCAN_LINE,
+		(dblscan ? 0x80 : 0x00) |
+		0x40 |
+		((VBS & 0x200) ? 0x20 : 0x00));
+	wcrt(CRT_ID_LINE_COMPARE, 0xff);
+	wcrt(CRT_ID_LACE_RETR_START, HT / 2);		/* (HT-5)/2 ? */
+	wcrt(CRT_ID_LACE_CONTROL, (lace ? 0x20 : 0x00));
+
+	wcrt(CRT_ID_SCREEN_OFFSET, SCO);
+	wcrt(CRT_ID_EXT_SYS_CNTL_2, (SCO >> 4) & 0x30 );
+
+	/* wait for vert sync before cr67 update */
+
+	for (i=0; i < 10000; i++) {
+		udelay(10);
+		mb();
+		if (rb_mmio(GREG_INPUT_STATUS1_R) & 0x08)
+			break;
+	}
+
+	wl_mmio(0x8200, 0x0000c000);	/* fifo control  (0x00110400 ?) */
+	wcrt(CRT_ID_EXT_MISC_CNTL_2, cr67);
+
+/* enable video */
+
+	tmp = rb_mmio(ACT_ADDRESS_RESET);
+	wb_mmio(ACT_ADDRESS_W, ((bpp == 8) ? 0x20 : 0x00));	/* set b5, ENB PLT in attr idx reg) */
+	tmp = rb_mmio(ACT_ADDRESS_RESET);
+
+/* turn gfx on again */
+
+	gfx_on_off(0);
+
+/* pass-through */
+
+	SetVSwitch(1);		/* cv3d */
+
+	DUMP;
+	DPRINTK("EXIT\n");
+}
+
+static inline void gfx_on_off(int toggle)
+{
+	unsigned char tmp;
+
+	DPRINTK("ENTER gfx %s\n", (toggle ? "off" : "on"));
+
+	toggle = (toggle & 0x01) << 5;
+	tmp = rseq(SEQ_ID_CLOCKING_MODE) & (~(0x01 << 5));
+	wseq(SEQ_ID_CLOCKING_MODE, tmp | toggle);
+
+	DPRINTK("EXIT\n");
+}
+
+#if defined (VIRGEFBDUMP)
+
+/*
+ * Dump board registers
+ */
+
+static void cv64_dump(void)
+{
+	int i;
+	u8 c, b;
+        u16 w;
+	u32 l;
+
+	/* crt, seq, gfx and atr regs */
+
+	SelectMMIO;
+
+	printk("\n");
+	for (i = 0; i <= 0x6f; i++) {
+		wb_mmio(CRT_ADDRESS, i);
+		printk("crt idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(CRT_ADDRESS_R));
+	}
+	for (i = 0; i <= 0x1c; i++) {
+		wb_mmio(SEQ_ADDRESS, i);
+		printk("seq idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(SEQ_ADDRESS_R));
+	}
+	for (i = 0; i <= 8; i++) {
+		wb_mmio(GCT_ADDRESS, i);
+		printk("gfx idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(GCT_ADDRESS_R));
+	}
+	for (i = 0; i <= 0x14; i++) {
+		c = rb_mmio(ACT_ADDRESS_RESET);
+		wb_mmio(ACT_ADDRESS_W, i);
+		printk("atr idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(ACT_ADDRESS_R));
+	}
+
+	/* re-enable video access to palette */
+
+	c = rb_mmio(ACT_ADDRESS_RESET);
+	udelay(10);
+	wb_mmio(ACT_ADDRESS_W, 0x20);
+	c = rb_mmio(ACT_ADDRESS_RESET);
+	udelay(10);
+
+	/* general regs */
+
+	printk("0x3cc(w 0x3c2) : 0x%2.2x\n", rb_mmio(0x3cc));	/* GREG_MISC_OUTPUT READ */
+	printk("0x3c2(-------) : 0x%2.2x\n", rb_mmio(0x3c2));	/* GREG_INPUT_STATUS 0 READ */
+	printk("0x3c3(w 0x3c3) : 0x%2.2x\n", rb_vgaio(0x3c3));	/* GREG_VIDEO_SUBS_ENABLE */
+	printk("0x3ca(w 0x3da) : 0x%2.2x\n", rb_vgaio(0x3ca));	/* GREG_FEATURE_CONTROL read */
+	printk("0x3da(-------) : 0x%2.2x\n", rb_mmio(0x3da));	/* GREG_INPUT_STATUS 1 READ */
+
+	/* engine regs */
+
+	for (i = 0x8180; i <= 0x8200; i = i + 4)
+		printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
+
+	i = 0x8504;
+	printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
+	i = 0x850c;
+	printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
+	for (i = 0xa4d4; i <= 0xa50c; i = i + 4)
+		printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
+
+	/* PCI regs */
+
+	SelectCFG;
+
+	for (c = 0; c < 0x08; c = c + 2) {
+		w = (*((u16 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 2)));
+		printk("pci 0x%2.2x : 0x%4.4x\n", c, w);
+	}
+	c = 8;
+	l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
+	printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
+	c = 0x0d;
+	b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
+	printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
+	c = 0x10;
+	l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
+	printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
+	c = 0x30;
+	l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
+	printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
+	c = 0x3c;
+	b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
+	printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
+	c = 0x3d;
+	b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
+	printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
+	c = 0x3e;
+	w = (*((u16 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 2)));
+	printk("pci 0x%2.2x : 0x%4.4x\n", c, w);
+	SelectMMIO;
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/video/virgefb.h linux/drivers/video/virgefb.h
--- linux.orig/drivers/video/virgefb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/video/virgefb.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,288 @@
+/*
+ * linux/drivers/video/virgefb.h -- CyberVision64 definitions for the
+ *                                  text console driver.
+ *
+ *   Copyright (c) 1998 Alan Bair
+ *
+ * This file is based on the initial port to Linux of grf_cvreg.h:
+ *
+ *   Copyright (c) 1997 Antonio Santos
+ *
+ * The original work is from the NetBSD CyberVision 64 framebuffer driver 
+ * and support files (grf_cv.c, grf_cvreg.h, ite_cv.c):
+ * Permission to use the source of this driver was obtained from the
+ * author Michael Teske by Alan Bair.
+ *
+ *   Copyright (c) 1995 Michael Teske
+ *
+ * History:
+ *
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/* Enhanced register mapping (MMIO mode) */
+
+#define S3_CRTC_ADR    0x03d4
+#define S3_CRTC_DATA   0x03d5
+
+#define S3_REG_LOCK2	0x39
+#define S3_HGC_MODE	0x45
+
+#define S3_HWGC_ORGX_H	0x46
+#define S3_HWGC_ORGX_L	0x47
+#define S3_HWGC_ORGY_H	0x48
+#define S3_HWGC_ORGY_L	0x49
+#define S3_HWGC_DX	0x4e
+#define S3_HWGC_DY	0x4f
+
+#define S3_LAW_CTL	0x58
+
+/**************************************************/
+
+/*
+ * Defines for the used register addresses (mw)
+ *
+ * NOTE: There are some registers that have different addresses when
+ *       in mono or color mode. We only support color mode, and thus
+ *       some addresses won't work in mono-mode!
+ *
+ * General and VGA-registers taken from retina driver. Fixed a few
+ * bugs in it. (SR and GR read address is Port + 1, NOT Port)
+ *
+ */
+
+/* General Registers: */
+#define GREG_MISC_OUTPUT_R	0x03CC
+#define GREG_MISC_OUTPUT_W	0x03C2	
+#define GREG_FEATURE_CONTROL_R	0x03CA 
+#define GREG_FEATURE_CONTROL_W	0x03DA
+#define GREG_INPUT_STATUS0_R	0x03C2
+#define GREG_INPUT_STATUS1_R	0x03DA
+
+/* Setup Registers: */
+#define SREG_VIDEO_SUBS_ENABLE	0x03C3	/* virge */
+
+/* Attribute Controller: */
+#define ACT_ADDRESS		0x03C0
+#define ACT_ADDRESS_R		0x03C1
+#define ACT_ADDRESS_W		0x03C0
+#define ACT_ADDRESS_RESET	0x03DA
+#define ACT_ID_PALETTE0		0x00
+#define ACT_ID_PALETTE1		0x01
+#define ACT_ID_PALETTE2		0x02
+#define ACT_ID_PALETTE3		0x03
+#define ACT_ID_PALETTE4		0x04
+#define ACT_ID_PALETTE5		0x05
+#define ACT_ID_PALETTE6		0x06
+#define ACT_ID_PALETTE7		0x07
+#define ACT_ID_PALETTE8		0x08
+#define ACT_ID_PALETTE9		0x09
+#define ACT_ID_PALETTE10	0x0A
+#define ACT_ID_PALETTE11	0x0B
+#define ACT_ID_PALETTE12	0x0C
+#define ACT_ID_PALETTE13	0x0D
+#define ACT_ID_PALETTE14	0x0E
+#define ACT_ID_PALETTE15	0x0F
+#define ACT_ID_ATTR_MODE_CNTL	0x10
+#define ACT_ID_OVERSCAN_COLOR	0x11
+#define ACT_ID_COLOR_PLANE_ENA	0x12
+#define ACT_ID_HOR_PEL_PANNING	0x13
+#define ACT_ID_COLOR_SELECT	0x14    /* virge PX_PADD  pixel padding register */
+
+/* Graphics Controller: */
+#define GCT_ADDRESS		0x03CE
+#define GCT_ADDRESS_R		0x03CF
+#define GCT_ADDRESS_W		0x03CF
+#define GCT_ID_SET_RESET	0x00
+#define GCT_ID_ENABLE_SET_RESET	0x01
+#define GCT_ID_COLOR_COMPARE	0x02
+#define GCT_ID_DATA_ROTATE	0x03
+#define GCT_ID_READ_MAP_SELECT	0x04
+#define GCT_ID_GRAPHICS_MODE	0x05
+#define GCT_ID_MISC		0x06
+#define GCT_ID_COLOR_XCARE	0x07
+#define GCT_ID_BITMASK		0x08
+
+/* Sequencer: */
+#define SEQ_ADDRESS		0x03C4
+#define SEQ_ADDRESS_R		0x03C5
+#define SEQ_ADDRESS_W		0x03C5
+#define SEQ_ID_RESET		0x00
+#define SEQ_ID_CLOCKING_MODE	0x01
+#define SEQ_ID_MAP_MASK		0x02
+#define SEQ_ID_CHAR_MAP_SELECT	0x03
+#define SEQ_ID_MEMORY_MODE	0x04
+#define SEQ_ID_UNKNOWN1		0x05
+#define SEQ_ID_UNKNOWN2		0x06
+#define SEQ_ID_UNKNOWN3		0x07
+/* S3 extensions */
+#define SEQ_ID_UNLOCK_EXT	0x08
+#define SEQ_ID_EXT_SEQ_REG9	0x09	/* b7 = 1 extended reg access by MMIO only */
+#define SEQ_ID_BUS_REQ_CNTL	0x0A
+#define SEQ_ID_EXT_MISC_SEQ	0x0B
+#define SEQ_ID_UNKNOWN4		0x0C
+#define SEQ_ID_EXT_SEQ		0x0D
+#define SEQ_ID_UNKNOWN5		0x0E
+#define SEQ_ID_UNKNOWN6		0x0F
+#define SEQ_ID_MCLK_LO		0x10
+#define SEQ_ID_MCLK_HI		0x11
+#define SEQ_ID_DCLK_LO		0x12
+#define SEQ_ID_DCLK_HI		0x13
+#define SEQ_ID_CLKSYN_CNTL_1	0x14
+#define SEQ_ID_CLKSYN_CNTL_2	0x15
+#define SEQ_ID_CLKSYN_TEST_HI	0x16	/* reserved for S3 testing of the */
+#define SEQ_ID_CLKSYN_TEST_LO	0x17	/* internal clock synthesizer   */
+#define SEQ_ID_RAMDAC_CNTL	0x18
+#define SEQ_ID_MORE_MAGIC	0x1A
+#define SEQ_ID_SIGNAL_SELECT	0x1C	/* new for virge */
+
+/* CRT Controller: */
+#define CRT_ADDRESS		0x03D4
+#define CRT_ADDRESS_R		0x03D5
+#define CRT_ADDRESS_W		0x03D5
+#define CRT_ID_HOR_TOTAL	0x00
+#define CRT_ID_HOR_DISP_ENA_END	0x01
+#define CRT_ID_START_HOR_BLANK	0x02
+#define CRT_ID_END_HOR_BLANK	0x03
+#define CRT_ID_START_HOR_RETR	0x04
+#define CRT_ID_END_HOR_RETR	0x05
+#define CRT_ID_VER_TOTAL	0x06
+#define CRT_ID_OVERFLOW		0x07
+#define CRT_ID_PRESET_ROW_SCAN	0x08
+#define CRT_ID_MAX_SCAN_LINE	0x09
+#define CRT_ID_CURSOR_START	0x0A
+#define CRT_ID_CURSOR_END	0x0B
+#define CRT_ID_START_ADDR_HIGH	0x0C
+#define CRT_ID_START_ADDR_LOW	0x0D
+#define CRT_ID_CURSOR_LOC_HIGH	0x0E
+#define CRT_ID_CURSOR_LOC_LOW	0x0F
+#define CRT_ID_START_VER_RETR	0x10
+#define CRT_ID_END_VER_RETR	0x11
+#define CRT_ID_VER_DISP_ENA_END	0x12
+#define CRT_ID_SCREEN_OFFSET	0x13
+#define CRT_ID_UNDERLINE_LOC	0x14
+#define CRT_ID_START_VER_BLANK	0x15
+#define CRT_ID_END_VER_BLANK	0x16
+#define CRT_ID_MODE_CONTROL	0x17
+#define CRT_ID_LINE_COMPARE	0x18
+#define CRT_ID_GD_LATCH_RBACK	0x22
+#define CRT_ID_ACT_TOGGLE_RBACK	0x24
+#define CRT_ID_ACT_INDEX_RBACK	0x26
+/* S3 extensions: S3 VGA Registers */
+#define CRT_ID_DEVICE_HIGH	0x2D
+#define CRT_ID_DEVICE_LOW	0x2E
+#define CRT_ID_REVISION 	0x2F
+#define CRT_ID_CHIP_ID_REV	0x30
+#define CRT_ID_MEMORY_CONF	0x31
+#define CRT_ID_BACKWAD_COMP_1	0x32
+#define CRT_ID_BACKWAD_COMP_2	0x33
+#define CRT_ID_BACKWAD_COMP_3	0x34
+#define CRT_ID_REGISTER_LOCK	0x35
+#define CRT_ID_CONFIG_1 	0x36
+#define CRT_ID_CONFIG_2 	0x37
+#define CRT_ID_REGISTER_LOCK_1	0x38
+#define CRT_ID_REGISTER_LOCK_2	0x39
+#define CRT_ID_MISC_1		0x3A
+#define CRT_ID_DISPLAY_FIFO	0x3B
+#define CRT_ID_LACE_RETR_START	0x3C
+/* S3 extensions: System Control Registers  */
+#define CRT_ID_SYSTEM_CONFIG	0x40
+#define CRT_ID_BIOS_FLAG	0x41
+#define CRT_ID_LACE_CONTROL	0x42
+#define CRT_ID_EXT_MODE 	0x43
+#define CRT_ID_HWGC_MODE	0x45	/* HWGC = Hardware Graphics Cursor */
+#define CRT_ID_HWGC_ORIGIN_X_HI	0x46
+#define CRT_ID_HWGC_ORIGIN_X_LO	0x47
+#define CRT_ID_HWGC_ORIGIN_Y_HI	0x48
+#define CRT_ID_HWGC_ORIGIN_Y_LO	0x49
+#define CRT_ID_HWGC_FG_STACK	0x4A
+#define CRT_ID_HWGC_BG_STACK	0x4B
+#define CRT_ID_HWGC_START_AD_HI	0x4C
+#define CRT_ID_HWGC_START_AD_LO	0x4D
+#define CRT_ID_HWGC_DSTART_X	0x4E
+#define CRT_ID_HWGC_DSTART_Y	0x4F
+/* S3 extensions: System Extension Registers  */
+#define CRT_ID_EXT_SYS_CNTL_1	0x50	/* NOT a virge register */
+#define CRT_ID_EXT_SYS_CNTL_2	0x51
+#define CRT_ID_EXT_BIOS_FLAG_1	0x52
+#define CRT_ID_EXT_MEM_CNTL_1	0x53
+#define CRT_ID_EXT_MEM_CNTL_2	0x54
+#define CRT_ID_EXT_DAC_CNTL	0x55
+#define CRT_ID_EX_SYNC_1	0x56
+#define CRT_ID_EX_SYNC_2	0x57
+#define CRT_ID_LAW_CNTL		0x58	/* LAW = Linear Address Window */
+#define CRT_ID_LAW_POS_HI	0x59
+#define CRT_ID_LAW_POS_LO	0x5A
+#define CRT_ID_GOUT_PORT	0x5C
+#define CRT_ID_EXT_HOR_OVF	0x5D
+#define CRT_ID_EXT_VER_OVF	0x5E
+#define CRT_ID_EXT_MEM_CNTL_3	0x60	/* NOT a virge register */
+#define CRT_ID_EXT_MEM_CNTL_4	0x61
+#define CRT_ID_EX_SYNC_3	0x63	/* NOT a virge register */
+#define CRT_ID_EXT_MISC_CNTL	0x65
+#define CRT_ID_EXT_MISC_CNTL_1	0x66
+#define CRT_ID_EXT_MISC_CNTL_2	0x67
+#define CRT_ID_CONFIG_3 	0x68
+#define CRT_ID_EXT_SYS_CNTL_3	0x69
+#define CRT_ID_EXT_SYS_CNTL_4	0x6A
+#define CRT_ID_EXT_BIOS_FLAG_3	0x6B
+#define CRT_ID_EXT_BIOS_FLAG_4	0x6C
+/* S3 virge extensions: more System Extension Registers  */
+#define CRT_ID_EXT_BIOS_FLAG_5	0x6D
+#define CRT_ID_EXT_DAC_TEST	0x6E
+#define CRT_ID_CONFIG_4 	0x6F
+
+/* Video DAC */
+#define VDAC_ADDRESS		0x03c8
+#define VDAC_ADDRESS_W		0x03c8
+#define VDAC_ADDRESS_R		0x03c7
+#define VDAC_STATE		0x03c7
+#define VDAC_DATA		0x03c9
+#define VDAC_MASK		0x03c6
+
+/* Miscellaneous Registers */
+#define MR_SUBSYSTEM_STATUS_R		0x8504	/* new for virge */
+#define MR_SUBSYSTEM_CNTL_W		0x8504	/* new for virge */
+#define MR_ADVANCED_FUNCTION_CONTROL	0x850C	/* new for virge */
+
+/* Blitter  */
+#define BLT_COMMAND_SET		0xA500
+#define BLT_SIZE_X_Y		0xA504
+#define BLT_SRC_X_Y		0xA508
+#define BLT_DEST_X_Y		0xA50C
+
+#define BLT_SRC_BASE		0xa4d4
+#define BLT_DEST_BASE		0xa4d8
+#define BLT_CLIP_LEFT_RIGHT	0xa4dc
+#define BLT_CLIP_TOP_BOTTOM	0xa4e0
+#define BLT_SRC_DEST_STRIDE	0xa4e4
+#define BLT_MONO_PATTERN_0	0xa4e8
+#define BLT_MONO_PATTERN_1	0xa4ec
+#define BLT_PATTERN_COLOR	0xa4f4
+
+#define L2D_COMMAND_SET		0xA900
+#define L2D_CLIP_LEFT_RIGHT	0xA8DC
+#define L2D_CLIP_TOP_BOTTOM	0xA8E0
+
+#define P2D_COMMAND_SET		0xAD00
+#define P2D_CLIP_LEFT_RIGHT	0xACDC
+#define P2D_CLIP_TOP_BOTTOM	0xACE0
+
+#define CMD_NOP		(0xf << 27)	/* %1111 << 27, was 0x07 */ 
+#define S3V_BITBLT	(0x0 << 27)
+#define S3V_RECTFILL	(0x2 << 27)
+#define S3V_AUTOEXE	0x01
+#define S3V_HWCLIP	0x02
+#define S3V_DRAW	0x20
+#define S3V_DST_8BPP	0x00
+#define S3V_DST_16BPP	0x04
+#define S3V_DST_24BPP	0x08
+#define S3V_MONO_PAT	0x100
+
+#define S3V_BLT_COPY	(0xcc<<17)
+#define S3V_BLT_CLEAR	(0x00<<17)
+#define S3V_BLT_SET	(0xff<<17)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/zorro/zorro.ids linux/drivers/zorro/zorro.ids
--- linux.orig/drivers/zorro/zorro.ids	2000-10-16 19:51:16.000000000 +0000
+++ linux/drivers/zorro/zorro.ids	2002-07-20 01:08:39.000000000 +0000
@@ -4,7 +4,7 @@
 #	Maintained by Geert Uytterhoeven <zorro@linux-m68k.org>
 #	If you have any new entries, please send them to the maintainer.
 #
-#	$Id: zorro.ids,v 1.16 2000/09/28 18:45:47 geert Exp $
+#	$Id: zorro.ids,v 1.17 2001/10/25 08:21:39 geert Exp $
 #
 
 # Manufacturers and Products. Please keep sorted.
@@ -229,6 +229,7 @@
 	0a00  Impact Series II [RAM Expansion]
 081e  Interworks Network
 0820  Hardital Synthesis
+	0100  Super Big Bang [Accelerator, SCSI Host Adapter and RAM Expansion]
 	1400  TQM 68030+68882 [Accelerator]
 0828  Applied Engineering
 	1000  DL2000 [Modem]
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/Config.in linux/fs/Config.in
--- linux.orig/fs/Config.in	2002-02-25 19:38:07.000000000 +0000
+++ linux/fs/Config.in	2002-07-20 01:08:25.000000000 +0000
@@ -21,7 +21,7 @@
 
 dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
 
-tristate 'Ext3 journalling file system support (EXPERIMENTAL)' CONFIG_EXT3_FS
+tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
 # CONFIG_JBD could be its own option (even modular), but until there are
 # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
 # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
@@ -45,7 +45,7 @@
 fi
 tristate 'Compressed ROM file system support' CONFIG_CRAMFS
 bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS
-tristate 'Simple RAM-based file system support' CONFIG_RAMFS
+define_bool CONFIG_RAMFS y
 
 tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS
 dep_mbool '  Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS
@@ -71,7 +71,7 @@
 # breaks.
 dep_bool '/dev/pts file system for Unix98 PTYs' CONFIG_DEVPTS_FS $CONFIG_UNIX98_PTYS
 
-dep_tristate 'QNX4 file system support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS $CONFIG_EXPERIMENTAL
+tristate 'QNX4 file system support (read only)' CONFIG_QNX4FS_FS
 dep_mbool '  QNX4FS write support (DANGEROUS)' CONFIG_QNX4FS_RW $CONFIG_QNX4FS_FS $CONFIG_EXPERIMENTAL
 
 tristate 'ROM file system support' CONFIG_ROMFS_FS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/autofs/autofs_i.h linux/fs/autofs/autofs_i.h
--- linux.orig/fs/autofs/autofs_i.h	2001-07-26 20:43:12.000000000 +0000
+++ linux/fs/autofs/autofs_i.h	2002-07-20 01:08:38.000000000 +0000
@@ -141,7 +141,6 @@
 extern struct inode_operations autofs_symlink_inode_operations;
 extern struct inode_operations autofs_dir_inode_operations;
 extern struct file_operations autofs_root_operations;
-extern struct file_operations autofs_dir_operations;
 
 /* Initializing function */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/autofs/dir.c linux/fs/autofs/dir.c
--- linux.orig/fs/autofs/dir.c	2000-05-20 17:55:26.000000000 +0000
+++ linux/fs/autofs/dir.c	2002-07-20 01:08:40.000000000 +0000
@@ -23,11 +23,6 @@
 	return NULL;
 }
 
-struct file_operations autofs_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	dcache_readdir,
-};
-
 struct inode_operations autofs_dir_inode_operations = {
 	lookup:		autofs_dir_lookup,
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/autofs/inode.c linux/fs/autofs/inode.c
--- linux.orig/fs/autofs/inode.c	2001-10-25 07:02:26.000000000 +0000
+++ linux/fs/autofs/inode.c	2002-07-20 01:08:39.000000000 +0000
@@ -208,7 +208,7 @@
 	/* Initialize to the default case (stub directory) */
 
 	inode->i_op = &autofs_dir_inode_operations;
-	inode->i_fop = &autofs_dir_operations;
+	inode->i_fop = &dcache_dir_ops;
 	inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
 	inode->i_nlink = 2;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/autofs4/autofs_i.h linux/fs/autofs4/autofs_i.h
--- linux.orig/fs/autofs4/autofs_i.h	2001-11-22 19:46:40.000000000 +0000
+++ linux/fs/autofs4/autofs_i.h	2002-07-20 01:08:26.000000000 +0000
@@ -139,7 +139,6 @@
 extern struct inode_operations autofs4_symlink_inode_operations;
 extern struct inode_operations autofs4_dir_inode_operations;
 extern struct inode_operations autofs4_root_inode_operations;
-extern struct file_operations autofs4_dir_operations;
 extern struct file_operations autofs4_root_operations;
 
 /* Initializing function */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/autofs4/inode.c linux/fs/autofs4/inode.c
--- linux.orig/fs/autofs4/inode.c	2001-11-09 22:11:14.000000000 +0000
+++ linux/fs/autofs4/inode.c	2002-07-20 01:08:39.000000000 +0000
@@ -314,7 +314,7 @@
 	if (S_ISDIR(inf->mode)) {
 		inode->i_nlink = 2;
 		inode->i_op = &autofs4_dir_inode_operations;
-		inode->i_fop = &autofs4_dir_operations;
+		inode->i_fop = &dcache_dir_ops;
 	} else if (S_ISLNK(inf->mode)) {
 		inode->i_size = inf->size;
 		inode->i_op = &autofs4_symlink_inode_operations;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/autofs4/root.c linux/fs/autofs4/root.c
--- linux.orig/fs/autofs4/root.c	2000-10-24 04:57:38.000000000 +0000
+++ linux/fs/autofs4/root.c	2002-07-20 01:08:22.000000000 +0000
@@ -27,16 +27,15 @@
 static struct dentry *autofs4_root_lookup(struct inode *,struct dentry *);
 
 struct file_operations autofs4_root_operations = {
+	open:		dcache_dir_open,
+	release:	dcache_dir_close,
+	llseek:		dcache_dir_lseek,
 	read:		generic_read_dir,
 	readdir:	dcache_readdir,
+	fsync:		dcache_dir_fsync,
 	ioctl:		autofs4_root_ioctl,
 };
 
-struct file_operations autofs4_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	dcache_readdir,
-};
-
 struct inode_operations autofs4_root_inode_operations = {
 	lookup:		autofs4_root_lookup,
 	unlink:		autofs4_dir_unlink,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/bad_inode.c linux/fs/bad_inode.c
--- linux.orig/fs/bad_inode.c	2000-04-12 16:47:28.000000000 +0000
+++ linux/fs/bad_inode.c	2002-07-20 01:08:28.000000000 +0000
@@ -17,9 +17,7 @@
  */
 static int bad_follow_link(struct dentry *dent, struct nameidata *nd)
 {
-	dput(nd->dentry);
-	nd->dentry = dget(dent);
-	return 0;
+	return vfs_follow_link(nd, ERR_PTR(-EIO));
 }
 
 static int return_EIO(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/bfs/bfs_defs.h linux/fs/bfs/bfs_defs.h
--- linux.orig/fs/bfs/bfs_defs.h	2000-02-07 02:43:21.000000000 +0000
+++ linux/fs/bfs/bfs_defs.h	2002-07-20 01:08:22.000000000 +0000
@@ -14,4 +14,7 @@
 #define iu_eblock	u.bfs_i.i_eblock
 
 #define printf(format, args...) \
-	printk(KERN_ERR "BFS-fs: " __FUNCTION__ "(): " format, ## args)
+do { \
+	printk(KERN_ERR "BFS-fs: %s(): ", __FUNCTION__); \
+	printk(format, args); \
+} while (0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- linux.orig/fs/binfmt_elf.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/binfmt_elf.c	2002-07-20 01:08:35.000000000 +0000
@@ -564,6 +564,9 @@
 			// printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
 			interpreter_type = INTERPRETER_ELF;
 		}
+	} else {
+		/* Executables without an interpreter also need a personality  */
+		SET_PERSONALITY(elf_ex, ibcs2_interpreter);
 	}
 
 	/* OK, we are done with that, now set up the arg stuff,
@@ -601,7 +604,12 @@
 	/* Do this so that we can load the interpreter, if need be.  We will
 	   change some of these later */
 	current->mm->rss = 0;
-	setup_arg_pages(bprm); /* XXX: check error */
+	retval = setup_arg_pages(bprm);
+	if (retval < 0) {
+		send_sig(SIGKILL, current, 0);
+		return retval;
+	}
+	
 	current->mm->start_stack = bprm->p;
 
 	/* Now we do a little grungy work by mmaping the ELF image into
@@ -1273,3 +1281,4 @@
 
 module_init(init_elf_binfmt)
 module_exit(exit_elf_binfmt)
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/binfmt_em86.c linux/fs/binfmt_em86.c
--- linux.orig/fs/binfmt_em86.c	2001-02-09 19:29:44.000000000 +0000
+++ linux/fs/binfmt_em86.c	2002-07-20 01:08:38.000000000 +0000
@@ -110,3 +110,4 @@
 
 module_init(init_em86_binfmt)
 module_exit(exit_em86_binfmt)
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/binfmt_misc.c linux/fs/binfmt_misc.c
--- linux.orig/fs/binfmt_misc.c	2001-10-21 02:14:42.000000000 +0000
+++ linux/fs/binfmt_misc.c	2002-07-20 01:08:32.000000000 +0000
@@ -38,7 +38,7 @@
 
 typedef struct {
 	struct list_head list;
-	int flags;			/* type, status, etc. */
+	unsigned long flags;		/* type, status, etc. */
 	int offset;			/* offset of magic */
 	int size;			/* size of magic/mask */
 	char *magic;			/* magic or filename extension */
@@ -600,11 +600,6 @@
 	return NULL;
 }
 
-static struct file_operations bm_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	dcache_readdir,
-};
-
 static struct inode_operations bm_dir_inode_operations = {
 	lookup:		bm_lookup,
 };
@@ -646,7 +641,7 @@
 	if (!inode)
 		return NULL;
 	inode->i_op = &bm_dir_inode_operations;
-	inode->i_fop = &bm_dir_operations;
+	inode->i_fop = &dcache_dir_ops;
 	dentry[0] = d_alloc_root(inode);
 	if (!dentry[0]) {
 		iput(inode);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/binfmt_script.c linux/fs/binfmt_script.c
--- linux.orig/fs/binfmt_script.c	2001-02-09 19:29:44.000000000 +0000
+++ linux/fs/binfmt_script.c	2002-07-20 01:08:25.000000000 +0000
@@ -108,3 +108,4 @@
 
 module_init(init_script_binfmt)
 module_exit(exit_script_binfmt)
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/block_dev.c linux/fs/block_dev.c
--- linux.orig/fs/block_dev.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/block_dev.c	2002-07-20 01:08:37.000000000 +0000
@@ -22,8 +22,6 @@
 
 #include <asm/uaccess.h>
 
-#define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
-
 static unsigned long max_block(kdev_t dev)
 {
 	unsigned int retval = ~0U;
@@ -102,6 +100,26 @@
 	return 0;
 }
 
+int sb_set_blocksize(struct super_block *sb, int size)
+{
+	int bits;
+	if (set_blocksize(sb->s_dev, size) < 0)
+		return 0;
+	sb->s_blocksize = size;
+	for (bits = 9, size >>= 9; size >>= 1; bits++)
+		;
+	sb->s_blocksize_bits = bits;
+	return sb->s_blocksize;
+}
+
+int sb_min_blocksize(struct super_block *sb, int size)
+{
+	int minsize = get_hardsect_size(sb->s_dev);
+	if (size < minsize)
+		size = minsize;
+	return sb_set_blocksize(sb, size);
+}
+
 static int blkdev_get_block(struct inode * inode, long iblock, struct buffer_head * bh, int create)
 {
 	if (iblock >= max_block(inode->i_rdev))
@@ -515,9 +533,6 @@
 	if (!bdops->check_media_change(dev))
 		return 0;
 
-	printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
-		bdevname(dev));
-
 	if (invalidate_device(dev, 0))
 		printk("VFS: busy inodes on changed media.\n");
 
@@ -616,7 +631,7 @@
 
 	down(&bdev->bd_sem);
 	lock_kernel();
-	if (kind == BDEV_FILE)
+	if (kind == BDEV_FILE && bdev->bd_openers == 1)
 		__block_fsync(bd_inode);
 	else if (kind == BDEV_FS)
 		fsync_no_super(rdev);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/buffer.c linux/fs/buffer.c
--- linux.orig/fs/buffer.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/buffer.c	2002-07-20 01:08:23.000000000 +0000
@@ -47,13 +47,13 @@
 #include <linux/highmem.h>
 #include <linux/module.h>
 #include <linux/completion.h>
+#include <linux/compiler.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/bitops.h>
 #include <asm/mmu_context.h>
 
-#define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
 #define NR_RESERVED (10*MAX_BUF_PER_PAGE)
 #define MAX_UNUSED_BUFFERS NR_RESERVED+20 /* don't ever have more than this 
 					     number of unused buffer heads */
@@ -73,7 +73,10 @@
 static rwlock_t hash_table_lock = RW_LOCK_UNLOCKED;
 
 static struct buffer_head *lru_list[NR_LIST];
-static spinlock_t lru_list_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+
+static spinlock_cacheline_t lru_list_lock_cacheline = {SPIN_LOCK_UNLOCKED};
+#define lru_list_lock  lru_list_lock_cacheline.lock
+
 static int nr_buffers_type[NR_LIST];
 static unsigned long size_buffers_type[NR_LIST];
 
@@ -83,6 +86,7 @@
 static DECLARE_WAIT_QUEUE_HEAD(buffer_wait);
 
 static int grow_buffers(kdev_t dev, unsigned long block, int size);
+static int osync_buffers_list(struct list_head *);
 static void __refile_buffer(struct buffer_head *);
 
 /* This is used by some architectures to estimate available memory. */
@@ -102,27 +106,35 @@
 	struct {
 		int nfract;	/* Percentage of buffer cache dirty to 
 				   activate bdflush */
-		int dummy1;	/* old "ndirty" */
+		int ndirty;	/* Maximum number of dirty blocks to write out per
+				   wake-cycle */
 		int dummy2;	/* old "nrefill" */
 		int dummy3;	/* unused */
 		int interval;	/* jiffies delay between kupdate flushes */
 		int age_buffer;	/* Time for normal buffer to age before we flush it */
 		int nfract_sync;/* Percentage of buffer cache dirty to 
 				   activate bdflush synchronously */
-		int dummy4;	/* unused */
+		int nfract_stop_bdflush; /* Percetange of buffer cache dirty to stop bdflush */
 		int dummy5;	/* unused */
 	} b_un;
 	unsigned int data[N_PARAM];
-} bdf_prm = {{40, 0, 0, 0, 5*HZ, 30*HZ, 60, 0, 0}};
+} bdf_prm = {{30, 500, 0, 0, 5*HZ, 30*HZ, 60, 20, 0}};
 
 /* These are the min and max parameter values that we will allow to be assigned */
-int bdflush_min[N_PARAM] = {  0,  10,    5,   25,  0,   1*HZ,   0, 0, 0};
-int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,10000*HZ, 6000*HZ, 100, 0, 0};
+int bdflush_min[N_PARAM] = {  0,  1,    0,   0,  0,   1*HZ,   0, 0, 0};
+int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,10000*HZ, 10000*HZ, 100, 100, 0};
 
 void unlock_buffer(struct buffer_head *bh)
 {
 	clear_bit(BH_Wait_IO, &bh->b_state);
-	clear_bit(BH_launder, &bh->b_state);
+	clear_bit(BH_Launder, &bh->b_state);
+	/*
+	 * When a locked buffer is visible to the I/O layer BH_Launder
+	 * is set. This means before unlocking we must clear BH_Launder,
+	 * mb() on alpha and then clear BH_Lock, so no reader can see
+	 * BH_Launder set on an unlocked buffer and then risk to deadlock.
+	 */
+	smp_mb__after_clear_bit();
 	clear_bit(BH_Lock, &bh->b_state);
 	smp_mb__after_clear_bit();
 	if (waitqueue_active(&bh->b_wait))
@@ -130,13 +142,9 @@
 }
 
 /*
- * Rewrote the wait-routines to use the "new" wait-queue functionality,
- * and getting rid of the cli-sti pairs. The wait-queue routines still
- * need cli-sti, but now it's just a couple of 386 instructions or so.
- *
  * Note that the real wait_on_buffer() is an inline function that checks
- * if 'b_wait' is set before calling this, so that the queues aren't set
- * up unnecessarily.
+ * that the buffer is locked before calling this, so that unnecessary disk
+ * unplugging does not occur.
  */
 void __wait_on_buffer(struct buffer_head * bh)
 {
@@ -232,10 +240,9 @@
  */
 static void write_unlocked_buffers(kdev_t dev)
 {
-	do {
+	do
 		spin_lock(&lru_list_lock);
-	} while (write_some_buffers(dev));
-	run_task_queue(&tq_disk);
+	while (write_some_buffers(dev));
 }
 
 /*
@@ -273,12 +280,6 @@
 	return 0;
 }
 
-static inline void wait_for_some_buffers(kdev_t dev)
-{
-	spin_lock(&lru_list_lock);
-	wait_for_buffers(dev, BUF_LOCKED, 1);
-}
-
 static int wait_for_locked_buffers(kdev_t dev, int index, int refile)
 {
 	do {
@@ -803,9 +804,10 @@
 	return;
 }
 
-inline void set_buffer_async_io(struct buffer_head *bh) {
-    bh->b_end_io = end_buffer_io_async ;
-    mark_buffer_async(bh, 1);
+inline void set_buffer_async_io(struct buffer_head *bh)
+{
+	bh->b_end_io = end_buffer_io_async;
+	mark_buffer_async(bh, 1);
 }
 
 /*
@@ -827,8 +829,7 @@
  * the osync code to catch these locked, dirty buffers without requeuing
  * any newly dirty buffers for write.
  */
-
-int fsync_inode_buffers(struct inode *inode)
+int fsync_buffers_list(struct list_head *list)
 {
 	struct buffer_head *bh;
 	struct inode tmp;
@@ -838,8 +839,8 @@
 	
 	spin_lock(&lru_list_lock);
 
-	while (!list_empty(&inode->i_dirty_buffers)) {
-		bh = BH_ENTRY(inode->i_dirty_buffers.next);
+	while (!list_empty(list)) {
+		bh = BH_ENTRY(list->next);
 		list_del(&bh->b_inode_buffers);
 		if (!buffer_dirty(bh) && !buffer_locked(bh))
 			bh->b_inode = NULL;
@@ -849,6 +850,15 @@
 			if (buffer_dirty(bh)) {
 				get_bh(bh);
 				spin_unlock(&lru_list_lock);
+			/*
+			 * Wait I/O completion before submitting
+			 * the buffer, to be sure the write will
+			 * be effective on the latest data in
+			 * the buffer. (otherwise - if there's old
+			 * I/O in flight - write_buffer would become
+			 * a noop)
+			 */
+				wait_on_buffer(bh);
 				ll_rw_block(WRITE, 1, &bh);
 				brelse(bh);
 				spin_lock(&lru_list_lock);
@@ -869,56 +879,7 @@
 	}
 	
 	spin_unlock(&lru_list_lock);
-	err2 = osync_inode_buffers(inode);
-
-	if (err)
-		return err;
-	else
-		return err2;
-}
-
-int fsync_inode_data_buffers(struct inode *inode)
-{
-	struct buffer_head *bh;
-	struct inode tmp;
-	int err = 0, err2;
-	
-	INIT_LIST_HEAD(&tmp.i_dirty_data_buffers);
-	
-	spin_lock(&lru_list_lock);
-
-	while (!list_empty(&inode->i_dirty_data_buffers)) {
-		bh = BH_ENTRY(inode->i_dirty_data_buffers.next);
-		list_del(&bh->b_inode_buffers);
-		if (!buffer_dirty(bh) && !buffer_locked(bh))
-			bh->b_inode = NULL;
-		else {
-			bh->b_inode = &tmp;
-			list_add(&bh->b_inode_buffers, &tmp.i_dirty_data_buffers);
-			if (buffer_dirty(bh)) {
-				get_bh(bh);
-				spin_unlock(&lru_list_lock);
-				ll_rw_block(WRITE, 1, &bh);
-				brelse(bh);
-				spin_lock(&lru_list_lock);
-			}
-		}
-	}
-
-	while (!list_empty(&tmp.i_dirty_data_buffers)) {
-		bh = BH_ENTRY(tmp.i_dirty_data_buffers.prev);
-		remove_inode_queue(bh);
-		get_bh(bh);
-		spin_unlock(&lru_list_lock);
-		wait_on_buffer(bh);
-		if (!buffer_uptodate(bh))
-			err = -EIO;
-		brelse(bh);
-		spin_lock(&lru_list_lock);
-	}
-	
-	spin_unlock(&lru_list_lock);
-	err2 = osync_inode_data_buffers(inode);
+	err2 = osync_buffers_list(list);
 
 	if (err)
 		return err;
@@ -932,24 +893,21 @@
  * writes to the disk.
  *
  * To do O_SYNC writes, just queue the buffer writes with ll_rw_block as
- * you dirty the buffers, and then use osync_inode_buffers to wait for
+ * you dirty the buffers, and then use osync_buffers_list to wait for
  * completion.  Any other dirty buffers which are not yet queued for
  * write will not be flushed to disk by the osync.
  */
-
-int osync_inode_buffers(struct inode *inode)
+static int osync_buffers_list(struct list_head *list)
 {
 	struct buffer_head *bh;
-	struct list_head *list;
+	struct list_head *p;
 	int err = 0;
 
 	spin_lock(&lru_list_lock);
 	
  repeat:
-	
-	for (list = inode->i_dirty_buffers.prev; 
-	     bh = BH_ENTRY(list), list != &inode->i_dirty_buffers;
-	     list = bh->b_inode_buffers.prev) {
+	list_for_each_prev(p, list) {
+		bh = BH_ENTRY(p);
 		if (buffer_locked(bh)) {
 			get_bh(bh);
 			spin_unlock(&lru_list_lock);
@@ -966,36 +924,6 @@
 	return err;
 }
 
-int osync_inode_data_buffers(struct inode *inode)
-{
-	struct buffer_head *bh;
-	struct list_head *list;
-	int err = 0;
-
-	spin_lock(&lru_list_lock);
-	
- repeat:
-
-	for (list = inode->i_dirty_data_buffers.prev; 
-	     bh = BH_ENTRY(list), list != &inode->i_dirty_data_buffers;
-	     list = bh->b_inode_buffers.prev) {
-		if (buffer_locked(bh)) {
-			get_bh(bh);
-			spin_unlock(&lru_list_lock);
-			wait_on_buffer(bh);
-			if (!buffer_uptodate(bh))
-				err = -EIO;
-			brelse(bh);
-			spin_lock(&lru_list_lock);
-			goto repeat;
-		}
-	}
-
-	spin_unlock(&lru_list_lock);
-	return err;
-}
-
-
 /*
  * Invalidate any and all dirty buffers on a given inode.  We are
  * probably unmounting the fs, but that doesn't mean we have already
@@ -1046,7 +974,6 @@
 	unsigned long dirty, tot, hard_dirty_limit, soft_dirty_limit;
 
 	dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT;
-	dirty += size_buffers_type[BUF_LOCKED] >> PAGE_SHIFT;
 	tot = nr_free_buffer_pages();
 
 	dirty *= 100;
@@ -1063,6 +990,21 @@
 	return -1;
 }
 
+static int bdflush_stop(void)
+{
+	unsigned long dirty, tot, dirty_limit;
+
+	dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT;
+	tot = nr_free_buffer_pages();
+
+	dirty *= 100;
+	dirty_limit = tot * bdf_prm.b_un.nfract_stop_bdflush;
+
+	if (dirty > dirty_limit)
+		return 0;
+	return 1;
+}
+
 /*
  * if a new dirty buffer is created we need to balance bdflush.
  *
@@ -1077,19 +1019,16 @@
 	if (state < 0)
 		return;
 
-	/* If we're getting into imbalance, start write-out */
-	spin_lock(&lru_list_lock);
-	write_some_buffers(NODEV);
+	wakeup_bdflush();
 
 	/*
 	 * And if we're _really_ out of balance, wait for
-	 * some of the dirty/locked buffers ourselves and
-	 * start bdflush.
+	 * some of the dirty/locked buffers ourselves.
 	 * This will throttle heavy writers.
 	 */
 	if (state > 0) {
-		wait_for_some_buffers(NODEV);
-		wakeup_bdflush();
+		spin_lock(&lru_list_lock);
+		write_some_buffers(NODEV);
 	}
 }
 
@@ -2257,8 +2196,7 @@
  * of kiobuf structs (much like a user-space iovec list).
  *
  * The kiobuf must already be locked for IO.  IO is submitted
- * asynchronously: you need to check page->locked, page->uptodate, and
- * maybe wait on page->wait.
+ * asynchronously: you need to check page->locked and page->uptodate.
  *
  * It is up to the caller to make sure that there are enough blocks
  * passed in to completely map the iobufs to disk.
@@ -2391,8 +2329,8 @@
 /*
  * Start I/O on a page.
  * This function expects the page to be locked and may return
- * before I/O is complete. You then have to check page->locked,
- * page->uptodate, and maybe wait on page->wait.
+ * before I/O is complete. You then have to check page->locked
+ * and page->uptodate.
  *
  * brw_page() is SMP-safe, although it's being called with the
  * kernel lock held - but the code is ready.
@@ -2593,23 +2531,58 @@
 	return 1;
 }
 
+/*
+ * The first time the VM inspects a page which has locked buffers, it
+ * will just mark it as needing waiting upon on the scan of the page LRU.
+ * BH_Wait_IO is used for this.
+ *
+ * The second time the VM visits the page, if it still has locked
+ * buffers, it is time to start writing them out.  (BH_Wait_IO was set).
+ *
+ * The third time the VM visits the page, if the I/O hasn't completed
+ * then it's time to wait upon writeout.  BH_Lock and BH_Launder are
+ * used for this.
+ *
+ * There is also the case of buffers which were locked by someone else
+ * - write(2) callers, bdflush, etc.  There can be a huge number of these
+ * and we don't want to just skip them all and fail the page allocation. 
+ * We want to be able to wait on these buffers as well.
+ *
+ * The BH_Launder bit is set in submit_bh() to indicate that I/O is
+ * underway against the buffer, doesn't matter who started it - we know
+ * that the buffer will eventually come unlocked, and so it's safe to
+ * wait on it.
+ *
+ * The caller holds the page lock and the caller will free this page
+ * into current->local_page, so by waiting on the page's buffers the
+ * caller is guaranteed to obtain this page.
+ *
+ * sync_page_buffers() will sort-of return true if all the buffers
+ * against this page are freeable, so try_to_free_buffers() should
+ * try to free the page's buffers a second time.  This is a bit
+ * broken for blocksize < PAGE_CACHE_SIZE, but not very importantly.
+ */
 static int sync_page_buffers(struct buffer_head *head)
 {
 	struct buffer_head * bh = head;
-	int tryagain = 0;
+	int tryagain = 1;
 
 	do {
 		if (!buffer_dirty(bh) && !buffer_locked(bh))
 			continue;
 
 		/* Don't start IO first time around.. */
-		if (!test_and_set_bit(BH_Wait_IO, &bh->b_state))
+		if (!test_and_set_bit(BH_Wait_IO, &bh->b_state)) {
+			tryagain = 0;
 			continue;
+		}
 
 		/* Second time through we start actively writing out.. */
 		if (test_and_set_bit(BH_Lock, &bh->b_state)) {
-			if (!test_bit(BH_launder, &bh->b_state))
+			if (unlikely(!buffer_launder(bh))) {
+				tryagain = 0;
 				continue;
+			}
 			wait_on_buffer(bh);
 			tryagain = 1;
 			continue;
@@ -2622,7 +2595,6 @@
 
 		__mark_buffer_clean(bh);
 		get_bh(bh);
-		set_bit(BH_launder, &bh->b_state);
 		bh->b_end_io = end_buffer_io_sync;
 		submit_bh(WRITE, bh);
 		tryagain = 0;
@@ -2947,14 +2919,29 @@
 
 	complete((struct completion *)startup);
 
+	/*
+	 * FIXME: The ndirty logic here is wrong.  It's supposed to
+	 * send bdflush back to sleep after writing ndirty buffers.
+	 * In fact, the test is wrong so bdflush will in fact
+	 * sleep when bdflush_stop() returns true.
+	 *
+	 * FIXME: If it proves useful to implement ndirty properly,
+	 * then perhaps the value of ndirty should be scaled by the
+	 * amount of memory in the machine.
+	 */
 	for (;;) {
+		int ndirty = bdf_prm.b_un.ndirty;
+
 		CHECK_EMERGENCY_SYNC
 
-		spin_lock(&lru_list_lock);
-		if (!write_some_buffers(NODEV) || balance_dirty_state() < 0) {
-			wait_for_some_buffers(NODEV);
-			interruptible_sleep_on(&bdflush_wait);
+		while (ndirty > 0) {
+			spin_lock(&lru_list_lock);
+			if (!write_some_buffers(NODEV))
+				break;
+			ndirty -= NRSYNC;
 		}
+		if (ndirty > 0 || bdflush_stop())
+			interruptible_sleep_on(&bdflush_wait);
 	}
 }
 
@@ -2983,8 +2970,6 @@
 	complete((struct completion *)startup);
 
 	for (;;) {
-		wait_for_some_buffers(NODEV);
-
 		/* update interval */
 		interval = bdf_prm.b_un.interval;
 		if (interval) {
@@ -3012,6 +2997,7 @@
 		printk(KERN_DEBUG "kupdate() activated...\n");
 #endif
 		sync_old_buffers();
+		run_task_queue(&tq_disk);
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/cache.c linux/fs/coda/cache.c
--- linux.orig/fs/coda/cache.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/coda/cache.c	2002-07-20 01:08:39.000000000 +0000
@@ -14,7 +14,6 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/locks.h>
-#include <asm/segment.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
 #include <linux/list.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/cnode.c linux/fs/coda/cnode.c
--- linux.orig/fs/coda/cnode.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/coda/cnode.c	2002-07-20 01:08:28.000000000 +0000
@@ -12,7 +12,6 @@
 #include <linux/coda_psdev.h>
 
 extern int coda_debug;
-extern int coda_print_entry;
 
 inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
 {
@@ -69,11 +68,14 @@
 	struct inode *inode;
 	struct coda_inode_info *cii;
 	ino_t ino = coda_f2i(fid);
+	struct coda_sb_info *sbi = coda_sbp(sb);
 
+	down(&sbi->sbi_iget4_mutex);
 	inode = iget4(sb, ino, coda_inocmp, fid);
 
 	if ( !inode ) { 
 		CDEBUG(D_CNODE, "coda_iget: no inode\n");
+		up(&sbi->sbi_iget4_mutex);
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -82,9 +84,7 @@
 	if (coda_isnullfid(&cii->c_fid))
 		/* new, empty inode found... initializing */
 		cii->c_fid = *fid;
-
-	/* we shouldnt see inode collisions anymore */
-	if (!coda_fideq(fid, &cii->c_fid)) BUG();
+	up(&sbi->sbi_iget4_mutex);
 
 	/* always replace the attributes, type might have changed */
 	coda_fill_inode(inode, attr);
@@ -149,6 +149,7 @@
 	ino_t nr;
 	struct inode *inode;
 	struct coda_inode_info *cii;
+	struct coda_sb_info *sbi;
 
 	if ( !sb ) {
 		printk("coda_fid_to_inode: no sb!\n");
@@ -157,12 +158,14 @@
 
 	CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
 
+	sbi = coda_sbp(sb);
 	nr = coda_f2i(fid);
+	down(&sbi->sbi_iget4_mutex);
 	inode = iget4(sb, nr, coda_inocmp, fid);
 	if ( !inode ) {
 		printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
 		       sb, (long)nr);
-		return NULL;
+		goto out_unlock;
 	}
 
 	cii = ITOC(inode);
@@ -171,31 +174,33 @@
 	if (coda_isnullfid(&cii->c_fid)) {
 		inode->i_nlink = 0;
 		iput(inode);
-		return NULL;
+		goto out_unlock;
 	}
 
-	/* we shouldn't see inode collisions anymore */
-	if ( !coda_fideq(fid, &cii->c_fid) ) BUG();
-
         CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
-        return inode;
+	up(&sbi->sbi_iget4_mutex);
+	return inode;
+
+out_unlock:
+	up(&sbi->sbi_iget4_mutex);
+	return NULL;
 }
 
 /* the CONTROL inode is made without asking attributes from Venus */
 int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
 {
-    int error = 0;
+	int error = 0;
 
-    *inode = iget(sb, CTL_INO);
-    if ( *inode ) {
-	(*inode)->i_op = &coda_ioctl_inode_operations;
-	(*inode)->i_fop = &coda_ioctl_operations;
-	(*inode)->i_mode = 0444;
-	error = 0;
-    } else { 
-	error = -ENOMEM;
-    }
+	*inode = iget(sb, CTL_INO);
+	if ( *inode ) {
+		(*inode)->i_op = &coda_ioctl_inode_operations;
+		(*inode)->i_fop = &coda_ioctl_operations;
+		(*inode)->i_mode = 0444;
+		error = 0;
+	} else { 
+		error = -ENOMEM;
+	}
     
-    return error;
+	return error;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/coda_linux.c linux/fs/coda/coda_linux.c
--- linux.orig/fs/coda/coda_linux.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/coda/coda_linux.c	2002-07-20 01:08:21.000000000 +0000
@@ -15,7 +15,6 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/locks.h>
-#include <asm/segment.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
 
@@ -26,7 +25,6 @@
 
 /* initialize the debugging variables */
 int coda_debug;
-int coda_print_entry; 
 int coda_access_cache = 1;
 int coda_fake_statfs;
 
@@ -34,21 +32,7 @@
 char * coda_f2s(ViceFid *f)
 {
 	static char s[60];
-	if ( f ) {
-		sprintf(s, "(%-#lx,%-#lx,%-#lx)", 
-			 f->Volume, f->Vnode, f->Unique);
-	}
-	return s;
-}
-
-/* print another fid */
-char * coda_f2s2(ViceFid *f)
-{
-	static char s[60];
-	if ( f ) {
-		sprintf(s, "(%-#lx,%-#lx,%-#lx)", 
-			 f->Volume, f->Vnode, f->Unique);
-	}
+	sprintf(s, "(%-#lx.%-#lx.%-#lx)", f->Volume, f->Vnode, f->Unique);
 	return s;
 }
 
@@ -172,8 +156,6 @@
 	        inode->i_mtime = attr->va_mtime.tv_sec;
         if (attr->va_ctime.tv_sec != -1)
 	        inode->i_ctime = attr->va_ctime.tv_sec;
-	if (!inode->i_ctime)
-		inode->i_ctime = inode->i_mtime;
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/dir.c linux/fs/coda/dir.c
--- linux.orig/fs/coda/dir.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/coda/dir.c	2002-07-20 01:08:26.000000000 +0000
@@ -50,11 +50,8 @@
 static int coda_dentry_delete(struct dentry *);
 
 /* support routines */
-static void coda_prepare_fakefile(struct file *coda_file, 
-				  struct dentry *open_dentry,
-				  struct file *open_file);
-static int coda_venus_readdir(struct file *filp, void *dirent, 
-			      filldir_t filldir);
+static int coda_venus_readdir(struct file *filp, filldir_t filldir,
+			      void *dirent, struct dentry *dir);
 int coda_fsync(struct file *, struct dentry *dentry, int datasync);
 
 int coda_hasmknod;
@@ -209,7 +206,7 @@
         int error=0;
 	const char *name=de->d_name.name;
 	int length=de->d_name.len;
-	struct inode *inode = NULL;
+	struct inode *inode;
 	struct ViceFid newfid;
 	struct coda_vattr attrs;
 
@@ -247,7 +244,7 @@
         int error=0;
 	const char *name=de->d_name.name;
 	int length=de->d_name.len;
-	struct inode *result = NULL;
+	struct inode *inode;
 	struct ViceFid newfid;
 	struct coda_vattr attrs;
 
@@ -272,23 +269,22 @@
 		return error;
 	}
 
-	error = coda_cnode_make(&result, &newfid, dir->i_sb);
-	if ( error ) {
+	inode = coda_iget(dir->i_sb, &newfid, &attrs);
+	if ( IS_ERR(inode) ) {
 		d_drop(de);
-		result = NULL;
-		return error;
+		return PTR_ERR(inode);
 	}
 
 	/* invalidate the directory cnode's attributes */
 	coda_dir_changed(dir, 0);
-	d_instantiate(de, result);
+	d_instantiate(de, inode);
         return 0;
 }			     
 
 static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
 {
 	struct inode *inode;
-	struct coda_vattr attr;
+	struct coda_vattr attrs;
 	const char *name = de->d_name.name;
 	int len = de->d_name.len;
 	int error;
@@ -302,9 +298,9 @@
 	CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.\n", 
 	       name, len, coda_i2s(dir), mode);
 
-	attr.va_mode = mode;
+	attrs.va_mode = mode;
 	error = venus_mkdir(dir->i_sb, coda_i2f(dir), 
-			       name, len, &newfid, &attr);
+			       name, len, &newfid, &attrs);
         
         if ( error ) {
 	        CDEBUG(D_INODE, "mkdir error: %s result %d\n", 
@@ -316,10 +312,10 @@
 	CDEBUG(D_INODE, "mkdir: new dir has fid %s.\n", 
 	       coda_f2s(&newfid)); 
 
-	error = coda_cnode_make(&inode, &newfid, dir->i_sb);
-	if ( error ) {
+	inode = coda_iget(dir->i_sb, &newfid, &attrs);
+	if ( IS_ERR(inode) ) {
 		d_drop(de);
-		return error;
+		return PTR_ERR(inode);
 	}
 	
 	/* invalidate the directory cnode's attributes */
@@ -490,156 +486,143 @@
 
 
 /* file operations for directories */
-int coda_readdir(struct file *file, void *dirent,  filldir_t filldir)
+int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir)
 {
-        int result = 0;
-	struct dentry *cdentry;
-	struct inode *cinode, *inode = file->f_dentry->d_inode;
-	struct file *cfile, fakefile;
-	struct coda_inode_info *cii = ITOC(inode);
+	struct dentry *coda_dentry = coda_file->f_dentry;
+	struct coda_file_info *cfi;
+	struct file *host_file;
+	int ret;
+
+	cfi = CODA_FTOC(coda_file);
+	if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
+	host_file = cfi->cfi_container;
 
 	coda_vfs_stat.readdir++;
 
-        cfile = cii->c_container;
-        if (!cfile) BUG();
+	down(&host_file->f_dentry->d_inode->i_sem);
+	host_file->f_pos = coda_file->f_pos;
 
-	cinode = cii->c_container->f_dentry->d_inode;
-	if ( S_ISREG(cinode->i_mode) ) {
+	if ( !host_file->f_op->readdir ) {
 		/* Venus: we must read Venus dirents from the file */
-		cdentry = cii->c_container->f_dentry;
-		coda_prepare_fakefile(file, cdentry, &fakefile);
-
-		result = coda_venus_readdir(&fakefile, dirent, filldir);
+		ret = coda_venus_readdir(host_file, filldir, dirent, coda_dentry);
+	} else {
+		/* potemkin case: we were handed a directory inode */
+		ret = vfs_readdir(host_file, filldir, dirent);
+	}
 
-		file->f_pos = fakefile.f_pos;
-		file->f_version = fakefile.f_version;
-        } else {
-		/* potemkin case: we are handed a directory inode */
-		result = vfs_readdir(file, filldir, dirent);
-        }
+	coda_file->f_pos = host_file->f_pos;
+	up(&host_file->f_dentry->d_inode->i_sem);
 
-	UPDATE_ATIME(inode);
-	return result;
+	return ret;
 }
 
-/* support routines */
-
-/* instantiate a fake file to pass to coda_venus_readdir */
-static void coda_prepare_fakefile(struct file *coda_file, 
-				  struct dentry *cont_dentry,
-				  struct file *fake_file)
-{
-	fake_file->f_dentry = cont_dentry;
-	fake_file->f_pos = coda_file->f_pos;
-	fake_file->f_version = coda_file->f_version;
-	fake_file->f_op = cont_dentry->d_inode->i_fop;
-	fake_file->f_flags = coda_file->f_flags;
-	return ;
-}
-
-/* 
- * this structure is manipulated by filldir in vfs layer.
- * the count holds the remaining amount of space in the getdents buffer,
- * beyond the current_dir pointer.
- *
- * What structure is this comment referring to?? -JH
- */
+static inline unsigned int CDT2DT(unsigned char cdt)
+{
+	unsigned int dt;
 
-/* should be big enough to hold any single directory entry */
-#define DIR_BUFSIZE 2048
+	switch(cdt) {
+	case CDT_UNKNOWN: dt = DT_UNKNOWN; break;
+	case CDT_FIFO:	  dt = DT_FIFO;    break;
+	case CDT_CHR:	  dt = DT_CHR;     break;
+	case CDT_DIR:	  dt = DT_DIR;     break;
+	case CDT_BLK:	  dt = DT_BLK;     break;
+	case CDT_REG:	  dt = DT_REG;     break;
+	case CDT_LNK:	  dt = DT_LNK;     break;
+	case CDT_SOCK:	  dt = DT_SOCK;    break;
+	case CDT_WHT:	  dt = DT_WHT;     break;
+	default:	  dt = DT_UNKNOWN; break;
+	}
+	return dt;
+}
 
-static int coda_venus_readdir(struct file *filp, void *getdent, 
-			      filldir_t filldir)
+/* support routines */
+static int coda_venus_readdir(struct file *filp, filldir_t filldir,
+			      void *dirent, struct dentry *dir)
 {
-        int bufsize;
-	int offset = filp->f_pos; /* offset in the directory file */
-	int count = 0;
-	int pos = 0;      /* offset in the block we read */
-	int result = 0; /* either an error or # of entries returned */
-	int errfill;
-        char *buff = NULL;
-        struct venus_dirent *vdirent;
-        int string_offset = (int) (&((struct venus_dirent *)(0))->d_name);
-	int i;
-
-        CODA_ALLOC(buff, char *, DIR_BUFSIZE);
-        if ( !buff ) { 
-                printk("coda_venus_readdir: out of memory.\n");
-                return -ENOMEM;
-        }
-
-        /* we use this routine to read the file into our buffer */
-        bufsize = kernel_read(filp, filp->f_pos, buff, DIR_BUFSIZE);
-        if ( bufsize < 0) {
-                printk("coda_venus_readdir: cannot read directory %d.\n",
-		       bufsize);
-                result = bufsize;
-                goto exit;
-        }
-        if ( bufsize == 0) {
-                result = 0;
-                goto exit;
-        }
-	
-        /* Parse and write into user space. Filldir tells us when done! */
-        CDEBUG(D_FILE, "buffsize: %d offset %d, count %d.\n", 
-	       bufsize, offset, count);
-
-	i = 0;
-	result = 0; 
-        while ( pos + string_offset < bufsize && i < 1024) {
-                vdirent = (struct venus_dirent *) (buff + pos);
-
-                /* test if the name is fully in the buffer */
-                if ( pos + string_offset + (int) vdirent->d_namlen >= bufsize ){
-			if ( result == 0 )
-				printk("CODA: Invalid directory cfino: %ld\n", 
-				       filp->f_dentry->d_inode->i_ino);
-                        break;
-                }
-                /* now we are certain that we can read the entry from buff */
+	int result = 0; /* # of entries returned */
+	struct venus_dirent *vdir;
+	unsigned long vdir_size =
+	    (unsigned long)(&((struct venus_dirent *)0)->d_name);
+	unsigned int type;
+	struct qstr name;
+	ino_t ino;
+	int ret, i;
+
+	vdir = (struct venus_dirent *)kmalloc(sizeof(*vdir), GFP_KERNEL);
+	if (!vdir) return -ENOMEM;
+
+	i = filp->f_pos;
+	switch(i) {
+	case 0:
+		ret = filldir(dirent, ".", 1, 0, dir->d_inode->i_ino, DT_DIR);
+		if (ret < 0) break;
+		result++;
+		filp->f_pos++;
+		/* fallthrough */
+	case 1:
+		ret = filldir(dirent, "..", 2, 1, dir->d_parent->d_inode->i_ino, DT_DIR);
+		if (ret < 0) break;
+		result++;
+		filp->f_pos++;
+		/* fallthrough */
+	default:
+	while (1) {
+		/* read entries from the directory file */
+		ret = kernel_read(filp, filp->f_pos - 2, (char *)vdir,
+				  sizeof(*vdir));
+		if (ret < 0) {
+			printk("coda_venus_readdir: read dir failed %d\n", ret);
+			break;
+		}
+		if (ret == 0) break; /* end of directory file reached */
 
-                /* if we don't have a null entry, copy it */
-                if ( vdirent->d_fileno && vdirent->d_reclen ) {
-                        int namlen  = vdirent->d_namlen;
-                        off_t offs  = filp->f_pos; 
-                        ino_t ino   = vdirent->d_fileno;
-                        char *name  = vdirent->d_name;
-
-			errfill = filldir(getdent,  name, namlen, 
-					  offs, ino, DT_UNKNOWN); 
-CDEBUG(D_FILE, "entry %d: ino %ld, namlen %d, reclen %d, type %d, pos %d, string_offs %d, name %*s, offset %d, result: %d, errfill: %d.\n", i,vdirent->d_fileno, vdirent->d_namlen, vdirent->d_reclen, vdirent->d_type, pos,  string_offset, vdirent->d_namlen, vdirent->d_name, (u_int) offs, result, errfill);
-			/* errfill means no space for filling in this round */
-			if ( errfill < 0 ) {
-				result = 0;
-				break;
-			}
-                        /* adjust count */
-                        result++;
-                }
-                /* next one */
-                filp->f_pos += vdirent->d_reclen;
-		if ( filp->f_pos > filp->f_dentry->d_inode->i_size )
-			break; 
-		if ( !vdirent->d_reclen ) {
-			printk("CODA: Invalid directory, cfino: %ld\n", 
+		/* catch truncated reads */
+		if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
+			printk("coda_venus_readdir: short read: %ld\n",
 			       filp->f_dentry->d_inode->i_ino);
-			result = -EINVAL;
+			ret = -EBADF;
+			break;
+		}
+		/* validate whether the directory file actually makes sense */
+		if (vdir->d_reclen < vdir_size + vdir->d_namlen ||
+		    vdir->d_namlen > CODA_MAXNAMLEN) {
+			printk("coda_venus_readdir: Invalid dir: %ld\n",
+			       filp->f_dentry->d_inode->i_ino);
+			ret = -EBADF;
 			break;
 		}
-                pos += (unsigned int) vdirent->d_reclen;
-		i++;
-	} 
 
-	if ( i >= 1024 ) {
-		printk("Repeating too much in readdir %ld\n", 
-		       filp->f_dentry->d_inode->i_ino);
-		result = -EINVAL;
-	}
+		name.len = vdir->d_namlen;
+		name.name = vdir->d_name;
 
-exit:
-        CODA_FREE(buff, DIR_BUFSIZE);
-        return result;
+		/* Make sure we skip '.' and '..', we already got those */
+		if (name.name[0] == '.' && (name.len == 1 ||
+		    (vdir->d_name[1] == '.' && name.len == 2)))
+			vdir->d_fileno = name.len = 0;
+
+		/* skip null entries */
+		if (vdir->d_fileno && name.len) {
+			/* try to look up this entry in the dcache, that way
+			 * userspace doesn't have to worry about breaking
+			 * getcwd by having mismatched inode numbers for
+			 * internal volume mountpoints. */
+			ino = find_inode_number(dir, &name);
+			if (!ino) ino = vdir->d_fileno;
+
+			type = CDT2DT(vdir->d_type);
+			ret = filldir(dirent, name.name, name.len, filp->f_pos,
+				      ino, type); 
+			/* failure means no space for filling in this round */
+			if (ret < 0) break;
+			result++;
+		}
+		/* we'll always have progress because d_reclen is unsigned and
+		 * we've already established it is non-zero. */
+		filp->f_pos += vdir->d_reclen;
+	}
+	} 
+	kfree(vdir);
+	return result ? result : ret;
 }
 
 /* called when a cache lookup succeeds */
@@ -754,9 +737,7 @@
 		if (inode->i_ino != old_ino)
 			goto return_bad_inode;
 		
-		if ( cii->c_flags ) 
-			coda_flag_inode_children(inode, C_FLUSH);
-		
+		coda_flag_inode_children(inode, C_FLUSH);
 		cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
 	}
 
@@ -765,12 +746,6 @@
 	return 0;
 
 return_bad_inode:
-        inode->i_mapping = &inode->i_data;
-	if (cii->c_container) {
-		fput(cii->c_container);
-		cii->c_container = NULL;
-	}
-	make_bad_inode(inode);
 	unlock_kernel();
 	return -EIO;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/file.c linux/fs/coda/file.c
--- linux.orig/fs/coda/file.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/coda/file.c	2002-07-20 01:08:33.000000000 +0000
@@ -16,7 +16,6 @@
 #include <linux/errno.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
-#include <asm/segment.h>
 #include <linux/string.h>
 #include <asm/uaccess.h>
 
@@ -31,249 +30,248 @@
 int use_coda_close;
 
 static ssize_t
-coda_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+coda_file_read(struct file *coda_file, char *buf, size_t count, loff_t *ppos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
-	struct coda_inode_info *cii = ITOC(inode);
-	struct file *cfile;
-	ssize_t ret;
+	struct coda_file_info *cfi;
+	struct file *host_file;
 
-	cfile = cii->c_container;
-	if (!cfile) BUG();
+	cfi = CODA_FTOC(coda_file);
+	if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
+	host_file = cfi->cfi_container;
 
-	if (!cfile->f_op || !cfile->f_op->read)
+	if (!host_file->f_op || !host_file->f_op->read)
 		return -EINVAL;
 
-	down(&inode->i_sem);
-	ret = cfile->f_op->read(cfile, buf, count, ppos);
-	UPDATE_ATIME(inode);
-	up(&inode->i_sem);
-
-	return ret;
+	return host_file->f_op->read(host_file, buf, count, ppos);
 }
 
 static ssize_t
-coda_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
+coda_file_write(struct file *coda_file, const char *buf, size_t count, loff_t *ppos)
 {
-	struct inode *cinode, *inode = file->f_dentry->d_inode;
-	struct coda_inode_info *cii = ITOC(inode);
-	struct file *cfile;
+	struct inode *coda_inode = coda_file->f_dentry->d_inode;
+	struct coda_file_info *cfi;
+	struct file *host_file;
 	ssize_t ret;
-	int flags;
 
-	cfile = cii->c_container;
-	if (!cfile) BUG();
+	cfi = CODA_FTOC(coda_file);
+	if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
+	host_file = cfi->cfi_container;
 
-	if (!cfile->f_op || !cfile->f_op->write)
+	if (!host_file->f_op || !host_file->f_op->write)
 		return -EINVAL;
 
-	cinode = cfile->f_dentry->d_inode;
-	down(&inode->i_sem);
-	flags = cfile->f_flags;
-        cfile->f_flags |= file->f_flags & (O_APPEND | O_SYNC);
-
-	ret = cfile->f_op->write(cfile, buf, count, ppos);
-
-	cfile->f_flags = flags;
-	inode->i_size = cinode->i_size;
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	up(&inode->i_sem);
+	down(&coda_inode->i_sem);
+
+	ret = host_file->f_op->write(host_file, buf, count, ppos);
+
+	coda_inode->i_size = host_file->f_dentry->d_inode->i_size;
+	coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
+	coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME;
+	up(&coda_inode->i_sem);
 
 	return ret;
 }
 
 static int
-coda_file_mmap(struct file *file, struct vm_area_struct *vma)
+coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
 {
-	struct inode *inode = file->f_dentry->d_inode;
-	struct coda_inode_info *cii = ITOC(inode);
-	struct file *cfile;
-	int ret;
-
-	cfile = cii->c_container;
+	struct coda_file_info *cfi;
+	struct coda_inode_info *cii;
+	struct file *host_file;
+	struct inode *coda_inode, *host_inode;
 
-	if (!cfile) BUG();
+	cfi = CODA_FTOC(coda_file);
+	if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
+	host_file = cfi->cfi_container;
 
-	if (!cfile->f_op || !cfile->f_op->mmap)
+	if (!host_file->f_op || !host_file->f_op->mmap)
 		return -ENODEV;
 
-	down(&inode->i_sem);
-	ret = cfile->f_op->mmap(cfile, vma);
-	UPDATE_ATIME(inode);
-	up(&inode->i_sem);
-
-	return ret;
+	coda_inode = coda_file->f_dentry->d_inode;
+	host_inode = host_file->f_dentry->d_inode;
+	if (coda_inode->i_mapping == &coda_inode->i_data)
+		coda_inode->i_mapping = host_inode->i_mapping;
+
+	/* only allow additional mmaps as long as userspace isn't changing
+	 * the container file on us! */
+	else if (coda_inode->i_mapping != host_inode->i_mapping)
+		return -EBUSY;
+
+	/* keep track of how often the coda_inode/host_file has been mmapped */
+	cii = ITOC(coda_inode);
+	cii->c_mapcount++;
+	cfi->cfi_mapcount++;
+ 
+	return host_file->f_op->mmap(host_file, vma);
 }
 
-int coda_open(struct inode *i, struct file *f)
+int coda_open(struct inode *coda_inode, struct file *coda_file)
 {
-	struct file *fh = NULL;
-	int error = 0;
-	unsigned short flags = f->f_flags & (~O_EXCL);
+	struct file *host_file = NULL;
+	int error;
+	unsigned short flags = coda_file->f_flags & (~O_EXCL);
 	unsigned short coda_flags = coda_flags_to_cflags(flags);
-	struct coda_cred *cred;
-	struct coda_inode_info *cii;
+	struct coda_file_info *cfi;
+	struct inode *host_inode;
 
-	lock_kernel();
 	coda_vfs_stat.open++;
 
-	CDEBUG(D_SPECIAL, "OPEN inode number: %ld, count %d, flags %o.\n", 
-	       f->f_dentry->d_inode->i_ino, atomic_read(&f->f_dentry->d_count), flags);
+	cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL);
+	if (!cfi) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
 
-	error = venus_open(i->i_sb, coda_i2f(i), coda_flags, &fh); 
-	if (error || !fh) {
-	        CDEBUG(D_FILE, "coda_open: venus_open result %d\n", error);
+	lock_kernel();
+
+	error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
+			   &host_file); 
+	if (error || !host_file) {
+		kfree(cfi);
 		unlock_kernel();
 		return error;
 	}
 
-	/* coda_upcall returns filehandle of container file object */
-	cii = ITOC(i);
-	if (cii->c_container)
-		fput(cii->c_container);
-
-	cii->c_contcount++;
-	cii->c_container = fh;
-	i->i_mapping = &cii->c_container->f_dentry->d_inode->i_data;
-
-	cred = kmalloc(sizeof(struct coda_cred), GFP_KERNEL);
-
-	/* If the allocation failed, we'll just muddle on. This actually works
-	 * fine for normal cases. (i.e. when open credentials are the same as
-	 * close credentials) */
-	if (cred) {
-		coda_load_creds(cred);
-		f->private_data = cred;
+	host_file->f_flags |= coda_file->f_flags & (O_APPEND | O_SYNC);
+
+	cfi->cfi_magic = CODA_MAGIC;
+	cfi->cfi_mapcount = 0;
+	cfi->cfi_container = host_file;
+	coda_load_creds(&cfi->cfi_cred);
+
+	host_inode = host_file->f_dentry->d_inode;
+	if (coda_inode->i_mapping == &coda_inode->i_data)
+		coda_inode->i_mapping = host_inode->i_mapping;
+
+	else if (coda_inode->i_mapping != host_inode->i_mapping) {
+		/* This is not a good thing, it doesn't happen with 'venus'
+		 * Coda's own userspace daemon, but others might not provide
+		 * the same guarantees. Still looking for the real fix. */
+		printk("coda_open: changed mapping\n");
+		coda_inode->i_mapping = host_inode->i_mapping;
 	}
 
-	CDEBUG(D_FILE, "result %d, coda i->i_count is %d, cii->contcount is %d for ino %ld\n", 
-	       error, atomic_read(&i->i_count), cii->c_contcount, i->i_ino);
-	CDEBUG(D_FILE, "cache ino: %ld, count %d, ops %p\n", 
-	       fh->f_dentry->d_inode->i_ino,
-	       atomic_read(&fh->f_dentry->d_inode->i_count),
-               fh->f_dentry->d_inode->i_op);
+	if (coda_file->private_data != NULL) BUG();
+	coda_file->private_data = cfi;
+
 	unlock_kernel();
 	return 0;
 }
 
-
-int coda_flush(struct file *file)
+int coda_flush(struct file *coda_file)
 {
-	unsigned short flags = (file->f_flags) & (~O_EXCL);
-	unsigned short cflags;
-	struct coda_inode_info *cii;
-	struct file *cfile;
-	struct inode *cinode, *inode;
+	unsigned short flags = coda_file->f_flags & ~O_EXCL;
+	unsigned short coda_flags = coda_flags_to_cflags(flags);
+	struct coda_file_info *cfi;
+	struct inode *coda_inode;
 	int err = 0, fcnt;
 
 	coda_vfs_stat.flush++;
 
 	/* No need to make an upcall when we have not made any modifications
 	 * to the file */
-	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+	if ((coda_file->f_flags & O_ACCMODE) == O_RDONLY)
 		return 0;
 
 	if (use_coda_close)
 		return 0;
 
-	fcnt = file_count(file);
+	fcnt = file_count(coda_file);
 	if (fcnt > 1) return 0;
 
-	cflags = coda_flags_to_cflags(flags);
+	coda_inode = coda_file->f_dentry->d_inode;
 
-	inode = file->f_dentry->d_inode;
-	cii = ITOC(inode);
-	cfile = cii->c_container;
-	if (!cfile) BUG();
+	cfi = CODA_FTOC(coda_file);
+	if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
 
-	cinode = cfile->f_dentry->d_inode;
+	err = venus_store(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
+			  &cfi->cfi_cred);
 
-	CDEBUG(D_FILE, "FLUSH coda (file %p ct %d)\n", file, fcnt);
-
-	err = venus_store(inode->i_sb, coda_i2f(inode), cflags,
-                          (struct coda_cred *)file->private_data);
 	if (err == -EOPNOTSUPP) {
 		use_coda_close = 1;
 		err = 0;
 	}
 
-	CDEBUG(D_FILE, "coda_flush: result: %d\n", err);
 	return err;
 }
 
-int coda_release(struct inode *i, struct file *f)
+int coda_release(struct inode *coda_inode, struct file *coda_file)
 {
-	unsigned short flags = (f->f_flags) & (~O_EXCL);
-	unsigned short cflags = coda_flags_to_cflags(flags);
+	unsigned short flags = (coda_file->f_flags) & (~O_EXCL);
+	unsigned short coda_flags = coda_flags_to_cflags(flags);
+	struct coda_file_info *cfi;
 	struct coda_inode_info *cii;
-	struct file *cfile;
+	struct inode *host_inode;
 	int err = 0;
 
 	lock_kernel();
 	coda_vfs_stat.release++;
  
 	if (!use_coda_close) {
-		err = venus_release(i->i_sb, coda_i2f(i), cflags);
+		err = venus_release(coda_inode->i_sb, coda_i2f(coda_inode),
+				    coda_flags);
 		if (err == -EOPNOTSUPP) {
 			use_coda_close = 1;
 			err = 0;
 		}
 	}
 
+	cfi = CODA_FTOC(coda_file);
+	if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
+
 	if (use_coda_close)
-		err = venus_close(i->i_sb, coda_i2f(i), cflags,
-                                  (struct coda_cred *)f->private_data);
+		err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
+				  coda_flags, &cfi->cfi_cred);
 
-	cii = ITOC(i);
-	cfile = cii->c_container;
-	if (!cfile) BUG();
+	host_inode = cfi->cfi_container->f_dentry->d_inode;
+	cii = ITOC(coda_inode);
 
-	if (--cii->c_contcount) {
-		unlock_kernel();
-		return err;
+	/* did we mmap this file? */
+	if (coda_inode->i_mapping == &host_inode->i_data) {
+		cii->c_mapcount -= cfi->cfi_mapcount;
+		if (!cii->c_mapcount)
+			coda_inode->i_mapping = &coda_inode->i_data;
 	}
 
-	i->i_mapping = &i->i_data;
-	fput(cfile);
-	cii->c_container = NULL;
-
-	if (f->private_data) {
-		kfree(f->private_data);
-		f->private_data = NULL;
-	}
+	coda_inode->i_mapping = &coda_inode->i_data;
+	fput(cfi->cfi_container);
+
+	kfree(coda_file->private_data);
+	coda_file->private_data = NULL;
 
 	unlock_kernel();
 	return err;
 }
 
-int coda_fsync(struct file *file, struct dentry *dentry, int datasync)
+int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync)
 {
-	struct file *cfile;
-	struct dentry *cdentry;
-	struct inode *cinode, *inode = dentry->d_inode;
-	struct coda_inode_info *cii = ITOC(inode);
+	struct file *host_file;
+	struct dentry *host_dentry;
+	struct inode *host_inode, *coda_inode = coda_dentry->d_inode;
+	struct coda_file_info *cfi;
 	int err = 0;
 
-	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-	      S_ISLNK(inode->i_mode)))
+	if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) ||
+	      S_ISLNK(coda_inode->i_mode)))
 		return -EINVAL;
 
-	cfile = cii->c_container;
-	if (!cfile) BUG();
+	cfi = CODA_FTOC(coda_file);
+	if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
+	host_file = cfi->cfi_container;
 
 	coda_vfs_stat.fsync++;
 
-	if (cfile->f_op && cfile->f_op->fsync) {
-		cdentry = cfile->f_dentry;
-		cinode = cdentry->d_inode;
-		down(&cinode->i_sem);
-		err = cfile->f_op->fsync(cfile, cdentry, datasync);
-		up(&cinode->i_sem);
+	if (host_file->f_op && host_file->f_op->fsync) {
+		host_dentry = host_file->f_dentry;
+		host_inode = host_dentry->d_inode;
+		down(&host_inode->i_sem);
+		err = host_file->f_op->fsync(host_file, host_dentry, datasync);
+		up(&host_inode->i_sem);
 	}
 
 	if ( !err && !datasync ) {
 		lock_kernel();
-		err = venus_fsync(inode->i_sb, coda_i2f(inode));
+		err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode));
 		unlock_kernel();
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/inode.c linux/fs/coda/inode.c
--- linux.orig/fs/coda/inode.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/coda/inode.c	2002-07-20 01:08:37.000000000 +0000
@@ -25,7 +25,6 @@
 
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
-#include <asm/segment.h>
 
 #include <linux/coda.h>
 #include <linux/coda_linux.h>
@@ -129,6 +128,7 @@
 	sbi->sbi_sb = sb;
 	sbi->sbi_vcomm = vc;
 	INIT_LIST_HEAD(&sbi->sbi_cihead);
+	init_MUTEX(&sbi->sbi_iget4_mutex);
 
         sb->u.generic_sbp = sbi;
         sb->s_blocksize = 1024;	/* XXXXX  what do we put here?? */
@@ -189,28 +189,13 @@
 
         if (!sbi) BUG();
 
-#if 0
-	/* check if the inode is already initialized */
-	if (inode->u.generic_ip) {
-            printk("coda_read_inode: initialized inode");
-            return;
-        }
-
-	inode->u.generic_ip = cii_alloc();
-	if (!inode->u.generic_ip) {
-		CDEBUG(D_CNODE, "coda_read_inode: failed to allocate inode info\n");
-		make_bad_inode(inode);
-		return;
-	}
-	memset(inode->u.generic_ip, 0, sizeof(struct coda_inode_info));
-#endif
-
 	cii = ITOC(inode);
 	if (!coda_isnullfid(&cii->c_fid)) {
             printk("coda_read_inode: initialized inode");
             return;
         }
 
+	cii->c_mapcount = 0;
 	list_add(&cii->c_cilist, &sbi->sbi_cihead);
 }
 
@@ -222,30 +207,21 @@
 	       inode->i_ino, atomic_read(&inode->i_count));        
 	CDEBUG(D_DOWNCALL, "clearing inode: %ld, %x\n", inode->i_ino, cii->c_flags);
 
-	if (cii->c_container) BUG();
-	
         list_del_init(&cii->c_cilist);
-	inode->i_mapping = &inode->i_data;
 	coda_cache_clear_inode(inode);
-
-#if 0
-	cii_free(inode->u.generic_ip);
-	inode->u.generic_ip = NULL;
-#endif
 }
 
 int coda_notify_change(struct dentry *de, struct iattr *iattr)
 {
 	struct inode *inode = de->d_inode;
-        struct coda_vattr vattr;
-        int error;
-	
-	inode->i_ctime = CURRENT_TIME;
+	struct coda_vattr vattr;
+	int error;
 
-        memset(&vattr, 0, sizeof(vattr)); 
-        coda_iattr_to_vattr(iattr, &vattr);
+	memset(&vattr, 0, sizeof(vattr)); 
 
-        vattr.va_type = C_VNON; /* cannot set type */
+	inode->i_ctime = CURRENT_TIME;
+	coda_iattr_to_vattr(iattr, &vattr);
+	vattr.va_type = C_VNON; /* cannot set type */
 	CDEBUG(D_SUPER, "vattr.va_mode %o\n", vattr.va_mode);
 
 	/* Venus is responsible for truncating the container-file!!! */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/pioctl.c linux/fs/coda/pioctl.c
--- linux.orig/fs/coda/pioctl.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/coda/pioctl.c	2002-07-20 01:08:38.000000000 +0000
@@ -14,7 +14,6 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/locks.h>
-#include <asm/segment.h>
 #include <linux/string.h>
 #define __NO_VERSION__
 #include <linux/module.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/psdev.c linux/fs/coda/psdev.c
--- linux.orig/fs/coda/psdev.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/coda/psdev.c	2002-07-20 01:08:38.000000000 +0000
@@ -38,7 +38,6 @@
 #include <linux/list.h>
 #include <linux/smp_lock.h>
 #include <asm/io.h>
-#include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/poll.h>
 #include <asm/uaccess.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/sysctl.c linux/fs/coda/sysctl.c
--- linux.orig/fs/coda/sysctl.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/coda/sysctl.c	2002-07-20 01:08:32.000000000 +0000
@@ -21,7 +21,6 @@
 #include <linux/stat.h>
 #include <linux/ctype.h>
 #include <asm/bitops.h>
-#include <asm/segment.h>
 #include <asm/uaccess.h>
 #include <linux/utsname.h>
 #define __NO_VERSION__
@@ -51,7 +50,6 @@
 
 static ctl_table coda_table[] = {
 	{CODA_DEBUG, "debug", &coda_debug, sizeof(int), 0644, NULL, &proc_dointvec},
-	{CODA_ENTRY, "printentry", &coda_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
  	{CODA_MC, "accesscache", &coda_access_cache, sizeof(int), 0644, NULL, &proc_dointvec}, 
  	{CODA_TIMEOUT, "timeout", &coda_timeout, sizeof(int), 0644, NULL, &proc_dointvec},
  	{CODA_HARD, "hard", &coda_hard, sizeof(int), 0644, NULL, &proc_dointvec},
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/coda/upcall.c linux/fs/coda/upcall.c
--- linux.orig/fs/coda/upcall.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/coda/upcall.c	2002-07-20 01:08:39.000000000 +0000
@@ -15,7 +15,6 @@
  */
 
 #include <asm/system.h>
-#include <asm/segment.h>
 #include <asm/signal.h>
 #include <linux/signal.h>
 
@@ -176,10 +175,7 @@
 	insize = SIZE(store);
 	UPARG(CODA_STORE);
 	
-	if ( cred ) {
-		memcpy(&(inp->ih.cred), cred, sizeof(*cred));
-	} else 
-		printk("CODA: store without valid file creds.\n");
+	memcpy(&(inp->ih.cred), cred, sizeof(*cred));
 	
         inp->coda_store.VFid = *fid;
         inp->coda_store.flags = flags;
@@ -218,10 +214,7 @@
 	insize = SIZE(release);
 	UPARG(CODA_CLOSE);
 	
-	if ( cred ) {
-		memcpy(&(inp->ih.cred), cred, sizeof(*cred));
-	} else 
-		printk("CODA: close without valid file creds.\n");
+	memcpy(&(inp->ih.cred), cred, sizeof(*cred));
 	
         inp->coda_close.VFid = *fid;
         inp->coda_close.flags = flags;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/cramfs/README linux/fs/cramfs/README
--- linux.orig/fs/cramfs/README	2001-07-19 23:14:53.000000000 +0000
+++ linux/fs/cramfs/README	2002-07-20 01:08:29.000000000 +0000
@@ -6,8 +6,8 @@
 swapped around (though it does care that directory entries (inodes) in
 a given directory are contiguous, as this is used by readdir).
 
-All data is in host-endian format; neither mkcramfs nor the kernel
-ever do swabbing.  (See section `Block Size' below.)
+All data is currently in host-endian format; neither mkcramfs nor the
+kernel ever do swabbing.  (See section `Block Size' below.)
 
 <filesystem>:
 	<superblock>
@@ -29,6 +29,10 @@
 lines); put another way, the same order as `find -type d -exec
 ls -AU1 {} \;'.
 
+Beginning in 2.4.7, directory entries are sorted.  This optimization
+allows cramfs_lookup to return more quickly when a filename does not
+exist, speeds up user-space directory sorts, etc.
+
 <data>:
 	One <file_data> for each file that's either a symlink or a
 	 regular file of non-zero st_size.
@@ -63,17 +67,15 @@
 This kernel supports cramfs holes (i.e. [efficient representation of]
 blocks in uncompressed data consisting entirely of NUL bytes), but by
 default mkcramfs doesn't test for & create holes, since cramfs in
-kernels up to at least 2.3.39 didn't support holes.  Compile mkcramfs
-with -DDO_HOLES if you want it to create files that can have holes in
-them.
+kernels up to at least 2.3.39 didn't support holes.  Run mkcramfs
+with -z if you want it to create files that can have holes in them.
 
 
 Tools
 -----
 
-If you're hacking on cramfs, you might find useful some tools for
-testing cramfs at <http://cvs.bofh.asn.au/cramfs/>, including a
-rudimentary fsck for cramfs.
+The cramfs user-space tools, including mkcramfs and cramfsck, are
+located at <http://sourceforge.net/projects/cramfs/>.
 
 
 Future Development
@@ -103,8 +105,8 @@
 PAGE_CACHE_SIZE (4096)' to `#include <asm/page.h>'.  The disadvantage
 is that the generated cramfs cannot always be shared between different
 kernels, not even necessarily kernels of the same architecture if
-PAGE_CACHE_SIZE is subject to change between kernel versions.
-
+PAGE_CACHE_SIZE is subject to change between kernel versions
+(currently possible with arm and ia64).
 
 The remaining options try to make cramfs more sharable.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/cramfs/inode.c linux/fs/cramfs/inode.c
--- linux.orig/fs/cramfs/inode.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/cramfs/inode.c	2002-07-20 01:08:23.000000000 +0000
@@ -116,7 +116,7 @@
 	unsigned i, blocknr, buffer, unread;
 	unsigned long devsize;
 	int major, minor;
-	
+
 	char *data;
 
 	if (!len)
@@ -186,7 +186,7 @@
 	}
 	return read_buffers[buffer] + offset;
 }
-			
+
 
 static struct super_block * cramfs_read_super(struct super_block *sb, void *data, int silent)
 {
@@ -268,7 +268,7 @@
 	buf->f_bavail = 0;
 	buf->f_files = sb->CRAMFS_SB_FILES;
 	buf->f_ffree = 0;
-	buf->f_namelen = 255;
+	buf->f_namelen = CRAMFS_MAXPATHLEN;
 	return 0;
 }
 
@@ -461,4 +461,3 @@
 module_init(init_cramfs_fs)
 module_exit(exit_cramfs_fs)
 MODULE_LICENSE("GPL");
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/dcache.c linux/fs/dcache.c
--- linux.orig/fs/dcache.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/dcache.c	2002-07-20 01:08:26.000000000 +0000
@@ -67,7 +67,7 @@
 }
 
 /*
- * Release the dentry's inode, using the fileystem
+ * Release the dentry's inode, using the filesystem
  * d_iput() operation if defined.
  * Called with dcache_lock held, drops it.
  */
@@ -568,8 +568,7 @@
 	count = dentry_stat.nr_unused / priority;
 
 	prune_dcache(count);
-	kmem_cache_shrink(dentry_cache);
-	return 0;
+	return kmem_cache_shrink(dentry_cache);
 }
 
 #define NAME_ALLOC_LEN(len)	((len+16) & ~15)
@@ -1210,7 +1209,7 @@
 			__get_free_pages(GFP_ATOMIC, order);
 	} while (dentry_hashtable == NULL && --order >= 0);
 
-	printk("Dentry-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+	printk(KERN_INFO "Dentry cache hash table entries: %d (order: %ld, %ld bytes)\n",
 			nr_hash, order, (PAGE_SIZE << order));
 
 	if (!dentry_hashtable)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/devfs/base.c linux/fs/devfs/base.c
--- linux.orig/fs/devfs/base.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/devfs/base.c	2002-07-20 01:08:27.000000000 +0000
@@ -608,6 +608,18 @@
 	       Fixed deadlock bug in <devfs_d_revalidate_wait>.
 	       Tag VFS deletable in <devfs_mk_symlink> if handle ignored.
   v1.10
+    20020129   Richard Gooch <rgooch@atnf.csiro.au>
+	       Added KERN_* to remaining messages.
+	       Cleaned up declaration of <stat_read>.
+  v1.11
+    20020219   Richard Gooch <rgooch@atnf.csiro.au>
+	       Changed <devfs_rmdir> to allow later additions if not yet empty.
+  v1.12
+    20020514   Richard Gooch <rgooch@atnf.csiro.au>
+	       Added BKL to <devfs_open> because drivers still need it.
+	       Protected <scan_dir_for_removable> and <get_removable_partition>
+	       from changing directory contents.
+  v1.12a
 */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -640,7 +652,7 @@
 #include <asm/bitops.h>
 #include <asm/atomic.h>
 
-#define DEVFS_VERSION            "1.10 (20020120)"
+#define DEVFS_VERSION            "1.12a (20020514)"
 
 #define DEVFS_NAME "devfs"
 
@@ -848,8 +860,8 @@
 			 unsigned int cmd, unsigned long arg);
 static int devfsd_close (struct inode *inode, struct file *file);
 #ifdef CONFIG_DEVFS_DEBUG
-static int stat_read (struct file *file, char *buf, size_t len,
-			    loff_t *ppos);
+static ssize_t stat_read (struct file *file, char *buf, size_t len,
+			  loff_t *ppos);
 static struct file_operations stat_fops =
 {
     read:    stat_read,
@@ -2415,6 +2427,9 @@
  *	@de: The device.
  *
  *	Returns 1 if the media was changed, else 0.
+ *
+ *	This function may block, and may indirectly cause the parent directory
+ *	contents to be changed due to partition re-reading.
  */
 
 static int check_disc_changed (struct devfs_entry *de)
@@ -2431,10 +2446,10 @@
     if (bdops->check_media_change == NULL) goto out;
     if ( !bdops->check_media_change (dev) ) goto out;
     retval = 1;
-    printk ( KERN_DEBUG "VFS: Disk change detected on device %s\n",
+    printk (KERN_DEBUG "VFS: Disk change detected on device %s\n",
 	     kdevname (dev) );
-    if (invalidate_device(dev, 0))
-	printk("VFS: busy inodes on changed media..\n");
+    if ( invalidate_device (dev, 0) )
+	printk (KERN_WARNING "VFS: busy inodes on changed media..\n");
     /*  Ugly hack to disable messages about unable to read partition table  */
     tmp = warn_no_part;
     warn_no_part = 0;
@@ -2449,19 +2464,29 @@
 /**
  *	scan_dir_for_removable - Scan a directory for removable media devices and check media.
  *	@dir: The directory.
+ *
+ *	This function may block, and may indirectly cause the directory
+ *	contents to be changed due to partition re-reading. The directory will
+ *	be locked for reading.
  */
 
 static void scan_dir_for_removable (struct devfs_entry *dir)
 {
     struct devfs_entry *de;
 
-    if (dir->u.dir.num_removable < 1) return;
-    for (de = dir->u.dir.first; de != NULL; de = de->next)
+    read_lock (&dir->u.dir.lock);
+    if (dir->u.dir.num_removable < 1) de = NULL;
+    else
     {
-	if ( !S_ISBLK (de->mode) ) continue;
-	if (!de->u.fcb.removable) continue;
-	check_disc_changed (de);
+	for (de = dir->u.dir.first; de != NULL; de = de->next)
+	{
+	    if (S_ISBLK (de->mode) && de->u.fcb.removable) break;
+	}
+	devfs_get (de);
     }
+    read_unlock (&dir->u.dir.lock);
+    if (de) check_disc_changed (de);
+    devfs_put (de);
 }   /*  End Function scan_dir_for_removable  */
 
 /**
@@ -2471,25 +2496,37 @@
  *	@namelen: The number of characters in <<name>>.
  *
  *	Returns 1 if the media was changed, else 0.
+ *
+ *	This function may block, and may indirectly cause the directory
+ *	contents to be changed due to partition re-reading. The directory must
+ *	be locked for reading upon entry, and will be unlocked upon exit.
  */
 
 static int get_removable_partition (struct devfs_entry *dir, const char *name,
 				    unsigned int namelen)
 {
+    int retval;
     struct devfs_entry *de;
 
+    if (dir->u.dir.num_removable < 1)
+    {
+	read_unlock (&dir->u.dir.lock);
+	return 0;
+    }
     for (de = dir->u.dir.first; de != NULL; de = de->next)
     {
-	if ( !S_ISBLK (de->mode) ) continue;
-	if (!de->u.fcb.removable) continue;
-	if (strcmp (de->name, "disc") == 0) return check_disc_changed (de);
+	if (!S_ISBLK (de->mode) || !de->u.fcb.removable) continue;
+	if (strcmp (de->name, "disc") == 0) break;
 	/*  Support for names where the partition is appended to the disc name
 	 */
 	if (de->namelen >= namelen) continue;
-	if (strncmp (de->name, name, de->namelen) != 0) continue;
-	return check_disc_changed (de);
+	if (strncmp (de->name, name, de->namelen) == 0) break;
     }
-    return 0;
+    devfs_get (de);
+    read_unlock (&dir->u.dir.lock);
+    retval = de ? check_disc_changed (de) : 0;
+    devfs_put (de);
+    return retval;
 }   /*  End Function get_removable_partition  */
 
 
@@ -2738,15 +2775,22 @@
     {
 	file->f_op = &def_blk_fops;
 	if (df->ops) inode->i_bdev->bd_op = df->ops;
+	err = def_blk_fops.open (inode, file);
     }
-    else file->f_op = fops_get ( (struct file_operations *) df->ops );
-    if (file->f_op)
-	err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0;
     else
     {
-	/*  Fallback to legacy scheme  */
-	if ( S_ISCHR (inode->i_mode) ) err = chrdev_open (inode, file);
-	else err = -ENODEV;
+	file->f_op = fops_get ( (struct file_operations *) df->ops );
+	if (file->f_op)
+	{
+	    lock_kernel ();
+	    err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0;
+	    unlock_kernel ();
+	}
+	else
+	{   /*  Fallback to legacy scheme  */
+	    if ( S_ISCHR (inode->i_mode) ) err = chrdev_open (inode, file);
+	    else err = -ENODEV;
+	}
     }
     if (err < 0) return err;
     /*  Open was successful  */
@@ -2946,15 +2990,17 @@
     if (parent == NULL) return ERR_PTR (-ENOENT);
     read_lock (&parent->u.dir.lock);
     de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len);
-    read_unlock (&parent->u.dir.lock);
-    if ( (de == NULL) && (parent->u.dir.num_removable > 0) &&
-	 get_removable_partition (parent, dentry->d_name.name,
-				  dentry->d_name.len) )
-    {
-	read_lock (&parent->u.dir.lock);
-	de = _devfs_search_dir (parent, dentry->d_name.name,
-				dentry->d_name.len);
-	read_unlock (&parent->u.dir.lock);
+    if (de) read_unlock (&parent->u.dir.lock);
+    else
+    {   /*  Try re-reading the partition (media may have changed)  */
+	if ( get_removable_partition (parent, dentry->d_name.name,
+				      dentry->d_name.len) )  /*  Unlocks  */
+	{   /*  Media did change  */
+	    read_lock (&parent->u.dir.lock);
+	    de = _devfs_search_dir (parent, dentry->d_name.name,
+				    dentry->d_name.len);
+	    read_unlock (&parent->u.dir.lock);
+	}
     }
     lookup_info.de = de;
     init_waitqueue_head (&lookup_info.wait_queue);
@@ -3112,10 +3158,10 @@
     if (de == NULL) return -ENOENT;
     if ( !S_ISDIR (de->mode) ) return -ENOTDIR;
     if (!de->vfs_deletable) return -EPERM;
-    /*  First ensure the directory is empty and will stay thay way  */
+    /*  First ensure the directory is empty and will stay that way  */
     write_lock (&de->u.dir.lock);
-    de->u.dir.no_more_additions = TRUE;
     if (de->u.dir.first) err = -ENOTEMPTY;
+    else de->u.dir.no_more_additions = TRUE;
     write_unlock (&de->u.dir.lock);
     if (err) return err;
     /*  Now unhook the directory from it's parent  */
@@ -3237,7 +3283,7 @@
     return sb;
 
 out_no_root:
-    printk ("devfs_read_super: get root inode failed\n");
+    PRINTK ("(): get root inode failed\n");
     if (root_inode) iput (root_inode);
     return NULL;
 }   /*  End Function devfs_read_super  */
@@ -3464,7 +3510,7 @@
 {
     int err;
 
-    printk ("%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n",
+    printk (KERN_INFO "%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n",
 	    DEVFS_NAME, DEVFS_VERSION);
     devfsd_buf_cache = kmem_cache_create ("devfsd_event",
 					  sizeof (struct devfsd_buf_entry),
@@ -3472,9 +3518,9 @@
     if (!devfsd_buf_cache) OOPS ("(): unable to allocate event slab\n");
 #ifdef CONFIG_DEVFS_DEBUG
     devfs_debug = devfs_debug_init;
-    printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
+    printk (KERN_INFO "%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
 #endif
-    printk ("%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options);
+    printk (KERN_INFO "%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options);
     err = register_filesystem (&devfs_fs_type);
     if (!err)
     {
@@ -3491,8 +3537,8 @@
 
     if ( !(boot_options & OPTION_MOUNT) ) return;
     err = do_mount ("none", "/dev", "devfs", 0, "");
-    if (err == 0) printk ("Mounted devfs on /dev\n");
-    else printk ("Warning: unable to mount devfs, err: %d\n", err);
+    if (err == 0) printk (KERN_INFO "Mounted devfs on /dev\n");
+    else PRINTK ("(): unable to mount devfs, err: %d\n", err);
 }   /*  End Function mount_devfs_fs  */
 
 module_init(init_devfs_fs)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/devfs/util.c linux/fs/devfs/util.c
--- linux.orig/fs/devfs/util.c	2001-10-11 16:43:30.000000000 +0000
+++ linux/fs/devfs/util.c	2002-07-20 01:08:38.000000000 +0000
@@ -1,6 +1,6 @@
 /*  devfs (Device FileSystem) utilities.
 
-    Copyright (C) 1999-2001  Richard Gooch
+    Copyright (C) 1999-2002  Richard Gooch
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -48,6 +48,16 @@
     20010818   Richard Gooch <rgooch@atnf.csiro.au>
                Updated major masks up to Linus' "no new majors" proclamation.
 	       Block: were 126 now 122 free, char: were 26 now 19 free.
+    20020324   Richard Gooch <rgooch@atnf.csiro.au>
+               Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
+	       bitfield.
+    20020326   Richard Gooch <rgooch@atnf.csiro.au>
+               Fixed bitfield data type for <devfs_*alloc_devnum>.
+               Made major bitfield type and initialiser 64 bit safe.
+    20020413   Richard Gooch <rgooch@atnf.csiro.au>
+               Fixed shift warning on 64 bit machines.
+    20020428   Richard Gooch <rgooch@atnf.csiro.au>
+               Copied and used macro for error messages from fs/devfs/base.c 
 */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -57,69 +67,11 @@
 
 #include <asm/bitops.h>
 
+#define PRINTK(format, args...) \
+   {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);}
 
-/*  Private functions follow  */
-
-/**
- *	_devfs_convert_name - Convert from an old style location-based name to new style.
- *	@new: The new name will be written here.
- *	@old: The old name.
- *	@disc: If true, disc partitioning information should be processed.
- */
-
-static void __init _devfs_convert_name (char *new, const char *old, int disc)
-{
-    int host, bus, target, lun;
-    char *ptr;
-    char part[8];
-
-    /*  Decode "c#b#t#u#"  */
-    if (old[0] != 'c') return;
-    host = simple_strtol (old + 1, &ptr, 10);
-    if (ptr[0] != 'b') return;
-    bus = simple_strtol (ptr + 1, &ptr, 10);
-    if (ptr[0] != 't') return;
-    target = simple_strtol (ptr + 1, &ptr, 10);
-    if (ptr[0] != 'u') return;
-    lun = simple_strtol (ptr + 1, &ptr, 10);
-    if (disc)
-    {
-	/*  Decode "p#"  */
-	if (ptr[0] == 'p') sprintf (part, "part%s", ptr + 1);
-	else strcpy (part, "disc");
-    }
-    else part[0] = '\0';
-    sprintf (new, "/host%d/bus%d/target%d/lun%d/%s",
-	     host, bus, target, lun, part);
-}   /*  End Function _devfs_convert_name  */
-
-
-/*  Public functions follow  */
-
-/**
- *	devfs_make_root - Create the root FS device entry if required.
- *	@name: The name of the root FS device, as passed by "root=".
- */
-
-void __init devfs_make_root (const char *name)
-{
-    char dest[64];
-
-    if ( (strncmp (name, "sd/", 3) == 0) || (strncmp (name, "sr/", 3) == 0) )
-    {
-	strcpy (dest, "../scsi");
-	_devfs_convert_name (dest + 7, name + 3, (name[1] == 'd') ? 1 : 0);
-    }
-    else if ( (strncmp (name, "ide/hd/", 7) == 0) ||
-	      (strncmp (name, "ide/cd/", 7) == 0) )
-    {
-	strcpy (dest, "..");
-	_devfs_convert_name (dest + 2, name + 7, (name[4] == 'h') ? 1 : 0);
-    }
-    else return;
-    devfs_mk_symlink (NULL, name, DEVFS_FL_DEFAULT, dest, NULL, NULL);
-}   /*  End Function devfs_make_root  */
 
+/*  Private functions follow  */
 
 /**
  *	devfs_register_tape - Register a tape device in the "/dev/tapes" hierarchy.
@@ -186,8 +138,13 @@
 struct major_list
 {
     spinlock_t lock;
-    __u32 bits[8];
+    unsigned long bits[256 / BITS_PER_LONG];
 };
+#if BITS_PER_LONG == 32
+#  define INITIALISER64(low,high) (low), (high)
+#else
+#  define INITIALISER64(low,high) ( (unsigned long) (high) << 32 | (low) )
+#endif
 
 /*  Block majors already assigned:
     0-3, 7-9, 11-63, 65-99, 101-113, 120-127, 199, 201, 240-255
@@ -195,14 +152,11 @@
 */
 static struct major_list block_major_list =
 {SPIN_LOCK_UNLOCKED,
-    {0xfffffb8f,  /*  Majors 0   to 31   */
-     0xffffffff,  /*  Majors 32  to 63   */
-     0xfffffffe,  /*  Majors 64  to 95   */
-     0xff03ffef,  /*  Majors 96  to 127  */
-     0x00000000,  /*  Majors 128 to 159  */
-     0x00000000,  /*  Majors 160 to 191  */
-     0x00000280,  /*  Majors 192 to 223  */
-     0xffff0000}  /*  Majors 224 to 255  */
+    {INITIALISER64 (0xfffffb8f, 0xffffffff),  /*  Majors 0-31,    32-63    */
+     INITIALISER64 (0xfffffffe, 0xff03ffef),  /*  Majors 64-95,   96-127   */
+     INITIALISER64 (0x00000000, 0x00000000),  /*  Majors 128-159, 160-191  */
+     INITIALISER64 (0x00000280, 0xffff0000),  /*  Majors 192-223, 224-255  */
+    }
 };
 
 /*  Char majors already assigned:
@@ -211,14 +165,11 @@
 */
 static struct major_list char_major_list =
 {SPIN_LOCK_UNLOCKED,
-    {0xfffffeff,  /*  Majors 0   to 31   */
-     0xffffffff,  /*  Majors 32  to 63   */
-     0xffffffff,  /*  Majors 64  to 95   */
-     0xffffffff,  /*  Majors 96  to 127  */
-     0x7cffffff,  /*  Majors 128 to 159  */
-     0xffffffff,  /*  Majors 160 to 191  */
-     0x3f0fffff,  /*  Majors 192 to 223  */
-     0xffff007f}  /*  Majors 224 to 255  */
+    {INITIALISER64 (0xfffffeff, 0xffffffff),  /*  Majors 0-31,    32-63    */
+     INITIALISER64 (0xffffffff, 0xffffffff),  /*  Majors 64-95,   96-127   */
+     INITIALISER64 (0x7cffffff, 0xffffffff),  /*  Majors 128-159, 160-191  */
+     INITIALISER64 (0x3f0fffff, 0xffff007f),  /*  Majors 192-223, 224-255  */
+    }
 };
 
 
@@ -263,9 +214,7 @@
     spin_lock (&list->lock);
     was_set = __test_and_clear_bit (major, list->bits);
     spin_unlock (&list->lock);
-    if (!was_set)
-	printk (KERN_ERR __FUNCTION__ "(): major %d was already free\n",
-		major);
+    if (!was_set) PRINTK ("(): major %d was already free\n", major);
 }   /*  End Function devfs_dealloc_major  */
 EXPORT_SYMBOL(devfs_dealloc_major);
 
@@ -273,7 +222,7 @@
 struct minor_list
 {
     int major;
-    __u32 bits[8];
+    unsigned long bits[256 / BITS_PER_LONG];
     struct minor_list *next;
 };
 
@@ -328,7 +277,7 @@
 	if (minor >= 256) continue;
 	__set_bit (minor, entry->bits);
 	up (semaphore);
-	return MKDEV (entry->major, minor);
+	return mk_kdev (entry->major, minor);
     }
     /*  Need to allocate a new major  */
     if ( ( entry = kmalloc (sizeof *entry, GFP_KERNEL) ) == NULL )
@@ -350,7 +299,7 @@
     else list->last->next = entry;
     list->last = entry;
     up (semaphore);
-    return MKDEV (entry->major, 0);
+    return mk_kdev (entry->major, 0);
 }   /*  End Function devfs_alloc_devnum  */
 EXPORT_SYMBOL(devfs_alloc_devnum);
 
@@ -370,7 +319,7 @@
     struct device_list *list;
     struct minor_list *entry;
 
-    if (devnum == NODEV) return;
+    if ( kdev_none (devnum) ) return;
     if (type == DEVFS_SPECIAL_CHR)
     {
 	semaphore = &char_semaphore;
@@ -381,8 +330,8 @@
 	semaphore = &block_semaphore;
 	list = &block_list;
     }
-    major = MAJOR (devnum);
-    minor = MINOR (devnum);
+    major = major (devnum);
+    minor = minor (devnum);
     down (semaphore);
     for (entry = list->first; entry != NULL; entry = entry->next)
     {
@@ -393,12 +342,11 @@
 	if (was_set) list->none_free = 0;
 	up (semaphore);
 	if (!was_set)
-	    printk ( KERN_ERR __FUNCTION__ "(): device %s was already free\n",
-		     kdevname (devnum) );
+	    PRINTK ( "(): device %s was already free\n", kdevname (devnum) );
 	return;
     }
     up (semaphore);
-    printk ( KERN_ERR __FUNCTION__ "(): major for %s not previously allocated\n",
+    PRINTK ( "(): major for %s not previously allocated\n",
 	     kdevname (devnum) );
 }   /*  End Function devfs_dealloc_devnum  */
 EXPORT_SYMBOL(devfs_dealloc_devnum);
@@ -416,7 +364,6 @@
 {
     int number;
     unsigned int length;
-    __u32 *bits;
 
     /*  Get around stupid lack of semaphore initialiser  */
     spin_lock (&space->init_lock);
@@ -429,6 +376,8 @@
     down (&space->semaphore);
     if (space->num_free < 1)
     {
+	void *bits;
+
 	if (space->length < 16) length = 16;
 	else length = space->length << 1;
 	if ( ( bits = vmalloc (length) ) == NULL )
@@ -472,8 +421,6 @@
     was_set = __test_and_clear_bit (number, space->bits);
     if (was_set) ++space->num_free;
     up (&space->semaphore);
-    if (!was_set)
-	printk (KERN_ERR __FUNCTION__ "(): number %d was already free\n",
-		number);
+    if (!was_set) PRINTK ("(): number %d was already free\n", number);
 }   /*  End Function devfs_dealloc_unique_number  */
 EXPORT_SYMBOL(devfs_dealloc_unique_number);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/dnotify.c linux/fs/dnotify.c
--- linux.orig/fs/dnotify.c	2000-11-08 07:27:57.000000000 +0000
+++ linux/fs/dnotify.c	2002-07-20 01:08:31.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Directory notifications for Linux.
  *
- * Copyright (C) 2000 Stephen Rothwell
+ * Copyright (C) 2000,2001,2002 Stephen Rothwell
  *
  * 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
@@ -38,59 +38,74 @@
 	inode->i_dnotify_mask = new_mask;
 }
 
+void dnotify_flush(struct file *filp, fl_owner_t id)
+{
+	struct dnotify_struct *dn;
+	struct dnotify_struct **prev;
+	struct inode *inode;
+
+	inode = filp->f_dentry->d_inode;
+	if (!S_ISDIR(inode->i_mode))
+		return;
+	write_lock(&dn_lock);
+	prev = &inode->i_dnotify;
+	while ((dn = *prev) != NULL) {
+		if ((dn->dn_owner == id) && (dn->dn_filp == filp)) {
+			*prev = dn->dn_next;
+			redo_inode_mask(inode);
+			kmem_cache_free(dn_cache, dn);
+			break;
+		}
+		prev = &dn->dn_next;
+	}
+	write_unlock(&dn_lock);
+}
+
 int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
 {
-	struct dnotify_struct *dn = NULL;
+	struct dnotify_struct *dn;
 	struct dnotify_struct *odn;
 	struct dnotify_struct **prev;
 	struct inode *inode;
-	int turning_off = (arg & ~DN_MULTISHOT) == 0;
+	fl_owner_t id = current->files;
 
-	if (!turning_off && !dir_notify_enable)
+	if ((arg & ~DN_MULTISHOT) == 0) {
+		dnotify_flush(filp, id);
+		return 0;
+	}
+	if (!dir_notify_enable)
 		return -EINVAL;
 	inode = filp->f_dentry->d_inode;
 	if (!S_ISDIR(inode->i_mode))
 		return -ENOTDIR;
-	if (!turning_off) {
-		dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL);
-		if (dn == NULL)
-			return -ENOMEM;
-	}
+	dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL);
+	if (dn == NULL)
+		return -ENOMEM;
 	write_lock(&dn_lock);
 	prev = &inode->i_dnotify;
-	for (odn = *prev; odn != NULL; prev = &odn->dn_next, odn = *prev)
-		if (odn->dn_filp == filp)
-			break;
-	if (odn != NULL) {
-		if (turning_off) {
-			*prev = odn->dn_next;
-			redo_inode_mask(inode);
-			dn = odn;
-			goto out_free;
+	while ((odn = *prev) != NULL) {
+		if ((odn->dn_owner == id) && (odn->dn_filp == filp)) {
+			odn->dn_fd = fd;
+			odn->dn_mask |= arg;
+			inode->i_dnotify_mask |= arg & ~DN_MULTISHOT;
+			kmem_cache_free(dn_cache, dn);
+			goto out;
 		}
-		odn->dn_fd = fd;
-		odn->dn_mask |= arg;
-		inode->i_dnotify_mask |= arg & ~DN_MULTISHOT;
-		goto out_free;
+		prev = &odn->dn_next;
 	}
-	if (turning_off)
-		goto out;
 	filp->f_owner.pid = current->pid;
 	filp->f_owner.uid = current->uid;
 	filp->f_owner.euid = current->euid;
-	dn->dn_magic = DNOTIFY_MAGIC;
 	dn->dn_mask = arg;
 	dn->dn_fd = fd;
 	dn->dn_filp = filp;
+	dn->dn_owner = id;
 	inode->i_dnotify_mask |= arg & ~DN_MULTISHOT;
 	dn->dn_next = inode->i_dnotify;
 	inode->i_dnotify = dn;
 out:
 	write_unlock(&dn_lock);
 	return 0;
-out_free:
-	kmem_cache_free(dn_cache, dn);
-	goto out;
 }
 
 void __inode_dir_notify(struct inode *inode, unsigned long event)
@@ -103,11 +118,6 @@
 	write_lock(&dn_lock);
 	prev = &inode->i_dnotify;
 	while ((dn = *prev) != NULL) {
-		if (dn->dn_magic != DNOTIFY_MAGIC) {
-		        printk(KERN_ERR "__inode_dir_notify: bad magic "
-				"number in dnotify_struct!\n");
-		        goto out;
-		}
 		if ((dn->dn_mask & event) == 0) {
 			prev = &dn->dn_next;
 			continue;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/dquot.c linux/fs/dquot.c
--- linux.orig/fs/dquot.c	2001-11-22 18:38:31.000000000 +0000
+++ linux/fs/dquot.c	2002-07-20 01:08:26.000000000 +0000
@@ -413,8 +413,7 @@
 	lock_kernel();
 	prune_dqcache(nr_free_dquots / (priority + 1));
 	unlock_kernel();
-	kmem_cache_shrink(dquot_cachep);
-	return 0;
+	return kmem_cache_shrink(dquot_cachep);
 }
 
 /* NOTE: If you change this function please check whether dqput_blocks() works right... */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/exec.c linux/fs/exec.c
--- linux.orig/fs/exec.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/exec.c	2002-07-20 01:08:33.000000000 +0000
@@ -951,8 +951,7 @@
 	if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
 		goto fail;
 
-	memcpy(corename,"core.", 5);
-	corename[4] = '\0';
+	memcpy(corename,"core", 5); /* include trailing \0 */
  	if (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)
  		sprintf(&corename[4], ".%d", current->pid);
 	file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW, 0600);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/ext2/inode.c linux/fs/ext2/inode.c
--- linux.orig/fs/ext2/inode.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/ext2/inode.c	2002-07-20 01:08:24.000000000 +0000
@@ -407,10 +407,10 @@
 		mark_buffer_uptodate(bh, 1);
 		unlock_buffer(bh);
 		mark_buffer_dirty_inode(bh, inode);
-		if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {
-			ll_rw_block (WRITE, 1, &bh);
-			wait_on_buffer (bh);
-		}
+		/* We used to sync bh here if IS_SYNC(inode).
+		 * But we now rely upon generic_osync_inode()
+		 * and b_inode_buffers
+		 */
 		parent = nr;
 	}
 	if (n == num)
@@ -469,18 +469,10 @@
 	inode->i_ctime = CURRENT_TIME;
 
 	/* had we spliced it onto indirect block? */
-	if (where->bh) {
+	if (where->bh)
 		mark_buffer_dirty_inode(where->bh, inode);
-		if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {
-			ll_rw_block (WRITE, 1, &where->bh);
-			wait_on_buffer(where->bh);
-		}
-	}
 
-	if (IS_SYNC(inode) || inode->u.ext2_i.i_osync)
-		ext2_sync_inode (inode);
-	else
-		mark_inode_dirty(inode);
+	mark_inode_dirty(inode);
 	return 0;
 
 changed:
@@ -837,10 +829,6 @@
 				   (u32*)partial->bh->b_data + addr_per_block,
 				   (chain+n-1) - partial);
 		mark_buffer_dirty_inode(partial->bh, inode);
-		if (IS_SYNC(inode)) {
-			ll_rw_block (WRITE, 1, &partial->bh);
-			wait_on_buffer (partial->bh);
-		}
 		brelse (partial->bh);
 		partial--;
 	}
@@ -872,10 +860,12 @@
 			;
 	}
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	if (IS_SYNC(inode))
+	if (IS_SYNC(inode)) {
+		fsync_inode_buffers(inode);
 		ext2_sync_inode (inode);
-	else
+	} else {
 		mark_inode_dirty(inode);
+	}
 }
 
 void ext2_read_inode (struct inode * inode)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/ext3/balloc.c linux/fs/ext3/balloc.c
--- linux.orig/fs/ext3/balloc.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/ext3/balloc.c	2002-07-20 01:08:24.000000000 +0000
@@ -542,6 +542,7 @@
 	int i, j, k, tmp, alloctmp;
 	int bitmap_nr;
 	int fatal = 0, err;
+	int performed_allocation = 0;
 	struct super_block * sb;
 	struct ext3_group_desc * gdp;
 	struct ext3_super_block * es;
@@ -644,8 +645,7 @@
 	}
 
 	/* No space left on the device */
-	unlock_super (sb);
-	return 0;
+	goto out;
 
 search_back:
 	/* 
@@ -694,6 +694,7 @@
 	J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data));
 	BUFFER_TRACE(bh, "setting bitmap bit");
 	ext3_set_bit(j, bh->b_data);
+	performed_allocation = 1;
 
 #ifdef CONFIG_JBD_DEBUG
 	{
@@ -815,6 +816,11 @@
 		ext3_std_error(sb, fatal);
 	}
 	unlock_super (sb);
+	/*
+	 * Undo the block allocation
+	 */
+	if (!performed_allocation)
+		DQUOT_FREE_BLOCK(inode, 1);
 	return 0;
 	
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/ext3/inode.c linux/fs/ext3/inode.c
--- linux.orig/fs/ext3/inode.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/ext3/inode.c	2002-07-20 01:08:38.000000000 +0000
@@ -581,8 +581,6 @@
 			
 			parent = nr;
 		}
-		if (IS_SYNC(inode))
-			handle->h_sync = 1;
 	}
 	if (n == num)
 		return 0;
@@ -1015,8 +1013,8 @@
 			      unsigned from, unsigned to)
 {
 	struct inode *inode = page->mapping->host;
-	handle_t *handle = ext3_journal_current_handle();
 	int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
+	handle_t *handle;
 
 	lock_kernel();
 	handle = ext3_journal_start(inode, needed_blocks);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/fat/inode.c linux/fs/fat/inode.c
--- linux.orig/fs/fat/inode.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/fat/inode.c	2002-07-20 01:08:35.000000000 +0000
@@ -434,12 +434,13 @@
 	struct dentry *result;
 
 	if (fhtype != 3)
-		return NULL;
+		return ERR_PTR(-ESTALE);
 	if (len < 5)
-		return NULL;
+		return ERR_PTR(-ESTALE);
+	/* We cannot find the parent,
+	   It better just *be* there */
 	if (parent)
-		return NULL; /* We cannot find the parent,
-				It better just *be* there */
+		return ERR_PTR(-ESTALE);
 
 	inode = iget(sb, fh[0]);
 	if (!inode || is_bad_inode(inode) ||
@@ -501,6 +502,7 @@
 		iput(inode);
 		return ERR_PTR(-ENOMEM);
 	}
+	result->d_op = sb->s_root->d_op;
 	result->d_flags |= DCACHE_NFSD_DISCONNECTED;
 	return result;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/fcntl.c linux/fs/fcntl.c
--- linux.orig/fs/fcntl.c	2001-09-17 20:16:30.000000000 +0000
+++ linux/fs/fcntl.c	2002-07-20 01:08:25.000000000 +0000
@@ -66,6 +66,10 @@
 
 	write_lock(&files->file_lock);
 	
+	error = -EINVAL;
+	if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+		goto out;
+
 repeat:
 	/*
 	 * Someone might have closed fd's in the range
@@ -409,7 +413,7 @@
 			   back to SIGIO in that case. --sct */
 			si.si_signo = fown->signum;
 			si.si_errno = 0;
-		        si.si_code  = reason & ~__SI_MASK;
+		        si.si_code  = reason;
 			/* Make sure we are called with one of the POLL_*
 			   reasons, otherwise we could leak kernel stack into
 			   userspace.  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/file.c linux/fs/file.c
--- linux.orig/fs/file.c	2001-02-09 19:29:44.000000000 +0000
+++ linux/fs/file.c	2002-07-20 01:08:25.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  linux/fs/open.c
+ *  linux/fs/file.c
  *
  *  Copyright (C) 1998-1999, Stephen Tweedie and Bill Hawes
  *
@@ -36,7 +36,8 @@
 	int size = num * sizeof(struct file *);
 
 	if (!array) {
-		printk (KERN_ERR __FUNCTION__ "array = 0 (num = %d)\n", num);
+		printk(KERN_ERR "%s array = 0 (num = %d)\n",
+				__FUNCTION__, num);
 		return;
 	}
 
@@ -145,7 +146,8 @@
 	int size = num / 8;
 
 	if (!array) {
-		printk (KERN_ERR __FUNCTION__ "array = 0 (num = %d)\n", num);
+		printk(KERN_ERR "%s array = 0 (num = %d)\n",
+				__FUNCTION__, num);
 		return;
 	}
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/filesystems.c linux/fs/filesystems.c
--- linux.orig/fs/filesystems.c	2001-04-18 06:23:12.000000000 +0000
+++ linux/fs/filesystems.c	2002-07-20 01:08:29.000000000 +0000
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
- *  table of configured filesystems
+ *  nfsservctl system-call when nfsd is not compiled in.
  */
 
 #include <linux/config.h>
@@ -13,28 +13,28 @@
 #include <linux/kmod.h>
 #include <linux/nfsd/interface.h>
 
-#if defined(CONFIG_NFSD_MODULE)
-struct nfsd_linkage *nfsd_linkage = NULL;
+#if ! defined(CONFIG_NFSD)
+struct nfsd_linkage *nfsd_linkage;
 
 long
 asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp)
 {
 	int ret = -ENOSYS;
 	
+#if defined(CONFIG_MODULES)
 	lock_kernel();
 
 	if (nfsd_linkage ||
-	    (request_module ("nfsd") == 0 && nfsd_linkage))
+	    (request_module ("nfsd") == 0 && nfsd_linkage)) {
+		__MOD_INC_USE_COUNT(nfsd_linkage->owner);
+		unlock_kernel();
 		ret = nfsd_linkage->do_nfsservctl(cmd, argp, resp);
-
-	unlock_kernel();
+		__MOD_DEC_USE_COUNT(nfsd_linkage->owner);
+	} else
+		unlock_kernel();
+#endif
 	return ret;
 }
 EXPORT_SYMBOL(nfsd_linkage);
 
-#elif ! defined (CONFIG_NFSD)
-asmlinkage int sys_nfsservctl(int cmd, void *argp, void *resp)
-{
-	return -ENOSYS;
-}
 #endif /* CONFIG_NFSD */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/freevxfs/vxfs_kcompat.h linux/fs/freevxfs/vxfs_kcompat.h
--- linux.orig/fs/freevxfs/vxfs_kcompat.h	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/freevxfs/vxfs_kcompat.h	2002-07-20 01:08:29.000000000 +0000
@@ -17,27 +17,5 @@
 	bh->b_blocknr = block;
 }
 
-/* From fs/block_dev.c (Linux 2.5.2-pre2)  */
-static inline int sb_set_blocksize(struct super_block *sb, int size)
-{
-	int bits;
-	if (set_blocksize(sb->s_dev, size) < 0)
-		return 0;
-	sb->s_blocksize = size;
-	for (bits = 9, size >>= 9; size >>= 1; bits++)
-		;
-	sb->s_blocksize_bits = bits;
-	return sb->s_blocksize;
-}
-
-/* Dito.  */
-static inline int sb_min_blocksize(struct super_block *sb, int size)
-{
-	int minsize = get_hardsect_size(sb->s_dev);
-	if (size < minsize)
-		size = minsize;
-	return sb_set_blocksize(sb, size);
-}
-
 #endif /* Kernel 2.4 */
 #endif /* _VXFS_KCOMPAT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/hfs/super.c linux/fs/hfs/super.c
--- linux.orig/fs/hfs/super.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/hfs/super.c	2002-07-20 01:08:32.000000000 +0000
@@ -32,6 +32,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
+MODULE_LICENSE("GPL");
+
 /*================ Forward declarations ================*/
 
 static void hfs_read_inode(struct inode *);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/hpfs/ea.c linux/fs/hpfs/ea.c
--- linux.orig/fs/hpfs/ea.c	2000-09-05 21:07:29.000000000 +0000
+++ linux/fs/hpfs/ea.c	2002-07-20 01:08:26.000000000 +0000
@@ -9,8 +9,8 @@
 #include <linux/string.h>
 #include "hpfs_fn.h"
 
-/* Remove external extended attributes. ano specifies wheter a is a 
-   direct sector where eas start or an anode */
+/* Remove external extended attributes. ano specifies whether a is a 
+   direct sector where eas starts or an anode */
 
 void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/hpfs/hpfs_fn.h linux/fs/hpfs/hpfs_fn.h
--- linux.orig/fs/hpfs/hpfs_fn.h	2001-02-09 19:29:44.000000000 +0000
+++ linux/fs/hpfs/hpfs_fn.h	2002-07-20 01:08:38.000000000 +0000
@@ -156,9 +156,11 @@
 
 extern inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src)
 {
-	int a = dst->down;
-	int n = dst->not_8x3;
+	int a;
+	int n;
 	if (!dst || !src) return;
+	a = dst->down;
+	n = dst->not_8x3;
 	memcpy((char *)dst + 2, (char *)src + 2, 28);
 	dst->down = a;
 	dst->not_8x3 = n;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/hpfs/super.c linux/fs/hpfs/super.c
--- linux.orig/fs/hpfs/super.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/hpfs/super.c	2002-07-20 01:08:38.000000000 +0000
@@ -410,6 +410,8 @@
 	/*s->s_hpfs_mounting = 1;*/
 	dev = s->s_dev;
 	set_blocksize(dev, 512);
+	s->s_blocksize = 512;
+	s->s_blocksize_bits = 9;
 	s->s_hpfs_fs_size = -1;
 	if (!(bootblock = hpfs_map_sector(s, 0, &bh0, 0))) goto bail1;
 	if (!(superblock = hpfs_map_sector(s, 16, &bh1, 1))) goto bail2;
@@ -436,8 +438,6 @@
 
 	/* Fill superblock stuff */
 	s->s_magic = HPFS_SUPER_MAGIC;
-	s->s_blocksize = 512;
-	s->s_blocksize_bits = 9;
 	s->s_op = &hpfs_sops;
 
 	s->s_hpfs_root = superblock->root;
@@ -584,3 +584,4 @@
 
 module_init(init_hpfs_fs)
 module_exit(exit_hpfs_fs)
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/inode.c linux/fs/inode.c
--- linux.orig/fs/inode.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/inode.c	2002-07-20 01:08:35.000000000 +0000
@@ -247,15 +247,15 @@
 
 static inline void sync_one(struct inode *inode, int sync)
 {
-	if (inode->i_state & I_LOCK) {
+	while (inode->i_state & I_LOCK) {
 		__iget(inode);
 		spin_unlock(&inode_lock);
 		__wait_on_inode(inode);
 		iput(inode);
 		spin_lock(&inode_lock);
-	} else {
-		__sync_one(inode, sync);
 	}
+
+	__sync_one(inode, sync);
 }
 
 static inline void sync_list(struct list_head *head)
@@ -725,8 +725,7 @@
 	count = inodes_stat.nr_unused / priority;
 
 	prune_icache(count);
-	kmem_cache_shrink(inode_cachep);
-	return 0;
+	return kmem_cache_shrink(inode_cachep);
 }
 
 /*
@@ -1152,7 +1151,7 @@
 			__get_free_pages(GFP_ATOMIC, order);
 	} while (inode_hashtable == NULL && --order >= 0);
 
-	printk("Inode-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+	printk(KERN_INFO "Inode cache hash table entries: %d (order: %ld, %ld bytes)\n",
 			nr_hash, order, (PAGE_SIZE << order));
 
 	if (!inode_hashtable)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/intermezzo/ext_attr.c linux/fs/intermezzo/ext_attr.c
--- linux.orig/fs/intermezzo/ext_attr.c	2001-11-11 18:20:21.000000000 +0000
+++ linux/fs/intermezzo/ext_attr.c	2002-07-20 01:08:24.000000000 +0000
@@ -106,9 +106,8 @@
                         printk("InterMezzo: out of memory!!!\n");
                         return -ENOMEM;
                 }
-                error = copy_from_user(buf, buffer, buffer_len);
-                if (error) 
-                        return error;
+                if (copy_from_user(buf, buffer, buffer_len))
+                        return -EFAULT;
             } else 
                 buf = buffer;
         } else
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/intermezzo/kml.c linux/fs/intermezzo/kml.c
--- linux.orig/fs/intermezzo/kml.c	2001-11-11 18:20:21.000000000 +0000
+++ linux/fs/intermezzo/kml.c	2002-07-20 01:08:21.000000000 +0000
@@ -31,10 +31,9 @@
 
         ENTRY;
         /* allocate buffer & copy it to kernel space */
-        error = copy_from_user(&input, (char *)arg, sizeof(input));
-        if ( error ) {
+        if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                 EXIT;
-                return error;
+                return -EFAULT;
         }
 
         if (input.reclen > kml_fsdata->kml_maxsize)
@@ -45,11 +44,10 @@
                 EXIT;
                 return -ENOMEM;
         }
-        error = copy_from_user(path, input.volname, input.namelen);
-        if ( error ) {
+        if (copy_from_user(path, input.volname, input.namelen)) {
                 PRESTO_FREE(path, input.namelen + 1);
                 EXIT;
-                return error;
+                return -EFAULT;
         }
         path[input.namelen] = '\0';
         fset = kml_getfset (path);
@@ -57,10 +55,9 @@
 
         kml_fsdata = FSET_GET_KMLDATA(fset);
         /* read the buf from user memory here */
-        error = copy_from_user(kml_fsdata->kml_buf, input.recbuf, input.reclen);
-        if ( error ) {
+        if (copy_from_user(kml_fsdata->kml_buf, input.recbuf, input.reclen)) {
                 EXIT;
-                return error;
+                return -EFAULT;
         }
         kml_fsdata->kml_len = input.reclen;
 
@@ -94,21 +91,19 @@
         struct presto_file_set *fset;
 
         ENTRY;
-        error = copy_from_user(&input, (char *)arg, sizeof(input));
-        if ( error ) {
+        if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                 EXIT;
-                return error;
+                return -EFAULT;
         }
         PRESTO_ALLOC(path, char *, input.namelen + 1);
         if ( !path ) {
                 EXIT;
                 return -ENOMEM;
         }
-        error = copy_from_user(path, input.volname, input.namelen);
-        if ( error ) {
+        if (copy_from_user(path, input.volname, input.namelen)) {
                 PRESTO_FREE(path, input.namelen + 1);
                 EXIT;
-                return error;
+                return -EFAULT;
         }
         path[input.namelen] = '\0';
         fset = kml_getfset (path);
@@ -138,7 +133,8 @@
                                 strlen (close->path) + 1, input.pathlen);
                         error = -ENOMEM;
                 }
-                copy_to_user((char *)arg, &input, sizeof (input));
+                if (copy_to_user((char *)arg, &input, sizeof (input)))
+			return -EFAULT;
         }
         return error;
 }
@@ -161,10 +157,9 @@
         char *path;
 
         ENTRY;
-        error = copy_from_user(&input, (char *)arg, sizeof(input));
-        if ( error ) {
+        if (copy_from_user(&input, (char *)arg, sizeof(input))) { 
                EXIT;
-               return error;
+               return -EFAULT;
         }
 
         PRESTO_ALLOC(path, char *, input.namelen + 1);
@@ -172,11 +167,11 @@
                 EXIT;
                 return -ENOMEM;
         }
-        error = copy_from_user(path, input.volname, input.namelen);
+        if (copy_from_user(path, input.volname, input.namelen)) {
         if ( error ) {
                 PRESTO_FREE(path, input.namelen + 1);
                 EXIT;
-                return error;
+                return -EFAULT;
         }
         path[input.namelen] = '\0';
         fset = kml_getfset (path);
@@ -193,7 +188,8 @@
 #if 0
         input.newpos = kml_upc->newpos;
         input.count = kml_upc->count;
-        copy_to_user((char *)arg, &input, sizeof (input));
+        if (copy_to_user((char *)arg, &input, sizeof (input)))
+		return -EFAULT;
 #endif
         return error;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/intermezzo/psdev.c linux/fs/intermezzo/psdev.c
--- linux.orig/fs/intermezzo/psdev.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/intermezzo/psdev.c	2002-07-20 01:08:32.000000000 +0000
@@ -46,6 +46,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <asm/io.h>
+#include <asm/ioctls.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/poll.h>
@@ -133,7 +134,6 @@
         struct upc_req *tmp;
         struct list_head *lh;
         struct lento_down_hdr hdr;
-        int error;
 
         if ( ! (upccom = presto_psdev_f2u(file)) ) {
                 kdev_t dev = file->f_dentry->d_inode->i_rdev;
@@ -147,9 +147,8 @@
                 return -EINVAL;
         }
 
-        error = copy_from_user(&hdr, buf, sizeof(hdr));
-        if ( error )
-                return error;
+        if (copy_from_user(&hdr, buf, sizeof(hdr)))
+                return -EFAULT;
 
         CDEBUG(D_PSDEV, "(process,opc,uniq)=(%d,%d,%d)\n",
                current->pid, hdr.opcode, hdr.unique);
@@ -181,9 +180,8 @@
                        req->rq_bufsize, count, hdr.opcode, hdr.unique);
                 count = req->rq_bufsize; /* don't have more space! */
         }
-        error = copy_from_user(req->rq_data, buf, count);
-        if ( error )
-                return error;
+        if (copy_from_user(req->rq_data, buf, count))
+                return -EFAULT;
 
         /* adjust outsize: good upcalls can be aware of this */
         req->rq_rep_size = count;
@@ -276,16 +274,12 @@
                 struct readmount readmount;
                 struct readmount *user_readmount = (struct readmount *) arg;
                 char * tmp;
-                int error;
+                int error = 0;
 
-                error = copy_from_user(&readmount, (void *)arg,
-                                       sizeof(readmount));
-                if ( error )  {
-                        printk("psdev: can't copy %Zd bytes from %p to %p\n",
-                                sizeof(readmount), (struct readmount *) arg,
-                                &readmount);
+                if (copy_from_user(&readmount, (void *)arg, sizeof(readmount)))
+                {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 len = readmount.io_len;
@@ -305,15 +299,16 @@
                  * I mean, let's let the compiler do a little work ...
                  * gcc suggested the extra ()
                  */
-                error = copy_to_user(readmount.io_string, tmp, outlen);
-                if ( error ) {
+                if (copy_to_user(readmount.io_string, tmp, outlen)) {
                         CDEBUG(D_PSDEV, "Copy_to_user string 0x%p failed\n",
                                readmount.io_string);
+			error = -EFAULT;
                 }
-                if ((!error) && (error = copy_to_user(&(user_readmount->io_len),
-                                                      &outlen, sizeof(int))) ) {
+                if (!error && copy_to_user(&(user_readmount->io_len),
+                                           &outlen, sizeof(int))) {
                         CDEBUG(D_PSDEV, "Copy_to_user len @0x%p failed\n",
                                &(user_readmount->io_len));
+			error = -EFAULT;
                 }
 
                 PRESTO_FREE(tmp, len);
@@ -358,10 +353,9 @@
                         int   path_len;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
@@ -369,11 +363,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(path, input.path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(path, input.path, input.path_len)) {
                         PRESTO_FREE(path, input.path_len + 1);
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 path[input.path_len] = '\0';
                 CDEBUG(D_PSDEV, "clear_fsetroot: path %s\n", path);
@@ -399,10 +392,9 @@
                         int   path_len;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
@@ -410,11 +402,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(path, input.path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(path, input.path, input.path_len)) {
                         PRESTO_FREE(path, input.path_len + 1);
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 path[input.path_len] = '\0';
                 CDEBUG(D_PSDEV, "clear_all_fsetroot: path %s\n", path);
@@ -438,10 +429,9 @@
                         int   path_len;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
@@ -449,11 +439,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(path, input.path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(path, input.path, input.path_len)) {
                         PRESTO_FREE(path, input.path_len + 1);
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 path[input.path_len] = '\0';
                 CDEBUG(D_PSDEV, "get_kmlsize: len %d path %s\n", 
@@ -472,7 +461,9 @@
                 CDEBUG(D_PSDEV, "get_kmlsize: size = %Zd\n", size);
 
                 EXIT;
-                return copy_to_user((char *)arg, &input, sizeof(input));
+                if (copy_to_user((char *)arg, &input, sizeof(input)))
+			return -EFAULT;
+		return 0;
         }
 
         case PRESTO_GET_RECNO: {
@@ -486,10 +477,9 @@
                         int   path_len;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
@@ -497,11 +487,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(path, input.path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(path, input.path, input.path_len)) {
                         PRESTO_FREE(path, input.path_len + 1);
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 path[input.path_len] = '\0';
                 CDEBUG(D_PSDEV, "get_recno: len %d path %s\n", 
@@ -520,7 +509,9 @@
                 CDEBUG(D_PSDEV, "get_recno: recno = %d\n", (int) recno);
 
                 EXIT;
-                return copy_to_user((char *)arg, &input, sizeof(input));
+                if (copy_to_user((char *)arg, &input, sizeof(input)))
+			return -EFAULT;
+		return 0;
         }
 
         case PRESTO_SET_FSETROOT: {
@@ -541,10 +532,9 @@
                         int   flags;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 PRESTO_ALLOC(path, char *, input.path_len + 1);
@@ -552,9 +542,9 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(path, input.path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(path, input.path, input.path_len)) {
                         EXIT;
+			error = -EFAULT;
                         goto exit_free_path;
                 }
                 path[input.path_len] = '\0';
@@ -565,9 +555,9 @@
                         EXIT;
                         goto exit_free_path;
                 }
-                error = copy_from_user(fsetname, input.name, input.name_len);
-                if ( error ) {
+                if (copy_from_user(fsetname, input.name, input.name_len)) {
                         EXIT;
+			error = -EFAULT;
                         goto exit_free_fsetname;
                 }
                 fsetname[input.name_len] = '\0';
@@ -616,15 +606,14 @@
                 int dogetopt(int, struct psdev_opt *);
                 int minor = 0;
                 struct psdev_opt kopt;
+                int error = 0;
                 struct psdev_opt *user_opt = (struct psdev_opt *) arg;
-                int error;
 
-                error = copy_from_user(&kopt, (void *)arg, sizeof(kopt));
-                if ( error )  {
+                if (copy_from_user(&kopt, (void *)arg, sizeof(kopt))) {
                         printk("psdev: can't copyin %Zd bytes from %p to %p\n",
                                sizeof(kopt), (struct kopt *) arg, &kopt);
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 minor = MINOR(dev);
                 if (cmd == PRESTO_SETOPT)
@@ -648,12 +637,11 @@
                         return error;
                 }
 
-                error = copy_to_user(user_opt, &kopt, sizeof(kopt));
-                if ( error ) {
+                if (copy_to_user(user_opt, &kopt, sizeof(kopt))) {
                         CDEBUG(D_PSDEV, "Copy_to_user opt 0x%p failed\n",
                                user_opt);
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 CDEBUG(D_PSDEV, "dosetopt minor %d, opt %d, val %d return %d\n",
                          minor, kopt.optname, kopt.optval, error);
@@ -666,10 +654,9 @@
                 struct lento_input_attr input;
                 struct iattr iattr;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 iattr.ia_valid = input.valid;
                 iattr.ia_mode  = (umode_t)input.mode;
@@ -690,10 +677,9 @@
                 int error;
                 struct lento_input_mode input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 error = lento_create(input.name, input.mode, &input.info);
@@ -705,10 +691,9 @@
                 int error;
                 struct lento_input_old_new input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 error = lento_link(input.oldname, input.newname, &input.info);
@@ -720,10 +705,9 @@
                 int error;
                 struct lento_input input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 error = lento_unlink(input.name, &input.info);
@@ -735,10 +719,9 @@
                 int error;
                 struct lento_input_old_new input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 error = lento_symlink(input.oldname, input.newname,&input.info);
@@ -750,10 +733,9 @@
                 int error;
                 struct lento_input_mode input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 error = lento_mkdir(input.name, input.mode, &input.info);
@@ -765,10 +747,9 @@
                 int error;
                 struct lento_input input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 error = lento_rmdir(input.name, &input.info);
@@ -780,10 +761,9 @@
                 int error;
                 struct lento_input_dev input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 error = lento_mknod(input.name, input.mode,
@@ -796,10 +776,9 @@
                 int error;
                 struct lento_input_old_new input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 error = lento_rename(input.oldname, input.newname, &input.info);
@@ -815,30 +794,27 @@
                 char *name;
                 char *buffer;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) { 
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                     EXIT;
-                    return error;
+                    return -EFAULT;
                 }
 
                 /* Now setup the input parameters */
                 PRESTO_ALLOC(name, char *, input.name_len+1);
                 /* We need null terminated strings for attr names */
                 name[input.name_len] = '\0';
-                error=copy_from_user(name, input.name, input.name_len);
-                if ( error ) { 
+                if (copy_from_user(name, input.name, input.name_len)) {
                     EXIT;
                     PRESTO_FREE(name,input.name_len+1);
-                    return error;
+                    return -EFAULT;
                 }
 
                 PRESTO_ALLOC(buffer, char *, input.buffer_len+1);
-                error=copy_from_user(buffer, input.buffer, input.buffer_len);
-                if ( error ) { 
+                if (copy_from_user(buffer, input.buffer, input.buffer_len)) {
                     EXIT;
                     PRESTO_FREE(name,input.name_len+1);
                     PRESTO_FREE(buffer,input.buffer_len+1);
-                    return error;
+                    return -EFAULT;
                 }
                 /* Make null terminated for easy printing */
                 buffer[input.buffer_len]='\0';
@@ -867,21 +843,19 @@
                 struct lento_input_ext_attr input;
                 char *name;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) { 
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                     EXIT;
-                    return error;
+                    return -EFAULT;
                 }
 
                 /* Now setup the input parameters */
                 PRESTO_ALLOC(name, char *, input.name_len+1);
                 /* We need null terminated strings for attr names */
                 name[input.name_len] = '\0';
-                error=copy_from_user(name, input.name, input.name_len);
-                if ( error ) { 
+                if (copy_from_user(name, input.name, input.name_len)) {
                     EXIT;
                     PRESTO_FREE(name,input.name_len+1);
-                    return error;
+                    return -EFAULT;
                 }
 
                 CDEBUG(D_PSDEV," delextattr params: name %s,"
@@ -903,12 +877,10 @@
 
         case PRESTO_VFS_IOPEN: {
                 struct lento_input_iopen input;
-                int error;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 input.fd = lento_iopen(input.name, (ino_t)input.ino,
@@ -919,17 +891,18 @@
                         return input.fd;
                 }
                 EXIT;
-                return copy_to_user((char *)arg, &input, sizeof(input));
+                if (copy_to_user((char *)arg, &input, sizeof(input)))
+			return -EFAULT;
+		return 0;
         }
 
         case PRESTO_VFS_CLOSE: {
                 int error;
                 struct lento_input_close input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
 
                 CDEBUG(D_PIOCTL, "lento_close file descriptor: %d\n", input.fd);
@@ -940,7 +913,6 @@
 
         case PRESTO_BACKFETCH_LML: {
                 char *user_path;
-                int error;
                 struct lml_arg {
                         char *path;
                         __u32 path_len;
@@ -950,10 +922,9 @@
                         struct presto_version remote_file_version;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 user_path = input.path;
 
@@ -962,11 +933,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(input.path, user_path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(input.path, user_path, input.path_len)) {
                         EXIT;
                         PRESTO_FREE(input.path, input.path_len + 1);
-                        return error;
+                        return -EFAULT;
                 }
                 input.path[input.path_len] = '\0';
 
@@ -983,7 +953,6 @@
 
         case PRESTO_CANCEL_LML: {
                 char *user_path;
-                int error;
                 struct lml_arg {
                         char *path;
                         __u64 lml_offset; 
@@ -994,10 +963,9 @@
                         struct lento_vfs_context info;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 user_path = input.path;
 
@@ -1006,11 +974,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(input.path, user_path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(input.path, user_path, input.path_len)) {
                         EXIT;
                         PRESTO_FREE(input.path, input.path_len + 1);
-                        return error;
+                        return -EFAULT;
                 }
                 input.path[input.path_len] = '\0';
 
@@ -1033,10 +1000,9 @@
                         __u32 path_len;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 user_path = input.path;
 
@@ -1045,11 +1011,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(input.path, user_path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(input.path, user_path, input.path_len)) {
                         EXIT;
                         PRESTO_FREE(input.path, input.path_len + 1);
-                        return error;
+                        return -EFAULT;
                 }
                 input.path[input.path_len] = '\0';
 
@@ -1062,7 +1027,6 @@
 
         case PRESTO_RESET_FSET: {
                 char *user_path;
-                int error;
                 struct lml_arg {
                         char *path;
                         __u32 path_len;
@@ -1070,10 +1034,9 @@
                         __u32 recno;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 user_path = input.path;
 
@@ -1082,11 +1045,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(input.path, user_path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(input.path, user_path, input.path_len)) {
                         EXIT;
                         PRESTO_FREE(input.path, input.path_len + 1);
-                        return error;
+                        return -EFAULT;
                 }
                 input.path[input.path_len] = '\0';
 
@@ -1109,10 +1071,9 @@
                         char *path;
                 } input;
 
-                error = copy_from_user(&input, (char *)arg, sizeof(input));
-                if ( error ) {
+                if (copy_from_user(&input, (char *)arg, sizeof(input))) {
                         EXIT;
-                        return error;
+                        return -EFAULT;
                 }
                 user_path = input.path;
 
@@ -1121,11 +1082,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(input.path, user_path, input.path_len);
-                if ( error ) {
+                if (copy_from_user(input.path, user_path, input.path_len)) {
                         EXIT;
                         PRESTO_FREE(input.path, input.path_len + 1);
-                        return error;
+                        return -EFAULT;
                 }
                 input.path[input.path_len] = '\0';
 
@@ -1188,7 +1148,9 @@
                 }
                 /* return the correct cookie to wait for */
                 input.mark_what = res;
-                return copy_to_user((char *)arg, &input, sizeof(input));
+                if (copy_to_user((char *)arg, &input, sizeof(input)))
+			return -EFAULT;
+		return 0;
         }
 
 #ifdef  CONFIG_KREINT
@@ -1209,11 +1171,10 @@
                         char *path;
                 } permit;
                 
-                error = copy_from_user(&permit, (char *)arg, sizeof(permit));
-                if ( error ) {
+                if (copy_from_user(&permit, (char *)arg, sizeof(permit))) {
                         EXIT;
-                        return error;
-                        }
+                        return -EFAULT;
+		}
                 user_path = permit.path;
                 
                 PRESTO_ALLOC(permit.path, char *, permit.path_len + 1);
@@ -1221,11 +1182,10 @@
                         EXIT;
                         return -ENOMEM;
                 }
-                error = copy_from_user(permit.path, user_path, permit.path_len);
-                if ( error ) {
+                if (copy_from_user(permit.path, user_path, permit.path_len)) {
                         EXIT;
                         PRESTO_FREE(permit.path, permit.path_len + 1);
-                        return error;
+                        return -EFAULT;
                 }
                 permit.path[permit.path_len] = '\0';
                 
@@ -1239,7 +1199,9 @@
                         return error;
                 }
                 /* return the correct cookie to wait for */
-                return copy_to_user((char *)arg, &permit, sizeof(permit));
+                if (copy_to_user((char *)arg, &permit, sizeof(permit)))
+			return -EFAULT;
+		return 0;
         }
         
         default:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/iobuf.c linux/fs/iobuf.c
--- linux.orig/fs/iobuf.c	2001-04-27 21:23:25.000000000 +0000
+++ linux/fs/iobuf.c	2002-07-20 01:08:39.000000000 +0000
@@ -24,10 +24,13 @@
 
 static void kiobuf_init(struct kiobuf *iobuf)
 {
-	memset(iobuf, 0, sizeof(*iobuf));
 	init_waitqueue_head(&iobuf->wait_queue);
 	iobuf->array_len = KIO_STATIC_PAGES;
-	iobuf->maplist   = iobuf->map_array;
+	iobuf->maplist = iobuf->map_array;
+	iobuf->nr_pages = 0;
+	iobuf->locked = 0;
+	atomic_set(&iobuf->io_count, 0);
+	iobuf->end_io = NULL;
 }
 
 int alloc_kiobuf_bhs(struct kiobuf * kiobuf)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jbd/journal.c linux/fs/jbd/journal.c
--- linux.orig/fs/jbd/journal.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/jbd/journal.c	2002-07-20 01:08:27.000000000 +0000
@@ -204,6 +204,7 @@
 
 	lock_kernel();
 	daemonize();
+	reparent_to_init();
 	spin_lock_irq(&current->sigmask_lock);
 	sigfillset(&current->blocked);
 	recalc_sigpending(current);
@@ -267,6 +268,7 @@
 
 	journal->j_task = NULL;
 	wake_up(&journal->j_wait_done_commit);
+	unlock_kernel();
 	jbd_debug(1, "Journal thread exiting.\n");
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/build.c linux/fs/jffs2/build.c
--- linux.orig/fs/jffs2/build.c	2001-09-14 21:04:07.000000000 +0000
+++ linux/fs/jffs2/build.c	2002-07-20 01:08:37.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: build.c,v 1.16 2001/03/15 15:38:23 dwmw2 Exp $
+ * $Id: build.c,v 1.16.2.2 2002/03/12 15:36:43 dwmw2 Exp $
  *
  */
 
@@ -59,7 +59,11 @@
 
 	/* First, scan the medium and build all the inode caches with
 	   lists of physical nodes */
+
+	c->flags |= JFFS2_SB_FLAG_MOUNTING;
 	ret = jffs2_scan_medium(c);
+	c->flags &= ~JFFS2_SB_FLAG_MOUNTING;
+
 	if (ret)
 		return ret;
 
@@ -201,6 +205,10 @@
 
 		if (child_ic->nlink++ && fd->type == DT_DIR) {
 			printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino);
+			if (fd->ino == 1 && ic->ino == 1) {
+				printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n");
+				printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
+			}
 			/* What do we do about it? */
 		}
 		D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino));
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/dir.c linux/fs/jffs2/dir.c
--- linux.orig/fs/jffs2/dir.c	2002-02-25 19:38:08.000000000 +0000
+++ linux/fs/jffs2/dir.c	2002-07-20 01:08:29.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: dir.c,v 1.45 2001/12/27 22:43:20 dwmw2 Exp $
+ * $Id: dir.c,v 1.45.2.6 2002/06/20 23:54:48 dwmw2 Exp $
  *
  */
 
@@ -177,11 +177,11 @@
 		}
 		D2(printk(KERN_DEBUG "Dirent %ld: \"%s\", ino #%u, type %d\n", offset, fd->name, fd->ino, fd->type));
 		if (filldir(dirent, fd->name, strlen(fd->name), offset, fd->ino, fd->type) < 0)
-			goto out;
+			break;
 		offset++;
 	}
- out:
 	up(&f->sem);
+ out:
 	filp->f_pos = offset;
 	return 0;
 }
@@ -293,7 +293,7 @@
 	rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
 
 	rd->pino = dir_i->i_ino;
-	rd->version = dir_f->highest_version++;
+	rd->version = ++dir_f->highest_version;
 	rd->ino = inode->i_ino;
 	rd->mctime = CURRENT_TIME;
 	rd->nsize = namelen;
@@ -304,16 +304,20 @@
 	fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
 
 	jffs2_complete_reservation(c);
-	jffs2_free_raw_dirent(rd);
 	
 	if (IS_ERR(fd)) {
 		/* dirent failed to write. Delete the inode normally 
 		   as if it were the final unlink() */
+		jffs2_free_raw_dirent(rd);
 		up(&dir_f->sem);
 		jffs2_clear_inode(inode);
 		return PTR_ERR(fd);
 	}
 
+	dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
+
+	jffs2_free_raw_dirent(rd);
+
 	/* Link the fd into the inode's list, obsoleting an old
 	   one if necessary. */
 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
@@ -359,7 +363,7 @@
 	rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
 
 	rd->pino = dir_i->i_ino;
-	rd->version = dir_f->highest_version++;
+	rd->version = ++dir_f->highest_version;
 	rd->ino = 0;
 	rd->mctime = CURRENT_TIME;
 	rd->nsize = dentry->d_name.len;
@@ -446,7 +450,7 @@
 	rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
 
 	rd->pino = dir_i->i_ino;
-	rd->version = dir_f->highest_version++;
+	rd->version = ++dir_f->highest_version;
 	rd->ino = old_dentry->d_inode->i_ino;
 	rd->mctime = CURRENT_TIME;
 	rd->nsize = dentry->d_name.len;
@@ -483,7 +487,12 @@
 
 static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
 {
-	int ret = jffs2_do_link(old_dentry, dir_i, dentry, 0);
+	int ret;
+
+	if (S_ISDIR(old_dentry->d_inode->i_mode))
+		return -EPERM;
+
+	ret = jffs2_do_link(old_dentry, dir_i, dentry, 0);
 	if (!ret) {
 		d_instantiate(dentry, old_dentry->d_inode);
 		atomic_inc(&old_dentry->d_inode->i_count);
@@ -600,7 +609,7 @@
 	rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
 
 	rd->pino = dir_i->i_ino;
-	rd->version = dir_f->highest_version++;
+	rd->version = ++dir_f->highest_version;
 	rd->ino = inode->i_ino;
 	rd->mctime = CURRENT_TIME;
 	rd->nsize = namelen;
@@ -611,16 +620,20 @@
 	fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
 	
 	jffs2_complete_reservation(c);
-	jffs2_free_raw_dirent(rd);
 	
 	if (IS_ERR(fd)) {
 		/* dirent failed to write. Delete the inode normally 
 		   as if it were the final unlink() */
+		jffs2_free_raw_dirent(rd);
 		up(&dir_f->sem);
 		jffs2_clear_inode(inode);
 		return PTR_ERR(fd);
 	}
 
+	dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
+
+	jffs2_free_raw_dirent(rd);
+
 	/* Link the fd into the inode's list, obsoleting an old
 	   one if necessary. */
 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
@@ -730,7 +743,7 @@
 	rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
 
 	rd->pino = dir_i->i_ino;
-	rd->version = dir_f->highest_version++;
+	rd->version = ++dir_f->highest_version;
 	rd->ino = inode->i_ino;
 	rd->mctime = CURRENT_TIME;
 	rd->nsize = namelen;
@@ -741,16 +754,20 @@
 	fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
 	
 	jffs2_complete_reservation(c);
-	jffs2_free_raw_dirent(rd);
 	
 	if (IS_ERR(fd)) {
 		/* dirent failed to write. Delete the inode normally 
 		   as if it were the final unlink() */
+		jffs2_free_raw_dirent(rd);
 		up(&dir_f->sem);
 		jffs2_clear_inode(inode);
 		return PTR_ERR(fd);
 	}
 
+	dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
+
+	jffs2_free_raw_dirent(rd);
+
 	/* Link the fd into the inode's list, obsoleting an old
 	   one if necessary. */
 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
@@ -794,8 +811,7 @@
 	
 	c = JFFS2_SB_INFO(dir_i->i_sb);
 	
-	if ((mode & S_IFMT) == S_IFBLK ||
-	    (mode & S_IFMT) == S_IFCHR) {
+	if (S_ISBLK(mode) || S_ISCHR(mode)) {
 		dev = (MAJOR(to_kdev_t(rdev)) << 8) | MINOR(to_kdev_t(rdev));
 		devlen = sizeof(dev);
 	}
@@ -881,7 +897,7 @@
 	rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
 
 	rd->pino = dir_i->i_ino;
-	rd->version = dir_f->highest_version++;
+	rd->version = ++dir_f->highest_version;
 	rd->ino = inode->i_ino;
 	rd->mctime = CURRENT_TIME;
 	rd->nsize = namelen;
@@ -895,22 +911,27 @@
 	fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
 	
 	jffs2_complete_reservation(c);
-	jffs2_free_raw_dirent(rd);
 	
 	if (IS_ERR(fd)) {
 		/* dirent failed to write. Delete the inode normally 
 		   as if it were the final unlink() */
+		jffs2_free_raw_dirent(rd);
 		up(&dir_f->sem);
 		jffs2_clear_inode(inode);
 		return PTR_ERR(fd);
 	}
 
+	dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
+
+	jffs2_free_raw_dirent(rd);
+
 	/* Link the fd into the inode's list, obsoleting an old
 	   one if necessary. */
 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
 	up(&dir_f->sem);
 
 	d_instantiate(dentry, inode);
+
 	return 0;
 }
 
@@ -918,6 +939,29 @@
                         struct inode *new_dir_i, struct dentry *new_dentry)
 {
 	int ret;
+	struct jffs2_inode_info *victim_f = NULL;
+
+	/* The VFS will check for us and prevent trying to rename a 
+	 * file over a directory and vice versa, but if it's a directory,
+	 * the VFS can't check whether the victim is empty. The filesystem
+	 * needs to do that for itself.
+	 */
+	if (new_dentry->d_inode) {
+		victim_f = JFFS2_INODE_INFO(new_dentry->d_inode);
+		if (S_ISDIR(new_dentry->d_inode->i_mode)) {
+			struct jffs2_full_dirent *fd;
+
+			down(&victim_f->sem);
+			for (fd = victim_f->dents; fd; fd = fd->next) {
+				if (fd->ino) {
+					up(&victim_f->sem);
+					return -ENOTEMPTY;
+				}
+			}
+			up(&victim_f->sem);
+		}
+	}
+
 	/* XXX: We probably ought to alloc enough space for
 	   both nodes at the same time. Writing the new link, 
 	   then getting -ENOSPC, is quite bad :)
@@ -928,6 +972,18 @@
 	if (ret)
 		return ret;
 
+	if (victim_f) {
+		/* There was a victim. Kill it off nicely */
+		new_dentry->d_inode->i_nlink--;
+		/* Don't oops if the victim was a dirent pointing to an
+		   inode which didn't exist. */
+		if (victim_f->inocache) {
+			down(&victim_f->sem);
+			victim_f->inocache->nlink--;
+			up(&victim_f->sem);
+		}
+	}
+
 	/* Unlink the original */
 	ret = jffs2_do_unlink(old_dir_i, old_dentry, 1);
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/erase.c linux/fs/jffs2/erase.c
--- linux.orig/fs/jffs2/erase.c	2001-10-04 22:13:18.000000000 +0000
+++ linux/fs/jffs2/erase.c	2002-07-20 01:08:25.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: erase.c,v 1.23 2001/09/19 21:51:11 dwmw2 Exp $
+ * $Id: erase.c,v 1.24 2001/12/06 16:38:38 dwmw2 Exp $
  *
  */
 #include <linux/kernel.h>
@@ -215,8 +215,8 @@
 
 	D2({
 		int i=0;
-        struct jffs2_raw_node_ref *this;		
-        printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG);
+		struct jffs2_raw_node_ref *this;
+		printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG);
 
 		this = ic->nodes;
 	   
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/file.c linux/fs/jffs2/file.c
--- linux.orig/fs/jffs2/file.c	2001-10-04 22:13:18.000000000 +0000
+++ linux/fs/jffs2/file.c	2002-07-20 01:08:36.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: file.c,v 1.58 2001/09/20 15:28:31 dwmw2 Exp $
+ * $Id: file.c,v 1.58.2.1 2002/02/23 14:25:36 dwmw2 Exp $
  *
  */
 
@@ -102,15 +102,14 @@
 	   must read the original data associated with the node
 	   (i.e. the device numbers or the target name) and write
 	   it out again with the appropriate data attached */
-	if ((inode->i_mode & S_IFMT) == S_IFBLK ||
-	    (inode->i_mode & S_IFMT) == S_IFCHR) {
+	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
 		/* For these, we don't actually need to read the old node */
 		dev =  (MAJOR(to_kdev_t(dentry->d_inode->i_rdev)) << 8) | 
 			MINOR(to_kdev_t(dentry->d_inode->i_rdev));
 		mdata = (char *)&dev;
 		mdatalen = sizeof(dev);
 		D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
-	} else if ((inode->i_mode & S_IFMT) == S_IFLNK) {
+	} else if (S_ISLNK(inode->i_mode)) {
 		mdatalen = f->metadata->size;
 		mdata = kmalloc(f->metadata->size, GFP_USER);
 		if (!mdata)
@@ -125,7 +124,7 @@
 
 	ri = jffs2_alloc_raw_inode();
 	if (!ri) {
-		if ((inode->i_mode & S_IFMT) == S_IFLNK)
+		if (S_ISLNK(inode->i_mode))
 			kfree(mdata);
 		return -ENOMEM;
 	}
@@ -133,7 +132,7 @@
 	ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
 	if (ret) {
 		jffs2_free_raw_inode(ri);
-		if ((inode->i_mode & S_IFMT) == S_IFLNK)
+		if (S_ISLNK(inode->i_mode))
 			 kfree(mdata);
 		return ret;
 	}
@@ -177,7 +176,7 @@
 		ri->data_crc = 0;
 
 	new_metadata = jffs2_write_dnode(inode, ri, mdata, mdatalen, phys_ofs, NULL);
-	if ((inode->i_mode & S_IFMT) == S_IFLNK)
+	if (S_ISLNK(inode->i_mode))
 		kfree(mdata);
 
 	jffs2_complete_reservation(c);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/gc.c linux/fs/jffs2/gc.c
--- linux.orig/fs/jffs2/gc.c	2001-10-04 22:13:18.000000000 +0000
+++ linux/fs/jffs2/gc.c	2002-07-20 01:08:30.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: gc.c,v 1.52 2001/09/19 21:53:47 dwmw2 Exp $
+ * $Id: gc.c,v 1.52.2.3 2002/05/12 17:27:08 dwmw2 Exp $
  *
  */
 
@@ -266,15 +266,14 @@
 	__u32 alloclen, phys_ofs;
 	int ret;
 
-	if ((inode->i_mode & S_IFMT) == S_IFBLK ||
-	    (inode->i_mode & S_IFMT) == S_IFCHR) {
+	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
 		/* For these, we don't actually need to read the old node */
 		dev =  (MAJOR(to_kdev_t(inode->i_rdev)) << 8) | 
 			MINOR(to_kdev_t(inode->i_rdev));
 		mdata = (char *)&dev;
 		mdatalen = sizeof(dev);
 		D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen));
-	} else if ((inode->i_mode & S_IFMT) == S_IFLNK) {
+	} else if (S_ISLNK(inode->i_mode)) {
 		mdatalen = fn->size;
 		mdata = kmalloc(fn->size, GFP_KERNEL);
 		if (!mdata) {
@@ -331,7 +330,7 @@
 	jffs2_free_full_dnode(fn);
 	f->metadata = new_fn;
  out:
-	if ((inode->i_mode & S_IFMT) == S_IFLNK)
+	if (S_ISLNK(inode->i_mode))
 		kfree(mdata);
 	return ret;
 }
@@ -466,8 +465,8 @@
 		ri.ino = inode->i_ino;
 		ri.version = ++f->highest_version;
 		ri.offset = start;
-		ri.csize = end - start;
-		ri.dsize = 0;
+		ri.dsize = end - start;
+		ri.csize = 0;
 		ri.compr = JFFS2_COMPR_ZERO;
 	}
 	ri.mode = inode->i_mode;
@@ -498,9 +497,21 @@
 			jffs2_mark_node_obsolete(c, f->metadata->raw);
 			jffs2_free_full_dnode(f->metadata);
 			f->metadata = NULL;
-			return 0;
 		}
+		return 0;
 	}
+
+	/* 
+	 * We should only get here in the case where the node we are
+	 * replacing had more than one frag, so we kept the same version
+	 * number as before. (Except in case of error -- see 'goto fill;' 
+	 * above.)
+	 */
+	D1(if(unlikely(fn->frags <= 1)) {
+		printk(KERN_WARNING "jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n",
+		       fn->frags, ri.version, f->highest_version, ri.ino);
+	});
+
 	for (frag = f->fraglist; frag; frag = frag->next) {
 		if (frag->ofs > fn->size + fn->ofs)
 			break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/nodelist.c linux/fs/jffs2/nodelist.c
--- linux.orig/fs/jffs2/nodelist.c	2001-11-14 16:19:40.000000000 +0000
+++ linux/fs/jffs2/nodelist.c	2002-07-20 01:08:38.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
- * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2001, 2002 Red Hat, Inc.
  *
  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
  *
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: nodelist.c,v 1.30 2001/11/14 10:35:21 dwmw2 Exp $
+ * $Id: nodelist.c,v 1.30.2.4 2002/05/10 18:30:33 dwmw2 Exp $
  *
  */
 
@@ -69,7 +69,7 @@
 	*prev = new;
 
  out:
-	D1(while(*list) {
+	D2(while(*list) {
 		printk(KERN_DEBUG "Dirent \"%s\" (hash 0x%08x, ino #%u\n", (*list)->name, (*list)->nhash, (*list)->ino);
 		list = &(*list)->next;
 	});
@@ -94,7 +94,8 @@
 
 int jffs2_get_inode_nodes(struct jffs2_sb_info *c, ino_t ino, struct jffs2_inode_info *f,
 			  struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
-			  __u32 *highest_version)
+			  __u32 *highest_version, __u32 *latest_mctime,
+			  __u32 *mctime_ver)
 {
 	struct jffs2_raw_node_ref *ref = f->inocache->nodes;
 	struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL;
@@ -104,6 +105,8 @@
 	size_t retlen;
 	int err;
 
+	*mctime_ver = 0;
+
 	D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%lu\n", ino));
 	if (!f->inocache->nodes) {
 		printk(KERN_WARNING "Eep. no nodes for ino #%lu\n", ino);
@@ -115,7 +118,7 @@
 			D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref->flash_offset &~3));
 			continue;
 		}
-		err = c->mtd->read(c->mtd, (ref->flash_offset & ~3), sizeof(node), &retlen, (void *)&node);
+		err = c->mtd->read(c->mtd, (ref->flash_offset & ~3), min(ref->totlen, sizeof(node)), &retlen, (void *)&node);
 		if (err) {
 			printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, (ref->flash_offset) & ~3);
 			goto free_out;
@@ -123,7 +126,7 @@
 			
 
 			/* Check we've managed to read at least the common node header */
-		if (retlen < sizeof(node.u)) {
+		if (retlen < min(ref->totlen, sizeof(node.u))) {
 			printk(KERN_WARNING "short read in get_inode_nodes()\n");
 			err = -EIO;
 			goto free_out;
@@ -153,15 +156,22 @@
 			fd->version = node.d.version;
 			fd->ino = node.d.ino;
 			fd->type = node.d.type;
-				/* memcpy as much of the name as possible from the raw
-				   dirent we've already read from the flash
-				*/
+
+			/* Pick out the mctime of the latest dirent */
+			if(fd->version > *mctime_ver) {
+				*mctime_ver = fd->version;
+				*latest_mctime = node.d.mctime;
+			}
+
+			/* memcpy as much of the name as possible from the raw
+			   dirent we've already read from the flash
+			*/
 			if (retlen > sizeof(struct jffs2_raw_dirent))
 				memcpy(&fd->name[0], &node.d.name[0], min((__u32)node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
 				
-				/* Do we need to copy any more of the name directly
-				   from the flash?
-				*/
+			/* Do we need to copy any more of the name directly
+			   from the flash?
+			*/
 			if (node.d.nsize + sizeof(struct jffs2_raw_dirent) > retlen) {
 				int already = retlen - sizeof(struct jffs2_raw_dirent);
 					
@@ -217,7 +227,12 @@
 			}
 			tn->version = node.i.version;
 			tn->fn->ofs = node.i.offset;
-			tn->fn->size = node.i.dsize;
+			/* There was a bug where we wrote hole nodes out with
+			   csize/dsize swapped. Deal with it */
+			if (node.i.compr == JFFS2_COMPR_ZERO && !node.i.dsize && node.i.csize)
+				tn->fn->size = node.i.csize;
+			else // normal case...
+				tn->fn->size = node.i.dsize;
 			tn->fn->raw = ref;
 			D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n", ref->flash_offset &~3, node.i.version, node.i.offset, node.i.dsize));
 			jffs2_add_tn_to_list(tn, &ret_tn);
@@ -242,6 +257,7 @@
 	}
 	*tnp = ret_tn;
 	*fdp = ret_fd;
+
 	return 0;
 
  free_out:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/nodelist.h linux/fs/jffs2/nodelist.h
--- linux.orig/fs/jffs2/nodelist.h	2001-10-04 22:13:18.000000000 +0000
+++ linux/fs/jffs2/nodelist.h	2002-07-20 01:08:37.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: nodelist.h,v 1.46 2001/09/18 23:43:05 dwmw2 Exp $
+ * $Id: nodelist.h,v 1.46.2.1 2002/02/23 14:04:44 dwmw2 Exp $
  *
  */
 
@@ -248,7 +248,8 @@
 void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list);
 int jffs2_get_inode_nodes(struct jffs2_sb_info *c, ino_t ino, struct jffs2_inode_info *f,
 			  struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
-			  __u32 *highest_version);
+			  __u32 *highest_version, __u32 *latest_mctime,
+			  __u32 *mctime_ver);
 struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, int ino);
 void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new);
 void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/nodemgmt.c linux/fs/jffs2/nodemgmt.c
--- linux.orig/fs/jffs2/nodemgmt.c	2001-10-04 22:13:18.000000000 +0000
+++ linux/fs/jffs2/nodemgmt.c	2002-07-20 01:08:27.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: nodemgmt.c,v 1.45 2001/09/20 08:05:05 dwmw2 Exp $
+ * $Id: nodemgmt.c,v 1.45.2.1 2002/02/23 14:13:34 dwmw2 Exp $
  *
  */
 
@@ -319,6 +319,15 @@
 
 	ACCT_PARANOIA_CHECK(jeb);
 
+	if (c->flags & JFFS2_SB_FLAG_MOUNTING) {
+		/* Mount in progress. Don't muck about with the block
+		   lists because they're not ready yet, and don't actually
+		   obliterate nodes that look obsolete. If they weren't 
+		   marked obsolete on the flash at the time they _became_
+		   obsolete, there was probably a reason for that. */
+		spin_unlock_bh(&c->erase_completion_lock);
+		return;
+	}
 	if (jeb == c->nextblock) {
 		D2(printk(KERN_DEBUG "Not moving nextblock 0x%08x to dirty/erase_pending list\n", jeb->offset));
 	} else if (jeb == c->gcblock) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/read.c linux/fs/jffs2/read.c
--- linux.orig/fs/jffs2/read.c	2001-09-14 21:04:07.000000000 +0000
+++ linux/fs/jffs2/read.c	2002-07-20 01:08:31.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: read.c,v 1.13 2001/05/01 16:24:44 dwmw2 Exp $
+ * $Id: read.c,v 1.13.2.1 2002/02/01 23:32:33 dwmw2 Exp $
  *
  */
 
@@ -75,6 +75,12 @@
 		ret = -EIO;
 		goto out_ri;
 	}
+	/* There was a bug where we wrote hole nodes out with csize/dsize
+	   swapped. Deal with it */
+	if (ri->compr == JFFS2_COMPR_ZERO && !ri->dsize && ri->csize) {
+		ri->dsize = ri->csize;
+		ri->csize = 0;
+	}
 
 	D1(if(ofs + len > ri->dsize) {
 		printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", len, ofs, ri->dsize);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/readinode.c linux/fs/jffs2/readinode.c
--- linux.orig/fs/jffs2/readinode.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/jffs2/readinode.c	2002-07-20 01:08:23.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: readinode.c,v 1.57 2001/12/27 22:49:46 dwmw2 Exp $
+ * $Id: readinode.c,v 1.58.2.5 2002/03/05 22:40:03 dwmw2 Exp $
  *
  */
 
@@ -173,12 +173,12 @@
 				jffs2_free_node_frag(newfrag);
 				return -ENOMEM;
 			}
-			printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
+			D1(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
 			if (this->node)
 				printk("phys 0x%08x\n", this->node->raw->flash_offset &~3);
 			else 
 				printk("hole\n");
-
+			   )
 			newfrag2->ofs = fn->ofs + fn->size;
 			newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
 			newfrag2->next = this->next;
@@ -251,6 +251,8 @@
 	struct jffs2_full_dnode *fn = NULL;
 	struct jffs2_sb_info *c;
 	struct jffs2_raw_inode latest_node;
+	__u32 latest_mctime, mctime_ver;
+	__u32 mdata_ver = 0;
 	int ret;
 	ssize_t retlen;
 
@@ -288,7 +290,7 @@
 	inode->i_nlink = f->inocache->nlink;
 
 	/* Grab all nodes relevant to this ino */
-	ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version);
+	ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
 
 	if (ret) {
 		printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret);
@@ -298,8 +300,6 @@
 	f->dents = fd_list;
 
 	while (tn_list) {
-		static __u32 mdata_ver = 0;
-
 		tn = tn_list;
 
 		fn = tn->fn;
@@ -335,6 +335,7 @@
 			printk(KERN_WARNING "jffs2_read_inode(): But it has children so we fake some modes for it\n");
 		}
 		inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
+		latest_node.version = 0;
 		inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 		inode->i_nlink = f->inocache->nlink;
 		inode->i_size = 0;
@@ -362,7 +363,7 @@
 		inode->i_uid = latest_node.uid;
 		inode->i_gid = latest_node.gid;
 		inode->i_size = latest_node.isize;
-		if ((inode->i_mode & S_IFMT) == S_IFREG)
+		if (S_ISREG(inode->i_mode))
 			jffs2_truncate_fraglist(c, &f->fraglist, latest_node.isize);
 		inode->i_atime = latest_node.atime;
 		inode->i_mtime = latest_node.mtime;
@@ -372,9 +373,8 @@
 	/* OK, now the special cases. Certain inode types should
 	   have only one data node, and it's kept as the metadata
 	   node */
-	if ((inode->i_mode & S_IFMT) == S_IFBLK ||
-	    (inode->i_mode & S_IFMT) == S_IFCHR ||
-	    (inode->i_mode & S_IFMT) == S_IFLNK) {
+	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode) ||
+	    S_ISLNK(inode->i_mode)) {
 		if (f->metadata) {
 			printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had metadata node\n", inode->i_ino, inode->i_mode);
 			jffs2_clear_inode(inode);
@@ -389,7 +389,8 @@
 		}
 		/* ASSERT: f->fraglist != NULL */
 		if (f->fraglist->next) {
-			printk(KERN_WARNING "Argh. Special inode #%lu had more than one node\n", inode->i_ino);
+			printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had more than one node\n", inode->i_ino, inode->i_mode);
+			/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
 			jffs2_clear_inode(inode);
 			make_bad_inode(inode);
 			return;
@@ -417,6 +418,12 @@
 		break;
 		
 	case S_IFDIR:
+		if (mctime_ver > latest_node.version) {
+			/* The times in the latest_node are actually older than
+			   mctime in the latest dirent. Cheat. */
+			inode->i_mtime = inode->i_ctime = inode->i_atime = 
+				latest_mctime;
+		}
 		inode->i_op = &jffs2_dir_inode_operations;
 		inode->i_fop = &jffs2_dir_operations;
 		break;
@@ -464,6 +471,8 @@
 
 	D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
 
+	down(&f->sem);
+
 	frags = f->fraglist;
 	fds = f->dents;
 	if (f->metadata) {
@@ -491,10 +500,7 @@
 		fds = fd->next;
 		jffs2_free_full_dirent(fd);
 	}
-	//	if (!f->inocache->nlink) {
-		//		D1(printk(KERN_DEBUG "jffs2_clear_inode() deleting inode #%lu\n", inode->i_ino));
-		//		jffs2_del_ino_cache(JFFS2_SB_INFO(inode->i_sb), f->inocache);
-		//		jffs2_free_inode_cache(f->inocache);
-	//	}
+
+	up(&f->sem);
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/scan.c linux/fs/jffs2/scan.c
--- linux.orig/fs/jffs2/scan.c	2001-10-04 22:13:18.000000000 +0000
+++ linux/fs/jffs2/scan.c	2002-07-20 01:08:33.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: scan.c,v 1.51 2001/09/19 00:06:35 dwmw2 Exp $
+ * $Id: scan.c,v 1.51.2.2 2002/02/23 13:34:31 dwmw2 Exp $
  *
  */
 #include <linux/kernel.h>
@@ -62,6 +62,9 @@
 	} \
 } while(0)
 
+static uint32_t pseudo_random;
+static void jffs2_rotate_lists(struct jffs2_sb_info *c);
+
 static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
 
 /* These helper functions _must_ increase ofs and also do the dirty/used space accounting. 
@@ -142,6 +145,9 @@
 			c->nr_erasing_blocks++;
 		}
 	}
+	/* Rotate the lists by some number to ensure wear levelling */
+	jffs2_rotate_lists(c);
+
 	if (c->nr_erasing_blocks) {
 		if (!c->used_size && empty_blocks != c->nr_blocks) {
 			printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
@@ -444,6 +450,12 @@
 		*ofs += 4;
 		return 0;
 	}
+	/* There was a bug where we wrote hole nodes out with csize/dsize
+	   swapped. Deal with it */
+	if (ri.compr == JFFS2_COMPR_ZERO && !ri.dsize && ri.csize) {
+		ri.dsize = ri.csize;
+		ri.csize = 0;
+	}
 
 	if (ri.csize) {
 		/* Check data CRC too */
@@ -474,7 +486,7 @@
 			       *ofs, ri.data_crc, crc);
 			DIRTY_SPACE(PAD(ri.totlen));
 			*ofs += PAD(ri.totlen);
-			return -0;
+			return 0;
 		}
 	}
 
@@ -518,6 +530,8 @@
 	D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", 
 		  ri.ino, ri.version, ri.offset, ri.offset+ri.dsize));
 
+	pseudo_random += ri.version;
+
 	for (tn_list = &ic->scan->tmpnodes; *tn_list; tn_list = &((*tn_list)->next)) {
 		if ((*tn_list)->version < ri.version)
 			continue;
@@ -613,6 +627,8 @@
 		return 0;
 	}
 
+	pseudo_random += rd.version;
+
 	fd = jffs2_alloc_full_dirent(rd.nsize+1);
 	if (!fd) {
 		return -ENOMEM;
@@ -686,3 +702,45 @@
 	*ofs += PAD(rd.totlen);
 	return 0;
 }
+
+static int count_list(struct list_head *l)
+{
+	uint32_t count = 0;
+	struct list_head *tmp;
+
+	list_for_each(tmp, l) {
+		count++;
+	}
+	return count;
+}
+
+/* Note: This breaks if list_empty(head). I don't care. You
+   might, if you copy this code and use it elsewhere :) */
+static void rotate_list(struct list_head *head, uint32_t count)
+{
+	struct list_head *n = head->next;
+
+	list_del(head);
+	while(count--)
+		n = n->next;
+	list_add(head, n);
+}
+
+static void jffs2_rotate_lists(struct jffs2_sb_info *c)
+{
+	uint32_t x;
+
+	x = count_list(&c->clean_list);
+	if (x)
+		rotate_list((&c->clean_list), pseudo_random % x);
+
+	x = count_list(&c->dirty_list);
+	if (x)
+		rotate_list((&c->dirty_list), pseudo_random % x);
+
+	if (c->nr_erasing_blocks)
+		rotate_list((&c->erase_pending_list), pseudo_random % c->nr_erasing_blocks);
+
+	if (c->nr_free_blocks) /* Not that it should ever be zero */
+		rotate_list((&c->free_list), pseudo_random % c->nr_free_blocks);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/super.c linux/fs/jffs2/super.c
--- linux.orig/fs/jffs2/super.c	2001-10-04 22:14:35.000000000 +0000
+++ linux/fs/jffs2/super.c	2002-07-20 01:08:32.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: super.c,v 1.48 2001/10/02 09:16:23 dwmw2 Exp $
+ * $Id: super.c,v 1.48.2.2 2002/03/12 15:36:43 dwmw2 Exp $
  *
  */
 
@@ -249,6 +249,7 @@
 		D1(printk(KERN_DEBUG "build_fs failed\n"));
 		goto out_nodes;
 	}
+
 	sb->s_op = &jffs2_super_operations;
 
 	D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n"));
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/symlink.c linux/fs/jffs2/symlink.c
--- linux.orig/fs/jffs2/symlink.c	2001-09-14 21:04:07.000000000 +0000
+++ linux/fs/jffs2/symlink.c	2002-07-20 01:08:21.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
- * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2001, 2002 Red Hat, Inc.
  *
  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
  *
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: symlink.c,v 1.5 2001/03/15 15:38:24 dwmw2 Exp $
+ * $Id: symlink.c,v 1.5.2.1 2002/01/15 10:39:06 dwmw2 Exp $
  *
  */
 
@@ -58,16 +58,21 @@
 	char *buf;
 	int ret;
 
+	down(&f->sem);
 	if (!f->metadata) {
+		up(&f->sem);
 		printk(KERN_NOTICE "No metadata for symlink inode #%lu\n", dentry->d_inode->i_ino);
 		return ERR_PTR(-EINVAL);
 	}
 	buf = kmalloc(f->metadata->size+1, GFP_USER);
-	if (!buf)
+	if (!buf) {
+		up(&f->sem);
 		return ERR_PTR(-ENOMEM);
+	}
 	buf[f->metadata->size]=0;
 
 	ret = jffs2_read_dnode(JFFS2_SB_INFO(dentry->d_inode->i_sb), f->metadata, buf, 0, f->metadata->size);
+	up(&f->sem);
 	if (ret) {
 		kfree(buf);
 		return ERR_PTR(ret);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/jffs2/zlib.c linux/fs/jffs2/zlib.c
--- linux.orig/fs/jffs2/zlib.c	2001-09-14 21:04:07.000000000 +0000
+++ linux/fs/jffs2/zlib.c	2002-07-20 01:08:35.000000000 +0000
@@ -14,7 +14,7 @@
  */
 
 /* 
- *  ==FILEVERSION 971210==
+ *  ==FILEVERSION 20020318==
  *
  * This marker is used by the Linux installation script to determine
  * whether an up-to-date version of this file is already installed.
@@ -772,7 +772,7 @@
         windowBits = -windowBits;
     }
     if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
-        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
 	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
         return Z_STREAM_ERROR;
     }
@@ -3860,10 +3860,12 @@
                              &s->sub.trees.tb, z);
       if (t != Z_OK)
       {
-        ZFREE(z, s->sub.trees.blens);
         r = t;
         if (r == Z_DATA_ERROR)
+	{
+	  ZFREE(z, s->sub.trees.blens);
           s->mode = BADB;
+	}
         LEAVE
       }
       s->sub.trees.index = 0;
@@ -3928,11 +3930,13 @@
 #endif
         t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
                                   s->sub.trees.blens, &bl, &bd, &tl, &td, z);
-        ZFREE(z, s->sub.trees.blens);
         if (t != Z_OK)
         {
           if (t == (uInt)Z_DATA_ERROR)
+	  {
+	    ZFREE(z, s->sub.trees.blens);
             s->mode = BADB;
+	  }
           r = t;
           LEAVE
         }
@@ -3945,6 +3949,7 @@
           r = Z_MEM_ERROR;
           LEAVE
         }
+        ZFREE(z, s->sub.trees.blens);
         s->sub.decode.codes = c;
         s->sub.decode.tl = tl;
         s->sub.decode.td = td;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/lockd/svc4proc.c linux/fs/lockd/svc4proc.c
--- linux.orig/fs/lockd/svc4proc.c	2001-10-01 20:45:47.000000000 +0000
+++ linux/fs/lockd/svc4proc.c	2002-07-20 01:08:32.000000000 +0000
@@ -254,6 +254,8 @@
 
 	dprintk("lockd: TEST_MSG      called\n");
 
+	memset(&res, 0, sizeof(res));
+
 	if ((stat = nlm4svc_proc_test(rqstp, argp, &res)) == 0)
 		stat = nlm4svc_callback(rqstp, NLMPROC_TEST_RES, &res);
 	return stat;
@@ -447,11 +449,13 @@
 	if (nlmsvc_ops != NULL) {
 		struct svc_client	*clnt;
 		saddr.sin_addr.s_addr = argp->addr;
+		nlmsvc_ops->exp_readlock();
 		if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL 
 		 && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) {
 			nlmsvc_free_host_resources(host);
 		}
 		nlm_release_host(host);
+		nlmsvc_ops->exp_unlock();
 	}
 
 	return rpc_success;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/lockd/svcproc.c linux/fs/lockd/svcproc.c
--- linux.orig/fs/lockd/svcproc.c	2001-10-11 14:52:18.000000000 +0000
+++ linux/fs/lockd/svcproc.c	2002-07-20 01:08:38.000000000 +0000
@@ -282,6 +282,8 @@
 
 	dprintk("lockd: TEST_MSG      called\n");
 
+	memset(&res, 0, sizeof(res));
+
 	if ((stat = nlmsvc_proc_test(rqstp, argp, &res)) == 0)
 		stat = nlmsvc_callback(rqstp, NLMPROC_TEST_RES, &res);
 	return stat;
@@ -474,12 +476,14 @@
 	/* If we run on an NFS server, delete all locks held by the client */
 	if (nlmsvc_ops != NULL) {
 		struct svc_client	*clnt;
-		saddr.sin_addr.s_addr = argp->addr;	
+		saddr.sin_addr.s_addr = argp->addr;
+		nlmsvc_ops->exp_readlock();
 		if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL 
 		 && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) {
 			nlmsvc_free_host_resources(host);
 		}
 		nlm_release_host(host);
+		nlmsvc_ops->exp_unlock();
 	}
 
 	return rpc_success;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/msdos/namei.c linux/fs/msdos/namei.c
--- linux.orig/fs/msdos/namei.c	2001-10-12 20:48:42.000000000 +0000
+++ linux/fs/msdos/namei.c	2002-07-20 01:08:37.000000000 +0000
@@ -45,9 +45,10 @@
 /***** Formats an MS-DOS file name. Rejects invalid names. */
 static int msdos_format_name(const char *name,int len,
 	char *res,struct fat_mount_options *opts)
-	/* conv is relaxed/normal/strict, name is proposed name,
-	 * len is the length of the proposed name, res is the result name,
-	 * dotsOK is if hidden files get dots.
+	/* name is the proposed name, len is its length, res is
+	 * the resulting name, opts->name_check is either (r)elaxed,
+	 * (n)ormal or (s)trict, opts->dotsOK allows dots at the
+	 * beginning of name (for hidden files)
 	 */
 {
 	char *walk;
@@ -69,11 +70,11 @@
 	for (walk = res; len && walk-res < 8; walk++) {
 	    	c = *name++;
 		len--;
-		if (opts->conversion != 'r' && strchr(bad_chars,c))
+		if (opts->name_check != 'r' && strchr(bad_chars,c))
 			return -EINVAL;
-		if (opts->conversion == 's' && strchr(bad_if_strict(opts),c))
+		if (opts->name_check == 's' && strchr(bad_if_strict(opts),c))
 			return -EINVAL;
-  		if (c >= 'A' && c <= 'Z' && opts->conversion == 's')
+  		if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
 			return -EINVAL;
 		if (c < ' ' || c == ':' || c == '\\') return -EINVAL;
 /*  0xE5 is legal as a first character, but we must substitute 0x05     */
@@ -86,7 +87,7 @@
 		*walk = (!opts->nocase && c >= 'a' && c <= 'z') ? c-32 : c;
 	}
 	if (space) return -EINVAL;
-	if (opts->conversion == 's' && len && c != '.') {
+	if (opts->name_check == 's' && len && c != '.') {
 		c = *name++;
 		len--;
 		if (c != '.') return -EINVAL;
@@ -97,25 +98,25 @@
 		while (len > 0 && walk-res < MSDOS_NAME) {
 			c = *name++;
 			len--;
-			if (opts->conversion != 'r' && strchr(bad_chars,c))
+			if (opts->name_check != 'r' && strchr(bad_chars,c))
 				return -EINVAL;
-			if (opts->conversion == 's' &&
+			if (opts->name_check == 's' &&
 			    strchr(bad_if_strict(opts),c))
 				return -EINVAL;
 			if (c < ' ' || c == ':' || c == '\\')
 				return -EINVAL;
 			if (c == '.') {
-				if (opts->conversion == 's')
+				if (opts->name_check == 's')
 					return -EINVAL;
 				break;
 			}
-			if (c >= 'A' && c <= 'Z' && opts->conversion == 's')
+			if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
 				return -EINVAL;
 			space = c == ' ';
 			*walk++ = (!opts->nocase && c >= 'a' && c <= 'z') ? c-32 : c;
 		}
 		if (space) return -EINVAL;
-		if (opts->conversion == 's' && len) return -EINVAL;
+		if (opts->name_check == 's' && len) return -EINVAL;
 	}
 	while (walk-res < MSDOS_NAME) *walk++ = ' ';
 	if (!opts->atari)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/namei.c linux/fs/namei.c
--- linux.orig/fs/namei.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/namei.c	2002-07-20 01:08:32.000000000 +0000
@@ -435,6 +435,8 @@
 		mntput(nd->mnt);
 		nd->mnt = parent;
 	}
+	while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
+		;
 }
 
 /*
@@ -455,7 +457,7 @@
 	while (*name=='/')
 		name++;
 	if (!*name)
-		goto return_base;
+		goto return_reval;
 
 	inode = nd->dentry->d_inode;
 	if (current->link_count)
@@ -574,7 +576,7 @@
 				inode = nd->dentry->d_inode;
 				/* fallthrough */
 			case 1:
-				goto return_base;
+				goto return_reval;
 		}
 		if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
 			err = nd->dentry->d_op->d_hash(nd->dentry, &this);
@@ -625,6 +627,19 @@
 			nd->last_type = LAST_DOT;
 		else if (this.len == 2 && this.name[1] == '.')
 			nd->last_type = LAST_DOTDOT;
+return_reval:
+		/*
+		 * We bypassed the ordinary revalidation routines.
+		 * Check the cached dentry for staleness.
+		 */
+		dentry = nd->dentry;
+		if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
+			err = -ESTALE;
+			if (!dentry->d_op->d_revalidate(dentry, 0)) {
+				d_invalidate(dentry);
+				break;
+			}
+		}
 return_base:
 		return 0;
 out_dput:
@@ -888,6 +903,8 @@
 			return -EBUSY;
 	} else if (S_ISDIR(victim->d_inode->i_mode))
 		return -EISDIR;
+	if (IS_DEADDIR(dir))
+		return -ENOENT;
 	return 0;
 }
 
@@ -1380,9 +1397,7 @@
 
 	double_down(&dir->i_zombie, &dentry->d_inode->i_zombie);
 	d_unhash(dentry);
-	if (IS_DEADDIR(dir))
-		error = -ENOENT;
-	else if (d_mountpoint(dentry))
+	if (d_mountpoint(dentry))
 		error = -EBUSY;
 	else {
 		lock_kernel();
@@ -1748,9 +1763,7 @@
 	} else
 		double_down(&old_dir->i_zombie,
 			    &new_dir->i_zombie);
-	if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
-		error = -ENOENT;
-	else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
+	if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
 		error = -EBUSY;
 	else 
 		error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/namespace.c linux/fs/namespace.c
--- linux.orig/fs/namespace.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/namespace.c	2002-07-20 01:08:38.000000000 +0000
@@ -15,13 +15,13 @@
 #include <linux/quotaops.h>
 #include <linux/acct.h>
 #include <linux/module.h>
-#include <linux/devfs_fs_kernel.h>
 
 #include <asm/uaccess.h>
 
 #include <linux/seq_file.h>
+#include <linux/namespace.h>
 
-struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
 int do_remount_sb(struct super_block *sb, int flags, void * data);
 void kill_super(struct super_block *sb);
 
@@ -29,12 +29,6 @@
 static int hash_mask, hash_bits;
 static kmem_cache_t *mnt_cache; 
 
-static LIST_HEAD(vfsmntlist);
-static DECLARE_MUTEX(mount_sem);
-
-/* Will be static */
-struct vfsmount *root_vfsmnt;
-
 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
 {
 	unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
@@ -43,7 +37,7 @@
 	return tmp & hash_mask;
 }
 
-struct vfsmount *alloc_vfsmnt(void)
+struct vfsmount *alloc_vfsmnt(char *name)
 {
 	struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL); 
 	if (mnt) {
@@ -53,6 +47,14 @@
 		INIT_LIST_HEAD(&mnt->mnt_child);
 		INIT_LIST_HEAD(&mnt->mnt_mounts);
 		INIT_LIST_HEAD(&mnt->mnt_list);
+		if (name) {
+			int size = strlen(name)+1;
+			char * newname = kmalloc(size, GFP_KERNEL);
+			if (newname) {
+				memcpy(newname, name, size);
+				mnt->mnt_devname = newname;
+			}
+		}
 	}
 	return mnt;
 }
@@ -64,18 +66,6 @@
 	kmem_cache_free(mnt_cache, mnt);
 }
 
-void set_devname(struct vfsmount *mnt, const char *name)
-{
-	if (name) {
-		int size = strlen(name)+1;
-		char * newname = kmalloc(size, GFP_KERNEL);
-		if (newname) {
-			memcpy(newname, name, size);
-			mnt->mnt_devname = newname;
-		}
-	}
-}
-
 struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
 {
 	struct list_head * head = mount_hashtable + hash(mnt, dentry);
@@ -100,7 +90,7 @@
 	while (mnt->mnt_parent != mnt)
 		mnt = mnt->mnt_parent;
 	spin_unlock(&dcache_lock);
-	return mnt == root_vfsmnt;
+	return mnt == current->namespace->root;
 }
 
 static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
@@ -143,11 +133,10 @@
 clone_mnt(struct vfsmount *old, struct dentry *root)
 {
 	struct super_block *sb = old->mnt_sb;
-	struct vfsmount *mnt = alloc_vfsmnt();
+	struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
 
 	if (mnt) {
 		mnt->mnt_flags = old->mnt_flags;
-		set_devname(mnt, old->mnt_devname);
 		atomic_inc(&sb->s_active);
 		mnt->mnt_sb = sb;
 		mnt->mnt_root = dget(root);
@@ -168,26 +157,29 @@
 /* iterator */
 static void *m_start(struct seq_file *m, loff_t *pos)
 {
+	struct namespace *n = m->private;
 	struct list_head *p;
-	loff_t n = *pos;
+	loff_t l = *pos;
 
-	down(&mount_sem);
-	list_for_each(p, &vfsmntlist)
-		if (!n--)
+	down_read(&n->sem);
+	list_for_each(p, &n->list)
+		if (!l--)
 			return list_entry(p, struct vfsmount, mnt_list);
 	return NULL;
 }
 
 static void *m_next(struct seq_file *m, void *v, loff_t *pos)
 {
+	struct namespace *n = m->private;
 	struct list_head *p = ((struct vfsmount *)v)->mnt_list.next;
 	(*pos)++;
-	return p==&vfsmntlist ? NULL : list_entry(p, struct vfsmount, mnt_list);
+	return p==&n->list ? NULL : list_entry(p, struct vfsmount, mnt_list);
 }
 
 static void m_stop(struct seq_file *m, void *v)
 {
-	up(&mount_sem);
+	struct namespace *n = m->private;
+	up_read(&n->sem);
 }
 
 static inline void mangle(struct seq_file *m, const char *s)
@@ -333,7 +325,7 @@
 		return retval;
 	}
 
-	down(&mount_sem);
+	down_write(&current->namespace->sem);
 	spin_lock(&dcache_lock);
 
 	if (atomic_read(&sb->s_active) == 1) {
@@ -352,7 +344,7 @@
 		retval = 0;
 	}
 	spin_unlock(&dcache_lock);
-	up(&mount_sem);
+	up_write(&current->namespace->sem);
 	return retval;
 }
 
@@ -462,8 +454,7 @@
 	return NULL;
 }
 
-/* Will become static */
-int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
+static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
 {
 	int err;
 	if (mnt->mnt_sb->s_flags & MS_NOUSER)
@@ -483,7 +474,7 @@
 		struct list_head head;
 		attach_mnt(mnt, nd);
 		list_add_tail(&head, &mnt->mnt_list);
-		list_splice(&head, vfsmntlist.prev);
+		list_splice(&head, current->namespace->list.prev);
 		mntget(mnt);
 		err = 0;
 	}
@@ -510,7 +501,7 @@
 	if (err)
 		return err;
 
-	down(&mount_sem);
+	down_write(&current->namespace->sem);
 	err = -EINVAL;
 	if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) {
 		err = -ENOMEM;
@@ -530,7 +521,7 @@
 			mntput(mnt);
 	}
 
-	up(&mount_sem);
+	up_write(&current->namespace->sem);
 	path_release(&old_nd);
 	return err;
 }
@@ -577,7 +568,7 @@
 	if (err)
 		return err;
 
-	down(&mount_sem);
+	down_write(&current->namespace->sem);
 	while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
 		;
 	err = -EINVAL;
@@ -617,7 +608,7 @@
 out1:
 	up(&nd->dentry->d_inode->i_zombie);
 out:
-	up(&mount_sem);
+	up_write(&current->namespace->sem);
 	if (!err)
 		path_release(&parent_nd);
 	path_release(&old_nd);
@@ -627,13 +618,22 @@
 static int do_add_mount(struct nameidata *nd, char *type, int flags,
 			int mnt_flags, char *name, void *data)
 {
-	struct vfsmount *mnt = do_kern_mount(type, flags, name, data);
-	int err = PTR_ERR(mnt);
+	struct vfsmount *mnt;
+	int err;
+
+	if (!type || !memchr(type, 0, PAGE_SIZE))
+		return -EINVAL;
 
+	/* we need capabilities... */
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	mnt = do_kern_mount(type, flags, name, data);
+	err = PTR_ERR(mnt);
 	if (IS_ERR(mnt))
 		goto out;
 
-	down(&mount_sem);
+	down_write(&current->namespace->sem);
 	/* Something was mounted here while we slept */
 	while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
 		;
@@ -649,7 +649,7 @@
 	mnt->mnt_flags = mnt_flags;
 	err = graft_tree(mnt, nd);
 unlock:
-	up(&mount_sem);
+	up_write(&current->namespace->sem);
 	mntput(mnt);
 out:
 	return err;
@@ -749,6 +749,86 @@
 	return retval;
 }
 
+int copy_namespace(int flags, struct task_struct *tsk)
+{
+	struct namespace *namespace = tsk->namespace;
+	struct namespace *new_ns;
+	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
+	struct fs_struct *fs = tsk->fs;
+
+	if (!namespace)
+		return 0;
+
+	get_namespace(namespace);
+
+	if (! (flags & CLONE_NEWNS))
+		return 0;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		put_namespace(namespace);
+		return -EPERM;
+	}
+
+	new_ns = kmalloc(sizeof(struct namespace *), GFP_KERNEL);
+	if (!new_ns)
+		goto out;
+
+	atomic_set(&new_ns->count, 1);
+	init_rwsem(&new_ns->sem);
+	new_ns->root = NULL;
+	INIT_LIST_HEAD(&new_ns->list);
+
+	down_write(&tsk->namespace->sem);
+	/* First pass: copy the tree topology */
+	new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
+	spin_lock(&dcache_lock);
+	list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
+	spin_unlock(&dcache_lock);
+
+	/* Second pass: switch the tsk->fs->* elements */
+	if (fs) {
+		struct vfsmount *p, *q;
+		write_lock(&fs->lock);
+
+		p = namespace->root;
+		q = new_ns->root;
+		while (p) {
+			if (p == fs->rootmnt) {
+				rootmnt = p;
+				fs->rootmnt = mntget(q);
+			}
+			if (p == fs->pwdmnt) {
+				pwdmnt = p;
+				fs->pwdmnt = mntget(q);
+			}
+			if (p == fs->altrootmnt) {
+				altrootmnt = p;
+				fs->altrootmnt = mntget(q);
+			}
+			p = next_mnt(p, namespace->root);
+			q = next_mnt(q, new_ns->root);
+		}
+		write_unlock(&fs->lock);
+	}
+	up_write(&tsk->namespace->sem);
+
+	tsk->namespace = new_ns;
+
+	if (rootmnt)
+		mntput(rootmnt);
+	if (pwdmnt)
+		mntput(pwdmnt);
+	if (altrootmnt)
+		mntput(altrootmnt);
+
+	put_namespace(namespace);
+	return 0;
+
+out:
+	put_namespace(namespace);
+	return -ENOMEM;
+}
+
 asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
 			  unsigned long flags, void * data)
 {
@@ -867,7 +947,7 @@
 	user_nd.mnt = mntget(current->fs->rootmnt);
 	user_nd.dentry = dget(current->fs->root);
 	read_unlock(&current->fs->lock);
-	down(&mount_sem);
+	down_write(&current->namespace->sem);
 	down(&old_nd.dentry->d_inode->i_zombie);
 	error = -EINVAL;
 	if (!check_mnt(user_nd.mnt))
@@ -912,7 +992,7 @@
 	path_release(&parent_nd);
 out2:
 	up(&old_nd.dentry->d_inode->i_zombie);
-	up(&mount_sem);
+	up_write(&current->namespace->sem);
 	path_release(&user_nd);
 	path_release(&old_nd);
 out1:
@@ -925,52 +1005,34 @@
 	goto out2;
 }
 
-/*
- * Absolutely minimal fake fs - only empty root directory and nothing else.
- * In 2.5 we'll use ramfs or tmpfs, but for now it's all we need - just
- * something to go with root vfsmount.
- */
-static struct dentry *rootfs_lookup(struct inode *dir, struct dentry *dentry)
-{
-	d_add(dentry, NULL);
-	return NULL;
-}
-static struct file_operations rootfs_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	dcache_readdir,
-};
-static struct inode_operations rootfs_dir_inode_operations = {
-	lookup:		rootfs_lookup,
-};
-static struct super_block *rootfs_read_super(struct super_block * sb, void * data, int silent)
+static void __init init_mount_tree(void)
 {
-	struct inode * inode;
-	struct dentry * root;
-	static struct super_operations s_ops = {};
-	sb->s_op = &s_ops;
-	inode = new_inode(sb);
-	if (!inode)
-		return NULL;
-	inode->i_mode = S_IFDIR|0555;
-	inode->i_uid = inode->i_gid = 0;
-	inode->i_op = &rootfs_dir_inode_operations;
-	inode->i_fop = &rootfs_dir_operations;
-	root = d_alloc_root(inode);
-	if (!root) {
-		iput(inode);
-		return NULL;
+	struct vfsmount *mnt;
+	struct namespace *namespace;
+	struct task_struct *p;
+
+	mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
+	if (IS_ERR(mnt))
+		panic("Can't create rootfs");
+	namespace = kmalloc(sizeof(*namespace), GFP_KERNEL);
+	if (!namespace)
+		panic("Can't allocate initial namespace");
+	atomic_set(&namespace->count, 1);
+	INIT_LIST_HEAD(&namespace->list);
+	init_rwsem(&namespace->sem);
+	list_add(&mnt->mnt_list, &namespace->list);
+	namespace->root = mnt;
+
+	init_task.namespace = namespace;
+	read_lock(&tasklist_lock);
+	for_each_task(p) {
+		get_namespace(namespace);
+		p->namespace = namespace;
 	}
-	sb->s_root = root;
-	return sb;
-}
-static DECLARE_FSTYPE(root_fs_type, "rootfs", rootfs_read_super, FS_NOMOUNT);
+	read_unlock(&tasklist_lock);
 
-static void __init init_mount_tree(void)
-{
-	register_filesystem(&root_fs_type);
-	root_vfsmnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
-	if (IS_ERR(root_vfsmnt))
-		panic("can't allocate root vfsmount");
+	set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
+	set_fs_root(current->fs, namespace->root, namespace->root->mnt_root);
 }
 
 void __init mnt_init(unsigned long mempages)
@@ -1028,93 +1090,6 @@
 		d++;
 		i--;
 	} while (i);
+	init_rootfs();
 	init_mount_tree();
 }
-
-#ifdef CONFIG_BLK_DEV_INITRD
-
-int __init change_root(kdev_t new_root_dev,const char *put_old)
-{
-	struct vfsmount *old_rootmnt;
-	struct nameidata devfs_nd, nd;
-	struct nameidata parent_nd;
-	char *new_devname = kmalloc(strlen("/dev/root.old")+1, GFP_KERNEL);
-	int error = 0;
-
-	if (new_devname)
-		strcpy(new_devname, "/dev/root.old");
-
-	read_lock(&current->fs->lock);
-	old_rootmnt = mntget(current->fs->rootmnt);
-	read_unlock(&current->fs->lock);
-	/*  First unmount devfs if mounted  */
-	if (path_init("/dev", LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd))
-		error = path_walk("/dev", &devfs_nd);
-	if (!error) {
-		if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
-		    devfs_nd.dentry == devfs_nd.mnt->mnt_root) {
-			do_umount(devfs_nd.mnt, 0);
-		}
-		path_release(&devfs_nd);
-	}
-	spin_lock(&dcache_lock);
-	detach_mnt(old_rootmnt, &parent_nd);
-	spin_unlock(&dcache_lock);
-	ROOT_DEV = new_root_dev;
-	mount_root();
-#if 1
-	shrink_dcache();
-	printk("change_root: old root has d_count=%d\n", 
-	       atomic_read(&old_rootmnt->mnt_root->d_count));
-#endif
-	mount_devfs_fs ();
-	/*
-	 * Get the new mount directory
-	 */
-	error = 0;
-	if (path_init(put_old, LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
-		error = path_walk(put_old, &nd);
-	if (error) {
-		int blivet;
-		struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
-
-		atomic_inc(&ramdisk->bd_count);
-		blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
-		printk(KERN_NOTICE "Trying to unmount old root ... ");
-		if (!blivet) {
-			spin_lock(&dcache_lock);
-			list_del_init(&old_rootmnt->mnt_list);
- 			spin_unlock(&dcache_lock);
- 			mntput(old_rootmnt);
-			mntput(old_rootmnt);
-			blivet = ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
-			path_release(&parent_nd);
-			blkdev_put(ramdisk, BDEV_FS);
-		}
-		if (blivet) {
-			printk(KERN_ERR "error %d\n", blivet);
-		} else {
-			printk("okay\n");
-			error = 0;
-		}			
-		kfree(new_devname);
-		return error;
-	}
-
-	spin_lock(&dcache_lock);
-	attach_mnt(old_rootmnt, &nd);
-	if (new_devname) {
-		if (old_rootmnt->mnt_devname)
-			kfree(old_rootmnt->mnt_devname);
-		old_rootmnt->mnt_devname = new_devname;
-	}
-	spin_unlock(&dcache_lock);
-
-	/* put the old stuff */
-	path_release(&parent_nd);
-	mntput(old_rootmnt);
-	path_release(&nd);
-	return 0;
-}
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/dir.c linux/fs/nfs/dir.c
--- linux.orig/fs/nfs/dir.c	2001-06-12 18:15:08.000000000 +0000
+++ linux/fs/nfs/dir.c	2002-07-20 01:08:36.000000000 +0000
@@ -402,6 +402,21 @@
 }
 
 /*
+ * A check for whether or not the parent directory has changed.
+ * In the case it has, we assume that the dentries are untrustworthy
+ * and may need to be looked up again.
+ */
+static inline
+int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
+{
+	if (IS_ROOT(dentry))
+		return 1;
+	if (nfs_revalidate_inode(NFS_SERVER(dir), dir))
+		return 0;
+	return time_after(dentry->d_time, NFS_MTIME_UPDATE(dir));
+}
+
+/*
  * Whenever an NFS operation succeeds, we know that the dentry
  * is valid, so we update the revalidation timestamp.
  */
@@ -410,48 +425,31 @@
 	dentry->d_time = jiffies;
 }
 
-static inline int nfs_dentry_force_reval(struct dentry *dentry, int flags)
+static inline
+int nfs_lookup_verify_inode(struct inode *inode, int flags)
 {
-	struct inode *inode = dentry->d_inode;
-	unsigned long timeout = NFS_ATTRTIMEO(inode);
-
+	struct nfs_server *server = NFS_SERVER(inode);
 	/*
-	 * If it's the last lookup in a series, we use a stricter
-	 * cache consistency check by looking at the parent mtime.
-	 *
-	 * If it's been modified in the last hour, be really strict.
-	 * (This still means that we can avoid doing unnecessary
-	 * work on directories like /usr/share/bin etc which basically
-	 * never change).
+	 * If we're interested in close-to-open cache consistency,
+	 * then we revalidate the inode upon lookup.
 	 */
-	if (!(flags & LOOKUP_CONTINUE)) {
-		long diff = CURRENT_TIME - dentry->d_parent->d_inode->i_mtime;
-
-		if (diff < 15*60)
-			timeout = 0;
-	}
-	
-	return time_after(jiffies,dentry->d_time + timeout);
+	if (!(server->flags & NFS_MOUNT_NOCTO) && !(flags & LOOKUP_CONTINUE))
+		NFS_CACHEINV(inode);
+	return nfs_revalidate_inode(server, inode);
 }
 
 /*
  * We judge how long we want to trust negative
  * dentries by looking at the parent inode mtime.
  *
- * If mtime is close to present time, we revalidate
- * more often.
+ * If parent mtime has changed, we revalidate, else we wait for a
+ * period corresponding to the parent's attribute cache timeout value.
  */
-#define NFS_REVALIDATE_NEGATIVE (1 * HZ)
-static inline int nfs_neg_need_reval(struct dentry *dentry)
+static inline int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry)
 {
-	struct inode *dir = dentry->d_parent->d_inode;
-	unsigned long timeout = NFS_ATTRTIMEO(dir);
-	long diff = CURRENT_TIME - dir->i_mtime;
-
-	if (diff < 5*60 && timeout > NFS_REVALIDATE_NEGATIVE)
-		timeout = NFS_REVALIDATE_NEGATIVE;
-
-	return time_after(jiffies, dentry->d_time + timeout);
+	if (!nfs_check_verifier(dir, dentry))
+		return 1;
+	return time_after(jiffies, dentry->d_time + NFS_ATTRTIMEO(dir));
 }
 
 /*
@@ -462,9 +460,8 @@
  * NOTE! The hit can be a negative hit too, don't assume
  * we have an inode!
  *
- * If the dentry is older than the revalidation interval, 
- * we do a new lookup and verify that the dentry is still
- * correct.
+ * If the parent directory is seen to have changed, we throw out the
+ * cached dentry and do a new lookup.
  */
 static int nfs_lookup_revalidate(struct dentry * dentry, int flags)
 {
@@ -477,13 +474,9 @@
 	lock_kernel();
 	dir = dentry->d_parent->d_inode;
 	inode = dentry->d_inode;
-	/*
-	 * If we don't have an inode, let's look at the parent
-	 * directory mtime to get a hint about how often we
-	 * should validate things..
-	 */
+
 	if (!inode) {
-		if (nfs_neg_need_reval(dentry))
+		if (nfs_neg_need_reval(dir, dentry))
 			goto out_bad;
 		goto out_valid;
 	}
@@ -494,48 +487,39 @@
 		goto out_bad;
 	}
 
-	if (!nfs_dentry_force_reval(dentry, flags))
+	/* Force a full look up iff the parent directory has changed */
+	if (nfs_check_verifier(dir, dentry)) {
+		if (nfs_lookup_verify_inode(inode, flags))
+			goto out_bad;
 		goto out_valid;
-
-	if (IS_ROOT(dentry)) {
-		__nfs_revalidate_inode(NFS_SERVER(inode), inode);
-		goto out_valid_renew;
 	}
 
-	/*
-	 * Do a new lookup and check the dentry attributes.
-	 */
+	if (NFS_STALE(inode))
+		goto out_bad;
+
 	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
 	if (error)
 		goto out_bad;
-
-	/* Inode number matches? */
-	if (!(fattr.valid & NFS_ATTR_FATTR) ||
-	    NFS_FSID(inode) != fattr.fsid ||
-	    NFS_FILEID(inode) != fattr.fileid)
+	if (memcmp(NFS_FH(inode), &fhandle, sizeof(struct nfs_fh))!= 0)
 		goto out_bad;
-
-	/* Ok, remember that we successfully checked it.. */
-	nfs_refresh_inode(inode, &fattr);
-
-	if (nfs_inode_is_stale(inode, &fhandle, &fattr))
+	if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
 		goto out_bad;
 
- out_valid_renew:
 	nfs_renew_times(dentry);
-out_valid:
+ out_valid:
 	unlock_kernel();
 	return 1;
-out_bad:
-	shrink_dcache_parent(dentry);
-	/* If we have submounts, don't unhash ! */
-	if (have_submounts(dentry))
-		goto out_valid;
-	d_drop(dentry);
-	/* Purge readdir caches. */
-	nfs_zap_caches(dir);
-	if (inode && S_ISDIR(inode->i_mode))
+ out_bad:
+	NFS_CACHEINV(dir);
+	if (inode && S_ISDIR(inode->i_mode)) {
+		/* Purge readdir caches. */
 		nfs_zap_caches(inode);
+		/* If we have submounts, don't unhash ! */
+		if (have_submounts(dentry))
+			goto out_valid;
+		shrink_dcache_parent(dentry);
+	}
+	d_drop(dentry);
 	unlock_kernel();
 	return 0;
 }
@@ -568,6 +552,8 @@
 		nfs_complete_unlink(dentry);
 		unlock_kernel();
 	}
+	if (is_bad_inode(inode))
+		force_delete(inode);
 	iput(inode);
 }
 
@@ -604,9 +590,9 @@
 		if (inode) {
 	    no_entry:
 			d_add(dentry, inode);
-			nfs_renew_times(dentry);
 			error = 0;
 		}
+		nfs_renew_times(dentry);
 	}
 out:
 	return ERR_PTR(error);
@@ -621,6 +607,12 @@
 	struct inode *inode;
 	int error = -EACCES;
 
+	if (fhandle->size == 0 || !(fattr->valid & NFS_ATTR_FATTR)) {
+		struct inode *dir = dentry->d_parent->d_inode;
+		error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
+		if (error)
+			goto out_err;
+	}
 	inode = nfs_fhget(dentry, fhandle, fattr);
 	if (inode) {
 		d_instantiate(dentry, inode);
@@ -628,6 +620,9 @@
 		error = 0;
 	}
 	return error;
+out_err:
+	d_drop(dentry);
+	return error;
 }
 
 /*
@@ -658,9 +653,9 @@
 	nfs_zap_caches(dir);
 	error = NFS_PROTO(dir)->create(dir, &dentry->d_name,
 					 &attr, 0, &fhandle, &fattr);
-	if (!error && fhandle.size != 0)
+	if (!error)
 		error = nfs_instantiate(dentry, &fhandle, &fattr);
-	if (error || fhandle.size == 0)
+	else
 		d_drop(dentry);
 	return error;
 }
@@ -684,9 +679,9 @@
 	nfs_zap_caches(dir);
 	error = NFS_PROTO(dir)->mknod(dir, &dentry->d_name, &attr, rdev,
 					&fhandle, &fattr);
-	if (!error && fhandle.size != 0)
+	if (!error)
 		error = nfs_instantiate(dentry, &fhandle, &fattr);
-	if (error || fhandle.size == 0)
+	else
 		d_drop(dentry);
 	return error;
 }
@@ -719,9 +714,9 @@
 	nfs_zap_caches(dir);
 	error = NFS_PROTO(dir)->mkdir(dir, &dentry->d_name, &attr, &fhandle,
 					&fattr);
-	if (!error && fhandle.size != 0)
+	if (!error)
 		error = nfs_instantiate(dentry, &fhandle, &fattr);
-	if (error || fhandle.size == 0)
+	else
 		d_drop(dentry);
 	return error;
 }
@@ -926,7 +921,7 @@
 	nfs_zap_caches(dir);
 	error = NFS_PROTO(dir)->symlink(dir, &dentry->d_name, &qsymname,
 					  &attr, &sym_fh, &sym_attr);
-	if (!error && sym_fh.size != 0 && (sym_attr.valid & NFS_ATTR_FATTR)) {
+	if (!error) {
 		error = nfs_instantiate(dentry, &sym_fh, &sym_attr);
 	} else {
 		if (error == -EEXIST)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/flushd.c linux/fs/nfs/flushd.c
--- linux.orig/fs/nfs/flushd.c	2001-11-09 22:28:15.000000000 +0000
+++ linux/fs/nfs/flushd.c	2002-07-20 01:08:38.000000000 +0000
@@ -59,7 +59,7 @@
 static void	nfs_flushd_exit(struct rpc_task *);
 
 
-int nfs_reqlist_init(struct nfs_server *server)
+static int nfs_reqlist_init(struct nfs_server *server)
 {
 	struct nfs_reqlist	*cache;
 	struct rpc_task		*task;
@@ -136,7 +136,7 @@
 	init_waitqueue_head(&cache->request_wait);
 	server->rw_requests = cache;
 
-	return 0;
+	return nfs_reqlist_init(server);
 }
 
 void nfs_reqlist_free(struct nfs_server *server)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/inode.c linux/fs/nfs/inode.c
--- linux.orig/fs/nfs/inode.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/nfs/inode.c	2002-07-20 01:08:29.000000000 +0000
@@ -463,6 +463,8 @@
                 server->namelen = maxlen;
 
 	sb->s_maxbytes = fsinfo.maxfilesize;
+	if (sb->s_maxbytes > MAX_LFS_FILESIZE) 
+		sb->s_maxbytes = MAX_LFS_FILESIZE; 
 
 	/* Fire up the writeback cache */
 	if (nfs_reqlist_alloc(server) < 0) {
@@ -632,7 +634,6 @@
 	 */
 	if (inode->i_mode == 0) {
 		NFS_FILEID(inode) = fattr->fileid;
-		NFS_FSID(inode) = fattr->fsid;
 		inode->i_mode = fattr->mode;
 		/* Why so? Because we want revalidate for devices/FIFOs, and
 		 * that's precisely what we have in nfs_file_inode_operations.
@@ -671,39 +672,18 @@
 	struct nfs_fh		*fh = desc->fh;
 	struct nfs_fattr	*fattr = desc->fattr;
 
-	if (NFS_FSID(inode) != fattr->fsid)
-		return 0;
 	if (NFS_FILEID(inode) != fattr->fileid)
 		return 0;
 	if (memcmp(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh)) != 0)
 		return 0;
+	if (is_bad_inode(inode))
+		return 0;
 	/* Force an attribute cache update if inode->i_count == 0 */
 	if (!atomic_read(&inode->i_count))
 		NFS_CACHEINV(inode);
 	return 1;
 }
 
-int
-nfs_inode_is_stale(struct inode *inode, struct nfs_fh *fh, struct nfs_fattr *fattr)
-{
-	/* Empty inodes are not stale */
-	if (!inode->i_mode)
-		return 0;
-
-	if ((fattr->mode & S_IFMT) != (inode->i_mode & S_IFMT))
-		return 1;
-
-	if (is_bad_inode(inode) || NFS_STALE(inode))
-		return 1;
-
-	/* Has the filehandle changed? If so is the old one stale? */
-	if (memcmp(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh)) != 0 &&
-	    __nfs_revalidate_inode(NFS_SERVER(inode),inode) == -ESTALE)
-		return 1;
-
-	return 0;
-}
-
 /*
  * This is our own version of iget that looks up inodes by file handle
  * instead of inode number.  We use this technique instead of using
@@ -769,7 +749,7 @@
 	/*
 	 * Make sure the inode is up-to-date.
 	 */
-	error = nfs_revalidate(dentry);
+	error = nfs_revalidate_inode(NFS_SERVER(inode),inode);
 	if (error) {
 #ifdef NFS_PARANOIA
 printk("nfs_notify_change: revalidate failed, error=%d\n", error);
@@ -1004,12 +984,11 @@
 			inode->i_dev, inode->i_ino,
 			atomic_read(&inode->i_count), fattr->valid);
 
-	if (NFS_FSID(inode) != fattr->fsid ||
-	    NFS_FILEID(inode) != fattr->fileid) {
+	if (NFS_FILEID(inode) != fattr->fileid) {
 		printk(KERN_ERR "nfs_refresh_inode: inode number mismatch\n"
-		       "expected (0x%Lx/0x%Lx), got (0x%Lx/0x%Lx)\n",
-		       (long long)NFS_FSID(inode), (long long)NFS_FILEID(inode),
-		       (long long)fattr->fsid, (long long)fattr->fileid);
+		       "expected (0x%x/0x%Lx), got (0x%x/0x%Lx)\n",
+		       inode->i_dev, (long long)NFS_FILEID(inode),
+		       inode->i_dev, (long long)fattr->fileid);
 		goto out_err;
 	}
 
@@ -1079,8 +1058,11 @@
 
 	inode->i_atime = new_atime;
 
-	NFS_CACHE_MTIME(inode) = new_mtime;
-	inode->i_mtime = nfs_time_to_secs(new_mtime);
+	if (NFS_CACHE_MTIME(inode) != new_mtime) {
+		NFS_MTIME_UPDATE(inode) = jiffies;
+		NFS_CACHE_MTIME(inode) = new_mtime;
+		inode->i_mtime = nfs_time_to_secs(new_mtime);
+	}
 
 	NFS_CACHE_ISIZE(inode) = new_size;
 	inode->i_size = new_isize;
@@ -1105,14 +1087,17 @@
  		inode->i_rdev = to_kdev_t(fattr->rdev);
  
 	/* Update attrtimeo value */
-	if (!invalid && time_after(jiffies, NFS_ATTRTIMEO_UPDATE(inode)+NFS_ATTRTIMEO(inode))) {
+	if (invalid) {
+		NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
+		NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
+		invalidate_inode_pages(inode);
+		memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
+	} else if (time_after(jiffies, NFS_ATTRTIMEO_UPDATE(inode)+NFS_ATTRTIMEO(inode))) {
 		if ((NFS_ATTRTIMEO(inode) <<= 1) > NFS_MAXATTRTIMEO(inode))
 			NFS_ATTRTIMEO(inode) = NFS_MAXATTRTIMEO(inode);
 		NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
 	}
 
-	if (invalid)
-		nfs_zap_caches(inode);
 	return 0;
  out_nochange:
 	if (new_atime - inode->i_atime > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/mount_clnt.c linux/fs/nfs/mount_clnt.c
--- linux.orig/fs/nfs/mount_clnt.c	2000-04-13 14:54:19.000000000 +0000
+++ linux/fs/nfs/mount_clnt.c	2002-07-20 01:08:24.000000000 +0000
@@ -13,7 +13,6 @@
 #include <linux/uio.h>
 #include <linux/net.h>
 #include <linux/in.h>
-#include <linux/inet.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xprt.h>
 #include <linux/sunrpc/sched.h>
@@ -67,7 +66,7 @@
 	dprintk("NFS:      nfs_mount(%08x:%s)\n",
 			(unsigned)ntohl(addr->sin_addr.s_addr), path);
 
-	strcpy(hostname, in_ntoa(addr->sin_addr.s_addr));
+	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr));
 	if (!(mnt_clnt = mnt_create(hostname, addr, version)))
 		return -EACCES;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/nfs3proc.c linux/fs/nfs/nfs3proc.c
--- linux.orig/fs/nfs/nfs3proc.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/nfs/nfs3proc.c	2002-07-20 01:08:36.000000000 +0000
@@ -111,7 +111,8 @@
 		status = rpc_call(NFS_CLIENT(dir), NFS3PROC_GETATTR,
 			 fhandle, fattr, 0);
 	dprintk("NFS reply lookup: %d\n", status);
-	nfs_refresh_inode(dir, &dir_attr);
+	if (status >= 0)
+		status = nfs_refresh_inode(dir, &dir_attr);
 	return status;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
--- linux.orig/fs/nfs/nfsroot.c	2001-10-25 07:02:26.000000000 +0000
+++ linux/fs/nfs/nfsroot.c	2002-07-20 01:08:38.000000000 +0000
@@ -78,7 +78,6 @@
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
 #include <linux/in.h>
-#include <linux/inet.h>
 #include <linux/major.h>
 #include <linux/utsname.h>
 #include <net/ipconfig.h>
@@ -163,37 +162,6 @@
 
 
 /*
- *  Extract IP address from the parameter string if needed. Note that we
- *  need to have root_server_addr set _before_ IPConfig gets called as it
- *  can override it.
- */
-static void __init root_nfs_parse_addr(char *name)
-{
-	int octets = 0;
-	char *cp, *cq;
-
-	cp = cq = name;
-	while (octets < 4) {
-		while (*cp >= '0' && *cp <= '9')
-			cp++;
-		if (cp == cq || cp - cq > 3)
-			break;
-		if (*cp == '.' || octets == 3)
-			octets++;
-		if (octets < 4)
-			cp++;
-		cq = cp;
-	}
-	if (octets == 4 && (*cp == ':' || *cp == '\0')) {
-		if (*cp == ':')
-			*cp++ = '\0';
-		root_server_addr = in_aton(name);
-		strcpy(name, cp);
-	}
-}
-
-
-/*
  *  Parse option string.
  */
 static void __init root_nfs_parse(char *name, char *buf)
@@ -281,7 +249,8 @@
 		return -1;
 	}
 
-	strncpy(nfs_data.hostname, in_ntoa(servaddr), sizeof(nfs_data.hostname)-1);
+	snprintf(nfs_data.hostname, sizeof(nfs_data.hostname),
+		 "%u.%u.%u.%u", NIPQUAD(servaddr));
 	return 0;
 }
 
@@ -344,7 +313,7 @@
 			line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0';
 		sprintf(nfs_root_name, NFS_ROOT, line);
 	}
-	root_nfs_parse_addr(nfs_root_name);
+	root_server_addr = root_nfs_parse_addr(nfs_root_name);
 	return 1;
 }
 
@@ -374,8 +343,8 @@
 {
 	struct sockaddr_in sin;
 
-	printk(KERN_NOTICE "Looking up port of RPC %d/%d on %s\n",
-		program, version, in_ntoa(servaddr));
+	printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n",
+		program, version, NIPQUAD(servaddr));
 	set_sockaddr(&sin, servaddr, 0);
 	return rpc_getport_external(&sin, program, version, proto);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/pagelist.c linux/fs/nfs/pagelist.c
--- linux.orig/fs/nfs/pagelist.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/nfs/pagelist.c	2002-07-20 01:08:32.000000000 +0000
@@ -53,7 +53,7 @@
 
 /**
  * nfs_create_request - Create an NFS read/write request.
- * @file: file that owns this request
+ * @cred: RPC credential to use
  * @inode: inode to which the request is attached
  * @page: page to write
  * @offset: starting offset within the page for the write
@@ -66,7 +66,7 @@
  * User should ensure it is safe to sleep in this function.
  */
 struct nfs_page *
-nfs_create_request(struct file *file, struct inode *inode,
+nfs_create_request(struct rpc_cred *cred, struct inode *inode,
 		   struct page *page,
 		   unsigned int offset, unsigned int count)
 {
@@ -96,7 +96,7 @@
 			continue;
 		if (signalled() && (server->flags & NFS_MOUNT_INTR))
 			return ERR_PTR(-ERESTARTSYS);
-		current->policy = SCHED_YIELD;
+		current->policy |= SCHED_YIELD;
 		schedule();
 	}
 
@@ -108,34 +108,49 @@
 	req->wb_offset  = offset;
 	req->wb_bytes   = count;
 
-	/* If we have a struct file, use its cached credentials */
-	if (file) {
-		req->wb_file    = file;
-		get_file(file);
-		req->wb_cred	= nfs_file_cred(file);
-	}
+	if (cred)
+		req->wb_cred = get_rpccred(cred);
 	req->wb_inode   = inode;
 	req->wb_count   = 1;
 
 	return req;
 }
 
+/**
+ * nfs_clear_request - Free up all resources allocated to the request
+ * @req:
+ *
+ * Release all resources associated with a write request after it
+ * has completed.
+ */
+void nfs_clear_request(struct nfs_page *req)
+{
+	/* Release struct file or cached credential */
+	if (req->wb_file) {
+		fput(req->wb_file);
+		req->wb_file = NULL;
+	}
+	if (req->wb_cred) {
+		put_rpccred(req->wb_cred);
+		req->wb_cred = NULL;
+	}
+	if (req->wb_page) {
+		page_cache_release(req->wb_page);
+		req->wb_page = NULL;
+		atomic_dec(&NFS_REQUESTLIST(req->wb_inode)->nr_requests);
+	}
+}
+
 
 /**
  * nfs_release_request - Release the count on an NFS read/write request
  * @req: request to release
  *
- * Release all resources associated with a write request after it
- * has been committed to stable storage
- *
  * Note: Should never be called with the spinlock held!
  */
 void
 nfs_release_request(struct nfs_page *req)
 {
-	struct inode		*inode = req->wb_inode;
-	struct nfs_reqlist	*cache = NFS_REQUESTLIST(inode);
-
 	spin_lock(&nfs_wreq_lock);
 	if (--req->wb_count) {
 		spin_unlock(&nfs_wreq_lock);
@@ -143,7 +158,6 @@
 	}
 	__nfs_del_lru(req);
 	spin_unlock(&nfs_wreq_lock);
-	atomic_dec(&cache->nr_requests);
 
 #ifdef NFS_PARANOIA
 	if (!list_empty(&req->wb_list))
@@ -152,16 +166,12 @@
 		BUG();
 	if (NFS_WBACK_BUSY(req))
 		BUG();
-	if (atomic_read(&cache->nr_requests) < 0)
+	if (atomic_read(&NFS_REQUESTLIST(req->wb_inode)->nr_requests) < 0)
 		BUG();
 #endif
 
 	/* Release struct file or cached credential */
-	if (req->wb_file)
-		fput(req->wb_file);
-	else if (req->wb_cred)
-		put_rpccred(req->wb_cred);
-	page_cache_release(req->wb_page);
+	nfs_clear_request(req);
 	nfs_page_free(req);
 }
 
@@ -236,7 +246,7 @@
 
 		req = nfs_list_entry(head->next);
 		if (prev) {
-			if (req->wb_file != prev->wb_file)
+			if (req->wb_cred != prev->wb_cred)
 				break;
 			if (page_index(req->wb_page) != page_index(prev->wb_page)+1)
 				break;
@@ -270,7 +280,7 @@
 {
 	struct nfs_server *server = NFS_SERVER(req->wb_inode);
 	struct list_head *pos, *head = req->wb_list_head;
-	struct file *file = req->wb_file;
+	struct rpc_cred *cred = req->wb_cred;
 	unsigned long idx = page_index(req->wb_page) + 1;
 	int npages = 0;
 
@@ -291,7 +301,7 @@
 			break;
 		if (req->wb_offset != 0)
 			break;
-		if (req->wb_file != file)
+		if (req->wb_cred != cred)
 			break;
 	}
 	return npages;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/read.c linux/fs/nfs/read.c
--- linux.orig/fs/nfs/read.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/nfs/read.c	2002-07-20 01:08:21.000000000 +0000
@@ -168,7 +168,7 @@
 {
 	struct nfs_page	*new;
 
-	new = nfs_create_request(file, inode, page, 0, PAGE_CACHE_SIZE);
+	new = nfs_create_request(nfs_file_cred(file), inode, page, 0, PAGE_CACHE_SIZE);
 	if (IS_ERR(new))
 		return PTR_ERR(new);
 	nfs_mark_request_read(new);
@@ -224,8 +224,9 @@
 		nfs_list_remove_request(req);
 		SetPageError(page);
 		UnlockPage(page);
-		nfs_unlock_request(req);
+		nfs_clear_request(req);
 		nfs_release_request(req);
+		nfs_unlock_request(req);
 	}
 }
 
@@ -431,6 +432,7 @@
                         (long long)NFS_FILEID(req->wb_inode),
                         req->wb_bytes,
                         (long long)(page_offset(page) + req->wb_offset));
+		nfs_clear_request(req);
 		nfs_release_request(req);
 		nfs_unlock_request(req);
 	}
@@ -448,19 +450,9 @@
 int
 nfs_readpage(struct file *file, struct page *page)
 {
-	struct inode *inode;
+	struct inode *inode = page->mapping->host;
 	int		error;
 
-	if (!file) {
-		struct address_space *mapping = page->mapping;
-		if (!mapping)
-			BUG();
-		inode = mapping->host;
-	} else
-		inode = file->f_dentry->d_inode;
-	if (!inode)
-		BUG();
-
 	dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
 		page, PAGE_CACHE_SIZE, page->index);
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfs/write.c linux/fs/nfs/write.c
--- linux.orig/fs/nfs/write.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/nfs/write.c	2002-07-20 01:08:28.000000000 +0000
@@ -238,17 +238,11 @@
 int
 nfs_writepage(struct page *page)
 {
-	struct inode *inode;
+	struct inode *inode = page->mapping->host;
 	unsigned long end_index;
 	unsigned offset = PAGE_CACHE_SIZE;
 	int err;
-	struct address_space *mapping = page->mapping;
 
-	if (!mapping)
-		BUG();
-	inode = mapping->host;
-	if (!inode)
-		BUG();
 	end_index = inode->i_size >> PAGE_CACHE_SHIFT;
 
 	/* Ensure we've flushed out any previous writes */
@@ -362,6 +356,7 @@
 		iput(inode);
 	} else
 		spin_unlock(&nfs_wreq_lock);
+	nfs_clear_request(req);
 	nfs_release_request(req);
 }
 
@@ -688,9 +683,13 @@
 		}
 		spin_unlock(&nfs_wreq_lock);
 
-		new = nfs_create_request(file, inode, page, offset, bytes);
+		new = nfs_create_request(nfs_file_cred(file), inode, page, offset, bytes);
 		if (IS_ERR(new))
 			return new;
+		if (file) {
+			new->wb_file = file;
+			get_file(file);
+		}
 		/* If the region is locked, adjust the timeout */
 		if (region_locked(inode, new))
 			new->wb_timeout = jiffies + NFS_WRITEBACK_LOCKDELAY;
@@ -768,7 +767,8 @@
 int
 nfs_flush_incompatible(struct file *file, struct page *page)
 {
-	struct inode	*inode = file->f_dentry->d_inode;
+	struct rpc_cred	*cred = nfs_file_cred(file);
+	struct inode	*inode = page->mapping->host;
 	struct nfs_page	*req;
 	int		status = 0;
 	/*
@@ -781,7 +781,7 @@
 	 */
 	req = nfs_find_request(inode,page);
 	if (req) {
-		if (req->wb_file != file || req->wb_page != page)
+		if (req->wb_file != file || req->wb_cred != cred || req->wb_page != page)
 			status = nfs_wb_page(inode, page);
 		nfs_release_request(req);
 	}
@@ -798,7 +798,7 @@
 nfs_updatepage(struct file *file, struct page *page, unsigned int offset, unsigned int count)
 {
 	struct dentry	*dentry = file->f_dentry;
-	struct inode	*inode = dentry->d_inode;
+	struct inode	*inode = page->mapping->host;
 	struct nfs_page	*req;
 	loff_t		end;
 	int		status = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfsd/export.c linux/fs/nfsd/export.c
--- linux.orig/fs/nfsd/export.c	2001-10-04 05:57:36.000000000 +0000
+++ linux/fs/nfsd/export.c	2002-07-20 01:08:38.000000000 +0000
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/in.h>
+#include <linux/seq_file.h>
 
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -31,7 +32,6 @@
 typedef struct svc_client	svc_client;
 typedef struct svc_export	svc_export;
 
-static svc_export *	exp_find(svc_client *clp, kdev_t dev);
 static svc_export *	exp_parent(svc_client *clp, kdev_t dev,
 					struct dentry *dentry);
 static svc_export *	exp_child(svc_client *clp, kdev_t dev,
@@ -65,41 +65,25 @@
 static int			hash_count;
 static DECLARE_WAIT_QUEUE_HEAD(	hash_wait );
 
-
-/*
- * Find a client's export for a device.
- */
-static inline svc_export *
-exp_find(svc_client *clp, kdev_t dev)
-{
-	svc_export *	exp;
-
-	exp = clp->cl_export[EXPORT_HASH(dev)];
-	while (exp && exp->ex_dev != dev)
-		exp = exp->ex_next;
-	return exp;
-}
-
 /*
  * Find the client's export entry matching xdev/xino.
  */
 svc_export *
 exp_get(svc_client *clp, kdev_t dev, ino_t ino)
 {
-	svc_export *	exp;
+	struct list_head *head, *p;
 
 	if (!clp)
 		return NULL;
 
-	exp = clp->cl_export[EXPORT_HASH(dev)];
-	if (exp)
-		do {
-			if (exp->ex_ino == ino && exp->ex_dev == dev)
-				goto out;
-		} while (NULL != (exp = exp->ex_next));
-	exp = NULL;
-out:
-	return exp;
+	head = &clp->cl_export[EXPORT_HASH(dev)];
+	list_for_each(p, head) {
+		svc_export *exp = list_entry(p, svc_export, ex_hash);
+		if (exp->ex_ino == ino && exp->ex_dev == dev)
+			return exp;
+	}
+
+	return NULL;
 }
 
 /*
@@ -108,15 +92,15 @@
 static svc_export *
 exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry)
 {
-	svc_export      *exp;
+	struct list_head *head = &clp->cl_export[EXPORT_HASH(dev)];
+	struct list_head *p;
 
-	if (clp == NULL)
-		return NULL;
-
-	for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next)
+	list_for_each(p,head) {
+		svc_export *exp = list_entry(p, svc_export, ex_hash);
 		if (is_subdir(dentry, exp->ex_dentry))
-			break;
-	return exp;
+			return exp;
+	}
+	return NULL;
 }
 
 /*
@@ -127,17 +111,31 @@
 static svc_export *
 exp_child(svc_client *clp, kdev_t dev, struct dentry *dentry)
 {
-	svc_export      *exp;
+	struct list_head *head = &clp->cl_export[EXPORT_HASH(dev)];
+	struct list_head *p;
 
-	if (clp == NULL)
-		return NULL;
 
-	for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) {
-		struct dentry	*ndentry = exp->ex_dentry;
+	list_for_each(p, head) {
+		svc_export *exp = list_entry(p, svc_export, ex_hash);
+		struct dentry *ndentry = exp->ex_dentry;
+
 		if (ndentry && is_subdir(ndentry->d_parent, dentry))
-			break;
+			return exp;
+	}
+	return NULL;
+}
+
+/* Update parent pointers of all exports */
+static void exp_change_parents(svc_client *clp, svc_export *old, svc_export *new)
+{
+	struct list_head *head = &clp->cl_list;
+	struct list_head *p;
+
+	list_for_each(p, head) {
+		svc_export *exp = list_entry(p, svc_export, ex_list);
+		if (exp->ex_parent == old)
+			exp->ex_parent = new;
 	}
-	return exp;
 }
 
 /*
@@ -148,10 +146,9 @@
 {
 	svc_client	*clp;
 	svc_export	*exp, *parent;
-	svc_export	**head;
 	struct nameidata nd;
 	struct inode	*inode = NULL;
-	int		i, err;
+	int		err;
 	kdev_t		dev;
 	ino_t		ino;
 
@@ -237,8 +234,8 @@
 	strcpy(exp->ex_path, nxp->ex_path);
 	exp->ex_client = clp;
 	exp->ex_parent = parent;
-	exp->ex_dentry = nd.dentry;
-	exp->ex_mnt = nd.mnt;
+	exp->ex_dentry = dget(nd.dentry);
+	exp->ex_mnt = mntget(nd.mnt);
 	exp->ex_flags = nxp->ex_flags;
 	exp->ex_dev = dev;
 	exp->ex_ino = ino;
@@ -246,34 +243,20 @@
 	exp->ex_anon_gid = nxp->ex_anon_gid;
 
 	/* Update parent pointers of all exports */
-	if (parent) {
-		for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-			svc_export *temp = clp->cl_export[i];
-
-			while (temp) {
-				if (temp->ex_parent == parent)
-					temp->ex_parent = exp;
-				temp = temp->ex_next;
-			}
-		}
-	}
+	if (parent)
+		exp_change_parents(clp, parent, exp);
 
-	head = clp->cl_export + EXPORT_HASH(dev);
-	exp->ex_next = *head;
-	*head = exp;
+	list_add(&exp->ex_hash, clp->cl_export + EXPORT_HASH(dev));
+	list_add_tail(&exp->ex_list, &clp->cl_list);
 
 	err = 0;
 
-	/* Unlock hashtable */
+finish:
+	path_release(&nd);
 out_unlock:
 	exp_unlock();
 out:
 	return err;
-
-	/* Release the dentry */
-finish:
-	path_release(&nd);
-	goto out_unlock;
 }
 
 /*
@@ -283,20 +266,14 @@
 static void
 exp_do_unexport(svc_export *unexp)
 {
-	svc_export	*exp;
-	svc_client	*clp;
 	struct dentry	*dentry;
 	struct vfsmount *mnt;
 	struct inode	*inode;
-	int		i;
 
-	/* Update parent pointers. */
-	clp = unexp->ex_client;
-	for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-		for (exp = clp->cl_export[i]; exp; exp = exp->ex_next)
-			if (exp->ex_parent == unexp)
-				exp->ex_parent = unexp->ex_parent;
-	}
+	list_del(&unexp->ex_hash);
+	list_del(&unexp->ex_list);
+
+	exp_change_parents(unexp->ex_client, unexp, unexp->ex_parent);
 
 	dentry = unexp->ex_dentry;
 	mnt = unexp->ex_mnt;
@@ -317,18 +294,13 @@
 static void
 exp_unexport_all(svc_client *clp)
 {
-	svc_export	*exp;
-	int		i;
+	struct list_head *p = &clp->cl_list;
 
 	dprintk("unexporting all fs's for clnt %p\n", clp);
-	for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-		exp = clp->cl_export[i];
-		clp->cl_export[i] = NULL;
-		while (exp) {
-			svc_export *next = exp->ex_next;
-			exp_do_unexport(exp);
-			exp = next;
-		}
+
+	while (!list_empty(p)) {
+		svc_export *exp = list_entry(p->next, svc_export, ex_list);
+		exp_do_unexport(exp);
 	}
 }
 
@@ -339,7 +311,6 @@
 exp_unexport(struct nfsctl_export *nxp)
 {
 	svc_client	*clp;
-	svc_export	**expp, *exp = NULL;
 	int		err;
 
 	/* Consistency check */
@@ -352,17 +323,10 @@
 	err = -EINVAL;
 	clp = exp_getclientbyname(nxp->ex_client);
 	if (clp) {
-		expp = clp->cl_export + EXPORT_HASH(nxp->ex_dev);
-		while ((exp = *expp) != NULL) {
-			if (exp->ex_dev == nxp->ex_dev) {
-				if (exp->ex_ino == nxp->ex_ino) {
-					*expp = exp->ex_next;
-					exp_do_unexport(exp);
-					err = 0;
-					break;
-				}
-			}
-			expp = &(exp->ex_next);
+		svc_export *exp = exp_get(clp, nxp->ex_dev, nxp->ex_ino);
+		if (exp) {
+			exp_do_unexport(exp);
+			err = 0;
 		}
 	}
 
@@ -542,6 +506,68 @@
 	return NULL;
 }
 
+/* Iterator */
+
+static void *e_start(struct seq_file *m, loff_t *pos)
+{
+	loff_t n = *pos;
+	unsigned client, export;
+	svc_client *clp;
+	struct list_head *p;
+	
+	exp_readlock();
+	if (!n--)
+		return (void *)1;
+	client = n >> 32;
+	export = n & ((1LL<<32) - 1);
+	for (clp = clients; client && clp; clp = clp->cl_next, client--)
+		;
+	if (!clp)
+		return NULL;
+	list_for_each(p, &clp->cl_list)
+		if (!export--)
+			return list_entry(p, svc_export, ex_list);
+	n &= ~((1LL<<32) - 1);
+	do {
+		clp = clp->cl_next;
+		n += 1LL<<32;
+	} while(clp && list_empty(&clp->cl_list));
+	if (!clp)
+		return NULL;
+	*pos = n+1;
+	return list_entry(clp->cl_list.next, svc_export, ex_list);
+}
+
+static void *e_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	svc_export *exp = p;
+	svc_client *clp;
+
+	if (p == (void *)1)
+		clp = clients;
+	else if (exp->ex_list.next == &exp->ex_client->cl_list) {
+		clp = exp->ex_client->cl_next;
+		*pos += 1LL<<32;
+	} else {
+		++*pos;
+		return list_entry(exp->ex_list.next, svc_export, ex_list);
+	}
+	*pos &= ~((1LL<<32) - 1);
+	while (clp && list_empty(&clp->cl_list)) {
+		clp = clp->cl_next;
+		*pos += 1LL<<32;
+	}
+	if (!clp)
+		return NULL;
+	++*pos;
+	return list_entry(clp->cl_list.next, svc_export, ex_list);
+}
+
+static void e_stop(struct seq_file *m, void *p)
+{
+	exp_unlock();
+}
+
 struct flags {
 	int flag;
 	char *name[2];
@@ -564,128 +590,77 @@
 	{ 0, {"", ""}}
 };
 
-static int
-exp_flags(char *buffer, int flag)
+static void exp_flags(struct seq_file *m, int flag)
 {
-    int len = 0, first = 0;
-    struct flags *flg = expflags;
+	int first = 0;
+	struct flags *flg;
 
-    for (;flg->flag;flg++) {
-        int state = (flg->flag & flag)?0:1;
-        if (!flg->flag)
-		break;
-        if (*flg->name[state]) {
-		len += sprintf(buffer + len, "%s%s",
-                               first++?",":"", flg->name[state]);
-        }
-    }
-    return len;
+	for (flg = expflags; flg->flag; flg++) {
+		int state = (flg->flag & flag)?0:1;
+		if (*flg->name[state])
+			seq_printf(m, "%s%s", first++?",":"", flg->name[state]);
+	}
 }
 
-
-
-/* mangling borrowed from fs/super.c */
-/* Use octal escapes, like mount does, for embedded spaces etc. */
-static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
-
-static int
-mangle(const unsigned char *s, char *buf, int len) {
-        char *sp;
-        int n;
-
-        sp = buf;
-        while(*s && sp-buf < len-3) {
-                for (n = 0; n < sizeof(need_escaping); n++) {
-                        if (*s == need_escaping[n]) {
-                                *sp++ = '\\';
-                                *sp++ = '0' + ((*s & 0300) >> 6);
-                                *sp++ = '0' + ((*s & 070) >> 3);
-                                *sp++ = '0' + (*s & 07);
-                                goto next;
-                        }
-                }
-                *sp++ = *s;
-        next:
-                s++;
-        }
-        return sp - buf;	/* no trailing NUL */
+static inline void mangle(struct seq_file *m, const char *s)
+{
+	seq_escape(m, s, " \t\n\\");
 }
 
-#define FREEROOM	((int)PAGE_SIZE-200-len)
-#define MANGLE(s)	len += mangle((s), buffer+len, FREEROOM);
-
-int
-exp_procfs_exports(char *buffer, char **start, off_t offset,
-                             int length, int *eof, void *data)
+static int e_show(struct seq_file *m, void *p)
 {
-	struct svc_clnthash	**hp, **head, *tmp;
-	struct svc_client	*clp;
-	svc_export *exp;
-	off_t	pos = 0;
-        off_t	begin = 0;
-        int	len = 0;
-	int	i,j;
+	struct svc_export *exp = p;
+	struct svc_client *clp;
+	int j, first = 0;
 
-        len += sprintf(buffer, "# Version 1.1\n");
-        len += sprintf(buffer+len, "# Path Client(Flags) # IPs\n");
-
-	for (clp = clients; clp; clp = clp->cl_next) {
-		for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-			exp = clp->cl_export[i];
-			while (exp) {
-				int first = 0;
-				MANGLE(exp->ex_path);
-				buffer[len++]='\t';
-				MANGLE(clp->cl_ident);
-				buffer[len++]='(';
-
-				len += exp_flags(buffer+len, exp->ex_flags);
-				len += sprintf(buffer+len, ") # ");
-				for (j = 0; j < clp->cl_naddr; j++) {
-					struct in_addr	addr = clp->cl_addr[j]; 
-
-					head = &clnt_hash[CLIENT_HASH(addr.s_addr)];
-					for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {
-						if (tmp->h_addr.s_addr == addr.s_addr) {
-							if (first++) len += sprintf(buffer+len, "%s", " ");
-							if (tmp->h_client != clp)
-								len += sprintf(buffer+len, "(");
-							len += sprintf(buffer+len, "%d.%d.%d.%d",
-									htonl(addr.s_addr) >> 24 & 0xff,
-									htonl(addr.s_addr) >> 16 & 0xff,
-									htonl(addr.s_addr) >>  8 & 0xff,
-									htonl(addr.s_addr) >>  0 & 0xff);
-							if (tmp->h_client != clp)
-							  len += sprintf(buffer+len, ")");
-							break;
-						}
-					}
-				}
-				exp = exp->ex_next;
-
-				buffer[len++]='\n';
-
-				pos=begin+len;
-				if(pos<offset) {
-					len=0;
-					begin=pos;
-				}
-				if (pos > offset + length)
-					goto done;
-			}
-		}
+	if (p == (void *)1) {
+		seq_puts(m, "# Version 1.1\n");
+		seq_puts(m, "# Path Client(Flags) # IPs\n");
+		return 0;
 	}
 
-	*eof = 1;
+	clp = exp->ex_client;
 
-done:
-	*start = buffer + (offset - begin);
-	len -= (offset - begin);
-	if ( len > length )
-		len = length;
-	return len;
+	mangle(m, exp->ex_path);
+	seq_putc(m, '\t');
+	mangle(m, clp->cl_ident);
+	seq_putc(m, '(');
+	exp_flags(m, exp->ex_flags);
+	seq_puts(m, ") # ");
+	for (j = 0; j < clp->cl_naddr; j++) {
+		struct svc_clnthash **hp, **head, *tmp;
+		struct in_addr addr = clp->cl_addr[j]; 
+
+		head = &clnt_hash[CLIENT_HASH(addr.s_addr)];
+		for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {
+			if (tmp->h_addr.s_addr == addr.s_addr)
+				break;
+		}
+		if (tmp) {
+			if (first++)
+				seq_putc(m, ' ');
+			if (tmp->h_client != clp)
+				seq_putc(m, '(');
+			seq_printf(m, "%d.%d.%d.%d",
+				htonl(addr.s_addr) >> 24 & 0xff,
+				htonl(addr.s_addr) >> 16 & 0xff,
+				htonl(addr.s_addr) >>  8 & 0xff,
+				htonl(addr.s_addr) >>  0 & 0xff);
+			if (tmp->h_client != clp)
+				seq_putc(m, ')');
+		}
+	}
+	seq_putc(m, '\n');
+	return 0;
 }
 
+struct seq_operations nfs_exports_op = {
+	start:	e_start,
+	next:	e_next,
+	stop:	e_stop,
+	show:	e_show,
+};
+
 /*
  * Add or modify a client.
  * Change requests may involve the list of host addresses. The list of
@@ -721,6 +696,9 @@
 		if (!(clp = kmalloc(sizeof(*clp), GFP_KERNEL)))
 			goto out_unlock;
 		memset(clp, 0, sizeof(*clp));
+		for (i = 0; i < NFSCLNT_EXPMAX; i++)
+			INIT_LIST_HEAD(&clp->cl_export[i]);
+		INIT_LIST_HEAD(&clp->cl_list);
 
 		dprintk("created client %s (%p)\n", ncp->cl_ident, clp);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfsd/nfs3proc.c linux/fs/nfsd/nfs3proc.c
--- linux.orig/fs/nfsd/nfs3proc.c	2001-09-21 04:02:01.000000000 +0000
+++ linux/fs/nfsd/nfs3proc.c	2002-07-20 01:08:33.000000000 +0000
@@ -339,7 +339,7 @@
 		    || (argp->ftype == NF3BLK && argp->major >= MAX_BLKDEV)
 		    || argp->minor > 0xFF)
 			RETURN_STATUS(nfserr_inval);
-		rdev = ((argp->major) << 8) | (argp->minor);
+		rdev = MKDEV(argp->major, argp->minor);
 	} else
 		if (argp->ftype != NF3SOCK && argp->ftype != NF3FIFO)
 			RETURN_STATUS(nfserr_inval);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
--- linux.orig/fs/nfsd/nfsctl.c	2001-10-21 17:32:33.000000000 +0000
+++ linux/fs/nfsd/nfsctl.c	2002-07-20 01:08:27.000000000 +0000
@@ -20,6 +20,7 @@
 #include <linux/unistd.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include <linux/nfs.h>
 #include <linux/sunrpc/svc.h>
@@ -31,6 +32,7 @@
 #include <asm/uaccess.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/init.h>
 
 static int	nfsctl_svc(struct nfsctl_svc *data);
 static int	nfsctl_addclient(struct nfsctl_client *data);
@@ -44,31 +46,26 @@
 static int	nfsctl_ugidupdate(struct nfsctl_ugidmap *data);
 #endif
 
-static int	initialized;
-
-int exp_procfs_exports(char *buffer, char **start, off_t offset,
-                             int length, int *eof, void *data);
+extern struct seq_operations nfs_exports_op;
+static int exports_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &nfs_exports_op);
+}
+static struct file_operations exports_operations = {
+	open:		exports_open,
+	read:		seq_read,
+	llseek:		seq_lseek,
+	release:	seq_release,
+};
 
 void proc_export_init(void)
 {
+	struct proc_dir_entry *entry;
 	if (!proc_mkdir("fs/nfs", 0))
 		return;
-	create_proc_read_entry("fs/nfs/exports", 0, 0, exp_procfs_exports,NULL);
-}
-
-
-/*
- * Initialize nfsd
- */
-static void
-nfsd_init(void)
-{
-	nfsd_stat_init();	/* Statistics */
-	nfsd_cache_init();	/* RPC reply cache */
-	nfsd_export_init();	/* Exports table */
-	nfsd_lockd_init();	/* lockd->nfsd callbacks */
-	proc_export_init();
-	initialized = 1;
+	entry = create_proc_entry("fs/nfs/exports", 0, NULL);
+	if (entry)
+		entry->proc_fops =  &exports_operations;
 }
 
 static inline int
@@ -225,10 +222,8 @@
 	int			err;
 	int			argsize, respsize;
 
-	MOD_INC_USE_COUNT;
 	lock_kernel ();
-	if (!initialized)
-		nfsd_init();
+
 	err = -EPERM;
 	if (!capable(CAP_SYS_ADMIN)) {
 		goto done;
@@ -301,38 +296,47 @@
 		kfree(res);
 
 	unlock_kernel ();
-	MOD_DEC_USE_COUNT;
 	return err;
 }
 
-#ifdef MODULE
-/* New-style module support since 2.1.18 */
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
 MODULE_LICENSE("GPL");
 
+#ifdef MODULE
 struct nfsd_linkage nfsd_linkage_s = {
 	do_nfsservctl: handle_sys_nfsservctl,
+	owner: THIS_MODULE,
 };
+#endif
 
 /*
  * Initialize the module
  */
-int
-init_module(void)
+static int __init
+nfsd_init(void)
 {
 	printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
+#ifdef MODULE
 	nfsd_linkage = &nfsd_linkage_s;
+#endif
+	nfsd_stat_init();	/* Statistics */
+	nfsd_cache_init();	/* RPC reply cache */
+	nfsd_export_init();	/* Exports table */
+	nfsd_lockd_init();	/* lockd->nfsd callbacks */
+	proc_export_init();
 	return 0;
 }
 
 /*
  * Clean up the mess before unloading the module
  */
-void
-cleanup_module(void)
+static void __exit
+nfsd_exit(void)
 {
+#ifdef MODULE
 	nfsd_linkage = NULL;
+#endif
 	nfsd_export_shutdown();
 	nfsd_cache_shutdown();
 	remove_proc_entry("fs/nfs/exports", NULL);
@@ -340,4 +344,6 @@
 	nfsd_stat_shutdown();
 	nfsd_lockd_shutdown();
 }
-#endif
+
+module_init(nfsd_init);
+module_exit(nfsd_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- linux.orig/fs/nfsd/nfsfh.c	2001-10-04 05:59:22.000000000 +0000
+++ linux/fs/nfsd/nfsfh.c	2002-07-20 01:08:32.000000000 +0000
@@ -576,11 +576,9 @@
 		error = nfserr_stale; 
 		exp = exp_get(rqstp->rq_client, xdev, xino);
 
-		if (!exp) {
+		if (!exp)
 			/* export entry revoked */
-			nfsdstats.fh_stale++;
 			goto out;
-		}
 
 		/* Check if the request originated from a secure port. */
 		error = nfserr_perm;
@@ -657,7 +655,7 @@
 	 * write call).
 	 */
 
-	/* When is type ever negative? */
+	/* Type can be negative to e.g. exclude directories from linking */
 	if (type > 0 && (inode->i_mode & S_IFMT) != type) {
 		error = (type == S_IFDIR)? nfserr_notdir : nfserr_isdir;
 		goto out;
@@ -690,13 +688,11 @@
 				    && !(tdentry->d_inode->i_mode & S_IXOTH)
 					) {
 					error = nfserr_stale;
-					nfsdstats.fh_stale++;
 					dprintk("fh_verify: no root_squashed access.\n");
 				}
 			} while ((tdentry != tdentry->d_parent));
 			if (exp->ex_dentry != tdentry) {
 				error = nfserr_stale;
-				nfsdstats.fh_stale++;
 				printk("nfsd Security: %s/%s bad export.\n",
 				       dentry->d_parent->d_name.name,
 				       dentry->d_name.name);
@@ -716,6 +712,8 @@
 	}
 #endif
 out:
+	if (error == nfserr_stale)
+		nfsdstats.fh_stale++;
 	return error;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfsd/nfssvc.c linux/fs/nfsd/nfssvc.c
--- linux.orig/fs/nfsd/nfssvc.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/nfsd/nfssvc.c	2002-07-20 01:08:22.000000000 +0000
@@ -66,7 +66,7 @@
 /*
  * Maximum number of nfsd processes
  */
-#define	NFSD_MAXSERVS		128
+#define	NFSD_MAXSERVS		8192
 
 int
 nfsd_svc(unsigned short port, int nrservs)
@@ -87,6 +87,7 @@
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
+		error = -ENOMEM;
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE, NFSSVC_XDRSIZE);
 		if (nfsd_serv == NULL)
 			goto out;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
--- linux.orig/fs/nfsd/vfs.c	2001-12-21 17:41:55.000000000 +0000
+++ linux/fs/nfsd/vfs.c	2002-07-20 01:08:33.000000000 +0000
@@ -216,36 +216,37 @@
 	dentry = fhp->fh_dentry;
 	inode = dentry->d_inode;
 
-	err = inode_change_ok(inode, iap);
-	/* could be a "touch" (utimes) request where the user is not the owner but does
-	 * have write permission. In this case the user should be allowed to set
-	 * both times to the current time.  We could just assume any such SETATTR
-	 * is intended to set the times to "now", but we do a couple of simple tests
-	 * to increase our confidence.
+	/* NFSv2 does not differentiate between "set-[ac]time-to-now"
+	 * which only requires access, and "set-[ac]time-to-X" which
+	 * requires ownership.
+	 * So if it looks like it might be "set both to the same time which
+	 * is close to now", and if inode_change_ok fails, then we
+	 * convert to "set to now" instead of "set to explicit time"
+	 *
+	 * We only call inode_change_ok as the last test as technically
+	 * it is not an interface that we should be using.  It is only
+	 * valid if the filesystem does not define it's own i_op->setattr.
 	 */
 #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
 #define	MAX_TOUCH_TIME_ERROR (30*60)
-	if (err
-	    && (iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET
+	if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET
 	    && iap->ia_mtime == iap->ia_atime
 	    ) {
-	    /* looks good.  now just make sure time is in the right ballpark.
-	     * solaris, at least, doesn't seem to care what the time request is
+	    /* Looks probable.  Now just make sure time is in the right ballpark.
+	     * Solaris, at least, doesn't seem to care what the time request is.
+	     * We require it be within 30 minutes of now.
 	     */
 	    time_t delta = iap->ia_atime - CURRENT_TIME;
 	    if (delta<0) delta = -delta;
-	    if (delta < MAX_TOUCH_TIME_ERROR) {
+	    if (delta < MAX_TOUCH_TIME_ERROR &&
+		inode_change_ok(inode, iap) != 0) {
 		/* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME
 		 * this will cause notify_change to set these times to "now"
 		 */
 		iap->ia_valid &= ~BOTH_TIME_SET;
-		err = inode_change_ok(inode, iap);
 	    }
 	}
 	    
-	if (err)
-		goto out_nfserr;
-
 	/* The size case is special. It changes the file as well as the attributes.  */
 	if (iap->ia_valid & ATTR_SIZE) {
 		if (iap->ia_size < inode->i_size) {
@@ -518,24 +519,33 @@
  * As this calls fsync (not fdatasync) there is no need for a write_inode
  * after it.
  */
+inline void nfsd_dosync(struct file *filp, struct dentry *dp, 
+			struct file_operations *fop)
+{
+	struct inode *inode = dp->d_inode;
+	int (*fsync) (struct file *, struct dentry *, int);
+
+	filemap_fdatasync(inode->i_mapping);
+	if (fop && (fsync = fop->fsync))
+		fsync(filp, dp, 0);
+	filemap_fdatawait(inode->i_mapping);
+}
+	
+
 void
 nfsd_sync(struct file *filp)
 {
+	struct inode *inode = filp->f_dentry->d_inode;
 	dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
-	down(&filp->f_dentry->d_inode->i_sem);
-	filp->f_op->fsync(filp, filp->f_dentry, 0);
-	up(&filp->f_dentry->d_inode->i_sem);
+	down(&inode->i_sem);
+	nfsd_dosync(filp, filp->f_dentry, filp->f_op);
+	up(&inode->i_sem);
 }
 
 void
 nfsd_sync_dir(struct dentry *dp)
 {
-	struct inode *inode = dp->d_inode;
-	int (*fsync) (struct file *, struct dentry *, int);
-	
-	if (inode->i_fop && (fsync = inode->i_fop->fsync)) {
-		fsync(NULL, dp, 0);
-	}
+	nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
 }
 
 /*
@@ -1380,7 +1390,6 @@
 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, 
              encode_dent_fn func, u32 *buffer, int *countp, u32 *verf)
 {
-	struct inode	*inode;
 	u32		*p;
 	int		oldlen, eof, err;
 	struct file	file;
@@ -1392,9 +1401,6 @@
 	if (offset > ~(u32) 0)
 		goto out_close;
 
-	err = nfserr_notdir;
-	if (!file.f_op->readdir)
-		goto out_close;
 	file.f_pos = offset;
 
 	/* Set up the readdir context */
@@ -1409,25 +1415,16 @@
 	 * readdir() is not guaranteed to fill up the entire buffer, but
 	 * may choose to do less.
 	 */
-	inode = file.f_dentry->d_inode;
-	down(&inode->i_sem);
-	while (1) {
+
+	do {
 		oldlen = cd.buflen;
 
-		/*
-		dprintk("nfsd: f_op->readdir(%x/%ld @ %d) buflen = %d (%d)\n",
-			file.f_inode->i_dev, file.f_inode->i_ino,
-			(int) file.f_pos, (int) oldlen, (int) cd.buflen);
-		 */
-		err = file.f_op->readdir(&file, &cd, (filldir_t) func);
+		err = vfs_readdir(&file, (filldir_t) func, &cd);
+
 		if (err < 0)
 			goto out_nfserr;
-		if (oldlen == cd.buflen)
-			break;
-		if (cd.eob)
-			break;
-	}
-	up(&inode->i_sem);
+
+	} while (oldlen != cd.buflen && !cd.eob);
 
 	/* If we didn't fill the buffer completely, we're at EOF */
 	eof = !cd.eob;
@@ -1454,7 +1451,6 @@
 	return err;
 
 out_nfserr:
-	up(&inode->i_sem);
 	err = nfserrno(err);
 	goto out_close;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nls/nls_base.c linux/fs/nls/nls_base.c
--- linux.orig/fs/nls/nls_base.c	2001-02-09 19:29:44.000000000 +0000
+++ linux/fs/nls/nls_base.c	2002-07-20 01:08:24.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls.c
+ * linux/fs/nls_base.c
  *
  * Native language support--charsets and unicode translations.
  * By Gordon Chaffee 1996, 1997
@@ -93,7 +93,7 @@
 				ip++;
 				n--;
 			} else {
-				op += size;
+				op++;
 				ip += size;
 				n -= size;
 			}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/nls/nls_koi8-ru.c linux/fs/nls/nls_koi8-ru.c
--- linux.orig/fs/nls/nls_koi8-ru.c	2001-12-21 17:42:03.000000000 +0000
+++ linux/fs/nls/nls_koi8-ru.c	2002-07-20 01:08:21.000000000 +0000
@@ -22,13 +22,14 @@
 	if ((uni & 0xffaf) == 0x040e || (uni & 0xffce) == 0x254c) {
 		/* koi8-ru and koi8-u differ only on two characters */
 		if (uni == 0x040e)
-			return 0xbe;
+			out[0] = 0xbe;
 		else if (uni == 0x045e)
-			return 0xae;
+			out[0] = 0xae;
 		else if (uni == 0x255d || uni == 0x256c)
 			return 0;
 		else
 			return p_nls->uni2char(uni, out, boundlen);
+		return 1;
 	}
 	else
 		/* fast path */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- linux.orig/fs/ntfs/fs.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/ntfs/fs.c	2002-07-20 01:08:27.000000000 +0000
@@ -1090,7 +1090,7 @@
 	/* Inform the kernel about which super operations are available. */
 	sb->s_op = &ntfs_super_operations;
 	sb->s_magic = NTFS_SUPER_MAGIC;
-	sb->s_maxbytes = ~0ULL >> 1;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	ntfs_debug(DEBUG_OTHER, "Reading special files\n");
 	if (ntfs_load_special_files(vol)) {
 		ntfs_error("Error loading special files\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/open.c linux/fs/open.c
--- linux.orig/fs/open.c	2001-10-12 20:48:42.000000000 +0000
+++ linux/fs/open.c	2002-07-20 01:08:24.000000000 +0000
@@ -71,6 +71,30 @@
 	return error;
 }
 
+/*
+ * Install a file pointer in the fd array.  
+ *
+ * The VFS is full of places where we drop the files lock between
+ * setting the open_fds bitmap and installing the file in the file
+ * array.  At any such point, we are vulnerable to a dup2() race
+ * installing a file in the array before us.  We need to detect this and
+ * fput() the struct file we are about to overwrite in this case.
+ *
+ * It should never happen - if we allow dup2() do it, _really_ bad things
+ * will follow.
+ */
+
+void fd_install(unsigned int fd, struct file * file)
+{
+	struct files_struct *files = current->files;
+	
+	write_lock(&files->file_lock);
+	if (files->fd[fd])
+		BUG();
+	files->fd[fd] = file;
+	write_unlock(&files->file_lock);
+}
+
 int do_truncate(struct dentry *dentry, loff_t length)
 {
 	struct inode *inode = dentry->d_inode;
@@ -301,7 +325,8 @@
 		newattrs.ia_mtime = times[1].tv_sec;
 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
 	} else {
-		if ((error = permission(inode,MAY_WRITE)) != 0)
+		if (current->fsuid != inode->i_uid &&
+		    (error = permission(inode,MAY_WRITE)) != 0)
 			goto dput_and_out;
 	}
 	error = notify_change(nd.dentry, &newattrs);
@@ -833,7 +858,7 @@
 		retval = filp->f_op->flush(filp);
 		unlock_kernel();
 	}
-	fcntl_dirnotify(0, filp, 0);
+	dnotify_flush(filp, id);
 	locks_remove_posix(filp, id);
 	fput(filp);
 	return retval;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/partitions/Makefile linux/fs/partitions/Makefile
--- linux.orig/fs/partitions/Makefile	2001-07-26 23:30:04.000000000 +0000
+++ linux/fs/partitions/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -9,7 +9,7 @@
 
 O_TARGET := partitions.o
 
-export-objs := check.o ibm.o
+export-objs := check.o msdos.o
 
 obj-y := check.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/partitions/acorn.c linux/fs/partitions/acorn.c
--- linux.orig/fs/partitions/acorn.c	2001-10-02 03:03:26.000000000 +0000
+++ linux/fs/partitions/acorn.c	2002-07-20 01:08:24.000000000 +0000
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/genhd.h>
 #include <linux/fs.h>
+#include <linux/pagemap.h>
 
 #include "check.h"
 #include "acorn.h"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/partitions/check.c linux/fs/partitions/check.c
--- linux.orig/fs/partitions/check.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/partitions/check.c	2002-07-20 01:08:32.000000000 +0000
@@ -77,13 +77,17 @@
 
 /*
  *	This is ucking fugly but its probably the best thing for 2.4.x
- *	Take it as a clear reminder than we should put the device name
+ *	Take it as a clear reminder that: 1) we should put the device name
  *	generation in the object kdev_t points to in 2.5.
+ *	and 2) ioctls better work on half-opened devices.
  */
  
 #ifdef CONFIG_ARCH_S390
 int (*genhd_dasd_name)(char*,int,int,struct gendisk*) = NULL;
+int (*genhd_dasd_ioctl)(struct inode *inp, struct file *filp,
+			    unsigned int no, unsigned long data);
 EXPORT_SYMBOL(genhd_dasd_name);
+EXPORT_SYMBOL(genhd_dasd_ioctl);
 #endif
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/partitions/ibm.c linux/fs/partitions/ibm.c
--- linux.orig/fs/partitions/ibm.c	2001-10-02 03:03:26.000000000 +0000
+++ linux/fs/partitions/ibm.c	2002-07-20 01:08:35.000000000 +0000
@@ -8,6 +8,7 @@
  * History of changes (starts July 2000)
  * 07/10/00 Fixed detection of CMS formatted disks     
  * 02/13/00 VTOC partition support added
+ * 12/27/01 fixed PL030593 (CMS reserved minidisk not detected on 64 bit)
  */
 
 #include <linux/config.h>
@@ -29,47 +30,6 @@
 #include "check.h"
 #include <asm/vtoc.h>
 
-typedef enum {
-  ibm_partition_lnx1 = 0,
-  ibm_partition_vol1 = 1,
-  ibm_partition_cms1 = 2,
-  ibm_partition_none = 3
-} ibm_partition_t;
-
-static char* part_names[] = {   [ibm_partition_lnx1] = "LNX1",
-			     [ibm_partition_vol1] = "VOL1",
-			     [ibm_partition_cms1] = "CMS1",
-			     [ibm_partition_none] = "(nonl)"
-};
-
-static ibm_partition_t
-get_partition_type ( char * type )
-{
-	int i;
-	for ( i = 0; i < 3; i ++) {
-		if ( ! strncmp (type,part_names[i],4) ) 
-			break;
-	}
-        return i;
-}
-
-/*
- * add the two default partitions
- * - whole dasd
- * - whole dasd without "offset"
- */
-static inline void
-two_partitions(struct gendisk *hd,
-	       int minor,
-	       int blocksize,
-	       int offset,
-	       int size) {
-
-        add_gd_partition( hd, minor, 0, size);
-	add_gd_partition( hd, minor+1, offset*blocksize, size-offset*blocksize);
-}
-
-
 /*
  * compute the block number from a 
  * cyl-cyl-head-head structure
@@ -92,119 +52,185 @@
 		ptr->b;
 }
 
+/*
+ * We used to use ioctl_by_bdev in early 2.4, but it broke
+ * between 2.4.9 and 2.4.18 somewhere.
+ */
+extern int (*genhd_dasd_ioctl)(struct inode *inp, struct file *filp,
+                            unsigned int no, unsigned long data);
+
+static int
+ibm_ioctl_unopened(struct block_device *bdev, unsigned cmd, unsigned long arg)
+{
+	int res;
+	mm_segment_t old_fs = get_fs();
+
+	if (genhd_dasd_ioctl == NULL)
+		return -ENODEV;
+#if 0
+	lock_kernel();
+	if (bd_ops->owner)
+		__MOD_INC_USE_COUNT(bdev->bd_op->owner);
+	unlock_kernel();
+#endif
+	set_fs(KERNEL_DS);
+	res = (*genhd_dasd_ioctl)(bdev->bd_inode, NULL, cmd, arg);
+	set_fs(old_fs);
+#if 0
+	lock_kernel();
+	if (bd_ops->owner)
+		__MOD_DEV_USE_COUNT(bd_ops->owner);
+	unlock_kernel();
+#endif
+	return res;
+}
+
+/*
+ */
 int 
 ibm_partition(struct gendisk *hd, struct block_device *bdev,
-		unsigned long first_sector, int first_part_minor)
+	      unsigned long first_sector, int first_part_minor)
 {
-	Sector sect, sect2;
-	unsigned char *data;
-	ibm_partition_t partition_type;
+	int blocksize, offset, size;
+	dasd_information_t *info;
+	struct hd_geometry *geo;
 	char type[5] = {0,};
 	char name[7] = {0,};
-	struct hd_geometry *geo;
-	int blocksize;
-	int offset=0, size=0, psize=0, counter=0;
-	unsigned int blk;
-	format1_label_t f1;
-	volume_label_t vlabel;
-	dasd_information_t *info;
-	kdev_t dev = to_kdev_t(bdev->bd_dev);
+	volume_label_t *vlabel;
+	unsigned char *data;
+	Sector sect;
 
 	if ( first_sector != 0 )
 		BUG();
 
-	info = (struct dasd_information_t *)kmalloc(sizeof(dasd_information_t),
-						    GFP_KERNEL);
-	if ( info == NULL )
-		return 0;
-	if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)(info)))
-		return 0;
-	geo = (struct hd_geometry *)kmalloc(sizeof(struct hd_geometry),
-					    GFP_KERNEL);
-	if ( geo == NULL )
-		return 0;
-	if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo);
-		return 0;
-	blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
-	if ( blocksize <= 0 ) {
-		return 0;
-	}
-	blocksize >>= 9;
-	
-	data = read_dev_sector(bdev, inode->label_block*blocksize, &sect);
-	if (!data)
-		return 0;
-
+	if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL)
+		goto out_noinfo;
+	if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
+		goto out_nogeo;
+	if ((vlabel = kmalloc(sizeof(volume_label_t), GFP_KERNEL)) == NULL)
+		goto out_novlab;
+
+	if (ibm_ioctl_unopened(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
+	    ibm_ioctl_unopened(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
+		goto out_noioctl;
+
+	if ((blocksize = get_hardsect_size(to_kdev_t(bdev->bd_dev))) <= 0)
+		goto out_badsect;
+
+	/*
+	 * Get volume label, extract name and type.
+	 */
+	data = read_dev_sector(bdev, info->label_block*(blocksize/512), &sect);
+	if (data == NULL)
+		goto out_readerr;
 	strncpy (type, data, 4);
-	if ((!info->FBA_layout) && (!strcmp(info->type,"ECKD"))) {
-		strncpy ( name, data + 8, 6);
-	} else {
-		strncpy ( name, data + 4, 6);
-	}
-	memcpy (&vlabel, data, sizeof(volume_label_t));
+	if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD")))
+		strncpy(name, data + 8, 6);
+	else
+		strncpy(name, data + 4, 6);
+	memcpy (vlabel, data, sizeof(volume_label_t));
+	put_dev_sector(sect);
+
+	EBCASC(type, 4);
+	EBCASC(name, 6);
+
+	/*
+	 * Three different types: CMS1, VOL1 and LNX1/unlabeled
+	 */
+	if (strncmp(type, "CMS1", 4) == 0) {
+		/*
+		 * VM style CMS1 labeled disk
+		 */
+		int *label = (int *) data;
 
-	EBCASC(type,4);
-	EBCASC(name,6);
-	
-	partition_type = get_partition_type(type);
-	printk ( "%4s/%8s:",part_names[partition_type],name);
-	switch ( partition_type ) {
-	case ibm_partition_cms1:
-		if (* ((long *)data + 13) != 0) {
+		if (label[13] != 0) {
+			printk("CMS1/%8s(MDSK):", name);
 			/* disk is reserved minidisk */
-			long *label=(long*)data;
-			blocksize = label[3]>>9;
+			blocksize = label[3];
 			offset = label[13];
-			size = (label[7]-1)*blocksize; 
-			printk ("(MDSK)");
+			size = (label[7] - 1)*(blocksize >> 9);
 		} else {
+			printk("CMS1/%8s:", name);
 			offset = (info->label_block + 1);
-			size = hd -> sizes[MINOR(dev)]<<1;
+			size = bdev->bd_inode->i_size >> 9;
 		}
-		two_partitions( hd, MINOR(dev), blocksize, offset, size);
-		break;
-	case ibm_partition_lnx1: 
-	case ibm_partition_none:
-		offset = (info->label_block + 1);
-		size = hd -> sizes[MINOR(dev)]<<1;
-		two_partitions( hd, MINOR(dev), blocksize, offset, size);
-		break;
-	case ibm_partition_vol1: 
-		size = hd -> sizes[MINOR(dev)]<<1;
-		add_gd_partition(hd, MINOR(dev), 0, size);
-		
-		/* get block number and read then first format1 label */
-		blk = cchhb2blk(&vlabel.vtoc, geo) + 1;
-		data = read_dev_sector(bdev, blk * blocksize, &sect2);
-		if (data) {
-		        memcpy (&f1, data, sizeof(format1_label_t));
-			put_dev_sector(sect2);
-		}
-		
-		while (f1.DS1FMTID == _ascebc['1']) {
+		// add_gd_partition(hd, first_part_minor - 1, 0, size);
+		add_gd_partition(hd, first_part_minor,
+				 offset*(blocksize >> 9),
+				 size-offset*(blocksize >> 9));
+	} else if (strncmp(type, "VOL1", 4) == 0) {
+		/*
+		 * New style VOL1 labeled disk
+		 */
+		unsigned int blk;
+		int counter;
+
+		printk("VOL1/%8s:", name);
+
+		/* get block number and read then go through format1 labels */
+		blk = cchhb2blk(&vlabel->vtoc, geo) + 1;
+		counter = 0;
+		while ((data = read_dev_sector(bdev, blk*(blocksize/512),
+					       &sect)) != NULL) {
+			format1_label_t f1;
+
+			memcpy(&f1, data, sizeof(format1_label_t));
+			put_dev_sector(sect);
+
+			/* skip FMT4 / FMT5 / FMT7 labels */
+			if (f1.DS1FMTID == _ascebc['4']
+			    || f1.DS1FMTID == _ascebc['5']
+			    || f1.DS1FMTID == _ascebc['7']) {
+			        blk++;
+				continue;
+			}
+
+			/* only FMT1 valid at this point */
+			if (f1.DS1FMTID != _ascebc['1'])
+				break;
+
+			/* OK, we got valid partition data */
 		        offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
-			psize  = cchh2blk(&f1.DS1EXT1.ulimit, geo) - 
+			size  = cchh2blk(&f1.DS1EXT1.ulimit, geo) - 
 				offset + geo->sectors;
-			
+			if (counter >= hd->max_p)
+				break;
+			add_gd_partition(hd, first_part_minor + counter, 
+					 offset * (blocksize >> 9),
+					 size * (blocksize >> 9));
 			counter++;
-			add_gd_partition(hd, MINOR(dev) + counter, 
-					 offset * blocksize,
-					 psize * blocksize);
-			
 			blk++;
-			data = read_dev_sector(bdev, blk * blocksize, &sect2);
-			if (data) {
-			        memcpy (&f1, data, sizeof(format1_label_t));
-				put_dev_sector(sect2);
-			}
 		}
-		break;
-	default:
-		add_gd_partition( hd, MINOR(dev), 0, 0);
-		add_gd_partition( hd, MINOR(dev) + 1, 0, 0);
+	} else {
+		/*
+		 * Old style LNX1 or unlabeled disk
+		 */
+		if (strncmp(type, "LNX1", 4) == 0)
+			printk ("LNX1/%8s:", name);
+		else
+			printk("(nonl)/%8s:", name);
+		offset = (info->label_block + 1);
+		size = (bdev->bd_inode->i_size >> 9);
+		// add_gd_partition(hd, first_part_minor - 1, 0, size);
+		add_gd_partition(hd, first_part_minor,
+				 offset*(blocksize >> 9),
+				  size-offset*(blocksize >> 9));
 	}
-	
-	printk ( "\n" );
-	put_dev_sector(sect);
+
+	printk("\n");
+	kfree(vlabel);
+	kfree(geo);
+	kfree(info);
 	return 1;
+
+out_readerr:
+out_badsect:
+out_noioctl:
+	kfree(vlabel);
+out_novlab:
+	kfree(geo);
+out_nogeo:
+	kfree(info);
+out_noinfo:
+	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/partitions/ldm.c linux/fs/partitions/ldm.c
--- linux.orig/fs/partitions/ldm.c	2001-11-12 17:43:11.000000000 +0000
+++ linux/fs/partitions/ldm.c	2002-07-20 01:08:33.000000000 +0000
@@ -29,6 +29,7 @@
 #include <linux/genhd.h>
 #include <linux/blkdev.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 #include "check.h"
 #include "ldm.h"
 #include "msdos.h"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/partitions/mac.c linux/fs/partitions/mac.c
--- linux.orig/fs/partitions/mac.c	2001-10-02 03:03:26.000000000 +0000
+++ linux/fs/partitions/mac.c	2002-07-20 01:08:28.000000000 +0000
@@ -20,22 +20,10 @@
 #include "check.h"
 #include "mac.h"
 
-#ifdef CONFIG_ALL_PPC
-extern void note_bootable_part(kdev_t dev, int part, int goodness);
-#endif
-
 /*
  * Code to understand MacOS partition tables.
  */
 
-static inline void mac_fix_string(char *stg, int len)
-{
-	int i;
-
-	for (i = len - 1; i >= 0 && stg[i] == ' '; i--)
-		stg[i] = 0;
-}
-
 int mac_partition(struct gendisk *hd, struct block_device *bdev,
 		unsigned long fsec, int first_part_minor)
 {
@@ -43,10 +31,6 @@
 	unsigned char *data;
 	int blk, blocks_in_map;
 	unsigned secsize;
-#ifdef CONFIG_ALL_PPC
-	int found_root = 0;
-	int found_root_goodness = 0;
-#endif
 	struct mac_partition *part;
 	struct mac_driver_desc *md;
 
@@ -83,56 +67,8 @@
 			fsec + be32_to_cpu(part->start_block) * (secsize/512),
 			be32_to_cpu(part->block_count) * (secsize/512));
 
-#ifdef CONFIG_ALL_PPC
-		/*
-		 * If this is the first bootable partition, tell the
-		 * setup code, in case it wants to make this the root.
-		 */
-		if (_machine == _MACH_Pmac) {
-			int goodness = 0;
-
-			mac_fix_string(part->processor, 16);
-			mac_fix_string(part->name, 32);
-			mac_fix_string(part->type, 32);					
-		    
-			if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
-			    && strcasecmp(part->processor, "powerpc") == 0)
-				goodness++;
-
-			if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
-			    || (strnicmp(part->type, "Linux", 5) == 0
-			        && strcasecmp(part->type, "Linux_swap") != 0)) {
-				int i, l;
-
-				goodness++;
-				l = strlen(part->name);
-				if (strcmp(part->name, "/") == 0)
-					goodness++;
-				for (i = 0; i <= l - 4; ++i) {
-					if (strnicmp(part->name + i, "root",
-						     4) == 0) {
-						goodness += 2;
-						break;
-					}
-				}
-				if (strnicmp(part->name, "swap", 4) == 0)
-					goodness--;
-			}
-
-			if (goodness > found_root_goodness) {
-				found_root = blk;
-				found_root_goodness = goodness;
-			}
-		}
-#endif /* CONFIG_ALL_PPC */
-
 		++first_part_minor;
 	}
-#ifdef CONFIG_ALL_PPC
-	if (found_root_goodness)
-		note_bootable_part(to_kdev_t(bdev->bd_dev),
-					found_root, found_root_goodness);
-#endif
 
 	put_dev_sector(sect);
 	printk("\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/partitions/mac.h linux/fs/partitions/mac.h
--- linux.orig/fs/partitions/mac.h	2001-10-02 03:03:26.000000000 +0000
+++ linux/fs/partitions/mac.h	2002-07-20 01:08:38.000000000 +0000
@@ -29,6 +29,14 @@
 	/* there is more stuff after this that we don't need */
 };
 
+static inline void macpart_fix_string(char *stg, int len)
+{
+	int i;
+
+	for (i = len - 1; i >= 0 && stg[i] == ' '; i--)
+		stg[i] = 0;
+}
+
 #define MAC_STATUS_BOOTABLE	8	/* partition is bootable */
 
 #define MAC_DRIVER_MAGIC	0x4552
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/partitions/msdos.c linux/fs/partitions/msdos.c
--- linux.orig/fs/partitions/msdos.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/partitions/msdos.c	2002-07-20 01:08:24.000000000 +0000
@@ -29,7 +29,13 @@
 
 #ifdef CONFIG_BLK_DEV_IDE
 #include <linux/ide.h>	/* IDE xlate */
-#endif /* CONFIG_BLK_DEV_IDE */
+#elif defined(CONFIG_BLK_DEV_IDE_MODULE)
+#include <linux/module.h>
+
+int (*ide_xlate_1024_hook)(kdev_t, int, int, const char *);
+EXPORT_SYMBOL(ide_xlate_1024_hook);
+#define ide_xlate_1024 ide_xlate_1024_hook
+#endif
 
 #include <asm/system.h>
 
@@ -66,13 +72,13 @@
 }
 
 /*
- * partition_name() formats the short partition name into the supplied
+ * msdos_partition_name() formats the short partition name into the supplied
  * buffer, and returns a pointer to that buffer.
  * Used by several partition types which makes conditional inclusion messy,
  * use __attribute__ ((unused)) instead.
  */
 static char __attribute__ ((unused))
-	*partition_name (struct gendisk *hd, int minor, char *buf)
+	*msdos_partition_name (struct gendisk *hd, int minor, char *buf)
 {
 #ifdef CONFIG_DEVFS_FS
 	sprintf(buf, "p%d", (minor & ((1 << hd->minor_shift) - 1)));
@@ -225,7 +231,7 @@
 		put_dev_sector(sect);
 		return;
 	}
-	printk(" %s: <solaris:", partition_name(hd, minor, buf));
+	printk(" %s: <solaris:", msdos_partition_name(hd, minor, buf));
 	if (le32_to_cpu(v->v_version) != 1) {
 		printk("  cannot handle version %d vtoc>\n",
 			le32_to_cpu(v->v_version));
@@ -319,7 +325,7 @@
 		put_dev_sector(sect);
 		return;
 	}
-	printk(" %s: <%s:", partition_name(hd, minor, buf), name);
+	printk(" %s: <%s:", msdos_partition_name(hd, minor, buf), name);
 
 	if (le16_to_cpu(l->d_npartitions) < max_partitions)
 		max_partitions = le16_to_cpu(l->d_npartitions);
@@ -385,7 +391,7 @@
 		put_dev_sector(sect);
 		return;
 	}
-	printk(" %s: <unixware:", partition_name(hd, minor, buf));
+	printk(" %s: <unixware:", msdos_partition_name(hd, minor, buf));
 	p = &l->vtoc.v_slice[1];
 	/* I omit the 0th slice as it is the same as whole disk. */
 	while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
@@ -433,7 +439,7 @@
 	if (msdos_magic_present (data + 510) &&
 	    SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */
 
-		printk(" %s: <minix:", partition_name(hd, minor, buf));
+		printk(" %s: <minix:", msdos_partition_name(hd, minor, buf));
 		for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) {
 			if ((*current_minor & mask) == 0)
 				break;
@@ -467,7 +473,7 @@
  */
 static int handle_ide_mess(struct block_device *bdev)
 {
-#ifdef CONFIG_BLK_DEV_IDE
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
 	Sector sect;
 	unsigned char *data;
 	kdev_t dev = to_kdev_t(bdev->bd_dev);
@@ -475,6 +481,10 @@
 	int heads = 0;
 	struct partition *p;
 	int i;
+#ifdef CONFIG_BLK_DEV_IDE_MODULE
+	if (!ide_xlate_1024)
+		return 1;
+#endif
 	/*
 	 * The i386 partition handling programs very often
 	 * make partitions end on cylinder boundaries.
@@ -536,7 +546,7 @@
 	/* Flush the cache */
 	invalidate_bdev(bdev, 1);
 	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
-#endif /* CONFIG_BLK_DEV_IDE */
+#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
 	return 1;
 }
  
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/pipe.c linux/fs/pipe.c
--- linux.orig/fs/pipe.c	2001-09-29 01:03:48.000000000 +0000
+++ linux/fs/pipe.c	2002-07-20 01:08:21.000000000 +0000
@@ -129,6 +129,8 @@
 out_nolock:
 	if (read)
 		ret = read;
+
+	UPDATE_ATIME(inode);
 	return ret;
 }
 
@@ -246,12 +248,6 @@
 	return -EPIPE;
 }
 
-static loff_t
-pipe_lseek(struct file *file, loff_t offset, int orig)
-{
-	return -ESPIPE;
-}
-
 static ssize_t
 bad_pipe_r(struct file *filp, char *buf, size_t count, loff_t *ppos)
 {
@@ -381,7 +377,7 @@
  * are also used in linux/fs/fifo.c to do operations on FIFOs.
  */
 struct file_operations read_fifo_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		pipe_read,
 	write:		bad_pipe_w,
 	poll:		fifo_poll,
@@ -391,7 +387,7 @@
 };
 
 struct file_operations write_fifo_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		bad_pipe_r,
 	write:		pipe_write,
 	poll:		fifo_poll,
@@ -401,7 +397,7 @@
 };
 
 struct file_operations rdwr_fifo_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		pipe_read,
 	write:		pipe_write,
 	poll:		fifo_poll,
@@ -411,7 +407,7 @@
 };
 
 struct file_operations read_pipe_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		pipe_read,
 	write:		bad_pipe_w,
 	poll:		pipe_poll,
@@ -421,7 +417,7 @@
 };
 
 struct file_operations write_pipe_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		bad_pipe_r,
 	write:		pipe_write,
 	poll:		pipe_poll,
@@ -431,7 +427,7 @@
 };
 
 struct file_operations rdwr_pipe_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		pipe_read,
 	write:		pipe_write,
 	poll:		pipe_poll,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/proc/array.c linux/fs/proc/array.c
--- linux.orig/fs/proc/array.c	2001-10-11 16:00:01.000000000 +0000
+++ linux/fs/proc/array.c	2002-07-20 01:08:23.000000000 +0000
@@ -226,6 +226,8 @@
 	sigemptyset(ign);
 	sigemptyset(catch);
 
+	spin_lock_irq(&p->sigmask_lock);
+
 	if (p->sig) {
 		k = p->sig->action;
 		for (i = 1; i <= _NSIG; ++i, ++k) {
@@ -235,6 +237,7 @@
 				sigaddset(catch, i);
 		}
 	}
+	spin_unlock_irq(&p->sigmask_lock);
 }
 
 static inline char * task_sig(struct task_struct *p, char *buffer)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/proc/base.c linux/fs/proc/base.c
--- linux.orig/fs/proc/base.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/proc/base.c	2002-07-20 01:08:24.000000000 +0000
@@ -23,6 +23,8 @@
 #include <linux/init.h>
 #include <linux/file.h>
 #include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/namespace.h>
 
 /*
  * For hysterical raisins we keep the same inumbers as in the old procfs.
@@ -246,6 +248,46 @@
 	read:		pid_maps_read,
 };
 
+extern struct seq_operations mounts_op;
+static int mounts_open(struct inode *inode, struct file *file)
+{
+	struct task_struct *task = inode->u.proc_i.task;
+	int ret = seq_open(file, &mounts_op);
+
+	if (!ret) {
+		struct seq_file *m = file->private_data;
+		struct namespace *namespace;
+		task_lock(task);
+		namespace = task->namespace;
+		if (namespace)
+			get_namespace(namespace);
+		task_unlock(task);
+
+		if (namespace)
+			m->private = namespace;
+		else {
+			seq_release(inode, file);
+			ret = -EINVAL;
+		}
+	}
+	return ret;
+}
+
+static int mounts_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *m = file->private_data;
+	struct namespace *namespace = m->private;
+	put_namespace(namespace);
+	return seq_release(inode, file);
+}
+
+static struct file_operations proc_mounts_operations = {
+	open:		mounts_open,
+	read:		seq_read,
+	llseek:		seq_lseek,
+	release:	mounts_release,
+};
+
 #define PROC_BLOCK_SIZE	(3*1024)		/* 4K page size but our output routines use some slack for overruns */
 
 static ssize_t proc_info_read(struct file * file, char * buf,
@@ -497,6 +539,7 @@
 	PROC_PID_STATM,
 	PROC_PID_MAPS,
 	PROC_PID_CPU,
+	PROC_PID_MOUNTS,
 	PROC_PID_FD_DIR = 0x8000,	/* 0x8000-0xffff */
 };
 
@@ -516,6 +559,7 @@
   E(PROC_PID_CWD,	"cwd",		S_IFLNK|S_IRWXUGO),
   E(PROC_PID_ROOT,	"root",		S_IFLNK|S_IRWXUGO),
   E(PROC_PID_EXE,	"exe",		S_IFLNK|S_IRWXUGO),
+  E(PROC_PID_MOUNTS,	"mounts",	S_IFREG|S_IRUGO),
   {0,0,NULL,0}
 };
 #undef E
@@ -881,6 +925,9 @@
 			inode->i_op = &proc_mem_inode_operations;
 			inode->i_fop = &proc_mem_operations;
 			break;
+		case PROC_PID_MOUNTS:
+			inode->i_fop = &proc_mounts_operations;
+			break;
 		default:
 			printk("procfs: impossible type (%d)",p->type);
 			iput(inode);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/proc/kcore.c linux/fs/proc/kcore.c
--- linux.orig/fs/proc/kcore.c	2001-09-13 23:04:43.000000000 +0000
+++ linux/fs/proc/kcore.c	2002-07-20 01:08:21.000000000 +0000
@@ -381,8 +381,13 @@
 			return tsz;
 	}
 #endif
-	/* fill the remainder of the buffer from kernel VM space */
-	start = (unsigned long)__va(*fpos - elf_buflen);
+	
+	/*
+	 * Fill the remainder of the buffer from kernel VM space.
+	 * We said in the ELF header that the data which starts
+	 * at 'elf_buflen' is virtual address PAGE_OFFSET. --rmk
+	 */
+	start = PAGE_OFFSET + (*fpos - elf_buflen);
 	if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
 		tsz = buflen;
 		
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/proc/proc_misc.c linux/fs/proc/proc_misc.c
--- linux.orig/fs/proc/proc_misc.c	2001-11-21 05:29:09.000000000 +0000
+++ linux/fs/proc/proc_misc.c	2002-07-20 01:08:26.000000000 +0000
@@ -41,7 +41,6 @@
 #include <asm/pgtable.h>
 #include <asm/io.h>
 
-
 #define LOAD_INT(x) ((x) >> FSHIFT)
 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
 /*
@@ -50,6 +49,8 @@
  * have a way to deal with that gracefully. Right now I used straightforward
  * wrappers, but this needs further analysis wrt potential overflows.
  */
+extern int get_hardware_list(char *);
+extern int get_stram_list(char *);
 #ifdef CONFIG_MODULES
 extern int get_module_list(char *);
 #endif
@@ -65,6 +66,27 @@
 extern int get_ds1286_status(char *);
 #endif
 
+void proc_sprintf(char *page, off_t *off, int *lenp, const char *format, ...)
+{
+	int len = *lenp;
+	va_list args;
+
+	/* try to only print whole lines */
+	if (len > PAGE_SIZE-512)
+		return;
+
+	va_start(args, format);
+	len += vsnprintf(page + len, PAGE_SIZE-len, format, args);
+	va_end(args);
+
+	if (len <= *off) {
+		*off -= len;
+		len = 0;
+	}
+
+	*lenp = len;
+}
+
 static int proc_calc_metrics(char *page, char **start, off_t off,
 				 int count, int *eof, int len)
 {
@@ -214,6 +236,24 @@
 	release:	seq_release,
 };
 
+#ifdef CONFIG_PROC_HARDWARE
+static int hardware_read_proc(char *page, char **start, off_t off,
+				 int count, int *eof, void *data)
+{
+	int len = get_hardware_list(page);
+	return proc_calc_metrics(page, start, off, count, eof, len);
+}
+#endif
+
+#ifdef CONFIG_STRAM_PROC
+static int stram_read_proc(char *page, char **start, off_t off,
+				 int count, int *eof, void *data)
+{
+	int len = get_stram_list(page);
+	return proc_calc_metrics(page, start, off, count, eof, len);
+}
+#endif
+
 #ifdef CONFIG_MODULES
 static int modules_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
@@ -235,10 +275,24 @@
 };
 #endif
 
+extern struct seq_operations slabinfo_op;
+extern ssize_t slabinfo_write(struct file *, const char *, size_t, loff_t *);
+static int slabinfo_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &slabinfo_op);
+}
+static struct file_operations proc_slabinfo_operations = {
+	open:		slabinfo_open,
+	read:		seq_read,
+	write:		slabinfo_write,
+	llseek:		seq_lseek,
+	release:	seq_release,
+};
+
 static int kstat_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
-	int i, len;
+	int i, len = 0;
 	extern unsigned long total_forks;
 	unsigned long jif = jiffies;
 	unsigned int sum = 0, user = 0, nice = 0, system = 0;
@@ -256,10 +310,12 @@
 #endif
 	}
 
-	len = sprintf(page, "cpu  %u %u %u %lu\n", user, nice, system,
+	proc_sprintf(page, &off, &len,
+		      "cpu  %u %u %u %lu\n", user, nice, system,
 		      jif * smp_num_cpus - (user + nice + system));
 	for (i = 0 ; i < smp_num_cpus; i++)
-		len += sprintf(page + len, "cpu%d %u %u %u %lu\n",
+		proc_sprintf(page, &off, &len,
+			"cpu%d %u %u %u %lu\n",
 			i,
 			kstat.per_cpu_user[cpu_logical_map(i)],
 			kstat.per_cpu_nice[cpu_logical_map(i)],
@@ -267,7 +323,7 @@
 			jif - (  kstat.per_cpu_user[cpu_logical_map(i)] \
 				   + kstat.per_cpu_nice[cpu_logical_map(i)] \
 				   + kstat.per_cpu_system[cpu_logical_map(i)]));
-	len += sprintf(page + len,
+	proc_sprintf(page, &off, &len,
 		"page %u %u\n"
 		"swap %u %u\n"
 		"intr %u",
@@ -279,10 +335,11 @@
 	);
 #if !defined(CONFIG_ARCH_S390)
 	for (i = 0 ; i < NR_IRQS ; i++)
-		len += sprintf(page + len, " %u", kstat_irqs(i));
+		proc_sprintf(page, &off, &len,
+			     " %u", kstat_irqs(i));
 #endif
 
-	len += sprintf(page + len, "\ndisk_io: ");
+	proc_sprintf(page, &off, &len, "\ndisk_io: ");
 
 	for (major = 0; major < DK_MAX_MAJOR; major++) {
 		for (disk = 0; disk < DK_MAX_DISK; disk++) {
@@ -290,7 +347,7 @@
 				kstat.dk_drive_rblk[major][disk] +
 				kstat.dk_drive_wblk[major][disk];
 			if (active)
-				len += sprintf(page + len,
+				proc_sprintf(page, &off, &len,
 					"(%u,%u):(%u,%u,%u,%u,%u) ",
 					major, disk,
 					kstat.dk_drive[major][disk],
@@ -302,7 +359,7 @@
 		}
 	}
 
-	len += sprintf(page + len,
+	proc_sprintf(page, &off, &len,
 		"\nctxt %u\n"
 		"btime %lu\n"
 		"processes %lu\n",
@@ -364,8 +421,7 @@
 	extern char saved_command_line[];
 	int len;
 
-	len = sprintf(page, "%s\n", saved_command_line);
-	len = strlen(page);
+	len = snprintf(page, count, "%s\n", saved_command_line);
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
@@ -473,18 +529,6 @@
 	write:		write_profile,
 };
 
-extern struct seq_operations mounts_op;
-static int mounts_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &mounts_op);
-}
-static struct file_operations proc_mounts_operations = {
-	open:		mounts_open,
-	read:		seq_read,
-	llseek:		seq_lseek,
-	release:	seq_release,
-};
-
 struct proc_dir_entry *proc_root_kcore;
 
 static void create_seq_entry(char *name, mode_t mode, struct file_operations *f)
@@ -506,6 +550,12 @@
 		{"uptime",	uptime_read_proc},
 		{"meminfo",	meminfo_read_proc},
 		{"version",	version_read_proc},
+#ifdef CONFIG_PROC_HARDWARE
+		{"hardware",	hardware_read_proc},
+#endif
+#ifdef CONFIG_STRAM_PROC
+		{"stram",	stram_read_proc},
+#endif
 #ifdef CONFIG_MODULES
 		{"modules",	modules_read_proc},
 #endif
@@ -531,12 +581,14 @@
 	for (p = simple_ones; p->name; p++)
 		create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
 
+	proc_symlink("mounts", NULL, "self/mounts");
+
 	/* And now for trickier ones */
 	entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
 	if (entry)
 		entry->proc_fops = &proc_kmsg_operations;
-	create_seq_entry("mounts", 0, &proc_mounts_operations);
 	create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
+	create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
 #ifdef CONFIG_MODULES
 	create_seq_entry("ksyms", 0, &proc_ksyms_operations);
 #endif
@@ -561,8 +613,4 @@
 			entry->proc_fops = &ppc_htab_operations;
 	}
 #endif
-	entry = create_proc_read_entry("slabinfo", S_IWUSR | S_IRUGO, NULL,
-				       slabinfo_read_proc, NULL);
-	if (entry)
-		entry->write_proc = slabinfo_write_proc;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/proc/root.c linux/fs/proc/root.c
--- linux.orig/fs/proc/root.c	2001-10-21 02:14:42.000000000 +0000
+++ linux/fs/proc/root.c	2002-07-20 01:08:29.000000000 +0000
@@ -58,6 +58,12 @@
 #ifdef CONFIG_PROC_DEVICETREE
 	proc_device_tree_init();
 #endif
+#ifdef CONFIG_PPC_ISERIES
+	iSeries_proc_create();
+#endif
+#ifdef CONFIG_PPC64
+	proc_ppc64_init(); 
+#endif
 #ifdef CONFIG_PPC_RTAS
 	proc_rtas_init();
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/qnx4/BUGS linux/fs/qnx4/BUGS
--- linux.orig/fs/qnx4/BUGS	1999-12-23 01:38:27.000000000 +0000
+++ linux/fs/qnx4/BUGS	1970-01-01 00:00:00.000000000 +0000
@@ -1,30 +0,0 @@
-Last update: 1999-12-23
-
-- Fragmented files and directories were incorrectly handled.
-  Fixed 1999-12-23, Anders.
-
-- readdir sometimes returned the same dir entry more than once.
-  Fixed 1999-12-13, Anders.
-
-- File names with a length of exactly 16 chars were handled incorrectly.
-  Fixed 1999-12-11, Anders.
-
-- Files in a subdir can't be accessed, I think that the inode information
-  is not correctly copied at some point. Solved 06-06-1998, Richard.
-  
-- At some point the mounted device can't be unmounted. I think that somewhere
-  in the code a buffer is not given free.
-
-- Make the '..' entry work, I give it a great chance that the above bug
-  (not given free) has something to do with this one, after a 'ls -l'
-  the mounted device can't be unmounted and that's where the '..' entry
-  is accessed.
-  Seems to be solved 21-06-1998, Frank.
-
-- File read function not correct, after the first block it goes beserk.
-  Solved 21-06-1998, Frank.
-
-- This fs will not work if not built as a module.
-  Solved 25-06-1998, Frank.
-
-- Write/truncate/delete functions don't update the bitmap.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/qnx4/TODO linux/fs/qnx4/TODO
--- linux.orig/fs/qnx4/TODO	1999-12-23 01:38:27.000000000 +0000
+++ linux/fs/qnx4/TODO	1970-01-01 00:00:00.000000000 +0000
@@ -1,30 +0,0 @@
-Name       : QNX4 TODO list
-Last update: 1999-12-23
-
-    - Writing is still unsupported (it may compile, but it certainly won't
-      bring you any joy).
-
-    - qnx4_checkroot (inode.c), currently there's a look for the '/' in
-      the root direntry, if so then the current mounted device is a qnx4
-      partition. This has to be rewritten with a look for 'QNX4' in the
-      bootblock, it seems to me the savest way to ensure that the mounted
-      device is in fact a QNX4 partition.
-      Done 20-06-1998, Frank. But some disks (like QNX install floppies)
-      don't have 'QNX4' in their bootblock.
-      
-    - Bitmap functions. To find out the free space, largest free block, etc.
-      Partly done (RO), Richard, 05/06/1998. Optimized 20-06-1998, Frank.
-    
-    - Complete write, unlink and truncate functions : the bitmap should be
-updated.
-
-    - Porting to linux 2.1.99+ with dcache support. 20-06-1998, Frank.
-    
-    - Don't rewrite the file_read function : use the generic_file_read hook,
-      and write readpage instead. Done on 21-06-1998, Frank.
-
-    - Write dinit and dcheck.
-
-    - Solving the bugs.
-    
-    - Use le32_to_cpu and vice-versa for portability.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/qnx4/inode.c linux/fs/qnx4/inode.c
--- linux.orig/fs/qnx4/inode.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/qnx4/inode.c	2002-07-20 01:08:31.000000000 +0000
@@ -351,26 +351,19 @@
 	s->s_blocksize = QNX4_BLOCK_SIZE;
 	s->s_blocksize_bits = QNX4_BLOCK_SIZE_BITS;
 
-	/* Check the boot signature. Since the qnx4 code is
+	/* Check the superblock signature. Since the qnx4 code is
 	   dangerous, we should leave as quickly as possible
 	   if we don't belong here... */
-	bh = sb_bread(s, 0);
+	bh = sb_bread(s, 1);
 	if (!bh) {
-		printk("qnx4: unable to read the boot sector\n");
+		printk("qnx4: unable to read the superblock\n");
 		goto outnobh;
 	}
-	if ( memcmp( (char*)bh->b_data + 4, "QNX4FS", 6 ) ) {
+	if ( le32_to_cpu( *(__u32*)bh->b_data ) != QNX4_SUPER_MAGIC ) {
 		if (!silent)
-			printk("qnx4: wrong fsid in boot sector.\n");
+			printk("qnx4: wrong fsid in superblock sector.\n");
 		goto out;
 	}
-	brelse(bh);
-
-	bh = sb_bread(s, 1);
-	if (!bh) {
-		printk("qnx4: unable to read the superblock\n");
-		goto outnobh;
-	}
 	s->s_op = &qnx4_sops;
 	s->s_magic = QNX4_SUPER_MAGIC;
 #ifndef CONFIG_QNX4FS_RW
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/ramfs/inode.c linux/fs/ramfs/inode.c
--- linux.orig/fs/ramfs/inode.c	2001-10-24 22:19:18.000000000 +0000
+++ linux/fs/ramfs/inode.c	2002-07-20 01:08:32.000000000 +0000
@@ -37,7 +37,6 @@
 
 static struct super_operations ramfs_ops;
 static struct address_space_operations ramfs_aops;
-static struct file_operations ramfs_dir_operations;
 static struct file_operations ramfs_file_operations;
 static struct inode_operations ramfs_dir_inode_operations;
 
@@ -120,7 +119,7 @@
 			break;
 		case S_IFDIR:
 			inode->i_op = &ramfs_dir_inode_operations;
-			inode->i_fop = &ramfs_dir_operations;
+			inode->i_fop = &dcache_dir_ops;
 			break;
 		case S_IFLNK:
 			inode->i_op = &page_symlink_inode_operations;
@@ -279,12 +278,6 @@
 	fsync:		ramfs_sync_file,
 };
 
-static struct file_operations ramfs_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	dcache_readdir,
-	fsync:		ramfs_sync_file,
-};
-
 static struct inode_operations ramfs_dir_inode_operations = {
 	create:		ramfs_create,
 	lookup:		ramfs_lookup,
@@ -325,6 +318,7 @@
 }
 
 static DECLARE_FSTYPE(ramfs_fs_type, "ramfs", ramfs_read_super, FS_LITTER);
+static DECLARE_FSTYPE(rootfs_fs_type, "rootfs", ramfs_read_super, FS_NOMOUNT|FS_LITTER);
 
 static int __init init_ramfs_fs(void)
 {
@@ -338,5 +332,11 @@
 
 module_init(init_ramfs_fs)
 module_exit(exit_ramfs_fs)
+
+int __init init_rootfs(void)
+{
+	return register_filesystem(&rootfs_fs_type);
+}
+
 MODULE_LICENSE("GPL");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/read_write.c linux/fs/read_write.c
--- linux.orig/fs/read_write.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/read_write.c	2002-07-20 01:08:38.000000000 +0000
@@ -2,6 +2,21 @@
  *  linux/fs/read_write.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Minor pieces Copyright (C) 2002 Red Hat 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/slab.h> 
@@ -203,7 +218,7 @@
 	typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
 	typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
 
-	size_t tot_len;
+	ssize_t tot_len;
 	struct iovec iovstack[UIO_FASTIOV];
 	struct iovec *iov=iovstack;
 	ssize_t ret, i;
@@ -233,17 +248,23 @@
 	if (copy_from_user(iov, vector, count*sizeof(*vector)))
 		goto out;
 
-	/* BSD readv/writev returns EINVAL if one of the iov_len
-	   values < 0 or tot_len overflowed a 32-bit integer. -ink */
+	/*
+	 * Single unix specification:
+	 * We should -EINVAL if an element length is not >= 0 and fitting an ssize_t
+	 * The total length is fitting an ssize_t
+	 *
+	 * Be careful here because iov_len is a size_t not an ssize_t
+	 */
+	 
 	tot_len = 0;
 	ret = -EINVAL;
 	for (i = 0 ; i < count ; i++) {
-		size_t tmp = tot_len;
-		int len = iov[i].iov_len;
-		if (len < 0)
+		ssize_t tmp = tot_len;
+		ssize_t len = (ssize_t) iov[i].iov_len;
+		if (len < 0)	/* size_t not fitting an ssize_t .. */
 			goto out;
-		(u32)tot_len += len;
-		if (tot_len < tmp || tot_len < (u32)len)
+		tot_len += len;
+		if (tot_len < tmp) /* maths overflow on the ssize_t */
 			goto out;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/readdir.c linux/fs/readdir.c
--- linux.orig/fs/readdir.c	2001-08-12 21:59:08.000000000 +0000
+++ linux/fs/readdir.c	2002-07-20 01:08:36.000000000 +0000
@@ -33,6 +33,64 @@
 	return res;
 }
 
+int dcache_dir_open(struct inode *inode, struct file *file)
+{
+	static struct qstr cursor_name = {len:1, name:"."};
+
+	file->private_data = d_alloc(file->f_dentry, &cursor_name);
+
+	return file->private_data ? 0 : -ENOMEM;
+}
+
+int dcache_dir_close(struct inode *inode, struct file *file)
+{
+	dput(file->private_data);
+	return 0;
+}
+
+loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
+{
+	down(&file->f_dentry->d_inode->i_sem);
+	switch (origin) {
+		case 1:
+			offset += file->f_pos;
+		case 0:
+			if (offset >= 0)
+				break;
+		default:
+			up(&file->f_dentry->d_inode->i_sem);
+			return -EINVAL;
+	}
+	if (offset != file->f_pos) {
+		file->f_pos = offset;
+		if (file->f_pos >= 2) {
+			struct list_head *p;
+			struct dentry *cursor = file->private_data;
+			loff_t n = file->f_pos - 2;
+
+			spin_lock(&dcache_lock);
+			p = file->f_dentry->d_subdirs.next;
+			while (n && p != &file->f_dentry->d_subdirs) {
+				struct dentry *next;
+				next = list_entry(p, struct dentry, d_child);
+				if (!list_empty(&next->d_hash) && next->d_inode)
+					n--;
+				p = p->next;
+			}
+			list_del(&cursor->d_child);
+			list_add_tail(&cursor->d_child, p);
+			spin_unlock(&dcache_lock);
+		}
+	}
+	up(&file->f_dentry->d_inode->i_sem);
+	return offset;
+}
+
+int dcache_dir_fsync(struct file * file, struct dentry *dentry, int datasync)
+{
+	return 0;
+}
+
 /*
  * Directory is locked and all positive dentries in it are safe, since
  * for ramfs-type trees they can't go away without unlink() or rmdir(),
@@ -41,62 +99,65 @@
 
 int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-	int i;
 	struct dentry *dentry = filp->f_dentry;
+	struct dentry *cursor = filp->private_data;
+	struct list_head *p, *q = &cursor->d_child;
+	ino_t ino;
+	int i = filp->f_pos;
 
-	i = filp->f_pos;
 	switch (i) {
 		case 0:
-			if (filldir(dirent, ".", 1, i, dentry->d_inode->i_ino, DT_DIR) < 0)
+			ino = dentry->d_inode->i_ino;
+			if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
 				break;
-			i++;
 			filp->f_pos++;
+			i++;
 			/* fallthrough */
 		case 1:
-			if (filldir(dirent, "..", 2, i, dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
+			spin_lock(&dcache_lock);
+			ino = dentry->d_parent->d_inode->i_ino;
+			spin_unlock(&dcache_lock);
+			if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
 				break;
-			i++;
 			filp->f_pos++;
+			i++;
 			/* fallthrough */
-		default: {
-			struct list_head *list;
-			int j = i-2;
-
+		default:
 			spin_lock(&dcache_lock);
-			list = dentry->d_subdirs.next;
-
-			for (;;) {
-				if (list == &dentry->d_subdirs) {
-					spin_unlock(&dcache_lock);
-					return 0;
-				}
-				if (!j)
-					break;
-				j--;
-				list = list->next;
+			if (filp->f_pos == 2) {
+				list_del(q);
+				list_add(q, &dentry->d_subdirs);
 			}
-
-			while(1) {
-				struct dentry *de = list_entry(list, struct dentry, d_child);
-
-				if (!list_empty(&de->d_hash) && de->d_inode) {
-					spin_unlock(&dcache_lock);
-					if (filldir(dirent, de->d_name.name, de->d_name.len, filp->f_pos, de->d_inode->i_ino, DT_UNKNOWN) < 0)
-						break;
-					spin_lock(&dcache_lock);
-				}
-				filp->f_pos++;
-				list = list->next;
-				if (list != &dentry->d_subdirs)
+			for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
+				struct dentry *next;
+				next = list_entry(p, struct dentry, d_child);
+				if (list_empty(&next->d_hash) || !next->d_inode)
 					continue;
+
 				spin_unlock(&dcache_lock);
-				break;
+				if (filldir(dirent, next->d_name.name, next->d_name.len, filp->f_pos, next->d_inode->i_ino, DT_UNKNOWN) < 0)
+					return 0;
+				spin_lock(&dcache_lock);
+				/* next is still alive */
+				list_del(q);
+				list_add(q, p);
+				p = q;
+				filp->f_pos++;
 			}
-		}
+			spin_unlock(&dcache_lock);
 	}
 	return 0;
 }
 
+struct file_operations dcache_dir_ops = {
+	open:		dcache_dir_open,
+	release:	dcache_dir_close,
+	llseek:		dcache_dir_lseek,
+	read:		generic_read_dir,
+	readdir:	dcache_readdir,
+	fsync:		dcache_dir_fsync,
+};
+
 /*
  * Traditional linux readdir() handling..
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/bitmap.c linux/fs/reiserfs/bitmap.c
--- linux.orig/fs/reiserfs/bitmap.c	2001-12-21 17:42:03.000000000 +0000
+++ linux/fs/reiserfs/bitmap.c	2002-07-20 01:08:38.000000000 +0000
@@ -139,10 +139,8 @@
 /* preallocated blocks don't need to be run through journal_mark_freed */
 void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, 
                           unsigned long block) {
-    struct super_block * s = th->t_super;
-
-    RFALSE(!s, "vs-4060: trying to free block on nonexistent device");
-    RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block");
+    RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device");
+    RFALSE(is_reusable (th->t_super, block, 1) == 0, "vs-4070: can not free such block");
     _reiserfs_free_block(th, block) ;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/dir.c linux/fs/reiserfs/dir.c
--- linux.orig/fs/reiserfs/dir.c	2001-12-21 17:42:03.000000000 +0000
+++ linux/fs/reiserfs/dir.c	2002-07-20 01:08:22.000000000 +0000
@@ -20,6 +20,7 @@
     read:	generic_read_dir,
     readdir:	reiserfs_readdir,
     fsync:	reiserfs_dir_fsync,
+    ioctl:	reiserfs_ioctl,
 };
 
 int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
@@ -76,7 +77,7 @@
 		
 	/* we must have found item, that is item of this directory, */
 	RFALSE( COMP_SHORT_KEYS (&(ih->ih_key), &pos_key),
-		"vs-9000: found item %h does not match to dir we readdir %k",
+		"vs-9000: found item %h does not match to dir we readdir %K",
 		ih, &pos_key);
 	RFALSE( item_num > B_NR_ITEMS (bh) - 1,
 		"vs-9005 item_num == %d, item amount == %d", 
@@ -115,13 +116,13 @@
 		if (d_reclen <= 32) {
 		  local_buf = small_buf ;
 		} else {
-		    local_buf = kmalloc(d_reclen, GFP_NOFS) ;
+		    local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
 		    if (!local_buf) {
 			pathrelse (&path_to_entry);
 			return -ENOMEM ;
 		    }
 		    if (item_moved (&tmp_ih, &path_to_entry)) {
-			kfree(local_buf) ;
+			reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
 			goto research;
 		    }
 		}
@@ -133,12 +134,12 @@
 		if (filldir (dirent, local_buf, d_reclen, d_off, d_ino, 
 		             DT_UNKNOWN) < 0) {
 		    if (local_buf != small_buf) {
-			kfree(local_buf) ;
+			reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
 		    }
 		    goto end;
 		}
 		if (local_buf != small_buf) {
-		    kfree(local_buf) ;
+		    reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
 		}
 
 		// next entry should be looked for with such offset
@@ -180,6 +181,7 @@
     filp->f_pos = next_pos;
     pathrelse (&path_to_entry);
     reiserfs_check_path(&path_to_entry) ;
+    UPDATE_ATIME(inode) ;
     return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/fix_node.c linux/fs/reiserfs/fix_node.c
--- linux.orig/fs/reiserfs/fix_node.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/reiserfs/fix_node.c	2002-07-20 01:08:31.000000000 +0000
@@ -1979,7 +1979,7 @@
     return CARRY_ON;
 }
 
-
+#ifdef CONFIG_REISERFS_CHECK
 void * reiserfs_kmalloc (size_t size, int flags, struct super_block * s)
 {
     void * vp;
@@ -2007,20 +2007,25 @@
 	reiserfs_warning ("vs-8302: reiserfs_kfree: allocated memory %d\n", s->u.reiserfs_sb.s_kmallocs);
 
 }
+#endif
 
 
 static int get_virtual_node_size (struct super_block * sb, struct buffer_head * bh)
 {
-  //  int size = sizeof (struct virtual_item); /* for new item in case of insert */
-  //  int i, nr_items;
-  //  struct item_head * ih;
-
-  // this is enough for _ALL_ currently possible cases. In 4 k block
-  // one may put < 170 empty items. Each virtual item eats 12
-  // byte. The biggest direntry item may have < 256 entries. Each
-  // entry would eat 2 byte of virtual node space
-  return sb->s_blocksize;
-
+    int max_num_of_items;
+    int max_num_of_entries;
+    unsigned long blocksize = sb->s_blocksize;
+
+#define MIN_NAME_LEN 1
+
+    max_num_of_items = (blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN);
+    max_num_of_entries = (blocksize - BLKH_SIZE - IH_SIZE) / 
+                         (DEH_SIZE + MIN_NAME_LEN);
+
+    return sizeof(struct virtual_node) + 
+           max(max_num_of_items * sizeof (struct virtual_item),
+	       sizeof (struct virtual_item) + sizeof(struct direntry_uarea) + 
+               (max_num_of_entries - 1) * sizeof (__u16));
 }
 
 
@@ -2356,7 +2361,6 @@
     for ( n_h = 0; n_h < MAX_HEIGHT && p_s_tb->insert_size[n_h]; n_h++ ) { 
 	if ( (n_ret_value = get_direct_parent(p_s_tb, n_h)) != CARRY_ON ) {
 	    goto repeat;
-	    return n_ret_value;
 	}
 
 	if ( (n_ret_value = check_balance (n_op_mode, p_s_tb, n_h, n_item_num,
@@ -2365,7 +2369,6 @@
 		/* No balancing for higher levels needed. */
 		if ( (n_ret_value = get_neighbors(p_s_tb, n_h)) != CARRY_ON ) {
 		    goto repeat;
-		    return n_ret_value;
 		}
 		if ( n_h != MAX_HEIGHT - 1 )  
 		    p_s_tb->insert_size[n_h + 1] = 0;
@@ -2373,17 +2376,14 @@
 		break;
 	    }
 	    goto repeat;
-	    return n_ret_value;
 	}
 
 	if ( (n_ret_value = get_neighbors(p_s_tb, n_h)) != CARRY_ON ) {
 	    goto repeat;
-	    return n_ret_value;
 	}
 
 	if ( (n_ret_value = get_empty_nodes(p_s_tb, n_h)) != CARRY_ON ) {
-	    goto repeat;
-	    return n_ret_value; /* No disk space, or schedule occurred and
+	    goto repeat;        /* No disk space, or schedule occurred and
 				   analysis may be invalid and needs to be redone. */
 	}
     
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/inode.c linux/fs/reiserfs/inode.c
--- linux.orig/fs/reiserfs/inode.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/reiserfs/inode.c	2002-07-20 01:08:31.000000000 +0000
@@ -445,6 +445,24 @@
     return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE) ;
 }
 
+static int reiserfs_get_block_direct_io (struct inode * inode, long block,
+			struct buffer_head * bh_result, int create) {
+    int ret ;
+
+    ret = reiserfs_get_block(inode, block, bh_result, create) ;
+
+    /* don't allow direct io onto tail pages */
+    if (ret == 0 && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
+	/* make sure future calls to the direct io funcs for this offset
+	** in the file fail by unmapping the buffer
+	*/
+	reiserfs_unmap_buffer(bh_result);
+        ret = -EINVAL ;
+    }
+    return ret ;
+}
+
+
 /*
 ** helper function for when reiserfs_get_block is called for a hole
 ** but the file tail is still in a direct item
@@ -748,14 +766,24 @@
 
 		retval = convert_tail_for_hole(inode, bh_result, tail_offset) ;
 		if (retval) {
-		    printk("clm-6004: convert tail failed inode %lu, error %d\n", inode->i_ino, retval) ;
-		    if (allocated_block_nr)
+		    if ( retval != -ENOSPC )
+			printk("clm-6004: convert tail failed inode %lu, error %d\n", inode->i_ino, retval) ;
+		    if (allocated_block_nr) {
+			/* the bitmap, the super, and the stat data == 3 */
+			journal_begin(&th, inode->i_sb, 3) ;
 			reiserfs_free_block (&th, allocated_block_nr);
+			transaction_started = 1 ;
+		    }
 		    goto failure ;
 		}
 		goto research ;
 	    }
 	    retval = direct2indirect (&th, inode, &path, unbh, tail_offset);
+	    if (retval) {
+		reiserfs_unmap_buffer(unbh);
+		reiserfs_free_block (&th, allocated_block_nr);
+		goto failure;
+	    }
 	    /* it is important the mark_buffer_uptodate is done after
 	    ** the direct2indirect.  The buffer might contain valid
 	    ** data newer than the data on disk (read by readpage, changed,
@@ -765,10 +793,7 @@
 	    ** the disk
 	    */
 	    mark_buffer_uptodate (unbh, 1);
-	    if (retval) {
-		reiserfs_free_block (&th, allocated_block_nr);
-		goto failure;
-	    }
+
 	    /* we've converted the tail, so we must 
 	    ** flush unbh before the transaction commits
 	    */
@@ -914,7 +939,7 @@
 	inode->i_blocks = sd_v1_blocks(sd);
 	inode->i_generation = le32_to_cpu (INODE_PKEY (inode)->k_dir_id);
 	blocks = (inode->i_size + 511) >> 9;
-	blocks = _ROUND_UP (blocks, inode->i_blksize >> 9);
+	blocks = _ROUND_UP (blocks, inode->i_sb->s_blocksize >> 9);
 	if (inode->i_blocks > blocks) {
 	    // there was a bug in <=3.5.23 when i_blocks could take negative
 	    // values. Starting from 3.5.17 this value could even be stored in
@@ -926,6 +951,9 @@
 
         rdev = sd_v1_rdev(sd);
 	inode->u.reiserfs_i.i_first_direct_byte = sd_v1_first_direct_byte(sd);
+	/* nopack is initially zero for v1 objects. For v2 objects,
+	   nopack is initialised from sd_attrs */
+	inode->u.reiserfs_i.i_flags &= ~i_nopack_mask;
     } else {
 	// new stat data found, but object may have old items
 	// (directories and symlinks)
@@ -952,10 +980,12 @@
             set_inode_item_key_version (inode, KEY_FORMAT_3_6);
 
         set_inode_sd_version (inode, STAT_DATA_V2);
+	/* read persistent inode attributes from sd and initalise
+	   generic inode flags from them */
+	inode -> u.reiserfs_i.i_attrs = sd_v2_attrs( sd );
+	sd_attrs_to_i_attrs( sd_v2_attrs( sd ), inode );
     }
 
-    /* nopack = 0, by default */
-    inode->u.reiserfs_i.i_flags &= ~i_nopack_mask;
 
     pathrelse (path);
     if (S_ISREG (inode->i_mode)) {
@@ -979,6 +1009,7 @@
 static void inode2sd (void * sd, struct inode * inode)
 {
     struct stat_data * sd_v2 = (struct stat_data *)sd;
+    __u16 flags;
 
     set_sd_v2_mode(sd_v2, inode->i_mode );
     set_sd_v2_nlink(sd_v2, inode->i_nlink );
@@ -989,13 +1020,13 @@
     set_sd_v2_atime(sd_v2, inode->i_atime );
     set_sd_v2_ctime(sd_v2, inode->i_ctime );
     set_sd_v2_blocks(sd_v2, inode->i_blocks );
-    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
+    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
         set_sd_v2_rdev(sd_v2, inode->i_rdev );
-}
     else
-    {
         set_sd_v2_generation(sd_v2, inode->i_generation);
-    }
+    flags = inode -> u.reiserfs_i.i_attrs;
+    i_attrs_to_sd_attrs( inode, &flags );
+    set_sd_v2_attrs( sd_v2, flags );
 }
 
 
@@ -1493,7 +1524,9 @@
     }
 
     sb = dir->i_sb;
-    inode->i_flags = 0;//inode->i_sb->s_flags;
+    inode -> u.reiserfs_i.i_attrs = 
+	    dir -> u.reiserfs_i.i_attrs & REISERFS_INHERIT_MASK;
+    sd_attrs_to_i_attrs( inode -> u.reiserfs_i.i_attrs, inode );
 
     /* item head of new item */
     ih.ih_key.k_dir_id = INODE_PKEY (dir)->k_objectid;
@@ -1552,6 +1585,10 @@
     } else
 	inode->i_gid = current->fsgid;
 
+    /* symlink cannot be immutable or append only, right? */
+    if( S_ISLNK( inode -> i_mode ) )
+	    inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );
+
     inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
     inode->i_size = i_size;
     inode->i_blocks = (inode->i_size + 511) >> 9;
@@ -1898,14 +1935,21 @@
 static inline void submit_bh_for_writepage(struct buffer_head **bhp, int nr) {
     struct buffer_head *bh ;
     int i;
+
+    /* lock them all first so the end_io handler doesn't unlock the page
+    ** too early
+    */
     for(i = 0 ; i < nr ; i++) {
         bh = bhp[i] ;
 	lock_buffer(bh) ;
 	set_buffer_async_io(bh) ;
+    }
+    for(i = 0 ; i < nr ; i++) {
 	/* submit_bh doesn't care if the buffer is dirty, but nobody
 	** later on in the call chain will be cleaning it.  So, we
 	** clean the buffer here, it still gets written either way.
 	*/
+        bh = bhp[i] ;
 	clear_bit(BH_Dirty, &bh->b_state) ;
 	set_bit(BH_Uptodate, &bh->b_state) ;
 	submit_bh(WRITE, bh) ;
@@ -2073,11 +2117,64 @@
     return ret ;
 }
 
+void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode )
+{
+	if( reiserfs_attrs( inode -> i_sb ) ) {
+		if( sd_attrs & REISERFS_SYNC_FL )
+			inode -> i_flags |= S_SYNC;
+		else
+			inode -> i_flags &= ~S_SYNC;
+		if( sd_attrs & REISERFS_IMMUTABLE_FL )
+			inode -> i_flags |= S_IMMUTABLE;
+		else
+			inode -> i_flags &= ~S_IMMUTABLE;
+		if( sd_attrs & REISERFS_NOATIME_FL )
+			inode -> i_flags |= S_NOATIME;
+		else
+			inode -> i_flags &= ~S_NOATIME;
+		if( sd_attrs & REISERFS_NOTAIL_FL )
+			inode->u.reiserfs_i.i_flags |= i_nopack_mask;
+		else
+			inode->u.reiserfs_i.i_flags &= ~i_nopack_mask;
+	}
+}
+
+void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs )
+{
+	if( reiserfs_attrs( inode -> i_sb ) ) {
+		if( inode -> i_flags & S_IMMUTABLE )
+			*sd_attrs |= REISERFS_IMMUTABLE_FL;
+		else
+			*sd_attrs &= ~REISERFS_IMMUTABLE_FL;
+		if( inode -> i_flags & S_SYNC )
+			*sd_attrs |= REISERFS_SYNC_FL;
+		else
+			*sd_attrs &= ~REISERFS_SYNC_FL;
+		if( inode -> i_flags & S_NOATIME )
+			*sd_attrs |= REISERFS_NOATIME_FL;
+		else
+			*sd_attrs &= ~REISERFS_NOATIME_FL;
+		if( inode->u.reiserfs_i.i_flags & i_nopack_mask )
+			*sd_attrs |= REISERFS_NOTAIL_FL;
+		else
+			*sd_attrs &= ~REISERFS_NOTAIL_FL;
+	}
+}
+
+static int reiserfs_direct_io(int rw, struct inode *inode, 
+                              struct kiobuf *iobuf, unsigned long blocknr,
+			      int blocksize) 
+{
+    return generic_direct_IO(rw, inode, iobuf, blocknr, blocksize,
+                             reiserfs_get_block_direct_io) ;
+}
+
 struct address_space_operations reiserfs_address_space_operations = {
     writepage: reiserfs_writepage,
     readpage: reiserfs_readpage, 
     sync_page: block_sync_page,
     prepare_write: reiserfs_prepare_write,
     commit_write: reiserfs_commit_write,
-    bmap: reiserfs_aop_bmap
+    bmap: reiserfs_aop_bmap,
+    direct_IO: reiserfs_direct_io,
 } ;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/ioctl.c linux/fs/reiserfs/ioctl.c
--- linux.orig/fs/reiserfs/ioctl.c	2001-12-21 17:42:03.000000000 +0000
+++ linux/fs/reiserfs/ioctl.c	2002-07-20 01:08:33.000000000 +0000
@@ -14,17 +14,70 @@
 ** supported commands:
 **  1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
 **                           and prevent packing file (argument arg has to be non-zero)
-**  2) That's all for a while ...
+**  2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
+**  3) That's all for a while ...
 */
 int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
 		unsigned long arg)
 {
+	unsigned int flags;
+
 	switch (cmd) {
 	    case REISERFS_IOC_UNPACK:
+		if( S_ISREG( inode -> i_mode ) ) {
 		if (arg)
 		    return reiserfs_unpack (inode, filp);
+			else
+				return 0;
+		} else
+			return -ENOTTY;
+	/* following two cases are taken from fs/ext2/ioctl.c by Remy
+	   Card (card@masi.ibp.fr) */
+	case REISERFS_IOC_GETFLAGS:
+		flags = inode -> u.reiserfs_i.i_attrs;
+		i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
+		return put_user(flags, (int *) arg);
+	case REISERFS_IOC_SETFLAGS: {
+		if (IS_RDONLY(inode))
+			return -EROFS;
+
+		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+			return -EPERM;
+
+		if (get_user(flags, (int *) arg))
+			return -EFAULT;
+
+		if ( ( flags & REISERFS_IMMUTABLE_FL ) && 
+		     !capable( CAP_LINUX_IMMUTABLE ) )
+			return -EPERM;
 			
-	    default:
+		if( ( flags & REISERFS_NOTAIL_FL ) &&
+		    S_ISREG( inode -> i_mode ) ) {
+				int result;
+
+				result = reiserfs_unpack( inode, filp );
+				if( result )
+					return result;
+		}
+		sd_attrs_to_i_attrs( flags, inode );
+		inode -> u.reiserfs_i.i_attrs = flags;
+		inode->i_ctime = CURRENT_TIME;
+		mark_inode_dirty(inode);
+		return 0;
+	}
+	case REISERFS_IOC_GETVERSION:
+		return put_user(inode->i_generation, (int *) arg);
+	case REISERFS_IOC_SETVERSION:
+		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+			return -EPERM;
+		if (IS_RDONLY(inode))
+			return -EROFS;
+		if (get_user(inode->i_generation, (int *) arg))
+			return -EFAULT;	
+		inode->i_ctime = CURRENT_TIME;
+		mark_inode_dirty(inode);
+		return 0;
+	default:
 		return -ENOTTY;
 	}
 }
@@ -43,7 +96,8 @@
     unsigned long blocksize = inode->i_sb->s_blocksize ;
     	
     if (inode->i_size == 0) {
-        return -EINVAL ;
+        inode->u.reiserfs_i.i_flags |= i_nopack_mask;
+        return 0 ;
     }
     /* ioctl already done */
     if (inode->u.reiserfs_i.i_flags & i_nopack_mask) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/item_ops.c linux/fs/reiserfs/item_ops.c
--- linux.orig/fs/reiserfs/item_ops.c	2001-10-12 21:19:28.000000000 +0000
+++ linux/fs/reiserfs/item_ops.c	2002-07-20 01:08:26.000000000 +0000
@@ -466,13 +466,6 @@
 
 #define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
 
-struct direntry_uarea {
-    int flags;
-    __u16 entry_count;
-    __u16 entry_sizes[1];
-} __attribute__ ((__packed__)) ;
-
-
 /*
  * function returns old entry number in directory item in real node
  * using new entry number in virtual item in virtual node */
@@ -685,17 +678,110 @@
 
 
 //////////////////////////////////////////////////////////////////////////////
+// Error catching functions to catch errors caused by incorrect item types.
+//
+static int errcatch_bytes_number (struct item_head * ih, int block_size)
+{
+    reiserfs_warning ("green-16001: Invalid item type observed, run fsck ASAP\n");
+    return 0;
+}
+
+static void errcatch_decrement_key (struct cpu_key * key)
+{
+    reiserfs_warning ("green-16002: Invalid item type observed, run fsck ASAP\n");
+}
+
+
+static int errcatch_is_left_mergeable (struct key * key, unsigned long bsize)
+{
+    reiserfs_warning ("green-16003: Invalid item type observed, run fsck ASAP\n");
+    return 0;
+}
+
+
+static void errcatch_print_item (struct item_head * ih, char * item)
+{
+    reiserfs_warning ("green-16004: Invalid item type observed, run fsck ASAP\n");
+}
+
+
+static void errcatch_check_item (struct item_head * ih, char * item)
+{
+    reiserfs_warning ("green-16005: Invalid item type observed, run fsck ASAP\n");
+}
+
+static int errcatch_create_vi (struct virtual_node * vn,
+			       struct virtual_item * vi, 
+			       int is_affected, 
+			       int insert_size)
+{
+    reiserfs_warning ("green-16006: Invalid item type observed, run fsck ASAP\n");
+    return 0;	// We might return -1 here as well, but it won't help as create_virtual_node() from where
+		// this operation is called from is of return type void.
+}
+
+static int errcatch_check_left (struct virtual_item * vi, int free,
+				int start_skip, int end_skip)
+{
+    reiserfs_warning ("green-16007: Invalid item type observed, run fsck ASAP\n");
+    return -1;
+}
+
+
+static int errcatch_check_right (struct virtual_item * vi, int free)
+{
+    reiserfs_warning ("green-16008: Invalid item type observed, run fsck ASAP\n");
+    return -1;
+}
+
+static int errcatch_part_size (struct virtual_item * vi, int first, int count)
+{
+    reiserfs_warning ("green-16009: Invalid item type observed, run fsck ASAP\n");
+    return 0;
+}
+
+static int errcatch_unit_num (struct virtual_item * vi)
+{
+    reiserfs_warning ("green-16010: Invalid item type observed, run fsck ASAP\n");
+    return 0;
+}
+
+static void errcatch_print_vi (struct virtual_item * vi)
+{
+    reiserfs_warning ("green-16011: Invalid item type observed, run fsck ASAP\n");
+}
+
+struct item_operations errcatch_ops = {
+    errcatch_bytes_number,
+    errcatch_decrement_key,
+    errcatch_is_left_mergeable,
+    errcatch_print_item,
+    errcatch_check_item,
+
+    errcatch_create_vi,
+    errcatch_check_left,
+    errcatch_check_right,
+    errcatch_part_size,
+    errcatch_unit_num,
+    errcatch_print_vi
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////////
 //
 //
 #if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
   do not compile
 #endif
 
-struct item_operations * item_ops [4] = {
+struct item_operations * item_ops [TYPE_ANY + 1] = {
   &stat_data_ops,
   &indirect_ops,
   &direct_ops,
-  &direntry_ops
+  &direntry_ops,
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+  &errcatch_ops		/* This is to catch errors with invalid type (15th entry for TYPE_ANY) */
 };
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/journal.c linux/fs/reiserfs/journal.c
--- linux.orig/fs/reiserfs/journal.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/reiserfs/journal.c	2002-07-20 01:08:23.000000000 +0000
@@ -71,7 +71,9 @@
 static DECLARE_WAIT_QUEUE_HEAD(reiserfs_commit_thread_done) ;
 DECLARE_TASK_QUEUE(reiserfs_commit_thread_tq) ;
 
-#define JOURNAL_TRANS_HALF 1018   /* must be correct to keep the desc and commit structs at 4k */
+#define JOURNAL_TRANS_HALF 1018   /* must be correct to keep the desc and commit
+				     structs at 4k */
+#define BUFNR 64 /*read ahead */
 
 /* cnode stat bits.  Move these into reiserfs_fs.h */
 
@@ -117,13 +119,13 @@
   struct reiserfs_bitmap_node *bn ;
   static int id = 0 ;
 
-  bn = kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS) ;
+  bn = reiserfs_kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS, p_s_sb) ;
   if (!bn) {
     return NULL ;
   }
-  bn->data = kmalloc(p_s_sb->s_blocksize, GFP_NOFS) ;
+  bn->data = reiserfs_kmalloc(p_s_sb->s_blocksize, GFP_NOFS, p_s_sb) ;
   if (!bn->data) {
-    kfree(bn) ;
+    reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb) ;
     return NULL ;
   }
   bn->id = id++ ;
@@ -159,8 +161,8 @@
                                     struct reiserfs_bitmap_node *bn) {
   SB_JOURNAL(p_s_sb)->j_used_bitmap_nodes-- ;
   if (SB_JOURNAL(p_s_sb)->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) {
-    kfree(bn->data) ;
-    kfree(bn) ;
+    reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb) ;
+    reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb) ;
   } else {
     list_add(&bn->list, &SB_JOURNAL(p_s_sb)->j_bitmap_nodes) ;
     SB_JOURNAL(p_s_sb)->j_free_bitmap_nodes++ ;
@@ -228,8 +230,8 @@
   while(next != &SB_JOURNAL(p_s_sb)->j_bitmap_nodes) {
     bn = list_entry(next, struct reiserfs_bitmap_node, list) ;
     list_del(next) ;
-    kfree(bn->data) ;
-    kfree(bn) ;
+    reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb) ;
+    reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb) ;
     next = SB_JOURNAL(p_s_sb)->j_bitmap_nodes.next ;
     SB_JOURNAL(p_s_sb)->j_free_bitmap_nodes-- ;
   }
@@ -1500,13 +1502,13 @@
   }
   trans_id = le32_to_cpu(desc->j_trans_id) ;
   /* now we know we've got a good transaction, and it was inside the valid time ranges */
-  log_blocks = kmalloc(le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), GFP_NOFS) ;
-  real_blocks = kmalloc(le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), GFP_NOFS) ;
+  log_blocks = reiserfs_kmalloc(le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), GFP_NOFS, p_s_sb) ;
+  real_blocks = reiserfs_kmalloc(le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), GFP_NOFS, p_s_sb) ;
   if (!log_blocks  || !real_blocks) {
     brelse(c_bh) ;
     brelse(d_bh) ;
-    kfree(log_blocks) ;
-    kfree(real_blocks) ;
+    reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+    reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
     reiserfs_warning("journal-1169: kmalloc failed, unable to mount FS\n") ;
     return -1 ;
   }
@@ -1525,8 +1527,8 @@
       brelse_array(real_blocks, i) ;
       brelse(c_bh) ;
       brelse(d_bh) ;
-      kfree(log_blocks) ;
-      kfree(real_blocks) ;
+      reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
       return -1 ;
     }
   }
@@ -1540,8 +1542,8 @@
       brelse_array(real_blocks, le32_to_cpu(desc->j_len)) ;
       brelse(c_bh) ;
       brelse(d_bh) ;
-      kfree(log_blocks) ;
-      kfree(real_blocks) ;
+      reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
       return -1 ;
     }
     memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data, real_blocks[i]->b_size) ;
@@ -1560,8 +1562,8 @@
       brelse_array(real_blocks + i, le32_to_cpu(desc->j_len) - i) ;
       brelse(c_bh) ;
       brelse(d_bh) ;
-      kfree(log_blocks) ;
-      kfree(real_blocks) ;
+      reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
       return -1 ;
     }
     brelse(real_blocks[i]) ;
@@ -1577,8 +1579,8 @@
   SB_JOURNAL(p_s_sb)->j_trans_id = trans_id + 1;
   brelse(c_bh) ;
   brelse(d_bh) ;
-  kfree(log_blocks) ;
-  kfree(real_blocks) ;
+  reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+  reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
   return 0 ;
 }
 
@@ -1591,6 +1593,41 @@
 **
 ** On exit, it sets things up so the first transaction will work correctly.
 */
+struct buffer_head * reiserfs_breada (kdev_t dev, int block, int bufsize,
+			    unsigned int max_block)
+{
+	struct buffer_head * bhlist[BUFNR];
+	unsigned int blocks = BUFNR;
+	struct buffer_head * bh;
+	int i, j;
+	
+	bh = getblk (dev, block, bufsize);
+	if (buffer_uptodate (bh))
+		return (bh);   
+		
+	if (block + BUFNR > max_block) {
+		blocks = max_block - block;
+	}
+	bhlist[0] = bh;
+	j = 1;
+	for (i = 1; i < blocks; i++) {
+		bh = getblk (dev, block + i, bufsize);
+		if (buffer_uptodate (bh)) {
+			brelse (bh);
+			break;
+		}
+		else bhlist[j++] = bh;
+	}
+	ll_rw_block (READ, j, bhlist);
+	for(i = 1; i < j; i++) 
+		brelse (bhlist[i]);
+	bh = bhlist[0];
+	wait_on_buffer (bh);
+	if (buffer_uptodate (bh))
+		return bh;
+	brelse (bh);
+	return NULL;
+}
 static int journal_read(struct super_block *p_s_sb) {
   struct reiserfs_journal_desc *desc ;
   unsigned long last_flush_trans_id = 0 ;
@@ -1660,7 +1697,8 @@
   ** all the valid transactions, and pick out the oldest.
   */
   while(continue_replay && cur_dblock < (reiserfs_get_journal_block(p_s_sb) + JOURNAL_BLOCK_COUNT)) {
-    d_bh = sb_bread(p_s_sb, cur_dblock) ;
+    d_bh = reiserfs_breada(p_s_sb->s_dev, cur_dblock, p_s_sb->s_blocksize,
+			   reiserfs_get_journal_block(p_s_sb) + JOURNAL_BLOCK_COUNT) ;
     ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ;
     if (ret == 1) {
       desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
@@ -1777,7 +1815,7 @@
       atomic_read(&(jl->j_commit_left)) == 0) {
     kupdate_one_transaction(ct->p_s_sb, jl) ;
   }
-  kfree(ct->self) ;
+  reiserfs_kfree(ct->self, sizeof(struct reiserfs_journal_commit_task), ct->p_s_sb) ;
 }
 
 static void setup_commit_task_arg(struct reiserfs_journal_commit_task *ct,
@@ -1801,7 +1839,7 @@
   /* using GFP_NOFS, GFP_KERNEL could try to flush inodes, which will try
   ** to start/join a transaction, which will deadlock
   */
-  ct = kmalloc(sizeof(struct reiserfs_journal_commit_task), GFP_NOFS) ;
+  ct = reiserfs_kmalloc(sizeof(struct reiserfs_journal_commit_task), GFP_NOFS, p_s_sb) ;
   if (ct) {
     setup_commit_task_arg(ct, p_s_sb, jindex) ;
     queue_task(&(ct->task), &reiserfs_commit_thread_tq);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/namei.c linux/fs/reiserfs/namei.c
--- linux.orig/fs/reiserfs/namei.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/reiserfs/namei.c	2002-07-20 01:08:23.000000000 +0000
@@ -340,7 +340,7 @@
 static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry)
 {
     int retval;
-    struct inode * inode = 0;
+    struct inode * inode = NULL;
     struct reiserfs_dir_entry de;
     INITIALIZE_PATH (path_to_entry);
 
@@ -358,6 +358,9 @@
 	    return ERR_PTR(-EACCES);
         }
     }
+    if ( retval == IO_ERROR ) {
+	return ERR_PTR(-EIO);
+    }
 
     d_add(dentry, inode);
     return NULL;
@@ -443,6 +446,10 @@
 	    reiserfs_kfree (buffer, buflen, dir->i_sb);
 	pathrelse (&path);
 
+	if ( retval == IO_ERROR ) {
+	    return -EIO;
+	}
+
         if (retval != NAME_FOUND) {
 	    reiserfs_warning ("zam-7002:" __FUNCTION__ ": \"reiserfs_find_entry\" has returned"
                               " unexpected value (%d)\n", retval);
@@ -470,7 +477,7 @@
     if (gen_number != 0) {	/* we need to re-search for the insertion point */
       if (search_by_entry_key (dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) {
             reiserfs_warning ("vs-7032: reiserfs_add_entry: "
-                            "entry with this key (%k) already exists\n", &entry_key);
+                            "entry with this key (%K) already exists\n", &entry_key);
 
 	    if (buffer != small_buf)
 		reiserfs_kfree (buffer, buflen, dir->i_sb);
@@ -715,10 +722,14 @@
     windex = push_journal_writer("reiserfs_rmdir") ;
 
     de.de_gen_number_bit_string = 0;
-    if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de) == NAME_NOT_FOUND) {
+    if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {
 	retval = -ENOENT;
 	goto end_rmdir;
+    } else if ( retval == IO_ERROR) {
+	retval = -EIO;
+	goto end_rmdir;
     }
+
     inode = dentry->d_inode;
 
     reiserfs_update_inode_transaction(inode) ;
@@ -800,9 +811,12 @@
     windex = push_journal_writer("reiserfs_unlink") ;
 	
     de.de_gen_number_bit_string = 0;
-    if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de) == NAME_NOT_FOUND) {
+    if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {
 	retval = -ENOENT;
 	goto end_unlink;
+    } else if (retval == IO_ERROR) {
+	retval = -EIO;
+	goto end_unlink;
     }
 
     reiserfs_update_inode_transaction(inode) ;
@@ -881,7 +895,7 @@
 	return -ENAMETOOLONG;
     }
   
-    name = kmalloc (item_len, GFP_NOFS);
+    name = reiserfs_kmalloc (item_len, GFP_NOFS, dir->i_sb);
     if (!name) {
 	iput(inode) ;
 	return -ENOMEM;
@@ -894,7 +908,7 @@
 
     inode = reiserfs_new_inode (&th, dir, S_IFLNK | S_IRWXUGO, name, strlen (symname), dentry,
 				inode, &retval);
-    kfree (name);
+    reiserfs_kfree (name, item_len, dir->i_sb);
     if (inode == 0) { /* reiserfs_new_inode iputs for us */
 	pop_journal_writer(windex) ;
 	journal_end(&th, dir->i_sb, jbegin_count) ;
@@ -1065,8 +1079,10 @@
     retval = reiserfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len,
 				  &old_entry_path, &old_de);
     pathrelse (&old_entry_path);
+    if (retval == IO_ERROR)
+	return -EIO;
+
     if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {
-	// FIXME: IO error is possible here
 	return -ENOENT;
     }
 
@@ -1138,6 +1154,8 @@
 	new_de.de_gen_number_bit_string = 0;
 	retval = reiserfs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, 
 				      &new_entry_path, &new_de);
+	// reiserfs_add_entry should not return IO_ERROR, because it is called with essentially same parameters from
+        // reiserfs_add_entry above, and we'll catch any i/o errors before we get here.
 	if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND)
 	    BUG ();
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/objectid.c linux/fs/reiserfs/objectid.c
--- linux.orig/fs/reiserfs/objectid.c	2001-12-21 17:42:03.000000000 +0000
+++ linux/fs/reiserfs/objectid.c	2002-07-20 01:08:33.000000000 +0000
@@ -5,6 +5,7 @@
 #include <linux/config.h>
 #include <linux/string.h>
 #include <linux/locks.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
 
@@ -196,6 +197,10 @@
     /* set the max size so we don't overflow later */
     disk_sb->s_oid_maxsize = cpu_to_le16(new_size) ;
 
+    /* Zero out label and generate random UUID */
+    memset(disk_sb->s_label, 0, sizeof(disk_sb->s_label)) ;
+    generate_random_uuid(disk_sb->s_uuid);
+
     /* finally, zero out the unused chunk of the new super */
     memset(disk_sb->s_unused, 0, sizeof(disk_sb->s_unused)) ;
     return 0 ;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/prints.c linux/fs/reiserfs/prints.c
--- linux.orig/fs/reiserfs/prints.c	2001-12-21 17:42:03.000000000 +0000
+++ linux/fs/reiserfs/prints.c	2002-07-20 01:08:24.000000000 +0000
@@ -477,6 +477,17 @@
     return 0;
 }
 
+char * reiserfs_hashname(int code)
+{
+    if ( code == YURA_HASH)
+	return "rupasov";
+    if ( code == TEA_HASH)
+	return "tea";
+    if ( code == R5_HASH)
+	return "r5";
+
+    return "unknown";
+}
 /* return 1 if this is not super block */
 static int print_super_block (struct buffer_head * bh)
 {
@@ -519,8 +530,7 @@
     printk ("Filesystem state %s\n", 
 	    (sb_state(rs) == REISERFS_VALID_FS) ? "VALID" : "ERROR");
     printk ("Hash function \"%s\"\n",
-            sb_hash_function_code(rs) == TEA_HASH ? "tea" :
-	    ( sb_hash_function_code(rs) == YURA_HASH ? "rupasov" : (sb_hash_function_code(rs) == R5_HASH ? "r5" : "unknown")));
+            reiserfs_hashname(sb_hash_function_code(rs)));
 
     printk ("Tree height %d\n", sb_tree_height(rs));
     return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/procfs.c linux/fs/reiserfs/procfs.c
--- linux.orig/fs/reiserfs/procfs.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/reiserfs/procfs.c	2002-07-20 01:08:30.000000000 +0000
@@ -172,6 +172,12 @@
 			"search_by_key_fs_changed: \t%lu\n"
 			"search_by_key_restarted: \t%lu\n"
 			
+			"insert_item_restarted: \t%lu\n"
+			"paste_into_item_restarted: \t%lu\n"
+			"cut_from_item_restarted: \t%lu\n"
+			"delete_solid_item_restarted: \t%lu\n"
+			"delete_item_restarted: \t%lu\n"
+
 			"leaked_oid: \t%lu\n"
 			"leaves_removable: \t%lu\n",
 
@@ -208,6 +214,13 @@
 			SFP( search_by_key ),
 			SFP( search_by_key_fs_changed ),
 			SFP( search_by_key_restarted ),
+
+			SFP( insert_item_restarted ),
+			SFP( paste_into_item_restarted ),
+			SFP( cut_from_item_restarted ),
+			SFP( delete_solid_item_restarted ),
+			SFP( delete_item_restarted ),
+
 			SFP( leaked_oid ),
 			SFP( leaves_removable ) );
 
@@ -341,6 +354,7 @@
 	struct reiserfs_sb_info *sb_info;
 	struct reiserfs_super_block *rs;
 	int hash_code;
+	__u32 flags;
 	int len = 0;
     
 	sb = procinfo_prologue( ( kdev_t ) ( long ) data );
@@ -349,6 +363,7 @@
 	sb_info = &sb->u.reiserfs_sb;
 	rs = sb_info -> s_rs;
 	hash_code = DFL( s_hash_function_code );
+	flags = DFL( s_flags );
 
 	len += sprintf( &buffer[ len ], 
 			"block_count: \t%i\n"
@@ -362,7 +377,8 @@
 			"hash: \t%s\n"
 			"tree_height: \t%i\n"
 			"bmap_nr: \t%i\n"
-			"version: \t%i\n",
+			"version: \t%i\n"
+			"flags: \t%x[%s]\n",
 
 			DFL( s_block_count ),
 			DFL( s_free_blocks ),
@@ -378,7 +394,10 @@
 			( hash_code == UNSET_HASH ) ? "unset" : "unknown",
 			DF( s_tree_height ),
 			DF( s_bmap_nr ),
-			DF( s_version ) );
+			DF( s_version ),
+			flags, 
+			( flags & reiserfs_attrs_cleared ) 
+			? "attrs_cleared" : "" );
 
 	procinfo_epilogue( sb );
 	return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/stree.c linux/fs/reiserfs/stree.c
--- linux.orig/fs/reiserfs/stree.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/reiserfs/stree.c	2002-07-20 01:08:27.000000000 +0000
@@ -166,7 +166,7 @@
     if (cpu_key_k_offset (key1) > cpu_key_k_offset (key2))
 	return 1;
 
-    reiserfs_warning ("comp_cpu_keys: type are compared for %k and %k\n",
+    reiserfs_warning ("comp_cpu_keys: type are compared for %K and %K\n",
 		      key1, key2);
 
     if (cpu_key_k_type (key1) < cpu_key_k_type (key2))
@@ -524,6 +524,10 @@
     ih = (struct item_head *)(buf + BLKH_SIZE);
     prev_location = blocksize;
     for (i = 0; i < nr; i ++, ih ++) {
+	if ( le_ih_k_type(ih) == TYPE_ANY) {
+	    reiserfs_warning ("is_leaf: wrong item type for item %h\n",ih);
+	    return 0;
+	}
 	if (ih_location (ih) >= blocksize || ih_location (ih) < IH_SIZE * nr) {
 	    reiserfs_warning ("is_leaf: item location seems wrong: %h\n", ih);
 	    return 0;
@@ -1242,6 +1246,8 @@
 	if ( n_ret_value != REPEAT_SEARCH )
 	    break;
 
+	PROC_INFO_INC( p_s_sb, delete_item_restarted );
+
 	// file system changed, repeat search
 	n_ret_value = search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
 	if (n_ret_value == IO_ERROR)
@@ -1339,8 +1345,10 @@
 	}
 	if (retval != ITEM_FOUND) {
 	    pathrelse (&path);
-	    reiserfs_warning ("vs-5355: reiserfs_delete_solid_item: %k not found",
-			      key);
+	    // No need for a warning, if there is just no free space to insert '..' item into the newly-created subdir
+	    if ( !( (unsigned long long) GET_HASH_VALUE (le_key_k_offset (le_key_version (key), key)) == 0 && \
+		 GET_GENERATION_NUMBER (le_key_k_offset (le_key_version (key), key)) == 1 ) )
+		reiserfs_warning ("vs-5355: reiserfs_delete_solid_item: %k not found", key);
 	    break;
 	}
 	if (!tb_init) {
@@ -1350,8 +1358,10 @@
 	}
 
 	retval = fix_nodes (M_DELETE, &tb, NULL, 0);
-	if (retval == REPEAT_SEARCH)
+	if (retval == REPEAT_SEARCH) {
+	    PROC_INFO_INC( th -> t_super, delete_solid_item_restarted );
 	    continue;
+	}
 
 	if (retval == CARRY_ON) {
 	    do_balance (&tb, 0, 0, M_DELETE);
@@ -1523,7 +1533,7 @@
 	    set_cpu_key_k_offset (p_s_item_key, n_new_file_size + 1);
 	    if ( search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_NOT_FOUND ){
 		print_block (PATH_PLAST_BUFFER (p_s_path), 3, PATH_LAST_POSITION (p_s_path) - 1, PATH_LAST_POSITION (p_s_path) + 1);
-		reiserfs_panic(p_s_sb, "PAP-5580: reiserfs_cut_from_item: item to convert does not exist (%k)", p_s_item_key);
+		reiserfs_panic(p_s_sb, "PAP-5580: reiserfs_cut_from_item: item to convert does not exist (%K)", p_s_item_key);
 	    }
 	    continue;
 	}
@@ -1538,6 +1548,8 @@
       	if ( n_ret_value != REPEAT_SEARCH )
 	    break;
 	
+	PROC_INFO_INC( p_s_sb, cut_from_item_restarted );
+
 	n_ret_value = search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
 	if (n_ret_value == POSITION_FOUND)
 	    continue;
@@ -1716,7 +1728,7 @@
 	}
 
 	RFALSE( n_deleted > n_file_size,
-		"PAP-5670: reiserfs_truncate_file returns too big number: deleted %d, file_size %lu, item_key %k",
+		"PAP-5670: reiserfs_truncate_file returns too big number: deleted %d, file_size %lu, item_key %K",
 		n_deleted, n_file_size, &s_item_key);
 
 	/* Change key to search the last file item. */
@@ -1805,6 +1817,7 @@
     
     while ( (retval = fix_nodes(M_PASTE, &s_paste_balance, NULL, p_c_body)) == REPEAT_SEARCH ) {
 	/* file system changed while we were in the fix_nodes */
+	PROC_INFO_INC( th -> t_super, paste_into_item_restarted );
 	retval = search_for_position_by_key (th->t_super, p_s_key, p_s_search_path);
 	if (retval == IO_ERROR) {
 	    retval = -EIO ;
@@ -1855,6 +1868,7 @@
 
     while ( (retval = fix_nodes(M_INSERT, &s_ins_balance, p_s_ih, p_c_body)) == REPEAT_SEARCH) {
 	/* file system changed while we were in the fix_nodes */
+	PROC_INFO_INC( th -> t_super, insert_item_restarted );
 	retval = search_item (th->t_super, key, p_s_path);
 	if (retval == IO_ERROR) {
 	    retval = -EIO;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/super.c linux/fs/reiserfs/super.c
--- linux.orig/fs/reiserfs/super.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/reiserfs/super.c	2002-07-20 01:08:35.000000000 +0000
@@ -207,7 +207,7 @@
         }
  
         iput (inode);
-        reiserfs_warning ("done\n");
+        printk ("done\n");
         done ++;
     }
     s -> u.reiserfs_sb.s_is_unlinked_ok = 0;
@@ -269,7 +269,8 @@
     /* look for its place in the tree */
     retval = search_item (inode->i_sb, &key, &path);
     if (retval != ITEM_NOT_FOUND) {
-	reiserfs_warning ("vs-2100: add_save_link:"
+	if ( retval != -ENOSPC )
+	    reiserfs_warning ("vs-2100: add_save_link:"
 			  "search_by_key (%K) returned %d\n", &key, retval);
 	pathrelse (&path);
 	return;
@@ -280,10 +281,11 @@
 
     /* put "save" link inot tree */
     retval = reiserfs_insert_item (th, &path, &key, &ih, (char *)&link);
-    if (retval)
-	reiserfs_warning ("vs-2120: add_save_link: insert_item returned %d\n",
+    if (retval) {
+	if (retval != -ENOSPC)
+	    reiserfs_warning ("vs-2120: add_save_link: insert_item returned %d\n",
 			  retval);
-    else {
+    } else {
 	if( truncate )
 	    inode -> u.reiserfs_i.i_flags |= i_link_saved_truncate_mask;
 	else
@@ -488,6 +490,8 @@
 	  	printk("reiserfs: hash option requires a value\n");
 		return 0 ;
 	    }
+	} else if (!strcmp (this_char, "attrs")) {
+	    set_bit (REISERFS_ATTRS, mount_options);
 	} else {
 	    printk ("reiserfs: Unrecognized mount option %s\n", this_char);
 	    return 0;
@@ -502,6 +506,24 @@
 }
 
 
+static void handle_attrs( struct super_block *s )
+{
+	struct reiserfs_super_block * rs;
+
+	if( reiserfs_attrs( s ) ) {
+		rs = SB_DISK_SUPER_BLOCK (s);
+		if( old_format_only(s) ) {
+			reiserfs_warning( "reiserfs: cannot support attributes on 3.5.x disk format\n" );
+			s -> u.reiserfs_sb.s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
+			return;
+		}
+		if( !( le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared ) ) {
+				reiserfs_warning( "reiserfs: cannot support attributes until flag is set in super-block\n" );
+				s -> u.reiserfs_sb.s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
+		}
+	}
+}
+
 //
 // a portion of this function, particularly the VFS interface portion,
 // was derived from minix or ext2's analog and evolved as the
@@ -514,13 +536,28 @@
   struct reiserfs_super_block * rs;
   struct reiserfs_transaction_handle th ;
   unsigned long blocks;
-  unsigned long mount_options;
+  unsigned long mount_options = 0;
 
   rs = SB_DISK_SUPER_BLOCK (s);
 
   if (!parse_options(data, &mount_options, &blocks))
   	return 0;
 
+#define SET_OPT( opt, bits, super )					\
+    if( ( bits ) & ( 1 << ( opt ) ) )					\
+	    ( super ) -> u.reiserfs_sb.s_mount_opt |= ( 1 << ( opt ) )
+
+  /* set options in the super-block bitmask */
+  SET_OPT( NOTAIL, mount_options, s );
+  SET_OPT( REISERFS_NO_BORDER, mount_options, s );
+  SET_OPT( REISERFS_NO_UNHASHED_RELOCATION, mount_options, s );
+  SET_OPT( REISERFS_HASHED_RELOCATION, mount_options, s );
+  SET_OPT( REISERFS_TEST4, mount_options, s );
+  SET_OPT( REISERFS_ATTRS, mount_options, s );
+#undef SET_OPT
+
+  handle_attrs( s );
+
   if(blocks) {
       int rc = reiserfs_resize(s, blocks);
       if (rc != 0)
@@ -572,28 +609,30 @@
 
 static int read_bitmaps (struct super_block * s)
 {
-    int i, bmp, dl ;
-    struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s);
+    int i, bmp;
 
-    SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * sb_bmap_nr(rs), GFP_NOFS, s);
+    SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * SB_BMAP_NR(s), GFP_NOFS, s);
     if (SB_AP_BITMAP (s) == 0)
+      return 1;
+    for (i = 0, bmp = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
+ 	 i < SB_BMAP_NR(s); i++, bmp = s->s_blocksize * 8 * i) {
+      SB_AP_BITMAP (s)[i] = getblk (s->s_dev, bmp, s->s_blocksize);
+      if (!buffer_uptodate(SB_AP_BITMAP(s)[i]))
+	ll_rw_block(READ, 1, SB_AP_BITMAP(s) + i); 
+    }
+    for (i = 0; i < SB_BMAP_NR(s); i++) {
+      wait_on_buffer(SB_AP_BITMAP (s)[i]);
+      if (!buffer_uptodate(SB_AP_BITMAP(s)[i])) {
+	reiserfs_warning("sh-2029: reiserfs read_bitmaps: "
+			 "bitmap block (#%lu) reading failed\n",
+			 SB_AP_BITMAP(s)[i]->b_blocknr);
+	for (i = 0; i < SB_BMAP_NR(s); i++)
+	  brelse(SB_AP_BITMAP(s)[i]);
+	reiserfs_kfree(SB_AP_BITMAP(s), sizeof(struct buffer_head *) * SB_BMAP_NR(s), s);
+	SB_AP_BITMAP(s) = NULL;
 	return 1;
-    memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * sb_bmap_nr(rs));
-
-    /* reiserfs leaves the first 64k unused so that any partition
-       labeling scheme currently used will have enough space. Then we
-       need one block for the super.  -Hans */
-    bmp = (REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1;	/* first of bitmap blocks */
-    SB_AP_BITMAP (s)[0] = reiserfs_bread (s, bmp, s->s_blocksize);
-    if(!SB_AP_BITMAP(s)[0])
-	return 1;
-    for (i = 1, bmp = dl = s->s_blocksize * 8; i < sb_bmap_nr(rs); i ++) {
-	SB_AP_BITMAP (s)[i] = reiserfs_bread (s, bmp, s->s_blocksize);
-	if (!SB_AP_BITMAP (s)[i])
-	    return 1;
-	bmp += dl;
-    }
-
+      }
+    }   
     return 0;
 }
 
@@ -704,8 +743,18 @@
 	       "It must not be of this format type.\n", bh->b_blocknr) ;
 	return 1 ;
     }
+
+    if ( rs->s_root_block == -1 ) {
+	brelse(bh) ;
+	printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
+	       "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
+	       "get newer reiserfsprogs package\n", kdevname (s->s_dev));
+	return 1;
+    }
+
     SB_BUFFER_WITH_SB (s) = bh;
     SB_DISK_SUPER_BLOCK (s) = rs;
+
     s->s_op = &reiserfs_sops;
 
     /* new format is limited by the 32 bit wide i_blocks field, want to
@@ -760,7 +809,9 @@
 
     inode = s->s_root->d_inode;
 
-    while (1) {
+    do { // Some serious "goto"-hater was there ;)
+	u32 teahash, r5hash, yurahash;
+
 	make_cpu_key (&key, inode, ~0, TYPE_DIRENTRY, 3);
 	retval = search_by_entry_key (s, &key, &path, &de);
 	if (retval == IO_ERROR) {
@@ -779,20 +830,30 @@
 	                     "is using the default hash\n");
 	    break;
 	}
-	if (GET_HASH_VALUE(yura_hash (de.de_name, de.de_namelen)) == 
-	    GET_HASH_VALUE(keyed_hash (de.de_name, de.de_namelen))) {
-	    reiserfs_warning ("reiserfs: Could not detect hash function "
-			      "please mount with -o hash={tea,rupasov,r5}\n") ;
-	    hash = UNSET_HASH ;
+	r5hash=GET_HASH_VALUE (r5_hash (de.de_name, de.de_namelen));
+	teahash=GET_HASH_VALUE (keyed_hash (de.de_name, de.de_namelen));
+	yurahash=GET_HASH_VALUE (yura_hash (de.de_name, de.de_namelen));
+	if ( ( (teahash == r5hash) && (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash) ) ||
+	     ( (teahash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ||
+	     ( (r5hash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ) {
+	    reiserfs_warning("reiserfs: Unable to automatically detect hash"
+		"function for device %s\n"
+		"please mount with -o hash={tea,rupasov,r5}\n", kdevname (s->s_dev));
+	    hash = UNSET_HASH;
 	    break;
 	}
-	if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) ==
-	    GET_HASH_VALUE (yura_hash (de.de_name, de.de_namelen)))
+	if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == yurahash)
 	    hash = YURA_HASH;
-	else
+	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == teahash)
 	    hash = TEA_HASH;
-	break;
-    }
+	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == r5hash)
+	    hash = R5_HASH;
+	else {
+	    reiserfs_warning("reiserfs: Unrecognised hash function for "
+			     "device %s\n", kdevname (s->s_dev));
+	    hash = UNSET_HASH;
+	}
+    } while (0);
 
     pathrelse (&path);
     return hash;
@@ -817,16 +878,16 @@
 	** mount options 
 	*/
 	if (reiserfs_rupasov_hash(s) && code != YURA_HASH) {
-	    printk("REISERFS: Error, tea hash detected, "
-		   "unable to force rupasov hash\n") ;
+	    printk("REISERFS: Error, %s hash detected, "
+		   "unable to force rupasov hash\n", reiserfs_hashname(code)) ;
 	    code = UNSET_HASH ;
 	} else if (reiserfs_tea_hash(s) && code != TEA_HASH) {
-	    printk("REISERFS: Error, rupasov hash detected, "
-		   "unable to force tea hash\n") ;
+	    printk("REISERFS: Error, %s hash detected, "
+		   "unable to force tea hash\n", reiserfs_hashname(code)) ;
 	    code = UNSET_HASH ;
 	} else if (reiserfs_r5_hash(s) && code != R5_HASH) {
-	    printk("REISERFS: Error, r5 hash detected, "
-		   "unable to force r5 hash\n") ;
+	    printk("REISERFS: Error, %s hash detected, "
+		   "unable to force r5 hash\n", reiserfs_hashname(code)) ;
 	    code = UNSET_HASH ;
 	} 
     } else { 
@@ -934,6 +995,8 @@
 	    old_format = 1;
     }
 
+    rs = SB_DISK_SUPER_BLOCK (s);
+
     s->u.reiserfs_sb.s_mount_state = SB_REISERFS_STATE(s);
     s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ;
 
@@ -1034,6 +1097,8 @@
     // mark hash in super block: it could be unset. overwrite should be ok
     set_sb_hash_function_code( rs, function2code(s->u.reiserfs_sb.s_hash_function ) );
 
+    handle_attrs( s );
+
     reiserfs_proc_info_init( s );
     reiserfs_proc_register( s, "version", reiserfs_version_in_proc );
     reiserfs_proc_register( s, "super", reiserfs_super_in_proc );
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/reiserfs/tail_conversion.c linux/fs/reiserfs/tail_conversion.c
--- linux.orig/fs/reiserfs/tail_conversion.c	2001-12-21 17:42:03.000000000 +0000
+++ linux/fs/reiserfs/tail_conversion.c	2002-07-20 01:08:37.000000000 +0000
@@ -49,9 +49,13 @@
     make_cpu_key (&end_key, inode, tail_offset, TYPE_INDIRECT, 4);
 
     // FIXME: we could avoid this 
-    if ( search_for_position_by_key (sb, &end_key, path) == POSITION_FOUND )
-	reiserfs_panic (sb, "PAP-14030: direct2indirect: "
-			"pasted or inserted byte exists in the tree");
+    if ( search_for_position_by_key (sb, &end_key, path) == POSITION_FOUND ) {
+	reiserfs_warning ("PAP-14030: direct2indirect: "
+			"pasted or inserted byte exists in the tree %K. "
+			"Use fsck to repair.\n", &end_key);
+	pathrelse(path);
+	return -EIO;
+    }
     
     p_le_ih = PATH_PITEM_HEAD (path);
 
@@ -90,10 +94,10 @@
            last item of the file */
 	if ( search_for_position_by_key (sb, &end_key, path) == POSITION_FOUND )
 	    reiserfs_panic (sb, "PAP-14050: direct2indirect: "
-			    "direct item (%k) not found", &end_key);
+			    "direct item (%K) not found", &end_key);
 	p_le_ih = PATH_PITEM_HEAD (path);
 	RFALSE( !is_direct_le_ih (p_le_ih),
-	        "vs-14055: direct item expected(%k), found %h",
+	        "vs-14055: direct item expected(%K), found %h",
                 &end_key, p_le_ih);
         tail_size = (le_ih_k_offset (p_le_ih) & (n_blk_size - 1))
             + ih_item_len(p_le_ih) - 1;
@@ -227,7 +231,7 @@
 	/* re-search indirect item */
 	if ( search_for_position_by_key (p_s_sb, p_s_item_key, p_s_path) == POSITION_NOT_FOUND )
 	    reiserfs_panic(p_s_sb, "PAP-5520: indirect2direct: "
-			   "item to be converted %k does not exist", p_s_item_key);
+			   "item to be converted %K does not exist", p_s_item_key);
 	copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
 #ifdef CONFIG_REISERFS_CHECK
 	pos = le_ih_k_offset (&s_ih) - 1 + 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/smbfs/cache.c linux/fs/smbfs/cache.c
--- linux.orig/fs/smbfs/cache.c	2001-10-03 00:03:34.000000000 +0000
+++ linux/fs/smbfs/cache.c	2002-07-20 01:08:22.000000000 +0000
@@ -84,7 +84,7 @@
 	struct list_head *next;
 
 	if (d_validate(dent, parent)) {
-		if (dent->d_name.len <= SMB_MAXPATHLEN &&
+		if (dent->d_name.len <= SMB_MAXNAMELEN &&
 		    (unsigned long)dent->d_fsdata == fpos) {
 			if (!dent->d_inode) {
 				dput(dent);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/smbfs/proc.c linux/fs/smbfs/proc.c
--- linux.orig/fs/smbfs/proc.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/smbfs/proc.c	2002-07-20 01:08:26.000000000 +0000
@@ -109,6 +109,22 @@
 	return ilen;
 }
 
+static inline int write_char(unsigned char ch, char *output, int olen)
+{
+	if (olen < 4)
+		return -ENAMETOOLONG;
+	sprintf(output, ":x%02x", ch);
+	return 4;
+}
+
+static inline int write_unichar(wchar_t ch, char *output, int olen)
+{
+	if (olen < 5)
+		return -ENAMETOOLONG;
+	sprintf(output, ":%04x", ch);
+	return 5;
+}
+
 /* convert from one "codepage" to another (possibly being utf8). */
 static int convert_cp(char *output, int olen,
 		      const char *input, int ilen,
@@ -119,20 +135,26 @@
 	int n;
 	wchar_t ch;
 
-	if (!nls_from || !nls_to) {
-		PARANOIA("nls_from=%p, nls_to=%p\n", nls_from, nls_to);
-		return convert_memcpy(output, olen, input, ilen, NULL, NULL);
-	}
-
 	while (ilen > 0) {
 		/* convert by changing to unicode and back to the new cp */
 		n = nls_from->char2uni((unsigned char *)input, ilen, &ch);
-		if (n < 0)
+		if (n == -EINVAL) {
+			ilen--;
+			n = write_char(*input++, output, olen);
+			if (n < 0)
+				goto fail;
+			output += n;
+			olen -= n;
+			len += n;
+			continue;
+		} else if (n < 0)
 			goto fail;
 		input += n;
 		ilen -= n;
 
 		n = nls_to->uni2char(ch, output, olen);
+		if (n == -EINVAL)
+			n = write_unichar(ch, output, olen);
 		if (n < 0)
 			goto fail;
 		output += n;
@@ -226,8 +248,8 @@
 	if (maxlen < 2)
 		return -ENAMETOOLONG;
 
-	if (maxlen > SMB_MAXNAMELEN + 1)
-		maxlen = SMB_MAXNAMELEN + 1;
+	if (maxlen > SMB_MAXPATHLEN + 1)
+		maxlen = SMB_MAXPATHLEN + 1;
 
 	if (entry == NULL)
 		goto test_name_and_out;
@@ -1579,12 +1601,16 @@
 	}
 #endif
 
-	qname->len = server->convert(server->name_buf, SMB_MAXNAMELEN,
-				     qname->name, len,
-				     server->remote_nls, server->local_nls);
-	qname->name = server->name_buf;
+	qname->len = 0;
+	len = server->convert(server->name_buf, SMB_MAXNAMELEN,
+			    qname->name, len,
+			    server->remote_nls, server->local_nls);
+	if (len > 0) {
+		qname->len = len;
+		qname->name = server->name_buf;
+		DEBUG1("len=%d, name=%.*s\n",qname->len,qname->len,qname->name);
+	}
 
-	DEBUG1("len=%d, name=%.*s\n", qname->len, qname->len, qname->name);
 	return p + 22;
 }
 
@@ -1700,7 +1726,8 @@
 		for (i = 0; i < count; i++) {
 			p = smb_decode_short_dirent(server, p, 
 						    &qname, &fattr);
-
+			if (qname.len == 0)
+				continue;
 			if (entries_seen == 2 && qname.name[0] == '.') {
 				if (qname.len == 1)
 					continue;
@@ -1737,6 +1764,7 @@
 {
 	char *result;
 	unsigned int len = 0;
+	int n;
 	__u16 date, time;
 
 	/*
@@ -1812,10 +1840,14 @@
 	}
 #endif
 
-	qname->len = server->convert(server->name_buf, SMB_MAXNAMELEN,
-				     qname->name, len,
-				     server->remote_nls, server->local_nls);
-	qname->name = server->name_buf;
+	qname->len = 0;
+	n = server->convert(server->name_buf, SMB_MAXNAMELEN,
+			    qname->name, len,
+			    server->remote_nls, server->local_nls);
+	if (n > 0) {
+		qname->len = n;
+		qname->name = server->name_buf;
+	}
 
 out:
 	return result;
@@ -1881,7 +1913,7 @@
 	 */
 	mask = param + 12;
 
-	mask_len = smb_encode_path(server, mask, SMB_MAXNAMELEN+1, dir, &star);
+	mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);
 	if (mask_len < 0) {
 		result = mask_len;
 		goto unlock_return;
@@ -2030,6 +2062,8 @@
 
 			p = smb_decode_long_dirent(server, p, info_level,
 						   &qname, &fattr);
+			if (qname.len == 0)
+				continue;
 
 			/* ignore . and .. from the server */
 			if (entries_seen == 2 && qname.name[0] == '.') {
@@ -2088,7 +2122,7 @@
 	int mask_len, result;
 
 retry:
-	mask_len = smb_encode_path(server, mask, SMB_MAXNAMELEN+1, dentry, NULL);
+	mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dentry, NULL);
 	if (mask_len < 0) {
 		result = mask_len;
 		goto out;
@@ -2214,7 +2248,7 @@
       retry:
 	WSET(param, 0, 1);	/* Info level SMB_INFO_STANDARD */
 	DSET(param, 2, 0);
-	result = smb_encode_path(server, param+6, SMB_MAXNAMELEN+1, dir, NULL);
+	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
 	if (result < 0)
 		goto out;
 	p = param + 6 + result;
@@ -2464,7 +2498,7 @@
       retry:
 	WSET(param, 0, 1);	/* Info level SMB_INFO_STANDARD */
 	DSET(param, 2, 0);
-	result = smb_encode_path(server, param+6, SMB_MAXNAMELEN+1, dir, NULL);
+	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
 	if (result < 0)
 		goto out;
 	p = param + 6 + result;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/super.c linux/fs/super.c
--- linux.orig/fs/super.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/super.c	2002-07-20 01:08:35.000000000 +0000
@@ -21,36 +21,19 @@
  */
 
 #include <linux/config.h>
-#include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/fd.h>
-#include <linux/init.h>
 #include <linux/major.h>
-#include <linux/quotaops.h>
 #include <linux/acct.h>
 
 #include <asm/uaccess.h>
 
-#include <linux/nfs_fs.h>
-#include <linux/nfs_fs_sb.h>
-#include <linux/nfs_mount.h>
-
 #include <linux/kmod.h>
 #define __NO_VERSION__
 #include <linux/module.h>
 
-extern void wait_for_keypress(void);
-
-extern int root_mountflags;
-
-int do_remount_sb(struct super_block *sb, int flags, void * data);
-
-/* this is initialized in init/main.c */
-kdev_t ROOT_DEV;
-
 LIST_HEAD(super_blocks);
 spinlock_t sb_lock = SPIN_LOCK_UNLOCKED;
 
@@ -392,7 +375,7 @@
 	get_filesystem(type);
 }
 
-void put_unnamed_dev(kdev_t dev);	/* should become static */
+static void put_anon_dev(kdev_t dev);
 
 /**
  *	remove_super	-	makes superblock unreachable
@@ -422,16 +405,11 @@
 	if (bdev)
 		blkdev_put(bdev, BDEV_FS);
 	else
-		put_unnamed_dev(dev);
+		put_anon_dev(dev);
 }
 
-struct vfsmount *alloc_vfsmnt(void);
+struct vfsmount *alloc_vfsmnt(char *name);
 void free_vfsmnt(struct vfsmount *mnt);
-void set_devname(struct vfsmount *mnt, const char *name);
-
-/* Will go away */
-extern struct vfsmount *root_vfsmnt;
-extern int graft_tree(struct vfsmount *mnt, struct nameidata *nd);
 
 static inline struct super_block * find_super(kdev_t dev)
 {
@@ -549,35 +527,38 @@
 	return err;
 }
 
-static struct super_block * read_super(kdev_t dev, struct block_device *bdev,
-				       struct file_system_type *type, int flags,
-				       void *data)
+/**
+ *	do_remount_sb	-	asks filesystem to change mount options.
+ *	@sb:	superblock in question
+ *	@flags:	numeric part of options
+ *	@data:	the rest of options
+ *
+ *	Alters the mount options of a mounted file system.
+ */
+int do_remount_sb(struct super_block *sb, int flags, void *data)
 {
-	struct super_block * s;
-	s = alloc_super();
-	if (!s)
-		goto out;
-	s->s_dev = dev;
-	s->s_bdev = bdev;
-	s->s_flags = flags;
-	spin_lock(&sb_lock);
-	insert_super(s, type);
-	lock_super(s);
-	if (!type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
-		goto out_fail;
-	s->s_flags |= MS_ACTIVE;
-	unlock_super(s);
-	/* tell bdcache that we are going to keep this one */
-	if (bdev)
-		atomic_inc(&bdev->bd_count);
-out:
-	return s;
-
-out_fail:
-	unlock_super(s);
-	deactivate_super(s);
-	remove_super(s);
-	return NULL;
+	int retval;
+	
+	if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
+		return -EACCES;
+		/*flags |= MS_RDONLY;*/
+	if (flags & MS_RDONLY)
+		acct_auto_close(sb->s_dev);
+	shrink_dcache_sb(sb);
+	fsync_super(sb);
+	/* If we are remounting RDONLY, make sure there are no rw files open */
+	if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
+		if (!fs_may_remount_ro(sb))
+			return -EBUSY;
+	if (sb->s_op && sb->s_op->remount_fs) {
+		lock_super(sb);
+		retval = sb->s_op->remount_fs(sb, &flags, data);
+		unlock_super(sb);
+		if (retval)
+			return retval;
+	}
+	sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
+	return 0;
 }
 
 /*
@@ -585,31 +566,84 @@
  * filesystems which don't use real block-devices.  -- jrs
  */
 
-static unsigned long unnamed_dev_in_use[256/(8*sizeof(unsigned long))];
+enum {Max_anon = 256};
+static unsigned long unnamed_dev_in_use[Max_anon/(8*sizeof(unsigned long))];
+static spinlock_t unnamed_dev_lock = SPIN_LOCK_UNLOCKED;/* protects the above */
 
-kdev_t get_unnamed_dev(void)
+/**
+ *	put_anon_dev	-	release anonymous device number.
+ *	@dev:	device in question
+ */
+static void put_anon_dev(kdev_t dev)
 {
-	int i;
-
-	for (i = 1; i < 256; i++) {
-		if (!test_and_set_bit(i,unnamed_dev_in_use))
-			return MKDEV(UNNAMED_MAJOR, i);
-	}
-	return 0;
+	spin_lock(&unnamed_dev_lock);
+	clear_bit(MINOR(dev), unnamed_dev_in_use);
+	spin_unlock(&unnamed_dev_lock);
 }
 
-void put_unnamed_dev(kdev_t dev)
+/**
+ *	get_anon_super	-	allocate a superblock for non-device fs
+ *	@type:		filesystem type
+ *	@compare:	check if existing superblock is what we want
+ *	@data:		argument for @compare.
+ *
+ *	get_anon_super is a helper for non-blockdevice filesystems.
+ *	It either finds and returns one of the superblocks of given type
+ *	(if it can find one that would satisfy caller) or creates a new
+ *	one.  In the either case we return an active reference to superblock
+ *	with ->s_umount locked.  If superblock is new it gets a new
+ *	anonymous device allocated for it and is inserted into lists -
+ *	other initialization is left to caller.
+ *
+ *	Rather than duplicating all that logics every time when
+ *	we want something that doesn't fit "nodev" and "single" we pull
+ *	the relevant code into common helper and let get_sb_...() call
+ *	it.
+ *
+ *	NB: get_sb_...() is going to become an fs type method, with
+ *	current ->read_super() becoming a callback used by common instances.
+ */
+struct super_block *get_anon_super(struct file_system_type *type,
+	int (*compare)(struct super_block *,void *), void *data)
 {
-	if (!dev || MAJOR(dev) != UNNAMED_MAJOR)
-		return;
-	if (test_and_clear_bit(MINOR(dev), unnamed_dev_in_use))
-		return;
-	printk("VFS: put_unnamed_dev: freeing unused device %s\n",
-			kdevname(dev));
+	struct super_block *s = alloc_super();
+	kdev_t dev;
+	struct list_head *p;
+
+	if (!s)
+		return ERR_PTR(-ENOMEM);
+
+retry:
+	spin_lock(&sb_lock);
+	if (compare) list_for_each(p, &type->fs_supers) {
+		struct super_block *old;
+		old = list_entry(p, struct super_block, s_instances);
+		if (!compare(old, data))
+			continue;
+		if (!grab_super(old))
+			goto retry;
+		destroy_super(s);
+		return old;
+	}
+
+	spin_lock(&unnamed_dev_lock);
+	dev = find_first_zero_bit(unnamed_dev_in_use, Max_anon);
+	if (dev == Max_anon) {
+		spin_unlock(&unnamed_dev_lock);
+		spin_unlock(&sb_lock);
+		destroy_super(s);
+		return ERR_PTR(-EMFILE);
+	}
+	set_bit(dev, unnamed_dev_in_use);
+	spin_unlock(&unnamed_dev_lock);
+
+	s->s_dev = dev;
+	insert_super(s, type);
+	return s;
 }
 
 static struct super_block *get_sb_bdev(struct file_system_type *fs_type,
-	char *dev_name, int flags, void * data)
+	int flags, char *dev_name, void * data)
 {
 	struct inode *inode;
 	struct block_device *bdev;
@@ -651,17 +685,13 @@
 		goto out;
 	check_disk_change(dev);
 	error = -EACCES;
-	if (!(flags & MS_RDONLY) && is_read_only(dev)) {
-		blkdev_put(bdev, BDEV_FS);
-		goto out;
-	}
+	if (!(flags & MS_RDONLY) && is_read_only(dev))
+		goto out1;
 
 	error = -ENOMEM;
 	s = alloc_super();
-	if (!s) {
-		blkdev_put(bdev, BDEV_FS);
-		goto out;
-	}
+	if (!s)
+		goto out1;
 
 	error = -EBUSY;
 restart:
@@ -675,8 +705,7 @@
 		    ((flags ^ old->s_flags) & MS_RDONLY)) {
 			spin_unlock(&sb_lock);
 			destroy_super(s);
-			blkdev_put(bdev, BDEV_FS);
-			goto out;
+			goto out1;
 		}
 		if (!grab_super(old))
 			goto restart;
@@ -689,85 +718,102 @@
 	s->s_bdev = bdev;
 	s->s_flags = flags;
 	insert_super(s, fs_type);
-
-	error = -EINVAL;
-	lock_super(s);
 	if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
-		goto out_fail;
+		goto Einval;
 	s->s_flags |= MS_ACTIVE;
-	unlock_super(s);
 	path_release(&nd);
 	return s;
 
-out_fail:
-	unlock_super(s);
+Einval:
 	deactivate_super(s);
 	remove_super(s);
+	error = -EINVAL;
+	goto out;
+out1:
+	blkdev_put(bdev, BDEV_FS);
 out:
 	path_release(&nd);
 	return ERR_PTR(error);
 }
 
 static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
-	int flags, void * data)
+	int flags, char *dev_name, void *data)
 {
-	kdev_t dev;
-	int error = -EMFILE;
-	dev = get_unnamed_dev();
-	if (dev) {
-		struct super_block * sb;
-		error = -EINVAL;
-		sb = read_super(dev, NULL, fs_type, flags, data);
-		if (sb)
-			return sb;
+	struct super_block *s = get_anon_super(fs_type, NULL, NULL);
+
+	if (IS_ERR(s))
+		return s;
+
+	s->s_flags = flags;
+	if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
+		deactivate_super(s);
+		remove_super(s);
+		return ERR_PTR(-EINVAL);
 	}
-	return ERR_PTR(error);
+	s->s_flags |= MS_ACTIVE;
+	return s;
+}
+
+static int compare_single(struct super_block *s, void *p)
+{
+	return 1;
 }
 
 static struct super_block *get_sb_single(struct file_system_type *fs_type,
-	int flags, void *data)
+	int flags, char *dev_name, void *data)
 {
-	struct super_block * s = alloc_super();
-	if (!s)
-		return ERR_PTR(-ENOMEM);
-	/*
-	 * Get the superblock of kernel-wide instance, but
-	 * keep the reference to fs_type.
-	 */
-retry:
-	spin_lock(&sb_lock);
-	if (!list_empty(&fs_type->fs_supers)) {
-		struct super_block *old;
-		old = list_entry(fs_type->fs_supers.next, struct super_block,
-				s_instances);
-		if (!grab_super(old))
-			goto retry;
-		destroy_super(s);
-		do_remount_sb(old, flags, data);
-		return old;
-	} else {
-		kdev_t dev = get_unnamed_dev();
-		if (!dev) {
-			spin_unlock(&sb_lock);
-			destroy_super(s);
-			return ERR_PTR(-EMFILE);
-		}
-		s->s_dev = dev;
+	struct super_block *s = get_anon_super(fs_type, compare_single, NULL);
+
+	if (IS_ERR(s))
+		return s;
+	if (!s->s_root) {
 		s->s_flags = flags;
-		insert_super(s, fs_type);
-		lock_super(s);
-		if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
-			goto out_fail;
+		if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
+			deactivate_super(s);
+			remove_super(s);
+			return ERR_PTR(-EINVAL);
+		}
 		s->s_flags |= MS_ACTIVE;
-		unlock_super(s);
-		return s;
-
-	out_fail:
-		unlock_super(s);
-		deactivate_super(s);
-		remove_super(s);
-		return ERR_PTR(-EINVAL);
 	}
+	do_remount_sb(s, flags, data);
+	return s;
+}
+
+struct vfsmount *
+do_kern_mount(const char *fstype, int flags, char *name, void *data)
+{
+	struct file_system_type *type = get_fs_type(fstype);
+	struct super_block *sb = ERR_PTR(-ENOMEM);
+	struct vfsmount *mnt;
+
+	if (!type)
+		return ERR_PTR(-ENODEV);
+
+	mnt = alloc_vfsmnt(name);
+	if (!mnt)
+		goto out;
+	if (type->fs_flags & FS_REQUIRES_DEV)
+		sb = get_sb_bdev(type, flags, name, data);
+	else if (type->fs_flags & FS_SINGLE)
+		sb = get_sb_single(type, flags, name, data);
+	else
+		sb = get_sb_nodev(type, flags, name, data);
+	if (IS_ERR(sb))
+		goto out_mnt;
+	if (type->fs_flags & FS_NOMOUNT)
+		sb->s_flags |= MS_NOUSER;
+	mnt->mnt_sb = sb;
+	mnt->mnt_root = dget(sb->s_root);
+	mnt->mnt_mountpoint = sb->s_root;
+	mnt->mnt_parent = mnt;
+	up_write(&sb->s_umount);
+	put_filesystem(type);
+	return mnt;
+out_mnt:
+	free_vfsmnt(mnt);
+out:
+	put_filesystem(type);
+	return (struct vfsmount *)sb;
 }
 
 void kill_super(struct super_block *sb)
@@ -780,7 +826,6 @@
 		return;
 
 	down_write(&sb->s_umount);
-	lock_kernel();
 	sb->s_root = NULL;
 	/* Need to clean after the sucker */
 	if (fs->fs_flags & FS_LITTER)
@@ -789,6 +834,7 @@
 	dput(root);
 	fsync_super(sb);
 	lock_super(sb);
+	lock_kernel();
 	sb->s_flags &= ~MS_ACTIVE;
 	invalidate_inodes(sb);	/* bad name - it should be evict_inodes() */
 	if (sop) {
@@ -800,7 +846,7 @@
 
 	/* Forget any remaining inodes */
 	if (invalidate_inodes(sb)) {
-		printk("VFS: Busy inodes after unmount. "
+		printk(KERN_ERR "VFS: Busy inodes after unmount. "
 			"Self-destruct in 5 seconds.  Have a nice day...\n");
 	}
 
@@ -809,313 +855,7 @@
 	remove_super(sb);
 }
 
-/*
- * Alters the mount flags of a mounted file system. Only the mount point
- * is used as a reference - file system type and the device are ignored.
- */
-
-int do_remount_sb(struct super_block *sb, int flags, void *data)
-{
-	int retval;
-	
-	if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
-		return -EACCES;
-		/*flags |= MS_RDONLY;*/
-	if (flags & MS_RDONLY)
-		acct_auto_close(sb->s_dev);
-	shrink_dcache_sb(sb);
-	fsync_super(sb);
-	/* If we are remounting RDONLY, make sure there are no rw files open */
-	if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
-		if (!fs_may_remount_ro(sb))
-			return -EBUSY;
-	if (sb->s_op && sb->s_op->remount_fs) {
-		lock_super(sb);
-		retval = sb->s_op->remount_fs(sb, &flags, data);
-		unlock_super(sb);
-		if (retval)
-			return retval;
-	}
-	sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
-
-	/*
-	 * We can't invalidate inodes as we can loose data when remounting
-	 * (someone might manage to alter data while we are waiting in lock_super()
-	 * or in foo_remount_fs()))
-	 */
-
-	return 0;
-}
-
-struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data)
-{
-	struct file_system_type * fstype;
-	struct vfsmount *mnt = NULL;
-	struct super_block *sb;
-
-	if (!type || !memchr(type, 0, PAGE_SIZE))
-		return ERR_PTR(-EINVAL);
-
-	/* we need capabilities... */
-	if (!capable(CAP_SYS_ADMIN))
-		return ERR_PTR(-EPERM);
-
-	/* ... filesystem driver... */
-	fstype = get_fs_type(type);
-	if (!fstype)		
-		return ERR_PTR(-ENODEV);
-
-	/* ... allocated vfsmount... */
-	mnt = alloc_vfsmnt();
-	if (!mnt) {
-		mnt = ERR_PTR(-ENOMEM);
-		goto fs_out;
-	}
-	set_devname(mnt, name);
-	/* get locked superblock */
-	if (fstype->fs_flags & FS_REQUIRES_DEV)
-		sb = get_sb_bdev(fstype, name, flags, data);
-	else if (fstype->fs_flags & FS_SINGLE)
-		sb = get_sb_single(fstype, flags, data);
-	else
-		sb = get_sb_nodev(fstype, flags, data);
-
-	if (IS_ERR(sb)) {
-		free_vfsmnt(mnt);
-		mnt = (struct vfsmount *)sb;
-		goto fs_out;
-	}
-	if (fstype->fs_flags & FS_NOMOUNT)
-		sb->s_flags |= MS_NOUSER;
-
-	mnt->mnt_sb = sb;
-	mnt->mnt_root = dget(sb->s_root);
-	mnt->mnt_mountpoint = mnt->mnt_root;
-	mnt->mnt_parent = mnt;
-	up_write(&sb->s_umount);
-fs_out:
-	put_filesystem(fstype);
-	return mnt;
-}
-
 struct vfsmount *kern_mount(struct file_system_type *type)
 {
-	return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
-}
-
-static char * __initdata root_mount_data;
-static int __init root_data_setup(char *str)
-{
-	root_mount_data = str;
-	return 1;
-}
-
-static char * __initdata root_fs_names;
-static int __init fs_names_setup(char *str)
-{
-	root_fs_names = str;
-	return 1;
-}
-
-__setup("rootflags=", root_data_setup);
-__setup("rootfstype=", fs_names_setup);
-
-static void __init get_fs_names(char *page)
-{
-	char *s = page;
-
-	if (root_fs_names) {
-		strcpy(page, root_fs_names);
-		while (*s++) {
-			if (s[-1] == ',')
-				s[-1] = '\0';
-		}
-	} else {
-		int len = get_filesystem_list(page);
-		char *p, *next;
-
-		page[len] = '\0';
-		for (p = page-1; p; p = next) {
-			next = strchr(++p, '\n');
-			if (*p++ != '\t')
-				continue;
-			while ((*s++ = *p++) != '\n')
-				;
-			s[-1] = '\0';
-		}
-	}
-	*s = '\0';
-}
-
-void __init mount_root(void)
-{
-	struct nameidata root_nd;
-	struct super_block * sb;
-	struct vfsmount *vfsmnt;
-	struct block_device *bdev = NULL;
-	mode_t mode;
-	int retval;
-	void *handle;
-	char path[64];
-	int path_start = -1;
-	char *name = "/dev/root";
-	char *fs_names, *p;
-#ifdef CONFIG_ROOT_NFS
-	void *data;
-#endif
-	root_mountflags |= MS_VERBOSE;
-
-#ifdef CONFIG_ROOT_NFS
-	if (MAJOR(ROOT_DEV) != UNNAMED_MAJOR)
-		goto skip_nfs;
-	data = nfs_root_data();
-	if (!data)
-		goto no_nfs;
-	vfsmnt = do_kern_mount("nfs", root_mountflags, "/dev/root", data);
-	if (!IS_ERR(vfsmnt)) {
-		printk ("VFS: Mounted root (%s filesystem).\n", "nfs");
-		ROOT_DEV = vfsmnt->mnt_sb->s_dev;
-		goto attach_it;
-	}
-no_nfs:
-	printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
-	ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
-skip_nfs:
-#endif
-
-#ifdef CONFIG_BLK_DEV_FD
-	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
-#ifdef CONFIG_BLK_DEV_RAM
-		extern int rd_doload;
-		extern void rd_load_secondary(void);
-#endif
-		floppy_eject();
-#ifndef CONFIG_BLK_DEV_RAM
-		printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
-#else
-		/* rd_doload is 2 for a dual initrd/ramload setup */
-		if(rd_doload==2)
-			rd_load_secondary();
-		else
-#endif
-		{
-			printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
-			wait_for_keypress();
-		}
-	}
-#endif
-
-	fs_names = __getname();
-	get_fs_names(fs_names);
-
-	devfs_make_root (root_device_name);
-	handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
-	                            MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
-				    DEVFS_SPECIAL_BLK, 1);
-	if (handle)  /*  Sigh: bd*() functions only paper over the cracks  */
-	{
-	    unsigned major, minor;
-
-	    devfs_get_maj_min (handle, &major, &minor);
-	    ROOT_DEV = MKDEV (major, minor);
-	}
-
-	/*
-	 * Probably pure paranoia, but I'm less than happy about delving into
-	 * devfs crap and checking it right now. Later.
-	 */
-	if (!ROOT_DEV)
-		panic("I have no root and I want to scream");
-
-retry:
-	bdev = bdget(kdev_t_to_nr(ROOT_DEV));
-	if (!bdev)
-		panic(__FUNCTION__ ": unable to allocate root device");
-	bdev->bd_op = devfs_get_ops (handle); /* Increments module use count */
-	path_start = devfs_generate_path (handle, path + 5, sizeof (path) - 5);
-	mode = FMODE_READ;
-	if (!(root_mountflags & MS_RDONLY))
-		mode |= FMODE_WRITE;
-	retval = blkdev_get(bdev, mode, 0, BDEV_FS);
-	devfs_put_ops (handle); /* Decrement module use count now we're safe */
-	if (retval == -EROFS) {
-		root_mountflags |= MS_RDONLY;
-		goto retry;
-	}
-	if (retval) {
-	        /*
-		 * Allow the user to distinguish between failed open
-		 * and bad superblock on root device.
-		 */
-Eio:
-		printk ("VFS: Cannot open root device \"%s\" or %s\n",
-			root_device_name, kdevname (ROOT_DEV));
-		printk ("Please append a correct \"root=\" boot option\n");
-		panic("VFS: Unable to mount root fs on %s",
-			kdevname(ROOT_DEV));
-	}
-
-	check_disk_change(ROOT_DEV);
-	sb = get_super(ROOT_DEV);
-	if (sb) {
-		/* FIXME */
-		p = (char *)sb->s_type->name;
-		atomic_inc(&sb->s_active);
-		up_read(&sb->s_umount);
-		down_write(&sb->s_umount);
-		goto mount_it;
-	}
-
-	for (p = fs_names; *p; p += strlen(p)+1) {
-		struct file_system_type * fs_type = get_fs_type(p);
-		if (!fs_type)
-  			continue;
-		atomic_inc(&bdev->bd_count);
-		retval = blkdev_get(bdev, mode, 0, BDEV_FS);
-		if (retval)
-			goto Eio;
-  		sb = read_super(ROOT_DEV, bdev, fs_type,
-				root_mountflags, root_mount_data);
-		put_filesystem(fs_type);
-		if (sb) {
-			blkdev_put(bdev, BDEV_FS);
-			goto mount_it;
-		}
-	}
-	panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
-
-mount_it:
-	/* FIXME */
-	up_write(&sb->s_umount);
-	printk ("VFS: Mounted root (%s filesystem)%s.\n", p,
-		(sb->s_flags & MS_RDONLY) ? " readonly" : "");
-	putname(fs_names);
-	if (path_start >= 0) {
-		name = path + path_start;
-		devfs_unregister (devfs_find_handle(NULL, "root", 0, 0, 0, 0));
-		devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
-				  name + 5, NULL, NULL);
-		memcpy (name, "/dev/", 5);
-	}
-	vfsmnt = alloc_vfsmnt();
-	if (!vfsmnt)
-		panic("VFS: alloc_vfsmnt failed for root fs");
-
-	set_devname(vfsmnt, name);
-	vfsmnt->mnt_sb = sb;
-	vfsmnt->mnt_root = dget(sb->s_root);
-	bdput(bdev); /* sb holds a reference */
-
-
-#ifdef CONFIG_ROOT_NFS
-attach_it:
-#endif
-	root_nd.mnt = root_vfsmnt;
-	root_nd.dentry = root_vfsmnt->mnt_sb->s_root;
-	graft_tree(vfsmnt, &root_nd);
-
-	set_fs_root(current->fs, vfsmnt, vfsmnt->mnt_root);
-	set_fs_pwd(current->fs, vfsmnt, vfsmnt->mnt_root);
-
-	mntput(vfsmnt);
+	return do_kern_mount(type->name, 0, (char *)type->name, NULL);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/balloc.c linux/fs/udf/balloc.c
--- linux.orig/fs/udf/balloc.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/balloc.c	2002-07-20 01:08:31.000000000 +0000
@@ -15,7 +15,7 @@
  *		ftp://prep.ai.mit.edu/pub/gnu/GPL
  *	Each contributing author retains all rights to their own work.
  *
- *  (C) 1999-2000 Ben Fennema
+ *  (C) 1999-2001 Ben Fennema
  *  (C) 1999 Stelias Computing Inc
  *
  * HISTORY
@@ -25,11 +25,9 @@
  */
 
 #include "udfdecl.h"
-#include <linux/fs.h>
+
 #include <linux/locks.h>
 #include <linux/quotaops.h>
-#include <linux/udf_fs.h>
-
 #include <asm/bitops.h>
 
 #include "udf_i.h"
@@ -44,15 +42,15 @@
 #define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
 #define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)
 #define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))
-#define UintBPL Uint(BITS_PER_LONG)
-#define Uint(x) xUint(x)
-#define xUint(x) Uint ## x
+#define uintBPL_t uint(BITS_PER_LONG)
+#define uint(x) xuint(x)
+#define xuint(x) uint ## x ## _t
 
 extern inline int find_next_one_bit (void * addr, int size, int offset)
 {
-	UintBPL * p = ((UintBPL *) addr) + (offset / BITS_PER_LONG);
-	UintBPL result = offset & ~(BITS_PER_LONG-1);
-	UintBPL tmp;
+	uintBPL_t * p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG);
+	uintBPL_t result = offset & ~(BITS_PER_LONG-1);
+	uintBPL_t tmp;
 
 	if (offset >= size)
 		return size;
@@ -147,7 +145,7 @@
 
 static void udf_bitmap_free_blocks(struct super_block * sb,
 	struct inode * inode,
-	struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
+	struct udf_bitmap *bitmap, lb_addr bloc, uint32_t offset, uint32_t count)
 {
 	struct buffer_head * bh = NULL;
 	unsigned long block;
@@ -167,7 +165,7 @@
 		goto error_return;
 	}
 
-	block = bloc.logicalBlockNum + offset + (sizeof(struct SpaceBitmapDesc) << 3);
+	block = bloc.logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3);
 
 do_more:
 	overflow = 0;
@@ -222,8 +220,8 @@
 
 static int udf_bitmap_prealloc_blocks(struct super_block * sb,
 	struct inode * inode,
-	struct udf_bitmap *bitmap, Uint16 partition, Uint32 first_block,
-	Uint32 block_count)
+	struct udf_bitmap *bitmap, uint16_t partition, uint32_t first_block,
+	uint32_t block_count)
 {
 	int alloc_count = 0;
 	int bit, block, block_group, group_start;
@@ -240,10 +238,10 @@
 
 repeat:
 	nr_groups = (UDF_SB_PARTLEN(sb, partition) +
-		(sizeof(struct SpaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
-	block = first_block + (sizeof(struct SpaceBitmapDesc) << 3);
+		(sizeof(struct spaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
+	block = first_block + (sizeof(struct spaceBitmapDesc) << 3);
 	block_group = block >> (sb->s_blocksize_bits + 3);
-	group_start = block_group ? 0 : sizeof(struct SpaceBitmapDesc);
+	group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
 
 	bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
 	if (bitmap_nr < 0)
@@ -286,7 +284,7 @@
 
 static int udf_bitmap_new_block(struct super_block * sb,
 	struct inode * inode,
-	struct udf_bitmap *bitmap, Uint16 partition, Uint32 goal, int *err)
+	struct udf_bitmap *bitmap, uint16_t partition, uint32_t goal, int *err)
 {
 	int newbit, bit=0, block, block_group, group_start;
 	int end_goal, nr_groups, bitmap_nr, i;
@@ -302,9 +300,9 @@
 		goal = 0;
 
 	nr_groups = bitmap->s_nr_groups;
-	block = goal + (sizeof(struct SpaceBitmapDesc) << 3);
+	block = goal + (sizeof(struct spaceBitmapDesc) << 3);
 	block_group = block >> (sb->s_blocksize_bits + 3);
-	group_start = block_group ? 0 : sizeof(struct SpaceBitmapDesc);
+	group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
 
 	bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
 	if (bitmap_nr < 0)
@@ -344,7 +342,7 @@
 		block_group ++;
 		if (block_group >= nr_groups)
 			block_group = 0;
-		group_start = block_group ? 0 : sizeof(struct SpaceBitmapDesc);
+		group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
 
 		bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
 		if (bitmap_nr < 0)
@@ -397,7 +395,7 @@
 	}
 
 	newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
-		(sizeof(struct SpaceBitmapDesc) << 3);
+		(sizeof(struct spaceBitmapDesc) << 3);
 
 	if (!udf_clear_bit(bit, bh->b_data))
 	{
@@ -426,13 +424,13 @@
 
 static void udf_table_free_blocks(struct super_block * sb,
 	struct inode * inode,
-	struct inode * table, lb_addr bloc, Uint32 offset, Uint32 count)
+	struct inode * table, lb_addr bloc, uint32_t offset, uint32_t count)
 {
-	Uint32 start, end;
-	Uint32 nextoffset, oextoffset, elen;
+	uint32_t start, end;
+	uint32_t nextoffset, oextoffset, elen;
 	lb_addr nbloc, obloc, eloc;
 	struct buffer_head *obh, *nbh;
-	Sint8 etype;
+	int8_t etype;
 	int i;
 
 	lock_super(sb);
@@ -459,7 +457,7 @@
 	start = bloc.logicalBlockNum + offset;
 	end = bloc.logicalBlockNum + offset + count - 1;
 
-	oextoffset = nextoffset = sizeof(struct UnallocatedSpaceEntry);
+	oextoffset = nextoffset = sizeof(struct unallocSpaceEntry);
 	elen = 0;
 	obloc = nbloc = UDF_I_LOCATION(table);
 
@@ -538,15 +536,15 @@
 		int adsize;
 		short_ad *sad = NULL;
 		long_ad *lad = NULL;
-		struct AllocExtDesc *aed;
+		struct allocExtDesc *aed;
 
 		eloc.logicalBlockNum = start;
-		elen = (EXTENT_RECORDED_ALLOCATED << 30) |
+		elen = EXT_RECORDED_ALLOCATED |
 			(count << sb->s_blocksize_bits);
 
-		if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
+		if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
 			adsize = sizeof(short_ad);
-		else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
+		else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
 			adsize = sizeof(long_ad);
 		else
 		{
@@ -576,27 +574,27 @@
 				udf_release_data(obh);
 				goto error_return;
 			}
-			aed = (struct AllocExtDesc *)(nbh->b_data);
+			aed = (struct allocExtDesc *)(nbh->b_data);
 			aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
 			if (nextoffset + adsize > sb->s_blocksize)
 			{
 				loffset = nextoffset;
 				aed->lengthAllocDescs = cpu_to_le32(adsize);
 				sptr = (obh)->b_data + nextoffset - adsize;
-				dptr = nbh->b_data + sizeof(struct AllocExtDesc);
+				dptr = nbh->b_data + sizeof(struct allocExtDesc);
 				memcpy(dptr, sptr, adsize);
-				nextoffset = sizeof(struct AllocExtDesc) + adsize;
+				nextoffset = sizeof(struct allocExtDesc) + adsize;
 			}
 			else
 			{
 				loffset = nextoffset + adsize;
 				aed->lengthAllocDescs = cpu_to_le32(0);
 				sptr = (obh)->b_data + nextoffset;
-				nextoffset = sizeof(struct AllocExtDesc);
+				nextoffset = sizeof(struct allocExtDesc);
 	
 				if (memcmp(&UDF_I_LOCATION(table), &obloc, sizeof(lb_addr)))
 				{
-					aed = (struct AllocExtDesc *)(obh)->b_data;
+					aed = (struct allocExtDesc *)(obh)->b_data;
 					aed->lengthAllocDescs =
 						cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
 				}
@@ -606,24 +604,28 @@
 					mark_inode_dirty(table);
 				}
 			}
-			udf_new_tag(nbh->b_data, TID_ALLOC_EXTENT_DESC, 2, 1,
-				nbloc.logicalBlockNum, sizeof(tag));
+			if (UDF_SB_UDFREV(sb) >= 0x0200)
+				udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
+					nbloc.logicalBlockNum, sizeof(tag));
+			else
+				udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
+					nbloc.logicalBlockNum, sizeof(tag));
 			switch (UDF_I_ALLOCTYPE(table))
 			{
-				case ICB_FLAG_AD_SHORT:
+				case ICBTAG_FLAG_AD_SHORT:
 				{
 					sad = (short_ad *)sptr;
 					sad->extLength = cpu_to_le32(
-						EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
+						EXT_NEXT_EXTENT_ALLOCDECS |
 						sb->s_blocksize);
 					sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum);
 					break;
 				}
-				case ICB_FLAG_AD_LONG:
+				case ICBTAG_FLAG_AD_LONG:
 				{
 					lad = (long_ad *)sptr;
 					lad->extLength = cpu_to_le32(
-						EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
+						EXT_NEXT_EXTENT_ALLOCDECS |
 						sb->s_blocksize);
 					lad->extLocation = cpu_to_lelb(nbloc);
 					break;
@@ -644,7 +646,7 @@
 			}
 			else
 			{
-				aed = (struct AllocExtDesc *)nbh->b_data;
+				aed = (struct allocExtDesc *)nbh->b_data;
 				aed->lengthAllocDescs =
 					cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
 				udf_update_tag(nbh->b_data, nextoffset);
@@ -664,28 +666,28 @@
 
 static int udf_table_prealloc_blocks(struct super_block * sb,
 	struct inode * inode,
-	struct inode *table, Uint16 partition, Uint32 first_block,
-	Uint32 block_count)
+	struct inode *table, uint16_t partition, uint32_t first_block,
+	uint32_t block_count)
 {
 	int alloc_count = 0;
-	Uint32 extoffset, elen, adsize;
+	uint32_t extoffset, elen, adsize;
 	lb_addr bloc, eloc;
 	struct buffer_head *bh;
-	Sint8 etype = -1;
+	int8_t etype = -1;
 
 	if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
 		return 0;
 
-	if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
+	if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
-	else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
+	else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
 		adsize = sizeof(long_ad);
 	else
 		return 0;
 
 	lock_super(sb);
 
-	extoffset = sizeof(struct UnallocatedSpaceEntry);
+	extoffset = sizeof(struct unallocSpaceEntry);
 	bloc = UDF_I_LOCATION(table);
 
 	bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0));
@@ -734,20 +736,20 @@
 
 static int udf_table_new_block(struct super_block * sb,
 	struct inode * inode,
-	struct inode *table, Uint16 partition, Uint32 goal, int *err)
+	struct inode *table, uint16_t partition, uint32_t goal, int *err)
 {
-	Uint32 spread = 0xFFFFFFFF, nspread;
-	Uint32 newblock = 0, adsize;
-	Uint32 extoffset, goal_extoffset, elen, goal_elen = 0;
+	uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
+	uint32_t newblock = 0, adsize;
+	uint32_t extoffset, goal_extoffset, elen, goal_elen = 0;
 	lb_addr bloc, goal_bloc, eloc, goal_eloc;
 	struct buffer_head *bh, *goal_bh;
-	Sint8 etype;
+	int8_t etype;
 
 	*err = -ENOSPC;
 
-	if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
+	if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
-	else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
+	else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
 		adsize = sizeof(long_ad);
 	else
 		return newblock;
@@ -757,12 +759,13 @@
 	if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
 		goal = 0;
 
-	/* We search for the closest matching block to goal. If we find a exact hit,	   we stop. Otherwise we keep going till we run out of extents.
+	/* We search for the closest matching block to goal. If we find a exact hit,
+	   we stop. Otherwise we keep going till we run out of extents.
 	   We store the buffer_head, bloc, and extoffset of the current closest
 	   match and use that when we are done.
 	*/
 
-	extoffset = sizeof(struct UnallocatedSpaceEntry);
+	extoffset = sizeof(struct unallocSpaceEntry);
 	bloc = UDF_I_LOCATION(table);
 
 	goal_bh = bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0));
@@ -845,9 +848,9 @@
 
 inline void udf_free_blocks(struct super_block * sb,
 	struct inode * inode,
-	lb_addr bloc, Uint32 offset, Uint32 count)
+	lb_addr bloc, uint32_t offset, uint32_t count)
 {
-	Uint16 partition = bloc.partitionReferenceNum;
+	uint16_t partition = bloc.partitionReferenceNum;
 
 	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
@@ -879,7 +882,7 @@
 
 inline int udf_prealloc_blocks(struct super_block * sb,
 	struct inode * inode,
-	Uint16 partition, Uint32 first_block, Uint32 block_count)
+	uint16_t partition, uint32_t first_block, uint32_t block_count)
 {
 	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
@@ -911,7 +914,7 @@
 
 inline int udf_new_block(struct super_block * sb,
 	struct inode * inode,
-	Uint16 partition, Uint32 goal, int *err)
+	uint16_t partition, uint32_t goal, int *err)
 {
 	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/crc.c linux/fs/udf/crc.c
--- linux.orig/fs/udf/crc.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/fs/udf/crc.c	2002-07-20 01:08:30.000000000 +0000
@@ -28,7 +28,7 @@
 
 #include "udfdecl.h"
 
-static Uint16 crc_table[256] = {
+static uint16_t crc_table[256] = {
 	0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50a5U, 0x60c6U, 0x70e7U,
 	0x8108U, 0x9129U, 0xa14aU, 0xb16bU, 0xc18cU, 0xd1adU, 0xe1ceU, 0xf1efU,
 	0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52b5U, 0x4294U, 0x72f7U, 0x62d6U,
@@ -84,8 +84,8 @@
  *	July 21, 1997 - Andrew E. Mileski
  *	Adapted from OSTA-UDF(tm) 1.50 standard.
  */
-extern Uint16
-udf_crc(Uint8 *data, Uint32 size, Uint16 crc)
+extern uint16_t
+udf_crc(uint8_t *data, uint32_t size, uint16_t crc)
 {
 	while (size--)
 		crc = crc_table[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/dir.c linux/fs/udf/dir.c
--- linux.orig/fs/udf/dir.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/dir.c	2002-07-20 01:08:30.000000000 +0000
@@ -15,14 +15,14 @@
  *		ftp://prep.ai.mit.edu/pub/gnu/GPL
  *	Each contributing author retains all rights to their own work.
  *
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *
  * HISTORY
  *
  *  10/05/98 dgb  Split directory operations into it's own file
  *                Implemented directory reads via do_udf_readdir
  *  10/06/98      Made directory operations work!
- *  11/17/98      Rewrote directory to support ICB_FLAG_AD_LONG
+ *  11/17/98      Rewrote directory to support ICBTAG_FLAG_AD_LONG
  *  11/25/98 blf  Rewrote directory handling (readdir+lookup) to support reading
  *                across blocks.
  *  12/12/98      Split out the lookup code to namei.c. bulk of directory
@@ -31,16 +31,13 @@
 
 #include "udfdecl.h"
 
-#if defined(__linux__) && defined(__KERNEL__)
-#include <linux/version.h>
-#include "udf_i.h"
-#include "udf_sb.h"
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/udf_fs.h>
-#endif
+
+#include "udf_i.h"
+#include "udf_sb.h"
 
 /* Prototypes for file operations */
 static int udf_readdir(struct file *, void *, filldir_t);
@@ -102,19 +99,19 @@
 do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *dirent)
 {
 	struct udf_fileident_bh fibh;
-	struct FileIdentDesc *fi=NULL;
-	struct FileIdentDesc cfi;
+	struct fileIdentDesc *fi=NULL;
+	struct fileIdentDesc cfi;
 	int block, iblock;
 	loff_t nf_pos = filp->f_pos - 1;
 	int flen;
 	char fname[255];
 	char *nameptr;
-	Uint16 liu;
-	Uint8 lfi;
+	uint16_t liu;
+	uint8_t lfi;
 	loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
 	struct buffer_head * bh = NULL, * tmp, * bha[16];
 	lb_addr bloc, eloc;
-	Uint32 extoffset, elen, offset;
+	uint32_t extoffset, elen, offset;
 	int i, num;
 	unsigned int dt_type;
 
@@ -126,15 +123,15 @@
 
 	fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
 	if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
-		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
+		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
 	{
 		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
-			if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
+			if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
 				extoffset -= sizeof(short_ad);
-			else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
+			else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
 				extoffset -= sizeof(long_ad);
 		}
 		else
@@ -198,7 +195,7 @@
 		{
 			int poffset;	/* Unpaded ending offset */
 
-			poffset = fibh.soffset + sizeof(struct FileIdentDesc) + liu + lfi;
+			poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi;
 
 			if (poffset >= lfi)
 				nameptr = (char *)(fibh.ebh->b_data + poffset - lfi);
@@ -210,19 +207,19 @@
 			}
 		}
 
-		if ( (cfi.fileCharacteristics & FILE_DELETED) != 0 )
+		if ( (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 )
 		{
 			if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) )
 				continue;
 		}
 		
-		if ( (cfi.fileCharacteristics & FILE_HIDDEN) != 0 )
+		if ( (cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0 )
 		{
 			if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
 				continue;
 		}
 
-		if ( cfi.fileCharacteristics & FILE_PARENT )
+		if ( cfi.fileCharacteristics & FID_FILE_CHAR_PARENT )
 		{
 			iblock = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(filp->f_dentry->d_parent->d_inode), 0);
 			flen = 2;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/directory.c linux/fs/udf/directory.c
--- linux.orig/fs/udf/directory.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/directory.c	2002-07-20 01:08:38.000000000 +0000
@@ -18,33 +18,20 @@
 
 #include "udfdecl.h"
 
-#if defined(__linux__) && defined(__KERNEL__)
-
 #include <linux/fs.h>
 #include <linux/string.h>
-#include <linux/udf_fs.h>
-
-#else
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#endif
-
-#ifdef __KERNEL__
 
-Uint8 * udf_filead_read(struct inode *dir, Uint8 *tmpad, Uint8 ad_size,
+uint8_t * udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size,
 	lb_addr fe_loc, int *pos, int *offset, struct buffer_head **bh, int *error)
 {
 	int loffset = *offset;
 	int block;
-	Uint8 *ad;
+	uint8_t *ad;
 	int remainder;
 
 	*error = 0;
 
-	ad = (Uint8 *)(*bh)->b_data + *offset;
+	ad = (uint8_t *)(*bh)->b_data + *offset;
 	*offset += ad_size;
 
 	if (!ad)
@@ -68,7 +55,7 @@
 		ad = tmpad;
 
 		remainder = dir->i_sb->s_blocksize - loffset;
-		memcpy((Uint8 *)ad, (*bh)->b_data + loffset, remainder);
+		memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder);
 
 		udf_release_data(*bh);
 		block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
@@ -77,21 +64,21 @@
 		if (!((*bh) = udf_tread(dir->i_sb, block)))
 			return NULL;
 
-		memcpy((Uint8 *)ad + remainder, (*bh)->b_data, ad_size - remainder);
+		memcpy((uint8_t *)ad + remainder, (*bh)->b_data, ad_size - remainder);
 		*offset = ad_size - remainder;
 	}
 	return ad;
 }
 
-struct FileIdentDesc *
+struct fileIdentDesc *
 udf_fileident_read(struct inode *dir, loff_t *nf_pos,
 	struct udf_fileident_bh *fibh,
-	struct FileIdentDesc *cfi,
-	lb_addr *bloc, Uint32 *extoffset, 
-	lb_addr *eloc, Uint32 *elen,
-	Uint32 *offset, struct buffer_head **bh)
+	struct fileIdentDesc *cfi,
+	lb_addr *bloc, uint32_t *extoffset, 
+	lb_addr *eloc, uint32_t *elen,
+	uint32_t *offset, struct buffer_head **bh)
 {
-	struct FileIdentDesc *fi;
+	struct fileIdentDesc *fi;
 	int i, num, block;
 	struct buffer_head * tmp, * bha[16];
 
@@ -102,7 +89,7 @@
 		int lextoffset = *extoffset;
 
 		if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
-			EXTENT_RECORDED_ALLOCATED)
+			(EXT_RECORDED_ALLOCATED >> 30))
 		{
 			return NULL;
 		}
@@ -159,14 +146,14 @@
 
 	if (fibh->eoffset <= dir->i_sb->s_blocksize)
 	{
-		memcpy((Uint8 *)cfi, (Uint8 *)fi, sizeof(struct FileIdentDesc));
+		memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc));
 	}
 	else if (fibh->eoffset > dir->i_sb->s_blocksize)
 	{
 		int lextoffset = *extoffset;
 
 		if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
-			EXTENT_RECORDED_ALLOCATED)
+			(EXT_RECORDED_ALLOCATED >> 30))
 		{
 			return NULL;
 		}
@@ -186,15 +173,15 @@
 		if (!(fibh->ebh = udf_tread(dir->i_sb, block)))
 			return NULL;
 
-		if (sizeof(struct FileIdentDesc) > - fibh->soffset)
+		if (sizeof(struct fileIdentDesc) > - fibh->soffset)
 		{
 			int fi_len;
 
-			memcpy((Uint8 *)cfi, (Uint8 *)fi, - fibh->soffset);
-			memcpy((Uint8 *)cfi - fibh->soffset, fibh->ebh->b_data,
-				sizeof(struct FileIdentDesc) + fibh->soffset);
+			memcpy((uint8_t *)cfi, (uint8_t *)fi, - fibh->soffset);
+			memcpy((uint8_t *)cfi - fibh->soffset, fibh->ebh->b_data,
+				sizeof(struct fileIdentDesc) + fibh->soffset);
 
-			fi_len = (sizeof(struct FileIdentDesc) + cfi->lengthFileIdent +
+			fi_len = (sizeof(struct fileIdentDesc) + cfi->lengthFileIdent +
 				le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
 
 			*nf_pos += ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2);
@@ -202,25 +189,22 @@
 		}
 		else
 		{
-			memcpy((Uint8 *)cfi, (Uint8 *)fi, sizeof(struct FileIdentDesc));
+			memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc));
 		}
 	}
 	return fi;
 }
-#endif
 
-struct FileIdentDesc * 
+struct fileIdentDesc * 
 udf_get_fileident(void * buffer, int bufsize, int * offset)
 {
-	struct FileIdentDesc *fi;
+	struct fileIdentDesc *fi;
 	int lengthThisIdent;
-	Uint8 * ptr;
+	uint8_t * ptr;
 	int padlen;
 
 	if ( (!buffer) || (!offset) ) {
-#ifdef __KERNEL__
 		udf_debug("invalidparms\n, buffer=%p, offset=%p\n", buffer, offset);
-#endif
 		return NULL;
 	}
 
@@ -229,23 +213,21 @@
 	if ( (*offset > 0) && (*offset < bufsize) ) {
 		ptr += *offset;
 	}
-	fi=(struct FileIdentDesc *)ptr;
-	if (le16_to_cpu(fi->descTag.tagIdent) != TID_FILE_IDENT_DESC)
+	fi=(struct fileIdentDesc *)ptr;
+	if (le16_to_cpu(fi->descTag.tagIdent) != TAG_IDENT_FID)
 	{
-#ifdef __KERNEL__
-		udf_debug("0x%x != TID_FILE_IDENT_DESC\n",
+		udf_debug("0x%x != TAG_IDENT_FID\n",
 			le16_to_cpu(fi->descTag.tagIdent));
 		udf_debug("offset: %u sizeof: %lu bufsize: %u\n",
-			*offset, (unsigned long)sizeof(struct FileIdentDesc), bufsize);
-#endif
+			*offset, (unsigned long)sizeof(struct fileIdentDesc), bufsize);
 		return NULL;
 	}
-	if ( (*offset + sizeof(struct FileIdentDesc)) > bufsize )
+	if ( (*offset + sizeof(struct fileIdentDesc)) > bufsize )
 	{
-		lengthThisIdent = sizeof(struct FileIdentDesc);
+		lengthThisIdent = sizeof(struct fileIdentDesc);
 	}
 	else
-		lengthThisIdent = sizeof(struct FileIdentDesc) +
+		lengthThisIdent = sizeof(struct fileIdentDesc) +
 			fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse);
 
 	/* we need to figure padding, too! */
@@ -261,29 +243,25 @@
 udf_get_fileextent(void * buffer, int bufsize, int * offset)
 {
 	extent_ad * ext;
-	struct FileEntry *fe;
-	Uint8 * ptr;
+	struct fileEntry *fe;
+	uint8_t * ptr;
 
 	if ( (!buffer) || (!offset) )
 	{
-#ifdef __KERNEL__
 		printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n");
-#endif
 		return NULL;
 	}
 
-	fe = (struct FileEntry *)buffer;
+	fe = (struct fileEntry *)buffer;
 
-	if ( le16_to_cpu(fe->descTag.tagIdent) != TID_FILE_ENTRY )
+	if ( le16_to_cpu(fe->descTag.tagIdent) != TAG_IDENT_FE )
 	{
-#ifdef __KERNEL__
-		udf_debug("0x%x != TID_FILE_ENTRY\n",
+		udf_debug("0x%x != TAG_IDENT_FE\n",
 			le16_to_cpu(fe->descTag.tagIdent));
-#endif
 		return NULL;
 	}
 
-	ptr=(Uint8 *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr);
+	ptr=(uint8_t *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr);
 
 	if ( (*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)) )
 	{
@@ -300,17 +278,15 @@
 udf_get_fileshortad(void * buffer, int maxoffset, int *offset, int inc)
 {
 	short_ad * sa;
-	Uint8 * ptr;
+	uint8_t * ptr;
 
 	if ( (!buffer) || (!offset) )
 	{
-#ifdef __KERNEL__
 		printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
-#endif
 		return NULL;
 	}
 
-	ptr = (Uint8 *)buffer;
+	ptr = (uint8_t *)buffer;
 
 	if ( (*offset > 0) && (*offset < maxoffset) )
 		ptr += *offset;
@@ -328,17 +304,15 @@
 udf_get_filelongad(void * buffer, int maxoffset, int * offset, int inc)
 {
 	long_ad * la;
-	Uint8 * ptr;
+	uint8_t * ptr;
 
 	if ( (!buffer) || !(offset) ) 
 	{
-#ifdef __KERNEL__
 		printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
-#endif
 		return NULL;
 	}
 
-	ptr = (Uint8 *)buffer;
+	ptr = (uint8_t *)buffer;
 
 	if ( (*offset > 0) && (*offset < maxoffset) )
 		ptr += *offset;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/ecma_167.h linux/fs/udf/ecma_167.h
--- linux.orig/fs/udf/ecma_167.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/fs/udf/ecma_167.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,822 @@
+/*
+ * ecma_167.h
+ *
+ * This file is based on ECMA-167 3rd edition (June 1997)
+ * http://www.ecma.ch
+ *
+ * Copyright (c) 2001-2002  Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+
+#ifndef _ECMA_167_H
+#define _ECMA_167_H 1
+
+/* Character set specification (ECMA 167r3 1/7.2.1) */
+typedef struct
+{
+	uint8_t		charSetType;
+	uint8_t		charSetInfo[63];
+} __attribute__ ((packed)) charspec;
+
+/* Character Set Type (ECMA 167r3 1/7.2.1.1) */
+#define CHARSPEC_TYPE_CS0		0x00	/* (1/7.2.2) */
+#define CHARSPEC_TYPE_CS1		0x01	/* (1/7.2.3) */
+#define CHARSPEC_TYPE_CS2		0x02	/* (1/7.2.4) */
+#define CHARSPEC_TYPE_CS3		0x03	/* (1/7.2.5) */
+#define CHARSPEC_TYPE_CS4		0x04	/* (1/7.2.6) */
+#define CHARSPEC_TYPE_CS5		0x05	/* (1/7.2.7) */
+#define CHARSPEC_TYPE_CS6		0x06	/* (1/7.2.8) */
+#define CHARSPEC_TYPE_CS7		0x07	/* (1/7.2.9) */
+#define CHARSPEC_TYPE_CS8		0x08	/* (1/7.2.10) */
+
+typedef uint8_t		dstring;
+
+/* Timestamp (ECMA 167r3 1/7.3) */
+typedef struct
+{
+	uint16_t	typeAndTimezone;
+	int16_t		year;
+	uint8_t		month;
+	uint8_t		day;
+	uint8_t		hour;
+	uint8_t		minute;
+	uint8_t		second;
+	uint8_t		centiseconds;
+	uint8_t		hundredsOfMicroseconds;
+	uint8_t		microseconds;
+} __attribute__ ((packed)) timestamp;
+
+/* Type and Time Zone (ECMA 167r3 1/7.3.1) */
+#define TIMESTAMP_TYPE_MASK		0xF000
+#define TIMESTAMP_TYPE_CUT		0x0000
+#define TIMESTAMP_TYPE_LOCAL		0x1000
+#define TIMESTAMP_TYPE_AGREEMENT	0x2000
+#define TIMESTAMP_TIMEZONE_MASK		0x0FFF
+
+/* Entity identifier (ECMA 167r3 1/7.4) */
+typedef struct
+{
+	uint8_t		flags;
+	uint8_t		ident[23];
+	uint8_t		identSuffix[8];
+} __attribute__ ((packed)) regid;
+
+/* Flags (ECMA 167r3 1/7.4.1) */
+#define ENTITYID_FLAGS_DIRTY		0x00
+#define ENTITYID_FLAGS_PROTECTED	0x01
+
+/* Volume Structure Descriptor (ECMA 167r3 2/9.1) */
+#define VSD_STD_ID_LEN			5
+struct volStructDesc
+{
+	uint8_t		structType;
+	uint8_t		stdIdent[VSD_STD_ID_LEN];
+	uint8_t		structVersion;
+	uint8_t		structData[2041];
+} __attribute__ ((packed));
+
+/* Standard Identifier (EMCA 167r2 2/9.1.2) */
+#define VSD_STD_ID_NSR02		"NSR02"	/* (3/9.1) */
+
+/* Standard Identifier (ECMA 167r3 2/9.1.2) */
+#define VSD_STD_ID_BEA01		"BEA01"	/* (2/9.2) */
+#define VSD_STD_ID_BOOT2		"BOOT2"	/* (2/9.4) */
+#define VSD_STD_ID_CD001		"CD001"	/* (ECMA-119) */
+#define VSD_STD_ID_CDW02		"CDW02"	/* (ECMA-168) */
+#define VSD_STD_ID_NSR03		"NSR03"	/* (3/9.1) */
+#define VSD_STD_ID_TEA01		"TEA01"	/* (2/9.3) */
+
+/* Beginning Extended Area Descriptor (ECMA 167r3 2/9.2) */
+struct beginningExtendedAreaDesc
+{
+	uint8_t		structType;
+	uint8_t		stdIdent[VSD_STD_ID_LEN];
+	uint8_t		structVersion;
+	uint8_t		structData[2041];
+} __attribute__ ((packed));
+
+/* Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */
+struct terminatingExtendedAreaDesc
+{
+	uint8_t		structType;
+	uint8_t		stdIdent[VSD_STD_ID_LEN];
+	uint8_t		structVersion;
+	uint8_t		structData[2041];
+} __attribute__ ((packed));
+
+/* Boot Descriptor (ECMA 167r3 2/9.4) */
+struct bootDesc
+{
+	uint8_t		structType;
+	uint8_t		stdIdent[VSD_STD_ID_LEN];
+	uint8_t		structVersion;
+	uint8_t		reserved1;
+	regid		archType;
+	regid		bootIdent;
+	uint32_t	bootExtLocation;
+	uint32_t	bootExtLength;
+	uint64_t	loadAddress;
+	uint64_t	startAddress;
+	timestamp	descCreationDateAndTime;
+	uint16_t	flags;
+	uint8_t		reserved2[32];
+	uint8_t		bootUse[1906];
+} __attribute__ ((packed));
+
+/* Flags (ECMA 167r3 2/9.4.12) */
+#define BOOT_FLAGS_ERASE		0x01
+
+/* Extent Descriptor (ECMA 167r3 3/7.1) */
+typedef struct
+{
+	uint32_t	extLength;
+	uint32_t	extLocation;
+} __attribute__ ((packed)) extent_ad;
+
+/* Descriptor Tag (ECMA 167r3 3/7.2) */
+typedef struct
+{
+	uint16_t	tagIdent;
+	uint16_t	descVersion;
+	uint8_t		tagChecksum;
+	uint8_t		reserved;
+	uint16_t	tagSerialNum;
+	uint16_t	descCRC;
+	uint16_t	descCRCLength;
+	uint32_t	tagLocation;
+} __attribute__ ((packed)) tag;
+
+/* Tag Identifier (ECMA 167r3 3/7.2.1) */
+#define TAG_IDENT_PVD			0x0001
+#define TAG_IDENT_AVDP			0x0002
+#define TAG_IDENT_VDP			0x0003
+#define TAG_IDENT_IUVD			0x0004
+#define TAG_IDENT_PD			0x0005
+#define TAG_IDENT_LVD			0x0006
+#define TAG_IDENT_USD			0x0007
+#define TAG_IDENT_TD			0x0008
+#define TAG_IDENT_LVID			0x0009
+
+/* NSR Descriptor (ECMA 167r3 3/9.1) */
+struct NSRDesc
+{
+	uint8_t		structType;
+	uint8_t		stdIdent[VSD_STD_ID_LEN];
+	uint8_t		structVersion;
+	uint8_t		reserved;
+	uint8_t		structData[2040];
+} __attribute__ ((packed));
+	
+/* Primary Volume Descriptor (ECMA 167r3 3/10.1) */
+struct primaryVolDesc
+{
+	tag		descTag;
+	uint32_t	volDescSeqNum;
+	uint32_t	primaryVolDescNum;
+	dstring		volIdent[32];
+	uint16_t	volSeqNum;
+	uint16_t	maxVolSeqNum;
+	uint16_t	interchangeLvl;
+	uint16_t	maxInterchangeLvl;
+	uint32_t	charSetList;
+	uint32_t	maxCharSetList;
+	dstring		volSetIdent[128];
+	charspec	descCharSet;
+	charspec	explanatoryCharSet;
+	extent_ad	volAbstract;
+	extent_ad	volCopyright;
+	regid		appIdent;
+	timestamp	recordingDateAndTime;
+	regid		impIdent;
+	uint8_t		impUse[64];
+	uint32_t	predecessorVolDescSeqLocation;
+	uint16_t	flags;
+	uint8_t		reserved[22];
+} __attribute__ ((packed));
+
+/* Flags (ECMA 167r3 3/10.1.21) */
+#define PVD_FLAGS_VSID_COMMON		0x0001
+
+/* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */
+struct anchorVolDescPtr
+{
+	tag		descTag;
+	extent_ad	mainVolDescSeqExt;
+	extent_ad	reserveVolDescSeqExt;
+	uint8_t	 	reserved[480];
+} __attribute__ ((packed));
+
+/* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
+struct volDescPtr
+{
+	tag		descTag;
+	uint32_t	volDescSeqNum;
+	extent_ad	nextVolDescSeqExt;
+	uint8_t		reserved[484];
+} __attribute__ ((packed));
+
+/* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
+struct impUseVolDesc
+{
+	tag		descTag;
+	uint32_t	volDescSeqNum;
+	regid		impIdent;
+	uint8_t		impUse[460];
+} __attribute__ ((packed));
+
+/* Partition Descriptor (ECMA 167r3 3/10.5) */
+struct partitionDesc
+{
+	tag		descTag;
+	uint32_t	volDescSeqNum;
+	uint16_t	partitionFlags;
+	uint16_t	partitionNumber;
+	regid		partitionContents;
+	uint8_t		partitionContentsUse[128];
+	uint32_t	accessType;
+	uint32_t	partitionStartingLocation;
+	uint32_t	partitionLength;
+	regid		impIdent;
+	uint8_t		impUse[128];
+	uint8_t		reserved[156];
+} __attribute__ ((packed));
+
+/* Partition Flags (ECMA 167r3 3/10.5.3) */
+#define PD_PARTITION_FLAGS_ALLOC	0x0001
+
+/* Partition Contents (ECMA 167r2 3/10.5.3) */
+#define PD_PARTITION_CONTENTS_NSR02	"+NSR02"
+
+/* Partition Contents (ECMA 167r3 3/10.5.5) */
+#define PD_PARTITION_CONTENTS_FDC01	"+FDC01"
+#define PD_PARTITION_CONTENTS_CD001	"+CD001"
+#define PD_PARTITION_CONTENTS_CDW02	"+CDW02"
+#define PD_PARTITION_CONTENTS_NSR03	"+NSR03"
+
+/* Access Type (ECMA 167r3 3/10.5.7) */
+#define PD_ACCESS_TYPE_NONE		0x00000000
+#define PD_ACCESS_TYPE_READ_ONLY	0x00000001
+#define PD_ACCESS_TYPE_WRITE_ONCE	0x00000002
+#define PD_ACCESS_TYPE_REWRITABLE	0x00000003
+#define PD_ACCESS_TYPE_OVERWRITABLE	0x00000004
+
+/* Logical Volume Descriptor (ECMA 167r3 3/10.6) */
+struct logicalVolDesc
+{
+	tag		descTag;
+	uint32_t	volDescSeqNum;
+	charspec	descCharSet;
+	dstring		logicalVolIdent[128];
+	uint32_t	logicalBlockSize;
+	regid		domainIdent;
+	uint8_t		logicalVolContentsUse[16];
+	uint32_t	mapTableLength;
+	uint32_t	numPartitionMaps;
+	regid		impIdent;
+	uint8_t		impUse[128];
+	extent_ad	integritySeqExt;
+	uint8_t		partitionMaps[0];
+} __attribute__ ((packed));
+
+/* Generic Partition Map (ECMA 167r3 3/10.7.1) */
+struct genericPartitionMap
+{
+	uint8_t		partitionMapType;
+	uint8_t		partitionMapLength;
+	uint8_t		partitionMapping[0];
+} __attribute__ ((packed));
+
+/* Partition Map Type (ECMA 167r3 3/10.7.1.1) */
+#define GP_PARTITION_MAP_TYPE_UNDEF	0x00
+#define GP_PARTIITON_MAP_TYPE_1		0x01
+#define GP_PARTITION_MAP_TYPE_2		0x02
+
+/* Type 1 Partition Map (ECMA 167r3 3/10.7.2) */
+struct genericPartitionMap1
+{
+	uint8_t		partitionMapType;
+	uint8_t		partitionMapLength;
+	uint16_t	volSeqNum;
+	uint16_t	partitionNum;
+} __attribute__ ((packed));
+
+/* Type 2 Partition Map (ECMA 167r3 3/10.7.3) */
+struct genericPartitionMap2
+{
+	uint8_t		partitionMapType;
+	uint8_t		partitionMapLength; 
+	uint8_t		partitionIdent[62];
+} __attribute__ ((packed));
+
+/* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
+struct unallocSpaceDesc
+{
+	tag		descTag;
+	uint32_t	volDescSeqNum;
+	uint32_t	numAllocDescs;
+	extent_ad	allocDescs[0];
+} __attribute__ ((packed));
+
+/* Terminating Descriptor (ECMA 167r3 3/10.9) */
+struct terminatingDesc
+{
+	tag		descTag;
+	uint8_t		reserved[496];
+} __attribute__ ((packed));
+
+/* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
+struct logicalVolIntegrityDesc
+{
+	tag		descTag;
+	timestamp	recordingDateAndTime;
+	uint32_t	integrityType;
+	extent_ad	nextIntegrityExt;
+	uint8_t		logicalVolContentsUse[32];
+	uint32_t	numOfPartitions;
+	uint32_t	lengthOfImpUse;
+	uint32_t	freeSpaceTable[0];
+	uint32_t	sizeTable[0];
+	uint8_t		impUse[0];
+} __attribute__ ((packed));
+
+/* Integrity Type (ECMA 167r3 3/10.10.3) */
+#define LVID_INTEGRITY_TYPE_OPEN	0x00000000
+#define LVID_INTEGRITY_TYPE_CLOSE	0x00000001
+
+/* Recorded Address (ECMA 167r3 4/7.1) */
+typedef struct 
+{
+	uint32_t	logicalBlockNum;
+	uint16_t	partitionReferenceNum;
+} __attribute__ ((packed)) lb_addr;
+
+/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
+typedef struct
+{
+        uint32_t	extLength;
+        uint32_t	extPosition;
+} __attribute__ ((packed)) short_ad;
+
+/* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
+typedef struct
+{
+	uint32_t	extLength;
+	lb_addr		extLocation;
+	uint8_t		impUse[6];
+} __attribute__ ((packed)) long_ad;
+
+/* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
+typedef struct
+{
+	uint32_t	extLength;
+	uint32_t	recordedLength;
+	uint32_t	informationLength;
+	lb_addr		extLocation;
+} __attribute__ ((packed)) ext_ad;
+
+/* Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */
+
+/* Tag Identifier (ECMA 167r3 4/7.2.1) */
+#define TAG_IDENT_FSD			0x0100
+#define TAG_IDENT_FID			0x0101
+#define TAG_IDENT_AED			0x0102
+#define TAG_IDENT_IE			0x0103
+#define TAG_IDENT_TE			0x0104
+#define TAG_IDENT_FE			0x0105
+#define TAG_IDENT_EAHD			0x0106
+#define TAG_IDENT_USE			0x0107
+#define TAG_IDENT_SBD			0x0108
+#define TAG_IDENT_PIE			0x0109
+#define TAG_IDENT_EFE			0x010A
+
+/* File Set Descriptor (ECMA 167r3 4/14.1) */
+struct fileSetDesc
+{
+	tag		descTag;
+	timestamp	recordingDateAndTime;
+	uint16_t	interchangeLvl;
+	uint16_t	maxInterchangeLvl;
+	uint32_t	charSetList;
+	uint32_t	maxCharSetList;
+	uint32_t	fileSetNum;
+	uint32_t	fileSetDescNum;
+	charspec	logicalVolIdentCharSet;
+	dstring		logicalVolIdent[128];
+	charspec	fileSetCharSet;
+	dstring		fileSetIdent[32];
+	dstring		copyrightFileIdent[32];
+	dstring		abstractFileIdent[32];
+	long_ad		rootDirectoryICB;
+	regid		domainIdent;
+	long_ad		nextExt;
+	long_ad		streamDirectoryICB;
+	uint8_t		reserved[32];
+} __attribute__ ((packed));
+
+/* Partition Header Descriptor (ECMA 167r3 4/14.3) */
+struct partitionHeaderDesc
+{
+	short_ad	unallocSpaceTable;
+	short_ad	unallocSpaceBitmap;
+	short_ad	partitionIntegrityTable;
+	short_ad	freedSpaceTable;
+	short_ad	freedSpaceBitmap;
+	uint8_t		reserved[88];
+} __attribute__ ((packed));
+
+/* File Identifier Descriptor (ECMA 167r3 4/14.4) */
+struct fileIdentDesc
+{
+	tag		descTag;
+	uint16_t	fileVersionNum;
+	uint8_t		fileCharacteristics;
+	uint8_t		lengthFileIdent;
+	long_ad		icb;
+	uint16_t	lengthOfImpUse;
+	uint8_t		impUse[0];
+	uint8_t		fileIdent[0];
+	uint8_t		padding[0];
+} __attribute__ ((packed));
+
+/* File Characteristics (ECMA 167r3 4/14.4.3) */
+#define FID_FILE_CHAR_HIDDEN		0x01
+#define FID_FILE_CHAR_DIRECTORY		0x02
+#define FID_FILE_CHAR_DELETED		0x04
+#define FID_FILE_CHAR_PARENT		0x08
+#define FID_FILE_CHAR_METADATA		0x10
+
+/* Allocation Ext Descriptor (ECMA 167r3 4/14.5) */
+struct allocExtDesc
+{
+	tag		descTag;
+	uint32_t	previousAllocExtLocation;
+	uint32_t	lengthAllocDescs;
+} __attribute__ ((packed));
+
+/* ICB Tag (ECMA 167r3 4/14.6) */
+typedef struct
+{
+	uint32_t	priorRecordedNumDirectEntries;
+	uint16_t	strategyType;
+	uint16_t	strategyParameter;
+	uint16_t	numEntries;
+	uint8_t		reserved;
+	uint8_t		fileType;
+	lb_addr		parentICBLocation;
+	uint16_t	flags;
+} __attribute__ ((packed)) icbtag;
+
+/* Strategy Type (ECMA 167r3 4/14.6.2) */
+#define ICBTAG_STRATEGY_TYPE_UNDEF	0x0000
+#define ICBTAG_STRATEGY_TYPE_1		0x0001
+#define ICBTAG_STRATEGY_TYPE_2		0x0002
+#define ICBTAG_STRATEGY_TYPE_3		0x0003
+#define ICBTAG_STRATEGY_TYPE_4		0x0004
+
+/* File Type (ECMA 167r3 4/14.6.6) */
+#define ICBTAG_FILE_TYPE_UNDEF		0x00
+#define ICBTAG_FILE_TYPE_USE		0x01
+#define ICBTAG_FILE_TYPE_PIE		0x02
+#define ICBTAG_FILE_TYPE_IE		0x03
+#define ICBTAG_FILE_TYPE_DIRECTORY	0x04
+#define ICBTAG_FILE_TYPE_REGULAR	0x05
+#define ICBTAG_FILE_TYPE_BLOCK		0x06
+#define ICBTAG_FILE_TYPE_CHAR		0x07
+#define ICBTAG_FILE_TYPE_EA		0x08
+#define ICBTAG_FILE_TYPE_FIFO		0x09
+#define ICBTAG_FILE_TYPE_SOCKET		0x0A
+#define ICBTAG_FILE_TYPE_TE		0x0B
+#define ICBTAG_FILE_TYPE_SYMLINK	0x0C
+#define ICBTAG_FILE_TYPE_STREAMDIR	0x0D
+
+/* Flags (ECMA 167r3 4/14.6.8) */
+#define ICBTAG_FLAG_AD_MASK		0x0007
+#define ICBTAG_FLAG_AD_SHORT		0x0000
+#define ICBTAG_FLAG_AD_LONG		0x0001
+#define ICBTAG_FLAG_AD_EXTENDED		0x0002
+#define ICBTAG_FLAG_AD_IN_ICB		0x0003
+#define ICBTAG_FLAG_SORTED		0x0008
+#define ICBTAG_FLAG_NONRELOCATABLE	0x0010
+#define ICBTAG_FLAG_ARCHIVE		0x0020
+#define ICBTAG_FLAG_SETUID		0x0040
+#define ICBTAG_FLAG_SETGID		0x0080
+#define ICBTAG_FLAG_STICKY		0x0100
+#define ICBTAG_FLAG_CONTIGUOUS		0x0200
+#define ICBTAG_FLAG_SYSTEM		0x0400
+#define ICBTAG_FLAG_TRANSFORMED		0x0800
+#define ICBTAG_FLAG_MULTIVERSIONS	0x1000
+#define ICBTAG_FLAG_STREAM		0x2000
+
+/* Indirect Entry (ECMA 167r3 4/14.7) */
+struct indirectEntry
+{
+	tag		descTag;
+	icbtag		icbTag;
+	long_ad		indirectICB;
+} __attribute__ ((packed));
+
+/* Terminal Entry (ECMA 167r3 4/14.8) */
+struct terminalEntry
+{
+	tag		descTag;
+	icbtag		icbTag;
+} __attribute__ ((packed));
+
+/* File Entry (ECMA 167r3 4/14.9) */
+struct fileEntry
+{
+	tag		descTag;
+	icbtag		icbTag;
+	uint32_t	uid;
+	uint32_t	gid;
+	uint32_t	permissions;
+	uint16_t	fileLinkCount;
+	uint8_t		recordFormat;
+	uint8_t		recordDisplayAttr;
+	uint32_t	recordLength;
+	uint64_t	informationLength;
+	uint64_t	logicalBlocksRecorded;
+	timestamp	accessTime;
+	timestamp	modificationTime;
+	timestamp	attrTime;
+	uint32_t	checkpoint;
+	long_ad		extendedAttrICB;
+	regid		impIdent;
+	uint64_t	uniqueID;
+	uint32_t	lengthExtendedAttr;
+	uint32_t	lengthAllocDescs;
+	uint8_t		extendedAttr[0];
+	uint8_t		allocDescs[0];
+} __attribute__ ((packed));
+
+/* Permissions (ECMA 167r3 4/14.9.5) */
+#define FE_PERM_O_EXEC			0x00000001U
+#define FE_PERM_O_WRITE			0x00000002U
+#define FE_PERM_O_READ			0x00000004U
+#define FE_PERM_O_CHATTR		0x00000008U
+#define FE_PERM_O_DELETE		0x00000010U
+#define FE_PERM_G_EXEC			0x00000020U
+#define FE_PERM_G_WRITE			0x00000040U
+#define FE_PERM_G_READ			0x00000080U
+#define FE_PERM_G_CHATTR		0x00000100U
+#define FE_PERM_G_DELETE		0x00000200U
+#define FE_PERM_U_EXEC			0x00000400U
+#define FE_PERM_U_WRITE			0x00000800U
+#define FE_PERM_U_READ			0x00001000U
+#define FE_PERM_U_CHATTR		0x00002000U
+#define FE_PERM_U_DELETE		0x00004000U
+
+/* Record Format (ECMA 167r3 4/14.9.7) */
+#define FE_RECORD_FMT_UNDEF		0x00
+#define FE_RECORD_FMT_FIXED_PAD		0x01
+#define FE_RECORD_FMT_FIXED		0x02
+#define FE_RECORD_FMT_VARIABLE8		0x03
+#define FE_RECORD_FMT_VARIABLE16	0x04
+#define FE_RECORD_FMT_VARIABLE16_MSB	0x05
+#define FE_RECORD_FMT_VARIABLE32	0x06
+#define FE_RECORD_FMT_PRINT		0x07
+#define FE_RECORD_FMT_LF		0x08
+#define FE_RECORD_FMT_CR		0x09
+#define FE_RECORD_FMT_CRLF		0x0A
+#define FE_RECORD_FMT_LFCR		0x0B
+
+#define Record Display Attributes (ECMA 167r3 4/14.9.8) */
+#define FE_RECORD_DISPLAY_ATTR_UNDEF	0x00
+#define FE_RECORD_DISPLAY_ATTR_1	0x01
+#define FE_RECORD_DISPLAY_ATTR_2	0x02
+#define FE_RECORD_DISPLAY_ATTR_3	0x03
+
+/* Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */
+struct extendedAttrHeaderDesc
+{
+	tag		descTag;
+	uint32_t	impAttrLocation;
+	uint32_t	appAttrLocation;
+} __attribute__ ((packed));
+
+/* Generic Format (ECMA 167r3 4/14.10.2) */
+struct genericFormat
+{
+	uint32_t	attrType;
+	uint8_t		attrSubtype;
+	uint8_t		reserved[3];
+	uint32_t	attrLength;
+	uint8_t		attrData[0];
+} __attribute__ ((packed));
+
+/* Character Set Information (ECMA 167r3 4/14.10.3) */
+struct charSetInfo
+{
+	uint32_t	attrType;
+	uint8_t		attrSubtype;
+	uint8_t		reserved[3];
+	uint32_t	attrLength;
+	uint32_t	escapeSeqLength;
+	uint8_t		charSetType;
+	uint8_t		escapeSeq[0];
+} __attribute__ ((packed));
+
+/* Alternate Permissions (ECMA 167r3 4/14.10.4) */
+struct altPerms
+{
+	uint32_t	attrType;
+	uint8_t		attrSubtype;
+	uint8_t		reserved[3];
+	uint32_t	attrLength;
+	uint16_t	ownerIdent;
+	uint16_t	groupIdent;
+	uint16_t	permission;
+} __attribute__ ((packed));
+
+/* File Times Extended Attribute (ECMA 167r3 4/14.10.5) */
+struct fileTimesExtAttr
+{
+	uint32_t	attrType;
+	uint8_t		attrSubtype;
+	uint8_t		reserved[3];
+	uint32_t	attrLength;
+	uint32_t	dataLength;
+	uint32_t	fileTimeExistence;
+	uint8_t		fileTimes;
+} __attribute__ ((packed));
+
+/* FileTimeExistence (ECMA 167r3 4/14.10.5.6) */
+#define FTE_CREATION			0x00000001
+#define FTE_DELETION			0x00000004
+#define FTE_EFFECTIVE			0x00000008
+#define FTE_BACKUP			0x00000002
+
+/* Information Times Extended Attribute (ECMA 167r3 4/14.10.6) */
+struct infoTimesExtAttr
+{
+	uint32_t	attrType;
+	uint8_t		attrSubtype;
+	uint8_t		reserved[3];
+	uint32_t	attrLength;
+	uint32_t	dataLength;
+	uint32_t	infoTimeExistence;
+	uint8_t		infoTimes[0];
+} __attribute__ ((packed));
+
+/* Device Specification (ECMA 167r3 4/14.10.7) */
+struct deviceSpec
+{
+	uint32_t	attrType;
+	uint8_t		attrSubtype;
+	uint8_t		reserved[3];
+	uint32_t	attrLength;
+	uint32_t	impUseLength;
+	uint32_t	majorDeviceIdent;
+	uint32_t	minorDeviceIdent;
+	uint8_t		impUse[0];
+} __attribute__ ((packed));
+
+/* Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */
+struct impUseExtAttr
+{
+	uint32_t	attrType;
+	uint8_t		attrSubtype;
+	uint8_t		reserved[3];
+	uint32_t	attrLength;
+	uint32_t	impUseLength;
+	regid		impIdent;
+	uint8_t		impUse[0];
+} __attribute__ ((packed));
+
+/* Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */
+struct appUseExtAttr
+{
+	uint32_t	attrType;
+	uint8_t		attrSubtype;
+	uint8_t		reserved[3];
+	uint32_t	attrLength;
+	uint32_t	appUseLength;
+	regid		appIdent;
+	uint8_t		appUse[0];
+} __attribute__ ((packed));
+
+#define EXTATTR_CHAR_SET		1
+#define EXTATTR_ALT_PERMS		3
+#define EXTATTR_FILE_TIMES		5
+#define EXTATTR_INFO_TIMES		6
+#define EXTATTR_DEV_SPEC		12
+#define EXTATTR_IMP_USE			2048
+#define EXTATTR_APP_USE			65536
+
+
+/* Unallocated Space Entry (ECMA 167r3 4/14.11) */
+struct unallocSpaceEntry
+{
+	tag		descTag;
+	icbtag		icbTag;
+	uint32_t	lengthAllocDescs;
+	uint8_t		allocDescs[0];
+} __attribute__ ((packed));
+
+/* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
+struct spaceBitmapDesc
+{
+	tag		descTag;
+	uint32_t	numOfBits;
+	uint32_t	numOfBytes;
+	uint8_t		bitmap[0];
+} __attribute__ ((packed));
+
+/* Partition Integrity Entry (ECMA 167r3 4/14.13) */
+struct partitionIntegrityEntry
+{
+	tag		descTag;
+	icbtag		icbTag;
+	timestamp	recordingDateAndTime;
+	uint8_t		integrityType;
+	uint8_t		reserved[175];
+	regid		impIdent;
+	uint8_t		impUse[256];
+} __attribute__ ((packed));
+
+/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
+
+/* Extent Length (ECMA 167r3 4/14.14.1.1) */
+#define EXT_RECORDED_ALLOCATED		0x00000000
+#define EXT_NOT_RECORDED_ALLOCATED	0x40000000
+#define EXT_NOT_RECORDED_NOT_ALLOCATED	0x80000000
+#define EXT_NEXT_EXTENT_ALLOCDECS	0xC0000000
+
+/* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
+
+/* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
+
+/* Logical Volume Header Descriptor (ECMA 167r3 4/14.15) */
+struct logicalVolHeaderDesc
+{
+	uint64_t	uniqueID;
+	uint8_t		reserved[24];
+} __attribute__ ((packed));
+
+/* Path Component (ECMA 167r3 4/14.16.1) */
+struct pathComponent
+{
+	uint8_t		componentType;
+	uint8_t		lengthComponentIdent;
+	uint16_t	componentFileVersionNum;
+	dstring		componentIdent[0];
+} __attribute__ ((packed));
+
+/* File Entry (ECMA 167r3 4/14.17) */
+struct extendedFileEntry
+{
+	tag		descTag;
+	icbtag		icbTag;
+	uint32_t	uid;
+	uint32_t	gid;
+	uint32_t	permissions;
+	uint16_t	fileLinkCount;
+	uint8_t		recordFormat;
+	uint8_t		recordDisplayAttr;
+	uint32_t	recordLength;
+	uint64_t	informationLength;
+	uint64_t	objectSize;
+	uint64_t	logicalBlocksRecorded;
+	timestamp	accessTime;
+	timestamp	modificationTime;
+	timestamp	createTime;
+	timestamp	attrTime;
+	uint32_t	checkpoint;
+	uint32_t	reserved;
+	long_ad		extendedAttrICB;
+	long_ad		streamDirectoryICB;
+	regid		impIdent;
+	uint64_t	uniqueID;
+	uint32_t	lengthExtendedAttr;
+	uint32_t	lengthAllocDescs;
+	uint8_t		extendedAttr[0];
+	uint8_t		allocDescs[0];
+} __attribute__ ((packed));
+
+#endif /* _ECMA_167_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/file.c linux/fs/udf/file.c
--- linux.orig/fs/udf/file.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/file.c	2002-07-20 01:08:23.000000000 +0000
@@ -16,7 +16,7 @@
  *  Each contributing author retains all rights to their own work.
  *
  *  (C) 1998-1999 Dave Boynton
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *  (C) 1999-2000 Stelias Computing Inc
  *
  * HISTORY
@@ -25,7 +25,7 @@
  *  10/07/98      Switched to using generic_readpage, etc., like isofs
  *                And it works!
  *  12/06/98 blf  Added udf_file_read. uses generic_file_read for all cases but
- *                ICB_FLAG_AD_IN_ICB.
+ *                ICBTAG_FLAG_AD_IN_ICB.
  *  04/06/99      64 bit file handling on 32 bit systems taken from ext2 file.c
  *  05/12/99      Preliminary file write support
  */
@@ -50,6 +50,7 @@
 	struct buffer_head *bh;
 	int block;
 	char *kaddr;
+	int err = 0;
 
 	if (!PageLocked(page))
 		PAGE_BUG(page);
@@ -58,13 +59,20 @@
 	memset(kaddr, 0, PAGE_CACHE_SIZE);
 	block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
 	bh = sb_bread(inode->i_sb, block);
+	if (!bh)
+	{
+		SetPageError(page);
+		err = -EIO;
+		goto out;
+	}
 	memcpy(kaddr, bh->b_data + udf_ext0_offset(inode), inode->i_size);
 	brelse(bh);
 	flush_dcache_page(page);
 	SetPageUptodate(page);
+out:
 	kunmap(page);
 	UnlockPage(page);
-	return 0;
+	return err;
 }
 
 static int udf_adinicb_writepage(struct page *page)
@@ -74,6 +82,7 @@
 	struct buffer_head *bh;
 	int block;
 	char *kaddr;
+	int err = 0;
 
 	if (!PageLocked(page))
 		PAGE_BUG(page);
@@ -81,13 +90,20 @@
 	kaddr = kmap(page);
 	block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
 	bh = sb_bread(inode->i_sb, block);
+	if (!bh)
+	{
+		SetPageError(page);
+		err = -EIO;
+		goto out;
+	}
 	memcpy(bh->b_data + udf_ext0_offset(inode), kaddr, inode->i_size);
 	mark_buffer_dirty(bh);
 	brelse(bh);
 	SetPageUptodate(page);
+out:
 	kunmap(page);
 	UnlockPage(page);
-	return 0;
+	return err;
 }
 
 static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
@@ -103,19 +119,27 @@
 	struct buffer_head *bh;
 	int block;
 	char *kaddr = page_address(page);
+	int err = 0;
 
 	block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
 	bh = sb_bread(inode->i_sb, block);
+	if (!bh)
+	{
+		SetPageError(page);
+		err = -EIO;
+		goto out;
+	}
 	memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset,
-		kaddr + offset, to-offset);
+		kaddr + offset, to - offset);
 	mark_buffer_dirty(bh);
 	brelse(bh);
 	SetPageUptodate(page);
+out:
 	kunmap(page);
 	/* only one page here */
 	if (to > inode->i_size)
 		inode->i_size = to;
-	return 0;
+	return err;
 }
 
 struct address_space_operations udf_adinicb_aops = {
@@ -133,7 +157,7 @@
 	struct inode *inode = file->f_dentry->d_inode;
 	int err, pos;
 
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 	{
 		if (file->f_flags & O_APPEND)
 			pos = inode->i_size;
@@ -144,7 +168,7 @@
 			pos + count))
 		{
 			udf_expand_file_adinicb(inode, pos + count, &err);
-			if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 			{
 				udf_debug("udf_expand_adinicb: err=%d\n", err);
 				return err;
@@ -209,7 +233,7 @@
 	int result = -EINVAL;
 	struct buffer_head *bh = NULL;
 	long_ad eaicb;
-	Uint8 *ea = NULL;
+	uint8_t *ea = NULL;
 
 	if ( permission(inode, MAY_READ) != 0 )
 	{
@@ -256,18 +280,18 @@
 
 	if (UDF_I_EXTENDED_FE(inode) == 0)
 	{
-		struct FileEntry *fe;
+		struct fileEntry *fe;
 
-		fe = (struct FileEntry *)bh->b_data;
+		fe = (struct fileEntry *)bh->b_data;
 		eaicb = lela_to_cpu(fe->extendedAttrICB);
 		if (UDF_I_LENEATTR(inode))
 			ea = fe->extendedAttr;
 	}
 	else
 	{
-		struct ExtendedFileEntry *efe;
+		struct extendedFileEntry *efe;
 
-		efe = (struct ExtendedFileEntry *)bh->b_data;
+		efe = (struct extendedFileEntry *)bh->b_data;
 		eaicb = lela_to_cpu(efe->extendedAttrICB);
 		if (UDF_I_LENEATTR(inode))
 			ea = efe->extendedAttr;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/fsync.c linux/fs/udf/fsync.c
--- linux.orig/fs/udf/fsync.c	2001-11-21 05:34:13.000000000 +0000
+++ linux/fs/udf/fsync.c	2002-07-20 01:08:27.000000000 +0000
@@ -15,7 +15,7 @@
  *      ftp://prep.ai.mit.edu/pub/gnu/GPL
  *  Each contributing author retains all rights to their own work.
  *
- *  (C) 1999-2000 Ben Fennema
+ *  (C) 1999-2001 Ben Fennema
  *  (C) 1999-2000 Stelias Computing Inc
  *
  * HISTORY
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/ialloc.c linux/fs/udf/ialloc.c
--- linux.orig/fs/udf/ialloc.c	2001-10-11 15:59:24.000000000 +0000
+++ linux/fs/udf/ialloc.c	2002-07-20 01:08:35.000000000 +0000
@@ -15,7 +15,7 @@
  *		ftp://prep.ai.mit.edu/pub/gnu/GPL
  *	Each contributing author retains all rights to their own work.
  *
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *
  * HISTORY
  *
@@ -74,7 +74,7 @@
 	struct super_block *sb;
 	struct inode * inode;
 	int block;
-	Uint32 start = UDF_I_LOCATION(dir).logicalBlockNum;
+	uint32_t start = UDF_I_LOCATION(dir).logicalBlockNum;
 
 	sb = dir->i_sb;
 	inode = new_inode(sb);
@@ -97,9 +97,9 @@
 
 	if (UDF_SB_LVIDBH(sb))
 	{
-		struct LogicalVolHeaderDesc *lvhd;
-		Uint64 uniqueID;
-		lvhd = (struct LogicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse);
+		struct logicalVolHeaderDesc *lvhd;
+		uint64_t uniqueID;
+		lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse);
 		if (S_ISDIR(mode))
 			UDF_SB_LVIDIU(sb)->numDirs =
 				cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1);
@@ -138,11 +138,11 @@
 	else
 		UDF_I_EXTENDED_FE(inode) = 0;
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
-		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_IN_ICB;
+		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
 	else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
-		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
+		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
 	else
-		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
+		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 	inode->i_mtime = inode->i_atime = inode->i_ctime =
 		UDF_I_CRTIME(inode) = CURRENT_TIME;
 	UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) =
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/inode.c linux/fs/udf/inode.c
--- linux.orig/fs/udf/inode.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/inode.c	2002-07-20 01:08:37.000000000 +0000
@@ -16,7 +16,7 @@
  *  Each contributing author retains all rights to their own work.
  *
  *  (C) 1998 Dave Boynton
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *  (C) 1999-2000 Stelias Computing Inc
  *
  * HISTORY
@@ -48,7 +48,7 @@
 
 #define EXTENT_MERGE_SIZE 5
 
-static mode_t udf_convert_permissions(struct FileEntry *);
+static mode_t udf_convert_permissions(struct fileEntry *);
 static int udf_update_inode(struct inode *, int);
 static void udf_fill_inode(struct inode *, struct buffer_head *);
 static struct buffer_head *inode_getblk(struct inode *, long, int *, long *, int *);
@@ -60,7 +60,7 @@
 	 long_ad [EXTENT_MERGE_SIZE], int *);
 static void udf_update_extents(struct inode *,
 	long_ad [EXTENT_MERGE_SIZE], int, int,
-	lb_addr, Uint32, struct buffer_head **);
+	lb_addr, uint32_t, struct buffer_head **);
 static int udf_get_block(struct inode *, long, struct buffer_head *, int);
 
 /*
@@ -83,9 +83,6 @@
 	{
 		lock_kernel();
 		udf_discard_prealloc(inode);
-		/* write the root inode on put, if dirty */
-		if (!inode->i_sb->s_root && inode->i_state & I_DIRTY)
-			udf_update_inode(inode, IS_SYNC(inode));
 		unlock_kernel();
 	}
 }
@@ -128,7 +125,7 @@
 void udf_discard_prealloc(struct inode * inode)
 {
 	if (inode->i_size && inode->i_size != UDF_I_LENEXTENTS(inode) &&
-		UDF_I_ALLOCTYPE(inode) != ICB_FLAG_AD_IN_ICB)
+		UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB)
 	{
 		udf_truncate_extents(inode);
 	}
@@ -176,9 +173,9 @@
 	if (!UDF_I_LENALLOC(inode))
 	{
 		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
-			UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
+			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
 		else
-			UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
+			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 		mark_inode_dirty(inode);
 		return;
 	}
@@ -205,9 +202,9 @@
 		0, UDF_I_LENALLOC(inode));
 	UDF_I_LENALLOC(inode) = 0;
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
-		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
+		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
 	else
-		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
+		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 	mark_buffer_dirty_inode(bh, inode);
 	udf_release_data(bh);
 
@@ -223,19 +220,19 @@
 	int newblock;
 	struct buffer_head *sbh = NULL, *dbh = NULL;
 	lb_addr bloc, eloc;
-	Uint32 elen, extoffset;
+	uint32_t elen, extoffset;
 
 	struct udf_fileident_bh sfibh, dfibh;
 	loff_t f_pos = udf_ext0_offset(inode) >> 2;
 	int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
-	struct FileIdentDesc cfi, *sfi, *dfi;
+	struct fileIdentDesc cfi, *sfi, *dfi;
 
 	if (!inode->i_size)
 	{
 		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
-			UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
+			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
 		else
-			UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
+			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 		mark_inode_dirty(inode);
 		return NULL;
 	}
@@ -279,7 +276,7 @@
 		sfi->descTag.tagLocation = *block;
 		dfibh.soffset = dfibh.eoffset;
 		dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
-		dfi = (struct FileIdentDesc *)(dbh->b_data + dfibh.soffset);
+		dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
 		if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
 			sfi->fileIdent + sfi->lengthOfImpUse))
 		{
@@ -295,9 +292,9 @@
 
 	UDF_I_LENALLOC(inode) = 0;
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
-		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
+		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
 	else
-		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
+		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 	bloc = UDF_I_LOCATION(inode);
 	eloc.logicalBlockNum = *block;
 	eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
@@ -401,19 +398,19 @@
 {
 	struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL;
 	long_ad laarr[EXTENT_MERGE_SIZE];
-	Uint32 pextoffset = 0, cextoffset = 0, nextoffset = 0;
+	uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0;
 	int count = 0, startnum = 0, endnum = 0;
-	Uint32 elen = 0;
+	uint32_t elen = 0;
 	lb_addr eloc, pbloc, cbloc, nbloc;
 	int c = 1;
-	Uint64 lbcount = 0, b_off = 0;
-	Uint32 newblocknum, newblock, offset = 0;
-	Sint8 etype;
+	uint64_t lbcount = 0, b_off = 0;
+	uint32_t newblocknum, newblock, offset = 0;
+	int8_t etype;
 	int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
 	char lastblock = 0;
 
 	pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
-	b_off = (Uint64)block << inode->i_sb->s_blocksize_bits;
+	b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits;
 	pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
 
 	/* find the extent which contains the block we are looking for.
@@ -450,7 +447,7 @@
 		laarr[c].extLength = (etype << 30) | elen;
 		laarr[c].extLocation = eloc;
 
-		if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
+		if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
 			pgoal = eloc.logicalBlockNum +
 				((elen + inode->i_sb->s_blocksize - 1) >>
 				inode->i_sb->s_blocksize_bits);
@@ -464,11 +461,11 @@
 	/* if the extent is allocated and recorded, return the block
        if the extent is not a multiple of the blocksize, round up */
 
-	if (etype == EXTENT_RECORDED_ALLOCATED)
+	if (etype == (EXT_RECORDED_ALLOCATED >> 30))
 	{
 		if (elen & (inode->i_sb->s_blocksize - 1))
 		{
-			elen = (EXTENT_RECORDED_ALLOCATED << 30) |
+			elen = EXT_RECORDED_ALLOCATED |
 				((elen + inode->i_sb->s_blocksize - 1) &
 				~(inode->i_sb->s_blocksize - 1));
 			etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1);
@@ -496,7 +493,7 @@
 					~(inode->i_sb->s_blocksize - 1);
 		}
 		c = !c;
-		laarr[c].extLength = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
+		laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
 			((offset + 1) << inode->i_sb->s_blocksize_bits);
 		memset(&laarr[c].extLocation, 0x00, sizeof(lb_addr));
 		count ++;
@@ -537,7 +534,7 @@
 
 	/* if the current extent is not recorded but allocated, get the
 		block in the extent corresponding to the requested block */
-	if ((laarr[c].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
+	if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
 		newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
 	else /* otherwise, allocate a new block */
 	{
@@ -603,8 +600,8 @@
 static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum,
 	long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
 {
-	if ((laarr[*c].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED ||
-		(laarr[*c].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)
+	if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
+		(laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
 	{
 		int curr = *c;
 		int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
@@ -626,10 +623,10 @@
 
 		if (offset)
 		{
-			if ((type >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
+			if ((type >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
 			{
 				udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset);
-				laarr[curr].extLength = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
+				laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
 					(offset << inode->i_sb->s_blocksize_bits);
 				laarr[curr].extLocation.logicalBlockNum = 0;
 				laarr[curr].extLocation.partitionReferenceNum = 0;
@@ -643,16 +640,16 @@
 		}
 		
 		laarr[curr].extLocation.logicalBlockNum = newblocknum;
-		if ((type >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)
+		if ((type >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
 			laarr[curr].extLocation.partitionReferenceNum =
 				UDF_I_LOCATION(inode).partitionReferenceNum;
-		laarr[curr].extLength = (EXTENT_RECORDED_ALLOCATED << 30) |
+		laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
 			inode->i_sb->s_blocksize;
 		curr ++;
 
 		if (blen != offset + 1)
 		{
-			if ((type >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
+			if ((type >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
 				laarr[curr].extLocation.logicalBlockNum += (offset + 1);
 			laarr[curr].extLength = type |
 				((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits);
@@ -676,7 +673,7 @@
 	}
 	else
 	{
-		if ((laarr[c+1].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
+		if ((laarr[c+1].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
 		{
 			start = c+1;
 			length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +
@@ -693,7 +690,7 @@
 			if (lastblock)
 				length += UDF_DEFAULT_PREALLOC_BLOCKS;
 		}
-		else if ((laarr[i].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)
+		else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
 			length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
 				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
 		else
@@ -712,7 +709,6 @@
 
 		if (numalloc)
 		{
-			UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
 			if (start == (c+1))
 				laarr[start].extLength +=
 					(numalloc << inode->i_sb->s_blocksize_bits);
@@ -724,7 +720,7 @@
 				laarr[c+1].extLocation.logicalBlockNum = next;
 				laarr[c+1].extLocation.partitionReferenceNum =
 					laarr[c].extLocation.partitionReferenceNum;
-				laarr[c+1].extLength = (EXTENT_NOT_RECORDED_ALLOCATED << 30) |
+				laarr[c+1].extLength = EXT_NOT_RECORDED_ALLOCATED |
 					(numalloc << inode->i_sb->s_blocksize_bits);
 				start = c+1;
 			}
@@ -736,7 +732,7 @@
 
 				if (elen > numalloc)
 				{
-					laarr[c+1].extLength -=
+					laarr[c].extLength -=
 						(numalloc << inode->i_sb->s_blocksize_bits);
 					numalloc = 0;
 				}
@@ -750,6 +746,7 @@
 					(*endnum) --;
 				}
 			}
+			UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
 		}
 	}
 }
@@ -763,7 +760,7 @@
 	{
 		if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30))
 		{
-			if (((laarr[i].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED) ||
+			if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) ||
 				((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) ==
 				(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
 				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits)))
@@ -800,11 +797,11 @@
 
 static void udf_update_extents(struct inode *inode,
 	long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,
-	lb_addr pbloc, Uint32 pextoffset, struct buffer_head **pbh)
+	lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh)
 {
 	int start = 0, i;
 	lb_addr tmploc;
-	Uint32 tmplen;
+	uint32_t tmplen;
 
 	if (startnum > endnum)
 	{
@@ -866,13 +863,13 @@
 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
 		return;
 
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 	{
 		if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
 			inode->i_size))
 		{
 			udf_expand_file_adinicb(inode, inode->i_size, &err);
-			if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 			{
 				inode->i_size = UDF_I_LENALLOC(inode);
 				return;
@@ -937,8 +934,8 @@
 __udf_read_inode(struct inode *inode)
 {
 	struct buffer_head *bh = NULL;
-	struct FileEntry *fe;
-	Uint16 ident;
+	struct fileEntry *fe;
+	uint16_t ident;
 
 	/*
 	 * Set defaults, but the inode is still incomplete!
@@ -966,8 +963,8 @@
 		return;
 	}
 
-	if (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY &&
-		ident != TID_UNALLOCATED_SPACE_ENTRY)
+	if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
+		ident != TAG_IDENT_USE)
 	{
 		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
 			inode->i_ino, ident);
@@ -976,28 +973,28 @@
 		return;
 	}
 
-	fe = (struct FileEntry *)bh->b_data;
+	fe = (struct fileEntry *)bh->b_data;
 
 	if (le16_to_cpu(fe->icbTag.strategyType) == 4096)
 	{
 		struct buffer_head *ibh = NULL, *nbh = NULL;
-		struct IndirectEntry *ie;
+		struct indirectEntry *ie;
 
 		ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident);
-		if (ident == TID_INDIRECT_ENTRY)
+		if (ident == TAG_IDENT_IE)
 		{
 			if (ibh)
 			{
 				lb_addr loc;
-				ie = (struct IndirectEntry *)ibh->b_data;
+				ie = (struct indirectEntry *)ibh->b_data;
 	
 				loc = lelb_to_cpu(ie->indirectICB.extLocation);
 	
 				if (ie->indirectICB.extLength && 
 					(nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident)))
 				{
-					if (ident == TID_FILE_ENTRY ||
-						ident == TID_EXTENDED_FILE_ENTRY)
+					if (ident == TAG_IDENT_FE ||
+						ident == TAG_IDENT_EFE)
 					{
 						memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(lb_addr));
 						udf_release_data(bh);
@@ -1033,8 +1030,8 @@
 
 static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
 {
-	struct FileEntry *fe;
-	struct ExtendedFileEntry *efe;
+	struct fileEntry *fe;
+	struct extendedFileEntry *efe;
 	time_t convtime;
 	long convtime_usec;
 	int offset, alen;
@@ -1042,24 +1039,24 @@
 	inode->i_version = ++event;
 	UDF_I_NEW_INODE(inode) = 0;
 
-	fe = (struct FileEntry *)bh->b_data;
-	efe = (struct ExtendedFileEntry *)bh->b_data;
+	fe = (struct fileEntry *)bh->b_data;
+	efe = (struct extendedFileEntry *)bh->b_data;
 
 	if (le16_to_cpu(fe->icbTag.strategyType) == 4)
 		UDF_I_STRAT4096(inode) = 0;
 	else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
 		UDF_I_STRAT4096(inode) = 1;
 
-	UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICB_FLAG_ALLOC_MASK;
-	if (fe->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY)
+	UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
+	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE)
 		UDF_I_EXTENDED_FE(inode) = 1;
-	else if (fe->descTag.tagIdent == TID_FILE_ENTRY)
+	else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE)
 		UDF_I_EXTENDED_FE(inode) = 0;
-	else if (fe->descTag.tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
+	else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
 	{
 		UDF_I_LENALLOC(inode) =
 			le32_to_cpu(
-				((struct UnallocatedSpaceEntry *)bh->b_data)->lengthAllocDescs);
+				((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs);
 		return;
 	}
 
@@ -1124,7 +1121,7 @@
 		UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
 		UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
 		UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);
-		offset = sizeof(struct FileEntry) + UDF_I_LENEATTR(inode);
+		offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);
 		alen = offset + UDF_I_LENALLOC(inode);
 	}
 	else
@@ -1181,13 +1178,13 @@
 		UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
 		UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
 		UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
-		offset = sizeof(struct ExtendedFileEntry) + UDF_I_LENEATTR(inode);
+		offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
 		alen = offset + UDF_I_LENALLOC(inode);
 	}
 
 	switch (fe->icbTag.fileType)
 	{
-		case FILE_TYPE_DIRECTORY:
+		case ICBTAG_FILE_TYPE_DIRECTORY:
 		{
 			inode->i_op = &udf_dir_inode_operations;
 			inode->i_fop = &udf_dir_operations;
@@ -1195,11 +1192,11 @@
 			inode->i_nlink ++;
 			break;
 		}
-		case FILE_TYPE_REALTIME:
-		case FILE_TYPE_REGULAR:
-		case FILE_TYPE_NONE:
+		case ICBTAG_FILE_TYPE_REALTIME:
+		case ICBTAG_FILE_TYPE_REGULAR:
+		case ICBTAG_FILE_TYPE_UNDEF:
 		{
-			if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 				inode->i_data.a_ops = &udf_adinicb_aops;
 			else
 				inode->i_data.a_ops = &udf_aops;
@@ -1208,22 +1205,22 @@
 			inode->i_mode |= S_IFREG;
 			break;
 		}
-		case FILE_TYPE_BLOCK:
+		case ICBTAG_FILE_TYPE_BLOCK:
 		{
 			inode->i_mode |= S_IFBLK;
 			break;
 		}
-		case FILE_TYPE_CHAR:
+		case ICBTAG_FILE_TYPE_CHAR:
 		{
 			inode->i_mode |= S_IFCHR;
 			break;
 		}
-		case FILE_TYPE_FIFO:
+		case ICBTAG_FILE_TYPE_FIFO:
 		{
 			init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
 			break;
 		}
-		case FILE_TYPE_SYMLINK:
+		case ICBTAG_FILE_TYPE_SYMLINK:
 		{
 			inode->i_data.a_ops = &udf_symlink_aops;
 			inode->i_op = &page_symlink_inode_operations;
@@ -1241,8 +1238,8 @@
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 	{
 		struct buffer_head *tbh = NULL;
-		struct DeviceSpecificationExtendedAttr *dsea =
-			(struct DeviceSpecificationExtendedAttr *)
+		struct deviceSpec *dsea =
+			(struct deviceSpec *)
 				udf_get_extendedattr(inode, 12, 1, &tbh);
 
 		if (dsea)
@@ -1261,11 +1258,11 @@
 }
 
 static mode_t
-udf_convert_permissions(struct FileEntry *fe)
+udf_convert_permissions(struct fileEntry *fe)
 {
 	mode_t mode;
-	Uint32 permissions;
-	Uint32 flags;
+	uint32_t permissions;
+	uint32_t flags;
 
 	permissions = le32_to_cpu(fe->permissions);
 	flags = le16_to_cpu(fe->icbTag.flags);
@@ -1273,9 +1270,9 @@
 	mode =	(( permissions      ) & S_IRWXO) |
 		(( permissions >> 2 ) & S_IRWXG) |
 		(( permissions >> 4 ) & S_IRWXU) |
-		(( flags & ICB_FLAG_SETUID) ? S_ISUID : 0) |
-		(( flags & ICB_FLAG_SETGID) ? S_ISGID : 0) |
-		(( flags & ICB_FLAG_STICKY) ? S_ISVTX : 0);
+		(( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
+		(( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
+		(( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
 
 	return mode;
 }
@@ -1311,11 +1308,11 @@
 udf_update_inode(struct inode *inode, int do_sync)
 {
 	struct buffer_head *bh = NULL;
-	struct FileEntry *fe;
-	struct ExtendedFileEntry *efe;
-	Uint32 udfperms;
-	Uint16 icbflags;
-	Uint16 crclen;
+	struct fileEntry *fe;
+	struct extendedFileEntry *efe;
+	uint32_t udfperms;
+	uint16_t icbflags;
+	uint16_t crclen;
 	int i;
 	timestamp cpu_time;
 	int err = 0;
@@ -1328,35 +1325,36 @@
 		udf_debug("bread failure\n");
 		return -EIO;
 	}
-	fe = (struct FileEntry *)bh->b_data;
-	efe = (struct ExtendedFileEntry *)bh->b_data;
+	fe = (struct fileEntry *)bh->b_data;
+	efe = (struct extendedFileEntry *)bh->b_data;
 	if (UDF_I_NEW_INODE(inode) == 1)
 	{
 		if (UDF_I_EXTENDED_FE(inode) == 0)
-			memset(bh->b_data, 0x00, sizeof(struct FileEntry));
+			memset(bh->b_data, 0x00, sizeof(struct fileEntry));
 		else
-			memset(bh->b_data, 0x00, sizeof(struct ExtendedFileEntry));
+			memset(bh->b_data, 0x00, sizeof(struct extendedFileEntry));
 		memset(bh->b_data + udf_file_entry_alloc_offset(inode) +
 			UDF_I_LENALLOC(inode), 0x0, inode->i_sb->s_blocksize -
 			udf_file_entry_alloc_offset(inode) - UDF_I_LENALLOC(inode));
 		UDF_I_NEW_INODE(inode) = 0;
 	}
 
-	if (fe->descTag.tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
+	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
 	{
-		struct UnallocatedSpaceEntry *use =
-			(struct UnallocatedSpaceEntry *)bh->b_data;
+		struct unallocSpaceEntry *use =
+			(struct unallocSpaceEntry *)bh->b_data;
 
 		use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
-		crclen = sizeof(struct UnallocatedSpaceEntry) + UDF_I_LENALLOC(inode) -
+		crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -
 			sizeof(tag);
+		use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
 		use->descTag.descCRCLength = cpu_to_le16(crclen);
 		use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
 
 		use->descTag.tagChecksum = 0;
 		for (i=0; i<16; i++)
 			if (i != 4)
-				use->descTag.tagChecksum += ((Uint8 *)&(use->descTag))[i];
+				use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];
 
 		mark_buffer_dirty(bh);
 		udf_release_data(bh);
@@ -1374,9 +1372,9 @@
 			((inode->i_mode & S_IRWXU) << 4);
 
 	udfperms |=	(le32_to_cpu(fe->permissions) &
-			(PERM_O_DELETE | PERM_O_CHATTR |
-			 PERM_G_DELETE | PERM_G_CHATTR |
-			 PERM_U_DELETE | PERM_U_CHATTR));
+			(FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
+			 FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
+			 FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
 	fe->permissions = cpu_to_le32(udfperms);
 
 	if (S_ISDIR(inode->i_mode))
@@ -1388,26 +1386,26 @@
 
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 	{
-		EntityID *eid;
+		regid *eid;
 		struct buffer_head *tbh = NULL;
-		struct DeviceSpecificationExtendedAttr *dsea =
-			(struct DeviceSpecificationExtendedAttr *)
+		struct deviceSpec *dsea =
+			(struct deviceSpec *)
 				udf_get_extendedattr(inode, 12, 1, &tbh);	
 
 		if (!dsea)
 		{
-			dsea = (struct DeviceSpecificationExtendedAttr *)
+			dsea = (struct deviceSpec *)
 				udf_add_extendedattr(inode,
-					sizeof(struct DeviceSpecificationExtendedAttr) +
-					sizeof(EntityID), 12, 0x3, &tbh);
+					sizeof(struct deviceSpec) +
+					sizeof(regid), 12, 0x3, &tbh);
 			dsea->attrType = 12;
 			dsea->attrSubtype = 1;
-			dsea->attrLength = sizeof(struct DeviceSpecificationExtendedAttr) +
-				sizeof(EntityID);
-			dsea->impUseLength = sizeof(EntityID);
+			dsea->attrLength = sizeof(struct deviceSpec) +
+				sizeof(regid);
+			dsea->impUseLength = sizeof(regid);
 		}
-		eid = (EntityID *)dsea->impUse;
-		memset(eid, 0, sizeof(EntityID));
+		eid = (regid *)dsea->impUse;
+		memset(eid, 0, sizeof(regid));
 		strcpy(eid->ident, UDF_ID_DEVELOPER);
 		eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
 		eid->identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1429,15 +1427,15 @@
 			fe->modificationTime = cpu_to_lets(cpu_time);
 		if (udf_time_to_stamp(&cpu_time, inode->i_ctime, UDF_I_UCTIME(inode)))
 			fe->attrTime = cpu_to_lets(cpu_time);
-		memset(&(fe->impIdent), 0, sizeof(EntityID));
+		memset(&(fe->impIdent), 0, sizeof(regid));
 		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
 		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
 		fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
 		fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
 		fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
 		fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
-		fe->descTag.tagIdent = le16_to_cpu(TID_FILE_ENTRY);
-		crclen = sizeof(struct FileEntry);
+		fe->descTag.tagIdent = le16_to_cpu(TAG_IDENT_FE);
+		crclen = sizeof(struct fileEntry);
 	}
 	else
 	{
@@ -1475,15 +1473,15 @@
 		if (udf_time_to_stamp(&cpu_time, inode->i_ctime, UDF_I_UCTIME(inode)))
 			efe->attrTime = cpu_to_lets(cpu_time);
 
-		memset(&(efe->impIdent), 0, sizeof(EntityID));
+		memset(&(efe->impIdent), 0, sizeof(regid));
 		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
 		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
 		efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
 		efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
 		efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
 		efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
-		efe->descTag.tagIdent = le16_to_cpu(TID_EXTENDED_FILE_ENTRY);
-		crclen = sizeof(struct ExtendedFileEntry);
+		efe->descTag.tagIdent = le16_to_cpu(TAG_IDENT_EFE);
+		crclen = sizeof(struct extendedFileEntry);
 	}
 	if (UDF_I_STRAT4096(inode))
 	{
@@ -1498,28 +1496,31 @@
 	}
 
 	if (S_ISDIR(inode->i_mode))
-		fe->icbTag.fileType = FILE_TYPE_DIRECTORY;
+		fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;
 	else if (S_ISREG(inode->i_mode))
-		fe->icbTag.fileType = FILE_TYPE_REGULAR;
+		fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR;
 	else if (S_ISLNK(inode->i_mode))
-		fe->icbTag.fileType = FILE_TYPE_SYMLINK;
+		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK;
 	else if (S_ISBLK(inode->i_mode))
-		fe->icbTag.fileType = FILE_TYPE_BLOCK;
+		fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK;
 	else if (S_ISCHR(inode->i_mode))
-		fe->icbTag.fileType = FILE_TYPE_CHAR;
+		fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR;
 	else if (S_ISFIFO(inode->i_mode))
-		fe->icbTag.fileType = FILE_TYPE_FIFO;
+		fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO;
 
 	icbflags =	UDF_I_ALLOCTYPE(inode) |
-			((inode->i_mode & S_ISUID) ? ICB_FLAG_SETUID : 0) |
-			((inode->i_mode & S_ISGID) ? ICB_FLAG_SETGID : 0) |
-			((inode->i_mode & S_ISVTX) ? ICB_FLAG_STICKY : 0) |
+			((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
+			((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
+			((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
 			(le16_to_cpu(fe->icbTag.flags) &
-				~(ICB_FLAG_ALLOC_MASK | ICB_FLAG_SETUID |
-				ICB_FLAG_SETGID | ICB_FLAG_STICKY));
+				~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
+				ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));
 
 	fe->icbTag.flags = cpu_to_le16(icbflags);
-	fe->descTag.descVersion = cpu_to_le16(2);
+	if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
+		fe->descTag.descVersion = cpu_to_le16(3);
+	else
+		fe->descTag.descVersion = cpu_to_le16(2);
 	fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
 	fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
 	crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
@@ -1529,7 +1530,7 @@
 	fe->descTag.tagChecksum = 0;
 	for (i=0; i<16; i++)
 		if (i != 4)
-			fe->descTag.tagChecksum += ((Uint8 *)&(fe->descTag))[i];
+			fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i];
 
 	/* write the data blocks */
 	mark_buffer_dirty(bh);
@@ -1610,14 +1611,14 @@
 	return inode;
 }
 
-Sint8 udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
-	lb_addr eloc, Uint32 elen, struct buffer_head **bh, int inc)
+int8_t udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+	lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc)
 {
 	int adsize;
 	short_ad *sad = NULL;
 	long_ad *lad = NULL;
-	struct AllocExtDesc *aed;
-	int ret;
+	struct allocExtDesc *aed;
+	int8_t etype;
 
 	if (!(*bh))
 	{
@@ -1630,9 +1631,9 @@
 		}
 	}
 
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
-	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
+	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
 		adsize = sizeof(long_ad);
 	else
 		return -1;
@@ -1660,7 +1661,7 @@
 		unlock_buffer(nbh);
 		mark_buffer_dirty_inode(nbh, inode);
 
-		aed = (struct AllocExtDesc *)(nbh->b_data);
+		aed = (struct allocExtDesc *)(nbh->b_data);
 		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
 			aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
 		if (*extoffset + adsize > inode->i_sb->s_blocksize)
@@ -1668,20 +1669,20 @@
 			loffset = *extoffset;
 			aed->lengthAllocDescs = cpu_to_le32(adsize);
 			sptr = (*bh)->b_data + *extoffset - adsize;
-			dptr = nbh->b_data + sizeof(struct AllocExtDesc);
+			dptr = nbh->b_data + sizeof(struct allocExtDesc);
 			memcpy(dptr, sptr, adsize);
-			*extoffset = sizeof(struct AllocExtDesc) + adsize;
+			*extoffset = sizeof(struct allocExtDesc) + adsize;
 		}
 		else
 		{
 			loffset = *extoffset + adsize;
 			aed->lengthAllocDescs = cpu_to_le32(0);
 			sptr = (*bh)->b_data + *extoffset;
-			*extoffset = sizeof(struct AllocExtDesc);
+			*extoffset = sizeof(struct allocExtDesc);
 
 			if (memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
 			{
-				aed = (struct AllocExtDesc *)(*bh)->b_data;
+				aed = (struct allocExtDesc *)(*bh)->b_data;
 				aed->lengthAllocDescs =
 					cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
 			}
@@ -1691,24 +1692,28 @@
 				mark_inode_dirty(inode);
 			}
 		}
-		udf_new_tag(nbh->b_data, TID_ALLOC_EXTENT_DESC, 2, 1,
-			bloc->logicalBlockNum, sizeof(tag));
+		if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
+			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
+				bloc->logicalBlockNum, sizeof(tag));
+		else
+			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
+				bloc->logicalBlockNum, sizeof(tag));
 		switch (UDF_I_ALLOCTYPE(inode))
 		{
-			case ICB_FLAG_AD_SHORT:
+			case ICBTAG_FLAG_AD_SHORT:
 			{
 				sad = (short_ad *)sptr;
 				sad->extLength = cpu_to_le32(
-					EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
+					EXT_NEXT_EXTENT_ALLOCDECS |
 					inode->i_sb->s_blocksize);
 				sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);
 				break;
 			}
-			case ICB_FLAG_AD_LONG:
+			case ICBTAG_FLAG_AD_LONG:
 			{
 				lad = (long_ad *)sptr;
 				lad->extLength = cpu_to_le32(
-					EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
+					EXT_NEXT_EXTENT_ALLOCDECS |
 					inode->i_sb->s_blocksize);
 				lad->extLocation = cpu_to_lelb(*bloc);
 				memset(lad->impUse, 0x00, sizeof(lad->impUse));
@@ -1718,13 +1723,13 @@
 		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
 			udf_update_tag((*bh)->b_data, loffset);
 		else
-			udf_update_tag((*bh)->b_data, sizeof(struct AllocExtDesc));
+			udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
 		mark_buffer_dirty_inode(*bh, inode);
 		udf_release_data(*bh);
 		*bh = nbh;
 	}
 
-	ret = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
+	etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
 
 	if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))
 	{
@@ -1733,21 +1738,21 @@
 	}
 	else
 	{
-		aed = (struct AllocExtDesc *)(*bh)->b_data;
+		aed = (struct allocExtDesc *)(*bh)->b_data;
 		aed->lengthAllocDescs =
 			cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
 		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
 			udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
 		else
-			udf_update_tag((*bh)->b_data, sizeof(struct AllocExtDesc));
+			udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
 		mark_buffer_dirty_inode(*bh, inode);
 	}
 
-	return ret;
+	return etype;
 }
 
-Sint8 udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
-    lb_addr eloc, Uint32 elen, struct buffer_head *bh, int inc)
+int8_t udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
+    lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc)
 {
 	int adsize;
 	short_ad *sad = NULL;
@@ -1766,23 +1771,23 @@
 	else
 		atomic_inc(&bh->b_count);
 
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
-	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
+	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
 		adsize = sizeof(long_ad);
 	else
 		return -1;
 
 	switch (UDF_I_ALLOCTYPE(inode))
 	{
-		case ICB_FLAG_AD_SHORT:
+		case ICBTAG_FLAG_AD_SHORT:
 		{
 			sad = (short_ad *)((bh)->b_data + *extoffset);
 			sad->extLength = cpu_to_le32(elen);
 			sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
 			break;
 		}
-		case ICB_FLAG_AD_LONG:
+		case ICBTAG_FLAG_AD_LONG:
 		{
 			lad = (long_ad *)((bh)->b_data + *extoffset);
 			lad->extLength = cpu_to_le32(elen);
@@ -1796,9 +1801,9 @@
 	{
 		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
 		{
-			struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh)->b_data;
+			struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data;
 			udf_update_tag((bh)->b_data,
-				le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct AllocExtDesc));
+				le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
 		}
 		mark_buffer_dirty_inode(bh, inode);
 	}
@@ -1814,12 +1819,12 @@
 	return (elen >> 30);
 }
 
-Sint8 udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
-	lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
+int8_t udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+	lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
 {
-	Uint16 tagIdent;
+	uint16_t tagIdent;
 	int pos, alen;
-	Sint8 etype;
+	int8_t etype;
 
 	if (!(*bh))
 	{
@@ -1832,29 +1837,29 @@
 		}
 	}
 
-	tagIdent = ((tag *)(*bh)->b_data)->tagIdent;
+	tagIdent = le16_to_cpu(((tag *)(*bh)->b_data)->tagIdent);
 
 	if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))
 	{
-		if (tagIdent == TID_FILE_ENTRY || tagIdent == TID_EXTENDED_FILE_ENTRY ||
+		if (tagIdent == TAG_IDENT_FE || tagIdent == TAG_IDENT_EFE ||
 			UDF_I_NEW_INODE(inode))
 		{
 			pos = udf_file_entry_alloc_offset(inode);
 			alen = UDF_I_LENALLOC(inode) + pos;
 		}
-		else if (tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
+		else if (tagIdent == TAG_IDENT_USE)
 		{
-			pos = sizeof(struct UnallocatedSpaceEntry);
+			pos = sizeof(struct unallocSpaceEntry);
 			alen = UDF_I_LENALLOC(inode) + pos;
 		}
 		else
 			return -1;
 	}
-	else if (tagIdent == TID_ALLOC_EXTENT_DESC)
+	else if (tagIdent == TAG_IDENT_AED)
 	{
-		struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data;
+		struct allocExtDesc *aed = (struct allocExtDesc *)(*bh)->b_data;
 
-		pos = sizeof(struct AllocExtDesc);
+		pos = sizeof(struct allocExtDesc);
 		alen = le32_to_cpu(aed->lengthAllocDescs) + pos;
 	}
 	else
@@ -1865,14 +1870,14 @@
 
 	switch (UDF_I_ALLOCTYPE(inode))
 	{
-		case ICB_FLAG_AD_SHORT:
+		case ICBTAG_FLAG_AD_SHORT:
 		{
 			short_ad *sad;
 
 			if (!(sad = udf_get_fileshortad((*bh)->b_data, alen, extoffset, inc)))
 				return -1;
 
-			if ((etype = le32_to_cpu(sad->extLength) >> 30) == EXTENT_NEXT_EXTENT_ALLOCDECS)
+			if ((etype = le32_to_cpu(sad->extLength) >> 30) == (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
 			{
 				bloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
 				*extoffset = 0;
@@ -1888,14 +1893,14 @@
 			}
 			break;
 		}
-		case ICB_FLAG_AD_LONG:
+		case ICBTAG_FLAG_AD_LONG:
 		{
 			long_ad *lad;
 
 			if (!(lad = udf_get_filelongad((*bh)->b_data, alen, extoffset, inc)))
 				return -1;
 
-			if ((etype = le32_to_cpu(lad->extLength) >> 30) == EXTENT_NEXT_EXTENT_ALLOCDECS)
+			if ((etype = le32_to_cpu(lad->extLength) >> 30) == (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
 			{
 				*bloc = lelb_to_cpu(lad->extLocation);
 				*extoffset = 0;
@@ -1910,11 +1915,11 @@
 			}
 			break;
 		}
-		case ICB_FLAG_AD_IN_ICB:
+		case ICBTAG_FLAG_AD_IN_ICB:
 		{
 			if (UDF_I_LENALLOC(inode) == 0)
 				return -1;
-			etype = EXTENT_RECORDED_ALLOCATED;
+			etype = (EXT_RECORDED_ALLOCATED >> 30);
 			*eloc = UDF_I_LOCATION(inode);
 			*elen = UDF_I_LENALLOC(inode);
 			break;
@@ -1930,18 +1935,18 @@
 
 	udf_debug("Empty Extent, inode=%ld, alloctype=%d, eloc=%d, elen=%d, etype=%d, extoffset=%d\n",
 		inode->i_ino, UDF_I_ALLOCTYPE(inode), eloc->logicalBlockNum, *elen, etype, *extoffset);
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
 		*extoffset -= sizeof(short_ad);
-	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
+	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
 		*extoffset -= sizeof(long_ad);
 	return -1;
 }
 
-Sint8 udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
-	lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
+int8_t udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+	lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
 {
 	int pos, alen;
-	Sint8 etype;
+	int8_t etype;
 
 	if (!(*bh))
 	{
@@ -1957,16 +1962,16 @@
 	if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))
 	{
 		if (!(UDF_I_EXTENDED_FE(inode)))
-			pos = sizeof(struct FileEntry) + UDF_I_LENEATTR(inode);
+			pos = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);
 		else
-			pos = sizeof(struct ExtendedFileEntry) + UDF_I_LENEATTR(inode);
+			pos = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
 		alen = UDF_I_LENALLOC(inode) + pos;
 	}
 	else
 	{
-		struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data;
+		struct allocExtDesc *aed = (struct allocExtDesc *)(*bh)->b_data;
 
-		pos = sizeof(struct AllocExtDesc);
+		pos = sizeof(struct allocExtDesc);
 		alen = le32_to_cpu(aed->lengthAllocDescs) + pos;
 	}
 
@@ -1975,7 +1980,7 @@
 
 	switch (UDF_I_ALLOCTYPE(inode))
 	{
-		case ICB_FLAG_AD_SHORT:
+		case ICBTAG_FLAG_AD_SHORT:
 		{
 			short_ad *sad;
 
@@ -1988,7 +1993,7 @@
 			*elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
 			break;
 		}
-		case ICB_FLAG_AD_LONG:
+		case ICBTAG_FLAG_AD_LONG:
 		{
 			long_ad *lad;
 
@@ -2010,19 +2015,19 @@
 		return etype;
 
 	udf_debug("Empty Extent!\n");
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
 		*extoffset -= sizeof(short_ad);
-	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
+	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
 		*extoffset -= sizeof(long_ad);
 	return -1;
 }
 
-Sint8 udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
-	lb_addr neloc, Uint32 nelen, struct buffer_head *bh)
+int8_t udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
+	lb_addr neloc, uint32_t nelen, struct buffer_head *bh)
 {
 	lb_addr oeloc;
-	Uint32 oelen;
-	Sint8 etype;
+	uint32_t oelen;
+	int8_t etype;
 
 	if (!bh)
 	{
@@ -2049,14 +2054,14 @@
 	return (nelen >> 30);
 }
 
-Sint8 udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
-	lb_addr eloc, Uint32 elen, struct buffer_head *nbh)
+int8_t udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
+	lb_addr eloc, uint32_t elen, struct buffer_head *nbh)
 {
 	struct buffer_head *obh;
 	lb_addr obloc;
 	int oextoffset, adsize;
-	Sint8 etype;
-	struct AllocExtDesc *aed;
+	int8_t etype;
+	struct allocExtDesc *aed;
 
 	if (!(nbh))
 	{
@@ -2072,9 +2077,9 @@
 		atomic_inc(&nbh->b_count);
 	atomic_inc(&nbh->b_count);
 
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
-	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
+	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
 		adsize = sizeof(long_ad);
 	else
 		adsize = 0;
@@ -2113,13 +2118,13 @@
 		}
 		else
 		{
-			aed = (struct AllocExtDesc *)(obh)->b_data;
+			aed = (struct allocExtDesc *)(obh)->b_data;
 			aed->lengthAllocDescs =
 				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
 			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
 				udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
 			else
-				udf_update_tag((obh)->b_data, sizeof(struct AllocExtDesc));
+				udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
 			mark_buffer_dirty_inode(obh, inode);
 		}
 	}
@@ -2133,13 +2138,13 @@
 		}
 		else
 		{
-			aed = (struct AllocExtDesc *)(obh)->b_data;
+			aed = (struct allocExtDesc *)(obh)->b_data;
 			aed->lengthAllocDescs =
 				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
 			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
 				udf_update_tag((obh)->b_data, oextoffset - adsize);
 			else
-				udf_update_tag((obh)->b_data, sizeof(struct AllocExtDesc));
+				udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
 			mark_buffer_dirty_inode(obh, inode);
 		}
 	}
@@ -2149,11 +2154,11 @@
 	return (elen >> 30);
 }
 
-Sint8 inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
-	lb_addr *eloc, Uint32 *elen, Uint32 *offset, struct buffer_head **bh)
+int8_t inode_bmap(struct inode *inode, int block, lb_addr *bloc, uint32_t *extoffset,
+	lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh)
 {
-	Uint64 lbcount = 0, bcount = (Uint64)block << inode->i_sb->s_blocksize_bits;
-	Sint8 etype;
+	uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits;
+	int8_t etype;
 
 	if (block < 0)
 	{
@@ -2189,13 +2194,13 @@
 long udf_block_map(struct inode *inode, long block)
 {
 	lb_addr eloc, bloc;
-	Uint32 offset, extoffset, elen;
+	uint32_t offset, extoffset, elen;
 	struct buffer_head *bh = NULL;
 	int ret;
 
 	lock_kernel();
 
-	if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
+	if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
 		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits);
 	else
 		ret = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/lowlevel.c linux/fs/udf/lowlevel.c
--- linux.orig/fs/udf/lowlevel.c	2001-10-15 20:27:41.000000000 +0000
+++ linux/fs/udf/lowlevel.c	2002-07-20 01:08:23.000000000 +0000
@@ -15,7 +15,7 @@
  *		ftp://prep.ai.mit.edu/pub/gnu/GPL
  *	Each contributing author retains all rights to their own work.
  *
- *  (C) 1999-2000 Ben Fennema
+ *  (C) 1999-2001 Ben Fennema
  *
  * HISTORY
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/misc.c linux/fs/udf/misc.c
--- linux.orig/fs/udf/misc.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/misc.c	2002-07-20 01:08:23.000000000 +0000
@@ -16,7 +16,7 @@
  *	Each contributing author retains all rights to their own work.
  *
  *  (C) 1998 Dave Boynton
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *  (C) 1999-2000 Stelias Computing Inc
  *
  * HISTORY
@@ -26,46 +26,25 @@
 
 #include "udfdecl.h"
 
-#if defined(__linux__) && defined(__KERNEL__)
-
-#include "udf_sb.h"
-#include "udf_i.h"
-
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/udf_fs.h>
 
-#else
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-
-int udf_blocksize=0;
-int udf_errno=0;
-
-void 
-udf_setblocksize(int size)
-{
-	udf_blocksize=size;
-}
-#endif
+#include "udf_i.h"
+#include "udf_sb.h"
 
-Uint32
-udf64_low32(Uint64 indat)
+uint32_t
+udf64_low32(uint64_t indat)
 {
 	return indat & 0x00000000FFFFFFFFULL;
 }
 
-Uint32
-udf64_high32(Uint64 indat)
+uint32_t
+udf64_high32(uint64_t indat)
 {
 	return indat >> 32;
 }
 
-#if defined(__linux__) && defined(__KERNEL__)
-
 extern struct buffer_head *
 udf_tgetblk(struct super_block *sb, int block)
 {
@@ -84,11 +63,11 @@
 		return sb_bread(sb, block);
 }
 
-extern struct GenericAttrFormat *
-udf_add_extendedattr(struct inode * inode, Uint32 size, Uint32 type,
-	Uint8 loc, struct buffer_head **bh)
+extern struct genericFormat *
+udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
+	uint8_t loc, struct buffer_head **bh)
 {
-	Uint8 *ea = NULL, *ad = NULL;
+	uint8_t *ea = NULL, *ad = NULL;
 	long_ad eaicb;
 	int offset;
 
@@ -96,26 +75,26 @@
 
 	if (UDF_I_EXTENDED_FE(inode) == 0)
 	{
-		struct FileEntry *fe;
+		struct fileEntry *fe;
 
-		fe = (struct FileEntry *)(*bh)->b_data;
+		fe = (struct fileEntry *)(*bh)->b_data;
 		eaicb = lela_to_cpu(fe->extendedAttrICB);
-		offset = sizeof(struct FileEntry);
+		offset = sizeof(struct fileEntry);
 	}
 	else
 	{
-		struct ExtendedFileEntry *efe;
+		struct extendedFileEntry *efe;
 
-		efe = (struct ExtendedFileEntry *)(*bh)->b_data;
+		efe = (struct extendedFileEntry *)(*bh)->b_data;
 		eaicb = lela_to_cpu(efe->extendedAttrICB);
-		offset = sizeof(struct ExtendedFileEntry);
+		offset = sizeof(struct extendedFileEntry);
 	}
 
 	ea = &(*bh)->b_data[offset];
 	if (UDF_I_LENEATTR(inode))
 		offset += UDF_I_LENEATTR(inode);
 	else
-		size += sizeof(struct ExtendedAttrHeaderDesc);
+		size += sizeof(struct extendedAttrHeaderDesc);
 
 	ad = &(*bh)->b_data[offset];
 	if (UDF_I_LENALLOC(inode))
@@ -127,8 +106,8 @@
 
 	if (loc & 0x01 && offset >= size)
 	{
-		struct ExtendedAttrHeaderDesc *eahd;
-		eahd = (struct ExtendedAttrHeaderDesc *)ea;
+		struct extendedAttrHeaderDesc *eahd;
+		eahd = (struct extendedAttrHeaderDesc *)ea;
 
 		if (UDF_I_LENALLOC(inode))
 		{
@@ -138,7 +117,7 @@
 		if (UDF_I_LENEATTR(inode))
 		{
 			/* check checksum/crc */
-			if (le16_to_cpu(eahd->descTag.tagIdent) != TID_EXTENDED_ATTRE_HEADER_DESC ||
+			if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD ||
 				le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum)
 			{
 				udf_release_data(*bh);
@@ -147,9 +126,9 @@
 		}
 		else
 		{
-			size -= sizeof(struct ExtendedAttrHeaderDesc);
-			UDF_I_LENEATTR(inode) += sizeof(struct ExtendedAttrHeaderDesc);
-			eahd->descTag.tagIdent = cpu_to_le16(TID_EXTENDED_ATTRE_HEADER_DESC);
+			size -= sizeof(struct extendedAttrHeaderDesc);
+			UDF_I_LENEATTR(inode) += sizeof(struct extendedAttrHeaderDesc);
+			eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD);
 			eahd->descTag.descVersion = cpu_to_le16(2);
 			eahd->descTag.tagSerialNum = cpu_to_le16(1);
 			eahd->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
@@ -162,7 +141,7 @@
 		{
 			if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode))
 			{
-				Uint32 aal = le32_to_cpu(eahd->appAttrLocation);
+				uint32_t aal = le32_to_cpu(eahd->appAttrLocation);
 				memmove(&ea[offset - aal + size],
 					&ea[aal], offset - aal);
 				offset -= aal;
@@ -170,7 +149,7 @@
 			}
 			if (le32_to_cpu(eahd->impAttrLocation) < UDF_I_LENEATTR(inode))
 			{
-				Uint32 ial = le32_to_cpu(eahd->impAttrLocation);
+				uint32_t ial = le32_to_cpu(eahd->impAttrLocation);
 				memmove(&ea[offset - ial + size],
 					&ea[ial], offset - ial);
 				offset -= ial;
@@ -181,7 +160,7 @@
 		{
 			if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode))
 			{
-				Uint32 aal = le32_to_cpu(eahd->appAttrLocation);
+				uint32_t aal = le32_to_cpu(eahd->appAttrLocation);
 				memmove(&ea[offset - aal + size],
 					&ea[aal], offset - aal);
 				offset -= aal;
@@ -190,7 +169,7 @@
 		}
 		/* rewrite CRC + checksum of eahd */
 		UDF_I_LENEATTR(inode) += size;
-		return (struct GenericAttrFormat *)&ea[offset];
+		return (struct genericFormat *)&ea[offset];
 	}
 	if (loc & 0x02)
 	{
@@ -199,31 +178,31 @@
 	return NULL;
 }
 
-extern struct GenericAttrFormat *
-udf_get_extendedattr(struct inode * inode, Uint32 type, Uint8 subtype,
+extern struct genericFormat *
+udf_get_extendedattr(struct inode * inode, uint32_t type, uint8_t subtype,
 	struct buffer_head **bh)
 {
-	struct GenericAttrFormat *gaf;
-	Uint8 *ea = NULL;
+	struct genericFormat *gaf;
+	uint8_t *ea = NULL;
 	long_ad eaicb;
-	Uint32 offset;
+	uint32_t offset;
 
 	*bh = udf_tread(inode->i_sb, inode->i_ino);
 
 	if (UDF_I_EXTENDED_FE(inode) == 0)
 	{
-		struct FileEntry *fe;
+		struct fileEntry *fe;
 
-		fe = (struct FileEntry *)(*bh)->b_data;
+		fe = (struct fileEntry *)(*bh)->b_data;
 		eaicb = lela_to_cpu(fe->extendedAttrICB);
 		if (UDF_I_LENEATTR(inode))
 			ea = fe->extendedAttr;
 	}
 	else
 	{
-		struct ExtendedFileEntry *efe;
+		struct extendedFileEntry *efe;
 
-		efe = (struct ExtendedFileEntry *)(*bh)->b_data;
+		efe = (struct extendedFileEntry *)(*bh)->b_data;
 		eaicb = lela_to_cpu(efe->extendedAttrICB);
 		if (UDF_I_LENEATTR(inode))
 			ea = efe->extendedAttr;
@@ -231,11 +210,11 @@
 
 	if (UDF_I_LENEATTR(inode))
 	{
-		struct ExtendedAttrHeaderDesc *eahd;
-		eahd = (struct ExtendedAttrHeaderDesc *)ea;
+		struct extendedAttrHeaderDesc *eahd;
+		eahd = (struct extendedAttrHeaderDesc *)ea;
 
 		/* check checksum/crc */
-		if (le16_to_cpu(eahd->descTag.tagIdent) != TID_EXTENDED_ATTRE_HEADER_DESC ||
+		if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD ||
 			le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum)
 		{
 			udf_release_data(*bh);
@@ -243,7 +222,7 @@
 		}
 	
 		if (type < 2048)
-			offset = sizeof(struct ExtendedAttrHeaderDesc);
+			offset = sizeof(struct extendedAttrHeaderDesc);
 		else if (type < 65536)
 			offset = le32_to_cpu(eahd->impAttrLocation);
 		else
@@ -251,7 +230,7 @@
 
 		while (offset < UDF_I_LENEATTR(inode))
 		{
-			gaf = (struct GenericAttrFormat *)&ea[offset];
+			gaf = (struct genericFormat *)&ea[offset];
 			if (le32_to_cpu(gaf->attrType) == type && gaf->attrSubtype == subtype)
 				return gaf;
 			else
@@ -267,22 +246,6 @@
 	return NULL;
 }
 
-extern struct buffer_head *
-udf_read_untagged(struct super_block *sb, Uint32 block, Uint32 offset)
-{
-	struct buffer_head *bh = NULL;
-
-	/* Read the block */
-	bh = udf_tread(sb, block+offset);
-	if (!bh)
-	{
-		printk(KERN_ERR "udf: udf_read_untagged(%p,%d,%d) failed\n",
-			sb, block, offset);
-		return NULL;
-	}
-	return bh;
-}
-
 /*
  * udf_read_tagged
  *
@@ -294,11 +257,11 @@
  *	Written, tested, and released.
  */
 extern struct buffer_head *
-udf_read_tagged(struct super_block *sb, Uint32 block, Uint32 location, Uint16 *ident)
+udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint16_t *ident)
 {
 	tag *tag_p;
 	struct buffer_head *bh = NULL;
-	register Uint8 checksum;
+	register uint8_t checksum;
 	register int i;
 
 	/* Read the block */
@@ -326,9 +289,9 @@
 	/* Verify the tag checksum */
 	checksum = 0U;
 	for (i = 0; i < 4; i++)
-		checksum += (Uint8)(bh->b_data[i]);
+		checksum += (uint8_t)(bh->b_data[i]);
 	for (i = 5; i < 16; i++)
-		checksum += (Uint8)(bh->b_data[i]);
+		checksum += (uint8_t)(bh->b_data[i]);
 	if (checksum != tag_p->tagChecksum) {
 		printk(KERN_ERR "udf: tag checksum failed block %d\n", block);
 		goto error_out;
@@ -359,7 +322,7 @@
 }
 
 extern struct buffer_head *
-udf_read_ptagged(struct super_block *sb, lb_addr loc, Uint32 offset, Uint16 *ident)
+udf_read_ptagged(struct super_block *sb, lb_addr loc, uint32_t offset, uint16_t *ident)
 {
 	return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset),
 		loc.logicalBlockNum + offset, ident);
@@ -371,8 +334,6 @@
 		brelse(bh);
 }
 
-#endif
-
 void udf_update_tag(char *data, int length)
 {
 	tag *tptr = (tag *)data;
@@ -386,11 +347,11 @@
 
 	for (i=0; i<16; i++)
 		if (i != 4)
-			tptr->tagChecksum += (Uint8)(data[i]);
+			tptr->tagChecksum += (uint8_t)(data[i]);
 }
 
-void udf_new_tag(char *data, Uint16 ident, Uint16 version, Uint16 snum,
-	Uint32 loc, int length)
+void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum,
+	uint32_t loc, int length)
 {
 	tag *tptr = (tag *)data;
 	tptr->tagIdent = le16_to_cpu(ident);
@@ -399,114 +360,3 @@
 	tptr->tagLocation = le32_to_cpu(loc);
 	udf_update_tag(data, length);
 }
-
-#ifndef __KERNEL__
-/*
- * udf_read_tagged_data
- *
- * PURPOSE
- *	Read the first block of a tagged descriptor.
- *	Usable from user-land.
- *
- * HISTORY
- *	  10/4/98 dgb: written
- */
-int
-udf_read_tagged_data(char *buffer, int size, int fd, int block, int offset)
-{
-	tag *tag_p;
-	register Uint8 checksum;
-	register int i;
-	unsigned long offs;
-
-	if (!buffer)
-	{
-		udf_errno = 1;
-		return -1;
-	}
-
-	if ( !udf_blocksize )
-	{
-		udf_errno = 2;
-		return -1;
-	}
-
-	if ( size < udf_blocksize )
-	{
-		udf_errno = 3;
-		return -1;
-	}
-	udf_errno = 0;
-	
-	offs = (long)block * udf_blocksize;
-	if ( lseek(fd, offs, SEEK_SET) != offs )
-	{
-		udf_errno = 4;
-		return -1;
-	}
-
-	i = read(fd, buffer, udf_blocksize);
-	if ( i < udf_blocksize )
-	{
-		udf_errno = 5;
-		return -1;
-	}
-
-	tag_p = (tag *)(buffer);
-
-	/* Verify the tag location */
-	if ((block-offset) != tag_p->tagLocation)
-	{
-#ifdef __KERNEL__
-		printk(KERN_ERR "udf: location mismatch block %d, tag %d\n",
-			block, tag_p->tagLocation);
-#else
-		udf_errno = 6;
-#endif
-		goto error_out;
-	}
-	
-	/* Verify the tag checksum */
-	checksum = 0U;
-	for (i = 0; i < 4; i++)
-		checksum += (Uint8)(buffer[i]);
-	for (i = 5; i < 16; i++)
-		checksum += (Uint8)(buffer[i]);
-	if (checksum != tag_p->tagChecksum)
-	{
-#ifdef __KERNEL__
-		printk(KERN_ERR "udf: tag checksum failed\n");
-#else
-		udf_errno = 7;
-#endif
-		goto error_out;
-	}
-
-	/* Verify the tag version */
-	if (tag_p->descVersion != 0x0002U)
-	{
-#ifdef __KERNEL__
-		printk(KERN_ERR "udf: tag version 0x%04x != 0x0002U\n",
-			tag_p->descVersion);
-#else
-		udf_errno = 8;
-#endif
-		goto error_out;
-	}
-
-	/* Verify the descriptor CRC */
-	if (tag_p->descCRC == udf_crc(buffer + 16, tag_p->descCRCLength, 0))
-	{
-		udf_errno = 0;
-		return 0;
-	}
-#ifdef __KERNEL__
-	printk(KERN_ERR "udf: crc failure in udf_read_tagged\n");
-#else
-	udf_errno = 9;
-#endif
-
-error_out:
-	return -1;
-}
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/namei.c linux/fs/udf/namei.c
--- linux.orig/fs/udf/namei.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/namei.c	2002-07-20 01:08:31.000000000 +0000
@@ -15,7 +15,7 @@
  *              ftp://prep.ai.mit.edu/pub/gnu/GPL
  *      Each contributing author retains all rights to their own work.
  *
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *  (C) 1999-2000 Stelias Computing Inc
  *
  * HISTORY
@@ -35,7 +35,6 @@
 #include <linux/quotaops.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
-#include <linux/udf_fs.h>
 
 static inline int udf_match(int len, const char * const name, struct qstr *qs)
 {
@@ -44,31 +43,31 @@
 	return !memcmp(name, qs->name, len);
 }
 
-int udf_write_fi(struct inode *inode, struct FileIdentDesc *cfi,
-	struct FileIdentDesc *sfi, struct udf_fileident_bh *fibh,
-	Uint8 *impuse, Uint8 *fileident)
+int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
+	struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh,
+	uint8_t *impuse, uint8_t *fileident)
 {
-	Uint16 crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
-	Uint16 crc;
-	Uint8 checksum = 0;
+	uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
+	uint16_t crc;
+	uint8_t checksum = 0;
 	int i;
 	int offset;
-	Uint16 liu = le16_to_cpu(cfi->lengthOfImpUse);
-	Uint8 lfi = cfi->lengthFileIdent;
+	uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse);
+	uint8_t lfi = cfi->lengthFileIdent;
 	int padlen = fibh->eoffset - fibh->soffset - liu - lfi -
-		sizeof(struct FileIdentDesc);
+		sizeof(struct fileIdentDesc);
 
-	offset = fibh->soffset + sizeof(struct FileIdentDesc);
+	offset = fibh->soffset + sizeof(struct fileIdentDesc);
 
 	if (impuse)
 	{
 		if (offset + liu < 0)
-			memcpy((Uint8 *)sfi->impUse, impuse, liu);
+			memcpy((uint8_t *)sfi->impUse, impuse, liu);
 		else if (offset >= 0)
 			memcpy(fibh->ebh->b_data + offset, impuse, liu);
 		else
 		{
-			memcpy((Uint8 *)sfi->impUse, impuse, -offset);
+			memcpy((uint8_t *)sfi->impUse, impuse, -offset);
 			memcpy(fibh->ebh->b_data, impuse - offset, liu + offset);
 		}
 	}
@@ -78,12 +77,12 @@
 	if (fileident)
 	{
 		if (offset + lfi < 0)
-			memcpy((Uint8 *)sfi->fileIdent + liu, fileident, lfi);
+			memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi);
 		else if (offset >= 0)
 			memcpy(fibh->ebh->b_data + offset, fileident, lfi);
 		else
 		{
-			memcpy((Uint8 *)sfi->fileIdent + liu, fileident, -offset);
+			memcpy((uint8_t *)sfi->fileIdent + liu, fileident, -offset);
 			memcpy(fibh->ebh->b_data, fileident - offset, lfi + offset);
 		}
 	}
@@ -91,28 +90,28 @@
 	offset += lfi;
 
 	if (offset + padlen < 0)
-		memset((Uint8 *)sfi->padding + liu + lfi, 0x00, padlen);
+		memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen);
 	else if (offset >= 0)
 		memset(fibh->ebh->b_data + offset, 0x00, padlen);
 	else
 	{
-		memset((Uint8 *)sfi->padding + liu + lfi, 0x00, -offset);
+		memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset);
 		memset(fibh->ebh->b_data, 0x00, padlen + offset);
 	}
 
-	crc = udf_crc((Uint8 *)cfi + sizeof(tag), sizeof(struct FileIdentDesc) -
+	crc = udf_crc((uint8_t *)cfi + sizeof(tag), sizeof(struct fileIdentDesc) -
 		sizeof(tag), 0);
 
 	if (fibh->sbh == fibh->ebh)
-		crc = udf_crc((Uint8 *)sfi->impUse,
-			crclen + sizeof(tag) - sizeof(struct FileIdentDesc), crc);
-	else if (sizeof(struct FileIdentDesc) >= -fibh->soffset)
-		crc = udf_crc(fibh->ebh->b_data + sizeof(struct FileIdentDesc) + fibh->soffset,
-			crclen + sizeof(tag) - sizeof(struct FileIdentDesc), crc);
+		crc = udf_crc((uint8_t *)sfi->impUse,
+			crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc);
+	else if (sizeof(struct fileIdentDesc) >= -fibh->soffset)
+		crc = udf_crc(fibh->ebh->b_data + sizeof(struct fileIdentDesc) + fibh->soffset,
+			crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc);
 	else
 	{
-		crc = udf_crc((Uint8 *)sfi->impUse,
-			-fibh->soffset - sizeof(struct FileIdentDesc), crc);
+		crc = udf_crc((uint8_t *)sfi->impUse,
+			-fibh->soffset - sizeof(struct fileIdentDesc), crc);
 		crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc);
 	}
 
@@ -121,16 +120,16 @@
 
 	for (i=0; i<16; i++)
 		if (i != 4)
-			checksum += ((Uint8 *)&cfi->descTag)[i];
+			checksum += ((uint8_t *)&cfi->descTag)[i];
 
 	cfi->descTag.tagChecksum = checksum;
-	if (sizeof(struct FileIdentDesc) <= -fibh->soffset)
-		memcpy((Uint8 *)sfi, (Uint8 *)cfi, sizeof(struct FileIdentDesc));
+	if (sizeof(struct fileIdentDesc) <= -fibh->soffset)
+		memcpy((uint8_t *)sfi, (uint8_t *)cfi, sizeof(struct fileIdentDesc));
 	else
 	{
-		memcpy((Uint8 *)sfi, (Uint8 *)cfi, -fibh->soffset);
-		memcpy(fibh->ebh->b_data, (Uint8 *)cfi - fibh->soffset,
-			sizeof(struct FileIdentDesc) + fibh->soffset);
+		memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset);
+		memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset,
+			sizeof(struct fileIdentDesc) + fibh->soffset);
 	}
 
 	if (fibh->sbh != fibh->ebh)
@@ -139,21 +138,21 @@
 	return 0;
 }
 
-static struct FileIdentDesc *
+static struct fileIdentDesc *
 udf_find_entry(struct inode *dir, struct dentry *dentry,
 	struct udf_fileident_bh *fibh,
-	struct FileIdentDesc *cfi)
+	struct fileIdentDesc *cfi)
 {
-	struct FileIdentDesc *fi=NULL;
+	struct fileIdentDesc *fi=NULL;
 	loff_t f_pos;
 	int block, flen;
 	char fname[255];
 	char *nameptr;
-	Uint8 lfi;
-	Uint16 liu;
+	uint8_t lfi;
+	uint16_t liu;
 	loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
 	lb_addr bloc, eloc;
-	Uint32 extoffset, elen, offset;
+	uint32_t extoffset, elen, offset;
 	struct buffer_head *bh = NULL;
 
 	if (!dir)
@@ -163,15 +162,15 @@
 
 	fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
 	if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
-		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
+		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
 	{
 		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
-			if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
+			if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
 				extoffset -= sizeof(short_ad);
-			else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
+			else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
 				extoffset -= sizeof(long_ad);
 		}
 		else
@@ -213,10 +212,10 @@
 		{
 			int poffset;	/* Unpaded ending offset */
 
-			poffset = fibh->soffset + sizeof(struct FileIdentDesc) + liu + lfi;
+			poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi;
 
 			if (poffset >= lfi)
-				nameptr = (Uint8 *)(fibh->ebh->b_data + poffset - lfi);
+				nameptr = (uint8_t *)(fibh->ebh->b_data + poffset - lfi);
 			else
 			{
 				nameptr = fname;
@@ -225,13 +224,13 @@
 			}
 		}
 
-		if ( (cfi->fileCharacteristics & FILE_DELETED) != 0 )
+		if ( (cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 )
 		{
 			if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) )
 				continue;
 		}
 	    
-		if ( (cfi->fileCharacteristics & FILE_HIDDEN) != 0 )
+		if ( (cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0 )
 		{
 			if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
 				continue;
@@ -292,7 +291,7 @@
 udf_lookup(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = NULL;
-	struct FileIdentDesc cfi, *fi;
+	struct fileIdentDesc cfi, *fi;
 	struct udf_fileident_bh fibh;
 
 	if (dentry->d_name.len > UDF_NAME_LEN)
@@ -324,13 +323,13 @@
 	return NULL;
 }
 
-static struct FileIdentDesc *
+static struct fileIdentDesc *
 udf_add_entry(struct inode *dir, struct dentry *dentry,
 	struct udf_fileident_bh *fibh,
-	struct FileIdentDesc *cfi, int *err)
+	struct fileIdentDesc *cfi, int *err)
 {
 	struct super_block *sb;
-	struct FileIdentDesc *fi=NULL;
+	struct fileIdentDesc *fi=NULL;
 	struct ustr unifilename;
 	char name[UDF_NAME_LEN], fname[UDF_NAME_LEN];
 	int namelen;
@@ -339,11 +338,11 @@
 	char *nameptr;
 	loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
 	int nfidlen;
-	Uint8 lfi;
-	Uint16 liu;
+	uint8_t lfi;
+	uint16_t liu;
 	int block;
 	lb_addr bloc, eloc;
-	Uint32 extoffset, elen, offset;
+	uint32_t extoffset, elen, offset;
 	struct buffer_head *bh = NULL;
 
 	sb = dir->i_sb;
@@ -384,21 +383,21 @@
 	else
 		namelen = 0;
 
-	nfidlen = (sizeof(struct FileIdentDesc) + namelen + 3) & ~3;
+	nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3;
 
 	f_pos = (udf_ext0_offset(dir) >> 2);
 
 	fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
 	if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
-		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
+		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
 	{
 		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
-			if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
+			if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
 				extoffset -= sizeof(short_ad);
-			else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
+			else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
 				extoffset -= sizeof(long_ad);
 		}
 		else
@@ -436,7 +435,7 @@
 			{
 				int poffset;	/* Unpaded ending offset */
 	
-				poffset = fibh->soffset + sizeof(struct FileIdentDesc) + liu + lfi;
+				poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi;
 	
 				if (poffset >= lfi)
 					nameptr = (char *)(fibh->ebh->b_data + poffset - lfi);
@@ -448,9 +447,9 @@
 				}
 			}
 	
-			if ( (cfi->fileCharacteristics & FILE_DELETED) != 0 )
+			if ( (cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 )
 			{
-				if (((sizeof(struct FileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen)
+				if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen)
 				{
 					udf_release_data(bh);
 					cfi->descTag.tagSerialNum = cpu_to_le16(1);
@@ -486,7 +485,7 @@
 	else
 	{
 		block = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(dir), 0);
-		if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
+		if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
 		{
 			fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block);
 			fibh->soffset = fibh->eoffset = udf_file_entry_alloc_offset(dir);
@@ -500,7 +499,7 @@
 
 	f_pos += nfidlen;
 
-	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB &&
+	if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB &&
 		sb->s_blocksize - fibh->eoffset < nfidlen)
 	{
 		udf_release_data(bh);
@@ -518,9 +517,9 @@
 		eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
 		elen = dir->i_sb->s_blocksize;
 		extoffset = udf_file_entry_alloc_offset(dir);
-		if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
+		if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
 			extoffset += sizeof(short_ad);
-		else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
+		else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
 			extoffset += sizeof(long_ad);
 	}
 
@@ -534,13 +533,13 @@
 			fibh->sbh = fibh->ebh;
 		}
 
-		if (UDF_I_ALLOCTYPE(dir) != ICB_FLAG_AD_IN_ICB)
+		if (UDF_I_ALLOCTYPE(dir) != ICBTAG_FLAG_AD_IN_ICB)
 			block = eloc.logicalBlockNum + ((elen - 1) >>
 				dir->i_sb->s_blocksize_bits);
 		else
 			block = UDF_I_LOCATION(dir).logicalBlockNum;
 				
-		fi = (struct FileIdentDesc *)(fibh->sbh->b_data + fibh->soffset);
+		fi = (struct fileIdentDesc *)(fibh->sbh->b_data + fibh->soffset);
 	}
 	else
 	{
@@ -565,7 +564,7 @@
 		if (!(fibh->soffset))
 		{
 			if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) ==
-				EXTENT_RECORDED_ALLOCATED)
+				(EXT_RECORDED_ALLOCATED >> 30))
 			{
 				block = eloc.logicalBlockNum + ((elen - 1) >>
 					dir->i_sb->s_blocksize_bits);
@@ -575,17 +574,20 @@
 
 			udf_release_data(fibh->sbh);
 			fibh->sbh = fibh->ebh;
-			fi = (struct FileIdentDesc *)(fibh->sbh->b_data);
+			fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
 		}
 		else
 		{
-			fi = (struct FileIdentDesc *)
+			fi = (struct fileIdentDesc *)
 				(fibh->sbh->b_data + sb->s_blocksize + fibh->soffset);
 		}
 	}
 
-	memset(cfi, 0, sizeof(struct FileIdentDesc));
-	udf_new_tag((char *)cfi, TID_FILE_IDENT_DESC, 2, 1, block, sizeof(tag));
+	memset(cfi, 0, sizeof(struct fileIdentDesc));
+	if (UDF_SB_UDFREV(sb) >= 0x0200)
+		udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, sizeof(tag));
+	else
+		udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, sizeof(tag));
 	cfi->fileVersionNum = cpu_to_le16(1);
 	cfi->lengthFileIdent = namelen;
 	cfi->lengthOfImpUse = cpu_to_le16(0);
@@ -593,7 +595,7 @@
 	{
 		udf_release_data(bh);
 		dir->i_size += nfidlen;
-		if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
+		if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
 			UDF_I_LENALLOC(dir) += nfidlen;
 		dir->i_version = ++event;
 		mark_inode_dirty(dir);
@@ -610,10 +612,10 @@
 	}
 }
 
-static int udf_delete_entry(struct inode *inode, struct FileIdentDesc *fi,
-	struct udf_fileident_bh *fibh, struct FileIdentDesc *cfi)
+static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
+	struct udf_fileident_bh *fibh, struct fileIdentDesc *cfi)
 {
-	cfi->fileCharacteristics |= FILE_DELETED;
+	cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
 		memset(&(cfi->icb), 0x00, sizeof(long_ad));
 	return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
@@ -623,14 +625,14 @@
 {
 	struct udf_fileident_bh fibh;
 	struct inode *inode;
-	struct FileIdentDesc cfi, *fi;
+	struct fileIdentDesc cfi, *fi;
 	int err;
 
 	inode = udf_new_inode(dir, mode, &err);
 	if (!inode)
 		return err;
 
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 		inode->i_data.a_ops = &udf_adinicb_aops;
 	else
 		inode->i_data.a_ops = &udf_aops;
@@ -648,10 +650,10 @@
 	}
 	cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
 	cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
-	*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
+	*(uint32_t *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
 		cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
 	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
-	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
 	{
 		mark_inode_dirty(dir);
 		dir->i_version = ++event;
@@ -668,7 +670,7 @@
 	struct inode * inode;
 	struct udf_fileident_bh fibh;
 	int err;
-	struct FileIdentDesc cfi, *fi;
+	struct fileIdentDesc cfi, *fi;
 
 	err = -EIO;
 	inode = udf_new_inode(dir, mode, &err);
@@ -686,10 +688,10 @@
 	}
 	cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
 	cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
-	*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
+	*(uint32_t *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
 		cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
 	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
-	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
 	{
 		mark_inode_dirty(dir);
 		dir->i_version = ++event;
@@ -710,7 +712,7 @@
 	struct inode * inode;
 	struct udf_fileident_bh fibh;
 	int err;
-	struct FileIdentDesc cfi, *fi;
+	struct fileIdentDesc cfi, *fi;
 
 	err = -EMLINK;
 	if (dir->i_nlink >= (256<<sizeof(dir->i_nlink))-1)
@@ -733,9 +735,9 @@
 	inode->i_nlink = 2;
 	cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
 	cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(dir));
-	*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
+	*(uint32_t *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
 		cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
-	cfi.fileCharacteristics = FILE_DIRECTORY | FILE_PARENT;
+	cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
 	udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
 	udf_release_data(fibh.sbh);
 	inode->i_mode = S_IFDIR | mode;
@@ -752,9 +754,9 @@
 	}
 	cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
 	cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
-	*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
+	*(uint32_t *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
 		cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
-	cfi.fileCharacteristics |= FILE_DIRECTORY;
+	cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
 	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
 	dir->i_version = ++event;
 	dir->i_nlink++;
@@ -770,28 +772,28 @@
 
 static int empty_dir(struct inode *dir)
 {
-	struct FileIdentDesc *fi, cfi;
+	struct fileIdentDesc *fi, cfi;
 	struct udf_fileident_bh fibh;
 	loff_t f_pos;
 	loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
 	int block;
 	lb_addr bloc, eloc;
-	Uint32 extoffset, elen, offset;
+	uint32_t extoffset, elen, offset;
 	struct buffer_head *bh = NULL;
 
 	f_pos = (udf_ext0_offset(dir) >> 2);
 
 	fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
 	if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
-		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
+		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
 	{
 		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
-			if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
+			if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
 				extoffset -= sizeof(short_ad);
-			else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
+			else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
 				extoffset -= sizeof(long_ad);
 		}
 		else
@@ -819,7 +821,7 @@
 			return 0;
 		}
 
-		if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FILE_DELETED) == 0)
+		if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0)
 		{
 			udf_release_data(bh);
 			return 0;
@@ -837,7 +839,7 @@
 	int retval;
 	struct inode * inode = dentry->d_inode;
 	struct udf_fileident_bh fibh;
-	struct FileIdentDesc *fi, cfi;
+	struct fileIdentDesc *fi, cfi;
 
 	retval = -ENOENT;
 	fi = udf_find_entry(dir, dentry, &fibh, &cfi);
@@ -880,8 +882,8 @@
 	int retval;
 	struct inode * inode = dentry->d_inode;
 	struct udf_fileident_bh fibh;
-	struct FileIdentDesc *fi;
-	struct FileIdentDesc cfi;
+	struct fileIdentDesc *fi;
+	struct fileIdentDesc cfi;
 
 	retval = -ENOENT;
 	fi = udf_find_entry(dir, dentry, &fibh, &cfi);
@@ -924,13 +926,13 @@
 static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * symname)
 {
 	struct inode * inode;
-	struct PathComponent *pc;
+	struct pathComponent *pc;
 	char *compstart;
 	struct udf_fileident_bh fibh;
 	struct buffer_head *bh = NULL;
 	int eoffset, elen = 0;
-	struct FileIdentDesc *fi;
-	struct FileIdentDesc cfi;
+	struct fileIdentDesc *fi;
+	struct fileIdentDesc cfi;
 	char *ea;
 	int err;
 	int block;
@@ -942,11 +944,11 @@
 	inode->i_data.a_ops = &udf_symlink_aops;
 	inode->i_op = &page_symlink_inode_operations;
 
-	if (UDF_I_ALLOCTYPE(inode) != ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB)
 	{
 		struct buffer_head *bh = NULL;
 		lb_addr bloc, eloc;
-		Uint32 elen, extoffset;
+		uint32_t elen, extoffset;
 
 		block = udf_new_block(inode->i_sb, inode,
 			UDF_I_LOCATION(inode).partitionReferenceNum,
@@ -979,7 +981,7 @@
 	ea = bh->b_data + udf_ext0_offset(inode);
 
 	eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
-	pc = (struct PathComponent *)ea;
+	pc = (struct pathComponent *)ea;
 
 	if (*symname == '/')
 	{
@@ -991,18 +993,18 @@
 		pc->componentType = 1;
 		pc->lengthComponentIdent = 0;
 		pc->componentFileVersionNum = 0;
-		pc += sizeof(struct PathComponent);
-		elen += sizeof(struct PathComponent);
+		pc += sizeof(struct pathComponent);
+		elen += sizeof(struct pathComponent);
 	}
 
 	err = -ENAMETOOLONG;
 
 	while (*symname)
 	{
-		if (elen + sizeof(struct PathComponent) > eoffset)
+		if (elen + sizeof(struct pathComponent) > eoffset)
 			goto out_no_entry;
 
-		pc = (struct PathComponent *)(ea + elen);
+		pc = (struct pathComponent *)(ea + elen);
 
 		compstart = (char *)symname;
 
@@ -1024,7 +1026,7 @@
 
 		if (pc->componentType == 5)
 		{
-			if (elen + sizeof(struct PathComponent) + symname - compstart > eoffset)
+			if (elen + sizeof(struct pathComponent) + symname - compstart > eoffset)
 				goto out_no_entry;
 			else
 				pc->lengthComponentIdent = symname - compstart;
@@ -1032,7 +1034,7 @@
 			memcpy(pc->componentIdent, compstart, pc->lengthComponentIdent);
 		}
 
-		elen += sizeof(struct PathComponent) + pc->lengthComponentIdent;
+		elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
 
 		if (*symname)
 		{
@@ -1045,7 +1047,7 @@
 
 	udf_release_data(bh);
 	inode->i_size = elen;
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 		UDF_I_LENALLOC(inode) = inode->i_size;
 	mark_inode_dirty(inode);
 
@@ -1055,11 +1057,11 @@
 	cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
 	if (UDF_SB_LVIDBH(inode->i_sb))
 	{
-		struct LogicalVolHeaderDesc *lvhd;
-		Uint64 uniqueID;
-		lvhd = (struct LogicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
+		struct logicalVolHeaderDesc *lvhd;
+		uint64_t uniqueID;
+		lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
 		uniqueID = le64_to_cpu(lvhd->uniqueID);
-		*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
+		*(uint32_t *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
 			cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
 		if (!(++uniqueID & 0x00000000FFFFFFFFUL))
 			uniqueID += 16;
@@ -1067,7 +1069,7 @@
 		mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
 	}
 	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
-	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
 	{
 		mark_inode_dirty(dir);
 		dir->i_version = ++event;
@@ -1094,7 +1096,7 @@
 	struct inode *inode = old_dentry->d_inode;
 	struct udf_fileident_bh fibh;
 	int err;
-	struct FileIdentDesc cfi, *fi;
+	struct fileIdentDesc cfi, *fi;
 
 	if (S_ISDIR(inode->i_mode))
 		return -EPERM;
@@ -1108,11 +1110,11 @@
 	cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
 	if (UDF_SB_LVIDBH(inode->i_sb))
 	{
-		struct LogicalVolHeaderDesc *lvhd;
-		Uint64 uniqueID;
-		lvhd = (struct LogicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
+		struct logicalVolHeaderDesc *lvhd;
+		uint64_t uniqueID;
+		lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
 		uniqueID = le64_to_cpu(lvhd->uniqueID);
-		*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
+		*(uint32_t *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
 			cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
 		if (!(++uniqueID & 0x00000000FFFFFFFFUL))
 			uniqueID += 16;
@@ -1120,7 +1122,7 @@
 		mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
 	}
 	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
-	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
 	{
 		mark_inode_dirty(dir);
 		dir->i_version = ++event;
@@ -1146,7 +1148,7 @@
 	struct inode * old_inode = old_dentry->d_inode;
 	struct inode * new_inode = new_dentry->d_inode;
 	struct udf_fileident_bh ofibh, nfibh;
-	struct FileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
+	struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
 	struct buffer_head *dir_bh = NULL;
 	int retval = -ENOENT;
 
@@ -1175,7 +1177,7 @@
 	}
 	if (S_ISDIR(old_inode->i_mode))
 	{
-		Uint32 offset = udf_ext0_offset(old_inode);
+		uint32_t offset = udf_ext0_offset(old_inode);
 
 		if (new_inode)
 		{
@@ -1242,12 +1244,12 @@
 	if (dir_bh)
 	{
 		dir_fi->icb.extLocation = lelb_to_cpu(UDF_I_LOCATION(new_dir));
-		udf_update_tag((char *)dir_fi, (sizeof(struct FileIdentDesc) +
+		udf_update_tag((char *)dir_fi, (sizeof(struct fileIdentDesc) +
 			cpu_to_le16(dir_fi->lengthOfImpUse) + 3) & ~3);
-		if (UDF_I_ALLOCTYPE(old_inode) == ICB_FLAG_AD_IN_ICB)
+		if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB)
 		{
-			mark_inode_dirty(old_inode);
 			old_inode->i_version = ++event;
+			mark_inode_dirty(old_inode);
 		}
 		else
 			mark_buffer_dirty_inode(dir_bh, old_inode);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/osta_udf.h linux/fs/udf/osta_udf.h
--- linux.orig/fs/udf/osta_udf.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/fs/udf/osta_udf.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,271 @@
+/*
+ * osta_udf.h
+ *
+ * This file is based on OSTA UDF(tm) 2.01 (March 15, 2000)
+ * http://www.osta.org
+ *
+ * Copyright (c) 2001-2002  Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "ecma_167.h"
+
+#ifndef _OSTA_UDF_H
+#define _OSTA_UDF_H 1
+
+/* OSTA CS0 Charspec (UDF 2.01 2.1.2) */
+#define UDF_CHAR_SET_TYPE		0
+#define UDF_CHAR_SET_INFO		"OSTA Compressed Unicode"
+
+/* Entity Identifier (UDF 2.01 2.1.5) */
+/* Identifiers (UDF 2.01 2.1.5.2) */
+#define UDF_ID_DEVELOPER		"*Linux UDFFS"
+#define	UDF_ID_COMPLIANT		"*OSTA UDF Compliant"
+#define UDF_ID_LV_INFO			"*UDF LV Info"
+#define UDF_ID_FREE_EA			"*UDF FreeEASpace"
+#define UDF_ID_FREE_APP_EA		"*UDF FreeAppEASpace"
+#define UDF_ID_DVD_CGMS			"*UDF DVD CGMS Info"
+#define UDF_ID_OS2_EA			"*UDF OS/2 EA"
+#define UDF_ID_OS2_EA_LENGTH		"*UDF OS/2 EALength"
+#define UDF_ID_MAC_VOLUME		"*UDF Mac VolumeInfo"
+#define UDF_ID_MAC_FINDER		"*UDF Mac FinderInfo"
+#define UDF_ID_MAC_UNIQUE		"*UDF Mac UniqueIDTable"
+#define UDF_ID_MAC_RESOURCE		"*UDF Mac ResourceFork"
+#define UDF_ID_VIRTUAL			"*UDF Virtual Partition"
+#define UDF_ID_SPARABLE			"*UDF Sparable Partition"
+#define UDF_ID_ALLOC			"*UDF Virtual Alloc Tbl"
+#define UDF_ID_SPARING			"*UDF Sparing Table"
+
+/* Identifier Suffix (UDF 2.01 2.1.5.3) */
+#define IS_DF_HARD_WRITE_PROTECT	0x01
+#define IS_DF_SOFT_WRITE_PROTECT	0x02
+
+struct UDFIdentSuffix
+{
+	uint16_t	UDFRevision;
+	uint8_t		OSClass;
+	uint8_t		OSIdentifier;
+	uint8_t		reserved[4];
+} __attribute__ ((packed));
+
+struct impIdentSuffix
+{
+	uint8_t		OSClass;
+	uint8_t		OSIdentifier;
+	uint8_t		reserved[6];
+} __attribute__ ((packed));
+
+struct appIdentSuffix
+{
+	uint8_t		impUse[8];
+} __attribute__ ((packed));
+ 
+/* Logical Volume Integrity Descriptor (UDF 2.01 2.2.6) */
+/* Implementation Use (UDF 2.01 2.2.6.4) */
+struct logicalVolIntegrityDescImpUse
+{
+	regid		impIdent;
+	uint32_t	numFiles;
+	uint32_t	numDirs;
+	uint16_t	minUDFReadRev;
+	uint16_t	minUDFWriteRev;
+	uint16_t	maxUDFWriteRev;
+	uint8_t		impUse[0];
+} __attribute__ ((packed));
+
+/* Implementation Use Volume Descriptor (UDF 2.01 2.2.7) */
+/* Implementation Use (UDF 2.01 2.2.7.2) */
+struct impUseVolDescImpUse
+{
+	charspec	LVICharset;
+	dstring		logicalVolIdent[128];
+	dstring		LVInfo1[36];
+	dstring		LVInfo2[36];
+	dstring		LVInfo3[36];
+	regid		impIdent;
+	uint8_t		impUse[128];
+} __attribute__ ((packed));
+
+struct udfPartitionMap2
+{
+	uint8_t		partitionMapType;
+	uint8_t		partitionMapLength;
+	uint8_t		reserved1[2];
+	regid		partIdent;
+	uint16_t	volSeqNum;
+	uint16_t	partitionNum;
+} __attribute__ ((packed));
+
+/* Virtual Partition Map (UDF 2.01 2.2.8) */
+struct virtualPartitionMap
+{
+	uint8_t		partitionMapType;
+	uint8_t		partitionMapLength;
+	uint8_t		reserved1[2];
+	regid		partIdent;
+	uint16_t	volSeqNum;
+	uint16_t	partitionNum;
+	uint8_t		reserved2[24];
+} __attribute__ ((packed));
+
+/* Sparable Partition Map (UDF 2.01 2.2.9) */
+struct sparablePartitionMap
+{
+	uint8_t		partitionMapType;
+	uint8_t		partitionMapLength;
+	uint8_t		reserved1[2];
+	regid		partIdent;
+	uint16_t	volSeqNum;
+	uint16_t	partitionNum;
+	uint16_t	packetLength;
+	uint8_t		numSparingTables;
+	uint8_t		reserved2[1];
+	uint32_t	sizeSparingTable;
+	uint32_t	locSparingTable[4];
+} __attribute__ ((packed));
+
+/* Virtual Allocation Table (UDF 1.5 2.2.10) */
+struct virtualAllocationTable15
+{
+	uint32_t	VirtualSector[0];
+	regid		ident;
+	uint32_t	previousVATICB;
+} __attribute__ ((packed));  
+
+#define ICBTAG_FILE_TYPE_VAT15		0x00U
+
+/* Virtual Allocation Table (UDF 2.01 2.2.10) */
+struct virtualAllocationTable20
+{
+	uint16_t	lengthHeader;
+	uint16_t	lengthImpUse;
+	dstring		logicalVolIdent[128];
+	uint32_t	previousVatICBLoc;
+	uint32_t	numFIDSFiles;
+	uint32_t	numFIDSDirectories;
+	uint16_t	minReadRevision;
+	uint16_t	minWriteRevision;
+	uint16_t	maxWriteRevision;
+	uint16_t	reserved;
+	uint8_t		impUse[0];
+	uint32_t	vatEntry[0];
+} __attribute__ ((packed));
+
+#define ICBTAG_FILE_TYPE_VAT20		0xF8U
+
+/* Sparing Table (UDF 2.01 2.2.11) */
+struct sparingEntry
+{
+	uint32_t	origLocation;
+	uint32_t	mappedLocation;
+} __attribute__ ((packed));
+
+struct sparingTable
+{
+	tag 		descTag;
+	regid		sparingIdent;
+	uint16_t	reallocationTableLen;
+	uint16_t	reserved;
+	uint32_t	sequenceNum;
+	struct sparingEntry
+			mapEntry[0];
+} __attribute__ ((packed));
+
+/* struct long_ad ICB - ADImpUse (UDF 2.01 2.2.4.3) */
+struct allocDescImpUse
+{
+	uint16_t	flags;
+	uint8_t		impUse[4];
+} __attribute__ ((packed));
+
+#define AD_IU_EXT_ERASED		0x0001
+
+/* Real-Time Files (UDF 2.01 6.11) */
+#define ICBTAG_FILE_TYPE_REALTIME	0xF9U
+
+/* Implementation Use Extended Attribute (UDF 2.01 3.3.4.5) */
+/* FreeEASpace (UDF 2.01 3.3.4.5.1.1) */
+struct freeEaSpace
+{
+	uint16_t	headerChecksum;
+	uint8_t		freeEASpace[0];
+} __attribute__ ((packed));
+
+/* DVD Copyright Management Information (UDF 2.01 3.3.4.5.1.2) */
+struct DVDCopyrightImpUse 
+{
+	uint16_t	headerChecksum;
+	uint8_t		CGMSInfo;
+	uint8_t		dataType;
+	uint8_t		protectionSystemInfo[4];
+} __attribute__ ((packed));
+
+/* Application Use Extended Attribute (UDF 2.01 3.3.4.6) */
+/* FreeAppEASpace (UDF 2.01 3.3.4.6.1) */
+struct freeAppEASpace
+{
+	uint16_t	headerChecksum;
+	uint8_t		freeEASpace[0];
+} __attribute__ ((packed));
+
+/* UDF Defined System Stream (UDF 2.01 3.3.7) */
+#define UDF_ID_UNIQUE_ID		"*UDF Unique ID Mapping Data"
+#define UDF_ID_NON_ALLOC		"*UDF Non-Allocatable Space"
+#define UDF_ID_POWER_CAL		"*UDF Power Cal Table"
+#define UDF_ID_BACKUP			"*UDF Backup"
+
+/* Operating System Identifiers (UDF 2.01 6.3) */
+#define UDF_OS_CLASS_UNDEF		0x00U
+#define UDF_OS_CLASS_DOS		0x01U
+#define UDF_OS_CLASS_OS2		0x02U
+#define UDF_OS_CLASS_MAC		0x03U
+#define UDF_OS_CLASS_UNIX		0x04U
+#define UDF_OS_CLASS_WIN9X		0x05U
+#define UDF_OS_CLASS_WINNT		0x06U
+#define UDF_OS_CLASS_OS400		0x07U
+#define UDF_OS_CLASS_BEOS		0x08U
+#define UDF_OS_CLASS_WINCE		0x09U
+
+#define UDF_OS_ID_UNDEF			0x00U
+#define UDF_OS_ID_DOS			0x00U
+#define UDF_OS_ID_OS2			0x00U
+#define UDF_OS_ID_MAC			0x00U
+#define UDF_OS_ID_UNIX			0x00U
+#define UDF_OS_ID_AIX			0x01U
+#define UDF_OS_ID_SOLARIS		0x02U
+#define UDF_OS_ID_HPUX			0x03U
+#define UDF_OS_ID_IRIX			0x04U
+#define UDF_OS_ID_LINUX			0x05U
+#define UDF_OS_ID_MKLINUX		0x06U
+#define UDF_OS_ID_FREEBSD		0x07U
+#define UDF_OS_ID_WIN9X			0x00U
+#define UDF_OS_ID_WINNT			0x00U
+#define UDF_OS_ID_OS400			0x00U
+#define UDF_OS_ID_BEOS			0x00U
+#define UDF_OS_ID_WINCE			0x00U
+
+#endif /* _OSTA_UDF_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/partition.c linux/fs/udf/partition.c
--- linux.orig/fs/udf/partition.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/partition.c	2002-07-20 01:08:21.000000000 +0000
@@ -15,7 +15,7 @@
  *              ftp://prep.ai.mit.edu/pub/gnu/GPL
  *      Each contributing author retains all rights to their own work.
  *
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *
  * HISTORY
  *
@@ -32,7 +32,7 @@
 #include <linux/udf_fs.h>
 #include <linux/slab.h>
 
-inline Uint32 udf_get_pblock(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
+inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
 {
 	if (partition >= UDF_SB_NUMPARTS(sb))
 	{
@@ -46,14 +46,14 @@
 		return UDF_SB_PARTROOT(sb, partition) + block + offset;
 }
 
-Uint32 udf_get_pblock_virt15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
+uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
 {
 	struct buffer_head *bh = NULL;
-	Uint32 newblock;
-	Uint32 index;
-	Uint32 loc;
+	uint32_t newblock;
+	uint32_t index;
+	uint32_t loc;
 
-	index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(Uint32);
+	index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(uint32_t);
 
 	if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries)
 	{
@@ -65,13 +65,13 @@
 	if (block >= index)
 	{
 		block -= index;
-		newblock = 1 + (block / (sb->s_blocksize / sizeof(Uint32)));
-		index = block % (sb->s_blocksize / sizeof(Uint32));
+		newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t)));
+		index = block % (sb->s_blocksize / sizeof(uint32_t));
 	}
 	else
 	{
 		newblock = 0;
-		index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(Uint32) + block;
+		index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(uint32_t) + block;
 	}
 
 	loc = udf_block_map(UDF_SB_VAT(sb), newblock);
@@ -83,7 +83,7 @@
 		return 0xFFFFFFFF;
 	}
 
-	loc = le32_to_cpu(((Uint32 *)bh->b_data)[index]);
+	loc = le32_to_cpu(((uint32_t *)bh->b_data)[index]);
 
 	udf_release_data(bh);
 
@@ -96,22 +96,22 @@
 	return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset);
 }
 
-inline Uint32 udf_get_pblock_virt20(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
+inline uint32_t udf_get_pblock_virt20(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
 {
 	return udf_get_pblock_virt15(sb, block, partition, offset);
 }
 
-Uint32 udf_get_pblock_spar15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
+uint32_t udf_get_pblock_spar15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
 {
 	int i;
-	struct SparingTable *st = NULL;
-	Uint32 packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1);
+	struct sparingTable *st = NULL;
+	uint32_t packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1);
 
 	for (i=0; i<4; i++)
 	{
 		if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL)
 		{
-			st = (struct SparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data;
+			st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data;
 			break;
 		}
 	}
@@ -137,9 +137,9 @@
 int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
 {
 	struct udf_sparing_data *sdata;
-	struct SparingTable *st = NULL;
-	SparingEntry mapEntry;
-	Uint32 packet;
+	struct sparingTable *st = NULL;
+	struct sparingEntry mapEntry;
+	uint32_t packet;
 	int i, j, k, l;
 
 	for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
@@ -154,7 +154,7 @@
 			{
 				if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
 				{
-					st = (struct SparingTable *)sdata->s_spar_map[j]->b_data;
+					st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
 					break;
 				}
 			}
@@ -170,9 +170,9 @@
 					{
 						if (sdata->s_spar_map[j])
 						{
-							st = (struct SparingTable *)sdata->s_spar_map[j]->b_data;
+							st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
 							st->mapEntry[k].origLocation = cpu_to_le32(packet);
-							udf_update_tag((char *)st, sizeof(struct SparingTable) + st->reallocationTableLen * sizeof(SparingEntry));
+							udf_update_tag((char *)st, sizeof(struct sparingTable) + st->reallocationTableLen * sizeof(struct sparingEntry));
 							mark_buffer_dirty(sdata->s_spar_map[j]);
 						}
 					}
@@ -197,12 +197,12 @@
 					{
 						if (sdata->s_spar_map[j])
 						{
-							st = (struct SparingTable *)sdata->s_spar_map[j]->b_data;
+							st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
 							mapEntry = st->mapEntry[l];
 							mapEntry.origLocation = cpu_to_le32(packet);
-							memmove(&st->mapEntry[k+1], &st->mapEntry[k], (l-k)*sizeof(SparingEntry));
+							memmove(&st->mapEntry[k+1], &st->mapEntry[k], (l-k)*sizeof(struct sparingEntry));
 							st->mapEntry[k] = mapEntry;
-							udf_update_tag((char *)st, sizeof(struct SparingTable) + st->reallocationTableLen * sizeof(SparingEntry));
+							udf_update_tag((char *)st, sizeof(struct sparingTable) + st->reallocationTableLen * sizeof(struct sparingEntry));
 							mark_buffer_dirty(sdata->s_spar_map[j]);
 						}
 					}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/super.c linux/fs/udf/super.c
--- linux.orig/fs/udf/super.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/super.c	2002-07-20 01:08:38.000000000 +0000
@@ -26,7 +26,7 @@
  *  Each contributing author retains all rights to their own work.
  *
  *  (C) 1998 Dave Boynton
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *  (C) 2000 Stelias Computing Inc
  *
  * HISTORY
@@ -387,7 +387,7 @@
 static int
 udf_vrs(struct super_block *sb, int silent)
 {
-	struct VolStructDesc *vsd = NULL;
+	struct volStructDesc *vsd = NULL;
 	int sector = 32768;
 	int sectorsize;
 	struct buffer_head *bh = NULL;
@@ -399,8 +399,8 @@
 	if (sb->s_blocksize & 511)
 		return 0;
 
-	if (sb->s_blocksize < sizeof(struct VolStructDesc))
-		sectorsize = sizeof(struct VolStructDesc);
+	if (sb->s_blocksize < sizeof(struct volStructDesc))
+		sectorsize = sizeof(struct volStructDesc);
 	else
 		sectorsize = sb->s_blocksize;
 
@@ -417,7 +417,7 @@
 			break;
 
 		/* Look for ISO  descriptors */
-		vsd = (struct VolStructDesc *)(bh->b_data +
+		vsd = (struct volStructDesc *)(bh->b_data +
 			(sector & (sb->s_blocksize - 1)));
 
 		if (vsd->stdIdent[0] == 0)
@@ -425,7 +425,7 @@
 			udf_release_data(bh);
 			break;
 		}
-		else if (!strncmp(vsd->stdIdent, STD_ID_CD001, STD_ID_LEN))
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN))
 		{
 			iso9660 = sector;
 			switch (vsd->structType)
@@ -450,19 +450,19 @@
 					break;
 			}
 		}
-		else if (!strncmp(vsd->stdIdent, STD_ID_BEA01, STD_ID_LEN))
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN))
 		{
 		}
-		else if (!strncmp(vsd->stdIdent, STD_ID_TEA01, STD_ID_LEN))
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN))
 		{
 			udf_release_data(bh);
 			break;
 		}
-		else if (!strncmp(vsd->stdIdent, STD_ID_NSR02, STD_ID_LEN))
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
 		{
 			nsr02 = sector;
 		}
-		else if (!strncmp(vsd->stdIdent, STD_ID_NSR03, STD_ID_LEN))
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN))
 		{
 			nsr03 = sector;
 		}
@@ -501,8 +501,8 @@
 {
 	int lastblock = UDF_SB_LASTBLOCK(sb);
 	struct buffer_head *bh = NULL;
-	Uint16 ident;
-	Uint32 location;
+	uint16_t ident;
+	uint32_t location;
 	int i;
 
 	if (lastblock)
@@ -536,7 +536,7 @@
 				udf_release_data(bh);
 			}
 	
-			if (ident == TID_ANCHOR_VOL_DESC_PTR)
+			if (ident == TAG_IDENT_AVDP)
 			{
 				if (location == last[i] - UDF_SB_SESSION(sb))
 				{
@@ -553,7 +553,7 @@
 					udf_debug("Anchor found at block %d, location mismatch %d.\n",
 						last[i], location);
 			}
-			else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
+			else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE)
 			{
 				lastblock = last[i];
 				UDF_SB_ANCHOR(sb)[3] = 512 + UDF_SB_SESSION(sb);
@@ -571,7 +571,7 @@
 					udf_release_data(bh);
 				}
 	
-				if (ident == TID_ANCHOR_VOL_DESC_PTR &&
+				if (ident == TAG_IDENT_AVDP &&
 					location == last[i] - 256 - UDF_SB_SESSION(sb))
 				{
 					lastblock = last[i];
@@ -590,7 +590,7 @@
 						udf_release_data(bh);
 					}
 	
-					if (ident == TID_ANCHOR_VOL_DESC_PTR &&
+					if (ident == TAG_IDENT_AVDP &&
 						location == udf_variable_to_fixed(last[i]) - 256)
 					{
 						UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
@@ -611,7 +611,7 @@
 			location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
 			udf_release_data(bh);
 
-			if (ident == TID_ANCHOR_VOL_DESC_PTR && location == 256)
+			if (ident == TAG_IDENT_AVDP && location == 256)
 				UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
 		}
 	}
@@ -628,8 +628,8 @@
 			else
 			{
 				udf_release_data(bh);
-				if ((ident != TID_ANCHOR_VOL_DESC_PTR) && (i ||
-					(ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY)))
+				if ((ident != TAG_IDENT_AVDP) && (i ||
+					(ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE)))
 				{
 					UDF_SB_ANCHOR(sb)[i] = 0;
 				}
@@ -645,7 +645,7 @@
 {
 	struct buffer_head *bh = NULL;
 	long lastblock;
-	Uint16 ident;
+	uint16_t ident;
 
 	if (fileset->logicalBlockNum != 0xFFFFFFFF ||
 		fileset->partitionReferenceNum != 0xFFFF)
@@ -654,7 +654,7 @@
 
 		if (!bh)
 			return 1;
-		else if (ident != TID_FILE_SET_DESC)
+		else if (ident != TAG_IDENT_FSD)
 		{
 			udf_release_data(bh);
 			return 1;
@@ -688,17 +688,17 @@
 
 				switch (ident)
 				{
-					case TID_SPACE_BITMAP_DESC:
+					case TAG_IDENT_SBD:
 					{
-						struct SpaceBitmapDesc *sp;
-						sp = (struct SpaceBitmapDesc *)bh->b_data;
+						struct spaceBitmapDesc *sp;
+						sp = (struct spaceBitmapDesc *)bh->b_data;
 						newfileset.logicalBlockNum += 1 +
-							((le32_to_cpu(sp->numOfBytes) + sizeof(struct SpaceBitmapDesc) - 1)
+							((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1)
 								>> sb->s_blocksize_bits);
 						udf_release_data(bh);
 						break;
 					}
-					case TID_FILE_SET_DESC:
+					case TAG_IDENT_FSD:
 					{
 						*fileset = newfileset;
 						break;
@@ -735,13 +735,13 @@
 static void 
 udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
 {
-	struct PrimaryVolDesc *pvoldesc;
+	struct primaryVolDesc *pvoldesc;
 	time_t recording;
 	long recording_usec;
 	struct ustr instr;
 	struct ustr outstr;
 
-	pvoldesc = (struct PrimaryVolDesc *)bh->b_data;
+	pvoldesc = (struct primaryVolDesc *)bh->b_data;
 
 	if ( udf_stamp_to_time(&recording, &recording_usec,
 		lets_to_cpu(pvoldesc->recordingDateAndTime)) )
@@ -774,9 +774,9 @@
 static void 
 udf_load_fileset(struct super_block *sb, struct buffer_head *bh, lb_addr *root)
 {
-	struct FileSetDesc *fset;
+	struct fileSetDesc *fset;
 
-	fset = (struct FileSetDesc *)bh->b_data;
+	fset = (struct fileSetDesc *)bh->b_data;
 
 	*root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
 
@@ -789,10 +789,10 @@
 static void 
 udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
 {
-	struct PartitionDesc *p;
+	struct partitionDesc *p;
 	int i;
 
-	p = (struct PartitionDesc *)bh->b_data;
+	p = (struct partitionDesc *)bh->b_data;
 
 	for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
 	{
@@ -802,34 +802,42 @@
 		{
 			UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */
 			UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation) + UDF_SB_SESSION(sb);
-
-			if (!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR02) ||
-				!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR03))
+			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY)
+				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY;
+			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE)
+				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_WRITE_ONCE;
+			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_REWRITABLE)
+				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_REWRITABLE;
+			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_OVERWRITABLE)
+				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_OVERWRITABLE;
+
+			if (!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) ||
+				!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
 			{
-				struct PartitionHeaderDesc *phd;
+				struct partitionHeaderDesc *phd;
 
-				phd = (struct PartitionHeaderDesc *)(p->partitionContentsUse);
-				if (phd->unallocatedSpaceTable.extLength)
+				phd = (struct partitionHeaderDesc *)(p->partitionContentsUse);
+				if (phd->unallocSpaceTable.extLength)
 				{
-					lb_addr loc = { le32_to_cpu(phd->unallocatedSpaceTable.extPosition), i };
+					lb_addr loc = { le32_to_cpu(phd->unallocSpaceTable.extPosition), i };
 
 					UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
 						udf_iget(sb, loc);
 					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
-					udf_debug("unallocatedSpaceTable (part %d) @ %ld\n",
+					udf_debug("unallocSpaceTable (part %d) @ %ld\n",
 						i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);
 				}
-				if (phd->unallocatedSpaceBitmap.extLength)
+				if (phd->unallocSpaceBitmap.extLength)
 				{
 					UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);
 					if (UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap != NULL)
 					{
 						UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength =
-							le32_to_cpu(phd->unallocatedSpaceBitmap.extLength);
+							le32_to_cpu(phd->unallocSpaceBitmap.extLength);
 						UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition =
-							le32_to_cpu(phd->unallocatedSpaceBitmap.extPosition);
+							le32_to_cpu(phd->unallocSpaceBitmap.extPosition);
 						UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;
-						udf_debug("unallocatedSpaceBitmap (part %d) @ %d\n",
+						udf_debug("unallocSpaceBitmap (part %d) @ %d\n",
 							i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition);
 					}
 				}
@@ -878,22 +886,22 @@
 static int 
 udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fileset)
 {
-	struct LogicalVolDesc *lvd;
+	struct logicalVolDesc *lvd;
 	int i, j, offset;
-	Uint8 type;
+	uint8_t type;
 
-	lvd = (struct LogicalVolDesc *)bh->b_data;
+	lvd = (struct logicalVolDesc *)bh->b_data;
 
 	UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
 
 	for (i=0,offset=0;
 		 i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength);
-		 i++,offset+=((struct GenericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength)
+		 i++,offset+=((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength)
 	{
-		type = ((struct GenericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;
+		type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;
 		if (type == 1)
 		{
-			struct GenericPartitionMap1 *gpm1 = (struct GenericPartitionMap1 *)&(lvd->partitionMaps[offset]);
+			struct genericPartitionMap1 *gpm1 = (struct genericPartitionMap1 *)&(lvd->partitionMaps[offset]);
 			UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15;
 			UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum);
 			UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum);
@@ -901,15 +909,15 @@
 		}
 		else if (type == 2)
 		{
-			struct UdfPartitionMap2 *upm2 = (struct UdfPartitionMap2 *)&(lvd->partitionMaps[offset]);
+			struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)&(lvd->partitionMaps[offset]);
 			if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)))
 			{
-				if (le16_to_cpu(((Uint16 *)upm2->partIdent.identSuffix)[0]) == 0x0150)
+				if (le16_to_cpu(((uint16_t *)upm2->partIdent.identSuffix)[0]) == 0x0150)
 				{
 					UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;
 					UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;
 				}
-				else if (le16_to_cpu(((Uint16 *)upm2->partIdent.identSuffix)[0]) == 0x0200)
+				else if (le16_to_cpu(((uint16_t *)upm2->partIdent.identSuffix)[0]) == 0x0200)
 				{
 					UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;
 					UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;
@@ -917,10 +925,10 @@
 			}
 			else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)))
 			{
-				Uint32 loc;
-				Uint16 ident;
-				struct SparingTable *st;
-				struct SparablePartitionMap *spm = (struct SparablePartitionMap *)&(lvd->partitionMaps[offset]);
+				uint32_t loc;
+				uint16_t ident;
+				struct sparingTable *st;
+				struct sparablePartitionMap *spm = (struct sparablePartitionMap *)&(lvd->partitionMaps[offset]);
 
 				UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;
 				UDF_SB_TYPESPAR(sb,i).s_packet_len = le16_to_cpu(spm->packetLength);
@@ -931,7 +939,7 @@
 						udf_read_tagged(sb, loc, loc, &ident);
 					if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
 					{
-						st = (struct SparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data;
+						st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data;
 						if (ident != 0 ||
 							strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
 						{
@@ -976,12 +984,12 @@
 udf_load_logicalvolint(struct super_block *sb, extent_ad loc)
 {
 	struct buffer_head *bh = NULL;
-	Uint16 ident;
+	uint16_t ident;
 
 	while (loc.extLength > 0 &&
 		(bh = udf_read_tagged(sb, loc.extLocation,
 			loc.extLocation, &ident)) &&
-		ident == TID_LOGICAL_VOL_INTEGRITY_DESC)
+		ident == TAG_IDENT_LVID)
 	{
 		UDF_SB_LVIDBH(sb) = bh;
 		
@@ -1017,12 +1025,12 @@
 {
 	struct buffer_head *bh = NULL;
 	struct udf_vds_record vds[VDS_POS_LENGTH];
-	struct GenericDesc *gd;
-	struct VolDescPtr *vdp;
+	struct generic_desc *gd;
+	struct volDescPtr *vdp;
 	int done=0;
 	int i,j;
-	Uint32 vdsn;
-	Uint16 ident;
+	uint32_t vdsn;
+	uint16_t ident;
 	long next_s = 0, next_e = 0;
 
 	memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
@@ -1036,56 +1044,56 @@
 			break;
 
 		/* Process each descriptor (ISO 13346 3/8.3-8.4) */
-		gd = (struct GenericDesc *)bh->b_data;
+		gd = (struct generic_desc *)bh->b_data;
 		vdsn = le32_to_cpu(gd->volDescSeqNum);
 		switch (ident)
 		{
-			case TID_PRIMARY_VOL_DESC: /* ISO 13346 3/10.1 */
+			case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
 				if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum)
 				{
 					vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn;
 					vds[VDS_POS_PRIMARY_VOL_DESC].block = block;
 				}
 				break;
-			case TID_VOL_DESC_PTR: /* ISO 13346 3/10.3 */
+			case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
 				if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum)
 				{
 					vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
 					vds[VDS_POS_VOL_DESC_PTR].block = block;
 
-					vdp = (struct VolDescPtr *)bh->b_data;
+					vdp = (struct volDescPtr *)bh->b_data;
 					next_s = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
 					next_e = le32_to_cpu(vdp->nextVolDescSeqExt.extLength);
 					next_e = next_e >> sb->s_blocksize_bits;
 					next_e += next_s;
 				}
 				break;
-			case TID_IMP_USE_VOL_DESC: /* ISO 13346 3/10.4 */
+			case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
 				if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum)
 				{
 					vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn;
 					vds[VDS_POS_IMP_USE_VOL_DESC].block = block;
 				}
 				break;
-			case TID_PARTITION_DESC: /* ISO 13346 3/10.5 */
+			case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
 				if (!vds[VDS_POS_PARTITION_DESC].block)
 					vds[VDS_POS_PARTITION_DESC].block = block;
 				break;
-			case TID_LOGICAL_VOL_DESC: /* ISO 13346 3/10.6 */
+			case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
 				if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum)
 				{
 					vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn;
 					vds[VDS_POS_LOGICAL_VOL_DESC].block = block;
 				}
 				break;
-			case TID_UNALLOC_SPACE_DESC: /* ISO 13346 3/10.8 */
+			case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
 				if (vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum)
 				{
 					vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn;
 					vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;
 				}
 				break;
-			case TID_TERMINATING_DESC: /* ISO 13346 3/10.9 */
+			case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
 				vds[VDS_POS_TERMINATING_DESC].block = block;
 				if (next_e)
 				{
@@ -1116,8 +1124,8 @@
 				for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++)
 				{
 					bh2 = udf_read_tagged(sb, j, j, &ident);
-					gd = (struct GenericDesc *)bh2->b_data;
-					if (ident == TID_PARTITION_DESC)
+					gd = (struct generic_desc *)bh2->b_data;
+					if (ident == TAG_IDENT_PD)
 						udf_load_partdesc(sb, bh2);
 					udf_release_data(bh2);
 				}
@@ -1158,8 +1166,8 @@
 static int
 udf_load_partition(struct super_block *sb, lb_addr *fileset)
 {
-	struct AnchorVolDescPtr *anchor;
-	Uint16 ident;
+	struct anchorVolDescPtr *anchor;
+	uint16_t ident;
 	struct buffer_head *bh;
 	long main_s, main_e, reserve_s, reserve_e;
 	int i, j;
@@ -1172,7 +1180,7 @@
 		if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
 			UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
 		{
-			anchor = (struct AnchorVolDescPtr *)bh->b_data;
+			anchor = (struct anchorVolDescPtr *)bh->b_data;
 
 			/* Locate the main sequence */
 			main_s = le32_to_cpu( anchor->mainVolDescSeqExt.extLocation );
@@ -1254,12 +1262,12 @@
 				else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20)
 				{
 					struct buffer_head *bh = NULL;
-					Uint32 pos;
+					uint32_t pos;
 
 					pos = udf_block_map(UDF_SB_VAT(sb), 0);
 					bh = sb_bread(sb, pos);
 					UDF_SB_TYPEVIRT(sb,i).s_start_offset =
-						le16_to_cpu(((struct VirtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
+						le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
 							udf_ext0_offset(UDF_SB_VAT(sb));
 					UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
 						UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
@@ -1284,7 +1292,7 @@
 		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
 		if (udf_time_to_stamp(&cpu_time, CURRENT_TIME, CURRENT_UTIME))
 			UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
-		UDF_SB_LVID(sb)->integrityType = INTEGRITY_TYPE_OPEN;
+		UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;
 
 		UDF_SB_LVID(sb)->descTag.descCRC =
 			cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
@@ -1294,7 +1302,7 @@
 		for (i=0; i<16; i++)
 			if (i != 4)
 				UDF_SB_LVID(sb)->descTag.tagChecksum +=
-					((Uint8 *)&(UDF_SB_LVID(sb)->descTag))[i];
+					((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
 
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
 	}
@@ -1303,7 +1311,7 @@
 static void udf_close_lvid(struct super_block *sb)
 {
 	if (UDF_SB_LVIDBH(sb) &&
-		UDF_SB_LVID(sb)->integrityType == INTEGRITY_TYPE_OPEN)
+		UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN)
 	{
 		int i;
 		timestamp cpu_time;
@@ -1318,7 +1326,7 @@
 			UDF_SB_LVIDIU(sb)->minUDFReadRev = cpu_to_le16(UDF_SB_UDFREV(sb));
 		if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
 			UDF_SB_LVIDIU(sb)->minUDFWriteRev = cpu_to_le16(UDF_SB_UDFREV(sb));
-		UDF_SB_LVID(sb)->integrityType = INTEGRITY_TYPE_CLOSE;
+		UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_CLOSE;
 
 		UDF_SB_LVID(sb)->descTag.descCRC =
 			cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
@@ -1328,7 +1336,7 @@
 		for (i=0; i<16; i++)
 			if (i != 4)
 				UDF_SB_LVID(sb)->descTag.tagChecksum +=
-					((Uint8 *)&(UDF_SB_LVID(sb)->descTag))[i];
+					((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
 
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
 	}
@@ -1441,9 +1449,9 @@
 
 	if ( UDF_SB_LVIDBH(sb) )
 	{
-		Uint16 minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
-		Uint16 minUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
-		/* Uint16 maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */
+		uint16_t minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
+		uint16_t minUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
+		/* uint16_t maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */
 
 		if (minUDFReadRev > UDF_MAX_READ_VERSION)
 		{
@@ -1507,7 +1515,7 @@
 		iput(inode);
 		goto error_out;
 	}
-	sb->s_maxbytes = ~0ULL;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	return sb;
 
 error_out:
@@ -1686,11 +1694,11 @@
 	int index;
 	int block = 0, newblock;
 	lb_addr loc;
-	Uint32 bytes;
-	Uint8 value;
-	Uint8 *ptr;
-	Uint16 ident;
-	struct SpaceBitmapDesc *bm;
+	uint32_t bytes;
+	uint8_t value;
+	uint8_t *ptr;
+	uint16_t ident;
+	struct spaceBitmapDesc *bm;
 
 	loc.logicalBlockNum = bitmap->s_extPosition;
 	loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
@@ -1701,17 +1709,17 @@
 		printk(KERN_ERR "udf: udf_count_free failed\n");
 		return 0;
 	}
-	else if (ident != TID_SPACE_BITMAP_DESC)
+	else if (ident != TAG_IDENT_SBD)
 	{
 		udf_release_data(bh);
 		printk(KERN_ERR "udf: udf_count_free failed\n");
 		return 0;
 	}
 
-	bm = (struct SpaceBitmapDesc *)bh->b_data;
+	bm = (struct spaceBitmapDesc *)bh->b_data;
 	bytes = bm->numOfBytes;
-	index = sizeof(struct SpaceBitmapDesc); /* offset in first block only */
-	ptr = (Uint8 *)bh->b_data;
+	index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
+	ptr = (uint8_t *)bh->b_data;
 
 	while ( bytes > 0 )
 	{
@@ -1734,7 +1742,7 @@
 				return accum;
 			}
 			index = 0;
-			ptr = (Uint8 *)bh->b_data;
+			ptr = (uint8_t *)bh->b_data;
 		}
 	}
 	udf_release_data(bh);
@@ -1745,13 +1753,13 @@
 udf_count_free_table(struct super_block *sb, struct inode * table)
 {
 	unsigned int accum = 0;
-	Uint32 extoffset, elen;
+	uint32_t extoffset, elen;
 	lb_addr bloc, eloc;
-	Sint8 etype;
+	int8_t etype;
 	struct buffer_head *bh = NULL;
 
 	bloc = UDF_I_LOCATION(table);
-	extoffset = sizeof(struct UnallocatedSpaceEntry);
+	extoffset = sizeof(struct unallocSpaceEntry);
 
 	while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
 	{
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/symlink.c linux/fs/udf/symlink.c
--- linux.orig/fs/udf/symlink.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/symlink.c	2002-07-20 01:08:29.000000000 +0000
@@ -15,7 +15,7 @@
  *		ftp://prep.ai.mit.edu/pub/gnu/GPL
  *	Each contributing author retains all rights to their own work.
  *
- *  (C) 1998-2000 Ben Fennema
+ *  (C) 1998-2001 Ben Fennema
  *  (C) 1999 Stelias Computing Inc 
  *
  * HISTORY
@@ -39,13 +39,13 @@
 
 static void udf_pc_to_char(char *from, int fromlen, char *to)
 {
-	struct PathComponent *pc;
+	struct pathComponent *pc;
 	int elen = 0;
 	char *p = to;
 
 	while (elen < fromlen)
 	{
-		pc = (struct PathComponent *)(from + elen);
+		pc = (struct pathComponent *)(from + elen);
 		switch (pc->componentType)
 		{
 			case 1:
@@ -69,7 +69,7 @@
 				p += pc->lengthComponentIdent;
 				*p++ = '/';
 		}
-		elen += sizeof(struct PathComponent) + pc->lengthComponentIdent;
+		elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
 	}
 	if (p > to+1)
 		p[-1] = '\0';
@@ -86,7 +86,7 @@
 	char *p = kmap(page);
 	
 	lock_kernel();
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 	{
 		bh = udf_tread(inode->i_sb, inode->i_ino);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/truncate.c linux/fs/udf/truncate.c
--- linux.orig/fs/udf/truncate.c	2001-10-11 15:59:24.000000000 +0000
+++ linux/fs/udf/truncate.c	2002-07-20 01:08:33.000000000 +0000
@@ -15,7 +15,7 @@
  *		ftp://prep.ai.mit.edu/pub/gnu/GPL
  *	Each contributing author retains all rights to their own work.
  *
- *  (C) 1999-2000 Ben Fennema
+ *  (C) 1999-2001 Ben Fennema
  *  (C) 1999 Stelias Computing Inc
  *
  * HISTORY
@@ -33,7 +33,7 @@
 #include "udf_sb.h"
 
 static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
-	lb_addr eloc, Sint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
+	lb_addr eloc, int8_t etype, uint32_t elen, struct buffer_head *bh, uint32_t nelen)
 {
 	lb_addr neloc = { 0, 0 };
 	int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
@@ -41,7 +41,13 @@
 
 	if (nelen)
 	{
-		neloc = eloc;
+		if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
+		{
+			udf_free_blocks(inode->i_sb, inode, eloc, 0, last_block);
+			etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30);
+		}
+		else
+			neloc = eloc;
 		nelen = (etype << 30) | nelen;
 	}
 
@@ -50,10 +56,10 @@
 		udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
 		if (last_block - first_block > 0)
 		{
-			if (etype == EXTENT_RECORDED_ALLOCATED)
+			if (etype == (EXT_RECORDED_ALLOCATED >> 30))
 				mark_inode_dirty(inode);
 
-			if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
+			if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
 				udf_free_blocks(inode->i_sb, inode, eloc, first_block, last_block - first_block);
 		}
 	}
@@ -62,15 +68,15 @@
 void udf_truncate_extents(struct inode * inode)
 {
 	lb_addr bloc, eloc, neloc = { 0, 0 };
-	Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
-	Sint8 etype;
+	uint32_t extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
+	int8_t etype;
 	int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
 	struct buffer_head *bh = NULL;
 	int adsize;
 
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
-	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
+	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
 		adsize = sizeof(long_ad);
 	else
 		adsize = 0;
@@ -91,11 +97,11 @@
 		if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
 			lenalloc -= udf_file_entry_alloc_offset(inode);
 		else
-			lenalloc -= sizeof(struct AllocExtDesc);
+			lenalloc -= sizeof(struct allocExtDesc);
 
 		while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1)
 		{
-			if (etype == EXTENT_NEXT_EXTENT_ALLOCDECS)
+			if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
 			{
 				udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
 				extoffset = 0;
@@ -104,7 +110,7 @@
 					if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
 						memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
 					else
-						memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
+						memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
 					udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
 				}
 				else
@@ -116,13 +122,13 @@
 					}
 					else
 					{
-						struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh->b_data);
+						struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
 						aed->lengthAllocDescs = cpu_to_le32(lenalloc);
 						if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
 							udf_update_tag(bh->b_data, lenalloc +
-								sizeof(struct AllocExtDesc));
+								sizeof(struct allocExtDesc));
 						else
-							udf_update_tag(bh->b_data, sizeof(struct AllocExtDesc));
+							udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
 						mark_buffer_dirty_inode(bh, inode);
 					}
 				}
@@ -149,7 +155,7 @@
 			if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
 				memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
 			else
-				memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
+				memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
 			udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
 		}
 		else
@@ -161,13 +167,13 @@
 			}
 			else
 			{
-				struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh->b_data);
+				struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
 				aed->lengthAllocDescs = cpu_to_le32(lenalloc);
 				if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
 					udf_update_tag(bh->b_data, lenalloc +
-						sizeof(struct AllocExtDesc));
+						sizeof(struct allocExtDesc));
 				else
-					udf_update_tag(bh->b_data, sizeof(struct AllocExtDesc));
+					udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
 				mark_buffer_dirty_inode(bh, inode);
 			}
 		}
@@ -178,17 +184,17 @@
 		{
 			extoffset -= adsize;
 			etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
-			if (etype == EXTENT_NOT_RECORDED_NOT_ALLOCATED)
+			if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
 			{
 				extoffset -= adsize;
-				elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) | (elen + offset);
+				elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
 				udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
 			}
-			else if (etype == EXTENT_NOT_RECORDED_ALLOCATED)
+			else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
 			{
 				lb_addr neloc = { 0, 0 };
 				extoffset -= adsize;
-				nelen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
+				nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
 					((elen + offset + inode->i_sb->s_blocksize - 1) &
 					~(inode->i_sb->s_blocksize - 1));
 				udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
@@ -199,13 +205,13 @@
 				if (elen & (inode->i_sb->s_blocksize - 1))
 				{
 					extoffset -= adsize;
-					elen = (EXTENT_RECORDED_ALLOCATED << 30) |
+					elen = EXT_RECORDED_ALLOCATED |
 						((elen + inode->i_sb->s_blocksize - 1) &
 						~(inode->i_sb->s_blocksize - 1));
 					udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
 				}
 				memset(&eloc, 0x00, sizeof(lb_addr));
-				elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) | offset;
+				elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
 				udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
 			}
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/udf_i.h linux/fs/udf/udf_i.h
--- linux.orig/fs/udf/udf_i.h	2001-07-02 21:10:02.000000000 +0000
+++ linux/fs/udf/udf_i.h	2002-07-20 01:08:24.000000000 +0000
@@ -9,7 +9,7 @@
 #define UDF_I_LENEXTENTS(X)	( UDF_I(X)->i_lenExtents )
 #define UDF_I_UNIQUE(X)		( UDF_I(X)->i_unique )
 #define UDF_I_ALLOCTYPE(X)	( UDF_I(X)->i_alloc_type )
-#define UDF_I_EXTENDED_FE(X)( UDF_I(X)->i_extended_fe )
+#define UDF_I_EXTENDED_FE(X)	( UDF_I(X)->i_extended_fe )
 #define UDF_I_STRAT4096(X)	( UDF_I(X)->i_strat_4096 )
 #define UDF_I_NEW_INODE(X)	( UDF_I(X)->i_new_inode )
 #define UDF_I_NEXT_ALLOC_BLOCK(X)	( UDF_I(X)->i_next_alloc_block )
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/udf_sb.h linux/fs/udf/udf_sb.h
--- linux.orig/fs/udf/udf_sb.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/fs/udf/udf_sb.h	2002-07-20 01:08:30.000000000 +0000
@@ -25,6 +25,10 @@
 #define UDF_PART_FLAG_UNALLOC_TABLE	0x0002
 #define UDF_PART_FLAG_FREED_BITMAP	0x0004
 #define UDF_PART_FLAG_FREED_TABLE	0x0008
+#define UDF_PART_FLAG_READ_ONLY		0x0010
+#define UDF_PART_FLAG_WRITE_ONCE	0x0020
+#define UDF_PART_FLAG_REWRITABLE	0x0040
+#define UDF_PART_FLAG_OVERWRITABLE	0x0080
 
 #define UDF_SB_FREE(X)\
 {\
@@ -54,7 +58,7 @@
 
 #define UDF_SB_ALLOC_BITMAP(X,Y,Z)\
 {\
-	int nr_groups = ((UDF_SB_PARTLEN((X),(Y)) + (sizeof(struct SpaceBitmapDesc) << 3) +\
+	int nr_groups = ((UDF_SB_PARTLEN((X),(Y)) + (sizeof(struct spaceBitmapDesc) << 3) +\
 		((X)->s_blocksize * 8) - 1) / ((X)->s_blocksize * 8));\
 	UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap = kmalloc(sizeof(struct udf_bitmap) +\
 		sizeof(struct buffer_head *) * nr_groups,\
@@ -74,18 +78,18 @@
 }
 
 
-#define UDF_QUERY_FLAG(X,Y)				( UDF_SB(X)->s_flags & ( 1 << (Y) ) )
-#define UDF_SET_FLAG(X,Y)				( UDF_SB(X)->s_flags |= ( 1 << (Y) ) )
-#define UDF_CLEAR_FLAG(X,Y)				( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) )
+#define UDF_QUERY_FLAG(X,Y)			( UDF_SB(X)->s_flags & ( 1 << (Y) ) )
+#define UDF_SET_FLAG(X,Y)			( UDF_SB(X)->s_flags |= ( 1 << (Y) ) )
+#define UDF_CLEAR_FLAG(X,Y)			( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) )
 
 #define UDF_UPDATE_UDFREV(X,Y)			( ((Y) > UDF_SB_UDFREV(X)) ? UDF_SB_UDFREV(X) = (Y) : UDF_SB_UDFREV(X) )
 
-#define UDF_SB_PARTMAPS(X)				( UDF_SB(X)->s_partmaps )
+#define UDF_SB_PARTMAPS(X)			( UDF_SB(X)->s_partmaps )
 #define UDF_SB_PARTTYPE(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_partition_type )
 #define UDF_SB_PARTROOT(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_partition_root )
-#define UDF_SB_PARTLEN(X,Y)				( UDF_SB_PARTMAPS(X)[(Y)].s_partition_len )
-#define UDF_SB_PARTVSN(X,Y)				( UDF_SB_PARTMAPS(X)[(Y)].s_volumeseqnum )
-#define UDF_SB_PARTNUM(X,Y)				( UDF_SB_PARTMAPS(X)[(Y)].s_partition_num )
+#define UDF_SB_PARTLEN(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_partition_len )
+#define UDF_SB_PARTVSN(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_volumeseqnum )
+#define UDF_SB_PARTNUM(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_partition_num )
 #define UDF_SB_TYPESPAR(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_type_specific.s_sparing )
 #define UDF_SB_TYPEVIRT(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_type_specific.s_virtual )
 #define UDF_SB_PARTFUNC(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_partition_func )
@@ -93,23 +97,23 @@
 #define UDF_SB_BITMAP(X,Y,Z,I)			( UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_block_bitmap[I] )
 #define UDF_SB_BITMAP_NR_GROUPS(X,Y,Z)	( UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_nr_groups )
 
-#define UDF_SB_VOLIDENT(X)				( UDF_SB(X)->s_volident )
-#define UDF_SB_NUMPARTS(X)				( UDF_SB(X)->s_partitions )
-#define UDF_SB_PARTITION(X)				( UDF_SB(X)->s_partition )
-#define UDF_SB_SESSION(X)				( UDF_SB(X)->s_session )
-#define UDF_SB_ANCHOR(X)				( UDF_SB(X)->s_anchor )
-#define UDF_SB_LASTBLOCK(X)				( UDF_SB(X)->s_lastblock )
-#define UDF_SB_LVIDBH(X)				( UDF_SB(X)->s_lvidbh )
-#define UDF_SB_LVID(X)					( (struct LogicalVolIntegrityDesc *)UDF_SB_LVIDBH(X)->b_data )
-#define UDF_SB_LVIDIU(X)				( (struct LogicalVolIntegrityDescImpUse *)&(UDF_SB_LVID(X)->impUse[UDF_SB_LVID(X)->numOfPartitions * 2 * sizeof(Uint32)/sizeof(Uint8)]) )
-
-#define UDF_SB_UMASK(X)					( UDF_SB(X)->s_umask )
-#define UDF_SB_GID(X)					( UDF_SB(X)->s_gid )
-#define UDF_SB_UID(X)					( UDF_SB(X)->s_uid )
+#define UDF_SB_VOLIDENT(X)			( UDF_SB(X)->s_volident )
+#define UDF_SB_NUMPARTS(X)			( UDF_SB(X)->s_partitions )
+#define UDF_SB_PARTITION(X)			( UDF_SB(X)->s_partition )
+#define UDF_SB_SESSION(X)			( UDF_SB(X)->s_session )
+#define UDF_SB_ANCHOR(X)			( UDF_SB(X)->s_anchor )
+#define UDF_SB_LASTBLOCK(X)			( UDF_SB(X)->s_lastblock )
+#define UDF_SB_LVIDBH(X)			( UDF_SB(X)->s_lvidbh )
+#define UDF_SB_LVID(X)				( (struct logicalVolIntegrityDesc *)UDF_SB_LVIDBH(X)->b_data )
+#define UDF_SB_LVIDIU(X)			( (struct logicalVolIntegrityDescImpUse *)&(UDF_SB_LVID(X)->impUse[le32_to_cpu(UDF_SB_LVID(X)->numOfPartitions) * 2 * sizeof(uint32_t)/sizeof(uint8_t)]) )
+
+#define UDF_SB_UMASK(X)				( UDF_SB(X)->s_umask )
+#define UDF_SB_GID(X)				( UDF_SB(X)->s_gid )
+#define UDF_SB_UID(X)				( UDF_SB(X)->s_uid )
 #define UDF_SB_RECORDTIME(X)			( UDF_SB(X)->s_recordtime )
-#define UDF_SB_SERIALNUM(X)				( UDF_SB(X)->s_serialnum )
-#define UDF_SB_UDFREV(X)				( UDF_SB(X)->s_udfrev )
-#define UDF_SB_FLAGS(X)					( UDF_SB(X)->s_flags )
-#define UDF_SB_VAT(X)					( UDF_SB(X)->s_vat )
+#define UDF_SB_SERIALNUM(X)			( UDF_SB(X)->s_serialnum )
+#define UDF_SB_UDFREV(X)			( UDF_SB(X)->s_udfrev )
+#define UDF_SB_FLAGS(X)				( UDF_SB(X)->s_flags )
+#define UDF_SB_VAT(X)				( UDF_SB(X)->s_vat )
 
 #endif /* __LINUX_UDF_SB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/udfdecl.h linux/fs/udf/udfdecl.h
--- linux.orig/fs/udf/udfdecl.h	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/udf/udfdecl.h	2002-07-20 01:08:34.000000000 +0000
@@ -1,50 +1,49 @@
 #ifndef __UDF_DECL_H
 #define __UDF_DECL_H
 
-#include <linux/udf_167.h>
-#include <linux/udf_udf.h>
-#include "udfend.h"
-
 #include <linux/udf_fs.h>
+#include "ecma_167.h"
+#include "osta_udf.h"
 
-#ifdef __KERNEL__
-
+#include <linux/fs.h>
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/fs.h>
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
 
 #if !defined(CONFIG_UDF_FS) && !defined(CONFIG_UDF_FS_MODULE)
 #define CONFIG_UDF_FS_MODULE
-#include <linux/udf_fs_sb.h>
 #include <linux/udf_fs_i.h>
+#include <linux/udf_fs_sb.h>
 #endif
 
+#include "udfend.h"
+
 #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) )
 #define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) )
 
+#define UDF_EXTENT_LENGTH_MASK	0x3FFFFFFF
+#define UDF_EXTENT_FLAG_MASK	0xC0000000
+
+#define UDF_NAME_PAD		4
+#define UDF_NAME_LEN		255
+#define UDF_PATH_LEN		1023
+
 #define CURRENT_UTIME	(xtime.tv_usec)
 
 #define udf_file_entry_alloc_offset(inode)\
 	((UDF_I_EXTENDED_FE(inode) ?\
-		sizeof(struct ExtendedFileEntry) :\
-		sizeof(struct FileEntry)) + UDF_I_LENEATTR(inode))
+		sizeof(struct extendedFileEntry) :\
+		sizeof(struct fileEntry)) + UDF_I_LENEATTR(inode))
 
 #define udf_ext0_offset(inode)\
-	(UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB ?\
+	(UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ?\
 		udf_file_entry_alloc_offset(inode) : 0)
 
 #define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset))
 
-#else
-
-#include <sys/types.h>
-
-#endif /* __KERNEL__ */
-
-
-
-#ifdef __KERNEL__
-
 struct dentry;
 struct inode;
 struct task_struct;
@@ -67,50 +66,38 @@
 	int eoffset;
 };
 
-#endif /* __KERNEL__ */
-
 struct udf_directory_record
 {
-	Uint32	d_parent;
-	Uint32	d_inode;
-	Uint32	d_name[255];
+	uint32_t	d_parent;
+	uint32_t	d_inode;
+	uint32_t	d_name[255];
 };
 
-
 struct udf_vds_record
 {
-	Uint32 block;
-	Uint32 volDescSeqNum;
+	uint32_t block;
+	uint32_t volDescSeqNum;
 };
 
-struct ktm
+struct generic_desc
 {
-	int tm_sec;
-	int tm_min;
-	int tm_hour;
-	int tm_mday;
-	int tm_mon;
-	int tm_year;
-	int tm_isdst;
+	tag		descTag;
+	uint32_t	volDescSeqNum;
 };
 
 struct ustr
 {
-	Uint8 u_cmpID;
-	Uint8 u_name[UDF_NAME_LEN];
-	Uint8 u_len;
-	Uint8 padding;
-	unsigned long u_hash;
+	uint8_t u_cmpID;
+	uint8_t u_name[UDF_NAME_LEN];
+	uint8_t u_len;
 };
 
-#ifdef __KERNEL__
-
 /* super.c */
 extern void udf_error(struct super_block *, const char *, const char *, ...);
 extern void udf_warning(struct super_block *, const char *, const char *, ...);
 
 /* namei.c */
-extern int udf_write_fi(struct inode *inode, struct FileIdentDesc *, struct FileIdentDesc *, struct udf_fileident_bh *, Uint8 *, Uint8 *);
+extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, struct fileIdentDesc *, struct udf_fileident_bh *, uint8_t *, uint8_t *);
 
 /* file.c */
 extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
@@ -128,24 +115,23 @@
 extern void udf_delete_inode(struct inode *);
 extern void udf_write_inode(struct inode *, int);
 extern long udf_block_map(struct inode *, long);
-extern Sint8 inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
-extern Sint8 udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
-extern Sint8 udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
-extern Sint8 udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
-extern Sint8 udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
-extern Sint8 udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
-extern Sint8 udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
+extern int8_t inode_bmap(struct inode *, int, lb_addr *, uint32_t *, lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
+extern int8_t udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, uint32_t, struct buffer_head **, int);
+extern int8_t udf_write_aext(struct inode *, lb_addr, int *, lb_addr, uint32_t, struct buffer_head *, int);
+extern int8_t udf_insert_aext(struct inode *, lb_addr, int, lb_addr, uint32_t, struct buffer_head *);
+extern int8_t udf_delete_aext(struct inode *, lb_addr, int, lb_addr, uint32_t, struct buffer_head *);
+extern int8_t udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, uint32_t *, struct buffer_head **, int);
+extern int8_t udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, uint32_t *, struct buffer_head **, int);
 extern void udf_discard_prealloc(struct inode *);
 
 /* misc.c */
 extern int udf_read_tagged_data(char *, int size, int fd, int block, int partref);
 extern struct buffer_head *udf_tgetblk(struct super_block *, int);
 extern struct buffer_head *udf_tread(struct super_block *, int);
-extern struct GenericAttrFormat *udf_add_extendedattr(struct inode *, Uint32, Uint32, Uint8, struct buffer_head **);
-extern struct GenericAttrFormat *udf_get_extendedattr(struct inode *, Uint32, Uint8, struct buffer_head **);
-extern struct buffer_head *udf_read_tagged(struct super_block *, Uint32, Uint32, Uint16 *);
-extern struct buffer_head *udf_read_ptagged(struct super_block *, lb_addr, Uint32, Uint16 *);
-extern struct buffer_head *udf_read_untagged(struct super_block *, Uint32, Uint32);
+extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, uint32_t, uint8_t, struct buffer_head **);
+extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t, struct buffer_head **);
+extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *);
+extern struct buffer_head *udf_read_ptagged(struct super_block *, lb_addr, uint32_t, uint16_t *);
 extern void udf_release_data(struct buffer_head *);
 
 /* lowlevel.c */
@@ -153,14 +139,14 @@
 extern unsigned long udf_get_last_block(struct super_block *);
 
 /* partition.c */
-extern Uint32 udf_get_pblock(struct super_block *, Uint32, Uint16, Uint32);
-extern Uint32 udf_get_pblock_virt15(struct super_block *, Uint32, Uint16, Uint32);
-extern Uint32 udf_get_pblock_virt20(struct super_block *, Uint32, Uint16, Uint32);
-extern Uint32 udf_get_pblock_spar15(struct super_block *, Uint32, Uint16, Uint32);
+extern uint32_t udf_get_pblock(struct super_block *, uint32_t, uint16_t, uint32_t);
+extern uint32_t udf_get_pblock_virt15(struct super_block *, uint32_t, uint16_t, uint32_t);
+extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t, uint32_t);
+extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, uint32_t);
 extern int udf_relocate_blocks(struct super_block *, long, long *);
 
 /* unicode.c */
-extern int udf_get_filename(struct super_block *, Uint8 *, Uint8 *, int);
+extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
 
 /* ialloc.c */
 extern void udf_free_inode(struct inode *);
@@ -170,58 +156,51 @@
 extern void udf_truncate_extents(struct inode *);
 
 /* balloc.c */
-extern void udf_free_blocks(struct super_block *, struct inode *, lb_addr, Uint32, Uint32);
-extern int udf_prealloc_blocks(struct super_block *, struct inode *, Uint16, Uint32, Uint32);
-extern int udf_new_block(struct super_block *, struct inode *, Uint16, Uint32, int *);
+extern void udf_free_blocks(struct super_block *, struct inode *, lb_addr, uint32_t, uint32_t);
+extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t, uint32_t, uint32_t);
+extern int udf_new_block(struct super_block *, struct inode *, uint16_t, uint32_t, int *);
 
 /* fsync.c */
 extern int udf_fsync_file(struct file *, struct dentry *, int);
 extern int udf_fsync_inode(struct inode *, int);
 
 /* directory.c */
-extern Uint8 * udf_filead_read(struct inode *, Uint8 *, Uint8, lb_addr, int *, int *, struct buffer_head **, int *);
-extern struct FileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct FileIdentDesc *, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
-
-#endif /* __KERNEL__ */
-
-/* Miscellaneous UDF Prototypes */
+extern uint8_t * udf_filead_read(struct inode *, uint8_t *, uint8_t, lb_addr, int *, int *, struct buffer_head **, int *);
+extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, lb_addr *, uint32_t *, lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
 
 /* unicode.c */
-extern int udf_ustr_to_dchars(Uint8 *, const struct ustr *, int);
-extern int udf_ustr_to_char(Uint8 *, const struct ustr *, int);
+extern int udf_ustr_to_dchars(uint8_t *, const struct ustr *, int);
+extern int udf_ustr_to_char(uint8_t *, const struct ustr *, int);
 extern int udf_ustr_to_dstring(dstring *, const struct ustr *, int);
-extern int udf_dchars_to_ustr(struct ustr *, const Uint8 *, int);
-extern int udf_char_to_ustr(struct ustr *, const Uint8 *, int);
+extern int udf_dchars_to_ustr(struct ustr *, const uint8_t *, int);
+extern int udf_char_to_ustr(struct ustr *, const uint8_t *, int);
 extern int udf_dstring_to_ustr(struct ustr *, const dstring *, int);
-extern int udf_translate_to_linux(Uint8 *, Uint8 *, int, Uint8 *, int);
+extern int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
 extern int udf_build_ustr(struct ustr *, dstring *, int);
 extern int udf_build_ustr_exact(struct ustr *, dstring *, int);
 extern int udf_CS0toUTF8(struct ustr *, struct ustr *);
 extern int udf_UTF8toCS0(dstring *, struct ustr *, int);
-#ifdef __KERNEL__
 extern int udf_CS0toNLS(struct nls_table *, struct ustr *, struct ustr *);
 extern int udf_NLStoCS0(struct nls_table *, dstring *, struct ustr *, int);
-#endif
 
 /* crc.c */
-extern Uint16 udf_crc(Uint8 *, Uint32, Uint16);
+extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t);
 
 /* misc.c */
-extern Uint32 udf64_low32(Uint64);
-extern Uint32 udf64_high32(Uint64);
+extern uint32_t udf64_low32(uint64_t);
+extern uint32_t udf64_high32(uint64_t);
 extern void udf_update_tag(char *, int);
-extern void udf_new_tag(char *, Uint16, Uint16, Uint16, Uint32, int);
+extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
 
 /* udftime.c */
 extern time_t *udf_stamp_to_time(time_t *, long *, timestamp);
 extern timestamp *udf_time_to_stamp(timestamp *, time_t, long);
-extern time_t udf_converttime (struct ktm *);
 
 /* directory.c */
-extern struct FileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
+extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
 extern extent_ad * udf_get_fileextent(void * buffer, int bufsize, int * offset);
 extern long_ad * udf_get_filelongad(void * buffer, int bufsize, int * offset, int);
 extern short_ad * udf_get_fileshortad(void * buffer, int bufsize, int * offset, int);
-extern Uint8 * udf_get_filead(struct FileEntry *, Uint8 *, int, int, int, int *);
+extern uint8_t * udf_get_filead(struct fileEntry *, uint8_t *, int, int, int, int *);
 
 #endif /* __UDF_DECL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/udfend.h linux/fs/udf/udfend.h
--- linux.orig/fs/udf/udfend.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/fs/udf/udfend.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,60 +1,9 @@
 #ifndef __UDF_ENDIAN_H
 #define __UDF_ENDIAN_H
 
-#ifndef __KERNEL__ 
-
-#include <sys/types.h>
-
-#if __BYTE_ORDER == 0
-
-#error "__BYTE_ORDER must be defined"
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-#define le16_to_cpu(x) \
-	((Uint16)((((Uint16)(x) & 0x00FFU) << 8) | \
-		  (((Uint16)(x) & 0xFF00U) >> 8)))
- 
-#define le32_to_cpu(x) \
-	((Uint32)((((Uint32)(x) & 0x000000FFU) << 24) | \
-		  (((Uint32)(x) & 0x0000FF00U) <<  8) | \
-		  (((Uint32)(x) & 0x00FF0000U) >>  8) | \
-		  (((Uint32)(x) & 0xFF000000U) >> 24)))
-
-#define le64_to_cpu(x) \
-	((Uint64)((((Uint64)(x) & 0x00000000000000FFULL) << 56) | \
-		  (((Uint64)(x) & 0x000000000000FF00ULL) << 40) | \
-		  (((Uint64)(x) & 0x0000000000FF0000ULL) << 24) | \
-		  (((Uint64)(x) & 0x00000000FF000000ULL) <<  8) | \
-		  (((Uint64)(x) & 0x000000FF00000000ULL) >>  8) | \
-		  (((Uint64)(x) & 0x0000FF0000000000ULL) >> 24) | \
-		  (((Uint64)(x) & 0x00FF000000000000ULL) >> 40) | \
-		  (((Uint64)(x) & 0xFF00000000000000ULL) >> 56)))		
-
-#define cpu_to_le16(x) (le16_to_cpu(x))
-#define cpu_to_le32(x) (le32_to_cpu(x))
-#define cpu_to_le64(x) (le64_to_cpu(x))
-
-#else /* __BYTE_ORDER == __LITTLE_ENDIAN */
-
-#define le16_to_cpu(x) (x)
-#define le32_to_cpu(x) (x)
-#define le64_to_cpu(x) (x)
-#define cpu_to_le16(x) (x)
-#define cpu_to_le32(x) (x)
-#define cpu_to_le64(x) (x)
-
-#endif /* __BYTE_ORDER == 0 */
-
-#include <string.h>
-
-#else /* __KERNEL__ */
-
 #include <asm/byteorder.h>
 #include <linux/string.h>
 
-#endif /* ! __KERNEL__ */
-
 static inline lb_addr lelb_to_cpu(lb_addr in)
 {
 	lb_addr out;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/udftime.c linux/fs/udf/udftime.c
--- linux.orig/fs/udf/udftime.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/fs/udf/udftime.c	2002-07-20 01:08:37.000000000 +0000
@@ -32,15 +32,8 @@
  *  http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
  */
 
-#if defined(__linux__) && defined(__KERNEL__)
 #include <linux/types.h>
 #include <linux/kernel.h>
-#else
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#endif
-
 #include "udfdecl.h"
 
 #define EPOCH_YEAR 1970
@@ -86,9 +79,7 @@
 /*2038*/ SPY(68,17,0)
 };
 
-#ifdef __KERNEL__
 extern struct timezone sys_tz;
-#endif
 
 #define SECS_PER_HOUR	(60 * 60)
 #define SECS_PER_DAY	(SECS_PER_HOUR * 24)
@@ -97,8 +88,8 @@
 udf_stamp_to_time(time_t *dest, long *dest_usec, timestamp src)
 {
 	int yday;
-	Uint8 type = src.typeAndTimezone >> 12;
-	Sint16 offset;
+	uint8_t type = src.typeAndTimezone >> 12;
+	int16_t offset;
 
 	if (type == 1)
 	{
@@ -134,13 +125,8 @@
 {
 	long int days, rem, y;
 	const unsigned short int *ip;
-	Sint16 offset;
-#ifndef __KERNEL__
-	struct timeval tv;
-	struct timezone sys_tz;
+	int16_t offset;
 
-	gettimeofday(&tv, &sys_tz);
-#endif
 	offset = -sys_tz.tz_minuteswest;
 
 	if (!dest)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/udf/unicode.c linux/fs/udf/unicode.c
--- linux.orig/fs/udf/unicode.c	2001-06-12 02:15:27.000000000 +0000
+++ linux/fs/udf/unicode.c	2002-07-20 01:08:33.000000000 +0000
@@ -23,20 +23,16 @@
  *	Each contributing author retains all rights to their own work.
  */
 
+#include "udfdecl.h"
 
-#ifdef __KERNEL__
 #include <linux/kernel.h>
 #include <linux/string.h>	/* for memset */
 #include <linux/nls.h>
 #include <linux/udf_fs.h>
-#include "udf_sb.h"
-#else
-#include <string.h>
-#endif
 
-#include "udfdecl.h"
+#include "udf_sb.h"
 
-int udf_ustr_to_dchars(Uint8 *dest, const struct ustr *src, int strlen)
+int udf_ustr_to_dchars(uint8_t *dest, const struct ustr *src, int strlen)
 {
 	if ( (!dest) || (!src) || (!strlen) || (src->u_len > strlen) )
 		return 0;
@@ -45,7 +41,7 @@
 	return src->u_len + 1;
 }
 
-int udf_ustr_to_char(Uint8 *dest, const struct ustr *src, int strlen)
+int udf_ustr_to_char(uint8_t *dest, const struct ustr *src, int strlen)
 {
 	if ( (!dest) || (!src) || (!strlen) || (src->u_len >= strlen) )
 		return 0;
@@ -64,7 +60,7 @@
 		return 0;
 }
 
-int udf_dchars_to_ustr(struct ustr *dest, const Uint8 *src, int strlen)
+int udf_dchars_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
 {
 	if ( (!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN) )
 		return 0;
@@ -75,7 +71,7 @@
 	return strlen-1;
 }
 
-int udf_char_to_ustr(struct ustr *dest, const Uint8 *src, int strlen)
+int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
 {
 	if ( (!dest) || (!src) || (!strlen) || (strlen >= UDF_NAME_LEN) )
 		return 0;
@@ -152,9 +148,9 @@
  */
 int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
 {
-	Uint8 *ocu;
-	Uint32 c;
-	Uint8 cmp_id, ocu_len;
+	uint8_t *ocu;
+	uint32_t c;
+	uint8_t cmp_id, ocu_len;
 	int i;
 
 	ocu = ocu_i->u_name;
@@ -173,9 +169,7 @@
 
 	if ((cmp_id != 8) && (cmp_id != 16))
 	{
-#ifdef __KERNEL__
 		printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name);
-#endif
 		return 0;
 	}
 
@@ -189,22 +183,20 @@
 
 		/* Compress Unicode to UTF-8 */
 		if (c < 0x80U)
-			utf_o->u_name[utf_o->u_len++] = (Uint8)c;
+			utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
 		else if (c < 0x800U)
 		{
-			utf_o->u_name[utf_o->u_len++] = (Uint8)(0xc0 | (c >> 6));
-			utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | (c & 0x3f));
+			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xc0 | (c >> 6));
+			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f));
 		}
 		else
 		{
-			utf_o->u_name[utf_o->u_len++] = (Uint8)(0xe0 | (c >> 12));
-			utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | ((c >> 6) & 0x3f));
-			utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | (c & 0x3f));
+			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xe0 | (c >> 12));
+			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | ((c >> 6) & 0x3f));
+			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f));
 		}
 	}
 	utf_o->u_cmpID=8;
-	utf_o->u_hash=0L;
-	utf_o->padding=0;
 
 	return utf_o->u_len;
 }
@@ -247,7 +239,7 @@
 	utf_cnt = 0U;
 	for (i = 0U; i < utf->u_len; i++)
 	{
-		c = (Uint8)utf->u_name[i];
+		c = (uint8_t)utf->u_name[i];
 
 		/* Complete a multi-byte UTF-8 character */
 		if (utf_cnt)
@@ -301,7 +293,7 @@
 			if ( 0xffU == max_val )
 			{
 				max_val = 0xffffU;
-				ocu[0] = (Uint8)0x10U;
+				ocu[0] = (uint8_t)0x10U;
 				goto try_again;
 			}
 			goto error_out;
@@ -309,31 +301,28 @@
 
 		if (max_val == 0xffffU)
 		{
-			ocu[++u_len] = (Uint8)(utf_char >> 8);
+			ocu[++u_len] = (uint8_t)(utf_char >> 8);
 		}
-		ocu[++u_len] = (Uint8)(utf_char & 0xffU);
+		ocu[++u_len] = (uint8_t)(utf_char & 0xffU);
 	}
 
 
 	if (utf_cnt)
 	{
 error_out:
-#ifdef __KERNEL__
 		printk(KERN_ERR "udf: bad UTF-8 character\n");
-#endif
 		return 0;
 	}
 
-	ocu[length - 1] = (Uint8)u_len + 1;
+	ocu[length - 1] = (uint8_t)u_len + 1;
 	return u_len + 1;
 }
 
-#ifdef __KERNEL__
 int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i)
 {
-	Uint8 *ocu;
-	Uint32 c;
-	Uint8 cmp_id, ocu_len;
+	uint8_t *ocu;
+	uint32_t c;
+	uint8_t cmp_id, ocu_len;
 	int i;
 
 	ocu = ocu_i->u_name;
@@ -367,8 +356,6 @@
 			UDF_NAME_LEN - utf_o->u_len);
 	}
 	utf_o->u_cmpID=8;
-	utf_o->u_hash=0L;
-	utf_o->padding=0;
 
 	return utf_o->u_len;
 }
@@ -376,7 +363,7 @@
 int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length)
 {
 	unsigned len, i, max_val;
-	Uint16 uni_char;
+	uint16_t uni_char;
 	int uni_cnt;
 	int u_len = 0;
 
@@ -394,23 +381,23 @@
 		if (len == 2 && max_val == 0xff)
 		{
 			max_val = 0xffffU;
-			ocu[0] = (Uint8)0x10U;
+			ocu[0] = (uint8_t)0x10U;
 			goto try_again;
 		}
 		
 		if (max_val == 0xffffU)
 		{
-			ocu[++u_len] = (Uint8)(uni_char >> 8);
+			ocu[++u_len] = (uint8_t)(uni_char >> 8);
 			i++;
 		}
-		ocu[++u_len] = (Uint8)(uni_char & 0xffU);
+		ocu[++u_len] = (uint8_t)(uni_char & 0xffU);
 	}
 
-	ocu[length - 1] = (Uint8)u_len + 1;
+	ocu[length - 1] = (uint8_t)u_len + 1;
 	return u_len + 1;
 }
 
-int udf_get_filename(struct super_block *sb, Uint8 *sname, Uint8 *dname, int flen)
+int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, int flen)
 {
 	struct ustr filename, unifilename;
 	int len;
@@ -446,20 +433,19 @@
 	}
 	return 0;
 }
-#endif
 
 #define ILLEGAL_CHAR_MARK	'_'
 #define EXT_MARK			'.'
 #define CRC_MARK			'#'
 #define EXT_SIZE			5
 
-int udf_translate_to_linux(Uint8 *newName, Uint8 *udfName, int udfLen, Uint8 *fidName, int fidNameLen)
+int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen, uint8_t *fidName, int fidNameLen)
 {
 	int index, newIndex = 0, needsCRC = 0;	
 	int extIndex = 0, newExtIndex = 0, hasExt = 0;
 	unsigned short valueCRC;
-	Uint8 curr;
-	const Uint8 hexChar[] = "0123456789ABCDEF";
+	uint8_t curr;
+	const uint8_t hexChar[] = "0123456789ABCDEF";
 
 	if (udfName[0] == '.' && (udfLen == 1 ||
 		(udfLen == 2 && udfName[1] == '.')))
@@ -500,7 +486,7 @@
 	}
 	if (needsCRC)
 	{
-		Uint8 ext[EXT_SIZE];
+		uint8_t ext[EXT_SIZE];
 		int localExtIndex = 0;
 
 		if (hasExt)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/ufs/file.c linux/fs/ufs/file.c
--- linux.orig/fs/ufs/file.c	2001-08-13 00:37:53.000000000 +0000
+++ linux/fs/ufs/file.c	2002-07-20 01:08:30.000000000 +0000
@@ -37,43 +37,12 @@
 #include <linux/pagemap.h>
 
 /*
- * Make sure the offset never goes beyond the 32-bit mark..
- */
-static long long ufs_file_lseek(
-	struct file *file,
-	long long offset,
-	int origin )
-{
-	long long retval;
-	struct inode *inode = file->f_dentry->d_inode;
-
-	switch (origin) {
-		case 2:
-			offset += inode->i_size;
-			break;
-		case 1:
-			offset += file->f_pos;
-	}
-	retval = -EINVAL;
-	/* make sure the offset fits in 32 bits */
-	if (((unsigned long long) offset >> 32) == 0) {
-		if (offset != file->f_pos) {
-			file->f_pos = offset;
-			file->f_reada = 0;
-			file->f_version = ++event;
-		}
-		retval = offset;
-	}
-	return retval;
-}
-
-/*
  * We have mostly NULL's here: the current defaults are ok for
  * the ufs filesystem.
  */
  
 struct file_operations ufs_file_operations = {
-	llseek:		ufs_file_lseek,
+	llseek:		generic_file_llseek,
 	read:		generic_file_read,
 	write:		generic_file_write,
 	mmap:		generic_file_mmap,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/ufs/super.c linux/fs/ufs/super.c
--- linux.orig/fs/ufs/super.c	2002-02-25 19:38:09.000000000 +0000
+++ linux/fs/ufs/super.c	2002-07-20 01:08:21.000000000 +0000
@@ -597,7 +597,11 @@
 	}
 	
 again:	
-	set_blocksize (sb->s_dev, block_size);
+	if (set_blocksize (sb->s_dev, block_size)) {
+		printk(KERN_ERR "UFS: failed to set blocksize\n");
+		goto failed;
+	}
+
 	sb->s_blocksize = block_size;
 
 	/*
@@ -653,14 +657,34 @@
 	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
 	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
 
-	if (uspi->s_bsize != 4096 && uspi->s_bsize != 8192 
-	  && uspi->s_bsize != 32768) {
-		printk("ufs_read_super: fs_bsize %u != {4096, 8192, 32768}\n", uspi->s_bsize);
+	if (uspi->s_fsize & (uspi->s_fsize - 1)) {
+		printk(KERN_ERR "ufs_read_super: fragment size %u is not a power of 2\n",
+			uspi->s_fsize);
+		goto failed;
+	}
+	if (uspi->s_fsize < 512) {
+		printk(KERN_ERR "ufs_read_super: fragment size %u is too small\n",
+			uspi->s_fsize);
+		goto failed;
+	}
+	if (uspi->s_fsize > 4096) {
+		printk(KERN_ERR "ufs_read_super: fragment size %u is too large\n",
+			uspi->s_fsize);
+		goto failed;
+	}
+	if (uspi->s_bsize & (uspi->s_bsize - 1)) {
+		printk(KERN_ERR "ufs_read_super: block size %u is not a power of 2\n",
+			uspi->s_bsize);
+		goto failed;
+	}
+	if (uspi->s_bsize < 4096) {
+		printk(KERN_ERR "ufs_read_super: block size %u is too small\n",
+			uspi->s_bsize);
 		goto failed;
 	}
-	if (uspi->s_fsize != 512 && uspi->s_fsize != 1024 
-	  && uspi->s_fsize != 2048 && uspi->s_fsize != 4096) {
-		printk("ufs_read_super: fs_fsize %u != {512, 1024, 2048. 4096}\n", uspi->s_fsize);
+	if (uspi->s_bsize / uspi->s_fsize > 8) {
+		printk(KERN_ERR "ufs_read_super: too many fragments per block (%u)\n",
+			uspi->s_bsize / uspi->s_fsize);
 		goto failed;
 	}
 	if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/vfat/namei.c linux/fs/vfat/namei.c
--- linux.orig/fs/vfat/namei.c	2001-10-25 07:02:26.000000000 +0000
+++ linux/fs/vfat/namei.c	2002-07-20 01:08:25.000000000 +0000
@@ -446,7 +446,7 @@
 	(x)->lower = 1;				\
 	(x)->upper = 1;				\
 	(x)->valid = 1;				\
-} while (0);
+} while (0)
 
 static inline unsigned char
 shortname_info_to_lcase(struct shortname_info *base,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/a.out.h linux/include/asm-alpha/a.out.h
--- linux.orig/include/asm-alpha/a.out.h	2001-11-03 01:39:20.000000000 +0000
+++ linux/include/asm-alpha/a.out.h	2002-07-20 01:08:27.000000000 +0000
@@ -95,8 +95,8 @@
    Worse, we have to notice the start address before swapping to use
    /sbin/loader, which of course is _not_ a TASO application.  */
 #define SET_AOUT_PERSONALITY(BFPM, EX) \
-	set_personality (BFPM->sh_bang || EX.ah.entry < 0x100000000 \
-			 ? PER_LINUX_32BIT : PER_LINUX)
+	set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
+			   ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
 
 #define STACK_TOP \
   (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/core_tsunami.h linux/include/asm-alpha/core_tsunami.h
--- linux.orig/include/asm-alpha/core_tsunami.h	2001-11-09 21:45:35.000000000 +0000
+++ linux/include/asm-alpha/core_tsunami.h	2002-07-20 01:08:26.000000000 +0000
@@ -288,7 +288,7 @@
 #ifdef __KERNEL__
 
 #ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
+#define __EXTERN_INLINE static inline
 #define __IO_EXTERN_INLINE
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/core_wildfire.h linux/include/asm-alpha/core_wildfire.h
--- linux.orig/include/asm-alpha/core_wildfire.h	2001-11-09 21:45:35.000000000 +0000
+++ linux/include/asm-alpha/core_wildfire.h	2002-07-20 01:08:25.000000000 +0000
@@ -269,7 +269,7 @@
 #ifdef __KERNEL__
 
 #ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
+#define __EXTERN_INLINE static inline
 #define __IO_EXTERN_INLINE
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/ide.h linux/include/asm-alpha/ide.h
--- linux.orig/include/asm-alpha/ide.h	2000-05-24 15:40:41.000000000 +0000
+++ linux/include/asm-alpha/ide.h	2002-07-20 01:08:31.000000000 +0000
@@ -91,7 +91,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+	} b;
+} control_t;
 
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
 #define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/jensen.h linux/include/asm-alpha/jensen.h
--- linux.orig/include/asm-alpha/jensen.h	2001-11-09 21:45:35.000000000 +0000
+++ linux/include/asm-alpha/jensen.h	2002-07-20 01:08:22.000000000 +0000
@@ -8,7 +8,7 @@
  */
 
 /* The Jensen is strange */
-#define AUX_IRQ (9)
+/* #define AUX_IRQ (9) *//* done in keyboard.h now */
 
 /*
  * NOTE! The memory operations do not set any memory barriers, as it's
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/keyboard.h linux/include/asm-alpha/keyboard.h
--- linux.orig/include/asm-alpha/keyboard.h	2001-09-13 22:21:32.000000000 +0000
+++ linux/include/asm-alpha/keyboard.h	2002-07-20 01:08:22.000000000 +0000
@@ -60,7 +60,7 @@
  * Machine specific bits for the PS/2 driver
  */
 
-#define AUX_IRQ 12
+#define AUX_IRQ ((RTC_PORT(0) == 0x170) ? 9 : 12) /* for JENSEN 9, others 12 */
 
 #define aux_request_irq(hand, dev_id)                                  \
        request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- linux.orig/include/asm-alpha/page.h	2001-10-05 19:22:07.000000000 +0000
+++ linux/include/asm-alpha/page.h	2002-07-20 01:08:39.000000000 +0000
@@ -98,6 +98,9 @@
 #define VALID_PAGE(page)	(((page) - mem_map) < max_mapnr)
 #endif /* CONFIG_DISCONTIGMEM */
 
+#define VM_DATA_DEFAULT_FLAGS		(VM_READ | VM_WRITE | VM_EXEC | \
+					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ALPHA_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/pgalloc.h linux/include/asm-alpha/pgalloc.h
--- linux.orig/include/asm-alpha/pgalloc.h	2001-05-24 22:20:18.000000000 +0000
+++ linux/include/asm-alpha/pgalloc.h	2002-07-20 01:08:22.000000000 +0000
@@ -70,8 +70,7 @@
 }
 
 /* We need to flush the userspace icache after setting breakpoints in
-   ptrace.  I don't think it's needed in do_swap_page, or do_no_page,
-   but I don't know how to get rid of it either.
+   ptrace.
 
    Instead of indiscriminately using imb, take advantage of the fact
    that icache entries are tagged with the ASN and load a new mm context.  */
@@ -79,7 +78,8 @@
 
 #ifndef CONFIG_SMP
 static inline 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)
 {
 	if (vma->vm_flags & VM_EXEC) {
 		struct mm_struct *mm = vma->vm_mm;
@@ -90,9 +90,13 @@
 	}
 }
 #else
-extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+extern void flush_icache_user_range(struct vm_area_struct *vma,
+		struct page *page, unsigned long addr, int len);
 #endif
 
+/* this is used only in do_no_page and do_swap_page */
+#define flush_icache_page(vma, page)	flush_icache_user_range((vma), (page), 0, 0)
+
 /*
  * Flush just one page in the current TLB set.
  * We need to be very careful about the icache here, there
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h
--- linux.orig/include/asm-alpha/pgtable.h	2001-10-25 21:00:32.000000000 +0000
+++ linux/include/asm-alpha/pgtable.h	2002-07-20 01:08:30.000000000 +0000
@@ -194,8 +194,8 @@
 #define PAGE_TO_PA(page)	((page - mem_map) << PAGE_SHIFT)
 #else
 #define PAGE_TO_PA(page) \
-		((((page)-(page)->zone->zone_mem_map) << PAGE_SHIFT) \
-		+ (page)->zone->zone_start_paddr)
+		((((page)-page_zone(page)->zone_mem_map) << PAGE_SHIFT) \
+		+ page_zone(page)->zone_start_paddr)
 #endif
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -213,8 +213,8 @@
 	pte_t pte;								\
 	unsigned long pfn;							\
 										\
-	pfn = ((unsigned long)((page)-(page)->zone->zone_mem_map)) << 32;	\
-	pfn += (page)->zone->zone_start_paddr << (32-PAGE_SHIFT);		\
+	pfn = ((unsigned long)((page)-page_zone(page)->zone_mem_map)) << 32;	\
+	pfn += page_zone(page)->zone_start_paddr << (32-PAGE_SHIFT);		\
 	pte_val(pte) = pfn | pgprot_val(pgprot);				\
 										\
 	pte;									\
@@ -268,8 +268,6 @@
 extern inline int pgd_present(pgd_t pgd)	{ return pgd_val(pgd) & _PAGE_VALID; }
 extern inline void pgd_clear(pgd_t * pgdp)	{ pgd_val(*pgdp) = 0; }
 
-#define page_address(page)	((page)->virtual)
-
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/siginfo.h linux/include/asm-alpha/siginfo.h
--- linux.orig/include/asm-alpha/siginfo.h	2000-05-25 01:38:26.000000000 +0000
+++ linux/include/asm-alpha/siginfo.h	2002-07-20 01:08:34.000000000 +0000
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h
--- linux.orig/include/asm-alpha/unistd.h	2001-11-09 21:45:35.000000000 +0000
+++ linux/include/asm-alpha/unistd.h	2002-07-20 01:08:34.000000000 +0000
@@ -318,6 +318,20 @@
 #define __NR_gettid			378
 #define __NR_readahead			379
 #define __NR_security			380 /* syscall for security modules */
+#define __NR_tkill			381
+#define __NR_setxattr			382
+#define __NR_lsetxattr			383
+#define __NR_fsetxattr			384
+#define __NR_getxattr			385
+#define __NR_lgetxattr			386
+#define __NR_fgetxattr			387
+#define __NR_listxattr			388
+#define __NR_llistxattr			389
+#define __NR_flistxattr			390
+#define __NR_removexattr		391
+#define __NR_lremovexattr		392
+#define __NR_fremovexattr		393
+
 
 #if defined(__GNUC__)
 
@@ -529,8 +543,8 @@
 	return sys_close(fd);
 }
 
-extern off_t sys_lseek(int, off_t, int);
-static inline off_t lseek(int fd, off_t off, int whense)
+extern off_t sys_lseek(unsigned int, off_t, unsigned int);
+static inline off_t lseek(unsigned int fd, off_t off, unsigned int whense)
 {
 	return sys_lseek(fd, off, whense);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-anakin/ide.h linux/include/asm-arm/arch-anakin/ide.h
--- linux.orig/include/asm-arm/arch-anakin/ide.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/arch-anakin/ide.h	2002-07-20 01:08:21.000000000 +0000
@@ -7,7 +7,6 @@
  *              (jonm@bluemug.com).
  */
  
-#include <linux/config.h>
 #include <asm/irq.h>
 #include <asm/hardware.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-anakin/uncompress.h linux/include/asm-arm/arch-anakin/uncompress.h
--- linux.orig/include/asm-arm/arch-anakin/uncompress.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/arch-anakin/uncompress.h	2002-07-20 01:08:39.000000000 +0000
@@ -14,6 +14,7 @@
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H
 
+#include <linux/config.h>
 #include <asm/io.h>
 #include <asm/arch/serial_reg.h>
 
@@ -24,7 +25,9 @@
 static inline void
 putc(int c)
 {
-	while (!(__raw_readl(IO_START + UART0 + 0x10) & TXEMPTY));
+	while (!(__raw_readl(IO_START + UART0 + 0x10) & TXEMPTY))
+		barrier();
+
 	__raw_writel(c, IO_START + UART0 + 0x14);
 	__raw_writel(__raw_readl(IO_START + UART0 + 0x18)
 			| SENDREQUEST, IO_START + UART0 + 0x18);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-cl7500/keyboard.h linux/include/asm-arm/arch-cl7500/keyboard.h
--- linux.orig/include/asm-arm/arch-cl7500/keyboard.h	2001-10-25 20:53:53.000000000 +0000
+++ linux/include/asm-arm/arch-cl7500/keyboard.h	2002-07-20 01:08:25.000000000 +0000
@@ -6,6 +6,7 @@
  *
  * Copyright (C) 1998-2001 Russell King
  */
+#include <asm/irq.h>
 #define NR_SCANCODES 128
 
 extern int ps2kbd_init_hw(void);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-cl7500/uncompress.h linux/include/asm-arm/arch-cl7500/uncompress.h
--- linux.orig/include/asm-arm/arch-cl7500/uncompress.h	2001-04-12 19:20:31.000000000 +0000
+++ linux/include/asm-arm/arch-cl7500/uncompress.h	2002-07-20 01:08:30.000000000 +0000
@@ -9,7 +9,8 @@
 
 static __inline__ void putc(char c)
 {
-	while (!(*((volatile unsigned int *)(SERBASE + 0x14)) & 0x20));
+	while (!(*((volatile unsigned int *)(SERBASE + 0x14)) & 0x20))
+		barrier();
 	*((volatile unsigned int *)(SERBASE)) = c;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/autcpu12.h linux/include/asm-arm/arch-clps711x/autcpu12.h
--- linux.orig/include/asm-arm/arch-clps711x/autcpu12.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/autcpu12.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,78 @@
+/*
+ * AUTCPU12 specific defines
+ *
+ * (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
+ */
+#ifndef __ASM_ARCH_AUTCPU12_H
+#define __ASM_ARCH_AUTCPU12_H
+
+/*
+ * The CS8900A ethernet chip has its I/O registers wired to chip select 2
+ * (nCS2). This is the mapping for it.
+ */
+#define AUTCPU12_PHYS_CS8900A		CS2_PHYS_BASE		/* physical */
+#define AUTCPU12_VIRT_CS8900A		(0xfe000000)		/* virtual */
+
+/*
+ * The flash bank is wired to chip select 0
+ */
+#define AUTCPU12_PHYS_FLASH		CS0_PHYS_BASE		/* physical */
+
+/* offset for device specific information structure */
+#define AUTCPU12_LCDINFO_OFFS		(0x00010000)	
+/*
+* Videomemory is the internal SRAM (CS 6)	
+*/
+#define AUTCPU12_PHYS_VIDEO		CS6_PHYS_BASE
+#define AUTCPU12_VIRT_VIDEO		(0xfd000000)
+
+/*
+* All special IO's are tied to CS1
+*/
+#define AUTCPU12_PHYS_CHAR_LCD         	CS1_PHYS_BASE +0x00000000  /* physical */
+
+#define AUTCPU12_PHYS_NVRAM            	CS1_PHYS_BASE +0x02000000  /* physical */
+
+#define AUTCPU12_PHYS_CSAUX1           	CS1_PHYS_BASE +0x04000000  /* physical */
+
+#define AUTCPU12_PHYS_SMC              	CS1_PHYS_BASE +0x06000000  /* physical */
+
+#define AUTCPU12_PHYS_CAN              	CS1_PHYS_BASE +0x08000000  /* physical */
+
+#define AUTCPU12_PHYS_TOUCH            	CS1_PHYS_BASE +0x0A000000  /* physical */
+
+#define AUTCPU12_PHYS_IO               	CS1_PHYS_BASE +0x0C000000  /* physical */
+
+#define AUTCPU12_PHYS_LPT              	CS1_PHYS_BASE +0x0E000000  /* physical */
+
+/* 
+* defines for smartmedia card access 
+*/
+#define AUTCPU12_SMC_RDY		(1<<2)
+#define AUTCPU12_SMC_ALE		(1<<3)
+#define AUTCPU12_SMC_CLE  		(1<<4)
+#define AUTCPU12_SMC_PORT_OFFSET	PBDR
+#define AUTCPU12_SMC_SELECT_OFFSET 	0x10
+/*
+* defines for lcd contrast 
+*/
+#define AUTCPU12_DPOT_PORT_OFFSET	PEDR
+#define	AUTCPU12_DPOT_CS		(1<<0)
+#define AUTCPU12_DPOT_CLK    		(1<<1)
+#define	AUTCPU12_DPOT_UD		(1<<2)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/dma.h linux/include/asm-arm/arch-clps711x/dma.h
--- linux.orig/include/asm-arm/arch-clps711x/dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/dma.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/dma.h
+ *
+ *  Copyright (C) 1997,1998 Russell King
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/hardware.h linux/include/asm-arm/arch-clps711x/hardware.h
--- linux.orig/include/asm-arm/arch-clps711x/hardware.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/hardware.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,179 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/hardware.h
+ *
+ *  This file contains the hardware definitions of the Prospector P720T.
+ *
+ *  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
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+
+#define CLPS7111_VIRT_BASE	0xff000000
+#define CLPS7111_BASE		CLPS7111_VIRT_BASE
+
+/*
+ * The physical addresses that the external chip select signals map to is
+ * dependent on the setting of the nMEDCHG signal on EP7211 and EP7212
+ * processors.  CONFIG_EP72XX_BOOT_ROM is only available if these
+ * processors are in use.
+ */
+#ifndef CONFIG_EP72XX_ROM_BOOT
+#define CS0_PHYS_BASE		(0x00000000)
+#define CS1_PHYS_BASE		(0x10000000)
+#define CS2_PHYS_BASE		(0x20000000)
+#define CS3_PHYS_BASE		(0x30000000)
+#define CS4_PHYS_BASE		(0x40000000)
+#define CS5_PHYS_BASE		(0x50000000)
+#define CS6_PHYS_BASE		(0x60000000)
+#define CS7_PHYS_BASE		(0x70000000)
+#else
+#define CS0_PHYS_BASE		(0x70000000)
+#define CS1_PHYS_BASE		(0x60000000)
+#define CS2_PHYS_BASE		(0x50000000)
+#define CS3_PHYS_BASE		(0x40000000)
+#define CS4_PHYS_BASE		(0x30000000)
+#define CS5_PHYS_BASE		(0x20000000)
+#define CS6_PHYS_BASE		(0x10000000)
+#define CS7_PHYS_BASE		(0x00000000)
+#endif
+
+#if defined (CONFIG_ARCH_EP7211)
+
+#define EP7211_VIRT_BASE	CLPS7111_VIRT_BASE
+#define EP7211_BASE		CLPS7111_VIRT_BASE
+#include <asm/hardware/ep7211.h>
+
+#elif defined (CONFIG_ARCH_EP7212)
+
+#define EP7212_VIRT_BASE	CLPS7111_VIRT_BASE
+#define EP7212_BASE		CLPS7111_VIRT_BASE
+#include <asm/hardware/ep7212.h>
+
+
+#endif
+
+#define SYSPLD_VIRT_BASE	0xfe000000
+#define SYSPLD_BASE		SYSPLD_VIRT_BASE
+
+#ifndef __ASSEMBLER__
+
+#define PCIO_BASE		IO_BASE
+
+#endif
+
+
+#if  defined (CONFIG_ARCH_AUTCPU12)
+
+#define  CS89712_VIRT_BASE	CLPS7111_VIRT_BASE
+#define  CS89712_BASE		CLPS7111_VIRT_BASE
+
+#include <asm/hardware/clps7111.h>
+#include <asm/hardware/ep7212.h>
+#include <asm/hardware/cs89712.h>
+
+#endif
+
+
+#if defined (CONFIG_ARCH_CDB89712)
+
+#include <asm/hardware/clps7111.h>
+#include <asm/hardware/ep7212.h>
+#include <asm/hardware/cs89712.h>
+
+/* dynamic ioremap() areas */
+#define FLASH_START      0x00000000
+#define FLASH_SIZE       0x800000
+#define FLASH_WIDTH      4
+
+#define SRAM_START       0x60000000
+#define SRAM_SIZE        0xc000
+#define SRAM_WIDTH       4
+
+#define BOOTROM_START    0x70000000
+#define BOOTROM_SIZE     0x80
+#define BOOTROM_WIDTH    4
+
+
+/* static cdb89712_map_io() areas */
+#define REGISTER_START   0x80000000
+#define REGISTER_SIZE    0x4000
+#define REGISTER_BASE    0xff000000
+
+#define ETHER_START      0x20000000
+#define ETHER_SIZE       0x1000
+#define ETHER_BASE       0xfe000000
+
+#endif
+
+
+#if defined (CONFIG_ARCH_EDB7211)
+
+/*
+ * The extra 8 lines of the keyboard matrix are wired to chip select 3 (nCS3) 
+ * and repeat across it. This is the mapping for it.
+ *
+ * In jumpered boot mode, nCS3 is mapped to 0x4000000, not 0x3000000. This 
+ * was cause for much consternation and headscratching. This should probably
+ * be made a compile/run time kernel option.
+ */
+#define EP7211_PHYS_EXTKBD		CS3_PHYS_BASE	/* physical */
+
+#define EP7211_VIRT_EXTKBD		(0xfd000000)	/* virtual */
+
+
+/*
+ * The CS8900A ethernet chip has its I/O registers wired to chip select 2 
+ * (nCS2). This is the mapping for it.
+ *
+ * In jumpered boot mode, nCS2 is mapped to 0x5000000, not 0x2000000. This 
+ * was cause for much consternation and headscratching. This should probably
+ * be made a compile/run time kernel option.
+ */
+#define EP7211_PHYS_CS8900A		CS2_PHYS_BASE	/* physical */
+
+#define EP7211_VIRT_CS8900A		(0xfc000000)	/* virtual */
+
+
+/*
+ * The two flash banks are wired to chip selects 0 and 1. This is the mapping
+ * for them.
+ *
+ * nCS0 and nCS1 are at 0x70000000 and 0x60000000, respectively, when running
+ * in jumpered boot mode.
+ */
+#define EP7211_PHYS_FLASH1		CS0_PHYS_BASE	/* physical */
+#define EP7211_PHYS_FLASH2		CS1_PHYS_BASE	/* physical */
+
+#define EP7211_VIRT_FLASH1		(0xfa000000)	/* virtual */
+#define EP7211_VIRT_FLASH2		(0xfb000000)	/* virtual */
+
+#endif /* CONFIG_ARCH_EDB7211 */
+
+
+/*
+ * Relevant bits in port D, which controls power to the various parts of
+ * the LCD on the EDB7211.
+ */
+#define EDB_PD1_LCD_DC_DC_EN	(1<<1)
+#define EDB_PD2_LCDEN		(1<<2)
+#define EDB_PD3_LCDBL		(1<<3)
+
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/io.h linux/include/asm-arm/arch-clps711x/io.h
--- linux.orig/include/asm-arm/arch-clps711x/io.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/io.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,50 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/io.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)			((a))
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
+
+/*
+ * ioremap support - validate a PCI memory address, and convert it
+ * to a physical address for the page tables.
+ */
+#define iomem_valid_addr(iomem,size)	(1)
+#define iomem_to_phys(iomem)		(iomem)
+
+/*
+ * We don't support ins[lb]/outs[lb].  Make them fault.
+ */
+#define __raw_readsb(p,d,l)	do { *(int *)0 = 0; } while (0)
+#define __raw_readsl(p,d,l)	do { *(int *)0 = 0; } while (0)
+#define __raw_writesb(p,d,l)	do { *(int *)0 = 0; } while (0)
+#define __raw_writesl(p,d,l)	do { *(int *)0 = 0; } while (0)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/irq.h linux/include/asm-arm/arch-clps711x/irq.h
--- linux.orig/include/asm-arm/arch-clps711x/irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/irq.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,20 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/irq.h
+ *
+ *  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
+ */
+#define fixup_irq(i)	(i)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/irqs.h linux/include/asm-arm/arch-clps711x/irqs.h
--- linux.orig/include/asm-arm/arch-clps711x/irqs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/irqs.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/irqs.h
+ *
+ *  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
+ */
+
+/*
+ * Interrupts from INTSR1
+ */
+#define IRQ_CSINT			4
+#define IRQ_EINT1			5
+#define IRQ_EINT2			6
+#define IRQ_EINT3			7
+#define IRQ_TC1OI			8
+#define IRQ_TC2OI			9
+#define IRQ_RTCMI			10
+#define IRQ_TINT			11
+#define IRQ_UTXINT1			12
+#define IRQ_URXINT1			13
+#define IRQ_UMSINT			14
+#define IRQ_SSEOTI			15
+
+#define INT1_IRQS			(0x0000fff0)
+#define INT1_ACK_IRQS			(0x00004f10)
+
+/*
+ * Interrupts from INTSR2
+ */
+#define IRQ_KBDINT			(16+0)	/* bit 0 */
+#define IRQ_SS2RX			(16+1)	/* bit 1 */
+#define IRQ_SS2TX			(16+2)	/* bit 2 */
+#define IRQ_UTXINT2			(16+12)	/* bit 12 */
+#define IRQ_URXINT2			(16+13)	/* bit 13 */
+
+#define INT2_IRQS			(0x30070000)
+#define INT2_ACK_IRQS			(0x00010000)
+
+#define NR_IRQS                         30
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/keyboard.h linux/include/asm-arm/arch-clps711x/keyboard.h
--- linux.orig/include/asm-arm/arch-clps711x/keyboard.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/keyboard.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-arm/arch-clps711x/keyboard.h
+ *
+ * Copyright (C) 1998-2001 Russell King
+ */
+#include <asm/mach-types.h>
+
+#define NR_SCANCODES 128
+
+#define kbd_disable_irq()	do { } while (0)
+#define kbd_enable_irq()	do { } while (0)
+
+/*
+ * EDB7211 keyboard driver
+ */
+extern void edb7211_kbd_init_hw(void);
+extern void clps711x_kbd_init_hw(void);
+
+static inline void kbd_init_hw(void)
+{
+	if (machine_is_edb7211())
+		edb7211_kbd_init_hw();
+
+	if (machine_is_autcpu12())
+		clps711x_kbd_init_hw();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/memory.h linux/include/asm-arm/arch-clps711x/memory.h
--- linux.orig/include/asm-arm/arch-clps711x/memory.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/memory.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,206 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/mmu.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#include <linux/config.h>
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+#define PHYS_OFFSET	(0xc0000000UL)
+
+/*
+ * On integrator, the dram is contiguous
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - PHYS_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+
+#if defined(CONFIG_ARCH_CDB89712)
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	(x)
+
+#elif defined (CONFIG_ARCH_AUTCPU12)
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	(x)
+
+#else
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	((x) - PAGE_OFFSET)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	((x) + PAGE_OFFSET)
+
+#endif
+
+
+/*
+ * Like the SA1100, the EDB7211 has a large gap between physical RAM
+ * banks.  In 2.2, the Psion (CL-PS7110) port added custom support for
+ * discontiguous physical memory.  In 2.4, we can use the standard
+ * Linux NUMA support.
+ *
+ * This is not necessary for EP7211 implementations with only one used
+ * memory bank.  For those systems, simply undefine CONFIG_DISCONTIGMEM.
+ */
+
+#ifdef CONFIG_ARCH_EDB7211
+
+#ifdef CONFIG_DISCONTIGMEM
+/*
+ * Because of the wide memory address space between physical RAM banks on the 
+ * SA1100, it's much more convenient to use Linux's NUMA support to implement
+ * our memory map representation.  Assuming all memory nodes have equal access 
+ * characteristics, we then have generic discontigous memory support.
+ *
+ * Of course, all this isn't mandatory for SA1100 implementations with only
+ * one used memory bank.  For those, simply undefine CONFIG_DISCONTIGMEM.
+ *
+ * The nodes are matched with the physical memory bank addresses which are 
+ * incidentally the same as virtual addresses.
+ * 
+ * 	node 0:  0xc0000000 - 0xc7ffffff
+ * 	node 1:  0xc8000000 - 0xcfffffff
+ * 	node 2:  0xd0000000 - 0xd7ffffff
+ * 	node 3:  0xd8000000 - 0xdfffffff
+ */
+
+#define NR_NODES	4
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(addr) \
+		(((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
+
+/*
+ * Given a physical address, convert it to a node id.
+ */
+#define PHYS_TO_NID(addr) KVADDR_TO_NID(__phys_to_virt(addr))
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and returns the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) \
+			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+
+/*
+ * Given a kaddr, LOCAL_MAR_NR finds the owning node of the memory
+ * and returns the index corresponding to the appropriate page in the
+ * node's mem_map.
+ */
+#define LOCAL_MAP_NR(kaddr) \
+	(((unsigned long)(kaddr)-LOCAL_BASE_ADDR((kaddr))) >> PAGE_SHIFT)
+
+/*
+ * Given a kaddr, virt_to_page returns a pointer to the corresponding 
+ * mem_map entry.
+ */
+#define virt_to_page(kaddr) \
+	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
+
+/*
+ * VALID_PAGE returns a non-zero value if given page pointer is valid.
+ * This assumes all node's mem_maps are stored within the node they refer to.
+ */
+#define VALID_PAGE(page) \
+({ unsigned int node = KVADDR_TO_NID(page); \
+   ( (node < NR_NODES) && \
+     ((unsigned)((page) - NODE_MEM_MAP(node)) < NODE_DATA(node)->node_size) ); \
+})
+
+/*
+ * The PS7211 allows up to 256MB max per DRAM bank, but the EDB7211
+ * uses only one of the two banks (bank #1).  However, even within
+ * bank #1, memory is discontiguous.
+ *
+ * The EDB7211 has two 8MB DRAM areas with 8MB of empty space between
+ * them, so we use 24 for the node max shift to get 16MB node sizes.
+ */
+#define NODE_MAX_MEM_SHIFT	24
+#define NODE_MAX_MEM_SIZE	(1<<NODE_MAX_MEM_SHIFT)
+
+/*
+ * Given a mem_map_t, LOCAL_MAP_BASE finds the owning node for the
+ * physical page and returns the kaddr for the mem_map of that node.
+ */
+#define LOCAL_MAP_BASE(page) \
+			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(page)))
+
+/*
+ * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
+ * and returns the kaddr corresponding to first physical page in the
+ * node's mem_map.
+ */
+#define LOCAL_BASE_ADDR(kaddr)	((unsigned long)(kaddr) & ~(NODE_MAX_MEM_SIZE-1))
+
+/* 
+ * With discontigmem, the conceptual mem_map array starts from PAGE_OFFSET.
+ * Given a kaddr, MAP_NR returns the appropriate global mem_map index so 
+ * it matches the corresponding node's local mem_map.
+ */
+#define MAP_NR(kaddr)	(LOCAL_MAP_NR((kaddr)) + \
+		(((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \
+		sizeof(mem_map_t)))
+
+#else
+
+#define PHYS_TO_NID(addr)	(0)
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif	/* CONFIG_ARCH_EDB7211 */
+
+#ifndef PHYS_TO_NID
+#define PHYS_TO_NID(addr)	(0)
+#endif
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/param.h linux/include/asm-arm/arch-clps711x/param.h
--- linux.orig/include/asm-arm/arch-clps711x/param.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/param.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/param.h
+ *
+ *  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
+ */
+
+#define HZ 100
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/syspld.h linux/include/asm-arm/arch-clps711x/syspld.h
--- linux.orig/include/asm-arm/arch-clps711x/syspld.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/syspld.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,121 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/syspld.h
+ *
+ *  System Control PLD register definitions.
+ *
+ *  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
+ */
+#ifndef __ASM_ARCH_SYSPLD_H
+#define __ASM_ARCH_SYSPLD_H
+
+#define SYSPLD_PHYS_BASE	(0x10000000)
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+
+#define SYSPLD_REG(type,off)	(*(volatile type *)(SYSPLD_BASE + off))
+#else
+#define SYSPLD_REG(type,off)	(off)
+#endif
+
+#define PLD_INT		SYSPLD_REG(u32, 0x000000)
+#define PLD_INT_PENIRQ		(1 << 5)
+#define PLD_INT_UCB_IRQ		(1 << 1)
+#define PLD_INT_KBD_ATN		(1 << 0)	/* EINT1 */
+
+#define PLD_PWR		SYSPLD_REG(u32, 0x000004)
+#define PLD_PWR_EXT		(1 << 5)
+#define PLD_PWR_MODE		(1 << 4)	/* 1 = PWM, 0 = PFM */
+#define PLD_S4_ON		(1 << 3)	/* LCD bias voltage enable */
+#define PLD_S3_ON		(1 << 2)	/* LCD backlight enable */
+#define PLD_S2_ON		(1 << 1)	/* LCD 3V3 supply enable */
+#define PLD_S1_ON		(1 << 0)	/* LCD 3V supply enable */
+
+#define PLD_KBD		SYSPLD_REG(u32, 0x000008)
+#define PLD_KBD_WAKE		(1 << 1)
+#define PLD_KBD_EN		(1 << 0)
+
+#define PLD_SPI		SYSPLD_REG(u32, 0x00000c)
+#define PLD_SPI_EN		(1 << 0)
+
+#define PLD_IO		SYSPLD_REG(u32, 0x000010)
+#define PLD_IO_BOOTSEL		(1 << 6)	/* boot sel switch */
+#define PLD_IO_USER		(1 << 5)	/* user defined switch */
+#define PLD_IO_LED3		(1 << 4)
+#define PLD_IO_LED2		(1 << 3)
+#define PLD_IO_LED1		(1 << 2)
+#define PLD_IO_LED0		(1 << 1)
+#define PLD_IO_LEDEN		(1 << 0)
+
+#define PLD_IRDA	SYSPLD_REG(u32, 0x000014)
+#define PLD_IRDA_EN		(1 << 0)
+
+#define PLD_COM2	SYSPLD_REG(u32, 0x000018)
+#define PLD_COM2_EN		(1 << 0)
+
+#define PLD_COM1	SYSPLD_REG(u32, 0x00001c)
+#define PLD_COM1_EN		(1 << 0)
+
+#define PLD_AUD		SYSPLD_REG(u32, 0x000020)
+#define PLD_AUD_DIV1		(1 << 6)
+#define PLD_AUD_DIV0		(1 << 5)
+#define PLD_AUD_CLK_SEL1	(1 << 4)
+#define PLD_AUD_CLK_SEL0	(1 << 3)
+#define PLD_AUD_MIC_PWR		(1 << 2)
+#define PLD_AUD_MIC_GAIN	(1 << 1)
+#define PLD_AUD_CODEC_EN	(1 << 0)
+
+#define PLD_CF		SYSPLD_REG(u32, 0x000024)
+#define PLD_CF2_SLEEP		(1 << 5)
+#define PLD_CF1_SLEEP		(1 << 4)
+#define PLD_CF2_nPDREQ		(1 << 3)
+#define PLD_CF1_nPDREQ		(1 << 2)
+#define PLD_CF2_nIRQ		(1 << 1)
+#define PLD_CF1_nIRQ		(1 << 0)
+
+#define PLD_SDC		SYSPLD_REG(u32, 0x000028)
+#define PLD_SDC_INT_EN		(1 << 2)
+#define PLD_SDC_WP		(1 << 1)
+#define PLD_SDC_CD		(1 << 0)
+
+#define PLD_FPGA	SYSPLD_REG(u32, 0x00002c)
+
+#define PLD_CODEC	SYSPLD_REG(u32, 0x400000)
+#define PLD_CODEC_IRQ3		(1 << 4)
+#define PLD_CODEC_IRQ2		(1 << 3)
+#define PLD_CODEC_IRQ1		(1 << 2)
+#define PLD_CODEC_EN		(1 << 0)
+
+#define PLD_BRITE	SYSPLD_REG(u32, 0x400004)
+#define PLD_BRITE_UP		(1 << 1)
+#define PLD_BRITE_DN		(1 << 0)
+
+#define PLD_LCDEN	SYSPLD_REG(u32, 0x400008)
+#define PLD_LCDEN_EN		(1 << 0)
+
+#define PLD_ID		SYSPLD_REG(u32, 0x40000c)
+
+#define PLD_TCH		SYSPLD_REG(u32, 0x400010)
+#define PLD_TCH_PENIRQ		(1 << 1)
+#define PLD_TCH_EN		(1 << 0)
+
+#define PLD_GPIO	SYSPLD_REG(u32, 0x400014)
+#define PLD_GPIO2		(1 << 2)
+#define PLD_GPIO1		(1 << 1)
+#define PLD_GPIO0		(1 << 0)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/system.h linux/include/asm-arm/arch-clps711x/system.h
--- linux.orig/include/asm-arm/arch-clps711x/system.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/system.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,40 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/system.h
+ *
+ *  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
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/hardware/clps7111.h>
+
+static void arch_idle(void)
+{
+	clps_writel(1, HALT);
+	__asm__ __volatile__(
+	"mov	r0, r0
+	mov	r0, r0");
+}
+
+static inline void arch_reset(char mode)
+{
+	cpu_reset(0);
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/time.h linux/include/asm-arm/arch-clps711x/time.h
--- linux.orig/include/asm-arm/arch-clps711x/time.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/time.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,43 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/time.h
+ *
+ *  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 <asm/leds.h>
+#include <asm/hardware/clps7111.h>
+
+extern void clps711x_setup_timer(void);
+
+/*
+ * IRQ handler for the timer
+ */
+static void p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_leds();
+	do_timer(regs);
+	do_profile(regs);
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static inline void setup_timer(void)
+{
+	clps711x_setup_timer();
+	timer_irq.handler = p720t_timer_interrupt;
+	setup_arm_irq(IRQ_TC2OI, &timer_irq);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/timex.h linux/include/asm-arm/arch-clps711x/timex.h
--- linux.orig/include/asm-arm/arch-clps711x/timex.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/timex.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,23 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/timex.h
+ *
+ *  Prospector 720T architecture timex specifications
+ *
+ *  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
+ */
+
+#define CLOCK_TICK_RATE 512000
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/uncompress.h linux/include/asm-arm/arch-clps711x/uncompress.h
--- linux.orig/include/asm-arm/arch-clps711x/uncompress.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/uncompress.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,67 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/uncompress.h
+ *
+ *  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 <asm/arch/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/hardware/clps7111.h>
+
+#undef CLPS7111_BASE
+#define CLPS7111_BASE CLPS7111_PHYS_BASE
+
+#define barrier()		__asm__ __volatile__("": : :"memory")
+#define __raw_readl(p)		(*(unsigned long *)(p))
+#define __raw_writel(v,p)	(*(unsigned long *)(p) = (v))
+
+#ifdef CONFIG_DEBUG_CLPS711X_UART2
+#define SYSFLGx	SYSFLG2
+#define UARTDRx	UARTDR2
+#else
+#define SYSFLGx	SYSFLG1
+#define UARTDRx	UARTDR1
+#endif
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+	char c;
+
+	while ((c = *s++) != '\0') {
+		while (clps_readl(SYSFLGx) & SYSFLG_UTXFF)
+			barrier();
+		clps_writel(c, UARTDRx);
+
+		if (c == '\n') {
+			while (clps_readl(SYSFLGx) & SYSFLG_UTXFF)
+				barrier();
+			clps_writel('\r', UARTDRx);
+		}
+	}
+	while (clps_readl(SYSFLGx) & SYSFLG_UBUSY)
+		barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-clps711x/vmalloc.h linux/include/asm-arm/arch-clps711x/vmalloc.h
--- linux.orig/include/asm-arm/arch-clps711x/vmalloc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-clps711x/vmalloc.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-clps711x/vmalloc.h
+ *
+ *  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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-ebsa110/io.h linux/include/asm-arm/arch-ebsa110/io.h
--- linux.orig/include/asm-arm/arch-ebsa110/io.h	2001-04-12 19:20:31.000000000 +0000
+++ linux/include/asm-arm/arch-ebsa110/io.h	2002-07-20 01:08:25.000000000 +0000
@@ -21,34 +21,48 @@
 #define __arch_getw(a)		(*(volatile unsigned short *)(a))
 #define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
 
-u8  __inb(int port);
-u16 __inw(int port);
-u32 __inl(int port);
+u8 __inb8(unsigned int port);
+void __outb8(u8  val, unsigned int port);
 
-#define inb(p)			__inb(p)
-#define inw(p)			__inw(p)
-#define inl(p)			__inl(p)
+u8 __inb16(unsigned int port);
+void __outb16(u8  val, unsigned int port);
 
-void __outb(u8  val, int port);
-void __outw(u16 val, int port);
-void __outl(u32 val, int port);
+u16 __inw(unsigned int port);
+void __outw(u16 val, unsigned int port);
 
-#define outb(v,p)		__outb(v,p)
-#define outw(v,p)		__outw(v,p)
-#define outl(v,p)		__outl(v,p)
+u32 __inl(unsigned int port);
+void __outl(u32 val, unsigned int port);
 
 u8  __readb(void *addr);
 u16 __readw(void *addr);
 u32 __readl(void *addr);
 
-#define readb(b)		__readb(b)
-#define readw(b)		__readw(b)
-#define readl(b)		__readl(b)
-
 void __writeb(u8  val, void *addr);
 void __writew(u16 val, void *addr);
 void __writel(u32 val, void *addr);
 
+/*
+ * Argh, someone forgot the IOCS16 line.  We therefore have to handle
+ * the byte stearing by selecting the correct byte IO functions here.
+ */
+#ifdef ISA_SIXTEEN_BIT_PERIPHERAL
+#define inb(p)			__inb16(p)
+#define outb(v,p)		__outb16(v,p)
+#else
+#define inb(p)			__inb8(p)
+#define outb(v,p)		__outb8(v,p)
+#endif
+
+#define inw(p)			__inw(p)
+#define outw(v,p)		__outw(v,p)
+
+#define inl(p)			__inl(p)
+#define outl(v,p)		__outl(v,p)
+
+#define readb(b)		__readb(b)
+#define readw(b)		__readw(b)
+#define readl(b)		__readl(b)
+
 #define writeb(v,b)		__writeb(v,b)
 #define writew(v,b)		__writew(v,b)
 #define writel(v,b)		__writel(v,b)
@@ -56,4 +70,12 @@
 #define __arch_ioremap(off,sz,c)	((void *)(off))
 #define __arch_iounmap(virt)		do { } while (0)
 
+extern void insb(unsigned int port, void *buf, int sz);
+extern void insw(unsigned int port, void *buf, int sz);
+extern void insl(unsigned int port, void *buf, int sz);
+
+extern void outsb(unsigned int port, const void *buf, int sz);
+extern void outsw(unsigned int port, const void *buf, int sz);
+extern void outsl(unsigned int port, const void *buf, int sz);
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-ebsa110/uncompress.h linux/include/asm-arm/arch-ebsa110/uncompress.h
--- linux.orig/include/asm-arm/arch-ebsa110/uncompress.h	2001-04-12 19:20:31.000000000 +0000
+++ linux/include/asm-arm/arch-ebsa110/uncompress.h	2002-07-20 01:08:37.000000000 +0000
@@ -13,6 +13,8 @@
  */
 static void puts(const char *s)
 {
+	unsigned long tmp1, tmp2;
+
 	__asm__ __volatile__("
 	ldrb	%0, [%2], #1
 	teq	%0, #0
@@ -32,7 +34,9 @@
 	and	%1, %1, #0x60
 	teq	%1, #0x60
 	bne	3b
-	" : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
+	"
+	 : "=&r" (tmp1), "=&r" (tmp2)
+	 : "0" (0), "1" (0), "r" (s), "r" (0xf0000be0) : "cc");
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-ebsa285/keyboard.h linux/include/asm-arm/arch-ebsa285/keyboard.h
--- linux.orig/include/asm-arm/arch-ebsa285/keyboard.h	2001-10-25 20:53:53.000000000 +0000
+++ linux/include/asm-arm/arch-ebsa285/keyboard.h	2002-07-20 01:08:31.000000000 +0000
@@ -6,6 +6,7 @@
  * Copyright (C) 1998-2001 Russell King
  * (C) 1998 Phil Blundell
  */
+#include <linux/config.h>
 #include <linux/ioport.h>
 #include <asm/irq.h>
 #include <asm/system.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-ebsa285/uncompress.h linux/include/asm-arm/arch-ebsa285/uncompress.h
--- linux.orig/include/asm-arm/arch-ebsa285/uncompress.h	2000-09-18 22:15:23.000000000 +0000
+++ linux/include/asm-arm/arch-ebsa285/uncompress.h	2002-07-20 01:08:34.000000000 +0000
@@ -18,10 +18,12 @@
 static __inline__ void putc(char c)
 {
 	if (machine_is_netwinder()) {
-		while ((SER0_BASE[5] & 0x60) != 0x60);
+		while ((SER0_BASE[5] & 0x60) != 0x60)
+			barrier();
 		SER0_BASE[0] = c;
 	} else {
-		while (DC21285_BASE[6] & 8);
+		while (DC21285_BASE[6] & 8)
+			barrier();
 		DC21285_BASE[0] = c;
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-epxa10db/ether00.h linux/include/asm-arm/arch-epxa10db/ether00.h
--- linux.orig/include/asm-arm/arch-epxa10db/ether00.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-epxa10db/ether00.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,482 @@
+#ifndef __ETHER00_H
+#define __ETHER00_H
+
+
+
+/*
+ * Register definitions for the Ethernet MAC
+ */
+
+/*
+ * Copyright (c) Altera Corporation 2000.
+ * All rights reserved.
+ */
+
+/*
+*	Structures for the DMA controller
+*/
+typedef struct fda_desc
+	{
+	struct fda_desc *	FDNext;
+	long				FDSystem;
+	long				FDStat;
+	short				FDLength;
+	short				FDCtl;
+	}FDA_DESC;
+
+typedef struct buf_desc
+	{
+	char *	BuffData;
+	short	BuffLength;
+	char	BDStat;
+	char	BDCtl;
+	}BUF_DESC;
+
+/*
+*	Control masks for the DMA controller
+*/
+#define FDCTL_BDCOUNT_MSK						(0x1F)
+#define FDCTL_BDCOUNT_OFST						(0)
+#define FDCTL_FRMOPT_MSK						(0x7C00)
+#define FDCTL_FRMOPT_OFST						(10)
+#define	FDCTL_COWNSFD_MSK						(0x8000)
+#define	FDCTL_COWNSFD_OFST						(15)
+
+#define BDCTL_RXBDSEQN_MSK						(0x7F)
+#define BDCTL_RXBDSEQN_OFST						(0)
+#define	BDCTL_COWNSBD_MSK						(0x80)
+#define	BDCTL_COWNSBD_OFST						(7)
+
+#define FDNEXT_EOL_MSK							(0x1)
+#define FDNEXT_EOL_OFST							(0)
+#define FDNEXT_EOL_POINTER_MSK					(0xFFFFFFF0)
+#define FDNEXT_EOL_POINTER_OFST					(4)
+
+#define ETHER_ARC_SIZE         (21)
+
+/*
+*	Regsiter definitions and masks
+*/
+#define ETHER_DMA_CTL(base)							(ETHER00_TYPE (base + 0x100))
+#define ETHER_DMA_CTL_DMBURST_OFST				(2)
+#define ETHER_DMA_CTL_DMBURST_MSK				(0x1FC)
+#define ETHER_DMA_CTL_POWRMGMNT_OFST			(11)
+#define ETHER_DMA_CTL_POWRMGMNT_MSK				(0x1000)
+#define ETHER_DMA_CTL_TXBIGE_OFST				(14)
+#define ETHER_DMA_CTL_TXBIGE_MSK				(0x4000)
+#define ETHER_DMA_CTL_RXBIGE_OFST				(15)
+#define ETHER_DMA_CTL_RXBIGE_MSK				(0x8000)
+#define ETHER_DMA_CTL_TXWAKEUP_OFST				(16)
+#define ETHER_DMA_CTL_TXWAKEUP_MSK				(0x10000)
+#define ETHER_DMA_CTL_SWINTREQ_OFST				(17)
+#define ETHER_DMA_CTL_SWINTREQ_MSK				(0x20000)
+#define ETHER_DMA_CTL_INTMASK_OFST				(18)
+#define ETHER_DMA_CTL_INTMASK_MSK				(0x40000)
+#define ETHER_DMA_CTL_M66ENSTAT_OFST			(19)
+#define ETHER_DMA_CTL_M66ENSTAT_MSK				(0x80000)
+#define ETHER_DMA_CTL_RMTXINIT_OFST				(20)
+#define ETHER_DMA_CTL_RMTXINIT_MSK				(0x100000)
+#define ETHER_DMA_CTL_RMRXINIT_OFST				(21)
+#define ETHER_DMA_CTL_RMRXINIT_MSK				(0x200000)
+#define ETHER_DMA_CTL_RXALIGN_OFST				(22)
+#define ETHER_DMA_CTL_RXALIGN_MSK				(0xC00000)
+#define ETHER_DMA_CTL_RMSWRQ_OFST				(24)
+#define ETHER_DMA_CTL_RMSWRQ_MSK				(0x1000000)
+#define ETHER_DMA_CTL_RMEMBANK_OFST				(25)
+#define ETHER_DMA_CTL_RMEMBANK_MSK				(0x2000000)
+
+#define ETHER_TXFRMPTR(base)							(ETHER00_TYPE (base + 0x104))
+
+#define ETHER_TXTHRSH(base)							(ETHER00_TYPE (base + 0x308))
+
+#define ETHER_TXPOLLCTR(base)							(ETHER00_TYPE (base + 0x30c))
+
+#define	ETHER_BLFRMPTR(base)							(ETHER00_TYPE (base + 0x110))
+#define ETHER_BLFFRMPTR_EOL_OFST				(0)
+#define ETHER_BLFFRMPTR_EOL_MSK					(0x1)
+#define ETHER_BLFFRMPTR_ADDRESS_OFST			(4)
+#define ETHER_BLFFRMPTR_ADDRESS_MSK				(0xFFFFFFF0)
+
+#define ETHER_RXFRAGSIZE(base)						(ETHER00_TYPE (base + 0x114))
+#define	ETHER_RXFRAGSIZE_MINFRAG_OFST			(2)
+#define	ETHER_RXFRAGSIZE_MINFRAG_MSK			(0xFFC)
+#define	ETHER_RXFRAGSIZE_ENPACK_OFST			(15)
+#define	ETHER_RXFRAGSIZE_ENPACK_MSK				(0x8000)
+
+#define ETHER_INT_EN(base)							(ETHER00_TYPE (base + 0x118))
+#define ETHER_INT_EN_FDAEXEN_OFST				(0)
+#define ETHER_INT_EN_FDAEXEN_MSK				(0x1)
+#define ETHER_INT_EN_BLEXEN_OFST				(1)
+#define ETHER_INT_EN_BLEXN_MSK					(0x2)
+#define ETHER_INT_EN_STARGABTEN_OFST			(2)
+#define ETHER_INT_EN_STARGABTEN_MSK				(0x4)
+#define ETHER_INT_EN_RTARGABTEN_OFST			(3)
+#define ETHER_INT_EN_RTARGABTEN_MSK				(0x8)
+#define ETHER_INT_EN_RMASABTEN_OFST				(4)
+#define ETHER_INT_EN_RMASABTEN_MSK				(0x10)
+#define ETHER_INT_EN_SSYSERREN_OFST				(5)
+#define ETHER_INT_EN_SSYSERREN_MSK				(0x20)
+#define ETHER_INT_EN_DPARERREN_OFST				(6)
+#define ETHER_INT_EN_DPARERREN_MSK				(0x40)
+#define ETHER_INT_EN_EARNOTEN_OFST				(7)
+#define ETHER_INT_EN_EARNOTEN_MSK				(0x80)
+#define ETHER_INT_EN_DPARDEN_OFST				(8)
+#define ETHER_INT_EN_DPARDEN_MSK				(0x100)
+#define ETHER_INT_EN_DMPARERREN_OFST			(9)
+#define ETHER_INT_EN_DMPARERREN_MSK				(0x200)
+#define ETHER_INT_EN_TXCTLCMPEN_OFST			(10)
+#define ETHER_INT_EN_TXCTLCMPEN_MSK				(0x400)
+#define ETHER_INT_EN_NRABTEN_OFST				(11)
+#define ETHER_INT_EN_NRABTEN_MSK				(0x800)
+
+#define	ETHER_FDA_BAS(base)							(ETHER00_TYPE (base + 0x11C))
+#define ETHER_FDA_BAS_ADDRESS_OFST				(4)
+#define ETHER_FDA_BAS_ADDRESS_MSK				(0xFFFFFFF0)
+
+#define ETHER_FDA_LIM(base)							(ETHER00_TYPE (base + 0x120))
+#define ETHER_FDA_LIM_COUNT_OFST				(4)
+#define ETHER_FDA_LIM_COUNT_MSK					(0xFFF0)
+
+#define ETHER_INT_SRC(base)							(ETHER00_TYPE (base + 0x124))
+#define ETHER_INT_SRC_INTMACTX_OFST				(0)
+#define ETHER_INT_SRC_INTMACTX_MSK				(0x1)
+#define ETHER_INT_SRC_INTMACRX_OFST				(1)
+#define ETHER_INT_SRC_INTMACRX_MSK				(0x2)
+#define ETHER_INT_SRC_INTSBUS_OFST				(2)
+#define ETHER_INT_SRC_INTSBUS_MSK				(0x4)
+#define ETHER_INT_SRC_INTFDAEX_OFST				(3)
+#define ETHER_INT_SRC_INTFDAEX_MSK				(0x8)
+#define ETHER_INT_SRC_INTBLEX_OFST				(4)
+#define ETHER_INT_SRC_INTBLEX_MSK				(0x10)
+#define ETHER_INT_SRC_SWINT_OFST				(5)
+#define ETHER_INT_SRC_SWINT_MSK					(0x20)
+#define ETHER_INT_SRC_INTEARNOT_OFST			(6)
+#define ETHER_INT_SRC_INTEARNOT_MSK				(0x40)
+#define ETHER_INT_SRC_DMPARERR_OFST				(7)
+#define ETHER_INT_SRC_DMPARERR_MSK				(0x80)
+#define ETHER_INT_SRC_INTEXBD_OFST				(8)
+#define ETHER_INT_SRC_INTEXBD_MSK				(0x100)
+#define ETHER_INT_SRC_INTTXCTLCMP_OFST			(9)
+#define ETHER_INT_SRC_INTTXCTLCMP_MSK			(0x200)
+#define ETHER_INT_SRC_INTNRABT_OFST				(10)
+#define ETHER_INT_SRC_INTNRABT_MSK				(0x400)
+#define ETHER_INT_SRC_FDAEX_OFST				(11)
+#define ETHER_INT_SRC_FDAEX_MSK					(0x800)
+#define ETHER_INT_SRC_BLEX_OFST					(12)
+#define ETHER_INT_SRC_BLEX_MSK					(0x1000)
+#define ETHER_INT_SRC_DMPARERRSTAT_OFST			(13)
+#define ETHER_INT_SRC_DMPARERRSTAT_MSK			(0x2000)
+#define ETHER_INT_SRC_NRABT_OFST				(14)
+#define ETHER_INT_SRC_NRABT_MSK					(0x4000)
+#define ETHER_INT_SRC_INTLINK_OFST				(15)
+#define ETHER_INT_SRC_INTLINK_MSK				(0x8000)
+#define ETHER_INT_SRC_INTEXDEFER_OFST			(16)
+#define ETHER_INT_SRC_INTEXDEFER_MSK			(0x10000)
+#define ETHER_INT_SRC_INTRMON_OFST				(17)
+#define ETHER_INT_SRC_INTRMON_MSK				(0x20000)
+#define ETHER_INT_SRC_IRQ_MSK					(0x83FF)
+
+#define ETHER_PAUSECNT(base)							(ETHER00_TYPE (base + 0x40))
+#define ETHER_PAUSECNT_COUNT_OFST				(0)
+#define ETHER_PAUSECNT_COUNT_MSK				(0xFFFF)
+
+#define ETHER_REMPAUCNT(base)							(ETHER00_TYPE (base + 0x44))
+#define ETHER_REMPAUCNT_COUNT_OFST				(0)
+#define ETHER_REMPAUCNT_COUNT_MSK				(0xFFFF)
+
+#define ETHER_TXCONFRMSTAT(base)						(ETHER00_TYPE (base + 0x348))
+#define ETHER_TXCONFRMSTAT_TS_STAT_VALUE_OFST	(0)
+#define ETHER_TXCONFRMSTAT_TS_STAT_VALUE_MSK	(0x3FFFFF)
+
+#define ETHER_MAC_CTL(base)							(ETHER00_TYPE (base + 0))
+#define ETHER_MAC_CTL_HALTREQ_OFST				(0)
+#define ETHER_MAC_CTL_HALTREQ_MSK				(0x1)
+#define ETHER_MAC_CTL_HALTIMM_OFST				(1)
+#define ETHER_MAC_CTL_HALTIMM_MSK				(0x2)
+#define ETHER_MAC_CTL_RESET_OFST				(2)
+#define ETHER_MAC_CTL_RESET_MSK					(0x4)
+#define ETHER_MAC_CTL_FULLDUP_OFST				(3)
+#define ETHER_MAC_CTL_FULLDUP_MSK				(0x8)
+#define ETHER_MAC_CTL_MACLOOP_OFST				(4)
+#define ETHER_MAC_CTL_MACLOOP_MSK				(0x10)
+#define ETHER_MAC_CTL_CONN_OFST					(5)
+#define ETHER_MAC_CTL_CONN_MSK					(0x60)
+#define ETHER_MAC_CTL_LOOP10_OFST				(7)
+#define ETHER_MAC_CTL_LOOP10_MSK				(0x80)
+#define ETHER_MAC_CTL_LNKCHG_OFST				(8)
+#define ETHER_MAC_CTL_LNKCHG_MSK				(0x100)
+#define ETHER_MAC_CTL_MISSROLL_OFST				(10)
+#define ETHER_MAC_CTL_MISSROLL_MSK				(0x400)
+#define ETHER_MAC_CTL_ENMISSROLL_OFST			(13)
+#define ETHER_MAC_CTL_ENMISSROLL_MSK			(0x2000)
+#define ETHER_MAC_CTL_LINK10_OFST				(15)
+#define ETHER_MAC_CTL_LINK10_MSK				(0x8000)
+
+#define ETHER_ARC_CTL(base)							(ETHER00_TYPE (base + 0x4))
+#define	ETHER_ARC_CTL_STATIONACC_OFST			(0)
+#define	ETHER_ARC_CTL_STATIONACC_MSK			(0x1)
+#define	ETHER_ARC_CTL_GROUPACC_OFST				(1)
+#define	ETHER_ARC_CTL_GROUPACC_MSK				(0x2)
+#define	ETHER_ARC_CTL_BROADACC_OFST				(2)
+#define	ETHER_ARC_CTL_BROADACC_MSK				(0x4)
+#define	ETHER_ARC_CTL_NEGARC_OFST				(3)
+#define	ETHER_ARC_CTL_NEGARC_MSK				(0x8)
+#define	ETHER_ARC_CTL_COMPEN_OFST				(4)
+#define	ETHER_ARC_CTL_COMPEN_MSK				(0x10)
+
+#define ETHER_TX_CTL(base)							(ETHER00_TYPE (base + 0x8))
+#define ETHER_TX_CTL_TXEN_OFST					(0)
+#define ETHER_TX_CTL_TXEN_MSK					(0x1)
+#define ETHER_TX_CTL_TXHALT_OFST				(1)
+#define ETHER_TX_CTL_TXHALT_MSK					(0x2)
+#define ETHER_TX_CTL_NOPAD_OFST					(2)
+#define ETHER_TX_CTL_NOPAD_MSK					(0x4)
+#define ETHER_TX_CTL_NOCRC_OFST					(3)
+#define ETHER_TX_CTL_NOCRC_MSK					(0x8)
+#define ETHER_TX_CTL_FBACK_OFST					(4)
+#define ETHER_TX_CTL_FBACK_MSK					(0x10)
+#define ETHER_TX_CTL_NOEXDEF_OFST				(5)
+#define ETHER_TX_CTL_NOEXDEF_MSK				(0x20)
+#define ETHER_TX_CTL_SDPAUSE_OFST				(6)
+#define ETHER_TX_CTL_SDPAUSE_MSK				(0x40)
+#define ETHER_TX_CTL_MII10_OFST					(7)
+#define ETHER_TX_CTL_MII10_MSK					(0x80)
+#define ETHER_TX_CTL_ENUNDER_OFST				(8)
+#define ETHER_TX_CTL_ENUNDER_MSK				(0x100)
+#define ETHER_TX_CTL_ENEXDEFER_OFST				(9)
+#define ETHER_TX_CTL_ENEXDEFER_MSK				(0x200)
+#define ETHER_TX_CTL_ENLCARR_OFST				(10)
+#define ETHER_TX_CTL_ENLCARR_MSK				(0x400)
+#define ETHER_TX_CTL_ENEXCOLL_OFST				(11)
+#define ETHER_TX_CTL_ENEXCOLL_MSK				(0x800)
+#define ETHER_TX_CTL_ENLATECOLL_OFST				(12)
+#define ETHER_TX_CTL_ENLATECOLL_MSK				(0x1000)
+#define ETHER_TX_CTL_ENTXPAR_OFST				(13)
+#define ETHER_TX_CTL_ENTXPAR_MSK				(0x2000)
+#define ETHER_TX_CTL_ENCOMP_OFST				(14)
+#define ETHER_TX_CTL_ENCOMP_MSK					(0x4000)
+
+#define ETHER_TX_STAT(base)							(ETHER00_TYPE (base + 0xc))
+#define ETHER_TX_STAT_TXCOLL_OFST				(0)
+#define ETHER_TX_STAT_TXCOLL_MSK				(0xF)
+#define ETHER_TX_STAT_EXCOLL_OFST				(4)
+#define ETHER_TX_STAT_EXCOLL_MSK				(0x10)
+#define ETHER_TX_STAT_TXDEFER_OFST				(5)
+#define ETHER_TX_STAT_TXDEFER_MSK				(0x20)
+#define ETHER_TX_STAT_PAUSED_OFST				(6)
+#define ETHER_TX_STAT_PAUSED_MSK				(0x40)
+#define ETHER_TX_STAT_INTTX_OFST				(7)
+#define ETHER_TX_STAT_INTTX_MSK					(0x80)
+#define ETHER_TX_STAT_UNDER_OFST				(8)
+#define ETHER_TX_STAT_UNDER_MSK					(0x100)
+#define ETHER_TX_STAT_EXDEFER_OFST				(9)
+#define ETHER_TX_STAT_EXDEFER_MSK				(0x200)
+#define ETHER_TX_STAT_LCARR_OFST				(10)
+#define ETHER_TX_STAT_LCARR_MSK					(0x400)
+#define ETHER_TX_STAT_TX10STAT_OFST				(11)
+#define ETHER_TX_STAT_TX10STAT_MSK				(0x800)
+#define ETHER_TX_STAT_LATECOLL_OFST				(12)
+#define ETHER_TX_STAT_LATECOLL_MSK				(0x1000)
+#define ETHER_TX_STAT_TXPAR_OFST				(13)
+#define ETHER_TX_STAT_TXPAR_MSK					(0x2000)
+#define ETHER_TX_STAT_COMP_OFST					(14)
+#define ETHER_TX_STAT_COMP_MSK					(0x4000)
+#define ETHER_TX_STAT_TXHALTED_OFST				(15)
+#define ETHER_TX_STAT_TXHALTED_MSK				(0x8000)
+#define ETHER_TX_STAT_SQERR_OFST				(16)
+#define ETHER_TX_STAT_SQERR_MSK					(0x10000)
+#define ETHER_TX_STAT_TXMCAST_OFST				(17)
+#define ETHER_TX_STAT_TXMCAST_MSK				(0x20000)
+#define ETHER_TX_STAT_TXBCAST_OFST				(18)
+#define ETHER_TX_STAT_TXBCAST_MSK				(0x40000)
+#define ETHER_TX_STAT_VLAN_OFST					(19)
+#define ETHER_TX_STAT_VLAN_MSK					(0x80000)
+#define ETHER_TX_STAT_MACC_OFST					(20)
+#define ETHER_TX_STAT_MACC_MSK					(0x100000)
+#define ETHER_TX_STAT_TXPAUSE_OFST				(21)
+#define ETHER_TX_STAT_TXPAUSE_MSK				(0x200000)
+
+#define ETHER_RX_CTL(base)							(ETHER00_TYPE (base + 0x10))
+#define ETHER_RX_CTL_RXEN_OFST					(0)
+#define ETHER_RX_CTL_RXEN_MSK					(0x1)
+#define ETHER_RX_CTL_RXHALT_OFST				(1)
+#define ETHER_RX_CTL_RXHALT_MSK					(0x2)
+#define ETHER_RX_CTL_LONGEN_OFST				(2)
+#define ETHER_RX_CTL_LONGEN_MSK					(0x4)
+#define ETHER_RX_CTL_SHORTEN_OFST				(3)
+#define ETHER_RX_CTL_SHORTEN_MSK				(0x8)
+#define ETHER_RX_CTL_STRIPCRC_OFST				(4)
+#define ETHER_RX_CTL_STRIPCRC_MSK				(0x10)
+#define ETHER_RX_CTL_PASSCTL_OFST				(5)
+#define ETHER_RX_CTL_PASSCTL_MSK				(0x20)
+#define ETHER_RX_CTL_IGNORECRC_OFST				(6)
+#define ETHER_RX_CTL_IGNORECRC_MSK				(0x40)
+#define ETHER_RX_CTL_ENALIGN_OFST				(8)
+#define ETHER_RX_CTL_ENALIGN_MSK				(0x100)
+#define ETHER_RX_CTL_ENCRCERR_OFST				(9)
+#define ETHER_RX_CTL_ENCRCERR_MSK				(0x200)
+#define ETHER_RX_CTL_ENOVER_OFST				(10)
+#define ETHER_RX_CTL_ENOVER_MSK					(0x400)
+#define ETHER_RX_CTL_ENLONGERR_OFST				(11)
+#define ETHER_RX_CTL_ENLONGERR_MSK				(0x800)
+#define ETHER_RX_CTL_ENRXPAR_OFST				(13)
+#define ETHER_RX_CTL_ENRXPAR_MSK				(0x2000)
+#define ETHER_RX_CTL_ENGOOD_OFST				(14)
+#define ETHER_RX_CTL_ENGOOD_MSK					(0x4000)
+
+#define ETHER_RX_STAT(base)							(ETHER00_TYPE (base + 0x14))
+#define ETHER_RX_STAT_LENERR_OFST				(4)
+#define ETHER_RX_STAT_LENERR_MSK				(0x10)
+#define ETHER_RX_STAT_CTLRECD_OFST				(5)
+#define ETHER_RX_STAT_CTLRECD_MSK				(0x20)
+#define ETHER_RX_STAT_INTRX_OFST				(6)
+#define ETHER_RX_STAT_INTRX_MSK					(0x40)
+#define ETHER_RX_STAT_RX10STAT_OFST				(7)
+#define ETHER_RX_STAT_RX10STAT_MSK				(0x80)
+#define ETHER_RX_STAT_ALIGNERR_OFST				(8)
+#define ETHER_RX_STAT_ALIGNERR_MSK				(0x100)
+#define ETHER_RX_STAT_CRCERR_OFST				(9)
+#define ETHER_RX_STAT_CRCERR_MSK				(0x200)
+#define ETHER_RX_STAT_OVERFLOW_OFST				(10)
+#define ETHER_RX_STAT_OVERFLOW_MSK				(0x400)
+#define ETHER_RX_STAT_LONGERR_OFST				(11)
+#define ETHER_RX_STAT_LONGERR_MSK				(0x800)
+#define ETHER_RX_STAT_RXPAR_OFST				(13)
+#define ETHER_RX_STAT_RXPAR_MSK					(0x2000)
+#define ETHER_RX_STAT_GOOD_OFST					(14)
+#define ETHER_RX_STAT_GOOD_MSK					(0x4000)
+#define ETHER_RX_STAT_RXHALTED_OFST				(15)
+#define ETHER_RX_STAT_RXHALTED_MSK				(0x8000)
+#define ETHER_RX_STAT_RXMCAST_OFST				(17)
+#define ETHER_RX_STAT_RXMCAST_MSK				(0x10000)
+#define ETHER_RX_STAT_RXBCAST_OFST				(18)
+#define ETHER_RX_STAT_RXBCAST_MSK				(0x20000)
+#define ETHER_RX_STAT_RXVLAN_OFST				(19)
+#define ETHER_RX_STAT_RXVLAN_MSK				(0x40000)
+#define ETHER_RX_STAT_RXPAUSE_OFST				(20)
+#define ETHER_RX_STAT_RXPAUSE_MSK				(0x80000)
+#define ETHER_RX_STAT_ARCSTATUS_OFST				(21)
+#define ETHER_RX_STAT_ARCSTATUS_MSK				(0xF00000)
+#define ETHER_RX_STAT_ARCENT_OFST				(25)
+#define ETHER_RX_STAT_ARCENT_MSK				(0x1F000000)
+
+#define ETHER_MD_DATA(base)							(ETHER00_TYPE (base + 0x18))
+
+#define ETHER_MD_CA(base)								(ETHER00_TYPE (base + 0x1c))
+#define ETHER_MD_CA_ADDR_OFST					(0)
+#define ETHER_MD_CA_ADDR_MSK					(0x1F)
+#define ETHER_MD_CA_PHY_OFST					(5)
+#define ETHER_MD_CA_PHY_MSK					(0x3E0)
+#define ETHER_MD_CA_WR_OFST					(10)
+#define ETHER_MD_CA_WR_MSK					(0x400)
+#define ETHER_MD_CA_BUSY_OFST					(11)
+#define ETHER_MD_CA_BUSY_MSK					(0x800)
+#define ETHER_MD_CA_PRESUPP_OFST				(12)
+#define ETHER_MD_CA_PRESUPP_MSK					(0x1000)
+
+#define ETHER_ARC_ADR(base)	      (ETHER00_TYPE (base + 0x160))
+#define ETHER_ARC_ADR_ARC_LOC_OFST				(2)
+#define ETHER_ARC_ADR_ARC_LOC_MSK				(0xFFC)
+
+#define ETHER_ARC_DATA(base)  (ETHER00_TYPE (base + 0x364))
+
+#define ETHER_ARC_ENA(base)   (ETHER00_TYPE (base + 0x28))
+#define ETHER_ARC_ENA_MSK					(0x1FFFFF)
+
+#define ETHER_PROM_CTL(base)							(ETHER00_TYPE (base + 0x2c))
+#define ETHER_PROM_CTL_PROM_ADDR_OFST			(0)
+#define ETHER_PROM_CTL_PROM_ADDR_MSK			(0x3F)
+#define ETHER_PROM_CTL_OPCODE_OFST				(13)
+#define ETHER_PROM_CTL_OPCODE_MSK				(0x6000)
+#define ETHER_PROM_CTL_OPCODE_READ_MSK			(0x4000)
+#define ETHER_PROM_CTL_OPCODE_WRITE_MSK			(0x2000)
+#define ETHER_PROM_CTL_OPCODE_ERASE_MSK			(0x6000)
+#define ETHER_PROM_CTL_ENABLE_MSK				(0x0030)
+#define ETHER_PROM_CTL_DISABLE_MSK				(0x0000)
+#define ETHER_PROM_CTL_BUSY_OFST				(15)
+#define ETHER_PROM_CTL_BUSY_MSK					(0x8000)
+
+#define ETHER_PROM_DATA(base)							(ETHER00_TYPE (base + 0x30))
+
+#define ETHER_MISS_CNT(base)							(ETHER00_TYPE (base + 0x3c))
+#define ETHER_MISS_CNT_COUNT_OFST				(0)
+#define ETHER_MISS_CNT_COUNT_MSK				(0xFFFF)
+
+#define ETHER_CNTDATA(base)							(ETHER00_TYPE (base + 0x80))
+
+#define ETHER_CNTACC(base)							(ETHER00_TYPE (base + 0x84))
+#define ETHER_CNTACC_ADDR_OFST					(0)
+#define ETHER_CNTACC_ADDR_MSK					(0xFF)
+#define ETHER_CNTACC_WRRDN_OFST					(8)
+#define ETHER_CNTACC_WRRDN_MSK					(0x100)
+#define ETHER_CNTACC_CLEAR_OFST					(9)
+#define ETHER_CNTACC_CLEAR_MSK					(0x200)
+
+#define ETHER_TXRMINTEN(base)							(ETHER00_TYPE (base + 0x88))
+#define ETHER_TXRMINTEN_MSK						(0x3FFFFFFF)
+
+#define ETHER_RXRMINTEN(base)							(ETHER00_TYPE (base + 0x8C))
+#define ETHER_RXRMINTEN_MSK						(0xFFFFFF)
+
+/*
+*	RMON Registers
+*/
+#define		RMON_COLLISION0						0x0
+#define		RMON_COLLISION1						0x1
+#define		RMON_COLLISION2						0x2
+#define		RMON_COLLISION3						0x3
+#define		RMON_COLLISION4						0x4
+#define		RMON_COLLISION5						0x5
+#define		RMON_COLLISION6						0x6
+#define		RMON_COLLISION7						0x7
+#define		RMON_COLLISION8						0x8
+#define		RMON_COLLISION9						0x9
+#define		RMON_COLLISION10					0xa
+#define		RMON_COLLISION11					0xb
+#define		RMON_COLLISION12					0xc
+#define		RMON_COLLISION13					0xd
+#define		RMON_COLLISION14					0xe
+#define		RMON_COLLISION15					0xf
+#define		RMON_COLLISION16					0x10
+#define		RMON_FRAMES_WITH_DEFERRED_XMISSIONS	0x11
+#define		RMON_LATE_COLLISIONS				0x12
+#define		RMON_FRAMES_LOST_DUE_TO_MAC_XMIT	0x13
+#define		RMON_CARRIER_SENSE_ERRORS			0x14
+#define		RMON_FRAMES_WITH_EXCESSIVE_DEFERAL	0x15
+#define		RMON_UNICAST_FRAMES_TRANSMITTED_OK	0x16
+#define		RMON_MULTICAST_FRAMES_XMITTED_OK	0x17
+#define		RMON_BROADCAST_FRAMES_XMITTED_OK	0x18
+#define		RMON_SQE_TEST_ERRORS				0x19
+#define		RMON_PAUSE_MACCTRL_FRAMES_XMITTED	0x1A
+#define		RMON_MACCTRL_FRAMES_XMITTED			0x1B
+#define		RMON_VLAN_FRAMES_XMITTED			0x1C
+#define		RMON_OCTETS_XMITTED_OK				0x1D
+#define		RMON_OCTETS_XMITTED_OK_HI			0x1E
+
+#define		RMON_RX_PACKET_SIZES0				0x40
+#define		RMON_RX_PACKET_SIZES1				0x41
+#define		RMON_RX_PACKET_SIZES2				0x42
+#define		RMON_RX_PACKET_SIZES3				0x43
+#define		RMON_RX_PACKET_SIZES4				0x44
+#define		RMON_RX_PACKET_SIZES5				0x45
+#define		RMON_RX_PACKET_SIZES6				0x46
+#define		RMON_RX_PACKET_SIZES7				0x47
+#define		RMON_FRAME_CHECK_SEQUENCE_ERRORS	0x48
+#define		RMON_ALIGNMENT_ERRORS				0x49
+#define		RMON_FRAGMENTS						0x4A
+#define		RMON_JABBERS						0x4B
+#define		RMON_FRAMES_LOST_TO_INTMACRCVERR	0x4C
+#define		RMON_UNICAST_FRAMES_RCVD_OK			0x4D
+#define		RMON_MULTICAST_FRAMES_RCVD_OK		0x4E
+#define		RMON_BROADCAST_FRAMES_RCVD_OK		0x4F
+#define		RMON_IN_RANGE_LENGTH_ERRORS			0x50
+#define		RMON_OUT_OF_RANGE_LENGTH_ERRORS		0x51
+#define		RMON_VLAN_FRAMES_RCVD				0x52
+#define		RMON_PAUSE_MAC_CTRL_FRAMES_RCVD		0x53
+#define		RMON_MAC_CTRL_FRAMES_RCVD			0x54
+#define		RMON_OCTETS_RCVD_OK					0x55
+#define		RMON_OCTETS_RCVD_OK_HI				0x56
+#define		RMON_OCTETS_RCVD_OTHER				0x57
+#define		RMON_OCTETS_RCVD_OTHER_HI			0x58
+
+#endif /* __ETHER00_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-epxa10db/io.h linux/include/asm-arm/arch-epxa10db/io.h
--- linux.orig/include/asm-arm/arch-epxa10db/io.h	2001-10-25 20:53:53.000000000 +0000
+++ linux/include/asm-arm/arch-epxa10db/io.h	2002-07-20 01:08:40.000000000 +0000
@@ -36,20 +36,11 @@
 #define insl    __arch_readsl*/
 
 #define __io(a)			(a)
-#if 0
-#define __mem_pci(a)		((unsigned long)(a))
-#define __mem_isa(a)		(PCI_MEMORY_VADDR + (unsigned long)(a))
-/*
- * Validate the pci memory address for ioremap.
- */
-#define iomem_valid_addr(iomem,size)	\
-	((iomem) > 0 && (iomem) + (size) <= 0x20000000)
+#define __mem_pci(a)            (a) 
+#define __arch_getw(a)			(*(volatile unsigned short  *)(a))
+#define __arch_putw(v,a)		(*(volatile unsigned short *)(a) = (v))
+#define iomem_valid_addr(off,size) (1)
+#define iomem_to_phys(off) (off)
 
-/*
- * Convert PCI memory space to a CPU physical address
- */
-#define iomem_to_phys(iomem)	((iomem) + PHYS_PCI_MEM_BASE)
-
-#endif
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-epxa10db/tdkphy.h linux/include/asm-arm/arch-epxa10db/tdkphy.h
--- linux.orig/include/asm-arm/arch-epxa10db/tdkphy.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-epxa10db/tdkphy.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,209 @@
+/*
+ *  linux/drivers/tdkphy.h
+ *
+ *  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
+ */
+
+#ifndef __TDKPHY_H
+#define __TDKPHY_H
+
+/*
+ * Register definitions for the TDK 78Q2120 PHY 
+ * which is on the Camelot board
+ */
+
+/*
+ * Copyright (c) Altera Corporation 2000.
+ * All rights reserved.
+ */
+#define PHY_CONTROL                                                                                     (0)
+#define PHY_CONTROL_COLT_MSK                                                            (0x80)
+#define PHY_CONTROL_COLT_OFST                                                           (7)
+#define PHY_CONTROL_DUPLEX_MSK                                                          (0x100)
+#define PHY_CONTROL_DUPLEX_OFST                                                         (8)
+#define PHY_CONTROL_RANEG_MSK                                                           (0x200)
+#define PHY_CONTROL_RANEG_OFST                                                          (9)
+#define PHY_CONTROL_ISO_MSK                                                                     (0x400)
+#define PHY_CONTROL_ISO_OFST                                                            (10)
+#define PHY_CONTROL_PWRDN_MSK                                                           (0x800)
+#define PHY_CONTROL_PWRDN_OFST                                                          (11)
+#define PHY_CONTROL_ANEGEN_MSK                                                          (0x1000)
+#define PHY_CONTROL_ANEGEN_OFST                                                         (12)
+#define PHY_CONTROL_SPEEDSL_MSK                                                         (0x2000)
+#define PHY_CONTROL_SPEEDSL_OFST                                                        (13)
+#define PHY_CONTROL_LOOPBK_MSK                                                          (0x4000)
+#define PHY_CONTROL_LOOPBK_OFST                                                         (14)
+#define PHY_CONTROL_RESET_MSK                                                           (0x8000)
+#define PHY_CONTROL_RESET_OFST                                                          (15)
+
+#define PHY_STATUS                                                                                      (1)
+#define PHY_STATUS_ETXD_MSK                                                                     (0x1)
+#define PHY_STATUS_EXTD_OFST                                                            (0)
+#define PHY_STATUS_JAB_MSK                                                                      (0x2)
+#define PHY_STATUS_JAB_OFST                                                                     (1)
+#define PHY_STATUS_LINK_MSK                                                                     (0x4)
+#define PHY_STATUS_LINK_OFST                                                            (2)
+#define PHY_STATUS_ANEGA_MSK                                                            (0x8)
+#define PHY_STATUS_ANEGA_OFST                                                           (3)
+#define PHY_STATUS_RFAULT_MSK                                                           (0x10)
+#define PHY_STATUS_RFAULT_OFST                                                          (4)
+#define PHY_STATUS_ANEGC_MSK                                                            (0x20)
+#define PHY_STATUS_ANEGC_OFST                                                           (5)
+#define PHY_STATUS_10T_H_MSK                                                            (0x800)
+#define PHY_STATUS_10T_H_OFST                                                           (11)
+#define PHY_STATUS_10T_F_MSK                                                            (0x1000)
+#define PHY_STATUS_10T_F_OFST                                                           (12)
+#define PHY_STATUS_100_X_H_MSK                                                          (0x2000)
+#define PHY_STATUS_100_X_H_OFST                                                         (13)
+#define PHY_STATUS_100_X_F_MSK                                                          (0x4000)
+#define PHY_STATUS_100_X_F_OFST                                                         (14)
+#define PHY_STATUS_100T4_MSK                                                            (0x8000)
+#define PHY_STATUS_100T4_OFST                                                           (15)
+
+#define PHY_ID1                                                                                         (2)
+#define PHY_ID1_OUI_MSK                                                                         (0xFFFF)
+#define PHY_ID1_OUI_OFST                                                                        (0)
+
+#define PHY_ID2                                                                                         (3)
+#define PHY_ID2_RN_MSK                                                                          (0xF)
+#define PHY_ID2_RN_OFST                                                                         (0)
+#define PHY_ID2_MN_MSK                                                                          (0x3F0)
+#define PHY_ID2_MN_OFST                                                                         (4)
+#define PHY_ID2_OUI_MSK                                                                         (0xFC00)
+#define PHY_ID2_OUI_OFST                                                                        (10)
+
+#define PHY_AUTO_NEG_ADVERTISEMENT                                                      (4)
+#define PHY_AUTO_NEG_ADVERTISEMENT_SELECTOR_MSK                         (0x1F)
+#define PHY_AUTO_NEG_ADVERTISEMENT_SELECTOR_OFST                        (0)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A0_MSK                                       (0x20)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A0_OFST                                      (5)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A1_MSK                                       (0x40)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A1_OFST                                      (6)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A2_MSK                                       (0x80)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A2_OFST                                      (7)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A3_MSK                                       (0x100)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A3_OFST                                      (8)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A4_MSK                                       (0x200)
+#define PHY_AUTO_NEG_ADVERTISEMENT_A4_OFST                                      (9)
+#define PHY_AUTO_NEG_ADVERTISEMENT_TAF_MSK                                      (0x1FE0)
+#define PHY_AUTO_NEG_ADVERTISEMENT_TAF_OFST                                     (5)
+#define PHY_AUTO_NEG_ADVERTISEMENT_RF_MSK                                       (0x2000)
+#define PHY_AUTO_NEG_ADVERTISEMENT_RF_OFST                                      (13)
+#define PHY_AUTO_NEG_ADVERTISEMENT_RSVD_MSK                                     (0x4000)
+#define PHY_AUTO_NEG_ADVERTISEMENT_RVSD_OFST                            (14)
+#define PHY_AUTO_NEG_ADVERTISEMENT_NP_MSK                                       (0x8000)
+#define PHY_AUTO_NEG_ADVERTISEMENT_NP_OFST                                      (15)
+
+#define PHY_AUTO_NEG_LINK_PARTNER                                                       (5)
+#define PHY_AUTO_NEG_LINK_PARTNER_S4_MSK                                        (0x1F)
+#define PHY_AUTO_NEG_LINK_PARTNER_S4_OFST                                       (0)
+#define PHY_AUTO_NEG_LINK_PARTNER_A7_MSK                                        (0x1FE0)
+#define PHY_AUTO_NEG_LINK_PARTNER_A7_OFST                                       (5)
+#define PHY_AUTO_NEG_LINK_PARTNER_RF_MSK                                        (0x2000)
+#define PHY_AUTO_NEG_LINK_PARTNER_RF_OFST                                       (13)
+#define PHY_AUTO_NEG_LINK_PARTNER_ACK_MSK                                       (0x4000)
+#define PHY_AUTO_NEG_LINK_PARTNER_ACK_OFST                                      (14)
+#define PHY_AUTO_NEG_LINK_PARTNER_NP_MSK                                        (0x8000)
+#define PHY_AUTO_NEG_LINK_PARTNER_NP_OFST                                       (15)
+
+#define PHY_AUTO_NEG_EXPANSION                                                          (6)
+#define PHY_AUTO_NEG_EXPANSION_LPANEGA_MSK                                      (0x1)
+#define PHY_AUTO_NEG_EXPANSION_LPANEGA_OFST                                     (0)
+#define PHY_AUTO_NEG_EXPANSION_PRX_MSK                                          (0x2)
+#define PHY_AUTO_NEG_EXPANSION_PRX_OFST                                         (1)
+#define PHY_AUTO_NEG_EXPANSION_NPA_MSK                                          (0x4)
+#define PHY_AUTO_NEG_EXPANSION_NPA_OFST                                         (2)
+#define PHY_AUTO_NEG_EXPANSION_LPNPA_MSK                                        (0x8)
+#define PHY_AUTO_NEG_EXPANSION_LPNPA_OFST                                       (3)
+#define PHY_AUTO_NEG_EXPANSION_PDF_MSK                                          (0x10)
+#define PHY_AUTO_NEG_EXPANSION_PDF_OFST                                         (4)
+
+#define PHY_VENDOR_SPECIFIC                                                                     (16)
+#define PHY_VENDOR_SPECIFIC_RXCC_MSK                                            (0x1)
+#define PHY_VENDOR_SPECIFIC_RXCC_OFST                                           (0)
+#define PHY_VENDOR_SPECIFIC_PCSBP_MSK                                           (0x2)
+#define PHY_VENDOR_SPECIFIC_PCSBP_OFST                                          (1)
+#define PHY_VENDOR_SPECIFIC_RVSPOL_MSK                                          (0x10)
+#define PHY_VENDOR_SPECIFIC_RVSPOL_OFST                                         (4)
+#define PHY_VENDOR_SPECIFIC_APOL_MSK                                            (0x20)  
+#define PHY_VENDOR_SPECIFIC_APOL_OFST                                           (5)
+#define PHY_VENDOR_SPECIFIC_GPIO0_DIR_MSK                                       (0x40)
+#define PHY_VENDOR_SPECIFIC_GPIO0_DIR_OFST                                      (6)
+#define PHY_VENDOR_SPECIFIC_GPIO0_DAT_MSK                                       (0x80)
+#define PHY_VENDOR_SPECIFIC_GPIO0_DAT_OFST                                      (7)
+#define PHY_VENDOR_SPECIFIC_GPIO1_DIR_MSK                                       (0x100)
+#define PHY_VENDOR_SPECIFIC_GPIO1_DIR_OFST                                      (8)
+#define PHY_VENDOR_SPECIFIC_GPIO1_DAT_MSK                                       (0x200)
+#define PHY_VENDOR_SPECIFIC_GPIO1_DAT_OFST                                      (9)
+#define PHY_VENDOR_SPECIFIC_10BT_NATURAL_LOOPBACK_DAT_MSK       (0x400)
+#define PHY_VENDOR_SPECIFIC_10BT_NATURAL_LOOPBACK_DAT_OFST      (10)
+#define PHY_VENDOR_SPECIFIC_10BT_SQE_TEST_INHIBIT_MSK           (0x800)
+#define PHY_VENDOR_SPECIFIC_10BT_SQE_TEST_INHIBIT_OFST          (11)
+#define PHY_VENDOR_SPECIFIC_TXHIM_MSK                                           (0x1000)
+#define PHY_VENDOR_SPECIFIC_TXHIM_OFST                                          (12)
+#define PHY_VENDOR_SPECIFIC_INT_LEVEL_MSK                                       (0x4000)
+#define PHY_VENDOR_SPECIFIC_INT_LEVEL_OFST                                      (14)
+#define PHY_VENDOR_SPECIFIC_RPTR_MSK                                            (0x8000)
+#define PHY_VENDOR_SPECIFIC_RPTR_OFST                                           (15)
+
+#define PHY_IRQ_CONTROL                                                                         (17)
+#define PHY_IRQ_CONTROL_ANEG_COMP_INT_MSK                                       (0x1)
+#define PHY_IRQ_CONTROL_ANEG_COMP_INT_OFST                                      (0)
+#define PHY_IRQ_CONTROL_RFAULT_INT_MSK                                          (0x2)
+#define PHY_IRQ_CONTROL_RFAULT_INT_OFST                                         (1)
+#define PHY_IRQ_CONTROL_LS_CHG_INT_MSK                                          (0x4)
+#define PHY_IRQ_CONTROL_LS_CHG_INT_OFST                                         (2)
+#define PHY_IRQ_CONTROL_LP_ACK_INT_MSK                                          (0x8)
+#define PHY_IRQ_CONTROL_LP_ACK_INT_OFST                                         (3)
+#define PHY_IRQ_CONTROL_PDF_INT_MSK                                                     (0x10)
+#define PHY_IRQ_CONTROL_PDF_INT_OFST                                            (4)
+#define PHY_IRQ_CONTROL_PRX_INT_MSK                                                     (0x20)
+#define PHY_IRQ_CONTROL_PRX_INT_OFST                                            (5)
+#define PHY_IRQ_CONTROL_RXER_INT_MSK                                            (0x40)
+#define PHY_IRQ_CONTROL_RXER_INT_OFST                                           (6)
+#define PHY_IRQ_CONTROL_JABBER_INT_MSK                                          (0x80)
+#define PHY_IRQ_CONTROL_JABBER_INT_OFST                                         (7)
+#define PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK                                        (0x100)
+#define PHY_IRQ_CONTROL_ANEG_COMP_IE_OFST                                       (8)
+#define PHY_IRQ_CONTROL_RFAULT_IE_MSK                                           (0x200)
+#define PHY_IRQ_CONTROL_RFAULT_IE_OFST                                          (9)
+#define PHY_IRQ_CONTROL_LS_CHG_IE_MSK                                           (0x400)
+#define PHY_IRQ_CONTROL_LS_CHG_IE_OFST                                          (10)
+#define PHY_IRQ_CONTROL_LP_ACK_IE_MSK                                           (0x800)
+#define PHY_IRQ_CONTROL_LP_ACK_IE_OFST                                          (11)
+#define PHY_IRQ_CONTROL_PDF_IE_MSK                                                      (0x1000)
+#define PHY_IRQ_CONTROL_PDF_IE_OFST                                                     (12)
+#define PHY_IRQ_CONTROL_PRX_IE_MSK                                                      (0x2000)
+#define PHY_IRQ_CONTROL_PRX_IE_OFST                                                     (13)
+#define PHY_IRQ_CONTROL_RXER_IE_MSK                                                     (0x4000)
+#define PHY_IRQ_CONTROL_RXER_IE_OFST                                            (14)
+#define PHY_IRQ_CONTROL_JABBER_IE_MSK                                           (0x8000)
+#define PHY_IRQ_CONTROL_JABBER_IE_OFST                                          (15)
+
+#define PHY_DIAGNOSTIC                                                                          (18)
+#define PHY_DIAGNOSTIC_RX_LOCK_MSK                                                      (0x100)
+#define PHY_DIAGNOSTIC_RX_LOCK_OFST                                                     (8)
+#define PHY_DIAGNOSTIC_RX_PASS_MSK                                                      (0x200)
+#define PHY_DIAGNOSTIC_RX_PASS_OFST                                                     (9)
+#define PHY_DIAGNOSTIC_RATE_MSK                                                         (0x400)
+#define PHY_DIAGNOSTIC_RATE_OFST                                                        (10)
+#define PHY_DIAGNOSTIC_DPLX_MSK                                                         (0x800)
+#define PHY_DIAGNOSTIC_DPLX_OFST                                                        (11)
+#define PHY_DIAGNOSTIC_ANEGF_MSK                                                        (0x1000)
+#define PHY_DIAGNOSTIC_ANEGF_OFST                                                       (12)
+
+#endif /* __TDKPHY_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-epxa10db/time.h linux/include/asm-arm/arch-epxa10db/time.h
--- linux.orig/include/asm-arm/arch-epxa10db/time.h	2001-10-25 20:53:53.000000000 +0000
+++ linux/include/asm-arm/arch-epxa10db/time.h	2002-07-20 01:08:36.000000000 +0000
@@ -55,7 +55,7 @@
 	setup_arm_irq(IRQ_TIMER0, &timer_irq);
 
 	/* Start the timer */
-	*TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/50);
+	*TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
 	*TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1;
 	*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-epxa10db/uncompress.h linux/include/asm-arm/arch-epxa10db/uncompress.h
--- linux.orig/include/asm-arm/arch-epxa10db/uncompress.h	2001-10-25 20:53:53.000000000 +0000
+++ linux/include/asm-arm/arch-epxa10db/uncompress.h	2002-07-20 01:08:32.000000000 +0000
@@ -29,14 +29,18 @@
 static void puts(const char *s)
 {
 	while (*s) {
-		while ((*UART_TSR(IO_ADDRESS(EXC_UART00_BASE)) & UART_TSR_TX_LEVEL_MSK)==15);
+		while ((*UART_TSR(EXC_UART00_BASE) &
+		       UART_TSR_TX_LEVEL_MSK)==15);
+			barrier();
 
-		*UART_TD(IO_ADDRESS(EXC_UART00_BASE)) = *s;
+		*UART_TD(EXC_UART00_BASE) = *s;
 
 		if (*s == '\n') {
-		while ((*UART_TSR(IO_ADDRESS(EXC_UART00_BASE)) & UART_TSR_TX_LEVEL_MSK)==15);
+			while ((*UART_TSR(EXC_UART00_BASE) &
+			       UART_TSR_TX_LEVEL_MSK)==15);
+				barrier();
 
-			*UART_TD(IO_ADDRESS(EXC_UART00_BASE)) = '\r';
+			*UART_TD(EXC_UART00_BASE) = '\r';
 		}
 		s++;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-integrator/system.h linux/include/asm-arm/arch-integrator/system.h
--- linux.orig/include/asm-arm/arch-integrator/system.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/arch-integrator/system.h	2002-07-20 01:08:22.000000000 +0000
@@ -21,6 +21,8 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <asm/hardware.h>
+#include <asm/io.h>
 #include <asm/arch/platform.h>
 
 static void arch_idle(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-integrator/uncompress.h linux/include/asm-arm/arch-integrator/uncompress.h
--- linux.orig/include/asm-arm/arch-integrator/uncompress.h	2001-03-03 02:38:39.000000000 +0000
+++ linux/include/asm-arm/arch-integrator/uncompress.h	2002-07-20 01:08:35.000000000 +0000
@@ -31,12 +31,14 @@
 static void puts(const char *s)
 {
 	while (*s) {
-		while (AMBA_UART_FR & (1 << 5));
+		while (AMBA_UART_FR & (1 << 5))
+			barrier();
 
 		AMBA_UART_DR = *s;
 
 		if (*s == '\n') {
-			while (AMBA_UART_FR & (1 << 5));
+			while (AMBA_UART_FR & (1 << 5))
+				barrier();
 
 			AMBA_UART_DR = '\r';
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-l7200/uncompress.h linux/include/asm-arm/arch-l7200/uncompress.h
--- linux.orig/include/asm-arm/arch-l7200/uncompress.h	2000-08-13 16:54:15.000000000 +0000
+++ linux/include/asm-arm/arch-l7200/uncompress.h	2002-07-20 01:08:40.000000000 +0000
@@ -19,7 +19,8 @@
 static __inline__ void putc(char c)
 {
 	while(__raw_readb(IO_UART + 0x18) & 0x20 ||
-		__raw_readb(IO_UART + 0x18) & 0x08);
+	      __raw_readb(IO_UART + 0x18) & 0x08)
+		barrier();
 	__raw_writeb(c, IO_UART + 0x00);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/dma.h linux/include/asm-arm/arch-mx1ads/dma.h
--- linux.orig/include/asm-arm/arch-mx1ads/dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/dma.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-arm/mx1ads/dma.h
+ *
+ *  Copyright (C) 1997,1998 Russell King
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/hardware.h linux/include/asm-arm/arch-mx1ads/hardware.h
--- linux.orig/include/asm-arm/arch-mx1ads/hardware.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/hardware.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,38 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/hardware.h
+ *
+ *  Copyright (C) 1999 ARM Limited.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <asm/arch/platform.h>
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+#define IO_BASE			0xF0000000                 // VA of IO
+#define IO_SIZE			0x0B000000                 // How much?
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(x) (x | IO_BASE)
+
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/io.h linux/include/asm-arm/arch-mx1ads/io.h
--- linux.orig/include/asm-arm/arch-mx1ads/io.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/io.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/io.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffff
+
+
+#define __io(a)			((a))
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Validate the pci memory address for ioremap.
+ */
+#define iomem_valid_addr(iomem,size)	(1)
+
+/*
+ * Convert PCI memory space to a CPU physical address
+ */
+#define iomem_to_phys(iomem)	(iomem)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/irq.h linux/include/asm-arm/arch-mx1ads/irq.h
--- linux.orig/include/asm-arm/arch-mx1ads/irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/irq.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,20 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/irq.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+#define fixup_irq(i)	(i)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/irqs.h linux/include/asm-arm/arch-mx1ads/irqs.h
--- linux.orig/include/asm-arm/arch-mx1ads/irqs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/irqs.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/irqs.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  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
+ */
+
+#ifndef __ARM_IRQS_H__
+#define __ARM_IRQS_H__
+
+/* Use the mx1ads definitions */
+#include <asm/arch/platform.h>
+
+/*
+ * Well, that's about all we need I think.
+ */
+#define NR_IRQS                         (MAXIRQNUM + 1)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/keyboard.h linux/include/asm-arm/arch-mx1ads/keyboard.h
--- linux.orig/include/asm-arm/arch-mx1ads/keyboard.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/keyboard.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,11 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/keyboard.h
+ *
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * Well..., what did you expect?, it's not really there :)
+ *
+ */
+#define kbd_init_hw()           do { } while (0)
+#define kbd_enable_irq()        do { } while (0)
+#define kbd_disable_irq()       do { } while (0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/memory.h linux/include/asm-arm/arch-mx1ads/memory.h
--- linux.orig/include/asm-arm/arch-mx1ads/memory.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/memory.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,75 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/memory.h
+ *
+ *  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
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB
+ */
+/* Note
+ * This should be hot-swapable with a CONFIG_MX1ADS_SDRAM
+ * or something similar, so we can swap between SRAM and
+ * SDRAM running kernel.
+ */
+
+#ifdef CONFIG_ARCH_MX1ADS_SRAM
+#define PAGE_OFFSET	(0xc0000000UL)
+#define PHYS_OFFSET	(0x12000000UL)
+#else
+#define PAGE_OFFSET	(0xc0000000UL)
+#define PHYS_OFFSET	(0x08000000UL)
+#endif
+
+/*
+ * On mx1, the sdram/sram is contiguous
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - PHYS_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	(x - PAGE_OFFSET +  PHYS_OFFSET)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	(x -  PHYS_OFFSET + PAGE_OFFSET)
+
+#define PHYS_TO_NID(addr)	(0)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/param.h linux/include/asm-arm/arch-mx1ads/param.h
--- linux.orig/include/asm-arm/arch-mx1ads/param.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/param.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/param.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+
+#define HZ 100
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/platform.h linux/include/asm-arm/arch-mx1ads/platform.h
--- linux.orig/include/asm-arm/arch-mx1ads/platform.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/platform.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,221 @@
+/*
+ * 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
+ *
+ *
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ */
+
+/**************************************************************************
+ * * Copyright © ARM Limited 1998.  All rights reserved.
+ * ***********************************************************************/
+/* ************************************************************************
+ *
+ *   MX1 address map
+ *
+ * ***********************************************************************/
+
+
+/* ========================================================================
+ *  MX1 definitions
+ * ========================================================================
+ * ------------------------------------------------------------------------
+ *  Memory definitions
+ * ------------------------------------------------------------------------
+ *  MX1 memory map
+ */
+
+
+#ifndef __MX1ADS_PLATFORM_H__
+#define __MX1ADS_PLATFORM_H__
+
+
+#define MX1ADS_SRAM_BASE           0x00300000
+#define MX1ADS_SRAM_SIZE           SZ_128K
+
+#define MX1ADS_SFLASH_BASE         0x0C000000
+#define MX1ADS_SFLASH_SIZE         SZ_16M
+
+#define MX1ADS_IO_BASE             0x00200000
+#define MX1ADS_IO_SIZE             SZ_256K
+
+#define MX1ADS_VID_BASE            0x00300000
+#define MX1ADS_VID_SIZE            0x26000
+
+#define MX1ADS_VID_START           IO_ADDRESS(MX1ADS_VID_BASE)
+
+
+/* ------------------------------------------------------------------------
+ *  Motorola MX1 system registers
+ * ------------------------------------------------------------------------
+ *
+ */
+
+/*
+ *  Register offests.
+ *
+ */
+
+#define MX1ADS_AIPI1_OFFSET             0x00000
+#define MX1ADS_WDT_OFFSET               0x01000
+#define MX1ADS_TIM1_OFFSET              0x02000
+#define MX1ADS_TIM2_OFFSET              0x03000
+#define MX1ADS_RTC_OFFSET               0x04000
+#define MX1ADS_LCDC_OFFSET              0x05000
+#define MX1ADS_UART1_OFFSET             0x06000
+#define MX1ADS_UART2_OFFSET             0x07000
+#define MX1ADS_PWM_OFFSET               0x08000
+#define MX1ADS_DMAC_OFFSET              0x09000
+#define MX1ADS_AIPI2_OFFSET             0x10000
+#define MX1ADS_SIM_OFFSET               0x11000
+#define MX1ADS_USBD_OFFSET              0x12000
+#define MX1ADS_SPI1_OFFSET              0x13000
+#define MX1ADS_MMC_OFFSET               0x14000
+#define MX1ADS_ASP_OFFSET               0x15000
+#define MX1ADS_BTA_OFFSET               0x16000
+#define MX1ADS_I2C_OFFSET               0x17000
+#define MX1ADS_SSI_OFFSET               0x18000
+#define MX1ADS_SPI2_OFFSET              0x19000
+#define MX1ADS_MSHC_OFFSET              0x1A000
+#define MX1ADS_PLL_OFFSET               0x1B000
+#define MX1ADS_GPIO_OFFSET              0x1C000
+#define MX1ADS_EIM_OFFSET               0x20000
+#define MX1ADS_SDRAMC_OFFSET            0x21000
+#define MX1ADS_MMA_OFFSET               0x22000
+#define MX1ADS_AITC_OFFSET              0x23000
+#define MX1ADS_CSI_OFFSET               0x24000
+
+
+/*
+ *  Register BASEs, based on OFFSETs
+ *
+ */
+
+#define MX1ADS_AIPI1_BASE             (MX1ADS_AIPI1_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_WDT_BASE               (MX1ADS_WDT_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_TIM1_BASE              (MX1ADS_TIM1_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_TIM2_BASE              (MX1ADS_TIM2_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_RTC_BASE               (MX1ADS_RTC_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_LCDC_BASE              (MX1ADS_LCDC_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_UART1_BASE             (MX1ADS_UART1_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_UART2_BASE             (MX1ADS_UART2_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_PWM_BASE               (MX1ADS_PWM_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_DMAC_BASE              (MX1ADS_DMAC_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_AIPI2_BASE             (MX1ADS_AIPI2_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_SIM_BASE               (MX1ADS_SIM_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_USBD_BASE              (MX1ADS_USBD_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_SPI1_BASE              (MX1ADS_SPI1_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_MMC_BASE               (MX1ADS_MMC_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_ASP_BASE               (MX1ADS_ASP_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_BTA_BASE               (MX1ADS_BTA_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_I2C_BASE               (MX1ADS_I2C_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_SSI_BASE               (MX1ADS_SSI_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_SPI2_BASE              (MX1ADS_SPI2_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_MSHC_BASE              (MX1ADS_MSHC_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_PLL_BASE               (MX1ADS_PLL_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_GPIO_BASE              (MX1ADS_GPIO_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_EIM_BASE               (MX1ADS_EIM_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_SDRAMC_BASE            (MX1ADS_SDRAMC_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_MMA_BASE               (MX1ADS_MMA_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_AITC_BASE              (MX1ADS_AITC_OFFSET + MX1ADS_IO_BASE)
+#define MX1ADS_CSI_BASE               (MX1ADS_CSI_OFFSET + MX1ADS_IO_BASE)
+
+
+/*
+ *  MX1 Interrupt numbers
+ *
+ */
+#define INT_SOFTINT                 0
+#define CSI_INT                     6
+#define DSPA_MAC_INT                7
+#define DSPA_INT                    8
+#define COMP_INT                    9
+#define MSHC_XINT                   10
+#define GPIO_INT_PORTA              11
+#define GPIO_INT_PORTB              12
+#define GPIO_INT_PORTC              13
+#define LCDC_INT                    14
+#define SIM_INT                     15
+#define SIM_DATA_INT                16
+#define RTC_INT                     17
+#define RTC_SAMINT                  18
+#define UART2_MINT_PFERR            19
+#define UART2_MINT_RTS              20
+#define UART2_MINT_DTR              21
+#define UART2_MINT_UARTC            22
+#define UART2_MINT_TX               23
+#define UART2_MINT_RX               24
+#define UART1_MINT_PFERR            25
+#define UART1_MINT_RTS              26
+#define UART1_MINT_DTR              27
+#define UART1_MINT_UARTC            28
+#define UART1_MINT_TX               29
+#define UART1_MINT_RX               30
+#define VOICE_DAC_INT               31
+#define VOICE_ADC_INT               32
+#define PEN_DATA_INT                33
+#define PWM_INT                     34
+#define SDHC_INT                    35
+#define I2C_INT                     39
+#define CSPI_INT                    41
+#define SSI_TX_INT                  42
+#define SSI_TX_ERR_INT              43
+#define SSI_RX_INT                  44
+#define SSI_RX_ERR_INT              45
+#define TOUCH_INT                   46
+#define USBD_INT0                   47
+#define USBD_INT1                   48
+#define USBD_INT2                   49
+#define USBD_INT3                   50
+#define USBD_INT4                   51
+#define USBD_INT5                   52
+#define USBD_INT6                   53
+#define BTSYS_INT                   55
+#define BTTIM_INT                   56
+#define BTWUI_INT                   57
+#define TIM2_INT                    58
+#define TIM1_INT                    59
+#define DMA_ERR                     60
+#define DMA_INT                     61
+#define GPIO_INT_PORTD              62
+
+
+
+
+#define MAXIRQNUM                       62
+#define MAXFIQNUM                       62
+#define MAXSWINUM                       62
+
+
+
+
+
+#define TICKS_PER_uSEC                  24
+
+/*
+ *  These are useconds NOT ticks.
+ *
+ */
+#define mSEC_1                          1000
+#define mSEC_5                          (mSEC_1 * 5)
+#define mSEC_10                         (mSEC_1 * 10)
+#define mSEC_25                         (mSEC_1 * 25)
+#define SEC_1                           (mSEC_1 * 1000)
+
+
+
+
+/* 	END */
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/system.h linux/include/asm-arm/arch-mx1ads/system.h
--- linux.orig/include/asm-arm/arch-mx1ads/system.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/system.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,41 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/system.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  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
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/arch/platform.h>
+
+static void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle(0);
+}
+
+static inline void arch_reset(char mode)
+{
+	/* FIXME
+	 */
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/time.h linux/include/asm-arm/arch-mx1ads/time.h
--- linux.orig/include/asm-arm/arch-mx1ads/time.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/time.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,138 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/time.h
+ *
+ * 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
+ *
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ */
+#include <asm/system.h>
+
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE (IO_ADDRESS(MX1ADS_TIM1_BASE)+0x00000000)
+#define TIMER1_VA_BASE (IO_ADDRESS(MX1ADS_TIM2_BASE)+0x00000000)
+
+/*
+ * How long is the timer interval?
+ *
+ * Note-
+ * Clocking is not accurate enough.  Need to change the input
+ * to CLKOUT, and fix what those values are.  However,
+ * first need to evaluate what a reasonable value is
+ * as several other things depend upon that clock.
+ *
+ */
+
+#define TIMER_RELOAD	(328)
+
+#define TICKS2USECS(x)	((x) * 30)
+
+#define TIM_32KHZ       0x08
+#define TIM_INTEN       0x10
+#define TIM_ENAB        0x01
+
+/*
+ * What does it look like?
+ */
+typedef struct TimerStruct {
+	unsigned long TimerControl;
+	unsigned long TimerPrescaler;
+	unsigned long TimerCompare;
+	unsigned long TimerCapture;
+	unsigned long TimerCounter;
+	unsigned long TimerClear;	/* Clear Status */
+} TimerStruct_t;
+
+extern unsigned long (*gettimeoffset) (void);
+
+/*
+ * Returns number of ms since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long
+mx1ads_gettimeoffset(void)
+{
+	volatile TimerStruct_t *timer1 = (TimerStruct_t *) TIMER1_VA_BASE;
+	unsigned long ticks, status;
+
+	/*
+	 * Get the current number of ticks.  Note that there is a race
+	 * condition between us reading the timer and checking for
+	 * an interrupt.  We get around this by ensuring that the
+	 * counter has not reloaded between our two reads.
+	 */
+	ticks = timer1->TimerCounter;
+
+	/*
+	 * Interrupt pending?  If so, we've reloaded once already.
+	 */
+	if (timer1->TimerClear & 1)
+		ticks += TIMER_RELOAD;
+
+	/*
+	 * Convert the ticks to usecs
+	 */
+	return TICKS2USECS(ticks);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static void
+mx1ads_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile TimerStruct_t *timer1 =
+	    (volatile TimerStruct_t *) TIMER1_VA_BASE;
+	// ...clear the interrupt
+	if (timer1->TimerClear) {
+		timer1->TimerClear = 0x0;
+	}
+
+	do_timer(regs);
+	do_profile(regs);
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static inline void
+setup_timer(void)
+{
+	volatile TimerStruct_t *timer0 =
+	    (volatile TimerStruct_t *) TIMER0_VA_BASE;
+	volatile TimerStruct_t *timer1 =
+	    (volatile TimerStruct_t *) TIMER1_VA_BASE;
+
+
+	timer_irq.handler = mx1ads_timer_interrupt;
+
+	/*
+	 * Initialise to a known state (all timers off, and timing reset)
+	 */
+	timer0->TimerControl = 0;
+	timer1->TimerControl = 0;
+	timer0->TimerPrescaler = 0;
+	timer1->TimerPrescaler = 0;
+
+	timer1->TimerCompare = 328;
+	timer1->TimerControl = (TIM_32KHZ | TIM_INTEN | TIM_ENAB);
+
+	/*
+	 * Make irqs happen for the system timer
+	 */
+	setup_arm_irq(TIM2_INT, &timer_irq);
+	gettimeoffset = mx1ads_gettimeoffset;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/timex.h linux/include/asm-arm/arch-mx1ads/timex.h
--- linux.orig/include/asm-arm/arch-mx1ads/timex.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/timex.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,24 @@
+/*
+ *  linux/include/asm-arm/mx1ads/timex.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+
+/*
+ * ??
+ */
+#define CLOCK_TICK_RATE		(50000000 / 16)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/uncompress.h linux/include/asm-arm/arch-mx1ads/uncompress.h
--- linux.orig/include/asm-arm/arch-mx1ads/uncompress.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/uncompress.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,56 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/uncompress.h
+ *
+ *
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 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
+ */
+
+#define UA1_USR2	(*(volatile unsigned char *)0x206098)
+#define UA1_TXR 	(*(volatile unsigned char *)0x206040)
+#define TXFEBIT         (14)
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+	while (*s) {
+		while (UA1_USR2 & (1 << TXFEBIT))
+			barrier();
+
+		UA1_TXR = *s;
+
+		if (*s == '\n') {
+			while (UA1_USR2 & (1 << TXFEBIT))
+				barrier();
+
+			UA1_TXR = '\r';
+		}
+		s++;
+	}
+	while (UA1_USR2 & (1 << TXFEBIT))
+		barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-mx1ads/vmalloc.h linux/include/asm-arm/arch-mx1ads/vmalloc.h
--- linux.orig/include/asm-arm/arch-mx1ads/vmalloc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-mx1ads/vmalloc.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-mx1ads/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-nexuspci/uncompress.h linux/include/asm-arm/arch-nexuspci/uncompress.h
--- linux.orig/include/asm-arm/arch-nexuspci/uncompress.h	2000-09-18 22:15:23.000000000 +0000
+++ linux/include/asm-arm/arch-nexuspci/uncompress.h	2002-07-20 01:08:23.000000000 +0000
@@ -20,7 +20,7 @@
 void _ll_write_char(char c)
 {
 	while (!(__raw_readb(DUART_START + 0x4) & 0x4))
-		;
+		barrier();
 	__raw_writeb(c, DUART_START + 0xc);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-rpc/io.h linux/include/asm-arm/arch-rpc/io.h
--- linux.orig/include/asm-arm/arch-rpc/io.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/arch-rpc/io.h	2002-07-20 01:08:23.000000000 +0000
@@ -241,4 +241,13 @@
 /* the following macro is depreciated */
 #define ioaddr(port)			__ioaddr((port))
 
+#define insb(p,d,l)	__raw_readsb(__ioaddr(p),d,l)
+#define insw(p,d,l)	__raw_readsw(__ioaddr(p),d,l)
+
+#define outsb(p,d,l)	__raw_writesb(__ioaddr(p),d,l)
+#define outsw(p,d,l)	__raw_writesw(__ioaddr(p),d,l)
+
+#define iomem_valid_addr(o,s)	(1)
+#define iomem_to_phys(a)	(a)
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/SA-1111.h linux/include/asm-arm/arch-sa1100/SA-1111.h
--- linux.orig/include/asm-arm/arch-sa1100/SA-1111.h	2001-10-25 20:53:54.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/SA-1111.h	2002-07-20 01:08:29.000000000 +0000
@@ -1,647 +1,5 @@
 /*
- * linux/include/asm/arch/SA-1111.h
- *
- * Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
- *
- * This file contains definitions for the SA-1111 Companion Chip.
- * (Structure and naming borrowed from SA-1101.h, by Peter Danielsson.)
- *
+ * Moved to new location
  */
-
-#ifndef _ASM_ARCH_SA1111
-#define _ASM_ARCH_SA1111
-
-#include <asm/arch/bitfield.h>
-
-/*
- * Macro that calculates real address for registers in the SA-1111
- */
-
-#define _SA1111( x )    ((x) + SA1111_BASE)
-
-/*
- * 26 bits of the SA-1110 address bus are available to the SA-1111.
- * Use these when feeding target addresses to the DMA engines.
- */
-
-#define SA1111_ADDR_WIDTH	(26)
-#define SA1111_ADDR_MASK	((1<<SA1111_ADDR_WIDTH)-1)
-#define SA1111_DMA_ADDR(x)	((x)&SA1111_ADDR_MASK)
-
-/*
- * Don't ask the (SAC) DMA engines to move less than this amount.
- */
-
-#define SA1111_SAC_DMA_MIN_XFER	(0x800)
-
-/*
- * SA1111 register definitions.
- */
-#define __CCREG(x)	__REGP(SA1111_VBASE + (x))
-
-/* System Bus Interface (SBI)
- *
- * Registers
- *    SKCR	Control Register
- *    SMCR	Shared Memory Controller Register
- *    SKID	ID Register
- */
-
-#define _SBI_SKCR	_SA1111(0x0000)
-#define _SBI_SMCR	_SA1111(0x0004)
-#define _SBI_SKID	_SA1111(0x0008)
-
-#if LANGUAGE == C
-
-#define SBI_SKCR	__CCREG(0x0000)
-#define SBI_SMCR	__CCREG(0x0004)
-#define SBI_SKID	__CCREG(0x0008)
-
-#endif  /* LANGUAGE == C */
-
-#define SKCR_PLL_BYPASS	(1<<0)
-#define SKCR_RCLKEN	(1<<1)
-#define SKCR_SLEEP	(1<<2)
-#define SKCR_DOZE	(1<<3)
-#define SKCR_VCO_OFF	(1<<4)
-#define SKCR_SCANTSTEN	(1<<5)
-#define SKCR_CLKTSTEN	(1<<6)
-#define SKCR_RDYEN	(1<<7)
-#define SKCR_SELAC	(1<<8)
-#define SKCR_OPPC	(1<<9)
-#define SKCR_PLLTSTEN	(1<<10)
-#define SKCR_USBIOTSTEN	(1<<11)
-/*
- * Don't believe the specs!  Take them, throw them outside.  Leave them
- * there for a week.  Spit on them.  Walk on them.  Stamp on them.
- * Pour gasoline over them and finally burn them.  Now think about coding.
- *  - The October 1999 errata (278260-007) says its bit 13, 1 to enable.
- *  - The Feb 2001 errata (278260-010) says that the previous errata
- *    (278260-009) is wrong, and its bit actually 12, fixed in spec
- *    278242-003.
- *  - The SA1111 manual (278242) says bit 12, but 0 to enable.
- *  - Reality is bit 13, 1 to enable.
- *      -- rmk
- */
-#define SKCR_OE_EN	(1<<13)
-
-#define SMCR_DTIM	(1<<0)
-#define SMCR_MBGE	(1<<1)
-#define SMCR_DRAC_0	(1<<2)
-#define SMCR_DRAC_1	(1<<3)
-#define SMCR_DRAC_2	(1<<4)
-#define SMCR_DRAC	Fld(3, 2)
-#define SMCR_CLAT	(1<<5)
-
-#define SKID_SIREV_MASK	(0x000000f0)
-#define SKID_MTREV_MASK (0x0000000f)
-#define SKID_ID_MASK	(0xffffff00)
-#define SKID_SA1111_ID	(0x690cc200)
-
-/*
- * System Controller
- *
- * Registers
- *    SKPCR	Power Control Register
- *    SKCDR	Clock Divider Register
- *    SKAUD	Audio Clock Divider Register
- *    SKPMC	PS/2 Mouse Clock Divider Register
- *    SKPTC	PS/2 Track Pad Clock Divider Register
- *    SKPEN0	PWM0 Enable Register
- *    SKPWM0	PWM0 Clock Register
- *    SKPEN1	PWM1 Enable Register
- *    SKPWM1	PWM1 Clock Register
- */
-
-#define _SKPCR		_SA1111(0x0200)
-#define _SKCDR		_SA1111(0x0204)
-#define _SKAUD		_SA1111(0x0208)
-#define _SKPMC		_SA1111(0x020c)
-#define _SKPTC		_SA1111(0x0210)
-#define _SKPEN0		_SA1111(0x0214)
-#define _SKPWM0		_SA1111(0x0218)
-#define _SKPEN1		_SA1111(0x021c)
-#define _SKPWM1		_SA1111(0x0220)
-
-#if LANGUAGE == C
-
-#define SKPCR		__CCREG(0x0200)
-#define SKCDR		__CCREG(0x0204)
-#define SKAUD		__CCREG(0x0208)
-#define SKPMC		__CCREG(0x020c)
-#define SKPTC		__CCREG(0x0210)
-#define SKPEN0		__CCREG(0x0214)
-#define SKPWM0		__CCREG(0x0218)
-#define SKPEN1		__CCREG(0x021c)
-#define SKPWM1		__CCREG(0x0220)
-
-#endif  /* LANGUAGE == C */
-
-#define SKPCR_UCLKEN	(1<<0)
-#define SKPCR_ACCLKEN	(1<<1)
-#define SKPCR_I2SCLKEN	(1<<2)
-#define SKPCR_L3CLKEN	(1<<3)
-#define SKPCR_SCLKEN	(1<<4)
-#define SKPCR_PMCLKEN	(1<<5)
-#define SKPCR_PTCLKEN	(1<<6)
-#define SKPCR_DCLKEN	(1<<7)
-#define SKPCR_PWMCLKEN	(1<<8)
-
-/*
- * USB Host controller
- */
-#define _USB_OHCI_OP_BASE	_SA1111( 0x400 )
-#define _USB_STATUS		_SA1111( 0x518 )
-#define _USB_RESET		_SA1111( 0x51c )
-#define _USB_INTERRUPTEST	_SA1111( 0x520 )
-
-#define _USB_EXTENT		(_USB_INTERRUPTEST - _USB_OHCI_OP_BASE + 4)
-
-#if LANGUAGE == C
-
-#define USB_OHCI_OP_BASE	__CCREG(0x0400)
-#define USB_STATUS		__CCREG(0x0518)
-#define USB_RESET		__CCREG(0x051c)
-#define USB_INTERRUPTEST	__CCReG(0x0520)
-
-#endif  /* LANGUAGE == C */
-
-#define USB_RESET_FORCEIFRESET	(1 << 0)
-#define USB_RESET_FORCEHCRESET	(1 << 1)
-#define USB_RESET_CLKGENRESET	(1 << 2)
-#define USB_RESET_SIMSCALEDOWN	(1 << 3)
-#define USB_RESET_USBINTTEST	(1 << 4)
-#define USB_RESET_SLEEPSTBYEN	(1 << 5)
-#define USB_RESET_PWRSENSELOW	(1 << 6)
-#define USB_RESET_PWRCTRLLOW	(1 << 7)
-
-/*
- * Serial Audio Controller
- *
- * Registers
- *    SACR0             Serial Audio Common Control Register
- *    SACR1             Serial Audio Alternate Mode (I2C/MSB) Control Register
- *    SACR2             Serial Audio AC-link Control Register
- *    SASR0             Serial Audio I2S/MSB Interface & FIFO Status Register
- *    SASR1             Serial Audio AC-link Interface & FIFO Status Register
- *    SASCR             Serial Audio Status Clear Register
- *    L3_CAR            L3 Control Bus Address Register
- *    L3_CDR            L3 Control Bus Data Register
- *    ACCAR             AC-link Command Address Register
- *    ACCDR             AC-link Command Data Register
- *    ACSAR             AC-link Status Address Register
- *    ACSDR             AC-link Status Data Register
- *    SADTCS            Serial Audio DMA Transmit Control/Status Register
- *    SADTSA            Serial Audio DMA Transmit Buffer Start Address A
- *    SADTCA            Serial Audio DMA Transmit Buffer Count Register A
- *    SADTSB            Serial Audio DMA Transmit Buffer Start Address B
- *    SADTCB            Serial Audio DMA Transmit Buffer Count Register B
- *    SADRCS            Serial Audio DMA Receive Control/Status Register
- *    SADRSA            Serial Audio DMA Receive Buffer Start Address A
- *    SADRCA            Serial Audio DMA Receive Buffer Count Register A
- *    SADRSB            Serial Audio DMA Receive Buffer Start Address B
- *    SADRCB            Serial Audio DMA Receive Buffer Count Register B
- *    SAITR             Serial Audio Interrupt Test Register
- *    SADR              Serial Audio Data Register (16 x 32-bit)
- */
-
-#define _SACR0          _SA1111( 0x0600 )
-#define _SACR1          _SA1111( 0x0604 )
-#define _SACR2          _SA1111( 0x0608 )
-#define _SASR0          _SA1111( 0x060c )
-#define _SASR1          _SA1111( 0x0610 )
-#define _SASCR          _SA1111( 0x0618 )
-#define _L3_CAR         _SA1111( 0x061c )
-#define _L3_CDR         _SA1111( 0x0620 )
-#define _ACCAR          _SA1111( 0x0624 )
-#define _ACCDR          _SA1111( 0x0628 )
-#define _ACSAR          _SA1111( 0x062c )
-#define _ACSDR          _SA1111( 0x0630 )
-#define _SADTCS         _SA1111( 0x0634 )
-#define _SADTSA         _SA1111( 0x0638 )
-#define _SADTCA         _SA1111( 0x063c )
-#define _SADTSB         _SA1111( 0x0640 )
-#define _SADTCB         _SA1111( 0x0644 )
-#define _SADRCS         _SA1111( 0x0648 )
-#define _SADRSA         _SA1111( 0x064c )
-#define _SADRCA         _SA1111( 0x0650 )
-#define _SADRSB         _SA1111( 0x0654 )
-#define _SADRCB         _SA1111( 0x0658 )
-#define _SAITR          _SA1111( 0x065c )
-#define _SADR           _SA1111( 0x0680 )
-
-#if LANGUAGE == C
-
-#define SACR0		__CCREG(0x0600)
-#define SACR1		__CCREG(0x0604)
-#define SACR2		__CCREG(0x0608)
-#define SASR0		__CCREG(0x060c)
-#define SASR1		__CCREG(0x0610)
-#define SASCR		__CCREG(0x0618)
-#define L3_CAR		__CCREG(0x061c)
-#define L3_CDR		__CCREG(0x0620)
-#define ACCAR		__CCREG(0x0624)
-#define ACCDR		__CCREG(0x0628)
-#define ACSAR		__CCREG(0x062c)
-#define ACSDR		__CCREG(0x0630)
-#define SADTCS		__CCREG(0x0634)
-#define SADTSA		__CCREG(0x0638)
-#define SADTCA		__CCREG(0x063c)
-#define SADTSB		__CCREG(0x0640)
-#define SADTCB		__CCREG(0x0644)
-#define SADRCS		__CCREG(0x0648)
-#define SADRSA		__CCREG(0x064c)
-#define SADRCA		__CCREG(0x0650)
-#define SADRSB		__CCREG(0x0654)
-#define SADRCB		__CCREG(0x0658)
-#define SAITR		__CCREG(0x065c)
-#define SADR		__CCREG(0x0680)
-
-#endif  /* LANGUAGE == C */
-
-#define SACR0_ENB	(1<<0)
-#define SACR0_BCKD	(1<<2)
-#define SACR0_RST	(1<<3)
-
-#define SACR1_AMSL	(1<<0)
-#define SACR1_L3EN	(1<<1)
-#define SACR1_L3MB	(1<<2)
-#define SACR1_DREC	(1<<3)
-#define SACR1_DRPL	(1<<4)
-#define SACR1_ENLBF	(1<<5)
-
-#define SACR2_TS3V	(1<<0)
-#define SACR2_TS4V	(1<<1)
-#define SACR2_WKUP	(1<<2)
-#define SACR2_DREC	(1<<3)
-#define SACR2_DRPL	(1<<4)
-#define SACR2_ENLBF	(1<<5)
-#define SACR2_RESET	(1<<6)
-
-#define SASR0_TNF	(1<<0)
-#define SASR0_RNE	(1<<1)
-#define SASR0_BSY	(1<<2)
-#define SASR0_TFS	(1<<3)
-#define SASR0_RFS	(1<<4)
-#define SASR0_TUR	(1<<5)
-#define SASR0_ROR	(1<<6)
-#define SASR0_L3WD	(1<<16)
-#define SASR0_L3RD	(1<<17)
-
-#define SASR1_TNF	(1<<0)
-#define SASR1_RNE	(1<<1)
-#define SASR1_BSY	(1<<2)
-#define SASR1_TFS	(1<<3)
-#define SASR1_RFS	(1<<4)
-#define SASR1_TUR	(1<<5)
-#define SASR1_ROR	(1<<6)
-#define SASR1_CADT	(1<<16)
-#define SASR1_SADR	(1<<17)
-#define SASR1_RSTO	(1<<18)
-#define SASR1_CLPM	(1<<19)
-#define SASR1_CRDY	(1<<20)
-#define SASR1_RS3V	(1<<21)
-#define SASR1_RS4V	(1<<22)
-
-#define SASCR_TUR	(1<<5)
-#define SASCR_ROR	(1<<6)
-#define SASCR_DTS	(1<<16)
-#define SASCR_RDD	(1<<17)
-#define SASCR_STO	(1<<18)
-
-#define SADTCS_TDEN	(1<<0)
-#define SADTCS_TDIE	(1<<1)
-#define SADTCS_TDBDA	(1<<3)
-#define SADTCS_TDSTA	(1<<4)
-#define SADTCS_TDBDB	(1<<5)
-#define SADTCS_TDSTB	(1<<6)
-#define SADTCS_TBIU	(1<<7)
-
-#define SADRCS_RDEN	(1<<0)
-#define SADRCS_RDIE	(1<<1)
-#define SADRCS_RDBDA	(1<<3)
-#define SADRCS_RDSTA	(1<<4)
-#define SADRCS_RDBDB	(1<<5)
-#define SADRCS_RDSTB	(1<<6)
-#define SADRCS_RBIU	(1<<7)
-
-#define SAD_CS_DEN	(1<<0)
-#define SAD_CS_DIE	(1<<1)	/* Not functional on metal 1 */
-#define SAD_CS_DBDA	(1<<3)	/* Not functional on metal 1 */
-#define SAD_CS_DSTA	(1<<4)
-#define SAD_CS_DBDB	(1<<5)	/* Not functional on metal 1 */
-#define SAD_CS_DSTB	(1<<6)
-#define SAD_CS_BIU	(1<<7)	/* Not functional on metal 1 */
-
-#define SAITR_TFS	(1<<0)
-#define SAITR_RFS	(1<<1)
-#define SAITR_TUR	(1<<2)
-#define SAITR_ROR	(1<<3)
-#define SAITR_CADT	(1<<4)
-#define SAITR_SADR	(1<<5)
-#define SAITR_RSTO	(1<<6)
-#define SAITR_TDBDA	(1<<8)
-#define SAITR_TDBDB	(1<<9)
-#define SAITR_RDBDA	(1<<10)
-#define SAITR_RDBDB	(1<<11)
-
-/*
- * General-Purpose I/O Interface
- *
- * Registers
- *    PA_DDR		GPIO Block A Data Direction
- *    PA_DRR/PA_DWR	GPIO Block A Data Value Register (read/write)
- *    PA_SDR		GPIO Block A Sleep Direction
- *    PA_SSR		GPIO Block A Sleep State
- *    PB_DDR		GPIO Block B Data Direction
- *    PB_DRR/PB_DWR	GPIO Block B Data Value Register (read/write)
- *    PB_SDR		GPIO Block B Sleep Direction
- *    PB_SSR		GPIO Block B Sleep State
- *    PC_DDR		GPIO Block C Data Direction
- *    PC_DRR/PC_DWR	GPIO Block C Data Value Register (read/write)
- *    PC_SDR		GPIO Block C Sleep Direction
- *    PC_SSR		GPIO Block C Sleep State
- */
-
-#define _PA_DDR		_SA1111( 0x1000 )
-#define _PA_DRR		_SA1111( 0x1004 )
-#define _PA_DWR		_SA1111( 0x1004 )
-#define _PA_SDR		_SA1111( 0x1008 )
-#define _PA_SSR		_SA1111( 0x100c )
-#define _PB_DDR		_SA1111( 0x1010 )
-#define _PB_DRR		_SA1111( 0x1014 )
-#define _PB_DWR		_SA1111( 0x1014 )
-#define _PB_SDR		_SA1111( 0x1018 )
-#define _PB_SSR		_SA1111( 0x101c )
-#define _PC_DDR		_SA1111( 0x1020 )
-#define _PC_DRR		_SA1111( 0x1024 )
-#define _PC_DWR		_SA1111( 0x1024 )
-#define _PC_SDR		_SA1111( 0x1028 )
-#define _PC_SSR		_SA1111( 0x102c )
-
-#if LANGUAGE == C
-
-#define PA_DDR		__CCREG(0x1000)
-#define PA_DRR		__CCREG(0x1004)
-#define PA_DWR		__CCREG(0x1004)
-#define PA_SDR		__CCREG(0x1008)
-#define PA_SSR		__CCREG(0x100c)
-#define PB_DDR		__CCREG(0x1010)
-#define PB_DRR		__CCREG(0x1014)
-#define PB_DWR		__CCREG(0x1014)
-#define PB_SDR		__CCREG(0x1018)
-#define PB_SSR		__CCREG(0x101c)
-#define PC_DDR		__CCREG(0x1020)
-#define PC_DRR		__CCREG(0x1024)
-#define PC_DWR		__CCREG(0x1024)
-#define PC_SDR		__CCREG(0x1028)
-#define PC_SSR		__CCREG(0x102c)
-
-#endif  /* LANGUAGE == C */
-
-/*
- * Interrupt Controller
- *
- * Registers
- *    INTTEST0		Test register 0
- *    INTTEST1		Test register 1
- *    INTEN0		Interrupt Enable register 0
- *    INTEN1		Interrupt Enable register 1
- *    INTPOL0		Interrupt Polarity selection 0
- *    INTPOL1		Interrupt Polarity selection 1
- *    INTTSTSEL		Interrupt source selection
- *    INTSTATCLR0	Interrupt Status/Clear 0
- *    INTSTATCLR1	Interrupt Status/Clear 1
- *    INTSET0		Interrupt source set 0
- *    INTSET1		Interrupt source set 1
- *    WAKE_EN0		Wake-up source enable 0
- *    WAKE_EN1		Wake-up source enable 1
- *    WAKE_POL0		Wake-up polarity selection 0
- *    WAKE_POL1		Wake-up polarity selection 1
- */
-
-#define _INTTEST0	_SA1111( 0x1600 )
-#define _INTTEST1	_SA1111( 0x1604 )
-#define _INTEN0		_SA1111( 0x1608 )
-#define _INTEN1		_SA1111( 0x160c )
-#define _INTPOL0	_SA1111( 0x1610 )
-#define _INTPOL1	_SA1111( 0x1614 )
-#define _INTTSTSEL	_SA1111( 0x1618 )
-#define _INTSTATCLR0	_SA1111( 0x161c )
-#define _INTSTATCLR1	_SA1111( 0x1620 )
-#define _INTSET0	_SA1111( 0x1624 )
-#define _INTSET1	_SA1111( 0x1628 )
-#define _WAKE_EN0	_SA1111( 0x162c )
-#define _WAKE_EN1	_SA1111( 0x1630 )
-#define _WAKE_POL0	_SA1111( 0x1634 )
-#define _WAKE_POL1	_SA1111( 0x1638 )
-
-#if LANGUAGE == C
-
-#define INTTEST0	__CCREG(0x1600)
-#define INTTEST1	__CCREG(0x1604)
-#define INTEN0		__CCREG(0x1608)
-#define INTEN1		__CCREG(0x160c)
-#define INTPOL0		__CCREG(0x1610)
-#define INTPOL1		__CCREG(0x1614)
-#define INTTSTSEL	__CCREG(0x1618)
-#define INTSTATCLR0	__CCREG(0x161c)
-#define INTSTATCLR1	__CCREG(0x1620)
-#define INTSET0		__CCREG(0x1624)
-#define INTSET1		__CCREG(0x1628)
-#define WAKE_EN0	__CCREG(0x162c)
-#define WAKE_EN1	__CCREG(0x1630)
-#define WAKE_POL0	__CCREG(0x1634)
-#define WAKE_POL1	__CCREG(0x1638)
-
-#endif  /* LANGUAGE == C */
-
-/*
- * PS/2 Trackpad and Mouse Interfaces
- *
- * Registers   (prefix kbd applies to trackpad interface, mse to mouse)
- *    KBDCR     Control Register
- *    KBDSTAT       Status Register
- *    KBDDATA       Transmit/Receive Data register
- *    KBDCLKDIV     Clock Division Register
- *    KBDPRECNT     Clock Precount Register
- *    KBDTEST1      Test register 1
- *    KBDTEST2      Test register 2
- *    KBDTEST3      Test register 3
- *    KBDTEST4      Test register 4
- *    MSECR
- *    MSESTAT
- *    MSEDATA
- *    MSECLKDIV
- *    MSEPRECNT
- *    MSETEST1
- *    MSETEST2
- *    MSETEST3
- *    MSETEST4
- *
- */
-
-#define _KBD( x )   _SA1111( 0x0A00 )
-#define _MSE( x )   _SA1111( 0x0C00 )
-
-#define _KBDCR	    _SA1111( 0x0A00 )
-#define _KBDSTAT    _SA1111( 0x0A04 )
-#define _KBDDATA    _SA1111( 0x0A08 )
-#define _KBDCLKDIV  _SA1111( 0x0A0C )
-#define _KBDPRECNT  _SA1111( 0x0A10 )
-#define _MSECR	    _SA1111( 0x0C00 )
-#define _MSESTAT    _SA1111( 0x0C04 )
-#define _MSEDATA    _SA1111( 0x0C08 )
-#define _MSECLKDIV  _SA1111( 0x0C0C )
-#define _MSEPRECNT  _SA1111( 0x0C10 )
-
-#if ( LANGUAGE == C )
-
-#define KBDCR		__CCREG(0x0a00)
-#define KBDSTAT		__CCREG(0x0a04)
-#define KBDDATA		__CCREG(0x0a08)
-#define KBDCLKDIV	__CCREG(0x0a0c)
-#define KBDPRECNT	__CCREG(0x0a10)
-#define MSECR		__CCREG(0x0c00)
-#define MSESTAT		__CCREG(0x0c04)
-#define MSEDATA		__CCREG(0x0c08)
-#define MSECLKDIV	__CCREG(0x0c0c)
-#define MSEPRECNT	__CCREG(0x0c10)
-
-#define KBDCR_ENA        0x08
-#define KBDCR_FKD        0x02
-#define KBDCR_FKC        0x01
-
-#define KBDSTAT_TXE      0x80
-#define KBDSTAT_TXB      0x40
-#define KBDSTAT_RXF      0x20
-#define KBDSTAT_RXB      0x10
-#define KBDSTAT_ENA      0x08
-#define KBDSTAT_RXP      0x04
-#define KBDSTAT_KBD      0x02
-#define KBDSTAT_KBC      0x01
-
-#define KBDCLKDIV_DivVal     Fld(4,0)
-
-#define MSECR_ENA        0x08
-#define MSECR_FKD        0x02
-#define MSECR_FKC        0x01
-
-#define MSESTAT_TXE      0x80
-#define MSESTAT_TXB      0x40
-#define MSESTAT_RXF      0x20
-#define MSESTAT_RXB      0x10
-#define MSESTAT_ENA      0x08
-#define MSESTAT_RXP      0x04
-#define MSESTAT_MSD      0x02
-#define MSESTAT_MSC      0x01
-
-#define MSECLKDIV_DivVal     Fld(4,0)
-
-#define KBDTEST1_CD      0x80
-#define KBDTEST1_RC1         0x40
-#define KBDTEST1_MC      0x20
-#define KBDTEST1_C       Fld(2,3)
-#define KBDTEST1_T2      0x40
-#define KBDTEST1_T1      0x20
-#define KBDTEST1_T0      0x10
-#define KBDTEST2_TICBnRES    0x08
-#define KBDTEST2_RKC         0x04
-#define KBDTEST2_RKD         0x02
-#define KBDTEST2_SEL         0x01
-#define KBDTEST3_ms_16       0x80
-#define KBDTEST3_us_64       0x40
-#define KBDTEST3_us_16       0x20
-#define KBDTEST3_DIV8        0x10
-#define KBDTEST3_DIn         0x08
-#define KBDTEST3_CIn         0x04
-#define KBDTEST3_KD      0x02
-#define KBDTEST3_KC      0x01
-#define KBDTEST4_BC12        0x80
-#define KBDTEST4_BC11        0x40
-#define KBDTEST4_TRES        0x20
-#define KBDTEST4_CLKOE       0x10
-#define KBDTEST4_CRES        0x08
-#define KBDTEST4_RXB         0x04
-#define KBDTEST4_TXB         0x02
-#define KBDTEST4_SRX         0x01
-
-#define MSETEST1_CD      0x80
-#define MSETEST1_RC1         0x40
-#define MSETEST1_MC      0x20
-#define MSETEST1_C       Fld(2,3)
-#define MSETEST1_T2      0x40
-#define MSETEST1_T1      0x20
-#define MSETEST1_T0      0x10
-#define MSETEST2_TICBnRES    0x08
-#define MSETEST2_RKC         0x04
-#define MSETEST2_RKD         0x02
-#define MSETEST2_SEL         0x01
-#define MSETEST3_ms_16       0x80
-#define MSETEST3_us_64       0x40
-#define MSETEST3_us_16       0x20
-#define MSETEST3_DIV8        0x10
-#define MSETEST3_DIn         0x08
-#define MSETEST3_CIn         0x04
-#define MSETEST3_KD      0x02
-#define MSETEST3_KC      0x01
-#define MSETEST4_BC12        0x80
-#define MSETEST4_BC11        0x40
-#define MSETEST4_TRES        0x20
-#define MSETEST4_CLKOE       0x10
-#define MSETEST4_CRES        0x08
-#define MSETEST4_RXB         0x04
-#define MSETEST4_TXB         0x02
-#define MSETEST4_SRX         0x01
-
-#endif  /* LANGUAGE == C */
-
-/*
- * PCMCIA Interface
- *
- * Registers
- *    PCSR	Status Register
- *    PCCR	Control Register
- *    PCSSR	Sleep State Register
- */
-
-#define _PCCR		_SA1111( 0x1800 )
-#define _PCSSR		_SA1111( 0x1804 )
-#define _PCSR		_SA1111( 0x1808 )
-
-#if LANGUAGE == C
-
-#define PCCR		__CCREG(0x1800)
-#define PCSSR		__CCREG(0x1804)
-#define PCSR		__CCREG(0x1808)
-
-#endif  /* LANGUAGE == C */
-
-#define PCSR_S0_READY	(1<<0)
-#define PCSR_S1_READY	(1<<1)
-#define PCSR_S0_DETECT	(1<<2)
-#define PCSR_S1_DETECT	(1<<3)
-#define PCSR_S0_VS1	(1<<4)
-#define PCSR_S0_VS2	(1<<5)
-#define PCSR_S1_VS1	(1<<6)
-#define PCSR_S1_VS2	(1<<7)
-#define PCSR_S0_WP	(1<<8)
-#define PCSR_S1_WP	(1<<9)
-#define PCSR_S0_BVD1	(1<<10)
-#define PCSR_S0_BVD2	(1<<11)
-#define PCSR_S1_BVD1	(1<<12)
-#define PCSR_S1_BVD2	(1<<13)
-
-#define PCCR_S0_RST	(1<<0)
-#define PCCR_S1_RST	(1<<1)
-#define PCCR_S0_FLT	(1<<2)
-#define PCCR_S1_FLT	(1<<3)
-#define PCCR_S0_PWAITEN	(1<<4)
-#define PCCR_S1_PWAITEN	(1<<5)
-#define PCCR_S0_PSE	(1<<6)
-#define PCCR_S1_PSE	(1<<7)
-
-#define PCSSR_S0_SLEEP	(1<<0)
-#define PCSSR_S1_SLEEP	(1<<1)
-
-#endif  /* _ASM_ARCH_SA1111 */
+#warning using old SA-1111.h - update to <asm/hardware/sa1111.h>
+#include <asm/hardware/sa1111.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/adsbitsy.h linux/include/asm-arm/arch-sa1100/adsbitsy.h
--- linux.orig/include/asm-arm/arch-sa1100/adsbitsy.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/adsbitsy.h	2002-07-20 01:08:35.000000000 +0000
@@ -11,4 +11,4 @@
 #error "include <asm/hardware.h> instead"
 #endif
 
-#define	SA1111_BASE		(0x18000000)
+#define ADSBITSY_SA1111_BASE	(0x18000000)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/assabet.h linux/include/asm-arm/arch-sa1100/assabet.h
--- linux.orig/include/asm-arm/arch-sa1100/assabet.h	2001-10-25 20:53:54.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/assabet.h	2002-07-20 01:08:21.000000000 +0000
@@ -29,19 +29,6 @@
 #define ASSABET_BCR_BASE  0xf1000000
 #define ASSABET_BCR (*(volatile unsigned int *)(ASSABET_BCR_BASE))
 
-#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)
-
 #define ASSABET_BCR_CF_PWR	(1<<0)	/* Compact Flash Power (1 = 3.3v, 0 = off) */
 #define ASSABET_BCR_CF_RST	(1<<1)	/* Compact Flash Reset (1 = power up reset) */
 #define ASSABET_BCR_GFX_RST	(1<<1)	/* Graphics Accelerator Reset (0 = hold reset) */
@@ -70,8 +57,15 @@
 
 extern unsigned long SCR_value;
 extern unsigned long BCR_value;
-#define ASSABET_BCR_set(x)	ASSABET_BCR = (BCR_value |= (x))
-#define ASSABET_BCR_clear(x)	ASSABET_BCR = (BCR_value &= ~(x))
+
+#ifdef CONFIG_SA1100_ASSABET
+extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set);
+#else
+#define ASSABET_BCR_frob(m,s)	do { } while (0)
+#endif
+
+#define ASSABET_BCR_set(x)	ASSABET_BCR_frob((x), (x))
+#define ASSABET_BCR_clear(x)	ASSABET_BCR_frob((x), 0)
 
 #define ASSABET_BSR_BASE	0xf1000000
 #define ASSABET_BSR (*(volatile unsigned int*)(ASSABET_BSR_BASE))
@@ -88,37 +82,27 @@
 
 /* GPIOs for which the generic definition doesn't say much */
 #define ASSABET_GPIO_RADIO_IRQ		GPIO_GPIO (14)	/* Radio interrupt request  */
-#define ASSABET_GPIO_L3_I2C_SDA		GPIO_GPIO (15)	/* L3 and SMB control ports */
 #define ASSABET_GPIO_PS_MODE_SYNC	GPIO_GPIO (16)	/* Power supply mode/sync   */
-#define ASSABET_GPIO_L3_MODE		GPIO_GPIO (17)	/* L3 mode signal with LED  */
-#define ASSABET_GPIO_L3_I2C_SCL		GPIO_GPIO (18)	/* L3 and I2C control ports */
 #define ASSABET_GPIO_STEREO_64FS_CLK	GPIO_GPIO (19)	/* SSP UDA1341 clock input  */
 #define ASSABET_GPIO_CF_IRQ		GPIO_GPIO (21)	/* CF IRQ   */
 #define ASSABET_GPIO_CF_CD		GPIO_GPIO (22)	/* CF CD */
-#define ASSABET_GPIO_UCB1300_IRQ	GPIO_GPIO (23)	/* UCB GPIO and touchscreen */
 #define ASSABET_GPIO_CF_BVD2		GPIO_GPIO (24)	/* CF BVD */
 #define ASSABET_GPIO_GFX_IRQ		GPIO_GPIO (24)	/* Graphics IRQ */
 #define ASSABET_GPIO_CF_BVD1		GPIO_GPIO (25)	/* CF BVD */
-#define ASSABET_GPIO_NEP_IRQ		GPIO_GPIO (25)	/* Neponset IRQ */
 #define ASSABET_GPIO_BATT_LOW		GPIO_GPIO (26)	/* Low battery */
 #define ASSABET_GPIO_RCLK		GPIO_GPIO (26)	/* CCLK/2  */
 
 #define ASSABET_IRQ_GPIO_CF_IRQ		IRQ_GPIO21
 #define ASSABET_IRQ_GPIO_CF_CD		IRQ_GPIO22
-#define ASSABET_IRQ_GPIO_UCB1300_IRQ	IRQ_GPIO23
 #define ASSABET_IRQ_GPIO_CF_BVD2	IRQ_GPIO24
 #define ASSABET_IRQ_GPIO_CF_BVD1	IRQ_GPIO25
-#define ASSABET_IRQ_GPIO_NEP_IRQ	IRQ_GPIO25
 
 
 /*
  * Neponset definitions: 
  */
 
-#define SA1111_BASE             (0x40000000)
-
-#define NEPONSET_ETHERNET_IRQ	MISC_IRQ0
-#define NEPONSET_USAR_IRQ	MISC_IRQ1
+#define NEPONSET_SA1111_BASE	(0x40000000)
 
 #define NEPONSET_CPLD_BASE      (0x10000000)
 #define Nep_p2v( x )            ((x) - NEPONSET_CPLD_BASE + 0xf3000000)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/badge4.h linux/include/asm-arm/arch-sa1100/badge4.h
--- linux.orig/include/asm-arm/arch-sa1100/badge4.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/badge4.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,74 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/badge4.h
+ *
+ *   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.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define BADGE4_SA1111_BASE		(0x48000000)
+
+/* GPIOs on the BadgePAD 4 */
+#define BADGE4_GPIO_INT_1111		GPIO_GPIO0   /* SA-1111 IRQ */
+
+#define BADGE4_GPIO_INT_VID		GPIO_GPIO1   /* Video expansion */
+#define BADGE4_GPIO_LGP2		GPIO_GPIO2   /* GPIO_LDD8 */
+#define BADGE4_GPIO_LGP3		GPIO_GPIO3   /* GPIO_LDD9 */
+#define BADGE4_GPIO_LGP4		GPIO_GPIO4   /* GPIO_LDD10 */
+#define BADGE4_GPIO_LGP5		GPIO_GPIO5   /* GPIO_LDD11 */
+#define BADGE4_GPIO_LGP6		GPIO_GPIO6   /* GPIO_LDD12 */
+#define BADGE4_GPIO_LGP7		GPIO_GPIO7   /* GPIO_LDD13 */
+#define BADGE4_GPIO_LGP8		GPIO_GPIO8   /* GPIO_LDD14 */
+#define BADGE4_GPIO_LGP9		GPIO_GPIO9   /* GPIO_LDD15 */
+#define BADGE4_GPIO_GPA_VID		GPIO_GPIO10  /* Video expansion */
+#define BADGE4_GPIO_GPB_VID		GPIO_GPIO11  /* Video expansion */
+#define BADGE4_GPIO_GPC_VID		GPIO_GPIO12  /* Video expansion */
+
+#define BADGE4_GPIO_UART_HS1		GPIO_GPIO13
+#define BADGE4_GPIO_UART_HS2		GPIO_GPIO14
+
+#define BADGE4_GPIO_MUXSEL0		GPIO_GPIO15
+#define BADGE4_GPIO_TESTPT_J7		GPIO_GPIO16
+
+#define BADGE4_GPIO_SDSDA		GPIO_GPIO17  /* SDRAM SPD Data */
+#define BADGE4_GPIO_SDSCL		GPIO_GPIO18  /* SDRAM SPD Clock */
+#define BADGE4_GPIO_SDTYP0		GPIO_GPIO19  /* SDRAM Type Control */
+#define BADGE4_GPIO_SDTYP1		GPIO_GPIO20  /* SDRAM Type Control */
+
+#define BADGE4_GPIO_BGNT_1111		GPIO_GPIO21  /* GPIO_MBGNT */
+#define BADGE4_GPIO_BREQ_1111		GPIO_GPIO22  /* GPIO_TREQA */
+
+#define BADGE4_GPIO_TESTPT_J6		GPIO_GPIO23
+
+#define BADGE4_GPIO_PCMEN5V		GPIO_GPIO24  /* 5V power */
+
+#define BADGE4_GPIO_SA1111_NRST		GPIO_GPIO25  /* SA-1111 nRESET */
+
+#define BADGE4_GPIO_TESTPT_J5		GPIO_GPIO26
+
+#define BADGE4_GPIO_CLK_1111		GPIO_GPIO27  /* GPIO_32_768kHz */
+
+/* Interrupts on the BadgePAD 4 */
+#define BADGE4_IRQ_GPIO_SA1111		IRQ_GPIO0    /* SA-1111 interrupt */
+
+
+/* PCM5ENV Usage tracking */
+
+#define BADGE4_5V_PCMCIA_SOCK0		(1<<0)
+#define BADGE4_5V_PCMCIA_SOCK1		(1<<1)
+#define BADGE4_5V_PCMCIA_SOCK(n)	(1<<(n))
+#define BADGE4_5V_USB			(1<<2)
+
+#ifndef __ASSEMBLY__
+extern void badge4_set_5V(unsigned subsystem, int on);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/cerf.h linux/include/asm-arm/arch-sa1100/cerf.h
--- linux.orig/include/asm-arm/arch-sa1100/cerf.h	2001-10-25 20:53:54.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/cerf.h	2002-07-20 01:08:40.000000000 +0000
@@ -1,6 +1,8 @@
 #ifndef _INCLUDE_CERF_H_
 #define _INCLUDE_CERF_H_
 
+#include <linux/config.h>
+
 #ifdef CONFIG_SA1100_CERF_CPLD
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/flexanet.h linux/include/asm-arm/arch-sa1100/flexanet.h
--- linux.orig/include/asm-arm/arch-sa1100/flexanet.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/flexanet.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-sa1100/flexanet.h
+ * include/asm-arm/arch-sa1100/flexanet.h
  *
  * Created 2001/05/04 by Jordi Colomer <jco@ict.es>
  *
@@ -11,39 +11,79 @@
 #error "include <asm/hardware.h> instead"
 #endif
 
-
 /* Board Control Register (virtual address) */
-#define BCR_PHYS  0x10000000
-#define BCR_VIRT  0xf0000000
-#define BCR (*(volatile unsigned int *)(BCR_VIRT))
+#define FHH_BCR_PHYS  0x10000000
+#define FHH_BCR_VIRT  0xf0000000
+#define FHH_BCR (*(volatile unsigned int *)(FHH_BCR_VIRT))
 
 /* Power-up value */
-#define BCR_POWERUP	0x00000000
+#define FHH_BCR_POWERUP	0x00000000
 
 /* Mandatory bits */
-#define BCR_LED_GREEN	(1<<0)	/* General-purpose green LED (1 = on) */
-#define BCR_GUI_NRST	(1<<4)	/* GUI board reset (0 = reset) */
-
-/* Board Status Register (virtual address) */
-#define BSR_BASE  BCR_BASE
-#define BSR (*(volatile unsigned int *)(BSR_BASE))
-
+#define FHH_BCR_LED_GREEN  (1<<0)  /* General-purpose green LED (1 = on) */
+#define FHH_BCR_SPARE_1    (1<<1)  /* Not defined */
+#define FHH_BCR_CF1_RST    (1<<2)  /* Compact Flash Slot #1 Reset (1 = reset) */
+#define FHH_BCR_CF2_RST    (1<<3)  /* Compact Flash Slot #2 Reset (1 = reset) */
+#define FHH_BCR_GUI_NRST   (1<<4)  /* GUI board reset (0 = reset) */
+#define FHH_BCR_RTS1       (1<<5)  /* RS232 RTS for UART-1 */
+#define FHH_BCR_RTS3       (1<<6)  /* RS232 RTS for UART-3 */
+#define FHH_BCR_XCDBG0     (1<<7)  /* Not defined. Wired to XPLA3 for debug */
+
+/* BCR extension, only required by L3-bus in some audio codecs */
+#define FHH_BCR_L3MOD      (1<<8)  /* L3-bus MODE signal */
+#define FHH_BCR_L3DAT      (1<<9)  /* L3-bus DATA signal */
+#define FHH_BCR_L3CLK      (1<<10) /* L3-bus CLK signal */
+#define FHH_BCR_SPARE_11   (1<<11) /* Not defined */
+#define FHH_BCR_SPARE_12   (1<<12) /* Not defined */
+#define FHH_BCR_SPARE_13   (1<<13) /* Not defined */
+#define FHH_BCR_SPARE_14   (1<<14) /* Not defined */
+#define FHH_BCR_SPARE_15   (1<<15) /* Not defined */
+
+ /* Board Status Register (virtual address) */
+#define FHH_BSR_BASE  FHH_BCR_VIRT
+#define FHH_BSR (*(volatile unsigned int *)(FHH_BSR_BASE))
+
+#define FHH_BSR_CTS1       (1<<0)  /* RS232 CTS for UART-1 */
+#define FHH_BSR_CTS3       (1<<1)  /* RS232 CTS for UART-3 */
+#define FHH_BSR_DSR1       (1<<2)  /* RS232 DSR for UART-1 */
+#define FHH_BSR_DSR3       (1<<3)  /* RS232 DSR for UART-3 */
+#define FHH_BSR_ID0        (1<<4)  /* Board identification */
+#define FHH_BSR_ID1        (1<<5)
+#define FHH_BSR_CFG0       (1<<6)  /* Board configuration options */
+#define FHH_BSR_CFG1       (1<<7)
 
 #ifndef __ASSEMBLY__
-extern unsigned long BCR_value;	/* Image of the BCR */
-#define BCR_set( x )	BCR = (BCR_value |= (x))
-#define BCR_clear( x )	BCR = (BCR_value &= ~(x))
+extern unsigned long flexanet_BCR;	/* Image of the BCR */
+#define FLEXANET_BCR_set( x )    FHH_BCR = (flexanet_BCR |= (x))
+#define FLEXANET_BCR_clear( x )  FHH_BCR = (flexanet_BCR &= ~(x))
 #endif
 
-
 /* GPIOs for which the generic definition doesn't say much */
-#define GPIO_GUI_IRQ		GPIO_GPIO (23)	/* IRQ from GUI board (i.e., UCB1300) */
-#define GPIO_ETH_IRQ		GPIO_GPIO (24)	/* IRQ from Ethernet controller */
-#define GPIO_LED_RED		GPIO_GPIO (26)	/* General-purpose red LED */
+#define GPIO_CF1_NCD       GPIO_GPIO (14)  /* Card Detect from CF slot #1 */
+#define GPIO_CF2_NCD       GPIO_GPIO (15)  /* Card Detect from CF slot #2 */
+#define GPIO_CF1_IRQ       GPIO_GPIO (16)  /* IRQ from CF slot #1 */
+#define GPIO_CF2_IRQ       GPIO_GPIO (17)  /* IRQ from CF slot #2 */
+#define GPIO_APP_IRQ       GPIO_GPIO (18)  /* Extra IRQ from application bus */
+#define GPIO_RADIO_REF     GPIO_GPIO (20)  /* Ref. clock for UART3 (Radio) */
+#define GPIO_CF1_BVD1      GPIO_GPIO (21)  /* BVD1 from CF slot #1 */
+#define GPIO_CF2_BVD1      GPIO_GPIO (22)  /* BVD1 from CF slot #2 */
+#define GPIO_GUI_IRQ       GPIO_GPIO (23)  /* IRQ from GUI board (i.e., UCB1300) */
+#define GPIO_ETH_IRQ       GPIO_GPIO (24)  /* IRQ from Ethernet controller */
+#define GPIO_INTIP_IRQ     GPIO_GPIO (25)  /* Measurement IRQ (INTIP) */
+#define GPIO_LED_RED       GPIO_GPIO (26)  /* General-purpose red LED */
 
 /* IRQ sources from GPIOs */
-#define IRQ_GPIO_GUI		IRQ_GPIO23
-#define IRQ_GPIO_ETH		IRQ_GPIO24
+#define IRQ_GPIO_CF1_CD    IRQ_GPIO14
+#define IRQ_GPIO_CF2_CD    IRQ_GPIO15
+#define IRQ_GPIO_CF1_IRQ   IRQ_GPIO16
+#define IRQ_GPIO_CF2_IRQ   IRQ_GPIO17
+#define IRQ_GPIO_APP       IRQ_GPIO18
+#define IRQ_GPIO_CF1_BVD1  IRQ_GPIO21
+#define IRQ_GPIO_CF2_BVD1  IRQ_GPIO22
+#define IRQ_GPIO_GUI       IRQ_GPIO23
+#define IRQ_GPIO_ETH       IRQ_GPIO24
+#define IRQ_GPIO_INTIP     IRQ_GPIO25
+
 
 /* On-Board Ethernet */
 #define _FHH_ETH_IOBASE		0x18000000	/* I/O base (physical addr) */
@@ -58,14 +98,3 @@
 #define FHH_ETH_MMBASE		FHH_ETH_p2v(_FHH_ETH_MMBASE)
 
 
-/* Types of GUI */
-#ifndef __ASSEMBLY__
-extern unsigned long GUI_type;
-#endif
-
-#define FHH_GUI_ERROR		0xFFFFFFFF
-#define FHH_GUI_NONE		0x0000000F
-#define FHH_GUI_TYPE_0		0
-#define FHH_GUI_TYPE_1		1
-#define FHH_GUI_TYPE_2		2
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/frodo.h linux/include/asm-arm/arch-sa1100/frodo.h
--- linux.orig/include/asm-arm/arch-sa1100/frodo.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/frodo.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,56 @@
+#ifndef _INCLUDE_FRODO_H_
+#define _INCLUDE_FRODO_H_
+
+/*
+ * linux/include/asm-arm/arch-sa1100/frodo.h
+ *
+ * Author: Abraham van der Merwe <abraham@2d3d.co.za>
+ *
+ * This file contains the hardware specific definitions for 2d3D, Inc.
+ * SA-1110 Development Board.
+ *
+ * Only include this file from SA1100-specific files.
+ *
+ * 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/02/28   Ethernet (cs89x0) support
+ *
+ *   2002/02/27   IDE support
+ *
+ *   2002/02/22   Added some CPLD registers to control backlight and
+ *                general purpose LEDs
+ *
+ *   2002/01/31   Initial version
+ */
+
+/* CPLD registers */
+#define FRODO_CPLD_UART				*((u16 *) 0xf000c000)
+#define FRODO_CPLD_IDE				*((u16 *) 0xf0008000)
+#define FRODO_CPLD_GENERAL			*((u16 *) 0xf0004004)
+#define FRODO_CPLD_PCMCIA_STATUS	*((u16 *) 0xf0004000)
+#define FRODO_CPLD_PCMCIA_COMMAND	*((u16 *) 0xf0000000)
+#define FRODO_CPLD_SCRATCHPAD		*((u16 *) 0xf0000004)
+
+/* general command/status register */
+#define FRODO_LCD_BACKLIGHT			0x0400		/* R/W */
+#define FRODO_LED1					0x0100		/* R/W */
+#define FRODO_LED2					0x0200		/* R/W */
+#define FRODO_PUSHBUTTON			0x8000		/* R/O */
+
+/* IDE related definitions */
+#define FRODO_IDE_GPIO			GPIO_GPIO23
+#define FRODO_IDE_IRQ			IRQ_GPIO23
+#define FRODO_IDE_DATA			0xf0020000
+#define FRODO_IDE_CTRL			0xf0038004
+
+/* Ethernet related definitions */
+#define FRODO_ETH_GPIO			GPIO_GPIO20
+#define FRODO_ETH_IRQ			IRQ_GPIO20
+#define FRODO_ETH_MEMORY		0xf0060000
+#define FRODO_ETH_IO			0xf0070000
+
+#endif	/* _INCLUDE_FRODO_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/graphicsmaster.h linux/include/asm-arm/arch-sa1100/graphicsmaster.h
--- linux.orig/include/asm-arm/arch-sa1100/graphicsmaster.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/graphicsmaster.h	2002-07-20 01:08:21.000000000 +0000
@@ -61,6 +61,4 @@
 #define ADS_DCR		(*((volatile u_char *) ADS_p2v(_ADS_DCR)))
 #endif
 
-#define	SA1111_BASE	(0x18000000)
-
-#include "SA-1111.h"
+#define ADS_SA1111_BASE		(0x18000000)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/h3600.h linux/include/asm-arm/arch-sa1100/h3600.h
--- linux.orig/include/asm-arm/arch-sa1100/h3600.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/h3600.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,81 +1,153 @@
 /*
-*
-* Definitions for H3600 Handheld Computer
-*
-* Copyright 2000 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.
-*
-*/
+ *
+ * Definitions for H3600 Handheld Computer
+ *
+ * Copyright 2000 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
+ *
+ */
 
 #ifndef _INCLUDE_H3600_H_
 #define _INCLUDE_H3600_H_
 
-#define GPIO_H3600_NPOWER_BUTTON	GPIO_GPIO (0)
-#define GPIO_H3600_ACTION_BUTTON	GPIO_GPIO (18)
+#include <linux/config.h>
+
+/* generalized support for H3xxx series Compaq Pocket PC's */
+#define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600() || machine_is_h3800())
+
+/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
+#define H3600_EGPIO_VIRT     0xf0000000
+#define H3600_BANK_2_VIRT    0xf1000000
+#define H3600_BANK_4_VIRT    0xf3800000
+
+/*
+   Machine-independent GPIO definitions
+   --- these are common across all current iPAQ platforms
+*/
+
+#define GPIO_H3600_NPOWER_BUTTON	GPIO_GPIO (0)	/* Also known as the "off button"  */
+#define GPIO_H3600_MICROCONTROLLER	GPIO_GPIO (1)	/* From ASIC2 on H3800 */
 
-#define GPIO_H3600_PCMCIA_CD0		GPIO_GPIO (17)
 #define GPIO_H3600_PCMCIA_CD1		GPIO_GPIO (10)
-#define GPIO_H3600_PCMCIA_IRQ0		GPIO_GPIO (21)
 #define GPIO_H3600_PCMCIA_IRQ1		GPIO_GPIO (11)
 
-/* audio sample rate clock generator */
-#define GPIO_H3600_CLK_SET0		GPIO_GPIO (12)
-#define GPIO_H3600_CLK_SET1		GPIO_GPIO (13)
-
 /* UDA1341 L3 Interface */
 #define GPIO_H3600_L3_DATA		GPIO_GPIO (14)
-#define GPIO_H3600_L3_CLOCK		GPIO_GPIO (16)
 #define GPIO_H3600_L3_MODE		GPIO_GPIO (15)
+#define GPIO_H3600_L3_CLOCK		GPIO_GPIO (16)
 
-#define GPIO_H3600_OPT_LOCK		GPIO_GPIO (22)
-#define GPIO_H3600_OPT_IRQ		GPIO_GPIO (24)
-#define GPIO_H3600_OPT_DET		GPIO_GPIO (27)
+#define GPIO_H3600_PCMCIA_CD0		GPIO_GPIO (17)
+#define GPIO_H3600_SYS_CLK		GPIO_GPIO (19)
+#define GPIO_H3600_PCMCIA_IRQ0		GPIO_GPIO (21)
 
 #define GPIO_H3600_COM_DCD		GPIO_GPIO (23)
+#define GPIO_H3600_OPT_IRQ		GPIO_GPIO (24)
 #define GPIO_H3600_COM_CTS		GPIO_GPIO (25)
 #define GPIO_H3600_COM_RTS		GPIO_GPIO (26)
 
-#define IRQ_GPIO_H3600_NPOWER_BUTTON    IRQ_GPIO0
-#define IRQ_GPIO_H3600_ACTION_BUTTON    IRQ_GPIO18
-#define IRQ_GPIO_H3600_PCMCIA_CD0	IRQ_GPIO17
+#define IRQ_GPIO_H3600_NPOWER_BUTTON	IRQ_GPIO0
+#define IRQ_GPIO_H3600_MICROCONTROLLER	IRQ_GPIO1
 #define IRQ_GPIO_H3600_PCMCIA_CD1	IRQ_GPIO10
-#define IRQ_GPIO_H3600_PCMCIA_IRQ0	IRQ_GPIO21
 #define IRQ_GPIO_H3600_PCMCIA_IRQ1	IRQ_GPIO11
+#define IRQ_GPIO_H3600_PCMCIA_CD0	IRQ_GPIO17
+#define IRQ_GPIO_H3600_PCMCIA_IRQ0	IRQ_GPIO21
+#define IRQ_GPIO_H3600_COM_DCD		IRQ_GPIO23
 #define IRQ_GPIO_H3600_OPT_IRQ		IRQ_GPIO24
-#define IRQ_GPIO_H3600_OPT_DET		IRQ_GPIO27
-#define IRQ_GPIO_H3600_COM_DCD          IRQ_GPIO23
-#define IRQ_GPIO_H3600_COM_CTS          IRQ_GPIO25
-
-#define EGPIO_H3600_VPP_ON		(1 << 0)
-#define EGPIO_H3600_CARD_RESET		(1 << 1)  /* reset the attached pcmcia/compactflash card.  active high. */
-#define EGPIO_H3600_OPT_RESET		(1 << 2)  /* reset the attached option pack.  active high. */
-#define EGPIO_H3600_CODEC_NRESET	(1 << 3)  /* reset the onboard UDA1341.  active low. */
-#define EGPIO_H3600_OPT_NVRAM_ON	(1 << 4)  /* apply power to optionpack nvram, active high. */
-#define EGPIO_H3600_OPT_ON		(1 << 5)  /* full power to option pack.  active high. */
-#define EGPIO_H3600_LCD_ON       	(1 << 6)  /* enable 3.3V to LCD.  active high. */
-#define EGPIO_H3600_RS232_ON		(1 << 7)  /* UART3 transceiver force on.  Active high. */
-#define EGPIO_H3600_LCD_PCI		(1 << 8)  /* LCD control IC enable.  active high. */
-#define EGPIO_H3600_IR_ON		(1 << 9)  /* apply power to IR module.  active high. */
-#define EGPIO_H3600_AUD_AMP_ON		(1 << 10) /* apply power to audio power amp.  active high. */
-#define EGPIO_H3600_AUD_PWR_ON		(1 << 11) /* apply poewr to reset of audio circuit.  active high. */
-#define EGPIO_H3600_QMUTE		(1 << 12) /* mute control for onboard UDA1341.  active high. */
-#define EGPIO_H3600_IR_FSEL		(1 << 13) /* IR speed select: 1->fast, 0->slow */
-#define EGPIO_H3600_LCD_5V_ON		(1 << 14) /* enable 5V to LCD. active high. */
-#define EGPIO_H3600_LVDD_ON		(1 << 15) /* enable 9V and -6.5V to LCD. */
+#define IRQ_GPIO_H3600_COM_CTS		IRQ_GPIO25
+
 
 #ifndef __ASSEMBLY__
-#define H3600_EGPIO	(*(volatile int *)0xf0000000)
-extern void clr_h3600_egpio(unsigned long x);
-extern void set_h3600_egpio(unsigned long x);
-#endif
+enum ipaq_model {
+	IPAQ_H3100,
+	IPAQ_H3600,
+	IPAQ_H3800
+};
+
+enum ipaq_egpio_type {
+	IPAQ_EGPIO_LCD_ON,	  /* Power to the LCD panel */
+	IPAQ_EGPIO_CODEC_NRESET,  /* Clear to reset the audio codec (remember to return high) */
+	IPAQ_EGPIO_AUDIO_ON,	  /* Audio power */
+	IPAQ_EGPIO_QMUTE,	  /* Audio muting */
+	IPAQ_EGPIO_OPT_NVRAM_ON,  /* Non-volatile RAM on extension sleeves (SPI interface) */
+	IPAQ_EGPIO_OPT_ON,	  /* Power to extension sleeves */
+	IPAQ_EGPIO_CARD_RESET,	  /* Reset PCMCIA cards on extension sleeve (???) */
+	IPAQ_EGPIO_OPT_RESET,	  /* Reset option pack (???) */
+	IPAQ_EGPIO_IR_ON,	  /* IR sensor/emitter power */
+	IPAQ_EGPIO_IR_FSEL,	  /* IR speed selection 1->fast, 0->slow */
+	IPAQ_EGPIO_RS232_ON,	  /* Maxim RS232 chip power */
+	IPAQ_EGPIO_VPP_ON,	  /* Turn on power to flash programming */
+};
+
+struct ipaq_model_ops {
+	enum ipaq_model model;
+	const char     *generic_name;
+	void	      (*initialize)(void);
+	void	      (*control)(enum ipaq_egpio_type, int);
+	unsigned long (*read)(void);
+};
+
+extern struct ipaq_model_ops ipaq_model_ops;
+
+#ifdef CONFIG_SA1100_H3XXX
+static __inline__ enum ipaq_model h3600_model( void ) {
+	return ipaq_model_ops.model;
+}
+
+static __inline__ const char * h3600_generic_name( void ) {
+	return ipaq_model_ops.generic_name;
+}
+
+static __inline__ void init_h3600_egpio( void ) {
+	if (ipaq_model_ops.initialize)
+		ipaq_model_ops.initialize();
+}
+
+static __inline__ void assign_h3600_egpio( enum ipaq_egpio_type x, int level ) {
+	if (ipaq_model_ops.control)
+		ipaq_model_ops.control(x,level);
+}
+
+static __inline__ void clr_h3600_egpio( enum ipaq_egpio_type x ) {
+	if (ipaq_model_ops.control)
+		ipaq_model_ops.control(x,0);
+}
+
+static __inline__ void set_h3600_egpio( enum ipaq_egpio_type x ) {
+	if (ipaq_model_ops.control)
+		ipaq_model_ops.control(x,1);
+}
+
+static __inline__ unsigned long read_h3600_egpio( void ) {
+	if (ipaq_model_ops.read)
+		return ipaq_model_ops.read();
+	return 0;
+}
+
+#else
+
+/*
+ * This allows some drives to loose some ifdefs
+ */
+#define assign_h3600_egpio(x,y)	do { } while (0)
+#define clr_h3600_egpio(x)	do { } while (0)
+#define set_h3600_egpio(x)	do { } while (0)
+#define read_h3600_egpio()	(0)
 
 #endif
+
+#endif /* ASSEMBLY */
+
+#endif /* _INCLUDE_H3600_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/h3600_gpio.h linux/include/asm-arm/arch-sa1100/h3600_gpio.h
--- linux.orig/include/asm-arm/arch-sa1100/h3600_gpio.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/h3600_gpio.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,540 @@
+/*
+ *
+ * Definitions for H3600 Handheld Computer
+ *
+ * Copyright 2000 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
+ *
+ */
+
+#ifndef _INCLUDE_H3600_GPIO_H_
+#define _INCLUDE_H3600_GPIO_H_
+
+/*
+ * GPIO lines that are common across ALL iPAQ models are in "h3600.h"
+ * This file contains machine-specific definitions
+ */
+
+#define GPIO_H3600_SUSPEND              GPIO_GPIO (0)
+/* GPIO[2:9] used by LCD on H3600/3800, used as GPIO on H3100 */
+#define GPIO_H3100_BT_ON		GPIO_GPIO (2)
+#define GPIO_H3100_GPIO3		GPIO_GPIO (3)
+#define GPIO_H3100_QMUTE		GPIO_GPIO (4)
+#define GPIO_H3100_LCD_3V_ON		GPIO_GPIO (5)
+#define GPIO_H3100_AUD_ON		GPIO_GPIO (6)
+#define GPIO_H3100_AUD_PWR_ON		GPIO_GPIO (7)
+#define GPIO_H3100_IR_ON		GPIO_GPIO (8)
+#define GPIO_H3100_IR_FSEL		GPIO_GPIO (9)
+
+/* for H3600, audio sample rate clock generator */
+#define GPIO_H3600_CLK_SET0		GPIO_GPIO (12)
+#define GPIO_H3600_CLK_SET1		GPIO_GPIO (13)
+
+#define GPIO_H3600_ACTION_BUTTON	GPIO_GPIO (18)
+#define GPIO_H3600_SOFT_RESET           GPIO_GPIO (20)   /* Also known as BATT_FAULT */
+#define GPIO_H3600_OPT_LOCK		GPIO_GPIO (22)
+#define GPIO_H3600_OPT_DET		GPIO_GPIO (27)
+
+/* H3800 specific pins */
+#define GPIO_H3800_AC_IN                GPIO_GPIO (12)
+#define GPIO_H3800_COM_DSR              GPIO_GPIO (13)
+#define GPIO_H3800_MMC_INT              GPIO_GPIO (18)
+#define GPIO_H3800_NOPT_IND             GPIO_GPIO (20)   /* Almost exactly the same as GPIO_H3600_OPT_DET */
+#define GPIO_H3800_OPT_BAT_FAULT        GPIO_GPIO (22)
+#define GPIO_H3800_CLK_OUT              GPIO_GPIO (27)
+
+/****************************************************/
+
+#define IRQ_GPIO_H3600_ACTION_BUTTON    IRQ_GPIO18
+#define IRQ_GPIO_H3600_OPT_DET		IRQ_GPIO27
+
+#define IRQ_GPIO_H3800_MMC_INT          IRQ_GPIO18
+#define IRQ_GPIO_H3800_NOPT_IND         IRQ_GPIO20 /* almost same as OPT_DET */
+
+/* H3100 / 3600 EGPIO pins */
+#define EGPIO_H3600_VPP_ON		(1 << 0)
+#define EGPIO_H3600_CARD_RESET		(1 << 1)   /* reset the attached pcmcia/compactflash card.  active high. */
+#define EGPIO_H3600_OPT_RESET		(1 << 2)   /* reset the attached option pack.  active high. */
+#define EGPIO_H3600_CODEC_NRESET	(1 << 3)   /* reset the onboard UDA1341.  active low. */
+#define EGPIO_H3600_OPT_NVRAM_ON	(1 << 4)   /* apply power to optionpack nvram, active high. */
+#define EGPIO_H3600_OPT_ON		(1 << 5)   /* full power to option pack.  active high. */
+#define EGPIO_H3600_LCD_ON		(1 << 6)   /* enable 3.3V to LCD.  active high. */
+#define EGPIO_H3600_RS232_ON		(1 << 7)   /* UART3 transceiver force on.  Active high. */
+
+/* H3600 only EGPIO pins */
+#define EGPIO_H3600_LCD_PCI		(1 << 8)   /* LCD control IC enable.  active high. */
+#define EGPIO_H3600_IR_ON		(1 << 9)   /* apply power to IR module.  active high. */
+#define EGPIO_H3600_AUD_AMP_ON		(1 << 10)  /* apply power to audio power amp.  active high. */
+#define EGPIO_H3600_AUD_PWR_ON		(1 << 11)  /* apply power to reset of audio circuit.  active high. */
+#define EGPIO_H3600_QMUTE		(1 << 12)  /* mute control for onboard UDA1341.  active high. */
+#define EGPIO_H3600_IR_FSEL		(1 << 13)  /* IR speed select: 1->fast, 0->slow */
+#define EGPIO_H3600_LCD_5V_ON		(1 << 14)  /* enable 5V to LCD. active high. */
+#define EGPIO_H3600_LVDD_ON		(1 << 15)  /* enable 9V and -6.5V to LCD. */
+
+/********************* H3800, ASIC #2 ********************/
+
+#define _H3800_ASIC2_Base            (H3600_EGPIO_VIRT)
+#define H3800_ASIC2_OFFSET(s,x,y)    \
+    (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC2_ ## x ## _Base + _H3800_ASIC2_ ## x ## _ ## y)))
+#define H3800_ASIC2_NOFFSET(s,x,n,y) \
+    (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC2_ ## x ## _ ## n ## _Base + _H3800_ASIC2_ ## x ## _ ## y)))
+
+#define _H3800_ASIC2_GPIO_Base                 0x0000
+#define _H3800_ASIC2_GPIO_Direction            0x0000    /* R/W, 16 bits 1:input, 0:output */
+#define _H3800_ASIC2_GPIO_InterruptType        0x0004    /* R/W, 12 bits 1:edge, 0:level          */
+#define _H3800_ASIC2_GPIO_InterruptEdgeType    0x0008    /* R/W, 12 bits 1:rising, 0:falling */
+#define _H3800_ASIC2_GPIO_InterruptLevelType   0x000C    /* R/W, 12 bits 1:high, 0:low  */
+#define _H3800_ASIC2_GPIO_InterruptClear       0x0010    /* W,   12 bits */
+#define _H3800_ASIC2_GPIO_InterruptFlag        0x0010    /* R,   12 bits - reads int status */
+#define _H3800_ASIC2_GPIO_Data                 0x0014    /* R/W, 16 bits */
+#define _H3800_ASIC2_GPIO_BattFaultOut         0x0018    /* R/W, 16 bit - sets level on batt fault */
+#define _H3800_ASIC2_GPIO_InterruptEnable      0x001c    /* R/W, 12 bits 1:enable interrupt */
+#define _H3800_ASIC2_GPIO_Alternate            0x003c    /* R/W, 12+1 bits - set alternate functions */
+
+#define H3800_ASIC2_GPIO_Direction          H3800_ASIC2_OFFSET( u16, GPIO, Direction )
+#define H3800_ASIC2_GPIO_InterruptType      H3800_ASIC2_OFFSET( u16, GPIO, InterruptType )
+#define H3800_ASIC2_GPIO_InterruptEdgeType  H3800_ASIC2_OFFSET( u16, GPIO, InterruptEdgeType )
+#define H3800_ASIC2_GPIO_InterruptLevelType H3800_ASIC2_OFFSET( u16, GPIO, InterruptLevelType )
+#define H3800_ASIC2_GPIO_InterruptClear     H3800_ASIC2_OFFSET( u16, GPIO, InterruptClear )
+#define H3800_ASIC2_GPIO_InterruptFlag      H3800_ASIC2_OFFSET( u16, GPIO, InterruptFlag )
+#define H3800_ASIC2_GPIO_Data               H3800_ASIC2_OFFSET( u16, GPIO, Data )
+#define H3800_ASIC2_GPIO_BattFaultOut       H3800_ASIC2_OFFSET( u16, GPIO, BattFaultOut )
+#define H3800_ASIC2_GPIO_InterruptEnable    H3800_ASIC2_OFFSET( u16, GPIO, InterruptEnable )
+#define H3800_ASIC2_GPIO_Alternate          H3800_ASIC2_OFFSET( u16, GPIO, Alternate )
+
+#define GPIO_H3800_ASIC2_IN_Y1_N          (1 << 0)   /* Output: Touchscreen Y1 */
+#define GPIO_H3800_ASIC2_IN_X0            (1 << 1)   /* Output: Touchscreen X0 */
+#define GPIO_H3800_ASIC2_IN_Y0            (1 << 2)   /* Output: Touchscreen Y0 */
+#define GPIO_H3800_ASIC2_IN_X1_N          (1 << 3)   /* Output: Touchscreen X1 */
+#define GPIO_H3800_ASIC2_BT_RST           (1 << 4)   /* Output: Bluetooth reset */
+#define GPIO_H3800_ASIC2_PEN_IRQ          (1 << 5)   /* Input : Pen down        */
+#define GPIO_H3800_ASIC2_SD_DETECT        (1 << 6)   /* Input : SD detect */
+#define GPIO_H3800_ASIC2_EAR_IN_N         (1 << 7)   /* Input : Audio jack plug inserted */
+#define GPIO_H3800_ASIC2_OPT_PCM_RESET    (1 << 8)   /* Output: */
+#define GPIO_H3800_ASIC2_OPT_RESET        (1 << 9)   /* Output: */
+#define GPIO_H3800_ASIC2_USB_DETECT_N     (1 << 10)  /* Input : */
+#define GPIO_H3800_ASIC2_SD_CON_SLT       (1 << 11)  /* Input : */
+
+#define _H3800_ASIC2_KPIO_Base                 0x0200
+#define _H3800_ASIC2_KPIO_Direction            0x0000    /* R/W, 12 bits 1:input, 0:output */
+#define _H3800_ASIC2_KPIO_InterruptType        0x0004    /* R/W, 12 bits 1:edge, 0:level          */
+#define _H3800_ASIC2_KPIO_InterruptEdgeType    0x0008    /* R/W, 12 bits 1:rising, 0:falling */
+#define _H3800_ASIC2_KPIO_InterruptLevelType   0x000C    /* R/W, 12 bits 1:high, 0:low  */
+#define _H3800_ASIC2_KPIO_InterruptClear       0x0010    /* W,   20 bits - 8 special */
+#define _H3800_ASIC2_KPIO_InterruptFlag        0x0010    /* R,   20 bits - 8 special - reads int status */
+#define _H3800_ASIC2_KPIO_Data                 0x0014    /* R/W, 16 bits */
+#define _H3800_ASIC2_KPIO_BattFaultOut         0x0018    /* R/W, 16 bit - sets level on batt fault */
+#define _H3800_ASIC2_KPIO_InterruptEnable      0x001c    /* R/W, 20 bits - 8 special */
+#define _H3800_ASIC2_KPIO_Alternate            0x003c    /* R/W, 6 bits */
+
+#define H3800_ASIC2_KPIO_Direction          H3800_ASIC2_OFFSET( u16, KPIO, Direction )
+#define H3800_ASIC2_KPIO_InterruptType      H3800_ASIC2_OFFSET( u16, KPIO, InterruptType )
+#define H3800_ASIC2_KPIO_InterruptEdgeType  H3800_ASIC2_OFFSET( u16, KPIO, InterruptEdgeType )
+#define H3800_ASIC2_KPIO_InterruptLevelType H3800_ASIC2_OFFSET( u16, KPIO, InterruptLevelType )
+#define H3800_ASIC2_KPIO_InterruptClear     H3800_ASIC2_OFFSET( u32, KPIO, InterruptClear )
+#define H3800_ASIC2_KPIO_InterruptFlag      H3800_ASIC2_OFFSET( u32, KPIO, InterruptFlag )
+#define H3800_ASIC2_KPIO_Data               H3800_ASIC2_OFFSET( u16, KPIO, Data )
+#define H3800_ASIC2_KPIO_BattFaultOut       H3800_ASIC2_OFFSET( u16, KPIO, BattFaultOut )
+#define H3800_ASIC2_KPIO_InterruptEnable    H3800_ASIC2_OFFSET( u32, KPIO, InterruptEnable )
+#define H3800_ASIC2_KPIO_Alternate          H3800_ASIC2_OFFSET( u16, KPIO, Alternate )
+
+#define H3800_ASIC2_KPIO_SPI_INT        ( 1 << 16 )
+#define H3800_ASIC2_KPIO_OWM_INT        ( 1 << 17 )
+#define H3800_ASIC2_KPIO_ADC_INT        ( 1 << 18 )
+#define H3800_ASIC2_KPIO_UART_0_INT     ( 1 << 19 )
+#define H3800_ASIC2_KPIO_UART_1_INT     ( 1 << 20 )
+#define H3800_ASIC2_KPIO_TIMER_0_INT    ( 1 << 21 )
+#define H3800_ASIC2_KPIO_TIMER_1_INT    ( 1 << 22 )
+#define H3800_ASIC2_KPIO_TIMER_2_INT    ( 1 << 23 )
+
+#define KPIO_H3800_ASIC2_RECORD_BTN_N     (1 << 0)   /* Record button */
+#define KPIO_H3800_ASIC2_KEY_5W1_N        (1 << 1)   /* Keypad */
+#define KPIO_H3800_ASIC2_KEY_5W2_N        (1 << 2)   /* */
+#define KPIO_H3800_ASIC2_KEY_5W3_N        (1 << 3)   /* */
+#define KPIO_H3800_ASIC2_KEY_5W4_N        (1 << 4)   /* */
+#define KPIO_H3800_ASIC2_KEY_5W5_N        (1 << 5)   /* */
+#define KPIO_H3800_ASIC2_KEY_LEFT_N       (1 << 6)   /* */
+#define KPIO_H3800_ASIC2_KEY_RIGHT_N      (1 << 7)   /* */
+#define KPIO_H3800_ASIC2_KEY_AP1_N        (1 << 8)   /* Old "Calendar" */
+#define KPIO_H3800_ASIC2_KEY_AP2_N        (1 << 9)   /* Old "Schedule" */
+#define KPIO_H3800_ASIC2_KEY_AP3_N        (1 << 10)  /* Old "Q"        */
+#define KPIO_H3800_ASIC2_KEY_AP4_N        (1 << 11)  /* Old "Undo"     */
+
+/* Alternate KPIO functions (set by default) */
+#define KPIO_ALT_H3800_ASIC2_KEY_5W1_N        (1 << 1)   /* Action key */
+#define KPIO_ALT_H3800_ASIC2_KEY_5W2_N        (1 << 2)   /* J1 of keypad input */
+#define KPIO_ALT_H3800_ASIC2_KEY_5W3_N        (1 << 3)   /* J2 of keypad input */
+#define KPIO_ALT_H3800_ASIC2_KEY_5W4_N        (1 << 4)   /* J3 of keypad input */
+#define KPIO_ALT_H3800_ASIC2_KEY_5W5_N        (1 << 5)   /* J4 of keypad input */
+
+#define _H3800_ASIC2_SPI_Base                  0x0400
+#define _H3800_ASIC2_SPI_Control               0x0000    /* R/W 8 bits */
+#define _H3800_ASIC2_SPI_Data                  0x0004    /* R/W 8 bits */
+#define _H3800_ASIC2_SPI_ChipSelectDisabled    0x0008    /* W   8 bits */
+
+#define H3800_ASIC2_SPI_Control             H3800_ASIC2_OFFSET( u8, SPI, Control )
+#define H3800_ASIC2_SPI_Data                H3800_ASIC2_OFFSET( u8, SPI, Data )
+#define H3800_ASIC2_SPI_ChipSelectDisabled  H3800_ASIC2_OFFSET( u8, SPI, ChipSelectDisabled )
+
+#define _H3800_ASIC2_PWM_0_Base                0x0600
+#define _H3800_ASIC2_PWM_1_Base                0x0700
+#define _H3800_ASIC2_PWM_TimeBase              0x0000    /* R/W 6 bits */
+#define _H3800_ASIC2_PWM_PeriodTime            0x0004    /* R/W 12 bits */
+#define _H3800_ASIC2_PWM_DutyTime              0x0008    /* R/W 12 bits */
+
+#define H3800_ASIC2_PWM_0_TimeBase          H3800_ASIC2_NOFFSET(  u8, PWM, 0, TimeBase )
+#define H3800_ASIC2_PWM_0_PeriodTime        H3800_ASIC2_NOFFSET( u16, PWM, 0, PeriodTime )
+#define H3800_ASIC2_PWM_0_DutyTime          H3800_ASIC2_NOFFSET( u16, PWM, 0, DutyTime )
+
+#define H3800_ASIC2_PWM_1_TimeBase          H3800_ASIC2_NOFFSET(  u8, PWM, 1, TimeBase )
+#define H3800_ASIC2_PWM_1_PeriodTime        H3800_ASIC2_NOFFSET( u16, PWM, 1, PeriodTime )
+#define H3800_ASIC2_PWM_1_DutyTime          H3800_ASIC2_NOFFSET( u16, PWM, 1, DutyTime )
+
+#define H3800_ASIC2_PWM_TIMEBASE_MASK             0xf    /* Low 4 bits sets time base, max = 8 */
+#define H3800_ASIC2_PWM_TIMEBASE_ENABLE    ( 1 << 4 )    /* Enable clock */
+#define H3800_ASIC2_PWM_TIMEBASE_CLEAR     ( 1 << 5 )    /* Clear the PWM */
+
+#define _H3800_ASIC2_LED_0_Base                0x0800
+#define _H3800_ASIC2_LED_1_Base                0x0880
+#define _H3800_ASIC2_LED_2_Base                0x0900
+#define _H3800_ASIC2_LED_TimeBase              0x0000    /* R/W  7 bits */
+#define _H3800_ASIC2_LED_PeriodTime            0x0004    /* R/W 12 bits */
+#define _H3800_ASIC2_LED_DutyTime              0x0008    /* R/W 12 bits */
+#define _H3800_ASIC2_LED_AutoStopCount         0x000c    /* R/W 16 bits */
+
+#define H3800_ASIC2_LED_0_TimeBase          H3800_ASIC2_NOFFSET(  u8, LED, 0, TimeBase )
+#define H3800_ASIC2_LED_0_PeriodTime        H3800_ASIC2_NOFFSET( u16, LED, 0, PeriodTime )
+#define H3800_ASIC2_LED_0_DutyTime          H3800_ASIC2_NOFFSET( u16, LED, 0, DutyTime )
+#define H3800_ASIC2_LED_0_AutoStopClock     H3800_ASIC2_NOFFSET( u16, LED, 0, AutoStopClock )
+
+#define H3800_ASIC2_LED_1_TimeBase          H3800_ASIC2_NOFFSET(  u8, LED, 1, TimeBase )
+#define H3800_ASIC2_LED_1_PeriodTime        H3800_ASIC2_NOFFSET( u16, LED, 1, PeriodTime )
+#define H3800_ASIC2_LED_1_DutyTime          H3800_ASIC2_NOFFSET( u16, LED, 1, DutyTime )
+#define H3800_ASIC2_LED_1_AutoStopClock     H3800_ASIC2_NOFFSET( u16, LED, 1, AutoStopClock )
+
+#define H3800_ASIC2_LED_2_TimeBase          H3800_ASIC2_NOFFSET(  u8, LED, 2, TimeBase )
+#define H3800_ASIC2_LED_2_PeriodTime        H3800_ASIC2_NOFFSET( u16, LED, 2, PeriodTime )
+#define H3800_ASIC2_LED_2_DutyTime          H3800_ASIC2_NOFFSET( u16, LED, 2, DutyTime )
+#define H3800_ASIC2_LED_2_AutoStopClock     H3800_ASIC2_NOFFSET( u16, LED, 2, AutoStopClock )
+
+#define H3800_ASIC2_LED_TIMEBASE_MASK            0x0f    /* Low 4 bits sets time base, max = 13 */
+#define H3800_ASIC2_LED_TIMEBASE_BLINK     ( 1 << 4 )    /* Enable blinking */
+#define H3800_ASIC2_LED_TIMEBASE_AUTOSTOP  ( 1 << 5 )
+#define H3800_ASIC2_LED_TIMEBASE_ALWAYS    ( 1 << 6 )    /* Enable blink always */
+
+#define _H3800_ASIC2_UART_0_Base               0x0A00
+#define _H3800_ASIC2_UART_1_Base               0x0C00
+#define _H3800_ASIC2_UART_Receive              0x0000    /* R    8 bits */
+#define _H3800_ASIC2_UART_Transmit             0x0000    /*   W  8 bits */
+#define _H3800_ASIC2_UART_IntEnable            0x0004    /* R/W  8 bits */
+#define _H3800_ASIC2_UART_IntVerify            0x0008    /* R/W  8 bits */
+#define _H3800_ASIC2_UART_FIFOControl          0x000c    /* R/W  8 bits */
+#define _H3800_ASIC2_UART_LineControl          0x0010    /* R/W  8 bits */
+#define _H3800_ASIC2_UART_ModemStatus          0x0014    /* R/W  8 bits */
+#define _H3800_ASIC2_UART_LineStatus           0x0018    /* R/W  8 bits */
+#define _H3800_ASIC2_UART_ScratchPad           0x001c    /* R/W  8 bits */
+#define _H3800_ASIC2_UART_DivisorLatchL        0x0020    /* R/W  8 bits */
+#define _H3800_ASIC2_UART_DivisorLatchH        0x0024    /* R/W  8 bits */
+
+#define H3800_ASIC2_UART_0_Receive          H3800_ASIC2_NOFFSET(  u8, UART, 0, Receive )
+#define H3800_ASIC2_UART_0_Transmit         H3800_ASIC2_NOFFSET(  u8, UART, 0, Transmit )
+#define H3800_ASIC2_UART_0_IntEnable        H3800_ASIC2_NOFFSET(  u8, UART, 0, IntEnable )
+#define H3800_ASIC2_UART_0_IntVerify        H3800_ASIC2_NOFFSET(  u8, UART, 0, IntVerify )
+#define H3800_ASIC2_UART_0_FIFOControl      H3800_ASIC2_NOFFSET(  u8, UART, 0, FIFOControl )
+#define H3800_ASIC2_UART_0_LineControl      H3800_ASIC2_NOFFSET(  u8, UART, 0, LineControl )
+#define H3800_ASIC2_UART_0_ModemStatus      H3800_ASIC2_NOFFSET(  u8, UART, 0, ModemStatus )
+#define H3800_ASIC2_UART_0_LineStatus       H3800_ASIC2_NOFFSET(  u8, UART, 0, LineStatus )
+#define H3800_ASIC2_UART_0_ScratchPad       H3800_ASIC2_NOFFSET(  u8, UART, 0, ScratchPad )
+#define H3800_ASIC2_UART_0_DivisorLatchL    H3800_ASIC2_NOFFSET(  u8, UART, 0, DivisorLatchL )
+#define H3800_ASIC2_UART_0_DivisorLatchH    H3800_ASIC2_NOFFSET(  u8, UART, 0, DivisorLatchH )
+
+#define H3800_ASIC2_UART_1_Receive          H3800_ASIC2_NOFFSET(  u8, UART, 1, Receive )
+#define H3800_ASIC2_UART_1_Transmit         H3800_ASIC2_NOFFSET(  u8, UART, 1, Transmit )
+#define H3800_ASIC2_UART_1_IntEnable        H3800_ASIC2_NOFFSET(  u8, UART, 1, IntEnable )
+#define H3800_ASIC2_UART_1_IntVerify        H3800_ASIC2_NOFFSET(  u8, UART, 1, IntVerify )
+#define H3800_ASIC2_UART_1_FIFOControl      H3800_ASIC2_NOFFSET(  u8, UART, 1, FIFOControl )
+#define H3800_ASIC2_UART_1_LineControl      H3800_ASIC2_NOFFSET(  u8, UART, 1, LineControl )
+#define H3800_ASIC2_UART_1_ModemStatus      H3800_ASIC2_NOFFSET(  u8, UART, 1, ModemStatus )
+#define H3800_ASIC2_UART_1_LineStatus       H3800_ASIC2_NOFFSET(  u8, UART, 1, LineStatus )
+#define H3800_ASIC2_UART_1_ScratchPad       H3800_ASIC2_NOFFSET(  u8, UART, 1, ScratchPad )
+#define H3800_ASIC2_UART_1_DivisorLatchL    H3800_ASIC2_NOFFSET(  u8, UART, 1, DivisorLatchL )
+#define H3800_ASIC2_UART_1_DivisorLatchH    H3800_ASIC2_NOFFSET(  u8, UART, 1, DivisorLatchH )
+
+#define _H3800_ASIC2_TIMER_Base                0x0E00
+#define _H3800_ASIC2_TIMER_Command             0x0000    /* R/W  8 bits */
+
+#define H3800_ASIC2_TIMER_Command           H3800_ASIC2_OFFSET( u8, Timer, Command )
+
+#define H3800_ASIC2_TIMER_GAT_0            ( 1 << 0 )    /* Gate enable, counter 0 */
+#define H3800_ASIC2_TIMER_GAT_1            ( 1 << 1 )    /* Gate enable, counter 1 */
+#define H3800_ASIC2_TIMER_GAT_2            ( 1 << 2 )    /* Gate enable, counter 2 */
+#define H3800_ASIC2_TIMER_CLK_0            ( 1 << 3 )    /* Clock enable, counter 0 */
+#define H3800_ASIC2_TIMER_CLK_1            ( 1 << 4 )    /* Clock enable, counter 1 */
+#define H3800_ASIC2_TIMER_CLK_2            ( 1 << 5 )    /* Clock enable, counter 2 */
+#define H3800_ASIC2_TIMER_MODE_0           ( 1 << 6 )    /* Mode 0 enable, counter 0 */
+#define H3800_ASIC2_TIMER_MODE_1           ( 1 << 7 )    /* Mode 0 enable, counter 1 */
+
+#define _H3800_ASIC2_CLOCK_Base                0x1000
+#define _H3800_ASIC2_CLOCK_Enable              0x0000    /* R/W  18 bits */
+
+#define H3800_ASIC2_CLOCK_Enable            H3800_ASIC2_OFFSET( u32, CLOCK, Enable )
+
+#define H3800_ASIC2_CLOCK_AUDIO_1              0x0001    /* Enable 4.1 MHz clock for 8Khz and 4khz sample rate */
+#define H3800_ASIC2_CLOCK_AUDIO_2              0x0002    /* Enable 12.3 MHz clock for 48Khz and 32khz sample rate */
+#define H3800_ASIC2_CLOCK_AUDIO_3              0x0004    /* Enable 5.6 MHz clock for 11 kHZ sample rate */
+#define H3800_ASIC2_CLOCK_AUDIO_4              0x0008    /* Enable 11.289 MHz clock for 44 and 22 kHz sample rate */
+#define H3800_ASIC2_CLOCK_ADC              ( 1 << 4 )    /* 1.024 MHz clock to ADC */
+#define H3800_ASIC2_CLOCK_SPI              ( 1 << 5 )    /* 4.096 MHz clock to SPI */
+#define H3800_ASIC2_CLOCK_OWM              ( 1 << 6 )    /* 4.096 MHz clock to OWM */
+#define H3800_ASIC2_CLOCK_PWM              ( 1 << 7 )    /* 2.048 MHz clock to PWM */
+#define H3800_ASIC2_CLOCK_UART_1           ( 1 << 8 )    /* 24.576 MHz clock to UART1 (turn off bit 16) */
+#define H3800_ASIC2_CLOCK_UART_0           ( 1 << 9 )    /* 24.576 MHz clock to UART0 (turn off bit 17) */
+#define H3800_ASIC2_CLOCK_SD_1             ( 1 << 10 )   /* 16.934 MHz to SD */
+#define H3800_ASIC2_CLOCK_SD_2             ( 2 << 10 )   /* 24.576 MHz to SD */
+#define H3800_ASIC2_CLOCK_SD_3             ( 3 << 10 )   /* 33.869 MHz to SD */
+#define H3800_ASIC2_CLOCK_SD_4             ( 4 << 10 )   /* 49.152 MHz to SD */
+#define H3800_ASIC2_CLOCK_EX0              ( 1 << 13 )   /* Enable 32.768 kHz crystal */
+#define H3800_ASIC2_CLOCK_EX1              ( 1 << 14 )   /* Enable 24.576 MHz crystal */
+#define H3800_ASIC2_CLOCK_EX2              ( 1 << 15 )   /* Enable 33.869 MHz crystal */
+#define H3800_ASIC2_CLOCK_SLOW_UART_1      ( 1 << 16 )   /* Enable 3.686 MHz to UART1 (turn off bit 8) */
+#define H3800_ASIC2_CLOCK_SLOW_UART_0      ( 1 << 17 )   /* Enable 3.686 MHz to UART0 (turn off bit 9) */
+
+#define _H3800_ASIC2_ADC_Base                  0x1200
+#define _H3800_ASIC2_ADC_Multiplexer           0x0000    /* R/W 4 bits - low 3 bits set channel */
+#define _H3800_ASIC2_ADC_ControlStatus         0x0004    /* R/W 8 bits */
+#define _H3800_ASIC2_ADC_Data                  0x0008    /* R   10 bits */
+
+#define H3800_ASIC2_ADC_Multiplexer       H3800_ASIC2_OFFSET(  u8, ADC, Multiplexer )
+#define H3800_ASIC2_ADC_ControlStatus     H3800_ASIC2_OFFSET(  u8, ADC, ControlStatus )
+#define H3800_ASIC2_ADC_Data              H3800_ASIC2_OFFSET( u16, ADC, Data )
+
+#define H3600_ASIC2_ADC_MUX_CHANNEL_MASK         0x07    /* Low 3 bits sets channel.  max = 4 */
+#define H3600_ASIC2_ADC_MUX_CLKEN          ( 1 << 3 )    /* Enable clock */
+
+#define H3600_ASIC2_ADC_CSR_ADPS_MASK            0x0f    /* Low 4 bits sets prescale, max = 8 */
+#define H3600_ASIC2_ADC_CSR_FREE_RUN       ( 1 << 4 )
+#define H3600_ASIC2_ADC_CSR_INT_ENABLE     ( 1 << 5 )
+#define H3600_ASIC2_ADC_CSR_START          ( 1 << 6 )    /* Set to start conversion.  Goes to 0 when done */
+#define H3600_ASIC2_ADC_CSR_ENABLE         ( 1 << 7 )    /* 1:power up ADC, 0:power down */
+
+
+#define _H3800_ASIC2_INTR_Base                 0x1600
+#define _H3800_ASIC2_INTR_MaskAndFlag          0x0000    /* R/(W) 8bits */
+#define _H3800_ASIC2_INTR_ClockPrescale        0x0004    /* R/(W) 5bits */
+#define _H3800_ASIC2_INTR_TimerSet             0x0008    /* R/(W) 8bits */
+
+#define H3800_ASIC2_INTR_MaskAndFlag      H3800_ASIC2_OFFSET( u8, INTR, MaskAndFlag )
+#define H3800_ASIC2_INTR_ClockPrescale    H3800_ASIC2_OFFSET( u8, INTR, ClockPrescale )
+#define H3800_ASIC2_INTR_TimerSet         H3800_ASIC2_OFFSET( u8, INTR, TimerSet )
+
+#define H3800_ASIC2_INTR_GLOBAL_MASK       ( 1 << 0 )    /* Global interrupt mask */
+#define H3800_ASIC2_INTR_POWER_ON_RESET    ( 1 << 1 )    /* 01: Power on reset (bits 1 & 2 ) */
+#define H3800_ASIC2_INTR_EXTERNAL_RESET    ( 2 << 1 )    /* 10: External reset (bits 1 & 2 ) */
+#define H3800_ASIC2_INTR_MASK_UART_0       ( 1 << 4 )
+#define H3800_ASIC2_INTR_MASK_UART_1       ( 1 << 5 )
+#define H3800_ASIC2_INTR_MASK_TIMER        ( 1 << 6 )
+#define H3800_ASIC2_INTR_MASK_OWM          ( 1 << 7 )
+
+#define H3800_ASIC2_INTR_CLOCK_PRESCALE          0x0f    /* 4 bits, max 14 */
+#define H3800_ASIC2_INTR_SET               ( 1 << 4 )    /* Time base enable */
+
+
+#define _H3800_ASIC2_OWM_Base                  0x1800
+#define _H3800_ASIC2_OWM_Command               0x0000    /* R/W 4 bits command register */
+#define _H3800_ASIC2_OWM_Data                  0x0004    /* R/W 8 bits, transmit / receive buffer */
+#define _H3800_ASIC2_OWM_Interrupt             0x0008    /* R/W Command register */
+#define _H3800_ASIC2_OWM_InterruptEnable       0x000c    /* R/W Command register */
+#define _H3800_ASIC2_OWM_ClockDivisor          0x0010    /* R/W 5 bits of divisor and pre-scale */
+
+#define H3800_ASIC2_OWM_Command            H3800_ASIC2_OFFSET( u8, OWM, Command )
+#define H3800_ASIC2_OWM_Data               H3800_ASIC2_OFFSET( u8, OWM, Data )
+#define H3800_ASIC2_OWM_Interrupt          H3800_ASIC2_OFFSET( u8, OWM, Interrupt )
+#define H3800_ASIC2_OWM_InterruptEnable    H3800_ASIC2_OFFSET( u8, OWM, InterruptEnable )
+#define H3800_ASIC2_OWM_ClockDivisor       H3800_ASIC2_OFFSET( u8, OWM, ClockDivisor )
+
+#define H3800_ASIC2_OWM_CMD_ONE_WIRE_RESET ( 1 << 0 )    /* Set to force reset on 1-wire bus */
+#define H3800_ASIC2_OWM_CMD_SRA            ( 1 << 1 )    /* Set to switch to Search ROM accelerator mode */
+#define H3800_ASIC2_OWM_CMD_DQ_OUTPUT      ( 1 << 2 )    /* Write only - forces bus low */
+#define H3800_ASIC2_OWM_CMD_DQ_INPUT       ( 1 << 3 )    /* Read only - reflects state of bus */
+
+#define H3800_ASIC2_OWM_INT_PD             ( 1 << 0 )    /* Presence detect */
+#define H3800_ASIC2_OWM_INT_PDR            ( 1 << 1 )    /* Presence detect result */
+#define H3800_ASIC2_OWM_INT_TBE            ( 1 << 2 )    /* Transmit buffer empty */
+#define H3800_ASIC2_OWM_INT_TEMT           ( 1 << 3 )    /* Transmit shift register empty */
+#define H3800_ASIC2_OWM_INT_RBF            ( 1 << 4 )    /* Receive buffer full */
+
+#define H3800_ASIC2_OWM_INTEN_EPD          ( 1 << 0 )    /* Enable receive buffer full interrupt */
+#define H3800_ASIC2_OWM_INTEN_IAS          ( 1 << 1 )    /* Enable transmit shift register empty interrupt */
+#define H3800_ASIC2_OWM_INTEN_ETBE         ( 1 << 2 )    /* Enable transmit buffer empty interrupt */
+#define H3800_ASIC2_OWM_INTEN_ETMT         ( 1 << 3 )    /* INTR active state */
+#define H3800_ASIC2_OWM_INTEN_ERBF         ( 1 << 4 )    /* Enable presence detect interrupt */
+
+#define _H3800_ASIC2_FlashCtl_Base             0x1A00
+
+/****************************************************/
+/* H3800, ASIC #1
+ * This ASIC is accesed through ASIC #2, and
+ * mapped into the 1c00 - 1f00 region
+ */
+
+#define H3800_ASIC1_OFFSET(s,x,y)   \
+     (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC1_ ## x ## _Base + (_H3800_ASIC1_ ## x ## _ ## y << 1))))
+
+#define _H3800_ASIC1_MMC_Base             0x1c00
+
+#define _H3800_ASIC1_MMC_StartStopClock     0x00    /* R/W 8bit                                  */
+#define _H3800_ASIC1_MMC_Status             0x02    /* R   See below, default 0x0040             */
+#define _H3800_ASIC1_MMC_ClockRate          0x04    /* R/W 8bit, low 3 bits are clock divisor    */
+#define _H3800_ASIC1_MMC_SPIRegister        0x08    /* R/W 8bit, see below                       */
+#define _H3800_ASIC1_MMC_CmdDataCont        0x0a    /* R/W 8bit, write to start MMC adapter      */
+#define _H3800_ASIC1_MMC_ResponseTimeout    0x0c    /* R/W 8bit, clocks before response timeout  */
+#define _H3800_ASIC1_MMC_ReadTimeout        0x0e    /* R/W 16bit, clocks before received data timeout */
+#define _H3800_ASIC1_MMC_BlockLength        0x10    /* R/W 10bit */
+#define _H3800_ASIC1_MMC_NumOfBlocks        0x12    /* R/W 16bit, in block mode, number of blocks  */
+#define _H3800_ASIC1_MMC_InterruptMask      0x1a    /* R/W 8bit */
+#define _H3800_ASIC1_MMC_CommandNumber      0x1c    /* R/W 6 bits */
+#define _H3800_ASIC1_MMC_ArgumentH          0x1e    /* R/W 16 bits  */
+#define _H3800_ASIC1_MMC_ArgumentL          0x20    /* R/W 16 bits */
+#define _H3800_ASIC1_MMC_ResFifo            0x22    /* R   8 x 16 bits - contains response FIFO */
+#define _H3800_ASIC1_MMC_BufferPartFull     0x28    /* R/W 8 bits */
+
+#define H3800_ASIC1_MMC_StartStopClock    H3800_ASIC1_OFFSET(  u8, MMC, StartStopClock )
+#define H3800_ASIC1_MMC_Status            H3800_ASIC1_OFFSET( u16, MMC, Status )
+#define H3800_ASIC1_MMC_ClockRate         H3800_ASIC1_OFFSET(  u8, MMC, ClockRate )
+#define H3800_ASIC1_MMC_SPIRegister       H3800_ASIC1_OFFSET(  u8, MMC, SPIRegister )
+#define H3800_ASIC1_MMC_CmdDataCont       H3800_ASIC1_OFFSET(  u8, MMC, CmdDataCont )
+#define H3800_ASIC1_MMC_ResponseTimeout   H3800_ASIC1_OFFSET(  u8, MMC, ResponseTimeout )
+#define H3800_ASIC1_MMC_ReadTimeout       H3800_ASIC1_OFFSET( u16, MMC, ReadTimeout )
+#define H3800_ASIC1_MMC_BlockLength       H3800_ASIC1_OFFSET( u16, MMC, BlockLength )
+#define H3800_ASIC1_MMC_NumOfBlocks       H3800_ASIC1_OFFSET( u16, MMC, NumOfBlocks )
+#define H3800_ASIC1_MMC_InterruptMask     H3800_ASIC1_OFFSET(  u8, MMC, InterruptMask )
+#define H3800_ASIC1_MMC_CommandNumber     H3800_ASIC1_OFFSET(  u8, MMC, CommandNumber )
+#define H3800_ASIC1_MMC_ArgumentH         H3800_ASIC1_OFFSET( u16, MMC, ArgumentH )
+#define H3800_ASIC1_MMC_ArgumentL         H3800_ASIC1_OFFSET( u16, MMC, ArgumentL )
+#define H3800_ASIC1_MMC_ResFifo           H3800_ASIC1_OFFSET( u16, MMC, ResFifo )
+#define H3800_ASIC1_MMC_BufferPartFull    H3800_ASIC1_OFFSET(  u8, MMC, BufferPartFull )
+
+#define H3800_ASIC1_MMC_STOP_CLOCK                   (1 << 0)   /* Write to "StartStopClock" register */
+#define H3800_ASIC1_MMC_START_CLOCK                  (1 << 1)
+
+#define H3800_ASIC1_MMC_STATUS_READ_TIMEOUT          (1 << 0)
+#define H3800_ASIC1_MMC_STATUS_RESPONSE_TIMEOUT      (1 << 1)
+#define H3800_ASIC1_MMC_STATUS_CRC_WRITE_ERROR       (1 << 2)
+#define H3800_ASIC1_MMC_STATUS_CRC_READ_ERROR        (1 << 3)
+#define H3800_ASIC1_MMC_STATUS_SPI_READ_ERROR        (1 << 4)  /* SPI data token error received */
+#define H3800_ASIC1_MMC_STATUS_CRC_RESPONSE_ERROR    (1 << 5)
+#define H3800_ASIC1_MMC_STATUS_FIFO_EMPTY            (1 << 6)
+#define H3800_ASIC1_MMC_STATUS_FIFO_FULL             (1 << 7)
+#define H3800_ASIC1_MMC_STATUS_CLOCK_ENABLE          (1 << 8)  /* MultiMediaCard clock stopped */
+#define H3800_ASIC1_MMC_STATUS_DATA_TRANSFER_DONE    (1 << 11) /* Write operation, indicates transfer finished */
+#define H3800_ASIC1_MMC_STATUS_END_PROGRAM           (1 << 12) /* End write and read operations */
+#define H3800_ASIC1_MMC_STATUS_END_COMMAND_RESPONSE  (1 << 13) /* End command response */
+
+#define H3800_ASIC1_MMC_SPI_REG_SPI_ENABLE           (1 << 0)  /* Enables SPI mode */
+#define H3800_ASIC1_MMC_SPI_REG_CRC_ON               (1 << 1)  /* 1:turn on CRC    */
+#define H3800_ASIC1_MMC_SPI_REG_SPI_CS_ENABLE        (1 << 2)  /* 1:turn on SPI CS */
+#define H3800_ASIC1_MMC_SPI_REG_CS_ADDRESS_MASK      0x38      /* Bits 3,4,5 are the SPI CS relative address */
+
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_NO_RESPONSE  0x00
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R1           0x01
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R2           0x02
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R3           0x03
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_DATA_ENABLE         (1 << 2)  /* This command contains a data transfer */
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_WRITE               (1 << 3)  /* This data transfer is a write */
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_STREAM_MODE         (1 << 4)  /* This data transfer is in stream mode */
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_BUSY_BIT            (1 << 5)  /* Busy signal expected after current cmd */
+#define H3800_ASIC1_MMC_CMD_DATA_CONT_INITIALIZE          (1 << 6)  /* Enables the 80 bits for initializing card */
+
+#define H3800_ASIC1_MMC_INT_MASK_DATA_TRANSFER_DONE       (1 << 0)
+#define H3800_ASIC1_MMC_INT_MASK_PROGRAM_DONE             (1 << 1)
+#define H3800_ASIC1_MMC_INT_MASK_END_COMMAND_RESPONSE     (1 << 2)
+#define H3800_ASIC1_MMC_INT_MASK_BUFFER_READY             (1 << 3)
+
+#define H3800_ASIC1_MMC_BUFFER_PART_FULL                  (1 << 0)
+
+/********* GPIO **********/
+
+#define _H3800_ASIC1_GPIO_Base        0x1e00
+
+#define _H3800_ASIC1_GPIO_Mask          0x30    /* R/W 0:don't mask, 1:mask interrupt */
+#define _H3800_ASIC1_GPIO_Direction     0x32    /* R/W 0:input, 1:output              */
+#define _H3800_ASIC1_GPIO_Out           0x34    /* R/W 0:output low, 1:output high    */
+#define _H3800_ASIC1_GPIO_TriggerType   0x36    /* R/W 0:level, 1:edge                */
+#define _H3800_ASIC1_GPIO_EdgeTrigger   0x38    /* R/W 0:falling, 1:rising            */
+#define _H3800_ASIC1_GPIO_LevelTrigger  0x3A    /* R/W 0:low, 1:high level detect     */
+#define _H3800_ASIC1_GPIO_LevelStatus   0x3C    /* R/W 0:none, 1:detect               */
+#define _H3800_ASIC1_GPIO_EdgeStatus    0x3E    /* R/W 0:none, 1:detect               */
+#define _H3800_ASIC1_GPIO_State         0x40    /* R   See masks below  (default 0)         */
+#define _H3800_ASIC1_GPIO_Reset         0x42    /* R/W See masks below  (default 0x04)      */
+#define _H3800_ASIC1_GPIO_SleepMask     0x44    /* R/W 0:don't mask, 1:mask trigger in sleep mode  */
+#define _H3800_ASIC1_GPIO_SleepDir      0x46    /* R/W direction 0:input, 1:ouput in sleep mode    */
+#define _H3800_ASIC1_GPIO_SleepOut      0x48    /* R/W level 0:low, 1:high in sleep mode           */
+#define _H3800_ASIC1_GPIO_Status        0x4A    /* R   Pin status                                  */
+#define _H3800_ASIC1_GPIO_BattFaultDir  0x4C    /* R/W direction 0:input, 1:output in batt_fault   */
+#define _H3800_ASIC1_GPIO_BattFaultOut  0x4E    /* R/W level 0:low, 1:high in batt_fault           */
+
+#define H3800_ASIC1_GPIO_Mask         H3800_ASIC1_OFFSET( u16, GPIO, Mask )
+#define H3800_ASIC1_GPIO_Direction    H3800_ASIC1_OFFSET( u16, GPIO, Direction )
+#define H3800_ASIC1_GPIO_Out          H3800_ASIC1_OFFSET( u16, GPIO, Out )
+#define H3800_ASIC1_GPIO_TriggerType  H3800_ASIC1_OFFSET( u16, GPIO, TriggerType )
+#define H3800_ASIC1_GPIO_EdgeTrigger  H3800_ASIC1_OFFSET( u16, GPIO, EdgeTrigger )
+#define H3800_ASIC1_GPIO_LevelTrigger H3800_ASIC1_OFFSET( u16, GPIO, LevelTrigger )
+#define H3800_ASIC1_GPIO_LevelStatus  H3800_ASIC1_OFFSET( u16, GPIO, LevelStatus )
+#define H3800_ASIC1_GPIO_EdgeStatus   H3800_ASIC1_OFFSET( u16, GPIO, EdgeStatus )
+#define H3800_ASIC1_GPIO_State        H3800_ASIC1_OFFSET(  u8, GPIO, State )
+#define H3800_ASIC1_GPIO_Reset        H3800_ASIC1_OFFSET(  u8, GPIO, Reset )
+#define H3800_ASIC1_GPIO_SleepMask    H3800_ASIC1_OFFSET( u16, GPIO, SleepMask )
+#define H3800_ASIC1_GPIO_SleepDir     H3800_ASIC1_OFFSET( u16, GPIO, SleepDir )
+#define H3800_ASIC1_GPIO_SleepOut     H3800_ASIC1_OFFSET( u16, GPIO, SleepOut )
+#define H3800_ASIC1_GPIO_Status       H3800_ASIC1_OFFSET( u16, GPIO, Status )
+#define H3800_ASIC1_GPIO_BattFaultDir H3800_ASIC1_OFFSET( u16, GPIO, BattFaultDir )
+#define H3800_ASIC1_GPIO_BattFaultOut H3800_ASIC1_OFFSET( u16, GPIO, BattFaultOut )
+
+#define H3800_ASIC1_GPIO_STATE_MASK            (1 << 0)
+#define H3800_ASIC1_GPIO_STATE_DIRECTION       (1 << 1)
+#define H3800_ASIC1_GPIO_STATE_OUT             (1 << 2)
+#define H3800_ASIC1_GPIO_STATE_TRIGGER_TYPE    (1 << 3)
+#define H3800_ASIC1_GPIO_STATE_EDGE_TRIGGER    (1 << 4)
+#define H3800_ASIC1_GPIO_STATE_LEVEL_TRIGGER   (1 << 5)
+
+#define H3800_ASIC1_GPIO_RESET_SOFTWARE        (1 << 0)
+#define H3800_ASIC1_GPIO_RESET_AUTO_SLEEP      (1 << 1)
+#define H3800_ASIC1_GPIO_RESET_FIRST_PWR_ON    (1 << 2)
+
+/* These are all outputs */
+#define GPIO_H3800_ASIC1_IR_ON_N          (1 << 0)   /* Apply power to the IR Module */
+#define GPIO_H3800_ASIC1_SD_PWR_ON        (1 << 1)   /* Secure Digital power on */
+#define GPIO_H3800_ASIC1_RS232_ON         (1 << 2)   /* Turn on power to the RS232 chip ? */
+#define GPIO_H3800_ASIC1_PULSE_GEN        (1 << 3)   /* Goes to speaker / earphone */
+#define GPIO_H3800_ASIC1_CH_TIMER         (1 << 4)   /* */
+#define GPIO_H3800_ASIC1_LCD_5V_ON        (1 << 5)   /* Enables LCD_5V */
+#define GPIO_H3800_ASIC1_LCD_ON           (1 << 6)   /* Enables LCD_3V */
+#define GPIO_H3800_ASIC1_LCD_PCI          (1 << 7)   /* Connects to PDWN on LCD controller */
+#define GPIO_H3800_ASIC1_VGH_ON           (1 << 8)   /* Drives VGH on the LCD (+9??) */
+#define GPIO_H3800_ASIC1_VGL_ON           (1 << 9)   /* Drivers VGL on the LCD (-6??) */
+#define GPIO_H3800_ASIC1_FL_PWR_ON        (1 << 10)  /* Frontlight power on */
+#define GPIO_H3800_ASIC1_BT_PWR_ON        (1 << 11)  /* Bluetooth power on */
+#define GPIO_H3800_ASIC1_SPK_ON           (1 << 12)  /* */
+#define GPIO_H3800_ASIC1_EAR_ON_N         (1 << 13)  /* */
+#define GPIO_H3800_ASIC1_AUD_PWR_ON       (1 << 14)  /* */
+
+/* Write enable for the flash */
+
+#define _H3800_ASIC1_FlashWP_Base         0x1F00
+#define _H3800_ASIC1_FlashWP_VPP_ON         0x00    /* R   1: write, 0: protect */
+#define H3800_ASIC1_FlashWP_VPP_ON       H3800_ASIC1_OFFSET( u8, FlashWP, VPP_ON )
+
+#endif /* _INCLUDE_H3600_GPIO_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/hardware.h linux/include/asm-arm/arch-sa1100/hardware.h
--- linux.orig/include/asm-arm/arch-sa1100/hardware.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/hardware.h	2002-07-20 01:08:33.000000000 +0000
@@ -60,6 +60,7 @@
    ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )
 
 #ifndef __ASSEMBLY__
+#include <asm/types.h>
 
 #if 0
 # define __REG(x)	(*((volatile u32 *)io_p2v(x)))
@@ -93,29 +94,38 @@
  * This must be called *before* the corresponding IRQ is registered.
  * Use this instead of directly setting GRER/GFER.
  */
-#define GPIO_FALLING_EDGE       1
-#define GPIO_RISING_EDGE        2
-#define GPIO_BOTH_EDGES         3
+#define GPIO_NO_EDGES		0
+#define GPIO_FALLING_EDGE	1
+#define GPIO_RISING_EDGE	2
+#define GPIO_BOTH_EDGES 	3
 #ifndef __ASSEMBLY__
 extern void set_GPIO_IRQ_edge( int gpio_mask, int edge_mask );
-
-/*
- * Return the current CPU clock frequency in units of 100kHz
- */
-extern unsigned short get_cclk_frequency(void);
-
 #endif
 
 
 /*
  * Implementation specifics.
  *
- * *** NOTE ***
+ *                      *** BIG FAT NOTE ***
+ *
  * Any definitions in these files should be prefixed by an identifier -
  * eg, ASSABET_UCB1300_IRQ  This will allow us to eleminate these
  * ifdefs, and lots of other preprocessor gunk elsewhere.
+ *
+ * Also, please try to add your entry in alphabetical order.  The
+ * initial ones below are the start of the alphabetical list.
+ *
+ * Do NOT add your ifdefs around your file.
  */
 
+#include "badge4.h"
+
+#include "frodo.h"
+
+#include "h3600.h"
+
+#include "system3.h"
+
 #ifdef CONFIG_SA1100_PANGOLIN
 #include "pangolin.h"
 #endif
@@ -145,10 +155,6 @@
 #include "empeg.h"
 #endif
 
-#ifdef CONFIG_SA1100_H3600
-#include "h3600.h"
-#endif
-
 #ifdef CONFIG_SA1100_ITSY
 #include "itsy.h"
 #endif
@@ -211,19 +217,4 @@
 #include "flexanet.h"
 #endif
 
-#ifdef CONFIG_SA1111
-
-/*
- * The SA1111 is always located at virtual 0xf4000000.
- */
-
-#define SA1111_VBASE		0xf4000000
-
-#define SA1111_p2v( x )         ((x) - SA1111_BASE + SA1111_VBASE)
-#define SA1111_v2p( x )         ((x) - SA1111_VBASE + SA1111_BASE)
-
-#include "SA-1111.h"
-
-#endif
-
 #endif  /* _ASM_ARCH_HARDWARE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/ide.h linux/include/asm-arm/arch-sa1100/ide.h
--- linux.orig/include/asm-arm/arch-sa1100/ide.h	2001-08-13 00:36:24.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/ide.h	2002-07-20 01:08:23.000000000 +0000
@@ -3,6 +3,9 @@
  *
  * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
  *
+ * 26-feb-2002: Add support for 2d3D SA-1110 Development board
+ *              Abraham van der Merwe <abraham@2d3d.co.za>
+ *
  * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
  *              Get rid of the special ide_init_hwif_ports() functions
  *              and make a generalised function that can be used by all
@@ -34,6 +37,10 @@
 	if (machine_is_lart())
 		regincr = 1 << 1;
 
+	/* Frodo has the first 14 address lines unused */
+	if (machine_is_frodo())
+		regincr = 1 << 14;
+
 	memset(hw, 0, sizeof(*hw));
 
 	reg = (ide_ioreg_t)data_port;
@@ -124,6 +131,20 @@
         ide_register_hw(&hw, NULL);
 #endif
     }
+	else if (machine_is_frodo ()) {
+#ifdef CONFIG_SA1100_FRODO
+		hw_regs_t hw;
+
+		/* enable GPIO as interrupt line */
+		GPDR &= ~FRODO_IDE_GPIO;
+		set_GPIO_IRQ_edge (FRODO_IDE_GPIO,GPIO_RISING_EDGE);
+
+		/* init the interface */
+		ide_init_hwif_ports (&hw,FRODO_IDE_DATA,FRODO_IDE_CTRL,NULL);
+		hw.irq = FRODO_IDE_IRQ;
+		ide_register_hw (&hw,NULL);
+#endif
+	}
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/irqs.h linux/include/asm-arm/arch-sa1100/irqs.h
--- linux.orig/include/asm-arm/arch-sa1100/irqs.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/irqs.h	2002-07-20 01:08:21.000000000 +0000
@@ -4,154 +4,150 @@
  * Copyright (C) 1996 Russell King
  * Copyright (C) 1998 Deborah Wallach (updates for SA1100/Brutus).
  * Copyright (C) 1999 Nicolas Pitre (full GPIO irq isolation)
+ *
+ * 2001/11/14	RMK	Cleaned up and standardised a lot of the IRQs.
  */
-
 #include <linux/config.h>
 
-#define SA1100_IRQ(x)		(0 + (x))
-
-#define	IRQ_GPIO0		SA1100_IRQ(0)
-#define	IRQ_GPIO1		SA1100_IRQ(1)
-#define	IRQ_GPIO2		SA1100_IRQ(2)
-#define	IRQ_GPIO3		SA1100_IRQ(3)
-#define	IRQ_GPIO4		SA1100_IRQ(4)
-#define	IRQ_GPIO5		SA1100_IRQ(5)
-#define	IRQ_GPIO6		SA1100_IRQ(6)
-#define	IRQ_GPIO7		SA1100_IRQ(7)
-#define	IRQ_GPIO8		SA1100_IRQ(8)
-#define	IRQ_GPIO9		SA1100_IRQ(9)
-#define	IRQ_GPIO10		SA1100_IRQ(10)
-#define	IRQ_GPIO11_27		SA1100_IRQ(11)
-#define	IRQ_LCD  		SA1100_IRQ(12)	/* LCD controller           */
-#define	IRQ_Ser0UDC		SA1100_IRQ(13)	/* Ser. port 0 UDC          */
-#define	IRQ_Ser1SDLC		SA1100_IRQ(14)	/* Ser. port 1 SDLC         */
-#define	IRQ_Ser1UART		SA1100_IRQ(15)	/* Ser. port 1 UART         */
-#define	IRQ_Ser2ICP		SA1100_IRQ(16)	/* Ser. port 2 ICP          */
-#define	IRQ_Ser3UART		SA1100_IRQ(17)	/* Ser. port 3 UART         */
-#define	IRQ_Ser4MCP		SA1100_IRQ(18)	/* Ser. port 4 MCP          */
-#define	IRQ_Ser4SSP		SA1100_IRQ(19)	/* Ser. port 4 SSP          */
-#define	IRQ_DMA0 		SA1100_IRQ(20)	/* DMA controller channel 0 */
-#define	IRQ_DMA1 		SA1100_IRQ(21)	/* DMA controller channel 1 */
-#define	IRQ_DMA2 		SA1100_IRQ(22)	/* DMA controller channel 2 */
-#define	IRQ_DMA3 		SA1100_IRQ(23)	/* DMA controller channel 3 */
-#define	IRQ_DMA4 		SA1100_IRQ(24)	/* DMA controller channel 4 */
-#define	IRQ_DMA5 		SA1100_IRQ(25)	/* DMA controller channel 5 */
-#define	IRQ_OST0 		SA1100_IRQ(26)	/* OS Timer match 0         */
-#define	IRQ_OST1 		SA1100_IRQ(27)	/* OS Timer match 1         */
-#define	IRQ_OST2 		SA1100_IRQ(28)	/* OS Timer match 2         */
-#define	IRQ_OST3 		SA1100_IRQ(29)	/* OS Timer match 3         */
-#define	IRQ_RTC1Hz		SA1100_IRQ(30)	/* RTC 1 Hz clock           */
-#define	IRQ_RTCAlrm		SA1100_IRQ(31)	/* RTC Alarm                */
-
-#define	IRQ_GPIO_11_27(x)	(32 + (x) - 11)
-
-#define	IRQ_GPIO11		IRQ_GPIO_11_27(11)
-#define	IRQ_GPIO12		IRQ_GPIO_11_27(12)
-#define	IRQ_GPIO13		IRQ_GPIO_11_27(13)
-#define	IRQ_GPIO14		IRQ_GPIO_11_27(14)
-#define	IRQ_GPIO15		IRQ_GPIO_11_27(15)
-#define	IRQ_GPIO16		IRQ_GPIO_11_27(16)
-#define	IRQ_GPIO17		IRQ_GPIO_11_27(17)
-#define	IRQ_GPIO18		IRQ_GPIO_11_27(18)
-#define	IRQ_GPIO19		IRQ_GPIO_11_27(19)
-#define	IRQ_GPIO20		IRQ_GPIO_11_27(20)
-#define	IRQ_GPIO21		IRQ_GPIO_11_27(21)
-#define	IRQ_GPIO22		IRQ_GPIO_11_27(22)
-#define	IRQ_GPIO23		IRQ_GPIO_11_27(23)
-#define	IRQ_GPIO24		IRQ_GPIO_11_27(24)
-#define	IRQ_GPIO25		IRQ_GPIO_11_27(25)
-#define	IRQ_GPIO26		IRQ_GPIO_11_27(26)
-#define	IRQ_GPIO27		IRQ_GPIO_11_27(27)
-
-#define SA1100_GPIO_TO_IRQ(i)	(((i) < 11) ? SA1100_IRQ(i) : IRQ_GPIO_11_27(i))
-
-/* To get the GPIO number from an IRQ number */
-#define GPIO_11_27_IRQ(i)	(11 + (i) - 32)
-#define SA1100_IRQ_TO_GPIO(i) 	(((i) < 11) ? (i) : GPIO_11_27_IRQ(i))
-
-#define	NR_IRQS		(IRQ_GPIO27 + 1)
-
-
-#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_GRAPHICSMASTER)
-#define ADS_EXT_IRQ(x)	(IRQ_GPIO27 + 1 + (x))
-#undef NR_IRQS
-#define NR_IRQS		(ADS_EXT_IRQ(15) + 1)
-#endif
+#define	IRQ_GPIO0		0
+#define	IRQ_GPIO1		1
+#define	IRQ_GPIO2		2
+#define	IRQ_GPIO3		3
+#define	IRQ_GPIO4		4
+#define	IRQ_GPIO5		5
+#define	IRQ_GPIO6		6
+#define	IRQ_GPIO7		7
+#define	IRQ_GPIO8		8
+#define	IRQ_GPIO9		9
+#define	IRQ_GPIO10		10
+#define	IRQ_GPIO11_27		11
+#define	IRQ_LCD  		12	/* LCD controller           */
+#define	IRQ_Ser0UDC		13	/* Ser. port 0 UDC          */
+#define	IRQ_Ser1SDLC		14	/* Ser. port 1 SDLC         */
+#define	IRQ_Ser1UART		15	/* Ser. port 1 UART         */
+#define	IRQ_Ser2ICP		16	/* Ser. port 2 ICP          */
+#define	IRQ_Ser3UART		17	/* Ser. port 3 UART         */
+#define	IRQ_Ser4MCP		18	/* Ser. port 4 MCP          */
+#define	IRQ_Ser4SSP		19	/* Ser. port 4 SSP          */
+#define	IRQ_DMA0 		20	/* DMA controller channel 0 */
+#define	IRQ_DMA1 		21	/* DMA controller channel 1 */
+#define	IRQ_DMA2 		22	/* DMA controller channel 2 */
+#define	IRQ_DMA3 		23	/* DMA controller channel 3 */
+#define	IRQ_DMA4 		24	/* DMA controller channel 4 */
+#define	IRQ_DMA5 		25	/* DMA controller channel 5 */
+#define	IRQ_OST0 		26	/* OS Timer match 0         */
+#define	IRQ_OST1 		27	/* OS Timer match 1         */
+#define	IRQ_OST2 		28	/* OS Timer match 2         */
+#define	IRQ_OST3 		29	/* OS Timer match 3         */
+#define	IRQ_RTC1Hz		30	/* RTC 1 Hz clock           */
+#define	IRQ_RTCAlrm		31	/* RTC Alarm                */
+
+#define	IRQ_GPIO11		32
+#define	IRQ_GPIO12		33
+#define	IRQ_GPIO13		34
+#define	IRQ_GPIO14		35
+#define	IRQ_GPIO15		36
+#define	IRQ_GPIO16		37
+#define	IRQ_GPIO17		38
+#define	IRQ_GPIO18		39
+#define	IRQ_GPIO19		40
+#define	IRQ_GPIO20		41
+#define	IRQ_GPIO21		42
+#define	IRQ_GPIO22		43
+#define	IRQ_GPIO23		44
+#define	IRQ_GPIO24		45
+#define	IRQ_GPIO25		46
+#define	IRQ_GPIO26		47
+#define	IRQ_GPIO27		48
 
+/*
+ * To get the GPIO number from an IRQ number
+ */
+#define GPIO_11_27_IRQ(i)	((i) - 21)
 
-#if defined(CONFIG_SA1111)
+/*
+ * The next 16 interrupts are for board specific purposes.  Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these.  If you need more, increase IRQ_BOARD_END, but keep it
+ * within sensible limits.  IRQs 49 to 64 are available.
+ */
+#define IRQ_BOARD_START		49
+#define IRQ_BOARD_END		65
 
-#if defined(CONFIG_SA1100_GRAPHICSMASTER)
-#define	SA1111_IRQ(x)	(ADS_EXT_IRQ(15) + 1 + 1 + (x))
+#define IRQ_SA1111_START	(IRQ_BOARD_END)
+#define IRQ_GPAIN0		(IRQ_BOARD_END + 0)
+#define IRQ_GPAIN1		(IRQ_BOARD_END + 1)
+#define IRQ_GPAIN2		(IRQ_BOARD_END + 2)
+#define IRQ_GPAIN3		(IRQ_BOARD_END + 3)
+#define IRQ_GPBIN0		(IRQ_BOARD_END + 4)
+#define IRQ_GPBIN1		(IRQ_BOARD_END + 5)
+#define IRQ_GPBIN2		(IRQ_BOARD_END + 6)
+#define IRQ_GPBIN3		(IRQ_BOARD_END + 7)
+#define IRQ_GPBIN4		(IRQ_BOARD_END + 8)
+#define IRQ_GPBIN5		(IRQ_BOARD_END + 9)
+#define IRQ_GPCIN0		(IRQ_BOARD_END + 10)
+#define IRQ_GPCIN1		(IRQ_BOARD_END + 11)
+#define IRQ_GPCIN2		(IRQ_BOARD_END + 12)
+#define IRQ_GPCIN3		(IRQ_BOARD_END + 13)
+#define IRQ_GPCIN4		(IRQ_BOARD_END + 14)
+#define IRQ_GPCIN5		(IRQ_BOARD_END + 15)
+#define IRQ_GPCIN6		(IRQ_BOARD_END + 16)
+#define IRQ_GPCIN7		(IRQ_BOARD_END + 17)
+#define IRQ_MSTXINT		(IRQ_BOARD_END + 18)
+#define IRQ_MSRXINT		(IRQ_BOARD_END + 19)
+#define IRQ_MSSTOPERRINT	(IRQ_BOARD_END + 20)
+#define IRQ_TPTXINT		(IRQ_BOARD_END + 21)
+#define IRQ_TPRXINT		(IRQ_BOARD_END + 22)
+#define IRQ_TPSTOPERRINT	(IRQ_BOARD_END + 23)
+#define SSPXMTINT		(IRQ_BOARD_END + 24)
+#define SSPRCVINT		(IRQ_BOARD_END + 25)
+#define SSPROR			(IRQ_BOARD_END + 26)
+#define AUDXMTDMADONEA		(IRQ_BOARD_END + 32)
+#define AUDRCVDMADONEA		(IRQ_BOARD_END + 33)
+#define AUDXMTDMADONEB		(IRQ_BOARD_END + 34)
+#define AUDRCVDMADONEB		(IRQ_BOARD_END + 35)
+#define AUDTFSR			(IRQ_BOARD_END + 36)
+#define AUDRFSR			(IRQ_BOARD_END + 37)
+#define AUDTUR			(IRQ_BOARD_END + 38)
+#define AUDROR			(IRQ_BOARD_END + 39)
+#define AUDDTS			(IRQ_BOARD_END + 40)
+#define AUDRDD			(IRQ_BOARD_END + 41)
+#define AUDSTO			(IRQ_BOARD_END + 42)
+#define USBPWR			(IRQ_BOARD_END + 43)
+#define NIRQHCIM		(IRQ_BOARD_END + 44)
+#define IRQHCIBUFFACC		(IRQ_BOARD_END + 45)
+#define IRQHCIRMTWKP		(IRQ_BOARD_END + 46)
+#define NHCIMFCIR		(IRQ_BOARD_END + 47)
+#define USB_PORT_RESUME		(IRQ_BOARD_END + 48)
+#define S0_READY_NINT		(IRQ_BOARD_END + 49)
+#define S1_READY_NINT		(IRQ_BOARD_END + 50)
+#define S0_CD_VALID		(IRQ_BOARD_END + 51)
+#define S1_CD_VALID		(IRQ_BOARD_END + 52)
+#define S0_BVD1_STSCHG		(IRQ_BOARD_END + 53)
+#define S1_BVD1_STSCHG		(IRQ_BOARD_END + 54)
+
+/*
+ * Figure out the MAX IRQ number.
+ *
+ * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
+ * If graphicsclient or graphicsmaster, we don't have a SA1111.
+ * Otherwise, we have the standard IRQs only.
+ */
+#ifdef CONFIG_SA1111
+#define NR_IRQS			(S1_BVD1_STSCHG + 1)
+#elif defined(CONFIG_SA1100_GRAPHICSCLIENT) || \
+      defined(CONFIG_SA1100_GRAPHICSMASTER)
+#define NR_IRQS			(IRQ_BOARD_END)
 #else
-#define SA1111_IRQ(x)	(IRQ_GPIO27 + 1 + (x))
+#define NR_IRQS			(IRQ_BOARD_START)
 #endif
 
-#define GPAIN0		SA1111_IRQ(0)
-#define GPAIN1		SA1111_IRQ(1)
-#define GPAIN2		SA1111_IRQ(2)
-#define GPAIN3		SA1111_IRQ(3)
-#define GPBIN0		SA1111_IRQ(4)
-#define GPBIN1		SA1111_IRQ(5)
-#define GPBIN2		SA1111_IRQ(6)
-#define GPBIN3		SA1111_IRQ(7)
-#define GPBIN4		SA1111_IRQ(8)
-#define GPBIN5		SA1111_IRQ(9)
-#define GPCIN0		SA1111_IRQ(10)
-#define GPCIN1		SA1111_IRQ(11)
-#define GPCIN2		SA1111_IRQ(12)
-#define GPCIN3		SA1111_IRQ(13)
-#define GPCIN4		SA1111_IRQ(14)
-#define GPCIN5		SA1111_IRQ(15)
-#define GPCIN6		SA1111_IRQ(16)
-#define GPCIN7		SA1111_IRQ(17)
-#define MSTXINT		SA1111_IRQ(18)
-#define MSRXINT		SA1111_IRQ(19)
-#define MSSTOPERRINT	SA1111_IRQ(20)
-#define TPTXINT		SA1111_IRQ(21)
-#define TPRXINT		SA1111_IRQ(22)
-#define TPSTOPERRINT	SA1111_IRQ(23)
-#define SSPXMTINT	SA1111_IRQ(24)
-#define SSPRCVINT	SA1111_IRQ(25)
-#define SSPROR		SA1111_IRQ(26)
-#define AUDXMTDMADONEA	SA1111_IRQ(32)
-#define AUDRCVDMADONEA	SA1111_IRQ(33)
-#define AUDXMTDMADONEB	SA1111_IRQ(34)
-#define AUDRCVDMADONEB	SA1111_IRQ(35)
-#define AUDTFSR		SA1111_IRQ(36)
-#define AUDRFSR		SA1111_IRQ(37)
-#define AUDTUR		SA1111_IRQ(38)
-#define AUDROR		SA1111_IRQ(39)
-#define AUDDTS		SA1111_IRQ(40)
-#define AUDRDD		SA1111_IRQ(41)
-#define AUDSTO		SA1111_IRQ(42)
-#define USBPWR		SA1111_IRQ(43)
-#define NIRQHCIM	SA1111_IRQ(44)
-#define IRQHCIBUFFACC	SA1111_IRQ(45)
-#define IRQHCIRMTWKP	SA1111_IRQ(46)
-#define NHCIMFCIR	SA1111_IRQ(47)
-#define USB_PORT_RESUME	SA1111_IRQ(48)
-#define S0_READY_NINT	SA1111_IRQ(49)
-#define S1_READY_NINT	SA1111_IRQ(50)
-#define S0_CD_VALID	SA1111_IRQ(51)
-#define S1_CD_VALID	SA1111_IRQ(52)
-#define S0_BVD1_STSCHG	SA1111_IRQ(53)
-#define S1_BVD1_STSCHG	SA1111_IRQ(54)
-
-#define SA1111_IRQ_MAX	SA1111_IRQ(54)
-
-#undef NR_IRQS
-#define NR_IRQS		(SA1111_IRQ_MAX + 1)
-
-
-#ifdef CONFIG_ASSABET_NEPONSET
-
-#define MISC_IRQ0	SA1111_IRQ(55)
-#define MISC_IRQ1	SA1111_IRQ(56)
-
-#undef NR_IRQS
-#define NR_IRQS		(SA1111_IRQ_MAX + 3)
-
-#endif  /* CONFIG_ASSABET_NEPONSET */
+/*
+ * Board specific IRQs.  Define them here.
+ * Do not surround them with ifdefs.
+ */
+#define IRQ_NEPONSET_SMC9196	(IRQ_BOARD_START + 0)
+#define IRQ_NEPONSET_USAR	(IRQ_BOARD_START + 1)
 
-#endif  /* CONFIG_SA1111 */
+/* PT Digital Board Interrupts (CONFIG_SA1100_PT_SYSTEM3) */
+#define IRQ_SYSTEM3_SMC9196	(IRQ_BOARD_START + 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/jornada720.h linux/include/asm-arm/arch-sa1100/jornada720.h
--- linux.orig/include/asm-arm/arch-sa1100/jornada720.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/jornada720.h	2002-07-20 01:08:33.000000000 +0000
@@ -11,7 +11,7 @@
 #error "include <asm/hardware.h> instead"
 #endif
 
-#define SA1111_BASE             (0x40000000)
+#define JORNADA720_SA1111_BASE		(0x40000000)
 
 #define GPIO_JORNADA720_KEYBOARD	GPIO_GPIO(0)
 #define GPIO_JORNADA720_MOUSE		GPIO_GPIO(9)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/keyboard.h linux/include/asm-arm/arch-sa1100/keyboard.h
--- linux.orig/include/asm-arm/arch-sa1100/keyboard.h	2001-10-25 20:53:54.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/keyboard.h	2002-07-20 01:08:36.000000000 +0000
@@ -13,7 +13,7 @@
 #define kbd_disable_irq()	do { } while(0);
 #define kbd_enable_irq()	do { } while(0);
 
-extern void sa1111_kbd_init_hw(void);
+extern int sa1111_kbd_init_hw(void);
 extern void gc_kbd_init_hw(void);
 extern void smartio_kbd_init_hw(void);
 extern void cerf_kbd_init_hw(void);
@@ -31,6 +31,11 @@
 	if (machine_is_cerf())
 		cerf_kbd_init_hw();
 #endif
+#ifdef CONFIG_SA1100_PT_SYSTEM3
+	/* TODO: add system 3 board specific functions here */
+	if (machine_is_pt_system3())
+		sa1111_kbd_init_hw();
+#endif
 }
 
 #endif  /* _SA1100_KEYBOARD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/pangolin.h linux/include/asm-arm/arch-sa1100/pangolin.h
--- linux.orig/include/asm-arm/arch-sa1100/pangolin.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/pangolin.h	2002-07-20 01:08:35.000000000 +0000
@@ -11,6 +11,8 @@
 #error "include <asm/hardware.h> instead"
 #endif
 
+#include <linux/config.h>
+
 #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
 
 /* GPIOs for which the generic definition doesn't say much */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/pcmcia.h linux/include/asm-arm/arch-sa1100/pcmcia.h
--- linux.orig/include/asm-arm/arch-sa1100/pcmcia.h	2001-04-12 19:20:31.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/pcmcia.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,70 +0,0 @@
-/*
- * linux/include/asm/arch/pcmcia.h
- *
- * Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
- *
- * This file contains definitions for the low-level SA-1100 kernel PCMCIA
- * interface. Please see linux/Documentation/arm/SA1100/PCMCIA for details.
- */
-
-#ifndef _ASM_ARCH_PCMCIA
-#define _ASM_ARCH_PCMCIA
-
-
-/* Ideally, we'd support up to MAX_SOCK sockets, but the SA-1100 only
- * has support for two. This shows up in lots of hardwired ways, such
- * as the fact that MECR only has enough bits to configure two sockets.
- * Since it's so entrenched in the hardware, limiting the software
- * in this way doesn't seem too terrible.
- */
-#define SA1100_PCMCIA_MAX_SOCK   (2)
-
-
-#ifndef __ASSEMBLY__
-
-struct pcmcia_init {
-  void (*handler)(int irq, void *dev, struct pt_regs *regs);
-};
-
-struct pcmcia_state {
-  unsigned detect: 1,
-            ready: 1,
-             bvd1: 1,
-             bvd2: 1,
-           wrprot: 1,
-            vs_3v: 1,
-            vs_Xv: 1;
-};
-
-struct pcmcia_state_array {
-  unsigned int size;
-  struct pcmcia_state *state;
-};
-
-struct pcmcia_configure {
-  unsigned sock: 8,
-            vcc: 8,
-            vpp: 8,
-         output: 1,
-        speaker: 1,
-          reset: 1;
-};
-
-struct pcmcia_irq_info {
-  unsigned int sock;
-  unsigned int irq;
-};
-
-struct pcmcia_low_level {
-  int (*init)(struct pcmcia_init *);
-  int (*shutdown)(void);
-  int (*socket_state)(struct pcmcia_state_array *);
-  int (*get_irq_info)(struct pcmcia_irq_info *);
-  int (*configure_socket)(const struct pcmcia_configure *);
-};
-
-extern struct pcmcia_low_level *pcmcia_low_level;
-
-#endif  /* __ASSEMBLY__ */
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/pfs168.h linux/include/asm-arm/arch-sa1100/pfs168.h
--- linux.orig/include/asm-arm/arch-sa1100/pfs168.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/pfs168.h	2002-07-20 01:08:32.000000000 +0000
@@ -44,7 +44,7 @@
  * PFS-168 definitions:
  */
 
-#define SA1111_BASE             (0x40000000)
+#define PFS168_SA1111_BASE	(0x40000000)
 
 #ifndef __ASSEMBLY__
 #define machine_has_neponset() (0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/shannon.h linux/include/asm-arm/arch-sa1100/shannon.h
--- linux.orig/include/asm-arm/arch-sa1100/shannon.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/shannon.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,43 @@
+#ifndef _INCLUDE_SHANNON_H
+#define _INCLUDE_SHANNON_H
+
+/* taken from comp.os.inferno Tue, 12 Sep 2000 09:21:50 GMT,
+ * written by <forsyth@vitanuova.com> */
+
+#define SHANNON_GPIO_SPI_FLASH		GPIO_GPIO (0)	/* Output - Driven low, enables SPI to flash */
+#define SHANNON_GPIO_SPI_DSP		GPIO_GPIO (1)	/* Output - Driven low, enables SPI to DSP */
+/* lcd lower = GPIO 2-9 */
+#define SHANNON_GPIO_SPI_OUTPUT		GPIO_GPIO (10)	/* Output - SPI output to DSP */
+#define SHANNON_GPIO_SPI_INPUT		GPIO_GPIO (11)	/* Input  - SPI input from DSP */
+#define SHANNON_GPIO_SPI_CLOCK		GPIO_GPIO (12)	/* Output - Clock for SPI */
+#define SHANNON_GPIO_SPI_FRAME		GPIO_GPIO (13)	/* Output - Frame marker - not used */
+#define SHANNON_GPIO_SPI_RTS		GPIO_GPIO (14)	/* Input  - SPI Ready to Send */
+#define SHANNON_IRQ_GPIO_SPI_RTS	IRQ_GPIO14
+#define SHANNON_GPIO_SPI_CTS		GPIO_GPIO (15)	/* Output - SPI Clear to Send */
+#define SHANNON_GPIO_IRQ_CODEC		GPIO_GPIO (16)	/* in, irq from ucb1200 */
+#define SHANNON_IRQ_GPIO_IRQ_CODEC	IRQ_GPIO16
+#define SHANNON_GPIO_DSP_RESET		GPIO_GPIO (17)	/* Output - Drive low to reset the DSP */
+#define SHANNON_GPIO_CODEC_RESET	GPIO_GPIO (18)	/* Output - Drive low to reset the UCB1x00 */
+#define SHANNON_GPIO_U3_RTS		GPIO_GPIO (19)	/* ?? */
+#define SHANNON_GPIO_U3_CTS		GPIO_GPIO (20)	/* ?? */
+#define SHANNON_GPIO_SENSE_12V		GPIO_GPIO (21)	/* Input, 12v flash unprotect detected */
+#define SHANNON_GPIO_DISP_EN		GPIO_GPIO (22)	/* out */
+/* XXX GPIO 23 unaccounted for */
+#define SHANNON_GPIO_EJECT_0		GPIO_GPIO (24)	/* in */
+#define SHANNON_IRQ_GPIO_EJECT_0	IRQ_GPIO24
+#define SHANNON_GPIO_EJECT_1		GPIO_GPIO (25)	/* in */
+#define SHANNON_IRQ_GPIO_EJECT_1	IRQ_GPIO25
+#define SHANNON_GPIO_RDY_0		GPIO_GPIO (26)	/* in */
+#define SHANNON_IRQ_GPIO_RDY_0		IRQ_GPIO26
+#define SHANNON_GPIO_RDY_1		GPIO_GPIO (27)	/* in */
+#define SHANNON_IRQ_GPIO_RDY_1		IRQ_GPIO27
+
+/* MCP UCB codec GPIO pins... */
+
+#define SHANNON_UCB_GPIO_BACKLIGHT	9
+#define SHANNON_UCB_GPIO_BRIGHT_MASK  	7
+#define SHANNON_UCB_GPIO_BRIGHT		6
+#define SHANNON_UCB_GPIO_CONTRAST_MASK	0x3f
+#define SHANNON_UCB_GPIO_CONTRAST	0
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/simpad.h linux/include/asm-arm/arch-sa1100/simpad.h
--- linux.orig/include/asm-arm/arch-sa1100/simpad.h	2001-10-25 20:53:54.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/simpad.h	2002-07-20 01:08:29.000000000 +0000
@@ -39,7 +39,6 @@
 
 #define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22 
 
-
 /*---  PCMCIA  ---*/
 #define GPIO_CF_CD              GPIO_GPIO24
 #define GPIO_CF_IRQ             GPIO_GPIO1          
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/system.h linux/include/asm-arm/arch-sa1100/system.h
--- linux.orig/include/asm-arm/arch-sa1100/system.h	2001-10-25 20:53:54.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/system.h	2002-07-20 01:08:40.000000000 +0000
@@ -4,6 +4,7 @@
  * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
  */
 #include <linux/config.h>
+#include <asm/arch/hardware.h>
 
 static inline void arch_idle(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/system3.h linux/include/asm-arm/arch-sa1100/system3.h
--- linux.orig/include/asm-arm/arch-sa1100/system3.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/system3.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,111 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/system3.h
+ *
+ * Copyright (C) 2001 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
+ *
+ * $Id: system3.h,v 1.2.4.2 2001/12/04 14:58:50 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: system3.h,v $
+ * Revision 1.2.4.2  2001/12/04 14:58:50  seletz
+ * - removed neponset hack
+ * - removed irq definitions (now in irqs.h)
+ *
+ * Revision 1.2.4.1  2001/12/04 12:51:18  seletz
+ * - re-added from linux_2_4_8_ac12_rmk1_np1_pt1
+ *
+ * Revision 1.2.2.2  2001/11/16 13:58:43  seletz
+ * - simplified cpld register access
+ *
+ * Revision 1.2.2.1  2001/10/15 16:17:20  seletz
+ * - first revision
+ *
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+/* System 3 LCD */
+#define SYS3LCD			SKPEN0
+#define SYS3LCDBACKL	SKPEN1
+#define SYS3LCDBRIGHT	SKPWM0
+#define SYS3LCDCONTR	SKPWM1
+
+#define PT_CPLD_BASE		(0x10000000)
+#define PT_SMC_BASE			(0x18000000)
+#define PT_SA1111_BASE		(0x40000000)
+
+#define Ptcpld_p2v( x )	((x) - PT_CPLD_BASE + 0xf3000000)
+#define Ptcpld_v2p( x )	((x) - 0xf3000000 + PT_CPLD_BASE)
+
+#define _PT_SYSID	( PT_CPLD_BASE + 0x00 )
+#define _PT_IRQSR	( PT_CPLD_BASE + 0x24 )
+#define _PT_CTRL0	( PT_CPLD_BASE + 0x90 )
+#define _PT_CTRL1	( PT_CPLD_BASE + 0xA0 )
+#define _PT_CTRL2	( PT_CPLD_BASE + 0xB0 )
+
+#define PT_SYSID	(*((volatile u_char *)Ptcpld_p2v( _PT_SYSID )))
+#define PT_IRQSR	(*((volatile u_char *)Ptcpld_p2v( _PT_IRQSR )))
+#define PT_CTRL0	(*((volatile u_char *)Ptcpld_p2v( _PT_CTRL0 )))
+#define PT_CTRL1	(*((volatile u_char *)Ptcpld_p2v( _PT_CTRL1 )))
+#define PT_CTRL2	(*((volatile u_char *)Ptcpld_p2v( _PT_CTRL2 )))
+
+#define PTCTRL0_set( x )	PT_CTRL0 |= (x)
+#define PTCTRL1_set( x )	PT_CTRL1 |= (x)
+#define PTCTRL2_set( x )	PT_CTRL2 |= (x)
+#define PTCTRL0_clear( x )	PT_CTRL0 &= ~(x)
+#define PTCTRL1_clear( x )	PT_CTRL1 &= ~(x)
+#define PTCTRL2_clear( x )	PT_CTRL2 &= ~(x)
+
+/* System ID register */
+
+/* IRQ Source Register */
+#define PT_IRQ_LAN		( 1<<0 )
+#define PT_IRQ_X		( 1<<1 )
+#define PT_IRQ_SA1111	( 1<<2 )
+#define PT_IRQ_RS1		( 1<<3 )
+#define PT_IRQ_RS1_RING	( 1<<4 )
+#define PT_IRQ_RS1_DCD	( 1<<5 )
+#define PT_IRQ_RS1_DSR	( 1<<6 )
+#define PT_IRQ_RS2		( 1<<7 )
+
+/* FIXME */
+#define PT_IRQ_USAR		( 1<<1 )
+
+/* CTRL 0 */
+#define PT_CTRL0_USBSLAVE	( 1<<0 )
+#define PT_CTRL0_USBHOST	( 1<<1 )
+#define PT_CTRL0_LCD_BL		( 1<<2 )
+#define PT_CTRL0_LAN_EN		( 1<<3 )	/* active low */
+#define PT_CTRL0_IRDA_M(x)	( (((u_char)x)&0x03)<<4 )
+#define PT_CTRL0_IRDA_M0	( 1<<4 )
+#define PT_CTRL0_IRDA_M1	( 1<<5 )
+#define PT_CTRL0_IRDA_FSEL	( 1<<6 )
+#define PT_CTRL0_LCD_EN		( 1<<7 )
+
+#define PT_CTRL0_INIT	( PT_CTRL0_USBSLAVE | PT_CTRL0_USBHOST | \
+						PT_CTRL0_LCD_BL | PT_CTRL0_LAN_EN | PT_CTRL0_LCD_EN )
+
+/* CTRL 1 */
+#define PT_CTRL1_RS3_MUX(x) ( (((u_char)x)&0x03)<<0 )
+#define PT_CTRL1_RS3_MUX0	( 1<<0 )
+#define PT_CTRL1_RS3_MUX1	( 1<<1 )
+#define PT_CTRL1_RS3_RST	( 1<<2 )
+#define PT_CTRL1_RS3_RS485_TERM	( 1<<4 )
+#define PT_CTRL1_X			( 1<<4 )
+#define PT_CTRL1_PCMCIA_A0VPP	( 1<<6 )
+#define PT_CTRL1_PCMCIA_A1VPP	( 1<<7 )
+
+#define PT_RS3_MUX_ALIRS	( 0 )
+#define PT_RS3_MUX_IDATA	( 1 )
+#define PT_RS3_MUX_RADIO	( 2 )
+#define PT_RS3_MUX_RS485	( 3 )
+
+/* CTRL 2 */
+#define PT_CTRL2_RS1_RTS	( 1<<0 )
+#define PT_CTRL2_RS1_DTR	( 1<<1 )
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/time.h linux/include/asm-arm/arch-sa1100/time.h
--- linux.orig/include/asm-arm/arch-sa1100/time.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/time.h	2002-07-20 01:08:37.000000000 +0000
@@ -10,7 +10,7 @@
  */
 
 
-#define RTC_DEF_DIVIDER		32768 - 1
+#define RTC_DEF_DIVIDER		(32768 - 1)
 #define RTC_DEF_TRIM            0
 
 static unsigned long __init sa1100_get_rtc_time(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-sa1100/uncompress.h linux/include/asm-arm/arch-sa1100/uncompress.h
--- linux.orig/include/asm-arm/arch-sa1100/uncompress.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/arch-sa1100/uncompress.h	2002-07-20 01:08:35.000000000 +0000
@@ -33,14 +33,16 @@
 
 	for (; *s; s++) {
 		/* wait for space in the UART's transmiter */
-		while (!(UART(UTSR1) & UTSR1_TNF));
+		while (!(UART(UTSR1) & UTSR1_TNF))
+			barrier();
 
 		/* send the character out. */
 		UART(UTDR) = *s;
 
 		/* if a LF, also do CR... */
 		if (*s == 10) {
-			while (!(UART(UTSR1) & UTSR1_TNF));
+			while (!(UART(UTSR1) & UTSR1_TNF))
+				barrier();
 			UART(UTDR) = 13;
 		}
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-shark/keyboard.h linux/include/asm-arm/arch-shark/keyboard.h
--- linux.orig/include/asm-arm/arch-shark/keyboard.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-arm/arch-shark/keyboard.h	2002-07-20 01:08:26.000000000 +0000
@@ -6,6 +6,7 @@
  * (C) 1998 Russell King
  * (C) 1998 Phil Blundell
  */
+#include <linux/config.h>
 #include <linux/ioport.h>
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -28,7 +29,6 @@
 
 static inline void kbd_init_hw(void)
 {
-	if (have_isa_bridge) {
 		k_setkeycode    = pckbd_setkeycode;
 		k_getkeycode    = pckbd_getkeycode;
 		k_translate     = pckbd_translate;
@@ -39,7 +39,6 @@
 		k_sysrq_xlate   = pckbd_sysrq_xlate;
 #endif
 		pckbd_init_hw();
-	}
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/arch-tbox/uncompress.h linux/include/asm-arm/arch-tbox/uncompress.h
--- linux.orig/include/asm-arm/arch-tbox/uncompress.h	2000-09-18 22:15:23.000000000 +0000
+++ linux/include/asm-arm/arch-tbox/uncompress.h	2002-07-20 01:08:34.000000000 +0000
@@ -18,10 +18,12 @@
   while (*s)
   {
     char c = *(s++);
-    while (!(__raw_readb(UARTBASE + 0x14) & 0x20));
+    while (!(__raw_readb(UARTBASE + 0x14) & 0x20))
+      barrier();
     __raw_writeb(c, UARTBASE);
     if (c == 10) {
-      while (!(__raw_readb(UARTBASE + 0x14) & 0x20));
+      while (!(__raw_readb(UARTBASE + 0x14) & 0x20))
+        barrier();
       __raw_writeb(13, UARTBASE);
     }
   }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/checksum.h linux/include/asm-arm/checksum.h
--- linux.orig/include/asm-arm/checksum.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/checksum.h	2002-07-20 01:08:39.000000000 +0000
@@ -55,25 +55,24 @@
 	unsigned int sum, tmp1;
 
 	__asm__ __volatile__(
-	"ldr	%0, [%1], #4		@ ip_fast_csum
-	ldr	%3, [%1], #4
-	sub	%2, %2, #5
-	adds	%0, %0, %3
-	ldr	%3, [%1], #4
-	adcs	%0, %0, %3
-	ldr	%3, [%1], #4
-	adcs	%0, %0, %3
-1:	ldr	%3, [%1], #4
-	adcs	%0, %0, %3
-	tst	%2, #15
-	subne	%2, %2, #1
-	bne	1b
-	adc	%0, %0, #0
-	adds	%0, %0, %0, lsl #16
-	addcs	%0, %0, #0x10000
-	mvn	%0, %0
-	mov	%0, %0, lsr #16
-	"
+	"ldr	%0, [%1], #4		@ ip_fast_csum		\n\
+	ldr	%3, [%1], #4					\n\
+	sub	%2, %2, #5					\n\
+	adds	%0, %0, %3					\n\
+	ldr	%3, [%1], #4					\n\
+	adcs	%0, %0, %3					\n\
+	ldr	%3, [%1], #4					\n\
+1:	adcs	%0, %0, %3					\n\
+	ldr	%3, [%1], #4					\n\
+	tst	%2, #15			@ do this carefully	\n\
+	subne	%2, %2, #1		@ without destroying	\n\
+	bne	1b			@ the carry flag	\n\
+	adcs	%0, %0, %3					\n\
+	adc	%0, %0, #0					\n\
+	adds	%0, %0, %0, lsl #16				\n\
+	addcs	%0, %0, #0x10000				\n\
+	mvn	%0, %0						\n\
+	mov	%0, %0, lsr #16"
 	: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
 	: "1" (iph), "2" (ihl)
 	: "cc");
@@ -87,7 +86,7 @@
 csum_fold(unsigned int sum)
 {
 	__asm__(
-	"adds	%0, %1, %1, lsl #16	@ csum_fold
+	"adds	%0, %1, %1, lsl #16	@ csum_fold		\n\
 	addcs	%0, %0, #0x10000"
 	: "=r" (sum)
 	: "r" (sum)
@@ -100,10 +99,10 @@
 		   unsigned int proto, unsigned int sum)
 {
 	__asm__(
-	"adds	%0, %1, %2		@ csum_tcpudp_nofold
-	adcs	%0, %0, %3
-	adcs	%0, %0, %4
-	adcs	%0, %0, %5
+	"adds	%0, %1, %2		@ csum_tcpudp_nofold	\n\
+	adcs	%0, %0, %3					\n\
+	adcs	%0, %0, %4					\n\
+	adcs	%0, %0, %5					\n\
 	adc	%0, %0, #0"
 	: "=&r"(sum)
 	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len) << 16), "Ir" (proto << 8)
@@ -119,13 +118,13 @@
 		  unsigned int proto, unsigned int sum)
 {
 	__asm__(
-	"adds	%0, %1, %2		@ csum_tcpudp_magic
-	adcs	%0, %0, %3
-	adcs	%0, %0, %4
-	adcs	%0, %0, %5
-	adc	%0, %0, #0
-	adds	%0, %0, %0, lsl #16
-	addcs	%0, %0, #0x10000
+	"adds	%0, %1, %2		@ csum_tcpudp_magic	\n\
+	adcs	%0, %0, %3					\n\
+	adcs	%0, %0, %4					\n\
+	adcs	%0, %0, %5					\n\
+	adc	%0, %0, #0					\n\
+	adds	%0, %0, %0, lsl #16				\n\
+	addcs	%0, %0, #0x10000				\n\
 	mvn	%0, %0"
 	: "=&r"(sum)
 	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (proto << 8)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/hardware/clps7111.h linux/include/asm-arm/hardware/clps7111.h
--- linux.orig/include/asm-arm/hardware/clps7111.h	2001-04-12 19:20:31.000000000 +0000
+++ linux/include/asm-arm/hardware/clps7111.h	2002-07-20 01:08:33.000000000 +0000
@@ -27,8 +27,10 @@
 
 #ifndef __ASSEMBLY__
 #define clps_readb(off)		__raw_readb(CLPS7111_BASE + (off))
+#define clps_readw(off)		__raw_readw(CLPS7111_BASE + (off))
 #define clps_readl(off)		__raw_readl(CLPS7111_BASE + (off))
 #define clps_writeb(val,off)	__raw_writeb(val, CLPS7111_BASE + (off))
+#define clps_writew(val,off)	__raw_writew(val, CLPS7111_BASE + (off))
 #define clps_writel(val,off)	__raw_writel(val, CLPS7111_BASE + (off))
 #endif
 
@@ -48,6 +50,7 @@
 #define INTSR1		(0x0240)
 #define INTMR1		(0x0280)
 #define LCDCON		(0x02c0)
+#define TC1D            (0x0300)
 #define TC2D		(0x0340)
 #define RTCDR		(0x0380)
 #define RTCMR		(0x03c0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/hardware/cs89712.h linux/include/asm-arm/hardware/cs89712.h
--- linux.orig/include/asm-arm/hardware/cs89712.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/hardware/cs89712.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,49 @@
+/*
+ *  linux/include/asm-arm/hardware/cs89712.h
+ *
+ *  This file contains the hardware definitions of the CS89712
+ *  additional internal registers.
+ *
+ *  Copyright (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
+ */
+#ifndef __ASM_HARDWARE_CS89712_H
+#define __ASM_HARDWARE_CS89712_H
+
+/*
+*	CS89712 additional registers
+*/
+                                  
+#define PCDR			0x0002	/* Port C Data register ---------------------------- */
+#define PCDDR			0x0042	/* Port C Data Direction register ------------------ */
+#define SDCONF			0x2300  /* SDRAM Configuration register ---------------------*/
+#define SDRFPR			0x2340  /* SDRAM Refresh period register --------------------*/
+
+#define SDCONF_ACTIVE		(1 << 10)
+#define SDCONF_CLKCTL		(1 << 9)
+#define SDCONF_WIDTH_4		(0 << 7)
+#define SDCONF_WIDTH_8		(1 << 7)
+#define SDCONF_WIDTH_16		(2 << 7)
+#define SDCONF_WIDTH_32		(3 << 7)
+#define SDCONF_SIZE_16		(0 << 5)
+#define SDCONF_SIZE_64		(1 << 5)
+#define SDCONF_SIZE_128		(2 << 5)
+#define SDCONF_SIZE_256		(3 << 5)
+#define SDCONF_CASLAT_2		(2)
+#define SDCONF_CASLAT_3		(3)
+
+#endif /* __ASM_HARDWARE_CS89712_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/hardware/ep7212.h linux/include/asm-arm/hardware/ep7212.h
--- linux.orig/include/asm-arm/hardware/ep7212.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-arm/hardware/ep7212.h	2002-07-20 01:08:29.000000000 +0000
@@ -23,8 +23,6 @@
 #ifndef __ASM_HARDWARE_EP7212_H
 #define __ASM_HARDWARE_EP7212_H
 
-#include <linux/config.h>
-
 /*
  * define EP7212_BASE to be the base address of the region
  * you want to access.
@@ -49,10 +47,6 @@
 #define INTSR3			0x2240
 #define INTMR3			0x2280
 #define LEDFLSH			0x22c0
-#if defined (CONFIG_ARCH_CDB89712)
-#define SDCONF			0x2300
-#define SDRFPR			0x2340
-#endif
 
 #define DAIR_DAIEN		(1 << 16)
 #define DAIR_ECS		(1 << 17)
@@ -86,19 +80,4 @@
 #define SYSCON3_FASTWAKE	(1 << 8)
 #define SYSCON3_DAIEN		(1 << 9)
 
-#if defined (CONFIG_ARCH_CDB89712)
-#define SDCONF_ACTIVE		(1 << 10)
-#define SDCONF_CLKCTL		(1 << 9)
-#define SDCONF_WIDTH_4		(0 << 7)
-#define SDCONF_WIDTH_8		(1 << 7)
-#define SDCONF_WIDTH_16		(2 << 7)
-#define SDCONF_WIDTH_32		(3 << 7)
-#define SDCONF_SIZE_16		(0 << 5)
-#define SDCONF_SIZE_64		(1 << 5)
-#define SDCONF_SIZE_128		(2 << 5)
-#define SDCONF_SIZE_256		(3 << 5)
-#define SDCONF_CASLAT_2		(2)
-#define SDCONF_CASLAT_3		(3)
-#endif
-
 #endif /* __ASM_HARDWARE_EP7212_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/hardware/sa1111.h linux/include/asm-arm/hardware/sa1111.h
--- linux.orig/include/asm-arm/hardware/sa1111.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-arm/hardware/sa1111.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,678 @@
+/*
+ * linux/include/asm-arm/hardware/SA-1111.h
+ *
+ * Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
+ *
+ * This file contains definitions for the SA-1111 Companion Chip.
+ * (Structure and naming borrowed from SA-1101.h, by Peter Danielsson.)
+ *
+ * Macro that calculates real address for registers in the SA-1111
+ */
+
+#ifndef _ASM_ARCH_SA1111
+#define _ASM_ARCH_SA1111
+
+#include <asm/arch/bitfield.h>
+
+/*
+ * The SA1111 is always located at virtual 0xf4000000, and is always
+ * "native" endian.
+ */
+
+#define SA1111_VBASE		0xf4000000
+
+/* Don't use these! */
+#define SA1111_p2v( x )         ((x) - SA1111_BASE + SA1111_VBASE)
+#define SA1111_v2p( x )         ((x) - SA1111_VBASE + SA1111_BASE)
+
+#ifndef __ASSEMBLY__
+
+extern struct resource sa1111_resource;
+#define _SA1111(x)	((x) + sa1111_resource.start)
+#endif
+
+/*
+ * 26 bits of the SA-1110 address bus are available to the SA-1111.
+ * Use these when feeding target addresses to the DMA engines.
+ */
+
+#define SA1111_ADDR_WIDTH	(26)
+#define SA1111_ADDR_MASK	((1<<SA1111_ADDR_WIDTH)-1)
+#define SA1111_DMA_ADDR(x)	((x)&SA1111_ADDR_MASK)
+
+/*
+ * Don't ask the (SAC) DMA engines to move less than this amount.
+ */
+
+#define SA1111_SAC_DMA_MIN_XFER	(0x800)
+
+/*
+ * SA1111 register definitions.
+ */
+#define __CCREG(x)	__REGP(SA1111_VBASE + (x))
+
+/* System Bus Interface (SBI)
+ *
+ * Registers
+ *    SKCR	Control Register
+ *    SMCR	Shared Memory Controller Register
+ *    SKID	ID Register
+ */
+#define SA1111_SKCR	0x0000
+#define SA1111_SMCR	0x0004
+#define SA1111_SKID	0x0008
+
+#define _SBI_SKCR	_SA1111(SA1111_SKCR)
+#define _SBI_SMCR	_SA1111(SA1111_SMCR)
+#define _SBI_SKID	_SA1111(SA1111_SKID)
+
+#if LANGUAGE == C
+
+#define SBI_SKCR	__CCREG(SA1111_SKCR)
+#define SBI_SMCR	__CCREG(SA1111_SMCR)
+#define SBI_SKID	__CCREG(SA1111_SKID)
+
+#endif  /* LANGUAGE == C */
+
+#define SKCR_PLL_BYPASS	(1<<0)
+#define SKCR_RCLKEN	(1<<1)
+#define SKCR_SLEEP	(1<<2)
+#define SKCR_DOZE	(1<<3)
+#define SKCR_VCO_OFF	(1<<4)
+#define SKCR_SCANTSTEN	(1<<5)
+#define SKCR_CLKTSTEN	(1<<6)
+#define SKCR_RDYEN	(1<<7)
+#define SKCR_SELAC	(1<<8)
+#define SKCR_OPPC	(1<<9)
+#define SKCR_PLLTSTEN	(1<<10)
+#define SKCR_USBIOTSTEN	(1<<11)
+/*
+ * Don't believe the specs!  Take them, throw them outside.  Leave them
+ * there for a week.  Spit on them.  Walk on them.  Stamp on them.
+ * Pour gasoline over them and finally burn them.  Now think about coding.
+ *  - The October 1999 errata (278260-007) says its bit 13, 1 to enable.
+ *  - The Feb 2001 errata (278260-010) says that the previous errata
+ *    (278260-009) is wrong, and its bit actually 12, fixed in spec
+ *    278242-003.
+ *  - The SA1111 manual (278242) says bit 12, but 0 to enable.
+ *  - Reality is bit 13, 1 to enable.
+ *      -- rmk
+ */
+#define SKCR_OE_EN	(1<<13)
+
+#define SMCR_DTIM	(1<<0)
+#define SMCR_MBGE	(1<<1)
+#define SMCR_DRAC_0	(1<<2)
+#define SMCR_DRAC_1	(1<<3)
+#define SMCR_DRAC_2	(1<<4)
+#define SMCR_DRAC	Fld(3, 2)
+#define SMCR_CLAT	(1<<5)
+
+#define SKID_SIREV_MASK	(0x000000f0)
+#define SKID_MTREV_MASK (0x0000000f)
+#define SKID_ID_MASK	(0xffffff00)
+#define SKID_SA1111_ID	(0x690cc200)
+
+/*
+ * System Controller
+ *
+ * Registers
+ *    SKPCR	Power Control Register
+ *    SKCDR	Clock Divider Register
+ *    SKAUD	Audio Clock Divider Register
+ *    SKPMC	PS/2 Mouse Clock Divider Register
+ *    SKPTC	PS/2 Track Pad Clock Divider Register
+ *    SKPEN0	PWM0 Enable Register
+ *    SKPWM0	PWM0 Clock Register
+ *    SKPEN1	PWM1 Enable Register
+ *    SKPWM1	PWM1 Clock Register
+ */
+
+#define _SKPCR		_SA1111(0x0200)
+#define _SKCDR		_SA1111(0x0204)
+#define _SKAUD		_SA1111(0x0208)
+#define _SKPMC		_SA1111(0x020c)
+#define _SKPTC		_SA1111(0x0210)
+#define _SKPEN0		_SA1111(0x0214)
+#define _SKPWM0		_SA1111(0x0218)
+#define _SKPEN1		_SA1111(0x021c)
+#define _SKPWM1		_SA1111(0x0220)
+
+#if LANGUAGE == C
+
+#define SKPCR		__CCREG(0x0200)
+#define SKCDR		__CCREG(0x0204)
+#define SKAUD		__CCREG(0x0208)
+#define SKPMC		__CCREG(0x020c)
+#define SKPTC		__CCREG(0x0210)
+#define SKPEN0		__CCREG(0x0214)
+#define SKPWM0		__CCREG(0x0218)
+#define SKPEN1		__CCREG(0x021c)
+#define SKPWM1		__CCREG(0x0220)
+
+#endif  /* LANGUAGE == C */
+
+#define SKPCR_UCLKEN	(1<<0)
+#define SKPCR_ACCLKEN	(1<<1)
+#define SKPCR_I2SCLKEN	(1<<2)
+#define SKPCR_L3CLKEN	(1<<3)
+#define SKPCR_SCLKEN	(1<<4)
+#define SKPCR_PMCLKEN	(1<<5)
+#define SKPCR_PTCLKEN	(1<<6)
+#define SKPCR_DCLKEN	(1<<7)
+#define SKPCR_PWMCLKEN	(1<<8)
+
+/*
+ * USB Host controller
+ */
+#define _USB_OHCI_OP_BASE	_SA1111( 0x400 )
+#define _USB_STATUS		_SA1111( 0x518 )
+#define _USB_RESET		_SA1111( 0x51c )
+#define _USB_INTERRUPTEST	_SA1111( 0x520 )
+
+#define _USB_EXTENT		(_USB_INTERRUPTEST - _USB_OHCI_OP_BASE + 4)
+
+#if LANGUAGE == C
+
+#define USB_OHCI_OP_BASE	__CCREG(0x0400)
+#define USB_STATUS		__CCREG(0x0518)
+#define USB_RESET		__CCREG(0x051c)
+#define USB_INTERRUPTEST	__CCReG(0x0520)
+
+#endif  /* LANGUAGE == C */
+
+#define USB_RESET_FORCEIFRESET	(1 << 0)
+#define USB_RESET_FORCEHCRESET	(1 << 1)
+#define USB_RESET_CLKGENRESET	(1 << 2)
+#define USB_RESET_SIMSCALEDOWN	(1 << 3)
+#define USB_RESET_USBINTTEST	(1 << 4)
+#define USB_RESET_SLEEPSTBYEN	(1 << 5)
+#define USB_RESET_PWRSENSELOW	(1 << 6)
+#define USB_RESET_PWRCTRLLOW	(1 << 7)
+
+/*
+ * Serial Audio Controller
+ *
+ * Registers
+ *    SACR0             Serial Audio Common Control Register
+ *    SACR1             Serial Audio Alternate Mode (I2C/MSB) Control Register
+ *    SACR2             Serial Audio AC-link Control Register
+ *    SASR0             Serial Audio I2S/MSB Interface & FIFO Status Register
+ *    SASR1             Serial Audio AC-link Interface & FIFO Status Register
+ *    SASCR             Serial Audio Status Clear Register
+ *    L3_CAR            L3 Control Bus Address Register
+ *    L3_CDR            L3 Control Bus Data Register
+ *    ACCAR             AC-link Command Address Register
+ *    ACCDR             AC-link Command Data Register
+ *    ACSAR             AC-link Status Address Register
+ *    ACSDR             AC-link Status Data Register
+ *    SADTCS            Serial Audio DMA Transmit Control/Status Register
+ *    SADTSA            Serial Audio DMA Transmit Buffer Start Address A
+ *    SADTCA            Serial Audio DMA Transmit Buffer Count Register A
+ *    SADTSB            Serial Audio DMA Transmit Buffer Start Address B
+ *    SADTCB            Serial Audio DMA Transmit Buffer Count Register B
+ *    SADRCS            Serial Audio DMA Receive Control/Status Register
+ *    SADRSA            Serial Audio DMA Receive Buffer Start Address A
+ *    SADRCA            Serial Audio DMA Receive Buffer Count Register A
+ *    SADRSB            Serial Audio DMA Receive Buffer Start Address B
+ *    SADRCB            Serial Audio DMA Receive Buffer Count Register B
+ *    SAITR             Serial Audio Interrupt Test Register
+ *    SADR              Serial Audio Data Register (16 x 32-bit)
+ */
+
+#define _SACR0          _SA1111( 0x0600 )
+#define _SACR1          _SA1111( 0x0604 )
+#define _SACR2          _SA1111( 0x0608 )
+#define _SASR0          _SA1111( 0x060c )
+#define _SASR1          _SA1111( 0x0610 )
+#define _SASCR          _SA1111( 0x0618 )
+#define _L3_CAR         _SA1111( 0x061c )
+#define _L3_CDR         _SA1111( 0x0620 )
+#define _ACCAR          _SA1111( 0x0624 )
+#define _ACCDR          _SA1111( 0x0628 )
+#define _ACSAR          _SA1111( 0x062c )
+#define _ACSDR          _SA1111( 0x0630 )
+#define _SADTCS         _SA1111( 0x0634 )
+#define _SADTSA         _SA1111( 0x0638 )
+#define _SADTCA         _SA1111( 0x063c )
+#define _SADTSB         _SA1111( 0x0640 )
+#define _SADTCB         _SA1111( 0x0644 )
+#define _SADRCS         _SA1111( 0x0648 )
+#define _SADRSA         _SA1111( 0x064c )
+#define _SADRCA         _SA1111( 0x0650 )
+#define _SADRSB         _SA1111( 0x0654 )
+#define _SADRCB         _SA1111( 0x0658 )
+#define _SAITR          _SA1111( 0x065c )
+#define _SADR           _SA1111( 0x0680 )
+
+#if LANGUAGE == C
+
+#define SACR0		__CCREG(0x0600)
+#define SACR1		__CCREG(0x0604)
+#define SACR2		__CCREG(0x0608)
+#define SASR0		__CCREG(0x060c)
+#define SASR1		__CCREG(0x0610)
+#define SASCR		__CCREG(0x0618)
+#define L3_CAR		__CCREG(0x061c)
+#define L3_CDR		__CCREG(0x0620)
+#define ACCAR		__CCREG(0x0624)
+#define ACCDR		__CCREG(0x0628)
+#define ACSAR		__CCREG(0x062c)
+#define ACSDR		__CCREG(0x0630)
+#define SADTCS		__CCREG(0x0634)
+#define SADTSA		__CCREG(0x0638)
+#define SADTCA		__CCREG(0x063c)
+#define SADTSB		__CCREG(0x0640)
+#define SADTCB		__CCREG(0x0644)
+#define SADRCS		__CCREG(0x0648)
+#define SADRSA		__CCREG(0x064c)
+#define SADRCA		__CCREG(0x0650)
+#define SADRSB		__CCREG(0x0654)
+#define SADRCB		__CCREG(0x0658)
+#define SAITR		__CCREG(0x065c)
+#define SADR		__CCREG(0x0680)
+
+#endif  /* LANGUAGE == C */
+
+#define SACR0_ENB	(1<<0)
+#define SACR0_BCKD	(1<<2)
+#define SACR0_RST	(1<<3)
+
+#define SACR1_AMSL	(1<<0)
+#define SACR1_L3EN	(1<<1)
+#define SACR1_L3MB	(1<<2)
+#define SACR1_DREC	(1<<3)
+#define SACR1_DRPL	(1<<4)
+#define SACR1_ENLBF	(1<<5)
+
+#define SACR2_TS3V	(1<<0)
+#define SACR2_TS4V	(1<<1)
+#define SACR2_WKUP	(1<<2)
+#define SACR2_DREC	(1<<3)
+#define SACR2_DRPL	(1<<4)
+#define SACR2_ENLBF	(1<<5)
+#define SACR2_RESET	(1<<6)
+
+#define SASR0_TNF	(1<<0)
+#define SASR0_RNE	(1<<1)
+#define SASR0_BSY	(1<<2)
+#define SASR0_TFS	(1<<3)
+#define SASR0_RFS	(1<<4)
+#define SASR0_TUR	(1<<5)
+#define SASR0_ROR	(1<<6)
+#define SASR0_L3WD	(1<<16)
+#define SASR0_L3RD	(1<<17)
+
+#define SASR1_TNF	(1<<0)
+#define SASR1_RNE	(1<<1)
+#define SASR1_BSY	(1<<2)
+#define SASR1_TFS	(1<<3)
+#define SASR1_RFS	(1<<4)
+#define SASR1_TUR	(1<<5)
+#define SASR1_ROR	(1<<6)
+#define SASR1_CADT	(1<<16)
+#define SASR1_SADR	(1<<17)
+#define SASR1_RSTO	(1<<18)
+#define SASR1_CLPM	(1<<19)
+#define SASR1_CRDY	(1<<20)
+#define SASR1_RS3V	(1<<21)
+#define SASR1_RS4V	(1<<22)
+
+#define SASCR_TUR	(1<<5)
+#define SASCR_ROR	(1<<6)
+#define SASCR_DTS	(1<<16)
+#define SASCR_RDD	(1<<17)
+#define SASCR_STO	(1<<18)
+
+#define SADTCS_TDEN	(1<<0)
+#define SADTCS_TDIE	(1<<1)
+#define SADTCS_TDBDA	(1<<3)
+#define SADTCS_TDSTA	(1<<4)
+#define SADTCS_TDBDB	(1<<5)
+#define SADTCS_TDSTB	(1<<6)
+#define SADTCS_TBIU	(1<<7)
+
+#define SADRCS_RDEN	(1<<0)
+#define SADRCS_RDIE	(1<<1)
+#define SADRCS_RDBDA	(1<<3)
+#define SADRCS_RDSTA	(1<<4)
+#define SADRCS_RDBDB	(1<<5)
+#define SADRCS_RDSTB	(1<<6)
+#define SADRCS_RBIU	(1<<7)
+
+#define SAD_CS_DEN	(1<<0)
+#define SAD_CS_DIE	(1<<1)	/* Not functional on metal 1 */
+#define SAD_CS_DBDA	(1<<3)	/* Not functional on metal 1 */
+#define SAD_CS_DSTA	(1<<4)
+#define SAD_CS_DBDB	(1<<5)	/* Not functional on metal 1 */
+#define SAD_CS_DSTB	(1<<6)
+#define SAD_CS_BIU	(1<<7)	/* Not functional on metal 1 */
+
+#define SAITR_TFS	(1<<0)
+#define SAITR_RFS	(1<<1)
+#define SAITR_TUR	(1<<2)
+#define SAITR_ROR	(1<<3)
+#define SAITR_CADT	(1<<4)
+#define SAITR_SADR	(1<<5)
+#define SAITR_RSTO	(1<<6)
+#define SAITR_TDBDA	(1<<8)
+#define SAITR_TDBDB	(1<<9)
+#define SAITR_RDBDA	(1<<10)
+#define SAITR_RDBDB	(1<<11)
+
+/*
+ * General-Purpose I/O Interface
+ *
+ * Registers
+ *    PA_DDR		GPIO Block A Data Direction
+ *    PA_DRR/PA_DWR	GPIO Block A Data Value Register (read/write)
+ *    PA_SDR		GPIO Block A Sleep Direction
+ *    PA_SSR		GPIO Block A Sleep State
+ *    PB_DDR		GPIO Block B Data Direction
+ *    PB_DRR/PB_DWR	GPIO Block B Data Value Register (read/write)
+ *    PB_SDR		GPIO Block B Sleep Direction
+ *    PB_SSR		GPIO Block B Sleep State
+ *    PC_DDR		GPIO Block C Data Direction
+ *    PC_DRR/PC_DWR	GPIO Block C Data Value Register (read/write)
+ *    PC_SDR		GPIO Block C Sleep Direction
+ *    PC_SSR		GPIO Block C Sleep State
+ */
+
+#define _PA_DDR		_SA1111( 0x1000 )
+#define _PA_DRR		_SA1111( 0x1004 )
+#define _PA_DWR		_SA1111( 0x1004 )
+#define _PA_SDR		_SA1111( 0x1008 )
+#define _PA_SSR		_SA1111( 0x100c )
+#define _PB_DDR		_SA1111( 0x1010 )
+#define _PB_DRR		_SA1111( 0x1014 )
+#define _PB_DWR		_SA1111( 0x1014 )
+#define _PB_SDR		_SA1111( 0x1018 )
+#define _PB_SSR		_SA1111( 0x101c )
+#define _PC_DDR		_SA1111( 0x1020 )
+#define _PC_DRR		_SA1111( 0x1024 )
+#define _PC_DWR		_SA1111( 0x1024 )
+#define _PC_SDR		_SA1111( 0x1028 )
+#define _PC_SSR		_SA1111( 0x102c )
+
+#if LANGUAGE == C
+
+#define PA_DDR		__CCREG(0x1000)
+#define PA_DRR		__CCREG(0x1004)
+#define PA_DWR		__CCREG(0x1004)
+#define PA_SDR		__CCREG(0x1008)
+#define PA_SSR		__CCREG(0x100c)
+#define PB_DDR		__CCREG(0x1010)
+#define PB_DRR		__CCREG(0x1014)
+#define PB_DWR		__CCREG(0x1014)
+#define PB_SDR		__CCREG(0x1018)
+#define PB_SSR		__CCREG(0x101c)
+#define PC_DDR		__CCREG(0x1020)
+#define PC_DRR		__CCREG(0x1024)
+#define PC_DWR		__CCREG(0x1024)
+#define PC_SDR		__CCREG(0x1028)
+#define PC_SSR		__CCREG(0x102c)
+
+#endif  /* LANGUAGE == C */
+
+/*
+ * Interrupt Controller
+ *
+ * Registers
+ *    INTTEST0		Test register 0
+ *    INTTEST1		Test register 1
+ *    INTEN0		Interrupt Enable register 0
+ *    INTEN1		Interrupt Enable register 1
+ *    INTPOL0		Interrupt Polarity selection 0
+ *    INTPOL1		Interrupt Polarity selection 1
+ *    INTTSTSEL		Interrupt source selection
+ *    INTSTATCLR0	Interrupt Status/Clear 0
+ *    INTSTATCLR1	Interrupt Status/Clear 1
+ *    INTSET0		Interrupt source set 0
+ *    INTSET1		Interrupt source set 1
+ *    WAKE_EN0		Wake-up source enable 0
+ *    WAKE_EN1		Wake-up source enable 1
+ *    WAKE_POL0		Wake-up polarity selection 0
+ *    WAKE_POL1		Wake-up polarity selection 1
+ */
+
+#define SA1111_INTTEST0		0x1600
+#define SA1111_INTTEST1		0x1604
+#define SA1111_INTEN0		0x1608
+#define SA1111_INTEN1		0x160c
+#define SA1111_INTPOL0		0x1610
+#define SA1111_INTPOL1		0x1614
+#define SA1111_INTTSTSEL	0x1618
+#define SA1111_INTSTATCLR0	0x161c
+#define SA1111_INTSTATCLR1	0x1620
+#define SA1111_INTSET0		0x1624
+#define SA1111_INTSET1		0x1628
+#define SA1111_WAKE_EN0		0x162c
+#define SA1111_WAKE_EN1		0x1630
+#define SA1111_WAKE_POL0	0x1634
+#define SA1111_WAKE_POL1	0x1638
+
+#define _INTTEST0	_SA1111(SA1111_INTTEST0)
+#define _INTTEST1	_SA1111(SA1111_INTTEST1)
+#define _INTEN0		_SA1111(SA1111_INTEN0)
+#define _INTEN1		_SA1111(SA1111_INTEN1)
+#define _INTPOL0	_SA1111(SA1111_INTPOL0)
+#define _INTPOL1	_SA1111(SA1111_INTPOL1)
+#define _INTTSTSEL	_SA1111(SA1111_INTTSTSEL)
+#define _INTSTATCLR0	_SA1111(SA1111_INTSTATCLR0)
+#define _INTSTATCLR1	_SA1111(SA1111_INTSTATCLR1)
+#define _INTSET0	_SA1111(SA1111_INTSET0)
+#define _INTSET1	_SA1111(SA1111_INTSET1)
+#define _WAKE_EN0	_SA1111(SA1111_WAKE_EN0)
+#define _WAKE_EN1	_SA1111(SA1111_WAKE_EN1)
+#define _WAKE_POL0	_SA1111(SA1111_WAKE_POL0)
+#define _WAKE_POL1	_SA1111(SA1111_WAKE_POL1)
+
+#if LANGUAGE == C
+
+#define INTTEST0	__CCREG(SA1111_INTTEST0)
+#define INTTEST1	__CCREG(SA1111_INTTEST1)
+#define INTEN0		__CCREG(SA1111_INTEN0)
+#define INTEN1		__CCREG(SA1111_INTEN1)
+#define INTPOL0		__CCREG(SA1111_INTPOL0)
+#define INTPOL1		__CCREG(SA1111_INTPOL1)
+#define INTTSTSEL	__CCREG(SA1111_INTTSTSEL)
+#define INTSTATCLR0	__CCREG(SA1111_INTSTATCLR0)
+#define INTSTATCLR1	__CCREG(SA1111_INTSTATCLR1)
+#define INTSET0		__CCREG(SA1111_INTSET0)
+#define INTSET1		__CCREG(SA1111_INTSET1)
+#define WAKE_EN0	__CCREG(SA1111_WAKE_EN0)
+#define WAKE_EN1	__CCREG(SA1111_WAKE_EN1)
+#define WAKE_POL0	__CCREG(SA1111_WAKE_POL0)
+#define WAKE_POL1	__CCREG(SA1111_WAKE_POL1)
+
+#endif  /* LANGUAGE == C */
+
+/*
+ * PS/2 Trackpad and Mouse Interfaces
+ *
+ * Registers   (prefix kbd applies to trackpad interface, mse to mouse)
+ *    KBDCR     Control Register
+ *    KBDSTAT       Status Register
+ *    KBDDATA       Transmit/Receive Data register
+ *    KBDCLKDIV     Clock Division Register
+ *    KBDPRECNT     Clock Precount Register
+ *    KBDTEST1      Test register 1
+ *    KBDTEST2      Test register 2
+ *    KBDTEST3      Test register 3
+ *    KBDTEST4      Test register 4
+ *    MSECR
+ *    MSESTAT
+ *    MSEDATA
+ *    MSECLKDIV
+ *    MSEPRECNT
+ *    MSETEST1
+ *    MSETEST2
+ *    MSETEST3
+ *    MSETEST4
+ *
+ */
+
+#define _KBD( x )   _SA1111( 0x0A00 )
+#define _MSE( x )   _SA1111( 0x0C00 )
+
+#define _KBDCR	    _SA1111( 0x0A00 )
+#define _KBDSTAT    _SA1111( 0x0A04 )
+#define _KBDDATA    _SA1111( 0x0A08 )
+#define _KBDCLKDIV  _SA1111( 0x0A0C )
+#define _KBDPRECNT  _SA1111( 0x0A10 )
+#define _MSECR	    _SA1111( 0x0C00 )
+#define _MSESTAT    _SA1111( 0x0C04 )
+#define _MSEDATA    _SA1111( 0x0C08 )
+#define _MSECLKDIV  _SA1111( 0x0C0C )
+#define _MSEPRECNT  _SA1111( 0x0C10 )
+
+#if ( LANGUAGE == C )
+
+#define KBDCR		__CCREG(0x0a00)
+#define KBDSTAT		__CCREG(0x0a04)
+#define KBDDATA		__CCREG(0x0a08)
+#define KBDCLKDIV	__CCREG(0x0a0c)
+#define KBDPRECNT	__CCREG(0x0a10)
+#define MSECR		__CCREG(0x0c00)
+#define MSESTAT		__CCREG(0x0c04)
+#define MSEDATA		__CCREG(0x0c08)
+#define MSECLKDIV	__CCREG(0x0c0c)
+#define MSEPRECNT	__CCREG(0x0c10)
+
+#define KBDCR_ENA        0x08
+#define KBDCR_FKD        0x02
+#define KBDCR_FKC        0x01
+
+#define KBDSTAT_TXE      0x80
+#define KBDSTAT_TXB      0x40
+#define KBDSTAT_RXF      0x20
+#define KBDSTAT_RXB      0x10
+#define KBDSTAT_ENA      0x08
+#define KBDSTAT_RXP      0x04
+#define KBDSTAT_KBD      0x02
+#define KBDSTAT_KBC      0x01
+
+#define KBDCLKDIV_DivVal     Fld(4,0)
+
+#define MSECR_ENA        0x08
+#define MSECR_FKD        0x02
+#define MSECR_FKC        0x01
+
+#define MSESTAT_TXE      0x80
+#define MSESTAT_TXB      0x40
+#define MSESTAT_RXF      0x20
+#define MSESTAT_RXB      0x10
+#define MSESTAT_ENA      0x08
+#define MSESTAT_RXP      0x04
+#define MSESTAT_MSD      0x02
+#define MSESTAT_MSC      0x01
+
+#define MSECLKDIV_DivVal     Fld(4,0)
+
+#define KBDTEST1_CD      0x80
+#define KBDTEST1_RC1         0x40
+#define KBDTEST1_MC      0x20
+#define KBDTEST1_C       Fld(2,3)
+#define KBDTEST1_T2      0x40
+#define KBDTEST1_T1      0x20
+#define KBDTEST1_T0      0x10
+#define KBDTEST2_TICBnRES    0x08
+#define KBDTEST2_RKC         0x04
+#define KBDTEST2_RKD         0x02
+#define KBDTEST2_SEL         0x01
+#define KBDTEST3_ms_16       0x80
+#define KBDTEST3_us_64       0x40
+#define KBDTEST3_us_16       0x20
+#define KBDTEST3_DIV8        0x10
+#define KBDTEST3_DIn         0x08
+#define KBDTEST3_CIn         0x04
+#define KBDTEST3_KD      0x02
+#define KBDTEST3_KC      0x01
+#define KBDTEST4_BC12        0x80
+#define KBDTEST4_BC11        0x40
+#define KBDTEST4_TRES        0x20
+#define KBDTEST4_CLKOE       0x10
+#define KBDTEST4_CRES        0x08
+#define KBDTEST4_RXB         0x04
+#define KBDTEST4_TXB         0x02
+#define KBDTEST4_SRX         0x01
+
+#define MSETEST1_CD      0x80
+#define MSETEST1_RC1         0x40
+#define MSETEST1_MC      0x20
+#define MSETEST1_C       Fld(2,3)
+#define MSETEST1_T2      0x40
+#define MSETEST1_T1      0x20
+#define MSETEST1_T0      0x10
+#define MSETEST2_TICBnRES    0x08
+#define MSETEST2_RKC         0x04
+#define MSETEST2_RKD         0x02
+#define MSETEST2_SEL         0x01
+#define MSETEST3_ms_16       0x80
+#define MSETEST3_us_64       0x40
+#define MSETEST3_us_16       0x20
+#define MSETEST3_DIV8        0x10
+#define MSETEST3_DIn         0x08
+#define MSETEST3_CIn         0x04
+#define MSETEST3_KD      0x02
+#define MSETEST3_KC      0x01
+#define MSETEST4_BC12        0x80
+#define MSETEST4_BC11        0x40
+#define MSETEST4_TRES        0x20
+#define MSETEST4_CLKOE       0x10
+#define MSETEST4_CRES        0x08
+#define MSETEST4_RXB         0x04
+#define MSETEST4_TXB         0x02
+#define MSETEST4_SRX         0x01
+
+#endif  /* LANGUAGE == C */
+
+/*
+ * PCMCIA Interface
+ *
+ * Registers
+ *    PCSR	Status Register
+ *    PCCR	Control Register
+ *    PCSSR	Sleep State Register
+ */
+
+#define _PCCR		_SA1111( 0x1800 )
+#define _PCSSR		_SA1111( 0x1804 )
+#define _PCSR		_SA1111( 0x1808 )
+
+#if LANGUAGE == C
+
+#define PCCR		__CCREG(0x1800)
+#define PCSSR		__CCREG(0x1804)
+#define PCSR		__CCREG(0x1808)
+
+#endif  /* LANGUAGE == C */
+
+#define PCSR_S0_READY	(1<<0)
+#define PCSR_S1_READY	(1<<1)
+#define PCSR_S0_DETECT	(1<<2)
+#define PCSR_S1_DETECT	(1<<3)
+#define PCSR_S0_VS1	(1<<4)
+#define PCSR_S0_VS2	(1<<5)
+#define PCSR_S1_VS1	(1<<6)
+#define PCSR_S1_VS2	(1<<7)
+#define PCSR_S0_WP	(1<<8)
+#define PCSR_S1_WP	(1<<9)
+#define PCSR_S0_BVD1	(1<<10)
+#define PCSR_S0_BVD2	(1<<11)
+#define PCSR_S1_BVD1	(1<<12)
+#define PCSR_S1_BVD2	(1<<13)
+
+#define PCCR_S0_RST	(1<<0)
+#define PCCR_S1_RST	(1<<1)
+#define PCCR_S0_FLT	(1<<2)
+#define PCCR_S1_FLT	(1<<3)
+#define PCCR_S0_PWAITEN	(1<<4)
+#define PCCR_S1_PWAITEN	(1<<5)
+#define PCCR_S0_PSE	(1<<6)
+#define PCCR_S1_PSE	(1<<7)
+
+#define PCSSR_S0_SLEEP	(1<<0)
+#define PCSSR_S1_SLEEP	(1<<1)
+
+#endif  /* _ASM_ARCH_SA1111 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/hdreg.h linux/include/asm-arm/hdreg.h
--- linux.orig/include/asm-arm/hdreg.h	1999-05-13 18:00:08.000000000 +0000
+++ linux/include/asm-arm/hdreg.h	2002-07-20 01:08:36.000000000 +0000
@@ -7,7 +7,7 @@
 #ifndef __ASMARM_HDREG_H
 #define __ASMARM_HDREG_H
 
-typedef unsigned long ide_ioreg_t;
+typedef unsigned int ide_ioreg_t;
 
 #endif /* __ASMARM_HDREG_H */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/ide.h linux/include/asm-arm/ide.h
--- linux.orig/include/asm-arm/ide.h	1999-06-17 08:11:35.000000000 +0000
+++ linux/include/asm-arm/ide.h	2002-07-20 01:08:34.000000000 +0000
@@ -30,7 +30,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+	} b;
+} control_t;
 
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
 #define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/io.h linux/include/asm-arm/io.h
--- linux.orig/include/asm-arm/io.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/io.h	2002-07-20 01:08:32.000000000 +0000
@@ -37,9 +37,9 @@
 #define __arch_putb(v,a)		(*(volatile unsigned char *)(a) = (v))
 #define __arch_putl(v,a)		(*(volatile unsigned int  *)(a) = (v))
 
-extern void __raw_writesb(unsigned int addr, void *data, int bytelen);
-extern void __raw_writesw(unsigned int addr, void *data, int wordlen);
-extern void __raw_writesl(unsigned int addr, void *data, int longlen);
+extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);
+extern void __raw_writesw(unsigned int addr, const void *data, int wordlen);
+extern void __raw_writesl(unsigned int addr, const void *data, int longlen);
 
 extern void __raw_readsb(unsigned int addr, void *data, int bytelen);
 extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/leds.h linux/include/asm-arm/leds.h
--- linux.orig/include/asm-arm/leds.h	2000-09-18 22:15:23.000000000 +0000
+++ linux/include/asm-arm/leds.h	2002-07-20 01:08:32.000000000 +0000
@@ -23,12 +23,16 @@
 	led_stop,
 	led_claim,		/* override idle & timer leds */
 	led_release,		/* restore idle & timer leds */
+	led_start_timer_mode,
+	led_stop_timer_mode,
 	led_green_on,
 	led_green_off,
 	led_amber_on,
 	led_amber_off,
 	led_red_on,
 	led_red_off,
+	led_blue_on,
+	led_blue_off,
 	/*
 	 * I want this between led_timer and led_start, but
 	 * someone has decided to export this to user space
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/mach/amba_kmi.h linux/include/asm-arm/mach/amba_kmi.h
--- linux.orig/include/asm-arm/mach/amba_kmi.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/mach/amba_kmi.h	2002-07-20 01:08:37.000000000 +0000
@@ -24,10 +24,16 @@
 	u_char			type;
 	u_char			state;
 	u_char			prev_rx;
+
 	u_char			last_tx;
 	u_char			resend_count;
 	u_short			res;
+
 	u_char			present;
+	u_char			reconnect;
+	u_char			config_num;
+	u_char			hotplug_state;
+
 	wait_queue_head_t	wait_q;
 	void			(*rx)(struct kmi_info *, u_int val,
 				      struct pt_regs *regs);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/mach/serial_sa1100.h linux/include/asm-arm/mach/serial_sa1100.h
--- linux.orig/include/asm-arm/mach/serial_sa1100.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/mach/serial_sa1100.h	2002-07-20 01:08:33.000000000 +0000
@@ -18,9 +18,10 @@
  */
 struct sa1100_port_fns {
 	void	(*set_mctrl)(struct uart_port *, u_int);
-	int	(*get_mctrl)(struct uart_port *);
+	u_int	(*get_mctrl)(struct uart_port *);
 	void	(*enable_ms)(struct uart_port *);
 	void	(*pm)(struct uart_port *, u_int, u_int);
+	int	(*set_wake)(struct uart_port *, u_int);
 	int	(*open)(struct uart_port *, struct uart_info *);
 	void	(*close)(struct uart_port *, struct uart_info *);
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/mmu_context.h linux/include/asm-arm/mmu_context.h
--- linux.orig/include/asm-arm/mmu_context.h	2000-09-18 22:15:24.000000000 +0000
+++ linux/include/asm-arm/mmu_context.h	2002-07-20 01:08:35.000000000 +0000
@@ -42,11 +42,8 @@
 switch_mm(struct mm_struct *prev, struct mm_struct *next,
 	  struct task_struct *tsk, unsigned int cpu)
 {
-	if (prev != next) {
+	if (prev != next)
 		cpu_switch_mm(next->pgd, tsk);
-		clear_bit(cpu, &prev->cpu_vm_mask);
-	}
-	set_bit(cpu, &next->cpu_vm_mask);
 }
 
 #define activate_mm(prev, next) \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/page.h linux/include/asm-arm/page.h
--- linux.orig/include/asm-arm/page.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/page.h	2002-07-20 01:08:27.000000000 +0000
@@ -63,11 +63,21 @@
 
 #ifndef __ASSEMBLY__
 
+#ifdef CONFIG_DEBUG_BUGVERBOSE
 extern void __bug(const char *file, int line, void *data);
 
+/* give file/line information */
 #define BUG()		__bug(__FILE__, __LINE__, NULL)
 #define PAGE_BUG(page)	__bug(__FILE__, __LINE__, page)
 
+#else
+
+/* these just cause an oops */
+#define BUG()		(*(int *)0 = 0)
+#define PAGE_BUG(page)	(*(int *)0 = 0)
+
+#endif
+
 /* Pure 2^n version of get_order */
 static inline int get_order(unsigned long size)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/pgtable.h linux/include/asm-arm/pgtable.h
--- linux.orig/include/asm-arm/pgtable.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/pgtable.h	2002-07-20 01:08:29.000000000 +0000
@@ -98,7 +98,6 @@
 /*
  * Permanent address of a page. We never have highmem, so this is trivial.
  */
-#define page_address(page)	((page)->virtual)
 #define pages_to_mb(x)		((x) >> (20 - PAGE_SHIFT))
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/proc-armv/cache.h linux/include/asm-arm/proc-armv/cache.h
--- linux.orig/include/asm-arm/proc-armv/cache.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-arm/proc-armv/cache.h	2002-07-20 01:08:35.000000000 +0000
@@ -44,15 +44,17 @@
 
 #define flush_cache_range(_mm,_start,_end)				\
 	do {								\
-		if ((_mm) == current->mm)				\
-			cpu_cache_clean_invalidate_range((_start), (_end), 1); \
+		if ((_mm) == current->active_mm)			\
+			cpu_cache_clean_invalidate_range((_start) & PAGE_MASK, \
+							 PAGE_ALIGN(_end), 1); \
 	} while (0)
 
 #define flush_cache_page(_vma,_vmaddr)					\
 	do {								\
-		if ((_vma)->vm_mm == current->mm) {			\
-			cpu_cache_clean_invalidate_range((_vmaddr),	\
-				(_vmaddr) + PAGE_SIZE,			\
+		if ((_vma)->vm_mm == current->active_mm) {		\
+			unsigned long _addr = (_vmaddr) & PAGE_MASK;	\
+			cpu_cache_clean_invalidate_range(_addr,		\
+				_addr + PAGE_SIZE,			\
 				((_vma)->vm_flags & VM_EXEC));		\
 		} \
 	} while (0)
@@ -114,10 +116,11 @@
  * about to change to user space.  This is the same method as used on SPARC64.
  * See update_mmu_cache for the user space part.
  */
+#define mapping_mapped(map)	((map)->i_mmap || (map)->i_mmap_shared)
+
 static inline void flush_dcache_page(struct page *page)
 {
-	if (page->mapping && !(page->mapping->i_mmap) &&
-	     !(page->mapping->i_mmap_shared))
+	if (page->mapping && !mapping_mapped(page->mapping))
 		set_bit(PG_dcache_dirty, &page->flags);
 	else {
 		unsigned long virt = (unsigned long)page_address(page);
@@ -128,21 +131,6 @@
 #define clean_dcache_entry(_s)		cpu_dcache_clean_entry((unsigned long)(_s))
 
 /*
- * I cache coherency stuff.
- *
- * 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 generally means that we have to clean out the Dcache and write
- * buffers, and maybe flush the Icache in the specified range.
- */
-#define flush_icache_range(_s,_e)					\
-	do {								\
-		cpu_icache_invalidate_range((_s), (_e));		\
-	} while (0)
-
-/*
  * This function is misnamed IMHO.  There are three places where it
  * is called, each of which is preceded immediately by a call to
  * flush_page_to_ram:
@@ -169,13 +157,19 @@
 #define flush_icache_page(vma,pg)	do { } while (0)
 
 /*
- * Old ARM MEMC stuff.  This supports the reversed mapping handling that
- * we have on the older 26-bit machines.  We don't have a MEMC chip, so...
+ * I cache coherency stuff.
+ *
+ * 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 generally means that we have to clean out the Dcache and write
+ * buffers, and maybe flush the Icache in the specified range.
  */
-#define memc_update_all()		do { } while (0)
-#define memc_update_mm(mm)		do { } while (0)
-#define memc_update_addr(mm,pte,log)	do { } while (0)
-#define memc_clear(mm,physaddr)		do { } while (0)
+#define flush_icache_range(_s,_e)					\
+	do {								\
+		cpu_icache_invalidate_range((_s), (_e));		\
+	} while (0)
 
 /*
  * TLB flushing.
@@ -239,3 +233,13 @@
  * back to the page.
  */
 extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
+
+/*
+ * Old ARM MEMC stuff.  This supports the reversed mapping handling that
+ * we have on the older 26-bit machines.  We don't have a MEMC chip, so...
+ */
+#define memc_update_all()		do { } while (0)
+#define memc_update_mm(mm)		do { } while (0)
+#define memc_update_addr(mm,pte,log)	do { } while (0)
+#define memc_clear(mm,physaddr)		do { } while (0)
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/proc-fns.h linux/include/asm-arm/proc-fns.h
--- linux.orig/include/asm-arm/proc-fns.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-arm/proc-fns.h	2002-07-20 01:08:37.000000000 +0000
@@ -60,6 +60,14 @@
 #   define CPU_NAME arm920
 #  endif
 # endif
+# ifdef CONFIG_CPU_ARM922T
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm922
+#  endif
+# endif
 # ifdef CONFIG_CPU_ARM926T
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/processor.h linux/include/asm-arm/processor.h
--- linux.orig/include/asm-arm/processor.h	2001-10-11 16:04:57.000000000 +0000
+++ linux/include/asm-arm/processor.h	2002-07-20 01:08:36.000000000 +0000
@@ -68,13 +68,6 @@
 	EXTRA_THREAD_STRUCT
 };
 
-#define INIT_MMAP {					\
-	vm_mm:		&init_mm,			\
-	vm_page_prot:	PAGE_SHARED,			\
-	vm_flags:	VM_READ | VM_WRITE | VM_EXEC,	\
-	vm_avl_height:	1,				\
-}
-
 #define INIT_THREAD  {					\
 	refcount:	ATOMIC_INIT(1),			\
 	EXTRA_THREAD_STRUCT_INIT			\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/scatterlist.h linux/include/asm-arm/scatterlist.h
--- linux.orig/include/asm-arm/scatterlist.h	2001-10-12 22:35:54.000000000 +0000
+++ linux/include/asm-arm/scatterlist.h	2002-07-20 01:08:34.000000000 +0000
@@ -5,6 +5,7 @@
 
 struct scatterlist {
 	char		*address;	/* virtual address		 */
+	struct page	*page;		/* Location for highmem page, if any */
 	dma_addr_t	dma_address;	/* dma address			 */
 	unsigned int	length;		/* length			 */
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/siginfo.h linux/include/asm-arm/siginfo.h
--- linux.orig/include/asm-arm/siginfo.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/siginfo.h	2002-07-20 01:08:21.000000000 +0000
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL        -6              /* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/unistd.h linux/include/asm-arm/unistd.h
--- linux.orig/include/asm-arm/unistd.h	2001-08-12 18:14:00.000000000 +0000
+++ linux/include/asm-arm/unistd.h	2002-07-20 01:08:33.000000000 +0000
@@ -240,6 +240,29 @@
 #define __NR_mincore			(__NR_SYSCALL_BASE+219)
 #define __NR_madvise			(__NR_SYSCALL_BASE+220)
 #define __NR_fcntl64			(__NR_SYSCALL_BASE+221)
+					/* 222 for tux */
+#define __NR_security			(__NR_SYSCALL_BASE+223)
+#define __NR_gettid			(__NR_SYSCALL_BASE+224)
+#define __NR_readahead			(__NR_SYSCALL_BASE+225)
+#if 0 /* allocated in 2.5 */
+#define __NR_setxattr			(__NR_SYSCALL_BASE+226)
+#define __NR_lsetxattr			(__NR_SYSCALL_BASE+227)
+#define __NR_fsetxattr			(__NR_SYSCALL_BASE+228)
+#define __NR_getxattr			(__NR_SYSCALL_BASE+229)
+#define __NR_lgetxattr			(__NR_SYSCALL_BASE+230)
+#define __NR_fgetxattr			(__NR_SYSCALL_BASE+231)
+#define __NR_listxattr			(__NR_SYSCALL_BASE+232)
+#define __NR_llistxattr			(__NR_SYSCALL_BASE+233)
+#define __NR_flistxattr			(__NR_SYSCALL_BASE+234)
+#define __NR_removexattr		(__NR_SYSCALL_BASE+235)
+#define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
+#define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
+#endif
+#define __NR_tkill			(__NR_SYSCALL_BASE+238)
+/*
+ * Please check 2.5 _before_ adding calls here,
+ * and copy changes to rmk@arm.linux.org.uk.  Thanks.
+ */
 
 /*
  * The following SWIs are ARM private.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-arm/vt.h linux/include/asm-arm/vt.h
--- linux.orig/include/asm-arm/vt.h	1998-01-21 00:39:43.000000000 +0000
+++ linux/include/asm-arm/vt.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-#ifndef _ASMARM_VT_H
-#define _ASMARM_VT_H
-
-#define VT_GETSCRINFO	0x56FD	/* get screen info */
-#define VT_GETPALETTE	0x56FE  /* get palette */
-#define VT_SETPALETTE	0x56FF  /* set palette */
-
-#endif /* _ASMARM_VT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/etraxgpio.h linux/include/asm-cris/etraxgpio.h
--- linux.orig/include/asm-cris/etraxgpio.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-cris/etraxgpio.h	2002-07-20 01:08:34.000000000 +0000
@@ -1,9 +1,27 @@
+/* $Id: etraxgpio.h,v 1.7 2002/04/10 11:55:50 johana Exp $ */
+/*
+ * The following devices are accessable using this driver using
+ * GPIO_MAJOR (120) and a couple of minor numbers:
+ * /dev/gpioa  minor 0, 8 bit GPIO, each bit can change direction
+ * /dev/gpiob  minor 1, 8 bit GPIO, each bit can change direction
+ * /dev/leds   minor 2, Access to leds depending on kernelconfig
+ * /dev/gpiog  minor 3
+         g0dir, g8_15dir, g16_23dir, g24 dir configurable in R_GEN_CONFIG
+         g1-g7 and g25-g31 is both input and outputs but on different pins
+         Also note that some bits change pins depending on what interfaces 
+         are enabled.
+ */
 #ifndef _ASM_ETRAXGPIO_H
 #define _ASM_ETRAXGPIO_H
 
 /* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */
 
 #define ETRAXGPIO_IOCTYPE 43
+#define GPIO_MINOR_A 0
+#define GPIO_MINOR_B 1
+#define GPIO_MINOR_LEDS 2
+#define GPIO_MINOR_G 3
+#define GPIO_MINOR_LAST 3
 
 /* supported ioctl _IOC_NR's */
 
@@ -23,10 +41,10 @@
 
 /* GPIO direction ioctl's */
 #define IO_READDIR    0x8  /* Read direction 0=input 1=output */
-#define IO_SETINPUT   0x9  /* Set direction 0=unchanged 1=input, 
-                              returns current dir */
-#define IO_SETOUTPUT  0xA  /* Set direction 0=unchanged 1=output,
-                              returns current dir */
+#define IO_SETINPUT   0x9  /* Set direction for bits set, 0=unchanged 1=input, 
+                              returns mask with current inputs */
+#define IO_SETOUTPUT  0xA  /* Set direction for bits set, 0=unchanged 1=output,
+                              returns mask with current outputs */
 
 /* LED ioctl extended */
 #define IO_LED_SETBIT 0xB
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/ide.h linux/include/asm-cris/ide.h
--- linux.orig/include/asm-cris/ide.h	2001-02-13 22:13:44.000000000 +0000
+++ linux/include/asm-cris/ide.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  linux/include/asm-cris/ide.h
  *
- *  Copyright (C) 2000  Axis Communications AB
+ *  Copyright (C) 2000, 2001, 2002  Axis Communications AB
  *
  *  Authors:    Bjorn Wesen
  *
@@ -97,7 +97,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all                    : 8;    /* all of the bits together */
+	struct {
+		unsigned bit0           : 1;
+		unsigned nIEN           : 1;    /* device INTRQ to host */
+		unsigned SRST           : 1;    /* host soft reset bit */
+		unsigned bit3           : 1;    /* ATA-2 thingy */
+		unsigned reserved456    : 3;
+		unsigned HOB            : 1;    /* 48-bit address ordering */
+	} b;
+} control_t;
 
 /* some configuration options we don't need */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/ioctls.h linux/include/asm-cris/ioctls.h
--- linux.orig/include/asm-cris/ioctls.h	2001-02-09 00:32:44.000000000 +0000
+++ linux/include/asm-cris/ioctls.h	2002-07-20 01:08:24.000000000 +0000
@@ -70,6 +70,11 @@
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
 
+#define TIOCSERSETRS485 0x5460  /* enable rs-485 */
+#define TIOCSERWRRS485  0x5461  /* write rs-485 */
+
+
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/page.h linux/include/asm-cris/page.h
--- linux.orig/include/asm-cris/page.h	2001-02-13 22:13:44.000000000 +0000
+++ linux/include/asm-cris/page.h	2002-07-20 01:08:31.000000000 +0000
@@ -112,6 +112,9 @@
 
 extern unsigned long dram_start, dram_end;
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 
 #endif /* _CRIS_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/pgtable.h linux/include/asm-cris/pgtable.h
--- linux.orig/include/asm-cris/pgtable.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-cris/pgtable.h	2002-07-20 01:08:22.000000000 +0000
@@ -3,6 +3,9 @@
  * HISTORY:
  *
  * $Log: pgtable.h,v $
+ * Revision 1.15  2002/04/23 15:37:52  bjornw
+ * Removed page_address and added flush_icache_user_range
+ *
  * Revision 1.14  2001/12/10 03:08:50  bjornw
  * Added pgtable_cache_init dummy
  *
@@ -125,6 +128,7 @@
 #define flush_dcache_page(page)                 do { } while (0)
 #define flush_icache_range(start, end)          do { } while (0)
 #define flush_icache_page(vma,pg)               do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 /*
  * TLB flushing (implemented in arch/cris/mm/tlb.c):
@@ -438,7 +442,6 @@
 
 /* permanent address of a page */
 
-#define page_address(page)      ((page)->virtual)
 #define __page_address(page)    (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
 #define pte_page(pte)           (mem_map+pte_pagenr(pte))
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/processor.h linux/include/asm-cris/processor.h
--- linux.orig/include/asm-cris/processor.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-cris/processor.h	2002-07-20 01:08:36.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * include/asm-cris/processor.h
  *
- * Copyright (C) 2000, 2001 Axis Communications AB
+ * Copyright (C) 2000, 2001, 2002 Axis Communications AB
  *
  * Authors:         Bjorn Wesen        Initial version
  *
@@ -33,7 +33,7 @@
 #ifdef CONFIG_CRIS_LOW_MAP
 #define TASK_SIZE       (0x50000000UL)   /* 1.25 GB */
 #else
-#define TASK_SIZE       (0xB0000000UL)   /* 2.75 GB */
+#define TASK_SIZE       (0xA0000000UL)   /* 2.56 GB */
 #endif
 
 /* This decides where the kernel will search for a free chunk of vm
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/rs485.h linux/include/asm-cris/rs485.h
--- linux.orig/include/asm-cris/rs485.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-cris/rs485.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,20 @@
+/* RS-485 structures */
+
+/* RS-485 support */
+/* Used with ioctl() TIOCSERSETRS485 */
+struct rs485_control {
+        unsigned short rts_on_send;
+        unsigned short rts_after_sent;
+        __u32 delay_rts_before_send;
+        unsigned short enabled;
+#ifdef __KERNEL__
+        int disable_serial_loopback;
+#endif
+};
+
+/* Used with ioctl() TIOCSERWRRS485 */
+struct rs485_write {
+        __u16 outc_size;
+        unsigned char *outc;
+};
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/siginfo.h linux/include/asm-cris/siginfo.h
--- linux.orig/include/asm-cris/siginfo.h	2001-02-09 00:32:44.000000000 +0000
+++ linux/include/asm-cris/siginfo.h	2002-07-20 01:08:22.000000000 +0000
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/sv_addr.agh linux/include/asm-cris/sv_addr.agh
--- linux.orig/include/asm-cris/sv_addr.agh	2001-04-06 17:51:19.000000000 +0000
+++ linux/include/asm-cris/sv_addr.agh	2002-07-20 01:08:34.000000000 +0000
@@ -691,10 +691,10 @@
 #define R_GEN_CONFIG__g24dir__WIDTH 1
 #define R_GEN_CONFIG__g24dir__in 0
 #define R_GEN_CONFIG__g24dir__out 1
-#define R_GEN_CONFIG__g16_20dir__BITNR 26
-#define R_GEN_CONFIG__g16_20dir__WIDTH 1
-#define R_GEN_CONFIG__g16_20dir__in 0
-#define R_GEN_CONFIG__g16_20dir__out 1
+#define R_GEN_CONFIG__g16_23dir__BITNR 26
+#define R_GEN_CONFIG__g16_23dir__WIDTH 1
+#define R_GEN_CONFIG__g16_23dir__in 0
+#define R_GEN_CONFIG__g16_23dir__out 1
 #define R_GEN_CONFIG__g8_15dir__BITNR 25
 #define R_GEN_CONFIG__g8_15dir__WIDTH 1
 #define R_GEN_CONFIG__g8_15dir__in 0
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/svinto.h linux/include/asm-cris/svinto.h
--- linux.orig/include/asm-cris/svinto.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-cris/svinto.h	2002-07-20 01:08:40.000000000 +0000
@@ -58,4 +58,7 @@
  */
 #define WAIT_DMA( n ) WAIT_DMA_NUM( n )
 
+extern void prepare_rx_descriptor(struct etrax_dma_descr *desc);
+extern void flush_etrax_cache(void);
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/system.h linux/include/asm-cris/system.h
--- linux.orig/include/asm-cris/system.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-cris/system.h	2002-07-20 01:08:22.000000000 +0000
@@ -62,8 +62,8 @@
 #define save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
 #define restore_flags(x) __asm__ __volatile__ ("move %0,$ccr\n\tbtstq 5,%0\n\tbpl 1f\n\tnop\n\tpush $r0\n\tmoveq 0,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0\n1:\n" : : "r" (x) : "memory");
 #else
-#define __cli() __asm__ __volatile__ ( "di");
-#define __sti() __asm__ __volatile__ ( "ei" );
+#define __cli() __asm__ __volatile__ ( "di" : : :"memory");
+#define __sti() __asm__ __volatile__ ( "ei" : : :"memory");
 #define __save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
 #define __restore_flags(x) __asm__ __volatile__ ("move %0,$ccr" : : "rm" (x) : "memory");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/termios.h linux/include/asm-cris/termios.h
--- linux.orig/include/asm-cris/termios.h	2001-04-06 17:51:19.000000000 +0000
+++ linux/include/asm-cris/termios.h	2002-07-20 01:08:26.000000000 +0000
@@ -3,6 +3,7 @@
 
 #include <asm/termbits.h>
 #include <asm/ioctls.h>
+#include <asm/rs485.h>
 
 struct winsize {
 	unsigned short ws_row;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/timex.h linux/include/asm-cris/timex.h
--- linux.orig/include/asm-cris/timex.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-cris/timex.h	2002-07-20 01:08:31.000000000 +0000
@@ -2,25 +2,34 @@
  * linux/include/asm-cris/timex.h
  *
  * CRIS architecture timex specifications
+ * 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.
  */
 #ifndef _ASM_CRIS_TIMEX_H
 #define _ASM_CRIS_TIMEX_H
 
-#define CLOCK_TICK_RATE 19200 /* Underlying frequency of the HZ timer */
-
-/* The timer0 values gives ~52.1us resolution (1/19200) but interrupts at HZ*/
+/* The prescaler clock runs at 25MHz, we divide it by 1000 in the prescaler */
+/* If you change anything here you must check time.c as well... */
+#define PRESCALE_FREQ 25000000
+#define PRESCALE_VALUE 1000
+#define CLOCK_TICK_RATE 25000 /* Underlying frequency of the HZ timer */
+/* The timer0 values gives 40us resolution (1/25000) but interrupts at HZ*/
 #define TIMER0_FREQ (CLOCK_TICK_RATE)
-#define TIMER0_CLKSEL c19k2Hz
+#define TIMER0_CLKSEL flexible
 #define TIMER0_DIV (TIMER0_FREQ/(HZ))
-/* This is the slow one: */
-/*
+
+
 #define GET_JIFFIES_USEC() \
-  ( (*R_TIMER0_DATA - TIMER0_DIV) * (1000000/HZ)/TIMER0_DIV )
-*/
-/* This is the fast version: */
-extern unsigned short cris_timer0_value_us[TIMER0_DIV+1]; /* in kernel/time.c */
-#define GET_JIFFIES_USEC() (cris_timer0_value_us[*R_TIMER0_DATA])
+  ( (TIMER0_DIV - *R_TIMER0_DATA) * (1000000/HZ)/TIMER0_DIV )
 
+unsigned long get_ns_in_jiffie(void);
+
+static inline unsigned long get_us_in_jiffie_highres(void)
+{
+	return get_ns_in_jiffie()/1000;
+}
 /*
  * We don't have a cycle-counter.. but we do not support SMP anyway where this is
  * used so it does not matter.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-cris/unistd.h linux/include/asm-cris/unistd.h
--- linux.orig/include/asm-cris/unistd.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-cris/unistd.h	2002-07-20 01:08:33.000000000 +0000
@@ -230,6 +230,7 @@
 #define __NR_security           223     /* syscall for security modules */
 #define __NR_gettid             224
 #define __NR_readahead          225
+#define __NR_tkill              226
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-generic/tlb.h linux/include/asm-generic/tlb.h
--- linux.orig/include/asm-generic/tlb.h	2001-09-14 15:41:04.000000000 +0000
+++ linux/include/asm-generic/tlb.h	2002-07-20 01:08:21.000000000 +0000
@@ -55,8 +55,9 @@
 #define tlb_remove_page(ctxp, pte, addr) do {\
 		/* Handle the common case fast, first. */\
 		if ((ctxp)->nr == ~0UL) {\
-			__free_pte(*(pte));\
-			pte_clear((pte));\
+			pte_t __pte = *(pte);\
+			pte_clear(pte);\
+			__free_pte(__pte);\
 			break;\
 		}\
 		if (!(ctxp)->nr) \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/apic.h linux/include/asm-i386/apic.h
--- linux.orig/include/asm-i386/apic.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/asm-i386/apic.h	2002-07-20 01:08:35.000000000 +0000
@@ -79,6 +79,8 @@
 extern void setup_apic_nmi_watchdog (void);
 extern inline void nmi_watchdog_tick (struct pt_regs * regs);
 extern int APIC_init_uniprocessor (void);
+extern void disable_APIC_timer(void);
+extern void enable_APIC_timer(void);
 
 extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback);
 extern void apic_pm_unregister(struct pm_dev*);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/checksum.h linux/include/asm-i386/checksum.h
--- linux.orig/include/asm-i386/checksum.h	2001-07-26 20:41:22.000000000 +0000
+++ linux/include/asm-i386/checksum.h	2002-07-20 01:08:39.000000000 +0000
@@ -29,9 +29,9 @@
 
 /*
  *	Note: when you get a NULL pointer exception here this means someone
- *	passed in an incorrect kernel address to one of these functions. 
- *	
- *	If you use these functions directly please don't forget the 
+ *	passed in an incorrect kernel address to one of these functions.
+ *
+ *	If you use these functions directly please don't forget the
  *	verify_area().
  */
 static __inline__
@@ -66,28 +66,28 @@
  *	Arnt Gulbrandsen.
  */
 static inline unsigned short ip_fast_csum(unsigned char * iph,
-					  unsigned int ihl) {
+					  unsigned int ihl)
+{
 	unsigned int sum;
 
-	__asm__ __volatile__("
-	    movl (%1), %0
-	    subl $4, %2
-	    jbe 2f
-	    addl 4(%1), %0
-	    adcl 8(%1), %0
-	    adcl 12(%1), %0
-1:	    adcl 16(%1), %0
-	    lea 4(%1), %1
-	    decl %2
-	    jne	1b
-	    adcl $0, %0
-	    movl %0, %2
-	    shrl $16, %0
-	    addw %w2, %w0
-	    adcl $0, %0
-	    notl %0
-2:
-	    "
+	__asm__ __volatile__(
+	    "movl (%1), %0	;\n"
+	    "subl $4, %2	;\n"
+	    "jbe 2f		;\n"
+	    "addl 4(%1), %0	;\n"
+	    "adcl 8(%1), %0	;\n"
+	    "adcl 12(%1), %0	;\n"
+"1:	    adcl 16(%1), %0	;\n"
+	    "lea 4(%1), %1	;\n"
+	    "decl %2		;\n"
+	    "jne 1b		;\n"
+	    "adcl $0, %0	;\n"
+	    "movl %0, %2	;\n"
+	    "shrl $16, %0	;\n"
+	    "addw %w2, %w0	;\n"
+	    "adcl $0, %0	;\n"
+	    "notl %0		;\n"
+"2:				;\n"
 	/* Since the input registers which are loaded with iph and ipl
 	   are modified, we must also specify them as outputs, or gcc
 	   will assume they contain their original values. */
@@ -102,28 +102,26 @@
 
 static inline unsigned int csum_fold(unsigned int sum)
 {
-	__asm__("
-		addl %1, %0
-		adcl $0xffff, %0
-		"
+	__asm__(
+		"addl %1, %0		;\n"
+		"adcl $0xffff, %0	;\n"
 		: "=r" (sum)
 		: "r" (sum << 16), "0" (sum & 0xffff0000)
 	);
 	return (~sum) >> 16;
 }
- 
+
 static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
 						   unsigned long daddr,
 						   unsigned short len,
 						   unsigned short proto,
-						   unsigned int sum) 
+						   unsigned int sum)
 {
-    __asm__("
-	addl %1, %0
-	adcl %2, %0
-	adcl %3, %0
-	adcl $0, %0
-	"
+    __asm__(
+	"addl %1, %0	;\n"
+	"adcl %2, %0	;\n"
+	"adcl %3, %0	;\n"
+	"adcl $0, %0	;\n"
 	: "=r" (sum)
 	: "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
     return sum;
@@ -137,7 +135,7 @@
 						   unsigned long daddr,
 						   unsigned short len,
 						   unsigned short proto,
-						   unsigned int sum) 
+						   unsigned int sum)
 {
 	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
 }
@@ -147,7 +145,8 @@
  * in icmp.c
  */
 
-static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
     return csum_fold (csum_partial(buff, len, 0));
 }
 
@@ -156,33 +155,32 @@
 						     struct in6_addr *daddr,
 						     __u32 len,
 						     unsigned short proto,
-						     unsigned int sum) 
+						     unsigned int sum)
 {
-	__asm__("
-		addl 0(%1), %0
-		adcl 4(%1), %0
-		adcl 8(%1), %0
-		adcl 12(%1), %0
-		adcl 0(%2), %0
-		adcl 4(%2), %0
-		adcl 8(%2), %0
-		adcl 12(%2), %0
-		adcl %3, %0
-		adcl %4, %0
-		adcl $0, %0
-		"
+	__asm__(
+		"addl 0(%1), %0		;\n"
+		"adcl 4(%1), %0		;\n"
+		"adcl 8(%1), %0		;\n"
+		"adcl 12(%1), %0	;\n"
+		"adcl 0(%2), %0		;\n"
+		"adcl 4(%2), %0		;\n"
+		"adcl 8(%2), %0		;\n"
+		"adcl 12(%2), %0	;\n"
+		"adcl %3, %0		;\n"
+		"adcl %4, %0		;\n"
+		"adcl $0, %0		;\n"
 		: "=&r" (sum)
-		: "r" (saddr), "r" (daddr), 
+		: "r" (saddr), "r" (daddr),
 		  "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
 
 	return csum_fold(sum);
 }
 
-/* 
+/*
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
+static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
 				    int len, int sum, int *err_ptr)
 {
 	if (access_ok(VERIFY_WRITE, dst, len))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/errno.h linux/include/asm-i386/errno.h
--- linux.orig/include/asm-i386/errno.h	2001-02-09 19:40:02.000000000 +0000
+++ linux/include/asm-i386/errno.h	2002-07-20 01:08:34.000000000 +0000
@@ -7,7 +7,7 @@
 #define	EINTR		 4	/* Interrupted system call */
 #define	EIO		 5	/* I/O error */
 #define	ENXIO		 6	/* No such device or address */
-#define	E2BIG		 7	/* Arg list too long */
+#define	E2BIG		 7	/* Argument list too long */
 #define	ENOEXEC		 8	/* Exec format error */
 #define	EBADF		 9	/* Bad file number */
 #define	ECHILD		10	/* No child processes */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/fixmap.h linux/include/asm-i386/fixmap.h
--- linux.orig/include/asm-i386/fixmap.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/asm-i386/fixmap.h	2002-07-20 01:08:24.000000000 +0000
@@ -65,6 +65,11 @@
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
 #endif
+	__end_of_permanent_fixed_addresses,
+	/* temporary boot-time mappings, used before ioremap() is functional */
+#define NR_FIX_BTMAPS	16
+	FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
+	FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
 	__end_of_fixed_addresses
 };
 
@@ -86,8 +91,8 @@
  * at the top of mem..
  */
 #define FIXADDR_TOP	(0xffffe000UL)
-#define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
-#define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
+#define __FIXADDR_SIZE	(__end_of_permanent_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START	(FIXADDR_TOP - __FIXADDR_SIZE)
 
 #define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/floppy.h linux/include/asm-i386/floppy.h
--- linux.orig/include/asm-i386/floppy.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/asm-i386/floppy.h	2002-07-20 01:08:28.000000000 +0000
@@ -75,28 +75,28 @@
 
 #ifndef NO_FLOPPY_ASSEMBLER
 	__asm__ (
-       "testl %1,%1
-	je 3f
-1:	inb %w4,%b0
-	andb $160,%b0
-	cmpb $160,%b0
-	jne 2f
-	incw %w4
-	testl %3,%3
-	jne 4f
-	inb %w4,%b0
-	movb %0,(%2)
-	jmp 5f
-4:     	movb (%2),%0
-	outb %b0,%w4
-5:	decw %w4
-	outb %0,$0x80
-	decl %1
-	incl %2
-	testl %1,%1
-	jne 1b
-3:	inb %w4,%b0
-2:	"
+       "testl %1,%1"
+	"je 3f"
+"1:	inb %w4,%b0"
+	"andb $160,%b0"
+	"cmpb $160,%b0"
+	"jne 2f"
+	"incw %w4"
+	"testl %3,%3"
+	"jne 4f"
+	"inb %w4,%b0"
+	"movb %0,(%2)"
+	"jmp 5f"
+"4:    	movb (%2),%0"
+	"outb %b0,%w4"
+"5:	decw %w4"
+	"outb %0,$0x80"
+	"decl %1"
+	"incl %2"
+	"testl %1,%1"
+	"jne 1b"
+"3:	inb %w4,%b0"
+"2:	"
        : "=a" ((char) st), 
        "=c" ((long) virtual_dma_count), 
        "=S" ((long) virtual_dma_addr)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/highmem.h linux/include/asm-i386/highmem.h
--- linux.orig/include/asm-i386/highmem.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/asm-i386/highmem.h	2002-07-20 01:08:25.000000000 +0000
@@ -62,7 +62,7 @@
 static inline void *kmap(struct page *page)
 {
 	if (in_interrupt())
-		BUG();
+		out_of_line_bug();
 	if (page < highmem_start_page)
 		return page_address(page);
 	return kmap_high(page);
@@ -71,7 +71,7 @@
 static inline void kunmap(struct page *page)
 {
 	if (in_interrupt())
-		BUG();
+		out_of_line_bug();
 	if (page < highmem_start_page)
 		return;
 	kunmap_high(page);
@@ -95,7 +95,7 @@
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #if HIGHMEM_DEBUG
 	if (!pte_none(*(kmap_pte-idx)))
-		BUG();
+		out_of_line_bug();
 #endif
 	set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
 	__flush_tlb_one(vaddr);
@@ -113,7 +113,7 @@
 		return;
 
 	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
-		BUG();
+		out_of_line_bug();
 
 	/*
 	 * force other mappings to Oops if they'll try to access
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/ide.h linux/include/asm-i386/ide.h
--- linux.orig/include/asm-i386/ide.h	2001-11-22 19:46:58.000000000 +0000
+++ linux/include/asm-i386/ide.h	2002-07-20 01:08:25.000000000 +0000
@@ -95,7 +95,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+	} b;
+} control_t;
 
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
 #define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/io.h linux/include/asm-i386/io.h
--- linux.orig/include/asm-i386/io.h	2001-11-22 19:46:27.000000000 +0000
+++ linux/include/asm-i386/io.h	2002-07-20 01:08:36.000000000 +0000
@@ -39,7 +39,8 @@
 #define IO_SPACE_LIMIT 0xffff
 
 #define XQUAD_PORTIO_BASE 0xfe400000
-#define XQUAD_PORTIO_LEN  0x40000   /* 256k per quad. Only remapping 1st */
+#define XQUAD_PORTIO_QUAD 0x40000  /* 256k per quad. */
+#define XQUAD_PORTIO_LEN  0x80000  /* Only remapping first 2 quads */
 
 #ifdef __KERNEL__
 
@@ -59,15 +60,37 @@
 //#define __io_phys(x) __pa(x)
 #endif
 
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are pretty trivial
+/**
+ *	virt_to_phys	-	map virtual addresses to physical
+ *	@address: address to remap
+ *
+ *	The returned physical address is the physical (CPU) mapping for
+ *	the memory address given. It is only valid to use this function on
+ *	addresses directly mapped or allocated via kmalloc. 
+ *
+ *	This function does not give bus mappings for DMA transfers. In
+ *	almost all conceivable cases a device driver should not be using
+ *	this function
  */
+ 
 static inline unsigned long virt_to_phys(volatile void * address)
 {
 	return __pa(address);
 }
 
+/**
+ *	phys_to_virt	-	map physical address to virtual
+ *	@address: address to remap
+ *
+ *	The returned virtual address is a current CPU mapping for
+ *	the memory address given. It is only valid to use this function on
+ *	addresses that have a kernel mapping
+ *
+ *	This function does not handle bus mappings for DMA transfers. In
+ *	almost all conceivable cases a device driver should not be using
+ *	this function
+ */
+
 static inline void * phys_to_virt(unsigned long address)
 {
 	return __va(address);
@@ -76,20 +99,51 @@
 /*
  * Change "struct page" to physical address.
  */
+#ifdef CONFIG_HIGHMEM64G
+#define page_to_phys(page)	((u64)(page - mem_map) << PAGE_SHIFT)
+#else
 #define page_to_phys(page)	((page - mem_map) << PAGE_SHIFT)
+#endif
 
 extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 
+/**
+ *	ioremap		-	map bus memory into CPU space
+ *	@offset:	bus address of the memory
+ *	@size:		size of the resource to map
+ *
+ *	ioremap performs a platform specific sequence of operations to
+ *	make bus memory CPU accessible via the readb/readw/readl/writeb/
+ *	writew/writel functions and the other mmio helpers. The returned
+ *	address is not guaranteed to be usable directly as a virtual
+ *	address. 
+ */
+ 
 static inline void * ioremap (unsigned long offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
 
-/*
- * This one maps high address device memory and turns off caching for that area.
- * it's useful if some control registers are in such an area and write combining
- * or read caching is not desirable:
+/**
+ *	ioremap_nocache		-	map bus memory into CPU space
+ *	@offset:	bus address of the memory
+ *	@size:		size of the resource to map
+ *
+ *	ioremap_nocache performs a platform specific sequence of operations to
+ *	make bus memory CPU accessible via the readb/readw/readl/writeb/
+ *	writew/writel functions and the other mmio helpers. The returned
+ *	address is not guaranteed to be usable directly as a virtual
+ *	address. 
+ *
+ *	This version of ioremap ensures that the memory is marked uncachable
+ *	on the CPU as well as honouring existing caching rules from things like
+ *	the PCI bus. Note that there are other caches and buffers on many 
+ *	busses. In paticular driver authors should read up on PCI writes
+ *
+ *	It's useful if some control registers are in such an area and
+ *	write combining or read caching is not desirable:
  */
+ 
 static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
 {
         return __ioremap(offset, size, _PAGE_PCD);
@@ -98,6 +152,14 @@
 extern void iounmap(void *addr);
 
 /*
+ * bt_ioremap() and bt_iounmap() are for temporary early boot-time
+ * mappings, before the real ioremap() is functional.
+ * A boot-time mapping is currently limited to at most 16 pages.
+ */
+extern void *bt_ioremap(unsigned long offset, unsigned long size);
+extern void bt_iounmap(void *addr, unsigned long size);
+
+/*
  * IO bus memory addresses are also 1:1 with the physical address
  */
 #define virt_to_bus virt_to_phys
@@ -157,6 +219,17 @@
 #define eth_io_copy_and_sum(a,b,c,d)		eth_copy_and_sum((a),__io_virt(b),(c),(d))
 #define isa_eth_io_copy_and_sum(a,b,c,d)	eth_copy_and_sum((a),__io_virt(__ISA_IO_base + (b)),(c),(d))
 
+/**
+ *	check_signature		-	find BIOS signatures
+ *	@io_addr: mmio address to check 
+ *	@signature:  signature block
+ *	@length: length of signature
+ *
+ *	Perform a signature comparison with the mmio address io_addr. This
+ *	address should have been obtained by ioremap.
+ *	Returns 1 on a match.
+ */
+ 
 static inline int check_signature(unsigned long io_addr,
 	const unsigned char *signature, int length)
 {
@@ -173,6 +246,20 @@
 	return retval;
 }
 
+/**
+ *	isa_check_signature		-	find BIOS signatures
+ *	@io_addr: mmio address to check 
+ *	@signature:  signature block
+ *	@length: length of signature
+ *
+ *	Perform a signature comparison with the ISA mmio address io_addr.
+ *	Returns 1 on a match.
+ *
+ *	This function is deprecated. New drivers should use ioremap and
+ *	check_signature.
+ */
+ 
+
 static inline int isa_check_signature(unsigned long io_addr,
 	const unsigned char *signature, int length)
 {
@@ -247,52 +334,65 @@
 __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
 
 #ifdef CONFIG_MULTIQUAD
-/* Make the default portio routines operate on quad 0 for now */
-#define __OUT(s,s1,x) \
-__OUT1(s##_local,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
-__OUT1(s##_p_local,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
-__OUTQ0(s,s,x) \
-__OUTQ0(s,s##_p,x) 
-#else
-#define __OUT(s,s1,x) \
-__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
-__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} 
-#endif /* CONFIG_MULTIQUAD */
-
-#ifdef CONFIG_MULTIQUAD
-#define __OUTQ0(s,ss,x)    /* Do the equivalent of the portio op on quad 0 */ \
+#define __OUTQ(s,ss,x)    /* Do the equivalent of the portio op on quads */ \
 static inline void out##ss(unsigned x value, unsigned short port) { \
 	if (xquad_portio) \
 		write##s(value, (unsigned long) xquad_portio + port); \
 	else               /* We're still in early boot, running on quad 0 */ \
 		out##ss##_local(value, port); \
-} 
+} \
+static inline void out##ss##_quad(unsigned x value, unsigned short port, int quad) { \
+	if (xquad_portio) \
+		write##s(value, (unsigned long) xquad_portio + (XQUAD_PORTIO_QUAD*quad)\
+			+ port); \
+}
 
-#define __INQ0(s,ss)       /* Do the equivalent of the portio op on quad 0 */ \
+#define __INQ(s,ss)       /* Do the equivalent of the portio op on quads */ \
 static inline RETURN_TYPE in##ss(unsigned short port) { \
 	if (xquad_portio) \
 		return read##s((unsigned long) xquad_portio + port); \
 	else               /* We're still in early boot, running on quad 0 */ \
 		return in##ss##_local(port); \
+} \
+static inline RETURN_TYPE in##ss##_quad(unsigned short port, int quad) { \
+	if (xquad_portio) \
+		return read##s((unsigned long) xquad_portio + (XQUAD_PORTIO_QUAD*quad)\
+			+ port); \
+	else\
+		return 0;\
 }
 #endif /* CONFIG_MULTIQUAD */
 
+#ifndef CONFIG_MULTIQUAD
+#define __OUT(s,s1,x) \
+__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
+__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} 
+#else
+/* Make the default portio routines operate on quad 0 */
+#define __OUT(s,s1,x) \
+__OUT1(s##_local,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
+__OUT1(s##_p_local,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
+__OUTQ(s,s,x) \
+__OUTQ(s,s##_p,x) 
+#endif /* CONFIG_MULTIQUAD */
+
 #define __IN1(s) \
 static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
 
 #define __IN2(s,s1,s2) \
 __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
 
-#ifdef CONFIG_MULTIQUAD
-#define __IN(s,s1,i...) \
-__IN1(s##_local) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-__IN1(s##_p_local) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-__INQ0(s,s) \
-__INQ0(s,s##_p) 
-#else
+#ifndef CONFIG_MULTIQUAD
 #define __IN(s,s1,i...) \
 __IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
 __IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } 
+#else
+/* Make the default portio routines operate on quad 0 */
+#define __IN(s,s1,i...) \
+__IN1(s##_local) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+__IN1(s##_p_local) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+__INQ(s,s) \
+__INQ(s,s##_p) 
 #endif /* CONFIG_MULTIQUAD */
 
 #define __INS(s) \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/ioctls.h linux/include/asm-i386/ioctls.h
--- linux.orig/include/asm-i386/ioctls.h	1998-07-24 18:10:16.000000000 +0000
+++ linux/include/asm-i386/ioctls.h	2002-07-20 01:08:25.000000000 +0000
@@ -6,7 +6,7 @@
 /* 0x54 is just a magic number to make these relatively unique ('T') */
 
 #define TCGETS		0x5401
-#define TCSETS		0x5402
+#define TCSETS		0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
 #define TCSETSW		0x5403
 #define TCSETSF		0x5404
 #define TCGETA		0x5405
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/irq.h linux/include/asm-i386/irq.h
--- linux.orig/include/asm-i386/irq.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/irq.h	2002-07-20 01:08:25.000000000 +0000
@@ -23,7 +23,11 @@
  * Since vectors 0x00-0x1f are used/reserved for the CPU,
  * the usable vector space is 0x20-0xff (224 vectors)
  */
+#ifdef CONFIG_X86_IO_APIC
 #define NR_IRQS 224
+#else
+#define NR_IRQS 16
+#endif
 
 static __inline__ int irq_cannonicalize(int irq)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/mmu_context.h linux/include/asm-i386/mmu_context.h
--- linux.orig/include/asm-i386/mmu_context.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/asm-i386/mmu_context.h	2002-07-20 01:08:21.000000000 +0000
@@ -42,18 +42,18 @@
 		set_bit(cpu, &next->cpu_vm_mask);
 		set_bit(cpu, &next->context.cpuvalid);
 		/* Re-load page tables */
-		asm volatile("movl %0,%%cr3": :"r" (__pa(next->pgd)));
+		load_cr3(next->pgd);
 	}
 #ifdef CONFIG_SMP
 	else {
 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
 		if(cpu_tlbstate[cpu].active_mm != next)
-			BUG();
+			out_of_line_bug();
 		if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
 			/* We were in lazy tlb mode and leave_mm disabled 
-			 * tlb flush IPI delivery. We must flush our tlb.
+			 * tlb flush IPI delivery. We must reload %cr3.
 			 */
-			local_flush_tlb();
+			load_cr3(next->pgd);
 		}
 		if (!test_and_set_bit(cpu, &next->context.cpuvalid))
 			load_LDT(next);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/mpspec.h linux/include/asm-i386/mpspec.h
--- linux.orig/include/asm-i386/mpspec.h	2001-11-22 19:46:18.000000000 +0000
+++ linux/include/asm-i386/mpspec.h	2002-07-20 01:08:21.000000000 +0000
@@ -198,6 +198,9 @@
 	MP_BUS_MCA
 };
 extern int mp_bus_id_to_type [MAX_MP_BUSSES];
+extern int mp_bus_id_to_node [MAX_MP_BUSSES];
+extern int mp_bus_id_to_local [MAX_MP_BUSSES];
+extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 
 extern unsigned int boot_cpu_physical_apicid;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/msr.h linux/include/asm-i386/msr.h
--- linux.orig/include/asm-i386/msr.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/asm-i386/msr.h	2002-07-20 01:08:22.000000000 +0000
@@ -48,18 +48,12 @@
 #define MSR_IA32_UCODE_WRITE		0x79
 #define MSR_IA32_UCODE_REV		0x8b
 
-#define MSR_IA32_PERFCTR0		0xc1
-#define MSR_IA32_PERFCTR1		0xc2
-
 #define MSR_IA32_BBL_CR_CTL		0x119
 
 #define MSR_IA32_MCG_CAP		0x179
 #define MSR_IA32_MCG_STATUS		0x17a
 #define MSR_IA32_MCG_CTL		0x17b
 
-#define MSR_IA32_EVNTSEL0		0x186
-#define MSR_IA32_EVNTSEL1		0x187
-
 #define MSR_IA32_DEBUGCTLMSR		0x1d9
 #define MSR_IA32_LASTBRANCHFROMIP	0x1db
 #define MSR_IA32_LASTBRANCHTOIP		0x1dc
@@ -71,6 +65,11 @@
 #define MSR_IA32_MC0_ADDR		0x402
 #define MSR_IA32_MC0_MISC		0x403
 
+#define MSR_P6_PERFCTR0			0xc1
+#define MSR_P6_PERFCTR1			0xc2
+#define MSR_P6_EVNTSEL0			0x186
+#define MSR_P6_EVNTSEL1			0x187
+
 /* AMD Defined MSRs */
 #define MSR_K6_EFER			0xC0000080
 #define MSR_K6_STAR			0xC0000081
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/page.h linux/include/asm-i386/page.h
--- linux.orig/include/asm-i386/page.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/page.h	2002-07-20 01:08:27.000000000 +0000
@@ -91,16 +91,18 @@
 /*
  * Tell the user there is some problem. Beep too, so we can
  * see^H^H^Hhear bugs in early bootup as well!
+ * The offending file and line are encoded after the "officially
+ * undefined" opcode for parsing in the trap handler.
  */
 
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-extern void do_BUG(const char *file, int line);
-#define BUG() do {					\
-	do_BUG(__FILE__, __LINE__);			\
-	__asm__ __volatile__("ud2");			\
-} while (0)
+#if 1	/* Set to zero for a slightly smaller kernel */
+#define BUG()				\
+ __asm__ __volatile__(	"ud2\n"		\
+			"\t.word %c0\n"	\
+			"\t.long %c1\n"	\
+			 : : "i" (__LINE__), "i" (__FILE__))
 #else
-#define BUG() __asm__ __volatile__(".byte 0x0f,0x0b")
+#define BUG() __asm__ __volatile__("ud2\n")
 #endif
 
 #define PAGE_BUG(page) do { \
@@ -132,6 +134,9 @@
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 
 #endif /* _I386_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/pci.h linux/include/asm-i386/pci.h
--- linux.orig/include/asm-i386/pci.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/pci.h	2002-07-20 01:08:34.000000000 +0000
@@ -73,7 +73,7 @@
 					size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 	flush_write_buffers();
 	return virt_to_bus(ptr);
 }
@@ -89,7 +89,7 @@
 				    size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 	/* Nothing to do */
 }
 
@@ -101,16 +101,16 @@
 				      unsigned long offset, size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
-	return (page - mem_map) * PAGE_SIZE + offset;
+	return (dma_addr_t)(page - mem_map) * PAGE_SIZE + offset;
 }
 
 static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
 				  size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 	/* Nothing to do */
 }
 
@@ -143,16 +143,16 @@
 	int i;
 
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
  
  	/*
  	 * temporary 2.4 hack
  	 */
  	for (i = 0; i < nents; i++ ) {
  		if (sg[i].address && sg[i].page)
- 			BUG();
+ 			out_of_line_bug();
  		else if (!sg[i].address && !sg[i].page)
- 			BUG();
+ 			out_of_line_bug();
  
  		if (sg[i].address)
  			sg[i].dma_address = virt_to_bus(sg[i].address);
@@ -172,7 +172,7 @@
 				int nents, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 	/* Nothing to do */
 }
 
@@ -190,7 +190,7 @@
 				       size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 	flush_write_buffers();
 }
 
@@ -205,7 +205,7 @@
 				   int nelems, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 	flush_write_buffers();
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/pgalloc.h linux/include/asm-i386/pgalloc.h
--- linux.orig/include/asm-i386/pgalloc.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/asm-i386/pgalloc.h	2002-07-20 01:08:24.000000000 +0000
@@ -139,7 +139,7 @@
 	free_page((unsigned long)pte);
 }
 
-#define pte_free(pte)		pte_free_slow(pte)
+#define pte_free(pte)		pte_free_fast(pte)
 #define pgd_free(pgd)		free_pgd_slow(pgd)
 #define pgd_alloc(mm)		get_pgd_fast()
 
@@ -227,13 +227,12 @@
 };
 extern struct tlb_state cpu_tlbstate[NR_CPUS];
 
-
-#endif
+#endif /* CONFIG_SMP */
 
 static inline void flush_tlb_pgtables(struct mm_struct *mm,
 				      unsigned long start, unsigned long end)
 {
-	/* i386 does not keep any page table caches in TLB */
+	flush_tlb_mm(mm);
 }
 
 #endif /* _I386_PGALLOC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h
--- linux.orig/include/asm-i386/pgtable.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/asm-i386/pgtable.h	2002-07-20 01:08:39.000000000 +0000
@@ -33,6 +33,7 @@
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_icache_range(start, end)		do { } while (0)
 #define flush_icache_page(vma,pg)		do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 #define __flush_tlb()							\
 	do {								\
@@ -263,11 +264,7 @@
 #define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
 #define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
 
-/*
- * Permanent address of a page. Obviously must never be
- * called on a highmem page.
- */
-#define page_address(page) ((page)->virtual)
+
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/processor.h linux/include/asm-i386/processor.h
--- linux.orig/include/asm-i386/processor.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/asm-i386/processor.h	2002-07-20 01:08:23.000000000 +0000
@@ -63,6 +63,7 @@
 #define X86_VENDOR_CENTAUR 5
 #define X86_VENDOR_RISE 6
 #define X86_VENDOR_TRANSMETA 7
+#define X86_VENDOR_NSC 8
 #define X86_VENDOR_UNKNOWN 0xff
 
 /*
@@ -190,6 +191,9 @@
 #define X86_CR4_OSFXSR		0x0200	/* enable fast FPU save and restore */
 #define X86_CR4_OSXMMEXCPT	0x0400	/* enable unmasked SSE exceptions */
 
+#define load_cr3(pgdir) \
+	asm volatile("movl %0,%%cr3": :"r" (__pa(pgdir)));
+
 /*
  * Save the cr4 feature set we're using (ie
  * Pentium 4MB enable and PPro Global page
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/rwlock.h linux/include/asm-i386/rwlock.h
--- linux.orig/include/asm-i386/rwlock.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/rwlock.h	2002-07-20 01:08:35.000000000 +0000
@@ -17,8 +17,6 @@
 #ifndef _ASM_I386_RWLOCK_H
 #define _ASM_I386_RWLOCK_H
 
-#include <linux/stringify.h>
-
 #define RW_LOCK_BIAS		 0x01000000
 #define RW_LOCK_BIAS_STR	"0x01000000"
 
@@ -26,29 +24,23 @@
 	asm volatile(LOCK "subl $1,(%0)\n\t" \
 		     "js 2f\n" \
 		     "1:\n" \
-		     ".subsection 1\n" \
-		     ".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n" \
-		     "_text_lock_" __stringify(KBUILD_BASENAME) ":\n" \
-		     ".endif\n" \
+		     LOCK_SECTION_START("") \
 		     "2:\tcall " helper "\n\t" \
 		     "jmp 1b\n" \
-		     ".subsection 0\n" \
+		     LOCK_SECTION_END \
 		     ::"a" (rw) : "memory")
 
 #define __build_read_lock_const(rw, helper)   \
 	asm volatile(LOCK "subl $1,%0\n\t" \
 		     "js 2f\n" \
 		     "1:\n" \
-		     ".subsection 1\n" \
-		     ".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n" \
-		     "_text_lock_" __stringify(KBUILD_BASENAME) ":\n" \
-		     ".endif\n" \
+		     LOCK_SECTION_START("") \
 		     "2:\tpushl %%eax\n\t" \
 		     "leal %0,%%eax\n\t" \
 		     "call " helper "\n\t" \
 		     "popl %%eax\n\t" \
 		     "jmp 1b\n" \
-		     ".subsection 0\n" \
+		     LOCK_SECTION_END \
 		     :"=m" (*(volatile int *)rw) : : "memory")
 
 #define __build_read_lock(rw, helper)	do { \
@@ -62,29 +54,23 @@
 	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
 		     "jnz 2f\n" \
 		     "1:\n" \
-		     ".subsection 1\n" \
-		     ".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n" \
-		     "_text_lock_" __stringify(KBUILD_BASENAME) ":\n" \
-		     ".endif\n" \
+		     LOCK_SECTION_START("") \
 		     "2:\tcall " helper "\n\t" \
 		     "jmp 1b\n" \
-		     ".subsection 0\n" \
+		     LOCK_SECTION_END \
 		     ::"a" (rw) : "memory")
 
 #define __build_write_lock_const(rw, helper) \
 	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
 		     "jnz 2f\n" \
 		     "1:\n" \
-		     ".subsection 1\n" \
-		     ".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n" \
-		     "_text_lock_" __stringify(KBUILD_BASENAME) ":\n" \
-		     ".endif\n" \
+		     LOCK_SECTION_START("") \
 		     "2:\tpushl %%eax\n\t" \
 		     "leal %0,%%eax\n\t" \
 		     "call " helper "\n\t" \
 		     "popl %%eax\n\t" \
 		     "jmp 1b\n" \
-		     ".subsection 0\n" \
+		     LOCK_SECTION_END \
 		     :"=m" (*(volatile int *)rw) : : "memory")
 
 #define __build_write_lock(rw, helper)	do { \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/rwsem.h linux/include/asm-i386/rwsem.h
--- linux.orig/include/asm-i386/rwsem.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/rwsem.h	2002-07-20 01:08:34.000000000 +0000
@@ -40,7 +40,6 @@
 
 #include <linux/list.h>
 #include <linux/spinlock.h>
-#include <linux/stringify.h>
 
 struct rwsem_waiter;
 
@@ -102,10 +101,7 @@
 LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
 		"  js        2f\n\t" /* jump if we weren't granted the lock */
 		"1:\n\t"
-		".subsection 1\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START("")
 		"2:\n\t"
 		"  pushl     %%ecx\n\t"
 		"  pushl     %%edx\n\t"
@@ -113,7 +109,7 @@
 		"  popl      %%edx\n\t"
 		"  popl      %%ecx\n\t"
 		"  jmp       1b\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		"# ending down_read\n\t"
 		: "+m"(sem->count)
 		: "a"(sem)
@@ -134,16 +130,13 @@
 		"  testl     %0,%0\n\t" /* was the count 0 before? */
 		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
 		"1:\n\t"
-		".subsection 1\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START("")
 		"2:\n\t"
 		"  pushl     %%ecx\n\t"
 		"  call      rwsem_down_write_failed\n\t"
 		"  popl      %%ecx\n\t"
 		"  jmp       1b\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		"# ending down_write"
 		: "+d"(tmp), "+m"(sem->count)
 		: "a"(sem)
@@ -161,10 +154,7 @@
 LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
-		".subsection 1\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START("")
 		"2:\n\t"
 		"  decw      %%dx\n\t" /* do nothing if still outstanding active readers */
 		"  jnz       1b\n\t"
@@ -172,7 +162,7 @@
 		"  call      rwsem_wake\n\t"
 		"  popl      %%ecx\n\t"
 		"  jmp       1b\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		"# ending __up_read\n"
 		: "+m"(sem->count), "+d"(tmp)
 		: "a"(sem)
@@ -190,10 +180,7 @@
 LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
-		".subsection 1\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START("")
 		"2:\n\t"
 		"  decw      %%dx\n\t" /* did the active count reduce to 0? */
 		"  jnz       1b\n\t" /* jump back if not */
@@ -201,7 +188,7 @@
 		"  call      rwsem_wake\n\t"
 		"  popl      %%ecx\n\t"
 		"  jmp       1b\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		"# ending __up_write\n"
 		: "+m"(sem->count)
 		: "a"(sem), "i"(-RWSEM_ACTIVE_WRITE_BIAS)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/semaphore.h linux/include/asm-i386/semaphore.h
--- linux.orig/include/asm-i386/semaphore.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/semaphore.h	2002-07-20 01:08:30.000000000 +0000
@@ -40,7 +40,6 @@
 #include <asm/atomic.h>
 #include <linux/wait.h>
 #include <linux/rwsem.h>
-#include <linux/stringify.h>
 
 struct semaphore {
 	atomic_t count;
@@ -123,13 +122,10 @@
 		LOCK "decl %0\n\t"     /* --sem->count */
 		"js 2f\n"
 		"1:\n"
-		".subsection 1\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START("")
 		"2:\tcall __down_failed\n\t"
 		"jmp 1b\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		:"=m" (sem->count)
 		:"c" (sem)
 		:"memory");
@@ -153,13 +149,10 @@
 		"js 2f\n\t"
 		"xorl %0,%0\n"
 		"1:\n"
-		".subsection 1\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START("")
 		"2:\tcall __down_failed_interruptible\n\t"
 		"jmp 1b\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		:"=a" (result), "=m" (sem->count)
 		:"c" (sem)
 		:"memory");
@@ -184,13 +177,10 @@
 		"js 2f\n\t"
 		"xorl %0,%0\n"
 		"1:\n"
-		".subsection 1\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START("")
 		"2:\tcall __down_failed_trylock\n\t"
 		"jmp 1b\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		:"=a" (result), "=m" (sem->count)
 		:"c" (sem)
 		:"memory");
@@ -213,12 +203,10 @@
 		LOCK "incl %0\n\t"     /* ++sem->count */
 		"jle 2f\n"
 		"1:\n"
-		".subsection 1\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START("")
 		"2:\tcall __up_wakeup\n\t"
 		"jmp 1b\n"
+		LOCK_SECTION_END
 		".subsection 0\n"
 		:"=m" (sem->count)
 		:"c" (sem)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/serial.h linux/include/asm-i386/serial.h
--- linux.orig/include/asm-i386/serial.h	2001-11-22 19:47:23.000000000 +0000
+++ linux/include/asm-i386/serial.h	2002-07-20 01:08:35.000000000 +0000
@@ -57,6 +57,20 @@
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
 
+/*
+ * HCDP_SERIAL_PORT_DEFNS should be placed in exactly the same slot 
+ * in rs_table as defined by HCDP_SERIAL_CONSOLE_PORT in 
+ * include/linux/serial.h
+ */
+#define HCDP_SERIAL_PORT_DEFNS	\
+	{ 0, BASE_BAUD, -1, 0, STD_COM_FLAGS},		/* ttySx device
+							   in comments sucks.
+							   You add an entry
+							   and you get to edit 
+							   boatloads of these 
+							   comments. Not worth
+							   it */
+
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
 #define EXTRA_SERIAL_PORT_DEFNS			\
@@ -127,6 +141,7 @@
 
 #define SERIAL_PORT_DFNS		\
 	STD_SERIAL_PORT_DEFNS		\
+	HCDP_SERIAL_PORT_DEFNS		\
 	EXTRA_SERIAL_PORT_DEFNS		\
 	HUB6_SERIAL_PORT_DFNS		\
 	MCA_SERIAL_PORT_DFNS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/siginfo.h linux/include/asm-i386/siginfo.h
--- linux.orig/include/asm-i386/siginfo.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/asm-i386/siginfo.h	2002-07-20 01:08:29.000000000 +0000
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/smplock.h linux/include/asm-i386/smplock.h
--- linux.orig/include/asm-i386/smplock.h	2001-11-22 19:46:20.000000000 +0000
+++ linux/include/asm-i386/smplock.h	2002-07-20 01:08:31.000000000 +0000
@@ -8,7 +8,8 @@
 #include <linux/sched.h>
 #include <asm/current.h>
 
-extern spinlock_t kernel_flag;
+extern spinlock_cacheline_t kernel_flag_cacheline;  
+#define kernel_flag kernel_flag_cacheline.lock      
 
 #define kernel_locked()		spin_is_locked(&kernel_flag)
 
@@ -59,7 +60,7 @@
 static __inline__ void unlock_kernel(void)
 {
 	if (current->lock_depth < 0)
-		BUG();
+		out_of_line_bug();
 #if 1
 	if (--current->lock_depth < 0)
 		spin_unlock(&kernel_flag);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/softirq.h linux/include/asm-i386/softirq.h
--- linux.orig/include/asm-i386/softirq.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/softirq.h	2002-07-20 01:08:34.000000000 +0000
@@ -3,7 +3,6 @@
 
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
-#include <linux/stringify.h>
 
 #define __cpu_bh_enable(cpu) \
 		do { barrier(); local_bh_count(cpu)--; } while (0)
@@ -34,15 +33,12 @@
 			"jnz 2f;"					\
 			"1:;"						\
 									\
-			".subsection 1;"				\
-			".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"		\
-			"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"		\
-			".endif\n"					\
+			LOCK_SECTION_START("")				\
 			"2: pushl %%eax; pushl %%ecx; pushl %%edx;"	\
 			"call %c1;"					\
 			"popl %%edx; popl %%ecx; popl %%eax;"		\
 			"jmp 1b;"					\
-			".subsection 0;"				\
+			LOCK_SECTION_END				\
 									\
 		: /* no output */					\
 		: "r" (ptr), "i" (do_softirq)				\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h
--- linux.orig/include/asm-i386/spinlock.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/spinlock.h	2002-07-20 01:08:29.000000000 +0000
@@ -5,7 +5,6 @@
 #include <asm/rwlock.h>
 #include <asm/page.h>
 #include <linux/config.h>
-#include <linux/stringify.h>
 
 extern int printk(const char * fmt, ...)
 	__attribute__ ((format (printf, 1, 2)));
@@ -57,16 +56,13 @@
 	"\n1:\t" \
 	"lock ; decb %0\n\t" \
 	"js 2f\n" \
-	".subsection 1\n" \
-	".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n" \
-	"_text_lock_" __stringify(KBUILD_BASENAME) ":\n" \
-	".endif\n" \
+	LOCK_SECTION_START("") \
 	"2:\t" \
 	"cmpb $0,%0\n\t" \
 	"rep;nop\n\t" \
 	"jle 2b\n\t" \
 	"jmp 1b\n" \
-	".subsection 0\n"
+	LOCK_SECTION_END
 
 /*
  * This works. Despite all the confusion.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/types.h linux/include/asm-i386/types.h
--- linux.orig/include/asm-i386/types.h	2001-10-12 22:35:54.000000000 +0000
+++ linux/include/asm-i386/types.h	2002-07-20 01:08:23.000000000 +0000
@@ -45,7 +45,7 @@
 
 /* DMA addresses come in generic and 64-bit flavours.  */
 
-#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM64G
 typedef u64 dma_addr_t;
 #else
 typedef u32 dma_addr_t;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- linux.orig/include/asm-i386/unistd.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-i386/unistd.h	2002-07-20 01:08:38.000000000 +0000
@@ -242,6 +242,11 @@
 #define __NR_removexattr	235
 #define __NR_lremovexattr	236
 #define __NR_fremovexattr	237
+#define __NR_tkill		238
+#define __NR_sendfile64		239
+#define __NR_futex		240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-i386/xor.h linux/include/asm-i386/xor.h
--- linux.orig/include/asm-i386/xor.h	2001-09-14 21:25:21.000000000 +0000
+++ linux/include/asm-i386/xor.h	2002-07-20 01:08:25.000000000 +0000
@@ -76,9 +76,9 @@
 	"       addl $128, %2         ;\n"
 	"       decl %0               ;\n"
 	"       jnz 1b                ;\n"
-       	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2)
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2)
+	:
 	: "memory");
 
 	FPU_RESTORE;
@@ -126,9 +126,9 @@
 	"       addl $128, %3         ;\n"
 	"       decl %0               ;\n"
 	"       jnz 1b                ;\n"
-       	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3)
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2), "+r" (p3)
+	:
 	: "memory");
 
 	FPU_RESTORE;
@@ -181,14 +181,15 @@
 	"       addl $128, %4         ;\n"
 	"       decl %0               ;\n"
 	"       jnz 1b                ;\n"
-       	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4)
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4)
+	:
 	: "memory");
 
 	FPU_RESTORE;
 }
 
+
 static void
 xor_pII_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
 	      unsigned long *p3, unsigned long *p4, unsigned long *p5)
@@ -198,7 +199,11 @@
 
 	FPU_SAVE;
 
+	/* need to save/restore p4/p5 manually otherwise gcc's 10 argument
+	   limit gets exceeded (+ counts as two arguments) */
 	__asm__ __volatile__ (
+		"  pushl %4\n"
+		"  pushl %5\n"
 #undef BLOCK
 #define BLOCK(i) \
 	LD(i,0)					\
@@ -241,9 +246,11 @@
 	"       addl $128, %5         ;\n"
 	"       decl %0               ;\n"
 	"       jnz 1b                ;\n"
-       	:
-	: "g" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
+	"	popl %5\n"
+	"	popl %4\n"
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2), "+r" (p3)
+	: "r" (p4), "r" (p5) 
 	: "memory");
 
 	FPU_RESTORE;
@@ -297,9 +304,9 @@
 	"       addl $64, %2         ;\n"
 	"       decl %0              ;\n"
 	"       jnz 1b               ;\n"
-	: 
-	: "r" (lines),
-	  "r" (p1), "r" (p2)
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2)
+	:
 	: "memory");
 
 	FPU_RESTORE;
@@ -355,9 +362,9 @@
 	"       addl $64, %3         ;\n"
 	"       decl %0              ;\n"
 	"       jnz 1b               ;\n"
-	: 
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3)
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2), "+r" (p3)
+	:
 	: "memory" );
 
 	FPU_RESTORE;
@@ -422,9 +429,9 @@
 	"       addl $64, %4         ;\n"
 	"       decl %0              ;\n"
 	"       jnz 1b               ;\n"
-	: 
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4)
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4)
+	:
 	: "memory");
 
 	FPU_RESTORE;
@@ -439,7 +446,10 @@
 
 	FPU_SAVE;
 
+	/* need to save p4/p5 manually to not exceed gcc's 10 argument limit */
 	__asm__ __volatile__ (
+	"	pushl %4\n"
+	"	pushl %5\n"        	
 	" .align 32,0x90             ;\n"
 	" 1:                         ;\n"
 	"       movq   (%1), %%mm0   ;\n"
@@ -498,9 +508,11 @@
 	"       addl $64, %5         ;\n"
 	"       decl %0              ;\n"
 	"       jnz 1b               ;\n"
-	: 
-	: "g" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
+	"	popl %5\n"
+	"	popl %4\n"
+	: "+g" (lines),
+	  "+r" (p1), "+r" (p2), "+r" (p3)
+	: "r" (p4), "r" (p5)
 	: "memory");
 
 	FPU_RESTORE;
@@ -538,7 +550,7 @@
 		"movups %%xmm1,0x10(%1)	;\n\t"	\
 		"movups %%xmm2,0x20(%1)	;\n\t"	\
 		"movups %%xmm3,0x30(%1)	;\n\t"	\
-		: "=r" (cr0)			\
+		: "=&r" (cr0)			\
 		: "r" (xmm_save) 		\
 		: "memory")
 
@@ -554,6 +566,8 @@
 		: "r" (cr0), "r" (xmm_save)	\
 		: "memory")
 
+#define ALIGN16 __attribute__((aligned(16)))
+
 #define OFFS(x)		"16*("#x")"
 #define PF_OFFS(x)	"256+16*("#x")"
 #define	PF0(x)		"	prefetchnta "PF_OFFS(x)"(%1)		;\n"
@@ -575,7 +589,7 @@
 xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
 {
         unsigned long lines = bytes >> 8;
-	char xmm_save[16*4];
+	char xmm_save[16*4] ALIGN16;
 	int cr0;
 
 	XMMS_SAVE;
@@ -616,9 +630,9 @@
         "       addl $256, %2           ;\n"
         "       decl %0                 ;\n"
         "       jnz 1b                  ;\n"
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2)
 	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2)
         : "memory");
 
 	XMMS_RESTORE;
@@ -629,7 +643,7 @@
 	  unsigned long *p3)
 {
         unsigned long lines = bytes >> 8;
-	char xmm_save[16*4];
+	char xmm_save[16*4] ALIGN16;
 	int cr0;
 
 	XMMS_SAVE;
@@ -677,9 +691,9 @@
         "       addl $256, %3           ;\n"
         "       decl %0                 ;\n"
         "       jnz 1b                  ;\n"
+	: "+r" (lines),
+	  "+r" (p1), "+r"(p2), "+r"(p3)
 	:
-	: "r" (lines),
-	  "r" (p1), "r"(p2), "r"(p3)
         : "memory" );
 
 	XMMS_RESTORE;
@@ -690,7 +704,7 @@
 	  unsigned long *p3, unsigned long *p4)
 {
         unsigned long lines = bytes >> 8;
-	char xmm_save[16*4];
+	char xmm_save[16*4] ALIGN16;
 	int cr0;
 
 	XMMS_SAVE;
@@ -745,9 +759,9 @@
         "       addl $256, %4           ;\n"
         "       decl %0                 ;\n"
         "       jnz 1b                  ;\n"
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4)
 	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4)
         : "memory" );
 
 	XMMS_RESTORE;
@@ -758,12 +772,15 @@
 	  unsigned long *p3, unsigned long *p4, unsigned long *p5)
 {
         unsigned long lines = bytes >> 8;
-	char xmm_save[16*4];
+	char xmm_save[16*4] ALIGN16;
 	int cr0;
 
 	XMMS_SAVE;
 
+	/* need to save p4/p5 manually to not exceed gcc's 10 argument limit */
         __asm__ __volatile__ (
+		" pushl %4\n"
+		" pushl %5\n"
 #undef BLOCK
 #define BLOCK(i) \
 		PF1(i)					\
@@ -820,9 +837,11 @@
         "       addl $256, %5           ;\n"
         "       decl %0                 ;\n"
         "       jnz 1b                  ;\n"
-	:
-	: "r" (lines),
-	  "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
+	"	popl %5\n"	
+	"	popl %4\n"	
+	: "+r" (lines),
+	  "+r" (p1), "+r" (p2), "+r" (p3)
+	: "r" (p4), "r" (p5)
 	: "memory");
 
 	XMMS_RESTORE;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/a.out.h linux/include/asm-ia64/a.out.h
--- linux.orig/include/asm-ia64/a.out.h	2001-07-31 17:30:09.000000000 +0000
+++ linux/include/asm-ia64/a.out.h	2002-07-20 01:08:30.000000000 +0000
@@ -7,8 +7,8 @@
  * probably would be better to clean up binfmt_elf.c so it does not
  * necessarily depend on there being a.out support.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2000, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/types.h>
@@ -31,7 +31,7 @@
 
 #ifdef __KERNEL__
 # include <asm/page.h>
-# define STACK_TOP	(0x8000000000000000UL + (1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)
+# define STACK_TOP	(0x6000000000000000UL + (1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)
 # define IA64_RBS_BOT	(STACK_TOP - 0x80000000L + PAGE_SIZE)	/* bottom of reg. backing store */
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/acpi-ext.h linux/include/asm-ia64/acpi-ext.h
--- linux.orig/include/asm-ia64/acpi-ext.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/acpi-ext.h	2002-07-20 01:08:22.000000000 +0000
@@ -13,7 +13,9 @@
  *	ACPI 2.0 specification
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
+#include <linux/mm.h>
 
 #pragma	pack(1)
 #define ACPI_RSDP_SIG "RSD PTR " /* Trailing space required */
@@ -24,7 +26,7 @@
 	char oem_id[6];
 	u8 revision;
 	u32 rsdt;
-	u32 lenth;
+	u32 length;
 	struct acpi_xsdt *xsdt;
 	u8 ext_checksum;
 	u8 reserved[3];
@@ -96,7 +98,7 @@
 	struct acpi_rsdt *rsdt;
 } acpi_rsdp_t;
 
-typedef struct {
+typedef struct acpi_rsdt {
 	acpi_desc_table_hdr_t header;
 	u8 reserved[4];
 	unsigned long entry_ptrs[1];	/* Not really . . . */
@@ -151,15 +153,15 @@
 #define MADT_PCAT_COMPAT	(1<<0)
 
 /* acpi 2.0 MADT structure types */
-#define ACPI20_ENTRY_LOCAL_APIC                 0
-#define ACPI20_ENTRY_IO_APIC                    1
-#define ACPI20_ENTRY_INT_SRC_OVERRIDE           2
-#define ACPI20_ENTRY_NMI_SOURCE                 3
-#define ACPI20_ENTRY_LOCAL_APIC_NMI             4
-#define ACPI20_ENTRY_LOCAL_APIC_ADDR_OVERRIDE   5
-#define ACPI20_ENTRY_IO_SAPIC                   6
-#define ACPI20_ENTRY_LOCAL_SAPIC                7
-#define ACPI20_ENTRY_PLATFORM_INT_SOURCE        8
+#define ACPI20_ENTRY_LOCAL_APIC			0
+#define ACPI20_ENTRY_IO_APIC			1
+#define ACPI20_ENTRY_INT_SRC_OVERRIDE		2
+#define ACPI20_ENTRY_NMI_SOURCE			3
+#define ACPI20_ENTRY_LOCAL_APIC_NMI		4
+#define ACPI20_ENTRY_LOCAL_APIC_ADDR_OVERRIDE	5
+#define ACPI20_ENTRY_IO_SAPIC			6
+#define ACPI20_ENTRY_LOCAL_SAPIC		7
+#define ACPI20_ENTRY_PLATFORM_INT_SOURCE	8
 
 typedef struct acpi20_entry_lsapic {
 	u8 type;
@@ -190,16 +192,132 @@
 } acpi20_entry_platform_src_t;
 
 /* constants for interrupt routing API for device drivers */
-#define	ACPI20_ENTRY_PIS_PMI	1
-#define	ACPI20_ENTRY_PIS_INIT	2
-#define	ACPI20_ENTRY_PIS_CPEI	3
-#define	ACPI_MAX_PLATFORM_IRQS	4
+#define ACPI20_ENTRY_PIS_PMI	1
+#define ACPI20_ENTRY_PIS_INIT	2
+#define ACPI20_ENTRY_PIS_CPEI	3
+#define ACPI_MAX_PLATFORM_IRQS	4
+
+#define ACPI_SPCRT_SIG	"SPCR"
+#define ACPI_SPCRT_SIG_LEN 4
+
+#define ACPI_DBGPT_SIG	"DBGP"
+#define ACPI_DBGPT_SIG_LEN 4
 
 extern int acpi20_parse(acpi20_rsdp_t *);
+extern int acpi20_early_parse(acpi20_rsdp_t *);
 extern int acpi_parse(acpi_rsdp_t *);
 extern const char *acpi_get_sysname (void);
 extern int acpi_request_vector(u32 int_type);
-
 extern void (*acpi_idle) (void);	/* power-management idle function, if any */
+#ifdef CONFIG_NUMA
+extern cnodeid_t paddr_to_nid(unsigned long paddr);
+#endif
+
+/*
+ * ACPI 2.0 SRAT Table
+ * http://www.microsoft.com/HWDEV/design/SRAT.htm
+ */
+
+typedef struct acpi_srat {
+	acpi_desc_table_hdr_t header;
+	u32 table_revision;
+	u64 reserved;
+} acpi_srat_t;
+
+typedef struct srat_cpu_affinity {
+	u8 type;
+	u8 length;
+	u8 proximity_domain;
+	u8 apic_id;
+	u32 flags;
+	u8 local_sapic_eid;
+	u8 reserved[7];
+} srat_cpu_affinity_t;
+
+typedef struct srat_memory_affinity {
+	u8 type;
+	u8 length;
+	u8 proximity_domain;
+	u8 reserved[5];
+	u32 base_addr_lo;
+	u32 base_addr_hi;
+	u32 length_lo;
+	u32 length_hi;
+	u32 memory_type;
+	u32 flags;
+	u64 reserved2;
+} srat_memory_affinity_t;
+
+/* ACPI 2.0 SRAT structure */
+#define ACPI_SRAT_SIG "SRAT"
+#define ACPI_SRAT_SIG_LEN 4
+#define ACPI_SRAT_REVISION 1
+
+#define SRAT_CPU_STRUCTURE		0
+#define SRAT_MEMORY_STRUCTURE		1
+
+/* Only 1 flag for cpu affinity structure! */
+#define SRAT_CPU_FLAGS_ENABLED			0x00000001
+
+#define SRAT_MEMORY_FLAGS_ENABLED		0x00000001
+#define SRAT_MEMORY_FLAGS_HOTREMOVABLE		0x00000002
+
+/* ACPI 2.0 address range types */
+#define ACPI_ADDRESS_RANGE_MEMORY	1
+#define ACPI_ADDRESS_RANGE_RESERVED	2
+#define ACPI_ADDRESS_RANGE_ACPI		3
+#define ACPI_ADDRESS_RANGE_NVS		4
+
+#define NODE_ARRAY_INDEX(x)	((x) / 8)	/* 8 bits/char */
+#define NODE_ARRAY_OFFSET(x)	((x) % 8)	/* 8 bits/char */
+#define MAX_PXM_DOMAINS		(256)
+
+#ifdef CONFIG_DISCONTIGMEM
+/*
+ * List of node memory chunks. Filled when parsing SRAT table to
+ * obtain information about memory nodes.
+*/
+
+struct node_memory_chunk_s {
+	unsigned long start_paddr;
+	unsigned long size;
+	int pxm;			// proximity domain of node
+	int nid;			// which cnode contains this chunk?
+	int bank;			// which mem bank on this node
+};
+
+extern struct node_memory_chunk_s node_memory_chunk[PLAT_MAXCLUMPS];	// temporary?
+
+struct node_cpuid_s {
+	u16	phys_id;		/* id << 8 | eid */
+	int	pxm;			// proximity domain of cpu
+	int	nid;
+};
+extern struct node_cpuid_s node_cpuid[NR_CPUS];
+
+extern int pxm_to_nid_map[MAX_PXM_DOMAINS]; /* _PXM to logical node ID map */
+extern int nid_to_pxm_map[PLAT_MAX_COMPACT_NODES]; /* logical node ID to _PXM map */
+extern int numnodes;			/* total number of nodes in system */
+extern int num_memory_chunks;		/* total number of memory chunks */
+
+/*
+ * ACPI 2.0 SLIT Table
+ * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
+ */
+
+typedef struct acpi_slit {
+	acpi_desc_table_hdr_t header;
+	u64 localities;
+	u8 entries[1];			/* dummy, real size = locality^2 */
+} acpi_slit_t;
+
+extern u8 acpi20_slit[PLAT_MAX_COMPACT_NODES * PLAT_MAX_COMPACT_NODES];
+
+#define ACPI_SLIT_SIG "SLIT"
+#define ACPI_SLIT_SIG_LEN 4
+#define ACPI_SLIT_REVISION 1
+#define ACPI_SLIT_LOCAL 10
+#endif /* CONFIG_DISCONTIGMEM */
+
 #pragma	pack()
 #endif /* _ASM_IA64_ACPI_EXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/bitops.h linux/include/asm-ia64/bitops.h
--- linux.orig/include/asm-ia64/bitops.h	2001-07-31 17:30:09.000000000 +0000
+++ linux/include/asm-ia64/bitops.h	2002-07-20 01:08:39.000000000 +0000
@@ -57,10 +57,10 @@
 }
 
 /*
- * clear_bit() doesn't provide any barrier for the compiler.
+ * clear_bit() has "acquire" semantics.
  */
 #define smp_mb__before_clear_bit()	smp_mb()
-#define smp_mb__after_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	do { /* skip */; } while (0)
 
 /**
  * clear_bit - Clears a bit in memory
@@ -357,6 +357,8 @@
 	tmp = *p;
 found_first:
 	tmp |= ~0UL << size;
+	if (tmp == ~0UL)		/* any bits zero? */
+		return result + size;	/* nope */
 found_middle:
 	return result + ffz(tmp);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/checksum.h linux/include/asm-ia64/checksum.h
--- linux.orig/include/asm-ia64/checksum.h	2000-02-07 02:42:40.000000000 +0000
+++ linux/include/asm-ia64/checksum.h	2002-07-20 01:08:21.000000000 +0000
@@ -89,11 +89,4 @@
 	return ~sum;
 }
 
-#define _HAVE_ARCH_IPV6_CSUM
-extern unsigned short int csum_ipv6_magic (struct in6_addr *saddr,
-					   struct in6_addr *daddr,
-					   __u16 len,
-					   unsigned short proto,
-					   unsigned int sum);
-
 #endif /* _ASM_IA64_CHECKSUM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/efi.h linux/include/asm-ia64/efi.h
--- linux.orig/include/asm-ia64/efi.h	2001-07-31 17:30:09.000000000 +0000
+++ linux/include/asm-ia64/efi.h	2002-07-20 01:08:36.000000000 +0000
@@ -181,6 +181,9 @@
 #define SAL_SYSTEM_TABLE_GUID    \
     ((efi_guid_t) { 0xeb9d2d32, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
 
+#define HCDP_TABLE_GUID	\
+    ((efi_guid_t) { 0xf951938d, 0x620b, 0x42ef, {0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98}})
+
 typedef struct {
 	efi_guid_t guid;
 	u64 table;
@@ -215,6 +218,7 @@
 	void *acpi20;			/* ACPI table  (ACPI 2.0) */
 	void *smbios;			/* SM BIOS table */
 	void *sal_systab;		/* SAL system table */
+	void *hcdp;			/* HCDP table */
 	void *boot_info;		/* boot info table */
 	efi_get_time_t *get_time;
 	efi_set_time_t *set_time;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/elf.h linux/include/asm-ia64/elf.h
--- linux.orig/include/asm-ia64/elf.h	2000-07-11 22:43:45.000000000 +0000
+++ linux/include/asm-ia64/elf.h	2002-07-20 01:08:26.000000000 +0000
@@ -4,8 +4,8 @@
 /*
  * ELF archtecture specific definitions.
  *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <asm/fpu.h>
@@ -25,6 +25,10 @@
 
 #define USE_ELF_CORE_DUMP
 
+/* Least-significant four bits of ELF header's e_flags are OS-specific.  The bits are
+   interpreted as follows by Linux: */
+#define EF_IA_64_LINUX_EXECUTABLE_STACK	0x1	/* is stack (& heap) executable by default? */
+
 /* always align to 64KB to allow for future page sizes of up to 64KB: */
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
@@ -82,7 +86,9 @@
 #define ELF_PLATFORM	0
 
 #ifdef __KERNEL__
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+struct elf64_hdr;
+extern void ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter);
+#define SET_PERSONALITY(ex, ibcs2)	ia64_set_personality(&(ex), ibcs2)
 #endif
 
 #endif /* _ASM_IA64_ELF_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/hardirq.h linux/include/asm-ia64/hardirq.h
--- linux.orig/include/asm-ia64/hardirq.h	2001-07-31 17:30:09.000000000 +0000
+++ linux/include/asm-ia64/hardirq.h	2002-07-20 01:08:29.000000000 +0000
@@ -25,8 +25,8 @@
 
 #define local_softirq_pending()		(local_cpu_data->softirq_pending)
 #define local_ksoftirqd_task()		(local_cpu_data->ksoftirqd)
-#define local_irq_count()		(local_cpu_data->irq_stat.f.irq_count)
-#define local_bh_count()		(local_cpu_data->irq_stat.f.bh_count)
+#define really_local_irq_count()	(local_cpu_data->irq_stat.f.irq_count)	/* XXX fix me */
+#define really_local_bh_count()		(local_cpu_data->irq_stat.f.bh_count)	/* XXX fix me */
 #define local_syscall_count()		/* unused on IA-64 */
 #define local_nmi_count()		0
 
@@ -38,11 +38,11 @@
 #define in_irq()			(local_cpu_data->irq_stat.f.irq_count != 0)
 
 #ifndef CONFIG_SMP
-# define local_hardirq_trylock()	(local_irq_count() == 0)
+# define local_hardirq_trylock()	(really_local_irq_count() == 0)
 # define local_hardirq_endlock()	do { } while (0)
 
-# define local_irq_enter(irq)		(local_irq_count()++)
-# define local_irq_exit(irq)		(local_irq_count()--)
+# define local_irq_enter(irq)		(really_local_irq_count()++)
+# define local_irq_exit(irq)		(really_local_irq_count()--)
 
 # define synchronize_irq()		barrier()
 #else
@@ -70,6 +70,7 @@
 	/* if we didn't own the irq lock, just ignore.. */
 	if (global_irq_holder == cpu) {
 		global_irq_holder = NO_PROC_ID;
+		smp_mb__before_clear_bit();	/* need barrier before releasing lock... */
 		clear_bit(0,&global_irq_lock);
         }
 }
@@ -77,7 +78,7 @@
 static inline void
 local_irq_enter (int irq)
 {
-	local_irq_count()++;
+	really_local_irq_count()++;
 
 	while (test_bit(0,&global_irq_lock)) {
 		/* nothing */;
@@ -87,13 +88,13 @@
 static inline void
 local_irq_exit (int irq)
 {
-	local_irq_count()--;
+	really_local_irq_count()--;
 }
 
 static inline int
 local_hardirq_trylock (void)
 {
-	return !local_irq_count() && !test_bit(0,&global_irq_lock);
+	return !really_local_irq_count() && !test_bit(0,&global_irq_lock);
 }
 
 #define local_hardirq_endlock()		do { } while (0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/ide.h linux/include/asm-ia64/ide.h
--- linux.orig/include/asm-ia64/ide.h	2000-05-24 15:40:41.000000000 +0000
+++ linux/include/asm-ia64/ide.h	2002-07-20 01:08:22.000000000 +0000
@@ -101,7 +101,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+	} b;
+} control_t;
 
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
 #define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/io.h linux/include/asm-ia64/io.h
--- linux.orig/include/asm-ia64/io.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/io.h	2002-07-20 01:08:24.000000000 +0000
@@ -408,5 +408,11 @@
 #define memset_io(addr,c,len) \
   __ia64_memset_c_io((unsigned long)(addr),0x0101010101010101UL*(u8)(c),(len))
 
+
+#define dma_cache_inv(_start,_size)             do { } while (0)
+#define dma_cache_wback(_start,_size)           do { } while (0)
+#define dma_cache_wback_inv(_start,_size)       do { } while (0)
+
 # endif /* __KERNEL__ */
+
 #endif /* _ASM_IA64_IO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/irq.h linux/include/asm-ia64/irq.h
--- linux.orig/include/asm-ia64/irq.h	2000-03-10 23:24:02.000000000 +0000
+++ linux/include/asm-ia64/irq.h	2002-07-20 01:08:35.000000000 +0000
@@ -2,9 +2,9 @@
 #define _ASM_IA64_IRQ_H
 
 /*
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1998 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
  *
  * 11/24/98	S.Eranian 	updated TIMER_IRQ and irq_cannonicalize
  * 01/20/99	S.Eranian	added keyboard interrupt
@@ -27,5 +27,6 @@
 extern void disable_irq (unsigned int);
 extern void disable_irq_nosync (unsigned int);
 extern void enable_irq (unsigned int);
+extern void set_irq_affinity_info (int irq, int dest, int redir);
 
 #endif /* _ASM_IA64_IRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/machvec.h linux/include/asm-ia64/machvec.h
--- linux.orig/include/asm-ia64/machvec.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/machvec.h	2002-07-20 01:08:22.000000000 +0000
@@ -20,6 +20,7 @@
 struct irq_desc;
 
 typedef void ia64_mv_setup_t (char **);
+typedef void ia64_mv_cpu_init_t(void);
 typedef void ia64_mv_irq_init_t (void);
 typedef void ia64_mv_pci_fixup_t (int);
 typedef unsigned long ia64_mv_map_nr_t (unsigned long);
@@ -77,6 +78,7 @@
 # else
 #  define platform_name		ia64_mv.name
 #  define platform_setup	ia64_mv.setup
+#  define platform_cpu_init	ia64_mv.cpu_init
 #  define platform_irq_init	ia64_mv.irq_init
 #  define platform_map_nr	ia64_mv.map_nr
 #  define platform_mca_init	ia64_mv.mca_init
@@ -110,6 +112,7 @@
 struct ia64_machine_vector {
 	const char *name;
 	ia64_mv_setup_t *setup;
+	ia64_mv_cpu_init_t *cpu_init;
 	ia64_mv_irq_init_t *irq_init;
 	ia64_mv_pci_fixup_t *pci_fixup;
 	ia64_mv_map_nr_t *map_nr;
@@ -201,6 +204,9 @@
 #ifndef platform_setup
 # define platform_setup		((ia64_mv_setup_t *) machvec_noop)
 #endif
+#ifndef platform_cpu_init
+# define platform_cpu_init	((ia64_mv_cpu_init_t *) machvec_noop)
+#endif
 #ifndef platform_irq_init
 # define platform_irq_init	((ia64_mv_irq_init_t *) machvec_noop)
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/machvec_sn1.h linux/include/asm-ia64/machvec_sn1.h
--- linux.orig/include/asm-ia64/machvec_sn1.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/machvec_sn1.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,27 +1,64 @@
+/*
+ * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
 #ifndef _ASM_IA64_MACHVEC_SN1_h
 #define _ASM_IA64_MACHVEC_SN1_h
 
-extern ia64_mv_setup_t sn1_setup;
-extern ia64_mv_irq_init_t sn1_irq_init;
+extern ia64_mv_setup_t sn_setup;
+extern ia64_mv_cpu_init_t sn_cpu_init;
+extern ia64_mv_irq_init_t sn_irq_init;
 extern ia64_mv_map_nr_t sn1_map_nr;
 extern ia64_mv_send_ipi_t sn1_send_IPI;
 extern ia64_mv_global_tlb_purge_t sn1_global_tlb_purge;
-extern ia64_mv_pci_fixup_t sn1_pci_fixup;
-extern ia64_mv_inb_t sn1_inb;
-extern ia64_mv_inw_t sn1_inw;
-extern ia64_mv_inl_t sn1_inl;
-extern ia64_mv_outb_t sn1_outb;
-extern ia64_mv_outw_t sn1_outw;
-extern ia64_mv_outl_t sn1_outl;
-extern ia64_mv_pci_alloc_consistent	sn1_pci_alloc_consistent;
-extern ia64_mv_pci_free_consistent	sn1_pci_free_consistent;
-extern ia64_mv_pci_map_single		sn1_pci_map_single;
-extern ia64_mv_pci_unmap_single		sn1_pci_unmap_single;
-extern ia64_mv_pci_map_sg		sn1_pci_map_sg;
-extern ia64_mv_pci_unmap_sg		sn1_pci_unmap_sg;
-extern ia64_mv_pci_dma_sync_single	sn1_pci_dma_sync_single;
-extern ia64_mv_pci_dma_sync_sg		sn1_pci_dma_sync_sg;
-extern ia64_mv_pci_dma_address		sn1_dma_address;
+extern ia64_mv_irq_desc sn_irq_desc;
+extern ia64_mv_irq_to_vector sn_irq_to_vector;
+extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq;
+extern ia64_mv_valid_irq sn_valid_irq;
+extern ia64_mv_pci_fixup_t sn_pci_fixup;
+extern ia64_mv_inb_t sn_inb;
+extern ia64_mv_inw_t sn_inw;
+extern ia64_mv_inl_t sn_inl;
+extern ia64_mv_outb_t sn_outb;
+extern ia64_mv_outw_t sn_outw;
+extern ia64_mv_outl_t sn_outl;
+extern ia64_mv_pci_alloc_consistent	sn_pci_alloc_consistent;
+extern ia64_mv_pci_free_consistent	sn_pci_free_consistent;
+extern ia64_mv_pci_map_single		sn_pci_map_single;
+extern ia64_mv_pci_unmap_single		sn_pci_unmap_single;
+extern ia64_mv_pci_map_sg		sn_pci_map_sg;
+extern ia64_mv_pci_unmap_sg		sn_pci_unmap_sg;
+extern ia64_mv_pci_dma_sync_single	sn_pci_dma_sync_single;
+extern ia64_mv_pci_dma_sync_sg		sn_pci_dma_sync_sg;
+extern ia64_mv_pci_dma_address		sn_dma_address;
 
 /*
  * This stuff has dual use!
@@ -30,28 +67,33 @@
  * platform's machvec structure.  When compiling a non-generic kernel,
  * the macros are used directly.
  */
-#define platform_name		"sn1"
-#define platform_setup		sn1_setup
-#define platform_irq_init	sn1_irq_init
-#define platform_map_nr		sn1_map_nr
-#define platform_send_ipi	sn1_send_IPI
+#define platform_name			"sn1"
+#define platform_setup			sn_setup
+#define platform_cpu_init		sn_cpu_init
+#define platform_irq_init		sn_irq_init
+#define platform_map_nr			sn_map_nr
+#define platform_send_ipi		sn1_send_IPI
 #define platform_global_tlb_purge       sn1_global_tlb_purge
-#define platform_pci_fixup	sn1_pci_fixup
-#define platform_inb		sn1_inb
-#define platform_inw		sn1_inw
-#define platform_inl		sn1_inl
-#define platform_outb		sn1_outb
-#define platform_outw		sn1_outw
-#define platform_outl		sn1_outl
-#define platform_pci_dma_init	machvec_noop
-#define platform_pci_alloc_consistent	sn1_pci_alloc_consistent
-#define platform_pci_free_consistent	sn1_pci_free_consistent
-#define platform_pci_map_single		sn1_pci_map_single
-#define platform_pci_unmap_single	sn1_pci_unmap_single
-#define platform_pci_map_sg		sn1_pci_map_sg
-#define platform_pci_unmap_sg		sn1_pci_unmap_sg
-#define platform_pci_dma_sync_single	sn1_pci_dma_sync_single
-#define platform_pci_dma_sync_sg	sn1_pci_dma_sync_sg
-#define platform_pci_dma_address	sn1_dma_address
+#define platform_pci_fixup		sn_pci_fixup
+#define platform_inb			sn_inb
+#define platform_inw			sn_inw
+#define platform_inl			sn_inl
+#define platform_outb			sn_outb
+#define platform_outw			sn_outw
+#define platform_oul			sn_outl
+#define platform_irq_desc		sn_irq_desc
+#define platform_irq_to_vector		sn_irq_to_vector
+#define platform_local_vector_to_irq	sn_local_vector_to_irq
+#define platform_valid_irq		sn_valid_irq
+#define platform_pci_dma_init		machvec_noop
+#define platform_pci_alloc_consistent	sn_pci_alloc_consistent
+#define platform_pci_free_consistent	sn_pci_free_consistent
+#define platform_pci_map_single		sn_pci_map_single
+#define platform_pci_unmap_single	sn_pci_unmap_single
+#define platform_pci_map_sg		sn_pci_map_sg
+#define platform_pci_unmap_sg		sn_pci_unmap_sg
+#define platform_pci_dma_sync_single	sn_pci_dma_sync_single
+#define platform_pci_dma_sync_sg	sn_pci_dma_sync_sg
+#define platform_pci_dma_address	sn_dma_address
 
 #endif /* _ASM_IA64_MACHVEC_SN1_h */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/machvec_sn2.h linux/include/asm-ia64/machvec_sn2.h
--- linux.orig/include/asm-ia64/machvec_sn2.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/machvec_sn2.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#ifndef _ASM_IA64_MACHVEC_SN2_H
+#define _ASM_IA64_MACHVEC_SN2_H
+
+extern ia64_mv_setup_t sn_setup;
+extern ia64_mv_cpu_init_t sn_cpu_init;
+extern ia64_mv_irq_init_t sn_irq_init;
+extern ia64_mv_map_nr_t sn2_map_nr;
+extern ia64_mv_send_ipi_t sn2_send_IPI;
+extern ia64_mv_global_tlb_purge_t sn2_global_tlb_purge;
+extern ia64_mv_irq_desc sn_irq_desc;
+extern ia64_mv_irq_to_vector sn_irq_to_vector;
+extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq;
+extern ia64_mv_valid_irq sn_valid_irq;
+extern ia64_mv_pci_fixup_t sn_pci_fixup;
+extern ia64_mv_inb_t sn_inb;
+extern ia64_mv_inw_t sn_inw;
+extern ia64_mv_inl_t sn_inl;
+extern ia64_mv_outb_t sn_outb;
+extern ia64_mv_outw_t sn_outw;
+extern ia64_mv_outl_t sn_outl;
+extern ia64_mv_pci_alloc_consistent	sn_pci_alloc_consistent;
+extern ia64_mv_pci_free_consistent	sn_pci_free_consistent;
+extern ia64_mv_pci_map_single		sn_pci_map_single;
+extern ia64_mv_pci_unmap_single		sn_pci_unmap_single;
+extern ia64_mv_pci_map_sg		sn_pci_map_sg;
+extern ia64_mv_pci_unmap_sg		sn_pci_unmap_sg;
+extern ia64_mv_pci_dma_sync_single	sn_pci_dma_sync_single;
+extern ia64_mv_pci_dma_sync_sg		sn_pci_dma_sync_sg;
+extern ia64_mv_pci_dma_address		sn_dma_address;
+
+/*
+ * This stuff has dual use!
+ *
+ * For a generic kernel, the macros are used to initialize the
+ * platform's machvec structure.  When compiling a non-generic kernel,
+ * the macros are used directly.
+ */
+#define platform_name			"sn2"
+#define platform_setup			sn_setup
+#define platform_cpu_init		sn_cpu_init
+#define platform_irq_init		sn_irq_init
+#define platform_map_nr			sn2_map_nr
+#define platform_send_ipi		sn2_send_IPI
+#define platform_global_tlb_purge       sn2_global_tlb_purge
+#define platform_pci_fixup		sn_pci_fixup
+#define platform_inb			sn_inb
+#define platform_inw			sn_inw
+#define platform_inl			sn_inl
+#define platform_outb			sn_outb
+#define platform_outw			sn_outw
+#define platform_oul			sn_outl
+#define platform_irq_desc		sn_irq_desc
+#define platform_irq_to_vector		sn_irq_to_vector
+#define platform_local_vector_to_irq	sn_local_vector_to_irq
+#define platform_valid_irq		sn_valid_irq
+#define platform_pci_dma_init		machvec_noop
+#define platform_pci_alloc_consistent	sn_pci_alloc_consistent
+#define platform_pci_free_consistent	sn_pci_free_consistent
+#define platform_pci_map_single		sn_pci_map_single
+#define platform_pci_unmap_single	sn_pci_unmap_single
+#define platform_pci_map_sg		sn_pci_map_sg
+#define platform_pci_unmap_sg		sn_pci_unmap_sg
+#define platform_pci_dma_sync_single	sn_pci_dma_sync_single
+#define platform_pci_dma_sync_sg	sn_pci_dma_sync_sg
+#define platform_pci_dma_address	sn_dma_address
+
+#endif /* _ASM_IA64_MACHVEC_SN2_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/mca.h linux/include/asm-ia64/mca.h
--- linux.orig/include/asm-ia64/mca.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/mca.h	2002-07-20 01:08:28.000000000 +0000
@@ -7,9 +7,6 @@
  * Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
  */
 
-/* XXX use this temporary define for MP systems trying to INIT */
-#undef SAL_MPINIT_WORKAROUND
-
 #ifndef _ASM_IA64_MCA_H
 #define _ASM_IA64_MCA_H
 
@@ -101,12 +98,19 @@
 	IA64_MCA_HALT		=	-3	/* System to be halted by SAL */
 };
 
+enum {
+	IA64_MCA_SAME_CONTEXT	=	0x0,	/* SAL to return to same context */
+	IA64_MCA_NEW_CONTEXT	=	-1	/* SAL to return to new context */
+};
+
 typedef struct ia64_mca_os_to_sal_state_s {
 	u64		imots_os_status;	/*   OS status to SAL as to what happened
 						 *   with the MCA handling.
 						 */
 	u64		imots_sal_gp;		/* GP of the SAL - physical */
-	u64		imots_new_min_state;	/* Pointer to structure containing
+	u64		imots_context;		/* 0 if return to same context
+						   1 if return to new context */
+	u64		*imots_new_min_state;	/* Pointer to structure containing
 						 * new values of registers in the min state
 						 * save area.
 						 */
@@ -127,13 +131,20 @@
 extern void ia64_mca_wakeup_int_handler(int,void *,struct pt_regs *);
 extern void ia64_mca_cmc_int_handler(int,void *,struct pt_regs *);
 extern void ia64_mca_cpe_int_handler(int,void *,struct pt_regs *);
-extern void ia64_log_print(int,prfunc_t);
+extern int  ia64_log_print(int,prfunc_t);
 extern void ia64_mca_cmc_vector_setup(void);
 extern void ia64_mca_check_errors( void );
 extern u64  ia64_log_get(int, prfunc_t);
 
 #define PLATFORM_CALL(fn, args)	printk("Platform call TBD\n")
 
+#define platform_mem_dev_err_print ia64_log_prt_oem_data
+#define platform_pci_bus_err_print ia64_log_prt_oem_data
+#define platform_pci_comp_err_print ia64_log_prt_oem_data
+#define platform_plat_specific_err_print ia64_log_prt_oem_data
+#define platform_host_ctlr_err_print ia64_log_prt_oem_data
+#define platform_plat_bus_err_print ia64_log_prt_oem_data
+
 #undef	MCA_TEST
 
 #undef IA64_MCA_DEBUG_INFO
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/mca_asm.h linux/include/asm-ia64/mca_asm.h
--- linux.orig/include/asm-ia64/mca_asm.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/mca_asm.h	2002-07-20 01:08:40.000000000 +0000
@@ -6,6 +6,8 @@
  * Copyright (C) Srinivasa Thirumalachar <sprasad@engr.sgi.com>
  * Copyright (C) 2000 Hewlett-Packard Co.
  * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com>
  */
 #ifndef _ASM_IA64_MCA_ASM_H
 #define _ASM_IA64_MCA_ASM_H
@@ -24,7 +26,7 @@
  *	1. Lop off bits 61 thru 63 in the virtual address
  */
 #define INST_VA_TO_PA(addr)							\
-	dep	addr	= 0, addr, 61, 3;
+	dep	addr	= 0, addr, 61, 3
 /*
  * This macro converts a data virtual address to a physical address
  * Right now for simulation purposes the virtual addresses are
@@ -32,7 +34,7 @@
  *	1. Lop off bits 61 thru 63 in the virtual address
  */
 #define DATA_VA_TO_PA(addr)							\
-	dep	addr	= 0, addr, 61, 3;
+	dep	addr	= 0, addr, 61, 3
 /*
  * This macro converts a data physical address to a virtual address
  * Right now for simulation purposes the virtual addresses are
@@ -41,7 +43,7 @@
  */
 #define DATA_PA_TO_VA(addr,temp)							\
 	mov	temp	= 0x7	;;							\
-	dep	addr	= temp, addr, 61, 3;;
+	dep	addr	= temp, addr, 61, 3
 
 /*
  * This macro jumps to the instruction at the given virtual address
@@ -112,8 +114,8 @@
 	;;										\
 	mov	cr.iip = temp2;								\
 	mov	cr.ifs = r0;								\
-	DATA_VA_TO_PA(sp)								\
-	DATA_VA_TO_PA(gp)								\
+	DATA_VA_TO_PA(sp);								\
+	DATA_VA_TO_PA(gp);								\
 	;;										\
 	srlz.i;										\
 	;;										\
@@ -130,8 +132,7 @@
  * translations turned on.
  *	1.	Get the old saved psr
  *
- *	2.	Clear the interrupt enable and interrupt state collection bits
- *		in the current psr.
+ *	2.	Clear the interrupt state collection bit in the current psr.
  *
  *	3.	Set the instruction translation bit back in the old psr
  *		Note we have to do this since we are right now saving only the
@@ -140,9 +141,11 @@
  *
  *	4.	Set ipsr to this old_psr with "it" bit set and "bn" = 1.
  *
- *	5.	Set iip to the virtual address of the next instruction bundle.
+ *	5.	Reset the current thread pointer (r13).
  *
- *	6.	Do an rfi to move ipsr to psr and iip to ip.
+ *	6.	Set iip to the virtual address of the next instruction bundle.
+ *
+ *	7.	Do an rfi to move ipsr to psr and iip to ip.
  */
 
 #define VIRTUAL_MODE_ENTER(temp1, temp2, start_addr, old_psr)	\
@@ -156,6 +159,10 @@
 	mov	ar.rsc = 0;					\
 	;;							\
 	srlz.d;							\
+	mov	r13 = ar.k6;					\
+	;;							\
+	DATA_PA_TO_VA(r13,temp1);				\
+	;;							\
 	mov	temp2 = ar.bspstore;				\
 	;;							\
 	DATA_PA_TO_VA(temp2,temp1);				\
@@ -170,8 +177,6 @@
 	;;							\
 	mov	temp2 = 1;					\
 	;;							\
-	dep	temp1 = temp2, temp1, PSR_I,  1;		\
-	;;							\
 	dep	temp1 = temp2, temp1, PSR_IC, 1;		\
 	;;							\
 	dep	temp1 = temp2, temp1, PSR_IT, 1;		\
@@ -195,7 +200,7 @@
 	nop	1;						\
 	nop	2;						\
 	nop	1;						\
-	rfi;							\
+	rfi							\
 	;;
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/offsets.h linux/include/asm-ia64/offsets.h
--- linux.orig/include/asm-ia64/offsets.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/offsets.h	2002-07-20 01:08:37.000000000 +0000
@@ -8,7 +8,7 @@
  */
 #define PT_PTRACED_BIT		0
 #define PT_TRACESYS_BIT		1
-#define IA64_TASK_SIZE			3408	/* 0xd50 */
+#define IA64_TASK_SIZE			3936	/* 0xf60 */
 #define IA64_PT_REGS_SIZE		400	/* 0x190 */
 #define IA64_SWITCH_STACK_SIZE		560	/* 0x230 */
 #define IA64_SIGINFO_SIZE		128	/* 0x80 */
@@ -19,11 +19,11 @@
 #define IA64_TASK_PTRACE_OFFSET		48	/* 0x30 */
 #define IA64_TASK_SIGPENDING_OFFSET	16	/* 0x10 */
 #define IA64_TASK_NEED_RESCHED_OFFSET	40	/* 0x28 */
-#define IA64_TASK_PROCESSOR_OFFSET	100	/* 0x64 */
-#define IA64_TASK_THREAD_OFFSET		976	/* 0x3d0 */
-#define IA64_TASK_THREAD_KSP_OFFSET	976	/* 0x3d0 */
-#define IA64_TASK_PFM_MUST_BLOCK_OFFSET	1600	/* 0x640 */
-#define IA64_TASK_PID_OFFSET		220	/* 0xdc */
+#define IA64_TASK_PROCESSOR_OFFSET	96	/* 0x60 */
+#define IA64_TASK_THREAD_OFFSET		1488	/* 0x5d0 */
+#define IA64_TASK_THREAD_KSP_OFFSET	1488	/* 0x5d0 */
+#define IA64_TASK_PFM_OVFL_BLOCK_RESET_OFFSET 2112	/* 0x840 */
+#define IA64_TASK_PID_OFFSET		228	/* 0xe4 */
 #define IA64_TASK_MM_OFFSET		88	/* 0x58 */
 #define IA64_PT_REGS_CR_IPSR_OFFSET	0	/* 0x0 */
 #define IA64_PT_REGS_CR_IIP_OFFSET	8	/* 0x8 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/page.h linux/include/asm-ia64/page.h
--- linux.orig/include/asm-ia64/page.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/page.h	2002-07-20 01:08:26.000000000 +0000
@@ -148,6 +148,11 @@
 # define __pgprot(x)	(x)
 #endif /* !STRICT_MM_TYPECHECKS */
 
-#define PAGE_OFFSET		0xe000000000000000
+#define PAGE_OFFSET			0xe000000000000000
+
+#define VM_DATA_DEFAULT_FLAGS		(VM_READ | VM_WRITE |					\
+					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC |		\
+					 (((current->thread.flags & IA64_THREAD_XSTACK) != 0)	\
+					  ? VM_EXEC : 0))
 
 #endif /* _ASM_IA64_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/pci.h linux/include/asm-ia64/pci.h
--- linux.orig/include/asm-ia64/pci.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-ia64/pci.h	2002-07-20 01:08:33.000000000 +0000
@@ -47,18 +47,12 @@
 #define sg_dma_address			platform_pci_dma_address
 
 /* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
-	dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		\
-	__u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)			\
-	((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)		\
-	(((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)			\
-	((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
-	(((PTR)->LEN_NAME) = (VAL))
+#define DECLARE_PCI_UNMAP_ADDR(addr_name)	dma_addr_t addr_name;
+#define DECLARE_PCI_UNMAP_LEN(len_name)		__u32 len_name;
+#define pci_unmap_addr(ptr, addr_name)		((ptr)->addr_name)
+#define pci_unmap_addr_set(ptr, addr_name, val)	(((ptr)->addr_name) = (val))
+#define pci_unmap_len(ptr, len_name)		((ptr)->len_name)
+#define pci_unmap_len_set(ptr, len_name, val)	(((ptr)->len_name) = (val))
 
 /*
  * Return whether the given PCI device DMA address mask can be supported properly.  For
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/perfmon.h linux/include/asm-ia64/perfmon.h
--- linux.orig/include/asm-ia64/perfmon.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/perfmon.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,55 +1,176 @@
 /*
- * Copyright (C) 2001 Hewlett-Packard Co
- * Copyright (C) 2001 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 2001-2002 Hewlett-Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
  */
 
 #ifndef _ASM_IA64_PERFMON_H
 #define _ASM_IA64_PERFMON_H
 
-#include <linux/types.h>
+/*
+ * perfmon comamnds supported on all CPU models
+ */
+#define PFM_WRITE_PMCS		0x01
+#define PFM_WRITE_PMDS		0x02
+#define PFM_READ_PMDS		0x03
+#define PFM_STOP		0x04
+#define PFM_START		0x05
+#define PFM_ENABLE		0x06
+#define PFM_DISABLE		0x07
+#define PFM_CREATE_CONTEXT	0x08
+#define PFM_DESTROY_CONTEXT	0x09
+#define PFM_RESTART		0x0a
+#define PFM_PROTECT_CONTEXT	0x0b
+#define PFM_GET_FEATURES	0x0c
+#define PFM_DEBUG		0x0d
+#define PFM_UNPROTECT_CONTEXT	0x0e
+
+
+/*
+ * CPU model specific commands (may not be supported on all models)
+ */
+#define PFM_WRITE_IBRS		0x20
+#define PFM_WRITE_DBRS		0x21
+
+/*
+ * context flags
+ */
+#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_NOTIFY_BLOCK    	 0x04	/* block task on user level notifications */
+#define PFM_FL_SYSTEM_WIDE	 0x08	/* create a system wide context */
+
+/*
+ * PMC flags
+ */
+#define PFM_REGFL_OVFL_NOTIFY	0x1	/* send notification on overflow */
+
+/*
+ * PMD/PMC/IBR/DBR return flags (ignored on input)
+ *
+ * Those flags are used on output and must be checked in case EAGAIN is returned
+ * by any of the calls using a pfarg_reg_t or pfarg_dbreg_t structure.
+ */
+#define PFM_REG_RETFL_NOTAVAIL	(1U<<31) /* set if register is implemented but not available */
+#define PFM_REG_RETFL_EINVAL	(1U<<30) /* set if register entry is invalid */
+#define PFM_REG_RETFL_MASK	(PFM_REG_RETFL_NOTAVAIL|PFM_REG_RETFL_EINVAL)
+
+#define PFM_REG_HAS_ERROR(flag)	(((flag) & PFM_REG_RETFL_MASK) != 0)
 
 /*
  * Request structure used to define a context
  */
 typedef struct {
-	unsigned long smpl_entries;	/* how many entries in sampling buffer */
-	unsigned long smpl_regs;	/* which pmds to record on overflow */
-	void	      *smpl_vaddr;	/* returns address of BTB buffer */
+	unsigned long ctx_smpl_entries;	/* how many entries in sampling buffer */
+	unsigned long ctx_smpl_regs[4];	/* which pmds to record on overflow */
 
-	pid_t	      notify_pid;	/* which process to notify on overflow */
-	int	      notify_sig; 	/* XXX: not used anymore */
+	pid_t	      ctx_notify_pid;	/* which process to notify on overflow */
+	int	      ctx_flags;	/* noblock/block, inherit flags */
+	void	      *ctx_smpl_vaddr;	/* returns address of BTB buffer */
 
-	int	      flags;		/* NOBLOCK/BLOCK/ INHERIT flags (will replace API flags) */
-} pfreq_context_t;
+	unsigned long ctx_cpu_mask;	/* on which CPU to enable perfmon (systemwide) */
+
+	unsigned long reserved[8];	/* for future use */
+} pfarg_context_t;
 
 /*
  * Request structure used to write/read a PMC or PMD
  */
 typedef struct {
-	unsigned long	reg_num;	/* which register */
+	unsigned int	reg_num;	/* which register */
+	unsigned int	reg_flags;	/* PMC: notify/don't notify. PMD/PMC: return flags */
 	unsigned long	reg_value;	/* configuration (PMC) or initial value (PMD) */
-	unsigned long	reg_smpl_reset;	/* reset of sampling buffer overflow (large) */
-	unsigned long	reg_ovfl_reset;	/* reset on counter overflow (small) */
-	int		reg_flags;	/* (PMD): notify/don't notify */
-} pfreq_reg_t;
+
+	unsigned long	reg_long_reset;	/* reset after sampling buffer overflow (large) */
+	unsigned long	reg_short_reset;/* reset after counter overflow (small) */
+
+	unsigned long	reg_reset_pmds[4]; /* which other counters to reset on overflow */
+
+	unsigned long   reserved[16];	/* for future use */
+} pfarg_reg_t;
+
+typedef struct {
+	unsigned int	dbreg_num;	/* which register */
+	unsigned int	dbreg_flags;	/* dbregs return flags */
+	unsigned long	dbreg_value;	/* configuration (PMC) or initial value (PMD) */
+	unsigned long	reserved[6];
+} pfarg_dbreg_t;
+
+typedef struct {			
+	unsigned int	ft_version;	/* perfmon: major [16-31], minor [0-15] */
+	unsigned int	ft_smpl_version;/* sampling format: major [16-31], minor [0-15] */
+	unsigned long	reserved[4];	/* for future use */
+} pfarg_features_t;
 
 /*
- * main request structure passed by user
- */
-typedef union {
-	pfreq_context_t	pfr_ctx;	/* request to configure a context */
-	pfreq_reg_t	pfr_reg;	/* request to configure a PMD/PMC */
-} perfmon_req_t;
+ * 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 by the
+ * first record.
+ */
+typedef struct {
+	unsigned int	hdr_version;		/* contains perfmon version (smpl format diffs) */
+	unsigned int	reserved;
+	unsigned long	hdr_entry_size;		/* size of one entry in bytes */
+	unsigned long	hdr_count;		/* how many valid entries */
+	unsigned long	hdr_pmds[4];		/* which pmds are recorded */
+} perfmon_smpl_hdr_t;
+
+/*
+ * Define the version numbers for both perfmon as a whole and the sampling buffer format.
+ */
+#define PFM_VERSION_MAJ		1U
+#define PFM_VERSION_MIN		0U
+#define PFM_VERSION		(((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
+
+#define PFM_SMPL_VERSION_MAJ	1U
+#define PFM_SMPL_VERSION_MIN	0U
+#define PFM_SMPL_VERSION	(((PFM_SMPL_VERSION_MAJ&0xffff)<<16)|(PFM_SMPL_VERSION_MIN & 0xffff))
+
+
+#define PFM_VERSION_MAJOR(x)	(((x)>>16) & 0xffff)
+#define PFM_VERSION_MINOR(x)	((x) & 0xffff)
+
+/*
+ * Entry header in the sampling buffer.
+ * The header is directly followed with the PMDS saved in increasing index 
+ * order: PMD4, PMD5, .... How many PMDs are present is determined by the 
+ * user program during context creation.
+ *
+ * XXX: in this version of the entry, only up to 64 registers can be recorded
+ * This should be enough for quite some time. Always check sampling format
+ * before parsing entries!
+ *
+ * Inn the case where multiple counters have overflowed at the same time, the 
+ * rate field indicate the initial value of the first PMD, based on the index.
+ * For instance, if PMD2 and PMD5 have ovewrflowed for this entry, the rate field
+ * will show the initial value of PMD2.
+ */
+typedef struct {
+	int		pid;		/* identification of process */
+	int		cpu;		/* which cpu was used */
+	unsigned long	rate;		/* initial value of overflowed counter */
+	unsigned long	stamp;		/* timestamp */
+	unsigned long	ip;		/* where did the overflow interrupt happened */
+	unsigned long	regs;		/* bitmask of which registers overflowed */
+	unsigned long   period;		/* sampling period used by overflowed counter (smallest pmd index) */
+} perfmon_smpl_entry_t;
+
+extern int perfmonctl(pid_t pid, int cmd, void *arg, int narg);
 
 #ifdef __KERNEL__
 
 extern void pfm_save_regs (struct task_struct *);
 extern void pfm_load_regs (struct task_struct *);
 
-extern int pfm_inherit (struct task_struct *, struct pt_regs *);
+extern int  pfm_inherit (struct task_struct *, struct pt_regs *);
 extern void pfm_context_exit (struct task_struct *);
 extern void pfm_flush_regs (struct task_struct *);
 extern void pfm_cleanup_notifiers (struct task_struct *);
+extern void pfm_cleanup_owners (struct task_struct *);
+extern int  pfm_use_debug_registers(struct task_struct *);
+extern int  pfm_release_debug_registers(struct task_struct *);
+extern int  pfm_cleanup_smpl_buf(struct task_struct *);
+extern void pfm_syst_wide_update_task(struct task_struct *, int);
 
 #endif /* __KERNEL__ */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/pgtable.h linux/include/asm-ia64/pgtable.h
--- linux.orig/include/asm-ia64/pgtable.h	2001-11-11 18:20:21.000000000 +0000
+++ linux/include/asm-ia64/pgtable.h	2002-07-20 01:08:31.000000000 +0000
@@ -8,7 +8,7 @@
  * This hopefully works with any (fixed) IA-64 page-size, as defined
  * in <asm/page.h> (currently 8192).
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -108,19 +108,15 @@
 /*
  * All the normal masks have the "page accessed" bits on, as any time
  * they are used, the page is accessed. They are cleared only by the
- * page-out routines.  On the other hand, we do NOT turn on the
- * execute bit on pages that are mapped writable.  For those pages, we
- * turn on the X bit only when the program attempts to actually
- * execute code in such a page (it's a "lazy execute bit", if you
- * will).  This lets reduce the amount of i-cache flushing we have to
- * do for data pages such as stack and heap pages.
+ * page-out routines.
  */
 #define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_A)
 #define PAGE_SHARED	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
 #define PAGE_READONLY	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
-#define PAGE_COPY	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
+#define PAGE_COPY	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
 #define PAGE_GATE	__pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
 #define PAGE_KERNEL	__pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
+#define PAGE_KERNELRX	__pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
 
 # ifndef __ASSEMBLY__
 
@@ -152,8 +148,8 @@
 #define __S011	PAGE_SHARED
 #define __S100	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX)
 #define __S101	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
-#define __S110	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
-#define __S111	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
+#define __S110	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX)
+#define __S111	__pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX)
 
 #define pgd_ERROR(e)	printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
 #define pmd_ERROR(e)	printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
@@ -165,11 +161,6 @@
  * addresses:
  */
 
-/*
- * Given a pointer to an mem_map[] entry, return the kernel virtual
- * address corresponding to that page.
- */
-#define page_address(page)	((page)->virtual)
 
 /* Quick test to see if ADDR is a (potentially) valid physical address. */
 static inline long
@@ -178,6 +169,7 @@
 	return (addr & (local_cpu_data->unimpl_pa_mask)) == 0;
 }
 
+#ifndef CONFIG_DISCONTIGMEM
 /*
  * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel
  * memory.  For the return value to be meaningful, ADDR must be >=
@@ -193,6 +185,8 @@
  */
 #define kern_addr_valid(addr)	(1)
 
+#endif
+
 /*
  * Now come the defines and routines to manage and access the three-level
  * page table.
@@ -237,8 +231,10 @@
 #define pte_none(pte) 			(!pte_val(pte))
 #define pte_present(pte)		(pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
 #define pte_clear(pte)			(pte_val(*(pte)) = 0UL)
+#ifndef CONFIG_DISCONTIGMEM
 /* pte_page() returns the "struct page *" corresponding to the PTE: */
 #define pte_page(pte)			(mem_map + (unsigned long) ((pte_val(pte) & _PFN_MASK) >> PAGE_SHIFT))
+#endif
 
 #define pmd_none(pmd)			(!pmd_val(pmd))
 #define pmd_bad(pmd)			(!ia64_phys_addr_valid(pmd_val(pmd)))
@@ -423,22 +419,6 @@
 	return pte_val(a) == pte_val(b);
 }
 
-/*
- * Macros to check the type of access that triggered a page fault.
- */
-
-static inline int
-is_write_access (int access_type)
-{
-	return (access_type & 0x2);
-}
-
-static inline int
-is_exec_access (int access_type)
-{
-	return (access_type & 0x4);
-}
-
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern void paging_init (void);
 
@@ -463,6 +443,11 @@
 /* We provide our own get_unmapped_area to cope with VA holes for userland */
 #define HAVE_ARCH_UNMAPPED_AREA
 
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()	do { } while (0)
+
 # endif /* !__ASSEMBLY__ */
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/processor.h linux/include/asm-ia64/processor.h
--- linux.orig/include/asm-ia64/processor.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/processor.h	2002-07-20 01:08:32.000000000 +0000
@@ -2,9 +2,9 @@
 #define _ASM_IA64_PROCESSOR_H
 
 /*
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1998-2001 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  *
@@ -14,6 +14,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/cache.h>
 
 #include <asm/ptrace.h>
 #include <asm/kregs.h>
@@ -27,7 +28,6 @@
  */
 #define IA64_NUM_PMC_REGS	32
 #define IA64_NUM_PMD_REGS	32
-#define IA64_NUM_PMD_COUNTERS	4
 
 #define DEFAULT_MAP_BASE	0x2000000000000000
 #define DEFAULT_TASK_SIZE	0xa000000000000000
@@ -170,6 +170,7 @@
 #define IA64_THREAD_KRBS_SYNCED	(__IA64_UL(1) << 5)	/* krbs synced with process vm? */
 #define IA64_THREAD_FPEMU_NOPRINT (__IA64_UL(1) << 6)	/* don't log any fpswa faults */
 #define IA64_THREAD_FPEMU_SIGFPE  (__IA64_UL(1) << 7)	/* send a SIGFPE for fpswa faults */
+#define IA64_THREAD_XSTACK	(__IA64_UL(1) << 8)	/* stack executable by default? */
 
 #define IA64_THREAD_UAC_SHIFT	3
 #define IA64_THREAD_UAC_MASK	(IA64_THREAD_UAC_NOPRINT | IA64_THREAD_UAC_SIGBUS)
@@ -275,15 +276,23 @@
 	__u32 ptce_stride[2];
 	struct task_struct *ksoftirqd;	/* kernel softirq daemon for this CPU */
 #ifdef CONFIG_SMP
+	int processor;
 	__u64 loops_per_jiffy;
 	__u64 ipi_count;
 	__u64 prof_counter;
 	__u64 prof_multiplier;
-	__u64 ipi_operation;
+	__u32 pfm_syst_wide;
+	__u32 pfm_dcr_pp;
+	/* this is written to by *other* CPUs: */
+	__u64 ipi_operation ____cacheline_aligned;
 #endif
 #ifdef CONFIG_NUMA
+	void *node_directory;
+	int numa_node_id;
 	struct cpuinfo_ia64 *cpu_data[NR_CPUS];
 #endif
+	/* Platform specific word.  MUST BE LAST IN STRUCT */
+	__u64 platform_specific;
 } __attribute__ ((aligned (PAGE_SIZE))) ;
 
 /*
@@ -303,7 +312,8 @@
  * the array.
  */
 #ifdef CONFIG_NUMA
-# define cpu_data(cpu)		local_cpu_data->cpu_data_ptrs[cpu]
+# define cpu_data(cpu)		local_cpu_data->cpu_data[cpu]
+# define numa_node_id()		(local_cpu_data->numa_node_id)
 #else
   extern struct cpuinfo_ia64 _cpu_data[NR_CPUS];
 # define cpu_data(cpu)		(&_cpu_data[cpu])
@@ -366,10 +376,12 @@
 #ifdef CONFIG_PERFMON
 	__u64 pmc[IA64_NUM_PMC_REGS];
 	__u64 pmd[IA64_NUM_PMD_REGS];
-	unsigned long pfm_must_block;	/* non-zero if we need to block on overflow */
+	unsigned long pfm_ovfl_block_reset;/* non-zero if we need to block or reset regs on ovfl */
 	void *pfm_context;		/* pointer to detailed PMU context */
-	atomic_t pfm_notifiers_check;	/* indicate if release_thread much check tasklist */
-# define INIT_THREAD_PM		{0, }, {0, }, 0, 0, {0},
+	atomic_t pfm_notifiers_check;	/* when >0, will cleanup ctx_notify_task in tasklist */
+	atomic_t pfm_owners_check;	/* when >0, will cleanup ctx_owner in tasklist */
+	void *pfm_smpl_buf_list;	/* list of sampling buffers to vfree */
+# define INIT_THREAD_PM		{0, }, {0, }, 0, NULL, {0}, {0}, NULL,
 #else
 # define INIT_THREAD_PM
 #endif
@@ -398,6 +410,7 @@
 	ia64_psr(regs)->cpl = 3;	/* set user mode */					\
 	ia64_psr(regs)->ri = 0;		/* clear return slot number */				\
 	ia64_psr(regs)->is = 0;		/* IA-64 instruction set */				\
+	ia64_psr(regs)->sp = 1;		/* enforce secure perfmon */				\
 	regs->cr_iip = new_ip;									\
 	regs->ar_rsc = 0xf;		/* eager mode, privilege level 3 */			\
 	regs->ar_rnat = 0;									\
@@ -542,11 +555,6 @@
 extern void ia32_load_state (struct task_struct *task);
 #endif
 
-#ifdef CONFIG_PERFMON
-extern void ia64_save_pm_regs (struct task_struct *task);
-extern void ia64_load_pm_regs (struct task_struct *task);
-#endif
-
 #define ia64_fph_enable()	asm volatile (";; rsm psr.dfh;; srlz.d;;" ::: "memory");
 #define ia64_fph_disable()	asm volatile (";; ssm psr.dfh;; srlz.d;;" ::: "memory");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/ptrace.h linux/include/asm-ia64/ptrace.h
--- linux.orig/include/asm-ia64/ptrace.h	2001-07-31 17:30:09.000000000 +0000
+++ linux/include/asm-ia64/ptrace.h	2002-07-20 01:08:25.000000000 +0000
@@ -247,8 +247,34 @@
 
 #endif /* !__KERNEL__ */
 
+/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
+struct pt_all_user_regs {
+	unsigned long nat;
+	unsigned long cr_iip;
+	unsigned long cfm;
+	unsigned long cr_ipsr;
+	unsigned long pr;
+
+	unsigned long gr[32];
+	unsigned long br[8];
+	unsigned long ar[128];
+	struct ia64_fpreg fr[128];
+};
+
 #endif /* !__ASSEMBLY__ */
 
+/* indices to application-registers array in pt_all_user_regs */
+#define PT_AUR_RSC	16
+#define PT_AUR_BSP	17
+#define PT_AUR_BSPSTORE	18
+#define PT_AUR_RNAT	19
+#define PT_AUR_CCV	32
+#define PT_AUR_UNAT	36
+#define PT_AUR_FPSR	40
+#define PT_AUR_PFS	64
+#define PT_AUR_LC	65
+#define PT_AUR_EC	66
+
 /*
  * The numbers chosen here are somewhat arbitrary but absolutely MUST
  * not overlap with any of the number assigned in <linux/ptrace.h>.
@@ -256,5 +282,7 @@
 #define PTRACE_SINGLEBLOCK	12	/* resume execution until next branch */
 #define PTRACE_GETSIGINFO	13	/* get child's siginfo structure */
 #define PTRACE_SETSIGINFO	14	/* set child's siginfo structure */
+#define PTRACE_GETREGS		18	/* get all registers (pt_all_user_regs) in one shot */
+#define PTRACE_SETREGS		19	/* set all registers (pt_all_user_regs) in one shot */
 
 #endif /* _ASM_IA64_PTRACE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sal.h linux/include/asm-ia64/sal.h
--- linux.orig/include/asm-ia64/sal.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/sal.h	2002-07-20 01:08:34.000000000 +0000
@@ -8,11 +8,14 @@
  * Abstraction Layer".
  *
  * Copyright (C) 2001 Intel
+ * Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com>
  * Copyright (C) 2001 Fred Lewis <frederick.v.lewis@intel.com>
  * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
  * Copyright (C) 1998, 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com>
  *
+ * 02/01/04 J. Hall Updated Error Record Structures to conform to July 2001
+ *		    revision of the SAL spec.
  * 01/01/03 fvlewis Updated Error Record Structures to conform with Nov. 2000
  *                  revision of the SAL spec.
  * 99/09/29 davidm	Updated for SAL 2.6.
@@ -149,6 +152,7 @@
 #define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK		(1 << 0)
 #define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT	(1 << 1)
 #define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT	(1 << 2)
+#define IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT	 	(1 << 3)
 
 typedef struct ia64_sal_desc_platform_feature {
 	u8 type;
@@ -227,6 +231,10 @@
 	SAL_VECTOR_OS_BOOT_RENDEZ	= 2
 };
 
+/* Encodings for mca_opt parameter sent to SAL_MC_SET_PARAMS */
+#define	SAL_MC_PARAM_RZ_ALWAYS		0x1
+#define	SAL_MC_PARAM_BINIT_ESCALATE	0x10
+
 /*
 ** Definition of the SAL Error Log from the SAL spec
 */
@@ -515,12 +523,12 @@
     {
         u16 vendor_id;
         u16 device_id;
-        u16 class_code;
+	u8  class_code[3];
         u8  func_num;
         u8  dev_num;
         u8  bus_num;
         u8  seg_num;
-        u8  reserved[6];
+        u8  reserved[5];
     }               comp_info;
     u32             num_mem_regs;
     u32             num_io_regs;
@@ -776,4 +784,6 @@
 	return isrv.status;
 }
 
+extern unsigned long sal_platform_features;
+
 #endif /* _ASM_IA64_PAL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/scatterlist.h linux/include/asm-ia64/scatterlist.h
--- linux.orig/include/asm-ia64/scatterlist.h	2001-11-13 17:01:16.000000000 +0000
+++ linux/include/asm-ia64/scatterlist.h	2002-07-20 01:08:21.000000000 +0000
@@ -2,7 +2,7 @@
 #define _ASM_IA64_SCATTERLIST_H
 
 /*
- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
+ * Copyright (C) 1998-1999, 2001-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -14,7 +14,6 @@
 	/* These two are only valid if ADDRESS member of this struct is NULL.  */
 	struct page *page;
 	unsigned int offset;
-
 	unsigned int length;	/* buffer length */
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/serial.h linux/include/asm-ia64/serial.h
--- linux.orig/include/asm-ia64/serial.h	2000-02-07 02:42:40.000000000 +0000
+++ linux/include/asm-ia64/serial.h	2002-07-20 01:08:35.000000000 +0000
@@ -59,6 +59,20 @@
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
 
+/*
+ * HCDP_SERIAL_PORT_DEFNS should be placed in exactly the same slot
+ * in rs_table as defined by HCDP_SERIAL_CONSOLE_PORT in
+ * include/linux/serial.h
+ */
+#define HCDP_SERIAL_PORT_DEFNS			\
+	{ 0, BASE_BAUD, -1, 0, STD_COM_FLAGS},		/* ttySx device
+							   in comments sucks.
+							   You add an entry
+							   and you get to edit
+							   boatloads of these
+							   comments. Not worth
+							   it */
+
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
 #define EXTRA_SERIAL_PORT_DEFNS			\
@@ -129,6 +143,7 @@
 
 #define SERIAL_PORT_DFNS		\
 	STD_SERIAL_PORT_DEFNS		\
+	HCDP_SERIAL_PORT_DEFNS		\
 	EXTRA_SERIAL_PORT_DEFNS		\
 	HUB6_SERIAL_PORT_DFNS		\
 	MCA_SERIAL_PORT_DFNS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sigcontext.h linux/include/asm-ia64/sigcontext.h
--- linux.orig/include/asm-ia64/sigcontext.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/sigcontext.h	2002-07-20 01:08:22.000000000 +0000
@@ -56,7 +56,9 @@
 	unsigned long		sc_rbs_base;	/* NULL or new base of sighandler's rbs */
 	unsigned long		sc_loadrs;	/* see description above */
 
-	unsigned long		sc_rsvd[14];	/* reserved for future use */
+	unsigned long		sc_ar25;	/* rsvd for scratch use */
+	unsigned long		sc_ar26;	/* rsvd for scratch use */
+	unsigned long		sc_rsvd[12];	/* reserved for future use */
 	/*
 	 * The mask must come last so we can increase _NSIG_WORDS
 	 * without breaking binary compatibility.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/siginfo.h linux/include/asm-ia64/siginfo.h
--- linux.orig/include/asm-ia64/siginfo.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/asm-ia64/siginfo.h	2002-07-20 01:08:33.000000000 +0000
@@ -2,8 +2,8 @@
 #define _ASM_IA64_SIGINFO_H
 
 /*
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/types.h>
@@ -57,7 +57,7 @@
 		struct {
 			void *_addr;		/* faulting insn/memory ref. */
 			int _imm;		/* immediate value for "break" */
-			int _pad0;
+			unsigned int _flags;	/* see below */
 			unsigned long _isr;	/* isr */
 		} _sigfault;
 
@@ -70,7 +70,7 @@
 		struct {
 			pid_t _pid;		/* which child */
 			uid_t _uid;		/* sender's uid */
-			unsigned long _pfm_ovfl_counters; /* which PMU counter overflowed */
+			unsigned long _pfm_ovfl_counters[4]; /* which PMU counter overflowed */
 		} _sigprof;
 	} _sifields;
 } siginfo_t;
@@ -88,12 +88,23 @@
 #define si_ptr		_sifields._rt._sigval.sival_ptr
 #define si_addr		_sifields._sigfault._addr
 #define si_imm		_sifields._sigfault._imm	/* as per UNIX SysV ABI spec */
-#define si_isr		_sifields._sigfault._isr	/* valid if si_code==FPE_FLTxxx */
+#define si_flags	_sifields._sigfault._flags
+/*
+ * si_isr is valid for SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP provided that
+ * si_code is non-zero and __ISR_VALID is set in si_flags.
+ */
+#define si_isr		_sifields._sigfault._isr
 #define si_band		_sifields._sigpoll._band
 #define si_fd		_sifields._sigpoll._fd
 #define si_pfm_ovfl	_sifields._sigprof._pfm_ovfl_counters
 
 /*
+ * Flag values for si_flags:
+ */
+#define __ISR_VALID_BIT	0
+#define __ISR_VALID	(1 << __ISR_VALID_BIT)
+
+/*
  * si_code values
  * Positive values for kernel-generated signals.
  */
@@ -124,6 +135,7 @@
 #define SI_MESGQ	(-3)		/* sent by real time mesq state change */
 #define SI_ASYNCIO	(-4)		/* sent by AIO completion */
 #define SI_SIGIO	(-5)		/* sent by queued SIGIO */
+#define SI_TKILL	(-6)		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/signal.h linux/include/asm-ia64/signal.h
--- linux.orig/include/asm-ia64/signal.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/signal.h	2002-07-20 01:08:26.000000000 +0000
@@ -115,6 +115,7 @@
 #define SA_PROBE		SA_ONESHOT
 #define SA_SAMPLE_RANDOM	SA_RESTART
 #define SA_SHIRQ		0x04000000
+#define SA_PERCPU_IRQ		0x02000000
 
 #endif /* __KERNEL__ */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/addrs.h linux/include/asm-ia64/sn/addrs.h
--- linux.orig/include/asm-ia64/sn/addrs.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/addrs.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,40 +1,42 @@
-/* $Id$
+
+/*
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
- * Copyright (C) 1999 by Ralf Baechle
+ * Copyright (c) 1992-1999,2001 Silicon Graphics, Inc.  All rights reserved.
  */
-#ifndef _ASM_SN_ADDRS_H
-#define _ASM_SN_ADDRS_H
 
-#include <linux/config.h>
 
-#if _LANGUAGE_C
-#include <linux/types.h>
-#endif /* _LANGUAGE_C */
-
-#if !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC)
-#include <asm/addrspace.h>
-#include <asm/reg.h>
-#include <asm/sn/kldir.h>
-#endif	/* CONFIG_IA64_SGI_SN1 */
+#ifndef _ASM_IA64_SN_ADDRS_H
+#define _ASM_IA64_SN_ADDRS_H
+
+#include <linux/config.h>
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#if defined (CONFIG_IA64_SGI_SN1)
 #include <asm/sn/sn1/addrs.h>
-#endif
+#elif defined (CONFIG_IA64_SGI_SN2)
+#include <asm/sn/sn2/addrs.h>
+#else
+#error <<<BOMB! addrs.h defined only for SN1, or SN2 >>>
+#endif /* !SN1 && !SN2 */
 
+#ifndef __ASSEMBLY__
+#include <asm/sn/types.h>
+#endif 
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define PS_UINT_CAST		(__psunsigned_t)
 #define UINT64_CAST		(uint64_t)
-
+#ifdef CONFIG_IA64_SGI_SN2
+#define HUBREG_CAST		(volatile mmr_t *)
+#else
 #define HUBREG_CAST		(volatile hubreg_t *)
+#endif
 
-#elif _LANGUAGE_ASSEMBLY
+#elif __ASSEMBLY__
 
 #define PS_UINT_CAST
 #define UINT64_CAST
@@ -43,18 +45,6 @@
 #endif
 
 
-#define NASID_GET_META(_n)	((_n) >> NASID_LOCAL_BITS)
-#if defined CONFIG_SGI_IP35 || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#define NASID_GET_LOCAL(_n)	((_n) & 0x7f)
-#endif
-#define NASID_MAKE(_m, _l)	(((_m) << NASID_LOCAL_BITS) | (_l))
-
-#define NODE_ADDRSPACE_MASK	(NODE_ADDRSPACE_SIZE - 1)
-#define TO_NODE_ADDRSPACE(_pa)	(UINT64_CAST (_pa) & NODE_ADDRSPACE_MASK)
-
-#define CHANGE_ADDR_NASID(_pa, _nasid)	\
-		((UINT64_CAST (_pa) & ~NASID_MASK) | \
-		 (UINT64_CAST(_nasid) <<  NASID_SHFT))
 
 
 /*
@@ -62,7 +52,11 @@
  * node's address space.
  */
 
+#ifdef CONFIG_IA64_SGI_SN2	/* SN2 has an extra AS field between node offset and node id (nasid) */
+#define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NASID_SHFT)
+#else
 #define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NODE_SIZE_BITS)
+#endif
 
 #define NODE_CAC_BASE(_n)	(CAC_BASE   + NODE_OFFSET(_n))
 #define NODE_HSPEC_BASE(_n)	(HSPEC_BASE + NODE_OFFSET(_n))
@@ -118,11 +112,6 @@
 /*
  * The following define the major position-independent aliases used
  * in SN.
- *	UALIAS -- 256MB in size, reads in the UALIAS result in
- *			uncached references to the memory of the reader's node.
- *	CPU_UALIAS -- 128kb in size, the bottom part of UALIAS is flipped
- *			depending on which CPU does the access to provide
- *			all CPUs with unique uncached memory at low addresses.
  *	LBOOT  -- 256MB in size, reads in the LBOOT area result in
  *			uncached references to the local hub's boot prom and
  *			other directory-bus connected devices.
@@ -130,17 +119,7 @@
  *			references to the local hub's registers.
  */
 
-#define UALIAS_BASE		HSPEC_BASE
-#define UALIAS_SIZE		0x10000000	/* 256 Megabytes */
-#define CPU_UALIAS		0x20000		/* 128 Kilobytes */
-#define UALIAS_CPU_SIZE		(CPU_UALIAS / CPUS_PER_NODE)
-#define UALIAS_LIMIT		(UALIAS_BASE + UALIAS_SIZE)
-
-/*
- * The bottom of ualias space is flipped depending on whether you're
- * processor 0 or 1 within a node.
- */
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#if defined CONFIG_IA64_SGI_SN1
 #define LREG_BASE		(HSPEC_BASE + 0x10000000)
 #define LREG_SIZE		0x8000000  /* 128 MB */
 #define LREG_LIMIT		(LREG_BASE + LREG_SIZE)
@@ -151,7 +130,11 @@
 #endif
 
 #define	HUB_REGISTER_WIDGET	1
+#ifdef CONFIG_IA64_SGI_SN2
+#define IALIAS_BASE		LOCAL_SWIN_BASE(HUB_REGISTER_WIDGET)
+#else
 #define IALIAS_BASE		NODE_SWIN_BASE(0, HUB_REGISTER_WIDGET)
+#endif
 #define IALIAS_SIZE		0x800000	/* 8 Megabytes */
 #define IS_IALIAS(_a)		(((_a) >= IALIAS_BASE) &&		\
 				 ((_a) < (IALIAS_BASE + IALIAS_SIZE)))
@@ -160,7 +143,7 @@
  * Macro for referring to Hub's RBOOT space
  */
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#if defined CONFIG_IA64_SGI_SN1
 
 #define NODE_LREG_BASE(_n)	(NODE_HSPEC_BASE(_n) + 0x30000000)
 #define NODE_LREG_LIMIT(_n)	(NODE_LREG_BASE(_n) + LREG_SIZE)
@@ -172,168 +155,6 @@
 
 #endif
 
-/*
- * Macros for referring the Hub's back door space
- *
- *   These macros correctly process addresses in any node's space.
- *   WARNING: They won't work in assembler.
- *
- *   BDDIR_ENTRY_LO returns the address of the low double-word of the dir
- *                  entry corresponding to a physical (Cac or Uncac) address.
- *   BDDIR_ENTRY_HI returns the address of the high double-word of the entry.
- *   BDPRT_ENTRY    returns the address of the double-word protection entry
- *                  corresponding to the page containing the physical address.
- *   BDPRT_ENTRY_S  Stores the value into the protection entry.
- *   BDPRT_ENTRY_L  Load the value from the protection entry.
- *   BDECC_ENTRY    returns the address of the ECC byte corresponding to a
- *                  double-word at a specified physical address.
- *   BDECC_ENTRY_H  returns the address of the two ECC bytes corresponding to a
- *                  quad-word at a specified physical address.
- */
-#define NODE_BDOOR_BASE(_n)	(NODE_HSPEC_BASE(_n) + (NODE_ADDRSPACE_SIZE/2))
-
-#define NODE_BDECC_BASE(_n)	(NODE_BDOOR_BASE(_n))
-#define NODE_BDDIR_BASE(_n)	(NODE_BDOOR_BASE(_n) + (NODE_ADDRSPACE_SIZE/4))
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-/*
- * Bedrock's directory entries are a single word:  no low/high
- */
-
-#define BDDIR_ENTRY(_pa)	(HSPEC_BASE +				      \
-				  NODE_ADDRSPACE_SIZE * 7 / 8  		    | \
-				 UINT64_CAST (_pa)	& NASID_MASK	    | \
-				 UINT64_CAST (_pa) >> 3 & BDDIR_UPPER_MASK)
-
-#ifdef BRINGUP
-        /* minimize source changes by mapping *_LO() & *_HI()   */
-#define BDDIR_ENTRY_LO(_pa)     BDDIR_ENTRY(_pa)
-#define BDDIR_ENTRY_HI(_pa)     BDDIR_ENTRY(_pa)
-#endif /* BRINGUP */
-
-#define BDDIR_PAGE_MASK		(BDDIR_UPPER_MASK & 0x7ffff << 11)
-#define BDDIR_PAGE_BASE_MASK	(UINT64_CAST 0xfffffffffffff800)
-
-#ifdef _LANGUAGE_C
-
-#define BDPRT_ENTRY_ADDR(_pa, _rgn)      ((uint64_t *) ( (HSPEC_BASE +       \
-                                 NODE_ADDRSPACE_SIZE * 7 / 8 + 0x408)       | \
-                                (UINT64_CAST (_pa)      & NASID_MASK)        | \
-                                (UINT64_CAST (_pa) >> 3 & BDDIR_PAGE_MASK)   | \
-                                (UINT64_CAST (_pa) >> 3 & 0x3 << 4)          | \
-                                ((_rgn) & 0x1e) << 5))
-
-static __inline uint64_t BDPRT_ENTRY_L(paddr_t pa,uint32_t rgn) {
-	uint64_t word=*BDPRT_ENTRY_ADDR(pa,rgn);
-
-	if(rgn&0x20)			/*If the region is > 32, move it down*/
-		word = word >> 32;
-	if(rgn&0x1)			/*If the region is odd, get that part */
-		word = word >> 16;
-	word = word & 0xffff;		/*Get the 16 bits we are interested in*/
-
-	return word;
-}
-
-static __inline void BDPRT_ENTRY_S(paddr_t pa,uint32_t rgn,uint64_t val) {
-        uint64_t *addr=(uint64_t *)BDPRT_ENTRY_ADDR(pa,rgn);
-        uint64_t word,mask;
-
-        word=*addr;
-	mask=0;
-	if(rgn&0x1) {
-		mask|=0x0000ffff0000ffff;
-		val=val<<16;
-	}
-	else
-		mask|=0xffff0000ffff0000;
-	if(rgn&0x20) {
-		mask|=0x00000000ffffffff;
-		val=val<<32;
-	}
-	else
-		mask|=0xffffffff00000000;
-	word &= mask;
-	word |= val;
-
-	*(addr++)=word;
-	addr++;
-        *(addr++)=word;
-        addr++;
-        *(addr++)=word;
-        addr++;
-        *addr=word;
-}
-#endif	/*_LANGUAGE_C*/
-
-#define BDCNT_ENTRY(_pa)	(HSPEC_BASE +				      \
-				  NODE_ADDRSPACE_SIZE * 7 / 8 + 0x8    	    | \
-				 UINT64_CAST (_pa)	& NASID_MASK	    | \
-				 UINT64_CAST (_pa) >> 3 & BDDIR_PAGE_MASK   | \
-				 UINT64_CAST (_pa) >> 3 & 0x3 << 4)
-
-
-#ifdef    BRINGUP
-  /* little endian packing of ecc bytes requires a swizzle */ 
-  /* this is problemmatic for memory_init_ecc              */
-#endif /* BRINGUP */
-#define BDECC_ENTRY(_pa)	(HSPEC_BASE +				      \
-				  NODE_ADDRSPACE_SIZE * 5 / 8 		    | \
-				 UINT64_CAST (_pa)	& NASID_MASK	    | \
-				 UINT64_CAST (_pa) >> 3 & BDECC_UPPER_MASK    \
-				   		        ^ 0x7ULL)
-
-#define BDECC_SCRUB(_pa)	(HSPEC_BASE +				      \
-				  NODE_ADDRSPACE_SIZE / 2 		    | \
-				 UINT64_CAST (_pa)	& NASID_MASK	    | \
-				 UINT64_CAST (_pa) >> 3 & BDECC_UPPER_MASK    \
-				   		        ^ 0x7ULL)
-
-  /* address for Halfword backdoor ecc access. Note that   */
-  /* ecc bytes are packed in little endian order           */
-#define BDECC_ENTRY_H(_pa)	(HSPEC_BASE +                                 \
-				  NODE_ADDRSPACE_SIZE * 5 / 8		    | \
-				 UINT64_CAST (_pa)	 & NASID_MASK	    | \
-				 UINT64_CAST (_pa) >> 3 & BDECC_UPPER_MASK    \
-				   		        ^ 0x6ULL)
-
-/*
- * Macro to convert a back door directory, protection, page counter, or ecc
- * address into the raw physical address of the associated cache line
- * or protection page.
- */
-
-#define BDDIR_TO_MEM(_ba)	(UINT64_CAST  (_ba) & NASID_MASK            | \
-				 (UINT64_CAST (_ba) & BDDIR_UPPER_MASK) << 3)
-
-#ifdef BRINGUP
-/*
- * This can't be done since there are 4 entries per address so you'd end up
- * mapping back to 4 different physical addrs.
- */
-  
-#define BDPRT_TO_MEM(_ba) 	(UINT64_CAST  (_ba) & NASID_MASK	    | \
-				 (UINT64_CAST (_ba) & BDDIR_PAGE_MASK) << 3 | \
-				 (UINT64_CAST (_ba) & 0x3 << 4) << 3)
-#endif
-
-#define BDCNT_TO_MEM(_ba) 	(UINT64_CAST  (_ba) & NASID_MASK	    | \
-				 (UINT64_CAST (_ba) & BDDIR_PAGE_MASK) << 3 | \
-				 (UINT64_CAST (_ba) & 0x3 << 4) << 3)
-
-#define BDECC_TO_MEM(_ba)	(UINT64_CAST  (_ba) & NASID_MASK	    | \
-				 ((UINT64_CAST (_ba) ^ 0x7ULL)                \
-				                    & BDECC_UPPER_MASK) << 3 )
-
-#define BDECC_H_TO_MEM(_ba)	(UINT64_CAST  (_ba) & NASID_MASK	    | \
-				 ((UINT64_CAST (_ba) ^ 0x6ULL)                \
-				                    & BDECC_UPPER_MASK) << 3 )
-
-#define BDADDR_IS_DIR(_ba)	((UINT64_CAST  (_ba) & 0x8) == 0)
-#define BDADDR_IS_PRT(_ba)	((UINT64_CAST  (_ba) & 0x408) == 0x408)
-#define BDADDR_IS_CNT(_ba)	((UINT64_CAST  (_ba) & 0x8) == 0x8)
-
-#endif /* CONFIG_SGI_IP35 */
-
 
 /*
  * The following macros produce the correct base virtual address for
@@ -344,6 +165,36 @@
  * for _x.
  */
 
+
+#ifdef CONFIG_IA64_SGI_SN2
+/*
+ * SN2 has II mmr's located inside small window space like SN0 & SN1,
+ * but has all other non-II mmr's located at the top of big window
+ * space, unlike SN0 & SN1.
+ */
+#define LOCAL_HUB_BASE(_x)	(LOCAL_MMR_ADDR(_x) | (((~(_x)) & BWIN_TOP)>>8))
+#define REMOTE_HUB_BASE(_x)						\
+        (UNCACHED | GLOBAL_MMR_SPACE |                                  \
+        (((~(_x)) & BWIN_TOP)>>8)    |                                       \
+        (((~(_x)) & BWIN_TOP)>>9)    | (_x))
+
+#define LOCAL_HUB(_x) (HUBREG_CAST LOCAL_HUB_BASE(_x))
+#define REMOTE_HUB(_n, _x)						\
+	(HUBREG_CAST (REMOTE_HUB_BASE(_x) | ((((long)(_n))<<NASID_SHFT))))
+
+#else	/* not CONFIG_IA64_SGI_SN2 */
+
+#define LOCAL_HUB(_x)		(HUBREG_CAST (IALIAS_BASE + (_x)))
+#define REMOTE_HUB(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
+					      0x800000 + (_x)))
+#endif
+
+#ifdef CONFIG_IA64_SGI_SN1
+#define LOCAL_HSPEC(_x)		(HUBREG_CAST (LREG_BASE + (_x)))
+#define REMOTE_HSPEC(_n, _x)		(HUBREG_CAST (RREG_BASE(_n) + (_x)))
+#endif /* CONFIG_IA64_SGI_SN1 */
+
+
 /*
  * WARNING:
  *	When certain Hub chip workaround are defined, it's not sufficient
@@ -352,17 +203,29 @@
  *	Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
  *	They're always safe.
  */
+#ifdef CONFIG_IA64_SGI_SN2
+#define LOCAL_HUB_ADDR(_x)							\
+	(((_x) & BWIN_TOP) ? (HUBREG_CAST (LOCAL_MMR_ADDR(_x)))		\
+	: (HUBREG_CAST (IALIAS_BASE + (_x))))
+#define REMOTE_HUB_ADDR(_n, _x)						\
+	(((_x) & BWIN_TOP) ? (HUBREG_CAST (GLOBAL_MMR_ADDR(_n, _x)))	\
+	: (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x))))
+#else
 #define LOCAL_HUB_ADDR(_x)	(HUBREG_CAST (IALIAS_BASE + (_x)))
 #define REMOTE_HUB_ADDR(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
 					      0x800000 + (_x)))
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#endif
+#if CONFIG_IA64_SGI_SN1
 #define REMOTE_HUB_PI_ADDR(_n, _sn, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
 					      0x800000 + PIREG(_x, _sn)))
+#endif
+
+#ifdef CONFIG_IA64_SGI_SN1
 #define LOCAL_HSPEC_ADDR(_x)		(HUBREG_CAST (LREG_BASE + (_x)))
 #define REMOTE_HSPEC_ADDR(_n, _x)	(HUBREG_CAST (RREG_BASE(_n) + (_x)))
-#endif /* CONFIG_SGI_IP35 */
+#endif /* CONFIG_IA64_SGI_SN1 */
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define HUB_L(_a)			*(_a)
 #define	HUB_S(_a, _d)			*(_a) = (_d)
@@ -374,14 +237,14 @@
 #define REMOTE_HUB_PI_L(_n, _sn, _r)	HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
 #define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#ifdef CONFIG_IA64_SGI_SN1
 #define LOCAL_HSPEC_L(_r)	     HUB_L(LOCAL_HSPEC_ADDR(_r))
 #define LOCAL_HSPEC_S(_r, _d)	     HUB_S(LOCAL_HSPEC_ADDR(_r), (_d))
 #define REMOTE_HSPEC_L(_n, _r)	     HUB_L(REMOTE_HSPEC_ADDR((_n), (_r)))
 #define REMOTE_HSPEC_S(_n, _r, _d)   HUB_S(REMOTE_HSPEC_ADDR((_n), (_r)), (_d))
-#endif /* CONFIG_SGI_IP35 */
+#endif /* CONFIG_IA64_SGI_SN1 */
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /*
  * The following macros are used to get to a hub/bridge register, given
@@ -410,13 +273,8 @@
 #define ARCS_SPB_SIZE		0x0400
 
 #define KLDIR_OFFSET		0x2000
-#ifndef __ia64
 #define KLDIR_ADDR(nasid)						\
-	TO_NODE_UNCAC((nasid), KLDIR_OFFSET)
-#else
-#define KLDIR_ADDR(nasid)                                               \
-        TO_NODE_CAC((nasid), KLDIR_OFFSET)
-#endif
+	TO_NODE_CAC((nasid), KLDIR_OFFSET)
 #define KLDIR_SIZE		0x0400
 
 
@@ -439,7 +297,7 @@
 #define	KLI_KERN_XP		8
 #define	KLI_KERN_PARTID		9
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define KLD_BASE(nasid)		((kldir_ent_t *) KLDIR_ADDR(nasid))
 #define KLD_LAUNCH(nasid)	(KLD_BASE(nasid) + KLI_LAUNCH)
@@ -453,85 +311,23 @@
 #define	KLD_KERN_XP(nasid)	(KLD_BASE(nasid) + KLI_KERN_XP)
 #define	KLD_KERN_PARTID(nasid)	(KLD_BASE(nasid) + KLI_KERN_PARTID)
 
-#define LAUNCH_OFFSET(nasid, slice)					\
-	(KLD_LAUNCH(nasid)->offset +					\
-	 KLD_LAUNCH(nasid)->stride * (slice))
-#define LAUNCH_ADDR(nasid, slice)					\
-	TO_NODE_UNCAC((nasid), LAUNCH_OFFSET(nasid, slice))
-#define LAUNCH_SIZE(nasid)	KLD_LAUNCH(nasid)->size
-
-#define NMI_OFFSET(nasid, slice)					\
-	(KLD_NMI(nasid)->offset +					\
-	 KLD_NMI(nasid)->stride * (slice))
-#define NMI_ADDR(nasid, slice)						\
-	TO_NODE_UNCAC((nasid), NMI_OFFSET(nasid, slice))
-#define NMI_SIZE(nasid)	KLD_NMI(nasid)->size
-
+#ifndef CONFIG_IA64_SGI_SN2
 #define KLCONFIG_OFFSET(nasid)	KLD_KLCONFIG(nasid)->offset
+#else
+#define KLCONFIG_OFFSET(nasid) \
+	ia64_sn_get_klconfig_addr(nasid)
+#endif /* CONFIG_IA64_SGI_SN2 */
+
 #define KLCONFIG_ADDR(nasid)						\
-	TO_NODE_UNCAC((nasid), KLCONFIG_OFFSET(nasid))
+	TO_NODE_CAC((nasid), KLCONFIG_OFFSET(nasid))
 #define KLCONFIG_SIZE(nasid)	KLD_KLCONFIG(nasid)->size
 
 #define GDA_ADDR(nasid)		KLD_GDA(nasid)->pointer
 #define GDA_SIZE(nasid)		KLD_GDA(nasid)->size
 
-#define SYMMON_STK_OFFSET(nasid, slice)					\
-	(KLD_SYMMON_STK(nasid)->offset +				\
-	 KLD_SYMMON_STK(nasid)->stride * (slice))
-#define SYMMON_STK_STRIDE(nasid)	KLD_SYMMON_STK(nasid)->stride
-
-#define SYMMON_STK_ADDR(nasid, slice)					\
-	TO_NODE_CAC((nasid), SYMMON_STK_OFFSET(nasid, slice))
-
-#define SYMMON_STK_SIZE(nasid)	KLD_SYMMON_STK(nasid)->stride
-
-#define SYMMON_STK_END(nasid)	(SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size)
-
-/* loading symmon 4k below UNIX. the arcs loader needs the topaddr for a
- * relocatable program
- */
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-/* update master.d/sn1_elspec.dbg, SN1/addrs.h/DEBUGUNIX_ADDR, and
- * DBGLOADADDR in symmon's Makefile when changing this */
-#define UNIX_DEBUG_LOADADDR     0x310000
-#elif defined(SN0XXL)
-#define UNIX_DEBUG_LOADADDR     0x360000
-#else
-#define	UNIX_DEBUG_LOADADDR	0x300000
-#endif
-#define	SYMMON_LOADADDR(nasid)						\
-	TO_NODE(nasid, PHYS_TO_K0(UNIX_DEBUG_LOADADDR - 0x1000))
-
-#define FREEMEM_OFFSET(nasid)	KLD_FREEMEM(nasid)->offset
-#define FREEMEM_ADDR(nasid)	SYMMON_STK_END(nasid)
-/*
- * XXX
- * Fix this. FREEMEM_ADDR should be aware of if symmon is loaded.
- * Also, it should take into account what prom thinks to be a safe
- * address
-	PHYS_TO_K0(NODE_OFFSET(nasid) + FREEMEM_OFFSET(nasid))
- */
-#define FREEMEM_SIZE(nasid)	KLD_FREEMEM(nasid)->size
-
-#define PI_ERROR_OFFSET(nasid)	KLD_PI_ERROR(nasid)->offset
-#define PI_ERROR_ADDR(nasid)						\
-	TO_NODE_UNCAC((nasid), PI_ERROR_OFFSET(nasid))
-#define PI_ERROR_SIZE(nasid)	KLD_PI_ERROR(nasid)->size
-
 #define NODE_OFFSET_TO_K0(_nasid, _off)					\
 	(PAGE_OFFSET | NODE_OFFSET(_nasid) | (_off))
-#define K0_TO_NODE_OFFSET(_k0addr)					\
-	((__psunsigned_t)(_k0addr) & NODE_ADDRSPACE_MASK)
-
-#define KERN_VARS_ADDR(nasid)	KLD_KERN_VARS(nasid)->pointer
-#define KERN_VARS_SIZE(nasid)	KLD_KERN_VARS(nasid)->size
-
-#define	KERN_XP_ADDR(nasid)	KLD_KERN_XP(nasid)->pointer
-#define	KERN_XP_SIZE(nasid)	KLD_KERN_XP(nasid)->size
-
-#define GPDA_ADDR(nasid)	TO_NODE_CAC(nasid, GPDA_OFFSET)
-
-#endif /* _LANGUAGE_C */
 
+#endif /* __ASSEMBLY__ */
 
-#endif /* _ASM_SN_ADDRS_H */
+#endif /* _ASM_IA64_SN_ADDRS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/agent.h linux/include/asm-ia64/sn/agent.h
--- linux.orig/include/asm-ia64/sn/agent.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/agent.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * This file has definitions for the hub and snac interfaces.
- *
- * Copyright (C) 1992 - 1997, 1999 Silcon Graphics, Inc.
- * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
- */
-#ifndef _ASM_SGI_SN_AGENT_H
-#define _ASM_SGI_SN_AGENT_H
-
-#include <linux/config.h>
-
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-//#include <asm/sn/io.h>
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/bedrock.h>
-#endif	/* CONFIG_SGI_IP35 */
-
-/*
- * NIC register macros
- */
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#define HUB_NIC_ADDR(_cpuid) 						   \
-	REMOTE_HUB_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(_cpuid)),       \
-		LB_MICROLAN_CTL)
-#endif
-
-#define SET_HUB_NIC(_my_cpuid, _val) 				  	   \
-	(HUB_S(HUB_NIC_ADDR(_my_cpuid), (_val)))
-
-#define SET_MY_HUB_NIC(_v) 					           \
-	SET_HUB_NIC(cpuid(), (_v))
-
-#define GET_HUB_NIC(_my_cpuid) 						   \
-	(HUB_L(HUB_NIC_ADDR(_my_cpuid)))
-
-#define GET_MY_HUB_NIC() 						   \
-	GET_HUB_NIC(cpuid())
-
-#endif /* _ASM_SGI_SN_AGENT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/alenlist.h linux/include/asm-ia64/sn/alenlist.h
--- linux.orig/include/asm-ia64/sn/alenlist.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/alenlist.h	2002-07-20 01:08:21.000000000 +0000
@@ -4,11 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_ALENLIST_H
-#define _ASM_SN_ALENLIST_H
+#ifndef _ASM_IA64_SN_ALENLIST_H
+#define _ASM_IA64_SN_ALENLIST_H
+
+#include <linux/types.h>
 
 /* Definition of Address/Length List */
 
@@ -51,7 +52,7 @@
 
 
 /* Return codes from alenlist routines.  */
-#define ALENLIST_FAILURE -1
+#define ALENLIST_FAILURE (-1)
 #define ALENLIST_SUCCESS 0
 
 
@@ -201,4 +202,4 @@
 }
 #endif
 
-#endif /* _ASM_SN_ALENLIST_H */
+#endif /* _ASM_IA64_SN_ALENLIST_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/arc/hinv.h linux/include/asm-ia64/sn/arc/hinv.h
--- linux.orig/include/asm-ia64/sn/arc/hinv.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/arc/hinv.h	2002-07-20 01:08:28.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/arc/types.h linux/include/asm-ia64/sn/arc/types.h
--- linux.orig/include/asm-ia64/sn/arc/types.h	2001-04-12 19:16:36.000000000 +0000
+++ linux/include/asm-ia64/sn/arc/types.h	2002-07-20 01:08:39.000000000 +0000
@@ -4,7 +4,7 @@
  * for more details.
  *
  * Copyright 1999 Ralf Baechle (ralf@gnu.org)
- * Copyright 1999 Silicon Graphics, Inc.
+ * Copyright 1999,2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SN_ARC_TYPES_H
 #define _ASM_SN_ARC_TYPES_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/arch.h linux/include/asm-ia64/sn/arch.h
--- linux.orig/include/asm-ia64/sn/arch.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/arch.h	2002-07-20 01:08:33.000000000 +0000
@@ -6,180 +6,50 @@
  *
  * SGI specific setup.
  *
- * Copyright (C) 1995 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1995-1997,1999,2001-2002 Silicon Graphics, Inc.  All rights reserved.
  * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
  */
-#ifndef _ASM_SN_ARCH_H
-#define _ASM_SN_ARCH_H
+#ifndef _ASM_IA64_SN_ARCH_H
+#define _ASM_IA64_SN_ARCH_H
 
-#include <linux/types.h>
 #include <linux/config.h>
-
+#include <linux/threads.h>
+#include <linux/mmzone.h>
 #include <asm/sn/types.h>
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_SGI_IP37) || defined(CONFIG_IA64_GENERIC)
+
+#if defined(CONFIG_IA64_SGI_SN1) 
 #include <asm/sn/sn1/arch.h>
+#elif defined(CONFIG_IA64_SGI_SN2)
+#include <asm/sn/sn2/arch.h>
 #endif
 
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+#if defined(CONFIG_IA64_SGI_SN1) 
+typedef u64	bdrkreg_t;
+#elif defined(CONFIG_IA64_SGI_SN2)
+typedef u64	shubreg_t;
+#endif
+
 typedef u64	hubreg_t;
+typedef u64	mmr_t;
 typedef u64	nic_t;
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-typedef u64     bdrkreg_t;
-#endif	/* CONFIG_SGI_xxxxx */
-#endif	/* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#define CPUS_PER_NODE		4	/* CPUs on a single hub */
-#define CPUS_PER_NODE_SHFT	2	/* Bits to shift in the node number */
-#define CPUS_PER_SUBNODE	2	/* CPUs on a single hub PI */
-#endif
-#define CNODE_NUM_CPUS(_cnode)		(NODEPDA(_cnode)->node_num_cpus)
 
 #define CNODE_TO_CPU_BASE(_cnode)	(NODEPDA(_cnode)->node_first_cpu)
 
-#define makespnum(_nasid, _slice)					\
-		(((_nasid) << CPUS_PER_NODE_SHFT) | (_slice))
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-
-/*
- * There are 2 very similar macros for dealing with "slices". Make sure
- * you use the right one. 
- * Unfortunately, on all platforms except IP35 (currently), the 2 macros 
- * are interchangible. 
- *
- * On IP35, there are 4 cpus per node. Each cpu is refered to by it's slice.
- * The slices are numbered 0 thru 3. 
- *
- * There are also 2 PI interfaces per node. Each PI interface supports 2 cpus.
- * The term "local slice" specifies the cpu number relative to the PI.
- *
- * The cpus on the node are numbered:
- *	slice	localslice
- *	  0          0
- *	  1          1
- *	  2          0
- *	  3          1
- *
- *	cputoslice - returns a number 0..3 that is the slice of the specified cpu.
- *	cputolocalslice - returns a number 0..1 that identifies the local slice of
- *			the cpu within it's PI interface.
- */
-#ifdef LATER
-	/* These are dummied up for now ..... */
-#define cputocnode(cpu)				\
-               (pdaindr[(cpu)].p_nodeid)
-#define cputonasid(cpu)				\
-               (pdaindr[(cpu)].p_nasid)
-#define cputoslice(cpu)				\
-               (ASSERT(pdaindr[(cpu)].pda), (pdaindr[(cpu)].pda->p_slice))
-#define cputolocalslice(cpu)			\
-               (ASSERT(pdaindr[(cpu)].pda), (LOCALCPU(pdaindr[(cpu)].pda->p_slice)))
-#define cputosubnode(cpu)			\
-		(ASSERT(pdaindr[(cpu)].pda), (SUBNODE(pdaindr[(cpu)].pda->p_slice)))
-#else
-#define cputocnode(cpu) 0
-#define cputonasid(cpu) 0
-#define cputoslice(cpu) 0
-#define cputolocalslice(cpu) 0
-#define cputosubnode(cpu) 0
-#endif	/* LATER */
-#endif	/* CONFIG_SGI_IP35 */
-
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
-
-#define INVALID_NASID		(nasid_t)-1
-#define INVALID_CNODEID		(cnodeid_t)-1
-#define INVALID_PNODEID		(pnodeid_t)-1
-#define INVALID_MODULE		(moduleid_t)-1
-#define	INVALID_PARTID		(partid_t)-1
-
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-extern int     get_slice(void);
-extern cpuid_t get_cnode_cpu(cnodeid_t);
-extern int get_cpu_slice(cpuid_t);
-extern cpuid_t cnodetocpu(cnodeid_t);
-// extern cpuid_t cnode_slice_to_cpuid(cnodeid_t, int);
-
-extern int cnode_exists(cnodeid_t cnode);
-extern cnodeid_t cpuid_to_compact_node[MAXCPUS];
-#endif	/* CONFIG_IP35 */
-
-extern nasid_t get_nasid(void);
-extern cnodeid_t get_cpu_cnode(int);
-extern int get_cpu_slice(cpuid_t);
-
-/*
- * NO ONE should access these arrays directly.  The only reason we refer to
- * them here is to avoid the procedure call that would be required in the
- * macros below.  (Really want private data members here :-)
- */
-extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
-extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
-
-/*
- * These macros are used by various parts of the kernel to convert
- * between the three different kinds of node numbering.   At least some
- * of them may change to procedure calls in the future, but the macros
- * will continue to work.  Don't use the arrays above directly.
- */
-
-#define	NASID_TO_REGION(nnode)	      	\
-    ((nnode) >> \
-     (is_fine_dirmode() ? NASID_TO_FINEREG_SHFT : NASID_TO_COARSEREG_SHFT))
-
-#ifndef __ia64
-extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
-extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
-extern cnodeid_t cpuid_to_compact_node[MAXCPUS];
-
-#if !defined(DEBUG)
-
-#define NASID_TO_COMPACT_NODEID(nnode)	(nasid_to_compact_node[nnode])
-#define COMPACT_TO_NASID_NODEID(cnode)	(compact_to_nasid_node[cnode])
-#define CPUID_TO_COMPACT_NODEID(cpu)	(cpuid_to_compact_node[(cpu)])
-#else
-
-/*
- * These functions can do type checking and fail if they need to return
- * a bad nodeid, but they're not as fast so just use 'em for debug kernels.
- */
-cnodeid_t nasid_to_compact_nodeid(nasid_t nasid);
-nasid_t compact_to_nasid_nodeid(cnodeid_t cnode);
-
-#define NASID_TO_COMPACT_NODEID(nnode)	nasid_to_compact_nodeid(nnode)
-#define COMPACT_TO_NASID_NODEID(cnode)	compact_to_nasid_nodeid(cnode)
-#define CPUID_TO_COMPACT_NODEID(cpu)	(cpuid_to_compact_node[(cpu)])
-#endif
-
-#else
-
-/*
- * IA64 specific nasid and cnode ids.
- */
 #define NASID_TO_COMPACT_NODEID(nasid)  (nasid_to_cnodeid(nasid))
 #define COMPACT_TO_NASID_NODEID(cnode)  (cnodeid_to_nasid(cnode))
-#define CPUID_TO_COMPACT_NODEID(cpu)    (cpuid_to_cnodeid(cpu))
 
-#endif /* #ifndef __ia64 */
 
-extern int node_getlastslot(cnodeid_t);
+#define INVALID_NASID		((nasid_t)-1)
+#define INVALID_CNODEID		((cnodeid_t)-1)
+#define INVALID_PNODEID		((pnodeid_t)-1)
+#define INVALID_MODULE		((moduleid_t)-1)
+#define	INVALID_PARTID		((partid_t)-1)
 
-#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
+extern cpuid_t cnodetocpu(cnodeid_t);
+void   sn_flush_all_caches(long addr, long bytes);
 
-#define SLOT_BITMASK    	(MAX_MEM_SLOTS - 1)
-#define SLOT_SIZE		(1LL<<SLOT_SHIFT)
+extern int     is_fine_dirmode(void);
 
-#define node_getnumslots(node)	(MAX_MEM_SLOTS)
-#define NODE_MAX_MEM_SIZE	SLOT_SIZE * MAX_MEM_SLOTS
 
-/*
- * New stuff in here from Irix sys/pfdat.h.
- */
-#define	SLOT_PFNSHIFT		(SLOT_SHIFT - PAGE_SHIFT)
-#define	PFN_NASIDSHFT		(NASID_SHFT - PAGE_SHIFT)
-#define mkpfn(nasid, off)	(((pfn_t)(nasid) << PFN_NASIDSHFT) | (off))
-#define slot_getbasepfn(node,slot) \
-		(mkpfn(COMPACT_TO_NASID_NODEID(node), slot<<SLOT_PFNSHIFT))
-#endif /* _ASM_SN_ARCH_H */
+#endif /* _ASM_IA64_SN_ARCH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/ate_utils.h linux/include/asm-ia64/sn/ate_utils.h
--- linux.orig/include/asm-ia64/sn/ate_utils.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/ate_utils.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,51 @@
+#ifndef _ASM_IA64_SN_ATE_UTILS_H
+#define _ASM_IA64_SN_ATE_UTILS_H
+
+/* $Id: ate_utils.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ *	struct map	X[]	.m_size		.m_addr
+ *			---	------------	-----------
+ *			[0]	mapsize(X)	unused
+ *				# X[] unused
+ *			[1]	map lock *	mapwant sv_t *
+ *				map access	wait for free map space
+ *
+ *	  mapstart(X)-> [2]	# units		unit number
+ *			 :	    :		  :
+ *			[ ]	    0
+ */
+
+#include <linux/types.h>
+
+#define ulong_t uint64_t
+
+struct map
+{
+	unsigned long m_size;	/* number of units available */
+	unsigned long m_addr;	/* address of first available unit */
+};
+
+#define mapstart(X)		&X[2]		/* start of map array */
+
+#define mapsize(X)		X[0].m_size	/* number of empty slots */
+						/* remaining in map array */
+#define maplock(X)		(((spinlock_t *) X[1].m_size))
+
+#define mapout(X)		((sv_t *) X[1].m_addr)
+
+
+extern ulong_t atealloc(struct map *, size_t);
+extern struct map *atemapalloc(ulong_t);
+extern void atefree(struct map *, size_t, ulong_t);
+extern void atemapfree(struct map *);
+
+#endif /* _ASM_IA64_SN_ATE_UTILS_H  */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/bte.h linux/include/asm-ia64/sn/bte.h
--- linux.orig/include/asm-ia64/sn/bte.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/bte.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,92 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_BTE_H
+#define _ASM_IA64_SN_BTE_H
+
+#ident "$Revision: 1.1 $"
+
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+#include <asm/sn/io.h>
+
+#define L1_CACHE_MASK (L1_CACHE_BYTES - 1)	/* Mask to retrieve
+						 * the offset into this
+						 * cache line.*/
+
+/* BTE status register only supports 16 bits for length field */
+#define BTE_LEN_BITS (16)
+#define BTE_LEN_MASK ((1 << BTE_LEN_BITS) - 1)
+#define BTE_MAX_XFER ((1 << BTE_LEN_BITS) * L1_CACHE_BYTES)
+
+
+/*
+ * Constants used in determining the best and worst case transfer
+ * times. To help explain the two, the following graph of transfer
+ * status vs time may help.
+ *
+ *     active +------------------:-+  :
+ *  status    |                  : |  :
+ *       idle +__________________:_+=======
+ *            0 Time           MaxT  MinT
+ *
+ *  Therefore, MaxT is the maximum thoeretical rate for transfering
+ *  the request block (assuming ideal circumstances)
+ *
+ *  MinT is the minimum theoretical rate for transferring the
+ *  requested block (assuming maximum link distance and contention)
+ *
+ *  The following defines are the inverse of the above.  They are
+ *  used for calculating the MaxT time and MinT time given the 
+ *  number of lines in the transfer.
+ */
+#define BTE_MAXT_LINES_PER_SECOND 800
+#define BTE_MINT_LINES_PER_SECOND 600
+
+
+/* Define hardware */
+#define BTES_PER_NODE 2
+
+/* Define hardware modes */
+#define BTE_NOTIFY (IBCT_NOTIFY)
+#define BTE_NORMAL BTE_NOTIFY
+#define BTE_ZERO_FILL (BTE_NOTIFY | IBCT_ZFIL_MODE)
+
+/* Use a reserved bit to let the caller specify a wait for any BTE */
+#define BTE_WACQUIRE (0x4000)
+
+/*
+ * Structure defining a bte.  An instance of this
+ * structure is created in the nodepda for each
+ * bte on that node (as defined by BTES_PER_NODE)
+ * This structure contains everything necessary
+ * to work with a BTE.
+ */
+typedef struct bteinfo_s {
+	u64 volatile notify ____cacheline_aligned;
+	char *bte_base_addr ____cacheline_aligned;
+	spinlock_t spinlock;
+	u64 idealTransferTimeout;
+	u64 idealTransferTimeoutReached;
+	u64 mostRecentSrc;
+	u64 mostRecentDest;
+	u64 mostRecentLen;
+	u64 mostRecentMode;
+	u64 volatile *mostRecentNotification;
+	void *bteTestBuf;
+} bteinfo_t;
+
+/* Possible results from bte_copy and bte_unaligned_copy */
+typedef enum {
+	BTE_SUCCESS,		/* 0 is success */
+	BTEFAIL_NOTAVAIL,	/* BTE not available */
+	BTEFAIL_ERROR,		/* Generic error */
+	BTEFAIL_DIR		/* Diretory error */
+} bte_result_t;
+
+#endif				/* _ASM_IA64_SN_BTE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/bte_copy.h linux/include/asm-ia64/sn/bte_copy.h
--- linux.orig/include/asm-ia64/sn/bte_copy.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/bte_copy.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,311 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_BTE_COPY_H
+#define _ASM_IA64_SN_BTE_COPY_H
+
+#ident "$Revision: 1.1 $"
+
+#include <asm/sn/bte.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/pda.h>
+#include <asm/delay.h>
+
+/*
+ * BTE_LOCKING support - Undefining the following line will
+ * adapt the bte_copy code to support one bte per cpu in
+ * synchronous mode.  Even if bte_copy is called with a
+ * notify address, the bte will spin and wait for the transfer
+ * to complete.  By defining the following, spin_locks and
+ * busy checks are placed around the initiation of a BTE
+ * transfer and multiple bte's per cpu are supported.
+ */
+#define CONFIG_IA64_SGI_BTE_LOCKING 1
+
+/*
+ * Some macros to simplify reading.
+ *
+ * Start with macros to locate the BTE control registers.
+ */
+
+#define BTEREG_LNSTAT_ADDR (bte->bte_base_addr)
+#define BTEREG_SOURCE_ADDR (bte->bte_base_addr + IIO_IBSA0 - IIO_IBLS0)
+#define BTEREG_DEST_ADDR (bte->bte_base_addr + IIO_IBDA0 - IIO_IBLS0)
+#define BTEREG_CTRL_ADDR ((volatile char *)bte->bte_base_addr + IIO_IBCT0 - IIO_IBLS0)
+#define BTEREG_NOTIF_ADDR (bte->bte_base_addr + IIO_IBNA0 - IIO_IBLS0)
+
+/* Some macros to force the IBCT0 value valid. */
+
+#define BTE_VALID_MODES BTE_NOTIFY
+#define BTE_VLD_MODE(x) (x & BTE_VALID_MODES)
+
+// #define DEBUG_BTE
+// #define DEBUG_BTE_VERBOSE
+// #define DEBUG_TIME_BTE
+
+#ifdef DEBUG_BTE
+#  define DPRINTK(x) printk x	// Terse
+#  ifdef DEBUG_BTE_VERBOSE
+#    define DPRINTKV(x) printk x	// Verbose
+#  else
+#    define DPRINTKV(x)
+#  endif
+#else
+#  define DPRINTK(x)
+#  define DPRINTKV(x)
+#endif
+
+#ifdef DEBUG_TIME_BTE
+extern u64 BteSetupTime;
+extern u64 BteTransferTime;
+extern u64 BteTeardownTime;
+extern u64 BteExecuteTime;
+#endif
+
+/*
+ * bte_copy(src, dest, len, mode, notification)
+ *
+ * use the block transfer engine to move kernel
+ * memory from src to dest using the assigned mode.
+ *
+ * Paramaters:
+ *   src - physical address of the transfer source.
+ *   dest - physical address of the transfer destination.
+ *   len - number of bytes to transfer from source to dest.
+ *   mode - hardware defined.  See reference information
+ *          for IBCT0/1 in the SHUB Programmers Reference
+ *   notification - kernel virtual address of the notification cache
+ *                  line.  If NULL, the default is used and
+ *                  the bte_copy is synchronous.
+ *
+ * NOTE:  This function requires src, dest, and len to
+ * be cache line aligned.
+ */
+extern __inline__ bte_result_t
+bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
+{
+#ifdef CONFIG_IA64_SGI_BTE_LOCKING
+	int bte_to_use;
+#endif
+
+#ifdef DEBUG_TIME_BTE
+	u64 invokeTime = 0;
+	u64 completeTime = 0;
+	u64 xferStartTime = 0;
+	u64 xferCompleteTime = 0;
+#endif
+	u64 transferSize;
+	bteinfo_t *bte;
+
+#ifdef DEBUG_TIME_BTE
+	invokeTime = ia64_get_itc();
+#endif
+
+	DPRINTK(("bte_copy (0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
+		 src, dest, len, mode, notification));
+
+	if (len == 0) {
+		return (BTE_SUCCESS);
+	}
+
+	ASSERT(!((len & L1_CACHE_MASK) ||
+		 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)));
+
+	ASSERT(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT));
+
+#ifdef CONFIG_IA64_SGI_BTE_LOCKING
+	{
+		bte_to_use = 0;
+
+		/* Attempt to lock one of the BTE interfaces */
+		while ((*pda.cpubte[bte_to_use]->
+			mostRecentNotification & IBLS_BUSY)
+		       &&
+		       (!(spin_trylock
+			  (&(pda.cpubte[bte_to_use]->spinlock))))
+		       && (bte_to_use < BTES_PER_NODE)) {
+			bte_to_use++;
+		}
+
+		if ((bte_to_use >= BTES_PER_NODE) &&
+		    !(mode & BTE_WACQUIRE)) {
+			return (BTEFAIL_NOTAVAIL);
+		}
+
+		/* Wait until a bte is available. */
+	}
+	while (bte_to_use >= BTES_PER_NODE);
+
+	bte = pda.cpubte[bte_to_use];
+	DPRINTKV(("Got a lock on bte %d\n", bte_to_use));
+#else
+	/* Assuming one BTE per CPU. */
+	bte = pda.cpubte[0];
+#endif
+
+	/*
+	 * The following are removed for optimization but is
+	 * available in the event that the SHUB exhibits
+	 * notification problems similar to the hub, bedrock et al.
+	 *
+	 * bte->mostRecentSrc = src;
+	 * bte->mostRecentDest = dest;
+	 * bte->mostRecentLen = len;
+	 * bte->mostRecentMode = mode;
+	 */
+	if (notification == NULL) {
+		/* User does not want to be notified. */
+		bte->mostRecentNotification = &bte->notify;
+	} else {
+		bte->mostRecentNotification = notification;
+	}
+
+	/* Calculate the number of cache lines to transfer. */
+	transferSize = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);
+
+	DPRINTKV(("Calculated transfer size of %d cache lines\n",
+		  transferSize));
+
+	/* Initialize the notification to a known value. */
+	*bte->mostRecentNotification = -1L;
+
+
+	DPRINTKV(("Before, status is 0x%lx and notify is 0x%lx\n",
+		  HUB_L(BTEREG_LNSTAT_ADDR),
+		  *bte->mostRecentNotification));
+
+	/* Set the status reg busy bit and transfer length */
+	DPRINTKV(("IBLS - HUB_S(0x%lx, 0x%lx)\n",
+		  BTEREG_LNSTAT_ADDR, IBLS_BUSY | transferSize));
+	HUB_S(BTEREG_LNSTAT_ADDR, IBLS_BUSY | transferSize);
+
+
+	DPRINTKV(("After setting status, status is 0x%lx and notify is 0x%lx\n", HUB_L(BTEREG_LNSTAT_ADDR), *bte->mostRecentNotification));
+
+	/* Set the source and destination registers */
+	DPRINTKV(("IBSA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_SOURCE_ADDR,
+		  src));
+	HUB_S(BTEREG_SOURCE_ADDR, src);
+	DPRINTKV(("IBDA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_DEST_ADDR, dest));
+	HUB_S(BTEREG_DEST_ADDR, dest);
+
+
+	/* Set the notification register */
+	DPRINTKV(("IBNA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_NOTIF_ADDR,
+		  __pa(bte->mostRecentNotification)));
+	HUB_S(BTEREG_NOTIF_ADDR, (__pa(bte->mostRecentNotification)));
+
+
+	DPRINTKV(("Set Notify, status is 0x%lx and notify is 0x%lx\n",
+		  HUB_L(BTEREG_LNSTAT_ADDR),
+		  *bte->mostRecentNotification));
+
+	/* Initiate the transfer */
+	DPRINTKV(("IBCT - HUB_S(0x%lx, 0x%lx)\n", BTEREG_CTRL_ADDR, mode));
+#ifdef DEBUG_TIME_BTE
+	xferStartTime = ia64_get_itc();
+#endif
+	HUB_S(BTEREG_CTRL_ADDR, BTE_VLD_MODE(mode));
+
+	DPRINTKV(("Initiated, status is 0x%lx and notify is 0x%lx\n",
+		  HUB_L(BTEREG_LNSTAT_ADDR),
+		  *bte->mostRecentNotification));
+
+	// >>> Temporarily work around not getting a notification
+	// from medusa.
+	// *bte->mostRecentNotification = HUB_L(bte->bte_base_addr);
+
+	if (notification == NULL) {
+		/*
+		 * Calculate our timeout
+		 *
+		 * What are we doing here?  We are trying to determine
+		 * the fastest time the BTE could have transfered our
+		 * block of data.  By takine the clock frequency (ticks/sec)
+		 * divided by the BTE MaxT Transfer Rate (lines/sec)
+		 * times the transfer size (lines), we get a tick
+		 * offset from current time that the transfer should
+		 * complete.
+		 *
+		 * Why do this?  We are watching for a notification
+		 * failure from the BTE.  This behaviour has been
+		 * seen in the SN0 and SN1 hardware on rare circumstances
+		 * and is expected in SN2.  By checking at the
+		 * ideal transfer timeout, we minimize our time
+		 * delay from hardware completing our request and
+		 * our detecting the failure.
+		 */
+		bte->idealTransferTimeout = jiffies +
+		    (HZ / BTE_MAXT_LINES_PER_SECOND * transferSize);
+
+		while ((IBLS_BUSY & bte->notify)) {
+			/*
+			 * Notification Workaround: When the max
+			 * theoretical time has elapsed, read the hub
+			 * status register into the notification area.
+			 * This fakes the shub performing the copy.
+			 */
+			if (jiffies > bte->idealTransferTimeout) {
+				bte->notify = HUB_L(bte->bte_base_addr);
+				bte->idealTransferTimeoutReached++;
+				bte->idealTransferTimeout = jiffies +
+				    (HZ / BTE_MAXT_LINES_PER_SECOND *
+				     (bte->notify & BTE_LEN_MASK));
+			}
+		}
+#ifdef DEBUG_TIME_BTE
+		xferCompleteTime = ia64_get_itc();
+#endif
+		if (bte->notify & IBLS_ERROR) {
+			/* >>> Need to do real error checking. */
+			transferSize = 0;
+
+#ifdef CONFIG_IA64_SGI_BTE_LOCKING
+			spin_unlock(&(bte->spinlock));
+#endif
+			return (BTEFAIL_ERROR);
+		}
+
+	}
+#ifdef CONFIG_IA64_SGI_BTE_LOCKING
+	spin_unlock(&(bte->spinlock));
+#endif
+#ifdef DEBUG_TIME_BTE
+	completeTime = ia64_get_itc();
+
+	BteSetupTime = xferStartTime - invokeTime;
+	BteTransferTime = xferCompleteTime - xferStartTime;
+	BteTeardownTime = completeTime - xferCompleteTime;
+	BteExecuteTime = completeTime - invokeTime;
+#endif
+	return (BTE_SUCCESS);
+}
+
+/*
+ * Define the bte_unaligned_copy as an extern.
+ */
+extern bte_result_t bte_unaligned_copy(u64, u64, u64, u64, char *);
+
+/*
+ * The following is the prefered way of calling bte_unaligned_copy
+ * If the copy is fully cache line aligned, then bte_copy is
+ * used instead.  Since bte_copy is inlined, this saves a call
+ * stack.  NOTE: bte_copy is called synchronously and does block
+ * until the transfer is complete.  In order to get the asynch
+ * version of bte_copy, you must perform this check yourself.
+ */
+#define BTE_UNALIGNED_COPY(src, dest, len, mode, bteBlock) \
+	if ((len & L1_CACHE_MASK) || \
+	    (src & L1_CACHE_MASK) || \
+	    (dest & L1_CACHE_MASK)) { \
+		bte_unaligned_copy (src, dest, len, mode, bteBlock); \
+	} else { \
+		bte_copy(src, dest, len, mode, NULL); \
+	}
+
+#endif				/* _ASM_IA64_SN_BTE_COPY_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/cdl.h linux/include/asm-ia64/sn/cdl.h
--- linux.orig/include/asm-ia64/sn/cdl.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/cdl.h	2002-07-20 01:08:38.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_CDL_H
-#define _ASM_SN_CDL_H
+#ifndef _ASM_IA64_SN_CDL_H
+#define _ASM_IA64_SN_CDL_H
 
 #include <asm/sn/sgi.h>
 
@@ -193,4 +192,4 @@
 void		async_attach_signal_done(async_attach_t);
 void		async_attach_waitall(async_attach_t);
 
-#endif	/* _ASM_SN_CDL_H */
+#endif /* _ASM_IA64_SN_CDL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/clksupport.h linux/include/asm-ia64/sn/clksupport.h
--- linux.orig/include/asm-ia64/sn/clksupport.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/clksupport.h	2002-07-20 01:08:38.000000000 +0000
@@ -4,61 +4,60 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
-
-#ifndef  _ASM_KSYS_CLKSUPPORT_H
-#define _ASM_KSYS_CLKSUPPORT_H
-
-/* #include <sys/mips_addrspace.h> */
-
-#if SN
-#include <asm/sn/agent.h>
-#include <asm/sn/intr_public.h>
-typedef hubreg_t clkreg_t;
-extern nasid_t master_nasid;
-
-#define GET_LOCAL_RTC		(clkreg_t)LOCAL_HUB_L(PI_RT_COUNT)
-#define DISABLE_TMO_INTR()	if  (cpuid_to_localslice(cpuid())) \
-					REMOTE_HUB_PI_S(get_nasid(),\
-						cputosubnode(cpuid()),\
-						PI_RT_COMPARE_B, 0); \
-				else \
-					REMOTE_HUB_PI_S(get_nasid(),\
-						cputosubnode(cpuid()),\
-						PI_RT_COMPARE_A, 0);
-
-/* This is a hack; we really need to figure these values out dynamically */
-/* 
- * Since 800 ns works very well with various HUB frequencies, such as
- * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
- */
-#define NSEC_PER_CYCLE		800
-#define CYCLE_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
 /*
- * Number of cycles per profiling intr 
+ * This file contains definitions for accessing a platform supported high resolution
+ * clock. The clock is monitonically increasing and can be accessed from any node
+ * in the system. The clock is synchronized across nodes - all nodes see the
+ * same value.
+ * 
+ *	RTC_COUNTER_ADDR - contains the address of the counter 
+ *
+ *	GET_RTC_COUNTER() - macro to read the value of the clock
+ *
+ *	RTC_CYCLES_PER_SEC - clock frequency in ticks per second	
+ *
  */
-#define CLK_FCLOCK_FAST_FREQ	1250
-#define CLK_FCLOCK_SLOW_FREQ	0
-/* The is the address that the user will use to mmap the cycle counter */
-#define CLK_CYCLE_ADDRESS_FOR_USER LOCAL_HUB_ADDR(PI_RT_COUNT)
-
-#elif IP30
-#include <sys/cpu.h>
-typedef heartreg_t clkreg_t;
-#define NSEC_PER_CYCLE		80
-#define CYCLE_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
-#define GET_LOCAL_RTC	*((volatile clkreg_t *)PHYS_TO_COMPATK1(HEART_COUNT))
-#define DISABLE_TMO_INTR()
-#define CLK_CYCLE_ADDRESS_FOR_USER PHYS_TO_K1(HEART_COUNT)
-#define CLK_FCLOCK_SLOW_FREQ (CYCLE_PER_SEC / HZ)
+
+#ifndef _ASM_IA64_SN_CLKSUPPORT_H
+#define _ASM_IA64_SN_CLKSUPPORT_H
+
+#include <linux/config.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+
+typedef long clkreg_t;
+extern long sn_rtc_cycles_per_second;
+
+
+#if defined(CONFIG_IA64_SGI_SN1)
+#include <asm/sn/sn1/bedrock.h>
+#include <asm/sn/sn1/hubpi_next.h>
+/* clocks are not synchronized yet on SN1  - used node 0 (problem if no NASID 0) */
+#define RTC_COUNTER_ADDR	((clkreg_t*)REMOTE_HUB_ADDR(0, PI_RT_COUNTER))
+#define RTC_COMPARE_A_ADDR      ((clkreg_t*)REMOTE_HUB_ADDR(0, PI_RT_COMPARE_A))
+#define RTC_COMPARE_B_ADDR      ((clkreg_t*)REMOTE_HUB_ADDR(0, PI_RT_COMPARE_B))
+#define RTC_INT_PENDING_A_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(0, PI_RT_INT_PEND_A))
+#define RTC_INT_PENDING_B_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(0, PI_RT_INT_PEND_B))
+#define RTC_INT_ENABLED_A_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(0, PI_RT_INT_EN_A))
+#define RTC_INT_ENABLED_B_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(0, PI_RT_INT_EN_B))
+#else
+#include <asm/sn/sn2/shub_mmr.h>
+#define RTC_COUNTER_ADDR	((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
+#define RTC_COMPARE_A_ADDR      ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
+#define RTC_COMPARE_B_ADDR      ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
+#define RTC_INT_PENDING_A_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
+#define RTC_INT_PENDING_B_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
+#define RTC_INT_ENABLED_A_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
+#define RTC_INT_ENABLED_B_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #endif
 
-/* Prototypes */
-extern void init_timebase(void);
-extern void fastick_maint(struct eframe_s *);
-extern int audioclock;
-extern int prfclk_enabled_cnt;
-#endif  /* _ASM_KSYS_CLKSUPPORT_H */
+
+#define GET_RTC_COUNTER()	(*RTC_COUNTER_ADDR)
+#define rtc_time()		GET_RTC_COUNTER()
+
+#define RTC_CYCLES_PER_SEC	sn_rtc_cycles_per_second
+
+#endif /* _ASM_IA64_SN_CLKSUPPORT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/dmamap.h linux/include/asm-ia64/sn/dmamap.h
--- linux.orig/include/asm-ia64/sn/dmamap.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/dmamap.h	2002-07-20 01:08:33.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_DMAMAP_H
-#define _ASM_SN_DMAMAP_H
+#ifndef _ASM_IA64_SN_DMAMAP_H
+#define _ASM_IA64_SN_DMAMAP_H
 
 #include <asm/sn/sv.h>
 
@@ -70,7 +69,6 @@
 extern int a24_mapsize;
 extern int a32_mapsize;
 
-extern lock_t dmamaplock;
 extern sv_t dmamapout;
 
 #ifdef __cplusplus
@@ -87,4 +85,4 @@
 
 #define	DMAMAP_FLAGS	0x7
 
-#endif /* _ASM_SN_DMAMAP_H */
+#endif /* _ASM_IA64_SN_DMAMAP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/driver.h linux/include/asm-ia64/sn/driver.h
--- linux.orig/include/asm-ia64/sn/driver.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/driver.h	2002-07-20 01:08:34.000000000 +0000
@@ -4,11 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_DRIVER_H
-#define _ASM_SN_DRIVER_H
+#ifndef _ASM_IA64_SN_DRIVER_H
+#define _ASM_IA64_SN_DRIVER_H
+
+#include <linux/devfs_fs_kernel.h>
+#include <asm/types.h>
 
 /*
 ** Interface for device driver handle management.
@@ -18,133 +20,77 @@
 */
 
 typedef struct device_driver_s *device_driver_t;
-#define DEVICE_DRIVER_NONE (device_driver_t)NULL
 
 /* == Driver thread priority support == */
 typedef int ilvl_t;
-/* default driver thread priority level */
-#define DRIVER_THREAD_PRI_DEFAULT	(ilvl_t)230
-/* invalid driver thread priority level */
-#define DRIVER_THREAD_PRI_INVALID	(ilvl_t)-1
-
-/* Associate a thread priority with a driver */
-extern int device_driver_thread_pri_set(device_driver_t driver,
-					ilvl_t pri);
-
-/* Get the thread priority associated with the driver */
-extern ilvl_t device_driver_thread_pri_get(device_driver_t driver);
-
-/* Get the thread priority for a driver from the sysgen paramters */
-extern ilvl_t device_driver_sysgen_thread_pri_get(char *driver_prefix);
-
-/* Initialize device driver functions. */
-extern void device_driver_init(void);
-
-
-/* Allocate a driver handle */
-extern device_driver_t device_driver_alloc(char *prefix);
-
-
-/* Free a driver handle */
-extern void device_driver_free(device_driver_t driver);
-
-
-/* Given a device driver prefix, return a handle to the driver. */
-extern device_driver_t device_driver_get(char *prefix);
-
-/* Given a device, return a handle to the driver. */
-extern device_driver_t device_driver_getbydev(devfs_handle_t device);
-
-struct cdevsw;
-struct bdevsw;
 
-/* Associate a driver with bdevsw/cdevsw pointers. */
-extern int
-device_driver_devsw_put(device_driver_t driver,
-			struct bdevsw *my_bdevsw,
-			struct cdevsw *my_cdevsw);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct eframe_s;
+struct piomap;
+struct dmamap;
+
+typedef __psunsigned_t iobush_t;
+
+/* interrupt function */
+typedef void	       *intr_arg_t;
+typedef void		intr_func_f(intr_arg_t);
+typedef intr_func_f    *intr_func_t;
+
+#define	INTR_ARG(n)	((intr_arg_t)(__psunsigned_t)(n))
+
+/* system interrupt resource handle -- returned from intr_alloc */
+typedef struct intr_s *intr_t;
+#define INTR_HANDLE_NONE ((intr_t)0)
 
-
-/* Given a driver, return the corresponding bdevsw and cdevsw pointers. */
-extern void
-device_driver_devsw_get(	device_driver_t driver, 
-				struct bdevsw **bdevswp,
-				struct cdevsw **cdevswp);
-
-/* Given a driver, return its name (prefix). */
-extern void device_driver_name_get(device_driver_t driver, char *buffer, int length);
+/*
+ * restore interrupt level value, returned from intr_block_level
+ * for use with intr_unblock_level.
+ */
+typedef void *rlvl_t;
 
 
 /* 
- * A descriptor for every static device driver in the system.
- * lboot creates a table of these and places in in master.c.
- * device_driver_init runs through this table during initialization
- * in order to "register" every static device driver.
+ * A basic, platform-independent description of I/O requirements for
+ * a device. This structure is usually formed by lboot based on information 
+ * in configuration files.  It contains information about PIO, DMA, and
+ * interrupt requirements for a specific instance of a device.
+ *
+ * The pio description is currently unused.
+ *
+ * The dma description describes bandwidth characteristics and bandwidth
+ * allocation requirements. (TBD)
+ *
+ * The Interrupt information describes the priority of interrupt, desired 
+ * destination, policy (TBD), whether this is an error interrupt, etc.  
+ * For now, interrupts are targeted to specific CPUs.
  */
-typedef struct static_device_driver_desc_s {
-	char 		*sdd_prefix;
-	struct bdevsw 	*sdd_bdevsw;
-	struct cdevsw 	*sdd_cdevsw;
-} *static_device_driver_desc_t;
-
-extern struct static_device_driver_desc_s static_device_driver_table[];
-extern int static_devsw_count;
 
+typedef struct device_desc_s {
+	/* pio description (currently none) */
 
-/*====== administration support ========== */
-/* structure of each entry in the table created by lboot for
- * device / driver administration
-*/
-typedef struct dev_admin_info_s {
-	char	*dai_name;		/* name of the device or driver
-					 * prefix 
-					 */
-	char	*dai_param_name;	/* device or driver parameter name */
-	char	*dai_param_val;		/* value of the parameter */
-} dev_admin_info_t;
-
-
-/* Update all the administrative hints associated with the device */
-extern void 	device_admin_info_update(devfs_handle_t	dev_vhdl);
-
-/* Update all the administrative hints associated with the device driver */
-extern void	device_driver_admin_info_update(device_driver_t	driver);
-
-/* Get a particular administrative hint associated with a device */
-extern char 	*device_admin_info_get(devfs_handle_t	dev_vhdl,
-				       char		*info_lbl);
-
-/* Associate a particular administrative hint for a device */
-extern int	device_admin_info_set(devfs_handle_t	dev_vhdl,
-				      char		*info_lbl,
-				      char		*info_val);
-
-/* Get a particular administrative hint associated with a device driver*/
-extern char 	*device_driver_admin_info_get(char	*driver_prefix,	
-					      char	*info_name);
-
-/* Associate a particular administrative hint for a device driver*/
-extern int	device_driver_admin_info_set(char	*driver_prefix,
-					     char	*driver_info_lbl,
-					     char	*driver_info_val);
-
-/* Initialize the extended device administrative hint table */
-extern void	device_admin_table_init(void);
-
-/* Add a hint corresponding to a device to the extended device administrative
- * hint table.
- */
-extern void	device_admin_table_update(char *dev_name,
-					  char *param_name,
-					  char *param_val);
-
-/* Initialize the extended device driver administrative hint table */
-extern void	device_driver_admin_table_init(void);
+	/* dma description */
+	/* TBD: allocated badwidth requirements */
 
-/* Add a hint corresponding to a device to the extended device driver 
- * administrative hint table.
- */
-extern void	device_driver_admin_table_update(char *drv_prefix,
-						 char *param_name,
-						 char *param_val);	
-#endif /* _ASM_SN_DRIVER_H */
+	/* interrupt description */
+	devfs_handle_t	intr_target;	/* Hardware locator string */
+	int 		intr_policy;	/* TBD */
+	ilvl_t		intr_swlevel;	/* software level for blocking intr */
+	char		*intr_name;	/* name of interrupt, if any */
+
+	int		flags;
+} *device_desc_t;
+
+/* flag values */
+#define	D_INTR_ISERR	0x1		/* interrupt is for error handling */
+#define D_IS_ASSOC	0x2		/* descriptor is associated with a dev */
+#define D_INTR_NOTHREAD	0x4		/* Interrupt handler isn't threaded. */
+
+#define INTR_SWLEVEL_NOTHREAD_DEFAULT 	0	/* Default
+						 * Interrupt level in case of
+						 * non-threaded interrupt 
+						 * handlers
+						 */
+#endif /* _ASM_IA64_SN_DRIVER_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/eeprom.h linux/include/asm-ia64/sn/eeprom.h
--- linux.orig/include/asm-ia64/sn/eeprom.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/eeprom.h	2002-07-20 01:08:37.000000000 +0000
@@ -6,11 +6,10 @@
  *
  * Public interface for reading Atmel EEPROMs via L1 system controllers
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_EEPROM_H
-#define _ASM_SN_EEPROM_H
+#ifndef _ASM_IA64_SN_EEPROM_H
+#define _ASM_IA64_SN_EEPROM_H
 
 #include <asm/sn/sgi.h>
 #include <asm/sn/vector.h>
@@ -385,14 +384,8 @@
 		          ( IO_BRICK, NASID_GET((r)), (v), 0 ) \
 		      : nic_bridge_vertex_info((v), (r)) )
 
-#ifdef BRINGUP /* will we read mfg info from IOC3's that aren't
-		* part of IO7 cards, or aren't in I/O bricks? */
-#define IOC3_VERTEX_MFG_INFO(v, r, e) \
-    eeprom_vertex_info_set( IO_IO7, NASID_GET((r)), (v), 0 )
-#endif /* BRINGUP */
-
 #define HUB_UID_GET(n,v,p)	cbrick_uid_get((n),(p))
 #define ROUTER_UID_GET(d,p)	rbrick_uid_get(get_nasid(),(d),(p))
 #define XBOW_UID_GET(n,p)	iobrick_uid_get((n),(p))
 
-#endif /* _ASM_SN_EEPROM_H */
+#endif /* _ASM_IA64_SN_EEPROM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/fetchop.h linux/include/asm-ia64/sn/fetchop.h
--- linux.orig/include/asm-ia64/sn/fetchop.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/fetchop.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,40 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+
+#ifndef _ASM_IA64_SN_FETCHOP_H
+#define _ASM_IA64_SN_FETCHOP_H
+
+#define FETCHOP_BASENAME	"sgi_fetchop"
+#define FETCHOP_FULLNAME	"/dev/sgi_fetchop"
+
+
+
+#define FETCHOP_VAR_SIZE 64 /* 64 byte per fetchop variable */
+
+#define FETCHOP_LOAD		0
+#define FETCHOP_INCREMENT	8
+#define FETCHOP_DECREMENT	16
+#define FETCHOP_CLEAR		24
+
+#define FETCHOP_STORE		0
+#define FETCHOP_AND		24
+#define FETCHOP_OR		32
+
+#define FETCHOP_CLEAR_CACHE	56
+
+#define FETCHOP_LOAD_OP(addr, op) ( \
+         *(long *)((char*) (addr) + (op)))
+
+#define FETCHOP_STORE_OP(addr, op, x) ( \
+         *(long *)((char*) (addr) + (op)) = \
+              (long) (x))
+
+#endif /* _ASM_IA64_SN_FETCHOP_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/gda.h linux/include/asm-ia64/sn/gda.h
--- linux.orig/include/asm-ia64/sn/gda.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/gda.h	2002-07-20 01:08:38.000000000 +0000
@@ -6,16 +6,17 @@
  *
  * Derived from IRIX <sys/SN/gda.h>.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  *
  * gda.h -- Contains the data structure for the global data area,
  * 	The GDA contains information communicated between the
  *	PROM, SYMMON, and the kernel. 
  */
-#ifndef _ASM_SN_GDA_H
-#define _ASM_SN_GDA_H
+#ifndef _ASM_IA64_SN_GDA_H
+#define _ASM_IA64_SN_GDA_H
 
 #include <asm/sn/addrs.h>
+#include <asm/sn/sn_cpuid.h>
 
 #define GDA_MAGIC	0x58464552
 
@@ -42,7 +43,7 @@
 #define G_PARTIDOFF	40
 #define G_TABLEOFF	128
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef struct gda {
 	u32	g_magic;	/* GDA magic number */
@@ -68,7 +69,7 @@
 
 #define GDA ((gda_t*) GDA_ADDR(get_nasid()))
 
-#endif /* __LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 /*
  * Define:	PART_GDA_VERSION
  * Purpose:	Define the minimum version of the GDA required, lower 
@@ -105,4 +106,4 @@
 #define PROMOP_BIST1		0x0800		/* keep track of which BIST ran */
 #define PROMOP_BIST2		0x1000		/* keep track of which BIST ran */
 
-#endif /* _ASM_SN_GDA_H */
+#endif /* _ASM_IA64_SN_GDA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/hack.h linux/include/asm-ia64/sn/hack.h
--- linux.orig/include/asm-ia64/sn/hack.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/hack.h	2002-07-20 01:08:27.000000000 +0000
@@ -4,13 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 
-#ifndef _ASM_SN_HACK_H
-#define _ASM_SN_HACK_H
+#ifndef _ASM_IA64_SN_HACK_H
+#define _ASM_IA64_SN_HACK_H
 
 #include <asm/sn/types.h>
 #include <asm/uaccess.h>		/* for copy_??_user */
@@ -32,7 +31,6 @@
 #include <linux/devfs_fs_kernel.h>
 
 #define DELAY(a)
-#define cpuid() 0
 
 /************************************************
  * Routines redefined to use linux equivalents. *
@@ -59,14 +57,14 @@
 #define spl7	splhi()
 #define splx(s)
 
-extern void * kmem_alloc_node(register size_t, register int, cnodeid_t);
-extern void * kmem_zalloc(size_t, int);
-extern void * kmem_zalloc_node(register size_t, register int, cnodeid_t );
-extern void * kmem_zone_alloc(register zone_t *, int);
-extern zone_t * kmem_zone_init(register int , char *);
-extern void kmem_zone_free(register zone_t *, void *);
+extern void * snia_kmem_alloc_node(register size_t, register int, cnodeid_t);
+extern void * snia_kmem_zalloc(size_t, int);
+extern void * snia_kmem_zalloc_node(register size_t, register int, cnodeid_t );
+extern void * snia_kmem_zone_alloc(register zone_t *, int);
+extern zone_t * snia_kmem_zone_init(register int , char *);
+extern void snia_kmem_zone_free(register zone_t *, void *);
 extern int is_specified(char *);
 extern int cap_able(uint64_t);
 extern int compare_and_swap_ptr(void **, void *, void *);
 
-#endif	/* _ASM_SN_HACK_H */
+#endif /* _ASM_IA64_SN_HACK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/hcl.h linux/include/asm-ia64/sn/hcl.h
--- linux.orig/include/asm-ia64/sn/hcl.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/hcl.h	2002-07-20 01:08:33.000000000 +0000
@@ -4,13 +4,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_HCL_H
-#define _ASM_SN_HCL_H
+#ifndef _ASM_IA64_SN_HCL_H
+#define _ASM_IA64_SN_HCL_H
+
+#include <asm/sn/sgi.h>
+#include <asm/sn/invent.h>
+#include <linux/devfs_fs_kernel.h>
 
-extern spinlock_t hcl_spinlock;
 extern devfs_handle_t hcl_handle; /* HCL driver */
 extern devfs_handle_t hwgraph_root;
 extern devfs_handle_t linux_busnum;
@@ -93,7 +95,6 @@
 extern devfs_handle_t hwgraph_char_device_get(devfs_handle_t);
 extern graph_error_t hwgraph_char_device_add(devfs_handle_t, char *, char *, devfs_handle_t *);
 extern int hwgraph_path_add(devfs_handle_t, char *, devfs_handle_t *);
-extern struct file_operations * hwgraph_bdevsw_get(devfs_handle_t);
 extern int hwgraph_info_add_LBL(devfs_handle_t, char *, arbitrary_info_t);
 extern int hwgraph_info_get_LBL(devfs_handle_t, char *, arbitrary_info_t *);
 extern int hwgraph_info_replace_LBL(devfs_handle_t, char *, arbitrary_info_t,
@@ -111,4 +112,4 @@
 
 
 
-#endif /* _ASM_SN_HCL_H */
+#endif /* _ASM_IA64_SN_HCL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/hcl_util.h linux/include/asm-ia64/sn/hcl_util.h
--- linux.orig/include/asm-ia64/sn/hcl_util.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/hcl_util.h	2002-07-20 01:08:24.000000000 +0000
@@ -4,12 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef _ASM_SN_HCL_UTIL_H
-#define _ASM_SN_HCL_UTIL_H
+#ifndef _ASM_IA64_SN_HCL_UTIL_H
+#define _ASM_IA64_SN_HCL_UTIL_H
+
+#include <linux/devfs_fs_kernel.h>
 
 extern char * dev_to_name(devfs_handle_t, char *, uint);
 extern int device_master_set(devfs_handle_t, devfs_handle_t);
@@ -17,8 +18,5 @@
 extern cnodeid_t master_node_get(devfs_handle_t);
 extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t);
 extern void mark_nodevertex_as_node(devfs_handle_t, cnodeid_t);
-extern void device_info_set(devfs_handle_t, void *);
-extern void *device_info_get(devfs_handle_t);
-
 
-#endif _ASM_SN_HCL_UTIL_H
+#endif /* _ASM_IA64_SN_HCL_UTIL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/hires_clock.h linux/include/asm-ia64/sn/hires_clock.h
--- linux.orig/include/asm-ia64/sn/hires_clock.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/hires_clock.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,52 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Silicon Graphics, Inc. All rights reserved.
+ *
+ * SGI Hi Resolution Clock
+ *
+ * SGI SN platforms provide a high resolution clock that is
+ * synchronized across all nodes. The clock can be memory mapped
+ * and directly read from user space.
+ *
+ * Access to the clock is thru the following:
+ *       (error checking not shown)
+ *
+ * (Note: should library routines be provided to encapsulate this??)
+ *
+ *	int		fd:
+ *	volatile long	*clk;
+ *
+ *	fd = open (HIRES_FULLNAME, O_RDONLY);
+ *	clk = mmap(0, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
+ *	clk += ioctl(fd, HIRES_IOCQGETOFFSET, 0);
+ *
+ * At this point, clk is a pointer to the high resolution clock.
+ *
+ * The clock period can be obtained via:
+ *
+ *	long	picosec_per_tick;
+ *	picosec_per_tick = ioctl(fd, HIRES_IOCQGETPICOSEC, 0);
+ */
+
+#ifndef _ASM_IA64_SN_HIRES_CLOCK_H
+#define _ASM_IA64_SN_HIRES_CLOCK_H
+
+
+#define HIRES_BASENAME	"sgi_hires_clock"
+#define HIRES_FULLNAME  "/dev/sgi_hires_clock"
+#define HIRES_IOC_BASE	's'
+
+
+/* Get page offset of hires timer */
+#define HIRES_IOCQGETOFFSET	_IO( HIRES_IOC_BASE, 0 )
+
+/* get clock period in picoseconds per tick */
+#define HIRES_IOCQGETPICOSEC	_IO( HIRES_IOC_BASE, 1 )
+
+/* get number of significant bits in clock counter */
+#define HIRES_IOCQGETCLOCKBITS	_IO( HIRES_IOC_BASE, 2 )
+
+#endif /* _ASM_IA64_SN_HIRES_CLOCK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/hubspc.h linux/include/asm-ia64/sn/hubspc.h
--- linux.orig/include/asm-ia64/sn/hubspc.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/hubspc.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,25 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_HUBSPC_H
-#define _ASM_SN_HUBSPC_H
-
-typedef enum {
-        HUBSPC_REFCOUNTERS,
-	HUBSPC_PROM
-} hubspc_subdevice_t;
-
-
-/*
- * Reference Counters
- */
-
-extern int refcounters_attach(devfs_handle_t hub);
-
-#endif /* _ASM_SN_HUBSPC_H */        
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/hwcntrs.h linux/include/asm-ia64/sn/hwcntrs.h
--- linux.orig/include/asm-ia64/sn/hwcntrs.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/hwcntrs.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,97 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_HWCNTRS_H
-#define _ASM_SN_HWCNTRS_H
-
-
-typedef  uint64_t refcnt_t;
-
-#define SN0_REFCNT_MAX_COUNTERS 64
-
-typedef struct sn0_refcnt_set {
-	refcnt_t    refcnt[SN0_REFCNT_MAX_COUNTERS];
-        uint64_t  flags;
-        uint64_t  reserved[4];
-} sn0_refcnt_set_t;
-
-typedef struct sn0_refcnt_buf {
-	sn0_refcnt_set_t   refcnt_set;
-	uint64_t         paddr;
-        uint64_t         page_size;
-        cnodeid_t          cnodeid;         /* cnodeid + pad[3] use 64 bits */
-        uint16_t           pad[3];
-        uint64_t         reserved[4];
-} sn0_refcnt_buf_t;
-
-typedef struct sn0_refcnt_args {
-	uint64_t          vaddr;
-	uint64_t          len;
-	sn0_refcnt_buf_t*   buf;
-        uint64_t          reserved[4];
-} sn0_refcnt_args_t;
-
-/*
- * Info needed by the user level program
- * to mmap the refcnt buffer
- */
-
-#define RCB_INFO_GET  1
-#define RCB_SLOT_GET  2
-
-typedef struct rcb_info {
-        uint64_t  rcb_len;                  /* total refcnt buffer len in bytes */
-
-        int         rcb_sw_sets;              /* number of sw counter sets in buffer */
-        int         rcb_sw_counters_per_set;  /* sw counters per set -- numnodes */
-        int         rcb_sw_counter_size;      /* sizeof(refcnt_t) -- size of sw cntr */
-
-        int         rcb_base_pages;           /* number of base pages in node */
-        int         rcb_base_page_size;       /* sw base page size */        
-        uint64_t  rcb_base_paddr;           /* base physical address for this node */
-
-        int         rcb_cnodeid;              /* cnodeid for this node */
-        int         rcb_granularity;          /* hw page size used for counter sets */
-        uint        rcb_hw_counter_max;       /* max hwcounter count (width mask) */
-        int         rcb_diff_threshold;       /* current node differential threshold */
-        int         rcb_abs_threshold;        /* current node absolute threshold */
-        int         rcb_num_slots;            /* physmem slots */
-        
-        int         rcb_reserved[512];
-        
-} rcb_info_t;
-
-typedef struct rcb_slot {
-        uint64_t  base;
-        uint64_t  size;
-} rcb_slot_t;
-
-#if defined(__KERNEL__)
-typedef struct sn0_refcnt_args_32 {
-	uint64_t    vaddr;
-	uint64_t    len;
-	app32_ptr_t   buf;
-        uint64_t    reserved[4];
-} sn0_refcnt_args_32_t;
-
-/* Defines and Macros  */
-/* A set of reference counts are for 4k bytes of physical memory */
-#define	NBPREFCNTP	0x1000	
-#define	BPREFCNTPSHIFT	12
-#define bytes_to_refcntpages(x)	(((__psunsigned_t)(x)+(NBPREFCNTP-1))>>BPREFCNTPSHIFT)
-#define refcntpage_offset(x)	((__psunsigned_t)(x)&((NBPP-1)&~(NBPREFCNTP-1)))
-#define align_to_refcntpage(x)	((__psunsigned_t)(x)&(~(NBPREFCNTP-1)))
-
-extern void migr_refcnt_read(sn0_refcnt_buf_t*);
-extern void migr_refcnt_read_extended(sn0_refcnt_buf_t*);
-extern int migr_refcnt_enabled(void);
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_SN_HWCNTRS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/idle.h linux/include/asm-ia64/sn/idle.h
--- linux.orig/include/asm-ia64/sn/idle.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/idle.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,54 @@
+#ifndef _ASM_IA64_SN_IDLE_H
+#define _ASM_IA64_SN_IDLE_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <asm/sn/leds.h>
+#include <asm/sn/simulator.h>
+
+static __inline__ void
+snidle(void) {
+
+#ifdef CONFIG_IA64_SGI_AUTOTEST
+	{
+		extern int	autotest_enabled;
+		if (autotest_enabled) {
+			extern void llsc_main(int);
+			llsc_main(smp_processor_id());
+		}
+	}
+#endif
+	
+	if (pda.idle_flag == 0) {
+		/* 
+		 * Turn the activity LED off.
+		 */
+		set_led_bits(0, LED_CPU_ACTIVITY);
+	}
+
+#ifdef CONFIG_IA64_SGI_SN_SIM
+	if (IS_RUNNING_ON_SIMULATOR())
+		SIMULATOR_SLEEP();
+#endif
+
+	pda.idle_flag = 1;
+}
+
+static __inline__ void
+snidleoff(void) {
+	/* 
+	 * Turn the activity LED on.
+	 */
+	set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
+
+	pda.idle_flag = 0;
+}
+
+#endif /* _ASM_IA64_SN_IDLE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/ifconfig_net.h linux/include/asm-ia64/sn/ifconfig_net.h
--- linux.orig/include/asm-ia64/sn/ifconfig_net.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/ifconfig_net.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_IFCONFIG_NET_H
+#define _ASM_IA64_SN_IFCONFIG_NET_H
+
+#define NETCONFIG_FILE "/tmp/ifconfig_net"
+#define POUND_CHAR                   '#'
+#define MAX_LINE_LEN 128
+#define MAXPATHLEN 128
+
+struct ifname_num {
+	long next_eth;
+	long next_fddi;
+	long next_hip;
+	long next_tr;
+	long next_fc;
+	long size;
+};
+
+struct ifname_MAC {
+	char name[16];
+	unsigned char           dev_addr[7];
+	unsigned char           addr_len;       /* hardware address length      */
+};
+
+#endif /* _ASM_IA64_SN_IFCONFIG_NET_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/intr.h linux/include/asm-ia64/sn/intr.h
--- linux.orig/include/asm-ia64/sn/intr.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/intr.h	2002-07-20 01:08:29.000000000 +0000
@@ -4,250 +4,21 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_INTR_H
-#define _ASM_SN_INTR_H
-
-/* Subnode wildcard */
-#define SUBNODE_ANY		-1
-
-/* Number of interrupt levels associated with each interrupt register. */
-#define N_INTPEND_BITS		64
-
-#define INT_PEND0_BASELVL	0
-#define INT_PEND1_BASELVL	64
-
-#define	N_INTPENDJUNK_BITS	8
-#define	INTPENDJUNK_CLRBIT	0x80
+#ifndef _ASM_IA64_SN_INTR_H
+#define _ASM_IA64_SN_INTR_H
 
 #include <linux/config.h>
-#include <asm/sn/intr_public.h>
-
-#if LANGUAGE_C
-
-#define II_NAMELEN	24
-
-/*
- * Dispatch table entry - contains information needed to call an interrupt
- * routine.
- */
-typedef struct intr_vector_s {
-	intr_func_t	iv_func;	/* Interrupt handler function */
-	intr_func_t	iv_prefunc;	/* Interrupt handler prologue func */
-	void		*iv_arg;	/* Argument to pass to handler */
-#ifdef LATER
-	thd_int_t		iv_tinfo;	/* Thread info */
-#endif
-	cpuid_t			iv_mustruncpu;	/* Where we must run. */
-} intr_vector_t;
-
-/* Interrupt information table. */
-typedef struct intr_info_s {
-	xtalk_intr_setfunc_t	ii_setfunc;	/* Function to set the interrupt
-						 * destination and level register.
-						 * It returns 0 (success) or an
-						 * error code.
-						 */
-	void			*ii_cookie;	/* arg passed to setfunc */
-	devfs_handle_t		ii_owner_dev;	/* device that owns this intr */
-	char			ii_name[II_NAMELEN];	/* Name of this intr. */
-	int			ii_flags;	/* informational flags */
-} intr_info_t;
-
-#define iv_tflags	iv_tinfo.thd_flags
-#define iv_isync	iv_tinfo.thd_isync
-#define iv_lat		iv_tinfo.thd_latstats
-#define iv_thread	iv_tinfo.thd_ithread
-#define iv_pri		iv_tinfo.thd_pri
-
-#define THD_CREATED	0x00000001	/*
-					 * We've created a thread for this
-					 * interrupt.
-					 */
-
-/*
- * Bits for ii_flags:
- */
-#define II_UNRESERVE	0
-#define II_RESERVE	1		/* Interrupt reserved. 			*/
-#define II_INUSE	2		/* Interrupt connected 			*/
-#define II_ERRORINT	4		/* INterrupt is an error condition 	*/
-#define II_THREADED	8		/* Interrupt handler is threaded.	*/
-
-/*
- * Interrupt level wildcard
- */
-#define INTRCONNECT_ANYBIT	-1
-
-/*
- * This structure holds information needed both to call and to maintain
- * interrupts.  The two are in separate arrays for the locality benefits.
- * Since there's only one set of vectors per hub chip (but more than one
- * CPU, the lock to change the vector tables must be here rather than in
- * the PDA.
- */
-
-typedef struct intr_vecblk_s {
-	intr_vector_t	vectors[N_INTPEND_BITS];  /* information needed to
-						     call an intr routine. */
-	intr_info_t	info[N_INTPEND_BITS];	  /* information needed only
-						     to maintain interrupts. */
-	spinlock_t	vector_lock;		  /* Lock for this and the
-						     masks in the PDA. */
-	splfunc_t	vector_spl;		  /* vector_lock req'd spl */
-	int		vector_state;		  /* Initialized to zero.
-						     Set to INTR_INITED
-						     by hubintr_init.
-						   */
-	int		vector_count;		  /* Number of vectors
-						   * reserved.
-						   */
-	int		cpu_count[CPUS_PER_SUBNODE]; /* How many interrupts are
-						   * connected to each CPU
-						   */
-	int		ithreads_enabled;	  /* Are interrupt threads
-						   * initialized on this node.
-						   * and block?
-						   */
-} intr_vecblk_t;
-
-/* Possible values for vector_state: */
-#define VECTOR_UNINITED	0
-#define VECTOR_INITED	1
-#define VECTOR_SET	2
-
-#define hub_intrvect0	private.p_intmasks.dispatch0->vectors
-#define hub_intrvect1	private.p_intmasks.dispatch1->vectors
-#define hub_intrinfo0	private.p_intmasks.dispatch0->info
-#define hub_intrinfo1	private.p_intmasks.dispatch1->info
-
-/*
- * Macros to manipulate the interrupt register on the calling hub chip.
- */
-
-#define LOCAL_HUB_SEND_INTR(_level)	LOCAL_HUB_S(PI_INT_PEND_MOD, \
-						    (0x100|(_level)))
-#define REMOTE_HUB_PI_SEND_INTR(_hub, _sn, _level) \
-		REMOTE_HUB_PI_S((_hub), _sn, PI_INT_PEND_MOD, (0x100|(_level)))
-
-#define REMOTE_CPU_SEND_INTR(_cpuid, _level) 					\
-		REMOTE_HUB_PI_S(cputonasid(_cpuid),				\
-			SUBNODE(cputoslice(_cpuid)),				\
-			PI_INT_PEND_MOD, (0x100|(_level)))
 
-/*
- * When clearing the interrupt, make sure this clear does make it 
- * to the hub. Otherwise we could end up losing interrupts.
- * We do an uncached load of the int_pend0 register to ensure this.
- */
-
-#define LOCAL_HUB_CLR_INTR(_level)	  \
-                LOCAL_HUB_S(PI_INT_PEND_MOD, (_level)),	\
-                LOCAL_HUB_L(PI_INT_PEND0)
-#define REMOTE_HUB_PI_CLR_INTR(_hub, _sn, _level) \
-		REMOTE_HUB_PI_S((_hub), (_sn), PI_INT_PEND_MOD, (_level)),	\
-                REMOTE_HUB_PI_L((_hub), (_sn), PI_INT_PEND0)
-
-/* Special support for use by gfx driver only.  Supports special gfx hub interrupt. */
-extern void install_gfxintr(cpuid_t cpu, ilvl_t swlevel, intr_func_t intr_func, void *intr_arg);
-
-void setrtvector(intr_func_t func);
-
-/*
- * Interrupt blocking
- */
-extern void intr_block_bit(cpuid_t cpu, int bit);
-extern void intr_unblock_bit(cpuid_t cpu, int bit);
-
-#endif /* LANGUAGE_C */
-
-/*
- * Hard-coded interrupt levels:
- */
-
-/*
- *	L0 = SW1
- *	L1 = SW2
- *	L2 = INT_PEND0
- *	L3 = INT_PEND1
- *	L4 = RTC
- *	L5 = Profiling Timer
- *	L6 = Hub Errors
- *	L7 = Count/Compare (T5 counters)
- */
-
-
-/* INT_PEND0 hard-coded bits. */
-#ifdef DEBUG_INTR_TSTAMP
-/* hard coded interrupt level for interrupt latency test interrupt */
-#define	CPU_INTRLAT_B	62
-#define	CPU_INTRLAT_A	61
+#if defined(CONFIG_IA64_SGI_SN1)
+#include <asm/sn/sn1/intr.h>
+#elif defined(CONFIG_IA64_SGI_SN2)
+#include <asm/sn/sn2/intr.h>
 #endif
 
-/* Hardcoded bits required by software. */
-#define MSC_MESG_INTR	9
-#define CPU_ACTION_B	8
-#define CPU_ACTION_A	7
+extern void sn_send_IPI_phys(long, int, int);
 
-/* These are determined by hardware: */
-#define CC_PEND_B	6
-#define CC_PEND_A	5
-#define UART_INTR	4
-#define PG_MIG_INTR	3
-#define GFX_INTR_B	2
-#define GFX_INTR_A	1
-#define RESERVED_INTR	0
-
-/* INT_PEND1 hard-coded bits: */
-#define MSC_PANIC_INTR	63
-#define NI_ERROR_INTR	62
-#define MD_COR_ERR_INTR	61
-#define COR_ERR_INTR_B	60
-#define COR_ERR_INTR_A	59
-#define CLK_ERR_INTR	58
-
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
-# define NACK_INT_B	57
-# define NACK_INT_A	56
-# define LB_ERROR	55
-# define XB_ERROR	54
-#else
-	<< BOMB! >>  Must define IP27 or IP35 or IP37
-#endif
-
-#define BRIDGE_ERROR_INTR 53	/* Setup by PROM to catch Bridge Errors */
-
-#define IP27_INTR_0	52	/* Reserved for PROM use */
-#define IP27_INTR_1	51	/*   (do not use in Kernel) */
-#define IP27_INTR_2	50
-#define IP27_INTR_3	49
-#define IP27_INTR_4	48
-#define IP27_INTR_5	47
-#define IP27_INTR_6	46
-#define IP27_INTR_7	45
-
-#define	TLB_INTR_B	44	/* used for tlb flush random */
-#define	TLB_INTR_A	43
-
-#define LLP_PFAIL_INTR_B 42	/* see ml/SN/SN0/sysctlr.c */
-#define LLP_PFAIL_INTR_A 41
-
-#define NI_BRDCAST_ERR_B 40
-#define NI_BRDCAST_ERR_A 39
-
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
-# define IO_ERROR_INTR	38	/* set up by prom */
-# define DEBUG_INTR_B	37	/* used by symmon to stop all cpus */
-# define DEBUG_INTR_A	36
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-// These aren't strictly accurate or complete.  See the
-// Synergy Spec. for details.
-#define SGI_UART_IRQ	(65)
-#define SGI_HUB_ERROR_IRQ	(182)
-#endif
+#define CPU_VECTOR_TO_IRQ(cpuid,vector) ((cpuid) << 8 | (vector))
 
-#endif /* _ASM_SN_INTR_H */
+#endif /* _ASM_IA64_SN_INTR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/intr_public.h linux/include/asm-ia64/sn/intr_public.h
--- linux.orig/include/asm-ia64/sn/intr_public.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/intr_public.h	2002-07-20 01:08:40.000000000 +0000
@@ -4,56 +4,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_INTR_PUBLIC_H__
-#define _ASM_SN_INTR_PUBLIC_H__
+#ifndef _ASM_IA64_SN_INTR_PUBLIC_H
+#define _ASM_IA64_SN_INTR_PUBLIC_H
 
 #include <linux/config.h>
 
-/* REMEMBER: If you change these, the whole world needs to be recompiled.
- * It would also require changing the hubspl.s code and SN0/intr.c
- * Currently, the spl code has no support for multiple INTPEND1 masks.
- */
-
-#define	N_INTPEND0_MASKS	1
-#define	N_INTPEND1_MASKS	1
-
-#define INTPEND0_MAXMASK	(N_INTPEND0_MASKS - 1)
-#define INTPEND1_MAXMASK	(N_INTPEND1_MASKS - 1)
-
-#if _LANGUAGE_C
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/arch.h>
+#if defined(CONFIG_IA64_SGI_SN1)
+#include <asm/sn/sn1/intr_public.h>
+#elif defined(CONFIG_IA64_SGI_SN2)
 #endif
-#include <asm/sn/arch.h>
-
-struct intr_vecblk_s;	/* defined in asm/sn/intr.h */
-
-/*
- * The following are necessary to create the illusion of a CEL
- * on the IP27 hub.  We'll add more priority levels soon, but for
- * now, any interrupt in a particular band effectively does an spl.
- * These must be in the PDA since they're different for each processor.
- * Users of this structure must hold the vector_lock in the appropriate vector
- * block before modifying the mask arrays.  There's only one vector block
- * for each Hub so a lock in the PDA wouldn't be adequate.
- */
-typedef struct hub_intmasks_s {
-	/*
-	 * The masks are stored with the lowest-priority (most inclusive)
-	 * in the lowest-numbered masks (i.e., 0, 1, 2...).
-	 */
-	/* INT_PEND0: */
-	hubreg_t		intpend0_masks[N_INTPEND0_MASKS]; 
-	/* INT_PEND1: */
-	hubreg_t		intpend1_masks[N_INTPEND1_MASKS];
-	/* INT_PEND0: */
-	struct intr_vecblk_s	*dispatch0;	
-	/* INT_PEND1: */
-	struct intr_vecblk_s	*dispatch1;
-} hub_intmasks_t;
 
-#endif /* _LANGUAGE_C */
-#endif /* _ASM_SN_INTR_PUBLIC_H__ */
+#endif /* _ASM_IA64_SN_INTR_PUBLIC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/invent.h linux/include/asm-ia64/sn/invent.h
--- linux.orig/include/asm-ia64/sn/invent.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/invent.h	2002-07-20 01:08:26.000000000 +0000
@@ -4,11 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_INVENT_H
-#define _ASM_SN_INVENT_H
+#ifndef _ASM_IA64_SN_INVENT_H
+#define _ASM_IA64_SN_INVENT_H
+
+#include <linux/types.h>
+#include <linux/devfs_fs_kernel.h>
 
 /*
  * sys/sn/invent.h --  Kernel Hardware Inventory
@@ -743,4 +745,4 @@
 					int);
 extern int device_controller_num_get(	devfs_handle_t);
 #endif /* __KERNEL__ */
-#endif /* _ASM_SN_INVENT_H */
+#endif /* _ASM_IA64_SN_INVENT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/io.h linux/include/asm-ia64/sn/io.h
--- linux.orig/include/asm-ia64/sn/io.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/io.h	2002-07-20 01:08:25.000000000 +0000
@@ -1,21 +1,17 @@
-
-/* $Id: io.h,v 1.2 2000/02/02 16:35:57 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 2000 Ralf Baechle
- * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc.
  */
-#ifndef _ASM_SN_IO_H
-#define _ASM_SN_IO_H
+#ifndef _ASM_IA64_SN_IO_H
+#define _ASM_IA64_SN_IO_H
 
 #include <linux/config.h>
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/addrs.h>
-#endif
+#include <asm/sn/addrs.h>
 
 /* Because we only have PCI I/O ports.  */
 #define IIO_ITTE_BASE	0x400160	/* base of translation table entries */
@@ -51,17 +47,35 @@
 #define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin))
 
 /*
- * Macro which takes the widget number, and returns the 
+ * Macro which takes the widget number, and returns the
  * IO PRB address of that widget.
- * value _x is expected to be a widget number in the range 
+ * value _x is expected to be a widget number in the range
  * 0, 8 - 0xF
  */
 #define	IIO_IOPRB(_x)	(IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
 			(_x) : \
 			(_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#if defined(CONFIG_IA64_SGI_SN1)
+#include <asm/sn/sn1/bedrock.h>
 #include <asm/sn/sn1/hubio.h>
+#include <asm/sn/sn1/hubio_next.h>
+#include <asm/sn/sn1/hubmd.h>
+#include <asm/sn/sn1/hubmd_next.h>
+#include <asm/sn/sn1/hubpi.h>
+#include <asm/sn/sn1/hubpi_next.h>
+#include <asm/sn/sn1/hublb.h>
+#include <asm/sn/sn1/hublb_next.h>
+#include <asm/sn/sn1/hubni.h>
+#include <asm/sn/sn1/hubni_next.h>
+#include <asm/sn/sn1/hubxb.h>
+#include <asm/sn/sn1/hubxb_next.h>
+#include <asm/sn/sn1/hubstat.h>
+#include <asm/sn/sn1/hubdev.h>
+#include <asm/sn/sn1/synergy.h>
+#elif defined(CONFIG_IA64_SGI_SN2)
+#include <asm/sn/sn2/shub.h>
+#include <asm/sn/sn2/shubio.h>
 #endif
 
-#endif /* _ASM_SN_IO_H */
+#endif /* _ASM_IA64_SN_IO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/iobus.h linux/include/asm-ia64/sn/iobus.h
--- linux.orig/include/asm-ia64/sn/iobus.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/iobus.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,185 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_IOBUS_H
-#define _ASM_SN_IOBUS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct eframe_s;
-struct piomap;
-struct dmamap;
-
-
-/* for ilvl_t interrupt level, for use with intr_block_level.  Can't
- * typedef twice without causing warnings, and some users of this header
- * file do not already include driver.h, but expect ilvl_t to be defined,
- * while others include both, leading to the warning ...
- */
-
-#include <asm/types.h>
-#include <asm/sn/driver.h>
-
-
-typedef __psunsigned_t iobush_t;
-
-#if __KERNEL__
-/* adapter handle */
-typedef devfs_handle_t adap_t;
-#endif
-
-
-/* interrupt function */
-typedef void	       *intr_arg_t;
-typedef void		intr_func_f(intr_arg_t);
-typedef intr_func_f    *intr_func_t;
-
-#define	INTR_ARG(n)	((intr_arg_t)(__psunsigned_t)(n))
-
-/* system interrupt resource handle -- returned from intr_alloc */
-typedef struct intr_s *intr_t;
-#define INTR_HANDLE_NONE ((intr_t)0)
-
-/*
- * restore interrupt level value, returned from intr_block_level
- * for use with intr_unblock_level.
- */
-typedef void *rlvl_t;
-
-
-/* 
- * A basic, platform-independent description of I/O requirements for
- * a device. This structure is usually formed by lboot based on information 
- * in configuration files.  It contains information about PIO, DMA, and
- * interrupt requirements for a specific instance of a device.
- *
- * The pio description is currently unused.
- *
- * The dma description describes bandwidth characteristics and bandwidth
- * allocation requirements. (TBD)
- *
- * The Interrupt information describes the priority of interrupt, desired 
- * destination, policy (TBD), whether this is an error interrupt, etc.  
- * For now, interrupts are targeted to specific CPUs.
- */
-
-typedef struct device_desc_s {
-	/* pio description (currently none) */
-
-	/* dma description */
-	/* TBD: allocated badwidth requirements */
-
-	/* interrupt description */
-	devfs_handle_t	intr_target;	/* Hardware locator string */
-	int 		intr_policy;	/* TBD */
-	ilvl_t		intr_swlevel;	/* software level for blocking intr */
-	char		*intr_name;	/* name of interrupt, if any */
-
-	int		flags;
-} *device_desc_t;
-
-/* flag values */
-#define	D_INTR_ISERR	0x1		/* interrupt is for error handling */
-#define D_IS_ASSOC	0x2		/* descriptor is associated with a dev */
-#define D_INTR_NOTHREAD	0x4		/* Interrupt handler isn't threaded. */
-
-#define INTR_SWLEVEL_NOTHREAD_DEFAULT 	0	/* Default
-						 * Interrupt level in case of
-						 * non-threaded interrupt 
-						 * handlers
-						 */
-/* 
- * Drivers use these interfaces to manage device descriptors.
- *
- * To examine defaults:
- *	desc = device_desc_default_get(dev);
- *	device_desc_*_get(desc);
- *
- * To modify defaults:
- *	desc = device_desc_default_get(dev);
- *	device_desc_*_set(desc);
- *
- * To eliminate defaults:
- *	device_desc_default_set(dev, NULL);
- *
- * To override defaults:
- *	desc = device_desc_dup(dev);
- *	device_desc_*_set(desc,...);
- *	use device_desc in calls
- *	device_desc_free(desc);
- *
- * Software must not set or eliminate default device descriptors for a device while
- * concurrently get'ing, dup'ing or using them.  Default device descriptors can be 
- * changed only for a device that is quiescent.  In general, device drivers have no
- * need to permanently change defaults anyway -- they just override defaults, when
- * necessary.
- */
-extern device_desc_t	device_desc_dup(devfs_handle_t dev);
-extern void		device_desc_free(device_desc_t device_desc);
-extern device_desc_t	device_desc_default_get(devfs_handle_t dev);
-extern void		device_desc_default_set(devfs_handle_t dev, device_desc_t device_desc);
-
-extern devfs_handle_t	device_desc_intr_target_get(device_desc_t device_desc);
-extern int		device_desc_intr_policy_get(device_desc_t device_desc);
-extern ilvl_t		device_desc_intr_swlevel_get(device_desc_t device_desc);
-extern char *		device_desc_intr_name_get(device_desc_t device_desc);
-extern int		device_desc_flags_get(device_desc_t device_desc);
-
-extern void		device_desc_intr_target_set(device_desc_t device_desc, devfs_handle_t target);
-extern void		device_desc_intr_policy_set(device_desc_t device_desc, int policy);
-extern void		device_desc_intr_swlevel_set(device_desc_t device_desc, ilvl_t swlevel);
-extern void		device_desc_intr_name_set(device_desc_t device_desc, char *name);
-extern void		device_desc_flags_set(device_desc_t device_desc, int flags);
-
-
-/* IO state */
-#ifdef COMMENT
-#define IO_STATE_EMPTY			0x01	/* non-existent */
-#define IO_STATE_INITIALIZING		0x02	/* being initialized */
-#define IO_STATE_ATTACHING   		0x04    /* becoming active */
-#define IO_STATE_ACTIVE      		0x08    /* active */
-#define IO_STATE_DETACHING   		0x10    /* becoming inactive */
-#define IO_STATE_INACTIVE    		0x20    /* not in use */
-#define IO_STATE_ERROR			0x40    /* problems */
-#define IO_STATE_BAD_HARDWARE		0x80	/* broken hardware */
-#endif
-
-struct edt;
-
-
-/* return codes */
-#define RC_OK				0	
-#define RC_ERROR			1
-
-/* bus configuration management op code */
-#define IOBUS_CONFIG_ATTACH		0	/* vary on */
-#define IOBUS_CONFIG_DETACH		1	/* vary off */
-#define IOBUS_CONFIG_RECOVER		2	/* clear error then vary on */
-
-/* get low-level PIO handle */
-extern int pio_geth(struct piomap*, int bus, int bus_id, int subtype, 
-	iopaddr_t addr, int size);	
-
-/* get low-level DMA handle */
-extern int dma_geth(struct dmamap*, int bus_type, int bus_id, int dma_type, 
-	int npages, int page_size, int flags);	
-
-#ifdef __cplusplus
-}
-#endif
-
-/*
- * Macros for page number and page offsets, using ps as page size
- */
-#define x_pnum(addr, ps) ((__psunsigned_t)(addr) / (__psunsigned_t)(ps))
-#define x_poff(addr, ps) ((__psunsigned_t)(addr) & ((__psunsigned_t)(ps) - 1))
-
-#endif /* _ASM_SN_IOBUS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/ioc3.h linux/include/asm-ia64/sn/ioc3.h
--- linux.orig/include/asm-ia64/sn/ioc3.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/ioc3.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,10 +1,44 @@
+/*
+ * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
 /* $Id: ioc3.h,v 1.2 2000/11/16 19:49:17 pfg Exp $
  *
  * Copyright (C) 1999 Ralf Baechle
  * This file is part of the Linux driver for the SGI IOC3.
  */
-#ifndef IOC3_H
-#define IOC3_H
+#ifndef _ASM_IA64_SN_IOC3_H
+#define _ASM_IA64_SN_IOC3_H
+
+#include <asm/types.h>
 
 /* SUPERIO uart register map */
 typedef volatile struct ioc3_uartregs {
@@ -668,4 +702,4 @@
 #define IOC3_VENDOR_ID_NUM	0x10A9
 #define IOC3_DEVICE_ID_NUM	0x0003
 
-#endif /* IOC3_H */
+#endif /* _ASM_IA64_SN_IOC3_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/ioerror.h linux/include/asm-ia64/sn/ioerror.h
--- linux.orig/include/asm-ia64/sn/ioerror.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/ioerror.h	2002-07-20 01:08:30.000000000 +0000
@@ -4,13 +4,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_IOERROR_H
-#define _ASM_SN_IOERROR_H
+#ifndef _ASM_IA64_SN_IOERROR_H
+#define _ASM_IA64_SN_IOERROR_H
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm/sn/types.h>
 
 /*
  * Macros defining the various Errors to be handled as part of
@@ -162,7 +164,6 @@
 #define	IOERROR_FIELDVALID(e,f)	(((e)->ie_v.iev_b.ievb_ ## f) != 0)
 #define	IOERROR_GETVALUE(e,f)	(ASSERT(IOERROR_FIELDVALID(e,f)),((e)->ie_ ## f))
 
-#if	IP27 || IP35
 /* hub code likes to call the SysAD address "hubaddr" ... */
 #define	ie_hubaddr	ie_sysioaddr
 #define	ievb_hubaddr	ievb_sysioaddr
@@ -178,7 +179,6 @@
     MODE_DEVREENABLE		/* Reenable pass                */
 } ioerror_mode_t;
 
-#endif				/* C || C++ */
 
 typedef int             error_handler_f(void *, int, ioerror_mode_t, ioerror_t *);
 typedef void           *error_handler_arg_t;
@@ -193,4 +193,4 @@
 #define	IOERR_PRINTF(x)
 #endif				/* ERROR_DEBUG */
 
-#endif				/* _ASM_SN_IOERROR_H */
+#endif /* _ASM_IA64_SN_IOERROR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/ioerror_handling.h linux/include/asm-ia64/sn/ioerror_handling.h
--- linux.orig/include/asm-ia64/sn/ioerror_handling.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/ioerror_handling.h	2002-07-20 01:08:37.000000000 +0000
@@ -1,16 +1,17 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_IOERROR_HANDLING_H
-#define _ASM_SN_IOERROR_HANDLING_H
+#ifndef _ASM_IA64_SN_IOERROR_HANDLING_H
+#define _ASM_IA64_SN_IOERROR_HANDLING_H
 
 #include <linux/config.h>
+#include <linux/types.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/sgi.h>
 
 #if __KERNEL__
 
@@ -264,7 +265,7 @@
 	 * one.								 
 	 */								 
 	if (v_error_skip_env_get(v, error_env) != GRAPH_SUCCESS) {	 
-		error_env = kmem_zalloc(sizeof(label_t), KM_NOSLEEP);	 
+		error_env = snia_kmem_zalloc(sizeof(label_t), KM_NOSLEEP);	 
 		/* Unable to allocate memory for jum buffer. This should 
 		 * be a very rare occurrence.				 
 		 */							 
@@ -302,4 +303,4 @@
 #endif
 
 #endif /* __KERNEL__ */
-#endif /* _ASM_SN_IOERROR_HANDLING_H */
+#endif /* _ASM_IA64_SN_IOERROR_HANDLING_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/iograph.h linux/include/asm-ia64/sn/iograph.h
--- linux.orig/include/asm-ia64/sn/iograph.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/iograph.h	2002-07-20 01:08:24.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_IOGRAPH_H
-#define _ASM_SN_IOGRAPH_H
+#ifndef _ASM_IA64_SN_IOGRAPH_H
+#define _ASM_IA64_SN_IOGRAPH_H
 
 /*
  * During initialization, platform-dependent kernel code establishes some
@@ -68,6 +67,7 @@
 #define EDGE_LBL_HPC			"hpc"
 #define EDGE_LBL_GFX			"gfx"
 #define EDGE_LBL_HUB			"hub"		/* For SN0 */
+#define EDGE_LBL_SYNERGY		"synergy"	/* For SNIA only */
 #define EDGE_LBL_IBUS			"ibus"		/* For EVEREST */
 #define EDGE_LBL_INTERCONNECT		"link"
 #define EDGE_LBL_IO			"io"
@@ -216,4 +216,4 @@
 };
 
 
-#endif /* _ASM_SN_IOGRAPH_H */
+#endif /* _ASM_IA64_SN_IOGRAPH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/klclock.h linux/include/asm-ia64/sn/klclock.h
--- linux.orig/include/asm-ia64/sn/klclock.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/klclock.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,60 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001 by Ralf Baechle
+ */
+#ifndef _ASM_IA64_SN_KLCLOCK_H
+#define _ASM_IA64_SN_KLCLOCK_H
+
+#include <asm/sn/ioc3.h>
+
+#define RTC_BASE_ADDR		(unsigned char *)(nvram_base)
+
+/* Defines for the SGS-Thomson M48T35 clock */
+#define RTC_SGS_WRITE_ENABLE    0x80
+#define RTC_SGS_READ_PROTECT    0x40
+#define RTC_SGS_YEAR_ADDR       (RTC_BASE_ADDR + 0x7fffL)
+#define RTC_SGS_MONTH_ADDR      (RTC_BASE_ADDR + 0x7ffeL)
+#define RTC_SGS_DATE_ADDR       (RTC_BASE_ADDR + 0x7ffdL)
+#define RTC_SGS_DAY_ADDR        (RTC_BASE_ADDR + 0x7ffcL)
+#define RTC_SGS_HOUR_ADDR       (RTC_BASE_ADDR + 0x7ffbL)
+#define RTC_SGS_MIN_ADDR        (RTC_BASE_ADDR + 0x7ffaL)
+#define RTC_SGS_SEC_ADDR        (RTC_BASE_ADDR + 0x7ff9L)
+#define RTC_SGS_CONTROL_ADDR    (RTC_BASE_ADDR + 0x7ff8L)
+
+/* Defines for the Dallas DS1386 */
+#define RTC_DAL_UPDATE_ENABLE   0x80
+#define RTC_DAL_UPDATE_DISABLE  0x00
+#define RTC_DAL_YEAR_ADDR       (RTC_BASE_ADDR + 0xaL)
+#define RTC_DAL_MONTH_ADDR      (RTC_BASE_ADDR + 0x9L)
+#define RTC_DAL_DATE_ADDR       (RTC_BASE_ADDR + 0x8L)
+#define RTC_DAL_DAY_ADDR        (RTC_BASE_ADDR + 0x6L)
+#define RTC_DAL_HOUR_ADDR       (RTC_BASE_ADDR + 0x4L)
+#define RTC_DAL_MIN_ADDR        (RTC_BASE_ADDR + 0x2L)
+#define RTC_DAL_SEC_ADDR        (RTC_BASE_ADDR + 0x1L)
+#define RTC_DAL_CONTROL_ADDR    (RTC_BASE_ADDR + 0xbL)
+#define RTC_DAL_USER_ADDR       (RTC_BASE_ADDR + 0xeL)
+
+/* Defines for the Dallas DS1742 */
+#define RTC_DS1742_WRITE_ENABLE    0x80
+#define RTC_DS1742_READ_ENABLE     0x40
+#define RTC_DS1742_UPDATE_DISABLE  0x00
+#define RTC_DS1742_YEAR_ADDR       (RTC_BASE_ADDR + 0x7ffL)
+#define RTC_DS1742_MONTH_ADDR      (RTC_BASE_ADDR + 0x7feL)
+#define RTC_DS1742_DATE_ADDR       (RTC_BASE_ADDR + 0x7fdL)
+#define RTC_DS1742_DAY_ADDR        (RTC_BASE_ADDR + 0x7fcL)
+#define RTC_DS1742_HOUR_ADDR       (RTC_BASE_ADDR + 0x7fbL)
+#define RTC_DS1742_MIN_ADDR        (RTC_BASE_ADDR + 0x7faL)
+#define RTC_DS1742_SEC_ADDR        (RTC_BASE_ADDR + 0x7f9L)
+#define RTC_DS1742_CONTROL_ADDR    (RTC_BASE_ADDR + 0x7f8L)
+#define RTC_DS1742_USER_ADDR       (RTC_BASE_ADDR + 0x0L)
+
+#define BCD_TO_INT(x) (((x>>4) * 10) + (x & 0xf))
+#define INT_TO_BCD(x) (((x / 10)<<4) + (x % 10))
+
+#define YRREF	1970 
+
+#endif /* _ASM_IA64_SN_KLCLOCK_H  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/klconfig.h linux/include/asm-ia64/sn/klconfig.h
--- linux.orig/include/asm-ia64/sn/klconfig.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/klconfig.h	2002-07-20 01:08:31.000000000 +0000
@@ -6,11 +6,11 @@
  *
  * Derived from IRIX <sys/SN/klconfig.h>.
  *
- * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1992-1997,1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
-#ifndef	_ASM_SN_KLCONFIG_H
-#define	_ASM_SN_KLCONFIG_H
+#ifndef _ASM_IA64_SN_KLCONFIG_H
+#define _ASM_IA64_SN_KLCONFIG_H
 
 #include <linux/config.h>
 
@@ -38,20 +38,22 @@
 #include <asm/sn/types.h>
 #include <asm/sn/slotnum.h>
 #include <asm/sn/router.h>
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/sgi.h>
-#include <asm/sn/sn1/addrs.h>
+#include <asm/sn/addrs.h>
 #include <asm/sn/vector.h>
-#include <asm/sn/agent.h>
-// #include <sys/graph.h>
-// #include <asm/sn/arc/types.h>
 #include <asm/sn/arc/hinv.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/kldir.h>
 #include <asm/sn/sn_fru.h>
 
-#endif  /* CONFIG_SGI_IP35 ... */
+#ifdef CONFIG_IA64_SGI_SN1
+#include <asm/sn/sn1/hubmd_next.h>
+#endif
+
+#ifdef CONFIG_IA64_SGI_SN2
+#include <asm/sn/sn2/shub_md.h>
+#endif
 
 #define KLCFGINFO_MAGIC	0xbeedbabe
 
@@ -59,19 +61,11 @@
 
 #define	MAX_MODULE_ID		255
 #define SIZE_PAD		4096 /* 4k padding for structures */
-#if (defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)) && defined(BRINGUP) /* MAX_SLOTS_PER_NODE??? */
 /* 
  * 1 NODE brick, 3 Router bricks (1 local, 1 meta, 1 repeater),
  * 6 XIO Widgets, 1 Xbow, 1 gfx
  */
 #define MAX_SLOTS_PER_NODE	(1 + 3 + 6 + 1 + 1) 
-#else
-/* 
- * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets, 
- * 2 Midplanes assuming no pci card cages 
- */
-#define MAX_SLOTS_PER_NODE	(1 + 2 + 6 + 2) 
-#endif
 
 /* XXX if each node is guranteed to have some memory */
 
@@ -349,7 +343,7 @@
 #define KLCLASS(_x) ((_x) & KLCLASS_MASK)
 
 /*
- * IP27 board types
+ * board types
  */
 
 #define KLTYPE_MASK	0x0f
@@ -357,11 +351,7 @@
 #define KLTYPE_EMPTY	0x00
 
 #define KLTYPE_WEIRDCPU (KLCLASS_CPU | 0x0)
-#define KLTYPE_IP27	(KLCLASS_CPU | 0x1) /* 2 CPUs(R10K) per board */
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#define KLTYPE_IP35	KLTYPE_IP27
-#define KLTYPE_IP37	KLTYPE_IP35
-#endif
+#define KLTYPE_SNIA	(KLCLASS_CPU | 0x1)
 
 #define KLTYPE_WEIRDIO	(KLCLASS_IO  | 0x0)
 #define KLTYPE_BASEIO	(KLCLASS_IO  | 0x1) /* IOC3, SuperIO, Bridge, SCSI */
@@ -949,7 +939,6 @@
 extern int	config_find_nic_router(nasid_t, nic_t, lboard_t **, klrou_t**);
 extern int	config_find_nic_hub(nasid_t, nic_t, lboard_t **, klhub_t**);
 extern int	config_find_xbow(nasid_t, lboard_t **, klxbow_t**);
-extern klcpu_t *get_cpuinfo(cpuid_t cpu);
 extern int 	update_klcfg_cpuinfo(nasid_t, int);
 extern void 	board_to_path(lboard_t *brd, char *path);
 extern moduleid_t get_module_id(nasid_t nasid);
@@ -963,4 +952,4 @@
 extern nasid_t	get_actual_nasid(lboard_t *brd) ;
 extern net_vec_t klcfg_discover_route(lboard_t *, lboard_t *, int);
 
-#endif /* _ASM_SN_KLCONFIG_H */
+#endif /* _ASM_IA64_SN_KLCONFIG_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/kldir.h linux/include/asm-ia64/sn/kldir.h
--- linux.orig/include/asm-ia64/sn/kldir.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/kldir.h	2002-07-20 01:08:35.000000000 +0000
@@ -1,18 +1,16 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Derived from IRIX <sys/SN/kldir.h>, revision 1.21.
  *
- * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1992-1997,1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
-#ifndef _ASM_SN_KLDIR_H
-#define _ASM_SN_KLDIR_H
+#ifndef _ASM_IA64_SN_KLDIR_H
+#define _ASM_IA64_SN_KLDIR_H
 
-#include <linux/config.h>
 #include <asm/sn/sgi.h>
 
 /*
@@ -125,16 +123,16 @@
  * 0x0   (0K)              +-----------------------------------------+
  */
 
-#ifdef LANGUAGE_ASSEMBLY
+#ifdef __ASSEMBLY__
 #define KLDIR_OFF_MAGIC			0x00
 #define KLDIR_OFF_OFFSET		0x08
 #define KLDIR_OFF_POINTER		0x10
 #define KLDIR_OFF_SIZE			0x18
 #define KLDIR_OFF_COUNT			0x20
 #define KLDIR_OFF_STRIDE		0x28
-#endif /* LANGUAGE_ASSEMBLY */
+#endif /* __ASSEMBLY__ */
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef struct kldir_ent_s {
 	u64		magic;		/* Indicates validity of entry      */
 	off_t		offset;		/* Offset from start of node space  */
@@ -146,19 +144,220 @@
 	/* NOTE: These 16 bytes are used in the Partition KLDIR
 	   entry to store partition info. Refer to klpart.h for this. */
 } kldir_ent_t;
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 
 #define KLDIR_ENT_SIZE			0x40
 #define KLDIR_MAX_ENTRIES		(0x400 / 0x40)
 
+
+
 /*
- * The actual offsets of each memory area are machine-dependent
+ * The upper portion of the memory map applies during boot
+ * only and is overwritten by IRIX/SYMMON.  The minimum memory bank
+ * size on IP35 is 64M, which provides a limit on the amount of space
+ * the PROM can assume it has available.
+ *
+ * Most of the addresses below are defined as macros in this file, or
+ * in SN/addrs.h or SN/SN1/addrs.h.
+ *
+ *                                    MEMORY MAP PER NODE
+ *
+ * 0x4000000 (64M)         +-----------------------------------------+
+ *                         |                                         |
+ *                         |                                         |
+ *                         |      IO7 TEXT/DATA/BSS/stack            |
+ * 0x3000000 (48M)         +-----------------------------------------+
+ *                         |      Free                               |
+ * 0x2102000 (>33M)        +-----------------------------------------+
+ *                         |      IP35 Topology (PCFG) + misc data   |
+ * 0x2000000 (32M)         +-----------------------------------------+
+ *                         |      IO7 BUFFERS FOR FLASH ENET IOC3    |
+ * 0x1F80000 (31.5M)       +-----------------------------------------+
+ *                         |      Free                               |
+ * 0x1C00000 (28M)         +-----------------------------------------+
+ *                         |      IP35 PROM TEXT/DATA/BSS/stack      |
+ * 0x1A00000 (26M)         +-----------------------------------------+
+ *                         |      Routing temp. space                |
+ * 0x1800000 (24M)         +-----------------------------------------+
+ *                         |      Diagnostics temp. space            |
+ * 0x1500000 (21M)         +-----------------------------------------+
+ *                         |      Free                               |
+ * 0x1400000 (20M)         +-----------------------------------------+
+ *                         |      IO7 PROM temporary copy            |
+ * 0x1300000 (19M)         +-----------------------------------------+
+ *                         |                                         |
+ *                         |      Free                               |
+ *                         |      (UNIX DATA starts above 0x1000000) |
+ *                         |                                         |
+ *                         +-----------------------------------------+
+ *                         |      UNIX DEBUG Version                 |
+ * 0x0310000 (3.1M)        +-----------------------------------------+
+ *                         |      SYMMON, loaded just below UNIX     |
+ *                         |      (For UNIX Debug only)              |
+ *                         |                                         |
+ *                         |                                         |
+ * 0x006C000 (432K)        +-----------------------------------------+
+ *                         |      SYMMON STACK [NUM_CPU_PER_NODE]    |
+ *                         |      (For UNIX Debug only)              |
+ * 0x004C000 (304K)        +-----------------------------------------+
+ *                         |                                         |
+ *                         |                                         |
+ *                         |      UNIX NON-DEBUG Version             |
+ * 0x0040000 (256K)        +-----------------------------------------+
+ *
+ *
+ * The lower portion of the memory map contains information that is
+ * permanent and is used by the IP35PROM, IO7PROM and IRIX.
+ *
+ * 0x40000 (256K)          +-----------------------------------------+
+ *                         |                                         |
+ *                         |      KLCONFIG (64K)                     |
+ *                         |                                         |
+ * 0x30000 (192K)          +-----------------------------------------+
+ *                         |                                         |
+ *                         |      PI Error Spools (64K)              |
+ *                         |                                         |
+ * 0x20000 (128K)          +-----------------------------------------+
+ *                         |                                         |
+ *                         |      Unused                             |
+ *                         |                                         |
+ * 0x19000 (100K)          +-----------------------------------------+
+ *                         |      Early cache Exception stack (CPU 3)|
+ * 0x18800 (98K)           +-----------------------------------------+
+ *			   |      cache error eframe (CPU 3)	     |
+ * 0x18400 (97K)           +-----------------------------------------+
+ *                         |      Exception Handlers (CPU 3)         |
+ * 0x18000 (96K)           +-----------------------------------------+
+ *                         |                                         |
+ *                         |      Unused                             |
+ *                         |                                         |
+ * 0x13c00 (79K)           +-----------------------------------------+
+ *                         |      GPDA (8k)                          |
+ * 0x11c00 (71K)           +-----------------------------------------+
+ *                         |      Early cache Exception stack (CPU 2)|
+ * 0x10800 (66k)	   +-----------------------------------------+
+ *			   |      cache error eframe (CPU 2)	     |
+ * 0x10400 (65K)           +-----------------------------------------+
+ *                         |      Exception Handlers (CPU 2)         |
+ * 0x10000 (64K)           +-----------------------------------------+
+ *                         |                                         |
+ *                         |      Unused                             |
+ *                         |                                         |
+ * 0x0b400 (45K)           +-----------------------------------------+
+ *                         |      GDA (1k)                           |
+ * 0x0b000 (44K)           +-----------------------------------------+
+ *                         |      NMI Eframe areas (4)       	     |
+ * 0x0a000 (40K)           +-----------------------------------------+
+ *                         |      NMI Register save areas (4)        |
+ * 0x09000 (36K)           +-----------------------------------------+
+ *                         |      Early cache Exception stack (CPU 1)|
+ * 0x08800 (34K)           +-----------------------------------------+
+ *			   |      cache error eframe (CPU 1)	     |
+ * 0x08400 (33K)           +-----------------------------------------+
+ *                         |      Exception Handlers (CPU 1)         |
+ * 0x08000 (32K)           +-----------------------------------------+
+ *                         |                                         |
+ *                         |                                         |
+ *                         |      Unused                             |
+ *                         |                                         |
+ *                         |                                         |
+ * 0x04000 (16K)           +-----------------------------------------+
+ *                         |      NMI Handler (Protected Page)       |
+ * 0x03000 (12K)           +-----------------------------------------+
+ *                         |      ARCS PVECTORS (master node only)   |
+ * 0x02c00 (11K)           +-----------------------------------------+
+ *                         |      ARCS TVECTORS (master node only)   |
+ * 0x02800 (10K)           +-----------------------------------------+
+ *                         |      LAUNCH [NUM_CPU]                   |
+ * 0x02400 (9K)            +-----------------------------------------+
+ *                         |      Low memory directory (KLDIR)       |
+ * 0x02000 (8K)            +-----------------------------------------+
+ *                         |      ARCS SPB (1K)                      |
+ * 0x01000 (4K)            +-----------------------------------------+
+ *                         |      Early cache Exception stack (CPU 0)|
+ * 0x00800 (2k)	           +-----------------------------------------+
+ *			   |      cache error eframe (CPU 0)	     |
+ * 0x00400 (1K)            +-----------------------------------------+
+ *                         |      Exception Handlers (CPU 0)         |
+ * 0x00000 (0K)            +-----------------------------------------+
+ */
+
+/*
+ * NOTE:  To change the kernel load address, you must update:
+ *  - the appropriate elspec files in irix/kern/master.d
+ *  - NODEBUGUNIX_ADDR in SN/SN1/addrs.h
+ *  - IP27_FREEMEM_OFFSET below
+ *  - KERNEL_START_OFFSET below (if supporting cells)
  */
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/kldir.h>
-#else
-#error "kldir.h is currently defined for IP27 and IP35 platforms only"
-#endif
 
-#endif /* _ASM_SN_KLDIR_H */
+
+/*
+ * This is defined here because IP27_SYMMON_STK_SIZE must be at least what
+ * we define here.  Since it's set up in the prom.  We can't redefine it later
+ * and expect more space to be allocated.  The way to find out the true size
+ * of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE
+ * for a particular node.
+ */
+#define SYMMON_STACK_SIZE		0x8000
+
+#if defined (PROM) || defined (SABLE)
+
+/*
+ * These defines are prom version dependent.  No code other than the IP35
+ * prom should attempt to use these values.
+ */
+#define IP27_LAUNCH_OFFSET		0x2400
+#define IP27_LAUNCH_SIZE		0x400
+#define IP27_LAUNCH_COUNT		4
+#define IP27_LAUNCH_STRIDE		0x100 /* could be as small as 0x80 */
+
+#define IP27_KLCONFIG_OFFSET		0x30000
+#define IP27_KLCONFIG_SIZE		0x10000
+#define IP27_KLCONFIG_COUNT		1
+#define IP27_KLCONFIG_STRIDE		0
+
+#define IP27_NMI_OFFSET			0x3000
+#define IP27_NMI_SIZE			0x100
+#define IP27_NMI_COUNT			4
+#define IP27_NMI_STRIDE			0x40
+
+#define IP27_PI_ERROR_OFFSET		0x20000
+#define IP27_PI_ERROR_SIZE		0x10000
+#define IP27_PI_ERROR_COUNT		1
+#define IP27_PI_ERROR_STRIDE		0
+
+#define IP27_SYMMON_STK_OFFSET		0x4c000
+#define IP27_SYMMON_STK_SIZE		0x20000
+#define IP27_SYMMON_STK_COUNT		4
+/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */
+#define IP27_SYMMON_STK_STRIDE		0x8000
+
+#define IP27_FREEMEM_OFFSET		0x40000
+#define IP27_FREEMEM_SIZE		(-1)
+#define IP27_FREEMEM_COUNT		1
+#define IP27_FREEMEM_STRIDE		0
+
+#endif /* PROM || SABLE*/
+/*
+ * There will be only one of these in a partition so the IO7 must set it up.
+ */
+#define IO6_GDA_OFFSET			0xb000
+#define IO6_GDA_SIZE			0x400
+#define IO6_GDA_COUNT			1
+#define IO6_GDA_STRIDE			0
+
+/*
+ * save area of kernel nmi regs in the prom format
+ */
+#define IP27_NMI_KREGS_OFFSET		0x9000
+#define IP27_NMI_KREGS_CPU_SIZE		0x400
+/*
+ * save area of kernel nmi regs in eframe format 
+ */
+#define IP27_NMI_EFRAME_OFFSET		0xa000
+#define IP27_NMI_EFRAME_SIZE		0x400
+
+#define GPDA_OFFSET			0x11c00
+
+#endif /* _ASM_IA64_SN_KLDIR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/ksys/elsc.h linux/include/asm-ia64/sn/ksys/elsc.h
--- linux.orig/include/asm-ia64/sn/ksys/elsc.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/ksys/elsc.h	2002-07-20 01:08:30.000000000 +0000
@@ -4,36 +4,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_KSYS_ELSC_H
 #define _ASM_SN_KSYS_ELSC_H
 
-#include <linux/config.h>
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/ksys/l1.h>
-#endif
-
-// #include <asm/sn/ksys/i2c.h>
 
-#define ELSC_I2C_ADDR		0x08
-#define ELSC_I2C_HUB0		0x09
-#define ELSC_I2C_HUB1		0x0a
-#define ELSC_I2C_HUB2		0x0b
-#define ELSC_I2C_HUB3		0x0c
-
-#define ELSC_PACKET_MAX		96
 #define ELSC_ACP_MAX		86		/* 84+cr+lf */
 #define ELSC_LINE_MAX		(ELSC_ACP_MAX - 2)
 
-/*
- * ELSC character queue type for I/O
- */
-
-#define ELSC_QSIZE	128		/* Power of 2 is more efficient */
-
 typedef sc_cq_t elsc_cq_t;
 
 /*
@@ -49,14 +29,11 @@
 int	elsc_msg_callback(elsc_t *e,
 			  void (*callback)(void *callback_data, char *msg),
 			  void *callback_data);
-#ifdef LATER
 char   *elsc_errmsg(int code);
 
 int	elsc_nvram_write(elsc_t *e, int addr, char *buf, int len);
 int	elsc_nvram_read(elsc_t *e, int addr, char *buf, int len);
 int	elsc_nvram_magic(elsc_t *e);
-#endif
-
 int	elsc_command(elsc_t *e, int only_if_message);
 int	elsc_parse(elsc_t *e, char *p1, char *p2, char *p3);
 int	elsc_ust_write(elsc_t *e, uchar_t c);
@@ -69,10 +46,8 @@
  */
 
 int	elsc_version(elsc_t *e, char *result);
-#ifdef LATER
 int	elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2);
 int	elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2);
-#endif
 int	elsc_module_set(elsc_t *e, int module);
 int	elsc_module_get(elsc_t *e);
 int	elsc_partition_set(elsc_t *e, int partition);
@@ -85,13 +60,10 @@
 int	elsc_cell_get(elsc_t *e);
 int	elsc_bist_set(elsc_t *e, char bist_status);
 char	elsc_bist_get(elsc_t *e);
-int	elsc_lock(elsc_t *e,
-		  int retry_interval_usec,
-		  int timeout_usec, u_char lock_val);
+int	elsc_lock(elsc_t *e, int retry_interval_usec, int timeout_usec, u_char lock_val);
 int	elsc_unlock(elsc_t *e);
 int	elsc_display_char(elsc_t *e, int led, int chr);
 int	elsc_display_digit(elsc_t *e, int led, int num, int l_case);
-#ifdef LATER
 int	elsc_display_mesg(elsc_t *e, char *chr);	/* 8-char input */
 int	elsc_password_set(elsc_t *e, char *password);	/* 4-char input */
 int	elsc_password_get(elsc_t *e, char *password);	/* 4-char output */
@@ -102,7 +74,6 @@
 int	elsc_system_reset(elsc_t *e);
 int	elsc_dip_switches(elsc_t *e);
 int	elsc_nic_get(elsc_t *e, uint64_t *nic, int verbose);
-#endif
 
 int	_elsc_hbt(elsc_t *e, int ival, int rdly);
 
@@ -110,29 +81,8 @@
 #define	elsc_hbt_disable(e)		_elsc_hbt(e, 0, 0)
 #define	elsc_hbt_send(e)		_elsc_hbt(e, 0, 1)
 
-/*
- * Routines for using the ELSC as a UART.  There's a version of each
- * routine that takes a pointer to an elsc_t, and another version that
- * gets the pointer by calling a user-supplied global routine "get_elsc".
- * The latter version is useful when the elsc is employed for stdio.
- */
-
-#define ELSCUART_FLASH		0x3c			/* LED pattern */
-
 elsc_t	       *get_elsc(void);
 
-int	elscuart_probe(void);
-void	elscuart_init(void *);
-int	elscuart_poll(void);
-int	elscuart_readc(void);
-int	elscuart_getc(void);
-int	elscuart_putc(int);
-int	elscuart_puts(char *);
-char   *elscuart_gets(char *, int);
-int	elscuart_flush(void);
-
-
-
 /*
  * Error codes
  *
@@ -142,23 +92,23 @@
 
 #define ELSC_ERROR_NONE			0
 
-#define ELSC_ERROR_CMD_SEND	       -100	/* Error sending command    */
-#define ELSC_ERROR_CMD_CHECKSUM	       -101	/* Command checksum bad     */
-#define ELSC_ERROR_CMD_UNKNOWN	       -102	/* Unknown command          */
-#define ELSC_ERROR_CMD_ARGS	       -103	/* Invalid argument(s)      */
-#define ELSC_ERROR_CMD_PERM	       -104	/* Permission denied	    */
-#define ELSC_ERROR_CMD_STATE	       -105	/* not allowed in this state*/
-
-#define ELSC_ERROR_RESP_TIMEOUT	       -110	/* ELSC response timeout    */
-#define ELSC_ERROR_RESP_CHECKSUM       -111	/* Response checksum bad    */
-#define ELSC_ERROR_RESP_FORMAT	       -112	/* Response format error    */
-#define ELSC_ERROR_RESP_DIR	       -113	/* Response direction error */
-
-#define ELSC_ERROR_MSG_LOST	       -120	/* Queue full; msg. lost    */
-#define ELSC_ERROR_LOCK_TIMEOUT	       -121	/* ELSC response timeout    */
-#define ELSC_ERROR_DATA_SEND	       -122	/* Error sending data       */
-#define ELSC_ERROR_NIC		       -123	/* NIC processing error     */
-#define ELSC_ERROR_NVMAGIC	       -124	/* Bad magic no. in NVRAM   */
-#define ELSC_ERROR_MODULE	       -125	/* Moduleid processing err  */
+#define ELSC_ERROR_CMD_SEND	       (-100)	/* Error sending command    */
+#define ELSC_ERROR_CMD_CHECKSUM	       (-101)	/* Command checksum bad     */
+#define ELSC_ERROR_CMD_UNKNOWN	       (-102)	/* Unknown command          */
+#define ELSC_ERROR_CMD_ARGS	       (-103)	/* Invalid argument(s)      */
+#define ELSC_ERROR_CMD_PERM	       (-104)	/* Permission denied	    */
+#define ELSC_ERROR_CMD_STATE	       (-105)	/* not allowed in this state*/
+
+#define ELSC_ERROR_RESP_TIMEOUT	       (-110)	/* ELSC response timeout    */
+#define ELSC_ERROR_RESP_CHECKSUM       (-111)	/* Response checksum bad    */
+#define ELSC_ERROR_RESP_FORMAT	       (-112)	/* Response format error    */
+#define ELSC_ERROR_RESP_DIR	       (-113)	/* Response direction error */
+
+#define ELSC_ERROR_MSG_LOST	       (-120)	/* Queue full; msg. lost    */
+#define ELSC_ERROR_LOCK_TIMEOUT	       (-121)	/* ELSC response timeout    */
+#define ELSC_ERROR_DATA_SEND	       (-122)	/* Error sending data       */
+#define ELSC_ERROR_NIC		       (-123)	/* NIC processing error     */
+#define ELSC_ERROR_NVMAGIC	       (-124)	/* Bad magic no. in NVRAM   */
+#define ELSC_ERROR_MODULE	       (-125)	/* Moduleid processing err  */
 
 #endif /* _ASM_SN_KSYS_ELSC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/ksys/i2c.h linux/include/asm-ia64/sn/ksys/i2c.h
--- linux.orig/include/asm-ia64/sn/ksys/i2c.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/ksys/i2c.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,77 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_KSYS_I2C_H
-#define _ASM_SN_KSYS_I2C_H
-
-#if _STANDALONE
-# include "rtc.h"
-#else
-# define rtc_time()	(GET_LOCAL_RTC * NSEC_PER_CYCLE / 1000)
-# define rtc_sleep	us_delay
-# define rtc_time_t	uint64_t
-#endif
-
-typedef u_char			i2c_addr_t;	/* 7-bit address            */
-
-int		i2c_init(nasid_t);
-
-int		i2c_probe(nasid_t nasid, rtc_time_t timeout);
-
-int		i2c_arb(nasid_t, rtc_time_t timeout, rtc_time_t *token_start);
-
-int		i2c_master_xmit(nasid_t,
-				i2c_addr_t addr,
-				u_char *buf,
-				int len_max,
-				int *len_ptr,
-				rtc_time_t timeout,
-				int only_if_message);
-
-int		i2c_master_recv(nasid_t,
-				i2c_addr_t addr,
-				u_char *buf,
-				int len_max,
-				int *len_ptr,
-				int emblen,
-				rtc_time_t timeout,
-				int only_if_message);
-
-int		i2c_master_xmit_recv(nasid_t,
-				     i2c_addr_t addr,
-				     u_char *xbuf,
-				     int xlen_max,
-				     int *xlen_ptr,
-				     u_char *rbuf,
-				     int rlen_max,
-				     int *rlen_ptr,
-				     int emblen,
-				     rtc_time_t timeout,
-				     int only_if_message);
-
-char	       *i2c_errmsg(int code);
-
-/*
- * Error codes
- */
-
-#define I2C_ERROR_NONE		 0
-#define I2C_ERROR_INIT		-1	/* Initialization error             */
-#define I2C_ERROR_STATE		-2	/* Unexpected chip state	    */
-#define I2C_ERROR_NAK		-3	/* Addressed slave not responding   */
-#define I2C_ERROR_TO_ARB	-4	/* Timeout waiting for sysctlr arb  */
-#define I2C_ERROR_TO_BUSY	-5	/* Timeout waiting for busy bus     */
-#define I2C_ERROR_TO_SENDA	-6	/* Timeout sending address byte     */
-#define I2C_ERROR_TO_SENDD	-7	/* Timeout sending data byte        */
-#define I2C_ERROR_TO_RECVA	-8	/* Timeout receiving address byte   */
-#define I2C_ERROR_TO_RECVD	-9	/* Timeout receiving data byte      */
-#define I2C_ERROR_NO_MESSAGE	-10	/* No message was waiting	    */
-#define I2C_ERROR_NO_ELSC	-11	/* ELSC is disabled for access 	    */ 	
-
-#endif /* _ASM_SN_KSYS_I2C_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/ksys/l1.h linux/include/asm-ia64/sn/ksys/l1.h
--- linux.orig/include/asm-ia64/sn/ksys/l1.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/ksys/l1.h	2002-07-20 01:08:31.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #ifndef _ASM_SN_KSYS_L1_H
@@ -13,7 +12,8 @@
 
 #include <asm/sn/vector.h>
 #include <asm/sn/addrs.h>
-#include <asm/sn/sn1/bedrock.h>
+#include <asm/atomic.h>
+#include <asm/sn/sv.h>
 
 #define BRL1_QSIZE	128	/* power of 2 is more efficient */
 #define BRL1_BUFSZ	264	/* needs to be large enough
@@ -39,7 +39,7 @@
  * This value can't be confused with a network vector because the least-
  * significant nibble of a network vector cannot be greater than 8.
  */
-#define BRL1_LOCALUART	((net_vec_t)0xf)
+#define BRL1_LOCALHUB_UART	((net_vec_t)0xf)
 
 /* L1<->Bedrock reserved subchannels */
 
@@ -71,7 +71,14 @@
 
 
 struct l1sc_s;     
-typedef void (*brl1_notif_t)(struct l1sc_s *, int);
+/* Saved off interrupt frame */
+typedef struct brl1_intr_frame {
+	int bf_irq;		/* irq received */
+	void *bf_dev_id;	/* device information */
+	struct pt_regs *bf_regs; /* register frame */
+} brl1_intr_frame_t;
+
+typedef void (*brl1_notif_t)(int, void *, struct pt_regs *, struct l1sc_s *, int);
 typedef int  (*brl1_uartf_t)(struct l1sc_s *);
 
 /* structure for controlling a subchannel */
@@ -90,6 +97,7 @@
 				 * continue */
     brl1_notif_t rx_notify;	/* notify higher layer that a packet has been
 				 * received */
+    brl1_intr_frame_t irq_frame; /* saved off irq information */
 } brl1_sch_t;
 
 /* br<->l1 protocol states */
@@ -101,7 +109,7 @@
 #define BRL1_RESET	7
 
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 /*
  * l1sc_t structure-- tracks protocol state, open subchannels, etc.
@@ -118,6 +126,8 @@
     brl1_uartf_t putc_f;	/* pointer to UART putc function */
     brl1_uartf_t getc_f;	/* pointer to UART getc function */
 
+    spinlock_t   send_lock;     /* arbitrates send synchronization */
+    spinlock_t   recv_lock;     /* arbitrates uart receive access */
     spinlock_t	 subch_lock;	/* arbitrates subchannel allocation */
     cpuid_t	 intr_cpu;	/* cpu that receives L1 interrupts */
 
@@ -327,15 +337,6 @@
 void	sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart );
 void	sc_intr_enable( l1sc_t *sc );
 
-int	_elscuart_putc( l1sc_t *sc, int c );
-int	_elscuart_getc( l1sc_t *sc );
-int	_elscuart_poll( l1sc_t *sc );
-int	_elscuart_readc( l1sc_t *sc );
-int	_elscuart_flush( l1sc_t *sc );
-int	_elscuart_probe( l1sc_t *sc );
-void	_elscuart_init( l1sc_t *sc );
-void	elscuart_syscon_listen( l1sc_t *sc );
-
 int	elsc_rack_bay_get(l1sc_t *e, uint *rack, uint *bay);
 int	elsc_rack_bay_type_get(l1sc_t *e, uint *rack, 
 			       uint *bay, uint *brick_type);
@@ -357,5 +358,5 @@
 int	iobrick_sc_version( l1sc_t *sc, char *result );
 
 
-#endif /* !_LANGUAGE_ASSEMBLY */
+#endif /* !__ASSEMBLY__ */
 #endif /* _ASM_SN_KSYS_L1_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/labelcl.h linux/include/asm-ia64/sn/labelcl.h
--- linux.orig/include/asm-ia64/sn/labelcl.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/labelcl.h	2002-07-20 01:08:38.000000000 +0000
@@ -4,15 +4,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_LABELCL_H
-#define _ASM_SN_LABELCL_H
+#ifndef _ASM_IA64_SN_LABELCL_H
+#define _ASM_IA64_SN_LABELCL_H
+
+#include <asm/sn/hcl.h>
 
 #define LABELCL_MAGIC 0x4857434c	/* 'HWLC' */
 #define LABEL_LENGTH_MAX 256		/* Includes NULL char */
-#define INFO_DESC_PRIVATE -1      	/* default */
+#define INFO_DESC_PRIVATE (-1)      	/* default */
 #define INFO_DESC_EXPORT  0       	/* export info itself */
 
 /*
@@ -90,4 +91,4 @@
 extern int labelcl_info_get_IDX(struct devfs_entry *, int, arbitrary_info_t *);
 extern struct devfs_entry *device_info_connectpt_get(struct devfs_entry *);
 
-#endif /* _ASM_SN_LABELCL_H */
+#endif /* _ASM_IA64_SN_LABELCL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/leds.h linux/include/asm-ia64/sn/leds.h
--- linux.orig/include/asm-ia64/sn/leds.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/leds.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,46 @@
+#ifndef _ASM_IA64_SN_LEDS_H
+#define _ASM_IA64_SN_LEDS_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <asm/smp.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pda.h>
+
+#ifdef CONFIG_IA64_SGI_SN1
+#define LED0		0xc0000b00100000c0LL	/* ZZZ fixme */
+#define LED_CPU_SHIFT	3
+#else
+#include <asm/sn/sn2/shub.h>
+#define LED0		(LOCAL_MMR_ADDR(SH_REAL_JUNK_BUS_LED0))
+#define LED_CPU_SHIFT	16
+#endif
+
+#define LED_CPU_HEARTBEAT	0x01
+#define LED_CPU_ACTIVITY	0x02
+#define LED_MASK_AUTOTEST	0xfe
+
+/*
+ * Basic macros for flashing the LEDS on an SGI, SN1.
+ */
+
+static __inline__ void
+set_led_bits(u8 value, u8 mask)
+{
+	pda.led_state = (pda.led_state & ~mask) | (value & mask);
+#ifdef CONFIG_IA64_SGI_SN1
+	*pda.led_address = (long) pda.led_state;
+#else
+	*pda.led_address = (short) pda.led_state;
+#endif
+}
+
+#endif /* _ASM_IA64_SN_LEDS_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/mca.h linux/include/asm-ia64/sn/mca.h
--- linux.orig/include/asm-ia64/sn/mca.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/mca.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,128 @@
+/*
+ * File:	mca.h
+ * Purpose:	Machine check handling specific to the SN platform defines
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/sal.h>
+#include <asm/mca.h>
+
+#ifdef CONFIG_IA64_SGI_SN
+
+typedef u64 __uint64_t;
+
+typedef struct {
+	__uint64_t sh_event_occurred;
+	__uint64_t sh_first_error;
+	__uint64_t sh_event_overflow;
+	__uint64_t sh_pi_first_error;
+	__uint64_t sh_pi_error_summary;
+	__uint64_t sh_pi_error_overflow;
+	__uint64_t sh_pi_error_detail_1;
+	__uint64_t sh_pi_error_detail_2;
+	__uint64_t sh_pi_hw_time_stamp;
+	__uint64_t sh_pi_uncorrected_detail_1;
+	__uint64_t sh_pi_uncorrected_detail_2;
+	__uint64_t sh_pi_uncorrected_detail_3;
+	__uint64_t sh_pi_uncorrected_detail_4;
+	__uint64_t sh_pi_uncor_time_stamp;
+	__uint64_t sh_pi_corrected_detail_1;
+	__uint64_t sh_pi_corrected_detail_2;
+	__uint64_t sh_pi_corrected_detail_3;
+	__uint64_t sh_pi_corrected_detail_4;
+	__uint64_t sh_pi_cor_time_stamp;
+	__uint64_t sh_mem_error_summary;
+	__uint64_t sh_mem_error_overflow;
+	__uint64_t sh_misc_err_hdr_lower;
+	__uint64_t sh_misc_err_hdr_upper;
+	__uint64_t sh_dir_uc_err_hdr_lower;
+	__uint64_t sh_dir_uc_err_hdr_upper;
+	__uint64_t sh_dir_cor_err_hdr_lower;
+	__uint64_t sh_dir_cor_err_hdr_upper;
+	__uint64_t sh_mem_error_mask;
+	__uint64_t sh_md_uncor_time_stamp;
+	__uint64_t sh_md_cor_time_stamp;
+	__uint64_t sh_md_hw_time_stamp;
+	__uint64_t sh_xn_error_summary;
+	__uint64_t sh_xn_first_error;
+	__uint64_t sh_xn_error_overflow;
+	__uint64_t sh_xniilb_error_summary;
+	__uint64_t sh_xniilb_first_error;
+	__uint64_t sh_xniilb_error_overflow;
+	__uint64_t sh_xniilb_error_detail_1;
+	__uint64_t sh_xniilb_error_detail_2;
+	__uint64_t sh_xniilb_error_detail_3;
+	__uint64_t sh_xnpi_error_summary;
+	__uint64_t sh_xnpi_first_error;
+	__uint64_t sh_xnpi_error_overflow;
+	__uint64_t sh_xnpi_error_detail_1;
+	__uint64_t sh_xnmd_error_summary;
+	__uint64_t sh_xnmd_first_error;
+	__uint64_t sh_xnmd_error_overflow;
+	__uint64_t sh_xnmd_ecc_err_report;
+	__uint64_t sh_xnmd_error_detail_1;
+	__uint64_t sh_lb_error_summary;
+	__uint64_t sh_lb_first_error;
+	__uint64_t sh_lb_error_overflow;
+	__uint64_t sh_lb_error_detail_1;
+	__uint64_t sh_lb_error_detail_2;
+	__uint64_t sh_lb_error_detail_3;
+	__uint64_t sh_lb_error_detail_4;
+	__uint64_t sh_lb_error_detail_5;
+} sal_log_shub_state_t;
+
+typedef struct {
+sal_log_section_hdr_t header;
+	struct
+	{
+		__uint64_t    err_status      : 1,
+		guid            : 1,
+		oem_data        : 1,
+		reserved        : 61;
+	} valid;
+	__uint64_t             err_status;
+	efi_guid_t      guid;
+	__uint64_t shub_nic;
+	sal_log_shub_state_t    shub_state;
+} sal_log_plat_info_t;
+
+
+extern void sal_log_plat_print(int header_len, int sect_len, u8 *p_data, prfunc_t prfunc);
+
+#ifdef platform_plat_specific_err_print
+#undef platform_plat_specific_err_print
+#endif
+#define platform_plat_specific_err_print sal_log_plat_print
+
+#endif /* CONFIG_IA64_SGI_SN */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/mem_refcnt.h linux/include/asm-ia64/sn/mem_refcnt.h
--- linux.orig/include/asm-ia64/sn/mem_refcnt.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/mem_refcnt.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,26 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_MEM_REFCNT_H
-#define _ASM_SN_MEM_REFCNT_H
-
-extern int mem_refcnt_attach(devfs_handle_t hub);
-extern int mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp);
-extern int mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp);
-extern int mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot);
-extern int mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt);
-extern int mem_refcnt_ioctl(devfs_handle_t dev,
-                 int cmd,
-                 void *arg,
-                 int mode,
-                 cred_t *cred_p,
-                 int *rvalp);
-        
-
-#endif /* _ASM_SN_MEM_REFCNT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/mmtimer_private.h linux/include/asm-ia64/sn/mmtimer_private.h
--- linux.orig/include/asm-ia64/sn/mmtimer_private.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/mmtimer_private.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,42 @@
+/*
+ * Intel Multimedia Timer device interface
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * Helper file for the SN implementation of mmtimers
+ *
+ * 11/01/01 - jbarnes - initial revision
+ */
+
+#ifndef _SN_MMTIMER_PRIVATE_H
+
+#define RTC_BITS 55 /* 55 bits for this implementation */
+#define NUM_COMPARATORS 2 /* two comparison registers in SN1 */
+
+/*
+ * Check for an interrupt and clear the pending bit if
+ * one is waiting.
+ */
+#define MMTIMER_INT_PENDING(x) (x ? *(RTC_INT_PENDING_B_ADDR) : *(RTC_INT_PENDING_A_ADDR))
+
+/*
+ * Set interrupts on RTC 'x' to 'v' (true or false)
+ */
+#define MMTIMER_SET_INT(x,v) (x ? (*(RTC_INT_ENABLED_B_ADDR) = (unsigned long)(v)) : (*(RTC_INT_ENABLED_A_ADDR) = (unsigned long)(v)))
+
+#define MMTIMER_ENABLE_INT(x) MMTIMER_SET_INT(x, 1)
+#define MMTIMER_DISABLE_INT(x) MMTIMER_SET_INT(x, 0)
+
+typedef struct mmtimer {
+	spinlock_t timer_lock;
+	unsigned long periodic;
+	int signo;
+	volatile unsigned long *compare;
+	struct task_struct *process;
+} mmtimer_t;
+
+#endif /* _SN_LINUX_MMTIMER_PRIVATE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/mmzone.h linux/include/asm-ia64/sn/mmzone.h
--- linux.orig/include/asm-ia64/sn/mmzone.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/mmzone.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,113 +0,0 @@
-/*
- * Written by Kanoj Sarcar (kanoj@sgi.com) Jan 2000
- * Copyright, 2000, Silicon Graphics, sprasad@engr.sgi.com
- */
-#ifndef _LINUX_ASM_SN_MMZONE_H
-#define _LINUX_ASM_SN_MMZONE_H
-
-#include <linux/config.h>
-
-#include <asm/sn/mmzone_sn1.h>
-#include <asm/sn/sn_cpuid.h>
-
-/*
- * Memory is conceptually divided into chunks. A chunk is either
- * completely present, or else the kernel assumes it is completely
- * absent. Each node consists of a number of contiguous chunks.
- */
-
-#define CHUNKMASK       	(~(CHUNKSZ - 1))
-#define CHUNKNUM(vaddr)        	(__pa(vaddr) >> CHUNKSHIFT)
-#define PCHUNKNUM(paddr)        ((paddr) >> CHUNKSHIFT)
-
-#define MAXCHUNKS      		(MAXNODES * MAX_CHUNKS_PER_NODE)
-
-extern int chunktonid[];
-#define CHUNKTONID(cnum)       (chunktonid[cnum])
-
-typedef struct plat_pglist_data {
-       pg_data_t       gendata;		/* try to keep this first. */
-       unsigned long   virtstart;
-       unsigned long   size;
-} plat_pg_data_t;
-
-extern plat_pg_data_t plat_node_data[];
-
-extern int numa_debug(void);
-
-/*
- * The foll two will move into linux/mmzone.h RSN.
- */
-#define NODE_START(n)  plat_node_data[(n)].virtstart
-#define NODE_SIZE(n)   plat_node_data[(n)].size
-
-#define KVADDR_TO_NID(kaddr) \
-       ((CHUNKTONID(CHUNKNUM((kaddr))) != -1) ? (CHUNKTONID(CHUNKNUM((kaddr)))) : \
-       (printk("DISCONTIGBUG: %s line %d addr 0x%lx", __FILE__, __LINE__, \
-       (unsigned long)(kaddr)), numa_debug()))
-#if 0
-#define KVADDR_TO_NID(kaddr) CHUNKTONID(CHUNKNUM((kaddr)))
-#endif
-
-/* These 2 macros should never be used if KVADDR_TO_NID(kaddr) is -1 */
-/*
- * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
- * and returns the mem_map of that node.
- */
-#define ADDR_TO_MAPBASE(kaddr) \
-                       NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
-
-/*
- * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
- * and returns the kaddr corresponding to first physical page in the
- * node's mem_map.
- */
-#define LOCAL_BASE_ADDR(kaddr) NODE_START(KVADDR_TO_NID(kaddr))
-
-#ifdef CONFIG_DISCONTIGMEM
-
-/*
- * Return a pointer to the node data for node n.
- * Assume that n is the compact node id.
- */
-#define NODE_DATA(n)   (&((plat_node_data + (n))->gendata))
-
-/*
- * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
- */
-#define NODE_MEM_MAP(nid)      (NODE_DATA((nid))->node_mem_map)
-
-/* This macro should never be used if KVADDR_TO_NID(kaddr) is -1 */
-#define LOCAL_MAP_NR(kvaddr) \
-        (((unsigned long)(kvaddr)-LOCAL_BASE_ADDR((kvaddr))) >> PAGE_SHIFT)
-#define MAP_NR_SN1(kaddr)   (LOCAL_MAP_NR((kaddr)) + \
-                (((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \
-                sizeof(mem_map_t)))
-#if 0
-#define MAP_NR_VALID(kaddr)   (LOCAL_MAP_NR((kaddr)) + \
-                (((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \
-                sizeof(mem_map_t)))
-#define MAP_NR_SN1(kaddr)	((KVADDR_TO_NID(kaddr) == -1) ? (max_mapnr + 1) :\
-				MAP_NR_VALID(kaddr))
-#endif
-
-/* FIXME */
-#define sn1_pte_pagenr(x)		MAP_NR_SN1(PAGE_OFFSET + (unsigned long)((pte_val(x)&_PFN_MASK) & PAGE_MASK))
-#define pte_page(pte)			(mem_map + sn1_pte_pagenr(pte))
-/* FIXME */
-
-#define kern_addr_valid(addr)   ((KVADDR_TO_NID((unsigned long)addr) >= \
-        numnodes) ? 0 : (test_bit(LOCAL_MAP_NR((addr)), \
-        NODE_DATA(KVADDR_TO_NID((unsigned long)addr))->valid_addr_bitmap)))
-
-#define virt_to_page(kaddr)	(mem_map + MAP_NR_SN1(kaddr))
-
-#else /* CONFIG_DISCONTIGMEM */
-
-#define MAP_NR_SN1(addr)	(((unsigned long) (addr) - PAGE_OFFSET) >> PAGE_SHIFT)
-
-#endif /* CONFIG_DISCONTIGMEM */
-
-#define numa_node_id()		cpuid_to_cnodeid(smp_processor_id())
-
-#endif /* !_LINUX_ASM_SN_MMZONE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/mmzone_default.h linux/include/asm-ia64/sn/mmzone_default.h
--- linux.orig/include/asm-ia64/sn/mmzone_default.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/mmzone_default.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,15 +0,0 @@
-/*
- * Copyright, 2000, Silicon Graphics, sprasad@engr.sgi.com
- */
-
-#define MAXNODES                16
-#define MAXNASIDS               16
-
-#define CHUNKSZ                (8*1024*1024)
-#define CHUNKSHIFT              23      /* 2 ^^ CHUNKSHIFT == CHUNKSZ */
-
-#define CNODEID_TO_NASID(n)	n
-#define NASID_TO_CNODEID(n)     n
-
-#define MAX_CHUNKS_PER_NODE     8
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/mmzone_sn1.h linux/include/asm-ia64/sn/mmzone_sn1.h
--- linux.orig/include/asm-ia64/sn/mmzone_sn1.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/mmzone_sn1.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,105 +0,0 @@
-#ifndef _ASM_IA64_MMZONE_SN1_H
-#define _ASM_IA64_MMZONE_SN1_H
-
-#include <linux/config.h>
-
-/*
- * Copyright, 2000, Silicon Graphics, sprasad@engr.sgi.com
- */
-/* Maximum configuration supported by SNIA hardware. There are other
- * restrictions that may limit us to a smaller max configuration.
- */
-#define MAXNODES                128
-#define MAXNASIDS		128
-
-#define CHUNKSZ                (64*1024*1024)
-#define CHUNKSHIFT              26      /* 2 ^^ CHUNKSHIFT == CHUNKSZ */
-
-extern int 	cnodeid_map[] ;
-extern int	nasid_map[] ;
-
-#define CNODEID_TO_NASID(n)	(cnodeid_map[(n)])
-#define NASID_TO_CNODEID(n)     (nasid_map[(n)])
-
-#define MAX_CHUNKS_PER_NODE     128
-
-
-/*
- * These are a bunch of sn1 hw specific defines. For now, keep it 
- * in this file. If it gets too diverse we may want to create a 
- * mmhwdefs_sn1.h
- */
-
-/*
- * Structure of the mem config of the node as a SN1 MI reg
- * Medusa supports this reg config.
- */
-
-typedef struct node_memmap_s
-{
-        unsigned int    b0      :1,     /* 0 bank 0 present */
-                        b1      :1,     /* 1 bank 1 present */
-                        r01     :2,     /* 2-3 reserved */
-                        b01size :4,     /* 4-7 Size of bank 0 and 1 */
-                        b2      :1,     /* 8 bank 2 present */
-                        b3      :1,     /* 9 bank 3 present */
-                        r23     :2,     /* 10-11 reserved */
-                        b23size :4,     /* 12-15 Size of bank 2 and 3 */
-                        b4      :1,     /* 16 bank 4 present */
-                        b5      :1,     /* 17 bank 5 present */
-                        r45     :2,     /* 18-19 reserved */
-                        b45size :4,     /* 20-23 Size of bank 4 and 5 */
-                        b6      :1,     /* 24 bank 6 present */
-                        b7      :1,     /* 25 bank 7 present */
-                        r67     :2,     /* 26-27 reserved */
-                        b67size :4;     /* 28-31 Size of bank 6 and 7 */
-} node_memmap_t ;
-
-#define GBSHIFT                 30
-#define MBSHIFT                 20
-
-/*
- * SN1 Arch defined values
- */
-#define SN1_MAX_BANK_PER_NODE   8
-#define SN1_BANK_PER_NODE_SHIFT 3       /* derived from SN1_MAX_BANK_PER_NODE */
-#define SN1_NODE_ADDR_SHIFT     (GBSHIFT+3)             /* 8GB */
-#define SN1_BANK_ADDR_SHIFT     (SN1_NODE_ADDR_SHIFT-SN1_BANK_PER_NODE_SHIFT)
-
-#define SN1_BANK_SIZE_SHIFT     (MBSHIFT+6)     /* 64 MB */
-#define SN1_MIN_BANK_SIZE_SHIFT SN1_BANK_SIZE_SHIFT
-
-/*
- * BankSize nibble to bank size mapping
- *
- *      1 - 64 MB
- *      2 - 128 MB
- *      3 - 256 MB
- *      4 - 512 MB
- *      5 - 1024 MB (1GB)
- */
-
-/* fixme - this macro breaks for bsize 6-8 and 0 */
-
-#ifdef CONFIG_IA64_SGI_SN1_SIM
-/* Support the medusa hack for 8M/16M/32M nodes */
-#define BankSizeBytes(bsize)            ((bsize<6) ? (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT)) :\
-					 (1<<((bsize-9)+MBSHIFT)))
-#else
-#define BankSizeBytes(bsize)            (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT))
-#endif
-
-#define BankSizeToEFIPages(bsize)       ((BankSizeBytes(bsize)) >> 12)
-
-#define GetPhysAddr(n,b)                (((u64)n<<SN1_NODE_ADDR_SHIFT) | \
-                                                ((u64)b<<SN1_BANK_ADDR_SHIFT))
-
-#define GetNasId(paddr)			((u64)(paddr) >> SN1_NODE_ADDR_SHIFT)
-
-#define GetBankId(paddr)						\
-				(((u64)(paddr) >> SN1_BANK_ADDR_SHIFT) & 7)
-
-#define SN1_MAX_BANK_SIZE		((u64)BankSizeBytes(5))
-#define SN1_BANK_SIZE_MASK		(~(SN1_MAX_BANK_SIZE-1))
-
-#endif /* _ASM_IA64_MMZONE_SN1_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/module.h linux/include/asm-ia64/sn/module.h
--- linux.orig/include/asm-ia64/sn/module.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/module.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,31 +1,24 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_MODULE_H
-#define _ASM_SN_MODULE_H
+#ifndef _ASM_IA64_SN_MODULE_H
+#define _ASM_IA64_SN_MODULE_H
 
 #ifdef	__cplusplus
 extern "C" {
 #endif
 
-#include <linux/config.h>
 
 #include <asm/sn/systeminfo.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/ksys/elsc.h>
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#ifdef BRINGUP /* max. number of modules?  Should be about 300.*/
-#define MODULE_MAX			56
-#endif /* BRINGUP */
+#define MODULE_MAX			128
 #define MODULE_MAX_NODES		1
-#endif /* CONFIG_SGI_IP35 */
 #define MODULE_HIST_CNT			16
 #define MAX_MODULE_LEN			16
 
@@ -39,8 +32,6 @@
 #define MODULE_FORMAT_LONG	2
 
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-
 /*
  *	Module id format
  *
@@ -134,17 +125,6 @@
 				 ((_m2)&(MODULE_RACK_MASK|MODULE_BPOS_MASK)))
 #define MODULE_MATCH(_m1, _m2)	(MODULE_CMP((_m1),(_m2)) == 0)
 
-#else
-
-/*
- * Some code that uses this macro will not be conditionally compiled.
- */
-#define MODULE_GET_BTCHAR(_m)	('?')
-#define MODULE_CMP(_m1, _m2)	((_m1) - (_m2))
-#define MODULE_MATCH(_m1, _m2)	(MODULE_CMP((_m1),(_m2)) == 0)
-
-#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
-
 typedef struct module_s module_t;
 
 struct module_s {
@@ -205,4 +185,4 @@
 }
 #endif
 
-#endif /* _ASM_SN_MODULE_H */
+#endif /* _ASM_IA64_SN_MODULE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/nag.h linux/include/asm-ia64/sn/nag.h
--- linux.orig/include/asm-ia64/sn/nag.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/nag.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+*/
+
+
+#ifndef _ASM_IA64_SN_NAG_H
+#define _ASM_IA64_SN_NAG_H
+
+
+#define NAG(mesg...) \
+do {										\
+	static unsigned int how_broken = 1;					\
+	static unsigned int threshold = 1;					\
+	if (how_broken == threshold) {						\
+		if (threshold < 10000)						\
+			threshold *= 10;					\
+		if (how_broken > 1)						\
+			printk(KERN_WARNING "%u times: ", how_broken);		\
+		else								\
+			printk(KERN_WARNING);					\
+		printk(mesg);							\
+	}									\
+	how_broken++;								\
+} while (0)
+
+
+#endif /* _ASM_IA64_SN_NAG_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/nic.h linux/include/asm-ia64/sn/nic.h
--- linux.orig/include/asm-ia64/sn/nic.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/nic.h	2002-07-20 01:08:29.000000000 +0000
@@ -4,13 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_NIC_H
-#define _ASM_SN_NIC_H
+#ifndef _ASM_IA64_SN_NIC_H
+#define _ASM_IA64_SN_NIC_H
 
 #include <asm/types.h>
+#include <asm/sn/types.h>
+#include <linux/devfs_fs_kernel.h>
 
 #define MCR_DATA(x)			((int) ((x) & 1))
 #define MCR_DONE(x)			((x) & 2)
@@ -125,4 +126,4 @@
 extern nic_vmce_t	nic_vmc_add(char *, nic_vmc_func *);
 extern void		nic_vmc_del(nic_vmce_t);
 
-#endif /* _ASM_SN_NIC_H */
+#endif /* _ASM_IA64_SN_NIC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/nodemask.h linux/include/asm-ia64/sn/nodemask.h
--- linux.orig/include/asm-ia64/sn/nodemask.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/nodemask.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,330 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_NODEMASK_H
-#define _ASM_SN_NODEMASK_H
-
-#if defined(__KERNEL__) || defined(_KMEMUSER)
-
-#include <linux/config.h>
-
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
-#include <asm/sn/sn1/arch.h>    /* needed for MAX_COMPACT_NODES */
-#endif
-
-#define CNODEMASK_BOOTED_MASK		boot_cnodemask
-#define CNODEMASK_BIPW    64
-
-#if !defined(SN0XXL) && !defined(CONFIG_SGI_IP35) && !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC)
-			/* MAXCPUS 128p (64 nodes) or less */
-
-#define CNODEMASK_SIZE    1
-typedef uint64_t cnodemask_t;
-
-#define CNODEMASK_WORD(p,w)     (p)
-#define CNODEMASK_SET_WORD(p,w,val)     (p) = val
-#define CNODEMASK_CLRALL(p)     (p) = 0
-#define CNODEMASK_SETALL(p)     (p) = ~((cnodemask_t)0)
-#define CNODEMASK_IS_ZERO(p)	((p) == 0)
-#define CNODEMASK_IS_NONZERO(p)	((p) != 0)
-#define CNODEMASK_NOTEQ(p, q)	((p) != (q))
-#define CNODEMASK_EQ(p, q)      ((p) == (q))
-#define CNODEMASK_LSB_ISONE(p)  ((p) & 0x1ULL)
-
-#define CNODEMASK_ZERO()        ((cnodemask_t)0)
-#define CNODEMASK_CVTB(bit)     (1ULL << (bit))
-#define CNODEMASK_SETB(p, bit)	((p) |= 1ULL << (bit))
-#define CNODEMASK_CLRB(p, bit)	((p) &= ~(1ULL << (bit)))
-#define CNODEMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
-
-#define CNODEMASK_SETM(p, q)	((p) |= (q))
-#define CNODEMASK_CLRM(p, q)	((p) &= ~(q))
-#define CNODEMASK_ANDM(p, q)	((p) &= (q))
-#define CNODEMASK_TSTM(p, q)	((p) & (q))
-
-#define CNODEMASK_CPYNOTM(p, q)	((p) = ~(q))
-#define CNODEMASK_CPY(p, q)     ((p) = (q))
-#define CNODEMASK_ORNOTM(p, q)	((p) |= ~(q))
-#define CNODEMASK_SHIFTL(p)     ((p) <<= 1)
-#define CNODEMASK_SHIFTR(p)     ((p) >>= 1)
-#define CNODEMASK_SHIFTL_PTR(p)     (*(p) <<= 1)
-#define CNODEMASK_SHIFTR_PTR(p)     (*(p) >>= 1)
-
-/* Atomically set or clear a particular bit */
-#define CNODEMASK_ATOMSET_BIT(p, bit) atomicSetUlong((cnodemask_t *)&(p), (1ULL<<(bit))) 
-#define CNODEMASK_ATOMCLR_BIT(p, bit) atomicClearUlong((cnodemask_t *)&(p), (1ULL<<(bit)))
-
-/* Atomically set or clear a collection of bits */
-#define CNODEMASK_ATOMSET(p, q)  atomicSetUlong((cnodemask_t *)&(p), q)
-#define CNODEMASK_ATOMCLR(p, q)  atomicClearUlong((cnodemask_t *)&(p), q)
-
-/* Atomically set or clear a collection of bits, returning the old value */
-#define CNODEMASK_ATOMSET_MASK(__old, p, q)	{ \
-		(__old) = atomicSetUlong((cnodemask_t *)&(p), q); \
-}
-#define CNODEMASK_ATOMCLR_MASK(__old, p, q)	{ \
-		(__old) = atomicClearUlong((cnodemask_t *)&(p),q); \
-}
-
-#define CNODEMASK_FROM_NUMNODES(n)	((~(cnodemask_t)0)>>(CNODEMASK_BIPW-(n)))
-
-#else  /* SN0XXL || SN1 - MAXCPUS > 128 */
-
-#define CNODEMASK_SIZE    (MAX_COMPACT_NODES / CNODEMASK_BIPW)
-
-typedef struct {
-        uint64_t _bits[CNODEMASK_SIZE];
-} cnodemask_t;
-
-#define CNODEMASK_WORD(p,w)  \
-	((w >= 0 && w < CNODEMASK_SIZE) ? (p)._bits[(w)] : 0)
-#define CNODEMASK_SET_WORD(p,w,val)  { 				\
-	if (w >= 0 && w < CNODEMASK_SIZE) 			\
-		(p)._bits[(w)] = val;				\
-}
-
-#define CNODEMASK_CLRALL(p)       {                             \
-        int i;                                                  \
-                                                                \
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)                  \
-                (p)._bits[i] = 0;                               \
-}
-
-#define CNODEMASK_SETALL(p)       {                             \
-        int i;                                                  \
-                                                                \
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)                  \
-                (p)._bits[i] = ~(0);                            \
-}
-
-#define CNODEMASK_LSB_ISONE(p)  ((p)._bits[0] & 0x1ULL)
-
-
-#define CNODEMASK_SETM(p,q)       {                             \
-        int i;                                                  \
-                                                                \
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)                  \
-                (p)._bits[i] |= ((q)._bits[i]);                 \
-}
-
-#define CNODEMASK_CLRM(p,q)       {                             \
-        int i;                                                  \
-                                                                \
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)                  \
-                (p)._bits[i] &= ~((q)._bits[i]);                \
-}
-
-#define CNODEMASK_ANDM(p,q)       {                             \
-        int i;                                                  \
-                                                                \
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)                  \
-                (p)._bits[i] &= ((q)._bits[i]);                 \
-}
-
-#define CNODEMASK_CPY(p, q)  {					\
-        int i;                                                  \
-                                                                \
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)                  \
-                (p)._bits[i] = (q)._bits[i];	                \
-}
-
-#define CNODEMASK_CPYNOTM(p,q)    {                             \
-        int i;                                                  \
-                                                                \
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)                  \
-                (p)._bits[i] = ~((q)._bits[i]);                 \
-}
-
-#define CNODEMASK_ORNOTM(p,q)     {                             \
-        int i;                                                  \
-                                                                \
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)                  \
-                (p)._bits[i] |= ~((q)._bits[i]);                \
-}
-
-#define CNODEMASK_INDEX(bit)      ((bit) >> 6)
-#define CNODEMASK_SHFT(bit)       ((bit) & 0x3f)
-
-
-#define CNODEMASK_SETB(p, bit)	 				\
-	(p)._bits[CNODEMASK_INDEX(bit)] |= (1ULL << CNODEMASK_SHFT(bit))
-
-
-#define CNODEMASK_CLRB(p, bit)					\
-	(p)._bits[CNODEMASK_INDEX(bit)] &= ~(1ULL << CNODEMASK_SHFT(bit)) 
-
-
-#define CNODEMASK_TSTB(p, bit)		\
-	((p)._bits[CNODEMASK_INDEX(bit)] & (1ULL << CNODEMASK_SHFT(bit))) 
-
-/** Probably should add atomic update for entire cnodemask_t struct **/
-
-/* Atomically set or clear a particular bit */
-#define CNODEMASK_ATOMSET_BIT(p, bit) \
-        (atomicSetUlong((unsigned long *)&(p)._bits[CNODEMASK_INDEX(bit)], (1ULL << CNODEMASK_SHFT(bit))));
-#define CNODEMASK_ATOMCLR_BIT(__old, p, bit) \
-        (atomicClearUlong((unsigned long *)&(p)._bits[CNODEMASK_INDEX(bit)], (1ULL << CNODEMASK_SHFT(bit))));
-
-/* Atomically set or clear a collection of bits */
-#define CNODEMASK_ATOMSET(p, q) { \
-        int i;				\
-					\
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++) { \
-	      atomicSetUlong((unsigned long *)&(p)._bits[i], (q)._bits[i]);  \
-        }				\
-}
-#define CNODEMASK_ATOMCLR(p, q) { \
-        int i;				\
-                        		\
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++) {	\
-	      atomicClearUlong((unsigned long *)&(p)._bits[i], (q)._bits[i]); \
-        }				\
-}
-
-/* Atomically set or clear a collection of bits, returning the old value */
-#define CNODEMASK_ATOMSET_MASK(__old, p, q)  { \
-        int i;				\
-					\
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++) { \
-           (__old)._bits[i] =	 \
-	      atomicSetUlong((unsigned long *)&(p)._bits[i], (q)._bits[i]);  \
-        }				\
-}
-#define CNODEMASK_ATOMCLR_MASK(__old, p, q) {					\
-        int i;				\
-                        		\
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++) {	\
-           (__old)._bits[i] =				\
-	      atomicClearUlong((unsigned long *)&(p)._bits[i], (q)._bits[i]); \
-        }				\
-}
-
-__inline static cnodemask_t CNODEMASK_CVTB(int bit) 
-{
-	cnodemask_t __tmp;
-	CNODEMASK_CLRALL(__tmp);
-	CNODEMASK_SETB(__tmp,bit);
-	return(__tmp);
-}
-
-
-__inline static cnodemask_t CNODEMASK_ZERO(void)
-{
-	cnodemask_t __tmp;
-	CNODEMASK_CLRALL(__tmp);
-	return(__tmp);
-}
-
-__inline static int CNODEMASK_IS_ZERO (cnodemask_t p)
-{
-        int i;
-
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)
-                if (p._bits[i] != 0)
-                        return 0;
-        return 1;
-}
-
-__inline static int CNODEMASK_IS_NONZERO (cnodemask_t p)
-{
-        int i;
-
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)
-                if (p._bits[i] != 0)
-                        return 1;
-        return 0;
-}
-
-__inline static int CNODEMASK_NOTEQ (cnodemask_t p, cnodemask_t q)
-{
-        int i;
-
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)
-                if (p._bits[i] != q._bits[i])
-                        return 1;
-        return 0;
-}
-
-__inline static int CNODEMASK_EQ (cnodemask_t p, cnodemask_t q)
-{
-        int i;
-
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)
-                if (p._bits[i] != q._bits[i])
-                        return 0;
-        return 1;
-}
-
-
-__inline static int CNODEMASK_TSTM (cnodemask_t p, cnodemask_t q)
-{
-        int i;
-
-        for (i = 0 ; i < CNODEMASK_SIZE ; i++)
-                if (p._bits[i] & q._bits[i])
-                        return 1;
-        return 0;
-}
-
-__inline static void CNODEMASK_SHIFTL_PTR (cnodemask_t *p)
-{
-        int i;
-        uint64_t upper;
-
-        /*
-         * shift words starting with the last word
-         * of the vector and work backward to the first
-         * word updating the low order bits with the
-         * high order bit of the prev word.
-         */
-        for (i=(CNODEMASK_SIZE-1); i > 0; --i) {
-	   upper = (p->_bits[i-1] & (1ULL<<(CNODEMASK_BIPW-1))) ? 1 : 0;
-           p->_bits[i] <<= 1;
-           p->_bits[i] |= upper;
-        }
-        p->_bits[i] <<= 1;
-}
-
-__inline static void CNODEMASK_SHIFTR_PTR (cnodemask_t *p)
-{
-        int i;
-        uint64_t lower;
-
-        /*
-         * shift words starting with the first word
-         * of the vector and work forward to the last
-         * word updating the high order bit with the
-         * low order bit of the next word.
-         */
-        for (i=0; i < (CNODEMASK_SIZE-2); ++i) {
-	   lower = (p->_bits[i+1] & (0x1)) ? 1 : 0;
-           p->_bits[i] >>= 1;
-           p->_bits[i] |= (lower<<((CNODEMASK_BIPW-1)));
-        }
-        p->_bits[i] >>= 1;
-}
-
-__inline static cnodemask_t CNODEMASK_FROM_NUMNODES(int n)
-{
-	cnodemask_t __tmp;
-	int i;
-	CNODEMASK_CLRALL(__tmp);
-	for (i=0; i<n; i++) {
-		CNODEMASK_SETB(__tmp, i);
-	}
-	return(__tmp);
-}
-
-#endif /* SN0XXL || SN1 */
-
-extern cnodemask_t boot_cnodemask;
-
-#endif /* __KERNEL__ || _KMEMUSER */
-
-#endif /* _ASM_SN_NODEMASK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/nodepda.h linux/include/asm-ia64/sn/nodepda.h
--- linux.orig/include/asm-ia64/sn/nodepda.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/nodepda.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,32 +1,28 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_NODEPDA_H
-#define _ASM_SN_NODEPDA_H
+#ifndef _ASM_IA64_SN_NODEPDA_H
+#define _ASM_IA64_SN_NODEPDA_H
 
-#ifdef	__cplusplus
-extern "C" {
-#endif
 
 #include <linux/config.h>
-
-#include <asm/sn/agent.h>
+#include <asm/irq.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/router.h>
-#include <asm/sn/synergy.h>
-/* #include <SN/klkernvars.h> */
-#ifdef LATER
-typedef struct module_s module_t;       /* Avoids sys/SN/module.h */
-#else
+#if defined(CONFIG_IA64_SGI_SN1)
+#include <asm/sn/sn1/synergy.h>
+#endif
+#include <asm/sn/pda.h>
 #include <asm/sn/module.h>
+#include <asm/sn/bte.h>
+
+#if defined(CONFIG_IA64_SGI_SN1)
+#include <asm/sn/sn1/hubstat.h>
 #endif
-/* #include <SN/slotnum.h> */
 
 /*
  * NUMA Node-Specific Data structures are defined in this file.
@@ -37,26 +33,16 @@
 /*
  * Subnode PDA structures. Each node needs a few data structures that 
  * correspond to the PIs on the HUB chip that supports the node.
- *
- * WARNING!!!! 6.5.x compatibility requirements prevent us from
- * changing or reordering fields in the following structure for IP27.
- * It is essential that the data mappings not change for IP27 platforms.
- * It is OK to add fields that are IP35 specific if they are under #ifdef IP35.
  */
+#if defined(CONFIG_IA64_SGI_SN1)
 struct subnodepda_s {
 	intr_vecblk_t	intr_dispatch0;
 	intr_vecblk_t	intr_dispatch1;
-	uint64_t	next_prof_timeout;
-	int		prof_count;
 };
 
-
 typedef struct subnodepda_s subnode_pda_t;
 
 
-struct ptpool_s;
-
-#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
 struct synergy_perf_s;
 #endif
 
@@ -65,8 +51,6 @@
  * Node-specific data structure.
  *
  * One of these structures is allocated on each node of a NUMA system.
- * Non-NUMA systems are considered to be systems with one node, and
- * hence there will be one of this structure for the entire system.
  *
  * This structure provides a convenient way of keeping together 
  * all per-node data structures. 
@@ -74,119 +58,13 @@
 
 
 
-#ifdef LATER
-/*
- * The following structure is contained in the nodepda & contains
- * a lock & queue-head for sanon pages that belong to the node.
- * See the anon manager for more details.
- */
-typedef struct {
-	lock_t  sal_lock;
-	plist_t sal_listhead;
-} sanon_list_head_t;
-#endif
 struct nodepda_s {
 
-#ifdef	NUMA_BASE
-
-	/* 
-	 * Pointer to this node's copy of Nodepdaindr 
-	 */
-	struct nodepda_s	**pernode_pdaindr; 
-
-	/*
-         * Data used for migration control
-         */
-	struct migr_control_data_s *mcd; 
-
-	/*
-         * Data used for replication control
-         */
-	struct repl_control_data_s *rcd;
-
-        /*
-         * Numa statistics
-         */
-	struct numa_stats_s *numa_stats;
-
-        /*
-         * Load distribution
-         */
-        uint memfit_assign;
-
-        /*
-         * New extended memory reference counters
-         */
-        void *migr_refcnt_counterbase;
-        void *migr_refcnt_counterbuffer;
-        size_t migr_refcnt_cbsize;
-        int  migr_refcnt_numsets;
-
-        /*
-         * mem_tick quiescing lock
-         */
-        uint mem_tick_lock;
-
-        /*
-         * Migration candidate set
-         * by migration prologue intr handler
-         */
-        uint64_t migr_candidate;
-
-	/*
-	 * Each node gets its own syswait counter to remove contention
-	 * on the global one.
-	 */
-#ifdef	LATER
-	struct syswait syswait;
-#endif
-
-#endif	/* NUMA_BASE */
-	/*
-	 * Node-specific Zone structures.
-	 */
-#ifdef LATER
-	zoneset_element_t	node_zones;
-	pg_data_t	node_pg_data;	/* VM page data structures */ 
-	plist_t	error_discard_plist;
-#endif
-	uint		error_discard_count;
-	uint		error_page_count;
-	uint		error_cleaned_count;
-	spinlock_t	error_discard_lock;
 
-	/* Information needed for SN Hub chip interrupt handling. */
-	subnode_pda_t	snpda[NUM_SUBNODES];
-	/* Distributed kernel support */
-#ifdef	LATER
-	kern_vars_t	kern_vars;
-#endif
-	/* Vector operation support */
-	/* Change this to a sleep lock? */
-	spinlock_t	vector_lock;
-	/* State of the vector unit for this node */
-	char		vector_unit_busy;
 	cpuid_t         node_first_cpu; /* Starting cpu number for node */
-	ushort          node_num_cpus;  /* Number of cpus present       */
-
-	/* node utlbmiss info */
-  	spinlock_t		node_utlbswitchlock;
-	volatile cpumask_t	node_utlbmiss_flush;
-	volatile signed char	node_need_utlbmiss_patch;
-	volatile char		node_utlbmiss_patched;
-	nodepda_router_info_t	*npda_rip_first;
-	nodepda_router_info_t	**npda_rip_last;
-	int		dependent_routers;
-
-#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
-	int			synergy_perf_enabled;
-        int       		synergy_perf_freq;
-	spinlock_t		synergy_perf_lock;
-        uint64_t       		synergy_inactive_intervals;
-        uint64_t       		synergy_active_intervals;
-        struct synergy_perf_s	*synergy_perf_data;
-        struct synergy_perf_s	*synergy_perf_first; /* reporting consistency .. */
-#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
+					/* WARNING: no guarantee that   */
+					/*  the second cpu on a node is */
+					/*  node_first_cpu+1.           */
 
 	devfs_handle_t 	xbow_vhdl;
 	nasid_t		xbow_peer;	/* NASID of our peer hub on xbow */
@@ -194,84 +72,67 @@
 	slotid_t	slotdesc;
 	moduleid_t	module_id;	/* Module ID (redundant local copy) */
 	module_t	*module;	/* Pointer to containing module */
-	int		hub_chip_rev;	/* Rev of my Hub chip */
-	char		nasid_mask[NASID_MASK_BYTES];
-					/* Need a copy of the nasid mask
-					 * on every node */
 	xwidgetnum_t 	basew_id;
 	devfs_handle_t 	basew_xc;
-	spinlock_t	fprom_lock;
-	char		ni_error_print; /* For printing ni error state
-					 * only once during system panic
-					 */
-#ifdef	LATER
-	md_perf_monitor_t node_md_perfmon;
-	hubstat_t	hubstats;
 	int		hubticks;
-	sbe_info_t	*sbe_info;	/* ECC single-bit error statistics */
-#endif	/* LATER */
-	int		huberror_ticks;
-
-	router_queue_t  *visited_router_q;
-	router_queue_t	*bfs_router_q; 
-					/* Used for router traversal */
-#if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-	router_map_ent_t router_map[MAX_RTR_BREADTH];
-#endif
-	int		num_routers;	/* Total routers in the system */
+	int		num_routers;	/* XXX not setup! Total routers in the system */
 
-        char		membank_flavor;
-	                                /* Indicates what sort of memory 
-					 * banks are present on this node
-					 */
 	
 	char		*hwg_node_name;	/* hwgraph node name */
-
-	struct widget_info_t *widget_info;	/* Node as xtalk widget */
 	devfs_handle_t	node_vertex;	/* Hwgraph vertex for this node */
 
 	void 		*pdinfo;	/* Platform-dependent per-node info */
-	uint64_t	*dump_stack;	/* Dump stack during nmi handling */
-	int		dump_count;	/* To allow only one cpu-per-node */
-#ifdef	LATER
-	io_perf_monitor_t node_io_perfmon;
-#endif
 
-	/*
-	 * Each node gets its own pdcount counter to remove contention
-	 * on the global one.
-	 */
-
-	int pdcount;			/* count of pdinserted pages */
 
-#ifdef	NUMA_BASE
-	void		*cached_global_pool;	/* pointer to cached vmpool */
-#endif /* NUMA_BASE */
+	nodepda_router_info_t	*npda_rip_first;
+	nodepda_router_info_t	**npda_rip_last;
 
-#ifdef	LATER
-	sanon_list_head_t sanon_list_head;	/* head for sanon pages */	
-#endif
-#ifdef	NUMA_BASE
-	struct ptpool_s	*ptpool;	/* ptpool for this node */
-#endif /* NUMA_BASE */
 
 	/*
 	 * The BTEs on this node are shared by the local cpus
 	 */
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#ifdef	LATER
-	bteinfo_t	*node_bte_info[BTES_PER_NODE];
-#endif
-#endif
+	bteinfo_t	node_bte_info[BTES_PER_NODE];
+
+#if defined(CONFIG_IA64_SGI_SN1)
+	subnode_pda_t	snpda[NUM_SUBNODES];
+	/*
+	 * New extended memory reference counters
+ 	 */
+	void			*migr_refcnt_counterbase;
+	void			*migr_refcnt_counterbuffer;
+	size_t			migr_refcnt_cbsize;
+	int			migr_refcnt_numsets;
+	hubstat_t		hubstats;
+	int			synergy_perf_enabled;
+        int       		synergy_perf_freq;
+	spinlock_t		synergy_perf_lock;
+        uint64_t       		synergy_inactive_intervals;
+        uint64_t       		synergy_active_intervals;
+        struct synergy_perf_s	*synergy_perf_data;
+        struct synergy_perf_s	*synergy_perf_first; /* reporting consistency .. */
+#endif /* CONFIG_IA64_SGI_SN1 */
+
+	/* 
+	 * Array of pointers to the nodepdas for each node.
+	 */
+	struct nodepda_s	*pernode_pdaindr[MAX_COMPACT_NODES]; 
+
 };
 
 typedef struct nodepda_s nodepda_t;
 
+#ifdef CONFIG_IA64_SGI_SN2
+struct irqpda_s {
+	int num_irq_used;
+	char irq_flags[NR_IRQS];
+};
+
+typedef struct irqpda_s irqpda_t;
+
+#endif /* CONFIG_IA64_SGI_SN2 */
+
 
-#define NODE_MODULEID(_node)	(NODEPDA(_node)->module_id)
-#define NODE_SLOTID(_node)	(NODEPDA(_node)->slotdesc)
 
-#ifdef	NUMA_BASE
 /*
  * Access Functions for node PDA.
  * Since there is one nodepda for each node, we need a convenient mechanism
@@ -279,180 +140,49 @@
  * The next set of definitions provides this.
  * Routines are expected to use 
  *
- *	nodepda		-> to access PDA for the node on which code is running
- *	subnodepda	-> to access subnode PDA for the node on which code is running
+ *	nodepda			-> to access node PDA for the node on which code is running
+ *	subnodepda		-> to access subnode PDA for the subnode on which code is running
  *
- *	NODEPDA(x)	-> to access node PDA for cnodeid 'x'
- *	SUBNODEPDA(x,s)	-> to access subnode PDA for cnodeid/slice 'x'
- */
-
-#ifdef	LATER
-#define	nodepda		private.p_nodepda	/* Ptr to this node's PDA */
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
-#define subnodepda	private.p_subnodepda	/* Ptr to this node's subnode PDA */
-#endif
-
-#else
-/*
- * Until we have a shared node local area defined, do it this way ..
- * like in Caliase space.  See above.
- */
-extern nodepda_t        *nodepda;
-extern subnode_pda_t	*subnodepda;
-#endif
-
-/* 
- * Nodepdaindr[]
- * This is a private data structure for use only in early initialization.
- * All users of nodepda should use the macro NODEPDA(nodenum) to get
- * the suitable nodepda structure.
- * This macro has the advantage of not requiring #ifdefs for NUMA and
- * non-NUMA code.
- */
-extern nodepda_t	*Nodepdaindr[]; 
-/*
- * NODEPDA_GLOBAL(x) macro should ONLY be used during early initialization.
- * Once meminit is complete, NODEPDA(x) is ready to use.
- * During early init, the system fills up Nodepdaindr.  By the time we
- * are in meminit(), all nodepdas are initialized, and hence
- * we can fill up the node_pdaindr array in each nodepda structure.
+ *	NODEPDA(cnode)		-> to access node PDA for cnodeid 
+ *	SUBNODEPDA(cnode,sn)	-> to access subnode PDA for cnodeid/subnode
  */
-#define	NODEPDA_GLOBAL(x)	Nodepdaindr[x]
 
-/*
- * Returns a pointer to a given node's nodepda.
- */
-#define	NODEPDA(x)		(nodepda->pernode_pdaindr[x])
+#define	nodepda		pda.p_nodepda		/* Ptr to this node's PDA */
+#define	NODEPDA(cnode)		(nodepda->pernode_pdaindr[cnode])
 
-/*
- * Returns a pointer to a given node/slice's subnodepda.
- *	SUBNODEPDA(cnode, subnode) - uses cnode as first arg
- *	SNPDA(npda, subnode)	   - uses pointer to nodepda as first arg
- */
-#define	SUBNODEPDA(x,sn)	(&nodepda->pernode_pdaindr[x]->snpda[sn])
+#if defined(CONFIG_IA64_SGI_SN1)
+#define subnodepda	pda.p_subnodepda	/* Ptr to this node's subnode PDA */
+#define	SUBNODEPDA(cnode,sn)	(&(NODEPDA(cnode)->snpda[sn]))
 #define	SNPDA(npda,sn)		(&(npda)->snpda[sn])
+#endif
 
-#define NODEPDA_ERROR_FOOTPRINT(node, cpu) \
-                   (&(NODEPDA(node)->error_stamp[cpu]))
-#define NODEPDA_MDP_MON(node)	(&(NODEPDA(node)->node_md_perfmon))
-#define NODEPDA_IOP_MON(node)	(&(NODEPDA(node)->node_io_perfmon))
 
 /*
  * Macros to access data structures inside nodepda 
  */
-#if NUMA_MIGR_CONTROL
-#define NODEPDA_MCD(node) (NODEPDA(node)->mcd)
-#endif /* NUMA_MIGR_CONTROL */
-
-#if NUMA_REPL_CONTROL
-#define NODEPDA_RCD(node) (NODEPDA(node)->rcd)
-#endif /* NUMA_REPL_CONTROL */
-
-#if (NUMA_MIGR_CONTROL || NUMA_REPL_CONTROL)
-#define NODEPDA_LRS(node) (NODEPDA(node)->lrs)
-#endif /* (NUMA_MIGR_CONTROL || NUMA_REPL_CONTROL) */
+#define NODE_MODULEID(cnode)	(NODEPDA(cnode)->module_id)
+#define NODE_SLOTID(cnode)	(NODEPDA(cnode)->slotdesc)
 
-/* 
- * Exported functions
- */
-extern nodepda_t *nodepda_alloc(void);
 
-#else	/* !NUMA_BASE */
 /*
- * For a single-node system we will just have one global nodepda pointer
- * allocated at startup.  The global nodepda will point to this nodepda 
- * structure.
+ * Quickly convert a compact node ID into a hwgraph vertex
  */
-extern nodepda_t	*Nodepdaindr; 
+#define cnodeid_to_vertex(cnodeid) (NODEPDA(cnodeid)->node_vertex)
 
-/*
- * On non-NUMA systems, NODEPDA_GLOBAL and NODEPDA macros collapse to
- * be the same.
- */
-#define	NODEPDA_GLOBAL(x)	Nodepdaindr
 
 /*
- * Returns a pointer to a given node's nodepda.
+ * Check if given a compact node id the corresponding node has all the
+ * cpus disabled. 
  */
-#define	NODEPDA(x)	Nodepdaindr
+#define is_headless_node(cnode)		((cnode == CNODEID_NONE) ||			\
+					 (node_data(cnode)->active_cpu_count == 0))
 
 /*
- * nodepda can also be defined as private.p_nodepda.
- * But on non-NUMA systems, there is only one nodepda, and there is
- * no reason to go through the PDA to access this pointer.
- * Hence nodepda aliases to the global nodepda directly.
- *
- * Routines should use nodepda to access the local node's PDA.
- */
-#define	nodepda		(Nodepdaindr)
-
-#endif	/* NUMA_BASE */
-
-/* Quickly convert a compact node ID into a hwgraph vertex */
-#define cnodeid_to_vertex(cnodeid) (NODEPDA(cnodeid)->node_vertex)
-
-
-/* Check if given a compact node id the corresponding node has all the
- * cpus disabled. 
- */
-#define is_headless_node(_cnode)	((_cnode == CNODEID_NONE) || \
-					 (CNODE_NUM_CPUS(_cnode) == 0))
-/* Check if given a node vertex handle the corresponding node has all the
+ * Check if given a node vertex handle the corresponding node has all the
  * cpus disabled. 
  */
 #define is_headless_node_vertex(_nodevhdl) \
 			is_headless_node(nodevertex_to_cnodeid(_nodevhdl))
 
-#ifdef	__cplusplus
-}
-#endif
-
-#ifdef NUMA_BASE
-/*
- * To remove contention on the global syswait counter each node will have
- * its own.  Each clock tick the clock cpu will re-calculate the global
- * syswait counter by summing from each of the nodes.  The other cpus will
- * continue to read the global one during their clock ticks.   This does 
- * present a problem when a thread increments the count on one node and wakes
- * up on a different node and decrements it there.  Eventually the count could
- * overflow if this happens continually for a long period.  To prevent this
- * second_thread() periodically preserves the current syswait state and
- * resets the counters.
- */
-#define ADD_SYSWAIT(_field)	atomicAddInt(&nodepda->syswait._field, 1)
-#define SUB_SYSWAIT(_field)	atomicAddInt(&nodepda->syswait._field, -1)
-#else
-#define ADD_SYSWAIT(_field)				\
-{							\
-	ASSERT(syswait._field >= 0);			\
-	atomicAddInt(&syswait._field, 1);		\
-}
-#define SUB_SYSWAIT(_field)				\
-{							\
-	ASSERT(syswait._field > 0);			\
-	atomicAddInt(&syswait._field, -1);		\
-}
-#endif /* NUMA_BASE */
-
-#ifdef NUMA_BASE
-/*
- * Another global variable to remove contention from: pdcount.
- * See above comments for SYSWAIT.
- */
-#define ADD_PDCOUNT(_n)					\
-{							\
-	atomicAddInt(&nodepda->pdcount, _n);		\
-	if (_n > 0 && !pdflag)				\
-		pdflag = 1;				\
-}
-#else
-#define ADD_PDCOUNT(_n)					\
-{							\
-	ASSERT(&pdcount >= 0);				\
-	atomicAddInt(&pdcount, _n);			\
-	if (_n > 0 && !pdflag)				\
-		pdflag = 1;				\
-}
-#endif /* NUMA_BASE */
 
-#endif /* _ASM_SN_NODEPDA_H */
+#endif /* _ASM_IA64_SN_NODEPDA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pci/bridge.h linux/include/asm-ia64/sn/pci/bridge.h
--- linux.orig/include/asm-ia64/sn/pci/bridge.h	2001-03-07 03:44:34.000000000 +0000
+++ linux/include/asm-ia64/sn/pci/bridge.h	2002-07-20 01:08:28.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_BRIDGE_H
 #define _ASM_SN_PCI_BRIDGE_H
@@ -53,7 +52,7 @@
  *    Bridge address map
  */
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+#ifndef __ASSEMBLY__
 
 #ifdef __cplusplus
 extern "C" {
@@ -373,7 +372,7 @@
 				    ds:2,	/* Data size	  */
 				    gbr:1,	/* GBR enable	  */
 				    vbpm:1,	/* VBPM message	  */
-				    error:1,	/* Error occurred  */
+				    error:1,	/* Error occurred */
 				    barr:1,	/* Barrier op	  */
 				    rsvd:8;
 	} berr_st;
@@ -638,7 +637,7 @@
 
 
 #define berr_field	berr_un.berr_st
-#endif				/* LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 
 /*
  * The values of these macros can and should be crosschecked
@@ -903,10 +902,10 @@
 #define BRIDGE_DEVIO_2MB	0x00200000	/* Device IO Offset (0..1) */
 #define BRIDGE_DEVIO_1MB	0x00100000	/* Device IO Offset (2..7) */
 
-#if	LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define BRIDGE_DEVIO(x)		((x)<=1 ? BRIDGE_DEVIO0+(x)*BRIDGE_DEVIO_2MB : BRIDGE_DEVIO2+((x)-2)*BRIDGE_DEVIO_1MB)
-#endif				/* LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 
 #define BRIDGE_EXTERNAL_FLASH	0x00C00000	/* External Flash PROMS */
 
@@ -971,6 +970,10 @@
 #define BRIDGE_CTRL_CLR_RLLP_CNT	(0x1 << 11)
 #define BRIDGE_CTRL_CLR_TLLP_CNT	(0x1 << 10)
 #define BRIDGE_CTRL_SYS_END		(0x1 << 9)
+#define BRIDGE_CTRL_BUS_SPEED(n)        ((n) << 4)
+#define BRIDGE_CTRL_BUS_SPEED_MASK      (BRIDGE_CTRL_BUS_SPEED(0x3))
+#define BRIDGE_CTRL_BUS_SPEED_33        0x00
+#define BRIDGE_CTRL_BUS_SPEED_66        0x10
 #define BRIDGE_CTRL_MAX_TRANS(n)	((n) << 4)
 #define BRIDGE_CTRL_MAX_TRANS_MASK	(BRIDGE_CTRL_MAX_TRANS(0x1f))
 #define BRIDGE_CTRL_WIDGET_ID(n)	((n) << 0)
@@ -1296,14 +1299,14 @@
 #define PCI32_MAPPED_BASE		BRIDGE_DMA_MAPPED_BASE
 #define PCI32_DIRECT_BASE		BRIDGE_DMA_DIRECT_BASE
 
-#if	LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define IS_PCI32_LOCAL(x)	((uint64_t)(x) < PCI32_MAPPED_BASE)
 #define IS_PCI32_MAPPED(x)	((uint64_t)(x) < PCI32_DIRECT_BASE && \
 					(uint64_t)(x) >= PCI32_MAPPED_BASE)
 #define IS_PCI32_DIRECT(x)	((uint64_t)(x) >= PCI32_MAPPED_BASE)
 #define IS_PCI64(x)		((uint64_t)(x) >= PCI64_BASE)
-#endif				/* LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 
 /*
  * The GIO address space.
@@ -1318,13 +1321,13 @@
 #define GIO_MAPPED_BASE			BRIDGE_DMA_MAPPED_BASE
 #define GIO_DIRECT_BASE			BRIDGE_DMA_DIRECT_BASE
 
-#if	LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define IS_GIO_LOCAL(x)		((uint64_t)(x) < GIO_MAPPED_BASE)
 #define IS_GIO_MAPPED(x)	((uint64_t)(x) < GIO_DIRECT_BASE && \
 					(uint64_t)(x) >= GIO_MAPPED_BASE)
 #define IS_GIO_DIRECT(x)	((uint64_t)(x) >= GIO_MAPPED_BASE)
-#endif				/* LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 
 /* PCI to xtalk mapping */
 
@@ -1347,7 +1350,7 @@
 #define PCI64_ATTR_RMF_MASK	0x00ff000000000000
 #define PCI64_ATTR_RMF_SHFT	48
 
-#if LANGUAGE_C
+#ifndef __ASSEMBLY__
 /* Address translation entry for mapped pci32 accesses */
 typedef union ate_u {
     uint64_t		    ent;
@@ -1375,7 +1378,7 @@
 	uint64_t		valid:1;
     } field;
 } ate_t;
-#endif				/* LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 
 #define ATE_V		(1 << 0)
 #define ATE_CO		(1 << 1)
@@ -1401,7 +1404,7 @@
 #define is_xbridge(bridge) \
         (XWIDGET_PART_NUM(bridge->b_wid_id) == XBRIDGE_WIDGET_PART_NUM)
 
-#if	LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /* ========================================================================
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pci/pci_bus_cvlink.h linux/include/asm-ia64/sn/pci/pci_bus_cvlink.h
--- linux.orig/include/asm-ia64/sn/pci/pci_bus_cvlink.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/pci/pci_bus_cvlink.h	2002-07-20 01:08:34.000000000 +0000
@@ -4,29 +4,61 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_CVLINK_H
 #define _ASM_SN_PCI_CVLINK_H
 
+#include <asm/sn/types.h>
+#include <asm/sn/hack.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/xtalk/xtalkaddrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/io.h>
+
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+
+#define MAX_PCI_XWIDGET 256
+#define MAX_ATE_MAPS 1024
+
 #define SET_PCIA64(dev) \
-	(((struct sn1_device_sysdata *)((dev)->sysdata))->isa64) = 1
+	(((struct sn_device_sysdata *)((dev)->sysdata))->isa64) = 1
 #define IS_PCIA64(dev)	(((dev)->dma_mask == 0xffffffffffffffffUL) || \
-		(((struct sn1_device_sysdata *)((dev)->sysdata))->isa64))
+		(((struct sn_device_sysdata *)((dev)->sysdata))->isa64))
 #define IS_PCI32G(dev)	((dev)->dma_mask >= 0xffffffff)
 #define IS_PCI32L(dev)	((dev)->dma_mask < 0xffffffff)
 
-struct sn1_widget_sysdata {
+#define PCIDEV_VERTEX(pci_dev) \
+	(((struct sn_device_sysdata *)((pci_dev)->sysdata))->vhdl)
+
+#define PCIBUS_VERTEX(pci_bus) \
+	(((struct sn_widget_sysdata *)((pci_bus)->sysdata))->vhdl)
+
+struct sn_widget_sysdata {
         devfs_handle_t  vhdl;
 };
 
-struct sn1_device_sysdata {
+struct sn_device_sysdata {
         devfs_handle_t  vhdl;
 	int		isa64;
+	volatile unsigned int *dma_buf_sync;
+	volatile unsigned int *xbow_buf_sync;
 };
 
-struct sn1_dma_maps_s{
+struct sn_dma_maps_s{
 	struct pcibr_dmamap_s dma_map;
         dma_addr_t      dma_addr;
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pci/pci_defs.h linux/include/asm-ia64/sn/pci/pci_defs.h
--- linux.orig/include/asm-ia64/sn/pci/pci_defs.h	2001-01-04 23:25:55.000000000 +0000
+++ linux/include/asm-ia64/sn/pci/pci_defs.h	2002-07-20 01:08:30.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCI_DEFS_H
 #define _ASM_SN_PCI_PCI_DEFS_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pci/pciba.h linux/include/asm-ia64/sn/pci/pciba.h
--- linux.orig/include/asm-ia64/sn/pci/pciba.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/pci/pciba.h	2002-07-20 01:08:25.000000000 +0000
@@ -1,24 +1,33 @@
-/* $Id$
+/* 
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
+ * Copyright (C) 1997, 2001 Silicon Graphics, Inc. All rights reserved.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
  */
+
 #ifndef _ASM_SN_PCI_PCIBA_H
 #define _ASM_SN_PCI_PCIBA_H
 
-/*
- * These are all the HACKS from ioccom.h ..
- */
-#define IOCPARM_MASK    0xff            /* parameters must be < 256 bytes */
-#define IOC_VOID        0x20000000      /* no parameters */
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+/* for application compatibility with IRIX (why do I bother?) */
+
+#ifndef __KERNEL__
+typedef u_int8_t uint8_t;
+typedef u_int16_t uint16_t;
+typedef u_int32_t uint32_t;
+#endif
+
+#define PCI_CFG_VENDOR_ID	PCI_VENDOR_ID
+#define PCI_CFG_COMMAND		PCI_COMMAND
+#define PCI_CFG_REV_ID		PCI_REVISION_ID
+#define PCI_CFG_HEADER_TYPE	PCI_HEADER_TYPE
+#define PCI_CFG_BASE_ADDR(n)	PCI_BASE_ADDRESS_##n
 
-/*
- * The above needs to be modified and follow LINUX ...
- */
 
 /* /hw/.../pci/[slot]/config accepts ioctls to read
  * and write specific registers as follows:
@@ -69,18 +78,11 @@
 /* PCIIOCGETBASE(n): arg is ptr to a 32-bit int,
  * which will get the value of the BASE<n> register.
  */
+
+/* FIXME chadt: this doesn't tell me whether or not this will work
+   with non-constant 'n.'  */
 #define	PCIIOCGETBASE(n)	PCIIOCCFGRD(uint32_t,PCI_CFG_BASE_ADDR(n))
 
-/* /hw/.../pci/[slot]/intr accepts an ioctl to
- * set up user level interrupt handling as follows:
- *
- * "n" is a bitmap of which of the four PCI interrupt
- * lines are of interest, using PCIIO_INTR_LINE_[ABCD].
- */
-#define	PCIIOCSETULI(n)		_IOWR(1,n,struct uliargs)
-#if _KERNEL
-#define PCIIOCSETULI32(n)	_IOWR(1,n,struct uliargs32)
-#endif
 
 /* /hw/.../pci/[slot]/dma accepts ioctls to allocate
  * and free physical memory for use in user-triggered
@@ -93,11 +95,20 @@
  * both the size of the request and the flag values
  * to be used in setting up the DMA.
  *
+
+FIXME chadt: gonna have to revisit this: what flags would an IRIXer like to
+ have available?
+
  * Any flags normally useful in pciio_dmamap
- * or pciio_dmatrans function calls can6 be used here.
- */
+ * or pciio_dmatrans function calls can6 be used here.  */
 #define	PCIIOCDMAALLOC_REQUEST_PACK(flags,size)		\
 	((((uint64_t)(flags))<<32)|			\
 	 (((uint64_t)(size))&0xFFFFFFFF))
 
+
+#ifdef __KERNEL__
+extern int pciba_init(void);
+#endif
+
+
 #endif	/* _ASM_SN_PCI_PCIBA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pci/pcibr.h linux/include/asm-ia64/sn/pci/pcibr.h
--- linux.orig/include/asm-ia64/sn/pci/pcibr.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/pci/pcibr.h	2002-07-20 01:08:30.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIBR_H
 #define _ASM_SN_PCI_PCIBR_H
@@ -13,7 +12,7 @@
 #if defined(__KERNEL__)
 
 #include <asm/sn/dmamap.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
 #include <asm/sn/pio.h>
 
 #include <asm/sn/pci/pciio.h>
@@ -31,7 +30,7 @@
 #define PCIBR_INTR_BLOCKED		0x40000000
 #define PCIBR_INTR_BUSY			0x80000000
 
-#if LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /* =====================================================================
  *    opaque types used by pcibr's xtalk bus provider
@@ -47,7 +46,7 @@
  *	These functions are normal device driver entry points
  *	and are called along with the similar entry points from
  *	other device drivers. They are included here as documentation
- *	of their existance and purpose.
+ *	of their existence and purpose.
  *
  *	pcibr_init() is called to inform us that there is a pcibr driver
  *	configured into the kernel; it is responsible for registering
@@ -183,10 +182,7 @@
 
 extern void		pcibr_intr_free(pcibr_intr_t intr);
 
-extern int		pcibr_intr_connect(pcibr_intr_t intr,
-					   intr_func_t intr_func,
-					   intr_arg_t intr_arg,
-					   void *thread);
+extern int		pcibr_intr_connect(pcibr_intr_t intr);
 
 extern void		pcibr_intr_disconnect(pcibr_intr_t intr);
 
@@ -349,7 +345,7 @@
 
 extern int		pcibr_asic_rev(devfs_handle_t);
 
-#endif 	/* _LANGUAGE_C */
+#endif 	/* __ASSEMBLY__ */
 #endif	/* #if defined(__KERNEL__) */
 /* 
  * Some useful ioctls into the pcibr driver
@@ -390,10 +386,34 @@
 /*
  * Structures for requesting PCI bridge information and receiving a response
  */
-typedef struct pcibr_slot_info_req_s *pcibr_slot_info_req_t;
+typedef struct pcibr_slot_req_s *pcibr_slot_req_t;
+typedef struct pcibr_slot_up_resp_s *pcibr_slot_up_resp_t;
+typedef struct pcibr_slot_down_resp_s *pcibr_slot_down_resp_t;
 typedef struct pcibr_slot_info_resp_s *pcibr_slot_info_resp_t;
 typedef struct pcibr_slot_func_info_resp_s *pcibr_slot_func_info_resp_t;
 
+#define L1_QSIZE                128      /* our L1 message buffer size */
+struct pcibr_slot_req_s {
+    int                      req_slot;
+    union {
+        pcibr_slot_up_resp_t     up;
+        pcibr_slot_down_resp_t   down;
+        pcibr_slot_info_resp_t   query;
+        void                    *any;
+    }                       req_respp;
+    int                     req_size;
+};
+
+struct pcibr_slot_up_resp_s {
+    int                     resp_sub_errno;
+    char                    resp_l1_msg[L1_QSIZE + 1];
+};
+
+struct pcibr_slot_down_resp_s {
+    int                     resp_sub_errno;
+    char                    resp_l1_msg[L1_QSIZE + 1];
+};
+
 struct pcibr_slot_info_req_s {
    int                      req_slot;
    pcibr_slot_info_resp_t   req_respp;
@@ -454,7 +474,40 @@
         int                     resp_f_att_det_error;
 
     } resp_func[8];
-
 };
 
+
+/*
+ * PCI specific errors, interpreted by pciconfig command
+ */
+
+/* EPERM                          1    */
+#define PCI_SLOT_ALREADY_UP       2     /* slot already up */
+#define PCI_SLOT_ALREADY_DOWN     3     /* slot already down */
+#define PCI_IS_SYS_CRITICAL       4     /* slot is system critical */
+/* EIO                            5    */
+/* ENXIO                          6    */
+#define PCI_L1_ERR                7     /* L1 console command error */
+#define PCI_NOT_A_BRIDGE          8     /* device is not a bridge */
+#define PCI_SLOT_IN_SHOEHORN      9     /* slot is in a shorhorn */
+#define PCI_NOT_A_SLOT           10     /* slot is invalid */
+#define PCI_RESP_AREA_TOO_SMALL  11     /* slot is invalid */
+/* ENOMEM                        12    */
+#define PCI_NO_DRIVER            13     /* no driver for device */
+/* EFAULT                        14    */
+#define PCI_EMPTY_33MHZ          15     /* empty 33 MHz bus */
+/* EBUSY                         16    */
+#define PCI_SLOT_RESET_ERR       17     /* slot reset error */
+#define PCI_SLOT_INFO_INIT_ERR   18     /* slot info init error */
+/* ENODEV                        19    */
+#define PCI_SLOT_ADDR_INIT_ERR   20     /* slot addr space init error */
+#define PCI_SLOT_DEV_INIT_ERR    21     /* slot device init error */
+/* EINVAL                        22    */
+#define PCI_SLOT_GUEST_INIT_ERR  23     /* slot guest info init error */
+#define PCI_SLOT_RRB_ALLOC_ERR   24     /* slot initial rrb alloc error */
+#define PCI_SLOT_DRV_ATTACH_ERR  25     /* driver attach error */
+#define PCI_SLOT_DRV_DETACH_ERR  26     /* driver detach error */
+/* ERANGE                        34    */
+/* EUNATCH                       42    */
+
 #endif				/* _ASM_SN_PCI_PCIBR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pci/pcibr_private.h linux/include/asm-ia64/sn/pci/pcibr_private.h
--- linux.orig/include/asm-ia64/sn/pci/pcibr_private.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/pci/pcibr_private.h	2002-07-20 01:08:21.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIBR_PRIVATE_H
 #define _ASM_SN_PCI_PCIBR_PRIVATE_H
@@ -16,6 +15,7 @@
  * should ever peek into this file.
  */
 
+#include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pciio_private.h>
 #include <asm/sn/ksys/l1.h>
 
@@ -100,9 +100,6 @@
 #define	bi_flags	bi_pi.pi_flags	/* PCIBR_INTR flags */
 #define	bi_dev		bi_pi.pi_dev	/* associated pci card */
 #define	bi_lines	bi_pi.pi_lines	/* which PCI interrupt line(s) */
-#define	bi_func		bi_pi.pi_func	/* handler function (when connected) */
-#define	bi_arg		bi_pi.pi_arg	/* handler parameter (when connected) */
-#define bi_tinfo	bi_pi.pi_tinfo	/* Thread info (when connected) */
 #define bi_mustruncpu	bi_pi.pi_mustruncpu /* Where we must run. */
 #define bi_irq		bi_pi.pi_irq	/* IRQ assigned. */
 #define bi_cpu		bi_pi.pi_cpu	/* cpu assigned. */
@@ -173,14 +170,17 @@
  */
 
 struct pcibr_soft_s {
-    devfs_handle_t            bs_conn;	/* xtalk connection point */
-    devfs_handle_t            bs_vhdl;	/* vertex owned by pcibr */
+    devfs_handle_t          bs_conn;		/* xtalk connection point */
+    devfs_handle_t          bs_vhdl;		/* vertex owned by pcibr */
     int                     bs_int_enable;	/* Mask of enabled intrs */
-    bridge_t               *bs_base;	/* PIO pointer to Bridge chip */
-    char                   *bs_name;	/* hw graph name */
-    xwidgetnum_t            bs_xid;	/* Bridge's xtalk ID number */
-    devfs_handle_t            bs_master;	/* xtalk master vertex */
-    xwidgetnum_t            bs_mxid;	/* master's xtalk ID number */
+    bridge_t               *bs_base;		/* PIO pointer to Bridge chip */
+    char                   *bs_name;		/* hw graph name */
+    xwidgetnum_t            bs_xid;		/* Bridge's xtalk ID number */
+    devfs_handle_t          bs_master;		/* xtalk master vertex */
+    xwidgetnum_t            bs_mxid;		/* master's xtalk ID number */
+    pciio_slot_t            bs_first_slot;      /* first existing slot */
+    pciio_slot_t            bs_last_slot;       /* last existing slot */
+
 
     iopaddr_t               bs_dir_xbase;	/* xtalk address for 32-bit PCI direct map */
     xwidgetnum_t	    bs_dir_xport;	/* xtalk port for 32-bit PCI direct map */
@@ -190,7 +190,7 @@
     short		    bs_int_ate_size;	/* number of internal ates */
     short		    bs_xbridge;		/* if 1 then xbridge */
 
-    int                     bs_rev_num;	/* revision number of Bridge */
+    int                     bs_rev_num;		/* revision number of Bridge */
 
     unsigned                bs_dma_flags;	/* revision-implied DMA flags */
 
@@ -253,6 +253,7 @@
 	struct {
 	    pciio_space_t           bssd_space;
 	    iopaddr_t               bssd_base;
+            int                     bssd_ref_cnt;
 	} bss_devio;
 
 	/* Shadow value for Device(x) register,
@@ -312,7 +313,9 @@
     int                     bs_rrb_fixed;
     int			    bs_rrb_avail[2];
     int			    bs_rrb_res[8];
-    int			    bs_rrb_valid[16];
+    int                     bs_rrb_res_dflt[8];
+    int                     bs_rrb_valid[16];
+    int                     bs_rrb_valid_dflt[16];
 
     struct {
 	/* Each Bridge interrupt bit has a single XIO
@@ -434,4 +437,41 @@
 #define pcibr_soft_get(v)       ((pcibr_soft_t)hwgraph_fastinfo_get((v)))
 #define pcibr_soft_set(v,i)     (hwgraph_fastinfo_set((v), (arbitrary_info_t)(i)))
 
+/* Use io spin locks. This ensures that all the PIO writes from a particular
+ * CPU to a particular IO device are synched before the start of the next
+ * set of PIO operations to the same device.
+ */
+#define pcibr_lock(pcibr_soft)		io_splock(&pcibr_soft->bs_lock)
+#define pcibr_unlock(pcibr_soft,s)	io_spunlock(&pcibr_soft->bs_lock,s)
+
+/*
+ * mem alloc/free macros
+ */
+#define NEWAf(ptr,n,f)	(ptr = snia_kmem_zalloc((n)*sizeof (*(ptr)), (f&PCIIO_NOSLEEP)?KM_NOSLEEP:KM_SLEEP))
+#define NEWA(ptr,n)	(ptr = snia_kmem_zalloc((n)*sizeof (*(ptr)), KM_SLEEP))
+#define DELA(ptr,n)	(kfree(ptr))
+
+#define NEWf(ptr,f)	NEWAf(ptr,1,f)
+#define NEW(ptr)	NEWA(ptr,1)
+#define DEL(ptr)	DELA(ptr,1)
+
+typedef volatile unsigned *cfg_p;
+typedef volatile bridgereg_t *reg_p;
+
+#define PCIBR_RRB_SLOT_VIRTUAL  8
+#define PCIBR_VALID_SLOT(s)     (s < 8)
+#define PCIBR_D64_BASE_UNSET    (0xFFFFFFFFFFFFFFFF)
+#define PCIBR_D32_BASE_UNSET    (0xFFFFFFFF)
+#define INFO_LBL_PCIBR_ASIC_REV "_pcibr_asic_rev"
+
+#define PCIBR_SOFT_LIST 1
+#if PCIBR_SOFT_LIST
+typedef struct pcibr_list_s *pcibr_list_p;
+struct pcibr_list_s {
+	pcibr_list_p            bl_next;
+	pcibr_soft_t            bl_soft;
+	devfs_handle_t          bl_vhdl;
+};
+#endif /* PCIBR_SOFT_LIST */
+
 #endif				/* _ASM_SN_PCI_PCIBR_PRIVATE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pci/pciio.h linux/include/asm-ia64/sn/pci/pciio.h
--- linux.orig/include/asm-ia64/sn/pci/pciio.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/pci/pciio.h	2002-07-20 01:08:22.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIIO_H
 #define _ASM_SN_PCI_PCIIO_H
@@ -15,25 +14,22 @@
  */
 
 #include <asm/sn/ioerror.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/hcl.h>
 
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+#ifndef __ASSEMBLY__
 
 #include <asm/sn/dmamap.h>
 #include <asm/sn/alenlist.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 typedef int pciio_vendor_id_t;
 
-#define PCIIO_VENDOR_ID_NONE	-1
+#define PCIIO_VENDOR_ID_NONE	(-1)
 
 typedef int pciio_device_id_t;
 
-#define PCIIO_DEVICE_ID_NONE	-1
+#define PCIIO_DEVICE_ID_NONE	(-1)
 
 typedef uint8_t pciio_bus_t;       /* PCI bus number (0..255) */
 typedef uint8_t pciio_slot_t;      /* PCI slot number (0..31, 255) */
@@ -387,10 +383,7 @@
 pciio_intr_free_f       (pciio_intr_t intr_hdl);
 
 typedef int
-pciio_intr_connect_f    (pciio_intr_t intr_hdl,		/* pciio intr resource handle */
-			 intr_func_t intr_func,		/* pciio intr handler */
-			 intr_arg_t intr_arg,	/* arg to intr handler */
-			 void *thread);	/* intr thread to use */
+pciio_intr_connect_f    (pciio_intr_t intr_hdl);	/* pciio intr resource handle */
 
 typedef void
 pciio_intr_disconnect_f (pciio_intr_t intr_hdl);
@@ -729,8 +722,5 @@
 extern int              pciio_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
 extern int		pciio_dma_enabled(devfs_handle_t);
 
-#ifdef __cplusplus
-};
-#endif
 #endif				/* C or C++ */
 #endif				/* _ASM_SN_PCI_PCIIO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pci/pciio_private.h linux/include/asm-ia64/sn/pci/pciio_private.h
--- linux.orig/include/asm-ia64/sn/pci/pciio_private.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/pci/pciio_private.h	2002-07-20 01:08:22.000000000 +0000
@@ -4,12 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIIO_PRIVATE_H
 #define _ASM_SN_PCI_PCIIO_PRIVATE_H
 
+#include <asm/sn/pci/pciio.h>
+
 /*
  * pciio_private.h -- private definitions for pciio
  * PCI drivers should NOT include this file.
@@ -48,11 +49,6 @@
     devfs_handle_t            pi_dev;	/* associated pci card */
     device_desc_t	    pi_dev_desc;	/* override device descriptor */
     pciio_intr_line_t       pi_lines;	/* which interrupt line(s) */
-    intr_func_t             pi_func;	/* handler function (when connected) */
-    intr_arg_t              pi_arg;	/* handler parameter (when connected) */
-#ifdef LATER
-    thd_int_t               pi_tinfo;	/* Thread info (when connected) */
-#endif
     cpuid_t                 pi_mustruncpu; /* Where we must run. */
     int                     pi_irq;     /* IRQ assigned */
     int                     pi_cpu;     /* cpu assigned */
@@ -84,6 +80,8 @@
 	pciio_space_t		w_space;
 	iopaddr_t		w_base;
 	size_t			w_size;
+        int                     w_devio_index;  /* DevIO[] register used to
+                                                   access this window */
     }			    c_window[6];
 
     unsigned		    c_rbase;	/* EXPANSION ROM base addr */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pda.h linux/include/asm-ia64/sn/pda.h
--- linux.orig/include/asm-ia64/sn/pda.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/pda.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,84 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_PDA_H
+#define _ASM_IA64_SN_PDA_H
+
+#include <linux/config.h>
+#include <linux/cache.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/sn/bte.h>
+
+
+/*
+ * CPU-specific data structure.
+ *
+ * One of these structures is allocated for each cpu of a NUMA system.
+ *
+ * This structure provides a convenient way of keeping together 
+ * all SN per-cpu data structures. 
+ */
+
+
+
+typedef struct pda_s {
+
+	/* Having a pointer in the begining of PDA tends to increase
+	 * the chance of having this pointer in cache. (Yes something
+	 * else gets pushed out). Doing this reduces the number of memory
+	 * access to all nodepda variables to be one
+	 */
+	struct nodepda_s *p_nodepda;		/* Pointer to Per node PDA */
+	struct subnodepda_s *p_subnodepda;	/* Pointer to CPU  subnode PDA */
+
+	/*
+	 * Support for SN LEDs
+	 */
+#ifdef CONFIG_IA64_SGI_SN1
+	volatile long	*led_address;
+#else
+	volatile short	*led_address;
+#endif
+	u8		led_state;
+	u8		hb_state;	/* supports blinking heartbeat leds */
+	unsigned int	hb_count;
+
+	unsigned int	idle_flag;
+	
+#ifdef CONFIG_IA64_SGI_SN2
+	struct irqpda_s *p_irqpda;			/* Pointer to CPU irq data */
+#endif
+	volatile unsigned long *bedrock_rev_id;
+	volatile unsigned long *pio_write_status_addr;
+
+	bteinfo_t *cpubte[BTES_PER_NODE];
+} pda_t;
+
+
+#define CACHE_ALIGN(x)	(((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
+
+/*
+ * PDA
+ * Per-cpu private data area for each cpu. The PDA is located immediately after
+ * the IA64 cpu_data area. A full page is allocated for the cp_data area for each
+ * cpu but only a small amout of the page is actually used. We put the SNIA PDA
+ * in the same page as the cpu_data area. Note that there is a check in the setup
+ * code to verify that we dont overflow the page.
+ *
+ * Seems like we should should cache-line align the pda so that any changes in the
+ * size of the cpu_data area dont change cache layout. Should we align to 32, 64, 128
+ * or 512 boundary. Each has merits. For now, pick 128 but should be revisited later.
+ */
+#define CPU_DATA_END	CACHE_ALIGN((long)&(((struct cpuinfo_ia64*)0)->platform_specific))
+#define PDAADDR		(PERCPU_ADDR+CPU_DATA_END)
+
+#define pda		(*((pda_t *) PDAADDR))
+
+
+#endif /* _ASM_IA64_SN_PDA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/pio.h linux/include/asm-ia64/sn/pio.h
--- linux.orig/include/asm-ia64/sn/pio.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/pio.h	2002-07-20 01:08:25.000000000 +0000
@@ -4,15 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_PIO_H
-#define _ASM_SN_PIO_H
+#ifndef _ASM_IA64_SN_PIO_H
+#define _ASM_IA64_SN_PIO_H
 
 #include <linux/types.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
 
 /*
  * pioaddr_t	- The kernel virtual address that a PIO can be done upon.
@@ -143,7 +142,7 @@
 #define LAN_RAM         2
 #define LAN_IO          3
 
-#define PIOREG_NULL	-1
+#define PIOREG_NULL	(-1)
 
 /* standard flags values for pio_map routines,
  * including {xtalk,pciio}_piomap calls.
@@ -156,4 +155,4 @@
 
 #define	PIOMAP_FLAGS	0x7
 
-#endif	/* _ASM_SN_PIO_H */
+#endif	/* _ASM_IA64_SN_PIO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/prio.h linux/include/asm-ia64/sn/prio.h
--- linux.orig/include/asm-ia64/sn/prio.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/prio.h	2002-07-20 01:08:36.000000000 +0000
@@ -4,11 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_PRIO_H
-#define _ASM_SN_PRIO_H
+#ifndef _ASM_IA64_SN_PRIO_H
+#define _ASM_IA64_SN_PRIO_H
+
+#include <linux/types.h>
 
 /*
  * Priority I/O function prototypes and macro definitions
@@ -33,6 +34,6 @@
 
 /* Error returns */
 #define PRIO_SUCCESS     0
-#define PRIO_FAIL       -1 
+#define PRIO_FAIL       (-1) 
 
-#endif /* _ASM_SN_PRIO_H */
+#endif /* _ASM_IA64_SN_PRIO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/router.h linux/include/asm-ia64/sn/router.h
--- linux.orig/include/asm-ia64/sn/router.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/router.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,19 +1,665 @@
+
 /* $Id$
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_ROUTER_H
+#define _ASM_IA64_SN_ROUTER_H
+
+/*
+ * Router Register definitions
+ *
+ * Macro argument _L always stands for a link number (1 to 8, inclusive).
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/vector.h>
+#include <asm/sn/slotnum.h>
+#include <asm/sn/arch.h>
+
+typedef uint64_t	router_reg_t;
+
+#define MAX_ROUTERS	64
+
+#define MAX_ROUTER_PATH	80
+
+#define ROUTER_REG_CAST		(volatile router_reg_t *)
+#define PS_UINT_CAST		(__psunsigned_t)
+#define UINT64_CAST		(uint64_t)
+typedef signed char port_no_t;	 /* Type for router port number      */
+
+#else 
+
+#define ROUTERREG_CAST
+#define PS_UINT_CAST
+#define UINT64_CAST
+
+#endif /* __ASSEMBLY__ */
+
+#define MAX_ROUTER_PORTS (8)	 /* Max. number of ports on a router */
+
+#define ALL_PORTS ((1 << MAX_ROUTER_PORTS) - 1)	/* for 0 based references */
+
+#define PORT_INVALID (-1)	 /* Invalid port number              */
+
+#define	IS_META(_rp)	((_rp)->flags & PCFG_ROUTER_META)
+
+#define	IS_REPEATER(_rp)((_rp)->flags & PCFG_ROUTER_REPEATER)
+
+/*
+ * RR_TURN makes a given number of clockwise turns (0 to 7) from an inport
+ * port to generate an output port.
+ *
+ * RR_DISTANCE returns the number of turns necessary (0 to 7) to go from
+ * an input port (_L1 = 1 to 8) to an output port ( _L2 = 1 to 8).
+ *
+ * These are written to work on unsigned data.
  */
-#ifndef _ASM_SN_ROUTER_H
-#define _ASM_SN_ROUTER_H
 
-#include <linux/config.h>
+#define RR_TURN(_L, count)	((_L) + (count) > MAX_ROUTER_PORTS ?	\
+				 (_L) + (count) - MAX_ROUTER_PORTS :	\
+				 (_L) + (count))
+
+#define RR_DISTANCE(_LS, _LD)	((_LD) >= (_LS) ?			\
+				 (_LD) - (_LS) :			\
+				 (_LD) + MAX_ROUTER_PORTS - (_LS))
+
+/* Router register addresses */
+
+#define RR_STATUS_REV_ID	0x00000	/* Status register and Revision ID  */
+#define RR_PORT_RESET		0x00008	/* Multiple port reset              */
+#define RR_PROT_CONF		0x00010	/* Inter-partition protection conf. */
+#define RR_GLOBAL_PORT_DEF	0x00018 /* Global Port definitions          */
+#define RR_GLOBAL_PARMS0	0x00020	/* Parameters shared by all 8 ports */
+#define RR_GLOBAL_PARMS1	0x00028	/* Parameters shared by all 8 ports */
+#define RR_DIAG_PARMS		0x00030	/* Parameters for diag. testing     */
+#define RR_DEBUG_ADDR		0x00038 /* Debug address select - debug port*/
+#define RR_LB_TO_L2		0x00040 /* Local Block to L2 cntrl intf reg */ 
+#define RR_L2_TO_LB		0x00048 /* L2 cntrl intf to Local Block reg */
+#define RR_JBUS_CONTROL		0x00050 /* read/write timing for JBUS intf  */
+
+#define RR_SCRATCH_REG0		0x00100	/* Scratch 0 is 64 bits */
+#define RR_SCRATCH_REG1		0x00108	/* Scratch 1 is 64 bits */
+#define RR_SCRATCH_REG2		0x00110	/* Scratch 2 is 64 bits */
+#define RR_SCRATCH_REG3		0x00118	/* Scratch 3 is 1 bit */
+#define RR_SCRATCH_REG4		0x00120	/* Scratch 4 is 1 bit */
+
+#define RR_JBUS0(_D)		(((_D) & 0x7) << 3 | 0x00200) /* JBUS0 addresses   */
+#define RR_JBUS1(_D)		(((_D) & 0x7) << 3 | 0x00240) /* JBUS1 addresses   */
+
+#define RR_SCRATCH_REG0_WZ	0x00500	/* Scratch 0 is 64 bits */
+#define RR_SCRATCH_REG1_WZ	0x00508	/* Scratch 1 is 64 bits */
+#define RR_SCRATCH_REG2_WZ	0x00510	/* Scratch 2 is 64 bits */
+#define RR_SCRATCH_REG3_SZ	0x00518	/* Scratch 3 is 1 bit */
+#define RR_SCRATCH_REG4_SZ	0x00520	/* Scratch 4 is 1 bit */
+
+#define RR_VECTOR_HW_BAR(context) (0x08000 | (context)<<3) /* barrier config registers */
+/* Port-specific registers (_L is the link number from 1 to 8) */
+
+#define RR_PORT_PARMS(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0000) /* LLP parameters     */
+#define RR_STATUS_ERROR(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0008) /* Port-related errs  */
+#define RR_CHANNEL_TEST(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0010) /* Port LLP chan test */
+#define RR_RESET_MASK(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0018) /* Remote reset mask  */
+#define RR_HISTOGRAM0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0020) /* Port usage histgrm */
+#define RR_HISTOGRAM1(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0028) /* Port usage histgrm */
+#define RR_HISTOGRAM0_WC(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0030) /* Port usage histgrm */
+#define RR_HISTOGRAM1_WC(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0038) /* Port usage histgrm */
+#define RR_ERROR_CLEAR(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0088) /* Read/clear errors  */
+#define RR_GLOBAL_TABLE0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0100) /* starting address of global table for this port */
+#define RR_GLOBAL_TABLE(_L, _x) (RR_GLOBAL_TABLE0(_L) + ((_x) << 3))
+#define RR_LOCAL_TABLE0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0200) /* starting address of local table for this port */
+#define RR_LOCAL_TABLE(_L, _x) (RR_LOCAL_TABLE0(_L) + ((_x) << 3))
+
+#define RR_META_ENTRIES		16
+
+#define RR_LOCAL_ENTRIES	128
+
+/*
+ * RR_STATUS_REV_ID mask and shift definitions
+ */
+
+#define RSRI_INPORT_SHFT	52
+#define RSRI_INPORT_MASK	(UINT64_CAST 0xf << 52)
+#define RSRI_LINKWORKING_BIT(_L) (35 + 2 * (_L))
+#define RSRI_LINKWORKING(_L)	(UINT64_CAST 1 << (35 + 2 * (_L)))
+#define RSRI_LINKRESETFAIL(_L)	(UINT64_CAST 1 << (34 + 2 * (_L)))
+#define RSRI_LSTAT_SHFT(_L)	(34 + 2 * (_L))
+#define RSRI_LSTAT_MASK(_L)	(UINT64_CAST 0x3 << 34 + 2 * (_L))
+#define RSRI_LOCALSBERROR	(UINT64_CAST 1 << 35)
+#define RSRI_LOCALSTUCK		(UINT64_CAST 1 << 34)
+#define RSRI_LOCALBADVEC	(UINT64_CAST 1 << 33)
+#define RSRI_LOCALTAILERR	(UINT64_CAST 1 << 32)
+#define RSRI_LOCAL_SHFT 	32
+#define RSRI_LOCAL_MASK		(UINT64_CAST 0xf << 32)
+#define RSRI_CHIPREV_SHFT	28
+#define RSRI_CHIPREV_MASK	(UINT64_CAST 0xf << 28)
+#define RSRI_CHIPID_SHFT	12
+#define RSRI_CHIPID_MASK	(UINT64_CAST 0xffff << 12)
+#define RSRI_MFGID_SHFT		1
+#define RSRI_MFGID_MASK		(UINT64_CAST 0x7ff << 1)
+
+#define RSRI_LSTAT_WENTDOWN	0
+#define RSRI_LSTAT_RESETFAIL	1
+#define RSRI_LSTAT_LINKUP	2
+#define RSRI_LSTAT_NOTUSED	3
+
+/*
+ * RR_PORT_RESET mask definitions
+ */
+
+#define RPRESET_WARM		(UINT64_CAST 1 << 9)
+#define RPRESET_LINK(_L)	(UINT64_CAST 1 << (_L))
+#define RPRESET_LOCAL		(UINT64_CAST 1)
+
+/*
+ * RR_PROT_CONF mask and shift definitions
+ */
+
+#define RPCONF_DIRCMPDIS_SHFT	13
+#define RPCONF_DIRCMPDIS_MASK	(UINT64_CAST 1 << 13)
+#define RPCONF_FORCELOCAL	(UINT64_CAST 1 << 12)
+#define RPCONF_FLOCAL_SHFT	12
+#define RPCONF_METAID_SHFT	8
+#define RPCONF_METAID_MASK	(UINT64_CAST 0xf << 8)
+#define RPCONF_RESETOK(_L)	(UINT64_CAST 1 << ((_L) - 1))
+
+/*
+ * RR_GLOBAL_PORT_DEF mask and shift definitions
+ */
+
+#define RGPD_MGLBLNHBR_ID_SHFT	12	/* -global neighbor ID */
+#define RGPD_MGLBLNHBR_ID_MASK	(UINT64_CAST 0xf << 12)
+#define RGPD_MGLBLNHBR_VLD_SHFT	11	/* -global neighbor Valid */
+#define RGPD_MGLBLNHBR_VLD_MASK	(UINT64_CAST 0x1 << 11)
+#define RGPD_MGLBLPORT_SHFT	8	/* -global neighbor Port */
+#define RGPD_MGLBLPORT_MASK	(UINT64_CAST 0x7 << 8)
+#define RGPD_PGLBLNHBR_ID_SHFT	4	/* +global neighbor ID */
+#define RGPD_PGLBLNHBR_ID_MASK	(UINT64_CAST 0xf << 4)
+#define RGPD_PGLBLNHBR_VLD_SHFT	3	/* +global neighbor Valid */
+#define RGPD_PGLBLNHBR_VLD_MASK	(UINT64_CAST 0x1 << 3)
+#define RGPD_PGLBLPORT_SHFT	0	/* +global neighbor Port */
+#define RGPD_PGLBLPORT_MASK	(UINT64_CAST 0x7 << 0)
+
+#define GLBL_PARMS_REGS		2	/* Two Global Parms registers */
+
+/*
+ * RR_GLOBAL_PARMS0 mask and shift definitions
+ */
+
+#define RGPARM0_ARB_VALUE_SHFT	54	/* Local Block Arbitration State */
+#define RGPARM0_ARB_VALUE_MASK	(UINT64_CAST 0x7 << 54)
+#define RGPARM0_ROTATEARB_SHFT	53	/* Rotate Local Block Arbitration */
+#define RGPARM0_ROTATEARB_MASK	(UINT64_CAST 0x1 << 53)
+#define RGPARM0_FAIREN_SHFT	52	/* Fairness logic Enable */
+#define RGPARM0_FAIREN_MASK	(UINT64_CAST 0x1 << 52)
+#define RGPARM0_LOCGNTTO_SHFT	40	/* Local grant timeout */
+#define RGPARM0_LOCGNTTO_MASK	(UINT64_CAST 0xfff << 40)
+#define RGPARM0_DATELINE_SHFT	38	/* Dateline crossing router */
+#define RGPARM0_DATELINE_MASK	(UINT64_CAST 0x1 << 38)
+#define RGPARM0_MAXRETRY_SHFT	28	/* Max retry count */
+#define RGPARM0_MAXRETRY_MASK	(UINT64_CAST 0x3ff << 28)
+#define RGPARM0_URGWRAP_SHFT	20	/* Urgent wrap */
+#define RGPARM0_URGWRAP_MASK	(UINT64_CAST 0xff << 20)
+#define RGPARM0_DEADLKTO_SHFT	16	/* Deadlock timeout */
+#define RGPARM0_DEADLKTO_MASK	(UINT64_CAST 0xf << 16)
+#define RGPARM0_URGVAL_SHFT	12	/* Urgent value */
+#define RGPARM0_URGVAL_MASK	(UINT64_CAST 0xf << 12)
+#define RGPARM0_VCHSELEN_SHFT	11	/* VCH_SEL_EN */
+#define RGPARM0_VCHSELEN_MASK	(UINT64_CAST 0x1 << 11)
+#define RGPARM0_LOCURGTO_SHFT	9	/* Local urgent timeout */
+#define RGPARM0_LOCURGTO_MASK	(UINT64_CAST 0x3 << 9)
+#define RGPARM0_TAILVAL_SHFT	5	/* Tail value */
+#define RGPARM0_TAILVAL_MASK	(UINT64_CAST 0xf << 5)
+#define RGPARM0_CLOCK_SHFT	1	/* Global clock select */
+#define RGPARM0_CLOCK_MASK	(UINT64_CAST 0xf << 1)
+#define RGPARM0_BYPEN_SHFT	0
+#define RGPARM0_BYPEN_MASK	(UINT64_CAST 1)	/* Bypass enable */
+
+/*
+ * RR_GLOBAL_PARMS1 shift and mask definitions
+ */
+
+#define RGPARM1_TTOWRAP_SHFT	12	/* Tail timeout wrap */
+#define RGPARM1_TTOWRAP_MASK	(UINT64_CAST 0xfffff << 12)
+#define RGPARM1_AGERATE_SHFT	8	/* Age rate */
+#define RGPARM1_AGERATE_MASK	(UINT64_CAST 0xf << 8)
+#define RGPARM1_JSWSTAT_SHFT	0	/* JTAG Sw Register bits */
+#define RGPARM1_JSWSTAT_MASK	(UINT64_CAST 0xff << 0)
+
+/*
+ * RR_DIAG_PARMS mask and shift definitions
+ */
+
+#define RDPARM_ABSHISTOGRAM	(UINT64_CAST 1 << 17)	/* Absolute histgrm */
+#define RDPARM_DEADLOCKRESET	(UINT64_CAST 1 << 16)	/* Reset on deadlck */
+#define RDPARM_DISABLE(_L)	(UINT64_CAST 1 << ((_L) +  7))
+#define RDPARM_SENDERROR(_L)	(UINT64_CAST 1 << ((_L) -  1))
+
+/*
+ * RR_DEBUG_ADDR mask and shift definitions
+ */
+
+#define RDA_DATA_SHFT		10	/* Observed debug data */
+#define RDA_DATA_MASK		(UINT64_CAST 0xffff << 10)
+#define RDA_ADDR_SHFT		0	/* debug address for data */
+#define RDA_ADDR_MASK		(UINT64_CAST 0x3ff << 0)
+
+/*
+ * RR_LB_TO_L2 mask and shift definitions
+ */
+
+#define RLBTOL2_DATA_VLD_SHFT	32	/* data is valid for JTAG controller */
+#define RLBTOL2_DATA_VLD_MASK	(UINT64_CAST 0x1 << 32)
+#define RLBTOL2_DATA_SHFT	0	/* data bits for JTAG controller */
+#define RLBTOL2_DATA_MASK	(UINT64_CAST 0xffffffff)
+
+/*
+ * RR_L2_TO_LB mask and shift definitions
+ */
+
+#define RL2TOLB_DATA_VLD_SHFT	33	/* data is valid from JTAG controller */
+#define RL2TOLB_DATA_VLD_MASK	(UINT64_CAST 0x1 << 33)
+#define RL2TOLB_PARITY_SHFT	32	/* sw implemented parity for data */
+#define RL2TOLB_PARITY_MASK	(UINT64_CAST 0x1 << 32)
+#define RL2TOLB_DATA_SHFT	0	/* data bits from JTAG controller */
+#define RL2TOLB_DATA_MASK	(UINT64_CAST 0xffffffff)
+
+/*
+ * RR_JBUS_CONTROL mask and shift definitions
+ */
 
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
-#include <asm/sn/sn1/router.h>
+#define RJC_POS_BITS_SHFT	20	/* Router position bits */
+#define RJC_POS_BITS_MASK	(UINT64_CAST 0xf << 20)
+#define RJC_RD_DATA_STROBE_SHFT	16	/* count when read data is strobed in */
+#define RJC_RD_DATA_STROBE_MASK	(UINT64_CAST 0xf << 16)
+#define RJC_WE_OE_HOLD_SHFT	8	/* time OE or WE is held */
+#define RJC_WE_OE_HOLD_MASK	(UINT64_CAST 0xff << 8)
+#define RJC_ADDR_SET_HLD_SHFT	0	/* time address driven around OE/WE */
+#define RJC_ADDR_SET_HLD_MASK	(UINT64_CAST 0xff)
+
+/*
+ * RR_SCRATCH_REGx mask and shift definitions
+ *  note: these fields represent a software convention, and are not
+ *        understood/interpreted by the hardware. 
+ */
+
+#define	RSCR0_BOOTED_SHFT	63
+#define	RSCR0_BOOTED_MASK	(UINT64_CAST 0x1 << RSCR0_BOOTED_SHFT)
+#define RSCR0_LOCALID_SHFT	56
+#define RSCR0_LOCALID_MASK	(UINT64_CAST 0x7f << RSCR0_LOCALID_SHFT)
+#define	RSCR0_UNUSED_SHFT	48
+#define	RSCR0_UNUSED_MASK	(UINT64_CAST 0xff << RSCR0_UNUSED_SHFT)
+#define RSCR0_NIC_SHFT		0
+#define RSCR0_NIC_MASK		(UINT64_CAST 0xffffffffffff)
+
+#define RSCR1_MODID_SHFT	0
+#define RSCR1_MODID_MASK	(UINT64_CAST 0xffff)
+
+/*
+ * RR_VECTOR_HW_BAR mask and shift definitions
+ */
+
+#define BAR_TX_SHFT		27	/* Barrier in trans(m)it when read */
+#define BAR_TX_MASK		(UINT64_CAST 1 << BAR_TX_SHFT)
+#define BAR_VLD_SHFT		26	/* Valid Configuration */
+#define BAR_VLD_MASK		(UINT64_CAST 1 << BAR_VLD_SHFT)
+#define BAR_SEQ_SHFT		24	/* Sequence number */
+#define BAR_SEQ_MASK		(UINT64_CAST 3 << BAR_SEQ_SHFT)
+#define BAR_LEAFSTATE_SHFT	18	/* Leaf State */
+#define BAR_LEAFSTATE_MASK	(UINT64_CAST 0x3f << BAR_LEAFSTATE_SHFT)
+#define BAR_PARENT_SHFT		14	/* Parent Port */
+#define BAR_PARENT_MASK		(UINT64_CAST 0xf << BAR_PARENT_SHFT)
+#define BAR_CHILDREN_SHFT	6	/* Child Select port bits */
+#define BAR_CHILDREN_MASK	(UINT64_CAST 0xff << BAR_CHILDREN_SHFT)
+#define BAR_LEAFCOUNT_SHFT	0	/* Leaf Count to trigger parent */
+#define BAR_LEAFCOUNT_MASK	(UINT64_CAST 0x3f)
+
+/*
+ * RR_PORT_PARMS(_L) mask and shift definitions
+ */
+
+#define RPPARM_MIPRESETEN_SHFT	29	/* Message In Progress reset enable */
+#define RPPARM_MIPRESETEN_MASK	(UINT64_CAST 0x1 << 29)
+#define RPPARM_UBAREN_SHFT	28	/* Enable user barrier requests */
+#define RPPARM_UBAREN_MASK	(UINT64_CAST 0x1 << 28)
+#define RPPARM_OUTPDTO_SHFT	24	/* Output Port Deadlock TO value */
+#define RPPARM_OUTPDTO_MASK	(UINT64_CAST 0xf << 24)
+#define RPPARM_PORTMATE_SHFT	21	/* Port Mate for the port */
+#define RPPARM_PORTMATE_MASK	(UINT64_CAST 0x7 << 21)
+#define RPPARM_HISTEN_SHFT	20	/* Histogram counter enable */
+#define RPPARM_HISTEN_MASK	(UINT64_CAST 0x1 << 20)
+#define RPPARM_HISTSEL_SHFT	18
+#define RPPARM_HISTSEL_MASK	(UINT64_CAST 0x3 << 18)
+#define RPPARM_DAMQHS_SHFT	16
+#define RPPARM_DAMQHS_MASK	(UINT64_CAST 0x3 << 16)
+#define RPPARM_NULLTO_SHFT	10
+#define RPPARM_NULLTO_MASK	(UINT64_CAST 0x3f << 10)
+#define RPPARM_MAXBURST_SHFT	0
+#define RPPARM_MAXBURST_MASK	(UINT64_CAST 0x3ff)
+
+/*
+ * NOTE: Normally the kernel tracks only UTILIZATION statistics.
+ * The other 2 should not be used, except during any experimentation
+ * with the router.
+ */
+#define RPPARM_HISTSEL_AGE	0	/* Histogram age characterization.  */
+#define RPPARM_HISTSEL_UTIL	1	/* Histogram link utilization 	    */
+#define RPPARM_HISTSEL_DAMQ	2	/* Histogram DAMQ characterization. */
+
+/*
+ * RR_STATUS_ERROR(_L) and RR_ERROR_CLEAR(_L) mask and shift definitions
+ */
+#define RSERR_POWERNOK		(UINT64_CAST 1 << 38)
+#define RSERR_PORT_DEADLOCK     (UINT64_CAST 1 << 37)
+#define RSERR_WARMRESET         (UINT64_CAST 1 << 36)
+#define RSERR_LINKRESET         (UINT64_CAST 1 << 35)
+#define RSERR_RETRYTIMEOUT      (UINT64_CAST 1 << 34)
+#define RSERR_FIFOOVERFLOW	(UINT64_CAST 1 << 33)
+#define RSERR_ILLEGALPORT	(UINT64_CAST 1 << 32)
+#define RSERR_DEADLOCKTO_SHFT	28
+#define RSERR_DEADLOCKTO_MASK	(UINT64_CAST 0xf << 28)
+#define RSERR_RECVTAILTO_SHFT	24
+#define RSERR_RECVTAILTO_MASK	(UINT64_CAST 0xf << 24)
+#define RSERR_RETRYCNT_SHFT	16
+#define RSERR_RETRYCNT_MASK	(UINT64_CAST 0xff << 16)
+#define RSERR_CBERRCNT_SHFT	8
+#define RSERR_CBERRCNT_MASK	(UINT64_CAST 0xff << 8)
+#define RSERR_SNERRCNT_SHFT	0
+#define RSERR_SNERRCNT_MASK	(UINT64_CAST 0xff << 0)
+
+
+#define PORT_STATUS_UP		(1 << 0)	/* Router link up */
+#define PORT_STATUS_FENCE	(1 << 1)	/* Router link fenced */
+#define PORT_STATUS_RESETFAIL	(1 << 2)	/* Router link didnot 
+						 * come out of reset */
+#define PORT_STATUS_DISCFAIL	(1 << 3)	/* Router link failed after 
+						 * out of reset but before
+						 * router tables were
+						 * programmed
+						 */
+#define PORT_STATUS_KERNFAIL	(1 << 4)	/* Router link failed
+						 * after reset and the 
+						 * router tables were
+						 * programmed
+						 */
+#define PORT_STATUS_UNDEF	(1 << 5)	/* Unable to pinpoint
+						 * why the router link
+						 * went down
+						 */	
+#define PROBE_RESULT_BAD	(-1)		/* Set if any of the router
+						 * links failed after reset
+						 */
+#define PROBE_RESULT_GOOD	(0)		/* Set if all the router links
+						 * which came out of reset 
+						 * are up
+						 */
+
+/* Should be enough for 256 CPUs */
+#define MAX_RTR_BREADTH		64		/* Max # of routers possible */
+
+/* Get the require set of bits in a var. corr to a sequence of bits  */
+#define GET_FIELD(var, fname) \
+        ((var) >> fname##_SHFT & fname##_MASK >> fname##_SHFT)
+/* Set the require set of bits in a var. corr to a sequence of bits  */
+#define SET_FIELD(var, fname, fval) \
+        ((var) = (var) & ~fname##_MASK | (uint64_t) (fval) << fname##_SHFT)
+
+
+#ifndef __ASSEMBLY__
+
+typedef struct router_map_ent_s {
+	uint64_t	nic;
+	moduleid_t	module;
+	slotid_t	slot;
+} router_map_ent_t;
+
+struct rr_status_error_fmt {
+	uint64_t	rserr_unused		: 30,
+			rserr_fifooverflow	: 1,
+			rserr_illegalport	: 1,
+			rserr_deadlockto	: 4,
+			rserr_recvtailto	: 4,
+			rserr_retrycnt		: 8,
+			rserr_cberrcnt		: 8,
+			rserr_snerrcnt		: 8;
+};
+
+/*
+ * This type is used to store "absolute" counts of router events
+ */
+typedef int	router_count_t;
+
+/* All utilizations are on a scale from 0 - 1023. */
+#define RP_BYPASS_UTIL	0
+#define RP_RCV_UTIL	1
+#define RP_SEND_UTIL	2
+#define RP_TOTAL_PKTS	3	/* Free running clock/packet counter */
+
+#define RP_NUM_UTILS	3
+
+#define RP_HIST_REGS	2
+#define RP_NUM_BUCKETS  4
+#define RP_HIST_TYPES	3
+
+#define RP_AGE0		0
+#define RP_AGE1		1
+#define RP_AGE2		2
+#define RP_AGE3		3
+
+
+#define RR_UTIL_SCALE	1024
+
+/*
+ * Router port-oriented information
+ */
+typedef struct router_port_info_s {
+	router_reg_t	rp_histograms[RP_HIST_REGS];/* Port usage info */
+	router_reg_t	rp_port_error;		/* Port error info */
+	router_count_t	rp_retry_errors;	/* Total retry errors */
+	router_count_t	rp_sn_errors;		/* Total sn errors */
+	router_count_t	rp_cb_errors;		/* Total cb errors */
+	int		rp_overflows;		/* Total count overflows */
+	int		rp_excess_err;		/* Port has excessive errors */
+	ushort		rp_util[RP_NUM_BUCKETS];/* Port utilization */
+} router_port_info_t;
+
+#define ROUTER_INFO_VERSION	7
+
+struct lboard_s;
+
+/*
+ * Router information
+ */
+typedef struct router_info_s {
+	char		ri_version;	/* structure version		    */
+	cnodeid_t	ri_cnode;	/* cnode of its legal guardian hub  */
+	nasid_t		ri_nasid;	/* Nasid of same 		    */
+	char		ri_ledcache;	/* Last LED bitmap		    */
+	char		ri_leds;	/* Current LED bitmap		    */
+	char		ri_portmask;	/* Active port bitmap		    */
+	router_reg_t	ri_stat_rev_id;	/* Status rev ID value		    */
+	net_vec_t	ri_vector;	/* vector from guardian to router   */
+	int		ri_writeid;	/* router's vector write ID	    */
+	int64_t	ri_timebase;	/* Time of first sample		    */
+	int64_t	ri_timestamp;	/* Time of last sample		    */
+	router_port_info_t ri_port[MAX_ROUTER_PORTS]; /* per port info      */
+	moduleid_t	ri_module;	/* Which module are we in?	    */
+	slotid_t	ri_slotnum;	/* Which slot are we in?	    */
+	router_reg_t	ri_glbl_parms[GLBL_PARMS_REGS];
+					/* Global parms0&1 register contents*/
+	devfs_handle_t	ri_vertex;	/* hardware graph vertex            */
+	router_reg_t	ri_prot_conf;	/* protection config. register	    */
+	int64_t	ri_per_minute;	/* Ticks per minute		    */
+
+	/*
+	 * Everything below here is for kernel use only and may change at	
+	 * at any time with or without a change in teh revision number
+	 *
+	 * Any pointers or things that come and go with DEBUG must go at
+ 	 * the bottom of the structure, below the user stuff.
+	 */
+	char		ri_hist_type;   /* histogram type		    */
+	devfs_handle_t	ri_guardian;	/* guardian node for the router	    */
+	int64_t	ri_last_print;	/* When did we last print	    */
+	char		ri_print;	/* Should we print 		    */
+	char 		ri_just_blink;	/* Should we blink the LEDs         */
+	
+#ifdef DEBUG
+	int64_t	ri_deltatime;	/* Time it took to sample	    */
 #endif
+	spinlock_t	ri_lock;	/* Lock for access to router info   */
+	net_vec_t	*ri_vecarray;	/* Pointer to array of vectors	    */
+	struct lboard_s	*ri_brd;	/* Pointer to board structure	    */
+	char *		ri_name;	/* This board's hwg path 	    */
+        unsigned char	ri_port_maint[MAX_ROUTER_PORTS]; /* should we send a 
+					message to availmon */
+} router_info_t;
+
+
+/* Router info location specifiers */
+
+#define RIP_PROMLOG			2	/* Router info in promlog */
+#define RIP_CONSOLE			4	/* Router info on console */
+
+#define ROUTER_INFO_PRINT(_rip,_where)	(_rip->ri_print |= _where)	
+					/* Set the field used to check if a 
+					 * router info can be printed
+					 */
+#define IS_ROUTER_INFO_PRINTED(_rip,_where)	\
+					(_rip->ri_print & _where)	
+					/* Was the router info printed to
+					 * the given location (_where) ?
+					 * Mainly used to prevent duplicate
+					 * router error states.
+					 */
+#define ROUTER_INFO_LOCK(_rip,_s)	_s = mutex_spinlock(&(_rip->ri_lock))
+					/* Take the lock on router info
+					 * to gain exclusive access
+					 */
+#define ROUTER_INFO_UNLOCK(_rip,_s)	mutex_spinunlock(&(_rip->ri_lock),_s)
+					/* Release the lock on router info */
+/* 
+ * Router info hanging in the nodepda 
+ */
+typedef struct nodepda_router_info_s {
+	devfs_handle_t 	router_vhdl;	/* vertex handle of the router 	    */
+	short		router_port;	/* port thru which we entered       */
+	short		router_portmask;
+	moduleid_t	router_module;	/* module in which router is there  */
+	slotid_t	router_slot;	/* router slot			    */
+	unsigned char	router_type;	/* kind of router 		    */
+	net_vec_t	router_vector;	/* vector from the guardian node    */
+
+	router_info_t	*router_infop;	/* info hanging off the hwg vertex  */
+	struct nodepda_router_info_s *router_next;
+	                                /* pointer to next element 	    */
+} nodepda_router_info_t;
+
+#define ROUTER_NAME_SIZE	20	/* Max size of a router name */
+
+#define NORMAL_ROUTER_NAME	"normal_router"
+#define NULL_ROUTER_NAME	"null_router"
+#define META_ROUTER_NAME	"meta_router"
+#define REPEATER_ROUTER_NAME	"repeater_router"
+#define UNKNOWN_ROUTER_NAME	"unknown_router" 
+
+/* The following definitions are needed by the router traversing
+ * code either using the hardware graph or using vector operations.
+ */
+/* Structure of the router queue element */
+typedef struct router_elt_s {
+	union {
+		/* queue element structure during router probing */
+		struct {
+			/* number-in-a-can (unique) for the router */
+			nic_t		nic;	
+			/* vector route from the master hub to 
+			 * this router.
+			 */
+			net_vec_t	vec;	
+			/* port status */
+			uint64_t	status;	
+			char		port_status[MAX_ROUTER_PORTS + 1];
+		} r_elt;
+		/* queue element structure during router guardian 
+		 * assignment
+		 */
+		struct {
+			/* vertex handle for the router */
+			devfs_handle_t	vhdl;
+			/* guardian for this router */
+			devfs_handle_t	guard;	
+			/* vector router from the guardian to the router */
+			net_vec_t	vec;
+		} k_elt;
+	} u;
+	                        /* easy to use port status interpretation */
+} router_elt_t;
+
+/* structure of the router queue */
+
+typedef struct router_queue_s {
+	char		head;	/* Point where a queue element is inserted */
+	char		tail;	/* Point where a queue element is removed */
+	int		type;
+	router_elt_t	array[MAX_RTR_BREADTH];
+	                        /* Entries for queue elements */
+} router_queue_t;
+
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * RR_HISTOGRAM(_L) mask and shift definitions
+ * There are two 64 bit histogram registers, so the following macros take
+ * into account dealing with an array of 4 32 bit values indexed by _x
+ */
+
+#define RHIST_BUCKET_SHFT(_x)	(32 * ((_x) & 0x1))
+#define RHIST_BUCKET_MASK(_x)	(UINT64_CAST 0xffffffff << RHIST_BUCKET_SHFT((_x) & 0x1))
+#define RHIST_GET_BUCKET(_x, _reg)	\
+	((RHIST_BUCKET_MASK(_x) & ((_reg)[(_x) >> 1])) >> RHIST_BUCKET_SHFT(_x))
+
+/*
+ * RR_RESET_MASK(_L) mask and shift definitions
+ */
+
+#define RRM_RESETOK(_L)		(UINT64_CAST 1 << ((_L) - 1))
+#define RRM_RESETOK_ALL		ALL_PORTS
+
+/*
+ * RR_META_TABLE(_x) and RR_LOCAL_TABLE(_x) mask and shift definitions
+ */
+
+#define RTABLE_SHFT(_L)		(4 * ((_L) - 1))
+#define RTABLE_MASK(_L)		(UINT64_CAST 0x7 << RTABLE_SHFT(_L))
+
+
+#define	ROUTERINFO_STKSZ	4096
+
+#ifndef __ASSEMBLY__
+
+int router_reg_read(router_info_t *rip, int regno, router_reg_t *val);
+int router_reg_write(router_info_t *rip, int regno, router_reg_t val);
+int router_get_info(devfs_handle_t routerv, router_info_t *, int);
+int router_init(cnodeid_t cnode,int writeid, nodepda_router_info_t *npda_rip);
+int router_set_leds(router_info_t *rip);
+void router_print_state(router_info_t *rip, int level,
+		   void (*pf)(int, char *, ...),int print_where);
+void capture_router_stats(router_info_t *rip);
+
+
+int 	probe_routers(void);
+void 	get_routername(unsigned char brd_type,char *rtrname);
+void 	router_guardians_set(devfs_handle_t hwgraph_root);
+int 	router_hist_reselect(router_info_t *, int64_t);
+#endif /* __ASSEMBLY__ */
 
-#endif /* _ASM_SN_ROUTER_H */
+#endif /* _ASM_IA64_SN_ROUTER_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sgi.h linux/include/asm-ia64/sn/sgi.h
--- linux.orig/include/asm-ia64/sn/sgi.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sgi.h	2002-07-20 01:08:22.000000000 +0000
@@ -4,13 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 
-#ifndef _ASM_SN_SGI_H
-#define _ASM_SN_SGI_H
+#ifndef _ASM_IA64_SN_SGI_H
+#define _ASM_IA64_SN_SGI_H
 
 #include <linux/config.h>
 
@@ -95,9 +94,6 @@
 				 bigger. This is NULL-terminated  */
 };
 
-#define MIN(_a,_b)		((_a)<(_b)?(_a):(_b))
-
-typedef uint32_t app32_ptr_t;	/* needed by edt.h */
 typedef int64_t  __psint_t;	/* needed by klgraph.c */
 
 typedef enum { B_FALSE, B_TRUE } boolean_t;
@@ -105,8 +101,6 @@
 #define ctob(x)			((uint64_t)(x)*NBPC)
 #define btoc(x)			(((uint64_t)(x)+(NBPC-1))/NBPC)
 
-typedef __psunsigned_t nic_data_t;
-
 
 /*
 ** Possible return values from graph routines.
@@ -129,10 +123,6 @@
 					 * calls */
 #define XG_WIDGET_PART_NUM      0xC102          /* KONA/xt_regs.h     XG_XT_PART_NUM_VALUE */
 
-#ifndef TO_PHYS_MASK
-#define TO_PHYS_MASK 0x0000000fffffffff
-#endif
-
 typedef uint64_t vhandl_t;
 
 
@@ -159,7 +149,7 @@
 typedef uint64_t mrlock_t;	/* needed by devsupport.c */
 
 #define HUB_PIO_CONVEYOR 0x1
-#define CNODEID_NONE (cnodeid_t)-1
+#define CNODEID_NONE ((cnodeid_t)-1)
 #define XTALK_PCI_PART_NUM "030-1275-"
 #define kdebug 0
 
@@ -177,7 +167,7 @@
 #define kern_free(x)		kfree(x)
 
 typedef cpuid_t cpu_cookie_t;
-#define CPU_NONE		-1
+#define CPU_NONE		(-1)
 
 /*
  * mutext support mapping
@@ -225,9 +215,6 @@
         } } while(0)
 #endif	/* DISABLE_ASSERT */
 
-#define PRINT_WARNING(x...)	do { printk("WARNING : "); printk(x); } while(0)
-#define PRINT_NOTICE(x...)	do { printk("NOTICE : "); printk(x); } while(0)
-#define PRINT_ALERT(x...)	do { printk("ALERT : "); printk(x); } while(0)
 #define PRINT_PANIC		panic
 
 #ifdef CONFIG_SMP
@@ -238,4 +225,4 @@
 
 #include <asm/sn/hack.h>	/* for now */
 
-#endif	/* _ASM_SN_SGI_H */
+#endif /* _ASM_IA64_SN_SGI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/simulator.h linux/include/asm-ia64/sn/simulator.h
--- linux.orig/include/asm-ia64/sn/simulator.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/simulator.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,27 @@
+#ifndef _ASM_IA64_SN_SIMULATOR_H
+#define _ASM_IA64_SN_SIMULATOR_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_IA64_SGI_SN_SIM
+
+#define SNMAGIC 0xaeeeeeee8badbeefL
+#define IS_RUNNING_ON_SIMULATOR() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;})
+
+#define SIMULATOR_SLEEP()	asm("nop.i 0x8beef")
+
+#else
+
+#define IS_RUNNING_ON_SIMULATOR()	(0)
+#define SIMULATOR_SLEEP()
+
+#endif
+
+#endif /* _ASM_IA64_SN_SIMULATOR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/slotnum.h linux/include/asm-ia64/sn/slotnum.h
--- linux.orig/include/asm-ia64/sn/slotnum.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/slotnum.h	2002-07-20 01:08:40.000000000 +0000
@@ -4,22 +4,23 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SLOTNUM_H
-#define _ASM_SN_SLOTNUM_H
+#ifndef _ASM_IA64_SN_SLOTNUM_H
+#define _ASM_IA64_SN_SLOTNUM_H
 
 #include <linux/config.h>
 
 typedef	unsigned char slotid_t;
 
-#if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#if defined (CONFIG_IA64_SGI_SN1)
 #include <asm/sn/sn1/slotnum.h>
+#elif defined (CONFIG_IA64_SGI_SN2)
+#include <asm/sn/sn2/slotnum.h>
 #else
 
 #error <<BOMB! slotnum defined only for SN0 and SN1 >>
 
-#endif /* !CONFIG_SGI_IP35 && !CONFIG_IA64_SGI_SN1 */
+#endif /* !CONFIG_IA64_SGI_SN1 */
 
-#endif /* _ASM_SN_SLOTNUM_H */
+#endif /* _ASM_IA64_SN_SLOTNUM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/addrs.h linux/include/asm-ia64/sn/sn1/addrs.h
--- linux.orig/include/asm-ia64/sn/sn1/addrs.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/addrs.h	2002-07-20 01:08:35.000000000 +0000
@@ -4,19 +4,21 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef _ASM_SN_SN1_ADDRS_H
-#define _ASM_SN_SN1_ADDRS_H
+#ifndef _ASM_IA64_SN_SN1_ADDRS_H
+#define _ASM_IA64_SN_SN1_ADDRS_H
 
+#include <linux/config.h>
+
+#ifdef CONFIG_IA64_SGI_SN1
 /*
- * IP35 (on a TRex) Address map
+ * SN1 (on a TRex) Address map
  *
  * This file contains a set of definitions and macros which are used
  * to reference into the major address spaces (CAC, HSPEC, IO, MSPEC,
- * and UNCAC) used by the IP35 architecture.  It also contains addresses
+ * and UNCAC) used by the SN1 architecture.  It also contains addresses
  * for "major" statically locatable PROM/Kernel data structures, such as
  * the partition table, the configuration data structure, etc.
  * We make an implicit assumption that the processor using this file
@@ -32,7 +34,6 @@
  *	 appropriately.
  */
 
-#include <linux/config.h>
 
 /*
  * Some of the macros here need to be casted to appropriate types when used
@@ -40,22 +41,14 @@
  * use some new ANSI preprocessor stuff to paste these on where needed.
  */
 
-#if defined(_RUN_UNCACHED)
-#define CAC_BASE		0x9600000000000000
-#else
-#ifndef __ia64
-#define CAC_BASE		0xa800000000000000
-#else
 #define CAC_BASE                0xe000000000000000
-#endif
-#endif
-
 #define HSPEC_BASE              0xc0000b0000000000
 #define HSPEC_SWIZ_BASE         0xc000030000000000
 #define IO_BASE                 0xc0000a0000000000
 #define IO_SWIZ_BASE            0xc000020000000000
-#define MSPEC_BASE              0xc000000000000000
+#define MSPEC_BASE              0xc000090000000000
 #define UNCAC_BASE              0xc000000000000000
+#define TO_PHYS_MASK		0x000000ffffffffff
 
 #define TO_PHYS(x)		(	      ((x) & TO_PHYS_MASK))
 #define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
@@ -109,18 +102,14 @@
 #define NASID_GET(_pa)		(int) ((UINT64_CAST (_pa) >>		\
 					NASID_SHFT) & NASID_BITMASK)
 
-#if _LANGUAGE_C && !defined(_STANDALONE)
-#ifndef REAL_HARDWARE
-#define NODE_SWIN_BASE(nasid, widget) RAW_NODE_SWIN_BASE(nasid, widget)
-#else
+#ifndef __ASSEMBLY__
 #define NODE_SWIN_BASE(nasid, widget)					\
 	((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN)		\
 	: RAW_NODE_SWIN_BASE(nasid, widget))
-#endif
 #else
 #define NODE_SWIN_BASE(nasid, widget) \
      (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /*
  * The following definitions pertain to the IO special address
@@ -155,7 +144,7 @@
 
 /*
  * The following define the major position-independent aliases used
- * in IP27.
+ * in SN1.
  *	CALIAS -- Varies in size, points to the first n bytes of memory
  *		  	on the reader's node.
  */
@@ -169,11 +158,6 @@
 
 #define SN0_WIDGET_BASE(_nasid, _wid)	(NODE_SWIN_BASE((_nasid), (_wid)))
 
-#if _LANGUAGE_C
-#define KERN_NMI_ADDR(nasid, slice)					\
-                    TO_NODE_UNCAC((nasid), IP27_NMI_KREGS_OFFSET + 	\
-				  (IP27_NMI_KREGS_CPU_SIZE * (slice)))
-#endif /* _LANGUAGE_C */
 
 
 /*
@@ -197,7 +181,7 @@
 #define KL_UART_CMD	LOCAL_HSPEC(HSPEC_UART_0)	/* UART command reg */
 #define KL_UART_DATA	LOCAL_HSPEC(HSPEC_UART_1)	/* UART data reg */
 
-#if !_LANGUAGE_ASSEMBLY
+#if !__ASSEMBLY__
 /* Address 0x400 to 0x1000 ualias points to cache error eframe + misc
  * CACHE_ERR_SP_PTR could either contain an address to the stack, or
  * the stack could start at CACHE_ERR_SP_PTR
@@ -210,28 +194,9 @@
 #define CACHE_ERR_SP		(CACHE_ERR_SP_PTR - 16)
 #define CACHE_ERR_AREA_SIZE	(ARCS_SPB_OFFSET - CACHE_ERR_EFRAME)
 
-#endif	/* !_LANGUAGE_ASSEMBLY */
+#endif	/* !__ASSEMBLY__ */
+
 
-/* Each CPU accesses UALIAS at a different physaddr, on 32k boundaries
- * This determines the locations of the exception vectors
- */
-#define UALIAS_FLIP_BASE	UALIAS_BASE
-#define UALIAS_FLIP_SHIFT	15
-#define UALIAS_FLIP_ADDR(_x)	((_x) ^ (cputoslice(getcpuid())<<UALIAS_FLIP_SHIFT))
-
-#if !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC)
-#define EX_HANDLER_OFFSET(slice) ((slice) << UALIAS_FLIP_SHIFT)
-#endif
-#define EX_HANDLER_ADDR(nasid, slice)					\
-	PHYS_TO_K0(NODE_OFFSET(nasid) | EX_HANDLER_OFFSET(slice))
-#define EX_HANDLER_SIZE		0x0400
-
-#if !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC)
-#define EX_FRAME_OFFSET(slice)	((slice) << UALIAS_FLIP_SHIFT | 0x400)
-#endif
-#define EX_FRAME_ADDR(nasid, slice)					\
-	PHYS_TO_K0(NODE_OFFSET(nasid) | EX_FRAME_OFFSET(slice))
-#define EX_FRAME_SIZE		0x0c00
 
 #define _ARCSPROM
 
@@ -241,7 +206,7 @@
  * The PROM needs to pass the device base address and the
  * device pci cfg space address to the device drivers during
  * install. The COMPONENT->Key field is used for this purpose.
- * Macros needed by IP27 device drivers to convert the
+ * Macros needed by SN1 device drivers to convert the
  * COMPONENT->Key field to the respective base address.
  * Key field looks as follows:
  *
@@ -256,7 +221,7 @@
  * is in place.
  */
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define uchar unsigned char
 
@@ -301,8 +266,9 @@
 #define PUT_INSTALL_STATUS(c,s)		c->Revision = s
 #define GET_INSTALL_STATUS(c)		c->Revision
 
-#endif /* LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 #endif /* _STANDALONE */
+#endif /* CONFIG_IA64_SGI_SN1 */
 
-#endif /* _ASM_SN_SN1_ADDRS_H */
+#endif /* _ASM_IA64_SN_SN1_ADDRS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/arch.h linux/include/asm-ia64/sn/sn1/arch.h
--- linux.orig/include/asm-ia64/sn/sn1/arch.h	2001-01-04 23:25:55.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/arch.h	2002-07-20 01:08:27.000000000 +0000
@@ -4,29 +4,29 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_ARCH_H
-#define _ASM_SN_SN1_ARCH_H
+#ifndef _ASM_IA64_SN_SN1_ARCH_H
+#define _ASM_IA64_SN_SN1_ARCH_H
 
 #if defined(N_MODE)
 #error "ERROR constants defined only for M-mode"
 #endif
 
+#include <linux/threads.h>
+#include <asm/types.h>
+
+#define CPUS_PER_NODE           4       /* CPUs on a single hub */
+#define CPUS_PER_SUBNODE        2       /* CPUs on a single hub PI */
+
 /*
  * This is the maximum number of NASIDS that can be present in a system.
+ * This include ALL nodes in ALL partitions connected via NUMALINK.
  * (Highest NASID plus one.)
  */
 #define MAX_NASIDS              128
 
 /*
- * MAXCPUS refers to the maximum number of CPUs in a single kernel.
- * This is not necessarily the same as MAXNODES * CPUS_PER_NODE
- */
-#define MAXCPUS                 512
-
-/*
  * This is the maximum number of nodes that can be part of a kernel.
  * Effectively, it's the maximum number of compact node ids (cnodeid_t).
  * This is not necessarily the same as MAX_NASIDS.
@@ -40,6 +40,19 @@
 #define MAX_NONPREMIUM_REGIONS  16
 #define MAX_PREMIUM_REGIONS     MAX_REGIONS
 
+/*
+ * Slot constants for IP35
+ */
+
+#define MAX_MEM_SLOTS    8                     /* max slots per node */
+
+#if defined(N_MODE)
+#error "N-mode not supported"
+#endif
+
+#define SLOT_SHIFT              (30)
+#define SLOT_MIN_MEM_SIZE       (64*1024*1024)
+
 
 /*
  * MAX_PARITIONS refers to the maximum number of logically defined 
@@ -51,17 +64,14 @@
 #define NASID_MASK_BYTES	((MAX_NASIDS + 7) / 8)
 
 /*
- * Slot constants for IP35
+ * New stuff in here from Irix sys/pfdat.h.
  */
+#define SLOT_PFNSHIFT           (SLOT_SHIFT - PAGE_SHIFT)
+#define PFN_NASIDSHFT           (NASID_SHFT - PAGE_SHIFT)
+#define slot_getbasepfn(node,slot)  (mkpfn(COMPACT_TO_NASID_NODEID(node), slot<<SLOT_PFNSHIFT))
+#define mkpfn(nasid, off)       (((pfn_t)(nasid) << PFN_NASIDSHFT) | (off))
 
-#define MAX_MEM_SLOTS    8                     /* max slots per node */
-
-#if defined(N_MODE)
-#error "N-mode not supported"
-#endif
 
-#define SLOT_SHIFT      	(30)
-#define SLOT_MIN_MEM_SIZE	(64*1024*1024)
 
 /*
  * two PIs per bedrock, two CPUs per PI
@@ -76,4 +86,4 @@
 #define TO_SLICE(subn, local)	(((subn) << SUBNODE_SHFT) | \
 				 ((local) << LOCALCPU_SHFT))
 
-#endif /* _ASM_SN_SN1_ARCH_H */
+#endif /* _ASM_IA64_SN_SN1_ARCH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/bedrock.h linux/include/asm-ia64/sn/sn1/bedrock.h
--- linux.orig/include/asm-ia64/sn/sn1/bedrock.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/bedrock.h	2002-07-20 01:08:37.000000000 +0000
@@ -4,14 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef _ASM_SN_SN1_BEDROCK_H
-#define _ASM_SN_SN1_BEDROCK_H
+#ifndef _ASM_IA64_SN_SN1_BEDROCK_H
+#define _ASM_IA64_SN_SN1_BEDROCK_H
 
-#include <linux/config.h>
 
 /* The secret password; used to release protection */
 #define HUB_PASSWORD		0x53474972756c6573ull
@@ -24,7 +22,6 @@
 
 #define MAX_HUB_PATH		80
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/arch.h>
 #include <asm/sn/sn1/addrs.h>
 #include <asm/sn/sn1/hubpi.h>
@@ -40,19 +37,13 @@
 #include <asm/sn/sn1/hublb_next.h>
 #include <asm/sn/sn1/hubxb_next.h>
 
-#else /* ! CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
-
-<< BOMB! CONFIG_SGI_IP35 is only defined for IP35 >>
-
-#endif /* defined(CONFIG_SGI_IP35) */
-
 /* Translation of uncached attributes */
 #define	UATTR_HSPEC	0
 #define	UATTR_IO	1
 #define	UATTR_MSPEC	2
 #define	UATTR_UNCAC	3
 
-#if _LANGUAGE_ASSEMBLY
+#if __ASSEMBLY__
 
 /*
  * Get nasid into register, r (uses at)
@@ -63,9 +54,9 @@
 	and	r, LRI_NODEID_MASK;			\
 	dsrl	r, LRI_NODEID_SHFT
 
-#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* __ASSEMBLY__ */
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #include <asm/sn/xtalk/xwidget.h>
 
@@ -78,6 +69,6 @@
 void capture_hub_stats(cnodeid_t, struct nodepda_s *);
 void init_hub_stats(cnodeid_t, struct nodepda_s *);
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
-#endif /* _ASM_SN_SN1_BEDROCK_H */
+#endif /* _ASM_IA64_SN_SN1_BEDROCK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubdev.h linux/include/asm-ia64/sn/sn1/hubdev.h
--- linux.orig/include/asm-ia64/sn/sn1/hubdev.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubdev.h	2002-07-20 01:08:33.000000000 +0000
@@ -4,12 +4,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef _ASM_SN_SN1_HUBDEV_H
-#define _ASM_SN_SN1_HUBDEV_H
+#ifndef _ASM_IA64_SN_SN1_HUBDEV_H
+#define _ASM_IA64_SN_SN1_HUBDEV_H
 
 extern void hubdev_init(void);
 extern void hubdev_register(int (*attach_method)(devfs_handle_t));
@@ -19,4 +18,4 @@
 extern caddr_t hubdev_prombase_get(devfs_handle_t hub);
 extern cnodeid_t hubdev_cnodeid_get(devfs_handle_t hub);
 
-#endif /* _ASM_SN_SN1_HUBDEV_H */
+#endif /* _ASM_IA64_SN_SN1_HUBDEV_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubio.h linux/include/asm-ia64/sn/sn1/hubio.h
--- linux.orig/include/asm-ia64/sn/sn1/hubio.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubio.h	2002-07-20 01:08:29.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 /************************************************************************
@@ -20,8 +19,8 @@
  ************************************************************************/
 
 
-#ifndef _ASM_SN_SN1_HUBIO_H
-#define _ASM_SN_SN1_HUBIO_H
+#ifndef _ASM_IA64_SN_SN1_HUBIO_H
+#define _ASM_IA64_SN_SN1_HUBIO_H
 
 
 #define    IIO_WID                   0x00400000    /*
@@ -762,7 +761,7 @@
 
 
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /************************************************************************
  *                                                                      *
@@ -2942,15 +2941,15 @@
 typedef union ii_ilct_u {
 	bdrkreg_t	ii_ilct_regval;
 	struct  {
-		bdrkreg_t	i_rsvd                    :	 9;
-		bdrkreg_t	i_test_err_capture        :	 1;
-		bdrkreg_t	i_test_clear              :	 1;
-		bdrkreg_t	i_test_flit               :	 3;
-		bdrkreg_t	i_test_cberr              :	 1;
-		bdrkreg_t	i_test_valid              :	 1;
-		bdrkreg_t	i_test_data               :	20;
-		bdrkreg_t	i_test_mask               :	 8;
-		bdrkreg_t	i_test_seed               :	20;
+		bdrkreg_t	i_test_seed		  :	20;
+		bdrkreg_t	i_test_mask		  :	 8;
+		bdrkreg_t	i_test_data		  :	20;
+		bdrkreg_t	i_test_valid		  :	 1;
+		bdrkreg_t	i_test_cberr		  :	 1;
+		bdrkreg_t	i_test_flit		  :	 3;
+		bdrkreg_t	i_test_clear		  :	 1;
+		bdrkreg_t	i_test_err_capture	  :	 1;
+		bdrkreg_t	i_rsvd			  :	 9;
 	} ii_ilct_fld_s;
 } ii_ilct_u_t;
 
@@ -4935,7 +4934,7 @@
 
 
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /************************************************************************
  *                                                                      *
@@ -5014,4 +5013,4 @@
 
 
 
-#endif /* _ASM_SN_SN1_HUBIO_H */
+#endif /* _ASM_IA64_SN_SN1_HUBIO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubio_next.h linux/include/asm-ia64/sn/sn1/hubio_next.h
--- linux.orig/include/asm-ia64/sn/sn1/hubio_next.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubio_next.h	2002-07-20 01:08:23.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBIO_NEXT_H
-#define _ASM_SN_SN1_HUBIO_NEXT_H
+#ifndef _ASM_IA64_SN_SN1_HUBIO_NEXT_H
+#define _ASM_IA64_SN_SN1_HUBIO_NEXT_H
 
 /*
  * Slightly friendlier names for some common registers.
@@ -64,7 +63,7 @@
 #define IIO_BTE_NOTIFY_0        IIO_IBNA_0   /* Also BTE notification 0 */
 #define IIO_BTE_INT_0           IIO_IBIA_0   /* Also BTE interrupt 0 */
 #define IIO_BTE_OFF_0           0            /* Base offset from BTE 0 regs. */
-#define IIO_BTE_OFF_1   IIO_IBLS_1 - IIO_IBLS_0 /* Offset from base to BTE 1 */
+#define IIO_BTE_OFF_1  (IIO_IBLS_1 - IIO_IBLS_0) /* Offset from base to BTE 1 */
 
 /* BTE register offsets from base */
 #define BTEOFF_STAT             0
@@ -78,11 +77,16 @@
 /* names used in hub_diags.c; carried over from SN0 */
 #define IIO_BASE_BTE0   IIO_IBLS_0		
 #define IIO_BASE_BTE1   IIO_IBLS_1		
-#if 0
-#define IIO_BASE        IIO_WID
-#define IIO_BASE_PERF   IIO_IPCR   /* IO Performance Control */
-#define IIO_PERF_CNT    IIO_IPPR   /* IO Performance Profiling */
-#endif
+
+/*
+ * Macro which takes the widget number, and returns the 
+ * IO PRB address of that widget.
+ * value _x is expected to be a widget number in the range 
+ * 0, 8 - 0xF
+ */
+#define	IIO_IOPRB(_x)	(IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
+			(_x) : \
+			(_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
 
 
 /* GFX Flow Control Node/Widget Register */
@@ -139,7 +143,7 @@
  * redefined big window 7 as small window 0.
  XXX does this still apply for SN1??
  */
-#define HUB_NUM_BIG_WINDOW      IIO_NUM_ITTES - 1
+#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
 
 /*
  * Use the top big window as a surrogate for the first small window
@@ -343,7 +347,7 @@
  * CRBs.
  */
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /*
  * Easy access macros for CRBs, all 4 registers (A-D)
@@ -389,7 +393,7 @@
 #define icrbd_context   ii_icrb0_d_fld_s.id_context
 #define d_regvalue	ii_icrb0_d_regval
 
-#endif /* LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /* Number of widgets supported by hub */
 #define HUB_NUM_WIDGET          9
@@ -399,7 +403,7 @@
 #define HUB_WIDGET_PART_NUM     0xc110
 #define MAX_HUBS_PER_XBOW       2
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 /* A few more #defines for backwards compatibility */
 #define iprb_t          ii_iprb0_u_t
 #define iprb_regval     ii_iprb0_regval
@@ -430,11 +434,11 @@
 #define IO_PERF_SETS	32
 
 #if __KERNEL__
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 /* XXX moved over from SN/SN0/hubio.h -- each should be checked for SN1 */
 #include <asm/sn/alenlist.h>
 #include <asm/sn/dmamap.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
 #include <asm/sn/xtalk/xtalk.h>
 
 /* Bit for the widget in inbound access register */
@@ -699,12 +703,9 @@
 
 extern int
 hub_intr_connect(       hub_intr_t intr_hdl,    /* xtalk intr resource hndl */
-                        intr_func_t intr_func,  /* xtalk intr handler */
-                        void *intr_arg,         /* arg to intr handler */
                         xtalk_intr_setfunc_t setfunc,
                                                 /* func to set intr hw */
-                        void *setfunc_arg,      /* arg to setfunc */
-                        void *thread);          /* intr thread to use */
+                        void *setfunc_arg);     /* arg to setfunc */
 
 extern void
 hub_intr_disconnect(hub_intr_t intr_hdl);
@@ -756,6 +757,6 @@
 extern void hub_widgetdev_shutdown(devfs_handle_t, int);
 extern int  hub_dma_enabled(devfs_handle_t);
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 #endif /* _KERNEL */
-#endif  /* _ASM_SN_SN1_HUBIO_NEXT_H */
+#endif  /* _ASM_IA64_SN_SN1_HUBIO_NEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hublb.h linux/include/asm-ia64/sn/sn1/hublb.h
--- linux.orig/include/asm-ia64/sn/sn1/hublb.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hublb.h	2002-07-20 01:08:31.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
 /************************************************************************
@@ -20,8 +19,8 @@
  ************************************************************************/
 
 
-#ifndef _ASM_SN_SN1_HUBLB_H
-#define _ASM_SN_SN1_HUBLB_H
+#ifndef _ASM_IA64_SN_SN1_HUBLB_H
+#define _ASM_IA64_SN_SN1_HUBLB_H
 
 
 #define    LB_REV_ID                 0x00600000    /*
@@ -251,7 +250,7 @@
 
 
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /************************************************************************
  *                                                                      *
@@ -1593,7 +1592,7 @@
 
 
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /************************************************************************
  *                                                                      *
@@ -1605,4 +1604,4 @@
 
 
 
-#endif /* _ASM_SN_SN1_HUBLB_H */
+#endif /* _ASM_IA64_SN_SN1_HUBLB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hublb_next.h linux/include/asm-ia64/sn/sn1/hublb_next.h
--- linux.orig/include/asm-ia64/sn/sn1/hublb_next.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hublb_next.h	2002-07-20 01:08:26.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBLB_NEXT_H
-#define _ASM_SN_SN1_HUBLB_NEXT_H
+#ifndef _ASM_IA64_SN_SN1_HUBLB_NEXT_H
+#define _ASM_IA64_SN_SN1_HUBLB_NEXT_H
 
 /**********************************************************************
 
@@ -107,4 +106,4 @@
 #define  PIOTYPE_PROT_ERR       6       /* VECTOR_STATUS only               */
 #define  PIOTYPE_UNKNOWN        7       /* VECTOR_STATUS only               */
 
-#endif	/* _ASM_SN_SN1_HUBLB_NEXT_H */
+#endif /* _ASM_IA64_SN_SN1_HUBLB_NEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubmd.h linux/include/asm-ia64/sn/sn1/hubmd.h
--- linux.orig/include/asm-ia64/sn/sn1/hubmd.h	2001-03-07 03:44:34.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubmd.h	2002-07-20 01:08:39.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBMD_H
-#define _ASM_SN_SN1_HUBMD_H
+#ifndef _ASM_IA64_SN_SN1_HUBMD_H
+#define _ASM_IA64_SN_SN1_HUBMD_H
 
 
 /************************************************************************
@@ -315,7 +314,7 @@
 
 
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /************************************************************************
  *                                                                      *
@@ -2140,7 +2139,7 @@
  * corresponds to the valid bit, and bit 1 of each two-bit field        *
  * corresponds to the overrun bit.                                      *
  * The rule for the valid bit is that it gets set whenever that error   *
- * occurs, regardless of whether a higher priority error has occurred.   *
+ * occurs, regardless of whether a higher priority error has occurred.  *
  * The rule for the overrun bit is that it gets set whenever we are     *
  * unable to record the address information for this particular         *
  * error, due to a previous error of the same or higher priority.       *
@@ -2463,7 +2462,7 @@
 
 
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /************************************************************************
  *                                                                      *
@@ -2474,4 +2473,4 @@
 
 
 
-#endif /* _ASM_SN_SN1_HUBMD_H */
+#endif /* _ASM_IA64_SN_SN1_HUBMD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubmd_next.h linux/include/asm-ia64/sn/sn1/hubmd_next.h
--- linux.orig/include/asm-ia64/sn/sn1/hubmd_next.h	2001-03-07 03:44:34.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubmd_next.h	2002-07-20 01:08:27.000000000 +0000
@@ -4,13 +4,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBMD_NEXT_H
-#define _ASM_SN_SN1_HUBMD_NEXT_H
+#ifndef _ASM_IA64_SN_SN1_HUBMD_NEXT_H
+#define _ASM_IA64_SN_SN1_HUBMD_NEXT_H
 
-#ifdef BRINGUP
 /* XXX moved over from SN/SN0/hubmd.h -- each should be checked for SN1 */
 /* In fact, most of this stuff is wrong. Some is correct, such as
  * MD_PAGE_SIZE and MD_PAGE_NUM_SHFT.
@@ -147,7 +145,7 @@
 #define MD_SPROT_REFCNT_GET(value) ( \
         ((value) & MD_SPROT_REFCNT_MASK) >> MD_SPROT_REFCNT_SHFT)
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 #ifdef LITTLE_ENDIAN
 
 typedef union md_perf_sel {
@@ -171,9 +169,8 @@
 } md_perf_sel_t;
 
 #endif
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
-#endif /* BRINGUP */
 
 /* Like SN0, SN1 supports a mostly-flat address space with 8
    CPU-visible, evenly spaced, contiguous regions, or "software
@@ -300,7 +297,7 @@
 
 ***********************************************************************/
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /* Standard Directory Entries */
 
@@ -533,7 +530,7 @@
 	struct	md_pdir_sparse_fmt	pds_fmt;
 } md_pdir_t;
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 
 /**********************************************************************
@@ -568,7 +565,7 @@
 #define MD_DIR_WAIT		(UINT64_CAST 0x6)	/* ptr format, hw-defined */
 #define MD_DIR_POISONED		(UINT64_CAST 0x7)	/* ptr format, hw-defined */
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /* Convert format and state fields into a single "cacheline state" value, defined above */
 
@@ -578,7 +575,7 @@
    MD_DIR_SHARED)
 #define MD_DIR_STATE(x) MD_FMT_ST_TO_STATE(MD_DIR_FORMAT(x), MD_DIR_STVAL(x))
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 
 
@@ -812,4 +809,4 @@
 
 #define MFC_ADDR_SHFT		6
 
-#endif  /* _ASM_SN_SN1_HUBMD_NEXT_H */
+#endif  /* _ASM_IA64_SN_SN1_HUBMD_NEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubni.h linux/include/asm-ia64/sn/sn1/hubni.h
--- linux.orig/include/asm-ia64/sn/sn1/hubni.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubni.h	2002-07-20 01:08:37.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBNI_H
-#define _ASM_SN_SN1_HUBNI_H
+#ifndef _ASM_IA64_SN_SN1_HUBNI_H
+#define _ASM_IA64_SN_SN1_HUBNI_H
 
 
 /************************************************************************
@@ -1000,7 +999,7 @@
 
 
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /************************************************************************
  *                                                                      *
@@ -1615,7 +1614,7 @@
 
 
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /************************************************************************
  *                                                                      *
@@ -1779,4 +1778,4 @@
 
 
 
-#endif /* _ASM_SN_SN1_HUBNI_H */
+#endif /* _ASM_IA64_SN_SN1_HUBNI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubni_next.h linux/include/asm-ia64/sn/sn1/hubni_next.h
--- linux.orig/include/asm-ia64/sn/sn1/hubni_next.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubni_next.h	2002-07-20 01:08:40.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBNI_NEXT_H
-#define _ASM_SN_SN1_HUBNI_NEXT_H
+#ifndef _ASM_IA64_SN_SN1_HUBNI_NEXT_H
+#define _ASM_IA64_SN_SN1_HUBNI_NEXT_H
 
 #define NI_LOCAL_ENTRIES        128
 #define NI_META_ENTRIES        1
@@ -67,7 +66,7 @@
 				 NPE_EXTLONG_MASK | NPE_EXTSHORT_MASK |\
 				 NPE_FIFOOVFLOW_MASK | NPE_TAILTO_MASK)
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 /* NI_PORT_HEADER[AB] registers (not automatically generated) */
 
 #ifdef LITTLE_ENDIAN
@@ -172,4 +171,4 @@
 				 0x6 << NPP_NULL_TIMEOUT_SHFT | \
 				 0x3f0 << NPP_MAX_BURST_SHFT)
 
-#endif  /* _ASM_SN_SN1_HUBNI_NEXT_H */
+#endif /* _ASM_IA64_SN_SN1_HUBNI_NEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubpi.h linux/include/asm-ia64/sn/sn1/hubpi.h
--- linux.orig/include/asm-ia64/sn/sn1/hubpi.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubpi.h	2002-07-20 01:08:32.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBPI_H
-#define _ASM_SN_SN1_HUBPI_H
+#ifndef _ASM_IA64_SN_SN1_HUBPI_H
+#define _ASM_IA64_SN_SN1_HUBPI_H
 
 /************************************************************************
  *                                                                      *
@@ -551,7 +550,7 @@
 
 
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /************************************************************************
  *                                                                      *
@@ -4248,7 +4247,7 @@
 
 
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /************************************************************************
  *                                                                      *
@@ -4261,4 +4260,4 @@
 #define PI_GFX_PAGE_ENABLE	0x0000010000000000LL
 
 
-#endif /* _ASM_SN_SN1_HUBPI_H */
+#endif /* _ASM_IA64_SN_SN1_HUBPI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubpi_next.h linux/include/asm-ia64/sn/sn1/hubpi_next.h
--- linux.orig/include/asm-ia64/sn/sn1/hubpi_next.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubpi_next.h	2002-07-20 01:08:30.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBPI_NEXT_H
-#define _ASM_SN_SN1_HUBPI_NEXT_H
+#ifndef _ASM_IA64_SN_SN1_HUBPI_NEXT_H
+#define _ASM_IA64_SN_SN1_HUBPI_NEXT_H
 
 
 /* define for remote PI_1 space. It is always half of a node_addressspace
@@ -54,7 +53,7 @@
     ((sts) & (PI_CRB_STS_I | PI_CRB_STS_H) | \
      ((sts) & (PI_CRB_STS_A | PI_CRB_STS_R)) >> 1)
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 /*
  * format of error stack and error status registers.
  */
@@ -329,4 +328,4 @@
 /* Error stack address shift, for use with pi_stk_fmt.sk_addr */
 #define ERR_STK_ADDR_SHFT	3
 
-#endif /* _ASM_SN_SN1_HUBPI_NEXT_H */
+#endif /* _ASM_IA64_SN_SN1_HUBPI_NEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubspc.h linux/include/asm-ia64/sn/sn1/hubspc.h
--- linux.orig/include/asm-ia64/sn/sn1/hubspc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubspc.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,24 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN1_HUBSPC_H
+#define _ASM_IA64_SN_SN1_HUBSPC_H
+
+typedef enum {
+        HUBSPC_REFCOUNTERS,
+	HUBSPC_PROM
+} hubspc_subdevice_t;
+
+
+/*
+ * Reference Counters
+ */
+
+extern int refcounters_attach(devfs_handle_t hub);
+
+#endif /* _ASM_IA64_SN_SN1_HUBSPC_H */        
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubstat.h linux/include/asm-ia64/sn/sn1/hubstat.h
--- linux.orig/include/asm-ia64/sn/sn1/hubstat.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubstat.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,56 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 - 2001 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_SN1_HUBSTAT_H
+#define _ASM_IA64_SN_SN1_HUBSTAT_H
+
+typedef int64_t 	hub_count_t;
+
+#define HUBSTAT_VERSION	1
+
+typedef struct hubstat_s {
+        char            hs_version;		/* structure version    */
+        cnodeid_t       hs_cnode;       	/* cnode of this hub    */
+        nasid_t         hs_nasid;       	/* Nasid of same        */	
+	int64_t		hs_timebase;		/* Time of first sample */
+	int64_t		hs_timestamp;		/* Time of last sample	*/
+	int64_t		hs_per_minute;		/* Ticks per minute 	*/
+
+	union {
+		hubreg_t	hs_niu_stat_rev_id; /* SN0: Status rev ID */
+		hubreg_t	hs_niu_port_status; /* SN1: Port status */
+	} hs_niu;
+
+        hub_count_t	hs_ni_retry_errors;	/* Total retry errors   */
+        hub_count_t	hs_ni_sn_errors;	/* Total sn errors      */
+        hub_count_t	hs_ni_cb_errors;	/* Total cb errors      */
+        int		hs_ni_overflows;	/* NI count overflows   */
+        hub_count_t	hs_ii_sn_errors;	/* Total sn errors      */
+        hub_count_t	hs_ii_cb_errors;	/* Total cb errors      */
+        int		hs_ii_overflows;	/* II count overflows   */
+
+	/*
+	 * Anything below this comment is intended for kernel internal-use
+	 * only and may be changed at any time.
+	 *
+	 * Any members that contain pointers or are conditionally compiled
+	 * need to be below here also.
+	 */
+        int64_t		hs_last_print;		/* When we last printed */
+        char		hs_print;		/* Should we print      */
+
+	char	       *hs_name;		/* This hub's name */
+	unsigned char	hs_maint;		/* Should we print to availmon */
+} hubstat_t;
+
+#define       hs_ni_stat_rev_id       hs_niu.hs_niu_stat_rev_id
+#define       hs_ni_port_status       hs_niu.hs_niu_port_status
+
+extern struct file_operations hub_mon_fops;
+
+#endif /* _ASM_IA64_SN_SN1_HUBSTAT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubxb.h linux/include/asm-ia64/sn/sn1/hubxb.h
--- linux.orig/include/asm-ia64/sn/sn1/hubxb.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubxb.h	2002-07-20 01:08:22.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBXB_H
-#define _ASM_SN_SN1_HUBXB_H
+#ifndef _ASM_IA64_SN_SN1_HUBXB_H
+#define _ASM_IA64_SN_SN1_HUBXB_H
 
 /************************************************************************
  *                                                                      *
@@ -273,7 +272,7 @@
 
 
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /************************************************************************
  *                                                                      *
@@ -1247,7 +1246,7 @@
 
 
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /************************************************************************
  *                                                                      *
@@ -1286,4 +1285,4 @@
 
 
 
-#endif /* _ASM_SN_SN1_HUBXB_H */
+#endif /* _ASM_IA64_SN_SN1_HUBXB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hubxb_next.h linux/include/asm-ia64/sn/sn1/hubxb_next.h
--- linux.orig/include/asm-ia64/sn/sn1/hubxb_next.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hubxb_next.h	2002-07-20 01:08:31.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SN1_HUBXB_NEXT_H
-#define _ASM_SN_SN1_HUBXB_NEXT_H
+#ifndef _ASM_IA64_SN_SN1_HUBXB_NEXT_H
+#define _ASM_IA64_SN_SN1_HUBXB_NEXT_H
 
 /* XB_FIRST_ERROR fe_source field encoding */
 #define XVE_SOURCE_POQ0 0xf	/* 1111 */
@@ -30,4 +29,4 @@
 #define XBP_RESET_DEFAULTS	0x0008000080000021LL
 #define XBP_ACTIVE_DEFAULTS	0x00080000fffff021LL
 
-#endif	/* _ASM_SN_SN1_HUBXB_NEXT_H */
+#endif /* _ASM_IA64_SN_SN1_HUBXB_NEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/hwcntrs.h linux/include/asm-ia64/sn/sn1/hwcntrs.h
--- linux.orig/include/asm-ia64/sn/sn1/hwcntrs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/hwcntrs.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,96 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN1_HWCNTRS_H
+#define _ASM_IA64_SN_SN1_HWCNTRS_H
+
+
+typedef  uint64_t refcnt_t;
+
+#define SN0_REFCNT_MAX_COUNTERS 64
+
+typedef struct sn0_refcnt_set {
+	refcnt_t    refcnt[SN0_REFCNT_MAX_COUNTERS];
+        uint64_t  flags;
+        uint64_t  reserved[4];
+} sn0_refcnt_set_t;
+
+typedef struct sn0_refcnt_buf {
+	sn0_refcnt_set_t   refcnt_set;
+	uint64_t         paddr;
+        uint64_t         page_size;
+        cnodeid_t          cnodeid;         /* cnodeid + pad[3] use 64 bits */
+        uint16_t           pad[3];
+        uint64_t         reserved[4];
+} sn0_refcnt_buf_t;
+
+typedef struct sn0_refcnt_args {
+	uint64_t          vaddr;
+	uint64_t          len;
+	sn0_refcnt_buf_t*   buf;
+        uint64_t          reserved[4];
+} sn0_refcnt_args_t;
+
+/*
+ * Info needed by the user level program
+ * to mmap the refcnt buffer
+ */
+
+#define RCB_INFO_GET  1
+#define RCB_SLOT_GET  2
+
+typedef struct rcb_info {
+        uint64_t  rcb_len;                  /* total refcnt buffer len in bytes */
+
+        int         rcb_sw_sets;              /* number of sw counter sets in buffer */
+        int         rcb_sw_counters_per_set;  /* sw counters per set -- num_compact_nodes */
+        int         rcb_sw_counter_size;      /* sizeof(refcnt_t) -- size of sw cntr */
+
+        int         rcb_base_pages;           /* number of base pages in node */
+        int         rcb_base_page_size;       /* sw base page size */        
+        uint64_t  rcb_base_paddr;           /* base physical address for this node */
+
+        int         rcb_cnodeid;              /* cnodeid for this node */
+        int         rcb_granularity;          /* hw page size used for counter sets */
+        uint        rcb_hw_counter_max;       /* max hwcounter count (width mask) */
+        int         rcb_diff_threshold;       /* current node differential threshold */
+        int         rcb_abs_threshold;        /* current node absolute threshold */
+        int         rcb_num_slots;            /* physmem slots */
+        
+        int         rcb_reserved[512];
+        
+} rcb_info_t;
+
+typedef struct rcb_slot {
+        uint64_t  base;
+        uint64_t  size;
+} rcb_slot_t;
+
+#if defined(__KERNEL__)
+typedef struct sn0_refcnt_args_32 {
+	uint64_t    vaddr;
+	uint64_t    len;
+	app32_ptr_t   buf;
+        uint64_t    reserved[4];
+} sn0_refcnt_args_32_t;
+
+/* Defines and Macros  */
+/* A set of reference counts are for 4k bytes of physical memory */
+#define	NBPREFCNTP	0x1000	
+#define	BPREFCNTPSHIFT	12
+#define bytes_to_refcntpages(x)	(((__psunsigned_t)(x)+(NBPREFCNTP-1))>>BPREFCNTPSHIFT)
+#define refcntpage_offset(x)	((__psunsigned_t)(x)&((NBPP-1)&~(NBPREFCNTP-1)))
+#define align_to_refcntpage(x)	((__psunsigned_t)(x)&(~(NBPREFCNTP-1)))
+
+extern void migr_refcnt_read(sn0_refcnt_buf_t*);
+extern void migr_refcnt_read_extended(sn0_refcnt_buf_t*);
+extern int migr_refcnt_enabled(void);
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IA64_SN_SN1_HWCNTRS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/intr.h linux/include/asm-ia64/sn/sn1/intr.h
--- linux.orig/include/asm-ia64/sn/sn1/intr.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/intr.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,237 @@
+/* $Id: intr.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN1_INTR_H
+#define _ASM_IA64_SN_SN1_INTR_H
+
+/* Subnode wildcard */
+#define SUBNODE_ANY		(-1)
+
+/* Number of interrupt levels associated with each interrupt register. */
+#define N_INTPEND_BITS		64
+
+#define INT_PEND0_BASELVL	0
+#define INT_PEND1_BASELVL	64
+
+#define	N_INTPENDJUNK_BITS	8
+#define	INTPENDJUNK_CLRBIT	0x80
+
+#include <asm/sn/intr_public.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/xtalk/xtalk.h>
+#include <asm/sn/hack.h>
+
+#ifndef __ASSEMBLY__
+#define II_NAMELEN	24
+
+/*
+ * Dispatch table entry - contains information needed to call an interrupt
+ * routine.
+ */
+typedef struct intr_vector_s {
+	intr_func_t	iv_func;	/* Interrupt handler function */
+	intr_func_t	iv_prefunc;	/* Interrupt handler prologue func */
+	void		*iv_arg;	/* Argument to pass to handler */
+	cpuid_t			iv_mustruncpu;	/* Where we must run. */
+} intr_vector_t;
+
+/* Interrupt information table. */
+typedef struct intr_info_s {
+	xtalk_intr_setfunc_t	ii_setfunc;	/* Function to set the interrupt
+						 * destination and level register.
+						 * It returns 0 (success) or an
+						 * error code.
+						 */
+	void			*ii_cookie;	/* arg passed to setfunc */
+	devfs_handle_t		ii_owner_dev;	/* device that owns this intr */
+	char			ii_name[II_NAMELEN];	/* Name of this intr. */
+	int			ii_flags;	/* informational flags */
+} intr_info_t;
+
+
+#define THD_CREATED	0x00000001	/*
+					 * We've created a thread for this
+					 * interrupt.
+					 */
+
+/*
+ * Bits for ii_flags:
+ */
+#define II_UNRESERVE	0
+#define II_RESERVE	1		/* Interrupt reserved. 			*/
+#define II_INUSE	2		/* Interrupt connected 			*/
+#define II_ERRORINT	4		/* INterrupt is an error condition 	*/
+#define II_THREADED	8		/* Interrupt handler is threaded.	*/
+
+/*
+ * Interrupt level wildcard
+ */
+#define INTRCONNECT_ANYBIT	(-1)
+
+/*
+ * This structure holds information needed both to call and to maintain
+ * interrupts.  The two are in separate arrays for the locality benefits.
+ * Since there's only one set of vectors per hub chip (but more than one
+ * CPU, the lock to change the vector tables must be here rather than in
+ * the PDA.
+ */
+
+typedef struct intr_vecblk_s {
+	intr_vector_t	vectors[N_INTPEND_BITS];  /* information needed to
+						     call an intr routine. */
+	intr_info_t	info[N_INTPEND_BITS];	  /* information needed only
+						     to maintain interrupts. */
+	spinlock_t	vector_lock;		  /* Lock for this and the
+						     masks in the PDA. */
+	splfunc_t	vector_spl;		  /* vector_lock req'd spl */
+	int		vector_state;		  /* Initialized to zero.
+						     Set to INTR_INITED
+						     by hubintr_init.
+						   */
+	int		vector_count;		  /* Number of vectors
+						   * reserved.
+						   */
+	int		cpu_count[CPUS_PER_SUBNODE]; /* How many interrupts are
+						   * connected to each CPU
+						   */
+	int		ithreads_enabled;	  /* Are interrupt threads
+						   * initialized on this node.
+						   * and block?
+						   */
+} intr_vecblk_t;
+
+/* Possible values for vector_state: */
+#define VECTOR_UNINITED	0
+#define VECTOR_INITED	1
+#define VECTOR_SET	2
+
+#define hub_intrvect0	private.p_intmasks.dispatch0->vectors
+#define hub_intrvect1	private.p_intmasks.dispatch1->vectors
+#define hub_intrinfo0	private.p_intmasks.dispatch0->info
+#define hub_intrinfo1	private.p_intmasks.dispatch1->info
+
+/*
+ * Macros to manipulate the interrupt register on the calling hub chip.
+ */
+
+#define LOCAL_HUB_SEND_INTR(_level)	LOCAL_HUB_S(PI_INT_PEND_MOD, \
+						    (0x100|(_level)))
+#define REMOTE_HUB_PI_SEND_INTR(_hub, _sn, _level) \
+		REMOTE_HUB_PI_S((_hub), _sn, PI_INT_PEND_MOD, (0x100|(_level)))
+
+#define REMOTE_CPU_SEND_INTR(_cpuid, _level) 					\
+		REMOTE_HUB_PI_S(cpuid_to_nasid(_cpuid),				\
+			SUBNODE(cpuid_to_slice(_cpuid)),				\
+			PI_INT_PEND_MOD, (0x100|(_level)))
+
+/*
+ * When clearing the interrupt, make sure this clear does make it 
+ * to the hub. Otherwise we could end up losing interrupts.
+ * We do an uncached load of the int_pend0 register to ensure this.
+ */
+
+#define LOCAL_HUB_CLR_INTR(_level)	  \
+                LOCAL_HUB_S(PI_INT_PEND_MOD, (_level)),	\
+                LOCAL_HUB_L(PI_INT_PEND0)
+#define REMOTE_HUB_PI_CLR_INTR(_hub, _sn, _level) \
+		REMOTE_HUB_PI_S((_hub), (_sn), PI_INT_PEND_MOD, (_level)),	\
+                REMOTE_HUB_PI_L((_hub), (_sn), PI_INT_PEND0)
+
+/* Special support for use by gfx driver only.  Supports special gfx hub interrupt. */
+extern void install_gfxintr(cpuid_t cpu, ilvl_t swlevel, intr_func_t intr_func, void *intr_arg);
+
+void setrtvector(intr_func_t func);
+
+/*
+ * Interrupt blocking
+ */
+extern void intr_block_bit(cpuid_t cpu, int bit);
+extern void intr_unblock_bit(cpuid_t cpu, int bit);
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Hard-coded interrupt levels:
+ */
+
+/*
+ *	L0 = SW1
+ *	L1 = SW2
+ *	L2 = INT_PEND0
+ *	L3 = INT_PEND1
+ *	L4 = RTC
+ *	L5 = Profiling Timer
+ *	L6 = Hub Errors
+ *	L7 = Count/Compare (T5 counters)
+ */
+
+
+/* INT_PEND0 hard-coded bits. */
+#ifdef DEBUG_INTR_TSTAMP
+/* hard coded interrupt level for interrupt latency test interrupt */
+#define	CPU_INTRLAT_B	62
+#define	CPU_INTRLAT_A	61
+#endif
+
+/* Hardcoded bits required by software. */
+#define MSC_MESG_INTR	9
+#define CPU_ACTION_B	8
+#define CPU_ACTION_A	7
+
+/* These are determined by hardware: */
+#define CC_PEND_B	6
+#define CC_PEND_A	5
+#define UART_INTR	4
+#define PG_MIG_INTR	3
+#define GFX_INTR_B	2
+#define GFX_INTR_A	1
+#define RESERVED_INTR	0
+
+/* INT_PEND1 hard-coded bits: */
+#define MSC_PANIC_INTR	63
+#define NI_ERROR_INTR	62
+#define MD_COR_ERR_INTR	61
+#define COR_ERR_INTR_B	60
+#define COR_ERR_INTR_A	59
+#define CLK_ERR_INTR	58
+
+# define NACK_INT_B	57
+# define NACK_INT_A	56
+# define LB_ERROR	55
+# define XB_ERROR	54
+
+#define BRIDGE_ERROR_INTR 53	/* Setup by PROM to catch Bridge Errors */
+
+#define IP27_INTR_0	52	/* Reserved for PROM use */
+#define IP27_INTR_1	51	/*   (do not use in Kernel) */
+#define IP27_INTR_2	50
+#define IP27_INTR_3	49
+#define IP27_INTR_4	48
+#define IP27_INTR_5	47
+#define IP27_INTR_6	46
+#define IP27_INTR_7	45
+
+#define	TLB_INTR_B	44	/* used for tlb flush random */
+#define	TLB_INTR_A	43
+
+#define LLP_PFAIL_INTR_B 42	/* see ml/SN/SN0/sysctlr.c */
+#define LLP_PFAIL_INTR_A 41
+
+#define NI_BRDCAST_ERR_B 40
+#define NI_BRDCAST_ERR_A 39
+
+# define IO_ERROR_INTR	38	/* set up by prom */
+# define DEBUG_INTR_B	37	/* used by symmon to stop all cpus */
+# define DEBUG_INTR_A	36
+
+// These aren't strictly accurate or complete.  See the
+// Synergy Spec. for details.
+#define SGI_UART_IRQ	(65)
+#define SGI_HUB_ERROR_IRQ	(182)
+
+#endif /* _ASM_IA64_SN_SN1_INTR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/intr_public.h linux/include/asm-ia64/sn/sn1/intr_public.h
--- linux.orig/include/asm-ia64/sn/sn1/intr_public.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/intr_public.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,53 @@
+/* $Id: intr_public.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN1_INTR_PUBLIC_H
+#define _ASM_IA64_SN_SN1_INTR_PUBLIC_H
+
+/* REMEMBER: If you change these, the whole world needs to be recompiled.
+ * It would also require changing the hubspl.s code and SN0/intr.c
+ * Currently, the spl code has no support for multiple INTPEND1 masks.
+ */
+
+#define	N_INTPEND0_MASKS	1
+#define	N_INTPEND1_MASKS	1
+
+#define INTPEND0_MAXMASK	(N_INTPEND0_MASKS - 1)
+#define INTPEND1_MAXMASK	(N_INTPEND1_MASKS - 1)
+
+#ifndef __ASSEMBLY__
+#include <asm/sn/arch.h>
+
+struct intr_vecblk_s;	/* defined in asm/sn/intr.h */
+
+/*
+ * The following are necessary to create the illusion of a CEL
+ * on the IP27 hub.  We'll add more priority levels soon, but for
+ * now, any interrupt in a particular band effectively does an spl.
+ * These must be in the PDA since they're different for each processor.
+ * Users of this structure must hold the vector_lock in the appropriate vector
+ * block before modifying the mask arrays.  There's only one vector block
+ * for each Hub so a lock in the PDA wouldn't be adequate.
+ */
+typedef struct hub_intmasks_s {
+	/*
+	 * The masks are stored with the lowest-priority (most inclusive)
+	 * in the lowest-numbered masks (i.e., 0, 1, 2...).
+	 */
+	/* INT_PEND0: */
+	hubreg_t		intpend0_masks[N_INTPEND0_MASKS]; 
+	/* INT_PEND1: */
+	hubreg_t		intpend1_masks[N_INTPEND1_MASKS];
+	/* INT_PEND0: */
+	struct intr_vecblk_s	*dispatch0;	
+	/* INT_PEND1: */
+	struct intr_vecblk_s	*dispatch1;
+} hub_intmasks_t;
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_IA64_SN_SN1_INTR_PUBLIC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/ip27config.h linux/include/asm-ia64/sn/sn1/ip27config.h
--- linux.orig/include/asm-ia64/sn/sn1/ip27config.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/ip27config.h	2002-07-20 01:08:29.000000000 +0000
@@ -4,12 +4,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef _ASM_SN_SN1_IP27CONFIG_H
-#define _ASM_SN_SN1_IP27CONFIG_H
+#ifndef _ASM_IA64_SN_SN1_IP27CONFIG_H
+#define _ASM_IA64_SN_SN1_IP27CONFIG_H
 
 
 /*
@@ -50,7 +49,7 @@
  */
 #define IP27_RTC_FREQ			1250	/* 800ns cycle time */
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef	struct ip27config_s {		/* KEEP IN SYNC w/ start.s & below  */
     uint		time_const;	/* Time constant 		    */
@@ -110,9 +109,9 @@
  */
 #define CONFIG_12P4I_NODE(n)	(0)
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
-#if _LANGUAGE_ASSEMBLY
+#if __ASSEMBLY__
 	.struct		0		/* KEEP IN SYNC WITH C structure */
 
 ip27c_time_const:	.word	0
@@ -137,7 +136,7 @@
 ip27c_pvers_rev:	.word	0
 
 ip27c_config_type:	.word 	0	/* To recognize special configs */
-#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* __ASSEMBLY__ */
 
 /*
  * R10000 Configuration Cycle - These define the SYSAD values used
@@ -245,7 +244,7 @@
 
 #define CONFIG_FREQ_RTC	IP27C_KHZ(IP27_RTC_FREQ)
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /* we are going to define all the known configs is a table
  * for building hex images we will pull out the particular
@@ -258,7 +257,7 @@
  */
 
 /* these numbers are as the are ordered in the table below */
-#define	IP27_CONFIG_UNKNOWN -1
+#define	IP27_CONFIG_UNKNOWN (-1)
 #define IP27_CONFIG_SN1_1MB_200_400_200_TABLE 0
 #define IP27_CONFIG_SN00_4MB_100_200_133_TABLE 1
 #define IP27_CONFIG_SN1_4MB_200_400_267_TABLE 2
@@ -500,9 +499,9 @@
 #define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].fprom_wr
 #endif /* IP27_CONFIG_SN1_4MB_180_360_240 */
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
-#if _LANGUAGE_ASSEMBLY
+#if __ASSEMBLY__
 
 /* these need to be in here since we need assembly definitions
  * for building hex images (as required by start.s)
@@ -653,6 +652,6 @@
 #define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
 #endif /* IP27_CONFIG_SN1_4MB_180_360_240 */
 
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
-#endif /* _ASM_SN_SN1_IP27CONFIG_H */
+#endif /* _ASM_IA64_SN_SN1_IP27CONFIG_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/kldir.h linux/include/asm-ia64/sn/sn1/kldir.h
--- linux.orig/include/asm-ia64/sn/sn1/kldir.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/kldir.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,222 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-#ifndef _ASM_SN_SN1_KLDIR_H
-#define _ASM_SN_SN1_KLDIR_H
-
-/*
- * The upper portion of the memory map applies during boot
- * only and is overwritten by IRIX/SYMMON.  The minimum memory bank
- * size on IP35 is 64M, which provides a limit on the amount of space
- * the PROM can assume it has available.
- *
- * Most of the addresses below are defined as macros in this file, or
- * in SN/addrs.h or SN/SN1/addrs.h.
- *
- *                                    MEMORY MAP PER NODE
- *
- * 0x4000000 (64M)         +-----------------------------------------+
- *                         |                                         |
- *                         |                                         |
- *                         |      IO7 TEXT/DATA/BSS/stack            |
- * 0x3000000 (48M)         +-----------------------------------------+
- *                         |      Free                               |
- * 0x2102000 (>33M)        +-----------------------------------------+
- *                         |      IP35 Topology (PCFG) + misc data   |
- * 0x2000000 (32M)         +-----------------------------------------+
- *                         |      IO7 BUFFERS FOR FLASH ENET IOC3    |
- * 0x1F80000 (31.5M)       +-----------------------------------------+
- *                         |      Free                               |
- * 0x1C00000 (28M)         +-----------------------------------------+
- *                         |      IP35 PROM TEXT/DATA/BSS/stack      |
- * 0x1A00000 (26M)         +-----------------------------------------+
- *                         |      Routing temp. space                |
- * 0x1800000 (24M)         +-----------------------------------------+
- *                         |      Diagnostics temp. space            |
- * 0x1500000 (21M)         +-----------------------------------------+
- *                         |      Free                               |
- * 0x1400000 (20M)         +-----------------------------------------+
- *                         |      IO7 PROM temporary copy            |
- * 0x1300000 (19M)         +-----------------------------------------+
- *                         |                                         |
- *                         |      Free                               |
- *                         |      (UNIX DATA starts above 0x1000000) |
- *                         |                                         |
- *                         +-----------------------------------------+
- *                         |      UNIX DEBUG Version                 |
- * 0x0310000 (3.1M)        +-----------------------------------------+
- *                         |      SYMMON, loaded just below UNIX     |
- *                         |      (For UNIX Debug only)              |
- *                         |                                         |
- *                         |                                         |
- * 0x006C000 (432K)        +-----------------------------------------+
- *                         |      SYMMON STACK [NUM_CPU_PER_NODE]    |
- *                         |      (For UNIX Debug only)              |
- * 0x004C000 (304K)        +-----------------------------------------+
- *                         |                                         |
- *                         |                                         |
- *                         |      UNIX NON-DEBUG Version             |
- * 0x0040000 (256K)        +-----------------------------------------+
- *
- *
- * The lower portion of the memory map contains information that is
- * permanent and is used by the IP35PROM, IO7PROM and IRIX.
- *
- * 0x40000 (256K)          +-----------------------------------------+
- *                         |                                         |
- *                         |      KLCONFIG (64K)                     |
- *                         |                                         |
- * 0x30000 (192K)          +-----------------------------------------+
- *                         |                                         |
- *                         |      PI Error Spools (64K)              |
- *                         |                                         |
- * 0x20000 (128K)          +-----------------------------------------+
- *                         |                                         |
- *                         |      Unused                             |
- *                         |                                         |
- * 0x19000 (100K)          +-----------------------------------------+
- *                         |      Early cache Exception stack (CPU 3)|
- * 0x18800 (98K)           +-----------------------------------------+
- *			   |      cache error eframe (CPU 3)	     |
- * 0x18400 (97K)           +-----------------------------------------+
- *                         |      Exception Handlers (CPU 3)         |
- * 0x18000 (96K)           +-----------------------------------------+
- *                         |                                         |
- *                         |      Unused                             |
- *                         |                                         |
- * 0x13c00 (79K)           +-----------------------------------------+
- *                         |      GPDA (8k)                          |
- * 0x11c00 (71K)           +-----------------------------------------+
- *                         |      Early cache Exception stack (CPU 2)|
- * 0x10800 (66k)	   +-----------------------------------------+
- *			   |      cache error eframe (CPU 2)	     |
- * 0x10400 (65K)           +-----------------------------------------+
- *                         |      Exception Handlers (CPU 2)         |
- * 0x10000 (64K)           +-----------------------------------------+
- *                         |                                         |
- *                         |      Unused                             |
- *                         |                                         |
- * 0x0b400 (45K)           +-----------------------------------------+
- *                         |      GDA (1k)                           |
- * 0x0b000 (44K)           +-----------------------------------------+
- *                         |      NMI Eframe areas (4)       	     |
- * 0x0a000 (40K)           +-----------------------------------------+
- *                         |      NMI Register save areas (4)        |
- * 0x09000 (36K)           +-----------------------------------------+
- *                         |      Early cache Exception stack (CPU 1)|
- * 0x08800 (34K)           +-----------------------------------------+
- *			   |      cache error eframe (CPU 1)	     |
- * 0x08400 (33K)           +-----------------------------------------+
- *                         |      Exception Handlers (CPU 1)         |
- * 0x08000 (32K)           +-----------------------------------------+
- *                         |                                         |
- *                         |                                         |
- *                         |      Unused                             |
- *                         |                                         |
- *                         |                                         |
- * 0x04000 (16K)           +-----------------------------------------+
- *                         |      NMI Handler (Protected Page)       |
- * 0x03000 (12K)           +-----------------------------------------+
- *                         |      ARCS PVECTORS (master node only)   |
- * 0x02c00 (11K)           +-----------------------------------------+
- *                         |      ARCS TVECTORS (master node only)   |
- * 0x02800 (10K)           +-----------------------------------------+
- *                         |      LAUNCH [NUM_CPU]                   |
- * 0x02400 (9K)            +-----------------------------------------+
- *                         |      Low memory directory (KLDIR)       |
- * 0x02000 (8K)            +-----------------------------------------+
- *                         |      ARCS SPB (1K)                      |
- * 0x01000 (4K)            +-----------------------------------------+
- *                         |      Early cache Exception stack (CPU 0)|
- * 0x00800 (2k)	           +-----------------------------------------+
- *			   |      cache error eframe (CPU 0)	     |
- * 0x00400 (1K)            +-----------------------------------------+
- *                         |      Exception Handlers (CPU 0)         |
- * 0x00000 (0K)            +-----------------------------------------+
- */
-
-/*
- * NOTE:  To change the kernel load address, you must update:
- *  - the appropriate elspec files in irix/kern/master.d
- *  - NODEBUGUNIX_ADDR in SN/SN1/addrs.h
- *  - IP27_FREEMEM_OFFSET below
- *  - KERNEL_START_OFFSET below (if supporting cells)
- */
-
-
-/*
- * This is defined here because IP27_SYMMON_STK_SIZE must be at least what
- * we define here.  Since it's set up in the prom.  We can't redefine it later
- * and expect more space to be allocated.  The way to find out the true size
- * of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE
- * for a particular node.
- */
-#define SYMMON_STACK_SIZE		0x8000
-
-#if defined (PROM) || defined (SABLE)
-
-/*
- * These defines are prom version dependent.  No code other than the IP35
- * prom should attempt to use these values.
- */
-#define IP27_LAUNCH_OFFSET		0x2400
-#define IP27_LAUNCH_SIZE		0x400
-#define IP27_LAUNCH_COUNT		4
-#define IP27_LAUNCH_STRIDE		0x100 /* could be as small as 0x80 */
-
-#define IP27_KLCONFIG_OFFSET		0x30000
-#define IP27_KLCONFIG_SIZE		0x10000
-#define IP27_KLCONFIG_COUNT		1
-#define IP27_KLCONFIG_STRIDE		0
-
-#define IP27_NMI_OFFSET			0x3000
-#define IP27_NMI_SIZE			0x100
-#define IP27_NMI_COUNT			4
-#define IP27_NMI_STRIDE			0x40
-
-#define IP27_PI_ERROR_OFFSET		0x20000
-#define IP27_PI_ERROR_SIZE		0x10000
-#define IP27_PI_ERROR_COUNT		1
-#define IP27_PI_ERROR_STRIDE		0
-
-#define IP27_SYMMON_STK_OFFSET		0x4c000
-#define IP27_SYMMON_STK_SIZE		0x20000
-#define IP27_SYMMON_STK_COUNT		4
-/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */
-#define IP27_SYMMON_STK_STRIDE		0x8000
-
-#define IP27_FREEMEM_OFFSET		0x40000
-#define IP27_FREEMEM_SIZE		-1
-#define IP27_FREEMEM_COUNT		1
-#define IP27_FREEMEM_STRIDE		0
-
-#endif /* PROM || SABLE*/
-/*
- * There will be only one of these in a partition so the IO7 must set it up.
- */
-#define IO6_GDA_OFFSET			0xb000
-#define IO6_GDA_SIZE			0x400
-#define IO6_GDA_COUNT			1
-#define IO6_GDA_STRIDE			0
-
-/*
- * save area of kernel nmi regs in the prom format
- */
-#define IP27_NMI_KREGS_OFFSET		0x9000
-#define IP27_NMI_KREGS_CPU_SIZE		0x400
-/*
- * save area of kernel nmi regs in eframe format 
- */
-#define IP27_NMI_EFRAME_OFFSET		0xa000
-#define IP27_NMI_EFRAME_SIZE		0x400
-
-#define GPDA_OFFSET			0x11c00
-
-#endif /* _ASM_SN_SN1_KLDIR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/leds.h linux/include/asm-ia64/sn/sn1/leds.h
--- linux.orig/include/asm-ia64/sn/sn1/leds.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/leds.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,35 +0,0 @@
-#ifndef _ASM_SN_SN1_LED_H
-#define _ASM_SN_SN1_LED_H
-
-/*
- * Copyright (C) 2000 Silicon Graphics, Inc
- * Copyright (C) 2000 Jack Steiner (steiner@sgi.com)
- */
-
-#include <asm/smp.h>
-
-#define LED0		0xc0000b00100000c0LL	/* ZZZ fixme */
-
-
-
-#define LED_AP_START	0x01		/* AP processor started */
-#define LED_AP_IDLE	0x01
-
-/*
- * Basic macros for flashing the LEDS on an SGI, SN1.
- */
-
-extern __inline__ void
-HUB_SET_LED(int val)
-{
-	long	*ledp;
-	int	eid;
-
-	eid = hard_smp_processor_id() & 3;
-	ledp = (long*) (LED0 + (eid<<3));
-	*ledp = val;
-}
-
-
-#endif /* _ASM_SN_SN1_LED_H */
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/mem_refcnt.h linux/include/asm-ia64/sn/sn1/mem_refcnt.h
--- linux.orig/include/asm-ia64/sn/sn1/mem_refcnt.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/mem_refcnt.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,25 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN1_MEM_REFCNT_H
+#define _ASM_IA64_SN_SN1_MEM_REFCNT_H
+
+extern int mem_refcnt_attach(devfs_handle_t hub);
+extern int mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp);
+extern int mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp);
+extern int mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot);
+extern int mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt);
+extern int mem_refcnt_ioctl(devfs_handle_t dev,
+                 int cmd,
+                 void *arg,
+                 int mode,
+                 cred_t *cred_p,
+                 int *rvalp);
+        
+
+#endif /* _ASM_IA64_SN_SN1_MEM_REFCNT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/mmzone_sn1.h linux/include/asm-ia64/sn/sn1/mmzone_sn1.h
--- linux.orig/include/asm-ia64/sn/sn1/mmzone_sn1.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/mmzone_sn1.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,149 @@
+#ifndef _ASM_IA64_SN_MMZONE_SN1_H
+#define _ASM_IA64_SN_MMZONE_SN1_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/config.h>
+
+
+/*
+ * SGI SN1 Arch defined values
+ *
+ * 	An SN1 physical address is broken down as follows:
+ *
+ *             +-----------------------------------------+
+ *             |         |    |      |   node offset     |
+ *             | unused  | AS | node |-------------------|
+ *             |         |    |      | cn | clump offset |
+ *             +-----------------------------------------+
+ *              6       4 4  4 3    3 3  3 2            0
+ *              3       4 3  0 9    3 2  0 9            0
+ *
+ *		bits 63-44	Unused - must be zero
+ *		bits 43-40	Address space ID. Cached memory has a value of 0.
+ *				Chipset & IO addresses have non-zero values.
+ *		bits 39-33	Node number. Note that some configurations do NOT
+ *				have a node zero.
+ *		bits 32-0	Node offset.
+ *
+ *	The node offset can be further broken down as:
+ *		bits 32-30	Clump (bank) number.
+ *		bits 29-0	Clump (bank) offset.
+ *
+ *	A node consists of up to 8 clumps (banks) of memory. A clump may be empty, or may be
+ *	populated with a single contiguous block of memory starting at clump
+ *	offset 0. The size of the block is (2**n) * 64MB, where 0<n<5.
+ *
+ *
+ * NOTE: This file exports symbols prefixed with "PLAT_". Symbols prefixed with
+ *	 "SN_" are intended for internal use only and should not be used in
+ *	 any platform independent code. 
+ *
+ *	 This file is also responsible for exporting the following definitions:
+ *		cnodeid_t	Define a compact node id. 
+ */
+
+typedef signed short cnodeid_t;
+
+#define SN1_BANKS_PER_NODE		8
+#define SN1_NODE_SIZE			(8UL*1024*1024*1024)	/* 8 GB per node */
+#define SN1_BANK_SIZE			(SN1_NODE_SIZE/SN1_BANKS_PER_NODE)
+#define SN1_NODE_SHIFT			33
+#define SN1_NODE_MASK			0x7fUL
+#define SN1_NODE_OFFSET_MASK		(SN1_NODE_SIZE-1)
+#define SN1_NODE_NUMBER(addr)		(((unsigned long)(addr) >> SN1_NODE_SHIFT) & SN1_NODE_MASK)
+#define SN1_NODE_CLUMP_NUMBER(addr)	(((unsigned long)(addr) >>30) & 7)
+#define SN1_NODE_OFFSET(addr)		(((unsigned long)(addr)) & SN1_NODE_OFFSET_MASK)
+#define SN1_KADDR(nasid, offset)	(((unsigned long)(nasid)<<SN1_NODE_SHIFT) | (offset) | PAGE_OFFSET)
+
+
+#define PLAT_MAX_NODE_NUMBER		128			/* Maximum node number +1 */
+#define PLAT_MAX_COMPACT_NODES		128			/* Maximum number of nodes in SSI */
+
+#define PLAT_MAX_PHYS_MEMORY		(1UL << 40)
+
+
+
+/*
+ * On the SN platforms, a clump is the same as a memory bank.
+ */
+#define PLAT_CLUMPS_PER_NODE		SN1_BANKS_PER_NODE
+#define PLAT_CLUMP_OFFSET(addr)		((unsigned long)(addr) & 0x3fffffffUL)
+#define PLAT_CLUMPSIZE                  (SN1_NODE_SIZE/PLAT_CLUMPS_PER_NODE)
+#define PLAT_MAXCLUMPS			(PLAT_CLUMPS_PER_NODE*PLAT_MAX_COMPACT_NODES)
+
+
+
+
+/*
+ * PLAT_VALID_MEM_KADDR returns a boolean to indicate if a kaddr is potentially a
+ * valid cacheable identity mapped RAM memory address.
+ * Note that the RAM may or may not actually be present!!
+ */
+#define SN1_VALID_KERN_ADDR_MASK	0xffffff0000000000UL
+#define SN1_VALID_KERN_ADDR_VALUE	0xe000000000000000UL
+#define PLAT_VALID_MEM_KADDR(kaddr)	(((unsigned long)(kaddr) & SN1_VALID_KERN_ADDR_MASK) == SN1_VALID_KERN_ADDR_VALUE)
+
+
+
+/*
+ * Memory is conceptually divided into chunks. A chunk is either
+ * completely present, or else the kernel assumes it is completely
+ * absent. Each node consists of a number of possibly discontiguous chunks.
+ */
+#define SN1_CHUNKSHIFT			26			/* 64 MB */
+#define PLAT_CHUNKSIZE			(1UL << SN1_CHUNKSHIFT)
+#define PLAT_CHUNKNUM(addr)		(((addr) & (PLAT_MAX_PHYS_MEMORY-1)) >> SN1_CHUNKSHIFT)
+
+
+/*
+ * Given a kaddr, find the nid (compact nodeid)
+ */
+#ifdef CONFIG_IA64_SGI_SN_DEBUG
+#define DISCONBUG(kaddr)		panic("DISCONTIG BUG: line %d, %s. kaddr 0x%lx",	 	\
+						__LINE__, __FILE__, (long)(kaddr))
+
+#define KVADDR_TO_NID(kaddr)		({long _ktn=(long)(kaddr);					\
+						kern_addr_valid(_ktn) ? 				\
+						local_node_data->physical_node_map[SN1_NODE_NUMBER(_ktn)] :\
+						(DISCONBUG(_ktn), 0UL);})
+#else
+#define KVADDR_TO_NID(kaddr)		(local_node_data->physical_node_map[SN1_NODE_NUMBER(kaddr)])
+#endif
+
+
+
+/*
+ * Given a kaddr, find the index into the clump_mem_map_base array of the page struct entry
+ * for the first page of the clump.
+ */
+#define PLAT_CLUMP_MEM_MAP_INDEX(kaddr)		({long _kmmi=(long)(kaddr);				\
+							KVADDR_TO_NID(_kmmi) * PLAT_CLUMPS_PER_NODE +	\
+							SN1_NODE_CLUMP_NUMBER(_kmmi);})
+
+
+/*
+ * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
+ * nodes so that they dont alias to the same line in the cache as the previous allocated structure.
+ * This macro takes an address of the end of previous allocation, rounds it to a page boundary & 
+ * changes the node number.
+ */
+#define PLAT_BOOTMEM_ALLOC_GOAL(cnode,kaddr)	__pa(SN1_KADDR(PLAT_PXM_TO_PHYS_NODE_NUMBER(nid_to_pxm_map[cnode]),		\
+						  (SN1_NODE_OFFSET(kaddr) + PAGE_SIZE - 1) >> PAGE_SHIFT << PAGE_SHIFT))
+
+
+
+
+/*
+ * Convert a proximity domain number (from the ACPI tables) into a physical node number.
+ */
+
+#define PLAT_PXM_TO_PHYS_NODE_NUMBER(pxm)	(pxm)
+
+#endif /* _ASM_IA64_SN_MMZONE_SN1_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/promlog.h linux/include/asm-ia64/sn/sn1/promlog.h
--- linux.orig/include/asm-ia64/sn/sn1/promlog.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/promlog.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,85 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-#ifndef	_ASM_SN_SN1_PROMLOG_H
-#define	_ASM_SN_SN1_PROMLOG_H
-
-#include <asm/sn/fprom.h>
-
-#define PROMLOG_MAGIC			0x504c4f49
-#define PROMLOG_VERSION			1
-
-#define PROMLOG_OFFSET_MAGIC		0x10
-#define PROMLOG_OFFSET_VERSION		0x14
-#define PROMLOG_OFFSET_SEQUENCE		0x18
-#define PROMLOG_OFFSET_ENTRY0		0x100
-
-#define PROMLOG_ERROR_NONE		0
-#define PROMLOG_ERROR_PROM	       -1
-#define PROMLOG_ERROR_MAGIC	       -2
-#define PROMLOG_ERROR_CORRUPT	       -3
-#define PROMLOG_ERROR_BOL	       -4
-#define PROMLOG_ERROR_EOL	       -5
-#define PROMLOG_ERROR_POS	       -6
-#define PROMLOG_ERROR_REPLACE	       -7
-#define PROMLOG_ERROR_COMPACT	       -8
-#define PROMLOG_ERROR_FULL	       -9
-#define PROMLOG_ERROR_ARG	       -10
-#define PROMLOG_ERROR_UNUSED	       -11	  	
-
-#define PROMLOG_TYPE_UNUSED		0xf
-#define PROMLOG_TYPE_LOG		3
-#define PROMLOG_TYPE_LIST		2
-#define PROMLOG_TYPE_VAR		1
-#define PROMLOG_TYPE_DELETED		0
-
-#define PROMLOG_TYPE_ANY		98
-#define PROMLOG_TYPE_INVALID		99
-
-#define PROMLOG_KEY_MAX			14
-#define PROMLOG_VALUE_MAX		47
-#define PROMLOG_CPU_MAX			4
-
-typedef struct promlog_header_s {
-    unsigned int	unused[4];
-    unsigned int	magic;
-    unsigned int	version;
-    unsigned int	sequence;
-} promlog_header_t;
-
-typedef unsigned int promlog_pos_t;
-
-typedef struct promlog_ent_s {		/* PROM individual entry */
-    uint		type		: 4;
-    uint		cpu_num		: 4;
-    char		key[PROMLOG_KEY_MAX + 1];
-
-    char		value[PROMLOG_VALUE_MAX + 1];
-
-} promlog_ent_t;
-
-typedef struct promlog_s {		/* Activation handle */
-    fprom_t		f;
-    int			sector_base;
-    int			cpu_num;
-
-    int			active;		/* Active sector, 0 or 1 */
-
-    promlog_pos_t	log_start;
-    promlog_pos_t	log_end;
-
-    promlog_pos_t	alt_start;
-    promlog_pos_t	alt_end;
-
-    promlog_pos_t	pos;
-    promlog_ent_t	ent;
-} promlog_t;
-
-#endif /* _ASM_SN_SN1_PROMLOG_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/router.h linux/include/asm-ia64/sn/sn1/router.h
--- linux.orig/include/asm-ia64/sn/sn1/router.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/router.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,670 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-#ifndef	_ASM_SN_SN1_ROUTER_H
-#define	_ASM_SN_SN1_ROUTER_H
-
-/*
- * Router Register definitions
- *
- * Macro argument _L always stands for a link number (1 to 8, inclusive).
- */
-
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
-
-#include <asm/sn/vector.h>
-#include <asm/sn/slotnum.h>
-#include <asm/sn/arch.h>
-
-typedef uint64_t	router_reg_t;
-
-#define MAX_ROUTERS	64
-
-#define MAX_ROUTER_PATH	80
-
-#define ROUTER_REG_CAST		(volatile router_reg_t *)
-#define PS_UINT_CAST		(__psunsigned_t)
-#define UINT64_CAST		(uint64_t)
-typedef signed char port_no_t;	 /* Type for router port number      */
-
-#elif _LANGUAGE_ASSEMBLY
-
-#define ROUTERREG_CAST
-#define PS_UINT_CAST
-#define UINT64_CAST
-
-#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
-
-#define MAX_ROUTER_PORTS (8)	 /* Max. number of ports on a router */
-
-#define ALL_PORTS ((1 << MAX_ROUTER_PORTS) - 1)	/* for 0 based references */
-
-#define PORT_INVALID (-1)	 /* Invalid port number              */
-
-#define	IS_META(_rp)	((_rp)->flags & PCFG_ROUTER_META)
-
-#define	IS_REPEATER(_rp)((_rp)->flags & PCFG_ROUTER_REPEATER)
-
-/*
- * RR_TURN makes a given number of clockwise turns (0 to 7) from an inport
- * port to generate an output port.
- *
- * RR_DISTANCE returns the number of turns necessary (0 to 7) to go from
- * an input port (_L1 = 1 to 8) to an output port ( _L2 = 1 to 8).
- *
- * These are written to work on unsigned data.
- */
-
-#define RR_TURN(_L, count)	((_L) + (count) > MAX_ROUTER_PORTS ?	\
-				 (_L) + (count) - MAX_ROUTER_PORTS :	\
-				 (_L) + (count))
-
-#define RR_DISTANCE(_LS, _LD)	((_LD) >= (_LS) ?			\
-				 (_LD) - (_LS) :			\
-				 (_LD) + MAX_ROUTER_PORTS - (_LS))
-
-/* Router register addresses */
-
-#define RR_STATUS_REV_ID	0x00000	/* Status register and Revision ID  */
-#define RR_PORT_RESET		0x00008	/* Multiple port reset              */
-#define RR_PROT_CONF		0x00010	/* Inter-partition protection conf. */
-#define RR_GLOBAL_PORT_DEF	0x00018 /* Global Port definitions          */
-#define RR_GLOBAL_PARMS0	0x00020	/* Parameters shared by all 8 ports */
-#define RR_GLOBAL_PARMS1	0x00028	/* Parameters shared by all 8 ports */
-#define RR_DIAG_PARMS		0x00030	/* Parameters for diag. testing     */
-#define RR_DEBUG_ADDR		0x00038 /* Debug address select - debug port*/
-#define RR_LB_TO_L2		0x00040 /* Local Block to L2 cntrl intf reg */ 
-#define RR_L2_TO_LB		0x00048 /* L2 cntrl intf to Local Block reg */
-#define RR_JBUS_CONTROL		0x00050 /* read/write timing for JBUS intf  */
-
-#define RR_SCRATCH_REG0		0x00100	/* Scratch 0 is 64 bits */
-#define RR_SCRATCH_REG1		0x00108	/* Scratch 1 is 64 bits */
-#define RR_SCRATCH_REG2		0x00110	/* Scratch 2 is 64 bits */
-#define RR_SCRATCH_REG3		0x00118	/* Scratch 3 is 1 bit */
-#define RR_SCRATCH_REG4		0x00120	/* Scratch 4 is 1 bit */
-
-#define RR_JBUS0(_D)		(((_D) & 0x7) << 3 | 0x00200) /* JBUS0 addresses   */
-#define RR_JBUS1(_D)		(((_D) & 0x7) << 3 | 0x00240) /* JBUS1 addresses   */
-
-#define RR_SCRATCH_REG0_WZ	0x00500	/* Scratch 0 is 64 bits */
-#define RR_SCRATCH_REG1_WZ	0x00508	/* Scratch 1 is 64 bits */
-#define RR_SCRATCH_REG2_WZ	0x00510	/* Scratch 2 is 64 bits */
-#define RR_SCRATCH_REG3_SZ	0x00518	/* Scratch 3 is 1 bit */
-#define RR_SCRATCH_REG4_SZ	0x00520	/* Scratch 4 is 1 bit */
-
-#define RR_VECTOR_HW_BAR(context) (0x08000 | (context)<<3) /* barrier config registers */
-/* Port-specific registers (_L is the link number from 1 to 8) */
-
-#define RR_PORT_PARMS(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0000) /* LLP parameters     */
-#define RR_STATUS_ERROR(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0008) /* Port-related errs  */
-#define RR_CHANNEL_TEST(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0010) /* Port LLP chan test */
-#define RR_RESET_MASK(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0018) /* Remote reset mask  */
-#define RR_HISTOGRAM0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0020) /* Port usage histgrm */
-#define RR_HISTOGRAM1(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0028) /* Port usage histgrm */
-#define RR_HISTOGRAM0_WC(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0030) /* Port usage histgrm */
-#define RR_HISTOGRAM1_WC(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0038) /* Port usage histgrm */
-#define RR_ERROR_CLEAR(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0088) /* Read/clear errors  */
-#define RR_GLOBAL_TABLE0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0100) /* starting address of global table for this port */
-#define RR_GLOBAL_TABLE(_L, _x) (RR_GLOBAL_TABLE0(_L) + ((_x) << 3))
-#define RR_LOCAL_TABLE0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0200) /* starting address of local table for this port */
-#define RR_LOCAL_TABLE(_L, _x) (RR_LOCAL_TABLE0(_L) + ((_x) << 3))
-
-#define RR_META_ENTRIES		16
-
-#define RR_LOCAL_ENTRIES	128
-
-/*
- * RR_STATUS_REV_ID mask and shift definitions
- */
-
-#define RSRI_INPORT_SHFT	52
-#define RSRI_INPORT_MASK	(UINT64_CAST 0xf << 52)
-#define RSRI_LINKWORKING_BIT(_L) (35 + 2 * (_L))
-#define RSRI_LINKWORKING(_L)	(UINT64_CAST 1 << (35 + 2 * (_L)))
-#define RSRI_LINKRESETFAIL(_L)	(UINT64_CAST 1 << (34 + 2 * (_L)))
-#define RSRI_LSTAT_SHFT(_L)	(34 + 2 * (_L))
-#define RSRI_LSTAT_MASK(_L)	(UINT64_CAST 0x3 << 34 + 2 * (_L))
-#define RSRI_LOCALSBERROR	(UINT64_CAST 1 << 35)
-#define RSRI_LOCALSTUCK		(UINT64_CAST 1 << 34)
-#define RSRI_LOCALBADVEC	(UINT64_CAST 1 << 33)
-#define RSRI_LOCALTAILERR	(UINT64_CAST 1 << 32)
-#define RSRI_LOCAL_SHFT 	32
-#define RSRI_LOCAL_MASK		(UINT64_CAST 0xf << 32)
-#define RSRI_CHIPREV_SHFT	28
-#define RSRI_CHIPREV_MASK	(UINT64_CAST 0xf << 28)
-#define RSRI_CHIPID_SHFT	12
-#define RSRI_CHIPID_MASK	(UINT64_CAST 0xffff << 12)
-#define RSRI_MFGID_SHFT		1
-#define RSRI_MFGID_MASK		(UINT64_CAST 0x7ff << 1)
-
-#define RSRI_LSTAT_WENTDOWN	0
-#define RSRI_LSTAT_RESETFAIL	1
-#define RSRI_LSTAT_LINKUP	2
-#define RSRI_LSTAT_NOTUSED	3
-
-/*
- * RR_PORT_RESET mask definitions
- */
-
-#define RPRESET_WARM		(UINT64_CAST 1 << 9)
-#define RPRESET_LINK(_L)	(UINT64_CAST 1 << (_L))
-#define RPRESET_LOCAL		(UINT64_CAST 1)
-
-/*
- * RR_PROT_CONF mask and shift definitions
- */
-
-#define RPCONF_DIRCMPDIS_SHFT	13
-#define RPCONF_DIRCMPDIS_MASK	(UINT64_CAST 1 << 13)
-#define RPCONF_FORCELOCAL	(UINT64_CAST 1 << 12)
-#define RPCONF_FLOCAL_SHFT	12
-#define RPCONF_METAID_SHFT	8
-#define RPCONF_METAID_MASK	(UINT64_CAST 0xf << 8)
-#define RPCONF_RESETOK(_L)	(UINT64_CAST 1 << ((_L) - 1))
-
-/*
- * RR_GLOBAL_PORT_DEF mask and shift definitions
- */
-
-#define RGPD_MGLBLNHBR_ID_SHFT	12	/* -global neighbor ID */
-#define RGPD_MGLBLNHBR_ID_MASK	(UINT64_CAST 0xf << 12)
-#define RGPD_MGLBLNHBR_VLD_SHFT	11	/* -global neighbor Valid */
-#define RGPD_MGLBLNHBR_VLD_MASK	(UINT64_CAST 0x1 << 11)
-#define RGPD_MGLBLPORT_SHFT	8	/* -global neighbor Port */
-#define RGPD_MGLBLPORT_MASK	(UINT64_CAST 0x7 << 8)
-#define RGPD_PGLBLNHBR_ID_SHFT	4	/* +global neighbor ID */
-#define RGPD_PGLBLNHBR_ID_MASK	(UINT64_CAST 0xf << 4)
-#define RGPD_PGLBLNHBR_VLD_SHFT	3	/* +global neighbor Valid */
-#define RGPD_PGLBLNHBR_VLD_MASK	(UINT64_CAST 0x1 << 3)
-#define RGPD_PGLBLPORT_SHFT	0	/* +global neighbor Port */
-#define RGPD_PGLBLPORT_MASK	(UINT64_CAST 0x7 << 0)
-
-#define GLBL_PARMS_REGS		2	/* Two Global Parms registers */
-
-/*
- * RR_GLOBAL_PARMS0 mask and shift definitions
- */
-
-#define RGPARM0_ARB_VALUE_SHFT	54	/* Local Block Arbitration State */
-#define RGPARM0_ARB_VALUE_MASK	(UINT64_CAST 0x7 << 54)
-#define RGPARM0_ROTATEARB_SHFT	53	/* Rotate Local Block Arbitration */
-#define RGPARM0_ROTATEARB_MASK	(UINT64_CAST 0x1 << 53)
-#define RGPARM0_FAIREN_SHFT	52	/* Fairness logic Enable */
-#define RGPARM0_FAIREN_MASK	(UINT64_CAST 0x1 << 52)
-#define RGPARM0_LOCGNTTO_SHFT	40	/* Local grant timeout */
-#define RGPARM0_LOCGNTTO_MASK	(UINT64_CAST 0xfff << 40)
-#define RGPARM0_DATELINE_SHFT	38	/* Dateline crossing router */
-#define RGPARM0_DATELINE_MASK	(UINT64_CAST 0x1 << 38)
-#define RGPARM0_MAXRETRY_SHFT	28	/* Max retry count */
-#define RGPARM0_MAXRETRY_MASK	(UINT64_CAST 0x3ff << 28)
-#define RGPARM0_URGWRAP_SHFT	20	/* Urgent wrap */
-#define RGPARM0_URGWRAP_MASK	(UINT64_CAST 0xff << 20)
-#define RGPARM0_DEADLKTO_SHFT	16	/* Deadlock timeout */
-#define RGPARM0_DEADLKTO_MASK	(UINT64_CAST 0xf << 16)
-#define RGPARM0_URGVAL_SHFT	12	/* Urgent value */
-#define RGPARM0_URGVAL_MASK	(UINT64_CAST 0xf << 12)
-#define RGPARM0_VCHSELEN_SHFT	11	/* VCH_SEL_EN */
-#define RGPARM0_VCHSELEN_MASK	(UINT64_CAST 0x1 << 11)
-#define RGPARM0_LOCURGTO_SHFT	9	/* Local urgent timeout */
-#define RGPARM0_LOCURGTO_MASK	(UINT64_CAST 0x3 << 9)
-#define RGPARM0_TAILVAL_SHFT	5	/* Tail value */
-#define RGPARM0_TAILVAL_MASK	(UINT64_CAST 0xf << 5)
-#define RGPARM0_CLOCK_SHFT	1	/* Global clock select */
-#define RGPARM0_CLOCK_MASK	(UINT64_CAST 0xf << 1)
-#define RGPARM0_BYPEN_SHFT	0
-#define RGPARM0_BYPEN_MASK	(UINT64_CAST 1)	/* Bypass enable */
-
-/*
- * RR_GLOBAL_PARMS1 shift and mask definitions
- */
-
-#define RGPARM1_TTOWRAP_SHFT	12	/* Tail timeout wrap */
-#define RGPARM1_TTOWRAP_MASK	(UINT64_CAST 0xfffff << 12)
-#define RGPARM1_AGERATE_SHFT	8	/* Age rate */
-#define RGPARM1_AGERATE_MASK	(UINT64_CAST 0xf << 8)
-#define RGPARM1_JSWSTAT_SHFT	0	/* JTAG Sw Register bits */
-#define RGPARM1_JSWSTAT_MASK	(UINT64_CAST 0xff << 0)
-
-/*
- * RR_DIAG_PARMS mask and shift definitions
- */
-
-#define RDPARM_ABSHISTOGRAM	(UINT64_CAST 1 << 17)	/* Absolute histgrm */
-#define RDPARM_DEADLOCKRESET	(UINT64_CAST 1 << 16)	/* Reset on deadlck */
-#define RDPARM_DISABLE(_L)	(UINT64_CAST 1 << ((_L) +  7))
-#define RDPARM_SENDERROR(_L)	(UINT64_CAST 1 << ((_L) -  1))
-
-/*
- * RR_DEBUG_ADDR mask and shift definitions
- */
-
-#define RDA_DATA_SHFT		10	/* Observed debug data */
-#define RDA_DATA_MASK		(UINT64_CAST 0xffff << 10)
-#define RDA_ADDR_SHFT		0	/* debug address for data */
-#define RDA_ADDR_MASK		(UINT64_CAST 0x3ff << 0)
-
-/*
- * RR_LB_TO_L2 mask and shift definitions
- */
-
-#define RLBTOL2_DATA_VLD_SHFT	32	/* data is valid for JTAG controller */
-#define RLBTOL2_DATA_VLD_MASK	(UINT64_CAST 0x1 << 32)
-#define RLBTOL2_DATA_SHFT	0	/* data bits for JTAG controller */
-#define RLBTOL2_DATA_MASK	(UINT64_CAST 0xffffffff)
-
-/*
- * RR_L2_TO_LB mask and shift definitions
- */
-
-#define RL2TOLB_DATA_VLD_SHFT	33	/* data is valid from JTAG controller */
-#define RL2TOLB_DATA_VLD_MASK	(UINT64_CAST 0x1 << 33)
-#define RL2TOLB_PARITY_SHFT	32	/* sw implemented parity for data */
-#define RL2TOLB_PARITY_MASK	(UINT64_CAST 0x1 << 32)
-#define RL2TOLB_DATA_SHFT	0	/* data bits from JTAG controller */
-#define RL2TOLB_DATA_MASK	(UINT64_CAST 0xffffffff)
-
-/*
- * RR_JBUS_CONTROL mask and shift definitions
- */
-
-#define RJC_POS_BITS_SHFT	20	/* Router position bits */
-#define RJC_POS_BITS_MASK	(UINT64_CAST 0xf << 20)
-#define RJC_RD_DATA_STROBE_SHFT	16	/* count when read data is strobed in */
-#define RJC_RD_DATA_STROBE_MASK	(UINT64_CAST 0xf << 16)
-#define RJC_WE_OE_HOLD_SHFT	8	/* time OE or WE is held */
-#define RJC_WE_OE_HOLD_MASK	(UINT64_CAST 0xff << 8)
-#define RJC_ADDR_SET_HLD_SHFT	0	/* time address driven around OE/WE */
-#define RJC_ADDR_SET_HLD_MASK	(UINT64_CAST 0xff)
-
-/*
- * RR_SCRATCH_REGx mask and shift definitions
- *  note: these fields represent a software convention, and are not
- *        understood/interpreted by the hardware. 
- */
-
-#define	RSCR0_BOOTED_SHFT	63
-#define	RSCR0_BOOTED_MASK	(UINT64_CAST 0x1 << RSCR0_BOOTED_SHFT)
-#define RSCR0_LOCALID_SHFT	56
-#define RSCR0_LOCALID_MASK	(UINT64_CAST 0x7f << RSCR0_LOCALID_SHFT)
-#define	RSCR0_UNUSED_SHFT	48
-#define	RSCR0_UNUSED_MASK	(UINT64_CAST 0xff << RSCR0_UNUSED_SHFT)
-#define RSCR0_NIC_SHFT		0
-#define RSCR0_NIC_MASK		(UINT64_CAST 0xffffffffffff)
-
-#define RSCR1_MODID_SHFT	0
-#define RSCR1_MODID_MASK	(UINT64_CAST 0xffff)
-
-/*
- * RR_VECTOR_HW_BAR mask and shift definitions
- */
-
-#define BAR_TX_SHFT		27	/* Barrier in trans(m)it when read */
-#define BAR_TX_MASK		(UINT64_CAST 1 << BAR_TX_SHFT)
-#define BAR_VLD_SHFT		26	/* Valid Configuration */
-#define BAR_VLD_MASK		(UINT64_CAST 1 << BAR_VLD_SHFT)
-#define BAR_SEQ_SHFT		24	/* Sequence number */
-#define BAR_SEQ_MASK		(UINT64_CAST 3 << BAR_SEQ_SHFT)
-#define BAR_LEAFSTATE_SHFT	18	/* Leaf State */
-#define BAR_LEAFSTATE_MASK	(UINT64_CAST 0x3f << BAR_LEAFSTATE_SHFT)
-#define BAR_PARENT_SHFT		14	/* Parent Port */
-#define BAR_PARENT_MASK		(UINT64_CAST 0xf << BAR_PARENT_SHFT)
-#define BAR_CHILDREN_SHFT	6	/* Child Select port bits */
-#define BAR_CHILDREN_MASK	(UINT64_CAST 0xff << BAR_CHILDREN_SHFT)
-#define BAR_LEAFCOUNT_SHFT	0	/* Leaf Count to trigger parent */
-#define BAR_LEAFCOUNT_MASK	(UINT64_CAST 0x3f)
-
-/*
- * RR_PORT_PARMS(_L) mask and shift definitions
- */
-
-#define RPPARM_MIPRESETEN_SHFT	29	/* Message In Progress reset enable */
-#define RPPARM_MIPRESETEN_MASK	(UINT64_CAST 0x1 << 29)
-#define RPPARM_UBAREN_SHFT	28	/* Enable user barrier requests */
-#define RPPARM_UBAREN_MASK	(UINT64_CAST 0x1 << 28)
-#define RPPARM_OUTPDTO_SHFT	24	/* Output Port Deadlock TO value */
-#define RPPARM_OUTPDTO_MASK	(UINT64_CAST 0xf << 24)
-#define RPPARM_PORTMATE_SHFT	21	/* Port Mate for the port */
-#define RPPARM_PORTMATE_MASK	(UINT64_CAST 0x7 << 21)
-#define RPPARM_HISTEN_SHFT	20	/* Histogram counter enable */
-#define RPPARM_HISTEN_MASK	(UINT64_CAST 0x1 << 20)
-#define RPPARM_HISTSEL_SHFT	18
-#define RPPARM_HISTSEL_MASK	(UINT64_CAST 0x3 << 18)
-#define RPPARM_DAMQHS_SHFT	16
-#define RPPARM_DAMQHS_MASK	(UINT64_CAST 0x3 << 16)
-#define RPPARM_NULLTO_SHFT	10
-#define RPPARM_NULLTO_MASK	(UINT64_CAST 0x3f << 10)
-#define RPPARM_MAXBURST_SHFT	0
-#define RPPARM_MAXBURST_MASK	(UINT64_CAST 0x3ff)
-
-/*
- * NOTE: Normally the kernel tracks only UTILIZATION statistics.
- * The other 2 should not be used, except during any experimentation
- * with the router.
- */
-#define RPPARM_HISTSEL_AGE	0	/* Histogram age characterization.  */
-#define RPPARM_HISTSEL_UTIL	1	/* Histogram link utilization 	    */
-#define RPPARM_HISTSEL_DAMQ	2	/* Histogram DAMQ characterization. */
-
-/*
- * RR_STATUS_ERROR(_L) and RR_ERROR_CLEAR(_L) mask and shift definitions
- */
-#define RSERR_POWERNOK		(UINT64_CAST 1 << 38)
-#define RSERR_PORT_DEADLOCK     (UINT64_CAST 1 << 37)
-#define RSERR_WARMRESET         (UINT64_CAST 1 << 36)
-#define RSERR_LINKRESET         (UINT64_CAST 1 << 35)
-#define RSERR_RETRYTIMEOUT      (UINT64_CAST 1 << 34)
-#define RSERR_FIFOOVERFLOW	(UINT64_CAST 1 << 33)
-#define RSERR_ILLEGALPORT	(UINT64_CAST 1 << 32)
-#define RSERR_DEADLOCKTO_SHFT	28
-#define RSERR_DEADLOCKTO_MASK	(UINT64_CAST 0xf << 28)
-#define RSERR_RECVTAILTO_SHFT	24
-#define RSERR_RECVTAILTO_MASK	(UINT64_CAST 0xf << 24)
-#define RSERR_RETRYCNT_SHFT	16
-#define RSERR_RETRYCNT_MASK	(UINT64_CAST 0xff << 16)
-#define RSERR_CBERRCNT_SHFT	8
-#define RSERR_CBERRCNT_MASK	(UINT64_CAST 0xff << 8)
-#define RSERR_SNERRCNT_SHFT	0
-#define RSERR_SNERRCNT_MASK	(UINT64_CAST 0xff << 0)
-
-
-#define PORT_STATUS_UP		(1 << 0)	/* Router link up */
-#define PORT_STATUS_FENCE	(1 << 1)	/* Router link fenced */
-#define PORT_STATUS_RESETFAIL	(1 << 2)	/* Router link didnot 
-						 * come out of reset */
-#define PORT_STATUS_DISCFAIL	(1 << 3)	/* Router link failed after 
-						 * out of reset but before
-						 * router tables were
-						 * programmed
-						 */
-#define PORT_STATUS_KERNFAIL	(1 << 4)	/* Router link failed
-						 * after reset and the 
-						 * router tables were
-						 * programmed
-						 */
-#define PORT_STATUS_UNDEF	(1 << 5)	/* Unable to pinpoint
-						 * why the router link
-						 * went down
-						 */	
-#define PROBE_RESULT_BAD	(-1)		/* Set if any of the router
-						 * links failed after reset
-						 */
-#define PROBE_RESULT_GOOD	(0)		/* Set if all the router links
-						 * which came out of reset 
-						 * are up
-						 */
-
-/* Should be enough for 256 CPUs */
-#define MAX_RTR_BREADTH		64		/* Max # of routers possible */
-
-/* Get the require set of bits in a var. corr to a sequence of bits  */
-#define GET_FIELD(var, fname) \
-        ((var) >> fname##_SHFT & fname##_MASK >> fname##_SHFT)
-/* Set the require set of bits in a var. corr to a sequence of bits  */
-#define SET_FIELD(var, fname, fval) \
-        ((var) = (var) & ~fname##_MASK | (uint64_t) (fval) << fname##_SHFT)
-
-
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
-
-typedef struct router_map_ent_s {
-	uint64_t	nic;
-	moduleid_t	module;
-	slotid_t	slot;
-} router_map_ent_t;
-
-struct rr_status_error_fmt {
-	uint64_t	rserr_unused		: 30,
-			rserr_fifooverflow	: 1,
-			rserr_illegalport	: 1,
-			rserr_deadlockto	: 4,
-			rserr_recvtailto	: 4,
-			rserr_retrycnt		: 8,
-			rserr_cberrcnt		: 8,
-			rserr_snerrcnt		: 8;
-};
-
-/*
- * This type is used to store "absolute" counts of router events
- */
-typedef int	router_count_t;
-
-/* All utilizations are on a scale from 0 - 1023. */
-#define RP_BYPASS_UTIL	0
-#define RP_RCV_UTIL	1
-#define RP_SEND_UTIL	2
-#define RP_TOTAL_PKTS	3	/* Free running clock/packet counter */
-
-#define RP_NUM_UTILS	3
-
-#define RP_HIST_REGS	2
-#define RP_NUM_BUCKETS  4
-#define RP_HIST_TYPES	3
-
-#define RP_AGE0		0
-#define RP_AGE1		1
-#define RP_AGE2		2
-#define RP_AGE3		3
-
-
-#define RR_UTIL_SCALE	1024
-
-/*
- * Router port-oriented information
- */
-typedef struct router_port_info_s {
-	router_reg_t	rp_histograms[RP_HIST_REGS];/* Port usage info */
-	router_reg_t	rp_port_error;		/* Port error info */
-	router_count_t	rp_retry_errors;	/* Total retry errors */
-	router_count_t	rp_sn_errors;		/* Total sn errors */
-	router_count_t	rp_cb_errors;		/* Total cb errors */
-	int		rp_overflows;		/* Total count overflows */
-	int		rp_excess_err;		/* Port has excessive errors */
-	ushort		rp_util[RP_NUM_BUCKETS];/* Port utilization */
-} router_port_info_t;
-
-#define ROUTER_INFO_VERSION	7
-
-struct lboard_s;
-
-/*
- * Router information
- */
-typedef struct router_info_s {
-	char		ri_version;	/* structure version		    */
-	cnodeid_t	ri_cnode;	/* cnode of its legal guardian hub  */
-	nasid_t		ri_nasid;	/* Nasid of same 		    */
-	char		ri_ledcache;	/* Last LED bitmap		    */
-	char		ri_leds;	/* Current LED bitmap		    */
-	char		ri_portmask;	/* Active port bitmap		    */
-	router_reg_t	ri_stat_rev_id;	/* Status rev ID value		    */
-	net_vec_t	ri_vector;	/* vector from guardian to router   */
-	int		ri_writeid;	/* router's vector write ID	    */
-	int64_t	ri_timebase;	/* Time of first sample		    */
-	int64_t	ri_timestamp;	/* Time of last sample		    */
-	router_port_info_t ri_port[MAX_ROUTER_PORTS]; /* per port info      */
-	moduleid_t	ri_module;	/* Which module are we in?	    */
-	slotid_t	ri_slotnum;	/* Which slot are we in?	    */
-	router_reg_t	ri_glbl_parms[GLBL_PARMS_REGS];
-					/* Global parms0&1 register contents*/
-	devfs_handle_t	ri_vertex;	/* hardware graph vertex            */
-	router_reg_t	ri_prot_conf;	/* protection config. register	    */
-	int64_t	ri_per_minute;	/* Ticks per minute		    */
-
-	/*
-	 * Everything below here is for kernel use only and may change at	
-	 * at any time with or without a change in teh revision number
-	 *
-	 * Any pointers or things that come and go with DEBUG must go at
- 	 * the bottom of the structure, below the user stuff.
-	 */
-	char		ri_hist_type;   /* histogram type		    */
-	devfs_handle_t	ri_guardian;	/* guardian node for the router	    */
-	int64_t	ri_last_print;	/* When did we last print	    */
-	char		ri_print;	/* Should we print 		    */
-	char 		ri_just_blink;	/* Should we blink the LEDs         */
-	
-#ifdef DEBUG
-	int64_t	ri_deltatime;	/* Time it took to sample	    */
-#endif
-	spinlock_t	ri_lock;	/* Lock for access to router info   */
-	net_vec_t	*ri_vecarray;	/* Pointer to array of vectors	    */
-	struct lboard_s	*ri_brd;	/* Pointer to board structure	    */
-	char *		ri_name;	/* This board's hwg path 	    */
-        unsigned char	ri_port_maint[MAX_ROUTER_PORTS]; /* should we send a 
-					message to availmon */
-} router_info_t;
-
-
-/* Router info location specifiers */
-
-#define RIP_PROMLOG			2	/* Router info in promlog */
-#define RIP_CONSOLE			4	/* Router info on console */
-
-#define ROUTER_INFO_PRINT(_rip,_where)	(_rip->ri_print |= _where)	
-					/* Set the field used to check if a 
-					 * router info can be printed
-					 */
-#define IS_ROUTER_INFO_PRINTED(_rip,_where)	\
-					(_rip->ri_print & _where)	
-					/* Was the router info printed to
-					 * the given location (_where) ?
-					 * Mainly used to prevent duplicate
-					 * router error states.
-					 */
-#define ROUTER_INFO_LOCK(_rip,_s)	_s = mutex_spinlock(&(_rip->ri_lock))
-					/* Take the lock on router info
-					 * to gain exclusive access
-					 */
-#define ROUTER_INFO_UNLOCK(_rip,_s)	mutex_spinunlock(&(_rip->ri_lock),_s)
-					/* Release the lock on router info */
-/* 
- * Router info hanging in the nodepda 
- */
-typedef struct nodepda_router_info_s {
-	devfs_handle_t 	router_vhdl;	/* vertex handle of the router 	    */
-	short		router_port;	/* port thru which we entered       */
-	short		router_portmask;
-	moduleid_t	router_module;	/* module in which router is there  */
-	slotid_t	router_slot;	/* router slot			    */
-	unsigned char	router_type;	/* kind of router 		    */
-	net_vec_t	router_vector;	/* vector from the guardian node    */
-
-	router_info_t	*router_infop;	/* info hanging off the hwg vertex  */
-	struct nodepda_router_info_s *router_next;
-	                                /* pointer to next element 	    */
-} nodepda_router_info_t;
-
-#define ROUTER_NAME_SIZE	20	/* Max size of a router name */
-
-#define NORMAL_ROUTER_NAME	"normal_router"
-#define NULL_ROUTER_NAME	"null_router"
-#define META_ROUTER_NAME	"meta_router"
-#define REPEATER_ROUTER_NAME	"repeater_router"
-#define UNKNOWN_ROUTER_NAME	"unknown_router" 
-
-/* The following definitions are needed by the router traversing
- * code either using the hardware graph or using vector operations.
- */
-/* Structure of the router queue element */
-typedef struct router_elt_s {
-	union {
-		/* queue element structure during router probing */
-		struct {
-			/* number-in-a-can (unique) for the router */
-			nic_t		nic;	
-			/* vector route from the master hub to 
-			 * this router.
-			 */
-			net_vec_t	vec;	
-			/* port status */
-			uint64_t	status;	
-			char		port_status[MAX_ROUTER_PORTS + 1];
-		} r_elt;
-		/* queue element structure during router guardian 
-		 * assignment
-		 */
-		struct {
-			/* vertex handle for the router */
-			devfs_handle_t	vhdl;
-			/* guardian for this router */
-			devfs_handle_t	guard;	
-			/* vector router from the guardian to the router */
-			net_vec_t	vec;
-		} k_elt;
-	} u;
-	                        /* easy to use port status interpretation */
-} router_elt_t;
-
-/* structure of the router queue */
-
-typedef struct router_queue_s {
-	char		head;	/* Point where a queue element is inserted */
-	char		tail;	/* Point where a queue element is removed */
-	int		type;
-	router_elt_t	array[MAX_RTR_BREADTH];
-	                        /* Entries for queue elements */
-} router_queue_t;
-
-
-#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
-
-/*
- * RR_HISTOGRAM(_L) mask and shift definitions
- * There are two 64 bit histogram registers, so the following macros take
- * into account dealing with an array of 4 32 bit values indexed by _x
- */
-
-#define RHIST_BUCKET_SHFT(_x)	(32 * ((_x) & 0x1))
-#define RHIST_BUCKET_MASK(_x)	(UINT64_CAST 0xffffffff << RHIST_BUCKET_SHFT((_x) & 0x1))
-#define RHIST_GET_BUCKET(_x, _reg)	\
-	((RHIST_BUCKET_MASK(_x) & ((_reg)[(_x) >> 1])) >> RHIST_BUCKET_SHFT(_x))
-
-/*
- * RR_RESET_MASK(_L) mask and shift definitions
- */
-
-#define RRM_RESETOK(_L)		(UINT64_CAST 1 << ((_L) - 1))
-#define RRM_RESETOK_ALL		ALL_PORTS
-
-/*
- * RR_META_TABLE(_x) and RR_LOCAL_TABLE(_x) mask and shift definitions
- */
-
-#define RTABLE_SHFT(_L)		(4 * ((_L) - 1))
-#define RTABLE_MASK(_L)		(UINT64_CAST 0x7 << RTABLE_SHFT(_L))
-
-
-#define	ROUTERINFO_STKSZ	4096
-
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
-#if defined(_LANGUAGE_C_PLUS_PLUS)
-extern "C" {
-#endif
-
-int router_reg_read(router_info_t *rip, int regno, router_reg_t *val);
-int router_reg_write(router_info_t *rip, int regno, router_reg_t val);
-int router_get_info(devfs_handle_t routerv, router_info_t *, int);
-int router_init(cnodeid_t cnode,int writeid, nodepda_router_info_t *npda_rip);
-int router_set_leds(router_info_t *rip);
-void router_print_state(router_info_t *rip, int level,
-		   void (*pf)(int, char *, ...),int print_where);
-void capture_router_stats(router_info_t *rip);
-
-
-int 	probe_routers(void);
-void 	get_routername(unsigned char brd_type,char *rtrname);
-void 	router_guardians_set(devfs_handle_t hwgraph_root);
-int 	router_hist_reselect(router_info_t *, int64_t);
-#if defined(_LANGUAGE_C_PLUS_PLUS)
-}
-#endif
-#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
-
-#endif /* _ASM_SN_SN1_ROUTER_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/slotnum.h linux/include/asm-ia64/sn/sn1/slotnum.h
--- linux.orig/include/asm-ia64/sn/sn1/slotnum.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/slotnum.h	2002-07-20 01:08:34.000000000 +0000
@@ -4,12 +4,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef _ASM_SN_SN1_SLOTNUM_H
-#define _ASM_SN_SN1_SLOTNUM_H
+#ifndef _ASM_IA64_SN_SN1_SLOTNUM_H
+#define _ASM_IA64_SN_SN1_SLOTNUM_H
 
 #define SLOTNUM_MAXLENGTH	16
 
@@ -85,4 +84,4 @@
 
 #endif /* __KERNEL__ */
 
-#endif /* _ASM_SN_SN1_SLOTNUM_H */
+#endif /* _ASM_IA64_SN_SN1_SLOTNUM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/sn1.h linux/include/asm-ia64/sn/sn1/sn1.h
--- linux.orig/include/asm-ia64/sn/sn1/sn1.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/sn1.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,34 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-/*
- * sn1.h -- hardware specific defines for sn1 boards
- * The defines used here are used to limit the size of 
- * various datastructures in the PROM. eg. KLCFGINFO, MPCONF etc.
- */
-
-#ifndef _ASM_SN_SN1_SN1_H
-#define _ASM_SN_SN1_SN1_H
-
-extern xwidgetnum_t hub_widget_id(nasid_t);
-extern nasid_t get_nasid(void);
-extern int	get_slice(void);
-extern int     is_fine_dirmode(void);
-extern hubreg_t get_hub_chiprev(nasid_t nasid);
-extern hubreg_t get_region(cnodeid_t);
-extern hubreg_t nasid_to_region(nasid_t);
-extern int      verify_snchip_rev(void);
-extern void 	ni_reset_port(void);
-
-#ifdef SN1_USE_POISON_BITS
-extern int hub_bte_poison_ok(void);
-#endif /* SN1_USE_POISON_BITS */
-
-#endif /* _ASM_SN_SN1_SN1_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/sn_private.h linux/include/asm-ia64/sn/sn1/sn_private.h
--- linux.orig/include/asm-ia64/sn/sn1/sn_private.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/sn_private.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,292 @@
+/* $Id: sn_private.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN1_SN_PRIVATE_H
+#define _ASM_IA64_SN_SN1_SN_PRIVATE_H
+
+#include <asm/sn/nodepda.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/xtalk/xtalk_private.h>
+
+extern nasid_t master_nasid;
+
+/* promif.c */
+#ifdef	LATER
+extern cpuid_t cpu_node_probe(cpumask_t *cpumask, int *numnodes);
+#endif
+extern void he_arcs_set_vectors(void);
+extern void mem_init(void);
+#ifdef	LATER
+extern int cpu_enabled(cpuid_t);
+#endif
+extern void cpu_unenable(cpuid_t);
+extern nasid_t get_lowest_nasid(void);
+extern __psunsigned_t get_master_bridge_base(void);
+extern void set_master_bridge_base(void);
+extern int check_nasid_equiv(nasid_t, nasid_t);
+extern nasid_t get_console_nasid(void);
+extern char get_console_pcislot(void);
+#ifdef	LATER
+extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
+#endif
+
+extern int is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid);
+
+/* memsupport.c */
+extern void poison_state_alter_range(__psunsigned_t start, int len, int poison);
+extern int memory_present(paddr_t);
+extern int memory_read_accessible(paddr_t);
+extern int memory_write_accessible(paddr_t);
+extern void memory_set_access(paddr_t, int, int);
+extern void show_dir_state(paddr_t, void (*)(char *, ...));
+extern void check_dir_state(nasid_t, int, void (*)(char *, ...));
+extern void set_dir_owner(paddr_t, int);
+extern void set_dir_state(paddr_t, int);
+extern void set_dir_state_POISONED(paddr_t);
+extern void set_dir_state_UNOWNED(paddr_t);
+extern int is_POISONED_dir_state(paddr_t);
+extern int is_UNOWNED_dir_state(paddr_t);
+extern void get_dir_ent(paddr_t paddr, int *state,
+			uint64_t *vec_ptr, hubreg_t *elo);
+
+/* intr.c */
+extern int intr_reserve_level(cpuid_t cpu, int level, int err, devfs_handle_t owner_dev, char *name);
+extern void intr_unreserve_level(cpuid_t cpu, int level);
+extern int intr_connect_level(cpuid_t cpu, int bit, ilvl_t mask_no, 
+			intr_func_t intr_prefunc);
+extern int intr_disconnect_level(cpuid_t cpu, int bit);
+extern cpuid_t intr_heuristic(devfs_handle_t dev, device_desc_t dev_desc,
+			      int req_bit,int intr_resflags,devfs_handle_t owner_dev,
+			      char *intr_name,int *resp_bit);
+extern void intr_block_bit(cpuid_t cpu, int bit);
+extern void intr_unblock_bit(cpuid_t cpu, int bit);
+extern void setrtvector(intr_func_t);
+extern void install_cpuintr(cpuid_t cpu);
+extern void install_dbgintr(cpuid_t cpu);
+extern void install_tlbintr(cpuid_t cpu);
+extern void hub_migrintr_init(cnodeid_t /*cnode*/);
+extern int cause_intr_connect(int level, intr_func_t handler, uint intr_spl_mask);
+extern int cause_intr_disconnect(int level);
+extern void intr_reserve_hardwired(cnodeid_t);
+extern void intr_clear_all(nasid_t);
+extern void intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...));
+
+/* error_dump.c */
+extern char *hub_rrb_err_type[];
+extern char *hub_wrb_err_type[];
+
+void nmi_dump(void);
+void install_cpu_nmi_handler(int slice);
+
+/* klclock.c */
+extern void hub_rtc_init(cnodeid_t);
+
+/* bte.c */
+void bte_lateinit(void);
+void bte_wait_for_xfer_completion(void *);
+
+/* klgraph.c */
+void klhwg_add_all_nodes(devfs_handle_t);
+void klhwg_add_all_modules(devfs_handle_t);
+
+/* klidbg.c */
+void install_klidbg_functions(void);
+
+/* klnuma.c */
+extern void replicate_kernel_text(int numnodes);
+extern __psunsigned_t get_freemem_start(cnodeid_t cnode);
+extern void setup_replication_mask(int maxnodes);
+
+/* init.c */
+extern cnodeid_t get_compact_nodeid(void);	/* get compact node id */
+extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node);
+extern void init_platform_pda(cpuid_t cpu);
+extern void per_cpu_init(void);
+#ifdef	LATER
+extern cpumask_t boot_cpumask;
+#endif
+extern int is_fine_dirmode(void);
+extern void update_node_information(cnodeid_t);
+ 
+#ifdef	LATER
+/* clksupport.c */
+extern void early_counter_intr(eframe_t *);
+#endif
+
+/* hubio.c */
+extern void hubio_init(void);
+extern void hub_merge_clean(nasid_t nasid);
+extern void hub_set_piomode(nasid_t nasid, int conveyor);
+
+/* huberror.c */
+extern void hub_error_init(cnodeid_t);
+extern void dump_error_spool(cpuid_t cpu, void (*pf)(char *, ...));
+extern void hubni_error_handler(char *, int);
+extern int check_ni_errors(void);
+
+/* Used for debugger to signal upper software a breakpoint has taken place */
+
+extern void		*debugger_update;
+extern __psunsigned_t	debugger_stopped;
+
+/* 
+ * IP27 piomap, created by hub_pio_alloc.
+ * xtalk_info MUST BE FIRST, since this structure is cast to a
+ * xtalk_piomap_s by generic xtalk routines.
+ */
+struct hub_piomap_s {
+	struct xtalk_piomap_s	hpio_xtalk_info;/* standard crosstalk pio info */
+	devfs_handle_t		hpio_hub;	/* which hub's mapping registers are set up */
+	short			hpio_holdcnt;	/* count of current users of bigwin mapping */
+	char			hpio_bigwin_num;/* if big window map, which one */
+	int 			hpio_flags;	/* defined below */
+};
+/* hub_piomap flags */
+#define HUB_PIOMAP_IS_VALID		0x1
+#define HUB_PIOMAP_IS_BIGWINDOW		0x2
+#define HUB_PIOMAP_IS_FIXED		0x4
+
+#define	hub_piomap_xt_piomap(hp)	(&hp->hpio_xtalk_info)
+#define	hub_piomap_hub_v(hp)	(hp->hpio_hub)
+#define	hub_piomap_winnum(hp)	(hp->hpio_bigwin_num)
+
+#if TBD
+ /* Ensure that hpio_xtalk_info is first */
+ #assert (&(((struct hub_piomap_s *)0)->hpio_xtalk_info) == 0)
+#endif
+
+
+/* 
+ * IP27 dmamap, created by hub_pio_alloc.
+ * xtalk_info MUST BE FIRST, since this structure is cast to a
+ * xtalk_dmamap_s by generic xtalk routines.
+ */
+struct hub_dmamap_s {
+	struct xtalk_dmamap_s	hdma_xtalk_info;/* standard crosstalk dma info */
+	devfs_handle_t		hdma_hub;	/* which hub we go through */
+	int			hdma_flags;	/* defined below */
+};
+/* hub_dmamap flags */
+#define HUB_DMAMAP_IS_VALID		0x1
+#define HUB_DMAMAP_USED			0x2
+#define	HUB_DMAMAP_IS_FIXED		0x4
+
+#if TBD
+ /* Ensure that hdma_xtalk_info is first */
+ #assert (&(((struct hub_dmamap_s *)0)->hdma_xtalk_info) == 0)
+#endif
+
+/* 
+ * IP27 interrupt handle, created by hub_intr_alloc.
+ * xtalk_info MUST BE FIRST, since this structure is cast to a
+ * xtalk_intr_s by generic xtalk routines.
+ */
+struct hub_intr_s {
+	struct xtalk_intr_s	i_xtalk_info;	/* standard crosstalk intr info */
+	ilvl_t			i_swlevel;	/* software level for blocking intr */
+	cpuid_t			i_cpuid;	/* which cpu */
+	int			i_bit;		/* which bit */
+	int			i_flags;
+};
+/* flag values */
+#define HUB_INTR_IS_ALLOCED	0x1	/* for debug: allocated */
+#define HUB_INTR_IS_CONNECTED	0x4	/* for debug: connected to a software driver */
+
+#if TBD
+ /* Ensure that i_xtalk_info is first */
+ #assert (&(((struct hub_intr_s *)0)->i_xtalk_info) == 0)
+#endif
+
+
+/* IP27 hub-specific information stored under INFO_LBL_HUB_INFO */
+/* TBD: IP27-dependent stuff currently in nodepda.h should be here */
+typedef struct hubinfo_s {
+	nodepda_t			*h_nodepda;	/* pointer to node's private data area */
+	cnodeid_t			h_cnodeid;	/* compact nodeid */
+	nasid_t				h_nasid;	/* nasid */
+
+	/* structures for PIO management */
+	xwidgetnum_t			h_widgetid;	/* my widget # (as viewed from xbow) */
+	struct hub_piomap_s		h_small_window_piomap[HUB_WIDGET_ID_MAX+1];
+	sv_t				h_bwwait;	/* wait for big window to free */
+	spinlock_t			h_bwlock;	/* guard big window piomap's */
+	spinlock_t			h_crblock;      /* gaurd CRB error handling */
+	int				h_num_big_window_fixed;	/* count number of FIXED maps */
+	struct hub_piomap_s		h_big_window_piomap[HUB_NUM_BIG_WINDOW];
+	hub_intr_t			hub_ii_errintr;
+} *hubinfo_t;
+
+#define hubinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
+	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t *)infoptr))
+
+#define hubinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
+	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t)infoptr)
+
+#define	hubinfo_to_hubv(hinfo, hub_v)	(hinfo->h_nodepda->node_vertex)
+
+/*
+ * Hub info PIO map access functions.
+ */
+#define	hubinfo_bwin_piomap_get(hinfo, win) 	\
+			(&hinfo->h_big_window_piomap[win])
+#define	hubinfo_swin_piomap_get(hinfo, win)	\
+			(&hinfo->h_small_window_piomap[win])
+	
+/* IP27 cpu-specific information stored under INFO_LBL_CPU_INFO */
+/* TBD: IP27-dependent stuff currently in pda.h should be here */
+typedef struct cpuinfo_s {
+#ifdef	LATER
+	pda_t		*ci_cpupda;	/* pointer to CPU's private data area */
+#endif
+	cpuid_t		ci_cpuid;	/* CPU ID */
+} *cpuinfo_t;
+
+#define cpuinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
+	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t *)infoptr))
+
+#define cpuinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
+	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t)infoptr)
+
+/* Special initialization function for xswitch vertices created during startup. */
+extern void xswitch_vertex_init(devfs_handle_t xswitch);
+
+extern xtalk_provider_t hub_provider;
+
+/* du.c */
+int ducons_write(char *buf, int len);
+
+/* memerror.c */
+
+extern void install_eccintr(cpuid_t cpu);
+extern void memerror_get_stats(cnodeid_t cnode,
+			       int *bank_stats, int *bank_stats_max);
+extern void probe_md_errors(nasid_t);
+/* sysctlr.c */
+extern void sysctlr_init(void);
+extern void sysctlr_power_off(int sdonly);
+extern void sysctlr_keepalive(void);
+
+#define valid_cpuid(_x)		(((_x) >= 0) && ((_x) < maxcpus))
+
+/* Useful definitions to get the memory dimm given a physical
+ * address.
+ */
+#define paddr_dimm(_pa)		((_pa & MD_BANK_MASK) >> MD_BANK_SHFT)
+#define paddr_cnode(_pa)	(NASID_TO_COMPACT_NODEID(NASID_GET(_pa)))
+extern void membank_pathname_get(paddr_t,char *);
+
+/* To redirect the output into the error buffer */
+#define errbuf_print(_s)	printf("#%s",_s)
+
+extern void crbx(nasid_t nasid, void (*pf)(char *, ...));
+void bootstrap(void);
+
+/* sndrv.c */
+extern int sndrv_attach(devfs_handle_t vertex);
+
+#endif /* _ASM_IA64_SN_SN1_SN_PRIVATE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/synergy.h linux/include/asm-ia64/sn/sn1/synergy.h
--- linux.orig/include/asm-ia64/sn/sn1/synergy.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/synergy.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,187 @@
+#ifndef _ASM_IA64_SN_SN1_SYNERGY_H
+#define _ASM_IA64_SN_SN1_SYNERGY_H
+
+#include <asm/io.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/intr_public.h>
+
+
+/*
+ * Definitions for the synergy asic driver
+ * 
+ * These are for SGI platforms only.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+
+#define SYNERGY_L4_BYTES		(64UL*1024*1024)
+#define SYNERGY_L4_WAYS			8
+#define SYNERGY_L4_BYTES_PER_WAY	(SYNERGY_L4_BYTES/SYNERGY_L4_WAYS)
+#define SYNERGY_BLOCK_SIZE		512UL
+
+
+#define SSPEC_BASE	(0xe0000000000UL)
+#define LB_REG_BASE	(SSPEC_BASE + 0x0)
+
+#define VEC_MASK3A_ADDR	(0x2a0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define VEC_MASK3B_ADDR	(0x2a8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define VEC_MASK3A	(0x2a0)
+#define VEC_MASK3B	(0x2a8)
+
+#define VEC_MASK2A_ADDR	(0x2b0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define VEC_MASK2B_ADDR	(0x2b8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define VEC_MASK2A	(0x2b0)
+#define VEC_MASK2B	(0x2b8)
+
+#define VEC_MASK1A_ADDR	(0x2c0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define VEC_MASK1B_ADDR	(0x2c8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define VEC_MASK1A	(0x2c0)
+#define VEC_MASK1B	(0x2c8)
+
+#define VEC_MASK0A_ADDR	(0x2d0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define VEC_MASK0B_ADDR	(0x2d8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define VEC_MASK0A	(0x2d0)
+#define VEC_MASK0B	(0x2d8)
+
+#define GBL_PERF_A_ADDR (0x330 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+#define GBL_PERF_B_ADDR (0x338 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
+
+#define WRITE_LOCAL_SYNERGY_REG(addr, value)	__synergy_out(addr, value)
+
+#define HUB_L(_a)               *(_a)
+#define HUB_S(_a, _d)           *(_a) = (_d)
+
+#define HSPEC_SYNERGY0_0        0x04000000    /* Synergy0 Registers     */
+#define HSPEC_SYNERGY1_0        0x05000000    /* Synergy1 Registers     */
+#define HS_SYNERGY_STRIDE       (HSPEC_SYNERGY1_0 - HSPEC_SYNERGY0_0)
+#define REMOTE_HSPEC(_n, _x)    (HUBREG_CAST (RREG_BASE(_n) + (_x)))
+
+#define RREG_BASE(_n)           (NODE_LREG_BASE(_n))
+#define NODE_LREG_BASE(_n)      (NODE_HSPEC_BASE(_n) + 0x30000000)
+#define NODE_HSPEC_BASE(_n)     (HSPEC_BASE + NODE_OFFSET(_n))
+#ifndef HSPEC_BASE
+#define HSPEC_BASE              (SYN_UNCACHED_SPACE | HSPEC_BASE_SYN)
+#endif
+#define SYN_UNCACHED_SPACE      0xc000000000000000
+#define HSPEC_BASE_SYN          0x00000b0000000000
+#define NODE_OFFSET(_n)         (UINT64_CAST (_n) << NODE_SIZE_BITS)
+#define NODE_SIZE_BITS		33
+
+#define SYN_TAG_DISABLE_WAY	(SSPEC_BASE+0xae0)
+
+
+#define RSYN_REG_OFFSET(fsb, reg) (((fsb) ? HSPEC_SYNERGY1_0 : HSPEC_SYNERGY0_0) | (reg))
+
+#define REMOTE_SYNERGY_LOAD(nasid, fsb, reg)  __remote_synergy_in(nasid, fsb, reg)
+#define REMOTE_SYNERGY_STORE(nasid, fsb, reg, val) __remote_synergy_out(nasid, fsb, reg, val)
+
+static inline uint64_t
+__remote_synergy_in(int nasid, int fsb, uint64_t reg) {
+	volatile uint64_t *addr;
+
+	addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, reg));
+	return (*addr);
+}
+
+static inline void
+__remote_synergy_out(int nasid, int fsb, uint64_t reg, uint64_t value) {
+	volatile uint64_t *addr;
+
+        addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, (reg<<2)));
+        *(addr+0) = value >> 48;
+        *(addr+1) = value >> 32;
+        *(addr+2) = value >> 16;
+        *(addr+3) = value;
+        __ia64_mf_a();
+}
+
+/* XX this doesn't make a lot of sense. Which fsb?  */
+static inline void
+__synergy_out(unsigned long addr, unsigned long value)
+{
+	volatile unsigned long *adr = (unsigned long *)
+			(addr | __IA64_UNCACHED_OFFSET);
+
+	*adr = value;
+	__ia64_mf_a();
+}
+
+#define READ_LOCAL_SYNERGY_REG(addr)	__synergy_in(addr)
+
+/* XX this doesn't make a lot of sense. Which fsb? */
+static inline unsigned long
+__synergy_in(unsigned long addr)
+{
+	unsigned long ret, *adr = (unsigned long *)
+			(addr | __IA64_UNCACHED_OFFSET);
+
+	ret = *adr;
+	__ia64_mf_a();
+	return ret;
+}
+
+struct sn1_intr_action {
+	void (*handler)(int, void *, struct pt_regs *);
+	void *intr_arg;
+	unsigned long flags;
+	struct sn1_intr_action * next;
+};
+
+typedef struct synergy_da_s {
+	hub_intmasks_t	s_intmasks;
+}synergy_da_t;
+
+struct sn1_cnode_action_list {
+	spinlock_t action_list_lock;
+	struct sn1_intr_action *action_list;
+};
+
+/*
+ * ioctl cmds for node/hub/synergy/[01]/mon for synergy
+ * perf monitoring are defined in sndrv.h
+ */
+
+/* multiplex the counters every 10 timer interrupts */ 
+#define SYNERGY_PERF_FREQ_DEFAULT 10
+
+/* macros for synergy "mon" device ioctl handler */
+#define SYNERGY_PERF_INFO(_s, _f)	(arbitrary_info_t)(((_s) << 16)|(_f))
+#define SYNERGY_PERF_INFO_CNODE(_x)	(cnodeid_t)(((uint64_t)_x) >> 16)
+#define SYNERGY_PERF_INFO_FSB(_x)	(((uint64_t)_x) & 1)
+
+/* synergy perf control registers */
+#define PERF_CNTL0_A            0xab0UL /* control A on FSB0 */
+#define PERF_CNTL0_B            0xab8UL /* control B on FSB0 */
+#define PERF_CNTL1_A            0xac0UL /* control A on FSB1 */
+#define PERF_CNTL1_B            0xac8UL /* control B on FSB1 */
+
+/* synergy perf counters */
+#define PERF_CNTR0_A            0xad0UL /* counter A on FSB0 */
+#define PERF_CNTR0_B            0xad8UL /* counter B on FSB0 */
+#define PERF_CNTR1_A            0xaf0UL /* counter A on FSB1 */
+#define PERF_CNTR1_B            0xaf8UL /* counter B on FSB1 */
+
+/* Synergy perf data. Each nodepda keeps a list of these */
+struct synergy_perf_s {
+        uint64_t        intervals;      /* count of active intervals for this event */
+        uint64_t        total_intervals;/* snapshot of total intervals */
+        uint64_t        modesel;        /* mode and sel bits, both A and B registers */
+        struct synergy_perf_s *next;	/* next in circular linked list */
+        uint64_t        counts[2];      /* [0] is synergy-A counter, [1] synergy-B counter */
+};
+
+typedef struct synergy_perf_s synergy_perf_t;
+
+typedef struct synergy_info_s synergy_info_t;
+
+extern void synergy_perf_init(void);
+extern void synergy_perf_update(int);
+extern struct file_operations synergy_mon_fops;
+
+#endif /* _ASM_IA64_SN_SN1_SYNERGY_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn1/uart16550.h linux/include/asm-ia64/sn/sn1/uart16550.h
--- linux.orig/include/asm-ia64/sn/sn1/uart16550.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn1/uart16550.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,228 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-#ifndef _ASM_SN_SN1_UART16550_H
-#define _ASM_SN_SN1_UART16550_H
-
-
-/*
- * Definitions for 16550  chip
- */
-
-	/* defined as offsets from the data register */
-#define REG_DAT     0   /* receive/transmit data */
-#define REG_ICR     1   /* interrupt control register */
-#define REG_ISR     2   /* interrupt status register */
-#define REG_FCR     2   /* fifo control register */
-#define REG_LCR     3   /* line control register */
-#define REG_MCR     4   /* modem control register */
-#define REG_LSR     5   /* line status register */
-#define REG_MSR     6   /* modem status register */
-#define REG_SCR     7   /* Scratch register      */
-#define REG_DLL     0   /* divisor latch (lsb) */
-#define REG_DLH     1   /* divisor latch (msb) */
-#define REG_EFR		2	/* 16650 enhanced feature register */
-
-/*
- * 16450/16550 Registers Structure.
- */
-
-/* Line Control Register */
-#define		LCR_WLS0	0x01	/*word length select bit 0 */	
-#define		LCR_WLS1	0x02	/*word length select bit 2 */	
-#define		LCR_STB	0x04		/* number of stop bits */
-#define		LCR_PEN	0x08		/* parity enable */
-#define		LCR_EPS	0x10		/* even parity select */
-#define		LCR_SETBREAK 0x40	/* break key */
-#define		LCR_DLAB	0x80	/* divisor latch access bit */
-#define 	LCR_RXLEN   0x03    /* # of data bits per received/xmitted char */
-#define 	LCR_STOP1   0x00
-#define 	LCR_STOP2   0x04
-#define 	LCR_PAREN   0x08
-#define 	LCR_PAREVN  0x10
-#define 	LCR_PARMARK 0x20
-#define 	LCR_SNDBRK  0x40
-#define 	LCR_DLAB    0x80
-
-
-#define		LCR_BITS5	0x00	/* 5 bits per char */
-#define		LCR_BITS6	0x01	/* 6 bits per char */
-#define		LCR_BITS7	0x02	/* 7 bits per char */
-#define		LCR_BITS8	0x03	/* 8 bits per char */
-
-#define		LCR_MASK_BITS_CHAR 		0x03
-#define 	LCR_MASK_STOP_BITS		0x04
-#define		LCR_MASK_PARITY_BITS	0x18
-
-
-/* Line Status Register */
-#define		LSR_RCA	0x01		/* data ready */
-#define		LSR_OVRRUN	0x02	/* overrun error */
-#define		LSR_PARERR	0x04	/* parity error */
-#define		LSR_FRMERR	0x08	/* framing error */
-#define		LSR_BRKDET 	0x10	/* a break has arrived */
-#define		LSR_XHRE	0x20	/* tx hold reg is now empty */
-#define		LSR_XSRE	0x40	/* tx shift reg is now empty */
-#define		LSR_RFBE	0x80	/* rx FIFO Buffer error */
-
-/* Interrupt Status Regisger */
-#define		ISR_MSTATUS	0x00
-#define		ISR_TxRDY	0x02
-#define		ISR_RxRDY	0x04
-#define		ISR_ERROR_INTR	0x08
-#define		ISR_FFTMOUT 0x0c	/* FIFO Timeout */
-#define		ISR_RSTATUS 0x06	/* Receiver Line status */
-
-/* Interrupt Enable Register */
-#define		ICR_RIEN	0x01	/* Received Data Ready */
-#define		ICR_TIEN	0x02	/* Tx Hold Register Empty */
-#define		ICR_SIEN	0x04	/* Receiver Line Status */
-#define		ICR_MIEN	0x08	/* Modem Status */
-
-/* Modem Control Register */
-#define		MCR_DTR		0x01	/* Data Terminal Ready */
-#define		MCR_RTS		0x02	/* Request To Send */
-#define		MCR_OUT1	0x04	/* Aux output - not used */
-#define		MCR_OUT2	0x08	/* turns intr to 386 on/off */	
-#define		MCR_LOOP	0x10	/* loopback for diagnostics */
-#define		MCR_AFE 	0x20	/* Auto flow control enable */
-
-/* Modem Status Register */
-#define		MSR_DCTS	0x01	/* Delta Clear To Send */
-#define		MSR_DDSR	0x02	/* Delta Data Set Ready */
-#define		MSR_DRI		0x04	/* Trail Edge Ring Indicator */
-#define		MSR_DDCD	0x08	/* Delta Data Carrier Detect */
-#define		MSR_CTS		0x10	/* Clear To Send */
-#define		MSR_DSR		0x20	/* Data Set Ready */
-#define		MSR_RI		0x40	/* Ring Indicator */
-#define		MSR_DCD		0x80	/* Data Carrier Detect */
-
-#define 	DELTAS(x) 	((x)&(MSR_DCTS|MSR_DDSR|MSR_DRI|MSR_DDCD))
-#define 	STATES(x) 	((x)(MSR_CTS|MSR_DSR|MSR_RI|MSR_DCD))
-
-
-#define		FCR_FIFOEN	0x01	/* enable receive/transmit fifo */
-#define		FCR_RxFIFO	0x02	/* enable receive fifo */
-#define		FCR_TxFIFO	0x04	/* enable transmit fifo */
-#define 	FCR_MODE1	0x08	/* change to mode 1 */
-#define		RxLVL0		0x00	/* Rx fifo level at 1	*/
-#define		RxLVL1		0x40	/* Rx fifo level at 4 */
-#define		RxLVL2		0x80	/* Rx fifo level at 8 */
-#define		RxLVL3		0xc0	/* Rx fifo level at 14 */
-
-#define 	FIFOEN		(FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL3 | FCR_MODE1) 
-
-#define		FCT_TxMASK	0x30	/* mask for Tx trigger */
-#define		FCT_RxMASK	0xc0	/* mask for Rx trigger */
-
-/* enhanced festures register */
-#define		EFR_SFLOW	0x0f	/* various S/w Flow Controls */
-#define 	EFR_EIC		0x10	/* Enhanced Interrupt Control bit */
-#define 	EFR_SCD		0x20	/* Special Character Detect */
-#define 	EFR_RTS		0x40	/* RTS flow control */
-#define 	EFR_CTS		0x80	/* CTS flow control */
-
-/* Rx Tx software flow controls in 16650 enhanced mode */
-#define		SFLOW_Tx0	0x00	/* no Xmit flow control */
-#define		SFLOW_Tx1	0x08	/* Transmit Xon1, Xoff1 */
-#define		SFLOW_Tx2	0x04	/* Transmit Xon2, Xoff2 */
-#define		SFLOW_Tx3	0x0c	/* Transmit Xon1,Xon2, Xoff1,Xoff2 */
-#define		SFLOW_Rx0	0x00	/* no Rcv flow control */
-#define		SFLOW_Rx1	0x02	/* Receiver compares Xon1, Xoff1 */
-#define		SFLOW_Rx2	0x01	/* Receiver compares Xon2, Xoff2 */
-
-#define	ASSERT_DTR(x)		(x |= MCR_DTR)
-#define	ASSERT_RTS(x)		(x |= MCR_RTS)
-#define DU_RTS_ASSERTED(x)  (((x) & MCR_RTS) != 0)
-#define DU_RTS_ASSERT(x)    ((x) |= MCR_RTS)
-#define DU_RTS_DEASSERT(x)  ((x) &= ~MCR_RTS)
-
-
-/*
- * ioctl(fd, I_STR, arg)
- * use the SIOC_RS422 and SIOC_EXTCLK combination to support MIDI
- */
-#define SIOC        ('z' << 8)  /* z for z85130 */
-#define SIOC_EXTCLK (SIOC | 1)  /* select/de-select external clock */
-#define SIOC_RS422  (SIOC | 2)  /* select/de-select RS422 protocol */
-#define SIOC_ITIMER (SIOC | 3)  /* upstream timer adjustment */
-#define SIOC_LOOPBACK   (SIOC | 4)  /* diagnostic loopback test mode */
-
-
-/* channel control register */
-#define	DMA_INT_MASK		0xe0	/* ring intr mask */
-#define DMA_INT_TH25		0x20	/* 25% threshold */
-#define DMA_INT_TH50		0x40	/* 50% threshold */
-#define DMA_INT_TH75		0x60	/* 75% threshold */
-#define DMA_INT_EMPTY		0x80	/* ring buffer empty */
-#define DMA_INT_NEMPTY		0xa0	/* ring buffer not empty */
-#define DMA_INT_FULL		0xc0	/* ring buffer full */
-#define DMA_INT_NFULL		0xe0	/* ring buffer not full */
-
-#define DMA_CHANNEL_RESET	0x400	/* reset dma channel */
-#define DMA_ENABLE			0x200	/* enable DMA */
-
-/* peripheral controller intr status bits applicable to serial ports */
-#define ISA_SERIAL0_MASK 		0x03f00000	/* mask for port #1 intrs */
-#define ISA_SERIAL0_DIR			0x00100000	/* device intr request */
-#define ISA_SERIAL0_Tx_THIR		0x00200000	/* Transmit DMA threshold */
-#define ISA_SERIAL0_Tx_PREQ		0x00400000	/* Transmit DMA pair req */
-#define ISA_SERIAL0_Tx_MEMERR	0x00800000	/* Transmit DMA memory err */
-#define ISA_SERIAL0_Rx_THIR		0x01000000	/* Receive DMA threshold  */
-#define ISA_SERIAL0_Rx_OVERRUN	0x02000000	/* Receive DMA over-run  */
-
-#define ISA_SERIAL1_MASK 		0xfc000000	/* mask for port #1 intrs */
-#define ISA_SERIAL1_DIR			0x04000000	/* device intr request */
-#define ISA_SERIAL1_Tx_THIR		0x08000000	/* Transmit DMA threshold */
-#define ISA_SERIAL1_Tx_PREQ		0x10000000	/* Transmit DMA pair req */
-#define ISA_SERIAL1_Tx_MEMERR	0x20000000	/* Transmit DMA memory err */
-#define ISA_SERIAL1_Rx_THIR		0x40000000	/* Receive DMA threshold  */
-#define ISA_SERIAL1_Rx_OVERRUN	0x80000000	/* Receive DMA over-run  */
-
-#define MAX_RING_BLOCKS		128			/* 4096/32 */
-#define MAX_RING_SIZE		4096
-
-/* DMA Input Control Byte */
-#define	DMA_IC_OVRRUN	0x01	/* overrun error */
-#define	DMA_IC_PARERR	0x02	/* parity error */
-#define	DMA_IC_FRMERR	0x04	/* framing error */
-#define	DMA_IC_BRKDET 	0x08	/* a break has arrived */
-#define DMA_IC_VALID	0x80	/* pair is valid */
-
-/* DMA Output Control Byte */
-#define DMA_OC_TxINTR	0x20	/* set Tx intr after processing byte */
-#define DMA_OC_INVALID	0x00	/* invalid pair */
-#define DMA_OC_WTHR		0x40	/* Write byte to THR */
-#define DMA_OC_WMCR		0x80	/* Write byte to MCR */
-#define DMA_OC_DELAY	0xc0	/* time delay before next xmit */
-
-/* ring id's */
-#define RID_SERIAL0_TX	0x4		/* serial port 0, transmit ring buffer */
-#define RID_SERIAL0_RX	0x5		/* serial port 0, receive ring buffer */
-#define RID_SERIAL1_TX	0x6		/* serial port 1, transmit ring buffer */
-#define RID_SERIAL1_RX	0x7		/* serial port 1, receive ring buffer */
-
-#define CLOCK_XIN			22
-#define PRESCALER_DIVISOR	3
-#define CLOCK_ACE			7333333
-
-/*
- * increment the ring offset. One way to do this would be to add b'100000.
- * this would let the offset value roll over automatically when it reaches
- * its maximum value (127). However when we use the offset, we must use
- * the appropriate bits only by masking with 0xfe0.
- * The other option is to shift the offset right by 5 bits and look at its
- * value. Then increment if required and shift back
- * note: 127 * 2^5 = 4064
- */
-#define INC_RING_POINTER(x) \
-	( ((x & 0xffe0) < 4064) ? (x += 32) : 0 )
-
-#endif /* _ASM_SN_SN1_UART16550_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/addrs.h linux/include/asm-ia64/sn/sn2/addrs.h
--- linux.orig/include/asm-ia64/sn/sn2/addrs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/addrs.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,159 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_SN2_ADDRS_H
+#define _ASM_IA64_SN_SN2_ADDRS_H
+
+/* McKinley Address Format:
+ *
+ *   4 4       3 3  3 3
+ *   9 8       8 7  6 5             0
+ *  +-+---------+----+--------------+
+ *  |0| Node ID | AS | Node Offset  |
+ *  +-+---------+----+--------------+
+ *
+ *   Node ID: If bit 38 = 1, is ICE, else is SHUB
+ *   AS: Address Space Identifier. Used only if bit 38 = 0.
+ *     b'00: Local Resources and MMR space
+ *           bit 35
+ *               0: Local resources space
+ *                  node id:
+ *                        0: IA64/NT compatibility space
+ *                        2: Local MMR Space
+ *                        4: Local memory, regardless of local node id
+ *               1: Global MMR space
+ *     b'01: GET space.
+ *     b'10: AMO space.
+ *     b'11: Cacheable memory space.
+ *
+ *   NodeOffset: byte offset
+ */
+
+#ifndef __ASSEMBLY__
+typedef union ia64_sn2_pa {
+	struct {
+		unsigned long off  : 36;
+		unsigned long as   : 2;
+		unsigned long nasid: 11;
+		unsigned long fill : 15;
+	} f;
+	unsigned long l;
+	void *p;
+} ia64_sn2_pa_t;
+#endif
+
+#define TO_PHYS_MASK		0x0001ffcfffffffff	/* Note - clear AS bits */
+
+
+/* Regions determined by AS */
+#define LOCAL_MMR_SPACE		0xc000008000000000	/* Local MMR space */
+#define LOCAL_MEM_SPACE		0xc000010000000000	/* Local Memory space */
+#define GLOBAL_MMR_SPACE	0xc000000800000000	/* Global MMR space */
+#define GET_SPACE		0xc000001000000000	/* GET space */
+#define AMO_SPACE		0xc000002000000000	/* AMO space */
+#define CACHEABLE_MEM_SPACE	0xe000003000000000	/* Cacheable memory space */
+#define UNCACHED                0xc000000000000000      /* UnCacheable memory space */
+
+/* SN2 address macros */
+#define NID_SHFT		38
+#define LOCAL_MMR_ADDR(a)	(UNCACHED | LOCAL_MMR_SPACE | (a))
+#define LOCAL_MEM_ADDR(a)	(LOCAL_MEM_SPACE | (a))
+#define REMOTE_ADDR(n,a)	((((unsigned long)(n))<<NID_SHFT) | (a))
+#define GLOBAL_MMR_ADDR(n,a)	(UNCACHED | GLOBAL_MMR_SPACE | REMOTE_ADDR(n,a))
+#define GET_ADDR(n,a)		(GET_SPACE | REMOTE_ADDR(n,a))
+#define AMO_ADDR(n,a)		(UNCACHED | AMO_SPACE | REMOTE_ADDR(n,a))
+#define GLOBAL_MEM_ADDR(n,a)	(CACHEABLE_MEM_SPACE | REMOTE_ADDR(n,a))
+
+/* non-II mmr's start at top of big window space (4G) */
+#define BWIN_TOP		0x0000000100000000
+
+/*
+ * general address defines - for code common to SN0/SN1/SN2
+ */
+#define CAC_BASE		CACHEABLE_MEM_SPACE			/* cacheable memory space */
+#define IO_BASE			(UNCACHED | GLOBAL_MMR_SPACE)		/* lower 4G maps II's XIO space */
+#define AMO_BASE		(UNCACHED | AMO_SPACE)			/* fetch & op space */
+#define MSPEC_BASE		AMO_BASE				/* fetch & op space */
+#define UNCAC_BASE		(UNCACHED | CACHEABLE_MEM_SPACE)	/* uncached global memory */
+#define GET_BASE		GET_SPACE				/* momentarily coherent remote mem. */
+#define CALIAS_BASE             LOCAL_CACHEABLE_BASE			/* cached node-local memory */
+#define UALIAS_BASE             (UNCACHED | LOCAL_CACHEABLE_BASE)	/* uncached node-local memory */
+
+#define TO_PHYS(x)              (              ((x) & TO_PHYS_MASK))
+#define TO_CAC(x)               (CAC_BASE    | ((x) & TO_PHYS_MASK))
+#define TO_UNCAC(x)             (UNCAC_BASE  | ((x) & TO_PHYS_MASK))
+#define TO_MSPEC(x)             (MSPEC_BASE  | ((x) & TO_PHYS_MASK))
+#define TO_GET(x)		(GET_BASE    | ((x) & TO_PHYS_MASK))
+#define TO_CALIAS(x)            (CALIAS_BASE | TO_NODE_ADDRSPACE(x))
+#define TO_UALIAS(x)            (UALIAS_BASE | TO_NODE_ADDRSPACE(x))
+#define NODE_SIZE_BITS		36	/* node offset : bits <35:0> */
+#define BWIN_SIZE_BITS		29	/* big window size: 512M */
+#define NASID_BITS		11	/* bits <48:38> */
+#define NASID_BITMASK		(0x7ffULL)
+#define NASID_SHFT		NID_SHFT
+#define NASID_META_BITS		0	/* ???? */
+#define NASID_LOCAL_BITS	7	/* same router as SN1 */
+
+#define NODE_ADDRSPACE_SIZE     (UINT64_CAST 1 << NODE_SIZE_BITS)
+#define NASID_MASK              (UINT64_CAST NASID_BITMASK << NASID_SHFT)
+#define NASID_GET(_pa)          (int) ((UINT64_CAST (_pa) >>            \
+                                        NASID_SHFT) & NASID_BITMASK)
+#ifdef __IA64
+#define PHYS_TO_DMA(x)          ( ((x & NASID_MASK) >> 2) |             \
+                                  (x & (NODE_ADDRSPACE_SIZE - 1)) )
+#else
+#define PHYS_TO_DMA(x)          ( (x) )
+#endif
+
+#define CHANGE_NASID(n,x)	({ia64_sn2_pa_t _v; _v.l = (long) (x); _v.f.nasid = n; _v.p;})
+
+#ifndef __ASSEMBLY__
+#define NODE_SWIN_BASE(nasid, widget)                                   \
+        ((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN)          \
+        : RAW_NODE_SWIN_BASE(nasid, widget))
+#else
+#define NODE_SWIN_BASE(nasid, widget) \
+     (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
+#define LOCAL_SWIN_BASE(widget) \
+	(UNCACHED | LOCAL_MMR_SPACE | ((UINT64_CAST (widget) << SWIN_SIZE_BITS)))
+#endif /* __ASSEMBLY__ */
+
+/*
+ * The following definitions pertain to the IO special address
+ * space.  They define the location of the big and little windows
+ * of any given node.
+ */
+
+#define BWIN_INDEX_BITS         3
+#define BWIN_SIZE               (UINT64_CAST 1 << BWIN_SIZE_BITS)
+#define BWIN_SIZEMASK           (BWIN_SIZE - 1)
+#define BWIN_WIDGET_MASK        0x7
+#define NODE_BWIN_BASE0(nasid)  (NODE_IO_BASE(nasid) + BWIN_SIZE)
+#define NODE_BWIN_BASE(nasid, bigwin)   (NODE_BWIN_BASE0(nasid) +       \
+                        (UINT64_CAST (bigwin) << BWIN_SIZE_BITS))
+
+#define BWIN_WIDGETADDR(addr)   ((addr) & BWIN_SIZEMASK)
+#define BWIN_WINDOWNUM(addr)    (((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
+
+/*
+ * Verify if addr belongs to large window address of node with "nasid"
+ *
+ *
+ * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
+ * address
+ *
+ *
+ */
+
+#define NODE_BWIN_ADDR(nasid, addr)     \
+                (((addr) >= NODE_BWIN_BASE0(nasid)) && \
+                 ((addr) < (NODE_BWIN_BASE(nasid, HUB_NUM_BIG_WINDOW) + \
+                                BWIN_SIZE)))
+
+#endif	/* _ASM_IA64_SN_SN2_ADDRS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/arch.h linux/include/asm-ia64/sn/sn2/arch.h
--- linux.orig/include/asm-ia64/sn/sn2/arch.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/arch.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,66 @@
+/* $Id: arch.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN2_ARCH_H
+#define _ASM_IA64_SN_SN2_ARCH_H
+
+#include <asm/types.h>
+
+
+#define CPUS_PER_NODE           4       /* CPUs on a single hub */
+#define CPUS_PER_SUBNODE        4       /* CPUs on a single hub PI */
+
+
+/*
+ * This is the maximum number of NASIDS that can be present in a system.
+ * (Highest NASID plus one.)
+ */
+#define MAX_NASIDS              2048
+
+
+/*
+ * This is the maximum number of nodes that can be part of a kernel.
+ * Effectively, it's the maximum number of compact node ids (cnodeid_t).
+ * This is not necessarily the same as MAX_NASIDS.
+ */
+#define MAX_COMPACT_NODES       128
+
+/*
+ * MAX_REGIONS refers to the maximum number of hardware partitioned regions.
+ */
+#define	MAX_REGIONS		64
+#define MAX_NONPREMIUM_REGIONS  16
+#define MAX_PREMIUM_REGIONS     MAX_REGIONS
+
+
+/*
+ * MAX_PARITIONS refers to the maximum number of logically defined 
+ * partitions the system can support.
+ */
+#define MAX_PARTITIONS		MAX_REGIONS
+
+
+#define NASID_MASK_BYTES	((MAX_NASIDS + 7) / 8)
+
+
+/*
+ * 1 FSB per SHUB, with up to 4 cpus per FSB.
+ */
+#define NUM_SUBNODES	1
+#define SUBNODE_SHFT	0
+#define SUBNODE_MASK	(0x0 << SUBNODE_SHFT)
+#define LOCALCPU_SHFT	0
+#define LOCALCPU_MASK	(0x3 << LOCALCPU_SHFT)
+#define SUBNODE(slice)	(((slice) & SUBNODE_MASK) >> SUBNODE_SHFT)
+#define LOCALCPU(slice)	(((slice) & LOCALCPU_MASK) >> LOCALCPU_SHFT)
+#define TO_SLICE(subn, local)	(((subn) << SUBNODE_SHFT) | \
+				 ((local) << LOCALCPU_SHFT))
+
+typedef u64 mmr_t;
+
+#endif /* _ASM_IA64_SN_SN2_ARCH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/intr.h linux/include/asm-ia64/sn/sn2/intr.h
--- linux.orig/include/asm-ia64/sn/sn2/intr.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/intr.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,25 @@
+/* $Id: intr.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN2_INTR_H
+#define _ASM_IA64_SN_SN2_INTR_H
+
+#define SGI_UART_VECTOR (0xe9)
+#define SGI_SHUB_ERROR_VECTOR   (0xea)
+
+// These two IRQ's are used by partitioning.
+#define SGI_XPC_NOTIFY			(0xe7)
+#define SGI_XPART_ACTIVATE		(0x30)
+
+#define IA64_SN2_FIRST_DEVICE_VECTOR	(0x31)
+#define IA64_SN2_LAST_DEVICE_VECTOR	(0xe6)
+
+#define SN2_IRQ_RESERVED        (0x1)
+#define SN2_IRQ_CONNECTED       (0x2)
+
+#endif /* _ASM_IA64_SN_SN2_INTR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/mmzone_sn2.h linux/include/asm-ia64/sn/sn2/mmzone_sn2.h
--- linux.orig/include/asm-ia64/sn/sn2/mmzone_sn2.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/mmzone_sn2.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,165 @@
+#ifndef _ASM_IA64_SN_MMZONE_SN2_H
+#define _ASM_IA64_SN_MMZONE_SN2_H
+
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/config.h>
+
+
+/*
+ * SGI SN2 Arch defined values
+ *
+ * 	An SN2 physical address is broken down as follows:
+ *
+ *             +-----------------------------------------+
+ *             |         |      |    |   node offset     |
+ *             | unused  | node | AS |-------------------|
+ *             |         |      |    | cn | clump offset |
+ *             +-----------------------------------------+
+ *              6       4 4    3 3  3 3  3 3            0
+ *              3       9 8    8 7  6 5  4 3            0
+ *
+ *		bits 63-49	Unused - must be zero
+ *		bits 48-38	Node number. Note that some configurations do NOT
+ *				have a node zero.
+ *		bits 37-36	Address space ID. Cached memory has a value of 3 (!!!).
+ *				Chipset & IO addresses have other values.
+ *				  (Yikes!! The hardware folks hate us...)
+ *		bits 35-0	Node offset.
+ *
+ *	The node offset can be further broken down as:
+ *		bits 35-34	Clump (bank) number.
+ *		bits 33-0	Clump (bank) offset.
+ *
+ *	A node consists of up to 4 clumps (banks) of memory. A clump may be empty, or may be
+ *	populated with a single contiguous block of memory starting at clump
+ *	offset 0. The size of the block is (2**n) * 64MB, where 0<n<9.
+ *
+ *	Important notes:
+ *		- IO space addresses are embedded with the range of valid memory addresses.
+ *		- All cached memory addresses have bits 36 & 37 set to 1's.
+ *		- There is no physical address 0.
+ *
+ * NOTE: This file exports symbols prefixed with "PLAT_". Symbols prefixed with
+ *	 "SN_" are intended for internal use only and should not be used in
+ *	 any platform independent code. 
+ *
+ *	 This file is also responsible for exporting the following definitions:
+ *		cnodeid_t	Define a compact node id. 
+ */
+
+typedef signed short cnodeid_t;
+
+#define SN2_BANKS_PER_NODE		4
+#define SN2_NODE_SIZE			(64UL*1024*1024*1024)	/* 64GB per node */
+#define SN2_BANK_SIZE			(SN2_NODE_SIZE/SN2_BANKS_PER_NODE)
+#define SN2_NODE_SHIFT			38
+#define SN2_NODE_MASK			0x7ffUL
+#define SN2_NODE_OFFSET_MASK		(SN2_NODE_SIZE-1)
+#define SN2_NODE_NUMBER(addr)		(((unsigned long)(addr) >> SN2_NODE_SHIFT) & SN2_NODE_MASK)
+#define SN2_NODE_CLUMP_NUMBER(kaddr)	(((unsigned long)(kaddr) >>34) & 3)
+#define SN2_NODE_OFFSET(addr)		(((unsigned long)(addr)) & SN2_NODE_OFFSET_MASK)
+#define SN2_KADDR(nasid, offset)	(((unsigned long)(nasid)<<SN2_NODE_SHIFT) | (offset) | SN2_PAGE_OFFSET)
+#define SN2_PAGE_OFFSET			0xe000003000000000UL      /* Cacheable memory space */
+
+
+#define PLAT_MAX_NODE_NUMBER		2048			/* Maximum node number + 1 */
+#define PLAT_MAX_COMPACT_NODES		128			/* Maximum number of nodes in SSI system */
+
+#define PLAT_MAX_PHYS_MEMORY		(1UL << 49)
+
+
+
+/*
+ * On the SN platforms, a clump is the same as a memory bank.
+ */
+#define PLAT_CLUMPS_PER_NODE		SN2_BANKS_PER_NODE
+#define PLAT_CLUMP_OFFSET(addr)		((unsigned long)(addr) & 0x3ffffffffUL)
+#define PLAT_CLUMPSIZE			(SN2_NODE_SIZE/PLAT_CLUMPS_PER_NODE)
+#define PLAT_MAXCLUMPS			(PLAT_CLUMPS_PER_NODE * PLAT_MAX_COMPACT_NODES)
+
+
+
+/*
+ * PLAT_VALID_MEM_KADDR returns a boolean to indicate if a kaddr is potentially a
+ * valid cacheable identity mapped RAM memory address.
+ * Note that the RAM may or may not actually be present!!
+ */
+#define SN2_VALID_KERN_ADDR_MASK	0xffff003000000000UL
+#define SN2_VALID_KERN_ADDR_VALUE	0xe000003000000000UL
+#define PLAT_VALID_MEM_KADDR(kaddr)	(((unsigned long)(kaddr) & SN2_VALID_KERN_ADDR_MASK) == SN2_VALID_KERN_ADDR_VALUE)
+
+
+
+/*
+ * Memory is conceptually divided into chunks. A chunk is either
+ * completely present, or else the kernel assumes it is completely
+ * absent. Each node consists of a number of possibly contiguous chunks.
+ */
+#define SN2_CHUNKSHIFT			25			/* 32 MB */
+#define PLAT_CHUNKSIZE			(1UL << SN2_CHUNKSHIFT)
+#define PLAT_CHUNKNUM(addr)		({unsigned long _p=(unsigned long)(addr);		\
+						(((_p&SN2_NODE_MASK)>>2) | 			\
+						(_p&SN2_NODE_OFFSET_MASK)) >>SN2_CHUNKSHIFT;})
+
+/*
+ * Given a kaddr, find the nid (compact nodeid)
+ */
+#ifdef CONFIG_IA64_SGI_SN_DEBUG
+#define DISCONBUG(kaddr)		panic("DISCONTIG BUG: line %d, %s. kaddr 0x%lx",	 	\
+						__LINE__, __FILE__, (long)(kaddr))
+
+#define KVADDR_TO_NID(kaddr)		({long _ktn=(long)(kaddr);					\
+						kern_addr_valid(_ktn) ? 				\
+						local_node_data->physical_node_map[SN2_NODE_NUMBER(_ktn)] :	\
+						(DISCONBUG(_ktn), 0UL);})
+#else
+#define KVADDR_TO_NID(kaddr)		(local_node_data->physical_node_map[SN2_NODE_NUMBER(kaddr)])
+#endif
+
+
+
+/*
+ * Given a kaddr, find the index into the clump_mem_map_base array of the page struct entry 
+ * for the first page of the clump.
+ */
+#define PLAT_CLUMP_MEM_MAP_INDEX(kaddr)		({long _kmmi=(long)(kaddr);				\
+							KVADDR_TO_NID(_kmmi) * PLAT_CLUMPS_PER_NODE +	\
+							SN2_NODE_CLUMP_NUMBER(_kmmi);})
+
+
+
+/*
+ * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
+ * nodes so that they dont alias to the same line in the cache as the previous allocated structure.
+ * This macro takes an address of the end of previous allocation, rounds it to a page boundary & 
+ * changes the node number.
+ */
+#define PLAT_BOOTMEM_ALLOC_GOAL(cnode,kaddr)	__pa(SN2_KADDR(PLAT_PXM_TO_PHYS_NODE_NUMBER(nid_to_pxm_map[cnode]),	       \
+						 (SN2_NODE_OFFSET(kaddr) + PAGE_SIZE - 1) >> PAGE_SHIFT << PAGE_SHIFT))
+
+
+
+
+/*
+ * Convert a proximity domain number (from the ACPI tables) into a physical node number.
+ *	Note: on SN2, the promity domain number is the same as bits [8:1] of the NASID. The following
+ *	algorithm relies on:
+ *		- bit 0 of the NASID for cpu nodes is always 0
+ *		- bits [10:9] of all NASIDs in a partition are always the same
+ *		- hard_smp_processor_id return the SAPIC of the current cpu &
+ *			bits 0..11 contain the NASID.
+ *
+ *	All of this complexity is because MS architectually limited proximity domain numbers to
+ *	8 bits. 
+ */
+
+#define PLAT_PXM_TO_PHYS_NODE_NUMBER(pxm)	(((pxm)<<1) | (hard_smp_processor_id() & 0x300))
+
+#endif /* _ASM_IA64_SN_MMZONE_SN2_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/shub.h linux/include/asm-ia64/sn/sn2/shub.h
--- linux.orig/include/asm-ia64/sn/sn2/shub.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/shub.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+
+#ifndef _ASM_IA64_SN_SN2_SHUB_H
+#define _ASM_IA64_SN_SN2_SHUB_H
+
+#include <asm/sn/sn2/shub_mmr.h>		/* shub mmr addresses and formats */
+#include <asm/sn/sn2/shub_md.h>	
+#include <asm/sn/sn2/shubio.h>	
+#ifndef __ASSEMBLY__
+#include <asm/sn/sn2/shub_mmr_t.h>		/* shub mmr struct defines */
+#endif
+
+/*
+ * Junk Bus Address Space
+ *   The junk bus is used to access the PROM, LED's, and UART. It's 
+ *   accessed through the local block MMR space. The data path is
+ *   16 bits wide. This space requires address bits 31-27 to be set, and
+ *   is further divided by address bits 26:15.
+ *   The LED addresses are write-only. To read the LEDs, you need to use
+ *   SH_JUNK_BUS_LED0-3, defined in shub_mmr.h
+ *		
+ */
+#define SH_REAL_JUNK_BUS_LED0           0x7fed00000
+#define SH_REAL_JUNK_BUS_LED1           0x7fed10000
+#define SH_REAL_JUNK_BUS_LED2           0x7fed20000
+#define SH_REAL_JUNK_BUS_LED3           0x7fed30000
+#define SH_JUNK_BUS_UART0               0x7fed40000
+#define SH_JUNK_BUS_UART1               0x7fed40008
+#define SH_JUNK_BUS_UART2               0x7fed40010
+#define SH_JUNK_BUS_UART3               0x7fed40018
+#define SH_JUNK_BUS_UART4               0x7fed40020
+#define SH_JUNK_BUS_UART5               0x7fed40028
+#define SH_JUNK_BUS_UART6               0x7fed40030
+#define SH_JUNK_BUS_UART7               0x7fed40038
+
+#endif /* _ASM_IA64_SN_SN2_SHUB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/shub_md.h linux/include/asm-ia64/sn/sn2/shub_md.h
--- linux.orig/include/asm-ia64/sn/sn2/shub_md.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/shub_md.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,278 @@
+/**************************************************************************
+ *                                                                        *
+ *  Copyright (C) 2001 Silicon Graphics, Inc. All rights reserved.        *
+ *                                                                        *
+ *  These coded instructions, statements, and computer programs  contain  *
+ *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
+ *  are protected by Federal copyright law.  They  may  not be disclosed  *
+ *  to  third  parties  or copied or duplicated in any form, in whole or  *
+ *  in part, without the prior written consent of Silicon Graphics, Inc.  *
+ *                                                                        *
+ **************************************************************************/
+
+#ifndef _SHUB_MD_H
+#define _SHUB_MD_H
+
+/* SN2 supports a mostly-flat address space with 4 CPU-visible, evenly spaced, 
+   contiguous regions, or "software banks".  On SN2, software bank n begins at 
+   addresses n * 16GB, 0 <= n < 4.  Each bank has a 16GB address space.  If 
+   the 4 dimms do not use up this space there will be holes between the 
+   banks.  Even with these holes the whole memory space within a bank is
+   not addressable address space.  The top 1/32 of each bank is directory
+   memory space and is accessible through bist only.
+
+   Physically a SN2 node board contains 2 daughter cards with 8 dimm sockets
+   each.  A total of 16 dimm sockets arranged as 4 "DIMM banks" of 4 dimms 
+   each.  The data is stripped across the 4 memory busses so all dimms within 
+   a dimm bank must have identical capacity dimms.  Memory is increased or 
+   decreased in sets of 4.  Each dimm bank has 2 dimms on each side.
+
+             Physical Dimm Bank layout.
+                  DTR Card0
+                 ------------
+   Dimm Bank 3   |  MemYL3  |   CS 3
+                 |  MemXL3  |
+                 |----------|
+   Dimm Bank 2   |  MemYL2  |   CS 2
+                 |  MemXL2  |
+                 |----------|
+   Dimm Bank 1   |  MemYL1  |   CS 1
+                 |  MemXL1  |
+                 |----------|
+   Dimm Bank 0   |  MemYL0  |   CS 0 
+                 |  MemXL0  |
+                 ------------
+                  |       |
+                  BUS     BUS
+                  XL      YL
+                  |       |
+                 ------------
+                 |   SHUB   |
+                 |    MD    |
+                 ------------
+                  |       |
+                  BUS     BUS
+                  XR      YR
+                  |       |
+                 ------------
+   Dimm Bank 0   |  MemXR0  |   CS 0
+                 |  MemYR0  |
+                 |----------|
+   Dimm Bank 1   |  MemXR1  |   CS 1
+                 |  MemYR1  |
+                 |----------|
+   Dimm Bank 2   |  MemXR2  |   CS 2
+                 |  MemYR2  |
+                 |----------|
+   Dimm Bank 3   |  MemXR3  |   CS 3
+                 |  MemYR3  |
+                 ------------
+                  DTR Card1
+
+   The dimms can be 1 or 2 sided dimms.  The size and bankness is defined  
+   separately for each dimm bank in the sh_[x,y,jnr]_dimm_cfg MMR register.
+
+   Normally software bank 0 would map directly to physical dimm bank 0.  The 
+   software banks can map to the different physical dimm banks via the 
+   DIMM[0-3]_CS field in SH_[x,y,jnr]_DIMM_CFG for each dimm slot.   
+
+   All the PROM's data structures (promlog variables, klconfig, etc.)
+   track memory by the physical dimm bank number.  The kernel usually
+   tracks memory by the software bank number.
+
+ */
+
+
+/* Preprocessor macros */
+#define MD_MEM_BANKS		4
+#define MD_PHYS_BANKS_PER_DIMM  2                  /* dimms may be 2 sided. */
+#define MD_NUM_PHYS_BANKS       (MD_MEM_BANKS * MD_PHYS_BANKS_PER_DIMM)
+#define MD_DIMMS_IN_SLOT	4  /* 4 dimms in each dimm bank.  aka slot */
+
+/* Address bits 35,34 control dimm bank access. */
+#define MD_BANK_SHFT       	34     
+#define MD_BANK_MASK       	(UINT64_CAST 0x3 << MD_BANK_SHFT )
+#define MD_BANK_GET(addr)  	(((addr) & MD_BANK_MASK) >> MD_BANK_SHFT)
+#define MD_BANK_SIZE       	(UINT64_CAST 0x1 << MD_BANK_SHFT ) /* 16 gb */
+#define MD_BANK_OFFSET(_b) 	(UINT64_CAST (_b) << MD_BANK_SHFT)
+
+/*Address bit 12 selects side of dimm if 2bnk dimms present. */
+#define MD_PHYS_BANK_SEL_SHFT   12
+#define MD_PHYS_BANK_SEL_MASK   (UINT64_CAST 0x1 << MD_PHYS_BANK_SEL_SHFT)
+
+/* Address bit 7 determines if data resides on X or Y memory system. 
+ * If addr Bit 7 is set the data resides on Y memory system and
+ * the corresponing directory entry reside on the X. 
+ */
+#define MD_X_OR_Y_SEL_SHFT	7	
+#define MD_X_OR_Y_SEL_MASK	(1 << MD_X_OR_Y_SEL_SHFT)	
+
+/* Address bit 8 determines which directory entry of the pair the address
+ * corresponds to.  If addr Bit 8 is set DirB corresponds to the memory address.
+ */
+#define MD_DIRA_OR_DIRB_SEL_SHFT	8
+#define MD_DIRA_OR_DIRB_SEL_MASK  	(1 << MD_DIRA_OR_DIRB_SEL_SHFT)	
+
+/* Address bit 11 determines if corresponding directory entry resides 
+ * on Left or Right memory bus.  If addr Bit 11 is set the corresponding 
+ * directory entry resides on Right memory bus.
+ */
+#define MD_L_OR_R_SEL_SHFT	11
+#define MD_L_OR_R_SEL_MASK	(1 << MD_L_OR_R_SEL_SHFT)	
+
+/* DRAM sizes. */
+#define MD_SZ_64_Mb		0x0
+#define MD_SZ_128_Mb		0x1
+#define MD_SZ_256_Mb		0x2
+#define MD_SZ_512_Mb		0x3
+#define MD_SZ_1024_Mb		0x4
+#define MD_SZ_2048_Mb	 	0x5
+#define MD_SZ_UNUSED		0x7
+
+#define MD_DIMM_SIZE_BYTES(_size, _2bk) (				 \
+		( (_size) == 7 ? 0 : ( 0x4000000L << (_size)) << (_2bk)))\
+
+#define MD_DIMM_SIZE_MBYTES(_size, _2bk) (				 \
+	 	( (_size) == 7 ? 0 : ( 0x40L << (_size) ) << (_2bk)))  	 \
+
+/* The top 1/32 of each bank is directory memory, and not accessable
+ * via normal reads and writes */
+#define MD_DIMM_USER_SIZE(_size)	((_size) * 31 / 32)
+
+/* Minimum size of a populated bank is 64M (62M usable) */
+#define MIN_BANK_SIZE		MD_DIMM_USER_SIZE((64 * 0x100000))
+#define MIN_BANK_STRING		"62"
+
+
+/*Possible values for FREQ field in sh_[x,y,jnr]_dimm_cfg regs */
+#define MD_DIMM_100_CL2_0 	0x0
+#define MD_DIMM_133_CL2_0 	0x1
+#define MD_DIMM_133_CL2_5 	0x2
+#define MD_DIMM_160_CL2_0 	0x3
+#define MD_DIMM_160_CL2_5 	0x4
+#define MD_DIMM_160_CL3_0 	0x5
+#define MD_DIMM_200_CL2_0 	0x6
+#define MD_DIMM_200_CL2_5 	0x7
+#define MD_DIMM_200_CL3_0 	0x8
+
+/* DIMM_CFG fields */
+#define MD_DIMM_SHFT(_dimm)	((_dimm) << 3)
+#define MD_DIMM_SIZE_MASK(_dimm)					\
+		(SH_JNR_DIMM_CFG_DIMM0_SIZE_MASK << 			\
+		(MD_DIMM_SHFT(_dimm)))
+
+#define MD_DIMM_2BK_MASK(_dimm)						\
+		(SH_JNR_DIMM_CFG_DIMM0_2BK_MASK << 			\
+		MD_DIMM_SHFT(_dimm))
+
+#define MD_DIMM_REV_MASK(_dimm)						\
+		(SH_JNR_DIMM_CFG_DIMM0_REV_MASK << 			\
+		MD_DIMM_SHFT(_dimm))
+
+#define MD_DIMM_CS_MASK(_dimm)						\
+		(SH_JNR_DIMM_CFG_DIMM0_CS_MASK << 			\
+		MD_DIMM_SHFT(_dimm))
+
+#define MD_DIMM_SIZE(_dimm, _cfg)					\
+		(((_cfg) & MD_DIMM_SIZE_MASK(_dimm))			\
+		>> (MD_DIMM_SHFT(_dimm)+SH_JNR_DIMM_CFG_DIMM0_SIZE_SHFT))
+
+#define MD_DIMM_TWO_SIDED(_dimm,_cfg)					\
+		( ((_cfg) & MD_DIMM_2BK_MASK(_dimm))			\
+		>> (MD_DIMM_SHFT(_dimm)+SH_JNR_DIMM_CFG_DIMM0_2BK_SHFT))
+
+#define MD_DIMM_REVERSED(_dimm,_cfg) 					\
+		(((_cfg) & MD_DIMM_REV_MASK(_dimm))			\
+		>> (MD_DIMM_SHFT(_dimm)+SH_JNR_DIMM_CFG_DIMM0_REV_SHFT))
+
+#define MD_DIMM_CS(_dimm,_cfg)						\
+		(((_cfg) & MD_DIMM_CS_MASK(_dimm))			\
+		>> (MD_DIMM_SHFT(_dimm)+SH_JNR_DIMM_CFG_DIMM0_CS_SHFT))
+
+
+
+/* Macros to set MMRs that must be set identically to others. */
+#define MD_SET_DIMM_CFG(_n, _value) {					\
+		REMOTE_HUB_S(_n, SH_X_DIMM_CFG,_value);			\
+                REMOTE_HUB_S(_n, SH_Y_DIMM_CFG, _value);		\
+                REMOTE_HUB_S(_n, SH_JNR_DIMM_CFG, _value);}
+
+#define MD_SET_DQCT_CFG(_n, _value) {					\
+		REMOTE_HUB_S(_n, SH_X_DQCT_CFG,_value);			\
+		REMOTE_HUB_S(_n, SH_Y_DQCT_CFG,_value); }
+
+#define MD_SET_CFG(_n, _value) {					\
+		REMOTE_HUB_S(_n, SH_X_CFG,_value);			\
+		REMOTE_HUB_S(_n, SH_Y_CFG,_value);} 
+
+#define MD_SET_REFRESH_CONTROL(_n, _value) {				\
+		REMOTE_HUB_S(_n, SH_X_REFRESH_CONTROL, _value);		\
+		REMOTE_HUB_S(_n, SH_Y_REFRESH_CONTROL, _value);}
+
+#define MD_SET_DQ_MMR_DIR_COFIG(_n, _value) {				\
+		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_DIR_CONFIG, _value);	\
+                REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_DIR_CONFIG, _value);}
+
+#define MD_SET_PIOWD_DIR_ENTRYS(_n, _value) {				\
+		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY, _value);\
+		REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY, _value);}
+
+/* 
+ * There are 12 Node Presence MMRs, 4 in each primary DQ and 4 in the
+ * LB.  The data in the left and right DQ MMRs and the LB must match.
+ */
+#define MD_SET_PRESENT_VEC(_n, _vec, _value) {				   \
+		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_DIR_PRESVEC0+((_vec)*0x10),\
+			 _value);					   \
+		REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_DIR_PRESVEC0+((_vec)*0x10),\
+			 _value);					   \
+		REMOTE_HUB_S(_n, SH_SHUBS_PRESENT0+((_vec)*0x80), _value);}
+/*
+ * There are 16 Privilege Vector MMRs, 8 in each primary DQ.  The data
+ * in the corresponding left and right DQ MMRs must match.  Each MMR
+ * pair is used for a single partition.
+ */
+#define MD_SET_PRI_VEC(_n, _vec, _value) {				  \
+		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_DIR_PRIVEC0+((_vec)*0x10),\
+			 _value);					  \
+		REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_DIR_PRIVEC0+((_vec)*0x10),\
+			 _value);}
+/*
+ * There are 16 Local/Remote MMRs, 8 in each primary DQ.  The data in
+ * the corresponding left and right DQ MMRs must match.  Each MMR pair
+ * is used for a single partition.
+ */
+#define MD_SET_LOC_VEC(_n, _vec, _value) {				\
+		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_DIR_LOCVEC0+((_vec)*0x10),\
+			 _value);					\
+		REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_DIR_LOCVEC0+((_vec)*0x10),\
+			 _value);}
+
+/* Memory BIST CMDS */
+#define MD_DIMM_INIT_MODE_SET	0x0
+#define MD_DIMM_INIT_REFRESH	0x1
+#define MD_DIMM_INIT_PRECHARGE	0x2
+#define MD_DIMM_INIT_BURST_TERM	0x6
+#define MD_DIMM_INIT_NOP	0x7
+#define MD_DIMM_BIST_READ	0x10
+#define MD_FILL_DIR		0x20
+#define MD_FILL_DATA		0x30
+#define MD_FILL_DIR_ACCESS	0X40
+#define MD_READ_DIR_PAIR	0x50
+#define MD_READ_DIR_TAG		0x60
+
+/* SH_MMRBIST_CTL macros */
+#define MD_BIST_FAIL(_n) (REMOTE_HUB_L(_n, SH_MMRBIST_CTL) &		\
+                SH_MMRBIST_CTL_FAIL_MASK)
+
+#define MD_BIST_IN_PROGRESS(_n) (REMOTE_HUB_L(_n, SH_MMRBIST_CTL) & 	\
+                SH_MMRBIST_CTL_IN_PROGRESS_MASK)
+
+#define MD_BIST_MEM_IDLE(_n); (REMOTE_HUB_L(_n, SH_MMRBIST_CTL) & 	\
+                SH_MMRBIST_CTL_MEM_IDLE_MASK)
+
+/* SH_MMRBIST_ERR macros */
+#define MD_BIST_MISCOMPARE(_n) (REMOTE_HUB_L(_n, SH_MMRBIST_ERR) &	\
+		SH_MMRBIST_ERR_DETECTED_MASK)
+
+#endif	/* _SHUB_MD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/shub_mmr.h linux/include/asm-ia64/sn/sn2/shub_mmr.h
--- linux.orig/include/asm-ia64/sn/sn2/shub_mmr.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/shub_mmr.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,31597 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+
+#ifndef _ASM_IA64_SN_SN2_SHUB_MMR_H
+#define _ASM_IA64_SN_SN2_SHUB_MMR_H
+
+/* ==================================================================== */
+/*                   Register "SH_FSB_BINIT_CONTROL"                    */
+/*                          FSB BINIT# Control                          */
+/* ==================================================================== */
+
+#define SH_FSB_BINIT_CONTROL                     0x0000000120010000
+#define SH_FSB_BINIT_CONTROL_MASK                0x0000000000000001
+#define SH_FSB_BINIT_CONTROL_INIT                0x0000000000000000
+
+/*   SH_FSB_BINIT_CONTROL_BINIT                                         */
+/*   Description:  Assert the FSB's BINIT# Signal                       */
+#define SH_FSB_BINIT_CONTROL_BINIT_SHFT          0
+#define SH_FSB_BINIT_CONTROL_BINIT_MASK          0x0000000000000001
+
+/* ==================================================================== */
+/*                   Register "SH_FSB_RESET_CONTROL"                    */
+/*                          FSB Reset Control                           */
+/* ==================================================================== */
+
+#define SH_FSB_RESET_CONTROL                     0x0000000120010080
+#define SH_FSB_RESET_CONTROL_MASK                0x0000000000000001
+#define SH_FSB_RESET_CONTROL_INIT                0x0000000000000000
+
+/*   SH_FSB_RESET_CONTROL_RESET                                         */
+/*   Description:  Assert the FSB's RESET# Signal                       */
+#define SH_FSB_RESET_CONTROL_RESET_SHFT          0
+#define SH_FSB_RESET_CONTROL_RESET_MASK          0x0000000000000001
+
+/* ==================================================================== */
+/*                Register "SH_FSB_SYSTEM_AGENT_CONFIG"                 */
+/*                    FSB System Agent Configuration                    */
+/* ==================================================================== */
+
+#define SH_FSB_SYSTEM_AGENT_CONFIG               0x0000000120010100
+#define SH_FSB_SYSTEM_AGENT_CONFIG_MASK          0x00003fff0187fff9
+#define SH_FSB_SYSTEM_AGENT_CONFIG_INIT          0x0000000000000000
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_RCNT_SCNT_EN                            */
+/*   Description:  RCNT/SCNT Assertion Enabled                          */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_RCNT_SCNT_EN_SHFT 0
+#define SH_FSB_SYSTEM_AGENT_CONFIG_RCNT_SCNT_EN_MASK 0x0000000000000001
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_BERR_ASSERT_EN                          */
+/*   Description:  BERR Assertion Enabled for Bus Errors                */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BERR_ASSERT_EN_SHFT 3
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BERR_ASSERT_EN_MASK 0x0000000000000008
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_BERR_SAMPLING_EN                        */
+/*   Description:  BERR Sampling Enabled                                */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BERR_SAMPLING_EN_SHFT 4
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BERR_SAMPLING_EN_MASK 0x0000000000000010
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_BINIT_ASSERT_EN                         */
+/*   Description:  BINIT Assertion Enabled                              */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BINIT_ASSERT_EN_SHFT 5
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BINIT_ASSERT_EN_MASK 0x0000000000000020
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_BNR_THROTTLING_EN                       */
+/*   Description:  stutter FSB request assertion                        */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BNR_THROTTLING_EN_SHFT 6
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BNR_THROTTLING_EN_MASK 0x0000000000000040
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_SHORT_HANG_EN                           */
+/*   Description:  use short duration hang timeout                      */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_SHORT_HANG_EN_SHFT 7
+#define SH_FSB_SYSTEM_AGENT_CONFIG_SHORT_HANG_EN_MASK 0x0000000000000080
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_INTA_RSP_DATA                           */
+/*   Description:  Interrupt Acknowledge Response Data                  */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_INTA_RSP_DATA_SHFT 8
+#define SH_FSB_SYSTEM_AGENT_CONFIG_INTA_RSP_DATA_MASK 0x000000000000ff00
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_IO_TRANS_RSP                            */
+/*   Description:  IO Transaction Response                              */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_IO_TRANS_RSP_SHFT 16
+#define SH_FSB_SYSTEM_AGENT_CONFIG_IO_TRANS_RSP_MASK 0x0000000000010000
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_XTPR_TRANS_RSP                          */
+/*   Description:  External Task Priority Register (xTPR) Transaction   */
+/*  Response                                                            */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_XTPR_TRANS_RSP_SHFT 17
+#define SH_FSB_SYSTEM_AGENT_CONFIG_XTPR_TRANS_RSP_MASK 0x0000000000020000
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_INTA_TRANS_RSP                          */
+/*   Description:  Interrupt Acknowledge Transaction Response           */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_INTA_TRANS_RSP_SHFT 18
+#define SH_FSB_SYSTEM_AGENT_CONFIG_INTA_TRANS_RSP_MASK 0x0000000000040000
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_TDOT                                    */
+/*   Description:  Throttle Data-bus Ownership Transitions              */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_TDOT_SHFT     23
+#define SH_FSB_SYSTEM_AGENT_CONFIG_TDOT_MASK     0x0000000000800000
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_SERIALIZE_FSB_EN                        */
+/*   Description:  serialize processor transactions                     */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_SERIALIZE_FSB_EN_SHFT 24
+#define SH_FSB_SYSTEM_AGENT_CONFIG_SERIALIZE_FSB_EN_MASK 0x0000000001000000
+
+/*   SH_FSB_SYSTEM_AGENT_CONFIG_BINIT_EVENT_ENABLES                     */
+/*   Description:  FSB error binit enables                              */
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BINIT_EVENT_ENABLES_SHFT 32
+#define SH_FSB_SYSTEM_AGENT_CONFIG_BINIT_EVENT_ENABLES_MASK 0x00003fff00000000
+
+/* ==================================================================== */
+/*                     Register "SH_FSB_VGA_REMAP"                      */
+/*                     FSB VGA Address Space Remap                      */
+/* ==================================================================== */
+
+#define SH_FSB_VGA_REMAP                         0x0000000120010180
+#define SH_FSB_VGA_REMAP_MASK                    0x4001fffffffe0000
+#define SH_FSB_VGA_REMAP_INIT                    0x0000000000000000
+
+/*   SH_FSB_VGA_REMAP_OFFSET                                            */
+/*   Description:  VGA Remap Node Offset                                */
+#define SH_FSB_VGA_REMAP_OFFSET_SHFT             17
+#define SH_FSB_VGA_REMAP_OFFSET_MASK             0x0000000ffffe0000
+
+/*   SH_FSB_VGA_REMAP_ASID                                              */
+/*   Description:  VGA Remap Address Space ID                           */
+#define SH_FSB_VGA_REMAP_ASID_SHFT               36
+#define SH_FSB_VGA_REMAP_ASID_MASK               0x0000003000000000
+
+/*   SH_FSB_VGA_REMAP_NID                                               */
+/*   Description:  VGA Remap Node ID                                    */
+#define SH_FSB_VGA_REMAP_NID_SHFT                38
+#define SH_FSB_VGA_REMAP_NID_MASK                0x0001ffc000000000
+
+/*   SH_FSB_VGA_REMAP_VGA_REMAPPING_ENABLED                             */
+/*   Description:  VGA Remapping Enabled                                */
+#define SH_FSB_VGA_REMAP_VGA_REMAPPING_ENABLED_SHFT 62
+#define SH_FSB_VGA_REMAP_VGA_REMAPPING_ENABLED_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_FSB_RESET_STATUS"                    */
+/*                           FSB Reset Status                           */
+/* ==================================================================== */
+
+#define SH_FSB_RESET_STATUS                      0x0000000120020000
+#define SH_FSB_RESET_STATUS_MASK                 0x0000000000000001
+#define SH_FSB_RESET_STATUS_INIT                 0x0000000000000000
+
+/*   SH_FSB_RESET_STATUS_RESET_IN_PROGRESS                              */
+/*   Description:  Reset in Progress                                    */
+#define SH_FSB_RESET_STATUS_RESET_IN_PROGRESS_SHFT 0
+#define SH_FSB_RESET_STATUS_RESET_IN_PROGRESS_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*               Register "SH_FSB_SYMMETRIC_AGENT_STATUS"               */
+/*                      FSB Symmetric Agent Status                      */
+/* ==================================================================== */
+
+#define SH_FSB_SYMMETRIC_AGENT_STATUS            0x0000000120020080
+#define SH_FSB_SYMMETRIC_AGENT_STATUS_MASK       0x0000000000000007
+#define SH_FSB_SYMMETRIC_AGENT_STATUS_INIT       0x0000000000000000
+
+/*   SH_FSB_SYMMETRIC_AGENT_STATUS_CPU_0_ACTIVE                         */
+/*   Description:  CPU 0 Active.                                        */
+#define SH_FSB_SYMMETRIC_AGENT_STATUS_CPU_0_ACTIVE_SHFT 0
+#define SH_FSB_SYMMETRIC_AGENT_STATUS_CPU_0_ACTIVE_MASK 0x0000000000000001
+
+/*   SH_FSB_SYMMETRIC_AGENT_STATUS_CPU_1_ACTIVE                         */
+/*   Description:  CPU 1 Active.                                        */
+#define SH_FSB_SYMMETRIC_AGENT_STATUS_CPU_1_ACTIVE_SHFT 1
+#define SH_FSB_SYMMETRIC_AGENT_STATUS_CPU_1_ACTIVE_MASK 0x0000000000000002
+
+/*   SH_FSB_SYMMETRIC_AGENT_STATUS_CPUS_READY                           */
+/*   Description:  The Processors are Ready                             */
+#define SH_FSB_SYMMETRIC_AGENT_STATUS_CPUS_READY_SHFT 2
+#define SH_FSB_SYMMETRIC_AGENT_STATUS_CPUS_READY_MASK 0x0000000000000004
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_CREDIT_COUNT_0"                   */
+/*                Graphics-write Credit Count for CPU 0                 */
+/* ==================================================================== */
+
+#define SH_GFX_CREDIT_COUNT_0                    0x0000000120030000
+#define SH_GFX_CREDIT_COUNT_0_MASK               0x80000000000fffff
+#define SH_GFX_CREDIT_COUNT_0_INIT               0x000000000000003f
+
+/*   SH_GFX_CREDIT_COUNT_0_COUNT                                        */
+/*   Description:  Credit Count                                         */
+#define SH_GFX_CREDIT_COUNT_0_COUNT_SHFT         0
+#define SH_GFX_CREDIT_COUNT_0_COUNT_MASK         0x00000000000fffff
+
+/*   SH_GFX_CREDIT_COUNT_0_RESET_GFX_STATE                              */
+/*   Description:  Reset GFX state                                      */
+#define SH_GFX_CREDIT_COUNT_0_RESET_GFX_STATE_SHFT 63
+#define SH_GFX_CREDIT_COUNT_0_RESET_GFX_STATE_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_CREDIT_COUNT_1"                   */
+/*                Graphics-write Credit Count for CPU 1                 */
+/* ==================================================================== */
+
+#define SH_GFX_CREDIT_COUNT_1                    0x0000000120030080
+#define SH_GFX_CREDIT_COUNT_1_MASK               0x80000000000fffff
+#define SH_GFX_CREDIT_COUNT_1_INIT               0x000000000000003f
+
+/*   SH_GFX_CREDIT_COUNT_1_COUNT                                        */
+/*   Description:  Credit Count                                         */
+#define SH_GFX_CREDIT_COUNT_1_COUNT_SHFT         0
+#define SH_GFX_CREDIT_COUNT_1_COUNT_MASK         0x00000000000fffff
+
+/*   SH_GFX_CREDIT_COUNT_1_RESET_GFX_STATE                              */
+/*   Description:  Reset GFX state                                      */
+#define SH_GFX_CREDIT_COUNT_1_RESET_GFX_STATE_SHFT 63
+#define SH_GFX_CREDIT_COUNT_1_RESET_GFX_STATE_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_GFX_MODE_CNTRL_0"                    */
+/*         Graphics credit mode amd message ordering for CPU 0          */
+/* ==================================================================== */
+
+#define SH_GFX_MODE_CNTRL_0                      0x0000000120030100
+#define SH_GFX_MODE_CNTRL_0_MASK                 0x0000000000000007
+#define SH_GFX_MODE_CNTRL_0_INIT                 0x0000000000000003
+
+/*   SH_GFX_MODE_CNTRL_0_DWORD_CREDITS                                  */
+/*   Description:  GFX credits are tracked by D-words                   */
+#define SH_GFX_MODE_CNTRL_0_DWORD_CREDITS_SHFT   0
+#define SH_GFX_MODE_CNTRL_0_DWORD_CREDITS_MASK   0x0000000000000001
+
+/*   SH_GFX_MODE_CNTRL_0_MIXED_MODE_CREDITS                             */
+/*   Description:  GFX credits are tracked by D-words and messages      */
+#define SH_GFX_MODE_CNTRL_0_MIXED_MODE_CREDITS_SHFT 1
+#define SH_GFX_MODE_CNTRL_0_MIXED_MODE_CREDITS_MASK 0x0000000000000002
+
+/*   SH_GFX_MODE_CNTRL_0_RELAXED_ORDERING                               */
+/*   Description:  GFX message routing order                            */
+#define SH_GFX_MODE_CNTRL_0_RELAXED_ORDERING_SHFT 2
+#define SH_GFX_MODE_CNTRL_0_RELAXED_ORDERING_MASK 0x0000000000000004
+
+/* ==================================================================== */
+/*                    Register "SH_GFX_MODE_CNTRL_1"                    */
+/*         Graphics credit mode amd message ordering for CPU 1          */
+/* ==================================================================== */
+
+#define SH_GFX_MODE_CNTRL_1                      0x0000000120030180
+#define SH_GFX_MODE_CNTRL_1_MASK                 0x0000000000000007
+#define SH_GFX_MODE_CNTRL_1_INIT                 0x0000000000000003
+
+/*   SH_GFX_MODE_CNTRL_1_DWORD_CREDITS                                  */
+/*   Description:  GFX credits are tracked by D-words                   */
+#define SH_GFX_MODE_CNTRL_1_DWORD_CREDITS_SHFT   0
+#define SH_GFX_MODE_CNTRL_1_DWORD_CREDITS_MASK   0x0000000000000001
+
+/*   SH_GFX_MODE_CNTRL_1_MIXED_MODE_CREDITS                             */
+/*   Description:  GFX credits are tracked by D-words and messages      */
+#define SH_GFX_MODE_CNTRL_1_MIXED_MODE_CREDITS_SHFT 1
+#define SH_GFX_MODE_CNTRL_1_MIXED_MODE_CREDITS_MASK 0x0000000000000002
+
+/*   SH_GFX_MODE_CNTRL_1_RELAXED_ORDERING                               */
+/*   Description:  GFX message routing order                            */
+#define SH_GFX_MODE_CNTRL_1_RELAXED_ORDERING_SHFT 2
+#define SH_GFX_MODE_CNTRL_1_RELAXED_ORDERING_MASK 0x0000000000000004
+
+/* ==================================================================== */
+/*                Register "SH_GFX_SKID_CREDIT_COUNT_0"                 */
+/*              Graphics-write Skid Credit Count for CPU 0              */
+/* ==================================================================== */
+
+#define SH_GFX_SKID_CREDIT_COUNT_0               0x0000000120030200
+#define SH_GFX_SKID_CREDIT_COUNT_0_MASK          0x00000000000fffff
+#define SH_GFX_SKID_CREDIT_COUNT_0_INIT          0x0000000000000030
+
+/*   SH_GFX_SKID_CREDIT_COUNT_0_SKID                                    */
+/*   Description:  Skid Credit Count                                    */
+#define SH_GFX_SKID_CREDIT_COUNT_0_SKID_SHFT     0
+#define SH_GFX_SKID_CREDIT_COUNT_0_SKID_MASK     0x00000000000fffff
+
+/* ==================================================================== */
+/*                Register "SH_GFX_SKID_CREDIT_COUNT_1"                 */
+/*              Graphics-write Skid Credit Count for CPU 1              */
+/* ==================================================================== */
+
+#define SH_GFX_SKID_CREDIT_COUNT_1               0x0000000120030280
+#define SH_GFX_SKID_CREDIT_COUNT_1_MASK          0x00000000000fffff
+#define SH_GFX_SKID_CREDIT_COUNT_1_INIT          0x0000000000000030
+
+/*   SH_GFX_SKID_CREDIT_COUNT_1_SKID                                    */
+/*   Description:  Skid Credit Count                                    */
+#define SH_GFX_SKID_CREDIT_COUNT_1_SKID_SHFT     0
+#define SH_GFX_SKID_CREDIT_COUNT_1_SKID_MASK     0x00000000000fffff
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_STALL_LIMIT_0"                    */
+/*                 Graphics-write Stall Limit for CPU 0                 */
+/* ==================================================================== */
+
+#define SH_GFX_STALL_LIMIT_0                     0x0000000120030300
+#define SH_GFX_STALL_LIMIT_0_MASK                0x0000000003ffffff
+#define SH_GFX_STALL_LIMIT_0_INIT                0x0000000000010000
+
+/*   SH_GFX_STALL_LIMIT_0_LIMIT                                         */
+/*   Description:  Graphics Stall Limit for CPU 0                       */
+#define SH_GFX_STALL_LIMIT_0_LIMIT_SHFT          0
+#define SH_GFX_STALL_LIMIT_0_LIMIT_MASK          0x0000000003ffffff
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_STALL_LIMIT_1"                    */
+/*                 Graphics-write Stall Limit for CPU 1                 */
+/* ==================================================================== */
+
+#define SH_GFX_STALL_LIMIT_1                     0x0000000120030380
+#define SH_GFX_STALL_LIMIT_1_MASK                0x0000000003ffffff
+#define SH_GFX_STALL_LIMIT_1_INIT                0x0000000000010000
+
+/*   SH_GFX_STALL_LIMIT_1_LIMIT                                         */
+/*   Description:  Graphics Stall Limit for CPU 1                       */
+#define SH_GFX_STALL_LIMIT_1_LIMIT_SHFT          0
+#define SH_GFX_STALL_LIMIT_1_LIMIT_MASK          0x0000000003ffffff
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_STALL_TIMER_0"                    */
+/*                 Graphics-write Stall Timer for CPU 0                 */
+/* ==================================================================== */
+
+#define SH_GFX_STALL_TIMER_0                     0x0000000120030400
+#define SH_GFX_STALL_TIMER_0_MASK                0x0000000003ffffff
+#define SH_GFX_STALL_TIMER_0_INIT                0x0000000000000000
+
+/*   SH_GFX_STALL_TIMER_0_TIMER_VALUE                                   */
+/*   Description:  Timer Value                                          */
+#define SH_GFX_STALL_TIMER_0_TIMER_VALUE_SHFT    0
+#define SH_GFX_STALL_TIMER_0_TIMER_VALUE_MASK    0x0000000003ffffff
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_STALL_TIMER_1"                    */
+/*                 Graphics-write Stall Timer for CPU 1                 */
+/* ==================================================================== */
+
+#define SH_GFX_STALL_TIMER_1                     0x0000000120030480
+#define SH_GFX_STALL_TIMER_1_MASK                0x0000000003ffffff
+#define SH_GFX_STALL_TIMER_1_INIT                0x0000000000000000
+
+/*   SH_GFX_STALL_TIMER_1_TIMER_VALUE                                   */
+/*   Description:  Timer Value                                          */
+#define SH_GFX_STALL_TIMER_1_TIMER_VALUE_SHFT    0
+#define SH_GFX_STALL_TIMER_1_TIMER_VALUE_MASK    0x0000000003ffffff
+
+/* ==================================================================== */
+/*                      Register "SH_GFX_WINDOW_0"                      */
+/*                   Graphics-write Window for CPU 0                    */
+/* ==================================================================== */
+
+#define SH_GFX_WINDOW_0                          0x0000000120030500
+#define SH_GFX_WINDOW_0_MASK                     0x8000000fff000000
+#define SH_GFX_WINDOW_0_INIT                     0x0000000000000000
+
+/*   SH_GFX_WINDOW_0_BASE_ADDR                                          */
+/*   Description:  Base Address for CPU 0's 16 MB Graphics Window       */
+#define SH_GFX_WINDOW_0_BASE_ADDR_SHFT           24
+#define SH_GFX_WINDOW_0_BASE_ADDR_MASK           0x0000000fff000000
+
+/*   SH_GFX_WINDOW_0_GFX_WINDOW_EN                                      */
+/*   Description:  Graphics Window Enabled                              */
+#define SH_GFX_WINDOW_0_GFX_WINDOW_EN_SHFT       63
+#define SH_GFX_WINDOW_0_GFX_WINDOW_EN_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                      Register "SH_GFX_WINDOW_1"                      */
+/*                   Graphics-write Window for CPU 1                    */
+/* ==================================================================== */
+
+#define SH_GFX_WINDOW_1                          0x0000000120030580
+#define SH_GFX_WINDOW_1_MASK                     0x8000000fff000000
+#define SH_GFX_WINDOW_1_INIT                     0x0000000000000000
+
+/*   SH_GFX_WINDOW_1_BASE_ADDR                                          */
+/*   Description:  Base Address for CPU 1's 16 MB Graphics Window       */
+#define SH_GFX_WINDOW_1_BASE_ADDR_SHFT           24
+#define SH_GFX_WINDOW_1_BASE_ADDR_MASK           0x0000000fff000000
+
+/*   SH_GFX_WINDOW_1_GFX_WINDOW_EN                                      */
+/*   Description:  Graphics Window Enabled                              */
+#define SH_GFX_WINDOW_1_GFX_WINDOW_EN_SHFT       63
+#define SH_GFX_WINDOW_1_GFX_WINDOW_EN_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*              Register "SH_GFX_INTERRUPT_TIMER_LIMIT_0"               */
+/*               Graphics-write Interrupt Limit for CPU 0               */
+/* ==================================================================== */
+
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_0           0x0000000120030600
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_0_MASK      0x00000000000000ff
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_0_INIT      0x0000000000000040
+
+/*   SH_GFX_INTERRUPT_TIMER_LIMIT_0_INTERRUPT_TIMER_LIMIT               */
+/*   Description:  GFX Interrupt Timer Limit                            */
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_0_INTERRUPT_TIMER_LIMIT_SHFT 0
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_0_INTERRUPT_TIMER_LIMIT_MASK 0x00000000000000ff
+
+/* ==================================================================== */
+/*              Register "SH_GFX_INTERRUPT_TIMER_LIMIT_1"               */
+/*               Graphics-write Interrupt Limit for CPU 1               */
+/* ==================================================================== */
+
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_1           0x0000000120030680
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_1_MASK      0x00000000000000ff
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_1_INIT      0x0000000000000040
+
+/*   SH_GFX_INTERRUPT_TIMER_LIMIT_1_INTERRUPT_TIMER_LIMIT               */
+/*   Description:  GFX Interrupt Timer Limit                            */
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_1_INTERRUPT_TIMER_LIMIT_SHFT 0
+#define SH_GFX_INTERRUPT_TIMER_LIMIT_1_INTERRUPT_TIMER_LIMIT_MASK 0x00000000000000ff
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_WRITE_STATUS_0"                   */
+/*                   Graphics Write Status for CPU 0                    */
+/* ==================================================================== */
+
+#define SH_GFX_WRITE_STATUS_0                    0x0000000120040000
+#define SH_GFX_WRITE_STATUS_0_MASK               0x8000000000000001
+#define SH_GFX_WRITE_STATUS_0_INIT               0x0000000000000000
+
+/*   SH_GFX_WRITE_STATUS_0_BUSY                                         */
+/*   Description:  Busy                                                 */
+#define SH_GFX_WRITE_STATUS_0_BUSY_SHFT          0
+#define SH_GFX_WRITE_STATUS_0_BUSY_MASK          0x0000000000000001
+
+/*   SH_GFX_WRITE_STATUS_0_RE_ENABLE_GFX_STALL                          */
+/*   Description:  Re-enable GFX stall logic for this processor         */
+#define SH_GFX_WRITE_STATUS_0_RE_ENABLE_GFX_STALL_SHFT 63
+#define SH_GFX_WRITE_STATUS_0_RE_ENABLE_GFX_STALL_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_WRITE_STATUS_1"                   */
+/*                   Graphics Write Status for CPU 1                    */
+/* ==================================================================== */
+
+#define SH_GFX_WRITE_STATUS_1                    0x0000000120040080
+#define SH_GFX_WRITE_STATUS_1_MASK               0x8000000000000001
+#define SH_GFX_WRITE_STATUS_1_INIT               0x0000000000000000
+
+/*   SH_GFX_WRITE_STATUS_1_BUSY                                         */
+/*   Description:  Busy                                                 */
+#define SH_GFX_WRITE_STATUS_1_BUSY_SHFT          0
+#define SH_GFX_WRITE_STATUS_1_BUSY_MASK          0x0000000000000001
+
+/*   SH_GFX_WRITE_STATUS_1_RE_ENABLE_GFX_STALL                          */
+/*   Description:  Re-enable GFX stall logic for this processor         */
+#define SH_GFX_WRITE_STATUS_1_RE_ENABLE_GFX_STALL_SHFT 63
+#define SH_GFX_WRITE_STATUS_1_RE_ENABLE_GFX_STALL_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                        Register "SH_II_INT0"                         */
+/*                    SHub II Interrupt 0 Registers                     */
+/* ==================================================================== */
+
+#define SH_II_INT0                               0x0000000110000000
+#define SH_II_INT0_MASK                          0x00000000000001ff
+#define SH_II_INT0_INIT                          0x0000000000000000
+
+/*   SH_II_INT0_IDX                                                     */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_II_INT0_IDX_SHFT                      0
+#define SH_II_INT0_IDX_MASK                      0x00000000000000ff
+
+/*   SH_II_INT0_SEND                                                    */
+/*   Description:  Send Interrupt Message to PI, This generates a puls  */
+#define SH_II_INT0_SEND_SHFT                     8
+#define SH_II_INT0_SEND_MASK                     0x0000000000000100
+
+/* ==================================================================== */
+/*                     Register "SH_II_INT0_CONFIG"                     */
+/*                 SHub II Interrupt 0 Config Registers                 */
+/* ==================================================================== */
+
+#define SH_II_INT0_CONFIG                        0x0000000110000080
+#define SH_II_INT0_CONFIG_MASK                   0x0003ffffffefffff
+#define SH_II_INT0_CONFIG_INIT                   0x0000000000000000
+
+/*   SH_II_INT0_CONFIG_TYPE                                             */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_II_INT0_CONFIG_TYPE_SHFT              0
+#define SH_II_INT0_CONFIG_TYPE_MASK              0x0000000000000007
+
+/*   SH_II_INT0_CONFIG_AGT                                              */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_II_INT0_CONFIG_AGT_SHFT               3
+#define SH_II_INT0_CONFIG_AGT_MASK               0x0000000000000008
+
+/*   SH_II_INT0_CONFIG_PID                                              */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_II_INT0_CONFIG_PID_SHFT               4
+#define SH_II_INT0_CONFIG_PID_MASK               0x00000000000ffff0
+
+/*   SH_II_INT0_CONFIG_BASE                                             */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_II_INT0_CONFIG_BASE_SHFT              21
+#define SH_II_INT0_CONFIG_BASE_MASK              0x0003ffffffe00000
+
+/* ==================================================================== */
+/*                     Register "SH_II_INT0_ENABLE"                     */
+/*                 SHub II Interrupt 0 Enable Registers                 */
+/* ==================================================================== */
+
+#define SH_II_INT0_ENABLE                        0x0000000110000200
+#define SH_II_INT0_ENABLE_MASK                   0x0000000000000001
+#define SH_II_INT0_ENABLE_INIT                   0x0000000000000000
+
+/*   SH_II_INT0_ENABLE_II_ENABLE                                        */
+/*   Description:  Enable II Interrupt                                  */
+#define SH_II_INT0_ENABLE_II_ENABLE_SHFT         0
+#define SH_II_INT0_ENABLE_II_ENABLE_MASK         0x0000000000000001
+
+/* ==================================================================== */
+/*                        Register "SH_II_INT1"                         */
+/*                    SHub II Interrupt 1 Registers                     */
+/* ==================================================================== */
+
+#define SH_II_INT1                               0x0000000110000100
+#define SH_II_INT1_MASK                          0x00000000000001ff
+#define SH_II_INT1_INIT                          0x0000000000000000
+
+/*   SH_II_INT1_IDX                                                     */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_II_INT1_IDX_SHFT                      0
+#define SH_II_INT1_IDX_MASK                      0x00000000000000ff
+
+/*   SH_II_INT1_SEND                                                    */
+/*   Description:  Send Interrupt Message to PI, This generates a puls  */
+#define SH_II_INT1_SEND_SHFT                     8
+#define SH_II_INT1_SEND_MASK                     0x0000000000000100
+
+/* ==================================================================== */
+/*                     Register "SH_II_INT1_CONFIG"                     */
+/*                 SHub II Interrupt 1 Config Registers                 */
+/* ==================================================================== */
+
+#define SH_II_INT1_CONFIG                        0x0000000110000180
+#define SH_II_INT1_CONFIG_MASK                   0x0003ffffffefffff
+#define SH_II_INT1_CONFIG_INIT                   0x0000000000000000
+
+/*   SH_II_INT1_CONFIG_TYPE                                             */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_II_INT1_CONFIG_TYPE_SHFT              0
+#define SH_II_INT1_CONFIG_TYPE_MASK              0x0000000000000007
+
+/*   SH_II_INT1_CONFIG_AGT                                              */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_II_INT1_CONFIG_AGT_SHFT               3
+#define SH_II_INT1_CONFIG_AGT_MASK               0x0000000000000008
+
+/*   SH_II_INT1_CONFIG_PID                                              */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_II_INT1_CONFIG_PID_SHFT               4
+#define SH_II_INT1_CONFIG_PID_MASK               0x00000000000ffff0
+
+/*   SH_II_INT1_CONFIG_BASE                                             */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_II_INT1_CONFIG_BASE_SHFT              21
+#define SH_II_INT1_CONFIG_BASE_MASK              0x0003ffffffe00000
+
+/* ==================================================================== */
+/*                     Register "SH_II_INT1_ENABLE"                     */
+/*                 SHub II Interrupt 1 Enable Registers                 */
+/* ==================================================================== */
+
+#define SH_II_INT1_ENABLE                        0x0000000110000280
+#define SH_II_INT1_ENABLE_MASK                   0x0000000000000001
+#define SH_II_INT1_ENABLE_INIT                   0x0000000000000000
+
+/*   SH_II_INT1_ENABLE_II_ENABLE                                        */
+/*   Description:  Enable II 1 Interrupt                                */
+#define SH_II_INT1_ENABLE_II_ENABLE_SHFT         0
+#define SH_II_INT1_ENABLE_II_ENABLE_MASK         0x0000000000000001
+
+/* ==================================================================== */
+/*                   Register "SH_INT_NODE_ID_CONFIG"                   */
+/*                 SHub Interrupt Node ID Configuration                 */
+/* ==================================================================== */
+
+#define SH_INT_NODE_ID_CONFIG                    0x0000000110000300
+#define SH_INT_NODE_ID_CONFIG_MASK               0x0000000000000fff
+#define SH_INT_NODE_ID_CONFIG_INIT               0x0000000000000000
+
+/*   SH_INT_NODE_ID_CONFIG_NODE_ID                                      */
+/*   Description:  Node ID for interrupt messages                       */
+#define SH_INT_NODE_ID_CONFIG_NODE_ID_SHFT       0
+#define SH_INT_NODE_ID_CONFIG_NODE_ID_MASK       0x00000000000007ff
+
+/*   SH_INT_NODE_ID_CONFIG_ID_SEL                                       */
+/*   Description:  Select node id for interrupt messages                */
+#define SH_INT_NODE_ID_CONFIG_ID_SEL_SHFT        11
+#define SH_INT_NODE_ID_CONFIG_ID_SEL_MASK        0x0000000000000800
+
+/* ==================================================================== */
+/*                        Register "SH_IPI_INT"                         */
+/*               SHub Inter-Processor Interrupt Registers               */
+/* ==================================================================== */
+
+#define SH_IPI_INT                               0x0000000110000380
+#define SH_IPI_INT_MASK                          0x8ff3ffffffefffff
+#define SH_IPI_INT_INIT                          0x0000000000000000
+
+/*   SH_IPI_INT_TYPE                                                    */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_IPI_INT_TYPE_SHFT                     0
+#define SH_IPI_INT_TYPE_MASK                     0x0000000000000007
+
+/*   SH_IPI_INT_AGT                                                     */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_IPI_INT_AGT_SHFT                      3
+#define SH_IPI_INT_AGT_MASK                      0x0000000000000008
+
+/*   SH_IPI_INT_PID                                                     */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_IPI_INT_PID_SHFT                      4
+#define SH_IPI_INT_PID_MASK                      0x00000000000ffff0
+
+/*   SH_IPI_INT_BASE                                                    */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_IPI_INT_BASE_SHFT                     21
+#define SH_IPI_INT_BASE_MASK                     0x0003ffffffe00000
+
+/*   SH_IPI_INT_IDX                                                     */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_IPI_INT_IDX_SHFT                      52
+#define SH_IPI_INT_IDX_MASK                      0x0ff0000000000000
+
+/*   SH_IPI_INT_SEND                                                    */
+/*   Description:  Send Interrupt Message to PI, This generates a puls  */
+#define SH_IPI_INT_SEND_SHFT                     63
+#define SH_IPI_INT_SEND_MASK                     0x8000000000000000
+
+/* ==================================================================== */
+/*                     Register "SH_IPI_INT_ENABLE"                     */
+/*           SHub Inter-Processor Interrupt Enable Registers            */
+/* ==================================================================== */
+
+#define SH_IPI_INT_ENABLE                        0x0000000110000400
+#define SH_IPI_INT_ENABLE_MASK                   0x0000000000000001
+#define SH_IPI_INT_ENABLE_INIT                   0x0000000000000000
+
+/*   SH_IPI_INT_ENABLE_PIO_ENABLE                                       */
+/*   Description:  Enable PIO Interrupt                                 */
+#define SH_IPI_INT_ENABLE_PIO_ENABLE_SHFT        0
+#define SH_IPI_INT_ENABLE_PIO_ENABLE_MASK        0x0000000000000001
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT0_CONFIG"                    */
+/*                   SHub Local Interrupt 0 Registers                   */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT0_CONFIG                     0x0000000110000480
+#define SH_LOCAL_INT0_CONFIG_MASK                0x0ff3ffffffefffff
+#define SH_LOCAL_INT0_CONFIG_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT0_CONFIG_TYPE                                          */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_LOCAL_INT0_CONFIG_TYPE_SHFT           0
+#define SH_LOCAL_INT0_CONFIG_TYPE_MASK           0x0000000000000007
+
+/*   SH_LOCAL_INT0_CONFIG_AGT                                           */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_LOCAL_INT0_CONFIG_AGT_SHFT            3
+#define SH_LOCAL_INT0_CONFIG_AGT_MASK            0x0000000000000008
+
+/*   SH_LOCAL_INT0_CONFIG_PID                                           */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_LOCAL_INT0_CONFIG_PID_SHFT            4
+#define SH_LOCAL_INT0_CONFIG_PID_MASK            0x00000000000ffff0
+
+/*   SH_LOCAL_INT0_CONFIG_BASE                                          */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_LOCAL_INT0_CONFIG_BASE_SHFT           21
+#define SH_LOCAL_INT0_CONFIG_BASE_MASK           0x0003ffffffe00000
+
+/*   SH_LOCAL_INT0_CONFIG_IDX                                           */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_LOCAL_INT0_CONFIG_IDX_SHFT            52
+#define SH_LOCAL_INT0_CONFIG_IDX_MASK            0x0ff0000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT0_ENABLE"                    */
+/*                    SHub Local Interrupt 0 Enable                     */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT0_ENABLE                     0x0000000110000500
+#define SH_LOCAL_INT0_ENABLE_MASK                0x000000000000f7ff
+#define SH_LOCAL_INT0_ENABLE_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT0_ENABLE_PI_HW_INT                                     */
+/*   Description:  Enable PI Hardware interrupt                         */
+#define SH_LOCAL_INT0_ENABLE_PI_HW_INT_SHFT      0
+#define SH_LOCAL_INT0_ENABLE_PI_HW_INT_MASK      0x0000000000000001
+
+/*   SH_LOCAL_INT0_ENABLE_MD_HW_INT                                     */
+/*   Description:  Enable MD Hardware interrupt                         */
+#define SH_LOCAL_INT0_ENABLE_MD_HW_INT_SHFT      1
+#define SH_LOCAL_INT0_ENABLE_MD_HW_INT_MASK      0x0000000000000002
+
+/*   SH_LOCAL_INT0_ENABLE_XN_HW_INT                                     */
+/*   Description:  Enable XN Hardware interrupt                         */
+#define SH_LOCAL_INT0_ENABLE_XN_HW_INT_SHFT      2
+#define SH_LOCAL_INT0_ENABLE_XN_HW_INT_MASK      0x0000000000000004
+
+/*   SH_LOCAL_INT0_ENABLE_LB_HW_INT                                     */
+/*   Description:  Enable LB Hardware interrupt                         */
+#define SH_LOCAL_INT0_ENABLE_LB_HW_INT_SHFT      3
+#define SH_LOCAL_INT0_ENABLE_LB_HW_INT_MASK      0x0000000000000008
+
+/*   SH_LOCAL_INT0_ENABLE_II_HW_INT                                     */
+/*   Description:  Enable II wrapper Hardware interrupt                 */
+#define SH_LOCAL_INT0_ENABLE_II_HW_INT_SHFT      4
+#define SH_LOCAL_INT0_ENABLE_II_HW_INT_MASK      0x0000000000000010
+
+/*   SH_LOCAL_INT0_ENABLE_PI_CE_INT                                     */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT0_ENABLE_PI_CE_INT_SHFT      5
+#define SH_LOCAL_INT0_ENABLE_PI_CE_INT_MASK      0x0000000000000020
+
+/*   SH_LOCAL_INT0_ENABLE_MD_CE_INT                                     */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT0_ENABLE_MD_CE_INT_SHFT      6
+#define SH_LOCAL_INT0_ENABLE_MD_CE_INT_MASK      0x0000000000000040
+
+/*   SH_LOCAL_INT0_ENABLE_XN_CE_INT                                     */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT0_ENABLE_XN_CE_INT_SHFT      7
+#define SH_LOCAL_INT0_ENABLE_XN_CE_INT_MASK      0x0000000000000080
+
+/*   SH_LOCAL_INT0_ENABLE_PI_UCE_INT                                    */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT0_ENABLE_PI_UCE_INT_SHFT     8
+#define SH_LOCAL_INT0_ENABLE_PI_UCE_INT_MASK     0x0000000000000100
+
+/*   SH_LOCAL_INT0_ENABLE_MD_UCE_INT                                    */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT0_ENABLE_MD_UCE_INT_SHFT     9
+#define SH_LOCAL_INT0_ENABLE_MD_UCE_INT_MASK     0x0000000000000200
+
+/*   SH_LOCAL_INT0_ENABLE_XN_UCE_INT                                    */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT0_ENABLE_XN_UCE_INT_SHFT     10
+#define SH_LOCAL_INT0_ENABLE_XN_UCE_INT_MASK     0x0000000000000400
+
+/*   SH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT                           */
+/*   Description:  Enable System Shutdown Interrupt                     */
+#define SH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 12
+#define SH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000001000
+
+/*   SH_LOCAL_INT0_ENABLE_UART_INT                                      */
+/*   Description:  Enable Junk Bus UART Interrupt                       */
+#define SH_LOCAL_INT0_ENABLE_UART_INT_SHFT       13
+#define SH_LOCAL_INT0_ENABLE_UART_INT_MASK       0x0000000000002000
+
+/*   SH_LOCAL_INT0_ENABLE_L1_NMI_INT                                    */
+/*   Description:  Enable L1 Controller NMI Interrupt                   */
+#define SH_LOCAL_INT0_ENABLE_L1_NMI_INT_SHFT     14
+#define SH_LOCAL_INT0_ENABLE_L1_NMI_INT_MASK     0x0000000000004000
+
+/*   SH_LOCAL_INT0_ENABLE_STOP_CLOCK                                    */
+/*   Description:  Stop Clock Interrupt                                 */
+#define SH_LOCAL_INT0_ENABLE_STOP_CLOCK_SHFT     15
+#define SH_LOCAL_INT0_ENABLE_STOP_CLOCK_MASK     0x0000000000008000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT1_CONFIG"                    */
+/*                   SHub Local Interrupt 1 Registers                   */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT1_CONFIG                     0x0000000110000580
+#define SH_LOCAL_INT1_CONFIG_MASK                0x0ff3ffffffefffff
+#define SH_LOCAL_INT1_CONFIG_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT1_CONFIG_TYPE                                          */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_LOCAL_INT1_CONFIG_TYPE_SHFT           0
+#define SH_LOCAL_INT1_CONFIG_TYPE_MASK           0x0000000000000007
+
+/*   SH_LOCAL_INT1_CONFIG_AGT                                           */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_LOCAL_INT1_CONFIG_AGT_SHFT            3
+#define SH_LOCAL_INT1_CONFIG_AGT_MASK            0x0000000000000008
+
+/*   SH_LOCAL_INT1_CONFIG_PID                                           */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_LOCAL_INT1_CONFIG_PID_SHFT            4
+#define SH_LOCAL_INT1_CONFIG_PID_MASK            0x00000000000ffff0
+
+/*   SH_LOCAL_INT1_CONFIG_BASE                                          */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_LOCAL_INT1_CONFIG_BASE_SHFT           21
+#define SH_LOCAL_INT1_CONFIG_BASE_MASK           0x0003ffffffe00000
+
+/*   SH_LOCAL_INT1_CONFIG_IDX                                           */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_LOCAL_INT1_CONFIG_IDX_SHFT            52
+#define SH_LOCAL_INT1_CONFIG_IDX_MASK            0x0ff0000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT1_ENABLE"                    */
+/*                    SHub Local Interrupt 1 Enable                     */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT1_ENABLE                     0x0000000110000600
+#define SH_LOCAL_INT1_ENABLE_MASK                0x000000000000f7ff
+#define SH_LOCAL_INT1_ENABLE_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT1_ENABLE_PI_HW_INT                                     */
+/*   Description:  Enable PI Hardware interrupt                         */
+#define SH_LOCAL_INT1_ENABLE_PI_HW_INT_SHFT      0
+#define SH_LOCAL_INT1_ENABLE_PI_HW_INT_MASK      0x0000000000000001
+
+/*   SH_LOCAL_INT1_ENABLE_MD_HW_INT                                     */
+/*   Description:  Enable MD Hardware interrupt                         */
+#define SH_LOCAL_INT1_ENABLE_MD_HW_INT_SHFT      1
+#define SH_LOCAL_INT1_ENABLE_MD_HW_INT_MASK      0x0000000000000002
+
+/*   SH_LOCAL_INT1_ENABLE_XN_HW_INT                                     */
+/*   Description:  Enable XN Hardware interrupt                         */
+#define SH_LOCAL_INT1_ENABLE_XN_HW_INT_SHFT      2
+#define SH_LOCAL_INT1_ENABLE_XN_HW_INT_MASK      0x0000000000000004
+
+/*   SH_LOCAL_INT1_ENABLE_LB_HW_INT                                     */
+/*   Description:  Enable LB Hardware interrupt                         */
+#define SH_LOCAL_INT1_ENABLE_LB_HW_INT_SHFT      3
+#define SH_LOCAL_INT1_ENABLE_LB_HW_INT_MASK      0x0000000000000008
+
+/*   SH_LOCAL_INT1_ENABLE_II_HW_INT                                     */
+/*   Description:  Enable II wrapper Hardware interrupt                 */
+#define SH_LOCAL_INT1_ENABLE_II_HW_INT_SHFT      4
+#define SH_LOCAL_INT1_ENABLE_II_HW_INT_MASK      0x0000000000000010
+
+/*   SH_LOCAL_INT1_ENABLE_PI_CE_INT                                     */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT1_ENABLE_PI_CE_INT_SHFT      5
+#define SH_LOCAL_INT1_ENABLE_PI_CE_INT_MASK      0x0000000000000020
+
+/*   SH_LOCAL_INT1_ENABLE_MD_CE_INT                                     */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT1_ENABLE_MD_CE_INT_SHFT      6
+#define SH_LOCAL_INT1_ENABLE_MD_CE_INT_MASK      0x0000000000000040
+
+/*   SH_LOCAL_INT1_ENABLE_XN_CE_INT                                     */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT1_ENABLE_XN_CE_INT_SHFT      7
+#define SH_LOCAL_INT1_ENABLE_XN_CE_INT_MASK      0x0000000000000080
+
+/*   SH_LOCAL_INT1_ENABLE_PI_UCE_INT                                    */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT1_ENABLE_PI_UCE_INT_SHFT     8
+#define SH_LOCAL_INT1_ENABLE_PI_UCE_INT_MASK     0x0000000000000100
+
+/*   SH_LOCAL_INT1_ENABLE_MD_UCE_INT                                    */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT1_ENABLE_MD_UCE_INT_SHFT     9
+#define SH_LOCAL_INT1_ENABLE_MD_UCE_INT_MASK     0x0000000000000200
+
+/*   SH_LOCAL_INT1_ENABLE_XN_UCE_INT                                    */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT1_ENABLE_XN_UCE_INT_SHFT     10
+#define SH_LOCAL_INT1_ENABLE_XN_UCE_INT_MASK     0x0000000000000400
+
+/*   SH_LOCAL_INT1_ENABLE_SYSTEM_SHUTDOWN_INT                           */
+/*   Description:  Enable System Shutdown Interrupt                     */
+#define SH_LOCAL_INT1_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 12
+#define SH_LOCAL_INT1_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000001000
+
+/*   SH_LOCAL_INT1_ENABLE_UART_INT                                      */
+/*   Description:  Enable Junk Bus UART Interrupt                       */
+#define SH_LOCAL_INT1_ENABLE_UART_INT_SHFT       13
+#define SH_LOCAL_INT1_ENABLE_UART_INT_MASK       0x0000000000002000
+
+/*   SH_LOCAL_INT1_ENABLE_L1_NMI_INT                                    */
+/*   Description:  Enable L1 Controller NMI Interrupt                   */
+#define SH_LOCAL_INT1_ENABLE_L1_NMI_INT_SHFT     14
+#define SH_LOCAL_INT1_ENABLE_L1_NMI_INT_MASK     0x0000000000004000
+
+/*   SH_LOCAL_INT1_ENABLE_STOP_CLOCK                                    */
+/*   Description:  Stop Clock Interrupt                                 */
+#define SH_LOCAL_INT1_ENABLE_STOP_CLOCK_SHFT     15
+#define SH_LOCAL_INT1_ENABLE_STOP_CLOCK_MASK     0x0000000000008000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT2_CONFIG"                    */
+/*                   SHub Local Interrupt 2 Registers                   */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT2_CONFIG                     0x0000000110000680
+#define SH_LOCAL_INT2_CONFIG_MASK                0x0ff3ffffffefffff
+#define SH_LOCAL_INT2_CONFIG_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT2_CONFIG_TYPE                                          */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_LOCAL_INT2_CONFIG_TYPE_SHFT           0
+#define SH_LOCAL_INT2_CONFIG_TYPE_MASK           0x0000000000000007
+
+/*   SH_LOCAL_INT2_CONFIG_AGT                                           */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_LOCAL_INT2_CONFIG_AGT_SHFT            3
+#define SH_LOCAL_INT2_CONFIG_AGT_MASK            0x0000000000000008
+
+/*   SH_LOCAL_INT2_CONFIG_PID                                           */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_LOCAL_INT2_CONFIG_PID_SHFT            4
+#define SH_LOCAL_INT2_CONFIG_PID_MASK            0x00000000000ffff0
+
+/*   SH_LOCAL_INT2_CONFIG_BASE                                          */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_LOCAL_INT2_CONFIG_BASE_SHFT           21
+#define SH_LOCAL_INT2_CONFIG_BASE_MASK           0x0003ffffffe00000
+
+/*   SH_LOCAL_INT2_CONFIG_IDX                                           */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_LOCAL_INT2_CONFIG_IDX_SHFT            52
+#define SH_LOCAL_INT2_CONFIG_IDX_MASK            0x0ff0000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT2_ENABLE"                    */
+/*                    SHub Local Interrupt 2 Enable                     */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT2_ENABLE                     0x0000000110000700
+#define SH_LOCAL_INT2_ENABLE_MASK                0x000000000000f7ff
+#define SH_LOCAL_INT2_ENABLE_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT2_ENABLE_PI_HW_INT                                     */
+/*   Description:  Enable PI Hardware interrupt                         */
+#define SH_LOCAL_INT2_ENABLE_PI_HW_INT_SHFT      0
+#define SH_LOCAL_INT2_ENABLE_PI_HW_INT_MASK      0x0000000000000001
+
+/*   SH_LOCAL_INT2_ENABLE_MD_HW_INT                                     */
+/*   Description:  Enable MD Hardware interrupt                         */
+#define SH_LOCAL_INT2_ENABLE_MD_HW_INT_SHFT      1
+#define SH_LOCAL_INT2_ENABLE_MD_HW_INT_MASK      0x0000000000000002
+
+/*   SH_LOCAL_INT2_ENABLE_XN_HW_INT                                     */
+/*   Description:  Enable XN Hardware interrupt                         */
+#define SH_LOCAL_INT2_ENABLE_XN_HW_INT_SHFT      2
+#define SH_LOCAL_INT2_ENABLE_XN_HW_INT_MASK      0x0000000000000004
+
+/*   SH_LOCAL_INT2_ENABLE_LB_HW_INT                                     */
+/*   Description:  Enable LB Hardware interrupt                         */
+#define SH_LOCAL_INT2_ENABLE_LB_HW_INT_SHFT      3
+#define SH_LOCAL_INT2_ENABLE_LB_HW_INT_MASK      0x0000000000000008
+
+/*   SH_LOCAL_INT2_ENABLE_II_HW_INT                                     */
+/*   Description:  Enable II wrapper Hardware interrupt                 */
+#define SH_LOCAL_INT2_ENABLE_II_HW_INT_SHFT      4
+#define SH_LOCAL_INT2_ENABLE_II_HW_INT_MASK      0x0000000000000010
+
+/*   SH_LOCAL_INT2_ENABLE_PI_CE_INT                                     */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT2_ENABLE_PI_CE_INT_SHFT      5
+#define SH_LOCAL_INT2_ENABLE_PI_CE_INT_MASK      0x0000000000000020
+
+/*   SH_LOCAL_INT2_ENABLE_MD_CE_INT                                     */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT2_ENABLE_MD_CE_INT_SHFT      6
+#define SH_LOCAL_INT2_ENABLE_MD_CE_INT_MASK      0x0000000000000040
+
+/*   SH_LOCAL_INT2_ENABLE_XN_CE_INT                                     */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT2_ENABLE_XN_CE_INT_SHFT      7
+#define SH_LOCAL_INT2_ENABLE_XN_CE_INT_MASK      0x0000000000000080
+
+/*   SH_LOCAL_INT2_ENABLE_PI_UCE_INT                                    */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT2_ENABLE_PI_UCE_INT_SHFT     8
+#define SH_LOCAL_INT2_ENABLE_PI_UCE_INT_MASK     0x0000000000000100
+
+/*   SH_LOCAL_INT2_ENABLE_MD_UCE_INT                                    */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT2_ENABLE_MD_UCE_INT_SHFT     9
+#define SH_LOCAL_INT2_ENABLE_MD_UCE_INT_MASK     0x0000000000000200
+
+/*   SH_LOCAL_INT2_ENABLE_XN_UCE_INT                                    */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT2_ENABLE_XN_UCE_INT_SHFT     10
+#define SH_LOCAL_INT2_ENABLE_XN_UCE_INT_MASK     0x0000000000000400
+
+/*   SH_LOCAL_INT2_ENABLE_SYSTEM_SHUTDOWN_INT                           */
+/*   Description:  Enable System Shutdown Interrupt                     */
+#define SH_LOCAL_INT2_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 12
+#define SH_LOCAL_INT2_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000001000
+
+/*   SH_LOCAL_INT2_ENABLE_UART_INT                                      */
+/*   Description:  Enable Junk Bus UART Interrupt                       */
+#define SH_LOCAL_INT2_ENABLE_UART_INT_SHFT       13
+#define SH_LOCAL_INT2_ENABLE_UART_INT_MASK       0x0000000000002000
+
+/*   SH_LOCAL_INT2_ENABLE_L1_NMI_INT                                    */
+/*   Description:  Enable L1 Controller NMI Interrupt                   */
+#define SH_LOCAL_INT2_ENABLE_L1_NMI_INT_SHFT     14
+#define SH_LOCAL_INT2_ENABLE_L1_NMI_INT_MASK     0x0000000000004000
+
+/*   SH_LOCAL_INT2_ENABLE_STOP_CLOCK                                    */
+/*   Description:  Stop Clock Interrupt                                 */
+#define SH_LOCAL_INT2_ENABLE_STOP_CLOCK_SHFT     15
+#define SH_LOCAL_INT2_ENABLE_STOP_CLOCK_MASK     0x0000000000008000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT3_CONFIG"                    */
+/*                   SHub Local Interrupt 3 Registers                   */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT3_CONFIG                     0x0000000110000780
+#define SH_LOCAL_INT3_CONFIG_MASK                0x0ff3ffffffefffff
+#define SH_LOCAL_INT3_CONFIG_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT3_CONFIG_TYPE                                          */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_LOCAL_INT3_CONFIG_TYPE_SHFT           0
+#define SH_LOCAL_INT3_CONFIG_TYPE_MASK           0x0000000000000007
+
+/*   SH_LOCAL_INT3_CONFIG_AGT                                           */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_LOCAL_INT3_CONFIG_AGT_SHFT            3
+#define SH_LOCAL_INT3_CONFIG_AGT_MASK            0x0000000000000008
+
+/*   SH_LOCAL_INT3_CONFIG_PID                                           */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_LOCAL_INT3_CONFIG_PID_SHFT            4
+#define SH_LOCAL_INT3_CONFIG_PID_MASK            0x00000000000ffff0
+
+/*   SH_LOCAL_INT3_CONFIG_BASE                                          */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_LOCAL_INT3_CONFIG_BASE_SHFT           21
+#define SH_LOCAL_INT3_CONFIG_BASE_MASK           0x0003ffffffe00000
+
+/*   SH_LOCAL_INT3_CONFIG_IDX                                           */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_LOCAL_INT3_CONFIG_IDX_SHFT            52
+#define SH_LOCAL_INT3_CONFIG_IDX_MASK            0x0ff0000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT3_ENABLE"                    */
+/*                    SHub Local Interrupt 3 Enable                     */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT3_ENABLE                     0x0000000110000800
+#define SH_LOCAL_INT3_ENABLE_MASK                0x000000000000f7ff
+#define SH_LOCAL_INT3_ENABLE_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT3_ENABLE_PI_HW_INT                                     */
+/*   Description:  Enable PI Hardware interrupt                         */
+#define SH_LOCAL_INT3_ENABLE_PI_HW_INT_SHFT      0
+#define SH_LOCAL_INT3_ENABLE_PI_HW_INT_MASK      0x0000000000000001
+
+/*   SH_LOCAL_INT3_ENABLE_MD_HW_INT                                     */
+/*   Description:  Enable MD Hardware interrupt                         */
+#define SH_LOCAL_INT3_ENABLE_MD_HW_INT_SHFT      1
+#define SH_LOCAL_INT3_ENABLE_MD_HW_INT_MASK      0x0000000000000002
+
+/*   SH_LOCAL_INT3_ENABLE_XN_HW_INT                                     */
+/*   Description:  Enable XN Hardware interrupt                         */
+#define SH_LOCAL_INT3_ENABLE_XN_HW_INT_SHFT      2
+#define SH_LOCAL_INT3_ENABLE_XN_HW_INT_MASK      0x0000000000000004
+
+/*   SH_LOCAL_INT3_ENABLE_LB_HW_INT                                     */
+/*   Description:  Enable LB Hardware interrupt                         */
+#define SH_LOCAL_INT3_ENABLE_LB_HW_INT_SHFT      3
+#define SH_LOCAL_INT3_ENABLE_LB_HW_INT_MASK      0x0000000000000008
+
+/*   SH_LOCAL_INT3_ENABLE_II_HW_INT                                     */
+/*   Description:  Enable II wrapper Hardware interrupt                 */
+#define SH_LOCAL_INT3_ENABLE_II_HW_INT_SHFT      4
+#define SH_LOCAL_INT3_ENABLE_II_HW_INT_MASK      0x0000000000000010
+
+/*   SH_LOCAL_INT3_ENABLE_PI_CE_INT                                     */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT3_ENABLE_PI_CE_INT_SHFT      5
+#define SH_LOCAL_INT3_ENABLE_PI_CE_INT_MASK      0x0000000000000020
+
+/*   SH_LOCAL_INT3_ENABLE_MD_CE_INT                                     */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT3_ENABLE_MD_CE_INT_SHFT      6
+#define SH_LOCAL_INT3_ENABLE_MD_CE_INT_MASK      0x0000000000000040
+
+/*   SH_LOCAL_INT3_ENABLE_XN_CE_INT                                     */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT3_ENABLE_XN_CE_INT_SHFT      7
+#define SH_LOCAL_INT3_ENABLE_XN_CE_INT_MASK      0x0000000000000080
+
+/*   SH_LOCAL_INT3_ENABLE_PI_UCE_INT                                    */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT3_ENABLE_PI_UCE_INT_SHFT     8
+#define SH_LOCAL_INT3_ENABLE_PI_UCE_INT_MASK     0x0000000000000100
+
+/*   SH_LOCAL_INT3_ENABLE_MD_UCE_INT                                    */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT3_ENABLE_MD_UCE_INT_SHFT     9
+#define SH_LOCAL_INT3_ENABLE_MD_UCE_INT_MASK     0x0000000000000200
+
+/*   SH_LOCAL_INT3_ENABLE_XN_UCE_INT                                    */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT3_ENABLE_XN_UCE_INT_SHFT     10
+#define SH_LOCAL_INT3_ENABLE_XN_UCE_INT_MASK     0x0000000000000400
+
+/*   SH_LOCAL_INT3_ENABLE_SYSTEM_SHUTDOWN_INT                           */
+/*   Description:  Enable System Shutdown Interrupt                     */
+#define SH_LOCAL_INT3_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 12
+#define SH_LOCAL_INT3_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000001000
+
+/*   SH_LOCAL_INT3_ENABLE_UART_INT                                      */
+/*   Description:  Enable Junk Bus UART Interrupt                       */
+#define SH_LOCAL_INT3_ENABLE_UART_INT_SHFT       13
+#define SH_LOCAL_INT3_ENABLE_UART_INT_MASK       0x0000000000002000
+
+/*   SH_LOCAL_INT3_ENABLE_L1_NMI_INT                                    */
+/*   Description:  Enable L1 Controller NMI Interrupt                   */
+#define SH_LOCAL_INT3_ENABLE_L1_NMI_INT_SHFT     14
+#define SH_LOCAL_INT3_ENABLE_L1_NMI_INT_MASK     0x0000000000004000
+
+/*   SH_LOCAL_INT3_ENABLE_STOP_CLOCK                                    */
+/*   Description:  Stop Clock Interrupt                                 */
+#define SH_LOCAL_INT3_ENABLE_STOP_CLOCK_SHFT     15
+#define SH_LOCAL_INT3_ENABLE_STOP_CLOCK_MASK     0x0000000000008000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT4_CONFIG"                    */
+/*                   SHub Local Interrupt 4 Registers                   */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT4_CONFIG                     0x0000000110000880
+#define SH_LOCAL_INT4_CONFIG_MASK                0x0ff3ffffffefffff
+#define SH_LOCAL_INT4_CONFIG_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT4_CONFIG_TYPE                                          */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_LOCAL_INT4_CONFIG_TYPE_SHFT           0
+#define SH_LOCAL_INT4_CONFIG_TYPE_MASK           0x0000000000000007
+
+/*   SH_LOCAL_INT4_CONFIG_AGT                                           */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_LOCAL_INT4_CONFIG_AGT_SHFT            3
+#define SH_LOCAL_INT4_CONFIG_AGT_MASK            0x0000000000000008
+
+/*   SH_LOCAL_INT4_CONFIG_PID                                           */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_LOCAL_INT4_CONFIG_PID_SHFT            4
+#define SH_LOCAL_INT4_CONFIG_PID_MASK            0x00000000000ffff0
+
+/*   SH_LOCAL_INT4_CONFIG_BASE                                          */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_LOCAL_INT4_CONFIG_BASE_SHFT           21
+#define SH_LOCAL_INT4_CONFIG_BASE_MASK           0x0003ffffffe00000
+
+/*   SH_LOCAL_INT4_CONFIG_IDX                                           */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_LOCAL_INT4_CONFIG_IDX_SHFT            52
+#define SH_LOCAL_INT4_CONFIG_IDX_MASK            0x0ff0000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT4_ENABLE"                    */
+/*                    SHub Local Interrupt 4 Enable                     */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT4_ENABLE                     0x0000000110000900
+#define SH_LOCAL_INT4_ENABLE_MASK                0x000000000000f7ff
+#define SH_LOCAL_INT4_ENABLE_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT4_ENABLE_PI_HW_INT                                     */
+/*   Description:  Enable PI Hardware interrupt                         */
+#define SH_LOCAL_INT4_ENABLE_PI_HW_INT_SHFT      0
+#define SH_LOCAL_INT4_ENABLE_PI_HW_INT_MASK      0x0000000000000001
+
+/*   SH_LOCAL_INT4_ENABLE_MD_HW_INT                                     */
+/*   Description:  Enable MD Hardware interrupt                         */
+#define SH_LOCAL_INT4_ENABLE_MD_HW_INT_SHFT      1
+#define SH_LOCAL_INT4_ENABLE_MD_HW_INT_MASK      0x0000000000000002
+
+/*   SH_LOCAL_INT4_ENABLE_XN_HW_INT                                     */
+/*   Description:  Enable XN Hardware interrupt                         */
+#define SH_LOCAL_INT4_ENABLE_XN_HW_INT_SHFT      2
+#define SH_LOCAL_INT4_ENABLE_XN_HW_INT_MASK      0x0000000000000004
+
+/*   SH_LOCAL_INT4_ENABLE_LB_HW_INT                                     */
+/*   Description:  Enable LB Hardware interrupt                         */
+#define SH_LOCAL_INT4_ENABLE_LB_HW_INT_SHFT      3
+#define SH_LOCAL_INT4_ENABLE_LB_HW_INT_MASK      0x0000000000000008
+
+/*   SH_LOCAL_INT4_ENABLE_II_HW_INT                                     */
+/*   Description:  Enable II wrapper Hardware interrupt                 */
+#define SH_LOCAL_INT4_ENABLE_II_HW_INT_SHFT      4
+#define SH_LOCAL_INT4_ENABLE_II_HW_INT_MASK      0x0000000000000010
+
+/*   SH_LOCAL_INT4_ENABLE_PI_CE_INT                                     */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT4_ENABLE_PI_CE_INT_SHFT      5
+#define SH_LOCAL_INT4_ENABLE_PI_CE_INT_MASK      0x0000000000000020
+
+/*   SH_LOCAL_INT4_ENABLE_MD_CE_INT                                     */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT4_ENABLE_MD_CE_INT_SHFT      6
+#define SH_LOCAL_INT4_ENABLE_MD_CE_INT_MASK      0x0000000000000040
+
+/*   SH_LOCAL_INT4_ENABLE_XN_CE_INT                                     */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT4_ENABLE_XN_CE_INT_SHFT      7
+#define SH_LOCAL_INT4_ENABLE_XN_CE_INT_MASK      0x0000000000000080
+
+/*   SH_LOCAL_INT4_ENABLE_PI_UCE_INT                                    */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT4_ENABLE_PI_UCE_INT_SHFT     8
+#define SH_LOCAL_INT4_ENABLE_PI_UCE_INT_MASK     0x0000000000000100
+
+/*   SH_LOCAL_INT4_ENABLE_MD_UCE_INT                                    */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT4_ENABLE_MD_UCE_INT_SHFT     9
+#define SH_LOCAL_INT4_ENABLE_MD_UCE_INT_MASK     0x0000000000000200
+
+/*   SH_LOCAL_INT4_ENABLE_XN_UCE_INT                                    */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT4_ENABLE_XN_UCE_INT_SHFT     10
+#define SH_LOCAL_INT4_ENABLE_XN_UCE_INT_MASK     0x0000000000000400
+
+/*   SH_LOCAL_INT4_ENABLE_SYSTEM_SHUTDOWN_INT                           */
+/*   Description:  Enable System Shutdown Interrupt                     */
+#define SH_LOCAL_INT4_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 12
+#define SH_LOCAL_INT4_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000001000
+
+/*   SH_LOCAL_INT4_ENABLE_UART_INT                                      */
+/*   Description:  Enable Junk Bus UART Interrupt                       */
+#define SH_LOCAL_INT4_ENABLE_UART_INT_SHFT       13
+#define SH_LOCAL_INT4_ENABLE_UART_INT_MASK       0x0000000000002000
+
+/*   SH_LOCAL_INT4_ENABLE_L1_NMI_INT                                    */
+/*   Description:  Enable L1 Controller NMI Interrupt                   */
+#define SH_LOCAL_INT4_ENABLE_L1_NMI_INT_SHFT     14
+#define SH_LOCAL_INT4_ENABLE_L1_NMI_INT_MASK     0x0000000000004000
+
+/*   SH_LOCAL_INT4_ENABLE_STOP_CLOCK                                    */
+/*   Description:  Stop Clock Interrupt                                 */
+#define SH_LOCAL_INT4_ENABLE_STOP_CLOCK_SHFT     15
+#define SH_LOCAL_INT4_ENABLE_STOP_CLOCK_MASK     0x0000000000008000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT5_CONFIG"                    */
+/*                   SHub Local Interrupt 5 Registers                   */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT5_CONFIG                     0x0000000110000980
+#define SH_LOCAL_INT5_CONFIG_MASK                0x0ff3ffffffefffff
+#define SH_LOCAL_INT5_CONFIG_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT5_CONFIG_TYPE                                          */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_LOCAL_INT5_CONFIG_TYPE_SHFT           0
+#define SH_LOCAL_INT5_CONFIG_TYPE_MASK           0x0000000000000007
+
+/*   SH_LOCAL_INT5_CONFIG_AGT                                           */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_LOCAL_INT5_CONFIG_AGT_SHFT            3
+#define SH_LOCAL_INT5_CONFIG_AGT_MASK            0x0000000000000008
+
+/*   SH_LOCAL_INT5_CONFIG_PID                                           */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_LOCAL_INT5_CONFIG_PID_SHFT            4
+#define SH_LOCAL_INT5_CONFIG_PID_MASK            0x00000000000ffff0
+
+/*   SH_LOCAL_INT5_CONFIG_BASE                                          */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_LOCAL_INT5_CONFIG_BASE_SHFT           21
+#define SH_LOCAL_INT5_CONFIG_BASE_MASK           0x0003ffffffe00000
+
+/*   SH_LOCAL_INT5_CONFIG_IDX                                           */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_LOCAL_INT5_CONFIG_IDX_SHFT            52
+#define SH_LOCAL_INT5_CONFIG_IDX_MASK            0x0ff0000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT5_ENABLE"                    */
+/*                    SHub Local Interrupt 5 Enable                     */
+/* ==================================================================== */
+
+#define SH_LOCAL_INT5_ENABLE                     0x0000000110000a00
+#define SH_LOCAL_INT5_ENABLE_MASK                0x000000000000f7ff
+#define SH_LOCAL_INT5_ENABLE_INIT                0x0000000000000000
+
+/*   SH_LOCAL_INT5_ENABLE_PI_HW_INT                                     */
+/*   Description:  Enable PI Hardware interrupt                         */
+#define SH_LOCAL_INT5_ENABLE_PI_HW_INT_SHFT      0
+#define SH_LOCAL_INT5_ENABLE_PI_HW_INT_MASK      0x0000000000000001
+
+/*   SH_LOCAL_INT5_ENABLE_MD_HW_INT                                     */
+/*   Description:  Enable MD Hardware interrupt                         */
+#define SH_LOCAL_INT5_ENABLE_MD_HW_INT_SHFT      1
+#define SH_LOCAL_INT5_ENABLE_MD_HW_INT_MASK      0x0000000000000002
+
+/*   SH_LOCAL_INT5_ENABLE_XN_HW_INT                                     */
+/*   Description:  Enable XN Hardware interrupt                         */
+#define SH_LOCAL_INT5_ENABLE_XN_HW_INT_SHFT      2
+#define SH_LOCAL_INT5_ENABLE_XN_HW_INT_MASK      0x0000000000000004
+
+/*   SH_LOCAL_INT5_ENABLE_LB_HW_INT                                     */
+/*   Description:  Enable LB Hardware interrupt                         */
+#define SH_LOCAL_INT5_ENABLE_LB_HW_INT_SHFT      3
+#define SH_LOCAL_INT5_ENABLE_LB_HW_INT_MASK      0x0000000000000008
+
+/*   SH_LOCAL_INT5_ENABLE_II_HW_INT                                     */
+/*   Description:  Enable II wrapper Hardware interrupt                 */
+#define SH_LOCAL_INT5_ENABLE_II_HW_INT_SHFT      4
+#define SH_LOCAL_INT5_ENABLE_II_HW_INT_MASK      0x0000000000000010
+
+/*   SH_LOCAL_INT5_ENABLE_PI_CE_INT                                     */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT5_ENABLE_PI_CE_INT_SHFT      5
+#define SH_LOCAL_INT5_ENABLE_PI_CE_INT_MASK      0x0000000000000020
+
+/*   SH_LOCAL_INT5_ENABLE_MD_CE_INT                                     */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT5_ENABLE_MD_CE_INT_SHFT      6
+#define SH_LOCAL_INT5_ENABLE_MD_CE_INT_MASK      0x0000000000000040
+
+/*   SH_LOCAL_INT5_ENABLE_XN_CE_INT                                     */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT5_ENABLE_XN_CE_INT_SHFT      7
+#define SH_LOCAL_INT5_ENABLE_XN_CE_INT_MASK      0x0000000000000080
+
+/*   SH_LOCAL_INT5_ENABLE_PI_UCE_INT                                    */
+/*   Description:  Enable PI Correctable Error Interrupt                */
+#define SH_LOCAL_INT5_ENABLE_PI_UCE_INT_SHFT     8
+#define SH_LOCAL_INT5_ENABLE_PI_UCE_INT_MASK     0x0000000000000100
+
+/*   SH_LOCAL_INT5_ENABLE_MD_UCE_INT                                    */
+/*   Description:  Enable MD Correctable Error Interrupt                */
+#define SH_LOCAL_INT5_ENABLE_MD_UCE_INT_SHFT     9
+#define SH_LOCAL_INT5_ENABLE_MD_UCE_INT_MASK     0x0000000000000200
+
+/*   SH_LOCAL_INT5_ENABLE_XN_UCE_INT                                    */
+/*   Description:  Enable XN Correctable Error Interrupt                */
+#define SH_LOCAL_INT5_ENABLE_XN_UCE_INT_SHFT     10
+#define SH_LOCAL_INT5_ENABLE_XN_UCE_INT_MASK     0x0000000000000400
+
+/*   SH_LOCAL_INT5_ENABLE_SYSTEM_SHUTDOWN_INT                           */
+/*   Description:  Enable System Shutdown Interrupt                     */
+#define SH_LOCAL_INT5_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 12
+#define SH_LOCAL_INT5_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000001000
+
+/*   SH_LOCAL_INT5_ENABLE_UART_INT                                      */
+/*   Description:  Enable Junk Bus UART Interrupt                       */
+#define SH_LOCAL_INT5_ENABLE_UART_INT_SHFT       13
+#define SH_LOCAL_INT5_ENABLE_UART_INT_MASK       0x0000000000002000
+
+/*   SH_LOCAL_INT5_ENABLE_L1_NMI_INT                                    */
+/*   Description:  Enable L1 Controller NMI Interrupt                   */
+#define SH_LOCAL_INT5_ENABLE_L1_NMI_INT_SHFT     14
+#define SH_LOCAL_INT5_ENABLE_L1_NMI_INT_MASK     0x0000000000004000
+
+/*   SH_LOCAL_INT5_ENABLE_STOP_CLOCK                                    */
+/*   Description:  Stop Clock Interrupt                                 */
+#define SH_LOCAL_INT5_ENABLE_STOP_CLOCK_SHFT     15
+#define SH_LOCAL_INT5_ENABLE_STOP_CLOCK_MASK     0x0000000000008000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ERR_INT_CONFIG"                  */
+/*              SHub Processor 0 Error Interrupt Registers              */
+/* ==================================================================== */
+
+#define SH_PROC0_ERR_INT_CONFIG                  0x0000000110000a80
+#define SH_PROC0_ERR_INT_CONFIG_MASK             0x0ff3ffffffefffff
+#define SH_PROC0_ERR_INT_CONFIG_INIT             0x0000000000000000
+
+/*   SH_PROC0_ERR_INT_CONFIG_TYPE                                       */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROC0_ERR_INT_CONFIG_TYPE_SHFT        0
+#define SH_PROC0_ERR_INT_CONFIG_TYPE_MASK        0x0000000000000007
+
+/*   SH_PROC0_ERR_INT_CONFIG_AGT                                        */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROC0_ERR_INT_CONFIG_AGT_SHFT         3
+#define SH_PROC0_ERR_INT_CONFIG_AGT_MASK         0x0000000000000008
+
+/*   SH_PROC0_ERR_INT_CONFIG_PID                                        */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROC0_ERR_INT_CONFIG_PID_SHFT         4
+#define SH_PROC0_ERR_INT_CONFIG_PID_MASK         0x00000000000ffff0
+
+/*   SH_PROC0_ERR_INT_CONFIG_BASE                                       */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROC0_ERR_INT_CONFIG_BASE_SHFT        21
+#define SH_PROC0_ERR_INT_CONFIG_BASE_MASK        0x0003ffffffe00000
+
+/*   SH_PROC0_ERR_INT_CONFIG_IDX                                        */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROC0_ERR_INT_CONFIG_IDX_SHFT         52
+#define SH_PROC0_ERR_INT_CONFIG_IDX_MASK         0x0ff0000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ERR_INT_CONFIG"                  */
+/*              SHub Processor 1 Error Interrupt Registers              */
+/* ==================================================================== */
+
+#define SH_PROC1_ERR_INT_CONFIG                  0x0000000110000b00
+#define SH_PROC1_ERR_INT_CONFIG_MASK             0x0ff3ffffffefffff
+#define SH_PROC1_ERR_INT_CONFIG_INIT             0x0000000000000000
+
+/*   SH_PROC1_ERR_INT_CONFIG_TYPE                                       */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROC1_ERR_INT_CONFIG_TYPE_SHFT        0
+#define SH_PROC1_ERR_INT_CONFIG_TYPE_MASK        0x0000000000000007
+
+/*   SH_PROC1_ERR_INT_CONFIG_AGT                                        */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROC1_ERR_INT_CONFIG_AGT_SHFT         3
+#define SH_PROC1_ERR_INT_CONFIG_AGT_MASK         0x0000000000000008
+
+/*   SH_PROC1_ERR_INT_CONFIG_PID                                        */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROC1_ERR_INT_CONFIG_PID_SHFT         4
+#define SH_PROC1_ERR_INT_CONFIG_PID_MASK         0x00000000000ffff0
+
+/*   SH_PROC1_ERR_INT_CONFIG_BASE                                       */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROC1_ERR_INT_CONFIG_BASE_SHFT        21
+#define SH_PROC1_ERR_INT_CONFIG_BASE_MASK        0x0003ffffffe00000
+
+/*   SH_PROC1_ERR_INT_CONFIG_IDX                                        */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROC1_ERR_INT_CONFIG_IDX_SHFT         52
+#define SH_PROC1_ERR_INT_CONFIG_IDX_MASK         0x0ff0000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ERR_INT_CONFIG"                  */
+/*              SHub Processor 2 Error Interrupt Registers              */
+/* ==================================================================== */
+
+#define SH_PROC2_ERR_INT_CONFIG                  0x0000000110000b80
+#define SH_PROC2_ERR_INT_CONFIG_MASK             0x0ff3ffffffefffff
+#define SH_PROC2_ERR_INT_CONFIG_INIT             0x0000000000000000
+
+/*   SH_PROC2_ERR_INT_CONFIG_TYPE                                       */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROC2_ERR_INT_CONFIG_TYPE_SHFT        0
+#define SH_PROC2_ERR_INT_CONFIG_TYPE_MASK        0x0000000000000007
+
+/*   SH_PROC2_ERR_INT_CONFIG_AGT                                        */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROC2_ERR_INT_CONFIG_AGT_SHFT         3
+#define SH_PROC2_ERR_INT_CONFIG_AGT_MASK         0x0000000000000008
+
+/*   SH_PROC2_ERR_INT_CONFIG_PID                                        */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROC2_ERR_INT_CONFIG_PID_SHFT         4
+#define SH_PROC2_ERR_INT_CONFIG_PID_MASK         0x00000000000ffff0
+
+/*   SH_PROC2_ERR_INT_CONFIG_BASE                                       */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROC2_ERR_INT_CONFIG_BASE_SHFT        21
+#define SH_PROC2_ERR_INT_CONFIG_BASE_MASK        0x0003ffffffe00000
+
+/*   SH_PROC2_ERR_INT_CONFIG_IDX                                        */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROC2_ERR_INT_CONFIG_IDX_SHFT         52
+#define SH_PROC2_ERR_INT_CONFIG_IDX_MASK         0x0ff0000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ERR_INT_CONFIG"                  */
+/*              SHub Processor 3 Error Interrupt Registers              */
+/* ==================================================================== */
+
+#define SH_PROC3_ERR_INT_CONFIG                  0x0000000110000c00
+#define SH_PROC3_ERR_INT_CONFIG_MASK             0x0ff3ffffffefffff
+#define SH_PROC3_ERR_INT_CONFIG_INIT             0x0000000000000000
+
+/*   SH_PROC3_ERR_INT_CONFIG_TYPE                                       */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROC3_ERR_INT_CONFIG_TYPE_SHFT        0
+#define SH_PROC3_ERR_INT_CONFIG_TYPE_MASK        0x0000000000000007
+
+/*   SH_PROC3_ERR_INT_CONFIG_AGT                                        */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROC3_ERR_INT_CONFIG_AGT_SHFT         3
+#define SH_PROC3_ERR_INT_CONFIG_AGT_MASK         0x0000000000000008
+
+/*   SH_PROC3_ERR_INT_CONFIG_PID                                        */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROC3_ERR_INT_CONFIG_PID_SHFT         4
+#define SH_PROC3_ERR_INT_CONFIG_PID_MASK         0x00000000000ffff0
+
+/*   SH_PROC3_ERR_INT_CONFIG_BASE                                       */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROC3_ERR_INT_CONFIG_BASE_SHFT        21
+#define SH_PROC3_ERR_INT_CONFIG_BASE_MASK        0x0003ffffffe00000
+
+/*   SH_PROC3_ERR_INT_CONFIG_IDX                                        */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROC3_ERR_INT_CONFIG_IDX_SHFT         52
+#define SH_PROC3_ERR_INT_CONFIG_IDX_MASK         0x0ff0000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ADV_INT_CONFIG"                  */
+/*            SHub Processor 0 Advisory Interrupt Registers             */
+/* ==================================================================== */
+
+#define SH_PROC0_ADV_INT_CONFIG                  0x0000000110000c80
+#define SH_PROC0_ADV_INT_CONFIG_MASK             0x0ff3ffffffefffff
+#define SH_PROC0_ADV_INT_CONFIG_INIT             0x0000000000000000
+
+/*   SH_PROC0_ADV_INT_CONFIG_TYPE                                       */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROC0_ADV_INT_CONFIG_TYPE_SHFT        0
+#define SH_PROC0_ADV_INT_CONFIG_TYPE_MASK        0x0000000000000007
+
+/*   SH_PROC0_ADV_INT_CONFIG_AGT                                        */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROC0_ADV_INT_CONFIG_AGT_SHFT         3
+#define SH_PROC0_ADV_INT_CONFIG_AGT_MASK         0x0000000000000008
+
+/*   SH_PROC0_ADV_INT_CONFIG_PID                                        */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROC0_ADV_INT_CONFIG_PID_SHFT         4
+#define SH_PROC0_ADV_INT_CONFIG_PID_MASK         0x00000000000ffff0
+
+/*   SH_PROC0_ADV_INT_CONFIG_BASE                                       */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROC0_ADV_INT_CONFIG_BASE_SHFT        21
+#define SH_PROC0_ADV_INT_CONFIG_BASE_MASK        0x0003ffffffe00000
+
+/*   SH_PROC0_ADV_INT_CONFIG_IDX                                        */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROC0_ADV_INT_CONFIG_IDX_SHFT         52
+#define SH_PROC0_ADV_INT_CONFIG_IDX_MASK         0x0ff0000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ADV_INT_CONFIG"                  */
+/*            SHub Processor 1 Advisory Interrupt Registers             */
+/* ==================================================================== */
+
+#define SH_PROC1_ADV_INT_CONFIG                  0x0000000110000d00
+#define SH_PROC1_ADV_INT_CONFIG_MASK             0x0ff3ffffffefffff
+#define SH_PROC1_ADV_INT_CONFIG_INIT             0x0000000000000000
+
+/*   SH_PROC1_ADV_INT_CONFIG_TYPE                                       */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROC1_ADV_INT_CONFIG_TYPE_SHFT        0
+#define SH_PROC1_ADV_INT_CONFIG_TYPE_MASK        0x0000000000000007
+
+/*   SH_PROC1_ADV_INT_CONFIG_AGT                                        */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROC1_ADV_INT_CONFIG_AGT_SHFT         3
+#define SH_PROC1_ADV_INT_CONFIG_AGT_MASK         0x0000000000000008
+
+/*   SH_PROC1_ADV_INT_CONFIG_PID                                        */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROC1_ADV_INT_CONFIG_PID_SHFT         4
+#define SH_PROC1_ADV_INT_CONFIG_PID_MASK         0x00000000000ffff0
+
+/*   SH_PROC1_ADV_INT_CONFIG_BASE                                       */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROC1_ADV_INT_CONFIG_BASE_SHFT        21
+#define SH_PROC1_ADV_INT_CONFIG_BASE_MASK        0x0003ffffffe00000
+
+/*   SH_PROC1_ADV_INT_CONFIG_IDX                                        */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROC1_ADV_INT_CONFIG_IDX_SHFT         52
+#define SH_PROC1_ADV_INT_CONFIG_IDX_MASK         0x0ff0000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ADV_INT_CONFIG"                  */
+/*            SHub Processor 2 Advisory Interrupt Registers             */
+/* ==================================================================== */
+
+#define SH_PROC2_ADV_INT_CONFIG                  0x0000000110000d80
+#define SH_PROC2_ADV_INT_CONFIG_MASK             0x0ff3ffffffefffff
+#define SH_PROC2_ADV_INT_CONFIG_INIT             0x0000000000000000
+
+/*   SH_PROC2_ADV_INT_CONFIG_TYPE                                       */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROC2_ADV_INT_CONFIG_TYPE_SHFT        0
+#define SH_PROC2_ADV_INT_CONFIG_TYPE_MASK        0x0000000000000007
+
+/*   SH_PROC2_ADV_INT_CONFIG_AGT                                        */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROC2_ADV_INT_CONFIG_AGT_SHFT         3
+#define SH_PROC2_ADV_INT_CONFIG_AGT_MASK         0x0000000000000008
+
+/*   SH_PROC2_ADV_INT_CONFIG_PID                                        */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROC2_ADV_INT_CONFIG_PID_SHFT         4
+#define SH_PROC2_ADV_INT_CONFIG_PID_MASK         0x00000000000ffff0
+
+/*   SH_PROC2_ADV_INT_CONFIG_BASE                                       */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROC2_ADV_INT_CONFIG_BASE_SHFT        21
+#define SH_PROC2_ADV_INT_CONFIG_BASE_MASK        0x0003ffffffe00000
+
+/*   SH_PROC2_ADV_INT_CONFIG_IDX                                        */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROC2_ADV_INT_CONFIG_IDX_SHFT         52
+#define SH_PROC2_ADV_INT_CONFIG_IDX_MASK         0x0ff0000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ADV_INT_CONFIG"                  */
+/*            SHub Processor 3 Advisory Interrupt Registers             */
+/* ==================================================================== */
+
+#define SH_PROC3_ADV_INT_CONFIG                  0x0000000110000e00
+#define SH_PROC3_ADV_INT_CONFIG_MASK             0x0ff3ffffffefffff
+#define SH_PROC3_ADV_INT_CONFIG_INIT             0x0000000000000000
+
+/*   SH_PROC3_ADV_INT_CONFIG_TYPE                                       */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROC3_ADV_INT_CONFIG_TYPE_SHFT        0
+#define SH_PROC3_ADV_INT_CONFIG_TYPE_MASK        0x0000000000000007
+
+/*   SH_PROC3_ADV_INT_CONFIG_AGT                                        */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROC3_ADV_INT_CONFIG_AGT_SHFT         3
+#define SH_PROC3_ADV_INT_CONFIG_AGT_MASK         0x0000000000000008
+
+/*   SH_PROC3_ADV_INT_CONFIG_PID                                        */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROC3_ADV_INT_CONFIG_PID_SHFT         4
+#define SH_PROC3_ADV_INT_CONFIG_PID_MASK         0x00000000000ffff0
+
+/*   SH_PROC3_ADV_INT_CONFIG_BASE                                       */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROC3_ADV_INT_CONFIG_BASE_SHFT        21
+#define SH_PROC3_ADV_INT_CONFIG_BASE_MASK        0x0003ffffffe00000
+
+/*   SH_PROC3_ADV_INT_CONFIG_IDX                                        */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROC3_ADV_INT_CONFIG_IDX_SHFT         52
+#define SH_PROC3_ADV_INT_CONFIG_IDX_MASK         0x0ff0000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ERR_INT_ENABLE"                  */
+/*          SHub Processor 0 Error Interrupt Enable Registers           */
+/* ==================================================================== */
+
+#define SH_PROC0_ERR_INT_ENABLE                  0x0000000110000e80
+#define SH_PROC0_ERR_INT_ENABLE_MASK             0x0000000000000001
+#define SH_PROC0_ERR_INT_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PROC0_ERR_INT_ENABLE_PROC0_ERR_ENABLE                           */
+/*   Description:  Enable Processor 0 Error Interrupt                   */
+#define SH_PROC0_ERR_INT_ENABLE_PROC0_ERR_ENABLE_SHFT 0
+#define SH_PROC0_ERR_INT_ENABLE_PROC0_ERR_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ERR_INT_ENABLE"                  */
+/*          SHub Processor 1 Error Interrupt Enable Registers           */
+/* ==================================================================== */
+
+#define SH_PROC1_ERR_INT_ENABLE                  0x0000000110000f00
+#define SH_PROC1_ERR_INT_ENABLE_MASK             0x0000000000000001
+#define SH_PROC1_ERR_INT_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PROC1_ERR_INT_ENABLE_PROC1_ERR_ENABLE                           */
+/*   Description:  Enable Processor 1 Error Interrupt                   */
+#define SH_PROC1_ERR_INT_ENABLE_PROC1_ERR_ENABLE_SHFT 0
+#define SH_PROC1_ERR_INT_ENABLE_PROC1_ERR_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ERR_INT_ENABLE"                  */
+/*          SHub Processor 2 Error Interrupt Enable Registers           */
+/* ==================================================================== */
+
+#define SH_PROC2_ERR_INT_ENABLE                  0x0000000110000f80
+#define SH_PROC2_ERR_INT_ENABLE_MASK             0x0000000000000001
+#define SH_PROC2_ERR_INT_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PROC2_ERR_INT_ENABLE_PROC2_ERR_ENABLE                           */
+/*   Description:  Enable Processor 2 Error Interrupt                   */
+#define SH_PROC2_ERR_INT_ENABLE_PROC2_ERR_ENABLE_SHFT 0
+#define SH_PROC2_ERR_INT_ENABLE_PROC2_ERR_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ERR_INT_ENABLE"                  */
+/*          SHub Processor 3 Error Interrupt Enable Registers           */
+/* ==================================================================== */
+
+#define SH_PROC3_ERR_INT_ENABLE                  0x0000000110001000
+#define SH_PROC3_ERR_INT_ENABLE_MASK             0x0000000000000001
+#define SH_PROC3_ERR_INT_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PROC3_ERR_INT_ENABLE_PROC3_ERR_ENABLE                           */
+/*   Description:  Enable Processor 3 Error Interrupt                   */
+#define SH_PROC3_ERR_INT_ENABLE_PROC3_ERR_ENABLE_SHFT 0
+#define SH_PROC3_ERR_INT_ENABLE_PROC3_ERR_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ADV_INT_ENABLE"                  */
+/*         SHub Processor 0 Advisory Interrupt Enable Registers         */
+/* ==================================================================== */
+
+#define SH_PROC0_ADV_INT_ENABLE                  0x0000000110001080
+#define SH_PROC0_ADV_INT_ENABLE_MASK             0x0000000000000001
+#define SH_PROC0_ADV_INT_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PROC0_ADV_INT_ENABLE_PROC0_ADV_ENABLE                           */
+/*   Description:  Enable Processor 0 Advisory Interrupt                */
+#define SH_PROC0_ADV_INT_ENABLE_PROC0_ADV_ENABLE_SHFT 0
+#define SH_PROC0_ADV_INT_ENABLE_PROC0_ADV_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ADV_INT_ENABLE"                  */
+/*         SHub Processor 1 Advisory Interrupt Enable Registers         */
+/* ==================================================================== */
+
+#define SH_PROC1_ADV_INT_ENABLE                  0x0000000110001100
+#define SH_PROC1_ADV_INT_ENABLE_MASK             0x0000000000000001
+#define SH_PROC1_ADV_INT_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PROC1_ADV_INT_ENABLE_PROC1_ADV_ENABLE                           */
+/*   Description:  Enable Processor 1 Advisory Interrupt                */
+#define SH_PROC1_ADV_INT_ENABLE_PROC1_ADV_ENABLE_SHFT 0
+#define SH_PROC1_ADV_INT_ENABLE_PROC1_ADV_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ADV_INT_ENABLE"                  */
+/*         SHub Processor 2 Advisory Interrupt Enable Registers         */
+/* ==================================================================== */
+
+#define SH_PROC2_ADV_INT_ENABLE                  0x0000000110001180
+#define SH_PROC2_ADV_INT_ENABLE_MASK             0x0000000000000001
+#define SH_PROC2_ADV_INT_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PROC2_ADV_INT_ENABLE_PROC2_ADV_ENABLE                           */
+/*   Description:  Enable Processor 2 Advisory Interrupt                */
+#define SH_PROC2_ADV_INT_ENABLE_PROC2_ADV_ENABLE_SHFT 0
+#define SH_PROC2_ADV_INT_ENABLE_PROC2_ADV_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ADV_INT_ENABLE"                  */
+/*         SHub Processor 3 Advisory Interrupt Enable Registers         */
+/* ==================================================================== */
+
+#define SH_PROC3_ADV_INT_ENABLE                  0x0000000110001200
+#define SH_PROC3_ADV_INT_ENABLE_MASK             0x0000000000000001
+#define SH_PROC3_ADV_INT_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PROC3_ADV_INT_ENABLE_PROC3_ADV_ENABLE                           */
+/*   Description:  Enable Processor 3 Advisory Interrupt                */
+#define SH_PROC3_ADV_INT_ENABLE_PROC3_ADV_ENABLE_SHFT 0
+#define SH_PROC3_ADV_INT_ENABLE_PROC3_ADV_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                   Register "SH_PROFILE_INT_CONFIG"                   */
+/*            SHub Profile Interrupt Configuration Registers            */
+/* ==================================================================== */
+
+#define SH_PROFILE_INT_CONFIG                    0x0000000110001280
+#define SH_PROFILE_INT_CONFIG_MASK               0x0ff3ffffffefffff
+#define SH_PROFILE_INT_CONFIG_INIT               0x0000000000000000
+
+/*   SH_PROFILE_INT_CONFIG_TYPE                                         */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_PROFILE_INT_CONFIG_TYPE_SHFT          0
+#define SH_PROFILE_INT_CONFIG_TYPE_MASK          0x0000000000000007
+
+/*   SH_PROFILE_INT_CONFIG_AGT                                          */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_PROFILE_INT_CONFIG_AGT_SHFT           3
+#define SH_PROFILE_INT_CONFIG_AGT_MASK           0x0000000000000008
+
+/*   SH_PROFILE_INT_CONFIG_PID                                          */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_PROFILE_INT_CONFIG_PID_SHFT           4
+#define SH_PROFILE_INT_CONFIG_PID_MASK           0x00000000000ffff0
+
+/*   SH_PROFILE_INT_CONFIG_BASE                                         */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_PROFILE_INT_CONFIG_BASE_SHFT          21
+#define SH_PROFILE_INT_CONFIG_BASE_MASK          0x0003ffffffe00000
+
+/*   SH_PROFILE_INT_CONFIG_IDX                                          */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_PROFILE_INT_CONFIG_IDX_SHFT           52
+#define SH_PROFILE_INT_CONFIG_IDX_MASK           0x0ff0000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_PROFILE_INT_ENABLE"                   */
+/*               SHub Profile Interrupt Enable Registers                */
+/* ==================================================================== */
+
+#define SH_PROFILE_INT_ENABLE                    0x0000000110001300
+#define SH_PROFILE_INT_ENABLE_MASK               0x0000000000000001
+#define SH_PROFILE_INT_ENABLE_INIT               0x0000000000000000
+
+/*   SH_PROFILE_INT_ENABLE_PROFILE_ENABLE                               */
+/*   Description:  Enable Profile Interrupt                             */
+#define SH_PROFILE_INT_ENABLE_PROFILE_ENABLE_SHFT 0
+#define SH_PROFILE_INT_ENABLE_PROFILE_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                    Register "SH_RTC0_INT_CONFIG"                     */
+/*                SHub RTC 0 Interrupt Config Registers                 */
+/* ==================================================================== */
+
+#define SH_RTC0_INT_CONFIG                       0x0000000110001380
+#define SH_RTC0_INT_CONFIG_MASK                  0x0ff3ffffffefffff
+#define SH_RTC0_INT_CONFIG_INIT                  0x0000000000000000
+
+/*   SH_RTC0_INT_CONFIG_TYPE                                            */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_RTC0_INT_CONFIG_TYPE_SHFT             0
+#define SH_RTC0_INT_CONFIG_TYPE_MASK             0x0000000000000007
+
+/*   SH_RTC0_INT_CONFIG_AGT                                             */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_RTC0_INT_CONFIG_AGT_SHFT              3
+#define SH_RTC0_INT_CONFIG_AGT_MASK              0x0000000000000008
+
+/*   SH_RTC0_INT_CONFIG_PID                                             */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_RTC0_INT_CONFIG_PID_SHFT              4
+#define SH_RTC0_INT_CONFIG_PID_MASK              0x00000000000ffff0
+
+/*   SH_RTC0_INT_CONFIG_BASE                                            */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_RTC0_INT_CONFIG_BASE_SHFT             21
+#define SH_RTC0_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+
+/*   SH_RTC0_INT_CONFIG_IDX                                             */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_RTC0_INT_CONFIG_IDX_SHFT              52
+#define SH_RTC0_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_RTC0_INT_ENABLE"                     */
+/*                SHub RTC 0 Interrupt Enable Registers                 */
+/* ==================================================================== */
+
+#define SH_RTC0_INT_ENABLE                       0x0000000110001400
+#define SH_RTC0_INT_ENABLE_MASK                  0x0000000000000001
+#define SH_RTC0_INT_ENABLE_INIT                  0x0000000000000000
+
+/*   SH_RTC0_INT_ENABLE_RTC0_ENABLE                                     */
+/*   Description:  Enable RTC 0 Interrupt                               */
+#define SH_RTC0_INT_ENABLE_RTC0_ENABLE_SHFT      0
+#define SH_RTC0_INT_ENABLE_RTC0_ENABLE_MASK      0x0000000000000001
+
+/* ==================================================================== */
+/*                    Register "SH_RTC1_INT_CONFIG"                     */
+/*                SHub RTC 1 Interrupt Config Registers                 */
+/* ==================================================================== */
+
+#define SH_RTC1_INT_CONFIG                       0x0000000110001480
+#define SH_RTC1_INT_CONFIG_MASK                  0x0ff3ffffffefffff
+#define SH_RTC1_INT_CONFIG_INIT                  0x0000000000000000
+
+/*   SH_RTC1_INT_CONFIG_TYPE                                            */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_RTC1_INT_CONFIG_TYPE_SHFT             0
+#define SH_RTC1_INT_CONFIG_TYPE_MASK             0x0000000000000007
+
+/*   SH_RTC1_INT_CONFIG_AGT                                             */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_RTC1_INT_CONFIG_AGT_SHFT              3
+#define SH_RTC1_INT_CONFIG_AGT_MASK              0x0000000000000008
+
+/*   SH_RTC1_INT_CONFIG_PID                                             */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_RTC1_INT_CONFIG_PID_SHFT              4
+#define SH_RTC1_INT_CONFIG_PID_MASK              0x00000000000ffff0
+
+/*   SH_RTC1_INT_CONFIG_BASE                                            */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_RTC1_INT_CONFIG_BASE_SHFT             21
+#define SH_RTC1_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+
+/*   SH_RTC1_INT_CONFIG_IDX                                             */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_RTC1_INT_CONFIG_IDX_SHFT              52
+#define SH_RTC1_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_RTC1_INT_ENABLE"                     */
+/*                SHub RTC 1 Interrupt Enable Registers                 */
+/* ==================================================================== */
+
+#define SH_RTC1_INT_ENABLE                       0x0000000110001500
+#define SH_RTC1_INT_ENABLE_MASK                  0x0000000000000001
+#define SH_RTC1_INT_ENABLE_INIT                  0x0000000000000000
+
+/*   SH_RTC1_INT_ENABLE_RTC1_ENABLE                                     */
+/*   Description:  Enable RTC 1 Interrupt                               */
+#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT      0
+#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK      0x0000000000000001
+
+/* ==================================================================== */
+/*                    Register "SH_RTC2_INT_CONFIG"                     */
+/*                SHub RTC 2 Interrupt Config Registers                 */
+/* ==================================================================== */
+
+#define SH_RTC2_INT_CONFIG                       0x0000000110001580
+#define SH_RTC2_INT_CONFIG_MASK                  0x0ff3ffffffefffff
+#define SH_RTC2_INT_CONFIG_INIT                  0x0000000000000000
+
+/*   SH_RTC2_INT_CONFIG_TYPE                                            */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_RTC2_INT_CONFIG_TYPE_SHFT             0
+#define SH_RTC2_INT_CONFIG_TYPE_MASK             0x0000000000000007
+
+/*   SH_RTC2_INT_CONFIG_AGT                                             */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_RTC2_INT_CONFIG_AGT_SHFT              3
+#define SH_RTC2_INT_CONFIG_AGT_MASK              0x0000000000000008
+
+/*   SH_RTC2_INT_CONFIG_PID                                             */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_RTC2_INT_CONFIG_PID_SHFT              4
+#define SH_RTC2_INT_CONFIG_PID_MASK              0x00000000000ffff0
+
+/*   SH_RTC2_INT_CONFIG_BASE                                            */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_RTC2_INT_CONFIG_BASE_SHFT             21
+#define SH_RTC2_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+
+/*   SH_RTC2_INT_CONFIG_IDX                                             */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_RTC2_INT_CONFIG_IDX_SHFT              52
+#define SH_RTC2_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_RTC2_INT_ENABLE"                     */
+/*                SHub RTC 2 Interrupt Enable Registers                 */
+/* ==================================================================== */
+
+#define SH_RTC2_INT_ENABLE                       0x0000000110001600
+#define SH_RTC2_INT_ENABLE_MASK                  0x0000000000000001
+#define SH_RTC2_INT_ENABLE_INIT                  0x0000000000000000
+
+/*   SH_RTC2_INT_ENABLE_RTC2_ENABLE                                     */
+/*   Description:  Enable RTC 2 Interrupt                               */
+#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT      0
+#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK      0x0000000000000001
+
+/* ==================================================================== */
+/*                    Register "SH_RTC3_INT_CONFIG"                     */
+/*                SHub RTC 3 Interrupt Config Registers                 */
+/* ==================================================================== */
+
+#define SH_RTC3_INT_CONFIG                       0x0000000110001680
+#define SH_RTC3_INT_CONFIG_MASK                  0x0ff3ffffffefffff
+#define SH_RTC3_INT_CONFIG_INIT                  0x0000000000000000
+
+/*   SH_RTC3_INT_CONFIG_TYPE                                            */
+/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
+#define SH_RTC3_INT_CONFIG_TYPE_SHFT             0
+#define SH_RTC3_INT_CONFIG_TYPE_MASK             0x0000000000000007
+
+/*   SH_RTC3_INT_CONFIG_AGT                                             */
+/*   Description:  Agent, must be 0 for SHub                            */
+#define SH_RTC3_INT_CONFIG_AGT_SHFT              3
+#define SH_RTC3_INT_CONFIG_AGT_MASK              0x0000000000000008
+
+/*   SH_RTC3_INT_CONFIG_PID                                             */
+/*   Description:  Processor ID, same setting as on targeted McKinley  */
+#define SH_RTC3_INT_CONFIG_PID_SHFT              4
+#define SH_RTC3_INT_CONFIG_PID_MASK              0x00000000000ffff0
+
+/*   SH_RTC3_INT_CONFIG_BASE                                            */
+/*   Description:  Optional interrupt vector area, 2MB aligned          */
+#define SH_RTC3_INT_CONFIG_BASE_SHFT             21
+#define SH_RTC3_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+
+/*   SH_RTC3_INT_CONFIG_IDX                                             */
+/*   Description:  Targeted McKinley interrupt vector                   */
+#define SH_RTC3_INT_CONFIG_IDX_SHFT              52
+#define SH_RTC3_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_RTC3_INT_ENABLE"                     */
+/*                SHub RTC 3 Interrupt Enable Registers                 */
+/* ==================================================================== */
+
+#define SH_RTC3_INT_ENABLE                       0x0000000110001700
+#define SH_RTC3_INT_ENABLE_MASK                  0x0000000000000001
+#define SH_RTC3_INT_ENABLE_INIT                  0x0000000000000000
+
+/*   SH_RTC3_INT_ENABLE_RTC3_ENABLE                                     */
+/*   Description:  Enable RTC 3 Interrupt                               */
+#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT      0
+#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK      0x0000000000000001
+
+/* ==================================================================== */
+/*                     Register "SH_EVENT_OCCURRED"                     */
+/*                    SHub Interrupt Event Occurred                     */
+/* ==================================================================== */
+
+#define SH_EVENT_OCCURRED                        0x0000000110010000
+#define SH_EVENT_OCCURRED_MASK                   0x000000007fffffff
+#define SH_EVENT_OCCURRED_INIT                   0x0000000000000000
+
+/*   SH_EVENT_OCCURRED_PI_HW_INT                                        */
+/*   Description:  Pending PI Hardware interrupt                        */
+#define SH_EVENT_OCCURRED_PI_HW_INT_SHFT         0
+#define SH_EVENT_OCCURRED_PI_HW_INT_MASK         0x0000000000000001
+
+/*   SH_EVENT_OCCURRED_MD_HW_INT                                        */
+/*   Description:  Pending MD Hardware interrupt                        */
+#define SH_EVENT_OCCURRED_MD_HW_INT_SHFT         1
+#define SH_EVENT_OCCURRED_MD_HW_INT_MASK         0x0000000000000002
+
+/*   SH_EVENT_OCCURRED_XN_HW_INT                                        */
+/*   Description:  Pending XN Hardware interrupt                        */
+#define SH_EVENT_OCCURRED_XN_HW_INT_SHFT         2
+#define SH_EVENT_OCCURRED_XN_HW_INT_MASK         0x0000000000000004
+
+/*   SH_EVENT_OCCURRED_LB_HW_INT                                        */
+/*   Description:  Pending LB Hardware interrupt                        */
+#define SH_EVENT_OCCURRED_LB_HW_INT_SHFT         3
+#define SH_EVENT_OCCURRED_LB_HW_INT_MASK         0x0000000000000008
+
+/*   SH_EVENT_OCCURRED_II_HW_INT                                        */
+/*   Description:  Pending II wrapper Hardware interrupt                */
+#define SH_EVENT_OCCURRED_II_HW_INT_SHFT         4
+#define SH_EVENT_OCCURRED_II_HW_INT_MASK         0x0000000000000010
+
+/*   SH_EVENT_OCCURRED_PI_CE_INT                                        */
+/*   Description:  Pending PI Correctable Error Interrupt               */
+#define SH_EVENT_OCCURRED_PI_CE_INT_SHFT         5
+#define SH_EVENT_OCCURRED_PI_CE_INT_MASK         0x0000000000000020
+
+/*   SH_EVENT_OCCURRED_MD_CE_INT                                        */
+/*   Description:  Pending MD Correctable Error Interrupt               */
+#define SH_EVENT_OCCURRED_MD_CE_INT_SHFT         6
+#define SH_EVENT_OCCURRED_MD_CE_INT_MASK         0x0000000000000040
+
+/*   SH_EVENT_OCCURRED_XN_CE_INT                                        */
+/*   Description:  Pending XN Correctable Error Interrupt               */
+#define SH_EVENT_OCCURRED_XN_CE_INT_SHFT         7
+#define SH_EVENT_OCCURRED_XN_CE_INT_MASK         0x0000000000000080
+
+/*   SH_EVENT_OCCURRED_PI_UCE_INT                                       */
+/*   Description:  Pending PI Correctable Error Interrupt               */
+#define SH_EVENT_OCCURRED_PI_UCE_INT_SHFT        8
+#define SH_EVENT_OCCURRED_PI_UCE_INT_MASK        0x0000000000000100
+
+/*   SH_EVENT_OCCURRED_MD_UCE_INT                                       */
+/*   Description:  Pending MD Correctable Error Interrupt               */
+#define SH_EVENT_OCCURRED_MD_UCE_INT_SHFT        9
+#define SH_EVENT_OCCURRED_MD_UCE_INT_MASK        0x0000000000000200
+
+/*   SH_EVENT_OCCURRED_XN_UCE_INT                                       */
+/*   Description:  Pending XN Correctable Error Interrupt               */
+#define SH_EVENT_OCCURRED_XN_UCE_INT_SHFT        10
+#define SH_EVENT_OCCURRED_XN_UCE_INT_MASK        0x0000000000000400
+
+/*   SH_EVENT_OCCURRED_PROC0_ADV_INT                                    */
+/*   Description:  Pending Processor 0 Advisory Interrupt               */
+#define SH_EVENT_OCCURRED_PROC0_ADV_INT_SHFT     11
+#define SH_EVENT_OCCURRED_PROC0_ADV_INT_MASK     0x0000000000000800
+
+/*   SH_EVENT_OCCURRED_PROC1_ADV_INT                                    */
+/*   Description:  Pending Processor 1 Advisory Interrupt               */
+#define SH_EVENT_OCCURRED_PROC1_ADV_INT_SHFT     12
+#define SH_EVENT_OCCURRED_PROC1_ADV_INT_MASK     0x0000000000001000
+
+/*   SH_EVENT_OCCURRED_PROC2_ADV_INT                                    */
+/*   Description:  Pending Processor 2 Advisory Interrupt               */
+#define SH_EVENT_OCCURRED_PROC2_ADV_INT_SHFT     13
+#define SH_EVENT_OCCURRED_PROC2_ADV_INT_MASK     0x0000000000002000
+
+/*   SH_EVENT_OCCURRED_PROC3_ADV_INT                                    */
+/*   Description:  Pending Processor 3 Advisory Interrupt               */
+#define SH_EVENT_OCCURRED_PROC3_ADV_INT_SHFT     14
+#define SH_EVENT_OCCURRED_PROC3_ADV_INT_MASK     0x0000000000004000
+
+/*   SH_EVENT_OCCURRED_PROC0_ERR_INT                                    */
+/*   Description:  Pending Processor 0 Error Interrupt                  */
+#define SH_EVENT_OCCURRED_PROC0_ERR_INT_SHFT     15
+#define SH_EVENT_OCCURRED_PROC0_ERR_INT_MASK     0x0000000000008000
+
+/*   SH_EVENT_OCCURRED_PROC1_ERR_INT                                    */
+/*   Description:  Pending Processor 1 Error Interrupt                  */
+#define SH_EVENT_OCCURRED_PROC1_ERR_INT_SHFT     16
+#define SH_EVENT_OCCURRED_PROC1_ERR_INT_MASK     0x0000000000010000
+
+/*   SH_EVENT_OCCURRED_PROC2_ERR_INT                                    */
+/*   Description:  Pending Processor 2 Error Interrupt                  */
+#define SH_EVENT_OCCURRED_PROC2_ERR_INT_SHFT     17
+#define SH_EVENT_OCCURRED_PROC2_ERR_INT_MASK     0x0000000000020000
+
+/*   SH_EVENT_OCCURRED_PROC3_ERR_INT                                    */
+/*   Description:  Pending Processor 3 Error Interrupt                  */
+#define SH_EVENT_OCCURRED_PROC3_ERR_INT_SHFT     18
+#define SH_EVENT_OCCURRED_PROC3_ERR_INT_MASK     0x0000000000040000
+
+/*   SH_EVENT_OCCURRED_SYSTEM_SHUTDOWN_INT                              */
+/*   Description:  Pending System Shutdown Interrupt                    */
+#define SH_EVENT_OCCURRED_SYSTEM_SHUTDOWN_INT_SHFT 19
+#define SH_EVENT_OCCURRED_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000080000
+
+/*   SH_EVENT_OCCURRED_UART_INT                                         */
+/*   Description:  Pending Junk Bus UART Interrupt                      */
+#define SH_EVENT_OCCURRED_UART_INT_SHFT          20
+#define SH_EVENT_OCCURRED_UART_INT_MASK          0x0000000000100000
+
+/*   SH_EVENT_OCCURRED_L1_NMI_INT                                       */
+/*   Description:  Pending L1 Controller NMI Interrupt                  */
+#define SH_EVENT_OCCURRED_L1_NMI_INT_SHFT        21
+#define SH_EVENT_OCCURRED_L1_NMI_INT_MASK        0x0000000000200000
+
+/*   SH_EVENT_OCCURRED_STOP_CLOCK                                       */
+/*   Description:  Pending Stop Clock Interrupt                         */
+#define SH_EVENT_OCCURRED_STOP_CLOCK_SHFT        22
+#define SH_EVENT_OCCURRED_STOP_CLOCK_MASK        0x0000000000400000
+
+/*   SH_EVENT_OCCURRED_RTC0_INT                                         */
+/*   Description:  Pending RTC 0 Interrupt                              */
+#define SH_EVENT_OCCURRED_RTC0_INT_SHFT          23
+#define SH_EVENT_OCCURRED_RTC0_INT_MASK          0x0000000000800000
+
+/*   SH_EVENT_OCCURRED_RTC1_INT                                         */
+/*   Description:  Pending RTC 1 Interrupt                              */
+#define SH_EVENT_OCCURRED_RTC1_INT_SHFT          24
+#define SH_EVENT_OCCURRED_RTC1_INT_MASK          0x0000000001000000
+
+/*   SH_EVENT_OCCURRED_RTC2_INT                                         */
+/*   Description:  Pending RTC 2 Interrupt                              */
+#define SH_EVENT_OCCURRED_RTC2_INT_SHFT          25
+#define SH_EVENT_OCCURRED_RTC2_INT_MASK          0x0000000002000000
+
+/*   SH_EVENT_OCCURRED_RTC3_INT                                         */
+/*   Description:  Pending RTC 3 Interrupt                              */
+#define SH_EVENT_OCCURRED_RTC3_INT_SHFT          26
+#define SH_EVENT_OCCURRED_RTC3_INT_MASK          0x0000000004000000
+
+/*   SH_EVENT_OCCURRED_PROFILE_INT                                      */
+/*   Description:  Pending Profile Interrupt                            */
+#define SH_EVENT_OCCURRED_PROFILE_INT_SHFT       27
+#define SH_EVENT_OCCURRED_PROFILE_INT_MASK       0x0000000008000000
+
+/*   SH_EVENT_OCCURRED_IPI_INT                                          */
+/*   Description:  Pending IPI Interrupt                                */
+#define SH_EVENT_OCCURRED_IPI_INT_SHFT           28
+#define SH_EVENT_OCCURRED_IPI_INT_MASK           0x0000000010000000
+
+/*   SH_EVENT_OCCURRED_II_INT0                                          */
+/*   Description:  Pending II 0 Interrupt                               */
+#define SH_EVENT_OCCURRED_II_INT0_SHFT           29
+#define SH_EVENT_OCCURRED_II_INT0_MASK           0x0000000020000000
+
+/*   SH_EVENT_OCCURRED_II_INT1                                          */
+/*   Description:  Pending II 1 Interrupt                               */
+#define SH_EVENT_OCCURRED_II_INT1_SHFT           30
+#define SH_EVENT_OCCURRED_II_INT1_MASK           0x0000000040000000
+
+/* ==================================================================== */
+/*                  Register "SH_EVENT_OCCURRED_ALIAS"                  */
+/*                 SHub Interrupt Event Occurred Alias                  */
+/* ==================================================================== */
+
+#define SH_EVENT_OCCURRED_ALIAS                  0x0000000110010008
+
+/* ==================================================================== */
+/*                     Register "SH_EVENT_OVERFLOW"                     */
+/*                SHub Interrupt Event Occurred Overflow                */
+/* ==================================================================== */
+
+#define SH_EVENT_OVERFLOW                        0x0000000110010080
+#define SH_EVENT_OVERFLOW_MASK                   0x000000000fffffff
+#define SH_EVENT_OVERFLOW_INIT                   0x0000000000000000
+
+/*   SH_EVENT_OVERFLOW_PI_HW_INT                                        */
+/*   Description:  Pending PI Hardware interrupt                        */
+#define SH_EVENT_OVERFLOW_PI_HW_INT_SHFT         0
+#define SH_EVENT_OVERFLOW_PI_HW_INT_MASK         0x0000000000000001
+
+/*   SH_EVENT_OVERFLOW_MD_HW_INT                                        */
+/*   Description:  Pending MD Hardware interrupt                        */
+#define SH_EVENT_OVERFLOW_MD_HW_INT_SHFT         1
+#define SH_EVENT_OVERFLOW_MD_HW_INT_MASK         0x0000000000000002
+
+/*   SH_EVENT_OVERFLOW_XN_HW_INT                                        */
+/*   Description:  Pending XN Hardware interrupt                        */
+#define SH_EVENT_OVERFLOW_XN_HW_INT_SHFT         2
+#define SH_EVENT_OVERFLOW_XN_HW_INT_MASK         0x0000000000000004
+
+/*   SH_EVENT_OVERFLOW_LB_HW_INT                                        */
+/*   Description:  Pending LB Hardware interrupt                        */
+#define SH_EVENT_OVERFLOW_LB_HW_INT_SHFT         3
+#define SH_EVENT_OVERFLOW_LB_HW_INT_MASK         0x0000000000000008
+
+/*   SH_EVENT_OVERFLOW_II_HW_INT                                        */
+/*   Description:  Pending II wrapper Hardware interrupt                */
+#define SH_EVENT_OVERFLOW_II_HW_INT_SHFT         4
+#define SH_EVENT_OVERFLOW_II_HW_INT_MASK         0x0000000000000010
+
+/*   SH_EVENT_OVERFLOW_PI_CE_INT                                        */
+/*   Description:  Pending PI Correctable Error Interrupt               */
+#define SH_EVENT_OVERFLOW_PI_CE_INT_SHFT         5
+#define SH_EVENT_OVERFLOW_PI_CE_INT_MASK         0x0000000000000020
+
+/*   SH_EVENT_OVERFLOW_MD_CE_INT                                        */
+/*   Description:  Pending MD Correctable Error Interrupt               */
+#define SH_EVENT_OVERFLOW_MD_CE_INT_SHFT         6
+#define SH_EVENT_OVERFLOW_MD_CE_INT_MASK         0x0000000000000040
+
+/*   SH_EVENT_OVERFLOW_XN_CE_INT                                        */
+/*   Description:  Pending XN Correctable Error Interrupt               */
+#define SH_EVENT_OVERFLOW_XN_CE_INT_SHFT         7
+#define SH_EVENT_OVERFLOW_XN_CE_INT_MASK         0x0000000000000080
+
+/*   SH_EVENT_OVERFLOW_PI_UCE_INT                                       */
+/*   Description:  Pending PI Correctable Error Interrupt               */
+#define SH_EVENT_OVERFLOW_PI_UCE_INT_SHFT        8
+#define SH_EVENT_OVERFLOW_PI_UCE_INT_MASK        0x0000000000000100
+
+/*   SH_EVENT_OVERFLOW_MD_UCE_INT                                       */
+/*   Description:  Pending MD Correctable Error Interrupt               */
+#define SH_EVENT_OVERFLOW_MD_UCE_INT_SHFT        9
+#define SH_EVENT_OVERFLOW_MD_UCE_INT_MASK        0x0000000000000200
+
+/*   SH_EVENT_OVERFLOW_XN_UCE_INT                                       */
+/*   Description:  Pending XN Correctable Error Interrupt               */
+#define SH_EVENT_OVERFLOW_XN_UCE_INT_SHFT        10
+#define SH_EVENT_OVERFLOW_XN_UCE_INT_MASK        0x0000000000000400
+
+/*   SH_EVENT_OVERFLOW_PROC0_ADV_INT                                    */
+/*   Description:  Pending Processor 0 Advisory Interrupt               */
+#define SH_EVENT_OVERFLOW_PROC0_ADV_INT_SHFT     11
+#define SH_EVENT_OVERFLOW_PROC0_ADV_INT_MASK     0x0000000000000800
+
+/*   SH_EVENT_OVERFLOW_PROC1_ADV_INT                                    */
+/*   Description:  Pending Processor 1 Advisory Interrupt               */
+#define SH_EVENT_OVERFLOW_PROC1_ADV_INT_SHFT     12
+#define SH_EVENT_OVERFLOW_PROC1_ADV_INT_MASK     0x0000000000001000
+
+/*   SH_EVENT_OVERFLOW_PROC2_ADV_INT                                    */
+/*   Description:  Pending Processor 2 Advisory Interrupt               */
+#define SH_EVENT_OVERFLOW_PROC2_ADV_INT_SHFT     13
+#define SH_EVENT_OVERFLOW_PROC2_ADV_INT_MASK     0x0000000000002000
+
+/*   SH_EVENT_OVERFLOW_PROC3_ADV_INT                                    */
+/*   Description:  Pending Processor 3 Advisory Interrupt               */
+#define SH_EVENT_OVERFLOW_PROC3_ADV_INT_SHFT     14
+#define SH_EVENT_OVERFLOW_PROC3_ADV_INT_MASK     0x0000000000004000
+
+/*   SH_EVENT_OVERFLOW_PROC0_ERR_INT                                    */
+/*   Description:  Pending Processor 0 Error Interrupt                  */
+#define SH_EVENT_OVERFLOW_PROC0_ERR_INT_SHFT     15
+#define SH_EVENT_OVERFLOW_PROC0_ERR_INT_MASK     0x0000000000008000
+
+/*   SH_EVENT_OVERFLOW_PROC1_ERR_INT                                    */
+/*   Description:  Pending Processor 1 Error Interrupt                  */
+#define SH_EVENT_OVERFLOW_PROC1_ERR_INT_SHFT     16
+#define SH_EVENT_OVERFLOW_PROC1_ERR_INT_MASK     0x0000000000010000
+
+/*   SH_EVENT_OVERFLOW_PROC2_ERR_INT                                    */
+/*   Description:  Pending Processor 2 Error Interrupt                  */
+#define SH_EVENT_OVERFLOW_PROC2_ERR_INT_SHFT     17
+#define SH_EVENT_OVERFLOW_PROC2_ERR_INT_MASK     0x0000000000020000
+
+/*   SH_EVENT_OVERFLOW_PROC3_ERR_INT                                    */
+/*   Description:  Pending Processor 3 Error Interrupt                  */
+#define SH_EVENT_OVERFLOW_PROC3_ERR_INT_SHFT     18
+#define SH_EVENT_OVERFLOW_PROC3_ERR_INT_MASK     0x0000000000040000
+
+/*   SH_EVENT_OVERFLOW_SYSTEM_SHUTDOWN_INT                              */
+/*   Description:  Pending System Shutdown Interrupt                    */
+#define SH_EVENT_OVERFLOW_SYSTEM_SHUTDOWN_INT_SHFT 19
+#define SH_EVENT_OVERFLOW_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000080000
+
+/*   SH_EVENT_OVERFLOW_UART_INT                                         */
+/*   Description:  Pending Junk Bus UART Interrupt                      */
+#define SH_EVENT_OVERFLOW_UART_INT_SHFT          20
+#define SH_EVENT_OVERFLOW_UART_INT_MASK          0x0000000000100000
+
+/*   SH_EVENT_OVERFLOW_L1_NMI_INT                                       */
+/*   Description:  Pending L1 Controller NMI Interrupt                  */
+#define SH_EVENT_OVERFLOW_L1_NMI_INT_SHFT        21
+#define SH_EVENT_OVERFLOW_L1_NMI_INT_MASK        0x0000000000200000
+
+/*   SH_EVENT_OVERFLOW_STOP_CLOCK                                       */
+/*   Description:  Pending Stop Clock Interrupt                         */
+#define SH_EVENT_OVERFLOW_STOP_CLOCK_SHFT        22
+#define SH_EVENT_OVERFLOW_STOP_CLOCK_MASK        0x0000000000400000
+
+/*   SH_EVENT_OVERFLOW_RTC0_INT                                         */
+/*   Description:  Pending RTC 0 Interrupt                              */
+#define SH_EVENT_OVERFLOW_RTC0_INT_SHFT          23
+#define SH_EVENT_OVERFLOW_RTC0_INT_MASK          0x0000000000800000
+
+/*   SH_EVENT_OVERFLOW_RTC1_INT                                         */
+/*   Description:  Pending RTC 1 Interrupt                              */
+#define SH_EVENT_OVERFLOW_RTC1_INT_SHFT          24
+#define SH_EVENT_OVERFLOW_RTC1_INT_MASK          0x0000000001000000
+
+/*   SH_EVENT_OVERFLOW_RTC2_INT                                         */
+/*   Description:  Pending RTC 2 Interrupt                              */
+#define SH_EVENT_OVERFLOW_RTC2_INT_SHFT          25
+#define SH_EVENT_OVERFLOW_RTC2_INT_MASK          0x0000000002000000
+
+/*   SH_EVENT_OVERFLOW_RTC3_INT                                         */
+/*   Description:  Pending RTC 3 Interrupt                              */
+#define SH_EVENT_OVERFLOW_RTC3_INT_SHFT          26
+#define SH_EVENT_OVERFLOW_RTC3_INT_MASK          0x0000000004000000
+
+/*   SH_EVENT_OVERFLOW_PROFILE_INT                                      */
+/*   Description:  Pending Profile Interrupt                            */
+#define SH_EVENT_OVERFLOW_PROFILE_INT_SHFT       27
+#define SH_EVENT_OVERFLOW_PROFILE_INT_MASK       0x0000000008000000
+
+/* ==================================================================== */
+/*                  Register "SH_EVENT_OVERFLOW_ALIAS"                  */
+/*             SHub Interrupt Event Occurred Overflow Alias             */
+/* ==================================================================== */
+
+#define SH_EVENT_OVERFLOW_ALIAS                  0x0000000110010088
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_TIME"                      */
+/*                           Junk Bus Timing                            */
+/* ==================================================================== */
+
+#define SH_JUNK_BUS_TIME                         0x0000000110020000
+#define SH_JUNK_BUS_TIME_MASK                    0x00000000ffffffff
+#define SH_JUNK_BUS_TIME_INIT                    0x0000000040404040
+
+/*   SH_JUNK_BUS_TIME_FPROM_SETUP_HOLD                                  */
+/*   Description:  Fprom_Setup_Hold                                     */
+#define SH_JUNK_BUS_TIME_FPROM_SETUP_HOLD_SHFT   0
+#define SH_JUNK_BUS_TIME_FPROM_SETUP_HOLD_MASK   0x00000000000000ff
+
+/*   SH_JUNK_BUS_TIME_FPROM_ENABLE                                      */
+/*   Description:  Fprom_Enable                                         */
+#define SH_JUNK_BUS_TIME_FPROM_ENABLE_SHFT       8
+#define SH_JUNK_BUS_TIME_FPROM_ENABLE_MASK       0x000000000000ff00
+
+/*   SH_JUNK_BUS_TIME_UART_SETUP_HOLD                                   */
+/*   Description:  Uart_Setup_Hold                                      */
+#define SH_JUNK_BUS_TIME_UART_SETUP_HOLD_SHFT    16
+#define SH_JUNK_BUS_TIME_UART_SETUP_HOLD_MASK    0x0000000000ff0000
+
+/*   SH_JUNK_BUS_TIME_UART_ENABLE                                       */
+/*   Description:  Uart_Enable                                          */
+#define SH_JUNK_BUS_TIME_UART_ENABLE_SHFT        24
+#define SH_JUNK_BUS_TIME_UART_ENABLE_MASK        0x00000000ff000000
+
+/* ==================================================================== */
+/*                    Register "SH_JUNK_LATCH_TIME"                     */
+/*                        Junk Bus Latch Timing                         */
+/* ==================================================================== */
+
+#define SH_JUNK_LATCH_TIME                       0x0000000110020080
+#define SH_JUNK_LATCH_TIME_MASK                  0x0000000000000007
+#define SH_JUNK_LATCH_TIME_INIT                  0x0000000000000002
+
+/*   SH_JUNK_LATCH_TIME_SETUP_HOLD                                      */
+/*   Description:  Setup and Hold Time                                  */
+#define SH_JUNK_LATCH_TIME_SETUP_HOLD_SHFT       0
+#define SH_JUNK_LATCH_TIME_SETUP_HOLD_MASK       0x0000000000000007
+
+/* ==================================================================== */
+/*                    Register "SH_JUNK_NACK_RESET"                     */
+/*                     Junk Bus Nack Counter Reset                      */
+/* ==================================================================== */
+
+#define SH_JUNK_NACK_RESET                       0x0000000110020100
+#define SH_JUNK_NACK_RESET_MASK                  0x0000000000000001
+#define SH_JUNK_NACK_RESET_INIT                  0x0000000000000000
+
+/*   SH_JUNK_NACK_RESET_PULSE                                           */
+/*   Description:  Junk bus nack counter reset                          */
+#define SH_JUNK_NACK_RESET_PULSE_SHFT            0
+#define SH_JUNK_NACK_RESET_PULSE_MASK            0x0000000000000001
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_LED0"                      */
+/*                            Junk Bus LED0                             */
+/* ==================================================================== */
+
+#define SH_JUNK_BUS_LED0                         0x0000000110030000
+#define SH_JUNK_BUS_LED0_MASK                    0x00000000000000ff
+#define SH_JUNK_BUS_LED0_INIT                    0x0000000000000000
+
+/*   SH_JUNK_BUS_LED0_LED0_DATA                                         */
+/*   Description:  LED0_data                                            */
+#define SH_JUNK_BUS_LED0_LED0_DATA_SHFT          0
+#define SH_JUNK_BUS_LED0_LED0_DATA_MASK          0x00000000000000ff
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_LED1"                      */
+/*                            Junk Bus LED1                             */
+/* ==================================================================== */
+
+#define SH_JUNK_BUS_LED1                         0x0000000110030080
+#define SH_JUNK_BUS_LED1_MASK                    0x00000000000000ff
+#define SH_JUNK_BUS_LED1_INIT                    0x0000000000000000
+
+/*   SH_JUNK_BUS_LED1_LED1_DATA                                         */
+/*   Description:  LED1_data                                            */
+#define SH_JUNK_BUS_LED1_LED1_DATA_SHFT          0
+#define SH_JUNK_BUS_LED1_LED1_DATA_MASK          0x00000000000000ff
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_LED2"                      */
+/*                            Junk Bus LED2                             */
+/* ==================================================================== */
+
+#define SH_JUNK_BUS_LED2                         0x0000000110030100
+#define SH_JUNK_BUS_LED2_MASK                    0x00000000000000ff
+#define SH_JUNK_BUS_LED2_INIT                    0x0000000000000000
+
+/*   SH_JUNK_BUS_LED2_LED2_DATA                                         */
+/*   Description:  LED2_data                                            */
+#define SH_JUNK_BUS_LED2_LED2_DATA_SHFT          0
+#define SH_JUNK_BUS_LED2_LED2_DATA_MASK          0x00000000000000ff
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_LED3"                      */
+/*                            Junk Bus LED3                             */
+/* ==================================================================== */
+
+#define SH_JUNK_BUS_LED3                         0x0000000110030180
+#define SH_JUNK_BUS_LED3_MASK                    0x00000000000000ff
+#define SH_JUNK_BUS_LED3_INIT                    0x0000000000000000
+
+/*   SH_JUNK_BUS_LED3_LED3_DATA                                         */
+/*   Description:  LED3_data                                            */
+#define SH_JUNK_BUS_LED3_LED3_DATA_SHFT          0
+#define SH_JUNK_BUS_LED3_LED3_DATA_MASK          0x00000000000000ff
+
+/* ==================================================================== */
+/*                   Register "SH_JUNK_ERROR_STATUS"                    */
+/*                        Junk Bus Error Status                         */
+/* ==================================================================== */
+
+#define SH_JUNK_ERROR_STATUS                     0x0000000110030200
+#define SH_JUNK_ERROR_STATUS_MASK                0x1fff7fffffffffff
+#define SH_JUNK_ERROR_STATUS_INIT                0x0000000000000000
+
+/*   SH_JUNK_ERROR_STATUS_ADDRESS                                       */
+/*   Description:  Failing junk bus address                             */
+#define SH_JUNK_ERROR_STATUS_ADDRESS_SHFT        0
+#define SH_JUNK_ERROR_STATUS_ADDRESS_MASK        0x00007fffffffffff
+
+/*   SH_JUNK_ERROR_STATUS_CMD                                           */
+/*   Description:  Junk bus command                                     */
+#define SH_JUNK_ERROR_STATUS_CMD_SHFT            48
+#define SH_JUNK_ERROR_STATUS_CMD_MASK            0x00ff000000000000
+
+/*   SH_JUNK_ERROR_STATUS_MODE                                          */
+/*   Description:  Mode                                                 */
+#define SH_JUNK_ERROR_STATUS_MODE_SHFT           56
+#define SH_JUNK_ERROR_STATUS_MODE_MASK           0x0100000000000000
+
+/*   SH_JUNK_ERROR_STATUS_STATUS                                        */
+/*   Description:  Status                                               */
+#define SH_JUNK_ERROR_STATUS_STATUS_SHFT         57
+#define SH_JUNK_ERROR_STATUS_STATUS_MASK         0x1e00000000000000
+
+/* ==================================================================== */
+/*                      Register "SH_NI0_LLP_STAT"                      */
+/*               This register describes the LLP status.                */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_STAT                          0x0000000150000000
+#define SH_NI0_LLP_STAT_MASK                     0x000000000000000f
+#define SH_NI0_LLP_STAT_INIT                     0x0000000000000000
+
+/*   SH_NI0_LLP_STAT_LINK_RESET_STATE                                   */
+/*   Description:  Status of LLP link.                                  */
+#define SH_NI0_LLP_STAT_LINK_RESET_STATE_SHFT    0
+#define SH_NI0_LLP_STAT_LINK_RESET_STATE_MASK    0x000000000000000f
+
+/* ==================================================================== */
+/*                     Register "SH_NI0_LLP_RESET"                      */
+/*           Writing issues a reset to the network interface            */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_RESET                         0x0000000150000008
+#define SH_NI0_LLP_RESET_MASK                    0x0000000000000003
+#define SH_NI0_LLP_RESET_INIT                    0x0000000000000000
+
+/*   SH_NI0_LLP_RESET_LINK                                              */
+/*   Description:  Send Link Reset. Generates a pulse.                  */
+#define SH_NI0_LLP_RESET_LINK_SHFT               0
+#define SH_NI0_LLP_RESET_LINK_MASK               0x0000000000000001
+
+/*   SH_NI0_LLP_RESET_WARM                                              */
+/*   Description:  Send Warm Reset. Generates a pulse.                  */
+#define SH_NI0_LLP_RESET_WARM_SHFT               1
+#define SH_NI0_LLP_RESET_WARM_MASK               0x0000000000000002
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LLP_RESET_EN"                    */
+/*                 Controls LLP warm reset propagation                  */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_RESET_EN                      0x0000000150000010
+#define SH_NI0_LLP_RESET_EN_MASK                 0x0000000000000001
+#define SH_NI0_LLP_RESET_EN_INIT                 0x0000000000000001
+
+/*   SH_NI0_LLP_RESET_EN_OK                                             */
+/*   Description:  Allow LLP warm reset to reset SHUB                   */
+#define SH_NI0_LLP_RESET_EN_OK_SHFT              0
+#define SH_NI0_LLP_RESET_EN_OK_MASK              0x0000000000000001
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_LLP_CHAN_MODE"                    */
+/*              Sets the signaling mode of LLP and channel              */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_CHAN_MODE                     0x0000000150000018
+#define SH_NI0_LLP_CHAN_MODE_MASK                0x000000000000001f
+#define SH_NI0_LLP_CHAN_MODE_INIT                0x0000000000000000
+
+/*   SH_NI0_LLP_CHAN_MODE_BITMODE32                                     */
+/*   Description:  Enables 32-bit (plus sideband) channel phits         */
+#define SH_NI0_LLP_CHAN_MODE_BITMODE32_SHFT      0
+#define SH_NI0_LLP_CHAN_MODE_BITMODE32_MASK      0x0000000000000001
+
+/*   SH_NI0_LLP_CHAN_MODE_AC_ENCODE                                     */
+/*   Description:  Enables nearly dc-free encoding for AC-coupling      */
+#define SH_NI0_LLP_CHAN_MODE_AC_ENCODE_SHFT      1
+#define SH_NI0_LLP_CHAN_MODE_AC_ENCODE_MASK      0x0000000000000002
+
+/*   SH_NI0_LLP_CHAN_MODE_ENABLE_TUNING                                 */
+/*   Description:  Enables automatic tuning of channel skew.            */
+#define SH_NI0_LLP_CHAN_MODE_ENABLE_TUNING_SHFT  2
+#define SH_NI0_LLP_CHAN_MODE_ENABLE_TUNING_MASK  0x0000000000000004
+
+/*   SH_NI0_LLP_CHAN_MODE_ENABLE_RMT_FT_UPD                             */
+/*   Description:  Enables remote fine tune updates                     */
+#define SH_NI0_LLP_CHAN_MODE_ENABLE_RMT_FT_UPD_SHFT 3
+#define SH_NI0_LLP_CHAN_MODE_ENABLE_RMT_FT_UPD_MASK 0x0000000000000008
+
+/*   SH_NI0_LLP_CHAN_MODE_ENABLE_CLKQUAD                                */
+/*   Description:  Enables quadrature clock in the pfssd                */
+#define SH_NI0_LLP_CHAN_MODE_ENABLE_CLKQUAD_SHFT 4
+#define SH_NI0_LLP_CHAN_MODE_ENABLE_CLKQUAD_MASK 0x0000000000000010
+
+/* ==================================================================== */
+/*                     Register "SH_NI0_LLP_CONFIG"                     */
+/*              Sets the configuration of LLP and channel               */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_CONFIG                        0x0000000150000020
+#define SH_NI0_LLP_CONFIG_MASK                   0x0000003fffffffff
+#define SH_NI0_LLP_CONFIG_INIT                   0x00000007fc6ffd00
+
+/*   SH_NI0_LLP_CONFIG_MAXBURST                                         */
+#define SH_NI0_LLP_CONFIG_MAXBURST_SHFT          0
+#define SH_NI0_LLP_CONFIG_MAXBURST_MASK          0x00000000000003ff
+
+/*   SH_NI0_LLP_CONFIG_MAXRETRY                                         */
+#define SH_NI0_LLP_CONFIG_MAXRETRY_SHFT          10
+#define SH_NI0_LLP_CONFIG_MAXRETRY_MASK          0x00000000000ffc00
+
+/*   SH_NI0_LLP_CONFIG_NULLTIMEOUT                                      */
+#define SH_NI0_LLP_CONFIG_NULLTIMEOUT_SHFT       20
+#define SH_NI0_LLP_CONFIG_NULLTIMEOUT_MASK       0x0000000003f00000
+
+/*   SH_NI0_LLP_CONFIG_FTU_TIME                                         */
+#define SH_NI0_LLP_CONFIG_FTU_TIME_SHFT          26
+#define SH_NI0_LLP_CONFIG_FTU_TIME_MASK          0x0000003ffc000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LLP_TEST_CTL"                    */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_TEST_CTL                      0x0000000150000028
+#define SH_NI0_LLP_TEST_CTL_MASK                 0x7ff3f3ffffffffff
+#define SH_NI0_LLP_TEST_CTL_INIT                 0x000000000a5fffff
+
+/*   SH_NI0_LLP_TEST_CTL_PATTERN                                        */
+/*   Description:  Send channel data pattern                            */
+#define SH_NI0_LLP_TEST_CTL_PATTERN_SHFT         0
+#define SH_NI0_LLP_TEST_CTL_PATTERN_MASK         0x000000ffffffffff
+
+/*   SH_NI0_LLP_TEST_CTL_SEND_TEST_MODE                                 */
+/*   Description:  Enables continuous send of data                      */
+#define SH_NI0_LLP_TEST_CTL_SEND_TEST_MODE_SHFT  40
+#define SH_NI0_LLP_TEST_CTL_SEND_TEST_MODE_MASK  0x0000030000000000
+
+/*   SH_NI0_LLP_TEST_CTL_WIRE_SEL                                       */
+#define SH_NI0_LLP_TEST_CTL_WIRE_SEL_SHFT        44
+#define SH_NI0_LLP_TEST_CTL_WIRE_SEL_MASK        0x0003f00000000000
+
+/*   SH_NI0_LLP_TEST_CTL_LFSR_MODE                                      */
+#define SH_NI0_LLP_TEST_CTL_LFSR_MODE_SHFT       52
+#define SH_NI0_LLP_TEST_CTL_LFSR_MODE_MASK       0x0030000000000000
+
+/*   SH_NI0_LLP_TEST_CTL_NOISE_MODE                                     */
+#define SH_NI0_LLP_TEST_CTL_NOISE_MODE_SHFT      54
+#define SH_NI0_LLP_TEST_CTL_NOISE_MODE_MASK      0x00c0000000000000
+
+/*   SH_NI0_LLP_TEST_CTL_ARMCAPTURE                                     */
+/*   Description:  Enable Capture of Next MicroPacket                   */
+#define SH_NI0_LLP_TEST_CTL_ARMCAPTURE_SHFT      56
+#define SH_NI0_LLP_TEST_CTL_ARMCAPTURE_MASK      0x0100000000000000
+
+/*   SH_NI0_LLP_TEST_CTL_CAPTURECBONLY                                  */
+/*   Description:  Only capture a micropacket with a Check Byte error  */
+#define SH_NI0_LLP_TEST_CTL_CAPTURECBONLY_SHFT   57
+#define SH_NI0_LLP_TEST_CTL_CAPTURECBONLY_MASK   0x0200000000000000
+
+/*   SH_NI0_LLP_TEST_CTL_SENDCBERROR                                    */
+/*   Description:  Sends a single error                                 */
+#define SH_NI0_LLP_TEST_CTL_SENDCBERROR_SHFT     58
+#define SH_NI0_LLP_TEST_CTL_SENDCBERROR_MASK     0x0400000000000000
+
+/*   SH_NI0_LLP_TEST_CTL_SENDSNERROR                                    */
+/*   Description:  Sends a single sequence number error                 */
+#define SH_NI0_LLP_TEST_CTL_SENDSNERROR_SHFT     59
+#define SH_NI0_LLP_TEST_CTL_SENDSNERROR_MASK     0x0800000000000000
+
+/*   SH_NI0_LLP_TEST_CTL_FAKESNERROR                                    */
+/*   Description:  Causes receiver to pretend it saw a sn error         */
+#define SH_NI0_LLP_TEST_CTL_FAKESNERROR_SHFT     60
+#define SH_NI0_LLP_TEST_CTL_FAKESNERROR_MASK     0x1000000000000000
+
+/*   SH_NI0_LLP_TEST_CTL_CAPTURED                                       */
+/*   Description:  Indicates a Valid Micropacket was captured           */
+#define SH_NI0_LLP_TEST_CTL_CAPTURED_SHFT        61
+#define SH_NI0_LLP_TEST_CTL_CAPTURED_MASK        0x2000000000000000
+
+/*   SH_NI0_LLP_TEST_CTL_CBERROR                                        */
+/*   Description:  Indicates a Micropacket with a CB error was capture  */
+#define SH_NI0_LLP_TEST_CTL_CBERROR_SHFT         62
+#define SH_NI0_LLP_TEST_CTL_CBERROR_MASK         0x4000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LLP_CAPT_WD1"                    */
+/*                    low order 64-bit captured word                    */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_CAPT_WD1                      0x0000000150000030
+#define SH_NI0_LLP_CAPT_WD1_MASK                 0xffffffffffffffff
+#define SH_NI0_LLP_CAPT_WD1_INIT                 0x0000000000000000
+
+/*   SH_NI0_LLP_CAPT_WD1_DATA                                           */
+/*   Description:  low order 64-bit captured word                       */
+#define SH_NI0_LLP_CAPT_WD1_DATA_SHFT            0
+#define SH_NI0_LLP_CAPT_WD1_DATA_MASK            0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LLP_CAPT_WD2"                    */
+/*                   high order 64-bit captured word                    */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_CAPT_WD2                      0x0000000150000038
+#define SH_NI0_LLP_CAPT_WD2_MASK                 0xffffffffffffffff
+#define SH_NI0_LLP_CAPT_WD2_INIT                 0x0000000000000000
+
+/*   SH_NI0_LLP_CAPT_WD2_DATA                                           */
+/*   Description:  high order 64-bit captured word                      */
+#define SH_NI0_LLP_CAPT_WD2_DATA_SHFT            0
+#define SH_NI0_LLP_CAPT_WD2_DATA_MASK            0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_LLP_CAPT_SBCB"                    */
+/*                 captured sideband, sequence, and CRC                 */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_CAPT_SBCB                     0x0000000150000040
+#define SH_NI0_LLP_CAPT_SBCB_MASK                0x0000001fffffffff
+#define SH_NI0_LLP_CAPT_SBCB_INIT                0x0000000000000000
+
+/*   SH_NI0_LLP_CAPT_SBCB_CAPTUREDRCVSBSN                               */
+/*   Description:  sideband and sequence                                */
+#define SH_NI0_LLP_CAPT_SBCB_CAPTUREDRCVSBSN_SHFT 0
+#define SH_NI0_LLP_CAPT_SBCB_CAPTUREDRCVSBSN_MASK 0x000000000000ffff
+
+/*   SH_NI0_LLP_CAPT_SBCB_CAPTUREDRCVCRC                                */
+/*   Description:  CRC                                                  */
+#define SH_NI0_LLP_CAPT_SBCB_CAPTUREDRCVCRC_SHFT 16
+#define SH_NI0_LLP_CAPT_SBCB_CAPTUREDRCVCRC_MASK 0x00000000ffff0000
+
+/*   SH_NI0_LLP_CAPT_SBCB_SENTALLCBERRORS                               */
+/*   Description:  All CB errors have been sent                         */
+#define SH_NI0_LLP_CAPT_SBCB_SENTALLCBERRORS_SHFT 32
+#define SH_NI0_LLP_CAPT_SBCB_SENTALLCBERRORS_MASK 0x0000000100000000
+
+/*   SH_NI0_LLP_CAPT_SBCB_SENTALLSNERRORS                               */
+/*   Description:  All SN errors have been sent                         */
+#define SH_NI0_LLP_CAPT_SBCB_SENTALLSNERRORS_SHFT 33
+#define SH_NI0_LLP_CAPT_SBCB_SENTALLSNERRORS_MASK 0x0000000200000000
+
+/*   SH_NI0_LLP_CAPT_SBCB_FAKEDALLSNERRORS                              */
+/*   Description:  All faked SN errors have been sent                   */
+#define SH_NI0_LLP_CAPT_SBCB_FAKEDALLSNERRORS_SHFT 34
+#define SH_NI0_LLP_CAPT_SBCB_FAKEDALLSNERRORS_MASK 0x0000000400000000
+
+/*   SH_NI0_LLP_CAPT_SBCB_CHARGEOVERFLOW                                */
+/*   Description:  wire charge counter overflowed, valid if llp_mode e  */
+#define SH_NI0_LLP_CAPT_SBCB_CHARGEOVERFLOW_SHFT 35
+#define SH_NI0_LLP_CAPT_SBCB_CHARGEOVERFLOW_MASK 0x0000000800000000
+
+/*   SH_NI0_LLP_CAPT_SBCB_CHARGEUNDERFLOW                               */
+/*   Description:  wire charge counter underflowed, valid if llp_mode   */
+/*  enabled                                                             */
+#define SH_NI0_LLP_CAPT_SBCB_CHARGEUNDERFLOW_SHFT 36
+#define SH_NI0_LLP_CAPT_SBCB_CHARGEUNDERFLOW_MASK 0x0000001000000000
+
+/* ==================================================================== */
+/*                      Register "SH_NI0_LLP_ERR"                       */
+/* ==================================================================== */
+
+#define SH_NI0_LLP_ERR                           0x0000000150000048
+#define SH_NI0_LLP_ERR_MASK                      0x001fffffffffffff
+#define SH_NI0_LLP_ERR_INIT                      0x0000000000000000
+
+/*   SH_NI0_LLP_ERR_RX_SN_ERR_COUNT                                     */
+/*   Description:  Counts the sequence number errors received           */
+#define SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_SHFT      0
+#define SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK      0x00000000000000ff
+
+/*   SH_NI0_LLP_ERR_RX_CB_ERR_COUNT                                     */
+/*   Description:  Counts the check byte errors received                */
+#define SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_SHFT      8
+#define SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK      0x000000000000ff00
+
+/*   SH_NI0_LLP_ERR_RETRY_COUNT                                         */
+/*   Description:  Counts the retries                                   */
+#define SH_NI0_LLP_ERR_RETRY_COUNT_SHFT          16
+#define SH_NI0_LLP_ERR_RETRY_COUNT_MASK          0x0000000000ff0000
+
+/*   SH_NI0_LLP_ERR_RETRY_TIMEOUT                                       */
+/*   Description:  Indicates a retry timeout has occured                */
+#define SH_NI0_LLP_ERR_RETRY_TIMEOUT_SHFT        24
+#define SH_NI0_LLP_ERR_RETRY_TIMEOUT_MASK        0x0000000001000000
+
+/*   SH_NI0_LLP_ERR_RCV_LINK_RESET                                      */
+/*   Description:  Indicates a link reset has been received             */
+#define SH_NI0_LLP_ERR_RCV_LINK_RESET_SHFT       25
+#define SH_NI0_LLP_ERR_RCV_LINK_RESET_MASK       0x0000000002000000
+
+/*   SH_NI0_LLP_ERR_SQUASH                                              */
+/*   Description:  Indicates a micropacket was squashed                 */
+#define SH_NI0_LLP_ERR_SQUASH_SHFT               26
+#define SH_NI0_LLP_ERR_SQUASH_MASK               0x0000000004000000
+
+/*   SH_NI0_LLP_ERR_POWER_NOT_OK                                        */
+/*   Description:  Detects and traps a loss of power_OK                 */
+#define SH_NI0_LLP_ERR_POWER_NOT_OK_SHFT         27
+#define SH_NI0_LLP_ERR_POWER_NOT_OK_MASK         0x0000000008000000
+
+/*   SH_NI0_LLP_ERR_WIRE_CNT                                            */
+/*   Description:  counts the errors detected on a single wire test     */
+#define SH_NI0_LLP_ERR_WIRE_CNT_SHFT             28
+#define SH_NI0_LLP_ERR_WIRE_CNT_MASK             0x000ffffff0000000
+
+/*   SH_NI0_LLP_ERR_WIRE_OVERFLOW                                       */
+/*   Description:  wire_error_cnt has overflowed                        */
+#define SH_NI0_LLP_ERR_WIRE_OVERFLOW_SHFT        52
+#define SH_NI0_LLP_ERR_WIRE_OVERFLOW_MASK        0x0010000000000000
+
+/* ==================================================================== */
+/*                      Register "SH_NI1_LLP_STAT"                      */
+/*               This register describes the LLP status.                */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_STAT                          0x0000000150002000
+#define SH_NI1_LLP_STAT_MASK                     0x000000000000000f
+#define SH_NI1_LLP_STAT_INIT                     0x0000000000000000
+
+/*   SH_NI1_LLP_STAT_LINK_RESET_STATE                                   */
+/*   Description:  Status of LLP link.                                  */
+#define SH_NI1_LLP_STAT_LINK_RESET_STATE_SHFT    0
+#define SH_NI1_LLP_STAT_LINK_RESET_STATE_MASK    0x000000000000000f
+
+/* ==================================================================== */
+/*                     Register "SH_NI1_LLP_RESET"                      */
+/*           Writing issues a reset to the network interface            */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_RESET                         0x0000000150002008
+#define SH_NI1_LLP_RESET_MASK                    0x0000000000000003
+#define SH_NI1_LLP_RESET_INIT                    0x0000000000000000
+
+/*   SH_NI1_LLP_RESET_LINK                                              */
+/*   Description:  Send Link Reset. Generates a pulse.                  */
+#define SH_NI1_LLP_RESET_LINK_SHFT               0
+#define SH_NI1_LLP_RESET_LINK_MASK               0x0000000000000001
+
+/*   SH_NI1_LLP_RESET_WARM                                              */
+/*   Description:  Send Warm Reset. Generates a pulse.                  */
+#define SH_NI1_LLP_RESET_WARM_SHFT               1
+#define SH_NI1_LLP_RESET_WARM_MASK               0x0000000000000002
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LLP_RESET_EN"                    */
+/*                 Controls LLP warm reset propagation                  */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_RESET_EN                      0x0000000150002010
+#define SH_NI1_LLP_RESET_EN_MASK                 0x0000000000000001
+#define SH_NI1_LLP_RESET_EN_INIT                 0x0000000000000001
+
+/*   SH_NI1_LLP_RESET_EN_OK                                             */
+/*   Description:  Allow LLP warm reset to reset SHUB                   */
+#define SH_NI1_LLP_RESET_EN_OK_SHFT              0
+#define SH_NI1_LLP_RESET_EN_OK_MASK              0x0000000000000001
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_LLP_CHAN_MODE"                    */
+/*              Sets the signaling mode of LLP and channel              */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_CHAN_MODE                     0x0000000150002018
+#define SH_NI1_LLP_CHAN_MODE_MASK                0x000000000000001f
+#define SH_NI1_LLP_CHAN_MODE_INIT                0x0000000000000000
+
+/*   SH_NI1_LLP_CHAN_MODE_BITMODE32                                     */
+/*   Description:  Enables 32-bit (plus sideband) channel phits         */
+#define SH_NI1_LLP_CHAN_MODE_BITMODE32_SHFT      0
+#define SH_NI1_LLP_CHAN_MODE_BITMODE32_MASK      0x0000000000000001
+
+/*   SH_NI1_LLP_CHAN_MODE_AC_ENCODE                                     */
+/*   Description:  Enables nearly dc-free encoding for AC-coupling      */
+#define SH_NI1_LLP_CHAN_MODE_AC_ENCODE_SHFT      1
+#define SH_NI1_LLP_CHAN_MODE_AC_ENCODE_MASK      0x0000000000000002
+
+/*   SH_NI1_LLP_CHAN_MODE_ENABLE_TUNING                                 */
+/*   Description:  Enables automatic tuning of channel skew.            */
+#define SH_NI1_LLP_CHAN_MODE_ENABLE_TUNING_SHFT  2
+#define SH_NI1_LLP_CHAN_MODE_ENABLE_TUNING_MASK  0x0000000000000004
+
+/*   SH_NI1_LLP_CHAN_MODE_ENABLE_RMT_FT_UPD                             */
+/*   Description:  Enables remote fine tune updates                     */
+#define SH_NI1_LLP_CHAN_MODE_ENABLE_RMT_FT_UPD_SHFT 3
+#define SH_NI1_LLP_CHAN_MODE_ENABLE_RMT_FT_UPD_MASK 0x0000000000000008
+
+/*   SH_NI1_LLP_CHAN_MODE_ENABLE_CLKQUAD                                */
+/*   Description:  Enables quadrature clock in the pfssd                */
+#define SH_NI1_LLP_CHAN_MODE_ENABLE_CLKQUAD_SHFT 4
+#define SH_NI1_LLP_CHAN_MODE_ENABLE_CLKQUAD_MASK 0x0000000000000010
+
+/* ==================================================================== */
+/*                     Register "SH_NI1_LLP_CONFIG"                     */
+/*              Sets the configuration of LLP and channel               */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_CONFIG                        0x0000000150002020
+#define SH_NI1_LLP_CONFIG_MASK                   0x0000003fffffffff
+#define SH_NI1_LLP_CONFIG_INIT                   0x00000007fc6ffd00
+
+/*   SH_NI1_LLP_CONFIG_MAXBURST                                         */
+#define SH_NI1_LLP_CONFIG_MAXBURST_SHFT          0
+#define SH_NI1_LLP_CONFIG_MAXBURST_MASK          0x00000000000003ff
+
+/*   SH_NI1_LLP_CONFIG_MAXRETRY                                         */
+#define SH_NI1_LLP_CONFIG_MAXRETRY_SHFT          10
+#define SH_NI1_LLP_CONFIG_MAXRETRY_MASK          0x00000000000ffc00
+
+/*   SH_NI1_LLP_CONFIG_NULLTIMEOUT                                      */
+#define SH_NI1_LLP_CONFIG_NULLTIMEOUT_SHFT       20
+#define SH_NI1_LLP_CONFIG_NULLTIMEOUT_MASK       0x0000000003f00000
+
+/*   SH_NI1_LLP_CONFIG_FTU_TIME                                         */
+#define SH_NI1_LLP_CONFIG_FTU_TIME_SHFT          26
+#define SH_NI1_LLP_CONFIG_FTU_TIME_MASK          0x0000003ffc000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LLP_TEST_CTL"                    */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_TEST_CTL                      0x0000000150002028
+#define SH_NI1_LLP_TEST_CTL_MASK                 0x7ff3f3ffffffffff
+#define SH_NI1_LLP_TEST_CTL_INIT                 0x000000000a5fffff
+
+/*   SH_NI1_LLP_TEST_CTL_PATTERN                                        */
+/*   Description:  Send channel data pattern                            */
+#define SH_NI1_LLP_TEST_CTL_PATTERN_SHFT         0
+#define SH_NI1_LLP_TEST_CTL_PATTERN_MASK         0x000000ffffffffff
+
+/*   SH_NI1_LLP_TEST_CTL_SEND_TEST_MODE                                 */
+/*   Description:  Enables continuous send of data                      */
+#define SH_NI1_LLP_TEST_CTL_SEND_TEST_MODE_SHFT  40
+#define SH_NI1_LLP_TEST_CTL_SEND_TEST_MODE_MASK  0x0000030000000000
+
+/*   SH_NI1_LLP_TEST_CTL_WIRE_SEL                                       */
+#define SH_NI1_LLP_TEST_CTL_WIRE_SEL_SHFT        44
+#define SH_NI1_LLP_TEST_CTL_WIRE_SEL_MASK        0x0003f00000000000
+
+/*   SH_NI1_LLP_TEST_CTL_LFSR_MODE                                      */
+#define SH_NI1_LLP_TEST_CTL_LFSR_MODE_SHFT       52
+#define SH_NI1_LLP_TEST_CTL_LFSR_MODE_MASK       0x0030000000000000
+
+/*   SH_NI1_LLP_TEST_CTL_NOISE_MODE                                     */
+#define SH_NI1_LLP_TEST_CTL_NOISE_MODE_SHFT      54
+#define SH_NI1_LLP_TEST_CTL_NOISE_MODE_MASK      0x00c0000000000000
+
+/*   SH_NI1_LLP_TEST_CTL_ARMCAPTURE                                     */
+/*   Description:  Enable Capture of Next MicroPacket                   */
+#define SH_NI1_LLP_TEST_CTL_ARMCAPTURE_SHFT      56
+#define SH_NI1_LLP_TEST_CTL_ARMCAPTURE_MASK      0x0100000000000000
+
+/*   SH_NI1_LLP_TEST_CTL_CAPTURECBONLY                                  */
+/*   Description:  Only capture a micropacket with a Check Byte error  */
+#define SH_NI1_LLP_TEST_CTL_CAPTURECBONLY_SHFT   57
+#define SH_NI1_LLP_TEST_CTL_CAPTURECBONLY_MASK   0x0200000000000000
+
+/*   SH_NI1_LLP_TEST_CTL_SENDCBERROR                                    */
+/*   Description:  Sends a single error                                 */
+#define SH_NI1_LLP_TEST_CTL_SENDCBERROR_SHFT     58
+#define SH_NI1_LLP_TEST_CTL_SENDCBERROR_MASK     0x0400000000000000
+
+/*   SH_NI1_LLP_TEST_CTL_SENDSNERROR                                    */
+/*   Description:  Sends a single sequence number error                 */
+#define SH_NI1_LLP_TEST_CTL_SENDSNERROR_SHFT     59
+#define SH_NI1_LLP_TEST_CTL_SENDSNERROR_MASK     0x0800000000000000
+
+/*   SH_NI1_LLP_TEST_CTL_FAKESNERROR                                    */
+/*   Description:  Causes receiver to pretend it saw a sn error         */
+#define SH_NI1_LLP_TEST_CTL_FAKESNERROR_SHFT     60
+#define SH_NI1_LLP_TEST_CTL_FAKESNERROR_MASK     0x1000000000000000
+
+/*   SH_NI1_LLP_TEST_CTL_CAPTURED                                       */
+/*   Description:  Indicates a Valid Micropacket was captured           */
+#define SH_NI1_LLP_TEST_CTL_CAPTURED_SHFT        61
+#define SH_NI1_LLP_TEST_CTL_CAPTURED_MASK        0x2000000000000000
+
+/*   SH_NI1_LLP_TEST_CTL_CBERROR                                        */
+/*   Description:  Indicates a Micropacket with a CB error was capture  */
+#define SH_NI1_LLP_TEST_CTL_CBERROR_SHFT         62
+#define SH_NI1_LLP_TEST_CTL_CBERROR_MASK         0x4000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LLP_CAPT_WD1"                    */
+/*                    low order 64-bit captured word                    */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_CAPT_WD1                      0x0000000150002030
+#define SH_NI1_LLP_CAPT_WD1_MASK                 0xffffffffffffffff
+#define SH_NI1_LLP_CAPT_WD1_INIT                 0x0000000000000000
+
+/*   SH_NI1_LLP_CAPT_WD1_DATA                                           */
+/*   Description:  low order 64-bit captured word                       */
+#define SH_NI1_LLP_CAPT_WD1_DATA_SHFT            0
+#define SH_NI1_LLP_CAPT_WD1_DATA_MASK            0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LLP_CAPT_WD2"                    */
+/*                   high order 64-bit captured word                    */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_CAPT_WD2                      0x0000000150002038
+#define SH_NI1_LLP_CAPT_WD2_MASK                 0xffffffffffffffff
+#define SH_NI1_LLP_CAPT_WD2_INIT                 0x0000000000000000
+
+/*   SH_NI1_LLP_CAPT_WD2_DATA                                           */
+/*   Description:  high order 64-bit captured word                      */
+#define SH_NI1_LLP_CAPT_WD2_DATA_SHFT            0
+#define SH_NI1_LLP_CAPT_WD2_DATA_MASK            0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_LLP_CAPT_SBCB"                    */
+/*                 captured sideband, sequence, and CRC                 */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_CAPT_SBCB                     0x0000000150002040
+#define SH_NI1_LLP_CAPT_SBCB_MASK                0x0000001fffffffff
+#define SH_NI1_LLP_CAPT_SBCB_INIT                0x0000000000000000
+
+/*   SH_NI1_LLP_CAPT_SBCB_CAPTUREDRCVSBSN                               */
+/*   Description:  sideband and sequence                                */
+#define SH_NI1_LLP_CAPT_SBCB_CAPTUREDRCVSBSN_SHFT 0
+#define SH_NI1_LLP_CAPT_SBCB_CAPTUREDRCVSBSN_MASK 0x000000000000ffff
+
+/*   SH_NI1_LLP_CAPT_SBCB_CAPTUREDRCVCRC                                */
+/*   Description:  CRC                                                  */
+#define SH_NI1_LLP_CAPT_SBCB_CAPTUREDRCVCRC_SHFT 16
+#define SH_NI1_LLP_CAPT_SBCB_CAPTUREDRCVCRC_MASK 0x00000000ffff0000
+
+/*   SH_NI1_LLP_CAPT_SBCB_SENTALLCBERRORS                               */
+/*   Description:  All CB errors have been sent                         */
+#define SH_NI1_LLP_CAPT_SBCB_SENTALLCBERRORS_SHFT 32
+#define SH_NI1_LLP_CAPT_SBCB_SENTALLCBERRORS_MASK 0x0000000100000000
+
+/*   SH_NI1_LLP_CAPT_SBCB_SENTALLSNERRORS                               */
+/*   Description:  All SN errors have been sent                         */
+#define SH_NI1_LLP_CAPT_SBCB_SENTALLSNERRORS_SHFT 33
+#define SH_NI1_LLP_CAPT_SBCB_SENTALLSNERRORS_MASK 0x0000000200000000
+
+/*   SH_NI1_LLP_CAPT_SBCB_FAKEDALLSNERRORS                              */
+/*   Description:  All faked SN errors have been sent                   */
+#define SH_NI1_LLP_CAPT_SBCB_FAKEDALLSNERRORS_SHFT 34
+#define SH_NI1_LLP_CAPT_SBCB_FAKEDALLSNERRORS_MASK 0x0000000400000000
+
+/*   SH_NI1_LLP_CAPT_SBCB_CHARGEOVERFLOW                                */
+/*   Description:  wire charge counter overflowed, valid if llp_mode e  */
+#define SH_NI1_LLP_CAPT_SBCB_CHARGEOVERFLOW_SHFT 35
+#define SH_NI1_LLP_CAPT_SBCB_CHARGEOVERFLOW_MASK 0x0000000800000000
+
+/*   SH_NI1_LLP_CAPT_SBCB_CHARGEUNDERFLOW                               */
+/*   Description:  wire charge counter underflowed, valid if llp_mode   */
+/*  enabled                                                             */
+#define SH_NI1_LLP_CAPT_SBCB_CHARGEUNDERFLOW_SHFT 36
+#define SH_NI1_LLP_CAPT_SBCB_CHARGEUNDERFLOW_MASK 0x0000001000000000
+
+/* ==================================================================== */
+/*                      Register "SH_NI1_LLP_ERR"                       */
+/* ==================================================================== */
+
+#define SH_NI1_LLP_ERR                           0x0000000150002048
+#define SH_NI1_LLP_ERR_MASK                      0x001fffffffffffff
+#define SH_NI1_LLP_ERR_INIT                      0x0000000000000000
+
+/*   SH_NI1_LLP_ERR_RX_SN_ERR_COUNT                                     */
+/*   Description:  Counts the sequence number errors received           */
+#define SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_SHFT      0
+#define SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK      0x00000000000000ff
+
+/*   SH_NI1_LLP_ERR_RX_CB_ERR_COUNT                                     */
+/*   Description:  Counts the check byte errors received                */
+#define SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_SHFT      8
+#define SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK      0x000000000000ff00
+
+/*   SH_NI1_LLP_ERR_RETRY_COUNT                                         */
+/*   Description:  Counts the retries                                   */
+#define SH_NI1_LLP_ERR_RETRY_COUNT_SHFT          16
+#define SH_NI1_LLP_ERR_RETRY_COUNT_MASK          0x0000000000ff0000
+
+/*   SH_NI1_LLP_ERR_RETRY_TIMEOUT                                       */
+/*   Description:  Indicates a retry timeout has occured                */
+#define SH_NI1_LLP_ERR_RETRY_TIMEOUT_SHFT        24
+#define SH_NI1_LLP_ERR_RETRY_TIMEOUT_MASK        0x0000000001000000
+
+/*   SH_NI1_LLP_ERR_RCV_LINK_RESET                                      */
+/*   Description:  Indicates a link reset has been received             */
+#define SH_NI1_LLP_ERR_RCV_LINK_RESET_SHFT       25
+#define SH_NI1_LLP_ERR_RCV_LINK_RESET_MASK       0x0000000002000000
+
+/*   SH_NI1_LLP_ERR_SQUASH                                              */
+/*   Description:  Indicates a micropacket was squashed                 */
+#define SH_NI1_LLP_ERR_SQUASH_SHFT               26
+#define SH_NI1_LLP_ERR_SQUASH_MASK               0x0000000004000000
+
+/*   SH_NI1_LLP_ERR_POWER_NOT_OK                                        */
+/*   Description:  Detects and traps a loss of power_OK                 */
+#define SH_NI1_LLP_ERR_POWER_NOT_OK_SHFT         27
+#define SH_NI1_LLP_ERR_POWER_NOT_OK_MASK         0x0000000008000000
+
+/*   SH_NI1_LLP_ERR_WIRE_CNT                                            */
+/*   Description:  counts the errors detected on a single wire test     */
+#define SH_NI1_LLP_ERR_WIRE_CNT_SHFT             28
+#define SH_NI1_LLP_ERR_WIRE_CNT_MASK             0x000ffffff0000000
+
+/*   SH_NI1_LLP_ERR_WIRE_OVERFLOW                                       */
+/*   Description:  wire_error_cnt has overflowed                        */
+#define SH_NI1_LLP_ERR_WIRE_OVERFLOW_SHFT        52
+#define SH_NI1_LLP_ERR_WIRE_OVERFLOW_MASK        0x0010000000000000
+
+/* ==================================================================== */
+/*                Register "SH_XNNI0_LLP_TO_FIFO02_FLOW"                */
+/* ==================================================================== */
+
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW              0x0000000150001010
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_MASK         0x3f3f003f3f00bfbf
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_INIT         0x0000000000000000
+
+/*   SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC0_WITHHOLD                     */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC0_FORCE_CRED                   */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC2_WITHHOLD                     */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC2_FORCE_CRED                   */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC0_DYN                         */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC0_CAP                         */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC2_DYN                         */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC2_CAP                         */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNNI0_LLP_TO_FIFO02_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*                Register "SH_XNNI0_LLP_TO_FIFO13_FLOW"                */
+/* ==================================================================== */
+
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW              0x0000000150001020
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_MASK         0x3f3f003f3f00bfbf
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_INIT         0x0000000000000000
+
+/*   SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC0_WITHHOLD                     */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC0_FORCE_CRED                   */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC2_WITHHOLD                     */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC2_FORCE_CRED                   */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC0_DYN                         */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC0_CAP                         */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC2_DYN                         */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC2_CAP                         */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNNI0_LLP_TO_FIFO13_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_LLP_DEBIT_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI0_LLP_DEBIT_FLOW                  0x0000000150001030
+#define SH_XNNI0_LLP_DEBIT_FLOW_MASK             0x1f1f1f1f1f1f1f1f
+#define SH_XNNI0_LLP_DEBIT_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC0_DYN                              */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC0_DYN_SHFT 0
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC0_DYN_MASK 0x000000000000001f
+
+/*   SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC0_CAP                              */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC0_CAP_SHFT 8
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC0_CAP_MASK 0x0000000000001f00
+
+/*   SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC1_DYN                              */
+/*   Description:  vc1 debit dynamic value                              */
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC1_DYN_SHFT 16
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC1_DYN_MASK 0x00000000001f0000
+
+/*   SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC1_CAP                              */
+/*   Description:  vc1 debit captured value                             */
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC1_CAP_SHFT 24
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC1_CAP_MASK 0x000000001f000000
+
+/*   SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC2_DYN                              */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC2_DYN_SHFT 32
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC2_DYN_MASK 0x0000001f00000000
+
+/*   SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC2_CAP                              */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC2_CAP_SHFT 40
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC2_CAP_MASK 0x00001f0000000000
+
+/*   SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC3_DYN                              */
+/*   Description:  vc3 debit dynamic value                              */
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC3_DYN_SHFT 48
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC3_DYN_MASK 0x001f000000000000
+
+/*   SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC3_CAP                              */
+/*   Description:  vc3 debit captured value                             */
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC3_CAP_SHFT 56
+#define SH_XNNI0_LLP_DEBIT_FLOW_DEBIT_VC3_CAP_MASK 0x1f00000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_LINK_0_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI0_LINK_0_FLOW                     0x0000000150001040
+#define SH_XNNI0_LINK_0_FLOW_MASK                0x000000007f7f7fbf
+#define SH_XNNI0_LINK_0_FLOW_INIT                0x0000000000001800
+
+/*   SH_XNNI0_LINK_0_FLOW_DEBIT_VC0_WITHHOLD                            */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI0_LINK_0_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI0_LINK_0_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_LINK_0_FLOW_DEBIT_VC0_FORCE_CRED                          */
+/*   Description:  Force Credit on vc0 from debit cntr                  */
+#define SH_XNNI0_LINK_0_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI0_LINK_0_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_TEST                               */
+/*   Description:  vc0 Limit Test                                       */
+#define SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_TEST_SHFT 8
+#define SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_TEST_MASK 0x0000000000007f00
+
+/*   SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_DYN                                */
+/*   Description:  Dynamic vc0 credit value                             */
+#define SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_DYN_SHFT 16
+#define SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_DYN_MASK 0x00000000007f0000
+
+/*   SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_CAP                                */
+/*   Description:  Captured vc0 credit                                  */
+#define SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_CAP_SHFT 24
+#define SH_XNNI0_LINK_0_FLOW_CREDIT_VC0_CAP_MASK 0x000000007f000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_LINK_1_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI0_LINK_1_FLOW                     0x0000000150001050
+#define SH_XNNI0_LINK_1_FLOW_MASK                0x000000007f7f7fbf
+#define SH_XNNI0_LINK_1_FLOW_INIT                0x0000000000001800
+
+/*   SH_XNNI0_LINK_1_FLOW_DEBIT_VC1_WITHHOLD                            */
+/*   Description:  vc1 withhold                                         */
+#define SH_XNNI0_LINK_1_FLOW_DEBIT_VC1_WITHHOLD_SHFT 0
+#define SH_XNNI0_LINK_1_FLOW_DEBIT_VC1_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_LINK_1_FLOW_DEBIT_VC1_FORCE_CRED                          */
+/*   Description:  Force Credit on vc1 from debit cntr                  */
+#define SH_XNNI0_LINK_1_FLOW_DEBIT_VC1_FORCE_CRED_SHFT 7
+#define SH_XNNI0_LINK_1_FLOW_DEBIT_VC1_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_TEST                               */
+/*   Description:  vc1 Limit Test                                       */
+#define SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_TEST_SHFT 8
+#define SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_TEST_MASK 0x0000000000007f00
+
+/*   SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_DYN                                */
+/*   Description:  Dynamic vc1 credit value                             */
+#define SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_DYN_SHFT 16
+#define SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_DYN_MASK 0x00000000007f0000
+
+/*   SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_CAP                                */
+/*   Description:  Captured vc1 credit                                  */
+#define SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_CAP_SHFT 24
+#define SH_XNNI0_LINK_1_FLOW_CREDIT_VC1_CAP_MASK 0x000000007f000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_LINK_2_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI0_LINK_2_FLOW                     0x0000000150001060
+#define SH_XNNI0_LINK_2_FLOW_MASK                0x000000007f7f7fbf
+#define SH_XNNI0_LINK_2_FLOW_INIT                0x0000000000001800
+
+/*   SH_XNNI0_LINK_2_FLOW_DEBIT_VC2_WITHHOLD                            */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI0_LINK_2_FLOW_DEBIT_VC2_WITHHOLD_SHFT 0
+#define SH_XNNI0_LINK_2_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_LINK_2_FLOW_DEBIT_VC2_FORCE_CRED                          */
+/*   Description:  Force Credit on vc2 from debit cntr                  */
+#define SH_XNNI0_LINK_2_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 7
+#define SH_XNNI0_LINK_2_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_TEST                               */
+/*   Description:  vc2 Limit Test                                       */
+#define SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_TEST_SHFT 8
+#define SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_TEST_MASK 0x0000000000007f00
+
+/*   SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_DYN                                */
+/*   Description:  Dynamic vc2 credit value                             */
+#define SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_DYN_SHFT 16
+#define SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_DYN_MASK 0x00000000007f0000
+
+/*   SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_CAP                                */
+/*   Description:  Captured vc2 credit                                  */
+#define SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_CAP_SHFT 24
+#define SH_XNNI0_LINK_2_FLOW_CREDIT_VC2_CAP_MASK 0x000000007f000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_LINK_3_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI0_LINK_3_FLOW                     0x0000000150001070
+#define SH_XNNI0_LINK_3_FLOW_MASK                0x000000007f7f7fbf
+#define SH_XNNI0_LINK_3_FLOW_INIT                0x0000000000001800
+
+/*   SH_XNNI0_LINK_3_FLOW_DEBIT_VC3_WITHHOLD                            */
+/*   Description:  vc3 withhold                                         */
+#define SH_XNNI0_LINK_3_FLOW_DEBIT_VC3_WITHHOLD_SHFT 0
+#define SH_XNNI0_LINK_3_FLOW_DEBIT_VC3_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_LINK_3_FLOW_DEBIT_VC3_FORCE_CRED                          */
+/*   Description:  Force Credit on vc3 from debit cntr                  */
+#define SH_XNNI0_LINK_3_FLOW_DEBIT_VC3_FORCE_CRED_SHFT 7
+#define SH_XNNI0_LINK_3_FLOW_DEBIT_VC3_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_TEST                               */
+/*   Description:  vc3 Limit Test                                       */
+#define SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_TEST_SHFT 8
+#define SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_TEST_MASK 0x0000000000007f00
+
+/*   SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_DYN                                */
+/*   Description:  Dynamic vc3 credit value                             */
+#define SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_DYN_SHFT 16
+#define SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_DYN_MASK 0x00000000007f0000
+
+/*   SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_CAP                                */
+/*   Description:  Captured vc3 credit                                  */
+#define SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_CAP_SHFT 24
+#define SH_XNNI0_LINK_3_FLOW_CREDIT_VC3_CAP_MASK 0x000000007f000000
+
+/* ==================================================================== */
+/*                Register "SH_XNNI1_LLP_TO_FIFO02_FLOW"                */
+/* ==================================================================== */
+
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW              0x0000000150003010
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_MASK         0x3f3f003f3f00bfbf
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_INIT         0x0000000000000000
+
+/*   SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC0_WITHHOLD                     */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC0_FORCE_CRED                   */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC2_WITHHOLD                     */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC2_FORCE_CRED                   */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC0_DYN                         */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC0_CAP                         */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC2_DYN                         */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC2_CAP                         */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNNI1_LLP_TO_FIFO02_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*                Register "SH_XNNI1_LLP_TO_FIFO13_FLOW"                */
+/* ==================================================================== */
+
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW              0x0000000150003020
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_MASK         0x3f3f003f3f00bfbf
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_INIT         0x0000000000000000
+
+/*   SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC0_WITHHOLD                     */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC0_FORCE_CRED                   */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC2_WITHHOLD                     */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC2_FORCE_CRED                   */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC0_DYN                         */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC0_CAP                         */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC2_DYN                         */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC2_CAP                         */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNNI1_LLP_TO_FIFO13_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_LLP_DEBIT_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI1_LLP_DEBIT_FLOW                  0x0000000150003030
+#define SH_XNNI1_LLP_DEBIT_FLOW_MASK             0x1f1f1f1f1f1f1f1f
+#define SH_XNNI1_LLP_DEBIT_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC0_DYN                              */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC0_DYN_SHFT 0
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC0_DYN_MASK 0x000000000000001f
+
+/*   SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC0_CAP                              */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC0_CAP_SHFT 8
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC0_CAP_MASK 0x0000000000001f00
+
+/*   SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC1_DYN                              */
+/*   Description:  vc1 debit dynamic value                              */
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC1_DYN_SHFT 16
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC1_DYN_MASK 0x00000000001f0000
+
+/*   SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC1_CAP                              */
+/*   Description:  vc1 debit captured value                             */
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC1_CAP_SHFT 24
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC1_CAP_MASK 0x000000001f000000
+
+/*   SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC2_DYN                              */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC2_DYN_SHFT 32
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC2_DYN_MASK 0x0000001f00000000
+
+/*   SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC2_CAP                              */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC2_CAP_SHFT 40
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC2_CAP_MASK 0x00001f0000000000
+
+/*   SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC3_DYN                              */
+/*   Description:  vc3 debit dynamic value                              */
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC3_DYN_SHFT 48
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC3_DYN_MASK 0x001f000000000000
+
+/*   SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC3_CAP                              */
+/*   Description:  vc3 debit captured value                             */
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC3_CAP_SHFT 56
+#define SH_XNNI1_LLP_DEBIT_FLOW_DEBIT_VC3_CAP_MASK 0x1f00000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_LINK_0_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI1_LINK_0_FLOW                     0x0000000150003040
+#define SH_XNNI1_LINK_0_FLOW_MASK                0x000000007f7f7fbf
+#define SH_XNNI1_LINK_0_FLOW_INIT                0x0000000000001800
+
+/*   SH_XNNI1_LINK_0_FLOW_DEBIT_VC0_WITHHOLD                            */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI1_LINK_0_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI1_LINK_0_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_LINK_0_FLOW_DEBIT_VC0_FORCE_CRED                          */
+/*   Description:  Force Credit on vc0 from debit cntr                  */
+#define SH_XNNI1_LINK_0_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI1_LINK_0_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_TEST                               */
+/*   Description:  vc0 Limit Test                                       */
+#define SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_TEST_SHFT 8
+#define SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_TEST_MASK 0x0000000000007f00
+
+/*   SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_DYN                                */
+/*   Description:  Dynamic vc0 credit value                             */
+#define SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_DYN_SHFT 16
+#define SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_DYN_MASK 0x00000000007f0000
+
+/*   SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_CAP                                */
+/*   Description:  Captured vc0 credit                                  */
+#define SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_CAP_SHFT 24
+#define SH_XNNI1_LINK_0_FLOW_CREDIT_VC0_CAP_MASK 0x000000007f000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_LINK_1_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI1_LINK_1_FLOW                     0x0000000150003050
+#define SH_XNNI1_LINK_1_FLOW_MASK                0x000000007f7f7fbf
+#define SH_XNNI1_LINK_1_FLOW_INIT                0x0000000000001800
+
+/*   SH_XNNI1_LINK_1_FLOW_DEBIT_VC1_WITHHOLD                            */
+/*   Description:  vc1 withhold                                         */
+#define SH_XNNI1_LINK_1_FLOW_DEBIT_VC1_WITHHOLD_SHFT 0
+#define SH_XNNI1_LINK_1_FLOW_DEBIT_VC1_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_LINK_1_FLOW_DEBIT_VC1_FORCE_CRED                          */
+/*   Description:  Force Credit on vc1 from debit cntr                  */
+#define SH_XNNI1_LINK_1_FLOW_DEBIT_VC1_FORCE_CRED_SHFT 7
+#define SH_XNNI1_LINK_1_FLOW_DEBIT_VC1_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_TEST                               */
+/*   Description:  vc1 Limit Test                                       */
+#define SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_TEST_SHFT 8
+#define SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_TEST_MASK 0x0000000000007f00
+
+/*   SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_DYN                                */
+/*   Description:  Dynamic vc1 credit value                             */
+#define SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_DYN_SHFT 16
+#define SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_DYN_MASK 0x00000000007f0000
+
+/*   SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_CAP                                */
+/*   Description:  Captured vc1 credit                                  */
+#define SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_CAP_SHFT 24
+#define SH_XNNI1_LINK_1_FLOW_CREDIT_VC1_CAP_MASK 0x000000007f000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_LINK_2_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI1_LINK_2_FLOW                     0x0000000150003060
+#define SH_XNNI1_LINK_2_FLOW_MASK                0x000000007f7f7fbf
+#define SH_XNNI1_LINK_2_FLOW_INIT                0x0000000000001800
+
+/*   SH_XNNI1_LINK_2_FLOW_DEBIT_VC2_WITHHOLD                            */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI1_LINK_2_FLOW_DEBIT_VC2_WITHHOLD_SHFT 0
+#define SH_XNNI1_LINK_2_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_LINK_2_FLOW_DEBIT_VC2_FORCE_CRED                          */
+/*   Description:  Force Credit on vc2 from debit cntr                  */
+#define SH_XNNI1_LINK_2_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 7
+#define SH_XNNI1_LINK_2_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_TEST                               */
+/*   Description:  vc2 Limit Test                                       */
+#define SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_TEST_SHFT 8
+#define SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_TEST_MASK 0x0000000000007f00
+
+/*   SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_DYN                                */
+/*   Description:  Dynamic vc2 credit value                             */
+#define SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_DYN_SHFT 16
+#define SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_DYN_MASK 0x00000000007f0000
+
+/*   SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_CAP                                */
+/*   Description:  Captured vc2 credit                                  */
+#define SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_CAP_SHFT 24
+#define SH_XNNI1_LINK_2_FLOW_CREDIT_VC2_CAP_MASK 0x000000007f000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_LINK_3_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI1_LINK_3_FLOW                     0x0000000150003070
+#define SH_XNNI1_LINK_3_FLOW_MASK                0x000000007f7f7fbf
+#define SH_XNNI1_LINK_3_FLOW_INIT                0x0000000000001800
+
+/*   SH_XNNI1_LINK_3_FLOW_DEBIT_VC3_WITHHOLD                            */
+/*   Description:  vc3 withhold                                         */
+#define SH_XNNI1_LINK_3_FLOW_DEBIT_VC3_WITHHOLD_SHFT 0
+#define SH_XNNI1_LINK_3_FLOW_DEBIT_VC3_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_LINK_3_FLOW_DEBIT_VC3_FORCE_CRED                          */
+/*   Description:  Force Credit on vc3 from debit cntr                  */
+#define SH_XNNI1_LINK_3_FLOW_DEBIT_VC3_FORCE_CRED_SHFT 7
+#define SH_XNNI1_LINK_3_FLOW_DEBIT_VC3_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_TEST                               */
+/*   Description:  vc3 Limit Test                                       */
+#define SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_TEST_SHFT 8
+#define SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_TEST_MASK 0x0000000000007f00
+
+/*   SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_DYN                                */
+/*   Description:  Dynamic vc3 credit value                             */
+#define SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_DYN_SHFT 16
+#define SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_DYN_MASK 0x00000000007f0000
+
+/*   SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_CAP                                */
+/*   Description:  Captured vc3 credit                                  */
+#define SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_CAP_SHFT 24
+#define SH_XNNI1_LINK_3_FLOW_CREDIT_VC3_CAP_MASK 0x000000007f000000
+
+/* ==================================================================== */
+/*                    Register "SH_IILB_LOCAL_TABLE"                    */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#define SH_IILB_LOCAL_TABLE                      0x0000000150020000
+#define SH_IILB_LOCAL_TABLE_MASK                 0x800000000000003f
+#define SH_IILB_LOCAL_TABLE_MEMDEPTH             128
+#define SH_IILB_LOCAL_TABLE_INIT                 0x0000000000000000
+
+/*   SH_IILB_LOCAL_TABLE_DIR0                                           */
+/*   Description:  Direction field for next chip                        */
+#define SH_IILB_LOCAL_TABLE_DIR0_SHFT            0
+#define SH_IILB_LOCAL_TABLE_DIR0_MASK            0x000000000000000f
+
+/*   SH_IILB_LOCAL_TABLE_V0                                             */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_IILB_LOCAL_TABLE_V0_SHFT              4
+#define SH_IILB_LOCAL_TABLE_V0_MASK              0x0000000000000010
+
+/*   SH_IILB_LOCAL_TABLE_NI_SEL0                                        */
+/*   Description:  ni select for requests                               */
+#define SH_IILB_LOCAL_TABLE_NI_SEL0_SHFT         5
+#define SH_IILB_LOCAL_TABLE_NI_SEL0_MASK         0x0000000000000020
+
+/*   SH_IILB_LOCAL_TABLE_VALID                                          */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_IILB_LOCAL_TABLE_VALID_SHFT           63
+#define SH_IILB_LOCAL_TABLE_VALID_MASK           0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_IILB_GLOBAL_TABLE"                    */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#define SH_IILB_GLOBAL_TABLE                     0x0000000150020400
+#define SH_IILB_GLOBAL_TABLE_MASK                0x800000000000003f
+#define SH_IILB_GLOBAL_TABLE_MEMDEPTH            16
+#define SH_IILB_GLOBAL_TABLE_INIT                0x0000000000000000
+
+/*   SH_IILB_GLOBAL_TABLE_DIR0                                          */
+/*   Description:  Direction field for next chip                        */
+#define SH_IILB_GLOBAL_TABLE_DIR0_SHFT           0
+#define SH_IILB_GLOBAL_TABLE_DIR0_MASK           0x000000000000000f
+
+/*   SH_IILB_GLOBAL_TABLE_V0                                            */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_IILB_GLOBAL_TABLE_V0_SHFT             4
+#define SH_IILB_GLOBAL_TABLE_V0_MASK             0x0000000000000010
+
+/*   SH_IILB_GLOBAL_TABLE_NI_SEL0                                       */
+/*   Description:  ni select for requests                               */
+#define SH_IILB_GLOBAL_TABLE_NI_SEL0_SHFT        5
+#define SH_IILB_GLOBAL_TABLE_NI_SEL0_MASK        0x0000000000000020
+
+/*   SH_IILB_GLOBAL_TABLE_VALID                                         */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_IILB_GLOBAL_TABLE_VALID_SHFT          63
+#define SH_IILB_GLOBAL_TABLE_VALID_MASK          0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_IILB_OVER_RIDE_TABLE"                  */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#define SH_IILB_OVER_RIDE_TABLE                  0x0000000150020480
+#define SH_IILB_OVER_RIDE_TABLE_MASK             0x800000000000003f
+#define SH_IILB_OVER_RIDE_TABLE_INIT             0x8000000000000000
+
+/*   SH_IILB_OVER_RIDE_TABLE_DIR0                                       */
+/*   Description:  Direction field for next chip                        */
+#define SH_IILB_OVER_RIDE_TABLE_DIR0_SHFT        0
+#define SH_IILB_OVER_RIDE_TABLE_DIR0_MASK        0x000000000000000f
+
+/*   SH_IILB_OVER_RIDE_TABLE_V0                                         */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_IILB_OVER_RIDE_TABLE_V0_SHFT          4
+#define SH_IILB_OVER_RIDE_TABLE_V0_MASK          0x0000000000000010
+
+/*   SH_IILB_OVER_RIDE_TABLE_NI_SEL0                                    */
+/*   Description:  ni select                                            */
+#define SH_IILB_OVER_RIDE_TABLE_NI_SEL0_SHFT     5
+#define SH_IILB_OVER_RIDE_TABLE_NI_SEL0_MASK     0x0000000000000020
+
+/*   SH_IILB_OVER_RIDE_TABLE_ENABLE                                     */
+/*   Description:  Indicates that this entry is enabled                 */
+#define SH_IILB_OVER_RIDE_TABLE_ENABLE_SHFT      63
+#define SH_IILB_OVER_RIDE_TABLE_ENABLE_MASK      0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_IILB_RSP_PLANE_HINT"                   */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#define SH_IILB_RSP_PLANE_HINT                   0x0000000150020488
+#define SH_IILB_RSP_PLANE_HINT_MASK              0x0000000000000000
+#define SH_IILB_RSP_PLANE_HINT_INIT              0x0000000000000000
+
+/* ==================================================================== */
+/*                     Register "SH_PI_LOCAL_TABLE"                     */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#define SH_PI_LOCAL_TABLE                        0x0000000150021000
+#define SH_PI_LOCAL_TABLE_MASK                   0x8000000000003f3f
+#define SH_PI_LOCAL_TABLE_MEMDEPTH               128
+#define SH_PI_LOCAL_TABLE_INIT                   0x0000000000000000
+
+/*   SH_PI_LOCAL_TABLE_DIR0                                             */
+/*   Description:  Direction field for next chip                        */
+#define SH_PI_LOCAL_TABLE_DIR0_SHFT              0
+#define SH_PI_LOCAL_TABLE_DIR0_MASK              0x000000000000000f
+
+/*   SH_PI_LOCAL_TABLE_V0                                               */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_PI_LOCAL_TABLE_V0_SHFT                4
+#define SH_PI_LOCAL_TABLE_V0_MASK                0x0000000000000010
+
+/*   SH_PI_LOCAL_TABLE_NI_SEL0                                          */
+/*   Description:  ni select for requests                               */
+#define SH_PI_LOCAL_TABLE_NI_SEL0_SHFT           5
+#define SH_PI_LOCAL_TABLE_NI_SEL0_MASK           0x0000000000000020
+
+/*   SH_PI_LOCAL_TABLE_DIR1                                             */
+#define SH_PI_LOCAL_TABLE_DIR1_SHFT              8
+#define SH_PI_LOCAL_TABLE_DIR1_MASK              0x0000000000000f00
+
+/*   SH_PI_LOCAL_TABLE_V1                                               */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_PI_LOCAL_TABLE_V1_SHFT                12
+#define SH_PI_LOCAL_TABLE_V1_MASK                0x0000000000001000
+
+/*   SH_PI_LOCAL_TABLE_NI_SEL1                                          */
+/*   Description:  ni select for plane-hint 1                           */
+#define SH_PI_LOCAL_TABLE_NI_SEL1_SHFT           13
+#define SH_PI_LOCAL_TABLE_NI_SEL1_MASK           0x0000000000002000
+
+/*   SH_PI_LOCAL_TABLE_VALID                                            */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_PI_LOCAL_TABLE_VALID_SHFT             63
+#define SH_PI_LOCAL_TABLE_VALID_MASK             0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_PI_GLOBAL_TABLE"                     */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#define SH_PI_GLOBAL_TABLE                       0x0000000150021400
+#define SH_PI_GLOBAL_TABLE_MASK                  0x8000000000003f3f
+#define SH_PI_GLOBAL_TABLE_MEMDEPTH              16
+#define SH_PI_GLOBAL_TABLE_INIT                  0x0000000000000000
+
+/*   SH_PI_GLOBAL_TABLE_DIR0                                            */
+/*   Description:  Direction field for next chip                        */
+#define SH_PI_GLOBAL_TABLE_DIR0_SHFT             0
+#define SH_PI_GLOBAL_TABLE_DIR0_MASK             0x000000000000000f
+
+/*   SH_PI_GLOBAL_TABLE_V0                                              */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_PI_GLOBAL_TABLE_V0_SHFT               4
+#define SH_PI_GLOBAL_TABLE_V0_MASK               0x0000000000000010
+
+/*   SH_PI_GLOBAL_TABLE_NI_SEL0                                         */
+/*   Description:  ni select for requests                               */
+#define SH_PI_GLOBAL_TABLE_NI_SEL0_SHFT          5
+#define SH_PI_GLOBAL_TABLE_NI_SEL0_MASK          0x0000000000000020
+
+/*   SH_PI_GLOBAL_TABLE_DIR1                                            */
+#define SH_PI_GLOBAL_TABLE_DIR1_SHFT             8
+#define SH_PI_GLOBAL_TABLE_DIR1_MASK             0x0000000000000f00
+
+/*   SH_PI_GLOBAL_TABLE_V1                                              */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_PI_GLOBAL_TABLE_V1_SHFT               12
+#define SH_PI_GLOBAL_TABLE_V1_MASK               0x0000000000001000
+
+/*   SH_PI_GLOBAL_TABLE_NI_SEL1                                         */
+/*   Description:  ni select for plane-hint 1                           */
+#define SH_PI_GLOBAL_TABLE_NI_SEL1_SHFT          13
+#define SH_PI_GLOBAL_TABLE_NI_SEL1_MASK          0x0000000000002000
+
+/*   SH_PI_GLOBAL_TABLE_VALID                                           */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_PI_GLOBAL_TABLE_VALID_SHFT            63
+#define SH_PI_GLOBAL_TABLE_VALID_MASK            0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_PI_OVER_RIDE_TABLE"                   */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#define SH_PI_OVER_RIDE_TABLE                    0x0000000150021480
+#define SH_PI_OVER_RIDE_TABLE_MASK               0x8000000000003f3f
+#define SH_PI_OVER_RIDE_TABLE_INIT               0x8000000000002000
+
+/*   SH_PI_OVER_RIDE_TABLE_DIR0                                         */
+/*   Description:  Direction field for next chip                        */
+#define SH_PI_OVER_RIDE_TABLE_DIR0_SHFT          0
+#define SH_PI_OVER_RIDE_TABLE_DIR0_MASK          0x000000000000000f
+
+/*   SH_PI_OVER_RIDE_TABLE_V0                                           */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_PI_OVER_RIDE_TABLE_V0_SHFT            4
+#define SH_PI_OVER_RIDE_TABLE_V0_MASK            0x0000000000000010
+
+/*   SH_PI_OVER_RIDE_TABLE_NI_SEL0                                      */
+/*   Description:  ni select                                            */
+#define SH_PI_OVER_RIDE_TABLE_NI_SEL0_SHFT       5
+#define SH_PI_OVER_RIDE_TABLE_NI_SEL0_MASK       0x0000000000000020
+
+/*   SH_PI_OVER_RIDE_TABLE_DIR1                                         */
+#define SH_PI_OVER_RIDE_TABLE_DIR1_SHFT          8
+#define SH_PI_OVER_RIDE_TABLE_DIR1_MASK          0x0000000000000f00
+
+/*   SH_PI_OVER_RIDE_TABLE_V1                                           */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_PI_OVER_RIDE_TABLE_V1_SHFT            12
+#define SH_PI_OVER_RIDE_TABLE_V1_MASK            0x0000000000001000
+
+/*   SH_PI_OVER_RIDE_TABLE_NI_SEL1                                      */
+/*   Description:  ni select                                            */
+#define SH_PI_OVER_RIDE_TABLE_NI_SEL1_SHFT       13
+#define SH_PI_OVER_RIDE_TABLE_NI_SEL1_MASK       0x0000000000002000
+
+/*   SH_PI_OVER_RIDE_TABLE_ENABLE                                       */
+/*   Description:  Indicates that this entry is enabled                 */
+#define SH_PI_OVER_RIDE_TABLE_ENABLE_SHFT        63
+#define SH_PI_OVER_RIDE_TABLE_ENABLE_MASK        0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_PI_RSP_PLANE_HINT"                    */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#define SH_PI_RSP_PLANE_HINT                     0x0000000150021488
+#define SH_PI_RSP_PLANE_HINT_MASK                0x0000000000000001
+#define SH_PI_RSP_PLANE_HINT_INIT                0x0000000000000000
+
+/*   SH_PI_RSP_PLANE_HINT_INVERT                                        */
+/*   Description:  Invert Response Plane Hint                           */
+#define SH_PI_RSP_PLANE_HINT_INVERT_SHFT         0
+#define SH_PI_RSP_PLANE_HINT_INVERT_MASK         0x0000000000000001
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LOCAL_TABLE"                     */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#define SH_NI0_LOCAL_TABLE                       0x0000000150022000
+#define SH_NI0_LOCAL_TABLE_MASK                  0x800000000000001f
+#define SH_NI0_LOCAL_TABLE_MEMDEPTH              128
+#define SH_NI0_LOCAL_TABLE_INIT                  0x0000000000000000
+
+/*   SH_NI0_LOCAL_TABLE_DIR0                                            */
+/*   Description:  Direction field for next chip                        */
+#define SH_NI0_LOCAL_TABLE_DIR0_SHFT             0
+#define SH_NI0_LOCAL_TABLE_DIR0_MASK             0x000000000000000f
+
+/*   SH_NI0_LOCAL_TABLE_V0                                              */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_NI0_LOCAL_TABLE_V0_SHFT               4
+#define SH_NI0_LOCAL_TABLE_V0_MASK               0x0000000000000010
+
+/*   SH_NI0_LOCAL_TABLE_VALID                                           */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_NI0_LOCAL_TABLE_VALID_SHFT            63
+#define SH_NI0_LOCAL_TABLE_VALID_MASK            0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_GLOBAL_TABLE"                    */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#define SH_NI0_GLOBAL_TABLE                      0x0000000150022400
+#define SH_NI0_GLOBAL_TABLE_MASK                 0x800000000000001f
+#define SH_NI0_GLOBAL_TABLE_MEMDEPTH             16
+#define SH_NI0_GLOBAL_TABLE_INIT                 0x0000000000000000
+
+/*   SH_NI0_GLOBAL_TABLE_DIR0                                           */
+/*   Description:  Direction field for next chip                        */
+#define SH_NI0_GLOBAL_TABLE_DIR0_SHFT            0
+#define SH_NI0_GLOBAL_TABLE_DIR0_MASK            0x000000000000000f
+
+/*   SH_NI0_GLOBAL_TABLE_V0                                             */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_NI0_GLOBAL_TABLE_V0_SHFT              4
+#define SH_NI0_GLOBAL_TABLE_V0_MASK              0x0000000000000010
+
+/*   SH_NI0_GLOBAL_TABLE_VALID                                          */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_NI0_GLOBAL_TABLE_VALID_SHFT           63
+#define SH_NI0_GLOBAL_TABLE_VALID_MASK           0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_OVER_RIDE_TABLE"                   */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#define SH_NI0_OVER_RIDE_TABLE                   0x0000000150022480
+#define SH_NI0_OVER_RIDE_TABLE_MASK              0x800000000000001f
+#define SH_NI0_OVER_RIDE_TABLE_INIT              0x8000000000000000
+
+/*   SH_NI0_OVER_RIDE_TABLE_DIR0                                        */
+/*   Description:  Direction field for next chip                        */
+#define SH_NI0_OVER_RIDE_TABLE_DIR0_SHFT         0
+#define SH_NI0_OVER_RIDE_TABLE_DIR0_MASK         0x000000000000000f
+
+/*   SH_NI0_OVER_RIDE_TABLE_V0                                          */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_NI0_OVER_RIDE_TABLE_V0_SHFT           4
+#define SH_NI0_OVER_RIDE_TABLE_V0_MASK           0x0000000000000010
+
+/*   SH_NI0_OVER_RIDE_TABLE_ENABLE                                      */
+/*   Description:  Indicates that this entry is enabled                 */
+#define SH_NI0_OVER_RIDE_TABLE_ENABLE_SHFT       63
+#define SH_NI0_OVER_RIDE_TABLE_ENABLE_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_RSP_PLANE_HINT"                   */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#define SH_NI0_RSP_PLANE_HINT                    0x0000000150022488
+#define SH_NI0_RSP_PLANE_HINT_MASK               0x0000000000000000
+#define SH_NI0_RSP_PLANE_HINT_INIT               0x0000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LOCAL_TABLE"                     */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#define SH_NI1_LOCAL_TABLE                       0x0000000150023000
+#define SH_NI1_LOCAL_TABLE_MASK                  0x800000000000001f
+#define SH_NI1_LOCAL_TABLE_MEMDEPTH              128
+#define SH_NI1_LOCAL_TABLE_INIT                  0x0000000000000000
+
+/*   SH_NI1_LOCAL_TABLE_DIR0                                            */
+/*   Description:  Direction field for next chip                        */
+#define SH_NI1_LOCAL_TABLE_DIR0_SHFT             0
+#define SH_NI1_LOCAL_TABLE_DIR0_MASK             0x000000000000000f
+
+/*   SH_NI1_LOCAL_TABLE_V0                                              */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_NI1_LOCAL_TABLE_V0_SHFT               4
+#define SH_NI1_LOCAL_TABLE_V0_MASK               0x0000000000000010
+
+/*   SH_NI1_LOCAL_TABLE_VALID                                           */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_NI1_LOCAL_TABLE_VALID_SHFT            63
+#define SH_NI1_LOCAL_TABLE_VALID_MASK            0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_GLOBAL_TABLE"                    */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#define SH_NI1_GLOBAL_TABLE                      0x0000000150023400
+#define SH_NI1_GLOBAL_TABLE_MASK                 0x800000000000001f
+#define SH_NI1_GLOBAL_TABLE_MEMDEPTH             16
+#define SH_NI1_GLOBAL_TABLE_INIT                 0x0000000000000000
+
+/*   SH_NI1_GLOBAL_TABLE_DIR0                                           */
+/*   Description:  Direction field for next chip                        */
+#define SH_NI1_GLOBAL_TABLE_DIR0_SHFT            0
+#define SH_NI1_GLOBAL_TABLE_DIR0_MASK            0x000000000000000f
+
+/*   SH_NI1_GLOBAL_TABLE_V0                                             */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_NI1_GLOBAL_TABLE_V0_SHFT              4
+#define SH_NI1_GLOBAL_TABLE_V0_MASK              0x0000000000000010
+
+/*   SH_NI1_GLOBAL_TABLE_VALID                                          */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_NI1_GLOBAL_TABLE_VALID_SHFT           63
+#define SH_NI1_GLOBAL_TABLE_VALID_MASK           0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_OVER_RIDE_TABLE"                   */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#define SH_NI1_OVER_RIDE_TABLE                   0x0000000150023480
+#define SH_NI1_OVER_RIDE_TABLE_MASK              0x800000000000001f
+#define SH_NI1_OVER_RIDE_TABLE_INIT              0x8000000000000000
+
+/*   SH_NI1_OVER_RIDE_TABLE_DIR0                                        */
+/*   Description:  Direction field for next chip                        */
+#define SH_NI1_OVER_RIDE_TABLE_DIR0_SHFT         0
+#define SH_NI1_OVER_RIDE_TABLE_DIR0_MASK         0x000000000000000f
+
+/*   SH_NI1_OVER_RIDE_TABLE_V0                                          */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_NI1_OVER_RIDE_TABLE_V0_SHFT           4
+#define SH_NI1_OVER_RIDE_TABLE_V0_MASK           0x0000000000000010
+
+/*   SH_NI1_OVER_RIDE_TABLE_ENABLE                                      */
+/*   Description:  Indicates that this entry is enabled                 */
+#define SH_NI1_OVER_RIDE_TABLE_ENABLE_SHFT       63
+#define SH_NI1_OVER_RIDE_TABLE_ENABLE_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_RSP_PLANE_HINT"                   */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#define SH_NI1_RSP_PLANE_HINT                    0x0000000150023488
+#define SH_NI1_RSP_PLANE_HINT_MASK               0x0000000000000000
+#define SH_NI1_RSP_PLANE_HINT_INIT               0x0000000000000000
+
+/* ==================================================================== */
+/*                     Register "SH_MD_LOCAL_TABLE"                     */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#define SH_MD_LOCAL_TABLE                        0x0000000150024000
+#define SH_MD_LOCAL_TABLE_MASK                   0x8000000000003f3f
+#define SH_MD_LOCAL_TABLE_MEMDEPTH               128
+#define SH_MD_LOCAL_TABLE_INIT                   0x0000000000000000
+
+/*   SH_MD_LOCAL_TABLE_DIR0                                             */
+/*   Description:  Direction field for next chip                        */
+#define SH_MD_LOCAL_TABLE_DIR0_SHFT              0
+#define SH_MD_LOCAL_TABLE_DIR0_MASK              0x000000000000000f
+
+/*   SH_MD_LOCAL_TABLE_V0                                               */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_MD_LOCAL_TABLE_V0_SHFT                4
+#define SH_MD_LOCAL_TABLE_V0_MASK                0x0000000000000010
+
+/*   SH_MD_LOCAL_TABLE_NI_SEL0                                          */
+/*   Description:  ni select for requests                               */
+#define SH_MD_LOCAL_TABLE_NI_SEL0_SHFT           5
+#define SH_MD_LOCAL_TABLE_NI_SEL0_MASK           0x0000000000000020
+
+/*   SH_MD_LOCAL_TABLE_DIR1                                             */
+#define SH_MD_LOCAL_TABLE_DIR1_SHFT              8
+#define SH_MD_LOCAL_TABLE_DIR1_MASK              0x0000000000000f00
+
+/*   SH_MD_LOCAL_TABLE_V1                                               */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_MD_LOCAL_TABLE_V1_SHFT                12
+#define SH_MD_LOCAL_TABLE_V1_MASK                0x0000000000001000
+
+/*   SH_MD_LOCAL_TABLE_NI_SEL1                                          */
+/*   Description:  ni select for plane-hint 1                           */
+#define SH_MD_LOCAL_TABLE_NI_SEL1_SHFT           13
+#define SH_MD_LOCAL_TABLE_NI_SEL1_MASK           0x0000000000002000
+
+/*   SH_MD_LOCAL_TABLE_VALID                                            */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_MD_LOCAL_TABLE_VALID_SHFT             63
+#define SH_MD_LOCAL_TABLE_VALID_MASK             0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_MD_GLOBAL_TABLE"                     */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#define SH_MD_GLOBAL_TABLE                       0x0000000150024400
+#define SH_MD_GLOBAL_TABLE_MASK                  0x8000000000003f3f
+#define SH_MD_GLOBAL_TABLE_MEMDEPTH              16
+#define SH_MD_GLOBAL_TABLE_INIT                  0x0000000000000000
+
+/*   SH_MD_GLOBAL_TABLE_DIR0                                            */
+/*   Description:  Direction field for next chip                        */
+#define SH_MD_GLOBAL_TABLE_DIR0_SHFT             0
+#define SH_MD_GLOBAL_TABLE_DIR0_MASK             0x000000000000000f
+
+/*   SH_MD_GLOBAL_TABLE_V0                                              */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_MD_GLOBAL_TABLE_V0_SHFT               4
+#define SH_MD_GLOBAL_TABLE_V0_MASK               0x0000000000000010
+
+/*   SH_MD_GLOBAL_TABLE_NI_SEL0                                         */
+/*   Description:  ni select for requests                               */
+#define SH_MD_GLOBAL_TABLE_NI_SEL0_SHFT          5
+#define SH_MD_GLOBAL_TABLE_NI_SEL0_MASK          0x0000000000000020
+
+/*   SH_MD_GLOBAL_TABLE_DIR1                                            */
+#define SH_MD_GLOBAL_TABLE_DIR1_SHFT             8
+#define SH_MD_GLOBAL_TABLE_DIR1_MASK             0x0000000000000f00
+
+/*   SH_MD_GLOBAL_TABLE_V1                                              */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_MD_GLOBAL_TABLE_V1_SHFT               12
+#define SH_MD_GLOBAL_TABLE_V1_MASK               0x0000000000001000
+
+/*   SH_MD_GLOBAL_TABLE_NI_SEL1                                         */
+/*   Description:  ni select for plane-hint 1                           */
+#define SH_MD_GLOBAL_TABLE_NI_SEL1_SHFT          13
+#define SH_MD_GLOBAL_TABLE_NI_SEL1_MASK          0x0000000000002000
+
+/*   SH_MD_GLOBAL_TABLE_VALID                                           */
+/*   Description:  Indicates that this entry is valid                   */
+#define SH_MD_GLOBAL_TABLE_VALID_SHFT            63
+#define SH_MD_GLOBAL_TABLE_VALID_MASK            0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_OVER_RIDE_TABLE"                   */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#define SH_MD_OVER_RIDE_TABLE                    0x0000000150024480
+#define SH_MD_OVER_RIDE_TABLE_MASK               0x8000000000003f3f
+#define SH_MD_OVER_RIDE_TABLE_INIT               0x8000000000002000
+
+/*   SH_MD_OVER_RIDE_TABLE_DIR0                                         */
+/*   Description:  Direction field for next chip                        */
+#define SH_MD_OVER_RIDE_TABLE_DIR0_SHFT          0
+#define SH_MD_OVER_RIDE_TABLE_DIR0_MASK          0x000000000000000f
+
+/*   SH_MD_OVER_RIDE_TABLE_V0                                           */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_MD_OVER_RIDE_TABLE_V0_SHFT            4
+#define SH_MD_OVER_RIDE_TABLE_V0_MASK            0x0000000000000010
+
+/*   SH_MD_OVER_RIDE_TABLE_NI_SEL0                                      */
+/*   Description:  ni select                                            */
+#define SH_MD_OVER_RIDE_TABLE_NI_SEL0_SHFT       5
+#define SH_MD_OVER_RIDE_TABLE_NI_SEL0_MASK       0x0000000000000020
+
+/*   SH_MD_OVER_RIDE_TABLE_DIR1                                         */
+#define SH_MD_OVER_RIDE_TABLE_DIR1_SHFT          8
+#define SH_MD_OVER_RIDE_TABLE_DIR1_MASK          0x0000000000000f00
+
+/*   SH_MD_OVER_RIDE_TABLE_V1                                           */
+/*   Description:  Low bit of virtual channel for next chip             */
+#define SH_MD_OVER_RIDE_TABLE_V1_SHFT            12
+#define SH_MD_OVER_RIDE_TABLE_V1_MASK            0x0000000000001000
+
+/*   SH_MD_OVER_RIDE_TABLE_NI_SEL1                                      */
+/*   Description:  ni select                                            */
+#define SH_MD_OVER_RIDE_TABLE_NI_SEL1_SHFT       13
+#define SH_MD_OVER_RIDE_TABLE_NI_SEL1_MASK       0x0000000000002000
+
+/*   SH_MD_OVER_RIDE_TABLE_ENABLE                                       */
+/*   Description:  Indicates that this entry is enabled                 */
+#define SH_MD_OVER_RIDE_TABLE_ENABLE_SHFT        63
+#define SH_MD_OVER_RIDE_TABLE_ENABLE_MASK        0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_RSP_PLANE_HINT"                    */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#define SH_MD_RSP_PLANE_HINT                     0x0000000150024488
+#define SH_MD_RSP_PLANE_HINT_MASK                0x0000000000000001
+#define SH_MD_RSP_PLANE_HINT_INIT                0x0000000000000000
+
+/*   SH_MD_RSP_PLANE_HINT_INVERT                                        */
+/*   Description:  Invert Response Plane Hint                           */
+#define SH_MD_RSP_PLANE_HINT_INVERT_SHFT         0
+#define SH_MD_RSP_PLANE_HINT_INVERT_MASK         0x0000000000000001
+
+/* ==================================================================== */
+/*                       Register "SH_LB_LIQ_CTL"                       */
+/*                       Local Block LIQ Control                        */
+/* ==================================================================== */
+
+#define SH_LB_LIQ_CTL                            0x0000000110040000
+#define SH_LB_LIQ_CTL_MASK                       0x0000000000070f1f
+#define SH_LB_LIQ_CTL_INIT                       0x0000000000000000
+
+/*   SH_LB_LIQ_CTL_LIQ_REQ_CTL                                          */
+/*   Description:  LIQ Request Control                                  */
+#define SH_LB_LIQ_CTL_LIQ_REQ_CTL_SHFT           0
+#define SH_LB_LIQ_CTL_LIQ_REQ_CTL_MASK           0x000000000000001f
+
+/*   SH_LB_LIQ_CTL_LIQ_RPL_CTL                                          */
+/*   Description:  LIQ Reply Control                                    */
+#define SH_LB_LIQ_CTL_LIQ_RPL_CTL_SHFT           8
+#define SH_LB_LIQ_CTL_LIQ_RPL_CTL_MASK           0x0000000000000f00
+
+/*   SH_LB_LIQ_CTL_FORCE_RQ_CREDIT                                      */
+/*   Description:  Force request credit                                 */
+#define SH_LB_LIQ_CTL_FORCE_RQ_CREDIT_SHFT       16
+#define SH_LB_LIQ_CTL_FORCE_RQ_CREDIT_MASK       0x0000000000010000
+
+/*   SH_LB_LIQ_CTL_FORCE_RP_CREDIT                                      */
+/*   Description:  Force reply credit                                   */
+#define SH_LB_LIQ_CTL_FORCE_RP_CREDIT_SHFT       17
+#define SH_LB_LIQ_CTL_FORCE_RP_CREDIT_MASK       0x0000000000020000
+
+/*   SH_LB_LIQ_CTL_FORCE_LINVV_CREDIT                                   */
+/*   Description:  Force linvv credit                                   */
+#define SH_LB_LIQ_CTL_FORCE_LINVV_CREDIT_SHFT    18
+#define SH_LB_LIQ_CTL_FORCE_LINVV_CREDIT_MASK    0x0000000000040000
+
+/* ==================================================================== */
+/*                       Register "SH_LB_LOQ_CTL"                       */
+/*                       Local Block LOQ Control                        */
+/* ==================================================================== */
+
+#define SH_LB_LOQ_CTL                            0x0000000110040080
+#define SH_LB_LOQ_CTL_MASK                       0x0000000000000003
+#define SH_LB_LOQ_CTL_INIT                       0x0000000000000000
+
+/*   SH_LB_LOQ_CTL_LOQ_REQ_CTL                                          */
+/*   Description:  LOQ Request Control                                  */
+#define SH_LB_LOQ_CTL_LOQ_REQ_CTL_SHFT           0
+#define SH_LB_LOQ_CTL_LOQ_REQ_CTL_MASK           0x0000000000000001
+
+/*   SH_LB_LOQ_CTL_LOQ_RPL_CTL                                          */
+/*   Description:  LOQ Reply Control                                    */
+#define SH_LB_LOQ_CTL_LOQ_RPL_CTL_SHFT           1
+#define SH_LB_LOQ_CTL_LOQ_RPL_CTL_MASK           0x0000000000000002
+
+/* ==================================================================== */
+/*                 Register "SH_LB_MAX_REP_CREDIT_CNT"                  */
+/*               Maximum number of reply credits from XN                */
+/* ==================================================================== */
+
+#define SH_LB_MAX_REP_CREDIT_CNT                 0x0000000110040100
+#define SH_LB_MAX_REP_CREDIT_CNT_MASK            0x000000000000001f
+#define SH_LB_MAX_REP_CREDIT_CNT_INIT            0x000000000000001f
+
+/*   SH_LB_MAX_REP_CREDIT_CNT_MAX_CNT                                   */
+/*   Description:  Max reply credits                                    */
+#define SH_LB_MAX_REP_CREDIT_CNT_MAX_CNT_SHFT    0
+#define SH_LB_MAX_REP_CREDIT_CNT_MAX_CNT_MASK    0x000000000000001f
+
+/* ==================================================================== */
+/*                 Register "SH_LB_MAX_REQ_CREDIT_CNT"                  */
+/*              Maximum number of request credits from XN               */
+/* ==================================================================== */
+
+#define SH_LB_MAX_REQ_CREDIT_CNT                 0x0000000110040180
+#define SH_LB_MAX_REQ_CREDIT_CNT_MASK            0x000000000000001f
+#define SH_LB_MAX_REQ_CREDIT_CNT_INIT            0x000000000000001f
+
+/*   SH_LB_MAX_REQ_CREDIT_CNT_MAX_CNT                                   */
+/*   Description:  Max request credits                                  */
+#define SH_LB_MAX_REQ_CREDIT_CNT_MAX_CNT_SHFT    0
+#define SH_LB_MAX_REQ_CREDIT_CNT_MAX_CNT_MASK    0x000000000000001f
+
+/* ==================================================================== */
+/*                      Register "SH_PIO_TIME_OUT"                      */
+/*                    Local Block PIO time out value                    */
+/* ==================================================================== */
+
+#define SH_PIO_TIME_OUT                          0x0000000110040200
+#define SH_PIO_TIME_OUT_MASK                     0x000000000000ffff
+#define SH_PIO_TIME_OUT_INIT                     0x0000000000000400
+
+/*   SH_PIO_TIME_OUT_VALUE                                              */
+/*   Description:  PIO time out value                                   */
+#define SH_PIO_TIME_OUT_VALUE_SHFT               0
+#define SH_PIO_TIME_OUT_VALUE_MASK               0x000000000000ffff
+
+/* ==================================================================== */
+/*                     Register "SH_PIO_NACK_RESET"                     */
+/*               Local Block PIO Reset for nack counters                */
+/* ==================================================================== */
+
+#define SH_PIO_NACK_RESET                        0x0000000110040280
+#define SH_PIO_NACK_RESET_MASK                   0x0000000000000001
+#define SH_PIO_NACK_RESET_INIT                   0x0000000000000000
+
+/*   SH_PIO_NACK_RESET_PULSE                                            */
+/*   Description:  PIO nack counter reset                               */
+#define SH_PIO_NACK_RESET_PULSE_SHFT             0
+#define SH_PIO_NACK_RESET_PULSE_MASK             0x0000000000000001
+
+/* ==================================================================== */
+/*                 Register "SH_CONVEYOR_BELT_TIME_OUT"                 */
+/*               Local Block conveyor belt time out value               */
+/* ==================================================================== */
+
+#define SH_CONVEYOR_BELT_TIME_OUT                0x0000000110040300
+#define SH_CONVEYOR_BELT_TIME_OUT_MASK           0x0000000000000fff
+#define SH_CONVEYOR_BELT_TIME_OUT_INIT           0x0000000000000000
+
+/*   SH_CONVEYOR_BELT_TIME_OUT_VALUE                                    */
+/*   Description:  Conveyor belt time out value                         */
+#define SH_CONVEYOR_BELT_TIME_OUT_VALUE_SHFT     0
+#define SH_CONVEYOR_BELT_TIME_OUT_VALUE_MASK     0x0000000000000fff
+
+/* ==================================================================== */
+/*                    Register "SH_LB_CREDIT_STATUS"                    */
+/*                    Credit Counter Status Register                    */
+/* ==================================================================== */
+
+#define SH_LB_CREDIT_STATUS                      0x0000000110050000
+#define SH_LB_CREDIT_STATUS_MASK                 0x000000000ffff3df
+#define SH_LB_CREDIT_STATUS_INIT                 0x0000000000000000
+
+/*   SH_LB_CREDIT_STATUS_LIQ_RQ_CREDIT                                  */
+/*   Description:  LIQ request queue credit counter                     */
+#define SH_LB_CREDIT_STATUS_LIQ_RQ_CREDIT_SHFT   0
+#define SH_LB_CREDIT_STATUS_LIQ_RQ_CREDIT_MASK   0x000000000000001f
+
+/*   SH_LB_CREDIT_STATUS_LIQ_RP_CREDIT                                  */
+/*   Description:  LIQ reply queue credit counter                       */
+#define SH_LB_CREDIT_STATUS_LIQ_RP_CREDIT_SHFT   6
+#define SH_LB_CREDIT_STATUS_LIQ_RP_CREDIT_MASK   0x00000000000003c0
+
+/*   SH_LB_CREDIT_STATUS_LINVV_CREDIT                                   */
+/*   Description:  LINVV credit counter                                 */
+#define SH_LB_CREDIT_STATUS_LINVV_CREDIT_SHFT    12
+#define SH_LB_CREDIT_STATUS_LINVV_CREDIT_MASK    0x000000000003f000
+
+/*   SH_LB_CREDIT_STATUS_LOQ_RQ_CREDIT                                  */
+/*   Description:  LOQ request queue credit counter                     */
+#define SH_LB_CREDIT_STATUS_LOQ_RQ_CREDIT_SHFT   18
+#define SH_LB_CREDIT_STATUS_LOQ_RQ_CREDIT_MASK   0x00000000007c0000
+
+/*   SH_LB_CREDIT_STATUS_LOQ_RP_CREDIT                                  */
+/*   Description:  LOQ reply queue credit counter                       */
+#define SH_LB_CREDIT_STATUS_LOQ_RP_CREDIT_SHFT   23
+#define SH_LB_CREDIT_STATUS_LOQ_RP_CREDIT_MASK   0x000000000f800000
+
+/* ==================================================================== */
+/*                   Register "SH_LB_DEBUG_LOCAL_SEL"                   */
+/*                         LB Debug Port Select                         */
+/* ==================================================================== */
+
+#define SH_LB_DEBUG_LOCAL_SEL                    0x0000000110050080
+#define SH_LB_DEBUG_LOCAL_SEL_MASK               0xf777777777777777
+#define SH_LB_DEBUG_LOCAL_SEL_INIT               0x0000000000000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE0_CHIPLET_SEL                          */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE0_CHIPLET_SEL_SHFT 0
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE0_NIBBLE_SEL                           */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE1_CHIPLET_SEL                          */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE1_CHIPLET_SEL_SHFT 8
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE1_NIBBLE_SEL                           */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE2_CHIPLET_SEL                          */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE2_CHIPLET_SEL_SHFT 16
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE2_NIBBLE_SEL                           */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE3_CHIPLET_SEL                          */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE3_CHIPLET_SEL_SHFT 24
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE3_NIBBLE_SEL                           */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE4_CHIPLET_SEL                          */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE4_CHIPLET_SEL_SHFT 32
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE4_NIBBLE_SEL                           */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE5_CHIPLET_SEL                          */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE5_CHIPLET_SEL_SHFT 40
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE5_NIBBLE_SEL                           */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE6_CHIPLET_SEL                          */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE6_CHIPLET_SEL_SHFT 48
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE6_NIBBLE_SEL                           */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE7_CHIPLET_SEL                          */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE7_CHIPLET_SEL_SHFT 56
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_NIBBLE7_NIBBLE_SEL                           */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_LB_DEBUG_LOCAL_SEL_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/*   SH_LB_DEBUG_LOCAL_SEL_TRIGGER_ENABLE                               */
+/*   Description:  Enable trigger on bit 32 of Analyzer data            */
+#define SH_LB_DEBUG_LOCAL_SEL_TRIGGER_ENABLE_SHFT 63
+#define SH_LB_DEBUG_LOCAL_SEL_TRIGGER_ENABLE_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LB_DEBUG_PERF_SEL"                    */
+/*                   LB Debug Port Performance Select                   */
+/* ==================================================================== */
+
+#define SH_LB_DEBUG_PERF_SEL                     0x0000000110050100
+#define SH_LB_DEBUG_PERF_SEL_MASK                0x7777777777777777
+#define SH_LB_DEBUG_PERF_SEL_INIT                0x0000000000000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE0_CHIPLET_SEL                           */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE0_CHIPLET_SEL_SHFT 0
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE0_NIBBLE_SEL                            */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE1_CHIPLET_SEL                           */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE1_CHIPLET_SEL_SHFT 8
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE1_NIBBLE_SEL                            */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE2_CHIPLET_SEL                           */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE2_CHIPLET_SEL_SHFT 16
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE2_NIBBLE_SEL                            */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE3_CHIPLET_SEL                           */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE3_CHIPLET_SEL_SHFT 24
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE3_NIBBLE_SEL                            */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE4_CHIPLET_SEL                           */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE4_CHIPLET_SEL_SHFT 32
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE4_NIBBLE_SEL                            */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE5_CHIPLET_SEL                           */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE5_CHIPLET_SEL_SHFT 40
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE5_NIBBLE_SEL                            */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE6_CHIPLET_SEL                           */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE6_CHIPLET_SEL_SHFT 48
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE6_NIBBLE_SEL                            */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE7_CHIPLET_SEL                           */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE7_CHIPLET_SEL_SHFT 56
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_LB_DEBUG_PERF_SEL_NIBBLE7_NIBBLE_SEL                            */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_LB_DEBUG_PERF_SEL_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LB_DEBUG_TRIG_SEL"                    */
+/*                       LB Debug Trigger Select                        */
+/* ==================================================================== */
+
+#define SH_LB_DEBUG_TRIG_SEL                     0x0000000110050180
+#define SH_LB_DEBUG_TRIG_SEL_MASK                0x7777777777777777
+#define SH_LB_DEBUG_TRIG_SEL_INIT                0x0000000000000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER0_CHIPLET_SEL                          */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER0_CHIPLET_SEL_SHFT 0
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER0_NIBBLE_SEL                           */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER0_NIBBLE_SEL_SHFT 4
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER1_CHIPLET_SEL                          */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER1_CHIPLET_SEL_SHFT 8
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER1_NIBBLE_SEL                           */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER1_NIBBLE_SEL_SHFT 12
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER2_CHIPLET_SEL                          */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER2_CHIPLET_SEL_SHFT 16
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER2_NIBBLE_SEL                           */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER2_NIBBLE_SEL_SHFT 20
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER3_CHIPLET_SEL                          */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER3_CHIPLET_SEL_SHFT 24
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER3_NIBBLE_SEL                           */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER3_NIBBLE_SEL_SHFT 28
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER4_CHIPLET_SEL                          */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER4_CHIPLET_SEL_SHFT 32
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER4_NIBBLE_SEL                           */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER4_NIBBLE_SEL_SHFT 36
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER5_CHIPLET_SEL                          */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER5_CHIPLET_SEL_SHFT 40
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER5_NIBBLE_SEL                           */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER5_NIBBLE_SEL_SHFT 44
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER6_CHIPLET_SEL                          */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER6_CHIPLET_SEL_SHFT 48
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER6_NIBBLE_SEL                           */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER6_NIBBLE_SEL_SHFT 52
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER7_CHIPLET_SEL                          */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER7_CHIPLET_SEL_SHFT 56
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_LB_DEBUG_TRIG_SEL_TRIGGER7_NIBBLE_SEL                           */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER7_NIBBLE_SEL_SHFT 60
+#define SH_LB_DEBUG_TRIG_SEL_TRIGGER7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_1"                    */
+/*                  LB Error capture information: HDR1                  */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_DETAIL_1                     0x0000000110050200
+#define SH_LB_ERROR_DETAIL_1_MASK                0x8003073fff3fffff
+#define SH_LB_ERROR_DETAIL_1_INIT                0x0000000000000000
+
+/*   SH_LB_ERROR_DETAIL_1_COMMAND                                       */
+/*   Description:  COMMAND                                              */
+#define SH_LB_ERROR_DETAIL_1_COMMAND_SHFT        0
+#define SH_LB_ERROR_DETAIL_1_COMMAND_MASK        0x00000000000000ff
+
+/*   SH_LB_ERROR_DETAIL_1_SUPPL                                         */
+/*   Description:  SUPPLMENTAL                                          */
+#define SH_LB_ERROR_DETAIL_1_SUPPL_SHFT          8
+#define SH_LB_ERROR_DETAIL_1_SUPPL_MASK          0x00000000003fff00
+
+/*   SH_LB_ERROR_DETAIL_1_SOURCE                                        */
+/*   Description:  SOURCE                                               */
+#define SH_LB_ERROR_DETAIL_1_SOURCE_SHFT         24
+#define SH_LB_ERROR_DETAIL_1_SOURCE_MASK         0x0000003fff000000
+
+/*   SH_LB_ERROR_DETAIL_1_DEST                                          */
+/*   Description:  DEST                                                 */
+#define SH_LB_ERROR_DETAIL_1_DEST_SHFT           40
+#define SH_LB_ERROR_DETAIL_1_DEST_MASK           0x0000070000000000
+
+/*   SH_LB_ERROR_DETAIL_1_HDR_ERR                                       */
+/*   Description:  HDR_ERR                                              */
+#define SH_LB_ERROR_DETAIL_1_HDR_ERR_SHFT        48
+#define SH_LB_ERROR_DETAIL_1_HDR_ERR_MASK        0x0001000000000000
+
+/*   SH_LB_ERROR_DETAIL_1_DATA_ERR                                      */
+/*   Description:  DATA_ERR                                             */
+#define SH_LB_ERROR_DETAIL_1_DATA_ERR_SHFT       49
+#define SH_LB_ERROR_DETAIL_1_DATA_ERR_MASK       0x0002000000000000
+
+/*   SH_LB_ERROR_DETAIL_1_VALID                                         */
+/*   Description:  VALID                                                */
+#define SH_LB_ERROR_DETAIL_1_VALID_SHFT          63
+#define SH_LB_ERROR_DETAIL_1_VALID_MASK          0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_2"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_DETAIL_2                     0x0000000110050280
+#define SH_LB_ERROR_DETAIL_2_MASK                0x00007fffffffffff
+#define SH_LB_ERROR_DETAIL_2_INIT                0x0000000000000000
+
+/*   SH_LB_ERROR_DETAIL_2_ADDRESS                                       */
+/*   Description:  ADDRESS                                              */
+#define SH_LB_ERROR_DETAIL_2_ADDRESS_SHFT        0
+#define SH_LB_ERROR_DETAIL_2_ADDRESS_MASK        0x00007fffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_3"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_DETAIL_3                     0x0000000110050300
+#define SH_LB_ERROR_DETAIL_3_MASK                0xffffffffffffffff
+#define SH_LB_ERROR_DETAIL_3_INIT                0x0000000000000000
+
+/*   SH_LB_ERROR_DETAIL_3_DATA                                          */
+/*   Description:  DATA                                                 */
+#define SH_LB_ERROR_DETAIL_3_DATA_SHFT           0
+#define SH_LB_ERROR_DETAIL_3_DATA_MASK           0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_4"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_DETAIL_4                     0x0000000110050380
+#define SH_LB_ERROR_DETAIL_4_MASK                0xffffffffffffffff
+#define SH_LB_ERROR_DETAIL_4_INIT                0x0000000000000000
+
+/*   SH_LB_ERROR_DETAIL_4_ROUTE                                         */
+/*   Description:  ROUTE                                                */
+#define SH_LB_ERROR_DETAIL_4_ROUTE_SHFT          0
+#define SH_LB_ERROR_DETAIL_4_ROUTE_MASK          0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_5"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_DETAIL_5                     0x0000000110050400
+#define SH_LB_ERROR_DETAIL_5_MASK                0x000000000000007f
+#define SH_LB_ERROR_DETAIL_5_INIT                0x0000000000000000
+
+/*   SH_LB_ERROR_DETAIL_5_READ_RETRY                                    */
+/*   Description:  Read retry error                                     */
+#define SH_LB_ERROR_DETAIL_5_READ_RETRY_SHFT     0
+#define SH_LB_ERROR_DETAIL_5_READ_RETRY_MASK     0x0000000000000001
+
+/*   SH_LB_ERROR_DETAIL_5_PTC1_WRITE                                    */
+/*   Description:  PTC1 write error                                     */
+#define SH_LB_ERROR_DETAIL_5_PTC1_WRITE_SHFT     1
+#define SH_LB_ERROR_DETAIL_5_PTC1_WRITE_MASK     0x0000000000000002
+
+/*   SH_LB_ERROR_DETAIL_5_WRITE_RETRY                                   */
+/*   Description:  Write retry error                                    */
+#define SH_LB_ERROR_DETAIL_5_WRITE_RETRY_SHFT    2
+#define SH_LB_ERROR_DETAIL_5_WRITE_RETRY_MASK    0x0000000000000004
+
+/*   SH_LB_ERROR_DETAIL_5_COUNT_A_OVERFLOW                              */
+/*   Description:  Nack A counter overflow error                        */
+#define SH_LB_ERROR_DETAIL_5_COUNT_A_OVERFLOW_SHFT 3
+#define SH_LB_ERROR_DETAIL_5_COUNT_A_OVERFLOW_MASK 0x0000000000000008
+
+/*   SH_LB_ERROR_DETAIL_5_COUNT_B_OVERFLOW                              */
+/*   Description:  Nack B counter overflow error                        */
+#define SH_LB_ERROR_DETAIL_5_COUNT_B_OVERFLOW_SHFT 4
+#define SH_LB_ERROR_DETAIL_5_COUNT_B_OVERFLOW_MASK 0x0000000000000010
+
+/*   SH_LB_ERROR_DETAIL_5_NACK_A_TIMEOUT                                */
+/*   Description:  Nack A counter timeout error                         */
+#define SH_LB_ERROR_DETAIL_5_NACK_A_TIMEOUT_SHFT 5
+#define SH_LB_ERROR_DETAIL_5_NACK_A_TIMEOUT_MASK 0x0000000000000020
+
+/*   SH_LB_ERROR_DETAIL_5_NACK_B_TIMEOUT                                */
+/*   Description:  Nack B counter timeout error                         */
+#define SH_LB_ERROR_DETAIL_5_NACK_B_TIMEOUT_SHFT 6
+#define SH_LB_ERROR_DETAIL_5_NACK_B_TIMEOUT_MASK 0x0000000000000040
+
+/* ==================================================================== */
+/*                     Register "SH_LB_ERROR_MASK"                      */
+/*                            LB Error Mask                             */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_MASK                         0x0000000110050480
+#define SH_LB_ERROR_MASK_MASK                    0x00000000007fffff
+#define SH_LB_ERROR_MASK_INIT                    0x00000000007fffff
+
+/*   SH_LB_ERROR_MASK_RQ_BAD_CMD                                        */
+/*   Description:  RQ_BAD_CMD                                           */
+#define SH_LB_ERROR_MASK_RQ_BAD_CMD_SHFT         0
+#define SH_LB_ERROR_MASK_RQ_BAD_CMD_MASK         0x0000000000000001
+
+/*   SH_LB_ERROR_MASK_RP_BAD_CMD                                        */
+/*   Description:  RP_BAD_CMD                                           */
+#define SH_LB_ERROR_MASK_RP_BAD_CMD_SHFT         1
+#define SH_LB_ERROR_MASK_RP_BAD_CMD_MASK         0x0000000000000002
+
+/*   SH_LB_ERROR_MASK_RQ_SHORT                                          */
+/*   Description:  RQ_SHORT                                             */
+#define SH_LB_ERROR_MASK_RQ_SHORT_SHFT           2
+#define SH_LB_ERROR_MASK_RQ_SHORT_MASK           0x0000000000000004
+
+/*   SH_LB_ERROR_MASK_RP_SHORT                                          */
+/*   Description:  RP_SHORT                                             */
+#define SH_LB_ERROR_MASK_RP_SHORT_SHFT           3
+#define SH_LB_ERROR_MASK_RP_SHORT_MASK           0x0000000000000008
+
+/*   SH_LB_ERROR_MASK_RQ_LONG                                           */
+/*   Description:  RQ_LONG                                              */
+#define SH_LB_ERROR_MASK_RQ_LONG_SHFT            4
+#define SH_LB_ERROR_MASK_RQ_LONG_MASK            0x0000000000000010
+
+/*   SH_LB_ERROR_MASK_RP_LONG                                           */
+/*   Description:  RP_LONG                                              */
+#define SH_LB_ERROR_MASK_RP_LONG_SHFT            5
+#define SH_LB_ERROR_MASK_RP_LONG_MASK            0x0000000000000020
+
+/*   SH_LB_ERROR_MASK_RQ_BAD_DATA                                       */
+/*   Description:  RQ_BAD_DATA                                          */
+#define SH_LB_ERROR_MASK_RQ_BAD_DATA_SHFT        6
+#define SH_LB_ERROR_MASK_RQ_BAD_DATA_MASK        0x0000000000000040
+
+/*   SH_LB_ERROR_MASK_RP_BAD_DATA                                       */
+/*   Description:  RP_BAD_DATA                                          */
+#define SH_LB_ERROR_MASK_RP_BAD_DATA_SHFT        7
+#define SH_LB_ERROR_MASK_RP_BAD_DATA_MASK        0x0000000000000080
+
+/*   SH_LB_ERROR_MASK_RQ_BAD_ADDR                                       */
+/*   Description:  RQ_BAD_ADDR                                          */
+#define SH_LB_ERROR_MASK_RQ_BAD_ADDR_SHFT        8
+#define SH_LB_ERROR_MASK_RQ_BAD_ADDR_MASK        0x0000000000000100
+
+/*   SH_LB_ERROR_MASK_RQ_TIME_OUT                                       */
+/*   Description:  RQ_TIME_OUT                                          */
+#define SH_LB_ERROR_MASK_RQ_TIME_OUT_SHFT        9
+#define SH_LB_ERROR_MASK_RQ_TIME_OUT_MASK        0x0000000000000200
+
+/*   SH_LB_ERROR_MASK_LINVV_OVERFLOW                                    */
+/*   Description:  LINVV_OVERFLOW                                       */
+#define SH_LB_ERROR_MASK_LINVV_OVERFLOW_SHFT     10
+#define SH_LB_ERROR_MASK_LINVV_OVERFLOW_MASK     0x0000000000000400
+
+/*   SH_LB_ERROR_MASK_UNEXPECTED_LINV                                   */
+/*   Description:  UNEXPECTED_LINV                                      */
+#define SH_LB_ERROR_MASK_UNEXPECTED_LINV_SHFT    11
+#define SH_LB_ERROR_MASK_UNEXPECTED_LINV_MASK    0x0000000000000800
+
+/*   SH_LB_ERROR_MASK_PTC_1_TIMEOUT                                     */
+/*   Description:  PTC_1 Time out                                       */
+#define SH_LB_ERROR_MASK_PTC_1_TIMEOUT_SHFT      12
+#define SH_LB_ERROR_MASK_PTC_1_TIMEOUT_MASK      0x0000000000001000
+
+/*   SH_LB_ERROR_MASK_JUNK_BUS_ERR                                      */
+/*   Description:  Junk Bus error                                       */
+#define SH_LB_ERROR_MASK_JUNK_BUS_ERR_SHFT       13
+#define SH_LB_ERROR_MASK_JUNK_BUS_ERR_MASK       0x0000000000002000
+
+/*   SH_LB_ERROR_MASK_PIO_CB_ERR                                        */
+/*   Description:  PIO Conveyor Belt operation error                    */
+#define SH_LB_ERROR_MASK_PIO_CB_ERR_SHFT         14
+#define SH_LB_ERROR_MASK_PIO_CB_ERR_MASK         0x0000000000004000
+
+/*   SH_LB_ERROR_MASK_VECTOR_RQ_ROUTE_ERROR                             */
+/*   Description:  Vector request Route data was invalid                */
+#define SH_LB_ERROR_MASK_VECTOR_RQ_ROUTE_ERROR_SHFT 15
+#define SH_LB_ERROR_MASK_VECTOR_RQ_ROUTE_ERROR_MASK 0x0000000000008000
+
+/*   SH_LB_ERROR_MASK_VECTOR_RP_ROUTE_ERROR                             */
+/*   Description:  Vector reply Route data was invalid                  */
+#define SH_LB_ERROR_MASK_VECTOR_RP_ROUTE_ERROR_SHFT 16
+#define SH_LB_ERROR_MASK_VECTOR_RP_ROUTE_ERROR_MASK 0x0000000000010000
+
+/*   SH_LB_ERROR_MASK_GCLK_DROP                                         */
+/*   Description:  Gclk drop error                                      */
+#define SH_LB_ERROR_MASK_GCLK_DROP_SHFT          17
+#define SH_LB_ERROR_MASK_GCLK_DROP_MASK          0x0000000000020000
+
+/*   SH_LB_ERROR_MASK_RQ_FIFO_ERROR                                     */
+/*   Description:  Request queue FIFO error                             */
+#define SH_LB_ERROR_MASK_RQ_FIFO_ERROR_SHFT      18
+#define SH_LB_ERROR_MASK_RQ_FIFO_ERROR_MASK      0x0000000000040000
+
+/*   SH_LB_ERROR_MASK_RP_FIFO_ERROR                                     */
+/*   Description:  Reply queue FIFO error                               */
+#define SH_LB_ERROR_MASK_RP_FIFO_ERROR_SHFT      19
+#define SH_LB_ERROR_MASK_RP_FIFO_ERROR_MASK      0x0000000000080000
+
+/*   SH_LB_ERROR_MASK_UNEXP_VALID                                       */
+/*   Description:  Unexpected valid error                               */
+#define SH_LB_ERROR_MASK_UNEXP_VALID_SHFT        20
+#define SH_LB_ERROR_MASK_UNEXP_VALID_MASK        0x0000000000100000
+
+/*   SH_LB_ERROR_MASK_RQ_CREDIT_OVERFLOW                                */
+/*   Description:  Request queue credit overflow                        */
+#define SH_LB_ERROR_MASK_RQ_CREDIT_OVERFLOW_SHFT 21
+#define SH_LB_ERROR_MASK_RQ_CREDIT_OVERFLOW_MASK 0x0000000000200000
+
+/*   SH_LB_ERROR_MASK_RP_CREDIT_OVERFLOW                                */
+/*   Description:  Reply queue credit overflow                          */
+#define SH_LB_ERROR_MASK_RP_CREDIT_OVERFLOW_SHFT 22
+#define SH_LB_ERROR_MASK_RP_CREDIT_OVERFLOW_MASK 0x0000000000400000
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_OVERFLOW"                    */
+/*                          LB Error Overflow                           */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_OVERFLOW                     0x0000000110050500
+#define SH_LB_ERROR_OVERFLOW_MASK                0x00000000007fffff
+#define SH_LB_ERROR_OVERFLOW_INIT                0x0000000000000000
+
+/*   SH_LB_ERROR_OVERFLOW_RQ_BAD_CMD_OVRFL                              */
+/*   Description:  RQ_BAD_CMD_OVRFL                                     */
+#define SH_LB_ERROR_OVERFLOW_RQ_BAD_CMD_OVRFL_SHFT 0
+#define SH_LB_ERROR_OVERFLOW_RQ_BAD_CMD_OVRFL_MASK 0x0000000000000001
+
+/*   SH_LB_ERROR_OVERFLOW_RP_BAD_CMD_OVRFL                              */
+/*   Description:  RP_BAD_CMD_OVRFL                                     */
+#define SH_LB_ERROR_OVERFLOW_RP_BAD_CMD_OVRFL_SHFT 1
+#define SH_LB_ERROR_OVERFLOW_RP_BAD_CMD_OVRFL_MASK 0x0000000000000002
+
+/*   SH_LB_ERROR_OVERFLOW_RQ_SHORT_OVRFL                                */
+/*   Description:  RQ_SHORT_OVRFL                                       */
+#define SH_LB_ERROR_OVERFLOW_RQ_SHORT_OVRFL_SHFT 2
+#define SH_LB_ERROR_OVERFLOW_RQ_SHORT_OVRFL_MASK 0x0000000000000004
+
+/*   SH_LB_ERROR_OVERFLOW_RP_SHORT_OVRFL                                */
+/*   Description:  RP_SHORT_OVRFL                                       */
+#define SH_LB_ERROR_OVERFLOW_RP_SHORT_OVRFL_SHFT 3
+#define SH_LB_ERROR_OVERFLOW_RP_SHORT_OVRFL_MASK 0x0000000000000008
+
+/*   SH_LB_ERROR_OVERFLOW_RQ_LONG_OVRFL                                 */
+/*   Description:  RQ_LONG_OVRFL                                        */
+#define SH_LB_ERROR_OVERFLOW_RQ_LONG_OVRFL_SHFT  4
+#define SH_LB_ERROR_OVERFLOW_RQ_LONG_OVRFL_MASK  0x0000000000000010
+
+/*   SH_LB_ERROR_OVERFLOW_RP_LONG_OVRFL                                 */
+/*   Description:  RP_LONG_OVRFL                                        */
+#define SH_LB_ERROR_OVERFLOW_RP_LONG_OVRFL_SHFT  5
+#define SH_LB_ERROR_OVERFLOW_RP_LONG_OVRFL_MASK  0x0000000000000020
+
+/*   SH_LB_ERROR_OVERFLOW_RQ_BAD_DATA_OVRFL                             */
+/*   Description:  RQ_BAD_DATA_OVRFL                                    */
+#define SH_LB_ERROR_OVERFLOW_RQ_BAD_DATA_OVRFL_SHFT 6
+#define SH_LB_ERROR_OVERFLOW_RQ_BAD_DATA_OVRFL_MASK 0x0000000000000040
+
+/*   SH_LB_ERROR_OVERFLOW_RP_BAD_DATA_OVRFL                             */
+/*   Description:  RP_BAD_DATA_OVRFL                                    */
+#define SH_LB_ERROR_OVERFLOW_RP_BAD_DATA_OVRFL_SHFT 7
+#define SH_LB_ERROR_OVERFLOW_RP_BAD_DATA_OVRFL_MASK 0x0000000000000080
+
+/*   SH_LB_ERROR_OVERFLOW_RQ_BAD_ADDR_OVRFL                             */
+/*   Description:  RQ_BAD_ADDR_OVRFL                                    */
+#define SH_LB_ERROR_OVERFLOW_RQ_BAD_ADDR_OVRFL_SHFT 8
+#define SH_LB_ERROR_OVERFLOW_RQ_BAD_ADDR_OVRFL_MASK 0x0000000000000100
+
+/*   SH_LB_ERROR_OVERFLOW_RQ_TIME_OUT_OVRFL                             */
+/*   Description:  RQ_TIME_OUT_OVRFL                                    */
+#define SH_LB_ERROR_OVERFLOW_RQ_TIME_OUT_OVRFL_SHFT 9
+#define SH_LB_ERROR_OVERFLOW_RQ_TIME_OUT_OVRFL_MASK 0x0000000000000200
+
+/*   SH_LB_ERROR_OVERFLOW_LINVV_OVERFLOW_OVRFL                          */
+/*   Description:  LINVV_OVERFLOW_OVRFL                                 */
+#define SH_LB_ERROR_OVERFLOW_LINVV_OVERFLOW_OVRFL_SHFT 10
+#define SH_LB_ERROR_OVERFLOW_LINVV_OVERFLOW_OVRFL_MASK 0x0000000000000400
+
+/*   SH_LB_ERROR_OVERFLOW_UNEXPECTED_LINV_OVRFL                         */
+/*   Description:  UNEXPECTED_LINV_OVRFL                                */
+#define SH_LB_ERROR_OVERFLOW_UNEXPECTED_LINV_OVRFL_SHFT 11
+#define SH_LB_ERROR_OVERFLOW_UNEXPECTED_LINV_OVRFL_MASK 0x0000000000000800
+
+/*   SH_LB_ERROR_OVERFLOW_PTC_1_TIMEOUT_OVRFL                           */
+/*   Description:  PTC_1 Time out overflow                              */
+#define SH_LB_ERROR_OVERFLOW_PTC_1_TIMEOUT_OVRFL_SHFT 12
+#define SH_LB_ERROR_OVERFLOW_PTC_1_TIMEOUT_OVRFL_MASK 0x0000000000001000
+
+/*   SH_LB_ERROR_OVERFLOW_JUNK_BUS_ERR_OVRFL                            */
+/*   Description:  Junk Bus error overflow                              */
+#define SH_LB_ERROR_OVERFLOW_JUNK_BUS_ERR_OVRFL_SHFT 13
+#define SH_LB_ERROR_OVERFLOW_JUNK_BUS_ERR_OVRFL_MASK 0x0000000000002000
+
+/*   SH_LB_ERROR_OVERFLOW_PIO_CB_ERR_OVRFL                              */
+/*   Description:  PIO Conveyor Belt operation error overflow           */
+#define SH_LB_ERROR_OVERFLOW_PIO_CB_ERR_OVRFL_SHFT 14
+#define SH_LB_ERROR_OVERFLOW_PIO_CB_ERR_OVRFL_MASK 0x0000000000004000
+
+/*   SH_LB_ERROR_OVERFLOW_VECTOR_RQ_ROUTE_ERROR_OVRFL                   */
+/*   Description:  Vector request Route data was invalid overflow       */
+#define SH_LB_ERROR_OVERFLOW_VECTOR_RQ_ROUTE_ERROR_OVRFL_SHFT 15
+#define SH_LB_ERROR_OVERFLOW_VECTOR_RQ_ROUTE_ERROR_OVRFL_MASK 0x0000000000008000
+
+/*   SH_LB_ERROR_OVERFLOW_VECTOR_RP_ROUTE_ERROR_OVRFL                   */
+/*   Description:  Vector reply Route data was invalid overflow         */
+#define SH_LB_ERROR_OVERFLOW_VECTOR_RP_ROUTE_ERROR_OVRFL_SHFT 16
+#define SH_LB_ERROR_OVERFLOW_VECTOR_RP_ROUTE_ERROR_OVRFL_MASK 0x0000000000010000
+
+/*   SH_LB_ERROR_OVERFLOW_GCLK_DROP_OVRFL                               */
+/*   Description:  Gclk drop error overflow                             */
+#define SH_LB_ERROR_OVERFLOW_GCLK_DROP_OVRFL_SHFT 17
+#define SH_LB_ERROR_OVERFLOW_GCLK_DROP_OVRFL_MASK 0x0000000000020000
+
+/*   SH_LB_ERROR_OVERFLOW_RQ_FIFO_ERROR_OVRFL                           */
+/*   Description:  Request queue FIFO error overflow                    */
+#define SH_LB_ERROR_OVERFLOW_RQ_FIFO_ERROR_OVRFL_SHFT 18
+#define SH_LB_ERROR_OVERFLOW_RQ_FIFO_ERROR_OVRFL_MASK 0x0000000000040000
+
+/*   SH_LB_ERROR_OVERFLOW_RP_FIFO_ERROR_OVRFL                           */
+/*   Description:  Reply queue FIFO error overflow                      */
+#define SH_LB_ERROR_OVERFLOW_RP_FIFO_ERROR_OVRFL_SHFT 19
+#define SH_LB_ERROR_OVERFLOW_RP_FIFO_ERROR_OVRFL_MASK 0x0000000000080000
+
+/*   SH_LB_ERROR_OVERFLOW_UNEXP_VALID_OVRFL                             */
+/*   Description:  Unexpected valid error overflow                      */
+#define SH_LB_ERROR_OVERFLOW_UNEXP_VALID_OVRFL_SHFT 20
+#define SH_LB_ERROR_OVERFLOW_UNEXP_VALID_OVRFL_MASK 0x0000000000100000
+
+/*   SH_LB_ERROR_OVERFLOW_RQ_CREDIT_OVERFLOW_OVRFL                      */
+/*   Description:  Request queue credit overflow                        */
+#define SH_LB_ERROR_OVERFLOW_RQ_CREDIT_OVERFLOW_OVRFL_SHFT 21
+#define SH_LB_ERROR_OVERFLOW_RQ_CREDIT_OVERFLOW_OVRFL_MASK 0x0000000000200000
+
+/*   SH_LB_ERROR_OVERFLOW_RP_CREDIT_OVERFLOW_OVRFL                      */
+/*   Description:  Reply queue credit overflow                          */
+#define SH_LB_ERROR_OVERFLOW_RP_CREDIT_OVERFLOW_OVRFL_SHFT 22
+#define SH_LB_ERROR_OVERFLOW_RP_CREDIT_OVERFLOW_OVRFL_MASK 0x0000000000400000
+
+/* ==================================================================== */
+/*                Register "SH_LB_ERROR_OVERFLOW_ALIAS"                 */
+/*                          LB Error Overflow                           */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_OVERFLOW_ALIAS               0x0000000110050508
+
+/* ==================================================================== */
+/*                    Register "SH_LB_ERROR_SUMMARY"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_SUMMARY                      0x0000000110050580
+#define SH_LB_ERROR_SUMMARY_MASK                 0x00000000007fffff
+#define SH_LB_ERROR_SUMMARY_INIT                 0x0000000000000000
+
+/*   SH_LB_ERROR_SUMMARY_RQ_BAD_CMD                                     */
+/*   Description:  RQ_BAD_CMD                                           */
+#define SH_LB_ERROR_SUMMARY_RQ_BAD_CMD_SHFT      0
+#define SH_LB_ERROR_SUMMARY_RQ_BAD_CMD_MASK      0x0000000000000001
+
+/*   SH_LB_ERROR_SUMMARY_RP_BAD_CMD                                     */
+/*   Description:  RP_BAD_CMD                                           */
+#define SH_LB_ERROR_SUMMARY_RP_BAD_CMD_SHFT      1
+#define SH_LB_ERROR_SUMMARY_RP_BAD_CMD_MASK      0x0000000000000002
+
+/*   SH_LB_ERROR_SUMMARY_RQ_SHORT                                       */
+/*   Description:  RQ_SHORT                                             */
+#define SH_LB_ERROR_SUMMARY_RQ_SHORT_SHFT        2
+#define SH_LB_ERROR_SUMMARY_RQ_SHORT_MASK        0x0000000000000004
+
+/*   SH_LB_ERROR_SUMMARY_RP_SHORT                                       */
+/*   Description:  RP_SHORT                                             */
+#define SH_LB_ERROR_SUMMARY_RP_SHORT_SHFT        3
+#define SH_LB_ERROR_SUMMARY_RP_SHORT_MASK        0x0000000000000008
+
+/*   SH_LB_ERROR_SUMMARY_RQ_LONG                                        */
+/*   Description:  RQ_LONG                                              */
+#define SH_LB_ERROR_SUMMARY_RQ_LONG_SHFT         4
+#define SH_LB_ERROR_SUMMARY_RQ_LONG_MASK         0x0000000000000010
+
+/*   SH_LB_ERROR_SUMMARY_RP_LONG                                        */
+/*   Description:  RP_LONG                                              */
+#define SH_LB_ERROR_SUMMARY_RP_LONG_SHFT         5
+#define SH_LB_ERROR_SUMMARY_RP_LONG_MASK         0x0000000000000020
+
+/*   SH_LB_ERROR_SUMMARY_RQ_BAD_DATA                                    */
+/*   Description:  RQ_BAD_DATA                                          */
+#define SH_LB_ERROR_SUMMARY_RQ_BAD_DATA_SHFT     6
+#define SH_LB_ERROR_SUMMARY_RQ_BAD_DATA_MASK     0x0000000000000040
+
+/*   SH_LB_ERROR_SUMMARY_RP_BAD_DATA                                    */
+/*   Description:  RP_BAD_DATA                                          */
+#define SH_LB_ERROR_SUMMARY_RP_BAD_DATA_SHFT     7
+#define SH_LB_ERROR_SUMMARY_RP_BAD_DATA_MASK     0x0000000000000080
+
+/*   SH_LB_ERROR_SUMMARY_RQ_BAD_ADDR                                    */
+/*   Description:  RQ_BAD_ADDR                                          */
+#define SH_LB_ERROR_SUMMARY_RQ_BAD_ADDR_SHFT     8
+#define SH_LB_ERROR_SUMMARY_RQ_BAD_ADDR_MASK     0x0000000000000100
+
+/*   SH_LB_ERROR_SUMMARY_RQ_TIME_OUT                                    */
+/*   Description:  RQ_TIME_OUT                                          */
+#define SH_LB_ERROR_SUMMARY_RQ_TIME_OUT_SHFT     9
+#define SH_LB_ERROR_SUMMARY_RQ_TIME_OUT_MASK     0x0000000000000200
+
+/*   SH_LB_ERROR_SUMMARY_LINVV_OVERFLOW                                 */
+/*   Description:  LINVV_OVERFLOW                                       */
+#define SH_LB_ERROR_SUMMARY_LINVV_OVERFLOW_SHFT  10
+#define SH_LB_ERROR_SUMMARY_LINVV_OVERFLOW_MASK  0x0000000000000400
+
+/*   SH_LB_ERROR_SUMMARY_UNEXPECTED_LINV                                */
+/*   Description:  UNEXPECTED_LINV                                      */
+#define SH_LB_ERROR_SUMMARY_UNEXPECTED_LINV_SHFT 11
+#define SH_LB_ERROR_SUMMARY_UNEXPECTED_LINV_MASK 0x0000000000000800
+
+/*   SH_LB_ERROR_SUMMARY_PTC_1_TIMEOUT                                  */
+/*   Description:  PTC_1 Time out                                       */
+#define SH_LB_ERROR_SUMMARY_PTC_1_TIMEOUT_SHFT   12
+#define SH_LB_ERROR_SUMMARY_PTC_1_TIMEOUT_MASK   0x0000000000001000
+
+/*   SH_LB_ERROR_SUMMARY_JUNK_BUS_ERR                                   */
+/*   Description:  Junk Bus error                                       */
+#define SH_LB_ERROR_SUMMARY_JUNK_BUS_ERR_SHFT    13
+#define SH_LB_ERROR_SUMMARY_JUNK_BUS_ERR_MASK    0x0000000000002000
+
+/*   SH_LB_ERROR_SUMMARY_PIO_CB_ERR                                     */
+/*   Description:  PIO Conveyor Belt operation error                    */
+#define SH_LB_ERROR_SUMMARY_PIO_CB_ERR_SHFT      14
+#define SH_LB_ERROR_SUMMARY_PIO_CB_ERR_MASK      0x0000000000004000
+
+/*   SH_LB_ERROR_SUMMARY_VECTOR_RQ_ROUTE_ERROR                          */
+/*   Description:  Vector request Route data was invalid                */
+#define SH_LB_ERROR_SUMMARY_VECTOR_RQ_ROUTE_ERROR_SHFT 15
+#define SH_LB_ERROR_SUMMARY_VECTOR_RQ_ROUTE_ERROR_MASK 0x0000000000008000
+
+/*   SH_LB_ERROR_SUMMARY_VECTOR_RP_ROUTE_ERROR                          */
+/*   Description:  Vector reply Route data was invalid                  */
+#define SH_LB_ERROR_SUMMARY_VECTOR_RP_ROUTE_ERROR_SHFT 16
+#define SH_LB_ERROR_SUMMARY_VECTOR_RP_ROUTE_ERROR_MASK 0x0000000000010000
+
+/*   SH_LB_ERROR_SUMMARY_GCLK_DROP                                      */
+/*   Description:  Gclk drop error                                      */
+#define SH_LB_ERROR_SUMMARY_GCLK_DROP_SHFT       17
+#define SH_LB_ERROR_SUMMARY_GCLK_DROP_MASK       0x0000000000020000
+
+/*   SH_LB_ERROR_SUMMARY_RQ_FIFO_ERROR                                  */
+/*   Description:  Request queue FIFO error                             */
+#define SH_LB_ERROR_SUMMARY_RQ_FIFO_ERROR_SHFT   18
+#define SH_LB_ERROR_SUMMARY_RQ_FIFO_ERROR_MASK   0x0000000000040000
+
+/*   SH_LB_ERROR_SUMMARY_RP_FIFO_ERROR                                  */
+/*   Description:  Reply queue FIFO error                               */
+#define SH_LB_ERROR_SUMMARY_RP_FIFO_ERROR_SHFT   19
+#define SH_LB_ERROR_SUMMARY_RP_FIFO_ERROR_MASK   0x0000000000080000
+
+/*   SH_LB_ERROR_SUMMARY_UNEXP_VALID                                    */
+/*   Description:  Unexpected valid error                               */
+#define SH_LB_ERROR_SUMMARY_UNEXP_VALID_SHFT     20
+#define SH_LB_ERROR_SUMMARY_UNEXP_VALID_MASK     0x0000000000100000
+
+/*   SH_LB_ERROR_SUMMARY_RQ_CREDIT_OVERFLOW                             */
+/*   Description:  Request queue credit overflow                        */
+#define SH_LB_ERROR_SUMMARY_RQ_CREDIT_OVERFLOW_SHFT 21
+#define SH_LB_ERROR_SUMMARY_RQ_CREDIT_OVERFLOW_MASK 0x0000000000200000
+
+/*   SH_LB_ERROR_SUMMARY_RP_CREDIT_OVERFLOW                             */
+/*   Description:  Reply queue credit overflow                          */
+#define SH_LB_ERROR_SUMMARY_RP_CREDIT_OVERFLOW_SHFT 22
+#define SH_LB_ERROR_SUMMARY_RP_CREDIT_OVERFLOW_MASK 0x0000000000400000
+
+/* ==================================================================== */
+/*                 Register "SH_LB_ERROR_SUMMARY_ALIAS"                 */
+/*                         LB Error Bits Alias                          */
+/* ==================================================================== */
+
+#define SH_LB_ERROR_SUMMARY_ALIAS                0x0000000110050588
+
+/* ==================================================================== */
+/*                     Register "SH_LB_FIRST_ERROR"                     */
+/*                            LB First Error                            */
+/* ==================================================================== */
+
+#define SH_LB_FIRST_ERROR                        0x0000000110050600
+#define SH_LB_FIRST_ERROR_MASK                   0x00000000007fffff
+#define SH_LB_FIRST_ERROR_INIT                   0x0000000000000000
+
+/*   SH_LB_FIRST_ERROR_RQ_BAD_CMD                                       */
+/*   Description:  RQ_BAD_CMD                                           */
+#define SH_LB_FIRST_ERROR_RQ_BAD_CMD_SHFT        0
+#define SH_LB_FIRST_ERROR_RQ_BAD_CMD_MASK        0x0000000000000001
+
+/*   SH_LB_FIRST_ERROR_RP_BAD_CMD                                       */
+/*   Description:  RP_BAD_CMD                                           */
+#define SH_LB_FIRST_ERROR_RP_BAD_CMD_SHFT        1
+#define SH_LB_FIRST_ERROR_RP_BAD_CMD_MASK        0x0000000000000002
+
+/*   SH_LB_FIRST_ERROR_RQ_SHORT                                         */
+/*   Description:  RQ_SHORT                                             */
+#define SH_LB_FIRST_ERROR_RQ_SHORT_SHFT          2
+#define SH_LB_FIRST_ERROR_RQ_SHORT_MASK          0x0000000000000004
+
+/*   SH_LB_FIRST_ERROR_RP_SHORT                                         */
+/*   Description:  RP_SHORT                                             */
+#define SH_LB_FIRST_ERROR_RP_SHORT_SHFT          3
+#define SH_LB_FIRST_ERROR_RP_SHORT_MASK          0x0000000000000008
+
+/*   SH_LB_FIRST_ERROR_RQ_LONG                                          */
+/*   Description:  RQ_LONG                                              */
+#define SH_LB_FIRST_ERROR_RQ_LONG_SHFT           4
+#define SH_LB_FIRST_ERROR_RQ_LONG_MASK           0x0000000000000010
+
+/*   SH_LB_FIRST_ERROR_RP_LONG                                          */
+/*   Description:  RP_LONG                                              */
+#define SH_LB_FIRST_ERROR_RP_LONG_SHFT           5
+#define SH_LB_FIRST_ERROR_RP_LONG_MASK           0x0000000000000020
+
+/*   SH_LB_FIRST_ERROR_RQ_BAD_DATA                                      */
+/*   Description:  RQ_BAD_DATA                                          */
+#define SH_LB_FIRST_ERROR_RQ_BAD_DATA_SHFT       6
+#define SH_LB_FIRST_ERROR_RQ_BAD_DATA_MASK       0x0000000000000040
+
+/*   SH_LB_FIRST_ERROR_RP_BAD_DATA                                      */
+/*   Description:  RP_BAD_DATA                                          */
+#define SH_LB_FIRST_ERROR_RP_BAD_DATA_SHFT       7
+#define SH_LB_FIRST_ERROR_RP_BAD_DATA_MASK       0x0000000000000080
+
+/*   SH_LB_FIRST_ERROR_RQ_BAD_ADDR                                      */
+/*   Description:  RQ_BAD_ADDR                                          */
+#define SH_LB_FIRST_ERROR_RQ_BAD_ADDR_SHFT       8
+#define SH_LB_FIRST_ERROR_RQ_BAD_ADDR_MASK       0x0000000000000100
+
+/*   SH_LB_FIRST_ERROR_RQ_TIME_OUT                                      */
+/*   Description:  RQ_TIME_OUT                                          */
+#define SH_LB_FIRST_ERROR_RQ_TIME_OUT_SHFT       9
+#define SH_LB_FIRST_ERROR_RQ_TIME_OUT_MASK       0x0000000000000200
+
+/*   SH_LB_FIRST_ERROR_LINVV_OVERFLOW                                   */
+/*   Description:  LINVV_OVERFLOW                                       */
+#define SH_LB_FIRST_ERROR_LINVV_OVERFLOW_SHFT    10
+#define SH_LB_FIRST_ERROR_LINVV_OVERFLOW_MASK    0x0000000000000400
+
+/*   SH_LB_FIRST_ERROR_UNEXPECTED_LINV                                  */
+/*   Description:  UNEXPECTED_LINV                                      */
+#define SH_LB_FIRST_ERROR_UNEXPECTED_LINV_SHFT   11
+#define SH_LB_FIRST_ERROR_UNEXPECTED_LINV_MASK   0x0000000000000800
+
+/*   SH_LB_FIRST_ERROR_PTC_1_TIMEOUT                                    */
+/*   Description:  PTC_1 Time out                                       */
+#define SH_LB_FIRST_ERROR_PTC_1_TIMEOUT_SHFT     12
+#define SH_LB_FIRST_ERROR_PTC_1_TIMEOUT_MASK     0x0000000000001000
+
+/*   SH_LB_FIRST_ERROR_JUNK_BUS_ERR                                     */
+/*   Description:  Junk Bus error                                       */
+#define SH_LB_FIRST_ERROR_JUNK_BUS_ERR_SHFT      13
+#define SH_LB_FIRST_ERROR_JUNK_BUS_ERR_MASK      0x0000000000002000
+
+/*   SH_LB_FIRST_ERROR_PIO_CB_ERR                                       */
+/*   Description:  PIO Conveyor Belt operation error                    */
+#define SH_LB_FIRST_ERROR_PIO_CB_ERR_SHFT        14
+#define SH_LB_FIRST_ERROR_PIO_CB_ERR_MASK        0x0000000000004000
+
+/*   SH_LB_FIRST_ERROR_VECTOR_RQ_ROUTE_ERROR                            */
+/*   Description:  Vector request Route data was invalid                */
+#define SH_LB_FIRST_ERROR_VECTOR_RQ_ROUTE_ERROR_SHFT 15
+#define SH_LB_FIRST_ERROR_VECTOR_RQ_ROUTE_ERROR_MASK 0x0000000000008000
+
+/*   SH_LB_FIRST_ERROR_VECTOR_RP_ROUTE_ERROR                            */
+/*   Description:  Vector reply Route data was invalid                  */
+#define SH_LB_FIRST_ERROR_VECTOR_RP_ROUTE_ERROR_SHFT 16
+#define SH_LB_FIRST_ERROR_VECTOR_RP_ROUTE_ERROR_MASK 0x0000000000010000
+
+/*   SH_LB_FIRST_ERROR_GCLK_DROP                                        */
+/*   Description:  Gclk drop error                                      */
+#define SH_LB_FIRST_ERROR_GCLK_DROP_SHFT         17
+#define SH_LB_FIRST_ERROR_GCLK_DROP_MASK         0x0000000000020000
+
+/*   SH_LB_FIRST_ERROR_RQ_FIFO_ERROR                                    */
+/*   Description:  Request queue FIFO error                             */
+#define SH_LB_FIRST_ERROR_RQ_FIFO_ERROR_SHFT     18
+#define SH_LB_FIRST_ERROR_RQ_FIFO_ERROR_MASK     0x0000000000040000
+
+/*   SH_LB_FIRST_ERROR_RP_FIFO_ERROR                                    */
+/*   Description:  Reply queue FIFO error                               */
+#define SH_LB_FIRST_ERROR_RP_FIFO_ERROR_SHFT     19
+#define SH_LB_FIRST_ERROR_RP_FIFO_ERROR_MASK     0x0000000000080000
+
+/*   SH_LB_FIRST_ERROR_UNEXP_VALID                                      */
+/*   Description:  Unexpected valid error                               */
+#define SH_LB_FIRST_ERROR_UNEXP_VALID_SHFT       20
+#define SH_LB_FIRST_ERROR_UNEXP_VALID_MASK       0x0000000000100000
+
+/*   SH_LB_FIRST_ERROR_RQ_CREDIT_OVERFLOW                               */
+/*   Description:  Request queue credit overflow                        */
+#define SH_LB_FIRST_ERROR_RQ_CREDIT_OVERFLOW_SHFT 21
+#define SH_LB_FIRST_ERROR_RQ_CREDIT_OVERFLOW_MASK 0x0000000000200000
+
+/*   SH_LB_FIRST_ERROR_RP_CREDIT_OVERFLOW                               */
+/*   Description:  Reply queue credit overflow                          */
+#define SH_LB_FIRST_ERROR_RP_CREDIT_OVERFLOW_SHFT 22
+#define SH_LB_FIRST_ERROR_RP_CREDIT_OVERFLOW_MASK 0x0000000000400000
+
+/* ==================================================================== */
+/*                     Register "SH_LB_LAST_CREDIT"                     */
+/*                    Credit counter status register                    */
+/* ==================================================================== */
+
+#define SH_LB_LAST_CREDIT                        0x0000000110050680
+#define SH_LB_LAST_CREDIT_MASK                   0x000000000ffff3df
+#define SH_LB_LAST_CREDIT_INIT                   0x0000000000000000
+
+/*   SH_LB_LAST_CREDIT_LIQ_RQ_CREDIT                                    */
+/*   Description:  LIQ request queue credit counter                     */
+#define SH_LB_LAST_CREDIT_LIQ_RQ_CREDIT_SHFT     0
+#define SH_LB_LAST_CREDIT_LIQ_RQ_CREDIT_MASK     0x000000000000001f
+
+/*   SH_LB_LAST_CREDIT_LIQ_RP_CREDIT                                    */
+/*   Description:  LIQ reply queue credit counter                       */
+#define SH_LB_LAST_CREDIT_LIQ_RP_CREDIT_SHFT     6
+#define SH_LB_LAST_CREDIT_LIQ_RP_CREDIT_MASK     0x00000000000003c0
+
+/*   SH_LB_LAST_CREDIT_LINVV_CREDIT                                     */
+/*   Description:  LINVV credit counter                                 */
+#define SH_LB_LAST_CREDIT_LINVV_CREDIT_SHFT      12
+#define SH_LB_LAST_CREDIT_LINVV_CREDIT_MASK      0x000000000003f000
+
+/*   SH_LB_LAST_CREDIT_LOQ_RQ_CREDIT                                    */
+/*   Description:  LOQ request queue credit counter                     */
+#define SH_LB_LAST_CREDIT_LOQ_RQ_CREDIT_SHFT     18
+#define SH_LB_LAST_CREDIT_LOQ_RQ_CREDIT_MASK     0x00000000007c0000
+
+/*   SH_LB_LAST_CREDIT_LOQ_RP_CREDIT                                    */
+/*   Description:  LOQ reply queue credit counter                       */
+#define SH_LB_LAST_CREDIT_LOQ_RP_CREDIT_SHFT     23
+#define SH_LB_LAST_CREDIT_LOQ_RP_CREDIT_MASK     0x000000000f800000
+
+/* ==================================================================== */
+/*                     Register "SH_LB_NACK_STATUS"                     */
+/*                     Nack Counter Status Register                     */
+/* ==================================================================== */
+
+#define SH_LB_NACK_STATUS                        0x0000000110050700
+#define SH_LB_NACK_STATUS_MASK                   0x3fffffff0fff0fff
+#define SH_LB_NACK_STATUS_INIT                   0x0000000000000000
+
+/*   SH_LB_NACK_STATUS_PIO_NACK_A                                       */
+/*   Description:  PIO nackA counter                                    */
+#define SH_LB_NACK_STATUS_PIO_NACK_A_SHFT        0
+#define SH_LB_NACK_STATUS_PIO_NACK_A_MASK        0x0000000000000fff
+
+/*   SH_LB_NACK_STATUS_PIO_NACK_B                                       */
+/*   Description:  PIO nackA counter                                    */
+#define SH_LB_NACK_STATUS_PIO_NACK_B_SHFT        16
+#define SH_LB_NACK_STATUS_PIO_NACK_B_MASK        0x000000000fff0000
+
+/*   SH_LB_NACK_STATUS_JUNK_NACK                                        */
+/*   Description:  Junk bus nack counter                                */
+#define SH_LB_NACK_STATUS_JUNK_NACK_SHFT         32
+#define SH_LB_NACK_STATUS_JUNK_NACK_MASK         0x0000ffff00000000
+
+/*   SH_LB_NACK_STATUS_CB_TIMEOUT_COUNT                                 */
+/*   Description:  Conveyor belt time out counter                       */
+#define SH_LB_NACK_STATUS_CB_TIMEOUT_COUNT_SHFT  48
+#define SH_LB_NACK_STATUS_CB_TIMEOUT_COUNT_MASK  0x0fff000000000000
+
+/*   SH_LB_NACK_STATUS_CB_STATE                                         */
+/*   Description:  Conveyor belt state                                  */
+#define SH_LB_NACK_STATUS_CB_STATE_SHFT          60
+#define SH_LB_NACK_STATUS_CB_STATE_MASK          0x3000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_LB_TRIGGER_COMPARE"                   */
+/*                    LB Test-point Trigger Compare                     */
+/* ==================================================================== */
+
+#define SH_LB_TRIGGER_COMPARE                    0x0000000110050780
+#define SH_LB_TRIGGER_COMPARE_MASK               0x00000000ffffffff
+#define SH_LB_TRIGGER_COMPARE_INIT               0x0000000000000000
+
+/*   SH_LB_TRIGGER_COMPARE_MASK                                         */
+/*   Description:  Mask to select Debug bits for trigger generation     */
+#define SH_LB_TRIGGER_COMPARE_MASK_SHFT          0
+#define SH_LB_TRIGGER_COMPARE_MASK_MASK          0x00000000ffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_LB_TRIGGER_DATA"                     */
+/*                  LB Test-point Trigger Compare Data                  */
+/* ==================================================================== */
+
+#define SH_LB_TRIGGER_DATA                       0x0000000110050800
+#define SH_LB_TRIGGER_DATA_MASK                  0x00000000ffffffff
+#define SH_LB_TRIGGER_DATA_INIT                  0x00000000ffffffff
+
+/*   SH_LB_TRIGGER_DATA_COMPARE_PATTERN                                 */
+/*   Description:  debug bit pattern for trigger generation             */
+#define SH_LB_TRIGGER_DATA_COMPARE_PATTERN_SHFT  0
+#define SH_LB_TRIGGER_DATA_COMPARE_PATTERN_MASK  0x00000000ffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_PI_AEC_CONFIG"                      */
+/*              PI Adaptive Error Correction Configuration              */
+/* ==================================================================== */
+
+#define SH_PI_AEC_CONFIG                         0x0000000120050000
+#define SH_PI_AEC_CONFIG_MASK                    0x0000000000000007
+#define SH_PI_AEC_CONFIG_INIT                    0x0000000000000000
+
+/*   SH_PI_AEC_CONFIG_MODE                                              */
+/*   Description:  AEC Operation Mode                                   */
+#define SH_PI_AEC_CONFIG_MODE_SHFT               0
+#define SH_PI_AEC_CONFIG_MODE_MASK               0x0000000000000007
+
+/* ==================================================================== */
+/*                   Register "SH_PI_AFI_ERROR_MASK"                    */
+/*                          PI AFI Error Mask                           */
+/* ==================================================================== */
+
+#define SH_PI_AFI_ERROR_MASK                     0x0000000120050080
+#define SH_PI_AFI_ERROR_MASK_MASK                0x00000007ffe00000
+#define SH_PI_AFI_ERROR_MASK_INIT                0x00000007ffe00000
+
+/*   SH_PI_AFI_ERROR_MASK_HUNG_BUS                                      */
+/*   Description:  FSB is hung                                          */
+#define SH_PI_AFI_ERROR_MASK_HUNG_BUS_SHFT       21
+#define SH_PI_AFI_ERROR_MASK_HUNG_BUS_MASK       0x0000000000200000
+
+/*   SH_PI_AFI_ERROR_MASK_RSP_PARITY                                    */
+/*   Description:  Parity error detecte during response phase           */
+#define SH_PI_AFI_ERROR_MASK_RSP_PARITY_SHFT     22
+#define SH_PI_AFI_ERROR_MASK_RSP_PARITY_MASK     0x0000000000400000
+
+/*   SH_PI_AFI_ERROR_MASK_IOQ_OVERRUN                                   */
+/*   Description:  Over run error detected on IOQ                       */
+#define SH_PI_AFI_ERROR_MASK_IOQ_OVERRUN_SHFT    23
+#define SH_PI_AFI_ERROR_MASK_IOQ_OVERRUN_MASK    0x0000000000800000
+
+/*   SH_PI_AFI_ERROR_MASK_REQ_FORMAT                                    */
+/*   Description:  FSB request format not supported                     */
+#define SH_PI_AFI_ERROR_MASK_REQ_FORMAT_SHFT     24
+#define SH_PI_AFI_ERROR_MASK_REQ_FORMAT_MASK     0x0000000001000000
+
+/*   SH_PI_AFI_ERROR_MASK_ADDR_ACCESS                                   */
+/*   Description:  Access to Address is not supported                   */
+#define SH_PI_AFI_ERROR_MASK_ADDR_ACCESS_SHFT    25
+#define SH_PI_AFI_ERROR_MASK_ADDR_ACCESS_MASK    0x0000000002000000
+
+/*   SH_PI_AFI_ERROR_MASK_REQ_PARITY                                    */
+/*   Description:  Parity error detected during request phase           */
+#define SH_PI_AFI_ERROR_MASK_REQ_PARITY_SHFT     26
+#define SH_PI_AFI_ERROR_MASK_REQ_PARITY_MASK     0x0000000004000000
+
+/*   SH_PI_AFI_ERROR_MASK_ADDR_PARITY                                   */
+/*   Description:  Parity error detected on address                     */
+#define SH_PI_AFI_ERROR_MASK_ADDR_PARITY_SHFT    27
+#define SH_PI_AFI_ERROR_MASK_ADDR_PARITY_MASK    0x0000000008000000
+
+/*   SH_PI_AFI_ERROR_MASK_SHUB_FSB_DQE                                  */
+/*   Description:  SHUB_FSB_DQE                                         */
+#define SH_PI_AFI_ERROR_MASK_SHUB_FSB_DQE_SHFT   28
+#define SH_PI_AFI_ERROR_MASK_SHUB_FSB_DQE_MASK   0x0000000010000000
+
+/*   SH_PI_AFI_ERROR_MASK_SHUB_FSB_UCE                                  */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_AFI_ERROR_MASK_SHUB_FSB_UCE_SHFT   29
+#define SH_PI_AFI_ERROR_MASK_SHUB_FSB_UCE_MASK   0x0000000020000000
+
+/*   SH_PI_AFI_ERROR_MASK_SHUB_FSB_CE                                   */
+/*   Description:  An correctable ECC error was detected                */
+#define SH_PI_AFI_ERROR_MASK_SHUB_FSB_CE_SHFT    30
+#define SH_PI_AFI_ERROR_MASK_SHUB_FSB_CE_MASK    0x0000000040000000
+
+/*   SH_PI_AFI_ERROR_MASK_LIVELOCK                                      */
+/*   Description:  AFI livelock error was detected                      */
+#define SH_PI_AFI_ERROR_MASK_LIVELOCK_SHFT       31
+#define SH_PI_AFI_ERROR_MASK_LIVELOCK_MASK       0x0000000080000000
+
+/*   SH_PI_AFI_ERROR_MASK_BAD_SNOOP                                     */
+/*   Description:  AFI bad snoop error was detected                     */
+#define SH_PI_AFI_ERROR_MASK_BAD_SNOOP_SHFT      32
+#define SH_PI_AFI_ERROR_MASK_BAD_SNOOP_MASK      0x0000000100000000
+
+/*   SH_PI_AFI_ERROR_MASK_FSB_TBL_MISS                                  */
+/*   Description:  AFI FSB request table miss error was detected        */
+#define SH_PI_AFI_ERROR_MASK_FSB_TBL_MISS_SHFT   33
+#define SH_PI_AFI_ERROR_MASK_FSB_TBL_MISS_MASK   0x0000000200000000
+
+/*   SH_PI_AFI_ERROR_MASK_MSG_LEN                                       */
+/*   Description:  Runt or Obese message received from SIC              */
+#define SH_PI_AFI_ERROR_MASK_MSG_LEN_SHFT        34
+#define SH_PI_AFI_ERROR_MASK_MSG_LEN_MASK        0x0000000400000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_AFI_TEST_POINT_COMPARE"                */
+/*                      PI AFI Test Point Compare                       */
+/* ==================================================================== */
+
+#define SH_PI_AFI_TEST_POINT_COMPARE             0x0000000120050100
+#define SH_PI_AFI_TEST_POINT_COMPARE_MASK        0xffffffffffffffff
+#define SH_PI_AFI_TEST_POINT_COMPARE_INIT        0xffffffff00000000
+
+/*   SH_PI_AFI_TEST_POINT_COMPARE_COMPARE_MASK                          */
+/*   Description:  Mask to select Debug bits for trigger generation     */
+#define SH_PI_AFI_TEST_POINT_COMPARE_COMPARE_MASK_SHFT 0
+#define SH_PI_AFI_TEST_POINT_COMPARE_COMPARE_MASK_MASK 0x00000000ffffffff
+
+/*   SH_PI_AFI_TEST_POINT_COMPARE_COMPARE_PATTERN                       */
+/*   Description:  debug bit pattern for trigger generation             */
+#define SH_PI_AFI_TEST_POINT_COMPARE_COMPARE_PATTERN_SHFT 32
+#define SH_PI_AFI_TEST_POINT_COMPARE_COMPARE_PATTERN_MASK 0xffffffff00000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_AFI_TEST_POINT_SELECT"                */
+/*                       PI AFI Test Point Select                       */
+/* ==================================================================== */
+
+#define SH_PI_AFI_TEST_POINT_SELECT              0x0000000120050180
+#define SH_PI_AFI_TEST_POINT_SELECT_MASK         0xff7f7f7f7f7f7f7f
+#define SH_PI_AFI_TEST_POINT_SELECT_INIT         0x0000000000000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL                    */
+/*   Description:  Nibble 0: Word Select                                */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL_SHFT 0
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL_MASK 0x000000000000000f
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL                     */
+/*   Description:  Nibble 0: Nibble Select                              */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL                    */
+/*   Description:  Nibble 1: Word Select                                */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL_SHFT 8
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL_MASK 0x0000000000000f00
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL                     */
+/*   Description:  Nibble 1: Nibble Select                              */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL                    */
+/*   Description:  Nibble 2: Word Select                                */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL_SHFT 16
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL_MASK 0x00000000000f0000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL                     */
+/*   Description:  Nibble 2: Nibble Select                              */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL                    */
+/*   Description:  Nibble 3: Word Select                                */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL_SHFT 24
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL_MASK 0x000000000f000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL                     */
+/*   Description:  Nibble 3: Nibble Select                              */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL                    */
+/*   Description:  Nibble 4: Word Select                                */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL_SHFT 32
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL_MASK 0x0000000f00000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL                     */
+/*   Description:  Nibble 4: Nibble Select                              */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL                    */
+/*   Description:  Nibble 5: Word Select                                */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL_SHFT 40
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL_MASK 0x00000f0000000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL                     */
+/*   Description:  Nibble 5: Nibble Select                              */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL                    */
+/*   Description:  Nibble 6: Word Select                                */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL_SHFT 48
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL_MASK 0x000f000000000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL                     */
+/*   Description:  Nibble 6: Nibble Select                              */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL                    */
+/*   Description:  Nibble 7: Word Select                                */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL_SHFT 56
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL_MASK 0x0f00000000000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL                     */
+/*   Description:  Nibble 7: Nibble Select                              */
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_PI_AFI_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/*   SH_PI_AFI_TEST_POINT_SELECT_TRIGGER_ENABLE                         */
+/*   Description:  Trigger Enabled                                      */
+#define SH_PI_AFI_TEST_POINT_SELECT_TRIGGER_ENABLE_SHFT 63
+#define SH_PI_AFI_TEST_POINT_SELECT_TRIGGER_ENABLE_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*            Register "SH_PI_AFI_TEST_POINT_TRIGGER_SELECT"            */
+/*                  PI CRBC Test Point Trigger Select                   */
+/* ==================================================================== */
+
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT      0x0000000120050200
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_MASK 0x7f7f7f7f7f7f7f7f
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_INIT 0x0000000000000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL           */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL_SHFT 0
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL_MASK 0x000000000000000f
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL            */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL_SHFT 4
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL           */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL_SHFT 8
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL_MASK 0x0000000000000f00
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL            */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL_SHFT 12
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL           */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL_SHFT 16
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL_MASK 0x00000000000f0000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL            */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL_SHFT 20
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL           */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL_SHFT 24
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL_MASK 0x000000000f000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL            */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL_SHFT 28
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL           */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL_SHFT 32
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL_MASK 0x0000000f00000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL            */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL_SHFT 36
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL           */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL_SHFT 40
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL_MASK 0x00000f0000000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL            */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL_SHFT 44
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL           */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL_SHFT 48
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL_MASK 0x000f000000000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL            */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL_SHFT 52
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL           */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL_SHFT 56
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL_MASK 0x0f00000000000000
+
+/*   SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL            */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL_SHFT 60
+#define SH_PI_AFI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PI_AUTO_REPLY_ENABLE"                  */
+/*                         PI Auto Reply Enable                         */
+/* ==================================================================== */
+
+#define SH_PI_AUTO_REPLY_ENABLE                  0x0000000120050280
+#define SH_PI_AUTO_REPLY_ENABLE_MASK             0x0000000000000001
+#define SH_PI_AUTO_REPLY_ENABLE_INIT             0x0000000000000000
+
+/*   SH_PI_AUTO_REPLY_ENABLE_AUTO_REPLY_ENABLE                          */
+/*   Description:  Auto Reply Enabled                                   */
+#define SH_PI_AUTO_REPLY_ENABLE_AUTO_REPLY_ENABLE_SHFT 0
+#define SH_PI_AUTO_REPLY_ENABLE_AUTO_REPLY_ENABLE_MASK 0x0000000000000001
+
+/* ==================================================================== */
+/*                     Register "SH_PI_CAM_CONTROL"                     */
+/*                      CRB CAM MMR Access Control                      */
+/* ==================================================================== */
+
+#define SH_PI_CAM_CONTROL                        0x0000000120050300
+#define SH_PI_CAM_CONTROL_MASK                   0x800000000000037f
+#define SH_PI_CAM_CONTROL_INIT                   0x0000000000000000
+
+/*   SH_PI_CAM_CONTROL_CAM_INDX                                         */
+/*   Description:  CRB CAM Index to perform read/write on.              */
+#define SH_PI_CAM_CONTROL_CAM_INDX_SHFT          0
+#define SH_PI_CAM_CONTROL_CAM_INDX_MASK          0x000000000000007f
+
+/*   SH_PI_CAM_CONTROL_CAM_WRITE                                        */
+/*   Description:  Is CRB CAM MMR function a write.                     */
+#define SH_PI_CAM_CONTROL_CAM_WRITE_SHFT         8
+#define SH_PI_CAM_CONTROL_CAM_WRITE_MASK         0x0000000000000100
+
+/*   SH_PI_CAM_CONTROL_RRB_RD_XFER_CLEAR                                */
+/*   Description:  Clear RRB read tranfer pending.                      */
+#define SH_PI_CAM_CONTROL_RRB_RD_XFER_CLEAR_SHFT 9
+#define SH_PI_CAM_CONTROL_RRB_RD_XFER_CLEAR_MASK 0x0000000000000200
+
+/*   SH_PI_CAM_CONTROL_START                                            */
+/*   Description:  Start CRB CAM read/write operation                   */
+#define SH_PI_CAM_CONTROL_START_SHFT             63
+#define SH_PI_CAM_CONTROL_START_MASK             0x8000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBC_TEST_POINT_COMPARE"               */
+/*                      PI CRBC Test Point Compare                      */
+/* ==================================================================== */
+
+#define SH_PI_CRBC_TEST_POINT_COMPARE            0x0000000120050380
+#define SH_PI_CRBC_TEST_POINT_COMPARE_MASK       0xffffffffffffffff
+#define SH_PI_CRBC_TEST_POINT_COMPARE_INIT       0xffffffff00000000
+
+/*   SH_PI_CRBC_TEST_POINT_COMPARE_COMPARE_MASK                         */
+/*   Description:  Mask to select Debug bits for trigger generation     */
+#define SH_PI_CRBC_TEST_POINT_COMPARE_COMPARE_MASK_SHFT 0
+#define SH_PI_CRBC_TEST_POINT_COMPARE_COMPARE_MASK_MASK 0x00000000ffffffff
+
+/*   SH_PI_CRBC_TEST_POINT_COMPARE_COMPARE_PATTERN                      */
+/*   Description:  debug bit pattern for trigger generation             */
+#define SH_PI_CRBC_TEST_POINT_COMPARE_COMPARE_PATTERN_SHFT 32
+#define SH_PI_CRBC_TEST_POINT_COMPARE_COMPARE_PATTERN_MASK 0xffffffff00000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBC_TEST_POINT_SELECT"                */
+/*                      PI CRBC Test Point Select                       */
+/* ==================================================================== */
+
+#define SH_PI_CRBC_TEST_POINT_SELECT             0x0000000120050400
+#define SH_PI_CRBC_TEST_POINT_SELECT_MASK        0xf777777777777777
+#define SH_PI_CRBC_TEST_POINT_SELECT_INIT        0x0000000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL                   */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL_SHFT 0
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL                    */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL                   */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL_SHFT 8
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL                    */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL                   */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL_SHFT 16
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL                    */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL                   */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL_SHFT 24
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL                    */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL                   */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL_SHFT 32
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL                    */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL                   */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL_SHFT 40
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL                    */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL                   */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL_SHFT 48
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL                    */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL                   */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL_SHFT 56
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL                    */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_PI_CRBC_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_SELECT_TRIGGER_ENABLE                        */
+/*   Description:  Enable trigger on bit 32 of Analyzer data            */
+#define SH_PI_CRBC_TEST_POINT_SELECT_TRIGGER_ENABLE_SHFT 63
+#define SH_PI_CRBC_TEST_POINT_SELECT_TRIGGER_ENABLE_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*           Register "SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT"            */
+/*                  PI CRBC Test Point Trigger Select                   */
+/* ==================================================================== */
+
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT     0x0000000120050480
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_MASK 0x7777777777777777
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_INIT 0x0000000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL          */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL_SHFT 0
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL           */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL_SHFT 4
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL          */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL_SHFT 8
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL           */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL_SHFT 12
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL          */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL_SHFT 16
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL           */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL_SHFT 20
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL          */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL_SHFT 24
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL           */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL_SHFT 28
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL          */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL_SHFT 32
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL           */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL_SHFT 36
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL          */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL_SHFT 40
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL           */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL_SHFT 44
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL          */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL_SHFT 48
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL           */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL_SHFT 52
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL          */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL_SHFT 56
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL           */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL_SHFT 60
+#define SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_PI_CRBP_ERROR_MASK"                   */
+/*                          PI CRBP Error Mask                          */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_ERROR_MASK                    0x0000000120050500
+#define SH_PI_CRBP_ERROR_MASK_MASK               0x00000000001fffff
+#define SH_PI_CRBP_ERROR_MASK_INIT               0x00000000001fffff
+
+/*   SH_PI_CRBP_ERROR_MASK_FSB_PROTO_ERR                                */
+/*   Description:  Mask detection internal protocol table misses        */
+#define SH_PI_CRBP_ERROR_MASK_FSB_PROTO_ERR_SHFT 0
+#define SH_PI_CRBP_ERROR_MASK_FSB_PROTO_ERR_MASK 0x0000000000000001
+
+/*   SH_PI_CRBP_ERROR_MASK_GFX_RP_ERR                                   */
+/*   Description:  Mask graphic reply error detection                   */
+#define SH_PI_CRBP_ERROR_MASK_GFX_RP_ERR_SHFT    1
+#define SH_PI_CRBP_ERROR_MASK_GFX_RP_ERR_MASK    0x0000000000000002
+
+/*   SH_PI_CRBP_ERROR_MASK_XB_PROTO_ERR                                 */
+/*   Description:  Mask detection of external protocol table misses     */
+#define SH_PI_CRBP_ERROR_MASK_XB_PROTO_ERR_SHFT  2
+#define SH_PI_CRBP_ERROR_MASK_XB_PROTO_ERR_MASK  0x0000000000000004
+
+/*   SH_PI_CRBP_ERROR_MASK_MEM_RP_ERR                                   */
+/*   Description:  Mask memory error reply message detection            */
+#define SH_PI_CRBP_ERROR_MASK_MEM_RP_ERR_SHFT    3
+#define SH_PI_CRBP_ERROR_MASK_MEM_RP_ERR_MASK    0x0000000000000008
+
+/*   SH_PI_CRBP_ERROR_MASK_PIO_RP_ERR                                   */
+/*   Description:  Mask PIO reply error message detection               */
+#define SH_PI_CRBP_ERROR_MASK_PIO_RP_ERR_SHFT    4
+#define SH_PI_CRBP_ERROR_MASK_PIO_RP_ERR_MASK    0x0000000000000010
+
+/*   SH_PI_CRBP_ERROR_MASK_MEM_TO_ERR                                   */
+/*   Description:  Mask memory time-out detection                       */
+#define SH_PI_CRBP_ERROR_MASK_MEM_TO_ERR_SHFT    5
+#define SH_PI_CRBP_ERROR_MASK_MEM_TO_ERR_MASK    0x0000000000000020
+
+/*   SH_PI_CRBP_ERROR_MASK_PIO_TO_ERR                                   */
+/*   Description:  Mask PIO time-out detection                          */
+#define SH_PI_CRBP_ERROR_MASK_PIO_TO_ERR_SHFT    6
+#define SH_PI_CRBP_ERROR_MASK_PIO_TO_ERR_MASK    0x0000000000000040
+
+/*   SH_PI_CRBP_ERROR_MASK_FSB_SHUB_UCE                                 */
+/*   Description:  Mask un-correctable ECC error detection              */
+#define SH_PI_CRBP_ERROR_MASK_FSB_SHUB_UCE_SHFT  7
+#define SH_PI_CRBP_ERROR_MASK_FSB_SHUB_UCE_MASK  0x0000000000000080
+
+/*   SH_PI_CRBP_ERROR_MASK_FSB_SHUB_CE                                  */
+/*   Description:  Mask correctable ECC error detection                 */
+#define SH_PI_CRBP_ERROR_MASK_FSB_SHUB_CE_SHFT   8
+#define SH_PI_CRBP_ERROR_MASK_FSB_SHUB_CE_MASK   0x0000000000000100
+
+/*   SH_PI_CRBP_ERROR_MASK_MSG_COLOR_ERR                                */
+/*   Description:  Mask detection of color errors                       */
+#define SH_PI_CRBP_ERROR_MASK_MSG_COLOR_ERR_SHFT 9
+#define SH_PI_CRBP_ERROR_MASK_MSG_COLOR_ERR_MASK 0x0000000000000200
+
+/*   SH_PI_CRBP_ERROR_MASK_MD_RQ_Q_OFLOW                                */
+/*   Description:  Mask MD Request input buffer over flow error         */
+#define SH_PI_CRBP_ERROR_MASK_MD_RQ_Q_OFLOW_SHFT 10
+#define SH_PI_CRBP_ERROR_MASK_MD_RQ_Q_OFLOW_MASK 0x0000000000000400
+
+/*   SH_PI_CRBP_ERROR_MASK_MD_RP_Q_OFLOW                                */
+/*   Description:  Mask MD Reply input buffer over flow error           */
+#define SH_PI_CRBP_ERROR_MASK_MD_RP_Q_OFLOW_SHFT 11
+#define SH_PI_CRBP_ERROR_MASK_MD_RP_Q_OFLOW_MASK 0x0000000000000800
+
+/*   SH_PI_CRBP_ERROR_MASK_XN_RQ_Q_OFLOW                                */
+/*   Description:  Mask XN Request input buffer over flow error         */
+#define SH_PI_CRBP_ERROR_MASK_XN_RQ_Q_OFLOW_SHFT 12
+#define SH_PI_CRBP_ERROR_MASK_XN_RQ_Q_OFLOW_MASK 0x0000000000001000
+
+/*   SH_PI_CRBP_ERROR_MASK_XN_RP_Q_OFLOW                                */
+/*   Description:  Mask XN Reply input buffer over flow error           */
+#define SH_PI_CRBP_ERROR_MASK_XN_RP_Q_OFLOW_SHFT 13
+#define SH_PI_CRBP_ERROR_MASK_XN_RP_Q_OFLOW_MASK 0x0000000000002000
+
+/*   SH_PI_CRBP_ERROR_MASK_NACK_OFLOW                                   */
+/*   Description:  Mask NACK over flow error                            */
+#define SH_PI_CRBP_ERROR_MASK_NACK_OFLOW_SHFT    14
+#define SH_PI_CRBP_ERROR_MASK_NACK_OFLOW_MASK    0x0000000000004000
+
+/*   SH_PI_CRBP_ERROR_MASK_GFX_INT_0                                    */
+/*   Description:  Mask GFX transfer interrupt for CPU 0                */
+#define SH_PI_CRBP_ERROR_MASK_GFX_INT_0_SHFT     15
+#define SH_PI_CRBP_ERROR_MASK_GFX_INT_0_MASK     0x0000000000008000
+
+/*   SH_PI_CRBP_ERROR_MASK_GFX_INT_1                                    */
+/*   Description:  Mask GFX transfer interrupt for CPU 1                */
+#define SH_PI_CRBP_ERROR_MASK_GFX_INT_1_SHFT     16
+#define SH_PI_CRBP_ERROR_MASK_GFX_INT_1_MASK     0x0000000000010000
+
+/*   SH_PI_CRBP_ERROR_MASK_MD_RQ_CRD_OFLOW                              */
+/*   Description:  Mask MD Request Credit Overflow Error                */
+#define SH_PI_CRBP_ERROR_MASK_MD_RQ_CRD_OFLOW_SHFT 17
+#define SH_PI_CRBP_ERROR_MASK_MD_RQ_CRD_OFLOW_MASK 0x0000000000020000
+
+/*   SH_PI_CRBP_ERROR_MASK_MD_RP_CRD_OFLOW                              */
+/*   Description:  Mask MD Reply Credit Overflow Error                  */
+#define SH_PI_CRBP_ERROR_MASK_MD_RP_CRD_OFLOW_SHFT 18
+#define SH_PI_CRBP_ERROR_MASK_MD_RP_CRD_OFLOW_MASK 0x0000000000040000
+
+/*   SH_PI_CRBP_ERROR_MASK_XN_RQ_CRD_OFLOW                              */
+/*   Description:  Mask XN Request Credit Overflow Error                */
+#define SH_PI_CRBP_ERROR_MASK_XN_RQ_CRD_OFLOW_SHFT 19
+#define SH_PI_CRBP_ERROR_MASK_XN_RQ_CRD_OFLOW_MASK 0x0000000000080000
+
+/*   SH_PI_CRBP_ERROR_MASK_XN_RP_CRD_OFLOW                              */
+/*   Description:  Mask XN Reply Credit Overflow Error                  */
+#define SH_PI_CRBP_ERROR_MASK_XN_RP_CRD_OFLOW_SHFT 20
+#define SH_PI_CRBP_ERROR_MASK_XN_RP_CRD_OFLOW_MASK 0x0000000000100000
+
+/* ==================================================================== */
+/*                Register "SH_PI_CRBP_FSB_PIPE_COMPARE"                */
+/*                        CRBP FSB Pipe Compare                         */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_FSB_PIPE_COMPARE              0x0000000120050580
+#define SH_PI_CRBP_FSB_PIPE_COMPARE_MASK         0x001fffffffffffff
+#define SH_PI_CRBP_FSB_PIPE_COMPARE_INIT         0x0000000000000000
+
+/*   SH_PI_CRBP_FSB_PIPE_COMPARE_COMPARE_ADDRESS                        */
+/*   Description:  Address A or B to compare against                    */
+#define SH_PI_CRBP_FSB_PIPE_COMPARE_COMPARE_ADDRESS_SHFT 0
+#define SH_PI_CRBP_FSB_PIPE_COMPARE_COMPARE_ADDRESS_MASK 0x00007fffffffffff
+
+/*   SH_PI_CRBP_FSB_PIPE_COMPARE_COMPARE_REQ                            */
+/*   Description:  REQa or REQb value to compare against                */
+#define SH_PI_CRBP_FSB_PIPE_COMPARE_COMPARE_REQ_SHFT 47
+#define SH_PI_CRBP_FSB_PIPE_COMPARE_COMPARE_REQ_MASK 0x001f800000000000
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CRBP_FSB_PIPE_MASK"                  */
+/*                          CRBP Compare Mask                           */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_FSB_PIPE_MASK                 0x0000000120050600
+#define SH_PI_CRBP_FSB_PIPE_MASK_MASK            0x001fffffffffffff
+#define SH_PI_CRBP_FSB_PIPE_MASK_INIT            0x0000000000000000
+
+/*   SH_PI_CRBP_FSB_PIPE_MASK_COMPARE_ADDRESS_MASK                      */
+/*   Description:  Address A or B mask values                           */
+#define SH_PI_CRBP_FSB_PIPE_MASK_COMPARE_ADDRESS_MASK_SHFT 0
+#define SH_PI_CRBP_FSB_PIPE_MASK_COMPARE_ADDRESS_MASK_MASK 0x00007fffffffffff
+
+/*   SH_PI_CRBP_FSB_PIPE_MASK_COMPARE_REQ_MASK                          */
+/*   Description:  REQa or REQb mask values                             */
+#define SH_PI_CRBP_FSB_PIPE_MASK_COMPARE_REQ_MASK_SHFT 47
+#define SH_PI_CRBP_FSB_PIPE_MASK_COMPARE_REQ_MASK_MASK 0x001f800000000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBP_TEST_POINT_COMPARE"               */
+/*                      PI CRBP Test Point Compare                      */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_TEST_POINT_COMPARE            0x0000000120050680
+#define SH_PI_CRBP_TEST_POINT_COMPARE_MASK       0xffffffffffffffff
+#define SH_PI_CRBP_TEST_POINT_COMPARE_INIT       0xffffffff00000000
+
+/*   SH_PI_CRBP_TEST_POINT_COMPARE_COMPARE_MASK                         */
+/*   Description:  Mask to select Debug bits for trigger generation     */
+#define SH_PI_CRBP_TEST_POINT_COMPARE_COMPARE_MASK_SHFT 0
+#define SH_PI_CRBP_TEST_POINT_COMPARE_COMPARE_MASK_MASK 0x00000000ffffffff
+
+/*   SH_PI_CRBP_TEST_POINT_COMPARE_COMPARE_PATTERN                      */
+/*   Description:  debug bit pattern for trigger generation             */
+#define SH_PI_CRBP_TEST_POINT_COMPARE_COMPARE_PATTERN_SHFT 32
+#define SH_PI_CRBP_TEST_POINT_COMPARE_COMPARE_PATTERN_MASK 0xffffffff00000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBP_TEST_POINT_SELECT"                */
+/*                      PI CRBP Test Point Select                       */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_TEST_POINT_SELECT             0x0000000120050700
+#define SH_PI_CRBP_TEST_POINT_SELECT_MASK        0xf777777777777777
+#define SH_PI_CRBP_TEST_POINT_SELECT_INIT        0x0000000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL                   */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL_SHFT 0
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL                    */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL                   */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL_SHFT 8
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL                    */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL                   */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL_SHFT 16
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL                    */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL                   */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL_SHFT 24
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL                    */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL                   */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL_SHFT 32
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL                    */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL                   */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL_SHFT 40
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL                    */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL                   */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL_SHFT 48
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL                    */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL                   */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL_SHFT 56
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL                    */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_PI_CRBP_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_SELECT_TRIGGER_ENABLE                        */
+/*   Description:  Enable trigger on bit 32 of Analyzer data            */
+#define SH_PI_CRBP_TEST_POINT_SELECT_TRIGGER_ENABLE_SHFT 63
+#define SH_PI_CRBP_TEST_POINT_SELECT_TRIGGER_ENABLE_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*           Register "SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT"            */
+/*                  PI CRBP Test Point Trigger Select                   */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT     0x0000000120050780
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_MASK 0x7777777777777777
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_INIT 0x0000000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL          */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL_SHFT 0
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL           */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL_SHFT 4
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL          */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL_SHFT 8
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL           */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL_SHFT 12
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL          */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL_SHFT 16
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL           */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL_SHFT 20
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL          */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL_SHFT 24
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL           */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL_SHFT 28
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL          */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL_SHFT 32
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL           */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL_SHFT 36
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL          */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL_SHFT 40
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL           */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL_SHFT 44
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL          */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL_SHFT 48
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL           */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL_SHFT 52
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL          */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL_SHFT 56
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL           */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL_SHFT 60
+#define SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBP_XB_PIPE_COMPARE_0"                */
+/*                         CRBP XB Pipe Compare                         */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_XB_PIPE_COMPARE_0             0x0000000120050800
+#define SH_PI_CRBP_XB_PIPE_COMPARE_0_MASK        0x007fffffffffffff
+#define SH_PI_CRBP_XB_PIPE_COMPARE_0_INIT        0x0000000000000000
+
+/*   SH_PI_CRBP_XB_PIPE_COMPARE_0_COMPARE_ADDRESS                       */
+/*   Description:  Address to compare against                           */
+#define SH_PI_CRBP_XB_PIPE_COMPARE_0_COMPARE_ADDRESS_SHFT 0
+#define SH_PI_CRBP_XB_PIPE_COMPARE_0_COMPARE_ADDRESS_MASK 0x00007fffffffffff
+
+/*   SH_PI_CRBP_XB_PIPE_COMPARE_0_COMPARE_COMMAND                       */
+/*   Description:  SN2NET Command to compare against                    */
+#define SH_PI_CRBP_XB_PIPE_COMPARE_0_COMPARE_COMMAND_SHFT 47
+#define SH_PI_CRBP_XB_PIPE_COMPARE_0_COMPARE_COMMAND_MASK 0x007f800000000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBP_XB_PIPE_COMPARE_1"                */
+/*                         CRBP XB Pipe Compare                         */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1             0x0000000120050880
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1_MASK        0x000001ff3fff3fff
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1_INIT        0x0000000000000000
+
+/*   SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_SOURCE                        */
+/*   Description:  Source to compare against                            */
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_SOURCE_SHFT 0
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_SOURCE_MASK 0x0000000000003fff
+
+/*   SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_SUPPLEMENTAL                  */
+/*   Description:  Supplemental to compare against                      */
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_SUPPLEMENTAL_SHFT 16
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_SUPPLEMENTAL_MASK 0x000000003fff0000
+
+/*   SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_ECHO                          */
+/*   Description:  Echo to compare against                              */
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_ECHO_SHFT 32
+#define SH_PI_CRBP_XB_PIPE_COMPARE_1_COMPARE_ECHO_MASK 0x000001ff00000000
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CRBP_XB_PIPE_MASK_0"                 */
+/*                     CRBP Compare Mask Register 1                     */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_XB_PIPE_MASK_0                0x0000000120050900
+#define SH_PI_CRBP_XB_PIPE_MASK_0_MASK           0x007fffffffffffff
+#define SH_PI_CRBP_XB_PIPE_MASK_0_INIT           0x0000000000000000
+
+/*   SH_PI_CRBP_XB_PIPE_MASK_0_COMPARE_ADDRESS_MASK                     */
+/*   Description:  Address to compare against                           */
+#define SH_PI_CRBP_XB_PIPE_MASK_0_COMPARE_ADDRESS_MASK_SHFT 0
+#define SH_PI_CRBP_XB_PIPE_MASK_0_COMPARE_ADDRESS_MASK_MASK 0x00007fffffffffff
+
+/*   SH_PI_CRBP_XB_PIPE_MASK_0_COMPARE_COMMAND_MASK                     */
+/*   Description:  SN2NET Command to compare against                    */
+#define SH_PI_CRBP_XB_PIPE_MASK_0_COMPARE_COMMAND_MASK_SHFT 47
+#define SH_PI_CRBP_XB_PIPE_MASK_0_COMPARE_COMMAND_MASK_MASK 0x007f800000000000
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CRBP_XB_PIPE_MASK_1"                 */
+/*                 CRBP XB Pipe Compare Mask Register 1                 */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_XB_PIPE_MASK_1                0x0000000120050980
+#define SH_PI_CRBP_XB_PIPE_MASK_1_MASK           0x000001ff3fff3fff
+#define SH_PI_CRBP_XB_PIPE_MASK_1_INIT           0x0000000000000000
+
+/*   SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_SOURCE_MASK                      */
+/*   Description:  Source to compare against                            */
+#define SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_SOURCE_MASK_SHFT 0
+#define SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_SOURCE_MASK_MASK 0x0000000000003fff
+
+/*   SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_SUPPLEMENTAL_MASK                */
+/*   Description:  Supplemental to compare against                      */
+#define SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_SUPPLEMENTAL_MASK_SHFT 16
+#define SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_SUPPLEMENTAL_MASK_MASK 0x000000003fff0000
+
+/*   SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_ECHO_MASK                        */
+/*   Description:  Echo to compare against                              */
+#define SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_ECHO_MASK_SHFT 32
+#define SH_PI_CRBP_XB_PIPE_MASK_1_COMPARE_ECHO_MASK_MASK 0x000001ff00000000
+
+/* ==================================================================== */
+/*                  Register "SH_PI_DPC_QUEUE_CONFIG"                   */
+/*                       DPC Queue Configuration                        */
+/* ==================================================================== */
+
+#define SH_PI_DPC_QUEUE_CONFIG                   0x0000000120050a00
+#define SH_PI_DPC_QUEUE_CONFIG_MASK              0x000000001f1f1f1f
+#define SH_PI_DPC_QUEUE_CONFIG_INIT              0x000000000c010c01
+
+/*   SH_PI_DPC_QUEUE_CONFIG_DWCQ_AE_LEVEL                               */
+/*   Description:  DXB WTL Command Queue Almost Empty Level             */
+#define SH_PI_DPC_QUEUE_CONFIG_DWCQ_AE_LEVEL_SHFT 0
+#define SH_PI_DPC_QUEUE_CONFIG_DWCQ_AE_LEVEL_MASK 0x000000000000001f
+
+/*   SH_PI_DPC_QUEUE_CONFIG_DWCQ_AF_THRESH                              */
+/*   Description:  DXB WTL Command Queue Almost Full Threshold          */
+#define SH_PI_DPC_QUEUE_CONFIG_DWCQ_AF_THRESH_SHFT 8
+#define SH_PI_DPC_QUEUE_CONFIG_DWCQ_AF_THRESH_MASK 0x0000000000001f00
+
+/*   SH_PI_DPC_QUEUE_CONFIG_FWCQ_AE_LEVEL                               */
+/*   Description:  FSB WTL Command Queue Almost Empty Level             */
+#define SH_PI_DPC_QUEUE_CONFIG_FWCQ_AE_LEVEL_SHFT 16
+#define SH_PI_DPC_QUEUE_CONFIG_FWCQ_AE_LEVEL_MASK 0x00000000001f0000
+
+/*   SH_PI_DPC_QUEUE_CONFIG_FWCQ_AF_THRESH                              */
+/*   Description:  FSB WTL Command Queue Almost Full Threshold          */
+#define SH_PI_DPC_QUEUE_CONFIG_FWCQ_AF_THRESH_SHFT 24
+#define SH_PI_DPC_QUEUE_CONFIG_FWCQ_AF_THRESH_MASK 0x000000001f000000
+
+/* ==================================================================== */
+/*                     Register "SH_PI_ERROR_MASK"                      */
+/*                            PI Error Mask                             */
+/* ==================================================================== */
+
+#define SH_PI_ERROR_MASK                         0x0000000120050a80
+#define SH_PI_ERROR_MASK_MASK                    0x00000007ffffffff
+#define SH_PI_ERROR_MASK_INIT                    0x00000007ffffffff
+
+/*   SH_PI_ERROR_MASK_FSB_PROTO_ERR                                     */
+/*   Description:  Mask detection of internal protocol table misses     */
+#define SH_PI_ERROR_MASK_FSB_PROTO_ERR_SHFT      0
+#define SH_PI_ERROR_MASK_FSB_PROTO_ERR_MASK      0x0000000000000001
+
+/*   SH_PI_ERROR_MASK_GFX_RP_ERR                                        */
+/*   Description:  Mask graphic reply error message error detection     */
+#define SH_PI_ERROR_MASK_GFX_RP_ERR_SHFT         1
+#define SH_PI_ERROR_MASK_GFX_RP_ERR_MASK         0x0000000000000002
+
+/*   SH_PI_ERROR_MASK_XB_PROTO_ERR                                      */
+/*   Description:  Mask detection of external protocol table misses     */
+#define SH_PI_ERROR_MASK_XB_PROTO_ERR_SHFT       2
+#define SH_PI_ERROR_MASK_XB_PROTO_ERR_MASK       0x0000000000000004
+
+/*   SH_PI_ERROR_MASK_MEM_RP_ERR                                        */
+/*   Description:  Mask memory reply error detection                    */
+#define SH_PI_ERROR_MASK_MEM_RP_ERR_SHFT         3
+#define SH_PI_ERROR_MASK_MEM_RP_ERR_MASK         0x0000000000000008
+
+/*   SH_PI_ERROR_MASK_PIO_RP_ERR                                        */
+/*   Description:  Mask PIO reply error detection                       */
+#define SH_PI_ERROR_MASK_PIO_RP_ERR_SHFT         4
+#define SH_PI_ERROR_MASK_PIO_RP_ERR_MASK         0x0000000000000010
+
+/*   SH_PI_ERROR_MASK_MEM_TO_ERR                                        */
+/*   Description:  Mask CRB time-out errors                             */
+#define SH_PI_ERROR_MASK_MEM_TO_ERR_SHFT         5
+#define SH_PI_ERROR_MASK_MEM_TO_ERR_MASK         0x0000000000000020
+
+/*   SH_PI_ERROR_MASK_PIO_TO_ERR                                        */
+/*   Description:  Mask PIO time-out errors                             */
+#define SH_PI_ERROR_MASK_PIO_TO_ERR_SHFT         6
+#define SH_PI_ERROR_MASK_PIO_TO_ERR_MASK         0x0000000000000040
+
+/*   SH_PI_ERROR_MASK_FSB_SHUB_UCE                                      */
+/*   Description:  Mask un-correctable ECC error detection              */
+#define SH_PI_ERROR_MASK_FSB_SHUB_UCE_SHFT       7
+#define SH_PI_ERROR_MASK_FSB_SHUB_UCE_MASK       0x0000000000000080
+
+/*   SH_PI_ERROR_MASK_FSB_SHUB_CE                                       */
+/*   Description:  Mask correctable ECC error detection                 */
+#define SH_PI_ERROR_MASK_FSB_SHUB_CE_SHFT        8
+#define SH_PI_ERROR_MASK_FSB_SHUB_CE_MASK        0x0000000000000100
+
+/*   SH_PI_ERROR_MASK_MSG_COLOR_ERR                                     */
+/*   Description:  Mask message color error detection                   */
+#define SH_PI_ERROR_MASK_MSG_COLOR_ERR_SHFT      9
+#define SH_PI_ERROR_MASK_MSG_COLOR_ERR_MASK      0x0000000000000200
+
+/*   SH_PI_ERROR_MASK_MD_RQ_Q_OFLOW                                     */
+/*   Description:  Mask MD Request input buffer over flow error         */
+#define SH_PI_ERROR_MASK_MD_RQ_Q_OFLOW_SHFT      10
+#define SH_PI_ERROR_MASK_MD_RQ_Q_OFLOW_MASK      0x0000000000000400
+
+/*   SH_PI_ERROR_MASK_MD_RP_Q_OFLOW                                     */
+/*   Description:  Mask MD Reply input buffer over flow error           */
+#define SH_PI_ERROR_MASK_MD_RP_Q_OFLOW_SHFT      11
+#define SH_PI_ERROR_MASK_MD_RP_Q_OFLOW_MASK      0x0000000000000800
+
+/*   SH_PI_ERROR_MASK_XN_RQ_Q_OFLOW                                     */
+/*   Description:  Mask XN Request input buffer over flow error         */
+#define SH_PI_ERROR_MASK_XN_RQ_Q_OFLOW_SHFT      12
+#define SH_PI_ERROR_MASK_XN_RQ_Q_OFLOW_MASK      0x0000000000001000
+
+/*   SH_PI_ERROR_MASK_XN_RP_Q_OFLOW                                     */
+/*   Description:  Mask XN Reply input buffer over flow error           */
+#define SH_PI_ERROR_MASK_XN_RP_Q_OFLOW_SHFT      13
+#define SH_PI_ERROR_MASK_XN_RP_Q_OFLOW_MASK      0x0000000000002000
+
+/*   SH_PI_ERROR_MASK_NACK_OFLOW                                        */
+/*   Description:  Mask NACK over flow error                            */
+#define SH_PI_ERROR_MASK_NACK_OFLOW_SHFT         14
+#define SH_PI_ERROR_MASK_NACK_OFLOW_MASK         0x0000000000004000
+
+/*   SH_PI_ERROR_MASK_GFX_INT_0                                         */
+/*   Description:  Mask GFX transfer interrupt for CPU 0                */
+#define SH_PI_ERROR_MASK_GFX_INT_0_SHFT          15
+#define SH_PI_ERROR_MASK_GFX_INT_0_MASK          0x0000000000008000
+
+/*   SH_PI_ERROR_MASK_GFX_INT_1                                         */
+/*   Description:  Mask GFX transfer interrupt for CPU 1                */
+#define SH_PI_ERROR_MASK_GFX_INT_1_SHFT          16
+#define SH_PI_ERROR_MASK_GFX_INT_1_MASK          0x0000000000010000
+
+/*   SH_PI_ERROR_MASK_MD_RQ_CRD_OFLOW                                   */
+/*   Description:  Mask MD Request Credit Overflow Error                */
+#define SH_PI_ERROR_MASK_MD_RQ_CRD_OFLOW_SHFT    17
+#define SH_PI_ERROR_MASK_MD_RQ_CRD_OFLOW_MASK    0x0000000000020000
+
+/*   SH_PI_ERROR_MASK_MD_RP_CRD_OFLOW                                   */
+/*   Description:  Mask MD Reply Credit Overflow Error                  */
+#define SH_PI_ERROR_MASK_MD_RP_CRD_OFLOW_SHFT    18
+#define SH_PI_ERROR_MASK_MD_RP_CRD_OFLOW_MASK    0x0000000000040000
+
+/*   SH_PI_ERROR_MASK_XN_RQ_CRD_OFLOW                                   */
+/*   Description:  Mask XN Request Credit Overflow Error                */
+#define SH_PI_ERROR_MASK_XN_RQ_CRD_OFLOW_SHFT    19
+#define SH_PI_ERROR_MASK_XN_RQ_CRD_OFLOW_MASK    0x0000000000080000
+
+/*   SH_PI_ERROR_MASK_XN_RP_CRD_OFLOW                                   */
+/*   Description:  Mask XN Reply Credit Overflow Error                  */
+#define SH_PI_ERROR_MASK_XN_RP_CRD_OFLOW_SHFT    20
+#define SH_PI_ERROR_MASK_XN_RP_CRD_OFLOW_MASK    0x0000000000100000
+
+/*   SH_PI_ERROR_MASK_HUNG_BUS                                          */
+/*   Description:  Mask FSB hung error                                  */
+#define SH_PI_ERROR_MASK_HUNG_BUS_SHFT           21
+#define SH_PI_ERROR_MASK_HUNG_BUS_MASK           0x0000000000200000
+
+/*   SH_PI_ERROR_MASK_RSP_PARITY                                        */
+/*   Description:  Parity error detecte during response phase           */
+#define SH_PI_ERROR_MASK_RSP_PARITY_SHFT         22
+#define SH_PI_ERROR_MASK_RSP_PARITY_MASK         0x0000000000400000
+
+/*   SH_PI_ERROR_MASK_IOQ_OVERRUN                                       */
+/*   Description:  Over run error detected on IOQ                       */
+#define SH_PI_ERROR_MASK_IOQ_OVERRUN_SHFT        23
+#define SH_PI_ERROR_MASK_IOQ_OVERRUN_MASK        0x0000000000800000
+
+/*   SH_PI_ERROR_MASK_REQ_FORMAT                                        */
+/*   Description:  FSB request format not supported                     */
+#define SH_PI_ERROR_MASK_REQ_FORMAT_SHFT         24
+#define SH_PI_ERROR_MASK_REQ_FORMAT_MASK         0x0000000001000000
+
+/*   SH_PI_ERROR_MASK_ADDR_ACCESS                                       */
+/*   Description:  Access to Address is not supported                   */
+#define SH_PI_ERROR_MASK_ADDR_ACCESS_SHFT        25
+#define SH_PI_ERROR_MASK_ADDR_ACCESS_MASK        0x0000000002000000
+
+/*   SH_PI_ERROR_MASK_REQ_PARITY                                        */
+/*   Description:  Parity error detected during request phase           */
+#define SH_PI_ERROR_MASK_REQ_PARITY_SHFT         26
+#define SH_PI_ERROR_MASK_REQ_PARITY_MASK         0x0000000004000000
+
+/*   SH_PI_ERROR_MASK_ADDR_PARITY                                       */
+/*   Description:  Parity error detected on address                     */
+#define SH_PI_ERROR_MASK_ADDR_PARITY_SHFT        27
+#define SH_PI_ERROR_MASK_ADDR_PARITY_MASK        0x0000000008000000
+
+/*   SH_PI_ERROR_MASK_SHUB_FSB_DQE                                      */
+/*   Description:  SHUB_FSB_DQE                                         */
+#define SH_PI_ERROR_MASK_SHUB_FSB_DQE_SHFT       28
+#define SH_PI_ERROR_MASK_SHUB_FSB_DQE_MASK       0x0000000010000000
+
+/*   SH_PI_ERROR_MASK_SHUB_FSB_UCE                                      */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_ERROR_MASK_SHUB_FSB_UCE_SHFT       29
+#define SH_PI_ERROR_MASK_SHUB_FSB_UCE_MASK       0x0000000020000000
+
+/*   SH_PI_ERROR_MASK_SHUB_FSB_CE                                       */
+/*   Description:  An correctable ECC error was detected                */
+#define SH_PI_ERROR_MASK_SHUB_FSB_CE_SHFT        30
+#define SH_PI_ERROR_MASK_SHUB_FSB_CE_MASK        0x0000000040000000
+
+/*   SH_PI_ERROR_MASK_LIVELOCK                                          */
+/*   Description:  AFI livelock error was detected                      */
+#define SH_PI_ERROR_MASK_LIVELOCK_SHFT           31
+#define SH_PI_ERROR_MASK_LIVELOCK_MASK           0x0000000080000000
+
+/*   SH_PI_ERROR_MASK_BAD_SNOOP                                         */
+/*   Description:  AFI bad snoop error was detected                     */
+#define SH_PI_ERROR_MASK_BAD_SNOOP_SHFT          32
+#define SH_PI_ERROR_MASK_BAD_SNOOP_MASK          0x0000000100000000
+
+/*   SH_PI_ERROR_MASK_FSB_TBL_MISS                                      */
+/*   Description:  AFI FSB request table miss error was detected        */
+#define SH_PI_ERROR_MASK_FSB_TBL_MISS_SHFT       33
+#define SH_PI_ERROR_MASK_FSB_TBL_MISS_MASK       0x0000000200000000
+
+/*   SH_PI_ERROR_MASK_MSG_LENGTH                                        */
+/*   Description:  Message length error on received message from SIC    */
+#define SH_PI_ERROR_MASK_MSG_LENGTH_SHFT         34
+#define SH_PI_ERROR_MASK_MSG_LENGTH_MASK         0x0000000400000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_EXPRESS_REPLY_CONFIG"                 */
+/*                    PI Express Reply Configuration                    */
+/* ==================================================================== */
+
+#define SH_PI_EXPRESS_REPLY_CONFIG               0x0000000120050b00
+#define SH_PI_EXPRESS_REPLY_CONFIG_MASK          0x0000000000000007
+#define SH_PI_EXPRESS_REPLY_CONFIG_INIT          0x0000000000000001
+
+/*   SH_PI_EXPRESS_REPLY_CONFIG_MODE                                    */
+/*   Description:  Express Reply Mode                                   */
+#define SH_PI_EXPRESS_REPLY_CONFIG_MODE_SHFT     0
+#define SH_PI_EXPRESS_REPLY_CONFIG_MODE_MASK     0x0000000000000007
+
+/* ==================================================================== */
+/*                  Register "SH_PI_FSB_COMPARE_VALUE"                  */
+/*                          FSB Compare Value                           */
+/* ==================================================================== */
+
+#define SH_PI_FSB_COMPARE_VALUE                  0x0000000120050c00
+#define SH_PI_FSB_COMPARE_VALUE_MASK             0xffffffffffffffff
+#define SH_PI_FSB_COMPARE_VALUE_INIT             0x0000000000000000
+
+/*   SH_PI_FSB_COMPARE_VALUE_COMPARE_VALUE                              */
+/*   Description:  Compare value                                        */
+#define SH_PI_FSB_COMPARE_VALUE_COMPARE_VALUE_SHFT 0
+#define SH_PI_FSB_COMPARE_VALUE_COMPARE_VALUE_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PI_FSB_COMPARE_MASK"                   */
+/*                           FSB Compare Mask                           */
+/* ==================================================================== */
+
+#define SH_PI_FSB_COMPARE_MASK                   0x0000000120050b80
+#define SH_PI_FSB_COMPARE_MASK_MASK              0xffffffffffffffff
+#define SH_PI_FSB_COMPARE_MASK_INIT              0x0000000000000000
+
+/*   SH_PI_FSB_COMPARE_MASK_MASK_VALUE                                  */
+/*   Description:  Mask value                                           */
+#define SH_PI_FSB_COMPARE_MASK_MASK_VALUE_SHFT   0
+#define SH_PI_FSB_COMPARE_MASK_MASK_VALUE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_PI_FSB_ERROR_INJECTION"                 */
+/*                     Inject an Error onto the FSB                     */
+/* ==================================================================== */
+
+#define SH_PI_FSB_ERROR_INJECTION                0x0000000120050c80
+#define SH_PI_FSB_ERROR_INJECTION_MASK           0x000000070fff03ff
+#define SH_PI_FSB_ERROR_INJECTION_INIT           0x0000000000000000
+
+/*   SH_PI_FSB_ERROR_INJECTION_RP_PE_TO_FSB                             */
+/*   Description:  Inject a RP# Parity Error onto the FSB               */
+#define SH_PI_FSB_ERROR_INJECTION_RP_PE_TO_FSB_SHFT 0
+#define SH_PI_FSB_ERROR_INJECTION_RP_PE_TO_FSB_MASK 0x0000000000000001
+
+/*   SH_PI_FSB_ERROR_INJECTION_AP0_PE_TO_FSB                            */
+/*   Description:  Inject an AP[0]# Parity Error onto the FSB           */
+#define SH_PI_FSB_ERROR_INJECTION_AP0_PE_TO_FSB_SHFT 1
+#define SH_PI_FSB_ERROR_INJECTION_AP0_PE_TO_FSB_MASK 0x0000000000000002
+
+/*   SH_PI_FSB_ERROR_INJECTION_AP1_PE_TO_FSB                            */
+/*   Description:  Inject an AP[1]# Parity Error onto the FSB           */
+#define SH_PI_FSB_ERROR_INJECTION_AP1_PE_TO_FSB_SHFT 2
+#define SH_PI_FSB_ERROR_INJECTION_AP1_PE_TO_FSB_MASK 0x0000000000000004
+
+/*   SH_PI_FSB_ERROR_INJECTION_RSP_PE_TO_FSB                            */
+/*   Description:  Inject a RSP# Parity Error onto the FSB              */
+#define SH_PI_FSB_ERROR_INJECTION_RSP_PE_TO_FSB_SHFT 3
+#define SH_PI_FSB_ERROR_INJECTION_RSP_PE_TO_FSB_MASK 0x0000000000000008
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW0_CE_TO_FSB                            */
+/*   Description:  Inject a Correctable Error in Doubleword 0 onto the  */
+#define SH_PI_FSB_ERROR_INJECTION_DW0_CE_TO_FSB_SHFT 4
+#define SH_PI_FSB_ERROR_INJECTION_DW0_CE_TO_FSB_MASK 0x0000000000000010
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW0_UCE_TO_FSB                           */
+/*   Description:  Inject an Uncorrectable Error in Doubleword 0 onto   */
+/*  the FSB                                                             */
+#define SH_PI_FSB_ERROR_INJECTION_DW0_UCE_TO_FSB_SHFT 5
+#define SH_PI_FSB_ERROR_INJECTION_DW0_UCE_TO_FSB_MASK 0x0000000000000020
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW1_CE_TO_FSB                            */
+/*   Description:  Inject a Correctable Error in Doubleword 1 onto the  */
+#define SH_PI_FSB_ERROR_INJECTION_DW1_CE_TO_FSB_SHFT 6
+#define SH_PI_FSB_ERROR_INJECTION_DW1_CE_TO_FSB_MASK 0x0000000000000040
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW1_UCE_TO_FSB                           */
+/*   Description:  Inject an Uncorrectable Error in Doubleword 1 onto   */
+/*  the FSB                                                             */
+#define SH_PI_FSB_ERROR_INJECTION_DW1_UCE_TO_FSB_SHFT 7
+#define SH_PI_FSB_ERROR_INJECTION_DW1_UCE_TO_FSB_MASK 0x0000000000000080
+
+/*   SH_PI_FSB_ERROR_INJECTION_IP0_PE_TO_FSB                            */
+/*   Description:  Inject an IP[0]# Parity Error onto the FSB           */
+#define SH_PI_FSB_ERROR_INJECTION_IP0_PE_TO_FSB_SHFT 8
+#define SH_PI_FSB_ERROR_INJECTION_IP0_PE_TO_FSB_MASK 0x0000000000000100
+
+/*   SH_PI_FSB_ERROR_INJECTION_IP1_PE_TO_FSB                            */
+/*   Description:  Inject an IP[1]# Parity Error onto the FSB           */
+#define SH_PI_FSB_ERROR_INJECTION_IP1_PE_TO_FSB_SHFT 9
+#define SH_PI_FSB_ERROR_INJECTION_IP1_PE_TO_FSB_MASK 0x0000000000000200
+
+/*   SH_PI_FSB_ERROR_INJECTION_RP_PE_FROM_FSB                           */
+/*   Description:  Inject a RP# Parity Error When Sampling the FSB      */
+#define SH_PI_FSB_ERROR_INJECTION_RP_PE_FROM_FSB_SHFT 16
+#define SH_PI_FSB_ERROR_INJECTION_RP_PE_FROM_FSB_MASK 0x0000000000010000
+
+/*   SH_PI_FSB_ERROR_INJECTION_AP0_PE_FROM_FSB                          */
+/*   Description:  Inject an AP[0]# Parity Error When Sampling the FSB  */
+#define SH_PI_FSB_ERROR_INJECTION_AP0_PE_FROM_FSB_SHFT 17
+#define SH_PI_FSB_ERROR_INJECTION_AP0_PE_FROM_FSB_MASK 0x0000000000020000
+
+/*   SH_PI_FSB_ERROR_INJECTION_AP1_PE_FROM_FSB                          */
+/*   Description:  Inject an AP[1]# Parity Error When Sampling the FSB  */
+#define SH_PI_FSB_ERROR_INJECTION_AP1_PE_FROM_FSB_SHFT 18
+#define SH_PI_FSB_ERROR_INJECTION_AP1_PE_FROM_FSB_MASK 0x0000000000040000
+
+/*   SH_PI_FSB_ERROR_INJECTION_RSP_PE_FROM_FSB                          */
+/*   Description:  Inject a RSP# Parity Error When Sampling the FSB     */
+#define SH_PI_FSB_ERROR_INJECTION_RSP_PE_FROM_FSB_SHFT 19
+#define SH_PI_FSB_ERROR_INJECTION_RSP_PE_FROM_FSB_MASK 0x0000000000080000
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW0_CE_FROM_FSB                          */
+/*   Description:  Inject a Correctable Error in Doubleword 0 of SIC D  */
+/*  ata Packet 0                                                        */
+#define SH_PI_FSB_ERROR_INJECTION_DW0_CE_FROM_FSB_SHFT 20
+#define SH_PI_FSB_ERROR_INJECTION_DW0_CE_FROM_FSB_MASK 0x0000000000100000
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW0_UCE_FROM_FSB                         */
+/*   Description:  Inject a Uncorrectable Error in Doubleword 0 of SIC  */
+/*   Data Packet 0                                                      */
+#define SH_PI_FSB_ERROR_INJECTION_DW0_UCE_FROM_FSB_SHFT 21
+#define SH_PI_FSB_ERROR_INJECTION_DW0_UCE_FROM_FSB_MASK 0x0000000000200000
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW1_CE_FROM_FSB                          */
+/*   Description:  Inject a Correctable Error in Doubleword 0 of SIC D  */
+/*  ata Packet 0                                                        */
+#define SH_PI_FSB_ERROR_INJECTION_DW1_CE_FROM_FSB_SHFT 22
+#define SH_PI_FSB_ERROR_INJECTION_DW1_CE_FROM_FSB_MASK 0x0000000000400000
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW1_UCE_FROM_FSB                         */
+/*   Description:  Inject a Uncorrectable Error in Doubleword 0 of SIC  */
+/*   Data Packet 0                                                      */
+#define SH_PI_FSB_ERROR_INJECTION_DW1_UCE_FROM_FSB_SHFT 23
+#define SH_PI_FSB_ERROR_INJECTION_DW1_UCE_FROM_FSB_MASK 0x0000000000800000
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW2_CE_FROM_FSB                          */
+/*   Description:  Inject a Correctable Error in Doubleword 0 of SIC D  */
+/*  ata Packet 0                                                        */
+#define SH_PI_FSB_ERROR_INJECTION_DW2_CE_FROM_FSB_SHFT 24
+#define SH_PI_FSB_ERROR_INJECTION_DW2_CE_FROM_FSB_MASK 0x0000000001000000
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW2_UCE_FROM_FSB                         */
+/*   Description:  Inject a Uncorrectable Error in Doubleword 0 of SIC  */
+/*   Data Packet 0                                                      */
+#define SH_PI_FSB_ERROR_INJECTION_DW2_UCE_FROM_FSB_SHFT 25
+#define SH_PI_FSB_ERROR_INJECTION_DW2_UCE_FROM_FSB_MASK 0x0000000002000000
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW3_CE_FROM_FSB                          */
+/*   Description:  Inject a Correctable Error in Doubleword 0 of SIC D  */
+/*  ata Packet 0                                                        */
+#define SH_PI_FSB_ERROR_INJECTION_DW3_CE_FROM_FSB_SHFT 26
+#define SH_PI_FSB_ERROR_INJECTION_DW3_CE_FROM_FSB_MASK 0x0000000004000000
+
+/*   SH_PI_FSB_ERROR_INJECTION_DW3_UCE_FROM_FSB                         */
+/*   Description:  Inject a Uncorrectable Error in Doubleword 0 of SIC  */
+/*   Data Packet 0                                                      */
+#define SH_PI_FSB_ERROR_INJECTION_DW3_UCE_FROM_FSB_SHFT 27
+#define SH_PI_FSB_ERROR_INJECTION_DW3_UCE_FROM_FSB_MASK 0x0000000008000000
+
+/*   SH_PI_FSB_ERROR_INJECTION_IOQ_OVERRUN                              */
+/*   Description:  Inject an ioq overrun Error on the FSB               */
+#define SH_PI_FSB_ERROR_INJECTION_IOQ_OVERRUN_SHFT 32
+#define SH_PI_FSB_ERROR_INJECTION_IOQ_OVERRUN_MASK 0x0000000100000000
+
+/*   SH_PI_FSB_ERROR_INJECTION_LIVELOCK                                 */
+/*   Description:  Inject a livelock Error on the FSB                   */
+#define SH_PI_FSB_ERROR_INJECTION_LIVELOCK_SHFT  33
+#define SH_PI_FSB_ERROR_INJECTION_LIVELOCK_MASK  0x0000000200000000
+
+/*   SH_PI_FSB_ERROR_INJECTION_BUS_HANG                                 */
+/*   Description:  Inject an bus hang on the FSB                        */
+#define SH_PI_FSB_ERROR_INJECTION_BUS_HANG_SHFT  34
+#define SH_PI_FSB_ERROR_INJECTION_BUS_HANG_MASK  0x0000000400000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_MD2PI_REPLY_VC_CONFIG"                */
+/*             MD-to-PI Reply Virtual Channel Configuration             */
+/* ==================================================================== */
+
+#define SH_PI_MD2PI_REPLY_VC_CONFIG              0x0000000120050d00
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_MASK         0xc000000000003fff
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_INIT         0x000000000000088c
+
+/*   SH_PI_MD2PI_REPLY_VC_CONFIG_HDR_DEPTH                              */
+/*   Description:  Depth of header Buffer                               */
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_HDR_DEPTH_SHFT 0
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_HDR_DEPTH_MASK 0x000000000000000f
+
+/*   SH_PI_MD2PI_REPLY_VC_CONFIG_DATA_DEPTH                             */
+/*   Description:  Number of data buffers Available                     */
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_DATA_DEPTH_SHFT 4
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_DATA_DEPTH_MASK 0x00000000000000f0
+
+/*   SH_PI_MD2PI_REPLY_VC_CONFIG_MAX_CREDITS                            */
+/*   Description:  Maximum credits from sender                          */
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_MAX_CREDITS_SHFT 8
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_MAX_CREDITS_MASK 0x0000000000003f00
+
+/*   SH_PI_MD2PI_REPLY_VC_CONFIG_FORCE_CREDIT                           */
+/*   Description:  Send an extra credit to sender                       */
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_FORCE_CREDIT_SHFT 62
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_FORCE_CREDIT_MASK 0x4000000000000000
+
+/*   SH_PI_MD2PI_REPLY_VC_CONFIG_CAPTURE_CREDIT_STATUS                  */
+/*   Description:  Capture credit and status information                */
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_CAPTURE_CREDIT_STATUS_SHFT 63
+#define SH_PI_MD2PI_REPLY_VC_CONFIG_CAPTURE_CREDIT_STATUS_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_MD2PI_REQUEST_VC_CONFIG"               */
+/*            MD-to-PI Request Virtual Channel Configuration            */
+/* ==================================================================== */
+
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG            0x0000000120050d80
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_MASK       0xc000000000003fff
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_INIT       0x000000000000088c
+
+/*   SH_PI_MD2PI_REQUEST_VC_CONFIG_HDR_DEPTH                            */
+/*   Description:  Depth of header Buffer                               */
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_HDR_DEPTH_SHFT 0
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_HDR_DEPTH_MASK 0x000000000000000f
+
+/*   SH_PI_MD2PI_REQUEST_VC_CONFIG_DATA_DEPTH                           */
+/*   Description:  Number of data buffers Available                     */
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_DATA_DEPTH_SHFT 4
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_DATA_DEPTH_MASK 0x00000000000000f0
+
+/*   SH_PI_MD2PI_REQUEST_VC_CONFIG_MAX_CREDITS                          */
+/*   Description:  Maximum credits from sender                          */
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_MAX_CREDITS_SHFT 8
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_MAX_CREDITS_MASK 0x0000000000003f00
+
+/*   SH_PI_MD2PI_REQUEST_VC_CONFIG_FORCE_CREDIT                         */
+/*   Description:  Send an extra credit to sender                       */
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_FORCE_CREDIT_SHFT 62
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_FORCE_CREDIT_MASK 0x4000000000000000
+
+/*   SH_PI_MD2PI_REQUEST_VC_CONFIG_CAPTURE_CREDIT_STATUS                */
+/*   Description:  Capture credit and status information                */
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_CAPTURE_CREDIT_STATUS_SHFT 63
+#define SH_PI_MD2PI_REQUEST_VC_CONFIG_CAPTURE_CREDIT_STATUS_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_QUEUE_ERROR_INJECTION"                */
+/*                       PI Queue Error Injection                       */
+/* ==================================================================== */
+
+#define SH_PI_QUEUE_ERROR_INJECTION              0x0000000120050e00
+#define SH_PI_QUEUE_ERROR_INJECTION_MASK         0x00000000000000ff
+#define SH_PI_QUEUE_ERROR_INJECTION_INIT         0x0000000000000000
+
+/*   SH_PI_QUEUE_ERROR_INJECTION_DAT_DFR_Q                              */
+#define SH_PI_QUEUE_ERROR_INJECTION_DAT_DFR_Q_SHFT 0
+#define SH_PI_QUEUE_ERROR_INJECTION_DAT_DFR_Q_MASK 0x0000000000000001
+
+/*   SH_PI_QUEUE_ERROR_INJECTION_DXB_WTL_CMND_Q                         */
+#define SH_PI_QUEUE_ERROR_INJECTION_DXB_WTL_CMND_Q_SHFT 1
+#define SH_PI_QUEUE_ERROR_INJECTION_DXB_WTL_CMND_Q_MASK 0x0000000000000002
+
+/*   SH_PI_QUEUE_ERROR_INJECTION_FSB_WTL_CMND_Q                         */
+#define SH_PI_QUEUE_ERROR_INJECTION_FSB_WTL_CMND_Q_SHFT 2
+#define SH_PI_QUEUE_ERROR_INJECTION_FSB_WTL_CMND_Q_MASK 0x0000000000000004
+
+/*   SH_PI_QUEUE_ERROR_INJECTION_MDPI_RPY_BFR                           */
+#define SH_PI_QUEUE_ERROR_INJECTION_MDPI_RPY_BFR_SHFT 3
+#define SH_PI_QUEUE_ERROR_INJECTION_MDPI_RPY_BFR_MASK 0x0000000000000008
+
+/*   SH_PI_QUEUE_ERROR_INJECTION_PTC_INTR                               */
+#define SH_PI_QUEUE_ERROR_INJECTION_PTC_INTR_SHFT 4
+#define SH_PI_QUEUE_ERROR_INJECTION_PTC_INTR_MASK 0x0000000000000010
+
+/*   SH_PI_QUEUE_ERROR_INJECTION_RXL_KILL_Q                             */
+#define SH_PI_QUEUE_ERROR_INJECTION_RXL_KILL_Q_SHFT 5
+#define SH_PI_QUEUE_ERROR_INJECTION_RXL_KILL_Q_MASK 0x0000000000000020
+
+/*   SH_PI_QUEUE_ERROR_INJECTION_RXL_RDY_Q                              */
+#define SH_PI_QUEUE_ERROR_INJECTION_RXL_RDY_Q_SHFT 6
+#define SH_PI_QUEUE_ERROR_INJECTION_RXL_RDY_Q_MASK 0x0000000000000040
+
+/*   SH_PI_QUEUE_ERROR_INJECTION_XNPI_RPY_BFR                           */
+#define SH_PI_QUEUE_ERROR_INJECTION_XNPI_RPY_BFR_SHFT 7
+#define SH_PI_QUEUE_ERROR_INJECTION_XNPI_RPY_BFR_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                 Register "SH_PI_TEST_POINT_COMPARE"                  */
+/*                        PI Test Point Compare                         */
+/* ==================================================================== */
+
+#define SH_PI_TEST_POINT_COMPARE                 0x0000000120050e80
+#define SH_PI_TEST_POINT_COMPARE_MASK            0xffffffffffffffff
+#define SH_PI_TEST_POINT_COMPARE_INIT            0xffffffff00000000
+
+/*   SH_PI_TEST_POINT_COMPARE_COMPARE_MASK                              */
+/*   Description:  Mask to select test point data for trigger generati  */
+#define SH_PI_TEST_POINT_COMPARE_COMPARE_MASK_SHFT 0
+#define SH_PI_TEST_POINT_COMPARE_COMPARE_MASK_MASK 0x00000000ffffffff
+
+/*   SH_PI_TEST_POINT_COMPARE_COMPARE_PATTERN                           */
+/*   Description:  Pattern of test point data to cause trigger          */
+#define SH_PI_TEST_POINT_COMPARE_COMPARE_PATTERN_SHFT 32
+#define SH_PI_TEST_POINT_COMPARE_COMPARE_PATTERN_MASK 0xffffffff00000000
+
+/* ==================================================================== */
+/*                  Register "SH_PI_TEST_POINT_SELECT"                  */
+/*                         PI Test Point Select                         */
+/* ==================================================================== */
+
+#define SH_PI_TEST_POINT_SELECT                  0x0000000120050f00
+#define SH_PI_TEST_POINT_SELECT_MASK             0xf777777777777777
+#define SH_PI_TEST_POINT_SELECT_INIT             0x0000000000000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL                        */
+/*   Description:  Nibble 0 data is from Chiplet X                      */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL_SHFT 0
+#define SH_PI_TEST_POINT_SELECT_NIBBLE0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL                         */
+/*   Description:  Nibble X is routed to Nibble 0                       */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_PI_TEST_POINT_SELECT_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL                        */
+/*   Description:  Nibble 1 data is from Chiplet X                      */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL_SHFT 8
+#define SH_PI_TEST_POINT_SELECT_NIBBLE1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL                         */
+/*   Description:  Nibble X is routed to Nibble 1                       */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_PI_TEST_POINT_SELECT_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL                        */
+/*   Description:  Nibble 2 data is from Chiplet X                      */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL_SHFT 16
+#define SH_PI_TEST_POINT_SELECT_NIBBLE2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL                         */
+/*   Description:  Nibble X is routed to Nibble 2                       */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_PI_TEST_POINT_SELECT_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL                        */
+/*   Description:  Nibble 3 data is from Chiplet X                      */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL_SHFT 24
+#define SH_PI_TEST_POINT_SELECT_NIBBLE3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL                         */
+/*   Description:  Nibble X is routed to Nibble 3                       */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_PI_TEST_POINT_SELECT_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL                        */
+/*   Description:  Nibble 4 data is from Chiplet X                      */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL_SHFT 32
+#define SH_PI_TEST_POINT_SELECT_NIBBLE4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL                         */
+/*   Description:  Nibble X is routed to Nibble 4                       */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_PI_TEST_POINT_SELECT_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL                        */
+/*   Description:  Nibble 5 data is from Chiplet X                      */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL_SHFT 40
+#define SH_PI_TEST_POINT_SELECT_NIBBLE5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL                         */
+/*   Description:  Nibble X is routed to Nibble 5                       */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_PI_TEST_POINT_SELECT_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL                        */
+/*   Description:  Nibble 6 data is from Chiplet X                      */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL_SHFT 48
+#define SH_PI_TEST_POINT_SELECT_NIBBLE6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL                         */
+/*   Description:  Nibble X is routed to Nibble 6                       */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_PI_TEST_POINT_SELECT_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL                        */
+/*   Description:  Nibble 7 data is from Chiplet X                      */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL_SHFT 56
+#define SH_PI_TEST_POINT_SELECT_NIBBLE7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_PI_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL                         */
+/*   Description:  Nibble X is routed to Nibble 7                       */
+#define SH_PI_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_PI_TEST_POINT_SELECT_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/*   SH_PI_TEST_POINT_SELECT_TRIGGER_ENABLE                             */
+/*   Description:  Enable trigger on bit 32 of Analyzer data            */
+#define SH_PI_TEST_POINT_SELECT_TRIGGER_ENABLE_SHFT 63
+#define SH_PI_TEST_POINT_SELECT_TRIGGER_ENABLE_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*              Register "SH_PI_TEST_POINT_TRIGGER_SELECT"              */
+/*                     PI Test Point Trigger Select                     */
+/* ==================================================================== */
+
+#define SH_PI_TEST_POINT_TRIGGER_SELECT          0x0000000120050f80
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_MASK     0x7777777777777777
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_INIT     0x0000000000000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL               */
+/*   Description:  Nibble 0 Chiplet select                              */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL_SHFT 0
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_CHIPLET_SEL_MASK 0x0000000000000007
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL                */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL_SHFT 4
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL               */
+/*   Description:  Nibble 1 Chiplet select                              */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL_SHFT 8
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_CHIPLET_SEL_MASK 0x0000000000000700
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL                */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL_SHFT 12
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL               */
+/*   Description:  Nibble 2 Chiplet select                              */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL_SHFT 16
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_CHIPLET_SEL_MASK 0x0000000000070000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL                */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL_SHFT 20
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL               */
+/*   Description:  Nibble 3 Chiplet select                              */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL_SHFT 24
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_CHIPLET_SEL_MASK 0x0000000007000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL                */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL_SHFT 28
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL               */
+/*   Description:  Nibble 4 Chiplet select                              */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL_SHFT 32
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_CHIPLET_SEL_MASK 0x0000000700000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL                */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL_SHFT 36
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL               */
+/*   Description:  Nibble 5 Chiplet select                              */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL_SHFT 40
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_CHIPLET_SEL_MASK 0x0000070000000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL                */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL_SHFT 44
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL               */
+/*   Description:  Nibble 6 Chiplet select                              */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL_SHFT 48
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_CHIPLET_SEL_MASK 0x0007000000000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL                */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL_SHFT 52
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL               */
+/*   Description:  Nibble 7 Chiplet select                              */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL_SHFT 56
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_CHIPLET_SEL_MASK 0x0700000000000000
+
+/*   SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL                */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL_SHFT 60
+#define SH_PI_TEST_POINT_TRIGGER_SELECT_TRIGGER7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_XN2PI_REPLY_VC_CONFIG"                */
+/*             XN-to-PI Reply Virtual Channel Configuration             */
+/* ==================================================================== */
+
+#define SH_PI_XN2PI_REPLY_VC_CONFIG              0x0000000120051000
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_MASK         0xc000000000003fff
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_INIT         0x000000000000068c
+
+/*   SH_PI_XN2PI_REPLY_VC_CONFIG_HDR_DEPTH                              */
+/*   Description:  Depth of header Buffer                               */
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_HDR_DEPTH_SHFT 0
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_HDR_DEPTH_MASK 0x000000000000000f
+
+/*   SH_PI_XN2PI_REPLY_VC_CONFIG_DATA_DEPTH                             */
+/*   Description:  Number of data buffers Available                     */
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_DATA_DEPTH_SHFT 4
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_DATA_DEPTH_MASK 0x00000000000000f0
+
+/*   SH_PI_XN2PI_REPLY_VC_CONFIG_MAX_CREDITS                            */
+/*   Description:  Maximum credits from sender                          */
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_MAX_CREDITS_SHFT 8
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_MAX_CREDITS_MASK 0x0000000000003f00
+
+/*   SH_PI_XN2PI_REPLY_VC_CONFIG_FORCE_CREDIT                           */
+/*   Description:  Send an extra credit to sender                       */
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_FORCE_CREDIT_SHFT 62
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_FORCE_CREDIT_MASK 0x4000000000000000
+
+/*   SH_PI_XN2PI_REPLY_VC_CONFIG_CAPTURE_CREDIT_STATUS                  */
+/*   Description:  Capture credit and status information                */
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_CAPTURE_CREDIT_STATUS_SHFT 63
+#define SH_PI_XN2PI_REPLY_VC_CONFIG_CAPTURE_CREDIT_STATUS_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_PI_XN2PI_REQUEST_VC_CONFIG"               */
+/*            XN-to-PI Request Virtual Channel Configuration            */
+/* ==================================================================== */
+
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG            0x0000000120051080
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_MASK       0xc000000000003fff
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_INIT       0x000000000000068c
+
+/*   SH_PI_XN2PI_REQUEST_VC_CONFIG_HDR_DEPTH                            */
+/*   Description:  Depth of header Buffer                               */
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_HDR_DEPTH_SHFT 0
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_HDR_DEPTH_MASK 0x000000000000000f
+
+/*   SH_PI_XN2PI_REQUEST_VC_CONFIG_DATA_DEPTH                           */
+/*   Description:  Number of data buffers Available                     */
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_DATA_DEPTH_SHFT 4
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_DATA_DEPTH_MASK 0x00000000000000f0
+
+/*   SH_PI_XN2PI_REQUEST_VC_CONFIG_MAX_CREDITS                          */
+/*   Description:  Maximum credits from sender                          */
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_MAX_CREDITS_SHFT 8
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_MAX_CREDITS_MASK 0x0000000000003f00
+
+/*   SH_PI_XN2PI_REQUEST_VC_CONFIG_FORCE_CREDIT                         */
+/*   Description:  Send an extra credit to sender                       */
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_FORCE_CREDIT_SHFT 62
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_FORCE_CREDIT_MASK 0x4000000000000000
+
+/*   SH_PI_XN2PI_REQUEST_VC_CONFIG_CAPTURE_CREDIT_STATUS                */
+/*   Description:  Capture credit and status information                */
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_CAPTURE_CREDIT_STATUS_SHFT 63
+#define SH_PI_XN2PI_REQUEST_VC_CONFIG_CAPTURE_CREDIT_STATUS_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                     Register "SH_PI_AEC_STATUS"                      */
+/*                 PI Adaptive Error Correction Status                  */
+/* ==================================================================== */
+
+#define SH_PI_AEC_STATUS                         0x0000000120060000
+#define SH_PI_AEC_STATUS_MASK                    0x0000000000000007
+#define SH_PI_AEC_STATUS_INIT                    0x0000000000000000
+
+/*   SH_PI_AEC_STATUS_STATE                                             */
+/*   Description:  AEC State                                            */
+#define SH_PI_AEC_STATUS_STATE_SHFT              0
+#define SH_PI_AEC_STATUS_STATE_MASK              0x0000000000000007
+
+/* ==================================================================== */
+/*                   Register "SH_PI_AFI_FIRST_ERROR"                   */
+/*                          PI AFI First Error                          */
+/* ==================================================================== */
+
+#define SH_PI_AFI_FIRST_ERROR                    0x0000000120060080
+#define SH_PI_AFI_FIRST_ERROR_MASK               0x00000007ffe00180
+#define SH_PI_AFI_FIRST_ERROR_INIT               0x0000000000000000
+
+/*   SH_PI_AFI_FIRST_ERROR_FSB_SHUB_UCE                                 */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_AFI_FIRST_ERROR_FSB_SHUB_UCE_SHFT  7
+#define SH_PI_AFI_FIRST_ERROR_FSB_SHUB_UCE_MASK  0x0000000000000080
+
+/*   SH_PI_AFI_FIRST_ERROR_FSB_SHUB_CE                                  */
+/*   Description:  A correctable ECC error was detected                 */
+#define SH_PI_AFI_FIRST_ERROR_FSB_SHUB_CE_SHFT   8
+#define SH_PI_AFI_FIRST_ERROR_FSB_SHUB_CE_MASK   0x0000000000000100
+
+/*   SH_PI_AFI_FIRST_ERROR_HUNG_BUS                                     */
+/*   Description:  FSB is hung                                          */
+#define SH_PI_AFI_FIRST_ERROR_HUNG_BUS_SHFT      21
+#define SH_PI_AFI_FIRST_ERROR_HUNG_BUS_MASK      0x0000000000200000
+
+/*   SH_PI_AFI_FIRST_ERROR_RSP_PARITY                                   */
+/*   Description:  Parity error detecte during response phase           */
+#define SH_PI_AFI_FIRST_ERROR_RSP_PARITY_SHFT    22
+#define SH_PI_AFI_FIRST_ERROR_RSP_PARITY_MASK    0x0000000000400000
+
+/*   SH_PI_AFI_FIRST_ERROR_IOQ_OVERRUN                                  */
+/*   Description:  Over run error detected on IOQ                       */
+#define SH_PI_AFI_FIRST_ERROR_IOQ_OVERRUN_SHFT   23
+#define SH_PI_AFI_FIRST_ERROR_IOQ_OVERRUN_MASK   0x0000000000800000
+
+/*   SH_PI_AFI_FIRST_ERROR_REQ_FORMAT                                   */
+/*   Description:  FSB request format not supported                     */
+#define SH_PI_AFI_FIRST_ERROR_REQ_FORMAT_SHFT    24
+#define SH_PI_AFI_FIRST_ERROR_REQ_FORMAT_MASK    0x0000000001000000
+
+/*   SH_PI_AFI_FIRST_ERROR_ADDR_ACCESS                                  */
+/*   Description:  Access to Address is not supported                   */
+#define SH_PI_AFI_FIRST_ERROR_ADDR_ACCESS_SHFT   25
+#define SH_PI_AFI_FIRST_ERROR_ADDR_ACCESS_MASK   0x0000000002000000
+
+/*   SH_PI_AFI_FIRST_ERROR_REQ_PARITY                                   */
+/*   Description:  Parity error detected during request phase           */
+#define SH_PI_AFI_FIRST_ERROR_REQ_PARITY_SHFT    26
+#define SH_PI_AFI_FIRST_ERROR_REQ_PARITY_MASK    0x0000000004000000
+
+/*   SH_PI_AFI_FIRST_ERROR_ADDR_PARITY                                  */
+/*   Description:  Parity error detected on address                     */
+#define SH_PI_AFI_FIRST_ERROR_ADDR_PARITY_SHFT   27
+#define SH_PI_AFI_FIRST_ERROR_ADDR_PARITY_MASK   0x0000000008000000
+
+/*   SH_PI_AFI_FIRST_ERROR_SHUB_FSB_DQE                                 */
+/*   Description:  SHUB_FSB_DQE                                         */
+#define SH_PI_AFI_FIRST_ERROR_SHUB_FSB_DQE_SHFT  28
+#define SH_PI_AFI_FIRST_ERROR_SHUB_FSB_DQE_MASK  0x0000000010000000
+
+/*   SH_PI_AFI_FIRST_ERROR_SHUB_FSB_UCE                                 */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_AFI_FIRST_ERROR_SHUB_FSB_UCE_SHFT  29
+#define SH_PI_AFI_FIRST_ERROR_SHUB_FSB_UCE_MASK  0x0000000020000000
+
+/*   SH_PI_AFI_FIRST_ERROR_SHUB_FSB_CE                                  */
+/*   Description:  An correctable ECC error was detected                */
+#define SH_PI_AFI_FIRST_ERROR_SHUB_FSB_CE_SHFT   30
+#define SH_PI_AFI_FIRST_ERROR_SHUB_FSB_CE_MASK   0x0000000040000000
+
+/*   SH_PI_AFI_FIRST_ERROR_LIVELOCK                                     */
+/*   Description:  AFI livelock error was detected                      */
+#define SH_PI_AFI_FIRST_ERROR_LIVELOCK_SHFT      31
+#define SH_PI_AFI_FIRST_ERROR_LIVELOCK_MASK      0x0000000080000000
+
+/*   SH_PI_AFI_FIRST_ERROR_BAD_SNOOP                                    */
+/*   Description:  AFI bad snoop error was detected                     */
+#define SH_PI_AFI_FIRST_ERROR_BAD_SNOOP_SHFT     32
+#define SH_PI_AFI_FIRST_ERROR_BAD_SNOOP_MASK     0x0000000100000000
+
+/*   SH_PI_AFI_FIRST_ERROR_FSB_TBL_MISS                                 */
+/*   Description:  AFI FSB request table miss error was detected        */
+#define SH_PI_AFI_FIRST_ERROR_FSB_TBL_MISS_SHFT  33
+#define SH_PI_AFI_FIRST_ERROR_FSB_TBL_MISS_MASK  0x0000000200000000
+
+/*   SH_PI_AFI_FIRST_ERROR_MSG_LEN                                      */
+/*   Description:  Runt or Obese message received from SIC              */
+#define SH_PI_AFI_FIRST_ERROR_MSG_LEN_SHFT       34
+#define SH_PI_AFI_FIRST_ERROR_MSG_LEN_MASK       0x0000000400000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_CAM_ADDRESS_READ_DATA"                */
+/*                    CRB CAM MMR Address Read Data                     */
+/* ==================================================================== */
+
+#define SH_PI_CAM_ADDRESS_READ_DATA              0x0000000120060100
+#define SH_PI_CAM_ADDRESS_READ_DATA_MASK         0x8000ffffffffffff
+#define SH_PI_CAM_ADDRESS_READ_DATA_INIT         0x0000000000000000
+
+/*   SH_PI_CAM_ADDRESS_READ_DATA_CAM_ADDR                               */
+/*   Description:  CRB CAM Address Read Data.                           */
+#define SH_PI_CAM_ADDRESS_READ_DATA_CAM_ADDR_SHFT 0
+#define SH_PI_CAM_ADDRESS_READ_DATA_CAM_ADDR_MASK 0x0000ffffffffffff
+
+/*   SH_PI_CAM_ADDRESS_READ_DATA_CAM_ADDR_VAL                           */
+/*   Description:  CRB CAM Address Read Data Valid.                     */
+#define SH_PI_CAM_ADDRESS_READ_DATA_CAM_ADDR_VAL_SHFT 63
+#define SH_PI_CAM_ADDRESS_READ_DATA_CAM_ADDR_VAL_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CAM_LPRA_READ_DATA"                  */
+/*                      CRB CAM MMR LPRA Read Data                      */
+/* ==================================================================== */
+
+#define SH_PI_CAM_LPRA_READ_DATA                 0x0000000120060180
+#define SH_PI_CAM_LPRA_READ_DATA_MASK            0xffffffffffffffff
+#define SH_PI_CAM_LPRA_READ_DATA_INIT            0x0000000000000000
+
+/*   SH_PI_CAM_LPRA_READ_DATA_CAM_LPRA                                  */
+/*   Description:  CRB CAM LPRA read data.                              */
+#define SH_PI_CAM_LPRA_READ_DATA_CAM_LPRA_SHFT   0
+#define SH_PI_CAM_LPRA_READ_DATA_CAM_LPRA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CAM_STATE_READ_DATA"                 */
+/*                     CRB CAM MMR State Read Data                      */
+/* ==================================================================== */
+
+#define SH_PI_CAM_STATE_READ_DATA                0x0000000120060200
+#define SH_PI_CAM_STATE_READ_DATA_MASK           0x8003ffff0000003f
+#define SH_PI_CAM_STATE_READ_DATA_INIT           0x0000000000000000
+
+/*   SH_PI_CAM_STATE_READ_DATA_CAM_STATE                                */
+/*   Description:  CRB CAM State read data.                             */
+#define SH_PI_CAM_STATE_READ_DATA_CAM_STATE_SHFT 0
+#define SH_PI_CAM_STATE_READ_DATA_CAM_STATE_MASK 0x000000000000000f
+
+/*   SH_PI_CAM_STATE_READ_DATA_CAM_TO                                   */
+/*   Description:  CRB CAM Time-out Status.                             */
+#define SH_PI_CAM_STATE_READ_DATA_CAM_TO_SHFT    4
+#define SH_PI_CAM_STATE_READ_DATA_CAM_TO_MASK    0x0000000000000010
+
+/*   SH_PI_CAM_STATE_READ_DATA_CAM_STATE_RD_PEND                        */
+/*   Description:  CRB CAM State Read Pending.                          */
+#define SH_PI_CAM_STATE_READ_DATA_CAM_STATE_RD_PEND_SHFT 5
+#define SH_PI_CAM_STATE_READ_DATA_CAM_STATE_RD_PEND_MASK 0x0000000000000020
+
+/*   SH_PI_CAM_STATE_READ_DATA_CAM_LPRA                                 */
+/*   Description:  CRB LPRA Overflow Data.                              */
+#define SH_PI_CAM_STATE_READ_DATA_CAM_LPRA_SHFT  32
+#define SH_PI_CAM_STATE_READ_DATA_CAM_LPRA_MASK  0x0003ffff00000000
+
+/*   SH_PI_CAM_STATE_READ_DATA_CAM_RD_DATA_VAL                          */
+/*   Description:  CRB CAM MMR read data is valid.                      */
+#define SH_PI_CAM_STATE_READ_DATA_CAM_RD_DATA_VAL_SHFT 63
+#define SH_PI_CAM_STATE_READ_DATA_CAM_RD_DATA_VAL_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CORRECTED_DETAIL_1"                  */
+/*                      PI Corrected Error Detail                       */
+/* ==================================================================== */
+
+#define SH_PI_CORRECTED_DETAIL_1                 0x0000000120060280
+#define SH_PI_CORRECTED_DETAIL_1_MASK            0xffffffffffffffff
+#define SH_PI_CORRECTED_DETAIL_1_INIT            0x0000000000000000
+
+/*   SH_PI_CORRECTED_DETAIL_1_ADDRESS                                   */
+/*   Description:  Address of Message that logged Correctable Error     */
+#define SH_PI_CORRECTED_DETAIL_1_ADDRESS_SHFT    0
+#define SH_PI_CORRECTED_DETAIL_1_ADDRESS_MASK    0x0000ffffffffffff
+
+/*   SH_PI_CORRECTED_DETAIL_1_SYNDROME                                  */
+/*   Description:  Syndrome for double word data with Correctable Erro  */
+#define SH_PI_CORRECTED_DETAIL_1_SYNDROME_SHFT   48
+#define SH_PI_CORRECTED_DETAIL_1_SYNDROME_MASK   0x00ff000000000000
+
+/*   SH_PI_CORRECTED_DETAIL_1_DEP                                       */
+/*   Description:  DEP code for Double word in error                    */
+#define SH_PI_CORRECTED_DETAIL_1_DEP_SHFT        56
+#define SH_PI_CORRECTED_DETAIL_1_DEP_MASK        0xff00000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CORRECTED_DETAIL_2"                  */
+/*                     PI Corrected Error Detail 2                      */
+/* ==================================================================== */
+
+#define SH_PI_CORRECTED_DETAIL_2                 0x0000000120060300
+#define SH_PI_CORRECTED_DETAIL_2_MASK            0xffffffffffffffff
+#define SH_PI_CORRECTED_DETAIL_2_INIT            0x0000000000000000
+
+/*   SH_PI_CORRECTED_DETAIL_2_DATA                                      */
+/*   Description:  Double word data in error                            */
+#define SH_PI_CORRECTED_DETAIL_2_DATA_SHFT       0
+#define SH_PI_CORRECTED_DETAIL_2_DATA_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CORRECTED_DETAIL_3"                  */
+/*                     PI Corrected Error Detail 3                      */
+/* ==================================================================== */
+
+#define SH_PI_CORRECTED_DETAIL_3                 0x0000000120060380
+#define SH_PI_CORRECTED_DETAIL_3_MASK            0xffffffffffffffff
+#define SH_PI_CORRECTED_DETAIL_3_INIT            0x0000000000000000
+
+/*   SH_PI_CORRECTED_DETAIL_3_ADDRESS                                   */
+/*   Description:  Address of Message that logged Correctable Error     */
+#define SH_PI_CORRECTED_DETAIL_3_ADDRESS_SHFT    0
+#define SH_PI_CORRECTED_DETAIL_3_ADDRESS_MASK    0x0000ffffffffffff
+
+/*   SH_PI_CORRECTED_DETAIL_3_SYNDROME                                  */
+/*   Description:  Syndrome for double word data with Correctable Erro  */
+#define SH_PI_CORRECTED_DETAIL_3_SYNDROME_SHFT   48
+#define SH_PI_CORRECTED_DETAIL_3_SYNDROME_MASK   0x00ff000000000000
+
+/*   SH_PI_CORRECTED_DETAIL_3_DEP                                       */
+/*   Description:  DEP code for Double word in error                    */
+#define SH_PI_CORRECTED_DETAIL_3_DEP_SHFT        56
+#define SH_PI_CORRECTED_DETAIL_3_DEP_MASK        0xff00000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CORRECTED_DETAIL_4"                  */
+/*                     PI Corrected Error Detail 4                      */
+/* ==================================================================== */
+
+#define SH_PI_CORRECTED_DETAIL_4                 0x0000000120060400
+#define SH_PI_CORRECTED_DETAIL_4_MASK            0xffffffffffffffff
+#define SH_PI_CORRECTED_DETAIL_4_INIT            0x0000000000000000
+
+/*   SH_PI_CORRECTED_DETAIL_4_DATA                                      */
+/*   Description:  Double word data in error                            */
+#define SH_PI_CORRECTED_DETAIL_4_DATA_SHFT       0
+#define SH_PI_CORRECTED_DETAIL_4_DATA_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PI_CRBP_FIRST_ERROR"                   */
+/*                         PI CRBP First Error                          */
+/* ==================================================================== */
+
+#define SH_PI_CRBP_FIRST_ERROR                   0x0000000120060480
+#define SH_PI_CRBP_FIRST_ERROR_MASK              0x00000000001fffff
+#define SH_PI_CRBP_FIRST_ERROR_INIT              0x0000000000000000
+
+/*   SH_PI_CRBP_FIRST_ERROR_FSB_PROTO_ERR                               */
+/*   Description:  CRB's FSB pipe detected protocol table miss          */
+#define SH_PI_CRBP_FIRST_ERROR_FSB_PROTO_ERR_SHFT 0
+#define SH_PI_CRBP_FIRST_ERROR_FSB_PROTO_ERR_MASK 0x0000000000000001
+
+/*   SH_PI_CRBP_FIRST_ERROR_GFX_RP_ERR                                  */
+/*   Description:  CRB's XB pipe received a GFX error reply             */
+#define SH_PI_CRBP_FIRST_ERROR_GFX_RP_ERR_SHFT   1
+#define SH_PI_CRBP_FIRST_ERROR_GFX_RP_ERR_MASK   0x0000000000000002
+
+/*   SH_PI_CRBP_FIRST_ERROR_XB_PROTO_ERR                                */
+/*   Description:  CRB's XB pipe detected protocol table miss           */
+#define SH_PI_CRBP_FIRST_ERROR_XB_PROTO_ERR_SHFT 2
+#define SH_PI_CRBP_FIRST_ERROR_XB_PROTO_ERR_MASK 0x0000000000000004
+
+/*   SH_PI_CRBP_FIRST_ERROR_MEM_RP_ERR                                  */
+/*   Description:  CRB's XB pipe received a memory error reply message  */
+#define SH_PI_CRBP_FIRST_ERROR_MEM_RP_ERR_SHFT   3
+#define SH_PI_CRBP_FIRST_ERROR_MEM_RP_ERR_MASK   0x0000000000000008
+
+/*   SH_PI_CRBP_FIRST_ERROR_PIO_RP_ERR                                  */
+/*   Description:  CRB's XB pipe received a PIO error reply message     */
+#define SH_PI_CRBP_FIRST_ERROR_PIO_RP_ERR_SHFT   4
+#define SH_PI_CRBP_FIRST_ERROR_PIO_RP_ERR_MASK   0x0000000000000010
+
+/*   SH_PI_CRBP_FIRST_ERROR_MEM_TO_ERR                                  */
+/*   Description:  CRB's XB pipe detected a CRB time-out                */
+#define SH_PI_CRBP_FIRST_ERROR_MEM_TO_ERR_SHFT   5
+#define SH_PI_CRBP_FIRST_ERROR_MEM_TO_ERR_MASK   0x0000000000000020
+
+/*   SH_PI_CRBP_FIRST_ERROR_PIO_TO_ERR                                  */
+/*   Description:  CRB's XB pipe detected a PIO time-out                */
+#define SH_PI_CRBP_FIRST_ERROR_PIO_TO_ERR_SHFT   6
+#define SH_PI_CRBP_FIRST_ERROR_PIO_TO_ERR_MASK   0x0000000000000040
+
+/*   SH_PI_CRBP_FIRST_ERROR_FSB_SHUB_UCE                                */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_CRBP_FIRST_ERROR_FSB_SHUB_UCE_SHFT 7
+#define SH_PI_CRBP_FIRST_ERROR_FSB_SHUB_UCE_MASK 0x0000000000000080
+
+/*   SH_PI_CRBP_FIRST_ERROR_FSB_SHUB_CE                                 */
+/*   Description:  A correctable ECC error was detected                 */
+#define SH_PI_CRBP_FIRST_ERROR_FSB_SHUB_CE_SHFT  8
+#define SH_PI_CRBP_FIRST_ERROR_FSB_SHUB_CE_MASK  0x0000000000000100
+
+/*   SH_PI_CRBP_FIRST_ERROR_MSG_COLOR_ERR                               */
+/*   Description:  Message color was wrong                              */
+#define SH_PI_CRBP_FIRST_ERROR_MSG_COLOR_ERR_SHFT 9
+#define SH_PI_CRBP_FIRST_ERROR_MSG_COLOR_ERR_MASK 0x0000000000000200
+
+/*   SH_PI_CRBP_FIRST_ERROR_MD_RQ_Q_OFLOW                               */
+/*   Description:  MD Request input buffer over flow error              */
+#define SH_PI_CRBP_FIRST_ERROR_MD_RQ_Q_OFLOW_SHFT 10
+#define SH_PI_CRBP_FIRST_ERROR_MD_RQ_Q_OFLOW_MASK 0x0000000000000400
+
+/*   SH_PI_CRBP_FIRST_ERROR_MD_RP_Q_OFLOW                               */
+/*   Description:  MD Reply input buffer over flow error                */
+#define SH_PI_CRBP_FIRST_ERROR_MD_RP_Q_OFLOW_SHFT 11
+#define SH_PI_CRBP_FIRST_ERROR_MD_RP_Q_OFLOW_MASK 0x0000000000000800
+
+/*   SH_PI_CRBP_FIRST_ERROR_XN_RQ_Q_OFLOW                               */
+/*   Description:  XN Request input buffer over flow error              */
+#define SH_PI_CRBP_FIRST_ERROR_XN_RQ_Q_OFLOW_SHFT 12
+#define SH_PI_CRBP_FIRST_ERROR_XN_RQ_Q_OFLOW_MASK 0x0000000000001000
+
+/*   SH_PI_CRBP_FIRST_ERROR_XN_RP_Q_OFLOW                               */
+/*   Description:  XN Reply input buffer over flow error                */
+#define SH_PI_CRBP_FIRST_ERROR_XN_RP_Q_OFLOW_SHFT 13
+#define SH_PI_CRBP_FIRST_ERROR_XN_RP_Q_OFLOW_MASK 0x0000000000002000
+
+/*   SH_PI_CRBP_FIRST_ERROR_NACK_OFLOW                                  */
+/*   Description:  NACK over flow error                                 */
+#define SH_PI_CRBP_FIRST_ERROR_NACK_OFLOW_SHFT   14
+#define SH_PI_CRBP_FIRST_ERROR_NACK_OFLOW_MASK   0x0000000000004000
+
+/*   SH_PI_CRBP_FIRST_ERROR_GFX_INT_0                                   */
+/*   Description:  GFX transfer interrupt for CPU 0                     */
+#define SH_PI_CRBP_FIRST_ERROR_GFX_INT_0_SHFT    15
+#define SH_PI_CRBP_FIRST_ERROR_GFX_INT_0_MASK    0x0000000000008000
+
+/*   SH_PI_CRBP_FIRST_ERROR_GFX_INT_1                                   */
+/*   Description:  GFX transfer interrupt for CPU 1                     */
+#define SH_PI_CRBP_FIRST_ERROR_GFX_INT_1_SHFT    16
+#define SH_PI_CRBP_FIRST_ERROR_GFX_INT_1_MASK    0x0000000000010000
+
+/*   SH_PI_CRBP_FIRST_ERROR_MD_RQ_CRD_OFLOW                             */
+/*   Description:  MD Request Credit Overflow Error                     */
+#define SH_PI_CRBP_FIRST_ERROR_MD_RQ_CRD_OFLOW_SHFT 17
+#define SH_PI_CRBP_FIRST_ERROR_MD_RQ_CRD_OFLOW_MASK 0x0000000000020000
+
+/*   SH_PI_CRBP_FIRST_ERROR_MD_RP_CRD_OFLOW                             */
+/*   Description:  MD Reply Credit Overflow Error                       */
+#define SH_PI_CRBP_FIRST_ERROR_MD_RP_CRD_OFLOW_SHFT 18
+#define SH_PI_CRBP_FIRST_ERROR_MD_RP_CRD_OFLOW_MASK 0x0000000000040000
+
+/*   SH_PI_CRBP_FIRST_ERROR_XN_RQ_CRD_OFLOW                             */
+/*   Description:  XN Request Credit Overflow Error                     */
+#define SH_PI_CRBP_FIRST_ERROR_XN_RQ_CRD_OFLOW_SHFT 19
+#define SH_PI_CRBP_FIRST_ERROR_XN_RQ_CRD_OFLOW_MASK 0x0000000000080000
+
+/*   SH_PI_CRBP_FIRST_ERROR_XN_RP_CRD_OFLOW                             */
+/*   Description:  XN Reply Credit Overflow Error                       */
+#define SH_PI_CRBP_FIRST_ERROR_XN_RP_CRD_OFLOW_SHFT 20
+#define SH_PI_CRBP_FIRST_ERROR_XN_RP_CRD_OFLOW_MASK 0x0000000000100000
+
+/* ==================================================================== */
+/*                   Register "SH_PI_ERROR_DETAIL_1"                    */
+/*                          PI Error Detail 1                           */
+/* ==================================================================== */
+
+#define SH_PI_ERROR_DETAIL_1                     0x0000000120060500
+#define SH_PI_ERROR_DETAIL_1_MASK                0xffffffffffffffff
+#define SH_PI_ERROR_DETAIL_1_INIT                0x0000000000000000
+
+/*   SH_PI_ERROR_DETAIL_1_STATUS                                        */
+/*   Description:  Error Detail 1                                       */
+#define SH_PI_ERROR_DETAIL_1_STATUS_SHFT         0
+#define SH_PI_ERROR_DETAIL_1_STATUS_MASK         0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_PI_ERROR_DETAIL_2"                    */
+/*                          PI Error Detail 2                           */
+/* ==================================================================== */
+
+#define SH_PI_ERROR_DETAIL_2                     0x0000000120060580
+#define SH_PI_ERROR_DETAIL_2_MASK                0xffffffffffffffff
+#define SH_PI_ERROR_DETAIL_2_INIT                0x0000000000000000
+
+/*   SH_PI_ERROR_DETAIL_2_STATUS                                        */
+/*   Description:  Error Status                                         */
+#define SH_PI_ERROR_DETAIL_2_STATUS_SHFT         0
+#define SH_PI_ERROR_DETAIL_2_STATUS_MASK         0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_PI_ERROR_OVERFLOW"                    */
+/*                          PI Error Overflow                           */
+/* ==================================================================== */
+
+#define SH_PI_ERROR_OVERFLOW                     0x0000000120060600
+#define SH_PI_ERROR_OVERFLOW_MASK                0x00000007ffffffff
+#define SH_PI_ERROR_OVERFLOW_INIT                0x0000000000000000
+
+/*   SH_PI_ERROR_OVERFLOW_FSB_PROTO_ERR                                 */
+/*   Description:  CRB's FSB pipe detected protocol table miss          */
+#define SH_PI_ERROR_OVERFLOW_FSB_PROTO_ERR_SHFT  0
+#define SH_PI_ERROR_OVERFLOW_FSB_PROTO_ERR_MASK  0x0000000000000001
+
+/*   SH_PI_ERROR_OVERFLOW_GFX_RP_ERR                                    */
+/*   Description:  CRB's XB pipe received another GFX reply error mess  */
+#define SH_PI_ERROR_OVERFLOW_GFX_RP_ERR_SHFT     1
+#define SH_PI_ERROR_OVERFLOW_GFX_RP_ERR_MASK     0x0000000000000002
+
+/*   SH_PI_ERROR_OVERFLOW_XB_PROTO_ERR                                  */
+/*   Description:  CRB's XB pipe detected another protocol table miss  */
+#define SH_PI_ERROR_OVERFLOW_XB_PROTO_ERR_SHFT   2
+#define SH_PI_ERROR_OVERFLOW_XB_PROTO_ERR_MASK   0x0000000000000004
+
+/*   SH_PI_ERROR_OVERFLOW_MEM_RP_ERR                                    */
+/*   Description:  CRB's XB pipe received another memory reply error m  */
+#define SH_PI_ERROR_OVERFLOW_MEM_RP_ERR_SHFT     3
+#define SH_PI_ERROR_OVERFLOW_MEM_RP_ERR_MASK     0x0000000000000008
+
+/*   SH_PI_ERROR_OVERFLOW_PIO_RP_ERR                                    */
+/*   Description:  CRB's XB pipe received another PIO reply error mess  */
+#define SH_PI_ERROR_OVERFLOW_PIO_RP_ERR_SHFT     4
+#define SH_PI_ERROR_OVERFLOW_PIO_RP_ERR_MASK     0x0000000000000010
+
+/*   SH_PI_ERROR_OVERFLOW_MEM_TO_ERR                                    */
+/*   Description:  CRB's XB pipe detected a CRB time-out                */
+#define SH_PI_ERROR_OVERFLOW_MEM_TO_ERR_SHFT     5
+#define SH_PI_ERROR_OVERFLOW_MEM_TO_ERR_MASK     0x0000000000000020
+
+/*   SH_PI_ERROR_OVERFLOW_PIO_TO_ERR                                    */
+/*   Description:  CRB's XB pipe detected a PIO time-out                */
+#define SH_PI_ERROR_OVERFLOW_PIO_TO_ERR_SHFT     6
+#define SH_PI_ERROR_OVERFLOW_PIO_TO_ERR_MASK     0x0000000000000040
+
+/*   SH_PI_ERROR_OVERFLOW_FSB_SHUB_UCE                                  */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_ERROR_OVERFLOW_FSB_SHUB_UCE_SHFT   7
+#define SH_PI_ERROR_OVERFLOW_FSB_SHUB_UCE_MASK   0x0000000000000080
+
+/*   SH_PI_ERROR_OVERFLOW_FSB_SHUB_CE                                   */
+/*   Description:  An correctable ECC error was detected                */
+#define SH_PI_ERROR_OVERFLOW_FSB_SHUB_CE_SHFT    8
+#define SH_PI_ERROR_OVERFLOW_FSB_SHUB_CE_MASK    0x0000000000000100
+
+/*   SH_PI_ERROR_OVERFLOW_MSG_COLOR_ERR                                 */
+/*   Description:  Message color was not correct                        */
+#define SH_PI_ERROR_OVERFLOW_MSG_COLOR_ERR_SHFT  9
+#define SH_PI_ERROR_OVERFLOW_MSG_COLOR_ERR_MASK  0x0000000000000200
+
+/*   SH_PI_ERROR_OVERFLOW_MD_RQ_Q_OFLOW                                 */
+/*   Description:  MD Request input buffer over flow error              */
+#define SH_PI_ERROR_OVERFLOW_MD_RQ_Q_OFLOW_SHFT  10
+#define SH_PI_ERROR_OVERFLOW_MD_RQ_Q_OFLOW_MASK  0x0000000000000400
+
+/*   SH_PI_ERROR_OVERFLOW_MD_RP_Q_OFLOW                                 */
+/*   Description:  MD Reply input buffer over flow error                */
+#define SH_PI_ERROR_OVERFLOW_MD_RP_Q_OFLOW_SHFT  11
+#define SH_PI_ERROR_OVERFLOW_MD_RP_Q_OFLOW_MASK  0x0000000000000800
+
+/*   SH_PI_ERROR_OVERFLOW_XN_RQ_Q_OFLOW                                 */
+/*   Description:  XN Request input buffer over flow error              */
+#define SH_PI_ERROR_OVERFLOW_XN_RQ_Q_OFLOW_SHFT  12
+#define SH_PI_ERROR_OVERFLOW_XN_RQ_Q_OFLOW_MASK  0x0000000000001000
+
+/*   SH_PI_ERROR_OVERFLOW_XN_RP_Q_OFLOW                                 */
+/*   Description:  XN Reply input buffer over flow error                */
+#define SH_PI_ERROR_OVERFLOW_XN_RP_Q_OFLOW_SHFT  13
+#define SH_PI_ERROR_OVERFLOW_XN_RP_Q_OFLOW_MASK  0x0000000000002000
+
+/*   SH_PI_ERROR_OVERFLOW_NACK_OFLOW                                    */
+/*   Description:  NACK over flow error                                 */
+#define SH_PI_ERROR_OVERFLOW_NACK_OFLOW_SHFT     14
+#define SH_PI_ERROR_OVERFLOW_NACK_OFLOW_MASK     0x0000000000004000
+
+/*   SH_PI_ERROR_OVERFLOW_GFX_INT_0                                     */
+/*   Description:  GFX transfer interrupt for CPU 0                     */
+#define SH_PI_ERROR_OVERFLOW_GFX_INT_0_SHFT      15
+#define SH_PI_ERROR_OVERFLOW_GFX_INT_0_MASK      0x0000000000008000
+
+/*   SH_PI_ERROR_OVERFLOW_GFX_INT_1                                     */
+/*   Description:  GFX transfer interrupt for CPU 1                     */
+#define SH_PI_ERROR_OVERFLOW_GFX_INT_1_SHFT      16
+#define SH_PI_ERROR_OVERFLOW_GFX_INT_1_MASK      0x0000000000010000
+
+/*   SH_PI_ERROR_OVERFLOW_MD_RQ_CRD_OFLOW                               */
+/*   Description:  MD Request Credit Overflow Error                     */
+#define SH_PI_ERROR_OVERFLOW_MD_RQ_CRD_OFLOW_SHFT 17
+#define SH_PI_ERROR_OVERFLOW_MD_RQ_CRD_OFLOW_MASK 0x0000000000020000
+
+/*   SH_PI_ERROR_OVERFLOW_MD_RP_CRD_OFLOW                               */
+/*   Description:  MD Reply Credit Overflow Error                       */
+#define SH_PI_ERROR_OVERFLOW_MD_RP_CRD_OFLOW_SHFT 18
+#define SH_PI_ERROR_OVERFLOW_MD_RP_CRD_OFLOW_MASK 0x0000000000040000
+
+/*   SH_PI_ERROR_OVERFLOW_XN_RQ_CRD_OFLOW                               */
+/*   Description:  XN Request Credit Overflow Error                     */
+#define SH_PI_ERROR_OVERFLOW_XN_RQ_CRD_OFLOW_SHFT 19
+#define SH_PI_ERROR_OVERFLOW_XN_RQ_CRD_OFLOW_MASK 0x0000000000080000
+
+/*   SH_PI_ERROR_OVERFLOW_XN_RP_CRD_OFLOW                               */
+/*   Description:  XN Reply Credit Overflow Error                       */
+#define SH_PI_ERROR_OVERFLOW_XN_RP_CRD_OFLOW_SHFT 20
+#define SH_PI_ERROR_OVERFLOW_XN_RP_CRD_OFLOW_MASK 0x0000000000100000
+
+/*   SH_PI_ERROR_OVERFLOW_HUNG_BUS                                      */
+/*   Description:  FSB is hung                                          */
+#define SH_PI_ERROR_OVERFLOW_HUNG_BUS_SHFT       21
+#define SH_PI_ERROR_OVERFLOW_HUNG_BUS_MASK       0x0000000000200000
+
+/*   SH_PI_ERROR_OVERFLOW_RSP_PARITY                                    */
+/*   Description:  Parity error detecte during response phase           */
+#define SH_PI_ERROR_OVERFLOW_RSP_PARITY_SHFT     22
+#define SH_PI_ERROR_OVERFLOW_RSP_PARITY_MASK     0x0000000000400000
+
+/*   SH_PI_ERROR_OVERFLOW_IOQ_OVERRUN                                   */
+/*   Description:  Over run error detected on IOQ                       */
+#define SH_PI_ERROR_OVERFLOW_IOQ_OVERRUN_SHFT    23
+#define SH_PI_ERROR_OVERFLOW_IOQ_OVERRUN_MASK    0x0000000000800000
+
+/*   SH_PI_ERROR_OVERFLOW_REQ_FORMAT                                    */
+/*   Description:  FSB request format not supported                     */
+#define SH_PI_ERROR_OVERFLOW_REQ_FORMAT_SHFT     24
+#define SH_PI_ERROR_OVERFLOW_REQ_FORMAT_MASK     0x0000000001000000
+
+/*   SH_PI_ERROR_OVERFLOW_ADDR_ACCESS                                   */
+/*   Description:  Access to Address is not supported                   */
+#define SH_PI_ERROR_OVERFLOW_ADDR_ACCESS_SHFT    25
+#define SH_PI_ERROR_OVERFLOW_ADDR_ACCESS_MASK    0x0000000002000000
+
+/*   SH_PI_ERROR_OVERFLOW_REQ_PARITY                                    */
+/*   Description:  Parity error detected during request phase           */
+#define SH_PI_ERROR_OVERFLOW_REQ_PARITY_SHFT     26
+#define SH_PI_ERROR_OVERFLOW_REQ_PARITY_MASK     0x0000000004000000
+
+/*   SH_PI_ERROR_OVERFLOW_ADDR_PARITY                                   */
+/*   Description:  Parity error detected on address                     */
+#define SH_PI_ERROR_OVERFLOW_ADDR_PARITY_SHFT    27
+#define SH_PI_ERROR_OVERFLOW_ADDR_PARITY_MASK    0x0000000008000000
+
+/*   SH_PI_ERROR_OVERFLOW_SHUB_FSB_DQE                                  */
+/*   Description:  SHUB_FSB_DQE                                         */
+#define SH_PI_ERROR_OVERFLOW_SHUB_FSB_DQE_SHFT   28
+#define SH_PI_ERROR_OVERFLOW_SHUB_FSB_DQE_MASK   0x0000000010000000
+
+/*   SH_PI_ERROR_OVERFLOW_SHUB_FSB_UCE                                  */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_ERROR_OVERFLOW_SHUB_FSB_UCE_SHFT   29
+#define SH_PI_ERROR_OVERFLOW_SHUB_FSB_UCE_MASK   0x0000000020000000
+
+/*   SH_PI_ERROR_OVERFLOW_SHUB_FSB_CE                                   */
+/*   Description:  An correctable ECC error was detected                */
+#define SH_PI_ERROR_OVERFLOW_SHUB_FSB_CE_SHFT    30
+#define SH_PI_ERROR_OVERFLOW_SHUB_FSB_CE_MASK    0x0000000040000000
+
+/*   SH_PI_ERROR_OVERFLOW_LIVELOCK                                      */
+/*   Description:  AFI livelock error was detected                      */
+#define SH_PI_ERROR_OVERFLOW_LIVELOCK_SHFT       31
+#define SH_PI_ERROR_OVERFLOW_LIVELOCK_MASK       0x0000000080000000
+
+/*   SH_PI_ERROR_OVERFLOW_BAD_SNOOP                                     */
+/*   Description:  AFI bad snoop error was detected                     */
+#define SH_PI_ERROR_OVERFLOW_BAD_SNOOP_SHFT      32
+#define SH_PI_ERROR_OVERFLOW_BAD_SNOOP_MASK      0x0000000100000000
+
+/*   SH_PI_ERROR_OVERFLOW_FSB_TBL_MISS                                  */
+/*   Description:  AFI FSB request table miss error was detected        */
+#define SH_PI_ERROR_OVERFLOW_FSB_TBL_MISS_SHFT   33
+#define SH_PI_ERROR_OVERFLOW_FSB_TBL_MISS_MASK   0x0000000200000000
+
+/*   SH_PI_ERROR_OVERFLOW_MSG_LENGTH                                    */
+/*   Description:  Message length error on received message from SIC    */
+#define SH_PI_ERROR_OVERFLOW_MSG_LENGTH_SHFT     34
+#define SH_PI_ERROR_OVERFLOW_MSG_LENGTH_MASK     0x0000000400000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_ERROR_OVERFLOW_ALIAS"                 */
+/*                       PI Error Overflow Alias                        */
+/* ==================================================================== */
+
+#define SH_PI_ERROR_OVERFLOW_ALIAS               0x0000000120060608
+
+/* ==================================================================== */
+/*                    Register "SH_PI_ERROR_SUMMARY"                    */
+/*                           PI Error Summary                           */
+/* ==================================================================== */
+
+#define SH_PI_ERROR_SUMMARY                      0x0000000120060680
+#define SH_PI_ERROR_SUMMARY_MASK                 0x00000007ffffffff
+#define SH_PI_ERROR_SUMMARY_INIT                 0x0000000000000000
+
+/*   SH_PI_ERROR_SUMMARY_FSB_PROTO_ERR                                  */
+/*   Description:  CRB's FSB pipe detected protocol table miss          */
+#define SH_PI_ERROR_SUMMARY_FSB_PROTO_ERR_SHFT   0
+#define SH_PI_ERROR_SUMMARY_FSB_PROTO_ERR_MASK   0x0000000000000001
+
+/*   SH_PI_ERROR_SUMMARY_GFX_RP_ERR                                     */
+/*   Description:  Graphic reply error message received                 */
+#define SH_PI_ERROR_SUMMARY_GFX_RP_ERR_SHFT      1
+#define SH_PI_ERROR_SUMMARY_GFX_RP_ERR_MASK      0x0000000000000002
+
+/*   SH_PI_ERROR_SUMMARY_XB_PROTO_ERR                                   */
+/*   Description:  CRB's XB pipe detected protocol table miss           */
+#define SH_PI_ERROR_SUMMARY_XB_PROTO_ERR_SHFT    2
+#define SH_PI_ERROR_SUMMARY_XB_PROTO_ERR_MASK    0x0000000000000004
+
+/*   SH_PI_ERROR_SUMMARY_MEM_RP_ERR                                     */
+/*   Description:  Memory reply error message received                  */
+#define SH_PI_ERROR_SUMMARY_MEM_RP_ERR_SHFT      3
+#define SH_PI_ERROR_SUMMARY_MEM_RP_ERR_MASK      0x0000000000000008
+
+/*   SH_PI_ERROR_SUMMARY_PIO_RP_ERR                                     */
+/*   Description:  PIO error reply message received                     */
+#define SH_PI_ERROR_SUMMARY_PIO_RP_ERR_SHFT      4
+#define SH_PI_ERROR_SUMMARY_PIO_RP_ERR_MASK      0x0000000000000010
+
+/*   SH_PI_ERROR_SUMMARY_MEM_TO_ERR                                     */
+/*   Description:  CRB's XB pipe detected a CRB time-out                */
+#define SH_PI_ERROR_SUMMARY_MEM_TO_ERR_SHFT      5
+#define SH_PI_ERROR_SUMMARY_MEM_TO_ERR_MASK      0x0000000000000020
+
+/*   SH_PI_ERROR_SUMMARY_PIO_TO_ERR                                     */
+/*   Description:  CRB's XB pipe detected a PIO time-out                */
+#define SH_PI_ERROR_SUMMARY_PIO_TO_ERR_SHFT      6
+#define SH_PI_ERROR_SUMMARY_PIO_TO_ERR_MASK      0x0000000000000040
+
+/*   SH_PI_ERROR_SUMMARY_FSB_SHUB_UCE                                   */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_ERROR_SUMMARY_FSB_SHUB_UCE_SHFT    7
+#define SH_PI_ERROR_SUMMARY_FSB_SHUB_UCE_MASK    0x0000000000000080
+
+/*   SH_PI_ERROR_SUMMARY_FSB_SHUB_CE                                    */
+/*   Description:  An correctable ECC error was detected                */
+#define SH_PI_ERROR_SUMMARY_FSB_SHUB_CE_SHFT     8
+#define SH_PI_ERROR_SUMMARY_FSB_SHUB_CE_MASK     0x0000000000000100
+
+/*   SH_PI_ERROR_SUMMARY_MSG_COLOR_ERR                                  */
+/*   Description:  Message color was wrong                              */
+#define SH_PI_ERROR_SUMMARY_MSG_COLOR_ERR_SHFT   9
+#define SH_PI_ERROR_SUMMARY_MSG_COLOR_ERR_MASK   0x0000000000000200
+
+/*   SH_PI_ERROR_SUMMARY_MD_RQ_Q_OFLOW                                  */
+/*   Description:  MD Request input buffer over flow error              */
+#define SH_PI_ERROR_SUMMARY_MD_RQ_Q_OFLOW_SHFT   10
+#define SH_PI_ERROR_SUMMARY_MD_RQ_Q_OFLOW_MASK   0x0000000000000400
+
+/*   SH_PI_ERROR_SUMMARY_MD_RP_Q_OFLOW                                  */
+/*   Description:  MD Reply input buffer over flow error                */
+#define SH_PI_ERROR_SUMMARY_MD_RP_Q_OFLOW_SHFT   11
+#define SH_PI_ERROR_SUMMARY_MD_RP_Q_OFLOW_MASK   0x0000000000000800
+
+/*   SH_PI_ERROR_SUMMARY_XN_RQ_Q_OFLOW                                  */
+/*   Description:  XN Request input buffer over flow error              */
+#define SH_PI_ERROR_SUMMARY_XN_RQ_Q_OFLOW_SHFT   12
+#define SH_PI_ERROR_SUMMARY_XN_RQ_Q_OFLOW_MASK   0x0000000000001000
+
+/*   SH_PI_ERROR_SUMMARY_XN_RP_Q_OFLOW                                  */
+/*   Description:  XN Reply input buffer over flow error                */
+#define SH_PI_ERROR_SUMMARY_XN_RP_Q_OFLOW_SHFT   13
+#define SH_PI_ERROR_SUMMARY_XN_RP_Q_OFLOW_MASK   0x0000000000002000
+
+/*   SH_PI_ERROR_SUMMARY_NACK_OFLOW                                     */
+/*   Description:  NACK over flow error                                 */
+#define SH_PI_ERROR_SUMMARY_NACK_OFLOW_SHFT      14
+#define SH_PI_ERROR_SUMMARY_NACK_OFLOW_MASK      0x0000000000004000
+
+/*   SH_PI_ERROR_SUMMARY_GFX_INT_0                                      */
+/*   Description:  GFX transfer interrupt for CPU 0                     */
+#define SH_PI_ERROR_SUMMARY_GFX_INT_0_SHFT       15
+#define SH_PI_ERROR_SUMMARY_GFX_INT_0_MASK       0x0000000000008000
+
+/*   SH_PI_ERROR_SUMMARY_GFX_INT_1                                      */
+/*   Description:  GFX transfer interrupt for CPU 1                     */
+#define SH_PI_ERROR_SUMMARY_GFX_INT_1_SHFT       16
+#define SH_PI_ERROR_SUMMARY_GFX_INT_1_MASK       0x0000000000010000
+
+/*   SH_PI_ERROR_SUMMARY_MD_RQ_CRD_OFLOW                                */
+/*   Description:  MD Request Credit Overflow Error                     */
+#define SH_PI_ERROR_SUMMARY_MD_RQ_CRD_OFLOW_SHFT 17
+#define SH_PI_ERROR_SUMMARY_MD_RQ_CRD_OFLOW_MASK 0x0000000000020000
+
+/*   SH_PI_ERROR_SUMMARY_MD_RP_CRD_OFLOW                                */
+/*   Description:  MD Reply Credit Overflow Error                       */
+#define SH_PI_ERROR_SUMMARY_MD_RP_CRD_OFLOW_SHFT 18
+#define SH_PI_ERROR_SUMMARY_MD_RP_CRD_OFLOW_MASK 0x0000000000040000
+
+/*   SH_PI_ERROR_SUMMARY_XN_RQ_CRD_OFLOW                                */
+/*   Description:  XN Request Credit Overflow Error                     */
+#define SH_PI_ERROR_SUMMARY_XN_RQ_CRD_OFLOW_SHFT 19
+#define SH_PI_ERROR_SUMMARY_XN_RQ_CRD_OFLOW_MASK 0x0000000000080000
+
+/*   SH_PI_ERROR_SUMMARY_XN_RP_CRD_OFLOW                                */
+/*   Description:  XN Reply Credit Overflow Error                       */
+#define SH_PI_ERROR_SUMMARY_XN_RP_CRD_OFLOW_SHFT 20
+#define SH_PI_ERROR_SUMMARY_XN_RP_CRD_OFLOW_MASK 0x0000000000100000
+
+/*   SH_PI_ERROR_SUMMARY_HUNG_BUS                                       */
+/*   Description:  FSB is hung                                          */
+#define SH_PI_ERROR_SUMMARY_HUNG_BUS_SHFT        21
+#define SH_PI_ERROR_SUMMARY_HUNG_BUS_MASK        0x0000000000200000
+
+/*   SH_PI_ERROR_SUMMARY_RSP_PARITY                                     */
+/*   Description:  Parity error detecte during response phase           */
+#define SH_PI_ERROR_SUMMARY_RSP_PARITY_SHFT      22
+#define SH_PI_ERROR_SUMMARY_RSP_PARITY_MASK      0x0000000000400000
+
+/*   SH_PI_ERROR_SUMMARY_IOQ_OVERRUN                                    */
+/*   Description:  Over run error detected on IOQ                       */
+#define SH_PI_ERROR_SUMMARY_IOQ_OVERRUN_SHFT     23
+#define SH_PI_ERROR_SUMMARY_IOQ_OVERRUN_MASK     0x0000000000800000
+
+/*   SH_PI_ERROR_SUMMARY_REQ_FORMAT                                     */
+/*   Description:  FSB request format not supported                     */
+#define SH_PI_ERROR_SUMMARY_REQ_FORMAT_SHFT      24
+#define SH_PI_ERROR_SUMMARY_REQ_FORMAT_MASK      0x0000000001000000
+
+/*   SH_PI_ERROR_SUMMARY_ADDR_ACCESS                                    */
+/*   Description:  Access to Address is not supported                   */
+#define SH_PI_ERROR_SUMMARY_ADDR_ACCESS_SHFT     25
+#define SH_PI_ERROR_SUMMARY_ADDR_ACCESS_MASK     0x0000000002000000
+
+/*   SH_PI_ERROR_SUMMARY_REQ_PARITY                                     */
+/*   Description:  Parity error detected during request phase           */
+#define SH_PI_ERROR_SUMMARY_REQ_PARITY_SHFT      26
+#define SH_PI_ERROR_SUMMARY_REQ_PARITY_MASK      0x0000000004000000
+
+/*   SH_PI_ERROR_SUMMARY_ADDR_PARITY                                    */
+/*   Description:  Parity error detected on address                     */
+#define SH_PI_ERROR_SUMMARY_ADDR_PARITY_SHFT     27
+#define SH_PI_ERROR_SUMMARY_ADDR_PARITY_MASK     0x0000000008000000
+
+/*   SH_PI_ERROR_SUMMARY_SHUB_FSB_DQE                                   */
+/*   Description:  SHUB_FSB_DQE error                                   */
+#define SH_PI_ERROR_SUMMARY_SHUB_FSB_DQE_SHFT    28
+#define SH_PI_ERROR_SUMMARY_SHUB_FSB_DQE_MASK    0x0000000010000000
+
+/*   SH_PI_ERROR_SUMMARY_SHUB_FSB_UCE                                   */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_ERROR_SUMMARY_SHUB_FSB_UCE_SHFT    29
+#define SH_PI_ERROR_SUMMARY_SHUB_FSB_UCE_MASK    0x0000000020000000
+
+/*   SH_PI_ERROR_SUMMARY_SHUB_FSB_CE                                    */
+/*   Description:  An correctable ECC error was detected                */
+#define SH_PI_ERROR_SUMMARY_SHUB_FSB_CE_SHFT     30
+#define SH_PI_ERROR_SUMMARY_SHUB_FSB_CE_MASK     0x0000000040000000
+
+/*   SH_PI_ERROR_SUMMARY_LIVELOCK                                       */
+/*   Description:  AFI livelock error was detected                      */
+#define SH_PI_ERROR_SUMMARY_LIVELOCK_SHFT        31
+#define SH_PI_ERROR_SUMMARY_LIVELOCK_MASK        0x0000000080000000
+
+/*   SH_PI_ERROR_SUMMARY_BAD_SNOOP                                      */
+/*   Description:  AFI bad snoop error was detected                     */
+#define SH_PI_ERROR_SUMMARY_BAD_SNOOP_SHFT       32
+#define SH_PI_ERROR_SUMMARY_BAD_SNOOP_MASK       0x0000000100000000
+
+/*   SH_PI_ERROR_SUMMARY_FSB_TBL_MISS                                   */
+/*   Description:  AFI FSB request table miss error was detected        */
+#define SH_PI_ERROR_SUMMARY_FSB_TBL_MISS_SHFT    33
+#define SH_PI_ERROR_SUMMARY_FSB_TBL_MISS_MASK    0x0000000200000000
+
+/*   SH_PI_ERROR_SUMMARY_MSG_LENGTH                                     */
+/*   Description:  Message length error on received message from SIC    */
+#define SH_PI_ERROR_SUMMARY_MSG_LENGTH_SHFT      34
+#define SH_PI_ERROR_SUMMARY_MSG_LENGTH_MASK      0x0000000400000000
+
+/* ==================================================================== */
+/*                 Register "SH_PI_ERROR_SUMMARY_ALIAS"                 */
+/*                        PI Error Summary Alias                        */
+/* ==================================================================== */
+
+#define SH_PI_ERROR_SUMMARY_ALIAS                0x0000000120060688
+
+/* ==================================================================== */
+/*                Register "SH_PI_EXPRESS_REPLY_STATUS"                 */
+/*                       PI Express Reply Status                        */
+/* ==================================================================== */
+
+#define SH_PI_EXPRESS_REPLY_STATUS               0x0000000120060700
+#define SH_PI_EXPRESS_REPLY_STATUS_MASK          0x0000000000000007
+#define SH_PI_EXPRESS_REPLY_STATUS_INIT          0x0000000000000000
+
+/*   SH_PI_EXPRESS_REPLY_STATUS_STATE                                   */
+/*   Description:  Express Reply State                                  */
+#define SH_PI_EXPRESS_REPLY_STATUS_STATE_SHFT    0
+#define SH_PI_EXPRESS_REPLY_STATUS_STATE_MASK    0x0000000000000007
+
+/* ==================================================================== */
+/*                     Register "SH_PI_FIRST_ERROR"                     */
+/*                            PI First Error                            */
+/* ==================================================================== */
+
+#define SH_PI_FIRST_ERROR                        0x0000000120060780
+#define SH_PI_FIRST_ERROR_MASK                   0x00000007ffffffff
+#define SH_PI_FIRST_ERROR_INIT                   0x0000000000000000
+
+/*   SH_PI_FIRST_ERROR_FSB_PROTO_ERR                                    */
+/*   Description:  CRB's FSB pipe detected protocol table miss          */
+#define SH_PI_FIRST_ERROR_FSB_PROTO_ERR_SHFT     0
+#define SH_PI_FIRST_ERROR_FSB_PROTO_ERR_MASK     0x0000000000000001
+
+/*   SH_PI_FIRST_ERROR_GFX_RP_ERR                                       */
+/*   Description:  Graphics error reply message received                */
+#define SH_PI_FIRST_ERROR_GFX_RP_ERR_SHFT        1
+#define SH_PI_FIRST_ERROR_GFX_RP_ERR_MASK        0x0000000000000002
+
+/*   SH_PI_FIRST_ERROR_XB_PROTO_ERR                                     */
+/*   Description:  CRB's XB pipe detected protocol table miss           */
+#define SH_PI_FIRST_ERROR_XB_PROTO_ERR_SHFT      2
+#define SH_PI_FIRST_ERROR_XB_PROTO_ERR_MASK      0x0000000000000004
+
+/*   SH_PI_FIRST_ERROR_MEM_RP_ERR                                       */
+/*   Description:  Memory reply error message received                  */
+#define SH_PI_FIRST_ERROR_MEM_RP_ERR_SHFT        3
+#define SH_PI_FIRST_ERROR_MEM_RP_ERR_MASK        0x0000000000000008
+
+/*   SH_PI_FIRST_ERROR_PIO_RP_ERR                                       */
+/*   Description:  PIO reply error message received                     */
+#define SH_PI_FIRST_ERROR_PIO_RP_ERR_SHFT        4
+#define SH_PI_FIRST_ERROR_PIO_RP_ERR_MASK        0x0000000000000010
+
+/*   SH_PI_FIRST_ERROR_MEM_TO_ERR                                       */
+/*   Description:  CRB's XB pipe detected a CRB time-out                */
+#define SH_PI_FIRST_ERROR_MEM_TO_ERR_SHFT        5
+#define SH_PI_FIRST_ERROR_MEM_TO_ERR_MASK        0x0000000000000020
+
+/*   SH_PI_FIRST_ERROR_PIO_TO_ERR                                       */
+/*   Description:  CRB's XB pipe detected a PIO time-out                */
+#define SH_PI_FIRST_ERROR_PIO_TO_ERR_SHFT        6
+#define SH_PI_FIRST_ERROR_PIO_TO_ERR_MASK        0x0000000000000040
+
+/*   SH_PI_FIRST_ERROR_FSB_SHUB_UCE                                     */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_FIRST_ERROR_FSB_SHUB_UCE_SHFT      7
+#define SH_PI_FIRST_ERROR_FSB_SHUB_UCE_MASK      0x0000000000000080
+
+/*   SH_PI_FIRST_ERROR_FSB_SHUB_CE                                      */
+/*   Description:  A correctable ECC error was detected                 */
+#define SH_PI_FIRST_ERROR_FSB_SHUB_CE_SHFT       8
+#define SH_PI_FIRST_ERROR_FSB_SHUB_CE_MASK       0x0000000000000100
+
+/*   SH_PI_FIRST_ERROR_MSG_COLOR_ERR                                    */
+/*   Description:  Message color was wrong                              */
+#define SH_PI_FIRST_ERROR_MSG_COLOR_ERR_SHFT     9
+#define SH_PI_FIRST_ERROR_MSG_COLOR_ERR_MASK     0x0000000000000200
+
+/*   SH_PI_FIRST_ERROR_MD_RQ_Q_OFLOW                                    */
+/*   Description:  MD Request input buffer over flow error              */
+#define SH_PI_FIRST_ERROR_MD_RQ_Q_OFLOW_SHFT     10
+#define SH_PI_FIRST_ERROR_MD_RQ_Q_OFLOW_MASK     0x0000000000000400
+
+/*   SH_PI_FIRST_ERROR_MD_RP_Q_OFLOW                                    */
+/*   Description:  MD Reply input buffer over flow error                */
+#define SH_PI_FIRST_ERROR_MD_RP_Q_OFLOW_SHFT     11
+#define SH_PI_FIRST_ERROR_MD_RP_Q_OFLOW_MASK     0x0000000000000800
+
+/*   SH_PI_FIRST_ERROR_XN_RQ_Q_OFLOW                                    */
+/*   Description:  XN Request input buffer over flow error              */
+#define SH_PI_FIRST_ERROR_XN_RQ_Q_OFLOW_SHFT     12
+#define SH_PI_FIRST_ERROR_XN_RQ_Q_OFLOW_MASK     0x0000000000001000
+
+/*   SH_PI_FIRST_ERROR_XN_RP_Q_OFLOW                                    */
+/*   Description:  XN Reply input buffer over flow error                */
+#define SH_PI_FIRST_ERROR_XN_RP_Q_OFLOW_SHFT     13
+#define SH_PI_FIRST_ERROR_XN_RP_Q_OFLOW_MASK     0x0000000000002000
+
+/*   SH_PI_FIRST_ERROR_NACK_OFLOW                                       */
+/*   Description:  NACK over flow error                                 */
+#define SH_PI_FIRST_ERROR_NACK_OFLOW_SHFT        14
+#define SH_PI_FIRST_ERROR_NACK_OFLOW_MASK        0x0000000000004000
+
+/*   SH_PI_FIRST_ERROR_GFX_INT_0                                        */
+/*   Description:  GFX transfer interrupt for CPU 0                     */
+#define SH_PI_FIRST_ERROR_GFX_INT_0_SHFT         15
+#define SH_PI_FIRST_ERROR_GFX_INT_0_MASK         0x0000000000008000
+
+/*   SH_PI_FIRST_ERROR_GFX_INT_1                                        */
+/*   Description:  GFX transfer interrupt for CPU 1                     */
+#define SH_PI_FIRST_ERROR_GFX_INT_1_SHFT         16
+#define SH_PI_FIRST_ERROR_GFX_INT_1_MASK         0x0000000000010000
+
+/*   SH_PI_FIRST_ERROR_MD_RQ_CRD_OFLOW                                  */
+/*   Description:  MD Request Credit Overflow Error                     */
+#define SH_PI_FIRST_ERROR_MD_RQ_CRD_OFLOW_SHFT   17
+#define SH_PI_FIRST_ERROR_MD_RQ_CRD_OFLOW_MASK   0x0000000000020000
+
+/*   SH_PI_FIRST_ERROR_MD_RP_CRD_OFLOW                                  */
+/*   Description:  MD Reply Credit Overflow Error                       */
+#define SH_PI_FIRST_ERROR_MD_RP_CRD_OFLOW_SHFT   18
+#define SH_PI_FIRST_ERROR_MD_RP_CRD_OFLOW_MASK   0x0000000000040000
+
+/*   SH_PI_FIRST_ERROR_XN_RQ_CRD_OFLOW                                  */
+/*   Description:  XN Request Credit Overflow Error                     */
+#define SH_PI_FIRST_ERROR_XN_RQ_CRD_OFLOW_SHFT   19
+#define SH_PI_FIRST_ERROR_XN_RQ_CRD_OFLOW_MASK   0x0000000000080000
+
+/*   SH_PI_FIRST_ERROR_XN_RP_CRD_OFLOW                                  */
+/*   Description:  XN Reply Credit Overflow Error                       */
+#define SH_PI_FIRST_ERROR_XN_RP_CRD_OFLOW_SHFT   20
+#define SH_PI_FIRST_ERROR_XN_RP_CRD_OFLOW_MASK   0x0000000000100000
+
+/*   SH_PI_FIRST_ERROR_HUNG_BUS                                         */
+/*   Description:  FSB is hung                                          */
+#define SH_PI_FIRST_ERROR_HUNG_BUS_SHFT          21
+#define SH_PI_FIRST_ERROR_HUNG_BUS_MASK          0x0000000000200000
+
+/*   SH_PI_FIRST_ERROR_RSP_PARITY                                       */
+/*   Description:  Parity error detecte during response phase           */
+#define SH_PI_FIRST_ERROR_RSP_PARITY_SHFT        22
+#define SH_PI_FIRST_ERROR_RSP_PARITY_MASK        0x0000000000400000
+
+/*   SH_PI_FIRST_ERROR_IOQ_OVERRUN                                      */
+/*   Description:  Over run error detected on IOQ                       */
+#define SH_PI_FIRST_ERROR_IOQ_OVERRUN_SHFT       23
+#define SH_PI_FIRST_ERROR_IOQ_OVERRUN_MASK       0x0000000000800000
+
+/*   SH_PI_FIRST_ERROR_REQ_FORMAT                                       */
+/*   Description:  FSB request format not supported                     */
+#define SH_PI_FIRST_ERROR_REQ_FORMAT_SHFT        24
+#define SH_PI_FIRST_ERROR_REQ_FORMAT_MASK        0x0000000001000000
+
+/*   SH_PI_FIRST_ERROR_ADDR_ACCESS                                      */
+/*   Description:  Access to Address is not supported                   */
+#define SH_PI_FIRST_ERROR_ADDR_ACCESS_SHFT       25
+#define SH_PI_FIRST_ERROR_ADDR_ACCESS_MASK       0x0000000002000000
+
+/*   SH_PI_FIRST_ERROR_REQ_PARITY                                       */
+/*   Description:  Parity error detected during request phase           */
+#define SH_PI_FIRST_ERROR_REQ_PARITY_SHFT        26
+#define SH_PI_FIRST_ERROR_REQ_PARITY_MASK        0x0000000004000000
+
+/*   SH_PI_FIRST_ERROR_ADDR_PARITY                                      */
+/*   Description:  Parity error detected on address                     */
+#define SH_PI_FIRST_ERROR_ADDR_PARITY_SHFT       27
+#define SH_PI_FIRST_ERROR_ADDR_PARITY_MASK       0x0000000008000000
+
+/*   SH_PI_FIRST_ERROR_SHUB_FSB_DQE                                     */
+/*   Description:  SHUB_FSB_DQE                                         */
+#define SH_PI_FIRST_ERROR_SHUB_FSB_DQE_SHFT      28
+#define SH_PI_FIRST_ERROR_SHUB_FSB_DQE_MASK      0x0000000010000000
+
+/*   SH_PI_FIRST_ERROR_SHUB_FSB_UCE                                     */
+/*   Description:  An un-correctable ECC error was detected             */
+#define SH_PI_FIRST_ERROR_SHUB_FSB_UCE_SHFT      29
+#define SH_PI_FIRST_ERROR_SHUB_FSB_UCE_MASK      0x0000000020000000
+
+/*   SH_PI_FIRST_ERROR_SHUB_FSB_CE                                      */
+/*   Description:  An correctable ECC error was detected                */
+#define SH_PI_FIRST_ERROR_SHUB_FSB_CE_SHFT       30
+#define SH_PI_FIRST_ERROR_SHUB_FSB_CE_MASK       0x0000000040000000
+
+/*   SH_PI_FIRST_ERROR_LIVELOCK                                         */
+/*   Description:  AFI livelock error was detected                      */
+#define SH_PI_FIRST_ERROR_LIVELOCK_SHFT          31
+#define SH_PI_FIRST_ERROR_LIVELOCK_MASK          0x0000000080000000
+
+/*   SH_PI_FIRST_ERROR_BAD_SNOOP                                        */
+/*   Description:  AFI bad snoop error was detected                     */
+#define SH_PI_FIRST_ERROR_BAD_SNOOP_SHFT         32
+#define SH_PI_FIRST_ERROR_BAD_SNOOP_MASK         0x0000000100000000
+
+/*   SH_PI_FIRST_ERROR_FSB_TBL_MISS                                     */
+/*   Description:  AFI FSB request table miss error was detected        */
+#define SH_PI_FIRST_ERROR_FSB_TBL_MISS_SHFT      33
+#define SH_PI_FIRST_ERROR_FSB_TBL_MISS_MASK      0x0000000200000000
+
+/*   SH_PI_FIRST_ERROR_MSG_LENGTH                                       */
+/*   Description:  Message length error on received message from SIC    */
+#define SH_PI_FIRST_ERROR_MSG_LENGTH_SHFT        34
+#define SH_PI_FIRST_ERROR_MSG_LENGTH_MASK        0x0000000400000000
+
+/* ==================================================================== */
+/*                  Register "SH_PI_FIRST_ERROR_ALIAS"                  */
+/*                         PI First Error Alias                         */
+/* ==================================================================== */
+
+#define SH_PI_FIRST_ERROR_ALIAS                  0x0000000120060788
+
+/* ==================================================================== */
+/*                Register "SH_PI_PI2MD_REPLY_VC_STATUS"                */
+/*                PI-to-MD Reply Virtual Channel Status                 */
+/* ==================================================================== */
+
+#define SH_PI_PI2MD_REPLY_VC_STATUS              0x0000000120060900
+#define SH_PI_PI2MD_REPLY_VC_STATUS_MASK         0x000000000000003f
+#define SH_PI_PI2MD_REPLY_VC_STATUS_INIT         0x0000000000000000
+
+/*   SH_PI_PI2MD_REPLY_VC_STATUS_OUTPUT_CRD_STAT                        */
+/*   Description:  Status of output credits                             */
+#define SH_PI_PI2MD_REPLY_VC_STATUS_OUTPUT_CRD_STAT_SHFT 0
+#define SH_PI_PI2MD_REPLY_VC_STATUS_OUTPUT_CRD_STAT_MASK 0x000000000000003f
+
+/* ==================================================================== */
+/*               Register "SH_PI_PI2MD_REQUEST_VC_STATUS"               */
+/*               PI-to-MD Request Virtual Channel Status                */
+/* ==================================================================== */
+
+#define SH_PI_PI2MD_REQUEST_VC_STATUS            0x0000000120060980
+#define SH_PI_PI2MD_REQUEST_VC_STATUS_MASK       0x000000000000003f
+#define SH_PI_PI2MD_REQUEST_VC_STATUS_INIT       0x0000000000000000
+
+/*   SH_PI_PI2MD_REQUEST_VC_STATUS_OUTPUT_CRD_STAT                      */
+/*   Description:  Status of output credits                             */
+#define SH_PI_PI2MD_REQUEST_VC_STATUS_OUTPUT_CRD_STAT_SHFT 0
+#define SH_PI_PI2MD_REQUEST_VC_STATUS_OUTPUT_CRD_STAT_MASK 0x000000000000003f
+
+/* ==================================================================== */
+/*                Register "SH_PI_PI2XN_REPLY_VC_STATUS"                */
+/*                PI-to-XN Reply Virtual Channel Status                 */
+/* ==================================================================== */
+
+#define SH_PI_PI2XN_REPLY_VC_STATUS              0x0000000120060a00
+#define SH_PI_PI2XN_REPLY_VC_STATUS_MASK         0x000000000000003f
+#define SH_PI_PI2XN_REPLY_VC_STATUS_INIT         0x0000000000000000
+
+/*   SH_PI_PI2XN_REPLY_VC_STATUS_OUTPUT_CRD_STAT                        */
+/*   Description:  Status of output credits                             */
+#define SH_PI_PI2XN_REPLY_VC_STATUS_OUTPUT_CRD_STAT_SHFT 0
+#define SH_PI_PI2XN_REPLY_VC_STATUS_OUTPUT_CRD_STAT_MASK 0x000000000000003f
+
+/* ==================================================================== */
+/*               Register "SH_PI_PI2XN_REQUEST_VC_STATUS"               */
+/*               PI-to-XN Request Virtual Channel Status                */
+/* ==================================================================== */
+
+#define SH_PI_PI2XN_REQUEST_VC_STATUS            0x0000000120060a80
+#define SH_PI_PI2XN_REQUEST_VC_STATUS_MASK       0x000000000000003f
+#define SH_PI_PI2XN_REQUEST_VC_STATUS_INIT       0x0000000000000000
+
+/*   SH_PI_PI2XN_REQUEST_VC_STATUS_OUTPUT_CRD_STAT                      */
+/*   Description:  Status of output credits                             */
+#define SH_PI_PI2XN_REQUEST_VC_STATUS_OUTPUT_CRD_STAT_SHFT 0
+#define SH_PI_PI2XN_REQUEST_VC_STATUS_OUTPUT_CRD_STAT_MASK 0x000000000000003f
+
+/* ==================================================================== */
+/*                Register "SH_PI_UNCORRECTED_DETAIL_1"                 */
+/*                    PI Uncorrected Error Detail 1                     */
+/* ==================================================================== */
+
+#define SH_PI_UNCORRECTED_DETAIL_1               0x0000000120060b00
+#define SH_PI_UNCORRECTED_DETAIL_1_MASK          0xffffffffffffffff
+#define SH_PI_UNCORRECTED_DETAIL_1_INIT          0x0000000000000000
+
+/*   SH_PI_UNCORRECTED_DETAIL_1_ADDRESS                                 */
+/*   Description:  Address of Message that logged Uncorrectable Error  */
+#define SH_PI_UNCORRECTED_DETAIL_1_ADDRESS_SHFT  0
+#define SH_PI_UNCORRECTED_DETAIL_1_ADDRESS_MASK  0x0000ffffffffffff
+
+/*   SH_PI_UNCORRECTED_DETAIL_1_SYNDROME                                */
+/*   Description:  Syndrome for double word data with Uncorrectable Er  */
+#define SH_PI_UNCORRECTED_DETAIL_1_SYNDROME_SHFT 48
+#define SH_PI_UNCORRECTED_DETAIL_1_SYNDROME_MASK 0x00ff000000000000
+
+/*   SH_PI_UNCORRECTED_DETAIL_1_DEP                                     */
+/*   Description:  DEP for Double word in error                         */
+#define SH_PI_UNCORRECTED_DETAIL_1_DEP_SHFT      56
+#define SH_PI_UNCORRECTED_DETAIL_1_DEP_MASK      0xff00000000000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_UNCORRECTED_DETAIL_2"                 */
+/*                    PI Uncorrected Error Detail 2                     */
+/* ==================================================================== */
+
+#define SH_PI_UNCORRECTED_DETAIL_2               0x0000000120060b80
+#define SH_PI_UNCORRECTED_DETAIL_2_MASK          0xffffffffffffffff
+#define SH_PI_UNCORRECTED_DETAIL_2_INIT          0x0000000000000000
+
+/*   SH_PI_UNCORRECTED_DETAIL_2_DATA                                    */
+/*   Description:  Double word data in error                            */
+#define SH_PI_UNCORRECTED_DETAIL_2_DATA_SHFT     0
+#define SH_PI_UNCORRECTED_DETAIL_2_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_PI_UNCORRECTED_DETAIL_3"                 */
+/*                    PI Uncorrected Error Detail 3                     */
+/* ==================================================================== */
+
+#define SH_PI_UNCORRECTED_DETAIL_3               0x0000000120060c00
+#define SH_PI_UNCORRECTED_DETAIL_3_MASK          0xffffffffffffffff
+#define SH_PI_UNCORRECTED_DETAIL_3_INIT          0x0000000000000000
+
+/*   SH_PI_UNCORRECTED_DETAIL_3_ADDRESS                                 */
+/*   Description:  Address of Message that logged Uncorrectable Error  */
+#define SH_PI_UNCORRECTED_DETAIL_3_ADDRESS_SHFT  0
+#define SH_PI_UNCORRECTED_DETAIL_3_ADDRESS_MASK  0x0000ffffffffffff
+
+/*   SH_PI_UNCORRECTED_DETAIL_3_SYNDROME                                */
+/*   Description:  Syndrome for double word data with Uncorrectable Er  */
+#define SH_PI_UNCORRECTED_DETAIL_3_SYNDROME_SHFT 48
+#define SH_PI_UNCORRECTED_DETAIL_3_SYNDROME_MASK 0x00ff000000000000
+
+/*   SH_PI_UNCORRECTED_DETAIL_3_DEP                                     */
+/*   Description:  DCP for Double word in error                         */
+#define SH_PI_UNCORRECTED_DETAIL_3_DEP_SHFT      56
+#define SH_PI_UNCORRECTED_DETAIL_3_DEP_MASK      0xff00000000000000
+
+/* ==================================================================== */
+/*                Register "SH_PI_UNCORRECTED_DETAIL_4"                 */
+/*                    PI Uncorrected Error Detail 4                     */
+/* ==================================================================== */
+
+#define SH_PI_UNCORRECTED_DETAIL_4               0x0000000120060c80
+#define SH_PI_UNCORRECTED_DETAIL_4_MASK          0xffffffffffffffff
+#define SH_PI_UNCORRECTED_DETAIL_4_INIT          0x0000000000000000
+
+/*   SH_PI_UNCORRECTED_DETAIL_4_DATA                                    */
+/*   Description:  Double word data in error                            */
+#define SH_PI_UNCORRECTED_DETAIL_4_DATA_SHFT     0
+#define SH_PI_UNCORRECTED_DETAIL_4_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_PI_MD2PI_REPLY_VC_STATUS"                */
+/*                MD-to-PI Reply Virtual Channel Status                 */
+/* ==================================================================== */
+
+#define SH_PI_MD2PI_REPLY_VC_STATUS              0x0000000120060800
+#define SH_PI_MD2PI_REPLY_VC_STATUS_MASK         0x0000000000000fff
+#define SH_PI_MD2PI_REPLY_VC_STATUS_INIT         0x0000000000000000
+
+/*   SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_HDR_CRD_STAT                     */
+/*   Description:  Status of input header credits                       */
+#define SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_HDR_CRD_STAT_SHFT 0
+#define SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_HDR_CRD_STAT_MASK 0x000000000000000f
+
+/*   SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_DAT_CRD_STAT                     */
+/*   Description:  Status of data credits                               */
+#define SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_DAT_CRD_STAT_SHFT 4
+#define SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_DAT_CRD_STAT_MASK 0x00000000000000f0
+
+/*   SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_QUEUE_STAT                       */
+/*   Description:  Status of MD Reply Input Queue                       */
+#define SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_QUEUE_STAT_SHFT 8
+#define SH_PI_MD2PI_REPLY_VC_STATUS_INPUT_QUEUE_STAT_MASK 0x0000000000000f00
+
+/* ==================================================================== */
+/*               Register "SH_PI_MD2PI_REQUEST_VC_STATUS"               */
+/*               MD-to-PI Request Virtual Channel Status                */
+/* ==================================================================== */
+
+#define SH_PI_MD2PI_REQUEST_VC_STATUS            0x0000000120060880
+#define SH_PI_MD2PI_REQUEST_VC_STATUS_MASK       0x0000000000000fff
+#define SH_PI_MD2PI_REQUEST_VC_STATUS_INIT       0x0000000000000000
+
+/*   SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_HDR_CRD_STAT                   */
+/*   Description:  Status of input header credits                       */
+#define SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_HDR_CRD_STAT_SHFT 0
+#define SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_HDR_CRD_STAT_MASK 0x000000000000000f
+
+/*   SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_DAT_CRD_STAT                   */
+/*   Description:  Status of input data credits                         */
+#define SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_DAT_CRD_STAT_SHFT 4
+#define SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_DAT_CRD_STAT_MASK 0x00000000000000f0
+
+/*   SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_QUEUE_STAT                     */
+/*   Description:  Status of MD Request Input Queue                     */
+#define SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_QUEUE_STAT_SHFT 8
+#define SH_PI_MD2PI_REQUEST_VC_STATUS_INPUT_QUEUE_STAT_MASK 0x0000000000000f00
+
+/* ==================================================================== */
+/*                Register "SH_PI_XN2PI_REPLY_VC_STATUS"                */
+/*                XN-to-PI Reply Virtual Channel Status                 */
+/* ==================================================================== */
+
+#define SH_PI_XN2PI_REPLY_VC_STATUS              0x0000000120060d00
+#define SH_PI_XN2PI_REPLY_VC_STATUS_MASK         0x0000000000000fff
+#define SH_PI_XN2PI_REPLY_VC_STATUS_INIT         0x0000000000000000
+
+/*   SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_HDR_CRD_STAT                     */
+/*   Description:  Status of input header credits                       */
+#define SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_HDR_CRD_STAT_SHFT 0
+#define SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_HDR_CRD_STAT_MASK 0x000000000000000f
+
+/*   SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_DAT_CRD_STAT                     */
+/*   Description:  Status of input data credits                         */
+#define SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_DAT_CRD_STAT_SHFT 4
+#define SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_DAT_CRD_STAT_MASK 0x00000000000000f0
+
+/*   SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_QUEUE_STAT                       */
+/*   Description:  Status of XN Reply Input Queue                       */
+#define SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_QUEUE_STAT_SHFT 8
+#define SH_PI_XN2PI_REPLY_VC_STATUS_INPUT_QUEUE_STAT_MASK 0x0000000000000f00
+
+/* ==================================================================== */
+/*               Register "SH_PI_XN2PI_REQUEST_VC_STATUS"               */
+/*               XN-to-PI Request Virtual Channel Status                */
+/* ==================================================================== */
+
+#define SH_PI_XN2PI_REQUEST_VC_STATUS            0x0000000120060d80
+#define SH_PI_XN2PI_REQUEST_VC_STATUS_MASK       0x0000000000000fff
+#define SH_PI_XN2PI_REQUEST_VC_STATUS_INIT       0x0000000000000000
+
+/*   SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_HDR_CRD_STAT                   */
+/*   Description:  Status of input header credits                       */
+#define SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_HDR_CRD_STAT_SHFT 0
+#define SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_HDR_CRD_STAT_MASK 0x000000000000000f
+
+/*   SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_DAT_CRD_STAT                   */
+/*   Description:  Status of input data credits                         */
+#define SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_DAT_CRD_STAT_SHFT 4
+#define SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_DAT_CRD_STAT_MASK 0x00000000000000f0
+
+/*   SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_QUEUE_STAT                     */
+/*   Description:  Status of XN Request Input Queue                     */
+#define SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_QUEUE_STAT_SHFT 8
+#define SH_PI_XN2PI_REQUEST_VC_STATUS_INPUT_QUEUE_STAT_MASK 0x0000000000000f00
+
+/* ==================================================================== */
+/*                     Register "SH_XNPI_SIC_FLOW"                      */
+/* ==================================================================== */
+
+#define SH_XNPI_SIC_FLOW                         0x0000000150030000
+#define SH_XNPI_SIC_FLOW_MASK                    0x9f1f1f1f1f1f9f9f
+#define SH_XNPI_SIC_FLOW_INIT                    0x0000080000080000
+
+/*   SH_XNPI_SIC_FLOW_DEBIT_VC0_WITHHOLD                                */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNPI_SIC_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNPI_SIC_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000001f
+
+/*   SH_XNPI_SIC_FLOW_DEBIT_VC0_FORCE_CRED                              */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNPI_SIC_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNPI_SIC_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNPI_SIC_FLOW_DEBIT_VC2_WITHHOLD                                */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNPI_SIC_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNPI_SIC_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000001f00
+
+/*   SH_XNPI_SIC_FLOW_DEBIT_VC2_FORCE_CRED                              */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNPI_SIC_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNPI_SIC_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNPI_SIC_FLOW_CREDIT_VC0_TEST                                   */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNPI_SIC_FLOW_CREDIT_VC0_TEST_SHFT    16
+#define SH_XNPI_SIC_FLOW_CREDIT_VC0_TEST_MASK    0x00000000001f0000
+
+/*   SH_XNPI_SIC_FLOW_CREDIT_VC0_DYN                                    */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNPI_SIC_FLOW_CREDIT_VC0_DYN_SHFT     24
+#define SH_XNPI_SIC_FLOW_CREDIT_VC0_DYN_MASK     0x000000001f000000
+
+/*   SH_XNPI_SIC_FLOW_CREDIT_VC0_CAP                                    */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNPI_SIC_FLOW_CREDIT_VC0_CAP_SHFT     32
+#define SH_XNPI_SIC_FLOW_CREDIT_VC0_CAP_MASK     0x0000001f00000000
+
+/*   SH_XNPI_SIC_FLOW_CREDIT_VC2_TEST                                   */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNPI_SIC_FLOW_CREDIT_VC2_TEST_SHFT    40
+#define SH_XNPI_SIC_FLOW_CREDIT_VC2_TEST_MASK    0x00001f0000000000
+
+/*   SH_XNPI_SIC_FLOW_CREDIT_VC2_DYN                                    */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNPI_SIC_FLOW_CREDIT_VC2_DYN_SHFT     48
+#define SH_XNPI_SIC_FLOW_CREDIT_VC2_DYN_MASK     0x001f000000000000
+
+/*   SH_XNPI_SIC_FLOW_CREDIT_VC2_CAP                                    */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNPI_SIC_FLOW_CREDIT_VC2_CAP_SHFT     56
+#define SH_XNPI_SIC_FLOW_CREDIT_VC2_CAP_MASK     0x1f00000000000000
+
+/*   SH_XNPI_SIC_FLOW_DISABLE_BYPASS_OUT                                */
+#define SH_XNPI_SIC_FLOW_DISABLE_BYPASS_OUT_SHFT 63
+#define SH_XNPI_SIC_FLOW_DISABLE_BYPASS_OUT_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_TO_NI0_PORT_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNPI_TO_NI0_PORT_FLOW                 0x0000000150030010
+#define SH_XNPI_TO_NI0_PORT_FLOW_MASK            0x3f3f003f3f00bfbf
+#define SH_XNPI_TO_NI0_PORT_FLOW_INIT            0x0000000000000000
+
+/*   SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC0_WITHHOLD                        */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC0_FORCE_CRED                      */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC2_WITHHOLD                        */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC2_FORCE_CRED                      */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNPI_TO_NI0_PORT_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC0_DYN                            */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC0_CAP                            */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC2_DYN                            */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC2_CAP                            */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNPI_TO_NI0_PORT_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_TO_NI1_PORT_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNPI_TO_NI1_PORT_FLOW                 0x0000000150030020
+#define SH_XNPI_TO_NI1_PORT_FLOW_MASK            0x3f3f003f3f00bfbf
+#define SH_XNPI_TO_NI1_PORT_FLOW_INIT            0x0000000000000000
+
+/*   SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC0_WITHHOLD                        */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC0_FORCE_CRED                      */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC2_WITHHOLD                        */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC2_FORCE_CRED                      */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNPI_TO_NI1_PORT_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC0_DYN                            */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC0_CAP                            */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC2_DYN                            */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC2_CAP                            */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNPI_TO_NI1_PORT_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_TO_IILB_PORT_FLOW"                 */
+/* ==================================================================== */
+
+#define SH_XNPI_TO_IILB_PORT_FLOW                0x0000000150030030
+#define SH_XNPI_TO_IILB_PORT_FLOW_MASK           0x3f3f003f3f00bfbf
+#define SH_XNPI_TO_IILB_PORT_FLOW_INIT           0x0000000000000000
+
+/*   SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC0_WITHHOLD                       */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC0_FORCE_CRED                     */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC2_WITHHOLD                       */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC2_FORCE_CRED                     */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNPI_TO_IILB_PORT_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC0_DYN                           */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC0_CAP                           */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC2_DYN                           */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC2_CAP                           */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNPI_TO_IILB_PORT_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*               Register "SH_XNPI_FR_NI0_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO            0x0000000150030040
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_MASK       0x00001f1f3f3f3f3f
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_INIT       0x00000c0c00000000
+
+/*   SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_DYN                        */
+/*   Description:  vc0 fifo entry dynamic value                         */
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_DYN_SHFT 0
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_DYN_MASK 0x000000000000003f
+
+/*   SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_CAP                        */
+/*   Description:  vc0 fifo entry captured value                        */
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_CAP_SHFT 8
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_CAP_MASK 0x0000000000003f00
+
+/*   SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_DYN                        */
+/*   Description:  vc2 fifo entry dynamic value                         */
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_DYN_SHFT 16
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_DYN_MASK 0x00000000003f0000
+
+/*   SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_CAP                        */
+/*   Description:  vc2 fifo entry  captured value                       */
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_CAP_SHFT 24
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_CAP_MASK 0x000000003f000000
+
+/*   SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_TEST                       */
+/*   Description:  vc0 test credits limit                               */
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_TEST_SHFT 32
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_TEST_MASK 0x0000001f00000000
+
+/*   SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_TEST                       */
+/*   Description:  vc2 test credits limit                               */
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_TEST_SHFT 40
+#define SH_XNPI_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_TEST_MASK 0x00001f0000000000
+
+/* ==================================================================== */
+/*               Register "SH_XNPI_FR_NI1_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO            0x0000000150030050
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_MASK       0x00001f1f3f3f3f3f
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_INIT       0x00000c0c00000000
+
+/*   SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_DYN                        */
+/*   Description:  vc0 fifo entry dynamic value                         */
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_DYN_SHFT 0
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_DYN_MASK 0x000000000000003f
+
+/*   SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_CAP                        */
+/*   Description:  vc0 fifo entry captured value                        */
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_CAP_SHFT 8
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_CAP_MASK 0x0000000000003f00
+
+/*   SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_DYN                        */
+/*   Description:  vc2 fifo entry dynamic value                         */
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_DYN_SHFT 16
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_DYN_MASK 0x00000000003f0000
+
+/*   SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_CAP                        */
+/*   Description:  vc2 fifo entry  captured value                       */
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_CAP_SHFT 24
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_CAP_MASK 0x000000003f000000
+
+/*   SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_TEST                       */
+/*   Description:  vc0 test credits limit                               */
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_TEST_SHFT 32
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_TEST_MASK 0x0000001f00000000
+
+/*   SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_TEST                       */
+/*   Description:  vc2 test credits limit                               */
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_TEST_SHFT 40
+#define SH_XNPI_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_TEST_MASK 0x00001f0000000000
+
+/* ==================================================================== */
+/*              Register "SH_XNPI_FR_IILB_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO           0x0000000150030060
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_MASK      0x00001f1f3f3f3f3f
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_INIT      0x00000c0c00000000
+
+/*   SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_DYN                       */
+/*   Description:  vc0 fifo entry dynamic value                         */
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_DYN_SHFT 0
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_DYN_MASK 0x000000000000003f
+
+/*   SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_CAP                       */
+/*   Description:  vc0 fifo entry captured value                        */
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_CAP_SHFT 8
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_CAP_MASK 0x0000000000003f00
+
+/*   SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_DYN                       */
+/*   Description:  vc2 fifo entry dynamic value                         */
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_DYN_SHFT 16
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_DYN_MASK 0x00000000003f0000
+
+/*   SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_CAP                       */
+/*   Description:  vc2 fifo entry  captured value                       */
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_CAP_SHFT 24
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_CAP_MASK 0x000000003f000000
+
+/*   SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_TEST                      */
+/*   Description:  vc0 test credits limit                               */
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_TEST_SHFT 32
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_TEST_MASK 0x0000001f00000000
+
+/*   SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_TEST                      */
+/*   Description:  vc2 test credits limit                               */
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_TEST_SHFT 40
+#define SH_XNPI_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_TEST_MASK 0x00001f0000000000
+
+/* ==================================================================== */
+/*                     Register "SH_XNMD_SIC_FLOW"                      */
+/* ==================================================================== */
+
+#define SH_XNMD_SIC_FLOW                         0x0000000150030100
+#define SH_XNMD_SIC_FLOW_MASK                    0x9f1f1f1f1f1f9f9f
+#define SH_XNMD_SIC_FLOW_INIT                    0x0000090000090000
+
+/*   SH_XNMD_SIC_FLOW_DEBIT_VC0_WITHHOLD                                */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNMD_SIC_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNMD_SIC_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000001f
+
+/*   SH_XNMD_SIC_FLOW_DEBIT_VC0_FORCE_CRED                              */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNMD_SIC_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNMD_SIC_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNMD_SIC_FLOW_DEBIT_VC2_WITHHOLD                                */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNMD_SIC_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNMD_SIC_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000001f00
+
+/*   SH_XNMD_SIC_FLOW_DEBIT_VC2_FORCE_CRED                              */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNMD_SIC_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNMD_SIC_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNMD_SIC_FLOW_CREDIT_VC0_TEST                                   */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNMD_SIC_FLOW_CREDIT_VC0_TEST_SHFT    16
+#define SH_XNMD_SIC_FLOW_CREDIT_VC0_TEST_MASK    0x00000000001f0000
+
+/*   SH_XNMD_SIC_FLOW_CREDIT_VC0_DYN                                    */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNMD_SIC_FLOW_CREDIT_VC0_DYN_SHFT     24
+#define SH_XNMD_SIC_FLOW_CREDIT_VC0_DYN_MASK     0x000000001f000000
+
+/*   SH_XNMD_SIC_FLOW_CREDIT_VC0_CAP                                    */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNMD_SIC_FLOW_CREDIT_VC0_CAP_SHFT     32
+#define SH_XNMD_SIC_FLOW_CREDIT_VC0_CAP_MASK     0x0000001f00000000
+
+/*   SH_XNMD_SIC_FLOW_CREDIT_VC2_TEST                                   */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNMD_SIC_FLOW_CREDIT_VC2_TEST_SHFT    40
+#define SH_XNMD_SIC_FLOW_CREDIT_VC2_TEST_MASK    0x00001f0000000000
+
+/*   SH_XNMD_SIC_FLOW_CREDIT_VC2_DYN                                    */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNMD_SIC_FLOW_CREDIT_VC2_DYN_SHFT     48
+#define SH_XNMD_SIC_FLOW_CREDIT_VC2_DYN_MASK     0x001f000000000000
+
+/*   SH_XNMD_SIC_FLOW_CREDIT_VC2_CAP                                    */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNMD_SIC_FLOW_CREDIT_VC2_CAP_SHFT     56
+#define SH_XNMD_SIC_FLOW_CREDIT_VC2_CAP_MASK     0x1f00000000000000
+
+/*   SH_XNMD_SIC_FLOW_DISABLE_BYPASS_OUT                                */
+#define SH_XNMD_SIC_FLOW_DISABLE_BYPASS_OUT_SHFT 63
+#define SH_XNMD_SIC_FLOW_DISABLE_BYPASS_OUT_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_TO_NI0_PORT_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNMD_TO_NI0_PORT_FLOW                 0x0000000150030110
+#define SH_XNMD_TO_NI0_PORT_FLOW_MASK            0x3f3f003f3f00bfbf
+#define SH_XNMD_TO_NI0_PORT_FLOW_INIT            0x0000000000000000
+
+/*   SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC0_WITHHOLD                        */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC0_FORCE_CRED                      */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC2_WITHHOLD                        */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC2_FORCE_CRED                      */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNMD_TO_NI0_PORT_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC0_DYN                            */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC0_CAP                            */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC2_DYN                            */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC2_CAP                            */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNMD_TO_NI0_PORT_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_TO_NI1_PORT_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNMD_TO_NI1_PORT_FLOW                 0x0000000150030120
+#define SH_XNMD_TO_NI1_PORT_FLOW_MASK            0x3f3f003f3f00bfbf
+#define SH_XNMD_TO_NI1_PORT_FLOW_INIT            0x0000000000000000
+
+/*   SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC0_WITHHOLD                        */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC0_FORCE_CRED                      */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC2_WITHHOLD                        */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC2_FORCE_CRED                      */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNMD_TO_NI1_PORT_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC0_DYN                            */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC0_CAP                            */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC2_DYN                            */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC2_CAP                            */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNMD_TO_NI1_PORT_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_TO_IILB_PORT_FLOW"                 */
+/* ==================================================================== */
+
+#define SH_XNMD_TO_IILB_PORT_FLOW                0x0000000150030130
+#define SH_XNMD_TO_IILB_PORT_FLOW_MASK           0x3f3f003f3f00bfbf
+#define SH_XNMD_TO_IILB_PORT_FLOW_INIT           0x0000000000000000
+
+/*   SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC0_WITHHOLD                       */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC0_FORCE_CRED                     */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC2_WITHHOLD                       */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC2_FORCE_CRED                     */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNMD_TO_IILB_PORT_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC0_DYN                           */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC0_DYN_SHFT 24
+#define SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC0_DYN_MASK 0x000000003f000000
+
+/*   SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC0_CAP                           */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC0_CAP_SHFT 32
+#define SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC0_CAP_MASK 0x0000003f00000000
+
+/*   SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC2_DYN                           */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC2_DYN_SHFT 48
+#define SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC2_DYN_MASK 0x003f000000000000
+
+/*   SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC2_CAP                           */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC2_CAP_SHFT 56
+#define SH_XNMD_TO_IILB_PORT_FLOW_CREDIT_VC2_CAP_MASK 0x3f00000000000000
+
+/* ==================================================================== */
+/*               Register "SH_XNMD_FR_NI0_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO            0x0000000150030140
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_MASK       0x00001f1f3f3f3f3f
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_INIT       0x00000c0c00000000
+
+/*   SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_DYN                        */
+/*   Description:  vc0 fifo entry dynamic value                         */
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_DYN_SHFT 0
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_DYN_MASK 0x000000000000003f
+
+/*   SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_CAP                        */
+/*   Description:  vc0 fifo entry captured value                        */
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_CAP_SHFT 8
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_CAP_MASK 0x0000000000003f00
+
+/*   SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_DYN                        */
+/*   Description:  vc2 fifo entry dynamic value                         */
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_DYN_SHFT 16
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_DYN_MASK 0x00000000003f0000
+
+/*   SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_CAP                        */
+/*   Description:  vc2 fifo entry  captured value                       */
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_CAP_SHFT 24
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_CAP_MASK 0x000000003f000000
+
+/*   SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_TEST                       */
+/*   Description:  vc0 test credits limit                               */
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_TEST_SHFT 32
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC0_TEST_MASK 0x0000001f00000000
+
+/*   SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_TEST                       */
+/*   Description:  vc2 test credits limit                               */
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_TEST_SHFT 40
+#define SH_XNMD_FR_NI0_PORT_FLOW_FIFO_ENTRY_VC2_TEST_MASK 0x00001f0000000000
+
+/* ==================================================================== */
+/*               Register "SH_XNMD_FR_NI1_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO            0x0000000150030150
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_MASK       0x00001f1f3f3f3f3f
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_INIT       0x00000c0c00000000
+
+/*   SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_DYN                        */
+/*   Description:  vc0 fifo entry dynamic value                         */
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_DYN_SHFT 0
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_DYN_MASK 0x000000000000003f
+
+/*   SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_CAP                        */
+/*   Description:  vc0 fifo entry captured value                        */
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_CAP_SHFT 8
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_CAP_MASK 0x0000000000003f00
+
+/*   SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_DYN                        */
+/*   Description:  vc2 fifo entry dynamic value                         */
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_DYN_SHFT 16
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_DYN_MASK 0x00000000003f0000
+
+/*   SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_CAP                        */
+/*   Description:  vc2 fifo entry  captured value                       */
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_CAP_SHFT 24
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_CAP_MASK 0x000000003f000000
+
+/*   SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_TEST                       */
+/*   Description:  vc0 test credits limit                               */
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_TEST_SHFT 32
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC0_TEST_MASK 0x0000001f00000000
+
+/*   SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_TEST                       */
+/*   Description:  vc2 test credits limit                               */
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_TEST_SHFT 40
+#define SH_XNMD_FR_NI1_PORT_FLOW_FIFO_ENTRY_VC2_TEST_MASK 0x00001f0000000000
+
+/* ==================================================================== */
+/*              Register "SH_XNMD_FR_IILB_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO           0x0000000150030160
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_MASK      0x00001f1f3f3f3f3f
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_INIT      0x00000c0c00000000
+
+/*   SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_DYN                       */
+/*   Description:  vc0 fifo entry dynamic value                         */
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_DYN_SHFT 0
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_DYN_MASK 0x000000000000003f
+
+/*   SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_CAP                       */
+/*   Description:  vc0 fifo entry captured value                        */
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_CAP_SHFT 8
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_CAP_MASK 0x0000000000003f00
+
+/*   SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_DYN                       */
+/*   Description:  vc2 fifo entry dynamic value                         */
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_DYN_SHFT 16
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_DYN_MASK 0x00000000003f0000
+
+/*   SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_CAP                       */
+/*   Description:  vc2 fifo entry  captured value                       */
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_CAP_SHFT 24
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_CAP_MASK 0x000000003f000000
+
+/*   SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_TEST                      */
+/*   Description:  vc0 test credits limit                               */
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_TEST_SHFT 32
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC0_TEST_MASK 0x0000001f00000000
+
+/*   SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_TEST                      */
+/*   Description:  vc2 test credits limit                               */
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_TEST_SHFT 40
+#define SH_XNMD_FR_IILB_PORT_FLOW_FIFO_ENTRY_VC2_TEST_MASK 0x00001f0000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNII_INTRA_FLOW"                     */
+/* ==================================================================== */
+
+#define SH_XNII_INTRA_FLOW                       0x0000000150030200
+#define SH_XNII_INTRA_FLOW_MASK                  0x7f7f7f7f7f7fbfbf
+#define SH_XNII_INTRA_FLOW_INIT                  0x00003f00003f0000
+
+/*   SH_XNII_INTRA_FLOW_DEBIT_VC0_WITHHOLD                              */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNII_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNII_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNII_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                            */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNII_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNII_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNII_INTRA_FLOW_DEBIT_VC2_WITHHOLD                              */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNII_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNII_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNII_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                            */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNII_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNII_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNII_INTRA_FLOW_CREDIT_VC0_TEST                                 */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNII_INTRA_FLOW_CREDIT_VC0_TEST_SHFT  16
+#define SH_XNII_INTRA_FLOW_CREDIT_VC0_TEST_MASK  0x00000000007f0000
+
+/*   SH_XNII_INTRA_FLOW_CREDIT_VC0_DYN                                  */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNII_INTRA_FLOW_CREDIT_VC0_DYN_SHFT   24
+#define SH_XNII_INTRA_FLOW_CREDIT_VC0_DYN_MASK   0x000000007f000000
+
+/*   SH_XNII_INTRA_FLOW_CREDIT_VC0_CAP                                  */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNII_INTRA_FLOW_CREDIT_VC0_CAP_SHFT   32
+#define SH_XNII_INTRA_FLOW_CREDIT_VC0_CAP_MASK   0x0000007f00000000
+
+/*   SH_XNII_INTRA_FLOW_CREDIT_VC2_TEST                                 */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNII_INTRA_FLOW_CREDIT_VC2_TEST_SHFT  40
+#define SH_XNII_INTRA_FLOW_CREDIT_VC2_TEST_MASK  0x00007f0000000000
+
+/*   SH_XNII_INTRA_FLOW_CREDIT_VC2_DYN                                  */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNII_INTRA_FLOW_CREDIT_VC2_DYN_SHFT   48
+#define SH_XNII_INTRA_FLOW_CREDIT_VC2_DYN_MASK   0x007f000000000000
+
+/*   SH_XNII_INTRA_FLOW_CREDIT_VC2_CAP                                  */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNII_INTRA_FLOW_CREDIT_VC2_CAP_SHFT   56
+#define SH_XNII_INTRA_FLOW_CREDIT_VC2_CAP_MASK   0x7f00000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNLB_INTRA_FLOW"                     */
+/* ==================================================================== */
+
+#define SH_XNLB_INTRA_FLOW                       0x0000000150030210
+#define SH_XNLB_INTRA_FLOW_MASK                  0xff7f7f7f7f7fbfbf
+#define SH_XNLB_INTRA_FLOW_INIT                  0x0000080000100000
+
+/*   SH_XNLB_INTRA_FLOW_DEBIT_VC0_WITHHOLD                              */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNLB_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNLB_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNLB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                            */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNLB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNLB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNLB_INTRA_FLOW_DEBIT_VC2_WITHHOLD                              */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNLB_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNLB_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNLB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                            */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNLB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNLB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNLB_INTRA_FLOW_CREDIT_VC0_TEST                                 */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC0_TEST_SHFT  16
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC0_TEST_MASK  0x00000000007f0000
+
+/*   SH_XNLB_INTRA_FLOW_CREDIT_VC0_DYN                                  */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC0_DYN_SHFT   24
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC0_DYN_MASK   0x000000007f000000
+
+/*   SH_XNLB_INTRA_FLOW_CREDIT_VC0_CAP                                  */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC0_CAP_SHFT   32
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC0_CAP_MASK   0x0000007f00000000
+
+/*   SH_XNLB_INTRA_FLOW_CREDIT_VC2_TEST                                 */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC2_TEST_SHFT  40
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC2_TEST_MASK  0x00007f0000000000
+
+/*   SH_XNLB_INTRA_FLOW_CREDIT_VC2_DYN                                  */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC2_DYN_SHFT   48
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC2_DYN_MASK   0x007f000000000000
+
+/*   SH_XNLB_INTRA_FLOW_CREDIT_VC2_CAP                                  */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC2_CAP_SHFT   56
+#define SH_XNLB_INTRA_FLOW_CREDIT_VC2_CAP_MASK   0x7f00000000000000
+
+/*   SH_XNLB_INTRA_FLOW_DISABLE_BYPASS_IN                               */
+#define SH_XNLB_INTRA_FLOW_DISABLE_BYPASS_IN_SHFT 63
+#define SH_XNLB_INTRA_FLOW_DISABLE_BYPASS_IN_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT        0x0000000150030220
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_MASK   0x7f7f007f7f00bfbf
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_INIT   0x0000000000000000
+
+/*   SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_WITHHOLD                     */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                   */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_WITHHOLD                     */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                   */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_DYN                          */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_CAP                          */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_DYN                          */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_CAP                          */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT        0x0000000150030230
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_MASK   0x7f7f007f7f00bfbf
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_INIT   0x0000000000000000
+
+/*   SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_WITHHOLD                     */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                   */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_WITHHOLD                     */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                   */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_DYN                          */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_CAP                          */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_DYN                          */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_CAP                          */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT         0x0000000150030240
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_MASK    0x7f7f007f7f00bfbf
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_INIT    0x0000000000000000
+
+/*   SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD                      */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                    */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD                      */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                    */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN                           */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP                           */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN                           */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP                           */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*            Register "SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT       0x0000000150030250
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_MASK  0x7f7f007f7f00bfbf
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_INIT  0x0000000000000000
+
+/*   SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD                    */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                  */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD                    */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                  */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN                         */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP                         */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN                         */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP                         */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT         0x0000000150030260
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_MASK    0x7f7f007f7f00bfbf
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_INIT    0x0000000000000000
+
+/*   SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD                      */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                    */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD                      */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                    */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN                           */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP                           */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN                           */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP                           */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*            Register "SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT       0x0000000150030270
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_MASK  0x00007f7f7f7f7f7f
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_INIT  0x000000000c00000c
+
+/*   SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_TEST                        */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_DYN                         */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_CAP                         */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_TEST                        */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_DYN                         */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_CAP                         */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*            Register "SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT       0x0000000150030280
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_MASK  0x00007f7f7f7f7f7f
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_INIT  0x000000000c00000c
+
+/*   SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_TEST                        */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_DYN                         */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_CAP                         */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_TEST                        */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_DYN                         */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_CAP                         */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT        0x0000000150030290
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_MASK   0x00007f7f7f7f7f7f
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_INIT   0x000000000c00000c
+
+/*   SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST                         */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN                          */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP                          */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST                         */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN                          */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP                          */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*            Register "SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT"            */
+/* ==================================================================== */
+
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT      0x00000001500302a0
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_MASK 0x00007f7f7f7f7f7f
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_INIT 0x000000000c00000c
+
+/*   SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST                       */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN                        */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP                        */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST                       */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN                        */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP                        */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT        0x00000001500302b0
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_MASK   0x00007f7f7f7f7f7f
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_INIT   0x000000000c00000c
+
+/*   SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST                         */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN                          */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP                          */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST                         */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN                          */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP                          */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*              Register "SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT          0x0000000150030300
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_MASK     0x7f7f007f7f00bfbf
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_INIT     0x0000000000000000
+
+/*   SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD                       */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                     */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD                       */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                     */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN                            */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP                            */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN                            */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP                            */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*              Register "SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT          0x0000000150030310
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_MASK     0x7f7f007f7f00bfbf
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_INIT     0x0000000000000000
+
+/*   SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD                       */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                     */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD                       */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                     */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN                            */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP                            */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN                            */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP                            */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT        0x0000000150030320
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_MASK   0x7f7f007f7f00bfbf
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_INIT   0x0000000000000000
+
+/*   SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD                     */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                   */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD                     */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                   */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN                          */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP                          */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN                          */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP                          */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT"              */
+/* ==================================================================== */
+
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT         0x0000000150030330
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_MASK    0x00007f7f7f7f7f7f
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_INIT    0x000000000c00000c
+
+/*   SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST                          */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN                           */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP                           */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST                          */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN                           */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP                           */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT"              */
+/* ==================================================================== */
+
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT         0x0000000150030340
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_MASK    0x00007f7f7f7f7f7f
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_INIT    0x000000000c00000c
+
+/*   SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST                          */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN                           */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP                           */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST                          */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN                           */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP                           */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*            Register "SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT       0x0000000150030350
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_MASK  0x00007f7f7f7f7f7f
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_INIT  0x000000000c00000c
+
+/*   SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST                        */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN                         */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP                         */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST                        */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN                         */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP                         */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_0_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI0_0_INTRANI_FLOW                  0x0000000150030360
+#define SH_XNNI0_0_INTRANI_FLOW_MASK             0x00000000000000bf
+#define SH_XNNI0_0_INTRANI_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI0_0_INTRANI_FLOW_DEBIT_VC0_WITHHOLD                         */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI0_0_INTRANI_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI0_0_INTRANI_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_0_INTRANI_FLOW_DEBIT_VC0_FORCE_CRED                       */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI0_0_INTRANI_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI0_0_INTRANI_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_1_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI0_1_INTRANI_FLOW                  0x0000000150030370
+#define SH_XNNI0_1_INTRANI_FLOW_MASK             0x00000000000000bf
+#define SH_XNNI0_1_INTRANI_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI0_1_INTRANI_FLOW_DEBIT_VC1_WITHHOLD                         */
+/*   Description:  vc1 withhold                                         */
+#define SH_XNNI0_1_INTRANI_FLOW_DEBIT_VC1_WITHHOLD_SHFT 0
+#define SH_XNNI0_1_INTRANI_FLOW_DEBIT_VC1_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_1_INTRANI_FLOW_DEBIT_VC1_FORCE_CRED                       */
+/*   Description:  Force Credit on VC1 from debit cntr                  */
+#define SH_XNNI0_1_INTRANI_FLOW_DEBIT_VC1_FORCE_CRED_SHFT 7
+#define SH_XNNI0_1_INTRANI_FLOW_DEBIT_VC1_FORCE_CRED_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_2_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI0_2_INTRANI_FLOW                  0x0000000150030380
+#define SH_XNNI0_2_INTRANI_FLOW_MASK             0x00000000000000bf
+#define SH_XNNI0_2_INTRANI_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI0_2_INTRANI_FLOW_DEBIT_VC2_WITHHOLD                         */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI0_2_INTRANI_FLOW_DEBIT_VC2_WITHHOLD_SHFT 0
+#define SH_XNNI0_2_INTRANI_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_2_INTRANI_FLOW_DEBIT_VC2_FORCE_CRED                       */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI0_2_INTRANI_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 7
+#define SH_XNNI0_2_INTRANI_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_3_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI0_3_INTRANI_FLOW                  0x0000000150030390
+#define SH_XNNI0_3_INTRANI_FLOW_MASK             0x00000000000000bf
+#define SH_XNNI0_3_INTRANI_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI0_3_INTRANI_FLOW_DEBIT_VC3_WITHHOLD                         */
+/*   Description:  vc3 withhold                                         */
+#define SH_XNNI0_3_INTRANI_FLOW_DEBIT_VC3_WITHHOLD_SHFT 0
+#define SH_XNNI0_3_INTRANI_FLOW_DEBIT_VC3_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI0_3_INTRANI_FLOW_DEBIT_VC3_FORCE_CRED                       */
+/*   Description:  Force Credit on VC3 from debit cntr                  */
+#define SH_XNNI0_3_INTRANI_FLOW_DEBIT_VC3_FORCE_CRED_SHFT 7
+#define SH_XNNI0_3_INTRANI_FLOW_DEBIT_VC3_FORCE_CRED_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_VCSWITCH_FLOW"                   */
+/* ==================================================================== */
+
+#define SH_XNNI0_VCSWITCH_FLOW                   0x00000001500303a0
+#define SH_XNNI0_VCSWITCH_FLOW_MASK              0x0000000701010101
+#define SH_XNNI0_VCSWITCH_FLOW_INIT              0x0000000000000000
+
+/*   SH_XNNI0_VCSWITCH_FLOW_NI_VCFIFO_DATELINE_SWITCH                   */
+/*   Description:  Swap VC0/2 with VC1/3                                */
+#define SH_XNNI0_VCSWITCH_FLOW_NI_VCFIFO_DATELINE_SWITCH_SHFT 0
+#define SH_XNNI0_VCSWITCH_FLOW_NI_VCFIFO_DATELINE_SWITCH_MASK 0x0000000000000001
+
+/*   SH_XNNI0_VCSWITCH_FLOW_PI_VCFIFO_SWITCH                            */
+/*   Description:  Swap VC0/2 with VC1/3                                */
+#define SH_XNNI0_VCSWITCH_FLOW_PI_VCFIFO_SWITCH_SHFT 8
+#define SH_XNNI0_VCSWITCH_FLOW_PI_VCFIFO_SWITCH_MASK 0x0000000000000100
+
+/*   SH_XNNI0_VCSWITCH_FLOW_MD_VCFIFO_SWITCH                            */
+/*   Description:  Swap VC0/2 with VC1/3                                */
+#define SH_XNNI0_VCSWITCH_FLOW_MD_VCFIFO_SWITCH_SHFT 16
+#define SH_XNNI0_VCSWITCH_FLOW_MD_VCFIFO_SWITCH_MASK 0x0000000000010000
+
+/*   SH_XNNI0_VCSWITCH_FLOW_IILB_VCFIFO_SWITCH                          */
+/*   Description:  Swap VC0/2 with VC1/3                                */
+#define SH_XNNI0_VCSWITCH_FLOW_IILB_VCFIFO_SWITCH_SHFT 24
+#define SH_XNNI0_VCSWITCH_FLOW_IILB_VCFIFO_SWITCH_MASK 0x0000000001000000
+
+/*   SH_XNNI0_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_IN                      */
+#define SH_XNNI0_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_IN_SHFT 32
+#define SH_XNNI0_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_IN_MASK 0x0000000100000000
+
+/*   SH_XNNI0_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_OUT                     */
+#define SH_XNNI0_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_OUT_SHFT 33
+#define SH_XNNI0_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_OUT_MASK 0x0000000200000000
+
+/*   SH_XNNI0_VCSWITCH_FLOW_ASYNC_FIFOES                                */
+#define SH_XNNI0_VCSWITCH_FLOW_ASYNC_FIFOES_SHFT 34
+#define SH_XNNI0_VCSWITCH_FLOW_ASYNC_FIFOES_MASK 0x0000000400000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI0_TIMER_REG"                     */
+/* ==================================================================== */
+
+#define SH_XNNI0_TIMER_REG                       0x00000001500303b0
+#define SH_XNNI0_TIMER_REG_MASK                  0x0000000100ffffff
+#define SH_XNNI0_TIMER_REG_INIT                  0x0000000000ffffff
+
+/*   SH_XNNI0_TIMER_REG_TIMEOUT_REG                                     */
+/*   Description:  Master Timeout Counter                               */
+#define SH_XNNI0_TIMER_REG_TIMEOUT_REG_SHFT      0
+#define SH_XNNI0_TIMER_REG_TIMEOUT_REG_MASK      0x0000000000ffffff
+
+/*   SH_XNNI0_TIMER_REG_LINKCLEANUP_REG                                 */
+/*   Description:  Link Clean Up                                        */
+#define SH_XNNI0_TIMER_REG_LINKCLEANUP_REG_SHFT  32
+#define SH_XNNI0_TIMER_REG_LINKCLEANUP_REG_MASK  0x0000000100000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_FIFO02_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI0_FIFO02_FLOW                     0x00000001500303c0
+#define SH_XNNI0_FIFO02_FLOW_MASK                0x00000f0f0f0f0f0f
+#define SH_XNNI0_FIFO02_FLOW_INIT                0x0000000000000000
+
+/*   SH_XNNI0_FIFO02_FLOW_COUNT_VC0_LIMIT                               */
+/*   Description:  limit reg zero disables functionality                */
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC0_LIMIT_SHFT 0
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC0_LIMIT_MASK 0x000000000000000f
+
+/*   SH_XNNI0_FIFO02_FLOW_COUNT_VC0_DYN                                 */
+/*   Description:  dynamic counter value                                */
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC0_DYN_SHFT  8
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC0_DYN_MASK  0x0000000000000f00
+
+/*   SH_XNNI0_FIFO02_FLOW_COUNT_VC0_CAP                                 */
+/*   Description:  captured counter value                               */
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC0_CAP_SHFT  16
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC0_CAP_MASK  0x00000000000f0000
+
+/*   SH_XNNI0_FIFO02_FLOW_COUNT_VC2_LIMIT                               */
+/*   Description:  limit reg zero disables functionality                */
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC2_LIMIT_SHFT 24
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC2_LIMIT_MASK 0x000000000f000000
+
+/*   SH_XNNI0_FIFO02_FLOW_COUNT_VC2_DYN                                 */
+/*   Description:  counter dynamic value                                */
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC2_DYN_SHFT  32
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC2_DYN_MASK  0x0000000f00000000
+
+/*   SH_XNNI0_FIFO02_FLOW_COUNT_VC2_CAP                                 */
+/*   Description:  captured counter value                               */
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC2_CAP_SHFT  40
+#define SH_XNNI0_FIFO02_FLOW_COUNT_VC2_CAP_MASK  0x00000f0000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_FIFO13_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI0_FIFO13_FLOW                     0x00000001500303d0
+#define SH_XNNI0_FIFO13_FLOW_MASK                0x00000f0f0f0f0f0f
+#define SH_XNNI0_FIFO13_FLOW_INIT                0x0000000000000000
+
+/*   SH_XNNI0_FIFO13_FLOW_COUNT_VC1_LIMIT                               */
+/*   Description:  limit reg zero disables functionality                */
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC1_LIMIT_SHFT 0
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC1_LIMIT_MASK 0x000000000000000f
+
+/*   SH_XNNI0_FIFO13_FLOW_COUNT_VC1_DYN                                 */
+/*   Description:  dynamic counter value                                */
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC1_DYN_SHFT  8
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC1_DYN_MASK  0x0000000000000f00
+
+/*   SH_XNNI0_FIFO13_FLOW_COUNT_VC1_CAP                                 */
+/*   Description:  captured counter value                               */
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC1_CAP_SHFT  16
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC1_CAP_MASK  0x00000000000f0000
+
+/*   SH_XNNI0_FIFO13_FLOW_COUNT_VC3_LIMIT                               */
+/*   Description:  limit reg zero disables functionality                */
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC3_LIMIT_SHFT 24
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC3_LIMIT_MASK 0x000000000f000000
+
+/*   SH_XNNI0_FIFO13_FLOW_COUNT_VC3_DYN                                 */
+/*   Description:  counter dynamic value                                */
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC3_DYN_SHFT  32
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC3_DYN_MASK  0x0000000f00000000
+
+/*   SH_XNNI0_FIFO13_FLOW_COUNT_VC3_CAP                                 */
+/*   Description:  captured counter value                               */
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC3_CAP_SHFT  40
+#define SH_XNNI0_FIFO13_FLOW_COUNT_VC3_CAP_MASK  0x00000f0000000000
+
+/* ==================================================================== */
+/*                     Register "SH_XNNI0_NI_FLOW"                      */
+/* ==================================================================== */
+
+#define SH_XNNI0_NI_FLOW                         0x00000001500303e0
+#define SH_XNNI0_NI_FLOW_MASK                    0xff0fff0fff0fff0f
+#define SH_XNNI0_NI_FLOW_INIT                    0x0000000000000000
+
+/*   SH_XNNI0_NI_FLOW_VC0_LIMIT                                         */
+/*   Description:  vc0 limit reg, zero disables functionality           */
+#define SH_XNNI0_NI_FLOW_VC0_LIMIT_SHFT          0
+#define SH_XNNI0_NI_FLOW_VC0_LIMIT_MASK          0x000000000000000f
+
+/*   SH_XNNI0_NI_FLOW_VC0_DYN                                           */
+/*   Description:  vc0 counter dynamic value                            */
+#define SH_XNNI0_NI_FLOW_VC0_DYN_SHFT            8
+#define SH_XNNI0_NI_FLOW_VC0_DYN_MASK            0x0000000000000f00
+
+/*   SH_XNNI0_NI_FLOW_VC0_CAP                                           */
+/*   Description:  vc0 counter captured value                           */
+#define SH_XNNI0_NI_FLOW_VC0_CAP_SHFT            12
+#define SH_XNNI0_NI_FLOW_VC0_CAP_MASK            0x000000000000f000
+
+/*   SH_XNNI0_NI_FLOW_VC1_LIMIT                                         */
+/*   Description:  vc1 limit reg, zero disables functionality           */
+#define SH_XNNI0_NI_FLOW_VC1_LIMIT_SHFT          16
+#define SH_XNNI0_NI_FLOW_VC1_LIMIT_MASK          0x00000000000f0000
+
+/*   SH_XNNI0_NI_FLOW_VC1_DYN                                           */
+/*   Description:  vc1 counter dynamic value                            */
+#define SH_XNNI0_NI_FLOW_VC1_DYN_SHFT            24
+#define SH_XNNI0_NI_FLOW_VC1_DYN_MASK            0x000000000f000000
+
+/*   SH_XNNI0_NI_FLOW_VC1_CAP                                           */
+/*   Description:  vc1 counter captured value                           */
+#define SH_XNNI0_NI_FLOW_VC1_CAP_SHFT            28
+#define SH_XNNI0_NI_FLOW_VC1_CAP_MASK            0x00000000f0000000
+
+/*   SH_XNNI0_NI_FLOW_VC2_LIMIT                                         */
+/*   Description:  vc2 limit reg, zero disables functionality           */
+#define SH_XNNI0_NI_FLOW_VC2_LIMIT_SHFT          32
+#define SH_XNNI0_NI_FLOW_VC2_LIMIT_MASK          0x0000000f00000000
+
+/*   SH_XNNI0_NI_FLOW_VC2_DYN                                           */
+/*   Description:  vc2 counter dynamic value                            */
+#define SH_XNNI0_NI_FLOW_VC2_DYN_SHFT            40
+#define SH_XNNI0_NI_FLOW_VC2_DYN_MASK            0x00000f0000000000
+
+/*   SH_XNNI0_NI_FLOW_VC2_CAP                                           */
+/*   Description:  vc2 counter captured value                           */
+#define SH_XNNI0_NI_FLOW_VC2_CAP_SHFT            44
+#define SH_XNNI0_NI_FLOW_VC2_CAP_MASK            0x0000f00000000000
+
+/*   SH_XNNI0_NI_FLOW_VC3_LIMIT                                         */
+/*   Description:  vc3 limit reg, zero disables functionality           */
+#define SH_XNNI0_NI_FLOW_VC3_LIMIT_SHFT          48
+#define SH_XNNI0_NI_FLOW_VC3_LIMIT_MASK          0x000f000000000000
+
+/*   SH_XNNI0_NI_FLOW_VC3_DYN                                           */
+/*   Description:  vc3 counter dynamic value                            */
+#define SH_XNNI0_NI_FLOW_VC3_DYN_SHFT            56
+#define SH_XNNI0_NI_FLOW_VC3_DYN_MASK            0x0f00000000000000
+
+/*   SH_XNNI0_NI_FLOW_VC3_CAP                                           */
+/*   Description:  vc3 counter captured value                           */
+#define SH_XNNI0_NI_FLOW_VC3_CAP_SHFT            60
+#define SH_XNNI0_NI_FLOW_VC3_CAP_MASK            0xf000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI0_DEAD_FLOW"                     */
+/* ==================================================================== */
+
+#define SH_XNNI0_DEAD_FLOW                       0x00000001500303f0
+#define SH_XNNI0_DEAD_FLOW_MASK                  0xff0fff0fff0fff0f
+#define SH_XNNI0_DEAD_FLOW_INIT                  0x0000000000000000
+
+/*   SH_XNNI0_DEAD_FLOW_VC0_LIMIT                                       */
+/*   Description:  vc0 limit reg, zero disables functionality           */
+#define SH_XNNI0_DEAD_FLOW_VC0_LIMIT_SHFT        0
+#define SH_XNNI0_DEAD_FLOW_VC0_LIMIT_MASK        0x000000000000000f
+
+/*   SH_XNNI0_DEAD_FLOW_VC0_DYN                                         */
+/*   Description:  vc0 counter dynamic value                            */
+#define SH_XNNI0_DEAD_FLOW_VC0_DYN_SHFT          8
+#define SH_XNNI0_DEAD_FLOW_VC0_DYN_MASK          0x0000000000000f00
+
+/*   SH_XNNI0_DEAD_FLOW_VC0_CAP                                         */
+/*   Description:  vc0 counter captured value                           */
+#define SH_XNNI0_DEAD_FLOW_VC0_CAP_SHFT          12
+#define SH_XNNI0_DEAD_FLOW_VC0_CAP_MASK          0x000000000000f000
+
+/*   SH_XNNI0_DEAD_FLOW_VC1_LIMIT                                       */
+/*   Description:  vc1 limit reg, zero disables functionality           */
+#define SH_XNNI0_DEAD_FLOW_VC1_LIMIT_SHFT        16
+#define SH_XNNI0_DEAD_FLOW_VC1_LIMIT_MASK        0x00000000000f0000
+
+/*   SH_XNNI0_DEAD_FLOW_VC1_DYN                                         */
+/*   Description:  vc1 counter dynamic value                            */
+#define SH_XNNI0_DEAD_FLOW_VC1_DYN_SHFT          24
+#define SH_XNNI0_DEAD_FLOW_VC1_DYN_MASK          0x000000000f000000
+
+/*   SH_XNNI0_DEAD_FLOW_VC1_CAP                                         */
+/*   Description:  vc1 counter captured value                           */
+#define SH_XNNI0_DEAD_FLOW_VC1_CAP_SHFT          28
+#define SH_XNNI0_DEAD_FLOW_VC1_CAP_MASK          0x00000000f0000000
+
+/*   SH_XNNI0_DEAD_FLOW_VC2_LIMIT                                       */
+/*   Description:  vc2 limit reg, zero disables functionality           */
+#define SH_XNNI0_DEAD_FLOW_VC2_LIMIT_SHFT        32
+#define SH_XNNI0_DEAD_FLOW_VC2_LIMIT_MASK        0x0000000f00000000
+
+/*   SH_XNNI0_DEAD_FLOW_VC2_DYN                                         */
+/*   Description:  vc2 counter dynamic value                            */
+#define SH_XNNI0_DEAD_FLOW_VC2_DYN_SHFT          40
+#define SH_XNNI0_DEAD_FLOW_VC2_DYN_MASK          0x00000f0000000000
+
+/*   SH_XNNI0_DEAD_FLOW_VC2_CAP                                         */
+/*   Description:  vc2 counter captured value                           */
+#define SH_XNNI0_DEAD_FLOW_VC2_CAP_SHFT          44
+#define SH_XNNI0_DEAD_FLOW_VC2_CAP_MASK          0x0000f00000000000
+
+/*   SH_XNNI0_DEAD_FLOW_VC3_LIMIT                                       */
+/*   Description:  vc3 limit reg, zero disables functionality           */
+#define SH_XNNI0_DEAD_FLOW_VC3_LIMIT_SHFT        48
+#define SH_XNNI0_DEAD_FLOW_VC3_LIMIT_MASK        0x000f000000000000
+
+/*   SH_XNNI0_DEAD_FLOW_VC3_DYN                                         */
+/*   Description:  vc3 counter dynamic value                            */
+#define SH_XNNI0_DEAD_FLOW_VC3_DYN_SHFT          56
+#define SH_XNNI0_DEAD_FLOW_VC3_DYN_MASK          0x0f00000000000000
+
+/*   SH_XNNI0_DEAD_FLOW_VC3_CAP                                         */
+/*   Description:  vc3 counter captured value                           */
+#define SH_XNNI0_DEAD_FLOW_VC3_CAP_SHFT          60
+#define SH_XNNI0_DEAD_FLOW_VC3_CAP_MASK          0xf000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI0_INJECT_AGE"                    */
+/* ==================================================================== */
+
+#define SH_XNNI0_INJECT_AGE                      0x0000000150030400
+#define SH_XNNI0_INJECT_AGE_MASK                 0x000000000000ffff
+#define SH_XNNI0_INJECT_AGE_INIT                 0x0000000000000000
+
+/*   SH_XNNI0_INJECT_AGE_REQUEST_INJECT                                 */
+/*   Description:  Value of AGE field for outgoing requests             */
+#define SH_XNNI0_INJECT_AGE_REQUEST_INJECT_SHFT  0
+#define SH_XNNI0_INJECT_AGE_REQUEST_INJECT_MASK  0x00000000000000ff
+
+/*   SH_XNNI0_INJECT_AGE_REPLY_INJECT                                   */
+/*   Description:  Value of AGE field for outgoing replies              */
+#define SH_XNNI0_INJECT_AGE_REPLY_INJECT_SHFT    8
+#define SH_XNNI0_INJECT_AGE_REPLY_INJECT_MASK    0x000000000000ff00
+
+/* ==================================================================== */
+/*              Register "SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT          0x0000000150030500
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_MASK     0x7f7f007f7f00bfbf
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_INIT     0x0000000000000000
+
+/*   SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD                       */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                     */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD                       */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                     */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN                            */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP                            */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN                            */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP                            */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*              Register "SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT          0x0000000150030510
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_MASK     0x7f7f007f7f00bfbf
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_INIT     0x0000000000000000
+
+/*   SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD                       */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                     */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD                       */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                     */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN                            */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP                            */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN                            */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP                            */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT        0x0000000150030520
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_MASK   0x7f7f007f7f00bfbf
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_INIT   0x0000000000000000
+
+/*   SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD                     */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED                   */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/*   SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD                     */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD_SHFT 8
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x0000000000003f00
+
+/*   SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED                   */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 15
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000008000
+
+/*   SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN                          */
+/*   Description:  vc0 debit dynamic value                              */
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN_SHFT 24
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_DYN_MASK 0x000000007f000000
+
+/*   SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP                          */
+/*   Description:  vc0 debit captured value                             */
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP_SHFT 32
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC0_CAP_MASK 0x0000007f00000000
+
+/*   SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN                          */
+/*   Description:  vc2 debit dynamic value                              */
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN_SHFT 48
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_DYN_MASK 0x007f000000000000
+
+/*   SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP                          */
+/*   Description:  vc2 debit captured value                             */
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP_SHFT 56
+#define SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT_VC2_CAP_MASK 0x7f00000000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT"              */
+/* ==================================================================== */
+
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT         0x0000000150030530
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_MASK    0x00007f7f7f7f7f7f
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_INIT    0x000000000c00000c
+
+/*   SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST                          */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN                           */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP                           */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST                          */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN                           */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP                           */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*             Register "SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT"              */
+/* ==================================================================== */
+
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT         0x0000000150030540
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_MASK    0x00007f7f7f7f7f7f
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_INIT    0x000000000c00000c
+
+/*   SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST                          */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN                           */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP                           */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST                          */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN                           */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP                           */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*            Register "SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT       0x0000000150030550
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_MASK  0x00007f7f7f7f7f7f
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_INIT  0x000000000c00000c
+
+/*   SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST                        */
+/*   Description:  vc0 credit_test                                      */
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST_SHFT 0
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_TEST_MASK 0x000000000000007f
+
+/*   SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN                         */
+/*   Description:  vc0 credit dynamic value                             */
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN_SHFT 8
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_DYN_MASK 0x0000000000007f00
+
+/*   SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP                         */
+/*   Description:  vc0 credit captured value                            */
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP_SHFT 16
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC0_CAP_MASK 0x00000000007f0000
+
+/*   SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST                        */
+/*   Description:  vc2 credit_test                                      */
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST_SHFT 24
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_TEST_MASK 0x000000007f000000
+
+/*   SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN                         */
+/*   Description:  vc2 credit dynamic value                             */
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN_SHFT 32
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_DYN_MASK 0x0000007f00000000
+
+/*   SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP                         */
+/*   Description:  vc2 credit captured value                            */
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP_SHFT 40
+#define SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT_VC2_CAP_MASK 0x00007f0000000000
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_0_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI1_0_INTRANI_FLOW                  0x0000000150030560
+#define SH_XNNI1_0_INTRANI_FLOW_MASK             0x00000000000000bf
+#define SH_XNNI1_0_INTRANI_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI1_0_INTRANI_FLOW_DEBIT_VC0_WITHHOLD                         */
+/*   Description:  vc0 withhold                                         */
+#define SH_XNNI1_0_INTRANI_FLOW_DEBIT_VC0_WITHHOLD_SHFT 0
+#define SH_XNNI1_0_INTRANI_FLOW_DEBIT_VC0_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_0_INTRANI_FLOW_DEBIT_VC0_FORCE_CRED                       */
+/*   Description:  Force Credit on VC0 from debit cntr                  */
+#define SH_XNNI1_0_INTRANI_FLOW_DEBIT_VC0_FORCE_CRED_SHFT 7
+#define SH_XNNI1_0_INTRANI_FLOW_DEBIT_VC0_FORCE_CRED_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_1_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI1_1_INTRANI_FLOW                  0x0000000150030570
+#define SH_XNNI1_1_INTRANI_FLOW_MASK             0x00000000000000bf
+#define SH_XNNI1_1_INTRANI_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI1_1_INTRANI_FLOW_DEBIT_VC1_WITHHOLD                         */
+/*   Description:  vc1 withhold                                         */
+#define SH_XNNI1_1_INTRANI_FLOW_DEBIT_VC1_WITHHOLD_SHFT 0
+#define SH_XNNI1_1_INTRANI_FLOW_DEBIT_VC1_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_1_INTRANI_FLOW_DEBIT_VC1_FORCE_CRED                       */
+/*   Description:  Force Credit on VC1 from debit cntr                  */
+#define SH_XNNI1_1_INTRANI_FLOW_DEBIT_VC1_FORCE_CRED_SHFT 7
+#define SH_XNNI1_1_INTRANI_FLOW_DEBIT_VC1_FORCE_CRED_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_2_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI1_2_INTRANI_FLOW                  0x0000000150030580
+#define SH_XNNI1_2_INTRANI_FLOW_MASK             0x00000000000000bf
+#define SH_XNNI1_2_INTRANI_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI1_2_INTRANI_FLOW_DEBIT_VC2_WITHHOLD                         */
+/*   Description:  vc2 withhold                                         */
+#define SH_XNNI1_2_INTRANI_FLOW_DEBIT_VC2_WITHHOLD_SHFT 0
+#define SH_XNNI1_2_INTRANI_FLOW_DEBIT_VC2_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_2_INTRANI_FLOW_DEBIT_VC2_FORCE_CRED                       */
+/*   Description:  Force Credit on VC2 from debit cntr                  */
+#define SH_XNNI1_2_INTRANI_FLOW_DEBIT_VC2_FORCE_CRED_SHFT 7
+#define SH_XNNI1_2_INTRANI_FLOW_DEBIT_VC2_FORCE_CRED_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_3_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNNI1_3_INTRANI_FLOW                  0x0000000150030590
+#define SH_XNNI1_3_INTRANI_FLOW_MASK             0x00000000000000bf
+#define SH_XNNI1_3_INTRANI_FLOW_INIT             0x0000000000000000
+
+/*   SH_XNNI1_3_INTRANI_FLOW_DEBIT_VC3_WITHHOLD                         */
+/*   Description:  vc3 withhold                                         */
+#define SH_XNNI1_3_INTRANI_FLOW_DEBIT_VC3_WITHHOLD_SHFT 0
+#define SH_XNNI1_3_INTRANI_FLOW_DEBIT_VC3_WITHHOLD_MASK 0x000000000000003f
+
+/*   SH_XNNI1_3_INTRANI_FLOW_DEBIT_VC3_FORCE_CRED                       */
+/*   Description:  Force Credit on VC3 from debit cntr                  */
+#define SH_XNNI1_3_INTRANI_FLOW_DEBIT_VC3_FORCE_CRED_SHFT 7
+#define SH_XNNI1_3_INTRANI_FLOW_DEBIT_VC3_FORCE_CRED_MASK 0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_VCSWITCH_FLOW"                   */
+/* ==================================================================== */
+
+#define SH_XNNI1_VCSWITCH_FLOW                   0x00000001500305a0
+#define SH_XNNI1_VCSWITCH_FLOW_MASK              0x0000000701010101
+#define SH_XNNI1_VCSWITCH_FLOW_INIT              0x0000000000000000
+
+/*   SH_XNNI1_VCSWITCH_FLOW_NI_VCFIFO_DATELINE_SWITCH                   */
+/*   Description:  Swap VC0/2 with VC1/3                                */
+#define SH_XNNI1_VCSWITCH_FLOW_NI_VCFIFO_DATELINE_SWITCH_SHFT 0
+#define SH_XNNI1_VCSWITCH_FLOW_NI_VCFIFO_DATELINE_SWITCH_MASK 0x0000000000000001
+
+/*   SH_XNNI1_VCSWITCH_FLOW_PI_VCFIFO_SWITCH                            */
+/*   Description:  Swap VC0/2 with VC1/3                                */
+#define SH_XNNI1_VCSWITCH_FLOW_PI_VCFIFO_SWITCH_SHFT 8
+#define SH_XNNI1_VCSWITCH_FLOW_PI_VCFIFO_SWITCH_MASK 0x0000000000000100
+
+/*   SH_XNNI1_VCSWITCH_FLOW_MD_VCFIFO_SWITCH                            */
+/*   Description:  Swap VC0/2 with VC1/3                                */
+#define SH_XNNI1_VCSWITCH_FLOW_MD_VCFIFO_SWITCH_SHFT 16
+#define SH_XNNI1_VCSWITCH_FLOW_MD_VCFIFO_SWITCH_MASK 0x0000000000010000
+
+/*   SH_XNNI1_VCSWITCH_FLOW_IILB_VCFIFO_SWITCH                          */
+/*   Description:  Swap VC0/2 with VC1/3                                */
+#define SH_XNNI1_VCSWITCH_FLOW_IILB_VCFIFO_SWITCH_SHFT 24
+#define SH_XNNI1_VCSWITCH_FLOW_IILB_VCFIFO_SWITCH_MASK 0x0000000001000000
+
+/*   SH_XNNI1_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_IN                      */
+#define SH_XNNI1_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_IN_SHFT 32
+#define SH_XNNI1_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_IN_MASK 0x0000000100000000
+
+/*   SH_XNNI1_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_OUT                     */
+#define SH_XNNI1_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_OUT_SHFT 33
+#define SH_XNNI1_VCSWITCH_FLOW_DISABLE_SYNC_BYPASS_OUT_MASK 0x0000000200000000
+
+/*   SH_XNNI1_VCSWITCH_FLOW_ASYNC_FIFOES                                */
+#define SH_XNNI1_VCSWITCH_FLOW_ASYNC_FIFOES_SHFT 34
+#define SH_XNNI1_VCSWITCH_FLOW_ASYNC_FIFOES_MASK 0x0000000400000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI1_TIMER_REG"                     */
+/* ==================================================================== */
+
+#define SH_XNNI1_TIMER_REG                       0x00000001500305b0
+#define SH_XNNI1_TIMER_REG_MASK                  0x0000000100ffffff
+#define SH_XNNI1_TIMER_REG_INIT                  0x0000000000ffffff
+
+/*   SH_XNNI1_TIMER_REG_TIMEOUT_REG                                     */
+/*   Description:  Master Timeout Counter                               */
+#define SH_XNNI1_TIMER_REG_TIMEOUT_REG_SHFT      0
+#define SH_XNNI1_TIMER_REG_TIMEOUT_REG_MASK      0x0000000000ffffff
+
+/*   SH_XNNI1_TIMER_REG_LINKCLEANUP_REG                                 */
+/*   Description:  Link Clean Up                                        */
+#define SH_XNNI1_TIMER_REG_LINKCLEANUP_REG_SHFT  32
+#define SH_XNNI1_TIMER_REG_LINKCLEANUP_REG_MASK  0x0000000100000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_FIFO02_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI1_FIFO02_FLOW                     0x00000001500305c0
+#define SH_XNNI1_FIFO02_FLOW_MASK                0x00000f0f0f0f0f0f
+#define SH_XNNI1_FIFO02_FLOW_INIT                0x0000000000000000
+
+/*   SH_XNNI1_FIFO02_FLOW_COUNT_VC0_LIMIT                               */
+/*   Description:  limit reg zero disables functionality                */
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC0_LIMIT_SHFT 0
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC0_LIMIT_MASK 0x000000000000000f
+
+/*   SH_XNNI1_FIFO02_FLOW_COUNT_VC0_DYN                                 */
+/*   Description:  dynamic counter value                                */
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC0_DYN_SHFT  8
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC0_DYN_MASK  0x0000000000000f00
+
+/*   SH_XNNI1_FIFO02_FLOW_COUNT_VC0_CAP                                 */
+/*   Description:  captured counter value                               */
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC0_CAP_SHFT  16
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC0_CAP_MASK  0x00000000000f0000
+
+/*   SH_XNNI1_FIFO02_FLOW_COUNT_VC2_LIMIT                               */
+/*   Description:  limit reg zero disables functionality                */
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC2_LIMIT_SHFT 24
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC2_LIMIT_MASK 0x000000000f000000
+
+/*   SH_XNNI1_FIFO02_FLOW_COUNT_VC2_DYN                                 */
+/*   Description:  counter dynamic value                                */
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC2_DYN_SHFT  32
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC2_DYN_MASK  0x0000000f00000000
+
+/*   SH_XNNI1_FIFO02_FLOW_COUNT_VC2_CAP                                 */
+/*   Description:  captured counter value                               */
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC2_CAP_SHFT  40
+#define SH_XNNI1_FIFO02_FLOW_COUNT_VC2_CAP_MASK  0x00000f0000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_FIFO13_FLOW"                    */
+/* ==================================================================== */
+
+#define SH_XNNI1_FIFO13_FLOW                     0x00000001500305d0
+#define SH_XNNI1_FIFO13_FLOW_MASK                0x00000f0f0f0f0f0f
+#define SH_XNNI1_FIFO13_FLOW_INIT                0x0000000000000000
+
+/*   SH_XNNI1_FIFO13_FLOW_COUNT_VC1_LIMIT                               */
+/*   Description:  limit reg zero disables functionality                */
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC1_LIMIT_SHFT 0
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC1_LIMIT_MASK 0x000000000000000f
+
+/*   SH_XNNI1_FIFO13_FLOW_COUNT_VC1_DYN                                 */
+/*   Description:  dynamic counter value                                */
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC1_DYN_SHFT  8
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC1_DYN_MASK  0x0000000000000f00
+
+/*   SH_XNNI1_FIFO13_FLOW_COUNT_VC1_CAP                                 */
+/*   Description:  captured counter value                               */
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC1_CAP_SHFT  16
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC1_CAP_MASK  0x00000000000f0000
+
+/*   SH_XNNI1_FIFO13_FLOW_COUNT_VC3_LIMIT                               */
+/*   Description:  limit reg zero disables functionality                */
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC3_LIMIT_SHFT 24
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC3_LIMIT_MASK 0x000000000f000000
+
+/*   SH_XNNI1_FIFO13_FLOW_COUNT_VC3_DYN                                 */
+/*   Description:  counter dynamic value                                */
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC3_DYN_SHFT  32
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC3_DYN_MASK  0x0000000f00000000
+
+/*   SH_XNNI1_FIFO13_FLOW_COUNT_VC3_CAP                                 */
+/*   Description:  captured counter value                               */
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC3_CAP_SHFT  40
+#define SH_XNNI1_FIFO13_FLOW_COUNT_VC3_CAP_MASK  0x00000f0000000000
+
+/* ==================================================================== */
+/*                     Register "SH_XNNI1_NI_FLOW"                      */
+/* ==================================================================== */
+
+#define SH_XNNI1_NI_FLOW                         0x00000001500305e0
+#define SH_XNNI1_NI_FLOW_MASK                    0xff0fff0fff0fff0f
+#define SH_XNNI1_NI_FLOW_INIT                    0x0000000000000000
+
+/*   SH_XNNI1_NI_FLOW_VC0_LIMIT                                         */
+/*   Description:  vc0 limit reg, zero disables functionality           */
+#define SH_XNNI1_NI_FLOW_VC0_LIMIT_SHFT          0
+#define SH_XNNI1_NI_FLOW_VC0_LIMIT_MASK          0x000000000000000f
+
+/*   SH_XNNI1_NI_FLOW_VC0_DYN                                           */
+/*   Description:  vc0 counter dynamic value                            */
+#define SH_XNNI1_NI_FLOW_VC0_DYN_SHFT            8
+#define SH_XNNI1_NI_FLOW_VC0_DYN_MASK            0x0000000000000f00
+
+/*   SH_XNNI1_NI_FLOW_VC0_CAP                                           */
+/*   Description:  vc0 counter captured value                           */
+#define SH_XNNI1_NI_FLOW_VC0_CAP_SHFT            12
+#define SH_XNNI1_NI_FLOW_VC0_CAP_MASK            0x000000000000f000
+
+/*   SH_XNNI1_NI_FLOW_VC1_LIMIT                                         */
+/*   Description:  vc1 limit reg, zero disables functionality           */
+#define SH_XNNI1_NI_FLOW_VC1_LIMIT_SHFT          16
+#define SH_XNNI1_NI_FLOW_VC1_LIMIT_MASK          0x00000000000f0000
+
+/*   SH_XNNI1_NI_FLOW_VC1_DYN                                           */
+/*   Description:  vc1 counter dynamic value                            */
+#define SH_XNNI1_NI_FLOW_VC1_DYN_SHFT            24
+#define SH_XNNI1_NI_FLOW_VC1_DYN_MASK            0x000000000f000000
+
+/*   SH_XNNI1_NI_FLOW_VC1_CAP                                           */
+/*   Description:  vc1 counter captured value                           */
+#define SH_XNNI1_NI_FLOW_VC1_CAP_SHFT            28
+#define SH_XNNI1_NI_FLOW_VC1_CAP_MASK            0x00000000f0000000
+
+/*   SH_XNNI1_NI_FLOW_VC2_LIMIT                                         */
+/*   Description:  vc2 limit reg, zero disables functionality           */
+#define SH_XNNI1_NI_FLOW_VC2_LIMIT_SHFT          32
+#define SH_XNNI1_NI_FLOW_VC2_LIMIT_MASK          0x0000000f00000000
+
+/*   SH_XNNI1_NI_FLOW_VC2_DYN                                           */
+/*   Description:  vc2 counter dynamic value                            */
+#define SH_XNNI1_NI_FLOW_VC2_DYN_SHFT            40
+#define SH_XNNI1_NI_FLOW_VC2_DYN_MASK            0x00000f0000000000
+
+/*   SH_XNNI1_NI_FLOW_VC2_CAP                                           */
+/*   Description:  vc2 counter captured value                           */
+#define SH_XNNI1_NI_FLOW_VC2_CAP_SHFT            44
+#define SH_XNNI1_NI_FLOW_VC2_CAP_MASK            0x0000f00000000000
+
+/*   SH_XNNI1_NI_FLOW_VC3_LIMIT                                         */
+/*   Description:  vc3 limit reg, zero disables functionality           */
+#define SH_XNNI1_NI_FLOW_VC3_LIMIT_SHFT          48
+#define SH_XNNI1_NI_FLOW_VC3_LIMIT_MASK          0x000f000000000000
+
+/*   SH_XNNI1_NI_FLOW_VC3_DYN                                           */
+/*   Description:  vc3 counter dynamic value                            */
+#define SH_XNNI1_NI_FLOW_VC3_DYN_SHFT            56
+#define SH_XNNI1_NI_FLOW_VC3_DYN_MASK            0x0f00000000000000
+
+/*   SH_XNNI1_NI_FLOW_VC3_CAP                                           */
+/*   Description:  vc3 counter captured value                           */
+#define SH_XNNI1_NI_FLOW_VC3_CAP_SHFT            60
+#define SH_XNNI1_NI_FLOW_VC3_CAP_MASK            0xf000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI1_DEAD_FLOW"                     */
+/* ==================================================================== */
+
+#define SH_XNNI1_DEAD_FLOW                       0x00000001500305f0
+#define SH_XNNI1_DEAD_FLOW_MASK                  0xff0fff0fff0fff0f
+#define SH_XNNI1_DEAD_FLOW_INIT                  0x0000000000000000
+
+/*   SH_XNNI1_DEAD_FLOW_VC0_LIMIT                                       */
+/*   Description:  vc0 limit reg, zero disables functionality           */
+#define SH_XNNI1_DEAD_FLOW_VC0_LIMIT_SHFT        0
+#define SH_XNNI1_DEAD_FLOW_VC0_LIMIT_MASK        0x000000000000000f
+
+/*   SH_XNNI1_DEAD_FLOW_VC0_DYN                                         */
+/*   Description:  vc0 counter dynamic value                            */
+#define SH_XNNI1_DEAD_FLOW_VC0_DYN_SHFT          8
+#define SH_XNNI1_DEAD_FLOW_VC0_DYN_MASK          0x0000000000000f00
+
+/*   SH_XNNI1_DEAD_FLOW_VC0_CAP                                         */
+/*   Description:  vc0 counter captured value                           */
+#define SH_XNNI1_DEAD_FLOW_VC0_CAP_SHFT          12
+#define SH_XNNI1_DEAD_FLOW_VC0_CAP_MASK          0x000000000000f000
+
+/*   SH_XNNI1_DEAD_FLOW_VC1_LIMIT                                       */
+/*   Description:  vc1 limit reg, zero disables functionality           */
+#define SH_XNNI1_DEAD_FLOW_VC1_LIMIT_SHFT        16
+#define SH_XNNI1_DEAD_FLOW_VC1_LIMIT_MASK        0x00000000000f0000
+
+/*   SH_XNNI1_DEAD_FLOW_VC1_DYN                                         */
+/*   Description:  vc1 counter dynamic value                            */
+#define SH_XNNI1_DEAD_FLOW_VC1_DYN_SHFT          24
+#define SH_XNNI1_DEAD_FLOW_VC1_DYN_MASK          0x000000000f000000
+
+/*   SH_XNNI1_DEAD_FLOW_VC1_CAP                                         */
+/*   Description:  vc1 counter captured value                           */
+#define SH_XNNI1_DEAD_FLOW_VC1_CAP_SHFT          28
+#define SH_XNNI1_DEAD_FLOW_VC1_CAP_MASK          0x00000000f0000000
+
+/*   SH_XNNI1_DEAD_FLOW_VC2_LIMIT                                       */
+/*   Description:  vc2 limit reg, zero disables functionality           */
+#define SH_XNNI1_DEAD_FLOW_VC2_LIMIT_SHFT        32
+#define SH_XNNI1_DEAD_FLOW_VC2_LIMIT_MASK        0x0000000f00000000
+
+/*   SH_XNNI1_DEAD_FLOW_VC2_DYN                                         */
+/*   Description:  vc2 counter dynamic value                            */
+#define SH_XNNI1_DEAD_FLOW_VC2_DYN_SHFT          40
+#define SH_XNNI1_DEAD_FLOW_VC2_DYN_MASK          0x00000f0000000000
+
+/*   SH_XNNI1_DEAD_FLOW_VC2_CAP                                         */
+/*   Description:  vc2 counter captured value                           */
+#define SH_XNNI1_DEAD_FLOW_VC2_CAP_SHFT          44
+#define SH_XNNI1_DEAD_FLOW_VC2_CAP_MASK          0x0000f00000000000
+
+/*   SH_XNNI1_DEAD_FLOW_VC3_LIMIT                                       */
+/*   Description:  vc3 limit reg, zero disables functionality           */
+#define SH_XNNI1_DEAD_FLOW_VC3_LIMIT_SHFT        48
+#define SH_XNNI1_DEAD_FLOW_VC3_LIMIT_MASK        0x000f000000000000
+
+/*   SH_XNNI1_DEAD_FLOW_VC3_DYN                                         */
+/*   Description:  vc3 counter dynamic value                            */
+#define SH_XNNI1_DEAD_FLOW_VC3_DYN_SHFT          56
+#define SH_XNNI1_DEAD_FLOW_VC3_DYN_MASK          0x0f00000000000000
+
+/*   SH_XNNI1_DEAD_FLOW_VC3_CAP                                         */
+/*   Description:  vc3 counter captured value                           */
+#define SH_XNNI1_DEAD_FLOW_VC3_CAP_SHFT          60
+#define SH_XNNI1_DEAD_FLOW_VC3_CAP_MASK          0xf000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI1_INJECT_AGE"                    */
+/* ==================================================================== */
+
+#define SH_XNNI1_INJECT_AGE                      0x0000000150030600
+#define SH_XNNI1_INJECT_AGE_MASK                 0x000000000000ffff
+#define SH_XNNI1_INJECT_AGE_INIT                 0x0000000000000000
+
+/*   SH_XNNI1_INJECT_AGE_REQUEST_INJECT                                 */
+/*   Description:  Value of AGE field for outgoing requests             */
+#define SH_XNNI1_INJECT_AGE_REQUEST_INJECT_SHFT  0
+#define SH_XNNI1_INJECT_AGE_REQUEST_INJECT_MASK  0x00000000000000ff
+
+/*   SH_XNNI1_INJECT_AGE_REPLY_INJECT                                   */
+/*   Description:  Value of AGE field for outgoing replies              */
+#define SH_XNNI1_INJECT_AGE_REPLY_INJECT_SHFT    8
+#define SH_XNNI1_INJECT_AGE_REPLY_INJECT_MASK    0x000000000000ff00
+
+/* ==================================================================== */
+/*                      Register "SH_XN_DEBUG_SEL"                      */
+/*                         XN Debug Port Select                         */
+/* ==================================================================== */
+
+#define SH_XN_DEBUG_SEL                          0x0000000150031000
+#define SH_XN_DEBUG_SEL_MASK                     0xf777777777777777
+#define SH_XN_DEBUG_SEL_INIT                     0x0000000000000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE0_RLM_SEL                                    */
+/*   Description:  Nibble 0 RLM select                                  */
+#define SH_XN_DEBUG_SEL_NIBBLE0_RLM_SEL_SHFT     0
+#define SH_XN_DEBUG_SEL_NIBBLE0_RLM_SEL_MASK     0x0000000000000007
+
+/*   SH_XN_DEBUG_SEL_NIBBLE0_NIBBLE_SEL                                 */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_XN_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_SHFT  4
+#define SH_XN_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_MASK  0x0000000000000070
+
+/*   SH_XN_DEBUG_SEL_NIBBLE1_RLM_SEL                                    */
+/*   Description:  Nibble 1 RLM select                                  */
+#define SH_XN_DEBUG_SEL_NIBBLE1_RLM_SEL_SHFT     8
+#define SH_XN_DEBUG_SEL_NIBBLE1_RLM_SEL_MASK     0x0000000000000700
+
+/*   SH_XN_DEBUG_SEL_NIBBLE1_NIBBLE_SEL                                 */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_XN_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_SHFT  12
+#define SH_XN_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_MASK  0x0000000000007000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE2_RLM_SEL                                    */
+/*   Description:  Nibble 2 RLM select                                  */
+#define SH_XN_DEBUG_SEL_NIBBLE2_RLM_SEL_SHFT     16
+#define SH_XN_DEBUG_SEL_NIBBLE2_RLM_SEL_MASK     0x0000000000070000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE2_NIBBLE_SEL                                 */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_XN_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_SHFT  20
+#define SH_XN_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_MASK  0x0000000000700000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE3_RLM_SEL                                    */
+/*   Description:  Nibble 3 RLM select                                  */
+#define SH_XN_DEBUG_SEL_NIBBLE3_RLM_SEL_SHFT     24
+#define SH_XN_DEBUG_SEL_NIBBLE3_RLM_SEL_MASK     0x0000000007000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE3_NIBBLE_SEL                                 */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_XN_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_SHFT  28
+#define SH_XN_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_MASK  0x0000000070000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE4_RLM_SEL                                    */
+/*   Description:  Nibble 4 RLM select                                  */
+#define SH_XN_DEBUG_SEL_NIBBLE4_RLM_SEL_SHFT     32
+#define SH_XN_DEBUG_SEL_NIBBLE4_RLM_SEL_MASK     0x0000000700000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE4_NIBBLE_SEL                                 */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_XN_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_SHFT  36
+#define SH_XN_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_MASK  0x0000007000000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE5_RLM_SEL                                    */
+/*   Description:  Nibble 5 RLM select                                  */
+#define SH_XN_DEBUG_SEL_NIBBLE5_RLM_SEL_SHFT     40
+#define SH_XN_DEBUG_SEL_NIBBLE5_RLM_SEL_MASK     0x0000070000000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE5_NIBBLE_SEL                                 */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_XN_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_SHFT  44
+#define SH_XN_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_MASK  0x0000700000000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE6_RLM_SEL                                    */
+/*   Description:  Nibble 6 RLM select                                  */
+#define SH_XN_DEBUG_SEL_NIBBLE6_RLM_SEL_SHFT     48
+#define SH_XN_DEBUG_SEL_NIBBLE6_RLM_SEL_MASK     0x0007000000000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE6_NIBBLE_SEL                                 */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_XN_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_SHFT  52
+#define SH_XN_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_MASK  0x0070000000000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE7_RLM_SEL                                    */
+/*   Description:  Nibble 7 RLM select                                  */
+#define SH_XN_DEBUG_SEL_NIBBLE7_RLM_SEL_SHFT     56
+#define SH_XN_DEBUG_SEL_NIBBLE7_RLM_SEL_MASK     0x0700000000000000
+
+/*   SH_XN_DEBUG_SEL_NIBBLE7_NIBBLE_SEL                                 */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_XN_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_SHFT  60
+#define SH_XN_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_MASK  0x7000000000000000
+
+/*   SH_XN_DEBUG_SEL_TRIGGER_ENABLE                                     */
+/*   Description:  Enable trigger on bit 32 of Analyzer data            */
+#define SH_XN_DEBUG_SEL_TRIGGER_ENABLE_SHFT      63
+#define SH_XN_DEBUG_SEL_TRIGGER_ENABLE_MASK      0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XN_DEBUG_TRIG_SEL"                    */
+/*                       XN Debug trigger Select                        */
+/* ==================================================================== */
+
+#define SH_XN_DEBUG_TRIG_SEL                     0x0000000150031020
+#define SH_XN_DEBUG_TRIG_SEL_MASK                0x7777777777777777
+#define SH_XN_DEBUG_TRIG_SEL_INIT                0x0000000000000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER0_RLM_SEL                              */
+/*   Description:  Nibble 0 RLM select                                  */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER0_RLM_SEL_SHFT 0
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER0_RLM_SEL_MASK 0x0000000000000007
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER0_NIBBLE_SEL                           */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER0_NIBBLE_SEL_SHFT 4
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER1_RLM_SEL                              */
+/*   Description:  Nibble 1 RLM select                                  */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER1_RLM_SEL_SHFT 8
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER1_RLM_SEL_MASK 0x0000000000000700
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER1_NIBBLE_SEL                           */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER1_NIBBLE_SEL_SHFT 12
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER2_RLM_SEL                              */
+/*   Description:  Nibble 2 RLM select                                  */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER2_RLM_SEL_SHFT 16
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER2_RLM_SEL_MASK 0x0000000000070000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER2_NIBBLE_SEL                           */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER2_NIBBLE_SEL_SHFT 20
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER3_RLM_SEL                              */
+/*   Description:  Nibble 3 RLM select                                  */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER3_RLM_SEL_SHFT 24
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER3_RLM_SEL_MASK 0x0000000007000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER3_NIBBLE_SEL                           */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER3_NIBBLE_SEL_SHFT 28
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER4_RLM_SEL                              */
+/*   Description:  Nibble 4 RLM select                                  */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER4_RLM_SEL_SHFT 32
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER4_RLM_SEL_MASK 0x0000000700000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER4_NIBBLE_SEL                           */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER4_NIBBLE_SEL_SHFT 36
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER5_RLM_SEL                              */
+/*   Description:  Nibble 5 RLM select                                  */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER5_RLM_SEL_SHFT 40
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER5_RLM_SEL_MASK 0x0000070000000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER5_NIBBLE_SEL                           */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER5_NIBBLE_SEL_SHFT 44
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER6_RLM_SEL                              */
+/*   Description:  Nibble 6 RLM select                                  */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER6_RLM_SEL_SHFT 48
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER6_RLM_SEL_MASK 0x0007000000000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER6_NIBBLE_SEL                           */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER6_NIBBLE_SEL_SHFT 52
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER7_RLM_SEL                              */
+/*   Description:  Nibble 7 RLM select                                  */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER7_RLM_SEL_SHFT 56
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER7_RLM_SEL_MASK 0x0700000000000000
+
+/*   SH_XN_DEBUG_TRIG_SEL_TRIGGER7_NIBBLE_SEL                           */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER7_NIBBLE_SEL_SHFT 60
+#define SH_XN_DEBUG_TRIG_SEL_TRIGGER7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XN_TRIGGER_COMPARE"                   */
+/*                           XN Debug Compare                           */
+/* ==================================================================== */
+
+#define SH_XN_TRIGGER_COMPARE                    0x0000000150031040
+#define SH_XN_TRIGGER_COMPARE_MASK               0x00000000ffffffff
+#define SH_XN_TRIGGER_COMPARE_INIT               0x0000000000000000
+
+/*   SH_XN_TRIGGER_COMPARE_MASK                                         */
+/*   Description:  Mask to select Debug bits for trigger generation     */
+#define SH_XN_TRIGGER_COMPARE_MASK_SHFT          0
+#define SH_XN_TRIGGER_COMPARE_MASK_MASK          0x00000000ffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_XN_TRIGGER_DATA"                     */
+/*                        XN Debug Compare Data                         */
+/* ==================================================================== */
+
+#define SH_XN_TRIGGER_DATA                       0x0000000150031050
+#define SH_XN_TRIGGER_DATA_MASK                  0x00000000ffffffff
+#define SH_XN_TRIGGER_DATA_INIT                  0x00000000ffffffff
+
+/*   SH_XN_TRIGGER_DATA_COMPARE_PATTERN                                 */
+/*   Description:  debug bit pattern for trigger generation             */
+#define SH_XN_TRIGGER_DATA_COMPARE_PATTERN_SHFT  0
+#define SH_XN_TRIGGER_DATA_COMPARE_PATTERN_MASK  0x00000000ffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_XN_IILB_DEBUG_SEL"                    */
+/*                      XN IILB Debug Port Select                       */
+/* ==================================================================== */
+
+#define SH_XN_IILB_DEBUG_SEL                     0x0000000150031060
+#define SH_XN_IILB_DEBUG_SEL_MASK                0x7777777777777777
+#define SH_XN_IILB_DEBUG_SEL_INIT                0x0000000000000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE0_INPUT_SEL                             */
+/*   Description:  Nibble 0 input select                                */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE0_INPUT_SEL_SHFT 0
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE0_INPUT_SEL_MASK 0x0000000000000007
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE0_NIBBLE_SEL                            */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE1_INPUT_SEL                             */
+/*   Description:  Nibble 1 input select                                */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE1_INPUT_SEL_SHFT 8
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE1_INPUT_SEL_MASK 0x0000000000000700
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE1_NIBBLE_SEL                            */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE2_INPUT_SEL                             */
+/*   Description:  Nibble 2 input select                                */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE2_INPUT_SEL_SHFT 16
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE2_INPUT_SEL_MASK 0x0000000000070000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE2_NIBBLE_SEL                            */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE3_INPUT_SEL                             */
+/*   Description:  Nibble 3 input select                                */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE3_INPUT_SEL_SHFT 24
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE3_INPUT_SEL_MASK 0x0000000007000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE3_NIBBLE_SEL                            */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE4_INPUT_SEL                             */
+/*   Description:  Nibble 4 input select                                */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE4_INPUT_SEL_SHFT 32
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE4_INPUT_SEL_MASK 0x0000000700000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE4_NIBBLE_SEL                            */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE5_INPUT_SEL                             */
+/*   Description:  Nibble 5 input select                                */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE5_INPUT_SEL_SHFT 40
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE5_INPUT_SEL_MASK 0x0000070000000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE5_NIBBLE_SEL                            */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE6_INPUT_SEL                             */
+/*   Description:  Nibble 6 input select                                */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE6_INPUT_SEL_SHFT 48
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE6_INPUT_SEL_MASK 0x0007000000000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE6_NIBBLE_SEL                            */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE7_INPUT_SEL                             */
+/*   Description:  Nibble 7 input select                                */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE7_INPUT_SEL_SHFT 56
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE7_INPUT_SEL_MASK 0x0700000000000000
+
+/*   SH_XN_IILB_DEBUG_SEL_NIBBLE7_NIBBLE_SEL                            */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_XN_IILB_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XN_PI_DEBUG_SEL"                     */
+/*                       XN PI Debug Port Select                        */
+/* ==================================================================== */
+
+#define SH_XN_PI_DEBUG_SEL                       0x00000001500310a0
+#define SH_XN_PI_DEBUG_SEL_MASK                  0x7777777777777777
+#define SH_XN_PI_DEBUG_SEL_INIT                  0x0000000000000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE0_INPUT_SEL                               */
+/*   Description:  Nibble 0 input select                                */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE0_INPUT_SEL_SHFT 0
+#define SH_XN_PI_DEBUG_SEL_NIBBLE0_INPUT_SEL_MASK 0x0000000000000007
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE0_NIBBLE_SEL                              */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_XN_PI_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE1_INPUT_SEL                               */
+/*   Description:  Nibble 1 input select                                */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE1_INPUT_SEL_SHFT 8
+#define SH_XN_PI_DEBUG_SEL_NIBBLE1_INPUT_SEL_MASK 0x0000000000000700
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE1_NIBBLE_SEL                              */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_XN_PI_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE2_INPUT_SEL                               */
+/*   Description:  Nibble 2 input select                                */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE2_INPUT_SEL_SHFT 16
+#define SH_XN_PI_DEBUG_SEL_NIBBLE2_INPUT_SEL_MASK 0x0000000000070000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE2_NIBBLE_SEL                              */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_XN_PI_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE3_INPUT_SEL                               */
+/*   Description:  Nibble 3 input select                                */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE3_INPUT_SEL_SHFT 24
+#define SH_XN_PI_DEBUG_SEL_NIBBLE3_INPUT_SEL_MASK 0x0000000007000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE3_NIBBLE_SEL                              */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_XN_PI_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE4_INPUT_SEL                               */
+/*   Description:  Nibble 4 input select                                */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE4_INPUT_SEL_SHFT 32
+#define SH_XN_PI_DEBUG_SEL_NIBBLE4_INPUT_SEL_MASK 0x0000000700000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE4_NIBBLE_SEL                              */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_XN_PI_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE5_INPUT_SEL                               */
+/*   Description:  Nibble 5 input select                                */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE5_INPUT_SEL_SHFT 40
+#define SH_XN_PI_DEBUG_SEL_NIBBLE5_INPUT_SEL_MASK 0x0000070000000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE5_NIBBLE_SEL                              */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_XN_PI_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE6_INPUT_SEL                               */
+/*   Description:  Nibble 6 input select                                */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE6_INPUT_SEL_SHFT 48
+#define SH_XN_PI_DEBUG_SEL_NIBBLE6_INPUT_SEL_MASK 0x0007000000000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE6_NIBBLE_SEL                              */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_XN_PI_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE7_INPUT_SEL                               */
+/*   Description:  Nibble 7 input select                                */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE7_INPUT_SEL_SHFT 56
+#define SH_XN_PI_DEBUG_SEL_NIBBLE7_INPUT_SEL_MASK 0x0700000000000000
+
+/*   SH_XN_PI_DEBUG_SEL_NIBBLE7_NIBBLE_SEL                              */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_XN_PI_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_XN_PI_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XN_MD_DEBUG_SEL"                     */
+/*                       XN MD Debug Port Select                        */
+/* ==================================================================== */
+
+#define SH_XN_MD_DEBUG_SEL                       0x0000000150031080
+#define SH_XN_MD_DEBUG_SEL_MASK                  0x7777777777777777
+#define SH_XN_MD_DEBUG_SEL_INIT                  0x0000000000000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE0_INPUT_SEL                               */
+/*   Description:  Nibble 0 input select                                */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE0_INPUT_SEL_SHFT 0
+#define SH_XN_MD_DEBUG_SEL_NIBBLE0_INPUT_SEL_MASK 0x0000000000000007
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE0_NIBBLE_SEL                              */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_XN_MD_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE1_INPUT_SEL                               */
+/*   Description:  Nibble 1 input select                                */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE1_INPUT_SEL_SHFT 8
+#define SH_XN_MD_DEBUG_SEL_NIBBLE1_INPUT_SEL_MASK 0x0000000000000700
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE1_NIBBLE_SEL                              */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_XN_MD_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE2_INPUT_SEL                               */
+/*   Description:  Nibble 2 input select                                */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE2_INPUT_SEL_SHFT 16
+#define SH_XN_MD_DEBUG_SEL_NIBBLE2_INPUT_SEL_MASK 0x0000000000070000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE2_NIBBLE_SEL                              */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_XN_MD_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE3_INPUT_SEL                               */
+/*   Description:  Nibble 3 input select                                */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE3_INPUT_SEL_SHFT 24
+#define SH_XN_MD_DEBUG_SEL_NIBBLE3_INPUT_SEL_MASK 0x0000000007000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE3_NIBBLE_SEL                              */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_XN_MD_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE4_INPUT_SEL                               */
+/*   Description:  Nibble 4 input select                                */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE4_INPUT_SEL_SHFT 32
+#define SH_XN_MD_DEBUG_SEL_NIBBLE4_INPUT_SEL_MASK 0x0000000700000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE4_NIBBLE_SEL                              */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_XN_MD_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE5_INPUT_SEL                               */
+/*   Description:  Nibble 5 input select                                */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE5_INPUT_SEL_SHFT 40
+#define SH_XN_MD_DEBUG_SEL_NIBBLE5_INPUT_SEL_MASK 0x0000070000000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE5_NIBBLE_SEL                              */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_XN_MD_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE6_INPUT_SEL                               */
+/*   Description:  Nibble 6 input select                                */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE6_INPUT_SEL_SHFT 48
+#define SH_XN_MD_DEBUG_SEL_NIBBLE6_INPUT_SEL_MASK 0x0007000000000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE6_NIBBLE_SEL                              */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_XN_MD_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE7_INPUT_SEL                               */
+/*   Description:  Nibble 7 input select                                */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE7_INPUT_SEL_SHFT 56
+#define SH_XN_MD_DEBUG_SEL_NIBBLE7_INPUT_SEL_MASK 0x0700000000000000
+
+/*   SH_XN_MD_DEBUG_SEL_NIBBLE7_NIBBLE_SEL                              */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_XN_MD_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_XN_MD_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XN_NI0_DEBUG_SEL"                    */
+/*                       XN NI0 Debug Port Select                       */
+/* ==================================================================== */
+
+#define SH_XN_NI0_DEBUG_SEL                      0x00000001500310c0
+#define SH_XN_NI0_DEBUG_SEL_MASK                 0x7777777777777777
+#define SH_XN_NI0_DEBUG_SEL_INIT                 0x0000000000000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE0_INPUT_SEL                              */
+/*   Description:  Nibble 0 input select                                */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE0_INPUT_SEL_SHFT 0
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE0_INPUT_SEL_MASK 0x0000000000000007
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE0_NIBBLE_SEL                             */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE1_INPUT_SEL                              */
+/*   Description:  Nibble 1 input select                                */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE1_INPUT_SEL_SHFT 8
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE1_INPUT_SEL_MASK 0x0000000000000700
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE1_NIBBLE_SEL                             */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE2_INPUT_SEL                              */
+/*   Description:  Nibble 2 input select                                */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE2_INPUT_SEL_SHFT 16
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE2_INPUT_SEL_MASK 0x0000000000070000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE2_NIBBLE_SEL                             */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE3_INPUT_SEL                              */
+/*   Description:  Nibble 3 input select                                */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE3_INPUT_SEL_SHFT 24
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE3_INPUT_SEL_MASK 0x0000000007000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE3_NIBBLE_SEL                             */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE4_INPUT_SEL                              */
+/*   Description:  Nibble 4 input select                                */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE4_INPUT_SEL_SHFT 32
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE4_INPUT_SEL_MASK 0x0000000700000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE4_NIBBLE_SEL                             */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE5_INPUT_SEL                              */
+/*   Description:  Nibble 5 input select                                */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE5_INPUT_SEL_SHFT 40
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE5_INPUT_SEL_MASK 0x0000070000000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE5_NIBBLE_SEL                             */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE6_INPUT_SEL                              */
+/*   Description:  Nibble 6 input select                                */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE6_INPUT_SEL_SHFT 48
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE6_INPUT_SEL_MASK 0x0007000000000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE6_NIBBLE_SEL                             */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE7_INPUT_SEL                              */
+/*   Description:  Nibble 7 input select                                */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE7_INPUT_SEL_SHFT 56
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE7_INPUT_SEL_MASK 0x0700000000000000
+
+/*   SH_XN_NI0_DEBUG_SEL_NIBBLE7_NIBBLE_SEL                             */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_XN_NI0_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XN_NI1_DEBUG_SEL"                    */
+/*                       XN NI1 Debug Port Select                       */
+/* ==================================================================== */
+
+#define SH_XN_NI1_DEBUG_SEL                      0x00000001500310e0
+#define SH_XN_NI1_DEBUG_SEL_MASK                 0x7777777777777777
+#define SH_XN_NI1_DEBUG_SEL_INIT                 0x0000000000000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE0_INPUT_SEL                              */
+/*   Description:  Nibble 0 input select                                */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE0_INPUT_SEL_SHFT 0
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE0_INPUT_SEL_MASK 0x0000000000000007
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE0_NIBBLE_SEL                             */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_SHFT 4
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE0_NIBBLE_SEL_MASK 0x0000000000000070
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE1_INPUT_SEL                              */
+/*   Description:  Nibble 1 input select                                */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE1_INPUT_SEL_SHFT 8
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE1_INPUT_SEL_MASK 0x0000000000000700
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE1_NIBBLE_SEL                             */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_SHFT 12
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE1_NIBBLE_SEL_MASK 0x0000000000007000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE2_INPUT_SEL                              */
+/*   Description:  Nibble 2 input select                                */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE2_INPUT_SEL_SHFT 16
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE2_INPUT_SEL_MASK 0x0000000000070000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE2_NIBBLE_SEL                             */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_SHFT 20
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE2_NIBBLE_SEL_MASK 0x0000000000700000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE3_INPUT_SEL                              */
+/*   Description:  Nibble 3 input select                                */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE3_INPUT_SEL_SHFT 24
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE3_INPUT_SEL_MASK 0x0000000007000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE3_NIBBLE_SEL                             */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_SHFT 28
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE3_NIBBLE_SEL_MASK 0x0000000070000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE4_INPUT_SEL                              */
+/*   Description:  Nibble 4 input select                                */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE4_INPUT_SEL_SHFT 32
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE4_INPUT_SEL_MASK 0x0000000700000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE4_NIBBLE_SEL                             */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_SHFT 36
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE4_NIBBLE_SEL_MASK 0x0000007000000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE5_INPUT_SEL                              */
+/*   Description:  Nibble 5 input select                                */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE5_INPUT_SEL_SHFT 40
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE5_INPUT_SEL_MASK 0x0000070000000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE5_NIBBLE_SEL                             */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_SHFT 44
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE5_NIBBLE_SEL_MASK 0x0000700000000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE6_INPUT_SEL                              */
+/*   Description:  Nibble 6 input select                                */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE6_INPUT_SEL_SHFT 48
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE6_INPUT_SEL_MASK 0x0007000000000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE6_NIBBLE_SEL                             */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_SHFT 52
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE6_NIBBLE_SEL_MASK 0x0070000000000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE7_INPUT_SEL                              */
+/*   Description:  Nibble 7 input select                                */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE7_INPUT_SEL_SHFT 56
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE7_INPUT_SEL_MASK 0x0700000000000000
+
+/*   SH_XN_NI1_DEBUG_SEL_NIBBLE7_NIBBLE_SEL                             */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_SHFT 60
+#define SH_XN_NI1_DEBUG_SEL_NIBBLE7_NIBBLE_SEL_MASK 0x7000000000000000
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_LB_CMP_EXP_DATA0"                */
+/*                 IILB compare LB input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_LB_CMP_EXP_DATA0              0x0000000150031100
+#define SH_XN_IILB_LB_CMP_EXP_DATA0_MASK         0xffffffffffffffff
+#define SH_XN_IILB_LB_CMP_EXP_DATA0_INIT         0x0000000000000000
+
+/*   SH_XN_IILB_LB_CMP_EXP_DATA0_DATA                                   */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_IILB_LB_CMP_EXP_DATA0_DATA_SHFT    0
+#define SH_XN_IILB_LB_CMP_EXP_DATA0_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_LB_CMP_EXP_DATA1"                */
+/*                 IILB compare LB input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_LB_CMP_EXP_DATA1              0x0000000150031110
+#define SH_XN_IILB_LB_CMP_EXP_DATA1_MASK         0xffffffffffffffff
+#define SH_XN_IILB_LB_CMP_EXP_DATA1_INIT         0x0000000000000000
+
+/*   SH_XN_IILB_LB_CMP_EXP_DATA1_DATA                                   */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_IILB_LB_CMP_EXP_DATA1_DATA_SHFT    0
+#define SH_XN_IILB_LB_CMP_EXP_DATA1_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_LB_CMP_ENABLE0"                 */
+/*                    IILB compare LB input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_IILB_LB_CMP_ENABLE0                0x0000000150031120
+#define SH_XN_IILB_LB_CMP_ENABLE0_MASK           0xffffffffffffffff
+#define SH_XN_IILB_LB_CMP_ENABLE0_INIT           0x0000000000000000
+
+/*   SH_XN_IILB_LB_CMP_ENABLE0_ENABLE                                   */
+/*   Description:  Enable0                                              */
+#define SH_XN_IILB_LB_CMP_ENABLE0_ENABLE_SHFT    0
+#define SH_XN_IILB_LB_CMP_ENABLE0_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_LB_CMP_ENABLE1"                 */
+/*                    IILB compare LB input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_IILB_LB_CMP_ENABLE1                0x0000000150031130
+#define SH_XN_IILB_LB_CMP_ENABLE1_MASK           0xffffffffffffffff
+#define SH_XN_IILB_LB_CMP_ENABLE1_INIT           0x0000000000000000
+
+/*   SH_XN_IILB_LB_CMP_ENABLE1_ENABLE                                   */
+/*   Description:  Enable1                                              */
+#define SH_XN_IILB_LB_CMP_ENABLE1_ENABLE_SHFT    0
+#define SH_XN_IILB_LB_CMP_ENABLE1_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_II_CMP_EXP_DATA0"                */
+/*                 IILB compare II input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_II_CMP_EXP_DATA0              0x0000000150031140
+#define SH_XN_IILB_II_CMP_EXP_DATA0_MASK         0xffffffffffffffff
+#define SH_XN_IILB_II_CMP_EXP_DATA0_INIT         0x0000000000000000
+
+/*   SH_XN_IILB_II_CMP_EXP_DATA0_DATA                                   */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_IILB_II_CMP_EXP_DATA0_DATA_SHFT    0
+#define SH_XN_IILB_II_CMP_EXP_DATA0_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_II_CMP_EXP_DATA1"                */
+/*                 IILB compare II input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_II_CMP_EXP_DATA1              0x0000000150031150
+#define SH_XN_IILB_II_CMP_EXP_DATA1_MASK         0xffffffffffffffff
+#define SH_XN_IILB_II_CMP_EXP_DATA1_INIT         0x0000000000000000
+
+/*   SH_XN_IILB_II_CMP_EXP_DATA1_DATA                                   */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_IILB_II_CMP_EXP_DATA1_DATA_SHFT    0
+#define SH_XN_IILB_II_CMP_EXP_DATA1_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_II_CMP_ENABLE0"                 */
+/*                    IILB compare II input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_IILB_II_CMP_ENABLE0                0x0000000150031160
+#define SH_XN_IILB_II_CMP_ENABLE0_MASK           0xffffffffffffffff
+#define SH_XN_IILB_II_CMP_ENABLE0_INIT           0x0000000000000000
+
+/*   SH_XN_IILB_II_CMP_ENABLE0_ENABLE                                   */
+/*   Description:  Enable0                                              */
+#define SH_XN_IILB_II_CMP_ENABLE0_ENABLE_SHFT    0
+#define SH_XN_IILB_II_CMP_ENABLE0_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_II_CMP_ENABLE1"                 */
+/*                    IILB compare II input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_IILB_II_CMP_ENABLE1                0x0000000150031170
+#define SH_XN_IILB_II_CMP_ENABLE1_MASK           0xffffffffffffffff
+#define SH_XN_IILB_II_CMP_ENABLE1_INIT           0x0000000000000000
+
+/*   SH_XN_IILB_II_CMP_ENABLE1_ENABLE                                   */
+/*   Description:  Enable1                                              */
+#define SH_XN_IILB_II_CMP_ENABLE1_ENABLE_SHFT    0
+#define SH_XN_IILB_II_CMP_ENABLE1_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_MD_CMP_EXP_DATA0"                */
+/*                 IILB compare MD input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_MD_CMP_EXP_DATA0              0x0000000150031180
+#define SH_XN_IILB_MD_CMP_EXP_DATA0_MASK         0xffffffffffffffff
+#define SH_XN_IILB_MD_CMP_EXP_DATA0_INIT         0x0000000000000000
+
+/*   SH_XN_IILB_MD_CMP_EXP_DATA0_DATA                                   */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_IILB_MD_CMP_EXP_DATA0_DATA_SHFT    0
+#define SH_XN_IILB_MD_CMP_EXP_DATA0_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_MD_CMP_EXP_DATA1"                */
+/*                 IILB compare MD input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_MD_CMP_EXP_DATA1              0x0000000150031190
+#define SH_XN_IILB_MD_CMP_EXP_DATA1_MASK         0xffffffffffffffff
+#define SH_XN_IILB_MD_CMP_EXP_DATA1_INIT         0x0000000000000000
+
+/*   SH_XN_IILB_MD_CMP_EXP_DATA1_DATA                                   */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_IILB_MD_CMP_EXP_DATA1_DATA_SHFT    0
+#define SH_XN_IILB_MD_CMP_EXP_DATA1_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_MD_CMP_ENABLE0"                 */
+/*                    IILB compare MD input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_IILB_MD_CMP_ENABLE0                0x00000001500311a0
+#define SH_XN_IILB_MD_CMP_ENABLE0_MASK           0xffffffffffffffff
+#define SH_XN_IILB_MD_CMP_ENABLE0_INIT           0x0000000000000000
+
+/*   SH_XN_IILB_MD_CMP_ENABLE0_ENABLE                                   */
+/*   Description:  Enable0                                              */
+#define SH_XN_IILB_MD_CMP_ENABLE0_ENABLE_SHFT    0
+#define SH_XN_IILB_MD_CMP_ENABLE0_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_MD_CMP_ENABLE1"                 */
+/*                    IILB compare MD input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_IILB_MD_CMP_ENABLE1                0x00000001500311b0
+#define SH_XN_IILB_MD_CMP_ENABLE1_MASK           0xffffffffffffffff
+#define SH_XN_IILB_MD_CMP_ENABLE1_INIT           0x0000000000000000
+
+/*   SH_XN_IILB_MD_CMP_ENABLE1_ENABLE                                   */
+/*   Description:  Enable1                                              */
+#define SH_XN_IILB_MD_CMP_ENABLE1_ENABLE_SHFT    0
+#define SH_XN_IILB_MD_CMP_ENABLE1_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_PI_CMP_EXP_DATA0"                */
+/*                 IILB compare PI input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_PI_CMP_EXP_DATA0              0x00000001500311c0
+#define SH_XN_IILB_PI_CMP_EXP_DATA0_MASK         0xffffffffffffffff
+#define SH_XN_IILB_PI_CMP_EXP_DATA0_INIT         0x0000000000000000
+
+/*   SH_XN_IILB_PI_CMP_EXP_DATA0_DATA                                   */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_IILB_PI_CMP_EXP_DATA0_DATA_SHFT    0
+#define SH_XN_IILB_PI_CMP_EXP_DATA0_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_PI_CMP_EXP_DATA1"                */
+/*                 IILB compare PI input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_PI_CMP_EXP_DATA1              0x00000001500311d0
+#define SH_XN_IILB_PI_CMP_EXP_DATA1_MASK         0xffffffffffffffff
+#define SH_XN_IILB_PI_CMP_EXP_DATA1_INIT         0x0000000000000000
+
+/*   SH_XN_IILB_PI_CMP_EXP_DATA1_DATA                                   */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_IILB_PI_CMP_EXP_DATA1_DATA_SHFT    0
+#define SH_XN_IILB_PI_CMP_EXP_DATA1_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_PI_CMP_ENABLE0"                 */
+/*                    IILB compare PI input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_IILB_PI_CMP_ENABLE0                0x00000001500311e0
+#define SH_XN_IILB_PI_CMP_ENABLE0_MASK           0xffffffffffffffff
+#define SH_XN_IILB_PI_CMP_ENABLE0_INIT           0x0000000000000000
+
+/*   SH_XN_IILB_PI_CMP_ENABLE0_ENABLE                                   */
+/*   Description:  Enable0                                              */
+#define SH_XN_IILB_PI_CMP_ENABLE0_ENABLE_SHFT    0
+#define SH_XN_IILB_PI_CMP_ENABLE0_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_PI_CMP_ENABLE1"                 */
+/*                    IILB compare PI input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_IILB_PI_CMP_ENABLE1                0x00000001500311f0
+#define SH_XN_IILB_PI_CMP_ENABLE1_MASK           0xffffffffffffffff
+#define SH_XN_IILB_PI_CMP_ENABLE1_INIT           0x0000000000000000
+
+/*   SH_XN_IILB_PI_CMP_ENABLE1_ENABLE                                   */
+/*   Description:  Enable1                                              */
+#define SH_XN_IILB_PI_CMP_ENABLE1_ENABLE_SHFT    0
+#define SH_XN_IILB_PI_CMP_ENABLE1_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_IILB_NI0_CMP_EXP_DATA0"                */
+/*                IILB compare NI0 input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_NI0_CMP_EXP_DATA0             0x0000000150031200
+#define SH_XN_IILB_NI0_CMP_EXP_DATA0_MASK        0xffffffffffffffff
+#define SH_XN_IILB_NI0_CMP_EXP_DATA0_INIT        0x0000000000000000
+
+/*   SH_XN_IILB_NI0_CMP_EXP_DATA0_DATA                                  */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_IILB_NI0_CMP_EXP_DATA0_DATA_SHFT   0
+#define SH_XN_IILB_NI0_CMP_EXP_DATA0_DATA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_IILB_NI0_CMP_EXP_DATA1"                */
+/*                IILB compare NI0 input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_NI0_CMP_EXP_DATA1             0x0000000150031210
+#define SH_XN_IILB_NI0_CMP_EXP_DATA1_MASK        0xffffffffffffffff
+#define SH_XN_IILB_NI0_CMP_EXP_DATA1_INIT        0x0000000000000000
+
+/*   SH_XN_IILB_NI0_CMP_EXP_DATA1_DATA                                  */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_IILB_NI0_CMP_EXP_DATA1_DATA_SHFT   0
+#define SH_XN_IILB_NI0_CMP_EXP_DATA1_DATA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_NI0_CMP_ENABLE0"                 */
+/*                    IILB compare NI0 input enable0                    */
+/* ==================================================================== */
+
+#define SH_XN_IILB_NI0_CMP_ENABLE0               0x0000000150031220
+#define SH_XN_IILB_NI0_CMP_ENABLE0_MASK          0xffffffffffffffff
+#define SH_XN_IILB_NI0_CMP_ENABLE0_INIT          0x0000000000000000
+
+/*   SH_XN_IILB_NI0_CMP_ENABLE0_ENABLE                                  */
+/*   Description:  Enable0                                              */
+#define SH_XN_IILB_NI0_CMP_ENABLE0_ENABLE_SHFT   0
+#define SH_XN_IILB_NI0_CMP_ENABLE0_ENABLE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_NI0_CMP_ENABLE1"                 */
+/*                    IILB compare NI0 input enable1                    */
+/* ==================================================================== */
+
+#define SH_XN_IILB_NI0_CMP_ENABLE1               0x0000000150031230
+#define SH_XN_IILB_NI0_CMP_ENABLE1_MASK          0xffffffffffffffff
+#define SH_XN_IILB_NI0_CMP_ENABLE1_INIT          0x0000000000000000
+
+/*   SH_XN_IILB_NI0_CMP_ENABLE1_ENABLE                                  */
+/*   Description:  Enable1                                              */
+#define SH_XN_IILB_NI0_CMP_ENABLE1_ENABLE_SHFT   0
+#define SH_XN_IILB_NI0_CMP_ENABLE1_ENABLE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_IILB_NI1_CMP_EXP_DATA0"                */
+/*                IILB compare NI1 input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_NI1_CMP_EXP_DATA0             0x0000000150031240
+#define SH_XN_IILB_NI1_CMP_EXP_DATA0_MASK        0xffffffffffffffff
+#define SH_XN_IILB_NI1_CMP_EXP_DATA0_INIT        0x0000000000000000
+
+/*   SH_XN_IILB_NI1_CMP_EXP_DATA0_DATA                                  */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_IILB_NI1_CMP_EXP_DATA0_DATA_SHFT   0
+#define SH_XN_IILB_NI1_CMP_EXP_DATA0_DATA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_IILB_NI1_CMP_EXP_DATA1"                */
+/*                IILB compare NI1 input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_IILB_NI1_CMP_EXP_DATA1             0x0000000150031250
+#define SH_XN_IILB_NI1_CMP_EXP_DATA1_MASK        0xffffffffffffffff
+#define SH_XN_IILB_NI1_CMP_EXP_DATA1_INIT        0x0000000000000000
+
+/*   SH_XN_IILB_NI1_CMP_EXP_DATA1_DATA                                  */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_IILB_NI1_CMP_EXP_DATA1_DATA_SHFT   0
+#define SH_XN_IILB_NI1_CMP_EXP_DATA1_DATA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_NI1_CMP_ENABLE0"                 */
+/*                    IILB compare NI1 input enable0                    */
+/* ==================================================================== */
+
+#define SH_XN_IILB_NI1_CMP_ENABLE0               0x0000000150031260
+#define SH_XN_IILB_NI1_CMP_ENABLE0_MASK          0xffffffffffffffff
+#define SH_XN_IILB_NI1_CMP_ENABLE0_INIT          0x0000000000000000
+
+/*   SH_XN_IILB_NI1_CMP_ENABLE0_ENABLE                                  */
+/*   Description:  Enable0                                              */
+#define SH_XN_IILB_NI1_CMP_ENABLE0_ENABLE_SHFT   0
+#define SH_XN_IILB_NI1_CMP_ENABLE0_ENABLE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_NI1_CMP_ENABLE1"                 */
+/*                    IILB compare NI1 input enable1                    */
+/* ==================================================================== */
+
+#define SH_XN_IILB_NI1_CMP_ENABLE1               0x0000000150031270
+#define SH_XN_IILB_NI1_CMP_ENABLE1_MASK          0xffffffffffffffff
+#define SH_XN_IILB_NI1_CMP_ENABLE1_INIT          0x0000000000000000
+
+/*   SH_XN_IILB_NI1_CMP_ENABLE1_ENABLE                                  */
+/*   Description:  Enable1                                              */
+#define SH_XN_IILB_NI1_CMP_ENABLE1_ENABLE_SHFT   0
+#define SH_XN_IILB_NI1_CMP_ENABLE1_ENABLE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_IILB_CMP_EXP_DATA0"                */
+/*                 MD compare IILB input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_MD_IILB_CMP_EXP_DATA0              0x0000000150031500
+#define SH_XN_MD_IILB_CMP_EXP_DATA0_MASK         0xffffffffffffffff
+#define SH_XN_MD_IILB_CMP_EXP_DATA0_INIT         0x0000000000000000
+
+/*   SH_XN_MD_IILB_CMP_EXP_DATA0_DATA                                   */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_MD_IILB_CMP_EXP_DATA0_DATA_SHFT    0
+#define SH_XN_MD_IILB_CMP_EXP_DATA0_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_IILB_CMP_EXP_DATA1"                */
+/*                 MD compare IILB input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_MD_IILB_CMP_EXP_DATA1              0x0000000150031510
+#define SH_XN_MD_IILB_CMP_EXP_DATA1_MASK         0xffffffffffffffff
+#define SH_XN_MD_IILB_CMP_EXP_DATA1_INIT         0x0000000000000000
+
+/*   SH_XN_MD_IILB_CMP_EXP_DATA1_DATA                                   */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_MD_IILB_CMP_EXP_DATA1_DATA_SHFT    0
+#define SH_XN_MD_IILB_CMP_EXP_DATA1_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_IILB_CMP_ENABLE0"                 */
+/*                    MD compare IILB input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_MD_IILB_CMP_ENABLE0                0x0000000150031520
+#define SH_XN_MD_IILB_CMP_ENABLE0_MASK           0xffffffffffffffff
+#define SH_XN_MD_IILB_CMP_ENABLE0_INIT           0x0000000000000000
+
+/*   SH_XN_MD_IILB_CMP_ENABLE0_ENABLE                                   */
+/*   Description:  Enable0                                              */
+#define SH_XN_MD_IILB_CMP_ENABLE0_ENABLE_SHFT    0
+#define SH_XN_MD_IILB_CMP_ENABLE0_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_IILB_CMP_ENABLE1"                 */
+/*                    MD compare IILB input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_MD_IILB_CMP_ENABLE1                0x0000000150031530
+#define SH_XN_MD_IILB_CMP_ENABLE1_MASK           0xffffffffffffffff
+#define SH_XN_MD_IILB_CMP_ENABLE1_INIT           0x0000000000000000
+
+/*   SH_XN_MD_IILB_CMP_ENABLE1_ENABLE                                   */
+/*   Description:  Enable1                                              */
+#define SH_XN_MD_IILB_CMP_ENABLE1_ENABLE_SHFT    0
+#define SH_XN_MD_IILB_CMP_ENABLE1_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_NI0_CMP_EXP_DATA0"                 */
+/*                 MD compare NI0 input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_MD_NI0_CMP_EXP_DATA0               0x0000000150031540
+#define SH_XN_MD_NI0_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_MD_NI0_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_MD_NI0_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_MD_NI0_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_MD_NI0_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_NI0_CMP_EXP_DATA1"                 */
+/*                 MD compare NI0 input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_MD_NI0_CMP_EXP_DATA1               0x0000000150031550
+#define SH_XN_MD_NI0_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_MD_NI0_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_MD_NI0_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_MD_NI0_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_MD_NI0_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_NI0_CMP_ENABLE0"                  */
+/*                     MD compare NI0 input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_MD_NI0_CMP_ENABLE0                 0x0000000150031560
+#define SH_XN_MD_NI0_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_MD_NI0_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_MD_NI0_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_MD_NI0_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_MD_NI0_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_NI0_CMP_ENABLE1"                  */
+/*                     MD compare NI0 input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_MD_NI0_CMP_ENABLE1                 0x0000000150031570
+#define SH_XN_MD_NI0_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_MD_NI0_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_MD_NI0_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_MD_NI0_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_MD_NI0_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_NI1_CMP_EXP_DATA0"                 */
+/*                 MD compare NI1 input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_MD_NI1_CMP_EXP_DATA0               0x0000000150031580
+#define SH_XN_MD_NI1_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_MD_NI1_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_MD_NI1_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_MD_NI1_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_MD_NI1_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_NI1_CMP_EXP_DATA1"                 */
+/*                 MD compare NI1 input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_MD_NI1_CMP_EXP_DATA1               0x0000000150031590
+#define SH_XN_MD_NI1_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_MD_NI1_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_MD_NI1_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_MD_NI1_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_MD_NI1_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_NI1_CMP_ENABLE0"                  */
+/*                     MD compare NI1 input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_MD_NI1_CMP_ENABLE0                 0x00000001500315a0
+#define SH_XN_MD_NI1_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_MD_NI1_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_MD_NI1_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_MD_NI1_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_MD_NI1_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_NI1_CMP_ENABLE1"                  */
+/*                     MD compare NI1 input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_MD_NI1_CMP_ENABLE1                 0x00000001500315b0
+#define SH_XN_MD_NI1_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_MD_NI1_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_MD_NI1_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_MD_NI1_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_MD_NI1_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_SIC_CMP_EXP_HDR0"                 */
+/*                MD compare SIC input expected header0                 */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_EXP_HDR0                0x00000001500315c0
+#define SH_XN_MD_SIC_CMP_EXP_HDR0_MASK           0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_EXP_HDR0_INIT           0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_EXP_HDR0_DATA                                     */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_MD_SIC_CMP_EXP_HDR0_DATA_SHFT      0
+#define SH_XN_MD_SIC_CMP_EXP_HDR0_DATA_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_SIC_CMP_EXP_HDR1"                 */
+/*                MD compare SIC input expected header1                 */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_EXP_HDR1                0x00000001500315d0
+#define SH_XN_MD_SIC_CMP_EXP_HDR1_MASK           0x000003ffffffffff
+#define SH_XN_MD_SIC_CMP_EXP_HDR1_INIT           0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_EXP_HDR1_DATA                                     */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_MD_SIC_CMP_EXP_HDR1_DATA_SHFT      0
+#define SH_XN_MD_SIC_CMP_EXP_HDR1_DATA_MASK      0x000003ffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_HDR_ENABLE0"                */
+/*                    MD compare SIC header enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE0             0x00000001500315e0
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE0_MASK        0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE0_INIT        0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_HDR_ENABLE0_ENABLE                                */
+/*   Description:  Enable0                                              */
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE0_ENABLE_SHFT 0
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE0_ENABLE_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_HDR_ENABLE1"                */
+/*                    MD compare SIC header enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE1             0x00000001500315f0
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE1_MASK        0x000003ffffffffff
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE1_INIT        0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_HDR_ENABLE1_ENABLE                                */
+/*   Description:  Enable1                                              */
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE1_ENABLE_SHFT 0
+#define SH_XN_MD_SIC_CMP_HDR_ENABLE1_ENABLE_MASK 0x000003ffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XN_MD_SIC_CMP_DATA0"                   */
+/*                         MD compare SIC data0                         */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_DATA0                   0x0000000150031600
+#define SH_XN_MD_SIC_CMP_DATA0_MASK              0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_DATA0_INIT              0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_DATA0_DATA0                                       */
+/*   Description:  Data0                                                */
+#define SH_XN_MD_SIC_CMP_DATA0_DATA0_SHFT        0
+#define SH_XN_MD_SIC_CMP_DATA0_DATA0_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XN_MD_SIC_CMP_DATA1"                   */
+/*                         MD compare SIC data1                         */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_DATA1                   0x0000000150031610
+#define SH_XN_MD_SIC_CMP_DATA1_MASK              0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_DATA1_INIT              0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_DATA1_DATA1                                       */
+/*   Description:  Data1                                                */
+#define SH_XN_MD_SIC_CMP_DATA1_DATA1_SHFT        0
+#define SH_XN_MD_SIC_CMP_DATA1_DATA1_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XN_MD_SIC_CMP_DATA2"                   */
+/*                         MD compare SIC data2                         */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_DATA2                   0x0000000150031620
+#define SH_XN_MD_SIC_CMP_DATA2_MASK              0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_DATA2_INIT              0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_DATA2_DATA2                                       */
+/*   Description:  Data2                                                */
+#define SH_XN_MD_SIC_CMP_DATA2_DATA2_SHFT        0
+#define SH_XN_MD_SIC_CMP_DATA2_DATA2_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XN_MD_SIC_CMP_DATA3"                   */
+/*                         MD compare SIC data3                         */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_DATA3                   0x0000000150031630
+#define SH_XN_MD_SIC_CMP_DATA3_MASK              0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_DATA3_INIT              0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_DATA3_DATA3                                       */
+/*   Description:  Data3                                                */
+#define SH_XN_MD_SIC_CMP_DATA3_DATA3_SHFT        0
+#define SH_XN_MD_SIC_CMP_DATA3_DATA3_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE0"               */
+/*                     MD enable compare SIC data0                      */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE0            0x0000000150031640
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE0_MASK       0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE0_INIT       0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_DATA_ENABLE0_DATA_ENABLE0                         */
+/*   Description:  Data0                                                */
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE0_DATA_ENABLE0_SHFT 0
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE0_DATA_ENABLE0_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE1"               */
+/*                     MD enable compare SIC data1                      */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE1            0x0000000150031650
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE1_MASK       0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE1_INIT       0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_DATA_ENABLE1_DATA_ENABLE1                         */
+/*   Description:  Data1                                                */
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE1_DATA_ENABLE1_SHFT 0
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE1_DATA_ENABLE1_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE2"               */
+/*                     MD enable compare SIC data2                      */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE2            0x0000000150031660
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE2_MASK       0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE2_INIT       0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_DATA_ENABLE2_DATA_ENABLE2                         */
+/*   Description:  Data2                                                */
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE2_DATA_ENABLE2_SHFT 0
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE2_DATA_ENABLE2_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE3"               */
+/*                     MD enable compare SIC data3                      */
+/* ==================================================================== */
+
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE3            0x0000000150031670
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE3_MASK       0xffffffffffffffff
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE3_INIT       0x0000000000000000
+
+/*   SH_XN_MD_SIC_CMP_DATA_ENABLE3_DATA_ENABLE3                         */
+/*   Description:  Data3                                                */
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE3_DATA_ENABLE3_SHFT 0
+#define SH_XN_MD_SIC_CMP_DATA_ENABLE3_DATA_ENABLE3_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_IILB_CMP_EXP_DATA0"                */
+/*                 PI compare IILB input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_PI_IILB_CMP_EXP_DATA0              0x0000000150031300
+#define SH_XN_PI_IILB_CMP_EXP_DATA0_MASK         0xffffffffffffffff
+#define SH_XN_PI_IILB_CMP_EXP_DATA0_INIT         0x0000000000000000
+
+/*   SH_XN_PI_IILB_CMP_EXP_DATA0_DATA                                   */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_PI_IILB_CMP_EXP_DATA0_DATA_SHFT    0
+#define SH_XN_PI_IILB_CMP_EXP_DATA0_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_IILB_CMP_EXP_DATA1"                */
+/*                 PI compare IILB input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_PI_IILB_CMP_EXP_DATA1              0x0000000150031310
+#define SH_XN_PI_IILB_CMP_EXP_DATA1_MASK         0xffffffffffffffff
+#define SH_XN_PI_IILB_CMP_EXP_DATA1_INIT         0x0000000000000000
+
+/*   SH_XN_PI_IILB_CMP_EXP_DATA1_DATA                                   */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_PI_IILB_CMP_EXP_DATA1_DATA_SHFT    0
+#define SH_XN_PI_IILB_CMP_EXP_DATA1_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_IILB_CMP_ENABLE0"                 */
+/*                    PI compare IILB input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_PI_IILB_CMP_ENABLE0                0x0000000150031320
+#define SH_XN_PI_IILB_CMP_ENABLE0_MASK           0xffffffffffffffff
+#define SH_XN_PI_IILB_CMP_ENABLE0_INIT           0x0000000000000000
+
+/*   SH_XN_PI_IILB_CMP_ENABLE0_ENABLE                                   */
+/*   Description:  Enable0                                              */
+#define SH_XN_PI_IILB_CMP_ENABLE0_ENABLE_SHFT    0
+#define SH_XN_PI_IILB_CMP_ENABLE0_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_IILB_CMP_ENABLE1"                 */
+/*                    PI compare IILB input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_PI_IILB_CMP_ENABLE1                0x0000000150031330
+#define SH_XN_PI_IILB_CMP_ENABLE1_MASK           0xffffffffffffffff
+#define SH_XN_PI_IILB_CMP_ENABLE1_INIT           0x0000000000000000
+
+/*   SH_XN_PI_IILB_CMP_ENABLE1_ENABLE                                   */
+/*   Description:  Enable1                                              */
+#define SH_XN_PI_IILB_CMP_ENABLE1_ENABLE_SHFT    0
+#define SH_XN_PI_IILB_CMP_ENABLE1_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_NI0_CMP_EXP_DATA0"                 */
+/*                 PI compare NI0 input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_PI_NI0_CMP_EXP_DATA0               0x0000000150031340
+#define SH_XN_PI_NI0_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_PI_NI0_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_PI_NI0_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_PI_NI0_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_PI_NI0_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_NI0_CMP_EXP_DATA1"                 */
+/*                 PI compare NI0 input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_PI_NI0_CMP_EXP_DATA1               0x0000000150031350
+#define SH_XN_PI_NI0_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_PI_NI0_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_PI_NI0_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_PI_NI0_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_PI_NI0_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_NI0_CMP_ENABLE0"                  */
+/*                     PI compare NI0 input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_PI_NI0_CMP_ENABLE0                 0x0000000150031360
+#define SH_XN_PI_NI0_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_PI_NI0_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_PI_NI0_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_PI_NI0_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_PI_NI0_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_NI0_CMP_ENABLE1"                  */
+/*                     PI compare NI0 input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_PI_NI0_CMP_ENABLE1                 0x0000000150031370
+#define SH_XN_PI_NI0_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_PI_NI0_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_PI_NI0_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_PI_NI0_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_PI_NI0_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_NI1_CMP_EXP_DATA0"                 */
+/*                 PI compare NI1 input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_PI_NI1_CMP_EXP_DATA0               0x0000000150031380
+#define SH_XN_PI_NI1_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_PI_NI1_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_PI_NI1_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_PI_NI1_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_PI_NI1_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_NI1_CMP_EXP_DATA1"                 */
+/*                 PI compare NI1 input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_PI_NI1_CMP_EXP_DATA1               0x0000000150031390
+#define SH_XN_PI_NI1_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_PI_NI1_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_PI_NI1_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_PI_NI1_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_PI_NI1_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_NI1_CMP_ENABLE0"                  */
+/*                     PI compare NI1 input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_PI_NI1_CMP_ENABLE0                 0x00000001500313a0
+#define SH_XN_PI_NI1_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_PI_NI1_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_PI_NI1_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_PI_NI1_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_PI_NI1_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_NI1_CMP_ENABLE1"                  */
+/*                     PI compare NI1 input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_PI_NI1_CMP_ENABLE1                 0x00000001500313b0
+#define SH_XN_PI_NI1_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_PI_NI1_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_PI_NI1_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_PI_NI1_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_PI_NI1_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_SIC_CMP_EXP_HDR0"                 */
+/*                PI compare SIC input expected header0                 */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_EXP_HDR0                0x00000001500313c0
+#define SH_XN_PI_SIC_CMP_EXP_HDR0_MASK           0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_EXP_HDR0_INIT           0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_EXP_HDR0_DATA                                     */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_PI_SIC_CMP_EXP_HDR0_DATA_SHFT      0
+#define SH_XN_PI_SIC_CMP_EXP_HDR0_DATA_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_SIC_CMP_EXP_HDR1"                 */
+/*                PI compare SIC input expected header1                 */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_EXP_HDR1                0x00000001500313d0
+#define SH_XN_PI_SIC_CMP_EXP_HDR1_MASK           0x000003ffffffffff
+#define SH_XN_PI_SIC_CMP_EXP_HDR1_INIT           0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_EXP_HDR1_DATA                                     */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_PI_SIC_CMP_EXP_HDR1_DATA_SHFT      0
+#define SH_XN_PI_SIC_CMP_EXP_HDR1_DATA_MASK      0x000003ffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_HDR_ENABLE0"                */
+/*                    PI compare SIC header enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE0             0x00000001500313e0
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE0_MASK        0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE0_INIT        0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_HDR_ENABLE0_ENABLE                                */
+/*   Description:  Enable0                                              */
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE0_ENABLE_SHFT 0
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE0_ENABLE_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_HDR_ENABLE1"                */
+/*                    PI compare SIC header enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE1             0x00000001500313f0
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE1_MASK        0x000003ffffffffff
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE1_INIT        0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_HDR_ENABLE1_ENABLE                                */
+/*   Description:  Enable1                                              */
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE1_ENABLE_SHFT 0
+#define SH_XN_PI_SIC_CMP_HDR_ENABLE1_ENABLE_MASK 0x000003ffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XN_PI_SIC_CMP_DATA0"                   */
+/*                         PI compare SIC data0                         */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_DATA0                   0x0000000150031400
+#define SH_XN_PI_SIC_CMP_DATA0_MASK              0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_DATA0_INIT              0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_DATA0_DATA0                                       */
+/*   Description:  Data0                                                */
+#define SH_XN_PI_SIC_CMP_DATA0_DATA0_SHFT        0
+#define SH_XN_PI_SIC_CMP_DATA0_DATA0_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XN_PI_SIC_CMP_DATA1"                   */
+/*                         PI compare SIC data1                         */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_DATA1                   0x0000000150031410
+#define SH_XN_PI_SIC_CMP_DATA1_MASK              0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_DATA1_INIT              0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_DATA1_DATA1                                       */
+/*   Description:  Data1                                                */
+#define SH_XN_PI_SIC_CMP_DATA1_DATA1_SHFT        0
+#define SH_XN_PI_SIC_CMP_DATA1_DATA1_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XN_PI_SIC_CMP_DATA2"                   */
+/*                         PI compare SIC data2                         */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_DATA2                   0x0000000150031420
+#define SH_XN_PI_SIC_CMP_DATA2_MASK              0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_DATA2_INIT              0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_DATA2_DATA2                                       */
+/*   Description:  Data2                                                */
+#define SH_XN_PI_SIC_CMP_DATA2_DATA2_SHFT        0
+#define SH_XN_PI_SIC_CMP_DATA2_DATA2_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XN_PI_SIC_CMP_DATA3"                   */
+/*                         PI compare SIC data3                         */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_DATA3                   0x0000000150031430
+#define SH_XN_PI_SIC_CMP_DATA3_MASK              0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_DATA3_INIT              0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_DATA3_DATA3                                       */
+/*   Description:  Data3                                                */
+#define SH_XN_PI_SIC_CMP_DATA3_DATA3_SHFT        0
+#define SH_XN_PI_SIC_CMP_DATA3_DATA3_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE0"               */
+/*                     PI enable compare SIC data0                      */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE0            0x0000000150031440
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE0_MASK       0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE0_INIT       0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_DATA_ENABLE0_DATA_ENABLE0                         */
+/*   Description:  Data0                                                */
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE0_DATA_ENABLE0_SHFT 0
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE0_DATA_ENABLE0_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE1"               */
+/*                     PI enable compare SIC data1                      */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE1            0x0000000150031450
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE1_MASK       0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE1_INIT       0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_DATA_ENABLE1_DATA_ENABLE1                         */
+/*   Description:  Data1                                                */
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE1_DATA_ENABLE1_SHFT 0
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE1_DATA_ENABLE1_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE2"               */
+/*                     PI enable compare SIC data2                      */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE2            0x0000000150031460
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE2_MASK       0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE2_INIT       0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_DATA_ENABLE2_DATA_ENABLE2                         */
+/*   Description:  Data2                                                */
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE2_DATA_ENABLE2_SHFT 0
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE2_DATA_ENABLE2_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE3"               */
+/*                     PI enable compare SIC data3                      */
+/* ==================================================================== */
+
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE3            0x0000000150031470
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE3_MASK       0xffffffffffffffff
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE3_INIT       0x0000000000000000
+
+/*   SH_XN_PI_SIC_CMP_DATA_ENABLE3_DATA_ENABLE3                         */
+/*   Description:  Data3                                                */
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE3_DATA_ENABLE3_SHFT 0
+#define SH_XN_PI_SIC_CMP_DATA_ENABLE3_DATA_ENABLE3_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_NI0_IILB_CMP_EXP_DATA0"                */
+/*                NI0 compare IILB input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_NI0_IILB_CMP_EXP_DATA0             0x0000000150031700
+#define SH_XN_NI0_IILB_CMP_EXP_DATA0_MASK        0xffffffffffffffff
+#define SH_XN_NI0_IILB_CMP_EXP_DATA0_INIT        0x0000000000000000
+
+/*   SH_XN_NI0_IILB_CMP_EXP_DATA0_DATA                                  */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI0_IILB_CMP_EXP_DATA0_DATA_SHFT   0
+#define SH_XN_NI0_IILB_CMP_EXP_DATA0_DATA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_NI0_IILB_CMP_EXP_DATA1"                */
+/*                NI0 compare IILB input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_NI0_IILB_CMP_EXP_DATA1             0x0000000150031710
+#define SH_XN_NI0_IILB_CMP_EXP_DATA1_MASK        0xffffffffffffffff
+#define SH_XN_NI0_IILB_CMP_EXP_DATA1_INIT        0x0000000000000000
+
+/*   SH_XN_NI0_IILB_CMP_EXP_DATA1_DATA                                  */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI0_IILB_CMP_EXP_DATA1_DATA_SHFT   0
+#define SH_XN_NI0_IILB_CMP_EXP_DATA1_DATA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_IILB_CMP_ENABLE0"                 */
+/*                    NI0 compare IILB input enable0                    */
+/* ==================================================================== */
+
+#define SH_XN_NI0_IILB_CMP_ENABLE0               0x0000000150031720
+#define SH_XN_NI0_IILB_CMP_ENABLE0_MASK          0xffffffffffffffff
+#define SH_XN_NI0_IILB_CMP_ENABLE0_INIT          0x0000000000000000
+
+/*   SH_XN_NI0_IILB_CMP_ENABLE0_ENABLE                                  */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI0_IILB_CMP_ENABLE0_ENABLE_SHFT   0
+#define SH_XN_NI0_IILB_CMP_ENABLE0_ENABLE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_IILB_CMP_ENABLE1"                 */
+/*                    NI0 compare IILB input enable1                    */
+/* ==================================================================== */
+
+#define SH_XN_NI0_IILB_CMP_ENABLE1               0x0000000150031730
+#define SH_XN_NI0_IILB_CMP_ENABLE1_MASK          0xffffffffffffffff
+#define SH_XN_NI0_IILB_CMP_ENABLE1_INIT          0x0000000000000000
+
+/*   SH_XN_NI0_IILB_CMP_ENABLE1_ENABLE                                  */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI0_IILB_CMP_ENABLE1_ENABLE_SHFT   0
+#define SH_XN_NI0_IILB_CMP_ENABLE1_ENABLE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_PI_CMP_EXP_DATA0"                 */
+/*                 NI0 compare PI input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_NI0_PI_CMP_EXP_DATA0               0x0000000150031740
+#define SH_XN_NI0_PI_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_NI0_PI_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_NI0_PI_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI0_PI_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_NI0_PI_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_PI_CMP_EXP_DATA1"                 */
+/*                 NI0 compare PI input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_NI0_PI_CMP_EXP_DATA1               0x0000000150031750
+#define SH_XN_NI0_PI_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_NI0_PI_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_NI0_PI_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI0_PI_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_NI0_PI_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_PI_CMP_ENABLE0"                  */
+/*                     NI0 compare PI input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_NI0_PI_CMP_ENABLE0                 0x0000000150031760
+#define SH_XN_NI0_PI_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_NI0_PI_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_NI0_PI_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI0_PI_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_NI0_PI_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_PI_CMP_ENABLE1"                  */
+/*                     NI0 compare PI input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_NI0_PI_CMP_ENABLE1                 0x0000000150031770
+#define SH_XN_NI0_PI_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_NI0_PI_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_NI0_PI_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI0_PI_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_NI0_PI_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_MD_CMP_EXP_DATA0"                 */
+/*                 NI0 compare MD input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_NI0_MD_CMP_EXP_DATA0               0x0000000150031780
+#define SH_XN_NI0_MD_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_NI0_MD_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_NI0_MD_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI0_MD_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_NI0_MD_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_MD_CMP_EXP_DATA1"                 */
+/*                 NI0 compare MD input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_NI0_MD_CMP_EXP_DATA1               0x0000000150031790
+#define SH_XN_NI0_MD_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_NI0_MD_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_NI0_MD_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI0_MD_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_NI0_MD_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_MD_CMP_ENABLE0"                  */
+/*                     NI0 compare MD input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_NI0_MD_CMP_ENABLE0                 0x00000001500317a0
+#define SH_XN_NI0_MD_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_NI0_MD_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_NI0_MD_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI0_MD_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_NI0_MD_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_MD_CMP_ENABLE1"                  */
+/*                     NI0 compare MD input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_NI0_MD_CMP_ENABLE1                 0x00000001500317b0
+#define SH_XN_NI0_MD_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_NI0_MD_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_NI0_MD_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI0_MD_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_NI0_MD_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_NI_CMP_EXP_DATA0"                 */
+/*                 NI0 compare NI input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_NI0_NI_CMP_EXP_DATA0               0x00000001500317c0
+#define SH_XN_NI0_NI_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_NI0_NI_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_NI0_NI_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI0_NI_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_NI0_NI_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_NI_CMP_EXP_DATA1"                 */
+/*                 NI0 compare NI input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_NI0_NI_CMP_EXP_DATA1               0x00000001500317d0
+#define SH_XN_NI0_NI_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_NI0_NI_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_NI0_NI_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI0_NI_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_NI0_NI_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_NI_CMP_ENABLE0"                  */
+/*                     NI0 compare NI input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_NI0_NI_CMP_ENABLE0                 0x00000001500317e0
+#define SH_XN_NI0_NI_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_NI0_NI_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_NI0_NI_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI0_NI_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_NI0_NI_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_NI_CMP_ENABLE1"                  */
+/*                     NI0 compare NI input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_NI0_NI_CMP_ENABLE1                 0x00000001500317f0
+#define SH_XN_NI0_NI_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_NI0_NI_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_NI0_NI_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI0_NI_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_NI0_NI_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_LLP_CMP_EXP_DATA0"                */
+/*                 NI0 compare LLP input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_NI0_LLP_CMP_EXP_DATA0              0x0000000150031800
+#define SH_XN_NI0_LLP_CMP_EXP_DATA0_MASK         0xffffffffffffffff
+#define SH_XN_NI0_LLP_CMP_EXP_DATA0_INIT         0x0000000000000000
+
+/*   SH_XN_NI0_LLP_CMP_EXP_DATA0_DATA                                   */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI0_LLP_CMP_EXP_DATA0_DATA_SHFT    0
+#define SH_XN_NI0_LLP_CMP_EXP_DATA0_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_LLP_CMP_EXP_DATA1"                */
+/*                 NI0 compare LLP input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_NI0_LLP_CMP_EXP_DATA1              0x0000000150031810
+#define SH_XN_NI0_LLP_CMP_EXP_DATA1_MASK         0xffffffffffffffff
+#define SH_XN_NI0_LLP_CMP_EXP_DATA1_INIT         0x0000000000000000
+
+/*   SH_XN_NI0_LLP_CMP_EXP_DATA1_DATA                                   */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI0_LLP_CMP_EXP_DATA1_DATA_SHFT    0
+#define SH_XN_NI0_LLP_CMP_EXP_DATA1_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_LLP_CMP_ENABLE0"                 */
+/*                    NI0 compare LLP input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_NI0_LLP_CMP_ENABLE0                0x0000000150031820
+#define SH_XN_NI0_LLP_CMP_ENABLE0_MASK           0xffffffffffffffff
+#define SH_XN_NI0_LLP_CMP_ENABLE0_INIT           0x0000000000000000
+
+/*   SH_XN_NI0_LLP_CMP_ENABLE0_ENABLE                                   */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI0_LLP_CMP_ENABLE0_ENABLE_SHFT    0
+#define SH_XN_NI0_LLP_CMP_ENABLE0_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_LLP_CMP_ENABLE1"                 */
+/*                    NI0 compare LLP input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_NI0_LLP_CMP_ENABLE1                0x0000000150031830
+#define SH_XN_NI0_LLP_CMP_ENABLE1_MASK           0xffffffffffffffff
+#define SH_XN_NI0_LLP_CMP_ENABLE1_INIT           0x0000000000000000
+
+/*   SH_XN_NI0_LLP_CMP_ENABLE1_ENABLE                                   */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI0_LLP_CMP_ENABLE1_ENABLE_SHFT    0
+#define SH_XN_NI0_LLP_CMP_ENABLE1_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_NI1_IILB_CMP_EXP_DATA0"                */
+/*                NI1 compare IILB input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_NI1_IILB_CMP_EXP_DATA0             0x0000000150031900
+#define SH_XN_NI1_IILB_CMP_EXP_DATA0_MASK        0xffffffffffffffff
+#define SH_XN_NI1_IILB_CMP_EXP_DATA0_INIT        0x0000000000000000
+
+/*   SH_XN_NI1_IILB_CMP_EXP_DATA0_DATA                                  */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI1_IILB_CMP_EXP_DATA0_DATA_SHFT   0
+#define SH_XN_NI1_IILB_CMP_EXP_DATA0_DATA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*               Register "SH_XN_NI1_IILB_CMP_EXP_DATA1"                */
+/*                NI1 compare IILB input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_NI1_IILB_CMP_EXP_DATA1             0x0000000150031910
+#define SH_XN_NI1_IILB_CMP_EXP_DATA1_MASK        0xffffffffffffffff
+#define SH_XN_NI1_IILB_CMP_EXP_DATA1_INIT        0x0000000000000000
+
+/*   SH_XN_NI1_IILB_CMP_EXP_DATA1_DATA                                  */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI1_IILB_CMP_EXP_DATA1_DATA_SHFT   0
+#define SH_XN_NI1_IILB_CMP_EXP_DATA1_DATA_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_IILB_CMP_ENABLE0"                 */
+/*                    NI1 compare IILB input enable0                    */
+/* ==================================================================== */
+
+#define SH_XN_NI1_IILB_CMP_ENABLE0               0x0000000150031920
+#define SH_XN_NI1_IILB_CMP_ENABLE0_MASK          0xffffffffffffffff
+#define SH_XN_NI1_IILB_CMP_ENABLE0_INIT          0x0000000000000000
+
+/*   SH_XN_NI1_IILB_CMP_ENABLE0_ENABLE                                  */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI1_IILB_CMP_ENABLE0_ENABLE_SHFT   0
+#define SH_XN_NI1_IILB_CMP_ENABLE0_ENABLE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_IILB_CMP_ENABLE1"                 */
+/*                    NI1 compare IILB input enable1                    */
+/* ==================================================================== */
+
+#define SH_XN_NI1_IILB_CMP_ENABLE1               0x0000000150031930
+#define SH_XN_NI1_IILB_CMP_ENABLE1_MASK          0xffffffffffffffff
+#define SH_XN_NI1_IILB_CMP_ENABLE1_INIT          0x0000000000000000
+
+/*   SH_XN_NI1_IILB_CMP_ENABLE1_ENABLE                                  */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI1_IILB_CMP_ENABLE1_ENABLE_SHFT   0
+#define SH_XN_NI1_IILB_CMP_ENABLE1_ENABLE_MASK   0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_PI_CMP_EXP_DATA0"                 */
+/*                 NI1 compare PI input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_NI1_PI_CMP_EXP_DATA0               0x0000000150031940
+#define SH_XN_NI1_PI_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_NI1_PI_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_NI1_PI_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI1_PI_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_NI1_PI_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_PI_CMP_EXP_DATA1"                 */
+/*                 NI1 compare PI input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_NI1_PI_CMP_EXP_DATA1               0x0000000150031950
+#define SH_XN_NI1_PI_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_NI1_PI_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_NI1_PI_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI1_PI_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_NI1_PI_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_PI_CMP_ENABLE0"                  */
+/*                     NI1 compare PI input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_NI1_PI_CMP_ENABLE0                 0x0000000150031960
+#define SH_XN_NI1_PI_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_NI1_PI_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_NI1_PI_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI1_PI_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_NI1_PI_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_PI_CMP_ENABLE1"                  */
+/*                     NI1 compare PI input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_NI1_PI_CMP_ENABLE1                 0x0000000150031970
+#define SH_XN_NI1_PI_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_NI1_PI_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_NI1_PI_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI1_PI_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_NI1_PI_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_MD_CMP_EXP_DATA0"                 */
+/*                 NI1 compare MD input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_NI1_MD_CMP_EXP_DATA0               0x0000000150031980
+#define SH_XN_NI1_MD_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_NI1_MD_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_NI1_MD_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI1_MD_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_NI1_MD_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_MD_CMP_EXP_DATA1"                 */
+/*                 NI1 compare MD input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_NI1_MD_CMP_EXP_DATA1               0x0000000150031990
+#define SH_XN_NI1_MD_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_NI1_MD_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_NI1_MD_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI1_MD_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_NI1_MD_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_MD_CMP_ENABLE0"                  */
+/*                     NI1 compare MD input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_NI1_MD_CMP_ENABLE0                 0x00000001500319a0
+#define SH_XN_NI1_MD_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_NI1_MD_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_NI1_MD_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI1_MD_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_NI1_MD_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_MD_CMP_ENABLE1"                  */
+/*                     NI1 compare MD input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_NI1_MD_CMP_ENABLE1                 0x00000001500319b0
+#define SH_XN_NI1_MD_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_NI1_MD_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_NI1_MD_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI1_MD_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_NI1_MD_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_NI_CMP_EXP_DATA0"                 */
+/*                 NI1 compare NI input expected data0                  */
+/* ==================================================================== */
+
+#define SH_XN_NI1_NI_CMP_EXP_DATA0               0x00000001500319c0
+#define SH_XN_NI1_NI_CMP_EXP_DATA0_MASK          0xffffffffffffffff
+#define SH_XN_NI1_NI_CMP_EXP_DATA0_INIT          0x0000000000000000
+
+/*   SH_XN_NI1_NI_CMP_EXP_DATA0_DATA                                    */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI1_NI_CMP_EXP_DATA0_DATA_SHFT     0
+#define SH_XN_NI1_NI_CMP_EXP_DATA0_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_NI_CMP_EXP_DATA1"                 */
+/*                 NI1 compare NI input expected data1                  */
+/* ==================================================================== */
+
+#define SH_XN_NI1_NI_CMP_EXP_DATA1               0x00000001500319d0
+#define SH_XN_NI1_NI_CMP_EXP_DATA1_MASK          0xffffffffffffffff
+#define SH_XN_NI1_NI_CMP_EXP_DATA1_INIT          0x0000000000000000
+
+/*   SH_XN_NI1_NI_CMP_EXP_DATA1_DATA                                    */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI1_NI_CMP_EXP_DATA1_DATA_SHFT     0
+#define SH_XN_NI1_NI_CMP_EXP_DATA1_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_NI_CMP_ENABLE0"                  */
+/*                     NI1 compare NI input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_NI1_NI_CMP_ENABLE0                 0x00000001500319e0
+#define SH_XN_NI1_NI_CMP_ENABLE0_MASK            0xffffffffffffffff
+#define SH_XN_NI1_NI_CMP_ENABLE0_INIT            0x0000000000000000
+
+/*   SH_XN_NI1_NI_CMP_ENABLE0_ENABLE                                    */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI1_NI_CMP_ENABLE0_ENABLE_SHFT     0
+#define SH_XN_NI1_NI_CMP_ENABLE0_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_NI_CMP_ENABLE1"                  */
+/*                     NI1 compare NI input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_NI1_NI_CMP_ENABLE1                 0x00000001500319f0
+#define SH_XN_NI1_NI_CMP_ENABLE1_MASK            0xffffffffffffffff
+#define SH_XN_NI1_NI_CMP_ENABLE1_INIT            0x0000000000000000
+
+/*   SH_XN_NI1_NI_CMP_ENABLE1_ENABLE                                    */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI1_NI_CMP_ENABLE1_ENABLE_SHFT     0
+#define SH_XN_NI1_NI_CMP_ENABLE1_ENABLE_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_LLP_CMP_EXP_DATA0"                */
+/*                 NI1 compare LLP input expected data0                 */
+/* ==================================================================== */
+
+#define SH_XN_NI1_LLP_CMP_EXP_DATA0              0x0000000150031a00
+#define SH_XN_NI1_LLP_CMP_EXP_DATA0_MASK         0xffffffffffffffff
+#define SH_XN_NI1_LLP_CMP_EXP_DATA0_INIT         0x0000000000000000
+
+/*   SH_XN_NI1_LLP_CMP_EXP_DATA0_DATA                                   */
+/*   Description:  Expected data 0                                      */
+#define SH_XN_NI1_LLP_CMP_EXP_DATA0_DATA_SHFT    0
+#define SH_XN_NI1_LLP_CMP_EXP_DATA0_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_LLP_CMP_EXP_DATA1"                */
+/*                 NI1 compare LLP input expected data1                 */
+/* ==================================================================== */
+
+#define SH_XN_NI1_LLP_CMP_EXP_DATA1              0x0000000150031a10
+#define SH_XN_NI1_LLP_CMP_EXP_DATA1_MASK         0xffffffffffffffff
+#define SH_XN_NI1_LLP_CMP_EXP_DATA1_INIT         0x0000000000000000
+
+/*   SH_XN_NI1_LLP_CMP_EXP_DATA1_DATA                                   */
+/*   Description:  Expected data 1                                      */
+#define SH_XN_NI1_LLP_CMP_EXP_DATA1_DATA_SHFT    0
+#define SH_XN_NI1_LLP_CMP_EXP_DATA1_DATA_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_LLP_CMP_ENABLE0"                 */
+/*                    NI1 compare LLP input enable0                     */
+/* ==================================================================== */
+
+#define SH_XN_NI1_LLP_CMP_ENABLE0                0x0000000150031a20
+#define SH_XN_NI1_LLP_CMP_ENABLE0_MASK           0xffffffffffffffff
+#define SH_XN_NI1_LLP_CMP_ENABLE0_INIT           0x0000000000000000
+
+/*   SH_XN_NI1_LLP_CMP_ENABLE0_ENABLE                                   */
+/*   Description:  Enable0                                              */
+#define SH_XN_NI1_LLP_CMP_ENABLE0_ENABLE_SHFT    0
+#define SH_XN_NI1_LLP_CMP_ENABLE0_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_LLP_CMP_ENABLE1"                 */
+/*                    NI1 compare LLP input enable1                     */
+/* ==================================================================== */
+
+#define SH_XN_NI1_LLP_CMP_ENABLE1                0x0000000150031a30
+#define SH_XN_NI1_LLP_CMP_ENABLE1_MASK           0xffffffffffffffff
+#define SH_XN_NI1_LLP_CMP_ENABLE1_INIT           0x0000000000000000
+
+/*   SH_XN_NI1_LLP_CMP_ENABLE1_ENABLE                                   */
+/*   Description:  Enable1                                              */
+#define SH_XN_NI1_LLP_CMP_ENABLE1_ENABLE_SHFT    0
+#define SH_XN_NI1_LLP_CMP_ENABLE1_ENABLE_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_XNPI_ECC_INJ_REG"                    */
+/* ==================================================================== */
+
+#define SH_XNPI_ECC_INJ_REG                      0x0000000150032000
+#define SH_XNPI_ECC_INJ_REG_MASK                 0xf0fff0fff0fff0ff
+#define SH_XNPI_ECC_INJ_REG_INIT                 0x0000000000000000
+
+/*   SH_XNPI_ECC_INJ_REG_BYTE0                                          */
+/*   Description:  Replacement Checkbyte                                */
+#define SH_XNPI_ECC_INJ_REG_BYTE0_SHFT           0
+#define SH_XNPI_ECC_INJ_REG_BYTE0_MASK           0x00000000000000ff
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_1SHOT0                                    */
+/*   Description:  1 shot mask data                                     */
+#define SH_XNPI_ECC_INJ_REG_DATA_1SHOT0_SHFT     12
+#define SH_XNPI_ECC_INJ_REG_DATA_1SHOT0_MASK     0x0000000000001000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CONT0                                     */
+/*   Description:  toggle mask data                                     */
+#define SH_XNPI_ECC_INJ_REG_DATA_CONT0_SHFT      13
+#define SH_XNPI_ECC_INJ_REG_DATA_CONT0_MASK      0x0000000000002000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT0                                 */
+/*   Description:  Replace Checkbyte One Shot                           */
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT0_SHFT  14
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT0_MASK  0x0000000000004000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CB_CONT0                                  */
+/*   Description:  Replace Checkbyte Continuous                         */
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_CONT0_SHFT   15
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_CONT0_MASK   0x0000000000008000
+
+/*   SH_XNPI_ECC_INJ_REG_BYTE1                                          */
+/*   Description:  Replacement Checkbyte                                */
+#define SH_XNPI_ECC_INJ_REG_BYTE1_SHFT           16
+#define SH_XNPI_ECC_INJ_REG_BYTE1_MASK           0x0000000000ff0000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_1SHOT1                                    */
+/*   Description:  1 shot mask data                                     */
+#define SH_XNPI_ECC_INJ_REG_DATA_1SHOT1_SHFT     28
+#define SH_XNPI_ECC_INJ_REG_DATA_1SHOT1_MASK     0x0000000010000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CONT1                                     */
+/*   Description:  toggle mask data                                     */
+#define SH_XNPI_ECC_INJ_REG_DATA_CONT1_SHFT      29
+#define SH_XNPI_ECC_INJ_REG_DATA_CONT1_MASK      0x0000000020000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT1                                 */
+/*   Description:  Replace Checkbyte One Shot                           */
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT1_SHFT  30
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT1_MASK  0x0000000040000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CB_CONT1                                  */
+/*   Description:  Replace Checkbyte Continous                          */
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_CONT1_SHFT   31
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_CONT1_MASK   0x0000000080000000
+
+/*   SH_XNPI_ECC_INJ_REG_BYTE2                                          */
+/*   Description:  Replacement Checkbyte                                */
+#define SH_XNPI_ECC_INJ_REG_BYTE2_SHFT           32
+#define SH_XNPI_ECC_INJ_REG_BYTE2_MASK           0x000000ff00000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_1SHOT2                                    */
+/*   Description:  1 shot mask data                                     */
+#define SH_XNPI_ECC_INJ_REG_DATA_1SHOT2_SHFT     44
+#define SH_XNPI_ECC_INJ_REG_DATA_1SHOT2_MASK     0x0000100000000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CONT2                                     */
+/*   Description:  toggle mask data                                     */
+#define SH_XNPI_ECC_INJ_REG_DATA_CONT2_SHFT      45
+#define SH_XNPI_ECC_INJ_REG_DATA_CONT2_MASK      0x0000200000000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT2                                 */
+/*   Description:  Replace Checkbyte OneShot                            */
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT2_SHFT  46
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT2_MASK  0x0000400000000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CB_CONT2                                  */
+/*   Description:  Replace Checkbyte Continous                          */
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_CONT2_SHFT   47
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_CONT2_MASK   0x0000800000000000
+
+/*   SH_XNPI_ECC_INJ_REG_BYTE3                                          */
+/*   Description:  Replacement Checkbyte                                */
+#define SH_XNPI_ECC_INJ_REG_BYTE3_SHFT           48
+#define SH_XNPI_ECC_INJ_REG_BYTE3_MASK           0x00ff000000000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_1SHOT3                                    */
+/*   Description:  1 shot mask data                                     */
+#define SH_XNPI_ECC_INJ_REG_DATA_1SHOT3_SHFT     60
+#define SH_XNPI_ECC_INJ_REG_DATA_1SHOT3_MASK     0x1000000000000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CONT3                                     */
+/*   Description:  toggle mask data                                     */
+#define SH_XNPI_ECC_INJ_REG_DATA_CONT3_SHFT      61
+#define SH_XNPI_ECC_INJ_REG_DATA_CONT3_MASK      0x2000000000000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT3                                 */
+/*   Description:  Replace Checkbyte One-Shot                           */
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT3_SHFT  62
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_1SHOT3_MASK  0x4000000000000000
+
+/*   SH_XNPI_ECC_INJ_REG_DATA_CB_CONT3                                  */
+/*   Description:  Replace Checkbyte Continous                          */
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_CONT3_SHFT   63
+#define SH_XNPI_ECC_INJ_REG_DATA_CB_CONT3_MASK   0x8000000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_ECC0_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#define SH_XNPI_ECC0_INJ_MASK_REG                0x0000000150032008
+#define SH_XNPI_ECC0_INJ_MASK_REG_MASK           0xffffffffffffffff
+#define SH_XNPI_ECC0_INJ_MASK_REG_INIT           0x0000000000000000
+
+/*   SH_XNPI_ECC0_INJ_MASK_REG_MASK_ECC0                                */
+/*   Description:  Replacement Data                                     */
+#define SH_XNPI_ECC0_INJ_MASK_REG_MASK_ECC0_SHFT 0
+#define SH_XNPI_ECC0_INJ_MASK_REG_MASK_ECC0_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_ECC1_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#define SH_XNPI_ECC1_INJ_MASK_REG                0x0000000150032010
+#define SH_XNPI_ECC1_INJ_MASK_REG_MASK           0xffffffffffffffff
+#define SH_XNPI_ECC1_INJ_MASK_REG_INIT           0x0000000000000000
+
+/*   SH_XNPI_ECC1_INJ_MASK_REG_MASK_ECC1                                */
+/*   Description:  Replacement Data                                     */
+#define SH_XNPI_ECC1_INJ_MASK_REG_MASK_ECC1_SHFT 0
+#define SH_XNPI_ECC1_INJ_MASK_REG_MASK_ECC1_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_ECC2_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#define SH_XNPI_ECC2_INJ_MASK_REG                0x0000000150032018
+#define SH_XNPI_ECC2_INJ_MASK_REG_MASK           0xffffffffffffffff
+#define SH_XNPI_ECC2_INJ_MASK_REG_INIT           0x0000000000000000
+
+/*   SH_XNPI_ECC2_INJ_MASK_REG_MASK_ECC2                                */
+/*   Description:  Replacement Data                                     */
+#define SH_XNPI_ECC2_INJ_MASK_REG_MASK_ECC2_SHFT 0
+#define SH_XNPI_ECC2_INJ_MASK_REG_MASK_ECC2_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_ECC3_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#define SH_XNPI_ECC3_INJ_MASK_REG                0x0000000150032020
+#define SH_XNPI_ECC3_INJ_MASK_REG_MASK           0xffffffffffffffff
+#define SH_XNPI_ECC3_INJ_MASK_REG_INIT           0x0000000000000000
+
+/*   SH_XNPI_ECC3_INJ_MASK_REG_MASK_ECC3                                */
+/*   Description:  Replacement Data                                     */
+#define SH_XNPI_ECC3_INJ_MASK_REG_MASK_ECC3_SHFT 0
+#define SH_XNPI_ECC3_INJ_MASK_REG_MASK_ECC3_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_XNMD_ECC_INJ_REG"                    */
+/* ==================================================================== */
+
+#define SH_XNMD_ECC_INJ_REG                      0x0000000150032030
+#define SH_XNMD_ECC_INJ_REG_MASK                 0xf0fff0fff0fff0ff
+#define SH_XNMD_ECC_INJ_REG_INIT                 0x0000000000000000
+
+/*   SH_XNMD_ECC_INJ_REG_BYTE0                                          */
+/*   Description:  Replacement Checkbyte                                */
+#define SH_XNMD_ECC_INJ_REG_BYTE0_SHFT           0
+#define SH_XNMD_ECC_INJ_REG_BYTE0_MASK           0x00000000000000ff
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_1SHOT0                                    */
+/*   Description:  1 shot mask data                                     */
+#define SH_XNMD_ECC_INJ_REG_DATA_1SHOT0_SHFT     12
+#define SH_XNMD_ECC_INJ_REG_DATA_1SHOT0_MASK     0x0000000000001000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CONT0                                     */
+/*   Description:  toggle mask data                                     */
+#define SH_XNMD_ECC_INJ_REG_DATA_CONT0_SHFT      13
+#define SH_XNMD_ECC_INJ_REG_DATA_CONT0_MASK      0x0000000000002000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT0                                 */
+/*   Description:  Replace Checkbyte One Shot                           */
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT0_SHFT  14
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT0_MASK  0x0000000000004000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CB_CONT0                                  */
+/*   Description:  Replace Checkbyte Continuous                         */
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_CONT0_SHFT   15
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_CONT0_MASK   0x0000000000008000
+
+/*   SH_XNMD_ECC_INJ_REG_BYTE1                                          */
+/*   Description:  Replacement Checkbyte                                */
+#define SH_XNMD_ECC_INJ_REG_BYTE1_SHFT           16
+#define SH_XNMD_ECC_INJ_REG_BYTE1_MASK           0x0000000000ff0000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_1SHOT1                                    */
+/*   Description:  1 shot mask data                                     */
+#define SH_XNMD_ECC_INJ_REG_DATA_1SHOT1_SHFT     28
+#define SH_XNMD_ECC_INJ_REG_DATA_1SHOT1_MASK     0x0000000010000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CONT1                                     */
+/*   Description:  toggle mask data                                     */
+#define SH_XNMD_ECC_INJ_REG_DATA_CONT1_SHFT      29
+#define SH_XNMD_ECC_INJ_REG_DATA_CONT1_MASK      0x0000000020000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT1                                 */
+/*   Description:  Replace Checkbyte One Shot                           */
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT1_SHFT  30
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT1_MASK  0x0000000040000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CB_CONT1                                  */
+/*   Description:  Replace Checkbyte Continous                          */
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_CONT1_SHFT   31
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_CONT1_MASK   0x0000000080000000
+
+/*   SH_XNMD_ECC_INJ_REG_BYTE2                                          */
+/*   Description:  Replacement Checkbyte                                */
+#define SH_XNMD_ECC_INJ_REG_BYTE2_SHFT           32
+#define SH_XNMD_ECC_INJ_REG_BYTE2_MASK           0x000000ff00000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_1SHOT2                                    */
+/*   Description:  1 shot mask data                                     */
+#define SH_XNMD_ECC_INJ_REG_DATA_1SHOT2_SHFT     44
+#define SH_XNMD_ECC_INJ_REG_DATA_1SHOT2_MASK     0x0000100000000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CONT2                                     */
+/*   Description:  toggle mask data                                     */
+#define SH_XNMD_ECC_INJ_REG_DATA_CONT2_SHFT      45
+#define SH_XNMD_ECC_INJ_REG_DATA_CONT2_MASK      0x0000200000000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT2                                 */
+/*   Description:  Replace Checkbyte OneShot                            */
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT2_SHFT  46
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT2_MASK  0x0000400000000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CB_CONT2                                  */
+/*   Description:  Replace Checkbyte Continous                          */
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_CONT2_SHFT   47
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_CONT2_MASK   0x0000800000000000
+
+/*   SH_XNMD_ECC_INJ_REG_BYTE3                                          */
+/*   Description:  Replacement Checkbyte                                */
+#define SH_XNMD_ECC_INJ_REG_BYTE3_SHFT           48
+#define SH_XNMD_ECC_INJ_REG_BYTE3_MASK           0x00ff000000000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_1SHOT3                                    */
+/*   Description:  1 shot mask data                                     */
+#define SH_XNMD_ECC_INJ_REG_DATA_1SHOT3_SHFT     60
+#define SH_XNMD_ECC_INJ_REG_DATA_1SHOT3_MASK     0x1000000000000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CONT3                                     */
+/*   Description:  toggle mask data                                     */
+#define SH_XNMD_ECC_INJ_REG_DATA_CONT3_SHFT      61
+#define SH_XNMD_ECC_INJ_REG_DATA_CONT3_MASK      0x2000000000000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT3                                 */
+/*   Description:  Replace Checkbyte One-Shot                           */
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT3_SHFT  62
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_1SHOT3_MASK  0x4000000000000000
+
+/*   SH_XNMD_ECC_INJ_REG_DATA_CB_CONT3                                  */
+/*   Description:  Replace Checkbyte Continous                          */
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_CONT3_SHFT   63
+#define SH_XNMD_ECC_INJ_REG_DATA_CB_CONT3_MASK   0x8000000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_ECC0_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#define SH_XNMD_ECC0_INJ_MASK_REG                0x0000000150032038
+#define SH_XNMD_ECC0_INJ_MASK_REG_MASK           0xffffffffffffffff
+#define SH_XNMD_ECC0_INJ_MASK_REG_INIT           0x0000000000000000
+
+/*   SH_XNMD_ECC0_INJ_MASK_REG_MASK_ECC0                                */
+/*   Description:  Replacement Data                                     */
+#define SH_XNMD_ECC0_INJ_MASK_REG_MASK_ECC0_SHFT 0
+#define SH_XNMD_ECC0_INJ_MASK_REG_MASK_ECC0_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_ECC1_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#define SH_XNMD_ECC1_INJ_MASK_REG                0x0000000150032040
+#define SH_XNMD_ECC1_INJ_MASK_REG_MASK           0xffffffffffffffff
+#define SH_XNMD_ECC1_INJ_MASK_REG_INIT           0x0000000000000000
+
+/*   SH_XNMD_ECC1_INJ_MASK_REG_MASK_ECC1                                */
+/*   Description:  Replacement Data                                     */
+#define SH_XNMD_ECC1_INJ_MASK_REG_MASK_ECC1_SHFT 0
+#define SH_XNMD_ECC1_INJ_MASK_REG_MASK_ECC1_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_ECC2_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#define SH_XNMD_ECC2_INJ_MASK_REG                0x0000000150032048
+#define SH_XNMD_ECC2_INJ_MASK_REG_MASK           0xffffffffffffffff
+#define SH_XNMD_ECC2_INJ_MASK_REG_INIT           0x0000000000000000
+
+/*   SH_XNMD_ECC2_INJ_MASK_REG_MASK_ECC2                                */
+/*   Description:  Replacement Data                                     */
+#define SH_XNMD_ECC2_INJ_MASK_REG_MASK_ECC2_SHFT 0
+#define SH_XNMD_ECC2_INJ_MASK_REG_MASK_ECC2_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_ECC3_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#define SH_XNMD_ECC3_INJ_MASK_REG                0x0000000150032050
+#define SH_XNMD_ECC3_INJ_MASK_REG_MASK           0xffffffffffffffff
+#define SH_XNMD_ECC3_INJ_MASK_REG_INIT           0x0000000000000000
+
+/*   SH_XNMD_ECC3_INJ_MASK_REG_MASK_ECC3                                */
+/*   Description:  Replacement Data                                     */
+#define SH_XNMD_ECC3_INJ_MASK_REG_MASK_ECC3_SHFT 0
+#define SH_XNMD_ECC3_INJ_MASK_REG_MASK_ECC3_MASK 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_XNMD_ECC_ERR_REPORT"                   */
+/* ==================================================================== */
+
+#define SH_XNMD_ECC_ERR_REPORT                   0x0000000150032058
+#define SH_XNMD_ECC_ERR_REPORT_MASK              0x0001000100010001
+#define SH_XNMD_ECC_ERR_REPORT_INIT              0x0000000000000000
+
+/*   SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE0                                */
+/*   Description:  Disable Error Correction                             */
+#define SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE0_SHFT 0
+#define SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE0_MASK 0x0000000000000001
+
+/*   SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE1                                */
+/*   Description:  Disable Error Correction                             */
+#define SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE1_SHFT 16
+#define SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE1_MASK 0x0000000000010000
+
+/*   SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE2                                */
+/*   Description:  Disable Error Correction                             */
+#define SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE2_SHFT 32
+#define SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE2_MASK 0x0000000100000000
+
+/*   SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE3                                */
+/*   Description:  Disable Error Correction                             */
+#define SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE3_SHFT 48
+#define SH_XNMD_ECC_ERR_REPORT_ECC_DISABLE3_MASK 0x0001000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_ERROR_SUMMARY_1"                   */
+/*                       ni0  Error Summary Bits                        */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_SUMMARY_1                   0x0000000150040500
+#define SH_NI0_ERROR_SUMMARY_1_MASK              0xffffffffffffffff
+#define SH_NI0_ERROR_SUMMARY_1_INIT              0xffffffffffffffff
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT0                      */
+/*   Description:  Fifo 02 debit0 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT0_SHFT 0
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT2                      */
+/*   Description:  Fifo 02 debit2 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT2_SHFT 1
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT0                      */
+/*   Description:  Fifo 13 debit0 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT0_SHFT 2
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT2                      */
+/*   Description:  Fifo 13 debit2 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT2_SHFT 3
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_POP                     */
+/*   Description:  Fifo 02 vc0 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_POP                     */
+/*   Description:  Fifo 02 vc2 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_POP                     */
+/*   Description:  Fifo 13 vc1 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_POP                     */
+/*   Description:  Fifo 13 vc3 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_PUSH                    */
+/*   Description:  Fifo 02 vc0 push overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_PUSH                    */
+/*   Description:  Fifo 02 vc2 push overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_PUSH                    */
+/*   Description:  Fifo 13 vc1 push overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_PUSH                    */
+/*   Description:  Fifo 13 vc3 push overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_CREDIT                  */
+/*   Description:  Fifo 02 vc0 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_CREDIT                  */
+/*   Description:  Fifo 02 vc2 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC0_CREDIT                  */
+/*   Description:  Fifo 13 vc0 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC2_CREDIT                  */
+/*   Description:  Fifo 13 vc2 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW0_VC0_CREDIT                        */
+/*   Description:  VC0 credit overflow 0                                */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW1_VC0_CREDIT                        */
+/*   Description:  VC0 credit overflow 1                                */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW2_VC0_CREDIT                        */
+/*   Description:  VC0 credit overflow 2                                */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW0_VC2_CREDIT                        */
+/*   Description:  VC2 credit overflow 0                                */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW1_VC2_CREDIT                        */
+/*   Description:  VC2 credit overflow 1                                */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW2_VC2_CREDIT                        */
+/*   Description:  VC2 credit overflow 2                                */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT0                     */
+/*   Description:  PI Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT0_SHFT 22
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT0_MASK 0x0000000000400000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT2                     */
+/*   Description:  PI Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT2_SHFT 23
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT2_MASK 0x0000000000800000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT0                   */
+/*   Description:  IILB Fifo debit0 overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT0_SHFT 24
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT0_MASK 0x0000000001000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT2                   */
+/*   Description:  IILB Fifo debit2 overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT2_SHFT 25
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT2_MASK 0x0000000002000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT0                     */
+/*   Description:  MD Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT0_SHFT 26
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT0_MASK 0x0000000004000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT2                     */
+/*   Description:  MD Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT2_SHFT 27
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT2_MASK 0x0000000008000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT0                     */
+/*   Description:  NI Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT0_SHFT 28
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT0_MASK 0x0000000010000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT1                     */
+/*   Description:  NI Fifo debit1 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT1_SHFT 29
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT1_MASK 0x0000000020000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT2                     */
+/*   Description:  NI Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT2_SHFT 30
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT2_MASK 0x0000000040000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT3                     */
+/*   Description:  NI Fifo debit3 overflow                              */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT3_SHFT 31
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT3_MASK 0x0000000080000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_POP                    */
+/*   Description:  PI Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_POP                    */
+/*   Description:  PI Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_POP                  */
+/*   Description:  IILB Fifo vc0 pop overflow                           */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_POP                  */
+/*   Description:  IILB Fifo vc2 pop overflow                           */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_POP                    */
+/*   Description:  MD Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_POP                    */
+/*   Description:  MD Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_POP                    */
+/*   Description:  NI Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_POP                    */
+/*   Description:  NI Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_PUSH                   */
+/*   Description:  PI Fifo vc0 push overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_PUSH                   */
+/*   Description:  PI Fifo vc2 push overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_PUSH                 */
+/*   Description:  IILB Fifo vc0 push overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_PUSH                 */
+/*   Description:  IILB Fifo vc2 push overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_PUSH                   */
+/*   Description:  MD Fifo vc0 push overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_PUSH                   */
+/*   Description:  MD Fifo vc2 push overflow                            */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_CREDIT                 */
+/*   Description:  PI Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_CREDIT                 */
+/*   Description:  PI Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_CREDIT               */
+/*   Description:  IILB Fifo vc0 credit overflow                        */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_CREDIT               */
+/*   Description:  IILB Fifo vc2 credit overflow                        */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_CREDIT                 */
+/*   Description:  MD Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_CREDIT                 */
+/*   Description:  MD Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_CREDIT                 */
+/*   Description:  NI Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC1_CREDIT                 */
+/*   Description:  NI Fifo vc1 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_CREDIT                 */
+/*   Description:  NI Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC3_CREDIT                 */
+/*   Description:  NI Fifo vc3 credit overflow                          */
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI0_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC0                     */
+/*   Description:  Fifo02 vc0 tail timeout                              */
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC0_SHFT 56
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC0_MASK 0x0100000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC2                     */
+/*   Description:  Fifo02 vc2 tail timeout                              */
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC2_SHFT 57
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC2_MASK 0x0200000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC1                     */
+/*   Description:  Fifo13 vc1 tail timeout                              */
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC1_SHFT 58
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC1_MASK 0x0400000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC3                     */
+/*   Description:  Fifo13 vc3 tail timeout                              */
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC3_SHFT 59
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC3_MASK 0x0800000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC0                         */
+/*   Description:  NI vc0 tail timeout                                  */
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC0_SHFT 60
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC0_MASK 0x1000000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC1                         */
+/*   Description:  NI vc1 tail timeout                                  */
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC1_SHFT 61
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC1_MASK 0x2000000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC2                         */
+/*   Description:  NI vc2 tail timeout                                  */
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC2_SHFT 62
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC2_MASK 0x4000000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC3                         */
+/*   Description:  NI vc3 tail timeout                                  */
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC3_SHFT 63
+#define SH_NI0_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC3_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_NI0_ERROR_SUMMARY_1_ALIAS"                */
+/*                     ni0 Error Summary Bits Alias                     */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_SUMMARY_1_ALIAS             0x0000000150040508
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_ERROR_SUMMARY_2"                   */
+/*                       ni0  Error Summary Bits                        */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_SUMMARY_2                   0x0000000150040510
+#define SH_NI0_ERROR_SUMMARY_2_MASK              0x7fffffff003fffff
+#define SH_NI0_ERROR_SUMMARY_2_INIT              0x7fffffff003fffff
+
+/*   SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCNI                                */
+/*   Description:  Illegal VC NI                                        */
+#define SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCNI_SHFT 0
+#define SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCNI_MASK 0x0000000000000001
+
+/*   SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCPI                                */
+/*   Description:  Illegal VC PI                                        */
+#define SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCPI_SHFT 1
+#define SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCPI_MASK 0x0000000000000002
+
+/*   SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCMD                                */
+/*   Description:  Illegal VC MD                                        */
+#define SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCMD_SHFT 2
+#define SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCMD_MASK 0x0000000000000004
+
+/*   SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCIILB                              */
+/*   Description:  Illegal VC IILB                                      */
+#define SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCIILB_SHFT 3
+#define SH_NI0_ERROR_SUMMARY_2_ILLEGAL_VCIILB_MASK 0x0000000000000008
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_POP                    */
+/*   Description:  Fifo 02 vc0 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_POP                    */
+/*   Description:  Fifo 02 vc2 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_POP                    */
+/*   Description:  Fifo 13 vc1 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_POP                    */
+/*   Description:  Fifo 13 vc3 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_PUSH                   */
+/*   Description:  Fifo 02 vc0 push underflow                           */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_PUSH                   */
+/*   Description:  Fifo 02 vc2 push underflow                           */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_PUSH                   */
+/*   Description:  Fifo 13 vc1 push underflow                           */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_PUSH                   */
+/*   Description:  Fifo 13 vc3 push underflow                           */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_CREDIT                 */
+/*   Description:  Fifo 02 vc0 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_CREDIT                 */
+/*   Description:  Fifo 02 vc2 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC0_CREDIT                 */
+/*   Description:  Fifo 13 vc0 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC2_CREDIT                 */
+/*   Description:  Fifo 13 vc2 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW0_VC0_CREDIT                       */
+/*   Description:  VC0 credit underflow 0                               */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW1_VC0_CREDIT                       */
+/*   Description:  VC0 credit underflow 1                               */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW2_VC0_CREDIT                       */
+/*   Description:  VC0 credit underflow 2                               */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW0_VC2_CREDIT                       */
+/*   Description:  VC2 credit underflow 0                               */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW1_VC2_CREDIT                       */
+/*   Description:  VC2 credit underflow 1                               */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW2_VC2_CREDIT                       */
+/*   Description:  VC2 credit underflow 2                               */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_POP                   */
+/*   Description:  PI Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_POP                   */
+/*   Description:  PI Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_POP                 */
+/*   Description:  IILB Fifo vc0 pop underflow                          */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_POP                 */
+/*   Description:  IILB Fifo vc2 pop underflow                          */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_POP                   */
+/*   Description:  MD Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_POP                   */
+/*   Description:  MD Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_POP                   */
+/*   Description:  NI Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_POP                   */
+/*   Description:  NI Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_PUSH                  */
+/*   Description:  PI Fifo vc0 push underflow                           */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_PUSH                  */
+/*   Description:  PI Fifo vc2 push underflow                           */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_PUSH                */
+/*   Description:  IILB Fifo vc0 push underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_PUSH                */
+/*   Description:  IILB Fifo vc2 push underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_PUSH                  */
+/*   Description:  MD Fifo vc0 push underflow                           */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_PUSH                  */
+/*   Description:  MD Fifo vc2 push underflow                           */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_CREDIT                */
+/*   Description:  PI Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_CREDIT                */
+/*   Description:  PI Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT              */
+/*   Description:  IILB Fifo vc0 credit underflow                       */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT              */
+/*   Description:  IILB Fifo vc2 credit underflow                       */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_CREDIT                */
+/*   Description:  MD Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_CREDIT                */
+/*   Description:  MD Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_CREDIT                */
+/*   Description:  NI Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC1_CREDIT                */
+/*   Description:  NI Fifo vc1 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_CREDIT                */
+/*   Description:  NI Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC3_CREDIT                */
+/*   Description:  NI Fifo vc3 credit underflow                         */
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI0_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC0                            */
+/*   Description:  llp deadlock vc0                                     */
+#define SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC0_SHFT 56
+#define SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC0_MASK 0x0100000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC1                            */
+/*   Description:  llp deadlock vc1                                     */
+#define SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC1_SHFT 57
+#define SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC1_MASK 0x0200000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC2                            */
+/*   Description:  llp deadlock vc2                                     */
+#define SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC2_SHFT 58
+#define SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC2_MASK 0x0400000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC3                            */
+/*   Description:  llp deadlock vc3                                     */
+#define SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC3_SHFT 59
+#define SH_NI0_ERROR_SUMMARY_2_LLP_DEADLOCK_VC3_MASK 0x0800000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_CHIPLET_NOMATCH                             */
+/*   Description:  chiplet nomatch                                      */
+#define SH_NI0_ERROR_SUMMARY_2_CHIPLET_NOMATCH_SHFT 60
+#define SH_NI0_ERROR_SUMMARY_2_CHIPLET_NOMATCH_MASK 0x1000000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_LUT_READ_ERROR                              */
+/*   Description:  LUT Read Error                                       */
+#define SH_NI0_ERROR_SUMMARY_2_LUT_READ_ERROR_SHFT 61
+#define SH_NI0_ERROR_SUMMARY_2_LUT_READ_ERROR_MASK 0x2000000000000000
+
+/*   SH_NI0_ERROR_SUMMARY_2_RETRY_TIMEOUT_ERROR                         */
+/*   Description:  Retry Timeout Error                                  */
+#define SH_NI0_ERROR_SUMMARY_2_RETRY_TIMEOUT_ERROR_SHFT 62
+#define SH_NI0_ERROR_SUMMARY_2_RETRY_TIMEOUT_ERROR_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_NI0_ERROR_SUMMARY_2_ALIAS"                */
+/*                     ni0 Error Summary Bits Alias                     */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_SUMMARY_2_ALIAS             0x0000000150040518
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_ERROR_OVERFLOW_1"                  */
+/*                       ni0  Error Overflow Bits                       */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_OVERFLOW_1                  0x0000000150040520
+#define SH_NI0_ERROR_OVERFLOW_1_MASK             0xffffffffffffffff
+#define SH_NI0_ERROR_OVERFLOW_1_INIT             0xffffffffffffffff
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT0                     */
+/*   Description:  Fifo 02 debit0 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT0_SHFT 0
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT2                     */
+/*   Description:  Fifo 02 debit2 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT2_SHFT 1
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT0                     */
+/*   Description:  Fifo 13 debit0 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT0_SHFT 2
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT2                     */
+/*   Description:  Fifo 13 debit2 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT2_SHFT 3
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_POP                    */
+/*   Description:  Fifo 02 vc0 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_POP                    */
+/*   Description:  Fifo 02 vc2 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_POP                    */
+/*   Description:  Fifo 13 vc1 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_POP                    */
+/*   Description:  Fifo 13 vc3 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_PUSH                   */
+/*   Description:  Fifo 02 vc0 push overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_PUSH                   */
+/*   Description:  Fifo 02 vc2 push overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_PUSH                   */
+/*   Description:  Fifo 13 vc1 push overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_PUSH                   */
+/*   Description:  Fifo 13 vc3 push overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_CREDIT                 */
+/*   Description:  Fifo 02 vc0 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_CREDIT                 */
+/*   Description:  Fifo 02 vc2 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC0_CREDIT                 */
+/*   Description:  Fifo 13 vc0 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC2_CREDIT                 */
+/*   Description:  Fifo 13 vc2 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW0_VC0_CREDIT                       */
+/*   Description:  VC0 credit overflow 0                                */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW1_VC0_CREDIT                       */
+/*   Description:  VC0 credit overflow 1                                */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW2_VC0_CREDIT                       */
+/*   Description:  VC0 credit overflow 2                                */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW0_VC2_CREDIT                       */
+/*   Description:  VC2 credit overflow 0                                */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW1_VC2_CREDIT                       */
+/*   Description:  VC2 credit overflow 1                                */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW2_VC2_CREDIT                       */
+/*   Description:  VC2 credit overflow 2                                */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT0                    */
+/*   Description:  PI Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT0_SHFT 22
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT0_MASK 0x0000000000400000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT2                    */
+/*   Description:  PI Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT2_SHFT 23
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT2_MASK 0x0000000000800000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT0                  */
+/*   Description:  IILB Fifo debit0 overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT0_SHFT 24
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT0_MASK 0x0000000001000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT2                  */
+/*   Description:  IILB Fifo debit2 overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT2_SHFT 25
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT2_MASK 0x0000000002000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT0                    */
+/*   Description:  MD Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT0_SHFT 26
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT0_MASK 0x0000000004000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT2                    */
+/*   Description:  MD Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT2_SHFT 27
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT2_MASK 0x0000000008000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT0                    */
+/*   Description:  NI Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT0_SHFT 28
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT0_MASK 0x0000000010000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT1                    */
+/*   Description:  NI Fifo debit1 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT1_SHFT 29
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT1_MASK 0x0000000020000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT2                    */
+/*   Description:  NI Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT2_SHFT 30
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT2_MASK 0x0000000040000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT3                    */
+/*   Description:  NI Fifo debit3 overflow                              */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT3_SHFT 31
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT3_MASK 0x0000000080000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_POP                   */
+/*   Description:  PI Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_POP                   */
+/*   Description:  PI Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_POP                 */
+/*   Description:  IILB Fifo vc0 pop overflow                           */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_POP                 */
+/*   Description:  IILB Fifo vc2 pop overflow                           */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_POP                   */
+/*   Description:  MD Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_POP                   */
+/*   Description:  MD Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_POP                   */
+/*   Description:  NI Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_POP                   */
+/*   Description:  NI Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_PUSH                  */
+/*   Description:  PI Fifo vc0 push overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_PUSH                  */
+/*   Description:  PI Fifo vc2 push overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_PUSH                */
+/*   Description:  IILB Fifo vc0 push overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_PUSH                */
+/*   Description:  IILB Fifo vc2 push overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_PUSH                  */
+/*   Description:  MD Fifo vc0 push overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_PUSH                  */
+/*   Description:  MD Fifo vc2 push overflow                            */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_CREDIT                */
+/*   Description:  PI Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_CREDIT                */
+/*   Description:  PI Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_CREDIT              */
+/*   Description:  IILB Fifo vc0 credit overflow                        */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_CREDIT              */
+/*   Description:  IILB Fifo vc2 credit overflow                        */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_CREDIT                */
+/*   Description:  MD Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_CREDIT                */
+/*   Description:  MD Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_CREDIT                */
+/*   Description:  NI Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC1_CREDIT                */
+/*   Description:  NI Fifo vc1 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_CREDIT                */
+/*   Description:  NI Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC3_CREDIT                */
+/*   Description:  NI Fifo vc3 credit overflow                          */
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI0_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC0                    */
+/*   Description:  Fifo02 vc0 tail timeout                              */
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC0_SHFT 56
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC0_MASK 0x0100000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC2                    */
+/*   Description:  Fifo02 vc2 tail timeout                              */
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC2_SHFT 57
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC2_MASK 0x0200000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC1                    */
+/*   Description:  Fifo13 vc1 tail timeout                              */
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC1_SHFT 58
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC1_MASK 0x0400000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC3                    */
+/*   Description:  Fifo13 vc3 tail timeout                              */
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC3_SHFT 59
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC3_MASK 0x0800000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC0                        */
+/*   Description:  NI vc0 tail timeout                                  */
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC0_SHFT 60
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC0_MASK 0x1000000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC1                        */
+/*   Description:  NI vc1 tail timeout                                  */
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC1_SHFT 61
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC1_MASK 0x2000000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC2                        */
+/*   Description:  NI vc2 tail timeout                                  */
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC2_SHFT 62
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC2_MASK 0x4000000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC3                        */
+/*   Description:  NI vc3 tail timeout                                  */
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC3_SHFT 63
+#define SH_NI0_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC3_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_NI0_ERROR_OVERFLOW_1_ALIAS"               */
+/*                    ni0 Error Overflow Bits Alias                     */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_OVERFLOW_1_ALIAS            0x0000000150040528
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_ERROR_OVERFLOW_2"                  */
+/*                       ni0  Error Overflow Bits                       */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_OVERFLOW_2                  0x0000000150040530
+#define SH_NI0_ERROR_OVERFLOW_2_MASK             0x7fffffff003fffff
+#define SH_NI0_ERROR_OVERFLOW_2_INIT             0x7fffffff003fffff
+
+/*   SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCNI                               */
+/*   Description:  Illegal VC NI                                        */
+#define SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCNI_SHFT 0
+#define SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCNI_MASK 0x0000000000000001
+
+/*   SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCPI                               */
+/*   Description:  Illegal VC PI                                        */
+#define SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCPI_SHFT 1
+#define SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCPI_MASK 0x0000000000000002
+
+/*   SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCMD                               */
+/*   Description:  Illegal VC MD                                        */
+#define SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCMD_SHFT 2
+#define SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCMD_MASK 0x0000000000000004
+
+/*   SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCIILB                             */
+/*   Description:  Illegal VC IILB                                      */
+#define SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCIILB_SHFT 3
+#define SH_NI0_ERROR_OVERFLOW_2_ILLEGAL_VCIILB_MASK 0x0000000000000008
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_POP                   */
+/*   Description:  Fifo 02 vc0 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_POP                   */
+/*   Description:  Fifo 02 vc2 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_POP                   */
+/*   Description:  Fifo 13 vc1 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_POP                   */
+/*   Description:  Fifo 13 vc3 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_PUSH                  */
+/*   Description:  Fifo 02 vc0 push underflow                           */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_PUSH                  */
+/*   Description:  Fifo 02 vc2 push underflow                           */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_PUSH                  */
+/*   Description:  Fifo 13 vc1 push underflow                           */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_PUSH                  */
+/*   Description:  Fifo 13 vc3 push underflow                           */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_CREDIT                */
+/*   Description:  Fifo 02 vc0 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_CREDIT                */
+/*   Description:  Fifo 02 vc2 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC0_CREDIT                */
+/*   Description:  Fifo 13 vc0 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC2_CREDIT                */
+/*   Description:  Fifo 13 vc2 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW0_VC0_CREDIT                      */
+/*   Description:  VC0 credit underflow 0                               */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW1_VC0_CREDIT                      */
+/*   Description:  VC0 credit underflow 1                               */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW2_VC0_CREDIT                      */
+/*   Description:  VC0 credit underflow 2                               */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW0_VC2_CREDIT                      */
+/*   Description:  VC2 credit underflow 0                               */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW1_VC2_CREDIT                      */
+/*   Description:  VC2 credit underflow 1                               */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW2_VC2_CREDIT                      */
+/*   Description:  VC2 credit underflow 2                               */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_POP                  */
+/*   Description:  PI Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_POP                  */
+/*   Description:  PI Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_POP                */
+/*   Description:  IILB Fifo vc0 pop underflow                          */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_POP                */
+/*   Description:  IILB Fifo vc2 pop underflow                          */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_POP                  */
+/*   Description:  MD Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_POP                  */
+/*   Description:  MD Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_POP                  */
+/*   Description:  NI Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_POP                  */
+/*   Description:  NI Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_PUSH                 */
+/*   Description:  PI Fifo vc0 push underflow                           */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_PUSH                 */
+/*   Description:  PI Fifo vc2 push underflow                           */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_PUSH               */
+/*   Description:  IILB Fifo vc0 push underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_PUSH               */
+/*   Description:  IILB Fifo vc2 push underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_PUSH                 */
+/*   Description:  MD Fifo vc0 push underflow                           */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_PUSH                 */
+/*   Description:  MD Fifo vc2 push underflow                           */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_CREDIT               */
+/*   Description:  PI Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_CREDIT               */
+/*   Description:  PI Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT             */
+/*   Description:  IILB Fifo vc0 credit underflow                       */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT             */
+/*   Description:  IILB Fifo vc2 credit underflow                       */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_CREDIT               */
+/*   Description:  MD Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_CREDIT               */
+/*   Description:  MD Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_CREDIT               */
+/*   Description:  NI Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC1_CREDIT               */
+/*   Description:  NI Fifo vc1 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_CREDIT               */
+/*   Description:  NI Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC3_CREDIT               */
+/*   Description:  NI Fifo vc3 credit underflow                         */
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI0_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC0                           */
+/*   Description:  llp deadlock vc0                                     */
+#define SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC0_SHFT 56
+#define SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC0_MASK 0x0100000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC1                           */
+/*   Description:  llp deadlock vc1                                     */
+#define SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC1_SHFT 57
+#define SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC1_MASK 0x0200000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC2                           */
+/*   Description:  llp deadlock vc2                                     */
+#define SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC2_SHFT 58
+#define SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC2_MASK 0x0400000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC3                           */
+/*   Description:  llp deadlock vc3                                     */
+#define SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC3_SHFT 59
+#define SH_NI0_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC3_MASK 0x0800000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_CHIPLET_NOMATCH                            */
+/*   Description:  chiplet nomatch                                      */
+#define SH_NI0_ERROR_OVERFLOW_2_CHIPLET_NOMATCH_SHFT 60
+#define SH_NI0_ERROR_OVERFLOW_2_CHIPLET_NOMATCH_MASK 0x1000000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_LUT_READ_ERROR                             */
+/*   Description:  LUT Read Error                                       */
+#define SH_NI0_ERROR_OVERFLOW_2_LUT_READ_ERROR_SHFT 61
+#define SH_NI0_ERROR_OVERFLOW_2_LUT_READ_ERROR_MASK 0x2000000000000000
+
+/*   SH_NI0_ERROR_OVERFLOW_2_RETRY_TIMEOUT_ERROR                        */
+/*   Description:  Retry Timeout Error                                  */
+#define SH_NI0_ERROR_OVERFLOW_2_RETRY_TIMEOUT_ERROR_SHFT 62
+#define SH_NI0_ERROR_OVERFLOW_2_RETRY_TIMEOUT_ERROR_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_NI0_ERROR_OVERFLOW_2_ALIAS"               */
+/*                    ni0 Error Overflow Bits Alias                     */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_OVERFLOW_2_ALIAS            0x0000000150040538
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_ERROR_MASK_1"                    */
+/*                         ni0  Error Mask Bits                         */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_MASK_1                      0x0000000150040540
+#define SH_NI0_ERROR_MASK_1_MASK                 0xffffffffffffffff
+#define SH_NI0_ERROR_MASK_1_INIT                 0xffffffffffffffff
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT0                         */
+/*   Description:  Fifo 02 debit0 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT0_SHFT 0
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT2                         */
+/*   Description:  Fifo 02 debit2 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT2_SHFT 1
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT0                         */
+/*   Description:  Fifo 13 debit0 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT0_SHFT 2
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT2                         */
+/*   Description:  Fifo 13 debit2 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT2_SHFT 3
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_POP                        */
+/*   Description:  Fifo 02 vc0 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_POP                        */
+/*   Description:  Fifo 02 vc2 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_POP                        */
+/*   Description:  Fifo 13 vc1 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_POP                        */
+/*   Description:  Fifo 13 vc3 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_PUSH                       */
+/*   Description:  Fifo 02 vc0 push overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_PUSH                       */
+/*   Description:  Fifo 02 vc2 push overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_PUSH                       */
+/*   Description:  Fifo 13 vc1 push overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_PUSH                       */
+/*   Description:  Fifo 13 vc3 push overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_CREDIT                     */
+/*   Description:  Fifo 02 vc0 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_CREDIT                     */
+/*   Description:  Fifo 02 vc2 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC0_CREDIT                     */
+/*   Description:  Fifo 13 vc0 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC2_CREDIT                     */
+/*   Description:  Fifo 13 vc2 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW0_VC0_CREDIT                           */
+/*   Description:  VC0 credit overflow 0                                */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI0_ERROR_MASK_1_OVERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW1_VC0_CREDIT                           */
+/*   Description:  VC0 credit overflow 1                                */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI0_ERROR_MASK_1_OVERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW2_VC0_CREDIT                           */
+/*   Description:  VC0 credit overflow 2                                */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI0_ERROR_MASK_1_OVERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW0_VC2_CREDIT                           */
+/*   Description:  VC2 credit overflow 0                                */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI0_ERROR_MASK_1_OVERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW1_VC2_CREDIT                           */
+/*   Description:  VC2 credit overflow 1                                */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI0_ERROR_MASK_1_OVERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW2_VC2_CREDIT                           */
+/*   Description:  VC2 credit overflow 2                                */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI0_ERROR_MASK_1_OVERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT0                        */
+/*   Description:  PI Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT0_SHFT 22
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT0_MASK 0x0000000000400000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT2                        */
+/*   Description:  PI Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT2_SHFT 23
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT2_MASK 0x0000000000800000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT0                      */
+/*   Description:  IILB Fifo debit0 overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT0_SHFT 24
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT0_MASK 0x0000000001000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT2                      */
+/*   Description:  IILB Fifo debit2 overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT2_SHFT 25
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT2_MASK 0x0000000002000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT0                        */
+/*   Description:  MD Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT0_SHFT 26
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT0_MASK 0x0000000004000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT2                        */
+/*   Description:  MD Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT2_SHFT 27
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT2_MASK 0x0000000008000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT0                        */
+/*   Description:  NI Fifo debit0 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT0_SHFT 28
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT0_MASK 0x0000000010000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT1                        */
+/*   Description:  NI Fifo debit1 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT1_SHFT 29
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT1_MASK 0x0000000020000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT2                        */
+/*   Description:  NI Fifo debit2 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT2_SHFT 30
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT2_MASK 0x0000000040000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT3                        */
+/*   Description:  NI Fifo debit3 overflow                              */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT3_SHFT 31
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT3_MASK 0x0000000080000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_POP                       */
+/*   Description:  PI Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_POP                       */
+/*   Description:  PI Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_POP                     */
+/*   Description:  IILB Fifo vc0 pop overflow                           */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_POP                     */
+/*   Description:  IILB Fifo vc2 pop overflow                           */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_POP                       */
+/*   Description:  MD Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_POP                       */
+/*   Description:  MD Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_POP                       */
+/*   Description:  NI Fifo vc0 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_POP                       */
+/*   Description:  NI Fifo vc2 pop overflow                             */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_PUSH                      */
+/*   Description:  PI Fifo vc0 push overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_PUSH                      */
+/*   Description:  PI Fifo vc2 push overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_PUSH                    */
+/*   Description:  IILB Fifo vc0 push overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_PUSH                    */
+/*   Description:  IILB Fifo vc2 push overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_PUSH                      */
+/*   Description:  MD Fifo vc0 push overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_PUSH                      */
+/*   Description:  MD Fifo vc2 push overflow                            */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_CREDIT                    */
+/*   Description:  PI Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_CREDIT                    */
+/*   Description:  PI Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_CREDIT                  */
+/*   Description:  IILB Fifo vc0 credit overflow                        */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_CREDIT                  */
+/*   Description:  IILB Fifo vc2 credit overflow                        */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_CREDIT                    */
+/*   Description:  MD Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_CREDIT                    */
+/*   Description:  MD Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_CREDIT                    */
+/*   Description:  NI Fifo vc0 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC1_CREDIT                    */
+/*   Description:  NI Fifo vc1 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_CREDIT                    */
+/*   Description:  NI Fifo vc2 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC3_CREDIT                    */
+/*   Description:  NI Fifo vc3 credit overflow                          */
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI0_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC0                        */
+/*   Description:  Fifo02 vc0 tail timeout                              */
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC0_SHFT 56
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC0_MASK 0x0100000000000000
+
+/*   SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC2                        */
+/*   Description:  Fifo02 vc2 tail timeout                              */
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC2_SHFT 57
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC2_MASK 0x0200000000000000
+
+/*   SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC1                        */
+/*   Description:  Fifo13 vc1 tail timeout                              */
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC1_SHFT 58
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC1_MASK 0x0400000000000000
+
+/*   SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC3                        */
+/*   Description:  Fifo13 vc3 tail timeout                              */
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC3_SHFT 59
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC3_MASK 0x0800000000000000
+
+/*   SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC0                            */
+/*   Description:  NI vc0 tail timeout                                  */
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC0_SHFT 60
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC0_MASK 0x1000000000000000
+
+/*   SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC1                            */
+/*   Description:  NI vc1 tail timeout                                  */
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC1_SHFT 61
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC1_MASK 0x2000000000000000
+
+/*   SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC2                            */
+/*   Description:  NI vc2 tail timeout                                  */
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC2_SHFT 62
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC2_MASK 0x4000000000000000
+
+/*   SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC3                            */
+/*   Description:  NI vc3 tail timeout                                  */
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC3_SHFT 63
+#define SH_NI0_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC3_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_ERROR_MASK_2"                    */
+/*                         ni0  Error Mask Bits                         */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_MASK_2                      0x0000000150040550
+#define SH_NI0_ERROR_MASK_2_MASK                 0x7fffffff003fffff
+#define SH_NI0_ERROR_MASK_2_INIT                 0x7fffffff003fffff
+
+/*   SH_NI0_ERROR_MASK_2_ILLEGAL_VCNI                                   */
+/*   Description:  Illegal VC NI                                        */
+#define SH_NI0_ERROR_MASK_2_ILLEGAL_VCNI_SHFT    0
+#define SH_NI0_ERROR_MASK_2_ILLEGAL_VCNI_MASK    0x0000000000000001
+
+/*   SH_NI0_ERROR_MASK_2_ILLEGAL_VCPI                                   */
+/*   Description:  Illegal VC PI                                        */
+#define SH_NI0_ERROR_MASK_2_ILLEGAL_VCPI_SHFT    1
+#define SH_NI0_ERROR_MASK_2_ILLEGAL_VCPI_MASK    0x0000000000000002
+
+/*   SH_NI0_ERROR_MASK_2_ILLEGAL_VCMD                                   */
+/*   Description:  Illegal VC MD                                        */
+#define SH_NI0_ERROR_MASK_2_ILLEGAL_VCMD_SHFT    2
+#define SH_NI0_ERROR_MASK_2_ILLEGAL_VCMD_MASK    0x0000000000000004
+
+/*   SH_NI0_ERROR_MASK_2_ILLEGAL_VCIILB                                 */
+/*   Description:  Illegal VC IILB                                      */
+#define SH_NI0_ERROR_MASK_2_ILLEGAL_VCIILB_SHFT  3
+#define SH_NI0_ERROR_MASK_2_ILLEGAL_VCIILB_MASK  0x0000000000000008
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_POP                       */
+/*   Description:  Fifo 02 vc0 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_POP                       */
+/*   Description:  Fifo 02 vc2 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_POP                       */
+/*   Description:  Fifo 13 vc1 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_POP                       */
+/*   Description:  Fifo 13 vc3 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_PUSH                      */
+/*   Description:  Fifo 02 vc0 push underflow                           */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_PUSH                      */
+/*   Description:  Fifo 02 vc2 push underflow                           */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_PUSH                      */
+/*   Description:  Fifo 13 vc1 push underflow                           */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_PUSH                      */
+/*   Description:  Fifo 13 vc3 push underflow                           */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_CREDIT                    */
+/*   Description:  Fifo 02 vc0 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_CREDIT                    */
+/*   Description:  Fifo 02 vc2 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC0_CREDIT                    */
+/*   Description:  Fifo 13 vc0 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC2_CREDIT                    */
+/*   Description:  Fifo 13 vc2 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW0_VC0_CREDIT                          */
+/*   Description:  VC0 credit underflow 0                               */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW1_VC0_CREDIT                          */
+/*   Description:  VC0 credit underflow 1                               */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW2_VC0_CREDIT                          */
+/*   Description:  VC0 credit underflow 2                               */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW0_VC2_CREDIT                          */
+/*   Description:  VC2 credit underflow 0                               */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW1_VC2_CREDIT                          */
+/*   Description:  VC2 credit underflow 1                               */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW2_VC2_CREDIT                          */
+/*   Description:  VC2 credit underflow 2                               */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_POP                      */
+/*   Description:  PI Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_POP                      */
+/*   Description:  PI Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_POP                    */
+/*   Description:  IILB Fifo vc0 pop underflow                          */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_POP                    */
+/*   Description:  IILB Fifo vc2 pop underflow                          */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_POP                      */
+/*   Description:  MD Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_POP                      */
+/*   Description:  MD Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_POP                      */
+/*   Description:  NI Fifo vc0 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_POP                      */
+/*   Description:  NI Fifo vc2 pop underflow                            */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_PUSH                     */
+/*   Description:  PI Fifo vc0 push underflow                           */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_PUSH                     */
+/*   Description:  PI Fifo vc2 push underflow                           */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_PUSH                   */
+/*   Description:  IILB Fifo vc0 push underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_PUSH                   */
+/*   Description:  IILB Fifo vc2 push underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_PUSH                     */
+/*   Description:  MD Fifo vc0 push underflow                           */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_PUSH                     */
+/*   Description:  MD Fifo vc2 push underflow                           */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_CREDIT                   */
+/*   Description:  PI Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_CREDIT                   */
+/*   Description:  PI Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT                 */
+/*   Description:  IILB Fifo vc0 credit underflow                       */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT                 */
+/*   Description:  IILB Fifo vc2 credit underflow                       */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_CREDIT                   */
+/*   Description:  MD Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_CREDIT                   */
+/*   Description:  MD Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_CREDIT                   */
+/*   Description:  NI Fifo vc0 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC1_CREDIT                   */
+/*   Description:  NI Fifo vc1 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_CREDIT                   */
+/*   Description:  NI Fifo vc2 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC3_CREDIT                   */
+/*   Description:  NI Fifo vc3 credit underflow                         */
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI0_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC0                               */
+/*   Description:  llp deadlock vc0                                     */
+#define SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC0_SHFT 56
+#define SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC0_MASK 0x0100000000000000
+
+/*   SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC1                               */
+/*   Description:  llp deadlock vc1                                     */
+#define SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC1_SHFT 57
+#define SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC1_MASK 0x0200000000000000
+
+/*   SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC2                               */
+/*   Description:  llp deadlock vc2                                     */
+#define SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC2_SHFT 58
+#define SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC2_MASK 0x0400000000000000
+
+/*   SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC3                               */
+/*   Description:  llp deadlock vc3                                     */
+#define SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC3_SHFT 59
+#define SH_NI0_ERROR_MASK_2_LLP_DEADLOCK_VC3_MASK 0x0800000000000000
+
+/*   SH_NI0_ERROR_MASK_2_CHIPLET_NOMATCH                                */
+/*   Description:  chiplet nomatch                                      */
+#define SH_NI0_ERROR_MASK_2_CHIPLET_NOMATCH_SHFT 60
+#define SH_NI0_ERROR_MASK_2_CHIPLET_NOMATCH_MASK 0x1000000000000000
+
+/*   SH_NI0_ERROR_MASK_2_LUT_READ_ERROR                                 */
+/*   Description:  LUT Read Error                                       */
+#define SH_NI0_ERROR_MASK_2_LUT_READ_ERROR_SHFT  61
+#define SH_NI0_ERROR_MASK_2_LUT_READ_ERROR_MASK  0x2000000000000000
+
+/*   SH_NI0_ERROR_MASK_2_RETRY_TIMEOUT_ERROR                            */
+/*   Description:  Retry Timeout Error                                  */
+#define SH_NI0_ERROR_MASK_2_RETRY_TIMEOUT_ERROR_SHFT 62
+#define SH_NI0_ERROR_MASK_2_RETRY_TIMEOUT_ERROR_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_FIRST_ERROR_1"                    */
+/*                        ni0  First Error Bits                         */
+/* ==================================================================== */
+
+#define SH_NI0_FIRST_ERROR_1                     0x0000000150040560
+#define SH_NI0_FIRST_ERROR_1_MASK                0xffffffffffffffff
+#define SH_NI0_FIRST_ERROR_1_INIT                0xffffffffffffffff
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT0                        */
+/*   Description:  Fifo 02 debit0 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT0_SHFT 0
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT2                        */
+/*   Description:  Fifo 02 debit2 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT2_SHFT 1
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT0                        */
+/*   Description:  Fifo 13 debit0 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT0_SHFT 2
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT2                        */
+/*   Description:  Fifo 13 debit2 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT2_SHFT 3
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_POP                       */
+/*   Description:  Fifo 02 vc0 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_POP                       */
+/*   Description:  Fifo 02 vc2 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_POP                       */
+/*   Description:  Fifo 13 vc1 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_POP                       */
+/*   Description:  Fifo 13 vc3 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_PUSH                      */
+/*   Description:  Fifo 02 vc0 push overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_PUSH                      */
+/*   Description:  Fifo 02 vc2 push overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_PUSH                      */
+/*   Description:  Fifo 13 vc1 push overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_PUSH                      */
+/*   Description:  Fifo 13 vc3 push overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_CREDIT                    */
+/*   Description:  Fifo 02 vc0 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_CREDIT                    */
+/*   Description:  Fifo 02 vc2 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC0_CREDIT                    */
+/*   Description:  Fifo 13 vc0 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC2_CREDIT                    */
+/*   Description:  Fifo 13 vc2 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW0_VC0_CREDIT                          */
+/*   Description:  VC0 credit overflow 0                                */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW1_VC0_CREDIT                          */
+/*   Description:  VC0 credit overflow 1                                */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW2_VC0_CREDIT                          */
+/*   Description:  VC0 credit overflow 2                                */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW0_VC2_CREDIT                          */
+/*   Description:  VC2 credit overflow 0                                */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW1_VC2_CREDIT                          */
+/*   Description:  VC2 credit overflow 1                                */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW2_VC2_CREDIT                          */
+/*   Description:  VC2 credit overflow 2                                */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT0                       */
+/*   Description:  PI Fifo debit0 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT0_SHFT 22
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT0_MASK 0x0000000000400000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT2                       */
+/*   Description:  PI Fifo debit2 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT2_SHFT 23
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT2_MASK 0x0000000000800000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT0                     */
+/*   Description:  IILB Fifo debit0 overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT0_SHFT 24
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT0_MASK 0x0000000001000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT2                     */
+/*   Description:  IILB Fifo debit2 overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT2_SHFT 25
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT2_MASK 0x0000000002000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT0                       */
+/*   Description:  MD Fifo debit0 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT0_SHFT 26
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT0_MASK 0x0000000004000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT2                       */
+/*   Description:  MD Fifo debit2 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT2_SHFT 27
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT2_MASK 0x0000000008000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT0                       */
+/*   Description:  NI Fifo debit0 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT0_SHFT 28
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT0_MASK 0x0000000010000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT1                       */
+/*   Description:  NI Fifo debit1 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT1_SHFT 29
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT1_MASK 0x0000000020000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT2                       */
+/*   Description:  NI Fifo debit2 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT2_SHFT 30
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT2_MASK 0x0000000040000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT3                       */
+/*   Description:  NI Fifo debit3 overflow                              */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT3_SHFT 31
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT3_MASK 0x0000000080000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_POP                      */
+/*   Description:  PI Fifo vc0 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_POP                      */
+/*   Description:  PI Fifo vc2 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_POP                    */
+/*   Description:  IILB Fifo vc0 pop overflow                           */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_POP                    */
+/*   Description:  IILB Fifo vc2 pop overflow                           */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_POP                      */
+/*   Description:  MD Fifo vc0 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_POP                      */
+/*   Description:  MD Fifo vc2 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_POP                      */
+/*   Description:  NI Fifo vc0 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_POP                      */
+/*   Description:  NI Fifo vc2 pop overflow                             */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_PUSH                     */
+/*   Description:  PI Fifo vc0 push overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_PUSH                     */
+/*   Description:  PI Fifo vc2 push overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_PUSH                   */
+/*   Description:  IILB Fifo vc0 push overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_PUSH                   */
+/*   Description:  IILB Fifo vc2 push overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_PUSH                     */
+/*   Description:  MD Fifo vc0 push overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_PUSH                     */
+/*   Description:  MD Fifo vc2 push overflow                            */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_CREDIT                   */
+/*   Description:  PI Fifo vc0 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_CREDIT                   */
+/*   Description:  PI Fifo vc2 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_CREDIT                 */
+/*   Description:  IILB Fifo vc0 credit overflow                        */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_CREDIT                 */
+/*   Description:  IILB Fifo vc2 credit overflow                        */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_CREDIT                   */
+/*   Description:  MD Fifo vc0 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_CREDIT                   */
+/*   Description:  MD Fifo vc2 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_CREDIT                   */
+/*   Description:  NI Fifo vc0 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC1_CREDIT                   */
+/*   Description:  NI Fifo vc1 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_CREDIT                   */
+/*   Description:  NI Fifo vc2 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC3_CREDIT                   */
+/*   Description:  NI Fifo vc3 credit overflow                          */
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI0_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC0                       */
+/*   Description:  Fifo02 vc0 tail timeout                              */
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC0_SHFT 56
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC0_MASK 0x0100000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC2                       */
+/*   Description:  Fifo02 vc2 tail timeout                              */
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC2_SHFT 57
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC2_MASK 0x0200000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC1                       */
+/*   Description:  Fifo13 vc1 tail timeout                              */
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC1_SHFT 58
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC1_MASK 0x0400000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC3                       */
+/*   Description:  Fifo13 vc3 tail timeout                              */
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC3_SHFT 59
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC3_MASK 0x0800000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC0                           */
+/*   Description:  NI vc0 tail timeout                                  */
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC0_SHFT 60
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC0_MASK 0x1000000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC1                           */
+/*   Description:  NI vc1 tail timeout                                  */
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC1_SHFT 61
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC1_MASK 0x2000000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC2                           */
+/*   Description:  NI vc2 tail timeout                                  */
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC2_SHFT 62
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC2_MASK 0x4000000000000000
+
+/*   SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC3                           */
+/*   Description:  NI vc3 tail timeout                                  */
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC3_SHFT 63
+#define SH_NI0_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC3_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_FIRST_ERROR_2"                    */
+/*                         ni0 First Error Bits                         */
+/* ==================================================================== */
+
+#define SH_NI0_FIRST_ERROR_2                     0x0000000150040570
+#define SH_NI0_FIRST_ERROR_2_MASK                0x7fffffff003fffff
+#define SH_NI0_FIRST_ERROR_2_INIT                0x7fffffff003fffff
+
+/*   SH_NI0_FIRST_ERROR_2_ILLEGAL_VCNI                                  */
+/*   Description:  Illegal VC NI                                        */
+#define SH_NI0_FIRST_ERROR_2_ILLEGAL_VCNI_SHFT   0
+#define SH_NI0_FIRST_ERROR_2_ILLEGAL_VCNI_MASK   0x0000000000000001
+
+/*   SH_NI0_FIRST_ERROR_2_ILLEGAL_VCPI                                  */
+/*   Description:  Illegal VC PI                                        */
+#define SH_NI0_FIRST_ERROR_2_ILLEGAL_VCPI_SHFT   1
+#define SH_NI0_FIRST_ERROR_2_ILLEGAL_VCPI_MASK   0x0000000000000002
+
+/*   SH_NI0_FIRST_ERROR_2_ILLEGAL_VCMD                                  */
+/*   Description:  Illegal VC MD                                        */
+#define SH_NI0_FIRST_ERROR_2_ILLEGAL_VCMD_SHFT   2
+#define SH_NI0_FIRST_ERROR_2_ILLEGAL_VCMD_MASK   0x0000000000000004
+
+/*   SH_NI0_FIRST_ERROR_2_ILLEGAL_VCIILB                                */
+/*   Description:  Illegal VC IILB                                      */
+#define SH_NI0_FIRST_ERROR_2_ILLEGAL_VCIILB_SHFT 3
+#define SH_NI0_FIRST_ERROR_2_ILLEGAL_VCIILB_MASK 0x0000000000000008
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_POP                      */
+/*   Description:  Fifo 02 vc0 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_POP                      */
+/*   Description:  Fifo 02 vc2 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_POP                      */
+/*   Description:  Fifo 13 vc1 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_POP                      */
+/*   Description:  Fifo 13 vc3 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_PUSH                     */
+/*   Description:  Fifo 02 vc0 push underflow                           */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_PUSH                     */
+/*   Description:  Fifo 02 vc2 push underflow                           */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_PUSH                     */
+/*   Description:  Fifo 13 vc1 push underflow                           */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_PUSH                     */
+/*   Description:  Fifo 13 vc3 push underflow                           */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_CREDIT                   */
+/*   Description:  Fifo 02 vc0 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_CREDIT                   */
+/*   Description:  Fifo 02 vc2 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC0_CREDIT                   */
+/*   Description:  Fifo 13 vc0 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC2_CREDIT                   */
+/*   Description:  Fifo 13 vc2 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW0_VC0_CREDIT                         */
+/*   Description:  VC0 credit underflow 0                               */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW1_VC0_CREDIT                         */
+/*   Description:  VC0 credit underflow 1                               */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW2_VC0_CREDIT                         */
+/*   Description:  VC0 credit underflow 2                               */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW0_VC2_CREDIT                         */
+/*   Description:  VC2 credit underflow 0                               */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW1_VC2_CREDIT                         */
+/*   Description:  VC2 credit underflow 1                               */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW2_VC2_CREDIT                         */
+/*   Description:  VC2 credit underflow 2                               */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_POP                     */
+/*   Description:  PI Fifo vc0 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_POP                     */
+/*   Description:  PI Fifo vc2 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_POP                   */
+/*   Description:  IILB Fifo vc0 pop underflow                          */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_POP                   */
+/*   Description:  IILB Fifo vc2 pop underflow                          */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_POP                     */
+/*   Description:  MD Fifo vc0 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_POP                     */
+/*   Description:  MD Fifo vc2 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_POP                     */
+/*   Description:  NI Fifo vc0 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_POP                     */
+/*   Description:  NI Fifo vc2 pop underflow                            */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_PUSH                    */
+/*   Description:  PI Fifo vc0 push underflow                           */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_PUSH                    */
+/*   Description:  PI Fifo vc2 push underflow                           */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_PUSH                  */
+/*   Description:  IILB Fifo vc0 push underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_PUSH                  */
+/*   Description:  IILB Fifo vc2 push underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_PUSH                    */
+/*   Description:  MD Fifo vc0 push underflow                           */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_PUSH                    */
+/*   Description:  MD Fifo vc2 push underflow                           */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_CREDIT                  */
+/*   Description:  PI Fifo vc0 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_CREDIT                  */
+/*   Description:  PI Fifo vc2 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT                */
+/*   Description:  IILB Fifo vc0 credit underflow                       */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT                */
+/*   Description:  IILB Fifo vc2 credit underflow                       */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_CREDIT                  */
+/*   Description:  MD Fifo vc0 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_CREDIT                  */
+/*   Description:  MD Fifo vc2 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_CREDIT                  */
+/*   Description:  NI Fifo vc0 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC1_CREDIT                  */
+/*   Description:  NI Fifo vc1 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_CREDIT                  */
+/*   Description:  NI Fifo vc2 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC3_CREDIT                  */
+/*   Description:  NI Fifo vc3 credit underflow                         */
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI0_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC0                              */
+/*   Description:  llp deadlock vc0                                     */
+#define SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC0_SHFT 56
+#define SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC0_MASK 0x0100000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC1                              */
+/*   Description:  llp deadlock vc1                                     */
+#define SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC1_SHFT 57
+#define SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC1_MASK 0x0200000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC2                              */
+/*   Description:  llp deadlock vc2                                     */
+#define SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC2_SHFT 58
+#define SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC2_MASK 0x0400000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC3                              */
+/*   Description:  llp deadlock vc3                                     */
+#define SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC3_SHFT 59
+#define SH_NI0_FIRST_ERROR_2_LLP_DEADLOCK_VC3_MASK 0x0800000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_CHIPLET_NOMATCH                               */
+/*   Description:  chiplet nomatch                                      */
+#define SH_NI0_FIRST_ERROR_2_CHIPLET_NOMATCH_SHFT 60
+#define SH_NI0_FIRST_ERROR_2_CHIPLET_NOMATCH_MASK 0x1000000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_LUT_READ_ERROR                                */
+/*   Description:  LUT Read Error                                       */
+#define SH_NI0_FIRST_ERROR_2_LUT_READ_ERROR_SHFT 61
+#define SH_NI0_FIRST_ERROR_2_LUT_READ_ERROR_MASK 0x2000000000000000
+
+/*   SH_NI0_FIRST_ERROR_2_RETRY_TIMEOUT_ERROR                           */
+/*   Description:  Retry Timeout Error                                  */
+#define SH_NI0_FIRST_ERROR_2_RETRY_TIMEOUT_ERROR_SHFT 62
+#define SH_NI0_FIRST_ERROR_2_RETRY_TIMEOUT_ERROR_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_ERROR_DETAIL_1"                   */
+/*                ni0 Chiplet no match header bits 63:0                 */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_DETAIL_1                    0x0000000150040580
+#define SH_NI0_ERROR_DETAIL_1_MASK               0xffffffffffffffff
+#define SH_NI0_ERROR_DETAIL_1_INIT               0x0000000000000000
+
+/*   SH_NI0_ERROR_DETAIL_1_HEADER                                       */
+/*   Description:  Header bits 63:0                                     */
+#define SH_NI0_ERROR_DETAIL_1_HEADER_SHFT        0
+#define SH_NI0_ERROR_DETAIL_1_HEADER_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_ERROR_DETAIL_2"                   */
+/*               ni0 Chiplet no match header bits 127:64                */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_DETAIL_2                    0x0000000150040590
+#define SH_NI0_ERROR_DETAIL_2_MASK               0xffffffffffffffff
+#define SH_NI0_ERROR_DETAIL_2_INIT               0x0000000000000000
+
+/*   SH_NI0_ERROR_DETAIL_2_HEADER                                       */
+/*   Description:  Header bits 127:64                                   */
+#define SH_NI0_ERROR_DETAIL_2_HEADER_SHFT        0
+#define SH_NI0_ERROR_DETAIL_2_HEADER_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_ERROR_SUMMARY_1"                   */
+/*                       ni1  Error Summary Bits                        */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_SUMMARY_1                   0x0000000150040600
+#define SH_NI1_ERROR_SUMMARY_1_MASK              0xffffffffffffffff
+#define SH_NI1_ERROR_SUMMARY_1_INIT              0xffffffffffffffff
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT0                      */
+/*   Description:  Fifo 02 debit0 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT0_SHFT 0
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT2                      */
+/*   Description:  Fifo 02 debit2 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT2_SHFT 1
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT0                      */
+/*   Description:  Fifo 13 debit0 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT0_SHFT 2
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT2                      */
+/*   Description:  Fifo 13 debit2 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT2_SHFT 3
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_POP                     */
+/*   Description:  Fifo 02 vc0 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_POP                     */
+/*   Description:  Fifo 02 vc2 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_POP                     */
+/*   Description:  Fifo 13 vc1 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_POP                     */
+/*   Description:  Fifo 13 vc3 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_PUSH                    */
+/*   Description:  Fifo 02 vc0 push overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_PUSH                    */
+/*   Description:  Fifo 02 vc2 push overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_PUSH                    */
+/*   Description:  Fifo 13 vc1 push overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_PUSH                    */
+/*   Description:  Fifo 13 vc3 push overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_CREDIT                  */
+/*   Description:  Fifo 02 vc0 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_CREDIT                  */
+/*   Description:  Fifo 02 vc2 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC0_CREDIT                  */
+/*   Description:  Fifo 13 vc0 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC2_CREDIT                  */
+/*   Description:  Fifo 13 vc2 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW0_VC0_CREDIT                        */
+/*   Description:  VC0 credit overflow 0                                */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW1_VC0_CREDIT                        */
+/*   Description:  VC0 credit overflow 1                                */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW2_VC0_CREDIT                        */
+/*   Description:  VC0 credit overflow 2                                */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW0_VC2_CREDIT                        */
+/*   Description:  VC2 credit overflow 0                                */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW1_VC2_CREDIT                        */
+/*   Description:  VC2 credit overflow 1                                */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW2_VC2_CREDIT                        */
+/*   Description:  VC2 credit overflow 2                                */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT0                     */
+/*   Description:  PI Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT0_SHFT 22
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT0_MASK 0x0000000000400000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT2                     */
+/*   Description:  PI Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT2_SHFT 23
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_DEBIT2_MASK 0x0000000000800000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT0                   */
+/*   Description:  IILB Fifo debit0 overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT0_SHFT 24
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT0_MASK 0x0000000001000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT2                   */
+/*   Description:  IILB Fifo debit2 overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT2_SHFT 25
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_DEBIT2_MASK 0x0000000002000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT0                     */
+/*   Description:  MD Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT0_SHFT 26
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT0_MASK 0x0000000004000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT2                     */
+/*   Description:  MD Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT2_SHFT 27
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_DEBIT2_MASK 0x0000000008000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT0                     */
+/*   Description:  NI Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT0_SHFT 28
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT0_MASK 0x0000000010000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT1                     */
+/*   Description:  NI Fifo debit1 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT1_SHFT 29
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT1_MASK 0x0000000020000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT2                     */
+/*   Description:  NI Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT2_SHFT 30
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT2_MASK 0x0000000040000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT3                     */
+/*   Description:  NI Fifo debit3 overflow                              */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT3_SHFT 31
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_DEBIT3_MASK 0x0000000080000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_POP                    */
+/*   Description:  PI Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_POP                    */
+/*   Description:  PI Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_POP                  */
+/*   Description:  IILB Fifo vc0 pop overflow                           */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_POP                  */
+/*   Description:  IILB Fifo vc2 pop overflow                           */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_POP                    */
+/*   Description:  MD Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_POP                    */
+/*   Description:  MD Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_POP                    */
+/*   Description:  NI Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_POP                    */
+/*   Description:  NI Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_PUSH                   */
+/*   Description:  PI Fifo vc0 push overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_PUSH                   */
+/*   Description:  PI Fifo vc2 push overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_PUSH                 */
+/*   Description:  IILB Fifo vc0 push overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_PUSH                 */
+/*   Description:  IILB Fifo vc2 push overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_PUSH                   */
+/*   Description:  MD Fifo vc0 push overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_PUSH                   */
+/*   Description:  MD Fifo vc2 push overflow                            */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_CREDIT                 */
+/*   Description:  PI Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_CREDIT                 */
+/*   Description:  PI Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_CREDIT               */
+/*   Description:  IILB Fifo vc0 credit overflow                        */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_CREDIT               */
+/*   Description:  IILB Fifo vc2 credit overflow                        */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_CREDIT                 */
+/*   Description:  MD Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_CREDIT                 */
+/*   Description:  MD Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_CREDIT                 */
+/*   Description:  NI Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC1_CREDIT                 */
+/*   Description:  NI Fifo vc1 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_CREDIT                 */
+/*   Description:  NI Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC3_CREDIT                 */
+/*   Description:  NI Fifo vc3 credit overflow                          */
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI1_ERROR_SUMMARY_1_OVERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC0                     */
+/*   Description:  Fifo02 vc0 tail timeout                              */
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC0_SHFT 56
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC0_MASK 0x0100000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC2                     */
+/*   Description:  Fifo02 vc2 tail timeout                              */
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC2_SHFT 57
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO02_VC2_MASK 0x0200000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC1                     */
+/*   Description:  Fifo13 vc1 tail timeout                              */
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC1_SHFT 58
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC1_MASK 0x0400000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC3                     */
+/*   Description:  Fifo13 vc3 tail timeout                              */
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC3_SHFT 59
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_FIFO13_VC3_MASK 0x0800000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC0                         */
+/*   Description:  NI vc0 tail timeout                                  */
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC0_SHFT 60
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC0_MASK 0x1000000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC1                         */
+/*   Description:  NI vc1 tail timeout                                  */
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC1_SHFT 61
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC1_MASK 0x2000000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC2                         */
+/*   Description:  NI vc2 tail timeout                                  */
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC2_SHFT 62
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC2_MASK 0x4000000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC3                         */
+/*   Description:  NI vc3 tail timeout                                  */
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC3_SHFT 63
+#define SH_NI1_ERROR_SUMMARY_1_TAIL_TIMEOUT_NI_VC3_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_NI1_ERROR_SUMMARY_1_ALIAS"                */
+/*                     ni1 Error Summary Bits Alias                     */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_SUMMARY_1_ALIAS             0x0000000150040608
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_ERROR_SUMMARY_2"                   */
+/*                       ni1  Error Summary Bits                        */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_SUMMARY_2                   0x0000000150040610
+#define SH_NI1_ERROR_SUMMARY_2_MASK              0x7fffffff003fffff
+#define SH_NI1_ERROR_SUMMARY_2_INIT              0x7fffffff003fffff
+
+/*   SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCNI                                */
+/*   Description:  Illegal VC NI                                        */
+#define SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCNI_SHFT 0
+#define SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCNI_MASK 0x0000000000000001
+
+/*   SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCPI                                */
+/*   Description:  Illegal VC PI                                        */
+#define SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCPI_SHFT 1
+#define SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCPI_MASK 0x0000000000000002
+
+/*   SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCMD                                */
+/*   Description:  Illegal VC MD                                        */
+#define SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCMD_SHFT 2
+#define SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCMD_MASK 0x0000000000000004
+
+/*   SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCIILB                              */
+/*   Description:  Illegal VC IILB                                      */
+#define SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCIILB_SHFT 3
+#define SH_NI1_ERROR_SUMMARY_2_ILLEGAL_VCIILB_MASK 0x0000000000000008
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_POP                    */
+/*   Description:  Fifo 02 vc0 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_POP                    */
+/*   Description:  Fifo 02 vc2 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_POP                    */
+/*   Description:  Fifo 13 vc1 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_POP                    */
+/*   Description:  Fifo 13 vc3 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_PUSH                   */
+/*   Description:  Fifo 02 vc0 push underflow                           */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_PUSH                   */
+/*   Description:  Fifo 02 vc2 push underflow                           */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_PUSH                   */
+/*   Description:  Fifo 13 vc1 push underflow                           */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_PUSH                   */
+/*   Description:  Fifo 13 vc3 push underflow                           */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_CREDIT                 */
+/*   Description:  Fifo 02 vc0 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_CREDIT                 */
+/*   Description:  Fifo 02 vc2 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC0_CREDIT                 */
+/*   Description:  Fifo 13 vc0 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC2_CREDIT                 */
+/*   Description:  Fifo 13 vc2 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW0_VC0_CREDIT                       */
+/*   Description:  VC0 credit underflow 0                               */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW1_VC0_CREDIT                       */
+/*   Description:  VC0 credit underflow 1                               */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW2_VC0_CREDIT                       */
+/*   Description:  VC0 credit underflow 2                               */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW0_VC2_CREDIT                       */
+/*   Description:  VC2 credit underflow 0                               */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW1_VC2_CREDIT                       */
+/*   Description:  VC2 credit underflow 1                               */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW2_VC2_CREDIT                       */
+/*   Description:  VC2 credit underflow 2                               */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_POP                   */
+/*   Description:  PI Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_POP                   */
+/*   Description:  PI Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_POP                 */
+/*   Description:  IILB Fifo vc0 pop underflow                          */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_POP                 */
+/*   Description:  IILB Fifo vc2 pop underflow                          */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_POP                   */
+/*   Description:  MD Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_POP                   */
+/*   Description:  MD Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_POP                   */
+/*   Description:  NI Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_POP                   */
+/*   Description:  NI Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_PUSH                  */
+/*   Description:  PI Fifo vc0 push underflow                           */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_PUSH                  */
+/*   Description:  PI Fifo vc2 push underflow                           */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_PUSH                */
+/*   Description:  IILB Fifo vc0 push underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_PUSH                */
+/*   Description:  IILB Fifo vc2 push underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_PUSH                  */
+/*   Description:  MD Fifo vc0 push underflow                           */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_PUSH                  */
+/*   Description:  MD Fifo vc2 push underflow                           */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_CREDIT                */
+/*   Description:  PI Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_CREDIT                */
+/*   Description:  PI Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT              */
+/*   Description:  IILB Fifo vc0 credit underflow                       */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT              */
+/*   Description:  IILB Fifo vc2 credit underflow                       */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_CREDIT                */
+/*   Description:  MD Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_CREDIT                */
+/*   Description:  MD Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_CREDIT                */
+/*   Description:  NI Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC1_CREDIT                */
+/*   Description:  NI Fifo vc1 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_CREDIT                */
+/*   Description:  NI Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC3_CREDIT                */
+/*   Description:  NI Fifo vc3 credit underflow                         */
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI1_ERROR_SUMMARY_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC0                            */
+/*   Description:  llp deadlock vc0                                     */
+#define SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC0_SHFT 56
+#define SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC0_MASK 0x0100000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC1                            */
+/*   Description:  llp deadlock vc1                                     */
+#define SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC1_SHFT 57
+#define SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC1_MASK 0x0200000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC2                            */
+/*   Description:  llp deadlock vc2                                     */
+#define SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC2_SHFT 58
+#define SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC2_MASK 0x0400000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC3                            */
+/*   Description:  llp deadlock vc3                                     */
+#define SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC3_SHFT 59
+#define SH_NI1_ERROR_SUMMARY_2_LLP_DEADLOCK_VC3_MASK 0x0800000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_CHIPLET_NOMATCH                             */
+/*   Description:  chiplet nomatch                                      */
+#define SH_NI1_ERROR_SUMMARY_2_CHIPLET_NOMATCH_SHFT 60
+#define SH_NI1_ERROR_SUMMARY_2_CHIPLET_NOMATCH_MASK 0x1000000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_LUT_READ_ERROR                              */
+/*   Description:  LUT Read Error                                       */
+#define SH_NI1_ERROR_SUMMARY_2_LUT_READ_ERROR_SHFT 61
+#define SH_NI1_ERROR_SUMMARY_2_LUT_READ_ERROR_MASK 0x2000000000000000
+
+/*   SH_NI1_ERROR_SUMMARY_2_RETRY_TIMEOUT_ERROR                         */
+/*   Description:  Retry Timeout Error                                  */
+#define SH_NI1_ERROR_SUMMARY_2_RETRY_TIMEOUT_ERROR_SHFT 62
+#define SH_NI1_ERROR_SUMMARY_2_RETRY_TIMEOUT_ERROR_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_NI1_ERROR_SUMMARY_2_ALIAS"                */
+/*                     ni1 Error Summary Bits Alias                     */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_SUMMARY_2_ALIAS             0x0000000150040618
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_ERROR_OVERFLOW_1"                  */
+/*                       ni1  Error Overflow Bits                       */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_OVERFLOW_1                  0x0000000150040620
+#define SH_NI1_ERROR_OVERFLOW_1_MASK             0xffffffffffffffff
+#define SH_NI1_ERROR_OVERFLOW_1_INIT             0xffffffffffffffff
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT0                     */
+/*   Description:  Fifo 02 debit0 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT0_SHFT 0
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT2                     */
+/*   Description:  Fifo 02 debit2 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT2_SHFT 1
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT0                     */
+/*   Description:  Fifo 13 debit0 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT0_SHFT 2
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT2                     */
+/*   Description:  Fifo 13 debit2 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT2_SHFT 3
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_POP                    */
+/*   Description:  Fifo 02 vc0 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_POP                    */
+/*   Description:  Fifo 02 vc2 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_POP                    */
+/*   Description:  Fifo 13 vc1 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_POP                    */
+/*   Description:  Fifo 13 vc3 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_PUSH                   */
+/*   Description:  Fifo 02 vc0 push overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_PUSH                   */
+/*   Description:  Fifo 02 vc2 push overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_PUSH                   */
+/*   Description:  Fifo 13 vc1 push overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_PUSH                   */
+/*   Description:  Fifo 13 vc3 push overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_CREDIT                 */
+/*   Description:  Fifo 02 vc0 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_CREDIT                 */
+/*   Description:  Fifo 02 vc2 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC0_CREDIT                 */
+/*   Description:  Fifo 13 vc0 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC2_CREDIT                 */
+/*   Description:  Fifo 13 vc2 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW0_VC0_CREDIT                       */
+/*   Description:  VC0 credit overflow 0                                */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW1_VC0_CREDIT                       */
+/*   Description:  VC0 credit overflow 1                                */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW2_VC0_CREDIT                       */
+/*   Description:  VC0 credit overflow 2                                */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW0_VC2_CREDIT                       */
+/*   Description:  VC2 credit overflow 0                                */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW1_VC2_CREDIT                       */
+/*   Description:  VC2 credit overflow 1                                */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW2_VC2_CREDIT                       */
+/*   Description:  VC2 credit overflow 2                                */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT0                    */
+/*   Description:  PI Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT0_SHFT 22
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT0_MASK 0x0000000000400000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT2                    */
+/*   Description:  PI Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT2_SHFT 23
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_DEBIT2_MASK 0x0000000000800000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT0                  */
+/*   Description:  IILB Fifo debit0 overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT0_SHFT 24
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT0_MASK 0x0000000001000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT2                  */
+/*   Description:  IILB Fifo debit2 overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT2_SHFT 25
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_DEBIT2_MASK 0x0000000002000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT0                    */
+/*   Description:  MD Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT0_SHFT 26
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT0_MASK 0x0000000004000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT2                    */
+/*   Description:  MD Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT2_SHFT 27
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_DEBIT2_MASK 0x0000000008000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT0                    */
+/*   Description:  NI Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT0_SHFT 28
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT0_MASK 0x0000000010000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT1                    */
+/*   Description:  NI Fifo debit1 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT1_SHFT 29
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT1_MASK 0x0000000020000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT2                    */
+/*   Description:  NI Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT2_SHFT 30
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT2_MASK 0x0000000040000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT3                    */
+/*   Description:  NI Fifo debit3 overflow                              */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT3_SHFT 31
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_DEBIT3_MASK 0x0000000080000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_POP                   */
+/*   Description:  PI Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_POP                   */
+/*   Description:  PI Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_POP                 */
+/*   Description:  IILB Fifo vc0 pop overflow                           */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_POP                 */
+/*   Description:  IILB Fifo vc2 pop overflow                           */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_POP                   */
+/*   Description:  MD Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_POP                   */
+/*   Description:  MD Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_POP                   */
+/*   Description:  NI Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_POP                   */
+/*   Description:  NI Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_PUSH                  */
+/*   Description:  PI Fifo vc0 push overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_PUSH                  */
+/*   Description:  PI Fifo vc2 push overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_PUSH                */
+/*   Description:  IILB Fifo vc0 push overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_PUSH                */
+/*   Description:  IILB Fifo vc2 push overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_PUSH                  */
+/*   Description:  MD Fifo vc0 push overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_PUSH                  */
+/*   Description:  MD Fifo vc2 push overflow                            */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_CREDIT                */
+/*   Description:  PI Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_CREDIT                */
+/*   Description:  PI Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_CREDIT              */
+/*   Description:  IILB Fifo vc0 credit overflow                        */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_CREDIT              */
+/*   Description:  IILB Fifo vc2 credit overflow                        */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_CREDIT                */
+/*   Description:  MD Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_CREDIT                */
+/*   Description:  MD Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_CREDIT                */
+/*   Description:  NI Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC1_CREDIT                */
+/*   Description:  NI Fifo vc1 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_CREDIT                */
+/*   Description:  NI Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC3_CREDIT                */
+/*   Description:  NI Fifo vc3 credit overflow                          */
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI1_ERROR_OVERFLOW_1_OVERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC0                    */
+/*   Description:  Fifo02 vc0 tail timeout                              */
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC0_SHFT 56
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC0_MASK 0x0100000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC2                    */
+/*   Description:  Fifo02 vc2 tail timeout                              */
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC2_SHFT 57
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO02_VC2_MASK 0x0200000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC1                    */
+/*   Description:  Fifo13 vc1 tail timeout                              */
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC1_SHFT 58
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC1_MASK 0x0400000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC3                    */
+/*   Description:  Fifo13 vc3 tail timeout                              */
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC3_SHFT 59
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_FIFO13_VC3_MASK 0x0800000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC0                        */
+/*   Description:  NI vc0 tail timeout                                  */
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC0_SHFT 60
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC0_MASK 0x1000000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC1                        */
+/*   Description:  NI vc1 tail timeout                                  */
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC1_SHFT 61
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC1_MASK 0x2000000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC2                        */
+/*   Description:  NI vc2 tail timeout                                  */
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC2_SHFT 62
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC2_MASK 0x4000000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC3                        */
+/*   Description:  NI vc3 tail timeout                                  */
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC3_SHFT 63
+#define SH_NI1_ERROR_OVERFLOW_1_TAIL_TIMEOUT_NI_VC3_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_NI1_ERROR_OVERFLOW_1_ALIAS"               */
+/*                    ni1 Error Overflow Bits Alias                     */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_OVERFLOW_1_ALIAS            0x0000000150040628
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_ERROR_OVERFLOW_2"                  */
+/*                       ni1  Error Overflow Bits                       */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_OVERFLOW_2                  0x0000000150040630
+#define SH_NI1_ERROR_OVERFLOW_2_MASK             0x7fffffff003fffff
+#define SH_NI1_ERROR_OVERFLOW_2_INIT             0x7fffffff003fffff
+
+/*   SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCNI                               */
+/*   Description:  Illegal VC NI                                        */
+#define SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCNI_SHFT 0
+#define SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCNI_MASK 0x0000000000000001
+
+/*   SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCPI                               */
+/*   Description:  Illegal VC PI                                        */
+#define SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCPI_SHFT 1
+#define SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCPI_MASK 0x0000000000000002
+
+/*   SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCMD                               */
+/*   Description:  Illegal VC MD                                        */
+#define SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCMD_SHFT 2
+#define SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCMD_MASK 0x0000000000000004
+
+/*   SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCIILB                             */
+/*   Description:  Illegal VC IILB                                      */
+#define SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCIILB_SHFT 3
+#define SH_NI1_ERROR_OVERFLOW_2_ILLEGAL_VCIILB_MASK 0x0000000000000008
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_POP                   */
+/*   Description:  Fifo 02 vc0 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_POP                   */
+/*   Description:  Fifo 02 vc2 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_POP                   */
+/*   Description:  Fifo 13 vc1 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_POP                   */
+/*   Description:  Fifo 13 vc3 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_PUSH                  */
+/*   Description:  Fifo 02 vc0 push underflow                           */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_PUSH                  */
+/*   Description:  Fifo 02 vc2 push underflow                           */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_PUSH                  */
+/*   Description:  Fifo 13 vc1 push underflow                           */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_PUSH                  */
+/*   Description:  Fifo 13 vc3 push underflow                           */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_CREDIT                */
+/*   Description:  Fifo 02 vc0 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_CREDIT                */
+/*   Description:  Fifo 02 vc2 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC0_CREDIT                */
+/*   Description:  Fifo 13 vc0 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC2_CREDIT                */
+/*   Description:  Fifo 13 vc2 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW0_VC0_CREDIT                      */
+/*   Description:  VC0 credit underflow 0                               */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW1_VC0_CREDIT                      */
+/*   Description:  VC0 credit underflow 1                               */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW2_VC0_CREDIT                      */
+/*   Description:  VC0 credit underflow 2                               */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW0_VC2_CREDIT                      */
+/*   Description:  VC2 credit underflow 0                               */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW1_VC2_CREDIT                      */
+/*   Description:  VC2 credit underflow 1                               */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW2_VC2_CREDIT                      */
+/*   Description:  VC2 credit underflow 2                               */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_POP                  */
+/*   Description:  PI Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_POP                  */
+/*   Description:  PI Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_POP                */
+/*   Description:  IILB Fifo vc0 pop underflow                          */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_POP                */
+/*   Description:  IILB Fifo vc2 pop underflow                          */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_POP                  */
+/*   Description:  MD Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_POP                  */
+/*   Description:  MD Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_POP                  */
+/*   Description:  NI Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_POP                  */
+/*   Description:  NI Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_PUSH                 */
+/*   Description:  PI Fifo vc0 push underflow                           */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_PUSH                 */
+/*   Description:  PI Fifo vc2 push underflow                           */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_PUSH               */
+/*   Description:  IILB Fifo vc0 push underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_PUSH               */
+/*   Description:  IILB Fifo vc2 push underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_PUSH                 */
+/*   Description:  MD Fifo vc0 push underflow                           */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_PUSH                 */
+/*   Description:  MD Fifo vc2 push underflow                           */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_CREDIT               */
+/*   Description:  PI Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_CREDIT               */
+/*   Description:  PI Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT             */
+/*   Description:  IILB Fifo vc0 credit underflow                       */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT             */
+/*   Description:  IILB Fifo vc2 credit underflow                       */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_CREDIT               */
+/*   Description:  MD Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_CREDIT               */
+/*   Description:  MD Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_CREDIT               */
+/*   Description:  NI Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC1_CREDIT               */
+/*   Description:  NI Fifo vc1 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_CREDIT               */
+/*   Description:  NI Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC3_CREDIT               */
+/*   Description:  NI Fifo vc3 credit underflow                         */
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI1_ERROR_OVERFLOW_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC0                           */
+/*   Description:  llp deadlock vc0                                     */
+#define SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC0_SHFT 56
+#define SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC0_MASK 0x0100000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC1                           */
+/*   Description:  llp deadlock vc1                                     */
+#define SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC1_SHFT 57
+#define SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC1_MASK 0x0200000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC2                           */
+/*   Description:  llp deadlock vc2                                     */
+#define SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC2_SHFT 58
+#define SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC2_MASK 0x0400000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC3                           */
+/*   Description:  llp deadlock vc3                                     */
+#define SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC3_SHFT 59
+#define SH_NI1_ERROR_OVERFLOW_2_LLP_DEADLOCK_VC3_MASK 0x0800000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_CHIPLET_NOMATCH                            */
+/*   Description:  chiplet nomatch                                      */
+#define SH_NI1_ERROR_OVERFLOW_2_CHIPLET_NOMATCH_SHFT 60
+#define SH_NI1_ERROR_OVERFLOW_2_CHIPLET_NOMATCH_MASK 0x1000000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_LUT_READ_ERROR                             */
+/*   Description:  LUT Read Error                                       */
+#define SH_NI1_ERROR_OVERFLOW_2_LUT_READ_ERROR_SHFT 61
+#define SH_NI1_ERROR_OVERFLOW_2_LUT_READ_ERROR_MASK 0x2000000000000000
+
+/*   SH_NI1_ERROR_OVERFLOW_2_RETRY_TIMEOUT_ERROR                        */
+/*   Description:  Retry Timeout Error                                  */
+#define SH_NI1_ERROR_OVERFLOW_2_RETRY_TIMEOUT_ERROR_SHFT 62
+#define SH_NI1_ERROR_OVERFLOW_2_RETRY_TIMEOUT_ERROR_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*               Register "SH_NI1_ERROR_OVERFLOW_2_ALIAS"               */
+/*                    ni1 Error Overflow Bits Alias                     */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_OVERFLOW_2_ALIAS            0x0000000150040638
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_ERROR_MASK_1"                    */
+/*                         ni1  Error Mask Bits                         */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_MASK_1                      0x0000000150040640
+#define SH_NI1_ERROR_MASK_1_MASK                 0xffffffffffffffff
+#define SH_NI1_ERROR_MASK_1_INIT                 0xffffffffffffffff
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT0                         */
+/*   Description:  Fifo 02 debit0 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT0_SHFT 0
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT2                         */
+/*   Description:  Fifo 02 debit2 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT2_SHFT 1
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT0                         */
+/*   Description:  Fifo 13 debit0 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT0_SHFT 2
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT2                         */
+/*   Description:  Fifo 13 debit2 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT2_SHFT 3
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_POP                        */
+/*   Description:  Fifo 02 vc0 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_POP                        */
+/*   Description:  Fifo 02 vc2 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_POP                        */
+/*   Description:  Fifo 13 vc1 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_POP                        */
+/*   Description:  Fifo 13 vc3 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_PUSH                       */
+/*   Description:  Fifo 02 vc0 push overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_PUSH                       */
+/*   Description:  Fifo 02 vc2 push overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_PUSH                       */
+/*   Description:  Fifo 13 vc1 push overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_PUSH                       */
+/*   Description:  Fifo 13 vc3 push overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_CREDIT                     */
+/*   Description:  Fifo 02 vc0 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_CREDIT                     */
+/*   Description:  Fifo 02 vc2 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC0_CREDIT                     */
+/*   Description:  Fifo 13 vc0 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC2_CREDIT                     */
+/*   Description:  Fifo 13 vc2 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW0_VC0_CREDIT                           */
+/*   Description:  VC0 credit overflow 0                                */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI1_ERROR_MASK_1_OVERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW1_VC0_CREDIT                           */
+/*   Description:  VC0 credit overflow 1                                */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI1_ERROR_MASK_1_OVERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW2_VC0_CREDIT                           */
+/*   Description:  VC0 credit overflow 2                                */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI1_ERROR_MASK_1_OVERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW0_VC2_CREDIT                           */
+/*   Description:  VC2 credit overflow 0                                */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI1_ERROR_MASK_1_OVERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW1_VC2_CREDIT                           */
+/*   Description:  VC2 credit overflow 1                                */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI1_ERROR_MASK_1_OVERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW2_VC2_CREDIT                           */
+/*   Description:  VC2 credit overflow 2                                */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI1_ERROR_MASK_1_OVERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT0                        */
+/*   Description:  PI Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT0_SHFT 22
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT0_MASK 0x0000000000400000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT2                        */
+/*   Description:  PI Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT2_SHFT 23
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_DEBIT2_MASK 0x0000000000800000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT0                      */
+/*   Description:  IILB Fifo debit0 overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT0_SHFT 24
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT0_MASK 0x0000000001000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT2                      */
+/*   Description:  IILB Fifo debit2 overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT2_SHFT 25
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_DEBIT2_MASK 0x0000000002000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT0                        */
+/*   Description:  MD Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT0_SHFT 26
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT0_MASK 0x0000000004000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT2                        */
+/*   Description:  MD Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT2_SHFT 27
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_DEBIT2_MASK 0x0000000008000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT0                        */
+/*   Description:  NI Fifo debit0 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT0_SHFT 28
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT0_MASK 0x0000000010000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT1                        */
+/*   Description:  NI Fifo debit1 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT1_SHFT 29
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT1_MASK 0x0000000020000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT2                        */
+/*   Description:  NI Fifo debit2 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT2_SHFT 30
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT2_MASK 0x0000000040000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT3                        */
+/*   Description:  NI Fifo debit3 overflow                              */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT3_SHFT 31
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_DEBIT3_MASK 0x0000000080000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_POP                       */
+/*   Description:  PI Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_POP                       */
+/*   Description:  PI Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_POP                     */
+/*   Description:  IILB Fifo vc0 pop overflow                           */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_POP                     */
+/*   Description:  IILB Fifo vc2 pop overflow                           */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_POP                       */
+/*   Description:  MD Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_POP                       */
+/*   Description:  MD Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_POP                       */
+/*   Description:  NI Fifo vc0 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_POP                       */
+/*   Description:  NI Fifo vc2 pop overflow                             */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_PUSH                      */
+/*   Description:  PI Fifo vc0 push overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_PUSH                      */
+/*   Description:  PI Fifo vc2 push overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_PUSH                    */
+/*   Description:  IILB Fifo vc0 push overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_PUSH                    */
+/*   Description:  IILB Fifo vc2 push overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_PUSH                      */
+/*   Description:  MD Fifo vc0 push overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_PUSH                      */
+/*   Description:  MD Fifo vc2 push overflow                            */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_CREDIT                    */
+/*   Description:  PI Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_CREDIT                    */
+/*   Description:  PI Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_CREDIT                  */
+/*   Description:  IILB Fifo vc0 credit overflow                        */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_CREDIT                  */
+/*   Description:  IILB Fifo vc2 credit overflow                        */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_CREDIT                    */
+/*   Description:  MD Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_CREDIT                    */
+/*   Description:  MD Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_CREDIT                    */
+/*   Description:  NI Fifo vc0 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC1_CREDIT                    */
+/*   Description:  NI Fifo vc1 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_CREDIT                    */
+/*   Description:  NI Fifo vc2 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC3_CREDIT                    */
+/*   Description:  NI Fifo vc3 credit overflow                          */
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI1_ERROR_MASK_1_OVERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC0                        */
+/*   Description:  Fifo02 vc0 tail timeout                              */
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC0_SHFT 56
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC0_MASK 0x0100000000000000
+
+/*   SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC2                        */
+/*   Description:  Fifo02 vc2 tail timeout                              */
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC2_SHFT 57
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO02_VC2_MASK 0x0200000000000000
+
+/*   SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC1                        */
+/*   Description:  Fifo13 vc1 tail timeout                              */
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC1_SHFT 58
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC1_MASK 0x0400000000000000
+
+/*   SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC3                        */
+/*   Description:  Fifo13 vc3 tail timeout                              */
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC3_SHFT 59
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_FIFO13_VC3_MASK 0x0800000000000000
+
+/*   SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC0                            */
+/*   Description:  NI vc0 tail timeout                                  */
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC0_SHFT 60
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC0_MASK 0x1000000000000000
+
+/*   SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC1                            */
+/*   Description:  NI vc1 tail timeout                                  */
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC1_SHFT 61
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC1_MASK 0x2000000000000000
+
+/*   SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC2                            */
+/*   Description:  NI vc2 tail timeout                                  */
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC2_SHFT 62
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC2_MASK 0x4000000000000000
+
+/*   SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC3                            */
+/*   Description:  NI vc3 tail timeout                                  */
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC3_SHFT 63
+#define SH_NI1_ERROR_MASK_1_TAIL_TIMEOUT_NI_VC3_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_ERROR_MASK_2"                    */
+/*                         ni1  Error Mask Bits                         */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_MASK_2                      0x0000000150040650
+#define SH_NI1_ERROR_MASK_2_MASK                 0x7fffffff003fffff
+#define SH_NI1_ERROR_MASK_2_INIT                 0x7fffffff003fffff
+
+/*   SH_NI1_ERROR_MASK_2_ILLEGAL_VCNI                                   */
+/*   Description:  Illegal VC NI                                        */
+#define SH_NI1_ERROR_MASK_2_ILLEGAL_VCNI_SHFT    0
+#define SH_NI1_ERROR_MASK_2_ILLEGAL_VCNI_MASK    0x0000000000000001
+
+/*   SH_NI1_ERROR_MASK_2_ILLEGAL_VCPI                                   */
+/*   Description:  Illegal VC PI                                        */
+#define SH_NI1_ERROR_MASK_2_ILLEGAL_VCPI_SHFT    1
+#define SH_NI1_ERROR_MASK_2_ILLEGAL_VCPI_MASK    0x0000000000000002
+
+/*   SH_NI1_ERROR_MASK_2_ILLEGAL_VCMD                                   */
+/*   Description:  Illegal VC MD                                        */
+#define SH_NI1_ERROR_MASK_2_ILLEGAL_VCMD_SHFT    2
+#define SH_NI1_ERROR_MASK_2_ILLEGAL_VCMD_MASK    0x0000000000000004
+
+/*   SH_NI1_ERROR_MASK_2_ILLEGAL_VCIILB                                 */
+/*   Description:  Illegal VC IILB                                      */
+#define SH_NI1_ERROR_MASK_2_ILLEGAL_VCIILB_SHFT  3
+#define SH_NI1_ERROR_MASK_2_ILLEGAL_VCIILB_MASK  0x0000000000000008
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_POP                       */
+/*   Description:  Fifo 02 vc0 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_POP                       */
+/*   Description:  Fifo 02 vc2 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_POP                       */
+/*   Description:  Fifo 13 vc1 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_POP                       */
+/*   Description:  Fifo 13 vc3 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_PUSH                      */
+/*   Description:  Fifo 02 vc0 push underflow                           */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_PUSH                      */
+/*   Description:  Fifo 02 vc2 push underflow                           */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_PUSH                      */
+/*   Description:  Fifo 13 vc1 push underflow                           */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_PUSH                      */
+/*   Description:  Fifo 13 vc3 push underflow                           */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_CREDIT                    */
+/*   Description:  Fifo 02 vc0 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_CREDIT                    */
+/*   Description:  Fifo 02 vc2 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC0_CREDIT                    */
+/*   Description:  Fifo 13 vc0 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC2_CREDIT                    */
+/*   Description:  Fifo 13 vc2 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW0_VC0_CREDIT                          */
+/*   Description:  VC0 credit underflow 0                               */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW1_VC0_CREDIT                          */
+/*   Description:  VC0 credit underflow 1                               */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW2_VC0_CREDIT                          */
+/*   Description:  VC0 credit underflow 2                               */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW0_VC2_CREDIT                          */
+/*   Description:  VC2 credit underflow 0                               */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW1_VC2_CREDIT                          */
+/*   Description:  VC2 credit underflow 1                               */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW2_VC2_CREDIT                          */
+/*   Description:  VC2 credit underflow 2                               */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_POP                      */
+/*   Description:  PI Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_POP                      */
+/*   Description:  PI Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_POP                    */
+/*   Description:  IILB Fifo vc0 pop underflow                          */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_POP                    */
+/*   Description:  IILB Fifo vc2 pop underflow                          */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_POP                      */
+/*   Description:  MD Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_POP                      */
+/*   Description:  MD Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_POP                      */
+/*   Description:  NI Fifo vc0 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_POP                      */
+/*   Description:  NI Fifo vc2 pop underflow                            */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_PUSH                     */
+/*   Description:  PI Fifo vc0 push underflow                           */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_PUSH                     */
+/*   Description:  PI Fifo vc2 push underflow                           */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_PUSH                   */
+/*   Description:  IILB Fifo vc0 push underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_PUSH                   */
+/*   Description:  IILB Fifo vc2 push underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_PUSH                     */
+/*   Description:  MD Fifo vc0 push underflow                           */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_PUSH                     */
+/*   Description:  MD Fifo vc2 push underflow                           */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_CREDIT                   */
+/*   Description:  PI Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_CREDIT                   */
+/*   Description:  PI Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT                 */
+/*   Description:  IILB Fifo vc0 credit underflow                       */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT                 */
+/*   Description:  IILB Fifo vc2 credit underflow                       */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_CREDIT                   */
+/*   Description:  MD Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_CREDIT                   */
+/*   Description:  MD Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_CREDIT                   */
+/*   Description:  NI Fifo vc0 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC1_CREDIT                   */
+/*   Description:  NI Fifo vc1 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_CREDIT                   */
+/*   Description:  NI Fifo vc2 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC3_CREDIT                   */
+/*   Description:  NI Fifo vc3 credit underflow                         */
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI1_ERROR_MASK_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC0                               */
+/*   Description:  llp deadlock vc0                                     */
+#define SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC0_SHFT 56
+#define SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC0_MASK 0x0100000000000000
+
+/*   SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC1                               */
+/*   Description:  llp deadlock vc1                                     */
+#define SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC1_SHFT 57
+#define SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC1_MASK 0x0200000000000000
+
+/*   SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC2                               */
+/*   Description:  llp deadlock vc2                                     */
+#define SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC2_SHFT 58
+#define SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC2_MASK 0x0400000000000000
+
+/*   SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC3                               */
+/*   Description:  llp deadlock vc3                                     */
+#define SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC3_SHFT 59
+#define SH_NI1_ERROR_MASK_2_LLP_DEADLOCK_VC3_MASK 0x0800000000000000
+
+/*   SH_NI1_ERROR_MASK_2_CHIPLET_NOMATCH                                */
+/*   Description:  chiplet nomatch                                      */
+#define SH_NI1_ERROR_MASK_2_CHIPLET_NOMATCH_SHFT 60
+#define SH_NI1_ERROR_MASK_2_CHIPLET_NOMATCH_MASK 0x1000000000000000
+
+/*   SH_NI1_ERROR_MASK_2_LUT_READ_ERROR                                 */
+/*   Description:  LUT Read Error                                       */
+#define SH_NI1_ERROR_MASK_2_LUT_READ_ERROR_SHFT  61
+#define SH_NI1_ERROR_MASK_2_LUT_READ_ERROR_MASK  0x2000000000000000
+
+/*   SH_NI1_ERROR_MASK_2_RETRY_TIMEOUT_ERROR                            */
+/*   Description:  Retry Timeout Error                                  */
+#define SH_NI1_ERROR_MASK_2_RETRY_TIMEOUT_ERROR_SHFT 62
+#define SH_NI1_ERROR_MASK_2_RETRY_TIMEOUT_ERROR_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_FIRST_ERROR_1"                    */
+/*                        ni1  First Error Bits                         */
+/* ==================================================================== */
+
+#define SH_NI1_FIRST_ERROR_1                     0x0000000150040660
+#define SH_NI1_FIRST_ERROR_1_MASK                0xffffffffffffffff
+#define SH_NI1_FIRST_ERROR_1_INIT                0xffffffffffffffff
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT0                        */
+/*   Description:  Fifo 02 debit0 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT0_SHFT 0
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT2                        */
+/*   Description:  Fifo 02 debit2 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT2_SHFT 1
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT0                        */
+/*   Description:  Fifo 13 debit0 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT0_SHFT 2
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT2                        */
+/*   Description:  Fifo 13 debit2 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT2_SHFT 3
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_POP                       */
+/*   Description:  Fifo 02 vc0 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_POP                       */
+/*   Description:  Fifo 02 vc2 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_POP                       */
+/*   Description:  Fifo 13 vc1 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_POP                       */
+/*   Description:  Fifo 13 vc3 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_PUSH                      */
+/*   Description:  Fifo 02 vc0 push overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_PUSH                      */
+/*   Description:  Fifo 02 vc2 push overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_PUSH                      */
+/*   Description:  Fifo 13 vc1 push overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_PUSH                      */
+/*   Description:  Fifo 13 vc3 push overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_CREDIT                    */
+/*   Description:  Fifo 02 vc0 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_CREDIT                    */
+/*   Description:  Fifo 02 vc2 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC0_CREDIT                    */
+/*   Description:  Fifo 13 vc0 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC2_CREDIT                    */
+/*   Description:  Fifo 13 vc2 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW0_VC0_CREDIT                          */
+/*   Description:  VC0 credit overflow 0                                */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW1_VC0_CREDIT                          */
+/*   Description:  VC0 credit overflow 1                                */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW2_VC0_CREDIT                          */
+/*   Description:  VC0 credit overflow 2                                */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW0_VC2_CREDIT                          */
+/*   Description:  VC2 credit overflow 0                                */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW1_VC2_CREDIT                          */
+/*   Description:  VC2 credit overflow 1                                */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW2_VC2_CREDIT                          */
+/*   Description:  VC2 credit overflow 2                                */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT0                       */
+/*   Description:  PI Fifo debit0 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT0_SHFT 22
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT0_MASK 0x0000000000400000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT2                       */
+/*   Description:  PI Fifo debit2 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT2_SHFT 23
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_DEBIT2_MASK 0x0000000000800000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT0                     */
+/*   Description:  IILB Fifo debit0 overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT0_SHFT 24
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT0_MASK 0x0000000001000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT2                     */
+/*   Description:  IILB Fifo debit2 overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT2_SHFT 25
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_DEBIT2_MASK 0x0000000002000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT0                       */
+/*   Description:  MD Fifo debit0 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT0_SHFT 26
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT0_MASK 0x0000000004000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT2                       */
+/*   Description:  MD Fifo debit2 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT2_SHFT 27
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_DEBIT2_MASK 0x0000000008000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT0                       */
+/*   Description:  NI Fifo debit0 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT0_SHFT 28
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT0_MASK 0x0000000010000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT1                       */
+/*   Description:  NI Fifo debit1 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT1_SHFT 29
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT1_MASK 0x0000000020000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT2                       */
+/*   Description:  NI Fifo debit2 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT2_SHFT 30
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT2_MASK 0x0000000040000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT3                       */
+/*   Description:  NI Fifo debit3 overflow                              */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT3_SHFT 31
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_DEBIT3_MASK 0x0000000080000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_POP                      */
+/*   Description:  PI Fifo vc0 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_POP                      */
+/*   Description:  PI Fifo vc2 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_POP                    */
+/*   Description:  IILB Fifo vc0 pop overflow                           */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_POP                    */
+/*   Description:  IILB Fifo vc2 pop overflow                           */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_POP                      */
+/*   Description:  MD Fifo vc0 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_POP                      */
+/*   Description:  MD Fifo vc2 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_POP                      */
+/*   Description:  NI Fifo vc0 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_POP                      */
+/*   Description:  NI Fifo vc2 pop overflow                             */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_PUSH                     */
+/*   Description:  PI Fifo vc0 push overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_PUSH                     */
+/*   Description:  PI Fifo vc2 push overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_PUSH                   */
+/*   Description:  IILB Fifo vc0 push overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_PUSH                   */
+/*   Description:  IILB Fifo vc2 push overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_PUSH                     */
+/*   Description:  MD Fifo vc0 push overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_PUSH                     */
+/*   Description:  MD Fifo vc2 push overflow                            */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_CREDIT                   */
+/*   Description:  PI Fifo vc0 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_CREDIT                   */
+/*   Description:  PI Fifo vc2 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_CREDIT                 */
+/*   Description:  IILB Fifo vc0 credit overflow                        */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_CREDIT                 */
+/*   Description:  IILB Fifo vc2 credit overflow                        */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_CREDIT                   */
+/*   Description:  MD Fifo vc0 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_CREDIT                   */
+/*   Description:  MD Fifo vc2 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_CREDIT                   */
+/*   Description:  NI Fifo vc0 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC1_CREDIT                   */
+/*   Description:  NI Fifo vc1 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_CREDIT                   */
+/*   Description:  NI Fifo vc2 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC3_CREDIT                   */
+/*   Description:  NI Fifo vc3 credit overflow                          */
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI1_FIRST_ERROR_1_OVERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC0                       */
+/*   Description:  Fifo02 vc0 tail timeout                              */
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC0_SHFT 56
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC0_MASK 0x0100000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC2                       */
+/*   Description:  Fifo02 vc2 tail timeout                              */
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC2_SHFT 57
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO02_VC2_MASK 0x0200000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC1                       */
+/*   Description:  Fifo13 vc1 tail timeout                              */
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC1_SHFT 58
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC1_MASK 0x0400000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC3                       */
+/*   Description:  Fifo13 vc3 tail timeout                              */
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC3_SHFT 59
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_FIFO13_VC3_MASK 0x0800000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC0                           */
+/*   Description:  NI vc0 tail timeout                                  */
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC0_SHFT 60
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC0_MASK 0x1000000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC1                           */
+/*   Description:  NI vc1 tail timeout                                  */
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC1_SHFT 61
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC1_MASK 0x2000000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC2                           */
+/*   Description:  NI vc2 tail timeout                                  */
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC2_SHFT 62
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC2_MASK 0x4000000000000000
+
+/*   SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC3                           */
+/*   Description:  NI vc3 tail timeout                                  */
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC3_SHFT 63
+#define SH_NI1_FIRST_ERROR_1_TAIL_TIMEOUT_NI_VC3_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_FIRST_ERROR_2"                    */
+/*                         ni1 First Error Bits                         */
+/* ==================================================================== */
+
+#define SH_NI1_FIRST_ERROR_2                     0x0000000150040670
+#define SH_NI1_FIRST_ERROR_2_MASK                0x7fffffff003fffff
+#define SH_NI1_FIRST_ERROR_2_INIT                0x7fffffff003fffff
+
+/*   SH_NI1_FIRST_ERROR_2_ILLEGAL_VCNI                                  */
+/*   Description:  Illegal VC NI                                        */
+#define SH_NI1_FIRST_ERROR_2_ILLEGAL_VCNI_SHFT   0
+#define SH_NI1_FIRST_ERROR_2_ILLEGAL_VCNI_MASK   0x0000000000000001
+
+/*   SH_NI1_FIRST_ERROR_2_ILLEGAL_VCPI                                  */
+/*   Description:  Illegal VC PI                                        */
+#define SH_NI1_FIRST_ERROR_2_ILLEGAL_VCPI_SHFT   1
+#define SH_NI1_FIRST_ERROR_2_ILLEGAL_VCPI_MASK   0x0000000000000002
+
+/*   SH_NI1_FIRST_ERROR_2_ILLEGAL_VCMD                                  */
+/*   Description:  Illegal VC MD                                        */
+#define SH_NI1_FIRST_ERROR_2_ILLEGAL_VCMD_SHFT   2
+#define SH_NI1_FIRST_ERROR_2_ILLEGAL_VCMD_MASK   0x0000000000000004
+
+/*   SH_NI1_FIRST_ERROR_2_ILLEGAL_VCIILB                                */
+/*   Description:  Illegal VC IILB                                      */
+#define SH_NI1_FIRST_ERROR_2_ILLEGAL_VCIILB_SHFT 3
+#define SH_NI1_FIRST_ERROR_2_ILLEGAL_VCIILB_MASK 0x0000000000000008
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_POP                      */
+/*   Description:  Fifo 02 vc0 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_POP_SHFT 4
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_POP_MASK 0x0000000000000010
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_POP                      */
+/*   Description:  Fifo 02 vc2 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_POP_SHFT 5
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_POP_MASK 0x0000000000000020
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_POP                      */
+/*   Description:  Fifo 13 vc1 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_POP_SHFT 6
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_POP_MASK 0x0000000000000040
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_POP                      */
+/*   Description:  Fifo 13 vc3 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_POP_SHFT 7
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_POP_MASK 0x0000000000000080
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_PUSH                     */
+/*   Description:  Fifo 02 vc0 push underflow                           */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_PUSH_SHFT 8
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_PUSH_MASK 0x0000000000000100
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_PUSH                     */
+/*   Description:  Fifo 02 vc2 push underflow                           */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_PUSH_SHFT 9
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_PUSH_MASK 0x0000000000000200
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_PUSH                     */
+/*   Description:  Fifo 13 vc1 push underflow                           */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_PUSH_SHFT 10
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC1_PUSH_MASK 0x0000000000000400
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_PUSH                     */
+/*   Description:  Fifo 13 vc3 push underflow                           */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_PUSH_SHFT 11
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC3_PUSH_MASK 0x0000000000000800
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_CREDIT                   */
+/*   Description:  Fifo 02 vc0 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_CREDIT_SHFT 12
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_CREDIT                   */
+/*   Description:  Fifo 02 vc2 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_CREDIT_SHFT 13
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO02_VC2_CREDIT_MASK 0x0000000000002000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC0_CREDIT                   */
+/*   Description:  Fifo 13 vc0 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC0_CREDIT_SHFT 14
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC0_CREDIT_MASK 0x0000000000004000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC2_CREDIT                   */
+/*   Description:  Fifo 13 vc2 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC2_CREDIT_SHFT 15
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_FIFO13_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW0_VC0_CREDIT                         */
+/*   Description:  VC0 credit underflow 0                               */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW0_VC0_CREDIT_SHFT 16
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW0_VC0_CREDIT_MASK 0x0000000000010000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW1_VC0_CREDIT                         */
+/*   Description:  VC0 credit underflow 1                               */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW1_VC0_CREDIT_SHFT 17
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW1_VC0_CREDIT_MASK 0x0000000000020000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW2_VC0_CREDIT                         */
+/*   Description:  VC0 credit underflow 2                               */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW2_VC0_CREDIT_SHFT 18
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW2_VC0_CREDIT_MASK 0x0000000000040000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW0_VC2_CREDIT                         */
+/*   Description:  VC2 credit underflow 0                               */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW0_VC2_CREDIT_SHFT 19
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW0_VC2_CREDIT_MASK 0x0000000000080000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW1_VC2_CREDIT                         */
+/*   Description:  VC2 credit underflow 1                               */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW1_VC2_CREDIT_SHFT 20
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW1_VC2_CREDIT_MASK 0x0000000000100000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW2_VC2_CREDIT                         */
+/*   Description:  VC2 credit underflow 2                               */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW2_VC2_CREDIT_SHFT 21
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW2_VC2_CREDIT_MASK 0x0000000000200000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_POP                     */
+/*   Description:  PI Fifo vc0 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_POP_SHFT 32
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_POP_MASK 0x0000000100000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_POP                     */
+/*   Description:  PI Fifo vc2 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_POP_SHFT 33
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_POP_MASK 0x0000000200000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_POP                   */
+/*   Description:  IILB Fifo vc0 pop underflow                          */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_POP_SHFT 34
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_POP_MASK 0x0000000400000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_POP                   */
+/*   Description:  IILB Fifo vc2 pop underflow                          */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_POP_SHFT 35
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_POP_MASK 0x0000000800000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_POP                     */
+/*   Description:  MD Fifo vc0 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_POP_SHFT 36
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_POP_MASK 0x0000001000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_POP                     */
+/*   Description:  MD Fifo vc2 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_POP_SHFT 37
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_POP_MASK 0x0000002000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_POP                     */
+/*   Description:  NI Fifo vc0 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_POP_SHFT 38
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_POP_MASK 0x0000004000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_POP                     */
+/*   Description:  NI Fifo vc2 pop underflow                            */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_POP_SHFT 39
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_POP_MASK 0x0000008000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_PUSH                    */
+/*   Description:  PI Fifo vc0 push underflow                           */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_PUSH_SHFT 40
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_PUSH_MASK 0x0000010000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_PUSH                    */
+/*   Description:  PI Fifo vc2 push underflow                           */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_PUSH_SHFT 41
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_PUSH_MASK 0x0000020000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_PUSH                  */
+/*   Description:  IILB Fifo vc0 push underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_SHFT 42
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_PUSH_MASK 0x0000040000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_PUSH                  */
+/*   Description:  IILB Fifo vc2 push underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_SHFT 43
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_PUSH_MASK 0x0000080000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_PUSH                    */
+/*   Description:  MD Fifo vc0 push underflow                           */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_PUSH_SHFT 44
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_PUSH_MASK 0x0000100000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_PUSH                    */
+/*   Description:  MD Fifo vc2 push underflow                           */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_PUSH_SHFT 45
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_PUSH_MASK 0x0000200000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_CREDIT                  */
+/*   Description:  PI Fifo vc0 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_SHFT 46
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_CREDIT                  */
+/*   Description:  PI Fifo vc2 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_SHFT 47
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_PI_FIFO_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT                */
+/*   Description:  IILB Fifo vc0 credit underflow                       */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_SHFT 48
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC0_CREDIT_MASK 0x0001000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT                */
+/*   Description:  IILB Fifo vc2 credit underflow                       */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_SHFT 49
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_IILB_FIFO_VC2_CREDIT_MASK 0x0002000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_CREDIT                  */
+/*   Description:  MD Fifo vc0 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_SHFT 50
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC0_CREDIT_MASK 0x0004000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_CREDIT                  */
+/*   Description:  MD Fifo vc2 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_SHFT 51
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_MD_FIFO_VC2_CREDIT_MASK 0x0008000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_CREDIT                  */
+/*   Description:  NI Fifo vc0 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_SHFT 52
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC0_CREDIT_MASK 0x0010000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC1_CREDIT                  */
+/*   Description:  NI Fifo vc1 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_SHFT 53
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC1_CREDIT_MASK 0x0020000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_CREDIT                  */
+/*   Description:  NI Fifo vc2 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_SHFT 54
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC2_CREDIT_MASK 0x0040000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC3_CREDIT                  */
+/*   Description:  NI Fifo vc3 credit underflow                         */
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_SHFT 55
+#define SH_NI1_FIRST_ERROR_2_UNDERFLOW_NI_FIFO_VC3_CREDIT_MASK 0x0080000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC0                              */
+/*   Description:  llp deadlock vc0                                     */
+#define SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC0_SHFT 56
+#define SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC0_MASK 0x0100000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC1                              */
+/*   Description:  llp deadlock vc1                                     */
+#define SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC1_SHFT 57
+#define SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC1_MASK 0x0200000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC2                              */
+/*   Description:  llp deadlock vc2                                     */
+#define SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC2_SHFT 58
+#define SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC2_MASK 0x0400000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC3                              */
+/*   Description:  llp deadlock vc3                                     */
+#define SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC3_SHFT 59
+#define SH_NI1_FIRST_ERROR_2_LLP_DEADLOCK_VC3_MASK 0x0800000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_CHIPLET_NOMATCH                               */
+/*   Description:  chiplet nomatch                                      */
+#define SH_NI1_FIRST_ERROR_2_CHIPLET_NOMATCH_SHFT 60
+#define SH_NI1_FIRST_ERROR_2_CHIPLET_NOMATCH_MASK 0x1000000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_LUT_READ_ERROR                                */
+/*   Description:  LUT Read Error                                       */
+#define SH_NI1_FIRST_ERROR_2_LUT_READ_ERROR_SHFT 61
+#define SH_NI1_FIRST_ERROR_2_LUT_READ_ERROR_MASK 0x2000000000000000
+
+/*   SH_NI1_FIRST_ERROR_2_RETRY_TIMEOUT_ERROR                           */
+/*   Description:  Retry Timeout Error                                  */
+#define SH_NI1_FIRST_ERROR_2_RETRY_TIMEOUT_ERROR_SHFT 62
+#define SH_NI1_FIRST_ERROR_2_RETRY_TIMEOUT_ERROR_MASK 0x4000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_ERROR_DETAIL_1"                   */
+/*                ni1 Chiplet no match header bits 63:0                 */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_DETAIL_1                    0x0000000150040680
+#define SH_NI1_ERROR_DETAIL_1_MASK               0xffffffffffffffff
+#define SH_NI1_ERROR_DETAIL_1_INIT               0x0000000000000000
+
+/*   SH_NI1_ERROR_DETAIL_1_HEADER                                       */
+/*   Description:  Header bits 63:0                                     */
+#define SH_NI1_ERROR_DETAIL_1_HEADER_SHFT        0
+#define SH_NI1_ERROR_DETAIL_1_HEADER_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_ERROR_DETAIL_2"                   */
+/*               ni1 Chiplet no match header bits 127:64                */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_DETAIL_2                    0x0000000150040690
+#define SH_NI1_ERROR_DETAIL_2_MASK               0xffffffffffffffff
+#define SH_NI1_ERROR_DETAIL_2_INIT               0x0000000000000000
+
+/*   SH_NI1_ERROR_DETAIL_2_HEADER                                       */
+/*   Description:  Header bits 127:64                                   */
+#define SH_NI1_ERROR_DETAIL_2_HEADER_SHFT        0
+#define SH_NI1_ERROR_DETAIL_2_HEADER_MASK        0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_CORRECTED_DETAIL_1"                  */
+/*                       Corrected error details                        */
+/* ==================================================================== */
+
+#define SH_XN_CORRECTED_DETAIL_1                 0x0000000150040070
+#define SH_XN_CORRECTED_DETAIL_1_MASK            0x0fff0fff0fff0fff
+#define SH_XN_CORRECTED_DETAIL_1_INIT            0x0000000000000000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC0_SYNDROME                             */
+/*   Description:  ECC0 Syndrome                                        */
+#define SH_XN_CORRECTED_DETAIL_1_ECC0_SYNDROME_SHFT 0
+#define SH_XN_CORRECTED_DETAIL_1_ECC0_SYNDROME_MASK 0x00000000000000ff
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC0_WC                                   */
+/*   Description:  ECC0 Word Count                                      */
+#define SH_XN_CORRECTED_DETAIL_1_ECC0_WC_SHFT    8
+#define SH_XN_CORRECTED_DETAIL_1_ECC0_WC_MASK    0x0000000000000300
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC0_VC                                   */
+/*   Description:  ECC0 Virtual Channel                                 */
+#define SH_XN_CORRECTED_DETAIL_1_ECC0_VC_SHFT    10
+#define SH_XN_CORRECTED_DETAIL_1_ECC0_VC_MASK    0x0000000000000c00
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC1_SYNDROME                             */
+/*   Description:  ECC1 Syndrome                                        */
+#define SH_XN_CORRECTED_DETAIL_1_ECC1_SYNDROME_SHFT 16
+#define SH_XN_CORRECTED_DETAIL_1_ECC1_SYNDROME_MASK 0x0000000000ff0000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC1_WC                                   */
+/*   Description:  ECC1 Word Count                                      */
+#define SH_XN_CORRECTED_DETAIL_1_ECC1_WC_SHFT    24
+#define SH_XN_CORRECTED_DETAIL_1_ECC1_WC_MASK    0x0000000003000000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC1_VC                                   */
+/*   Description:  ECC1 Virtual Channel                                 */
+#define SH_XN_CORRECTED_DETAIL_1_ECC1_VC_SHFT    26
+#define SH_XN_CORRECTED_DETAIL_1_ECC1_VC_MASK    0x000000000c000000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC2_SYNDROME                             */
+/*   Description:  ECC2 Syndrome                                        */
+#define SH_XN_CORRECTED_DETAIL_1_ECC2_SYNDROME_SHFT 32
+#define SH_XN_CORRECTED_DETAIL_1_ECC2_SYNDROME_MASK 0x000000ff00000000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC2_WC                                   */
+/*   Description:  ECC2 Word Count                                      */
+#define SH_XN_CORRECTED_DETAIL_1_ECC2_WC_SHFT    40
+#define SH_XN_CORRECTED_DETAIL_1_ECC2_WC_MASK    0x0000030000000000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC2_VC                                   */
+/*   Description:  ECC2 Virtual Channel                                 */
+#define SH_XN_CORRECTED_DETAIL_1_ECC2_VC_SHFT    42
+#define SH_XN_CORRECTED_DETAIL_1_ECC2_VC_MASK    0x00000c0000000000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC3_SYNDROME                             */
+/*   Description:  ECC3 Syndrome                                        */
+#define SH_XN_CORRECTED_DETAIL_1_ECC3_SYNDROME_SHFT 48
+#define SH_XN_CORRECTED_DETAIL_1_ECC3_SYNDROME_MASK 0x00ff000000000000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC3_WC                                   */
+/*   Description:  ECC3 Word Count                                      */
+#define SH_XN_CORRECTED_DETAIL_1_ECC3_WC_SHFT    56
+#define SH_XN_CORRECTED_DETAIL_1_ECC3_WC_MASK    0x0300000000000000
+
+/*   SH_XN_CORRECTED_DETAIL_1_ECC3_VC                                   */
+/*   Description:  ECC3 Virtual Channel                                 */
+#define SH_XN_CORRECTED_DETAIL_1_ECC3_VC_SHFT    58
+#define SH_XN_CORRECTED_DETAIL_1_ECC3_VC_MASK    0x0c00000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_XN_CORRECTED_DETAIL_2"                  */
+/*                         Corrected error data                         */
+/* ==================================================================== */
+
+#define SH_XN_CORRECTED_DETAIL_2                 0x0000000150040080
+#define SH_XN_CORRECTED_DETAIL_2_MASK            0xffffffffffffffff
+#define SH_XN_CORRECTED_DETAIL_2_INIT            0x0000000000000000
+
+/*   SH_XN_CORRECTED_DETAIL_2_DATA                                      */
+/*   Description:  ECC data                                             */
+#define SH_XN_CORRECTED_DETAIL_2_DATA_SHFT       0
+#define SH_XN_CORRECTED_DETAIL_2_DATA_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_CORRECTED_DETAIL_3"                  */
+/*                       Corrected error header0                        */
+/* ==================================================================== */
+
+#define SH_XN_CORRECTED_DETAIL_3                 0x0000000150040090
+#define SH_XN_CORRECTED_DETAIL_3_MASK            0xffffffffffffffff
+#define SH_XN_CORRECTED_DETAIL_3_INIT            0x0000000000000000
+
+/*   SH_XN_CORRECTED_DETAIL_3_HEADER0                                   */
+/*   Description:  ECC header0 (bits 63 - 0)                            */
+#define SH_XN_CORRECTED_DETAIL_3_HEADER0_SHFT    0
+#define SH_XN_CORRECTED_DETAIL_3_HEADER0_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XN_CORRECTED_DETAIL_4"                  */
+/*                       Corrected error header1                        */
+/* ==================================================================== */
+
+#define SH_XN_CORRECTED_DETAIL_4                 0x00000001500400a0
+#define SH_XN_CORRECTED_DETAIL_4_MASK            0xc00003ffffffffff
+#define SH_XN_CORRECTED_DETAIL_4_INIT            0x0000000000000000
+
+/*   SH_XN_CORRECTED_DETAIL_4_HEADER1                                   */
+/*   Description:  ECC header1 (bits 104 - 64)                          */
+#define SH_XN_CORRECTED_DETAIL_4_HEADER1_SHFT    0
+#define SH_XN_CORRECTED_DETAIL_4_HEADER1_MASK    0x000003ffffffffff
+
+/*   SH_XN_CORRECTED_DETAIL_4_ERR_GROUP                                 */
+/*   Description:  Error group                                          */
+#define SH_XN_CORRECTED_DETAIL_4_ERR_GROUP_SHFT  62
+#define SH_XN_CORRECTED_DETAIL_4_ERR_GROUP_MASK  0xc000000000000000
+
+/* ==================================================================== */
+/*                Register "SH_XN_UNCORRECTED_DETAIL_1"                 */
+/*                      Uncorrected error details                       */
+/* ==================================================================== */
+
+#define SH_XN_UNCORRECTED_DETAIL_1               0x00000001500400b0
+#define SH_XN_UNCORRECTED_DETAIL_1_MASK          0x0fff0fff0fff0fff
+#define SH_XN_UNCORRECTED_DETAIL_1_INIT          0x0000000000000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC0_SYNDROME                           */
+/*   Description:  ECC0 Syndrome                                        */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC0_SYNDROME_SHFT 0
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC0_SYNDROME_MASK 0x00000000000000ff
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC0_WC                                 */
+/*   Description:  ECC0 Word Count                                      */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC0_WC_SHFT  8
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC0_WC_MASK  0x0000000000000300
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC0_VC                                 */
+/*   Description:  ECC0 Virtual Channel                                 */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC0_VC_SHFT  10
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC0_VC_MASK  0x0000000000000c00
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC1_SYNDROME                           */
+/*   Description:  ECC1 Syndrome                                        */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC1_SYNDROME_SHFT 16
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC1_SYNDROME_MASK 0x0000000000ff0000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC1_WC                                 */
+/*   Description:  ECC1 Word Count                                      */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC1_WC_SHFT  24
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC1_WC_MASK  0x0000000003000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC1_VC                                 */
+/*   Description:  ECC1 Virtual Channel                                 */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC1_VC_SHFT  26
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC1_VC_MASK  0x000000000c000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC2_SYNDROME                           */
+/*   Description:  ECC2 Syndrome                                        */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC2_SYNDROME_SHFT 32
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC2_SYNDROME_MASK 0x000000ff00000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC2_WC                                 */
+/*   Description:  ECC2 Word Count                                      */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC2_WC_SHFT  40
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC2_WC_MASK  0x0000030000000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC2_VC                                 */
+/*   Description:  ECC2 Virtual Channel                                 */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC2_VC_SHFT  42
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC2_VC_MASK  0x00000c0000000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC3_SYNDROME                           */
+/*   Description:  ECC3 Syndrome                                        */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC3_SYNDROME_SHFT 48
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC3_SYNDROME_MASK 0x00ff000000000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC3_WC                                 */
+/*   Description:  ECC3 Word Count                                      */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC3_WC_SHFT  56
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC3_WC_MASK  0x0300000000000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_1_ECC3_VC                                 */
+/*   Description:  ECC3 Virtual Channel                                 */
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC3_VC_SHFT  58
+#define SH_XN_UNCORRECTED_DETAIL_1_ECC3_VC_MASK  0x0c00000000000000
+
+/* ==================================================================== */
+/*                Register "SH_XN_UNCORRECTED_DETAIL_2"                 */
+/*                        Uncorrected error data                        */
+/* ==================================================================== */
+
+#define SH_XN_UNCORRECTED_DETAIL_2               0x00000001500400c0
+#define SH_XN_UNCORRECTED_DETAIL_2_MASK          0xffffffffffffffff
+#define SH_XN_UNCORRECTED_DETAIL_2_INIT          0x0000000000000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_2_DATA                                    */
+/*   Description:  ECC data                                             */
+#define SH_XN_UNCORRECTED_DETAIL_2_DATA_SHFT     0
+#define SH_XN_UNCORRECTED_DETAIL_2_DATA_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_UNCORRECTED_DETAIL_3"                 */
+/*                      Uncorrected error header0                       */
+/* ==================================================================== */
+
+#define SH_XN_UNCORRECTED_DETAIL_3               0x00000001500400d0
+#define SH_XN_UNCORRECTED_DETAIL_3_MASK          0xffffffffffffffff
+#define SH_XN_UNCORRECTED_DETAIL_3_INIT          0x0000000000000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_3_HEADER0                                 */
+/*   Description:  ECC header0 (bits 63 - 0)                            */
+#define SH_XN_UNCORRECTED_DETAIL_3_HEADER0_SHFT  0
+#define SH_XN_UNCORRECTED_DETAIL_3_HEADER0_MASK  0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_XN_UNCORRECTED_DETAIL_4"                 */
+/*                      Uncorrected error header1                       */
+/* ==================================================================== */
+
+#define SH_XN_UNCORRECTED_DETAIL_4               0x00000001500400e0
+#define SH_XN_UNCORRECTED_DETAIL_4_MASK          0xc00003ffffffffff
+#define SH_XN_UNCORRECTED_DETAIL_4_INIT          0x0000000000000000
+
+/*   SH_XN_UNCORRECTED_DETAIL_4_HEADER1                                 */
+/*   Description:  ECC header1 (bits 104 - 64)                          */
+#define SH_XN_UNCORRECTED_DETAIL_4_HEADER1_SHFT  0
+#define SH_XN_UNCORRECTED_DETAIL_4_HEADER1_MASK  0x000003ffffffffff
+
+/*   SH_XN_UNCORRECTED_DETAIL_4_ERR_GROUP                               */
+/*   Description:  Error group                                          */
+#define SH_XN_UNCORRECTED_DETAIL_4_ERR_GROUP_SHFT 62
+#define SH_XN_UNCORRECTED_DETAIL_4_ERR_GROUP_MASK 0xc000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_XNMD_ERROR_DETAIL_1"                   */
+/*                      Look Up Table Address (md)                      */
+/* ==================================================================== */
+
+#define SH_XNMD_ERROR_DETAIL_1                   0x00000001500400f0
+#define SH_XNMD_ERROR_DETAIL_1_MASK              0x00000000000007ff
+#define SH_XNMD_ERROR_DETAIL_1_INIT              0x0000000000000000
+
+/*   SH_XNMD_ERROR_DETAIL_1_LUT_ADDR                                    */
+/*   Description:  Look Up Table Read Address                           */
+#define SH_XNMD_ERROR_DETAIL_1_LUT_ADDR_SHFT     0
+#define SH_XNMD_ERROR_DETAIL_1_LUT_ADDR_MASK     0x00000000000007ff
+
+/* ==================================================================== */
+/*                  Register "SH_XNPI_ERROR_DETAIL_1"                   */
+/*                      Look Up Table Address (pi)                      */
+/* ==================================================================== */
+
+#define SH_XNPI_ERROR_DETAIL_1                   0x0000000150040100
+#define SH_XNPI_ERROR_DETAIL_1_MASK              0x00000000000007ff
+#define SH_XNPI_ERROR_DETAIL_1_INIT              0x0000000000000000
+
+/*   SH_XNPI_ERROR_DETAIL_1_LUT_ADDR                                    */
+/*   Description:  Look Up Table Read Address                           */
+#define SH_XNPI_ERROR_DETAIL_1_LUT_ADDR_SHFT     0
+#define SH_XNPI_ERROR_DETAIL_1_LUT_ADDR_MASK     0x00000000000007ff
+
+/* ==================================================================== */
+/*                 Register "SH_XNIILB_ERROR_DETAIL_1"                  */
+/*                    Chiplet NoMatch header [63:0]                     */
+/* ==================================================================== */
+
+#define SH_XNIILB_ERROR_DETAIL_1                 0x0000000150040110
+#define SH_XNIILB_ERROR_DETAIL_1_MASK            0xffffffffffffffff
+#define SH_XNIILB_ERROR_DETAIL_1_INIT            0x0000000000000000
+
+/*   SH_XNIILB_ERROR_DETAIL_1_HEADER                                    */
+/*   Description:  header bits [63:0]                                   */
+#define SH_XNIILB_ERROR_DETAIL_1_HEADER_SHFT     0
+#define SH_XNIILB_ERROR_DETAIL_1_HEADER_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XNIILB_ERROR_DETAIL_2"                  */
+/*                   Chiplet NoMatch header [127:64]                    */
+/* ==================================================================== */
+
+#define SH_XNIILB_ERROR_DETAIL_2                 0x0000000150040120
+#define SH_XNIILB_ERROR_DETAIL_2_MASK            0xffffffffffffffff
+#define SH_XNIILB_ERROR_DETAIL_2_INIT            0x0000000000000000
+
+/*   SH_XNIILB_ERROR_DETAIL_2_HEADER                                    */
+/*   Description:  header bits [127:64]                                 */
+#define SH_XNIILB_ERROR_DETAIL_2_HEADER_SHFT     0
+#define SH_XNIILB_ERROR_DETAIL_2_HEADER_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                 Register "SH_XNIILB_ERROR_DETAIL_3"                  */
+/*                     Look Up Table Address (iilb)                     */
+/* ==================================================================== */
+
+#define SH_XNIILB_ERROR_DETAIL_3                 0x0000000150040130
+#define SH_XNIILB_ERROR_DETAIL_3_MASK            0x00000000000007ff
+#define SH_XNIILB_ERROR_DETAIL_3_INIT            0x0000000000000000
+
+/*   SH_XNIILB_ERROR_DETAIL_3_LUT_ADDR                                  */
+/*   Description:  Look Up Table Read Address                           */
+#define SH_XNIILB_ERROR_DETAIL_3_LUT_ADDR_SHFT   0
+#define SH_XNIILB_ERROR_DETAIL_3_LUT_ADDR_MASK   0x00000000000007ff
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_ERROR_DETAIL_3"                   */
+/*                     Look Up Table Address (ni0)                      */
+/* ==================================================================== */
+
+#define SH_NI0_ERROR_DETAIL_3                    0x0000000150040140
+#define SH_NI0_ERROR_DETAIL_3_MASK               0x00000000000007ff
+#define SH_NI0_ERROR_DETAIL_3_INIT               0x0000000000000000
+
+/*   SH_NI0_ERROR_DETAIL_3_LUT_ADDR                                     */
+/*   Description:  Look Up Table Read Address                           */
+#define SH_NI0_ERROR_DETAIL_3_LUT_ADDR_SHFT      0
+#define SH_NI0_ERROR_DETAIL_3_LUT_ADDR_MASK      0x00000000000007ff
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_ERROR_DETAIL_3"                   */
+/*                     Look Up Table Address (ni1)                      */
+/* ==================================================================== */
+
+#define SH_NI1_ERROR_DETAIL_3                    0x0000000150040150
+#define SH_NI1_ERROR_DETAIL_3_MASK               0x00000000000007ff
+#define SH_NI1_ERROR_DETAIL_3_INIT               0x0000000000000000
+
+/*   SH_NI1_ERROR_DETAIL_3_LUT_ADDR                                     */
+/*   Description:  Look Up Table Read Address                           */
+#define SH_NI1_ERROR_DETAIL_3_LUT_ADDR_SHFT      0
+#define SH_NI1_ERROR_DETAIL_3_LUT_ADDR_MASK      0x00000000000007ff
+
+/* ==================================================================== */
+/*                    Register "SH_XN_ERROR_SUMMARY"                    */
+/* ==================================================================== */
+
+#define SH_XN_ERROR_SUMMARY                      0x0000000150040000
+#define SH_XN_ERROR_SUMMARY_MASK                 0x0000003fffffffff
+#define SH_XN_ERROR_SUMMARY_INIT                 0x0000003fffffffff
+
+/*   SH_XN_ERROR_SUMMARY_NI0_POP_OVERFLOW                               */
+/*   Description:  NI0 pop overflow                                     */
+#define SH_XN_ERROR_SUMMARY_NI0_POP_OVERFLOW_SHFT 0
+#define SH_XN_ERROR_SUMMARY_NI0_POP_OVERFLOW_MASK 0x0000000000000001
+
+/*   SH_XN_ERROR_SUMMARY_NI0_PUSH_OVERFLOW                              */
+/*   Description:  NI0 push overflow                                    */
+#define SH_XN_ERROR_SUMMARY_NI0_PUSH_OVERFLOW_SHFT 1
+#define SH_XN_ERROR_SUMMARY_NI0_PUSH_OVERFLOW_MASK 0x0000000000000002
+
+/*   SH_XN_ERROR_SUMMARY_NI0_CREDIT_OVERFLOW                            */
+/*   Description:  NI0 credit overflow                                  */
+#define SH_XN_ERROR_SUMMARY_NI0_CREDIT_OVERFLOW_SHFT 2
+#define SH_XN_ERROR_SUMMARY_NI0_CREDIT_OVERFLOW_MASK 0x0000000000000004
+
+/*   SH_XN_ERROR_SUMMARY_NI0_DEBIT_OVERFLOW                             */
+/*   Description:  NI0 debit overflow                                   */
+#define SH_XN_ERROR_SUMMARY_NI0_DEBIT_OVERFLOW_SHFT 3
+#define SH_XN_ERROR_SUMMARY_NI0_DEBIT_OVERFLOW_MASK 0x0000000000000008
+
+/*   SH_XN_ERROR_SUMMARY_NI0_POP_UNDERFLOW                              */
+/*   Description:  NI0 pop underflow                                    */
+#define SH_XN_ERROR_SUMMARY_NI0_POP_UNDERFLOW_SHFT 4
+#define SH_XN_ERROR_SUMMARY_NI0_POP_UNDERFLOW_MASK 0x0000000000000010
+
+/*   SH_XN_ERROR_SUMMARY_NI0_PUSH_UNDERFLOW                             */
+/*   Description:  NI0 push underflow                                   */
+#define SH_XN_ERROR_SUMMARY_NI0_PUSH_UNDERFLOW_SHFT 5
+#define SH_XN_ERROR_SUMMARY_NI0_PUSH_UNDERFLOW_MASK 0x0000000000000020
+
+/*   SH_XN_ERROR_SUMMARY_NI0_CREDIT_UNDERFLOW                           */
+/*   Description:  NI0 credit underflow                                 */
+#define SH_XN_ERROR_SUMMARY_NI0_CREDIT_UNDERFLOW_SHFT 6
+#define SH_XN_ERROR_SUMMARY_NI0_CREDIT_UNDERFLOW_MASK 0x0000000000000040
+
+/*   SH_XN_ERROR_SUMMARY_NI0_LLP_ERROR                                  */
+/*   Description:  NI0 llp error                                        */
+#define SH_XN_ERROR_SUMMARY_NI0_LLP_ERROR_SHFT   7
+#define SH_XN_ERROR_SUMMARY_NI0_LLP_ERROR_MASK   0x0000000000000080
+
+/*   SH_XN_ERROR_SUMMARY_NI0_PIPE_ERROR                                 */
+/*   Description:  NI0 Pipe in/out errors                               */
+#define SH_XN_ERROR_SUMMARY_NI0_PIPE_ERROR_SHFT  8
+#define SH_XN_ERROR_SUMMARY_NI0_PIPE_ERROR_MASK  0x0000000000000100
+
+/*   SH_XN_ERROR_SUMMARY_NI1_POP_OVERFLOW                               */
+/*   Description:  NI1 pop overflow                                     */
+#define SH_XN_ERROR_SUMMARY_NI1_POP_OVERFLOW_SHFT 9
+#define SH_XN_ERROR_SUMMARY_NI1_POP_OVERFLOW_MASK 0x0000000000000200
+
+/*   SH_XN_ERROR_SUMMARY_NI1_PUSH_OVERFLOW                              */
+/*   Description:  NI1 push overflow                                    */
+#define SH_XN_ERROR_SUMMARY_NI1_PUSH_OVERFLOW_SHFT 10
+#define SH_XN_ERROR_SUMMARY_NI1_PUSH_OVERFLOW_MASK 0x0000000000000400
+
+/*   SH_XN_ERROR_SUMMARY_NI1_CREDIT_OVERFLOW                            */
+/*   Description:  NI1 credit overflow                                  */
+#define SH_XN_ERROR_SUMMARY_NI1_CREDIT_OVERFLOW_SHFT 11
+#define SH_XN_ERROR_SUMMARY_NI1_CREDIT_OVERFLOW_MASK 0x0000000000000800
+
+/*   SH_XN_ERROR_SUMMARY_NI1_DEBIT_OVERFLOW                             */
+/*   Description:  NI1 debit overflow                                   */
+#define SH_XN_ERROR_SUMMARY_NI1_DEBIT_OVERFLOW_SHFT 12
+#define SH_XN_ERROR_SUMMARY_NI1_DEBIT_OVERFLOW_MASK 0x0000000000001000
+
+/*   SH_XN_ERROR_SUMMARY_NI1_POP_UNDERFLOW                              */
+/*   Description:  NI1 pop underflow                                    */
+#define SH_XN_ERROR_SUMMARY_NI1_POP_UNDERFLOW_SHFT 13
+#define SH_XN_ERROR_SUMMARY_NI1_POP_UNDERFLOW_MASK 0x0000000000002000
+
+/*   SH_XN_ERROR_SUMMARY_NI1_PUSH_UNDERFLOW                             */
+/*   Description:  NI1 push underflow                                   */
+#define SH_XN_ERROR_SUMMARY_NI1_PUSH_UNDERFLOW_SHFT 14
+#define SH_XN_ERROR_SUMMARY_NI1_PUSH_UNDERFLOW_MASK 0x0000000000004000
+
+/*   SH_XN_ERROR_SUMMARY_NI1_CREDIT_UNDERFLOW                           */
+/*   Description:  NI1 credit underflow                                 */
+#define SH_XN_ERROR_SUMMARY_NI1_CREDIT_UNDERFLOW_SHFT 15
+#define SH_XN_ERROR_SUMMARY_NI1_CREDIT_UNDERFLOW_MASK 0x0000000000008000
+
+/*   SH_XN_ERROR_SUMMARY_NI1_LLP_ERROR                                  */
+/*   Description:  NI1 llp error                                        */
+#define SH_XN_ERROR_SUMMARY_NI1_LLP_ERROR_SHFT   16
+#define SH_XN_ERROR_SUMMARY_NI1_LLP_ERROR_MASK   0x0000000000010000
+
+/*   SH_XN_ERROR_SUMMARY_NI1_PIPE_ERROR                                 */
+/*   Description:  NI1 pipe in/out error                                */
+#define SH_XN_ERROR_SUMMARY_NI1_PIPE_ERROR_SHFT  17
+#define SH_XN_ERROR_SUMMARY_NI1_PIPE_ERROR_MASK  0x0000000000020000
+
+/*   SH_XN_ERROR_SUMMARY_XNMD_CREDIT_OVERFLOW                           */
+/*   Description:  XNMD credit overflow                                 */
+#define SH_XN_ERROR_SUMMARY_XNMD_CREDIT_OVERFLOW_SHFT 18
+#define SH_XN_ERROR_SUMMARY_XNMD_CREDIT_OVERFLOW_MASK 0x0000000000040000
+
+/*   SH_XN_ERROR_SUMMARY_XNMD_DEBIT_OVERFLOW                            */
+/*   Description:  XNMD debit overflow                                  */
+#define SH_XN_ERROR_SUMMARY_XNMD_DEBIT_OVERFLOW_SHFT 19
+#define SH_XN_ERROR_SUMMARY_XNMD_DEBIT_OVERFLOW_MASK 0x0000000000080000
+
+/*   SH_XN_ERROR_SUMMARY_XNMD_DATA_BUFF_OVERFLOW                        */
+/*   Description:  XNMD data buffer overflow                            */
+#define SH_XN_ERROR_SUMMARY_XNMD_DATA_BUFF_OVERFLOW_SHFT 20
+#define SH_XN_ERROR_SUMMARY_XNMD_DATA_BUFF_OVERFLOW_MASK 0x0000000000100000
+
+/*   SH_XN_ERROR_SUMMARY_XNMD_CREDIT_UNDERFLOW                          */
+/*   Description:  XNMD credit underflow                                */
+#define SH_XN_ERROR_SUMMARY_XNMD_CREDIT_UNDERFLOW_SHFT 21
+#define SH_XN_ERROR_SUMMARY_XNMD_CREDIT_UNDERFLOW_MASK 0x0000000000200000
+
+/*   SH_XN_ERROR_SUMMARY_XNMD_SBE_ERROR                                 */
+/*   Description:  XNMD single bit error                                */
+#define SH_XN_ERROR_SUMMARY_XNMD_SBE_ERROR_SHFT  22
+#define SH_XN_ERROR_SUMMARY_XNMD_SBE_ERROR_MASK  0x0000000000400000
+
+/*   SH_XN_ERROR_SUMMARY_XNMD_UCE_ERROR                                 */
+/*   Description:  XNMD uncorrectable error                             */
+#define SH_XN_ERROR_SUMMARY_XNMD_UCE_ERROR_SHFT  23
+#define SH_XN_ERROR_SUMMARY_XNMD_UCE_ERROR_MASK  0x0000000000800000
+
+/*   SH_XN_ERROR_SUMMARY_XNMD_LUT_ERROR                                 */
+/*   Description:  XNMD look up table error                             */
+#define SH_XN_ERROR_SUMMARY_XNMD_LUT_ERROR_SHFT  24
+#define SH_XN_ERROR_SUMMARY_XNMD_LUT_ERROR_MASK  0x0000000001000000
+
+/*   SH_XN_ERROR_SUMMARY_XNPI_CREDIT_OVERFLOW                           */
+/*   Description:  XNMD credit overflow                                 */
+#define SH_XN_ERROR_SUMMARY_XNPI_CREDIT_OVERFLOW_SHFT 25
+#define SH_XN_ERROR_SUMMARY_XNPI_CREDIT_OVERFLOW_MASK 0x0000000002000000
+
+/*   SH_XN_ERROR_SUMMARY_XNPI_DEBIT_OVERFLOW                            */
+/*   Description:  XNPI debit overflow                                  */
+#define SH_XN_ERROR_SUMMARY_XNPI_DEBIT_OVERFLOW_SHFT 26
+#define SH_XN_ERROR_SUMMARY_XNPI_DEBIT_OVERFLOW_MASK 0x0000000004000000
+
+/*   SH_XN_ERROR_SUMMARY_XNPI_DATA_BUFF_OVERFLOW                        */
+/*   Description:  XNPI data buffer overflow                            */
+#define SH_XN_ERROR_SUMMARY_XNPI_DATA_BUFF_OVERFLOW_SHFT 27
+#define SH_XN_ERROR_SUMMARY_XNPI_DATA_BUFF_OVERFLOW_MASK 0x0000000008000000
+
+/*   SH_XN_ERROR_SUMMARY_XNPI_CREDIT_UNDERFLOW                          */
+/*   Description:  XNPI credit underflow                                */
+#define SH_XN_ERROR_SUMMARY_XNPI_CREDIT_UNDERFLOW_SHFT 28
+#define SH_XN_ERROR_SUMMARY_XNPI_CREDIT_UNDERFLOW_MASK 0x0000000010000000
+
+/*   SH_XN_ERROR_SUMMARY_XNPI_SBE_ERROR                                 */
+/*   Description:  XNPI single bit error                                */
+#define SH_XN_ERROR_SUMMARY_XNPI_SBE_ERROR_SHFT  29
+#define SH_XN_ERROR_SUMMARY_XNPI_SBE_ERROR_MASK  0x0000000020000000
+
+/*   SH_XN_ERROR_SUMMARY_XNPI_UCE_ERROR                                 */
+/*   Description:  XNPI uncorrectable error                             */
+#define SH_XN_ERROR_SUMMARY_XNPI_UCE_ERROR_SHFT  30
+#define SH_XN_ERROR_SUMMARY_XNPI_UCE_ERROR_MASK  0x0000000040000000
+
+/*   SH_XN_ERROR_SUMMARY_XNPI_LUT_ERROR                                 */
+/*   Description:  XNPI look up table error                             */
+#define SH_XN_ERROR_SUMMARY_XNPI_LUT_ERROR_SHFT  31
+#define SH_XN_ERROR_SUMMARY_XNPI_LUT_ERROR_MASK  0x0000000080000000
+
+/*   SH_XN_ERROR_SUMMARY_IILB_DEBIT_OVERFLOW                            */
+/*   Description:  IILB debit overflow                                  */
+#define SH_XN_ERROR_SUMMARY_IILB_DEBIT_OVERFLOW_SHFT 32
+#define SH_XN_ERROR_SUMMARY_IILB_DEBIT_OVERFLOW_MASK 0x0000000100000000
+
+/*   SH_XN_ERROR_SUMMARY_IILB_CREDIT_OVERFLOW                           */
+/*   Description:  IILB credit overflow                                 */
+#define SH_XN_ERROR_SUMMARY_IILB_CREDIT_OVERFLOW_SHFT 33
+#define SH_XN_ERROR_SUMMARY_IILB_CREDIT_OVERFLOW_MASK 0x0000000200000000
+
+/*   SH_XN_ERROR_SUMMARY_IILB_FIFO_OVERFLOW                             */
+/*   Description:  IILB fifo overflow                                   */
+#define SH_XN_ERROR_SUMMARY_IILB_FIFO_OVERFLOW_SHFT 34
+#define SH_XN_ERROR_SUMMARY_IILB_FIFO_OVERFLOW_MASK 0x0000000400000000
+
+/*   SH_XN_ERROR_SUMMARY_IILB_CREDIT_UNDERFLOW                          */
+/*   Description:  IILB credit underflow                                */
+#define SH_XN_ERROR_SUMMARY_IILB_CREDIT_UNDERFLOW_SHFT 35
+#define SH_XN_ERROR_SUMMARY_IILB_CREDIT_UNDERFLOW_MASK 0x0000000800000000
+
+/*   SH_XN_ERROR_SUMMARY_IILB_FIFO_UNDERFLOW                            */
+/*   Description:  IILB fifo underflow                                  */
+#define SH_XN_ERROR_SUMMARY_IILB_FIFO_UNDERFLOW_SHFT 36
+#define SH_XN_ERROR_SUMMARY_IILB_FIFO_UNDERFLOW_MASK 0x0000001000000000
+
+/*   SH_XN_ERROR_SUMMARY_IILB_CHIPLET_OR_LUT                            */
+/*   Description:  IILB chiplet nomatch or lut read error               */
+#define SH_XN_ERROR_SUMMARY_IILB_CHIPLET_OR_LUT_SHFT 37
+#define SH_XN_ERROR_SUMMARY_IILB_CHIPLET_OR_LUT_MASK 0x0000002000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XN_ERRORS_ALIAS"                     */
+/* ==================================================================== */
+
+#define SH_XN_ERRORS_ALIAS                       0x0000000150040008
+
+/* ==================================================================== */
+/*                   Register "SH_XN_ERROR_OVERFLOW"                    */
+/* ==================================================================== */
+
+#define SH_XN_ERROR_OVERFLOW                     0x0000000150040020
+#define SH_XN_ERROR_OVERFLOW_MASK                0x0000003fffffffff
+#define SH_XN_ERROR_OVERFLOW_INIT                0x0000003fffffffff
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_POP_OVERFLOW                              */
+/*   Description:  NI0 pop overflow                                     */
+#define SH_XN_ERROR_OVERFLOW_NI0_POP_OVERFLOW_SHFT 0
+#define SH_XN_ERROR_OVERFLOW_NI0_POP_OVERFLOW_MASK 0x0000000000000001
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_PUSH_OVERFLOW                             */
+/*   Description:  NI0 push overflow                                    */
+#define SH_XN_ERROR_OVERFLOW_NI0_PUSH_OVERFLOW_SHFT 1
+#define SH_XN_ERROR_OVERFLOW_NI0_PUSH_OVERFLOW_MASK 0x0000000000000002
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_CREDIT_OVERFLOW                           */
+/*   Description:  NI0 credit overflow                                  */
+#define SH_XN_ERROR_OVERFLOW_NI0_CREDIT_OVERFLOW_SHFT 2
+#define SH_XN_ERROR_OVERFLOW_NI0_CREDIT_OVERFLOW_MASK 0x0000000000000004
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_DEBIT_OVERFLOW                            */
+/*   Description:  NI0 debit overflow                                   */
+#define SH_XN_ERROR_OVERFLOW_NI0_DEBIT_OVERFLOW_SHFT 3
+#define SH_XN_ERROR_OVERFLOW_NI0_DEBIT_OVERFLOW_MASK 0x0000000000000008
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_POP_UNDERFLOW                             */
+/*   Description:  NI0 pop underflow                                    */
+#define SH_XN_ERROR_OVERFLOW_NI0_POP_UNDERFLOW_SHFT 4
+#define SH_XN_ERROR_OVERFLOW_NI0_POP_UNDERFLOW_MASK 0x0000000000000010
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_PUSH_UNDERFLOW                            */
+/*   Description:  NI0 push underflow                                   */
+#define SH_XN_ERROR_OVERFLOW_NI0_PUSH_UNDERFLOW_SHFT 5
+#define SH_XN_ERROR_OVERFLOW_NI0_PUSH_UNDERFLOW_MASK 0x0000000000000020
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_CREDIT_UNDERFLOW                          */
+/*   Description:  NI0 credit underflow                                 */
+#define SH_XN_ERROR_OVERFLOW_NI0_CREDIT_UNDERFLOW_SHFT 6
+#define SH_XN_ERROR_OVERFLOW_NI0_CREDIT_UNDERFLOW_MASK 0x0000000000000040
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_LLP_ERROR                                 */
+/*   Description:  NI0 llp error                                        */
+#define SH_XN_ERROR_OVERFLOW_NI0_LLP_ERROR_SHFT  7
+#define SH_XN_ERROR_OVERFLOW_NI0_LLP_ERROR_MASK  0x0000000000000080
+
+/*   SH_XN_ERROR_OVERFLOW_NI0_PIPE_ERROR                                */
+/*   Description:  NI0 Pipe in/out errors                               */
+#define SH_XN_ERROR_OVERFLOW_NI0_PIPE_ERROR_SHFT 8
+#define SH_XN_ERROR_OVERFLOW_NI0_PIPE_ERROR_MASK 0x0000000000000100
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_POP_OVERFLOW                              */
+/*   Description:  NI1 pop overflow                                     */
+#define SH_XN_ERROR_OVERFLOW_NI1_POP_OVERFLOW_SHFT 9
+#define SH_XN_ERROR_OVERFLOW_NI1_POP_OVERFLOW_MASK 0x0000000000000200
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_PUSH_OVERFLOW                             */
+/*   Description:  NI1 push overflow                                    */
+#define SH_XN_ERROR_OVERFLOW_NI1_PUSH_OVERFLOW_SHFT 10
+#define SH_XN_ERROR_OVERFLOW_NI1_PUSH_OVERFLOW_MASK 0x0000000000000400
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_CREDIT_OVERFLOW                           */
+/*   Description:  NI1 credit overflow                                  */
+#define SH_XN_ERROR_OVERFLOW_NI1_CREDIT_OVERFLOW_SHFT 11
+#define SH_XN_ERROR_OVERFLOW_NI1_CREDIT_OVERFLOW_MASK 0x0000000000000800
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_DEBIT_OVERFLOW                            */
+/*   Description:  NI1 debit overflow                                   */
+#define SH_XN_ERROR_OVERFLOW_NI1_DEBIT_OVERFLOW_SHFT 12
+#define SH_XN_ERROR_OVERFLOW_NI1_DEBIT_OVERFLOW_MASK 0x0000000000001000
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_POP_UNDERFLOW                             */
+/*   Description:  NI1 pop underflow                                    */
+#define SH_XN_ERROR_OVERFLOW_NI1_POP_UNDERFLOW_SHFT 13
+#define SH_XN_ERROR_OVERFLOW_NI1_POP_UNDERFLOW_MASK 0x0000000000002000
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_PUSH_UNDERFLOW                            */
+/*   Description:  NI1 push underflow                                   */
+#define SH_XN_ERROR_OVERFLOW_NI1_PUSH_UNDERFLOW_SHFT 14
+#define SH_XN_ERROR_OVERFLOW_NI1_PUSH_UNDERFLOW_MASK 0x0000000000004000
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_CREDIT_UNDERFLOW                          */
+/*   Description:  NI1 credit underflow                                 */
+#define SH_XN_ERROR_OVERFLOW_NI1_CREDIT_UNDERFLOW_SHFT 15
+#define SH_XN_ERROR_OVERFLOW_NI1_CREDIT_UNDERFLOW_MASK 0x0000000000008000
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_LLP_ERROR                                 */
+/*   Description:  NI1 llp error                                        */
+#define SH_XN_ERROR_OVERFLOW_NI1_LLP_ERROR_SHFT  16
+#define SH_XN_ERROR_OVERFLOW_NI1_LLP_ERROR_MASK  0x0000000000010000
+
+/*   SH_XN_ERROR_OVERFLOW_NI1_PIPE_ERROR                                */
+/*   Description:  NI1 pipe in/out error                                */
+#define SH_XN_ERROR_OVERFLOW_NI1_PIPE_ERROR_SHFT 17
+#define SH_XN_ERROR_OVERFLOW_NI1_PIPE_ERROR_MASK 0x0000000000020000
+
+/*   SH_XN_ERROR_OVERFLOW_XNMD_CREDIT_OVERFLOW                          */
+/*   Description:  XNMD credit overflow                                 */
+#define SH_XN_ERROR_OVERFLOW_XNMD_CREDIT_OVERFLOW_SHFT 18
+#define SH_XN_ERROR_OVERFLOW_XNMD_CREDIT_OVERFLOW_MASK 0x0000000000040000
+
+/*   SH_XN_ERROR_OVERFLOW_XNMD_DEBIT_OVERFLOW                           */
+/*   Description:  XNMD debit overflow                                  */
+#define SH_XN_ERROR_OVERFLOW_XNMD_DEBIT_OVERFLOW_SHFT 19
+#define SH_XN_ERROR_OVERFLOW_XNMD_DEBIT_OVERFLOW_MASK 0x0000000000080000
+
+/*   SH_XN_ERROR_OVERFLOW_XNMD_DATA_BUFF_OVERFLOW                       */
+/*   Description:  XNMD data buffer overflow                            */
+#define SH_XN_ERROR_OVERFLOW_XNMD_DATA_BUFF_OVERFLOW_SHFT 20
+#define SH_XN_ERROR_OVERFLOW_XNMD_DATA_BUFF_OVERFLOW_MASK 0x0000000000100000
+
+/*   SH_XN_ERROR_OVERFLOW_XNMD_CREDIT_UNDERFLOW                         */
+/*   Description:  XNMD credit underflow                                */
+#define SH_XN_ERROR_OVERFLOW_XNMD_CREDIT_UNDERFLOW_SHFT 21
+#define SH_XN_ERROR_OVERFLOW_XNMD_CREDIT_UNDERFLOW_MASK 0x0000000000200000
+
+/*   SH_XN_ERROR_OVERFLOW_XNMD_SBE_ERROR                                */
+/*   Description:  XNMD single bit error                                */
+#define SH_XN_ERROR_OVERFLOW_XNMD_SBE_ERROR_SHFT 22
+#define SH_XN_ERROR_OVERFLOW_XNMD_SBE_ERROR_MASK 0x0000000000400000
+
+/*   SH_XN_ERROR_OVERFLOW_XNMD_UCE_ERROR                                */
+/*   Description:  XNMD uncorrectable error                             */
+#define SH_XN_ERROR_OVERFLOW_XNMD_UCE_ERROR_SHFT 23
+#define SH_XN_ERROR_OVERFLOW_XNMD_UCE_ERROR_MASK 0x0000000000800000
+
+/*   SH_XN_ERROR_OVERFLOW_XNMD_LUT_ERROR                                */
+/*   Description:  XNMD look up table error                             */
+#define SH_XN_ERROR_OVERFLOW_XNMD_LUT_ERROR_SHFT 24
+#define SH_XN_ERROR_OVERFLOW_XNMD_LUT_ERROR_MASK 0x0000000001000000
+
+/*   SH_XN_ERROR_OVERFLOW_XNPI_CREDIT_OVERFLOW                          */
+/*   Description:  XNMD credit overflow                                 */
+#define SH_XN_ERROR_OVERFLOW_XNPI_CREDIT_OVERFLOW_SHFT 25
+#define SH_XN_ERROR_OVERFLOW_XNPI_CREDIT_OVERFLOW_MASK 0x0000000002000000
+
+/*   SH_XN_ERROR_OVERFLOW_XNPI_DEBIT_OVERFLOW                           */
+/*   Description:  XNPI debit overflow                                  */
+#define SH_XN_ERROR_OVERFLOW_XNPI_DEBIT_OVERFLOW_SHFT 26
+#define SH_XN_ERROR_OVERFLOW_XNPI_DEBIT_OVERFLOW_MASK 0x0000000004000000
+
+/*   SH_XN_ERROR_OVERFLOW_XNPI_DATA_BUFF_OVERFLOW                       */
+/*   Description:  XNPI data buffer overflow                            */
+#define SH_XN_ERROR_OVERFLOW_XNPI_DATA_BUFF_OVERFLOW_SHFT 27
+#define SH_XN_ERROR_OVERFLOW_XNPI_DATA_BUFF_OVERFLOW_MASK 0x0000000008000000
+
+/*   SH_XN_ERROR_OVERFLOW_XNPI_CREDIT_UNDERFLOW                         */
+/*   Description:  XNPI credit underflow                                */
+#define SH_XN_ERROR_OVERFLOW_XNPI_CREDIT_UNDERFLOW_SHFT 28
+#define SH_XN_ERROR_OVERFLOW_XNPI_CREDIT_UNDERFLOW_MASK 0x0000000010000000
+
+/*   SH_XN_ERROR_OVERFLOW_XNPI_SBE_ERROR                                */
+/*   Description:  XNPI single bit error                                */
+#define SH_XN_ERROR_OVERFLOW_XNPI_SBE_ERROR_SHFT 29
+#define SH_XN_ERROR_OVERFLOW_XNPI_SBE_ERROR_MASK 0x0000000020000000
+
+/*   SH_XN_ERROR_OVERFLOW_XNPI_UCE_ERROR                                */
+/*   Description:  XNPI uncorrectable error                             */
+#define SH_XN_ERROR_OVERFLOW_XNPI_UCE_ERROR_SHFT 30
+#define SH_XN_ERROR_OVERFLOW_XNPI_UCE_ERROR_MASK 0x0000000040000000
+
+/*   SH_XN_ERROR_OVERFLOW_XNPI_LUT_ERROR                                */
+/*   Description:  XNPI look up table error                             */
+#define SH_XN_ERROR_OVERFLOW_XNPI_LUT_ERROR_SHFT 31
+#define SH_XN_ERROR_OVERFLOW_XNPI_LUT_ERROR_MASK 0x0000000080000000
+
+/*   SH_XN_ERROR_OVERFLOW_IILB_DEBIT_OVERFLOW                           */
+/*   Description:  IILB debit overflow                                  */
+#define SH_XN_ERROR_OVERFLOW_IILB_DEBIT_OVERFLOW_SHFT 32
+#define SH_XN_ERROR_OVERFLOW_IILB_DEBIT_OVERFLOW_MASK 0x0000000100000000
+
+/*   SH_XN_ERROR_OVERFLOW_IILB_CREDIT_OVERFLOW                          */
+/*   Description:  IILB credit overflow                                 */
+#define SH_XN_ERROR_OVERFLOW_IILB_CREDIT_OVERFLOW_SHFT 33
+#define SH_XN_ERROR_OVERFLOW_IILB_CREDIT_OVERFLOW_MASK 0x0000000200000000
+
+/*   SH_XN_ERROR_OVERFLOW_IILB_FIFO_OVERFLOW                            */
+/*   Description:  IILB fifo overflow                                   */
+#define SH_XN_ERROR_OVERFLOW_IILB_FIFO_OVERFLOW_SHFT 34
+#define SH_XN_ERROR_OVERFLOW_IILB_FIFO_OVERFLOW_MASK 0x0000000400000000
+
+/*   SH_XN_ERROR_OVERFLOW_IILB_CREDIT_UNDERFLOW                         */
+/*   Description:  IILB credit underflow                                */
+#define SH_XN_ERROR_OVERFLOW_IILB_CREDIT_UNDERFLOW_SHFT 35
+#define SH_XN_ERROR_OVERFLOW_IILB_CREDIT_UNDERFLOW_MASK 0x0000000800000000
+
+/*   SH_XN_ERROR_OVERFLOW_IILB_FIFO_UNDERFLOW                           */
+/*   Description:  IILB fifo underflow                                  */
+#define SH_XN_ERROR_OVERFLOW_IILB_FIFO_UNDERFLOW_SHFT 36
+#define SH_XN_ERROR_OVERFLOW_IILB_FIFO_UNDERFLOW_MASK 0x0000001000000000
+
+/*   SH_XN_ERROR_OVERFLOW_IILB_CHIPLET_OR_LUT                           */
+/*   Description:  IILB chiplet nomatch or lut read error               */
+#define SH_XN_ERROR_OVERFLOW_IILB_CHIPLET_OR_LUT_SHFT 37
+#define SH_XN_ERROR_OVERFLOW_IILB_CHIPLET_OR_LUT_MASK 0x0000002000000000
+
+/* ==================================================================== */
+/*                Register "SH_XN_ERROR_OVERFLOW_ALIAS"                 */
+/* ==================================================================== */
+
+#define SH_XN_ERROR_OVERFLOW_ALIAS               0x0000000150040028
+
+/* ==================================================================== */
+/*                     Register "SH_XN_ERROR_MASK"                      */
+/* ==================================================================== */
+
+#define SH_XN_ERROR_MASK                         0x0000000150040040
+#define SH_XN_ERROR_MASK_MASK                    0x0000003fffffffff
+#define SH_XN_ERROR_MASK_INIT                    0x0000003fffffffff
+
+/*   SH_XN_ERROR_MASK_NI0_POP_OVERFLOW                                  */
+/*   Description:  NI0 pop overflow                                     */
+#define SH_XN_ERROR_MASK_NI0_POP_OVERFLOW_SHFT   0
+#define SH_XN_ERROR_MASK_NI0_POP_OVERFLOW_MASK   0x0000000000000001
+
+/*   SH_XN_ERROR_MASK_NI0_PUSH_OVERFLOW                                 */
+/*   Description:  NI0 push overflow                                    */
+#define SH_XN_ERROR_MASK_NI0_PUSH_OVERFLOW_SHFT  1
+#define SH_XN_ERROR_MASK_NI0_PUSH_OVERFLOW_MASK  0x0000000000000002
+
+/*   SH_XN_ERROR_MASK_NI0_CREDIT_OVERFLOW                               */
+/*   Description:  NI0 credit overflow                                  */
+#define SH_XN_ERROR_MASK_NI0_CREDIT_OVERFLOW_SHFT 2
+#define SH_XN_ERROR_MASK_NI0_CREDIT_OVERFLOW_MASK 0x0000000000000004
+
+/*   SH_XN_ERROR_MASK_NI0_DEBIT_OVERFLOW                                */
+/*   Description:  NI0 debit overflow                                   */
+#define SH_XN_ERROR_MASK_NI0_DEBIT_OVERFLOW_SHFT 3
+#define SH_XN_ERROR_MASK_NI0_DEBIT_OVERFLOW_MASK 0x0000000000000008
+
+/*   SH_XN_ERROR_MASK_NI0_POP_UNDERFLOW                                 */
+/*   Description:  NI0 pop underflow                                    */
+#define SH_XN_ERROR_MASK_NI0_POP_UNDERFLOW_SHFT  4
+#define SH_XN_ERROR_MASK_NI0_POP_UNDERFLOW_MASK  0x0000000000000010
+
+/*   SH_XN_ERROR_MASK_NI0_PUSH_UNDERFLOW                                */
+/*   Description:  NI0 push underflow                                   */
+#define SH_XN_ERROR_MASK_NI0_PUSH_UNDERFLOW_SHFT 5
+#define SH_XN_ERROR_MASK_NI0_PUSH_UNDERFLOW_MASK 0x0000000000000020
+
+/*   SH_XN_ERROR_MASK_NI0_CREDIT_UNDERFLOW                              */
+/*   Description:  NI0 credit underflow                                 */
+#define SH_XN_ERROR_MASK_NI0_CREDIT_UNDERFLOW_SHFT 6
+#define SH_XN_ERROR_MASK_NI0_CREDIT_UNDERFLOW_MASK 0x0000000000000040
+
+/*   SH_XN_ERROR_MASK_NI0_LLP_ERROR                                     */
+/*   Description:  NI0 llp error                                        */
+#define SH_XN_ERROR_MASK_NI0_LLP_ERROR_SHFT      7
+#define SH_XN_ERROR_MASK_NI0_LLP_ERROR_MASK      0x0000000000000080
+
+/*   SH_XN_ERROR_MASK_NI0_PIPE_ERROR                                    */
+/*   Description:  NI0 Pipe in/out errors                               */
+#define SH_XN_ERROR_MASK_NI0_PIPE_ERROR_SHFT     8
+#define SH_XN_ERROR_MASK_NI0_PIPE_ERROR_MASK     0x0000000000000100
+
+/*   SH_XN_ERROR_MASK_NI1_POP_OVERFLOW                                  */
+/*   Description:  NI1 pop overflow                                     */
+#define SH_XN_ERROR_MASK_NI1_POP_OVERFLOW_SHFT   9
+#define SH_XN_ERROR_MASK_NI1_POP_OVERFLOW_MASK   0x0000000000000200
+
+/*   SH_XN_ERROR_MASK_NI1_PUSH_OVERFLOW                                 */
+/*   Description:  NI1 push overflow                                    */
+#define SH_XN_ERROR_MASK_NI1_PUSH_OVERFLOW_SHFT  10
+#define SH_XN_ERROR_MASK_NI1_PUSH_OVERFLOW_MASK  0x0000000000000400
+
+/*   SH_XN_ERROR_MASK_NI1_CREDIT_OVERFLOW                               */
+/*   Description:  NI1 credit overflow                                  */
+#define SH_XN_ERROR_MASK_NI1_CREDIT_OVERFLOW_SHFT 11
+#define SH_XN_ERROR_MASK_NI1_CREDIT_OVERFLOW_MASK 0x0000000000000800
+
+/*   SH_XN_ERROR_MASK_NI1_DEBIT_OVERFLOW                                */
+/*   Description:  NI1 debit overflow                                   */
+#define SH_XN_ERROR_MASK_NI1_DEBIT_OVERFLOW_SHFT 12
+#define SH_XN_ERROR_MASK_NI1_DEBIT_OVERFLOW_MASK 0x0000000000001000
+
+/*   SH_XN_ERROR_MASK_NI1_POP_UNDERFLOW                                 */
+/*   Description:  NI1 pop underflow                                    */
+#define SH_XN_ERROR_MASK_NI1_POP_UNDERFLOW_SHFT  13
+#define SH_XN_ERROR_MASK_NI1_POP_UNDERFLOW_MASK  0x0000000000002000
+
+/*   SH_XN_ERROR_MASK_NI1_PUSH_UNDERFLOW                                */
+/*   Description:  NI1 push underflow                                   */
+#define SH_XN_ERROR_MASK_NI1_PUSH_UNDERFLOW_SHFT 14
+#define SH_XN_ERROR_MASK_NI1_PUSH_UNDERFLOW_MASK 0x0000000000004000
+
+/*   SH_XN_ERROR_MASK_NI1_CREDIT_UNDERFLOW                              */
+/*   Description:  NI1 credit underflow                                 */
+#define SH_XN_ERROR_MASK_NI1_CREDIT_UNDERFLOW_SHFT 15
+#define SH_XN_ERROR_MASK_NI1_CREDIT_UNDERFLOW_MASK 0x0000000000008000
+
+/*   SH_XN_ERROR_MASK_NI1_LLP_ERROR                                     */
+/*   Description:  NI1 llp error                                        */
+#define SH_XN_ERROR_MASK_NI1_LLP_ERROR_SHFT      16
+#define SH_XN_ERROR_MASK_NI1_LLP_ERROR_MASK      0x0000000000010000
+
+/*   SH_XN_ERROR_MASK_NI1_PIPE_ERROR                                    */
+/*   Description:  NI1 pipe in/out error                                */
+#define SH_XN_ERROR_MASK_NI1_PIPE_ERROR_SHFT     17
+#define SH_XN_ERROR_MASK_NI1_PIPE_ERROR_MASK     0x0000000000020000
+
+/*   SH_XN_ERROR_MASK_XNMD_CREDIT_OVERFLOW                              */
+/*   Description:  XNMD credit overflow                                 */
+#define SH_XN_ERROR_MASK_XNMD_CREDIT_OVERFLOW_SHFT 18
+#define SH_XN_ERROR_MASK_XNMD_CREDIT_OVERFLOW_MASK 0x0000000000040000
+
+/*   SH_XN_ERROR_MASK_XNMD_DEBIT_OVERFLOW                               */
+/*   Description:  XNMD debit overflow                                  */
+#define SH_XN_ERROR_MASK_XNMD_DEBIT_OVERFLOW_SHFT 19
+#define SH_XN_ERROR_MASK_XNMD_DEBIT_OVERFLOW_MASK 0x0000000000080000
+
+/*   SH_XN_ERROR_MASK_XNMD_DATA_BUFF_OVERFLOW                           */
+/*   Description:  XNMD data buffer overflow                            */
+#define SH_XN_ERROR_MASK_XNMD_DATA_BUFF_OVERFLOW_SHFT 20
+#define SH_XN_ERROR_MASK_XNMD_DATA_BUFF_OVERFLOW_MASK 0x0000000000100000
+
+/*   SH_XN_ERROR_MASK_XNMD_CREDIT_UNDERFLOW                             */
+/*   Description:  XNMD credit underflow                                */
+#define SH_XN_ERROR_MASK_XNMD_CREDIT_UNDERFLOW_SHFT 21
+#define SH_XN_ERROR_MASK_XNMD_CREDIT_UNDERFLOW_MASK 0x0000000000200000
+
+/*   SH_XN_ERROR_MASK_XNMD_SBE_ERROR                                    */
+/*   Description:  XNMD single bit error                                */
+#define SH_XN_ERROR_MASK_XNMD_SBE_ERROR_SHFT     22
+#define SH_XN_ERROR_MASK_XNMD_SBE_ERROR_MASK     0x0000000000400000
+
+/*   SH_XN_ERROR_MASK_XNMD_UCE_ERROR                                    */
+/*   Description:  XNMD uncorrectable error                             */
+#define SH_XN_ERROR_MASK_XNMD_UCE_ERROR_SHFT     23
+#define SH_XN_ERROR_MASK_XNMD_UCE_ERROR_MASK     0x0000000000800000
+
+/*   SH_XN_ERROR_MASK_XNMD_LUT_ERROR                                    */
+/*   Description:  XNMD look up table error                             */
+#define SH_XN_ERROR_MASK_XNMD_LUT_ERROR_SHFT     24
+#define SH_XN_ERROR_MASK_XNMD_LUT_ERROR_MASK     0x0000000001000000
+
+/*   SH_XN_ERROR_MASK_XNPI_CREDIT_OVERFLOW                              */
+/*   Description:  XNMD credit overflow                                 */
+#define SH_XN_ERROR_MASK_XNPI_CREDIT_OVERFLOW_SHFT 25
+#define SH_XN_ERROR_MASK_XNPI_CREDIT_OVERFLOW_MASK 0x0000000002000000
+
+/*   SH_XN_ERROR_MASK_XNPI_DEBIT_OVERFLOW                               */
+/*   Description:  XNPI debit overflow                                  */
+#define SH_XN_ERROR_MASK_XNPI_DEBIT_OVERFLOW_SHFT 26
+#define SH_XN_ERROR_MASK_XNPI_DEBIT_OVERFLOW_MASK 0x0000000004000000
+
+/*   SH_XN_ERROR_MASK_XNPI_DATA_BUFF_OVERFLOW                           */
+/*   Description:  XNPI data buffer overflow                            */
+#define SH_XN_ERROR_MASK_XNPI_DATA_BUFF_OVERFLOW_SHFT 27
+#define SH_XN_ERROR_MASK_XNPI_DATA_BUFF_OVERFLOW_MASK 0x0000000008000000
+
+/*   SH_XN_ERROR_MASK_XNPI_CREDIT_UNDERFLOW                             */
+/*   Description:  XNPI credit underflow                                */
+#define SH_XN_ERROR_MASK_XNPI_CREDIT_UNDERFLOW_SHFT 28
+#define SH_XN_ERROR_MASK_XNPI_CREDIT_UNDERFLOW_MASK 0x0000000010000000
+
+/*   SH_XN_ERROR_MASK_XNPI_SBE_ERROR                                    */
+/*   Description:  XNPI single bit error                                */
+#define SH_XN_ERROR_MASK_XNPI_SBE_ERROR_SHFT     29
+#define SH_XN_ERROR_MASK_XNPI_SBE_ERROR_MASK     0x0000000020000000
+
+/*   SH_XN_ERROR_MASK_XNPI_UCE_ERROR                                    */
+/*   Description:  XNPI uncorrectable error                             */
+#define SH_XN_ERROR_MASK_XNPI_UCE_ERROR_SHFT     30
+#define SH_XN_ERROR_MASK_XNPI_UCE_ERROR_MASK     0x0000000040000000
+
+/*   SH_XN_ERROR_MASK_XNPI_LUT_ERROR                                    */
+/*   Description:  XNPI look up table error                             */
+#define SH_XN_ERROR_MASK_XNPI_LUT_ERROR_SHFT     31
+#define SH_XN_ERROR_MASK_XNPI_LUT_ERROR_MASK     0x0000000080000000
+
+/*   SH_XN_ERROR_MASK_IILB_DEBIT_OVERFLOW                               */
+/*   Description:  IILB debit overflow                                  */
+#define SH_XN_ERROR_MASK_IILB_DEBIT_OVERFLOW_SHFT 32
+#define SH_XN_ERROR_MASK_IILB_DEBIT_OVERFLOW_MASK 0x0000000100000000
+
+/*   SH_XN_ERROR_MASK_IILB_CREDIT_OVERFLOW                              */
+/*   Description:  IILB credit overflow                                 */
+#define SH_XN_ERROR_MASK_IILB_CREDIT_OVERFLOW_SHFT 33
+#define SH_XN_ERROR_MASK_IILB_CREDIT_OVERFLOW_MASK 0x0000000200000000
+
+/*   SH_XN_ERROR_MASK_IILB_FIFO_OVERFLOW                                */
+/*   Description:  IILB fifo overflow                                   */
+#define SH_XN_ERROR_MASK_IILB_FIFO_OVERFLOW_SHFT 34
+#define SH_XN_ERROR_MASK_IILB_FIFO_OVERFLOW_MASK 0x0000000400000000
+
+/*   SH_XN_ERROR_MASK_IILB_CREDIT_UNDERFLOW                             */
+/*   Description:  IILB credit underflow                                */
+#define SH_XN_ERROR_MASK_IILB_CREDIT_UNDERFLOW_SHFT 35
+#define SH_XN_ERROR_MASK_IILB_CREDIT_UNDERFLOW_MASK 0x0000000800000000
+
+/*   SH_XN_ERROR_MASK_IILB_FIFO_UNDERFLOW                               */
+/*   Description:  IILB fifo underflow                                  */
+#define SH_XN_ERROR_MASK_IILB_FIFO_UNDERFLOW_SHFT 36
+#define SH_XN_ERROR_MASK_IILB_FIFO_UNDERFLOW_MASK 0x0000001000000000
+
+/*   SH_XN_ERROR_MASK_IILB_CHIPLET_OR_LUT                               */
+/*   Description:  IILB chiplet nomatch or lut read error               */
+#define SH_XN_ERROR_MASK_IILB_CHIPLET_OR_LUT_SHFT 37
+#define SH_XN_ERROR_MASK_IILB_CHIPLET_OR_LUT_MASK 0x0000002000000000
+
+/* ==================================================================== */
+/*                     Register "SH_XN_FIRST_ERROR"                     */
+/* ==================================================================== */
+
+#define SH_XN_FIRST_ERROR                        0x0000000150040060
+#define SH_XN_FIRST_ERROR_MASK                   0x0000003fffffffff
+#define SH_XN_FIRST_ERROR_INIT                   0x0000003fffffffff
+
+/*   SH_XN_FIRST_ERROR_NI0_POP_OVERFLOW                                 */
+/*   Description:  NI0 pop overflow                                     */
+#define SH_XN_FIRST_ERROR_NI0_POP_OVERFLOW_SHFT  0
+#define SH_XN_FIRST_ERROR_NI0_POP_OVERFLOW_MASK  0x0000000000000001
+
+/*   SH_XN_FIRST_ERROR_NI0_PUSH_OVERFLOW                                */
+/*   Description:  NI0 push overflow                                    */
+#define SH_XN_FIRST_ERROR_NI0_PUSH_OVERFLOW_SHFT 1
+#define SH_XN_FIRST_ERROR_NI0_PUSH_OVERFLOW_MASK 0x0000000000000002
+
+/*   SH_XN_FIRST_ERROR_NI0_CREDIT_OVERFLOW                              */
+/*   Description:  NI0 credit overflow                                  */
+#define SH_XN_FIRST_ERROR_NI0_CREDIT_OVERFLOW_SHFT 2
+#define SH_XN_FIRST_ERROR_NI0_CREDIT_OVERFLOW_MASK 0x0000000000000004
+
+/*   SH_XN_FIRST_ERROR_NI0_DEBIT_OVERFLOW                               */
+/*   Description:  NI0 debit overflow                                   */
+#define SH_XN_FIRST_ERROR_NI0_DEBIT_OVERFLOW_SHFT 3
+#define SH_XN_FIRST_ERROR_NI0_DEBIT_OVERFLOW_MASK 0x0000000000000008
+
+/*   SH_XN_FIRST_ERROR_NI0_POP_UNDERFLOW                                */
+/*   Description:  NI0 pop underflow                                    */
+#define SH_XN_FIRST_ERROR_NI0_POP_UNDERFLOW_SHFT 4
+#define SH_XN_FIRST_ERROR_NI0_POP_UNDERFLOW_MASK 0x0000000000000010
+
+/*   SH_XN_FIRST_ERROR_NI0_PUSH_UNDERFLOW                               */
+/*   Description:  NI0 push underflow                                   */
+#define SH_XN_FIRST_ERROR_NI0_PUSH_UNDERFLOW_SHFT 5
+#define SH_XN_FIRST_ERROR_NI0_PUSH_UNDERFLOW_MASK 0x0000000000000020
+
+/*   SH_XN_FIRST_ERROR_NI0_CREDIT_UNDERFLOW                             */
+/*   Description:  NI0 credit underflow                                 */
+#define SH_XN_FIRST_ERROR_NI0_CREDIT_UNDERFLOW_SHFT 6
+#define SH_XN_FIRST_ERROR_NI0_CREDIT_UNDERFLOW_MASK 0x0000000000000040
+
+/*   SH_XN_FIRST_ERROR_NI0_LLP_ERROR                                    */
+/*   Description:  NI0 llp error                                        */
+#define SH_XN_FIRST_ERROR_NI0_LLP_ERROR_SHFT     7
+#define SH_XN_FIRST_ERROR_NI0_LLP_ERROR_MASK     0x0000000000000080
+
+/*   SH_XN_FIRST_ERROR_NI0_PIPE_ERROR                                   */
+/*   Description:  NI0 Pipe in/out errors                               */
+#define SH_XN_FIRST_ERROR_NI0_PIPE_ERROR_SHFT    8
+#define SH_XN_FIRST_ERROR_NI0_PIPE_ERROR_MASK    0x0000000000000100
+
+/*   SH_XN_FIRST_ERROR_NI1_POP_OVERFLOW                                 */
+/*   Description:  NI1 pop overflow                                     */
+#define SH_XN_FIRST_ERROR_NI1_POP_OVERFLOW_SHFT  9
+#define SH_XN_FIRST_ERROR_NI1_POP_OVERFLOW_MASK  0x0000000000000200
+
+/*   SH_XN_FIRST_ERROR_NI1_PUSH_OVERFLOW                                */
+/*   Description:  NI1 push overflow                                    */
+#define SH_XN_FIRST_ERROR_NI1_PUSH_OVERFLOW_SHFT 10
+#define SH_XN_FIRST_ERROR_NI1_PUSH_OVERFLOW_MASK 0x0000000000000400
+
+/*   SH_XN_FIRST_ERROR_NI1_CREDIT_OVERFLOW                              */
+/*   Description:  NI1 credit overflow                                  */
+#define SH_XN_FIRST_ERROR_NI1_CREDIT_OVERFLOW_SHFT 11
+#define SH_XN_FIRST_ERROR_NI1_CREDIT_OVERFLOW_MASK 0x0000000000000800
+
+/*   SH_XN_FIRST_ERROR_NI1_DEBIT_OVERFLOW                               */
+/*   Description:  NI1 debit overflow                                   */
+#define SH_XN_FIRST_ERROR_NI1_DEBIT_OVERFLOW_SHFT 12
+#define SH_XN_FIRST_ERROR_NI1_DEBIT_OVERFLOW_MASK 0x0000000000001000
+
+/*   SH_XN_FIRST_ERROR_NI1_POP_UNDERFLOW                                */
+/*   Description:  NI1 pop underflow                                    */
+#define SH_XN_FIRST_ERROR_NI1_POP_UNDERFLOW_SHFT 13
+#define SH_XN_FIRST_ERROR_NI1_POP_UNDERFLOW_MASK 0x0000000000002000
+
+/*   SH_XN_FIRST_ERROR_NI1_PUSH_UNDERFLOW                               */
+/*   Description:  NI1 push underflow                                   */
+#define SH_XN_FIRST_ERROR_NI1_PUSH_UNDERFLOW_SHFT 14
+#define SH_XN_FIRST_ERROR_NI1_PUSH_UNDERFLOW_MASK 0x0000000000004000
+
+/*   SH_XN_FIRST_ERROR_NI1_CREDIT_UNDERFLOW                             */
+/*   Description:  NI1 credit underflow                                 */
+#define SH_XN_FIRST_ERROR_NI1_CREDIT_UNDERFLOW_SHFT 15
+#define SH_XN_FIRST_ERROR_NI1_CREDIT_UNDERFLOW_MASK 0x0000000000008000
+
+/*   SH_XN_FIRST_ERROR_NI1_LLP_ERROR                                    */
+/*   Description:  NI1 llp error                                        */
+#define SH_XN_FIRST_ERROR_NI1_LLP_ERROR_SHFT     16
+#define SH_XN_FIRST_ERROR_NI1_LLP_ERROR_MASK     0x0000000000010000
+
+/*   SH_XN_FIRST_ERROR_NI1_PIPE_ERROR                                   */
+/*   Description:  NI1 pipe in/out error                                */
+#define SH_XN_FIRST_ERROR_NI1_PIPE_ERROR_SHFT    17
+#define SH_XN_FIRST_ERROR_NI1_PIPE_ERROR_MASK    0x0000000000020000
+
+/*   SH_XN_FIRST_ERROR_XNMD_CREDIT_OVERFLOW                             */
+/*   Description:  XNMD credit overflow                                 */
+#define SH_XN_FIRST_ERROR_XNMD_CREDIT_OVERFLOW_SHFT 18
+#define SH_XN_FIRST_ERROR_XNMD_CREDIT_OVERFLOW_MASK 0x0000000000040000
+
+/*   SH_XN_FIRST_ERROR_XNMD_DEBIT_OVERFLOW                              */
+/*   Description:  XNMD debit overflow                                  */
+#define SH_XN_FIRST_ERROR_XNMD_DEBIT_OVERFLOW_SHFT 19
+#define SH_XN_FIRST_ERROR_XNMD_DEBIT_OVERFLOW_MASK 0x0000000000080000
+
+/*   SH_XN_FIRST_ERROR_XNMD_DATA_BUFF_OVERFLOW                          */
+/*   Description:  XNMD data buffer overflow                            */
+#define SH_XN_FIRST_ERROR_XNMD_DATA_BUFF_OVERFLOW_SHFT 20
+#define SH_XN_FIRST_ERROR_XNMD_DATA_BUFF_OVERFLOW_MASK 0x0000000000100000
+
+/*   SH_XN_FIRST_ERROR_XNMD_CREDIT_UNDERFLOW                            */
+/*   Description:  XNMD credit underflow                                */
+#define SH_XN_FIRST_ERROR_XNMD_CREDIT_UNDERFLOW_SHFT 21
+#define SH_XN_FIRST_ERROR_XNMD_CREDIT_UNDERFLOW_MASK 0x0000000000200000
+
+/*   SH_XN_FIRST_ERROR_XNMD_SBE_ERROR                                   */
+/*   Description:  XNMD single bit error                                */
+#define SH_XN_FIRST_ERROR_XNMD_SBE_ERROR_SHFT    22
+#define SH_XN_FIRST_ERROR_XNMD_SBE_ERROR_MASK    0x0000000000400000
+
+/*   SH_XN_FIRST_ERROR_XNMD_UCE_ERROR                                   */
+/*   Description:  XNMD uncorrectable error                             */
+#define SH_XN_FIRST_ERROR_XNMD_UCE_ERROR_SHFT    23
+#define SH_XN_FIRST_ERROR_XNMD_UCE_ERROR_MASK    0x0000000000800000
+
+/*   SH_XN_FIRST_ERROR_XNMD_LUT_ERROR                                   */
+/*   Description:  XNMD look up table error                             */
+#define SH_XN_FIRST_ERROR_XNMD_LUT_ERROR_SHFT    24
+#define SH_XN_FIRST_ERROR_XNMD_LUT_ERROR_MASK    0x0000000001000000
+
+/*   SH_XN_FIRST_ERROR_XNPI_CREDIT_OVERFLOW                             */
+/*   Description:  XNMD credit overflow                                 */
+#define SH_XN_FIRST_ERROR_XNPI_CREDIT_OVERFLOW_SHFT 25
+#define SH_XN_FIRST_ERROR_XNPI_CREDIT_OVERFLOW_MASK 0x0000000002000000
+
+/*   SH_XN_FIRST_ERROR_XNPI_DEBIT_OVERFLOW                              */
+/*   Description:  XNPI debit overflow                                  */
+#define SH_XN_FIRST_ERROR_XNPI_DEBIT_OVERFLOW_SHFT 26
+#define SH_XN_FIRST_ERROR_XNPI_DEBIT_OVERFLOW_MASK 0x0000000004000000
+
+/*   SH_XN_FIRST_ERROR_XNPI_DATA_BUFF_OVERFLOW                          */
+/*   Description:  XNPI data buffer overflow                            */
+#define SH_XN_FIRST_ERROR_XNPI_DATA_BUFF_OVERFLOW_SHFT 27
+#define SH_XN_FIRST_ERROR_XNPI_DATA_BUFF_OVERFLOW_MASK 0x0000000008000000
+
+/*   SH_XN_FIRST_ERROR_XNPI_CREDIT_UNDERFLOW                            */
+/*   Description:  XNPI credit underflow                                */
+#define SH_XN_FIRST_ERROR_XNPI_CREDIT_UNDERFLOW_SHFT 28
+#define SH_XN_FIRST_ERROR_XNPI_CREDIT_UNDERFLOW_MASK 0x0000000010000000
+
+/*   SH_XN_FIRST_ERROR_XNPI_SBE_ERROR                                   */
+/*   Description:  XNPI single bit error                                */
+#define SH_XN_FIRST_ERROR_XNPI_SBE_ERROR_SHFT    29
+#define SH_XN_FIRST_ERROR_XNPI_SBE_ERROR_MASK    0x0000000020000000
+
+/*   SH_XN_FIRST_ERROR_XNPI_UCE_ERROR                                   */
+/*   Description:  XNPI uncorrectable error                             */
+#define SH_XN_FIRST_ERROR_XNPI_UCE_ERROR_SHFT    30
+#define SH_XN_FIRST_ERROR_XNPI_UCE_ERROR_MASK    0x0000000040000000
+
+/*   SH_XN_FIRST_ERROR_XNPI_LUT_ERROR                                   */
+/*   Description:  XNPI look up table error                             */
+#define SH_XN_FIRST_ERROR_XNPI_LUT_ERROR_SHFT    31
+#define SH_XN_FIRST_ERROR_XNPI_LUT_ERROR_MASK    0x0000000080000000
+
+/*   SH_XN_FIRST_ERROR_IILB_DEBIT_OVERFLOW                              */
+/*   Description:  IILB debit overflow                                  */
+#define SH_XN_FIRST_ERROR_IILB_DEBIT_OVERFLOW_SHFT 32
+#define SH_XN_FIRST_ERROR_IILB_DEBIT_OVERFLOW_MASK 0x0000000100000000
+
+/*   SH_XN_FIRST_ERROR_IILB_CREDIT_OVERFLOW                             */
+/*   Description:  IILB credit overflow                                 */
+#define SH_XN_FIRST_ERROR_IILB_CREDIT_OVERFLOW_SHFT 33
+#define SH_XN_FIRST_ERROR_IILB_CREDIT_OVERFLOW_MASK 0x0000000200000000
+
+/*   SH_XN_FIRST_ERROR_IILB_FIFO_OVERFLOW                               */
+/*   Description:  IILB fifo overflow                                   */
+#define SH_XN_FIRST_ERROR_IILB_FIFO_OVERFLOW_SHFT 34
+#define SH_XN_FIRST_ERROR_IILB_FIFO_OVERFLOW_MASK 0x0000000400000000
+
+/*   SH_XN_FIRST_ERROR_IILB_CREDIT_UNDERFLOW                            */
+/*   Description:  IILB credit underflow                                */
+#define SH_XN_FIRST_ERROR_IILB_CREDIT_UNDERFLOW_SHFT 35
+#define SH_XN_FIRST_ERROR_IILB_CREDIT_UNDERFLOW_MASK 0x0000000800000000
+
+/*   SH_XN_FIRST_ERROR_IILB_FIFO_UNDERFLOW                              */
+/*   Description:  IILB fifo underflow                                  */
+#define SH_XN_FIRST_ERROR_IILB_FIFO_UNDERFLOW_SHFT 36
+#define SH_XN_FIRST_ERROR_IILB_FIFO_UNDERFLOW_MASK 0x0000001000000000
+
+/*   SH_XN_FIRST_ERROR_IILB_CHIPLET_OR_LUT                              */
+/*   Description:  IILB chiplet nomatch or lut read error               */
+#define SH_XN_FIRST_ERROR_IILB_CHIPLET_OR_LUT_SHFT 37
+#define SH_XN_FIRST_ERROR_IILB_CHIPLET_OR_LUT_MASK 0x0000002000000000
+
+/* ==================================================================== */
+/*                  Register "SH_XNIILB_ERROR_SUMMARY"                  */
+/* ==================================================================== */
+
+#define SH_XNIILB_ERROR_SUMMARY                  0x0000000150040200
+#define SH_XNIILB_ERROR_SUMMARY_MASK             0xffffffffffffffff
+#define SH_XNIILB_ERROR_SUMMARY_INIT             0xffffffffffffffff
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_DEBIT0                         */
+/*   Description:  II debit0 overflow                                   */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_DEBIT0_SHFT 0
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_DEBIT2                         */
+/*   Description:  II debit2 overflow                                   */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_DEBIT2_SHFT 1
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_DEBIT0                         */
+/*   Description:  LB debit0 overflow                                   */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_DEBIT0_SHFT 2
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_DEBIT2                         */
+/*   Description:  LB debit2 overflow                                   */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_DEBIT2_SHFT 3
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_VC0                            */
+/*   Description:  II VC0 fifo overflow                                 */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_VC0_SHFT 4
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_VC0_MASK 0x0000000000000010
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_VC2                            */
+/*   Description:  II VC2 fifo overflow                                 */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_VC2_SHFT 5
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_II_VC2_MASK 0x0000000000000020
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_II_VC0                           */
+/*   Description:  II VC0 fifo underflow                                */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_II_VC0_SHFT 6
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_II_VC0_MASK 0x0000000000000040
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_II_VC2                           */
+/*   Description:  II VC2 fifo underflow                                */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_II_VC2_SHFT 7
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_II_VC2_MASK 0x0000000000000080
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_VC0                            */
+/*   Description:  LB VC0 fifo overflow                                 */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_VC0_SHFT 8
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_VC2                            */
+/*   Description:  LB VC2 fifo overflow                                 */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_VC2_SHFT 9
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_LB_VC2_MASK 0x0000000000000200
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_LB_VC0                           */
+/*   Description:  LB VC0 fifo underflow                                */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_LB_VC0_SHFT 10
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_LB_VC0_MASK 0x0000000000000400
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_LB_VC2                           */
+/*   Description:  LB VC2 fifo underflow                                */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_LB_VC2_SHFT 11
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_LB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC0_CREDIT_IN                  */
+/*   Description:  PI VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC0_CREDIT_IN_SHFT 12
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC0_CREDIT_IN_MASK 0x0000000000001000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_IN                */
+/*   Description:  IILB VC0 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_IN_SHFT 13
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_IN_MASK 0x0000000000002000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC0_CREDIT_IN                  */
+/*   Description:  MD VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC0_CREDIT_IN_SHFT 14
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC0_CREDIT_IN_MASK 0x0000000000004000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_IN                 */
+/*   Description:  NI0 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_IN_SHFT 15
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_IN_MASK 0x0000000000008000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_IN                 */
+/*   Description:  NI1 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_IN_SHFT 16
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_IN_MASK 0x0000000000010000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC2_CREDIT_IN                  */
+/*   Description:  PI VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC2_CREDIT_IN_SHFT 17
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC2_CREDIT_IN_MASK 0x0000000000020000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_IN                */
+/*   Description:  IILB VC2 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_IN_SHFT 18
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_IN_MASK 0x0000000000040000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC2_CREDIT_IN                  */
+/*   Description:  MD VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC2_CREDIT_IN_SHFT 19
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC2_CREDIT_IN_MASK 0x0000000000080000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_IN                 */
+/*   Description:  NI0 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_IN_SHFT 20
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_IN_MASK 0x0000000000100000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_IN                 */
+/*   Description:  NI1 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_IN_SHFT 21
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_IN_MASK 0x0000000000200000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC0_CREDIT_IN                 */
+/*   Description:  PI VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC0_CREDIT_IN_SHFT 22
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC0_CREDIT_IN_MASK 0x0000000000400000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_IN               */
+/*   Description:  IILB VC0 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_IN_SHFT 23
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_IN_MASK 0x0000000000800000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC0_CREDIT_IN                 */
+/*   Description:  MD VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC0_CREDIT_IN_SHFT 24
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC0_CREDIT_IN_MASK 0x0000000001000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_IN                */
+/*   Description:  NI0 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_IN_SHFT 25
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_IN_MASK 0x0000000002000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_IN                */
+/*   Description:  NI1 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_IN_SHFT 26
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_IN_MASK 0x0000000004000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC2_CREDIT_IN                 */
+/*   Description:  PI VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC2_CREDIT_IN_SHFT 27
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC2_CREDIT_IN_MASK 0x0000000008000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_IN               */
+/*   Description:  IILB VC2 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_IN_SHFT 28
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_IN_MASK 0x0000000010000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC2_CREDIT_IN                 */
+/*   Description:  MD VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC2_CREDIT_IN_SHFT 29
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC2_CREDIT_IN_MASK 0x0000000020000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_IN                */
+/*   Description:  NI0 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_IN_SHFT 30
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_IN_MASK 0x0000000040000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_IN                */
+/*   Description:  NI1 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_IN_SHFT 31
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_IN_MASK 0x0000000080000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_DEBIT0                         */
+/*   Description:  PI Fifo Debit0 overflow                              */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_DEBIT0_SHFT 32
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_DEBIT0_MASK 0x0000000100000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_DEBIT2                         */
+/*   Description:  PI Fifo Debit2 overflow                              */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_DEBIT2_SHFT 33
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_DEBIT2_MASK 0x0000000200000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0                       */
+/*   Description:  IILB Fifo Debit0 overflow                            */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0_SHFT 34
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0_MASK 0x0000000400000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2                       */
+/*   Description:  IILB Fifo Debit2 overflow                            */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2_SHFT 35
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2_MASK 0x0000000800000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_DEBIT0                         */
+/*   Description:  MD Fifo Debit0 overflow                              */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_DEBIT0_SHFT 36
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_DEBIT0_MASK 0x0000001000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_DEBIT2                         */
+/*   Description:  MD Fifo Debit2 overflow                              */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_DEBIT2_SHFT 37
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_DEBIT2_MASK 0x0000002000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0                        */
+/*   Description:  NI0 Fifo Debit0 overflow                             */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0_SHFT 38
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0_MASK 0x0000004000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2                        */
+/*   Description:  NI0 Fifo Debit2 overflow                             */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2_SHFT 39
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2_MASK 0x0000008000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0                        */
+/*   Description:  NI1 Fifo Debit0 overflow                             */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0_SHFT 40
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0_MASK 0x0000010000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2                        */
+/*   Description:  NI1 Fifo Debit2 overflow                             */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2_SHFT 41
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2_MASK 0x0000020000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC0_CREDIT_OUT                 */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC0_CREDIT_OUT_SHFT 42
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC0_CREDIT_OUT_MASK 0x0000040000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC2_CREDIT_OUT                 */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC2_CREDIT_OUT_SHFT 43
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_PI_VC2_CREDIT_OUT_MASK 0x0000080000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC0_CREDIT_OUT                 */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC0_CREDIT_OUT_SHFT 44
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC0_CREDIT_OUT_MASK 0x0000100000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC2_CREDIT_OUT                 */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC2_CREDIT_OUT_SHFT 45
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_MD_VC2_CREDIT_OUT_MASK 0x0000200000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_OUT               */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_OUT_SHFT 46
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_OUT_MASK 0x0000400000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_OUT               */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_OUT_SHFT 47
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_OUT_MASK 0x0000800000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_OUT                */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_OUT_SHFT 48
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_OUT_MASK 0x0001000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_OUT                */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_OUT_SHFT 49
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_OUT_MASK 0x0002000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_OUT                */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_OUT_SHFT 50
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_OUT_MASK 0x0004000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_OUT                */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_OUT_SHFT 51
+#define SH_XNIILB_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_OUT_MASK 0x0008000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC0_CREDIT_OUT                */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC0_CREDIT_OUT_SHFT 52
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC0_CREDIT_OUT_MASK 0x0010000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC2_CREDIT_OUT                */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC2_CREDIT_OUT_SHFT 53
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_PI_VC2_CREDIT_OUT_MASK 0x0020000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC0_CREDIT_OUT                */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC0_CREDIT_OUT_SHFT 54
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC0_CREDIT_OUT_MASK 0x0040000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC2_CREDIT_OUT                */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC2_CREDIT_OUT_SHFT 55
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_MD_VC2_CREDIT_OUT_MASK 0x0080000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_OUT              */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_OUT_SHFT 56
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_OUT_MASK 0x0100000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_OUT              */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_OUT_SHFT 57
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_OUT_MASK 0x0200000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_OUT               */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_OUT_SHFT 58
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_OUT_MASK 0x0400000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_OUT               */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_OUT_SHFT 59
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_OUT_MASK 0x0800000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_OUT               */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_OUT_SHFT 60
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_OUT_MASK 0x1000000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_OUT               */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_OUT_SHFT 61
+#define SH_XNIILB_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_OUT_MASK 0x2000000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_CHIPLET_NOMATCH                            */
+/*   Description:  chiplet nomatch                                      */
+#define SH_XNIILB_ERROR_SUMMARY_CHIPLET_NOMATCH_SHFT 62
+#define SH_XNIILB_ERROR_SUMMARY_CHIPLET_NOMATCH_MASK 0x4000000000000000
+
+/*   SH_XNIILB_ERROR_SUMMARY_LUT_READ_ERROR                             */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNIILB_ERROR_SUMMARY_LUT_READ_ERROR_SHFT 63
+#define SH_XNIILB_ERROR_SUMMARY_LUT_READ_ERROR_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_XNIILB_ERRORS_ALIAS"                   */
+/* ==================================================================== */
+
+#define SH_XNIILB_ERRORS_ALIAS                   0x0000000150040208
+
+/* ==================================================================== */
+/*                 Register "SH_XNIILB_ERROR_OVERFLOW"                  */
+/* ==================================================================== */
+
+#define SH_XNIILB_ERROR_OVERFLOW                 0x0000000150040220
+#define SH_XNIILB_ERROR_OVERFLOW_MASK            0xffffffffffffffff
+#define SH_XNIILB_ERROR_OVERFLOW_INIT            0xffffffffffffffff
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_DEBIT0                        */
+/*   Description:  II debit0 overflow                                   */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_DEBIT0_SHFT 0
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_DEBIT2                        */
+/*   Description:  II debit2 overflow                                   */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_DEBIT2_SHFT 1
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_DEBIT0                        */
+/*   Description:  LB debit0 overflow                                   */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_DEBIT0_SHFT 2
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_DEBIT2                        */
+/*   Description:  LB debit2 overflow                                   */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_DEBIT2_SHFT 3
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_VC0                           */
+/*   Description:  II VC0 fifo overflow                                 */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_VC0_SHFT 4
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_VC0_MASK 0x0000000000000010
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_VC2                           */
+/*   Description:  II VC2 fifo overflow                                 */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_VC2_SHFT 5
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_II_VC2_MASK 0x0000000000000020
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_II_VC0                          */
+/*   Description:  II VC0 fifo underflow                                */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_II_VC0_SHFT 6
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_II_VC0_MASK 0x0000000000000040
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_II_VC2                          */
+/*   Description:  II VC2 fifo underflow                                */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_II_VC2_SHFT 7
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_II_VC2_MASK 0x0000000000000080
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_VC0                           */
+/*   Description:  LB VC0 fifo overflow                                 */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_VC0_SHFT 8
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_VC2                           */
+/*   Description:  LB VC2 fifo overflow                                 */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_VC2_SHFT 9
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_LB_VC2_MASK 0x0000000000000200
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_LB_VC0                          */
+/*   Description:  LB VC0 fifo underflow                                */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_LB_VC0_SHFT 10
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_LB_VC0_MASK 0x0000000000000400
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_LB_VC2                          */
+/*   Description:  LB VC2 fifo underflow                                */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_LB_VC2_SHFT 11
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_LB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC0_CREDIT_IN                 */
+/*   Description:  PI VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC0_CREDIT_IN_SHFT 12
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC0_CREDIT_IN_MASK 0x0000000000001000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_IN               */
+/*   Description:  IILB VC0 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_IN_SHFT 13
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_IN_MASK 0x0000000000002000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC0_CREDIT_IN                 */
+/*   Description:  MD VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC0_CREDIT_IN_SHFT 14
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC0_CREDIT_IN_MASK 0x0000000000004000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_IN                */
+/*   Description:  NI0 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_IN_SHFT 15
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_IN_MASK 0x0000000000008000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_IN                */
+/*   Description:  NI1 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_IN_SHFT 16
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_IN_MASK 0x0000000000010000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC2_CREDIT_IN                 */
+/*   Description:  PI VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC2_CREDIT_IN_SHFT 17
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC2_CREDIT_IN_MASK 0x0000000000020000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_IN               */
+/*   Description:  IILB VC2 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_IN_SHFT 18
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_IN_MASK 0x0000000000040000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC2_CREDIT_IN                 */
+/*   Description:  MD VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC2_CREDIT_IN_SHFT 19
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC2_CREDIT_IN_MASK 0x0000000000080000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_IN                */
+/*   Description:  NI0 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_IN_SHFT 20
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_IN_MASK 0x0000000000100000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_IN                */
+/*   Description:  NI1 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_IN_SHFT 21
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_IN_MASK 0x0000000000200000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC0_CREDIT_IN                */
+/*   Description:  PI VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC0_CREDIT_IN_SHFT 22
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC0_CREDIT_IN_MASK 0x0000000000400000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_IN              */
+/*   Description:  IILB VC0 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_IN_SHFT 23
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_IN_MASK 0x0000000000800000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC0_CREDIT_IN                */
+/*   Description:  MD VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC0_CREDIT_IN_SHFT 24
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC0_CREDIT_IN_MASK 0x0000000001000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_IN               */
+/*   Description:  NI0 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_IN_SHFT 25
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_IN_MASK 0x0000000002000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_IN               */
+/*   Description:  NI1 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_IN_SHFT 26
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_IN_MASK 0x0000000004000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC2_CREDIT_IN                */
+/*   Description:  PI VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC2_CREDIT_IN_SHFT 27
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC2_CREDIT_IN_MASK 0x0000000008000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_IN              */
+/*   Description:  IILB VC2 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_IN_SHFT 28
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_IN_MASK 0x0000000010000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC2_CREDIT_IN                */
+/*   Description:  MD VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC2_CREDIT_IN_SHFT 29
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC2_CREDIT_IN_MASK 0x0000000020000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_IN               */
+/*   Description:  NI0 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_IN_SHFT 30
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_IN_MASK 0x0000000040000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_IN               */
+/*   Description:  NI1 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_IN_SHFT 31
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_IN_MASK 0x0000000080000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_DEBIT0                        */
+/*   Description:  PI Fifo Debit0 overflow                              */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_DEBIT0_SHFT 32
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_DEBIT0_MASK 0x0000000100000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_DEBIT2                        */
+/*   Description:  PI Fifo Debit2 overflow                              */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_DEBIT2_SHFT 33
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_DEBIT2_MASK 0x0000000200000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0                      */
+/*   Description:  IILB Fifo Debit0 overflow                            */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0_SHFT 34
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0_MASK 0x0000000400000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2                      */
+/*   Description:  IILB Fifo Debit2 overflow                            */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2_SHFT 35
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2_MASK 0x0000000800000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_DEBIT0                        */
+/*   Description:  MD Fifo Debit0 overflow                              */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_DEBIT0_SHFT 36
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_DEBIT0_MASK 0x0000001000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_DEBIT2                        */
+/*   Description:  MD Fifo Debit2 overflow                              */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_DEBIT2_SHFT 37
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_DEBIT2_MASK 0x0000002000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0                       */
+/*   Description:  NI0 Fifo Debit0 overflow                             */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0_SHFT 38
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0_MASK 0x0000004000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2                       */
+/*   Description:  NI0 Fifo Debit2 overflow                             */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2_SHFT 39
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2_MASK 0x0000008000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0                       */
+/*   Description:  NI1 Fifo Debit0 overflow                             */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0_SHFT 40
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0_MASK 0x0000010000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2                       */
+/*   Description:  NI1 Fifo Debit2 overflow                             */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2_SHFT 41
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2_MASK 0x0000020000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC0_CREDIT_OUT                */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC0_CREDIT_OUT_SHFT 42
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC0_CREDIT_OUT_MASK 0x0000040000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC2_CREDIT_OUT                */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC2_CREDIT_OUT_SHFT 43
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_PI_VC2_CREDIT_OUT_MASK 0x0000080000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC0_CREDIT_OUT                */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC0_CREDIT_OUT_SHFT 44
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC0_CREDIT_OUT_MASK 0x0000100000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC2_CREDIT_OUT                */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC2_CREDIT_OUT_SHFT 45
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_MD_VC2_CREDIT_OUT_MASK 0x0000200000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_OUT              */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_OUT_SHFT 46
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_OUT_MASK 0x0000400000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_OUT              */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_OUT_SHFT 47
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_OUT_MASK 0x0000800000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_OUT               */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_OUT_SHFT 48
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_OUT_MASK 0x0001000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_OUT               */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_OUT_SHFT 49
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_OUT_MASK 0x0002000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_OUT               */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_OUT_SHFT 50
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_OUT_MASK 0x0004000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_OUT               */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_OUT_SHFT 51
+#define SH_XNIILB_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_OUT_MASK 0x0008000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC0_CREDIT_OUT               */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC0_CREDIT_OUT_SHFT 52
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC0_CREDIT_OUT_MASK 0x0010000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC2_CREDIT_OUT               */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC2_CREDIT_OUT_SHFT 53
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_PI_VC2_CREDIT_OUT_MASK 0x0020000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC0_CREDIT_OUT               */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC0_CREDIT_OUT_SHFT 54
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC0_CREDIT_OUT_MASK 0x0040000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC2_CREDIT_OUT               */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC2_CREDIT_OUT_SHFT 55
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_MD_VC2_CREDIT_OUT_MASK 0x0080000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_OUT             */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_OUT_SHFT 56
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_OUT_MASK 0x0100000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_OUT             */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_OUT_SHFT 57
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_OUT_MASK 0x0200000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_OUT              */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_OUT_SHFT 58
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_OUT_MASK 0x0400000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_OUT              */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_OUT_SHFT 59
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_OUT_MASK 0x0800000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_OUT              */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_OUT_SHFT 60
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_OUT_MASK 0x1000000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_OUT              */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_OUT_SHFT 61
+#define SH_XNIILB_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_OUT_MASK 0x2000000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_CHIPLET_NOMATCH                           */
+/*   Description:  chiplet nomatch                                      */
+#define SH_XNIILB_ERROR_OVERFLOW_CHIPLET_NOMATCH_SHFT 62
+#define SH_XNIILB_ERROR_OVERFLOW_CHIPLET_NOMATCH_MASK 0x4000000000000000
+
+/*   SH_XNIILB_ERROR_OVERFLOW_LUT_READ_ERROR                            */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNIILB_ERROR_OVERFLOW_LUT_READ_ERROR_SHFT 63
+#define SH_XNIILB_ERROR_OVERFLOW_LUT_READ_ERROR_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*              Register "SH_XNIILB_ERROR_OVERFLOW_ALIAS"               */
+/* ==================================================================== */
+
+#define SH_XNIILB_ERROR_OVERFLOW_ALIAS           0x0000000150040228
+
+/* ==================================================================== */
+/*                   Register "SH_XNIILB_ERROR_MASK"                    */
+/* ==================================================================== */
+
+#define SH_XNIILB_ERROR_MASK                     0x0000000150040240
+#define SH_XNIILB_ERROR_MASK_MASK                0xffffffffffffffff
+#define SH_XNIILB_ERROR_MASK_INIT                0xffffffffffffffff
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_II_DEBIT0                            */
+/*   Description:  II debit0 overflow                                   */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_II_DEBIT0_SHFT 0
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_II_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_II_DEBIT2                            */
+/*   Description:  II debit2 overflow                                   */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_II_DEBIT2_SHFT 1
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_II_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_LB_DEBIT0                            */
+/*   Description:  LB debit0 overflow                                   */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_LB_DEBIT0_SHFT 2
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_LB_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_LB_DEBIT2                            */
+/*   Description:  LB debit2 overflow                                   */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_LB_DEBIT2_SHFT 3
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_LB_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_II_VC0                               */
+/*   Description:  II VC0 fifo overflow                                 */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_II_VC0_SHFT 4
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_II_VC0_MASK 0x0000000000000010
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_II_VC2                               */
+/*   Description:  II VC2 fifo overflow                                 */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_II_VC2_SHFT 5
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_II_VC2_MASK 0x0000000000000020
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_II_VC0                              */
+/*   Description:  II VC0 fifo underflow                                */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_II_VC0_SHFT 6
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_II_VC0_MASK 0x0000000000000040
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_II_VC2                              */
+/*   Description:  II VC2 fifo underflow                                */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_II_VC2_SHFT 7
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_II_VC2_MASK 0x0000000000000080
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_LB_VC0                               */
+/*   Description:  LB VC0 fifo overflow                                 */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_LB_VC0_SHFT 8
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_LB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_LB_VC2                               */
+/*   Description:  LB VC2 fifo overflow                                 */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_LB_VC2_SHFT 9
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_LB_VC2_MASK 0x0000000000000200
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_LB_VC0                              */
+/*   Description:  LB VC0 fifo underflow                                */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_LB_VC0_SHFT 10
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_LB_VC0_MASK 0x0000000000000400
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_LB_VC2                              */
+/*   Description:  LB VC2 fifo underflow                                */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_LB_VC2_SHFT 11
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_LB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC0_CREDIT_IN                     */
+/*   Description:  PI VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC0_CREDIT_IN_SHFT 12
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC0_CREDIT_IN_MASK 0x0000000000001000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_IN                   */
+/*   Description:  IILB VC0 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_IN_SHFT 13
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_IN_MASK 0x0000000000002000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC0_CREDIT_IN                     */
+/*   Description:  MD VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC0_CREDIT_IN_SHFT 14
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC0_CREDIT_IN_MASK 0x0000000000004000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_IN                    */
+/*   Description:  NI0 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_IN_SHFT 15
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_IN_MASK 0x0000000000008000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_IN                    */
+/*   Description:  NI1 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_IN_SHFT 16
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_IN_MASK 0x0000000000010000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC2_CREDIT_IN                     */
+/*   Description:  PI VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC2_CREDIT_IN_SHFT 17
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC2_CREDIT_IN_MASK 0x0000000000020000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_IN                   */
+/*   Description:  IILB VC2 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_IN_SHFT 18
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_IN_MASK 0x0000000000040000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC2_CREDIT_IN                     */
+/*   Description:  MD VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC2_CREDIT_IN_SHFT 19
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC2_CREDIT_IN_MASK 0x0000000000080000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_IN                    */
+/*   Description:  NI0 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_IN_SHFT 20
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_IN_MASK 0x0000000000100000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_IN                    */
+/*   Description:  NI1 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_IN_SHFT 21
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_IN_MASK 0x0000000000200000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC0_CREDIT_IN                    */
+/*   Description:  PI VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC0_CREDIT_IN_SHFT 22
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC0_CREDIT_IN_MASK 0x0000000000400000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_IN                  */
+/*   Description:  IILB VC0 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_IN_SHFT 23
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_IN_MASK 0x0000000000800000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC0_CREDIT_IN                    */
+/*   Description:  MD VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC0_CREDIT_IN_SHFT 24
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC0_CREDIT_IN_MASK 0x0000000001000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_IN                   */
+/*   Description:  NI0 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_IN_SHFT 25
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_IN_MASK 0x0000000002000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_IN                   */
+/*   Description:  NI1 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_IN_SHFT 26
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_IN_MASK 0x0000000004000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC2_CREDIT_IN                    */
+/*   Description:  PI VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC2_CREDIT_IN_SHFT 27
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC2_CREDIT_IN_MASK 0x0000000008000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_IN                  */
+/*   Description:  IILB VC2 credit overflow Pipe In                     */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_IN_SHFT 28
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_IN_MASK 0x0000000010000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC2_CREDIT_IN                    */
+/*   Description:  MD VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC2_CREDIT_IN_SHFT 29
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC2_CREDIT_IN_MASK 0x0000000020000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_IN                   */
+/*   Description:  NI0 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_IN_SHFT 30
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_IN_MASK 0x0000000040000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_IN                   */
+/*   Description:  NI1 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_IN_SHFT 31
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_IN_MASK 0x0000000080000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_PI_DEBIT0                            */
+/*   Description:  PI Fifo Debit0 overflow                              */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_DEBIT0_SHFT 32
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_DEBIT0_MASK 0x0000000100000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_PI_DEBIT2                            */
+/*   Description:  PI Fifo Debit2 overflow                              */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_DEBIT2_SHFT 33
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_DEBIT2_MASK 0x0000000200000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_DEBIT0                          */
+/*   Description:  IILB Fifo Debit0 overflow                            */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_DEBIT0_SHFT 34
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_DEBIT0_MASK 0x0000000400000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_DEBIT2                          */
+/*   Description:  IILB Fifo Debit2 overflow                            */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_DEBIT2_SHFT 35
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_DEBIT2_MASK 0x0000000800000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_MD_DEBIT0                            */
+/*   Description:  MD Fifo Debit0 overflow                              */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_DEBIT0_SHFT 36
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_DEBIT0_MASK 0x0000001000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_MD_DEBIT2                            */
+/*   Description:  MD Fifo Debit2 overflow                              */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_DEBIT2_SHFT 37
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_DEBIT2_MASK 0x0000002000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_DEBIT0                           */
+/*   Description:  NI0 Fifo Debit0 overflow                             */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_DEBIT0_SHFT 38
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_DEBIT0_MASK 0x0000004000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_DEBIT2                           */
+/*   Description:  NI0 Fifo Debit2 overflow                             */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_DEBIT2_SHFT 39
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_DEBIT2_MASK 0x0000008000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_DEBIT0                           */
+/*   Description:  NI1 Fifo Debit0 overflow                             */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_DEBIT0_SHFT 40
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_DEBIT0_MASK 0x0000010000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_DEBIT2                           */
+/*   Description:  NI1 Fifo Debit2 overflow                             */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_DEBIT2_SHFT 41
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_DEBIT2_MASK 0x0000020000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC0_CREDIT_OUT                    */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC0_CREDIT_OUT_SHFT 42
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC0_CREDIT_OUT_MASK 0x0000040000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC2_CREDIT_OUT                    */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC2_CREDIT_OUT_SHFT 43
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_PI_VC2_CREDIT_OUT_MASK 0x0000080000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC0_CREDIT_OUT                    */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC0_CREDIT_OUT_SHFT 44
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC0_CREDIT_OUT_MASK 0x0000100000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC2_CREDIT_OUT                    */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC2_CREDIT_OUT_SHFT 45
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_MD_VC2_CREDIT_OUT_MASK 0x0000200000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_OUT                  */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_OUT_SHFT 46
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_OUT_MASK 0x0000400000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_OUT                  */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_OUT_SHFT 47
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_OUT_MASK 0x0000800000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_OUT                   */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_OUT_SHFT 48
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_OUT_MASK 0x0001000000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_OUT                   */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_OUT_SHFT 49
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_OUT_MASK 0x0002000000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_OUT                   */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_OUT_SHFT 50
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_OUT_MASK 0x0004000000000000
+
+/*   SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_OUT                   */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_OUT_SHFT 51
+#define SH_XNIILB_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_OUT_MASK 0x0008000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC0_CREDIT_OUT                   */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC0_CREDIT_OUT_SHFT 52
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC0_CREDIT_OUT_MASK 0x0010000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC2_CREDIT_OUT                   */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC2_CREDIT_OUT_SHFT 53
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_PI_VC2_CREDIT_OUT_MASK 0x0020000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC0_CREDIT_OUT                   */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC0_CREDIT_OUT_SHFT 54
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC0_CREDIT_OUT_MASK 0x0040000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC2_CREDIT_OUT                   */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC2_CREDIT_OUT_SHFT 55
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_MD_VC2_CREDIT_OUT_MASK 0x0080000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_OUT                 */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_OUT_SHFT 56
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_OUT_MASK 0x0100000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_OUT                 */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_OUT_SHFT 57
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_OUT_MASK 0x0200000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_OUT                  */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_OUT_SHFT 58
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_OUT_MASK 0x0400000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_OUT                  */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_OUT_SHFT 59
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_OUT_MASK 0x0800000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_OUT                  */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_OUT_SHFT 60
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_OUT_MASK 0x1000000000000000
+
+/*   SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_OUT                  */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_OUT_SHFT 61
+#define SH_XNIILB_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_OUT_MASK 0x2000000000000000
+
+/*   SH_XNIILB_ERROR_MASK_CHIPLET_NOMATCH                               */
+/*   Description:  chiplet nomatch                                      */
+#define SH_XNIILB_ERROR_MASK_CHIPLET_NOMATCH_SHFT 62
+#define SH_XNIILB_ERROR_MASK_CHIPLET_NOMATCH_MASK 0x4000000000000000
+
+/*   SH_XNIILB_ERROR_MASK_LUT_READ_ERROR                                */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNIILB_ERROR_MASK_LUT_READ_ERROR_SHFT 63
+#define SH_XNIILB_ERROR_MASK_LUT_READ_ERROR_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNIILB_FIRST_ERROR"                   */
+/* ==================================================================== */
+
+#define SH_XNIILB_FIRST_ERROR                    0x0000000150040260
+#define SH_XNIILB_FIRST_ERROR_MASK               0xffffffffffffffff
+#define SH_XNIILB_FIRST_ERROR_INIT               0xffffffffffffffff
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_II_DEBIT0                           */
+/*   Description:  II debit0 overflow                                   */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_II_DEBIT0_SHFT 0
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_II_DEBIT0_MASK 0x0000000000000001
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_II_DEBIT2                           */
+/*   Description:  II debit2 overflow                                   */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_II_DEBIT2_SHFT 1
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_II_DEBIT2_MASK 0x0000000000000002
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_DEBIT0                           */
+/*   Description:  LB debit0 overflow                                   */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_DEBIT0_SHFT 2
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_DEBIT0_MASK 0x0000000000000004
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_DEBIT2                           */
+/*   Description:  LB debit2 overflow                                   */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_DEBIT2_SHFT 3
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_DEBIT2_MASK 0x0000000000000008
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_II_VC0                              */
+/*   Description:  II VC0 fifo overflow                                 */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_II_VC0_SHFT 4
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_II_VC0_MASK 0x0000000000000010
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_II_VC2                              */
+/*   Description:  II VC2 fifo overflow                                 */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_II_VC2_SHFT 5
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_II_VC2_MASK 0x0000000000000020
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_II_VC0                             */
+/*   Description:  II VC0 fifo underflow                                */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_II_VC0_SHFT 6
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_II_VC0_MASK 0x0000000000000040
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_II_VC2                             */
+/*   Description:  II VC2 fifo underflow                                */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_II_VC2_SHFT 7
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_II_VC2_MASK 0x0000000000000080
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_VC0                              */
+/*   Description:  LB VC0 fifo overflow                                 */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_VC0_SHFT 8
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_VC2                              */
+/*   Description:  LB VC2 fifo overflow                                 */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_VC2_SHFT 9
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_LB_VC2_MASK 0x0000000000000200
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_LB_VC0                             */
+/*   Description:  LB VC0 fifo underflow                                */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_LB_VC0_SHFT 10
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_LB_VC0_MASK 0x0000000000000400
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_LB_VC2                             */
+/*   Description:  LB VC2 fifo underflow                                */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_LB_VC2_SHFT 11
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_LB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC0_CREDIT_IN                    */
+/*   Description:  PI VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC0_CREDIT_IN_SHFT 12
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC0_CREDIT_IN_MASK 0x0000000000001000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_IN                  */
+/*   Description:  IILB VC0 credit overflow Pipe In                     */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_IN_SHFT 13
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_IN_MASK 0x0000000000002000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC0_CREDIT_IN                    */
+/*   Description:  MD VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC0_CREDIT_IN_SHFT 14
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC0_CREDIT_IN_MASK 0x0000000000004000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_IN                   */
+/*   Description:  NI0 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_IN_SHFT 15
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_IN_MASK 0x0000000000008000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_IN                   */
+/*   Description:  NI1 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_IN_SHFT 16
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_IN_MASK 0x0000000000010000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC2_CREDIT_IN                    */
+/*   Description:  PI VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC2_CREDIT_IN_SHFT 17
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC2_CREDIT_IN_MASK 0x0000000000020000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_IN                  */
+/*   Description:  IILB VC2 credit overflow Pipe In                     */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_IN_SHFT 18
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_IN_MASK 0x0000000000040000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC2_CREDIT_IN                    */
+/*   Description:  MD VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC2_CREDIT_IN_SHFT 19
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC2_CREDIT_IN_MASK 0x0000000000080000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_IN                   */
+/*   Description:  NI0 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_IN_SHFT 20
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_IN_MASK 0x0000000000100000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_IN                   */
+/*   Description:  NI1 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_IN_SHFT 21
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_IN_MASK 0x0000000000200000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC0_CREDIT_IN                   */
+/*   Description:  PI VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC0_CREDIT_IN_SHFT 22
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC0_CREDIT_IN_MASK 0x0000000000400000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_IN                 */
+/*   Description:  IILB VC0 credit overflow Pipe In                     */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_IN_SHFT 23
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_IN_MASK 0x0000000000800000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC0_CREDIT_IN                   */
+/*   Description:  MD VC0 credit overflow Pipe In                       */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC0_CREDIT_IN_SHFT 24
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC0_CREDIT_IN_MASK 0x0000000001000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_IN                  */
+/*   Description:  NI0 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_IN_SHFT 25
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_IN_MASK 0x0000000002000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_IN                  */
+/*   Description:  NI1 VC0 credit overflow Pipe In                      */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_IN_SHFT 26
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_IN_MASK 0x0000000004000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC2_CREDIT_IN                   */
+/*   Description:  PI VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC2_CREDIT_IN_SHFT 27
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC2_CREDIT_IN_MASK 0x0000000008000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_IN                 */
+/*   Description:  IILB VC2 credit overflow Pipe In                     */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_IN_SHFT 28
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_IN_MASK 0x0000000010000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC2_CREDIT_IN                   */
+/*   Description:  MD VC2 credit overflow Pipe In                       */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC2_CREDIT_IN_SHFT 29
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC2_CREDIT_IN_MASK 0x0000000020000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_IN                  */
+/*   Description:  NI0 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_IN_SHFT 30
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_IN_MASK 0x0000000040000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_IN                  */
+/*   Description:  NI1 VC2 credit overflow Pipe In                      */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_IN_SHFT 31
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_IN_MASK 0x0000000080000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_DEBIT0                           */
+/*   Description:  PI Fifo Debit0 overflow                              */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_DEBIT0_SHFT 32
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_DEBIT0_MASK 0x0000000100000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_DEBIT2                           */
+/*   Description:  PI Fifo Debit2 overflow                              */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_DEBIT2_SHFT 33
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_DEBIT2_MASK 0x0000000200000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_DEBIT0                         */
+/*   Description:  IILB Fifo Debit0 overflow                            */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_DEBIT0_SHFT 34
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_DEBIT0_MASK 0x0000000400000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_DEBIT2                         */
+/*   Description:  IILB Fifo Debit2 overflow                            */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_DEBIT2_SHFT 35
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_DEBIT2_MASK 0x0000000800000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_DEBIT0                           */
+/*   Description:  MD Fifo Debit0 overflow                              */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_DEBIT0_SHFT 36
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_DEBIT0_MASK 0x0000001000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_DEBIT2                           */
+/*   Description:  MD Fifo Debit2 overflow                              */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_DEBIT2_SHFT 37
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_DEBIT2_MASK 0x0000002000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_DEBIT0                          */
+/*   Description:  NI0 Fifo Debit0 overflow                             */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_DEBIT0_SHFT 38
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_DEBIT0_MASK 0x0000004000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_DEBIT2                          */
+/*   Description:  NI0 Fifo Debit2 overflow                             */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_DEBIT2_SHFT 39
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_DEBIT2_MASK 0x0000008000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_DEBIT0                          */
+/*   Description:  NI1 Fifo Debit0 overflow                             */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_DEBIT0_SHFT 40
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_DEBIT0_MASK 0x0000010000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_DEBIT2                          */
+/*   Description:  NI1 Fifo Debit2 overflow                             */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_DEBIT2_SHFT 41
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_DEBIT2_MASK 0x0000020000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC0_CREDIT_OUT                   */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC0_CREDIT_OUT_SHFT 42
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC0_CREDIT_OUT_MASK 0x0000040000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC2_CREDIT_OUT                   */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC2_CREDIT_OUT_SHFT 43
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_PI_VC2_CREDIT_OUT_MASK 0x0000080000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC0_CREDIT_OUT                   */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC0_CREDIT_OUT_SHFT 44
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC0_CREDIT_OUT_MASK 0x0000100000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC2_CREDIT_OUT                   */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC2_CREDIT_OUT_SHFT 45
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_MD_VC2_CREDIT_OUT_MASK 0x0000200000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_OUT                 */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_OUT_SHFT 46
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_OUT_MASK 0x0000400000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_OUT                 */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_OUT_SHFT 47
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_OUT_MASK 0x0000800000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_OUT                  */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_OUT_SHFT 48
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_OUT_MASK 0x0001000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_OUT                  */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_OUT_SHFT 49
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_OUT_MASK 0x0002000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_OUT                  */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_OUT_SHFT 50
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_OUT_MASK 0x0004000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_OUT                  */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_OUT_SHFT 51
+#define SH_XNIILB_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_OUT_MASK 0x0008000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC0_CREDIT_OUT                  */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC0_CREDIT_OUT_SHFT 52
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC0_CREDIT_OUT_MASK 0x0010000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC2_CREDIT_OUT                  */
+/*   Description:  PI VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC2_CREDIT_OUT_SHFT 53
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_PI_VC2_CREDIT_OUT_MASK 0x0020000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC0_CREDIT_OUT                  */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC0_CREDIT_OUT_SHFT 54
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC0_CREDIT_OUT_MASK 0x0040000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC2_CREDIT_OUT                  */
+/*   Description:  MD VC0 Credit overflow Pipe Out                      */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC2_CREDIT_OUT_SHFT 55
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_MD_VC2_CREDIT_OUT_MASK 0x0080000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_OUT                */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_OUT_SHFT 56
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_OUT_MASK 0x0100000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_OUT                */
+/*   Description:  IILB VC0 Credit overflow Pipe Out                    */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_OUT_SHFT 57
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_OUT_MASK 0x0200000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_OUT                 */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_OUT_SHFT 58
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_OUT_MASK 0x0400000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_OUT                 */
+/*   Description:  NI0 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_OUT_SHFT 59
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_OUT_MASK 0x0800000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_OUT                 */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_OUT_SHFT 60
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_OUT_MASK 0x1000000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_OUT                 */
+/*   Description:  NI1 VC0 Credit overflow Pipe Out                     */
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_OUT_SHFT 61
+#define SH_XNIILB_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_OUT_MASK 0x2000000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_CHIPLET_NOMATCH                              */
+/*   Description:  chiplet nomatch                                      */
+#define SH_XNIILB_FIRST_ERROR_CHIPLET_NOMATCH_SHFT 62
+#define SH_XNIILB_FIRST_ERROR_CHIPLET_NOMATCH_MASK 0x4000000000000000
+
+/*   SH_XNIILB_FIRST_ERROR_LUT_READ_ERROR                               */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNIILB_FIRST_ERROR_LUT_READ_ERROR_SHFT 63
+#define SH_XNIILB_FIRST_ERROR_LUT_READ_ERROR_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNPI_ERROR_SUMMARY"                   */
+/* ==================================================================== */
+
+#define SH_XNPI_ERROR_SUMMARY                    0x0000000150040300
+#define SH_XNPI_ERROR_SUMMARY_MASK               0x0003ffffffffffff
+#define SH_XNPI_ERROR_SUMMARY_INIT               0x0003ffffffffffff
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC0                            */
+/*   Description:  NI0 VC0 fifo underflow                               */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_SHFT 0
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_MASK 0x0000000000000001
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC0                             */
+/*   Description:  NI0 VC0 fifo overflow                                */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC0_SHFT 1
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC0_MASK 0x0000000000000002
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC2                            */
+/*   Description:  NI0 VC2 fifo underflow                               */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_SHFT 2
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_MASK 0x0000000000000004
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC2                             */
+/*   Description:  NI0 VC2 fifo overflow                                */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC2_SHFT 3
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC2_MASK 0x0000000000000008
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC0                            */
+/*   Description:  NI1 VC0 fifo underflow                               */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_SHFT 4
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_MASK 0x0000000000000010
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC0                             */
+/*   Description:  NI1 VC0 fifo overflow                                */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC0_SHFT 5
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC0_MASK 0x0000000000000020
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC2                            */
+/*   Description:  NI1 VC2 fifo underflow                               */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_SHFT 6
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_MASK 0x0000000000000040
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC2                             */
+/*   Description:  NI1 VC2 fifo overflow                                */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC2_SHFT 7
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC2_MASK 0x0000000000000080
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC0                           */
+/*   Description:  IILB VC0 fifo underflow                              */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_SHFT 8
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC0                            */
+/*   Description:  IILB VC0 fifo overflow                               */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC0_SHFT 9
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC0_MASK 0x0000000000000200
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC2                           */
+/*   Description:  IILB VC2 fifo underflow                              */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_SHFT 10
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_MASK 0x0000000000000400
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC2                            */
+/*   Description:  IILB VC2 fifo overflow                               */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC2_SHFT 11
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_VC0_CREDIT                         */
+/*   Description:  VC0 Credit underflow                                 */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_VC0_CREDIT_SHFT 12
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_VC0_CREDIT                          */
+/*   Description:  VC0 Credit overflow                                  */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_VC0_CREDIT_SHFT 13
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_VC0_CREDIT_MASK 0x0000000000002000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_VC2_CREDIT                         */
+/*   Description:  VC2 Credit underflow                                 */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_VC2_CREDIT_SHFT 14
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_VC2_CREDIT_MASK 0x0000000000004000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_VC2_CREDIT                          */
+/*   Description:  VC2 Credit overflow                                  */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_VC2_CREDIT_SHFT 15
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC0                        */
+/*   Description:  VC0 Data Buffer overflow                             */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC0_SHFT 16
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC0_MASK 0x0000000000010000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC2                        */
+/*   Description:  VC2 Data Buffer overflow                             */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC2_SHFT 17
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC2_MASK 0x0000000000020000
+
+/*   SH_XNPI_ERROR_SUMMARY_LUT_READ_ERROR                               */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNPI_ERROR_SUMMARY_LUT_READ_ERROR_SHFT 18
+#define SH_XNPI_ERROR_SUMMARY_LUT_READ_ERROR_MASK 0x0000000000040000
+
+/*   SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR0                            */
+/*   Description:  Single Bit Error in Bits 63:0                        */
+#define SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR0_SHFT 19
+#define SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR0_MASK 0x0000000000080000
+
+/*   SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR1                            */
+/*   Description:  Single Bit Error in Bits 127:64                      */
+#define SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR1_SHFT 20
+#define SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR1_MASK 0x0000000000100000
+
+/*   SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR2                            */
+/*   Description:  Single Bit Error in Bits 191:128                     */
+#define SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR2_SHFT 21
+#define SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR2_MASK 0x0000000000200000
+
+/*   SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR3                            */
+/*   Description:  Single Bit Error in Bits 255:192                     */
+#define SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR3_SHFT 22
+#define SH_XNPI_ERROR_SUMMARY_SINGLE_BIT_ERROR3_MASK 0x0000000000400000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR0                                 */
+/*   Description:  Uncorrectable Error in Bits 63:0                     */
+#define SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR0_SHFT  23
+#define SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR0_MASK  0x0000000000800000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR1                                 */
+/*   Description:  Uncorrectable Error in Bits 127:64                   */
+#define SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR1_SHFT  24
+#define SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR1_MASK  0x0000000001000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR2                                 */
+/*   Description:  Uncorrectable Error in Bits 191:128                  */
+#define SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR2_SHFT  25
+#define SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR2_MASK  0x0000000002000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR3                                 */
+/*   Description:  Uncorrectable Error in Bits 255:192                  */
+#define SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR3_SHFT  26
+#define SH_XNPI_ERROR_SUMMARY_UNCOR_ERROR3_MASK  0x0000000004000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR0                          */
+/*   Description:  SIC Counter 0 Underflow                              */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR0_SHFT 27
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR0_MASK 0x0000000008000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_SIC_CNTR0                           */
+/*   Description:  SIC Counter 0 Overflow                               */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_SIC_CNTR0_SHFT 28
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_SIC_CNTR0_MASK 0x0000000010000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR2                          */
+/*   Description:  SIC Counter 2 Underflow                              */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR2_SHFT 29
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR2_MASK 0x0000000020000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_SIC_CNTR2                           */
+/*   Description:  SIC Counter 2 Overflow                               */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_SIC_CNTR2_SHFT 30
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_SIC_CNTR2_MASK 0x0000000040000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0                          */
+/*   Description:  NI0 Debit 0 Overflow                                 */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0_SHFT 31
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0_MASK 0x0000000080000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2                          */
+/*   Description:  NI0 Debit 2 Overflow                                 */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2_SHFT 32
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2_MASK 0x0000000100000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0                          */
+/*   Description:  NI1 Debit 0 Overflow                                 */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0_SHFT 33
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0_MASK 0x0000000200000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2                          */
+/*   Description:  NI1 Debit 2 Overflow                                 */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2_SHFT 34
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2_MASK 0x0000000400000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0                         */
+/*   Description:  IILB Debit 0 Overflow                                */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0_SHFT 35
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0_MASK 0x0000000800000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2                         */
+/*   Description:  IILB Debit 2 Overflow                                */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2_SHFT 36
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2_MASK 0x0000001000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT                     */
+/*   Description:  NI0 VC0 Credit Underflow                             */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_SHFT 37
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_MASK 0x0000002000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT                      */
+/*   Description:  NI0 VC0 Credit Overflow                              */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_SHFT 38
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_MASK 0x0000004000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT                     */
+/*   Description:  NI0 VC2 Credit Underflow                             */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_SHFT 39
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_MASK 0x0000008000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT                      */
+/*   Description:  NI0 VC2 Credit Overflow                              */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_SHFT 40
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_MASK 0x0000010000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT                     */
+/*   Description:  NI1 VC0 Credit Underflow                             */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_SHFT 41
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_MASK 0x0000020000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT                      */
+/*   Description:  NI1 VC0 Credit Overflow                              */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_SHFT 42
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_MASK 0x0000040000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT                     */
+/*   Description:  NI1 VC2 Credit Underflow                             */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_SHFT 43
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_MASK 0x0000080000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT                      */
+/*   Description:  NI1 VC2 Credit Overflow                              */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_SHFT 44
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_MASK 0x0000100000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT                    */
+/*   Description:  IILB VC0 Credit Underflow                            */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_SHFT 45
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_MASK 0x0000200000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT                     */
+/*   Description:  IILB VC0 Credit Overflow                             */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_SHFT 46
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT                    */
+/*   Description:  IILB VC2 Credit Underflow                            */
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_SHFT 47
+#define SH_XNPI_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT                     */
+/*   Description:  IILB VC2 Credit Overflow                             */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_SHFT 48
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_MASK 0x0001000000000000
+
+/*   SH_XNPI_ERROR_SUMMARY_OVERFLOW_HEADER_CANCEL_FIFO                  */
+/*   Description:  Header Cancel Fifo Overflow                          */
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_HEADER_CANCEL_FIFO_SHFT 49
+#define SH_XNPI_ERROR_SUMMARY_OVERFLOW_HEADER_CANCEL_FIFO_MASK 0x0002000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNPI_ERRORS_ALIAS"                    */
+/* ==================================================================== */
+
+#define SH_XNPI_ERRORS_ALIAS                     0x0000000150040308
+
+/* ==================================================================== */
+/*                  Register "SH_XNPI_ERROR_OVERFLOW"                   */
+/* ==================================================================== */
+
+#define SH_XNPI_ERROR_OVERFLOW                   0x0000000150040320
+#define SH_XNPI_ERROR_OVERFLOW_MASK              0x0003ffffffffffff
+#define SH_XNPI_ERROR_OVERFLOW_INIT              0x0003ffffffffffff
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0                           */
+/*   Description:  NI0 VC0 fifo underflow                               */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_SHFT 0
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_MASK 0x0000000000000001
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC0                            */
+/*   Description:  NI0 VC0 fifo overflow                                */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_SHFT 1
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_MASK 0x0000000000000002
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2                           */
+/*   Description:  NI0 VC2 fifo underflow                               */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_SHFT 2
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_MASK 0x0000000000000004
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC2                            */
+/*   Description:  NI0 VC2 fifo overflow                                */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_SHFT 3
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_MASK 0x0000000000000008
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0                           */
+/*   Description:  NI1 VC0 fifo underflow                               */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_SHFT 4
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_MASK 0x0000000000000010
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC0                            */
+/*   Description:  NI1 VC0 fifo overflow                                */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_SHFT 5
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_MASK 0x0000000000000020
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2                           */
+/*   Description:  NI1 VC2 fifo underflow                               */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_SHFT 6
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_MASK 0x0000000000000040
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC2                            */
+/*   Description:  NI1 VC2 fifo overflow                                */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_SHFT 7
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_MASK 0x0000000000000080
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0                          */
+/*   Description:  IILB VC0 fifo underflow                              */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_SHFT 8
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC0                           */
+/*   Description:  IILB VC0 fifo overflow                               */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_SHFT 9
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_MASK 0x0000000000000200
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2                          */
+/*   Description:  IILB VC2 fifo underflow                              */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_SHFT 10
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_MASK 0x0000000000000400
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC2                           */
+/*   Description:  IILB VC2 fifo overflow                               */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_SHFT 11
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_VC0_CREDIT                        */
+/*   Description:  VC0 Credit underflow                                 */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_VC0_CREDIT_SHFT 12
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_VC0_CREDIT                         */
+/*   Description:  VC0 Credit overflow                                  */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_VC0_CREDIT_SHFT 13
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_VC0_CREDIT_MASK 0x0000000000002000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_VC2_CREDIT                        */
+/*   Description:  VC2 Credit underflow                                 */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_VC2_CREDIT_SHFT 14
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_VC2_CREDIT_MASK 0x0000000000004000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_VC2_CREDIT                         */
+/*   Description:  VC2 Credit overflow                                  */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_VC2_CREDIT_SHFT 15
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC0                       */
+/*   Description:  VC0 Data Buffer overflow                             */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC0_SHFT 16
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC0_MASK 0x0000000000010000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC2                       */
+/*   Description:  VC2 Data Buffer overflow                             */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC2_SHFT 17
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC2_MASK 0x0000000000020000
+
+/*   SH_XNPI_ERROR_OVERFLOW_LUT_READ_ERROR                              */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNPI_ERROR_OVERFLOW_LUT_READ_ERROR_SHFT 18
+#define SH_XNPI_ERROR_OVERFLOW_LUT_READ_ERROR_MASK 0x0000000000040000
+
+/*   SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR0                           */
+/*   Description:  Single Bit Error in Bits 63:0                        */
+#define SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR0_SHFT 19
+#define SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR0_MASK 0x0000000000080000
+
+/*   SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR1                           */
+/*   Description:  Single Bit Error in Bits 127:64                      */
+#define SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR1_SHFT 20
+#define SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR1_MASK 0x0000000000100000
+
+/*   SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR2                           */
+/*   Description:  Single Bit Error in Bits 191:128                     */
+#define SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR2_SHFT 21
+#define SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR2_MASK 0x0000000000200000
+
+/*   SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR3                           */
+/*   Description:  Single Bit Error in Bits 255:192                     */
+#define SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR3_SHFT 22
+#define SH_XNPI_ERROR_OVERFLOW_SINGLE_BIT_ERROR3_MASK 0x0000000000400000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR0                                */
+/*   Description:  Uncorrectable Error in Bits 63:0                     */
+#define SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR0_SHFT 23
+#define SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR0_MASK 0x0000000000800000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR1                                */
+/*   Description:  Uncorrectable Error in Bits 127:64                   */
+#define SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR1_SHFT 24
+#define SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR1_MASK 0x0000000001000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR2                                */
+/*   Description:  Uncorrectable Error in Bits 191:128                  */
+#define SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR2_SHFT 25
+#define SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR2_MASK 0x0000000002000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR3                                */
+/*   Description:  Uncorrectable Error in Bits 255:192                  */
+#define SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR3_SHFT 26
+#define SH_XNPI_ERROR_OVERFLOW_UNCOR_ERROR3_MASK 0x0000000004000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR0                         */
+/*   Description:  SIC Counter 0 Underflow                              */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR0_SHFT 27
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR0_MASK 0x0000000008000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR0                          */
+/*   Description:  SIC Counter 0 Overflow                               */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR0_SHFT 28
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR0_MASK 0x0000000010000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR2                         */
+/*   Description:  SIC Counter 2 Underflow                              */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR2_SHFT 29
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR2_MASK 0x0000000020000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR2                          */
+/*   Description:  SIC Counter 2 Overflow                               */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR2_SHFT 30
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR2_MASK 0x0000000040000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0                         */
+/*   Description:  NI0 Debit 0 Overflow                                 */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0_SHFT 31
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0_MASK 0x0000000080000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2                         */
+/*   Description:  NI0 Debit 2 Overflow                                 */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2_SHFT 32
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2_MASK 0x0000000100000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0                         */
+/*   Description:  NI1 Debit 0 Overflow                                 */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0_SHFT 33
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0_MASK 0x0000000200000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2                         */
+/*   Description:  NI1 Debit 2 Overflow                                 */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2_SHFT 34
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2_MASK 0x0000000400000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0                        */
+/*   Description:  IILB Debit 0 Overflow                                */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0_SHFT 35
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0_MASK 0x0000000800000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2                        */
+/*   Description:  IILB Debit 2 Overflow                                */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2_SHFT 36
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2_MASK 0x0000001000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT                    */
+/*   Description:  NI0 VC0 Credit Underflow                             */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_SHFT 37
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_MASK 0x0000002000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT                     */
+/*   Description:  NI0 VC0 Credit Overflow                              */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_SHFT 38
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_MASK 0x0000004000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT                    */
+/*   Description:  NI0 VC2 Credit Underflow                             */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_SHFT 39
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_MASK 0x0000008000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT                     */
+/*   Description:  NI0 VC2 Credit Overflow                              */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_SHFT 40
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_MASK 0x0000010000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT                    */
+/*   Description:  NI1 VC0 Credit Underflow                             */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_SHFT 41
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_MASK 0x0000020000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT                     */
+/*   Description:  NI1 VC0 Credit Overflow                              */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_SHFT 42
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_MASK 0x0000040000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT                    */
+/*   Description:  NI1 VC2 Credit Underflow                             */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_SHFT 43
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_MASK 0x0000080000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT                     */
+/*   Description:  NI1 VC2 Credit Overflow                              */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_SHFT 44
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_MASK 0x0000100000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT                   */
+/*   Description:  IILB VC0 Credit Underflow                            */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_SHFT 45
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_MASK 0x0000200000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT                    */
+/*   Description:  IILB VC0 Credit Overflow                             */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_SHFT 46
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT                   */
+/*   Description:  IILB VC2 Credit Underflow                            */
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_SHFT 47
+#define SH_XNPI_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT                    */
+/*   Description:  IILB VC2 Credit Overflow                             */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_SHFT 48
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_MASK 0x0001000000000000
+
+/*   SH_XNPI_ERROR_OVERFLOW_OVERFLOW_HEADER_CANCEL_FIFO                 */
+/*   Description:  Header Cancel Fifo Overflow                          */
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_HEADER_CANCEL_FIFO_SHFT 49
+#define SH_XNPI_ERROR_OVERFLOW_OVERFLOW_HEADER_CANCEL_FIFO_MASK 0x0002000000000000
+
+/* ==================================================================== */
+/*               Register "SH_XNPI_ERROR_OVERFLOW_ALIAS"                */
+/* ==================================================================== */
+
+#define SH_XNPI_ERROR_OVERFLOW_ALIAS             0x0000000150040328
+
+/* ==================================================================== */
+/*                    Register "SH_XNPI_ERROR_MASK"                     */
+/* ==================================================================== */
+
+#define SH_XNPI_ERROR_MASK                       0x0000000150040340
+#define SH_XNPI_ERROR_MASK_MASK                  0x0003ffffffffffff
+#define SH_XNPI_ERROR_MASK_INIT                  0x0003ffffffffffff
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC0                               */
+/*   Description:  NI0 VC0 fifo underflow                               */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC0_SHFT 0
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC0_MASK 0x0000000000000001
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC0                                */
+/*   Description:  NI0 VC0 fifo overflow                                */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC0_SHFT 1
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC0_MASK 0x0000000000000002
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC2                               */
+/*   Description:  NI0 VC2 fifo underflow                               */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC2_SHFT 2
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC2_MASK 0x0000000000000004
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC2                                */
+/*   Description:  NI0 VC2 fifo overflow                                */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC2_SHFT 3
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC2_MASK 0x0000000000000008
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC0                               */
+/*   Description:  NI1 VC0 fifo underflow                               */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC0_SHFT 4
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC0_MASK 0x0000000000000010
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC0                                */
+/*   Description:  NI1 VC0 fifo overflow                                */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC0_SHFT 5
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC0_MASK 0x0000000000000020
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC2                               */
+/*   Description:  NI1 VC2 fifo underflow                               */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC2_SHFT 6
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC2_MASK 0x0000000000000040
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC2                                */
+/*   Description:  NI1 VC2 fifo overflow                                */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC2_SHFT 7
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC2_MASK 0x0000000000000080
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC0                              */
+/*   Description:  IILB VC0 fifo underflow                              */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC0_SHFT 8
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC0                               */
+/*   Description:  IILB VC0 fifo overflow                               */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC0_SHFT 9
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC0_MASK 0x0000000000000200
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC2                              */
+/*   Description:  IILB VC2 fifo underflow                              */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC2_SHFT 10
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC2_MASK 0x0000000000000400
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC2                               */
+/*   Description:  IILB VC2 fifo overflow                               */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC2_SHFT 11
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_VC0_CREDIT                            */
+/*   Description:  VC0 Credit underflow                                 */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_VC0_CREDIT_SHFT 12
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_VC0_CREDIT                             */
+/*   Description:  VC0 Credit overflow                                  */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_VC0_CREDIT_SHFT 13
+#define SH_XNPI_ERROR_MASK_OVERFLOW_VC0_CREDIT_MASK 0x0000000000002000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_VC2_CREDIT                            */
+/*   Description:  VC2 Credit underflow                                 */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_VC2_CREDIT_SHFT 14
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_VC2_CREDIT_MASK 0x0000000000004000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_VC2_CREDIT                             */
+/*   Description:  VC2 Credit overflow                                  */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_VC2_CREDIT_SHFT 15
+#define SH_XNPI_ERROR_MASK_OVERFLOW_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_DATABUFF_VC0                           */
+/*   Description:  VC0 Data Buffer overflow                             */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_DATABUFF_VC0_SHFT 16
+#define SH_XNPI_ERROR_MASK_OVERFLOW_DATABUFF_VC0_MASK 0x0000000000010000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_DATABUFF_VC2                           */
+/*   Description:  VC2 Data Buffer overflow                             */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_DATABUFF_VC2_SHFT 17
+#define SH_XNPI_ERROR_MASK_OVERFLOW_DATABUFF_VC2_MASK 0x0000000000020000
+
+/*   SH_XNPI_ERROR_MASK_LUT_READ_ERROR                                  */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNPI_ERROR_MASK_LUT_READ_ERROR_SHFT   18
+#define SH_XNPI_ERROR_MASK_LUT_READ_ERROR_MASK   0x0000000000040000
+
+/*   SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR0                               */
+/*   Description:  Single Bit Error in Bits 63:0                        */
+#define SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR0_SHFT 19
+#define SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR0_MASK 0x0000000000080000
+
+/*   SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR1                               */
+/*   Description:  Single Bit Error in Bits 127:64                      */
+#define SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR1_SHFT 20
+#define SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR1_MASK 0x0000000000100000
+
+/*   SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR2                               */
+/*   Description:  Single Bit Error in Bits 191:128                     */
+#define SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR2_SHFT 21
+#define SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR2_MASK 0x0000000000200000
+
+/*   SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR3                               */
+/*   Description:  Single Bit Error in Bits 255:192                     */
+#define SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR3_SHFT 22
+#define SH_XNPI_ERROR_MASK_SINGLE_BIT_ERROR3_MASK 0x0000000000400000
+
+/*   SH_XNPI_ERROR_MASK_UNCOR_ERROR0                                    */
+/*   Description:  Uncorrectable Error in Bits 63:0                     */
+#define SH_XNPI_ERROR_MASK_UNCOR_ERROR0_SHFT     23
+#define SH_XNPI_ERROR_MASK_UNCOR_ERROR0_MASK     0x0000000000800000
+
+/*   SH_XNPI_ERROR_MASK_UNCOR_ERROR1                                    */
+/*   Description:  Uncorrectable Error in Bits 127:64                   */
+#define SH_XNPI_ERROR_MASK_UNCOR_ERROR1_SHFT     24
+#define SH_XNPI_ERROR_MASK_UNCOR_ERROR1_MASK     0x0000000001000000
+
+/*   SH_XNPI_ERROR_MASK_UNCOR_ERROR2                                    */
+/*   Description:  Uncorrectable Error in Bits 191:128                  */
+#define SH_XNPI_ERROR_MASK_UNCOR_ERROR2_SHFT     25
+#define SH_XNPI_ERROR_MASK_UNCOR_ERROR2_MASK     0x0000000002000000
+
+/*   SH_XNPI_ERROR_MASK_UNCOR_ERROR3                                    */
+/*   Description:  Uncorrectable Error in Bits 255:192                  */
+#define SH_XNPI_ERROR_MASK_UNCOR_ERROR3_SHFT     26
+#define SH_XNPI_ERROR_MASK_UNCOR_ERROR3_MASK     0x0000000004000000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_SIC_CNTR0                             */
+/*   Description:  SIC Counter 0 Underflow                              */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_SIC_CNTR0_SHFT 27
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_SIC_CNTR0_MASK 0x0000000008000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_SIC_CNTR0                              */
+/*   Description:  SIC Counter 0 Overflow                               */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_SIC_CNTR0_SHFT 28
+#define SH_XNPI_ERROR_MASK_OVERFLOW_SIC_CNTR0_MASK 0x0000000010000000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_SIC_CNTR2                             */
+/*   Description:  SIC Counter 2 Underflow                              */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_SIC_CNTR2_SHFT 29
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_SIC_CNTR2_MASK 0x0000000020000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_SIC_CNTR2                              */
+/*   Description:  SIC Counter 2 Overflow                               */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_SIC_CNTR2_SHFT 30
+#define SH_XNPI_ERROR_MASK_OVERFLOW_SIC_CNTR2_MASK 0x0000000040000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI0_DEBIT0                             */
+/*   Description:  NI0 Debit 0 Overflow                                 */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_DEBIT0_SHFT 31
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_DEBIT0_MASK 0x0000000080000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI0_DEBIT2                             */
+/*   Description:  NI0 Debit 2 Overflow                                 */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_DEBIT2_SHFT 32
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_DEBIT2_MASK 0x0000000100000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI1_DEBIT0                             */
+/*   Description:  NI1 Debit 0 Overflow                                 */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_DEBIT0_SHFT 33
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_DEBIT0_MASK 0x0000000200000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI1_DEBIT2                             */
+/*   Description:  NI1 Debit 2 Overflow                                 */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_DEBIT2_SHFT 34
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_DEBIT2_MASK 0x0000000400000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_IILB_DEBIT0                            */
+/*   Description:  IILB Debit 0 Overflow                                */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_DEBIT0_SHFT 35
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_DEBIT0_MASK 0x0000000800000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_IILB_DEBIT2                            */
+/*   Description:  IILB Debit 2 Overflow                                */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_DEBIT2_SHFT 36
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_DEBIT2_MASK 0x0000001000000000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT                        */
+/*   Description:  NI0 VC0 Credit Underflow                             */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_SHFT 37
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_MASK 0x0000002000000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT                         */
+/*   Description:  NI0 VC0 Credit Overflow                              */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_SHFT 38
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_MASK 0x0000004000000000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT                        */
+/*   Description:  NI0 VC2 Credit Underflow                             */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_SHFT 39
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_MASK 0x0000008000000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT                         */
+/*   Description:  NI0 VC2 Credit Overflow                              */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_SHFT 40
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_MASK 0x0000010000000000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT                        */
+/*   Description:  NI1 VC0 Credit Underflow                             */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_SHFT 41
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_MASK 0x0000020000000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT                         */
+/*   Description:  NI1 VC0 Credit Overflow                              */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_SHFT 42
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_MASK 0x0000040000000000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT                        */
+/*   Description:  NI1 VC2 Credit Underflow                             */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_SHFT 43
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_MASK 0x0000080000000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT                         */
+/*   Description:  NI1 VC2 Credit Overflow                              */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_SHFT 44
+#define SH_XNPI_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_MASK 0x0000100000000000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT                       */
+/*   Description:  IILB VC0 Credit Underflow                            */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_SHFT 45
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_MASK 0x0000200000000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT                        */
+/*   Description:  IILB VC0 Credit Overflow                             */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_SHFT 46
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT                       */
+/*   Description:  IILB VC2 Credit Underflow                            */
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_SHFT 47
+#define SH_XNPI_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT                        */
+/*   Description:  IILB VC2 Credit Overflow                             */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_SHFT 48
+#define SH_XNPI_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_MASK 0x0001000000000000
+
+/*   SH_XNPI_ERROR_MASK_OVERFLOW_HEADER_CANCEL_FIFO                     */
+/*   Description:  Header Cancel Fifo Overflow                          */
+#define SH_XNPI_ERROR_MASK_OVERFLOW_HEADER_CANCEL_FIFO_SHFT 49
+#define SH_XNPI_ERROR_MASK_OVERFLOW_HEADER_CANCEL_FIFO_MASK 0x0002000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNPI_FIRST_ERROR"                    */
+/* ==================================================================== */
+
+#define SH_XNPI_FIRST_ERROR                      0x0000000150040360
+#define SH_XNPI_FIRST_ERROR_MASK                 0x0003ffffffffffff
+#define SH_XNPI_FIRST_ERROR_INIT                 0x0003ffffffffffff
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC0                              */
+/*   Description:  NI0 VC0 fifo underflow                               */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC0_SHFT 0
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC0_MASK 0x0000000000000001
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC0                               */
+/*   Description:  NI0 VC0 fifo overflow                                */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC0_SHFT 1
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC0_MASK 0x0000000000000002
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC2                              */
+/*   Description:  NI0 VC2 fifo underflow                               */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC2_SHFT 2
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC2_MASK 0x0000000000000004
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC2                               */
+/*   Description:  NI0 VC2 fifo overflow                                */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC2_SHFT 3
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC2_MASK 0x0000000000000008
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC0                              */
+/*   Description:  NI1 VC0 fifo underflow                               */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC0_SHFT 4
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC0_MASK 0x0000000000000010
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC0                               */
+/*   Description:  NI1 VC0 fifo overflow                                */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC0_SHFT 5
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC0_MASK 0x0000000000000020
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC2                              */
+/*   Description:  NI1 VC2 fifo underflow                               */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC2_SHFT 6
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC2_MASK 0x0000000000000040
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC2                               */
+/*   Description:  NI1 VC2 fifo overflow                                */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC2_SHFT 7
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC2_MASK 0x0000000000000080
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC0                             */
+/*   Description:  IILB VC0 fifo underflow                              */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC0_SHFT 8
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC0                              */
+/*   Description:  IILB VC0 fifo overflow                               */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC0_SHFT 9
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC0_MASK 0x0000000000000200
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC2                             */
+/*   Description:  IILB VC2 fifo underflow                              */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC2_SHFT 10
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC2_MASK 0x0000000000000400
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC2                              */
+/*   Description:  IILB VC2 fifo overflow                               */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC2_SHFT 11
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_VC0_CREDIT                           */
+/*   Description:  VC0 Credit underflow                                 */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_VC0_CREDIT_SHFT 12
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_VC0_CREDIT                            */
+/*   Description:  VC0 Credit overflow                                  */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_VC0_CREDIT_SHFT 13
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_VC0_CREDIT_MASK 0x0000000000002000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_VC2_CREDIT                           */
+/*   Description:  VC2 Credit underflow                                 */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_VC2_CREDIT_SHFT 14
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_VC2_CREDIT_MASK 0x0000000000004000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_VC2_CREDIT                            */
+/*   Description:  VC2 Credit overflow                                  */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_VC2_CREDIT_SHFT 15
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_DATABUFF_VC0                          */
+/*   Description:  VC0 Data Buffer overflow                             */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_DATABUFF_VC0_SHFT 16
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_DATABUFF_VC0_MASK 0x0000000000010000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_DATABUFF_VC2                          */
+/*   Description:  VC2 Data Buffer overflow                             */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_DATABUFF_VC2_SHFT 17
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_DATABUFF_VC2_MASK 0x0000000000020000
+
+/*   SH_XNPI_FIRST_ERROR_LUT_READ_ERROR                                 */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNPI_FIRST_ERROR_LUT_READ_ERROR_SHFT  18
+#define SH_XNPI_FIRST_ERROR_LUT_READ_ERROR_MASK  0x0000000000040000
+
+/*   SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR0                              */
+/*   Description:  Single Bit Error in Bits 63:0                        */
+#define SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR0_SHFT 19
+#define SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR0_MASK 0x0000000000080000
+
+/*   SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR1                              */
+/*   Description:  Single Bit Error in Bits 127:64                      */
+#define SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR1_SHFT 20
+#define SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR1_MASK 0x0000000000100000
+
+/*   SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR2                              */
+/*   Description:  Single Bit Error in Bits 191:128                     */
+#define SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR2_SHFT 21
+#define SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR2_MASK 0x0000000000200000
+
+/*   SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR3                              */
+/*   Description:  Single Bit Error in Bits 255:192                     */
+#define SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR3_SHFT 22
+#define SH_XNPI_FIRST_ERROR_SINGLE_BIT_ERROR3_MASK 0x0000000000400000
+
+/*   SH_XNPI_FIRST_ERROR_UNCOR_ERROR0                                   */
+/*   Description:  Uncorrectable Error in Bits 63:0                     */
+#define SH_XNPI_FIRST_ERROR_UNCOR_ERROR0_SHFT    23
+#define SH_XNPI_FIRST_ERROR_UNCOR_ERROR0_MASK    0x0000000000800000
+
+/*   SH_XNPI_FIRST_ERROR_UNCOR_ERROR1                                   */
+/*   Description:  Uncorrectable Error in Bits 127:64                   */
+#define SH_XNPI_FIRST_ERROR_UNCOR_ERROR1_SHFT    24
+#define SH_XNPI_FIRST_ERROR_UNCOR_ERROR1_MASK    0x0000000001000000
+
+/*   SH_XNPI_FIRST_ERROR_UNCOR_ERROR2                                   */
+/*   Description:  Uncorrectable Error in Bits 191:128                  */
+#define SH_XNPI_FIRST_ERROR_UNCOR_ERROR2_SHFT    25
+#define SH_XNPI_FIRST_ERROR_UNCOR_ERROR2_MASK    0x0000000002000000
+
+/*   SH_XNPI_FIRST_ERROR_UNCOR_ERROR3                                   */
+/*   Description:  Uncorrectable Error in Bits 255:192                  */
+#define SH_XNPI_FIRST_ERROR_UNCOR_ERROR3_SHFT    26
+#define SH_XNPI_FIRST_ERROR_UNCOR_ERROR3_MASK    0x0000000004000000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_SIC_CNTR0                            */
+/*   Description:  SIC Counter 0 Underflow                              */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_SIC_CNTR0_SHFT 27
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_SIC_CNTR0_MASK 0x0000000008000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_SIC_CNTR0                             */
+/*   Description:  SIC Counter 0 Overflow                               */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_SIC_CNTR0_SHFT 28
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_SIC_CNTR0_MASK 0x0000000010000000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_SIC_CNTR2                            */
+/*   Description:  SIC Counter 2 Underflow                              */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_SIC_CNTR2_SHFT 29
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_SIC_CNTR2_MASK 0x0000000020000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_SIC_CNTR2                             */
+/*   Description:  SIC Counter 2 Overflow                               */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_SIC_CNTR2_SHFT 30
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_SIC_CNTR2_MASK 0x0000000040000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_DEBIT0                            */
+/*   Description:  NI0 Debit 0 Overflow                                 */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_DEBIT0_SHFT 31
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_DEBIT0_MASK 0x0000000080000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_DEBIT2                            */
+/*   Description:  NI0 Debit 2 Overflow                                 */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_DEBIT2_SHFT 32
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_DEBIT2_MASK 0x0000000100000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_DEBIT0                            */
+/*   Description:  NI1 Debit 0 Overflow                                 */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_DEBIT0_SHFT 33
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_DEBIT0_MASK 0x0000000200000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_DEBIT2                            */
+/*   Description:  NI1 Debit 2 Overflow                                 */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_DEBIT2_SHFT 34
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_DEBIT2_MASK 0x0000000400000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_DEBIT0                           */
+/*   Description:  IILB Debit 0 Overflow                                */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_DEBIT0_SHFT 35
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_DEBIT0_MASK 0x0000000800000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_DEBIT2                           */
+/*   Description:  IILB Debit 2 Overflow                                */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_DEBIT2_SHFT 36
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_DEBIT2_MASK 0x0000001000000000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT                       */
+/*   Description:  NI0 VC0 Credit Underflow                             */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_SHFT 37
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_MASK 0x0000002000000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT                        */
+/*   Description:  NI0 VC0 Credit Overflow                              */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_SHFT 38
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_MASK 0x0000004000000000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT                       */
+/*   Description:  NI0 VC2 Credit Underflow                             */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_SHFT 39
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_MASK 0x0000008000000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT                        */
+/*   Description:  NI0 VC2 Credit Overflow                              */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_SHFT 40
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_MASK 0x0000010000000000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT                       */
+/*   Description:  NI1 VC0 Credit Underflow                             */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_SHFT 41
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_MASK 0x0000020000000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT                        */
+/*   Description:  NI1 VC0 Credit Overflow                              */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_SHFT 42
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_MASK 0x0000040000000000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT                       */
+/*   Description:  NI1 VC2 Credit Underflow                             */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_SHFT 43
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_MASK 0x0000080000000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT                        */
+/*   Description:  NI1 VC2 Credit Overflow                              */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_SHFT 44
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_MASK 0x0000100000000000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT                      */
+/*   Description:  IILB VC0 Credit Underflow                            */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_SHFT 45
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_MASK 0x0000200000000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT                       */
+/*   Description:  IILB VC0 Credit Overflow                             */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_SHFT 46
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT                      */
+/*   Description:  IILB VC2 Credit Underflow                            */
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_SHFT 47
+#define SH_XNPI_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT                       */
+/*   Description:  IILB VC2 Credit Overflow                             */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_SHFT 48
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_MASK 0x0001000000000000
+
+/*   SH_XNPI_FIRST_ERROR_OVERFLOW_HEADER_CANCEL_FIFO                    */
+/*   Description:  Header Cancel Fifo Overflow                          */
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_HEADER_CANCEL_FIFO_SHFT 49
+#define SH_XNPI_FIRST_ERROR_OVERFLOW_HEADER_CANCEL_FIFO_MASK 0x0002000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNMD_ERROR_SUMMARY"                   */
+/* ==================================================================== */
+
+#define SH_XNMD_ERROR_SUMMARY                    0x0000000150040400
+#define SH_XNMD_ERROR_SUMMARY_MASK               0x0003ffffffffffff
+#define SH_XNMD_ERROR_SUMMARY_INIT               0x0003ffffffffffff
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC0                            */
+/*   Description:  NI0 VC0 fifo underflow                               */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_SHFT 0
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_MASK 0x0000000000000001
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC0                             */
+/*   Description:  NI0 VC0 fifo overflow                                */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC0_SHFT 1
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC0_MASK 0x0000000000000002
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC2                            */
+/*   Description:  NI0 VC2 fifo underflow                               */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_SHFT 2
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_MASK 0x0000000000000004
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC2                             */
+/*   Description:  NI0 VC2 fifo overflow                                */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC2_SHFT 3
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC2_MASK 0x0000000000000008
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC0                            */
+/*   Description:  NI1 VC0 fifo underflow                               */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_SHFT 4
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_MASK 0x0000000000000010
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC0                             */
+/*   Description:  NI1 VC0 fifo overflow                                */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC0_SHFT 5
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC0_MASK 0x0000000000000020
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC2                            */
+/*   Description:  NI1 VC2 fifo underflow                               */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_SHFT 6
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_MASK 0x0000000000000040
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC2                             */
+/*   Description:  NI1 VC2 fifo overflow                                */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC2_SHFT 7
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC2_MASK 0x0000000000000080
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC0                           */
+/*   Description:  IILB VC0 fifo underflow                              */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_SHFT 8
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC0                            */
+/*   Description:  IILB VC0 fifo overflow                               */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC0_SHFT 9
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC0_MASK 0x0000000000000200
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC2                           */
+/*   Description:  IILB VC2 fifo underflow                              */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_SHFT 10
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_MASK 0x0000000000000400
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC2                            */
+/*   Description:  IILB VC2 fifo overflow                               */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC2_SHFT 11
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_VC0_CREDIT                         */
+/*   Description:  VC0 Credit underflow                                 */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_VC0_CREDIT_SHFT 12
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_VC0_CREDIT                          */
+/*   Description:  VC0 Credit overflow                                  */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_VC0_CREDIT_SHFT 13
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_VC0_CREDIT_MASK 0x0000000000002000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_VC2_CREDIT                         */
+/*   Description:  VC2 Credit underflow                                 */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_VC2_CREDIT_SHFT 14
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_VC2_CREDIT_MASK 0x0000000000004000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_VC2_CREDIT                          */
+/*   Description:  VC2 Credit overflow                                  */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_VC2_CREDIT_SHFT 15
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC0                        */
+/*   Description:  VC0 Data Buffer overflow                             */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC0_SHFT 16
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC0_MASK 0x0000000000010000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC2                        */
+/*   Description:  VC2 Data Buffer overflow                             */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC2_SHFT 17
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_DATABUFF_VC2_MASK 0x0000000000020000
+
+/*   SH_XNMD_ERROR_SUMMARY_LUT_READ_ERROR                               */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNMD_ERROR_SUMMARY_LUT_READ_ERROR_SHFT 18
+#define SH_XNMD_ERROR_SUMMARY_LUT_READ_ERROR_MASK 0x0000000000040000
+
+/*   SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR0                            */
+/*   Description:  Single Bit Error in Bits 63:0                        */
+#define SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR0_SHFT 19
+#define SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR0_MASK 0x0000000000080000
+
+/*   SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR1                            */
+/*   Description:  Single Bit Error in Bits 127:64                      */
+#define SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR1_SHFT 20
+#define SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR1_MASK 0x0000000000100000
+
+/*   SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR2                            */
+/*   Description:  Single Bit Error in Bits 191:128                     */
+#define SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR2_SHFT 21
+#define SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR2_MASK 0x0000000000200000
+
+/*   SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR3                            */
+/*   Description:  Single Bit Error in Bits 255:192                     */
+#define SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR3_SHFT 22
+#define SH_XNMD_ERROR_SUMMARY_SINGLE_BIT_ERROR3_MASK 0x0000000000400000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR0                                 */
+/*   Description:  Uncorrectable Error in Bits 63:0                     */
+#define SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR0_SHFT  23
+#define SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR0_MASK  0x0000000000800000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR1                                 */
+/*   Description:  Uncorrectable Error in Bits 127:64                   */
+#define SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR1_SHFT  24
+#define SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR1_MASK  0x0000000001000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR2                                 */
+/*   Description:  Uncorrectable Error in Bits 191:128                  */
+#define SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR2_SHFT  25
+#define SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR2_MASK  0x0000000002000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR3                                 */
+/*   Description:  Uncorrectable Error in Bits 255:192                  */
+#define SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR3_SHFT  26
+#define SH_XNMD_ERROR_SUMMARY_UNCOR_ERROR3_MASK  0x0000000004000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR0                          */
+/*   Description:  SIC Counter 0 Underflow                              */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR0_SHFT 27
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR0_MASK 0x0000000008000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_SIC_CNTR0                           */
+/*   Description:  SIC Counter 0 Overflow                               */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_SIC_CNTR0_SHFT 28
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_SIC_CNTR0_MASK 0x0000000010000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR2                          */
+/*   Description:  SIC Counter 2 Underflow                              */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR2_SHFT 29
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_SIC_CNTR2_MASK 0x0000000020000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_SIC_CNTR2                           */
+/*   Description:  SIC Counter 2 Overflow                               */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_SIC_CNTR2_SHFT 30
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_SIC_CNTR2_MASK 0x0000000040000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0                          */
+/*   Description:  NI0 Debit 0 Overflow                                 */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0_SHFT 31
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT0_MASK 0x0000000080000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2                          */
+/*   Description:  NI0 Debit 2 Overflow                                 */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2_SHFT 32
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_DEBIT2_MASK 0x0000000100000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0                          */
+/*   Description:  NI1 Debit 0 Overflow                                 */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0_SHFT 33
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT0_MASK 0x0000000200000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2                          */
+/*   Description:  NI1 Debit 2 Overflow                                 */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2_SHFT 34
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_DEBIT2_MASK 0x0000000400000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0                         */
+/*   Description:  IILB Debit 0 Overflow                                */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0_SHFT 35
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT0_MASK 0x0000000800000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2                         */
+/*   Description:  IILB Debit 2 Overflow                                */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2_SHFT 36
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_DEBIT2_MASK 0x0000001000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT                     */
+/*   Description:  NI0 VC0 Credit Underflow                             */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_SHFT 37
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC0_CREDIT_MASK 0x0000002000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT                      */
+/*   Description:  NI0 VC0 Credit Overflow                              */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_SHFT 38
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC0_CREDIT_MASK 0x0000004000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT                     */
+/*   Description:  NI0 VC2 Credit Underflow                             */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_SHFT 39
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI0_VC2_CREDIT_MASK 0x0000008000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT                      */
+/*   Description:  NI0 VC2 Credit Overflow                              */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_SHFT 40
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI0_VC2_CREDIT_MASK 0x0000010000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT                     */
+/*   Description:  NI1 VC0 Credit Underflow                             */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_SHFT 41
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC0_CREDIT_MASK 0x0000020000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT                      */
+/*   Description:  NI1 VC0 Credit Overflow                              */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_SHFT 42
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC0_CREDIT_MASK 0x0000040000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT                     */
+/*   Description:  NI1 VC2 Credit Underflow                             */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_SHFT 43
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_NI1_VC2_CREDIT_MASK 0x0000080000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT                      */
+/*   Description:  NI1 VC2 Credit Overflow                              */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_SHFT 44
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_NI1_VC2_CREDIT_MASK 0x0000100000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT                    */
+/*   Description:  IILB VC0 Credit Underflow                            */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_SHFT 45
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC0_CREDIT_MASK 0x0000200000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT                     */
+/*   Description:  IILB VC0 Credit Overflow                             */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_SHFT 46
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT                    */
+/*   Description:  IILB VC2 Credit Underflow                            */
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_SHFT 47
+#define SH_XNMD_ERROR_SUMMARY_UNDERFLOW_IILB_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT                     */
+/*   Description:  IILB VC2 Credit Overflow                             */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_SHFT 48
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_IILB_VC2_CREDIT_MASK 0x0001000000000000
+
+/*   SH_XNMD_ERROR_SUMMARY_OVERFLOW_HEADER_CANCEL_FIFO                  */
+/*   Description:  Header Cancel Fifo Overflow                          */
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_HEADER_CANCEL_FIFO_SHFT 49
+#define SH_XNMD_ERROR_SUMMARY_OVERFLOW_HEADER_CANCEL_FIFO_MASK 0x0002000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XNMD_ERRORS_ALIAS"                    */
+/* ==================================================================== */
+
+#define SH_XNMD_ERRORS_ALIAS                     0x0000000150040408
+
+/* ==================================================================== */
+/*                  Register "SH_XNMD_ERROR_OVERFLOW"                   */
+/* ==================================================================== */
+
+#define SH_XNMD_ERROR_OVERFLOW                   0x0000000150040420
+#define SH_XNMD_ERROR_OVERFLOW_MASK              0x0003ffffffffffff
+#define SH_XNMD_ERROR_OVERFLOW_INIT              0x0003ffffffffffff
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0                           */
+/*   Description:  NI0 VC0 fifo underflow                               */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_SHFT 0
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_MASK 0x0000000000000001
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC0                            */
+/*   Description:  NI0 VC0 fifo overflow                                */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_SHFT 1
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_MASK 0x0000000000000002
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2                           */
+/*   Description:  NI0 VC2 fifo underflow                               */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_SHFT 2
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_MASK 0x0000000000000004
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC2                            */
+/*   Description:  NI0 VC2 fifo overflow                                */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_SHFT 3
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_MASK 0x0000000000000008
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0                           */
+/*   Description:  NI1 VC0 fifo underflow                               */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_SHFT 4
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_MASK 0x0000000000000010
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC0                            */
+/*   Description:  NI1 VC0 fifo overflow                                */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_SHFT 5
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_MASK 0x0000000000000020
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2                           */
+/*   Description:  NI1 VC2 fifo underflow                               */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_SHFT 6
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_MASK 0x0000000000000040
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC2                            */
+/*   Description:  NI1 VC2 fifo overflow                                */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_SHFT 7
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_MASK 0x0000000000000080
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0                          */
+/*   Description:  IILB VC0 fifo underflow                              */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_SHFT 8
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC0                           */
+/*   Description:  IILB VC0 fifo overflow                               */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_SHFT 9
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_MASK 0x0000000000000200
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2                          */
+/*   Description:  IILB VC2 fifo underflow                              */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_SHFT 10
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_MASK 0x0000000000000400
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC2                           */
+/*   Description:  IILB VC2 fifo overflow                               */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_SHFT 11
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_VC0_CREDIT                        */
+/*   Description:  VC0 Credit underflow                                 */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_VC0_CREDIT_SHFT 12
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_VC0_CREDIT                         */
+/*   Description:  VC0 Credit overflow                                  */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_VC0_CREDIT_SHFT 13
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_VC0_CREDIT_MASK 0x0000000000002000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_VC2_CREDIT                        */
+/*   Description:  VC2 Credit underflow                                 */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_VC2_CREDIT_SHFT 14
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_VC2_CREDIT_MASK 0x0000000000004000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_VC2_CREDIT                         */
+/*   Description:  VC2 Credit overflow                                  */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_VC2_CREDIT_SHFT 15
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC0                       */
+/*   Description:  VC0 Data Buffer overflow                             */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC0_SHFT 16
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC0_MASK 0x0000000000010000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC2                       */
+/*   Description:  VC2 Data Buffer overflow                             */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC2_SHFT 17
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_DATABUFF_VC2_MASK 0x0000000000020000
+
+/*   SH_XNMD_ERROR_OVERFLOW_LUT_READ_ERROR                              */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNMD_ERROR_OVERFLOW_LUT_READ_ERROR_SHFT 18
+#define SH_XNMD_ERROR_OVERFLOW_LUT_READ_ERROR_MASK 0x0000000000040000
+
+/*   SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR0                           */
+/*   Description:  Single Bit Error in Bits 63:0                        */
+#define SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR0_SHFT 19
+#define SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR0_MASK 0x0000000000080000
+
+/*   SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR1                           */
+/*   Description:  Single Bit Error in Bits 127:64                      */
+#define SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR1_SHFT 20
+#define SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR1_MASK 0x0000000000100000
+
+/*   SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR2                           */
+/*   Description:  Single Bit Error in Bits 191:128                     */
+#define SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR2_SHFT 21
+#define SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR2_MASK 0x0000000000200000
+
+/*   SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR3                           */
+/*   Description:  Single Bit Error in Bits 255:192                     */
+#define SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR3_SHFT 22
+#define SH_XNMD_ERROR_OVERFLOW_SINGLE_BIT_ERROR3_MASK 0x0000000000400000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR0                                */
+/*   Description:  Uncorrectable Error in Bits 63:0                     */
+#define SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR0_SHFT 23
+#define SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR0_MASK 0x0000000000800000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR1                                */
+/*   Description:  Uncorrectable Error in Bits 127:64                   */
+#define SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR1_SHFT 24
+#define SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR1_MASK 0x0000000001000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR2                                */
+/*   Description:  Uncorrectable Error in Bits 191:128                  */
+#define SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR2_SHFT 25
+#define SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR2_MASK 0x0000000002000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR3                                */
+/*   Description:  Uncorrectable Error in Bits 255:192                  */
+#define SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR3_SHFT 26
+#define SH_XNMD_ERROR_OVERFLOW_UNCOR_ERROR3_MASK 0x0000000004000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR0                         */
+/*   Description:  SIC Counter 0 Underflow                              */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR0_SHFT 27
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR0_MASK 0x0000000008000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR0                          */
+/*   Description:  SIC Counter 0 Overflow                               */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR0_SHFT 28
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR0_MASK 0x0000000010000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR2                         */
+/*   Description:  SIC Counter 2 Underflow                              */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR2_SHFT 29
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_SIC_CNTR2_MASK 0x0000000020000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR2                          */
+/*   Description:  SIC Counter 2 Overflow                               */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR2_SHFT 30
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_SIC_CNTR2_MASK 0x0000000040000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0                         */
+/*   Description:  NI0 Debit 0 Overflow                                 */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0_SHFT 31
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT0_MASK 0x0000000080000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2                         */
+/*   Description:  NI0 Debit 2 Overflow                                 */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2_SHFT 32
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_DEBIT2_MASK 0x0000000100000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0                         */
+/*   Description:  NI1 Debit 0 Overflow                                 */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0_SHFT 33
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT0_MASK 0x0000000200000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2                         */
+/*   Description:  NI1 Debit 2 Overflow                                 */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2_SHFT 34
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_DEBIT2_MASK 0x0000000400000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0                        */
+/*   Description:  IILB Debit 0 Overflow                                */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0_SHFT 35
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT0_MASK 0x0000000800000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2                        */
+/*   Description:  IILB Debit 2 Overflow                                */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2_SHFT 36
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_DEBIT2_MASK 0x0000001000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT                    */
+/*   Description:  NI0 VC0 Credit Underflow                             */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_SHFT 37
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC0_CREDIT_MASK 0x0000002000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT                     */
+/*   Description:  NI0 VC0 Credit Overflow                              */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_SHFT 38
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC0_CREDIT_MASK 0x0000004000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT                    */
+/*   Description:  NI0 VC2 Credit Underflow                             */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_SHFT 39
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI0_VC2_CREDIT_MASK 0x0000008000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT                     */
+/*   Description:  NI0 VC2 Credit Overflow                              */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_SHFT 40
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI0_VC2_CREDIT_MASK 0x0000010000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT                    */
+/*   Description:  NI1 VC0 Credit Underflow                             */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_SHFT 41
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC0_CREDIT_MASK 0x0000020000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT                     */
+/*   Description:  NI1 VC0 Credit Overflow                              */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_SHFT 42
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC0_CREDIT_MASK 0x0000040000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT                    */
+/*   Description:  NI1 VC2 Credit Underflow                             */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_SHFT 43
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_NI1_VC2_CREDIT_MASK 0x0000080000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT                     */
+/*   Description:  NI1 VC2 Credit Overflow                              */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_SHFT 44
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_NI1_VC2_CREDIT_MASK 0x0000100000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT                   */
+/*   Description:  IILB VC0 Credit Underflow                            */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_SHFT 45
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC0_CREDIT_MASK 0x0000200000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT                    */
+/*   Description:  IILB VC0 Credit Overflow                             */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_SHFT 46
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT                   */
+/*   Description:  IILB VC2 Credit Underflow                            */
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_SHFT 47
+#define SH_XNMD_ERROR_OVERFLOW_UNDERFLOW_IILB_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT                    */
+/*   Description:  IILB VC2 Credit Overflow                             */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_SHFT 48
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_IILB_VC2_CREDIT_MASK 0x0001000000000000
+
+/*   SH_XNMD_ERROR_OVERFLOW_OVERFLOW_HEADER_CANCEL_FIFO                 */
+/*   Description:  Header Cancel Fifo Overflow                          */
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_HEADER_CANCEL_FIFO_SHFT 49
+#define SH_XNMD_ERROR_OVERFLOW_OVERFLOW_HEADER_CANCEL_FIFO_MASK 0x0002000000000000
+
+/* ==================================================================== */
+/*               Register "SH_XNMD_ERROR_OVERFLOW_ALIAS"                */
+/* ==================================================================== */
+
+#define SH_XNMD_ERROR_OVERFLOW_ALIAS             0x0000000150040428
+
+/* ==================================================================== */
+/*                    Register "SH_XNMD_ERROR_MASK"                     */
+/* ==================================================================== */
+
+#define SH_XNMD_ERROR_MASK                       0x0000000150040440
+#define SH_XNMD_ERROR_MASK_MASK                  0x0003ffffffffffff
+#define SH_XNMD_ERROR_MASK_INIT                  0x0003ffffffffffff
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC0                               */
+/*   Description:  NI0 VC0 fifo underflow                               */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC0_SHFT 0
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC0_MASK 0x0000000000000001
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC0                                */
+/*   Description:  NI0 VC0 fifo overflow                                */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC0_SHFT 1
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC0_MASK 0x0000000000000002
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC2                               */
+/*   Description:  NI0 VC2 fifo underflow                               */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC2_SHFT 2
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC2_MASK 0x0000000000000004
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC2                                */
+/*   Description:  NI0 VC2 fifo overflow                                */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC2_SHFT 3
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC2_MASK 0x0000000000000008
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC0                               */
+/*   Description:  NI1 VC0 fifo underflow                               */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC0_SHFT 4
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC0_MASK 0x0000000000000010
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC0                                */
+/*   Description:  NI1 VC0 fifo overflow                                */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC0_SHFT 5
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC0_MASK 0x0000000000000020
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC2                               */
+/*   Description:  NI1 VC2 fifo underflow                               */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC2_SHFT 6
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC2_MASK 0x0000000000000040
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC2                                */
+/*   Description:  NI1 VC2 fifo overflow                                */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC2_SHFT 7
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC2_MASK 0x0000000000000080
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC0                              */
+/*   Description:  IILB VC0 fifo underflow                              */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC0_SHFT 8
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC0                               */
+/*   Description:  IILB VC0 fifo overflow                               */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC0_SHFT 9
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC0_MASK 0x0000000000000200
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC2                              */
+/*   Description:  IILB VC2 fifo underflow                              */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC2_SHFT 10
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC2_MASK 0x0000000000000400
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC2                               */
+/*   Description:  IILB VC2 fifo overflow                               */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC2_SHFT 11
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_VC0_CREDIT                            */
+/*   Description:  VC0 Credit underflow                                 */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_VC0_CREDIT_SHFT 12
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_VC0_CREDIT                             */
+/*   Description:  VC0 Credit overflow                                  */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_VC0_CREDIT_SHFT 13
+#define SH_XNMD_ERROR_MASK_OVERFLOW_VC0_CREDIT_MASK 0x0000000000002000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_VC2_CREDIT                            */
+/*   Description:  VC2 Credit underflow                                 */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_VC2_CREDIT_SHFT 14
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_VC2_CREDIT_MASK 0x0000000000004000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_VC2_CREDIT                             */
+/*   Description:  VC2 Credit overflow                                  */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_VC2_CREDIT_SHFT 15
+#define SH_XNMD_ERROR_MASK_OVERFLOW_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_DATABUFF_VC0                           */
+/*   Description:  VC0 Data Buffer overflow                             */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_DATABUFF_VC0_SHFT 16
+#define SH_XNMD_ERROR_MASK_OVERFLOW_DATABUFF_VC0_MASK 0x0000000000010000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_DATABUFF_VC2                           */
+/*   Description:  VC2 Data Buffer overflow                             */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_DATABUFF_VC2_SHFT 17
+#define SH_XNMD_ERROR_MASK_OVERFLOW_DATABUFF_VC2_MASK 0x0000000000020000
+
+/*   SH_XNMD_ERROR_MASK_LUT_READ_ERROR                                  */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNMD_ERROR_MASK_LUT_READ_ERROR_SHFT   18
+#define SH_XNMD_ERROR_MASK_LUT_READ_ERROR_MASK   0x0000000000040000
+
+/*   SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR0                               */
+/*   Description:  Single Bit Error in Bits 63:0                        */
+#define SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR0_SHFT 19
+#define SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR0_MASK 0x0000000000080000
+
+/*   SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR1                               */
+/*   Description:  Single Bit Error in Bits 127:64                      */
+#define SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR1_SHFT 20
+#define SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR1_MASK 0x0000000000100000
+
+/*   SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR2                               */
+/*   Description:  Single Bit Error in Bits 191:128                     */
+#define SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR2_SHFT 21
+#define SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR2_MASK 0x0000000000200000
+
+/*   SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR3                               */
+/*   Description:  Single Bit Error in Bits 255:192                     */
+#define SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR3_SHFT 22
+#define SH_XNMD_ERROR_MASK_SINGLE_BIT_ERROR3_MASK 0x0000000000400000
+
+/*   SH_XNMD_ERROR_MASK_UNCOR_ERROR0                                    */
+/*   Description:  Uncorrectable Error in Bits 63:0                     */
+#define SH_XNMD_ERROR_MASK_UNCOR_ERROR0_SHFT     23
+#define SH_XNMD_ERROR_MASK_UNCOR_ERROR0_MASK     0x0000000000800000
+
+/*   SH_XNMD_ERROR_MASK_UNCOR_ERROR1                                    */
+/*   Description:  Uncorrectable Error in Bits 127:64                   */
+#define SH_XNMD_ERROR_MASK_UNCOR_ERROR1_SHFT     24
+#define SH_XNMD_ERROR_MASK_UNCOR_ERROR1_MASK     0x0000000001000000
+
+/*   SH_XNMD_ERROR_MASK_UNCOR_ERROR2                                    */
+/*   Description:  Uncorrectable Error in Bits 191:128                  */
+#define SH_XNMD_ERROR_MASK_UNCOR_ERROR2_SHFT     25
+#define SH_XNMD_ERROR_MASK_UNCOR_ERROR2_MASK     0x0000000002000000
+
+/*   SH_XNMD_ERROR_MASK_UNCOR_ERROR3                                    */
+/*   Description:  Uncorrectable Error in Bits 255:192                  */
+#define SH_XNMD_ERROR_MASK_UNCOR_ERROR3_SHFT     26
+#define SH_XNMD_ERROR_MASK_UNCOR_ERROR3_MASK     0x0000000004000000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_SIC_CNTR0                             */
+/*   Description:  SIC Counter 0 Underflow                              */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_SIC_CNTR0_SHFT 27
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_SIC_CNTR0_MASK 0x0000000008000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_SIC_CNTR0                              */
+/*   Description:  SIC Counter 0 Overflow                               */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_SIC_CNTR0_SHFT 28
+#define SH_XNMD_ERROR_MASK_OVERFLOW_SIC_CNTR0_MASK 0x0000000010000000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_SIC_CNTR2                             */
+/*   Description:  SIC Counter 2 Underflow                              */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_SIC_CNTR2_SHFT 29
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_SIC_CNTR2_MASK 0x0000000020000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_SIC_CNTR2                              */
+/*   Description:  SIC Counter 2 Overflow                               */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_SIC_CNTR2_SHFT 30
+#define SH_XNMD_ERROR_MASK_OVERFLOW_SIC_CNTR2_MASK 0x0000000040000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI0_DEBIT0                             */
+/*   Description:  NI0 Debit 0 Overflow                                 */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_DEBIT0_SHFT 31
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_DEBIT0_MASK 0x0000000080000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI0_DEBIT2                             */
+/*   Description:  NI0 Debit 2 Overflow                                 */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_DEBIT2_SHFT 32
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_DEBIT2_MASK 0x0000000100000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI1_DEBIT0                             */
+/*   Description:  NI1 Debit 0 Overflow                                 */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_DEBIT0_SHFT 33
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_DEBIT0_MASK 0x0000000200000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI1_DEBIT2                             */
+/*   Description:  NI1 Debit 2 Overflow                                 */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_DEBIT2_SHFT 34
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_DEBIT2_MASK 0x0000000400000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_IILB_DEBIT0                            */
+/*   Description:  IILB Debit 0 Overflow                                */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_DEBIT0_SHFT 35
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_DEBIT0_MASK 0x0000000800000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_IILB_DEBIT2                            */
+/*   Description:  IILB Debit 2 Overflow                                */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_DEBIT2_SHFT 36
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_DEBIT2_MASK 0x0000001000000000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT                        */
+/*   Description:  NI0 VC0 Credit Underflow                             */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_SHFT 37
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC0_CREDIT_MASK 0x0000002000000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT                         */
+/*   Description:  NI0 VC0 Credit Overflow                              */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_SHFT 38
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC0_CREDIT_MASK 0x0000004000000000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT                        */
+/*   Description:  NI0 VC2 Credit Underflow                             */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_SHFT 39
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI0_VC2_CREDIT_MASK 0x0000008000000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT                         */
+/*   Description:  NI0 VC2 Credit Overflow                              */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_SHFT 40
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI0_VC2_CREDIT_MASK 0x0000010000000000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT                        */
+/*   Description:  NI1 VC0 Credit Underflow                             */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_SHFT 41
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC0_CREDIT_MASK 0x0000020000000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT                         */
+/*   Description:  NI1 VC0 Credit Overflow                              */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_SHFT 42
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC0_CREDIT_MASK 0x0000040000000000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT                        */
+/*   Description:  NI1 VC2 Credit Underflow                             */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_SHFT 43
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_NI1_VC2_CREDIT_MASK 0x0000080000000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT                         */
+/*   Description:  NI1 VC2 Credit Overflow                              */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_SHFT 44
+#define SH_XNMD_ERROR_MASK_OVERFLOW_NI1_VC2_CREDIT_MASK 0x0000100000000000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT                       */
+/*   Description:  IILB VC0 Credit Underflow                            */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_SHFT 45
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC0_CREDIT_MASK 0x0000200000000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT                        */
+/*   Description:  IILB VC0 Credit Overflow                             */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_SHFT 46
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT                       */
+/*   Description:  IILB VC2 Credit Underflow                            */
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_SHFT 47
+#define SH_XNMD_ERROR_MASK_UNDERFLOW_IILB_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT                        */
+/*   Description:  IILB VC2 Credit Overflow                             */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_SHFT 48
+#define SH_XNMD_ERROR_MASK_OVERFLOW_IILB_VC2_CREDIT_MASK 0x0001000000000000
+
+/*   SH_XNMD_ERROR_MASK_OVERFLOW_HEADER_CANCEL_FIFO                     */
+/*   Description:  Header Cancel Fifo Overflow                          */
+#define SH_XNMD_ERROR_MASK_OVERFLOW_HEADER_CANCEL_FIFO_SHFT 49
+#define SH_XNMD_ERROR_MASK_OVERFLOW_HEADER_CANCEL_FIFO_MASK 0x0002000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XNMD_FIRST_ERROR"                    */
+/* ==================================================================== */
+
+#define SH_XNMD_FIRST_ERROR                      0x0000000150040460
+#define SH_XNMD_FIRST_ERROR_MASK                 0x0003ffffffffffff
+#define SH_XNMD_FIRST_ERROR_INIT                 0x0003ffffffffffff
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC0                              */
+/*   Description:  NI0 VC0 fifo underflow                               */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC0_SHFT 0
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC0_MASK 0x0000000000000001
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC0                               */
+/*   Description:  NI0 VC0 fifo overflow                                */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC0_SHFT 1
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC0_MASK 0x0000000000000002
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC2                              */
+/*   Description:  NI0 VC2 fifo underflow                               */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC2_SHFT 2
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC2_MASK 0x0000000000000004
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC2                               */
+/*   Description:  NI0 VC2 fifo overflow                                */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC2_SHFT 3
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC2_MASK 0x0000000000000008
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC0                              */
+/*   Description:  NI1 VC0 fifo underflow                               */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC0_SHFT 4
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC0_MASK 0x0000000000000010
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC0                               */
+/*   Description:  NI1 VC0 fifo overflow                                */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC0_SHFT 5
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC0_MASK 0x0000000000000020
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC2                              */
+/*   Description:  NI1 VC2 fifo underflow                               */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC2_SHFT 6
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC2_MASK 0x0000000000000040
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC2                               */
+/*   Description:  NI1 VC2 fifo overflow                                */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC2_SHFT 7
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC2_MASK 0x0000000000000080
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC0                             */
+/*   Description:  IILB VC0 fifo underflow                              */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC0_SHFT 8
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC0_MASK 0x0000000000000100
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC0                              */
+/*   Description:  IILB VC0 fifo overflow                               */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC0_SHFT 9
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC0_MASK 0x0000000000000200
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC2                             */
+/*   Description:  IILB VC2 fifo underflow                              */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC2_SHFT 10
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC2_MASK 0x0000000000000400
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC2                              */
+/*   Description:  IILB VC2 fifo overflow                               */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC2_SHFT 11
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC2_MASK 0x0000000000000800
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_VC0_CREDIT                           */
+/*   Description:  VC0 Credit underflow                                 */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_VC0_CREDIT_SHFT 12
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_VC0_CREDIT_MASK 0x0000000000001000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_VC0_CREDIT                            */
+/*   Description:  VC0 Credit overflow                                  */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_VC0_CREDIT_SHFT 13
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_VC0_CREDIT_MASK 0x0000000000002000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_VC2_CREDIT                           */
+/*   Description:  VC2 Credit underflow                                 */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_VC2_CREDIT_SHFT 14
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_VC2_CREDIT_MASK 0x0000000000004000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_VC2_CREDIT                            */
+/*   Description:  VC2 Credit overflow                                  */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_VC2_CREDIT_SHFT 15
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_VC2_CREDIT_MASK 0x0000000000008000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_DATABUFF_VC0                          */
+/*   Description:  VC0 Data Buffer overflow                             */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_DATABUFF_VC0_SHFT 16
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_DATABUFF_VC0_MASK 0x0000000000010000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_DATABUFF_VC2                          */
+/*   Description:  VC2 Data Buffer overflow                             */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_DATABUFF_VC2_SHFT 17
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_DATABUFF_VC2_MASK 0x0000000000020000
+
+/*   SH_XNMD_FIRST_ERROR_LUT_READ_ERROR                                 */
+/*   Description:  LUT Read Error                                       */
+#define SH_XNMD_FIRST_ERROR_LUT_READ_ERROR_SHFT  18
+#define SH_XNMD_FIRST_ERROR_LUT_READ_ERROR_MASK  0x0000000000040000
+
+/*   SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR0                              */
+/*   Description:  Single Bit Error in Bits 63:0                        */
+#define SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR0_SHFT 19
+#define SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR0_MASK 0x0000000000080000
+
+/*   SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR1                              */
+/*   Description:  Single Bit Error in Bits 127:64                      */
+#define SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR1_SHFT 20
+#define SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR1_MASK 0x0000000000100000
+
+/*   SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR2                              */
+/*   Description:  Single Bit Error in Bits 191:128                     */
+#define SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR2_SHFT 21
+#define SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR2_MASK 0x0000000000200000
+
+/*   SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR3                              */
+/*   Description:  Single Bit Error in Bits 255:192                     */
+#define SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR3_SHFT 22
+#define SH_XNMD_FIRST_ERROR_SINGLE_BIT_ERROR3_MASK 0x0000000000400000
+
+/*   SH_XNMD_FIRST_ERROR_UNCOR_ERROR0                                   */
+/*   Description:  Uncorrectable Error in Bits 63:0                     */
+#define SH_XNMD_FIRST_ERROR_UNCOR_ERROR0_SHFT    23
+#define SH_XNMD_FIRST_ERROR_UNCOR_ERROR0_MASK    0x0000000000800000
+
+/*   SH_XNMD_FIRST_ERROR_UNCOR_ERROR1                                   */
+/*   Description:  Uncorrectable Error in Bits 127:64                   */
+#define SH_XNMD_FIRST_ERROR_UNCOR_ERROR1_SHFT    24
+#define SH_XNMD_FIRST_ERROR_UNCOR_ERROR1_MASK    0x0000000001000000
+
+/*   SH_XNMD_FIRST_ERROR_UNCOR_ERROR2                                   */
+/*   Description:  Uncorrectable Error in Bits 191:128                  */
+#define SH_XNMD_FIRST_ERROR_UNCOR_ERROR2_SHFT    25
+#define SH_XNMD_FIRST_ERROR_UNCOR_ERROR2_MASK    0x0000000002000000
+
+/*   SH_XNMD_FIRST_ERROR_UNCOR_ERROR3                                   */
+/*   Description:  Uncorrectable Error in Bits 255:192                  */
+#define SH_XNMD_FIRST_ERROR_UNCOR_ERROR3_SHFT    26
+#define SH_XNMD_FIRST_ERROR_UNCOR_ERROR3_MASK    0x0000000004000000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_SIC_CNTR0                            */
+/*   Description:  SIC Counter 0 Underflow                              */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_SIC_CNTR0_SHFT 27
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_SIC_CNTR0_MASK 0x0000000008000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_SIC_CNTR0                             */
+/*   Description:  SIC Counter 0 Overflow                               */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_SIC_CNTR0_SHFT 28
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_SIC_CNTR0_MASK 0x0000000010000000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_SIC_CNTR2                            */
+/*   Description:  SIC Counter 2 Underflow                              */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_SIC_CNTR2_SHFT 29
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_SIC_CNTR2_MASK 0x0000000020000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_SIC_CNTR2                             */
+/*   Description:  SIC Counter 2 Overflow                               */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_SIC_CNTR2_SHFT 30
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_SIC_CNTR2_MASK 0x0000000040000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_DEBIT0                            */
+/*   Description:  NI0 Debit 0 Overflow                                 */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_DEBIT0_SHFT 31
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_DEBIT0_MASK 0x0000000080000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_DEBIT2                            */
+/*   Description:  NI0 Debit 2 Overflow                                 */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_DEBIT2_SHFT 32
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_DEBIT2_MASK 0x0000000100000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_DEBIT0                            */
+/*   Description:  NI1 Debit 0 Overflow                                 */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_DEBIT0_SHFT 33
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_DEBIT0_MASK 0x0000000200000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_DEBIT2                            */
+/*   Description:  NI1 Debit 2 Overflow                                 */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_DEBIT2_SHFT 34
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_DEBIT2_MASK 0x0000000400000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_DEBIT0                           */
+/*   Description:  IILB Debit 0 Overflow                                */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_DEBIT0_SHFT 35
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_DEBIT0_MASK 0x0000000800000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_DEBIT2                           */
+/*   Description:  IILB Debit 2 Overflow                                */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_DEBIT2_SHFT 36
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_DEBIT2_MASK 0x0000001000000000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT                       */
+/*   Description:  NI0 VC0 Credit Underflow                             */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_SHFT 37
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC0_CREDIT_MASK 0x0000002000000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT                        */
+/*   Description:  NI0 VC0 Credit Overflow                              */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_SHFT 38
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC0_CREDIT_MASK 0x0000004000000000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT                       */
+/*   Description:  NI0 VC2 Credit Underflow                             */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_SHFT 39
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI0_VC2_CREDIT_MASK 0x0000008000000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT                        */
+/*   Description:  NI0 VC2 Credit Overflow                              */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_SHFT 40
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI0_VC2_CREDIT_MASK 0x0000010000000000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT                       */
+/*   Description:  NI1 VC0 Credit Underflow                             */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_SHFT 41
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC0_CREDIT_MASK 0x0000020000000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT                        */
+/*   Description:  NI1 VC0 Credit Overflow                              */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_SHFT 42
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC0_CREDIT_MASK 0x0000040000000000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT                       */
+/*   Description:  NI1 VC2 Credit Underflow                             */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_SHFT 43
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_NI1_VC2_CREDIT_MASK 0x0000080000000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT                        */
+/*   Description:  NI1 VC2 Credit Overflow                              */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_SHFT 44
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_NI1_VC2_CREDIT_MASK 0x0000100000000000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT                      */
+/*   Description:  IILB VC0 Credit Underflow                            */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_SHFT 45
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC0_CREDIT_MASK 0x0000200000000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT                       */
+/*   Description:  IILB VC0 Credit Overflow                             */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_SHFT 46
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC0_CREDIT_MASK 0x0000400000000000
+
+/*   SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT                      */
+/*   Description:  IILB VC2 Credit Underflow                            */
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_SHFT 47
+#define SH_XNMD_FIRST_ERROR_UNDERFLOW_IILB_VC2_CREDIT_MASK 0x0000800000000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT                       */
+/*   Description:  IILB VC2 Credit Overflow                             */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_SHFT 48
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_IILB_VC2_CREDIT_MASK 0x0001000000000000
+
+/*   SH_XNMD_FIRST_ERROR_OVERFLOW_HEADER_CANCEL_FIFO                    */
+/*   Description:  Header Cancel Fifo Overflow                          */
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_HEADER_CANCEL_FIFO_SHFT 49
+#define SH_XNMD_FIRST_ERROR_OVERFLOW_HEADER_CANCEL_FIFO_MASK 0x0002000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_AUTO_REPLY_ENABLE0"                   */
+/*                 Automatic Maintenance Reply Enable 0                 */
+/* ==================================================================== */
+
+#define SH_AUTO_REPLY_ENABLE0                    0x0000000110061000
+#define SH_AUTO_REPLY_ENABLE0_MASK               0xffffffffffffffff
+#define SH_AUTO_REPLY_ENABLE0_INIT               0x0000000000000000
+
+/*   SH_AUTO_REPLY_ENABLE0_ENABLE0                                      */
+/*   Description:  Enable 0                                             */
+#define SH_AUTO_REPLY_ENABLE0_ENABLE0_SHFT       0
+#define SH_AUTO_REPLY_ENABLE0_ENABLE0_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_AUTO_REPLY_ENABLE1"                   */
+/*                 Automatic Maintenance Reply Enable 1                 */
+/* ==================================================================== */
+
+#define SH_AUTO_REPLY_ENABLE1                    0x0000000110061080
+#define SH_AUTO_REPLY_ENABLE1_MASK               0xffffffffffffffff
+#define SH_AUTO_REPLY_ENABLE1_INIT               0x0000000000000000
+
+/*   SH_AUTO_REPLY_ENABLE1_ENABLE1                                      */
+/*   Description:  Enable 1                                             */
+#define SH_AUTO_REPLY_ENABLE1_ENABLE1_SHFT       0
+#define SH_AUTO_REPLY_ENABLE1_ENABLE1_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_AUTO_REPLY_HEADER0"                   */
+/*                 Automatic Maintenance Reply Header 0                 */
+/* ==================================================================== */
+
+#define SH_AUTO_REPLY_HEADER0                    0x0000000110061100
+#define SH_AUTO_REPLY_HEADER0_MASK               0xffffffffffffffff
+#define SH_AUTO_REPLY_HEADER0_INIT               0x0000000000000000
+
+/*   SH_AUTO_REPLY_HEADER0_HEADER0                                      */
+/*   Description:  Header 0                                             */
+#define SH_AUTO_REPLY_HEADER0_HEADER0_SHFT       0
+#define SH_AUTO_REPLY_HEADER0_HEADER0_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_AUTO_REPLY_HEADER1"                   */
+/*                 Automatic Maintenance Reply Header 1                 */
+/* ==================================================================== */
+
+#define SH_AUTO_REPLY_HEADER1                    0x0000000110061180
+#define SH_AUTO_REPLY_HEADER1_MASK               0xffffffffffffffff
+#define SH_AUTO_REPLY_HEADER1_INIT               0x0000000000000000
+
+/*   SH_AUTO_REPLY_HEADER1_HEADER1                                      */
+/*   Description:  Header 1                                             */
+#define SH_AUTO_REPLY_HEADER1_HEADER1_SHFT       0
+#define SH_AUTO_REPLY_HEADER1_HEADER1_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_ENABLE_RP_AUTO_REPLY"                  */
+/*         Enable Automatic Maintenance Reply From Reply Queue          */
+/* ==================================================================== */
+
+#define SH_ENABLE_RP_AUTO_REPLY                  0x0000000110061200
+#define SH_ENABLE_RP_AUTO_REPLY_MASK             0x0000000000000001
+#define SH_ENABLE_RP_AUTO_REPLY_INIT             0x0000000000000000
+
+/*   SH_ENABLE_RP_AUTO_REPLY_ENABLE                                     */
+/*   Description:  Enable Reply Auto Reply                              */
+#define SH_ENABLE_RP_AUTO_REPLY_ENABLE_SHFT      0
+#define SH_ENABLE_RP_AUTO_REPLY_ENABLE_MASK      0x0000000000000001
+
+/* ==================================================================== */
+/*                  Register "SH_ENABLE_RQ_AUTO_REPLY"                  */
+/*        Enable Automatic Maintenance Reply From Request Queue         */
+/* ==================================================================== */
+
+#define SH_ENABLE_RQ_AUTO_REPLY                  0x0000000110061280
+#define SH_ENABLE_RQ_AUTO_REPLY_MASK             0x0000000000000001
+#define SH_ENABLE_RQ_AUTO_REPLY_INIT             0x0000000000000000
+
+/*   SH_ENABLE_RQ_AUTO_REPLY_ENABLE                                     */
+/*   Description:  Enable Request Auto Reply                            */
+#define SH_ENABLE_RQ_AUTO_REPLY_ENABLE_SHFT      0
+#define SH_ENABLE_RQ_AUTO_REPLY_ENABLE_MASK      0x0000000000000001
+
+/* ==================================================================== */
+/*                     Register "SH_REDIRECT_INVAL"                     */
+/*               Redirect invalidate to LB instead of PI                */
+/* ==================================================================== */
+
+#define SH_REDIRECT_INVAL                        0x0000000110061300
+#define SH_REDIRECT_INVAL_MASK                   0x0000000000000001
+#define SH_REDIRECT_INVAL_INIT                   0x0000000000000000
+
+/*   SH_REDIRECT_INVAL_REDIRECT                                         */
+/*   Description:  Redirect invalidates to LB instead of PI             */
+#define SH_REDIRECT_INVAL_REDIRECT_SHFT          0
+#define SH_REDIRECT_INVAL_REDIRECT_MASK          0x0000000000000001
+
+/* ==================================================================== */
+/*                     Register "SH_DIAG_MSG_CNTRL"                     */
+/*                 Diagnostic Message Control Register                  */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_CNTRL                        0x0000000110062000
+#define SH_DIAG_MSG_CNTRL_MASK                   0xc000000000003fff
+#define SH_DIAG_MSG_CNTRL_INIT                   0x0000000000000000
+
+/*   SH_DIAG_MSG_CNTRL_MSG_LENGTH                                       */
+/*   Description:  Message data payload length, 0 - 63                  */
+#define SH_DIAG_MSG_CNTRL_MSG_LENGTH_SHFT        0
+#define SH_DIAG_MSG_CNTRL_MSG_LENGTH_MASK        0x000000000000003f
+
+/*   SH_DIAG_MSG_CNTRL_ERROR_INJECT_POINT                               */
+/*   Description:  Point message that the error bit would be activated  */
+#define SH_DIAG_MSG_CNTRL_ERROR_INJECT_POINT_SHFT 6
+#define SH_DIAG_MSG_CNTRL_ERROR_INJECT_POINT_MASK 0x0000000000000fc0
+
+/*   SH_DIAG_MSG_CNTRL_ERROR_INJECT_ENABLE                              */
+/*   Description:  Enable ERROR_INJECT_POINT field                      */
+#define SH_DIAG_MSG_CNTRL_ERROR_INJECT_ENABLE_SHFT 12
+#define SH_DIAG_MSG_CNTRL_ERROR_INJECT_ENABLE_MASK 0x0000000000001000
+
+/*   SH_DIAG_MSG_CNTRL_PORT                                             */
+/*   Description:  0 = request port, 1 = reply port                     */
+#define SH_DIAG_MSG_CNTRL_PORT_SHFT              13
+#define SH_DIAG_MSG_CNTRL_PORT_MASK              0x0000000000002000
+
+/*   SH_DIAG_MSG_CNTRL_START                                            */
+/*   Description:  Start                                                */
+#define SH_DIAG_MSG_CNTRL_START_SHFT             62
+#define SH_DIAG_MSG_CNTRL_START_MASK             0x4000000000000000
+
+/*   SH_DIAG_MSG_CNTRL_BUSY                                             */
+/*   Description:  Busy                                                 */
+#define SH_DIAG_MSG_CNTRL_BUSY_SHFT              63
+#define SH_DIAG_MSG_CNTRL_BUSY_MASK              0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA0L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA0L                       0x0000000110062080
+#define SH_DIAG_MSG_DATA0L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA0L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA0L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA0L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA0L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA0U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA0U                       0x0000000110062100
+#define SH_DIAG_MSG_DATA0U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA0U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA0U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA0U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA0U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA1L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA1L                       0x0000000110062180
+#define SH_DIAG_MSG_DATA1L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA1L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA1L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA1L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA1L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA1U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA1U                       0x0000000110062200
+#define SH_DIAG_MSG_DATA1U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA1U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA1U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA1U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA1U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA2L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA2L                       0x0000000110062280
+#define SH_DIAG_MSG_DATA2L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA2L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA2L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA2L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA2L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA2U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA2U                       0x0000000110062300
+#define SH_DIAG_MSG_DATA2U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA2U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA2U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA2U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA2U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA3L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA3L                       0x0000000110062380
+#define SH_DIAG_MSG_DATA3L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA3L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA3L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA3L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA3L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA3U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA3U                       0x0000000110062400
+#define SH_DIAG_MSG_DATA3U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA3U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA3U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA3U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA3U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA4L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA4L                       0x0000000110062480
+#define SH_DIAG_MSG_DATA4L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA4L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA4L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA4L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA4L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA4U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA4U                       0x0000000110062500
+#define SH_DIAG_MSG_DATA4U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA4U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA4U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA4U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA4U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA5L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA5L                       0x0000000110062580
+#define SH_DIAG_MSG_DATA5L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA5L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA5L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA5L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA5L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA5U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA5U                       0x0000000110062600
+#define SH_DIAG_MSG_DATA5U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA5U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA5U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA5U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA5U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA6L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA6L                       0x0000000110062680
+#define SH_DIAG_MSG_DATA6L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA6L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA6L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA6L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA6L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA6U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA6U                       0x0000000110062700
+#define SH_DIAG_MSG_DATA6U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA6U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA6U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA6U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA6U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA7L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA7L                       0x0000000110062780
+#define SH_DIAG_MSG_DATA7L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA7L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA7L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA7L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA7L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA7U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA7U                       0x0000000110062800
+#define SH_DIAG_MSG_DATA7U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA7U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA7U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA7U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA7U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA8L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA8L                       0x0000000110062880
+#define SH_DIAG_MSG_DATA8L_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA8L_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA8L_DATA_LOWER                                      */
+/*   Description:  Lower 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA8L_DATA_LOWER_SHFT       0
+#define SH_DIAG_MSG_DATA8L_DATA_LOWER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA8U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_DATA8U                       0x0000000110062900
+#define SH_DIAG_MSG_DATA8U_MASK                  0xffffffffffffffff
+#define SH_DIAG_MSG_DATA8U_INIT                  0x0000000000000000
+
+/*   SH_DIAG_MSG_DATA8U_DATA_UPPER                                      */
+/*   Description:  Upper 64 bits of Diagnositic Message Data            */
+#define SH_DIAG_MSG_DATA8U_DATA_UPPER_SHFT       0
+#define SH_DIAG_MSG_DATA8U_DATA_UPPER_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_DIAG_MSG_HDR0"                      */
+/*              Diagnostice Data, lower 64 bits of header               */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_HDR0                         0x0000000110062980
+#define SH_DIAG_MSG_HDR0_MASK                    0xffffffffffffffff
+#define SH_DIAG_MSG_HDR0_INIT                    0x0000000000000000
+
+/*   SH_DIAG_MSG_HDR0_HEADER0                                           */
+/*   Description:  Lower 64 bits of Diagnositic Message Header          */
+#define SH_DIAG_MSG_HDR0_HEADER0_SHFT            0
+#define SH_DIAG_MSG_HDR0_HEADER0_MASK            0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_DIAG_MSG_HDR1"                      */
+/*              Diagnostice Data, upper 64 bits of header               */
+/* ==================================================================== */
+
+#define SH_DIAG_MSG_HDR1                         0x0000000110062a00
+#define SH_DIAG_MSG_HDR1_MASK                    0xffffffffffffffff
+#define SH_DIAG_MSG_HDR1_INIT                    0x0000000000000000
+
+/*   SH_DIAG_MSG_HDR1_HEADER1                                           */
+/*   Description:  Upper 64 bits of Diagnositic Message Header          */
+#define SH_DIAG_MSG_HDR1_HEADER1_SHFT            0
+#define SH_DIAG_MSG_HDR1_HEADER1_MASK            0xffffffffffffffff
+
+/* ==================================================================== */
+/*                      Register "SH_DEBUG_SELECT"                      */
+/*                        SHub Debug Port Select                        */
+/* ==================================================================== */
+
+#define SH_DEBUG_SELECT                          0x0000000110063000
+#define SH_DEBUG_SELECT_MASK                     0x8fffffffffffffff
+#define SH_DEBUG_SELECT_INIT                     0x0000e38e38e38e38
+
+/*   SH_DEBUG_SELECT_NIBBLE0_NIBBLE_SEL                                 */
+/*   Description:  Nibble0_nibble_select                                */
+#define SH_DEBUG_SELECT_NIBBLE0_NIBBLE_SEL_SHFT  0
+#define SH_DEBUG_SELECT_NIBBLE0_NIBBLE_SEL_MASK  0x0000000000000007
+
+/*   SH_DEBUG_SELECT_NIBBLE0_CHIPLET_SEL                                */
+/*   Description:  Nibble0_chiplet_select                               */
+#define SH_DEBUG_SELECT_NIBBLE0_CHIPLET_SEL_SHFT 3
+#define SH_DEBUG_SELECT_NIBBLE0_CHIPLET_SEL_MASK 0x0000000000000038
+
+/*   SH_DEBUG_SELECT_NIBBLE1_NIBBLE_SEL                                 */
+/*   Description:  Nibble1_nibble_select                                */
+#define SH_DEBUG_SELECT_NIBBLE1_NIBBLE_SEL_SHFT  6
+#define SH_DEBUG_SELECT_NIBBLE1_NIBBLE_SEL_MASK  0x00000000000001c0
+
+/*   SH_DEBUG_SELECT_NIBBLE1_CHIPLET_SEL                                */
+/*   Description:  Nibble1_chiplet_select                               */
+#define SH_DEBUG_SELECT_NIBBLE1_CHIPLET_SEL_SHFT 9
+#define SH_DEBUG_SELECT_NIBBLE1_CHIPLET_SEL_MASK 0x0000000000000e00
+
+/*   SH_DEBUG_SELECT_NIBBLE2_NIBBLE_SEL                                 */
+/*   Description:  Nibble2_nibble_select                                */
+#define SH_DEBUG_SELECT_NIBBLE2_NIBBLE_SEL_SHFT  12
+#define SH_DEBUG_SELECT_NIBBLE2_NIBBLE_SEL_MASK  0x0000000000007000
+
+/*   SH_DEBUG_SELECT_NIBBLE2_CHIPLET_SEL                                */
+/*   Description:  Nibble2_chiplet_select                               */
+#define SH_DEBUG_SELECT_NIBBLE2_CHIPLET_SEL_SHFT 15
+#define SH_DEBUG_SELECT_NIBBLE2_CHIPLET_SEL_MASK 0x0000000000038000
+
+/*   SH_DEBUG_SELECT_NIBBLE3_NIBBLE_SEL                                 */
+/*   Description:  Nibble3_nibble_select                                */
+#define SH_DEBUG_SELECT_NIBBLE3_NIBBLE_SEL_SHFT  18
+#define SH_DEBUG_SELECT_NIBBLE3_NIBBLE_SEL_MASK  0x00000000001c0000
+
+/*   SH_DEBUG_SELECT_NIBBLE3_CHIPLET_SEL                                */
+/*   Description:  Nibble3_chiplet_select                               */
+#define SH_DEBUG_SELECT_NIBBLE3_CHIPLET_SEL_SHFT 21
+#define SH_DEBUG_SELECT_NIBBLE3_CHIPLET_SEL_MASK 0x0000000000e00000
+
+/*   SH_DEBUG_SELECT_NIBBLE4_NIBBLE_SEL                                 */
+/*   Description:  Nibble4_nibble_select                                */
+#define SH_DEBUG_SELECT_NIBBLE4_NIBBLE_SEL_SHFT  24
+#define SH_DEBUG_SELECT_NIBBLE4_NIBBLE_SEL_MASK  0x0000000007000000
+
+/*   SH_DEBUG_SELECT_NIBBLE4_CHIPLET_SEL                                */
+/*   Description:  Nibble4_chiplet_select                               */
+#define SH_DEBUG_SELECT_NIBBLE4_CHIPLET_SEL_SHFT 27
+#define SH_DEBUG_SELECT_NIBBLE4_CHIPLET_SEL_MASK 0x0000000038000000
+
+/*   SH_DEBUG_SELECT_NIBBLE5_NIBBLE_SEL                                 */
+/*   Description:  Nibble5_nibble_select                                */
+#define SH_DEBUG_SELECT_NIBBLE5_NIBBLE_SEL_SHFT  30
+#define SH_DEBUG_SELECT_NIBBLE5_NIBBLE_SEL_MASK  0x00000001c0000000
+
+/*   SH_DEBUG_SELECT_NIBBLE5_CHIPLET_SEL                                */
+/*   Description:  Nibble5_chiplet_select                               */
+#define SH_DEBUG_SELECT_NIBBLE5_CHIPLET_SEL_SHFT 33
+#define SH_DEBUG_SELECT_NIBBLE5_CHIPLET_SEL_MASK 0x0000000e00000000
+
+/*   SH_DEBUG_SELECT_NIBBLE6_NIBBLE_SEL                                 */
+/*   Description:  Nibble6_nibble_select                                */
+#define SH_DEBUG_SELECT_NIBBLE6_NIBBLE_SEL_SHFT  36
+#define SH_DEBUG_SELECT_NIBBLE6_NIBBLE_SEL_MASK  0x0000007000000000
+
+/*   SH_DEBUG_SELECT_NIBBLE6_CHIPLET_SEL                                */
+/*   Description:  Nibble6_chiplet_select                               */
+#define SH_DEBUG_SELECT_NIBBLE6_CHIPLET_SEL_SHFT 39
+#define SH_DEBUG_SELECT_NIBBLE6_CHIPLET_SEL_MASK 0x0000038000000000
+
+/*   SH_DEBUG_SELECT_NIBBLE7_NIBBLE_SEL                                 */
+/*   Description:  Nibble7_nibble_select                                */
+#define SH_DEBUG_SELECT_NIBBLE7_NIBBLE_SEL_SHFT  42
+#define SH_DEBUG_SELECT_NIBBLE7_NIBBLE_SEL_MASK  0x00001c0000000000
+
+/*   SH_DEBUG_SELECT_NIBBLE7_CHIPLET_SEL                                */
+/*   Description:  Nibble7_chiplet_select                               */
+#define SH_DEBUG_SELECT_NIBBLE7_CHIPLET_SEL_SHFT 45
+#define SH_DEBUG_SELECT_NIBBLE7_CHIPLET_SEL_MASK 0x0000e00000000000
+
+/*   SH_DEBUG_SELECT_DEBUG_II_SEL                                       */
+/*   Description:  Select bits to II port                               */
+#define SH_DEBUG_SELECT_DEBUG_II_SEL_SHFT        48
+#define SH_DEBUG_SELECT_DEBUG_II_SEL_MASK        0x0007000000000000
+
+/*   SH_DEBUG_SELECT_SEL_II                                             */
+/*   Description:  Select II to debug port                              */
+#define SH_DEBUG_SELECT_SEL_II_SHFT              51
+#define SH_DEBUG_SELECT_SEL_II_MASK              0x0ff8000000000000
+
+/*   SH_DEBUG_SELECT_TRIGGER_ENABLE                                     */
+/*   Description:  Enable trigger on bit 32 of Analyzer data            */
+#define SH_DEBUG_SELECT_TRIGGER_ENABLE_SHFT      63
+#define SH_DEBUG_SELECT_TRIGGER_ENABLE_MASK      0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_TRIGGER_COMPARE_MASK"                  */
+/*                      SHub Trigger Compare Mask                       */
+/* ==================================================================== */
+
+#define SH_TRIGGER_COMPARE_MASK                  0x0000000110063080
+#define SH_TRIGGER_COMPARE_MASK_MASK             0x00000000ffffffff
+#define SH_TRIGGER_COMPARE_MASK_INIT             0x0000000000000000
+
+/*   SH_TRIGGER_COMPARE_MASK_MASK                                       */
+/*   Description:  SHub Trigger Compare Mask                            */
+#define SH_TRIGGER_COMPARE_MASK_MASK_SHFT        0
+#define SH_TRIGGER_COMPARE_MASK_MASK_MASK        0x00000000ffffffff
+
+/* ==================================================================== */
+/*                Register "SH_TRIGGER_COMPARE_PATTERN"                 */
+/*                     SHub Trigger Compare Pattern                     */
+/* ==================================================================== */
+
+#define SH_TRIGGER_COMPARE_PATTERN               0x0000000110063100
+#define SH_TRIGGER_COMPARE_PATTERN_MASK          0x00000000ffffffff
+#define SH_TRIGGER_COMPARE_PATTERN_INIT          0x0000000000000000
+
+/*   SH_TRIGGER_COMPARE_PATTERN_DATA                                    */
+/*   Description:  SHub Trigger Compare Pattern                         */
+#define SH_TRIGGER_COMPARE_PATTERN_DATA_SHFT     0
+#define SH_TRIGGER_COMPARE_PATTERN_DATA_MASK     0x00000000ffffffff
+
+/* ==================================================================== */
+/*                      Register "SH_TRIGGER_SEL"                       */
+/*                  Trigger select for SHUB debug port                  */
+/* ==================================================================== */
+
+#define SH_TRIGGER_SEL                           0x0000000110063180
+#define SH_TRIGGER_SEL_MASK                      0x7777777777777777
+#define SH_TRIGGER_SEL_INIT                      0x0000000000000000
+
+/*   SH_TRIGGER_SEL_NIBBLE0_INPUT_SEL                                   */
+/*   Description:  Nibble 0 input select                                */
+#define SH_TRIGGER_SEL_NIBBLE0_INPUT_SEL_SHFT    0
+#define SH_TRIGGER_SEL_NIBBLE0_INPUT_SEL_MASK    0x0000000000000007
+
+/*   SH_TRIGGER_SEL_NIBBLE0_NIBBLE_SEL                                  */
+/*   Description:  Nibble 0 Nibble select                               */
+#define SH_TRIGGER_SEL_NIBBLE0_NIBBLE_SEL_SHFT   4
+#define SH_TRIGGER_SEL_NIBBLE0_NIBBLE_SEL_MASK   0x0000000000000070
+
+/*   SH_TRIGGER_SEL_NIBBLE1_INPUT_SEL                                   */
+/*   Description:  Nibble 1 input select                                */
+#define SH_TRIGGER_SEL_NIBBLE1_INPUT_SEL_SHFT    8
+#define SH_TRIGGER_SEL_NIBBLE1_INPUT_SEL_MASK    0x0000000000000700
+
+/*   SH_TRIGGER_SEL_NIBBLE1_NIBBLE_SEL                                  */
+/*   Description:  Nibble 1 Nibble select                               */
+#define SH_TRIGGER_SEL_NIBBLE1_NIBBLE_SEL_SHFT   12
+#define SH_TRIGGER_SEL_NIBBLE1_NIBBLE_SEL_MASK   0x0000000000007000
+
+/*   SH_TRIGGER_SEL_NIBBLE2_INPUT_SEL                                   */
+/*   Description:  Nibble 2 input select                                */
+#define SH_TRIGGER_SEL_NIBBLE2_INPUT_SEL_SHFT    16
+#define SH_TRIGGER_SEL_NIBBLE2_INPUT_SEL_MASK    0x0000000000070000
+
+/*   SH_TRIGGER_SEL_NIBBLE2_NIBBLE_SEL                                  */
+/*   Description:  Nibble 2 Nibble select                               */
+#define SH_TRIGGER_SEL_NIBBLE2_NIBBLE_SEL_SHFT   20
+#define SH_TRIGGER_SEL_NIBBLE2_NIBBLE_SEL_MASK   0x0000000000700000
+
+/*   SH_TRIGGER_SEL_NIBBLE3_INPUT_SEL                                   */
+/*   Description:  Nibble 3 input select                                */
+#define SH_TRIGGER_SEL_NIBBLE3_INPUT_SEL_SHFT    24
+#define SH_TRIGGER_SEL_NIBBLE3_INPUT_SEL_MASK    0x0000000007000000
+
+/*   SH_TRIGGER_SEL_NIBBLE3_NIBBLE_SEL                                  */
+/*   Description:  Nibble 3 Nibble select                               */
+#define SH_TRIGGER_SEL_NIBBLE3_NIBBLE_SEL_SHFT   28
+#define SH_TRIGGER_SEL_NIBBLE3_NIBBLE_SEL_MASK   0x0000000070000000
+
+/*   SH_TRIGGER_SEL_NIBBLE4_INPUT_SEL                                   */
+/*   Description:  Nibble 4 input select                                */
+#define SH_TRIGGER_SEL_NIBBLE4_INPUT_SEL_SHFT    32
+#define SH_TRIGGER_SEL_NIBBLE4_INPUT_SEL_MASK    0x0000000700000000
+
+/*   SH_TRIGGER_SEL_NIBBLE4_NIBBLE_SEL                                  */
+/*   Description:  Nibble 4 Nibble select                               */
+#define SH_TRIGGER_SEL_NIBBLE4_NIBBLE_SEL_SHFT   36
+#define SH_TRIGGER_SEL_NIBBLE4_NIBBLE_SEL_MASK   0x0000007000000000
+
+/*   SH_TRIGGER_SEL_NIBBLE5_INPUT_SEL                                   */
+/*   Description:  Nibble 5 input select                                */
+#define SH_TRIGGER_SEL_NIBBLE5_INPUT_SEL_SHFT    40
+#define SH_TRIGGER_SEL_NIBBLE5_INPUT_SEL_MASK    0x0000070000000000
+
+/*   SH_TRIGGER_SEL_NIBBLE5_NIBBLE_SEL                                  */
+/*   Description:  Nibble 5 Nibble select                               */
+#define SH_TRIGGER_SEL_NIBBLE5_NIBBLE_SEL_SHFT   44
+#define SH_TRIGGER_SEL_NIBBLE5_NIBBLE_SEL_MASK   0x0000700000000000
+
+/*   SH_TRIGGER_SEL_NIBBLE6_INPUT_SEL                                   */
+/*   Description:  Nibble 6 input select                                */
+#define SH_TRIGGER_SEL_NIBBLE6_INPUT_SEL_SHFT    48
+#define SH_TRIGGER_SEL_NIBBLE6_INPUT_SEL_MASK    0x0007000000000000
+
+/*   SH_TRIGGER_SEL_NIBBLE6_NIBBLE_SEL                                  */
+/*   Description:  Nibble 6 Nibble select                               */
+#define SH_TRIGGER_SEL_NIBBLE6_NIBBLE_SEL_SHFT   52
+#define SH_TRIGGER_SEL_NIBBLE6_NIBBLE_SEL_MASK   0x0070000000000000
+
+/*   SH_TRIGGER_SEL_NIBBLE7_INPUT_SEL                                   */
+/*   Description:  Nibble 7 input select                                */
+#define SH_TRIGGER_SEL_NIBBLE7_INPUT_SEL_SHFT    56
+#define SH_TRIGGER_SEL_NIBBLE7_INPUT_SEL_MASK    0x0700000000000000
+
+/*   SH_TRIGGER_SEL_NIBBLE7_NIBBLE_SEL                                  */
+/*   Description:  Nibble 7 Nibble select                               */
+#define SH_TRIGGER_SEL_NIBBLE7_NIBBLE_SEL_SHFT   60
+#define SH_TRIGGER_SEL_NIBBLE7_NIBBLE_SEL_MASK   0x7000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_STOP_CLK_CONTROL"                    */
+/*                          Stop Clock Control                          */
+/* ==================================================================== */
+
+#define SH_STOP_CLK_CONTROL                      0x0000000110064000
+#define SH_STOP_CLK_CONTROL_MASK                 0x00000000000000ff
+#define SH_STOP_CLK_CONTROL_INIT                 0x00000000000000e0
+
+/*   SH_STOP_CLK_CONTROL_STIMULUS                                       */
+/*   Description:  Counter stimulus                                     */
+#define SH_STOP_CLK_CONTROL_STIMULUS_SHFT        0
+#define SH_STOP_CLK_CONTROL_STIMULUS_MASK        0x000000000000001f
+
+/*   SH_STOP_CLK_CONTROL_EVENT                                          */
+/*   Description:  Counter event select (0-greater than, 1-equal)       */
+#define SH_STOP_CLK_CONTROL_EVENT_SHFT           5
+#define SH_STOP_CLK_CONTROL_EVENT_MASK           0x0000000000000020
+
+/*   SH_STOP_CLK_CONTROL_POLARITY                                       */
+/*   Description:  Counter polarity select (0-negative edge, 1-positiv  */
+/*  e edge)                                                             */
+#define SH_STOP_CLK_CONTROL_POLARITY_SHFT        6
+#define SH_STOP_CLK_CONTROL_POLARITY_MASK        0x0000000000000040
+
+/*   SH_STOP_CLK_CONTROL_MODE                                           */
+/*   Description:  Counter mode select (0-internal, 1-external)         */
+#define SH_STOP_CLK_CONTROL_MODE_SHFT            7
+#define SH_STOP_CLK_CONTROL_MODE_MASK            0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_STOP_CLK_DELAY_PHASE"                  */
+/*                        Stop Clock Delay Phase                        */
+/* ==================================================================== */
+
+#define SH_STOP_CLK_DELAY_PHASE                  0x0000000110064080
+#define SH_STOP_CLK_DELAY_PHASE_MASK             0x00000000000000ff
+#define SH_STOP_CLK_DELAY_PHASE_INIT             0x0000000000000000
+
+/*   SH_STOP_CLK_DELAY_PHASE_DELAY                                      */
+/*   Description:  Delay phase                                          */
+#define SH_STOP_CLK_DELAY_PHASE_DELAY_SHFT       0
+#define SH_STOP_CLK_DELAY_PHASE_DELAY_MASK       0x00000000000000ff
+
+/* ==================================================================== */
+/*                      Register "SH_TSF_ARM_MASK"                      */
+/*                 Trigger sequencing facility arm mask                 */
+/* ==================================================================== */
+
+#define SH_TSF_ARM_MASK                          0x0000000110065000
+#define SH_TSF_ARM_MASK_MASK                     0xffffffffffffffff
+#define SH_TSF_ARM_MASK_INIT                     0x0000000000000000
+
+/*   SH_TSF_ARM_MASK_MASK                                               */
+/*   Description:  Trigger sequencing facility arm mask                 */
+#define SH_TSF_ARM_MASK_MASK_SHFT                0
+#define SH_TSF_ARM_MASK_MASK_MASK                0xffffffffffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_TSF_COUNTER_PRESETS"                   */
+/*             Trigger sequencing facility counter presets              */
+/* ==================================================================== */
+
+#define SH_TSF_COUNTER_PRESETS                   0x0000000110065080
+#define SH_TSF_COUNTER_PRESETS_MASK              0xffffffffffffffff
+#define SH_TSF_COUNTER_PRESETS_INIT              0x0000000000000000
+
+/*   SH_TSF_COUNTER_PRESETS_COUNT_32                                    */
+/*   Description:  Trigger sequencing facility counter 32               */
+#define SH_TSF_COUNTER_PRESETS_COUNT_32_SHFT     0
+#define SH_TSF_COUNTER_PRESETS_COUNT_32_MASK     0x00000000ffffffff
+
+/*   SH_TSF_COUNTER_PRESETS_COUNT_16                                    */
+/*   Description:  Trigger sequencing facility counter 16               */
+#define SH_TSF_COUNTER_PRESETS_COUNT_16_SHFT     32
+#define SH_TSF_COUNTER_PRESETS_COUNT_16_MASK     0x0000ffff00000000
+
+/*   SH_TSF_COUNTER_PRESETS_COUNT_8B                                    */
+/*   Description:  Trigger sequencing facility counter 8b               */
+#define SH_TSF_COUNTER_PRESETS_COUNT_8B_SHFT     48
+#define SH_TSF_COUNTER_PRESETS_COUNT_8B_MASK     0x00ff000000000000
+
+/*   SH_TSF_COUNTER_PRESETS_COUNT_8A                                    */
+/*   Description:  Trigger sequencing facility counter 8a               */
+#define SH_TSF_COUNTER_PRESETS_COUNT_8A_SHFT     56
+#define SH_TSF_COUNTER_PRESETS_COUNT_8A_MASK     0xff00000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_TSF_DECREMENT_CTL"                    */
+/*        Trigger sequencing facility counter decrement control         */
+/* ==================================================================== */
+
+#define SH_TSF_DECREMENT_CTL                     0x0000000110065100
+#define SH_TSF_DECREMENT_CTL_MASK                0x000000000000ffff
+#define SH_TSF_DECREMENT_CTL_INIT                0x0000000000000000
+
+/*   SH_TSF_DECREMENT_CTL_CTL                                           */
+/*   Description:  Trigger sequencing facility counter decrement contr  */
+#define SH_TSF_DECREMENT_CTL_CTL_SHFT            0
+#define SH_TSF_DECREMENT_CTL_CTL_MASK            0x000000000000ffff
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_DIAG_MSG_CTL"                    */
+/*        Trigger sequencing facility diagnostic message control        */
+/* ==================================================================== */
+
+#define SH_TSF_DIAG_MSG_CTL                      0x0000000110065180
+#define SH_TSF_DIAG_MSG_CTL_MASK                 0x00000000000000ff
+#define SH_TSF_DIAG_MSG_CTL_INIT                 0x0000000000000000
+
+/*   SH_TSF_DIAG_MSG_CTL_ENABLE                                         */
+/*   Description:  Trigger sequencing facility diagnostic message cont  */
+#define SH_TSF_DIAG_MSG_CTL_ENABLE_SHFT          0
+#define SH_TSF_DIAG_MSG_CTL_ENABLE_MASK          0x00000000000000ff
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_DISARM_MASK"                     */
+/*               Trigger sequencing facility disarm mask                */
+/* ==================================================================== */
+
+#define SH_TSF_DISARM_MASK                       0x0000000110065200
+#define SH_TSF_DISARM_MASK_MASK                  0xffffffffffffffff
+#define SH_TSF_DISARM_MASK_INIT                  0x0000000000000000
+
+/*   SH_TSF_DISARM_MASK_MASK                                            */
+/*   Description:  Trigger sequencing facility disarm mask              */
+#define SH_TSF_DISARM_MASK_MASK_SHFT             0
+#define SH_TSF_DISARM_MASK_MASK_MASK             0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_TSF_ENABLE_CTL"                     */
+/*          Trigger sequencing facility counter enable control          */
+/* ==================================================================== */
+
+#define SH_TSF_ENABLE_CTL                        0x0000000110065280
+#define SH_TSF_ENABLE_CTL_MASK                   0x000000000000ffff
+#define SH_TSF_ENABLE_CTL_INIT                   0x0000000000000000
+
+/*   SH_TSF_ENABLE_CTL_CTL                                              */
+/*   Description:  Trigger sequencing facility counter enable control  */
+#define SH_TSF_ENABLE_CTL_CTL_SHFT               0
+#define SH_TSF_ENABLE_CTL_CTL_MASK               0x000000000000ffff
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_SOFTWARE_ARM"                    */
+/*               Trigger sequencing facility software arm               */
+/* ==================================================================== */
+
+#define SH_TSF_SOFTWARE_ARM                      0x0000000110065300
+#define SH_TSF_SOFTWARE_ARM_MASK                 0x00000000000000ff
+#define SH_TSF_SOFTWARE_ARM_INIT                 0x0000000000000000
+
+/*   SH_TSF_SOFTWARE_ARM_BIT0                                           */
+/*   Description:  Trigger sequencing facility software arm bit 0       */
+#define SH_TSF_SOFTWARE_ARM_BIT0_SHFT            0
+#define SH_TSF_SOFTWARE_ARM_BIT0_MASK            0x0000000000000001
+
+/*   SH_TSF_SOFTWARE_ARM_BIT1                                           */
+/*   Description:  Trigger sequencing facility software arm bit 1       */
+#define SH_TSF_SOFTWARE_ARM_BIT1_SHFT            1
+#define SH_TSF_SOFTWARE_ARM_BIT1_MASK            0x0000000000000002
+
+/*   SH_TSF_SOFTWARE_ARM_BIT2                                           */
+/*   Description:  Trigger sequencing facility software arm bit 2       */
+#define SH_TSF_SOFTWARE_ARM_BIT2_SHFT            2
+#define SH_TSF_SOFTWARE_ARM_BIT2_MASK            0x0000000000000004
+
+/*   SH_TSF_SOFTWARE_ARM_BIT3                                           */
+/*   Description:  Trigger sequencing facility software arm bit 3       */
+#define SH_TSF_SOFTWARE_ARM_BIT3_SHFT            3
+#define SH_TSF_SOFTWARE_ARM_BIT3_MASK            0x0000000000000008
+
+/*   SH_TSF_SOFTWARE_ARM_BIT4                                           */
+/*   Description:  Trigger sequencing facility software arm bit 4       */
+#define SH_TSF_SOFTWARE_ARM_BIT4_SHFT            4
+#define SH_TSF_SOFTWARE_ARM_BIT4_MASK            0x0000000000000010
+
+/*   SH_TSF_SOFTWARE_ARM_BIT5                                           */
+/*   Description:  Trigger sequencing facility software arm bit 5       */
+#define SH_TSF_SOFTWARE_ARM_BIT5_SHFT            5
+#define SH_TSF_SOFTWARE_ARM_BIT5_MASK            0x0000000000000020
+
+/*   SH_TSF_SOFTWARE_ARM_BIT6                                           */
+/*   Description:  Trigger sequencing facility software arm bit 6       */
+#define SH_TSF_SOFTWARE_ARM_BIT6_SHFT            6
+#define SH_TSF_SOFTWARE_ARM_BIT6_MASK            0x0000000000000040
+
+/*   SH_TSF_SOFTWARE_ARM_BIT7                                           */
+/*   Description:  Trigger sequencing facility software arm bit 7       */
+#define SH_TSF_SOFTWARE_ARM_BIT7_SHFT            7
+#define SH_TSF_SOFTWARE_ARM_BIT7_MASK            0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_TSF_SOFTWARE_DISARM"                   */
+/*             Trigger sequencing facility software disarm              */
+/* ==================================================================== */
+
+#define SH_TSF_SOFTWARE_DISARM                   0x0000000110065380
+#define SH_TSF_SOFTWARE_DISARM_MASK              0x00000000000000ff
+#define SH_TSF_SOFTWARE_DISARM_INIT              0x0000000000000000
+
+/*   SH_TSF_SOFTWARE_DISARM_BIT0                                        */
+/*   Description:  Trigger sequencing facility software disarm bit 0    */
+#define SH_TSF_SOFTWARE_DISARM_BIT0_SHFT         0
+#define SH_TSF_SOFTWARE_DISARM_BIT0_MASK         0x0000000000000001
+
+/*   SH_TSF_SOFTWARE_DISARM_BIT1                                        */
+/*   Description:  Trigger sequencing facility software disarm bit 1    */
+#define SH_TSF_SOFTWARE_DISARM_BIT1_SHFT         1
+#define SH_TSF_SOFTWARE_DISARM_BIT1_MASK         0x0000000000000002
+
+/*   SH_TSF_SOFTWARE_DISARM_BIT2                                        */
+/*   Description:  Trigger sequencing facility software disarm bit 2    */
+#define SH_TSF_SOFTWARE_DISARM_BIT2_SHFT         2
+#define SH_TSF_SOFTWARE_DISARM_BIT2_MASK         0x0000000000000004
+
+/*   SH_TSF_SOFTWARE_DISARM_BIT3                                        */
+/*   Description:  Trigger sequencing facility software disarm bit 3    */
+#define SH_TSF_SOFTWARE_DISARM_BIT3_SHFT         3
+#define SH_TSF_SOFTWARE_DISARM_BIT3_MASK         0x0000000000000008
+
+/*   SH_TSF_SOFTWARE_DISARM_BIT4                                        */
+/*   Description:  Trigger sequencing facility software disarm bit 4    */
+#define SH_TSF_SOFTWARE_DISARM_BIT4_SHFT         4
+#define SH_TSF_SOFTWARE_DISARM_BIT4_MASK         0x0000000000000010
+
+/*   SH_TSF_SOFTWARE_DISARM_BIT5                                        */
+/*   Description:  Trigger sequencing facility software disarm bit 5    */
+#define SH_TSF_SOFTWARE_DISARM_BIT5_SHFT         5
+#define SH_TSF_SOFTWARE_DISARM_BIT5_MASK         0x0000000000000020
+
+/*   SH_TSF_SOFTWARE_DISARM_BIT6                                        */
+/*   Description:  Trigger sequencing facility software disarm bit 6    */
+#define SH_TSF_SOFTWARE_DISARM_BIT6_SHFT         6
+#define SH_TSF_SOFTWARE_DISARM_BIT6_MASK         0x0000000000000040
+
+/*   SH_TSF_SOFTWARE_DISARM_BIT7                                        */
+/*   Description:  Trigger sequencing facility software disarm bit 7    */
+#define SH_TSF_SOFTWARE_DISARM_BIT7_SHFT         7
+#define SH_TSF_SOFTWARE_DISARM_BIT7_MASK         0x0000000000000080
+
+/* ==================================================================== */
+/*                 Register "SH_TSF_SOFTWARE_TRIGGERED"                 */
+/*            Trigger sequencing facility software triggered            */
+/* ==================================================================== */
+
+#define SH_TSF_SOFTWARE_TRIGGERED                0x0000000110065400
+#define SH_TSF_SOFTWARE_TRIGGERED_MASK           0x00000000000000ff
+#define SH_TSF_SOFTWARE_TRIGGERED_INIT           0x0000000000000000
+
+/*   SH_TSF_SOFTWARE_TRIGGERED_BIT0                                     */
+/*   Description:  Trigger sequencing facility software triggered bit   */
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT0_SHFT      0
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT0_MASK      0x0000000000000001
+
+/*   SH_TSF_SOFTWARE_TRIGGERED_BIT1                                     */
+/*   Description:  Trigger sequencing facility software triggered bit   */
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT1_SHFT      1
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT1_MASK      0x0000000000000002
+
+/*   SH_TSF_SOFTWARE_TRIGGERED_BIT2                                     */
+/*   Description:  Trigger sequencing facility software triggered bit   */
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT2_SHFT      2
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT2_MASK      0x0000000000000004
+
+/*   SH_TSF_SOFTWARE_TRIGGERED_BIT3                                     */
+/*   Description:  Trigger sequencing facility software triggered bit   */
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT3_SHFT      3
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT3_MASK      0x0000000000000008
+
+/*   SH_TSF_SOFTWARE_TRIGGERED_BIT4                                     */
+/*   Description:  Trigger sequencing facility software triggered bit   */
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT4_SHFT      4
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT4_MASK      0x0000000000000010
+
+/*   SH_TSF_SOFTWARE_TRIGGERED_BIT5                                     */
+/*   Description:  Trigger sequencing facility software triggered bit   */
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT5_SHFT      5
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT5_MASK      0x0000000000000020
+
+/*   SH_TSF_SOFTWARE_TRIGGERED_BIT6                                     */
+/*   Description:  Trigger sequencing facility software triggered bit   */
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT6_SHFT      6
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT6_MASK      0x0000000000000040
+
+/*   SH_TSF_SOFTWARE_TRIGGERED_BIT7                                     */
+/*   Description:  Trigger sequencing facility software triggered bit   */
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT7_SHFT      7
+#define SH_TSF_SOFTWARE_TRIGGERED_BIT7_MASK      0x0000000000000080
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_TRIGGER_MASK"                    */
+/*               Trigger sequencing facility trigger mask               */
+/* ==================================================================== */
+
+#define SH_TSF_TRIGGER_MASK                      0x0000000110065480
+#define SH_TSF_TRIGGER_MASK_MASK                 0xffffffffffffffff
+#define SH_TSF_TRIGGER_MASK_INIT                 0x0000000000000000
+
+/*   SH_TSF_TRIGGER_MASK_MASK                                           */
+/*   Description:  Trigger sequencing facility trigger mask             */
+#define SH_TSF_TRIGGER_MASK_MASK_SHFT            0
+#define SH_TSF_TRIGGER_MASK_MASK_MASK            0xffffffffffffffff
+
+/* ==================================================================== */
+/*                        Register "SH_VEC_DATA"                        */
+/*                  Vector Write Request Message Data                   */
+/* ==================================================================== */
+
+#define SH_VEC_DATA                              0x0000000110066000
+#define SH_VEC_DATA_MASK                         0xffffffffffffffff
+#define SH_VEC_DATA_INIT                         0x0000000000000000
+
+/*   SH_VEC_DATA_DATA                                                   */
+/*   Description:  Data                                                 */
+#define SH_VEC_DATA_DATA_SHFT                    0
+#define SH_VEC_DATA_DATA_MASK                    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_PARMS"                        */
+/*                  Vector Message Parameters Register                  */
+/* ==================================================================== */
+
+#define SH_VEC_PARMS                             0x0000000110066080
+#define SH_VEC_PARMS_MASK                        0xc0003ffffffffffb
+#define SH_VEC_PARMS_INIT                        0x0000000000000000
+
+/*   SH_VEC_PARMS_TYPE                                                  */
+/*   Description:  Vector Request Message Type                          */
+#define SH_VEC_PARMS_TYPE_SHFT                   0
+#define SH_VEC_PARMS_TYPE_MASK                   0x0000000000000001
+
+/*   SH_VEC_PARMS_NI_PORT                                               */
+/*   Description:  Network Interface Port Select                        */
+#define SH_VEC_PARMS_NI_PORT_SHFT                1
+#define SH_VEC_PARMS_NI_PORT_MASK                0x0000000000000002
+
+/*   SH_VEC_PARMS_ADDRESS                                               */
+/*   Description:  Address[37:6]                                        */
+#define SH_VEC_PARMS_ADDRESS_SHFT                3
+#define SH_VEC_PARMS_ADDRESS_MASK                0x00000007fffffff8
+
+/*   SH_VEC_PARMS_PIO_ID                                                */
+/*   Description:  PIO ID                                               */
+#define SH_VEC_PARMS_PIO_ID_SHFT                 35
+#define SH_VEC_PARMS_PIO_ID_MASK                 0x00003ff800000000
+
+/*   SH_VEC_PARMS_START                                                 */
+/*   Description:  Start                                                */
+#define SH_VEC_PARMS_START_SHFT                  62
+#define SH_VEC_PARMS_START_MASK                  0x4000000000000000
+
+/*   SH_VEC_PARMS_BUSY                                                  */
+/*   Description:  Busy                                                 */
+#define SH_VEC_PARMS_BUSY_SHFT                   63
+#define SH_VEC_PARMS_BUSY_MASK                   0x8000000000000000
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_ROUTE"                        */
+/*                     Vector Request Message Route                     */
+/* ==================================================================== */
+
+#define SH_VEC_ROUTE                             0x0000000110066100
+#define SH_VEC_ROUTE_MASK                        0xffffffffffffffff
+#define SH_VEC_ROUTE_INIT                        0x0000000000000000
+
+/*   SH_VEC_ROUTE_ROUTE                                                 */
+/*   Description:  Route                                                */
+#define SH_VEC_ROUTE_ROUTE_SHFT                  0
+#define SH_VEC_ROUTE_ROUTE_MASK                  0xffffffffffffffff
+
+/* ==================================================================== */
+/*                        Register "SH_CPU_PERM"                        */
+/*                    CPU MMR Access Permission Bits                    */
+/* ==================================================================== */
+
+#define SH_CPU_PERM                              0x0000000110060000
+#define SH_CPU_PERM_MASK                         0xffffffffffffffff
+#define SH_CPU_PERM_INIT                         0xffffffffffffffff
+
+/*   SH_CPU_PERM_ACCESS_BITS                                            */
+/*   Description:  Access Bits                                          */
+#define SH_CPU_PERM_ACCESS_BITS_SHFT             0
+#define SH_CPU_PERM_ACCESS_BITS_MASK             0xffffffffffffffff
+
+/* ==================================================================== */
+/*                      Register "SH_CPU_PERM_OVR"                      */
+/*                  CPU MMR Access Permission Override                  */
+/* ==================================================================== */
+
+#define SH_CPU_PERM_OVR                          0x0000000110060080
+#define SH_CPU_PERM_OVR_MASK                     0xffffffffffffffff
+#define SH_CPU_PERM_OVR_INIT                     0x0000000000000000
+
+/*   SH_CPU_PERM_OVR_OVERRIDE                                           */
+/*   Description:  Override                                             */
+#define SH_CPU_PERM_OVR_OVERRIDE_SHFT            0
+#define SH_CPU_PERM_OVR_OVERRIDE_MASK            0xffffffffffffffff
+
+/* ==================================================================== */
+/*                      Register "SH_EXT_IO_PERM"                       */
+/*                External IO MMR Access Permission Bits                */
+/* ==================================================================== */
+
+#define SH_EXT_IO_PERM                           0x0000000110060100
+#define SH_EXT_IO_PERM_MASK                      0xffffffffffffffff
+#define SH_EXT_IO_PERM_INIT                      0x0000000000000000
+
+/*   SH_EXT_IO_PERM_ACCESS_BITS                                         */
+/*   Description:  Access Bits                                          */
+#define SH_EXT_IO_PERM_ACCESS_BITS_SHFT          0
+#define SH_EXT_IO_PERM_ACCESS_BITS_MASK          0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_EXT_IOI_ACCESS"                     */
+/*             External IO Interrupt Access Permission Bits             */
+/* ==================================================================== */
+
+#define SH_EXT_IOI_ACCESS                        0x0000000110060180
+#define SH_EXT_IOI_ACCESS_MASK                   0xffffffffffffffff
+#define SH_EXT_IOI_ACCESS_INIT                   0xffffffffffffffff
+
+/*   SH_EXT_IOI_ACCESS_ACCESS_BITS                                      */
+/*   Description:  Access Bits                                          */
+#define SH_EXT_IOI_ACCESS_ACCESS_BITS_SHFT       0
+#define SH_EXT_IOI_ACCESS_ACCESS_BITS_MASK       0xffffffffffffffff
+
+/* ==================================================================== */
+/*                      Register "SH_GC_FIL_CTRL"                       */
+/*                   SHub Global Clock Filter Control                   */
+/* ==================================================================== */
+
+#define SH_GC_FIL_CTRL                           0x0000000110060200
+#define SH_GC_FIL_CTRL_MASK                      0x03ff3ff3ff1fff1f
+#define SH_GC_FIL_CTRL_INIT                      0x0000000000000000
+
+/*   SH_GC_FIL_CTRL_OFFSET                                              */
+/*   Description:  Offset                                               */
+#define SH_GC_FIL_CTRL_OFFSET_SHFT               0
+#define SH_GC_FIL_CTRL_OFFSET_MASK               0x000000000000001f
+
+/*   SH_GC_FIL_CTRL_MASK_COUNTER                                        */
+/*   Description:  Mask Counter                                         */
+#define SH_GC_FIL_CTRL_MASK_COUNTER_SHFT         8
+#define SH_GC_FIL_CTRL_MASK_COUNTER_MASK         0x00000000000fff00
+
+/*   SH_GC_FIL_CTRL_MASK_ENABLE                                         */
+/*   Description:  Mask Enable                                          */
+#define SH_GC_FIL_CTRL_MASK_ENABLE_SHFT          20
+#define SH_GC_FIL_CTRL_MASK_ENABLE_MASK          0x0000000000100000
+
+/*   SH_GC_FIL_CTRL_DROPOUT_COUNTER                                     */
+/*   Description:  Dropout Counter                                      */
+#define SH_GC_FIL_CTRL_DROPOUT_COUNTER_SHFT      24
+#define SH_GC_FIL_CTRL_DROPOUT_COUNTER_MASK      0x00000003ff000000
+
+/*   SH_GC_FIL_CTRL_DROPOUT_THRESH                                      */
+/*   Description:  Dropout threshold                                    */
+#define SH_GC_FIL_CTRL_DROPOUT_THRESH_SHFT       36
+#define SH_GC_FIL_CTRL_DROPOUT_THRESH_MASK       0x00003ff000000000
+
+/*   SH_GC_FIL_CTRL_ERROR_COUNTER                                       */
+/*   Description:  Error counter                                        */
+#define SH_GC_FIL_CTRL_ERROR_COUNTER_SHFT        48
+#define SH_GC_FIL_CTRL_ERROR_COUNTER_MASK        0x03ff000000000000
+
+/* ==================================================================== */
+/*                      Register "SH_GC_SRC_CTRL"                       */
+/*                      SHub Global Clock Control                       */
+/* ==================================================================== */
+
+#define SH_GC_SRC_CTRL                           0x0000000110060280
+#define SH_GC_SRC_CTRL_MASK                      0x0000000313ff3ff1
+#define SH_GC_SRC_CTRL_INIT                      0x0000000100000000
+
+/*   SH_GC_SRC_CTRL_ENABLE_COUNTER                                      */
+/*   Description:  Enable Counter                                       */
+#define SH_GC_SRC_CTRL_ENABLE_COUNTER_SHFT       0
+#define SH_GC_SRC_CTRL_ENABLE_COUNTER_MASK       0x0000000000000001
+
+/*   SH_GC_SRC_CTRL_MAX_COUNT                                           */
+/*   Description:  Max Count                                            */
+#define SH_GC_SRC_CTRL_MAX_COUNT_SHFT            4
+#define SH_GC_SRC_CTRL_MAX_COUNT_MASK            0x0000000000003ff0
+
+/*   SH_GC_SRC_CTRL_COUNTER                                             */
+/*   Description:  Counter                                              */
+#define SH_GC_SRC_CTRL_COUNTER_SHFT              16
+#define SH_GC_SRC_CTRL_COUNTER_MASK              0x0000000003ff0000
+
+/*   SH_GC_SRC_CTRL_TOGGLE_BIT                                          */
+/*   Description:  Toggle bit                                           */
+#define SH_GC_SRC_CTRL_TOGGLE_BIT_SHFT           28
+#define SH_GC_SRC_CTRL_TOGGLE_BIT_MASK           0x0000000010000000
+
+/*   SH_GC_SRC_CTRL_SOURCE_SEL                                          */
+/*   Description:  Source select (0=ext., 1=Int., 2=SHUB)               */
+#define SH_GC_SRC_CTRL_SOURCE_SEL_SHFT           32
+#define SH_GC_SRC_CTRL_SOURCE_SEL_MASK           0x0000000300000000
+
+/* ==================================================================== */
+/*                       Register "SH_HARD_RESET"                       */
+/*                           SHub Hard Reset                            */
+/* ==================================================================== */
+
+#define SH_HARD_RESET                            0x0000000110060300
+#define SH_HARD_RESET_MASK                       0x0000000000000001
+#define SH_HARD_RESET_INIT                       0x0000000000000000
+
+/*   SH_HARD_RESET_HARD_RESET                                           */
+/*   Description:  Hard Reset                                           */
+#define SH_HARD_RESET_HARD_RESET_SHFT            0
+#define SH_HARD_RESET_HARD_RESET_MASK            0x0000000000000001
+
+/* ==================================================================== */
+/*                        Register "SH_IO_PERM"                         */
+/*                    II MMR Access Permission Bits                     */
+/* ==================================================================== */
+
+#define SH_IO_PERM                               0x0000000110060380
+#define SH_IO_PERM_MASK                          0xffffffffffffffff
+#define SH_IO_PERM_INIT                          0x0000000000000000
+
+/*   SH_IO_PERM_ACCESS_BITS                                             */
+/*   Description:  Access Bits                                          */
+#define SH_IO_PERM_ACCESS_BITS_SHFT              0
+#define SH_IO_PERM_ACCESS_BITS_MASK              0xffffffffffffffff
+
+/* ==================================================================== */
+/*                       Register "SH_IOI_ACCESS"                       */
+/*                 II Interrupt Access Permission Bits                  */
+/* ==================================================================== */
+
+#define SH_IOI_ACCESS                            0x0000000110060400
+#define SH_IOI_ACCESS_MASK                       0xffffffffffffffff
+#define SH_IOI_ACCESS_INIT                       0xffffffffffffffff
+
+/*   SH_IOI_ACCESS_ACCESS_BITS                                          */
+/*   Description:  Access Bits                                          */
+#define SH_IOI_ACCESS_ACCESS_BITS_SHFT           0
+#define SH_IOI_ACCESS_ACCESS_BITS_MASK           0xffffffffffffffff
+
+/* ==================================================================== */
+/*                       Register "SH_IPI_ACCESS"                       */
+/*                 CPU interrupt Access Permission Bits                 */
+/* ==================================================================== */
+
+#define SH_IPI_ACCESS                            0x0000000110060480
+#define SH_IPI_ACCESS_MASK                       0xffffffffffffffff
+#define SH_IPI_ACCESS_INIT                       0xffffffffffffffff
+
+/*   SH_IPI_ACCESS_ACCESS_BITS                                          */
+/*   Description:  Access Bits                                          */
+#define SH_IPI_ACCESS_ACCESS_BITS_SHFT           0
+#define SH_IPI_ACCESS_ACCESS_BITS_MASK           0xffffffffffffffff
+
+/* ==================================================================== */
+/*                      Register "SH_JTAG_CONFIG"                       */
+/*                       SHub JTAG configuration                        */
+/* ==================================================================== */
+
+#define SH_JTAG_CONFIG                           0x0000000110060500
+#define SH_JTAG_CONFIG_MASK                      0x00ffffffffffffff
+#define SH_JTAG_CONFIG_INIT                      0x0000000000000000
+
+/*   SH_JTAG_CONFIG_MD_CLK_SEL                                          */
+/*   Description:  Select divide freq of DRAMCLK                        */
+#define SH_JTAG_CONFIG_MD_CLK_SEL_SHFT           0
+#define SH_JTAG_CONFIG_MD_CLK_SEL_MASK           0x0000000000000003
+
+/*   SH_JTAG_CONFIG_NI_CLK_SEL                                          */
+/*   Description:  Selects clock source for NICLK domain                */
+#define SH_JTAG_CONFIG_NI_CLK_SEL_SHFT           2
+#define SH_JTAG_CONFIG_NI_CLK_SEL_MASK           0x0000000000000004
+
+/*   SH_JTAG_CONFIG_II_CLK_SEL                                          */
+/*   Description:  Selects clock source for IOCLK domain                */
+#define SH_JTAG_CONFIG_II_CLK_SEL_SHFT           3
+#define SH_JTAG_CONFIG_II_CLK_SEL_MASK           0x0000000000000018
+
+/*   SH_JTAG_CONFIG_WRT90_TARGET                                        */
+/*   Description:  wrt90_target                                         */
+#define SH_JTAG_CONFIG_WRT90_TARGET_SHFT         5
+#define SH_JTAG_CONFIG_WRT90_TARGET_MASK         0x000000000007ffe0
+
+/*   SH_JTAG_CONFIG_WRT90_OVERRIDER                                     */
+/*   Description:  wrt90_overrideR                                      */
+#define SH_JTAG_CONFIG_WRT90_OVERRIDER_SHFT      19
+#define SH_JTAG_CONFIG_WRT90_OVERRIDER_MASK      0x0000000000080000
+
+/*   SH_JTAG_CONFIG_WRT90_OVERRIDE                                      */
+/*   Description:  wrt90_override                                       */
+#define SH_JTAG_CONFIG_WRT90_OVERRIDE_SHFT       20
+#define SH_JTAG_CONFIG_WRT90_OVERRIDE_MASK       0x0000000000100000
+
+/*   SH_JTAG_CONFIG_JTAG_MCI_RESET_DELAY                                */
+/*   Description:  jtag_mci_reset_delay                                 */
+#define SH_JTAG_CONFIG_JTAG_MCI_RESET_DELAY_SHFT 21
+#define SH_JTAG_CONFIG_JTAG_MCI_RESET_DELAY_MASK 0x0000000001e00000
+
+/*   SH_JTAG_CONFIG_JTAG_MCI_TARGET                                     */
+/*   Description:  jtag_mci_target                                      */
+#define SH_JTAG_CONFIG_JTAG_MCI_TARGET_SHFT      25
+#define SH_JTAG_CONFIG_JTAG_MCI_TARGET_MASK      0x0000007ffe000000
+
+/*   SH_JTAG_CONFIG_JTAG_MCI_OVERRIDE                                   */
+/*   Description:  jtag_mci_override                                    */
+#define SH_JTAG_CONFIG_JTAG_MCI_OVERRIDE_SHFT    39
+#define SH_JTAG_CONFIG_JTAG_MCI_OVERRIDE_MASK    0x0000008000000000
+
+/*   SH_JTAG_CONFIG_FSB_CONFIG_IOQ_DEPTH                                */
+/*   Description:  0=depth 8, 1=depth1                                  */
+#define SH_JTAG_CONFIG_FSB_CONFIG_IOQ_DEPTH_SHFT 40
+#define SH_JTAG_CONFIG_FSB_CONFIG_IOQ_DEPTH_MASK 0x0000010000000000
+
+/*   SH_JTAG_CONFIG_FSB_CONFIG_SAMPLE_BINIT                             */
+/*   Description:  Enable sampling of BINIT                             */
+#define SH_JTAG_CONFIG_FSB_CONFIG_SAMPLE_BINIT_SHFT 41
+#define SH_JTAG_CONFIG_FSB_CONFIG_SAMPLE_BINIT_MASK 0x0000020000000000
+
+/*   SH_JTAG_CONFIG_FSB_CONFIG_ENABLE_BUS_PARKING                       */
+#define SH_JTAG_CONFIG_FSB_CONFIG_ENABLE_BUS_PARKING_SHFT 42
+#define SH_JTAG_CONFIG_FSB_CONFIG_ENABLE_BUS_PARKING_MASK 0x0000040000000000
+
+/*   SH_JTAG_CONFIG_FSB_CONFIG_CLOCK_RATIO                              */
+#define SH_JTAG_CONFIG_FSB_CONFIG_CLOCK_RATIO_SHFT 43
+#define SH_JTAG_CONFIG_FSB_CONFIG_CLOCK_RATIO_MASK 0x0000f80000000000
+
+/*   SH_JTAG_CONFIG_FSB_CONFIG_OUTPUT_TRISTATE                          */
+/*   Description:  Output tristate control                              */
+#define SH_JTAG_CONFIG_FSB_CONFIG_OUTPUT_TRISTATE_SHFT 48
+#define SH_JTAG_CONFIG_FSB_CONFIG_OUTPUT_TRISTATE_MASK 0x000f000000000000
+
+/*   SH_JTAG_CONFIG_FSB_CONFIG_ENABLE_BIST                              */
+/*   Description:  Enables BIST                                         */
+#define SH_JTAG_CONFIG_FSB_CONFIG_ENABLE_BIST_SHFT 52
+#define SH_JTAG_CONFIG_FSB_CONFIG_ENABLE_BIST_MASK 0x0010000000000000
+
+/*   SH_JTAG_CONFIG_FSB_CONFIG_AUX                                      */
+/*   Description:  Enables BIST                                         */
+#define SH_JTAG_CONFIG_FSB_CONFIG_AUX_SHFT       53
+#define SH_JTAG_CONFIG_FSB_CONFIG_AUX_MASK       0x0060000000000000
+
+/*   SH_JTAG_CONFIG_GTL_CONFIG_RE                                       */
+/*   Description:  Reference Enable selection for GTL io                */
+#define SH_JTAG_CONFIG_GTL_CONFIG_RE_SHFT        55
+#define SH_JTAG_CONFIG_GTL_CONFIG_RE_MASK        0x0080000000000000
+
+/* ==================================================================== */
+/*                        Register "SH_SHUB_ID"                         */
+/*                            SHub ID Number                            */
+/* ==================================================================== */
+
+#define SH_SHUB_ID                               0x0000000110060580
+#define SH_SHUB_ID_MASK                          0x011f37ffffffffff
+#define SH_SHUB_ID_INIT                          0x0010300000000000
+
+/*   SH_SHUB_ID_FORCE1                                                  */
+/*   Description:  Must be 1                                            */
+#define SH_SHUB_ID_FORCE1_SHFT                   0
+#define SH_SHUB_ID_FORCE1_MASK                   0x0000000000000001
+
+/*   SH_SHUB_ID_MANUFACTURER                                            */
+/*   Description:  Manufacturer                                         */
+#define SH_SHUB_ID_MANUFACTURER_SHFT             1
+#define SH_SHUB_ID_MANUFACTURER_MASK             0x0000000000000ffe
+
+/*   SH_SHUB_ID_PART_NUMBER                                             */
+/*   Description:  Part Number                                          */
+#define SH_SHUB_ID_PART_NUMBER_SHFT              12
+#define SH_SHUB_ID_PART_NUMBER_MASK              0x000000000ffff000
+
+/*   SH_SHUB_ID_REVISION                                                */
+/*   Description:  Revision                                             */
+#define SH_SHUB_ID_REVISION_SHFT                 28
+#define SH_SHUB_ID_REVISION_MASK                 0x00000000f0000000
+
+/*   SH_SHUB_ID_NODE_ID                                                 */
+/*   Description:  Node Identification                                  */
+#define SH_SHUB_ID_NODE_ID_SHFT                  32
+#define SH_SHUB_ID_NODE_ID_MASK                  0x000007ff00000000
+
+/*   SH_SHUB_ID_SHARING_MODE                                            */
+/*   Description:  Sharing mode (Coherency Domain Size)                 */
+#define SH_SHUB_ID_SHARING_MODE_SHFT             44
+#define SH_SHUB_ID_SHARING_MODE_MASK             0x0000300000000000
+
+/*   SH_SHUB_ID_NODES_PER_BIT                                           */
+/*   Description:  Nodes per bit definition for MMR access              */
+#define SH_SHUB_ID_NODES_PER_BIT_SHFT            48
+#define SH_SHUB_ID_NODES_PER_BIT_MASK            0x001f000000000000
+
+/*   SH_SHUB_ID_NI_PORT                                                 */
+/*   Description:  NI port of vector reference, 0 = NI0, 1 = NI1        */
+#define SH_SHUB_ID_NI_PORT_SHFT                  56
+#define SH_SHUB_ID_NI_PORT_MASK                  0x0100000000000000
+
+/* ==================================================================== */
+/*                     Register "SH_SHUBS_PRESENT0"                     */
+/*         Shubs 0 - 63 Present. Used for invalidate generation         */
+/* ==================================================================== */
+
+#define SH_SHUBS_PRESENT0                        0x0000000110060600
+#define SH_SHUBS_PRESENT0_MASK                   0xffffffffffffffff
+#define SH_SHUBS_PRESENT0_INIT                   0xffffffffffffffff
+
+/*   SH_SHUBS_PRESENT0_SHUBS_PRESENT0                                   */
+/*   Description:  Shubs 0 - 63 Present configuration                   */
+#define SH_SHUBS_PRESENT0_SHUBS_PRESENT0_SHFT    0
+#define SH_SHUBS_PRESENT0_SHUBS_PRESENT0_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_SHUBS_PRESENT1"                     */
+/*        Shubs 64 - 127 Present. Used for invalidate generation        */
+/* ==================================================================== */
+
+#define SH_SHUBS_PRESENT1                        0x0000000110060680
+#define SH_SHUBS_PRESENT1_MASK                   0xffffffffffffffff
+#define SH_SHUBS_PRESENT1_INIT                   0xffffffffffffffff
+
+/*   SH_SHUBS_PRESENT1_SHUBS_PRESENT1                                   */
+/*   Description:  Shubs 64 - 127 Present configuration                 */
+#define SH_SHUBS_PRESENT1_SHUBS_PRESENT1_SHFT    0
+#define SH_SHUBS_PRESENT1_SHUBS_PRESENT1_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_SHUBS_PRESENT2"                     */
+/*       Shubs 128 - 191 Present. Used for invalidate generation        */
+/* ==================================================================== */
+
+#define SH_SHUBS_PRESENT2                        0x0000000110060700
+#define SH_SHUBS_PRESENT2_MASK                   0xffffffffffffffff
+#define SH_SHUBS_PRESENT2_INIT                   0xffffffffffffffff
+
+/*   SH_SHUBS_PRESENT2_SHUBS_PRESENT2                                   */
+/*   Description:  Shubs 128 - 191 Present configuration                */
+#define SH_SHUBS_PRESENT2_SHUBS_PRESENT2_SHFT    0
+#define SH_SHUBS_PRESENT2_SHUBS_PRESENT2_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_SHUBS_PRESENT3"                     */
+/*       Shubs 192 - 255 Present. Used for invalidate generation        */
+/* ==================================================================== */
+
+#define SH_SHUBS_PRESENT3                        0x0000000110060780
+#define SH_SHUBS_PRESENT3_MASK                   0xffffffffffffffff
+#define SH_SHUBS_PRESENT3_INIT                   0xffffffffffffffff
+
+/*   SH_SHUBS_PRESENT3_SHUBS_PRESENT3                                   */
+/*   Description:  Shubs 192 - 255 Present configuration                */
+#define SH_SHUBS_PRESENT3_SHUBS_PRESENT3_SHFT    0
+#define SH_SHUBS_PRESENT3_SHUBS_PRESENT3_MASK    0xffffffffffffffff
+
+/* ==================================================================== */
+/*                       Register "SH_SOFT_RESET"                       */
+/*                           SHub Soft Reset                            */
+/* ==================================================================== */
+
+#define SH_SOFT_RESET                            0x0000000110060800
+#define SH_SOFT_RESET_MASK                       0x0000000000000001
+#define SH_SOFT_RESET_INIT                       0x0000000000000000
+
+/*   SH_SOFT_RESET_SOFT_RESET                                           */
+/*   Description:  Soft Reset                                           */
+#define SH_SOFT_RESET_SOFT_RESET_SHFT            0
+#define SH_SOFT_RESET_SOFT_RESET_MASK            0x0000000000000001
+
+/* ==================================================================== */
+/*                      Register "SH_FIRST_ERROR"                       */
+/*                    Shub Global First Error Flags                     */
+/* ==================================================================== */
+
+#define SH_FIRST_ERROR                           0x0000000110071000
+#define SH_FIRST_ERROR_MASK                      0x000000000007ffff
+#define SH_FIRST_ERROR_INIT                      0x0000000000000000
+
+/*   SH_FIRST_ERROR_FIRST_ERROR                                         */
+/*   Description:  Chiplet with first error                             */
+#define SH_FIRST_ERROR_FIRST_ERROR_SHFT          0
+#define SH_FIRST_ERROR_FIRST_ERROR_MASK          0x000000000007ffff
+
+/* ==================================================================== */
+/*                    Register "SH_II_HW_TIME_STAMP"                    */
+/*                     II hardware error time stamp                     */
+/* ==================================================================== */
+
+#define SH_II_HW_TIME_STAMP                      0x0000000110071080
+#define SH_II_HW_TIME_STAMP_MASK                 0xffffffffffffffff
+#define SH_II_HW_TIME_STAMP_INIT                 0x0000000000000000
+
+/*   SH_II_HW_TIME_STAMP_TIME                                           */
+/*   Description:  II hardware error time stamp                         */
+#define SH_II_HW_TIME_STAMP_TIME_SHFT            0
+#define SH_II_HW_TIME_STAMP_TIME_MASK            0x7fffffffffffffff
+
+/*   SH_II_HW_TIME_STAMP_VALID                                          */
+/*   Description:  II hardware error time stamp valid                   */
+#define SH_II_HW_TIME_STAMP_VALID_SHFT           63
+#define SH_II_HW_TIME_STAMP_VALID_MASK           0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_LB_HW_TIME_STAMP"                    */
+/*                     LB hardware error time stamp                     */
+/* ==================================================================== */
+
+#define SH_LB_HW_TIME_STAMP                      0x0000000110071100
+#define SH_LB_HW_TIME_STAMP_MASK                 0xffffffffffffffff
+#define SH_LB_HW_TIME_STAMP_INIT                 0x0000000000000000
+
+/*   SH_LB_HW_TIME_STAMP_TIME                                           */
+/*   Description:  LB hardware error time stamp                         */
+#define SH_LB_HW_TIME_STAMP_TIME_SHFT            0
+#define SH_LB_HW_TIME_STAMP_TIME_MASK            0x7fffffffffffffff
+
+/*   SH_LB_HW_TIME_STAMP_VALID                                          */
+/*   Description:  LB hardware error time stamp valid                   */
+#define SH_LB_HW_TIME_STAMP_VALID_SHFT           63
+#define SH_LB_HW_TIME_STAMP_VALID_MASK           0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_COR_TIME_STAMP"                    */
+/*                   MD correctable error time stamp                    */
+/* ==================================================================== */
+
+#define SH_MD_COR_TIME_STAMP                     0x0000000110071180
+#define SH_MD_COR_TIME_STAMP_MASK                0xffffffffffffffff
+#define SH_MD_COR_TIME_STAMP_INIT                0x0000000000000000
+
+/*   SH_MD_COR_TIME_STAMP_TIME                                          */
+/*   Description:  MD correctable error time stamp                      */
+#define SH_MD_COR_TIME_STAMP_TIME_SHFT           0
+#define SH_MD_COR_TIME_STAMP_TIME_MASK           0x7fffffffffffffff
+
+/*   SH_MD_COR_TIME_STAMP_VALID                                         */
+/*   Description:  MD correctable error time stamp valid                */
+#define SH_MD_COR_TIME_STAMP_VALID_SHFT          63
+#define SH_MD_COR_TIME_STAMP_VALID_MASK          0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_MD_HW_TIME_STAMP"                    */
+/*                     MD hardware error time stamp                     */
+/* ==================================================================== */
+
+#define SH_MD_HW_TIME_STAMP                      0x0000000110071200
+#define SH_MD_HW_TIME_STAMP_MASK                 0xffffffffffffffff
+#define SH_MD_HW_TIME_STAMP_INIT                 0x0000000000000000
+
+/*   SH_MD_HW_TIME_STAMP_TIME                                           */
+/*   Description:  MD hardware error time stamp                         */
+#define SH_MD_HW_TIME_STAMP_TIME_SHFT            0
+#define SH_MD_HW_TIME_STAMP_TIME_MASK            0x7fffffffffffffff
+
+/*   SH_MD_HW_TIME_STAMP_VALID                                          */
+/*   Description:  MD hardware error time stamp valid                   */
+#define SH_MD_HW_TIME_STAMP_VALID_SHFT           63
+#define SH_MD_HW_TIME_STAMP_VALID_MASK           0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_UNCOR_TIME_STAMP"                   */
+/*                  MD uncorrectable error time stamp                   */
+/* ==================================================================== */
+
+#define SH_MD_UNCOR_TIME_STAMP                   0x0000000110071280
+#define SH_MD_UNCOR_TIME_STAMP_MASK              0xffffffffffffffff
+#define SH_MD_UNCOR_TIME_STAMP_INIT              0x0000000000000000
+
+/*   SH_MD_UNCOR_TIME_STAMP_TIME                                        */
+/*   Description:  MD uncorrectable error time stamp                    */
+#define SH_MD_UNCOR_TIME_STAMP_TIME_SHFT         0
+#define SH_MD_UNCOR_TIME_STAMP_TIME_MASK         0x7fffffffffffffff
+
+/*   SH_MD_UNCOR_TIME_STAMP_VALID                                       */
+/*   Description:  MD uncorrectable error time stamp valid              */
+#define SH_MD_UNCOR_TIME_STAMP_VALID_SHFT        63
+#define SH_MD_UNCOR_TIME_STAMP_VALID_MASK        0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_PI_COR_TIME_STAMP"                    */
+/*                   PI correctable error time stamp                    */
+/* ==================================================================== */
+
+#define SH_PI_COR_TIME_STAMP                     0x0000000110071300
+#define SH_PI_COR_TIME_STAMP_MASK                0xffffffffffffffff
+#define SH_PI_COR_TIME_STAMP_INIT                0x0000000000000000
+
+/*   SH_PI_COR_TIME_STAMP_TIME                                          */
+/*   Description:  PI correctable error time stamp                      */
+#define SH_PI_COR_TIME_STAMP_TIME_SHFT           0
+#define SH_PI_COR_TIME_STAMP_TIME_MASK           0x7fffffffffffffff
+
+/*   SH_PI_COR_TIME_STAMP_VALID                                         */
+/*   Description:  PI correctable error time stamp valid                */
+#define SH_PI_COR_TIME_STAMP_VALID_SHFT          63
+#define SH_PI_COR_TIME_STAMP_VALID_MASK          0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_PI_HW_TIME_STAMP"                    */
+/*                     PI hardware error time stamp                     */
+/* ==================================================================== */
+
+#define SH_PI_HW_TIME_STAMP                      0x0000000110071380
+#define SH_PI_HW_TIME_STAMP_MASK                 0xffffffffffffffff
+#define SH_PI_HW_TIME_STAMP_INIT                 0x0000000000000000
+
+/*   SH_PI_HW_TIME_STAMP_TIME                                           */
+/*   Description:  PI hardware error time stamp                         */
+#define SH_PI_HW_TIME_STAMP_TIME_SHFT            0
+#define SH_PI_HW_TIME_STAMP_TIME_MASK            0x7fffffffffffffff
+
+/*   SH_PI_HW_TIME_STAMP_VALID                                          */
+/*   Description:  PI hardware error time stamp valid                   */
+#define SH_PI_HW_TIME_STAMP_VALID_SHFT           63
+#define SH_PI_HW_TIME_STAMP_VALID_MASK           0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PI_UNCOR_TIME_STAMP"                   */
+/*                  PI uncorrectable error time stamp                   */
+/* ==================================================================== */
+
+#define SH_PI_UNCOR_TIME_STAMP                   0x0000000110071400
+#define SH_PI_UNCOR_TIME_STAMP_MASK              0xffffffffffffffff
+#define SH_PI_UNCOR_TIME_STAMP_INIT              0x0000000000000000
+
+/*   SH_PI_UNCOR_TIME_STAMP_TIME                                        */
+/*   Description:  PI uncorrectable error time stamp                    */
+#define SH_PI_UNCOR_TIME_STAMP_TIME_SHFT         0
+#define SH_PI_UNCOR_TIME_STAMP_TIME_MASK         0x7fffffffffffffff
+
+/*   SH_PI_UNCOR_TIME_STAMP_VALID                                       */
+/*   Description:  PI uncorrectable error time stamp valid              */
+#define SH_PI_UNCOR_TIME_STAMP_VALID_SHFT        63
+#define SH_PI_UNCOR_TIME_STAMP_VALID_MASK        0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ADV_TIME_STAMP"                  */
+/*                      Proc 0 advisory time stamp                      */
+/* ==================================================================== */
+
+#define SH_PROC0_ADV_TIME_STAMP                  0x0000000110071480
+#define SH_PROC0_ADV_TIME_STAMP_MASK             0xffffffffffffffff
+#define SH_PROC0_ADV_TIME_STAMP_INIT             0x0000000000000000
+
+/*   SH_PROC0_ADV_TIME_STAMP_TIME                                       */
+/*   Description:  Processor 0 advisory time stamp                      */
+#define SH_PROC0_ADV_TIME_STAMP_TIME_SHFT        0
+#define SH_PROC0_ADV_TIME_STAMP_TIME_MASK        0x7fffffffffffffff
+
+/*   SH_PROC0_ADV_TIME_STAMP_VALID                                      */
+/*   Description:  Processor 0 advisory time stamp valid                */
+#define SH_PROC0_ADV_TIME_STAMP_VALID_SHFT       63
+#define SH_PROC0_ADV_TIME_STAMP_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ERR_TIME_STAMP"                  */
+/*                       Proc 0 error time stamp                        */
+/* ==================================================================== */
+
+#define SH_PROC0_ERR_TIME_STAMP                  0x0000000110071500
+#define SH_PROC0_ERR_TIME_STAMP_MASK             0xffffffffffffffff
+#define SH_PROC0_ERR_TIME_STAMP_INIT             0x0000000000000000
+
+/*   SH_PROC0_ERR_TIME_STAMP_TIME                                       */
+/*   Description:  Processor 0 error time stamp                         */
+#define SH_PROC0_ERR_TIME_STAMP_TIME_SHFT        0
+#define SH_PROC0_ERR_TIME_STAMP_TIME_MASK        0x7fffffffffffffff
+
+/*   SH_PROC0_ERR_TIME_STAMP_VALID                                      */
+/*   Description:  Processor 0 error time stamp valid                   */
+#define SH_PROC0_ERR_TIME_STAMP_VALID_SHFT       63
+#define SH_PROC0_ERR_TIME_STAMP_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ADV_TIME_STAMP"                  */
+/*                      Proc 1 advisory time stamp                      */
+/* ==================================================================== */
+
+#define SH_PROC1_ADV_TIME_STAMP                  0x0000000110071580
+#define SH_PROC1_ADV_TIME_STAMP_MASK             0xffffffffffffffff
+#define SH_PROC1_ADV_TIME_STAMP_INIT             0x0000000000000000
+
+/*   SH_PROC1_ADV_TIME_STAMP_TIME                                       */
+/*   Description:  Processor 1 advisory time stamp                      */
+#define SH_PROC1_ADV_TIME_STAMP_TIME_SHFT        0
+#define SH_PROC1_ADV_TIME_STAMP_TIME_MASK        0x7fffffffffffffff
+
+/*   SH_PROC1_ADV_TIME_STAMP_VALID                                      */
+/*   Description:  Processor 1 advisory time stamp valid                */
+#define SH_PROC1_ADV_TIME_STAMP_VALID_SHFT       63
+#define SH_PROC1_ADV_TIME_STAMP_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ERR_TIME_STAMP"                  */
+/*                       Proc 1 error time stamp                        */
+/* ==================================================================== */
+
+#define SH_PROC1_ERR_TIME_STAMP                  0x0000000110071600
+#define SH_PROC1_ERR_TIME_STAMP_MASK             0xffffffffffffffff
+#define SH_PROC1_ERR_TIME_STAMP_INIT             0x0000000000000000
+
+/*   SH_PROC1_ERR_TIME_STAMP_TIME                                       */
+/*   Description:  Processor 1 error time stamp                         */
+#define SH_PROC1_ERR_TIME_STAMP_TIME_SHFT        0
+#define SH_PROC1_ERR_TIME_STAMP_TIME_MASK        0x7fffffffffffffff
+
+/*   SH_PROC1_ERR_TIME_STAMP_VALID                                      */
+/*   Description:  Processor 1 error time stamp valid                   */
+#define SH_PROC1_ERR_TIME_STAMP_VALID_SHFT       63
+#define SH_PROC1_ERR_TIME_STAMP_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ADV_TIME_STAMP"                  */
+/*                      Proc 2 advisory time stamp                      */
+/* ==================================================================== */
+
+#define SH_PROC2_ADV_TIME_STAMP                  0x0000000110071680
+#define SH_PROC2_ADV_TIME_STAMP_MASK             0xffffffffffffffff
+#define SH_PROC2_ADV_TIME_STAMP_INIT             0x0000000000000000
+
+/*   SH_PROC2_ADV_TIME_STAMP_TIME                                       */
+/*   Description:  Processor 2 advisory time stamp                      */
+#define SH_PROC2_ADV_TIME_STAMP_TIME_SHFT        0
+#define SH_PROC2_ADV_TIME_STAMP_TIME_MASK        0x7fffffffffffffff
+
+/*   SH_PROC2_ADV_TIME_STAMP_VALID                                      */
+/*   Description:  Processor 2 advisory time stamp valid                */
+#define SH_PROC2_ADV_TIME_STAMP_VALID_SHFT       63
+#define SH_PROC2_ADV_TIME_STAMP_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ERR_TIME_STAMP"                  */
+/*                       Proc 2 error time stamp                        */
+/* ==================================================================== */
+
+#define SH_PROC2_ERR_TIME_STAMP                  0x0000000110071700
+#define SH_PROC2_ERR_TIME_STAMP_MASK             0xffffffffffffffff
+#define SH_PROC2_ERR_TIME_STAMP_INIT             0x0000000000000000
+
+/*   SH_PROC2_ERR_TIME_STAMP_TIME                                       */
+/*   Description:  Processor 2 error time stamp                         */
+#define SH_PROC2_ERR_TIME_STAMP_TIME_SHFT        0
+#define SH_PROC2_ERR_TIME_STAMP_TIME_MASK        0x7fffffffffffffff
+
+/*   SH_PROC2_ERR_TIME_STAMP_VALID                                      */
+/*   Description:  Processor 2 error time stamp valid                   */
+#define SH_PROC2_ERR_TIME_STAMP_VALID_SHFT       63
+#define SH_PROC2_ERR_TIME_STAMP_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ADV_TIME_STAMP"                  */
+/*                      Proc 3 advisory time stamp                      */
+/* ==================================================================== */
+
+#define SH_PROC3_ADV_TIME_STAMP                  0x0000000110071780
+#define SH_PROC3_ADV_TIME_STAMP_MASK             0xffffffffffffffff
+#define SH_PROC3_ADV_TIME_STAMP_INIT             0x0000000000000000
+
+/*   SH_PROC3_ADV_TIME_STAMP_TIME                                       */
+/*   Description:  Processor 3 advisory time stamp                      */
+#define SH_PROC3_ADV_TIME_STAMP_TIME_SHFT        0
+#define SH_PROC3_ADV_TIME_STAMP_TIME_MASK        0x7fffffffffffffff
+
+/*   SH_PROC3_ADV_TIME_STAMP_VALID                                      */
+/*   Description:  Processor 3 advisory time stamp valid                */
+#define SH_PROC3_ADV_TIME_STAMP_VALID_SHFT       63
+#define SH_PROC3_ADV_TIME_STAMP_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ERR_TIME_STAMP"                  */
+/*                       Proc 3 error time stamp                        */
+/* ==================================================================== */
+
+#define SH_PROC3_ERR_TIME_STAMP                  0x0000000110071800
+#define SH_PROC3_ERR_TIME_STAMP_MASK             0xffffffffffffffff
+#define SH_PROC3_ERR_TIME_STAMP_INIT             0x0000000000000000
+
+/*   SH_PROC3_ERR_TIME_STAMP_TIME                                       */
+/*   Description:  Processor 3 error time stamp                         */
+#define SH_PROC3_ERR_TIME_STAMP_TIME_SHFT        0
+#define SH_PROC3_ERR_TIME_STAMP_TIME_MASK        0x7fffffffffffffff
+
+/*   SH_PROC3_ERR_TIME_STAMP_VALID                                      */
+/*   Description:  Processor 3 error time stamp valid                   */
+#define SH_PROC3_ERR_TIME_STAMP_VALID_SHFT       63
+#define SH_PROC3_ERR_TIME_STAMP_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_XN_COR_TIME_STAMP"                    */
+/*                   XN correctable error time stamp                    */
+/* ==================================================================== */
+
+#define SH_XN_COR_TIME_STAMP                     0x0000000110071880
+#define SH_XN_COR_TIME_STAMP_MASK                0xffffffffffffffff
+#define SH_XN_COR_TIME_STAMP_INIT                0x0000000000000000
+
+/*   SH_XN_COR_TIME_STAMP_TIME                                          */
+/*   Description:  XN correctable error time stamp                      */
+#define SH_XN_COR_TIME_STAMP_TIME_SHFT           0
+#define SH_XN_COR_TIME_STAMP_TIME_MASK           0x7fffffffffffffff
+
+/*   SH_XN_COR_TIME_STAMP_VALID                                         */
+/*   Description:  XN correctable error time stamp valid                */
+#define SH_XN_COR_TIME_STAMP_VALID_SHFT          63
+#define SH_XN_COR_TIME_STAMP_VALID_MASK          0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_XN_HW_TIME_STAMP"                    */
+/*                     XN hardware error time stamp                     */
+/* ==================================================================== */
+
+#define SH_XN_HW_TIME_STAMP                      0x0000000110071900
+#define SH_XN_HW_TIME_STAMP_MASK                 0xffffffffffffffff
+#define SH_XN_HW_TIME_STAMP_INIT                 0x0000000000000000
+
+/*   SH_XN_HW_TIME_STAMP_TIME                                           */
+/*   Description:  XN hardware error time stamp                         */
+#define SH_XN_HW_TIME_STAMP_TIME_SHFT            0
+#define SH_XN_HW_TIME_STAMP_TIME_MASK            0x7fffffffffffffff
+
+/*   SH_XN_HW_TIME_STAMP_VALID                                          */
+/*   Description:  XN hardware error time stamp valid                   */
+#define SH_XN_HW_TIME_STAMP_VALID_SHFT           63
+#define SH_XN_HW_TIME_STAMP_VALID_MASK           0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_XN_UNCOR_TIME_STAMP"                   */
+/*                  XN uncorrectable error time stamp                   */
+/* ==================================================================== */
+
+#define SH_XN_UNCOR_TIME_STAMP                   0x0000000110071980
+#define SH_XN_UNCOR_TIME_STAMP_MASK              0xffffffffffffffff
+#define SH_XN_UNCOR_TIME_STAMP_INIT              0x0000000000000000
+
+/*   SH_XN_UNCOR_TIME_STAMP_TIME                                        */
+/*   Description:  XN uncorrectable error time stamp                    */
+#define SH_XN_UNCOR_TIME_STAMP_TIME_SHFT         0
+#define SH_XN_UNCOR_TIME_STAMP_TIME_MASK         0x7fffffffffffffff
+
+/*   SH_XN_UNCOR_TIME_STAMP_VALID                                       */
+/*   Description:  XN uncorrectable error time stamp valid              */
+#define SH_XN_UNCOR_TIME_STAMP_VALID_SHFT        63
+#define SH_XN_UNCOR_TIME_STAMP_VALID_MASK        0x8000000000000000
+
+/* ==================================================================== */
+/*                       Register "SH_DEBUG_PORT"                       */
+/*                           SHub Debug Port                            */
+/* ==================================================================== */
+
+#define SH_DEBUG_PORT                            0x0000000110072000
+#define SH_DEBUG_PORT_MASK                       0x00000000ffffffff
+#define SH_DEBUG_PORT_INIT                       0x0000000000000000
+
+/*   SH_DEBUG_PORT_DEBUG_NIBBLE0                                        */
+/*   Description:  Debug port nibble 0                                  */
+#define SH_DEBUG_PORT_DEBUG_NIBBLE0_SHFT         0
+#define SH_DEBUG_PORT_DEBUG_NIBBLE0_MASK         0x000000000000000f
+
+/*   SH_DEBUG_PORT_DEBUG_NIBBLE1                                        */
+/*   Description:  Debug port nibble 1                                  */
+#define SH_DEBUG_PORT_DEBUG_NIBBLE1_SHFT         4
+#define SH_DEBUG_PORT_DEBUG_NIBBLE1_MASK         0x00000000000000f0
+
+/*   SH_DEBUG_PORT_DEBUG_NIBBLE2                                        */
+/*   Description:  Debug port nibble 2                                  */
+#define SH_DEBUG_PORT_DEBUG_NIBBLE2_SHFT         8
+#define SH_DEBUG_PORT_DEBUG_NIBBLE2_MASK         0x0000000000000f00
+
+/*   SH_DEBUG_PORT_DEBUG_NIBBLE3                                        */
+/*   Description:  Debug port nibble 3                                  */
+#define SH_DEBUG_PORT_DEBUG_NIBBLE3_SHFT         12
+#define SH_DEBUG_PORT_DEBUG_NIBBLE3_MASK         0x000000000000f000
+
+/*   SH_DEBUG_PORT_DEBUG_NIBBLE4                                        */
+/*   Description:  Debug port nibble 4                                  */
+#define SH_DEBUG_PORT_DEBUG_NIBBLE4_SHFT         16
+#define SH_DEBUG_PORT_DEBUG_NIBBLE4_MASK         0x00000000000f0000
+
+/*   SH_DEBUG_PORT_DEBUG_NIBBLE5                                        */
+/*   Description:  Debug port nibble 5                                  */
+#define SH_DEBUG_PORT_DEBUG_NIBBLE5_SHFT         20
+#define SH_DEBUG_PORT_DEBUG_NIBBLE5_MASK         0x0000000000f00000
+
+/*   SH_DEBUG_PORT_DEBUG_NIBBLE6                                        */
+/*   Description:  Debug port nibble 6                                  */
+#define SH_DEBUG_PORT_DEBUG_NIBBLE6_SHFT         24
+#define SH_DEBUG_PORT_DEBUG_NIBBLE6_MASK         0x000000000f000000
+
+/*   SH_DEBUG_PORT_DEBUG_NIBBLE7                                        */
+/*   Description:  Debug port nibble 7                                  */
+#define SH_DEBUG_PORT_DEBUG_NIBBLE7_SHFT         28
+#define SH_DEBUG_PORT_DEBUG_NIBBLE7_MASK         0x00000000f0000000
+
+/* ==================================================================== */
+/*                     Register "SH_II_DEBUG_DATA"                      */
+/*                            II Debug Data                             */
+/* ==================================================================== */
+
+#define SH_II_DEBUG_DATA                         0x0000000110072080
+#define SH_II_DEBUG_DATA_MASK                    0x00000000ffffffff
+#define SH_II_DEBUG_DATA_INIT                    0x0000000000000000
+
+/*   SH_II_DEBUG_DATA_II_DATA                                           */
+/*   Description:  II debug data                                        */
+#define SH_II_DEBUG_DATA_II_DATA_SHFT            0
+#define SH_II_DEBUG_DATA_II_DATA_MASK            0x00000000ffffffff
+
+/* ==================================================================== */
+/*                   Register "SH_II_WRAP_DEBUG_DATA"                   */
+/*                      SHub II Wrapper Debug Data                      */
+/* ==================================================================== */
+
+#define SH_II_WRAP_DEBUG_DATA                    0x0000000110072100
+#define SH_II_WRAP_DEBUG_DATA_MASK               0x00000000ffffffff
+#define SH_II_WRAP_DEBUG_DATA_INIT               0x0000000000000000
+
+/*   SH_II_WRAP_DEBUG_DATA_II_WRAP_DATA                                 */
+/*   Description:  II wrapper debug data                                */
+#define SH_II_WRAP_DEBUG_DATA_II_WRAP_DATA_SHFT  0
+#define SH_II_WRAP_DEBUG_DATA_II_WRAP_DATA_MASK  0x00000000ffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_LB_DEBUG_DATA"                      */
+/*                          SHub LB Debug Data                          */
+/* ==================================================================== */
+
+#define SH_LB_DEBUG_DATA                         0x0000000110072180
+#define SH_LB_DEBUG_DATA_MASK                    0x00000000ffffffff
+#define SH_LB_DEBUG_DATA_INIT                    0x0000000000000000
+
+/*   SH_LB_DEBUG_DATA_LB_DATA                                           */
+/*   Description:  LB debug data                                        */
+#define SH_LB_DEBUG_DATA_LB_DATA_SHFT            0
+#define SH_LB_DEBUG_DATA_LB_DATA_MASK            0x00000000ffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_MD_DEBUG_DATA"                      */
+/*                          SHub MD Debug Data                          */
+/* ==================================================================== */
+
+#define SH_MD_DEBUG_DATA                         0x0000000110072200
+#define SH_MD_DEBUG_DATA_MASK                    0x00000000ffffffff
+#define SH_MD_DEBUG_DATA_INIT                    0x0000000000000000
+
+/*   SH_MD_DEBUG_DATA_MD_DATA                                           */
+/*   Description:  MD debug data                                        */
+#define SH_MD_DEBUG_DATA_MD_DATA_SHFT            0
+#define SH_MD_DEBUG_DATA_MD_DATA_MASK            0x00000000ffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_PI_DEBUG_DATA"                      */
+/*                          SHub PI Debug Data                          */
+/* ==================================================================== */
+
+#define SH_PI_DEBUG_DATA                         0x0000000110072280
+#define SH_PI_DEBUG_DATA_MASK                    0x00000000ffffffff
+#define SH_PI_DEBUG_DATA_INIT                    0x0000000000000000
+
+/*   SH_PI_DEBUG_DATA_PI_DATA                                           */
+/*   Description:  PI Debug Data                                        */
+#define SH_PI_DEBUG_DATA_PI_DATA_SHFT            0
+#define SH_PI_DEBUG_DATA_PI_DATA_MASK            0x00000000ffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_XN_DEBUG_DATA"                      */
+/*                          SHub XN Debug Data                          */
+/* ==================================================================== */
+
+#define SH_XN_DEBUG_DATA                         0x0000000110072300
+#define SH_XN_DEBUG_DATA_MASK                    0x00000000ffffffff
+#define SH_XN_DEBUG_DATA_INIT                    0x0000000000000000
+
+/*   SH_XN_DEBUG_DATA_XN_DATA                                           */
+/*   Description:  XN debug data                                        */
+#define SH_XN_DEBUG_DATA_XN_DATA_SHFT            0
+#define SH_XN_DEBUG_DATA_XN_DATA_MASK            0x00000000ffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_ARMED_STATE"                     */
+/*                Trigger sequencing facility arm state                 */
+/* ==================================================================== */
+
+#define SH_TSF_ARMED_STATE                       0x0000000110073000
+#define SH_TSF_ARMED_STATE_MASK                  0x00000000000000ff
+#define SH_TSF_ARMED_STATE_INIT                  0x0000000000000000
+
+/*   SH_TSF_ARMED_STATE_STATE                                           */
+/*   Description:  Trigger sequencing facility armed state              */
+#define SH_TSF_ARMED_STATE_STATE_SHFT            0
+#define SH_TSF_ARMED_STATE_STATE_MASK            0x00000000000000ff
+
+/* ==================================================================== */
+/*                   Register "SH_TSF_COUNTER_VALUE"                    */
+/*              Trigger sequencing facility counter value               */
+/* ==================================================================== */
+
+#define SH_TSF_COUNTER_VALUE                     0x0000000110073080
+#define SH_TSF_COUNTER_VALUE_MASK                0xffffffffffffffff
+#define SH_TSF_COUNTER_VALUE_INIT                0x0000000000000000
+
+/*   SH_TSF_COUNTER_VALUE_COUNT_32                                      */
+/*   Description:  Trigger sequencing facility counter 32               */
+#define SH_TSF_COUNTER_VALUE_COUNT_32_SHFT       0
+#define SH_TSF_COUNTER_VALUE_COUNT_32_MASK       0x00000000ffffffff
+
+/*   SH_TSF_COUNTER_VALUE_COUNT_16                                      */
+/*   Description:  Trigger sequencing facility counter 16               */
+#define SH_TSF_COUNTER_VALUE_COUNT_16_SHFT       32
+#define SH_TSF_COUNTER_VALUE_COUNT_16_MASK       0x0000ffff00000000
+
+/*   SH_TSF_COUNTER_VALUE_COUNT_8B                                      */
+/*   Description:  Trigger sequencing facility counter 8b               */
+#define SH_TSF_COUNTER_VALUE_COUNT_8B_SHFT       48
+#define SH_TSF_COUNTER_VALUE_COUNT_8B_MASK       0x00ff000000000000
+
+/*   SH_TSF_COUNTER_VALUE_COUNT_8A                                      */
+/*   Description:  Trigger sequencing facility counter 8a               */
+#define SH_TSF_COUNTER_VALUE_COUNT_8A_SHFT       56
+#define SH_TSF_COUNTER_VALUE_COUNT_8A_MASK       0xff00000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_TSF_TRIGGERED_STATE"                   */
+/*             Trigger sequencing facility triggered state              */
+/* ==================================================================== */
+
+#define SH_TSF_TRIGGERED_STATE                   0x0000000110073100
+#define SH_TSF_TRIGGERED_STATE_MASK              0x00000000000000ff
+#define SH_TSF_TRIGGERED_STATE_INIT              0x0000000000000000
+
+/*   SH_TSF_TRIGGERED_STATE_STATE                                       */
+/*   Description:  Trigger sequencing facility triggered state          */
+#define SH_TSF_TRIGGERED_STATE_STATE_SHFT        0
+#define SH_TSF_TRIGGERED_STATE_STATE_MASK        0x00000000000000ff
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_RDDATA"                       */
+/*                      Vector Reply Message Data                       */
+/* ==================================================================== */
+
+#define SH_VEC_RDDATA                            0x0000000110074000
+#define SH_VEC_RDDATA_MASK                       0xffffffffffffffff
+#define SH_VEC_RDDATA_INIT                       0x0000000000000000
+
+/*   SH_VEC_RDDATA_DATA                                                 */
+/*   Description:  Data                                                 */
+#define SH_VEC_RDDATA_DATA_SHFT                  0
+#define SH_VEC_RDDATA_DATA_MASK                  0xffffffffffffffff
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_RETURN"                       */
+/*                  Vector Reply Message Return Route                   */
+/* ==================================================================== */
+
+#define SH_VEC_RETURN                            0x0000000110074080
+#define SH_VEC_RETURN_MASK                       0xffffffffffffffff
+#define SH_VEC_RETURN_INIT                       0x0000000000000000
+
+/*   SH_VEC_RETURN_ROUTE                                                */
+/*   Description:  Route                                                */
+#define SH_VEC_RETURN_ROUTE_SHFT                 0
+#define SH_VEC_RETURN_ROUTE_MASK                 0xffffffffffffffff
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_STATUS"                       */
+/*                     Vector Reply Message Status                      */
+/* ==================================================================== */
+
+#define SH_VEC_STATUS                            0x0000000110074100
+#define SH_VEC_STATUS_MASK                       0xcfffffffffffffff
+#define SH_VEC_STATUS_INIT                       0x0000000000000000
+
+/*   SH_VEC_STATUS_TYPE                                                 */
+/*   Description:  Type                                                 */
+#define SH_VEC_STATUS_TYPE_SHFT                  0
+#define SH_VEC_STATUS_TYPE_MASK                  0x0000000000000007
+
+/*   SH_VEC_STATUS_ADDRESS                                              */
+/*   Description:  Address                                              */
+#define SH_VEC_STATUS_ADDRESS_SHFT               3
+#define SH_VEC_STATUS_ADDRESS_MASK               0x00000007fffffff8
+
+/*   SH_VEC_STATUS_PIO_ID                                               */
+/*   Description:  PIO ID                                               */
+#define SH_VEC_STATUS_PIO_ID_SHFT                35
+#define SH_VEC_STATUS_PIO_ID_MASK                0x00003ff800000000
+
+/*   SH_VEC_STATUS_SOURCE                                               */
+/*   Description:  Source                                               */
+#define SH_VEC_STATUS_SOURCE_SHFT                46
+#define SH_VEC_STATUS_SOURCE_MASK                0x0fffc00000000000
+
+/*   SH_VEC_STATUS_OVERRUN                                              */
+/*   Description:  Overrun                                              */
+#define SH_VEC_STATUS_OVERRUN_SHFT               62
+#define SH_VEC_STATUS_OVERRUN_MASK               0x4000000000000000
+
+/*   SH_VEC_STATUS_STATUS_VALID                                         */
+/*   Description:  Status_Valid                                         */
+#define SH_VEC_STATUS_STATUS_VALID_SHFT          63
+#define SH_VEC_STATUS_STATUS_VALID_MASK          0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_VEC_STATUS_ALIAS"                    */
+/*                  Vector Reply Message Status Alias                   */
+/* ==================================================================== */
+
+#define SH_VEC_STATUS_ALIAS                      0x0000000110074108
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT0_CONTROL"               */
+/*                    Performance Counter 0 Control                     */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNT0_CONTROL            0x0000000110080000
+#define SH_PERFORMANCE_COUNT0_CONTROL_MASK       0x000000000007ffff
+#define SH_PERFORMANCE_COUNT0_CONTROL_INIT       0x000000000000b8b8
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_UP_STIMULUS                          */
+/*   Description:  Counter 0 up stimulus                                */
+#define SH_PERFORMANCE_COUNT0_CONTROL_UP_STIMULUS_SHFT 0
+#define SH_PERFORMANCE_COUNT0_CONTROL_UP_STIMULUS_MASK 0x000000000000001f
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_UP_EVENT                             */
+/*   Description:  Counter 0 up event select (1-greater than, 0-equal)  */
+#define SH_PERFORMANCE_COUNT0_CONTROL_UP_EVENT_SHFT 5
+#define SH_PERFORMANCE_COUNT0_CONTROL_UP_EVENT_MASK 0x0000000000000020
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_UP_POLARITY                          */
+/*   Description:  Counter 0 up polarity select (1-negative edge, 0-po  */
+/*  sitive edge)                                                        */
+#define SH_PERFORMANCE_COUNT0_CONTROL_UP_POLARITY_SHFT 6
+#define SH_PERFORMANCE_COUNT0_CONTROL_UP_POLARITY_MASK 0x0000000000000040
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_UP_MODE                              */
+/*   Description:  Counter 0 up mode select (1-internal, 0-external)    */
+#define SH_PERFORMANCE_COUNT0_CONTROL_UP_MODE_SHFT 7
+#define SH_PERFORMANCE_COUNT0_CONTROL_UP_MODE_MASK 0x0000000000000080
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_DN_STIMULUS                          */
+/*   Description:  Counter 0 down stimulus                              */
+#define SH_PERFORMANCE_COUNT0_CONTROL_DN_STIMULUS_SHFT 8
+#define SH_PERFORMANCE_COUNT0_CONTROL_DN_STIMULUS_MASK 0x0000000000001f00
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_DN_EVENT                             */
+/*   Description:  Counter 0 down event select (1-greater than, 0-equa  */
+#define SH_PERFORMANCE_COUNT0_CONTROL_DN_EVENT_SHFT 13
+#define SH_PERFORMANCE_COUNT0_CONTROL_DN_EVENT_MASK 0x0000000000002000
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_DN_POLARITY                          */
+/*   Description:  Counter 0 down polarity select (1-negative edge, 0-  */
+/*  positive edge)                                                      */
+#define SH_PERFORMANCE_COUNT0_CONTROL_DN_POLARITY_SHFT 14
+#define SH_PERFORMANCE_COUNT0_CONTROL_DN_POLARITY_MASK 0x0000000000004000
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_DN_MODE                              */
+/*   Description:  Counter 0 down mode select (1-internal, 0-external)  */
+#define SH_PERFORMANCE_COUNT0_CONTROL_DN_MODE_SHFT 15
+#define SH_PERFORMANCE_COUNT0_CONTROL_DN_MODE_MASK 0x0000000000008000
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_INC_ENABLE                           */
+/*   Description:  Counter 0 enable increment                           */
+#define SH_PERFORMANCE_COUNT0_CONTROL_INC_ENABLE_SHFT 16
+#define SH_PERFORMANCE_COUNT0_CONTROL_INC_ENABLE_MASK 0x0000000000010000
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_DEC_ENABLE                           */
+/*   Description:  Counter 0 enable decrement                           */
+#define SH_PERFORMANCE_COUNT0_CONTROL_DEC_ENABLE_SHFT 17
+#define SH_PERFORMANCE_COUNT0_CONTROL_DEC_ENABLE_MASK 0x0000000000020000
+
+/*   SH_PERFORMANCE_COUNT0_CONTROL_PEAK_DET_ENABLE                      */
+/*   Description:  Counter 0 enable peak detection                      */
+#define SH_PERFORMANCE_COUNT0_CONTROL_PEAK_DET_ENABLE_SHFT 18
+#define SH_PERFORMANCE_COUNT0_CONTROL_PEAK_DET_ENABLE_MASK 0x0000000000040000
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT1_CONTROL"               */
+/*                    Performance Counter 1 Control                     */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNT1_CONTROL            0x0000000110090000
+#define SH_PERFORMANCE_COUNT1_CONTROL_MASK       0x000000000007ffff
+#define SH_PERFORMANCE_COUNT1_CONTROL_INIT       0x000000000000b8b8
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_UP_STIMULUS                          */
+/*   Description:  Counter 1 up stimulus                                */
+#define SH_PERFORMANCE_COUNT1_CONTROL_UP_STIMULUS_SHFT 0
+#define SH_PERFORMANCE_COUNT1_CONTROL_UP_STIMULUS_MASK 0x000000000000001f
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_UP_EVENT                             */
+/*   Description:  Counter 1 up event select (1-greater than, 0-equal)  */
+#define SH_PERFORMANCE_COUNT1_CONTROL_UP_EVENT_SHFT 5
+#define SH_PERFORMANCE_COUNT1_CONTROL_UP_EVENT_MASK 0x0000000000000020
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_UP_POLARITY                          */
+/*   Description:  Counter 1 up polarity select (1-negative edge, 0-po  */
+/*  sitive edge)                                                        */
+#define SH_PERFORMANCE_COUNT1_CONTROL_UP_POLARITY_SHFT 6
+#define SH_PERFORMANCE_COUNT1_CONTROL_UP_POLARITY_MASK 0x0000000000000040
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_UP_MODE                              */
+/*   Description:  Counter 1 up mode select (1-internal, 0-external)    */
+#define SH_PERFORMANCE_COUNT1_CONTROL_UP_MODE_SHFT 7
+#define SH_PERFORMANCE_COUNT1_CONTROL_UP_MODE_MASK 0x0000000000000080
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_DN_STIMULUS                          */
+/*   Description:  Counter 1 down stimulus                              */
+#define SH_PERFORMANCE_COUNT1_CONTROL_DN_STIMULUS_SHFT 8
+#define SH_PERFORMANCE_COUNT1_CONTROL_DN_STIMULUS_MASK 0x0000000000001f00
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_DN_EVENT                             */
+/*   Description:  Counter 1 down event select (1-greater than, 0-equa  */
+#define SH_PERFORMANCE_COUNT1_CONTROL_DN_EVENT_SHFT 13
+#define SH_PERFORMANCE_COUNT1_CONTROL_DN_EVENT_MASK 0x0000000000002000
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_DN_POLARITY                          */
+/*   Description:  Counter 1 down polarity select (1-negative edge, 0-  */
+/*  positive edge)                                                      */
+#define SH_PERFORMANCE_COUNT1_CONTROL_DN_POLARITY_SHFT 14
+#define SH_PERFORMANCE_COUNT1_CONTROL_DN_POLARITY_MASK 0x0000000000004000
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_DN_MODE                              */
+/*   Description:  Counter 1 down mode select (1-internal, 0-external)  */
+#define SH_PERFORMANCE_COUNT1_CONTROL_DN_MODE_SHFT 15
+#define SH_PERFORMANCE_COUNT1_CONTROL_DN_MODE_MASK 0x0000000000008000
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_INC_ENABLE                           */
+/*   Description:  Counter 1 enable increment                           */
+#define SH_PERFORMANCE_COUNT1_CONTROL_INC_ENABLE_SHFT 16
+#define SH_PERFORMANCE_COUNT1_CONTROL_INC_ENABLE_MASK 0x0000000000010000
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_DEC_ENABLE                           */
+/*   Description:  Counter 1 enable decrement                           */
+#define SH_PERFORMANCE_COUNT1_CONTROL_DEC_ENABLE_SHFT 17
+#define SH_PERFORMANCE_COUNT1_CONTROL_DEC_ENABLE_MASK 0x0000000000020000
+
+/*   SH_PERFORMANCE_COUNT1_CONTROL_PEAK_DET_ENABLE                      */
+/*   Description:  Counter 1 enable peak detection                      */
+#define SH_PERFORMANCE_COUNT1_CONTROL_PEAK_DET_ENABLE_SHFT 18
+#define SH_PERFORMANCE_COUNT1_CONTROL_PEAK_DET_ENABLE_MASK 0x0000000000040000
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT2_CONTROL"               */
+/*                    Performance Counter 2 Control                     */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNT2_CONTROL            0x00000001100a0000
+#define SH_PERFORMANCE_COUNT2_CONTROL_MASK       0x000000000007ffff
+#define SH_PERFORMANCE_COUNT2_CONTROL_INIT       0x000000000000b8b8
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_UP_STIMULUS                          */
+/*   Description:  Counter 2 up stimulus                                */
+#define SH_PERFORMANCE_COUNT2_CONTROL_UP_STIMULUS_SHFT 0
+#define SH_PERFORMANCE_COUNT2_CONTROL_UP_STIMULUS_MASK 0x000000000000001f
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_UP_EVENT                             */
+/*   Description:  Counter 2 up event select (1-greater than, 0-equal)  */
+#define SH_PERFORMANCE_COUNT2_CONTROL_UP_EVENT_SHFT 5
+#define SH_PERFORMANCE_COUNT2_CONTROL_UP_EVENT_MASK 0x0000000000000020
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_UP_POLARITY                          */
+/*   Description:  Counter 2 up polarity select (1-negative edge, 0-po  */
+/*  sitive edge)                                                        */
+#define SH_PERFORMANCE_COUNT2_CONTROL_UP_POLARITY_SHFT 6
+#define SH_PERFORMANCE_COUNT2_CONTROL_UP_POLARITY_MASK 0x0000000000000040
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_UP_MODE                              */
+/*   Description:  Counter 2 up mode select (1-internal, 0-external)    */
+#define SH_PERFORMANCE_COUNT2_CONTROL_UP_MODE_SHFT 7
+#define SH_PERFORMANCE_COUNT2_CONTROL_UP_MODE_MASK 0x0000000000000080
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_DN_STIMULUS                          */
+/*   Description:  Counter 2 down stimulus                              */
+#define SH_PERFORMANCE_COUNT2_CONTROL_DN_STIMULUS_SHFT 8
+#define SH_PERFORMANCE_COUNT2_CONTROL_DN_STIMULUS_MASK 0x0000000000001f00
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_DN_EVENT                             */
+/*   Description:  Counter 2 down event select (1-greater than, 0-equa  */
+#define SH_PERFORMANCE_COUNT2_CONTROL_DN_EVENT_SHFT 13
+#define SH_PERFORMANCE_COUNT2_CONTROL_DN_EVENT_MASK 0x0000000000002000
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_DN_POLARITY                          */
+/*   Description:  Counter 2 down polarity select (1-negative edge, 0-  */
+/*  positive edge)                                                      */
+#define SH_PERFORMANCE_COUNT2_CONTROL_DN_POLARITY_SHFT 14
+#define SH_PERFORMANCE_COUNT2_CONTROL_DN_POLARITY_MASK 0x0000000000004000
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_DN_MODE                              */
+/*   Description:  Counter 2 down mode select (1-internal, 0-external)  */
+#define SH_PERFORMANCE_COUNT2_CONTROL_DN_MODE_SHFT 15
+#define SH_PERFORMANCE_COUNT2_CONTROL_DN_MODE_MASK 0x0000000000008000
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_INC_ENABLE                           */
+/*   Description:  Counter 2 enable increment                           */
+#define SH_PERFORMANCE_COUNT2_CONTROL_INC_ENABLE_SHFT 16
+#define SH_PERFORMANCE_COUNT2_CONTROL_INC_ENABLE_MASK 0x0000000000010000
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_DEC_ENABLE                           */
+/*   Description:  Counter 2 enable decrement                           */
+#define SH_PERFORMANCE_COUNT2_CONTROL_DEC_ENABLE_SHFT 17
+#define SH_PERFORMANCE_COUNT2_CONTROL_DEC_ENABLE_MASK 0x0000000000020000
+
+/*   SH_PERFORMANCE_COUNT2_CONTROL_PEAK_DET_ENABLE                      */
+/*   Description:  Counter 2 enable peak detection                      */
+#define SH_PERFORMANCE_COUNT2_CONTROL_PEAK_DET_ENABLE_SHFT 18
+#define SH_PERFORMANCE_COUNT2_CONTROL_PEAK_DET_ENABLE_MASK 0x0000000000040000
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT3_CONTROL"               */
+/*                    Performance Counter 3 Control                     */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNT3_CONTROL            0x00000001100b0000
+#define SH_PERFORMANCE_COUNT3_CONTROL_MASK       0x000000000007ffff
+#define SH_PERFORMANCE_COUNT3_CONTROL_INIT       0x000000000000b8b8
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_UP_STIMULUS                          */
+/*   Description:  Counter 3 up stimulus                                */
+#define SH_PERFORMANCE_COUNT3_CONTROL_UP_STIMULUS_SHFT 0
+#define SH_PERFORMANCE_COUNT3_CONTROL_UP_STIMULUS_MASK 0x000000000000001f
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_UP_EVENT                             */
+/*   Description:  Counter 3 up event select (1-greater than, 0-equal)  */
+#define SH_PERFORMANCE_COUNT3_CONTROL_UP_EVENT_SHFT 5
+#define SH_PERFORMANCE_COUNT3_CONTROL_UP_EVENT_MASK 0x0000000000000020
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_UP_POLARITY                          */
+/*   Description:  Counter 3 up polarity select (1-negative edge, 0-po  */
+/*  sitive edge)                                                        */
+#define SH_PERFORMANCE_COUNT3_CONTROL_UP_POLARITY_SHFT 6
+#define SH_PERFORMANCE_COUNT3_CONTROL_UP_POLARITY_MASK 0x0000000000000040
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_UP_MODE                              */
+/*   Description:  Counter 3 up mode select (1-internal, 0-external)    */
+#define SH_PERFORMANCE_COUNT3_CONTROL_UP_MODE_SHFT 7
+#define SH_PERFORMANCE_COUNT3_CONTROL_UP_MODE_MASK 0x0000000000000080
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_DN_STIMULUS                          */
+/*   Description:  Counter 3 down stimulus                              */
+#define SH_PERFORMANCE_COUNT3_CONTROL_DN_STIMULUS_SHFT 8
+#define SH_PERFORMANCE_COUNT3_CONTROL_DN_STIMULUS_MASK 0x0000000000001f00
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_DN_EVENT                             */
+/*   Description:  Counter 3 down event select (1-greater than, 0-equa  */
+#define SH_PERFORMANCE_COUNT3_CONTROL_DN_EVENT_SHFT 13
+#define SH_PERFORMANCE_COUNT3_CONTROL_DN_EVENT_MASK 0x0000000000002000
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_DN_POLARITY                          */
+/*   Description:  Counter 3 down polarity select (1-negative edge, 0-  */
+/*  positive edge)                                                      */
+#define SH_PERFORMANCE_COUNT3_CONTROL_DN_POLARITY_SHFT 14
+#define SH_PERFORMANCE_COUNT3_CONTROL_DN_POLARITY_MASK 0x0000000000004000
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_DN_MODE                              */
+/*   Description:  Counter 3 down mode select (1-internal, 0-external)  */
+#define SH_PERFORMANCE_COUNT3_CONTROL_DN_MODE_SHFT 15
+#define SH_PERFORMANCE_COUNT3_CONTROL_DN_MODE_MASK 0x0000000000008000
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_INC_ENABLE                           */
+/*   Description:  Counter 3 enable increment                           */
+#define SH_PERFORMANCE_COUNT3_CONTROL_INC_ENABLE_SHFT 16
+#define SH_PERFORMANCE_COUNT3_CONTROL_INC_ENABLE_MASK 0x0000000000010000
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_DEC_ENABLE                           */
+/*   Description:  Counter 3 enable decrement                           */
+#define SH_PERFORMANCE_COUNT3_CONTROL_DEC_ENABLE_SHFT 17
+#define SH_PERFORMANCE_COUNT3_CONTROL_DEC_ENABLE_MASK 0x0000000000020000
+
+/*   SH_PERFORMANCE_COUNT3_CONTROL_PEAK_DET_ENABLE                      */
+/*   Description:  Counter 3 enable peak detection                      */
+#define SH_PERFORMANCE_COUNT3_CONTROL_PEAK_DET_ENABLE_SHFT 18
+#define SH_PERFORMANCE_COUNT3_CONTROL_PEAK_DET_ENABLE_MASK 0x0000000000040000
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT4_CONTROL"               */
+/*                    Performance Counter 4 Control                     */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNT4_CONTROL            0x00000001100c0000
+#define SH_PERFORMANCE_COUNT4_CONTROL_MASK       0x000000000007ffff
+#define SH_PERFORMANCE_COUNT4_CONTROL_INIT       0x000000000000b8b8
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_UP_STIMULUS                          */
+/*   Description:  Counter 4 up stimulus                                */
+#define SH_PERFORMANCE_COUNT4_CONTROL_UP_STIMULUS_SHFT 0
+#define SH_PERFORMANCE_COUNT4_CONTROL_UP_STIMULUS_MASK 0x000000000000001f
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_UP_EVENT                             */
+/*   Description:  Counter 4 up event select (1-greater than, 0-equal)  */
+#define SH_PERFORMANCE_COUNT4_CONTROL_UP_EVENT_SHFT 5
+#define SH_PERFORMANCE_COUNT4_CONTROL_UP_EVENT_MASK 0x0000000000000020
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_UP_POLARITY                          */
+/*   Description:  Counter 4 up polarity select (1-negative edge, 0-po  */
+/*  sitive edge)                                                        */
+#define SH_PERFORMANCE_COUNT4_CONTROL_UP_POLARITY_SHFT 6
+#define SH_PERFORMANCE_COUNT4_CONTROL_UP_POLARITY_MASK 0x0000000000000040
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_UP_MODE                              */
+/*   Description:  Counter 4 up mode select (1-internal, 0-external)    */
+#define SH_PERFORMANCE_COUNT4_CONTROL_UP_MODE_SHFT 7
+#define SH_PERFORMANCE_COUNT4_CONTROL_UP_MODE_MASK 0x0000000000000080
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_DN_STIMULUS                          */
+/*   Description:  Counter 4 down stimulus                              */
+#define SH_PERFORMANCE_COUNT4_CONTROL_DN_STIMULUS_SHFT 8
+#define SH_PERFORMANCE_COUNT4_CONTROL_DN_STIMULUS_MASK 0x0000000000001f00
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_DN_EVENT                             */
+/*   Description:  Counter 4 down event select (1-greater than, 0-equa  */
+#define SH_PERFORMANCE_COUNT4_CONTROL_DN_EVENT_SHFT 13
+#define SH_PERFORMANCE_COUNT4_CONTROL_DN_EVENT_MASK 0x0000000000002000
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_DN_POLARITY                          */
+/*   Description:  Counter 4 down polarity select (1-negative edge, 0-  */
+/*  positive edge)                                                      */
+#define SH_PERFORMANCE_COUNT4_CONTROL_DN_POLARITY_SHFT 14
+#define SH_PERFORMANCE_COUNT4_CONTROL_DN_POLARITY_MASK 0x0000000000004000
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_DN_MODE                              */
+/*   Description:  Counter 4 down mode select (1-internal, 0-external)  */
+#define SH_PERFORMANCE_COUNT4_CONTROL_DN_MODE_SHFT 15
+#define SH_PERFORMANCE_COUNT4_CONTROL_DN_MODE_MASK 0x0000000000008000
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_INC_ENABLE                           */
+/*   Description:  Counter 4 enable increment                           */
+#define SH_PERFORMANCE_COUNT4_CONTROL_INC_ENABLE_SHFT 16
+#define SH_PERFORMANCE_COUNT4_CONTROL_INC_ENABLE_MASK 0x0000000000010000
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_DEC_ENABLE                           */
+/*   Description:  Counter 4 enable decrement                           */
+#define SH_PERFORMANCE_COUNT4_CONTROL_DEC_ENABLE_SHFT 17
+#define SH_PERFORMANCE_COUNT4_CONTROL_DEC_ENABLE_MASK 0x0000000000020000
+
+/*   SH_PERFORMANCE_COUNT4_CONTROL_PEAK_DET_ENABLE                      */
+/*   Description:  Counter 4 enable peak detection                      */
+#define SH_PERFORMANCE_COUNT4_CONTROL_PEAK_DET_ENABLE_SHFT 18
+#define SH_PERFORMANCE_COUNT4_CONTROL_PEAK_DET_ENABLE_MASK 0x0000000000040000
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT5_CONTROL"               */
+/*                    Performance Counter 5 Control                     */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNT5_CONTROL            0x00000001100d0000
+#define SH_PERFORMANCE_COUNT5_CONTROL_MASK       0x000000000007ffff
+#define SH_PERFORMANCE_COUNT5_CONTROL_INIT       0x000000000000b8b8
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_UP_STIMULUS                          */
+/*   Description:  Counter 5 up stimulus                                */
+#define SH_PERFORMANCE_COUNT5_CONTROL_UP_STIMULUS_SHFT 0
+#define SH_PERFORMANCE_COUNT5_CONTROL_UP_STIMULUS_MASK 0x000000000000001f
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_UP_EVENT                             */
+/*   Description:  Counter 5 up event select (1-greater than, 0-equal)  */
+#define SH_PERFORMANCE_COUNT5_CONTROL_UP_EVENT_SHFT 5
+#define SH_PERFORMANCE_COUNT5_CONTROL_UP_EVENT_MASK 0x0000000000000020
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_UP_POLARITY                          */
+/*   Description:  Counter 5 up polarity select (1-negative edge, 0-po  */
+/*  sitive edge)                                                        */
+#define SH_PERFORMANCE_COUNT5_CONTROL_UP_POLARITY_SHFT 6
+#define SH_PERFORMANCE_COUNT5_CONTROL_UP_POLARITY_MASK 0x0000000000000040
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_UP_MODE                              */
+/*   Description:  Counter 5 up mode select (1-internal, 0-external)    */
+#define SH_PERFORMANCE_COUNT5_CONTROL_UP_MODE_SHFT 7
+#define SH_PERFORMANCE_COUNT5_CONTROL_UP_MODE_MASK 0x0000000000000080
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_DN_STIMULUS                          */
+/*   Description:  Counter 5 down stimulus                              */
+#define SH_PERFORMANCE_COUNT5_CONTROL_DN_STIMULUS_SHFT 8
+#define SH_PERFORMANCE_COUNT5_CONTROL_DN_STIMULUS_MASK 0x0000000000001f00
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_DN_EVENT                             */
+/*   Description:  Counter 5 down event select (1-greater than, 0-equa  */
+#define SH_PERFORMANCE_COUNT5_CONTROL_DN_EVENT_SHFT 13
+#define SH_PERFORMANCE_COUNT5_CONTROL_DN_EVENT_MASK 0x0000000000002000
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_DN_POLARITY                          */
+/*   Description:  Counter 5 down polarity select (1-negative edge, 0-  */
+/*  positive edge)                                                      */
+#define SH_PERFORMANCE_COUNT5_CONTROL_DN_POLARITY_SHFT 14
+#define SH_PERFORMANCE_COUNT5_CONTROL_DN_POLARITY_MASK 0x0000000000004000
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_DN_MODE                              */
+/*   Description:  Counter 5 down mode select (1-internal, 0-external)  */
+#define SH_PERFORMANCE_COUNT5_CONTROL_DN_MODE_SHFT 15
+#define SH_PERFORMANCE_COUNT5_CONTROL_DN_MODE_MASK 0x0000000000008000
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_INC_ENABLE                           */
+/*   Description:  Counter 5 enable increment                           */
+#define SH_PERFORMANCE_COUNT5_CONTROL_INC_ENABLE_SHFT 16
+#define SH_PERFORMANCE_COUNT5_CONTROL_INC_ENABLE_MASK 0x0000000000010000
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_DEC_ENABLE                           */
+/*   Description:  Counter 5 enable decrement                           */
+#define SH_PERFORMANCE_COUNT5_CONTROL_DEC_ENABLE_SHFT 17
+#define SH_PERFORMANCE_COUNT5_CONTROL_DEC_ENABLE_MASK 0x0000000000020000
+
+/*   SH_PERFORMANCE_COUNT5_CONTROL_PEAK_DET_ENABLE                      */
+/*   Description:  Counter 5 enable peak detection                      */
+#define SH_PERFORMANCE_COUNT5_CONTROL_PEAK_DET_ENABLE_SHFT 18
+#define SH_PERFORMANCE_COUNT5_CONTROL_PEAK_DET_ENABLE_MASK 0x0000000000040000
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT6_CONTROL"               */
+/*                    Performance Counter 6 Control                     */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNT6_CONTROL            0x00000001100e0000
+#define SH_PERFORMANCE_COUNT6_CONTROL_MASK       0x000000000007ffff
+#define SH_PERFORMANCE_COUNT6_CONTROL_INIT       0x000000000000b8b8
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_UP_STIMULUS                          */
+/*   Description:  Counter 6 up stimulus                                */
+#define SH_PERFORMANCE_COUNT6_CONTROL_UP_STIMULUS_SHFT 0
+#define SH_PERFORMANCE_COUNT6_CONTROL_UP_STIMULUS_MASK 0x000000000000001f
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_UP_EVENT                             */
+/*   Description:  Counter 6 up event select (1-greater than, 0-equal)  */
+#define SH_PERFORMANCE_COUNT6_CONTROL_UP_EVENT_SHFT 5
+#define SH_PERFORMANCE_COUNT6_CONTROL_UP_EVENT_MASK 0x0000000000000020
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_UP_POLARITY                          */
+/*   Description:  Counter 6 up polarity select (1-negative edge, 0-po  */
+/*  sitive edge)                                                        */
+#define SH_PERFORMANCE_COUNT6_CONTROL_UP_POLARITY_SHFT 6
+#define SH_PERFORMANCE_COUNT6_CONTROL_UP_POLARITY_MASK 0x0000000000000040
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_UP_MODE                              */
+/*   Description:  Counter 6 up mode select (1-internal, 0-external)    */
+#define SH_PERFORMANCE_COUNT6_CONTROL_UP_MODE_SHFT 7
+#define SH_PERFORMANCE_COUNT6_CONTROL_UP_MODE_MASK 0x0000000000000080
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_DN_STIMULUS                          */
+/*   Description:  Counter 6 down stimulus                              */
+#define SH_PERFORMANCE_COUNT6_CONTROL_DN_STIMULUS_SHFT 8
+#define SH_PERFORMANCE_COUNT6_CONTROL_DN_STIMULUS_MASK 0x0000000000001f00
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_DN_EVENT                             */
+/*   Description:  Counter 6 down event select (1-greater than, 0-equa  */
+#define SH_PERFORMANCE_COUNT6_CONTROL_DN_EVENT_SHFT 13
+#define SH_PERFORMANCE_COUNT6_CONTROL_DN_EVENT_MASK 0x0000000000002000
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_DN_POLARITY                          */
+/*   Description:  Counter 6 down polarity select (1-negative edge, 0-  */
+/*  positive edge)                                                      */
+#define SH_PERFORMANCE_COUNT6_CONTROL_DN_POLARITY_SHFT 14
+#define SH_PERFORMANCE_COUNT6_CONTROL_DN_POLARITY_MASK 0x0000000000004000
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_DN_MODE                              */
+/*   Description:  Counter 6 down mode select (1-internal, 0-external)  */
+#define SH_PERFORMANCE_COUNT6_CONTROL_DN_MODE_SHFT 15
+#define SH_PERFORMANCE_COUNT6_CONTROL_DN_MODE_MASK 0x0000000000008000
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_INC_ENABLE                           */
+/*   Description:  Counter 6 enable increment                           */
+#define SH_PERFORMANCE_COUNT6_CONTROL_INC_ENABLE_SHFT 16
+#define SH_PERFORMANCE_COUNT6_CONTROL_INC_ENABLE_MASK 0x0000000000010000
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_DEC_ENABLE                           */
+/*   Description:  Counter 6 enable decrement                           */
+#define SH_PERFORMANCE_COUNT6_CONTROL_DEC_ENABLE_SHFT 17
+#define SH_PERFORMANCE_COUNT6_CONTROL_DEC_ENABLE_MASK 0x0000000000020000
+
+/*   SH_PERFORMANCE_COUNT6_CONTROL_PEAK_DET_ENABLE                      */
+/*   Description:  Counter 6 enable peak detection                      */
+#define SH_PERFORMANCE_COUNT6_CONTROL_PEAK_DET_ENABLE_SHFT 18
+#define SH_PERFORMANCE_COUNT6_CONTROL_PEAK_DET_ENABLE_MASK 0x0000000000040000
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT7_CONTROL"               */
+/*                    Performance Counter 7 Control                     */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNT7_CONTROL            0x00000001100f0000
+#define SH_PERFORMANCE_COUNT7_CONTROL_MASK       0x000000000007ffff
+#define SH_PERFORMANCE_COUNT7_CONTROL_INIT       0x000000000000b8b8
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_UP_STIMULUS                          */
+/*   Description:  Counter 7 up stimulus                                */
+#define SH_PERFORMANCE_COUNT7_CONTROL_UP_STIMULUS_SHFT 0
+#define SH_PERFORMANCE_COUNT7_CONTROL_UP_STIMULUS_MASK 0x000000000000001f
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_UP_EVENT                             */
+/*   Description:  Counter 7 up event select (1-greater than, 0-equal)  */
+#define SH_PERFORMANCE_COUNT7_CONTROL_UP_EVENT_SHFT 5
+#define SH_PERFORMANCE_COUNT7_CONTROL_UP_EVENT_MASK 0x0000000000000020
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_UP_POLARITY                          */
+/*   Description:  Counter 7 up polarity select (1-negative edge, 0-po  */
+/*  sitive edge)                                                        */
+#define SH_PERFORMANCE_COUNT7_CONTROL_UP_POLARITY_SHFT 6
+#define SH_PERFORMANCE_COUNT7_CONTROL_UP_POLARITY_MASK 0x0000000000000040
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_UP_MODE                              */
+/*   Description:  Counter 7 up mode select (1-internal, 0-external)    */
+#define SH_PERFORMANCE_COUNT7_CONTROL_UP_MODE_SHFT 7
+#define SH_PERFORMANCE_COUNT7_CONTROL_UP_MODE_MASK 0x0000000000000080
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_DN_STIMULUS                          */
+/*   Description:  Counter 7 down stimulus                              */
+#define SH_PERFORMANCE_COUNT7_CONTROL_DN_STIMULUS_SHFT 8
+#define SH_PERFORMANCE_COUNT7_CONTROL_DN_STIMULUS_MASK 0x0000000000001f00
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_DN_EVENT                             */
+/*   Description:  Counter 7 down event select (1-greater than, 0-equa  */
+#define SH_PERFORMANCE_COUNT7_CONTROL_DN_EVENT_SHFT 13
+#define SH_PERFORMANCE_COUNT7_CONTROL_DN_EVENT_MASK 0x0000000000002000
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_DN_POLARITY                          */
+/*   Description:  Counter 7 down polarity select (1-negative edge, 0-  */
+/*  positive edge)                                                      */
+#define SH_PERFORMANCE_COUNT7_CONTROL_DN_POLARITY_SHFT 14
+#define SH_PERFORMANCE_COUNT7_CONTROL_DN_POLARITY_MASK 0x0000000000004000
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_DN_MODE                              */
+/*   Description:  Counter 7 down mode select (1-internal, 0-external)  */
+#define SH_PERFORMANCE_COUNT7_CONTROL_DN_MODE_SHFT 15
+#define SH_PERFORMANCE_COUNT7_CONTROL_DN_MODE_MASK 0x0000000000008000
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_INC_ENABLE                           */
+/*   Description:  Counter 7 enable increment                           */
+#define SH_PERFORMANCE_COUNT7_CONTROL_INC_ENABLE_SHFT 16
+#define SH_PERFORMANCE_COUNT7_CONTROL_INC_ENABLE_MASK 0x0000000000010000
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_DEC_ENABLE                           */
+/*   Description:  Counter 7 enable decrement                           */
+#define SH_PERFORMANCE_COUNT7_CONTROL_DEC_ENABLE_SHFT 17
+#define SH_PERFORMANCE_COUNT7_CONTROL_DEC_ENABLE_MASK 0x0000000000020000
+
+/*   SH_PERFORMANCE_COUNT7_CONTROL_PEAK_DET_ENABLE                      */
+/*   Description:  Counter 7 enable peak detection                      */
+#define SH_PERFORMANCE_COUNT7_CONTROL_PEAK_DET_ENABLE_SHFT 18
+#define SH_PERFORMANCE_COUNT7_CONTROL_PEAK_DET_ENABLE_MASK 0x0000000000040000
+
+/* ==================================================================== */
+/*                   Register "SH_PROFILE_DN_CONTROL"                   */
+/*                     Profile Counter Down Control                     */
+/* ==================================================================== */
+
+#define SH_PROFILE_DN_CONTROL                    0x0000000110100000
+#define SH_PROFILE_DN_CONTROL_MASK               0x00000000000000ff
+#define SH_PROFILE_DN_CONTROL_INIT               0x00000000000000b8
+
+/*   SH_PROFILE_DN_CONTROL_STIMULUS                                     */
+/*   Description:  Counter stimulus                                     */
+#define SH_PROFILE_DN_CONTROL_STIMULUS_SHFT      0
+#define SH_PROFILE_DN_CONTROL_STIMULUS_MASK      0x000000000000001f
+
+/*   SH_PROFILE_DN_CONTROL_EVENT                                        */
+/*   Description:  Counter event select (1-greater than, 0-equal)       */
+#define SH_PROFILE_DN_CONTROL_EVENT_SHFT         5
+#define SH_PROFILE_DN_CONTROL_EVENT_MASK         0x0000000000000020
+
+/*   SH_PROFILE_DN_CONTROL_POLARITY                                     */
+/*   Description:  Counter polarity select (1-negative edge, 0-positiv  */
+/*  e edge)                                                             */
+#define SH_PROFILE_DN_CONTROL_POLARITY_SHFT      6
+#define SH_PROFILE_DN_CONTROL_POLARITY_MASK      0x0000000000000040
+
+/*   SH_PROFILE_DN_CONTROL_MODE                                         */
+/*   Description:  Counter mode select (1-internal, 0-external)         */
+#define SH_PROFILE_DN_CONTROL_MODE_SHFT          7
+#define SH_PROFILE_DN_CONTROL_MODE_MASK          0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_PROFILE_PEAK_CONTROL"                  */
+/*                     Profile Counter Peak Control                     */
+/* ==================================================================== */
+
+#define SH_PROFILE_PEAK_CONTROL                  0x0000000110100080
+#define SH_PROFILE_PEAK_CONTROL_MASK             0x0000000000000068
+#define SH_PROFILE_PEAK_CONTROL_INIT             0x0000000000000060
+
+/*   SH_PROFILE_PEAK_CONTROL_STIMULUS                                   */
+/*   Description:  Counter stimulus                                     */
+#define SH_PROFILE_PEAK_CONTROL_STIMULUS_SHFT    3
+#define SH_PROFILE_PEAK_CONTROL_STIMULUS_MASK    0x0000000000000008
+
+/*   SH_PROFILE_PEAK_CONTROL_EVENT                                      */
+/*   Description:  Counter event select (0-greater than, 1-equal)       */
+#define SH_PROFILE_PEAK_CONTROL_EVENT_SHFT       5
+#define SH_PROFILE_PEAK_CONTROL_EVENT_MASK       0x0000000000000020
+
+/*   SH_PROFILE_PEAK_CONTROL_POLARITY                                   */
+/*   Description:  Counter polarity select (0-negative edge, 1-positiv  */
+/*  e edge)                                                             */
+#define SH_PROFILE_PEAK_CONTROL_POLARITY_SHFT    6
+#define SH_PROFILE_PEAK_CONTROL_POLARITY_MASK    0x0000000000000040
+
+/* ==================================================================== */
+/*                     Register "SH_PROFILE_RANGE"                      */
+/*                        Profile Counter Range                         */
+/* ==================================================================== */
+
+#define SH_PROFILE_RANGE                         0x0000000110100100
+#define SH_PROFILE_RANGE_MASK                    0xffffffffffffffff
+#define SH_PROFILE_RANGE_INIT                    0x0000000000000000
+
+/*   SH_PROFILE_RANGE_RANGE0                                            */
+/*   Description:  Profiling range 0                                    */
+#define SH_PROFILE_RANGE_RANGE0_SHFT             0
+#define SH_PROFILE_RANGE_RANGE0_MASK             0x00000000000000ff
+
+/*   SH_PROFILE_RANGE_RANGE1                                            */
+/*   Description:  Profiling range 1                                    */
+#define SH_PROFILE_RANGE_RANGE1_SHFT             8
+#define SH_PROFILE_RANGE_RANGE1_MASK             0x000000000000ff00
+
+/*   SH_PROFILE_RANGE_RANGE2                                            */
+/*   Description:  Profiling range 2                                    */
+#define SH_PROFILE_RANGE_RANGE2_SHFT             16
+#define SH_PROFILE_RANGE_RANGE2_MASK             0x0000000000ff0000
+
+/*   SH_PROFILE_RANGE_RANGE3                                            */
+/*   Description:  Profiling range 3                                    */
+#define SH_PROFILE_RANGE_RANGE3_SHFT             24
+#define SH_PROFILE_RANGE_RANGE3_MASK             0x00000000ff000000
+
+/*   SH_PROFILE_RANGE_RANGE4                                            */
+/*   Description:  Profiling range 4                                    */
+#define SH_PROFILE_RANGE_RANGE4_SHFT             32
+#define SH_PROFILE_RANGE_RANGE4_MASK             0x000000ff00000000
+
+/*   SH_PROFILE_RANGE_RANGE5                                            */
+/*   Description:  Profiling range 5                                    */
+#define SH_PROFILE_RANGE_RANGE5_SHFT             40
+#define SH_PROFILE_RANGE_RANGE5_MASK             0x0000ff0000000000
+
+/*   SH_PROFILE_RANGE_RANGE6                                            */
+/*   Description:  Profiling range 6                                    */
+#define SH_PROFILE_RANGE_RANGE6_SHFT             48
+#define SH_PROFILE_RANGE_RANGE6_MASK             0x00ff000000000000
+
+/*   SH_PROFILE_RANGE_RANGE7                                            */
+/*   Description:  Profiling range 7                                    */
+#define SH_PROFILE_RANGE_RANGE7_SHFT             56
+#define SH_PROFILE_RANGE_RANGE7_MASK             0xff00000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_PROFILE_UP_CONTROL"                   */
+/*                      Profile Counter Up Control                      */
+/* ==================================================================== */
+
+#define SH_PROFILE_UP_CONTROL                    0x0000000110100180
+#define SH_PROFILE_UP_CONTROL_MASK               0x00000000000000ff
+#define SH_PROFILE_UP_CONTROL_INIT               0x00000000000000b8
+
+/*   SH_PROFILE_UP_CONTROL_STIMULUS                                     */
+/*   Description:  Counter stimulus                                     */
+#define SH_PROFILE_UP_CONTROL_STIMULUS_SHFT      0
+#define SH_PROFILE_UP_CONTROL_STIMULUS_MASK      0x000000000000001f
+
+/*   SH_PROFILE_UP_CONTROL_EVENT                                        */
+/*   Description:  Counter event select (1-greater than, 0-equal)       */
+#define SH_PROFILE_UP_CONTROL_EVENT_SHFT         5
+#define SH_PROFILE_UP_CONTROL_EVENT_MASK         0x0000000000000020
+
+/*   SH_PROFILE_UP_CONTROL_POLARITY                                     */
+/*   Description:  Counter polarity select (1-negative edge, 0-positiv  */
+/*  e edge)                                                             */
+#define SH_PROFILE_UP_CONTROL_POLARITY_SHFT      6
+#define SH_PROFILE_UP_CONTROL_POLARITY_MASK      0x0000000000000040
+
+/*   SH_PROFILE_UP_CONTROL_MODE                                         */
+/*   Description:  Counter mode select (1-internal, 0-external)         */
+#define SH_PROFILE_UP_CONTROL_MODE_SHFT          7
+#define SH_PROFILE_UP_CONTROL_MODE_MASK          0x0000000000000080
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER0"                  */
+/*                        Performance Counter 0                         */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNTER0                  0x0000000110110000
+#define SH_PERFORMANCE_COUNTER0_MASK             0x00000000ffffffff
+#define SH_PERFORMANCE_COUNTER0_INIT             0x0000000000000000
+
+/*   SH_PERFORMANCE_COUNTER0_COUNT                                      */
+/*   Description:  Counter 0                                            */
+#define SH_PERFORMANCE_COUNTER0_COUNT_SHFT       0
+#define SH_PERFORMANCE_COUNTER0_COUNT_MASK       0x00000000ffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER1"                  */
+/*                        Performance Counter 1                         */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNTER1                  0x0000000110120000
+#define SH_PERFORMANCE_COUNTER1_MASK             0x00000000ffffffff
+#define SH_PERFORMANCE_COUNTER1_INIT             0x0000000000000000
+
+/*   SH_PERFORMANCE_COUNTER1_COUNT                                      */
+/*   Description:  Counter 1                                            */
+#define SH_PERFORMANCE_COUNTER1_COUNT_SHFT       0
+#define SH_PERFORMANCE_COUNTER1_COUNT_MASK       0x00000000ffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER2"                  */
+/*                        Performance Counter 2                         */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNTER2                  0x0000000110130000
+#define SH_PERFORMANCE_COUNTER2_MASK             0x00000000ffffffff
+#define SH_PERFORMANCE_COUNTER2_INIT             0x0000000000000000
+
+/*   SH_PERFORMANCE_COUNTER2_COUNT                                      */
+/*   Description:  Counter 2                                            */
+#define SH_PERFORMANCE_COUNTER2_COUNT_SHFT       0
+#define SH_PERFORMANCE_COUNTER2_COUNT_MASK       0x00000000ffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER3"                  */
+/*                        Performance Counter 3                         */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNTER3                  0x0000000110140000
+#define SH_PERFORMANCE_COUNTER3_MASK             0x00000000ffffffff
+#define SH_PERFORMANCE_COUNTER3_INIT             0x0000000000000000
+
+/*   SH_PERFORMANCE_COUNTER3_COUNT                                      */
+/*   Description:  Counter 3                                            */
+#define SH_PERFORMANCE_COUNTER3_COUNT_SHFT       0
+#define SH_PERFORMANCE_COUNTER3_COUNT_MASK       0x00000000ffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER4"                  */
+/*                        Performance Counter 4                         */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNTER4                  0x0000000110150000
+#define SH_PERFORMANCE_COUNTER4_MASK             0x00000000ffffffff
+#define SH_PERFORMANCE_COUNTER4_INIT             0x0000000000000000
+
+/*   SH_PERFORMANCE_COUNTER4_COUNT                                      */
+/*   Description:  Counter 4                                            */
+#define SH_PERFORMANCE_COUNTER4_COUNT_SHFT       0
+#define SH_PERFORMANCE_COUNTER4_COUNT_MASK       0x00000000ffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER5"                  */
+/*                        Performance Counter 5                         */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNTER5                  0x0000000110160000
+#define SH_PERFORMANCE_COUNTER5_MASK             0x00000000ffffffff
+#define SH_PERFORMANCE_COUNTER5_INIT             0x0000000000000000
+
+/*   SH_PERFORMANCE_COUNTER5_COUNT                                      */
+/*   Description:  Counter 5                                            */
+#define SH_PERFORMANCE_COUNTER5_COUNT_SHFT       0
+#define SH_PERFORMANCE_COUNTER5_COUNT_MASK       0x00000000ffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER6"                  */
+/*                        Performance Counter 6                         */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNTER6                  0x0000000110170000
+#define SH_PERFORMANCE_COUNTER6_MASK             0x00000000ffffffff
+#define SH_PERFORMANCE_COUNTER6_INIT             0x0000000000000000
+
+/*   SH_PERFORMANCE_COUNTER6_COUNT                                      */
+/*   Description:  Counter 6                                            */
+#define SH_PERFORMANCE_COUNTER6_COUNT_SHFT       0
+#define SH_PERFORMANCE_COUNTER6_COUNT_MASK       0x00000000ffffffff
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER7"                  */
+/*                        Performance Counter 7                         */
+/* ==================================================================== */
+
+#define SH_PERFORMANCE_COUNTER7                  0x0000000110180000
+#define SH_PERFORMANCE_COUNTER7_MASK             0x00000000ffffffff
+#define SH_PERFORMANCE_COUNTER7_INIT             0x0000000000000000
+
+/*   SH_PERFORMANCE_COUNTER7_COUNT                                      */
+/*   Description:  Counter 7                                            */
+#define SH_PERFORMANCE_COUNTER7_COUNT_SHFT       0
+#define SH_PERFORMANCE_COUNTER7_COUNT_MASK       0x00000000ffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_PROFILE_COUNTER"                     */
+/*                           Profile Counter                            */
+/* ==================================================================== */
+
+#define SH_PROFILE_COUNTER                       0x0000000110190000
+#define SH_PROFILE_COUNTER_MASK                  0x00000000000000ff
+#define SH_PROFILE_COUNTER_INIT                  0x0000000000000000
+
+/*   SH_PROFILE_COUNTER_COUNTER                                         */
+/*   Description:  Counter Value                                        */
+#define SH_PROFILE_COUNTER_COUNTER_SHFT          0
+#define SH_PROFILE_COUNTER_COUNTER_MASK          0x00000000000000ff
+
+/* ==================================================================== */
+/*                      Register "SH_PROFILE_PEAK"                      */
+/*                         Profile Peak Counter                         */
+/* ==================================================================== */
+
+#define SH_PROFILE_PEAK                          0x0000000110190080
+#define SH_PROFILE_PEAK_MASK                     0x00000000000000ff
+#define SH_PROFILE_PEAK_INIT                     0x0000000000000000
+
+/*   SH_PROFILE_PEAK_COUNTER                                            */
+/*   Description:  Counter Value                                        */
+#define SH_PROFILE_PEAK_COUNTER_SHFT             0
+#define SH_PROFILE_PEAK_COUNTER_MASK             0x00000000000000ff
+
+/* ==================================================================== */
+/*                         Register "SH_PTC_0"                          */
+/*       Puge Translation Cache Message Configuration Information       */
+/* ==================================================================== */
+
+#define SH_PTC_0                                 0x00000001101a0000
+#define SH_PTC_0_MASK                            0x80000000fffffffd
+#define SH_PTC_0_INIT                            0x0000000000000000
+
+/*   SH_PTC_0_A                                                         */
+/*   Description:  Type                                                 */
+#define SH_PTC_0_A_SHFT                          0
+#define SH_PTC_0_A_MASK                          0x0000000000000001
+
+/*   SH_PTC_0_PS                                                        */
+/*   Description:  Page Size                                            */
+#define SH_PTC_0_PS_SHFT                         2
+#define SH_PTC_0_PS_MASK                         0x00000000000000fc
+
+/*   SH_PTC_0_RID                                                       */
+/*   Description:  Region ID                                            */
+#define SH_PTC_0_RID_SHFT                        8
+#define SH_PTC_0_RID_MASK                        0x00000000ffffff00
+
+/*   SH_PTC_0_START                                                     */
+/*   Description:  Start                                                */
+#define SH_PTC_0_START_SHFT                      63
+#define SH_PTC_0_START_MASK                      0x8000000000000000
+
+/* ==================================================================== */
+/*                         Register "SH_PTC_1"                          */
+/*       Puge Translation Cache Message Configuration Information       */
+/* ==================================================================== */
+
+#define SH_PTC_1                                 0x00000001101a0080
+#define SH_PTC_1_MASK                            0x9ffffffffffff000
+#define SH_PTC_1_INIT                            0x0000000000000000
+
+/*   SH_PTC_1_VPN                                                       */
+/*   Description:  Virtual page number                                  */
+#define SH_PTC_1_VPN_SHFT                        12
+#define SH_PTC_1_VPN_MASK                        0x1ffffffffffff000
+
+/*   SH_PTC_1_START                                                     */
+/*   Description:  PTC_1 Start                                          */
+#define SH_PTC_1_START_SHFT                      63
+#define SH_PTC_1_START_MASK                      0x8000000000000000
+
+/* ==================================================================== */
+/*                       Register "SH_PTC_PARMS"                        */
+/*                       PTC Time-out parmaeters                        */
+/* ==================================================================== */
+
+#define SH_PTC_PARMS                             0x00000001101a0100
+#define SH_PTC_PARMS_MASK                        0x0000000fffffffff
+#define SH_PTC_PARMS_INIT                        0x00000007ffffffff
+
+/*   SH_PTC_PARMS_PTC_TO_WRAP                                           */
+/*   Description:  PTC time-out period                                  */
+#define SH_PTC_PARMS_PTC_TO_WRAP_SHFT            0
+#define SH_PTC_PARMS_PTC_TO_WRAP_MASK            0x0000000000ffffff
+
+/*   SH_PTC_PARMS_PTC_TO_VAL                                            */
+/*   Description:  PTC time-out valid                                   */
+#define SH_PTC_PARMS_PTC_TO_VAL_SHFT             24
+#define SH_PTC_PARMS_PTC_TO_VAL_MASK             0x0000000fff000000
+
+/* ==================================================================== */
+/*                        Register "SH_INT_CMPA"                        */
+/*                  RTC Compare Value for Processor A                   */
+/* ==================================================================== */
+
+#define SH_INT_CMPA                              0x00000001101b0000
+#define SH_INT_CMPA_MASK                         0x007fffffffffffff
+#define SH_INT_CMPA_INIT                         0x0000000000000000
+
+/*   SH_INT_CMPA_REAL_TIME_CMPA                                         */
+/*   Description:  Real Time Clock Compare                              */
+#define SH_INT_CMPA_REAL_TIME_CMPA_SHFT          0
+#define SH_INT_CMPA_REAL_TIME_CMPA_MASK          0x007fffffffffffff
+
+/* ==================================================================== */
+/*                        Register "SH_INT_CMPB"                        */
+/*                  RTC Compare Value for Processor B                   */
+/* ==================================================================== */
+
+#define SH_INT_CMPB                              0x00000001101b0080
+#define SH_INT_CMPB_MASK                         0x007fffffffffffff
+#define SH_INT_CMPB_INIT                         0x0000000000000000
+
+/*   SH_INT_CMPB_REAL_TIME_CMPB                                         */
+/*   Description:  Real Time Clock Compare                              */
+#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT          0
+#define SH_INT_CMPB_REAL_TIME_CMPB_MASK          0x007fffffffffffff
+
+/* ==================================================================== */
+/*                        Register "SH_INT_CMPC"                        */
+/*                  RTC Compare Value for Processor C                   */
+/* ==================================================================== */
+
+#define SH_INT_CMPC                              0x00000001101b0100
+#define SH_INT_CMPC_MASK                         0x007fffffffffffff
+#define SH_INT_CMPC_INIT                         0x0000000000000000
+
+/*   SH_INT_CMPC_REAL_TIME_CMPC                                         */
+/*   Description:  Real Time Clock Compare                              */
+#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT          0
+#define SH_INT_CMPC_REAL_TIME_CMPC_MASK          0x007fffffffffffff
+
+/* ==================================================================== */
+/*                        Register "SH_INT_CMPD"                        */
+/*                  RTC Compare Value for Processor D                   */
+/* ==================================================================== */
+
+#define SH_INT_CMPD                              0x00000001101b0180
+#define SH_INT_CMPD_MASK                         0x007fffffffffffff
+#define SH_INT_CMPD_INIT                         0x0000000000000000
+
+/*   SH_INT_CMPD_REAL_TIME_CMPD                                         */
+/*   Description:  Real Time Clock Compare                              */
+#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT          0
+#define SH_INT_CMPD_REAL_TIME_CMPD_MASK          0x007fffffffffffff
+
+/* ==================================================================== */
+/*                        Register "SH_INT_PROF"                        */
+/*                      Profile Compare Registers                       */
+/* ==================================================================== */
+
+#define SH_INT_PROF                              0x00000001101b0200
+#define SH_INT_PROF_MASK                         0x00000000ffffffff
+#define SH_INT_PROF_INIT                         0x0000000000000000
+
+/*   SH_INT_PROF_PROFILE_COMPARE                                        */
+/*   Description:  Profile Compare                                      */
+#define SH_INT_PROF_PROFILE_COMPARE_SHFT         0
+#define SH_INT_PROF_PROFILE_COMPARE_MASK         0x00000000ffffffff
+
+/* ==================================================================== */
+/*                          Register "SH_RTC"                           */
+/*                           Real-time Clock                            */
+/* ==================================================================== */
+
+#define SH_RTC                                   0x00000001101c0000
+#define SH_RTC_MASK                              0x007fffffffffffff
+#define SH_RTC_INIT                              0x0000000000000000
+
+/*   SH_RTC_REAL_TIME_CLOCK                                             */
+/*   Description:  Real-time Clock                                      */
+#define SH_RTC_REAL_TIME_CLOCK_SHFT              0
+#define SH_RTC_REAL_TIME_CLOCK_MASK              0x007fffffffffffff
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH0"                        */
+/*                          Scratch Register 0                          */
+/* ==================================================================== */
+
+#define SH_SCRATCH0                              0x00000001101d0000
+#define SH_SCRATCH0_MASK                         0xffffffffffffffff
+#define SH_SCRATCH0_INIT                         0x0000000000000000
+
+/*   SH_SCRATCH0_SCRATCH0                                               */
+/*   Description:  Scratch register 0                                   */
+#define SH_SCRATCH0_SCRATCH0_SHFT                0
+#define SH_SCRATCH0_SCRATCH0_MASK                0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_SCRATCH0_ALIAS"                     */
+/*                   Scratch Register 0 Alias Address                   */
+/* ==================================================================== */
+
+#define SH_SCRATCH0_ALIAS                        0x00000001101d0008
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH1"                        */
+/*                          Scratch Register 1                          */
+/* ==================================================================== */
+
+#define SH_SCRATCH1                              0x00000001101d0080
+#define SH_SCRATCH1_MASK                         0xffffffffffffffff
+#define SH_SCRATCH1_INIT                         0x0000000000000000
+
+/*   SH_SCRATCH1_SCRATCH1                                               */
+/*   Description:  Scratch register 1                                   */
+#define SH_SCRATCH1_SCRATCH1_SHFT                0
+#define SH_SCRATCH1_SCRATCH1_MASK                0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_SCRATCH1_ALIAS"                     */
+/*                   Scratch Register 1 Alias Address                   */
+/* ==================================================================== */
+
+#define SH_SCRATCH1_ALIAS                        0x00000001101d0088
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH2"                        */
+/*                          Scratch Register 2                          */
+/* ==================================================================== */
+
+#define SH_SCRATCH2                              0x00000001101d0100
+#define SH_SCRATCH2_MASK                         0xffffffffffffffff
+#define SH_SCRATCH2_INIT                         0x0000000000000000
+
+/*   SH_SCRATCH2_SCRATCH2                                               */
+/*   Description:  Scratch register 2                                   */
+#define SH_SCRATCH2_SCRATCH2_SHFT                0
+#define SH_SCRATCH2_SCRATCH2_MASK                0xffffffffffffffff
+
+/* ==================================================================== */
+/*                     Register "SH_SCRATCH2_ALIAS"                     */
+/*                   Scratch Register 2 Alias Address                   */
+/* ==================================================================== */
+
+#define SH_SCRATCH2_ALIAS                        0x00000001101d0108
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH3"                        */
+/*                          Scratch Register 3                          */
+/* ==================================================================== */
+
+#define SH_SCRATCH3                              0x00000001101d0180
+#define SH_SCRATCH3_MASK                         0x0000000000000001
+#define SH_SCRATCH3_INIT                         0x0000000000000000
+
+/*   SH_SCRATCH3_SCRATCH3                                               */
+/*   Description:  Scratch register 3                                   */
+#define SH_SCRATCH3_SCRATCH3_SHFT                0
+#define SH_SCRATCH3_SCRATCH3_MASK                0x0000000000000001
+
+/* ==================================================================== */
+/*                     Register "SH_SCRATCH3_ALIAS"                     */
+/*                   Scratch Register 3 Alias Address                   */
+/* ==================================================================== */
+
+#define SH_SCRATCH3_ALIAS                        0x00000001101d0188
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH4"                        */
+/*                          Scratch Register 4                          */
+/* ==================================================================== */
+
+#define SH_SCRATCH4                              0x00000001101d0200
+#define SH_SCRATCH4_MASK                         0x0000000000000001
+#define SH_SCRATCH4_INIT                         0x0000000000000000
+
+/*   SH_SCRATCH4_SCRATCH4                                               */
+/*   Description:  Scratch register 4                                   */
+#define SH_SCRATCH4_SCRATCH4_SHFT                0
+#define SH_SCRATCH4_SCRATCH4_MASK                0x0000000000000001
+
+/* ==================================================================== */
+/*                     Register "SH_SCRATCH4_ALIAS"                     */
+/*                   Scratch Register 4 Alias Address                   */
+/* ==================================================================== */
+
+#define SH_SCRATCH4_ALIAS                        0x00000001101d0208
+
+/* ==================================================================== */
+/*                  Register "SH_CRB_MESSAGE_CONTROL"                   */
+/*               Coherent Request Buffer Message Control                */
+/* ==================================================================== */
+
+#define SH_CRB_MESSAGE_CONTROL                   0x0000000120000000
+#define SH_CRB_MESSAGE_CONTROL_MASK              0xffffffff00000fff
+#define SH_CRB_MESSAGE_CONTROL_INIT              0x0000000000000006
+
+/*   SH_CRB_MESSAGE_CONTROL_SYSTEM_COHERENCE_ENABLE                     */
+/*   Description:  System Coherence Enabled                             */
+#define SH_CRB_MESSAGE_CONTROL_SYSTEM_COHERENCE_ENABLE_SHFT 0
+#define SH_CRB_MESSAGE_CONTROL_SYSTEM_COHERENCE_ENABLE_MASK 0x0000000000000001
+
+/*   SH_CRB_MESSAGE_CONTROL_LOCAL_SPECULATIVE_MESSAGE_ENABLE            */
+/*   Description:  Speculative Read Requests to Local Memory Enabled    */
+#define SH_CRB_MESSAGE_CONTROL_LOCAL_SPECULATIVE_MESSAGE_ENABLE_SHFT 1
+#define SH_CRB_MESSAGE_CONTROL_LOCAL_SPECULATIVE_MESSAGE_ENABLE_MASK 0x0000000000000002
+
+/*   SH_CRB_MESSAGE_CONTROL_REMOTE_SPECULATIVE_MESSAGE_ENABLE           */
+/*   Description:  Speculative Read Requests to Remote Memory Enabled  */
+#define SH_CRB_MESSAGE_CONTROL_REMOTE_SPECULATIVE_MESSAGE_ENABLE_SHFT 2
+#define SH_CRB_MESSAGE_CONTROL_REMOTE_SPECULATIVE_MESSAGE_ENABLE_MASK 0x0000000000000004
+
+/*   SH_CRB_MESSAGE_CONTROL_MESSAGE_COLOR                               */
+/*   Description:  Define color of message                              */
+#define SH_CRB_MESSAGE_CONTROL_MESSAGE_COLOR_SHFT 3
+#define SH_CRB_MESSAGE_CONTROL_MESSAGE_COLOR_MASK 0x0000000000000008
+
+/*   SH_CRB_MESSAGE_CONTROL_MESSAGE_COLOR_ENABLE                        */
+/*   Description:  Enable color message processing                      */
+#define SH_CRB_MESSAGE_CONTROL_MESSAGE_COLOR_ENABLE_SHFT 4
+#define SH_CRB_MESSAGE_CONTROL_MESSAGE_COLOR_ENABLE_MASK 0x0000000000000010
+
+/*   SH_CRB_MESSAGE_CONTROL_RRB_ATTRIBUTE_MISMATCH_FSB_ENABLE           */
+/*   Description:  Enable FSB RRB Mismatch check                        */
+#define SH_CRB_MESSAGE_CONTROL_RRB_ATTRIBUTE_MISMATCH_FSB_ENABLE_SHFT 5
+#define SH_CRB_MESSAGE_CONTROL_RRB_ATTRIBUTE_MISMATCH_FSB_ENABLE_MASK 0x0000000000000020
+
+/*   SH_CRB_MESSAGE_CONTROL_WRB_ATTRIBUTE_MISMATCH_FSB_ENABLE           */
+/*   Description:  Enable FSB WRB Mismatch check                        */
+#define SH_CRB_MESSAGE_CONTROL_WRB_ATTRIBUTE_MISMATCH_FSB_ENABLE_SHFT 6
+#define SH_CRB_MESSAGE_CONTROL_WRB_ATTRIBUTE_MISMATCH_FSB_ENABLE_MASK 0x0000000000000040
+
+/*   SH_CRB_MESSAGE_CONTROL_IRB_ATTRIBUTE_MISMATCH_FSB_ENABLE           */
+/*   Description:  Enable FSB IRB Mismatch check                        */
+#define SH_CRB_MESSAGE_CONTROL_IRB_ATTRIBUTE_MISMATCH_FSB_ENABLE_SHFT 7
+#define SH_CRB_MESSAGE_CONTROL_IRB_ATTRIBUTE_MISMATCH_FSB_ENABLE_MASK 0x0000000000000080
+
+/*   SH_CRB_MESSAGE_CONTROL_RRB_ATTRIBUTE_MISMATCH_XB_ENABLE            */
+/*   Description:  Enable XB RRB Mismatch check                         */
+#define SH_CRB_MESSAGE_CONTROL_RRB_ATTRIBUTE_MISMATCH_XB_ENABLE_SHFT 8
+#define SH_CRB_MESSAGE_CONTROL_RRB_ATTRIBUTE_MISMATCH_XB_ENABLE_MASK 0x0000000000000100
+
+/*   SH_CRB_MESSAGE_CONTROL_WRB_ATTRIBUTE_MISMATCH_XB_ENABLE            */
+/*   Description:  Enable XB WRB Mismatch check                         */
+#define SH_CRB_MESSAGE_CONTROL_WRB_ATTRIBUTE_MISMATCH_XB_ENABLE_SHFT 9
+#define SH_CRB_MESSAGE_CONTROL_WRB_ATTRIBUTE_MISMATCH_XB_ENABLE_MASK 0x0000000000000200
+
+/*   SH_CRB_MESSAGE_CONTROL_SUPPRESS_BOGUS_WRITES                       */
+/*   Description:  ignor residual write data                            */
+#define SH_CRB_MESSAGE_CONTROL_SUPPRESS_BOGUS_WRITES_SHFT 10
+#define SH_CRB_MESSAGE_CONTROL_SUPPRESS_BOGUS_WRITES_MASK 0x0000000000000400
+
+/*   SH_CRB_MESSAGE_CONTROL_ENABLE_IVACK_CONSOLIDATION                  */
+/*   Description:  enable IVACK reply consolidation                     */
+#define SH_CRB_MESSAGE_CONTROL_ENABLE_IVACK_CONSOLIDATION_SHFT 11
+#define SH_CRB_MESSAGE_CONTROL_ENABLE_IVACK_CONSOLIDATION_MASK 0x0000000000000800
+
+/*   SH_CRB_MESSAGE_CONTROL_IVACK_STALL_COUNT                           */
+/*   Description:  IVACK stall counter                                  */
+#define SH_CRB_MESSAGE_CONTROL_IVACK_STALL_COUNT_SHFT 32
+#define SH_CRB_MESSAGE_CONTROL_IVACK_STALL_COUNT_MASK 0x0000ffff00000000
+
+/*   SH_CRB_MESSAGE_CONTROL_IVACK_THROTTLE_CONTROL                      */
+/*   Description:  IVACK throttling limit/timer control                 */
+#define SH_CRB_MESSAGE_CONTROL_IVACK_THROTTLE_CONTROL_SHFT 48
+#define SH_CRB_MESSAGE_CONTROL_IVACK_THROTTLE_CONTROL_MASK 0xffff000000000000
+
+/* ==================================================================== */
+/*                     Register "SH_CRB_NACK_LIMIT"                     */
+/*                            CRB Nack Limit                            */
+/* ==================================================================== */
+
+#define SH_CRB_NACK_LIMIT                        0x0000000120000080
+#define SH_CRB_NACK_LIMIT_MASK                   0x800000000000ffff
+#define SH_CRB_NACK_LIMIT_INIT                   0x0000000000000000
+
+/*   SH_CRB_NACK_LIMIT_LIMIT                                            */
+/*   Description:  Nack Count Limit                                     */
+#define SH_CRB_NACK_LIMIT_LIMIT_SHFT             0
+#define SH_CRB_NACK_LIMIT_LIMIT_MASK             0x0000000000000fff
+
+/*   SH_CRB_NACK_LIMIT_PRI_FREQ                                         */
+/*   Description:  Frequency at which priority count is incremented     */
+#define SH_CRB_NACK_LIMIT_PRI_FREQ_SHFT          12
+#define SH_CRB_NACK_LIMIT_PRI_FREQ_MASK          0x000000000000f000
+
+/*   SH_CRB_NACK_LIMIT_ENABLE                                           */
+/*   Description:  Enable NACK limit detection                          */
+#define SH_CRB_NACK_LIMIT_ENABLE_SHFT            63
+#define SH_CRB_NACK_LIMIT_ENABLE_MASK            0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_CRB_TIMEOUT_PRESCALE"                  */
+/*               Coherent Request Buffer Timeout Prescale               */
+/* ==================================================================== */
+
+#define SH_CRB_TIMEOUT_PRESCALE                  0x0000000120000100
+#define SH_CRB_TIMEOUT_PRESCALE_MASK             0x00000000ffffffff
+#define SH_CRB_TIMEOUT_PRESCALE_INIT             0x0000000000000000
+
+/*   SH_CRB_TIMEOUT_PRESCALE_SCALING_FACTOR                             */
+/*   Description:  CRB Time-out Prescale Factor                         */
+#define SH_CRB_TIMEOUT_PRESCALE_SCALING_FACTOR_SHFT 0
+#define SH_CRB_TIMEOUT_PRESCALE_SCALING_FACTOR_MASK 0x00000000ffffffff
+
+/* ==================================================================== */
+/*                    Register "SH_CRB_TIMEOUT_SKID"                    */
+/*              Coherent Request Buffer Timeout Skid Limit              */
+/* ==================================================================== */
+
+#define SH_CRB_TIMEOUT_SKID                      0x0000000120000180
+#define SH_CRB_TIMEOUT_SKID_MASK                 0x800000000000003f
+#define SH_CRB_TIMEOUT_SKID_INIT                 0x0000000000000007
+
+/*   SH_CRB_TIMEOUT_SKID_SKID                                           */
+/*   Description:  CRB Time-out Skid                                    */
+#define SH_CRB_TIMEOUT_SKID_SKID_SHFT            0
+#define SH_CRB_TIMEOUT_SKID_SKID_MASK            0x000000000000003f
+
+/*   SH_CRB_TIMEOUT_SKID_RESET_SKID_COUNT                               */
+/*   Description:  Reset Skid counter                                   */
+#define SH_CRB_TIMEOUT_SKID_RESET_SKID_COUNT_SHFT 63
+#define SH_CRB_TIMEOUT_SKID_RESET_SKID_COUNT_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_MEMORY_WRITE_STATUS_0"                  */
+/*                    Memory Write Status for CPU 0                     */
+/* ==================================================================== */
+
+#define SH_MEMORY_WRITE_STATUS_0                 0x0000000120070000
+#define SH_MEMORY_WRITE_STATUS_0_MASK            0x000000000000003f
+#define SH_MEMORY_WRITE_STATUS_0_INIT            0x0000000000000000
+
+/*   SH_MEMORY_WRITE_STATUS_0_PENDING_WRITE_COUNT                       */
+/*   Description:  Pending Write Count                                  */
+#define SH_MEMORY_WRITE_STATUS_0_PENDING_WRITE_COUNT_SHFT 0
+#define SH_MEMORY_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK 0x000000000000003f
+
+/* ==================================================================== */
+/*                 Register "SH_MEMORY_WRITE_STATUS_1"                  */
+/*                    Memory Write Status for CPU 1                     */
+/* ==================================================================== */
+
+#define SH_MEMORY_WRITE_STATUS_1                 0x0000000120070080
+#define SH_MEMORY_WRITE_STATUS_1_MASK            0x000000000000003f
+#define SH_MEMORY_WRITE_STATUS_1_INIT            0x0000000000000000
+
+/*   SH_MEMORY_WRITE_STATUS_1_PENDING_WRITE_COUNT                       */
+/*   Description:  Pending Write Count                                  */
+#define SH_MEMORY_WRITE_STATUS_1_PENDING_WRITE_COUNT_SHFT 0
+#define SH_MEMORY_WRITE_STATUS_1_PENDING_WRITE_COUNT_MASK 0x000000000000003f
+
+/* ==================================================================== */
+/*                   Register "SH_PIO_WRITE_STATUS_0"                   */
+/*                      PIO Write Status for CPU 0                      */
+/* ==================================================================== */
+
+#define SH_PIO_WRITE_STATUS_0                    0x0000000120070200
+#define SH_PIO_WRITE_STATUS_0_MASK               0xbf03ffffffffffff
+#define SH_PIO_WRITE_STATUS_0_INIT               0x8000000000000000
+
+/*   SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR                            */
+/*   Description:  More than one PIO write error occured                */
+#define SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR_SHFT 0
+#define SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR_MASK 0x0000000000000001
+
+/*   SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK                               */
+/*   Description:  Deaklock response detected                           */
+#define SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_SHFT 1
+#define SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK 0x0000000000000002
+
+/*   SH_PIO_WRITE_STATUS_0_WRITE_ERROR                                  */
+/*   Description:  Error response detected                              */
+#define SH_PIO_WRITE_STATUS_0_WRITE_ERROR_SHFT   2
+#define SH_PIO_WRITE_STATUS_0_WRITE_ERROR_MASK   0x0000000000000004
+
+/*   SH_PIO_WRITE_STATUS_0_WRITE_ERROR_ADDRESS                          */
+/*   Description:  Address associated with error response               */
+#define SH_PIO_WRITE_STATUS_0_WRITE_ERROR_ADDRESS_SHFT 3
+#define SH_PIO_WRITE_STATUS_0_WRITE_ERROR_ADDRESS_MASK 0x0003fffffffffff8
+
+/*   SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT                          */
+/*   Description:  Count of currently pending PIO writes                */
+#define SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_SHFT 56
+#define SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK 0x3f00000000000000
+
+/*   SH_PIO_WRITE_STATUS_0_WRITES_OK                                    */
+/*   Description:  No pending writes or errors                          */
+#define SH_PIO_WRITE_STATUS_0_WRITES_OK_SHFT     63
+#define SH_PIO_WRITE_STATUS_0_WRITES_OK_MASK     0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_PIO_WRITE_STATUS_1"                   */
+/*                      PIO Write Status for CPU 1                      */
+/* ==================================================================== */
+
+#define SH_PIO_WRITE_STATUS_1                    0x0000000120070280
+#define SH_PIO_WRITE_STATUS_1_MASK               0xbf03ffffffffffff
+#define SH_PIO_WRITE_STATUS_1_INIT               0x8000000000000000
+
+/*   SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR                            */
+/*   Description:  More than one PIO write error occured                */
+#define SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR_SHFT 0
+#define SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR_MASK 0x0000000000000001
+
+/*   SH_PIO_WRITE_STATUS_1_WRITE_DEADLOCK                               */
+/*   Description:  Deaklock response detected                           */
+#define SH_PIO_WRITE_STATUS_1_WRITE_DEADLOCK_SHFT 1
+#define SH_PIO_WRITE_STATUS_1_WRITE_DEADLOCK_MASK 0x0000000000000002
+
+/*   SH_PIO_WRITE_STATUS_1_WRITE_ERROR                                  */
+/*   Description:  Error response detected                              */
+#define SH_PIO_WRITE_STATUS_1_WRITE_ERROR_SHFT   2
+#define SH_PIO_WRITE_STATUS_1_WRITE_ERROR_MASK   0x0000000000000004
+
+/*   SH_PIO_WRITE_STATUS_1_WRITE_ERROR_ADDRESS                          */
+/*   Description:  Address associated with error response               */
+#define SH_PIO_WRITE_STATUS_1_WRITE_ERROR_ADDRESS_SHFT 3
+#define SH_PIO_WRITE_STATUS_1_WRITE_ERROR_ADDRESS_MASK 0x0003fffffffffff8
+
+/*   SH_PIO_WRITE_STATUS_1_PENDING_WRITE_COUNT                          */
+/*   Description:  Count of currently pending PIO writes                */
+#define SH_PIO_WRITE_STATUS_1_PENDING_WRITE_COUNT_SHFT 56
+#define SH_PIO_WRITE_STATUS_1_PENDING_WRITE_COUNT_MASK 0x3f00000000000000
+
+/*   SH_PIO_WRITE_STATUS_1_WRITES_OK                                    */
+/*   Description:  No pending writes or errors                          */
+#define SH_PIO_WRITE_STATUS_1_WRITES_OK_SHFT     63
+#define SH_PIO_WRITE_STATUS_1_WRITES_OK_MASK     0x8000000000000000
+
+/* ==================================================================== */
+/*                Register "SH_PIO_WRITE_STATUS_0_ALIAS"                */
+/* ==================================================================== */
+
+#define SH_PIO_WRITE_STATUS_0_ALIAS              0x0000000120070208
+
+/* ==================================================================== */
+/*                Register "SH_PIO_WRITE_STATUS_1_ALIAS"                */
+/* ==================================================================== */
+
+#define SH_PIO_WRITE_STATUS_1_ALIAS              0x0000000120070288
+
+/* ==================================================================== */
+/*             Register "SH_MEMORY_WRITE_STATUS_NON_USER_0"             */
+/*            Memory Write Status for CPU 0. OS access only             */
+/* ==================================================================== */
+
+#define SH_MEMORY_WRITE_STATUS_NON_USER_0        0x0000000120070400
+#define SH_MEMORY_WRITE_STATUS_NON_USER_0_MASK   0x800000000000003f
+#define SH_MEMORY_WRITE_STATUS_NON_USER_0_INIT   0x0000000000000000
+
+/*   SH_MEMORY_WRITE_STATUS_NON_USER_0_PENDING_WRITE_COUNT              */
+/*   Description:  Pending Write Count                                  */
+#define SH_MEMORY_WRITE_STATUS_NON_USER_0_PENDING_WRITE_COUNT_SHFT 0
+#define SH_MEMORY_WRITE_STATUS_NON_USER_0_PENDING_WRITE_COUNT_MASK 0x000000000000003f
+
+/*   SH_MEMORY_WRITE_STATUS_NON_USER_0_CLEAR                            */
+/*   Description:  Clear pending write count                            */
+#define SH_MEMORY_WRITE_STATUS_NON_USER_0_CLEAR_SHFT 63
+#define SH_MEMORY_WRITE_STATUS_NON_USER_0_CLEAR_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*             Register "SH_MEMORY_WRITE_STATUS_NON_USER_1"             */
+/*            Memory Write Status for CPU 1. OS access only             */
+/* ==================================================================== */
+
+#define SH_MEMORY_WRITE_STATUS_NON_USER_1        0x0000000120070480
+#define SH_MEMORY_WRITE_STATUS_NON_USER_1_MASK   0x800000000000003f
+#define SH_MEMORY_WRITE_STATUS_NON_USER_1_INIT   0x0000000000000000
+
+/*   SH_MEMORY_WRITE_STATUS_NON_USER_1_PENDING_WRITE_COUNT              */
+/*   Description:  Pending Write Count                                  */
+#define SH_MEMORY_WRITE_STATUS_NON_USER_1_PENDING_WRITE_COUNT_SHFT 0
+#define SH_MEMORY_WRITE_STATUS_NON_USER_1_PENDING_WRITE_COUNT_MASK 0x000000000000003f
+
+/*   SH_MEMORY_WRITE_STATUS_NON_USER_1_CLEAR                            */
+/*   Description:  Clear pending write count                            */
+#define SH_MEMORY_WRITE_STATUS_NON_USER_1_CLEAR_SHFT 63
+#define SH_MEMORY_WRITE_STATUS_NON_USER_1_CLEAR_MASK 0x8000000000000000
+
+/* ==================================================================== */
+/*                      Register "SH_MMRBIST_ERR"                       */
+/*                  Error capture for bist read errors                  */
+/* ==================================================================== */
+
+#define SH_MMRBIST_ERR                           0x0000000100000080
+#define SH_MMRBIST_ERR_MASK                      0x00000071ffffffff
+#define SH_MMRBIST_ERR_INIT                      0x0000000000000000
+
+/*   SH_MMRBIST_ERR_ADDR                                                */
+/*   Description:  dword address of bist error                          */
+#define SH_MMRBIST_ERR_ADDR_SHFT                 0
+#define SH_MMRBIST_ERR_ADDR_MASK                 0x00000001ffffffff
+
+/*   SH_MMRBIST_ERR_DETECTED                                            */
+/*   Description:  error detected flag                                  */
+#define SH_MMRBIST_ERR_DETECTED_SHFT             36
+#define SH_MMRBIST_ERR_DETECTED_MASK             0x0000001000000000
+
+/*   SH_MMRBIST_ERR_MULTIPLE_DETECTED                                   */
+/*   Description:  multiple errors detected flag                        */
+#define SH_MMRBIST_ERR_MULTIPLE_DETECTED_SHFT    37
+#define SH_MMRBIST_ERR_MULTIPLE_DETECTED_MASK    0x0000002000000000
+
+/*   SH_MMRBIST_ERR_CANCELLED                                           */
+/*   Description:  mmr/bist was cancelled                               */
+#define SH_MMRBIST_ERR_CANCELLED_SHFT            38
+#define SH_MMRBIST_ERR_CANCELLED_MASK            0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MISC_ERR_HDR_LOWER"                   */
+/*                       Header capture register                        */
+/* ==================================================================== */
+
+#define SH_MISC_ERR_HDR_LOWER                    0x0000000100000088
+#define SH_MISC_ERR_HDR_LOWER_MASK               0x93fffffffffffff8
+#define SH_MISC_ERR_HDR_LOWER_INIT               0x0000000000000000
+
+/*   SH_MISC_ERR_HDR_LOWER_ADDR                                         */
+/*   Description:  upper bits of reference address                      */
+#define SH_MISC_ERR_HDR_LOWER_ADDR_SHFT          3
+#define SH_MISC_ERR_HDR_LOWER_ADDR_MASK          0x0000000ffffffff8
+
+/*   SH_MISC_ERR_HDR_LOWER_CMD                                          */
+/*   Description:  command of reference                                 */
+#define SH_MISC_ERR_HDR_LOWER_CMD_SHFT           36
+#define SH_MISC_ERR_HDR_LOWER_CMD_MASK           0x00000ff000000000
+
+/*   SH_MISC_ERR_HDR_LOWER_SRC                                          */
+/*   Description:  source node of reference                             */
+#define SH_MISC_ERR_HDR_LOWER_SRC_SHFT           44
+#define SH_MISC_ERR_HDR_LOWER_SRC_MASK           0x03fff00000000000
+
+/*   SH_MISC_ERR_HDR_LOWER_WRITE                                        */
+/*   Description:  reference is a write                                 */
+#define SH_MISC_ERR_HDR_LOWER_WRITE_SHFT         60
+#define SH_MISC_ERR_HDR_LOWER_WRITE_MASK         0x1000000000000000
+
+/*   SH_MISC_ERR_HDR_LOWER_VALID                                        */
+/*   Description:  set when capture occurs                              */
+#define SH_MISC_ERR_HDR_LOWER_VALID_SHFT         63
+#define SH_MISC_ERR_HDR_LOWER_VALID_MASK         0x8000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MISC_ERR_HDR_UPPER"                   */
+/*           Error header capture packet and protocol errors            */
+/* ==================================================================== */
+
+#define SH_MISC_ERR_HDR_UPPER                    0x0000000100000090
+#define SH_MISC_ERR_HDR_UPPER_MASK               0x000000001ff000ff
+#define SH_MISC_ERR_HDR_UPPER_INIT               0x0000000000000000
+
+/*   SH_MISC_ERR_HDR_UPPER_DIR_PROTOCOL                                 */
+/*   Description:  indicates a directory protocol error captured        */
+#define SH_MISC_ERR_HDR_UPPER_DIR_PROTOCOL_SHFT  0
+#define SH_MISC_ERR_HDR_UPPER_DIR_PROTOCOL_MASK  0x0000000000000001
+
+/*   SH_MISC_ERR_HDR_UPPER_ILLEGAL_CMD                                  */
+/*   Description:  indicates an illegal command error captured          */
+#define SH_MISC_ERR_HDR_UPPER_ILLEGAL_CMD_SHFT   1
+#define SH_MISC_ERR_HDR_UPPER_ILLEGAL_CMD_MASK   0x0000000000000002
+
+/*   SH_MISC_ERR_HDR_UPPER_NONEXIST_ADDR                                */
+/*   Description:  indicates a non-existent memory error captured       */
+#define SH_MISC_ERR_HDR_UPPER_NONEXIST_ADDR_SHFT 2
+#define SH_MISC_ERR_HDR_UPPER_NONEXIST_ADDR_MASK 0x0000000000000004
+
+/*   SH_MISC_ERR_HDR_UPPER_RMW_UC                                       */
+/*   Description:  indicates an uncorrectable store rmw                 */
+#define SH_MISC_ERR_HDR_UPPER_RMW_UC_SHFT        3
+#define SH_MISC_ERR_HDR_UPPER_RMW_UC_MASK        0x0000000000000008
+
+/*   SH_MISC_ERR_HDR_UPPER_RMW_COR                                      */
+/*   Description:  indicates a correctable store rmw                    */
+#define SH_MISC_ERR_HDR_UPPER_RMW_COR_SHFT       4
+#define SH_MISC_ERR_HDR_UPPER_RMW_COR_MASK       0x0000000000000010
+
+/*   SH_MISC_ERR_HDR_UPPER_DIR_ACC                                      */
+/*   Description:  indicates a data request to directory memory error   */
+/*  captured                                                            */
+#define SH_MISC_ERR_HDR_UPPER_DIR_ACC_SHFT       5
+#define SH_MISC_ERR_HDR_UPPER_DIR_ACC_MASK       0x0000000000000020
+
+/*   SH_MISC_ERR_HDR_UPPER_PI_PKT_SIZE                                  */
+/*   Description:  indicates a pkt size error from pi                   */
+#define SH_MISC_ERR_HDR_UPPER_PI_PKT_SIZE_SHFT   6
+#define SH_MISC_ERR_HDR_UPPER_PI_PKT_SIZE_MASK   0x0000000000000040
+
+/*   SH_MISC_ERR_HDR_UPPER_XN_PKT_SIZE                                  */
+/*   Description:  indicates a pkt size error from xn                   */
+#define SH_MISC_ERR_HDR_UPPER_XN_PKT_SIZE_SHFT   7
+#define SH_MISC_ERR_HDR_UPPER_XN_PKT_SIZE_MASK   0x0000000000000080
+
+/*   SH_MISC_ERR_HDR_UPPER_ECHO                                         */
+#define SH_MISC_ERR_HDR_UPPER_ECHO_SHFT          20
+#define SH_MISC_ERR_HDR_UPPER_ECHO_MASK          0x000000001ff00000
+
+/* ==================================================================== */
+/*                  Register "SH_DIR_UC_ERR_HDR_LOWER"                  */
+/*                       Header capture register                        */
+/* ==================================================================== */
+
+#define SH_DIR_UC_ERR_HDR_LOWER                  0x0000000100000098
+#define SH_DIR_UC_ERR_HDR_LOWER_MASK             0x93fffffffffffff8
+#define SH_DIR_UC_ERR_HDR_LOWER_INIT             0x0000000000000000
+
+/*   SH_DIR_UC_ERR_HDR_LOWER_ADDR                                       */
+/*   Description:  upper bits of reference address                      */
+#define SH_DIR_UC_ERR_HDR_LOWER_ADDR_SHFT        3
+#define SH_DIR_UC_ERR_HDR_LOWER_ADDR_MASK        0x0000000ffffffff8
+
+/*   SH_DIR_UC_ERR_HDR_LOWER_CMD                                        */
+/*   Description:  command of reference                                 */
+#define SH_DIR_UC_ERR_HDR_LOWER_CMD_SHFT         36
+#define SH_DIR_UC_ERR_HDR_LOWER_CMD_MASK         0x00000ff000000000
+
+/*   SH_DIR_UC_ERR_HDR_LOWER_SRC                                        */
+/*   Description:  source node of reference                             */
+#define SH_DIR_UC_ERR_HDR_LOWER_SRC_SHFT         44
+#define SH_DIR_UC_ERR_HDR_LOWER_SRC_MASK         0x03fff00000000000
+
+/*   SH_DIR_UC_ERR_HDR_LOWER_WRITE                                      */
+/*   Description:  reference is a write                                 */
+#define SH_DIR_UC_ERR_HDR_LOWER_WRITE_SHFT       60
+#define SH_DIR_UC_ERR_HDR_LOWER_WRITE_MASK       0x1000000000000000
+
+/*   SH_DIR_UC_ERR_HDR_LOWER_VALID                                      */
+/*   Description:  set when capture occurs                              */
+#define SH_DIR_UC_ERR_HDR_LOWER_VALID_SHFT       63
+#define SH_DIR_UC_ERR_HDR_LOWER_VALID_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_DIR_UC_ERR_HDR_UPPER"                  */
+/*           Error header capture packet and protocol errors            */
+/* ==================================================================== */
+
+#define SH_DIR_UC_ERR_HDR_UPPER                  0x00000001000000a0
+#define SH_DIR_UC_ERR_HDR_UPPER_MASK             0x000000001ff00008
+#define SH_DIR_UC_ERR_HDR_UPPER_INIT             0x0000000000000000
+
+/*   SH_DIR_UC_ERR_HDR_UPPER_DIR_UC                                     */
+/*   Description:  indicates uncorrectable directory error captured     */
+#define SH_DIR_UC_ERR_HDR_UPPER_DIR_UC_SHFT      3
+#define SH_DIR_UC_ERR_HDR_UPPER_DIR_UC_MASK      0x0000000000000008
+
+/*   SH_DIR_UC_ERR_HDR_UPPER_ECHO                                       */
+#define SH_DIR_UC_ERR_HDR_UPPER_ECHO_SHFT        20
+#define SH_DIR_UC_ERR_HDR_UPPER_ECHO_MASK        0x000000001ff00000
+
+/* ==================================================================== */
+/*                 Register "SH_DIR_COR_ERR_HDR_LOWER"                  */
+/*                       Header capture register                        */
+/* ==================================================================== */
+
+#define SH_DIR_COR_ERR_HDR_LOWER                 0x00000001000000a8
+#define SH_DIR_COR_ERR_HDR_LOWER_MASK            0x93fffffffffffff8
+#define SH_DIR_COR_ERR_HDR_LOWER_INIT            0x0000000000000000
+
+/*   SH_DIR_COR_ERR_HDR_LOWER_ADDR                                      */
+/*   Description:  upper bits of reference address                      */
+#define SH_DIR_COR_ERR_HDR_LOWER_ADDR_SHFT       3
+#define SH_DIR_COR_ERR_HDR_LOWER_ADDR_MASK       0x0000000ffffffff8
+
+/*   SH_DIR_COR_ERR_HDR_LOWER_CMD                                       */
+/*   Description:  command of reference                                 */
+#define SH_DIR_COR_ERR_HDR_LOWER_CMD_SHFT        36
+#define SH_DIR_COR_ERR_HDR_LOWER_CMD_MASK        0x00000ff000000000
+
+/*   SH_DIR_COR_ERR_HDR_LOWER_SRC                                       */
+/*   Description:  source node of reference                             */
+#define SH_DIR_COR_ERR_HDR_LOWER_SRC_SHFT        44
+#define SH_DIR_COR_ERR_HDR_LOWER_SRC_MASK        0x03fff00000000000
+
+/*   SH_DIR_COR_ERR_HDR_LOWER_WRITE                                     */
+/*   Description:  reference is a write                                 */
+#define SH_DIR_COR_ERR_HDR_LOWER_WRITE_SHFT      60
+#define SH_DIR_COR_ERR_HDR_LOWER_WRITE_MASK      0x1000000000000000
+
+/*   SH_DIR_COR_ERR_HDR_LOWER_VALID                                     */
+/*   Description:  set when capture occurs                              */
+#define SH_DIR_COR_ERR_HDR_LOWER_VALID_SHFT      63
+#define SH_DIR_COR_ERR_HDR_LOWER_VALID_MASK      0x8000000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_DIR_COR_ERR_HDR_UPPER"                  */
+/*           Error header capture packet and protocol errors            */
+/* ==================================================================== */
+
+#define SH_DIR_COR_ERR_HDR_UPPER                 0x00000001000000b0
+#define SH_DIR_COR_ERR_HDR_UPPER_MASK            0x000000001ff00100
+#define SH_DIR_COR_ERR_HDR_UPPER_INIT            0x0000000000000000
+
+/*   SH_DIR_COR_ERR_HDR_UPPER_DIR_COR                                   */
+/*   Description:  indicates correctable directory error captured       */
+#define SH_DIR_COR_ERR_HDR_UPPER_DIR_COR_SHFT    8
+#define SH_DIR_COR_ERR_HDR_UPPER_DIR_COR_MASK    0x0000000000000100
+
+/*   SH_DIR_COR_ERR_HDR_UPPER_ECHO                                      */
+#define SH_DIR_COR_ERR_HDR_UPPER_ECHO_SHFT       20
+#define SH_DIR_COR_ERR_HDR_UPPER_ECHO_MASK       0x000000001ff00000
+
+/* ==================================================================== */
+/*                   Register "SH_MEM_ERROR_SUMMARY"                    */
+/*                          Memory error flags                          */
+/* ==================================================================== */
+
+#define SH_MEM_ERROR_SUMMARY                     0x00000001000000b8
+#define SH_MEM_ERROR_SUMMARY_MASK                0x00000007f77777ff
+#define SH_MEM_ERROR_SUMMARY_INIT                0x0000000000000000
+
+/*   SH_MEM_ERROR_SUMMARY_ILLEGAL_CMD                                   */
+/*   Description:  illegal command error                                */
+#define SH_MEM_ERROR_SUMMARY_ILLEGAL_CMD_SHFT    0
+#define SH_MEM_ERROR_SUMMARY_ILLEGAL_CMD_MASK    0x0000000000000001
+
+/*   SH_MEM_ERROR_SUMMARY_NONEXIST_ADDR                                 */
+/*   Description:  non-existent memory error                            */
+#define SH_MEM_ERROR_SUMMARY_NONEXIST_ADDR_SHFT  1
+#define SH_MEM_ERROR_SUMMARY_NONEXIST_ADDR_MASK  0x0000000000000002
+
+/*   SH_MEM_ERROR_SUMMARY_DQLP_DIR_PERR                                 */
+/*   Description:  directory protocol error in dqlp                     */
+#define SH_MEM_ERROR_SUMMARY_DQLP_DIR_PERR_SHFT  2
+#define SH_MEM_ERROR_SUMMARY_DQLP_DIR_PERR_MASK  0x0000000000000004
+
+/*   SH_MEM_ERROR_SUMMARY_DQRP_DIR_PERR                                 */
+/*   Description:  directory protocol error in dqrp                     */
+#define SH_MEM_ERROR_SUMMARY_DQRP_DIR_PERR_SHFT  3
+#define SH_MEM_ERROR_SUMMARY_DQRP_DIR_PERR_MASK  0x0000000000000008
+
+/*   SH_MEM_ERROR_SUMMARY_DQLP_DIR_UC                                   */
+/*   Description:  uncorrectable directory error in dqlp                */
+#define SH_MEM_ERROR_SUMMARY_DQLP_DIR_UC_SHFT    4
+#define SH_MEM_ERROR_SUMMARY_DQLP_DIR_UC_MASK    0x0000000000000010
+
+/*   SH_MEM_ERROR_SUMMARY_DQLP_DIR_COR                                  */
+/*   Description:  correctable directory error in dqlp                  */
+#define SH_MEM_ERROR_SUMMARY_DQLP_DIR_COR_SHFT   5
+#define SH_MEM_ERROR_SUMMARY_DQLP_DIR_COR_MASK   0x0000000000000020
+
+/*   SH_MEM_ERROR_SUMMARY_DQRP_DIR_UC                                   */
+/*   Description:  uncorrectable directory error in dqrp                */
+#define SH_MEM_ERROR_SUMMARY_DQRP_DIR_UC_SHFT    6
+#define SH_MEM_ERROR_SUMMARY_DQRP_DIR_UC_MASK    0x0000000000000040
+
+/*   SH_MEM_ERROR_SUMMARY_DQRP_DIR_COR                                  */
+/*   Description:  correctable directory error in dqrp                  */
+#define SH_MEM_ERROR_SUMMARY_DQRP_DIR_COR_SHFT   7
+#define SH_MEM_ERROR_SUMMARY_DQRP_DIR_COR_MASK   0x0000000000000080
+
+/*   SH_MEM_ERROR_SUMMARY_ACX_INT_HW                                    */
+/*   Description:  hardware interrupt from acx                          */
+#define SH_MEM_ERROR_SUMMARY_ACX_INT_HW_SHFT     8
+#define SH_MEM_ERROR_SUMMARY_ACX_INT_HW_MASK     0x0000000000000100
+
+/*   SH_MEM_ERROR_SUMMARY_ACY_INT_HW                                    */
+/*   Description:  hardware interrupt from acy                          */
+#define SH_MEM_ERROR_SUMMARY_ACY_INT_HW_SHFT     9
+#define SH_MEM_ERROR_SUMMARY_ACY_INT_HW_MASK     0x0000000000000200
+
+/*   SH_MEM_ERROR_SUMMARY_DIR_ACC                                       */
+/*   Description:  directory memory access error                        */
+#define SH_MEM_ERROR_SUMMARY_DIR_ACC_SHFT        10
+#define SH_MEM_ERROR_SUMMARY_DIR_ACC_MASK        0x0000000000000400
+
+/*   SH_MEM_ERROR_SUMMARY_DQLP_INT_UC                                   */
+/*   Description:  uncorrectable interrupt from dqlp                    */
+#define SH_MEM_ERROR_SUMMARY_DQLP_INT_UC_SHFT    12
+#define SH_MEM_ERROR_SUMMARY_DQLP_INT_UC_MASK    0x0000000000001000
+
+/*   SH_MEM_ERROR_SUMMARY_DQLP_INT_COR                                  */
+/*   Description:  correctable interrupt from dqlp                      */
+#define SH_MEM_ERROR_SUMMARY_DQLP_INT_COR_SHFT   13
+#define SH_MEM_ERROR_SUMMARY_DQLP_INT_COR_MASK   0x0000000000002000
+
+/*   SH_MEM_ERROR_SUMMARY_DQLP_INT_HW                                   */
+/*   Description:  hardware interrupt from dqlp                         */
+#define SH_MEM_ERROR_SUMMARY_DQLP_INT_HW_SHFT    14
+#define SH_MEM_ERROR_SUMMARY_DQLP_INT_HW_MASK    0x0000000000004000
+
+/*   SH_MEM_ERROR_SUMMARY_DQLS_INT_UC                                   */
+/*   Description:  uncorrectable interrupt from dqls                    */
+#define SH_MEM_ERROR_SUMMARY_DQLS_INT_UC_SHFT    16
+#define SH_MEM_ERROR_SUMMARY_DQLS_INT_UC_MASK    0x0000000000010000
+
+/*   SH_MEM_ERROR_SUMMARY_DQLS_INT_COR                                  */
+/*   Description:  correctable interrupt from dqls                      */
+#define SH_MEM_ERROR_SUMMARY_DQLS_INT_COR_SHFT   17
+#define SH_MEM_ERROR_SUMMARY_DQLS_INT_COR_MASK   0x0000000000020000
+
+/*   SH_MEM_ERROR_SUMMARY_DQLS_INT_HW                                   */
+/*   Description:  hardware interrupt from dqls                         */
+#define SH_MEM_ERROR_SUMMARY_DQLS_INT_HW_SHFT    18
+#define SH_MEM_ERROR_SUMMARY_DQLS_INT_HW_MASK    0x0000000000040000
+
+/*   SH_MEM_ERROR_SUMMARY_DQRP_INT_UC                                   */
+/*   Description:  uncorrectable interrupt from dqrp                    */
+#define SH_MEM_ERROR_SUMMARY_DQRP_INT_UC_SHFT    20
+#define SH_MEM_ERROR_SUMMARY_DQRP_INT_UC_MASK    0x0000000000100000
+
+/*   SH_MEM_ERROR_SUMMARY_DQRP_INT_COR                                  */
+/*   Description:  correctable interrupt from dqrp                      */
+#define SH_MEM_ERROR_SUMMARY_DQRP_INT_COR_SHFT   21
+#define SH_MEM_ERROR_SUMMARY_DQRP_INT_COR_MASK   0x0000000000200000
+
+/*   SH_MEM_ERROR_SUMMARY_DQRP_INT_HW                                   */
+/*   Description:  hardware interrupt from dqrp                         */
+#define SH_MEM_ERROR_SUMMARY_DQRP_INT_HW_SHFT    22
+#define SH_MEM_ERROR_SUMMARY_DQRP_INT_HW_MASK    0x0000000000400000
+
+/*   SH_MEM_ERROR_SUMMARY_DQRS_INT_UC                                   */
+/*   Description:  uncorrectable interrupt from dqrs                    */
+#define SH_MEM_ERROR_SUMMARY_DQRS_INT_UC_SHFT    24
+#define SH_MEM_ERROR_SUMMARY_DQRS_INT_UC_MASK    0x0000000001000000
+
+/*   SH_MEM_ERROR_SUMMARY_DQRS_INT_COR                                  */
+/*   Description:  correctable interrupt from dqrs                      */
+#define SH_MEM_ERROR_SUMMARY_DQRS_INT_COR_SHFT   25
+#define SH_MEM_ERROR_SUMMARY_DQRS_INT_COR_MASK   0x0000000002000000
+
+/*   SH_MEM_ERROR_SUMMARY_DQRS_INT_HW                                   */
+/*   Description:  hardware interrupt from dqrs                         */
+#define SH_MEM_ERROR_SUMMARY_DQRS_INT_HW_SHFT    26
+#define SH_MEM_ERROR_SUMMARY_DQRS_INT_HW_MASK    0x0000000004000000
+
+/*   SH_MEM_ERROR_SUMMARY_PI_REPLY_OVERFLOW                             */
+/*   Description:  too many reply packets came from pi                  */
+#define SH_MEM_ERROR_SUMMARY_PI_REPLY_OVERFLOW_SHFT 28
+#define SH_MEM_ERROR_SUMMARY_PI_REPLY_OVERFLOW_MASK 0x0000000010000000
+
+/*   SH_MEM_ERROR_SUMMARY_XN_REPLY_OVERFLOW                             */
+/*   Description:  too many reply packets came from xn                  */
+#define SH_MEM_ERROR_SUMMARY_XN_REPLY_OVERFLOW_SHFT 29
+#define SH_MEM_ERROR_SUMMARY_XN_REPLY_OVERFLOW_MASK 0x0000000020000000
+
+/*   SH_MEM_ERROR_SUMMARY_PI_REQUEST_OVERFLOW                           */
+/*   Description:  too many request packets came from pi                */
+#define SH_MEM_ERROR_SUMMARY_PI_REQUEST_OVERFLOW_SHFT 30
+#define SH_MEM_ERROR_SUMMARY_PI_REQUEST_OVERFLOW_MASK 0x0000000040000000
+
+/*   SH_MEM_ERROR_SUMMARY_XN_REQUEST_OVERFLOW                           */
+/*   Description:  too many request packets came from xn                */
+#define SH_MEM_ERROR_SUMMARY_XN_REQUEST_OVERFLOW_SHFT 31
+#define SH_MEM_ERROR_SUMMARY_XN_REQUEST_OVERFLOW_MASK 0x0000000080000000
+
+/*   SH_MEM_ERROR_SUMMARY_RED_BLACK_ERR_TIMEOUT                         */
+/*   Description:  red black scheme did not clean up soon enough        */
+#define SH_MEM_ERROR_SUMMARY_RED_BLACK_ERR_TIMEOUT_SHFT 32
+#define SH_MEM_ERROR_SUMMARY_RED_BLACK_ERR_TIMEOUT_MASK 0x0000000100000000
+
+/*   SH_MEM_ERROR_SUMMARY_PI_PKT_SIZE                                   */
+/*   Description:  received data bearing packet from pi with wrong siz  */
+#define SH_MEM_ERROR_SUMMARY_PI_PKT_SIZE_SHFT    33
+#define SH_MEM_ERROR_SUMMARY_PI_PKT_SIZE_MASK    0x0000000200000000
+
+/*   SH_MEM_ERROR_SUMMARY_XN_PKT_SIZE                                   */
+/*   Description:  received data bearing packet from xn with wrong siz  */
+#define SH_MEM_ERROR_SUMMARY_XN_PKT_SIZE_SHFT    34
+#define SH_MEM_ERROR_SUMMARY_XN_PKT_SIZE_MASK    0x0000000400000000
+
+/* ==================================================================== */
+/*                Register "SH_MEM_ERROR_SUMMARY_ALIAS"                 */
+/*                    Memory error flags clear alias                    */
+/* ==================================================================== */
+
+#define SH_MEM_ERROR_SUMMARY_ALIAS               0x00000001000000c0
+
+/* ==================================================================== */
+/*                   Register "SH_MEM_ERROR_OVERFLOW"                   */
+/*                          Memory error flags                          */
+/* ==================================================================== */
+
+#define SH_MEM_ERROR_OVERFLOW                    0x00000001000000c8
+#define SH_MEM_ERROR_OVERFLOW_MASK               0x00000007f77777ff
+#define SH_MEM_ERROR_OVERFLOW_INIT               0x0000000000000000
+
+/*   SH_MEM_ERROR_OVERFLOW_ILLEGAL_CMD                                  */
+/*   Description:  illegal command error                                */
+#define SH_MEM_ERROR_OVERFLOW_ILLEGAL_CMD_SHFT   0
+#define SH_MEM_ERROR_OVERFLOW_ILLEGAL_CMD_MASK   0x0000000000000001
+
+/*   SH_MEM_ERROR_OVERFLOW_NONEXIST_ADDR                                */
+/*   Description:  non-existent memory error                            */
+#define SH_MEM_ERROR_OVERFLOW_NONEXIST_ADDR_SHFT 1
+#define SH_MEM_ERROR_OVERFLOW_NONEXIST_ADDR_MASK 0x0000000000000002
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLP_DIR_PERR                                */
+/*   Description:  directory protocol error in dqlp                     */
+#define SH_MEM_ERROR_OVERFLOW_DQLP_DIR_PERR_SHFT 2
+#define SH_MEM_ERROR_OVERFLOW_DQLP_DIR_PERR_MASK 0x0000000000000004
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRP_DIR_PERR                                */
+/*   Description:  directory protocol error in dqrp                     */
+#define SH_MEM_ERROR_OVERFLOW_DQRP_DIR_PERR_SHFT 3
+#define SH_MEM_ERROR_OVERFLOW_DQRP_DIR_PERR_MASK 0x0000000000000008
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLP_DIR_UC                                  */
+/*   Description:  uncorrectable directory error in dqlp                */
+#define SH_MEM_ERROR_OVERFLOW_DQLP_DIR_UC_SHFT   4
+#define SH_MEM_ERROR_OVERFLOW_DQLP_DIR_UC_MASK   0x0000000000000010
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLP_DIR_COR                                 */
+/*   Description:  correctable directory error in dqlp                  */
+#define SH_MEM_ERROR_OVERFLOW_DQLP_DIR_COR_SHFT  5
+#define SH_MEM_ERROR_OVERFLOW_DQLP_DIR_COR_MASK  0x0000000000000020
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRP_DIR_UC                                  */
+/*   Description:  uncorrectable directory error in dqrp                */
+#define SH_MEM_ERROR_OVERFLOW_DQRP_DIR_UC_SHFT   6
+#define SH_MEM_ERROR_OVERFLOW_DQRP_DIR_UC_MASK   0x0000000000000040
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRP_DIR_COR                                 */
+/*   Description:  correctable directory error in dqrp                  */
+#define SH_MEM_ERROR_OVERFLOW_DQRP_DIR_COR_SHFT  7
+#define SH_MEM_ERROR_OVERFLOW_DQRP_DIR_COR_MASK  0x0000000000000080
+
+/*   SH_MEM_ERROR_OVERFLOW_ACX_INT_HW                                   */
+/*   Description:  hardware interrupt from acx                          */
+#define SH_MEM_ERROR_OVERFLOW_ACX_INT_HW_SHFT    8
+#define SH_MEM_ERROR_OVERFLOW_ACX_INT_HW_MASK    0x0000000000000100
+
+/*   SH_MEM_ERROR_OVERFLOW_ACY_INT_HW                                   */
+/*   Description:  hardware interrupt from acy                          */
+#define SH_MEM_ERROR_OVERFLOW_ACY_INT_HW_SHFT    9
+#define SH_MEM_ERROR_OVERFLOW_ACY_INT_HW_MASK    0x0000000000000200
+
+/*   SH_MEM_ERROR_OVERFLOW_DIR_ACC                                      */
+/*   Description:  directory memory access error                        */
+#define SH_MEM_ERROR_OVERFLOW_DIR_ACC_SHFT       10
+#define SH_MEM_ERROR_OVERFLOW_DIR_ACC_MASK       0x0000000000000400
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLP_INT_UC                                  */
+/*   Description:  uncorrectable interrupt from dqlp                    */
+#define SH_MEM_ERROR_OVERFLOW_DQLP_INT_UC_SHFT   12
+#define SH_MEM_ERROR_OVERFLOW_DQLP_INT_UC_MASK   0x0000000000001000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLP_INT_COR                                 */
+/*   Description:  correctable interrupt from dqlp                      */
+#define SH_MEM_ERROR_OVERFLOW_DQLP_INT_COR_SHFT  13
+#define SH_MEM_ERROR_OVERFLOW_DQLP_INT_COR_MASK  0x0000000000002000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLP_INT_HW                                  */
+/*   Description:  hardware interrupt from dqlp                         */
+#define SH_MEM_ERROR_OVERFLOW_DQLP_INT_HW_SHFT   14
+#define SH_MEM_ERROR_OVERFLOW_DQLP_INT_HW_MASK   0x0000000000004000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLS_INT_UC                                  */
+/*   Description:  uncorrectable interrupt from dqls                    */
+#define SH_MEM_ERROR_OVERFLOW_DQLS_INT_UC_SHFT   16
+#define SH_MEM_ERROR_OVERFLOW_DQLS_INT_UC_MASK   0x0000000000010000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLS_INT_COR                                 */
+/*   Description:  correctable interrupt from dqls                      */
+#define SH_MEM_ERROR_OVERFLOW_DQLS_INT_COR_SHFT  17
+#define SH_MEM_ERROR_OVERFLOW_DQLS_INT_COR_MASK  0x0000000000020000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQLS_INT_HW                                  */
+/*   Description:  hardware interrupt from dqls                         */
+#define SH_MEM_ERROR_OVERFLOW_DQLS_INT_HW_SHFT   18
+#define SH_MEM_ERROR_OVERFLOW_DQLS_INT_HW_MASK   0x0000000000040000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRP_INT_UC                                  */
+/*   Description:  uncorrectable interrupt from dqrp                    */
+#define SH_MEM_ERROR_OVERFLOW_DQRP_INT_UC_SHFT   20
+#define SH_MEM_ERROR_OVERFLOW_DQRP_INT_UC_MASK   0x0000000000100000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRP_INT_COR                                 */
+/*   Description:  correctable interrupt from dqrp                      */
+#define SH_MEM_ERROR_OVERFLOW_DQRP_INT_COR_SHFT  21
+#define SH_MEM_ERROR_OVERFLOW_DQRP_INT_COR_MASK  0x0000000000200000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRP_INT_HW                                  */
+/*   Description:  hardware interrupt from dqrp                         */
+#define SH_MEM_ERROR_OVERFLOW_DQRP_INT_HW_SHFT   22
+#define SH_MEM_ERROR_OVERFLOW_DQRP_INT_HW_MASK   0x0000000000400000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRS_INT_UC                                  */
+/*   Description:  uncorrectable interrupt from dqrs                    */
+#define SH_MEM_ERROR_OVERFLOW_DQRS_INT_UC_SHFT   24
+#define SH_MEM_ERROR_OVERFLOW_DQRS_INT_UC_MASK   0x0000000001000000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRS_INT_COR                                 */
+/*   Description:  correctable interrupt from dqrs                      */
+#define SH_MEM_ERROR_OVERFLOW_DQRS_INT_COR_SHFT  25
+#define SH_MEM_ERROR_OVERFLOW_DQRS_INT_COR_MASK  0x0000000002000000
+
+/*   SH_MEM_ERROR_OVERFLOW_DQRS_INT_HW                                  */
+/*   Description:  hardware interrupt from dqrs                         */
+#define SH_MEM_ERROR_OVERFLOW_DQRS_INT_HW_SHFT   26
+#define SH_MEM_ERROR_OVERFLOW_DQRS_INT_HW_MASK   0x0000000004000000
+
+/*   SH_MEM_ERROR_OVERFLOW_PI_REPLY_OVERFLOW                            */
+/*   Description:  too many reply packets came from pi                  */
+#define SH_MEM_ERROR_OVERFLOW_PI_REPLY_OVERFLOW_SHFT 28
+#define SH_MEM_ERROR_OVERFLOW_PI_REPLY_OVERFLOW_MASK 0x0000000010000000
+
+/*   SH_MEM_ERROR_OVERFLOW_XN_REPLY_OVERFLOW                            */
+/*   Description:  too many reply packets came from xn                  */
+#define SH_MEM_ERROR_OVERFLOW_XN_REPLY_OVERFLOW_SHFT 29
+#define SH_MEM_ERROR_OVERFLOW_XN_REPLY_OVERFLOW_MASK 0x0000000020000000
+
+/*   SH_MEM_ERROR_OVERFLOW_PI_REQUEST_OVERFLOW                          */
+/*   Description:  too many request packets came from pi                */
+#define SH_MEM_ERROR_OVERFLOW_PI_REQUEST_OVERFLOW_SHFT 30
+#define SH_MEM_ERROR_OVERFLOW_PI_REQUEST_OVERFLOW_MASK 0x0000000040000000
+
+/*   SH_MEM_ERROR_OVERFLOW_XN_REQUEST_OVERFLOW                          */
+/*   Description:  too many request packets came from xn                */
+#define SH_MEM_ERROR_OVERFLOW_XN_REQUEST_OVERFLOW_SHFT 31
+#define SH_MEM_ERROR_OVERFLOW_XN_REQUEST_OVERFLOW_MASK 0x0000000080000000
+
+/*   SH_MEM_ERROR_OVERFLOW_RED_BLACK_ERR_TIMEOUT                        */
+/*   Description:  red black scheme did not clean up soon enough        */
+#define SH_MEM_ERROR_OVERFLOW_RED_BLACK_ERR_TIMEOUT_SHFT 32
+#define SH_MEM_ERROR_OVERFLOW_RED_BLACK_ERR_TIMEOUT_MASK 0x0000000100000000
+
+/*   SH_MEM_ERROR_OVERFLOW_PI_PKT_SIZE                                  */
+/*   Description:  received data bearing packet from pi with wrong siz  */
+#define SH_MEM_ERROR_OVERFLOW_PI_PKT_SIZE_SHFT   33
+#define SH_MEM_ERROR_OVERFLOW_PI_PKT_SIZE_MASK   0x0000000200000000
+
+/*   SH_MEM_ERROR_OVERFLOW_XN_PKT_SIZE                                  */
+/*   Description:  received data bearing packet from xn with wrong siz  */
+#define SH_MEM_ERROR_OVERFLOW_XN_PKT_SIZE_SHFT   34
+#define SH_MEM_ERROR_OVERFLOW_XN_PKT_SIZE_MASK   0x0000000400000000
+
+/* ==================================================================== */
+/*                Register "SH_MEM_ERROR_OVERFLOW_ALIAS"                */
+/*                    Memory error flags clear alias                    */
+/* ==================================================================== */
+
+#define SH_MEM_ERROR_OVERFLOW_ALIAS              0x00000001000000d0
+
+/* ==================================================================== */
+/*                     Register "SH_MEM_ERROR_MASK"                     */
+/*                          Memory error flags                          */
+/* ==================================================================== */
+
+#define SH_MEM_ERROR_MASK                        0x00000001000000d8
+#define SH_MEM_ERROR_MASK_MASK                   0x00000007f77777ff
+#define SH_MEM_ERROR_MASK_INIT                   0x00000007f77773ff
+
+/*   SH_MEM_ERROR_MASK_ILLEGAL_CMD                                      */
+/*   Description:  illegal command error                                */
+#define SH_MEM_ERROR_MASK_ILLEGAL_CMD_SHFT       0
+#define SH_MEM_ERROR_MASK_ILLEGAL_CMD_MASK       0x0000000000000001
+
+/*   SH_MEM_ERROR_MASK_NONEXIST_ADDR                                    */
+/*   Description:  non-existent memory error                            */
+#define SH_MEM_ERROR_MASK_NONEXIST_ADDR_SHFT     1
+#define SH_MEM_ERROR_MASK_NONEXIST_ADDR_MASK     0x0000000000000002
+
+/*   SH_MEM_ERROR_MASK_DQLP_DIR_PERR                                    */
+/*   Description:  directory protocol error in dqlp                     */
+#define SH_MEM_ERROR_MASK_DQLP_DIR_PERR_SHFT     2
+#define SH_MEM_ERROR_MASK_DQLP_DIR_PERR_MASK     0x0000000000000004
+
+/*   SH_MEM_ERROR_MASK_DQRP_DIR_PERR                                    */
+/*   Description:  directory protocol error in dqrp                     */
+#define SH_MEM_ERROR_MASK_DQRP_DIR_PERR_SHFT     3
+#define SH_MEM_ERROR_MASK_DQRP_DIR_PERR_MASK     0x0000000000000008
+
+/*   SH_MEM_ERROR_MASK_DQLP_DIR_UC                                      */
+/*   Description:  uncorrectable directory error in dqlp                */
+#define SH_MEM_ERROR_MASK_DQLP_DIR_UC_SHFT       4
+#define SH_MEM_ERROR_MASK_DQLP_DIR_UC_MASK       0x0000000000000010
+
+/*   SH_MEM_ERROR_MASK_DQLP_DIR_COR                                     */
+/*   Description:  correctable directory error in dqlp                  */
+#define SH_MEM_ERROR_MASK_DQLP_DIR_COR_SHFT      5
+#define SH_MEM_ERROR_MASK_DQLP_DIR_COR_MASK      0x0000000000000020
+
+/*   SH_MEM_ERROR_MASK_DQRP_DIR_UC                                      */
+/*   Description:  uncorrectable directory error in dqrp                */
+#define SH_MEM_ERROR_MASK_DQRP_DIR_UC_SHFT       6
+#define SH_MEM_ERROR_MASK_DQRP_DIR_UC_MASK       0x0000000000000040
+
+/*   SH_MEM_ERROR_MASK_DQRP_DIR_COR                                     */
+/*   Description:  correctable directory error in dqrp                  */
+#define SH_MEM_ERROR_MASK_DQRP_DIR_COR_SHFT      7
+#define SH_MEM_ERROR_MASK_DQRP_DIR_COR_MASK      0x0000000000000080
+
+/*   SH_MEM_ERROR_MASK_ACX_INT_HW                                       */
+/*   Description:  hardware interrupt from acx                          */
+#define SH_MEM_ERROR_MASK_ACX_INT_HW_SHFT        8
+#define SH_MEM_ERROR_MASK_ACX_INT_HW_MASK        0x0000000000000100
+
+/*   SH_MEM_ERROR_MASK_ACY_INT_HW                                       */
+/*   Description:  hardware interrupt from acy                          */
+#define SH_MEM_ERROR_MASK_ACY_INT_HW_SHFT        9
+#define SH_MEM_ERROR_MASK_ACY_INT_HW_MASK        0x0000000000000200
+
+/*   SH_MEM_ERROR_MASK_DIR_ACC                                          */
+/*   Description:  directory memory access error                        */
+#define SH_MEM_ERROR_MASK_DIR_ACC_SHFT           10
+#define SH_MEM_ERROR_MASK_DIR_ACC_MASK           0x0000000000000400
+
+/*   SH_MEM_ERROR_MASK_DQLP_INT_UC                                      */
+/*   Description:  uncorrectable interrupt from dqlp                    */
+#define SH_MEM_ERROR_MASK_DQLP_INT_UC_SHFT       12
+#define SH_MEM_ERROR_MASK_DQLP_INT_UC_MASK       0x0000000000001000
+
+/*   SH_MEM_ERROR_MASK_DQLP_INT_COR                                     */
+/*   Description:  correctable interrupt from dqlp                      */
+#define SH_MEM_ERROR_MASK_DQLP_INT_COR_SHFT      13
+#define SH_MEM_ERROR_MASK_DQLP_INT_COR_MASK      0x0000000000002000
+
+/*   SH_MEM_ERROR_MASK_DQLP_INT_HW                                      */
+/*   Description:  hardware interrupt from dqlp                         */
+#define SH_MEM_ERROR_MASK_DQLP_INT_HW_SHFT       14
+#define SH_MEM_ERROR_MASK_DQLP_INT_HW_MASK       0x0000000000004000
+
+/*   SH_MEM_ERROR_MASK_DQLS_INT_UC                                      */
+/*   Description:  uncorrectable interrupt from dqls                    */
+#define SH_MEM_ERROR_MASK_DQLS_INT_UC_SHFT       16
+#define SH_MEM_ERROR_MASK_DQLS_INT_UC_MASK       0x0000000000010000
+
+/*   SH_MEM_ERROR_MASK_DQLS_INT_COR                                     */
+/*   Description:  correctable interrupt from dqls                      */
+#define SH_MEM_ERROR_MASK_DQLS_INT_COR_SHFT      17
+#define SH_MEM_ERROR_MASK_DQLS_INT_COR_MASK      0x0000000000020000
+
+/*   SH_MEM_ERROR_MASK_DQLS_INT_HW                                      */
+/*   Description:  hardware interrupt from dqls                         */
+#define SH_MEM_ERROR_MASK_DQLS_INT_HW_SHFT       18
+#define SH_MEM_ERROR_MASK_DQLS_INT_HW_MASK       0x0000000000040000
+
+/*   SH_MEM_ERROR_MASK_DQRP_INT_UC                                      */
+/*   Description:  uncorrectable interrupt from dqrp                    */
+#define SH_MEM_ERROR_MASK_DQRP_INT_UC_SHFT       20
+#define SH_MEM_ERROR_MASK_DQRP_INT_UC_MASK       0x0000000000100000
+
+/*   SH_MEM_ERROR_MASK_DQRP_INT_COR                                     */
+/*   Description:  correctable interrupt from dqrp                      */
+#define SH_MEM_ERROR_MASK_DQRP_INT_COR_SHFT      21
+#define SH_MEM_ERROR_MASK_DQRP_INT_COR_MASK      0x0000000000200000
+
+/*   SH_MEM_ERROR_MASK_DQRP_INT_HW                                      */
+/*   Description:  hardware interrupt from dqrp                         */
+#define SH_MEM_ERROR_MASK_DQRP_INT_HW_SHFT       22
+#define SH_MEM_ERROR_MASK_DQRP_INT_HW_MASK       0x0000000000400000
+
+/*   SH_MEM_ERROR_MASK_DQRS_INT_UC                                      */
+/*   Description:  uncorrectable interrupt from dqrs                    */
+#define SH_MEM_ERROR_MASK_DQRS_INT_UC_SHFT       24
+#define SH_MEM_ERROR_MASK_DQRS_INT_UC_MASK       0x0000000001000000
+
+/*   SH_MEM_ERROR_MASK_DQRS_INT_COR                                     */
+/*   Description:  correctable interrupt from dqrs                      */
+#define SH_MEM_ERROR_MASK_DQRS_INT_COR_SHFT      25
+#define SH_MEM_ERROR_MASK_DQRS_INT_COR_MASK      0x0000000002000000
+
+/*   SH_MEM_ERROR_MASK_DQRS_INT_HW                                      */
+/*   Description:  hardware interrupt from dqrs                         */
+#define SH_MEM_ERROR_MASK_DQRS_INT_HW_SHFT       26
+#define SH_MEM_ERROR_MASK_DQRS_INT_HW_MASK       0x0000000004000000
+
+/*   SH_MEM_ERROR_MASK_PI_REPLY_OVERFLOW                                */
+/*   Description:  too many reply packets came from pi                  */
+#define SH_MEM_ERROR_MASK_PI_REPLY_OVERFLOW_SHFT 28
+#define SH_MEM_ERROR_MASK_PI_REPLY_OVERFLOW_MASK 0x0000000010000000
+
+/*   SH_MEM_ERROR_MASK_XN_REPLY_OVERFLOW                                */
+/*   Description:  too many reply packets came from xn                  */
+#define SH_MEM_ERROR_MASK_XN_REPLY_OVERFLOW_SHFT 29
+#define SH_MEM_ERROR_MASK_XN_REPLY_OVERFLOW_MASK 0x0000000020000000
+
+/*   SH_MEM_ERROR_MASK_PI_REQUEST_OVERFLOW                              */
+/*   Description:  too many request packets came from pi                */
+#define SH_MEM_ERROR_MASK_PI_REQUEST_OVERFLOW_SHFT 30
+#define SH_MEM_ERROR_MASK_PI_REQUEST_OVERFLOW_MASK 0x0000000040000000
+
+/*   SH_MEM_ERROR_MASK_XN_REQUEST_OVERFLOW                              */
+/*   Description:  too many request packets came from xn                */
+#define SH_MEM_ERROR_MASK_XN_REQUEST_OVERFLOW_SHFT 31
+#define SH_MEM_ERROR_MASK_XN_REQUEST_OVERFLOW_MASK 0x0000000080000000
+
+/*   SH_MEM_ERROR_MASK_RED_BLACK_ERR_TIMEOUT                            */
+/*   Description:  red black scheme did not clean up soon enough        */
+#define SH_MEM_ERROR_MASK_RED_BLACK_ERR_TIMEOUT_SHFT 32
+#define SH_MEM_ERROR_MASK_RED_BLACK_ERR_TIMEOUT_MASK 0x0000000100000000
+
+/*   SH_MEM_ERROR_MASK_PI_PKT_SIZE                                      */
+/*   Description:  received data bearing packet from pi with wrong siz  */
+#define SH_MEM_ERROR_MASK_PI_PKT_SIZE_SHFT       33
+#define SH_MEM_ERROR_MASK_PI_PKT_SIZE_MASK       0x0000000200000000
+
+/*   SH_MEM_ERROR_MASK_XN_PKT_SIZE                                      */
+/*   Description:  received data bearing packet from xn with wrong siz  */
+#define SH_MEM_ERROR_MASK_XN_PKT_SIZE_SHFT       34
+#define SH_MEM_ERROR_MASK_XN_PKT_SIZE_MASK       0x0000000400000000
+
+/* ==================================================================== */
+/*                       Register "SH_X_DIMM_CFG"                       */
+/*                       AC Mem Config Registers                        */
+/* ==================================================================== */
+
+#define SH_X_DIMM_CFG                            0x0000000100010000
+#define SH_X_DIMM_CFG_MASK                       0x0000000f7f7f7f7f
+#define SH_X_DIMM_CFG_INIT                       0x000000026f4f2f0f
+
+/*   SH_X_DIMM_CFG_DIMM0_SIZE                                           */
+/*   Description:  DIMM 0 DRAM size                                     */
+#define SH_X_DIMM_CFG_DIMM0_SIZE_SHFT            0
+#define SH_X_DIMM_CFG_DIMM0_SIZE_MASK            0x0000000000000007
+
+/*   SH_X_DIMM_CFG_DIMM0_2BK                                            */
+/*   Description:  DIMM 0 has two physical banks                        */
+#define SH_X_DIMM_CFG_DIMM0_2BK_SHFT             3
+#define SH_X_DIMM_CFG_DIMM0_2BK_MASK             0x0000000000000008
+
+/*   SH_X_DIMM_CFG_DIMM0_REV                                            */
+/*   Description:  DIMM 0 physical banks reversed                       */
+#define SH_X_DIMM_CFG_DIMM0_REV_SHFT             4
+#define SH_X_DIMM_CFG_DIMM0_REV_MASK             0x0000000000000010
+
+/*   SH_X_DIMM_CFG_DIMM0_CS                                             */
+/*   Description:  DIMM 0 chip select, addr[35:34] match                */
+#define SH_X_DIMM_CFG_DIMM0_CS_SHFT              5
+#define SH_X_DIMM_CFG_DIMM0_CS_MASK              0x0000000000000060
+
+/*   SH_X_DIMM_CFG_DIMM1_SIZE                                           */
+/*   Description:  DIMM 1 DRAM size                                     */
+#define SH_X_DIMM_CFG_DIMM1_SIZE_SHFT            8
+#define SH_X_DIMM_CFG_DIMM1_SIZE_MASK            0x0000000000000700
+
+/*   SH_X_DIMM_CFG_DIMM1_2BK                                            */
+/*   Description:  DIMM 1 has two physical banks                        */
+#define SH_X_DIMM_CFG_DIMM1_2BK_SHFT             11
+#define SH_X_DIMM_CFG_DIMM1_2BK_MASK             0x0000000000000800
+
+/*   SH_X_DIMM_CFG_DIMM1_REV                                            */
+/*   Description:  DIMM 1 physical banks reversed                       */
+#define SH_X_DIMM_CFG_DIMM1_REV_SHFT             12
+#define SH_X_DIMM_CFG_DIMM1_REV_MASK             0x0000000000001000
+
+/*   SH_X_DIMM_CFG_DIMM1_CS                                             */
+/*   Description:  DIMM 1 chip select, addr[35:34] match                */
+#define SH_X_DIMM_CFG_DIMM1_CS_SHFT              13
+#define SH_X_DIMM_CFG_DIMM1_CS_MASK              0x0000000000006000
+
+/*   SH_X_DIMM_CFG_DIMM2_SIZE                                           */
+/*   Description:  DIMM 2 DRAM size                                     */
+#define SH_X_DIMM_CFG_DIMM2_SIZE_SHFT            16
+#define SH_X_DIMM_CFG_DIMM2_SIZE_MASK            0x0000000000070000
+
+/*   SH_X_DIMM_CFG_DIMM2_2BK                                            */
+/*   Description:  DIMM 2 has two physical banks                        */
+#define SH_X_DIMM_CFG_DIMM2_2BK_SHFT             19
+#define SH_X_DIMM_CFG_DIMM2_2BK_MASK             0x0000000000080000
+
+/*   SH_X_DIMM_CFG_DIMM2_REV                                            */
+/*   Description:  DIMM 2 physical banks reversed                       */
+#define SH_X_DIMM_CFG_DIMM2_REV_SHFT             20
+#define SH_X_DIMM_CFG_DIMM2_REV_MASK             0x0000000000100000
+
+/*   SH_X_DIMM_CFG_DIMM2_CS                                             */
+/*   Description:  DIMM 2 chip select, addr[35:34] match                */
+#define SH_X_DIMM_CFG_DIMM2_CS_SHFT              21
+#define SH_X_DIMM_CFG_DIMM2_CS_MASK              0x0000000000600000
+
+/*   SH_X_DIMM_CFG_DIMM3_SIZE                                           */
+/*   Description:  DIMM 3 DRAM size                                     */
+#define SH_X_DIMM_CFG_DIMM3_SIZE_SHFT            24
+#define SH_X_DIMM_CFG_DIMM3_SIZE_MASK            0x0000000007000000
+
+/*   SH_X_DIMM_CFG_DIMM3_2BK                                            */
+/*   Description:  DIMM 3 has two physical banks                        */
+#define SH_X_DIMM_CFG_DIMM3_2BK_SHFT             27
+#define SH_X_DIMM_CFG_DIMM3_2BK_MASK             0x0000000008000000
+
+/*   SH_X_DIMM_CFG_DIMM3_REV                                            */
+/*   Description:  DIMM 3 physical banks reversed                       */
+#define SH_X_DIMM_CFG_DIMM3_REV_SHFT             28
+#define SH_X_DIMM_CFG_DIMM3_REV_MASK             0x0000000010000000
+
+/*   SH_X_DIMM_CFG_DIMM3_CS                                             */
+/*   Description:  DIMM 3 chip select, addr[35:34] match                */
+#define SH_X_DIMM_CFG_DIMM3_CS_SHFT              29
+#define SH_X_DIMM_CFG_DIMM3_CS_MASK              0x0000000060000000
+
+/*   SH_X_DIMM_CFG_FREQ                                                 */
+/*   Description:  DIMM frequency select                                */
+#define SH_X_DIMM_CFG_FREQ_SHFT                  32
+#define SH_X_DIMM_CFG_FREQ_MASK                  0x0000000f00000000
+
+/* ==================================================================== */
+/*                       Register "SH_Y_DIMM_CFG"                       */
+/*                       AC Mem Config Registers                        */
+/* ==================================================================== */
+
+#define SH_Y_DIMM_CFG                            0x0000000100010008
+#define SH_Y_DIMM_CFG_MASK                       0x0000000f7f7f7f7f
+#define SH_Y_DIMM_CFG_INIT                       0x000000026f4f2f0f
+
+/*   SH_Y_DIMM_CFG_DIMM0_SIZE                                           */
+/*   Description:  DIMM 0 DRAM size                                     */
+#define SH_Y_DIMM_CFG_DIMM0_SIZE_SHFT            0
+#define SH_Y_DIMM_CFG_DIMM0_SIZE_MASK            0x0000000000000007
+
+/*   SH_Y_DIMM_CFG_DIMM0_2BK                                            */
+/*   Description:  DIMM 0 has two physical banks                        */
+#define SH_Y_DIMM_CFG_DIMM0_2BK_SHFT             3
+#define SH_Y_DIMM_CFG_DIMM0_2BK_MASK             0x0000000000000008
+
+/*   SH_Y_DIMM_CFG_DIMM0_REV                                            */
+/*   Description:  DIMM 0 physical banks reversed                       */
+#define SH_Y_DIMM_CFG_DIMM0_REV_SHFT             4
+#define SH_Y_DIMM_CFG_DIMM0_REV_MASK             0x0000000000000010
+
+/*   SH_Y_DIMM_CFG_DIMM0_CS                                             */
+/*   Description:  DIMM 0 chip select, addr[35:34] match                */
+#define SH_Y_DIMM_CFG_DIMM0_CS_SHFT              5
+#define SH_Y_DIMM_CFG_DIMM0_CS_MASK              0x0000000000000060
+
+/*   SH_Y_DIMM_CFG_DIMM1_SIZE                                           */
+/*   Description:  DIMM 1 DRAM size                                     */
+#define SH_Y_DIMM_CFG_DIMM1_SIZE_SHFT            8
+#define SH_Y_DIMM_CFG_DIMM1_SIZE_MASK            0x0000000000000700
+
+/*   SH_Y_DIMM_CFG_DIMM1_2BK                                            */
+/*   Description:  DIMM 1 has two physical banks                        */
+#define SH_Y_DIMM_CFG_DIMM1_2BK_SHFT             11
+#define SH_Y_DIMM_CFG_DIMM1_2BK_MASK             0x0000000000000800
+
+/*   SH_Y_DIMM_CFG_DIMM1_REV                                            */
+/*   Description:  DIMM 1 physical banks reversed                       */
+#define SH_Y_DIMM_CFG_DIMM1_REV_SHFT             12
+#define SH_Y_DIMM_CFG_DIMM1_REV_MASK             0x0000000000001000
+
+/*   SH_Y_DIMM_CFG_DIMM1_CS                                             */
+/*   Description:  DIMM 1 chip select, addr[35:34] match                */
+#define SH_Y_DIMM_CFG_DIMM1_CS_SHFT              13
+#define SH_Y_DIMM_CFG_DIMM1_CS_MASK              0x0000000000006000
+
+/*   SH_Y_DIMM_CFG_DIMM2_SIZE                                           */
+/*   Description:  DIMM 2 DRAM size                                     */
+#define SH_Y_DIMM_CFG_DIMM2_SIZE_SHFT            16
+#define SH_Y_DIMM_CFG_DIMM2_SIZE_MASK            0x0000000000070000
+
+/*   SH_Y_DIMM_CFG_DIMM2_2BK                                            */
+/*   Description:  DIMM 2 has two physical banks                        */
+#define SH_Y_DIMM_CFG_DIMM2_2BK_SHFT             19
+#define SH_Y_DIMM_CFG_DIMM2_2BK_MASK             0x0000000000080000
+
+/*   SH_Y_DIMM_CFG_DIMM2_REV                                            */
+/*   Description:  DIMM 2 physical banks reversed                       */
+#define SH_Y_DIMM_CFG_DIMM2_REV_SHFT             20
+#define SH_Y_DIMM_CFG_DIMM2_REV_MASK             0x0000000000100000
+
+/*   SH_Y_DIMM_CFG_DIMM2_CS                                             */
+/*   Description:  DIMM 2 chip select, addr[35:34] match                */
+#define SH_Y_DIMM_CFG_DIMM2_CS_SHFT              21
+#define SH_Y_DIMM_CFG_DIMM2_CS_MASK              0x0000000000600000
+
+/*   SH_Y_DIMM_CFG_DIMM3_SIZE                                           */
+/*   Description:  DIMM 3 DRAM size                                     */
+#define SH_Y_DIMM_CFG_DIMM3_SIZE_SHFT            24
+#define SH_Y_DIMM_CFG_DIMM3_SIZE_MASK            0x0000000007000000
+
+/*   SH_Y_DIMM_CFG_DIMM3_2BK                                            */
+/*   Description:  DIMM 3 has two physical banks                        */
+#define SH_Y_DIMM_CFG_DIMM3_2BK_SHFT             27
+#define SH_Y_DIMM_CFG_DIMM3_2BK_MASK             0x0000000008000000
+
+/*   SH_Y_DIMM_CFG_DIMM3_REV                                            */
+/*   Description:  DIMM 3 physical banks reversed                       */
+#define SH_Y_DIMM_CFG_DIMM3_REV_SHFT             28
+#define SH_Y_DIMM_CFG_DIMM3_REV_MASK             0x0000000010000000
+
+/*   SH_Y_DIMM_CFG_DIMM3_CS                                             */
+/*   Description:  DIMM 3 chip select, addr[35:34] match                */
+#define SH_Y_DIMM_CFG_DIMM3_CS_SHFT              29
+#define SH_Y_DIMM_CFG_DIMM3_CS_MASK              0x0000000060000000
+
+/*   SH_Y_DIMM_CFG_FREQ                                                 */
+/*   Description:  DIMM frequency select                                */
+#define SH_Y_DIMM_CFG_FREQ_SHFT                  32
+#define SH_Y_DIMM_CFG_FREQ_MASK                  0x0000000f00000000
+
+/* ==================================================================== */
+/*                      Register "SH_JNR_DIMM_CFG"                      */
+/*                       AC Mem Config Registers                        */
+/* ==================================================================== */
+
+#define SH_JNR_DIMM_CFG                          0x0000000100010010
+#define SH_JNR_DIMM_CFG_MASK                     0x0000000f7f7f7f7f
+#define SH_JNR_DIMM_CFG_INIT                     0x000000026f4f2f0f
+
+/*   SH_JNR_DIMM_CFG_DIMM0_SIZE                                         */
+/*   Description:  DIMM 0 DRAM size                                     */
+#define SH_JNR_DIMM_CFG_DIMM0_SIZE_SHFT          0
+#define SH_JNR_DIMM_CFG_DIMM0_SIZE_MASK          0x0000000000000007
+
+/*   SH_JNR_DIMM_CFG_DIMM0_2BK                                          */
+/*   Description:  DIMM 0 has two physical banks                        */
+#define SH_JNR_DIMM_CFG_DIMM0_2BK_SHFT           3
+#define SH_JNR_DIMM_CFG_DIMM0_2BK_MASK           0x0000000000000008
+
+/*   SH_JNR_DIMM_CFG_DIMM0_REV                                          */
+/*   Description:  DIMM 0 physical banks reversed                       */
+#define SH_JNR_DIMM_CFG_DIMM0_REV_SHFT           4
+#define SH_JNR_DIMM_CFG_DIMM0_REV_MASK           0x0000000000000010
+
+/*   SH_JNR_DIMM_CFG_DIMM0_CS                                           */
+/*   Description:  DIMM 0 chip select, addr[35:34] match                */
+#define SH_JNR_DIMM_CFG_DIMM0_CS_SHFT            5
+#define SH_JNR_DIMM_CFG_DIMM0_CS_MASK            0x0000000000000060
+
+/*   SH_JNR_DIMM_CFG_DIMM1_SIZE                                         */
+/*   Description:  DIMM 1 DRAM size                                     */
+#define SH_JNR_DIMM_CFG_DIMM1_SIZE_SHFT          8
+#define SH_JNR_DIMM_CFG_DIMM1_SIZE_MASK          0x0000000000000700
+
+/*   SH_JNR_DIMM_CFG_DIMM1_2BK                                          */
+/*   Description:  DIMM 1 has two physical banks                        */
+#define SH_JNR_DIMM_CFG_DIMM1_2BK_SHFT           11
+#define SH_JNR_DIMM_CFG_DIMM1_2BK_MASK           0x0000000000000800
+
+/*   SH_JNR_DIMM_CFG_DIMM1_REV                                          */
+/*   Description:  DIMM 1 physical banks reversed                       */
+#define SH_JNR_DIMM_CFG_DIMM1_REV_SHFT           12
+#define SH_JNR_DIMM_CFG_DIMM1_REV_MASK           0x0000000000001000
+
+/*   SH_JNR_DIMM_CFG_DIMM1_CS                                           */
+/*   Description:  DIMM 1 chip select, addr[35:34] match                */
+#define SH_JNR_DIMM_CFG_DIMM1_CS_SHFT            13
+#define SH_JNR_DIMM_CFG_DIMM1_CS_MASK            0x0000000000006000
+
+/*   SH_JNR_DIMM_CFG_DIMM2_SIZE                                         */
+/*   Description:  DIMM 2 DRAM size                                     */
+#define SH_JNR_DIMM_CFG_DIMM2_SIZE_SHFT          16
+#define SH_JNR_DIMM_CFG_DIMM2_SIZE_MASK          0x0000000000070000
+
+/*   SH_JNR_DIMM_CFG_DIMM2_2BK                                          */
+/*   Description:  DIMM 2 has two physical banks                        */
+#define SH_JNR_DIMM_CFG_DIMM2_2BK_SHFT           19
+#define SH_JNR_DIMM_CFG_DIMM2_2BK_MASK           0x0000000000080000
+
+/*   SH_JNR_DIMM_CFG_DIMM2_REV                                          */
+/*   Description:  DIMM 2 physical banks reversed                       */
+#define SH_JNR_DIMM_CFG_DIMM2_REV_SHFT           20
+#define SH_JNR_DIMM_CFG_DIMM2_REV_MASK           0x0000000000100000
+
+/*   SH_JNR_DIMM_CFG_DIMM2_CS                                           */
+/*   Description:  DIMM 2 chip select, addr[35:34] match                */
+#define SH_JNR_DIMM_CFG_DIMM2_CS_SHFT            21
+#define SH_JNR_DIMM_CFG_DIMM2_CS_MASK            0x0000000000600000
+
+/*   SH_JNR_DIMM_CFG_DIMM3_SIZE                                         */
+/*   Description:  DIMM 3 DRAM size                                     */
+#define SH_JNR_DIMM_CFG_DIMM3_SIZE_SHFT          24
+#define SH_JNR_DIMM_CFG_DIMM3_SIZE_MASK          0x0000000007000000
+
+/*   SH_JNR_DIMM_CFG_DIMM3_2BK                                          */
+/*   Description:  DIMM 3 has two physical banks                        */
+#define SH_JNR_DIMM_CFG_DIMM3_2BK_SHFT           27
+#define SH_JNR_DIMM_CFG_DIMM3_2BK_MASK           0x0000000008000000
+
+/*   SH_JNR_DIMM_CFG_DIMM3_REV                                          */
+/*   Description:  DIMM 3 physical banks reversed                       */
+#define SH_JNR_DIMM_CFG_DIMM3_REV_SHFT           28
+#define SH_JNR_DIMM_CFG_DIMM3_REV_MASK           0x0000000010000000
+
+/*   SH_JNR_DIMM_CFG_DIMM3_CS                                           */
+/*   Description:  DIMM 3 chip select, addr[35:34] match                */
+#define SH_JNR_DIMM_CFG_DIMM3_CS_SHFT            29
+#define SH_JNR_DIMM_CFG_DIMM3_CS_MASK            0x0000000060000000
+
+/*   SH_JNR_DIMM_CFG_FREQ                                               */
+/*   Description:  DIMM frequency select                                */
+#define SH_JNR_DIMM_CFG_FREQ_SHFT                32
+#define SH_JNR_DIMM_CFG_FREQ_MASK                0x0000000f00000000
+
+/* ==================================================================== */
+/*                      Register "SH_X_PHASE_CFG"                       */
+/*                      AC Phase Config Registers                       */
+/* ==================================================================== */
+
+#define SH_X_PHASE_CFG                           0x0000000100010018
+#define SH_X_PHASE_CFG_MASK                      0x7fffffffffffffff
+#define SH_X_PHASE_CFG_INIT                      0x0000000000000000
+
+/*   SH_X_PHASE_CFG_LD_A                                                */
+/*   Description:  Address, control load core clock A latch             */
+#define SH_X_PHASE_CFG_LD_A_SHFT                 0
+#define SH_X_PHASE_CFG_LD_A_MASK                 0x000000000000001f
+
+/*   SH_X_PHASE_CFG_LD_B                                                */
+/*   Description:  Address, control load core clock B latch             */
+#define SH_X_PHASE_CFG_LD_B_SHFT                 5
+#define SH_X_PHASE_CFG_LD_B_MASK                 0x00000000000003e0
+
+/*   SH_X_PHASE_CFG_DQ_LD_A                                             */
+/*   Description:  DATA MCI load core clock A latch                     */
+#define SH_X_PHASE_CFG_DQ_LD_A_SHFT              10
+#define SH_X_PHASE_CFG_DQ_LD_A_MASK              0x0000000000007c00
+
+/*   SH_X_PHASE_CFG_DQ_LD_B                                             */
+/*   Description:  DATA MCI load core clock B latch                     */
+#define SH_X_PHASE_CFG_DQ_LD_B_SHFT              15
+#define SH_X_PHASE_CFG_DQ_LD_B_MASK              0x00000000000f8000
+
+/*   SH_X_PHASE_CFG_HOLD                                                */
+/*   Description:  Hold request on core clock phase                     */
+#define SH_X_PHASE_CFG_HOLD_SHFT                 20
+#define SH_X_PHASE_CFG_HOLD_MASK                 0x0000000001f00000
+
+/*   SH_X_PHASE_CFG_HOLD_REQ                                            */
+/*   Description:  Hold next request on core clock phase                */
+#define SH_X_PHASE_CFG_HOLD_REQ_SHFT             25
+#define SH_X_PHASE_CFG_HOLD_REQ_MASK             0x000000003e000000
+
+/*   SH_X_PHASE_CFG_ADD_CP                                              */
+/*   Description:  add delay clock period to dqct delay chain on phase  */
+#define SH_X_PHASE_CFG_ADD_CP_SHFT               30
+#define SH_X_PHASE_CFG_ADD_CP_MASK               0x00000007c0000000
+
+/*   SH_X_PHASE_CFG_BUBBLE_EN                                           */
+/*   Description:  bubble, idle core clock to wait for memory clock     */
+#define SH_X_PHASE_CFG_BUBBLE_EN_SHFT            35
+#define SH_X_PHASE_CFG_BUBBLE_EN_MASK            0x000000f800000000
+
+/*   SH_X_PHASE_CFG_PHA_BUBBLE                                          */
+/*   Description:  MMR phaseA bubble value                              */
+#define SH_X_PHASE_CFG_PHA_BUBBLE_SHFT           40
+#define SH_X_PHASE_CFG_PHA_BUBBLE_MASK           0x0000070000000000
+
+/*   SH_X_PHASE_CFG_PHB_BUBBLE                                          */
+/*   Description:  MMR phaseB bubble value                              */
+#define SH_X_PHASE_CFG_PHB_BUBBLE_SHFT           43
+#define SH_X_PHASE_CFG_PHB_BUBBLE_MASK           0x0000380000000000
+
+/*   SH_X_PHASE_CFG_PHC_BUBBLE                                          */
+/*   Description:  MMR phaseC bubble value                              */
+#define SH_X_PHASE_CFG_PHC_BUBBLE_SHFT           46
+#define SH_X_PHASE_CFG_PHC_BUBBLE_MASK           0x0001c00000000000
+
+/*   SH_X_PHASE_CFG_PHD_BUBBLE                                          */
+/*   Description:  MMR phaseD bubble value                              */
+#define SH_X_PHASE_CFG_PHD_BUBBLE_SHFT           49
+#define SH_X_PHASE_CFG_PHD_BUBBLE_MASK           0x000e000000000000
+
+/*   SH_X_PHASE_CFG_PHE_BUBBLE                                          */
+/*   Description:  MMR phaseE bubble value                              */
+#define SH_X_PHASE_CFG_PHE_BUBBLE_SHFT           52
+#define SH_X_PHASE_CFG_PHE_BUBBLE_MASK           0x0070000000000000
+
+/*   SH_X_PHASE_CFG_SEL_A                                               */
+/*   Description:  address,control select A memory clock latch          */
+#define SH_X_PHASE_CFG_SEL_A_SHFT                55
+#define SH_X_PHASE_CFG_SEL_A_MASK                0x0780000000000000
+
+/*   SH_X_PHASE_CFG_DQ_SEL_A                                            */
+/*   Description:  DATA MCI select A memory clock latch                 */
+#define SH_X_PHASE_CFG_DQ_SEL_A_SHFT             59
+#define SH_X_PHASE_CFG_DQ_SEL_A_MASK             0x7800000000000000
+
+/* ==================================================================== */
+/*                         Register "SH_X_CFG"                          */
+/*                         AC Config Registers                          */
+/* ==================================================================== */
+
+#define SH_X_CFG                                 0x0000000100010020
+#define SH_X_CFG_MASK                            0xffffffffffffffff
+#define SH_X_CFG_INIT                            0x108443103322100c
+
+/*   SH_X_CFG_MODE_SERIAL                                               */
+/*   Description:  Arbque arbitration in serial mode                    */
+#define SH_X_CFG_MODE_SERIAL_SHFT                0
+#define SH_X_CFG_MODE_SERIAL_MASK                0x0000000000000001
+
+/*   SH_X_CFG_DIRC_RANDOM_REPLACEMENT                                   */
+/*   Description:  Directory cache random replacement                   */
+#define SH_X_CFG_DIRC_RANDOM_REPLACEMENT_SHFT    1
+#define SH_X_CFG_DIRC_RANDOM_REPLACEMENT_MASK    0x0000000000000002
+
+/*   SH_X_CFG_DIR_COUNTER_INIT                                          */
+/*   Description:  Dir counter initial value                            */
+#define SH_X_CFG_DIR_COUNTER_INIT_SHFT           2
+#define SH_X_CFG_DIR_COUNTER_INIT_MASK           0x00000000000000fc
+
+/*   SH_X_CFG_TA_DLYS                                                   */
+/*   Description:  Turn around delays                                   */
+#define SH_X_CFG_TA_DLYS_SHFT                    8
+#define SH_X_CFG_TA_DLYS_MASK                    0x000000ffffffff00
+
+/*   SH_X_CFG_DA_BB_CLR                                                 */
+/*   Description:  Bank busy CPs for a data read request                */
+#define SH_X_CFG_DA_BB_CLR_SHFT                  40
+#define SH_X_CFG_DA_BB_CLR_MASK                  0x00000f0000000000
+
+/*   SH_X_CFG_DC_BB_CLR                                                 */
+/*   Description:  Bank busy CPs for a directory cache read request     */
+#define SH_X_CFG_DC_BB_CLR_SHFT                  44
+#define SH_X_CFG_DC_BB_CLR_MASK                  0x0000f00000000000
+
+/*   SH_X_CFG_WT_BB_CLR                                                 */
+/*   Description:  Bank busy CPs for all write request                  */
+#define SH_X_CFG_WT_BB_CLR_SHFT                  48
+#define SH_X_CFG_WT_BB_CLR_MASK                  0x000f000000000000
+
+/*   SH_X_CFG_SSO_WT_EN                                                 */
+/*   Description:  Simultaneous switching enabled on output data pins  */
+#define SH_X_CFG_SSO_WT_EN_SHFT                  52
+#define SH_X_CFG_SSO_WT_EN_MASK                  0x0010000000000000
+
+/*   SH_X_CFG_TRCD2_EN                                                  */
+/*   Description:  Trcd, ras to cas delay of 2 CPs enabled              */
+#define SH_X_CFG_TRCD2_EN_SHFT                   53
+#define SH_X_CFG_TRCD2_EN_MASK                   0x0020000000000000
+
+/*   SH_X_CFG_TRCD4_EN                                                  */
+/*   Description:  Trcd, ras to case delay of 4 CPs enabled             */
+#define SH_X_CFG_TRCD4_EN_SHFT                   54
+#define SH_X_CFG_TRCD4_EN_MASK                   0x0040000000000000
+
+/*   SH_X_CFG_REQ_CNTR_DIS                                              */
+/*   Description:  Request delay counter disabled                       */
+#define SH_X_CFG_REQ_CNTR_DIS_SHFT               55
+#define SH_X_CFG_REQ_CNTR_DIS_MASK               0x0080000000000000
+
+/*   SH_X_CFG_REQ_CNTR_VAL                                              */
+/*   Description:  Request counter delay value in CPs                   */
+#define SH_X_CFG_REQ_CNTR_VAL_SHFT               56
+#define SH_X_CFG_REQ_CNTR_VAL_MASK               0x3f00000000000000
+
+/*   SH_X_CFG_INV_CAS_ADDR                                              */
+/*   Description:  Invert cas address bits 3 to 7                       */
+#define SH_X_CFG_INV_CAS_ADDR_SHFT               62
+#define SH_X_CFG_INV_CAS_ADDR_MASK               0x4000000000000000
+
+/*   SH_X_CFG_CLR_DIR_CACHE                                             */
+/*   Description:  Clear directory cache tags                           */
+#define SH_X_CFG_CLR_DIR_CACHE_SHFT              63
+#define SH_X_CFG_CLR_DIR_CACHE_MASK              0x8000000000000000
+
+/* ==================================================================== */
+/*                       Register "SH_X_DQCT_CFG"                       */
+/*                         AC Config Registers                          */
+/* ==================================================================== */
+
+#define SH_X_DQCT_CFG                            0x0000000100010028
+#define SH_X_DQCT_CFG_MASK                       0x0000000000ffffff
+#define SH_X_DQCT_CFG_INIT                       0x0000000000585418
+
+/*   SH_X_DQCT_CFG_RD_SEL                                               */
+/*   Description:  Read data select                                     */
+#define SH_X_DQCT_CFG_RD_SEL_SHFT                0
+#define SH_X_DQCT_CFG_RD_SEL_MASK                0x000000000000000f
+
+/*   SH_X_DQCT_CFG_WT_SEL                                               */
+/*   Description:  Write data select                                    */
+#define SH_X_DQCT_CFG_WT_SEL_SHFT                4
+#define SH_X_DQCT_CFG_WT_SEL_MASK                0x00000000000000f0
+
+/*   SH_X_DQCT_CFG_DTA_RD_SEL                                           */
+/*   Description:  Data ready read select                               */
+#define SH_X_DQCT_CFG_DTA_RD_SEL_SHFT            8
+#define SH_X_DQCT_CFG_DTA_RD_SEL_MASK            0x0000000000000f00
+
+/*   SH_X_DQCT_CFG_DTA_WT_SEL                                           */
+/*   Description:  Data ready write select                              */
+#define SH_X_DQCT_CFG_DTA_WT_SEL_SHFT            12
+#define SH_X_DQCT_CFG_DTA_WT_SEL_MASK            0x000000000000f000
+
+/*   SH_X_DQCT_CFG_DIR_RD_SEL                                           */
+/*   Description:  Dir ready read select                                */
+#define SH_X_DQCT_CFG_DIR_RD_SEL_SHFT            16
+#define SH_X_DQCT_CFG_DIR_RD_SEL_MASK            0x00000000000f0000
+
+/*   SH_X_DQCT_CFG_MDIR_RD_SEL                                          */
+/*   Description:  Dir ready read select                                */
+#define SH_X_DQCT_CFG_MDIR_RD_SEL_SHFT           20
+#define SH_X_DQCT_CFG_MDIR_RD_SEL_MASK           0x0000000000f00000
+
+/* ==================================================================== */
+/*                   Register "SH_X_REFRESH_CONTROL"                    */
+/*                       Refresh Control Register                       */
+/* ==================================================================== */
+
+#define SH_X_REFRESH_CONTROL                     0x0000000100010030
+#define SH_X_REFRESH_CONTROL_MASK                0x000000000fffffff
+#define SH_X_REFRESH_CONTROL_INIT                0x00000000009cc300
+
+/*   SH_X_REFRESH_CONTROL_ENABLE                                        */
+/*   Description:  Refresh enable                                       */
+#define SH_X_REFRESH_CONTROL_ENABLE_SHFT         0
+#define SH_X_REFRESH_CONTROL_ENABLE_MASK         0x00000000000000ff
+
+/*   SH_X_REFRESH_CONTROL_INTERVAL                                      */
+/*   Description:  Refresh interval in core CPs                         */
+#define SH_X_REFRESH_CONTROL_INTERVAL_SHFT       8
+#define SH_X_REFRESH_CONTROL_INTERVAL_MASK       0x000000000001ff00
+
+/*   SH_X_REFRESH_CONTROL_HOLD                                          */
+/*   Description:  Refresh hold                                         */
+#define SH_X_REFRESH_CONTROL_HOLD_SHFT           17
+#define SH_X_REFRESH_CONTROL_HOLD_MASK           0x00000000007e0000
+
+/*   SH_X_REFRESH_CONTROL_INTERLEAVE                                    */
+/*   Description:  Refresh interleave                                   */
+#define SH_X_REFRESH_CONTROL_INTERLEAVE_SHFT     23
+#define SH_X_REFRESH_CONTROL_INTERLEAVE_MASK     0x0000000000800000
+
+/*   SH_X_REFRESH_CONTROL_HALF_RATE                                     */
+/*   Description:  Refresh half rate                                    */
+#define SH_X_REFRESH_CONTROL_HALF_RATE_SHFT      24
+#define SH_X_REFRESH_CONTROL_HALF_RATE_MASK      0x000000000f000000
+
+/* ==================================================================== */
+/*                      Register "SH_Y_PHASE_CFG"                       */
+/*                      AC Phase Config Registers                       */
+/* ==================================================================== */
+
+#define SH_Y_PHASE_CFG                           0x0000000100010038
+#define SH_Y_PHASE_CFG_MASK                      0x7fffffffffffffff
+#define SH_Y_PHASE_CFG_INIT                      0x0000000000000000
+
+/*   SH_Y_PHASE_CFG_LD_A                                                */
+/*   Description:  Address, control load core clock A latch             */
+#define SH_Y_PHASE_CFG_LD_A_SHFT                 0
+#define SH_Y_PHASE_CFG_LD_A_MASK                 0x000000000000001f
+
+/*   SH_Y_PHASE_CFG_LD_B                                                */
+/*   Description:  Address, control load core clock B latch             */
+#define SH_Y_PHASE_CFG_LD_B_SHFT                 5
+#define SH_Y_PHASE_CFG_LD_B_MASK                 0x00000000000003e0
+
+/*   SH_Y_PHASE_CFG_DQ_LD_A                                             */
+/*   Description:  DATA MCI load core clock A latch                     */
+#define SH_Y_PHASE_CFG_DQ_LD_A_SHFT              10
+#define SH_Y_PHASE_CFG_DQ_LD_A_MASK              0x0000000000007c00
+
+/*   SH_Y_PHASE_CFG_DQ_LD_B                                             */
+/*   Description:  DATA MCI load core clock B latch                     */
+#define SH_Y_PHASE_CFG_DQ_LD_B_SHFT              15
+#define SH_Y_PHASE_CFG_DQ_LD_B_MASK              0x00000000000f8000
+
+/*   SH_Y_PHASE_CFG_HOLD                                                */
+/*   Description:  Hold request on core clock phase                     */
+#define SH_Y_PHASE_CFG_HOLD_SHFT                 20
+#define SH_Y_PHASE_CFG_HOLD_MASK                 0x0000000001f00000
+
+/*   SH_Y_PHASE_CFG_HOLD_REQ                                            */
+/*   Description:  Hold next request on core clock phase                */
+#define SH_Y_PHASE_CFG_HOLD_REQ_SHFT             25
+#define SH_Y_PHASE_CFG_HOLD_REQ_MASK             0x000000003e000000
+
+/*   SH_Y_PHASE_CFG_ADD_CP                                              */
+/*   Description:  add delay clock period to dqct delay chain on phase  */
+#define SH_Y_PHASE_CFG_ADD_CP_SHFT               30
+#define SH_Y_PHASE_CFG_ADD_CP_MASK               0x00000007c0000000
+
+/*   SH_Y_PHASE_CFG_BUBBLE_EN                                           */
+/*   Description:  bubble, idle core clock to wait for memory clock     */
+#define SH_Y_PHASE_CFG_BUBBLE_EN_SHFT            35
+#define SH_Y_PHASE_CFG_BUBBLE_EN_MASK            0x000000f800000000
+
+/*   SH_Y_PHASE_CFG_PHA_BUBBLE                                          */
+/*   Description:  MMR phaseA bubble value                              */
+#define SH_Y_PHASE_CFG_PHA_BUBBLE_SHFT           40
+#define SH_Y_PHASE_CFG_PHA_BUBBLE_MASK           0x0000070000000000
+
+/*   SH_Y_PHASE_CFG_PHB_BUBBLE                                          */
+/*   Description:  MMR phaseB bubble value                              */
+#define SH_Y_PHASE_CFG_PHB_BUBBLE_SHFT           43
+#define SH_Y_PHASE_CFG_PHB_BUBBLE_MASK           0x0000380000000000
+
+/*   SH_Y_PHASE_CFG_PHC_BUBBLE                                          */
+/*   Description:  MMR phaseC bubble value                              */
+#define SH_Y_PHASE_CFG_PHC_BUBBLE_SHFT           46
+#define SH_Y_PHASE_CFG_PHC_BUBBLE_MASK           0x0001c00000000000
+
+/*   SH_Y_PHASE_CFG_PHD_BUBBLE                                          */
+/*   Description:  MMR phaseD bubble value                              */
+#define SH_Y_PHASE_CFG_PHD_BUBBLE_SHFT           49
+#define SH_Y_PHASE_CFG_PHD_BUBBLE_MASK           0x000e000000000000
+
+/*   SH_Y_PHASE_CFG_PHE_BUBBLE                                          */
+/*   Description:  MMR phaseE bubble value                              */
+#define SH_Y_PHASE_CFG_PHE_BUBBLE_SHFT           52
+#define SH_Y_PHASE_CFG_PHE_BUBBLE_MASK           0x0070000000000000
+
+/*   SH_Y_PHASE_CFG_SEL_A                                               */
+/*   Description:  address,control select A memory clock latch          */
+#define SH_Y_PHASE_CFG_SEL_A_SHFT                55
+#define SH_Y_PHASE_CFG_SEL_A_MASK                0x0780000000000000
+
+/*   SH_Y_PHASE_CFG_DQ_SEL_A                                            */
+/*   Description:  DATA MCI select A memory clock latch                 */
+#define SH_Y_PHASE_CFG_DQ_SEL_A_SHFT             59
+#define SH_Y_PHASE_CFG_DQ_SEL_A_MASK             0x7800000000000000
+
+/* ==================================================================== */
+/*                         Register "SH_Y_CFG"                          */
+/*                         AC Config Registers                          */
+/* ==================================================================== */
+
+#define SH_Y_CFG                                 0x0000000100010040
+#define SH_Y_CFG_MASK                            0xffffffffffffffff
+#define SH_Y_CFG_INIT                            0x108443103322100c
+
+/*   SH_Y_CFG_MODE_SERIAL                                               */
+/*   Description:  Arbque arbitration in serial mode                    */
+#define SH_Y_CFG_MODE_SERIAL_SHFT                0
+#define SH_Y_CFG_MODE_SERIAL_MASK                0x0000000000000001
+
+/*   SH_Y_CFG_DIRC_RANDOM_REPLACEMENT                                   */
+/*   Description:  Directory cache random replacement                   */
+#define SH_Y_CFG_DIRC_RANDOM_REPLACEMENT_SHFT    1
+#define SH_Y_CFG_DIRC_RANDOM_REPLACEMENT_MASK    0x0000000000000002
+
+/*   SH_Y_CFG_DIR_COUNTER_INIT                                          */
+/*   Description:  Dir counter initial value                            */
+#define SH_Y_CFG_DIR_COUNTER_INIT_SHFT           2
+#define SH_Y_CFG_DIR_COUNTER_INIT_MASK           0x00000000000000fc
+
+/*   SH_Y_CFG_TA_DLYS                                                   */
+/*   Description:  Turn around delays                                   */
+#define SH_Y_CFG_TA_DLYS_SHFT                    8
+#define SH_Y_CFG_TA_DLYS_MASK                    0x000000ffffffff00
+
+/*   SH_Y_CFG_DA_BB_CLR                                                 */
+/*   Description:  Bank busy CPs for a data read request                */
+#define SH_Y_CFG_DA_BB_CLR_SHFT                  40
+#define SH_Y_CFG_DA_BB_CLR_MASK                  0x00000f0000000000
+
+/*   SH_Y_CFG_DC_BB_CLR                                                 */
+/*   Description:  Bank busy CPs for a directory cache read request     */
+#define SH_Y_CFG_DC_BB_CLR_SHFT                  44
+#define SH_Y_CFG_DC_BB_CLR_MASK                  0x0000f00000000000
+
+/*   SH_Y_CFG_WT_BB_CLR                                                 */
+/*   Description:  Bank busy CPs for all write request                  */
+#define SH_Y_CFG_WT_BB_CLR_SHFT                  48
+#define SH_Y_CFG_WT_BB_CLR_MASK                  0x000f000000000000
+
+/*   SH_Y_CFG_SSO_WT_EN                                                 */
+/*   Description:  Simultaneous switching enabled on output data pins  */
+#define SH_Y_CFG_SSO_WT_EN_SHFT                  52
+#define SH_Y_CFG_SSO_WT_EN_MASK                  0x0010000000000000
+
+/*   SH_Y_CFG_TRCD2_EN                                                  */
+/*   Description:  Trcd, ras to cas delay of 2 CPs enabled              */
+#define SH_Y_CFG_TRCD2_EN_SHFT                   53
+#define SH_Y_CFG_TRCD2_EN_MASK                   0x0020000000000000
+
+/*   SH_Y_CFG_TRCD4_EN                                                  */
+/*   Description:  Trcd, ras to case delay of 4 CPs enabled             */
+#define SH_Y_CFG_TRCD4_EN_SHFT                   54
+#define SH_Y_CFG_TRCD4_EN_MASK                   0x0040000000000000
+
+/*   SH_Y_CFG_REQ_CNTR_DIS                                              */
+/*   Description:  Request delay counter disabled                       */
+#define SH_Y_CFG_REQ_CNTR_DIS_SHFT               55
+#define SH_Y_CFG_REQ_CNTR_DIS_MASK               0x0080000000000000
+
+/*   SH_Y_CFG_REQ_CNTR_VAL                                              */
+/*   Description:  Request counter delay value in CPs                   */
+#define SH_Y_CFG_REQ_CNTR_VAL_SHFT               56
+#define SH_Y_CFG_REQ_CNTR_VAL_MASK               0x3f00000000000000
+
+/*   SH_Y_CFG_INV_CAS_ADDR                                              */
+/*   Description:  Invert cas address bits 3 to 7                       */
+#define SH_Y_CFG_INV_CAS_ADDR_SHFT               62
+#define SH_Y_CFG_INV_CAS_ADDR_MASK               0x4000000000000000
+
+/*   SH_Y_CFG_CLR_DIR_CACHE                                             */
+/*   Description:  Clear directory cache tags                           */
+#define SH_Y_CFG_CLR_DIR_CACHE_SHFT              63
+#define SH_Y_CFG_CLR_DIR_CACHE_MASK              0x8000000000000000
+
+/* ==================================================================== */
+/*                       Register "SH_Y_DQCT_CFG"                       */
+/*                         AC Config Registers                          */
+/* ==================================================================== */
+
+#define SH_Y_DQCT_CFG                            0x0000000100010048
+#define SH_Y_DQCT_CFG_MASK                       0x0000000000ffffff
+#define SH_Y_DQCT_CFG_INIT                       0x0000000000585418
+
+/*   SH_Y_DQCT_CFG_RD_SEL                                               */
+/*   Description:  Read data select                                     */
+#define SH_Y_DQCT_CFG_RD_SEL_SHFT                0
+#define SH_Y_DQCT_CFG_RD_SEL_MASK                0x000000000000000f
+
+/*   SH_Y_DQCT_CFG_WT_SEL                                               */
+/*   Description:  Write data select                                    */
+#define SH_Y_DQCT_CFG_WT_SEL_SHFT                4
+#define SH_Y_DQCT_CFG_WT_SEL_MASK                0x00000000000000f0
+
+/*   SH_Y_DQCT_CFG_DTA_RD_SEL                                           */
+/*   Description:  Data ready read select                               */
+#define SH_Y_DQCT_CFG_DTA_RD_SEL_SHFT            8
+#define SH_Y_DQCT_CFG_DTA_RD_SEL_MASK            0x0000000000000f00
+
+/*   SH_Y_DQCT_CFG_DTA_WT_SEL                                           */
+/*   Description:  Data ready write select                              */
+#define SH_Y_DQCT_CFG_DTA_WT_SEL_SHFT            12
+#define SH_Y_DQCT_CFG_DTA_WT_SEL_MASK            0x000000000000f000
+
+/*   SH_Y_DQCT_CFG_DIR_RD_SEL                                           */
+/*   Description:  Dir ready read select                                */
+#define SH_Y_DQCT_CFG_DIR_RD_SEL_SHFT            16
+#define SH_Y_DQCT_CFG_DIR_RD_SEL_MASK            0x00000000000f0000
+
+/*   SH_Y_DQCT_CFG_MDIR_RD_SEL                                          */
+/*   Description:  Dir ready read select                                */
+#define SH_Y_DQCT_CFG_MDIR_RD_SEL_SHFT           20
+#define SH_Y_DQCT_CFG_MDIR_RD_SEL_MASK           0x0000000000f00000
+
+/* ==================================================================== */
+/*                   Register "SH_Y_REFRESH_CONTROL"                    */
+/*                       Refresh Control Register                       */
+/* ==================================================================== */
+
+#define SH_Y_REFRESH_CONTROL                     0x0000000100010050
+#define SH_Y_REFRESH_CONTROL_MASK                0x000000000fffffff
+#define SH_Y_REFRESH_CONTROL_INIT                0x00000000009cc300
+
+/*   SH_Y_REFRESH_CONTROL_ENABLE                                        */
+/*   Description:  Refresh enable                                       */
+#define SH_Y_REFRESH_CONTROL_ENABLE_SHFT         0
+#define SH_Y_REFRESH_CONTROL_ENABLE_MASK         0x00000000000000ff
+
+/*   SH_Y_REFRESH_CONTROL_INTERVAL                                      */
+/*   Description:  Refresh interval in core CPs                         */
+#define SH_Y_REFRESH_CONTROL_INTERVAL_SHFT       8
+#define SH_Y_REFRESH_CONTROL_INTERVAL_MASK       0x000000000001ff00
+
+/*   SH_Y_REFRESH_CONTROL_HOLD                                          */
+/*   Description:  Refresh hold                                         */
+#define SH_Y_REFRESH_CONTROL_HOLD_SHFT           17
+#define SH_Y_REFRESH_CONTROL_HOLD_MASK           0x00000000007e0000
+
+/*   SH_Y_REFRESH_CONTROL_INTERLEAVE                                    */
+/*   Description:  Refresh interleave                                   */
+#define SH_Y_REFRESH_CONTROL_INTERLEAVE_SHFT     23
+#define SH_Y_REFRESH_CONTROL_INTERLEAVE_MASK     0x0000000000800000
+
+/*   SH_Y_REFRESH_CONTROL_HALF_RATE                                     */
+/*   Description:  Refresh half rate                                    */
+#define SH_Y_REFRESH_CONTROL_HALF_RATE_SHFT      24
+#define SH_Y_REFRESH_CONTROL_HALF_RATE_MASK      0x000000000f000000
+
+/* ==================================================================== */
+/*                     Register "SH_MEM_RED_BLACK"                      */
+/*                     MD fairness watchdog timers                      */
+/* ==================================================================== */
+
+#define SH_MEM_RED_BLACK                         0x0000000100010058
+#define SH_MEM_RED_BLACK_MASK                    0x000fffffffffffff
+#define SH_MEM_RED_BLACK_INIT                    0x0000000040000400
+
+/*   SH_MEM_RED_BLACK_TIME                                              */
+/*   Description:  Clocks to tag references with a given color          */
+#define SH_MEM_RED_BLACK_TIME_SHFT               0
+#define SH_MEM_RED_BLACK_TIME_MASK               0x000000000000ffff
+
+/*   SH_MEM_RED_BLACK_ERR_TIME                                          */
+/*   Description:  Max clocks to wait after red/black change for old c  */
+/*  olor to clear.                                                      */
+#define SH_MEM_RED_BLACK_ERR_TIME_SHFT           16
+#define SH_MEM_RED_BLACK_ERR_TIME_MASK           0x000fffffffff0000
+
+/* ==================================================================== */
+/*                      Register "SH_MISC_MEM_CFG"                      */
+/* ==================================================================== */
+
+#define SH_MISC_MEM_CFG                          0x0000000100010060
+#define SH_MISC_MEM_CFG_MASK                     0x0013f1f1fff3f3ff
+#define SH_MISC_MEM_CFG_INIT                     0x0000000000010107
+
+/*   SH_MISC_MEM_CFG_EXPRESS_HEADER_ENABLE                              */
+/*   Description:  enables the use of express headers from md to pi     */
+#define SH_MISC_MEM_CFG_EXPRESS_HEADER_ENABLE_SHFT 0
+#define SH_MISC_MEM_CFG_EXPRESS_HEADER_ENABLE_MASK 0x0000000000000001
+
+/*   SH_MISC_MEM_CFG_SPEC_HEADER_ENABLE                                 */
+/*   Description:  enables the use of speculative headers from md to p  */
+#define SH_MISC_MEM_CFG_SPEC_HEADER_ENABLE_SHFT  1
+#define SH_MISC_MEM_CFG_SPEC_HEADER_ENABLE_MASK  0x0000000000000002
+
+/*   SH_MISC_MEM_CFG_JNR_BYPASS_ENABLE                                  */
+/*   Description:  enables bypass path for requests going through ac    */
+#define SH_MISC_MEM_CFG_JNR_BYPASS_ENABLE_SHFT   2
+#define SH_MISC_MEM_CFG_JNR_BYPASS_ENABLE_MASK   0x0000000000000004
+
+/*   SH_MISC_MEM_CFG_XN_RD_SAME_AS_PI                                   */
+/*   Description:  disables a one clock delay of XN read data           */
+#define SH_MISC_MEM_CFG_XN_RD_SAME_AS_PI_SHFT    3
+#define SH_MISC_MEM_CFG_XN_RD_SAME_AS_PI_MASK    0x0000000000000008
+
+/*   SH_MISC_MEM_CFG_LOW_WRITE_BUFFER_THRESHOLD                         */
+/*   Description:  point at which data writes get higher priority       */
+#define SH_MISC_MEM_CFG_LOW_WRITE_BUFFER_THRESHOLD_SHFT 4
+#define SH_MISC_MEM_CFG_LOW_WRITE_BUFFER_THRESHOLD_MASK 0x00000000000003f0
+
+/*   SH_MISC_MEM_CFG_LOW_VICTIM_BUFFER_THRESHOLD                        */
+/*   Description:  point at which dir cache writes get higher priority  */
+#define SH_MISC_MEM_CFG_LOW_VICTIM_BUFFER_THRESHOLD_SHFT 12
+#define SH_MISC_MEM_CFG_LOW_VICTIM_BUFFER_THRESHOLD_MASK 0x000000000003f000
+
+/*   SH_MISC_MEM_CFG_THROTTLE_CNT                                       */
+/*   Description:  number of clocks between accepting references        */
+#define SH_MISC_MEM_CFG_THROTTLE_CNT_SHFT        20
+#define SH_MISC_MEM_CFG_THROTTLE_CNT_MASK        0x000000000ff00000
+
+/*   SH_MISC_MEM_CFG_DISABLED_READ_TNUMS                                */
+/*   Description:  number of read tnums to take out of circulation      */
+#define SH_MISC_MEM_CFG_DISABLED_READ_TNUMS_SHFT 28
+#define SH_MISC_MEM_CFG_DISABLED_READ_TNUMS_MASK 0x00000001f0000000
+
+/*   SH_MISC_MEM_CFG_DISABLED_WRITE_TNUMS                               */
+/*   Description:  number of write tnums to take out of circulation     */
+#define SH_MISC_MEM_CFG_DISABLED_WRITE_TNUMS_SHFT 36
+#define SH_MISC_MEM_CFG_DISABLED_WRITE_TNUMS_MASK 0x000001f000000000
+
+/*   SH_MISC_MEM_CFG_DISABLED_VICTIMS                                   */
+/*   Description:  number of dir cache victim buffers to take out of c  */
+/*  irculation in each quadrant of the MD                               */
+#define SH_MISC_MEM_CFG_DISABLED_VICTIMS_SHFT    44
+#define SH_MISC_MEM_CFG_DISABLED_VICTIMS_MASK    0x0003f00000000000
+
+/*   SH_MISC_MEM_CFG_ALTERNATE_XN_RP_PLANE                              */
+/*   Description:  enables plane alternating for replies to XN          */
+#define SH_MISC_MEM_CFG_ALTERNATE_XN_RP_PLANE_SHFT 52
+#define SH_MISC_MEM_CFG_ALTERNATE_XN_RP_PLANE_MASK 0x0010000000000000
+
+/* ==================================================================== */
+/*                     Register "SH_PIO_RQ_CRD_CTL"                     */
+/*                  pio_rq Credit Circulation Control                   */
+/* ==================================================================== */
+
+#define SH_PIO_RQ_CRD_CTL                        0x0000000100010068
+#define SH_PIO_RQ_CRD_CTL_MASK                   0x000000000000003f
+#define SH_PIO_RQ_CRD_CTL_INIT                   0x0000000000000002
+
+/*   SH_PIO_RQ_CRD_CTL_DEPTH                                            */
+/*   Description:  Total depth of buffering (in sic packets)            */
+#define SH_PIO_RQ_CRD_CTL_DEPTH_SHFT             0
+#define SH_PIO_RQ_CRD_CTL_DEPTH_MASK             0x000000000000003f
+
+/* ==================================================================== */
+/*                    Register "SH_PI_MD_RQ_CRD_CTL"                    */
+/*                 pi_md_rq Credit Circulation Control                  */
+/* ==================================================================== */
+
+#define SH_PI_MD_RQ_CRD_CTL                      0x0000000100010070
+#define SH_PI_MD_RQ_CRD_CTL_MASK                 0x000000000000003f
+#define SH_PI_MD_RQ_CRD_CTL_INIT                 0x0000000000000008
+
+/*   SH_PI_MD_RQ_CRD_CTL_DEPTH                                          */
+/*   Description:  Total depth of buffering (in sic packets)            */
+#define SH_PI_MD_RQ_CRD_CTL_DEPTH_SHFT           0
+#define SH_PI_MD_RQ_CRD_CTL_DEPTH_MASK           0x000000000000003f
+
+/* ==================================================================== */
+/*                    Register "SH_PI_MD_RP_CRD_CTL"                    */
+/*                 pi_md_rp Credit Circulation Control                  */
+/* ==================================================================== */
+
+#define SH_PI_MD_RP_CRD_CTL                      0x0000000100010078
+#define SH_PI_MD_RP_CRD_CTL_MASK                 0x000000000000003f
+#define SH_PI_MD_RP_CRD_CTL_INIT                 0x0000000000000004
+
+/*   SH_PI_MD_RP_CRD_CTL_DEPTH                                          */
+/*   Description:  Total depth of buffering (in sic packets)            */
+#define SH_PI_MD_RP_CRD_CTL_DEPTH_SHFT           0
+#define SH_PI_MD_RP_CRD_CTL_DEPTH_MASK           0x000000000000003f
+
+/* ==================================================================== */
+/*                    Register "SH_XN_MD_RQ_CRD_CTL"                    */
+/*                 xn_md_rq Credit Circulation Control                  */
+/* ==================================================================== */
+
+#define SH_XN_MD_RQ_CRD_CTL                      0x0000000100010080
+#define SH_XN_MD_RQ_CRD_CTL_MASK                 0x000000000000003f
+#define SH_XN_MD_RQ_CRD_CTL_INIT                 0x0000000000000008
+
+/*   SH_XN_MD_RQ_CRD_CTL_DEPTH                                          */
+/*   Description:  Total depth of buffering (in sic packets)            */
+#define SH_XN_MD_RQ_CRD_CTL_DEPTH_SHFT           0
+#define SH_XN_MD_RQ_CRD_CTL_DEPTH_MASK           0x000000000000003f
+
+/* ==================================================================== */
+/*                    Register "SH_XN_MD_RP_CRD_CTL"                    */
+/*                 xn_md_rp Credit Circulation Control                  */
+/* ==================================================================== */
+
+#define SH_XN_MD_RP_CRD_CTL                      0x0000000100010088
+#define SH_XN_MD_RP_CRD_CTL_MASK                 0x000000000000003f
+#define SH_XN_MD_RP_CRD_CTL_INIT                 0x0000000000000004
+
+/*   SH_XN_MD_RP_CRD_CTL_DEPTH                                          */
+/*   Description:  Total depth of buffering (in sic packets)            */
+#define SH_XN_MD_RP_CRD_CTL_DEPTH_SHFT           0
+#define SH_XN_MD_RP_CRD_CTL_DEPTH_MASK           0x000000000000003f
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG0"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_X_TAG0                                0x0000000100020000
+#define SH_X_TAG0_MASK                           0x00000000000fffff
+#define SH_X_TAG0_INIT                           0x0000000000000000
+
+/*   SH_X_TAG0_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_X_TAG0_TAG_SHFT                       0
+#define SH_X_TAG0_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG1"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_X_TAG1                                0x0000000100020008
+#define SH_X_TAG1_MASK                           0x00000000000fffff
+#define SH_X_TAG1_INIT                           0x0000000000000000
+
+/*   SH_X_TAG1_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_X_TAG1_TAG_SHFT                       0
+#define SH_X_TAG1_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG2"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_X_TAG2                                0x0000000100020010
+#define SH_X_TAG2_MASK                           0x00000000000fffff
+#define SH_X_TAG2_INIT                           0x0000000000000000
+
+/*   SH_X_TAG2_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_X_TAG2_TAG_SHFT                       0
+#define SH_X_TAG2_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG3"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_X_TAG3                                0x0000000100020018
+#define SH_X_TAG3_MASK                           0x00000000000fffff
+#define SH_X_TAG3_INIT                           0x0000000000000000
+
+/*   SH_X_TAG3_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_X_TAG3_TAG_SHFT                       0
+#define SH_X_TAG3_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG4"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_X_TAG4                                0x0000000100020020
+#define SH_X_TAG4_MASK                           0x00000000000fffff
+#define SH_X_TAG4_INIT                           0x0000000000000000
+
+/*   SH_X_TAG4_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_X_TAG4_TAG_SHFT                       0
+#define SH_X_TAG4_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG5"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_X_TAG5                                0x0000000100020028
+#define SH_X_TAG5_MASK                           0x00000000000fffff
+#define SH_X_TAG5_INIT                           0x0000000000000000
+
+/*   SH_X_TAG5_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_X_TAG5_TAG_SHFT                       0
+#define SH_X_TAG5_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG6"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_X_TAG6                                0x0000000100020030
+#define SH_X_TAG6_MASK                           0x00000000000fffff
+#define SH_X_TAG6_INIT                           0x0000000000000000
+
+/*   SH_X_TAG6_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_X_TAG6_TAG_SHFT                       0
+#define SH_X_TAG6_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG7"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_X_TAG7                                0x0000000100020038
+#define SH_X_TAG7_MASK                           0x00000000000fffff
+#define SH_X_TAG7_INIT                           0x0000000000000000
+
+/*   SH_X_TAG7_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_X_TAG7_TAG_SHFT                       0
+#define SH_X_TAG7_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG0"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_Y_TAG0                                0x0000000100020040
+#define SH_Y_TAG0_MASK                           0x00000000000fffff
+#define SH_Y_TAG0_INIT                           0x0000000000000000
+
+/*   SH_Y_TAG0_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_Y_TAG0_TAG_SHFT                       0
+#define SH_Y_TAG0_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG1"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_Y_TAG1                                0x0000000100020048
+#define SH_Y_TAG1_MASK                           0x00000000000fffff
+#define SH_Y_TAG1_INIT                           0x0000000000000000
+
+/*   SH_Y_TAG1_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_Y_TAG1_TAG_SHFT                       0
+#define SH_Y_TAG1_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG2"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_Y_TAG2                                0x0000000100020050
+#define SH_Y_TAG2_MASK                           0x00000000000fffff
+#define SH_Y_TAG2_INIT                           0x0000000000000000
+
+/*   SH_Y_TAG2_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_Y_TAG2_TAG_SHFT                       0
+#define SH_Y_TAG2_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG3"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_Y_TAG3                                0x0000000100020058
+#define SH_Y_TAG3_MASK                           0x00000000000fffff
+#define SH_Y_TAG3_INIT                           0x0000000000000000
+
+/*   SH_Y_TAG3_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_Y_TAG3_TAG_SHFT                       0
+#define SH_Y_TAG3_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG4"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_Y_TAG4                                0x0000000100020060
+#define SH_Y_TAG4_MASK                           0x00000000000fffff
+#define SH_Y_TAG4_INIT                           0x0000000000000000
+
+/*   SH_Y_TAG4_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_Y_TAG4_TAG_SHFT                       0
+#define SH_Y_TAG4_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG5"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_Y_TAG5                                0x0000000100020068
+#define SH_Y_TAG5_MASK                           0x00000000000fffff
+#define SH_Y_TAG5_INIT                           0x0000000000000000
+
+/*   SH_Y_TAG5_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_Y_TAG5_TAG_SHFT                       0
+#define SH_Y_TAG5_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG6"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_Y_TAG6                                0x0000000100020070
+#define SH_Y_TAG6_MASK                           0x00000000000fffff
+#define SH_Y_TAG6_INIT                           0x0000000000000000
+
+/*   SH_Y_TAG6_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_Y_TAG6_TAG_SHFT                       0
+#define SH_Y_TAG6_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG7"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#define SH_Y_TAG7                                0x0000000100020078
+#define SH_Y_TAG7_MASK                           0x00000000000fffff
+#define SH_Y_TAG7_INIT                           0x0000000000000000
+
+/*   SH_Y_TAG7_TAG                                                      */
+/*   Description:  Valid + Tag Address                                  */
+#define SH_Y_TAG7_TAG_SHFT                       0
+#define SH_Y_TAG7_TAG_MASK                       0x00000000000fffff
+
+/* ==================================================================== */
+/*                      Register "SH_MMRBIST_BASE"                      */
+/*                        mmr/bist base address                         */
+/* ==================================================================== */
+
+#define SH_MMRBIST_BASE                          0x0000000100020080
+#define SH_MMRBIST_BASE_MASK                     0x0003fffffffffff8
+#define SH_MMRBIST_BASE_INIT                     0x0000000000000000
+
+/*   SH_MMRBIST_BASE_DWORD_ADDR                                         */
+/*   Description:  bits 49:3 of the memory address                      */
+#define SH_MMRBIST_BASE_DWORD_ADDR_SHFT          3
+#define SH_MMRBIST_BASE_DWORD_ADDR_MASK          0x0003fffffffffff8
+
+/* ==================================================================== */
+/*                      Register "SH_MMRBIST_CTL"                       */
+/*                          Bist base address                           */
+/* ==================================================================== */
+
+#define SH_MMRBIST_CTL                           0x0000000100020088
+#define SH_MMRBIST_CTL_MASK                      0x0000177f7fffffff
+#define SH_MMRBIST_CTL_INIT                      0x0000000000000000
+
+/*   SH_MMRBIST_CTL_BLOCK_LENGTH                                        */
+/*   Description:  number of dwords in operation                        */
+#define SH_MMRBIST_CTL_BLOCK_LENGTH_SHFT         0
+#define SH_MMRBIST_CTL_BLOCK_LENGTH_MASK         0x000000007fffffff
+
+/*   SH_MMRBIST_CTL_CMD                                                 */
+/*   Description:  mmr/bist function                                    */
+#define SH_MMRBIST_CTL_CMD_SHFT                  32
+#define SH_MMRBIST_CTL_CMD_MASK                  0x0000007f00000000
+
+/*   SH_MMRBIST_CTL_IN_PROGRESS                                         */
+/*   Description:  writing a 1 starts operation, hardware clears on co  */
+/*  mpletion                                                            */
+#define SH_MMRBIST_CTL_IN_PROGRESS_SHFT          40
+#define SH_MMRBIST_CTL_IN_PROGRESS_MASK          0x0000010000000000
+
+/*   SH_MMRBIST_CTL_FAIL                                                */
+/*   Description:  mmr/bist had a data or address error                 */
+#define SH_MMRBIST_CTL_FAIL_SHFT                 41
+#define SH_MMRBIST_CTL_FAIL_MASK                 0x0000020000000000
+
+/*   SH_MMRBIST_CTL_MEM_IDLE                                            */
+/*   Description:  all memory activity is complete                      */
+#define SH_MMRBIST_CTL_MEM_IDLE_SHFT             42
+#define SH_MMRBIST_CTL_MEM_IDLE_MASK             0x0000040000000000
+
+/*   SH_MMRBIST_CTL_RESET_STATE                                         */
+/*   Description:  writing a 1 resets mmrbist hardware, hardware clear  */
+/*  s on completion                                                     */
+#define SH_MMRBIST_CTL_RESET_STATE_SHFT          44
+#define SH_MMRBIST_CTL_RESET_STATE_MASK          0x0000100000000000
+
+/* ==================================================================== */
+/*                    Register "SH_MD_DBUG_DATA_CFG"                    */
+/*                configuration for md debug data muxes                 */
+/* ==================================================================== */
+
+#define SH_MD_DBUG_DATA_CFG                      0x0000000100020100
+#define SH_MD_DBUG_DATA_CFG_MASK                 0x7777777777777777
+#define SH_MD_DBUG_DATA_CFG_INIT                 0x0000000000000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE0_CHIPLET                                */
+/*   Description:  selects which md chiplet drives nibble0              */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE0_CHIPLET_SHFT 0
+#define SH_MD_DBUG_DATA_CFG_NIBBLE0_CHIPLET_MASK 0x0000000000000007
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE0_NIBBLE                                 */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE0_NIBBLE_SHFT  4
+#define SH_MD_DBUG_DATA_CFG_NIBBLE0_NIBBLE_MASK  0x0000000000000070
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE1_CHIPLET                                */
+/*   Description:  selects which md chiplet drives nibble1              */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE1_CHIPLET_SHFT 8
+#define SH_MD_DBUG_DATA_CFG_NIBBLE1_CHIPLET_MASK 0x0000000000000700
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE1_NIBBLE                                 */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE1_NIBBLE_SHFT  12
+#define SH_MD_DBUG_DATA_CFG_NIBBLE1_NIBBLE_MASK  0x0000000000007000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE2_CHIPLET                                */
+/*   Description:  selects which md chiplet drives nibble2              */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE2_CHIPLET_SHFT 16
+#define SH_MD_DBUG_DATA_CFG_NIBBLE2_CHIPLET_MASK 0x0000000000070000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE2_NIBBLE                                 */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE2_NIBBLE_SHFT  20
+#define SH_MD_DBUG_DATA_CFG_NIBBLE2_NIBBLE_MASK  0x0000000000700000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE3_CHIPLET                                */
+/*   Description:  selects which md chiplet drives nibble3              */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE3_CHIPLET_SHFT 24
+#define SH_MD_DBUG_DATA_CFG_NIBBLE3_CHIPLET_MASK 0x0000000007000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE3_NIBBLE                                 */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE3_NIBBLE_SHFT  28
+#define SH_MD_DBUG_DATA_CFG_NIBBLE3_NIBBLE_MASK  0x0000000070000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE4_CHIPLET                                */
+/*   Description:  selects which md chiplet drives nibble4              */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE4_CHIPLET_SHFT 32
+#define SH_MD_DBUG_DATA_CFG_NIBBLE4_CHIPLET_MASK 0x0000000700000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE4_NIBBLE                                 */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE4_NIBBLE_SHFT  36
+#define SH_MD_DBUG_DATA_CFG_NIBBLE4_NIBBLE_MASK  0x0000007000000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE5_CHIPLET                                */
+/*   Description:  selects which md chiplet drives nibble5              */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE5_CHIPLET_SHFT 40
+#define SH_MD_DBUG_DATA_CFG_NIBBLE5_CHIPLET_MASK 0x0000070000000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE5_NIBBLE                                 */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE5_NIBBLE_SHFT  44
+#define SH_MD_DBUG_DATA_CFG_NIBBLE5_NIBBLE_MASK  0x0000700000000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE6_CHIPLET                                */
+/*   Description:  selects which md chiplet drives nibble6              */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE6_CHIPLET_SHFT 48
+#define SH_MD_DBUG_DATA_CFG_NIBBLE6_CHIPLET_MASK 0x0007000000000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE6_NIBBLE                                 */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE6_NIBBLE_SHFT  52
+#define SH_MD_DBUG_DATA_CFG_NIBBLE6_NIBBLE_MASK  0x0070000000000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE7_CHIPLET                                */
+/*   Description:  selects which md chiplet drives nibble7              */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE7_CHIPLET_SHFT 56
+#define SH_MD_DBUG_DATA_CFG_NIBBLE7_CHIPLET_MASK 0x0700000000000000
+
+/*   SH_MD_DBUG_DATA_CFG_NIBBLE7_NIBBLE                                 */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_DATA_CFG_NIBBLE7_NIBBLE_SHFT  60
+#define SH_MD_DBUG_DATA_CFG_NIBBLE7_NIBBLE_MASK  0x7000000000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DBUG_TRIGGER_CFG"                   */
+/*                 configuration for md debug triggers                  */
+/* ==================================================================== */
+
+#define SH_MD_DBUG_TRIGGER_CFG                   0x0000000100020108
+#define SH_MD_DBUG_TRIGGER_CFG_MASK              0xf777777777777777
+#define SH_MD_DBUG_TRIGGER_CFG_INIT              0x0000000000000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE0_CHIPLET                             */
+/*   Description:  selects which md chiplet drives nibble0              */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE0_CHIPLET_SHFT 0
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE0_CHIPLET_MASK 0x0000000000000007
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE0_NIBBLE                              */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE0_NIBBLE_SHFT 4
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE0_NIBBLE_MASK 0x0000000000000070
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE1_CHIPLET                             */
+/*   Description:  selects which md chiplet drives nibble1              */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE1_CHIPLET_SHFT 8
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE1_CHIPLET_MASK 0x0000000000000700
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE1_NIBBLE                              */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE1_NIBBLE_SHFT 12
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE1_NIBBLE_MASK 0x0000000000007000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE2_CHIPLET                             */
+/*   Description:  selects which md chiplet drives nibble2              */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE2_CHIPLET_SHFT 16
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE2_CHIPLET_MASK 0x0000000000070000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE2_NIBBLE                              */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE2_NIBBLE_SHFT 20
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE2_NIBBLE_MASK 0x0000000000700000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE3_CHIPLET                             */
+/*   Description:  selects which md chiplet drives nibble3              */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE3_CHIPLET_SHFT 24
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE3_CHIPLET_MASK 0x0000000007000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE3_NIBBLE                              */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE3_NIBBLE_SHFT 28
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE3_NIBBLE_MASK 0x0000000070000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE4_CHIPLET                             */
+/*   Description:  selects which md chiplet drives nibble4              */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE4_CHIPLET_SHFT 32
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE4_CHIPLET_MASK 0x0000000700000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE4_NIBBLE                              */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE4_NIBBLE_SHFT 36
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE4_NIBBLE_MASK 0x0000007000000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE5_CHIPLET                             */
+/*   Description:  selects which md chiplet drives nibble5              */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE5_CHIPLET_SHFT 40
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE5_CHIPLET_MASK 0x0000070000000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE5_NIBBLE                              */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE5_NIBBLE_SHFT 44
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE5_NIBBLE_MASK 0x0000700000000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE6_CHIPLET                             */
+/*   Description:  selects which md chiplet drives nibble6              */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE6_CHIPLET_SHFT 48
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE6_CHIPLET_MASK 0x0007000000000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE6_NIBBLE                              */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE6_NIBBLE_SHFT 52
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE6_NIBBLE_MASK 0x0070000000000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE7_CHIPLET                             */
+/*   Description:  selects which md chiplet drives nibble7              */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE7_CHIPLET_SHFT 56
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE7_CHIPLET_MASK 0x0700000000000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_NIBBLE7_NIBBLE                              */
+/*   Description:  selects which nibble from selected chiplet drives n  */
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE7_NIBBLE_SHFT 60
+#define SH_MD_DBUG_TRIGGER_CFG_NIBBLE7_NIBBLE_MASK 0x7000000000000000
+
+/*   SH_MD_DBUG_TRIGGER_CFG_ENABLE                                      */
+/*   Description:  enables triggering on pattern match                  */
+#define SH_MD_DBUG_TRIGGER_CFG_ENABLE_SHFT       63
+#define SH_MD_DBUG_TRIGGER_CFG_ENABLE_MASK       0x8000000000000000
+
+/* ==================================================================== */
+/*                    Register "SH_MD_DBUG_COMPARE"                     */
+/*                  md debug compare pattern and mask                   */
+/* ==================================================================== */
+
+#define SH_MD_DBUG_COMPARE                       0x0000000100020110
+#define SH_MD_DBUG_COMPARE_MASK                  0xffffffffffffffff
+#define SH_MD_DBUG_COMPARE_INIT                  0x0000000000000000
+
+/*   SH_MD_DBUG_COMPARE_PATTERN                                         */
+/*   Description:  pattern against which to compare dbug data for trig  */
+#define SH_MD_DBUG_COMPARE_PATTERN_SHFT          0
+#define SH_MD_DBUG_COMPARE_PATTERN_MASK          0x00000000ffffffff
+
+/*   SH_MD_DBUG_COMPARE_MASK                                            */
+/*   Description:  bits to include in compare of dbug data for trigger  */
+#define SH_MD_DBUG_COMPARE_MASK_SHFT             32
+#define SH_MD_DBUG_COMPARE_MASK_MASK             0xffffffff00000000
+
+/* ==================================================================== */
+/*                     Register "SH_X_MOD_DBUG_SEL"                     */
+/*                         MD acx debug select                          */
+/* ==================================================================== */
+
+#define SH_X_MOD_DBUG_SEL                        0x0000000100020118
+#define SH_X_MOD_DBUG_SEL_MASK                   0x03ffffffffffffff
+#define SH_X_MOD_DBUG_SEL_INIT                   0x0000000000000000
+
+/*   SH_X_MOD_DBUG_SEL_TAG_SEL                                          */
+/*   Description:  tagmgr select                                        */
+#define SH_X_MOD_DBUG_SEL_TAG_SEL_SHFT           0
+#define SH_X_MOD_DBUG_SEL_TAG_SEL_MASK           0x00000000000000ff
+
+/*   SH_X_MOD_DBUG_SEL_WBQ_SEL                                          */
+/*   Description:  wbqtg select                                         */
+#define SH_X_MOD_DBUG_SEL_WBQ_SEL_SHFT           8
+#define SH_X_MOD_DBUG_SEL_WBQ_SEL_MASK           0x000000000000ff00
+
+/*   SH_X_MOD_DBUG_SEL_ARB_SEL                                          */
+/*   Description:  arbque select                                        */
+#define SH_X_MOD_DBUG_SEL_ARB_SEL_SHFT           16
+#define SH_X_MOD_DBUG_SEL_ARB_SEL_MASK           0x0000000000ff0000
+
+/*   SH_X_MOD_DBUG_SEL_ATL_SEL                                          */
+/*   Description:  aintl select                                         */
+#define SH_X_MOD_DBUG_SEL_ATL_SEL_SHFT           24
+#define SH_X_MOD_DBUG_SEL_ATL_SEL_MASK           0x00000007ff000000
+
+/*   SH_X_MOD_DBUG_SEL_ATR_SEL                                          */
+/*   Description:  aintr select                                         */
+#define SH_X_MOD_DBUG_SEL_ATR_SEL_SHFT           35
+#define SH_X_MOD_DBUG_SEL_ATR_SEL_MASK           0x00003ff800000000
+
+/*   SH_X_MOD_DBUG_SEL_DQL_SEL                                          */
+/*   Description:  dqctr select                                         */
+#define SH_X_MOD_DBUG_SEL_DQL_SEL_SHFT           46
+#define SH_X_MOD_DBUG_SEL_DQL_SEL_MASK           0x000fc00000000000
+
+/*   SH_X_MOD_DBUG_SEL_DQR_SEL                                          */
+/*   Description:  dqctl select                                         */
+#define SH_X_MOD_DBUG_SEL_DQR_SEL_SHFT           52
+#define SH_X_MOD_DBUG_SEL_DQR_SEL_MASK           0x03f0000000000000
+
+/* ==================================================================== */
+/*                       Register "SH_X_DBUG_SEL"                       */
+/*                         MD acx debug select                          */
+/* ==================================================================== */
+
+#define SH_X_DBUG_SEL                            0x0000000100020120
+#define SH_X_DBUG_SEL_MASK                       0x0000000000ffffff
+#define SH_X_DBUG_SEL_INIT                       0x0000000000000000
+
+/*   SH_X_DBUG_SEL_DBG_SEL                                              */
+/*   Description:  debug select                                         */
+#define SH_X_DBUG_SEL_DBG_SEL_SHFT               0
+#define SH_X_DBUG_SEL_DBG_SEL_MASK               0x0000000000ffffff
+
+/* ==================================================================== */
+/*                      Register "SH_X_LADDR_CMP"                       */
+/*                        MD acx address compare                        */
+/* ==================================================================== */
+
+#define SH_X_LADDR_CMP                           0x0000000100020128
+#define SH_X_LADDR_CMP_MASK                      0x0fffffff0fffffff
+#define SH_X_LADDR_CMP_INIT                      0x0000000000000000
+
+/*   SH_X_LADDR_CMP_CMP_VAL                                             */
+/*   Description:  Compare value                                        */
+#define SH_X_LADDR_CMP_CMP_VAL_SHFT              0
+#define SH_X_LADDR_CMP_CMP_VAL_MASK              0x000000000fffffff
+
+/*   SH_X_LADDR_CMP_MASK_VAL                                            */
+/*   Description:  Mask value                                           */
+#define SH_X_LADDR_CMP_MASK_VAL_SHFT             32
+#define SH_X_LADDR_CMP_MASK_VAL_MASK             0x0fffffff00000000
+
+/* ==================================================================== */
+/*                      Register "SH_X_RADDR_CMP"                       */
+/*                        MD acx address compare                        */
+/* ==================================================================== */
+
+#define SH_X_RADDR_CMP                           0x0000000100020130
+#define SH_X_RADDR_CMP_MASK                      0x0fffffff0fffffff
+#define SH_X_RADDR_CMP_INIT                      0x0000000000000000
+
+/*   SH_X_RADDR_CMP_CMP_VAL                                             */
+/*   Description:  Compare value                                        */
+#define SH_X_RADDR_CMP_CMP_VAL_SHFT              0
+#define SH_X_RADDR_CMP_CMP_VAL_MASK              0x000000000fffffff
+
+/*   SH_X_RADDR_CMP_MASK_VAL                                            */
+/*   Description:  Mask value                                           */
+#define SH_X_RADDR_CMP_MASK_VAL_SHFT             32
+#define SH_X_RADDR_CMP_MASK_VAL_MASK             0x0fffffff00000000
+
+/* ==================================================================== */
+/*                       Register "SH_X_TAG_CMP"                        */
+/*                        MD acx tagmgr compare                         */
+/* ==================================================================== */
+
+#define SH_X_TAG_CMP                             0x0000000100020138
+#define SH_X_TAG_CMP_MASK                        0x007fffffffffffff
+#define SH_X_TAG_CMP_INIT                        0x0000000000000000
+
+/*   SH_X_TAG_CMP_CMD                                                   */
+/*   Description:  Command compare value                                */
+#define SH_X_TAG_CMP_CMD_SHFT                    0
+#define SH_X_TAG_CMP_CMD_MASK                    0x00000000000000ff
+
+/*   SH_X_TAG_CMP_ADDR                                                  */
+/*   Description:  Address compare value                                */
+#define SH_X_TAG_CMP_ADDR_SHFT                   8
+#define SH_X_TAG_CMP_ADDR_MASK                   0x000001ffffffff00
+
+/*   SH_X_TAG_CMP_SRC                                                   */
+/*   Description:  Source compare value                                 */
+#define SH_X_TAG_CMP_SRC_SHFT                    41
+#define SH_X_TAG_CMP_SRC_MASK                    0x007ffe0000000000
+
+/* ==================================================================== */
+/*                       Register "SH_X_TAG_MASK"                       */
+/*                          MD acx tagmgr mask                          */
+/* ==================================================================== */
+
+#define SH_X_TAG_MASK                            0x0000000100020140
+#define SH_X_TAG_MASK_MASK                       0x007fffffffffffff
+#define SH_X_TAG_MASK_INIT                       0x0000000000000000
+
+/*   SH_X_TAG_MASK_CMD                                                  */
+/*   Description:  Command compare value                                */
+#define SH_X_TAG_MASK_CMD_SHFT                   0
+#define SH_X_TAG_MASK_CMD_MASK                   0x00000000000000ff
+
+/*   SH_X_TAG_MASK_ADDR                                                 */
+/*   Description:  Address compare value                                */
+#define SH_X_TAG_MASK_ADDR_SHFT                  8
+#define SH_X_TAG_MASK_ADDR_MASK                  0x000001ffffffff00
+
+/*   SH_X_TAG_MASK_SRC                                                  */
+/*   Description:  Source compare value                                 */
+#define SH_X_TAG_MASK_SRC_SHFT                   41
+#define SH_X_TAG_MASK_SRC_MASK                   0x007ffe0000000000
+
+/* ==================================================================== */
+/*                     Register "SH_Y_MOD_DBUG_SEL"                     */
+/*                         MD acy debug select                          */
+/* ==================================================================== */
+
+#define SH_Y_MOD_DBUG_SEL                        0x0000000100020148
+#define SH_Y_MOD_DBUG_SEL_MASK                   0x03ffffffffffffff
+#define SH_Y_MOD_DBUG_SEL_INIT                   0x0000000000000000
+
+/*   SH_Y_MOD_DBUG_SEL_TAG_SEL                                          */
+/*   Description:  tagmgr select                                        */
+#define SH_Y_MOD_DBUG_SEL_TAG_SEL_SHFT           0
+#define SH_Y_MOD_DBUG_SEL_TAG_SEL_MASK           0x00000000000000ff
+
+/*   SH_Y_MOD_DBUG_SEL_WBQ_SEL                                          */
+/*   Description:  wbqtg select                                         */
+#define SH_Y_MOD_DBUG_SEL_WBQ_SEL_SHFT           8
+#define SH_Y_MOD_DBUG_SEL_WBQ_SEL_MASK           0x000000000000ff00
+
+/*   SH_Y_MOD_DBUG_SEL_ARB_SEL                                          */
+/*   Description:  arbque select                                        */
+#define SH_Y_MOD_DBUG_SEL_ARB_SEL_SHFT           16
+#define SH_Y_MOD_DBUG_SEL_ARB_SEL_MASK           0x0000000000ff0000
+
+/*   SH_Y_MOD_DBUG_SEL_ATL_SEL                                          */
+/*   Description:  aintl select                                         */
+#define SH_Y_MOD_DBUG_SEL_ATL_SEL_SHFT           24
+#define SH_Y_MOD_DBUG_SEL_ATL_SEL_MASK           0x00000007ff000000
+
+/*   SH_Y_MOD_DBUG_SEL_ATR_SEL                                          */
+/*   Description:  aintr select                                         */
+#define SH_Y_MOD_DBUG_SEL_ATR_SEL_SHFT           35
+#define SH_Y_MOD_DBUG_SEL_ATR_SEL_MASK           0x00003ff800000000
+
+/*   SH_Y_MOD_DBUG_SEL_DQL_SEL                                          */
+/*   Description:  dqctr select                                         */
+#define SH_Y_MOD_DBUG_SEL_DQL_SEL_SHFT           46
+#define SH_Y_MOD_DBUG_SEL_DQL_SEL_MASK           0x000fc00000000000
+
+/*   SH_Y_MOD_DBUG_SEL_DQR_SEL                                          */
+/*   Description:  dqctl select                                         */
+#define SH_Y_MOD_DBUG_SEL_DQR_SEL_SHFT           52
+#define SH_Y_MOD_DBUG_SEL_DQR_SEL_MASK           0x03f0000000000000
+
+/* ==================================================================== */
+/*                       Register "SH_Y_DBUG_SEL"                       */
+/*                         MD acy debug select                          */
+/* ==================================================================== */
+
+#define SH_Y_DBUG_SEL                            0x0000000100020150
+#define SH_Y_DBUG_SEL_MASK                       0x0000000000ffffff
+#define SH_Y_DBUG_SEL_INIT                       0x0000000000000000
+
+/*   SH_Y_DBUG_SEL_DBG_SEL                                              */
+/*   Description:  debug select                                         */
+#define SH_Y_DBUG_SEL_DBG_SEL_SHFT               0
+#define SH_Y_DBUG_SEL_DBG_SEL_MASK               0x0000000000ffffff
+
+/* ==================================================================== */
+/*                      Register "SH_Y_LADDR_CMP"                       */
+/*                        MD acy address compare                        */
+/* ==================================================================== */
+
+#define SH_Y_LADDR_CMP                           0x0000000100020158
+#define SH_Y_LADDR_CMP_MASK                      0x0fffffff0fffffff
+#define SH_Y_LADDR_CMP_INIT                      0x0000000000000000
+
+/*   SH_Y_LADDR_CMP_CMP_VAL                                             */
+/*   Description:  Compare value                                        */
+#define SH_Y_LADDR_CMP_CMP_VAL_SHFT              0
+#define SH_Y_LADDR_CMP_CMP_VAL_MASK              0x000000000fffffff
+
+/*   SH_Y_LADDR_CMP_MASK_VAL                                            */
+/*   Description:  Mask value                                           */
+#define SH_Y_LADDR_CMP_MASK_VAL_SHFT             32
+#define SH_Y_LADDR_CMP_MASK_VAL_MASK             0x0fffffff00000000
+
+/* ==================================================================== */
+/*                      Register "SH_Y_RADDR_CMP"                       */
+/*                        MD acy address compare                        */
+/* ==================================================================== */
+
+#define SH_Y_RADDR_CMP                           0x0000000100020160
+#define SH_Y_RADDR_CMP_MASK                      0x0fffffff0fffffff
+#define SH_Y_RADDR_CMP_INIT                      0x0000000000000000
+
+/*   SH_Y_RADDR_CMP_CMP_VAL                                             */
+/*   Description:  Compare value                                        */
+#define SH_Y_RADDR_CMP_CMP_VAL_SHFT              0
+#define SH_Y_RADDR_CMP_CMP_VAL_MASK              0x000000000fffffff
+
+/*   SH_Y_RADDR_CMP_MASK_VAL                                            */
+/*   Description:  Mask value                                           */
+#define SH_Y_RADDR_CMP_MASK_VAL_SHFT             32
+#define SH_Y_RADDR_CMP_MASK_VAL_MASK             0x0fffffff00000000
+
+/* ==================================================================== */
+/*                       Register "SH_Y_TAG_CMP"                        */
+/*                        MD acy tagmgr compare                         */
+/* ==================================================================== */
+
+#define SH_Y_TAG_CMP                             0x0000000100020168
+#define SH_Y_TAG_CMP_MASK                        0x007fffffffffffff
+#define SH_Y_TAG_CMP_INIT                        0x0000000000000000
+
+/*   SH_Y_TAG_CMP_CMD                                                   */
+/*   Description:  Command compare value                                */
+#define SH_Y_TAG_CMP_CMD_SHFT                    0
+#define SH_Y_TAG_CMP_CMD_MASK                    0x00000000000000ff
+
+/*   SH_Y_TAG_CMP_ADDR                                                  */
+/*   Description:  Address compare value                                */
+#define SH_Y_TAG_CMP_ADDR_SHFT                   8
+#define SH_Y_TAG_CMP_ADDR_MASK                   0x000001ffffffff00
+
+/*   SH_Y_TAG_CMP_SRC                                                   */
+/*   Description:  Source compare value                                 */
+#define SH_Y_TAG_CMP_SRC_SHFT                    41
+#define SH_Y_TAG_CMP_SRC_MASK                    0x007ffe0000000000
+
+/* ==================================================================== */
+/*                       Register "SH_Y_TAG_MASK"                       */
+/*                          MD acy tagmgr mask                          */
+/* ==================================================================== */
+
+#define SH_Y_TAG_MASK                            0x0000000100020170
+#define SH_Y_TAG_MASK_MASK                       0x007fffffffffffff
+#define SH_Y_TAG_MASK_INIT                       0x0000000000000000
+
+/*   SH_Y_TAG_MASK_CMD                                                  */
+/*   Description:  Command compare value                                */
+#define SH_Y_TAG_MASK_CMD_SHFT                   0
+#define SH_Y_TAG_MASK_CMD_MASK                   0x00000000000000ff
+
+/*   SH_Y_TAG_MASK_ADDR                                                 */
+/*   Description:  Address compare value                                */
+#define SH_Y_TAG_MASK_ADDR_SHFT                  8
+#define SH_Y_TAG_MASK_ADDR_MASK                  0x000001ffffffff00
+
+/*   SH_Y_TAG_MASK_SRC                                                  */
+/*   Description:  Source compare value                                 */
+#define SH_Y_TAG_MASK_SRC_SHFT                   41
+#define SH_Y_TAG_MASK_SRC_MASK                   0x007ffe0000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_JNR_DBUG_DATA_CFG"                  */
+/*              configuration for md jnr debug data muxes               */
+/* ==================================================================== */
+
+#define SH_MD_JNR_DBUG_DATA_CFG                  0x0000000100020178
+#define SH_MD_JNR_DBUG_DATA_CFG_MASK             0x0000000077777777
+#define SH_MD_JNR_DBUG_DATA_CFG_INIT             0x0000000000000000
+
+/*   SH_MD_JNR_DBUG_DATA_CFG_NIBBLE0_SEL                                */
+/*   Description:  selects which nibble drives nibble0                  */
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE0_SEL_SHFT 0
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE0_SEL_MASK 0x0000000000000007
+
+/*   SH_MD_JNR_DBUG_DATA_CFG_NIBBLE1_SEL                                */
+/*   Description:  selects which nibble drives nibble1                  */
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE1_SEL_SHFT 4
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE1_SEL_MASK 0x0000000000000070
+
+/*   SH_MD_JNR_DBUG_DATA_CFG_NIBBLE2_SEL                                */
+/*   Description:  selects which nibble drives nibble2                  */
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE2_SEL_SHFT 8
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE2_SEL_MASK 0x0000000000000700
+
+/*   SH_MD_JNR_DBUG_DATA_CFG_NIBBLE3_SEL                                */
+/*   Description:  selects which nibble drives nibble3                  */
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE3_SEL_SHFT 12
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE3_SEL_MASK 0x0000000000007000
+
+/*   SH_MD_JNR_DBUG_DATA_CFG_NIBBLE4_SEL                                */
+/*   Description:  selects which nibble drives nibble4                  */
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE4_SEL_SHFT 16
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE4_SEL_MASK 0x0000000000070000
+
+/*   SH_MD_JNR_DBUG_DATA_CFG_NIBBLE5_SEL                                */
+/*   Description:  selects which nibble drives nibble5                  */
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE5_SEL_SHFT 20
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE5_SEL_MASK 0x0000000000700000
+
+/*   SH_MD_JNR_DBUG_DATA_CFG_NIBBLE6_SEL                                */
+/*   Description:  selects which nibble drives nibble6                  */
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE6_SEL_SHFT 24
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE6_SEL_MASK 0x0000000007000000
+
+/*   SH_MD_JNR_DBUG_DATA_CFG_NIBBLE7_SEL                                */
+/*   Description:  selects which nibble drives nibble7                  */
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE7_SEL_SHFT 28
+#define SH_MD_JNR_DBUG_DATA_CFG_NIBBLE7_SEL_MASK 0x0000000070000000
+
+/* ==================================================================== */
+/*                     Register "SH_MD_LAST_CREDIT"                     */
+/*                 captures last credit values on reset                 */
+/* ==================================================================== */
+
+#define SH_MD_LAST_CREDIT                        0x0000000100020180
+#define SH_MD_LAST_CREDIT_MASK                   0x0000003f3f3f3f3f
+#define SH_MD_LAST_CREDIT_INIT                   0x0000000000000000
+
+/*   SH_MD_LAST_CREDIT_RQ_TO_PI                                         */
+/*   Description:  capture of request credits to pi                     */
+#define SH_MD_LAST_CREDIT_RQ_TO_PI_SHFT          0
+#define SH_MD_LAST_CREDIT_RQ_TO_PI_MASK          0x000000000000003f
+
+/*   SH_MD_LAST_CREDIT_RP_TO_PI                                         */
+/*   Description:  capture of reply credits to pi                       */
+#define SH_MD_LAST_CREDIT_RP_TO_PI_SHFT          8
+#define SH_MD_LAST_CREDIT_RP_TO_PI_MASK          0x0000000000003f00
+
+/*   SH_MD_LAST_CREDIT_RQ_TO_XN                                         */
+/*   Description:  capture of request credits to xn                     */
+#define SH_MD_LAST_CREDIT_RQ_TO_XN_SHFT          16
+#define SH_MD_LAST_CREDIT_RQ_TO_XN_MASK          0x00000000003f0000
+
+/*   SH_MD_LAST_CREDIT_RP_TO_XN                                         */
+/*   Description:  capture of reply credits to xn                       */
+#define SH_MD_LAST_CREDIT_RP_TO_XN_SHFT          24
+#define SH_MD_LAST_CREDIT_RP_TO_XN_MASK          0x000000003f000000
+
+/*   SH_MD_LAST_CREDIT_TO_LB                                            */
+/*   Description:  capture of credits to pi                             */
+#define SH_MD_LAST_CREDIT_TO_LB_SHFT             32
+#define SH_MD_LAST_CREDIT_TO_LB_MASK             0x0000003f00000000
+
+/* ==================================================================== */
+/*                    Register "SH_MEM_CAPTURE_ADDR"                    */
+/*                   Address capture address register                   */
+/* ==================================================================== */
+
+#define SH_MEM_CAPTURE_ADDR                      0x0000000100020300
+#define SH_MEM_CAPTURE_ADDR_MASK                 0x00000ffffffffff8
+#define SH_MEM_CAPTURE_ADDR_INIT                 0x0000000000000000
+
+/*   SH_MEM_CAPTURE_ADDR_ADDR                                           */
+/*   Description:  upper bits of address                                */
+#define SH_MEM_CAPTURE_ADDR_ADDR_SHFT            3
+#define SH_MEM_CAPTURE_ADDR_ADDR_MASK            0x0000000ffffffff8
+
+/*   SH_MEM_CAPTURE_ADDR_CMD                                            */
+/*   Description:  command of reference                                 */
+#define SH_MEM_CAPTURE_ADDR_CMD_SHFT             36
+#define SH_MEM_CAPTURE_ADDR_CMD_MASK             0x00000ff000000000
+
+/* ==================================================================== */
+/*                    Register "SH_MEM_CAPTURE_MASK"                    */
+/*                    Address capture mask register                     */
+/* ==================================================================== */
+
+#define SH_MEM_CAPTURE_MASK                      0x0000000100020308
+#define SH_MEM_CAPTURE_MASK_MASK                 0x00003ffffffffff8
+#define SH_MEM_CAPTURE_MASK_INIT                 0x0000000000000000
+
+/*   SH_MEM_CAPTURE_MASK_ADDR                                           */
+/*   Description:  upper bits of address                                */
+#define SH_MEM_CAPTURE_MASK_ADDR_SHFT            3
+#define SH_MEM_CAPTURE_MASK_ADDR_MASK            0x0000000ffffffff8
+
+/*   SH_MEM_CAPTURE_MASK_CMD                                            */
+/*   Description:  command of reference                                 */
+#define SH_MEM_CAPTURE_MASK_CMD_SHFT             36
+#define SH_MEM_CAPTURE_MASK_CMD_MASK             0x00000ff000000000
+
+/*   SH_MEM_CAPTURE_MASK_ENABLE_LOCAL                                   */
+/*   Description:  capture references originating locally               */
+#define SH_MEM_CAPTURE_MASK_ENABLE_LOCAL_SHFT    44
+#define SH_MEM_CAPTURE_MASK_ENABLE_LOCAL_MASK    0x0000100000000000
+
+/*   SH_MEM_CAPTURE_MASK_ENABLE_REMOTE                                  */
+/*   Description:  capture references originating remotely              */
+#define SH_MEM_CAPTURE_MASK_ENABLE_REMOTE_SHFT   45
+#define SH_MEM_CAPTURE_MASK_ENABLE_REMOTE_MASK   0x0000200000000000
+
+/* ==================================================================== */
+/*                    Register "SH_MEM_CAPTURE_HDR"                     */
+/*                   Address capture header register                    */
+/* ==================================================================== */
+
+#define SH_MEM_CAPTURE_HDR                       0x0000000100020310
+#define SH_MEM_CAPTURE_HDR_MASK                  0xfffffffffffffff8
+#define SH_MEM_CAPTURE_HDR_INIT                  0x0000000000000000
+
+/*   SH_MEM_CAPTURE_HDR_ADDR                                            */
+/*   Description:  upper bits of reference address                      */
+#define SH_MEM_CAPTURE_HDR_ADDR_SHFT             3
+#define SH_MEM_CAPTURE_HDR_ADDR_MASK             0x0000000ffffffff8
+
+/*   SH_MEM_CAPTURE_HDR_CMD                                             */
+/*   Description:  command of reference                                 */
+#define SH_MEM_CAPTURE_HDR_CMD_SHFT              36
+#define SH_MEM_CAPTURE_HDR_CMD_MASK              0x00000ff000000000
+
+/*   SH_MEM_CAPTURE_HDR_SRC                                             */
+/*   Description:  source node of reference                             */
+#define SH_MEM_CAPTURE_HDR_SRC_SHFT              44
+#define SH_MEM_CAPTURE_HDR_SRC_MASK              0x03fff00000000000
+
+/*   SH_MEM_CAPTURE_HDR_CNTR                                            */
+/*   Description:  increments on every capture                          */
+#define SH_MEM_CAPTURE_HDR_CNTR_SHFT             58
+#define SH_MEM_CAPTURE_HDR_CNTR_MASK             0xfc00000000000000
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQLP_MMR_DIR_CONFIG"                 */
+/*                     DQ directory config register                     */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_CONFIG                0x0000000100030000
+#define SH_MD_DQLP_MMR_DIR_CONFIG_MASK           0x000000000000001f
+#define SH_MD_DQLP_MMR_DIR_CONFIG_INIT           0x0000000000000010
+
+/*   SH_MD_DQLP_MMR_DIR_CONFIG_SYS_SIZE                                 */
+/*   Description:  system size code                                     */
+#define SH_MD_DQLP_MMR_DIR_CONFIG_SYS_SIZE_SHFT  0
+#define SH_MD_DQLP_MMR_DIR_CONFIG_SYS_SIZE_MASK  0x0000000000000007
+
+/*   SH_MD_DQLP_MMR_DIR_CONFIG_EN_DIRECC                                */
+/*   Description:  enable directory ecc correction                      */
+#define SH_MD_DQLP_MMR_DIR_CONFIG_EN_DIRECC_SHFT 3
+#define SH_MD_DQLP_MMR_DIR_CONFIG_EN_DIRECC_MASK 0x0000000000000008
+
+/*   SH_MD_DQLP_MMR_DIR_CONFIG_EN_DIRPOIS                               */
+/*   Description:  enable local poisoning for dir table fall-through    */
+#define SH_MD_DQLP_MMR_DIR_CONFIG_EN_DIRPOIS_SHFT 4
+#define SH_MD_DQLP_MMR_DIR_CONFIG_EN_DIRPOIS_MASK 0x0000000000000010
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC0"                */
+/*                      node [63:0] presence bits                       */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRESVEC0              0x0000000100030100
+#define SH_MD_DQLP_MMR_DIR_PRESVEC0_MASK         0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_PRESVEC0_INIT         0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRESVEC0_VEC                                    */
+/*   Description:  node presence bits, 1=present                        */
+#define SH_MD_DQLP_MMR_DIR_PRESVEC0_VEC_SHFT     0
+#define SH_MD_DQLP_MMR_DIR_PRESVEC0_VEC_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC1"                */
+/*                     node [127:64] presence bits                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRESVEC1              0x0000000100030110
+#define SH_MD_DQLP_MMR_DIR_PRESVEC1_MASK         0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_PRESVEC1_INIT         0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRESVEC1_VEC                                    */
+/*   Description:  node presence bits, 1=present                        */
+#define SH_MD_DQLP_MMR_DIR_PRESVEC1_VEC_SHFT     0
+#define SH_MD_DQLP_MMR_DIR_PRESVEC1_VEC_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC2"                */
+/*                     node [191:128] presence bits                     */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRESVEC2              0x0000000100030120
+#define SH_MD_DQLP_MMR_DIR_PRESVEC2_MASK         0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_PRESVEC2_INIT         0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRESVEC2_VEC                                    */
+/*   Description:  node presence bits, 1=present                        */
+#define SH_MD_DQLP_MMR_DIR_PRESVEC2_VEC_SHFT     0
+#define SH_MD_DQLP_MMR_DIR_PRESVEC2_VEC_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC3"                */
+/*                     node [255:192] presence bits                     */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRESVEC3              0x0000000100030130
+#define SH_MD_DQLP_MMR_DIR_PRESVEC3_MASK         0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_PRESVEC3_INIT         0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRESVEC3_VEC                                    */
+/*   Description:  node presence bits, 1=present                        */
+#define SH_MD_DQLP_MMR_DIR_PRESVEC3_VEC_SHFT     0
+#define SH_MD_DQLP_MMR_DIR_PRESVEC3_VEC_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC0"                 */
+/*                        local vector for acc=0                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_LOCVEC0               0x0000000100030200
+#define SH_MD_DQLP_MMR_DIR_LOCVEC0_MASK          0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_LOCVEC0_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_LOCVEC0_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQLP_MMR_DIR_LOCVEC0_VEC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_LOCVEC0_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC1"                 */
+/*                        local vector for acc=1                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_LOCVEC1               0x0000000100030210
+#define SH_MD_DQLP_MMR_DIR_LOCVEC1_MASK          0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_LOCVEC1_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_LOCVEC1_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQLP_MMR_DIR_LOCVEC1_VEC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_LOCVEC1_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC2"                 */
+/*                        local vector for acc=2                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_LOCVEC2               0x0000000100030220
+#define SH_MD_DQLP_MMR_DIR_LOCVEC2_MASK          0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_LOCVEC2_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_LOCVEC2_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQLP_MMR_DIR_LOCVEC2_VEC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_LOCVEC2_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC3"                 */
+/*                        local vector for acc=3                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_LOCVEC3               0x0000000100030230
+#define SH_MD_DQLP_MMR_DIR_LOCVEC3_MASK          0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_LOCVEC3_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_LOCVEC3_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQLP_MMR_DIR_LOCVEC3_VEC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_LOCVEC3_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC4"                 */
+/*                        local vector for acc=4                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_LOCVEC4               0x0000000100030240
+#define SH_MD_DQLP_MMR_DIR_LOCVEC4_MASK          0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_LOCVEC4_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_LOCVEC4_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQLP_MMR_DIR_LOCVEC4_VEC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_LOCVEC4_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC5"                 */
+/*                        local vector for acc=5                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_LOCVEC5               0x0000000100030250
+#define SH_MD_DQLP_MMR_DIR_LOCVEC5_MASK          0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_LOCVEC5_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_LOCVEC5_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQLP_MMR_DIR_LOCVEC5_VEC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_LOCVEC5_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC6"                 */
+/*                        local vector for acc=6                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_LOCVEC6               0x0000000100030260
+#define SH_MD_DQLP_MMR_DIR_LOCVEC6_MASK          0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_LOCVEC6_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_LOCVEC6_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQLP_MMR_DIR_LOCVEC6_VEC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_LOCVEC6_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC7"                 */
+/*                        local vector for acc=7                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_LOCVEC7               0x0000000100030270
+#define SH_MD_DQLP_MMR_DIR_LOCVEC7_MASK          0xffffffffffffffff
+#define SH_MD_DQLP_MMR_DIR_LOCVEC7_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_LOCVEC7_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQLP_MMR_DIR_LOCVEC7_VEC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_LOCVEC7_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC0"                 */
+/*                      privilege vector for acc=0                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRIVEC0               0x0000000100030300
+#define SH_MD_DQLP_MMR_DIR_PRIVEC0_MASK          0x000000000fffffff
+#define SH_MD_DQLP_MMR_DIR_PRIVEC0_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC0_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC0_IN_SHFT       0
+#define SH_MD_DQLP_MMR_DIR_PRIVEC0_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC0_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC0_OUT_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_PRIVEC0_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC1"                 */
+/*                      privilege vector for acc=1                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRIVEC1               0x0000000100030310
+#define SH_MD_DQLP_MMR_DIR_PRIVEC1_MASK          0x000000000fffffff
+#define SH_MD_DQLP_MMR_DIR_PRIVEC1_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC1_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC1_IN_SHFT       0
+#define SH_MD_DQLP_MMR_DIR_PRIVEC1_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC1_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC1_OUT_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_PRIVEC1_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC2"                 */
+/*                      privilege vector for acc=2                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRIVEC2               0x0000000100030320
+#define SH_MD_DQLP_MMR_DIR_PRIVEC2_MASK          0x000000000fffffff
+#define SH_MD_DQLP_MMR_DIR_PRIVEC2_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC2_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC2_IN_SHFT       0
+#define SH_MD_DQLP_MMR_DIR_PRIVEC2_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC2_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC2_OUT_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_PRIVEC2_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC3"                 */
+/*                      privilege vector for acc=3                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRIVEC3               0x0000000100030330
+#define SH_MD_DQLP_MMR_DIR_PRIVEC3_MASK          0x000000000fffffff
+#define SH_MD_DQLP_MMR_DIR_PRIVEC3_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC3_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC3_IN_SHFT       0
+#define SH_MD_DQLP_MMR_DIR_PRIVEC3_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC3_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC3_OUT_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_PRIVEC3_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC4"                 */
+/*                      privilege vector for acc=4                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRIVEC4               0x0000000100030340
+#define SH_MD_DQLP_MMR_DIR_PRIVEC4_MASK          0x000000000fffffff
+#define SH_MD_DQLP_MMR_DIR_PRIVEC4_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC4_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC4_IN_SHFT       0
+#define SH_MD_DQLP_MMR_DIR_PRIVEC4_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC4_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC4_OUT_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_PRIVEC4_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC5"                 */
+/*                      privilege vector for acc=5                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRIVEC5               0x0000000100030350
+#define SH_MD_DQLP_MMR_DIR_PRIVEC5_MASK          0x000000000fffffff
+#define SH_MD_DQLP_MMR_DIR_PRIVEC5_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC5_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC5_IN_SHFT       0
+#define SH_MD_DQLP_MMR_DIR_PRIVEC5_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC5_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC5_OUT_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_PRIVEC5_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC6"                 */
+/*                      privilege vector for acc=6                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRIVEC6               0x0000000100030360
+#define SH_MD_DQLP_MMR_DIR_PRIVEC6_MASK          0x000000000fffffff
+#define SH_MD_DQLP_MMR_DIR_PRIVEC6_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC6_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC6_IN_SHFT       0
+#define SH_MD_DQLP_MMR_DIR_PRIVEC6_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC6_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC6_OUT_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_PRIVEC6_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC7"                 */
+/*                      privilege vector for acc=7                      */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_PRIVEC7               0x0000000100030370
+#define SH_MD_DQLP_MMR_DIR_PRIVEC7_MASK          0x000000000fffffff
+#define SH_MD_DQLP_MMR_DIR_PRIVEC7_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC7_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC7_IN_SHFT       0
+#define SH_MD_DQLP_MMR_DIR_PRIVEC7_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_PRIVEC7_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQLP_MMR_DIR_PRIVEC7_OUT_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_PRIVEC7_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQLP_MMR_DIR_TIMER"                  */
+/*                            MD SXRO timer                             */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_TIMER                 0x0000000100030400
+#define SH_MD_DQLP_MMR_DIR_TIMER_MASK            0x00000000003fffff
+#define SH_MD_DQLP_MMR_DIR_TIMER_INIT            0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_TIMER_TIMER_DIV                                 */
+/*   Description:  timer divide register                                */
+#define SH_MD_DQLP_MMR_DIR_TIMER_TIMER_DIV_SHFT  0
+#define SH_MD_DQLP_MMR_DIR_TIMER_TIMER_DIV_MASK  0x0000000000000fff
+
+/*   SH_MD_DQLP_MMR_DIR_TIMER_TIMER_EN                                  */
+/*   Description:  timer enable                                         */
+#define SH_MD_DQLP_MMR_DIR_TIMER_TIMER_EN_SHFT   12
+#define SH_MD_DQLP_MMR_DIR_TIMER_TIMER_EN_MASK   0x0000000000001000
+
+/*   SH_MD_DQLP_MMR_DIR_TIMER_TIMER_CUR                                 */
+/*   Description:  value of current timer                               */
+#define SH_MD_DQLP_MMR_DIR_TIMER_TIMER_CUR_SHFT  13
+#define SH_MD_DQLP_MMR_DIR_TIMER_TIMER_CUR_MASK  0x00000000003fe000
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY"               */
+/*                       directory pio write data                       */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY           0x0000000100031000
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_MASK      0x03ffffffffffffff
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_INIT      0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_DIRA                                */
+/*   Description:  directory entry A                                    */
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_DIRA_SHFT 0
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_DIRA_MASK 0x0000000003ffffff
+
+/*   SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_DIRB                                */
+/*   Description:  directory entry B                                    */
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_DIRB_SHFT 26
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_DIRB_MASK 0x000ffffffc000000
+
+/*   SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_PRI                                 */
+/*   Description:  directory priority                                   */
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_PRI_SHFT  52
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_PRI_MASK  0x0070000000000000
+
+/*   SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_ACC                                 */
+/*   Description:  directory access bits                                */
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_ACC_SHFT  55
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY_ACC_MASK  0x0380000000000000
+
+/* ==================================================================== */
+/*               Register "SH_MD_DQLP_MMR_PIOWD_DIR_ECC"                */
+/*                        directory ecc register                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ECC             0x0000000100031010
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ECC_MASK        0x0000000000003fff
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ECC_INIT        0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_PIOWD_DIR_ECC_ECCA                                  */
+/*   Description:  XOR bits for directory ECC group 1                   */
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ECC_ECCA_SHFT   0
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ECC_ECCA_MASK   0x000000000000007f
+
+/*   SH_MD_DQLP_MMR_PIOWD_DIR_ECC_ECCB                                  */
+/*   Description:  XOR bits for directory ECC group 2                   */
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ECC_ECCB_SHFT   7
+#define SH_MD_DQLP_MMR_PIOWD_DIR_ECC_ECCB_MASK   0x0000000000003f80
+
+/* ==================================================================== */
+/*             Register "SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY"              */
+/*                      x directory pio read data                       */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY         0x0000000100032000
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_MASK    0x0fffffffffffffff
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_INIT    0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_DIRA                              */
+/*   Description:  directory entry A                                    */
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_DIRA_SHFT 0
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_DIRA_MASK 0x0000000003ffffff
+
+/*   SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_DIRB                              */
+/*   Description:  directory entry B                                    */
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_DIRB_SHFT 26
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_DIRB_MASK 0x000ffffffc000000
+
+/*   SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_PRI                               */
+/*   Description:  directory priority                                   */
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_PRI_SHFT 52
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_PRI_MASK 0x0070000000000000
+
+/*   SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_ACC                               */
+/*   Description:  directory access bits                                */
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_ACC_SHFT 55
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_ACC_MASK 0x0380000000000000
+
+/*   SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_COR                               */
+/*   Description:  correctable ecc error                                */
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_COR_SHFT 58
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_COR_MASK 0x0400000000000000
+
+/*   SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_UNC                               */
+/*   Description:  uncorrectable ecc error                              */
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_UNC_SHFT 59
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY_UNC_MASK 0x0800000000000000
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQLP_MMR_XPIORD_XDIR_ECC"               */
+/*                           x directory ecc                            */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ECC           0x0000000100032010
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ECC_MASK      0x0000000000003fff
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ECC_INIT      0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XPIORD_XDIR_ECC_ECCA                                */
+/*   Description:  group 1 ecc                                          */
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ECC_ECCA_SHFT 0
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ECC_ECCA_MASK 0x000000000000007f
+
+/*   SH_MD_DQLP_MMR_XPIORD_XDIR_ECC_ECCB                                */
+/*   Description:  group 2 ecc                                          */
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ECC_ECCB_SHFT 7
+#define SH_MD_DQLP_MMR_XPIORD_XDIR_ECC_ECCB_MASK 0x0000000000003f80
+
+/* ==================================================================== */
+/*             Register "SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY"              */
+/*                      y directory pio read data                       */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY         0x0000000100032800
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_MASK    0x0fffffffffffffff
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_INIT    0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_DIRA                              */
+/*   Description:  directory entry A                                    */
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_DIRA_SHFT 0
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_DIRA_MASK 0x0000000003ffffff
+
+/*   SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_DIRB                              */
+/*   Description:  directory entry B                                    */
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_DIRB_SHFT 26
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_DIRB_MASK 0x000ffffffc000000
+
+/*   SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_PRI                               */
+/*   Description:  directory priority                                   */
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_PRI_SHFT 52
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_PRI_MASK 0x0070000000000000
+
+/*   SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_ACC                               */
+/*   Description:  directory access bits                                */
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_ACC_SHFT 55
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_ACC_MASK 0x0380000000000000
+
+/*   SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_COR                               */
+/*   Description:  correctable ecc error                                */
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_COR_SHFT 58
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_COR_MASK 0x0400000000000000
+
+/*   SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_UNC                               */
+/*   Description:  uncorrectable ecc error                              */
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_UNC_SHFT 59
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY_UNC_MASK 0x0800000000000000
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQLP_MMR_YPIORD_YDIR_ECC"               */
+/*                           y directory ecc                            */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ECC           0x0000000100032810
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ECC_MASK      0x0000000000003fff
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ECC_INIT      0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YPIORD_YDIR_ECC_ECCA                                */
+/*   Description:  group 1 ecc                                          */
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ECC_ECCA_SHFT 0
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ECC_ECCA_MASK 0x000000000000007f
+
+/*   SH_MD_DQLP_MMR_YPIORD_YDIR_ECC_ECCB                                */
+/*   Description:  group 2 ecc                                          */
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ECC_ECCB_SHFT 7
+#define SH_MD_DQLP_MMR_YPIORD_YDIR_ECC_ECCB_MASK 0x0000000000003f80
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XCERR1"                   */
+/*              correctable dir ecc group 1 error register              */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XCERR1                    0x0000000100033000
+#define SH_MD_DQLP_MMR_XCERR1_MASK               0x0000007fffffffff
+#define SH_MD_DQLP_MMR_XCERR1_INIT               0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XCERR1_GRP1                                         */
+/*   Description:  ecc group 1 bits                                     */
+#define SH_MD_DQLP_MMR_XCERR1_GRP1_SHFT          0
+#define SH_MD_DQLP_MMR_XCERR1_GRP1_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQLP_MMR_XCERR1_VAL                                          */
+/*   Description:  correctable ecc error in group 1 bits                */
+#define SH_MD_DQLP_MMR_XCERR1_VAL_SHFT           36
+#define SH_MD_DQLP_MMR_XCERR1_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQLP_MMR_XCERR1_MORE                                         */
+/*   Description:  more than one correctable ecc error in group 1       */
+#define SH_MD_DQLP_MMR_XCERR1_MORE_SHFT          37
+#define SH_MD_DQLP_MMR_XCERR1_MORE_MASK          0x0000002000000000
+
+/*   SH_MD_DQLP_MMR_XCERR1_ARM                                          */
+/*   Description:  writing 1 arms uncorrectable ecc error capture       */
+#define SH_MD_DQLP_MMR_XCERR1_ARM_SHFT           38
+#define SH_MD_DQLP_MMR_XCERR1_ARM_MASK           0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XCERR2"                   */
+/*              correctable dir ecc group 2 error register              */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XCERR2                    0x0000000100033010
+#define SH_MD_DQLP_MMR_XCERR2_MASK               0x0000003fffffffff
+#define SH_MD_DQLP_MMR_XCERR2_INIT               0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XCERR2_GRP2                                         */
+/*   Description:  ecc group 2 bits                                     */
+#define SH_MD_DQLP_MMR_XCERR2_GRP2_SHFT          0
+#define SH_MD_DQLP_MMR_XCERR2_GRP2_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQLP_MMR_XCERR2_VAL                                          */
+/*   Description:  correctable ecc error in group 2 bits                */
+#define SH_MD_DQLP_MMR_XCERR2_VAL_SHFT           36
+#define SH_MD_DQLP_MMR_XCERR2_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQLP_MMR_XCERR2_MORE                                         */
+/*   Description:  more than one correctable ecc error in group 2       */
+#define SH_MD_DQLP_MMR_XCERR2_MORE_SHFT          37
+#define SH_MD_DQLP_MMR_XCERR2_MORE_MASK          0x0000002000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XUERR1"                   */
+/*             uncorrectable dir ecc group 1 error register             */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XUERR1                    0x0000000100033020
+#define SH_MD_DQLP_MMR_XUERR1_MASK               0x0000007fffffffff
+#define SH_MD_DQLP_MMR_XUERR1_INIT               0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XUERR1_GRP1                                         */
+/*   Description:  ecc group 1 bits                                     */
+#define SH_MD_DQLP_MMR_XUERR1_GRP1_SHFT          0
+#define SH_MD_DQLP_MMR_XUERR1_GRP1_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQLP_MMR_XUERR1_VAL                                          */
+/*   Description:  uncorrectable ecc error in group 1 bits              */
+#define SH_MD_DQLP_MMR_XUERR1_VAL_SHFT           36
+#define SH_MD_DQLP_MMR_XUERR1_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQLP_MMR_XUERR1_MORE                                         */
+/*   Description:  more than one uncorrectable ecc error in group 1     */
+#define SH_MD_DQLP_MMR_XUERR1_MORE_SHFT          37
+#define SH_MD_DQLP_MMR_XUERR1_MORE_MASK          0x0000002000000000
+
+/*   SH_MD_DQLP_MMR_XUERR1_ARM                                          */
+/*   Description:  writing 1 arms uncorrectable ecc error capture       */
+#define SH_MD_DQLP_MMR_XUERR1_ARM_SHFT           38
+#define SH_MD_DQLP_MMR_XUERR1_ARM_MASK           0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XUERR2"                   */
+/*             uncorrectable dir ecc group 2 error register             */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XUERR2                    0x0000000100033030
+#define SH_MD_DQLP_MMR_XUERR2_MASK               0x0000003fffffffff
+#define SH_MD_DQLP_MMR_XUERR2_INIT               0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XUERR2_GRP2                                         */
+/*   Description:  ecc group 2 bits                                     */
+#define SH_MD_DQLP_MMR_XUERR2_GRP2_SHFT          0
+#define SH_MD_DQLP_MMR_XUERR2_GRP2_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQLP_MMR_XUERR2_VAL                                          */
+/*   Description:  uncorrectable ecc error in group 2 bits              */
+#define SH_MD_DQLP_MMR_XUERR2_VAL_SHFT           36
+#define SH_MD_DQLP_MMR_XUERR2_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQLP_MMR_XUERR2_MORE                                         */
+/*   Description:  more than one uncorrectable ecc error in group 2     */
+#define SH_MD_DQLP_MMR_XUERR2_MORE_SHFT          37
+#define SH_MD_DQLP_MMR_XUERR2_MORE_MASK          0x0000002000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XPERR"                    */
+/*                       protocol error register                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XPERR                     0x0000000100033040
+#define SH_MD_DQLP_MMR_XPERR_MASK                0x7fffffffffffffff
+#define SH_MD_DQLP_MMR_XPERR_INIT                0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XPERR_DIR                                           */
+/*   Description:  directory entry                                      */
+#define SH_MD_DQLP_MMR_XPERR_DIR_SHFT            0
+#define SH_MD_DQLP_MMR_XPERR_DIR_MASK            0x0000000003ffffff
+
+/*   SH_MD_DQLP_MMR_XPERR_CMD                                           */
+/*   Description:  incoming command                                     */
+#define SH_MD_DQLP_MMR_XPERR_CMD_SHFT            26
+#define SH_MD_DQLP_MMR_XPERR_CMD_MASK            0x00000003fc000000
+
+/*   SH_MD_DQLP_MMR_XPERR_SRC                                           */
+/*   Description:  source node of dir operation                         */
+#define SH_MD_DQLP_MMR_XPERR_SRC_SHFT            34
+#define SH_MD_DQLP_MMR_XPERR_SRC_MASK            0x0000fffc00000000
+
+/*   SH_MD_DQLP_MMR_XPERR_PRIGE                                         */
+/*   Description:  priority was greater-equal                           */
+#define SH_MD_DQLP_MMR_XPERR_PRIGE_SHFT          48
+#define SH_MD_DQLP_MMR_XPERR_PRIGE_MASK          0x0001000000000000
+
+/*   SH_MD_DQLP_MMR_XPERR_PRIV                                          */
+/*   Description:  access privilege bit                                 */
+#define SH_MD_DQLP_MMR_XPERR_PRIV_SHFT           49
+#define SH_MD_DQLP_MMR_XPERR_PRIV_MASK           0x0002000000000000
+
+/*   SH_MD_DQLP_MMR_XPERR_COR                                           */
+/*   Description:  correctable ecc error                                */
+#define SH_MD_DQLP_MMR_XPERR_COR_SHFT            50
+#define SH_MD_DQLP_MMR_XPERR_COR_MASK            0x0004000000000000
+
+/*   SH_MD_DQLP_MMR_XPERR_UNC                                           */
+/*   Description:  uncorrectable ecc error                              */
+#define SH_MD_DQLP_MMR_XPERR_UNC_SHFT            51
+#define SH_MD_DQLP_MMR_XPERR_UNC_MASK            0x0008000000000000
+
+/*   SH_MD_DQLP_MMR_XPERR_MYBIT                                         */
+/*   Description:  ptreq,timeq,timlast,timspec,onlyme,anytim,ptrii,src  */
+#define SH_MD_DQLP_MMR_XPERR_MYBIT_SHFT          52
+#define SH_MD_DQLP_MMR_XPERR_MYBIT_MASK          0x0ff0000000000000
+
+/*   SH_MD_DQLP_MMR_XPERR_VAL                                           */
+/*   Description:  protocol error info valid                            */
+#define SH_MD_DQLP_MMR_XPERR_VAL_SHFT            60
+#define SH_MD_DQLP_MMR_XPERR_VAL_MASK            0x1000000000000000
+
+/*   SH_MD_DQLP_MMR_XPERR_MORE                                          */
+/*   Description:  more than one protocol error                         */
+#define SH_MD_DQLP_MMR_XPERR_MORE_SHFT           61
+#define SH_MD_DQLP_MMR_XPERR_MORE_MASK           0x2000000000000000
+
+/*   SH_MD_DQLP_MMR_XPERR_ARM                                           */
+/*   Description:  writing 1 arms error capture                         */
+#define SH_MD_DQLP_MMR_XPERR_ARM_SHFT            62
+#define SH_MD_DQLP_MMR_XPERR_ARM_MASK            0x4000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YCERR1"                   */
+/*              correctable dir ecc group 1 error register              */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YCERR1                    0x0000000100033800
+#define SH_MD_DQLP_MMR_YCERR1_MASK               0x0000007fffffffff
+#define SH_MD_DQLP_MMR_YCERR1_INIT               0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YCERR1_GRP1                                         */
+/*   Description:  ecc group 1 bits                                     */
+#define SH_MD_DQLP_MMR_YCERR1_GRP1_SHFT          0
+#define SH_MD_DQLP_MMR_YCERR1_GRP1_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQLP_MMR_YCERR1_VAL                                          */
+/*   Description:  correctable ecc error in group 1 bits                */
+#define SH_MD_DQLP_MMR_YCERR1_VAL_SHFT           36
+#define SH_MD_DQLP_MMR_YCERR1_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQLP_MMR_YCERR1_MORE                                         */
+/*   Description:  more than one correctable ecc error in group 1       */
+#define SH_MD_DQLP_MMR_YCERR1_MORE_SHFT          37
+#define SH_MD_DQLP_MMR_YCERR1_MORE_MASK          0x0000002000000000
+
+/*   SH_MD_DQLP_MMR_YCERR1_ARM                                          */
+/*   Description:  writing 1 arms uncorrectable ecc error capture       */
+#define SH_MD_DQLP_MMR_YCERR1_ARM_SHFT           38
+#define SH_MD_DQLP_MMR_YCERR1_ARM_MASK           0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YCERR2"                   */
+/*              correctable dir ecc group 2 error register              */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YCERR2                    0x0000000100033810
+#define SH_MD_DQLP_MMR_YCERR2_MASK               0x0000003fffffffff
+#define SH_MD_DQLP_MMR_YCERR2_INIT               0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YCERR2_GRP2                                         */
+/*   Description:  ecc group 2 bits                                     */
+#define SH_MD_DQLP_MMR_YCERR2_GRP2_SHFT          0
+#define SH_MD_DQLP_MMR_YCERR2_GRP2_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQLP_MMR_YCERR2_VAL                                          */
+/*   Description:  correctable ecc error in group 2 bits                */
+#define SH_MD_DQLP_MMR_YCERR2_VAL_SHFT           36
+#define SH_MD_DQLP_MMR_YCERR2_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQLP_MMR_YCERR2_MORE                                         */
+/*   Description:  more than one correctable ecc error in group 2       */
+#define SH_MD_DQLP_MMR_YCERR2_MORE_SHFT          37
+#define SH_MD_DQLP_MMR_YCERR2_MORE_MASK          0x0000002000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YUERR1"                   */
+/*             uncorrectable dir ecc group 1 error register             */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YUERR1                    0x0000000100033820
+#define SH_MD_DQLP_MMR_YUERR1_MASK               0x0000007fffffffff
+#define SH_MD_DQLP_MMR_YUERR1_INIT               0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YUERR1_GRP1                                         */
+/*   Description:  ecc group 1 bits                                     */
+#define SH_MD_DQLP_MMR_YUERR1_GRP1_SHFT          0
+#define SH_MD_DQLP_MMR_YUERR1_GRP1_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQLP_MMR_YUERR1_VAL                                          */
+/*   Description:  uncorrectable ecc error in group 1 bits              */
+#define SH_MD_DQLP_MMR_YUERR1_VAL_SHFT           36
+#define SH_MD_DQLP_MMR_YUERR1_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQLP_MMR_YUERR1_MORE                                         */
+/*   Description:  more than one uncorrectable ecc error in group 1     */
+#define SH_MD_DQLP_MMR_YUERR1_MORE_SHFT          37
+#define SH_MD_DQLP_MMR_YUERR1_MORE_MASK          0x0000002000000000
+
+/*   SH_MD_DQLP_MMR_YUERR1_ARM                                          */
+/*   Description:  writing 1 arms uncorrectable ecc error capture       */
+#define SH_MD_DQLP_MMR_YUERR1_ARM_SHFT           38
+#define SH_MD_DQLP_MMR_YUERR1_ARM_MASK           0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YUERR2"                   */
+/*             uncorrectable dir ecc group 2 error register             */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YUERR2                    0x0000000100033830
+#define SH_MD_DQLP_MMR_YUERR2_MASK               0x0000003fffffffff
+#define SH_MD_DQLP_MMR_YUERR2_INIT               0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YUERR2_GRP2                                         */
+/*   Description:  ecc group 2 bits                                     */
+#define SH_MD_DQLP_MMR_YUERR2_GRP2_SHFT          0
+#define SH_MD_DQLP_MMR_YUERR2_GRP2_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQLP_MMR_YUERR2_VAL                                          */
+/*   Description:  uncorrectable ecc error in group 2 bits              */
+#define SH_MD_DQLP_MMR_YUERR2_VAL_SHFT           36
+#define SH_MD_DQLP_MMR_YUERR2_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQLP_MMR_YUERR2_MORE                                         */
+/*   Description:  more than one uncorrectable ecc error in group 2     */
+#define SH_MD_DQLP_MMR_YUERR2_MORE_SHFT          37
+#define SH_MD_DQLP_MMR_YUERR2_MORE_MASK          0x0000002000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YPERR"                    */
+/*                       protocol error register                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YPERR                     0x0000000100033840
+#define SH_MD_DQLP_MMR_YPERR_MASK                0x7fffffffffffffff
+#define SH_MD_DQLP_MMR_YPERR_INIT                0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YPERR_DIR                                           */
+/*   Description:  directory entry                                      */
+#define SH_MD_DQLP_MMR_YPERR_DIR_SHFT            0
+#define SH_MD_DQLP_MMR_YPERR_DIR_MASK            0x0000000003ffffff
+
+/*   SH_MD_DQLP_MMR_YPERR_CMD                                           */
+/*   Description:  incoming command                                     */
+#define SH_MD_DQLP_MMR_YPERR_CMD_SHFT            26
+#define SH_MD_DQLP_MMR_YPERR_CMD_MASK            0x00000003fc000000
+
+/*   SH_MD_DQLP_MMR_YPERR_SRC                                           */
+/*   Description:  source node of dir operation                         */
+#define SH_MD_DQLP_MMR_YPERR_SRC_SHFT            34
+#define SH_MD_DQLP_MMR_YPERR_SRC_MASK            0x0000fffc00000000
+
+/*   SH_MD_DQLP_MMR_YPERR_PRIGE                                         */
+/*   Description:  priority was greater-equal                           */
+#define SH_MD_DQLP_MMR_YPERR_PRIGE_SHFT          48
+#define SH_MD_DQLP_MMR_YPERR_PRIGE_MASK          0x0001000000000000
+
+/*   SH_MD_DQLP_MMR_YPERR_PRIV                                          */
+/*   Description:  access privilege bit                                 */
+#define SH_MD_DQLP_MMR_YPERR_PRIV_SHFT           49
+#define SH_MD_DQLP_MMR_YPERR_PRIV_MASK           0x0002000000000000
+
+/*   SH_MD_DQLP_MMR_YPERR_COR                                           */
+/*   Description:  correctable ecc error                                */
+#define SH_MD_DQLP_MMR_YPERR_COR_SHFT            50
+#define SH_MD_DQLP_MMR_YPERR_COR_MASK            0x0004000000000000
+
+/*   SH_MD_DQLP_MMR_YPERR_UNC                                           */
+/*   Description:  uncorrectable ecc error                              */
+#define SH_MD_DQLP_MMR_YPERR_UNC_SHFT            51
+#define SH_MD_DQLP_MMR_YPERR_UNC_MASK            0x0008000000000000
+
+/*   SH_MD_DQLP_MMR_YPERR_MYBIT                                         */
+/*   Description:  ptreq,timeq,timlast,timspec,onlyme,anytim,ptrii,src  */
+#define SH_MD_DQLP_MMR_YPERR_MYBIT_SHFT          52
+#define SH_MD_DQLP_MMR_YPERR_MYBIT_MASK          0x0ff0000000000000
+
+/*   SH_MD_DQLP_MMR_YPERR_VAL                                           */
+/*   Description:  protocol error info valid                            */
+#define SH_MD_DQLP_MMR_YPERR_VAL_SHFT            60
+#define SH_MD_DQLP_MMR_YPERR_VAL_MASK            0x1000000000000000
+
+/*   SH_MD_DQLP_MMR_YPERR_MORE                                          */
+/*   Description:  more than one protocol error                         */
+#define SH_MD_DQLP_MMR_YPERR_MORE_SHFT           61
+#define SH_MD_DQLP_MMR_YPERR_MORE_MASK           0x2000000000000000
+
+/*   SH_MD_DQLP_MMR_YPERR_ARM                                           */
+/*   Description:  writing 1 arms error capture                         */
+#define SH_MD_DQLP_MMR_YPERR_ARM_SHFT            62
+#define SH_MD_DQLP_MMR_YPERR_ARM_MASK            0x4000000000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_CMDTRIG"                 */
+/*                             cmd triggers                             */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG               0x0000000100034000
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_MASK          0x00000000ffffffff
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD0                                    */
+/*   Description:  command trigger 0                                    */
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD0_SHFT     0
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD0_MASK     0x00000000000000ff
+
+/*   SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD1                                    */
+/*   Description:  command trigger 1                                    */
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD1_SHFT     8
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD1_MASK     0x000000000000ff00
+
+/*   SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD2                                    */
+/*   Description:  command trigger 2                                    */
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD2_SHFT     16
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD2_MASK     0x0000000000ff0000
+
+/*   SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD3                                    */
+/*   Description:  command trigger 3                                    */
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD3_SHFT     24
+#define SH_MD_DQLP_MMR_DIR_CMDTRIG_CMD3_MASK     0x00000000ff000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_TBLTRIG"                 */
+/*                          dir table trigger                           */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG               0x0000000100034010
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_MASK          0x000003ffffffffff
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLTRIG_SRC                                     */
+/*   Description:  source of request                                    */
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_SRC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_SRC_MASK      0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_TBLTRIG_CMD                                     */
+/*   Description:  incoming request                                     */
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_CMD_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_CMD_MASK      0x00000000003fc000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLTRIG_ACC                                     */
+/*   Description:  uncorrectable error, privilege bit                   */
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_ACC_SHFT      22
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_ACC_MASK      0x0000000000c00000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLTRIG_PRIGE                                   */
+/*   Description:  priority greater-equal                               */
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_PRIGE_SHFT    24
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_PRIGE_MASK    0x0000000001000000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLTRIG_DIRST                                   */
+/*   Description:  shrd,sxro,sub-state                                  */
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_DIRST_SHFT    25
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_DIRST_MASK    0x00000003fe000000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLTRIG_MYBIT                                   */
+/*   Description:  ptreq,timeq,timlast,timspec,onlyme,anytim,ptrii,src  */
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_MYBIT_SHFT    34
+#define SH_MD_DQLP_MMR_DIR_TBLTRIG_MYBIT_MASK    0x000003fc00000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_TBLMASK"                 */
+/*                        dir table trigger mask                        */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_DIR_TBLMASK               0x0000000100034020
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_MASK          0x000003ffffffffff
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLMASK_SRC                                     */
+/*   Description:  source of request                                    */
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_SRC_SHFT      0
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_SRC_MASK      0x0000000000003fff
+
+/*   SH_MD_DQLP_MMR_DIR_TBLMASK_CMD                                     */
+/*   Description:  incoming request                                     */
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_CMD_SHFT      14
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_CMD_MASK      0x00000000003fc000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLMASK_ACC                                     */
+/*   Description:  uncorrectable error, privilege bit                   */
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_ACC_SHFT      22
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_ACC_MASK      0x0000000000c00000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLMASK_PRIGE                                   */
+/*   Description:  priority greater-equal                               */
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_PRIGE_SHFT    24
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_PRIGE_MASK    0x0000000001000000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLMASK_DIRST                                   */
+/*   Description:  shrd,sxro,sub-state                                  */
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_DIRST_SHFT    25
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_DIRST_MASK    0x00000003fe000000
+
+/*   SH_MD_DQLP_MMR_DIR_TBLMASK_MYBIT                                   */
+/*   Description:  ptreq,timeq,timlast,timspec,onlyme,anytim,ptrii,src  */
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_MYBIT_SHFT    34
+#define SH_MD_DQLP_MMR_DIR_TBLMASK_MYBIT_MASK    0x000003fc00000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLP_MMR_XBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XBIST_H                   0x0000000100038000
+#define SH_MD_DQLP_MMR_XBIST_H_MASK              0x00000700ffffffff
+#define SH_MD_DQLP_MMR_XBIST_H_INIT              0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_H_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLP_MMR_XBIST_H_PAT_SHFT          0
+#define SH_MD_DQLP_MMR_XBIST_H_PAT_MASK          0x00000000ffffffff
+
+/*   SH_MD_DQLP_MMR_XBIST_H_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQLP_MMR_XBIST_H_INV_SHFT          40
+#define SH_MD_DQLP_MMR_XBIST_H_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_H_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQLP_MMR_XBIST_H_ROT_SHFT          41
+#define SH_MD_DQLP_MMR_XBIST_H_ROT_MASK          0x0000020000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_H_ARM                                         */
+/*   Description:  writing 1 arms data miscompare capture               */
+#define SH_MD_DQLP_MMR_XBIST_H_ARM_SHFT          42
+#define SH_MD_DQLP_MMR_XBIST_H_ARM_MASK          0x0000040000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLP_MMR_XBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XBIST_L                   0x0000000100038010
+#define SH_MD_DQLP_MMR_XBIST_L_MASK              0x00000300ffffffff
+#define SH_MD_DQLP_MMR_XBIST_L_INIT              0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_L_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLP_MMR_XBIST_L_PAT_SHFT          0
+#define SH_MD_DQLP_MMR_XBIST_L_PAT_MASK          0x00000000ffffffff
+
+/*   SH_MD_DQLP_MMR_XBIST_L_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQLP_MMR_XBIST_L_INV_SHFT          40
+#define SH_MD_DQLP_MMR_XBIST_L_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_L_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQLP_MMR_XBIST_L_ROT_SHFT          41
+#define SH_MD_DQLP_MMR_XBIST_L_ROT_MASK          0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_XBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XBIST_ERR_H               0x0000000100038020
+#define SH_MD_DQLP_MMR_XBIST_ERR_H_MASK          0x00000300ffffffff
+#define SH_MD_DQLP_MMR_XBIST_ERR_H_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_ERR_H_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLP_MMR_XBIST_ERR_H_PAT_SHFT      0
+#define SH_MD_DQLP_MMR_XBIST_ERR_H_PAT_MASK      0x00000000ffffffff
+
+/*   SH_MD_DQLP_MMR_XBIST_ERR_H_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQLP_MMR_XBIST_ERR_H_VAL_SHFT      40
+#define SH_MD_DQLP_MMR_XBIST_ERR_H_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_ERR_H_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQLP_MMR_XBIST_ERR_H_MORE_SHFT     41
+#define SH_MD_DQLP_MMR_XBIST_ERR_H_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_XBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_XBIST_ERR_L               0x0000000100038030
+#define SH_MD_DQLP_MMR_XBIST_ERR_L_MASK          0x00000300ffffffff
+#define SH_MD_DQLP_MMR_XBIST_ERR_L_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_ERR_L_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLP_MMR_XBIST_ERR_L_PAT_SHFT      0
+#define SH_MD_DQLP_MMR_XBIST_ERR_L_PAT_MASK      0x00000000ffffffff
+
+/*   SH_MD_DQLP_MMR_XBIST_ERR_L_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQLP_MMR_XBIST_ERR_L_VAL_SHFT      40
+#define SH_MD_DQLP_MMR_XBIST_ERR_L_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQLP_MMR_XBIST_ERR_L_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQLP_MMR_XBIST_ERR_L_MORE_SHFT     41
+#define SH_MD_DQLP_MMR_XBIST_ERR_L_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLP_MMR_YBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YBIST_H                   0x0000000100038800
+#define SH_MD_DQLP_MMR_YBIST_H_MASK              0x00000700ffffffff
+#define SH_MD_DQLP_MMR_YBIST_H_INIT              0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_H_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLP_MMR_YBIST_H_PAT_SHFT          0
+#define SH_MD_DQLP_MMR_YBIST_H_PAT_MASK          0x00000000ffffffff
+
+/*   SH_MD_DQLP_MMR_YBIST_H_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQLP_MMR_YBIST_H_INV_SHFT          40
+#define SH_MD_DQLP_MMR_YBIST_H_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_H_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQLP_MMR_YBIST_H_ROT_SHFT          41
+#define SH_MD_DQLP_MMR_YBIST_H_ROT_MASK          0x0000020000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_H_ARM                                         */
+/*   Description:  writing 1 arms data miscompare capture               */
+#define SH_MD_DQLP_MMR_YBIST_H_ARM_SHFT          42
+#define SH_MD_DQLP_MMR_YBIST_H_ARM_MASK          0x0000040000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLP_MMR_YBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YBIST_L                   0x0000000100038810
+#define SH_MD_DQLP_MMR_YBIST_L_MASK              0x00000300ffffffff
+#define SH_MD_DQLP_MMR_YBIST_L_INIT              0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_L_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLP_MMR_YBIST_L_PAT_SHFT          0
+#define SH_MD_DQLP_MMR_YBIST_L_PAT_MASK          0x00000000ffffffff
+
+/*   SH_MD_DQLP_MMR_YBIST_L_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQLP_MMR_YBIST_L_INV_SHFT          40
+#define SH_MD_DQLP_MMR_YBIST_L_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_L_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQLP_MMR_YBIST_L_ROT_SHFT          41
+#define SH_MD_DQLP_MMR_YBIST_L_ROT_MASK          0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_YBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YBIST_ERR_H               0x0000000100038820
+#define SH_MD_DQLP_MMR_YBIST_ERR_H_MASK          0x00000300ffffffff
+#define SH_MD_DQLP_MMR_YBIST_ERR_H_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_ERR_H_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLP_MMR_YBIST_ERR_H_PAT_SHFT      0
+#define SH_MD_DQLP_MMR_YBIST_ERR_H_PAT_MASK      0x00000000ffffffff
+
+/*   SH_MD_DQLP_MMR_YBIST_ERR_H_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQLP_MMR_YBIST_ERR_H_VAL_SHFT      40
+#define SH_MD_DQLP_MMR_YBIST_ERR_H_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_ERR_H_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQLP_MMR_YBIST_ERR_H_MORE_SHFT     41
+#define SH_MD_DQLP_MMR_YBIST_ERR_H_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_YBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLP_MMR_YBIST_ERR_L               0x0000000100038830
+#define SH_MD_DQLP_MMR_YBIST_ERR_L_MASK          0x00000300ffffffff
+#define SH_MD_DQLP_MMR_YBIST_ERR_L_INIT          0x0000000000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_ERR_L_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLP_MMR_YBIST_ERR_L_PAT_SHFT      0
+#define SH_MD_DQLP_MMR_YBIST_ERR_L_PAT_MASK      0x00000000ffffffff
+
+/*   SH_MD_DQLP_MMR_YBIST_ERR_L_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQLP_MMR_YBIST_ERR_L_VAL_SHFT      40
+#define SH_MD_DQLP_MMR_YBIST_ERR_L_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQLP_MMR_YBIST_ERR_L_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQLP_MMR_YBIST_ERR_L_MORE_SHFT     41
+#define SH_MD_DQLP_MMR_YBIST_ERR_L_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLS_MMR_XBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_XBIST_H                   0x0000000100048000
+#define SH_MD_DQLS_MMR_XBIST_H_MASK              0x000007ffffffffff
+#define SH_MD_DQLS_MMR_XBIST_H_INIT              0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_H_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLS_MMR_XBIST_H_PAT_SHFT          0
+#define SH_MD_DQLS_MMR_XBIST_H_PAT_MASK          0x000000ffffffffff
+
+/*   SH_MD_DQLS_MMR_XBIST_H_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQLS_MMR_XBIST_H_INV_SHFT          40
+#define SH_MD_DQLS_MMR_XBIST_H_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_H_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQLS_MMR_XBIST_H_ROT_SHFT          41
+#define SH_MD_DQLS_MMR_XBIST_H_ROT_MASK          0x0000020000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_H_ARM                                         */
+/*   Description:  writing 1 arms data miscompare capture               */
+#define SH_MD_DQLS_MMR_XBIST_H_ARM_SHFT          42
+#define SH_MD_DQLS_MMR_XBIST_H_ARM_MASK          0x0000040000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLS_MMR_XBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_XBIST_L                   0x0000000100048010
+#define SH_MD_DQLS_MMR_XBIST_L_MASK              0x000003ffffffffff
+#define SH_MD_DQLS_MMR_XBIST_L_INIT              0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_L_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLS_MMR_XBIST_L_PAT_SHFT          0
+#define SH_MD_DQLS_MMR_XBIST_L_PAT_MASK          0x000000ffffffffff
+
+/*   SH_MD_DQLS_MMR_XBIST_L_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQLS_MMR_XBIST_L_INV_SHFT          40
+#define SH_MD_DQLS_MMR_XBIST_L_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_L_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQLS_MMR_XBIST_L_ROT_SHFT          41
+#define SH_MD_DQLS_MMR_XBIST_L_ROT_MASK          0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLS_MMR_XBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_XBIST_ERR_H               0x0000000100048020
+#define SH_MD_DQLS_MMR_XBIST_ERR_H_MASK          0x000003ffffffffff
+#define SH_MD_DQLS_MMR_XBIST_ERR_H_INIT          0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_ERR_H_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLS_MMR_XBIST_ERR_H_PAT_SHFT      0
+#define SH_MD_DQLS_MMR_XBIST_ERR_H_PAT_MASK      0x000000ffffffffff
+
+/*   SH_MD_DQLS_MMR_XBIST_ERR_H_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQLS_MMR_XBIST_ERR_H_VAL_SHFT      40
+#define SH_MD_DQLS_MMR_XBIST_ERR_H_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_ERR_H_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQLS_MMR_XBIST_ERR_H_MORE_SHFT     41
+#define SH_MD_DQLS_MMR_XBIST_ERR_H_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLS_MMR_XBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_XBIST_ERR_L               0x0000000100048030
+#define SH_MD_DQLS_MMR_XBIST_ERR_L_MASK          0x000003ffffffffff
+#define SH_MD_DQLS_MMR_XBIST_ERR_L_INIT          0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_ERR_L_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLS_MMR_XBIST_ERR_L_PAT_SHFT      0
+#define SH_MD_DQLS_MMR_XBIST_ERR_L_PAT_MASK      0x000000ffffffffff
+
+/*   SH_MD_DQLS_MMR_XBIST_ERR_L_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQLS_MMR_XBIST_ERR_L_VAL_SHFT      40
+#define SH_MD_DQLS_MMR_XBIST_ERR_L_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQLS_MMR_XBIST_ERR_L_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQLS_MMR_XBIST_ERR_L_MORE_SHFT     41
+#define SH_MD_DQLS_MMR_XBIST_ERR_L_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLS_MMR_YBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_YBIST_H                   0x0000000100048800
+#define SH_MD_DQLS_MMR_YBIST_H_MASK              0x000007ffffffffff
+#define SH_MD_DQLS_MMR_YBIST_H_INIT              0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_H_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLS_MMR_YBIST_H_PAT_SHFT          0
+#define SH_MD_DQLS_MMR_YBIST_H_PAT_MASK          0x000000ffffffffff
+
+/*   SH_MD_DQLS_MMR_YBIST_H_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQLS_MMR_YBIST_H_INV_SHFT          40
+#define SH_MD_DQLS_MMR_YBIST_H_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_H_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQLS_MMR_YBIST_H_ROT_SHFT          41
+#define SH_MD_DQLS_MMR_YBIST_H_ROT_MASK          0x0000020000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_H_ARM                                         */
+/*   Description:  writing 1 arms data miscompare capture               */
+#define SH_MD_DQLS_MMR_YBIST_H_ARM_SHFT          42
+#define SH_MD_DQLS_MMR_YBIST_H_ARM_MASK          0x0000040000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLS_MMR_YBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_YBIST_L                   0x0000000100048810
+#define SH_MD_DQLS_MMR_YBIST_L_MASK              0x000003ffffffffff
+#define SH_MD_DQLS_MMR_YBIST_L_INIT              0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_L_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLS_MMR_YBIST_L_PAT_SHFT          0
+#define SH_MD_DQLS_MMR_YBIST_L_PAT_MASK          0x000000ffffffffff
+
+/*   SH_MD_DQLS_MMR_YBIST_L_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQLS_MMR_YBIST_L_INV_SHFT          40
+#define SH_MD_DQLS_MMR_YBIST_L_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_L_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQLS_MMR_YBIST_L_ROT_SHFT          41
+#define SH_MD_DQLS_MMR_YBIST_L_ROT_MASK          0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLS_MMR_YBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_YBIST_ERR_H               0x0000000100048820
+#define SH_MD_DQLS_MMR_YBIST_ERR_H_MASK          0x000003ffffffffff
+#define SH_MD_DQLS_MMR_YBIST_ERR_H_INIT          0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_ERR_H_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLS_MMR_YBIST_ERR_H_PAT_SHFT      0
+#define SH_MD_DQLS_MMR_YBIST_ERR_H_PAT_MASK      0x000000ffffffffff
+
+/*   SH_MD_DQLS_MMR_YBIST_ERR_H_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQLS_MMR_YBIST_ERR_H_VAL_SHFT      40
+#define SH_MD_DQLS_MMR_YBIST_ERR_H_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_ERR_H_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQLS_MMR_YBIST_ERR_H_MORE_SHFT     41
+#define SH_MD_DQLS_MMR_YBIST_ERR_H_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLS_MMR_YBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_YBIST_ERR_L               0x0000000100048830
+#define SH_MD_DQLS_MMR_YBIST_ERR_L_MASK          0x000003ffffffffff
+#define SH_MD_DQLS_MMR_YBIST_ERR_L_INIT          0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_ERR_L_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQLS_MMR_YBIST_ERR_L_PAT_SHFT      0
+#define SH_MD_DQLS_MMR_YBIST_ERR_L_PAT_MASK      0x000000ffffffffff
+
+/*   SH_MD_DQLS_MMR_YBIST_ERR_L_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQLS_MMR_YBIST_ERR_L_VAL_SHFT      40
+#define SH_MD_DQLS_MMR_YBIST_ERR_L_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQLS_MMR_YBIST_ERR_L_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQLS_MMR_YBIST_ERR_L_MORE_SHFT     41
+#define SH_MD_DQLS_MMR_YBIST_ERR_L_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQLS_MMR_JNR_DEBUG"                  */
+/*                    joiner/fct debug configuration                    */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_JNR_DEBUG                 0x0000000100049000
+#define SH_MD_DQLS_MMR_JNR_DEBUG_MASK            0x0000000000000003
+#define SH_MD_DQLS_MMR_JNR_DEBUG_INIT            0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_JNR_DEBUG_PX                                        */
+/*   Description:  select 0=pi 1=xn side                                */
+#define SH_MD_DQLS_MMR_JNR_DEBUG_PX_SHFT         0
+#define SH_MD_DQLS_MMR_JNR_DEBUG_PX_MASK         0x0000000000000001
+
+/*   SH_MD_DQLS_MMR_JNR_DEBUG_RW                                        */
+/*   Description:  select 0=read 1=write side                           */
+#define SH_MD_DQLS_MMR_JNR_DEBUG_RW_SHFT         1
+#define SH_MD_DQLS_MMR_JNR_DEBUG_RW_MASK         0x0000000000000002
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQLS_MMR_XAMOPW_ERR"                 */
+/*                  amo/partial rmw ecc error register                  */
+/* ==================================================================== */
+
+#define SH_MD_DQLS_MMR_XAMOPW_ERR                0x000000010004a000
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_MASK           0x0000000103ff03ff
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_INIT           0x0000000000000000
+
+/*   SH_MD_DQLS_MMR_XAMOPW_ERR_SSYN                                     */
+/*   Description:  store data syndrome                                  */
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_SSYN_SHFT      0
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_SSYN_MASK      0x00000000000000ff
+
+/*   SH_MD_DQLS_MMR_XAMOPW_ERR_SCOR                                     */
+/*   Description:  correctable ecc errror on store data                 */
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_SCOR_SHFT      8
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_SCOR_MASK      0x0000000000000100
+
+/*   SH_MD_DQLS_MMR_XAMOPW_ERR_SUNC                                     */
+/*   Description:  uncorrectable ecc errror on store data               */
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_SUNC_SHFT      9
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_SUNC_MASK      0x0000000000000200
+
+/*   SH_MD_DQLS_MMR_XAMOPW_ERR_RSYN                                     */
+/*   Description:  memory read data syndrome                            */
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_RSYN_SHFT      16
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_RSYN_MASK      0x0000000000ff0000
+
+/*   SH_MD_DQLS_MMR_XAMOPW_ERR_RCOR                                     */
+/*   Description:  correctable ecc errror on read data                  */
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_RCOR_SHFT      24
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_RCOR_MASK      0x0000000001000000
+
+/*   SH_MD_DQLS_MMR_XAMOPW_ERR_RUNC                                     */
+/*   Description:  uncorrectable ecc errror on read data                */
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_RUNC_SHFT      25
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_RUNC_MASK      0x0000000002000000
+
+/*   SH_MD_DQLS_MMR_XAMOPW_ERR_ARM                                      */
+/*   Description:  writing 1 arms ecc error capture                     */
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_ARM_SHFT       32
+#define SH_MD_DQLS_MMR_XAMOPW_ERR_ARM_MASK       0x0000000100000000
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQRP_MMR_DIR_CONFIG"                 */
+/*                     DQ directory config register                     */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_CONFIG                0x0000000100050000
+#define SH_MD_DQRP_MMR_DIR_CONFIG_MASK           0x000000000000001f
+#define SH_MD_DQRP_MMR_DIR_CONFIG_INIT           0x0000000000000010
+
+/*   SH_MD_DQRP_MMR_DIR_CONFIG_SYS_SIZE                                 */
+/*   Description:  system size code                                     */
+#define SH_MD_DQRP_MMR_DIR_CONFIG_SYS_SIZE_SHFT  0
+#define SH_MD_DQRP_MMR_DIR_CONFIG_SYS_SIZE_MASK  0x0000000000000007
+
+/*   SH_MD_DQRP_MMR_DIR_CONFIG_EN_DIRECC                                */
+/*   Description:  enable directory ecc correction                      */
+#define SH_MD_DQRP_MMR_DIR_CONFIG_EN_DIRECC_SHFT 3
+#define SH_MD_DQRP_MMR_DIR_CONFIG_EN_DIRECC_MASK 0x0000000000000008
+
+/*   SH_MD_DQRP_MMR_DIR_CONFIG_EN_DIRPOIS                               */
+/*   Description:  enable local poisoning for dir table fall-through    */
+#define SH_MD_DQRP_MMR_DIR_CONFIG_EN_DIRPOIS_SHFT 4
+#define SH_MD_DQRP_MMR_DIR_CONFIG_EN_DIRPOIS_MASK 0x0000000000000010
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC0"                */
+/*                      node [63:0] presence bits                       */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRESVEC0              0x0000000100050100
+#define SH_MD_DQRP_MMR_DIR_PRESVEC0_MASK         0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_PRESVEC0_INIT         0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRESVEC0_VEC                                    */
+/*   Description:  node presence bits, 1=present                        */
+#define SH_MD_DQRP_MMR_DIR_PRESVEC0_VEC_SHFT     0
+#define SH_MD_DQRP_MMR_DIR_PRESVEC0_VEC_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC1"                */
+/*                     node [127:64] presence bits                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRESVEC1              0x0000000100050110
+#define SH_MD_DQRP_MMR_DIR_PRESVEC1_MASK         0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_PRESVEC1_INIT         0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRESVEC1_VEC                                    */
+/*   Description:  node presence bits, 1=present                        */
+#define SH_MD_DQRP_MMR_DIR_PRESVEC1_VEC_SHFT     0
+#define SH_MD_DQRP_MMR_DIR_PRESVEC1_VEC_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC2"                */
+/*                     node [191:128] presence bits                     */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRESVEC2              0x0000000100050120
+#define SH_MD_DQRP_MMR_DIR_PRESVEC2_MASK         0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_PRESVEC2_INIT         0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRESVEC2_VEC                                    */
+/*   Description:  node presence bits, 1=present                        */
+#define SH_MD_DQRP_MMR_DIR_PRESVEC2_VEC_SHFT     0
+#define SH_MD_DQRP_MMR_DIR_PRESVEC2_VEC_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC3"                */
+/*                     node [255:192] presence bits                     */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRESVEC3              0x0000000100050130
+#define SH_MD_DQRP_MMR_DIR_PRESVEC3_MASK         0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_PRESVEC3_INIT         0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRESVEC3_VEC                                    */
+/*   Description:  node presence bits, 1=present                        */
+#define SH_MD_DQRP_MMR_DIR_PRESVEC3_VEC_SHFT     0
+#define SH_MD_DQRP_MMR_DIR_PRESVEC3_VEC_MASK     0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC0"                 */
+/*                        local vector for acc=0                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_LOCVEC0               0x0000000100050200
+#define SH_MD_DQRP_MMR_DIR_LOCVEC0_MASK          0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_LOCVEC0_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_LOCVEC0_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQRP_MMR_DIR_LOCVEC0_VEC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_LOCVEC0_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC1"                 */
+/*                        local vector for acc=1                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_LOCVEC1               0x0000000100050210
+#define SH_MD_DQRP_MMR_DIR_LOCVEC1_MASK          0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_LOCVEC1_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_LOCVEC1_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQRP_MMR_DIR_LOCVEC1_VEC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_LOCVEC1_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC2"                 */
+/*                        local vector for acc=2                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_LOCVEC2               0x0000000100050220
+#define SH_MD_DQRP_MMR_DIR_LOCVEC2_MASK          0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_LOCVEC2_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_LOCVEC2_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQRP_MMR_DIR_LOCVEC2_VEC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_LOCVEC2_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC3"                 */
+/*                        local vector for acc=3                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_LOCVEC3               0x0000000100050230
+#define SH_MD_DQRP_MMR_DIR_LOCVEC3_MASK          0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_LOCVEC3_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_LOCVEC3_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQRP_MMR_DIR_LOCVEC3_VEC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_LOCVEC3_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC4"                 */
+/*                        local vector for acc=4                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_LOCVEC4               0x0000000100050240
+#define SH_MD_DQRP_MMR_DIR_LOCVEC4_MASK          0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_LOCVEC4_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_LOCVEC4_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQRP_MMR_DIR_LOCVEC4_VEC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_LOCVEC4_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC5"                 */
+/*                        local vector for acc=5                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_LOCVEC5               0x0000000100050250
+#define SH_MD_DQRP_MMR_DIR_LOCVEC5_MASK          0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_LOCVEC5_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_LOCVEC5_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQRP_MMR_DIR_LOCVEC5_VEC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_LOCVEC5_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC6"                 */
+/*                        local vector for acc=6                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_LOCVEC6               0x0000000100050260
+#define SH_MD_DQRP_MMR_DIR_LOCVEC6_MASK          0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_LOCVEC6_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_LOCVEC6_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQRP_MMR_DIR_LOCVEC6_VEC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_LOCVEC6_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC7"                 */
+/*                        local vector for acc=7                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_LOCVEC7               0x0000000100050270
+#define SH_MD_DQRP_MMR_DIR_LOCVEC7_MASK          0xffffffffffffffff
+#define SH_MD_DQRP_MMR_DIR_LOCVEC7_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_LOCVEC7_VEC                                     */
+/*   Description:  1 node is local                                      */
+#define SH_MD_DQRP_MMR_DIR_LOCVEC7_VEC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_LOCVEC7_VEC_MASK      0xffffffffffffffff
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC0"                 */
+/*                      privilege vector for acc=0                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRIVEC0               0x0000000100050300
+#define SH_MD_DQRP_MMR_DIR_PRIVEC0_MASK          0x000000000fffffff
+#define SH_MD_DQRP_MMR_DIR_PRIVEC0_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC0_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC0_IN_SHFT       0
+#define SH_MD_DQRP_MMR_DIR_PRIVEC0_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC0_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC0_OUT_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_PRIVEC0_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC1"                 */
+/*                      privilege vector for acc=1                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRIVEC1               0x0000000100050310
+#define SH_MD_DQRP_MMR_DIR_PRIVEC1_MASK          0x000000000fffffff
+#define SH_MD_DQRP_MMR_DIR_PRIVEC1_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC1_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC1_IN_SHFT       0
+#define SH_MD_DQRP_MMR_DIR_PRIVEC1_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC1_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC1_OUT_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_PRIVEC1_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC2"                 */
+/*                      privilege vector for acc=2                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRIVEC2               0x0000000100050320
+#define SH_MD_DQRP_MMR_DIR_PRIVEC2_MASK          0x000000000fffffff
+#define SH_MD_DQRP_MMR_DIR_PRIVEC2_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC2_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC2_IN_SHFT       0
+#define SH_MD_DQRP_MMR_DIR_PRIVEC2_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC2_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC2_OUT_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_PRIVEC2_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC3"                 */
+/*                      privilege vector for acc=3                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRIVEC3               0x0000000100050330
+#define SH_MD_DQRP_MMR_DIR_PRIVEC3_MASK          0x000000000fffffff
+#define SH_MD_DQRP_MMR_DIR_PRIVEC3_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC3_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC3_IN_SHFT       0
+#define SH_MD_DQRP_MMR_DIR_PRIVEC3_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC3_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC3_OUT_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_PRIVEC3_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC4"                 */
+/*                      privilege vector for acc=4                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRIVEC4               0x0000000100050340
+#define SH_MD_DQRP_MMR_DIR_PRIVEC4_MASK          0x000000000fffffff
+#define SH_MD_DQRP_MMR_DIR_PRIVEC4_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC4_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC4_IN_SHFT       0
+#define SH_MD_DQRP_MMR_DIR_PRIVEC4_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC4_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC4_OUT_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_PRIVEC4_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC5"                 */
+/*                      privilege vector for acc=5                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRIVEC5               0x0000000100050350
+#define SH_MD_DQRP_MMR_DIR_PRIVEC5_MASK          0x000000000fffffff
+#define SH_MD_DQRP_MMR_DIR_PRIVEC5_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC5_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC5_IN_SHFT       0
+#define SH_MD_DQRP_MMR_DIR_PRIVEC5_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC5_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC5_OUT_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_PRIVEC5_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC6"                 */
+/*                      privilege vector for acc=6                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRIVEC6               0x0000000100050360
+#define SH_MD_DQRP_MMR_DIR_PRIVEC6_MASK          0x000000000fffffff
+#define SH_MD_DQRP_MMR_DIR_PRIVEC6_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC6_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC6_IN_SHFT       0
+#define SH_MD_DQRP_MMR_DIR_PRIVEC6_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC6_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC6_OUT_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_PRIVEC6_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC7"                 */
+/*                      privilege vector for acc=7                      */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_PRIVEC7               0x0000000100050370
+#define SH_MD_DQRP_MMR_DIR_PRIVEC7_MASK          0x000000000fffffff
+#define SH_MD_DQRP_MMR_DIR_PRIVEC7_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC7_IN                                      */
+/*   Description:  in partition privileges, locvec bit=1                */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC7_IN_SHFT       0
+#define SH_MD_DQRP_MMR_DIR_PRIVEC7_IN_MASK       0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_PRIVEC7_OUT                                     */
+/*   Description:  out of partition privileges, locvec bit=0            */
+#define SH_MD_DQRP_MMR_DIR_PRIVEC7_OUT_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_PRIVEC7_OUT_MASK      0x000000000fffc000
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQRP_MMR_DIR_TIMER"                  */
+/*                            MD SXRO timer                             */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_TIMER                 0x0000000100050400
+#define SH_MD_DQRP_MMR_DIR_TIMER_MASK            0x00000000003fffff
+#define SH_MD_DQRP_MMR_DIR_TIMER_INIT            0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_TIMER_TIMER_DIV                                 */
+/*   Description:  timer divide register                                */
+#define SH_MD_DQRP_MMR_DIR_TIMER_TIMER_DIV_SHFT  0
+#define SH_MD_DQRP_MMR_DIR_TIMER_TIMER_DIV_MASK  0x0000000000000fff
+
+/*   SH_MD_DQRP_MMR_DIR_TIMER_TIMER_EN                                  */
+/*   Description:  timer enable                                         */
+#define SH_MD_DQRP_MMR_DIR_TIMER_TIMER_EN_SHFT   12
+#define SH_MD_DQRP_MMR_DIR_TIMER_TIMER_EN_MASK   0x0000000000001000
+
+/*   SH_MD_DQRP_MMR_DIR_TIMER_TIMER_CUR                                 */
+/*   Description:  value of current timer                               */
+#define SH_MD_DQRP_MMR_DIR_TIMER_TIMER_CUR_SHFT  13
+#define SH_MD_DQRP_MMR_DIR_TIMER_TIMER_CUR_MASK  0x00000000003fe000
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY"               */
+/*                       directory pio write data                       */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY           0x0000000100051000
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_MASK      0x03ffffffffffffff
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_INIT      0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_DIRA                                */
+/*   Description:  directory entry A                                    */
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_DIRA_SHFT 0
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_DIRA_MASK 0x0000000003ffffff
+
+/*   SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_DIRB                                */
+/*   Description:  directory entry B                                    */
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_DIRB_SHFT 26
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_DIRB_MASK 0x000ffffffc000000
+
+/*   SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_PRI                                 */
+/*   Description:  directory priority                                   */
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_PRI_SHFT  52
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_PRI_MASK  0x0070000000000000
+
+/*   SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_ACC                                 */
+/*   Description:  directory access bits                                */
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_ACC_SHFT  55
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY_ACC_MASK  0x0380000000000000
+
+/* ==================================================================== */
+/*               Register "SH_MD_DQRP_MMR_PIOWD_DIR_ECC"                */
+/*                        directory ecc register                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ECC             0x0000000100051010
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ECC_MASK        0x0000000000003fff
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ECC_INIT        0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_PIOWD_DIR_ECC_ECCA                                  */
+/*   Description:  XOR bits for directory ECC group 1                   */
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ECC_ECCA_SHFT   0
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ECC_ECCA_MASK   0x000000000000007f
+
+/*   SH_MD_DQRP_MMR_PIOWD_DIR_ECC_ECCB                                  */
+/*   Description:  XOR bits for directory ECC group 2                   */
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ECC_ECCB_SHFT   7
+#define SH_MD_DQRP_MMR_PIOWD_DIR_ECC_ECCB_MASK   0x0000000000003f80
+
+/* ==================================================================== */
+/*             Register "SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY"              */
+/*                      x directory pio read data                       */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY         0x0000000100052000
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_MASK    0x0fffffffffffffff
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_INIT    0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_DIRA                              */
+/*   Description:  directory entry A                                    */
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_DIRA_SHFT 0
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_DIRA_MASK 0x0000000003ffffff
+
+/*   SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_DIRB                              */
+/*   Description:  directory entry B                                    */
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_DIRB_SHFT 26
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_DIRB_MASK 0x000ffffffc000000
+
+/*   SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_PRI                               */
+/*   Description:  directory priority                                   */
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_PRI_SHFT 52
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_PRI_MASK 0x0070000000000000
+
+/*   SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_ACC                               */
+/*   Description:  directory access bits                                */
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_ACC_SHFT 55
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_ACC_MASK 0x0380000000000000
+
+/*   SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_COR                               */
+/*   Description:  correctable ecc error                                */
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_COR_SHFT 58
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_COR_MASK 0x0400000000000000
+
+/*   SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_UNC                               */
+/*   Description:  uncorrectable ecc error                              */
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_UNC_SHFT 59
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY_UNC_MASK 0x0800000000000000
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQRP_MMR_XPIORD_XDIR_ECC"               */
+/*                           x directory ecc                            */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ECC           0x0000000100052010
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ECC_MASK      0x0000000000003fff
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ECC_INIT      0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XPIORD_XDIR_ECC_ECCA                                */
+/*   Description:  group 1 ecc                                          */
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ECC_ECCA_SHFT 0
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ECC_ECCA_MASK 0x000000000000007f
+
+/*   SH_MD_DQRP_MMR_XPIORD_XDIR_ECC_ECCB                                */
+/*   Description:  group 2 ecc                                          */
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ECC_ECCB_SHFT 7
+#define SH_MD_DQRP_MMR_XPIORD_XDIR_ECC_ECCB_MASK 0x0000000000003f80
+
+/* ==================================================================== */
+/*             Register "SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY"              */
+/*                      y directory pio read data                       */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY         0x0000000100052800
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_MASK    0x0fffffffffffffff
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_INIT    0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_DIRA                              */
+/*   Description:  directory entry A                                    */
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_DIRA_SHFT 0
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_DIRA_MASK 0x0000000003ffffff
+
+/*   SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_DIRB                              */
+/*   Description:  directory entry B                                    */
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_DIRB_SHFT 26
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_DIRB_MASK 0x000ffffffc000000
+
+/*   SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_PRI                               */
+/*   Description:  directory priority                                   */
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_PRI_SHFT 52
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_PRI_MASK 0x0070000000000000
+
+/*   SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_ACC                               */
+/*   Description:  directory access bits                                */
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_ACC_SHFT 55
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_ACC_MASK 0x0380000000000000
+
+/*   SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_COR                               */
+/*   Description:  correctable ecc error                                */
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_COR_SHFT 58
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_COR_MASK 0x0400000000000000
+
+/*   SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_UNC                               */
+/*   Description:  uncorrectable ecc error                              */
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_UNC_SHFT 59
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY_UNC_MASK 0x0800000000000000
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQRP_MMR_YPIORD_YDIR_ECC"               */
+/*                           y directory ecc                            */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ECC           0x0000000100052810
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ECC_MASK      0x0000000000003fff
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ECC_INIT      0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YPIORD_YDIR_ECC_ECCA                                */
+/*   Description:  group 1 ecc                                          */
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ECC_ECCA_SHFT 0
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ECC_ECCA_MASK 0x000000000000007f
+
+/*   SH_MD_DQRP_MMR_YPIORD_YDIR_ECC_ECCB                                */
+/*   Description:  group 2 ecc                                          */
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ECC_ECCB_SHFT 7
+#define SH_MD_DQRP_MMR_YPIORD_YDIR_ECC_ECCB_MASK 0x0000000000003f80
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XCERR1"                   */
+/*              correctable dir ecc group 1 error register              */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XCERR1                    0x0000000100053000
+#define SH_MD_DQRP_MMR_XCERR1_MASK               0x0000007fffffffff
+#define SH_MD_DQRP_MMR_XCERR1_INIT               0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XCERR1_GRP1                                         */
+/*   Description:  ecc group 1 bits                                     */
+#define SH_MD_DQRP_MMR_XCERR1_GRP1_SHFT          0
+#define SH_MD_DQRP_MMR_XCERR1_GRP1_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQRP_MMR_XCERR1_VAL                                          */
+/*   Description:  correctable ecc error in group 1 bits                */
+#define SH_MD_DQRP_MMR_XCERR1_VAL_SHFT           36
+#define SH_MD_DQRP_MMR_XCERR1_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQRP_MMR_XCERR1_MORE                                         */
+/*   Description:  more than one correctable ecc error in group 1       */
+#define SH_MD_DQRP_MMR_XCERR1_MORE_SHFT          37
+#define SH_MD_DQRP_MMR_XCERR1_MORE_MASK          0x0000002000000000
+
+/*   SH_MD_DQRP_MMR_XCERR1_ARM                                          */
+/*   Description:  writing 1 arms uncorrectable ecc error capture       */
+#define SH_MD_DQRP_MMR_XCERR1_ARM_SHFT           38
+#define SH_MD_DQRP_MMR_XCERR1_ARM_MASK           0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XCERR2"                   */
+/*              correctable dir ecc group 2 error register              */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XCERR2                    0x0000000100053010
+#define SH_MD_DQRP_MMR_XCERR2_MASK               0x0000003fffffffff
+#define SH_MD_DQRP_MMR_XCERR2_INIT               0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XCERR2_GRP2                                         */
+/*   Description:  ecc group 2 bits                                     */
+#define SH_MD_DQRP_MMR_XCERR2_GRP2_SHFT          0
+#define SH_MD_DQRP_MMR_XCERR2_GRP2_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQRP_MMR_XCERR2_VAL                                          */
+/*   Description:  correctable ecc error in group 2 bits                */
+#define SH_MD_DQRP_MMR_XCERR2_VAL_SHFT           36
+#define SH_MD_DQRP_MMR_XCERR2_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQRP_MMR_XCERR2_MORE                                         */
+/*   Description:  more than one correctable ecc error in group 2       */
+#define SH_MD_DQRP_MMR_XCERR2_MORE_SHFT          37
+#define SH_MD_DQRP_MMR_XCERR2_MORE_MASK          0x0000002000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XUERR1"                   */
+/*             uncorrectable dir ecc group 1 error register             */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XUERR1                    0x0000000100053020
+#define SH_MD_DQRP_MMR_XUERR1_MASK               0x0000007fffffffff
+#define SH_MD_DQRP_MMR_XUERR1_INIT               0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XUERR1_GRP1                                         */
+/*   Description:  ecc group 1 bits                                     */
+#define SH_MD_DQRP_MMR_XUERR1_GRP1_SHFT          0
+#define SH_MD_DQRP_MMR_XUERR1_GRP1_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQRP_MMR_XUERR1_VAL                                          */
+/*   Description:  uncorrectable ecc error in group 1 bits              */
+#define SH_MD_DQRP_MMR_XUERR1_VAL_SHFT           36
+#define SH_MD_DQRP_MMR_XUERR1_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQRP_MMR_XUERR1_MORE                                         */
+/*   Description:  more than one uncorrectable ecc error in group 1     */
+#define SH_MD_DQRP_MMR_XUERR1_MORE_SHFT          37
+#define SH_MD_DQRP_MMR_XUERR1_MORE_MASK          0x0000002000000000
+
+/*   SH_MD_DQRP_MMR_XUERR1_ARM                                          */
+/*   Description:  writing 1 arms uncorrectable ecc error capture       */
+#define SH_MD_DQRP_MMR_XUERR1_ARM_SHFT           38
+#define SH_MD_DQRP_MMR_XUERR1_ARM_MASK           0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XUERR2"                   */
+/*             uncorrectable dir ecc group 2 error register             */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XUERR2                    0x0000000100053030
+#define SH_MD_DQRP_MMR_XUERR2_MASK               0x0000003fffffffff
+#define SH_MD_DQRP_MMR_XUERR2_INIT               0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XUERR2_GRP2                                         */
+/*   Description:  ecc group 2 bits                                     */
+#define SH_MD_DQRP_MMR_XUERR2_GRP2_SHFT          0
+#define SH_MD_DQRP_MMR_XUERR2_GRP2_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQRP_MMR_XUERR2_VAL                                          */
+/*   Description:  uncorrectable ecc error in group 2 bits              */
+#define SH_MD_DQRP_MMR_XUERR2_VAL_SHFT           36
+#define SH_MD_DQRP_MMR_XUERR2_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQRP_MMR_XUERR2_MORE                                         */
+/*   Description:  more than one uncorrectable ecc error in group 2     */
+#define SH_MD_DQRP_MMR_XUERR2_MORE_SHFT          37
+#define SH_MD_DQRP_MMR_XUERR2_MORE_MASK          0x0000002000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XPERR"                    */
+/*                       protocol error register                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XPERR                     0x0000000100053040
+#define SH_MD_DQRP_MMR_XPERR_MASK                0x7fffffffffffffff
+#define SH_MD_DQRP_MMR_XPERR_INIT                0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XPERR_DIR                                           */
+/*   Description:  directory entry                                      */
+#define SH_MD_DQRP_MMR_XPERR_DIR_SHFT            0
+#define SH_MD_DQRP_MMR_XPERR_DIR_MASK            0x0000000003ffffff
+
+/*   SH_MD_DQRP_MMR_XPERR_CMD                                           */
+/*   Description:  incoming command                                     */
+#define SH_MD_DQRP_MMR_XPERR_CMD_SHFT            26
+#define SH_MD_DQRP_MMR_XPERR_CMD_MASK            0x00000003fc000000
+
+/*   SH_MD_DQRP_MMR_XPERR_SRC                                           */
+/*   Description:  source node of dir operation                         */
+#define SH_MD_DQRP_MMR_XPERR_SRC_SHFT            34
+#define SH_MD_DQRP_MMR_XPERR_SRC_MASK            0x0000fffc00000000
+
+/*   SH_MD_DQRP_MMR_XPERR_PRIGE                                         */
+/*   Description:  priority was greater-equal                           */
+#define SH_MD_DQRP_MMR_XPERR_PRIGE_SHFT          48
+#define SH_MD_DQRP_MMR_XPERR_PRIGE_MASK          0x0001000000000000
+
+/*   SH_MD_DQRP_MMR_XPERR_PRIV                                          */
+/*   Description:  access privilege bit                                 */
+#define SH_MD_DQRP_MMR_XPERR_PRIV_SHFT           49
+#define SH_MD_DQRP_MMR_XPERR_PRIV_MASK           0x0002000000000000
+
+/*   SH_MD_DQRP_MMR_XPERR_COR                                           */
+/*   Description:  correctable ecc error                                */
+#define SH_MD_DQRP_MMR_XPERR_COR_SHFT            50
+#define SH_MD_DQRP_MMR_XPERR_COR_MASK            0x0004000000000000
+
+/*   SH_MD_DQRP_MMR_XPERR_UNC                                           */
+/*   Description:  uncorrectable ecc error                              */
+#define SH_MD_DQRP_MMR_XPERR_UNC_SHFT            51
+#define SH_MD_DQRP_MMR_XPERR_UNC_MASK            0x0008000000000000
+
+/*   SH_MD_DQRP_MMR_XPERR_MYBIT                                         */
+/*   Description:  ptreq,timeq,timlast,timspec,onlyme,anytim,ptrii,src  */
+#define SH_MD_DQRP_MMR_XPERR_MYBIT_SHFT          52
+#define SH_MD_DQRP_MMR_XPERR_MYBIT_MASK          0x0ff0000000000000
+
+/*   SH_MD_DQRP_MMR_XPERR_VAL                                           */
+/*   Description:  protocol error info valid                            */
+#define SH_MD_DQRP_MMR_XPERR_VAL_SHFT            60
+#define SH_MD_DQRP_MMR_XPERR_VAL_MASK            0x1000000000000000
+
+/*   SH_MD_DQRP_MMR_XPERR_MORE                                          */
+/*   Description:  more than one protocol error                         */
+#define SH_MD_DQRP_MMR_XPERR_MORE_SHFT           61
+#define SH_MD_DQRP_MMR_XPERR_MORE_MASK           0x2000000000000000
+
+/*   SH_MD_DQRP_MMR_XPERR_ARM                                           */
+/*   Description:  writing 1 arms error capture                         */
+#define SH_MD_DQRP_MMR_XPERR_ARM_SHFT            62
+#define SH_MD_DQRP_MMR_XPERR_ARM_MASK            0x4000000000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YCERR1"                   */
+/*              correctable dir ecc group 1 error register              */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YCERR1                    0x0000000100053800
+#define SH_MD_DQRP_MMR_YCERR1_MASK               0x0000007fffffffff
+#define SH_MD_DQRP_MMR_YCERR1_INIT               0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YCERR1_GRP1                                         */
+/*   Description:  ecc group 1 bits                                     */
+#define SH_MD_DQRP_MMR_YCERR1_GRP1_SHFT          0
+#define SH_MD_DQRP_MMR_YCERR1_GRP1_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQRP_MMR_YCERR1_VAL                                          */
+/*   Description:  correctable ecc error in group 1 bits                */
+#define SH_MD_DQRP_MMR_YCERR1_VAL_SHFT           36
+#define SH_MD_DQRP_MMR_YCERR1_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQRP_MMR_YCERR1_MORE                                         */
+/*   Description:  more than one correctable ecc error in group 1       */
+#define SH_MD_DQRP_MMR_YCERR1_MORE_SHFT          37
+#define SH_MD_DQRP_MMR_YCERR1_MORE_MASK          0x0000002000000000
+
+/*   SH_MD_DQRP_MMR_YCERR1_ARM                                          */
+/*   Description:  writing 1 arms uncorrectable ecc error capture       */
+#define SH_MD_DQRP_MMR_YCERR1_ARM_SHFT           38
+#define SH_MD_DQRP_MMR_YCERR1_ARM_MASK           0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YCERR2"                   */
+/*              correctable dir ecc group 2 error register              */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YCERR2                    0x0000000100053810
+#define SH_MD_DQRP_MMR_YCERR2_MASK               0x0000003fffffffff
+#define SH_MD_DQRP_MMR_YCERR2_INIT               0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YCERR2_GRP2                                         */
+/*   Description:  ecc group 2 bits                                     */
+#define SH_MD_DQRP_MMR_YCERR2_GRP2_SHFT          0
+#define SH_MD_DQRP_MMR_YCERR2_GRP2_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQRP_MMR_YCERR2_VAL                                          */
+/*   Description:  correctable ecc error in group 2 bits                */
+#define SH_MD_DQRP_MMR_YCERR2_VAL_SHFT           36
+#define SH_MD_DQRP_MMR_YCERR2_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQRP_MMR_YCERR2_MORE                                         */
+/*   Description:  more than one correctable ecc error in group 2       */
+#define SH_MD_DQRP_MMR_YCERR2_MORE_SHFT          37
+#define SH_MD_DQRP_MMR_YCERR2_MORE_MASK          0x0000002000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YUERR1"                   */
+/*             uncorrectable dir ecc group 1 error register             */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YUERR1                    0x0000000100053820
+#define SH_MD_DQRP_MMR_YUERR1_MASK               0x0000007fffffffff
+#define SH_MD_DQRP_MMR_YUERR1_INIT               0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YUERR1_GRP1                                         */
+/*   Description:  ecc group 1 bits                                     */
+#define SH_MD_DQRP_MMR_YUERR1_GRP1_SHFT          0
+#define SH_MD_DQRP_MMR_YUERR1_GRP1_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQRP_MMR_YUERR1_VAL                                          */
+/*   Description:  uncorrectable ecc error in group 1 bits              */
+#define SH_MD_DQRP_MMR_YUERR1_VAL_SHFT           36
+#define SH_MD_DQRP_MMR_YUERR1_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQRP_MMR_YUERR1_MORE                                         */
+/*   Description:  more than one uncorrectable ecc error in group 1     */
+#define SH_MD_DQRP_MMR_YUERR1_MORE_SHFT          37
+#define SH_MD_DQRP_MMR_YUERR1_MORE_MASK          0x0000002000000000
+
+/*   SH_MD_DQRP_MMR_YUERR1_ARM                                          */
+/*   Description:  writing 1 arms uncorrectable ecc error capture       */
+#define SH_MD_DQRP_MMR_YUERR1_ARM_SHFT           38
+#define SH_MD_DQRP_MMR_YUERR1_ARM_MASK           0x0000004000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YUERR2"                   */
+/*             uncorrectable dir ecc group 2 error register             */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YUERR2                    0x0000000100053830
+#define SH_MD_DQRP_MMR_YUERR2_MASK               0x0000003fffffffff
+#define SH_MD_DQRP_MMR_YUERR2_INIT               0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YUERR2_GRP2                                         */
+/*   Description:  ecc group 2 bits                                     */
+#define SH_MD_DQRP_MMR_YUERR2_GRP2_SHFT          0
+#define SH_MD_DQRP_MMR_YUERR2_GRP2_MASK          0x0000000fffffffff
+
+/*   SH_MD_DQRP_MMR_YUERR2_VAL                                          */
+/*   Description:  uncorrectable ecc error in group 2 bits              */
+#define SH_MD_DQRP_MMR_YUERR2_VAL_SHFT           36
+#define SH_MD_DQRP_MMR_YUERR2_VAL_MASK           0x0000001000000000
+
+/*   SH_MD_DQRP_MMR_YUERR2_MORE                                         */
+/*   Description:  more than one uncorrectable ecc error in group 2     */
+#define SH_MD_DQRP_MMR_YUERR2_MORE_SHFT          37
+#define SH_MD_DQRP_MMR_YUERR2_MORE_MASK          0x0000002000000000
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YPERR"                    */
+/*                       protocol error register                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YPERR                     0x0000000100053840
+#define SH_MD_DQRP_MMR_YPERR_MASK                0x7fffffffffffffff
+#define SH_MD_DQRP_MMR_YPERR_INIT                0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YPERR_DIR                                           */
+/*   Description:  directory entry                                      */
+#define SH_MD_DQRP_MMR_YPERR_DIR_SHFT            0
+#define SH_MD_DQRP_MMR_YPERR_DIR_MASK            0x0000000003ffffff
+
+/*   SH_MD_DQRP_MMR_YPERR_CMD                                           */
+/*   Description:  incoming command                                     */
+#define SH_MD_DQRP_MMR_YPERR_CMD_SHFT            26
+#define SH_MD_DQRP_MMR_YPERR_CMD_MASK            0x00000003fc000000
+
+/*   SH_MD_DQRP_MMR_YPERR_SRC                                           */
+/*   Description:  source node of dir operation                         */
+#define SH_MD_DQRP_MMR_YPERR_SRC_SHFT            34
+#define SH_MD_DQRP_MMR_YPERR_SRC_MASK            0x0000fffc00000000
+
+/*   SH_MD_DQRP_MMR_YPERR_PRIGE                                         */
+/*   Description:  priority was greater-equal                           */
+#define SH_MD_DQRP_MMR_YPERR_PRIGE_SHFT          48
+#define SH_MD_DQRP_MMR_YPERR_PRIGE_MASK          0x0001000000000000
+
+/*   SH_MD_DQRP_MMR_YPERR_PRIV                                          */
+/*   Description:  access privilege bit                                 */
+#define SH_MD_DQRP_MMR_YPERR_PRIV_SHFT           49
+#define SH_MD_DQRP_MMR_YPERR_PRIV_MASK           0x0002000000000000
+
+/*   SH_MD_DQRP_MMR_YPERR_COR                                           */
+/*   Description:  correctable ecc error                                */
+#define SH_MD_DQRP_MMR_YPERR_COR_SHFT            50
+#define SH_MD_DQRP_MMR_YPERR_COR_MASK            0x0004000000000000
+
+/*   SH_MD_DQRP_MMR_YPERR_UNC                                           */
+/*   Description:  uncorrectable ecc error                              */
+#define SH_MD_DQRP_MMR_YPERR_UNC_SHFT            51
+#define SH_MD_DQRP_MMR_YPERR_UNC_MASK            0x0008000000000000
+
+/*   SH_MD_DQRP_MMR_YPERR_MYBIT                                         */
+/*   Description:  ptreq,timeq,timlast,timspec,onlyme,anytim,ptrii,src  */
+#define SH_MD_DQRP_MMR_YPERR_MYBIT_SHFT          52
+#define SH_MD_DQRP_MMR_YPERR_MYBIT_MASK          0x0ff0000000000000
+
+/*   SH_MD_DQRP_MMR_YPERR_VAL                                           */
+/*   Description:  protocol error info valid                            */
+#define SH_MD_DQRP_MMR_YPERR_VAL_SHFT            60
+#define SH_MD_DQRP_MMR_YPERR_VAL_MASK            0x1000000000000000
+
+/*   SH_MD_DQRP_MMR_YPERR_MORE                                          */
+/*   Description:  more than one protocol error                         */
+#define SH_MD_DQRP_MMR_YPERR_MORE_SHFT           61
+#define SH_MD_DQRP_MMR_YPERR_MORE_MASK           0x2000000000000000
+
+/*   SH_MD_DQRP_MMR_YPERR_ARM                                           */
+/*   Description:  writing 1 arms error capture                         */
+#define SH_MD_DQRP_MMR_YPERR_ARM_SHFT            62
+#define SH_MD_DQRP_MMR_YPERR_ARM_MASK            0x4000000000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_CMDTRIG"                 */
+/*                             cmd triggers                             */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG               0x0000000100054000
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_MASK          0x00000000ffffffff
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD0                                    */
+/*   Description:  command trigger 0                                    */
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD0_SHFT     0
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD0_MASK     0x00000000000000ff
+
+/*   SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD1                                    */
+/*   Description:  command trigger 1                                    */
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD1_SHFT     8
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD1_MASK     0x000000000000ff00
+
+/*   SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD2                                    */
+/*   Description:  command trigger 2                                    */
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD2_SHFT     16
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD2_MASK     0x0000000000ff0000
+
+/*   SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD3                                    */
+/*   Description:  command trigger 3                                    */
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD3_SHFT     24
+#define SH_MD_DQRP_MMR_DIR_CMDTRIG_CMD3_MASK     0x00000000ff000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_TBLTRIG"                 */
+/*                          dir table trigger                           */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG               0x0000000100054010
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_MASK          0x000003ffffffffff
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLTRIG_SRC                                     */
+/*   Description:  source of request                                    */
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_SRC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_SRC_MASK      0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_TBLTRIG_CMD                                     */
+/*   Description:  incoming request                                     */
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_CMD_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_CMD_MASK      0x00000000003fc000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLTRIG_ACC                                     */
+/*   Description:  uncorrectable error, privilege bit                   */
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_ACC_SHFT      22
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_ACC_MASK      0x0000000000c00000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLTRIG_PRIGE                                   */
+/*   Description:  priority greater-equal                               */
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_PRIGE_SHFT    24
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_PRIGE_MASK    0x0000000001000000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLTRIG_DIRST                                   */
+/*   Description:  shrd,sxro,sub-state                                  */
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_DIRST_SHFT    25
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_DIRST_MASK    0x00000003fe000000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLTRIG_MYBIT                                   */
+/*   Description:  ptreq,timeq,timlast,timspec,onlyme,anytim,ptrii,src  */
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_MYBIT_SHFT    34
+#define SH_MD_DQRP_MMR_DIR_TBLTRIG_MYBIT_MASK    0x000003fc00000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_TBLMASK"                 */
+/*                        dir table trigger mask                        */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_DIR_TBLMASK               0x0000000100054020
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_MASK          0x000003ffffffffff
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLMASK_SRC                                     */
+/*   Description:  source of request                                    */
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_SRC_SHFT      0
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_SRC_MASK      0x0000000000003fff
+
+/*   SH_MD_DQRP_MMR_DIR_TBLMASK_CMD                                     */
+/*   Description:  incoming request                                     */
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_CMD_SHFT      14
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_CMD_MASK      0x00000000003fc000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLMASK_ACC                                     */
+/*   Description:  uncorrectable error, privilege bit                   */
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_ACC_SHFT      22
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_ACC_MASK      0x0000000000c00000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLMASK_PRIGE                                   */
+/*   Description:  priority greater-equal                               */
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_PRIGE_SHFT    24
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_PRIGE_MASK    0x0000000001000000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLMASK_DIRST                                   */
+/*   Description:  shrd,sxro,sub-state                                  */
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_DIRST_SHFT    25
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_DIRST_MASK    0x00000003fe000000
+
+/*   SH_MD_DQRP_MMR_DIR_TBLMASK_MYBIT                                   */
+/*   Description:  ptreq,timeq,timlast,timspec,onlyme,anytim,ptrii,src  */
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_MYBIT_SHFT    34
+#define SH_MD_DQRP_MMR_DIR_TBLMASK_MYBIT_MASK    0x000003fc00000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRP_MMR_XBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XBIST_H                   0x0000000100058000
+#define SH_MD_DQRP_MMR_XBIST_H_MASK              0x00000700ffffffff
+#define SH_MD_DQRP_MMR_XBIST_H_INIT              0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_H_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRP_MMR_XBIST_H_PAT_SHFT          0
+#define SH_MD_DQRP_MMR_XBIST_H_PAT_MASK          0x00000000ffffffff
+
+/*   SH_MD_DQRP_MMR_XBIST_H_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQRP_MMR_XBIST_H_INV_SHFT          40
+#define SH_MD_DQRP_MMR_XBIST_H_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_H_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQRP_MMR_XBIST_H_ROT_SHFT          41
+#define SH_MD_DQRP_MMR_XBIST_H_ROT_MASK          0x0000020000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_H_ARM                                         */
+/*   Description:  writing 1 arms data miscompare capture               */
+#define SH_MD_DQRP_MMR_XBIST_H_ARM_SHFT          42
+#define SH_MD_DQRP_MMR_XBIST_H_ARM_MASK          0x0000040000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRP_MMR_XBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XBIST_L                   0x0000000100058010
+#define SH_MD_DQRP_MMR_XBIST_L_MASK              0x00000300ffffffff
+#define SH_MD_DQRP_MMR_XBIST_L_INIT              0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_L_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRP_MMR_XBIST_L_PAT_SHFT          0
+#define SH_MD_DQRP_MMR_XBIST_L_PAT_MASK          0x00000000ffffffff
+
+/*   SH_MD_DQRP_MMR_XBIST_L_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQRP_MMR_XBIST_L_INV_SHFT          40
+#define SH_MD_DQRP_MMR_XBIST_L_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_L_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQRP_MMR_XBIST_L_ROT_SHFT          41
+#define SH_MD_DQRP_MMR_XBIST_L_ROT_MASK          0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_XBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XBIST_ERR_H               0x0000000100058020
+#define SH_MD_DQRP_MMR_XBIST_ERR_H_MASK          0x00000300ffffffff
+#define SH_MD_DQRP_MMR_XBIST_ERR_H_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_ERR_H_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRP_MMR_XBIST_ERR_H_PAT_SHFT      0
+#define SH_MD_DQRP_MMR_XBIST_ERR_H_PAT_MASK      0x00000000ffffffff
+
+/*   SH_MD_DQRP_MMR_XBIST_ERR_H_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQRP_MMR_XBIST_ERR_H_VAL_SHFT      40
+#define SH_MD_DQRP_MMR_XBIST_ERR_H_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_ERR_H_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQRP_MMR_XBIST_ERR_H_MORE_SHFT     41
+#define SH_MD_DQRP_MMR_XBIST_ERR_H_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_XBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_XBIST_ERR_L               0x0000000100058030
+#define SH_MD_DQRP_MMR_XBIST_ERR_L_MASK          0x00000300ffffffff
+#define SH_MD_DQRP_MMR_XBIST_ERR_L_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_ERR_L_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRP_MMR_XBIST_ERR_L_PAT_SHFT      0
+#define SH_MD_DQRP_MMR_XBIST_ERR_L_PAT_MASK      0x00000000ffffffff
+
+/*   SH_MD_DQRP_MMR_XBIST_ERR_L_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQRP_MMR_XBIST_ERR_L_VAL_SHFT      40
+#define SH_MD_DQRP_MMR_XBIST_ERR_L_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQRP_MMR_XBIST_ERR_L_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQRP_MMR_XBIST_ERR_L_MORE_SHFT     41
+#define SH_MD_DQRP_MMR_XBIST_ERR_L_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRP_MMR_YBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YBIST_H                   0x0000000100058800
+#define SH_MD_DQRP_MMR_YBIST_H_MASK              0x00000700ffffffff
+#define SH_MD_DQRP_MMR_YBIST_H_INIT              0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_H_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRP_MMR_YBIST_H_PAT_SHFT          0
+#define SH_MD_DQRP_MMR_YBIST_H_PAT_MASK          0x00000000ffffffff
+
+/*   SH_MD_DQRP_MMR_YBIST_H_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQRP_MMR_YBIST_H_INV_SHFT          40
+#define SH_MD_DQRP_MMR_YBIST_H_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_H_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQRP_MMR_YBIST_H_ROT_SHFT          41
+#define SH_MD_DQRP_MMR_YBIST_H_ROT_MASK          0x0000020000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_H_ARM                                         */
+/*   Description:  writing 1 arms data miscompare capture               */
+#define SH_MD_DQRP_MMR_YBIST_H_ARM_SHFT          42
+#define SH_MD_DQRP_MMR_YBIST_H_ARM_MASK          0x0000040000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRP_MMR_YBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YBIST_L                   0x0000000100058810
+#define SH_MD_DQRP_MMR_YBIST_L_MASK              0x00000300ffffffff
+#define SH_MD_DQRP_MMR_YBIST_L_INIT              0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_L_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRP_MMR_YBIST_L_PAT_SHFT          0
+#define SH_MD_DQRP_MMR_YBIST_L_PAT_MASK          0x00000000ffffffff
+
+/*   SH_MD_DQRP_MMR_YBIST_L_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQRP_MMR_YBIST_L_INV_SHFT          40
+#define SH_MD_DQRP_MMR_YBIST_L_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_L_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQRP_MMR_YBIST_L_ROT_SHFT          41
+#define SH_MD_DQRP_MMR_YBIST_L_ROT_MASK          0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_YBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YBIST_ERR_H               0x0000000100058820
+#define SH_MD_DQRP_MMR_YBIST_ERR_H_MASK          0x00000300ffffffff
+#define SH_MD_DQRP_MMR_YBIST_ERR_H_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_ERR_H_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRP_MMR_YBIST_ERR_H_PAT_SHFT      0
+#define SH_MD_DQRP_MMR_YBIST_ERR_H_PAT_MASK      0x00000000ffffffff
+
+/*   SH_MD_DQRP_MMR_YBIST_ERR_H_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQRP_MMR_YBIST_ERR_H_VAL_SHFT      40
+#define SH_MD_DQRP_MMR_YBIST_ERR_H_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_ERR_H_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQRP_MMR_YBIST_ERR_H_MORE_SHFT     41
+#define SH_MD_DQRP_MMR_YBIST_ERR_H_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_YBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRP_MMR_YBIST_ERR_L               0x0000000100058830
+#define SH_MD_DQRP_MMR_YBIST_ERR_L_MASK          0x00000300ffffffff
+#define SH_MD_DQRP_MMR_YBIST_ERR_L_INIT          0x0000000000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_ERR_L_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRP_MMR_YBIST_ERR_L_PAT_SHFT      0
+#define SH_MD_DQRP_MMR_YBIST_ERR_L_PAT_MASK      0x00000000ffffffff
+
+/*   SH_MD_DQRP_MMR_YBIST_ERR_L_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQRP_MMR_YBIST_ERR_L_VAL_SHFT      40
+#define SH_MD_DQRP_MMR_YBIST_ERR_L_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQRP_MMR_YBIST_ERR_L_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQRP_MMR_YBIST_ERR_L_MORE_SHFT     41
+#define SH_MD_DQRP_MMR_YBIST_ERR_L_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRS_MMR_XBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_XBIST_H                   0x0000000100068000
+#define SH_MD_DQRS_MMR_XBIST_H_MASK              0x000007ffffffffff
+#define SH_MD_DQRS_MMR_XBIST_H_INIT              0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_H_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRS_MMR_XBIST_H_PAT_SHFT          0
+#define SH_MD_DQRS_MMR_XBIST_H_PAT_MASK          0x000000ffffffffff
+
+/*   SH_MD_DQRS_MMR_XBIST_H_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQRS_MMR_XBIST_H_INV_SHFT          40
+#define SH_MD_DQRS_MMR_XBIST_H_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_H_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQRS_MMR_XBIST_H_ROT_SHFT          41
+#define SH_MD_DQRS_MMR_XBIST_H_ROT_MASK          0x0000020000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_H_ARM                                         */
+/*   Description:  writing 1 arms data miscompare capture               */
+#define SH_MD_DQRS_MMR_XBIST_H_ARM_SHFT          42
+#define SH_MD_DQRS_MMR_XBIST_H_ARM_MASK          0x0000040000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRS_MMR_XBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_XBIST_L                   0x0000000100068010
+#define SH_MD_DQRS_MMR_XBIST_L_MASK              0x000003ffffffffff
+#define SH_MD_DQRS_MMR_XBIST_L_INIT              0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_L_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRS_MMR_XBIST_L_PAT_SHFT          0
+#define SH_MD_DQRS_MMR_XBIST_L_PAT_MASK          0x000000ffffffffff
+
+/*   SH_MD_DQRS_MMR_XBIST_L_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQRS_MMR_XBIST_L_INV_SHFT          40
+#define SH_MD_DQRS_MMR_XBIST_L_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_L_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQRS_MMR_XBIST_L_ROT_SHFT          41
+#define SH_MD_DQRS_MMR_XBIST_L_ROT_MASK          0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRS_MMR_XBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_XBIST_ERR_H               0x0000000100068020
+#define SH_MD_DQRS_MMR_XBIST_ERR_H_MASK          0x000003ffffffffff
+#define SH_MD_DQRS_MMR_XBIST_ERR_H_INIT          0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_ERR_H_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRS_MMR_XBIST_ERR_H_PAT_SHFT      0
+#define SH_MD_DQRS_MMR_XBIST_ERR_H_PAT_MASK      0x000000ffffffffff
+
+/*   SH_MD_DQRS_MMR_XBIST_ERR_H_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQRS_MMR_XBIST_ERR_H_VAL_SHFT      40
+#define SH_MD_DQRS_MMR_XBIST_ERR_H_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_ERR_H_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQRS_MMR_XBIST_ERR_H_MORE_SHFT     41
+#define SH_MD_DQRS_MMR_XBIST_ERR_H_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRS_MMR_XBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_XBIST_ERR_L               0x0000000100068030
+#define SH_MD_DQRS_MMR_XBIST_ERR_L_MASK          0x000003ffffffffff
+#define SH_MD_DQRS_MMR_XBIST_ERR_L_INIT          0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_ERR_L_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRS_MMR_XBIST_ERR_L_PAT_SHFT      0
+#define SH_MD_DQRS_MMR_XBIST_ERR_L_PAT_MASK      0x000000ffffffffff
+
+/*   SH_MD_DQRS_MMR_XBIST_ERR_L_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQRS_MMR_XBIST_ERR_L_VAL_SHFT      40
+#define SH_MD_DQRS_MMR_XBIST_ERR_L_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQRS_MMR_XBIST_ERR_L_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQRS_MMR_XBIST_ERR_L_MORE_SHFT     41
+#define SH_MD_DQRS_MMR_XBIST_ERR_L_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRS_MMR_YBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_YBIST_H                   0x0000000100068800
+#define SH_MD_DQRS_MMR_YBIST_H_MASK              0x000007ffffffffff
+#define SH_MD_DQRS_MMR_YBIST_H_INIT              0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_H_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRS_MMR_YBIST_H_PAT_SHFT          0
+#define SH_MD_DQRS_MMR_YBIST_H_PAT_MASK          0x000000ffffffffff
+
+/*   SH_MD_DQRS_MMR_YBIST_H_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQRS_MMR_YBIST_H_INV_SHFT          40
+#define SH_MD_DQRS_MMR_YBIST_H_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_H_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQRS_MMR_YBIST_H_ROT_SHFT          41
+#define SH_MD_DQRS_MMR_YBIST_H_ROT_MASK          0x0000020000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_H_ARM                                         */
+/*   Description:  writing 1 arms data miscompare capture               */
+#define SH_MD_DQRS_MMR_YBIST_H_ARM_SHFT          42
+#define SH_MD_DQRS_MMR_YBIST_H_ARM_MASK          0x0000040000000000
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRS_MMR_YBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_YBIST_L                   0x0000000100068810
+#define SH_MD_DQRS_MMR_YBIST_L_MASK              0x000003ffffffffff
+#define SH_MD_DQRS_MMR_YBIST_L_INIT              0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_L_PAT                                         */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRS_MMR_YBIST_L_PAT_SHFT          0
+#define SH_MD_DQRS_MMR_YBIST_L_PAT_MASK          0x000000ffffffffff
+
+/*   SH_MD_DQRS_MMR_YBIST_L_INV                                         */
+/*   Description:  invert data pattern in next cycle                    */
+#define SH_MD_DQRS_MMR_YBIST_L_INV_SHFT          40
+#define SH_MD_DQRS_MMR_YBIST_L_INV_MASK          0x0000010000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_L_ROT                                         */
+/*   Description:  rotate left data pattern in next cycle               */
+#define SH_MD_DQRS_MMR_YBIST_L_ROT_SHFT          41
+#define SH_MD_DQRS_MMR_YBIST_L_ROT_MASK          0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRS_MMR_YBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_YBIST_ERR_H               0x0000000100068820
+#define SH_MD_DQRS_MMR_YBIST_ERR_H_MASK          0x000003ffffffffff
+#define SH_MD_DQRS_MMR_YBIST_ERR_H_INIT          0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_ERR_H_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRS_MMR_YBIST_ERR_H_PAT_SHFT      0
+#define SH_MD_DQRS_MMR_YBIST_ERR_H_PAT_MASK      0x000000ffffffffff
+
+/*   SH_MD_DQRS_MMR_YBIST_ERR_H_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQRS_MMR_YBIST_ERR_H_VAL_SHFT      40
+#define SH_MD_DQRS_MMR_YBIST_ERR_H_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_ERR_H_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQRS_MMR_YBIST_ERR_H_MORE_SHFT     41
+#define SH_MD_DQRS_MMR_YBIST_ERR_H_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRS_MMR_YBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_YBIST_ERR_L               0x0000000100068830
+#define SH_MD_DQRS_MMR_YBIST_ERR_L_MASK          0x000003ffffffffff
+#define SH_MD_DQRS_MMR_YBIST_ERR_L_INIT          0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_ERR_L_PAT                                     */
+/*   Description:  data pattern                                         */
+#define SH_MD_DQRS_MMR_YBIST_ERR_L_PAT_SHFT      0
+#define SH_MD_DQRS_MMR_YBIST_ERR_L_PAT_MASK      0x000000ffffffffff
+
+/*   SH_MD_DQRS_MMR_YBIST_ERR_L_VAL                                     */
+/*   Description:  bist data miscompare                                 */
+#define SH_MD_DQRS_MMR_YBIST_ERR_L_VAL_SHFT      40
+#define SH_MD_DQRS_MMR_YBIST_ERR_L_VAL_MASK      0x0000010000000000
+
+/*   SH_MD_DQRS_MMR_YBIST_ERR_L_MORE                                    */
+/*   Description:  more than one bist data miscompare                   */
+#define SH_MD_DQRS_MMR_YBIST_ERR_L_MORE_SHFT     41
+#define SH_MD_DQRS_MMR_YBIST_ERR_L_MORE_MASK     0x0000020000000000
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQRS_MMR_JNR_DEBUG"                  */
+/*                    joiner/fct debug configuration                    */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_JNR_DEBUG                 0x0000000100069000
+#define SH_MD_DQRS_MMR_JNR_DEBUG_MASK            0x0000000000000003
+#define SH_MD_DQRS_MMR_JNR_DEBUG_INIT            0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_JNR_DEBUG_PX                                        */
+/*   Description:  select 0=pi 1=xn side                                */
+#define SH_MD_DQRS_MMR_JNR_DEBUG_PX_SHFT         0
+#define SH_MD_DQRS_MMR_JNR_DEBUG_PX_MASK         0x0000000000000001
+
+/*   SH_MD_DQRS_MMR_JNR_DEBUG_RW                                        */
+/*   Description:  select 0=read 1=write side                           */
+#define SH_MD_DQRS_MMR_JNR_DEBUG_RW_SHFT         1
+#define SH_MD_DQRS_MMR_JNR_DEBUG_RW_MASK         0x0000000000000002
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQRS_MMR_YAMOPW_ERR"                 */
+/*                  amo/partial rmw ecc error register                  */
+/* ==================================================================== */
+
+#define SH_MD_DQRS_MMR_YAMOPW_ERR                0x000000010006a000
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_MASK           0x0000000103ff03ff
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_INIT           0x0000000000000000
+
+/*   SH_MD_DQRS_MMR_YAMOPW_ERR_SSYN                                     */
+/*   Description:  store data syndrome                                  */
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_SSYN_SHFT      0
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_SSYN_MASK      0x00000000000000ff
+
+/*   SH_MD_DQRS_MMR_YAMOPW_ERR_SCOR                                     */
+/*   Description:  correctable ecc errror on store data                 */
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_SCOR_SHFT      8
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_SCOR_MASK      0x0000000000000100
+
+/*   SH_MD_DQRS_MMR_YAMOPW_ERR_SUNC                                     */
+/*   Description:  uncorrectable ecc errror on store data               */
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_SUNC_SHFT      9
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_SUNC_MASK      0x0000000000000200
+
+/*   SH_MD_DQRS_MMR_YAMOPW_ERR_RSYN                                     */
+/*   Description:  memory read data syndrome                            */
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_RSYN_SHFT      16
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_RSYN_MASK      0x0000000000ff0000
+
+/*   SH_MD_DQRS_MMR_YAMOPW_ERR_RCOR                                     */
+/*   Description:  correctable ecc errror on read data                  */
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_RCOR_SHFT      24
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_RCOR_MASK      0x0000000001000000
+
+/*   SH_MD_DQRS_MMR_YAMOPW_ERR_RUNC                                     */
+/*   Description:  uncorrectable ecc errror on read data                */
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_RUNC_SHFT      25
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_RUNC_MASK      0x0000000002000000
+
+/*   SH_MD_DQRS_MMR_YAMOPW_ERR_ARM                                      */
+/*   Description:  writing 1 arms ecc error capture                     */
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_ARM_SHFT       32
+#define SH_MD_DQRS_MMR_YAMOPW_ERR_ARM_MASK       0x0000000100000000
+
+
+#endif /* _ASM_IA64_SN_SN2_SHUB_MMR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/shub_mmr_t.h linux/include/asm-ia64/sn/sn2/shub_mmr_t.h
--- linux.orig/include/asm-ia64/sn/sn2/shub_mmr_t.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/shub_mmr_t.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,27385 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+
+
+#ifndef _ASM_IA64_SN_SN2_SHUB_MMR_T_H
+#define _ASM_IA64_SN_SN2_SHUB_MMR_T_H
+
+#include <asm/sn/arch.h>
+
+/* ==================================================================== */
+/*                   Register "SH_FSB_BINIT_CONTROL"                    */
+/*                          FSB BINIT# Control                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_fsb_binit_control_u {
+	mmr_t	sh_fsb_binit_control_regval;
+	struct {
+		mmr_t	binit       : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_fsb_binit_control_s;
+} sh_fsb_binit_control_u_t;
+#else
+typedef union sh_fsb_binit_control_u {
+	mmr_t	sh_fsb_binit_control_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	binit       : 1;
+	} sh_fsb_binit_control_s;
+} sh_fsb_binit_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_FSB_RESET_CONTROL"                    */
+/*                          FSB Reset Control                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_fsb_reset_control_u {
+	mmr_t	sh_fsb_reset_control_regval;
+	struct {
+		mmr_t	reset       : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_fsb_reset_control_s;
+} sh_fsb_reset_control_u_t;
+#else
+typedef union sh_fsb_reset_control_u {
+	mmr_t	sh_fsb_reset_control_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	reset       : 1;
+	} sh_fsb_reset_control_s;
+} sh_fsb_reset_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_FSB_SYSTEM_AGENT_CONFIG"                 */
+/*                    FSB System Agent Configuration                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_fsb_system_agent_config_u {
+	mmr_t	sh_fsb_system_agent_config_regval;
+	struct {
+		mmr_t	rcnt_scnt_en        : 1;
+		mmr_t	reserved_0          : 2;
+		mmr_t	berr_assert_en      : 1;
+		mmr_t	berr_sampling_en    : 1;
+		mmr_t	binit_assert_en     : 1;
+		mmr_t	bnr_throttling_en   : 1;
+		mmr_t	short_hang_en       : 1;
+		mmr_t	inta_rsp_data       : 8;
+		mmr_t	io_trans_rsp        : 1;
+		mmr_t	xtpr_trans_rsp      : 1;
+		mmr_t	inta_trans_rsp      : 1;
+		mmr_t	reserved_1          : 4;
+		mmr_t	tdot                : 1;
+		mmr_t	serialize_fsb_en    : 1;
+		mmr_t	reserved_2          : 7;
+		mmr_t	binit_event_enables : 14;
+		mmr_t	reserved_3          : 18;
+	} sh_fsb_system_agent_config_s;
+} sh_fsb_system_agent_config_u_t;
+#else
+typedef union sh_fsb_system_agent_config_u {
+	mmr_t	sh_fsb_system_agent_config_regval;
+	struct {
+		mmr_t	reserved_3          : 18;
+		mmr_t	binit_event_enables : 14;
+		mmr_t	reserved_2          : 7;
+		mmr_t	serialize_fsb_en    : 1;
+		mmr_t	tdot                : 1;
+		mmr_t	reserved_1          : 4;
+		mmr_t	inta_trans_rsp      : 1;
+		mmr_t	xtpr_trans_rsp      : 1;
+		mmr_t	io_trans_rsp        : 1;
+		mmr_t	inta_rsp_data       : 8;
+		mmr_t	short_hang_en       : 1;
+		mmr_t	bnr_throttling_en   : 1;
+		mmr_t	binit_assert_en     : 1;
+		mmr_t	berr_sampling_en    : 1;
+		mmr_t	berr_assert_en      : 1;
+		mmr_t	reserved_0          : 2;
+		mmr_t	rcnt_scnt_en        : 1;
+	} sh_fsb_system_agent_config_s;
+} sh_fsb_system_agent_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_FSB_VGA_REMAP"                      */
+/*                     FSB VGA Address Space Remap                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_fsb_vga_remap_u {
+	mmr_t	sh_fsb_vga_remap_regval;
+	struct {
+		mmr_t	reserved_0            : 17;
+		mmr_t	offset                : 19;
+		mmr_t	asid                  : 2;
+		mmr_t	nid                   : 11;
+		mmr_t	reserved_1            : 13;
+		mmr_t	vga_remapping_enabled : 1;
+		mmr_t	reserved_2            : 1;
+	} sh_fsb_vga_remap_s;
+} sh_fsb_vga_remap_u_t;
+#else
+typedef union sh_fsb_vga_remap_u {
+	mmr_t	sh_fsb_vga_remap_regval;
+	struct {
+		mmr_t	reserved_2            : 1;
+		mmr_t	vga_remapping_enabled : 1;
+		mmr_t	reserved_1            : 13;
+		mmr_t	nid                   : 11;
+		mmr_t	asid                  : 2;
+		mmr_t	offset                : 19;
+		mmr_t	reserved_0            : 17;
+	} sh_fsb_vga_remap_s;
+} sh_fsb_vga_remap_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_FSB_RESET_STATUS"                    */
+/*                           FSB Reset Status                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_fsb_reset_status_u {
+	mmr_t	sh_fsb_reset_status_regval;
+	struct {
+		mmr_t	reset_in_progress : 1;
+		mmr_t	reserved_0        : 63;
+	} sh_fsb_reset_status_s;
+} sh_fsb_reset_status_u_t;
+#else
+typedef union sh_fsb_reset_status_u {
+	mmr_t	sh_fsb_reset_status_regval;
+	struct {
+		mmr_t	reserved_0        : 63;
+		mmr_t	reset_in_progress : 1;
+	} sh_fsb_reset_status_s;
+} sh_fsb_reset_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_FSB_SYMMETRIC_AGENT_STATUS"               */
+/*                      FSB Symmetric Agent Status                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_fsb_symmetric_agent_status_u {
+	mmr_t	sh_fsb_symmetric_agent_status_regval;
+	struct {
+		mmr_t	cpu_0_active : 1;
+		mmr_t	cpu_1_active : 1;
+		mmr_t	cpus_ready   : 1;
+		mmr_t	reserved_0   : 61;
+	} sh_fsb_symmetric_agent_status_s;
+} sh_fsb_symmetric_agent_status_u_t;
+#else
+typedef union sh_fsb_symmetric_agent_status_u {
+	mmr_t	sh_fsb_symmetric_agent_status_regval;
+	struct {
+		mmr_t	reserved_0   : 61;
+		mmr_t	cpus_ready   : 1;
+		mmr_t	cpu_1_active : 1;
+		mmr_t	cpu_0_active : 1;
+	} sh_fsb_symmetric_agent_status_s;
+} sh_fsb_symmetric_agent_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_CREDIT_COUNT_0"                   */
+/*                Graphics-write Credit Count for CPU 0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_credit_count_0_u {
+	mmr_t	sh_gfx_credit_count_0_regval;
+	struct {
+		mmr_t	count           : 20;
+		mmr_t	reserved_0      : 43;
+		mmr_t	reset_gfx_state : 1;
+	} sh_gfx_credit_count_0_s;
+} sh_gfx_credit_count_0_u_t;
+#else
+typedef union sh_gfx_credit_count_0_u {
+	mmr_t	sh_gfx_credit_count_0_regval;
+	struct {
+		mmr_t	reset_gfx_state : 1;
+		mmr_t	reserved_0      : 43;
+		mmr_t	count           : 20;
+	} sh_gfx_credit_count_0_s;
+} sh_gfx_credit_count_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_CREDIT_COUNT_1"                   */
+/*                Graphics-write Credit Count for CPU 1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_credit_count_1_u {
+	mmr_t	sh_gfx_credit_count_1_regval;
+	struct {
+		mmr_t	count           : 20;
+		mmr_t	reserved_0      : 43;
+		mmr_t	reset_gfx_state : 1;
+	} sh_gfx_credit_count_1_s;
+} sh_gfx_credit_count_1_u_t;
+#else
+typedef union sh_gfx_credit_count_1_u {
+	mmr_t	sh_gfx_credit_count_1_regval;
+	struct {
+		mmr_t	reset_gfx_state : 1;
+		mmr_t	reserved_0      : 43;
+		mmr_t	count           : 20;
+	} sh_gfx_credit_count_1_s;
+} sh_gfx_credit_count_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_GFX_MODE_CNTRL_0"                    */
+/*         Graphics credit mode amd message ordering for CPU 0          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_mode_cntrl_0_u {
+	mmr_t	sh_gfx_mode_cntrl_0_regval;
+	struct {
+		mmr_t	dword_credits      : 1;
+		mmr_t	mixed_mode_credits : 1;
+		mmr_t	relaxed_ordering   : 1;
+		mmr_t	reserved_0         : 61;
+	} sh_gfx_mode_cntrl_0_s;
+} sh_gfx_mode_cntrl_0_u_t;
+#else
+typedef union sh_gfx_mode_cntrl_0_u {
+	mmr_t	sh_gfx_mode_cntrl_0_regval;
+	struct {
+		mmr_t	reserved_0         : 61;
+		mmr_t	relaxed_ordering   : 1;
+		mmr_t	mixed_mode_credits : 1;
+		mmr_t	dword_credits      : 1;
+	} sh_gfx_mode_cntrl_0_s;
+} sh_gfx_mode_cntrl_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_GFX_MODE_CNTRL_1"                    */
+/*         Graphics credit mode amd message ordering for CPU 1          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_mode_cntrl_1_u {
+	mmr_t	sh_gfx_mode_cntrl_1_regval;
+	struct {
+		mmr_t	dword_credits      : 1;
+		mmr_t	mixed_mode_credits : 1;
+		mmr_t	relaxed_ordering   : 1;
+		mmr_t	reserved_0         : 61;
+	} sh_gfx_mode_cntrl_1_s;
+} sh_gfx_mode_cntrl_1_u_t;
+#else
+typedef union sh_gfx_mode_cntrl_1_u {
+	mmr_t	sh_gfx_mode_cntrl_1_regval;
+	struct {
+		mmr_t	reserved_0         : 61;
+		mmr_t	relaxed_ordering   : 1;
+		mmr_t	mixed_mode_credits : 1;
+		mmr_t	dword_credits      : 1;
+	} sh_gfx_mode_cntrl_1_s;
+} sh_gfx_mode_cntrl_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_GFX_SKID_CREDIT_COUNT_0"                 */
+/*              Graphics-write Skid Credit Count for CPU 0              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_skid_credit_count_0_u {
+	mmr_t	sh_gfx_skid_credit_count_0_regval;
+	struct {
+		mmr_t	skid        : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_gfx_skid_credit_count_0_s;
+} sh_gfx_skid_credit_count_0_u_t;
+#else
+typedef union sh_gfx_skid_credit_count_0_u {
+	mmr_t	sh_gfx_skid_credit_count_0_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	skid        : 20;
+	} sh_gfx_skid_credit_count_0_s;
+} sh_gfx_skid_credit_count_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_GFX_SKID_CREDIT_COUNT_1"                 */
+/*              Graphics-write Skid Credit Count for CPU 1              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_skid_credit_count_1_u {
+	mmr_t	sh_gfx_skid_credit_count_1_regval;
+	struct {
+		mmr_t	skid        : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_gfx_skid_credit_count_1_s;
+} sh_gfx_skid_credit_count_1_u_t;
+#else
+typedef union sh_gfx_skid_credit_count_1_u {
+	mmr_t	sh_gfx_skid_credit_count_1_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	skid        : 20;
+	} sh_gfx_skid_credit_count_1_s;
+} sh_gfx_skid_credit_count_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_STALL_LIMIT_0"                    */
+/*                 Graphics-write Stall Limit for CPU 0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_stall_limit_0_u {
+	mmr_t	sh_gfx_stall_limit_0_regval;
+	struct {
+		mmr_t	limit       : 26;
+		mmr_t	reserved_0  : 38;
+	} sh_gfx_stall_limit_0_s;
+} sh_gfx_stall_limit_0_u_t;
+#else
+typedef union sh_gfx_stall_limit_0_u {
+	mmr_t	sh_gfx_stall_limit_0_regval;
+	struct {
+		mmr_t	reserved_0  : 38;
+		mmr_t	limit       : 26;
+	} sh_gfx_stall_limit_0_s;
+} sh_gfx_stall_limit_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_STALL_LIMIT_1"                    */
+/*                 Graphics-write Stall Limit for CPU 1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_stall_limit_1_u {
+	mmr_t	sh_gfx_stall_limit_1_regval;
+	struct {
+		mmr_t	limit       : 26;
+		mmr_t	reserved_0  : 38;
+	} sh_gfx_stall_limit_1_s;
+} sh_gfx_stall_limit_1_u_t;
+#else
+typedef union sh_gfx_stall_limit_1_u {
+	mmr_t	sh_gfx_stall_limit_1_regval;
+	struct {
+		mmr_t	reserved_0  : 38;
+		mmr_t	limit       : 26;
+	} sh_gfx_stall_limit_1_s;
+} sh_gfx_stall_limit_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_STALL_TIMER_0"                    */
+/*                 Graphics-write Stall Timer for CPU 0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_stall_timer_0_u {
+	mmr_t	sh_gfx_stall_timer_0_regval;
+	struct {
+		mmr_t	timer_value : 26;
+		mmr_t	reserved_0  : 38;
+	} sh_gfx_stall_timer_0_s;
+} sh_gfx_stall_timer_0_u_t;
+#else
+typedef union sh_gfx_stall_timer_0_u {
+	mmr_t	sh_gfx_stall_timer_0_regval;
+	struct {
+		mmr_t	reserved_0  : 38;
+		mmr_t	timer_value : 26;
+	} sh_gfx_stall_timer_0_s;
+} sh_gfx_stall_timer_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_STALL_TIMER_1"                    */
+/*                 Graphics-write Stall Timer for CPU 1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_stall_timer_1_u {
+	mmr_t	sh_gfx_stall_timer_1_regval;
+	struct {
+		mmr_t	timer_value : 26;
+		mmr_t	reserved_0  : 38;
+	} sh_gfx_stall_timer_1_s;
+} sh_gfx_stall_timer_1_u_t;
+#else
+typedef union sh_gfx_stall_timer_1_u {
+	mmr_t	sh_gfx_stall_timer_1_regval;
+	struct {
+		mmr_t	reserved_0  : 38;
+		mmr_t	timer_value : 26;
+	} sh_gfx_stall_timer_1_s;
+} sh_gfx_stall_timer_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_GFX_WINDOW_0"                      */
+/*                   Graphics-write Window for CPU 0                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_window_0_u {
+	mmr_t	sh_gfx_window_0_regval;
+	struct {
+		mmr_t	reserved_0    : 24;
+		mmr_t	base_addr     : 12;
+		mmr_t	reserved_1    : 27;
+		mmr_t	gfx_window_en : 1;
+	} sh_gfx_window_0_s;
+} sh_gfx_window_0_u_t;
+#else
+typedef union sh_gfx_window_0_u {
+	mmr_t	sh_gfx_window_0_regval;
+	struct {
+		mmr_t	gfx_window_en : 1;
+		mmr_t	reserved_1    : 27;
+		mmr_t	base_addr     : 12;
+		mmr_t	reserved_0    : 24;
+	} sh_gfx_window_0_s;
+} sh_gfx_window_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_GFX_WINDOW_1"                      */
+/*                   Graphics-write Window for CPU 1                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_window_1_u {
+	mmr_t	sh_gfx_window_1_regval;
+	struct {
+		mmr_t	reserved_0    : 24;
+		mmr_t	base_addr     : 12;
+		mmr_t	reserved_1    : 27;
+		mmr_t	gfx_window_en : 1;
+	} sh_gfx_window_1_s;
+} sh_gfx_window_1_u_t;
+#else
+typedef union sh_gfx_window_1_u {
+	mmr_t	sh_gfx_window_1_regval;
+	struct {
+		mmr_t	gfx_window_en : 1;
+		mmr_t	reserved_1    : 27;
+		mmr_t	base_addr     : 12;
+		mmr_t	reserved_0    : 24;
+	} sh_gfx_window_1_s;
+} sh_gfx_window_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_GFX_INTERRUPT_TIMER_LIMIT_0"               */
+/*               Graphics-write Interrupt Limit for CPU 0               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_interrupt_timer_limit_0_u {
+	mmr_t	sh_gfx_interrupt_timer_limit_0_regval;
+	struct {
+		mmr_t	interrupt_timer_limit : 8;
+		mmr_t	reserved_0            : 56;
+	} sh_gfx_interrupt_timer_limit_0_s;
+} sh_gfx_interrupt_timer_limit_0_u_t;
+#else
+typedef union sh_gfx_interrupt_timer_limit_0_u {
+	mmr_t	sh_gfx_interrupt_timer_limit_0_regval;
+	struct {
+		mmr_t	reserved_0            : 56;
+		mmr_t	interrupt_timer_limit : 8;
+	} sh_gfx_interrupt_timer_limit_0_s;
+} sh_gfx_interrupt_timer_limit_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_GFX_INTERRUPT_TIMER_LIMIT_1"               */
+/*               Graphics-write Interrupt Limit for CPU 1               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_interrupt_timer_limit_1_u {
+	mmr_t	sh_gfx_interrupt_timer_limit_1_regval;
+	struct {
+		mmr_t	interrupt_timer_limit : 8;
+		mmr_t	reserved_0            : 56;
+	} sh_gfx_interrupt_timer_limit_1_s;
+} sh_gfx_interrupt_timer_limit_1_u_t;
+#else
+typedef union sh_gfx_interrupt_timer_limit_1_u {
+	mmr_t	sh_gfx_interrupt_timer_limit_1_regval;
+	struct {
+		mmr_t	reserved_0            : 56;
+		mmr_t	interrupt_timer_limit : 8;
+	} sh_gfx_interrupt_timer_limit_1_s;
+} sh_gfx_interrupt_timer_limit_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_WRITE_STATUS_0"                   */
+/*                   Graphics Write Status for CPU 0                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_write_status_0_u {
+	mmr_t	sh_gfx_write_status_0_regval;
+	struct {
+		mmr_t	busy                : 1;
+		mmr_t	reserved_0          : 62;
+		mmr_t	re_enable_gfx_stall : 1;
+	} sh_gfx_write_status_0_s;
+} sh_gfx_write_status_0_u_t;
+#else
+typedef union sh_gfx_write_status_0_u {
+	mmr_t	sh_gfx_write_status_0_regval;
+	struct {
+		mmr_t	re_enable_gfx_stall : 1;
+		mmr_t	reserved_0          : 62;
+		mmr_t	busy                : 1;
+	} sh_gfx_write_status_0_s;
+} sh_gfx_write_status_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_GFX_WRITE_STATUS_1"                   */
+/*                   Graphics Write Status for CPU 1                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gfx_write_status_1_u {
+	mmr_t	sh_gfx_write_status_1_regval;
+	struct {
+		mmr_t	busy                : 1;
+		mmr_t	reserved_0          : 62;
+		mmr_t	re_enable_gfx_stall : 1;
+	} sh_gfx_write_status_1_s;
+} sh_gfx_write_status_1_u_t;
+#else
+typedef union sh_gfx_write_status_1_u {
+	mmr_t	sh_gfx_write_status_1_regval;
+	struct {
+		mmr_t	re_enable_gfx_stall : 1;
+		mmr_t	reserved_0          : 62;
+		mmr_t	busy                : 1;
+	} sh_gfx_write_status_1_s;
+} sh_gfx_write_status_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_II_INT0"                         */
+/*                    SHub II Interrupt 0 Registers                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_int0_u {
+	mmr_t	sh_ii_int0_regval;
+	struct {
+		mmr_t	idx         : 8;
+		mmr_t	send        : 1;
+		mmr_t	reserved_0  : 55;
+	} sh_ii_int0_s;
+} sh_ii_int0_u_t;
+#else
+typedef union sh_ii_int0_u {
+	mmr_t	sh_ii_int0_regval;
+	struct {
+		mmr_t	reserved_0  : 55;
+		mmr_t	send        : 1;
+		mmr_t	idx         : 8;
+	} sh_ii_int0_s;
+} sh_ii_int0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_II_INT0_CONFIG"                     */
+/*                 SHub II Interrupt 0 Config Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_int0_config_u {
+	mmr_t	sh_ii_int0_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 14;
+	} sh_ii_int0_config_s;
+} sh_ii_int0_config_u_t;
+#else
+typedef union sh_ii_int0_config_u {
+	mmr_t	sh_ii_int0_config_regval;
+	struct {
+		mmr_t	reserved_1  : 14;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_ii_int0_config_s;
+} sh_ii_int0_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_II_INT0_ENABLE"                     */
+/*                 SHub II Interrupt 0 Enable Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_int0_enable_u {
+	mmr_t	sh_ii_int0_enable_regval;
+	struct {
+		mmr_t	ii_enable   : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_ii_int0_enable_s;
+} sh_ii_int0_enable_u_t;
+#else
+typedef union sh_ii_int0_enable_u {
+	mmr_t	sh_ii_int0_enable_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	ii_enable   : 1;
+	} sh_ii_int0_enable_s;
+} sh_ii_int0_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_II_INT1"                         */
+/*                    SHub II Interrupt 1 Registers                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_int1_u {
+	mmr_t	sh_ii_int1_regval;
+	struct {
+		mmr_t	idx         : 8;
+		mmr_t	send        : 1;
+		mmr_t	reserved_0  : 55;
+	} sh_ii_int1_s;
+} sh_ii_int1_u_t;
+#else
+typedef union sh_ii_int1_u {
+	mmr_t	sh_ii_int1_regval;
+	struct {
+		mmr_t	reserved_0  : 55;
+		mmr_t	send        : 1;
+		mmr_t	idx         : 8;
+	} sh_ii_int1_s;
+} sh_ii_int1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_II_INT1_CONFIG"                     */
+/*                 SHub II Interrupt 1 Config Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_int1_config_u {
+	mmr_t	sh_ii_int1_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 14;
+	} sh_ii_int1_config_s;
+} sh_ii_int1_config_u_t;
+#else
+typedef union sh_ii_int1_config_u {
+	mmr_t	sh_ii_int1_config_regval;
+	struct {
+		mmr_t	reserved_1  : 14;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_ii_int1_config_s;
+} sh_ii_int1_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_II_INT1_ENABLE"                     */
+/*                 SHub II Interrupt 1 Enable Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_int1_enable_u {
+	mmr_t	sh_ii_int1_enable_regval;
+	struct {
+		mmr_t	ii_enable   : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_ii_int1_enable_s;
+} sh_ii_int1_enable_u_t;
+#else
+typedef union sh_ii_int1_enable_u {
+	mmr_t	sh_ii_int1_enable_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	ii_enable   : 1;
+	} sh_ii_int1_enable_s;
+} sh_ii_int1_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_INT_NODE_ID_CONFIG"                   */
+/*                 SHub Interrupt Node ID Configuration                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_int_node_id_config_u {
+	mmr_t	sh_int_node_id_config_regval;
+	struct {
+		mmr_t	node_id     : 11;
+		mmr_t	id_sel      : 1;
+		mmr_t	reserved_0  : 52;
+	} sh_int_node_id_config_s;
+} sh_int_node_id_config_u_t;
+#else
+typedef union sh_int_node_id_config_u {
+	mmr_t	sh_int_node_id_config_regval;
+	struct {
+		mmr_t	reserved_0  : 52;
+		mmr_t	id_sel      : 1;
+		mmr_t	node_id     : 11;
+	} sh_int_node_id_config_s;
+} sh_int_node_id_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_IPI_INT"                         */
+/*               SHub Inter-Processor Interrupt Registers               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ipi_int_u {
+	mmr_t	sh_ipi_int_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 3;
+		mmr_t	send        : 1;
+	} sh_ipi_int_s;
+} sh_ipi_int_u_t;
+#else
+typedef union sh_ipi_int_u {
+	mmr_t	sh_ipi_int_regval;
+	struct {
+		mmr_t	send        : 1;
+		mmr_t	reserved_2  : 3;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_ipi_int_s;
+} sh_ipi_int_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_IPI_INT_ENABLE"                     */
+/*           SHub Inter-Processor Interrupt Enable Registers            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ipi_int_enable_u {
+	mmr_t	sh_ipi_int_enable_regval;
+	struct {
+		mmr_t	pio_enable  : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_ipi_int_enable_s;
+} sh_ipi_int_enable_u_t;
+#else
+typedef union sh_ipi_int_enable_u {
+	mmr_t	sh_ipi_int_enable_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	pio_enable  : 1;
+	} sh_ipi_int_enable_s;
+} sh_ipi_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT0_CONFIG"                    */
+/*                   SHub Local Interrupt 0 Registers                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int0_config_u {
+	mmr_t	sh_local_int0_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_local_int0_config_s;
+} sh_local_int0_config_u_t;
+#else
+typedef union sh_local_int0_config_u {
+	mmr_t	sh_local_int0_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_local_int0_config_s;
+} sh_local_int0_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT0_ENABLE"                    */
+/*                    SHub Local Interrupt 0 Enable                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int0_enable_u {
+	mmr_t	sh_local_int0_enable_regval;
+	struct {
+		mmr_t	pi_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	reserved_1          : 48;
+	} sh_local_int0_enable_s;
+} sh_local_int0_enable_u_t;
+#else
+typedef union sh_local_int0_enable_u {
+	mmr_t	sh_local_int0_enable_regval;
+	struct {
+		mmr_t	reserved_1          : 48;
+		mmr_t	stop_clock          : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	pi_hw_int           : 1;
+	} sh_local_int0_enable_s;
+} sh_local_int0_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT1_CONFIG"                    */
+/*                   SHub Local Interrupt 1 Registers                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int1_config_u {
+	mmr_t	sh_local_int1_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_local_int1_config_s;
+} sh_local_int1_config_u_t;
+#else
+typedef union sh_local_int1_config_u {
+	mmr_t	sh_local_int1_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_local_int1_config_s;
+} sh_local_int1_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT1_ENABLE"                    */
+/*                    SHub Local Interrupt 1 Enable                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int1_enable_u {
+	mmr_t	sh_local_int1_enable_regval;
+	struct {
+		mmr_t	pi_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	reserved_1          : 48;
+	} sh_local_int1_enable_s;
+} sh_local_int1_enable_u_t;
+#else
+typedef union sh_local_int1_enable_u {
+	mmr_t	sh_local_int1_enable_regval;
+	struct {
+		mmr_t	reserved_1          : 48;
+		mmr_t	stop_clock          : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	pi_hw_int           : 1;
+	} sh_local_int1_enable_s;
+} sh_local_int1_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT2_CONFIG"                    */
+/*                   SHub Local Interrupt 2 Registers                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int2_config_u {
+	mmr_t	sh_local_int2_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_local_int2_config_s;
+} sh_local_int2_config_u_t;
+#else
+typedef union sh_local_int2_config_u {
+	mmr_t	sh_local_int2_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_local_int2_config_s;
+} sh_local_int2_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT2_ENABLE"                    */
+/*                    SHub Local Interrupt 2 Enable                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int2_enable_u {
+	mmr_t	sh_local_int2_enable_regval;
+	struct {
+		mmr_t	pi_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	reserved_1          : 48;
+	} sh_local_int2_enable_s;
+} sh_local_int2_enable_u_t;
+#else
+typedef union sh_local_int2_enable_u {
+	mmr_t	sh_local_int2_enable_regval;
+	struct {
+		mmr_t	reserved_1          : 48;
+		mmr_t	stop_clock          : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	pi_hw_int           : 1;
+	} sh_local_int2_enable_s;
+} sh_local_int2_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT3_CONFIG"                    */
+/*                   SHub Local Interrupt 3 Registers                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int3_config_u {
+	mmr_t	sh_local_int3_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_local_int3_config_s;
+} sh_local_int3_config_u_t;
+#else
+typedef union sh_local_int3_config_u {
+	mmr_t	sh_local_int3_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_local_int3_config_s;
+} sh_local_int3_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT3_ENABLE"                    */
+/*                    SHub Local Interrupt 3 Enable                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int3_enable_u {
+	mmr_t	sh_local_int3_enable_regval;
+	struct {
+		mmr_t	pi_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	reserved_1          : 48;
+	} sh_local_int3_enable_s;
+} sh_local_int3_enable_u_t;
+#else
+typedef union sh_local_int3_enable_u {
+	mmr_t	sh_local_int3_enable_regval;
+	struct {
+		mmr_t	reserved_1          : 48;
+		mmr_t	stop_clock          : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	pi_hw_int           : 1;
+	} sh_local_int3_enable_s;
+} sh_local_int3_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT4_CONFIG"                    */
+/*                   SHub Local Interrupt 4 Registers                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int4_config_u {
+	mmr_t	sh_local_int4_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_local_int4_config_s;
+} sh_local_int4_config_u_t;
+#else
+typedef union sh_local_int4_config_u {
+	mmr_t	sh_local_int4_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_local_int4_config_s;
+} sh_local_int4_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT4_ENABLE"                    */
+/*                    SHub Local Interrupt 4 Enable                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int4_enable_u {
+	mmr_t	sh_local_int4_enable_regval;
+	struct {
+		mmr_t	pi_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	reserved_1          : 48;
+	} sh_local_int4_enable_s;
+} sh_local_int4_enable_u_t;
+#else
+typedef union sh_local_int4_enable_u {
+	mmr_t	sh_local_int4_enable_regval;
+	struct {
+		mmr_t	reserved_1          : 48;
+		mmr_t	stop_clock          : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	pi_hw_int           : 1;
+	} sh_local_int4_enable_s;
+} sh_local_int4_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT5_CONFIG"                    */
+/*                   SHub Local Interrupt 5 Registers                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int5_config_u {
+	mmr_t	sh_local_int5_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_local_int5_config_s;
+} sh_local_int5_config_u_t;
+#else
+typedef union sh_local_int5_config_u {
+	mmr_t	sh_local_int5_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_local_int5_config_s;
+} sh_local_int5_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LOCAL_INT5_ENABLE"                    */
+/*                    SHub Local Interrupt 5 Enable                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_local_int5_enable_u {
+	mmr_t	sh_local_int5_enable_regval;
+	struct {
+		mmr_t	pi_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	reserved_1          : 48;
+	} sh_local_int5_enable_s;
+} sh_local_int5_enable_u_t;
+#else
+typedef union sh_local_int5_enable_u {
+	mmr_t	sh_local_int5_enable_regval;
+	struct {
+		mmr_t	reserved_1          : 48;
+		mmr_t	stop_clock          : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	reserved_0          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	pi_hw_int           : 1;
+	} sh_local_int5_enable_s;
+} sh_local_int5_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ERR_INT_CONFIG"                  */
+/*              SHub Processor 0 Error Interrupt Registers              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc0_err_int_config_u {
+	mmr_t	sh_proc0_err_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_proc0_err_int_config_s;
+} sh_proc0_err_int_config_u_t;
+#else
+typedef union sh_proc0_err_int_config_u {
+	mmr_t	sh_proc0_err_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_proc0_err_int_config_s;
+} sh_proc0_err_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ERR_INT_CONFIG"                  */
+/*              SHub Processor 1 Error Interrupt Registers              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc1_err_int_config_u {
+	mmr_t	sh_proc1_err_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_proc1_err_int_config_s;
+} sh_proc1_err_int_config_u_t;
+#else
+typedef union sh_proc1_err_int_config_u {
+	mmr_t	sh_proc1_err_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_proc1_err_int_config_s;
+} sh_proc1_err_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ERR_INT_CONFIG"                  */
+/*              SHub Processor 2 Error Interrupt Registers              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc2_err_int_config_u {
+	mmr_t	sh_proc2_err_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_proc2_err_int_config_s;
+} sh_proc2_err_int_config_u_t;
+#else
+typedef union sh_proc2_err_int_config_u {
+	mmr_t	sh_proc2_err_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_proc2_err_int_config_s;
+} sh_proc2_err_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ERR_INT_CONFIG"                  */
+/*              SHub Processor 3 Error Interrupt Registers              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc3_err_int_config_u {
+	mmr_t	sh_proc3_err_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_proc3_err_int_config_s;
+} sh_proc3_err_int_config_u_t;
+#else
+typedef union sh_proc3_err_int_config_u {
+	mmr_t	sh_proc3_err_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_proc3_err_int_config_s;
+} sh_proc3_err_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ADV_INT_CONFIG"                  */
+/*            SHub Processor 0 Advisory Interrupt Registers             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc0_adv_int_config_u {
+	mmr_t	sh_proc0_adv_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_proc0_adv_int_config_s;
+} sh_proc0_adv_int_config_u_t;
+#else
+typedef union sh_proc0_adv_int_config_u {
+	mmr_t	sh_proc0_adv_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_proc0_adv_int_config_s;
+} sh_proc0_adv_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ADV_INT_CONFIG"                  */
+/*            SHub Processor 1 Advisory Interrupt Registers             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc1_adv_int_config_u {
+	mmr_t	sh_proc1_adv_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_proc1_adv_int_config_s;
+} sh_proc1_adv_int_config_u_t;
+#else
+typedef union sh_proc1_adv_int_config_u {
+	mmr_t	sh_proc1_adv_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_proc1_adv_int_config_s;
+} sh_proc1_adv_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ADV_INT_CONFIG"                  */
+/*            SHub Processor 2 Advisory Interrupt Registers             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc2_adv_int_config_u {
+	mmr_t	sh_proc2_adv_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_proc2_adv_int_config_s;
+} sh_proc2_adv_int_config_u_t;
+#else
+typedef union sh_proc2_adv_int_config_u {
+	mmr_t	sh_proc2_adv_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_proc2_adv_int_config_s;
+} sh_proc2_adv_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ADV_INT_CONFIG"                  */
+/*            SHub Processor 3 Advisory Interrupt Registers             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc3_adv_int_config_u {
+	mmr_t	sh_proc3_adv_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_proc3_adv_int_config_s;
+} sh_proc3_adv_int_config_u_t;
+#else
+typedef union sh_proc3_adv_int_config_u {
+	mmr_t	sh_proc3_adv_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_proc3_adv_int_config_s;
+} sh_proc3_adv_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ERR_INT_ENABLE"                  */
+/*          SHub Processor 0 Error Interrupt Enable Registers           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc0_err_int_enable_u {
+	mmr_t	sh_proc0_err_int_enable_regval;
+	struct {
+		mmr_t	proc0_err_enable : 1;
+		mmr_t	reserved_0       : 63;
+	} sh_proc0_err_int_enable_s;
+} sh_proc0_err_int_enable_u_t;
+#else
+typedef union sh_proc0_err_int_enable_u {
+	mmr_t	sh_proc0_err_int_enable_regval;
+	struct {
+		mmr_t	reserved_0       : 63;
+		mmr_t	proc0_err_enable : 1;
+	} sh_proc0_err_int_enable_s;
+} sh_proc0_err_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ERR_INT_ENABLE"                  */
+/*          SHub Processor 1 Error Interrupt Enable Registers           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc1_err_int_enable_u {
+	mmr_t	sh_proc1_err_int_enable_regval;
+	struct {
+		mmr_t	proc1_err_enable : 1;
+		mmr_t	reserved_0       : 63;
+	} sh_proc1_err_int_enable_s;
+} sh_proc1_err_int_enable_u_t;
+#else
+typedef union sh_proc1_err_int_enable_u {
+	mmr_t	sh_proc1_err_int_enable_regval;
+	struct {
+		mmr_t	reserved_0       : 63;
+		mmr_t	proc1_err_enable : 1;
+	} sh_proc1_err_int_enable_s;
+} sh_proc1_err_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ERR_INT_ENABLE"                  */
+/*          SHub Processor 2 Error Interrupt Enable Registers           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc2_err_int_enable_u {
+	mmr_t	sh_proc2_err_int_enable_regval;
+	struct {
+		mmr_t	proc2_err_enable : 1;
+		mmr_t	reserved_0       : 63;
+	} sh_proc2_err_int_enable_s;
+} sh_proc2_err_int_enable_u_t;
+#else
+typedef union sh_proc2_err_int_enable_u {
+	mmr_t	sh_proc2_err_int_enable_regval;
+	struct {
+		mmr_t	reserved_0       : 63;
+		mmr_t	proc2_err_enable : 1;
+	} sh_proc2_err_int_enable_s;
+} sh_proc2_err_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ERR_INT_ENABLE"                  */
+/*          SHub Processor 3 Error Interrupt Enable Registers           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc3_err_int_enable_u {
+	mmr_t	sh_proc3_err_int_enable_regval;
+	struct {
+		mmr_t	proc3_err_enable : 1;
+		mmr_t	reserved_0       : 63;
+	} sh_proc3_err_int_enable_s;
+} sh_proc3_err_int_enable_u_t;
+#else
+typedef union sh_proc3_err_int_enable_u {
+	mmr_t	sh_proc3_err_int_enable_regval;
+	struct {
+		mmr_t	reserved_0       : 63;
+		mmr_t	proc3_err_enable : 1;
+	} sh_proc3_err_int_enable_s;
+} sh_proc3_err_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ADV_INT_ENABLE"                  */
+/*         SHub Processor 0 Advisory Interrupt Enable Registers         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc0_adv_int_enable_u {
+	mmr_t	sh_proc0_adv_int_enable_regval;
+	struct {
+		mmr_t	proc0_adv_enable : 1;
+		mmr_t	reserved_0       : 63;
+	} sh_proc0_adv_int_enable_s;
+} sh_proc0_adv_int_enable_u_t;
+#else
+typedef union sh_proc0_adv_int_enable_u {
+	mmr_t	sh_proc0_adv_int_enable_regval;
+	struct {
+		mmr_t	reserved_0       : 63;
+		mmr_t	proc0_adv_enable : 1;
+	} sh_proc0_adv_int_enable_s;
+} sh_proc0_adv_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ADV_INT_ENABLE"                  */
+/*         SHub Processor 1 Advisory Interrupt Enable Registers         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc1_adv_int_enable_u {
+	mmr_t	sh_proc1_adv_int_enable_regval;
+	struct {
+		mmr_t	proc1_adv_enable : 1;
+		mmr_t	reserved_0       : 63;
+	} sh_proc1_adv_int_enable_s;
+} sh_proc1_adv_int_enable_u_t;
+#else
+typedef union sh_proc1_adv_int_enable_u {
+	mmr_t	sh_proc1_adv_int_enable_regval;
+	struct {
+		mmr_t	reserved_0       : 63;
+		mmr_t	proc1_adv_enable : 1;
+	} sh_proc1_adv_int_enable_s;
+} sh_proc1_adv_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ADV_INT_ENABLE"                  */
+/*         SHub Processor 2 Advisory Interrupt Enable Registers         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc2_adv_int_enable_u {
+	mmr_t	sh_proc2_adv_int_enable_regval;
+	struct {
+		mmr_t	proc2_adv_enable : 1;
+		mmr_t	reserved_0       : 63;
+	} sh_proc2_adv_int_enable_s;
+} sh_proc2_adv_int_enable_u_t;
+#else
+typedef union sh_proc2_adv_int_enable_u {
+	mmr_t	sh_proc2_adv_int_enable_regval;
+	struct {
+		mmr_t	reserved_0       : 63;
+		mmr_t	proc2_adv_enable : 1;
+	} sh_proc2_adv_int_enable_s;
+} sh_proc2_adv_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ADV_INT_ENABLE"                  */
+/*         SHub Processor 3 Advisory Interrupt Enable Registers         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc3_adv_int_enable_u {
+	mmr_t	sh_proc3_adv_int_enable_regval;
+	struct {
+		mmr_t	proc3_adv_enable : 1;
+		mmr_t	reserved_0       : 63;
+	} sh_proc3_adv_int_enable_s;
+} sh_proc3_adv_int_enable_u_t;
+#else
+typedef union sh_proc3_adv_int_enable_u {
+	mmr_t	sh_proc3_adv_int_enable_regval;
+	struct {
+		mmr_t	reserved_0       : 63;
+		mmr_t	proc3_adv_enable : 1;
+	} sh_proc3_adv_int_enable_s;
+} sh_proc3_adv_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PROFILE_INT_CONFIG"                   */
+/*            SHub Profile Interrupt Configuration Registers            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_profile_int_config_u {
+	mmr_t	sh_profile_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_profile_int_config_s;
+} sh_profile_int_config_u_t;
+#else
+typedef union sh_profile_int_config_u {
+	mmr_t	sh_profile_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_profile_int_config_s;
+} sh_profile_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PROFILE_INT_ENABLE"                   */
+/*               SHub Profile Interrupt Enable Registers                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_profile_int_enable_u {
+	mmr_t	sh_profile_int_enable_regval;
+	struct {
+		mmr_t	profile_enable : 1;
+		mmr_t	reserved_0     : 63;
+	} sh_profile_int_enable_s;
+} sh_profile_int_enable_u_t;
+#else
+typedef union sh_profile_int_enable_u {
+	mmr_t	sh_profile_int_enable_regval;
+	struct {
+		mmr_t	reserved_0     : 63;
+		mmr_t	profile_enable : 1;
+	} sh_profile_int_enable_s;
+} sh_profile_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_RTC0_INT_CONFIG"                     */
+/*                SHub RTC 0 Interrupt Config Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc0_int_config_u {
+	mmr_t	sh_rtc0_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_rtc0_int_config_s;
+} sh_rtc0_int_config_u_t;
+#else
+typedef union sh_rtc0_int_config_u {
+	mmr_t	sh_rtc0_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_rtc0_int_config_s;
+} sh_rtc0_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_RTC0_INT_ENABLE"                     */
+/*                SHub RTC 0 Interrupt Enable Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc0_int_enable_u {
+	mmr_t	sh_rtc0_int_enable_regval;
+	struct {
+		mmr_t	rtc0_enable : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_rtc0_int_enable_s;
+} sh_rtc0_int_enable_u_t;
+#else
+typedef union sh_rtc0_int_enable_u {
+	mmr_t	sh_rtc0_int_enable_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	rtc0_enable : 1;
+	} sh_rtc0_int_enable_s;
+} sh_rtc0_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_RTC1_INT_CONFIG"                     */
+/*                SHub RTC 1 Interrupt Config Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc1_int_config_u {
+	mmr_t	sh_rtc1_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_rtc1_int_config_s;
+} sh_rtc1_int_config_u_t;
+#else
+typedef union sh_rtc1_int_config_u {
+	mmr_t	sh_rtc1_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_rtc1_int_config_s;
+} sh_rtc1_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_RTC1_INT_ENABLE"                     */
+/*                SHub RTC 1 Interrupt Enable Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc1_int_enable_u {
+	mmr_t	sh_rtc1_int_enable_regval;
+	struct {
+		mmr_t	rtc1_enable : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_rtc1_int_enable_s;
+} sh_rtc1_int_enable_u_t;
+#else
+typedef union sh_rtc1_int_enable_u {
+	mmr_t	sh_rtc1_int_enable_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	rtc1_enable : 1;
+	} sh_rtc1_int_enable_s;
+} sh_rtc1_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_RTC2_INT_CONFIG"                     */
+/*                SHub RTC 2 Interrupt Config Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc2_int_config_u {
+	mmr_t	sh_rtc2_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_rtc2_int_config_s;
+} sh_rtc2_int_config_u_t;
+#else
+typedef union sh_rtc2_int_config_u {
+	mmr_t	sh_rtc2_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_rtc2_int_config_s;
+} sh_rtc2_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_RTC2_INT_ENABLE"                     */
+/*                SHub RTC 2 Interrupt Enable Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc2_int_enable_u {
+	mmr_t	sh_rtc2_int_enable_regval;
+	struct {
+		mmr_t	rtc2_enable : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_rtc2_int_enable_s;
+} sh_rtc2_int_enable_u_t;
+#else
+typedef union sh_rtc2_int_enable_u {
+	mmr_t	sh_rtc2_int_enable_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	rtc2_enable : 1;
+	} sh_rtc2_int_enable_s;
+} sh_rtc2_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_RTC3_INT_CONFIG"                     */
+/*                SHub RTC 3 Interrupt Config Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc3_int_config_u {
+	mmr_t	sh_rtc3_int_config_regval;
+	struct {
+		mmr_t	type        : 3;
+		mmr_t	agt         : 1;
+		mmr_t	pid         : 16;
+		mmr_t	reserved_0  : 1;
+		mmr_t	base        : 29;
+		mmr_t	reserved_1  : 2;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_2  : 4;
+	} sh_rtc3_int_config_s;
+} sh_rtc3_int_config_u_t;
+#else
+typedef union sh_rtc3_int_config_u {
+	mmr_t	sh_rtc3_int_config_regval;
+	struct {
+		mmr_t	reserved_2  : 4;
+		mmr_t	idx         : 8;
+		mmr_t	reserved_1  : 2;
+		mmr_t	base        : 29;
+		mmr_t	reserved_0  : 1;
+		mmr_t	pid         : 16;
+		mmr_t	agt         : 1;
+		mmr_t	type        : 3;
+	} sh_rtc3_int_config_s;
+} sh_rtc3_int_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_RTC3_INT_ENABLE"                     */
+/*                SHub RTC 3 Interrupt Enable Registers                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc3_int_enable_u {
+	mmr_t	sh_rtc3_int_enable_regval;
+	struct {
+		mmr_t	rtc3_enable : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_rtc3_int_enable_s;
+} sh_rtc3_int_enable_u_t;
+#else
+typedef union sh_rtc3_int_enable_u {
+	mmr_t	sh_rtc3_int_enable_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	rtc3_enable : 1;
+	} sh_rtc3_int_enable_s;
+} sh_rtc3_int_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_EVENT_OCCURRED"                     */
+/*                    SHub Interrupt Event Occurred                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_event_occurred_u {
+	mmr_t	sh_event_occurred_regval;
+	struct {
+		mmr_t	pi_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	proc0_adv_int       : 1;
+		mmr_t	proc1_adv_int       : 1;
+		mmr_t	proc2_adv_int       : 1;
+		mmr_t	proc3_adv_int       : 1;
+		mmr_t	proc0_err_int       : 1;
+		mmr_t	proc1_err_int       : 1;
+		mmr_t	proc2_err_int       : 1;
+		mmr_t	proc3_err_int       : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	rtc0_int            : 1;
+		mmr_t	rtc1_int            : 1;
+		mmr_t	rtc2_int            : 1;
+		mmr_t	rtc3_int            : 1;
+		mmr_t	profile_int         : 1;
+		mmr_t	ipi_int             : 1;
+		mmr_t	ii_int0             : 1;
+		mmr_t	ii_int1             : 1;
+		mmr_t	reserved_0          : 33;
+	} sh_event_occurred_s;
+} sh_event_occurred_u_t;
+#else
+typedef union sh_event_occurred_u {
+	mmr_t	sh_event_occurred_regval;
+	struct {
+		mmr_t	reserved_0          : 33;
+		mmr_t	ii_int1             : 1;
+		mmr_t	ii_int0             : 1;
+		mmr_t	ipi_int             : 1;
+		mmr_t	profile_int         : 1;
+		mmr_t	rtc3_int            : 1;
+		mmr_t	rtc2_int            : 1;
+		mmr_t	rtc1_int            : 1;
+		mmr_t	rtc0_int            : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	proc3_err_int       : 1;
+		mmr_t	proc2_err_int       : 1;
+		mmr_t	proc1_err_int       : 1;
+		mmr_t	proc0_err_int       : 1;
+		mmr_t	proc3_adv_int       : 1;
+		mmr_t	proc2_adv_int       : 1;
+		mmr_t	proc1_adv_int       : 1;
+		mmr_t	proc0_adv_int       : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	pi_hw_int           : 1;
+	} sh_event_occurred_s;
+} sh_event_occurred_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_EVENT_OVERFLOW"                     */
+/*                SHub Interrupt Event Occurred Overflow                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_event_overflow_u {
+	mmr_t	sh_event_overflow_regval;
+	struct {
+		mmr_t	pi_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	proc0_adv_int       : 1;
+		mmr_t	proc1_adv_int       : 1;
+		mmr_t	proc2_adv_int       : 1;
+		mmr_t	proc3_adv_int       : 1;
+		mmr_t	proc0_err_int       : 1;
+		mmr_t	proc1_err_int       : 1;
+		mmr_t	proc2_err_int       : 1;
+		mmr_t	proc3_err_int       : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	rtc0_int            : 1;
+		mmr_t	rtc1_int            : 1;
+		mmr_t	rtc2_int            : 1;
+		mmr_t	rtc3_int            : 1;
+		mmr_t	profile_int         : 1;
+		mmr_t	reserved_0          : 36;
+	} sh_event_overflow_s;
+} sh_event_overflow_u_t;
+#else
+typedef union sh_event_overflow_u {
+	mmr_t	sh_event_overflow_regval;
+	struct {
+		mmr_t	reserved_0          : 36;
+		mmr_t	profile_int         : 1;
+		mmr_t	rtc3_int            : 1;
+		mmr_t	rtc2_int            : 1;
+		mmr_t	rtc1_int            : 1;
+		mmr_t	rtc0_int            : 1;
+		mmr_t	stop_clock          : 1;
+		mmr_t	l1_nmi_int          : 1;
+		mmr_t	uart_int            : 1;
+		mmr_t	system_shutdown_int : 1;
+		mmr_t	proc3_err_int       : 1;
+		mmr_t	proc2_err_int       : 1;
+		mmr_t	proc1_err_int       : 1;
+		mmr_t	proc0_err_int       : 1;
+		mmr_t	proc3_adv_int       : 1;
+		mmr_t	proc2_adv_int       : 1;
+		mmr_t	proc1_adv_int       : 1;
+		mmr_t	proc0_adv_int       : 1;
+		mmr_t	xn_uce_int          : 1;
+		mmr_t	md_uce_int          : 1;
+		mmr_t	pi_uce_int          : 1;
+		mmr_t	xn_ce_int           : 1;
+		mmr_t	md_ce_int           : 1;
+		mmr_t	pi_ce_int           : 1;
+		mmr_t	ii_hw_int           : 1;
+		mmr_t	lb_hw_int           : 1;
+		mmr_t	xn_hw_int           : 1;
+		mmr_t	md_hw_int           : 1;
+		mmr_t	pi_hw_int           : 1;
+	} sh_event_overflow_s;
+} sh_event_overflow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_TIME"                      */
+/*                           Junk Bus Timing                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_junk_bus_time_u {
+	mmr_t	sh_junk_bus_time_regval;
+	struct {
+		mmr_t	fprom_setup_hold : 8;
+		mmr_t	fprom_enable     : 8;
+		mmr_t	uart_setup_hold  : 8;
+		mmr_t	uart_enable      : 8;
+		mmr_t	reserved_0       : 32;
+	} sh_junk_bus_time_s;
+} sh_junk_bus_time_u_t;
+#else
+typedef union sh_junk_bus_time_u {
+	mmr_t	sh_junk_bus_time_regval;
+	struct {
+		mmr_t	reserved_0       : 32;
+		mmr_t	uart_enable      : 8;
+		mmr_t	uart_setup_hold  : 8;
+		mmr_t	fprom_enable     : 8;
+		mmr_t	fprom_setup_hold : 8;
+	} sh_junk_bus_time_s;
+} sh_junk_bus_time_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_JUNK_LATCH_TIME"                     */
+/*                        Junk Bus Latch Timing                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_junk_latch_time_u {
+	mmr_t	sh_junk_latch_time_regval;
+	struct {
+		mmr_t	setup_hold  : 3;
+		mmr_t	reserved_0  : 61;
+	} sh_junk_latch_time_s;
+} sh_junk_latch_time_u_t;
+#else
+typedef union sh_junk_latch_time_u {
+	mmr_t	sh_junk_latch_time_regval;
+	struct {
+		mmr_t	reserved_0  : 61;
+		mmr_t	setup_hold  : 3;
+	} sh_junk_latch_time_s;
+} sh_junk_latch_time_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_JUNK_NACK_RESET"                     */
+/*                     Junk Bus Nack Counter Reset                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_junk_nack_reset_u {
+	mmr_t	sh_junk_nack_reset_regval;
+	struct {
+		mmr_t	pulse       : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_junk_nack_reset_s;
+} sh_junk_nack_reset_u_t;
+#else
+typedef union sh_junk_nack_reset_u {
+	mmr_t	sh_junk_nack_reset_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	pulse       : 1;
+	} sh_junk_nack_reset_s;
+} sh_junk_nack_reset_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_LED0"                      */
+/*                            Junk Bus LED0                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_junk_bus_led0_u {
+	mmr_t	sh_junk_bus_led0_regval;
+	struct {
+		mmr_t	led0_data   : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_junk_bus_led0_s;
+} sh_junk_bus_led0_u_t;
+#else
+typedef union sh_junk_bus_led0_u {
+	mmr_t	sh_junk_bus_led0_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	led0_data   : 8;
+	} sh_junk_bus_led0_s;
+} sh_junk_bus_led0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_LED1"                      */
+/*                            Junk Bus LED1                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_junk_bus_led1_u {
+	mmr_t	sh_junk_bus_led1_regval;
+	struct {
+		mmr_t	led1_data   : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_junk_bus_led1_s;
+} sh_junk_bus_led1_u_t;
+#else
+typedef union sh_junk_bus_led1_u {
+	mmr_t	sh_junk_bus_led1_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	led1_data   : 8;
+	} sh_junk_bus_led1_s;
+} sh_junk_bus_led1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_LED2"                      */
+/*                            Junk Bus LED2                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_junk_bus_led2_u {
+	mmr_t	sh_junk_bus_led2_regval;
+	struct {
+		mmr_t	led2_data   : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_junk_bus_led2_s;
+} sh_junk_bus_led2_u_t;
+#else
+typedef union sh_junk_bus_led2_u {
+	mmr_t	sh_junk_bus_led2_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	led2_data   : 8;
+	} sh_junk_bus_led2_s;
+} sh_junk_bus_led2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_JUNK_BUS_LED3"                      */
+/*                            Junk Bus LED3                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_junk_bus_led3_u {
+	mmr_t	sh_junk_bus_led3_regval;
+	struct {
+		mmr_t	led3_data   : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_junk_bus_led3_s;
+} sh_junk_bus_led3_u_t;
+#else
+typedef union sh_junk_bus_led3_u {
+	mmr_t	sh_junk_bus_led3_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	led3_data   : 8;
+	} sh_junk_bus_led3_s;
+} sh_junk_bus_led3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_JUNK_ERROR_STATUS"                    */
+/*                        Junk Bus Error Status                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_junk_error_status_u {
+	mmr_t	sh_junk_error_status_regval;
+	struct {
+		mmr_t	address     : 47;
+		mmr_t	reserved_0  : 1;
+		mmr_t	cmd         : 8;
+		mmr_t	mode        : 1;
+		mmr_t	status      : 4;
+		mmr_t	reserved_1  : 3;
+	} sh_junk_error_status_s;
+} sh_junk_error_status_u_t;
+#else
+typedef union sh_junk_error_status_u {
+	mmr_t	sh_junk_error_status_regval;
+	struct {
+		mmr_t	reserved_1  : 3;
+		mmr_t	status      : 4;
+		mmr_t	mode        : 1;
+		mmr_t	cmd         : 8;
+		mmr_t	reserved_0  : 1;
+		mmr_t	address     : 47;
+	} sh_junk_error_status_s;
+} sh_junk_error_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_NI0_LLP_STAT"                      */
+/*               This register describes the LLP status.                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_stat_u {
+	mmr_t	sh_ni0_llp_stat_regval;
+	struct {
+		mmr_t	link_reset_state : 4;
+		mmr_t	reserved_0       : 60;
+	} sh_ni0_llp_stat_s;
+} sh_ni0_llp_stat_u_t;
+#else
+typedef union sh_ni0_llp_stat_u {
+	mmr_t	sh_ni0_llp_stat_regval;
+	struct {
+		mmr_t	reserved_0       : 60;
+		mmr_t	link_reset_state : 4;
+	} sh_ni0_llp_stat_s;
+} sh_ni0_llp_stat_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_NI0_LLP_RESET"                      */
+/*           Writing issues a reset to the network interface            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_reset_u {
+	mmr_t	sh_ni0_llp_reset_regval;
+	struct {
+		mmr_t	link        : 1;
+		mmr_t	warm        : 1;
+		mmr_t	reserved_0  : 62;
+	} sh_ni0_llp_reset_s;
+} sh_ni0_llp_reset_u_t;
+#else
+typedef union sh_ni0_llp_reset_u {
+	mmr_t	sh_ni0_llp_reset_regval;
+	struct {
+		mmr_t	reserved_0  : 62;
+		mmr_t	warm        : 1;
+		mmr_t	link        : 1;
+	} sh_ni0_llp_reset_s;
+} sh_ni0_llp_reset_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LLP_RESET_EN"                    */
+/*                 Controls LLP warm reset propagation                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_reset_en_u {
+	mmr_t	sh_ni0_llp_reset_en_regval;
+	struct {
+		mmr_t	ok          : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_ni0_llp_reset_en_s;
+} sh_ni0_llp_reset_en_u_t;
+#else
+typedef union sh_ni0_llp_reset_en_u {
+	mmr_t	sh_ni0_llp_reset_en_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	ok          : 1;
+	} sh_ni0_llp_reset_en_s;
+} sh_ni0_llp_reset_en_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_LLP_CHAN_MODE"                    */
+/*              Sets the signaling mode of LLP and channel              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_chan_mode_u {
+	mmr_t	sh_ni0_llp_chan_mode_regval;
+	struct {
+		mmr_t	bitmode32         : 1;
+		mmr_t	ac_encode         : 1;
+		mmr_t	enable_tuning     : 1;
+		mmr_t	enable_rmt_ft_upd : 1;
+		mmr_t	enable_clkquad    : 1;
+		mmr_t	reserved_0        : 59;
+	} sh_ni0_llp_chan_mode_s;
+} sh_ni0_llp_chan_mode_u_t;
+#else
+typedef union sh_ni0_llp_chan_mode_u {
+	mmr_t	sh_ni0_llp_chan_mode_regval;
+	struct {
+		mmr_t	reserved_0        : 59;
+		mmr_t	enable_clkquad    : 1;
+		mmr_t	enable_rmt_ft_upd : 1;
+		mmr_t	enable_tuning     : 1;
+		mmr_t	ac_encode         : 1;
+		mmr_t	bitmode32         : 1;
+	} sh_ni0_llp_chan_mode_s;
+} sh_ni0_llp_chan_mode_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_NI0_LLP_CONFIG"                     */
+/*              Sets the configuration of LLP and channel               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_config_u {
+	mmr_t	sh_ni0_llp_config_regval;
+	struct {
+		mmr_t	maxburst    : 10;
+		mmr_t	maxretry    : 10;
+		mmr_t	nulltimeout : 6;
+		mmr_t	ftu_time    : 12;
+		mmr_t	reserved_0  : 26;
+	} sh_ni0_llp_config_s;
+} sh_ni0_llp_config_u_t;
+#else
+typedef union sh_ni0_llp_config_u {
+	mmr_t	sh_ni0_llp_config_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	ftu_time    : 12;
+		mmr_t	nulltimeout : 6;
+		mmr_t	maxretry    : 10;
+		mmr_t	maxburst    : 10;
+	} sh_ni0_llp_config_s;
+} sh_ni0_llp_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LLP_TEST_CTL"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_test_ctl_u {
+	mmr_t	sh_ni0_llp_test_ctl_regval;
+	struct {
+		mmr_t	pattern        : 40;
+		mmr_t	send_test_mode : 2;
+		mmr_t	reserved_0     : 2;
+		mmr_t	wire_sel       : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	lfsr_mode      : 2;
+		mmr_t	noise_mode     : 2;
+		mmr_t	armcapture     : 1;
+		mmr_t	capturecbonly  : 1;
+		mmr_t	sendcberror    : 1;
+		mmr_t	sendsnerror    : 1;
+		mmr_t	fakesnerror    : 1;
+		mmr_t	captured       : 1;
+		mmr_t	cberror        : 1;
+		mmr_t	reserved_2     : 1;
+	} sh_ni0_llp_test_ctl_s;
+} sh_ni0_llp_test_ctl_u_t;
+#else
+typedef union sh_ni0_llp_test_ctl_u {
+	mmr_t	sh_ni0_llp_test_ctl_regval;
+	struct {
+		mmr_t	reserved_2     : 1;
+		mmr_t	cberror        : 1;
+		mmr_t	captured       : 1;
+		mmr_t	fakesnerror    : 1;
+		mmr_t	sendsnerror    : 1;
+		mmr_t	sendcberror    : 1;
+		mmr_t	capturecbonly  : 1;
+		mmr_t	armcapture     : 1;
+		mmr_t	noise_mode     : 2;
+		mmr_t	lfsr_mode      : 2;
+		mmr_t	reserved_1     : 2;
+		mmr_t	wire_sel       : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	send_test_mode : 2;
+		mmr_t	pattern        : 40;
+	} sh_ni0_llp_test_ctl_s;
+} sh_ni0_llp_test_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LLP_CAPT_WD1"                    */
+/*                    low order 64-bit captured word                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_capt_wd1_u {
+	mmr_t	sh_ni0_llp_capt_wd1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_ni0_llp_capt_wd1_s;
+} sh_ni0_llp_capt_wd1_u_t;
+#else
+typedef union sh_ni0_llp_capt_wd1_u {
+	mmr_t	sh_ni0_llp_capt_wd1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_ni0_llp_capt_wd1_s;
+} sh_ni0_llp_capt_wd1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LLP_CAPT_WD2"                    */
+/*                   high order 64-bit captured word                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_capt_wd2_u {
+	mmr_t	sh_ni0_llp_capt_wd2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_ni0_llp_capt_wd2_s;
+} sh_ni0_llp_capt_wd2_u_t;
+#else
+typedef union sh_ni0_llp_capt_wd2_u {
+	mmr_t	sh_ni0_llp_capt_wd2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_ni0_llp_capt_wd2_s;
+} sh_ni0_llp_capt_wd2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_LLP_CAPT_SBCB"                    */
+/*                 captured sideband, sequence, and CRC                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_capt_sbcb_u {
+	mmr_t	sh_ni0_llp_capt_sbcb_regval;
+	struct {
+		mmr_t	capturedrcvsbsn  : 16;
+		mmr_t	capturedrcvcrc   : 16;
+		mmr_t	sentallcberrors  : 1;
+		mmr_t	sentallsnerrors  : 1;
+		mmr_t	fakedallsnerrors : 1;
+		mmr_t	chargeoverflow   : 1;
+		mmr_t	chargeunderflow  : 1;
+		mmr_t	reserved_0       : 27;
+	} sh_ni0_llp_capt_sbcb_s;
+} sh_ni0_llp_capt_sbcb_u_t;
+#else
+typedef union sh_ni0_llp_capt_sbcb_u {
+	mmr_t	sh_ni0_llp_capt_sbcb_regval;
+	struct {
+		mmr_t	reserved_0       : 27;
+		mmr_t	chargeunderflow  : 1;
+		mmr_t	chargeoverflow   : 1;
+		mmr_t	fakedallsnerrors : 1;
+		mmr_t	sentallsnerrors  : 1;
+		mmr_t	sentallcberrors  : 1;
+		mmr_t	capturedrcvcrc   : 16;
+		mmr_t	capturedrcvsbsn  : 16;
+	} sh_ni0_llp_capt_sbcb_s;
+} sh_ni0_llp_capt_sbcb_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_NI0_LLP_ERR"                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_llp_err_u {
+	mmr_t	sh_ni0_llp_err_regval;
+	struct {
+		mmr_t	rx_sn_err_count : 8;
+		mmr_t	rx_cb_err_count : 8;
+		mmr_t	retry_count     : 8;
+		mmr_t	retry_timeout   : 1;
+		mmr_t	rcv_link_reset  : 1;
+		mmr_t	squash          : 1;
+		mmr_t	power_not_ok    : 1;
+		mmr_t	wire_cnt        : 24;
+		mmr_t	wire_overflow   : 1;
+		mmr_t	reserved_0      : 11;
+	} sh_ni0_llp_err_s;
+} sh_ni0_llp_err_u_t;
+#else
+typedef union sh_ni0_llp_err_u {
+	mmr_t	sh_ni0_llp_err_regval;
+	struct {
+		mmr_t	reserved_0      : 11;
+		mmr_t	wire_overflow   : 1;
+		mmr_t	wire_cnt        : 24;
+		mmr_t	power_not_ok    : 1;
+		mmr_t	squash          : 1;
+		mmr_t	rcv_link_reset  : 1;
+		mmr_t	retry_timeout   : 1;
+		mmr_t	retry_count     : 8;
+		mmr_t	rx_cb_err_count : 8;
+		mmr_t	rx_sn_err_count : 8;
+	} sh_ni0_llp_err_s;
+} sh_ni0_llp_err_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_NI1_LLP_STAT"                      */
+/*               This register describes the LLP status.                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_stat_u {
+	mmr_t	sh_ni1_llp_stat_regval;
+	struct {
+		mmr_t	link_reset_state : 4;
+		mmr_t	reserved_0       : 60;
+	} sh_ni1_llp_stat_s;
+} sh_ni1_llp_stat_u_t;
+#else
+typedef union sh_ni1_llp_stat_u {
+	mmr_t	sh_ni1_llp_stat_regval;
+	struct {
+		mmr_t	reserved_0       : 60;
+		mmr_t	link_reset_state : 4;
+	} sh_ni1_llp_stat_s;
+} sh_ni1_llp_stat_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_NI1_LLP_RESET"                      */
+/*           Writing issues a reset to the network interface            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_reset_u {
+	mmr_t	sh_ni1_llp_reset_regval;
+	struct {
+		mmr_t	link        : 1;
+		mmr_t	warm        : 1;
+		mmr_t	reserved_0  : 62;
+	} sh_ni1_llp_reset_s;
+} sh_ni1_llp_reset_u_t;
+#else
+typedef union sh_ni1_llp_reset_u {
+	mmr_t	sh_ni1_llp_reset_regval;
+	struct {
+		mmr_t	reserved_0  : 62;
+		mmr_t	warm        : 1;
+		mmr_t	link        : 1;
+	} sh_ni1_llp_reset_s;
+} sh_ni1_llp_reset_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LLP_RESET_EN"                    */
+/*                 Controls LLP warm reset propagation                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_reset_en_u {
+	mmr_t	sh_ni1_llp_reset_en_regval;
+	struct {
+		mmr_t	ok          : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_ni1_llp_reset_en_s;
+} sh_ni1_llp_reset_en_u_t;
+#else
+typedef union sh_ni1_llp_reset_en_u {
+	mmr_t	sh_ni1_llp_reset_en_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	ok          : 1;
+	} sh_ni1_llp_reset_en_s;
+} sh_ni1_llp_reset_en_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_LLP_CHAN_MODE"                    */
+/*              Sets the signaling mode of LLP and channel              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_chan_mode_u {
+	mmr_t	sh_ni1_llp_chan_mode_regval;
+	struct {
+		mmr_t	bitmode32         : 1;
+		mmr_t	ac_encode         : 1;
+		mmr_t	enable_tuning     : 1;
+		mmr_t	enable_rmt_ft_upd : 1;
+		mmr_t	enable_clkquad    : 1;
+		mmr_t	reserved_0        : 59;
+	} sh_ni1_llp_chan_mode_s;
+} sh_ni1_llp_chan_mode_u_t;
+#else
+typedef union sh_ni1_llp_chan_mode_u {
+	mmr_t	sh_ni1_llp_chan_mode_regval;
+	struct {
+		mmr_t	reserved_0        : 59;
+		mmr_t	enable_clkquad    : 1;
+		mmr_t	enable_rmt_ft_upd : 1;
+		mmr_t	enable_tuning     : 1;
+		mmr_t	ac_encode         : 1;
+		mmr_t	bitmode32         : 1;
+	} sh_ni1_llp_chan_mode_s;
+} sh_ni1_llp_chan_mode_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_NI1_LLP_CONFIG"                     */
+/*              Sets the configuration of LLP and channel               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_config_u {
+	mmr_t	sh_ni1_llp_config_regval;
+	struct {
+		mmr_t	maxburst    : 10;
+		mmr_t	maxretry    : 10;
+		mmr_t	nulltimeout : 6;
+		mmr_t	ftu_time    : 12;
+		mmr_t	reserved_0  : 26;
+	} sh_ni1_llp_config_s;
+} sh_ni1_llp_config_u_t;
+#else
+typedef union sh_ni1_llp_config_u {
+	mmr_t	sh_ni1_llp_config_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	ftu_time    : 12;
+		mmr_t	nulltimeout : 6;
+		mmr_t	maxretry    : 10;
+		mmr_t	maxburst    : 10;
+	} sh_ni1_llp_config_s;
+} sh_ni1_llp_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LLP_TEST_CTL"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_test_ctl_u {
+	mmr_t	sh_ni1_llp_test_ctl_regval;
+	struct {
+		mmr_t	pattern        : 40;
+		mmr_t	send_test_mode : 2;
+		mmr_t	reserved_0     : 2;
+		mmr_t	wire_sel       : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	lfsr_mode      : 2;
+		mmr_t	noise_mode     : 2;
+		mmr_t	armcapture     : 1;
+		mmr_t	capturecbonly  : 1;
+		mmr_t	sendcberror    : 1;
+		mmr_t	sendsnerror    : 1;
+		mmr_t	fakesnerror    : 1;
+		mmr_t	captured       : 1;
+		mmr_t	cberror        : 1;
+		mmr_t	reserved_2     : 1;
+	} sh_ni1_llp_test_ctl_s;
+} sh_ni1_llp_test_ctl_u_t;
+#else
+typedef union sh_ni1_llp_test_ctl_u {
+	mmr_t	sh_ni1_llp_test_ctl_regval;
+	struct {
+		mmr_t	reserved_2     : 1;
+		mmr_t	cberror        : 1;
+		mmr_t	captured       : 1;
+		mmr_t	fakesnerror    : 1;
+		mmr_t	sendsnerror    : 1;
+		mmr_t	sendcberror    : 1;
+		mmr_t	capturecbonly  : 1;
+		mmr_t	armcapture     : 1;
+		mmr_t	noise_mode     : 2;
+		mmr_t	lfsr_mode      : 2;
+		mmr_t	reserved_1     : 2;
+		mmr_t	wire_sel       : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	send_test_mode : 2;
+		mmr_t	pattern        : 40;
+	} sh_ni1_llp_test_ctl_s;
+} sh_ni1_llp_test_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LLP_CAPT_WD1"                    */
+/*                    low order 64-bit captured word                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_capt_wd1_u {
+	mmr_t	sh_ni1_llp_capt_wd1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_ni1_llp_capt_wd1_s;
+} sh_ni1_llp_capt_wd1_u_t;
+#else
+typedef union sh_ni1_llp_capt_wd1_u {
+	mmr_t	sh_ni1_llp_capt_wd1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_ni1_llp_capt_wd1_s;
+} sh_ni1_llp_capt_wd1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LLP_CAPT_WD2"                    */
+/*                   high order 64-bit captured word                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_capt_wd2_u {
+	mmr_t	sh_ni1_llp_capt_wd2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_ni1_llp_capt_wd2_s;
+} sh_ni1_llp_capt_wd2_u_t;
+#else
+typedef union sh_ni1_llp_capt_wd2_u {
+	mmr_t	sh_ni1_llp_capt_wd2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_ni1_llp_capt_wd2_s;
+} sh_ni1_llp_capt_wd2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_LLP_CAPT_SBCB"                    */
+/*                 captured sideband, sequence, and CRC                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_capt_sbcb_u {
+	mmr_t	sh_ni1_llp_capt_sbcb_regval;
+	struct {
+		mmr_t	capturedrcvsbsn  : 16;
+		mmr_t	capturedrcvcrc   : 16;
+		mmr_t	sentallcberrors  : 1;
+		mmr_t	sentallsnerrors  : 1;
+		mmr_t	fakedallsnerrors : 1;
+		mmr_t	chargeoverflow   : 1;
+		mmr_t	chargeunderflow  : 1;
+		mmr_t	reserved_0       : 27;
+	} sh_ni1_llp_capt_sbcb_s;
+} sh_ni1_llp_capt_sbcb_u_t;
+#else
+typedef union sh_ni1_llp_capt_sbcb_u {
+	mmr_t	sh_ni1_llp_capt_sbcb_regval;
+	struct {
+		mmr_t	reserved_0       : 27;
+		mmr_t	chargeunderflow  : 1;
+		mmr_t	chargeoverflow   : 1;
+		mmr_t	fakedallsnerrors : 1;
+		mmr_t	sentallsnerrors  : 1;
+		mmr_t	sentallcberrors  : 1;
+		mmr_t	capturedrcvcrc   : 16;
+		mmr_t	capturedrcvsbsn  : 16;
+	} sh_ni1_llp_capt_sbcb_s;
+} sh_ni1_llp_capt_sbcb_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_NI1_LLP_ERR"                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_llp_err_u {
+	mmr_t	sh_ni1_llp_err_regval;
+	struct {
+		mmr_t	rx_sn_err_count : 8;
+		mmr_t	rx_cb_err_count : 8;
+		mmr_t	retry_count     : 8;
+		mmr_t	retry_timeout   : 1;
+		mmr_t	rcv_link_reset  : 1;
+		mmr_t	squash          : 1;
+		mmr_t	power_not_ok    : 1;
+		mmr_t	wire_cnt        : 24;
+		mmr_t	wire_overflow   : 1;
+		mmr_t	reserved_0      : 11;
+	} sh_ni1_llp_err_s;
+} sh_ni1_llp_err_u_t;
+#else
+typedef union sh_ni1_llp_err_u {
+	mmr_t	sh_ni1_llp_err_regval;
+	struct {
+		mmr_t	reserved_0      : 11;
+		mmr_t	wire_overflow   : 1;
+		mmr_t	wire_cnt        : 24;
+		mmr_t	power_not_ok    : 1;
+		mmr_t	squash          : 1;
+		mmr_t	rcv_link_reset  : 1;
+		mmr_t	retry_timeout   : 1;
+		mmr_t	retry_count     : 8;
+		mmr_t	rx_cb_err_count : 8;
+		mmr_t	rx_sn_err_count : 8;
+	} sh_ni1_llp_err_s;
+} sh_ni1_llp_err_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XNNI0_LLP_TO_FIFO02_FLOW"                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_llp_to_fifo02_flow_u {
+	mmr_t	sh_xnni0_llp_to_fifo02_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnni0_llp_to_fifo02_flow_s;
+} sh_xnni0_llp_to_fifo02_flow_u_t;
+#else
+typedef union sh_xnni0_llp_to_fifo02_flow_u {
+	mmr_t	sh_xnni0_llp_to_fifo02_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnni0_llp_to_fifo02_flow_s;
+} sh_xnni0_llp_to_fifo02_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XNNI0_LLP_TO_FIFO13_FLOW"                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_llp_to_fifo13_flow_u {
+	mmr_t	sh_xnni0_llp_to_fifo13_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnni0_llp_to_fifo13_flow_s;
+} sh_xnni0_llp_to_fifo13_flow_u_t;
+#else
+typedef union sh_xnni0_llp_to_fifo13_flow_u {
+	mmr_t	sh_xnni0_llp_to_fifo13_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnni0_llp_to_fifo13_flow_s;
+} sh_xnni0_llp_to_fifo13_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_LLP_DEBIT_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_llp_debit_flow_u {
+	mmr_t	sh_xnni0_llp_debit_flow_regval;
+	struct {
+		mmr_t	debit_vc0_dyn : 5;
+		mmr_t	reserved_0    : 3;
+		mmr_t	debit_vc0_cap : 5;
+		mmr_t	reserved_1    : 3;
+		mmr_t	debit_vc1_dyn : 5;
+		mmr_t	reserved_2    : 3;
+		mmr_t	debit_vc1_cap : 5;
+		mmr_t	reserved_3    : 3;
+		mmr_t	debit_vc2_dyn : 5;
+		mmr_t	reserved_4    : 3;
+		mmr_t	debit_vc2_cap : 5;
+		mmr_t	reserved_5    : 3;
+		mmr_t	debit_vc3_dyn : 5;
+		mmr_t	reserved_6    : 3;
+		mmr_t	debit_vc3_cap : 5;
+		mmr_t	reserved_7    : 3;
+	} sh_xnni0_llp_debit_flow_s;
+} sh_xnni0_llp_debit_flow_u_t;
+#else
+typedef union sh_xnni0_llp_debit_flow_u {
+	mmr_t	sh_xnni0_llp_debit_flow_regval;
+	struct {
+		mmr_t	reserved_7    : 3;
+		mmr_t	debit_vc3_cap : 5;
+		mmr_t	reserved_6    : 3;
+		mmr_t	debit_vc3_dyn : 5;
+		mmr_t	reserved_5    : 3;
+		mmr_t	debit_vc2_cap : 5;
+		mmr_t	reserved_4    : 3;
+		mmr_t	debit_vc2_dyn : 5;
+		mmr_t	reserved_3    : 3;
+		mmr_t	debit_vc1_cap : 5;
+		mmr_t	reserved_2    : 3;
+		mmr_t	debit_vc1_dyn : 5;
+		mmr_t	reserved_1    : 3;
+		mmr_t	debit_vc0_cap : 5;
+		mmr_t	reserved_0    : 3;
+		mmr_t	debit_vc0_dyn : 5;
+	} sh_xnni0_llp_debit_flow_s;
+} sh_xnni0_llp_debit_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_LINK_0_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_link_0_flow_u {
+	mmr_t	sh_xnni0_link_0_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	credit_vc0_test      : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc0_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc0_cap       : 7;
+		mmr_t	reserved_3           : 33;
+	} sh_xnni0_link_0_flow_s;
+} sh_xnni0_link_0_flow_u_t;
+#else
+typedef union sh_xnni0_link_0_flow_u {
+	mmr_t	sh_xnni0_link_0_flow_regval;
+	struct {
+		mmr_t	reserved_3           : 33;
+		mmr_t	credit_vc0_cap       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc0_dyn       : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc0_test      : 7;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnni0_link_0_flow_s;
+} sh_xnni0_link_0_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_LINK_1_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_link_1_flow_u {
+	mmr_t	sh_xnni0_link_1_flow_regval;
+	struct {
+		mmr_t	debit_vc1_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc1_force_cred : 1;
+		mmr_t	credit_vc1_test      : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc1_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc1_cap       : 7;
+		mmr_t	reserved_3           : 33;
+	} sh_xnni0_link_1_flow_s;
+} sh_xnni0_link_1_flow_u_t;
+#else
+typedef union sh_xnni0_link_1_flow_u {
+	mmr_t	sh_xnni0_link_1_flow_regval;
+	struct {
+		mmr_t	reserved_3           : 33;
+		mmr_t	credit_vc1_cap       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc1_dyn       : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc1_test      : 7;
+		mmr_t	debit_vc1_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc1_withhold   : 6;
+	} sh_xnni0_link_1_flow_s;
+} sh_xnni0_link_1_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_LINK_2_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_link_2_flow_u {
+	mmr_t	sh_xnni0_link_2_flow_regval;
+	struct {
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	credit_vc2_test      : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc2_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc2_cap       : 7;
+		mmr_t	reserved_3           : 33;
+	} sh_xnni0_link_2_flow_s;
+} sh_xnni0_link_2_flow_u_t;
+#else
+typedef union sh_xnni0_link_2_flow_u {
+	mmr_t	sh_xnni0_link_2_flow_regval;
+	struct {
+		mmr_t	reserved_3           : 33;
+		mmr_t	credit_vc2_cap       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc2_dyn       : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc2_test      : 7;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+	} sh_xnni0_link_2_flow_s;
+} sh_xnni0_link_2_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_LINK_3_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_link_3_flow_u {
+	mmr_t	sh_xnni0_link_3_flow_regval;
+	struct {
+		mmr_t	debit_vc3_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc3_force_cred : 1;
+		mmr_t	credit_vc3_test      : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc3_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc3_cap       : 7;
+		mmr_t	reserved_3           : 33;
+	} sh_xnni0_link_3_flow_s;
+} sh_xnni0_link_3_flow_u_t;
+#else
+typedef union sh_xnni0_link_3_flow_u {
+	mmr_t	sh_xnni0_link_3_flow_regval;
+	struct {
+		mmr_t	reserved_3           : 33;
+		mmr_t	credit_vc3_cap       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc3_dyn       : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc3_test      : 7;
+		mmr_t	debit_vc3_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc3_withhold   : 6;
+	} sh_xnni0_link_3_flow_s;
+} sh_xnni0_link_3_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XNNI1_LLP_TO_FIFO02_FLOW"                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_llp_to_fifo02_flow_u {
+	mmr_t	sh_xnni1_llp_to_fifo02_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnni1_llp_to_fifo02_flow_s;
+} sh_xnni1_llp_to_fifo02_flow_u_t;
+#else
+typedef union sh_xnni1_llp_to_fifo02_flow_u {
+	mmr_t	sh_xnni1_llp_to_fifo02_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnni1_llp_to_fifo02_flow_s;
+} sh_xnni1_llp_to_fifo02_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XNNI1_LLP_TO_FIFO13_FLOW"                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_llp_to_fifo13_flow_u {
+	mmr_t	sh_xnni1_llp_to_fifo13_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnni1_llp_to_fifo13_flow_s;
+} sh_xnni1_llp_to_fifo13_flow_u_t;
+#else
+typedef union sh_xnni1_llp_to_fifo13_flow_u {
+	mmr_t	sh_xnni1_llp_to_fifo13_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnni1_llp_to_fifo13_flow_s;
+} sh_xnni1_llp_to_fifo13_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_LLP_DEBIT_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_llp_debit_flow_u {
+	mmr_t	sh_xnni1_llp_debit_flow_regval;
+	struct {
+		mmr_t	debit_vc0_dyn : 5;
+		mmr_t	reserved_0    : 3;
+		mmr_t	debit_vc0_cap : 5;
+		mmr_t	reserved_1    : 3;
+		mmr_t	debit_vc1_dyn : 5;
+		mmr_t	reserved_2    : 3;
+		mmr_t	debit_vc1_cap : 5;
+		mmr_t	reserved_3    : 3;
+		mmr_t	debit_vc2_dyn : 5;
+		mmr_t	reserved_4    : 3;
+		mmr_t	debit_vc2_cap : 5;
+		mmr_t	reserved_5    : 3;
+		mmr_t	debit_vc3_dyn : 5;
+		mmr_t	reserved_6    : 3;
+		mmr_t	debit_vc3_cap : 5;
+		mmr_t	reserved_7    : 3;
+	} sh_xnni1_llp_debit_flow_s;
+} sh_xnni1_llp_debit_flow_u_t;
+#else
+typedef union sh_xnni1_llp_debit_flow_u {
+	mmr_t	sh_xnni1_llp_debit_flow_regval;
+	struct {
+		mmr_t	reserved_7    : 3;
+		mmr_t	debit_vc3_cap : 5;
+		mmr_t	reserved_6    : 3;
+		mmr_t	debit_vc3_dyn : 5;
+		mmr_t	reserved_5    : 3;
+		mmr_t	debit_vc2_cap : 5;
+		mmr_t	reserved_4    : 3;
+		mmr_t	debit_vc2_dyn : 5;
+		mmr_t	reserved_3    : 3;
+		mmr_t	debit_vc1_cap : 5;
+		mmr_t	reserved_2    : 3;
+		mmr_t	debit_vc1_dyn : 5;
+		mmr_t	reserved_1    : 3;
+		mmr_t	debit_vc0_cap : 5;
+		mmr_t	reserved_0    : 3;
+		mmr_t	debit_vc0_dyn : 5;
+	} sh_xnni1_llp_debit_flow_s;
+} sh_xnni1_llp_debit_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_LINK_0_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_link_0_flow_u {
+	mmr_t	sh_xnni1_link_0_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	credit_vc0_test      : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc0_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc0_cap       : 7;
+		mmr_t	reserved_3           : 33;
+	} sh_xnni1_link_0_flow_s;
+} sh_xnni1_link_0_flow_u_t;
+#else
+typedef union sh_xnni1_link_0_flow_u {
+	mmr_t	sh_xnni1_link_0_flow_regval;
+	struct {
+		mmr_t	reserved_3           : 33;
+		mmr_t	credit_vc0_cap       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc0_dyn       : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc0_test      : 7;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnni1_link_0_flow_s;
+} sh_xnni1_link_0_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_LINK_1_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_link_1_flow_u {
+	mmr_t	sh_xnni1_link_1_flow_regval;
+	struct {
+		mmr_t	debit_vc1_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc1_force_cred : 1;
+		mmr_t	credit_vc1_test      : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc1_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc1_cap       : 7;
+		mmr_t	reserved_3           : 33;
+	} sh_xnni1_link_1_flow_s;
+} sh_xnni1_link_1_flow_u_t;
+#else
+typedef union sh_xnni1_link_1_flow_u {
+	mmr_t	sh_xnni1_link_1_flow_regval;
+	struct {
+		mmr_t	reserved_3           : 33;
+		mmr_t	credit_vc1_cap       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc1_dyn       : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc1_test      : 7;
+		mmr_t	debit_vc1_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc1_withhold   : 6;
+	} sh_xnni1_link_1_flow_s;
+} sh_xnni1_link_1_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_LINK_2_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_link_2_flow_u {
+	mmr_t	sh_xnni1_link_2_flow_regval;
+	struct {
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	credit_vc2_test      : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc2_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc2_cap       : 7;
+		mmr_t	reserved_3           : 33;
+	} sh_xnni1_link_2_flow_s;
+} sh_xnni1_link_2_flow_u_t;
+#else
+typedef union sh_xnni1_link_2_flow_u {
+	mmr_t	sh_xnni1_link_2_flow_regval;
+	struct {
+		mmr_t	reserved_3           : 33;
+		mmr_t	credit_vc2_cap       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc2_dyn       : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc2_test      : 7;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+	} sh_xnni1_link_2_flow_s;
+} sh_xnni1_link_2_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_LINK_3_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_link_3_flow_u {
+	mmr_t	sh_xnni1_link_3_flow_regval;
+	struct {
+		mmr_t	debit_vc3_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc3_force_cred : 1;
+		mmr_t	credit_vc3_test      : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc3_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc3_cap       : 7;
+		mmr_t	reserved_3           : 33;
+	} sh_xnni1_link_3_flow_s;
+} sh_xnni1_link_3_flow_u_t;
+#else
+typedef union sh_xnni1_link_3_flow_u {
+	mmr_t	sh_xnni1_link_3_flow_regval;
+	struct {
+		mmr_t	reserved_3           : 33;
+		mmr_t	credit_vc3_cap       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc3_dyn       : 7;
+		mmr_t	reserved_1           : 1;
+		mmr_t	credit_vc3_test      : 7;
+		mmr_t	debit_vc3_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc3_withhold   : 6;
+	} sh_xnni1_link_3_flow_s;
+} sh_xnni1_link_3_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_IILB_LOCAL_TABLE"                    */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_iilb_local_table_u {
+	mmr_t	sh_iilb_local_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 57;
+		mmr_t	valid       : 1;
+	} sh_iilb_local_table_s;
+} sh_iilb_local_table_u_t;
+#else
+typedef union sh_iilb_local_table_u {
+	mmr_t	sh_iilb_local_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_0  : 57;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_iilb_local_table_s;
+} sh_iilb_local_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_IILB_GLOBAL_TABLE"                    */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_iilb_global_table_u {
+	mmr_t	sh_iilb_global_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 57;
+		mmr_t	valid       : 1;
+	} sh_iilb_global_table_s;
+} sh_iilb_global_table_u_t;
+#else
+typedef union sh_iilb_global_table_u {
+	mmr_t	sh_iilb_global_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_0  : 57;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_iilb_global_table_s;
+} sh_iilb_global_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_IILB_OVER_RIDE_TABLE"                  */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_iilb_over_ride_table_u {
+	mmr_t	sh_iilb_over_ride_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 57;
+		mmr_t	enable      : 1;
+	} sh_iilb_over_ride_table_s;
+} sh_iilb_over_ride_table_u_t;
+#else
+typedef union sh_iilb_over_ride_table_u {
+	mmr_t	sh_iilb_over_ride_table_regval;
+	struct {
+		mmr_t	enable      : 1;
+		mmr_t	reserved_0  : 57;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_iilb_over_ride_table_s;
+} sh_iilb_over_ride_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_IILB_RSP_PLANE_HINT"                   */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_iilb_rsp_plane_hint_u {
+	mmr_t	sh_iilb_rsp_plane_hint_regval;
+	struct {
+		mmr_t	reserved_0  : 64;
+	} sh_iilb_rsp_plane_hint_s;
+} sh_iilb_rsp_plane_hint_u_t;
+#else
+typedef union sh_iilb_rsp_plane_hint_u {
+	mmr_t	sh_iilb_rsp_plane_hint_regval;
+	struct {
+		mmr_t	reserved_0  : 64;
+	} sh_iilb_rsp_plane_hint_s;
+} sh_iilb_rsp_plane_hint_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PI_LOCAL_TABLE"                     */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_local_table_u {
+	mmr_t	sh_pi_local_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 2;
+		mmr_t	dir1        : 4;
+		mmr_t	v1          : 1;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	valid       : 1;
+	} sh_pi_local_table_s;
+} sh_pi_local_table_u_t;
+#else
+typedef union sh_pi_local_table_u {
+	mmr_t	sh_pi_local_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	v1          : 1;
+		mmr_t	dir1        : 4;
+		mmr_t	reserved_0  : 2;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_pi_local_table_s;
+} sh_pi_local_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_PI_GLOBAL_TABLE"                     */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_global_table_u {
+	mmr_t	sh_pi_global_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 2;
+		mmr_t	dir1        : 4;
+		mmr_t	v1          : 1;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	valid       : 1;
+	} sh_pi_global_table_s;
+} sh_pi_global_table_u_t;
+#else
+typedef union sh_pi_global_table_u {
+	mmr_t	sh_pi_global_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	v1          : 1;
+		mmr_t	dir1        : 4;
+		mmr_t	reserved_0  : 2;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_pi_global_table_s;
+} sh_pi_global_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_OVER_RIDE_TABLE"                   */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_over_ride_table_u {
+	mmr_t	sh_pi_over_ride_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 2;
+		mmr_t	dir1        : 4;
+		mmr_t	v1          : 1;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	enable      : 1;
+	} sh_pi_over_ride_table_s;
+} sh_pi_over_ride_table_u_t;
+#else
+typedef union sh_pi_over_ride_table_u {
+	mmr_t	sh_pi_over_ride_table_regval;
+	struct {
+		mmr_t	enable      : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	v1          : 1;
+		mmr_t	dir1        : 4;
+		mmr_t	reserved_0  : 2;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_pi_over_ride_table_s;
+} sh_pi_over_ride_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_RSP_PLANE_HINT"                    */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_rsp_plane_hint_u {
+	mmr_t	sh_pi_rsp_plane_hint_regval;
+	struct {
+		mmr_t	invert      : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_pi_rsp_plane_hint_s;
+} sh_pi_rsp_plane_hint_u_t;
+#else
+typedef union sh_pi_rsp_plane_hint_u {
+	mmr_t	sh_pi_rsp_plane_hint_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	invert      : 1;
+	} sh_pi_rsp_plane_hint_s;
+} sh_pi_rsp_plane_hint_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_LOCAL_TABLE"                     */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_local_table_u {
+	mmr_t	sh_ni0_local_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	valid       : 1;
+	} sh_ni0_local_table_s;
+} sh_ni0_local_table_u_t;
+#else
+typedef union sh_ni0_local_table_u {
+	mmr_t	sh_ni0_local_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_ni0_local_table_s;
+} sh_ni0_local_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_GLOBAL_TABLE"                    */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_global_table_u {
+	mmr_t	sh_ni0_global_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	valid       : 1;
+	} sh_ni0_global_table_s;
+} sh_ni0_global_table_u_t;
+#else
+typedef union sh_ni0_global_table_u {
+	mmr_t	sh_ni0_global_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_ni0_global_table_s;
+} sh_ni0_global_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_OVER_RIDE_TABLE"                   */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_over_ride_table_u {
+	mmr_t	sh_ni0_over_ride_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	enable      : 1;
+	} sh_ni0_over_ride_table_s;
+} sh_ni0_over_ride_table_u_t;
+#else
+typedef union sh_ni0_over_ride_table_u {
+	mmr_t	sh_ni0_over_ride_table_regval;
+	struct {
+		mmr_t	enable      : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_ni0_over_ride_table_s;
+} sh_ni0_over_ride_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_RSP_PLANE_HINT"                   */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_rsp_plane_hint_u {
+	mmr_t	sh_ni0_rsp_plane_hint_regval;
+	struct {
+		mmr_t	reserved_0  : 64;
+	} sh_ni0_rsp_plane_hint_s;
+} sh_ni0_rsp_plane_hint_u_t;
+#else
+typedef union sh_ni0_rsp_plane_hint_u {
+	mmr_t	sh_ni0_rsp_plane_hint_regval;
+	struct {
+		mmr_t	reserved_0  : 64;
+	} sh_ni0_rsp_plane_hint_s;
+} sh_ni0_rsp_plane_hint_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_LOCAL_TABLE"                     */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_local_table_u {
+	mmr_t	sh_ni1_local_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	valid       : 1;
+	} sh_ni1_local_table_s;
+} sh_ni1_local_table_u_t;
+#else
+typedef union sh_ni1_local_table_u {
+	mmr_t	sh_ni1_local_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_ni1_local_table_s;
+} sh_ni1_local_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_GLOBAL_TABLE"                    */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_global_table_u {
+	mmr_t	sh_ni1_global_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	valid       : 1;
+	} sh_ni1_global_table_s;
+} sh_ni1_global_table_u_t;
+#else
+typedef union sh_ni1_global_table_u {
+	mmr_t	sh_ni1_global_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_ni1_global_table_s;
+} sh_ni1_global_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_OVER_RIDE_TABLE"                   */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_over_ride_table_u {
+	mmr_t	sh_ni1_over_ride_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	enable      : 1;
+	} sh_ni1_over_ride_table_s;
+} sh_ni1_over_ride_table_u_t;
+#else
+typedef union sh_ni1_over_ride_table_u {
+	mmr_t	sh_ni1_over_ride_table_regval;
+	struct {
+		mmr_t	enable      : 1;
+		mmr_t	reserved_0  : 58;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_ni1_over_ride_table_s;
+} sh_ni1_over_ride_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_RSP_PLANE_HINT"                   */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_rsp_plane_hint_u {
+	mmr_t	sh_ni1_rsp_plane_hint_regval;
+	struct {
+		mmr_t	reserved_0  : 64;
+	} sh_ni1_rsp_plane_hint_s;
+} sh_ni1_rsp_plane_hint_u_t;
+#else
+typedef union sh_ni1_rsp_plane_hint_u {
+	mmr_t	sh_ni1_rsp_plane_hint_regval;
+	struct {
+		mmr_t	reserved_0  : 64;
+	} sh_ni1_rsp_plane_hint_s;
+} sh_ni1_rsp_plane_hint_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_MD_LOCAL_TABLE"                     */
+/*                          local lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_local_table_u {
+	mmr_t	sh_md_local_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 2;
+		mmr_t	dir1        : 4;
+		mmr_t	v1          : 1;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	valid       : 1;
+	} sh_md_local_table_s;
+} sh_md_local_table_u_t;
+#else
+typedef union sh_md_local_table_u {
+	mmr_t	sh_md_local_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	v1          : 1;
+		mmr_t	dir1        : 4;
+		mmr_t	reserved_0  : 2;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_md_local_table_s;
+} sh_md_local_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_MD_GLOBAL_TABLE"                     */
+/*                         global lookup table                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_global_table_u {
+	mmr_t	sh_md_global_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 2;
+		mmr_t	dir1        : 4;
+		mmr_t	v1          : 1;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	valid       : 1;
+	} sh_md_global_table_s;
+} sh_md_global_table_u_t;
+#else
+typedef union sh_md_global_table_u {
+	mmr_t	sh_md_global_table_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	v1          : 1;
+		mmr_t	dir1        : 4;
+		mmr_t	reserved_0  : 2;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_md_global_table_s;
+} sh_md_global_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_OVER_RIDE_TABLE"                   */
+/*              If enabled, bypass the Global/Local tables              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_over_ride_table_u {
+	mmr_t	sh_md_over_ride_table_regval;
+	struct {
+		mmr_t	dir0        : 4;
+		mmr_t	v0          : 1;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	reserved_0  : 2;
+		mmr_t	dir1        : 4;
+		mmr_t	v1          : 1;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	enable      : 1;
+	} sh_md_over_ride_table_s;
+} sh_md_over_ride_table_u_t;
+#else
+typedef union sh_md_over_ride_table_u {
+	mmr_t	sh_md_over_ride_table_regval;
+	struct {
+		mmr_t	enable      : 1;
+		mmr_t	reserved_1  : 49;
+		mmr_t	ni_sel1     : 1;
+		mmr_t	v1          : 1;
+		mmr_t	dir1        : 4;
+		mmr_t	reserved_0  : 2;
+		mmr_t	ni_sel0     : 1;
+		mmr_t	v0          : 1;
+		mmr_t	dir0        : 4;
+	} sh_md_over_ride_table_s;
+} sh_md_over_ride_table_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_RSP_PLANE_HINT"                    */
+/*  If enabled, invert incoming response only plane hint bit before lo  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_rsp_plane_hint_u {
+	mmr_t	sh_md_rsp_plane_hint_regval;
+	struct {
+		mmr_t	invert      : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_md_rsp_plane_hint_s;
+} sh_md_rsp_plane_hint_u_t;
+#else
+typedef union sh_md_rsp_plane_hint_u {
+	mmr_t	sh_md_rsp_plane_hint_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	invert      : 1;
+	} sh_md_rsp_plane_hint_s;
+} sh_md_rsp_plane_hint_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_LB_LIQ_CTL"                       */
+/*                       Local Block LIQ Control                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_liq_ctl_u {
+	mmr_t	sh_lb_liq_ctl_regval;
+	struct {
+		mmr_t	liq_req_ctl        : 5;
+		mmr_t	reserved_0         : 3;
+		mmr_t	liq_rpl_ctl        : 4;
+		mmr_t	reserved_1         : 4;
+		mmr_t	force_rq_credit    : 1;
+		mmr_t	force_rp_credit    : 1;
+		mmr_t	force_linvv_credit : 1;
+		mmr_t	reserved_2         : 45;
+	} sh_lb_liq_ctl_s;
+} sh_lb_liq_ctl_u_t;
+#else
+typedef union sh_lb_liq_ctl_u {
+	mmr_t	sh_lb_liq_ctl_regval;
+	struct {
+		mmr_t	reserved_2         : 45;
+		mmr_t	force_linvv_credit : 1;
+		mmr_t	force_rp_credit    : 1;
+		mmr_t	force_rq_credit    : 1;
+		mmr_t	reserved_1         : 4;
+		mmr_t	liq_rpl_ctl        : 4;
+		mmr_t	reserved_0         : 3;
+		mmr_t	liq_req_ctl        : 5;
+	} sh_lb_liq_ctl_s;
+} sh_lb_liq_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_LB_LOQ_CTL"                       */
+/*                       Local Block LOQ Control                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_loq_ctl_u {
+	mmr_t	sh_lb_loq_ctl_regval;
+	struct {
+		mmr_t	loq_req_ctl : 1;
+		mmr_t	loq_rpl_ctl : 1;
+		mmr_t	reserved_0  : 62;
+	} sh_lb_loq_ctl_s;
+} sh_lb_loq_ctl_u_t;
+#else
+typedef union sh_lb_loq_ctl_u {
+	mmr_t	sh_lb_loq_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 62;
+		mmr_t	loq_rpl_ctl : 1;
+		mmr_t	loq_req_ctl : 1;
+	} sh_lb_loq_ctl_s;
+} sh_lb_loq_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_LB_MAX_REP_CREDIT_CNT"                  */
+/*               Maximum number of reply credits from XN                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_max_rep_credit_cnt_u {
+	mmr_t	sh_lb_max_rep_credit_cnt_regval;
+	struct {
+		mmr_t	max_cnt     : 5;
+		mmr_t	reserved_0  : 59;
+	} sh_lb_max_rep_credit_cnt_s;
+} sh_lb_max_rep_credit_cnt_u_t;
+#else
+typedef union sh_lb_max_rep_credit_cnt_u {
+	mmr_t	sh_lb_max_rep_credit_cnt_regval;
+	struct {
+		mmr_t	reserved_0  : 59;
+		mmr_t	max_cnt     : 5;
+	} sh_lb_max_rep_credit_cnt_s;
+} sh_lb_max_rep_credit_cnt_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_LB_MAX_REQ_CREDIT_CNT"                  */
+/*              Maximum number of request credits from XN               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_max_req_credit_cnt_u {
+	mmr_t	sh_lb_max_req_credit_cnt_regval;
+	struct {
+		mmr_t	max_cnt     : 5;
+		mmr_t	reserved_0  : 59;
+	} sh_lb_max_req_credit_cnt_s;
+} sh_lb_max_req_credit_cnt_u_t;
+#else
+typedef union sh_lb_max_req_credit_cnt_u {
+	mmr_t	sh_lb_max_req_credit_cnt_regval;
+	struct {
+		mmr_t	reserved_0  : 59;
+		mmr_t	max_cnt     : 5;
+	} sh_lb_max_req_credit_cnt_s;
+} sh_lb_max_req_credit_cnt_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_PIO_TIME_OUT"                      */
+/*                    Local Block PIO time out value                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pio_time_out_u {
+	mmr_t	sh_pio_time_out_regval;
+	struct {
+		mmr_t	value       : 16;
+		mmr_t	reserved_0  : 48;
+	} sh_pio_time_out_s;
+} sh_pio_time_out_u_t;
+#else
+typedef union sh_pio_time_out_u {
+	mmr_t	sh_pio_time_out_regval;
+	struct {
+		mmr_t	reserved_0  : 48;
+		mmr_t	value       : 16;
+	} sh_pio_time_out_s;
+} sh_pio_time_out_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PIO_NACK_RESET"                     */
+/*               Local Block PIO Reset for nack counters                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pio_nack_reset_u {
+	mmr_t	sh_pio_nack_reset_regval;
+	struct {
+		mmr_t	pulse       : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_pio_nack_reset_s;
+} sh_pio_nack_reset_u_t;
+#else
+typedef union sh_pio_nack_reset_u {
+	mmr_t	sh_pio_nack_reset_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	pulse       : 1;
+	} sh_pio_nack_reset_s;
+} sh_pio_nack_reset_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_CONVEYOR_BELT_TIME_OUT"                 */
+/*               Local Block conveyor belt time out value               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_conveyor_belt_time_out_u {
+	mmr_t	sh_conveyor_belt_time_out_regval;
+	struct {
+		mmr_t	value       : 12;
+		mmr_t	reserved_0  : 52;
+	} sh_conveyor_belt_time_out_s;
+} sh_conveyor_belt_time_out_u_t;
+#else
+typedef union sh_conveyor_belt_time_out_u {
+	mmr_t	sh_conveyor_belt_time_out_regval;
+	struct {
+		mmr_t	reserved_0  : 52;
+		mmr_t	value       : 12;
+	} sh_conveyor_belt_time_out_s;
+} sh_conveyor_belt_time_out_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_LB_CREDIT_STATUS"                    */
+/*                    Credit Counter Status Register                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_credit_status_u {
+	mmr_t	sh_lb_credit_status_regval;
+	struct {
+		mmr_t	liq_rq_credit : 5;
+		mmr_t	reserved_0    : 1;
+		mmr_t	liq_rp_credit : 4;
+		mmr_t	reserved_1    : 2;
+		mmr_t	linvv_credit  : 6;
+		mmr_t	loq_rq_credit : 5;
+		mmr_t	loq_rp_credit : 5;
+		mmr_t	reserved_2    : 36;
+	} sh_lb_credit_status_s;
+} sh_lb_credit_status_u_t;
+#else
+typedef union sh_lb_credit_status_u {
+	mmr_t	sh_lb_credit_status_regval;
+	struct {
+		mmr_t	reserved_2    : 36;
+		mmr_t	loq_rp_credit : 5;
+		mmr_t	loq_rq_credit : 5;
+		mmr_t	linvv_credit  : 6;
+		mmr_t	reserved_1    : 2;
+		mmr_t	liq_rp_credit : 4;
+		mmr_t	reserved_0    : 1;
+		mmr_t	liq_rq_credit : 5;
+	} sh_lb_credit_status_s;
+} sh_lb_credit_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_DEBUG_LOCAL_SEL"                   */
+/*                         LB Debug Port Select                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_debug_local_sel_u {
+	mmr_t	sh_lb_debug_local_sel_regval;
+	struct {
+		mmr_t	nibble0_chiplet_sel : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	trigger_enable      : 1;
+	} sh_lb_debug_local_sel_s;
+} sh_lb_debug_local_sel_u_t;
+#else
+typedef union sh_lb_debug_local_sel_u {
+	mmr_t	sh_lb_debug_local_sel_regval;
+	struct {
+		mmr_t	trigger_enable      : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_chiplet_sel : 3;
+	} sh_lb_debug_local_sel_s;
+} sh_lb_debug_local_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_DEBUG_PERF_SEL"                    */
+/*                   LB Debug Port Performance Select                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_debug_perf_sel_u {
+	mmr_t	sh_lb_debug_perf_sel_regval;
+	struct {
+		mmr_t	nibble0_chiplet_sel : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	reserved_15         : 1;
+	} sh_lb_debug_perf_sel_s;
+} sh_lb_debug_perf_sel_u_t;
+#else
+typedef union sh_lb_debug_perf_sel_u {
+	mmr_t	sh_lb_debug_perf_sel_regval;
+	struct {
+		mmr_t	reserved_15         : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_chiplet_sel : 3;
+	} sh_lb_debug_perf_sel_s;
+} sh_lb_debug_perf_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_DEBUG_TRIG_SEL"                    */
+/*                       LB Debug Trigger Select                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_debug_trig_sel_u {
+	mmr_t	sh_lb_debug_trig_sel_regval;
+	struct {
+		mmr_t	trigger0_chiplet_sel : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger1_chiplet_sel : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger2_chiplet_sel : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger3_chiplet_sel : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger4_chiplet_sel : 3;
+		mmr_t	reserved_8           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_9           : 1;
+		mmr_t	trigger5_chiplet_sel : 3;
+		mmr_t	reserved_10          : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_11          : 1;
+		mmr_t	trigger6_chiplet_sel : 3;
+		mmr_t	reserved_12          : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_13          : 1;
+		mmr_t	trigger7_chiplet_sel : 3;
+		mmr_t	reserved_14          : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_15          : 1;
+	} sh_lb_debug_trig_sel_s;
+} sh_lb_debug_trig_sel_u_t;
+#else
+typedef union sh_lb_debug_trig_sel_u {
+	mmr_t	sh_lb_debug_trig_sel_regval;
+	struct {
+		mmr_t	reserved_15          : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_14          : 1;
+		mmr_t	trigger7_chiplet_sel : 3;
+		mmr_t	reserved_13          : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_12          : 1;
+		mmr_t	trigger6_chiplet_sel : 3;
+		mmr_t	reserved_11          : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_10          : 1;
+		mmr_t	trigger5_chiplet_sel : 3;
+		mmr_t	reserved_9           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_8           : 1;
+		mmr_t	trigger4_chiplet_sel : 3;
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger3_chiplet_sel : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger2_chiplet_sel : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger1_chiplet_sel : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_chiplet_sel : 3;
+	} sh_lb_debug_trig_sel_s;
+} sh_lb_debug_trig_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_1"                    */
+/*                  LB Error capture information: HDR1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_error_detail_1_u {
+	mmr_t	sh_lb_error_detail_1_regval;
+	struct {
+		mmr_t	command     : 8;
+		mmr_t	suppl       : 14;
+		mmr_t	reserved_0  : 2;
+		mmr_t	source      : 14;
+		mmr_t	reserved_1  : 2;
+		mmr_t	dest        : 3;
+		mmr_t	reserved_2  : 5;
+		mmr_t	hdr_err     : 1;
+		mmr_t	data_err    : 1;
+		mmr_t	reserved_3  : 13;
+		mmr_t	valid       : 1;
+	} sh_lb_error_detail_1_s;
+} sh_lb_error_detail_1_u_t;
+#else
+typedef union sh_lb_error_detail_1_u {
+	mmr_t	sh_lb_error_detail_1_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_3  : 13;
+		mmr_t	data_err    : 1;
+		mmr_t	hdr_err     : 1;
+		mmr_t	reserved_2  : 5;
+		mmr_t	dest        : 3;
+		mmr_t	reserved_1  : 2;
+		mmr_t	source      : 14;
+		mmr_t	reserved_0  : 2;
+		mmr_t	suppl       : 14;
+		mmr_t	command     : 8;
+	} sh_lb_error_detail_1_s;
+} sh_lb_error_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_2"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_error_detail_2_u {
+	mmr_t	sh_lb_error_detail_2_regval;
+	struct {
+		mmr_t	address     : 47;
+		mmr_t	reserved_0  : 17;
+	} sh_lb_error_detail_2_s;
+} sh_lb_error_detail_2_u_t;
+#else
+typedef union sh_lb_error_detail_2_u {
+	mmr_t	sh_lb_error_detail_2_regval;
+	struct {
+		mmr_t	reserved_0  : 17;
+		mmr_t	address     : 47;
+	} sh_lb_error_detail_2_s;
+} sh_lb_error_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_3"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_error_detail_3_u {
+	mmr_t	sh_lb_error_detail_3_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_lb_error_detail_3_s;
+} sh_lb_error_detail_3_u_t;
+#else
+typedef union sh_lb_error_detail_3_u {
+	mmr_t	sh_lb_error_detail_3_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_lb_error_detail_3_s;
+} sh_lb_error_detail_3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_4"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_error_detail_4_u {
+	mmr_t	sh_lb_error_detail_4_regval;
+	struct {
+		mmr_t	route       : 64;
+	} sh_lb_error_detail_4_s;
+} sh_lb_error_detail_4_u_t;
+#else
+typedef union sh_lb_error_detail_4_u {
+	mmr_t	sh_lb_error_detail_4_regval;
+	struct {
+		mmr_t	route       : 64;
+	} sh_lb_error_detail_4_s;
+} sh_lb_error_detail_4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_DETAIL_5"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_error_detail_5_u {
+	mmr_t	sh_lb_error_detail_5_regval;
+	struct {
+		mmr_t	read_retry       : 1;
+		mmr_t	ptc1_write       : 1;
+		mmr_t	write_retry      : 1;
+		mmr_t	count_a_overflow : 1;
+		mmr_t	count_b_overflow : 1;
+		mmr_t	nack_a_timeout   : 1;
+		mmr_t	nack_b_timeout   : 1;
+		mmr_t	reserved_0       : 57;
+	} sh_lb_error_detail_5_s;
+} sh_lb_error_detail_5_u_t;
+#else
+typedef union sh_lb_error_detail_5_u {
+	mmr_t	sh_lb_error_detail_5_regval;
+	struct {
+		mmr_t	reserved_0       : 57;
+		mmr_t	nack_b_timeout   : 1;
+		mmr_t	nack_a_timeout   : 1;
+		mmr_t	count_b_overflow : 1;
+		mmr_t	count_a_overflow : 1;
+		mmr_t	write_retry      : 1;
+		mmr_t	ptc1_write       : 1;
+		mmr_t	read_retry       : 1;
+	} sh_lb_error_detail_5_s;
+} sh_lb_error_detail_5_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_LB_ERROR_MASK"                      */
+/*                            LB Error Mask                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_error_mask_u {
+	mmr_t	sh_lb_error_mask_regval;
+	struct {
+		mmr_t	rq_bad_cmd            : 1;
+		mmr_t	rp_bad_cmd            : 1;
+		mmr_t	rq_short              : 1;
+		mmr_t	rp_short              : 1;
+		mmr_t	rq_long               : 1;
+		mmr_t	rp_long               : 1;
+		mmr_t	rq_bad_data           : 1;
+		mmr_t	rp_bad_data           : 1;
+		mmr_t	rq_bad_addr           : 1;
+		mmr_t	rq_time_out           : 1;
+		mmr_t	linvv_overflow        : 1;
+		mmr_t	unexpected_linv       : 1;
+		mmr_t	ptc_1_timeout         : 1;
+		mmr_t	junk_bus_err          : 1;
+		mmr_t	pio_cb_err            : 1;
+		mmr_t	vector_rq_route_error : 1;
+		mmr_t	vector_rp_route_error : 1;
+		mmr_t	gclk_drop             : 1;
+		mmr_t	rq_fifo_error         : 1;
+		mmr_t	rp_fifo_error         : 1;
+		mmr_t	unexp_valid           : 1;
+		mmr_t	rq_credit_overflow    : 1;
+		mmr_t	rp_credit_overflow    : 1;
+		mmr_t	reserved_0            : 41;
+	} sh_lb_error_mask_s;
+} sh_lb_error_mask_u_t;
+#else
+typedef union sh_lb_error_mask_u {
+	mmr_t	sh_lb_error_mask_regval;
+	struct {
+		mmr_t	reserved_0            : 41;
+		mmr_t	rp_credit_overflow    : 1;
+		mmr_t	rq_credit_overflow    : 1;
+		mmr_t	unexp_valid           : 1;
+		mmr_t	rp_fifo_error         : 1;
+		mmr_t	rq_fifo_error         : 1;
+		mmr_t	gclk_drop             : 1;
+		mmr_t	vector_rp_route_error : 1;
+		mmr_t	vector_rq_route_error : 1;
+		mmr_t	pio_cb_err            : 1;
+		mmr_t	junk_bus_err          : 1;
+		mmr_t	ptc_1_timeout         : 1;
+		mmr_t	unexpected_linv       : 1;
+		mmr_t	linvv_overflow        : 1;
+		mmr_t	rq_time_out           : 1;
+		mmr_t	rq_bad_addr           : 1;
+		mmr_t	rp_bad_data           : 1;
+		mmr_t	rq_bad_data           : 1;
+		mmr_t	rp_long               : 1;
+		mmr_t	rq_long               : 1;
+		mmr_t	rp_short              : 1;
+		mmr_t	rq_short              : 1;
+		mmr_t	rp_bad_cmd            : 1;
+		mmr_t	rq_bad_cmd            : 1;
+	} sh_lb_error_mask_s;
+} sh_lb_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_ERROR_OVERFLOW"                    */
+/*                          LB Error Overflow                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_error_overflow_u {
+	mmr_t	sh_lb_error_overflow_regval;
+	struct {
+		mmr_t	rq_bad_cmd_ovrfl            : 1;
+		mmr_t	rp_bad_cmd_ovrfl            : 1;
+		mmr_t	rq_short_ovrfl              : 1;
+		mmr_t	rp_short_ovrfl              : 1;
+		mmr_t	rq_long_ovrfl               : 1;
+		mmr_t	rp_long_ovrfl               : 1;
+		mmr_t	rq_bad_data_ovrfl           : 1;
+		mmr_t	rp_bad_data_ovrfl           : 1;
+		mmr_t	rq_bad_addr_ovrfl           : 1;
+		mmr_t	rq_time_out_ovrfl           : 1;
+		mmr_t	linvv_overflow_ovrfl        : 1;
+		mmr_t	unexpected_linv_ovrfl       : 1;
+		mmr_t	ptc_1_timeout_ovrfl         : 1;
+		mmr_t	junk_bus_err_ovrfl          : 1;
+		mmr_t	pio_cb_err_ovrfl            : 1;
+		mmr_t	vector_rq_route_error_ovrfl : 1;
+		mmr_t	vector_rp_route_error_ovrfl : 1;
+		mmr_t	gclk_drop_ovrfl             : 1;
+		mmr_t	rq_fifo_error_ovrfl         : 1;
+		mmr_t	rp_fifo_error_ovrfl         : 1;
+		mmr_t	unexp_valid_ovrfl           : 1;
+		mmr_t	rq_credit_overflow_ovrfl    : 1;
+		mmr_t	rp_credit_overflow_ovrfl    : 1;
+		mmr_t	reserved_0                  : 41;
+	} sh_lb_error_overflow_s;
+} sh_lb_error_overflow_u_t;
+#else
+typedef union sh_lb_error_overflow_u {
+	mmr_t	sh_lb_error_overflow_regval;
+	struct {
+		mmr_t	reserved_0                  : 41;
+		mmr_t	rp_credit_overflow_ovrfl    : 1;
+		mmr_t	rq_credit_overflow_ovrfl    : 1;
+		mmr_t	unexp_valid_ovrfl           : 1;
+		mmr_t	rp_fifo_error_ovrfl         : 1;
+		mmr_t	rq_fifo_error_ovrfl         : 1;
+		mmr_t	gclk_drop_ovrfl             : 1;
+		mmr_t	vector_rp_route_error_ovrfl : 1;
+		mmr_t	vector_rq_route_error_ovrfl : 1;
+		mmr_t	pio_cb_err_ovrfl            : 1;
+		mmr_t	junk_bus_err_ovrfl          : 1;
+		mmr_t	ptc_1_timeout_ovrfl         : 1;
+		mmr_t	unexpected_linv_ovrfl       : 1;
+		mmr_t	linvv_overflow_ovrfl        : 1;
+		mmr_t	rq_time_out_ovrfl           : 1;
+		mmr_t	rq_bad_addr_ovrfl           : 1;
+		mmr_t	rp_bad_data_ovrfl           : 1;
+		mmr_t	rq_bad_data_ovrfl           : 1;
+		mmr_t	rp_long_ovrfl               : 1;
+		mmr_t	rq_long_ovrfl               : 1;
+		mmr_t	rp_short_ovrfl              : 1;
+		mmr_t	rq_short_ovrfl              : 1;
+		mmr_t	rp_bad_cmd_ovrfl            : 1;
+		mmr_t	rq_bad_cmd_ovrfl            : 1;
+	} sh_lb_error_overflow_s;
+} sh_lb_error_overflow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_LB_ERROR_SUMMARY"                    */
+/*                            LB Error Bits                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_error_summary_u {
+	mmr_t	sh_lb_error_summary_regval;
+	struct {
+		mmr_t	rq_bad_cmd            : 1;
+		mmr_t	rp_bad_cmd            : 1;
+		mmr_t	rq_short              : 1;
+		mmr_t	rp_short              : 1;
+		mmr_t	rq_long               : 1;
+		mmr_t	rp_long               : 1;
+		mmr_t	rq_bad_data           : 1;
+		mmr_t	rp_bad_data           : 1;
+		mmr_t	rq_bad_addr           : 1;
+		mmr_t	rq_time_out           : 1;
+		mmr_t	linvv_overflow        : 1;
+		mmr_t	unexpected_linv       : 1;
+		mmr_t	ptc_1_timeout         : 1;
+		mmr_t	junk_bus_err          : 1;
+		mmr_t	pio_cb_err            : 1;
+		mmr_t	vector_rq_route_error : 1;
+		mmr_t	vector_rp_route_error : 1;
+		mmr_t	gclk_drop             : 1;
+		mmr_t	rq_fifo_error         : 1;
+		mmr_t	rp_fifo_error         : 1;
+		mmr_t	unexp_valid           : 1;
+		mmr_t	rq_credit_overflow    : 1;
+		mmr_t	rp_credit_overflow    : 1;
+		mmr_t	reserved_0            : 41;
+	} sh_lb_error_summary_s;
+} sh_lb_error_summary_u_t;
+#else
+typedef union sh_lb_error_summary_u {
+	mmr_t	sh_lb_error_summary_regval;
+	struct {
+		mmr_t	reserved_0            : 41;
+		mmr_t	rp_credit_overflow    : 1;
+		mmr_t	rq_credit_overflow    : 1;
+		mmr_t	unexp_valid           : 1;
+		mmr_t	rp_fifo_error         : 1;
+		mmr_t	rq_fifo_error         : 1;
+		mmr_t	gclk_drop             : 1;
+		mmr_t	vector_rp_route_error : 1;
+		mmr_t	vector_rq_route_error : 1;
+		mmr_t	pio_cb_err            : 1;
+		mmr_t	junk_bus_err          : 1;
+		mmr_t	ptc_1_timeout         : 1;
+		mmr_t	unexpected_linv       : 1;
+		mmr_t	linvv_overflow        : 1;
+		mmr_t	rq_time_out           : 1;
+		mmr_t	rq_bad_addr           : 1;
+		mmr_t	rp_bad_data           : 1;
+		mmr_t	rq_bad_data           : 1;
+		mmr_t	rp_long               : 1;
+		mmr_t	rq_long               : 1;
+		mmr_t	rp_short              : 1;
+		mmr_t	rq_short              : 1;
+		mmr_t	rp_bad_cmd            : 1;
+		mmr_t	rq_bad_cmd            : 1;
+	} sh_lb_error_summary_s;
+} sh_lb_error_summary_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_LB_FIRST_ERROR"                     */
+/*                            LB First Error                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_first_error_u {
+	mmr_t	sh_lb_first_error_regval;
+	struct {
+		mmr_t	rq_bad_cmd            : 1;
+		mmr_t	rp_bad_cmd            : 1;
+		mmr_t	rq_short              : 1;
+		mmr_t	rp_short              : 1;
+		mmr_t	rq_long               : 1;
+		mmr_t	rp_long               : 1;
+		mmr_t	rq_bad_data           : 1;
+		mmr_t	rp_bad_data           : 1;
+		mmr_t	rq_bad_addr           : 1;
+		mmr_t	rq_time_out           : 1;
+		mmr_t	linvv_overflow        : 1;
+		mmr_t	unexpected_linv       : 1;
+		mmr_t	ptc_1_timeout         : 1;
+		mmr_t	junk_bus_err          : 1;
+		mmr_t	pio_cb_err            : 1;
+		mmr_t	vector_rq_route_error : 1;
+		mmr_t	vector_rp_route_error : 1;
+		mmr_t	gclk_drop             : 1;
+		mmr_t	rq_fifo_error         : 1;
+		mmr_t	rp_fifo_error         : 1;
+		mmr_t	unexp_valid           : 1;
+		mmr_t	rq_credit_overflow    : 1;
+		mmr_t	rp_credit_overflow    : 1;
+		mmr_t	reserved_0            : 41;
+	} sh_lb_first_error_s;
+} sh_lb_first_error_u_t;
+#else
+typedef union sh_lb_first_error_u {
+	mmr_t	sh_lb_first_error_regval;
+	struct {
+		mmr_t	reserved_0            : 41;
+		mmr_t	rp_credit_overflow    : 1;
+		mmr_t	rq_credit_overflow    : 1;
+		mmr_t	unexp_valid           : 1;
+		mmr_t	rp_fifo_error         : 1;
+		mmr_t	rq_fifo_error         : 1;
+		mmr_t	gclk_drop             : 1;
+		mmr_t	vector_rp_route_error : 1;
+		mmr_t	vector_rq_route_error : 1;
+		mmr_t	pio_cb_err            : 1;
+		mmr_t	junk_bus_err          : 1;
+		mmr_t	ptc_1_timeout         : 1;
+		mmr_t	unexpected_linv       : 1;
+		mmr_t	linvv_overflow        : 1;
+		mmr_t	rq_time_out           : 1;
+		mmr_t	rq_bad_addr           : 1;
+		mmr_t	rp_bad_data           : 1;
+		mmr_t	rq_bad_data           : 1;
+		mmr_t	rp_long               : 1;
+		mmr_t	rq_long               : 1;
+		mmr_t	rp_short              : 1;
+		mmr_t	rq_short              : 1;
+		mmr_t	rp_bad_cmd            : 1;
+		mmr_t	rq_bad_cmd            : 1;
+	} sh_lb_first_error_s;
+} sh_lb_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_LB_LAST_CREDIT"                     */
+/*                    Credit counter status register                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_last_credit_u {
+	mmr_t	sh_lb_last_credit_regval;
+	struct {
+		mmr_t	liq_rq_credit : 5;
+		mmr_t	reserved_0    : 1;
+		mmr_t	liq_rp_credit : 4;
+		mmr_t	reserved_1    : 2;
+		mmr_t	linvv_credit  : 6;
+		mmr_t	loq_rq_credit : 5;
+		mmr_t	loq_rp_credit : 5;
+		mmr_t	reserved_2    : 36;
+	} sh_lb_last_credit_s;
+} sh_lb_last_credit_u_t;
+#else
+typedef union sh_lb_last_credit_u {
+	mmr_t	sh_lb_last_credit_regval;
+	struct {
+		mmr_t	reserved_2    : 36;
+		mmr_t	loq_rp_credit : 5;
+		mmr_t	loq_rq_credit : 5;
+		mmr_t	linvv_credit  : 6;
+		mmr_t	reserved_1    : 2;
+		mmr_t	liq_rp_credit : 4;
+		mmr_t	reserved_0    : 1;
+		mmr_t	liq_rq_credit : 5;
+	} sh_lb_last_credit_s;
+} sh_lb_last_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_LB_NACK_STATUS"                     */
+/*                     Nack Counter Status Register                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_nack_status_u {
+	mmr_t	sh_lb_nack_status_regval;
+	struct {
+		mmr_t	pio_nack_a       : 12;
+		mmr_t	reserved_0       : 4;
+		mmr_t	pio_nack_b       : 12;
+		mmr_t	reserved_1       : 4;
+		mmr_t	junk_nack        : 16;
+		mmr_t	cb_timeout_count : 12;
+		mmr_t	cb_state         : 2;
+		mmr_t	reserved_2       : 2;
+	} sh_lb_nack_status_s;
+} sh_lb_nack_status_u_t;
+#else
+typedef union sh_lb_nack_status_u {
+	mmr_t	sh_lb_nack_status_regval;
+	struct {
+		mmr_t	reserved_2       : 2;
+		mmr_t	cb_state         : 2;
+		mmr_t	cb_timeout_count : 12;
+		mmr_t	junk_nack        : 16;
+		mmr_t	reserved_1       : 4;
+		mmr_t	pio_nack_b       : 12;
+		mmr_t	reserved_0       : 4;
+		mmr_t	pio_nack_a       : 12;
+	} sh_lb_nack_status_s;
+} sh_lb_nack_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_LB_TRIGGER_COMPARE"                   */
+/*                    LB Test-point Trigger Compare                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_trigger_compare_u {
+	mmr_t	sh_lb_trigger_compare_regval;
+	struct {
+		mmr_t	mask        : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_lb_trigger_compare_s;
+} sh_lb_trigger_compare_u_t;
+#else
+typedef union sh_lb_trigger_compare_u {
+	mmr_t	sh_lb_trigger_compare_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	mask        : 32;
+	} sh_lb_trigger_compare_s;
+} sh_lb_trigger_compare_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_LB_TRIGGER_DATA"                     */
+/*                  LB Test-point Trigger Compare Data                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_trigger_data_u {
+	mmr_t	sh_lb_trigger_data_regval;
+	struct {
+		mmr_t	compare_pattern : 32;
+		mmr_t	reserved_0      : 32;
+	} sh_lb_trigger_data_s;
+} sh_lb_trigger_data_u_t;
+#else
+typedef union sh_lb_trigger_data_u {
+	mmr_t	sh_lb_trigger_data_regval;
+	struct {
+		mmr_t	reserved_0      : 32;
+		mmr_t	compare_pattern : 32;
+	} sh_lb_trigger_data_s;
+} sh_lb_trigger_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PI_AEC_CONFIG"                      */
+/*              PI Adaptive Error Correction Configuration              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_aec_config_u {
+	mmr_t	sh_pi_aec_config_regval;
+	struct {
+		mmr_t	mode        : 3;
+		mmr_t	reserved_0  : 61;
+	} sh_pi_aec_config_s;
+} sh_pi_aec_config_u_t;
+#else
+typedef union sh_pi_aec_config_u {
+	mmr_t	sh_pi_aec_config_regval;
+	struct {
+		mmr_t	reserved_0  : 61;
+		mmr_t	mode        : 3;
+	} sh_pi_aec_config_s;
+} sh_pi_aec_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_AFI_ERROR_MASK"                    */
+/*                          PI AFI Error Mask                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_afi_error_mask_u {
+	mmr_t	sh_pi_afi_error_mask_regval;
+	struct {
+		mmr_t	reserved_0   : 21;
+		mmr_t	hung_bus     : 1;
+		mmr_t	rsp_parity   : 1;
+		mmr_t	ioq_overrun  : 1;
+		mmr_t	req_format   : 1;
+		mmr_t	addr_access  : 1;
+		mmr_t	req_parity   : 1;
+		mmr_t	addr_parity  : 1;
+		mmr_t	shub_fsb_dqe : 1;
+		mmr_t	shub_fsb_uce : 1;
+		mmr_t	shub_fsb_ce  : 1;
+		mmr_t	livelock     : 1;
+		mmr_t	bad_snoop    : 1;
+		mmr_t	fsb_tbl_miss : 1;
+		mmr_t	msg_len      : 1;
+		mmr_t	reserved_1   : 29;
+	} sh_pi_afi_error_mask_s;
+} sh_pi_afi_error_mask_u_t;
+#else
+typedef union sh_pi_afi_error_mask_u {
+	mmr_t	sh_pi_afi_error_mask_regval;
+	struct {
+		mmr_t	reserved_1   : 29;
+		mmr_t	msg_len      : 1;
+		mmr_t	fsb_tbl_miss : 1;
+		mmr_t	bad_snoop    : 1;
+		mmr_t	livelock     : 1;
+		mmr_t	shub_fsb_ce  : 1;
+		mmr_t	shub_fsb_uce : 1;
+		mmr_t	shub_fsb_dqe : 1;
+		mmr_t	addr_parity  : 1;
+		mmr_t	req_parity   : 1;
+		mmr_t	addr_access  : 1;
+		mmr_t	req_format   : 1;
+		mmr_t	ioq_overrun  : 1;
+		mmr_t	rsp_parity   : 1;
+		mmr_t	hung_bus     : 1;
+		mmr_t	reserved_0   : 21;
+	} sh_pi_afi_error_mask_s;
+} sh_pi_afi_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_AFI_TEST_POINT_COMPARE"                */
+/*                      PI AFI Test Point Compare                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_afi_test_point_compare_u {
+	mmr_t	sh_pi_afi_test_point_compare_regval;
+	struct {
+		mmr_t	compare_mask    : 32;
+		mmr_t	compare_pattern : 32;
+	} sh_pi_afi_test_point_compare_s;
+} sh_pi_afi_test_point_compare_u_t;
+#else
+typedef union sh_pi_afi_test_point_compare_u {
+	mmr_t	sh_pi_afi_test_point_compare_regval;
+	struct {
+		mmr_t	compare_pattern : 32;
+		mmr_t	compare_mask    : 32;
+	} sh_pi_afi_test_point_compare_s;
+} sh_pi_afi_test_point_compare_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_AFI_TEST_POINT_SELECT"                */
+/*                       PI AFI Test Point Select                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_afi_test_point_select_u {
+	mmr_t	sh_pi_afi_test_point_select_regval;
+	struct {
+		mmr_t	nibble0_chiplet_sel : 4;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble1_chiplet_sel : 4;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble2_chiplet_sel : 4;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble3_chiplet_sel : 4;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble4_chiplet_sel : 4;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble5_chiplet_sel : 4;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble6_chiplet_sel : 4;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble7_chiplet_sel : 4;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	trigger_enable      : 1;
+	} sh_pi_afi_test_point_select_s;
+} sh_pi_afi_test_point_select_u_t;
+#else
+typedef union sh_pi_afi_test_point_select_u {
+	mmr_t	sh_pi_afi_test_point_select_regval;
+	struct {
+		mmr_t	trigger_enable      : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	nibble7_chiplet_sel : 4;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	nibble6_chiplet_sel : 4;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	nibble5_chiplet_sel : 4;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	nibble4_chiplet_sel : 4;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	nibble3_chiplet_sel : 4;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	nibble2_chiplet_sel : 4;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	nibble1_chiplet_sel : 4;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	nibble0_chiplet_sel : 4;
+	} sh_pi_afi_test_point_select_s;
+} sh_pi_afi_test_point_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*            Register "SH_PI_AFI_TEST_POINT_TRIGGER_SELECT"            */
+/*                  PI CRBC Test Point Trigger Select                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_afi_test_point_trigger_select_u {
+	mmr_t	sh_pi_afi_test_point_trigger_select_regval;
+	struct {
+		mmr_t	trigger0_chiplet_sel : 4;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger1_chiplet_sel : 4;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger2_chiplet_sel : 4;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger3_chiplet_sel : 4;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger4_chiplet_sel : 4;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger5_chiplet_sel : 4;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger6_chiplet_sel : 4;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger7_chiplet_sel : 4;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_7           : 1;
+	} sh_pi_afi_test_point_trigger_select_s;
+} sh_pi_afi_test_point_trigger_select_u_t;
+#else
+typedef union sh_pi_afi_test_point_trigger_select_u {
+	mmr_t	sh_pi_afi_test_point_trigger_select_regval;
+	struct {
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	trigger7_chiplet_sel : 4;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	trigger6_chiplet_sel : 4;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	trigger5_chiplet_sel : 4;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	trigger4_chiplet_sel : 4;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	trigger3_chiplet_sel : 4;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	trigger2_chiplet_sel : 4;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	trigger1_chiplet_sel : 4;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	trigger0_chiplet_sel : 4;
+	} sh_pi_afi_test_point_trigger_select_s;
+} sh_pi_afi_test_point_trigger_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PI_AUTO_REPLY_ENABLE"                  */
+/*                         PI Auto Reply Enable                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_auto_reply_enable_u {
+	mmr_t	sh_pi_auto_reply_enable_regval;
+	struct {
+		mmr_t	auto_reply_enable : 1;
+		mmr_t	reserved_0        : 63;
+	} sh_pi_auto_reply_enable_s;
+} sh_pi_auto_reply_enable_u_t;
+#else
+typedef union sh_pi_auto_reply_enable_u {
+	mmr_t	sh_pi_auto_reply_enable_regval;
+	struct {
+		mmr_t	reserved_0        : 63;
+		mmr_t	auto_reply_enable : 1;
+	} sh_pi_auto_reply_enable_s;
+} sh_pi_auto_reply_enable_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PI_CAM_CONTROL"                     */
+/*                      CRB CAM MMR Access Control                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_cam_control_u {
+	mmr_t	sh_pi_cam_control_regval;
+	struct {
+		mmr_t	cam_indx          : 7;
+		mmr_t	reserved_0        : 1;
+		mmr_t	cam_write         : 1;
+		mmr_t	rrb_rd_xfer_clear : 1;
+		mmr_t	reserved_1        : 53;
+		mmr_t	start             : 1;
+	} sh_pi_cam_control_s;
+} sh_pi_cam_control_u_t;
+#else
+typedef union sh_pi_cam_control_u {
+	mmr_t	sh_pi_cam_control_regval;
+	struct {
+		mmr_t	start             : 1;
+		mmr_t	reserved_1        : 53;
+		mmr_t	rrb_rd_xfer_clear : 1;
+		mmr_t	cam_write         : 1;
+		mmr_t	reserved_0        : 1;
+		mmr_t	cam_indx          : 7;
+	} sh_pi_cam_control_s;
+} sh_pi_cam_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBC_TEST_POINT_COMPARE"               */
+/*                      PI CRBC Test Point Compare                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbc_test_point_compare_u {
+	mmr_t	sh_pi_crbc_test_point_compare_regval;
+	struct {
+		mmr_t	compare_mask    : 32;
+		mmr_t	compare_pattern : 32;
+	} sh_pi_crbc_test_point_compare_s;
+} sh_pi_crbc_test_point_compare_u_t;
+#else
+typedef union sh_pi_crbc_test_point_compare_u {
+	mmr_t	sh_pi_crbc_test_point_compare_regval;
+	struct {
+		mmr_t	compare_pattern : 32;
+		mmr_t	compare_mask    : 32;
+	} sh_pi_crbc_test_point_compare_s;
+} sh_pi_crbc_test_point_compare_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBC_TEST_POINT_SELECT"                */
+/*                      PI CRBC Test Point Select                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbc_test_point_select_u {
+	mmr_t	sh_pi_crbc_test_point_select_regval;
+	struct {
+		mmr_t	nibble0_chiplet_sel : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	trigger_enable      : 1;
+	} sh_pi_crbc_test_point_select_s;
+} sh_pi_crbc_test_point_select_u_t;
+#else
+typedef union sh_pi_crbc_test_point_select_u {
+	mmr_t	sh_pi_crbc_test_point_select_regval;
+	struct {
+		mmr_t	trigger_enable      : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_chiplet_sel : 3;
+	} sh_pi_crbc_test_point_select_s;
+} sh_pi_crbc_test_point_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*           Register "SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT"            */
+/*                  PI CRBC Test Point Trigger Select                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbc_test_point_trigger_select_u {
+	mmr_t	sh_pi_crbc_test_point_trigger_select_regval;
+	struct {
+		mmr_t	trigger0_chiplet_sel : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger1_chiplet_sel : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger2_chiplet_sel : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger3_chiplet_sel : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger4_chiplet_sel : 3;
+		mmr_t	reserved_8           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_9           : 1;
+		mmr_t	trigger5_chiplet_sel : 3;
+		mmr_t	reserved_10          : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_11          : 1;
+		mmr_t	trigger6_chiplet_sel : 3;
+		mmr_t	reserved_12          : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_13          : 1;
+		mmr_t	trigger7_chiplet_sel : 3;
+		mmr_t	reserved_14          : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_15          : 1;
+	} sh_pi_crbc_test_point_trigger_select_s;
+} sh_pi_crbc_test_point_trigger_select_u_t;
+#else
+typedef union sh_pi_crbc_test_point_trigger_select_u {
+	mmr_t	sh_pi_crbc_test_point_trigger_select_regval;
+	struct {
+		mmr_t	reserved_15          : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_14          : 1;
+		mmr_t	trigger7_chiplet_sel : 3;
+		mmr_t	reserved_13          : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_12          : 1;
+		mmr_t	trigger6_chiplet_sel : 3;
+		mmr_t	reserved_11          : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_10          : 1;
+		mmr_t	trigger5_chiplet_sel : 3;
+		mmr_t	reserved_9           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_8           : 1;
+		mmr_t	trigger4_chiplet_sel : 3;
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger3_chiplet_sel : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger2_chiplet_sel : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger1_chiplet_sel : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_chiplet_sel : 3;
+	} sh_pi_crbc_test_point_trigger_select_s;
+} sh_pi_crbc_test_point_trigger_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_CRBP_ERROR_MASK"                   */
+/*                          PI CRBP Error Mask                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_error_mask_u {
+	mmr_t	sh_pi_crbp_error_mask_regval;
+	struct {
+		mmr_t	fsb_proto_err   : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	reserved_0      : 43;
+	} sh_pi_crbp_error_mask_s;
+} sh_pi_crbp_error_mask_u_t;
+#else
+typedef union sh_pi_crbp_error_mask_u {
+	mmr_t	sh_pi_crbp_error_mask_regval;
+	struct {
+		mmr_t	reserved_0      : 43;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	fsb_proto_err   : 1;
+	} sh_pi_crbp_error_mask_s;
+} sh_pi_crbp_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_CRBP_FSB_PIPE_COMPARE"                */
+/*                        CRBP FSB Pipe Compare                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_fsb_pipe_compare_u {
+	mmr_t	sh_pi_crbp_fsb_pipe_compare_regval;
+	struct {
+		mmr_t	compare_address : 47;
+		mmr_t	compare_req     : 6;
+		mmr_t	reserved_0      : 11;
+	} sh_pi_crbp_fsb_pipe_compare_s;
+} sh_pi_crbp_fsb_pipe_compare_u_t;
+#else
+typedef union sh_pi_crbp_fsb_pipe_compare_u {
+	mmr_t	sh_pi_crbp_fsb_pipe_compare_regval;
+	struct {
+		mmr_t	reserved_0      : 11;
+		mmr_t	compare_req     : 6;
+		mmr_t	compare_address : 47;
+	} sh_pi_crbp_fsb_pipe_compare_s;
+} sh_pi_crbp_fsb_pipe_compare_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CRBP_FSB_PIPE_MASK"                  */
+/*                          CRBP Compare Mask                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_fsb_pipe_mask_u {
+	mmr_t	sh_pi_crbp_fsb_pipe_mask_regval;
+	struct {
+		mmr_t	compare_address_mask : 47;
+		mmr_t	compare_req_mask     : 6;
+		mmr_t	reserved_0           : 11;
+	} sh_pi_crbp_fsb_pipe_mask_s;
+} sh_pi_crbp_fsb_pipe_mask_u_t;
+#else
+typedef union sh_pi_crbp_fsb_pipe_mask_u {
+	mmr_t	sh_pi_crbp_fsb_pipe_mask_regval;
+	struct {
+		mmr_t	reserved_0           : 11;
+		mmr_t	compare_req_mask     : 6;
+		mmr_t	compare_address_mask : 47;
+	} sh_pi_crbp_fsb_pipe_mask_s;
+} sh_pi_crbp_fsb_pipe_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBP_TEST_POINT_COMPARE"               */
+/*                      PI CRBP Test Point Compare                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_test_point_compare_u {
+	mmr_t	sh_pi_crbp_test_point_compare_regval;
+	struct {
+		mmr_t	compare_mask    : 32;
+		mmr_t	compare_pattern : 32;
+	} sh_pi_crbp_test_point_compare_s;
+} sh_pi_crbp_test_point_compare_u_t;
+#else
+typedef union sh_pi_crbp_test_point_compare_u {
+	mmr_t	sh_pi_crbp_test_point_compare_regval;
+	struct {
+		mmr_t	compare_pattern : 32;
+		mmr_t	compare_mask    : 32;
+	} sh_pi_crbp_test_point_compare_s;
+} sh_pi_crbp_test_point_compare_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBP_TEST_POINT_SELECT"                */
+/*                      PI CRBP Test Point Select                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_test_point_select_u {
+	mmr_t	sh_pi_crbp_test_point_select_regval;
+	struct {
+		mmr_t	nibble0_chiplet_sel : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	trigger_enable      : 1;
+	} sh_pi_crbp_test_point_select_s;
+} sh_pi_crbp_test_point_select_u_t;
+#else
+typedef union sh_pi_crbp_test_point_select_u {
+	mmr_t	sh_pi_crbp_test_point_select_regval;
+	struct {
+		mmr_t	trigger_enable      : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_chiplet_sel : 3;
+	} sh_pi_crbp_test_point_select_s;
+} sh_pi_crbp_test_point_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*           Register "SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT"            */
+/*                  PI CRBP Test Point Trigger Select                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_test_point_trigger_select_u {
+	mmr_t	sh_pi_crbp_test_point_trigger_select_regval;
+	struct {
+		mmr_t	trigger0_chiplet_sel : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger1_chiplet_sel : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger2_chiplet_sel : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger3_chiplet_sel : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger4_chiplet_sel : 3;
+		mmr_t	reserved_8           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_9           : 1;
+		mmr_t	trigger5_chiplet_sel : 3;
+		mmr_t	reserved_10          : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_11          : 1;
+		mmr_t	trigger6_chiplet_sel : 3;
+		mmr_t	reserved_12          : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_13          : 1;
+		mmr_t	trigger7_chiplet_sel : 3;
+		mmr_t	reserved_14          : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_15          : 1;
+	} sh_pi_crbp_test_point_trigger_select_s;
+} sh_pi_crbp_test_point_trigger_select_u_t;
+#else
+typedef union sh_pi_crbp_test_point_trigger_select_u {
+	mmr_t	sh_pi_crbp_test_point_trigger_select_regval;
+	struct {
+		mmr_t	reserved_15          : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_14          : 1;
+		mmr_t	trigger7_chiplet_sel : 3;
+		mmr_t	reserved_13          : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_12          : 1;
+		mmr_t	trigger6_chiplet_sel : 3;
+		mmr_t	reserved_11          : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_10          : 1;
+		mmr_t	trigger5_chiplet_sel : 3;
+		mmr_t	reserved_9           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_8           : 1;
+		mmr_t	trigger4_chiplet_sel : 3;
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger3_chiplet_sel : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger2_chiplet_sel : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger1_chiplet_sel : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_chiplet_sel : 3;
+	} sh_pi_crbp_test_point_trigger_select_s;
+} sh_pi_crbp_test_point_trigger_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBP_XB_PIPE_COMPARE_0"                */
+/*                         CRBP XB Pipe Compare                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_xb_pipe_compare_0_u {
+	mmr_t	sh_pi_crbp_xb_pipe_compare_0_regval;
+	struct {
+		mmr_t	compare_address : 47;
+		mmr_t	compare_command : 8;
+		mmr_t	reserved_0      : 9;
+	} sh_pi_crbp_xb_pipe_compare_0_s;
+} sh_pi_crbp_xb_pipe_compare_0_u_t;
+#else
+typedef union sh_pi_crbp_xb_pipe_compare_0_u {
+	mmr_t	sh_pi_crbp_xb_pipe_compare_0_regval;
+	struct {
+		mmr_t	reserved_0      : 9;
+		mmr_t	compare_command : 8;
+		mmr_t	compare_address : 47;
+	} sh_pi_crbp_xb_pipe_compare_0_s;
+} sh_pi_crbp_xb_pipe_compare_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_CRBP_XB_PIPE_COMPARE_1"                */
+/*                         CRBP XB Pipe Compare                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_xb_pipe_compare_1_u {
+	mmr_t	sh_pi_crbp_xb_pipe_compare_1_regval;
+	struct {
+		mmr_t	compare_source       : 14;
+		mmr_t	reserved_0           : 2;
+		mmr_t	compare_supplemental : 14;
+		mmr_t	reserved_1           : 2;
+		mmr_t	compare_echo         : 9;
+		mmr_t	reserved_2           : 23;
+	} sh_pi_crbp_xb_pipe_compare_1_s;
+} sh_pi_crbp_xb_pipe_compare_1_u_t;
+#else
+typedef union sh_pi_crbp_xb_pipe_compare_1_u {
+	mmr_t	sh_pi_crbp_xb_pipe_compare_1_regval;
+	struct {
+		mmr_t	reserved_2           : 23;
+		mmr_t	compare_echo         : 9;
+		mmr_t	reserved_1           : 2;
+		mmr_t	compare_supplemental : 14;
+		mmr_t	reserved_0           : 2;
+		mmr_t	compare_source       : 14;
+	} sh_pi_crbp_xb_pipe_compare_1_s;
+} sh_pi_crbp_xb_pipe_compare_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CRBP_XB_PIPE_MASK_0"                 */
+/*                     CRBP Compare Mask Register 1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_xb_pipe_mask_0_u {
+	mmr_t	sh_pi_crbp_xb_pipe_mask_0_regval;
+	struct {
+		mmr_t	compare_address_mask : 47;
+		mmr_t	compare_command_mask : 8;
+		mmr_t	reserved_0           : 9;
+	} sh_pi_crbp_xb_pipe_mask_0_s;
+} sh_pi_crbp_xb_pipe_mask_0_u_t;
+#else
+typedef union sh_pi_crbp_xb_pipe_mask_0_u {
+	mmr_t	sh_pi_crbp_xb_pipe_mask_0_regval;
+	struct {
+		mmr_t	reserved_0           : 9;
+		mmr_t	compare_command_mask : 8;
+		mmr_t	compare_address_mask : 47;
+	} sh_pi_crbp_xb_pipe_mask_0_s;
+} sh_pi_crbp_xb_pipe_mask_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CRBP_XB_PIPE_MASK_1"                 */
+/*                 CRBP XB Pipe Compare Mask Register 1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_xb_pipe_mask_1_u {
+	mmr_t	sh_pi_crbp_xb_pipe_mask_1_regval;
+	struct {
+		mmr_t	compare_source_mask       : 14;
+		mmr_t	reserved_0                : 2;
+		mmr_t	compare_supplemental_mask : 14;
+		mmr_t	reserved_1                : 2;
+		mmr_t	compare_echo_mask         : 9;
+		mmr_t	reserved_2                : 23;
+	} sh_pi_crbp_xb_pipe_mask_1_s;
+} sh_pi_crbp_xb_pipe_mask_1_u_t;
+#else
+typedef union sh_pi_crbp_xb_pipe_mask_1_u {
+	mmr_t	sh_pi_crbp_xb_pipe_mask_1_regval;
+	struct {
+		mmr_t	reserved_2                : 23;
+		mmr_t	compare_echo_mask         : 9;
+		mmr_t	reserved_1                : 2;
+		mmr_t	compare_supplemental_mask : 14;
+		mmr_t	reserved_0                : 2;
+		mmr_t	compare_source_mask       : 14;
+	} sh_pi_crbp_xb_pipe_mask_1_s;
+} sh_pi_crbp_xb_pipe_mask_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PI_DPC_QUEUE_CONFIG"                   */
+/*                       DPC Queue Configuration                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_dpc_queue_config_u {
+	mmr_t	sh_pi_dpc_queue_config_regval;
+	struct {
+		mmr_t	dwcq_ae_level  : 5;
+		mmr_t	reserved_0     : 3;
+		mmr_t	dwcq_af_thresh : 5;
+		mmr_t	reserved_1     : 3;
+		mmr_t	fwcq_ae_level  : 5;
+		mmr_t	reserved_2     : 3;
+		mmr_t	fwcq_af_thresh : 5;
+		mmr_t	reserved_3     : 35;
+	} sh_pi_dpc_queue_config_s;
+} sh_pi_dpc_queue_config_u_t;
+#else
+typedef union sh_pi_dpc_queue_config_u {
+	mmr_t	sh_pi_dpc_queue_config_regval;
+	struct {
+		mmr_t	reserved_3     : 35;
+		mmr_t	fwcq_af_thresh : 5;
+		mmr_t	reserved_2     : 3;
+		mmr_t	fwcq_ae_level  : 5;
+		mmr_t	reserved_1     : 3;
+		mmr_t	dwcq_af_thresh : 5;
+		mmr_t	reserved_0     : 3;
+		mmr_t	dwcq_ae_level  : 5;
+	} sh_pi_dpc_queue_config_s;
+} sh_pi_dpc_queue_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PI_ERROR_MASK"                      */
+/*                            PI Error Mask                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_error_mask_u {
+	mmr_t	sh_pi_error_mask_regval;
+	struct {
+		mmr_t	fsb_proto_err   : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	hung_bus        : 1;
+		mmr_t	rsp_parity      : 1;
+		mmr_t	ioq_overrun     : 1;
+		mmr_t	req_format      : 1;
+		mmr_t	addr_access     : 1;
+		mmr_t	req_parity      : 1;
+		mmr_t	addr_parity     : 1;
+		mmr_t	shub_fsb_dqe    : 1;
+		mmr_t	shub_fsb_uce    : 1;
+		mmr_t	shub_fsb_ce     : 1;
+		mmr_t	livelock        : 1;
+		mmr_t	bad_snoop       : 1;
+		mmr_t	fsb_tbl_miss    : 1;
+		mmr_t	msg_length      : 1;
+		mmr_t	reserved_0      : 29;
+	} sh_pi_error_mask_s;
+} sh_pi_error_mask_u_t;
+#else
+typedef union sh_pi_error_mask_u {
+	mmr_t	sh_pi_error_mask_regval;
+	struct {
+		mmr_t	reserved_0      : 29;
+		mmr_t	msg_length      : 1;
+		mmr_t	fsb_tbl_miss    : 1;
+		mmr_t	bad_snoop       : 1;
+		mmr_t	livelock        : 1;
+		mmr_t	shub_fsb_ce     : 1;
+		mmr_t	shub_fsb_uce    : 1;
+		mmr_t	shub_fsb_dqe    : 1;
+		mmr_t	addr_parity     : 1;
+		mmr_t	req_parity      : 1;
+		mmr_t	addr_access     : 1;
+		mmr_t	req_format      : 1;
+		mmr_t	ioq_overrun     : 1;
+		mmr_t	rsp_parity      : 1;
+		mmr_t	hung_bus        : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	fsb_proto_err   : 1;
+	} sh_pi_error_mask_s;
+} sh_pi_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_EXPRESS_REPLY_CONFIG"                 */
+/*                    PI Express Reply Configuration                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_express_reply_config_u {
+	mmr_t	sh_pi_express_reply_config_regval;
+	struct {
+		mmr_t	mode        : 3;
+		mmr_t	reserved_0  : 61;
+	} sh_pi_express_reply_config_s;
+} sh_pi_express_reply_config_u_t;
+#else
+typedef union sh_pi_express_reply_config_u {
+	mmr_t	sh_pi_express_reply_config_regval;
+	struct {
+		mmr_t	reserved_0  : 61;
+		mmr_t	mode        : 3;
+	} sh_pi_express_reply_config_s;
+} sh_pi_express_reply_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PI_FSB_COMPARE_VALUE"                  */
+/*                          FSB Compare Value                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_fsb_compare_value_u {
+	mmr_t	sh_pi_fsb_compare_value_regval;
+	struct {
+		mmr_t	compare_value : 64;
+	} sh_pi_fsb_compare_value_s;
+} sh_pi_fsb_compare_value_u_t;
+#else
+typedef union sh_pi_fsb_compare_value_u {
+	mmr_t	sh_pi_fsb_compare_value_regval;
+	struct {
+		mmr_t	compare_value : 64;
+	} sh_pi_fsb_compare_value_s;
+} sh_pi_fsb_compare_value_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PI_FSB_COMPARE_MASK"                   */
+/*                           FSB Compare Mask                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_fsb_compare_mask_u {
+	mmr_t	sh_pi_fsb_compare_mask_regval;
+	struct {
+		mmr_t	mask_value  : 64;
+	} sh_pi_fsb_compare_mask_s;
+} sh_pi_fsb_compare_mask_u_t;
+#else
+typedef union sh_pi_fsb_compare_mask_u {
+	mmr_t	sh_pi_fsb_compare_mask_regval;
+	struct {
+		mmr_t	mask_value  : 64;
+	} sh_pi_fsb_compare_mask_s;
+} sh_pi_fsb_compare_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_FSB_ERROR_INJECTION"                 */
+/*                     Inject an Error onto the FSB                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_fsb_error_injection_u {
+	mmr_t	sh_pi_fsb_error_injection_regval;
+	struct {
+		mmr_t	rp_pe_to_fsb     : 1;
+		mmr_t	ap0_pe_to_fsb    : 1;
+		mmr_t	ap1_pe_to_fsb    : 1;
+		mmr_t	rsp_pe_to_fsb    : 1;
+		mmr_t	dw0_ce_to_fsb    : 1;
+		mmr_t	dw0_uce_to_fsb   : 1;
+		mmr_t	dw1_ce_to_fsb    : 1;
+		mmr_t	dw1_uce_to_fsb   : 1;
+		mmr_t	ip0_pe_to_fsb    : 1;
+		mmr_t	ip1_pe_to_fsb    : 1;
+		mmr_t	reserved_0       : 6;
+		mmr_t	rp_pe_from_fsb   : 1;
+		mmr_t	ap0_pe_from_fsb  : 1;
+		mmr_t	ap1_pe_from_fsb  : 1;
+		mmr_t	rsp_pe_from_fsb  : 1;
+		mmr_t	dw0_ce_from_fsb  : 1;
+		mmr_t	dw0_uce_from_fsb : 1;
+		mmr_t	dw1_ce_from_fsb  : 1;
+		mmr_t	dw1_uce_from_fsb : 1;
+		mmr_t	dw2_ce_from_fsb  : 1;
+		mmr_t	dw2_uce_from_fsb : 1;
+		mmr_t	dw3_ce_from_fsb  : 1;
+		mmr_t	dw3_uce_from_fsb : 1;
+		mmr_t	reserved_1       : 4;
+		mmr_t	ioq_overrun      : 1;
+		mmr_t	livelock         : 1;
+		mmr_t	bus_hang         : 1;
+		mmr_t	reserved_2       : 29;
+	} sh_pi_fsb_error_injection_s;
+} sh_pi_fsb_error_injection_u_t;
+#else
+typedef union sh_pi_fsb_error_injection_u {
+	mmr_t	sh_pi_fsb_error_injection_regval;
+	struct {
+		mmr_t	reserved_2       : 29;
+		mmr_t	bus_hang         : 1;
+		mmr_t	livelock         : 1;
+		mmr_t	ioq_overrun      : 1;
+		mmr_t	reserved_1       : 4;
+		mmr_t	dw3_uce_from_fsb : 1;
+		mmr_t	dw3_ce_from_fsb  : 1;
+		mmr_t	dw2_uce_from_fsb : 1;
+		mmr_t	dw2_ce_from_fsb  : 1;
+		mmr_t	dw1_uce_from_fsb : 1;
+		mmr_t	dw1_ce_from_fsb  : 1;
+		mmr_t	dw0_uce_from_fsb : 1;
+		mmr_t	dw0_ce_from_fsb  : 1;
+		mmr_t	rsp_pe_from_fsb  : 1;
+		mmr_t	ap1_pe_from_fsb  : 1;
+		mmr_t	ap0_pe_from_fsb  : 1;
+		mmr_t	rp_pe_from_fsb   : 1;
+		mmr_t	reserved_0       : 6;
+		mmr_t	ip1_pe_to_fsb    : 1;
+		mmr_t	ip0_pe_to_fsb    : 1;
+		mmr_t	dw1_uce_to_fsb   : 1;
+		mmr_t	dw1_ce_to_fsb    : 1;
+		mmr_t	dw0_uce_to_fsb   : 1;
+		mmr_t	dw0_ce_to_fsb    : 1;
+		mmr_t	rsp_pe_to_fsb    : 1;
+		mmr_t	ap1_pe_to_fsb    : 1;
+		mmr_t	ap0_pe_to_fsb    : 1;
+		mmr_t	rp_pe_to_fsb     : 1;
+	} sh_pi_fsb_error_injection_s;
+} sh_pi_fsb_error_injection_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_MD2PI_REPLY_VC_CONFIG"                */
+/*             MD-to-PI Reply Virtual Channel Configuration             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_md2pi_reply_vc_config_u {
+	mmr_t	sh_pi_md2pi_reply_vc_config_regval;
+	struct {
+		mmr_t	hdr_depth             : 4;
+		mmr_t	data_depth            : 4;
+		mmr_t	max_credits           : 6;
+		mmr_t	reserved_0            : 48;
+		mmr_t	force_credit          : 1;
+		mmr_t	capture_credit_status : 1;
+	} sh_pi_md2pi_reply_vc_config_s;
+} sh_pi_md2pi_reply_vc_config_u_t;
+#else
+typedef union sh_pi_md2pi_reply_vc_config_u {
+	mmr_t	sh_pi_md2pi_reply_vc_config_regval;
+	struct {
+		mmr_t	capture_credit_status : 1;
+		mmr_t	force_credit          : 1;
+		mmr_t	reserved_0            : 48;
+		mmr_t	max_credits           : 6;
+		mmr_t	data_depth            : 4;
+		mmr_t	hdr_depth             : 4;
+	} sh_pi_md2pi_reply_vc_config_s;
+} sh_pi_md2pi_reply_vc_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_MD2PI_REQUEST_VC_CONFIG"               */
+/*            MD-to-PI Request Virtual Channel Configuration            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_md2pi_request_vc_config_u {
+	mmr_t	sh_pi_md2pi_request_vc_config_regval;
+	struct {
+		mmr_t	hdr_depth             : 4;
+		mmr_t	data_depth            : 4;
+		mmr_t	max_credits           : 6;
+		mmr_t	reserved_0            : 48;
+		mmr_t	force_credit          : 1;
+		mmr_t	capture_credit_status : 1;
+	} sh_pi_md2pi_request_vc_config_s;
+} sh_pi_md2pi_request_vc_config_u_t;
+#else
+typedef union sh_pi_md2pi_request_vc_config_u {
+	mmr_t	sh_pi_md2pi_request_vc_config_regval;
+	struct {
+		mmr_t	capture_credit_status : 1;
+		mmr_t	force_credit          : 1;
+		mmr_t	reserved_0            : 48;
+		mmr_t	max_credits           : 6;
+		mmr_t	data_depth            : 4;
+		mmr_t	hdr_depth             : 4;
+	} sh_pi_md2pi_request_vc_config_s;
+} sh_pi_md2pi_request_vc_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_QUEUE_ERROR_INJECTION"                */
+/*                       PI Queue Error Injection                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_queue_error_injection_u {
+	mmr_t	sh_pi_queue_error_injection_regval;
+	struct {
+		mmr_t	dat_dfr_q      : 1;
+		mmr_t	dxb_wtl_cmnd_q : 1;
+		mmr_t	fsb_wtl_cmnd_q : 1;
+		mmr_t	mdpi_rpy_bfr   : 1;
+		mmr_t	ptc_intr       : 1;
+		mmr_t	rxl_kill_q     : 1;
+		mmr_t	rxl_rdy_q      : 1;
+		mmr_t	xnpi_rpy_bfr   : 1;
+		mmr_t	reserved_0     : 56;
+	} sh_pi_queue_error_injection_s;
+} sh_pi_queue_error_injection_u_t;
+#else
+typedef union sh_pi_queue_error_injection_u {
+	mmr_t	sh_pi_queue_error_injection_regval;
+	struct {
+		mmr_t	reserved_0     : 56;
+		mmr_t	xnpi_rpy_bfr   : 1;
+		mmr_t	rxl_rdy_q      : 1;
+		mmr_t	rxl_kill_q     : 1;
+		mmr_t	ptc_intr       : 1;
+		mmr_t	mdpi_rpy_bfr   : 1;
+		mmr_t	fsb_wtl_cmnd_q : 1;
+		mmr_t	dxb_wtl_cmnd_q : 1;
+		mmr_t	dat_dfr_q      : 1;
+	} sh_pi_queue_error_injection_s;
+} sh_pi_queue_error_injection_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_TEST_POINT_COMPARE"                  */
+/*                        PI Test Point Compare                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_test_point_compare_u {
+	mmr_t	sh_pi_test_point_compare_regval;
+	struct {
+		mmr_t	compare_mask    : 32;
+		mmr_t	compare_pattern : 32;
+	} sh_pi_test_point_compare_s;
+} sh_pi_test_point_compare_u_t;
+#else
+typedef union sh_pi_test_point_compare_u {
+	mmr_t	sh_pi_test_point_compare_regval;
+	struct {
+		mmr_t	compare_pattern : 32;
+		mmr_t	compare_mask    : 32;
+	} sh_pi_test_point_compare_s;
+} sh_pi_test_point_compare_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PI_TEST_POINT_SELECT"                  */
+/*                         PI Test Point Select                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_test_point_select_u {
+	mmr_t	sh_pi_test_point_select_regval;
+	struct {
+		mmr_t	nibble0_chiplet_sel : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	trigger_enable      : 1;
+	} sh_pi_test_point_select_s;
+} sh_pi_test_point_select_u_t;
+#else
+typedef union sh_pi_test_point_select_u {
+	mmr_t	sh_pi_test_point_select_regval;
+	struct {
+		mmr_t	trigger_enable      : 1;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	nibble0_chiplet_sel : 3;
+	} sh_pi_test_point_select_s;
+} sh_pi_test_point_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_PI_TEST_POINT_TRIGGER_SELECT"              */
+/*                     PI Test Point Trigger Select                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_test_point_trigger_select_u {
+	mmr_t	sh_pi_test_point_trigger_select_regval;
+	struct {
+		mmr_t	trigger0_chiplet_sel : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger1_chiplet_sel : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger2_chiplet_sel : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger3_chiplet_sel : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger4_chiplet_sel : 3;
+		mmr_t	reserved_8           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_9           : 1;
+		mmr_t	trigger5_chiplet_sel : 3;
+		mmr_t	reserved_10          : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_11          : 1;
+		mmr_t	trigger6_chiplet_sel : 3;
+		mmr_t	reserved_12          : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_13          : 1;
+		mmr_t	trigger7_chiplet_sel : 3;
+		mmr_t	reserved_14          : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_15          : 1;
+	} sh_pi_test_point_trigger_select_s;
+} sh_pi_test_point_trigger_select_u_t;
+#else
+typedef union sh_pi_test_point_trigger_select_u {
+	mmr_t	sh_pi_test_point_trigger_select_regval;
+	struct {
+		mmr_t	reserved_15          : 1;
+		mmr_t	trigger7_nibble_sel  : 3;
+		mmr_t	reserved_14          : 1;
+		mmr_t	trigger7_chiplet_sel : 3;
+		mmr_t	reserved_13          : 1;
+		mmr_t	trigger6_nibble_sel  : 3;
+		mmr_t	reserved_12          : 1;
+		mmr_t	trigger6_chiplet_sel : 3;
+		mmr_t	reserved_11          : 1;
+		mmr_t	trigger5_nibble_sel  : 3;
+		mmr_t	reserved_10          : 1;
+		mmr_t	trigger5_chiplet_sel : 3;
+		mmr_t	reserved_9           : 1;
+		mmr_t	trigger4_nibble_sel  : 3;
+		mmr_t	reserved_8           : 1;
+		mmr_t	trigger4_chiplet_sel : 3;
+		mmr_t	reserved_7           : 1;
+		mmr_t	trigger3_nibble_sel  : 3;
+		mmr_t	reserved_6           : 1;
+		mmr_t	trigger3_chiplet_sel : 3;
+		mmr_t	reserved_5           : 1;
+		mmr_t	trigger2_nibble_sel  : 3;
+		mmr_t	reserved_4           : 1;
+		mmr_t	trigger2_chiplet_sel : 3;
+		mmr_t	reserved_3           : 1;
+		mmr_t	trigger1_nibble_sel  : 3;
+		mmr_t	reserved_2           : 1;
+		mmr_t	trigger1_chiplet_sel : 3;
+		mmr_t	reserved_1           : 1;
+		mmr_t	trigger0_nibble_sel  : 3;
+		mmr_t	reserved_0           : 1;
+		mmr_t	trigger0_chiplet_sel : 3;
+	} sh_pi_test_point_trigger_select_s;
+} sh_pi_test_point_trigger_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_XN2PI_REPLY_VC_CONFIG"                */
+/*             XN-to-PI Reply Virtual Channel Configuration             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_xn2pi_reply_vc_config_u {
+	mmr_t	sh_pi_xn2pi_reply_vc_config_regval;
+	struct {
+		mmr_t	hdr_depth             : 4;
+		mmr_t	data_depth            : 4;
+		mmr_t	max_credits           : 6;
+		mmr_t	reserved_0            : 48;
+		mmr_t	force_credit          : 1;
+		mmr_t	capture_credit_status : 1;
+	} sh_pi_xn2pi_reply_vc_config_s;
+} sh_pi_xn2pi_reply_vc_config_u_t;
+#else
+typedef union sh_pi_xn2pi_reply_vc_config_u {
+	mmr_t	sh_pi_xn2pi_reply_vc_config_regval;
+	struct {
+		mmr_t	capture_credit_status : 1;
+		mmr_t	force_credit          : 1;
+		mmr_t	reserved_0            : 48;
+		mmr_t	max_credits           : 6;
+		mmr_t	data_depth            : 4;
+		mmr_t	hdr_depth             : 4;
+	} sh_pi_xn2pi_reply_vc_config_s;
+} sh_pi_xn2pi_reply_vc_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_XN2PI_REQUEST_VC_CONFIG"               */
+/*            XN-to-PI Request Virtual Channel Configuration            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_xn2pi_request_vc_config_u {
+	mmr_t	sh_pi_xn2pi_request_vc_config_regval;
+	struct {
+		mmr_t	hdr_depth             : 4;
+		mmr_t	data_depth            : 4;
+		mmr_t	max_credits           : 6;
+		mmr_t	reserved_0            : 48;
+		mmr_t	force_credit          : 1;
+		mmr_t	capture_credit_status : 1;
+	} sh_pi_xn2pi_request_vc_config_s;
+} sh_pi_xn2pi_request_vc_config_u_t;
+#else
+typedef union sh_pi_xn2pi_request_vc_config_u {
+	mmr_t	sh_pi_xn2pi_request_vc_config_regval;
+	struct {
+		mmr_t	capture_credit_status : 1;
+		mmr_t	force_credit          : 1;
+		mmr_t	reserved_0            : 48;
+		mmr_t	max_credits           : 6;
+		mmr_t	data_depth            : 4;
+		mmr_t	hdr_depth             : 4;
+	} sh_pi_xn2pi_request_vc_config_s;
+} sh_pi_xn2pi_request_vc_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PI_AEC_STATUS"                      */
+/*                 PI Adaptive Error Correction Status                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_aec_status_u {
+	mmr_t	sh_pi_aec_status_regval;
+	struct {
+		mmr_t	state       : 3;
+		mmr_t	reserved_0  : 61;
+	} sh_pi_aec_status_s;
+} sh_pi_aec_status_u_t;
+#else
+typedef union sh_pi_aec_status_u {
+	mmr_t	sh_pi_aec_status_regval;
+	struct {
+		mmr_t	reserved_0  : 61;
+		mmr_t	state       : 3;
+	} sh_pi_aec_status_s;
+} sh_pi_aec_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_AFI_FIRST_ERROR"                   */
+/*                          PI AFI First Error                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_afi_first_error_u {
+	mmr_t	sh_pi_afi_first_error_regval;
+	struct {
+		mmr_t	reserved_0   : 7;
+		mmr_t	fsb_shub_uce : 1;
+		mmr_t	fsb_shub_ce  : 1;
+		mmr_t	reserved_1   : 12;
+		mmr_t	hung_bus     : 1;
+		mmr_t	rsp_parity   : 1;
+		mmr_t	ioq_overrun  : 1;
+		mmr_t	req_format   : 1;
+		mmr_t	addr_access  : 1;
+		mmr_t	req_parity   : 1;
+		mmr_t	addr_parity  : 1;
+		mmr_t	shub_fsb_dqe : 1;
+		mmr_t	shub_fsb_uce : 1;
+		mmr_t	shub_fsb_ce  : 1;
+		mmr_t	livelock     : 1;
+		mmr_t	bad_snoop    : 1;
+		mmr_t	fsb_tbl_miss : 1;
+		mmr_t	msg_len      : 1;
+		mmr_t	reserved_2   : 29;
+	} sh_pi_afi_first_error_s;
+} sh_pi_afi_first_error_u_t;
+#else
+typedef union sh_pi_afi_first_error_u {
+	mmr_t	sh_pi_afi_first_error_regval;
+	struct {
+		mmr_t	reserved_2   : 29;
+		mmr_t	msg_len      : 1;
+		mmr_t	fsb_tbl_miss : 1;
+		mmr_t	bad_snoop    : 1;
+		mmr_t	livelock     : 1;
+		mmr_t	shub_fsb_ce  : 1;
+		mmr_t	shub_fsb_uce : 1;
+		mmr_t	shub_fsb_dqe : 1;
+		mmr_t	addr_parity  : 1;
+		mmr_t	req_parity   : 1;
+		mmr_t	addr_access  : 1;
+		mmr_t	req_format   : 1;
+		mmr_t	ioq_overrun  : 1;
+		mmr_t	rsp_parity   : 1;
+		mmr_t	hung_bus     : 1;
+		mmr_t	reserved_1   : 12;
+		mmr_t	fsb_shub_ce  : 1;
+		mmr_t	fsb_shub_uce : 1;
+		mmr_t	reserved_0   : 7;
+	} sh_pi_afi_first_error_s;
+} sh_pi_afi_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_CAM_ADDRESS_READ_DATA"                */
+/*                    CRB CAM MMR Address Read Data                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_cam_address_read_data_u {
+	mmr_t	sh_pi_cam_address_read_data_regval;
+	struct {
+		mmr_t	cam_addr     : 48;
+		mmr_t	reserved_0   : 15;
+		mmr_t	cam_addr_val : 1;
+	} sh_pi_cam_address_read_data_s;
+} sh_pi_cam_address_read_data_u_t;
+#else
+typedef union sh_pi_cam_address_read_data_u {
+	mmr_t	sh_pi_cam_address_read_data_regval;
+	struct {
+		mmr_t	cam_addr_val : 1;
+		mmr_t	reserved_0   : 15;
+		mmr_t	cam_addr     : 48;
+	} sh_pi_cam_address_read_data_s;
+} sh_pi_cam_address_read_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CAM_LPRA_READ_DATA"                  */
+/*                      CRB CAM MMR LPRA Read Data                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_cam_lpra_read_data_u {
+	mmr_t	sh_pi_cam_lpra_read_data_regval;
+	struct {
+		mmr_t	cam_lpra    : 64;
+	} sh_pi_cam_lpra_read_data_s;
+} sh_pi_cam_lpra_read_data_u_t;
+#else
+typedef union sh_pi_cam_lpra_read_data_u {
+	mmr_t	sh_pi_cam_lpra_read_data_regval;
+	struct {
+		mmr_t	cam_lpra    : 64;
+	} sh_pi_cam_lpra_read_data_s;
+} sh_pi_cam_lpra_read_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CAM_STATE_READ_DATA"                 */
+/*                     CRB CAM MMR State Read Data                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_cam_state_read_data_u {
+	mmr_t	sh_pi_cam_state_read_data_regval;
+	struct {
+		mmr_t	cam_state         : 4;
+		mmr_t	cam_to            : 1;
+		mmr_t	cam_state_rd_pend : 1;
+		mmr_t	reserved_0        : 26;
+		mmr_t	cam_lpra          : 18;
+		mmr_t	reserved_1        : 13;
+		mmr_t	cam_rd_data_val   : 1;
+	} sh_pi_cam_state_read_data_s;
+} sh_pi_cam_state_read_data_u_t;
+#else
+typedef union sh_pi_cam_state_read_data_u {
+	mmr_t	sh_pi_cam_state_read_data_regval;
+	struct {
+		mmr_t	cam_rd_data_val   : 1;
+		mmr_t	reserved_1        : 13;
+		mmr_t	cam_lpra          : 18;
+		mmr_t	reserved_0        : 26;
+		mmr_t	cam_state_rd_pend : 1;
+		mmr_t	cam_to            : 1;
+		mmr_t	cam_state         : 4;
+	} sh_pi_cam_state_read_data_s;
+} sh_pi_cam_state_read_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CORRECTED_DETAIL_1"                  */
+/*                      PI Corrected Error Detail                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_corrected_detail_1_u {
+	mmr_t	sh_pi_corrected_detail_1_regval;
+	struct {
+		mmr_t	address     : 48;
+		mmr_t	syndrome    : 8;
+		mmr_t	dep         : 8;
+	} sh_pi_corrected_detail_1_s;
+} sh_pi_corrected_detail_1_u_t;
+#else
+typedef union sh_pi_corrected_detail_1_u {
+	mmr_t	sh_pi_corrected_detail_1_regval;
+	struct {
+		mmr_t	dep         : 8;
+		mmr_t	syndrome    : 8;
+		mmr_t	address     : 48;
+	} sh_pi_corrected_detail_1_s;
+} sh_pi_corrected_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CORRECTED_DETAIL_2"                  */
+/*                     PI Corrected Error Detail 2                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_corrected_detail_2_u {
+	mmr_t	sh_pi_corrected_detail_2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_pi_corrected_detail_2_s;
+} sh_pi_corrected_detail_2_u_t;
+#else
+typedef union sh_pi_corrected_detail_2_u {
+	mmr_t	sh_pi_corrected_detail_2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_pi_corrected_detail_2_s;
+} sh_pi_corrected_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CORRECTED_DETAIL_3"                  */
+/*                     PI Corrected Error Detail 3                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_corrected_detail_3_u {
+	mmr_t	sh_pi_corrected_detail_3_regval;
+	struct {
+		mmr_t	address     : 48;
+		mmr_t	syndrome    : 8;
+		mmr_t	dep         : 8;
+	} sh_pi_corrected_detail_3_s;
+} sh_pi_corrected_detail_3_u_t;
+#else
+typedef union sh_pi_corrected_detail_3_u {
+	mmr_t	sh_pi_corrected_detail_3_regval;
+	struct {
+		mmr_t	dep         : 8;
+		mmr_t	syndrome    : 8;
+		mmr_t	address     : 48;
+	} sh_pi_corrected_detail_3_s;
+} sh_pi_corrected_detail_3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_PI_CORRECTED_DETAIL_4"                  */
+/*                     PI Corrected Error Detail 4                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_corrected_detail_4_u {
+	mmr_t	sh_pi_corrected_detail_4_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_pi_corrected_detail_4_s;
+} sh_pi_corrected_detail_4_u_t;
+#else
+typedef union sh_pi_corrected_detail_4_u {
+	mmr_t	sh_pi_corrected_detail_4_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_pi_corrected_detail_4_s;
+} sh_pi_corrected_detail_4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PI_CRBP_FIRST_ERROR"                   */
+/*                         PI CRBP First Error                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_crbp_first_error_u {
+	mmr_t	sh_pi_crbp_first_error_regval;
+	struct {
+		mmr_t	fsb_proto_err   : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	reserved_0      : 43;
+	} sh_pi_crbp_first_error_s;
+} sh_pi_crbp_first_error_u_t;
+#else
+typedef union sh_pi_crbp_first_error_u {
+	mmr_t	sh_pi_crbp_first_error_regval;
+	struct {
+		mmr_t	reserved_0      : 43;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	fsb_proto_err   : 1;
+	} sh_pi_crbp_first_error_s;
+} sh_pi_crbp_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_ERROR_DETAIL_1"                    */
+/*                          PI Error Detail 1                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_error_detail_1_u {
+	mmr_t	sh_pi_error_detail_1_regval;
+	struct {
+		mmr_t	status      : 64;
+	} sh_pi_error_detail_1_s;
+} sh_pi_error_detail_1_u_t;
+#else
+typedef union sh_pi_error_detail_1_u {
+	mmr_t	sh_pi_error_detail_1_regval;
+	struct {
+		mmr_t	status      : 64;
+	} sh_pi_error_detail_1_s;
+} sh_pi_error_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_ERROR_DETAIL_2"                    */
+/*                          PI Error Detail 2                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_error_detail_2_u {
+	mmr_t	sh_pi_error_detail_2_regval;
+	struct {
+		mmr_t	status      : 64;
+	} sh_pi_error_detail_2_s;
+} sh_pi_error_detail_2_u_t;
+#else
+typedef union sh_pi_error_detail_2_u {
+	mmr_t	sh_pi_error_detail_2_regval;
+	struct {
+		mmr_t	status      : 64;
+	} sh_pi_error_detail_2_s;
+} sh_pi_error_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_ERROR_OVERFLOW"                    */
+/*                          PI Error Overflow                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_error_overflow_u {
+	mmr_t	sh_pi_error_overflow_regval;
+	struct {
+		mmr_t	fsb_proto_err   : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	hung_bus        : 1;
+		mmr_t	rsp_parity      : 1;
+		mmr_t	ioq_overrun     : 1;
+		mmr_t	req_format      : 1;
+		mmr_t	addr_access     : 1;
+		mmr_t	req_parity      : 1;
+		mmr_t	addr_parity     : 1;
+		mmr_t	shub_fsb_dqe    : 1;
+		mmr_t	shub_fsb_uce    : 1;
+		mmr_t	shub_fsb_ce     : 1;
+		mmr_t	livelock        : 1;
+		mmr_t	bad_snoop       : 1;
+		mmr_t	fsb_tbl_miss    : 1;
+		mmr_t	msg_length      : 1;
+		mmr_t	reserved_0      : 29;
+	} sh_pi_error_overflow_s;
+} sh_pi_error_overflow_u_t;
+#else
+typedef union sh_pi_error_overflow_u {
+	mmr_t	sh_pi_error_overflow_regval;
+	struct {
+		mmr_t	reserved_0      : 29;
+		mmr_t	msg_length      : 1;
+		mmr_t	fsb_tbl_miss    : 1;
+		mmr_t	bad_snoop       : 1;
+		mmr_t	livelock        : 1;
+		mmr_t	shub_fsb_ce     : 1;
+		mmr_t	shub_fsb_uce    : 1;
+		mmr_t	shub_fsb_dqe    : 1;
+		mmr_t	addr_parity     : 1;
+		mmr_t	req_parity      : 1;
+		mmr_t	addr_access     : 1;
+		mmr_t	req_format      : 1;
+		mmr_t	ioq_overrun     : 1;
+		mmr_t	rsp_parity      : 1;
+		mmr_t	hung_bus        : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	fsb_proto_err   : 1;
+	} sh_pi_error_overflow_s;
+} sh_pi_error_overflow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_PI_ERROR_SUMMARY"                    */
+/*                           PI Error Summary                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_error_summary_u {
+	mmr_t	sh_pi_error_summary_regval;
+	struct {
+		mmr_t	fsb_proto_err   : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	hung_bus        : 1;
+		mmr_t	rsp_parity      : 1;
+		mmr_t	ioq_overrun     : 1;
+		mmr_t	req_format      : 1;
+		mmr_t	addr_access     : 1;
+		mmr_t	req_parity      : 1;
+		mmr_t	addr_parity     : 1;
+		mmr_t	shub_fsb_dqe    : 1;
+		mmr_t	shub_fsb_uce    : 1;
+		mmr_t	shub_fsb_ce     : 1;
+		mmr_t	livelock        : 1;
+		mmr_t	bad_snoop       : 1;
+		mmr_t	fsb_tbl_miss    : 1;
+		mmr_t	msg_length      : 1;
+		mmr_t	reserved_0      : 29;
+	} sh_pi_error_summary_s;
+} sh_pi_error_summary_u_t;
+#else
+typedef union sh_pi_error_summary_u {
+	mmr_t	sh_pi_error_summary_regval;
+	struct {
+		mmr_t	reserved_0      : 29;
+		mmr_t	msg_length      : 1;
+		mmr_t	fsb_tbl_miss    : 1;
+		mmr_t	bad_snoop       : 1;
+		mmr_t	livelock        : 1;
+		mmr_t	shub_fsb_ce     : 1;
+		mmr_t	shub_fsb_uce    : 1;
+		mmr_t	shub_fsb_dqe    : 1;
+		mmr_t	addr_parity     : 1;
+		mmr_t	req_parity      : 1;
+		mmr_t	addr_access     : 1;
+		mmr_t	req_format      : 1;
+		mmr_t	ioq_overrun     : 1;
+		mmr_t	rsp_parity      : 1;
+		mmr_t	hung_bus        : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	fsb_proto_err   : 1;
+	} sh_pi_error_summary_s;
+} sh_pi_error_summary_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_EXPRESS_REPLY_STATUS"                 */
+/*                       PI Express Reply Status                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_express_reply_status_u {
+	mmr_t	sh_pi_express_reply_status_regval;
+	struct {
+		mmr_t	state       : 3;
+		mmr_t	reserved_0  : 61;
+	} sh_pi_express_reply_status_s;
+} sh_pi_express_reply_status_u_t;
+#else
+typedef union sh_pi_express_reply_status_u {
+	mmr_t	sh_pi_express_reply_status_regval;
+	struct {
+		mmr_t	reserved_0  : 61;
+		mmr_t	state       : 3;
+	} sh_pi_express_reply_status_s;
+} sh_pi_express_reply_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PI_FIRST_ERROR"                     */
+/*                            PI First Error                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_first_error_u {
+	mmr_t	sh_pi_first_error_regval;
+	struct {
+		mmr_t	fsb_proto_err   : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	hung_bus        : 1;
+		mmr_t	rsp_parity      : 1;
+		mmr_t	ioq_overrun     : 1;
+		mmr_t	req_format      : 1;
+		mmr_t	addr_access     : 1;
+		mmr_t	req_parity      : 1;
+		mmr_t	addr_parity     : 1;
+		mmr_t	shub_fsb_dqe    : 1;
+		mmr_t	shub_fsb_uce    : 1;
+		mmr_t	shub_fsb_ce     : 1;
+		mmr_t	livelock        : 1;
+		mmr_t	bad_snoop       : 1;
+		mmr_t	fsb_tbl_miss    : 1;
+		mmr_t	msg_length      : 1;
+		mmr_t	reserved_0      : 29;
+	} sh_pi_first_error_s;
+} sh_pi_first_error_u_t;
+#else
+typedef union sh_pi_first_error_u {
+	mmr_t	sh_pi_first_error_regval;
+	struct {
+		mmr_t	reserved_0      : 29;
+		mmr_t	msg_length      : 1;
+		mmr_t	fsb_tbl_miss    : 1;
+		mmr_t	bad_snoop       : 1;
+		mmr_t	livelock        : 1;
+		mmr_t	shub_fsb_ce     : 1;
+		mmr_t	shub_fsb_uce    : 1;
+		mmr_t	shub_fsb_dqe    : 1;
+		mmr_t	addr_parity     : 1;
+		mmr_t	req_parity      : 1;
+		mmr_t	addr_access     : 1;
+		mmr_t	req_format      : 1;
+		mmr_t	ioq_overrun     : 1;
+		mmr_t	rsp_parity      : 1;
+		mmr_t	hung_bus        : 1;
+		mmr_t	xn_rp_crd_oflow : 1;
+		mmr_t	xn_rq_crd_oflow : 1;
+		mmr_t	md_rp_crd_oflow : 1;
+		mmr_t	md_rq_crd_oflow : 1;
+		mmr_t	gfx_int_1       : 1;
+		mmr_t	gfx_int_0       : 1;
+		mmr_t	nack_oflow      : 1;
+		mmr_t	xn_rp_q_oflow   : 1;
+		mmr_t	xn_rq_q_oflow   : 1;
+		mmr_t	md_rp_q_oflow   : 1;
+		mmr_t	md_rq_q_oflow   : 1;
+		mmr_t	msg_color_err   : 1;
+		mmr_t	fsb_shub_ce     : 1;
+		mmr_t	fsb_shub_uce    : 1;
+		mmr_t	pio_to_err      : 1;
+		mmr_t	mem_to_err      : 1;
+		mmr_t	pio_rp_err      : 1;
+		mmr_t	mem_rp_err      : 1;
+		mmr_t	xb_proto_err    : 1;
+		mmr_t	gfx_rp_err      : 1;
+		mmr_t	fsb_proto_err   : 1;
+	} sh_pi_first_error_s;
+} sh_pi_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_PI2MD_REPLY_VC_STATUS"                */
+/*                PI-to-MD Reply Virtual Channel Status                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_pi2md_reply_vc_status_u {
+	mmr_t	sh_pi_pi2md_reply_vc_status_regval;
+	struct {
+		mmr_t	output_crd_stat : 6;
+		mmr_t	reserved_0      : 58;
+	} sh_pi_pi2md_reply_vc_status_s;
+} sh_pi_pi2md_reply_vc_status_u_t;
+#else
+typedef union sh_pi_pi2md_reply_vc_status_u {
+	mmr_t	sh_pi_pi2md_reply_vc_status_regval;
+	struct {
+		mmr_t	reserved_0      : 58;
+		mmr_t	output_crd_stat : 6;
+	} sh_pi_pi2md_reply_vc_status_s;
+} sh_pi_pi2md_reply_vc_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_PI2MD_REQUEST_VC_STATUS"               */
+/*               PI-to-MD Request Virtual Channel Status                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_pi2md_request_vc_status_u {
+	mmr_t	sh_pi_pi2md_request_vc_status_regval;
+	struct {
+		mmr_t	output_crd_stat : 6;
+		mmr_t	reserved_0      : 58;
+	} sh_pi_pi2md_request_vc_status_s;
+} sh_pi_pi2md_request_vc_status_u_t;
+#else
+typedef union sh_pi_pi2md_request_vc_status_u {
+	mmr_t	sh_pi_pi2md_request_vc_status_regval;
+	struct {
+		mmr_t	reserved_0      : 58;
+		mmr_t	output_crd_stat : 6;
+	} sh_pi_pi2md_request_vc_status_s;
+} sh_pi_pi2md_request_vc_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_PI2XN_REPLY_VC_STATUS"                */
+/*                PI-to-XN Reply Virtual Channel Status                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_pi2xn_reply_vc_status_u {
+	mmr_t	sh_pi_pi2xn_reply_vc_status_regval;
+	struct {
+		mmr_t	output_crd_stat : 6;
+		mmr_t	reserved_0      : 58;
+	} sh_pi_pi2xn_reply_vc_status_s;
+} sh_pi_pi2xn_reply_vc_status_u_t;
+#else
+typedef union sh_pi_pi2xn_reply_vc_status_u {
+	mmr_t	sh_pi_pi2xn_reply_vc_status_regval;
+	struct {
+		mmr_t	reserved_0      : 58;
+		mmr_t	output_crd_stat : 6;
+	} sh_pi_pi2xn_reply_vc_status_s;
+} sh_pi_pi2xn_reply_vc_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_PI2XN_REQUEST_VC_STATUS"               */
+/*               PI-to-XN Request Virtual Channel Status                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_pi2xn_request_vc_status_u {
+	mmr_t	sh_pi_pi2xn_request_vc_status_regval;
+	struct {
+		mmr_t	output_crd_stat : 6;
+		mmr_t	reserved_0      : 58;
+	} sh_pi_pi2xn_request_vc_status_s;
+} sh_pi_pi2xn_request_vc_status_u_t;
+#else
+typedef union sh_pi_pi2xn_request_vc_status_u {
+	mmr_t	sh_pi_pi2xn_request_vc_status_regval;
+	struct {
+		mmr_t	reserved_0      : 58;
+		mmr_t	output_crd_stat : 6;
+	} sh_pi_pi2xn_request_vc_status_s;
+} sh_pi_pi2xn_request_vc_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_UNCORRECTED_DETAIL_1"                 */
+/*                    PI Uncorrected Error Detail 1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_uncorrected_detail_1_u {
+	mmr_t	sh_pi_uncorrected_detail_1_regval;
+	struct {
+		mmr_t	address     : 48;
+		mmr_t	syndrome    : 8;
+		mmr_t	dep         : 8;
+	} sh_pi_uncorrected_detail_1_s;
+} sh_pi_uncorrected_detail_1_u_t;
+#else
+typedef union sh_pi_uncorrected_detail_1_u {
+	mmr_t	sh_pi_uncorrected_detail_1_regval;
+	struct {
+		mmr_t	dep         : 8;
+		mmr_t	syndrome    : 8;
+		mmr_t	address     : 48;
+	} sh_pi_uncorrected_detail_1_s;
+} sh_pi_uncorrected_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_UNCORRECTED_DETAIL_2"                 */
+/*                    PI Uncorrected Error Detail 2                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_uncorrected_detail_2_u {
+	mmr_t	sh_pi_uncorrected_detail_2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_pi_uncorrected_detail_2_s;
+} sh_pi_uncorrected_detail_2_u_t;
+#else
+typedef union sh_pi_uncorrected_detail_2_u {
+	mmr_t	sh_pi_uncorrected_detail_2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_pi_uncorrected_detail_2_s;
+} sh_pi_uncorrected_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_UNCORRECTED_DETAIL_3"                 */
+/*                    PI Uncorrected Error Detail 3                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_uncorrected_detail_3_u {
+	mmr_t	sh_pi_uncorrected_detail_3_regval;
+	struct {
+		mmr_t	address     : 48;
+		mmr_t	syndrome    : 8;
+		mmr_t	dep         : 8;
+	} sh_pi_uncorrected_detail_3_s;
+} sh_pi_uncorrected_detail_3_u_t;
+#else
+typedef union sh_pi_uncorrected_detail_3_u {
+	mmr_t	sh_pi_uncorrected_detail_3_regval;
+	struct {
+		mmr_t	dep         : 8;
+		mmr_t	syndrome    : 8;
+		mmr_t	address     : 48;
+	} sh_pi_uncorrected_detail_3_s;
+} sh_pi_uncorrected_detail_3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_UNCORRECTED_DETAIL_4"                 */
+/*                    PI Uncorrected Error Detail 4                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_uncorrected_detail_4_u {
+	mmr_t	sh_pi_uncorrected_detail_4_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_pi_uncorrected_detail_4_s;
+} sh_pi_uncorrected_detail_4_u_t;
+#else
+typedef union sh_pi_uncorrected_detail_4_u {
+	mmr_t	sh_pi_uncorrected_detail_4_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_pi_uncorrected_detail_4_s;
+} sh_pi_uncorrected_detail_4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_MD2PI_REPLY_VC_STATUS"                */
+/*                MD-to-PI Reply Virtual Channel Status                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_md2pi_reply_vc_status_u {
+	mmr_t	sh_pi_md2pi_reply_vc_status_regval;
+	struct {
+		mmr_t	input_hdr_crd_stat : 4;
+		mmr_t	input_dat_crd_stat : 4;
+		mmr_t	input_queue_stat   : 4;
+		mmr_t	reserved_0         : 52;
+	} sh_pi_md2pi_reply_vc_status_s;
+} sh_pi_md2pi_reply_vc_status_u_t;
+#else
+typedef union sh_pi_md2pi_reply_vc_status_u {
+	mmr_t	sh_pi_md2pi_reply_vc_status_regval;
+	struct {
+		mmr_t	reserved_0         : 52;
+		mmr_t	input_queue_stat   : 4;
+		mmr_t	input_dat_crd_stat : 4;
+		mmr_t	input_hdr_crd_stat : 4;
+	} sh_pi_md2pi_reply_vc_status_s;
+} sh_pi_md2pi_reply_vc_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_MD2PI_REQUEST_VC_STATUS"               */
+/*               MD-to-PI Request Virtual Channel Status                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_md2pi_request_vc_status_u {
+	mmr_t	sh_pi_md2pi_request_vc_status_regval;
+	struct {
+		mmr_t	input_hdr_crd_stat : 4;
+		mmr_t	input_dat_crd_stat : 4;
+		mmr_t	input_queue_stat   : 4;
+		mmr_t	reserved_0         : 52;
+	} sh_pi_md2pi_request_vc_status_s;
+} sh_pi_md2pi_request_vc_status_u_t;
+#else
+typedef union sh_pi_md2pi_request_vc_status_u {
+	mmr_t	sh_pi_md2pi_request_vc_status_regval;
+	struct {
+		mmr_t	reserved_0         : 52;
+		mmr_t	input_queue_stat   : 4;
+		mmr_t	input_dat_crd_stat : 4;
+		mmr_t	input_hdr_crd_stat : 4;
+	} sh_pi_md2pi_request_vc_status_s;
+} sh_pi_md2pi_request_vc_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_PI_XN2PI_REPLY_VC_STATUS"                */
+/*                XN-to-PI Reply Virtual Channel Status                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_xn2pi_reply_vc_status_u {
+	mmr_t	sh_pi_xn2pi_reply_vc_status_regval;
+	struct {
+		mmr_t	input_hdr_crd_stat : 4;
+		mmr_t	input_dat_crd_stat : 4;
+		mmr_t	input_queue_stat   : 4;
+		mmr_t	reserved_0         : 52;
+	} sh_pi_xn2pi_reply_vc_status_s;
+} sh_pi_xn2pi_reply_vc_status_u_t;
+#else
+typedef union sh_pi_xn2pi_reply_vc_status_u {
+	mmr_t	sh_pi_xn2pi_reply_vc_status_regval;
+	struct {
+		mmr_t	reserved_0         : 52;
+		mmr_t	input_queue_stat   : 4;
+		mmr_t	input_dat_crd_stat : 4;
+		mmr_t	input_hdr_crd_stat : 4;
+	} sh_pi_xn2pi_reply_vc_status_s;
+} sh_pi_xn2pi_reply_vc_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PI_XN2PI_REQUEST_VC_STATUS"               */
+/*               XN-to-PI Request Virtual Channel Status                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_xn2pi_request_vc_status_u {
+	mmr_t	sh_pi_xn2pi_request_vc_status_regval;
+	struct {
+		mmr_t	input_hdr_crd_stat : 4;
+		mmr_t	input_dat_crd_stat : 4;
+		mmr_t	input_queue_stat   : 4;
+		mmr_t	reserved_0         : 52;
+	} sh_pi_xn2pi_request_vc_status_s;
+} sh_pi_xn2pi_request_vc_status_u_t;
+#else
+typedef union sh_pi_xn2pi_request_vc_status_u {
+	mmr_t	sh_pi_xn2pi_request_vc_status_regval;
+	struct {
+		mmr_t	reserved_0         : 52;
+		mmr_t	input_queue_stat   : 4;
+		mmr_t	input_dat_crd_stat : 4;
+		mmr_t	input_hdr_crd_stat : 4;
+	} sh_pi_xn2pi_request_vc_status_s;
+} sh_pi_xn2pi_request_vc_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_XNPI_SIC_FLOW"                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_sic_flow_u {
+	mmr_t	sh_xnpi_sic_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 5;
+		mmr_t	reserved_0           : 2;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 5;
+		mmr_t	reserved_1           : 2;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	credit_vc0_test      : 5;
+		mmr_t	reserved_2           : 3;
+		mmr_t	credit_vc0_dyn       : 5;
+		mmr_t	reserved_3           : 3;
+		mmr_t	credit_vc0_cap       : 5;
+		mmr_t	reserved_4           : 3;
+		mmr_t	credit_vc2_test      : 5;
+		mmr_t	reserved_5           : 3;
+		mmr_t	credit_vc2_dyn       : 5;
+		mmr_t	reserved_6           : 3;
+		mmr_t	credit_vc2_cap       : 5;
+		mmr_t	reserved_7           : 2;
+		mmr_t	disable_bypass_out   : 1;
+	} sh_xnpi_sic_flow_s;
+} sh_xnpi_sic_flow_u_t;
+#else
+typedef union sh_xnpi_sic_flow_u {
+	mmr_t	sh_xnpi_sic_flow_regval;
+	struct {
+		mmr_t	disable_bypass_out   : 1;
+		mmr_t	reserved_7           : 2;
+		mmr_t	credit_vc2_cap       : 5;
+		mmr_t	reserved_6           : 3;
+		mmr_t	credit_vc2_dyn       : 5;
+		mmr_t	reserved_5           : 3;
+		mmr_t	credit_vc2_test      : 5;
+		mmr_t	reserved_4           : 3;
+		mmr_t	credit_vc0_cap       : 5;
+		mmr_t	reserved_3           : 3;
+		mmr_t	credit_vc0_dyn       : 5;
+		mmr_t	reserved_2           : 3;
+		mmr_t	credit_vc0_test      : 5;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 2;
+		mmr_t	debit_vc2_withhold   : 5;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 2;
+		mmr_t	debit_vc0_withhold   : 5;
+	} sh_xnpi_sic_flow_s;
+} sh_xnpi_sic_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_TO_NI0_PORT_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_to_ni0_port_flow_u {
+	mmr_t	sh_xnpi_to_ni0_port_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnpi_to_ni0_port_flow_s;
+} sh_xnpi_to_ni0_port_flow_u_t;
+#else
+typedef union sh_xnpi_to_ni0_port_flow_u {
+	mmr_t	sh_xnpi_to_ni0_port_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnpi_to_ni0_port_flow_s;
+} sh_xnpi_to_ni0_port_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_TO_NI1_PORT_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_to_ni1_port_flow_u {
+	mmr_t	sh_xnpi_to_ni1_port_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnpi_to_ni1_port_flow_s;
+} sh_xnpi_to_ni1_port_flow_u_t;
+#else
+typedef union sh_xnpi_to_ni1_port_flow_u {
+	mmr_t	sh_xnpi_to_ni1_port_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnpi_to_ni1_port_flow_s;
+} sh_xnpi_to_ni1_port_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_TO_IILB_PORT_FLOW"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_to_iilb_port_flow_u {
+	mmr_t	sh_xnpi_to_iilb_port_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnpi_to_iilb_port_flow_s;
+} sh_xnpi_to_iilb_port_flow_u_t;
+#else
+typedef union sh_xnpi_to_iilb_port_flow_u {
+	mmr_t	sh_xnpi_to_iilb_port_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnpi_to_iilb_port_flow_s;
+} sh_xnpi_to_iilb_port_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XNPI_FR_NI0_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_fr_ni0_port_flow_fifo_u {
+	mmr_t	sh_xnpi_fr_ni0_port_flow_fifo_regval;
+	struct {
+		mmr_t	entry_vc0_dyn  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_5     : 19;
+	} sh_xnpi_fr_ni0_port_flow_fifo_s;
+} sh_xnpi_fr_ni0_port_flow_fifo_u_t;
+#else
+typedef union sh_xnpi_fr_ni0_port_flow_fifo_u {
+	mmr_t	sh_xnpi_fr_ni0_port_flow_fifo_regval;
+	struct {
+		mmr_t	reserved_5     : 19;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_dyn  : 6;
+	} sh_xnpi_fr_ni0_port_flow_fifo_s;
+} sh_xnpi_fr_ni0_port_flow_fifo_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XNPI_FR_NI1_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_fr_ni1_port_flow_fifo_u {
+	mmr_t	sh_xnpi_fr_ni1_port_flow_fifo_regval;
+	struct {
+		mmr_t	entry_vc0_dyn  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_5     : 19;
+	} sh_xnpi_fr_ni1_port_flow_fifo_s;
+} sh_xnpi_fr_ni1_port_flow_fifo_u_t;
+#else
+typedef union sh_xnpi_fr_ni1_port_flow_fifo_u {
+	mmr_t	sh_xnpi_fr_ni1_port_flow_fifo_regval;
+	struct {
+		mmr_t	reserved_5     : 19;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_dyn  : 6;
+	} sh_xnpi_fr_ni1_port_flow_fifo_s;
+} sh_xnpi_fr_ni1_port_flow_fifo_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_XNPI_FR_IILB_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_fr_iilb_port_flow_fifo_u {
+	mmr_t	sh_xnpi_fr_iilb_port_flow_fifo_regval;
+	struct {
+		mmr_t	entry_vc0_dyn  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_5     : 19;
+	} sh_xnpi_fr_iilb_port_flow_fifo_s;
+} sh_xnpi_fr_iilb_port_flow_fifo_u_t;
+#else
+typedef union sh_xnpi_fr_iilb_port_flow_fifo_u {
+	mmr_t	sh_xnpi_fr_iilb_port_flow_fifo_regval;
+	struct {
+		mmr_t	reserved_5     : 19;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_dyn  : 6;
+	} sh_xnpi_fr_iilb_port_flow_fifo_s;
+} sh_xnpi_fr_iilb_port_flow_fifo_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_XNMD_SIC_FLOW"                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_sic_flow_u {
+	mmr_t	sh_xnmd_sic_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 5;
+		mmr_t	reserved_0           : 2;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 5;
+		mmr_t	reserved_1           : 2;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	credit_vc0_test      : 5;
+		mmr_t	reserved_2           : 3;
+		mmr_t	credit_vc0_dyn       : 5;
+		mmr_t	reserved_3           : 3;
+		mmr_t	credit_vc0_cap       : 5;
+		mmr_t	reserved_4           : 3;
+		mmr_t	credit_vc2_test      : 5;
+		mmr_t	reserved_5           : 3;
+		mmr_t	credit_vc2_dyn       : 5;
+		mmr_t	reserved_6           : 3;
+		mmr_t	credit_vc2_cap       : 5;
+		mmr_t	reserved_7           : 2;
+		mmr_t	disable_bypass_out   : 1;
+	} sh_xnmd_sic_flow_s;
+} sh_xnmd_sic_flow_u_t;
+#else
+typedef union sh_xnmd_sic_flow_u {
+	mmr_t	sh_xnmd_sic_flow_regval;
+	struct {
+		mmr_t	disable_bypass_out   : 1;
+		mmr_t	reserved_7           : 2;
+		mmr_t	credit_vc2_cap       : 5;
+		mmr_t	reserved_6           : 3;
+		mmr_t	credit_vc2_dyn       : 5;
+		mmr_t	reserved_5           : 3;
+		mmr_t	credit_vc2_test      : 5;
+		mmr_t	reserved_4           : 3;
+		mmr_t	credit_vc0_cap       : 5;
+		mmr_t	reserved_3           : 3;
+		mmr_t	credit_vc0_dyn       : 5;
+		mmr_t	reserved_2           : 3;
+		mmr_t	credit_vc0_test      : 5;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 2;
+		mmr_t	debit_vc2_withhold   : 5;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 2;
+		mmr_t	debit_vc0_withhold   : 5;
+	} sh_xnmd_sic_flow_s;
+} sh_xnmd_sic_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_TO_NI0_PORT_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_to_ni0_port_flow_u {
+	mmr_t	sh_xnmd_to_ni0_port_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnmd_to_ni0_port_flow_s;
+} sh_xnmd_to_ni0_port_flow_u_t;
+#else
+typedef union sh_xnmd_to_ni0_port_flow_u {
+	mmr_t	sh_xnmd_to_ni0_port_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnmd_to_ni0_port_flow_s;
+} sh_xnmd_to_ni0_port_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_TO_NI1_PORT_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_to_ni1_port_flow_u {
+	mmr_t	sh_xnmd_to_ni1_port_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnmd_to_ni1_port_flow_s;
+} sh_xnmd_to_ni1_port_flow_u_t;
+#else
+typedef union sh_xnmd_to_ni1_port_flow_u {
+	mmr_t	sh_xnmd_to_ni1_port_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnmd_to_ni1_port_flow_s;
+} sh_xnmd_to_ni1_port_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_TO_IILB_PORT_FLOW"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_to_iilb_port_flow_u {
+	mmr_t	sh_xnmd_to_iilb_port_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_2           : 8;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_6           : 2;
+	} sh_xnmd_to_iilb_port_flow_s;
+} sh_xnmd_to_iilb_port_flow_u_t;
+#else
+typedef union sh_xnmd_to_iilb_port_flow_u {
+	mmr_t	sh_xnmd_to_iilb_port_flow_regval;
+	struct {
+		mmr_t	reserved_6           : 2;
+		mmr_t	credit_vc2_cap       : 6;
+		mmr_t	reserved_5           : 2;
+		mmr_t	credit_vc2_dyn       : 6;
+		mmr_t	reserved_4           : 10;
+		mmr_t	credit_vc0_cap       : 6;
+		mmr_t	reserved_3           : 2;
+		mmr_t	credit_vc0_dyn       : 6;
+		mmr_t	reserved_2           : 8;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnmd_to_iilb_port_flow_s;
+} sh_xnmd_to_iilb_port_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XNMD_FR_NI0_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_fr_ni0_port_flow_fifo_u {
+	mmr_t	sh_xnmd_fr_ni0_port_flow_fifo_regval;
+	struct {
+		mmr_t	entry_vc0_dyn  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_5     : 19;
+	} sh_xnmd_fr_ni0_port_flow_fifo_s;
+} sh_xnmd_fr_ni0_port_flow_fifo_u_t;
+#else
+typedef union sh_xnmd_fr_ni0_port_flow_fifo_u {
+	mmr_t	sh_xnmd_fr_ni0_port_flow_fifo_regval;
+	struct {
+		mmr_t	reserved_5     : 19;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_dyn  : 6;
+	} sh_xnmd_fr_ni0_port_flow_fifo_s;
+} sh_xnmd_fr_ni0_port_flow_fifo_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XNMD_FR_NI1_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_fr_ni1_port_flow_fifo_u {
+	mmr_t	sh_xnmd_fr_ni1_port_flow_fifo_regval;
+	struct {
+		mmr_t	entry_vc0_dyn  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_5     : 19;
+	} sh_xnmd_fr_ni1_port_flow_fifo_s;
+} sh_xnmd_fr_ni1_port_flow_fifo_u_t;
+#else
+typedef union sh_xnmd_fr_ni1_port_flow_fifo_u {
+	mmr_t	sh_xnmd_fr_ni1_port_flow_fifo_regval;
+	struct {
+		mmr_t	reserved_5     : 19;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_dyn  : 6;
+	} sh_xnmd_fr_ni1_port_flow_fifo_s;
+} sh_xnmd_fr_ni1_port_flow_fifo_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_XNMD_FR_IILB_PORT_FLOW_FIFO"               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_fr_iilb_port_flow_fifo_u {
+	mmr_t	sh_xnmd_fr_iilb_port_flow_fifo_regval;
+	struct {
+		mmr_t	entry_vc0_dyn  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_5     : 19;
+	} sh_xnmd_fr_iilb_port_flow_fifo_s;
+} sh_xnmd_fr_iilb_port_flow_fifo_u_t;
+#else
+typedef union sh_xnmd_fr_iilb_port_flow_fifo_u {
+	mmr_t	sh_xnmd_fr_iilb_port_flow_fifo_regval;
+	struct {
+		mmr_t	reserved_5     : 19;
+		mmr_t	entry_vc2_test : 5;
+		mmr_t	reserved_4     : 3;
+		mmr_t	entry_vc0_test : 5;
+		mmr_t	reserved_3     : 2;
+		mmr_t	entry_vc2_cap  : 6;
+		mmr_t	reserved_2     : 2;
+		mmr_t	entry_vc2_dyn  : 6;
+		mmr_t	reserved_1     : 2;
+		mmr_t	entry_vc0_cap  : 6;
+		mmr_t	reserved_0     : 2;
+		mmr_t	entry_vc0_dyn  : 6;
+	} sh_xnmd_fr_iilb_port_flow_fifo_s;
+} sh_xnmd_fr_iilb_port_flow_fifo_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNII_INTRA_FLOW"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnii_intra_flow_u {
+	mmr_t	sh_xnii_intra_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	credit_vc0_test      : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc0_dyn       : 7;
+		mmr_t	reserved_3           : 1;
+		mmr_t	credit_vc0_cap       : 7;
+		mmr_t	reserved_4           : 1;
+		mmr_t	credit_vc2_test      : 7;
+		mmr_t	reserved_5           : 1;
+		mmr_t	credit_vc2_dyn       : 7;
+		mmr_t	reserved_6           : 1;
+		mmr_t	credit_vc2_cap       : 7;
+		mmr_t	reserved_7           : 1;
+	} sh_xnii_intra_flow_s;
+} sh_xnii_intra_flow_u_t;
+#else
+typedef union sh_xnii_intra_flow_u {
+	mmr_t	sh_xnii_intra_flow_regval;
+	struct {
+		mmr_t	reserved_7           : 1;
+		mmr_t	credit_vc2_cap       : 7;
+		mmr_t	reserved_6           : 1;
+		mmr_t	credit_vc2_dyn       : 7;
+		mmr_t	reserved_5           : 1;
+		mmr_t	credit_vc2_test      : 7;
+		mmr_t	reserved_4           : 1;
+		mmr_t	credit_vc0_cap       : 7;
+		mmr_t	reserved_3           : 1;
+		mmr_t	credit_vc0_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc0_test      : 7;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnii_intra_flow_s;
+} sh_xnii_intra_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNLB_INTRA_FLOW"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnlb_intra_flow_u {
+	mmr_t	sh_xnlb_intra_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	credit_vc0_test      : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc0_dyn       : 7;
+		mmr_t	reserved_3           : 1;
+		mmr_t	credit_vc0_cap       : 7;
+		mmr_t	reserved_4           : 1;
+		mmr_t	credit_vc2_test      : 7;
+		mmr_t	reserved_5           : 1;
+		mmr_t	credit_vc2_dyn       : 7;
+		mmr_t	reserved_6           : 1;
+		mmr_t	credit_vc2_cap       : 7;
+		mmr_t	disable_bypass_in    : 1;
+	} sh_xnlb_intra_flow_s;
+} sh_xnlb_intra_flow_u_t;
+#else
+typedef union sh_xnlb_intra_flow_u {
+	mmr_t	sh_xnlb_intra_flow_regval;
+	struct {
+		mmr_t	disable_bypass_in    : 1;
+		mmr_t	credit_vc2_cap       : 7;
+		mmr_t	reserved_6           : 1;
+		mmr_t	credit_vc2_dyn       : 7;
+		mmr_t	reserved_5           : 1;
+		mmr_t	credit_vc2_test      : 7;
+		mmr_t	reserved_4           : 1;
+		mmr_t	credit_vc0_cap       : 7;
+		mmr_t	reserved_3           : 1;
+		mmr_t	credit_vc0_dyn       : 7;
+		mmr_t	reserved_2           : 1;
+		mmr_t	credit_vc0_test      : 7;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnlb_intra_flow_s;
+} sh_xnlb_intra_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_to_ni0_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_ni0_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xniilb_to_ni0_intra_flow_debit_s;
+} sh_xniilb_to_ni0_intra_flow_debit_u_t;
+#else
+typedef union sh_xniilb_to_ni0_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_ni0_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xniilb_to_ni0_intra_flow_debit_s;
+} sh_xniilb_to_ni0_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_to_ni1_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_ni1_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xniilb_to_ni1_intra_flow_debit_s;
+} sh_xniilb_to_ni1_intra_flow_debit_u_t;
+#else
+typedef union sh_xniilb_to_ni1_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_ni1_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xniilb_to_ni1_intra_flow_debit_s;
+} sh_xniilb_to_ni1_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_to_md_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_md_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xniilb_to_md_intra_flow_debit_s;
+} sh_xniilb_to_md_intra_flow_debit_u_t;
+#else
+typedef union sh_xniilb_to_md_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_md_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xniilb_to_md_intra_flow_debit_s;
+} sh_xniilb_to_md_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*            Register "SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_to_iilb_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_iilb_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xniilb_to_iilb_intra_flow_debit_s;
+} sh_xniilb_to_iilb_intra_flow_debit_u_t;
+#else
+typedef union sh_xniilb_to_iilb_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_iilb_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xniilb_to_iilb_intra_flow_debit_s;
+} sh_xniilb_to_iilb_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_to_pi_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_pi_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xniilb_to_pi_intra_flow_debit_s;
+} sh_xniilb_to_pi_intra_flow_debit_u_t;
+#else
+typedef union sh_xniilb_to_pi_intra_flow_debit_u {
+	mmr_t	sh_xniilb_to_pi_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xniilb_to_pi_intra_flow_debit_s;
+} sh_xniilb_to_pi_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*            Register "SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_fr_ni0_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_ni0_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xniilb_fr_ni0_intra_flow_credit_s;
+} sh_xniilb_fr_ni0_intra_flow_credit_u_t;
+#else
+typedef union sh_xniilb_fr_ni0_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_ni0_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xniilb_fr_ni0_intra_flow_credit_s;
+} sh_xniilb_fr_ni0_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*            Register "SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_fr_ni1_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_ni1_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xniilb_fr_ni1_intra_flow_credit_s;
+} sh_xniilb_fr_ni1_intra_flow_credit_u_t;
+#else
+typedef union sh_xniilb_fr_ni1_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_ni1_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xniilb_fr_ni1_intra_flow_credit_s;
+} sh_xniilb_fr_ni1_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_fr_md_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_md_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xniilb_fr_md_intra_flow_credit_s;
+} sh_xniilb_fr_md_intra_flow_credit_u_t;
+#else
+typedef union sh_xniilb_fr_md_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_md_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xniilb_fr_md_intra_flow_credit_s;
+} sh_xniilb_fr_md_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*            Register "SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT"            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_fr_iilb_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_iilb_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xniilb_fr_iilb_intra_flow_credit_s;
+} sh_xniilb_fr_iilb_intra_flow_credit_u_t;
+#else
+typedef union sh_xniilb_fr_iilb_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_iilb_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xniilb_fr_iilb_intra_flow_credit_s;
+} sh_xniilb_fr_iilb_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_fr_pi_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_pi_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xniilb_fr_pi_intra_flow_credit_s;
+} sh_xniilb_fr_pi_intra_flow_credit_u_t;
+#else
+typedef union sh_xniilb_fr_pi_intra_flow_credit_u {
+	mmr_t	sh_xniilb_fr_pi_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xniilb_fr_pi_intra_flow_credit_s;
+} sh_xniilb_fr_pi_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_to_pi_intra_flow_debit_u {
+	mmr_t	sh_xnni0_to_pi_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xnni0_to_pi_intra_flow_debit_s;
+} sh_xnni0_to_pi_intra_flow_debit_u_t;
+#else
+typedef union sh_xnni0_to_pi_intra_flow_debit_u {
+	mmr_t	sh_xnni0_to_pi_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xnni0_to_pi_intra_flow_debit_s;
+} sh_xnni0_to_pi_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_to_md_intra_flow_debit_u {
+	mmr_t	sh_xnni0_to_md_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xnni0_to_md_intra_flow_debit_s;
+} sh_xnni0_to_md_intra_flow_debit_u_t;
+#else
+typedef union sh_xnni0_to_md_intra_flow_debit_u {
+	mmr_t	sh_xnni0_to_md_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xnni0_to_md_intra_flow_debit_s;
+} sh_xnni0_to_md_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_to_iilb_intra_flow_debit_u {
+	mmr_t	sh_xnni0_to_iilb_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xnni0_to_iilb_intra_flow_debit_s;
+} sh_xnni0_to_iilb_intra_flow_debit_u_t;
+#else
+typedef union sh_xnni0_to_iilb_intra_flow_debit_u {
+	mmr_t	sh_xnni0_to_iilb_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xnni0_to_iilb_intra_flow_debit_s;
+} sh_xnni0_to_iilb_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_fr_pi_intra_flow_credit_u {
+	mmr_t	sh_xnni0_fr_pi_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xnni0_fr_pi_intra_flow_credit_s;
+} sh_xnni0_fr_pi_intra_flow_credit_u_t;
+#else
+typedef union sh_xnni0_fr_pi_intra_flow_credit_u {
+	mmr_t	sh_xnni0_fr_pi_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xnni0_fr_pi_intra_flow_credit_s;
+} sh_xnni0_fr_pi_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_fr_md_intra_flow_credit_u {
+	mmr_t	sh_xnni0_fr_md_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xnni0_fr_md_intra_flow_credit_s;
+} sh_xnni0_fr_md_intra_flow_credit_u_t;
+#else
+typedef union sh_xnni0_fr_md_intra_flow_credit_u {
+	mmr_t	sh_xnni0_fr_md_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xnni0_fr_md_intra_flow_credit_s;
+} sh_xnni0_fr_md_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*            Register "SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_fr_iilb_intra_flow_credit_u {
+	mmr_t	sh_xnni0_fr_iilb_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xnni0_fr_iilb_intra_flow_credit_s;
+} sh_xnni0_fr_iilb_intra_flow_credit_u_t;
+#else
+typedef union sh_xnni0_fr_iilb_intra_flow_credit_u {
+	mmr_t	sh_xnni0_fr_iilb_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xnni0_fr_iilb_intra_flow_credit_s;
+} sh_xnni0_fr_iilb_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_0_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_0_intrani_flow_u {
+	mmr_t	sh_xnni0_0_intrani_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_1           : 56;
+	} sh_xnni0_0_intrani_flow_s;
+} sh_xnni0_0_intrani_flow_u_t;
+#else
+typedef union sh_xnni0_0_intrani_flow_u {
+	mmr_t	sh_xnni0_0_intrani_flow_regval;
+	struct {
+		mmr_t	reserved_1           : 56;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnni0_0_intrani_flow_s;
+} sh_xnni0_0_intrani_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_1_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_1_intrani_flow_u {
+	mmr_t	sh_xnni0_1_intrani_flow_regval;
+	struct {
+		mmr_t	debit_vc1_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc1_force_cred : 1;
+		mmr_t	reserved_1           : 56;
+	} sh_xnni0_1_intrani_flow_s;
+} sh_xnni0_1_intrani_flow_u_t;
+#else
+typedef union sh_xnni0_1_intrani_flow_u {
+	mmr_t	sh_xnni0_1_intrani_flow_regval;
+	struct {
+		mmr_t	reserved_1           : 56;
+		mmr_t	debit_vc1_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc1_withhold   : 6;
+	} sh_xnni0_1_intrani_flow_s;
+} sh_xnni0_1_intrani_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_2_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_2_intrani_flow_u {
+	mmr_t	sh_xnni0_2_intrani_flow_regval;
+	struct {
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 56;
+	} sh_xnni0_2_intrani_flow_s;
+} sh_xnni0_2_intrani_flow_u_t;
+#else
+typedef union sh_xnni0_2_intrani_flow_u {
+	mmr_t	sh_xnni0_2_intrani_flow_regval;
+	struct {
+		mmr_t	reserved_1           : 56;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+	} sh_xnni0_2_intrani_flow_s;
+} sh_xnni0_2_intrani_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_3_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_3_intrani_flow_u {
+	mmr_t	sh_xnni0_3_intrani_flow_regval;
+	struct {
+		mmr_t	debit_vc3_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc3_force_cred : 1;
+		mmr_t	reserved_1           : 56;
+	} sh_xnni0_3_intrani_flow_s;
+} sh_xnni0_3_intrani_flow_u_t;
+#else
+typedef union sh_xnni0_3_intrani_flow_u {
+	mmr_t	sh_xnni0_3_intrani_flow_regval;
+	struct {
+		mmr_t	reserved_1           : 56;
+		mmr_t	debit_vc3_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc3_withhold   : 6;
+	} sh_xnni0_3_intrani_flow_s;
+} sh_xnni0_3_intrani_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI0_VCSWITCH_FLOW"                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_vcswitch_flow_u {
+	mmr_t	sh_xnni0_vcswitch_flow_regval;
+	struct {
+		mmr_t	ni_vcfifo_dateline_switch : 1;
+		mmr_t	reserved_0                : 7;
+		mmr_t	pi_vcfifo_switch          : 1;
+		mmr_t	reserved_1                : 7;
+		mmr_t	md_vcfifo_switch          : 1;
+		mmr_t	reserved_2                : 7;
+		mmr_t	iilb_vcfifo_switch        : 1;
+		mmr_t	reserved_3                : 7;
+		mmr_t	disable_sync_bypass_in    : 1;
+		mmr_t	disable_sync_bypass_out   : 1;
+		mmr_t	async_fifoes              : 1;
+		mmr_t	reserved_4                : 29;
+	} sh_xnni0_vcswitch_flow_s;
+} sh_xnni0_vcswitch_flow_u_t;
+#else
+typedef union sh_xnni0_vcswitch_flow_u {
+	mmr_t	sh_xnni0_vcswitch_flow_regval;
+	struct {
+		mmr_t	reserved_4                : 29;
+		mmr_t	async_fifoes              : 1;
+		mmr_t	disable_sync_bypass_out   : 1;
+		mmr_t	disable_sync_bypass_in    : 1;
+		mmr_t	reserved_3                : 7;
+		mmr_t	iilb_vcfifo_switch        : 1;
+		mmr_t	reserved_2                : 7;
+		mmr_t	md_vcfifo_switch          : 1;
+		mmr_t	reserved_1                : 7;
+		mmr_t	pi_vcfifo_switch          : 1;
+		mmr_t	reserved_0                : 7;
+		mmr_t	ni_vcfifo_dateline_switch : 1;
+	} sh_xnni0_vcswitch_flow_s;
+} sh_xnni0_vcswitch_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI0_TIMER_REG"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_timer_reg_u {
+	mmr_t	sh_xnni0_timer_reg_regval;
+	struct {
+		mmr_t	timeout_reg     : 24;
+		mmr_t	reserved_0      : 8;
+		mmr_t	linkcleanup_reg : 1;
+		mmr_t	reserved_1      : 31;
+	} sh_xnni0_timer_reg_s;
+} sh_xnni0_timer_reg_u_t;
+#else
+typedef union sh_xnni0_timer_reg_u {
+	mmr_t	sh_xnni0_timer_reg_regval;
+	struct {
+		mmr_t	reserved_1      : 31;
+		mmr_t	linkcleanup_reg : 1;
+		mmr_t	reserved_0      : 8;
+		mmr_t	timeout_reg     : 24;
+	} sh_xnni0_timer_reg_s;
+} sh_xnni0_timer_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_FIFO02_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_fifo02_flow_u {
+	mmr_t	sh_xnni0_fifo02_flow_regval;
+	struct {
+		mmr_t	count_vc0_limit : 4;
+		mmr_t	reserved_0      : 4;
+		mmr_t	count_vc0_dyn   : 4;
+		mmr_t	reserved_1      : 4;
+		mmr_t	count_vc0_cap   : 4;
+		mmr_t	reserved_2      : 4;
+		mmr_t	count_vc2_limit : 4;
+		mmr_t	reserved_3      : 4;
+		mmr_t	count_vc2_dyn   : 4;
+		mmr_t	reserved_4      : 4;
+		mmr_t	count_vc2_cap   : 4;
+		mmr_t	reserved_5      : 20;
+	} sh_xnni0_fifo02_flow_s;
+} sh_xnni0_fifo02_flow_u_t;
+#else
+typedef union sh_xnni0_fifo02_flow_u {
+	mmr_t	sh_xnni0_fifo02_flow_regval;
+	struct {
+		mmr_t	reserved_5      : 20;
+		mmr_t	count_vc2_cap   : 4;
+		mmr_t	reserved_4      : 4;
+		mmr_t	count_vc2_dyn   : 4;
+		mmr_t	reserved_3      : 4;
+		mmr_t	count_vc2_limit : 4;
+		mmr_t	reserved_2      : 4;
+		mmr_t	count_vc0_cap   : 4;
+		mmr_t	reserved_1      : 4;
+		mmr_t	count_vc0_dyn   : 4;
+		mmr_t	reserved_0      : 4;
+		mmr_t	count_vc0_limit : 4;
+	} sh_xnni0_fifo02_flow_s;
+} sh_xnni0_fifo02_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI0_FIFO13_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_fifo13_flow_u {
+	mmr_t	sh_xnni0_fifo13_flow_regval;
+	struct {
+		mmr_t	count_vc1_limit : 4;
+		mmr_t	reserved_0      : 4;
+		mmr_t	count_vc1_dyn   : 4;
+		mmr_t	reserved_1      : 4;
+		mmr_t	count_vc1_cap   : 4;
+		mmr_t	reserved_2      : 4;
+		mmr_t	count_vc3_limit : 4;
+		mmr_t	reserved_3      : 4;
+		mmr_t	count_vc3_dyn   : 4;
+		mmr_t	reserved_4      : 4;
+		mmr_t	count_vc3_cap   : 4;
+		mmr_t	reserved_5      : 20;
+	} sh_xnni0_fifo13_flow_s;
+} sh_xnni0_fifo13_flow_u_t;
+#else
+typedef union sh_xnni0_fifo13_flow_u {
+	mmr_t	sh_xnni0_fifo13_flow_regval;
+	struct {
+		mmr_t	reserved_5      : 20;
+		mmr_t	count_vc3_cap   : 4;
+		mmr_t	reserved_4      : 4;
+		mmr_t	count_vc3_dyn   : 4;
+		mmr_t	reserved_3      : 4;
+		mmr_t	count_vc3_limit : 4;
+		mmr_t	reserved_2      : 4;
+		mmr_t	count_vc1_cap   : 4;
+		mmr_t	reserved_1      : 4;
+		mmr_t	count_vc1_dyn   : 4;
+		mmr_t	reserved_0      : 4;
+		mmr_t	count_vc1_limit : 4;
+	} sh_xnni0_fifo13_flow_s;
+} sh_xnni0_fifo13_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_XNNI0_NI_FLOW"                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_ni_flow_u {
+	mmr_t	sh_xnni0_ni_flow_regval;
+	struct {
+		mmr_t	vc0_limit   : 4;
+		mmr_t	reserved_0  : 4;
+		mmr_t	vc0_dyn     : 4;
+		mmr_t	vc0_cap     : 4;
+		mmr_t	vc1_limit   : 4;
+		mmr_t	reserved_1  : 4;
+		mmr_t	vc1_dyn     : 4;
+		mmr_t	vc1_cap     : 4;
+		mmr_t	vc2_limit   : 4;
+		mmr_t	reserved_2  : 4;
+		mmr_t	vc2_dyn     : 4;
+		mmr_t	vc2_cap     : 4;
+		mmr_t	vc3_limit   : 4;
+		mmr_t	reserved_3  : 4;
+		mmr_t	vc3_dyn     : 4;
+		mmr_t	vc3_cap     : 4;
+	} sh_xnni0_ni_flow_s;
+} sh_xnni0_ni_flow_u_t;
+#else
+typedef union sh_xnni0_ni_flow_u {
+	mmr_t	sh_xnni0_ni_flow_regval;
+	struct {
+		mmr_t	vc3_cap     : 4;
+		mmr_t	vc3_dyn     : 4;
+		mmr_t	reserved_3  : 4;
+		mmr_t	vc3_limit   : 4;
+		mmr_t	vc2_cap     : 4;
+		mmr_t	vc2_dyn     : 4;
+		mmr_t	reserved_2  : 4;
+		mmr_t	vc2_limit   : 4;
+		mmr_t	vc1_cap     : 4;
+		mmr_t	vc1_dyn     : 4;
+		mmr_t	reserved_1  : 4;
+		mmr_t	vc1_limit   : 4;
+		mmr_t	vc0_cap     : 4;
+		mmr_t	vc0_dyn     : 4;
+		mmr_t	reserved_0  : 4;
+		mmr_t	vc0_limit   : 4;
+	} sh_xnni0_ni_flow_s;
+} sh_xnni0_ni_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI0_DEAD_FLOW"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_dead_flow_u {
+	mmr_t	sh_xnni0_dead_flow_regval;
+	struct {
+		mmr_t	vc0_limit   : 4;
+		mmr_t	reserved_0  : 4;
+		mmr_t	vc0_dyn     : 4;
+		mmr_t	vc0_cap     : 4;
+		mmr_t	vc1_limit   : 4;
+		mmr_t	reserved_1  : 4;
+		mmr_t	vc1_dyn     : 4;
+		mmr_t	vc1_cap     : 4;
+		mmr_t	vc2_limit   : 4;
+		mmr_t	reserved_2  : 4;
+		mmr_t	vc2_dyn     : 4;
+		mmr_t	vc2_cap     : 4;
+		mmr_t	vc3_limit   : 4;
+		mmr_t	reserved_3  : 4;
+		mmr_t	vc3_dyn     : 4;
+		mmr_t	vc3_cap     : 4;
+	} sh_xnni0_dead_flow_s;
+} sh_xnni0_dead_flow_u_t;
+#else
+typedef union sh_xnni0_dead_flow_u {
+	mmr_t	sh_xnni0_dead_flow_regval;
+	struct {
+		mmr_t	vc3_cap     : 4;
+		mmr_t	vc3_dyn     : 4;
+		mmr_t	reserved_3  : 4;
+		mmr_t	vc3_limit   : 4;
+		mmr_t	vc2_cap     : 4;
+		mmr_t	vc2_dyn     : 4;
+		mmr_t	reserved_2  : 4;
+		mmr_t	vc2_limit   : 4;
+		mmr_t	vc1_cap     : 4;
+		mmr_t	vc1_dyn     : 4;
+		mmr_t	reserved_1  : 4;
+		mmr_t	vc1_limit   : 4;
+		mmr_t	vc0_cap     : 4;
+		mmr_t	vc0_dyn     : 4;
+		mmr_t	reserved_0  : 4;
+		mmr_t	vc0_limit   : 4;
+	} sh_xnni0_dead_flow_s;
+} sh_xnni0_dead_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI0_INJECT_AGE"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni0_inject_age_u {
+	mmr_t	sh_xnni0_inject_age_regval;
+	struct {
+		mmr_t	request_inject : 8;
+		mmr_t	reply_inject   : 8;
+		mmr_t	reserved_0     : 48;
+	} sh_xnni0_inject_age_s;
+} sh_xnni0_inject_age_u_t;
+#else
+typedef union sh_xnni0_inject_age_u {
+	mmr_t	sh_xnni0_inject_age_regval;
+	struct {
+		mmr_t	reserved_0     : 48;
+		mmr_t	reply_inject   : 8;
+		mmr_t	request_inject : 8;
+	} sh_xnni0_inject_age_s;
+} sh_xnni0_inject_age_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_to_pi_intra_flow_debit_u {
+	mmr_t	sh_xnni1_to_pi_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xnni1_to_pi_intra_flow_debit_s;
+} sh_xnni1_to_pi_intra_flow_debit_u_t;
+#else
+typedef union sh_xnni1_to_pi_intra_flow_debit_u {
+	mmr_t	sh_xnni1_to_pi_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xnni1_to_pi_intra_flow_debit_s;
+} sh_xnni1_to_pi_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_to_md_intra_flow_debit_u {
+	mmr_t	sh_xnni1_to_md_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xnni1_to_md_intra_flow_debit_s;
+} sh_xnni1_to_md_intra_flow_debit_u_t;
+#else
+typedef union sh_xnni1_to_md_intra_flow_debit_u {
+	mmr_t	sh_xnni1_to_md_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xnni1_to_md_intra_flow_debit_s;
+} sh_xnni1_to_md_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_to_iilb_intra_flow_debit_u {
+	mmr_t	sh_xnni1_to_iilb_intra_flow_debit_regval;
+	struct {
+		mmr_t	vc0_withhold   : 6;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_6     : 1;
+	} sh_xnni1_to_iilb_intra_flow_debit_s;
+} sh_xnni1_to_iilb_intra_flow_debit_u_t;
+#else
+typedef union sh_xnni1_to_iilb_intra_flow_debit_u {
+	mmr_t	sh_xnni1_to_iilb_intra_flow_debit_regval;
+	struct {
+		mmr_t	reserved_6     : 1;
+		mmr_t	vc2_cap        : 7;
+		mmr_t	reserved_5     : 1;
+		mmr_t	vc2_dyn        : 7;
+		mmr_t	reserved_4     : 9;
+		mmr_t	vc0_cap        : 7;
+		mmr_t	reserved_3     : 1;
+		mmr_t	vc0_dyn        : 7;
+		mmr_t	reserved_2     : 8;
+		mmr_t	vc2_force_cred : 1;
+		mmr_t	reserved_1     : 1;
+		mmr_t	vc2_withhold   : 6;
+		mmr_t	vc0_force_cred : 1;
+		mmr_t	reserved_0     : 1;
+		mmr_t	vc0_withhold   : 6;
+	} sh_xnni1_to_iilb_intra_flow_debit_s;
+} sh_xnni1_to_iilb_intra_flow_debit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_fr_pi_intra_flow_credit_u {
+	mmr_t	sh_xnni1_fr_pi_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xnni1_fr_pi_intra_flow_credit_s;
+} sh_xnni1_fr_pi_intra_flow_credit_u_t;
+#else
+typedef union sh_xnni1_fr_pi_intra_flow_credit_u {
+	mmr_t	sh_xnni1_fr_pi_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xnni1_fr_pi_intra_flow_credit_s;
+} sh_xnni1_fr_pi_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT"              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_fr_md_intra_flow_credit_u {
+	mmr_t	sh_xnni1_fr_md_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xnni1_fr_md_intra_flow_credit_s;
+} sh_xnni1_fr_md_intra_flow_credit_u_t;
+#else
+typedef union sh_xnni1_fr_md_intra_flow_credit_u {
+	mmr_t	sh_xnni1_fr_md_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xnni1_fr_md_intra_flow_credit_s;
+} sh_xnni1_fr_md_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*            Register "SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT"             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_fr_iilb_intra_flow_credit_u {
+	mmr_t	sh_xnni1_fr_iilb_intra_flow_credit_regval;
+	struct {
+		mmr_t	vc0_test    : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_5  : 17;
+	} sh_xnni1_fr_iilb_intra_flow_credit_s;
+} sh_xnni1_fr_iilb_intra_flow_credit_u_t;
+#else
+typedef union sh_xnni1_fr_iilb_intra_flow_credit_u {
+	mmr_t	sh_xnni1_fr_iilb_intra_flow_credit_regval;
+	struct {
+		mmr_t	reserved_5  : 17;
+		mmr_t	vc2_cap     : 7;
+		mmr_t	reserved_4  : 1;
+		mmr_t	vc2_dyn     : 7;
+		mmr_t	reserved_3  : 1;
+		mmr_t	vc2_test    : 7;
+		mmr_t	reserved_2  : 1;
+		mmr_t	vc0_cap     : 7;
+		mmr_t	reserved_1  : 1;
+		mmr_t	vc0_dyn     : 7;
+		mmr_t	reserved_0  : 1;
+		mmr_t	vc0_test    : 7;
+	} sh_xnni1_fr_iilb_intra_flow_credit_s;
+} sh_xnni1_fr_iilb_intra_flow_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_0_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_0_intrani_flow_u {
+	mmr_t	sh_xnni1_0_intrani_flow_regval;
+	struct {
+		mmr_t	debit_vc0_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_1           : 56;
+	} sh_xnni1_0_intrani_flow_s;
+} sh_xnni1_0_intrani_flow_u_t;
+#else
+typedef union sh_xnni1_0_intrani_flow_u {
+	mmr_t	sh_xnni1_0_intrani_flow_regval;
+	struct {
+		mmr_t	reserved_1           : 56;
+		mmr_t	debit_vc0_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc0_withhold   : 6;
+	} sh_xnni1_0_intrani_flow_s;
+} sh_xnni1_0_intrani_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_1_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_1_intrani_flow_u {
+	mmr_t	sh_xnni1_1_intrani_flow_regval;
+	struct {
+		mmr_t	debit_vc1_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc1_force_cred : 1;
+		mmr_t	reserved_1           : 56;
+	} sh_xnni1_1_intrani_flow_s;
+} sh_xnni1_1_intrani_flow_u_t;
+#else
+typedef union sh_xnni1_1_intrani_flow_u {
+	mmr_t	sh_xnni1_1_intrani_flow_regval;
+	struct {
+		mmr_t	reserved_1           : 56;
+		mmr_t	debit_vc1_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc1_withhold   : 6;
+	} sh_xnni1_1_intrani_flow_s;
+} sh_xnni1_1_intrani_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_2_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_2_intrani_flow_u {
+	mmr_t	sh_xnni1_2_intrani_flow_regval;
+	struct {
+		mmr_t	debit_vc2_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_1           : 56;
+	} sh_xnni1_2_intrani_flow_s;
+} sh_xnni1_2_intrani_flow_u_t;
+#else
+typedef union sh_xnni1_2_intrani_flow_u {
+	mmr_t	sh_xnni1_2_intrani_flow_regval;
+	struct {
+		mmr_t	reserved_1           : 56;
+		mmr_t	debit_vc2_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc2_withhold   : 6;
+	} sh_xnni1_2_intrani_flow_s;
+} sh_xnni1_2_intrani_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_3_INTRANI_FLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_3_intrani_flow_u {
+	mmr_t	sh_xnni1_3_intrani_flow_regval;
+	struct {
+		mmr_t	debit_vc3_withhold   : 6;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc3_force_cred : 1;
+		mmr_t	reserved_1           : 56;
+	} sh_xnni1_3_intrani_flow_s;
+} sh_xnni1_3_intrani_flow_u_t;
+#else
+typedef union sh_xnni1_3_intrani_flow_u {
+	mmr_t	sh_xnni1_3_intrani_flow_regval;
+	struct {
+		mmr_t	reserved_1           : 56;
+		mmr_t	debit_vc3_force_cred : 1;
+		mmr_t	reserved_0           : 1;
+		mmr_t	debit_vc3_withhold   : 6;
+	} sh_xnni1_3_intrani_flow_s;
+} sh_xnni1_3_intrani_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNNI1_VCSWITCH_FLOW"                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_vcswitch_flow_u {
+	mmr_t	sh_xnni1_vcswitch_flow_regval;
+	struct {
+		mmr_t	ni_vcfifo_dateline_switch : 1;
+		mmr_t	reserved_0                : 7;
+		mmr_t	pi_vcfifo_switch          : 1;
+		mmr_t	reserved_1                : 7;
+		mmr_t	md_vcfifo_switch          : 1;
+		mmr_t	reserved_2                : 7;
+		mmr_t	iilb_vcfifo_switch        : 1;
+		mmr_t	reserved_3                : 7;
+		mmr_t	disable_sync_bypass_in    : 1;
+		mmr_t	disable_sync_bypass_out   : 1;
+		mmr_t	async_fifoes              : 1;
+		mmr_t	reserved_4                : 29;
+	} sh_xnni1_vcswitch_flow_s;
+} sh_xnni1_vcswitch_flow_u_t;
+#else
+typedef union sh_xnni1_vcswitch_flow_u {
+	mmr_t	sh_xnni1_vcswitch_flow_regval;
+	struct {
+		mmr_t	reserved_4                : 29;
+		mmr_t	async_fifoes              : 1;
+		mmr_t	disable_sync_bypass_out   : 1;
+		mmr_t	disable_sync_bypass_in    : 1;
+		mmr_t	reserved_3                : 7;
+		mmr_t	iilb_vcfifo_switch        : 1;
+		mmr_t	reserved_2                : 7;
+		mmr_t	md_vcfifo_switch          : 1;
+		mmr_t	reserved_1                : 7;
+		mmr_t	pi_vcfifo_switch          : 1;
+		mmr_t	reserved_0                : 7;
+		mmr_t	ni_vcfifo_dateline_switch : 1;
+	} sh_xnni1_vcswitch_flow_s;
+} sh_xnni1_vcswitch_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI1_TIMER_REG"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_timer_reg_u {
+	mmr_t	sh_xnni1_timer_reg_regval;
+	struct {
+		mmr_t	timeout_reg     : 24;
+		mmr_t	reserved_0      : 8;
+		mmr_t	linkcleanup_reg : 1;
+		mmr_t	reserved_1      : 31;
+	} sh_xnni1_timer_reg_s;
+} sh_xnni1_timer_reg_u_t;
+#else
+typedef union sh_xnni1_timer_reg_u {
+	mmr_t	sh_xnni1_timer_reg_regval;
+	struct {
+		mmr_t	reserved_1      : 31;
+		mmr_t	linkcleanup_reg : 1;
+		mmr_t	reserved_0      : 8;
+		mmr_t	timeout_reg     : 24;
+	} sh_xnni1_timer_reg_s;
+} sh_xnni1_timer_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_FIFO02_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_fifo02_flow_u {
+	mmr_t	sh_xnni1_fifo02_flow_regval;
+	struct {
+		mmr_t	count_vc0_limit : 4;
+		mmr_t	reserved_0      : 4;
+		mmr_t	count_vc0_dyn   : 4;
+		mmr_t	reserved_1      : 4;
+		mmr_t	count_vc0_cap   : 4;
+		mmr_t	reserved_2      : 4;
+		mmr_t	count_vc2_limit : 4;
+		mmr_t	reserved_3      : 4;
+		mmr_t	count_vc2_dyn   : 4;
+		mmr_t	reserved_4      : 4;
+		mmr_t	count_vc2_cap   : 4;
+		mmr_t	reserved_5      : 20;
+	} sh_xnni1_fifo02_flow_s;
+} sh_xnni1_fifo02_flow_u_t;
+#else
+typedef union sh_xnni1_fifo02_flow_u {
+	mmr_t	sh_xnni1_fifo02_flow_regval;
+	struct {
+		mmr_t	reserved_5      : 20;
+		mmr_t	count_vc2_cap   : 4;
+		mmr_t	reserved_4      : 4;
+		mmr_t	count_vc2_dyn   : 4;
+		mmr_t	reserved_3      : 4;
+		mmr_t	count_vc2_limit : 4;
+		mmr_t	reserved_2      : 4;
+		mmr_t	count_vc0_cap   : 4;
+		mmr_t	reserved_1      : 4;
+		mmr_t	count_vc0_dyn   : 4;
+		mmr_t	reserved_0      : 4;
+		mmr_t	count_vc0_limit : 4;
+	} sh_xnni1_fifo02_flow_s;
+} sh_xnni1_fifo02_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNNI1_FIFO13_FLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_fifo13_flow_u {
+	mmr_t	sh_xnni1_fifo13_flow_regval;
+	struct {
+		mmr_t	count_vc1_limit : 4;
+		mmr_t	reserved_0      : 4;
+		mmr_t	count_vc1_dyn   : 4;
+		mmr_t	reserved_1      : 4;
+		mmr_t	count_vc1_cap   : 4;
+		mmr_t	reserved_2      : 4;
+		mmr_t	count_vc3_limit : 4;
+		mmr_t	reserved_3      : 4;
+		mmr_t	count_vc3_dyn   : 4;
+		mmr_t	reserved_4      : 4;
+		mmr_t	count_vc3_cap   : 4;
+		mmr_t	reserved_5      : 20;
+	} sh_xnni1_fifo13_flow_s;
+} sh_xnni1_fifo13_flow_u_t;
+#else
+typedef union sh_xnni1_fifo13_flow_u {
+	mmr_t	sh_xnni1_fifo13_flow_regval;
+	struct {
+		mmr_t	reserved_5      : 20;
+		mmr_t	count_vc3_cap   : 4;
+		mmr_t	reserved_4      : 4;
+		mmr_t	count_vc3_dyn   : 4;
+		mmr_t	reserved_3      : 4;
+		mmr_t	count_vc3_limit : 4;
+		mmr_t	reserved_2      : 4;
+		mmr_t	count_vc1_cap   : 4;
+		mmr_t	reserved_1      : 4;
+		mmr_t	count_vc1_dyn   : 4;
+		mmr_t	reserved_0      : 4;
+		mmr_t	count_vc1_limit : 4;
+	} sh_xnni1_fifo13_flow_s;
+} sh_xnni1_fifo13_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_XNNI1_NI_FLOW"                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_ni_flow_u {
+	mmr_t	sh_xnni1_ni_flow_regval;
+	struct {
+		mmr_t	vc0_limit   : 4;
+		mmr_t	reserved_0  : 4;
+		mmr_t	vc0_dyn     : 4;
+		mmr_t	vc0_cap     : 4;
+		mmr_t	vc1_limit   : 4;
+		mmr_t	reserved_1  : 4;
+		mmr_t	vc1_dyn     : 4;
+		mmr_t	vc1_cap     : 4;
+		mmr_t	vc2_limit   : 4;
+		mmr_t	reserved_2  : 4;
+		mmr_t	vc2_dyn     : 4;
+		mmr_t	vc2_cap     : 4;
+		mmr_t	vc3_limit   : 4;
+		mmr_t	reserved_3  : 4;
+		mmr_t	vc3_dyn     : 4;
+		mmr_t	vc3_cap     : 4;
+	} sh_xnni1_ni_flow_s;
+} sh_xnni1_ni_flow_u_t;
+#else
+typedef union sh_xnni1_ni_flow_u {
+	mmr_t	sh_xnni1_ni_flow_regval;
+	struct {
+		mmr_t	vc3_cap     : 4;
+		mmr_t	vc3_dyn     : 4;
+		mmr_t	reserved_3  : 4;
+		mmr_t	vc3_limit   : 4;
+		mmr_t	vc2_cap     : 4;
+		mmr_t	vc2_dyn     : 4;
+		mmr_t	reserved_2  : 4;
+		mmr_t	vc2_limit   : 4;
+		mmr_t	vc1_cap     : 4;
+		mmr_t	vc1_dyn     : 4;
+		mmr_t	reserved_1  : 4;
+		mmr_t	vc1_limit   : 4;
+		mmr_t	vc0_cap     : 4;
+		mmr_t	vc0_dyn     : 4;
+		mmr_t	reserved_0  : 4;
+		mmr_t	vc0_limit   : 4;
+	} sh_xnni1_ni_flow_s;
+} sh_xnni1_ni_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI1_DEAD_FLOW"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_dead_flow_u {
+	mmr_t	sh_xnni1_dead_flow_regval;
+	struct {
+		mmr_t	vc0_limit   : 4;
+		mmr_t	reserved_0  : 4;
+		mmr_t	vc0_dyn     : 4;
+		mmr_t	vc0_cap     : 4;
+		mmr_t	vc1_limit   : 4;
+		mmr_t	reserved_1  : 4;
+		mmr_t	vc1_dyn     : 4;
+		mmr_t	vc1_cap     : 4;
+		mmr_t	vc2_limit   : 4;
+		mmr_t	reserved_2  : 4;
+		mmr_t	vc2_dyn     : 4;
+		mmr_t	vc2_cap     : 4;
+		mmr_t	vc3_limit   : 4;
+		mmr_t	reserved_3  : 4;
+		mmr_t	vc3_dyn     : 4;
+		mmr_t	vc3_cap     : 4;
+	} sh_xnni1_dead_flow_s;
+} sh_xnni1_dead_flow_u_t;
+#else
+typedef union sh_xnni1_dead_flow_u {
+	mmr_t	sh_xnni1_dead_flow_regval;
+	struct {
+		mmr_t	vc3_cap     : 4;
+		mmr_t	vc3_dyn     : 4;
+		mmr_t	reserved_3  : 4;
+		mmr_t	vc3_limit   : 4;
+		mmr_t	vc2_cap     : 4;
+		mmr_t	vc2_dyn     : 4;
+		mmr_t	reserved_2  : 4;
+		mmr_t	vc2_limit   : 4;
+		mmr_t	vc1_cap     : 4;
+		mmr_t	vc1_dyn     : 4;
+		mmr_t	reserved_1  : 4;
+		mmr_t	vc1_limit   : 4;
+		mmr_t	vc0_cap     : 4;
+		mmr_t	vc0_dyn     : 4;
+		mmr_t	reserved_0  : 4;
+		mmr_t	vc0_limit   : 4;
+	} sh_xnni1_dead_flow_s;
+} sh_xnni1_dead_flow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNNI1_INJECT_AGE"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnni1_inject_age_u {
+	mmr_t	sh_xnni1_inject_age_regval;
+	struct {
+		mmr_t	request_inject : 8;
+		mmr_t	reply_inject   : 8;
+		mmr_t	reserved_0     : 48;
+	} sh_xnni1_inject_age_s;
+} sh_xnni1_inject_age_u_t;
+#else
+typedef union sh_xnni1_inject_age_u {
+	mmr_t	sh_xnni1_inject_age_regval;
+	struct {
+		mmr_t	reserved_0     : 48;
+		mmr_t	reply_inject   : 8;
+		mmr_t	request_inject : 8;
+	} sh_xnni1_inject_age_s;
+} sh_xnni1_inject_age_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_XN_DEBUG_SEL"                      */
+/*                         XN Debug Port Select                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_debug_sel_u {
+	mmr_t	sh_xn_debug_sel_regval;
+	struct {
+		mmr_t	nibble0_rlm_sel    : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble1_rlm_sel    : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble2_rlm_sel    : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble3_rlm_sel    : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble4_rlm_sel    : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble5_rlm_sel    : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble6_rlm_sel    : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble7_rlm_sel    : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	trigger_enable     : 1;
+	} sh_xn_debug_sel_s;
+} sh_xn_debug_sel_u_t;
+#else
+typedef union sh_xn_debug_sel_u {
+	mmr_t	sh_xn_debug_sel_regval;
+	struct {
+		mmr_t	trigger_enable     : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_rlm_sel    : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_rlm_sel    : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_rlm_sel    : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_rlm_sel    : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_rlm_sel    : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_rlm_sel    : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_rlm_sel    : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_rlm_sel    : 3;
+	} sh_xn_debug_sel_s;
+} sh_xn_debug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XN_DEBUG_TRIG_SEL"                    */
+/*                       XN Debug trigger Select                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_debug_trig_sel_u {
+	mmr_t	sh_xn_debug_trig_sel_regval;
+	struct {
+		mmr_t	trigger0_rlm_sel    : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	trigger0_nibble_sel : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	trigger1_rlm_sel    : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	trigger1_nibble_sel : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	trigger2_rlm_sel    : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	trigger2_nibble_sel : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	trigger3_rlm_sel    : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	trigger3_nibble_sel : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	trigger4_rlm_sel    : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	trigger4_nibble_sel : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	trigger5_rlm_sel    : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	trigger5_nibble_sel : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	trigger6_rlm_sel    : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	trigger6_nibble_sel : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	trigger7_rlm_sel    : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	trigger7_nibble_sel : 3;
+		mmr_t	reserved_15         : 1;
+	} sh_xn_debug_trig_sel_s;
+} sh_xn_debug_trig_sel_u_t;
+#else
+typedef union sh_xn_debug_trig_sel_u {
+	mmr_t	sh_xn_debug_trig_sel_regval;
+	struct {
+		mmr_t	reserved_15         : 1;
+		mmr_t	trigger7_nibble_sel : 3;
+		mmr_t	reserved_14         : 1;
+		mmr_t	trigger7_rlm_sel    : 3;
+		mmr_t	reserved_13         : 1;
+		mmr_t	trigger6_nibble_sel : 3;
+		mmr_t	reserved_12         : 1;
+		mmr_t	trigger6_rlm_sel    : 3;
+		mmr_t	reserved_11         : 1;
+		mmr_t	trigger5_nibble_sel : 3;
+		mmr_t	reserved_10         : 1;
+		mmr_t	trigger5_rlm_sel    : 3;
+		mmr_t	reserved_9          : 1;
+		mmr_t	trigger4_nibble_sel : 3;
+		mmr_t	reserved_8          : 1;
+		mmr_t	trigger4_rlm_sel    : 3;
+		mmr_t	reserved_7          : 1;
+		mmr_t	trigger3_nibble_sel : 3;
+		mmr_t	reserved_6          : 1;
+		mmr_t	trigger3_rlm_sel    : 3;
+		mmr_t	reserved_5          : 1;
+		mmr_t	trigger2_nibble_sel : 3;
+		mmr_t	reserved_4          : 1;
+		mmr_t	trigger2_rlm_sel    : 3;
+		mmr_t	reserved_3          : 1;
+		mmr_t	trigger1_nibble_sel : 3;
+		mmr_t	reserved_2          : 1;
+		mmr_t	trigger1_rlm_sel    : 3;
+		mmr_t	reserved_1          : 1;
+		mmr_t	trigger0_nibble_sel : 3;
+		mmr_t	reserved_0          : 1;
+		mmr_t	trigger0_rlm_sel    : 3;
+	} sh_xn_debug_trig_sel_s;
+} sh_xn_debug_trig_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XN_TRIGGER_COMPARE"                   */
+/*                           XN Debug Compare                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_trigger_compare_u {
+	mmr_t	sh_xn_trigger_compare_regval;
+	struct {
+		mmr_t	mask        : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_xn_trigger_compare_s;
+} sh_xn_trigger_compare_u_t;
+#else
+typedef union sh_xn_trigger_compare_u {
+	mmr_t	sh_xn_trigger_compare_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	mask        : 32;
+	} sh_xn_trigger_compare_s;
+} sh_xn_trigger_compare_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_TRIGGER_DATA"                     */
+/*                        XN Debug Compare Data                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_trigger_data_u {
+	mmr_t	sh_xn_trigger_data_regval;
+	struct {
+		mmr_t	compare_pattern : 32;
+		mmr_t	reserved_0      : 32;
+	} sh_xn_trigger_data_s;
+} sh_xn_trigger_data_u_t;
+#else
+typedef union sh_xn_trigger_data_u {
+	mmr_t	sh_xn_trigger_data_regval;
+	struct {
+		mmr_t	reserved_0      : 32;
+		mmr_t	compare_pattern : 32;
+	} sh_xn_trigger_data_s;
+} sh_xn_trigger_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XN_IILB_DEBUG_SEL"                    */
+/*                      XN IILB Debug Port Select                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_debug_sel_u {
+	mmr_t	sh_xn_iilb_debug_sel_regval;
+	struct {
+		mmr_t	nibble0_input_sel  : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_15        : 1;
+	} sh_xn_iilb_debug_sel_s;
+} sh_xn_iilb_debug_sel_u_t;
+#else
+typedef union sh_xn_iilb_debug_sel_u {
+	mmr_t	sh_xn_iilb_debug_sel_regval;
+	struct {
+		mmr_t	reserved_15        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_input_sel  : 3;
+	} sh_xn_iilb_debug_sel_s;
+} sh_xn_iilb_debug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_PI_DEBUG_SEL"                     */
+/*                       XN PI Debug Port Select                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_debug_sel_u {
+	mmr_t	sh_xn_pi_debug_sel_regval;
+	struct {
+		mmr_t	nibble0_input_sel  : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_15        : 1;
+	} sh_xn_pi_debug_sel_s;
+} sh_xn_pi_debug_sel_u_t;
+#else
+typedef union sh_xn_pi_debug_sel_u {
+	mmr_t	sh_xn_pi_debug_sel_regval;
+	struct {
+		mmr_t	reserved_15        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_input_sel  : 3;
+	} sh_xn_pi_debug_sel_s;
+} sh_xn_pi_debug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_MD_DEBUG_SEL"                     */
+/*                       XN MD Debug Port Select                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_debug_sel_u {
+	mmr_t	sh_xn_md_debug_sel_regval;
+	struct {
+		mmr_t	nibble0_input_sel  : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_15        : 1;
+	} sh_xn_md_debug_sel_s;
+} sh_xn_md_debug_sel_u_t;
+#else
+typedef union sh_xn_md_debug_sel_u {
+	mmr_t	sh_xn_md_debug_sel_regval;
+	struct {
+		mmr_t	reserved_15        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_input_sel  : 3;
+	} sh_xn_md_debug_sel_s;
+} sh_xn_md_debug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_NI0_DEBUG_SEL"                    */
+/*                       XN NI0 Debug Port Select                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_debug_sel_u {
+	mmr_t	sh_xn_ni0_debug_sel_regval;
+	struct {
+		mmr_t	nibble0_input_sel  : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_15        : 1;
+	} sh_xn_ni0_debug_sel_s;
+} sh_xn_ni0_debug_sel_u_t;
+#else
+typedef union sh_xn_ni0_debug_sel_u {
+	mmr_t	sh_xn_ni0_debug_sel_regval;
+	struct {
+		mmr_t	reserved_15        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_input_sel  : 3;
+	} sh_xn_ni0_debug_sel_s;
+} sh_xn_ni0_debug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_NI1_DEBUG_SEL"                    */
+/*                       XN NI1 Debug Port Select                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_debug_sel_u {
+	mmr_t	sh_xn_ni1_debug_sel_regval;
+	struct {
+		mmr_t	nibble0_input_sel  : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_15        : 1;
+	} sh_xn_ni1_debug_sel_s;
+} sh_xn_ni1_debug_sel_u_t;
+#else
+typedef union sh_xn_ni1_debug_sel_u {
+	mmr_t	sh_xn_ni1_debug_sel_regval;
+	struct {
+		mmr_t	reserved_15        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_input_sel  : 3;
+	} sh_xn_ni1_debug_sel_s;
+} sh_xn_ni1_debug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_LB_CMP_EXP_DATA0"                */
+/*                 IILB compare LB input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_lb_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_lb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_lb_cmp_exp_data0_s;
+} sh_xn_iilb_lb_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_iilb_lb_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_lb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_lb_cmp_exp_data0_s;
+} sh_xn_iilb_lb_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_LB_CMP_EXP_DATA1"                */
+/*                 IILB compare LB input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_lb_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_lb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_lb_cmp_exp_data1_s;
+} sh_xn_iilb_lb_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_iilb_lb_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_lb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_lb_cmp_exp_data1_s;
+} sh_xn_iilb_lb_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_LB_CMP_ENABLE0"                 */
+/*                    IILB compare LB input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_lb_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_lb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_lb_cmp_enable0_s;
+} sh_xn_iilb_lb_cmp_enable0_u_t;
+#else
+typedef union sh_xn_iilb_lb_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_lb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_lb_cmp_enable0_s;
+} sh_xn_iilb_lb_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_LB_CMP_ENABLE1"                 */
+/*                    IILB compare LB input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_lb_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_lb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_lb_cmp_enable1_s;
+} sh_xn_iilb_lb_cmp_enable1_u_t;
+#else
+typedef union sh_xn_iilb_lb_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_lb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_lb_cmp_enable1_s;
+} sh_xn_iilb_lb_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_II_CMP_EXP_DATA0"                */
+/*                 IILB compare II input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ii_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_ii_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ii_cmp_exp_data0_s;
+} sh_xn_iilb_ii_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_iilb_ii_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_ii_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ii_cmp_exp_data0_s;
+} sh_xn_iilb_ii_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_II_CMP_EXP_DATA1"                */
+/*                 IILB compare II input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ii_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_ii_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ii_cmp_exp_data1_s;
+} sh_xn_iilb_ii_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_iilb_ii_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_ii_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ii_cmp_exp_data1_s;
+} sh_xn_iilb_ii_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_II_CMP_ENABLE0"                 */
+/*                    IILB compare II input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ii_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_ii_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ii_cmp_enable0_s;
+} sh_xn_iilb_ii_cmp_enable0_u_t;
+#else
+typedef union sh_xn_iilb_ii_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_ii_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ii_cmp_enable0_s;
+} sh_xn_iilb_ii_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_II_CMP_ENABLE1"                 */
+/*                    IILB compare II input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ii_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_ii_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ii_cmp_enable1_s;
+} sh_xn_iilb_ii_cmp_enable1_u_t;
+#else
+typedef union sh_xn_iilb_ii_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_ii_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ii_cmp_enable1_s;
+} sh_xn_iilb_ii_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_MD_CMP_EXP_DATA0"                */
+/*                 IILB compare MD input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_md_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_md_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_md_cmp_exp_data0_s;
+} sh_xn_iilb_md_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_iilb_md_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_md_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_md_cmp_exp_data0_s;
+} sh_xn_iilb_md_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_MD_CMP_EXP_DATA1"                */
+/*                 IILB compare MD input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_md_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_md_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_md_cmp_exp_data1_s;
+} sh_xn_iilb_md_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_iilb_md_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_md_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_md_cmp_exp_data1_s;
+} sh_xn_iilb_md_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_MD_CMP_ENABLE0"                 */
+/*                    IILB compare MD input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_md_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_md_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_md_cmp_enable0_s;
+} sh_xn_iilb_md_cmp_enable0_u_t;
+#else
+typedef union sh_xn_iilb_md_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_md_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_md_cmp_enable0_s;
+} sh_xn_iilb_md_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_MD_CMP_ENABLE1"                 */
+/*                    IILB compare MD input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_md_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_md_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_md_cmp_enable1_s;
+} sh_xn_iilb_md_cmp_enable1_u_t;
+#else
+typedef union sh_xn_iilb_md_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_md_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_md_cmp_enable1_s;
+} sh_xn_iilb_md_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_PI_CMP_EXP_DATA0"                */
+/*                 IILB compare PI input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_pi_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_pi_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_pi_cmp_exp_data0_s;
+} sh_xn_iilb_pi_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_iilb_pi_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_pi_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_pi_cmp_exp_data0_s;
+} sh_xn_iilb_pi_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_PI_CMP_EXP_DATA1"                */
+/*                 IILB compare PI input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_pi_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_pi_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_pi_cmp_exp_data1_s;
+} sh_xn_iilb_pi_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_iilb_pi_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_pi_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_pi_cmp_exp_data1_s;
+} sh_xn_iilb_pi_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_PI_CMP_ENABLE0"                 */
+/*                    IILB compare PI input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_pi_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_pi_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_pi_cmp_enable0_s;
+} sh_xn_iilb_pi_cmp_enable0_u_t;
+#else
+typedef union sh_xn_iilb_pi_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_pi_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_pi_cmp_enable0_s;
+} sh_xn_iilb_pi_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_IILB_PI_CMP_ENABLE1"                 */
+/*                    IILB compare PI input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_pi_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_pi_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_pi_cmp_enable1_s;
+} sh_xn_iilb_pi_cmp_enable1_u_t;
+#else
+typedef union sh_xn_iilb_pi_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_pi_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_pi_cmp_enable1_s;
+} sh_xn_iilb_pi_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_IILB_NI0_CMP_EXP_DATA0"                */
+/*                IILB compare NI0 input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ni0_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_ni0_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ni0_cmp_exp_data0_s;
+} sh_xn_iilb_ni0_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_iilb_ni0_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_ni0_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ni0_cmp_exp_data0_s;
+} sh_xn_iilb_ni0_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_IILB_NI0_CMP_EXP_DATA1"                */
+/*                IILB compare NI0 input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ni0_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_ni0_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ni0_cmp_exp_data1_s;
+} sh_xn_iilb_ni0_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_iilb_ni0_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_ni0_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ni0_cmp_exp_data1_s;
+} sh_xn_iilb_ni0_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_NI0_CMP_ENABLE0"                 */
+/*                    IILB compare NI0 input enable0                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ni0_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_ni0_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ni0_cmp_enable0_s;
+} sh_xn_iilb_ni0_cmp_enable0_u_t;
+#else
+typedef union sh_xn_iilb_ni0_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_ni0_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ni0_cmp_enable0_s;
+} sh_xn_iilb_ni0_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_NI0_CMP_ENABLE1"                 */
+/*                    IILB compare NI0 input enable1                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ni0_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_ni0_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ni0_cmp_enable1_s;
+} sh_xn_iilb_ni0_cmp_enable1_u_t;
+#else
+typedef union sh_xn_iilb_ni0_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_ni0_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ni0_cmp_enable1_s;
+} sh_xn_iilb_ni0_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_IILB_NI1_CMP_EXP_DATA0"                */
+/*                IILB compare NI1 input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ni1_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_ni1_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ni1_cmp_exp_data0_s;
+} sh_xn_iilb_ni1_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_iilb_ni1_cmp_exp_data0_u {
+	mmr_t	sh_xn_iilb_ni1_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ni1_cmp_exp_data0_s;
+} sh_xn_iilb_ni1_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_IILB_NI1_CMP_EXP_DATA1"                */
+/*                IILB compare NI1 input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ni1_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_ni1_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ni1_cmp_exp_data1_s;
+} sh_xn_iilb_ni1_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_iilb_ni1_cmp_exp_data1_u {
+	mmr_t	sh_xn_iilb_ni1_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_iilb_ni1_cmp_exp_data1_s;
+} sh_xn_iilb_ni1_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_NI1_CMP_ENABLE0"                 */
+/*                    IILB compare NI1 input enable0                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ni1_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_ni1_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ni1_cmp_enable0_s;
+} sh_xn_iilb_ni1_cmp_enable0_u_t;
+#else
+typedef union sh_xn_iilb_ni1_cmp_enable0_u {
+	mmr_t	sh_xn_iilb_ni1_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ni1_cmp_enable0_s;
+} sh_xn_iilb_ni1_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_IILB_NI1_CMP_ENABLE1"                 */
+/*                    IILB compare NI1 input enable1                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_iilb_ni1_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_ni1_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ni1_cmp_enable1_s;
+} sh_xn_iilb_ni1_cmp_enable1_u_t;
+#else
+typedef union sh_xn_iilb_ni1_cmp_enable1_u {
+	mmr_t	sh_xn_iilb_ni1_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_iilb_ni1_cmp_enable1_s;
+} sh_xn_iilb_ni1_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_IILB_CMP_EXP_DATA0"                */
+/*                 MD compare IILB input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_iilb_cmp_exp_data0_u {
+	mmr_t	sh_xn_md_iilb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_iilb_cmp_exp_data0_s;
+} sh_xn_md_iilb_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_md_iilb_cmp_exp_data0_u {
+	mmr_t	sh_xn_md_iilb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_iilb_cmp_exp_data0_s;
+} sh_xn_md_iilb_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_IILB_CMP_EXP_DATA1"                */
+/*                 MD compare IILB input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_iilb_cmp_exp_data1_u {
+	mmr_t	sh_xn_md_iilb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_iilb_cmp_exp_data1_s;
+} sh_xn_md_iilb_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_md_iilb_cmp_exp_data1_u {
+	mmr_t	sh_xn_md_iilb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_iilb_cmp_exp_data1_s;
+} sh_xn_md_iilb_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_IILB_CMP_ENABLE0"                 */
+/*                    MD compare IILB input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_iilb_cmp_enable0_u {
+	mmr_t	sh_xn_md_iilb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_iilb_cmp_enable0_s;
+} sh_xn_md_iilb_cmp_enable0_u_t;
+#else
+typedef union sh_xn_md_iilb_cmp_enable0_u {
+	mmr_t	sh_xn_md_iilb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_iilb_cmp_enable0_s;
+} sh_xn_md_iilb_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_IILB_CMP_ENABLE1"                 */
+/*                    MD compare IILB input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_iilb_cmp_enable1_u {
+	mmr_t	sh_xn_md_iilb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_iilb_cmp_enable1_s;
+} sh_xn_md_iilb_cmp_enable1_u_t;
+#else
+typedef union sh_xn_md_iilb_cmp_enable1_u {
+	mmr_t	sh_xn_md_iilb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_iilb_cmp_enable1_s;
+} sh_xn_md_iilb_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_NI0_CMP_EXP_DATA0"                 */
+/*                 MD compare NI0 input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_ni0_cmp_exp_data0_u {
+	mmr_t	sh_xn_md_ni0_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_ni0_cmp_exp_data0_s;
+} sh_xn_md_ni0_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_md_ni0_cmp_exp_data0_u {
+	mmr_t	sh_xn_md_ni0_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_ni0_cmp_exp_data0_s;
+} sh_xn_md_ni0_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_NI0_CMP_EXP_DATA1"                 */
+/*                 MD compare NI0 input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_ni0_cmp_exp_data1_u {
+	mmr_t	sh_xn_md_ni0_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_ni0_cmp_exp_data1_s;
+} sh_xn_md_ni0_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_md_ni0_cmp_exp_data1_u {
+	mmr_t	sh_xn_md_ni0_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_ni0_cmp_exp_data1_s;
+} sh_xn_md_ni0_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_NI0_CMP_ENABLE0"                  */
+/*                     MD compare NI0 input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_ni0_cmp_enable0_u {
+	mmr_t	sh_xn_md_ni0_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_ni0_cmp_enable0_s;
+} sh_xn_md_ni0_cmp_enable0_u_t;
+#else
+typedef union sh_xn_md_ni0_cmp_enable0_u {
+	mmr_t	sh_xn_md_ni0_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_ni0_cmp_enable0_s;
+} sh_xn_md_ni0_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_NI0_CMP_ENABLE1"                  */
+/*                     MD compare NI0 input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_ni0_cmp_enable1_u {
+	mmr_t	sh_xn_md_ni0_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_ni0_cmp_enable1_s;
+} sh_xn_md_ni0_cmp_enable1_u_t;
+#else
+typedef union sh_xn_md_ni0_cmp_enable1_u {
+	mmr_t	sh_xn_md_ni0_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_ni0_cmp_enable1_s;
+} sh_xn_md_ni0_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_NI1_CMP_EXP_DATA0"                 */
+/*                 MD compare NI1 input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_ni1_cmp_exp_data0_u {
+	mmr_t	sh_xn_md_ni1_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_ni1_cmp_exp_data0_s;
+} sh_xn_md_ni1_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_md_ni1_cmp_exp_data0_u {
+	mmr_t	sh_xn_md_ni1_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_ni1_cmp_exp_data0_s;
+} sh_xn_md_ni1_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_MD_NI1_CMP_EXP_DATA1"                 */
+/*                 MD compare NI1 input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_ni1_cmp_exp_data1_u {
+	mmr_t	sh_xn_md_ni1_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_ni1_cmp_exp_data1_s;
+} sh_xn_md_ni1_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_md_ni1_cmp_exp_data1_u {
+	mmr_t	sh_xn_md_ni1_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_ni1_cmp_exp_data1_s;
+} sh_xn_md_ni1_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_NI1_CMP_ENABLE0"                  */
+/*                     MD compare NI1 input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_ni1_cmp_enable0_u {
+	mmr_t	sh_xn_md_ni1_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_ni1_cmp_enable0_s;
+} sh_xn_md_ni1_cmp_enable0_u_t;
+#else
+typedef union sh_xn_md_ni1_cmp_enable0_u {
+	mmr_t	sh_xn_md_ni1_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_ni1_cmp_enable0_s;
+} sh_xn_md_ni1_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_NI1_CMP_ENABLE1"                  */
+/*                     MD compare NI1 input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_ni1_cmp_enable1_u {
+	mmr_t	sh_xn_md_ni1_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_ni1_cmp_enable1_s;
+} sh_xn_md_ni1_cmp_enable1_u_t;
+#else
+typedef union sh_xn_md_ni1_cmp_enable1_u {
+	mmr_t	sh_xn_md_ni1_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_ni1_cmp_enable1_s;
+} sh_xn_md_ni1_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_SIC_CMP_EXP_HDR0"                 */
+/*                MD compare SIC input expected header0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_exp_hdr0_u {
+	mmr_t	sh_xn_md_sic_cmp_exp_hdr0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_sic_cmp_exp_hdr0_s;
+} sh_xn_md_sic_cmp_exp_hdr0_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_exp_hdr0_u {
+	mmr_t	sh_xn_md_sic_cmp_exp_hdr0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_md_sic_cmp_exp_hdr0_s;
+} sh_xn_md_sic_cmp_exp_hdr0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_MD_SIC_CMP_EXP_HDR1"                 */
+/*                MD compare SIC input expected header1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_exp_hdr1_u {
+	mmr_t	sh_xn_md_sic_cmp_exp_hdr1_regval;
+	struct {
+		mmr_t	data        : 42;
+		mmr_t	reserved_0  : 22;
+	} sh_xn_md_sic_cmp_exp_hdr1_s;
+} sh_xn_md_sic_cmp_exp_hdr1_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_exp_hdr1_u {
+	mmr_t	sh_xn_md_sic_cmp_exp_hdr1_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	data        : 42;
+	} sh_xn_md_sic_cmp_exp_hdr1_s;
+} sh_xn_md_sic_cmp_exp_hdr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_HDR_ENABLE0"                */
+/*                    MD compare SIC header enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_hdr_enable0_u {
+	mmr_t	sh_xn_md_sic_cmp_hdr_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_sic_cmp_hdr_enable0_s;
+} sh_xn_md_sic_cmp_hdr_enable0_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_hdr_enable0_u {
+	mmr_t	sh_xn_md_sic_cmp_hdr_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_md_sic_cmp_hdr_enable0_s;
+} sh_xn_md_sic_cmp_hdr_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_HDR_ENABLE1"                */
+/*                    MD compare SIC header enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_hdr_enable1_u {
+	mmr_t	sh_xn_md_sic_cmp_hdr_enable1_regval;
+	struct {
+		mmr_t	enable      : 42;
+		mmr_t	reserved_0  : 22;
+	} sh_xn_md_sic_cmp_hdr_enable1_s;
+} sh_xn_md_sic_cmp_hdr_enable1_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_hdr_enable1_u {
+	mmr_t	sh_xn_md_sic_cmp_hdr_enable1_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	enable      : 42;
+	} sh_xn_md_sic_cmp_hdr_enable1_s;
+} sh_xn_md_sic_cmp_hdr_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_MD_SIC_CMP_DATA0"                   */
+/*                         MD compare SIC data0                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_data0_u {
+	mmr_t	sh_xn_md_sic_cmp_data0_regval;
+	struct {
+		mmr_t	data0       : 64;
+	} sh_xn_md_sic_cmp_data0_s;
+} sh_xn_md_sic_cmp_data0_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_data0_u {
+	mmr_t	sh_xn_md_sic_cmp_data0_regval;
+	struct {
+		mmr_t	data0       : 64;
+	} sh_xn_md_sic_cmp_data0_s;
+} sh_xn_md_sic_cmp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_MD_SIC_CMP_DATA1"                   */
+/*                         MD compare SIC data1                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_data1_u {
+	mmr_t	sh_xn_md_sic_cmp_data1_regval;
+	struct {
+		mmr_t	data1       : 64;
+	} sh_xn_md_sic_cmp_data1_s;
+} sh_xn_md_sic_cmp_data1_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_data1_u {
+	mmr_t	sh_xn_md_sic_cmp_data1_regval;
+	struct {
+		mmr_t	data1       : 64;
+	} sh_xn_md_sic_cmp_data1_s;
+} sh_xn_md_sic_cmp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_MD_SIC_CMP_DATA2"                   */
+/*                         MD compare SIC data2                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_data2_u {
+	mmr_t	sh_xn_md_sic_cmp_data2_regval;
+	struct {
+		mmr_t	data2       : 64;
+	} sh_xn_md_sic_cmp_data2_s;
+} sh_xn_md_sic_cmp_data2_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_data2_u {
+	mmr_t	sh_xn_md_sic_cmp_data2_regval;
+	struct {
+		mmr_t	data2       : 64;
+	} sh_xn_md_sic_cmp_data2_s;
+} sh_xn_md_sic_cmp_data2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_MD_SIC_CMP_DATA3"                   */
+/*                         MD compare SIC data3                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_data3_u {
+	mmr_t	sh_xn_md_sic_cmp_data3_regval;
+	struct {
+		mmr_t	data3       : 64;
+	} sh_xn_md_sic_cmp_data3_s;
+} sh_xn_md_sic_cmp_data3_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_data3_u {
+	mmr_t	sh_xn_md_sic_cmp_data3_regval;
+	struct {
+		mmr_t	data3       : 64;
+	} sh_xn_md_sic_cmp_data3_s;
+} sh_xn_md_sic_cmp_data3_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE0"               */
+/*                     MD enable compare SIC data0                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_data_enable0_u {
+	mmr_t	sh_xn_md_sic_cmp_data_enable0_regval;
+	struct {
+		mmr_t	data_enable0 : 64;
+	} sh_xn_md_sic_cmp_data_enable0_s;
+} sh_xn_md_sic_cmp_data_enable0_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_data_enable0_u {
+	mmr_t	sh_xn_md_sic_cmp_data_enable0_regval;
+	struct {
+		mmr_t	data_enable0 : 64;
+	} sh_xn_md_sic_cmp_data_enable0_s;
+} sh_xn_md_sic_cmp_data_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE1"               */
+/*                     MD enable compare SIC data1                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_data_enable1_u {
+	mmr_t	sh_xn_md_sic_cmp_data_enable1_regval;
+	struct {
+		mmr_t	data_enable1 : 64;
+	} sh_xn_md_sic_cmp_data_enable1_s;
+} sh_xn_md_sic_cmp_data_enable1_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_data_enable1_u {
+	mmr_t	sh_xn_md_sic_cmp_data_enable1_regval;
+	struct {
+		mmr_t	data_enable1 : 64;
+	} sh_xn_md_sic_cmp_data_enable1_s;
+} sh_xn_md_sic_cmp_data_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE2"               */
+/*                     MD enable compare SIC data2                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_data_enable2_u {
+	mmr_t	sh_xn_md_sic_cmp_data_enable2_regval;
+	struct {
+		mmr_t	data_enable2 : 64;
+	} sh_xn_md_sic_cmp_data_enable2_s;
+} sh_xn_md_sic_cmp_data_enable2_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_data_enable2_u {
+	mmr_t	sh_xn_md_sic_cmp_data_enable2_regval;
+	struct {
+		mmr_t	data_enable2 : 64;
+	} sh_xn_md_sic_cmp_data_enable2_s;
+} sh_xn_md_sic_cmp_data_enable2_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE3"               */
+/*                     MD enable compare SIC data3                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_sic_cmp_data_enable3_u {
+	mmr_t	sh_xn_md_sic_cmp_data_enable3_regval;
+	struct {
+		mmr_t	data_enable3 : 64;
+	} sh_xn_md_sic_cmp_data_enable3_s;
+} sh_xn_md_sic_cmp_data_enable3_u_t;
+#else
+typedef union sh_xn_md_sic_cmp_data_enable3_u {
+	mmr_t	sh_xn_md_sic_cmp_data_enable3_regval;
+	struct {
+		mmr_t	data_enable3 : 64;
+	} sh_xn_md_sic_cmp_data_enable3_s;
+} sh_xn_md_sic_cmp_data_enable3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_IILB_CMP_EXP_DATA0"                */
+/*                 PI compare IILB input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_iilb_cmp_exp_data0_u {
+	mmr_t	sh_xn_pi_iilb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_iilb_cmp_exp_data0_s;
+} sh_xn_pi_iilb_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_pi_iilb_cmp_exp_data0_u {
+	mmr_t	sh_xn_pi_iilb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_iilb_cmp_exp_data0_s;
+} sh_xn_pi_iilb_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_IILB_CMP_EXP_DATA1"                */
+/*                 PI compare IILB input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_iilb_cmp_exp_data1_u {
+	mmr_t	sh_xn_pi_iilb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_iilb_cmp_exp_data1_s;
+} sh_xn_pi_iilb_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_pi_iilb_cmp_exp_data1_u {
+	mmr_t	sh_xn_pi_iilb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_iilb_cmp_exp_data1_s;
+} sh_xn_pi_iilb_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_IILB_CMP_ENABLE0"                 */
+/*                    PI compare IILB input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_iilb_cmp_enable0_u {
+	mmr_t	sh_xn_pi_iilb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_iilb_cmp_enable0_s;
+} sh_xn_pi_iilb_cmp_enable0_u_t;
+#else
+typedef union sh_xn_pi_iilb_cmp_enable0_u {
+	mmr_t	sh_xn_pi_iilb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_iilb_cmp_enable0_s;
+} sh_xn_pi_iilb_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_IILB_CMP_ENABLE1"                 */
+/*                    PI compare IILB input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_iilb_cmp_enable1_u {
+	mmr_t	sh_xn_pi_iilb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_iilb_cmp_enable1_s;
+} sh_xn_pi_iilb_cmp_enable1_u_t;
+#else
+typedef union sh_xn_pi_iilb_cmp_enable1_u {
+	mmr_t	sh_xn_pi_iilb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_iilb_cmp_enable1_s;
+} sh_xn_pi_iilb_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_NI0_CMP_EXP_DATA0"                 */
+/*                 PI compare NI0 input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_ni0_cmp_exp_data0_u {
+	mmr_t	sh_xn_pi_ni0_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_ni0_cmp_exp_data0_s;
+} sh_xn_pi_ni0_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_pi_ni0_cmp_exp_data0_u {
+	mmr_t	sh_xn_pi_ni0_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_ni0_cmp_exp_data0_s;
+} sh_xn_pi_ni0_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_NI0_CMP_EXP_DATA1"                 */
+/*                 PI compare NI0 input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_ni0_cmp_exp_data1_u {
+	mmr_t	sh_xn_pi_ni0_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_ni0_cmp_exp_data1_s;
+} sh_xn_pi_ni0_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_pi_ni0_cmp_exp_data1_u {
+	mmr_t	sh_xn_pi_ni0_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_ni0_cmp_exp_data1_s;
+} sh_xn_pi_ni0_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_NI0_CMP_ENABLE0"                  */
+/*                     PI compare NI0 input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_ni0_cmp_enable0_u {
+	mmr_t	sh_xn_pi_ni0_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_ni0_cmp_enable0_s;
+} sh_xn_pi_ni0_cmp_enable0_u_t;
+#else
+typedef union sh_xn_pi_ni0_cmp_enable0_u {
+	mmr_t	sh_xn_pi_ni0_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_ni0_cmp_enable0_s;
+} sh_xn_pi_ni0_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_NI0_CMP_ENABLE1"                  */
+/*                     PI compare NI0 input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_ni0_cmp_enable1_u {
+	mmr_t	sh_xn_pi_ni0_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_ni0_cmp_enable1_s;
+} sh_xn_pi_ni0_cmp_enable1_u_t;
+#else
+typedef union sh_xn_pi_ni0_cmp_enable1_u {
+	mmr_t	sh_xn_pi_ni0_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_ni0_cmp_enable1_s;
+} sh_xn_pi_ni0_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_NI1_CMP_EXP_DATA0"                 */
+/*                 PI compare NI1 input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_ni1_cmp_exp_data0_u {
+	mmr_t	sh_xn_pi_ni1_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_ni1_cmp_exp_data0_s;
+} sh_xn_pi_ni1_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_pi_ni1_cmp_exp_data0_u {
+	mmr_t	sh_xn_pi_ni1_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_ni1_cmp_exp_data0_s;
+} sh_xn_pi_ni1_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_PI_NI1_CMP_EXP_DATA1"                 */
+/*                 PI compare NI1 input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_ni1_cmp_exp_data1_u {
+	mmr_t	sh_xn_pi_ni1_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_ni1_cmp_exp_data1_s;
+} sh_xn_pi_ni1_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_pi_ni1_cmp_exp_data1_u {
+	mmr_t	sh_xn_pi_ni1_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_ni1_cmp_exp_data1_s;
+} sh_xn_pi_ni1_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_NI1_CMP_ENABLE0"                  */
+/*                     PI compare NI1 input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_ni1_cmp_enable0_u {
+	mmr_t	sh_xn_pi_ni1_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_ni1_cmp_enable0_s;
+} sh_xn_pi_ni1_cmp_enable0_u_t;
+#else
+typedef union sh_xn_pi_ni1_cmp_enable0_u {
+	mmr_t	sh_xn_pi_ni1_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_ni1_cmp_enable0_s;
+} sh_xn_pi_ni1_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_NI1_CMP_ENABLE1"                  */
+/*                     PI compare NI1 input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_ni1_cmp_enable1_u {
+	mmr_t	sh_xn_pi_ni1_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_ni1_cmp_enable1_s;
+} sh_xn_pi_ni1_cmp_enable1_u_t;
+#else
+typedef union sh_xn_pi_ni1_cmp_enable1_u {
+	mmr_t	sh_xn_pi_ni1_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_ni1_cmp_enable1_s;
+} sh_xn_pi_ni1_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_SIC_CMP_EXP_HDR0"                 */
+/*                PI compare SIC input expected header0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_exp_hdr0_u {
+	mmr_t	sh_xn_pi_sic_cmp_exp_hdr0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_sic_cmp_exp_hdr0_s;
+} sh_xn_pi_sic_cmp_exp_hdr0_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_exp_hdr0_u {
+	mmr_t	sh_xn_pi_sic_cmp_exp_hdr0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_pi_sic_cmp_exp_hdr0_s;
+} sh_xn_pi_sic_cmp_exp_hdr0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_PI_SIC_CMP_EXP_HDR1"                 */
+/*                PI compare SIC input expected header1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_exp_hdr1_u {
+	mmr_t	sh_xn_pi_sic_cmp_exp_hdr1_regval;
+	struct {
+		mmr_t	data        : 42;
+		mmr_t	reserved_0  : 22;
+	} sh_xn_pi_sic_cmp_exp_hdr1_s;
+} sh_xn_pi_sic_cmp_exp_hdr1_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_exp_hdr1_u {
+	mmr_t	sh_xn_pi_sic_cmp_exp_hdr1_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	data        : 42;
+	} sh_xn_pi_sic_cmp_exp_hdr1_s;
+} sh_xn_pi_sic_cmp_exp_hdr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_HDR_ENABLE0"                */
+/*                    PI compare SIC header enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_hdr_enable0_u {
+	mmr_t	sh_xn_pi_sic_cmp_hdr_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_sic_cmp_hdr_enable0_s;
+} sh_xn_pi_sic_cmp_hdr_enable0_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_hdr_enable0_u {
+	mmr_t	sh_xn_pi_sic_cmp_hdr_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_pi_sic_cmp_hdr_enable0_s;
+} sh_xn_pi_sic_cmp_hdr_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_HDR_ENABLE1"                */
+/*                    PI compare SIC header enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_hdr_enable1_u {
+	mmr_t	sh_xn_pi_sic_cmp_hdr_enable1_regval;
+	struct {
+		mmr_t	enable      : 42;
+		mmr_t	reserved_0  : 22;
+	} sh_xn_pi_sic_cmp_hdr_enable1_s;
+} sh_xn_pi_sic_cmp_hdr_enable1_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_hdr_enable1_u {
+	mmr_t	sh_xn_pi_sic_cmp_hdr_enable1_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	enable      : 42;
+	} sh_xn_pi_sic_cmp_hdr_enable1_s;
+} sh_xn_pi_sic_cmp_hdr_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_PI_SIC_CMP_DATA0"                   */
+/*                         PI compare SIC data0                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_data0_u {
+	mmr_t	sh_xn_pi_sic_cmp_data0_regval;
+	struct {
+		mmr_t	data0       : 64;
+	} sh_xn_pi_sic_cmp_data0_s;
+} sh_xn_pi_sic_cmp_data0_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_data0_u {
+	mmr_t	sh_xn_pi_sic_cmp_data0_regval;
+	struct {
+		mmr_t	data0       : 64;
+	} sh_xn_pi_sic_cmp_data0_s;
+} sh_xn_pi_sic_cmp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_PI_SIC_CMP_DATA1"                   */
+/*                         PI compare SIC data1                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_data1_u {
+	mmr_t	sh_xn_pi_sic_cmp_data1_regval;
+	struct {
+		mmr_t	data1       : 64;
+	} sh_xn_pi_sic_cmp_data1_s;
+} sh_xn_pi_sic_cmp_data1_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_data1_u {
+	mmr_t	sh_xn_pi_sic_cmp_data1_regval;
+	struct {
+		mmr_t	data1       : 64;
+	} sh_xn_pi_sic_cmp_data1_s;
+} sh_xn_pi_sic_cmp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_PI_SIC_CMP_DATA2"                   */
+/*                         PI compare SIC data2                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_data2_u {
+	mmr_t	sh_xn_pi_sic_cmp_data2_regval;
+	struct {
+		mmr_t	data2       : 64;
+	} sh_xn_pi_sic_cmp_data2_s;
+} sh_xn_pi_sic_cmp_data2_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_data2_u {
+	mmr_t	sh_xn_pi_sic_cmp_data2_regval;
+	struct {
+		mmr_t	data2       : 64;
+	} sh_xn_pi_sic_cmp_data2_s;
+} sh_xn_pi_sic_cmp_data2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_PI_SIC_CMP_DATA3"                   */
+/*                         PI compare SIC data3                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_data3_u {
+	mmr_t	sh_xn_pi_sic_cmp_data3_regval;
+	struct {
+		mmr_t	data3       : 64;
+	} sh_xn_pi_sic_cmp_data3_s;
+} sh_xn_pi_sic_cmp_data3_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_data3_u {
+	mmr_t	sh_xn_pi_sic_cmp_data3_regval;
+	struct {
+		mmr_t	data3       : 64;
+	} sh_xn_pi_sic_cmp_data3_s;
+} sh_xn_pi_sic_cmp_data3_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE0"               */
+/*                     PI enable compare SIC data0                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_data_enable0_u {
+	mmr_t	sh_xn_pi_sic_cmp_data_enable0_regval;
+	struct {
+		mmr_t	data_enable0 : 64;
+	} sh_xn_pi_sic_cmp_data_enable0_s;
+} sh_xn_pi_sic_cmp_data_enable0_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_data_enable0_u {
+	mmr_t	sh_xn_pi_sic_cmp_data_enable0_regval;
+	struct {
+		mmr_t	data_enable0 : 64;
+	} sh_xn_pi_sic_cmp_data_enable0_s;
+} sh_xn_pi_sic_cmp_data_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE1"               */
+/*                     PI enable compare SIC data1                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_data_enable1_u {
+	mmr_t	sh_xn_pi_sic_cmp_data_enable1_regval;
+	struct {
+		mmr_t	data_enable1 : 64;
+	} sh_xn_pi_sic_cmp_data_enable1_s;
+} sh_xn_pi_sic_cmp_data_enable1_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_data_enable1_u {
+	mmr_t	sh_xn_pi_sic_cmp_data_enable1_regval;
+	struct {
+		mmr_t	data_enable1 : 64;
+	} sh_xn_pi_sic_cmp_data_enable1_s;
+} sh_xn_pi_sic_cmp_data_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE2"               */
+/*                     PI enable compare SIC data2                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_data_enable2_u {
+	mmr_t	sh_xn_pi_sic_cmp_data_enable2_regval;
+	struct {
+		mmr_t	data_enable2 : 64;
+	} sh_xn_pi_sic_cmp_data_enable2_s;
+} sh_xn_pi_sic_cmp_data_enable2_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_data_enable2_u {
+	mmr_t	sh_xn_pi_sic_cmp_data_enable2_regval;
+	struct {
+		mmr_t	data_enable2 : 64;
+	} sh_xn_pi_sic_cmp_data_enable2_s;
+} sh_xn_pi_sic_cmp_data_enable2_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE3"               */
+/*                     PI enable compare SIC data3                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_pi_sic_cmp_data_enable3_u {
+	mmr_t	sh_xn_pi_sic_cmp_data_enable3_regval;
+	struct {
+		mmr_t	data_enable3 : 64;
+	} sh_xn_pi_sic_cmp_data_enable3_s;
+} sh_xn_pi_sic_cmp_data_enable3_u_t;
+#else
+typedef union sh_xn_pi_sic_cmp_data_enable3_u {
+	mmr_t	sh_xn_pi_sic_cmp_data_enable3_regval;
+	struct {
+		mmr_t	data_enable3 : 64;
+	} sh_xn_pi_sic_cmp_data_enable3_s;
+} sh_xn_pi_sic_cmp_data_enable3_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_NI0_IILB_CMP_EXP_DATA0"                */
+/*                NI0 compare IILB input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_iilb_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_iilb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_iilb_cmp_exp_data0_s;
+} sh_xn_ni0_iilb_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni0_iilb_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_iilb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_iilb_cmp_exp_data0_s;
+} sh_xn_ni0_iilb_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_NI0_IILB_CMP_EXP_DATA1"                */
+/*                NI0 compare IILB input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_iilb_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_iilb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_iilb_cmp_exp_data1_s;
+} sh_xn_ni0_iilb_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni0_iilb_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_iilb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_iilb_cmp_exp_data1_s;
+} sh_xn_ni0_iilb_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_IILB_CMP_ENABLE0"                 */
+/*                    NI0 compare IILB input enable0                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_iilb_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_iilb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_iilb_cmp_enable0_s;
+} sh_xn_ni0_iilb_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni0_iilb_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_iilb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_iilb_cmp_enable0_s;
+} sh_xn_ni0_iilb_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_IILB_CMP_ENABLE1"                 */
+/*                    NI0 compare IILB input enable1                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_iilb_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_iilb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_iilb_cmp_enable1_s;
+} sh_xn_ni0_iilb_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni0_iilb_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_iilb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_iilb_cmp_enable1_s;
+} sh_xn_ni0_iilb_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_PI_CMP_EXP_DATA0"                 */
+/*                 NI0 compare PI input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_pi_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_pi_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_pi_cmp_exp_data0_s;
+} sh_xn_ni0_pi_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni0_pi_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_pi_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_pi_cmp_exp_data0_s;
+} sh_xn_ni0_pi_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_PI_CMP_EXP_DATA1"                 */
+/*                 NI0 compare PI input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_pi_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_pi_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_pi_cmp_exp_data1_s;
+} sh_xn_ni0_pi_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni0_pi_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_pi_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_pi_cmp_exp_data1_s;
+} sh_xn_ni0_pi_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_PI_CMP_ENABLE0"                  */
+/*                     NI0 compare PI input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_pi_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_pi_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_pi_cmp_enable0_s;
+} sh_xn_ni0_pi_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni0_pi_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_pi_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_pi_cmp_enable0_s;
+} sh_xn_ni0_pi_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_PI_CMP_ENABLE1"                  */
+/*                     NI0 compare PI input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_pi_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_pi_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_pi_cmp_enable1_s;
+} sh_xn_ni0_pi_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni0_pi_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_pi_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_pi_cmp_enable1_s;
+} sh_xn_ni0_pi_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_MD_CMP_EXP_DATA0"                 */
+/*                 NI0 compare MD input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_md_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_md_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_md_cmp_exp_data0_s;
+} sh_xn_ni0_md_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni0_md_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_md_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_md_cmp_exp_data0_s;
+} sh_xn_ni0_md_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_MD_CMP_EXP_DATA1"                 */
+/*                 NI0 compare MD input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_md_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_md_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_md_cmp_exp_data1_s;
+} sh_xn_ni0_md_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni0_md_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_md_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_md_cmp_exp_data1_s;
+} sh_xn_ni0_md_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_MD_CMP_ENABLE0"                  */
+/*                     NI0 compare MD input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_md_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_md_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_md_cmp_enable0_s;
+} sh_xn_ni0_md_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni0_md_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_md_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_md_cmp_enable0_s;
+} sh_xn_ni0_md_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_MD_CMP_ENABLE1"                  */
+/*                     NI0 compare MD input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_md_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_md_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_md_cmp_enable1_s;
+} sh_xn_ni0_md_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni0_md_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_md_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_md_cmp_enable1_s;
+} sh_xn_ni0_md_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_NI_CMP_EXP_DATA0"                 */
+/*                 NI0 compare NI input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_ni_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_ni_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_ni_cmp_exp_data0_s;
+} sh_xn_ni0_ni_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni0_ni_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_ni_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_ni_cmp_exp_data0_s;
+} sh_xn_ni0_ni_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_NI_CMP_EXP_DATA1"                 */
+/*                 NI0 compare NI input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_ni_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_ni_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_ni_cmp_exp_data1_s;
+} sh_xn_ni0_ni_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni0_ni_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_ni_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_ni_cmp_exp_data1_s;
+} sh_xn_ni0_ni_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_NI_CMP_ENABLE0"                  */
+/*                     NI0 compare NI input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_ni_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_ni_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_ni_cmp_enable0_s;
+} sh_xn_ni0_ni_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni0_ni_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_ni_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_ni_cmp_enable0_s;
+} sh_xn_ni0_ni_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_NI_CMP_ENABLE1"                  */
+/*                     NI0 compare NI input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_ni_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_ni_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_ni_cmp_enable1_s;
+} sh_xn_ni0_ni_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni0_ni_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_ni_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_ni_cmp_enable1_s;
+} sh_xn_ni0_ni_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_LLP_CMP_EXP_DATA0"                */
+/*                 NI0 compare LLP input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_llp_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_llp_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_llp_cmp_exp_data0_s;
+} sh_xn_ni0_llp_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni0_llp_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni0_llp_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_llp_cmp_exp_data0_s;
+} sh_xn_ni0_llp_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI0_LLP_CMP_EXP_DATA1"                */
+/*                 NI0 compare LLP input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_llp_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_llp_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_llp_cmp_exp_data1_s;
+} sh_xn_ni0_llp_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni0_llp_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni0_llp_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni0_llp_cmp_exp_data1_s;
+} sh_xn_ni0_llp_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_LLP_CMP_ENABLE0"                 */
+/*                    NI0 compare LLP input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_llp_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_llp_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_llp_cmp_enable0_s;
+} sh_xn_ni0_llp_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni0_llp_cmp_enable0_u {
+	mmr_t	sh_xn_ni0_llp_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_llp_cmp_enable0_s;
+} sh_xn_ni0_llp_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI0_LLP_CMP_ENABLE1"                 */
+/*                    NI0 compare LLP input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni0_llp_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_llp_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_llp_cmp_enable1_s;
+} sh_xn_ni0_llp_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni0_llp_cmp_enable1_u {
+	mmr_t	sh_xn_ni0_llp_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni0_llp_cmp_enable1_s;
+} sh_xn_ni0_llp_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_NI1_IILB_CMP_EXP_DATA0"                */
+/*                NI1 compare IILB input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_iilb_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_iilb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_iilb_cmp_exp_data0_s;
+} sh_xn_ni1_iilb_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni1_iilb_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_iilb_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_iilb_cmp_exp_data0_s;
+} sh_xn_ni1_iilb_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_XN_NI1_IILB_CMP_EXP_DATA1"                */
+/*                NI1 compare IILB input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_iilb_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_iilb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_iilb_cmp_exp_data1_s;
+} sh_xn_ni1_iilb_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni1_iilb_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_iilb_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_iilb_cmp_exp_data1_s;
+} sh_xn_ni1_iilb_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_IILB_CMP_ENABLE0"                 */
+/*                    NI1 compare IILB input enable0                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_iilb_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_iilb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_iilb_cmp_enable0_s;
+} sh_xn_ni1_iilb_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni1_iilb_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_iilb_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_iilb_cmp_enable0_s;
+} sh_xn_ni1_iilb_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_IILB_CMP_ENABLE1"                 */
+/*                    NI1 compare IILB input enable1                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_iilb_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_iilb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_iilb_cmp_enable1_s;
+} sh_xn_ni1_iilb_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni1_iilb_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_iilb_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_iilb_cmp_enable1_s;
+} sh_xn_ni1_iilb_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_PI_CMP_EXP_DATA0"                 */
+/*                 NI1 compare PI input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_pi_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_pi_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_pi_cmp_exp_data0_s;
+} sh_xn_ni1_pi_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni1_pi_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_pi_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_pi_cmp_exp_data0_s;
+} sh_xn_ni1_pi_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_PI_CMP_EXP_DATA1"                 */
+/*                 NI1 compare PI input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_pi_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_pi_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_pi_cmp_exp_data1_s;
+} sh_xn_ni1_pi_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni1_pi_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_pi_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_pi_cmp_exp_data1_s;
+} sh_xn_ni1_pi_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_PI_CMP_ENABLE0"                  */
+/*                     NI1 compare PI input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_pi_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_pi_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_pi_cmp_enable0_s;
+} sh_xn_ni1_pi_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni1_pi_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_pi_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_pi_cmp_enable0_s;
+} sh_xn_ni1_pi_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_PI_CMP_ENABLE1"                  */
+/*                     NI1 compare PI input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_pi_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_pi_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_pi_cmp_enable1_s;
+} sh_xn_ni1_pi_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni1_pi_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_pi_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_pi_cmp_enable1_s;
+} sh_xn_ni1_pi_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_MD_CMP_EXP_DATA0"                 */
+/*                 NI1 compare MD input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_md_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_md_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_md_cmp_exp_data0_s;
+} sh_xn_ni1_md_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni1_md_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_md_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_md_cmp_exp_data0_s;
+} sh_xn_ni1_md_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_MD_CMP_EXP_DATA1"                 */
+/*                 NI1 compare MD input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_md_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_md_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_md_cmp_exp_data1_s;
+} sh_xn_ni1_md_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni1_md_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_md_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_md_cmp_exp_data1_s;
+} sh_xn_ni1_md_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_MD_CMP_ENABLE0"                  */
+/*                     NI1 compare MD input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_md_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_md_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_md_cmp_enable0_s;
+} sh_xn_ni1_md_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni1_md_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_md_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_md_cmp_enable0_s;
+} sh_xn_ni1_md_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_MD_CMP_ENABLE1"                  */
+/*                     NI1 compare MD input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_md_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_md_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_md_cmp_enable1_s;
+} sh_xn_ni1_md_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni1_md_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_md_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_md_cmp_enable1_s;
+} sh_xn_ni1_md_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_NI_CMP_EXP_DATA0"                 */
+/*                 NI1 compare NI input expected data0                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_ni_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_ni_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_ni_cmp_exp_data0_s;
+} sh_xn_ni1_ni_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni1_ni_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_ni_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_ni_cmp_exp_data0_s;
+} sh_xn_ni1_ni_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_NI_CMP_EXP_DATA1"                 */
+/*                 NI1 compare NI input expected data1                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_ni_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_ni_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_ni_cmp_exp_data1_s;
+} sh_xn_ni1_ni_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni1_ni_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_ni_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_ni_cmp_exp_data1_s;
+} sh_xn_ni1_ni_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_NI_CMP_ENABLE0"                  */
+/*                     NI1 compare NI input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_ni_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_ni_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_ni_cmp_enable0_s;
+} sh_xn_ni1_ni_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni1_ni_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_ni_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_ni_cmp_enable0_s;
+} sh_xn_ni1_ni_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_NI_CMP_ENABLE1"                  */
+/*                     NI1 compare NI input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_ni_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_ni_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_ni_cmp_enable1_s;
+} sh_xn_ni1_ni_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni1_ni_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_ni_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_ni_cmp_enable1_s;
+} sh_xn_ni1_ni_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_LLP_CMP_EXP_DATA0"                */
+/*                 NI1 compare LLP input expected data0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_llp_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_llp_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_llp_cmp_exp_data0_s;
+} sh_xn_ni1_llp_cmp_exp_data0_u_t;
+#else
+typedef union sh_xn_ni1_llp_cmp_exp_data0_u {
+	mmr_t	sh_xn_ni1_llp_cmp_exp_data0_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_llp_cmp_exp_data0_s;
+} sh_xn_ni1_llp_cmp_exp_data0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_NI1_LLP_CMP_EXP_DATA1"                */
+/*                 NI1 compare LLP input expected data1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_llp_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_llp_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_llp_cmp_exp_data1_s;
+} sh_xn_ni1_llp_cmp_exp_data1_u_t;
+#else
+typedef union sh_xn_ni1_llp_cmp_exp_data1_u {
+	mmr_t	sh_xn_ni1_llp_cmp_exp_data1_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_ni1_llp_cmp_exp_data1_s;
+} sh_xn_ni1_llp_cmp_exp_data1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_LLP_CMP_ENABLE0"                 */
+/*                    NI1 compare LLP input enable0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_llp_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_llp_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_llp_cmp_enable0_s;
+} sh_xn_ni1_llp_cmp_enable0_u_t;
+#else
+typedef union sh_xn_ni1_llp_cmp_enable0_u {
+	mmr_t	sh_xn_ni1_llp_cmp_enable0_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_llp_cmp_enable0_s;
+} sh_xn_ni1_llp_cmp_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_NI1_LLP_CMP_ENABLE1"                 */
+/*                    NI1 compare LLP input enable1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_ni1_llp_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_llp_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_llp_cmp_enable1_s;
+} sh_xn_ni1_llp_cmp_enable1_u_t;
+#else
+typedef union sh_xn_ni1_llp_cmp_enable1_u {
+	mmr_t	sh_xn_ni1_llp_cmp_enable1_regval;
+	struct {
+		mmr_t	enable      : 64;
+	} sh_xn_ni1_llp_cmp_enable1_s;
+} sh_xn_ni1_llp_cmp_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNPI_ECC_INJ_REG"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_ecc_inj_reg_u {
+	mmr_t	sh_xnpi_ecc_inj_reg_regval;
+	struct {
+		mmr_t	byte0          : 8;
+		mmr_t	reserved_0     : 4;
+		mmr_t	data_1shot0    : 1;
+		mmr_t	data_cont0     : 1;
+		mmr_t	data_cb_1shot0 : 1;
+		mmr_t	data_cb_cont0  : 1;
+		mmr_t	byte1          : 8;
+		mmr_t	reserved_1     : 4;
+		mmr_t	data_1shot1    : 1;
+		mmr_t	data_cont1     : 1;
+		mmr_t	data_cb_1shot1 : 1;
+		mmr_t	data_cb_cont1  : 1;
+		mmr_t	byte2          : 8;
+		mmr_t	reserved_2     : 4;
+		mmr_t	data_1shot2    : 1;
+		mmr_t	data_cont2     : 1;
+		mmr_t	data_cb_1shot2 : 1;
+		mmr_t	data_cb_cont2  : 1;
+		mmr_t	byte3          : 8;
+		mmr_t	reserved_3     : 4;
+		mmr_t	data_1shot3    : 1;
+		mmr_t	data_cont3     : 1;
+		mmr_t	data_cb_1shot3 : 1;
+		mmr_t	data_cb_cont3  : 1;
+	} sh_xnpi_ecc_inj_reg_s;
+} sh_xnpi_ecc_inj_reg_u_t;
+#else
+typedef union sh_xnpi_ecc_inj_reg_u {
+	mmr_t	sh_xnpi_ecc_inj_reg_regval;
+	struct {
+		mmr_t	data_cb_cont3  : 1;
+		mmr_t	data_cb_1shot3 : 1;
+		mmr_t	data_cont3     : 1;
+		mmr_t	data_1shot3    : 1;
+		mmr_t	reserved_3     : 4;
+		mmr_t	byte3          : 8;
+		mmr_t	data_cb_cont2  : 1;
+		mmr_t	data_cb_1shot2 : 1;
+		mmr_t	data_cont2     : 1;
+		mmr_t	data_1shot2    : 1;
+		mmr_t	reserved_2     : 4;
+		mmr_t	byte2          : 8;
+		mmr_t	data_cb_cont1  : 1;
+		mmr_t	data_cb_1shot1 : 1;
+		mmr_t	data_cont1     : 1;
+		mmr_t	data_1shot1    : 1;
+		mmr_t	reserved_1     : 4;
+		mmr_t	byte1          : 8;
+		mmr_t	data_cb_cont0  : 1;
+		mmr_t	data_cb_1shot0 : 1;
+		mmr_t	data_cont0     : 1;
+		mmr_t	data_1shot0    : 1;
+		mmr_t	reserved_0     : 4;
+		mmr_t	byte0          : 8;
+	} sh_xnpi_ecc_inj_reg_s;
+} sh_xnpi_ecc_inj_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_ECC0_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_ecc0_inj_mask_reg_u {
+	mmr_t	sh_xnpi_ecc0_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc0   : 64;
+	} sh_xnpi_ecc0_inj_mask_reg_s;
+} sh_xnpi_ecc0_inj_mask_reg_u_t;
+#else
+typedef union sh_xnpi_ecc0_inj_mask_reg_u {
+	mmr_t	sh_xnpi_ecc0_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc0   : 64;
+	} sh_xnpi_ecc0_inj_mask_reg_s;
+} sh_xnpi_ecc0_inj_mask_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_ECC1_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_ecc1_inj_mask_reg_u {
+	mmr_t	sh_xnpi_ecc1_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc1   : 64;
+	} sh_xnpi_ecc1_inj_mask_reg_s;
+} sh_xnpi_ecc1_inj_mask_reg_u_t;
+#else
+typedef union sh_xnpi_ecc1_inj_mask_reg_u {
+	mmr_t	sh_xnpi_ecc1_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc1   : 64;
+	} sh_xnpi_ecc1_inj_mask_reg_s;
+} sh_xnpi_ecc1_inj_mask_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_ECC2_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_ecc2_inj_mask_reg_u {
+	mmr_t	sh_xnpi_ecc2_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc2   : 64;
+	} sh_xnpi_ecc2_inj_mask_reg_s;
+} sh_xnpi_ecc2_inj_mask_reg_u_t;
+#else
+typedef union sh_xnpi_ecc2_inj_mask_reg_u {
+	mmr_t	sh_xnpi_ecc2_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc2   : 64;
+	} sh_xnpi_ecc2_inj_mask_reg_s;
+} sh_xnpi_ecc2_inj_mask_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNPI_ECC3_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_ecc3_inj_mask_reg_u {
+	mmr_t	sh_xnpi_ecc3_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc3   : 64;
+	} sh_xnpi_ecc3_inj_mask_reg_s;
+} sh_xnpi_ecc3_inj_mask_reg_u_t;
+#else
+typedef union sh_xnpi_ecc3_inj_mask_reg_u {
+	mmr_t	sh_xnpi_ecc3_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc3   : 64;
+	} sh_xnpi_ecc3_inj_mask_reg_s;
+} sh_xnpi_ecc3_inj_mask_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNMD_ECC_INJ_REG"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_ecc_inj_reg_u {
+	mmr_t	sh_xnmd_ecc_inj_reg_regval;
+	struct {
+		mmr_t	byte0          : 8;
+		mmr_t	reserved_0     : 4;
+		mmr_t	data_1shot0    : 1;
+		mmr_t	data_cont0     : 1;
+		mmr_t	data_cb_1shot0 : 1;
+		mmr_t	data_cb_cont0  : 1;
+		mmr_t	byte1          : 8;
+		mmr_t	reserved_1     : 4;
+		mmr_t	data_1shot1    : 1;
+		mmr_t	data_cont1     : 1;
+		mmr_t	data_cb_1shot1 : 1;
+		mmr_t	data_cb_cont1  : 1;
+		mmr_t	byte2          : 8;
+		mmr_t	reserved_2     : 4;
+		mmr_t	data_1shot2    : 1;
+		mmr_t	data_cont2     : 1;
+		mmr_t	data_cb_1shot2 : 1;
+		mmr_t	data_cb_cont2  : 1;
+		mmr_t	byte3          : 8;
+		mmr_t	reserved_3     : 4;
+		mmr_t	data_1shot3    : 1;
+		mmr_t	data_cont3     : 1;
+		mmr_t	data_cb_1shot3 : 1;
+		mmr_t	data_cb_cont3  : 1;
+	} sh_xnmd_ecc_inj_reg_s;
+} sh_xnmd_ecc_inj_reg_u_t;
+#else
+typedef union sh_xnmd_ecc_inj_reg_u {
+	mmr_t	sh_xnmd_ecc_inj_reg_regval;
+	struct {
+		mmr_t	data_cb_cont3  : 1;
+		mmr_t	data_cb_1shot3 : 1;
+		mmr_t	data_cont3     : 1;
+		mmr_t	data_1shot3    : 1;
+		mmr_t	reserved_3     : 4;
+		mmr_t	byte3          : 8;
+		mmr_t	data_cb_cont2  : 1;
+		mmr_t	data_cb_1shot2 : 1;
+		mmr_t	data_cont2     : 1;
+		mmr_t	data_1shot2    : 1;
+		mmr_t	reserved_2     : 4;
+		mmr_t	byte2          : 8;
+		mmr_t	data_cb_cont1  : 1;
+		mmr_t	data_cb_1shot1 : 1;
+		mmr_t	data_cont1     : 1;
+		mmr_t	data_1shot1    : 1;
+		mmr_t	reserved_1     : 4;
+		mmr_t	byte1          : 8;
+		mmr_t	data_cb_cont0  : 1;
+		mmr_t	data_cb_1shot0 : 1;
+		mmr_t	data_cont0     : 1;
+		mmr_t	data_1shot0    : 1;
+		mmr_t	reserved_0     : 4;
+		mmr_t	byte0          : 8;
+	} sh_xnmd_ecc_inj_reg_s;
+} sh_xnmd_ecc_inj_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_ECC0_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_ecc0_inj_mask_reg_u {
+	mmr_t	sh_xnmd_ecc0_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc0   : 64;
+	} sh_xnmd_ecc0_inj_mask_reg_s;
+} sh_xnmd_ecc0_inj_mask_reg_u_t;
+#else
+typedef union sh_xnmd_ecc0_inj_mask_reg_u {
+	mmr_t	sh_xnmd_ecc0_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc0   : 64;
+	} sh_xnmd_ecc0_inj_mask_reg_s;
+} sh_xnmd_ecc0_inj_mask_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_ECC1_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_ecc1_inj_mask_reg_u {
+	mmr_t	sh_xnmd_ecc1_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc1   : 64;
+	} sh_xnmd_ecc1_inj_mask_reg_s;
+} sh_xnmd_ecc1_inj_mask_reg_u_t;
+#else
+typedef union sh_xnmd_ecc1_inj_mask_reg_u {
+	mmr_t	sh_xnmd_ecc1_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc1   : 64;
+	} sh_xnmd_ecc1_inj_mask_reg_s;
+} sh_xnmd_ecc1_inj_mask_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_ECC2_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_ecc2_inj_mask_reg_u {
+	mmr_t	sh_xnmd_ecc2_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc2   : 64;
+	} sh_xnmd_ecc2_inj_mask_reg_s;
+} sh_xnmd_ecc2_inj_mask_reg_u_t;
+#else
+typedef union sh_xnmd_ecc2_inj_mask_reg_u {
+	mmr_t	sh_xnmd_ecc2_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc2   : 64;
+	} sh_xnmd_ecc2_inj_mask_reg_s;
+} sh_xnmd_ecc2_inj_mask_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNMD_ECC3_INJ_MASK_REG"                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_ecc3_inj_mask_reg_u {
+	mmr_t	sh_xnmd_ecc3_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc3   : 64;
+	} sh_xnmd_ecc3_inj_mask_reg_s;
+} sh_xnmd_ecc3_inj_mask_reg_u_t;
+#else
+typedef union sh_xnmd_ecc3_inj_mask_reg_u {
+	mmr_t	sh_xnmd_ecc3_inj_mask_reg_regval;
+	struct {
+		mmr_t	mask_ecc3   : 64;
+	} sh_xnmd_ecc3_inj_mask_reg_s;
+} sh_xnmd_ecc3_inj_mask_reg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNMD_ECC_ERR_REPORT"                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_ecc_err_report_u {
+	mmr_t	sh_xnmd_ecc_err_report_regval;
+	struct {
+		mmr_t	ecc_disable0 : 1;
+		mmr_t	reserved_0   : 15;
+		mmr_t	ecc_disable1 : 1;
+		mmr_t	reserved_1   : 15;
+		mmr_t	ecc_disable2 : 1;
+		mmr_t	reserved_2   : 15;
+		mmr_t	ecc_disable3 : 1;
+		mmr_t	reserved_3   : 15;
+	} sh_xnmd_ecc_err_report_s;
+} sh_xnmd_ecc_err_report_u_t;
+#else
+typedef union sh_xnmd_ecc_err_report_u {
+	mmr_t	sh_xnmd_ecc_err_report_regval;
+	struct {
+		mmr_t	reserved_3   : 15;
+		mmr_t	ecc_disable3 : 1;
+		mmr_t	reserved_2   : 15;
+		mmr_t	ecc_disable2 : 1;
+		mmr_t	reserved_1   : 15;
+		mmr_t	ecc_disable1 : 1;
+		mmr_t	reserved_0   : 15;
+		mmr_t	ecc_disable0 : 1;
+	} sh_xnmd_ecc_err_report_s;
+} sh_xnmd_ecc_err_report_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_ERROR_SUMMARY_1"                   */
+/*                       ni0  Error Summary Bits                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_summary_1_u {
+	mmr_t	sh_ni0_error_summary_1_regval;
+	struct {
+		mmr_t	overflow_fifo02_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc3           : 1;
+	} sh_ni0_error_summary_1_s;
+} sh_ni0_error_summary_1_u_t;
+#else
+typedef union sh_ni0_error_summary_1_u {
+	mmr_t	sh_ni0_error_summary_1_regval;
+	struct {
+		mmr_t	tail_timeout_ni_vc3           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo02_debit0        : 1;
+	} sh_ni0_error_summary_1_s;
+} sh_ni0_error_summary_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_ERROR_SUMMARY_2"                   */
+/*                       ni0  Error Summary Bits                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_summary_2_u {
+	mmr_t	sh_ni0_error_summary_2_regval;
+	struct {
+		mmr_t	illegal_vcni                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	reserved_1                     : 1;
+	} sh_ni0_error_summary_2_s;
+} sh_ni0_error_summary_2_u_t;
+#else
+typedef union sh_ni0_error_summary_2_u {
+	mmr_t	sh_ni0_error_summary_2_regval;
+	struct {
+		mmr_t	reserved_1                     : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcni                   : 1;
+	} sh_ni0_error_summary_2_s;
+} sh_ni0_error_summary_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_ERROR_OVERFLOW_1"                  */
+/*                       ni0  Error Overflow Bits                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_overflow_1_u {
+	mmr_t	sh_ni0_error_overflow_1_regval;
+	struct {
+		mmr_t	overflow_fifo02_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc3           : 1;
+	} sh_ni0_error_overflow_1_s;
+} sh_ni0_error_overflow_1_u_t;
+#else
+typedef union sh_ni0_error_overflow_1_u {
+	mmr_t	sh_ni0_error_overflow_1_regval;
+	struct {
+		mmr_t	tail_timeout_ni_vc3           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo02_debit0        : 1;
+	} sh_ni0_error_overflow_1_s;
+} sh_ni0_error_overflow_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI0_ERROR_OVERFLOW_2"                  */
+/*                       ni0  Error Overflow Bits                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_overflow_2_u {
+	mmr_t	sh_ni0_error_overflow_2_regval;
+	struct {
+		mmr_t	illegal_vcni                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	reserved_1                     : 1;
+	} sh_ni0_error_overflow_2_s;
+} sh_ni0_error_overflow_2_u_t;
+#else
+typedef union sh_ni0_error_overflow_2_u {
+	mmr_t	sh_ni0_error_overflow_2_regval;
+	struct {
+		mmr_t	reserved_1                     : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcni                   : 1;
+	} sh_ni0_error_overflow_2_s;
+} sh_ni0_error_overflow_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_ERROR_MASK_1"                    */
+/*                         ni0  Error Mask Bits                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_mask_1_u {
+	mmr_t	sh_ni0_error_mask_1_regval;
+	struct {
+		mmr_t	overflow_fifo02_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc3           : 1;
+	} sh_ni0_error_mask_1_s;
+} sh_ni0_error_mask_1_u_t;
+#else
+typedef union sh_ni0_error_mask_1_u {
+	mmr_t	sh_ni0_error_mask_1_regval;
+	struct {
+		mmr_t	tail_timeout_ni_vc3           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo02_debit0        : 1;
+	} sh_ni0_error_mask_1_s;
+} sh_ni0_error_mask_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI0_ERROR_MASK_2"                    */
+/*                         ni0  Error Mask Bits                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_mask_2_u {
+	mmr_t	sh_ni0_error_mask_2_regval;
+	struct {
+		mmr_t	illegal_vcni                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	reserved_1                     : 1;
+	} sh_ni0_error_mask_2_s;
+} sh_ni0_error_mask_2_u_t;
+#else
+typedef union sh_ni0_error_mask_2_u {
+	mmr_t	sh_ni0_error_mask_2_regval;
+	struct {
+		mmr_t	reserved_1                     : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcni                   : 1;
+	} sh_ni0_error_mask_2_s;
+} sh_ni0_error_mask_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_FIRST_ERROR_1"                    */
+/*                        ni0  First Error Bits                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_first_error_1_u {
+	mmr_t	sh_ni0_first_error_1_regval;
+	struct {
+		mmr_t	overflow_fifo02_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc3           : 1;
+	} sh_ni0_first_error_1_s;
+} sh_ni0_first_error_1_u_t;
+#else
+typedef union sh_ni0_first_error_1_u {
+	mmr_t	sh_ni0_first_error_1_regval;
+	struct {
+		mmr_t	tail_timeout_ni_vc3           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo02_debit0        : 1;
+	} sh_ni0_first_error_1_s;
+} sh_ni0_first_error_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_FIRST_ERROR_2"                    */
+/*                         ni0 First Error Bits                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_first_error_2_u {
+	mmr_t	sh_ni0_first_error_2_regval;
+	struct {
+		mmr_t	illegal_vcni                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	reserved_1                     : 1;
+	} sh_ni0_first_error_2_s;
+} sh_ni0_first_error_2_u_t;
+#else
+typedef union sh_ni0_first_error_2_u {
+	mmr_t	sh_ni0_first_error_2_regval;
+	struct {
+		mmr_t	reserved_1                     : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcni                   : 1;
+	} sh_ni0_first_error_2_s;
+} sh_ni0_first_error_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_ERROR_DETAIL_1"                   */
+/*                ni0 Chiplet no match header bits 63:0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_detail_1_u {
+	mmr_t	sh_ni0_error_detail_1_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_ni0_error_detail_1_s;
+} sh_ni0_error_detail_1_u_t;
+#else
+typedef union sh_ni0_error_detail_1_u {
+	mmr_t	sh_ni0_error_detail_1_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_ni0_error_detail_1_s;
+} sh_ni0_error_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_ERROR_DETAIL_2"                   */
+/*               ni0 Chiplet no match header bits 127:64                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_detail_2_u {
+	mmr_t	sh_ni0_error_detail_2_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_ni0_error_detail_2_s;
+} sh_ni0_error_detail_2_u_t;
+#else
+typedef union sh_ni0_error_detail_2_u {
+	mmr_t	sh_ni0_error_detail_2_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_ni0_error_detail_2_s;
+} sh_ni0_error_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_ERROR_SUMMARY_1"                   */
+/*                       ni1  Error Summary Bits                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_summary_1_u {
+	mmr_t	sh_ni1_error_summary_1_regval;
+	struct {
+		mmr_t	overflow_fifo02_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc3           : 1;
+	} sh_ni1_error_summary_1_s;
+} sh_ni1_error_summary_1_u_t;
+#else
+typedef union sh_ni1_error_summary_1_u {
+	mmr_t	sh_ni1_error_summary_1_regval;
+	struct {
+		mmr_t	tail_timeout_ni_vc3           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo02_debit0        : 1;
+	} sh_ni1_error_summary_1_s;
+} sh_ni1_error_summary_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_ERROR_SUMMARY_2"                   */
+/*                       ni1  Error Summary Bits                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_summary_2_u {
+	mmr_t	sh_ni1_error_summary_2_regval;
+	struct {
+		mmr_t	illegal_vcni                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	reserved_1                     : 1;
+	} sh_ni1_error_summary_2_s;
+} sh_ni1_error_summary_2_u_t;
+#else
+typedef union sh_ni1_error_summary_2_u {
+	mmr_t	sh_ni1_error_summary_2_regval;
+	struct {
+		mmr_t	reserved_1                     : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcni                   : 1;
+	} sh_ni1_error_summary_2_s;
+} sh_ni1_error_summary_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_ERROR_OVERFLOW_1"                  */
+/*                       ni1  Error Overflow Bits                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_overflow_1_u {
+	mmr_t	sh_ni1_error_overflow_1_regval;
+	struct {
+		mmr_t	overflow_fifo02_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc3           : 1;
+	} sh_ni1_error_overflow_1_s;
+} sh_ni1_error_overflow_1_u_t;
+#else
+typedef union sh_ni1_error_overflow_1_u {
+	mmr_t	sh_ni1_error_overflow_1_regval;
+	struct {
+		mmr_t	tail_timeout_ni_vc3           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo02_debit0        : 1;
+	} sh_ni1_error_overflow_1_s;
+} sh_ni1_error_overflow_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_NI1_ERROR_OVERFLOW_2"                  */
+/*                       ni1  Error Overflow Bits                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_overflow_2_u {
+	mmr_t	sh_ni1_error_overflow_2_regval;
+	struct {
+		mmr_t	illegal_vcni                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	reserved_1                     : 1;
+	} sh_ni1_error_overflow_2_s;
+} sh_ni1_error_overflow_2_u_t;
+#else
+typedef union sh_ni1_error_overflow_2_u {
+	mmr_t	sh_ni1_error_overflow_2_regval;
+	struct {
+		mmr_t	reserved_1                     : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcni                   : 1;
+	} sh_ni1_error_overflow_2_s;
+} sh_ni1_error_overflow_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_ERROR_MASK_1"                    */
+/*                         ni1  Error Mask Bits                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_mask_1_u {
+	mmr_t	sh_ni1_error_mask_1_regval;
+	struct {
+		mmr_t	overflow_fifo02_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc3           : 1;
+	} sh_ni1_error_mask_1_s;
+} sh_ni1_error_mask_1_u_t;
+#else
+typedef union sh_ni1_error_mask_1_u {
+	mmr_t	sh_ni1_error_mask_1_regval;
+	struct {
+		mmr_t	tail_timeout_ni_vc3           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo02_debit0        : 1;
+	} sh_ni1_error_mask_1_s;
+} sh_ni1_error_mask_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_NI1_ERROR_MASK_2"                    */
+/*                         ni1  Error Mask Bits                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_mask_2_u {
+	mmr_t	sh_ni1_error_mask_2_regval;
+	struct {
+		mmr_t	illegal_vcni                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	reserved_1                     : 1;
+	} sh_ni1_error_mask_2_s;
+} sh_ni1_error_mask_2_u_t;
+#else
+typedef union sh_ni1_error_mask_2_u {
+	mmr_t	sh_ni1_error_mask_2_regval;
+	struct {
+		mmr_t	reserved_1                     : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcni                   : 1;
+	} sh_ni1_error_mask_2_s;
+} sh_ni1_error_mask_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_FIRST_ERROR_1"                    */
+/*                        ni1  First Error Bits                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_first_error_1_u {
+	mmr_t	sh_ni1_first_error_1_regval;
+	struct {
+		mmr_t	overflow_fifo02_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc3           : 1;
+	} sh_ni1_first_error_1_s;
+} sh_ni1_first_error_1_u_t;
+#else
+typedef union sh_ni1_first_error_1_u {
+	mmr_t	sh_ni1_first_error_1_regval;
+	struct {
+		mmr_t	tail_timeout_ni_vc3           : 1;
+		mmr_t	tail_timeout_ni_vc2           : 1;
+		mmr_t	tail_timeout_ni_vc1           : 1;
+		mmr_t	tail_timeout_ni_vc0           : 1;
+		mmr_t	tail_timeout_fifo13_vc3       : 1;
+		mmr_t	tail_timeout_fifo13_vc1       : 1;
+		mmr_t	tail_timeout_fifo02_vc2       : 1;
+		mmr_t	tail_timeout_fifo02_vc0       : 1;
+		mmr_t	overflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	overflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_credit   : 1;
+		mmr_t	overflow_md_fifo_vc0_credit   : 1;
+		mmr_t	overflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	overflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	overflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	overflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	overflow_md_fifo_vc2_push     : 1;
+		mmr_t	overflow_md_fifo_vc0_push     : 1;
+		mmr_t	overflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	overflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	overflow_pi_fifo_vc2_push     : 1;
+		mmr_t	overflow_pi_fifo_vc0_push     : 1;
+		mmr_t	overflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	overflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	overflow_md_fifo_vc2_pop      : 1;
+		mmr_t	overflow_md_fifo_vc0_pop      : 1;
+		mmr_t	overflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	overflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	overflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	overflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	overflow_ni_fifo_debit3       : 1;
+		mmr_t	overflow_ni_fifo_debit2       : 1;
+		mmr_t	overflow_ni_fifo_debit1       : 1;
+		mmr_t	overflow_ni_fifo_debit0       : 1;
+		mmr_t	overflow_md_fifo_debit2       : 1;
+		mmr_t	overflow_md_fifo_debit0       : 1;
+		mmr_t	overflow_iilb_fifo_debit2     : 1;
+		mmr_t	overflow_iilb_fifo_debit0     : 1;
+		mmr_t	overflow_pi_fifo_debit2       : 1;
+		mmr_t	overflow_pi_fifo_debit0       : 1;
+		mmr_t	overflow2_vc2_credit          : 1;
+		mmr_t	overflow1_vc2_credit          : 1;
+		mmr_t	overflow0_vc2_credit          : 1;
+		mmr_t	overflow2_vc0_credit          : 1;
+		mmr_t	overflow1_vc0_credit          : 1;
+		mmr_t	overflow0_vc0_credit          : 1;
+		mmr_t	overflow_fifo13_vc2_credit    : 1;
+		mmr_t	overflow_fifo13_vc0_credit    : 1;
+		mmr_t	overflow_fifo02_vc2_credit    : 1;
+		mmr_t	overflow_fifo02_vc0_credit    : 1;
+		mmr_t	overflow_fifo13_vc3_push      : 1;
+		mmr_t	overflow_fifo13_vc1_push      : 1;
+		mmr_t	overflow_fifo02_vc2_push      : 1;
+		mmr_t	overflow_fifo02_vc0_push      : 1;
+		mmr_t	overflow_fifo13_vc3_pop       : 1;
+		mmr_t	overflow_fifo13_vc1_pop       : 1;
+		mmr_t	overflow_fifo02_vc2_pop       : 1;
+		mmr_t	overflow_fifo02_vc0_pop       : 1;
+		mmr_t	overflow_fifo13_debit2        : 1;
+		mmr_t	overflow_fifo13_debit0        : 1;
+		mmr_t	overflow_fifo02_debit2        : 1;
+		mmr_t	overflow_fifo02_debit0        : 1;
+	} sh_ni1_first_error_1_s;
+} sh_ni1_first_error_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_FIRST_ERROR_2"                    */
+/*                         ni1 First Error Bits                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_first_error_2_u {
+	mmr_t	sh_ni1_first_error_2_regval;
+	struct {
+		mmr_t	illegal_vcni                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	reserved_1                     : 1;
+	} sh_ni1_first_error_2_s;
+} sh_ni1_first_error_2_u_t;
+#else
+typedef union sh_ni1_first_error_2_u {
+	mmr_t	sh_ni1_first_error_2_regval;
+	struct {
+		mmr_t	reserved_1                     : 1;
+		mmr_t	retry_timeout_error            : 1;
+		mmr_t	lut_read_error                 : 1;
+		mmr_t	chiplet_nomatch                : 1;
+		mmr_t	llp_deadlock_vc3               : 1;
+		mmr_t	llp_deadlock_vc2               : 1;
+		mmr_t	llp_deadlock_vc1               : 1;
+		mmr_t	llp_deadlock_vc0               : 1;
+		mmr_t	underflow_ni_fifo_vc3_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc2_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc1_credit   : 1;
+		mmr_t	underflow_ni_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_credit   : 1;
+		mmr_t	underflow_md_fifo_vc0_credit   : 1;
+		mmr_t	underflow_iilb_fifo_vc2_credit : 1;
+		mmr_t	underflow_iilb_fifo_vc0_credit : 1;
+		mmr_t	underflow_pi_fifo_vc2_credit   : 1;
+		mmr_t	underflow_pi_fifo_vc0_credit   : 1;
+		mmr_t	underflow_md_fifo_vc2_push     : 1;
+		mmr_t	underflow_md_fifo_vc0_push     : 1;
+		mmr_t	underflow_iilb_fifo_vc2_push   : 1;
+		mmr_t	underflow_iilb_fifo_vc0_push   : 1;
+		mmr_t	underflow_pi_fifo_vc2_push     : 1;
+		mmr_t	underflow_pi_fifo_vc0_push     : 1;
+		mmr_t	underflow_ni_fifo_vc2_pop      : 1;
+		mmr_t	underflow_ni_fifo_vc0_pop      : 1;
+		mmr_t	underflow_md_fifo_vc2_pop      : 1;
+		mmr_t	underflow_md_fifo_vc0_pop      : 1;
+		mmr_t	underflow_iilb_fifo_vc2_pop    : 1;
+		mmr_t	underflow_iilb_fifo_vc0_pop    : 1;
+		mmr_t	underflow_pi_fifo_vc2_pop      : 1;
+		mmr_t	underflow_pi_fifo_vc0_pop      : 1;
+		mmr_t	reserved_0                     : 10;
+		mmr_t	underflow2_vc2_credit          : 1;
+		mmr_t	underflow1_vc2_credit          : 1;
+		mmr_t	underflow0_vc2_credit          : 1;
+		mmr_t	underflow2_vc0_credit          : 1;
+		mmr_t	underflow1_vc0_credit          : 1;
+		mmr_t	underflow0_vc0_credit          : 1;
+		mmr_t	underflow_fifo13_vc2_credit    : 1;
+		mmr_t	underflow_fifo13_vc0_credit    : 1;
+		mmr_t	underflow_fifo02_vc2_credit    : 1;
+		mmr_t	underflow_fifo02_vc0_credit    : 1;
+		mmr_t	underflow_fifo13_vc3_push      : 1;
+		mmr_t	underflow_fifo13_vc1_push      : 1;
+		mmr_t	underflow_fifo02_vc2_push      : 1;
+		mmr_t	underflow_fifo02_vc0_push      : 1;
+		mmr_t	underflow_fifo13_vc3_pop       : 1;
+		mmr_t	underflow_fifo13_vc1_pop       : 1;
+		mmr_t	underflow_fifo02_vc2_pop       : 1;
+		mmr_t	underflow_fifo02_vc0_pop       : 1;
+		mmr_t	illegal_vciilb                 : 1;
+		mmr_t	illegal_vcmd                   : 1;
+		mmr_t	illegal_vcpi                   : 1;
+		mmr_t	illegal_vcni                   : 1;
+	} sh_ni1_first_error_2_s;
+} sh_ni1_first_error_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_ERROR_DETAIL_1"                   */
+/*                ni1 Chiplet no match header bits 63:0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_detail_1_u {
+	mmr_t	sh_ni1_error_detail_1_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_ni1_error_detail_1_s;
+} sh_ni1_error_detail_1_u_t;
+#else
+typedef union sh_ni1_error_detail_1_u {
+	mmr_t	sh_ni1_error_detail_1_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_ni1_error_detail_1_s;
+} sh_ni1_error_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_ERROR_DETAIL_2"                   */
+/*               ni1 Chiplet no match header bits 127:64                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_detail_2_u {
+	mmr_t	sh_ni1_error_detail_2_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_ni1_error_detail_2_s;
+} sh_ni1_error_detail_2_u_t;
+#else
+typedef union sh_ni1_error_detail_2_u {
+	mmr_t	sh_ni1_error_detail_2_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_ni1_error_detail_2_s;
+} sh_ni1_error_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_CORRECTED_DETAIL_1"                  */
+/*                       Corrected error details                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_corrected_detail_1_u {
+	mmr_t	sh_xn_corrected_detail_1_regval;
+	struct {
+		mmr_t	ecc0_syndrome : 8;
+		mmr_t	ecc0_wc       : 2;
+		mmr_t	ecc0_vc       : 2;
+		mmr_t	reserved_0    : 4;
+		mmr_t	ecc1_syndrome : 8;
+		mmr_t	ecc1_wc       : 2;
+		mmr_t	ecc1_vc       : 2;
+		mmr_t	reserved_1    : 4;
+		mmr_t	ecc2_syndrome : 8;
+		mmr_t	ecc2_wc       : 2;
+		mmr_t	ecc2_vc       : 2;
+		mmr_t	reserved_2    : 4;
+		mmr_t	ecc3_syndrome : 8;
+		mmr_t	ecc3_wc       : 2;
+		mmr_t	ecc3_vc       : 2;
+		mmr_t	reserved_3    : 4;
+	} sh_xn_corrected_detail_1_s;
+} sh_xn_corrected_detail_1_u_t;
+#else
+typedef union sh_xn_corrected_detail_1_u {
+	mmr_t	sh_xn_corrected_detail_1_regval;
+	struct {
+		mmr_t	reserved_3    : 4;
+		mmr_t	ecc3_vc       : 2;
+		mmr_t	ecc3_wc       : 2;
+		mmr_t	ecc3_syndrome : 8;
+		mmr_t	reserved_2    : 4;
+		mmr_t	ecc2_vc       : 2;
+		mmr_t	ecc2_wc       : 2;
+		mmr_t	ecc2_syndrome : 8;
+		mmr_t	reserved_1    : 4;
+		mmr_t	ecc1_vc       : 2;
+		mmr_t	ecc1_wc       : 2;
+		mmr_t	ecc1_syndrome : 8;
+		mmr_t	reserved_0    : 4;
+		mmr_t	ecc0_vc       : 2;
+		mmr_t	ecc0_wc       : 2;
+		mmr_t	ecc0_syndrome : 8;
+	} sh_xn_corrected_detail_1_s;
+} sh_xn_corrected_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_CORRECTED_DETAIL_2"                  */
+/*                         Corrected error data                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_corrected_detail_2_u {
+	mmr_t	sh_xn_corrected_detail_2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_corrected_detail_2_s;
+} sh_xn_corrected_detail_2_u_t;
+#else
+typedef union sh_xn_corrected_detail_2_u {
+	mmr_t	sh_xn_corrected_detail_2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_corrected_detail_2_s;
+} sh_xn_corrected_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_CORRECTED_DETAIL_3"                  */
+/*                       Corrected error header0                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_corrected_detail_3_u {
+	mmr_t	sh_xn_corrected_detail_3_regval;
+	struct {
+		mmr_t	header0     : 64;
+	} sh_xn_corrected_detail_3_s;
+} sh_xn_corrected_detail_3_u_t;
+#else
+typedef union sh_xn_corrected_detail_3_u {
+	mmr_t	sh_xn_corrected_detail_3_regval;
+	struct {
+		mmr_t	header0     : 64;
+	} sh_xn_corrected_detail_3_s;
+} sh_xn_corrected_detail_3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XN_CORRECTED_DETAIL_4"                  */
+/*                       Corrected error header1                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_corrected_detail_4_u {
+	mmr_t	sh_xn_corrected_detail_4_regval;
+	struct {
+		mmr_t	header1     : 42;
+		mmr_t	reserved_0  : 20;
+		mmr_t	err_group   : 2;
+	} sh_xn_corrected_detail_4_s;
+} sh_xn_corrected_detail_4_u_t;
+#else
+typedef union sh_xn_corrected_detail_4_u {
+	mmr_t	sh_xn_corrected_detail_4_regval;
+	struct {
+		mmr_t	err_group   : 2;
+		mmr_t	reserved_0  : 20;
+		mmr_t	header1     : 42;
+	} sh_xn_corrected_detail_4_s;
+} sh_xn_corrected_detail_4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_UNCORRECTED_DETAIL_1"                 */
+/*                      Uncorrected error details                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_uncorrected_detail_1_u {
+	mmr_t	sh_xn_uncorrected_detail_1_regval;
+	struct {
+		mmr_t	ecc0_syndrome : 8;
+		mmr_t	ecc0_wc       : 2;
+		mmr_t	ecc0_vc       : 2;
+		mmr_t	reserved_0    : 4;
+		mmr_t	ecc1_syndrome : 8;
+		mmr_t	ecc1_wc       : 2;
+		mmr_t	ecc1_vc       : 2;
+		mmr_t	reserved_1    : 4;
+		mmr_t	ecc2_syndrome : 8;
+		mmr_t	ecc2_wc       : 2;
+		mmr_t	ecc2_vc       : 2;
+		mmr_t	reserved_2    : 4;
+		mmr_t	ecc3_syndrome : 8;
+		mmr_t	ecc3_wc       : 2;
+		mmr_t	ecc3_vc       : 2;
+		mmr_t	reserved_3    : 4;
+	} sh_xn_uncorrected_detail_1_s;
+} sh_xn_uncorrected_detail_1_u_t;
+#else
+typedef union sh_xn_uncorrected_detail_1_u {
+	mmr_t	sh_xn_uncorrected_detail_1_regval;
+	struct {
+		mmr_t	reserved_3    : 4;
+		mmr_t	ecc3_vc       : 2;
+		mmr_t	ecc3_wc       : 2;
+		mmr_t	ecc3_syndrome : 8;
+		mmr_t	reserved_2    : 4;
+		mmr_t	ecc2_vc       : 2;
+		mmr_t	ecc2_wc       : 2;
+		mmr_t	ecc2_syndrome : 8;
+		mmr_t	reserved_1    : 4;
+		mmr_t	ecc1_vc       : 2;
+		mmr_t	ecc1_wc       : 2;
+		mmr_t	ecc1_syndrome : 8;
+		mmr_t	reserved_0    : 4;
+		mmr_t	ecc0_vc       : 2;
+		mmr_t	ecc0_wc       : 2;
+		mmr_t	ecc0_syndrome : 8;
+	} sh_xn_uncorrected_detail_1_s;
+} sh_xn_uncorrected_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_UNCORRECTED_DETAIL_2"                 */
+/*                        Uncorrected error data                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_uncorrected_detail_2_u {
+	mmr_t	sh_xn_uncorrected_detail_2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_uncorrected_detail_2_s;
+} sh_xn_uncorrected_detail_2_u_t;
+#else
+typedef union sh_xn_uncorrected_detail_2_u {
+	mmr_t	sh_xn_uncorrected_detail_2_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_xn_uncorrected_detail_2_s;
+} sh_xn_uncorrected_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_UNCORRECTED_DETAIL_3"                 */
+/*                      Uncorrected error header0                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_uncorrected_detail_3_u {
+	mmr_t	sh_xn_uncorrected_detail_3_regval;
+	struct {
+		mmr_t	header0     : 64;
+	} sh_xn_uncorrected_detail_3_s;
+} sh_xn_uncorrected_detail_3_u_t;
+#else
+typedef union sh_xn_uncorrected_detail_3_u {
+	mmr_t	sh_xn_uncorrected_detail_3_regval;
+	struct {
+		mmr_t	header0     : 64;
+	} sh_xn_uncorrected_detail_3_s;
+} sh_xn_uncorrected_detail_3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_XN_UNCORRECTED_DETAIL_4"                 */
+/*                      Uncorrected error header1                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_uncorrected_detail_4_u {
+	mmr_t	sh_xn_uncorrected_detail_4_regval;
+	struct {
+		mmr_t	header1     : 42;
+		mmr_t	reserved_0  : 20;
+		mmr_t	err_group   : 2;
+	} sh_xn_uncorrected_detail_4_s;
+} sh_xn_uncorrected_detail_4_u_t;
+#else
+typedef union sh_xn_uncorrected_detail_4_u {
+	mmr_t	sh_xn_uncorrected_detail_4_regval;
+	struct {
+		mmr_t	err_group   : 2;
+		mmr_t	reserved_0  : 20;
+		mmr_t	header1     : 42;
+	} sh_xn_uncorrected_detail_4_s;
+} sh_xn_uncorrected_detail_4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNMD_ERROR_DETAIL_1"                   */
+/*                      Look Up Table Address (md)                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_error_detail_1_u {
+	mmr_t	sh_xnmd_error_detail_1_regval;
+	struct {
+		mmr_t	lut_addr    : 11;
+		mmr_t	reserved_0  : 53;
+	} sh_xnmd_error_detail_1_s;
+} sh_xnmd_error_detail_1_u_t;
+#else
+typedef union sh_xnmd_error_detail_1_u {
+	mmr_t	sh_xnmd_error_detail_1_regval;
+	struct {
+		mmr_t	reserved_0  : 53;
+		mmr_t	lut_addr    : 11;
+	} sh_xnmd_error_detail_1_s;
+} sh_xnmd_error_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNPI_ERROR_DETAIL_1"                   */
+/*                      Look Up Table Address (pi)                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_error_detail_1_u {
+	mmr_t	sh_xnpi_error_detail_1_regval;
+	struct {
+		mmr_t	lut_addr    : 11;
+		mmr_t	reserved_0  : 53;
+	} sh_xnpi_error_detail_1_s;
+} sh_xnpi_error_detail_1_u_t;
+#else
+typedef union sh_xnpi_error_detail_1_u {
+	mmr_t	sh_xnpi_error_detail_1_regval;
+	struct {
+		mmr_t	reserved_0  : 53;
+		mmr_t	lut_addr    : 11;
+	} sh_xnpi_error_detail_1_s;
+} sh_xnpi_error_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNIILB_ERROR_DETAIL_1"                  */
+/*                    Chiplet NoMatch header [63:0]                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_error_detail_1_u {
+	mmr_t	sh_xniilb_error_detail_1_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_xniilb_error_detail_1_s;
+} sh_xniilb_error_detail_1_u_t;
+#else
+typedef union sh_xniilb_error_detail_1_u {
+	mmr_t	sh_xniilb_error_detail_1_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_xniilb_error_detail_1_s;
+} sh_xniilb_error_detail_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNIILB_ERROR_DETAIL_2"                  */
+/*                   Chiplet NoMatch header [127:64]                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_error_detail_2_u {
+	mmr_t	sh_xniilb_error_detail_2_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_xniilb_error_detail_2_s;
+} sh_xniilb_error_detail_2_u_t;
+#else
+typedef union sh_xniilb_error_detail_2_u {
+	mmr_t	sh_xniilb_error_detail_2_regval;
+	struct {
+		mmr_t	header      : 64;
+	} sh_xniilb_error_detail_2_s;
+} sh_xniilb_error_detail_2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNIILB_ERROR_DETAIL_3"                  */
+/*                     Look Up Table Address (iilb)                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_error_detail_3_u {
+	mmr_t	sh_xniilb_error_detail_3_regval;
+	struct {
+		mmr_t	lut_addr    : 11;
+		mmr_t	reserved_0  : 53;
+	} sh_xniilb_error_detail_3_s;
+} sh_xniilb_error_detail_3_u_t;
+#else
+typedef union sh_xniilb_error_detail_3_u {
+	mmr_t	sh_xniilb_error_detail_3_regval;
+	struct {
+		mmr_t	reserved_0  : 53;
+		mmr_t	lut_addr    : 11;
+	} sh_xniilb_error_detail_3_s;
+} sh_xniilb_error_detail_3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI0_ERROR_DETAIL_3"                   */
+/*                     Look Up Table Address (ni0)                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni0_error_detail_3_u {
+	mmr_t	sh_ni0_error_detail_3_regval;
+	struct {
+		mmr_t	lut_addr    : 11;
+		mmr_t	reserved_0  : 53;
+	} sh_ni0_error_detail_3_s;
+} sh_ni0_error_detail_3_u_t;
+#else
+typedef union sh_ni0_error_detail_3_u {
+	mmr_t	sh_ni0_error_detail_3_regval;
+	struct {
+		mmr_t	reserved_0  : 53;
+		mmr_t	lut_addr    : 11;
+	} sh_ni0_error_detail_3_s;
+} sh_ni0_error_detail_3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_NI1_ERROR_DETAIL_3"                   */
+/*                     Look Up Table Address (ni1)                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ni1_error_detail_3_u {
+	mmr_t	sh_ni1_error_detail_3_regval;
+	struct {
+		mmr_t	lut_addr    : 11;
+		mmr_t	reserved_0  : 53;
+	} sh_ni1_error_detail_3_s;
+} sh_ni1_error_detail_3_u_t;
+#else
+typedef union sh_ni1_error_detail_3_u {
+	mmr_t	sh_ni1_error_detail_3_regval;
+	struct {
+		mmr_t	reserved_0  : 53;
+		mmr_t	lut_addr    : 11;
+	} sh_ni1_error_detail_3_s;
+} sh_ni1_error_detail_3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_ERROR_SUMMARY"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_error_summary_u {
+	mmr_t	sh_xn_error_summary_regval;
+	struct {
+		mmr_t	ni0_pop_overflow        : 1;
+		mmr_t	ni0_push_overflow       : 1;
+		mmr_t	ni0_credit_overflow     : 1;
+		mmr_t	ni0_debit_overflow      : 1;
+		mmr_t	ni0_pop_underflow       : 1;
+		mmr_t	ni0_push_underflow      : 1;
+		mmr_t	ni0_credit_underflow    : 1;
+		mmr_t	ni0_llp_error           : 1;
+		mmr_t	ni0_pipe_error          : 1;
+		mmr_t	ni1_pop_overflow        : 1;
+		mmr_t	ni1_push_overflow       : 1;
+		mmr_t	ni1_credit_overflow     : 1;
+		mmr_t	ni1_debit_overflow      : 1;
+		mmr_t	ni1_pop_underflow       : 1;
+		mmr_t	ni1_push_underflow      : 1;
+		mmr_t	ni1_credit_underflow    : 1;
+		mmr_t	ni1_llp_error           : 1;
+		mmr_t	ni1_pipe_error          : 1;
+		mmr_t	xnmd_credit_overflow    : 1;
+		mmr_t	xnmd_debit_overflow     : 1;
+		mmr_t	xnmd_data_buff_overflow : 1;
+		mmr_t	xnmd_credit_underflow   : 1;
+		mmr_t	xnmd_sbe_error          : 1;
+		mmr_t	xnmd_uce_error          : 1;
+		mmr_t	xnmd_lut_error          : 1;
+		mmr_t	xnpi_credit_overflow    : 1;
+		mmr_t	xnpi_debit_overflow     : 1;
+		mmr_t	xnpi_data_buff_overflow : 1;
+		mmr_t	xnpi_credit_underflow   : 1;
+		mmr_t	xnpi_sbe_error          : 1;
+		mmr_t	xnpi_uce_error          : 1;
+		mmr_t	xnpi_lut_error          : 1;
+		mmr_t	iilb_debit_overflow     : 1;
+		mmr_t	iilb_credit_overflow    : 1;
+		mmr_t	iilb_fifo_overflow      : 1;
+		mmr_t	iilb_credit_underflow   : 1;
+		mmr_t	iilb_fifo_underflow     : 1;
+		mmr_t	iilb_chiplet_or_lut     : 1;
+		mmr_t	reserved_0              : 26;
+	} sh_xn_error_summary_s;
+} sh_xn_error_summary_u_t;
+#else
+typedef union sh_xn_error_summary_u {
+	mmr_t	sh_xn_error_summary_regval;
+	struct {
+		mmr_t	reserved_0              : 26;
+		mmr_t	iilb_chiplet_or_lut     : 1;
+		mmr_t	iilb_fifo_underflow     : 1;
+		mmr_t	iilb_credit_underflow   : 1;
+		mmr_t	iilb_fifo_overflow      : 1;
+		mmr_t	iilb_credit_overflow    : 1;
+		mmr_t	iilb_debit_overflow     : 1;
+		mmr_t	xnpi_lut_error          : 1;
+		mmr_t	xnpi_uce_error          : 1;
+		mmr_t	xnpi_sbe_error          : 1;
+		mmr_t	xnpi_credit_underflow   : 1;
+		mmr_t	xnpi_data_buff_overflow : 1;
+		mmr_t	xnpi_debit_overflow     : 1;
+		mmr_t	xnpi_credit_overflow    : 1;
+		mmr_t	xnmd_lut_error          : 1;
+		mmr_t	xnmd_uce_error          : 1;
+		mmr_t	xnmd_sbe_error          : 1;
+		mmr_t	xnmd_credit_underflow   : 1;
+		mmr_t	xnmd_data_buff_overflow : 1;
+		mmr_t	xnmd_debit_overflow     : 1;
+		mmr_t	xnmd_credit_overflow    : 1;
+		mmr_t	ni1_pipe_error          : 1;
+		mmr_t	ni1_llp_error           : 1;
+		mmr_t	ni1_credit_underflow    : 1;
+		mmr_t	ni1_push_underflow      : 1;
+		mmr_t	ni1_pop_underflow       : 1;
+		mmr_t	ni1_debit_overflow      : 1;
+		mmr_t	ni1_credit_overflow     : 1;
+		mmr_t	ni1_push_overflow       : 1;
+		mmr_t	ni1_pop_overflow        : 1;
+		mmr_t	ni0_pipe_error          : 1;
+		mmr_t	ni0_llp_error           : 1;
+		mmr_t	ni0_credit_underflow    : 1;
+		mmr_t	ni0_push_underflow      : 1;
+		mmr_t	ni0_pop_underflow       : 1;
+		mmr_t	ni0_debit_overflow      : 1;
+		mmr_t	ni0_credit_overflow     : 1;
+		mmr_t	ni0_push_overflow       : 1;
+		mmr_t	ni0_pop_overflow        : 1;
+	} sh_xn_error_summary_s;
+} sh_xn_error_summary_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XN_ERROR_OVERFLOW"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_error_overflow_u {
+	mmr_t	sh_xn_error_overflow_regval;
+	struct {
+		mmr_t	ni0_pop_overflow        : 1;
+		mmr_t	ni0_push_overflow       : 1;
+		mmr_t	ni0_credit_overflow     : 1;
+		mmr_t	ni0_debit_overflow      : 1;
+		mmr_t	ni0_pop_underflow       : 1;
+		mmr_t	ni0_push_underflow      : 1;
+		mmr_t	ni0_credit_underflow    : 1;
+		mmr_t	ni0_llp_error           : 1;
+		mmr_t	ni0_pipe_error          : 1;
+		mmr_t	ni1_pop_overflow        : 1;
+		mmr_t	ni1_push_overflow       : 1;
+		mmr_t	ni1_credit_overflow     : 1;
+		mmr_t	ni1_debit_overflow      : 1;
+		mmr_t	ni1_pop_underflow       : 1;
+		mmr_t	ni1_push_underflow      : 1;
+		mmr_t	ni1_credit_underflow    : 1;
+		mmr_t	ni1_llp_error           : 1;
+		mmr_t	ni1_pipe_error          : 1;
+		mmr_t	xnmd_credit_overflow    : 1;
+		mmr_t	xnmd_debit_overflow     : 1;
+		mmr_t	xnmd_data_buff_overflow : 1;
+		mmr_t	xnmd_credit_underflow   : 1;
+		mmr_t	xnmd_sbe_error          : 1;
+		mmr_t	xnmd_uce_error          : 1;
+		mmr_t	xnmd_lut_error          : 1;
+		mmr_t	xnpi_credit_overflow    : 1;
+		mmr_t	xnpi_debit_overflow     : 1;
+		mmr_t	xnpi_data_buff_overflow : 1;
+		mmr_t	xnpi_credit_underflow   : 1;
+		mmr_t	xnpi_sbe_error          : 1;
+		mmr_t	xnpi_uce_error          : 1;
+		mmr_t	xnpi_lut_error          : 1;
+		mmr_t	iilb_debit_overflow     : 1;
+		mmr_t	iilb_credit_overflow    : 1;
+		mmr_t	iilb_fifo_overflow      : 1;
+		mmr_t	iilb_credit_underflow   : 1;
+		mmr_t	iilb_fifo_underflow     : 1;
+		mmr_t	iilb_chiplet_or_lut     : 1;
+		mmr_t	reserved_0              : 26;
+	} sh_xn_error_overflow_s;
+} sh_xn_error_overflow_u_t;
+#else
+typedef union sh_xn_error_overflow_u {
+	mmr_t	sh_xn_error_overflow_regval;
+	struct {
+		mmr_t	reserved_0              : 26;
+		mmr_t	iilb_chiplet_or_lut     : 1;
+		mmr_t	iilb_fifo_underflow     : 1;
+		mmr_t	iilb_credit_underflow   : 1;
+		mmr_t	iilb_fifo_overflow      : 1;
+		mmr_t	iilb_credit_overflow    : 1;
+		mmr_t	iilb_debit_overflow     : 1;
+		mmr_t	xnpi_lut_error          : 1;
+		mmr_t	xnpi_uce_error          : 1;
+		mmr_t	xnpi_sbe_error          : 1;
+		mmr_t	xnpi_credit_underflow   : 1;
+		mmr_t	xnpi_data_buff_overflow : 1;
+		mmr_t	xnpi_debit_overflow     : 1;
+		mmr_t	xnpi_credit_overflow    : 1;
+		mmr_t	xnmd_lut_error          : 1;
+		mmr_t	xnmd_uce_error          : 1;
+		mmr_t	xnmd_sbe_error          : 1;
+		mmr_t	xnmd_credit_underflow   : 1;
+		mmr_t	xnmd_data_buff_overflow : 1;
+		mmr_t	xnmd_debit_overflow     : 1;
+		mmr_t	xnmd_credit_overflow    : 1;
+		mmr_t	ni1_pipe_error          : 1;
+		mmr_t	ni1_llp_error           : 1;
+		mmr_t	ni1_credit_underflow    : 1;
+		mmr_t	ni1_push_underflow      : 1;
+		mmr_t	ni1_pop_underflow       : 1;
+		mmr_t	ni1_debit_overflow      : 1;
+		mmr_t	ni1_credit_overflow     : 1;
+		mmr_t	ni1_push_overflow       : 1;
+		mmr_t	ni1_pop_overflow        : 1;
+		mmr_t	ni0_pipe_error          : 1;
+		mmr_t	ni0_llp_error           : 1;
+		mmr_t	ni0_credit_underflow    : 1;
+		mmr_t	ni0_push_underflow      : 1;
+		mmr_t	ni0_pop_underflow       : 1;
+		mmr_t	ni0_debit_overflow      : 1;
+		mmr_t	ni0_credit_overflow     : 1;
+		mmr_t	ni0_push_overflow       : 1;
+		mmr_t	ni0_pop_overflow        : 1;
+	} sh_xn_error_overflow_s;
+} sh_xn_error_overflow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_XN_ERROR_MASK"                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_error_mask_u {
+	mmr_t	sh_xn_error_mask_regval;
+	struct {
+		mmr_t	ni0_pop_overflow        : 1;
+		mmr_t	ni0_push_overflow       : 1;
+		mmr_t	ni0_credit_overflow     : 1;
+		mmr_t	ni0_debit_overflow      : 1;
+		mmr_t	ni0_pop_underflow       : 1;
+		mmr_t	ni0_push_underflow      : 1;
+		mmr_t	ni0_credit_underflow    : 1;
+		mmr_t	ni0_llp_error           : 1;
+		mmr_t	ni0_pipe_error          : 1;
+		mmr_t	ni1_pop_overflow        : 1;
+		mmr_t	ni1_push_overflow       : 1;
+		mmr_t	ni1_credit_overflow     : 1;
+		mmr_t	ni1_debit_overflow      : 1;
+		mmr_t	ni1_pop_underflow       : 1;
+		mmr_t	ni1_push_underflow      : 1;
+		mmr_t	ni1_credit_underflow    : 1;
+		mmr_t	ni1_llp_error           : 1;
+		mmr_t	ni1_pipe_error          : 1;
+		mmr_t	xnmd_credit_overflow    : 1;
+		mmr_t	xnmd_debit_overflow     : 1;
+		mmr_t	xnmd_data_buff_overflow : 1;
+		mmr_t	xnmd_credit_underflow   : 1;
+		mmr_t	xnmd_sbe_error          : 1;
+		mmr_t	xnmd_uce_error          : 1;
+		mmr_t	xnmd_lut_error          : 1;
+		mmr_t	xnpi_credit_overflow    : 1;
+		mmr_t	xnpi_debit_overflow     : 1;
+		mmr_t	xnpi_data_buff_overflow : 1;
+		mmr_t	xnpi_credit_underflow   : 1;
+		mmr_t	xnpi_sbe_error          : 1;
+		mmr_t	xnpi_uce_error          : 1;
+		mmr_t	xnpi_lut_error          : 1;
+		mmr_t	iilb_debit_overflow     : 1;
+		mmr_t	iilb_credit_overflow    : 1;
+		mmr_t	iilb_fifo_overflow      : 1;
+		mmr_t	iilb_credit_underflow   : 1;
+		mmr_t	iilb_fifo_underflow     : 1;
+		mmr_t	iilb_chiplet_or_lut     : 1;
+		mmr_t	reserved_0              : 26;
+	} sh_xn_error_mask_s;
+} sh_xn_error_mask_u_t;
+#else
+typedef union sh_xn_error_mask_u {
+	mmr_t	sh_xn_error_mask_regval;
+	struct {
+		mmr_t	reserved_0              : 26;
+		mmr_t	iilb_chiplet_or_lut     : 1;
+		mmr_t	iilb_fifo_underflow     : 1;
+		mmr_t	iilb_credit_underflow   : 1;
+		mmr_t	iilb_fifo_overflow      : 1;
+		mmr_t	iilb_credit_overflow    : 1;
+		mmr_t	iilb_debit_overflow     : 1;
+		mmr_t	xnpi_lut_error          : 1;
+		mmr_t	xnpi_uce_error          : 1;
+		mmr_t	xnpi_sbe_error          : 1;
+		mmr_t	xnpi_credit_underflow   : 1;
+		mmr_t	xnpi_data_buff_overflow : 1;
+		mmr_t	xnpi_debit_overflow     : 1;
+		mmr_t	xnpi_credit_overflow    : 1;
+		mmr_t	xnmd_lut_error          : 1;
+		mmr_t	xnmd_uce_error          : 1;
+		mmr_t	xnmd_sbe_error          : 1;
+		mmr_t	xnmd_credit_underflow   : 1;
+		mmr_t	xnmd_data_buff_overflow : 1;
+		mmr_t	xnmd_debit_overflow     : 1;
+		mmr_t	xnmd_credit_overflow    : 1;
+		mmr_t	ni1_pipe_error          : 1;
+		mmr_t	ni1_llp_error           : 1;
+		mmr_t	ni1_credit_underflow    : 1;
+		mmr_t	ni1_push_underflow      : 1;
+		mmr_t	ni1_pop_underflow       : 1;
+		mmr_t	ni1_debit_overflow      : 1;
+		mmr_t	ni1_credit_overflow     : 1;
+		mmr_t	ni1_push_overflow       : 1;
+		mmr_t	ni1_pop_overflow        : 1;
+		mmr_t	ni0_pipe_error          : 1;
+		mmr_t	ni0_llp_error           : 1;
+		mmr_t	ni0_credit_underflow    : 1;
+		mmr_t	ni0_push_underflow      : 1;
+		mmr_t	ni0_pop_underflow       : 1;
+		mmr_t	ni0_debit_overflow      : 1;
+		mmr_t	ni0_credit_overflow     : 1;
+		mmr_t	ni0_push_overflow       : 1;
+		mmr_t	ni0_pop_overflow        : 1;
+	} sh_xn_error_mask_s;
+} sh_xn_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_XN_FIRST_ERROR"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_first_error_u {
+	mmr_t	sh_xn_first_error_regval;
+	struct {
+		mmr_t	ni0_pop_overflow        : 1;
+		mmr_t	ni0_push_overflow       : 1;
+		mmr_t	ni0_credit_overflow     : 1;
+		mmr_t	ni0_debit_overflow      : 1;
+		mmr_t	ni0_pop_underflow       : 1;
+		mmr_t	ni0_push_underflow      : 1;
+		mmr_t	ni0_credit_underflow    : 1;
+		mmr_t	ni0_llp_error           : 1;
+		mmr_t	ni0_pipe_error          : 1;
+		mmr_t	ni1_pop_overflow        : 1;
+		mmr_t	ni1_push_overflow       : 1;
+		mmr_t	ni1_credit_overflow     : 1;
+		mmr_t	ni1_debit_overflow      : 1;
+		mmr_t	ni1_pop_underflow       : 1;
+		mmr_t	ni1_push_underflow      : 1;
+		mmr_t	ni1_credit_underflow    : 1;
+		mmr_t	ni1_llp_error           : 1;
+		mmr_t	ni1_pipe_error          : 1;
+		mmr_t	xnmd_credit_overflow    : 1;
+		mmr_t	xnmd_debit_overflow     : 1;
+		mmr_t	xnmd_data_buff_overflow : 1;
+		mmr_t	xnmd_credit_underflow   : 1;
+		mmr_t	xnmd_sbe_error          : 1;
+		mmr_t	xnmd_uce_error          : 1;
+		mmr_t	xnmd_lut_error          : 1;
+		mmr_t	xnpi_credit_overflow    : 1;
+		mmr_t	xnpi_debit_overflow     : 1;
+		mmr_t	xnpi_data_buff_overflow : 1;
+		mmr_t	xnpi_credit_underflow   : 1;
+		mmr_t	xnpi_sbe_error          : 1;
+		mmr_t	xnpi_uce_error          : 1;
+		mmr_t	xnpi_lut_error          : 1;
+		mmr_t	iilb_debit_overflow     : 1;
+		mmr_t	iilb_credit_overflow    : 1;
+		mmr_t	iilb_fifo_overflow      : 1;
+		mmr_t	iilb_credit_underflow   : 1;
+		mmr_t	iilb_fifo_underflow     : 1;
+		mmr_t	iilb_chiplet_or_lut     : 1;
+		mmr_t	reserved_0              : 26;
+	} sh_xn_first_error_s;
+} sh_xn_first_error_u_t;
+#else
+typedef union sh_xn_first_error_u {
+	mmr_t	sh_xn_first_error_regval;
+	struct {
+		mmr_t	reserved_0              : 26;
+		mmr_t	iilb_chiplet_or_lut     : 1;
+		mmr_t	iilb_fifo_underflow     : 1;
+		mmr_t	iilb_credit_underflow   : 1;
+		mmr_t	iilb_fifo_overflow      : 1;
+		mmr_t	iilb_credit_overflow    : 1;
+		mmr_t	iilb_debit_overflow     : 1;
+		mmr_t	xnpi_lut_error          : 1;
+		mmr_t	xnpi_uce_error          : 1;
+		mmr_t	xnpi_sbe_error          : 1;
+		mmr_t	xnpi_credit_underflow   : 1;
+		mmr_t	xnpi_data_buff_overflow : 1;
+		mmr_t	xnpi_debit_overflow     : 1;
+		mmr_t	xnpi_credit_overflow    : 1;
+		mmr_t	xnmd_lut_error          : 1;
+		mmr_t	xnmd_uce_error          : 1;
+		mmr_t	xnmd_sbe_error          : 1;
+		mmr_t	xnmd_credit_underflow   : 1;
+		mmr_t	xnmd_data_buff_overflow : 1;
+		mmr_t	xnmd_debit_overflow     : 1;
+		mmr_t	xnmd_credit_overflow    : 1;
+		mmr_t	ni1_pipe_error          : 1;
+		mmr_t	ni1_llp_error           : 1;
+		mmr_t	ni1_credit_underflow    : 1;
+		mmr_t	ni1_push_underflow      : 1;
+		mmr_t	ni1_pop_underflow       : 1;
+		mmr_t	ni1_debit_overflow      : 1;
+		mmr_t	ni1_credit_overflow     : 1;
+		mmr_t	ni1_push_overflow       : 1;
+		mmr_t	ni1_pop_overflow        : 1;
+		mmr_t	ni0_pipe_error          : 1;
+		mmr_t	ni0_llp_error           : 1;
+		mmr_t	ni0_credit_underflow    : 1;
+		mmr_t	ni0_push_underflow      : 1;
+		mmr_t	ni0_pop_underflow       : 1;
+		mmr_t	ni0_debit_overflow      : 1;
+		mmr_t	ni0_credit_overflow     : 1;
+		mmr_t	ni0_push_overflow       : 1;
+		mmr_t	ni0_pop_overflow        : 1;
+	} sh_xn_first_error_s;
+} sh_xn_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNIILB_ERROR_SUMMARY"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_error_summary_u {
+	mmr_t	sh_xniilb_error_summary_regval;
+	struct {
+		mmr_t	overflow_ii_debit0            : 1;
+		mmr_t	overflow_ii_debit2            : 1;
+		mmr_t	overflow_lb_debit0            : 1;
+		mmr_t	overflow_lb_debit2            : 1;
+		mmr_t	overflow_ii_vc0               : 1;
+		mmr_t	overflow_ii_vc2               : 1;
+		mmr_t	underflow_ii_vc0              : 1;
+		mmr_t	underflow_ii_vc2              : 1;
+		mmr_t	overflow_lb_vc0               : 1;
+		mmr_t	overflow_lb_vc2               : 1;
+		mmr_t	underflow_lb_vc0              : 1;
+		mmr_t	underflow_lb_vc2              : 1;
+		mmr_t	overflow_pi_vc0_credit_in     : 1;
+		mmr_t	overflow_iilb_vc0_credit_in   : 1;
+		mmr_t	overflow_md_vc0_credit_in     : 1;
+		mmr_t	overflow_ni0_vc0_credit_in    : 1;
+		mmr_t	overflow_ni1_vc0_credit_in    : 1;
+		mmr_t	overflow_pi_vc2_credit_in     : 1;
+		mmr_t	overflow_iilb_vc2_credit_in   : 1;
+		mmr_t	overflow_md_vc2_credit_in     : 1;
+		mmr_t	overflow_ni0_vc2_credit_in    : 1;
+		mmr_t	overflow_ni1_vc2_credit_in    : 1;
+		mmr_t	underflow_pi_vc0_credit_in    : 1;
+		mmr_t	underflow_iilb_vc0_credit_in  : 1;
+		mmr_t	underflow_md_vc0_credit_in    : 1;
+		mmr_t	underflow_ni0_vc0_credit_in   : 1;
+		mmr_t	underflow_ni1_vc0_credit_in   : 1;
+		mmr_t	underflow_pi_vc2_credit_in    : 1;
+		mmr_t	underflow_iilb_vc2_credit_in  : 1;
+		mmr_t	underflow_md_vc2_credit_in    : 1;
+		mmr_t	underflow_ni0_vc2_credit_in   : 1;
+		mmr_t	underflow_ni1_vc2_credit_in   : 1;
+		mmr_t	overflow_pi_debit0            : 1;
+		mmr_t	overflow_pi_debit2            : 1;
+		mmr_t	overflow_iilb_debit0          : 1;
+		mmr_t	overflow_iilb_debit2          : 1;
+		mmr_t	overflow_md_debit0            : 1;
+		mmr_t	overflow_md_debit2            : 1;
+		mmr_t	overflow_ni0_debit0           : 1;
+		mmr_t	overflow_ni0_debit2           : 1;
+		mmr_t	overflow_ni1_debit0           : 1;
+		mmr_t	overflow_ni1_debit2           : 1;
+		mmr_t	overflow_pi_vc0_credit_out    : 1;
+		mmr_t	overflow_pi_vc2_credit_out    : 1;
+		mmr_t	overflow_md_vc0_credit_out    : 1;
+		mmr_t	overflow_md_vc2_credit_out    : 1;
+		mmr_t	overflow_iilb_vc0_credit_out  : 1;
+		mmr_t	overflow_iilb_vc2_credit_out  : 1;
+		mmr_t	overflow_ni0_vc0_credit_out   : 1;
+		mmr_t	overflow_ni0_vc2_credit_out   : 1;
+		mmr_t	overflow_ni1_vc0_credit_out   : 1;
+		mmr_t	overflow_ni1_vc2_credit_out   : 1;
+		mmr_t	underflow_pi_vc0_credit_out   : 1;
+		mmr_t	underflow_pi_vc2_credit_out   : 1;
+		mmr_t	underflow_md_vc0_credit_out   : 1;
+		mmr_t	underflow_md_vc2_credit_out   : 1;
+		mmr_t	underflow_iilb_vc0_credit_out : 1;
+		mmr_t	underflow_iilb_vc2_credit_out : 1;
+		mmr_t	underflow_ni0_vc0_credit_out  : 1;
+		mmr_t	underflow_ni0_vc2_credit_out  : 1;
+		mmr_t	underflow_ni1_vc0_credit_out  : 1;
+		mmr_t	underflow_ni1_vc2_credit_out  : 1;
+		mmr_t	chiplet_nomatch               : 1;
+		mmr_t	lut_read_error                : 1;
+	} sh_xniilb_error_summary_s;
+} sh_xniilb_error_summary_u_t;
+#else
+typedef union sh_xniilb_error_summary_u {
+	mmr_t	sh_xniilb_error_summary_regval;
+	struct {
+		mmr_t	lut_read_error                : 1;
+		mmr_t	chiplet_nomatch               : 1;
+		mmr_t	underflow_ni1_vc2_credit_out  : 1;
+		mmr_t	underflow_ni1_vc0_credit_out  : 1;
+		mmr_t	underflow_ni0_vc2_credit_out  : 1;
+		mmr_t	underflow_ni0_vc0_credit_out  : 1;
+		mmr_t	underflow_iilb_vc2_credit_out : 1;
+		mmr_t	underflow_iilb_vc0_credit_out : 1;
+		mmr_t	underflow_md_vc2_credit_out   : 1;
+		mmr_t	underflow_md_vc0_credit_out   : 1;
+		mmr_t	underflow_pi_vc2_credit_out   : 1;
+		mmr_t	underflow_pi_vc0_credit_out   : 1;
+		mmr_t	overflow_ni1_vc2_credit_out   : 1;
+		mmr_t	overflow_ni1_vc0_credit_out   : 1;
+		mmr_t	overflow_ni0_vc2_credit_out   : 1;
+		mmr_t	overflow_ni0_vc0_credit_out   : 1;
+		mmr_t	overflow_iilb_vc2_credit_out  : 1;
+		mmr_t	overflow_iilb_vc0_credit_out  : 1;
+		mmr_t	overflow_md_vc2_credit_out    : 1;
+		mmr_t	overflow_md_vc0_credit_out    : 1;
+		mmr_t	overflow_pi_vc2_credit_out    : 1;
+		mmr_t	overflow_pi_vc0_credit_out    : 1;
+		mmr_t	overflow_ni1_debit2           : 1;
+		mmr_t	overflow_ni1_debit0           : 1;
+		mmr_t	overflow_ni0_debit2           : 1;
+		mmr_t	overflow_ni0_debit0           : 1;
+		mmr_t	overflow_md_debit2            : 1;
+		mmr_t	overflow_md_debit0            : 1;
+		mmr_t	overflow_iilb_debit2          : 1;
+		mmr_t	overflow_iilb_debit0          : 1;
+		mmr_t	overflow_pi_debit2            : 1;
+		mmr_t	overflow_pi_debit0            : 1;
+		mmr_t	underflow_ni1_vc2_credit_in   : 1;
+		mmr_t	underflow_ni0_vc2_credit_in   : 1;
+		mmr_t	underflow_md_vc2_credit_in    : 1;
+		mmr_t	underflow_iilb_vc2_credit_in  : 1;
+		mmr_t	underflow_pi_vc2_credit_in    : 1;
+		mmr_t	underflow_ni1_vc0_credit_in   : 1;
+		mmr_t	underflow_ni0_vc0_credit_in   : 1;
+		mmr_t	underflow_md_vc0_credit_in    : 1;
+		mmr_t	underflow_iilb_vc0_credit_in  : 1;
+		mmr_t	underflow_pi_vc0_credit_in    : 1;
+		mmr_t	overflow_ni1_vc2_credit_in    : 1;
+		mmr_t	overflow_ni0_vc2_credit_in    : 1;
+		mmr_t	overflow_md_vc2_credit_in     : 1;
+		mmr_t	overflow_iilb_vc2_credit_in   : 1;
+		mmr_t	overflow_pi_vc2_credit_in     : 1;
+		mmr_t	overflow_ni1_vc0_credit_in    : 1;
+		mmr_t	overflow_ni0_vc0_credit_in    : 1;
+		mmr_t	overflow_md_vc0_credit_in     : 1;
+		mmr_t	overflow_iilb_vc0_credit_in   : 1;
+		mmr_t	overflow_pi_vc0_credit_in     : 1;
+		mmr_t	underflow_lb_vc2              : 1;
+		mmr_t	underflow_lb_vc0              : 1;
+		mmr_t	overflow_lb_vc2               : 1;
+		mmr_t	overflow_lb_vc0               : 1;
+		mmr_t	underflow_ii_vc2              : 1;
+		mmr_t	underflow_ii_vc0              : 1;
+		mmr_t	overflow_ii_vc2               : 1;
+		mmr_t	overflow_ii_vc0               : 1;
+		mmr_t	overflow_lb_debit2            : 1;
+		mmr_t	overflow_lb_debit0            : 1;
+		mmr_t	overflow_ii_debit2            : 1;
+		mmr_t	overflow_ii_debit0            : 1;
+	} sh_xniilb_error_summary_s;
+} sh_xniilb_error_summary_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_XNIILB_ERROR_OVERFLOW"                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_error_overflow_u {
+	mmr_t	sh_xniilb_error_overflow_regval;
+	struct {
+		mmr_t	overflow_ii_debit0            : 1;
+		mmr_t	overflow_ii_debit2            : 1;
+		mmr_t	overflow_lb_debit0            : 1;
+		mmr_t	overflow_lb_debit2            : 1;
+		mmr_t	overflow_ii_vc0               : 1;
+		mmr_t	overflow_ii_vc2               : 1;
+		mmr_t	underflow_ii_vc0              : 1;
+		mmr_t	underflow_ii_vc2              : 1;
+		mmr_t	overflow_lb_vc0               : 1;
+		mmr_t	overflow_lb_vc2               : 1;
+		mmr_t	underflow_lb_vc0              : 1;
+		mmr_t	underflow_lb_vc2              : 1;
+		mmr_t	overflow_pi_vc0_credit_in     : 1;
+		mmr_t	overflow_iilb_vc0_credit_in   : 1;
+		mmr_t	overflow_md_vc0_credit_in     : 1;
+		mmr_t	overflow_ni0_vc0_credit_in    : 1;
+		mmr_t	overflow_ni1_vc0_credit_in    : 1;
+		mmr_t	overflow_pi_vc2_credit_in     : 1;
+		mmr_t	overflow_iilb_vc2_credit_in   : 1;
+		mmr_t	overflow_md_vc2_credit_in     : 1;
+		mmr_t	overflow_ni0_vc2_credit_in    : 1;
+		mmr_t	overflow_ni1_vc2_credit_in    : 1;
+		mmr_t	underflow_pi_vc0_credit_in    : 1;
+		mmr_t	underflow_iilb_vc0_credit_in  : 1;
+		mmr_t	underflow_md_vc0_credit_in    : 1;
+		mmr_t	underflow_ni0_vc0_credit_in   : 1;
+		mmr_t	underflow_ni1_vc0_credit_in   : 1;
+		mmr_t	underflow_pi_vc2_credit_in    : 1;
+		mmr_t	underflow_iilb_vc2_credit_in  : 1;
+		mmr_t	underflow_md_vc2_credit_in    : 1;
+		mmr_t	underflow_ni0_vc2_credit_in   : 1;
+		mmr_t	underflow_ni1_vc2_credit_in   : 1;
+		mmr_t	overflow_pi_debit0            : 1;
+		mmr_t	overflow_pi_debit2            : 1;
+		mmr_t	overflow_iilb_debit0          : 1;
+		mmr_t	overflow_iilb_debit2          : 1;
+		mmr_t	overflow_md_debit0            : 1;
+		mmr_t	overflow_md_debit2            : 1;
+		mmr_t	overflow_ni0_debit0           : 1;
+		mmr_t	overflow_ni0_debit2           : 1;
+		mmr_t	overflow_ni1_debit0           : 1;
+		mmr_t	overflow_ni1_debit2           : 1;
+		mmr_t	overflow_pi_vc0_credit_out    : 1;
+		mmr_t	overflow_pi_vc2_credit_out    : 1;
+		mmr_t	overflow_md_vc0_credit_out    : 1;
+		mmr_t	overflow_md_vc2_credit_out    : 1;
+		mmr_t	overflow_iilb_vc0_credit_out  : 1;
+		mmr_t	overflow_iilb_vc2_credit_out  : 1;
+		mmr_t	overflow_ni0_vc0_credit_out   : 1;
+		mmr_t	overflow_ni0_vc2_credit_out   : 1;
+		mmr_t	overflow_ni1_vc0_credit_out   : 1;
+		mmr_t	overflow_ni1_vc2_credit_out   : 1;
+		mmr_t	underflow_pi_vc0_credit_out   : 1;
+		mmr_t	underflow_pi_vc2_credit_out   : 1;
+		mmr_t	underflow_md_vc0_credit_out   : 1;
+		mmr_t	underflow_md_vc2_credit_out   : 1;
+		mmr_t	underflow_iilb_vc0_credit_out : 1;
+		mmr_t	underflow_iilb_vc2_credit_out : 1;
+		mmr_t	underflow_ni0_vc0_credit_out  : 1;
+		mmr_t	underflow_ni0_vc2_credit_out  : 1;
+		mmr_t	underflow_ni1_vc0_credit_out  : 1;
+		mmr_t	underflow_ni1_vc2_credit_out  : 1;
+		mmr_t	chiplet_nomatch               : 1;
+		mmr_t	lut_read_error                : 1;
+	} sh_xniilb_error_overflow_s;
+} sh_xniilb_error_overflow_u_t;
+#else
+typedef union sh_xniilb_error_overflow_u {
+	mmr_t	sh_xniilb_error_overflow_regval;
+	struct {
+		mmr_t	lut_read_error                : 1;
+		mmr_t	chiplet_nomatch               : 1;
+		mmr_t	underflow_ni1_vc2_credit_out  : 1;
+		mmr_t	underflow_ni1_vc0_credit_out  : 1;
+		mmr_t	underflow_ni0_vc2_credit_out  : 1;
+		mmr_t	underflow_ni0_vc0_credit_out  : 1;
+		mmr_t	underflow_iilb_vc2_credit_out : 1;
+		mmr_t	underflow_iilb_vc0_credit_out : 1;
+		mmr_t	underflow_md_vc2_credit_out   : 1;
+		mmr_t	underflow_md_vc0_credit_out   : 1;
+		mmr_t	underflow_pi_vc2_credit_out   : 1;
+		mmr_t	underflow_pi_vc0_credit_out   : 1;
+		mmr_t	overflow_ni1_vc2_credit_out   : 1;
+		mmr_t	overflow_ni1_vc0_credit_out   : 1;
+		mmr_t	overflow_ni0_vc2_credit_out   : 1;
+		mmr_t	overflow_ni0_vc0_credit_out   : 1;
+		mmr_t	overflow_iilb_vc2_credit_out  : 1;
+		mmr_t	overflow_iilb_vc0_credit_out  : 1;
+		mmr_t	overflow_md_vc2_credit_out    : 1;
+		mmr_t	overflow_md_vc0_credit_out    : 1;
+		mmr_t	overflow_pi_vc2_credit_out    : 1;
+		mmr_t	overflow_pi_vc0_credit_out    : 1;
+		mmr_t	overflow_ni1_debit2           : 1;
+		mmr_t	overflow_ni1_debit0           : 1;
+		mmr_t	overflow_ni0_debit2           : 1;
+		mmr_t	overflow_ni0_debit0           : 1;
+		mmr_t	overflow_md_debit2            : 1;
+		mmr_t	overflow_md_debit0            : 1;
+		mmr_t	overflow_iilb_debit2          : 1;
+		mmr_t	overflow_iilb_debit0          : 1;
+		mmr_t	overflow_pi_debit2            : 1;
+		mmr_t	overflow_pi_debit0            : 1;
+		mmr_t	underflow_ni1_vc2_credit_in   : 1;
+		mmr_t	underflow_ni0_vc2_credit_in   : 1;
+		mmr_t	underflow_md_vc2_credit_in    : 1;
+		mmr_t	underflow_iilb_vc2_credit_in  : 1;
+		mmr_t	underflow_pi_vc2_credit_in    : 1;
+		mmr_t	underflow_ni1_vc0_credit_in   : 1;
+		mmr_t	underflow_ni0_vc0_credit_in   : 1;
+		mmr_t	underflow_md_vc0_credit_in    : 1;
+		mmr_t	underflow_iilb_vc0_credit_in  : 1;
+		mmr_t	underflow_pi_vc0_credit_in    : 1;
+		mmr_t	overflow_ni1_vc2_credit_in    : 1;
+		mmr_t	overflow_ni0_vc2_credit_in    : 1;
+		mmr_t	overflow_md_vc2_credit_in     : 1;
+		mmr_t	overflow_iilb_vc2_credit_in   : 1;
+		mmr_t	overflow_pi_vc2_credit_in     : 1;
+		mmr_t	overflow_ni1_vc0_credit_in    : 1;
+		mmr_t	overflow_ni0_vc0_credit_in    : 1;
+		mmr_t	overflow_md_vc0_credit_in     : 1;
+		mmr_t	overflow_iilb_vc0_credit_in   : 1;
+		mmr_t	overflow_pi_vc0_credit_in     : 1;
+		mmr_t	underflow_lb_vc2              : 1;
+		mmr_t	underflow_lb_vc0              : 1;
+		mmr_t	overflow_lb_vc2               : 1;
+		mmr_t	overflow_lb_vc0               : 1;
+		mmr_t	underflow_ii_vc2              : 1;
+		mmr_t	underflow_ii_vc0              : 1;
+		mmr_t	overflow_ii_vc2               : 1;
+		mmr_t	overflow_ii_vc0               : 1;
+		mmr_t	overflow_lb_debit2            : 1;
+		mmr_t	overflow_lb_debit0            : 1;
+		mmr_t	overflow_ii_debit2            : 1;
+		mmr_t	overflow_ii_debit0            : 1;
+	} sh_xniilb_error_overflow_s;
+} sh_xniilb_error_overflow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNIILB_ERROR_MASK"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_error_mask_u {
+	mmr_t	sh_xniilb_error_mask_regval;
+	struct {
+		mmr_t	overflow_ii_debit0            : 1;
+		mmr_t	overflow_ii_debit2            : 1;
+		mmr_t	overflow_lb_debit0            : 1;
+		mmr_t	overflow_lb_debit2            : 1;
+		mmr_t	overflow_ii_vc0               : 1;
+		mmr_t	overflow_ii_vc2               : 1;
+		mmr_t	underflow_ii_vc0              : 1;
+		mmr_t	underflow_ii_vc2              : 1;
+		mmr_t	overflow_lb_vc0               : 1;
+		mmr_t	overflow_lb_vc2               : 1;
+		mmr_t	underflow_lb_vc0              : 1;
+		mmr_t	underflow_lb_vc2              : 1;
+		mmr_t	overflow_pi_vc0_credit_in     : 1;
+		mmr_t	overflow_iilb_vc0_credit_in   : 1;
+		mmr_t	overflow_md_vc0_credit_in     : 1;
+		mmr_t	overflow_ni0_vc0_credit_in    : 1;
+		mmr_t	overflow_ni1_vc0_credit_in    : 1;
+		mmr_t	overflow_pi_vc2_credit_in     : 1;
+		mmr_t	overflow_iilb_vc2_credit_in   : 1;
+		mmr_t	overflow_md_vc2_credit_in     : 1;
+		mmr_t	overflow_ni0_vc2_credit_in    : 1;
+		mmr_t	overflow_ni1_vc2_credit_in    : 1;
+		mmr_t	underflow_pi_vc0_credit_in    : 1;
+		mmr_t	underflow_iilb_vc0_credit_in  : 1;
+		mmr_t	underflow_md_vc0_credit_in    : 1;
+		mmr_t	underflow_ni0_vc0_credit_in   : 1;
+		mmr_t	underflow_ni1_vc0_credit_in   : 1;
+		mmr_t	underflow_pi_vc2_credit_in    : 1;
+		mmr_t	underflow_iilb_vc2_credit_in  : 1;
+		mmr_t	underflow_md_vc2_credit_in    : 1;
+		mmr_t	underflow_ni0_vc2_credit_in   : 1;
+		mmr_t	underflow_ni1_vc2_credit_in   : 1;
+		mmr_t	overflow_pi_debit0            : 1;
+		mmr_t	overflow_pi_debit2            : 1;
+		mmr_t	overflow_iilb_debit0          : 1;
+		mmr_t	overflow_iilb_debit2          : 1;
+		mmr_t	overflow_md_debit0            : 1;
+		mmr_t	overflow_md_debit2            : 1;
+		mmr_t	overflow_ni0_debit0           : 1;
+		mmr_t	overflow_ni0_debit2           : 1;
+		mmr_t	overflow_ni1_debit0           : 1;
+		mmr_t	overflow_ni1_debit2           : 1;
+		mmr_t	overflow_pi_vc0_credit_out    : 1;
+		mmr_t	overflow_pi_vc2_credit_out    : 1;
+		mmr_t	overflow_md_vc0_credit_out    : 1;
+		mmr_t	overflow_md_vc2_credit_out    : 1;
+		mmr_t	overflow_iilb_vc0_credit_out  : 1;
+		mmr_t	overflow_iilb_vc2_credit_out  : 1;
+		mmr_t	overflow_ni0_vc0_credit_out   : 1;
+		mmr_t	overflow_ni0_vc2_credit_out   : 1;
+		mmr_t	overflow_ni1_vc0_credit_out   : 1;
+		mmr_t	overflow_ni1_vc2_credit_out   : 1;
+		mmr_t	underflow_pi_vc0_credit_out   : 1;
+		mmr_t	underflow_pi_vc2_credit_out   : 1;
+		mmr_t	underflow_md_vc0_credit_out   : 1;
+		mmr_t	underflow_md_vc2_credit_out   : 1;
+		mmr_t	underflow_iilb_vc0_credit_out : 1;
+		mmr_t	underflow_iilb_vc2_credit_out : 1;
+		mmr_t	underflow_ni0_vc0_credit_out  : 1;
+		mmr_t	underflow_ni0_vc2_credit_out  : 1;
+		mmr_t	underflow_ni1_vc0_credit_out  : 1;
+		mmr_t	underflow_ni1_vc2_credit_out  : 1;
+		mmr_t	chiplet_nomatch               : 1;
+		mmr_t	lut_read_error                : 1;
+	} sh_xniilb_error_mask_s;
+} sh_xniilb_error_mask_u_t;
+#else
+typedef union sh_xniilb_error_mask_u {
+	mmr_t	sh_xniilb_error_mask_regval;
+	struct {
+		mmr_t	lut_read_error                : 1;
+		mmr_t	chiplet_nomatch               : 1;
+		mmr_t	underflow_ni1_vc2_credit_out  : 1;
+		mmr_t	underflow_ni1_vc0_credit_out  : 1;
+		mmr_t	underflow_ni0_vc2_credit_out  : 1;
+		mmr_t	underflow_ni0_vc0_credit_out  : 1;
+		mmr_t	underflow_iilb_vc2_credit_out : 1;
+		mmr_t	underflow_iilb_vc0_credit_out : 1;
+		mmr_t	underflow_md_vc2_credit_out   : 1;
+		mmr_t	underflow_md_vc0_credit_out   : 1;
+		mmr_t	underflow_pi_vc2_credit_out   : 1;
+		mmr_t	underflow_pi_vc0_credit_out   : 1;
+		mmr_t	overflow_ni1_vc2_credit_out   : 1;
+		mmr_t	overflow_ni1_vc0_credit_out   : 1;
+		mmr_t	overflow_ni0_vc2_credit_out   : 1;
+		mmr_t	overflow_ni0_vc0_credit_out   : 1;
+		mmr_t	overflow_iilb_vc2_credit_out  : 1;
+		mmr_t	overflow_iilb_vc0_credit_out  : 1;
+		mmr_t	overflow_md_vc2_credit_out    : 1;
+		mmr_t	overflow_md_vc0_credit_out    : 1;
+		mmr_t	overflow_pi_vc2_credit_out    : 1;
+		mmr_t	overflow_pi_vc0_credit_out    : 1;
+		mmr_t	overflow_ni1_debit2           : 1;
+		mmr_t	overflow_ni1_debit0           : 1;
+		mmr_t	overflow_ni0_debit2           : 1;
+		mmr_t	overflow_ni0_debit0           : 1;
+		mmr_t	overflow_md_debit2            : 1;
+		mmr_t	overflow_md_debit0            : 1;
+		mmr_t	overflow_iilb_debit2          : 1;
+		mmr_t	overflow_iilb_debit0          : 1;
+		mmr_t	overflow_pi_debit2            : 1;
+		mmr_t	overflow_pi_debit0            : 1;
+		mmr_t	underflow_ni1_vc2_credit_in   : 1;
+		mmr_t	underflow_ni0_vc2_credit_in   : 1;
+		mmr_t	underflow_md_vc2_credit_in    : 1;
+		mmr_t	underflow_iilb_vc2_credit_in  : 1;
+		mmr_t	underflow_pi_vc2_credit_in    : 1;
+		mmr_t	underflow_ni1_vc0_credit_in   : 1;
+		mmr_t	underflow_ni0_vc0_credit_in   : 1;
+		mmr_t	underflow_md_vc0_credit_in    : 1;
+		mmr_t	underflow_iilb_vc0_credit_in  : 1;
+		mmr_t	underflow_pi_vc0_credit_in    : 1;
+		mmr_t	overflow_ni1_vc2_credit_in    : 1;
+		mmr_t	overflow_ni0_vc2_credit_in    : 1;
+		mmr_t	overflow_md_vc2_credit_in     : 1;
+		mmr_t	overflow_iilb_vc2_credit_in   : 1;
+		mmr_t	overflow_pi_vc2_credit_in     : 1;
+		mmr_t	overflow_ni1_vc0_credit_in    : 1;
+		mmr_t	overflow_ni0_vc0_credit_in    : 1;
+		mmr_t	overflow_md_vc0_credit_in     : 1;
+		mmr_t	overflow_iilb_vc0_credit_in   : 1;
+		mmr_t	overflow_pi_vc0_credit_in     : 1;
+		mmr_t	underflow_lb_vc2              : 1;
+		mmr_t	underflow_lb_vc0              : 1;
+		mmr_t	overflow_lb_vc2               : 1;
+		mmr_t	overflow_lb_vc0               : 1;
+		mmr_t	underflow_ii_vc2              : 1;
+		mmr_t	underflow_ii_vc0              : 1;
+		mmr_t	overflow_ii_vc2               : 1;
+		mmr_t	overflow_ii_vc0               : 1;
+		mmr_t	overflow_lb_debit2            : 1;
+		mmr_t	overflow_lb_debit0            : 1;
+		mmr_t	overflow_ii_debit2            : 1;
+		mmr_t	overflow_ii_debit0            : 1;
+	} sh_xniilb_error_mask_s;
+} sh_xniilb_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNIILB_FIRST_ERROR"                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xniilb_first_error_u {
+	mmr_t	sh_xniilb_first_error_regval;
+	struct {
+		mmr_t	overflow_ii_debit0            : 1;
+		mmr_t	overflow_ii_debit2            : 1;
+		mmr_t	overflow_lb_debit0            : 1;
+		mmr_t	overflow_lb_debit2            : 1;
+		mmr_t	overflow_ii_vc0               : 1;
+		mmr_t	overflow_ii_vc2               : 1;
+		mmr_t	underflow_ii_vc0              : 1;
+		mmr_t	underflow_ii_vc2              : 1;
+		mmr_t	overflow_lb_vc0               : 1;
+		mmr_t	overflow_lb_vc2               : 1;
+		mmr_t	underflow_lb_vc0              : 1;
+		mmr_t	underflow_lb_vc2              : 1;
+		mmr_t	overflow_pi_vc0_credit_in     : 1;
+		mmr_t	overflow_iilb_vc0_credit_in   : 1;
+		mmr_t	overflow_md_vc0_credit_in     : 1;
+		mmr_t	overflow_ni0_vc0_credit_in    : 1;
+		mmr_t	overflow_ni1_vc0_credit_in    : 1;
+		mmr_t	overflow_pi_vc2_credit_in     : 1;
+		mmr_t	overflow_iilb_vc2_credit_in   : 1;
+		mmr_t	overflow_md_vc2_credit_in     : 1;
+		mmr_t	overflow_ni0_vc2_credit_in    : 1;
+		mmr_t	overflow_ni1_vc2_credit_in    : 1;
+		mmr_t	underflow_pi_vc0_credit_in    : 1;
+		mmr_t	underflow_iilb_vc0_credit_in  : 1;
+		mmr_t	underflow_md_vc0_credit_in    : 1;
+		mmr_t	underflow_ni0_vc0_credit_in   : 1;
+		mmr_t	underflow_ni1_vc0_credit_in   : 1;
+		mmr_t	underflow_pi_vc2_credit_in    : 1;
+		mmr_t	underflow_iilb_vc2_credit_in  : 1;
+		mmr_t	underflow_md_vc2_credit_in    : 1;
+		mmr_t	underflow_ni0_vc2_credit_in   : 1;
+		mmr_t	underflow_ni1_vc2_credit_in   : 1;
+		mmr_t	overflow_pi_debit0            : 1;
+		mmr_t	overflow_pi_debit2            : 1;
+		mmr_t	overflow_iilb_debit0          : 1;
+		mmr_t	overflow_iilb_debit2          : 1;
+		mmr_t	overflow_md_debit0            : 1;
+		mmr_t	overflow_md_debit2            : 1;
+		mmr_t	overflow_ni0_debit0           : 1;
+		mmr_t	overflow_ni0_debit2           : 1;
+		mmr_t	overflow_ni1_debit0           : 1;
+		mmr_t	overflow_ni1_debit2           : 1;
+		mmr_t	overflow_pi_vc0_credit_out    : 1;
+		mmr_t	overflow_pi_vc2_credit_out    : 1;
+		mmr_t	overflow_md_vc0_credit_out    : 1;
+		mmr_t	overflow_md_vc2_credit_out    : 1;
+		mmr_t	overflow_iilb_vc0_credit_out  : 1;
+		mmr_t	overflow_iilb_vc2_credit_out  : 1;
+		mmr_t	overflow_ni0_vc0_credit_out   : 1;
+		mmr_t	overflow_ni0_vc2_credit_out   : 1;
+		mmr_t	overflow_ni1_vc0_credit_out   : 1;
+		mmr_t	overflow_ni1_vc2_credit_out   : 1;
+		mmr_t	underflow_pi_vc0_credit_out   : 1;
+		mmr_t	underflow_pi_vc2_credit_out   : 1;
+		mmr_t	underflow_md_vc0_credit_out   : 1;
+		mmr_t	underflow_md_vc2_credit_out   : 1;
+		mmr_t	underflow_iilb_vc0_credit_out : 1;
+		mmr_t	underflow_iilb_vc2_credit_out : 1;
+		mmr_t	underflow_ni0_vc0_credit_out  : 1;
+		mmr_t	underflow_ni0_vc2_credit_out  : 1;
+		mmr_t	underflow_ni1_vc0_credit_out  : 1;
+		mmr_t	underflow_ni1_vc2_credit_out  : 1;
+		mmr_t	chiplet_nomatch               : 1;
+		mmr_t	lut_read_error                : 1;
+	} sh_xniilb_first_error_s;
+} sh_xniilb_first_error_u_t;
+#else
+typedef union sh_xniilb_first_error_u {
+	mmr_t	sh_xniilb_first_error_regval;
+	struct {
+		mmr_t	lut_read_error                : 1;
+		mmr_t	chiplet_nomatch               : 1;
+		mmr_t	underflow_ni1_vc2_credit_out  : 1;
+		mmr_t	underflow_ni1_vc0_credit_out  : 1;
+		mmr_t	underflow_ni0_vc2_credit_out  : 1;
+		mmr_t	underflow_ni0_vc0_credit_out  : 1;
+		mmr_t	underflow_iilb_vc2_credit_out : 1;
+		mmr_t	underflow_iilb_vc0_credit_out : 1;
+		mmr_t	underflow_md_vc2_credit_out   : 1;
+		mmr_t	underflow_md_vc0_credit_out   : 1;
+		mmr_t	underflow_pi_vc2_credit_out   : 1;
+		mmr_t	underflow_pi_vc0_credit_out   : 1;
+		mmr_t	overflow_ni1_vc2_credit_out   : 1;
+		mmr_t	overflow_ni1_vc0_credit_out   : 1;
+		mmr_t	overflow_ni0_vc2_credit_out   : 1;
+		mmr_t	overflow_ni0_vc0_credit_out   : 1;
+		mmr_t	overflow_iilb_vc2_credit_out  : 1;
+		mmr_t	overflow_iilb_vc0_credit_out  : 1;
+		mmr_t	overflow_md_vc2_credit_out    : 1;
+		mmr_t	overflow_md_vc0_credit_out    : 1;
+		mmr_t	overflow_pi_vc2_credit_out    : 1;
+		mmr_t	overflow_pi_vc0_credit_out    : 1;
+		mmr_t	overflow_ni1_debit2           : 1;
+		mmr_t	overflow_ni1_debit0           : 1;
+		mmr_t	overflow_ni0_debit2           : 1;
+		mmr_t	overflow_ni0_debit0           : 1;
+		mmr_t	overflow_md_debit2            : 1;
+		mmr_t	overflow_md_debit0            : 1;
+		mmr_t	overflow_iilb_debit2          : 1;
+		mmr_t	overflow_iilb_debit0          : 1;
+		mmr_t	overflow_pi_debit2            : 1;
+		mmr_t	overflow_pi_debit0            : 1;
+		mmr_t	underflow_ni1_vc2_credit_in   : 1;
+		mmr_t	underflow_ni0_vc2_credit_in   : 1;
+		mmr_t	underflow_md_vc2_credit_in    : 1;
+		mmr_t	underflow_iilb_vc2_credit_in  : 1;
+		mmr_t	underflow_pi_vc2_credit_in    : 1;
+		mmr_t	underflow_ni1_vc0_credit_in   : 1;
+		mmr_t	underflow_ni0_vc0_credit_in   : 1;
+		mmr_t	underflow_md_vc0_credit_in    : 1;
+		mmr_t	underflow_iilb_vc0_credit_in  : 1;
+		mmr_t	underflow_pi_vc0_credit_in    : 1;
+		mmr_t	overflow_ni1_vc2_credit_in    : 1;
+		mmr_t	overflow_ni0_vc2_credit_in    : 1;
+		mmr_t	overflow_md_vc2_credit_in     : 1;
+		mmr_t	overflow_iilb_vc2_credit_in   : 1;
+		mmr_t	overflow_pi_vc2_credit_in     : 1;
+		mmr_t	overflow_ni1_vc0_credit_in    : 1;
+		mmr_t	overflow_ni0_vc0_credit_in    : 1;
+		mmr_t	overflow_md_vc0_credit_in     : 1;
+		mmr_t	overflow_iilb_vc0_credit_in   : 1;
+		mmr_t	overflow_pi_vc0_credit_in     : 1;
+		mmr_t	underflow_lb_vc2              : 1;
+		mmr_t	underflow_lb_vc0              : 1;
+		mmr_t	overflow_lb_vc2               : 1;
+		mmr_t	overflow_lb_vc0               : 1;
+		mmr_t	underflow_ii_vc2              : 1;
+		mmr_t	underflow_ii_vc0              : 1;
+		mmr_t	overflow_ii_vc2               : 1;
+		mmr_t	overflow_ii_vc0               : 1;
+		mmr_t	overflow_lb_debit2            : 1;
+		mmr_t	overflow_lb_debit0            : 1;
+		mmr_t	overflow_ii_debit2            : 1;
+		mmr_t	overflow_ii_debit0            : 1;
+	} sh_xniilb_first_error_s;
+} sh_xniilb_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNPI_ERROR_SUMMARY"                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_error_summary_u {
+	mmr_t	sh_xnpi_error_summary_regval;
+	struct {
+		mmr_t	underflow_ni0_vc0           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	reserved_0                  : 14;
+	} sh_xnpi_error_summary_s;
+} sh_xnpi_error_summary_u_t;
+#else
+typedef union sh_xnpi_error_summary_u {
+	mmr_t	sh_xnpi_error_summary_regval;
+	struct {
+		mmr_t	reserved_0                  : 14;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc0           : 1;
+	} sh_xnpi_error_summary_s;
+} sh_xnpi_error_summary_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNPI_ERROR_OVERFLOW"                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_error_overflow_u {
+	mmr_t	sh_xnpi_error_overflow_regval;
+	struct {
+		mmr_t	underflow_ni0_vc0           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	reserved_0                  : 14;
+	} sh_xnpi_error_overflow_s;
+} sh_xnpi_error_overflow_u_t;
+#else
+typedef union sh_xnpi_error_overflow_u {
+	mmr_t	sh_xnpi_error_overflow_regval;
+	struct {
+		mmr_t	reserved_0                  : 14;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc0           : 1;
+	} sh_xnpi_error_overflow_s;
+} sh_xnpi_error_overflow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNPI_ERROR_MASK"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_error_mask_u {
+	mmr_t	sh_xnpi_error_mask_regval;
+	struct {
+		mmr_t	underflow_ni0_vc0           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	reserved_0                  : 14;
+	} sh_xnpi_error_mask_s;
+} sh_xnpi_error_mask_u_t;
+#else
+typedef union sh_xnpi_error_mask_u {
+	mmr_t	sh_xnpi_error_mask_regval;
+	struct {
+		mmr_t	reserved_0                  : 14;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc0           : 1;
+	} sh_xnpi_error_mask_s;
+} sh_xnpi_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNPI_FIRST_ERROR"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnpi_first_error_u {
+	mmr_t	sh_xnpi_first_error_regval;
+	struct {
+		mmr_t	underflow_ni0_vc0           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	reserved_0                  : 14;
+	} sh_xnpi_first_error_s;
+} sh_xnpi_first_error_u_t;
+#else
+typedef union sh_xnpi_first_error_u {
+	mmr_t	sh_xnpi_first_error_regval;
+	struct {
+		mmr_t	reserved_0                  : 14;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc0           : 1;
+	} sh_xnpi_first_error_s;
+} sh_xnpi_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XNMD_ERROR_SUMMARY"                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_error_summary_u {
+	mmr_t	sh_xnmd_error_summary_regval;
+	struct {
+		mmr_t	underflow_ni0_vc0           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	reserved_0                  : 14;
+	} sh_xnmd_error_summary_s;
+} sh_xnmd_error_summary_u_t;
+#else
+typedef union sh_xnmd_error_summary_u {
+	mmr_t	sh_xnmd_error_summary_regval;
+	struct {
+		mmr_t	reserved_0                  : 14;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc0           : 1;
+	} sh_xnmd_error_summary_s;
+} sh_xnmd_error_summary_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XNMD_ERROR_OVERFLOW"                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_error_overflow_u {
+	mmr_t	sh_xnmd_error_overflow_regval;
+	struct {
+		mmr_t	underflow_ni0_vc0           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	reserved_0                  : 14;
+	} sh_xnmd_error_overflow_s;
+} sh_xnmd_error_overflow_u_t;
+#else
+typedef union sh_xnmd_error_overflow_u {
+	mmr_t	sh_xnmd_error_overflow_regval;
+	struct {
+		mmr_t	reserved_0                  : 14;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc0           : 1;
+	} sh_xnmd_error_overflow_s;
+} sh_xnmd_error_overflow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNMD_ERROR_MASK"                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_error_mask_u {
+	mmr_t	sh_xnmd_error_mask_regval;
+	struct {
+		mmr_t	underflow_ni0_vc0           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	reserved_0                  : 14;
+	} sh_xnmd_error_mask_s;
+} sh_xnmd_error_mask_u_t;
+#else
+typedef union sh_xnmd_error_mask_u {
+	mmr_t	sh_xnmd_error_mask_regval;
+	struct {
+		mmr_t	reserved_0                  : 14;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc0           : 1;
+	} sh_xnmd_error_mask_s;
+} sh_xnmd_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XNMD_FIRST_ERROR"                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xnmd_first_error_u {
+	mmr_t	sh_xnmd_first_error_regval;
+	struct {
+		mmr_t	underflow_ni0_vc0           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	reserved_0                  : 14;
+	} sh_xnmd_first_error_s;
+} sh_xnmd_first_error_u_t;
+#else
+typedef union sh_xnmd_first_error_u {
+	mmr_t	sh_xnmd_first_error_regval;
+	struct {
+		mmr_t	reserved_0                  : 14;
+		mmr_t	overflow_header_cancel_fifo : 1;
+		mmr_t	overflow_iilb_vc2_credit    : 1;
+		mmr_t	underflow_iilb_vc2_credit   : 1;
+		mmr_t	overflow_iilb_vc0_credit    : 1;
+		mmr_t	underflow_iilb_vc0_credit   : 1;
+		mmr_t	overflow_ni1_vc2_credit     : 1;
+		mmr_t	underflow_ni1_vc2_credit    : 1;
+		mmr_t	overflow_ni1_vc0_credit     : 1;
+		mmr_t	underflow_ni1_vc0_credit    : 1;
+		mmr_t	overflow_ni0_vc2_credit     : 1;
+		mmr_t	underflow_ni0_vc2_credit    : 1;
+		mmr_t	overflow_ni0_vc0_credit     : 1;
+		mmr_t	underflow_ni0_vc0_credit    : 1;
+		mmr_t	overflow_iilb_debit2        : 1;
+		mmr_t	overflow_iilb_debit0        : 1;
+		mmr_t	overflow_ni1_debit2         : 1;
+		mmr_t	overflow_ni1_debit0         : 1;
+		mmr_t	overflow_ni0_debit2         : 1;
+		mmr_t	overflow_ni0_debit0         : 1;
+		mmr_t	overflow_sic_cntr2          : 1;
+		mmr_t	underflow_sic_cntr2         : 1;
+		mmr_t	overflow_sic_cntr0          : 1;
+		mmr_t	underflow_sic_cntr0         : 1;
+		mmr_t	uncor_error3                : 1;
+		mmr_t	uncor_error2                : 1;
+		mmr_t	uncor_error1                : 1;
+		mmr_t	uncor_error0                : 1;
+		mmr_t	single_bit_error3           : 1;
+		mmr_t	single_bit_error2           : 1;
+		mmr_t	single_bit_error1           : 1;
+		mmr_t	single_bit_error0           : 1;
+		mmr_t	lut_read_error              : 1;
+		mmr_t	overflow_databuff_vc2       : 1;
+		mmr_t	overflow_databuff_vc0       : 1;
+		mmr_t	overflow_vc2_credit         : 1;
+		mmr_t	underflow_vc2_credit        : 1;
+		mmr_t	overflow_vc0_credit         : 1;
+		mmr_t	underflow_vc0_credit        : 1;
+		mmr_t	overflow_iilb_vc2           : 1;
+		mmr_t	underflow_iilb_vc2          : 1;
+		mmr_t	overflow_iilb_vc0           : 1;
+		mmr_t	underflow_iilb_vc0          : 1;
+		mmr_t	overflow_ni1_vc2            : 1;
+		mmr_t	underflow_ni1_vc2           : 1;
+		mmr_t	overflow_ni1_vc0            : 1;
+		mmr_t	underflow_ni1_vc0           : 1;
+		mmr_t	overflow_ni0_vc2            : 1;
+		mmr_t	underflow_ni0_vc2           : 1;
+		mmr_t	overflow_ni0_vc0            : 1;
+		mmr_t	underflow_ni0_vc0           : 1;
+	} sh_xnmd_first_error_s;
+} sh_xnmd_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_AUTO_REPLY_ENABLE0"                   */
+/*                 Automatic Maintenance Reply Enable 0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_auto_reply_enable0_u {
+	mmr_t	sh_auto_reply_enable0_regval;
+	struct {
+		mmr_t	enable0     : 64;
+	} sh_auto_reply_enable0_s;
+} sh_auto_reply_enable0_u_t;
+#else
+typedef union sh_auto_reply_enable0_u {
+	mmr_t	sh_auto_reply_enable0_regval;
+	struct {
+		mmr_t	enable0     : 64;
+	} sh_auto_reply_enable0_s;
+} sh_auto_reply_enable0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_AUTO_REPLY_ENABLE1"                   */
+/*                 Automatic Maintenance Reply Enable 1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_auto_reply_enable1_u {
+	mmr_t	sh_auto_reply_enable1_regval;
+	struct {
+		mmr_t	enable1     : 64;
+	} sh_auto_reply_enable1_s;
+} sh_auto_reply_enable1_u_t;
+#else
+typedef union sh_auto_reply_enable1_u {
+	mmr_t	sh_auto_reply_enable1_regval;
+	struct {
+		mmr_t	enable1     : 64;
+	} sh_auto_reply_enable1_s;
+} sh_auto_reply_enable1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_AUTO_REPLY_HEADER0"                   */
+/*                 Automatic Maintenance Reply Header 0                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_auto_reply_header0_u {
+	mmr_t	sh_auto_reply_header0_regval;
+	struct {
+		mmr_t	header0     : 64;
+	} sh_auto_reply_header0_s;
+} sh_auto_reply_header0_u_t;
+#else
+typedef union sh_auto_reply_header0_u {
+	mmr_t	sh_auto_reply_header0_regval;
+	struct {
+		mmr_t	header0     : 64;
+	} sh_auto_reply_header0_s;
+} sh_auto_reply_header0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_AUTO_REPLY_HEADER1"                   */
+/*                 Automatic Maintenance Reply Header 1                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_auto_reply_header1_u {
+	mmr_t	sh_auto_reply_header1_regval;
+	struct {
+		mmr_t	header1     : 64;
+	} sh_auto_reply_header1_s;
+} sh_auto_reply_header1_u_t;
+#else
+typedef union sh_auto_reply_header1_u {
+	mmr_t	sh_auto_reply_header1_regval;
+	struct {
+		mmr_t	header1     : 64;
+	} sh_auto_reply_header1_s;
+} sh_auto_reply_header1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_ENABLE_RP_AUTO_REPLY"                  */
+/*         Enable Automatic Maintenance Reply From Reply Queue          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_enable_rp_auto_reply_u {
+	mmr_t	sh_enable_rp_auto_reply_regval;
+	struct {
+		mmr_t	enable      : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_enable_rp_auto_reply_s;
+} sh_enable_rp_auto_reply_u_t;
+#else
+typedef union sh_enable_rp_auto_reply_u {
+	mmr_t	sh_enable_rp_auto_reply_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	enable      : 1;
+	} sh_enable_rp_auto_reply_s;
+} sh_enable_rp_auto_reply_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_ENABLE_RQ_AUTO_REPLY"                  */
+/*        Enable Automatic Maintenance Reply From Request Queue         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_enable_rq_auto_reply_u {
+	mmr_t	sh_enable_rq_auto_reply_regval;
+	struct {
+		mmr_t	enable      : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_enable_rq_auto_reply_s;
+} sh_enable_rq_auto_reply_u_t;
+#else
+typedef union sh_enable_rq_auto_reply_u {
+	mmr_t	sh_enable_rq_auto_reply_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	enable      : 1;
+	} sh_enable_rq_auto_reply_s;
+} sh_enable_rq_auto_reply_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_REDIRECT_INVAL"                     */
+/*               Redirect invalidate to LB instead of PI                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_redirect_inval_u {
+	mmr_t	sh_redirect_inval_regval;
+	struct {
+		mmr_t	redirect    : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_redirect_inval_s;
+} sh_redirect_inval_u_t;
+#else
+typedef union sh_redirect_inval_u {
+	mmr_t	sh_redirect_inval_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	redirect    : 1;
+	} sh_redirect_inval_s;
+} sh_redirect_inval_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_DIAG_MSG_CNTRL"                     */
+/*                 Diagnostic Message Control Register                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_cntrl_u {
+	mmr_t	sh_diag_msg_cntrl_regval;
+	struct {
+		mmr_t	msg_length          : 6;
+		mmr_t	error_inject_point  : 6;
+		mmr_t	error_inject_enable : 1;
+		mmr_t	port                : 1;
+		mmr_t	reserved_0          : 48;
+		mmr_t	start               : 1;
+		mmr_t	busy                : 1;
+	} sh_diag_msg_cntrl_s;
+} sh_diag_msg_cntrl_u_t;
+#else
+typedef union sh_diag_msg_cntrl_u {
+	mmr_t	sh_diag_msg_cntrl_regval;
+	struct {
+		mmr_t	busy                : 1;
+		mmr_t	start               : 1;
+		mmr_t	reserved_0          : 48;
+		mmr_t	port                : 1;
+		mmr_t	error_inject_enable : 1;
+		mmr_t	error_inject_point  : 6;
+		mmr_t	msg_length          : 6;
+	} sh_diag_msg_cntrl_s;
+} sh_diag_msg_cntrl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA0L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data0l_u {
+	mmr_t	sh_diag_msg_data0l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data0l_s;
+} sh_diag_msg_data0l_u_t;
+#else
+typedef union sh_diag_msg_data0l_u {
+	mmr_t	sh_diag_msg_data0l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data0l_s;
+} sh_diag_msg_data0l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA0U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data0u_u {
+	mmr_t	sh_diag_msg_data0u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data0u_s;
+} sh_diag_msg_data0u_u_t;
+#else
+typedef union sh_diag_msg_data0u_u {
+	mmr_t	sh_diag_msg_data0u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data0u_s;
+} sh_diag_msg_data0u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA1L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data1l_u {
+	mmr_t	sh_diag_msg_data1l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data1l_s;
+} sh_diag_msg_data1l_u_t;
+#else
+typedef union sh_diag_msg_data1l_u {
+	mmr_t	sh_diag_msg_data1l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data1l_s;
+} sh_diag_msg_data1l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA1U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data1u_u {
+	mmr_t	sh_diag_msg_data1u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data1u_s;
+} sh_diag_msg_data1u_u_t;
+#else
+typedef union sh_diag_msg_data1u_u {
+	mmr_t	sh_diag_msg_data1u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data1u_s;
+} sh_diag_msg_data1u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA2L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data2l_u {
+	mmr_t	sh_diag_msg_data2l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data2l_s;
+} sh_diag_msg_data2l_u_t;
+#else
+typedef union sh_diag_msg_data2l_u {
+	mmr_t	sh_diag_msg_data2l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data2l_s;
+} sh_diag_msg_data2l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA2U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data2u_u {
+	mmr_t	sh_diag_msg_data2u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data2u_s;
+} sh_diag_msg_data2u_u_t;
+#else
+typedef union sh_diag_msg_data2u_u {
+	mmr_t	sh_diag_msg_data2u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data2u_s;
+} sh_diag_msg_data2u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA3L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data3l_u {
+	mmr_t	sh_diag_msg_data3l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data3l_s;
+} sh_diag_msg_data3l_u_t;
+#else
+typedef union sh_diag_msg_data3l_u {
+	mmr_t	sh_diag_msg_data3l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data3l_s;
+} sh_diag_msg_data3l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA3U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data3u_u {
+	mmr_t	sh_diag_msg_data3u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data3u_s;
+} sh_diag_msg_data3u_u_t;
+#else
+typedef union sh_diag_msg_data3u_u {
+	mmr_t	sh_diag_msg_data3u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data3u_s;
+} sh_diag_msg_data3u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA4L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data4l_u {
+	mmr_t	sh_diag_msg_data4l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data4l_s;
+} sh_diag_msg_data4l_u_t;
+#else
+typedef union sh_diag_msg_data4l_u {
+	mmr_t	sh_diag_msg_data4l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data4l_s;
+} sh_diag_msg_data4l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA4U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data4u_u {
+	mmr_t	sh_diag_msg_data4u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data4u_s;
+} sh_diag_msg_data4u_u_t;
+#else
+typedef union sh_diag_msg_data4u_u {
+	mmr_t	sh_diag_msg_data4u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data4u_s;
+} sh_diag_msg_data4u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA5L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data5l_u {
+	mmr_t	sh_diag_msg_data5l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data5l_s;
+} sh_diag_msg_data5l_u_t;
+#else
+typedef union sh_diag_msg_data5l_u {
+	mmr_t	sh_diag_msg_data5l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data5l_s;
+} sh_diag_msg_data5l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA5U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data5u_u {
+	mmr_t	sh_diag_msg_data5u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data5u_s;
+} sh_diag_msg_data5u_u_t;
+#else
+typedef union sh_diag_msg_data5u_u {
+	mmr_t	sh_diag_msg_data5u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data5u_s;
+} sh_diag_msg_data5u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA6L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data6l_u {
+	mmr_t	sh_diag_msg_data6l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data6l_s;
+} sh_diag_msg_data6l_u_t;
+#else
+typedef union sh_diag_msg_data6l_u {
+	mmr_t	sh_diag_msg_data6l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data6l_s;
+} sh_diag_msg_data6l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA6U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data6u_u {
+	mmr_t	sh_diag_msg_data6u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data6u_s;
+} sh_diag_msg_data6u_u_t;
+#else
+typedef union sh_diag_msg_data6u_u {
+	mmr_t	sh_diag_msg_data6u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data6u_s;
+} sh_diag_msg_data6u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA7L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data7l_u {
+	mmr_t	sh_diag_msg_data7l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data7l_s;
+} sh_diag_msg_data7l_u_t;
+#else
+typedef union sh_diag_msg_data7l_u {
+	mmr_t	sh_diag_msg_data7l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data7l_s;
+} sh_diag_msg_data7l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA7U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data7u_u {
+	mmr_t	sh_diag_msg_data7u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data7u_s;
+} sh_diag_msg_data7u_u_t;
+#else
+typedef union sh_diag_msg_data7u_u {
+	mmr_t	sh_diag_msg_data7u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data7u_s;
+} sh_diag_msg_data7u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA8L"                     */
+/*                    Diagnostic Data, lower 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data8l_u {
+	mmr_t	sh_diag_msg_data8l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data8l_s;
+} sh_diag_msg_data8l_u_t;
+#else
+typedef union sh_diag_msg_data8l_u {
+	mmr_t	sh_diag_msg_data8l_regval;
+	struct {
+		mmr_t	data_lower  : 64;
+	} sh_diag_msg_data8l_s;
+} sh_diag_msg_data8l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_DIAG_MSG_DATA8U"                     */
+/*                   Diagnostice Data, upper 64 bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_data8u_u {
+	mmr_t	sh_diag_msg_data8u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data8u_s;
+} sh_diag_msg_data8u_u_t;
+#else
+typedef union sh_diag_msg_data8u_u {
+	mmr_t	sh_diag_msg_data8u_regval;
+	struct {
+		mmr_t	data_upper  : 64;
+	} sh_diag_msg_data8u_s;
+} sh_diag_msg_data8u_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_DIAG_MSG_HDR0"                      */
+/*              Diagnostice Data, lower 64 bits of header               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_hdr0_u {
+	mmr_t	sh_diag_msg_hdr0_regval;
+	struct {
+		mmr_t	header0     : 64;
+	} sh_diag_msg_hdr0_s;
+} sh_diag_msg_hdr0_u_t;
+#else
+typedef union sh_diag_msg_hdr0_u {
+	mmr_t	sh_diag_msg_hdr0_regval;
+	struct {
+		mmr_t	header0     : 64;
+	} sh_diag_msg_hdr0_s;
+} sh_diag_msg_hdr0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_DIAG_MSG_HDR1"                      */
+/*              Diagnostice Data, upper 64 bits of header               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_diag_msg_hdr1_u {
+	mmr_t	sh_diag_msg_hdr1_regval;
+	struct {
+		mmr_t	header1     : 64;
+	} sh_diag_msg_hdr1_s;
+} sh_diag_msg_hdr1_u_t;
+#else
+typedef union sh_diag_msg_hdr1_u {
+	mmr_t	sh_diag_msg_hdr1_regval;
+	struct {
+		mmr_t	header1     : 64;
+	} sh_diag_msg_hdr1_s;
+} sh_diag_msg_hdr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_DEBUG_SELECT"                      */
+/*                        SHub Debug Port Select                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_debug_select_u {
+	mmr_t	sh_debug_select_regval;
+	struct {
+		mmr_t	nibble0_nibble_sel  : 3;
+		mmr_t	nibble0_chiplet_sel : 3;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	debug_ii_sel        : 3;
+		mmr_t	sel_ii              : 9;
+		mmr_t	reserved_0          : 3;
+		mmr_t	trigger_enable      : 1;
+	} sh_debug_select_s;
+} sh_debug_select_u_t;
+#else
+typedef union sh_debug_select_u {
+	mmr_t	sh_debug_select_regval;
+	struct {
+		mmr_t	trigger_enable      : 1;
+		mmr_t	reserved_0          : 3;
+		mmr_t	sel_ii              : 9;
+		mmr_t	debug_ii_sel        : 3;
+		mmr_t	nibble7_chiplet_sel : 3;
+		mmr_t	nibble7_nibble_sel  : 3;
+		mmr_t	nibble6_chiplet_sel : 3;
+		mmr_t	nibble6_nibble_sel  : 3;
+		mmr_t	nibble5_chiplet_sel : 3;
+		mmr_t	nibble5_nibble_sel  : 3;
+		mmr_t	nibble4_chiplet_sel : 3;
+		mmr_t	nibble4_nibble_sel  : 3;
+		mmr_t	nibble3_chiplet_sel : 3;
+		mmr_t	nibble3_nibble_sel  : 3;
+		mmr_t	nibble2_chiplet_sel : 3;
+		mmr_t	nibble2_nibble_sel  : 3;
+		mmr_t	nibble1_chiplet_sel : 3;
+		mmr_t	nibble1_nibble_sel  : 3;
+		mmr_t	nibble0_chiplet_sel : 3;
+		mmr_t	nibble0_nibble_sel  : 3;
+	} sh_debug_select_s;
+} sh_debug_select_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_TRIGGER_COMPARE_MASK"                  */
+/*                      SHub Trigger Compare Mask                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_trigger_compare_mask_u {
+	mmr_t	sh_trigger_compare_mask_regval;
+	struct {
+		mmr_t	mask        : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_trigger_compare_mask_s;
+} sh_trigger_compare_mask_u_t;
+#else
+typedef union sh_trigger_compare_mask_u {
+	mmr_t	sh_trigger_compare_mask_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	mask        : 32;
+	} sh_trigger_compare_mask_s;
+} sh_trigger_compare_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_TRIGGER_COMPARE_PATTERN"                 */
+/*                     SHub Trigger Compare Pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_trigger_compare_pattern_u {
+	mmr_t	sh_trigger_compare_pattern_regval;
+	struct {
+		mmr_t	data        : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_trigger_compare_pattern_s;
+} sh_trigger_compare_pattern_u_t;
+#else
+typedef union sh_trigger_compare_pattern_u {
+	mmr_t	sh_trigger_compare_pattern_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	data        : 32;
+	} sh_trigger_compare_pattern_s;
+} sh_trigger_compare_pattern_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_TRIGGER_SEL"                       */
+/*                  Trigger select for SHUB debug port                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_trigger_sel_u {
+	mmr_t	sh_trigger_sel_regval;
+	struct {
+		mmr_t	nibble0_input_sel  : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_15        : 1;
+	} sh_trigger_sel_s;
+} sh_trigger_sel_u_t;
+#else
+typedef union sh_trigger_sel_u {
+	mmr_t	sh_trigger_sel_regval;
+	struct {
+		mmr_t	reserved_15        : 1;
+		mmr_t	nibble7_nibble_sel : 3;
+		mmr_t	reserved_14        : 1;
+		mmr_t	nibble7_input_sel  : 3;
+		mmr_t	reserved_13        : 1;
+		mmr_t	nibble6_nibble_sel : 3;
+		mmr_t	reserved_12        : 1;
+		mmr_t	nibble6_input_sel  : 3;
+		mmr_t	reserved_11        : 1;
+		mmr_t	nibble5_nibble_sel : 3;
+		mmr_t	reserved_10        : 1;
+		mmr_t	nibble5_input_sel  : 3;
+		mmr_t	reserved_9         : 1;
+		mmr_t	nibble4_nibble_sel : 3;
+		mmr_t	reserved_8         : 1;
+		mmr_t	nibble4_input_sel  : 3;
+		mmr_t	reserved_7         : 1;
+		mmr_t	nibble3_nibble_sel : 3;
+		mmr_t	reserved_6         : 1;
+		mmr_t	nibble3_input_sel  : 3;
+		mmr_t	reserved_5         : 1;
+		mmr_t	nibble2_nibble_sel : 3;
+		mmr_t	reserved_4         : 1;
+		mmr_t	nibble2_input_sel  : 3;
+		mmr_t	reserved_3         : 1;
+		mmr_t	nibble1_nibble_sel : 3;
+		mmr_t	reserved_2         : 1;
+		mmr_t	nibble1_input_sel  : 3;
+		mmr_t	reserved_1         : 1;
+		mmr_t	nibble0_nibble_sel : 3;
+		mmr_t	reserved_0         : 1;
+		mmr_t	nibble0_input_sel  : 3;
+	} sh_trigger_sel_s;
+} sh_trigger_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_STOP_CLK_CONTROL"                    */
+/*                          Stop Clock Control                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_stop_clk_control_u {
+	mmr_t	sh_stop_clk_control_regval;
+	struct {
+		mmr_t	stimulus    : 5;
+		mmr_t	event       : 1;
+		mmr_t	polarity    : 1;
+		mmr_t	mode        : 1;
+		mmr_t	reserved_0  : 56;
+	} sh_stop_clk_control_s;
+} sh_stop_clk_control_u_t;
+#else
+typedef union sh_stop_clk_control_u {
+	mmr_t	sh_stop_clk_control_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	mode        : 1;
+		mmr_t	polarity    : 1;
+		mmr_t	event       : 1;
+		mmr_t	stimulus    : 5;
+	} sh_stop_clk_control_s;
+} sh_stop_clk_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_STOP_CLK_DELAY_PHASE"                  */
+/*                        Stop Clock Delay Phase                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_stop_clk_delay_phase_u {
+	mmr_t	sh_stop_clk_delay_phase_regval;
+	struct {
+		mmr_t	delay       : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_stop_clk_delay_phase_s;
+} sh_stop_clk_delay_phase_u_t;
+#else
+typedef union sh_stop_clk_delay_phase_u {
+	mmr_t	sh_stop_clk_delay_phase_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	delay       : 8;
+	} sh_stop_clk_delay_phase_s;
+} sh_stop_clk_delay_phase_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_TSF_ARM_MASK"                      */
+/*                 Trigger sequencing facility arm mask                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_arm_mask_u {
+	mmr_t	sh_tsf_arm_mask_regval;
+	struct {
+		mmr_t	mask        : 64;
+	} sh_tsf_arm_mask_s;
+} sh_tsf_arm_mask_u_t;
+#else
+typedef union sh_tsf_arm_mask_u {
+	mmr_t	sh_tsf_arm_mask_regval;
+	struct {
+		mmr_t	mask        : 64;
+	} sh_tsf_arm_mask_s;
+} sh_tsf_arm_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_TSF_COUNTER_PRESETS"                   */
+/*             Trigger sequencing facility counter presets              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_counter_presets_u {
+	mmr_t	sh_tsf_counter_presets_regval;
+	struct {
+		mmr_t	count_32    : 32;
+		mmr_t	count_16    : 16;
+		mmr_t	count_8b    : 8;
+		mmr_t	count_8a    : 8;
+	} sh_tsf_counter_presets_s;
+} sh_tsf_counter_presets_u_t;
+#else
+typedef union sh_tsf_counter_presets_u {
+	mmr_t	sh_tsf_counter_presets_regval;
+	struct {
+		mmr_t	count_8a    : 8;
+		mmr_t	count_8b    : 8;
+		mmr_t	count_16    : 16;
+		mmr_t	count_32    : 32;
+	} sh_tsf_counter_presets_s;
+} sh_tsf_counter_presets_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_TSF_DECREMENT_CTL"                    */
+/*        Trigger sequencing facility counter decrement control         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_decrement_ctl_u {
+	mmr_t	sh_tsf_decrement_ctl_regval;
+	struct {
+		mmr_t	ctl         : 16;
+		mmr_t	reserved_0  : 48;
+	} sh_tsf_decrement_ctl_s;
+} sh_tsf_decrement_ctl_u_t;
+#else
+typedef union sh_tsf_decrement_ctl_u {
+	mmr_t	sh_tsf_decrement_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 48;
+		mmr_t	ctl         : 16;
+	} sh_tsf_decrement_ctl_s;
+} sh_tsf_decrement_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_DIAG_MSG_CTL"                    */
+/*        Trigger sequencing facility diagnostic message control        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_diag_msg_ctl_u {
+	mmr_t	sh_tsf_diag_msg_ctl_regval;
+	struct {
+		mmr_t	enable      : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_tsf_diag_msg_ctl_s;
+} sh_tsf_diag_msg_ctl_u_t;
+#else
+typedef union sh_tsf_diag_msg_ctl_u {
+	mmr_t	sh_tsf_diag_msg_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	enable      : 8;
+	} sh_tsf_diag_msg_ctl_s;
+} sh_tsf_diag_msg_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_DISARM_MASK"                     */
+/*               Trigger sequencing facility disarm mask                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_disarm_mask_u {
+	mmr_t	sh_tsf_disarm_mask_regval;
+	struct {
+		mmr_t	mask        : 64;
+	} sh_tsf_disarm_mask_s;
+} sh_tsf_disarm_mask_u_t;
+#else
+typedef union sh_tsf_disarm_mask_u {
+	mmr_t	sh_tsf_disarm_mask_regval;
+	struct {
+		mmr_t	mask        : 64;
+	} sh_tsf_disarm_mask_s;
+} sh_tsf_disarm_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_TSF_ENABLE_CTL"                     */
+/*          Trigger sequencing facility counter enable control          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_enable_ctl_u {
+	mmr_t	sh_tsf_enable_ctl_regval;
+	struct {
+		mmr_t	ctl         : 16;
+		mmr_t	reserved_0  : 48;
+	} sh_tsf_enable_ctl_s;
+} sh_tsf_enable_ctl_u_t;
+#else
+typedef union sh_tsf_enable_ctl_u {
+	mmr_t	sh_tsf_enable_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 48;
+		mmr_t	ctl         : 16;
+	} sh_tsf_enable_ctl_s;
+} sh_tsf_enable_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_SOFTWARE_ARM"                    */
+/*               Trigger sequencing facility software arm               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_software_arm_u {
+	mmr_t	sh_tsf_software_arm_regval;
+	struct {
+		mmr_t	bit0        : 1;
+		mmr_t	bit1        : 1;
+		mmr_t	bit2        : 1;
+		mmr_t	bit3        : 1;
+		mmr_t	bit4        : 1;
+		mmr_t	bit5        : 1;
+		mmr_t	bit6        : 1;
+		mmr_t	bit7        : 1;
+		mmr_t	reserved_0  : 56;
+	} sh_tsf_software_arm_s;
+} sh_tsf_software_arm_u_t;
+#else
+typedef union sh_tsf_software_arm_u {
+	mmr_t	sh_tsf_software_arm_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	bit7        : 1;
+		mmr_t	bit6        : 1;
+		mmr_t	bit5        : 1;
+		mmr_t	bit4        : 1;
+		mmr_t	bit3        : 1;
+		mmr_t	bit2        : 1;
+		mmr_t	bit1        : 1;
+		mmr_t	bit0        : 1;
+	} sh_tsf_software_arm_s;
+} sh_tsf_software_arm_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_TSF_SOFTWARE_DISARM"                   */
+/*             Trigger sequencing facility software disarm              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_software_disarm_u {
+	mmr_t	sh_tsf_software_disarm_regval;
+	struct {
+		mmr_t	bit0        : 1;
+		mmr_t	bit1        : 1;
+		mmr_t	bit2        : 1;
+		mmr_t	bit3        : 1;
+		mmr_t	bit4        : 1;
+		mmr_t	bit5        : 1;
+		mmr_t	bit6        : 1;
+		mmr_t	bit7        : 1;
+		mmr_t	reserved_0  : 56;
+	} sh_tsf_software_disarm_s;
+} sh_tsf_software_disarm_u_t;
+#else
+typedef union sh_tsf_software_disarm_u {
+	mmr_t	sh_tsf_software_disarm_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	bit7        : 1;
+		mmr_t	bit6        : 1;
+		mmr_t	bit5        : 1;
+		mmr_t	bit4        : 1;
+		mmr_t	bit3        : 1;
+		mmr_t	bit2        : 1;
+		mmr_t	bit1        : 1;
+		mmr_t	bit0        : 1;
+	} sh_tsf_software_disarm_s;
+} sh_tsf_software_disarm_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_TSF_SOFTWARE_TRIGGERED"                 */
+/*            Trigger sequencing facility software triggered            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_software_triggered_u {
+	mmr_t	sh_tsf_software_triggered_regval;
+	struct {
+		mmr_t	bit0        : 1;
+		mmr_t	bit1        : 1;
+		mmr_t	bit2        : 1;
+		mmr_t	bit3        : 1;
+		mmr_t	bit4        : 1;
+		mmr_t	bit5        : 1;
+		mmr_t	bit6        : 1;
+		mmr_t	bit7        : 1;
+		mmr_t	reserved_0  : 56;
+	} sh_tsf_software_triggered_s;
+} sh_tsf_software_triggered_u_t;
+#else
+typedef union sh_tsf_software_triggered_u {
+	mmr_t	sh_tsf_software_triggered_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	bit7        : 1;
+		mmr_t	bit6        : 1;
+		mmr_t	bit5        : 1;
+		mmr_t	bit4        : 1;
+		mmr_t	bit3        : 1;
+		mmr_t	bit2        : 1;
+		mmr_t	bit1        : 1;
+		mmr_t	bit0        : 1;
+	} sh_tsf_software_triggered_s;
+} sh_tsf_software_triggered_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_TRIGGER_MASK"                    */
+/*               Trigger sequencing facility trigger mask               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_trigger_mask_u {
+	mmr_t	sh_tsf_trigger_mask_regval;
+	struct {
+		mmr_t	mask        : 64;
+	} sh_tsf_trigger_mask_s;
+} sh_tsf_trigger_mask_u_t;
+#else
+typedef union sh_tsf_trigger_mask_u {
+	mmr_t	sh_tsf_trigger_mask_regval;
+	struct {
+		mmr_t	mask        : 64;
+	} sh_tsf_trigger_mask_s;
+} sh_tsf_trigger_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_VEC_DATA"                        */
+/*                  Vector Write Request Message Data                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_vec_data_u {
+	mmr_t	sh_vec_data_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_vec_data_s;
+} sh_vec_data_u_t;
+#else
+typedef union sh_vec_data_u {
+	mmr_t	sh_vec_data_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_vec_data_s;
+} sh_vec_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_PARMS"                        */
+/*                  Vector Message Parameters Register                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_vec_parms_u {
+	mmr_t	sh_vec_parms_regval;
+	struct {
+		mmr_t	type        : 1;
+		mmr_t	ni_port     : 1;
+		mmr_t	reserved_0  : 1;
+		mmr_t	address     : 32;
+		mmr_t	pio_id      : 11;
+		mmr_t	reserved_1  : 16;
+		mmr_t	start       : 1;
+		mmr_t	busy        : 1;
+	} sh_vec_parms_s;
+} sh_vec_parms_u_t;
+#else
+typedef union sh_vec_parms_u {
+	mmr_t	sh_vec_parms_regval;
+	struct {
+		mmr_t	busy        : 1;
+		mmr_t	start       : 1;
+		mmr_t	reserved_1  : 16;
+		mmr_t	pio_id      : 11;
+		mmr_t	address     : 32;
+		mmr_t	reserved_0  : 1;
+		mmr_t	ni_port     : 1;
+		mmr_t	type        : 1;
+	} sh_vec_parms_s;
+} sh_vec_parms_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_ROUTE"                        */
+/*                     Vector Request Message Route                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_vec_route_u {
+	mmr_t	sh_vec_route_regval;
+	struct {
+		mmr_t	route       : 64;
+	} sh_vec_route_s;
+} sh_vec_route_u_t;
+#else
+typedef union sh_vec_route_u {
+	mmr_t	sh_vec_route_regval;
+	struct {
+		mmr_t	route       : 64;
+	} sh_vec_route_s;
+} sh_vec_route_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_CPU_PERM"                        */
+/*                    CPU MMR Access Permission Bits                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_cpu_perm_u {
+	mmr_t	sh_cpu_perm_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_cpu_perm_s;
+} sh_cpu_perm_u_t;
+#else
+typedef union sh_cpu_perm_u {
+	mmr_t	sh_cpu_perm_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_cpu_perm_s;
+} sh_cpu_perm_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_CPU_PERM_OVR"                      */
+/*                  CPU MMR Access Permission Override                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_cpu_perm_ovr_u {
+	mmr_t	sh_cpu_perm_ovr_regval;
+	struct {
+		mmr_t	override    : 64;
+	} sh_cpu_perm_ovr_s;
+} sh_cpu_perm_ovr_u_t;
+#else
+typedef union sh_cpu_perm_ovr_u {
+	mmr_t	sh_cpu_perm_ovr_regval;
+	struct {
+		mmr_t	override    : 64;
+	} sh_cpu_perm_ovr_s;
+} sh_cpu_perm_ovr_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_EXT_IO_PERM"                       */
+/*                External IO MMR Access Permission Bits                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ext_io_perm_u {
+	mmr_t	sh_ext_io_perm_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_ext_io_perm_s;
+} sh_ext_io_perm_u_t;
+#else
+typedef union sh_ext_io_perm_u {
+	mmr_t	sh_ext_io_perm_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_ext_io_perm_s;
+} sh_ext_io_perm_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_EXT_IOI_ACCESS"                     */
+/*             External IO Interrupt Access Permission Bits             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ext_ioi_access_u {
+	mmr_t	sh_ext_ioi_access_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_ext_ioi_access_s;
+} sh_ext_ioi_access_u_t;
+#else
+typedef union sh_ext_ioi_access_u {
+	mmr_t	sh_ext_ioi_access_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_ext_ioi_access_s;
+} sh_ext_ioi_access_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_GC_FIL_CTRL"                       */
+/*                   SHub Global Clock Filter Control                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gc_fil_ctrl_u {
+	mmr_t	sh_gc_fil_ctrl_regval;
+	struct {
+		mmr_t	offset          : 5;
+		mmr_t	reserved_0      : 3;
+		mmr_t	mask_counter    : 12;
+		mmr_t	mask_enable     : 1;
+		mmr_t	reserved_1      : 3;
+		mmr_t	dropout_counter : 10;
+		mmr_t	reserved_2      : 2;
+		mmr_t	dropout_thresh  : 10;
+		mmr_t	reserved_3      : 2;
+		mmr_t	error_counter   : 10;
+		mmr_t	reserved_4      : 6;
+	} sh_gc_fil_ctrl_s;
+} sh_gc_fil_ctrl_u_t;
+#else
+typedef union sh_gc_fil_ctrl_u {
+	mmr_t	sh_gc_fil_ctrl_regval;
+	struct {
+		mmr_t	reserved_4      : 6;
+		mmr_t	error_counter   : 10;
+		mmr_t	reserved_3      : 2;
+		mmr_t	dropout_thresh  : 10;
+		mmr_t	reserved_2      : 2;
+		mmr_t	dropout_counter : 10;
+		mmr_t	reserved_1      : 3;
+		mmr_t	mask_enable     : 1;
+		mmr_t	mask_counter    : 12;
+		mmr_t	reserved_0      : 3;
+		mmr_t	offset          : 5;
+	} sh_gc_fil_ctrl_s;
+} sh_gc_fil_ctrl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_GC_SRC_CTRL"                       */
+/*                      SHub Global Clock Control                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_gc_src_ctrl_u {
+	mmr_t	sh_gc_src_ctrl_regval;
+	struct {
+		mmr_t	enable_counter : 1;
+		mmr_t	reserved_0     : 3;
+		mmr_t	max_count      : 10;
+		mmr_t	reserved_1     : 2;
+		mmr_t	counter        : 10;
+		mmr_t	reserved_2     : 2;
+		mmr_t	toggle_bit     : 1;
+		mmr_t	reserved_3     : 3;
+		mmr_t	source_sel     : 2;
+		mmr_t	reserved_4     : 30;
+	} sh_gc_src_ctrl_s;
+} sh_gc_src_ctrl_u_t;
+#else
+typedef union sh_gc_src_ctrl_u {
+	mmr_t	sh_gc_src_ctrl_regval;
+	struct {
+		mmr_t	reserved_4     : 30;
+		mmr_t	source_sel     : 2;
+		mmr_t	reserved_3     : 3;
+		mmr_t	toggle_bit     : 1;
+		mmr_t	reserved_2     : 2;
+		mmr_t	counter        : 10;
+		mmr_t	reserved_1     : 2;
+		mmr_t	max_count      : 10;
+		mmr_t	reserved_0     : 3;
+		mmr_t	enable_counter : 1;
+	} sh_gc_src_ctrl_s;
+} sh_gc_src_ctrl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_HARD_RESET"                       */
+/*                           SHub Hard Reset                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_hard_reset_u {
+	mmr_t	sh_hard_reset_regval;
+	struct {
+		mmr_t	hard_reset  : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_hard_reset_s;
+} sh_hard_reset_u_t;
+#else
+typedef union sh_hard_reset_u {
+	mmr_t	sh_hard_reset_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	hard_reset  : 1;
+	} sh_hard_reset_s;
+} sh_hard_reset_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_IO_PERM"                         */
+/*                    II MMR Access Permission Bits                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_io_perm_u {
+	mmr_t	sh_io_perm_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_io_perm_s;
+} sh_io_perm_u_t;
+#else
+typedef union sh_io_perm_u {
+	mmr_t	sh_io_perm_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_io_perm_s;
+} sh_io_perm_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_IOI_ACCESS"                       */
+/*                 II Interrupt Access Permission Bits                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ioi_access_u {
+	mmr_t	sh_ioi_access_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_ioi_access_s;
+} sh_ioi_access_u_t;
+#else
+typedef union sh_ioi_access_u {
+	mmr_t	sh_ioi_access_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_ioi_access_s;
+} sh_ioi_access_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_IPI_ACCESS"                       */
+/*                 CPU interrupt Access Permission Bits                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ipi_access_u {
+	mmr_t	sh_ipi_access_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_ipi_access_s;
+} sh_ipi_access_u_t;
+#else
+typedef union sh_ipi_access_u {
+	mmr_t	sh_ipi_access_regval;
+	struct {
+		mmr_t	access_bits : 64;
+	} sh_ipi_access_s;
+} sh_ipi_access_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_JTAG_CONFIG"                       */
+/*                       SHub JTAG configuration                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_jtag_config_u {
+	mmr_t	sh_jtag_config_regval;
+	struct {
+		mmr_t	md_clk_sel                    : 2;
+		mmr_t	ni_clk_sel                    : 1;
+		mmr_t	ii_clk_sel                    : 2;
+		mmr_t	wrt90_target                  : 14;
+		mmr_t	wrt90_overrider               : 1;
+		mmr_t	wrt90_override                : 1;
+		mmr_t	jtag_mci_reset_delay          : 4;
+		mmr_t	jtag_mci_target               : 14;
+		mmr_t	jtag_mci_override             : 1;
+		mmr_t	fsb_config_ioq_depth          : 1;
+		mmr_t	fsb_config_sample_binit       : 1;
+		mmr_t	fsb_config_enable_bus_parking : 1;
+		mmr_t	fsb_config_clock_ratio        : 5;
+		mmr_t	fsb_config_output_tristate    : 4;
+		mmr_t	fsb_config_enable_bist        : 1;
+		mmr_t	fsb_config_aux                : 2;
+		mmr_t	gtl_config_re                 : 1;
+		mmr_t	reserved_0                    : 8;
+	} sh_jtag_config_s;
+} sh_jtag_config_u_t;
+#else
+typedef union sh_jtag_config_u {
+	mmr_t	sh_jtag_config_regval;
+	struct {
+		mmr_t	reserved_0                    : 8;
+		mmr_t	gtl_config_re                 : 1;
+		mmr_t	fsb_config_aux                : 2;
+		mmr_t	fsb_config_enable_bist        : 1;
+		mmr_t	fsb_config_output_tristate    : 4;
+		mmr_t	fsb_config_clock_ratio        : 5;
+		mmr_t	fsb_config_enable_bus_parking : 1;
+		mmr_t	fsb_config_sample_binit       : 1;
+		mmr_t	fsb_config_ioq_depth          : 1;
+		mmr_t	jtag_mci_override             : 1;
+		mmr_t	jtag_mci_target               : 14;
+		mmr_t	jtag_mci_reset_delay          : 4;
+		mmr_t	wrt90_override                : 1;
+		mmr_t	wrt90_overrider               : 1;
+		mmr_t	wrt90_target                  : 14;
+		mmr_t	ii_clk_sel                    : 2;
+		mmr_t	ni_clk_sel                    : 1;
+		mmr_t	md_clk_sel                    : 2;
+	} sh_jtag_config_s;
+} sh_jtag_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_SHUB_ID"                         */
+/*                            SHub ID Number                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_shub_id_u {
+	mmr_t	sh_shub_id_regval;
+	struct {
+		mmr_t	force1        : 1;
+		mmr_t	manufacturer  : 11;
+		mmr_t	part_number   : 16;
+		mmr_t	revision      : 4;
+		mmr_t	node_id       : 11;
+		mmr_t	reserved_0    : 1;
+		mmr_t	sharing_mode  : 2;
+		mmr_t	reserved_1    : 2;
+		mmr_t	nodes_per_bit : 5;
+		mmr_t	reserved_2    : 3;
+		mmr_t	ni_port       : 1;
+		mmr_t	reserved_3    : 7;
+	} sh_shub_id_s;
+} sh_shub_id_u_t;
+#else
+typedef union sh_shub_id_u {
+	mmr_t	sh_shub_id_regval;
+	struct {
+		mmr_t	reserved_3    : 7;
+		mmr_t	ni_port       : 1;
+		mmr_t	reserved_2    : 3;
+		mmr_t	nodes_per_bit : 5;
+		mmr_t	reserved_1    : 2;
+		mmr_t	sharing_mode  : 2;
+		mmr_t	reserved_0    : 1;
+		mmr_t	node_id       : 11;
+		mmr_t	revision      : 4;
+		mmr_t	part_number   : 16;
+		mmr_t	manufacturer  : 11;
+		mmr_t	force1        : 1;
+	} sh_shub_id_s;
+} sh_shub_id_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_SHUBS_PRESENT0"                     */
+/*         Shubs 0 - 63 Present. Used for invalidate generation         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_shubs_present0_u {
+	mmr_t	sh_shubs_present0_regval;
+	struct {
+		mmr_t	shubs_present0 : 64;
+	} sh_shubs_present0_s;
+} sh_shubs_present0_u_t;
+#else
+typedef union sh_shubs_present0_u {
+	mmr_t	sh_shubs_present0_regval;
+	struct {
+		mmr_t	shubs_present0 : 64;
+	} sh_shubs_present0_s;
+} sh_shubs_present0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_SHUBS_PRESENT1"                     */
+/*        Shubs 64 - 127 Present. Used for invalidate generation        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_shubs_present1_u {
+	mmr_t	sh_shubs_present1_regval;
+	struct {
+		mmr_t	shubs_present1 : 64;
+	} sh_shubs_present1_s;
+} sh_shubs_present1_u_t;
+#else
+typedef union sh_shubs_present1_u {
+	mmr_t	sh_shubs_present1_regval;
+	struct {
+		mmr_t	shubs_present1 : 64;
+	} sh_shubs_present1_s;
+} sh_shubs_present1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_SHUBS_PRESENT2"                     */
+/*       Shubs 128 - 191 Present. Used for invalidate generation        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_shubs_present2_u {
+	mmr_t	sh_shubs_present2_regval;
+	struct {
+		mmr_t	shubs_present2 : 64;
+	} sh_shubs_present2_s;
+} sh_shubs_present2_u_t;
+#else
+typedef union sh_shubs_present2_u {
+	mmr_t	sh_shubs_present2_regval;
+	struct {
+		mmr_t	shubs_present2 : 64;
+	} sh_shubs_present2_s;
+} sh_shubs_present2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_SHUBS_PRESENT3"                     */
+/*       Shubs 192 - 255 Present. Used for invalidate generation        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_shubs_present3_u {
+	mmr_t	sh_shubs_present3_regval;
+	struct {
+		mmr_t	shubs_present3 : 64;
+	} sh_shubs_present3_s;
+} sh_shubs_present3_u_t;
+#else
+typedef union sh_shubs_present3_u {
+	mmr_t	sh_shubs_present3_regval;
+	struct {
+		mmr_t	shubs_present3 : 64;
+	} sh_shubs_present3_s;
+} sh_shubs_present3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_SOFT_RESET"                       */
+/*                           SHub Soft Reset                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_soft_reset_u {
+	mmr_t	sh_soft_reset_regval;
+	struct {
+		mmr_t	soft_reset  : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_soft_reset_s;
+} sh_soft_reset_u_t;
+#else
+typedef union sh_soft_reset_u {
+	mmr_t	sh_soft_reset_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	soft_reset  : 1;
+	} sh_soft_reset_s;
+} sh_soft_reset_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_FIRST_ERROR"                       */
+/*                    Shub Global First Error Flags                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_first_error_u {
+	mmr_t	sh_first_error_regval;
+	struct {
+		mmr_t	first_error : 19;
+		mmr_t	reserved_0  : 45;
+	} sh_first_error_s;
+} sh_first_error_u_t;
+#else
+typedef union sh_first_error_u {
+	mmr_t	sh_first_error_regval;
+	struct {
+		mmr_t	reserved_0  : 45;
+		mmr_t	first_error : 19;
+	} sh_first_error_s;
+} sh_first_error_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_II_HW_TIME_STAMP"                    */
+/*                     II hardware error time stamp                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_hw_time_stamp_u {
+	mmr_t	sh_ii_hw_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_ii_hw_time_stamp_s;
+} sh_ii_hw_time_stamp_u_t;
+#else
+typedef union sh_ii_hw_time_stamp_u {
+	mmr_t	sh_ii_hw_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_ii_hw_time_stamp_s;
+} sh_ii_hw_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_LB_HW_TIME_STAMP"                    */
+/*                     LB hardware error time stamp                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_hw_time_stamp_u {
+	mmr_t	sh_lb_hw_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_lb_hw_time_stamp_s;
+} sh_lb_hw_time_stamp_u_t;
+#else
+typedef union sh_lb_hw_time_stamp_u {
+	mmr_t	sh_lb_hw_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_lb_hw_time_stamp_s;
+} sh_lb_hw_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_COR_TIME_STAMP"                    */
+/*                   MD correctable error time stamp                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_cor_time_stamp_u {
+	mmr_t	sh_md_cor_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_md_cor_time_stamp_s;
+} sh_md_cor_time_stamp_u_t;
+#else
+typedef union sh_md_cor_time_stamp_u {
+	mmr_t	sh_md_cor_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_md_cor_time_stamp_s;
+} sh_md_cor_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_MD_HW_TIME_STAMP"                    */
+/*                     MD hardware error time stamp                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_hw_time_stamp_u {
+	mmr_t	sh_md_hw_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_md_hw_time_stamp_s;
+} sh_md_hw_time_stamp_u_t;
+#else
+typedef union sh_md_hw_time_stamp_u {
+	mmr_t	sh_md_hw_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_md_hw_time_stamp_s;
+} sh_md_hw_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_UNCOR_TIME_STAMP"                   */
+/*                  MD uncorrectable error time stamp                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_uncor_time_stamp_u {
+	mmr_t	sh_md_uncor_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_md_uncor_time_stamp_s;
+} sh_md_uncor_time_stamp_u_t;
+#else
+typedef union sh_md_uncor_time_stamp_u {
+	mmr_t	sh_md_uncor_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_md_uncor_time_stamp_s;
+} sh_md_uncor_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PI_COR_TIME_STAMP"                    */
+/*                   PI correctable error time stamp                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_cor_time_stamp_u {
+	mmr_t	sh_pi_cor_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_pi_cor_time_stamp_s;
+} sh_pi_cor_time_stamp_u_t;
+#else
+typedef union sh_pi_cor_time_stamp_u {
+	mmr_t	sh_pi_cor_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_pi_cor_time_stamp_s;
+} sh_pi_cor_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_PI_HW_TIME_STAMP"                    */
+/*                     PI hardware error time stamp                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_hw_time_stamp_u {
+	mmr_t	sh_pi_hw_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_pi_hw_time_stamp_s;
+} sh_pi_hw_time_stamp_u_t;
+#else
+typedef union sh_pi_hw_time_stamp_u {
+	mmr_t	sh_pi_hw_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_pi_hw_time_stamp_s;
+} sh_pi_hw_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PI_UNCOR_TIME_STAMP"                   */
+/*                  PI uncorrectable error time stamp                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_uncor_time_stamp_u {
+	mmr_t	sh_pi_uncor_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_pi_uncor_time_stamp_s;
+} sh_pi_uncor_time_stamp_u_t;
+#else
+typedef union sh_pi_uncor_time_stamp_u {
+	mmr_t	sh_pi_uncor_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_pi_uncor_time_stamp_s;
+} sh_pi_uncor_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ADV_TIME_STAMP"                  */
+/*                      Proc 0 advisory time stamp                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc0_adv_time_stamp_u {
+	mmr_t	sh_proc0_adv_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_proc0_adv_time_stamp_s;
+} sh_proc0_adv_time_stamp_u_t;
+#else
+typedef union sh_proc0_adv_time_stamp_u {
+	mmr_t	sh_proc0_adv_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_proc0_adv_time_stamp_s;
+} sh_proc0_adv_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC0_ERR_TIME_STAMP"                  */
+/*                       Proc 0 error time stamp                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc0_err_time_stamp_u {
+	mmr_t	sh_proc0_err_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_proc0_err_time_stamp_s;
+} sh_proc0_err_time_stamp_u_t;
+#else
+typedef union sh_proc0_err_time_stamp_u {
+	mmr_t	sh_proc0_err_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_proc0_err_time_stamp_s;
+} sh_proc0_err_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ADV_TIME_STAMP"                  */
+/*                      Proc 1 advisory time stamp                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc1_adv_time_stamp_u {
+	mmr_t	sh_proc1_adv_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_proc1_adv_time_stamp_s;
+} sh_proc1_adv_time_stamp_u_t;
+#else
+typedef union sh_proc1_adv_time_stamp_u {
+	mmr_t	sh_proc1_adv_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_proc1_adv_time_stamp_s;
+} sh_proc1_adv_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC1_ERR_TIME_STAMP"                  */
+/*                       Proc 1 error time stamp                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc1_err_time_stamp_u {
+	mmr_t	sh_proc1_err_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_proc1_err_time_stamp_s;
+} sh_proc1_err_time_stamp_u_t;
+#else
+typedef union sh_proc1_err_time_stamp_u {
+	mmr_t	sh_proc1_err_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_proc1_err_time_stamp_s;
+} sh_proc1_err_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ADV_TIME_STAMP"                  */
+/*                      Proc 2 advisory time stamp                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc2_adv_time_stamp_u {
+	mmr_t	sh_proc2_adv_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_proc2_adv_time_stamp_s;
+} sh_proc2_adv_time_stamp_u_t;
+#else
+typedef union sh_proc2_adv_time_stamp_u {
+	mmr_t	sh_proc2_adv_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_proc2_adv_time_stamp_s;
+} sh_proc2_adv_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC2_ERR_TIME_STAMP"                  */
+/*                       Proc 2 error time stamp                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc2_err_time_stamp_u {
+	mmr_t	sh_proc2_err_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_proc2_err_time_stamp_s;
+} sh_proc2_err_time_stamp_u_t;
+#else
+typedef union sh_proc2_err_time_stamp_u {
+	mmr_t	sh_proc2_err_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_proc2_err_time_stamp_s;
+} sh_proc2_err_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ADV_TIME_STAMP"                  */
+/*                      Proc 3 advisory time stamp                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc3_adv_time_stamp_u {
+	mmr_t	sh_proc3_adv_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_proc3_adv_time_stamp_s;
+} sh_proc3_adv_time_stamp_u_t;
+#else
+typedef union sh_proc3_adv_time_stamp_u {
+	mmr_t	sh_proc3_adv_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_proc3_adv_time_stamp_s;
+} sh_proc3_adv_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROC3_ERR_TIME_STAMP"                  */
+/*                       Proc 3 error time stamp                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_proc3_err_time_stamp_u {
+	mmr_t	sh_proc3_err_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_proc3_err_time_stamp_s;
+} sh_proc3_err_time_stamp_u_t;
+#else
+typedef union sh_proc3_err_time_stamp_u {
+	mmr_t	sh_proc3_err_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_proc3_err_time_stamp_s;
+} sh_proc3_err_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_XN_COR_TIME_STAMP"                    */
+/*                   XN correctable error time stamp                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_cor_time_stamp_u {
+	mmr_t	sh_xn_cor_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_xn_cor_time_stamp_s;
+} sh_xn_cor_time_stamp_u_t;
+#else
+typedef union sh_xn_cor_time_stamp_u {
+	mmr_t	sh_xn_cor_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_xn_cor_time_stamp_s;
+} sh_xn_cor_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_HW_TIME_STAMP"                    */
+/*                     XN hardware error time stamp                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_hw_time_stamp_u {
+	mmr_t	sh_xn_hw_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_xn_hw_time_stamp_s;
+} sh_xn_hw_time_stamp_u_t;
+#else
+typedef union sh_xn_hw_time_stamp_u {
+	mmr_t	sh_xn_hw_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_xn_hw_time_stamp_s;
+} sh_xn_hw_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_XN_UNCOR_TIME_STAMP"                   */
+/*                  XN uncorrectable error time stamp                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_uncor_time_stamp_u {
+	mmr_t	sh_xn_uncor_time_stamp_regval;
+	struct {
+		mmr_t	time        : 63;
+		mmr_t	valid       : 1;
+	} sh_xn_uncor_time_stamp_s;
+} sh_xn_uncor_time_stamp_u_t;
+#else
+typedef union sh_xn_uncor_time_stamp_u {
+	mmr_t	sh_xn_uncor_time_stamp_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	time        : 63;
+	} sh_xn_uncor_time_stamp_s;
+} sh_xn_uncor_time_stamp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_DEBUG_PORT"                       */
+/*                           SHub Debug Port                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_debug_port_u {
+	mmr_t	sh_debug_port_regval;
+	struct {
+		mmr_t	debug_nibble0 : 4;
+		mmr_t	debug_nibble1 : 4;
+		mmr_t	debug_nibble2 : 4;
+		mmr_t	debug_nibble3 : 4;
+		mmr_t	debug_nibble4 : 4;
+		mmr_t	debug_nibble5 : 4;
+		mmr_t	debug_nibble6 : 4;
+		mmr_t	debug_nibble7 : 4;
+		mmr_t	reserved_0    : 32;
+	} sh_debug_port_s;
+} sh_debug_port_u_t;
+#else
+typedef union sh_debug_port_u {
+	mmr_t	sh_debug_port_regval;
+	struct {
+		mmr_t	reserved_0    : 32;
+		mmr_t	debug_nibble7 : 4;
+		mmr_t	debug_nibble6 : 4;
+		mmr_t	debug_nibble5 : 4;
+		mmr_t	debug_nibble4 : 4;
+		mmr_t	debug_nibble3 : 4;
+		mmr_t	debug_nibble2 : 4;
+		mmr_t	debug_nibble1 : 4;
+		mmr_t	debug_nibble0 : 4;
+	} sh_debug_port_s;
+} sh_debug_port_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_II_DEBUG_DATA"                      */
+/*                            II Debug Data                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_debug_data_u {
+	mmr_t	sh_ii_debug_data_regval;
+	struct {
+		mmr_t	ii_data     : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_ii_debug_data_s;
+} sh_ii_debug_data_u_t;
+#else
+typedef union sh_ii_debug_data_u {
+	mmr_t	sh_ii_debug_data_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	ii_data     : 32;
+	} sh_ii_debug_data_s;
+} sh_ii_debug_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_II_WRAP_DEBUG_DATA"                   */
+/*                      SHub II Wrapper Debug Data                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ii_wrap_debug_data_u {
+	mmr_t	sh_ii_wrap_debug_data_regval;
+	struct {
+		mmr_t	ii_wrap_data : 32;
+		mmr_t	reserved_0   : 32;
+	} sh_ii_wrap_debug_data_s;
+} sh_ii_wrap_debug_data_u_t;
+#else
+typedef union sh_ii_wrap_debug_data_u {
+	mmr_t	sh_ii_wrap_debug_data_regval;
+	struct {
+		mmr_t	reserved_0   : 32;
+		mmr_t	ii_wrap_data : 32;
+	} sh_ii_wrap_debug_data_s;
+} sh_ii_wrap_debug_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_LB_DEBUG_DATA"                      */
+/*                          SHub LB Debug Data                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_lb_debug_data_u {
+	mmr_t	sh_lb_debug_data_regval;
+	struct {
+		mmr_t	lb_data     : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_lb_debug_data_s;
+} sh_lb_debug_data_u_t;
+#else
+typedef union sh_lb_debug_data_u {
+	mmr_t	sh_lb_debug_data_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	lb_data     : 32;
+	} sh_lb_debug_data_s;
+} sh_lb_debug_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_MD_DEBUG_DATA"                      */
+/*                          SHub MD Debug Data                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_debug_data_u {
+	mmr_t	sh_md_debug_data_regval;
+	struct {
+		mmr_t	md_data     : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_md_debug_data_s;
+} sh_md_debug_data_u_t;
+#else
+typedef union sh_md_debug_data_u {
+	mmr_t	sh_md_debug_data_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	md_data     : 32;
+	} sh_md_debug_data_s;
+} sh_md_debug_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PI_DEBUG_DATA"                      */
+/*                          SHub PI Debug Data                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_debug_data_u {
+	mmr_t	sh_pi_debug_data_regval;
+	struct {
+		mmr_t	pi_data     : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_pi_debug_data_s;
+} sh_pi_debug_data_u_t;
+#else
+typedef union sh_pi_debug_data_u {
+	mmr_t	sh_pi_debug_data_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	pi_data     : 32;
+	} sh_pi_debug_data_s;
+} sh_pi_debug_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_XN_DEBUG_DATA"                      */
+/*                          SHub XN Debug Data                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_debug_data_u {
+	mmr_t	sh_xn_debug_data_regval;
+	struct {
+		mmr_t	xn_data     : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_xn_debug_data_s;
+} sh_xn_debug_data_u_t;
+#else
+typedef union sh_xn_debug_data_u {
+	mmr_t	sh_xn_debug_data_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	xn_data     : 32;
+	} sh_xn_debug_data_s;
+} sh_xn_debug_data_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_TSF_ARMED_STATE"                     */
+/*                Trigger sequencing facility arm state                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_armed_state_u {
+	mmr_t	sh_tsf_armed_state_regval;
+	struct {
+		mmr_t	state       : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_tsf_armed_state_s;
+} sh_tsf_armed_state_u_t;
+#else
+typedef union sh_tsf_armed_state_u {
+	mmr_t	sh_tsf_armed_state_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	state       : 8;
+	} sh_tsf_armed_state_s;
+} sh_tsf_armed_state_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_TSF_COUNTER_VALUE"                    */
+/*              Trigger sequencing facility counter value               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_counter_value_u {
+	mmr_t	sh_tsf_counter_value_regval;
+	struct {
+		mmr_t	count_32    : 32;
+		mmr_t	count_16    : 16;
+		mmr_t	count_8b    : 8;
+		mmr_t	count_8a    : 8;
+	} sh_tsf_counter_value_s;
+} sh_tsf_counter_value_u_t;
+#else
+typedef union sh_tsf_counter_value_u {
+	mmr_t	sh_tsf_counter_value_regval;
+	struct {
+		mmr_t	count_8a    : 8;
+		mmr_t	count_8b    : 8;
+		mmr_t	count_16    : 16;
+		mmr_t	count_32    : 32;
+	} sh_tsf_counter_value_s;
+} sh_tsf_counter_value_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_TSF_TRIGGERED_STATE"                   */
+/*             Trigger sequencing facility triggered state              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_tsf_triggered_state_u {
+	mmr_t	sh_tsf_triggered_state_regval;
+	struct {
+		mmr_t	state       : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_tsf_triggered_state_s;
+} sh_tsf_triggered_state_u_t;
+#else
+typedef union sh_tsf_triggered_state_u {
+	mmr_t	sh_tsf_triggered_state_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	state       : 8;
+	} sh_tsf_triggered_state_s;
+} sh_tsf_triggered_state_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_RDDATA"                       */
+/*                      Vector Reply Message Data                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_vec_rddata_u {
+	mmr_t	sh_vec_rddata_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_vec_rddata_s;
+} sh_vec_rddata_u_t;
+#else
+typedef union sh_vec_rddata_u {
+	mmr_t	sh_vec_rddata_regval;
+	struct {
+		mmr_t	data        : 64;
+	} sh_vec_rddata_s;
+} sh_vec_rddata_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_RETURN"                       */
+/*                  Vector Reply Message Return Route                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_vec_return_u {
+	mmr_t	sh_vec_return_regval;
+	struct {
+		mmr_t	route       : 64;
+	} sh_vec_return_s;
+} sh_vec_return_u_t;
+#else
+typedef union sh_vec_return_u {
+	mmr_t	sh_vec_return_regval;
+	struct {
+		mmr_t	route       : 64;
+	} sh_vec_return_s;
+} sh_vec_return_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_VEC_STATUS"                       */
+/*                     Vector Reply Message Status                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_vec_status_u {
+	mmr_t	sh_vec_status_regval;
+	struct {
+		mmr_t	type         : 3;
+		mmr_t	address      : 32;
+		mmr_t	pio_id       : 11;
+		mmr_t	source       : 14;
+		mmr_t	reserved_0   : 2;
+		mmr_t	overrun      : 1;
+		mmr_t	status_valid : 1;
+	} sh_vec_status_s;
+} sh_vec_status_u_t;
+#else
+typedef union sh_vec_status_u {
+	mmr_t	sh_vec_status_regval;
+	struct {
+		mmr_t	status_valid : 1;
+		mmr_t	overrun      : 1;
+		mmr_t	reserved_0   : 2;
+		mmr_t	source       : 14;
+		mmr_t	pio_id       : 11;
+		mmr_t	address      : 32;
+		mmr_t	type         : 3;
+	} sh_vec_status_s;
+} sh_vec_status_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT0_CONTROL"               */
+/*                    Performance Counter 0 Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_count0_control_u {
+	mmr_t	sh_performance_count0_control_regval;
+	struct {
+		mmr_t	up_stimulus     : 5;
+		mmr_t	up_event        : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_mode         : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	reserved_0      : 45;
+	} sh_performance_count0_control_s;
+} sh_performance_count0_control_u_t;
+#else
+typedef union sh_performance_count0_control_u {
+	mmr_t	sh_performance_count0_control_regval;
+	struct {
+		mmr_t	reserved_0      : 45;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	up_mode         : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_event        : 1;
+		mmr_t	up_stimulus     : 5;
+	} sh_performance_count0_control_s;
+} sh_performance_count0_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT1_CONTROL"               */
+/*                    Performance Counter 1 Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_count1_control_u {
+	mmr_t	sh_performance_count1_control_regval;
+	struct {
+		mmr_t	up_stimulus     : 5;
+		mmr_t	up_event        : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_mode         : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	reserved_0      : 45;
+	} sh_performance_count1_control_s;
+} sh_performance_count1_control_u_t;
+#else
+typedef union sh_performance_count1_control_u {
+	mmr_t	sh_performance_count1_control_regval;
+	struct {
+		mmr_t	reserved_0      : 45;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	up_mode         : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_event        : 1;
+		mmr_t	up_stimulus     : 5;
+	} sh_performance_count1_control_s;
+} sh_performance_count1_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT2_CONTROL"               */
+/*                    Performance Counter 2 Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_count2_control_u {
+	mmr_t	sh_performance_count2_control_regval;
+	struct {
+		mmr_t	up_stimulus     : 5;
+		mmr_t	up_event        : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_mode         : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	reserved_0      : 45;
+	} sh_performance_count2_control_s;
+} sh_performance_count2_control_u_t;
+#else
+typedef union sh_performance_count2_control_u {
+	mmr_t	sh_performance_count2_control_regval;
+	struct {
+		mmr_t	reserved_0      : 45;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	up_mode         : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_event        : 1;
+		mmr_t	up_stimulus     : 5;
+	} sh_performance_count2_control_s;
+} sh_performance_count2_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT3_CONTROL"               */
+/*                    Performance Counter 3 Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_count3_control_u {
+	mmr_t	sh_performance_count3_control_regval;
+	struct {
+		mmr_t	up_stimulus     : 5;
+		mmr_t	up_event        : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_mode         : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	reserved_0      : 45;
+	} sh_performance_count3_control_s;
+} sh_performance_count3_control_u_t;
+#else
+typedef union sh_performance_count3_control_u {
+	mmr_t	sh_performance_count3_control_regval;
+	struct {
+		mmr_t	reserved_0      : 45;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	up_mode         : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_event        : 1;
+		mmr_t	up_stimulus     : 5;
+	} sh_performance_count3_control_s;
+} sh_performance_count3_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT4_CONTROL"               */
+/*                    Performance Counter 4 Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_count4_control_u {
+	mmr_t	sh_performance_count4_control_regval;
+	struct {
+		mmr_t	up_stimulus     : 5;
+		mmr_t	up_event        : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_mode         : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	reserved_0      : 45;
+	} sh_performance_count4_control_s;
+} sh_performance_count4_control_u_t;
+#else
+typedef union sh_performance_count4_control_u {
+	mmr_t	sh_performance_count4_control_regval;
+	struct {
+		mmr_t	reserved_0      : 45;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	up_mode         : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_event        : 1;
+		mmr_t	up_stimulus     : 5;
+	} sh_performance_count4_control_s;
+} sh_performance_count4_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT5_CONTROL"               */
+/*                    Performance Counter 5 Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_count5_control_u {
+	mmr_t	sh_performance_count5_control_regval;
+	struct {
+		mmr_t	up_stimulus     : 5;
+		mmr_t	up_event        : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_mode         : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	reserved_0      : 45;
+	} sh_performance_count5_control_s;
+} sh_performance_count5_control_u_t;
+#else
+typedef union sh_performance_count5_control_u {
+	mmr_t	sh_performance_count5_control_regval;
+	struct {
+		mmr_t	reserved_0      : 45;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	up_mode         : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_event        : 1;
+		mmr_t	up_stimulus     : 5;
+	} sh_performance_count5_control_s;
+} sh_performance_count5_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT6_CONTROL"               */
+/*                    Performance Counter 6 Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_count6_control_u {
+	mmr_t	sh_performance_count6_control_regval;
+	struct {
+		mmr_t	up_stimulus     : 5;
+		mmr_t	up_event        : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_mode         : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	reserved_0      : 45;
+	} sh_performance_count6_control_s;
+} sh_performance_count6_control_u_t;
+#else
+typedef union sh_performance_count6_control_u {
+	mmr_t	sh_performance_count6_control_regval;
+	struct {
+		mmr_t	reserved_0      : 45;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	up_mode         : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_event        : 1;
+		mmr_t	up_stimulus     : 5;
+	} sh_performance_count6_control_s;
+} sh_performance_count6_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_PERFORMANCE_COUNT7_CONTROL"               */
+/*                    Performance Counter 7 Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_count7_control_u {
+	mmr_t	sh_performance_count7_control_regval;
+	struct {
+		mmr_t	up_stimulus     : 5;
+		mmr_t	up_event        : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_mode         : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	reserved_0      : 45;
+	} sh_performance_count7_control_s;
+} sh_performance_count7_control_u_t;
+#else
+typedef union sh_performance_count7_control_u {
+	mmr_t	sh_performance_count7_control_regval;
+	struct {
+		mmr_t	reserved_0      : 45;
+		mmr_t	peak_det_enable : 1;
+		mmr_t	dec_enable      : 1;
+		mmr_t	inc_enable      : 1;
+		mmr_t	dn_mode         : 1;
+		mmr_t	dn_polarity     : 1;
+		mmr_t	dn_event        : 1;
+		mmr_t	dn_stimulus     : 5;
+		mmr_t	up_mode         : 1;
+		mmr_t	up_polarity     : 1;
+		mmr_t	up_event        : 1;
+		mmr_t	up_stimulus     : 5;
+	} sh_performance_count7_control_s;
+} sh_performance_count7_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PROFILE_DN_CONTROL"                   */
+/*                     Profile Counter Down Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_profile_dn_control_u {
+	mmr_t	sh_profile_dn_control_regval;
+	struct {
+		mmr_t	stimulus    : 5;
+		mmr_t	event       : 1;
+		mmr_t	polarity    : 1;
+		mmr_t	mode        : 1;
+		mmr_t	reserved_0  : 56;
+	} sh_profile_dn_control_s;
+} sh_profile_dn_control_u_t;
+#else
+typedef union sh_profile_dn_control_u {
+	mmr_t	sh_profile_dn_control_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	mode        : 1;
+		mmr_t	polarity    : 1;
+		mmr_t	event       : 1;
+		mmr_t	stimulus    : 5;
+	} sh_profile_dn_control_s;
+} sh_profile_dn_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PROFILE_PEAK_CONTROL"                  */
+/*                     Profile Counter Peak Control                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_profile_peak_control_u {
+	mmr_t	sh_profile_peak_control_regval;
+	struct {
+		mmr_t	reserved_0  : 3;
+		mmr_t	stimulus    : 1;
+		mmr_t	reserved_1  : 1;
+		mmr_t	event       : 1;
+		mmr_t	polarity    : 1;
+		mmr_t	reserved_2  : 57;
+	} sh_profile_peak_control_s;
+} sh_profile_peak_control_u_t;
+#else
+typedef union sh_profile_peak_control_u {
+	mmr_t	sh_profile_peak_control_regval;
+	struct {
+		mmr_t	reserved_2  : 57;
+		mmr_t	polarity    : 1;
+		mmr_t	event       : 1;
+		mmr_t	reserved_1  : 1;
+		mmr_t	stimulus    : 1;
+		mmr_t	reserved_0  : 3;
+	} sh_profile_peak_control_s;
+} sh_profile_peak_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PROFILE_RANGE"                      */
+/*                        Profile Counter Range                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_profile_range_u {
+	mmr_t	sh_profile_range_regval;
+	struct {
+		mmr_t	range0      : 8;
+		mmr_t	range1      : 8;
+		mmr_t	range2      : 8;
+		mmr_t	range3      : 8;
+		mmr_t	range4      : 8;
+		mmr_t	range5      : 8;
+		mmr_t	range6      : 8;
+		mmr_t	range7      : 8;
+	} sh_profile_range_s;
+} sh_profile_range_u_t;
+#else
+typedef union sh_profile_range_u {
+	mmr_t	sh_profile_range_regval;
+	struct {
+		mmr_t	range7      : 8;
+		mmr_t	range6      : 8;
+		mmr_t	range5      : 8;
+		mmr_t	range4      : 8;
+		mmr_t	range3      : 8;
+		mmr_t	range2      : 8;
+		mmr_t	range1      : 8;
+		mmr_t	range0      : 8;
+	} sh_profile_range_s;
+} sh_profile_range_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PROFILE_UP_CONTROL"                   */
+/*                      Profile Counter Up Control                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_profile_up_control_u {
+	mmr_t	sh_profile_up_control_regval;
+	struct {
+		mmr_t	stimulus    : 5;
+		mmr_t	event       : 1;
+		mmr_t	polarity    : 1;
+		mmr_t	mode        : 1;
+		mmr_t	reserved_0  : 56;
+	} sh_profile_up_control_s;
+} sh_profile_up_control_u_t;
+#else
+typedef union sh_profile_up_control_u {
+	mmr_t	sh_profile_up_control_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	mode        : 1;
+		mmr_t	polarity    : 1;
+		mmr_t	event       : 1;
+		mmr_t	stimulus    : 5;
+	} sh_profile_up_control_s;
+} sh_profile_up_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER0"                  */
+/*                        Performance Counter 0                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_counter0_u {
+	mmr_t	sh_performance_counter0_regval;
+	struct {
+		mmr_t	count       : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_performance_counter0_s;
+} sh_performance_counter0_u_t;
+#else
+typedef union sh_performance_counter0_u {
+	mmr_t	sh_performance_counter0_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	count       : 32;
+	} sh_performance_counter0_s;
+} sh_performance_counter0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER1"                  */
+/*                        Performance Counter 1                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_counter1_u {
+	mmr_t	sh_performance_counter1_regval;
+	struct {
+		mmr_t	count       : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_performance_counter1_s;
+} sh_performance_counter1_u_t;
+#else
+typedef union sh_performance_counter1_u {
+	mmr_t	sh_performance_counter1_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	count       : 32;
+	} sh_performance_counter1_s;
+} sh_performance_counter1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER2"                  */
+/*                        Performance Counter 2                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_counter2_u {
+	mmr_t	sh_performance_counter2_regval;
+	struct {
+		mmr_t	count       : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_performance_counter2_s;
+} sh_performance_counter2_u_t;
+#else
+typedef union sh_performance_counter2_u {
+	mmr_t	sh_performance_counter2_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	count       : 32;
+	} sh_performance_counter2_s;
+} sh_performance_counter2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER3"                  */
+/*                        Performance Counter 3                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_counter3_u {
+	mmr_t	sh_performance_counter3_regval;
+	struct {
+		mmr_t	count       : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_performance_counter3_s;
+} sh_performance_counter3_u_t;
+#else
+typedef union sh_performance_counter3_u {
+	mmr_t	sh_performance_counter3_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	count       : 32;
+	} sh_performance_counter3_s;
+} sh_performance_counter3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER4"                  */
+/*                        Performance Counter 4                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_counter4_u {
+	mmr_t	sh_performance_counter4_regval;
+	struct {
+		mmr_t	count       : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_performance_counter4_s;
+} sh_performance_counter4_u_t;
+#else
+typedef union sh_performance_counter4_u {
+	mmr_t	sh_performance_counter4_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	count       : 32;
+	} sh_performance_counter4_s;
+} sh_performance_counter4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER5"                  */
+/*                        Performance Counter 5                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_counter5_u {
+	mmr_t	sh_performance_counter5_regval;
+	struct {
+		mmr_t	count       : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_performance_counter5_s;
+} sh_performance_counter5_u_t;
+#else
+typedef union sh_performance_counter5_u {
+	mmr_t	sh_performance_counter5_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	count       : 32;
+	} sh_performance_counter5_s;
+} sh_performance_counter5_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER6"                  */
+/*                        Performance Counter 6                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_counter6_u {
+	mmr_t	sh_performance_counter6_regval;
+	struct {
+		mmr_t	count       : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_performance_counter6_s;
+} sh_performance_counter6_u_t;
+#else
+typedef union sh_performance_counter6_u {
+	mmr_t	sh_performance_counter6_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	count       : 32;
+	} sh_performance_counter6_s;
+} sh_performance_counter6_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_PERFORMANCE_COUNTER7"                  */
+/*                        Performance Counter 7                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_performance_counter7_u {
+	mmr_t	sh_performance_counter7_regval;
+	struct {
+		mmr_t	count       : 32;
+		mmr_t	reserved_0  : 32;
+	} sh_performance_counter7_s;
+} sh_performance_counter7_u_t;
+#else
+typedef union sh_performance_counter7_u {
+	mmr_t	sh_performance_counter7_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	count       : 32;
+	} sh_performance_counter7_s;
+} sh_performance_counter7_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_PROFILE_COUNTER"                     */
+/*                           Profile Counter                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_profile_counter_u {
+	mmr_t	sh_profile_counter_regval;
+	struct {
+		mmr_t	counter     : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_profile_counter_s;
+} sh_profile_counter_u_t;
+#else
+typedef union sh_profile_counter_u {
+	mmr_t	sh_profile_counter_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	counter     : 8;
+	} sh_profile_counter_s;
+} sh_profile_counter_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_PROFILE_PEAK"                      */
+/*                         Profile Peak Counter                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_profile_peak_u {
+	mmr_t	sh_profile_peak_regval;
+	struct {
+		mmr_t	counter     : 8;
+		mmr_t	reserved_0  : 56;
+	} sh_profile_peak_s;
+} sh_profile_peak_u_t;
+#else
+typedef union sh_profile_peak_u {
+	mmr_t	sh_profile_peak_regval;
+	struct {
+		mmr_t	reserved_0  : 56;
+		mmr_t	counter     : 8;
+	} sh_profile_peak_s;
+} sh_profile_peak_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_PTC_0"                          */
+/*       Puge Translation Cache Message Configuration Information       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ptc_0_u {
+	mmr_t	sh_ptc_0_regval;
+	struct {
+		mmr_t	a           : 1;
+		mmr_t	reserved_0  : 1;
+		mmr_t	ps          : 6;
+		mmr_t	rid         : 24;
+		mmr_t	reserved_1  : 31;
+		mmr_t	start       : 1;
+	} sh_ptc_0_s;
+} sh_ptc_0_u_t;
+#else
+typedef union sh_ptc_0_u {
+	mmr_t	sh_ptc_0_regval;
+	struct {
+		mmr_t	start       : 1;
+		mmr_t	reserved_1  : 31;
+		mmr_t	rid         : 24;
+		mmr_t	ps          : 6;
+		mmr_t	reserved_0  : 1;
+		mmr_t	a           : 1;
+	} sh_ptc_0_s;
+} sh_ptc_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_PTC_1"                          */
+/*       Puge Translation Cache Message Configuration Information       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ptc_1_u {
+	mmr_t	sh_ptc_1_regval;
+	struct {
+		mmr_t	reserved_0  : 12;
+		mmr_t	vpn         : 49;
+		mmr_t	reserved_1  : 2;
+		mmr_t	start       : 1;
+	} sh_ptc_1_s;
+} sh_ptc_1_u_t;
+#else
+typedef union sh_ptc_1_u {
+	mmr_t	sh_ptc_1_regval;
+	struct {
+		mmr_t	start       : 1;
+		mmr_t	reserved_1  : 2;
+		mmr_t	vpn         : 49;
+		mmr_t	reserved_0  : 12;
+	} sh_ptc_1_s;
+} sh_ptc_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_PTC_PARMS"                        */
+/*                       PTC Time-out parmaeters                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_ptc_parms_u {
+	mmr_t	sh_ptc_parms_regval;
+	struct {
+		mmr_t	ptc_to_wrap : 24;
+		mmr_t	ptc_to_val  : 12;
+		mmr_t	reserved_0  : 28;
+	} sh_ptc_parms_s;
+} sh_ptc_parms_u_t;
+#else
+typedef union sh_ptc_parms_u {
+	mmr_t	sh_ptc_parms_regval;
+	struct {
+		mmr_t	reserved_0  : 28;
+		mmr_t	ptc_to_val  : 12;
+		mmr_t	ptc_to_wrap : 24;
+	} sh_ptc_parms_s;
+} sh_ptc_parms_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_INT_CMPA"                        */
+/*                  RTC Compare Value for Processor A                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_int_cmpa_u {
+	mmr_t	sh_int_cmpa_regval;
+	struct {
+		mmr_t	real_time_cmpa : 55;
+		mmr_t	reserved_0     : 9;
+	} sh_int_cmpa_s;
+} sh_int_cmpa_u_t;
+#else
+typedef union sh_int_cmpa_u {
+	mmr_t	sh_int_cmpa_regval;
+	struct {
+		mmr_t	reserved_0     : 9;
+		mmr_t	real_time_cmpa : 55;
+	} sh_int_cmpa_s;
+} sh_int_cmpa_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_INT_CMPB"                        */
+/*                  RTC Compare Value for Processor B                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_int_cmpb_u {
+	mmr_t	sh_int_cmpb_regval;
+	struct {
+		mmr_t	real_time_cmpb : 55;
+		mmr_t	reserved_0     : 9;
+	} sh_int_cmpb_s;
+} sh_int_cmpb_u_t;
+#else
+typedef union sh_int_cmpb_u {
+	mmr_t	sh_int_cmpb_regval;
+	struct {
+		mmr_t	reserved_0     : 9;
+		mmr_t	real_time_cmpb : 55;
+	} sh_int_cmpb_s;
+} sh_int_cmpb_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_INT_CMPC"                        */
+/*                  RTC Compare Value for Processor C                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_int_cmpc_u {
+	mmr_t	sh_int_cmpc_regval;
+	struct {
+		mmr_t	real_time_cmpc : 55;
+		mmr_t	reserved_0     : 9;
+	} sh_int_cmpc_s;
+} sh_int_cmpc_u_t;
+#else
+typedef union sh_int_cmpc_u {
+	mmr_t	sh_int_cmpc_regval;
+	struct {
+		mmr_t	reserved_0     : 9;
+		mmr_t	real_time_cmpc : 55;
+	} sh_int_cmpc_s;
+} sh_int_cmpc_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_INT_CMPD"                        */
+/*                  RTC Compare Value for Processor D                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_int_cmpd_u {
+	mmr_t	sh_int_cmpd_regval;
+	struct {
+		mmr_t	real_time_cmpd : 55;
+		mmr_t	reserved_0     : 9;
+	} sh_int_cmpd_s;
+} sh_int_cmpd_u_t;
+#else
+typedef union sh_int_cmpd_u {
+	mmr_t	sh_int_cmpd_regval;
+	struct {
+		mmr_t	reserved_0     : 9;
+		mmr_t	real_time_cmpd : 55;
+	} sh_int_cmpd_s;
+} sh_int_cmpd_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_INT_PROF"                        */
+/*                      Profile Compare Registers                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_int_prof_u {
+	mmr_t	sh_int_prof_regval;
+	struct {
+		mmr_t	profile_compare : 32;
+		mmr_t	reserved_0      : 32;
+	} sh_int_prof_s;
+} sh_int_prof_u_t;
+#else
+typedef union sh_int_prof_u {
+	mmr_t	sh_int_prof_regval;
+	struct {
+		mmr_t	reserved_0      : 32;
+		mmr_t	profile_compare : 32;
+	} sh_int_prof_s;
+} sh_int_prof_u_t;
+#endif
+
+/* ==================================================================== */
+/*                          Register "SH_RTC"                           */
+/*                           Real-time Clock                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_rtc_u {
+	mmr_t	sh_rtc_regval;
+	struct {
+		mmr_t	real_time_clock : 55;
+		mmr_t	reserved_0      : 9;
+	} sh_rtc_s;
+} sh_rtc_u_t;
+#else
+typedef union sh_rtc_u {
+	mmr_t	sh_rtc_regval;
+	struct {
+		mmr_t	reserved_0      : 9;
+		mmr_t	real_time_clock : 55;
+	} sh_rtc_s;
+} sh_rtc_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH0"                        */
+/*                          Scratch Register 0                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_scratch0_u {
+	mmr_t	sh_scratch0_regval;
+	struct {
+		mmr_t	scratch0    : 64;
+	} sh_scratch0_s;
+} sh_scratch0_u_t;
+#else
+typedef union sh_scratch0_u {
+	mmr_t	sh_scratch0_regval;
+	struct {
+		mmr_t	scratch0    : 64;
+	} sh_scratch0_s;
+} sh_scratch0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH1"                        */
+/*                          Scratch Register 1                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_scratch1_u {
+	mmr_t	sh_scratch1_regval;
+	struct {
+		mmr_t	scratch1    : 64;
+	} sh_scratch1_s;
+} sh_scratch1_u_t;
+#else
+typedef union sh_scratch1_u {
+	mmr_t	sh_scratch1_regval;
+	struct {
+		mmr_t	scratch1    : 64;
+	} sh_scratch1_s;
+} sh_scratch1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH2"                        */
+/*                          Scratch Register 2                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_scratch2_u {
+	mmr_t	sh_scratch2_regval;
+	struct {
+		mmr_t	scratch2    : 64;
+	} sh_scratch2_s;
+} sh_scratch2_u_t;
+#else
+typedef union sh_scratch2_u {
+	mmr_t	sh_scratch2_regval;
+	struct {
+		mmr_t	scratch2    : 64;
+	} sh_scratch2_s;
+} sh_scratch2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH3"                        */
+/*                          Scratch Register 3                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_scratch3_u {
+	mmr_t	sh_scratch3_regval;
+	struct {
+		mmr_t	scratch3    : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_scratch3_s;
+} sh_scratch3_u_t;
+#else
+typedef union sh_scratch3_u {
+	mmr_t	sh_scratch3_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	scratch3    : 1;
+	} sh_scratch3_s;
+} sh_scratch3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                        Register "SH_SCRATCH4"                        */
+/*                          Scratch Register 4                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_scratch4_u {
+	mmr_t	sh_scratch4_regval;
+	struct {
+		mmr_t	scratch4    : 1;
+		mmr_t	reserved_0  : 63;
+	} sh_scratch4_s;
+} sh_scratch4_u_t;
+#else
+typedef union sh_scratch4_u {
+	mmr_t	sh_scratch4_regval;
+	struct {
+		mmr_t	reserved_0  : 63;
+		mmr_t	scratch4    : 1;
+	} sh_scratch4_s;
+} sh_scratch4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_CRB_MESSAGE_CONTROL"                   */
+/*               Coherent Request Buffer Message Control                */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_crb_message_control_u {
+	mmr_t	sh_crb_message_control_regval;
+	struct {
+		mmr_t	system_coherence_enable           : 1;
+		mmr_t	local_speculative_message_enable  : 1;
+		mmr_t	remote_speculative_message_enable : 1;
+		mmr_t	message_color                     : 1;
+		mmr_t	message_color_enable              : 1;
+		mmr_t	rrb_attribute_mismatch_fsb_enable : 1;
+		mmr_t	wrb_attribute_mismatch_fsb_enable : 1;
+		mmr_t	irb_attribute_mismatch_fsb_enable : 1;
+		mmr_t	rrb_attribute_mismatch_xb_enable  : 1;
+		mmr_t	wrb_attribute_mismatch_xb_enable  : 1;
+		mmr_t	suppress_bogus_writes             : 1;
+		mmr_t	enable_ivack_consolidation        : 1;
+		mmr_t	reserved_0                        : 20;
+		mmr_t	ivack_stall_count                 : 16;
+		mmr_t	ivack_throttle_control            : 16;
+	} sh_crb_message_control_s;
+} sh_crb_message_control_u_t;
+#else
+typedef union sh_crb_message_control_u {
+	mmr_t	sh_crb_message_control_regval;
+	struct {
+		mmr_t	ivack_throttle_control            : 16;
+		mmr_t	ivack_stall_count                 : 16;
+		mmr_t	reserved_0                        : 20;
+		mmr_t	enable_ivack_consolidation        : 1;
+		mmr_t	suppress_bogus_writes             : 1;
+		mmr_t	wrb_attribute_mismatch_xb_enable  : 1;
+		mmr_t	rrb_attribute_mismatch_xb_enable  : 1;
+		mmr_t	irb_attribute_mismatch_fsb_enable : 1;
+		mmr_t	wrb_attribute_mismatch_fsb_enable : 1;
+		mmr_t	rrb_attribute_mismatch_fsb_enable : 1;
+		mmr_t	message_color_enable              : 1;
+		mmr_t	message_color                     : 1;
+		mmr_t	remote_speculative_message_enable : 1;
+		mmr_t	local_speculative_message_enable  : 1;
+		mmr_t	system_coherence_enable           : 1;
+	} sh_crb_message_control_s;
+} sh_crb_message_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_CRB_NACK_LIMIT"                     */
+/*                            CRB Nack Limit                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_crb_nack_limit_u {
+	mmr_t	sh_crb_nack_limit_regval;
+	struct {
+		mmr_t	limit       : 12;
+		mmr_t	pri_freq    : 4;
+		mmr_t	reserved_0  : 47;
+		mmr_t	enable      : 1;
+	} sh_crb_nack_limit_s;
+} sh_crb_nack_limit_u_t;
+#else
+typedef union sh_crb_nack_limit_u {
+	mmr_t	sh_crb_nack_limit_regval;
+	struct {
+		mmr_t	enable      : 1;
+		mmr_t	reserved_0  : 47;
+		mmr_t	pri_freq    : 4;
+		mmr_t	limit       : 12;
+	} sh_crb_nack_limit_s;
+} sh_crb_nack_limit_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_CRB_TIMEOUT_PRESCALE"                  */
+/*               Coherent Request Buffer Timeout Prescale               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_crb_timeout_prescale_u {
+	mmr_t	sh_crb_timeout_prescale_regval;
+	struct {
+		mmr_t	scaling_factor : 32;
+		mmr_t	reserved_0     : 32;
+	} sh_crb_timeout_prescale_s;
+} sh_crb_timeout_prescale_u_t;
+#else
+typedef union sh_crb_timeout_prescale_u {
+	mmr_t	sh_crb_timeout_prescale_regval;
+	struct {
+		mmr_t	reserved_0     : 32;
+		mmr_t	scaling_factor : 32;
+	} sh_crb_timeout_prescale_s;
+} sh_crb_timeout_prescale_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_CRB_TIMEOUT_SKID"                    */
+/*              Coherent Request Buffer Timeout Skid Limit              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_crb_timeout_skid_u {
+	mmr_t	sh_crb_timeout_skid_regval;
+	struct {
+		mmr_t	skid             : 6;
+		mmr_t	reserved_0       : 57;
+		mmr_t	reset_skid_count : 1;
+	} sh_crb_timeout_skid_s;
+} sh_crb_timeout_skid_u_t;
+#else
+typedef union sh_crb_timeout_skid_u {
+	mmr_t	sh_crb_timeout_skid_regval;
+	struct {
+		mmr_t	reset_skid_count : 1;
+		mmr_t	reserved_0       : 57;
+		mmr_t	skid             : 6;
+	} sh_crb_timeout_skid_s;
+} sh_crb_timeout_skid_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MEMORY_WRITE_STATUS_0"                  */
+/*                    Memory Write Status for CPU 0                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_memory_write_status_0_u {
+	mmr_t	sh_memory_write_status_0_regval;
+	struct {
+		mmr_t	pending_write_count : 6;
+		mmr_t	reserved_0          : 58;
+	} sh_memory_write_status_0_s;
+} sh_memory_write_status_0_u_t;
+#else
+typedef union sh_memory_write_status_0_u {
+	mmr_t	sh_memory_write_status_0_regval;
+	struct {
+		mmr_t	reserved_0          : 58;
+		mmr_t	pending_write_count : 6;
+	} sh_memory_write_status_0_s;
+} sh_memory_write_status_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MEMORY_WRITE_STATUS_1"                  */
+/*                    Memory Write Status for CPU 1                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_memory_write_status_1_u {
+	mmr_t	sh_memory_write_status_1_regval;
+	struct {
+		mmr_t	pending_write_count : 6;
+		mmr_t	reserved_0          : 58;
+	} sh_memory_write_status_1_s;
+} sh_memory_write_status_1_u_t;
+#else
+typedef union sh_memory_write_status_1_u {
+	mmr_t	sh_memory_write_status_1_regval;
+	struct {
+		mmr_t	reserved_0          : 58;
+		mmr_t	pending_write_count : 6;
+	} sh_memory_write_status_1_s;
+} sh_memory_write_status_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PIO_WRITE_STATUS_0"                   */
+/*                      PIO Write Status for CPU 0                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pio_write_status_0_u {
+	mmr_t	sh_pio_write_status_0_regval;
+	struct {
+		mmr_t	multi_write_error   : 1;
+		mmr_t	write_deadlock      : 1;
+		mmr_t	write_error         : 1;
+		mmr_t	write_error_address : 47;
+		mmr_t	reserved_0          : 6;
+		mmr_t	pending_write_count : 6;
+		mmr_t	reserved_1          : 1;
+		mmr_t	writes_ok           : 1;
+	} sh_pio_write_status_0_s;
+} sh_pio_write_status_0_u_t;
+#else
+typedef union sh_pio_write_status_0_u {
+	mmr_t	sh_pio_write_status_0_regval;
+	struct {
+		mmr_t	writes_ok           : 1;
+		mmr_t	reserved_1          : 1;
+		mmr_t	pending_write_count : 6;
+		mmr_t	reserved_0          : 6;
+		mmr_t	write_error_address : 47;
+		mmr_t	write_error         : 1;
+		mmr_t	write_deadlock      : 1;
+		mmr_t	multi_write_error   : 1;
+	} sh_pio_write_status_0_s;
+} sh_pio_write_status_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_PIO_WRITE_STATUS_1"                   */
+/*                      PIO Write Status for CPU 1                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pio_write_status_1_u {
+	mmr_t	sh_pio_write_status_1_regval;
+	struct {
+		mmr_t	multi_write_error   : 1;
+		mmr_t	write_deadlock      : 1;
+		mmr_t	write_error         : 1;
+		mmr_t	write_error_address : 47;
+		mmr_t	reserved_0          : 6;
+		mmr_t	pending_write_count : 6;
+		mmr_t	reserved_1          : 1;
+		mmr_t	writes_ok           : 1;
+	} sh_pio_write_status_1_s;
+} sh_pio_write_status_1_u_t;
+#else
+typedef union sh_pio_write_status_1_u {
+	mmr_t	sh_pio_write_status_1_regval;
+	struct {
+		mmr_t	writes_ok           : 1;
+		mmr_t	reserved_1          : 1;
+		mmr_t	pending_write_count : 6;
+		mmr_t	reserved_0          : 6;
+		mmr_t	write_error_address : 47;
+		mmr_t	write_error         : 1;
+		mmr_t	write_deadlock      : 1;
+		mmr_t	multi_write_error   : 1;
+	} sh_pio_write_status_1_s;
+} sh_pio_write_status_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_MEMORY_WRITE_STATUS_NON_USER_0"             */
+/*            Memory Write Status for CPU 0. OS access only             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_memory_write_status_non_user_0_u {
+	mmr_t	sh_memory_write_status_non_user_0_regval;
+	struct {
+		mmr_t	pending_write_count : 6;
+		mmr_t	reserved_0          : 57;
+		mmr_t	clear               : 1;
+	} sh_memory_write_status_non_user_0_s;
+} sh_memory_write_status_non_user_0_u_t;
+#else
+typedef union sh_memory_write_status_non_user_0_u {
+	mmr_t	sh_memory_write_status_non_user_0_regval;
+	struct {
+		mmr_t	clear               : 1;
+		mmr_t	reserved_0          : 57;
+		mmr_t	pending_write_count : 6;
+	} sh_memory_write_status_non_user_0_s;
+} sh_memory_write_status_non_user_0_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_MEMORY_WRITE_STATUS_NON_USER_1"             */
+/*            Memory Write Status for CPU 1. OS access only             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_memory_write_status_non_user_1_u {
+	mmr_t	sh_memory_write_status_non_user_1_regval;
+	struct {
+		mmr_t	pending_write_count : 6;
+		mmr_t	reserved_0          : 57;
+		mmr_t	clear               : 1;
+	} sh_memory_write_status_non_user_1_s;
+} sh_memory_write_status_non_user_1_u_t;
+#else
+typedef union sh_memory_write_status_non_user_1_u {
+	mmr_t	sh_memory_write_status_non_user_1_regval;
+	struct {
+		mmr_t	clear               : 1;
+		mmr_t	reserved_0          : 57;
+		mmr_t	pending_write_count : 6;
+	} sh_memory_write_status_non_user_1_s;
+} sh_memory_write_status_non_user_1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_MMRBIST_ERR"                       */
+/*                  Error capture for bist read errors                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mmrbist_err_u {
+	mmr_t	sh_mmrbist_err_regval;
+	struct {
+		mmr_t	addr              : 33;
+		mmr_t	reserved_0        : 3;
+		mmr_t	detected          : 1;
+		mmr_t	multiple_detected : 1;
+		mmr_t	cancelled         : 1;
+		mmr_t	reserved_1        : 25;
+	} sh_mmrbist_err_s;
+} sh_mmrbist_err_u_t;
+#else
+typedef union sh_mmrbist_err_u {
+	mmr_t	sh_mmrbist_err_regval;
+	struct {
+		mmr_t	reserved_1        : 25;
+		mmr_t	cancelled         : 1;
+		mmr_t	multiple_detected : 1;
+		mmr_t	detected          : 1;
+		mmr_t	reserved_0        : 3;
+		mmr_t	addr              : 33;
+	} sh_mmrbist_err_s;
+} sh_mmrbist_err_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MISC_ERR_HDR_LOWER"                   */
+/*                       Header capture register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_misc_err_hdr_lower_u {
+	mmr_t	sh_misc_err_hdr_lower_regval;
+	struct {
+		mmr_t	reserved_0  : 3;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+		mmr_t	reserved_1  : 2;
+		mmr_t	write       : 1;
+		mmr_t	reserved_2  : 2;
+		mmr_t	valid       : 1;
+	} sh_misc_err_hdr_lower_s;
+} sh_misc_err_hdr_lower_u_t;
+#else
+typedef union sh_misc_err_hdr_lower_u {
+	mmr_t	sh_misc_err_hdr_lower_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_2  : 2;
+		mmr_t	write       : 1;
+		mmr_t	reserved_1  : 2;
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	reserved_0  : 3;
+	} sh_misc_err_hdr_lower_s;
+} sh_misc_err_hdr_lower_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MISC_ERR_HDR_UPPER"                   */
+/*           Error header capture packet and protocol errors            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_misc_err_hdr_upper_u {
+	mmr_t	sh_misc_err_hdr_upper_regval;
+	struct {
+		mmr_t	dir_protocol  : 1;
+		mmr_t	illegal_cmd   : 1;
+		mmr_t	nonexist_addr : 1;
+		mmr_t	rmw_uc        : 1;
+		mmr_t	rmw_cor       : 1;
+		mmr_t	dir_acc       : 1;
+		mmr_t	pi_pkt_size   : 1;
+		mmr_t	xn_pkt_size   : 1;
+		mmr_t	reserved_0    : 12;
+		mmr_t	echo          : 9;
+		mmr_t	reserved_1    : 35;
+	} sh_misc_err_hdr_upper_s;
+} sh_misc_err_hdr_upper_u_t;
+#else
+typedef union sh_misc_err_hdr_upper_u {
+	mmr_t	sh_misc_err_hdr_upper_regval;
+	struct {
+		mmr_t	reserved_1    : 35;
+		mmr_t	echo          : 9;
+		mmr_t	reserved_0    : 12;
+		mmr_t	xn_pkt_size   : 1;
+		mmr_t	pi_pkt_size   : 1;
+		mmr_t	dir_acc       : 1;
+		mmr_t	rmw_cor       : 1;
+		mmr_t	rmw_uc        : 1;
+		mmr_t	nonexist_addr : 1;
+		mmr_t	illegal_cmd   : 1;
+		mmr_t	dir_protocol  : 1;
+	} sh_misc_err_hdr_upper_s;
+} sh_misc_err_hdr_upper_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_DIR_UC_ERR_HDR_LOWER"                  */
+/*                       Header capture register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_dir_uc_err_hdr_lower_u {
+	mmr_t	sh_dir_uc_err_hdr_lower_regval;
+	struct {
+		mmr_t	reserved_0  : 3;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+		mmr_t	reserved_1  : 2;
+		mmr_t	write       : 1;
+		mmr_t	reserved_2  : 2;
+		mmr_t	valid       : 1;
+	} sh_dir_uc_err_hdr_lower_s;
+} sh_dir_uc_err_hdr_lower_u_t;
+#else
+typedef union sh_dir_uc_err_hdr_lower_u {
+	mmr_t	sh_dir_uc_err_hdr_lower_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_2  : 2;
+		mmr_t	write       : 1;
+		mmr_t	reserved_1  : 2;
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	reserved_0  : 3;
+	} sh_dir_uc_err_hdr_lower_s;
+} sh_dir_uc_err_hdr_lower_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_DIR_UC_ERR_HDR_UPPER"                  */
+/*           Error header capture packet and protocol errors            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_dir_uc_err_hdr_upper_u {
+	mmr_t	sh_dir_uc_err_hdr_upper_regval;
+	struct {
+		mmr_t	reserved_0  : 3;
+		mmr_t	dir_uc      : 1;
+		mmr_t	reserved_1  : 16;
+		mmr_t	echo        : 9;
+		mmr_t	reserved_2  : 35;
+	} sh_dir_uc_err_hdr_upper_s;
+} sh_dir_uc_err_hdr_upper_u_t;
+#else
+typedef union sh_dir_uc_err_hdr_upper_u {
+	mmr_t	sh_dir_uc_err_hdr_upper_regval;
+	struct {
+		mmr_t	reserved_2  : 35;
+		mmr_t	echo        : 9;
+		mmr_t	reserved_1  : 16;
+		mmr_t	dir_uc      : 1;
+		mmr_t	reserved_0  : 3;
+	} sh_dir_uc_err_hdr_upper_s;
+} sh_dir_uc_err_hdr_upper_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_DIR_COR_ERR_HDR_LOWER"                  */
+/*                       Header capture register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_dir_cor_err_hdr_lower_u {
+	mmr_t	sh_dir_cor_err_hdr_lower_regval;
+	struct {
+		mmr_t	reserved_0  : 3;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+		mmr_t	reserved_1  : 2;
+		mmr_t	write       : 1;
+		mmr_t	reserved_2  : 2;
+		mmr_t	valid       : 1;
+	} sh_dir_cor_err_hdr_lower_s;
+} sh_dir_cor_err_hdr_lower_u_t;
+#else
+typedef union sh_dir_cor_err_hdr_lower_u {
+	mmr_t	sh_dir_cor_err_hdr_lower_regval;
+	struct {
+		mmr_t	valid       : 1;
+		mmr_t	reserved_2  : 2;
+		mmr_t	write       : 1;
+		mmr_t	reserved_1  : 2;
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	reserved_0  : 3;
+	} sh_dir_cor_err_hdr_lower_s;
+} sh_dir_cor_err_hdr_lower_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_DIR_COR_ERR_HDR_UPPER"                  */
+/*           Error header capture packet and protocol errors            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_dir_cor_err_hdr_upper_u {
+	mmr_t	sh_dir_cor_err_hdr_upper_regval;
+	struct {
+		mmr_t	reserved_0  : 8;
+		mmr_t	dir_cor     : 1;
+		mmr_t	reserved_1  : 11;
+		mmr_t	echo        : 9;
+		mmr_t	reserved_2  : 35;
+	} sh_dir_cor_err_hdr_upper_s;
+} sh_dir_cor_err_hdr_upper_u_t;
+#else
+typedef union sh_dir_cor_err_hdr_upper_u {
+	mmr_t	sh_dir_cor_err_hdr_upper_regval;
+	struct {
+		mmr_t	reserved_2  : 35;
+		mmr_t	echo        : 9;
+		mmr_t	reserved_1  : 11;
+		mmr_t	dir_cor     : 1;
+		mmr_t	reserved_0  : 8;
+	} sh_dir_cor_err_hdr_upper_s;
+} sh_dir_cor_err_hdr_upper_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MEM_ERROR_SUMMARY"                    */
+/*                          Memory error flags                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mem_error_summary_u {
+	mmr_t	sh_mem_error_summary_regval;
+	struct {
+		mmr_t	illegal_cmd           : 1;
+		mmr_t	nonexist_addr         : 1;
+		mmr_t	dqlp_dir_perr         : 1;
+		mmr_t	dqrp_dir_perr         : 1;
+		mmr_t	dqlp_dir_uc           : 1;
+		mmr_t	dqlp_dir_cor          : 1;
+		mmr_t	dqrp_dir_uc           : 1;
+		mmr_t	dqrp_dir_cor          : 1;
+		mmr_t	acx_int_hw            : 1;
+		mmr_t	acy_int_hw            : 1;
+		mmr_t	dir_acc               : 1;
+		mmr_t	reserved_0            : 1;
+		mmr_t	dqlp_int_uc           : 1;
+		mmr_t	dqlp_int_cor          : 1;
+		mmr_t	dqlp_int_hw           : 1;
+		mmr_t	reserved_1            : 1;
+		mmr_t	dqls_int_uc           : 1;
+		mmr_t	dqls_int_cor          : 1;
+		mmr_t	dqls_int_hw           : 1;
+		mmr_t	reserved_2            : 1;
+		mmr_t	dqrp_int_uc           : 1;
+		mmr_t	dqrp_int_cor          : 1;
+		mmr_t	dqrp_int_hw           : 1;
+		mmr_t	reserved_3            : 1;
+		mmr_t	dqrs_int_uc           : 1;
+		mmr_t	dqrs_int_cor          : 1;
+		mmr_t	dqrs_int_hw           : 1;
+		mmr_t	reserved_4            : 1;
+		mmr_t	pi_reply_overflow     : 1;
+		mmr_t	xn_reply_overflow     : 1;
+		mmr_t	pi_request_overflow   : 1;
+		mmr_t	xn_request_overflow   : 1;
+		mmr_t	red_black_err_timeout : 1;
+		mmr_t	pi_pkt_size           : 1;
+		mmr_t	xn_pkt_size           : 1;
+		mmr_t	reserved_5            : 29;
+	} sh_mem_error_summary_s;
+} sh_mem_error_summary_u_t;
+#else
+typedef union sh_mem_error_summary_u {
+	mmr_t	sh_mem_error_summary_regval;
+	struct {
+		mmr_t	reserved_5            : 29;
+		mmr_t	xn_pkt_size           : 1;
+		mmr_t	pi_pkt_size           : 1;
+		mmr_t	red_black_err_timeout : 1;
+		mmr_t	xn_request_overflow   : 1;
+		mmr_t	pi_request_overflow   : 1;
+		mmr_t	xn_reply_overflow     : 1;
+		mmr_t	pi_reply_overflow     : 1;
+		mmr_t	reserved_4            : 1;
+		mmr_t	dqrs_int_hw           : 1;
+		mmr_t	dqrs_int_cor          : 1;
+		mmr_t	dqrs_int_uc           : 1;
+		mmr_t	reserved_3            : 1;
+		mmr_t	dqrp_int_hw           : 1;
+		mmr_t	dqrp_int_cor          : 1;
+		mmr_t	dqrp_int_uc           : 1;
+		mmr_t	reserved_2            : 1;
+		mmr_t	dqls_int_hw           : 1;
+		mmr_t	dqls_int_cor          : 1;
+		mmr_t	dqls_int_uc           : 1;
+		mmr_t	reserved_1            : 1;
+		mmr_t	dqlp_int_hw           : 1;
+		mmr_t	dqlp_int_cor          : 1;
+		mmr_t	dqlp_int_uc           : 1;
+		mmr_t	reserved_0            : 1;
+		mmr_t	dir_acc               : 1;
+		mmr_t	acy_int_hw            : 1;
+		mmr_t	acx_int_hw            : 1;
+		mmr_t	dqrp_dir_cor          : 1;
+		mmr_t	dqrp_dir_uc           : 1;
+		mmr_t	dqlp_dir_cor          : 1;
+		mmr_t	dqlp_dir_uc           : 1;
+		mmr_t	dqrp_dir_perr         : 1;
+		mmr_t	dqlp_dir_perr         : 1;
+		mmr_t	nonexist_addr         : 1;
+		mmr_t	illegal_cmd           : 1;
+	} sh_mem_error_summary_s;
+} sh_mem_error_summary_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MEM_ERROR_OVERFLOW"                   */
+/*                          Memory error flags                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mem_error_overflow_u {
+	mmr_t	sh_mem_error_overflow_regval;
+	struct {
+		mmr_t	illegal_cmd           : 1;
+		mmr_t	nonexist_addr         : 1;
+		mmr_t	dqlp_dir_perr         : 1;
+		mmr_t	dqrp_dir_perr         : 1;
+		mmr_t	dqlp_dir_uc           : 1;
+		mmr_t	dqlp_dir_cor          : 1;
+		mmr_t	dqrp_dir_uc           : 1;
+		mmr_t	dqrp_dir_cor          : 1;
+		mmr_t	acx_int_hw            : 1;
+		mmr_t	acy_int_hw            : 1;
+		mmr_t	dir_acc               : 1;
+		mmr_t	reserved_0            : 1;
+		mmr_t	dqlp_int_uc           : 1;
+		mmr_t	dqlp_int_cor          : 1;
+		mmr_t	dqlp_int_hw           : 1;
+		mmr_t	reserved_1            : 1;
+		mmr_t	dqls_int_uc           : 1;
+		mmr_t	dqls_int_cor          : 1;
+		mmr_t	dqls_int_hw           : 1;
+		mmr_t	reserved_2            : 1;
+		mmr_t	dqrp_int_uc           : 1;
+		mmr_t	dqrp_int_cor          : 1;
+		mmr_t	dqrp_int_hw           : 1;
+		mmr_t	reserved_3            : 1;
+		mmr_t	dqrs_int_uc           : 1;
+		mmr_t	dqrs_int_cor          : 1;
+		mmr_t	dqrs_int_hw           : 1;
+		mmr_t	reserved_4            : 1;
+		mmr_t	pi_reply_overflow     : 1;
+		mmr_t	xn_reply_overflow     : 1;
+		mmr_t	pi_request_overflow   : 1;
+		mmr_t	xn_request_overflow   : 1;
+		mmr_t	red_black_err_timeout : 1;
+		mmr_t	pi_pkt_size           : 1;
+		mmr_t	xn_pkt_size           : 1;
+		mmr_t	reserved_5            : 29;
+	} sh_mem_error_overflow_s;
+} sh_mem_error_overflow_u_t;
+#else
+typedef union sh_mem_error_overflow_u {
+	mmr_t	sh_mem_error_overflow_regval;
+	struct {
+		mmr_t	reserved_5            : 29;
+		mmr_t	xn_pkt_size           : 1;
+		mmr_t	pi_pkt_size           : 1;
+		mmr_t	red_black_err_timeout : 1;
+		mmr_t	xn_request_overflow   : 1;
+		mmr_t	pi_request_overflow   : 1;
+		mmr_t	xn_reply_overflow     : 1;
+		mmr_t	pi_reply_overflow     : 1;
+		mmr_t	reserved_4            : 1;
+		mmr_t	dqrs_int_hw           : 1;
+		mmr_t	dqrs_int_cor          : 1;
+		mmr_t	dqrs_int_uc           : 1;
+		mmr_t	reserved_3            : 1;
+		mmr_t	dqrp_int_hw           : 1;
+		mmr_t	dqrp_int_cor          : 1;
+		mmr_t	dqrp_int_uc           : 1;
+		mmr_t	reserved_2            : 1;
+		mmr_t	dqls_int_hw           : 1;
+		mmr_t	dqls_int_cor          : 1;
+		mmr_t	dqls_int_uc           : 1;
+		mmr_t	reserved_1            : 1;
+		mmr_t	dqlp_int_hw           : 1;
+		mmr_t	dqlp_int_cor          : 1;
+		mmr_t	dqlp_int_uc           : 1;
+		mmr_t	reserved_0            : 1;
+		mmr_t	dir_acc               : 1;
+		mmr_t	acy_int_hw            : 1;
+		mmr_t	acx_int_hw            : 1;
+		mmr_t	dqrp_dir_cor          : 1;
+		mmr_t	dqrp_dir_uc           : 1;
+		mmr_t	dqlp_dir_cor          : 1;
+		mmr_t	dqlp_dir_uc           : 1;
+		mmr_t	dqrp_dir_perr         : 1;
+		mmr_t	dqlp_dir_perr         : 1;
+		mmr_t	nonexist_addr         : 1;
+		mmr_t	illegal_cmd           : 1;
+	} sh_mem_error_overflow_s;
+} sh_mem_error_overflow_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_MEM_ERROR_MASK"                     */
+/*                          Memory error flags                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mem_error_mask_u {
+	mmr_t	sh_mem_error_mask_regval;
+	struct {
+		mmr_t	illegal_cmd           : 1;
+		mmr_t	nonexist_addr         : 1;
+		mmr_t	dqlp_dir_perr         : 1;
+		mmr_t	dqrp_dir_perr         : 1;
+		mmr_t	dqlp_dir_uc           : 1;
+		mmr_t	dqlp_dir_cor          : 1;
+		mmr_t	dqrp_dir_uc           : 1;
+		mmr_t	dqrp_dir_cor          : 1;
+		mmr_t	acx_int_hw            : 1;
+		mmr_t	acy_int_hw            : 1;
+		mmr_t	dir_acc               : 1;
+		mmr_t	reserved_0            : 1;
+		mmr_t	dqlp_int_uc           : 1;
+		mmr_t	dqlp_int_cor          : 1;
+		mmr_t	dqlp_int_hw           : 1;
+		mmr_t	reserved_1            : 1;
+		mmr_t	dqls_int_uc           : 1;
+		mmr_t	dqls_int_cor          : 1;
+		mmr_t	dqls_int_hw           : 1;
+		mmr_t	reserved_2            : 1;
+		mmr_t	dqrp_int_uc           : 1;
+		mmr_t	dqrp_int_cor          : 1;
+		mmr_t	dqrp_int_hw           : 1;
+		mmr_t	reserved_3            : 1;
+		mmr_t	dqrs_int_uc           : 1;
+		mmr_t	dqrs_int_cor          : 1;
+		mmr_t	dqrs_int_hw           : 1;
+		mmr_t	reserved_4            : 1;
+		mmr_t	pi_reply_overflow     : 1;
+		mmr_t	xn_reply_overflow     : 1;
+		mmr_t	pi_request_overflow   : 1;
+		mmr_t	xn_request_overflow   : 1;
+		mmr_t	red_black_err_timeout : 1;
+		mmr_t	pi_pkt_size           : 1;
+		mmr_t	xn_pkt_size           : 1;
+		mmr_t	reserved_5            : 29;
+	} sh_mem_error_mask_s;
+} sh_mem_error_mask_u_t;
+#else
+typedef union sh_mem_error_mask_u {
+	mmr_t	sh_mem_error_mask_regval;
+	struct {
+		mmr_t	reserved_5            : 29;
+		mmr_t	xn_pkt_size           : 1;
+		mmr_t	pi_pkt_size           : 1;
+		mmr_t	red_black_err_timeout : 1;
+		mmr_t	xn_request_overflow   : 1;
+		mmr_t	pi_request_overflow   : 1;
+		mmr_t	xn_reply_overflow     : 1;
+		mmr_t	pi_reply_overflow     : 1;
+		mmr_t	reserved_4            : 1;
+		mmr_t	dqrs_int_hw           : 1;
+		mmr_t	dqrs_int_cor          : 1;
+		mmr_t	dqrs_int_uc           : 1;
+		mmr_t	reserved_3            : 1;
+		mmr_t	dqrp_int_hw           : 1;
+		mmr_t	dqrp_int_cor          : 1;
+		mmr_t	dqrp_int_uc           : 1;
+		mmr_t	reserved_2            : 1;
+		mmr_t	dqls_int_hw           : 1;
+		mmr_t	dqls_int_cor          : 1;
+		mmr_t	dqls_int_uc           : 1;
+		mmr_t	reserved_1            : 1;
+		mmr_t	dqlp_int_hw           : 1;
+		mmr_t	dqlp_int_cor          : 1;
+		mmr_t	dqlp_int_uc           : 1;
+		mmr_t	reserved_0            : 1;
+		mmr_t	dir_acc               : 1;
+		mmr_t	acy_int_hw            : 1;
+		mmr_t	acx_int_hw            : 1;
+		mmr_t	dqrp_dir_cor          : 1;
+		mmr_t	dqrp_dir_uc           : 1;
+		mmr_t	dqlp_dir_cor          : 1;
+		mmr_t	dqlp_dir_uc           : 1;
+		mmr_t	dqrp_dir_perr         : 1;
+		mmr_t	dqlp_dir_perr         : 1;
+		mmr_t	nonexist_addr         : 1;
+		mmr_t	illegal_cmd           : 1;
+	} sh_mem_error_mask_s;
+} sh_mem_error_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_X_DIMM_CFG"                       */
+/*                       AC Mem Config Registers                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_dimm_cfg_u {
+	mmr_t	sh_x_dimm_cfg_regval;
+	struct {
+		mmr_t	dimm0_size  : 3;
+		mmr_t	dimm0_2bk   : 1;
+		mmr_t	dimm0_rev   : 1;
+		mmr_t	dimm0_cs    : 2;
+		mmr_t	reserved_0  : 1;
+		mmr_t	dimm1_size  : 3;
+		mmr_t	dimm1_2bk   : 1;
+		mmr_t	dimm1_rev   : 1;
+		mmr_t	dimm1_cs    : 2;
+		mmr_t	reserved_1  : 1;
+		mmr_t	dimm2_size  : 3;
+		mmr_t	dimm2_2bk   : 1;
+		mmr_t	dimm2_rev   : 1;
+		mmr_t	dimm2_cs    : 2;
+		mmr_t	reserved_2  : 1;
+		mmr_t	dimm3_size  : 3;
+		mmr_t	dimm3_2bk   : 1;
+		mmr_t	dimm3_rev   : 1;
+		mmr_t	dimm3_cs    : 2;
+		mmr_t	reserved_3  : 1;
+		mmr_t	freq        : 4;
+		mmr_t	reserved_4  : 28;
+	} sh_x_dimm_cfg_s;
+} sh_x_dimm_cfg_u_t;
+#else
+typedef union sh_x_dimm_cfg_u {
+	mmr_t	sh_x_dimm_cfg_regval;
+	struct {
+		mmr_t	reserved_4  : 28;
+		mmr_t	freq        : 4;
+		mmr_t	reserved_3  : 1;
+		mmr_t	dimm3_cs    : 2;
+		mmr_t	dimm3_rev   : 1;
+		mmr_t	dimm3_2bk   : 1;
+		mmr_t	dimm3_size  : 3;
+		mmr_t	reserved_2  : 1;
+		mmr_t	dimm2_cs    : 2;
+		mmr_t	dimm2_rev   : 1;
+		mmr_t	dimm2_2bk   : 1;
+		mmr_t	dimm2_size  : 3;
+		mmr_t	reserved_1  : 1;
+		mmr_t	dimm1_cs    : 2;
+		mmr_t	dimm1_rev   : 1;
+		mmr_t	dimm1_2bk   : 1;
+		mmr_t	dimm1_size  : 3;
+		mmr_t	reserved_0  : 1;
+		mmr_t	dimm0_cs    : 2;
+		mmr_t	dimm0_rev   : 1;
+		mmr_t	dimm0_2bk   : 1;
+		mmr_t	dimm0_size  : 3;
+	} sh_x_dimm_cfg_s;
+} sh_x_dimm_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_Y_DIMM_CFG"                       */
+/*                       AC Mem Config Registers                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_dimm_cfg_u {
+	mmr_t	sh_y_dimm_cfg_regval;
+	struct {
+		mmr_t	dimm0_size  : 3;
+		mmr_t	dimm0_2bk   : 1;
+		mmr_t	dimm0_rev   : 1;
+		mmr_t	dimm0_cs    : 2;
+		mmr_t	reserved_0  : 1;
+		mmr_t	dimm1_size  : 3;
+		mmr_t	dimm1_2bk   : 1;
+		mmr_t	dimm1_rev   : 1;
+		mmr_t	dimm1_cs    : 2;
+		mmr_t	reserved_1  : 1;
+		mmr_t	dimm2_size  : 3;
+		mmr_t	dimm2_2bk   : 1;
+		mmr_t	dimm2_rev   : 1;
+		mmr_t	dimm2_cs    : 2;
+		mmr_t	reserved_2  : 1;
+		mmr_t	dimm3_size  : 3;
+		mmr_t	dimm3_2bk   : 1;
+		mmr_t	dimm3_rev   : 1;
+		mmr_t	dimm3_cs    : 2;
+		mmr_t	reserved_3  : 1;
+		mmr_t	freq        : 4;
+		mmr_t	reserved_4  : 28;
+	} sh_y_dimm_cfg_s;
+} sh_y_dimm_cfg_u_t;
+#else
+typedef union sh_y_dimm_cfg_u {
+	mmr_t	sh_y_dimm_cfg_regval;
+	struct {
+		mmr_t	reserved_4  : 28;
+		mmr_t	freq        : 4;
+		mmr_t	reserved_3  : 1;
+		mmr_t	dimm3_cs    : 2;
+		mmr_t	dimm3_rev   : 1;
+		mmr_t	dimm3_2bk   : 1;
+		mmr_t	dimm3_size  : 3;
+		mmr_t	reserved_2  : 1;
+		mmr_t	dimm2_cs    : 2;
+		mmr_t	dimm2_rev   : 1;
+		mmr_t	dimm2_2bk   : 1;
+		mmr_t	dimm2_size  : 3;
+		mmr_t	reserved_1  : 1;
+		mmr_t	dimm1_cs    : 2;
+		mmr_t	dimm1_rev   : 1;
+		mmr_t	dimm1_2bk   : 1;
+		mmr_t	dimm1_size  : 3;
+		mmr_t	reserved_0  : 1;
+		mmr_t	dimm0_cs    : 2;
+		mmr_t	dimm0_rev   : 1;
+		mmr_t	dimm0_2bk   : 1;
+		mmr_t	dimm0_size  : 3;
+	} sh_y_dimm_cfg_s;
+} sh_y_dimm_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_JNR_DIMM_CFG"                      */
+/*                       AC Mem Config Registers                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_jnr_dimm_cfg_u {
+	mmr_t	sh_jnr_dimm_cfg_regval;
+	struct {
+		mmr_t	dimm0_size  : 3;
+		mmr_t	dimm0_2bk   : 1;
+		mmr_t	dimm0_rev   : 1;
+		mmr_t	dimm0_cs    : 2;
+		mmr_t	reserved_0  : 1;
+		mmr_t	dimm1_size  : 3;
+		mmr_t	dimm1_2bk   : 1;
+		mmr_t	dimm1_rev   : 1;
+		mmr_t	dimm1_cs    : 2;
+		mmr_t	reserved_1  : 1;
+		mmr_t	dimm2_size  : 3;
+		mmr_t	dimm2_2bk   : 1;
+		mmr_t	dimm2_rev   : 1;
+		mmr_t	dimm2_cs    : 2;
+		mmr_t	reserved_2  : 1;
+		mmr_t	dimm3_size  : 3;
+		mmr_t	dimm3_2bk   : 1;
+		mmr_t	dimm3_rev   : 1;
+		mmr_t	dimm3_cs    : 2;
+		mmr_t	reserved_3  : 1;
+		mmr_t	freq        : 4;
+		mmr_t	reserved_4  : 28;
+	} sh_jnr_dimm_cfg_s;
+} sh_jnr_dimm_cfg_u_t;
+#else
+typedef union sh_jnr_dimm_cfg_u {
+	mmr_t	sh_jnr_dimm_cfg_regval;
+	struct {
+		mmr_t	reserved_4  : 28;
+		mmr_t	freq        : 4;
+		mmr_t	reserved_3  : 1;
+		mmr_t	dimm3_cs    : 2;
+		mmr_t	dimm3_rev   : 1;
+		mmr_t	dimm3_2bk   : 1;
+		mmr_t	dimm3_size  : 3;
+		mmr_t	reserved_2  : 1;
+		mmr_t	dimm2_cs    : 2;
+		mmr_t	dimm2_rev   : 1;
+		mmr_t	dimm2_2bk   : 1;
+		mmr_t	dimm2_size  : 3;
+		mmr_t	reserved_1  : 1;
+		mmr_t	dimm1_cs    : 2;
+		mmr_t	dimm1_rev   : 1;
+		mmr_t	dimm1_2bk   : 1;
+		mmr_t	dimm1_size  : 3;
+		mmr_t	reserved_0  : 1;
+		mmr_t	dimm0_cs    : 2;
+		mmr_t	dimm0_rev   : 1;
+		mmr_t	dimm0_2bk   : 1;
+		mmr_t	dimm0_size  : 3;
+	} sh_jnr_dimm_cfg_s;
+} sh_jnr_dimm_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_X_PHASE_CFG"                       */
+/*                      AC Phase Config Registers                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_phase_cfg_u {
+	mmr_t	sh_x_phase_cfg_regval;
+	struct {
+		mmr_t	ld_a        : 5;
+		mmr_t	ld_b        : 5;
+		mmr_t	dq_ld_a     : 5;
+		mmr_t	dq_ld_b     : 5;
+		mmr_t	hold        : 5;
+		mmr_t	hold_req    : 5;
+		mmr_t	add_cp      : 5;
+		mmr_t	bubble_en   : 5;
+		mmr_t	pha_bubble  : 3;
+		mmr_t	phb_bubble  : 3;
+		mmr_t	phc_bubble  : 3;
+		mmr_t	phd_bubble  : 3;
+		mmr_t	phe_bubble  : 3;
+		mmr_t	sel_a       : 4;
+		mmr_t	dq_sel_a    : 4;
+		mmr_t	reserved_0  : 1;
+	} sh_x_phase_cfg_s;
+} sh_x_phase_cfg_u_t;
+#else
+typedef union sh_x_phase_cfg_u {
+	mmr_t	sh_x_phase_cfg_regval;
+	struct {
+		mmr_t	reserved_0  : 1;
+		mmr_t	dq_sel_a    : 4;
+		mmr_t	sel_a       : 4;
+		mmr_t	phe_bubble  : 3;
+		mmr_t	phd_bubble  : 3;
+		mmr_t	phc_bubble  : 3;
+		mmr_t	phb_bubble  : 3;
+		mmr_t	pha_bubble  : 3;
+		mmr_t	bubble_en   : 5;
+		mmr_t	add_cp      : 5;
+		mmr_t	hold_req    : 5;
+		mmr_t	hold        : 5;
+		mmr_t	dq_ld_b     : 5;
+		mmr_t	dq_ld_a     : 5;
+		mmr_t	ld_b        : 5;
+		mmr_t	ld_a        : 5;
+	} sh_x_phase_cfg_s;
+} sh_x_phase_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_CFG"                          */
+/*                         AC Config Registers                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_cfg_u {
+	mmr_t	sh_x_cfg_regval;
+	struct {
+		mmr_t	mode_serial             : 1;
+		mmr_t	dirc_random_replacement : 1;
+		mmr_t	dir_counter_init        : 6;
+		mmr_t	ta_dlys                 : 32;
+		mmr_t	da_bb_clr               : 4;
+		mmr_t	dc_bb_clr               : 4;
+		mmr_t	wt_bb_clr               : 4;
+		mmr_t	sso_wt_en               : 1;
+		mmr_t	trcd2_en                : 1;
+		mmr_t	trcd4_en                : 1;
+		mmr_t	req_cntr_dis            : 1;
+		mmr_t	req_cntr_val            : 6;
+		mmr_t	inv_cas_addr            : 1;
+		mmr_t	clr_dir_cache           : 1;
+	} sh_x_cfg_s;
+} sh_x_cfg_u_t;
+#else
+typedef union sh_x_cfg_u {
+	mmr_t	sh_x_cfg_regval;
+	struct {
+		mmr_t	clr_dir_cache           : 1;
+		mmr_t	inv_cas_addr            : 1;
+		mmr_t	req_cntr_val            : 6;
+		mmr_t	req_cntr_dis            : 1;
+		mmr_t	trcd4_en                : 1;
+		mmr_t	trcd2_en                : 1;
+		mmr_t	sso_wt_en               : 1;
+		mmr_t	wt_bb_clr               : 4;
+		mmr_t	dc_bb_clr               : 4;
+		mmr_t	da_bb_clr               : 4;
+		mmr_t	ta_dlys                 : 32;
+		mmr_t	dir_counter_init        : 6;
+		mmr_t	dirc_random_replacement : 1;
+		mmr_t	mode_serial             : 1;
+	} sh_x_cfg_s;
+} sh_x_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_X_DQCT_CFG"                       */
+/*                         AC Config Registers                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_dqct_cfg_u {
+	mmr_t	sh_x_dqct_cfg_regval;
+	struct {
+		mmr_t	rd_sel      : 4;
+		mmr_t	wt_sel      : 4;
+		mmr_t	dta_rd_sel  : 4;
+		mmr_t	dta_wt_sel  : 4;
+		mmr_t	dir_rd_sel  : 4;
+		mmr_t	mdir_rd_sel : 4;
+		mmr_t	reserved_0  : 40;
+	} sh_x_dqct_cfg_s;
+} sh_x_dqct_cfg_u_t;
+#else
+typedef union sh_x_dqct_cfg_u {
+	mmr_t	sh_x_dqct_cfg_regval;
+	struct {
+		mmr_t	reserved_0  : 40;
+		mmr_t	mdir_rd_sel : 4;
+		mmr_t	dir_rd_sel  : 4;
+		mmr_t	dta_wt_sel  : 4;
+		mmr_t	dta_rd_sel  : 4;
+		mmr_t	wt_sel      : 4;
+		mmr_t	rd_sel      : 4;
+	} sh_x_dqct_cfg_s;
+} sh_x_dqct_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_X_REFRESH_CONTROL"                    */
+/*                       Refresh Control Register                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_refresh_control_u {
+	mmr_t	sh_x_refresh_control_regval;
+	struct {
+		mmr_t	enable      : 8;
+		mmr_t	interval    : 9;
+		mmr_t	hold        : 6;
+		mmr_t	interleave  : 1;
+		mmr_t	half_rate   : 4;
+		mmr_t	reserved_0  : 36;
+	} sh_x_refresh_control_s;
+} sh_x_refresh_control_u_t;
+#else
+typedef union sh_x_refresh_control_u {
+	mmr_t	sh_x_refresh_control_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	half_rate   : 4;
+		mmr_t	interleave  : 1;
+		mmr_t	hold        : 6;
+		mmr_t	interval    : 9;
+		mmr_t	enable      : 8;
+	} sh_x_refresh_control_s;
+} sh_x_refresh_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_Y_PHASE_CFG"                       */
+/*                      AC Phase Config Registers                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_phase_cfg_u {
+	mmr_t	sh_y_phase_cfg_regval;
+	struct {
+		mmr_t	ld_a        : 5;
+		mmr_t	ld_b        : 5;
+		mmr_t	dq_ld_a     : 5;
+		mmr_t	dq_ld_b     : 5;
+		mmr_t	hold        : 5;
+		mmr_t	hold_req    : 5;
+		mmr_t	add_cp      : 5;
+		mmr_t	bubble_en   : 5;
+		mmr_t	pha_bubble  : 3;
+		mmr_t	phb_bubble  : 3;
+		mmr_t	phc_bubble  : 3;
+		mmr_t	phd_bubble  : 3;
+		mmr_t	phe_bubble  : 3;
+		mmr_t	sel_a       : 4;
+		mmr_t	dq_sel_a    : 4;
+		mmr_t	reserved_0  : 1;
+	} sh_y_phase_cfg_s;
+} sh_y_phase_cfg_u_t;
+#else
+typedef union sh_y_phase_cfg_u {
+	mmr_t	sh_y_phase_cfg_regval;
+	struct {
+		mmr_t	reserved_0  : 1;
+		mmr_t	dq_sel_a    : 4;
+		mmr_t	sel_a       : 4;
+		mmr_t	phe_bubble  : 3;
+		mmr_t	phd_bubble  : 3;
+		mmr_t	phc_bubble  : 3;
+		mmr_t	phb_bubble  : 3;
+		mmr_t	pha_bubble  : 3;
+		mmr_t	bubble_en   : 5;
+		mmr_t	add_cp      : 5;
+		mmr_t	hold_req    : 5;
+		mmr_t	hold        : 5;
+		mmr_t	dq_ld_b     : 5;
+		mmr_t	dq_ld_a     : 5;
+		mmr_t	ld_b        : 5;
+		mmr_t	ld_a        : 5;
+	} sh_y_phase_cfg_s;
+} sh_y_phase_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_CFG"                          */
+/*                         AC Config Registers                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_cfg_u {
+	mmr_t	sh_y_cfg_regval;
+	struct {
+		mmr_t	mode_serial             : 1;
+		mmr_t	dirc_random_replacement : 1;
+		mmr_t	dir_counter_init        : 6;
+		mmr_t	ta_dlys                 : 32;
+		mmr_t	da_bb_clr               : 4;
+		mmr_t	dc_bb_clr               : 4;
+		mmr_t	wt_bb_clr               : 4;
+		mmr_t	sso_wt_en               : 1;
+		mmr_t	trcd2_en                : 1;
+		mmr_t	trcd4_en                : 1;
+		mmr_t	req_cntr_dis            : 1;
+		mmr_t	req_cntr_val            : 6;
+		mmr_t	inv_cas_addr            : 1;
+		mmr_t	clr_dir_cache           : 1;
+	} sh_y_cfg_s;
+} sh_y_cfg_u_t;
+#else
+typedef union sh_y_cfg_u {
+	mmr_t	sh_y_cfg_regval;
+	struct {
+		mmr_t	clr_dir_cache           : 1;
+		mmr_t	inv_cas_addr            : 1;
+		mmr_t	req_cntr_val            : 6;
+		mmr_t	req_cntr_dis            : 1;
+		mmr_t	trcd4_en                : 1;
+		mmr_t	trcd2_en                : 1;
+		mmr_t	sso_wt_en               : 1;
+		mmr_t	wt_bb_clr               : 4;
+		mmr_t	dc_bb_clr               : 4;
+		mmr_t	da_bb_clr               : 4;
+		mmr_t	ta_dlys                 : 32;
+		mmr_t	dir_counter_init        : 6;
+		mmr_t	dirc_random_replacement : 1;
+		mmr_t	mode_serial             : 1;
+	} sh_y_cfg_s;
+} sh_y_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_Y_DQCT_CFG"                       */
+/*                         AC Config Registers                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_dqct_cfg_u {
+	mmr_t	sh_y_dqct_cfg_regval;
+	struct {
+		mmr_t	rd_sel      : 4;
+		mmr_t	wt_sel      : 4;
+		mmr_t	dta_rd_sel  : 4;
+		mmr_t	dta_wt_sel  : 4;
+		mmr_t	dir_rd_sel  : 4;
+		mmr_t	mdir_rd_sel : 4;
+		mmr_t	reserved_0  : 40;
+	} sh_y_dqct_cfg_s;
+} sh_y_dqct_cfg_u_t;
+#else
+typedef union sh_y_dqct_cfg_u {
+	mmr_t	sh_y_dqct_cfg_regval;
+	struct {
+		mmr_t	reserved_0  : 40;
+		mmr_t	mdir_rd_sel : 4;
+		mmr_t	dir_rd_sel  : 4;
+		mmr_t	dta_wt_sel  : 4;
+		mmr_t	dta_rd_sel  : 4;
+		mmr_t	wt_sel      : 4;
+		mmr_t	rd_sel      : 4;
+	} sh_y_dqct_cfg_s;
+} sh_y_dqct_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_Y_REFRESH_CONTROL"                    */
+/*                       Refresh Control Register                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_refresh_control_u {
+	mmr_t	sh_y_refresh_control_regval;
+	struct {
+		mmr_t	enable      : 8;
+		mmr_t	interval    : 9;
+		mmr_t	hold        : 6;
+		mmr_t	interleave  : 1;
+		mmr_t	half_rate   : 4;
+		mmr_t	reserved_0  : 36;
+	} sh_y_refresh_control_s;
+} sh_y_refresh_control_u_t;
+#else
+typedef union sh_y_refresh_control_u {
+	mmr_t	sh_y_refresh_control_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	half_rate   : 4;
+		mmr_t	interleave  : 1;
+		mmr_t	hold        : 6;
+		mmr_t	interval    : 9;
+		mmr_t	enable      : 8;
+	} sh_y_refresh_control_s;
+} sh_y_refresh_control_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_MEM_RED_BLACK"                      */
+/*                     MD fairness watchdog timers                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mem_red_black_u {
+	mmr_t	sh_mem_red_black_regval;
+	struct {
+		mmr_t	time        : 16;
+		mmr_t	err_time    : 36;
+		mmr_t	reserved_0  : 12;
+	} sh_mem_red_black_s;
+} sh_mem_red_black_u_t;
+#else
+typedef union sh_mem_red_black_u {
+	mmr_t	sh_mem_red_black_regval;
+	struct {
+		mmr_t	reserved_0  : 12;
+		mmr_t	err_time    : 36;
+		mmr_t	time        : 16;
+	} sh_mem_red_black_s;
+} sh_mem_red_black_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_MISC_MEM_CFG"                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_misc_mem_cfg_u {
+	mmr_t	sh_misc_mem_cfg_regval;
+	struct {
+		mmr_t	express_header_enable       : 1;
+		mmr_t	spec_header_enable          : 1;
+		mmr_t	jnr_bypass_enable           : 1;
+		mmr_t	xn_rd_same_as_pi            : 1;
+		mmr_t	low_write_buffer_threshold  : 6;
+		mmr_t	reserved_0                  : 2;
+		mmr_t	low_victim_buffer_threshold : 6;
+		mmr_t	reserved_1                  : 2;
+		mmr_t	throttle_cnt                : 8;
+		mmr_t	disabled_read_tnums         : 5;
+		mmr_t	reserved_2                  : 3;
+		mmr_t	disabled_write_tnums        : 5;
+		mmr_t	reserved_3                  : 3;
+		mmr_t	disabled_victims            : 6;
+		mmr_t	reserved_4                  : 2;
+		mmr_t	alternate_xn_rp_plane       : 1;
+		mmr_t	reserved_5                  : 11;
+	} sh_misc_mem_cfg_s;
+} sh_misc_mem_cfg_u_t;
+#else
+typedef union sh_misc_mem_cfg_u {
+	mmr_t	sh_misc_mem_cfg_regval;
+	struct {
+		mmr_t	reserved_5                  : 11;
+		mmr_t	alternate_xn_rp_plane       : 1;
+		mmr_t	reserved_4                  : 2;
+		mmr_t	disabled_victims            : 6;
+		mmr_t	reserved_3                  : 3;
+		mmr_t	disabled_write_tnums        : 5;
+		mmr_t	reserved_2                  : 3;
+		mmr_t	disabled_read_tnums         : 5;
+		mmr_t	throttle_cnt                : 8;
+		mmr_t	reserved_1                  : 2;
+		mmr_t	low_victim_buffer_threshold : 6;
+		mmr_t	reserved_0                  : 2;
+		mmr_t	low_write_buffer_threshold  : 6;
+		mmr_t	xn_rd_same_as_pi            : 1;
+		mmr_t	jnr_bypass_enable           : 1;
+		mmr_t	spec_header_enable          : 1;
+		mmr_t	express_header_enable       : 1;
+	} sh_misc_mem_cfg_s;
+} sh_misc_mem_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_PIO_RQ_CRD_CTL"                     */
+/*                  pio_rq Credit Circulation Control                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pio_rq_crd_ctl_u {
+	mmr_t	sh_pio_rq_crd_ctl_regval;
+	struct {
+		mmr_t	depth       : 6;
+		mmr_t	reserved_0  : 58;
+	} sh_pio_rq_crd_ctl_s;
+} sh_pio_rq_crd_ctl_u_t;
+#else
+typedef union sh_pio_rq_crd_ctl_u {
+	mmr_t	sh_pio_rq_crd_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 58;
+		mmr_t	depth       : 6;
+	} sh_pio_rq_crd_ctl_s;
+} sh_pio_rq_crd_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_PI_MD_RQ_CRD_CTL"                    */
+/*                 pi_md_rq Credit Circulation Control                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_md_rq_crd_ctl_u {
+	mmr_t	sh_pi_md_rq_crd_ctl_regval;
+	struct {
+		mmr_t	depth       : 6;
+		mmr_t	reserved_0  : 58;
+	} sh_pi_md_rq_crd_ctl_s;
+} sh_pi_md_rq_crd_ctl_u_t;
+#else
+typedef union sh_pi_md_rq_crd_ctl_u {
+	mmr_t	sh_pi_md_rq_crd_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 58;
+		mmr_t	depth       : 6;
+	} sh_pi_md_rq_crd_ctl_s;
+} sh_pi_md_rq_crd_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_PI_MD_RP_CRD_CTL"                    */
+/*                 pi_md_rp Credit Circulation Control                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_pi_md_rp_crd_ctl_u {
+	mmr_t	sh_pi_md_rp_crd_ctl_regval;
+	struct {
+		mmr_t	depth       : 6;
+		mmr_t	reserved_0  : 58;
+	} sh_pi_md_rp_crd_ctl_s;
+} sh_pi_md_rp_crd_ctl_u_t;
+#else
+typedef union sh_pi_md_rp_crd_ctl_u {
+	mmr_t	sh_pi_md_rp_crd_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 58;
+		mmr_t	depth       : 6;
+	} sh_pi_md_rp_crd_ctl_s;
+} sh_pi_md_rp_crd_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_MD_RQ_CRD_CTL"                    */
+/*                 xn_md_rq Credit Circulation Control                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_rq_crd_ctl_u {
+	mmr_t	sh_xn_md_rq_crd_ctl_regval;
+	struct {
+		mmr_t	depth       : 6;
+		mmr_t	reserved_0  : 58;
+	} sh_xn_md_rq_crd_ctl_s;
+} sh_xn_md_rq_crd_ctl_u_t;
+#else
+typedef union sh_xn_md_rq_crd_ctl_u {
+	mmr_t	sh_xn_md_rq_crd_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 58;
+		mmr_t	depth       : 6;
+	} sh_xn_md_rq_crd_ctl_s;
+} sh_xn_md_rq_crd_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_XN_MD_RP_CRD_CTL"                    */
+/*                 xn_md_rp Credit Circulation Control                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_xn_md_rp_crd_ctl_u {
+	mmr_t	sh_xn_md_rp_crd_ctl_regval;
+	struct {
+		mmr_t	depth       : 6;
+		mmr_t	reserved_0  : 58;
+	} sh_xn_md_rp_crd_ctl_s;
+} sh_xn_md_rp_crd_ctl_u_t;
+#else
+typedef union sh_xn_md_rp_crd_ctl_u {
+	mmr_t	sh_xn_md_rp_crd_ctl_regval;
+	struct {
+		mmr_t	reserved_0  : 58;
+		mmr_t	depth       : 6;
+	} sh_xn_md_rp_crd_ctl_s;
+} sh_xn_md_rp_crd_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG0"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag0_u {
+	mmr_t	sh_x_tag0_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_x_tag0_s;
+} sh_x_tag0_u_t;
+#else
+typedef union sh_x_tag0_u {
+	mmr_t	sh_x_tag0_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_x_tag0_s;
+} sh_x_tag0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG1"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag1_u {
+	mmr_t	sh_x_tag1_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_x_tag1_s;
+} sh_x_tag1_u_t;
+#else
+typedef union sh_x_tag1_u {
+	mmr_t	sh_x_tag1_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_x_tag1_s;
+} sh_x_tag1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG2"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag2_u {
+	mmr_t	sh_x_tag2_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_x_tag2_s;
+} sh_x_tag2_u_t;
+#else
+typedef union sh_x_tag2_u {
+	mmr_t	sh_x_tag2_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_x_tag2_s;
+} sh_x_tag2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG3"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag3_u {
+	mmr_t	sh_x_tag3_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_x_tag3_s;
+} sh_x_tag3_u_t;
+#else
+typedef union sh_x_tag3_u {
+	mmr_t	sh_x_tag3_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_x_tag3_s;
+} sh_x_tag3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG4"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag4_u {
+	mmr_t	sh_x_tag4_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_x_tag4_s;
+} sh_x_tag4_u_t;
+#else
+typedef union sh_x_tag4_u {
+	mmr_t	sh_x_tag4_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_x_tag4_s;
+} sh_x_tag4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG5"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag5_u {
+	mmr_t	sh_x_tag5_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_x_tag5_s;
+} sh_x_tag5_u_t;
+#else
+typedef union sh_x_tag5_u {
+	mmr_t	sh_x_tag5_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_x_tag5_s;
+} sh_x_tag5_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG6"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag6_u {
+	mmr_t	sh_x_tag6_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_x_tag6_s;
+} sh_x_tag6_u_t;
+#else
+typedef union sh_x_tag6_u {
+	mmr_t	sh_x_tag6_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_x_tag6_s;
+} sh_x_tag6_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_X_TAG7"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag7_u {
+	mmr_t	sh_x_tag7_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_x_tag7_s;
+} sh_x_tag7_u_t;
+#else
+typedef union sh_x_tag7_u {
+	mmr_t	sh_x_tag7_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_x_tag7_s;
+} sh_x_tag7_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG0"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag0_u {
+	mmr_t	sh_y_tag0_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_y_tag0_s;
+} sh_y_tag0_u_t;
+#else
+typedef union sh_y_tag0_u {
+	mmr_t	sh_y_tag0_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_y_tag0_s;
+} sh_y_tag0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG1"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag1_u {
+	mmr_t	sh_y_tag1_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_y_tag1_s;
+} sh_y_tag1_u_t;
+#else
+typedef union sh_y_tag1_u {
+	mmr_t	sh_y_tag1_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_y_tag1_s;
+} sh_y_tag1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG2"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag2_u {
+	mmr_t	sh_y_tag2_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_y_tag2_s;
+} sh_y_tag2_u_t;
+#else
+typedef union sh_y_tag2_u {
+	mmr_t	sh_y_tag2_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_y_tag2_s;
+} sh_y_tag2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG3"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag3_u {
+	mmr_t	sh_y_tag3_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_y_tag3_s;
+} sh_y_tag3_u_t;
+#else
+typedef union sh_y_tag3_u {
+	mmr_t	sh_y_tag3_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_y_tag3_s;
+} sh_y_tag3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG4"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag4_u {
+	mmr_t	sh_y_tag4_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_y_tag4_s;
+} sh_y_tag4_u_t;
+#else
+typedef union sh_y_tag4_u {
+	mmr_t	sh_y_tag4_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_y_tag4_s;
+} sh_y_tag4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG5"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag5_u {
+	mmr_t	sh_y_tag5_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_y_tag5_s;
+} sh_y_tag5_u_t;
+#else
+typedef union sh_y_tag5_u {
+	mmr_t	sh_y_tag5_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_y_tag5_s;
+} sh_y_tag5_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG6"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag6_u {
+	mmr_t	sh_y_tag6_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_y_tag6_s;
+} sh_y_tag6_u_t;
+#else
+typedef union sh_y_tag6_u {
+	mmr_t	sh_y_tag6_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_y_tag6_s;
+} sh_y_tag6_u_t;
+#endif
+
+/* ==================================================================== */
+/*                         Register "SH_Y_TAG7"                         */
+/*                           AC tag Registers                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag7_u {
+	mmr_t	sh_y_tag7_regval;
+	struct {
+		mmr_t	tag         : 20;
+		mmr_t	reserved_0  : 44;
+	} sh_y_tag7_s;
+} sh_y_tag7_u_t;
+#else
+typedef union sh_y_tag7_u {
+	mmr_t	sh_y_tag7_regval;
+	struct {
+		mmr_t	reserved_0  : 44;
+		mmr_t	tag         : 20;
+	} sh_y_tag7_s;
+} sh_y_tag7_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_MMRBIST_BASE"                      */
+/*                        mmr/bist base address                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mmrbist_base_u {
+	mmr_t	sh_mmrbist_base_regval;
+	struct {
+		mmr_t	reserved_0  : 3;
+		mmr_t	dword_addr  : 47;
+		mmr_t	reserved_1  : 14;
+	} sh_mmrbist_base_s;
+} sh_mmrbist_base_u_t;
+#else
+typedef union sh_mmrbist_base_u {
+	mmr_t	sh_mmrbist_base_regval;
+	struct {
+		mmr_t	reserved_1  : 14;
+		mmr_t	dword_addr  : 47;
+		mmr_t	reserved_0  : 3;
+	} sh_mmrbist_base_s;
+} sh_mmrbist_base_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_MMRBIST_CTL"                       */
+/*                          Bist base address                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mmrbist_ctl_u {
+	mmr_t	sh_mmrbist_ctl_regval;
+	struct {
+		mmr_t	block_length : 31;
+		mmr_t	reserved_0   : 1;
+		mmr_t	cmd          : 7;
+		mmr_t	reserved_1   : 1;
+		mmr_t	in_progress  : 1;
+		mmr_t	fail         : 1;
+		mmr_t	mem_idle     : 1;
+		mmr_t	reserved_2   : 1;
+		mmr_t	reset_state  : 1;
+		mmr_t	reserved_3   : 19;
+	} sh_mmrbist_ctl_s;
+} sh_mmrbist_ctl_u_t;
+#else
+typedef union sh_mmrbist_ctl_u {
+	mmr_t	sh_mmrbist_ctl_regval;
+	struct {
+		mmr_t	reserved_3   : 19;
+		mmr_t	reset_state  : 1;
+		mmr_t	reserved_2   : 1;
+		mmr_t	mem_idle     : 1;
+		mmr_t	fail         : 1;
+		mmr_t	in_progress  : 1;
+		mmr_t	reserved_1   : 1;
+		mmr_t	cmd          : 7;
+		mmr_t	reserved_0   : 1;
+		mmr_t	block_length : 31;
+	} sh_mmrbist_ctl_s;
+} sh_mmrbist_ctl_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_MD_DBUG_DATA_CFG"                    */
+/*                configuration for md debug data muxes                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dbug_data_cfg_u {
+	mmr_t	sh_md_dbug_data_cfg_regval;
+	struct {
+		mmr_t	nibble0_chiplet : 3;
+		mmr_t	reserved_0      : 1;
+		mmr_t	nibble0_nibble  : 3;
+		mmr_t	reserved_1      : 1;
+		mmr_t	nibble1_chiplet : 3;
+		mmr_t	reserved_2      : 1;
+		mmr_t	nibble1_nibble  : 3;
+		mmr_t	reserved_3      : 1;
+		mmr_t	nibble2_chiplet : 3;
+		mmr_t	reserved_4      : 1;
+		mmr_t	nibble2_nibble  : 3;
+		mmr_t	reserved_5      : 1;
+		mmr_t	nibble3_chiplet : 3;
+		mmr_t	reserved_6      : 1;
+		mmr_t	nibble3_nibble  : 3;
+		mmr_t	reserved_7      : 1;
+		mmr_t	nibble4_chiplet : 3;
+		mmr_t	reserved_8      : 1;
+		mmr_t	nibble4_nibble  : 3;
+		mmr_t	reserved_9      : 1;
+		mmr_t	nibble5_chiplet : 3;
+		mmr_t	reserved_10     : 1;
+		mmr_t	nibble5_nibble  : 3;
+		mmr_t	reserved_11     : 1;
+		mmr_t	nibble6_chiplet : 3;
+		mmr_t	reserved_12     : 1;
+		mmr_t	nibble6_nibble  : 3;
+		mmr_t	reserved_13     : 1;
+		mmr_t	nibble7_chiplet : 3;
+		mmr_t	reserved_14     : 1;
+		mmr_t	nibble7_nibble  : 3;
+		mmr_t	reserved_15     : 1;
+	} sh_md_dbug_data_cfg_s;
+} sh_md_dbug_data_cfg_u_t;
+#else
+typedef union sh_md_dbug_data_cfg_u {
+	mmr_t	sh_md_dbug_data_cfg_regval;
+	struct {
+		mmr_t	reserved_15     : 1;
+		mmr_t	nibble7_nibble  : 3;
+		mmr_t	reserved_14     : 1;
+		mmr_t	nibble7_chiplet : 3;
+		mmr_t	reserved_13     : 1;
+		mmr_t	nibble6_nibble  : 3;
+		mmr_t	reserved_12     : 1;
+		mmr_t	nibble6_chiplet : 3;
+		mmr_t	reserved_11     : 1;
+		mmr_t	nibble5_nibble  : 3;
+		mmr_t	reserved_10     : 1;
+		mmr_t	nibble5_chiplet : 3;
+		mmr_t	reserved_9      : 1;
+		mmr_t	nibble4_nibble  : 3;
+		mmr_t	reserved_8      : 1;
+		mmr_t	nibble4_chiplet : 3;
+		mmr_t	reserved_7      : 1;
+		mmr_t	nibble3_nibble  : 3;
+		mmr_t	reserved_6      : 1;
+		mmr_t	nibble3_chiplet : 3;
+		mmr_t	reserved_5      : 1;
+		mmr_t	nibble2_nibble  : 3;
+		mmr_t	reserved_4      : 1;
+		mmr_t	nibble2_chiplet : 3;
+		mmr_t	reserved_3      : 1;
+		mmr_t	nibble1_nibble  : 3;
+		mmr_t	reserved_2      : 1;
+		mmr_t	nibble1_chiplet : 3;
+		mmr_t	reserved_1      : 1;
+		mmr_t	nibble0_nibble  : 3;
+		mmr_t	reserved_0      : 1;
+		mmr_t	nibble0_chiplet : 3;
+	} sh_md_dbug_data_cfg_s;
+} sh_md_dbug_data_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DBUG_TRIGGER_CFG"                   */
+/*                 configuration for md debug triggers                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dbug_trigger_cfg_u {
+	mmr_t	sh_md_dbug_trigger_cfg_regval;
+	struct {
+		mmr_t	nibble0_chiplet : 3;
+		mmr_t	reserved_0      : 1;
+		mmr_t	nibble0_nibble  : 3;
+		mmr_t	reserved_1      : 1;
+		mmr_t	nibble1_chiplet : 3;
+		mmr_t	reserved_2      : 1;
+		mmr_t	nibble1_nibble  : 3;
+		mmr_t	reserved_3      : 1;
+		mmr_t	nibble2_chiplet : 3;
+		mmr_t	reserved_4      : 1;
+		mmr_t	nibble2_nibble  : 3;
+		mmr_t	reserved_5      : 1;
+		mmr_t	nibble3_chiplet : 3;
+		mmr_t	reserved_6      : 1;
+		mmr_t	nibble3_nibble  : 3;
+		mmr_t	reserved_7      : 1;
+		mmr_t	nibble4_chiplet : 3;
+		mmr_t	reserved_8      : 1;
+		mmr_t	nibble4_nibble  : 3;
+		mmr_t	reserved_9      : 1;
+		mmr_t	nibble5_chiplet : 3;
+		mmr_t	reserved_10     : 1;
+		mmr_t	nibble5_nibble  : 3;
+		mmr_t	reserved_11     : 1;
+		mmr_t	nibble6_chiplet : 3;
+		mmr_t	reserved_12     : 1;
+		mmr_t	nibble6_nibble  : 3;
+		mmr_t	reserved_13     : 1;
+		mmr_t	nibble7_chiplet : 3;
+		mmr_t	reserved_14     : 1;
+		mmr_t	nibble7_nibble  : 3;
+		mmr_t	enable          : 1;
+	} sh_md_dbug_trigger_cfg_s;
+} sh_md_dbug_trigger_cfg_u_t;
+#else
+typedef union sh_md_dbug_trigger_cfg_u {
+	mmr_t	sh_md_dbug_trigger_cfg_regval;
+	struct {
+		mmr_t	enable          : 1;
+		mmr_t	nibble7_nibble  : 3;
+		mmr_t	reserved_14     : 1;
+		mmr_t	nibble7_chiplet : 3;
+		mmr_t	reserved_13     : 1;
+		mmr_t	nibble6_nibble  : 3;
+		mmr_t	reserved_12     : 1;
+		mmr_t	nibble6_chiplet : 3;
+		mmr_t	reserved_11     : 1;
+		mmr_t	nibble5_nibble  : 3;
+		mmr_t	reserved_10     : 1;
+		mmr_t	nibble5_chiplet : 3;
+		mmr_t	reserved_9      : 1;
+		mmr_t	nibble4_nibble  : 3;
+		mmr_t	reserved_8      : 1;
+		mmr_t	nibble4_chiplet : 3;
+		mmr_t	reserved_7      : 1;
+		mmr_t	nibble3_nibble  : 3;
+		mmr_t	reserved_6      : 1;
+		mmr_t	nibble3_chiplet : 3;
+		mmr_t	reserved_5      : 1;
+		mmr_t	nibble2_nibble  : 3;
+		mmr_t	reserved_4      : 1;
+		mmr_t	nibble2_chiplet : 3;
+		mmr_t	reserved_3      : 1;
+		mmr_t	nibble1_nibble  : 3;
+		mmr_t	reserved_2      : 1;
+		mmr_t	nibble1_chiplet : 3;
+		mmr_t	reserved_1      : 1;
+		mmr_t	nibble0_nibble  : 3;
+		mmr_t	reserved_0      : 1;
+		mmr_t	nibble0_chiplet : 3;
+	} sh_md_dbug_trigger_cfg_s;
+} sh_md_dbug_trigger_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_MD_DBUG_COMPARE"                     */
+/*                  md debug compare pattern and mask                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dbug_compare_u {
+	mmr_t	sh_md_dbug_compare_regval;
+	struct {
+		mmr_t	pattern     : 32;
+		mmr_t	mask        : 32;
+	} sh_md_dbug_compare_s;
+} sh_md_dbug_compare_u_t;
+#else
+typedef union sh_md_dbug_compare_u {
+	mmr_t	sh_md_dbug_compare_regval;
+	struct {
+		mmr_t	mask        : 32;
+		mmr_t	pattern     : 32;
+	} sh_md_dbug_compare_s;
+} sh_md_dbug_compare_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_X_MOD_DBUG_SEL"                     */
+/*                         MD acx debug select                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_mod_dbug_sel_u {
+	mmr_t	sh_x_mod_dbug_sel_regval;
+	struct {
+		mmr_t	tag_sel     : 8;
+		mmr_t	wbq_sel     : 8;
+		mmr_t	arb_sel     : 8;
+		mmr_t	atl_sel     : 11;
+		mmr_t	atr_sel     : 11;
+		mmr_t	dql_sel     : 6;
+		mmr_t	dqr_sel     : 6;
+		mmr_t	reserved_0  : 6;
+	} sh_x_mod_dbug_sel_s;
+} sh_x_mod_dbug_sel_u_t;
+#else
+typedef union sh_x_mod_dbug_sel_u {
+	mmr_t	sh_x_mod_dbug_sel_regval;
+	struct {
+		mmr_t	reserved_0  : 6;
+		mmr_t	dqr_sel     : 6;
+		mmr_t	dql_sel     : 6;
+		mmr_t	atr_sel     : 11;
+		mmr_t	atl_sel     : 11;
+		mmr_t	arb_sel     : 8;
+		mmr_t	wbq_sel     : 8;
+		mmr_t	tag_sel     : 8;
+	} sh_x_mod_dbug_sel_s;
+} sh_x_mod_dbug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_X_DBUG_SEL"                       */
+/*                         MD acx debug select                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_dbug_sel_u {
+	mmr_t	sh_x_dbug_sel_regval;
+	struct {
+		mmr_t	dbg_sel     : 24;
+		mmr_t	reserved_0  : 40;
+	} sh_x_dbug_sel_s;
+} sh_x_dbug_sel_u_t;
+#else
+typedef union sh_x_dbug_sel_u {
+	mmr_t	sh_x_dbug_sel_regval;
+	struct {
+		mmr_t	reserved_0  : 40;
+		mmr_t	dbg_sel     : 24;
+	} sh_x_dbug_sel_s;
+} sh_x_dbug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_X_LADDR_CMP"                       */
+/*                        MD acx address compare                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_laddr_cmp_u {
+	mmr_t	sh_x_laddr_cmp_regval;
+	struct {
+		mmr_t	cmp_val     : 28;
+		mmr_t	reserved_0  : 4;
+		mmr_t	mask_val    : 28;
+		mmr_t	reserved_1  : 4;
+	} sh_x_laddr_cmp_s;
+} sh_x_laddr_cmp_u_t;
+#else
+typedef union sh_x_laddr_cmp_u {
+	mmr_t	sh_x_laddr_cmp_regval;
+	struct {
+		mmr_t	reserved_1  : 4;
+		mmr_t	mask_val    : 28;
+		mmr_t	reserved_0  : 4;
+		mmr_t	cmp_val     : 28;
+	} sh_x_laddr_cmp_s;
+} sh_x_laddr_cmp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_X_RADDR_CMP"                       */
+/*                        MD acx address compare                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_raddr_cmp_u {
+	mmr_t	sh_x_raddr_cmp_regval;
+	struct {
+		mmr_t	cmp_val     : 28;
+		mmr_t	reserved_0  : 4;
+		mmr_t	mask_val    : 28;
+		mmr_t	reserved_1  : 4;
+	} sh_x_raddr_cmp_s;
+} sh_x_raddr_cmp_u_t;
+#else
+typedef union sh_x_raddr_cmp_u {
+	mmr_t	sh_x_raddr_cmp_regval;
+	struct {
+		mmr_t	reserved_1  : 4;
+		mmr_t	mask_val    : 28;
+		mmr_t	reserved_0  : 4;
+		mmr_t	cmp_val     : 28;
+	} sh_x_raddr_cmp_s;
+} sh_x_raddr_cmp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_X_TAG_CMP"                        */
+/*                        MD acx tagmgr compare                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag_cmp_u {
+	mmr_t	sh_x_tag_cmp_regval;
+	struct {
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	src         : 14;
+		mmr_t	reserved_0  : 9;
+	} sh_x_tag_cmp_s;
+} sh_x_tag_cmp_u_t;
+#else
+typedef union sh_x_tag_cmp_u {
+	mmr_t	sh_x_tag_cmp_regval;
+	struct {
+		mmr_t	reserved_0  : 9;
+		mmr_t	src         : 14;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+	} sh_x_tag_cmp_s;
+} sh_x_tag_cmp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_X_TAG_MASK"                       */
+/*                          MD acx tagmgr mask                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_x_tag_mask_u {
+	mmr_t	sh_x_tag_mask_regval;
+	struct {
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	src         : 14;
+		mmr_t	reserved_0  : 9;
+	} sh_x_tag_mask_s;
+} sh_x_tag_mask_u_t;
+#else
+typedef union sh_x_tag_mask_u {
+	mmr_t	sh_x_tag_mask_regval;
+	struct {
+		mmr_t	reserved_0  : 9;
+		mmr_t	src         : 14;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+	} sh_x_tag_mask_s;
+} sh_x_tag_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_Y_MOD_DBUG_SEL"                     */
+/*                         MD acy debug select                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_mod_dbug_sel_u {
+	mmr_t	sh_y_mod_dbug_sel_regval;
+	struct {
+		mmr_t	tag_sel     : 8;
+		mmr_t	wbq_sel     : 8;
+		mmr_t	arb_sel     : 8;
+		mmr_t	atl_sel     : 11;
+		mmr_t	atr_sel     : 11;
+		mmr_t	dql_sel     : 6;
+		mmr_t	dqr_sel     : 6;
+		mmr_t	reserved_0  : 6;
+	} sh_y_mod_dbug_sel_s;
+} sh_y_mod_dbug_sel_u_t;
+#else
+typedef union sh_y_mod_dbug_sel_u {
+	mmr_t	sh_y_mod_dbug_sel_regval;
+	struct {
+		mmr_t	reserved_0  : 6;
+		mmr_t	dqr_sel     : 6;
+		mmr_t	dql_sel     : 6;
+		mmr_t	atr_sel     : 11;
+		mmr_t	atl_sel     : 11;
+		mmr_t	arb_sel     : 8;
+		mmr_t	wbq_sel     : 8;
+		mmr_t	tag_sel     : 8;
+	} sh_y_mod_dbug_sel_s;
+} sh_y_mod_dbug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_Y_DBUG_SEL"                       */
+/*                         MD acy debug select                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_dbug_sel_u {
+	mmr_t	sh_y_dbug_sel_regval;
+	struct {
+		mmr_t	dbg_sel     : 24;
+		mmr_t	reserved_0  : 40;
+	} sh_y_dbug_sel_s;
+} sh_y_dbug_sel_u_t;
+#else
+typedef union sh_y_dbug_sel_u {
+	mmr_t	sh_y_dbug_sel_regval;
+	struct {
+		mmr_t	reserved_0  : 40;
+		mmr_t	dbg_sel     : 24;
+	} sh_y_dbug_sel_s;
+} sh_y_dbug_sel_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_Y_LADDR_CMP"                       */
+/*                        MD acy address compare                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_laddr_cmp_u {
+	mmr_t	sh_y_laddr_cmp_regval;
+	struct {
+		mmr_t	cmp_val     : 28;
+		mmr_t	reserved_0  : 4;
+		mmr_t	mask_val    : 28;
+		mmr_t	reserved_1  : 4;
+	} sh_y_laddr_cmp_s;
+} sh_y_laddr_cmp_u_t;
+#else
+typedef union sh_y_laddr_cmp_u {
+	mmr_t	sh_y_laddr_cmp_regval;
+	struct {
+		mmr_t	reserved_1  : 4;
+		mmr_t	mask_val    : 28;
+		mmr_t	reserved_0  : 4;
+		mmr_t	cmp_val     : 28;
+	} sh_y_laddr_cmp_s;
+} sh_y_laddr_cmp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                      Register "SH_Y_RADDR_CMP"                       */
+/*                        MD acy address compare                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_raddr_cmp_u {
+	mmr_t	sh_y_raddr_cmp_regval;
+	struct {
+		mmr_t	cmp_val     : 28;
+		mmr_t	reserved_0  : 4;
+		mmr_t	mask_val    : 28;
+		mmr_t	reserved_1  : 4;
+	} sh_y_raddr_cmp_s;
+} sh_y_raddr_cmp_u_t;
+#else
+typedef union sh_y_raddr_cmp_u {
+	mmr_t	sh_y_raddr_cmp_regval;
+	struct {
+		mmr_t	reserved_1  : 4;
+		mmr_t	mask_val    : 28;
+		mmr_t	reserved_0  : 4;
+		mmr_t	cmp_val     : 28;
+	} sh_y_raddr_cmp_s;
+} sh_y_raddr_cmp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_Y_TAG_CMP"                        */
+/*                        MD acy tagmgr compare                         */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag_cmp_u {
+	mmr_t	sh_y_tag_cmp_regval;
+	struct {
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	src         : 14;
+		mmr_t	reserved_0  : 9;
+	} sh_y_tag_cmp_s;
+} sh_y_tag_cmp_u_t;
+#else
+typedef union sh_y_tag_cmp_u {
+	mmr_t	sh_y_tag_cmp_regval;
+	struct {
+		mmr_t	reserved_0  : 9;
+		mmr_t	src         : 14;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+	} sh_y_tag_cmp_s;
+} sh_y_tag_cmp_u_t;
+#endif
+
+/* ==================================================================== */
+/*                       Register "SH_Y_TAG_MASK"                       */
+/*                          MD acy tagmgr mask                          */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_y_tag_mask_u {
+	mmr_t	sh_y_tag_mask_regval;
+	struct {
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	src         : 14;
+		mmr_t	reserved_0  : 9;
+	} sh_y_tag_mask_s;
+} sh_y_tag_mask_u_t;
+#else
+typedef union sh_y_tag_mask_u {
+	mmr_t	sh_y_tag_mask_regval;
+	struct {
+		mmr_t	reserved_0  : 9;
+		mmr_t	src         : 14;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+	} sh_y_tag_mask_s;
+} sh_y_tag_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_JNR_DBUG_DATA_CFG"                  */
+/*              configuration for md jnr debug data muxes               */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_jnr_dbug_data_cfg_u {
+	mmr_t	sh_md_jnr_dbug_data_cfg_regval;
+	struct {
+		mmr_t	nibble0_sel : 3;
+		mmr_t	reserved_0  : 1;
+		mmr_t	nibble1_sel : 3;
+		mmr_t	reserved_1  : 1;
+		mmr_t	nibble2_sel : 3;
+		mmr_t	reserved_2  : 1;
+		mmr_t	nibble3_sel : 3;
+		mmr_t	reserved_3  : 1;
+		mmr_t	nibble4_sel : 3;
+		mmr_t	reserved_4  : 1;
+		mmr_t	nibble5_sel : 3;
+		mmr_t	reserved_5  : 1;
+		mmr_t	nibble6_sel : 3;
+		mmr_t	reserved_6  : 1;
+		mmr_t	nibble7_sel : 3;
+		mmr_t	reserved_7  : 33;
+	} sh_md_jnr_dbug_data_cfg_s;
+} sh_md_jnr_dbug_data_cfg_u_t;
+#else
+typedef union sh_md_jnr_dbug_data_cfg_u {
+	mmr_t	sh_md_jnr_dbug_data_cfg_regval;
+	struct {
+		mmr_t	reserved_7  : 33;
+		mmr_t	nibble7_sel : 3;
+		mmr_t	reserved_6  : 1;
+		mmr_t	nibble6_sel : 3;
+		mmr_t	reserved_5  : 1;
+		mmr_t	nibble5_sel : 3;
+		mmr_t	reserved_4  : 1;
+		mmr_t	nibble4_sel : 3;
+		mmr_t	reserved_3  : 1;
+		mmr_t	nibble3_sel : 3;
+		mmr_t	reserved_2  : 1;
+		mmr_t	nibble2_sel : 3;
+		mmr_t	reserved_1  : 1;
+		mmr_t	nibble1_sel : 3;
+		mmr_t	reserved_0  : 1;
+		mmr_t	nibble0_sel : 3;
+	} sh_md_jnr_dbug_data_cfg_s;
+} sh_md_jnr_dbug_data_cfg_u_t;
+#endif
+
+/* ==================================================================== */
+/*                     Register "SH_MD_LAST_CREDIT"                     */
+/*                 captures last credit values on reset                 */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_last_credit_u {
+	mmr_t	sh_md_last_credit_regval;
+	struct {
+		mmr_t	rq_to_pi    : 6;
+		mmr_t	reserved_0  : 2;
+		mmr_t	rp_to_pi    : 6;
+		mmr_t	reserved_1  : 2;
+		mmr_t	rq_to_xn    : 6;
+		mmr_t	reserved_2  : 2;
+		mmr_t	rp_to_xn    : 6;
+		mmr_t	reserved_3  : 2;
+		mmr_t	to_lb       : 6;
+		mmr_t	reserved_4  : 26;
+	} sh_md_last_credit_s;
+} sh_md_last_credit_u_t;
+#else
+typedef union sh_md_last_credit_u {
+	mmr_t	sh_md_last_credit_regval;
+	struct {
+		mmr_t	reserved_4  : 26;
+		mmr_t	to_lb       : 6;
+		mmr_t	reserved_3  : 2;
+		mmr_t	rp_to_xn    : 6;
+		mmr_t	reserved_2  : 2;
+		mmr_t	rq_to_xn    : 6;
+		mmr_t	reserved_1  : 2;
+		mmr_t	rp_to_pi    : 6;
+		mmr_t	reserved_0  : 2;
+		mmr_t	rq_to_pi    : 6;
+	} sh_md_last_credit_s;
+} sh_md_last_credit_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_MEM_CAPTURE_ADDR"                    */
+/*                   Address capture address register                   */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mem_capture_addr_u {
+	mmr_t	sh_mem_capture_addr_regval;
+	struct {
+		mmr_t	reserved_0  : 3;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+		mmr_t	reserved_1  : 20;
+	} sh_mem_capture_addr_s;
+} sh_mem_capture_addr_u_t;
+#else
+typedef union sh_mem_capture_addr_u {
+	mmr_t	sh_mem_capture_addr_regval;
+	struct {
+		mmr_t	reserved_1  : 20;
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	reserved_0  : 3;
+	} sh_mem_capture_addr_s;
+} sh_mem_capture_addr_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_MEM_CAPTURE_MASK"                    */
+/*                    Address capture mask register                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mem_capture_mask_u {
+	mmr_t	sh_mem_capture_mask_regval;
+	struct {
+		mmr_t	reserved_0    : 3;
+		mmr_t	addr          : 33;
+		mmr_t	cmd           : 8;
+		mmr_t	enable_local  : 1;
+		mmr_t	enable_remote : 1;
+		mmr_t	reserved_1    : 18;
+	} sh_mem_capture_mask_s;
+} sh_mem_capture_mask_u_t;
+#else
+typedef union sh_mem_capture_mask_u {
+	mmr_t	sh_mem_capture_mask_regval;
+	struct {
+		mmr_t	reserved_1    : 18;
+		mmr_t	enable_remote : 1;
+		mmr_t	enable_local  : 1;
+		mmr_t	cmd           : 8;
+		mmr_t	addr          : 33;
+		mmr_t	reserved_0    : 3;
+	} sh_mem_capture_mask_s;
+} sh_mem_capture_mask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                    Register "SH_MEM_CAPTURE_HDR"                     */
+/*                   Address capture header register                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_mem_capture_hdr_u {
+	mmr_t	sh_mem_capture_hdr_regval;
+	struct {
+		mmr_t	reserved_0  : 3;
+		mmr_t	addr        : 33;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+		mmr_t	cntr        : 6;
+	} sh_mem_capture_hdr_s;
+} sh_mem_capture_hdr_u_t;
+#else
+typedef union sh_mem_capture_hdr_u {
+	mmr_t	sh_mem_capture_hdr_regval;
+	struct {
+		mmr_t	cntr        : 6;
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	addr        : 33;
+		mmr_t	reserved_0  : 3;
+	} sh_mem_capture_hdr_s;
+} sh_mem_capture_hdr_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQLP_MMR_DIR_CONFIG"                 */
+/*                     DQ directory config register                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_config_u {
+	mmr_t	sh_md_dqlp_mmr_dir_config_regval;
+	struct {
+		mmr_t	sys_size    : 3;
+		mmr_t	en_direcc   : 1;
+		mmr_t	en_dirpois  : 1;
+		mmr_t	reserved_0  : 59;
+	} sh_md_dqlp_mmr_dir_config_s;
+} sh_md_dqlp_mmr_dir_config_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_config_u {
+	mmr_t	sh_md_dqlp_mmr_dir_config_regval;
+	struct {
+		mmr_t	reserved_0  : 59;
+		mmr_t	en_dirpois  : 1;
+		mmr_t	en_direcc   : 1;
+		mmr_t	sys_size    : 3;
+	} sh_md_dqlp_mmr_dir_config_s;
+} sh_md_dqlp_mmr_dir_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC0"                */
+/*                      node [63:0] presence bits                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_presvec0_u {
+	mmr_t	sh_md_dqlp_mmr_dir_presvec0_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_presvec0_s;
+} sh_md_dqlp_mmr_dir_presvec0_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_presvec0_u {
+	mmr_t	sh_md_dqlp_mmr_dir_presvec0_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_presvec0_s;
+} sh_md_dqlp_mmr_dir_presvec0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC1"                */
+/*                     node [127:64] presence bits                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_presvec1_u {
+	mmr_t	sh_md_dqlp_mmr_dir_presvec1_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_presvec1_s;
+} sh_md_dqlp_mmr_dir_presvec1_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_presvec1_u {
+	mmr_t	sh_md_dqlp_mmr_dir_presvec1_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_presvec1_s;
+} sh_md_dqlp_mmr_dir_presvec1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC2"                */
+/*                     node [191:128] presence bits                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_presvec2_u {
+	mmr_t	sh_md_dqlp_mmr_dir_presvec2_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_presvec2_s;
+} sh_md_dqlp_mmr_dir_presvec2_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_presvec2_u {
+	mmr_t	sh_md_dqlp_mmr_dir_presvec2_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_presvec2_s;
+} sh_md_dqlp_mmr_dir_presvec2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC3"                */
+/*                     node [255:192] presence bits                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_presvec3_u {
+	mmr_t	sh_md_dqlp_mmr_dir_presvec3_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_presvec3_s;
+} sh_md_dqlp_mmr_dir_presvec3_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_presvec3_u {
+	mmr_t	sh_md_dqlp_mmr_dir_presvec3_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_presvec3_s;
+} sh_md_dqlp_mmr_dir_presvec3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC0"                 */
+/*                        local vector for acc=0                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_locvec0_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec0_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec0_s;
+} sh_md_dqlp_mmr_dir_locvec0_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_locvec0_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec0_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec0_s;
+} sh_md_dqlp_mmr_dir_locvec0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC1"                 */
+/*                        local vector for acc=1                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_locvec1_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec1_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec1_s;
+} sh_md_dqlp_mmr_dir_locvec1_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_locvec1_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec1_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec1_s;
+} sh_md_dqlp_mmr_dir_locvec1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC2"                 */
+/*                        local vector for acc=2                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_locvec2_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec2_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec2_s;
+} sh_md_dqlp_mmr_dir_locvec2_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_locvec2_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec2_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec2_s;
+} sh_md_dqlp_mmr_dir_locvec2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC3"                 */
+/*                        local vector for acc=3                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_locvec3_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec3_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec3_s;
+} sh_md_dqlp_mmr_dir_locvec3_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_locvec3_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec3_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec3_s;
+} sh_md_dqlp_mmr_dir_locvec3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC4"                 */
+/*                        local vector for acc=4                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_locvec4_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec4_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec4_s;
+} sh_md_dqlp_mmr_dir_locvec4_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_locvec4_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec4_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec4_s;
+} sh_md_dqlp_mmr_dir_locvec4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC5"                 */
+/*                        local vector for acc=5                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_locvec5_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec5_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec5_s;
+} sh_md_dqlp_mmr_dir_locvec5_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_locvec5_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec5_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec5_s;
+} sh_md_dqlp_mmr_dir_locvec5_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC6"                 */
+/*                        local vector for acc=6                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_locvec6_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec6_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec6_s;
+} sh_md_dqlp_mmr_dir_locvec6_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_locvec6_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec6_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec6_s;
+} sh_md_dqlp_mmr_dir_locvec6_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC7"                 */
+/*                        local vector for acc=7                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_locvec7_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec7_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec7_s;
+} sh_md_dqlp_mmr_dir_locvec7_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_locvec7_u {
+	mmr_t	sh_md_dqlp_mmr_dir_locvec7_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqlp_mmr_dir_locvec7_s;
+} sh_md_dqlp_mmr_dir_locvec7_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC0"                 */
+/*                      privilege vector for acc=0                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_privec0_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec0_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqlp_mmr_dir_privec0_s;
+} sh_md_dqlp_mmr_dir_privec0_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_privec0_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec0_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqlp_mmr_dir_privec0_s;
+} sh_md_dqlp_mmr_dir_privec0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC1"                 */
+/*                      privilege vector for acc=1                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_privec1_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec1_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqlp_mmr_dir_privec1_s;
+} sh_md_dqlp_mmr_dir_privec1_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_privec1_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec1_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqlp_mmr_dir_privec1_s;
+} sh_md_dqlp_mmr_dir_privec1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC2"                 */
+/*                      privilege vector for acc=2                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_privec2_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec2_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqlp_mmr_dir_privec2_s;
+} sh_md_dqlp_mmr_dir_privec2_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_privec2_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec2_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqlp_mmr_dir_privec2_s;
+} sh_md_dqlp_mmr_dir_privec2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC3"                 */
+/*                      privilege vector for acc=3                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_privec3_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec3_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqlp_mmr_dir_privec3_s;
+} sh_md_dqlp_mmr_dir_privec3_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_privec3_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec3_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqlp_mmr_dir_privec3_s;
+} sh_md_dqlp_mmr_dir_privec3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC4"                 */
+/*                      privilege vector for acc=4                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_privec4_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec4_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqlp_mmr_dir_privec4_s;
+} sh_md_dqlp_mmr_dir_privec4_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_privec4_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec4_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqlp_mmr_dir_privec4_s;
+} sh_md_dqlp_mmr_dir_privec4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC5"                 */
+/*                      privilege vector for acc=5                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_privec5_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec5_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqlp_mmr_dir_privec5_s;
+} sh_md_dqlp_mmr_dir_privec5_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_privec5_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec5_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqlp_mmr_dir_privec5_s;
+} sh_md_dqlp_mmr_dir_privec5_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC6"                 */
+/*                      privilege vector for acc=6                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_privec6_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec6_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqlp_mmr_dir_privec6_s;
+} sh_md_dqlp_mmr_dir_privec6_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_privec6_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec6_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqlp_mmr_dir_privec6_s;
+} sh_md_dqlp_mmr_dir_privec6_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC7"                 */
+/*                      privilege vector for acc=7                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_privec7_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec7_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqlp_mmr_dir_privec7_s;
+} sh_md_dqlp_mmr_dir_privec7_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_privec7_u {
+	mmr_t	sh_md_dqlp_mmr_dir_privec7_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqlp_mmr_dir_privec7_s;
+} sh_md_dqlp_mmr_dir_privec7_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQLP_MMR_DIR_TIMER"                  */
+/*                            MD SXRO timer                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_timer_u {
+	mmr_t	sh_md_dqlp_mmr_dir_timer_regval;
+	struct {
+		mmr_t	timer_div   : 12;
+		mmr_t	timer_en    : 1;
+		mmr_t	timer_cur   : 9;
+		mmr_t	reserved_0  : 42;
+	} sh_md_dqlp_mmr_dir_timer_s;
+} sh_md_dqlp_mmr_dir_timer_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_timer_u {
+	mmr_t	sh_md_dqlp_mmr_dir_timer_regval;
+	struct {
+		mmr_t	reserved_0  : 42;
+		mmr_t	timer_cur   : 9;
+		mmr_t	timer_en    : 1;
+		mmr_t	timer_div   : 12;
+	} sh_md_dqlp_mmr_dir_timer_s;
+} sh_md_dqlp_mmr_dir_timer_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY"               */
+/*                       directory pio write data                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_piowd_dir_entry_u {
+	mmr_t	sh_md_dqlp_mmr_piowd_dir_entry_regval;
+	struct {
+		mmr_t	dira        : 26;
+		mmr_t	dirb        : 26;
+		mmr_t	pri         : 3;
+		mmr_t	acc         : 3;
+		mmr_t	reserved_0  : 6;
+	} sh_md_dqlp_mmr_piowd_dir_entry_s;
+} sh_md_dqlp_mmr_piowd_dir_entry_u_t;
+#else
+typedef union sh_md_dqlp_mmr_piowd_dir_entry_u {
+	mmr_t	sh_md_dqlp_mmr_piowd_dir_entry_regval;
+	struct {
+		mmr_t	reserved_0  : 6;
+		mmr_t	acc         : 3;
+		mmr_t	pri         : 3;
+		mmr_t	dirb        : 26;
+		mmr_t	dira        : 26;
+	} sh_md_dqlp_mmr_piowd_dir_entry_s;
+} sh_md_dqlp_mmr_piowd_dir_entry_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_MD_DQLP_MMR_PIOWD_DIR_ECC"                */
+/*                        directory ecc register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_piowd_dir_ecc_u {
+	mmr_t	sh_md_dqlp_mmr_piowd_dir_ecc_regval;
+	struct {
+		mmr_t	ecca        : 7;
+		mmr_t	eccb        : 7;
+		mmr_t	reserved_0  : 50;
+	} sh_md_dqlp_mmr_piowd_dir_ecc_s;
+} sh_md_dqlp_mmr_piowd_dir_ecc_u_t;
+#else
+typedef union sh_md_dqlp_mmr_piowd_dir_ecc_u {
+	mmr_t	sh_md_dqlp_mmr_piowd_dir_ecc_regval;
+	struct {
+		mmr_t	reserved_0  : 50;
+		mmr_t	eccb        : 7;
+		mmr_t	ecca        : 7;
+	} sh_md_dqlp_mmr_piowd_dir_ecc_s;
+} sh_md_dqlp_mmr_piowd_dir_ecc_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY"              */
+/*                      x directory pio read data                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xpiord_xdir_entry_u {
+	mmr_t	sh_md_dqlp_mmr_xpiord_xdir_entry_regval;
+	struct {
+		mmr_t	dira        : 26;
+		mmr_t	dirb        : 26;
+		mmr_t	pri         : 3;
+		mmr_t	acc         : 3;
+		mmr_t	cor         : 1;
+		mmr_t	unc         : 1;
+		mmr_t	reserved_0  : 4;
+	} sh_md_dqlp_mmr_xpiord_xdir_entry_s;
+} sh_md_dqlp_mmr_xpiord_xdir_entry_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xpiord_xdir_entry_u {
+	mmr_t	sh_md_dqlp_mmr_xpiord_xdir_entry_regval;
+	struct {
+		mmr_t	reserved_0  : 4;
+		mmr_t	unc         : 1;
+		mmr_t	cor         : 1;
+		mmr_t	acc         : 3;
+		mmr_t	pri         : 3;
+		mmr_t	dirb        : 26;
+		mmr_t	dira        : 26;
+	} sh_md_dqlp_mmr_xpiord_xdir_entry_s;
+} sh_md_dqlp_mmr_xpiord_xdir_entry_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQLP_MMR_XPIORD_XDIR_ECC"               */
+/*                           x directory ecc                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xpiord_xdir_ecc_u {
+	mmr_t	sh_md_dqlp_mmr_xpiord_xdir_ecc_regval;
+	struct {
+		mmr_t	ecca        : 7;
+		mmr_t	eccb        : 7;
+		mmr_t	reserved_0  : 50;
+	} sh_md_dqlp_mmr_xpiord_xdir_ecc_s;
+} sh_md_dqlp_mmr_xpiord_xdir_ecc_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xpiord_xdir_ecc_u {
+	mmr_t	sh_md_dqlp_mmr_xpiord_xdir_ecc_regval;
+	struct {
+		mmr_t	reserved_0  : 50;
+		mmr_t	eccb        : 7;
+		mmr_t	ecca        : 7;
+	} sh_md_dqlp_mmr_xpiord_xdir_ecc_s;
+} sh_md_dqlp_mmr_xpiord_xdir_ecc_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY"              */
+/*                      y directory pio read data                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_ypiord_ydir_entry_u {
+	mmr_t	sh_md_dqlp_mmr_ypiord_ydir_entry_regval;
+	struct {
+		mmr_t	dira        : 26;
+		mmr_t	dirb        : 26;
+		mmr_t	pri         : 3;
+		mmr_t	acc         : 3;
+		mmr_t	cor         : 1;
+		mmr_t	unc         : 1;
+		mmr_t	reserved_0  : 4;
+	} sh_md_dqlp_mmr_ypiord_ydir_entry_s;
+} sh_md_dqlp_mmr_ypiord_ydir_entry_u_t;
+#else
+typedef union sh_md_dqlp_mmr_ypiord_ydir_entry_u {
+	mmr_t	sh_md_dqlp_mmr_ypiord_ydir_entry_regval;
+	struct {
+		mmr_t	reserved_0  : 4;
+		mmr_t	unc         : 1;
+		mmr_t	cor         : 1;
+		mmr_t	acc         : 3;
+		mmr_t	pri         : 3;
+		mmr_t	dirb        : 26;
+		mmr_t	dira        : 26;
+	} sh_md_dqlp_mmr_ypiord_ydir_entry_s;
+} sh_md_dqlp_mmr_ypiord_ydir_entry_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQLP_MMR_YPIORD_YDIR_ECC"               */
+/*                           y directory ecc                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_ypiord_ydir_ecc_u {
+	mmr_t	sh_md_dqlp_mmr_ypiord_ydir_ecc_regval;
+	struct {
+		mmr_t	ecca        : 7;
+		mmr_t	eccb        : 7;
+		mmr_t	reserved_0  : 50;
+	} sh_md_dqlp_mmr_ypiord_ydir_ecc_s;
+} sh_md_dqlp_mmr_ypiord_ydir_ecc_u_t;
+#else
+typedef union sh_md_dqlp_mmr_ypiord_ydir_ecc_u {
+	mmr_t	sh_md_dqlp_mmr_ypiord_ydir_ecc_regval;
+	struct {
+		mmr_t	reserved_0  : 50;
+		mmr_t	eccb        : 7;
+		mmr_t	ecca        : 7;
+	} sh_md_dqlp_mmr_ypiord_ydir_ecc_s;
+} sh_md_dqlp_mmr_ypiord_ydir_ecc_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XCERR1"                   */
+/*              correctable dir ecc group 1 error register              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xcerr1_u {
+	mmr_t	sh_md_dqlp_mmr_xcerr1_regval;
+	struct {
+		mmr_t	grp1        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 25;
+	} sh_md_dqlp_mmr_xcerr1_s;
+} sh_md_dqlp_mmr_xcerr1_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xcerr1_u {
+	mmr_t	sh_md_dqlp_mmr_xcerr1_regval;
+	struct {
+		mmr_t	reserved_0  : 25;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp1        : 36;
+	} sh_md_dqlp_mmr_xcerr1_s;
+} sh_md_dqlp_mmr_xcerr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XCERR2"                   */
+/*              correctable dir ecc group 2 error register              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xcerr2_u {
+	mmr_t	sh_md_dqlp_mmr_xcerr2_regval;
+	struct {
+		mmr_t	grp2        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 26;
+	} sh_md_dqlp_mmr_xcerr2_s;
+} sh_md_dqlp_mmr_xcerr2_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xcerr2_u {
+	mmr_t	sh_md_dqlp_mmr_xcerr2_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp2        : 36;
+	} sh_md_dqlp_mmr_xcerr2_s;
+} sh_md_dqlp_mmr_xcerr2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XUERR1"                   */
+/*             uncorrectable dir ecc group 1 error register             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xuerr1_u {
+	mmr_t	sh_md_dqlp_mmr_xuerr1_regval;
+	struct {
+		mmr_t	grp1        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 25;
+	} sh_md_dqlp_mmr_xuerr1_s;
+} sh_md_dqlp_mmr_xuerr1_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xuerr1_u {
+	mmr_t	sh_md_dqlp_mmr_xuerr1_regval;
+	struct {
+		mmr_t	reserved_0  : 25;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp1        : 36;
+	} sh_md_dqlp_mmr_xuerr1_s;
+} sh_md_dqlp_mmr_xuerr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XUERR2"                   */
+/*             uncorrectable dir ecc group 2 error register             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xuerr2_u {
+	mmr_t	sh_md_dqlp_mmr_xuerr2_regval;
+	struct {
+		mmr_t	grp2        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 26;
+	} sh_md_dqlp_mmr_xuerr2_s;
+} sh_md_dqlp_mmr_xuerr2_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xuerr2_u {
+	mmr_t	sh_md_dqlp_mmr_xuerr2_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp2        : 36;
+	} sh_md_dqlp_mmr_xuerr2_s;
+} sh_md_dqlp_mmr_xuerr2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_XPERR"                    */
+/*                       protocol error register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xperr_u {
+	mmr_t	sh_md_dqlp_mmr_xperr_regval;
+	struct {
+		mmr_t	dir         : 26;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+		mmr_t	prige       : 1;
+		mmr_t	priv        : 1;
+		mmr_t	cor         : 1;
+		mmr_t	unc         : 1;
+		mmr_t	mybit       : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 1;
+	} sh_md_dqlp_mmr_xperr_s;
+} sh_md_dqlp_mmr_xperr_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xperr_u {
+	mmr_t	sh_md_dqlp_mmr_xperr_regval;
+	struct {
+		mmr_t	reserved_0  : 1;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	mybit       : 8;
+		mmr_t	unc         : 1;
+		mmr_t	cor         : 1;
+		mmr_t	priv        : 1;
+		mmr_t	prige       : 1;
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	dir         : 26;
+	} sh_md_dqlp_mmr_xperr_s;
+} sh_md_dqlp_mmr_xperr_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YCERR1"                   */
+/*              correctable dir ecc group 1 error register              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_ycerr1_u {
+	mmr_t	sh_md_dqlp_mmr_ycerr1_regval;
+	struct {
+		mmr_t	grp1        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 25;
+	} sh_md_dqlp_mmr_ycerr1_s;
+} sh_md_dqlp_mmr_ycerr1_u_t;
+#else
+typedef union sh_md_dqlp_mmr_ycerr1_u {
+	mmr_t	sh_md_dqlp_mmr_ycerr1_regval;
+	struct {
+		mmr_t	reserved_0  : 25;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp1        : 36;
+	} sh_md_dqlp_mmr_ycerr1_s;
+} sh_md_dqlp_mmr_ycerr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YCERR2"                   */
+/*              correctable dir ecc group 2 error register              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_ycerr2_u {
+	mmr_t	sh_md_dqlp_mmr_ycerr2_regval;
+	struct {
+		mmr_t	grp2        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 26;
+	} sh_md_dqlp_mmr_ycerr2_s;
+} sh_md_dqlp_mmr_ycerr2_u_t;
+#else
+typedef union sh_md_dqlp_mmr_ycerr2_u {
+	mmr_t	sh_md_dqlp_mmr_ycerr2_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp2        : 36;
+	} sh_md_dqlp_mmr_ycerr2_s;
+} sh_md_dqlp_mmr_ycerr2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YUERR1"                   */
+/*             uncorrectable dir ecc group 1 error register             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_yuerr1_u {
+	mmr_t	sh_md_dqlp_mmr_yuerr1_regval;
+	struct {
+		mmr_t	grp1        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 25;
+	} sh_md_dqlp_mmr_yuerr1_s;
+} sh_md_dqlp_mmr_yuerr1_u_t;
+#else
+typedef union sh_md_dqlp_mmr_yuerr1_u {
+	mmr_t	sh_md_dqlp_mmr_yuerr1_regval;
+	struct {
+		mmr_t	reserved_0  : 25;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp1        : 36;
+	} sh_md_dqlp_mmr_yuerr1_s;
+} sh_md_dqlp_mmr_yuerr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YUERR2"                   */
+/*             uncorrectable dir ecc group 2 error register             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_yuerr2_u {
+	mmr_t	sh_md_dqlp_mmr_yuerr2_regval;
+	struct {
+		mmr_t	grp2        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 26;
+	} sh_md_dqlp_mmr_yuerr2_s;
+} sh_md_dqlp_mmr_yuerr2_u_t;
+#else
+typedef union sh_md_dqlp_mmr_yuerr2_u {
+	mmr_t	sh_md_dqlp_mmr_yuerr2_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp2        : 36;
+	} sh_md_dqlp_mmr_yuerr2_s;
+} sh_md_dqlp_mmr_yuerr2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQLP_MMR_YPERR"                    */
+/*                       protocol error register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_yperr_u {
+	mmr_t	sh_md_dqlp_mmr_yperr_regval;
+	struct {
+		mmr_t	dir         : 26;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+		mmr_t	prige       : 1;
+		mmr_t	priv        : 1;
+		mmr_t	cor         : 1;
+		mmr_t	unc         : 1;
+		mmr_t	mybit       : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 1;
+	} sh_md_dqlp_mmr_yperr_s;
+} sh_md_dqlp_mmr_yperr_u_t;
+#else
+typedef union sh_md_dqlp_mmr_yperr_u {
+	mmr_t	sh_md_dqlp_mmr_yperr_regval;
+	struct {
+		mmr_t	reserved_0  : 1;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	mybit       : 8;
+		mmr_t	unc         : 1;
+		mmr_t	cor         : 1;
+		mmr_t	priv        : 1;
+		mmr_t	prige       : 1;
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	dir         : 26;
+	} sh_md_dqlp_mmr_yperr_s;
+} sh_md_dqlp_mmr_yperr_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_CMDTRIG"                 */
+/*                             cmd triggers                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_cmdtrig_u {
+	mmr_t	sh_md_dqlp_mmr_dir_cmdtrig_regval;
+	struct {
+		mmr_t	cmd0        : 8;
+		mmr_t	cmd1        : 8;
+		mmr_t	cmd2        : 8;
+		mmr_t	cmd3        : 8;
+		mmr_t	reserved_0  : 32;
+	} sh_md_dqlp_mmr_dir_cmdtrig_s;
+} sh_md_dqlp_mmr_dir_cmdtrig_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_cmdtrig_u {
+	mmr_t	sh_md_dqlp_mmr_dir_cmdtrig_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	cmd3        : 8;
+		mmr_t	cmd2        : 8;
+		mmr_t	cmd1        : 8;
+		mmr_t	cmd0        : 8;
+	} sh_md_dqlp_mmr_dir_cmdtrig_s;
+} sh_md_dqlp_mmr_dir_cmdtrig_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_TBLTRIG"                 */
+/*                          dir table trigger                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_tbltrig_u {
+	mmr_t	sh_md_dqlp_mmr_dir_tbltrig_regval;
+	struct {
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	acc         : 2;
+		mmr_t	prige       : 1;
+		mmr_t	dirst       : 9;
+		mmr_t	mybit       : 8;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqlp_mmr_dir_tbltrig_s;
+} sh_md_dqlp_mmr_dir_tbltrig_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_tbltrig_u {
+	mmr_t	sh_md_dqlp_mmr_dir_tbltrig_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	mybit       : 8;
+		mmr_t	dirst       : 9;
+		mmr_t	prige       : 1;
+		mmr_t	acc         : 2;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+	} sh_md_dqlp_mmr_dir_tbltrig_s;
+} sh_md_dqlp_mmr_dir_tbltrig_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_TBLMASK"                 */
+/*                        dir table trigger mask                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_dir_tblmask_u {
+	mmr_t	sh_md_dqlp_mmr_dir_tblmask_regval;
+	struct {
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	acc         : 2;
+		mmr_t	prige       : 1;
+		mmr_t	dirst       : 9;
+		mmr_t	mybit       : 8;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqlp_mmr_dir_tblmask_s;
+} sh_md_dqlp_mmr_dir_tblmask_u_t;
+#else
+typedef union sh_md_dqlp_mmr_dir_tblmask_u {
+	mmr_t	sh_md_dqlp_mmr_dir_tblmask_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	mybit       : 8;
+		mmr_t	dirst       : 9;
+		mmr_t	prige       : 1;
+		mmr_t	acc         : 2;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+	} sh_md_dqlp_mmr_dir_tblmask_s;
+} sh_md_dqlp_mmr_dir_tblmask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLP_MMR_XBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xbist_h_u {
+	mmr_t	sh_md_dqlp_mmr_xbist_h_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_1  : 21;
+	} sh_md_dqlp_mmr_xbist_h_s;
+} sh_md_dqlp_mmr_xbist_h_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xbist_h_u {
+	mmr_t	sh_md_dqlp_mmr_xbist_h_regval;
+	struct {
+		mmr_t	reserved_1  : 21;
+		mmr_t	arm         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqlp_mmr_xbist_h_s;
+} sh_md_dqlp_mmr_xbist_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLP_MMR_XBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xbist_l_u {
+	mmr_t	sh_md_dqlp_mmr_xbist_l_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqlp_mmr_xbist_l_s;
+} sh_md_dqlp_mmr_xbist_l_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xbist_l_u {
+	mmr_t	sh_md_dqlp_mmr_xbist_l_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqlp_mmr_xbist_l_s;
+} sh_md_dqlp_mmr_xbist_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_XBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xbist_err_h_u {
+	mmr_t	sh_md_dqlp_mmr_xbist_err_h_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqlp_mmr_xbist_err_h_s;
+} sh_md_dqlp_mmr_xbist_err_h_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xbist_err_h_u {
+	mmr_t	sh_md_dqlp_mmr_xbist_err_h_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqlp_mmr_xbist_err_h_s;
+} sh_md_dqlp_mmr_xbist_err_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_XBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_xbist_err_l_u {
+	mmr_t	sh_md_dqlp_mmr_xbist_err_l_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqlp_mmr_xbist_err_l_s;
+} sh_md_dqlp_mmr_xbist_err_l_u_t;
+#else
+typedef union sh_md_dqlp_mmr_xbist_err_l_u {
+	mmr_t	sh_md_dqlp_mmr_xbist_err_l_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqlp_mmr_xbist_err_l_s;
+} sh_md_dqlp_mmr_xbist_err_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLP_MMR_YBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_ybist_h_u {
+	mmr_t	sh_md_dqlp_mmr_ybist_h_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_1  : 21;
+	} sh_md_dqlp_mmr_ybist_h_s;
+} sh_md_dqlp_mmr_ybist_h_u_t;
+#else
+typedef union sh_md_dqlp_mmr_ybist_h_u {
+	mmr_t	sh_md_dqlp_mmr_ybist_h_regval;
+	struct {
+		mmr_t	reserved_1  : 21;
+		mmr_t	arm         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqlp_mmr_ybist_h_s;
+} sh_md_dqlp_mmr_ybist_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLP_MMR_YBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_ybist_l_u {
+	mmr_t	sh_md_dqlp_mmr_ybist_l_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqlp_mmr_ybist_l_s;
+} sh_md_dqlp_mmr_ybist_l_u_t;
+#else
+typedef union sh_md_dqlp_mmr_ybist_l_u {
+	mmr_t	sh_md_dqlp_mmr_ybist_l_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqlp_mmr_ybist_l_s;
+} sh_md_dqlp_mmr_ybist_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_YBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_ybist_err_h_u {
+	mmr_t	sh_md_dqlp_mmr_ybist_err_h_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqlp_mmr_ybist_err_h_s;
+} sh_md_dqlp_mmr_ybist_err_h_u_t;
+#else
+typedef union sh_md_dqlp_mmr_ybist_err_h_u {
+	mmr_t	sh_md_dqlp_mmr_ybist_err_h_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqlp_mmr_ybist_err_h_s;
+} sh_md_dqlp_mmr_ybist_err_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_YBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqlp_mmr_ybist_err_l_u {
+	mmr_t	sh_md_dqlp_mmr_ybist_err_l_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqlp_mmr_ybist_err_l_s;
+} sh_md_dqlp_mmr_ybist_err_l_u_t;
+#else
+typedef union sh_md_dqlp_mmr_ybist_err_l_u {
+	mmr_t	sh_md_dqlp_mmr_ybist_err_l_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqlp_mmr_ybist_err_l_s;
+} sh_md_dqlp_mmr_ybist_err_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLS_MMR_XBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_xbist_h_u {
+	mmr_t	sh_md_dqls_mmr_xbist_h_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 21;
+	} sh_md_dqls_mmr_xbist_h_s;
+} sh_md_dqls_mmr_xbist_h_u_t;
+#else
+typedef union sh_md_dqls_mmr_xbist_h_u {
+	mmr_t	sh_md_dqls_mmr_xbist_h_regval;
+	struct {
+		mmr_t	reserved_0  : 21;
+		mmr_t	arm         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqls_mmr_xbist_h_s;
+} sh_md_dqls_mmr_xbist_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLS_MMR_XBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_xbist_l_u {
+	mmr_t	sh_md_dqls_mmr_xbist_l_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqls_mmr_xbist_l_s;
+} sh_md_dqls_mmr_xbist_l_u_t;
+#else
+typedef union sh_md_dqls_mmr_xbist_l_u {
+	mmr_t	sh_md_dqls_mmr_xbist_l_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqls_mmr_xbist_l_s;
+} sh_md_dqls_mmr_xbist_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLS_MMR_XBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_xbist_err_h_u {
+	mmr_t	sh_md_dqls_mmr_xbist_err_h_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqls_mmr_xbist_err_h_s;
+} sh_md_dqls_mmr_xbist_err_h_u_t;
+#else
+typedef union sh_md_dqls_mmr_xbist_err_h_u {
+	mmr_t	sh_md_dqls_mmr_xbist_err_h_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqls_mmr_xbist_err_h_s;
+} sh_md_dqls_mmr_xbist_err_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLS_MMR_XBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_xbist_err_l_u {
+	mmr_t	sh_md_dqls_mmr_xbist_err_l_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqls_mmr_xbist_err_l_s;
+} sh_md_dqls_mmr_xbist_err_l_u_t;
+#else
+typedef union sh_md_dqls_mmr_xbist_err_l_u {
+	mmr_t	sh_md_dqls_mmr_xbist_err_l_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqls_mmr_xbist_err_l_s;
+} sh_md_dqls_mmr_xbist_err_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLS_MMR_YBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_ybist_h_u {
+	mmr_t	sh_md_dqls_mmr_ybist_h_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 21;
+	} sh_md_dqls_mmr_ybist_h_s;
+} sh_md_dqls_mmr_ybist_h_u_t;
+#else
+typedef union sh_md_dqls_mmr_ybist_h_u {
+	mmr_t	sh_md_dqls_mmr_ybist_h_regval;
+	struct {
+		mmr_t	reserved_0  : 21;
+		mmr_t	arm         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqls_mmr_ybist_h_s;
+} sh_md_dqls_mmr_ybist_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQLS_MMR_YBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_ybist_l_u {
+	mmr_t	sh_md_dqls_mmr_ybist_l_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqls_mmr_ybist_l_s;
+} sh_md_dqls_mmr_ybist_l_u_t;
+#else
+typedef union sh_md_dqls_mmr_ybist_l_u {
+	mmr_t	sh_md_dqls_mmr_ybist_l_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqls_mmr_ybist_l_s;
+} sh_md_dqls_mmr_ybist_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLS_MMR_YBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_ybist_err_h_u {
+	mmr_t	sh_md_dqls_mmr_ybist_err_h_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqls_mmr_ybist_err_h_s;
+} sh_md_dqls_mmr_ybist_err_h_u_t;
+#else
+typedef union sh_md_dqls_mmr_ybist_err_h_u {
+	mmr_t	sh_md_dqls_mmr_ybist_err_h_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqls_mmr_ybist_err_h_s;
+} sh_md_dqls_mmr_ybist_err_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQLS_MMR_YBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_ybist_err_l_u {
+	mmr_t	sh_md_dqls_mmr_ybist_err_l_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqls_mmr_ybist_err_l_s;
+} sh_md_dqls_mmr_ybist_err_l_u_t;
+#else
+typedef union sh_md_dqls_mmr_ybist_err_l_u {
+	mmr_t	sh_md_dqls_mmr_ybist_err_l_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqls_mmr_ybist_err_l_s;
+} sh_md_dqls_mmr_ybist_err_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQLS_MMR_JNR_DEBUG"                  */
+/*                    joiner/fct debug configuration                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_jnr_debug_u {
+	mmr_t	sh_md_dqls_mmr_jnr_debug_regval;
+	struct {
+		mmr_t	px          : 1;
+		mmr_t	rw          : 1;
+		mmr_t	reserved_0  : 62;
+	} sh_md_dqls_mmr_jnr_debug_s;
+} sh_md_dqls_mmr_jnr_debug_u_t;
+#else
+typedef union sh_md_dqls_mmr_jnr_debug_u {
+	mmr_t	sh_md_dqls_mmr_jnr_debug_regval;
+	struct {
+		mmr_t	reserved_0  : 62;
+		mmr_t	rw          : 1;
+		mmr_t	px          : 1;
+	} sh_md_dqls_mmr_jnr_debug_s;
+} sh_md_dqls_mmr_jnr_debug_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQLS_MMR_XAMOPW_ERR"                 */
+/*                  amo/partial rmw ecc error register                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqls_mmr_xamopw_err_u {
+	mmr_t	sh_md_dqls_mmr_xamopw_err_regval;
+	struct {
+		mmr_t	ssyn        : 8;
+		mmr_t	scor        : 1;
+		mmr_t	sunc        : 1;
+		mmr_t	reserved_0  : 6;
+		mmr_t	rsyn        : 8;
+		mmr_t	rcor        : 1;
+		mmr_t	runc        : 1;
+		mmr_t	reserved_1  : 6;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_2  : 31;
+	} sh_md_dqls_mmr_xamopw_err_s;
+} sh_md_dqls_mmr_xamopw_err_u_t;
+#else
+typedef union sh_md_dqls_mmr_xamopw_err_u {
+	mmr_t	sh_md_dqls_mmr_xamopw_err_regval;
+	struct {
+		mmr_t	reserved_2  : 31;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_1  : 6;
+		mmr_t	runc        : 1;
+		mmr_t	rcor        : 1;
+		mmr_t	rsyn        : 8;
+		mmr_t	reserved_0  : 6;
+		mmr_t	sunc        : 1;
+		mmr_t	scor        : 1;
+		mmr_t	ssyn        : 8;
+	} sh_md_dqls_mmr_xamopw_err_s;
+} sh_md_dqls_mmr_xamopw_err_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQRP_MMR_DIR_CONFIG"                 */
+/*                     DQ directory config register                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_config_u {
+	mmr_t	sh_md_dqrp_mmr_dir_config_regval;
+	struct {
+		mmr_t	sys_size    : 3;
+		mmr_t	en_direcc   : 1;
+		mmr_t	en_dirpois  : 1;
+		mmr_t	reserved_0  : 59;
+	} sh_md_dqrp_mmr_dir_config_s;
+} sh_md_dqrp_mmr_dir_config_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_config_u {
+	mmr_t	sh_md_dqrp_mmr_dir_config_regval;
+	struct {
+		mmr_t	reserved_0  : 59;
+		mmr_t	en_dirpois  : 1;
+		mmr_t	en_direcc   : 1;
+		mmr_t	sys_size    : 3;
+	} sh_md_dqrp_mmr_dir_config_s;
+} sh_md_dqrp_mmr_dir_config_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC0"                */
+/*                      node [63:0] presence bits                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_presvec0_u {
+	mmr_t	sh_md_dqrp_mmr_dir_presvec0_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_presvec0_s;
+} sh_md_dqrp_mmr_dir_presvec0_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_presvec0_u {
+	mmr_t	sh_md_dqrp_mmr_dir_presvec0_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_presvec0_s;
+} sh_md_dqrp_mmr_dir_presvec0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC1"                */
+/*                     node [127:64] presence bits                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_presvec1_u {
+	mmr_t	sh_md_dqrp_mmr_dir_presvec1_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_presvec1_s;
+} sh_md_dqrp_mmr_dir_presvec1_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_presvec1_u {
+	mmr_t	sh_md_dqrp_mmr_dir_presvec1_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_presvec1_s;
+} sh_md_dqrp_mmr_dir_presvec1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC2"                */
+/*                     node [191:128] presence bits                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_presvec2_u {
+	mmr_t	sh_md_dqrp_mmr_dir_presvec2_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_presvec2_s;
+} sh_md_dqrp_mmr_dir_presvec2_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_presvec2_u {
+	mmr_t	sh_md_dqrp_mmr_dir_presvec2_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_presvec2_s;
+} sh_md_dqrp_mmr_dir_presvec2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC3"                */
+/*                     node [255:192] presence bits                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_presvec3_u {
+	mmr_t	sh_md_dqrp_mmr_dir_presvec3_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_presvec3_s;
+} sh_md_dqrp_mmr_dir_presvec3_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_presvec3_u {
+	mmr_t	sh_md_dqrp_mmr_dir_presvec3_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_presvec3_s;
+} sh_md_dqrp_mmr_dir_presvec3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC0"                 */
+/*                        local vector for acc=0                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_locvec0_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec0_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec0_s;
+} sh_md_dqrp_mmr_dir_locvec0_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_locvec0_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec0_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec0_s;
+} sh_md_dqrp_mmr_dir_locvec0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC1"                 */
+/*                        local vector for acc=1                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_locvec1_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec1_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec1_s;
+} sh_md_dqrp_mmr_dir_locvec1_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_locvec1_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec1_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec1_s;
+} sh_md_dqrp_mmr_dir_locvec1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC2"                 */
+/*                        local vector for acc=2                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_locvec2_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec2_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec2_s;
+} sh_md_dqrp_mmr_dir_locvec2_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_locvec2_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec2_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec2_s;
+} sh_md_dqrp_mmr_dir_locvec2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC3"                 */
+/*                        local vector for acc=3                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_locvec3_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec3_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec3_s;
+} sh_md_dqrp_mmr_dir_locvec3_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_locvec3_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec3_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec3_s;
+} sh_md_dqrp_mmr_dir_locvec3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC4"                 */
+/*                        local vector for acc=4                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_locvec4_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec4_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec4_s;
+} sh_md_dqrp_mmr_dir_locvec4_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_locvec4_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec4_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec4_s;
+} sh_md_dqrp_mmr_dir_locvec4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC5"                 */
+/*                        local vector for acc=5                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_locvec5_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec5_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec5_s;
+} sh_md_dqrp_mmr_dir_locvec5_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_locvec5_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec5_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec5_s;
+} sh_md_dqrp_mmr_dir_locvec5_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC6"                 */
+/*                        local vector for acc=6                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_locvec6_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec6_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec6_s;
+} sh_md_dqrp_mmr_dir_locvec6_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_locvec6_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec6_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec6_s;
+} sh_md_dqrp_mmr_dir_locvec6_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC7"                 */
+/*                        local vector for acc=7                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_locvec7_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec7_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec7_s;
+} sh_md_dqrp_mmr_dir_locvec7_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_locvec7_u {
+	mmr_t	sh_md_dqrp_mmr_dir_locvec7_regval;
+	struct {
+		mmr_t	vec         : 64;
+	} sh_md_dqrp_mmr_dir_locvec7_s;
+} sh_md_dqrp_mmr_dir_locvec7_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC0"                 */
+/*                      privilege vector for acc=0                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_privec0_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec0_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqrp_mmr_dir_privec0_s;
+} sh_md_dqrp_mmr_dir_privec0_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_privec0_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec0_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqrp_mmr_dir_privec0_s;
+} sh_md_dqrp_mmr_dir_privec0_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC1"                 */
+/*                      privilege vector for acc=1                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_privec1_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec1_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqrp_mmr_dir_privec1_s;
+} sh_md_dqrp_mmr_dir_privec1_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_privec1_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec1_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqrp_mmr_dir_privec1_s;
+} sh_md_dqrp_mmr_dir_privec1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC2"                 */
+/*                      privilege vector for acc=2                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_privec2_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec2_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqrp_mmr_dir_privec2_s;
+} sh_md_dqrp_mmr_dir_privec2_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_privec2_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec2_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqrp_mmr_dir_privec2_s;
+} sh_md_dqrp_mmr_dir_privec2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC3"                 */
+/*                      privilege vector for acc=3                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_privec3_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec3_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqrp_mmr_dir_privec3_s;
+} sh_md_dqrp_mmr_dir_privec3_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_privec3_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec3_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqrp_mmr_dir_privec3_s;
+} sh_md_dqrp_mmr_dir_privec3_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC4"                 */
+/*                      privilege vector for acc=4                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_privec4_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec4_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqrp_mmr_dir_privec4_s;
+} sh_md_dqrp_mmr_dir_privec4_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_privec4_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec4_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqrp_mmr_dir_privec4_s;
+} sh_md_dqrp_mmr_dir_privec4_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC5"                 */
+/*                      privilege vector for acc=5                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_privec5_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec5_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqrp_mmr_dir_privec5_s;
+} sh_md_dqrp_mmr_dir_privec5_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_privec5_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec5_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqrp_mmr_dir_privec5_s;
+} sh_md_dqrp_mmr_dir_privec5_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC6"                 */
+/*                      privilege vector for acc=6                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_privec6_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec6_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqrp_mmr_dir_privec6_s;
+} sh_md_dqrp_mmr_dir_privec6_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_privec6_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec6_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqrp_mmr_dir_privec6_s;
+} sh_md_dqrp_mmr_dir_privec6_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC7"                 */
+/*                      privilege vector for acc=7                      */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_privec7_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec7_regval;
+	struct {
+		mmr_t	in          : 14;
+		mmr_t	out         : 14;
+		mmr_t	reserved_0  : 36;
+	} sh_md_dqrp_mmr_dir_privec7_s;
+} sh_md_dqrp_mmr_dir_privec7_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_privec7_u {
+	mmr_t	sh_md_dqrp_mmr_dir_privec7_regval;
+	struct {
+		mmr_t	reserved_0  : 36;
+		mmr_t	out         : 14;
+		mmr_t	in          : 14;
+	} sh_md_dqrp_mmr_dir_privec7_s;
+} sh_md_dqrp_mmr_dir_privec7_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQRP_MMR_DIR_TIMER"                  */
+/*                            MD SXRO timer                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_timer_u {
+	mmr_t	sh_md_dqrp_mmr_dir_timer_regval;
+	struct {
+		mmr_t	timer_div   : 12;
+		mmr_t	timer_en    : 1;
+		mmr_t	timer_cur   : 9;
+		mmr_t	reserved_0  : 42;
+	} sh_md_dqrp_mmr_dir_timer_s;
+} sh_md_dqrp_mmr_dir_timer_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_timer_u {
+	mmr_t	sh_md_dqrp_mmr_dir_timer_regval;
+	struct {
+		mmr_t	reserved_0  : 42;
+		mmr_t	timer_cur   : 9;
+		mmr_t	timer_en    : 1;
+		mmr_t	timer_div   : 12;
+	} sh_md_dqrp_mmr_dir_timer_s;
+} sh_md_dqrp_mmr_dir_timer_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY"               */
+/*                       directory pio write data                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_piowd_dir_entry_u {
+	mmr_t	sh_md_dqrp_mmr_piowd_dir_entry_regval;
+	struct {
+		mmr_t	dira        : 26;
+		mmr_t	dirb        : 26;
+		mmr_t	pri         : 3;
+		mmr_t	acc         : 3;
+		mmr_t	reserved_0  : 6;
+	} sh_md_dqrp_mmr_piowd_dir_entry_s;
+} sh_md_dqrp_mmr_piowd_dir_entry_u_t;
+#else
+typedef union sh_md_dqrp_mmr_piowd_dir_entry_u {
+	mmr_t	sh_md_dqrp_mmr_piowd_dir_entry_regval;
+	struct {
+		mmr_t	reserved_0  : 6;
+		mmr_t	acc         : 3;
+		mmr_t	pri         : 3;
+		mmr_t	dirb        : 26;
+		mmr_t	dira        : 26;
+	} sh_md_dqrp_mmr_piowd_dir_entry_s;
+} sh_md_dqrp_mmr_piowd_dir_entry_u_t;
+#endif
+
+/* ==================================================================== */
+/*               Register "SH_MD_DQRP_MMR_PIOWD_DIR_ECC"                */
+/*                        directory ecc register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_piowd_dir_ecc_u {
+	mmr_t	sh_md_dqrp_mmr_piowd_dir_ecc_regval;
+	struct {
+		mmr_t	ecca        : 7;
+		mmr_t	eccb        : 7;
+		mmr_t	reserved_0  : 50;
+	} sh_md_dqrp_mmr_piowd_dir_ecc_s;
+} sh_md_dqrp_mmr_piowd_dir_ecc_u_t;
+#else
+typedef union sh_md_dqrp_mmr_piowd_dir_ecc_u {
+	mmr_t	sh_md_dqrp_mmr_piowd_dir_ecc_regval;
+	struct {
+		mmr_t	reserved_0  : 50;
+		mmr_t	eccb        : 7;
+		mmr_t	ecca        : 7;
+	} sh_md_dqrp_mmr_piowd_dir_ecc_s;
+} sh_md_dqrp_mmr_piowd_dir_ecc_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY"              */
+/*                      x directory pio read data                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xpiord_xdir_entry_u {
+	mmr_t	sh_md_dqrp_mmr_xpiord_xdir_entry_regval;
+	struct {
+		mmr_t	dira        : 26;
+		mmr_t	dirb        : 26;
+		mmr_t	pri         : 3;
+		mmr_t	acc         : 3;
+		mmr_t	cor         : 1;
+		mmr_t	unc         : 1;
+		mmr_t	reserved_0  : 4;
+	} sh_md_dqrp_mmr_xpiord_xdir_entry_s;
+} sh_md_dqrp_mmr_xpiord_xdir_entry_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xpiord_xdir_entry_u {
+	mmr_t	sh_md_dqrp_mmr_xpiord_xdir_entry_regval;
+	struct {
+		mmr_t	reserved_0  : 4;
+		mmr_t	unc         : 1;
+		mmr_t	cor         : 1;
+		mmr_t	acc         : 3;
+		mmr_t	pri         : 3;
+		mmr_t	dirb        : 26;
+		mmr_t	dira        : 26;
+	} sh_md_dqrp_mmr_xpiord_xdir_entry_s;
+} sh_md_dqrp_mmr_xpiord_xdir_entry_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQRP_MMR_XPIORD_XDIR_ECC"               */
+/*                           x directory ecc                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xpiord_xdir_ecc_u {
+	mmr_t	sh_md_dqrp_mmr_xpiord_xdir_ecc_regval;
+	struct {
+		mmr_t	ecca        : 7;
+		mmr_t	eccb        : 7;
+		mmr_t	reserved_0  : 50;
+	} sh_md_dqrp_mmr_xpiord_xdir_ecc_s;
+} sh_md_dqrp_mmr_xpiord_xdir_ecc_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xpiord_xdir_ecc_u {
+	mmr_t	sh_md_dqrp_mmr_xpiord_xdir_ecc_regval;
+	struct {
+		mmr_t	reserved_0  : 50;
+		mmr_t	eccb        : 7;
+		mmr_t	ecca        : 7;
+	} sh_md_dqrp_mmr_xpiord_xdir_ecc_s;
+} sh_md_dqrp_mmr_xpiord_xdir_ecc_u_t;
+#endif
+
+/* ==================================================================== */
+/*             Register "SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY"              */
+/*                      y directory pio read data                       */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_ypiord_ydir_entry_u {
+	mmr_t	sh_md_dqrp_mmr_ypiord_ydir_entry_regval;
+	struct {
+		mmr_t	dira        : 26;
+		mmr_t	dirb        : 26;
+		mmr_t	pri         : 3;
+		mmr_t	acc         : 3;
+		mmr_t	cor         : 1;
+		mmr_t	unc         : 1;
+		mmr_t	reserved_0  : 4;
+	} sh_md_dqrp_mmr_ypiord_ydir_entry_s;
+} sh_md_dqrp_mmr_ypiord_ydir_entry_u_t;
+#else
+typedef union sh_md_dqrp_mmr_ypiord_ydir_entry_u {
+	mmr_t	sh_md_dqrp_mmr_ypiord_ydir_entry_regval;
+	struct {
+		mmr_t	reserved_0  : 4;
+		mmr_t	unc         : 1;
+		mmr_t	cor         : 1;
+		mmr_t	acc         : 3;
+		mmr_t	pri         : 3;
+		mmr_t	dirb        : 26;
+		mmr_t	dira        : 26;
+	} sh_md_dqrp_mmr_ypiord_ydir_entry_s;
+} sh_md_dqrp_mmr_ypiord_ydir_entry_u_t;
+#endif
+
+/* ==================================================================== */
+/*              Register "SH_MD_DQRP_MMR_YPIORD_YDIR_ECC"               */
+/*                           y directory ecc                            */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_ypiord_ydir_ecc_u {
+	mmr_t	sh_md_dqrp_mmr_ypiord_ydir_ecc_regval;
+	struct {
+		mmr_t	ecca        : 7;
+		mmr_t	eccb        : 7;
+		mmr_t	reserved_0  : 50;
+	} sh_md_dqrp_mmr_ypiord_ydir_ecc_s;
+} sh_md_dqrp_mmr_ypiord_ydir_ecc_u_t;
+#else
+typedef union sh_md_dqrp_mmr_ypiord_ydir_ecc_u {
+	mmr_t	sh_md_dqrp_mmr_ypiord_ydir_ecc_regval;
+	struct {
+		mmr_t	reserved_0  : 50;
+		mmr_t	eccb        : 7;
+		mmr_t	ecca        : 7;
+	} sh_md_dqrp_mmr_ypiord_ydir_ecc_s;
+} sh_md_dqrp_mmr_ypiord_ydir_ecc_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XCERR1"                   */
+/*              correctable dir ecc group 1 error register              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xcerr1_u {
+	mmr_t	sh_md_dqrp_mmr_xcerr1_regval;
+	struct {
+		mmr_t	grp1        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 25;
+	} sh_md_dqrp_mmr_xcerr1_s;
+} sh_md_dqrp_mmr_xcerr1_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xcerr1_u {
+	mmr_t	sh_md_dqrp_mmr_xcerr1_regval;
+	struct {
+		mmr_t	reserved_0  : 25;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp1        : 36;
+	} sh_md_dqrp_mmr_xcerr1_s;
+} sh_md_dqrp_mmr_xcerr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XCERR2"                   */
+/*              correctable dir ecc group 2 error register              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xcerr2_u {
+	mmr_t	sh_md_dqrp_mmr_xcerr2_regval;
+	struct {
+		mmr_t	grp2        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 26;
+	} sh_md_dqrp_mmr_xcerr2_s;
+} sh_md_dqrp_mmr_xcerr2_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xcerr2_u {
+	mmr_t	sh_md_dqrp_mmr_xcerr2_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp2        : 36;
+	} sh_md_dqrp_mmr_xcerr2_s;
+} sh_md_dqrp_mmr_xcerr2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XUERR1"                   */
+/*             uncorrectable dir ecc group 1 error register             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xuerr1_u {
+	mmr_t	sh_md_dqrp_mmr_xuerr1_regval;
+	struct {
+		mmr_t	grp1        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 25;
+	} sh_md_dqrp_mmr_xuerr1_s;
+} sh_md_dqrp_mmr_xuerr1_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xuerr1_u {
+	mmr_t	sh_md_dqrp_mmr_xuerr1_regval;
+	struct {
+		mmr_t	reserved_0  : 25;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp1        : 36;
+	} sh_md_dqrp_mmr_xuerr1_s;
+} sh_md_dqrp_mmr_xuerr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XUERR2"                   */
+/*             uncorrectable dir ecc group 2 error register             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xuerr2_u {
+	mmr_t	sh_md_dqrp_mmr_xuerr2_regval;
+	struct {
+		mmr_t	grp2        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 26;
+	} sh_md_dqrp_mmr_xuerr2_s;
+} sh_md_dqrp_mmr_xuerr2_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xuerr2_u {
+	mmr_t	sh_md_dqrp_mmr_xuerr2_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp2        : 36;
+	} sh_md_dqrp_mmr_xuerr2_s;
+} sh_md_dqrp_mmr_xuerr2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_XPERR"                    */
+/*                       protocol error register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xperr_u {
+	mmr_t	sh_md_dqrp_mmr_xperr_regval;
+	struct {
+		mmr_t	dir         : 26;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+		mmr_t	prige       : 1;
+		mmr_t	priv        : 1;
+		mmr_t	cor         : 1;
+		mmr_t	unc         : 1;
+		mmr_t	mybit       : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 1;
+	} sh_md_dqrp_mmr_xperr_s;
+} sh_md_dqrp_mmr_xperr_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xperr_u {
+	mmr_t	sh_md_dqrp_mmr_xperr_regval;
+	struct {
+		mmr_t	reserved_0  : 1;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	mybit       : 8;
+		mmr_t	unc         : 1;
+		mmr_t	cor         : 1;
+		mmr_t	priv        : 1;
+		mmr_t	prige       : 1;
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	dir         : 26;
+	} sh_md_dqrp_mmr_xperr_s;
+} sh_md_dqrp_mmr_xperr_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YCERR1"                   */
+/*              correctable dir ecc group 1 error register              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_ycerr1_u {
+	mmr_t	sh_md_dqrp_mmr_ycerr1_regval;
+	struct {
+		mmr_t	grp1        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 25;
+	} sh_md_dqrp_mmr_ycerr1_s;
+} sh_md_dqrp_mmr_ycerr1_u_t;
+#else
+typedef union sh_md_dqrp_mmr_ycerr1_u {
+	mmr_t	sh_md_dqrp_mmr_ycerr1_regval;
+	struct {
+		mmr_t	reserved_0  : 25;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp1        : 36;
+	} sh_md_dqrp_mmr_ycerr1_s;
+} sh_md_dqrp_mmr_ycerr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YCERR2"                   */
+/*              correctable dir ecc group 2 error register              */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_ycerr2_u {
+	mmr_t	sh_md_dqrp_mmr_ycerr2_regval;
+	struct {
+		mmr_t	grp2        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 26;
+	} sh_md_dqrp_mmr_ycerr2_s;
+} sh_md_dqrp_mmr_ycerr2_u_t;
+#else
+typedef union sh_md_dqrp_mmr_ycerr2_u {
+	mmr_t	sh_md_dqrp_mmr_ycerr2_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp2        : 36;
+	} sh_md_dqrp_mmr_ycerr2_s;
+} sh_md_dqrp_mmr_ycerr2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YUERR1"                   */
+/*             uncorrectable dir ecc group 1 error register             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_yuerr1_u {
+	mmr_t	sh_md_dqrp_mmr_yuerr1_regval;
+	struct {
+		mmr_t	grp1        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 25;
+	} sh_md_dqrp_mmr_yuerr1_s;
+} sh_md_dqrp_mmr_yuerr1_u_t;
+#else
+typedef union sh_md_dqrp_mmr_yuerr1_u {
+	mmr_t	sh_md_dqrp_mmr_yuerr1_regval;
+	struct {
+		mmr_t	reserved_0  : 25;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp1        : 36;
+	} sh_md_dqrp_mmr_yuerr1_s;
+} sh_md_dqrp_mmr_yuerr1_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YUERR2"                   */
+/*             uncorrectable dir ecc group 2 error register             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_yuerr2_u {
+	mmr_t	sh_md_dqrp_mmr_yuerr2_regval;
+	struct {
+		mmr_t	grp2        : 36;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 26;
+	} sh_md_dqrp_mmr_yuerr2_s;
+} sh_md_dqrp_mmr_yuerr2_u_t;
+#else
+typedef union sh_md_dqrp_mmr_yuerr2_u {
+	mmr_t	sh_md_dqrp_mmr_yuerr2_regval;
+	struct {
+		mmr_t	reserved_0  : 26;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	grp2        : 36;
+	} sh_md_dqrp_mmr_yuerr2_s;
+} sh_md_dqrp_mmr_yuerr2_u_t;
+#endif
+
+/* ==================================================================== */
+/*                   Register "SH_MD_DQRP_MMR_YPERR"                    */
+/*                       protocol error register                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_yperr_u {
+	mmr_t	sh_md_dqrp_mmr_yperr_regval;
+	struct {
+		mmr_t	dir         : 26;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+		mmr_t	prige       : 1;
+		mmr_t	priv        : 1;
+		mmr_t	cor         : 1;
+		mmr_t	unc         : 1;
+		mmr_t	mybit       : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 1;
+	} sh_md_dqrp_mmr_yperr_s;
+} sh_md_dqrp_mmr_yperr_u_t;
+#else
+typedef union sh_md_dqrp_mmr_yperr_u {
+	mmr_t	sh_md_dqrp_mmr_yperr_regval;
+	struct {
+		mmr_t	reserved_0  : 1;
+		mmr_t	arm         : 1;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	mybit       : 8;
+		mmr_t	unc         : 1;
+		mmr_t	cor         : 1;
+		mmr_t	priv        : 1;
+		mmr_t	prige       : 1;
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	dir         : 26;
+	} sh_md_dqrp_mmr_yperr_s;
+} sh_md_dqrp_mmr_yperr_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_CMDTRIG"                 */
+/*                             cmd triggers                             */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_cmdtrig_u {
+	mmr_t	sh_md_dqrp_mmr_dir_cmdtrig_regval;
+	struct {
+		mmr_t	cmd0        : 8;
+		mmr_t	cmd1        : 8;
+		mmr_t	cmd2        : 8;
+		mmr_t	cmd3        : 8;
+		mmr_t	reserved_0  : 32;
+	} sh_md_dqrp_mmr_dir_cmdtrig_s;
+} sh_md_dqrp_mmr_dir_cmdtrig_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_cmdtrig_u {
+	mmr_t	sh_md_dqrp_mmr_dir_cmdtrig_regval;
+	struct {
+		mmr_t	reserved_0  : 32;
+		mmr_t	cmd3        : 8;
+		mmr_t	cmd2        : 8;
+		mmr_t	cmd1        : 8;
+		mmr_t	cmd0        : 8;
+	} sh_md_dqrp_mmr_dir_cmdtrig_s;
+} sh_md_dqrp_mmr_dir_cmdtrig_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_TBLTRIG"                 */
+/*                          dir table trigger                           */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_tbltrig_u {
+	mmr_t	sh_md_dqrp_mmr_dir_tbltrig_regval;
+	struct {
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	acc         : 2;
+		mmr_t	prige       : 1;
+		mmr_t	dirst       : 9;
+		mmr_t	mybit       : 8;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqrp_mmr_dir_tbltrig_s;
+} sh_md_dqrp_mmr_dir_tbltrig_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_tbltrig_u {
+	mmr_t	sh_md_dqrp_mmr_dir_tbltrig_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	mybit       : 8;
+		mmr_t	dirst       : 9;
+		mmr_t	prige       : 1;
+		mmr_t	acc         : 2;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+	} sh_md_dqrp_mmr_dir_tbltrig_s;
+} sh_md_dqrp_mmr_dir_tbltrig_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_TBLMASK"                 */
+/*                        dir table trigger mask                        */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_dir_tblmask_u {
+	mmr_t	sh_md_dqrp_mmr_dir_tblmask_regval;
+	struct {
+		mmr_t	src         : 14;
+		mmr_t	cmd         : 8;
+		mmr_t	acc         : 2;
+		mmr_t	prige       : 1;
+		mmr_t	dirst       : 9;
+		mmr_t	mybit       : 8;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqrp_mmr_dir_tblmask_s;
+} sh_md_dqrp_mmr_dir_tblmask_u_t;
+#else
+typedef union sh_md_dqrp_mmr_dir_tblmask_u {
+	mmr_t	sh_md_dqrp_mmr_dir_tblmask_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	mybit       : 8;
+		mmr_t	dirst       : 9;
+		mmr_t	prige       : 1;
+		mmr_t	acc         : 2;
+		mmr_t	cmd         : 8;
+		mmr_t	src         : 14;
+	} sh_md_dqrp_mmr_dir_tblmask_s;
+} sh_md_dqrp_mmr_dir_tblmask_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRP_MMR_XBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xbist_h_u {
+	mmr_t	sh_md_dqrp_mmr_xbist_h_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_1  : 21;
+	} sh_md_dqrp_mmr_xbist_h_s;
+} sh_md_dqrp_mmr_xbist_h_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xbist_h_u {
+	mmr_t	sh_md_dqrp_mmr_xbist_h_regval;
+	struct {
+		mmr_t	reserved_1  : 21;
+		mmr_t	arm         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqrp_mmr_xbist_h_s;
+} sh_md_dqrp_mmr_xbist_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRP_MMR_XBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xbist_l_u {
+	mmr_t	sh_md_dqrp_mmr_xbist_l_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqrp_mmr_xbist_l_s;
+} sh_md_dqrp_mmr_xbist_l_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xbist_l_u {
+	mmr_t	sh_md_dqrp_mmr_xbist_l_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqrp_mmr_xbist_l_s;
+} sh_md_dqrp_mmr_xbist_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_XBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xbist_err_h_u {
+	mmr_t	sh_md_dqrp_mmr_xbist_err_h_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqrp_mmr_xbist_err_h_s;
+} sh_md_dqrp_mmr_xbist_err_h_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xbist_err_h_u {
+	mmr_t	sh_md_dqrp_mmr_xbist_err_h_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqrp_mmr_xbist_err_h_s;
+} sh_md_dqrp_mmr_xbist_err_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_XBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_xbist_err_l_u {
+	mmr_t	sh_md_dqrp_mmr_xbist_err_l_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqrp_mmr_xbist_err_l_s;
+} sh_md_dqrp_mmr_xbist_err_l_u_t;
+#else
+typedef union sh_md_dqrp_mmr_xbist_err_l_u {
+	mmr_t	sh_md_dqrp_mmr_xbist_err_l_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqrp_mmr_xbist_err_l_s;
+} sh_md_dqrp_mmr_xbist_err_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRP_MMR_YBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_ybist_h_u {
+	mmr_t	sh_md_dqrp_mmr_ybist_h_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_1  : 21;
+	} sh_md_dqrp_mmr_ybist_h_s;
+} sh_md_dqrp_mmr_ybist_h_u_t;
+#else
+typedef union sh_md_dqrp_mmr_ybist_h_u {
+	mmr_t	sh_md_dqrp_mmr_ybist_h_regval;
+	struct {
+		mmr_t	reserved_1  : 21;
+		mmr_t	arm         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqrp_mmr_ybist_h_s;
+} sh_md_dqrp_mmr_ybist_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRP_MMR_YBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_ybist_l_u {
+	mmr_t	sh_md_dqrp_mmr_ybist_l_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqrp_mmr_ybist_l_s;
+} sh_md_dqrp_mmr_ybist_l_u_t;
+#else
+typedef union sh_md_dqrp_mmr_ybist_l_u {
+	mmr_t	sh_md_dqrp_mmr_ybist_l_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqrp_mmr_ybist_l_s;
+} sh_md_dqrp_mmr_ybist_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_YBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_ybist_err_h_u {
+	mmr_t	sh_md_dqrp_mmr_ybist_err_h_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqrp_mmr_ybist_err_h_s;
+} sh_md_dqrp_mmr_ybist_err_h_u_t;
+#else
+typedef union sh_md_dqrp_mmr_ybist_err_h_u {
+	mmr_t	sh_md_dqrp_mmr_ybist_err_h_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqrp_mmr_ybist_err_h_s;
+} sh_md_dqrp_mmr_ybist_err_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_YBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrp_mmr_ybist_err_l_u {
+	mmr_t	sh_md_dqrp_mmr_ybist_err_l_regval;
+	struct {
+		mmr_t	pat         : 32;
+		mmr_t	reserved_0  : 8;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_1  : 22;
+	} sh_md_dqrp_mmr_ybist_err_l_s;
+} sh_md_dqrp_mmr_ybist_err_l_u_t;
+#else
+typedef union sh_md_dqrp_mmr_ybist_err_l_u {
+	mmr_t	sh_md_dqrp_mmr_ybist_err_l_regval;
+	struct {
+		mmr_t	reserved_1  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	reserved_0  : 8;
+		mmr_t	pat         : 32;
+	} sh_md_dqrp_mmr_ybist_err_l_s;
+} sh_md_dqrp_mmr_ybist_err_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRS_MMR_XBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_xbist_h_u {
+	mmr_t	sh_md_dqrs_mmr_xbist_h_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 21;
+	} sh_md_dqrs_mmr_xbist_h_s;
+} sh_md_dqrs_mmr_xbist_h_u_t;
+#else
+typedef union sh_md_dqrs_mmr_xbist_h_u {
+	mmr_t	sh_md_dqrs_mmr_xbist_h_regval;
+	struct {
+		mmr_t	reserved_0  : 21;
+		mmr_t	arm         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqrs_mmr_xbist_h_s;
+} sh_md_dqrs_mmr_xbist_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRS_MMR_XBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_xbist_l_u {
+	mmr_t	sh_md_dqrs_mmr_xbist_l_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqrs_mmr_xbist_l_s;
+} sh_md_dqrs_mmr_xbist_l_u_t;
+#else
+typedef union sh_md_dqrs_mmr_xbist_l_u {
+	mmr_t	sh_md_dqrs_mmr_xbist_l_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqrs_mmr_xbist_l_s;
+} sh_md_dqrs_mmr_xbist_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRS_MMR_XBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_xbist_err_h_u {
+	mmr_t	sh_md_dqrs_mmr_xbist_err_h_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqrs_mmr_xbist_err_h_s;
+} sh_md_dqrs_mmr_xbist_err_h_u_t;
+#else
+typedef union sh_md_dqrs_mmr_xbist_err_h_u {
+	mmr_t	sh_md_dqrs_mmr_xbist_err_h_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqrs_mmr_xbist_err_h_s;
+} sh_md_dqrs_mmr_xbist_err_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRS_MMR_XBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_xbist_err_l_u {
+	mmr_t	sh_md_dqrs_mmr_xbist_err_l_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqrs_mmr_xbist_err_l_s;
+} sh_md_dqrs_mmr_xbist_err_l_u_t;
+#else
+typedef union sh_md_dqrs_mmr_xbist_err_l_u {
+	mmr_t	sh_md_dqrs_mmr_xbist_err_l_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqrs_mmr_xbist_err_l_s;
+} sh_md_dqrs_mmr_xbist_err_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRS_MMR_YBIST_H"                   */
+/*                    rising edge bist/fill pattern                     */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_ybist_h_u {
+	mmr_t	sh_md_dqrs_mmr_ybist_h_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_0  : 21;
+	} sh_md_dqrs_mmr_ybist_h_s;
+} sh_md_dqrs_mmr_ybist_h_u_t;
+#else
+typedef union sh_md_dqrs_mmr_ybist_h_u {
+	mmr_t	sh_md_dqrs_mmr_ybist_h_regval;
+	struct {
+		mmr_t	reserved_0  : 21;
+		mmr_t	arm         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqrs_mmr_ybist_h_s;
+} sh_md_dqrs_mmr_ybist_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                  Register "SH_MD_DQRS_MMR_YBIST_L"                   */
+/*                    falling edge bist/fill pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_ybist_l_u {
+	mmr_t	sh_md_dqrs_mmr_ybist_l_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	inv         : 1;
+		mmr_t	rot         : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqrs_mmr_ybist_l_s;
+} sh_md_dqrs_mmr_ybist_l_u_t;
+#else
+typedef union sh_md_dqrs_mmr_ybist_l_u {
+	mmr_t	sh_md_dqrs_mmr_ybist_l_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	rot         : 1;
+		mmr_t	inv         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqrs_mmr_ybist_l_s;
+} sh_md_dqrs_mmr_ybist_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRS_MMR_YBIST_ERR_H"                 */
+/*                    rising edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_ybist_err_h_u {
+	mmr_t	sh_md_dqrs_mmr_ybist_err_h_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqrs_mmr_ybist_err_h_s;
+} sh_md_dqrs_mmr_ybist_err_h_u_t;
+#else
+typedef union sh_md_dqrs_mmr_ybist_err_h_u {
+	mmr_t	sh_md_dqrs_mmr_ybist_err_h_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqrs_mmr_ybist_err_h_s;
+} sh_md_dqrs_mmr_ybist_err_h_u_t;
+#endif
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRS_MMR_YBIST_ERR_L"                 */
+/*                   falling edge bist error pattern                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_ybist_err_l_u {
+	mmr_t	sh_md_dqrs_mmr_ybist_err_l_regval;
+	struct {
+		mmr_t	pat         : 40;
+		mmr_t	val         : 1;
+		mmr_t	more        : 1;
+		mmr_t	reserved_0  : 22;
+	} sh_md_dqrs_mmr_ybist_err_l_s;
+} sh_md_dqrs_mmr_ybist_err_l_u_t;
+#else
+typedef union sh_md_dqrs_mmr_ybist_err_l_u {
+	mmr_t	sh_md_dqrs_mmr_ybist_err_l_regval;
+	struct {
+		mmr_t	reserved_0  : 22;
+		mmr_t	more        : 1;
+		mmr_t	val         : 1;
+		mmr_t	pat         : 40;
+	} sh_md_dqrs_mmr_ybist_err_l_s;
+} sh_md_dqrs_mmr_ybist_err_l_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQRS_MMR_JNR_DEBUG"                  */
+/*                    joiner/fct debug configuration                    */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_jnr_debug_u {
+	mmr_t	sh_md_dqrs_mmr_jnr_debug_regval;
+	struct {
+		mmr_t	px          : 1;
+		mmr_t	rw          : 1;
+		mmr_t	reserved_0  : 62;
+	} sh_md_dqrs_mmr_jnr_debug_s;
+} sh_md_dqrs_mmr_jnr_debug_u_t;
+#else
+typedef union sh_md_dqrs_mmr_jnr_debug_u {
+	mmr_t	sh_md_dqrs_mmr_jnr_debug_regval;
+	struct {
+		mmr_t	reserved_0  : 62;
+		mmr_t	rw          : 1;
+		mmr_t	px          : 1;
+	} sh_md_dqrs_mmr_jnr_debug_s;
+} sh_md_dqrs_mmr_jnr_debug_u_t;
+#endif
+
+/* ==================================================================== */
+/*                 Register "SH_MD_DQRS_MMR_YAMOPW_ERR"                 */
+/*                  amo/partial rmw ecc error register                  */
+/* ==================================================================== */
+
+#ifdef LITTLE_ENDIAN
+typedef union sh_md_dqrs_mmr_yamopw_err_u {
+	mmr_t	sh_md_dqrs_mmr_yamopw_err_regval;
+	struct {
+		mmr_t	ssyn        : 8;
+		mmr_t	scor        : 1;
+		mmr_t	sunc        : 1;
+		mmr_t	reserved_0  : 6;
+		mmr_t	rsyn        : 8;
+		mmr_t	rcor        : 1;
+		mmr_t	runc        : 1;
+		mmr_t	reserved_1  : 6;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_2  : 31;
+	} sh_md_dqrs_mmr_yamopw_err_s;
+} sh_md_dqrs_mmr_yamopw_err_u_t;
+#else
+typedef union sh_md_dqrs_mmr_yamopw_err_u {
+	mmr_t	sh_md_dqrs_mmr_yamopw_err_regval;
+	struct {
+		mmr_t	reserved_2  : 31;
+		mmr_t	arm         : 1;
+		mmr_t	reserved_1  : 6;
+		mmr_t	runc        : 1;
+		mmr_t	rcor        : 1;
+		mmr_t	rsyn        : 8;
+		mmr_t	reserved_0  : 6;
+		mmr_t	sunc        : 1;
+		mmr_t	scor        : 1;
+		mmr_t	ssyn        : 8;
+	} sh_md_dqrs_mmr_yamopw_err_s;
+} sh_md_dqrs_mmr_yamopw_err_u_t;
+#endif
+
+
+#endif /* _ASM_IA64_SN_SN2_SHUB_MMR_T_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/shubio.h linux/include/asm-ia64/sn/sn2/shubio.h
--- linux.orig/include/asm-ia64/sn/sn2/shubio.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/shubio.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,3639 @@
+/* $Id: shubio.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_SN2_SHUBIO_H
+#define _ASM_IA64_SN_SN2_SHUBIO_H
+
+#include <asm/sn/arch.h>
+
+#define HUB_WIDGET_ID_MAX 0xf
+#define IIO_NUM_ITTES   7
+#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
+
+#define    IIO_WID                   0x00400000    /* Crosstalk Widget Identification */
+                                                   /* This register is also accessible from
+                                                    * Crosstalk at address 0x0.  */
+#define    IIO_WSTAT                 0x00400008    /* Crosstalk Widget Status */
+#define    IIO_WCR                   0x00400020    /* Crosstalk Widget Control Register */
+#define    IIO_ILAPR                 0x00400100    /* IO Local Access Protection Register */
+#define    IIO_ILAPO                 0x00400108    /* IO Local Access Protection Override */
+#define    IIO_IOWA                  0x00400110    /* IO Outbound Widget Access */
+#define    IIO_IIWA                  0x00400118    /* IO Inbound Widget Access */
+#define    IIO_IIDEM                 0x00400120    /* IO Inbound Device Error Mask */
+#define    IIO_ILCSR                 0x00400128    /* IO LLP Control and Status Register */
+#define    IIO_ILLR                  0x00400130    /* IO LLP Log Register    */
+#define    IIO_IIDSR                 0x00400138    /* IO Interrupt Destination */
+
+#define    IIO_IGFX0                 0x00400140    /* IO Graphics Node-Widget Map 0 */
+#define    IIO_IGFX1                 0x00400148    /* IO Graphics Node-Widget Map 1 */
+
+#define    IIO_ISCR0                 0x00400150    /* IO Scratch Register 0 */
+#define    IIO_ISCR1                 0x00400158    /* IO Scratch Register 1 */
+
+#define    IIO_ITTE1                 0x00400160    /* IO Translation Table Entry 1 */
+#define    IIO_ITTE2                 0x00400168    /* IO Translation Table Entry 2 */
+#define    IIO_ITTE3                 0x00400170    /* IO Translation Table Entry 3 */
+#define    IIO_ITTE4                 0x00400178    /* IO Translation Table Entry 4 */
+#define    IIO_ITTE5                 0x00400180    /* IO Translation Table Entry 5 */
+#define    IIO_ITTE6                 0x00400188    /* IO Translation Table Entry 6 */
+#define    IIO_ITTE7                 0x00400190    /* IO Translation Table Entry 7 */
+
+#define    IIO_IPRB0                 0x00400198    /* IO PRB Entry 0         */
+#define    IIO_IPRB8                 0x004001A0    /* IO PRB Entry 8         */
+#define    IIO_IPRB9                 0x004001A8    /* IO PRB Entry 9         */
+#define    IIO_IPRBA                 0x004001B0    /* IO PRB Entry A         */
+#define    IIO_IPRBB                 0x004001B8    /* IO PRB Entry B         */
+#define    IIO_IPRBC                 0x004001C0    /* IO PRB Entry C         */
+#define    IIO_IPRBD                 0x004001C8    /* IO PRB Entry D         */
+#define    IIO_IPRBE                 0x004001D0    /* IO PRB Entry E         */
+#define    IIO_IPRBF                 0x004001D8    /* IO PRB Entry F         */
+
+#define    IIO_IXCC                  0x004001E0    /* IO Crosstalk Credit Count Timeout */
+#define    IIO_IMEM                  0x004001E8    /* IO Miscellaneous Error Mask */
+#define    IIO_IXTT                  0x004001F0    /* IO Crosstalk Timeout Threshold */
+#define    IIO_IECLR                 0x004001F8    /* IO Error Clear Register */
+#define    IIO_IBCR                  0x00400200    /* IO BTE Control Register */
+
+#define    IIO_IXSM                  0x00400208    /* IO Crosstalk Spurious Message */
+#define    IIO_IXSS                  0x00400210    /* IO Crosstalk Spurious Sideband */
+
+#define    IIO_ILCT                  0x00400218    /* IO LLP Channel Test    */
+
+#define    IIO_IIEPH1                0x00400220    /* IO Incoming Error Packet Header, Part 1 */
+#define    IIO_IIEPH2                0x00400228    /* IO Incoming Error Packet Header, Part 2 */
+
+
+#define    IIO_ISLAPR                0x00400230    /* IO SXB Local Access Protection Regster */
+#define    IIO_ISLAPO                0x00400238    /* IO SXB Local Access Protection Override */
+
+#define    IIO_IWI                   0x00400240    /* IO Wrapper Interrupt Register */
+#define    IIO_IWEL                  0x00400248    /* IO Wrapper Error Log Register */
+#define    IIO_IWC                   0x00400250    /* IO Wrapper Control Register */
+#define    IIO_IWS                   0x00400258    /* IO Wrapper Status Register */
+#define    IIO_IWEIM                 0x00400260    /* IO Wrapper Error Interrupt Masking Register */
+
+#define    IIO_IPCA                  0x00400300    /* IO PRB Counter Adjust */
+
+#define    IIO_IPRTE0_A              0x00400308    /* IO PIO Read Address Table Entry 0, Part A */
+#define    IIO_IPRTE1_A              0x00400310    /* IO PIO Read Address Table Entry 1, Part A */
+#define    IIO_IPRTE2_A              0x00400318    /* IO PIO Read Address Table Entry 2, Part A */
+#define    IIO_IPRTE3_A               0x00400320    /* IO PIO Read Address Table Entry 3, Part A */
+#define    IIO_IPRTE4_A               0x00400328    /* IO PIO Read Address Table Entry 4, Part A */
+#define    IIO_IPRTE5_A               0x00400330    /* IO PIO Read Address Table Entry 5, Part A */
+#define    IIO_IPRTE6_A               0x00400338    /* IO PIO Read Address Table Entry 6, Part A */
+#define    IIO_IPRTE7_A               0x00400340    /* IO PIO Read Address Table Entry 7, Part A */
+
+#define    IIO_IPRTE0_B              0x00400348    /* IO PIO Read Address Table Entry 0, Part B */
+#define    IIO_IPRTE1_B              0x00400350    /* IO PIO Read Address Table Entry 1, Part B */
+#define    IIO_IPRTE2_B              0x00400358    /* IO PIO Read Address Table Entry 2, Part B */
+#define    IIO_IPRTE3_B               0x00400360    /* IO PIO Read Address Table Entry 3, Part B */
+#define    IIO_IPRTE4_B               0x00400368    /* IO PIO Read Address Table Entry 4, Part B */
+#define    IIO_IPRTE5_B               0x00400370    /* IO PIO Read Address Table Entry 5, Part B */
+#define    IIO_IPRTE6_B               0x00400378    /* IO PIO Read Address Table Entry 6, Part B */
+#define    IIO_IPRTE7_B               0x00400380    /* IO PIO Read Address Table Entry 7, Part B */
+
+#define    IIO_IPDR                  0x00400388    /* IO PIO Deallocation Register */
+#define    IIO_ICDR                  0x00400390    /* IO CRB Entry Deallocation Register */
+#define    IIO_IFDR                  0x00400398    /* IO IOQ FIFO Depth Register */
+#define    IIO_IIAP                  0x004003A0    /* IO IIQ Arbitration Parameters */
+#define    IIO_ICMR                  0x004003A8    /* IO CRB Management Register */
+#define    IIO_ICCR                  0x004003B0    /* IO CRB Control Register */
+#define    IIO_ICTO                  0x004003B8    /* IO CRB Timeout         */
+#define    IIO_ICTP                  0x004003C0    /* IO CRB Timeout Prescalar */
+
+#define    IIO_ICRB0_A               0x00400400    /* IO CRB Entry 0_A       */
+#define    IIO_ICRB0_B               0x00400408    /* IO CRB Entry 0_B       */
+#define    IIO_ICRB0_C               0x00400410    /* IO CRB Entry 0_C       */
+#define    IIO_ICRB0_D               0x00400418    /* IO CRB Entry 0_D       */
+#define    IIO_ICRB0_E               0x00400420    /* IO CRB Entry 0_E       */
+
+#define    IIO_ICRB1_A               0x00400430    /* IO CRB Entry 1_A       */
+#define    IIO_ICRB1_B               0x00400438    /* IO CRB Entry 1_B       */
+#define    IIO_ICRB1_C               0x00400440    /* IO CRB Entry 1_C       */
+#define    IIO_ICRB1_D               0x00400448    /* IO CRB Entry 1_D       */
+#define    IIO_ICRB1_E               0x00400450    /* IO CRB Entry 1_E       */
+
+#define    IIO_ICRB2_A               0x00400460    /* IO CRB Entry 2_A       */
+#define    IIO_ICRB2_B               0x00400468    /* IO CRB Entry 2_B       */
+#define    IIO_ICRB2_C               0x00400470    /* IO CRB Entry 2_C       */
+#define    IIO_ICRB2_D               0x00400478    /* IO CRB Entry 2_D       */
+#define    IIO_ICRB2_E               0x00400480    /* IO CRB Entry 2_E       */
+
+#define    IIO_ICRB3_A               0x00400490    /* IO CRB Entry 3_A       */
+#define    IIO_ICRB3_B               0x00400498    /* IO CRB Entry 3_B       */
+#define    IIO_ICRB3_C               0x004004a0    /* IO CRB Entry 3_C       */
+#define    IIO_ICRB3_D               0x004004a8    /* IO CRB Entry 3_D       */
+#define    IIO_ICRB3_E               0x004004b0    /* IO CRB Entry 3_E       */
+
+#define    IIO_ICRB4_A               0x004004c0    /* IO CRB Entry 4_A       */
+#define    IIO_ICRB4_B               0x004004c8    /* IO CRB Entry 4_B       */
+#define    IIO_ICRB4_C               0x004004d0    /* IO CRB Entry 4_C       */
+#define    IIO_ICRB4_D               0x004004d8    /* IO CRB Entry 4_D       */
+#define    IIO_ICRB4_E               0x004004e0    /* IO CRB Entry 4_E       */
+
+#define    IIO_ICRB5_A               0x004004f0    /* IO CRB Entry 5_A       */
+#define    IIO_ICRB5_B               0x004004f8    /* IO CRB Entry 5_B       */
+#define    IIO_ICRB5_C               0x00400500    /* IO CRB Entry 5_C       */
+#define    IIO_ICRB5_D               0x00400508    /* IO CRB Entry 5_D       */
+#define    IIO_ICRB5_E               0x00400510    /* IO CRB Entry 5_E       */
+
+#define    IIO_ICRB6_A               0x00400520    /* IO CRB Entry 6_A       */
+#define    IIO_ICRB6_B               0x00400528    /* IO CRB Entry 6_B       */
+#define    IIO_ICRB6_C               0x00400530    /* IO CRB Entry 6_C       */
+#define    IIO_ICRB6_D               0x00400538    /* IO CRB Entry 6_D       */
+#define    IIO_ICRB6_E               0x00400540    /* IO CRB Entry 6_E       */
+
+#define    IIO_ICRB7_A               0x00400550    /* IO CRB Entry 7_A       */
+#define    IIO_ICRB7_B               0x00400558    /* IO CRB Entry 7_B       */
+#define    IIO_ICRB7_C               0x00400560    /* IO CRB Entry 7_C       */
+#define    IIO_ICRB7_D               0x00400568    /* IO CRB Entry 7_D       */
+#define    IIO_ICRB7_E               0x00400570    /* IO CRB Entry 7_E       */
+
+#define    IIO_ICRB8_A               0x00400580    /* IO CRB Entry 8_A       */
+#define    IIO_ICRB8_B               0x00400588    /* IO CRB Entry 8_B       */
+#define    IIO_ICRB8_C               0x00400590    /* IO CRB Entry 8_C       */
+#define    IIO_ICRB8_D               0x00400598    /* IO CRB Entry 8_D       */
+#define    IIO_ICRB8_E               0x004005a0    /* IO CRB Entry 8_E       */
+
+#define    IIO_ICRB9_A               0x004005b0    /* IO CRB Entry 9_A       */
+#define    IIO_ICRB9_B               0x004005b8    /* IO CRB Entry 9_B       */
+#define    IIO_ICRB9_C               0x004005c0    /* IO CRB Entry 9_C       */
+#define    IIO_ICRB9_D               0x004005c8    /* IO CRB Entry 9_D       */
+#define    IIO_ICRB9_E               0x004005d0    /* IO CRB Entry 9_E       */
+
+#define    IIO_ICRBA_A               0x004005e0    /* IO CRB Entry A_A       */
+#define    IIO_ICRBA_B               0x004005e8    /* IO CRB Entry A_B       */
+#define    IIO_ICRBA_C               0x004005f0    /* IO CRB Entry A_C       */
+#define    IIO_ICRBA_D               0x004005f8    /* IO CRB Entry A_D       */
+#define    IIO_ICRBA_E               0x00400600    /* IO CRB Entry A_E       */
+
+#define    IIO_ICRBB_A               0x00400610    /* IO CRB Entry B_A       */
+#define    IIO_ICRBB_B               0x00400618    /* IO CRB Entry B_B       */
+#define    IIO_ICRBB_C               0x00400620    /* IO CRB Entry B_C       */
+#define    IIO_ICRBB_D               0x00400628    /* IO CRB Entry B_D       */
+#define    IIO_ICRBB_E               0x00400630    /* IO CRB Entry B_E       */
+
+#define    IIO_ICRBC_A               0x00400640    /* IO CRB Entry C_A       */
+#define    IIO_ICRBC_B               0x00400648    /* IO CRB Entry C_B       */
+#define    IIO_ICRBC_C               0x00400650    /* IO CRB Entry C_C       */
+#define    IIO_ICRBC_D               0x00400658    /* IO CRB Entry C_D       */
+#define    IIO_ICRBC_E               0x00400660    /* IO CRB Entry C_E       */
+
+#define    IIO_ICRBD_A               0x00400670    /* IO CRB Entry D_A       */
+#define    IIO_ICRBD_B               0x00400678    /* IO CRB Entry D_B       */
+#define    IIO_ICRBD_C               0x00400680    /* IO CRB Entry D_C       */
+#define    IIO_ICRBD_D               0x00400688    /* IO CRB Entry D_D       */
+#define    IIO_ICRBD_E               0x00400690    /* IO CRB Entry D_E       */
+
+#define    IIO_ICRBE_A               0x004006a0    /* IO CRB Entry E_A       */
+#define    IIO_ICRBE_B               0x004006a8    /* IO CRB Entry E_B       */
+#define    IIO_ICRBE_C               0x004006b0    /* IO CRB Entry E_C       */
+#define    IIO_ICRBE_D               0x004006b8    /* IO CRB Entry E_D       */
+#define    IIO_ICRBE_E               0x004006c0    /* IO CRB Entry E_E       */
+
+#define    IIO_ICSML                 0x00400700    /* IO CRB Spurious Message Low */
+#define    IIO_ICSMM                 0x00400708    /* IO CRB Spurious Message Middle */
+#define    IIO_ICSMH                 0x00400710    /* IO CRB Spurious Message High */
+
+#define    IIO_IDBSS                 0x00400718    /* IO Debug Submenu Select */
+
+#define    IIO_IBLS0                 0x00410000    /* IO BTE Length Status 0 */
+#define    IIO_IBSA0                 0x00410008    /* IO BTE Source Address 0 */
+#define    IIO_IBDA0                 0x00410010    /* IO BTE Destination Address 0 */
+#define    IIO_IBCT0                 0x00410018    /* IO BTE Control Terminate 0 */
+#define    IIO_IBNA0                 0x00410020    /* IO BTE Notification Address 0 */
+#define    IIO_IBIA0                 0x00410028    /* IO BTE Interrupt Address 0 */
+#define    IIO_IBLS1                 0x00420000    /* IO BTE Length Status 1 */
+#define    IIO_IBSA1                 0x00420008    /* IO BTE Source Address 1 */
+#define    IIO_IBDA1                 0x00420010    /* IO BTE Destination Address 1 */
+#define    IIO_IBCT1                 0x00420018    /* IO BTE Control Terminate 1 */
+#define    IIO_IBNA1                 0x00420020    /* IO BTE Notification Address 1 */
+#define    IIO_IBIA1                 0x00420028    /* IO BTE Interrupt Address 1 */
+
+#define    IIO_IPCR                  0x00430000    /* IO Performance Control */
+#define    IIO_IPPR                  0x00430008    /* IO Performance Profiling */
+
+
+#ifndef __ASSEMBLY__
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register echoes some information from the         *
+ * LB_REV_ID register. It is available through Crosstalk as described   *
+ * above. The REV_NUM and MFG_NUM fields receive their values from      *
+ * the REVISION and MANUFACTURER fields in the LB_REV_ID register.      *
+ * The PART_NUM field's value is the Crosstalk device ID number that    *
+ * Steve Miller assigned to the SHub chip.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_wid_u {
+	shubreg_t	ii_wid_regval;
+	struct	{
+		shubreg_t	w_rsvd_1		  :	 1;
+		shubreg_t	w_mfg_num		  :	11;
+		shubreg_t	w_part_num		  :	16;
+		shubreg_t	w_rev_num		  :	 4;
+		shubreg_t	w_rsvd			  :	32;
+	} ii_wid_fld_s;
+} ii_wid_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  The fields in this register are set upon detection of an error      *
+ * and cleared by various mechanisms, as explained in the               *
+ * description.                                                         *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_wstat_u {
+	shubreg_t	ii_wstat_regval;
+	struct	{
+		shubreg_t	w_pending		  :	 4;
+		shubreg_t	w_xt_crd_to		  :	 1;
+		shubreg_t	w_xt_tail_to		  :	 1;
+		shubreg_t	w_rsvd_3		  :	 3;
+		shubreg_t       w_tx_mx_rty               :      1;
+		shubreg_t	w_rsvd_2		  :	 6;
+		shubreg_t	w_llp_tx_cnt		  :	 8;
+		shubreg_t	w_rsvd_1		  :	 8;
+		shubreg_t	w_crazy			  :	 1;
+		shubreg_t	w_rsvd			  :	31;
+	} ii_wstat_fld_s;
+} ii_wstat_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This is a read-write enabled register. It controls     *
+ * various aspects of the Crosstalk flow control.                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_wcr_u {
+	shubreg_t	ii_wcr_regval;
+	struct	{
+		shubreg_t	w_wid			  :	 4;
+		shubreg_t	w_tag			  :	 1;
+		shubreg_t	w_rsvd_1		  :	 8;
+		shubreg_t	w_dst_crd		  :	 3;
+		shubreg_t	w_f_bad_pkt		  :	 1;
+		shubreg_t	w_dir_con		  :	 1;
+		shubreg_t	w_e_thresh		  :	 5;
+		shubreg_t	w_rsvd			  :	41;
+	} ii_wcr_fld_s;
+} ii_wcr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register's value is a bit vector that guards      *
+ * access to local registers within the II as well as to external       *
+ * Crosstalk widgets. Each bit in the register corresponds to a         *
+ * particular region in the system; a region consists of one, two or    *
+ * four nodes (depending on the value of the REGION_SIZE field in the   *
+ * LB_REV_ID register, which is documented in Section 8.3.1.1). The     *
+ * protection provided by this register applies to PIO read             *
+ * operations as well as PIO write operations. The II will perform a    *
+ * PIO read or write request only if the bit for the requestor's        *
+ * region is set; otherwise, the II will not perform the requested      *
+ * operation and will return an error response. When a PIO read or      *
+ * write request targets an external Crosstalk widget, then not only    *
+ * must the bit for the requestor's region be set in the ILAPR, but     *
+ * also the target widget's bit in the IOWA register must be set in     *
+ * order for the II to perform the requested operation; otherwise,      *
+ * the II will return an error response. Hence, the protection          *
+ * provided by the IOWA register supplements the protection provided    *
+ * by the ILAPR for requests that target external Crosstalk widgets.    *
+ * This register itself can be accessed only by the nodes whose         *
+ * region ID bits are enabled in this same register. It can also be     *
+ * accessed through the IAlias space by the local processors.           *
+ * The reset value of this register allows access by all nodes.         *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ilapr_u {
+	shubreg_t	ii_ilapr_regval;
+	struct  {
+		shubreg_t	i_region                  :	64;
+	} ii_ilapr_fld_s;
+} ii_ilapr_u_t;
+
+
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  A write to this register of the 64-bit value           *
+ * "SGIrules" in ASCII, will cause the bit in the ILAPR register        *
+ * corresponding to the region of the requestor to be set (allow        *
+ * access). A write of any other value will be ignored. Access          *
+ * protection for this register is "SGIrules".                          *
+ * This register can also be accessed through the IAlias space.         *
+ * However, this access will not change the access permissions in the   *
+ * ILAPR.                                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ilapo_u {
+	shubreg_t	ii_ilapo_regval;
+	struct	{
+		shubreg_t	i_io_ovrride            :	64;
+	} ii_ilapo_fld_s;
+} ii_ilapo_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register qualifies all the PIO and Graphics writes launched    *
+ * from the SHUB towards a widget.                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iowa_u {
+	shubreg_t	ii_iowa_regval;
+	struct	{
+		shubreg_t	i_w0_oac		  :	 1;
+		shubreg_t	i_rsvd_1		  :	 7;
+                shubreg_t       i_wx_oac                  :      8;
+		shubreg_t	i_rsvd			  :	48;
+	} ii_iowa_fld_s;
+} ii_iowa_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register qualifies all the requests launched      *
+ * from a widget towards the Shub. This register is intended to be      *
+ * used by software in case of misbehaving widgets.                     *
+ *                                                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iiwa_u {
+	shubreg_t	ii_iiwa_regval;
+	struct  {
+		shubreg_t	i_w0_iac                  :	 1;
+		shubreg_t	i_rsvd_1		  :	 7;
+		shubreg_t	i_wx_iac		  :	 8;
+		shubreg_t	i_rsvd			  :	48;
+	} ii_iiwa_fld_s;
+} ii_iiwa_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register qualifies all the operations launched    *
+ * from a widget towards the SHub. It allows individual access          *
+ * control for up to 8 devices per widget. A device refers to           *
+ * individual DMA master hosted by a widget.                            *
+ * The bits in each field of this register are cleared by the Shub      *
+ * upon detection of an error which requires the device to be           *
+ * disabled. These fields assume that 0=TNUM=7 (i.e., Bridge-centric    *
+ * Crosstalk). Whether or not a device has access rights to this        *
+ * Shub is determined by an AND of the device enable bit in the         *
+ * appropriate field of this register and the corresponding bit in      *
+ * the Wx_IAC field (for the widget which this device belongs to).      *
+ * The bits in this field are set by writing a 1 to them. Incoming      *
+ * replies from Crosstalk are not subject to this access control        *
+ * mechanism.                                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iidem_u {
+	shubreg_t	ii_iidem_regval;
+	struct	{
+		shubreg_t	i_w8_dxs		  :	 8;
+		shubreg_t	i_w9_dxs		  :	 8;
+		shubreg_t	i_wa_dxs		  :	 8;
+		shubreg_t	i_wb_dxs		  :	 8;
+		shubreg_t	i_wc_dxs		  :	 8;
+		shubreg_t	i_wd_dxs		  :	 8;
+		shubreg_t	i_we_dxs		  :	 8;
+		shubreg_t	i_wf_dxs		  :	 8;
+	} ii_iidem_fld_s;
+} ii_iidem_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the various programmable fields necessary    *
+ * for controlling and observing the LLP signals.                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ilcsr_u {
+	shubreg_t	ii_ilcsr_regval;
+	struct  {
+		shubreg_t	i_nullto                  :	 6;
+		shubreg_t	i_rsvd_4		  :	 2;
+		shubreg_t	i_wrmrst		  :	 1;
+		shubreg_t	i_rsvd_3		  :	 1;
+		shubreg_t	i_llp_en		  :	 1;
+		shubreg_t	i_bm8			  :	 1;
+		shubreg_t	i_llp_stat		  :	 2;
+		shubreg_t	i_remote_power		  :	 1;
+		shubreg_t	i_rsvd_2		  :	 1;
+		shubreg_t	i_maxrtry		  :	10;
+		shubreg_t	i_d_avail_sel		  :	 2;
+		shubreg_t	i_rsvd_1		  :	 4;
+		shubreg_t	i_maxbrst		  :	10;
+                shubreg_t       i_rsvd                    :     22;
+
+	} ii_ilcsr_fld_s;
+} ii_ilcsr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This is simply a status registers that monitors the LLP error       *
+ * rate.                                                                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_illr_u {
+	shubreg_t	ii_illr_regval;
+	struct	{
+		shubreg_t	i_sn_cnt		  :	16;
+		shubreg_t	i_cb_cnt		  :	16;
+		shubreg_t	i_rsvd			  :	32;
+	} ii_illr_fld_s;
+} ii_illr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  All II-detected non-BTE error interrupts are           *
+ * specified via this register.                                         *
+ * NOTE: The PI interrupt register address is hardcoded in the II. If   *
+ * PI_ID==0, then the II sends an interrupt request (Duplonet PWRI      *
+ * packet) to address offset 0x0180_0090 within the local register      *
+ * address space of PI0 on the node specified by the NODE field. If     *
+ * PI_ID==1, then the II sends the interrupt request to address         *
+ * offset 0x01A0_0090 within the local register address space of PI1    *
+ * on the node specified by the NODE field.                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iidsr_u {
+	shubreg_t	ii_iidsr_regval;
+	struct  {
+		shubreg_t	i_level                   :	 8;
+		shubreg_t	i_pi_id			  :	 1;
+		shubreg_t	i_node			  :	11;
+		shubreg_t       i_rsvd_3                  :      4;
+		shubreg_t	i_enable		  :	 1;
+		shubreg_t	i_rsvd_2		  :	 3;
+		shubreg_t	i_int_sent		  :	 2;
+		shubreg_t       i_rsvd_1                  :      2;
+		shubreg_t	i_pi0_forward_int	  :	 1;
+		shubreg_t	i_pi1_forward_int	  :	 1;
+		shubreg_t	i_rsvd			  :	30;
+	} ii_iidsr_fld_s;
+} ii_iidsr_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are two instances of this register. This register is used     *
+ * for matching up the incoming responses from the graphics widget to   *
+ * the processor that initiated the graphics operation. The             *
+ * write-responses are converted to graphics credits and returned to    *
+ * the processor so that the processor interface can manage the flow    *
+ * control.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_igfx0_u {
+	shubreg_t	ii_igfx0_regval;
+	struct	{
+		shubreg_t	i_w_num			  :	 4;
+		shubreg_t       i_pi_id                   :      1;
+		shubreg_t	i_n_num			  :	12;
+		shubreg_t       i_p_num                   :      1;
+		shubreg_t       i_rsvd                    :     46;
+	} ii_igfx0_fld_s;
+} ii_igfx0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are two instances of this register. This register is used     *
+ * for matching up the incoming responses from the graphics widget to   *
+ * the processor that initiated the graphics operation. The             *
+ * write-responses are converted to graphics credits and returned to    *
+ * the processor so that the processor interface can manage the flow    *
+ * control.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_igfx1_u {
+	shubreg_t	ii_igfx1_regval;
+	struct  {
+		shubreg_t	i_w_num			  :	 4;
+		shubreg_t       i_pi_id                   :      1;
+		shubreg_t	i_n_num			  :	12;
+		shubreg_t       i_p_num                   :      1;
+		shubreg_t       i_rsvd                    :     46;
+	} ii_igfx1_fld_s;
+} ii_igfx1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are two instances of this registers. These registers are      *
+ * used as scratch registers for software use.                          *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iscr0_u {
+	shubreg_t	ii_iscr0_regval;
+	struct  {
+		shubreg_t	i_scratch                 :	64;
+	} ii_iscr0_fld_s;
+} ii_iscr0_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are two instances of this registers. These registers are      *
+ * used as scratch registers for software use.                          *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iscr1_u {
+	shubreg_t	ii_iscr1_regval;
+	struct  {
+		shubreg_t	i_scratch                 :	64;
+	} ii_iscr1_fld_s;
+} ii_iscr1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the SHub is thus the lower 16 GBytes per widget       * 
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the Shub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte1_u {
+	shubreg_t	ii_itte1_regval;
+	struct  {
+		shubreg_t	i_offset                  :	 5;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t	i_w_num			  :	 4;
+		shubreg_t	i_iosp			  :	 1;
+		shubreg_t	i_rsvd			  :	51;
+	} ii_itte1_fld_s;
+} ii_itte1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the Shub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte2_u {
+	shubreg_t	ii_itte2_regval;
+	struct	{
+		shubreg_t	i_offset		  :	 5;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t	i_w_num			  :	 4;
+		shubreg_t	i_iosp			  :	 1;
+		shubreg_t       i_rsvd                    :     51;
+	} ii_itte2_fld_s;
+} ii_itte2_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the SHub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte3_u {
+	shubreg_t	ii_itte3_regval;
+	struct  {
+		shubreg_t	i_offset                  :	 5;
+		shubreg_t       i_rsvd_1                  :      3;
+		shubreg_t       i_w_num                   :      4;
+		shubreg_t       i_iosp                    :      1;
+		shubreg_t       i_rsvd                    :     51;
+	} ii_itte3_fld_s;
+} ii_itte3_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a SHub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the SHub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the SHub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte4_u {
+	shubreg_t	ii_itte4_regval;
+	struct  {
+		shubreg_t	i_offset                  :	 5;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t       i_w_num                   :      4;
+		shubreg_t       i_iosp                    :      1;
+		shubreg_t       i_rsvd                    :     51;
+	} ii_itte4_fld_s;
+} ii_itte4_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a SHub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the Shub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte5_u {
+	shubreg_t	ii_itte5_regval;
+	struct  {
+		shubreg_t	i_offset                  :	 5;
+		shubreg_t       i_rsvd_1                  :      3;
+		shubreg_t       i_w_num                   :      4;
+		shubreg_t       i_iosp                    :      1;
+		shubreg_t       i_rsvd                    :     51;
+	} ii_itte5_fld_s;
+} ii_itte5_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the Shub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte6_u {
+	shubreg_t	ii_itte6_regval;
+	struct  {
+		shubreg_t	i_offset                  :	 5;
+		shubreg_t       i_rsvd_1                  :      3;
+		shubreg_t       i_w_num                   :      4;
+		shubreg_t       i_iosp                    :      1;
+		shubreg_t       i_rsvd                    :     51;
+	} ii_itte6_fld_s;
+} ii_itte6_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the SHub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte7_u {
+	shubreg_t	ii_itte7_regval;
+	struct  {
+		shubreg_t	i_offset                  :	 5;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t       i_w_num                   :      4;
+		shubreg_t       i_iosp                    :      1;
+		shubreg_t       i_rsvd                    :     51;
+	} ii_itte7_fld_s;
+} ii_itte7_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprb0_u {
+	shubreg_t	ii_iprb0_regval;
+	struct  {
+		shubreg_t	i_c                       :	 8;
+		shubreg_t	i_na			  :	14;
+		shubreg_t       i_rsvd_2                  :      2;
+		shubreg_t	i_nb			  :	14;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_m			  :	 2;
+		shubreg_t	i_f			  :	 1;
+		shubreg_t	i_of_cnt		  :	 5;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rd_to			  :	 1;
+		shubreg_t	i_spur_wr		  :	 1;
+		shubreg_t	i_spur_rd		  :	 1;
+		shubreg_t	i_rsvd			  :	11;
+		shubreg_t	i_mult_err		  :	 1;
+	} ii_iprb0_fld_s;
+} ii_iprb0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprb8_u {
+	shubreg_t	ii_iprb8_regval;
+	struct  {
+		shubreg_t	i_c                       :	 8;
+		shubreg_t	i_na			  :	14;
+		shubreg_t       i_rsvd_2                  :      2;
+		shubreg_t	i_nb			  :	14;
+		shubreg_t       i_rsvd_1                  :      2;
+		shubreg_t       i_m                       :      2;
+		shubreg_t       i_f                       :      1;
+		shubreg_t       i_of_cnt                  :      5;
+		shubreg_t       i_error                   :      1;
+		shubreg_t       i_rd_to                   :      1;
+		shubreg_t       i_spur_wr                 :      1;
+		shubreg_t	i_spur_rd		  :	 1;
+		shubreg_t       i_rsvd                    :     11;
+		shubreg_t	i_mult_err		  :	 1;
+	} ii_iprb8_fld_s;
+} ii_iprb8_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprb9_u {
+	shubreg_t	ii_iprb9_regval;
+	struct	{
+		shubreg_t	i_c			  :	 8;
+		shubreg_t	i_na			  :	14;
+		shubreg_t	i_rsvd_2		  :	 2;
+		shubreg_t	i_nb			  :	14;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_m			  :	 2;
+		shubreg_t	i_f			  :	 1;
+		shubreg_t	i_of_cnt		  :	 5;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rd_to			  :	 1;
+		shubreg_t	i_spur_wr		  :	 1;
+		shubreg_t	i_spur_rd		  :	 1;
+		shubreg_t	i_rsvd			  :	11;
+		shubreg_t	i_mult_err		  :	 1;
+	} ii_iprb9_fld_s;
+} ii_iprb9_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.        *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ *                                                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprba_u {
+	shubreg_t	ii_iprba_regval;
+	struct  {
+		shubreg_t	i_c                       :	 8;
+		shubreg_t	i_na			  :	14;
+		shubreg_t       i_rsvd_2                  :      2;
+		shubreg_t	i_nb			  :	14;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_m			  :	 2;
+		shubreg_t	i_f			  :	 1;
+		shubreg_t	i_of_cnt		  :	 5;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rd_to			  :	 1;
+		shubreg_t	i_spur_wr		  :	 1;
+		shubreg_t	i_spur_rd		  :	 1;
+		shubreg_t	i_rsvd			  :	11;
+		shubreg_t	i_mult_err		  :	 1;
+	} ii_iprba_fld_s;
+} ii_iprba_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbb_u {
+	shubreg_t	ii_iprbb_regval;
+	struct	{
+		shubreg_t	i_c			  :	 8;
+		shubreg_t	i_na			  :	14;
+		shubreg_t	i_rsvd_2		  :	 2;
+		shubreg_t	i_nb			  :	14;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_m			  :	 2;
+		shubreg_t	i_f			  :	 1;
+		shubreg_t	i_of_cnt		  :	 5;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rd_to			  :	 1;
+		shubreg_t	i_spur_wr		  :	 1;
+		shubreg_t	i_spur_rd		  :	 1;
+		shubreg_t	i_rsvd			  :	11;
+		shubreg_t	i_mult_err		  :	 1;
+	} ii_iprbb_fld_s;
+} ii_iprbb_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbc_u {
+	shubreg_t	ii_iprbc_regval;
+	struct	{
+		shubreg_t	i_c			  :	 8;
+		shubreg_t	i_na			  :	14;
+		shubreg_t	i_rsvd_2		  :	 2;
+		shubreg_t	i_nb			  :	14;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_m			  :	 2;
+		shubreg_t	i_f			  :	 1;
+		shubreg_t	i_of_cnt		  :	 5;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rd_to			  :	 1;
+		shubreg_t	i_spur_wr		  :	 1;
+		shubreg_t	i_spur_rd		  :	 1;
+		shubreg_t	i_rsvd			  :	11;
+		shubreg_t	i_mult_err		  :	 1;
+	} ii_iprbc_fld_s;
+} ii_iprbc_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbd_u {
+	shubreg_t	ii_iprbd_regval;
+	struct	{
+		shubreg_t	i_c			  :	 8;
+		shubreg_t	i_na			  :	14;
+		shubreg_t	i_rsvd_2		  :	 2;
+		shubreg_t	i_nb			  :	14;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_m			  :	 2;
+		shubreg_t	i_f			  :	 1;
+		shubreg_t	i_of_cnt		  :	 5;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rd_to			  :	 1;
+		shubreg_t	i_spur_wr		  :	 1;
+		shubreg_t	i_spur_rd		  :	 1;
+		shubreg_t	i_rsvd			  :	11;
+		shubreg_t	i_mult_err		  :	 1;
+	} ii_iprbd_fld_s;
+} ii_iprbd_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbe_u {
+	shubreg_t	ii_iprbe_regval;
+	struct	{
+		shubreg_t	i_c			  :	 8;
+		shubreg_t	i_na			  :	14;
+		shubreg_t	i_rsvd_2		  :	 2;
+		shubreg_t	i_nb			  :	14;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_m			  :	 2;
+		shubreg_t	i_f			  :	 1;
+		shubreg_t	i_of_cnt		  :	 5;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rd_to			  :	 1;
+		shubreg_t	i_spur_wr		  :	 1;
+		shubreg_t	i_spur_rd		  :	 1;
+		shubreg_t	i_rsvd			  :	11;
+		shubreg_t	i_mult_err		  :	 1;
+	} ii_iprbe_fld_s;
+} ii_iprbe_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of Shub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbf_u {
+        shubreg_t       ii_iprbf_regval;
+        struct  {
+                shubreg_t       i_c                       :      8;
+                shubreg_t       i_na                      :     14;
+                shubreg_t       i_rsvd_2                  :      2;
+                shubreg_t       i_nb                      :     14;
+                shubreg_t       i_rsvd_1                  :      2;
+                shubreg_t       i_m                       :      2;
+                shubreg_t       i_f                       :      1;
+                shubreg_t       i_of_cnt                  :      5;
+                shubreg_t       i_error                   :      1;
+                shubreg_t       i_rd_to                   :      1;
+                shubreg_t       i_spur_wr                 :      1;
+                shubreg_t       i_spur_rd                 :      1;
+                shubreg_t       i_rsvd                    :     11;
+                shubreg_t       i_mult_err                :      1;
+        } ii_iprbe_fld_s;
+} ii_iprbf_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register specifies the timeout value to use for monitoring     *
+ * Crosstalk credits which are used outbound to Crosstalk. An           *
+ * internal counter called the Crosstalk Credit Timeout Counter         *
+ * increments every 128 II clocks. The counter starts counting          *
+ * anytime the credit count drops below a threshold, and resets to      *
+ * zero (stops counting) anytime the credit count is at or above the    *
+ * threshold. The threshold is 1 credit in direct connect mode and 2    *
+ * in Crossbow connect mode. When the internal Crosstalk Credit         *
+ * Timeout Counter reaches the value programmed in this register, a     *
+ * Crosstalk Credit Timeout has occurred. The internal counter is not   *
+ * readable from software, and stops counting at its maximum value,     *
+ * so it cannot cause more than one interrupt.                          *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ixcc_u {
+	shubreg_t	ii_ixcc_regval;
+	struct  {
+		shubreg_t	i_time_out                :	26;
+		shubreg_t	i_rsvd			  :	38;
+	} ii_ixcc_fld_s;
+} ii_ixcc_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register qualifies all the PIO and DMA            *
+ * operations launched from widget 0 towards the SHub. In               *
+ * addition, it also qualifies accesses by the BTE streams.             *
+ * The bits in each field of this register are cleared by the SHub      *
+ * upon detection of an error which requires widget 0 or the BTE        *
+ * streams to be terminated. Whether or not widget x has access         *
+ * rights to this SHub is determined by an AND of the device            *
+ * enable bit in the appropriate field of this register and bit 0 in    *
+ * the Wx_IAC field. The bits in this field are set by writing a 1 to   *
+ * them. Incoming replies from Crosstalk are not subject to this        *
+ * access control mechanism.                                            *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_imem_u {
+	shubreg_t	ii_imem_regval;
+	struct  {
+		shubreg_t	i_w0_esd                  :	 1;
+		shubreg_t	i_rsvd_3		  :	 3;
+		shubreg_t	i_b0_esd		  :	 1;
+		shubreg_t	i_rsvd_2		  :	 3;
+		shubreg_t	i_b1_esd		  :	 1;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t	i_clr_precise		  :	 1;
+		shubreg_t       i_rsvd                    :     51;
+	} ii_imem_fld_s;
+} ii_imem_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register specifies the timeout value to use for   *
+ * monitoring Crosstalk tail flits coming into the Shub in the          *
+ * TAIL_TO field. An internal counter associated with this register     *
+ * is incremented every 128 II internal clocks (7 bits). The counter    *
+ * starts counting anytime a header micropacket is received and stops   *
+ * counting (and resets to zero) any time a micropacket with a Tail     *
+ * bit is received. Once the counter reaches the threshold value        *
+ * programmed in this register, it generates an interrupt to the        *
+ * processor that is programmed into the IIDSR. The counter saturates   *
+ * (does not roll over) at its maximum value, so it cannot cause        *
+ * another interrupt until after it is cleared.                         *
+ * The register also contains the Read Response Timeout values. The     *
+ * Prescalar is 23 bits, and counts II clocks. An internal counter      *
+ * increments on every II clock and when it reaches the value in the    *
+ * Prescalar field, all IPRTE registers with their valid bits set       *
+ * have their Read Response timers bumped. Whenever any of them match   *
+ * the value in the RRSP_TO field, a Read Response Timeout has          *
+ * occurred, and error handling occurs as described in the Error        *
+ * Handling section of this document.                                   *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ixtt_u {
+	shubreg_t	ii_ixtt_regval;
+	struct  {
+		shubreg_t	i_tail_to                 :	26;
+		shubreg_t	i_rsvd_1		  :	 6;
+		shubreg_t	i_rrsp_ps		  :	23;
+		shubreg_t	i_rrsp_to		  :	 5;
+		shubreg_t	i_rsvd			  :	 4;
+	} ii_ixtt_fld_s;
+} ii_ixtt_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  Writing a 1 to the fields of this register clears the appropriate   *
+ * error bits in other areas of SHub. Note that when the                *
+ * E_PRB_x bits are used to clear error bits in PRB registers,          *
+ * SPUR_RD and SPUR_WR may persist, because they require additional     *
+ * action to clear them. See the IPRBx and IXSS Register                *
+ * specifications.                                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ieclr_u {
+	shubreg_t	ii_ieclr_regval;
+	struct  {
+		shubreg_t	i_e_prb_0                 :	 1;
+		shubreg_t	i_rsvd			  :	 7;
+		shubreg_t	i_e_prb_8		  :	 1;
+		shubreg_t	i_e_prb_9		  :	 1;
+		shubreg_t	i_e_prb_a		  :	 1;
+		shubreg_t	i_e_prb_b		  :	 1;
+		shubreg_t	i_e_prb_c		  :	 1;
+		shubreg_t	i_e_prb_d		  :	 1;
+		shubreg_t	i_e_prb_e		  :	 1;
+		shubreg_t	i_e_prb_f		  :	 1;
+		shubreg_t	i_e_crazy		  :	 1;
+		shubreg_t	i_e_bte_0		  :	 1;
+		shubreg_t	i_e_bte_1		  :	 1;
+		shubreg_t	i_reserved_1		  :	10;
+		shubreg_t	i_spur_rd_hdr		  :	 1;
+		shubreg_t	i_cam_intr_to		  :	 1;
+		shubreg_t	i_cam_overflow		  :	 1;
+		shubreg_t	i_cam_read_miss		  :	 1;
+		shubreg_t	i_ioq_rep_underflow	  :	 1;
+		shubreg_t	i_ioq_req_underflow	  :	 1;
+		shubreg_t	i_ioq_rep_overflow	  :	 1;
+		shubreg_t	i_ioq_req_overflow	  :	 1;
+		shubreg_t	i_iiq_rep_overflow	  :	 1;
+		shubreg_t	i_iiq_req_overflow	  :	 1;
+		shubreg_t	i_ii_xn_rep_cred_overflow :	 1;
+		shubreg_t	i_ii_xn_req_cred_overflow :	 1;
+		shubreg_t	i_ii_xn_invalid_cmd	  :	 1;
+		shubreg_t	i_xn_ii_invalid_cmd	  :	 1;
+		shubreg_t	i_reserved_2		  :	21;
+	} ii_ieclr_fld_s;
+} ii_ieclr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register controls both BTEs. SOFT_RESET is intended for        *
+ * recovery after an error. COUNT controls the total number of CRBs     *
+ * that both BTEs (combined) can use, which affects total BTE           *
+ * bandwidth.                                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibcr_u {
+	shubreg_t	ii_ibcr_regval;
+	struct  {
+		shubreg_t	i_count                   :	 4;
+		shubreg_t	i_rsvd_1		  :	 4;
+		shubreg_t	i_soft_reset		  :	 1;
+		shubreg_t	i_rsvd			  :	55;
+	} ii_ibcr_fld_s;
+} ii_ibcr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the header of a spurious read response       *
+ * received from Crosstalk. A spurious read response is defined as a    *
+ * read response received by II from a widget for which (1) the SIDN    *
+ * has a value between 1 and 7, inclusive (II never sends requests to   *
+ * these widgets (2) there is no valid IPRTE register which             *
+ * corresponds to the TNUM, or (3) the widget indicated in SIDN is      *
+ * not the same as the widget recorded in the IPRTE register            *
+ * referenced by the TNUM. If this condition is true, and if the        *
+ * IXSS[VALID] bit is clear, then the header of the spurious read       *
+ * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The    *
+ * errant header is thereby captured, and no further spurious read      *
+ * respones are captured until IXSS[VALID] is cleared by setting the    *
+ * appropriate bit in IECLR.Everytime a spurious read response is       *
+ * detected, the SPUR_RD bit of the PRB corresponding to the incoming   *
+ * message's SIDN field is set. This always happens, regarless of       *
+ * whether a header is captured. The programmer should check            *
+ * IXSM[SIDN] to determine which widget sent the spurious response,     *
+ * because there may be more than one SPUR_RD bit set in the PRB        *
+ * registers. The widget indicated by IXSM[SIDN] was the first          *
+ * spurious read response to be received since the last time            *
+ * IXSS[VALID] was clear. The SPUR_RD bit of the corresponding PRB      *
+ * will be set. Any SPUR_RD bits in any other PRB registers indicate    *
+ * spurious messages from other widets which were detected after the    *
+ * header was captured..                                                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ixsm_u {
+	shubreg_t	ii_ixsm_regval;
+	struct  {
+		shubreg_t	i_byte_en                 :	32;
+		shubreg_t	i_reserved		  :	 1;
+		shubreg_t	i_tag			  :	 3;
+		shubreg_t	i_alt_pactyp		  :	 4;
+		shubreg_t	i_bo			  :	 1;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_vbpm			  :	 1;
+		shubreg_t	i_gbr			  :	 1;
+		shubreg_t	i_ds			  :	 2;
+		shubreg_t	i_ct			  :	 1;
+		shubreg_t	i_tnum			  :	 5;
+		shubreg_t	i_pactyp		  :	 4;
+		shubreg_t	i_sidn			  :	 4;
+		shubreg_t	i_didn			  :	 4;
+	} ii_ixsm_fld_s;
+} ii_ixsm_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the sideband bits of a spurious read         *
+ * response received from Crosstalk.                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ixss_u {
+	shubreg_t	ii_ixss_regval;
+	struct  {
+		shubreg_t	i_sideband                :	 8;
+		shubreg_t	i_rsvd			  :	55;
+		shubreg_t	i_valid			  :	 1;
+	} ii_ixss_fld_s;
+} ii_ixss_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register enables software to access the II LLP's test port.    *
+ * Refer to the LLP 2.5 documentation for an explanation of the test    *
+ * port. Software can write to this register to program the values      *
+ * for the control fields (TestErrCapture, TestClear, TestFlit,         *
+ * TestMask and TestSeed). Similarly, software can read from this       *
+ * register to obtain the values of the test port's status outputs      *
+ * (TestCBerr, TestValid and TestData).                                 *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ilct_u {
+	shubreg_t	ii_ilct_regval;
+	struct  {
+		shubreg_t	i_test_seed               :	20;
+		shubreg_t	i_test_mask               :	 8;
+		shubreg_t	i_test_data               :	20;
+		shubreg_t	i_test_valid              :	 1;
+		shubreg_t	i_test_cberr              :	 1;
+		shubreg_t	i_test_flit               :	 3;
+		shubreg_t	i_test_clear              :	 1;
+		shubreg_t	i_test_err_capture        :	 1;
+		shubreg_t	i_rsvd                    :	 9;
+	} ii_ilct_fld_s;
+} ii_ilct_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  If the II detects an illegal incoming Duplonet packet (request or   *
+ * reply) when VALID==0 in the IIEPH1 register, then it saves the       *
+ * contents of the packet's header flit in the IIEPH1 and IIEPH2        *
+ * registers, sets the VALID bit in IIEPH1, clears the OVERRUN bit,     *
+ * and assigns a value to the ERR_TYPE field which indicates the        *
+ * specific nature of the error. The II recognizes four different       *
+ * types of errors: short request packets (ERR_TYPE==2), short reply    *
+ * packets (ERR_TYPE==3), long request packets (ERR_TYPE==4) and long   *
+ * reply packets (ERR_TYPE==5). The encodings for these types of        *
+ * errors were chosen to be consistent with the same types of errors    *
+ * indicated by the ERR_TYPE field in the LB_ERROR_HDR1 register (in    *
+ * the LB unit). If the II detects an illegal incoming Duplonet         *
+ * packet when VALID==1 in the IIEPH1 register, then it merely sets     *
+ * the OVERRUN bit to indicate that a subsequent error has happened,    *
+ * and does nothing further.                                            *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iieph1_u {
+	shubreg_t	ii_iieph1_regval;
+	struct	{
+		shubreg_t	i_command		  :	 7;
+		shubreg_t	i_rsvd_5		  :	 1;
+		shubreg_t	i_suppl			  :	14;
+		shubreg_t	i_rsvd_4		  :	 1;
+		shubreg_t	i_source		  :	14;
+		shubreg_t	i_rsvd_3		  :	 1;
+		shubreg_t	i_err_type		  :	 4;
+		shubreg_t	i_rsvd_2		  :	 4;
+		shubreg_t	i_overrun		  :	 1;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t	i_valid			  :	 1;
+		shubreg_t	i_rsvd			  :	13;
+	} ii_iieph1_fld_s;
+} ii_iieph1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register holds the Address field from the header flit of an    *
+ * incoming erroneous Duplonet packet, along with the tail bit which    *
+ * accompanied this header flit. This register is essentially an        *
+ * extension of IIEPH1. Two registers were necessary because the 64     *
+ * bits available in only a single register were insufficient to        *
+ * capture the entire header flit of an erroneous packet.               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iieph2_u {
+	shubreg_t	ii_iieph2_regval;
+	struct  {
+		shubreg_t	i_rsvd_0		  :	 3;
+		shubreg_t	i_address                 :	47;
+		shubreg_t	i_rsvd_1		  :	10;
+		shubreg_t	i_tail			  :	 1;
+		shubreg_t	i_rsvd			  :	 3;
+	} ii_iieph2_fld_s;
+} ii_iieph2_u_t;
+
+
+/******************************/
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register's value is a bit vector that guards access from SXBs  *
+ * to local registers within the II as well as to external Crosstalk    *
+ * widgets								*
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_islapr_u {
+	shubreg_t	ii_islapr_regval;
+	struct  {
+		shubreg_t	i_region		  :	64;
+	} ii_islapr_fld_s;
+} ii_islapr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  A write to this register of the 56-bit value "Pup+Bun" will cause	*
+ * the bit in the ISLAPR register corresponding to the region of the	*
+ * requestor to be set (access allowed).				(
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_islapo_u {
+	shubreg_t	ii_islapo_regval;
+	struct  {
+		shubreg_t	i_io_sbx_ovrride	  :	56;
+		shubreg_t	i_rsvd			  :	 8;
+	} ii_islapo_fld_s;
+} ii_islapo_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Determines how long the wrapper will wait aftr an interrupt is	*
+ * initially issued from the II before it times out the outstanding	*
+ * interrupt and drops it from the interrupt queue.			* 
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iwi_u {
+	shubreg_t	ii_iwi_regval;
+	struct  {
+		shubreg_t	i_prescale		  :	24;
+		shubreg_t	i_rsvd			  :	 8;
+		shubreg_t	i_timeout		  :	 8;
+		shubreg_t	i_rsvd1			  :	 8;
+		shubreg_t	i_intrpt_retry_period	  :	 8;
+		shubreg_t	i_rsvd2			  :	 8;
+	} ii_iwi_fld_s;
+} ii_iwi_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Log errors which have occurred in the II wrapper. The errors are	*
+ * cleared by writing to the IECLR register.				* 
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iwel_u {
+	shubreg_t	ii_iwel_regval;
+	struct  {
+		shubreg_t	i_intr_timed_out	  :	 1;
+		shubreg_t	i_rsvd			  :	 7;
+		shubreg_t	i_cam_overflow		  :	 1;
+		shubreg_t	i_cam_read_miss		  :	 1;
+		shubreg_t	i_rsvd1			  :	 2;
+		shubreg_t	i_ioq_rep_underflow	  :	 1;
+		shubreg_t	i_ioq_req_underflow	  :	 1;
+		shubreg_t	i_ioq_rep_overflow	  :	 1;
+		shubreg_t	i_ioq_req_overflow	  :	 1;
+		shubreg_t	i_iiq_rep_overflow	  :	 1;
+		shubreg_t	i_iiq_req_overflow	  :	 1;
+		shubreg_t	i_rsvd2			  :	 6;
+		shubreg_t	i_ii_xn_rep_cred_over_under:	 1;
+		shubreg_t	i_ii_xn_req_cred_over_under:	 1;
+		shubreg_t	i_rsvd3			  :	 6;
+		shubreg_t	i_ii_xn_invalid_cmd	  :	 1;
+		shubreg_t	i_xn_ii_invalid_cmd	  :	 1;
+		shubreg_t	i_rsvd4			  :	30;
+	} ii_iwel_fld_s;
+} ii_iwel_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Controls the II wrapper.						* 
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iwc_u {
+	shubreg_t	ii_iwc_regval;
+	struct  {
+		shubreg_t	i_dma_byte_swap		  :	 1;
+		shubreg_t	i_rsvd			  :	 3;
+		shubreg_t	i_cam_read_lines_reset	  :	 1;
+		shubreg_t	i_rsvd1			  :	 3;
+		shubreg_t	i_ii_xn_cred_over_under_log:	 1;
+		shubreg_t	i_rsvd2			  :	19;
+		shubreg_t	i_xn_rep_iq_depth	  :	 5;
+		shubreg_t	i_rsvd3			  :	 3;
+		shubreg_t	i_xn_req_iq_depth	  :	 5;
+		shubreg_t	i_rsvd4			  :	 3;
+		shubreg_t	i_iiq_depth		  :	 6;
+		shubreg_t	i_rsvd5			  :	12;
+		shubreg_t	i_force_rep_cred	  :	 1;
+		shubreg_t	i_force_req_cred	  :	 1;
+	} ii_iwc_fld_s;
+} ii_iwc_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Status in the II wrapper.						* 
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iws_u {
+	shubreg_t	ii_iws_regval;
+	struct  {
+		shubreg_t	i_xn_rep_iq_credits	  :	 5;
+		shubreg_t	i_rsvd			  :	 3;
+		shubreg_t	i_xn_req_iq_credits	  :	 5;
+		shubreg_t	i_rsvd1			  :	51;
+	} ii_iws_fld_s;
+} ii_iws_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Masks errors in the IWEL register.					*
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iweim_u {
+	shubreg_t	ii_iweim_regval;
+	struct  {
+		shubreg_t	i_intr_timed_out	  :	 1;
+		shubreg_t	i_rsvd			  :	 7;
+		shubreg_t	i_cam_overflow		  :	 1;
+		shubreg_t	i_cam_read_miss		  :	 1;
+		shubreg_t	i_rsvd1			  :	 2;
+		shubreg_t	i_ioq_rep_underflow	  :	 1;
+		shubreg_t	i_ioq_req_underflow	  :	 1;
+		shubreg_t	i_ioq_rep_overflow	  :	 1;
+		shubreg_t	i_ioq_req_overflow	  :	 1;
+		shubreg_t	i_iiq_rep_overflow	  :	 1;
+		shubreg_t	i_iiq_req_overflow	  :	 1;
+		shubreg_t	i_rsvd2			  :	 6;
+		shubreg_t	i_ii_xn_rep_cred_overflow :	 1;
+		shubreg_t	i_ii_xn_req_cred_overflow :	 1;
+		shubreg_t	i_rsvd3			  :	 6;
+		shubreg_t	i_ii_xn_invalid_cmd	  :	 1;
+		shubreg_t	i_xn_ii_invalid_cmd	  :	 1;
+		shubreg_t	i_rsvd4			  :	30;
+	} ii_iweim_fld_s;
+} ii_iweim_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  A write to this register causes a particular field in the           *
+ * corresponding widget's PRB entry to be adjusted up or down by 1.     *
+ * This counter should be used when recovering from error and reset     *
+ * conditions. Note that software would be capable of causing           *
+ * inadvertent overflow or underflow of these counters.                 *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ipca_u {
+	shubreg_t	ii_ipca_regval;
+	struct  {
+		shubreg_t	i_wid                     :	 4;
+		shubreg_t	i_adjust		  :	 1;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t	i_field			  :	 2;
+		shubreg_t	i_rsvd			  :	54;
+	} ii_ipca_fld_s;
+} ii_ipca_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+
+typedef union ii_iprte0a_u {
+	shubreg_t	ii_iprte0a_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	54;
+		shubreg_t	i_widget		  :	 4;
+		shubreg_t	i_to_cnt		  :	 5;
+		shubreg_t       i_vld                     :      1;
+	} ii_iprte0a_fld_s;
+} ii_iprte0a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte1a_u {
+	shubreg_t	ii_iprte1a_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	54;
+		shubreg_t	i_widget		  :	 4;
+		shubreg_t	i_to_cnt		  :	 5;
+		shubreg_t       i_vld                     :      1;
+	} ii_iprte1a_fld_s;
+} ii_iprte1a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte2a_u {
+	shubreg_t	ii_iprte2a_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	54;
+		shubreg_t	i_widget		  :	 4;
+		shubreg_t	i_to_cnt		  :	 5;
+		shubreg_t       i_vld                     :      1;
+	} ii_iprte2a_fld_s;
+} ii_iprte2a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte3a_u {
+	shubreg_t	ii_iprte3a_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	54;
+		shubreg_t	i_widget		  :	 4;
+		shubreg_t	i_to_cnt		  :	 5;
+		shubreg_t	i_vld			  :	 1;
+	} ii_iprte3a_fld_s;
+} ii_iprte3a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte4a_u {
+	shubreg_t	ii_iprte4a_regval;
+	struct	{
+		shubreg_t	i_rsvd_1		  :	54;
+		shubreg_t	i_widget		  :	 4;
+		shubreg_t	i_to_cnt		  :	 5;
+		shubreg_t	i_vld			  :	 1;
+	} ii_iprte4a_fld_s;
+} ii_iprte4a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte5a_u {
+	shubreg_t	ii_iprte5a_regval;
+	struct	{
+		shubreg_t	i_rsvd_1		  :	54;
+		shubreg_t	i_widget		  :	 4;
+		shubreg_t	i_to_cnt		  :	 5;
+		shubreg_t	i_vld			  :	 1;
+	} ii_iprte5a_fld_s;
+} ii_iprte5a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte6a_u {
+	shubreg_t	ii_iprte6a_regval;
+	struct	{
+		shubreg_t	i_rsvd_1		  :	54;
+		shubreg_t	i_widget		  :	 4;
+		shubreg_t	i_to_cnt		  :	 5;
+		shubreg_t	i_vld			  :	 1;
+	} ii_iprte6a_fld_s;
+} ii_iprte6a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte7a_u {
+        shubreg_t       ii_iprte7a_regval;
+        struct  {
+                shubreg_t       i_rsvd_1                  :     54;
+                shubreg_t       i_widget                  :      4;
+                shubreg_t       i_to_cnt                  :      5;
+                shubreg_t       i_vld                     :      1;
+        } ii_iprtea7_fld_s;
+} ii_iprte7a_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+
+typedef union ii_iprte0b_u {
+	shubreg_t	ii_iprte0b_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_address		  :	47;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t       i_source                  :     11;
+	} ii_iprte0b_fld_s;
+} ii_iprte0b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte1b_u {
+	shubreg_t	ii_iprte1b_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_address		  :	47;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t       i_source                  :     11;
+	} ii_iprte1b_fld_s;
+} ii_iprte1b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte2b_u {
+	shubreg_t	ii_iprte2b_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_address		  :	47;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t       i_source                  :     11;
+	} ii_iprte2b_fld_s;
+} ii_iprte2b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte3b_u {
+	shubreg_t	ii_iprte3b_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_address		  :	47;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t       i_source                  :     11;
+	} ii_iprte3b_fld_s;
+} ii_iprte3b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte4b_u {
+	shubreg_t	ii_iprte4b_regval;
+	struct	{
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_address		  :	47;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t       i_source                  :     11;
+	} ii_iprte4b_fld_s;
+} ii_iprte4b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte5b_u {
+	shubreg_t	ii_iprte5b_regval;
+	struct	{
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_address		  :	47;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t       i_source                  :     11;
+	} ii_iprte5b_fld_s;
+} ii_iprte5b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte6b_u {
+	shubreg_t	ii_iprte6b_regval;
+	struct	{
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_address		  :	47;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t       i_source                  :     11;
+
+	} ii_iprte6b_fld_s;
+} ii_iprte6b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte7b_u {
+        shubreg_t       ii_iprte7b_regval;
+        struct  {
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_address		  :	47;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t       i_source                  :     11;
+        } ii_iprte7b_fld_s;
+} ii_iprte7b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  SHub II contains a feature which did not exist in      *
+ * the Hub which automatically cleans up after a Read Response          *
+ * timeout, including deallocation of the IPRTE and recovery of IBuf    *
+ * space. The inclusion of this register in SHub is for backward        *
+ * compatibility                                                        *
+ * A write to this register causes an entry from the table of           *
+ * outstanding PIO Read Requests to be freed and returned to the        *
+ * stack of free entries. This register is used in handling the         *
+ * timeout errors that result in a PIO Reply never returning from       *
+ * Crosstalk.                                                           *
+ * Note that this register does not affect the contents of the IPRTE    *
+ * registers. The Valid bits in those registers have to be              *
+ * specifically turned off by software.                                 *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ipdr_u {
+	shubreg_t	ii_ipdr_regval;
+	struct  {
+		shubreg_t	i_te                      :	 3;
+		shubreg_t	i_rsvd_1		  :	 1;
+		shubreg_t	i_pnd			  :	 1;
+		shubreg_t	i_init_rpcnt		  :	 1;
+		shubreg_t	i_rsvd			  :	58;
+	} ii_ipdr_fld_s;
+} ii_ipdr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  A write to this register causes a CRB entry to be returned to the   *
+ * queue of free CRBs. The entry should have previously been cleared    *
+ * (mark bit) via backdoor access to the pertinent CRB entry. This      *
+ * register is used in the last step of handling the errors that are    *
+ * captured and marked in CRB entries.  Briefly: 1) first error for     *
+ * DMA write from a particular device, and first error for a            *
+ * particular BTE stream, lead to a marked CRB entry, and processor     *
+ * interrupt, 2) software reads the error information captured in the   *
+ * CRB entry, and presumably takes some corrective action, 3)           *
+ * software clears the mark bit, and finally 4) software writes to      *
+ * the ICDR register to return the CRB entry to the list of free CRB    *
+ * entries.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icdr_u {
+	shubreg_t	ii_icdr_regval;
+	struct  {
+		shubreg_t	i_crb_num                 :	 4;
+		shubreg_t	i_pnd			  :	 1;
+		shubreg_t       i_rsvd                    :     59;
+	} ii_icdr_fld_s;
+} ii_icdr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register provides debug access to two FIFOs inside of II.      *
+ * Both IOQ_MAX* fields of this register contain the instantaneous      *
+ * depth (in units of the number of available entries) of the           *
+ * associated IOQ FIFO.  A read of this register will return the        *
+ * number of free entries on each FIFO at the time of the read.  So     *
+ * when a FIFO is idle, the associated field contains the maximum       *
+ * depth of the FIFO.  This register is writable for debug reasons      *
+ * and is intended to be written with the maximum desired FIFO depth    *
+ * while the FIFO is idle. Software must assure that II is idle when    *
+ * this register is written. If there are any active entries in any     *
+ * of these FIFOs when this register is written, the results are        *
+ * undefined.                                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ifdr_u {
+	shubreg_t	ii_ifdr_regval;
+	struct  {
+		shubreg_t	i_ioq_max_rq              :	 7;
+		shubreg_t	i_set_ioq_rq		  :	 1;
+		shubreg_t	i_ioq_max_rp		  :	 7;
+		shubreg_t	i_set_ioq_rp		  :	 1;
+		shubreg_t	i_rsvd			  :	48;
+	} ii_ifdr_fld_s;
+} ii_ifdr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows the II to become sluggish in removing          *
+ * messages from its inbound queue (IIQ). This will cause messages to   *
+ * back up in either virtual channel. Disabling the "molasses" mode     *
+ * subsequently allows the II to be tested under stress. In the         *
+ * sluggish ("Molasses") mode, the localized effects of congestion      *
+ * can be observed.                                                     *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iiap_u {
+        shubreg_t       ii_iiap_regval;
+        struct  {
+                shubreg_t       i_rq_mls                  :      6;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_rp_mls		  :	 6;
+		shubreg_t       i_rsvd                    :     50;
+        } ii_iiap_fld_s;
+} ii_iiap_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows several parameters of CRB operation to be      *
+ * set. Note that writing to this register can have catastrophic side   *
+ * effects, if the CRB is not quiescent, i.e. if the CRB is             *
+ * processing protocol messages when the write occurs.                  *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icmr_u {
+	shubreg_t	ii_icmr_regval;
+	struct  {
+		shubreg_t	i_sp_msg                  :	 1;
+		shubreg_t	i_rd_hdr		  :	 1;
+		shubreg_t	i_rsvd_4		  :	 2;
+		shubreg_t	i_c_cnt			  :	 4;
+		shubreg_t	i_rsvd_3		  :	 4;
+		shubreg_t	i_clr_rqpd		  :	 1;
+		shubreg_t	i_clr_rppd		  :	 1;
+		shubreg_t	i_rsvd_2		  :	 2;
+		shubreg_t	i_fc_cnt		  :	 4;
+		shubreg_t	i_crb_vld		  :	15;
+		shubreg_t	i_crb_mark		  :	15;
+		shubreg_t	i_rsvd_1		  :	 2;
+		shubreg_t	i_precise		  :	 1;
+		shubreg_t	i_rsvd			  :	11;
+	} ii_icmr_fld_s;
+} ii_icmr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows control of the table portion of the CRB        *
+ * logic via software. Control operations from this register have       *
+ * priority over all incoming Crosstalk or BTE requests.                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iccr_u {
+	shubreg_t	ii_iccr_regval;
+	struct  {
+		shubreg_t	i_crb_num                 :	 4;
+		shubreg_t	i_rsvd_1		  :	 4;
+		shubreg_t	i_cmd			  :	 8;
+		shubreg_t	i_pending		  :	 1;
+		shubreg_t	i_rsvd			  :	47;
+	} ii_iccr_fld_s;
+} ii_iccr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows the maximum timeout value to be programmed.    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icto_u {
+	shubreg_t	ii_icto_regval;
+	struct  {
+		shubreg_t	i_timeout                 :	 8;
+		shubreg_t	i_rsvd			  :	56;
+	} ii_icto_fld_s;
+} ii_icto_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows the timeout prescalar to be programmed. An     *
+ * internal counter is associated with this register. When the          *
+ * internal counter reaches the value of the PRESCALE field, the        *
+ * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT]   *
+ * field). The internal counter resets to zero, and then continues      *
+ * counting.                                                            *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ictp_u {
+	shubreg_t	ii_ictp_regval;
+	struct  {
+		shubreg_t	i_prescale                :	24;
+		shubreg_t	i_rsvd			  :	40;
+	} ii_ictp_fld_s;
+} ii_ictp_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ * The CRB Entry registers can be conceptualized as rows and columns    *
+ * (illustrated in the table above). Each row contains the 4            *
+ * registers required for a single CRB Entry. The first doubleword      *
+ * (column) for each entry is labeled A, and the second doubleword      *
+ * (higher address) is labeled B, the third doubleword is labeled C,    *
+ * the fourth doubleword is labeled D and the fifth doubleword is       *
+ * labeled E. All CRB entries have their addresses on a quarter         *
+ * cacheline aligned boundary.                   *
+ * Upon reset, only the following fields are initialized: valid         *
+ * (VLD), priority count, timeout, timeout valid, and context valid.    *
+ * All other bits should be cleared by software before use (after       *
+ * recovering any potential error state from before the reset).         *
+ * The following four tables summarize the format for the four          *
+ * registers that are used for each ICRB# Entry.                        *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_a_u {
+	shubreg_t	ii_icrb0_a_regval;
+	struct  {
+		shubreg_t	ia_iow                    :	 1;
+		shubreg_t	ia_vld			  :	 1;
+		shubreg_t	ia_addr			  :	47;
+		shubreg_t	ia_tnum			  :	 5;
+		shubreg_t	ia_sidn			  :	 4;
+		shubreg_t       ia_rsvd                   :      6;
+	} ii_icrb0_a_fld_s;
+} ii_icrb0_a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_b_u {
+	shubreg_t	ii_icrb0_b_regval;
+	struct	{
+		shubreg_t	ib_xt_err		  :	 1;
+		shubreg_t	ib_mark			  :	 1;
+		shubreg_t	ib_ln_uce		  :	 1;
+		shubreg_t	ib_errcode		  :	 3;
+		shubreg_t	ib_error		  :	 1;
+		shubreg_t	ib_stall__bte_1		  :	 1;
+		shubreg_t	ib_stall__bte_0		  :	 1;
+		shubreg_t	ib_stall__intr		  :	 1;
+		shubreg_t	ib_stall_ib		  :	 1;
+		shubreg_t	ib_intvn		  :	 1;
+		shubreg_t	ib_wb			  :	 1;
+		shubreg_t	ib_hold			  :	 1;
+		shubreg_t	ib_ack			  :	 1;
+		shubreg_t	ib_resp			  :	 1;
+		shubreg_t	ib_ack_cnt		  :	11;
+		shubreg_t	ib_rsvd			  :	 7;
+		shubreg_t	ib_exc			  :	 5;
+		shubreg_t	ib_init			  :	 3;
+		shubreg_t	ib_imsg			  :	 8;
+		shubreg_t	ib_imsgtype		  :	 2;
+		shubreg_t	ib_use_old		  :	 1;
+		shubreg_t	ib_rsvd_1		  :	11;
+	} ii_icrb0_b_fld_s;
+} ii_icrb0_b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_c_u {
+	shubreg_t	ii_icrb0_c_regval;
+	struct	{
+		shubreg_t	ic_source		  :	15;
+		shubreg_t	ic_size			  :	 2;
+		shubreg_t	ic_ct			  :	 1;
+		shubreg_t	ic_bte_num		  :	 1;
+		shubreg_t	ic_gbr			  :	 1;
+		shubreg_t	ic_resprqd		  :	 1;
+		shubreg_t	ic_bo			  :	 1;
+		shubreg_t	ic_suppl		  :	15;
+		shubreg_t	ic_rsvd			  :	27;
+	} ii_icrb0_c_fld_s;
+} ii_icrb0_c_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_d_u {
+	shubreg_t	ii_icrb0_d_regval;
+	struct  {
+		shubreg_t	id_pa_be                  :	43;
+		shubreg_t	id_bte_op		  :	 1;
+		shubreg_t	id_pr_psc		  :	 4;
+		shubreg_t	id_pr_cnt		  :	 4;
+		shubreg_t	id_sleep		  :	 1;
+		shubreg_t	id_rsvd			  :	11;
+	} ii_icrb0_d_fld_s;
+} ii_icrb0_d_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_e_u {
+	shubreg_t	ii_icrb0_e_regval;
+	struct  {
+		shubreg_t	ie_timeout                :	 8;
+		shubreg_t	ie_context		  :	15;
+		shubreg_t	ie_rsvd			  :	 1;
+		shubreg_t	ie_tvld			  :	 1;
+		shubreg_t	ie_cvld			  :	 1;
+		shubreg_t	ie_rsvd_0		  :	38;
+	} ii_icrb0_e_fld_s;
+} ii_icrb0_e_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the lower 64 bits of the header of the       *
+ * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
+ * register is set.                                                     *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icsml_u {
+	shubreg_t	ii_icsml_regval;
+	struct  {
+		shubreg_t	i_tt_addr                 :	47;
+		shubreg_t	i_newsuppl_ex		  :	14;
+		shubreg_t	i_reserved		  :	 2;
+		shubreg_t       i_overflow                :      1;
+	} ii_icsml_fld_s;
+} ii_icsml_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the middle 64 bits of the header of the      *
+ * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
+ * register is set.                                                     *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icsmm_u {
+	shubreg_t	ii_icsmm_regval;
+	struct  {
+		shubreg_t	i_tt_ack_cnt              :	11;
+		shubreg_t	i_reserved		  :	53;
+	} ii_icsmm_fld_s;
+} ii_icsmm_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the microscopic state, all the inputs to     *
+ * the protocol table, captured with the spurious message. Valid when   *
+ * the SP_MSG bit in the ICMR register is set.                          *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icsmh_u {
+	shubreg_t	ii_icsmh_regval;
+	struct  {
+		shubreg_t	i_tt_vld                  :	 1;
+		shubreg_t	i_xerr			  :	 1;
+		shubreg_t	i_ft_cwact_o		  :	 1;
+		shubreg_t	i_ft_wact_o		  :	 1;
+		shubreg_t       i_ft_active_o             :      1;
+		shubreg_t	i_sync			  :	 1;
+		shubreg_t	i_mnusg			  :	 1;
+		shubreg_t	i_mnusz			  :	 1;
+		shubreg_t	i_plusz			  :	 1;
+		shubreg_t	i_plusg			  :	 1;
+		shubreg_t	i_tt_exc		  :	 5;
+		shubreg_t	i_tt_wb			  :	 1;
+		shubreg_t	i_tt_hold		  :	 1;
+		shubreg_t	i_tt_ack		  :	 1;
+		shubreg_t	i_tt_resp		  :	 1;
+		shubreg_t	i_tt_intvn		  :	 1;
+		shubreg_t	i_g_stall_bte1		  :	 1;
+		shubreg_t	i_g_stall_bte0		  :	 1;
+		shubreg_t	i_g_stall_il		  :	 1;
+		shubreg_t	i_g_stall_ib		  :	 1;
+		shubreg_t	i_tt_imsg		  :	 8;
+		shubreg_t	i_tt_imsgtype		  :	 2;
+		shubreg_t	i_tt_use_old		  :	 1;
+		shubreg_t	i_tt_respreqd		  :	 1;
+		shubreg_t	i_tt_bte_num		  :	 1;
+		shubreg_t	i_cbn			  :	 1;
+		shubreg_t	i_match			  :	 1;
+		shubreg_t	i_rpcnt_lt_34		  :	 1;
+		shubreg_t	i_rpcnt_ge_34		  :	 1;
+		shubreg_t	i_rpcnt_lt_18		  :	 1;
+		shubreg_t	i_rpcnt_ge_18		  :	 1;
+		shubreg_t       i_rpcnt_lt_2              :      1;
+		shubreg_t	i_rpcnt_ge_2		  :	 1;
+		shubreg_t	i_rqcnt_lt_18		  :	 1;
+		shubreg_t	i_rqcnt_ge_18		  :	 1;
+		shubreg_t	i_rqcnt_lt_2		  :	 1;
+		shubreg_t	i_rqcnt_ge_2		  :	 1;
+		shubreg_t	i_tt_device		  :	 7;
+		shubreg_t	i_tt_init		  :	 3;
+		shubreg_t	i_reserved		  :	 5;
+	} ii_icsmh_fld_s;
+} ii_icsmh_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  The Shub DEBUG unit provides a 3-bit selection signal to the        *
+ * II core and a 3-bit selection signal to the fsbclk domain in the II  *
+ * wrapper.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_idbss_u {
+	shubreg_t	ii_idbss_regval;
+	struct  {
+		shubreg_t	i_iioclk_core_submenu     :	 3;
+		shubreg_t	i_rsvd			  :	 5;
+		shubreg_t	i_fsbclk_wrapper_submenu  :	 3;
+		shubreg_t	i_rsvd_1		  :	 5;
+		shubreg_t	i_iioclk_menu		  :	 5;
+		shubreg_t	i_rsvd_2		  :	43;
+	} ii_idbss_fld_s;
+} ii_idbss_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register is used to set up the length for a       *
+ * transfer and then to monitor the progress of that transfer. This     *
+ * register needs to be initialized before a transfer is started. A     *
+ * legitimate write to this register will set the Busy bit, clear the   *
+ * Error bit, and initialize the length to the value desired.           *
+ * While the transfer is in progress, hardware will decrement the       *
+ * length field with each successful block that is copied. Once the     *
+ * transfer completes, hardware will clear the Busy bit. The length     *
+ * field will also contain the number of cache lines left to be         *
+ * transferred.                                                         *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibls0_u {
+	shubreg_t	ii_ibls0_regval;
+	struct	{
+		shubreg_t	i_length		  :	16;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t	i_busy			  :	 1;
+		shubreg_t       i_rsvd                    :     43;
+	} ii_ibls0_fld_s;
+} ii_ibls0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register should be loaded before a transfer is started. The    *
+ * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
+ * address as described in Section 1.3, Figure2 and Figure3. Since      *
+ * the bottom 7 bits of the address are always taken to be zero, BTE    *
+ * transfers are always cacheline-aligned.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibsa0_u {
+	shubreg_t	ii_ibsa0_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 7;
+		shubreg_t	i_addr			  :	42;
+		shubreg_t       i_rsvd                    :     15;
+	} ii_ibsa0_fld_s;
+} ii_ibsa0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register should be loaded before a transfer is started. The    *
+ * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
+ * address as described in Section 1.3, Figure2 and Figure3. Since      *
+ * the bottom 7 bits of the address are always taken to be zero, BTE    *
+ * transfers are always cacheline-aligned.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibda0_u {
+	shubreg_t	ii_ibda0_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 7;
+		shubreg_t	i_addr			  :	42;
+		shubreg_t	i_rsvd			  :	15;
+	} ii_ibda0_fld_s;
+} ii_ibda0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  Writing to this register sets up the attributes of the transfer     *
+ * and initiates the transfer operation. Reading this register has      *
+ * the side effect of terminating any transfer in progress. Note:       *
+ * stopping a transfer midstream could have an adverse impact on the    *
+ * other BTE. If a BTE stream has to be stopped (due to error           *
+ * handling for example), both BTE streams should be stopped and        *
+ * their transfers discarded.                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibct0_u {
+	shubreg_t	ii_ibct0_regval;
+	struct  {
+		shubreg_t	i_zerofill                :	 1;
+		shubreg_t	i_rsvd_2		  :	 3;
+		shubreg_t	i_notify		  :	 1;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t       i_poison                  :      1;
+		shubreg_t       i_rsvd                    :     55;
+	} ii_ibct0_fld_s;
+} ii_ibct0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the address to which the WINV is sent.       *
+ * This address has to be cache line aligned.                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibna0_u {
+	shubreg_t	ii_ibna0_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 7;
+		shubreg_t	i_addr			  :	42;
+		shubreg_t	i_rsvd			  :	15;
+	} ii_ibna0_fld_s;
+} ii_ibna0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the programmable level as well as the node   *
+ * ID and PI unit of the processor to which the interrupt will be       *
+ * sent.                                                                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibia0_u {
+	shubreg_t	ii_ibia0_regval;
+	struct  {
+		shubreg_t	i_rsvd_2                   :	 1;
+		shubreg_t	i_node_id		  :	11;
+		shubreg_t	i_rsvd_1		  :	 4;
+		shubreg_t	i_level			  :	 7;
+		shubreg_t       i_rsvd                    :     41;
+	} ii_ibia0_fld_s;
+} ii_ibia0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register is used to set up the length for a       *
+ * transfer and then to monitor the progress of that transfer. This     *
+ * register needs to be initialized before a transfer is started. A     *
+ * legitimate write to this register will set the Busy bit, clear the   *
+ * Error bit, and initialize the length to the value desired.           *
+ * While the transfer is in progress, hardware will decrement the       *
+ * length field with each successful block that is copied. Once the     *
+ * transfer completes, hardware will clear the Busy bit. The length     *
+ * field will also contain the number of cache lines left to be         *
+ * transferred.                                                         *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibls1_u {
+	shubreg_t	ii_ibls1_regval;
+	struct  {
+		shubreg_t	i_length                  :	16;
+		shubreg_t	i_error			  :	 1;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t	i_busy			  :	 1;
+		shubreg_t       i_rsvd                    :     43;
+	} ii_ibls1_fld_s;
+} ii_ibls1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register should be loaded before a transfer is started. The    *
+ * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
+ * address as described in Section 1.3, Figure2 and Figure3. Since      *
+ * the bottom 7 bits of the address are always taken to be zero, BTE    *
+ * transfers are always cacheline-aligned.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibsa1_u {
+	shubreg_t	ii_ibsa1_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 7;
+		shubreg_t	i_addr			  :	33;
+		shubreg_t	i_rsvd			  :	24;
+	} ii_ibsa1_fld_s;
+} ii_ibsa1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register should be loaded before a transfer is started. The    *
+ * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
+ * address as described in Section 1.3, Figure2 and Figure3. Since      *
+ * the bottom 7 bits of the address are always taken to be zero, BTE    *
+ * transfers are always cacheline-aligned.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibda1_u {
+	shubreg_t	ii_ibda1_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 7;
+		shubreg_t	i_addr			  :	33;
+		shubreg_t	i_rsvd			  :	24;
+	} ii_ibda1_fld_s;
+} ii_ibda1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  Writing to this register sets up the attributes of the transfer     *
+ * and initiates the transfer operation. Reading this register has      *
+ * the side effect of terminating any transfer in progress. Note:       *
+ * stopping a transfer midstream could have an adverse impact on the    *
+ * other BTE. If a BTE stream has to be stopped (due to error           *
+ * handling for example), both BTE streams should be stopped and        *
+ * their transfers discarded.                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibct1_u {
+	shubreg_t	ii_ibct1_regval;
+	struct  {
+		shubreg_t	i_zerofill                :	 1;
+		shubreg_t	i_rsvd_2		  :	 3;
+		shubreg_t	i_notify		  :	 1;
+		shubreg_t	i_rsvd_1		  :	 3;
+		shubreg_t	i_poison		  :	 1;
+		shubreg_t	i_rsvd			  :	55;
+	} ii_ibct1_fld_s;
+} ii_ibct1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the address to which the WINV is sent.       *
+ * This address has to be cache line aligned.                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibna1_u {
+	shubreg_t	ii_ibna1_regval;
+	struct  {
+		shubreg_t	i_rsvd_1                  :	 7;
+		shubreg_t	i_addr			  :	33;
+		shubreg_t       i_rsvd                    :     24;
+	} ii_ibna1_fld_s;
+} ii_ibna1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the programmable level as well as the node   *
+ * ID and PI unit of the processor to which the interrupt will be       *
+ * sent.                                                                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibia1_u {
+	shubreg_t	ii_ibia1_regval;
+	struct  {
+		shubreg_t	i_pi_id                   :	 1;
+		shubreg_t	i_node_id		  :	 8;
+		shubreg_t	i_rsvd_1		  :	 7;
+		shubreg_t	i_level			  :	 7;
+		shubreg_t	i_rsvd			  :	41;
+	} ii_ibia1_fld_s;
+} ii_ibia1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register defines the resources that feed information into      *
+ * the two performance counters located in the IO Performance           *
+ * Profiling Register. There are 17 different quantities that can be    *
+ * measured. Given these 17 different options, the two performance      *
+ * counters have 15 of them in common; menu selections 0 through 0xE    *
+ * are identical for each performance counter. As for the other two     *
+ * options, one is available from one performance counter and the       *
+ * other is available from the other performance counter. Hence, the    *
+ * II supports all 17*16=272 possible combinations of quantities to     *
+ * measure.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ipcr_u {
+	shubreg_t	ii_ipcr_regval;
+	struct  {
+		shubreg_t	i_ippr0_c                 :	 4;
+		shubreg_t	i_ippr1_c		  :	 4;
+		shubreg_t	i_icct			  :	 8;
+		shubreg_t       i_rsvd                    :     48;
+	} ii_ipcr_fld_s;
+} ii_ipcr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *                                                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ippr_u {
+	shubreg_t	ii_ippr_regval;
+	struct  {
+		shubreg_t	i_ippr0                   :	32;
+		shubreg_t	i_ippr1			  :	32;
+	} ii_ippr_fld_s;
+} ii_ippr_u_t;
+
+
+#endif /* __ASSEMBLY__ */
+
+/**************************************************************************
+ *                                                                        *
+ * The following defines which were not formed into structures are        *
+ * probably indentical to another register, and the name of the           *
+ * register is provided against each of these registers. This             *
+ * information needs to be checked carefully                              *
+ *                                                                        *
+ *           IIO_ICRB1_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB1_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB1_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB1_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB1_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB2_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB2_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB2_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB2_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB2_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB3_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB3_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB3_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB3_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB3_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB4_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB4_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB4_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB4_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB4_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB5_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB5_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB5_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB5_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB5_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB6_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB6_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB6_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB6_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB6_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB7_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB7_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB7_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB7_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB7_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB8_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB8_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB8_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB8_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB8_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB9_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB9_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB9_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB9_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB9_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBA_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBA_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBA_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBA_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBA_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBB_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBB_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBB_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBB_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBB_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBC_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBC_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBC_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBC_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBC_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBD_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBD_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBD_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBD_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBD_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBE_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBE_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBE_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBE_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBE_E                IIO_ICRB0_E                       *
+ *                                                                        *
+ **************************************************************************/
+
+
+/*
+ * Slightly friendlier names for some common registers.
+ */
+#define IIO_WIDGET              IIO_WID      /* Widget identification */
+#define IIO_WIDGET_STAT         IIO_WSTAT    /* Widget status register */
+#define IIO_WIDGET_CTRL         IIO_WCR      /* Widget control register */
+#define IIO_PROTECT             IIO_ILAPR    /* IO interface protection */
+#define IIO_PROTECT_OVRRD       IIO_ILAPO    /* IO protect override */
+#define IIO_OUTWIDGET_ACCESS    IIO_IOWA     /* Outbound widget access */
+#define IIO_INWIDGET_ACCESS     IIO_IIWA     /* Inbound widget access */
+#define IIO_INDEV_ERR_MASK      IIO_IIDEM    /* Inbound device error mask */
+#define IIO_LLP_CSR             IIO_ILCSR    /* LLP control and status */
+#define IIO_LLP_LOG             IIO_ILLR     /* LLP log */
+#define IIO_XTALKCC_TOUT        IIO_IXCC     /* Xtalk credit count timeout*/
+#define IIO_XTALKTT_TOUT        IIO_IXTT     /* Xtalk tail timeout */
+#define IIO_IO_ERR_CLR          IIO_IECLR    /* IO error clear */
+#define IIO_IGFX_0 		IIO_IGFX0
+#define IIO_IGFX_1 		IIO_IGFX1
+#define IIO_IBCT_0		IIO_IBCT0
+#define IIO_IBCT_1		IIO_IBCT1
+#define IIO_IBLS_0		IIO_IBLS0
+#define IIO_IBLS_1		IIO_IBLS1
+#define IIO_IBSA_0		IIO_IBSA0
+#define IIO_IBSA_1		IIO_IBSA1
+#define IIO_IBDA_0		IIO_IBDA0
+#define IIO_IBDA_1		IIO_IBDA1
+#define IIO_IBNA_0		IIO_IBNA0
+#define IIO_IBNA_1		IIO_IBNA1
+#define IIO_IBIA_0		IIO_IBIA0
+#define IIO_IBIA_1		IIO_IBIA1
+#define IIO_IOPRB_0		IIO_IPRB0
+
+#define IIO_PRTE_A(_x)		(IIO_IPRTE0_A + (8 * (_x)))
+#define IIO_PRTE_B(_x)		(IIO_IPRTE0_B + (8 * (_x)))
+#define IIO_NUM_PRTES		8	/* Total number of PRB table entries */
+#define IIO_WIDPRTE_A(x)	IIO_PRTE_A(((x) - 8)) /* widget ID to its PRTE num */
+#define IIO_WIDPRTE_B(x)	IIO_PRTE_B(((x) - 8)) /* widget ID to its PRTE num */
+
+#define IIO_NUM_IPRBS 		(9) 
+
+#define IIO_LLP_CSR_IS_UP               0x00002000
+#define IIO_LLP_CSR_LLP_STAT_MASK       0x00003000
+#define IIO_LLP_CSR_LLP_STAT_SHFT       12
+
+#define IIO_LLP_CB_MAX  0xffff	/* in ILLR CB_CNT, Max Check Bit errors */
+#define IIO_LLP_SN_MAX  0xffff	/* in ILLR SN_CNT, Max Sequence Number errors */
+
+/* key to IIO_PROTECT_OVRRD */
+#define IIO_PROTECT_OVRRD_KEY   0x53474972756c6573ull   /* "SGIrules" */
+
+/* BTE register names */
+#define IIO_BTE_STAT_0          IIO_IBLS_0   /* Also BTE length/status 0 */
+#define IIO_BTE_SRC_0           IIO_IBSA_0   /* Also BTE source address  0 */
+#define IIO_BTE_DEST_0          IIO_IBDA_0   /* Also BTE dest. address 0 */
+#define IIO_BTE_CTRL_0          IIO_IBCT_0   /* Also BTE control/terminate 0 */
+#define IIO_BTE_NOTIFY_0        IIO_IBNA_0   /* Also BTE notification 0 */
+#define IIO_BTE_INT_0           IIO_IBIA_0   /* Also BTE interrupt 0 */
+#define IIO_BTE_OFF_0           0            /* Base offset from BTE 0 regs. */
+#define IIO_BTE_OFF_1   	(IIO_IBLS_1 - IIO_IBLS_0) /* Offset from base to BTE 1 */
+
+/* BTE register offsets from base */
+#define BTEOFF_STAT             0
+#define BTEOFF_SRC              (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
+#define BTEOFF_DEST             (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
+#define BTEOFF_CTRL             (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
+#define BTEOFF_NOTIFY           (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
+#define BTEOFF_INT              (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
+
+
+/* names used in shub diags */
+#define IIO_BASE_BTE0   IIO_IBLS_0		
+#define IIO_BASE_BTE1   IIO_IBLS_1		
+
+/*
+ * Macro which takes the widget number, and returns the
+ * IO PRB address of that widget.
+ * value _x is expected to be a widget number in the range
+ * 0, 8 - 0xF
+ */
+#define IIO_IOPRB(_x)   (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
+                        (_x) : \
+                        (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
+
+
+/* GFX Flow Control Node/Widget Register */
+#define IIO_IGFX_W_NUM_BITS	4	/* size of widget num field */
+#define IIO_IGFX_W_NUM_MASK	((1<<IIO_IGFX_W_NUM_BITS)-1)
+#define IIO_IGFX_W_NUM_SHIFT	0
+#define IIO_IGFX_PI_NUM_BITS	1	/* size of PI num field */
+#define IIO_IGFX_PI_NUM_MASK	((1<<IIO_IGFX_PI_NUM_BITS)-1)
+#define IIO_IGFX_PI_NUM_SHIFT	4
+#define IIO_IGFX_N_NUM_BITS	8	/* size of node num field */
+#define IIO_IGFX_N_NUM_MASK	((1<<IIO_IGFX_N_NUM_BITS)-1)
+#define IIO_IGFX_N_NUM_SHIFT	5
+#define IIO_IGFX_P_NUM_BITS	1	/* size of processor num field */
+#define IIO_IGFX_P_NUM_MASK	((1<<IIO_IGFX_P_NUM_BITS)-1)
+#define IIO_IGFX_P_NUM_SHIFT	16
+#define IIO_IGFX_INIT(widget, pi, node, cpu)				(\
+	(((widget) & IIO_IGFX_W_NUM_MASK) << IIO_IGFX_W_NUM_SHIFT) |	 \
+	(((pi)     & IIO_IGFX_PI_NUM_MASK)<< IIO_IGFX_PI_NUM_SHIFT)|	 \
+	(((node)   & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) |	 \
+	(((cpu)    & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT))
+
+
+/* Scratch registers (all bits available) */
+#define IIO_SCRATCH_REG0        IIO_ISCR0
+#define IIO_SCRATCH_REG1        IIO_ISCR1
+#define IIO_SCRATCH_MASK        0xffffffffffffffff
+
+#define IIO_SCRATCH_BIT0_0      0x0000000000000001
+#define IIO_SCRATCH_BIT0_1      0x0000000000000002
+#define IIO_SCRATCH_BIT0_2      0x0000000000000004
+#define IIO_SCRATCH_BIT0_3      0x0000000000000008
+#define IIO_SCRATCH_BIT0_4      0x0000000000000010
+#define IIO_SCRATCH_BIT0_5      0x0000000000000020
+#define IIO_SCRATCH_BIT0_6      0x0000000000000040
+#define IIO_SCRATCH_BIT0_7      0x0000000000000080
+#define IIO_SCRATCH_BIT0_8      0x0000000000000100
+#define IIO_SCRATCH_BIT0_9      0x0000000000000200
+#define IIO_SCRATCH_BIT0_A      0x0000000000000400
+
+#define IIO_SCRATCH_BIT1_0      0x0000000000000001
+#define IIO_SCRATCH_BIT1_1      0x0000000000000002
+/* IO Translation Table Entries */
+#define IIO_NUM_ITTES   7               /* ITTEs numbered 0..6 */
+                                        /* Hw manuals number them 1..7! */
+/*
+ * IIO_IMEM Register fields.
+ */
+#define IIO_IMEM_W0ESD  0x1             /* Widget 0 shut down due to error */
+#define IIO_IMEM_B0ESD  (1 << 4)        /* BTE 0 shut down due to error */
+#define IIO_IMEM_B1ESD  (1 << 8)        /* BTE 1 Shut down due to error */
+
+/*
+ * As a permanent workaround for a bug in the PI side of the shub, we've
+ * redefined big window 7 as small window 0.
+ XXX does this still apply for SN1??
+ */
+#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
+
+/*
+ * Use the top big window as a surrogate for the first small window
+ */
+#define SWIN0_BIGWIN            HUB_NUM_BIG_WINDOW
+
+#define ILCSR_WARM_RESET        0x100
+
+/*
+ * CRB manipulation macros
+ *      The CRB macros are slightly complicated, since there are up to
+ *      four registers associated with each CRB entry.
+ */
+#define IIO_NUM_CRBS            15      /* Number of CRBs */
+#define IIO_NUM_PC_CRBS         4       /* Number of partial cache CRBs */
+#define IIO_ICRB_OFFSET         8
+#define IIO_ICRB_0              IIO_ICRB0_A
+#define IIO_ICRB_ADDR_SHFT	2	/* Shift to get proper address */
+/* XXX - This is now tuneable:
+        #define IIO_FIRST_PC_ENTRY 12
+ */
+
+#define IIO_ICRB_A(_x)  (IIO_ICRB_0 + (6 * IIO_ICRB_OFFSET * (_x)))
+#define IIO_ICRB_B(_x)  (IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET)
+#define IIO_ICRB_C(_x)  (IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET)
+#define IIO_ICRB_D(_x)  (IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET)
+#define IIO_ICRB_E(_x)  (IIO_ICRB_A(_x) + 4*IIO_ICRB_OFFSET)
+
+#define TNUM_TO_WIDGET_DEV(_tnum)	(_tnum & 0x7)
+
+/*
+ * values for "ecode" field
+ */
+#define IIO_ICRB_ECODE_DERR     0       /* Directory error due to IIO access */
+#define IIO_ICRB_ECODE_PERR     1       /* Poison error on IO access */
+#define IIO_ICRB_ECODE_WERR     2       /* Write error by IIO access
+                                         * e.g. WINV to a Read only line. */
+#define IIO_ICRB_ECODE_AERR     3       /* Access error caused by IIO access */
+#define IIO_ICRB_ECODE_PWERR    4       /* Error on partial write       */
+#define IIO_ICRB_ECODE_PRERR    5       /* Error on partial read        */
+#define IIO_ICRB_ECODE_TOUT     6       /* CRB timeout before deallocating */
+#define IIO_ICRB_ECODE_XTERR    7       /* Incoming xtalk pkt had error bit */
+
+/*
+ * Values for field imsgtype
+ */
+#define IIO_ICRB_IMSGT_XTALK    0       /* Incoming Meessage from Xtalk */
+#define IIO_ICRB_IMSGT_BTE      1       /* Incoming message from BTE    */
+#define IIO_ICRB_IMSGT_SN1NET   2       /* Incoming message from SN1 net */
+#define IIO_ICRB_IMSGT_CRB      3       /* Incoming message from CRB ???  */
+
+/*
+ * values for field initiator.
+ */
+#define IIO_ICRB_INIT_XTALK     0       /* Message originated in xtalk  */
+#define IIO_ICRB_INIT_BTE0      0x1     /* Message originated in BTE 0  */
+#define IIO_ICRB_INIT_SN1NET    0x2     /* Message originated in SN1net */
+#define IIO_ICRB_INIT_CRB       0x3     /* Message originated in CRB ?  */
+#define IIO_ICRB_INIT_BTE1      0x5     /* MEssage originated in BTE 1  */
+
+/*
+ * Number of credits Hub widget has while sending req/response to
+ * xbow.
+ * Value of 3 is required by Xbow 1.1
+ * We may be able to increase this to 4 with Xbow 1.2.
+ */
+#define       HUBII_XBOW_CREDIT       3
+#define       HUBII_XBOW_REV2_CREDIT  4
+
+/*
+ * Number of credits that xtalk devices should use when communicating
+ * with a SHub (depth of SHub's queue).
+ */
+#define HUB_CREDIT 4
+
+/*
+ * Some IIO_PRB fields
+ */
+#define IIO_PRB_MULTI_ERR	(1LL << 63)
+#define IIO_PRB_SPUR_RD		(1LL << 51)
+#define IIO_PRB_SPUR_WR		(1LL << 50)
+#define IIO_PRB_RD_TO		(1LL << 49)
+#define IIO_PRB_ERROR		(1LL << 48)
+
+/*************************************************************************
+
+ Some of the IIO field masks and shifts are defined here.
+ This is in order to maintain compatibility in SN0 and SN1 code
+ 
+**************************************************************************/
+
+/*
+ * ICMR register fields
+ * (Note: the IIO_ICMR_P_CNT and IIO_ICMR_PC_VLD from Hub are not
+ * present in SHub)
+ */
+
+#define IIO_ICMR_CRB_VLD_SHFT   20
+#define IIO_ICMR_CRB_VLD_MASK   (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
+
+#define IIO_ICMR_FC_CNT_SHFT    16
+#define IIO_ICMR_FC_CNT_MASK    (0xf << IIO_ICMR_FC_CNT_SHFT)
+
+#define IIO_ICMR_C_CNT_SHFT     4
+#define IIO_ICMR_C_CNT_MASK     (0xf << IIO_ICMR_C_CNT_SHFT)
+
+#define IIO_ICMR_PRECISE        (1UL << 52)
+#define IIO_ICMR_CLR_RPPD       (1UL << 13)
+#define IIO_ICMR_CLR_RQPD       (1UL << 12)
+
+/*
+ * IIO PIO Deallocation register field masks : (IIO_IPDR)
+ XXX present but not needed in bedrock?  See the manual.
+ */
+#define IIO_IPDR_PND    (1 << 4)
+
+/*
+ * IIO CRB deallocation register field masks: (IIO_ICDR)
+ */
+#define IIO_ICDR_PND    (1 << 4)
+
+/* 
+ * IO BTE Length/Status (IIO_IBLS) register bit field definitions
+ */
+#define IBLS_BUSY		(0x1 << 20)
+#define IBLS_ERROR_SHFT		16
+#define IBLS_ERROR		(0x1 << IBLS_ERROR_SHFT)
+#define IBLS_LENGTH_MASK	0xffff
+
+/*
+ * IO BTE Control/Terminate register (IBCT) register bit field definitions
+ */
+#define IBCT_POISON		(0x1 << 8)
+#define IBCT_NOTIFY		(0x1 << 4)
+#define IBCT_ZFIL_MODE		(0x1 << 0)
+
+/*
+ * IIO Incoming Error Packet Header (IIO_IIEPH1/IIO_IIEPH2)
+ */
+#define IIEPH1_VALID		(1 << 44)
+#define IIEPH1_OVERRUN		(1 << 40)
+#define IIEPH1_ERR_TYPE_SHFT	32
+#define IIEPH1_ERR_TYPE_MASK	0xf
+#define IIEPH1_SOURCE_SHFT	20
+#define IIEPH1_SOURCE_MASK	11
+#define IIEPH1_SUPPL_SHFT	8
+#define IIEPH1_SUPPL_MASK	11
+#define IIEPH1_CMD_SHFT		0
+#define IIEPH1_CMD_MASK		7
+
+#define IIEPH2_TAIL		(1 << 40)
+#define IIEPH2_ADDRESS_SHFT	0
+#define IIEPH2_ADDRESS_MASK	38
+
+#define IIEPH1_ERR_SHORT_REQ	2
+#define IIEPH1_ERR_SHORT_REPLY	3
+#define IIEPH1_ERR_LONG_REQ	4
+#define IIEPH1_ERR_LONG_REPLY	5
+
+/*
+ * IO Error Clear register bit field definitions
+ */
+#define IECLR_PI1_FWD_INT	(1 << 31)  /* clear PI1_FORWARD_INT in iidsr */
+#define IECLR_PI0_FWD_INT	(1 << 30)  /* clear PI0_FORWARD_INT in iidsr */
+#define IECLR_SPUR_RD_HDR	(1 << 29)  /* clear valid bit in ixss reg */
+#define IECLR_BTE1		(1 << 18)  /* clear bte error 1 */
+#define IECLR_BTE0		(1 << 17)  /* clear bte error 0 */
+#define IECLR_CRAZY		(1 << 16)  /* clear crazy bit in wstat reg */
+#define IECLR_PRB_F		(1 << 15)  /* clear err bit in PRB_F reg */
+#define IECLR_PRB_E		(1 << 14)  /* clear err bit in PRB_E reg */
+#define IECLR_PRB_D		(1 << 13)  /* clear err bit in PRB_D reg */
+#define IECLR_PRB_C		(1 << 12)  /* clear err bit in PRB_C reg */
+#define IECLR_PRB_B		(1 << 11)  /* clear err bit in PRB_B reg */
+#define IECLR_PRB_A		(1 << 10)  /* clear err bit in PRB_A reg */
+#define IECLR_PRB_9		(1 << 9)   /* clear err bit in PRB_9 reg */
+#define IECLR_PRB_8		(1 << 8)   /* clear err bit in PRB_8 reg */
+#define IECLR_PRB_0		(1 << 0)   /* clear err bit in PRB_0 reg */
+
+/*
+ * IIO CRB control register Fields: IIO_ICCR 
+ */
+#define	IIO_ICCR_PENDING	(0x10000)
+#define	IIO_ICCR_CMD_MASK	(0xFF)
+#define	IIO_ICCR_CMD_SHFT	(7)
+#define	IIO_ICCR_CMD_NOP	(0x0)	/* No Op */
+#define	IIO_ICCR_CMD_WAKE	(0x100) /* Reactivate CRB entry and process */
+#define	IIO_ICCR_CMD_TIMEOUT	(0x200)	/* Make CRB timeout & mark invalid */
+#define	IIO_ICCR_CMD_EJECT	(0x400)	/* Contents of entry written to memory 
+					 * via a WB
+					 */
+#define	IIO_ICCR_CMD_FLUSH	(0x800)
+
+/*
+ *
+ * CRB Register description.
+ *
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ *
+ * Many of the fields in CRB are status bits used by hardware
+ * for implementation of the protocol. It's very dangerous to
+ * mess around with the CRB registers.
+ *
+ * It's OK to read the CRB registers and try to make sense out of the
+ * fields in CRB.
+ *
+ * Updating CRB requires all activities in Hub IIO to be quiesced.
+ * otherwise, a write to CRB could corrupt other CRB entries.
+ * CRBs are here only as a back door peek to shub IIO's status.
+ * Quiescing implies  no dmas no PIOs
+ * either directly from the cpu or from sn0net.
+ * this is not something that can be done easily. So, AVOID updating
+ * CRBs.
+ */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Easy access macros for CRBs, all 4 registers (A-D)
+ */
+typedef ii_icrb0_a_u_t icrba_t;
+#define a_lnetuce       ii_icrb0_a_fld_s.ia_ln_uce
+#define a_mark          ii_icrb0_a_fld_s.ia_mark
+#define a_xerr          ii_icrb0_a_fld_s.ia_xt_err
+#define a_sidn          ii_icrb0_a_fld_s.ia_sidn
+#define a_tnum          ii_icrb0_a_fld_s.ia_tnum
+#define a_addr          ii_icrb0_a_fld_s.ia_addr
+#define a_valid         ii_icrb0_a_fld_s.ia_vld
+#define a_iow           ii_icrb0_a_fld_s.ia_iow
+#define a_regvalue	ii_icrb0_a_regval
+
+typedef ii_icrb0_b_u_t icrbb_t;
+#define b_error         ii_icrb0_b_fld_s.ib_error
+#define b_ecode         ii_icrb0_b_fld_s.ib_errcode
+#define b_cohtrans      ii_icrb0_b_fld_s.ib_ct
+#define b_xtsize        ii_icrb0_b_fld_s.ib_size
+#define b_source        ii_icrb0_b_fld_s.ib_source
+#define b_imsgtype      ii_icrb0_b_fld_s.ib_imsgtype
+#define b_imsg          ii_icrb0_b_fld_s.ib_imsg
+#define b_initiator     ii_icrb0_b_fld_s.ib_init
+#define b_regvalue	ii_icrb0_b_regval
+
+typedef ii_icrb0_c_u_t icrbc_t;
+#define c_btenum        ii_icrb0_c_fld_s.ic_bte_num
+#define c_pricnt        ii_icrb0_c_fld_s.ic_pr_cnt
+#define c_pripsc        ii_icrb0_c_fld_s.ic_pr_psc
+#define c_bteaddr       ii_icrb0_c_fld_s.ic_pa_be /* ic_pa_be fld has 2 names*/
+#define c_benable       ii_icrb0_c_fld_s.ic_pa_be /* ic_pa_be fld has 2 names*/
+#define c_suppl         ii_icrb0_c_fld_s.ic_suppl
+#define c_barrop        ii_icrb0_c_fld_s.ic_bo
+#define c_doresp        ii_icrb0_c_fld_s.ic_resprqd
+#define c_gbr           ii_icrb0_c_fld_s.ic_gbr
+#define c_regvalue	ii_icrb0_c_regval
+
+typedef ii_icrb0_d_u_t icrbd_t;
+#define d_bteop         ii_icrb0_d_fld_s.id_bte_op
+#define icrbd_ctxtvld   ii_icrb0_d_fld_s.id_cvld
+#define icrbd_toutvld   ii_icrb0_d_fld_s.id_tvld
+#define icrbd_context   ii_icrb0_d_fld_s.id_context
+#define d_regvalue	ii_icrb0_d_regval
+
+#endif /* __ASSEMBLY__ */
+
+/* Number of widgets supported by shub */
+#define HUB_NUM_WIDGET          9
+#define HUB_WIDGET_ID_MIN       0x8
+#define HUB_WIDGET_ID_MAX       0xf
+
+#define HUB_WIDGET_PART_NUM     0xc120
+#define MAX_HUBS_PER_XBOW       2
+
+#ifndef __ASSEMBLY__
+/* A few more #defines for backwards compatibility */
+#define iprb_t          ii_iprb0_u_t
+#define iprb_regval     ii_iprb0_regval
+#define iprb_mult_err	ii_iprb0_fld_s.i_mult_err
+#define iprb_spur_rd	ii_iprb0_fld_s.i_spur_rd
+#define iprb_spur_wr	ii_iprb0_fld_s.i_spur_wr
+#define iprb_rd_to	ii_iprb0_fld_s.i_rd_to
+#define iprb_ovflow     ii_iprb0_fld_s.i_of_cnt
+#define iprb_error      ii_iprb0_fld_s.i_error
+#define iprb_ff         ii_iprb0_fld_s.i_f
+#define iprb_mode       ii_iprb0_fld_s.i_m
+#define iprb_bnakctr    ii_iprb0_fld_s.i_nb
+#define iprb_anakctr    ii_iprb0_fld_s.i_na
+#define iprb_xtalkctr   ii_iprb0_fld_s.i_c
+#endif
+
+#define LNK_STAT_WORKING        0x2		/* LLP is working */
+
+#define IIO_WSTAT_ECRAZY        (1ULL << 32)    /* Hub gone crazy */
+#define IIO_WSTAT_TXRETRY       (1ULL << 9)     /* Hub Tx Retry timeout */
+#define IIO_WSTAT_TXRETRY_MASK  (0x7F)   /* should be 0xFF?? */
+#define IIO_WSTAT_TXRETRY_SHFT  (16)
+#define IIO_WSTAT_TXRETRY_CNT(w)        (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
+                                          IIO_WSTAT_TXRETRY_MASK)
+
+/* Number of II perf. counters we can multiplex at once */
+
+#define IO_PERF_SETS	32
+
+#if __KERNEL__
+#ifndef __ASSEMBLY__
+#include <asm/sn/alenlist.h>
+#include <asm/sn/dmamap.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/xtalk/xtalk.h>
+
+/* Bit for the widget in inbound access register */
+#define IIO_IIWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
+/* Bit for the widget in outbound access register */
+#define IIO_IOWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
+
+/* NOTE: The following define assumes that we are going to get
+ * widget numbers from 8 thru F and the device numbers within
+ * widget from 0 thru 7.
+ */
+#define IIO_IIDEM_WIDGETDEV_MASK(w, d)  ((uint64_t)(1ULL << (8 * ((w) - 8) + (d))))
+
+/* IO Interrupt Destination Register */
+#define IIO_IIDSR_SENT_SHIFT    28
+#define IIO_IIDSR_SENT_MASK     0x30000000
+#define IIO_IIDSR_ENB_SHIFT     24
+#define IIO_IIDSR_ENB_MASK      0x01000000
+#define IIO_IIDSR_NODE_SHIFT    9
+#define IIO_IIDSR_NODE_MASK     0x000ff700
+#define IIO_IIDSR_PI_ID_SHIFT   8
+#define IIO_IIDSR_PI_ID_MASK    0x00000100
+#define IIO_IIDSR_LVL_SHIFT     0
+#define IIO_IIDSR_LVL_MASK      0x000000ff
+
+/* Xtalk timeout threshhold register (IIO_IXTT) */
+#define IXTT_RRSP_TO_SHFT	55	   /* read response timeout */
+#define IXTT_RRSP_TO_MASK	(0x1FULL << IXTT_RRSP_TO_SHFT)
+#define IXTT_RRSP_PS_SHFT	32	   /* read responsed TO prescalar */
+#define IXTT_RRSP_PS_MASK	(0x7FFFFFULL << IXTT_RRSP_PS_SHFT)
+#define IXTT_TAIL_TO_SHFT	0	   /* tail timeout counter threshold */
+#define IXTT_TAIL_TO_MASK	(0x3FFFFFFULL << IXTT_TAIL_TO_SHFT)
+
+/*
+ * The IO LLP control status register and widget control register
+ */
+
+typedef union hubii_wcr_u {
+        uint64_t      wcr_reg_value;
+        struct {
+	  uint64_t	wcr_widget_id:   4,     /* LLP crossbar credit */
+			wcr_tag_mode:	 1,	/* Tag mode */
+			wcr_rsvd1:	 8,	/* Reserved */
+			wcr_xbar_crd:	 3,	/* LLP crossbar credit */
+			wcr_f_bad_pkt:	 1,	/* Force bad llp pkt enable */
+			wcr_dir_con:	 1,	/* widget direct connect */
+			wcr_e_thresh:	 5,	/* elasticity threshold */
+			wcr_rsvd:	41;	/* unused */
+        } wcr_fields_s;
+} hubii_wcr_t;
+
+#define iwcr_dir_con    wcr_fields_s.wcr_dir_con
+
+/* The structures below are defined to extract and modify the ii
+performance registers */
+
+/* io_perf_sel allows the caller to specify what tests will be
+   performed */
+
+typedef union io_perf_sel {
+        uint64_t perf_sel_reg;
+        struct {
+               uint64_t	perf_ippr0 :  4,
+				perf_ippr1 :  4,
+				perf_icct  :  8,
+				perf_rsvd  : 48;
+        } perf_sel_bits;
+} io_perf_sel_t;
+
+/* io_perf_cnt is to extract the count from the shub registers. Due to
+   hardware problems there is only one counter, not two. */
+
+typedef union io_perf_cnt {
+        uint64_t      perf_cnt;
+        struct {
+               uint64_t	perf_cnt   : 20,
+				perf_rsvd2 : 12,
+				perf_rsvd1 : 32;
+        } perf_cnt_bits;
+
+} io_perf_cnt_t;
+
+typedef union iprte_a {
+	shubreg_t	entry;
+	struct {
+		shubreg_t	i_rsvd_1                  :	 3;
+		shubreg_t	i_addr			  :	38;
+		shubreg_t	i_init			  :	 3;
+		shubreg_t	i_source		  :	 8;
+		shubreg_t	i_rsvd			  :	 2;
+		shubreg_t	i_widget		  :	 4;
+		shubreg_t	i_to_cnt		  :	 5;
+		shubreg_t       i_vld                     :      1;
+	} iprte_fields;
+} iprte_a_t;
+
+
+/* PIO MANAGEMENT */
+typedef struct hub_piomap_s *hub_piomap_t;
+
+extern hub_piomap_t
+hub_piomap_alloc(devfs_handle_t dev,      /* set up mapping for this device */
+                device_desc_t dev_desc, /* device descriptor */
+                iopaddr_t xtalk_addr,   /* map for this xtalk_addr range */
+                size_t byte_count,
+                size_t byte_count_max,  /* maximum size of a mapping */
+                unsigned flags);                /* defined in sys/pio.h */
+
+extern void hub_piomap_free(hub_piomap_t hub_piomap);
+
+extern caddr_t
+hub_piomap_addr(hub_piomap_t hub_piomap,        /* mapping resources */
+                iopaddr_t xtalk_addr,           /* map for this xtalk addr */
+                size_t byte_count);             /* map this many bytes */
+
+extern void
+hub_piomap_done(hub_piomap_t hub_piomap);
+
+extern caddr_t
+hub_piotrans_addr(      devfs_handle_t dev,       /* translate to this device */
+                        device_desc_t dev_desc, /* device descriptor */
+                        iopaddr_t xtalk_addr,   /* Crosstalk address */
+                        size_t byte_count,      /* map this many bytes */
+                        unsigned flags);        /* (currently unused) */
+
+/* DMA MANAGEMENT */
+typedef struct hub_dmamap_s *hub_dmamap_t;
+
+extern hub_dmamap_t
+hub_dmamap_alloc(       devfs_handle_t dev,       /* set up mappings for dev */
+                        device_desc_t dev_desc, /* device descriptor */
+                        size_t byte_count_max,  /* max size of a mapping */
+                        unsigned flags);        /* defined in dma.h */
+
+extern void
+hub_dmamap_free(hub_dmamap_t dmamap);
+
+extern iopaddr_t
+hub_dmamap_addr(        hub_dmamap_t dmamap,    /* use mapping resources */
+                        paddr_t paddr,          /* map for this address */
+                        size_t byte_count);     /* map this many bytes */
+
+extern alenlist_t
+hub_dmamap_list(        hub_dmamap_t dmamap,    /* use mapping resources */
+                        alenlist_t alenlist,    /* map this Addr/Length List */
+                        unsigned flags);
+
+extern void
+hub_dmamap_done(        hub_dmamap_t dmamap);   /* done w/ mapping resources */
+
+extern iopaddr_t
+hub_dmatrans_addr(      devfs_handle_t dev,       /* translate for this device */
+                        device_desc_t dev_desc, /* device descriptor */
+                        paddr_t paddr,          /* system physical address */
+                        size_t byte_count,      /* length */
+                        unsigned flags);                /* defined in dma.h */
+
+extern alenlist_t
+hub_dmatrans_list(      devfs_handle_t dev,       /* translate for this device */
+                        device_desc_t dev_desc, /* device descriptor */
+                        alenlist_t palenlist,   /* system addr/length list */
+                        unsigned flags);                /* defined in dma.h */
+
+extern void
+hub_dmamap_drain(       hub_dmamap_t map);
+
+extern void
+hub_dmaaddr_drain(      devfs_handle_t vhdl,
+                        paddr_t addr,
+                        size_t bytes);
+
+extern void
+hub_dmalist_drain(      devfs_handle_t vhdl,
+                        alenlist_t list);
+
+
+/* INTERRUPT MANAGEMENT */
+typedef struct hub_intr_s *hub_intr_t;
+
+extern hub_intr_t
+hub_intr_alloc( devfs_handle_t dev,               /* which device */
+                device_desc_t dev_desc,         /* device descriptor */
+                devfs_handle_t owner_dev);        /* owner of this interrupt */
+
+extern hub_intr_t
+hub_intr_alloc_nothd(devfs_handle_t dev,          /* which device */
+                device_desc_t dev_desc,         /* device descriptor */
+                devfs_handle_t owner_dev);        /* owner of this interrupt */
+
+extern void
+hub_intr_free(hub_intr_t intr_hdl);
+
+extern int
+hub_intr_connect(       hub_intr_t intr_hdl,    /* xtalk intr resource hndl */
+                        xtalk_intr_setfunc_t setfunc,
+                                                /* func to set intr hw */
+                        void *setfunc_arg);     /* arg to setfunc */
+
+extern void
+hub_intr_disconnect(hub_intr_t intr_hdl);
+
+extern devfs_handle_t
+hub_intr_cpu_get(hub_intr_t intr_hdl);
+
+/* CONFIGURATION MANAGEMENT */
+
+extern void
+hub_provider_startup(devfs_handle_t hub);
+
+extern void
+hub_provider_shutdown(devfs_handle_t hub);
+
+#define HUB_PIO_CONVEYOR        0x1     /* PIO in conveyor belt mode */
+#define HUB_PIO_FIRE_N_FORGET   0x2     /* PIO in fire-and-forget mode */
+
+/* Flags that make sense to hub_widget_flags_set */
+#define HUB_WIDGET_FLAGS        (                               \
+				 HUB_PIO_CONVEYOR       |       \
+				 HUB_PIO_FIRE_N_FORGET          \
+				)
+
+
+typedef int     hub_widget_flags_t;
+
+/* Set the PIO mode for a widget.  These two functions perform the
+ * same operation, but hub_device_flags_set() takes a hardware graph
+ * vertex while hub_widget_flags_set() takes a nasid and widget
+ * number.  In most cases, hub_device_flags_set() should be used.
+ */
+extern int      hub_widget_flags_set(nasid_t            nasid,
+                                     xwidgetnum_t       widget_num,
+                                     hub_widget_flags_t flags);
+
+/* Depending on the flags set take the appropriate actions */
+extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
+                                     hub_widget_flags_t flags);
+                                                    
+
+/* Error Handling. */
+extern int hub_ioerror_handler(devfs_handle_t, int, int, struct io_error_s *);
+extern int kl_ioerror_handler(cnodeid_t, cnodeid_t, cpuid_t,
+                              int, paddr_t, caddr_t, ioerror_mode_t);
+extern void hub_widget_reset(devfs_handle_t, xwidgetnum_t);
+extern int hub_error_devenable(devfs_handle_t, int, int);
+extern void hub_widgetdev_enable(devfs_handle_t, int);
+extern void hub_widgetdev_shutdown(devfs_handle_t, int);
+extern int  hub_dma_enabled(devfs_handle_t);
+
+/* hubdev */
+extern void hubdev_init(void);
+extern void hubdev_register(int (*attach_method)(devfs_handle_t));
+extern int hubdev_unregister(int (*attach_method)(devfs_handle_t));
+extern int hubdev_docallouts(devfs_handle_t hub);
+
+extern caddr_t hubdev_prombase_get(devfs_handle_t hub);
+extern cnodeid_t hubdev_cnodeid_get(devfs_handle_t hub);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _KERNEL */
+#endif /* _ASM_IA64_SN_SN2_SHUBIO_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/slotnum.h linux/include/asm-ia64/sn/sn2/slotnum.h
--- linux.orig/include/asm-ia64/sn/sn2/slotnum.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/slotnum.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,41 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1992 - 1997,2001 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_SN2_SLOTNUM_H
+#define _ASM_IA64_SN_SN2_SLOTNUM_H
+
+#define SLOTNUM_MAXLENGTH	16
+
+/*
+ * This file defines IO widget to slot/device assignments.
+ */
+
+
+/* This determines module to pnode mapping. */
+
+#define NODESLOTS_PER_MODULE		1
+#define NODESLOTS_PER_MODULE_SHFT	1
+
+#define SLOTNUM_NODE_CLASS	0x00	/* Node   */
+#define SLOTNUM_ROUTER_CLASS	0x10	/* Router */
+#define SLOTNUM_XTALK_CLASS	0x20	/* Xtalk  */
+#define SLOTNUM_MIDPLANE_CLASS	0x30	/* Midplane */
+#define SLOTNUM_XBOW_CLASS	0x40	/* Xbow  */
+#define SLOTNUM_KNODE_CLASS	0x50	/* Kego node */
+#define SLOTNUM_PCI_CLASS	0x60	/* PCI widgets on XBridge */
+#define SLOTNUM_INVALID_CLASS	0xf0	/* Invalid */
+
+#define SLOTNUM_CLASS_MASK	0xf0
+#define SLOTNUM_SLOT_MASK	0x0f
+
+#define SLOTNUM_GETCLASS(_sn)	((_sn) & SLOTNUM_CLASS_MASK)
+#define SLOTNUM_GETSLOT(_sn)	((_sn) & SLOTNUM_SLOT_MASK)
+
+
+#endif /* _ASM_IA64_SN_SN2_SLOTNUM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn2/sn_private.h linux/include/asm-ia64/sn/sn2/sn_private.h
--- linux.orig/include/asm-ia64/sn/sn2/sn_private.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn2/sn_private.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,251 @@
+/* $Id: sn_private.h,v 1.1 2002/02/28 17:31:26 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_SN2_SN_PRIVATE_H
+#define _ASM_IA64_SN_SN2_SN_PRIVATE_H
+
+#include <asm/sn/nodepda.h>
+#include <asm/sn/io.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/xtalk/xtalk_private.h>
+
+extern nasid_t master_nasid;
+
+/* promif.c */
+extern void he_arcs_set_vectors(void);
+extern void mem_init(void);
+extern void cpu_unenable(cpuid_t);
+extern nasid_t get_lowest_nasid(void);
+extern __psunsigned_t get_master_bridge_base(void);
+extern void set_master_bridge_base(void);
+extern int check_nasid_equiv(nasid_t, nasid_t);
+extern nasid_t get_console_nasid(void);
+extern char get_console_pcislot(void);
+
+extern int is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid);
+
+/* memsupport.c */
+extern void poison_state_alter_range(__psunsigned_t start, int len, int poison);
+extern int memory_present(paddr_t);
+extern int memory_read_accessible(paddr_t);
+extern int memory_write_accessible(paddr_t);
+extern void memory_set_access(paddr_t, int, int);
+extern void show_dir_state(paddr_t, void (*)(char *, ...));
+extern void check_dir_state(nasid_t, int, void (*)(char *, ...));
+extern void set_dir_owner(paddr_t, int);
+extern void set_dir_state(paddr_t, int);
+extern void set_dir_state_POISONED(paddr_t);
+extern void set_dir_state_UNOWNED(paddr_t);
+extern int is_POISONED_dir_state(paddr_t);
+extern int is_UNOWNED_dir_state(paddr_t);
+extern void get_dir_ent(paddr_t paddr, int *state,
+			uint64_t *vec_ptr, hubreg_t *elo);
+
+/* intr.c */
+extern int intr_reserve_level(cpuid_t cpu, int level, int err, devfs_handle_t owner_dev, char *name);
+extern void intr_unreserve_level(cpuid_t cpu, int level);
+extern int intr_connect_level(cpuid_t cpu, int bit, ilvl_t mask_no, 
+			intr_func_t intr_prefunc);
+extern int intr_disconnect_level(cpuid_t cpu, int bit);
+extern cpuid_t intr_heuristic(devfs_handle_t dev, device_desc_t dev_desc,
+			      int req_bit,int intr_resflags,devfs_handle_t owner_dev,
+			      char *intr_name,int *resp_bit);
+extern void intr_block_bit(cpuid_t cpu, int bit);
+extern void intr_unblock_bit(cpuid_t cpu, int bit);
+extern void setrtvector(intr_func_t);
+extern void install_cpuintr(cpuid_t cpu);
+extern void install_dbgintr(cpuid_t cpu);
+extern void install_tlbintr(cpuid_t cpu);
+extern void hub_migrintr_init(cnodeid_t /*cnode*/);
+extern int cause_intr_connect(int level, intr_func_t handler, uint intr_spl_mask);
+extern int cause_intr_disconnect(int level);
+extern void intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...));
+
+/* error_dump.c */
+extern char *hub_rrb_err_type[];
+extern char *hub_wrb_err_type[];
+
+void nmi_dump(void);
+void install_cpu_nmi_handler(int slice);
+
+/* klclock.c */
+extern void hub_rtc_init(cnodeid_t);
+
+/* bte.c */
+void bte_lateinit(void);
+void bte_wait_for_xfer_completion(void *);
+
+/* klgraph.c */
+void klhwg_add_all_nodes(devfs_handle_t);
+void klhwg_add_all_modules(devfs_handle_t);
+
+/* klidbg.c */
+void install_klidbg_functions(void);
+
+/* klnuma.c */
+extern void replicate_kernel_text(int numnodes);
+extern __psunsigned_t get_freemem_start(cnodeid_t cnode);
+extern void setup_replication_mask(int maxnodes);
+
+/* init.c */
+extern cnodeid_t get_compact_nodeid(void);	/* get compact node id */
+extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node);
+extern void init_platform_pda(cpuid_t cpu);
+extern void per_cpu_init(void);
+extern int is_fine_dirmode(void);
+extern void update_node_information(cnodeid_t);
+ 
+/* shubio.c */
+extern void hubio_init(void);
+extern void hub_merge_clean(nasid_t nasid);
+extern void hub_set_piomode(nasid_t nasid, int conveyor);
+
+/* shuberror.c */
+extern void hub_error_init(cnodeid_t);
+extern void dump_error_spool(cpuid_t cpu, void (*pf)(char *, ...));
+extern void hubni_error_handler(char *, int);
+extern int check_ni_errors(void);
+
+/* Used for debugger to signal upper software a breakpoint has taken place */
+
+extern void		*debugger_update;
+extern __psunsigned_t	debugger_stopped;
+
+/* 
+ * piomap, created by shub_pio_alloc.
+ * xtalk_info MUST BE FIRST, since this structure is cast to a
+ * xtalk_piomap_s by generic xtalk routines.
+ */
+struct hub_piomap_s {
+	struct xtalk_piomap_s	hpio_xtalk_info;/* standard crosstalk pio info */
+	devfs_handle_t		hpio_hub;	/* which shub's mapping registers are set up */
+	short			hpio_holdcnt;	/* count of current users of bigwin mapping */
+	char			hpio_bigwin_num;/* if big window map, which one */
+	int 			hpio_flags;	/* defined below */
+};
+/* hub_piomap flags */
+#define HUB_PIOMAP_IS_VALID		0x1
+#define HUB_PIOMAP_IS_BIGWINDOW		0x2
+#define HUB_PIOMAP_IS_FIXED		0x4
+
+#define	hub_piomap_xt_piomap(hp)	(&hp->hpio_xtalk_info)
+#define	hub_piomap_hub_v(hp)	(hp->hpio_hub)
+#define	hub_piomap_winnum(hp)	(hp->hpio_bigwin_num)
+
+/* 
+ * dmamap, created by shub_pio_alloc.
+ * xtalk_info MUST BE FIRST, since this structure is cast to a
+ * xtalk_dmamap_s by generic xtalk routines.
+ */
+struct hub_dmamap_s {
+	struct xtalk_dmamap_s	hdma_xtalk_info;/* standard crosstalk dma info */
+	devfs_handle_t		hdma_hub;	/* which shub we go through */
+	int			hdma_flags;	/* defined below */
+};
+/* shub_dmamap flags */
+#define HUB_DMAMAP_IS_VALID		0x1
+#define HUB_DMAMAP_USED			0x2
+#define	HUB_DMAMAP_IS_FIXED		0x4
+
+/* 
+ * interrupt handle, created by shub_intr_alloc.
+ * xtalk_info MUST BE FIRST, since this structure is cast to a
+ * xtalk_intr_s by generic xtalk routines.
+ */
+struct hub_intr_s {
+	struct xtalk_intr_s	i_xtalk_info;	/* standard crosstalk intr info */
+	ilvl_t			i_swlevel;	/* software level for blocking intr */
+	cpuid_t			i_cpuid;	/* which cpu */
+	int			i_bit;		/* which bit */
+	int			i_flags;
+};
+/* flag values */
+#define HUB_INTR_IS_ALLOCED	0x1	/* for debug: allocated */
+#define HUB_INTR_IS_CONNECTED	0x4	/* for debug: connected to a software driver */
+
+typedef struct hubinfo_s {
+	nodepda_t			*h_nodepda;	/* pointer to node's private data area */
+	cnodeid_t			h_cnodeid;	/* compact nodeid */
+	nasid_t				h_nasid;	/* nasid */
+
+	/* structures for PIO management */
+	xwidgetnum_t			h_widgetid;	/* my widget # (as viewed from xbow) */
+	struct hub_piomap_s		h_small_window_piomap[HUB_WIDGET_ID_MAX+1];
+	sv_t				h_bwwait;	/* wait for big window to free */
+	spinlock_t			h_bwlock;	/* guard big window piomap's */
+	spinlock_t			h_crblock;      /* gaurd CRB error handling */
+	int				h_num_big_window_fixed;	/* count number of FIXED maps */
+	struct hub_piomap_s		h_big_window_piomap[HUB_NUM_BIG_WINDOW];
+	hub_intr_t			hub_ii_errintr;
+} *hubinfo_t;
+
+#define hubinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
+	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t *)infoptr))
+
+#define hubinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
+	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t)infoptr)
+
+#define	hubinfo_to_hubv(hinfo, hub_v)	(hinfo->h_nodepda->node_vertex)
+
+/*
+ * Hub info PIO map access functions.
+ */
+#define	hubinfo_bwin_piomap_get(hinfo, win) 	\
+			(&hinfo->h_big_window_piomap[win])
+#define	hubinfo_swin_piomap_get(hinfo, win)	\
+			(&hinfo->h_small_window_piomap[win])
+	
+/* cpu-specific information stored under INFO_LBL_CPU_INFO */
+typedef struct cpuinfo_s {
+	cpuid_t		ci_cpuid;	/* CPU ID */
+} *cpuinfo_t;
+
+#define cpuinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
+	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t *)infoptr))
+
+#define cpuinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
+	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t)infoptr)
+
+/* Special initialization function for xswitch vertices created during startup. */
+extern void xswitch_vertex_init(devfs_handle_t xswitch);
+
+extern xtalk_provider_t hub_provider;
+
+/* du.c */
+int ducons_write(char *buf, int len);
+
+/* memerror.c */
+
+extern void install_eccintr(cpuid_t cpu);
+extern void memerror_get_stats(cnodeid_t cnode,
+			       int *bank_stats, int *bank_stats_max);
+extern void probe_md_errors(nasid_t);
+/* sysctlr.c */
+extern void sysctlr_init(void);
+extern void sysctlr_power_off(int sdonly);
+extern void sysctlr_keepalive(void);
+
+#define valid_cpuid(_x)		(((_x) >= 0) && ((_x) < maxcpus))
+
+/* Useful definitions to get the memory dimm given a physical
+ * address.
+ */
+#define paddr_dimm(_pa)		((_pa & MD_BANK_MASK) >> MD_BANK_SHFT)
+#define paddr_cnode(_pa)	(NASID_TO_COMPACT_NODEID(NASID_GET(_pa)))
+extern void membank_pathname_get(paddr_t,char *);
+
+/* To redirect the output into the error buffer */
+#define errbuf_print(_s)	printf("#%s",_s)
+
+extern void crbx(nasid_t nasid, void (*pf)(char *, ...));
+void bootstrap(void);
+
+/* sndrv.c */
+extern int sndrv_attach(devfs_handle_t vertex);
+
+#endif /* _ASM_IA64_SN_SN2_SN_PRIVATE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn_cpuid.h linux/include/asm-ia64/sn/sn_cpuid.h
--- linux.orig/include/asm-ia64/sn/sn_cpuid.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn_cpuid.h	2002-07-20 01:08:26.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
+ * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -13,8 +12,13 @@
 #define _ASM_IA64_SN_SN_CPUID_H
 
 #include <linux/config.h>
-#include <asm/processor.h>
-#include <asm/sn/mmzone_sn1.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/mmzone.h>
+#include <asm/sn/types.h>
+#include <asm/current.h>
+#include <asm/nodedata.h>
+
 
 /*
  * Functions for converting between cpuids, nodeids and NASIDs.
@@ -46,10 +50,15 @@
  *				* not real efficient - dont use in perf critical code
  *
  *         LID - processor defined register (see PRM V2).
+ *
+ *           On SN1
  *		31:24 - id   Contains the NASID
  *		23:16 - eid  Contains 0-3 to identify the cpu on the node
  *				bit 17 - synergy number
  *				bit 16 - FSB slot number 
+ *           On SN2
+ *		31:28 - id   Contains 0-3 to identify the cpu on the node
+ *		27:16 - eid  Contains the NASID
  *
  *
  *
@@ -70,15 +79,15 @@
  *                |                       |
  *             -------                 -------
  *             |     |                 |     |
- *             |  0  |                 |  1  |         SYNERGY
+ *             |  0  |                 |  1  |         SYNERGY (SN1 only)
  *             |     |                 |     |
  *             -------                 -------
  *                |                       |
  *                |                       |
  *             -------------------------------
  *             |                             |
- *             |         BEDROCK             |        NASID   (0..127)
- *             |                             |        CNODEID (0..numnodes-1)
+ *             |         BEDROCK / SHUB      |        NASID   (0..MAX_NASIDS)
+ *             |                             |        CNODEID (0..num_compact_nodes-1)
  *             |                             |
  *             |                             |
  *             -------------------------------
@@ -91,10 +100,25 @@
 #define cpu_physical_id(cpuid)			((ia64_get_lid() >> 16) & 0xffff)
 #endif
 
+#ifdef CONFIG_IA64_SGI_SN1
+/*
+ * macros for some of these exist in sn/addrs.h & sn/arch.h, etc. However, 
+ * trying #include these files here causes circular dependencies.
+ */
 #define cpu_physical_id_to_nasid(cpi)		((cpi) >> 8)
 #define cpu_physical_id_to_synergy(cpi)		(((cpi) >> 1) & 1)
 #define cpu_physical_id_to_fsb_slot(cpi)	((cpi) & 1)
 #define cpu_physical_id_to_slice(cpi)		((cpi) & 3)
+#define get_nasid()				((ia64_get_lid() >> 24))
+#define get_slice()				((ia64_get_lid() >> 16) & 3)
+#define get_node_number(addr)			(((unsigned long)(addr)>>33) & 0x7f)
+#else
+#define cpu_physical_id_to_nasid(cpi)		((cpi) &0xfff)
+#define cpu_physical_id_to_slice(cpi)		((cpi>>12) & 3)
+#define get_nasid()				((ia64_get_lid() >> 16) & 0xfff)
+#define get_slice()				((ia64_get_lid() >> 28) & 0xf)
+#define get_node_number(addr)			(((unsigned long)(addr)>>38) & 0x7ff)
+#endif
 
 /*
  * NOTE: id & eid refer to Intels definitions of the LID register
@@ -118,15 +142,12 @@
 
 
 
+#ifdef CONFIG_IA64_SGI_SN1
 /*
  * cpuid_to_fsb_slot  - convert a cpuid to the fsb slot number that it is in.
  *   (there are 2 cpus per FSB. This function returns 0 or 1)
  */
-static __inline__ int
-cpuid_to_fsb_slot(int cpuid)
-{
-	return cpu_physical_id_to_fsb_slot(cpu_physical_id(cpuid));
-}
+#define cpuid_to_fsb_slot(cpuid)	(cpu_physical_id_to_fsb_slot(cpu_physical_id(cpuid)))
 
 
 /*
@@ -134,108 +155,75 @@
  *   (there are 2 synergies per node. Function returns 0 or 1 to
  *    specify which synergy the cpu is on)
  */
-static __inline__ int
-cpuid_to_synergy(int cpuid)
-{
-	return cpu_physical_id_to_synergy(cpu_physical_id(cpuid));
-}
+#define cpuid_to_synergy(cpuid)		(cpu_physical_id_to_synergy(cpu_physical_id(cpuid)))
 
+#endif
 
 /*
  * cpuid_to_slice  - convert a cpuid to the slice that it resides on
  *  There are 4 cpus per node. This function returns 0 .. 3)
  */
-static __inline__ int
-cpuid_to_slice(int cpuid)
-{
-	return cpu_physical_id_to_slice(cpu_physical_id(cpuid));
-}
+#define cpuid_to_slice(cpuid)		(cpu_physical_id_to_slice(cpu_physical_id(cpuid)))
 
 
 /*
  * cpuid_to_nasid  - convert a cpuid to the NASID that it resides on
  */
-static __inline__ int
-cpuid_to_nasid(int cpuid)
-{
-	return cpu_physical_id_to_nasid(cpu_physical_id(cpuid));
-}
+#define cpuid_to_nasid(cpuid)		(cpu_physical_id_to_nasid(cpu_physical_id(cpuid)))
 
 
 /*
  * cpuid_to_cnodeid  - convert a cpuid to the cnode that it resides on
  */
-static __inline__ int
-cpuid_to_cnodeid(int cpuid)
-{
-	return nasid_map[cpuid_to_nasid(cpuid)];
-}
+#define cpuid_to_cnodeid(cpuid)		(local_node_data->physical_node_map[cpuid_to_nasid(cpuid)])
+
 
 /*
  * cnodeid_to_nasid - convert a cnodeid to a NASID
+ *	Macro relies on pg_data for a node being on the node itself.
+ *	Just extract the NASID from the pointer.
+ *
  */
-static __inline__ int
-cnodeid_to_nasid(int cnodeid)
-{
-	if (nasid_map[cnodeid_map[cnodeid]] != cnodeid)
-		panic("cnodeid_to_nasid, cnode = %d", cnodeid);
-	return cnodeid_map[cnodeid];
-}
+#define cnodeid_to_nasid(cnodeid)	(get_node_number(local_node_data->pg_data_ptrs[cnodeid]))
+ 
 
 /*
  * nasid_to_cnodeid - convert a NASID to a cnodeid
  */
-static __inline__ int
-nasid_to_cnodeid(int nasid)
-{
-	if (cnodeid_map[nasid_map[nasid]] != nasid)
-		panic("nasid_to_cnodeid");
-	return nasid_map[nasid];
-}
+#define nasid_to_cnodeid(nasid)		(local_node_data->physical_node_map[nasid])
 
 
 /*
  * cnode_slice_to_cpuid - convert a codeid & slice to a cpuid
  */
-static __inline__ int
-cnode_slice_to_cpuid(int cnodeid, int slice) {
-	return(id_eid_to_cpuid(cnodeid_to_nasid(cnodeid),slice));
-}
+#define cnode_slice_to_cpuid(cnodeid,slice) (id_eid_to_cpuid(cnodeid_to_nasid(cnodeid),(slice)))
+ 
 
 /*
  * cpuid_to_subnode - convert a cpuid to the subnode it resides on.
  *   slice 0 & 1 are on subnode 0
  *   slice 2 & 3 are on subnode 1.
  */
-static __inline__ int
-cpuid_to_subnode(int cpuid) {
-	int ret = cpuid_to_slice(cpuid);
-	if (ret < 2) return 0;
-	else return 1;
-}
+#define cpuid_to_subnode(cpuid)		((cpuid_to_slice(cpuid)<2) ? 0 : 1)
+ 
 
 /*
  * cpuid_to_localslice - convert a cpuid to a local slice
  *    slice 0 & 2 are local slice 0
  *    slice 1 & 3 are local slice 1
  */
-static __inline__ int
-cpuid_to_localslice(int cpuid) {
-	return(cpuid_to_slice(cpuid) & 1);
-}
-
-static __inline__ int
-cnodeid_to_cpuid(int cnode) {
-	int cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		if (cpuid_to_cnodeid(cpu) == cnode) {
-			break;
-		}
-	}
-	if (cpu == smp_num_cpus) cpu = -1;
-	return cpu;
-}
+#define cpuid_to_localslice(cpuid)	(cpuid_to_slice(cpuid) & 1)
+ 
+
+#define smp_physical_node_id()			(cpuid_to_nasid(smp_processor_id()))
+
+
+/*
+ * cnodeid_to_cpuid - convert a cnode  to a cpuid of a cpu on the node.
+ *	returns -1 if no cpus exist on the node
+ */
+extern int cnodeid_to_cpuid(int cnode);
 
 
 #endif /* _ASM_IA64_SN_SN_CPUID_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn_fru.h linux/include/asm-ia64/sn/sn_fru.h
--- linux.orig/include/asm-ia64/sn/sn_fru.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn_fru.h	2002-07-20 01:08:23.000000000 +0000
@@ -4,11 +4,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 1999-2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Patrick Gefre
+ * Copyright (C) 1992 - 1997, 1999-2001 Silicon Graphics, Inc. 
+ * All rights reserved.
  */
-#ifndef _ASM_SN_SN_FRU_H
-#define _ASM_SN_SN_FRU_H
+#ifndef _ASM_IA64_SN_SN_FRU_H
+#define _ASM_IA64_SN_SN_FRU_H
 
 #define MAX_DIMMS			8	 /* max # of dimm banks */
 #define MAX_PCIDEV			8	 /* max # of pci devices on a pci bus */
@@ -42,5 +42,5 @@
 } kf_pci_bus_t;
 
 
-#endif	/* _ASM_SN_SN_FRU_H */
+#endif /* _ASM_IA64_SN_SN_FRU_H */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn_pio_sync.h linux/include/asm-ia64/sn/sn_pio_sync.h
--- linux.orig/include/asm-ia64/sn/sn_pio_sync.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sn_pio_sync.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+#ifndef _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H
+#define _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H
+
+#include <linux/config.h>
+#ifdef CONFIG_IA64_SGI_SN2
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/sn2/addrs.h>
+#include <asm/sn/sn2/shub_mmr.h>
+#include <asm/sn/sn2/shub_mmr_t.h>
+
+/*
+ * This macro flushes all outstanding PIOs performed by this cpu to the 
+ * intended destination SHUB.  This in essence ensures that all PIO's
+ * issues by this cpu has landed at it's destination.
+ *
+ * This macro expects the caller:
+ *	1.  The thread is locked.
+ *	2.  All prior PIO operations has been fenced with __ia64_mf_a().
+ *
+ * The expectation is that get_slice() will return either 0 or 2.
+ * When we have multi-core cpu's, the expectation is get_slice() will 
+ * return either 0,1 or 2,3.
+ */
+
+#define SN_PIO_WRITE_SYNC \
+	{ \
+		volatile unsigned long sn_pio_writes_done; \
+	do { \
+		sn_pio_writes_done = (volatile unsigned long) (SH_PIO_WRITE_STATUS_0_WRITES_OK_MASK & HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(get_nasid(), (get_slice() < 2) ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ))); \
+	} while (!sn_pio_writes_done); \
+	__ia64_mf_a(); \
+	}
+#else
+
+/*
+ * For all ARCHITECTURE type, this is a NOOP.
+ */
+
+#define SN_PIO_WRITE_SYNC
+
+#endif
+
+#endif /* _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn_private.h linux/include/asm-ia64/sn/sn_private.h
--- linux.orig/include/asm-ia64/sn/sn_private.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn_private.h	2002-07-20 01:08:25.000000000 +0000
@@ -4,299 +4,20 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_PRIVATE_H
-#define _ASM_SN_PRIVATE_H
+#ifndef _ASM_IA64_SN_SN_PRIVATE_H
+#define _ASM_IA64_SN_SN_PRIVATE_H
 
+#include <linux/config.h>
 #include <asm/sn/nodepda.h>
 #include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/xtalk/xtalk_private.h>
 
-extern nasid_t master_nasid;
-
-extern hubreg_t get_region(cnodeid_t);
-extern hubreg_t	nasid_to_region(nasid_t);
-/* promif.c */
-#ifdef	LATER
-extern cpuid_t cpu_node_probe(cpumask_t *cpumask, int *numnodes);
-#endif
-extern void he_arcs_set_vectors(void);
-extern void mem_init(void);
-#ifdef	LATER
-extern int cpu_enabled(cpuid_t);
-#endif
-extern void cpu_unenable(cpuid_t);
-extern nasid_t get_lowest_nasid(void);
-extern __psunsigned_t get_master_bridge_base(void);
-extern void set_master_bridge_base(void);
-extern int check_nasid_equiv(nasid_t, nasid_t);
-extern nasid_t get_console_nasid(void);
-extern char get_console_pcislot(void);
-#ifdef	LATER
-extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-#endif
-
-extern int is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid);
-
-/* memsupport.c */
-extern void poison_state_alter_range(__psunsigned_t start, int len, int poison);
-extern int memory_present(paddr_t);
-extern int memory_read_accessible(paddr_t);
-extern int memory_write_accessible(paddr_t);
-extern void memory_set_access(paddr_t, int, int);
-extern void show_dir_state(paddr_t, void (*)(char *, ...));
-extern void check_dir_state(nasid_t, int, void (*)(char *, ...));
-extern void set_dir_owner(paddr_t, int);
-extern void set_dir_state(paddr_t, int);
-extern void set_dir_state_POISONED(paddr_t);
-extern void set_dir_state_UNOWNED(paddr_t);
-extern int is_POISONED_dir_state(paddr_t);
-extern int is_UNOWNED_dir_state(paddr_t);
-extern void get_dir_ent(paddr_t paddr, int *state,
-			uint64_t *vec_ptr, hubreg_t *elo);
-
-/* intr.c */
-#if defined(NEW_INTERRUPTS)
-extern int intr_reserve_level(cpuid_t cpu, int level, int err, devfs_handle_t owner_dev, char *name);
-extern void intr_unreserve_level(cpuid_t cpu, int level);
-extern int intr_connect_level(cpuid_t cpu, int bit, ilvl_t mask_no, 
-			intr_func_t intr_func, void *intr_arg,
-			intr_func_t intr_prefunc);
-extern int intr_disconnect_level(cpuid_t cpu, int bit);
-extern cpuid_t intr_heuristic(devfs_handle_t dev, device_desc_t dev_desc,
-			      int req_bit,int intr_resflags,devfs_handle_t owner_dev,
-			      char *intr_name,int *resp_bit);
-#endif	/* NEW_INTERRUPTS */
-extern void intr_block_bit(cpuid_t cpu, int bit);
-extern void intr_unblock_bit(cpuid_t cpu, int bit);
-extern void setrtvector(intr_func_t);
-extern void install_cpuintr(cpuid_t cpu);
-extern void install_dbgintr(cpuid_t cpu);
-extern void install_tlbintr(cpuid_t cpu);
-extern void hub_migrintr_init(cnodeid_t /*cnode*/);
-extern int cause_intr_connect(int level, intr_func_t handler, uint intr_spl_mask);
-extern int cause_intr_disconnect(int level);
-extern void intr_reserve_hardwired(cnodeid_t);
-extern void intr_clear_all(nasid_t);
-extern void intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...));
-extern int protected_broadcast(hubreg_t intrbit);
-
-/* error_dump.c */
-extern char *hub_rrb_err_type[];
-extern char *hub_wrb_err_type[];
-
-void nmi_dump(void);
-void install_cpu_nmi_handler(int slice);
-
-/* klclock.c */
-extern void hub_rtc_init(cnodeid_t);
-
-/* bte.c */
-void bte_lateinit(void);
-void bte_wait_for_xfer_completion(void *);
-
-/* klgraph.c */
-void klhwg_add_all_nodes(devfs_handle_t);
-void klhwg_add_all_modules(devfs_handle_t);
-
-/* klidbg.c */
-void install_klidbg_functions(void);
-
-/* klnuma.c */
-extern void replicate_kernel_text(int numnodes);
-extern __psunsigned_t get_freemem_start(cnodeid_t cnode);
-extern void setup_replication_mask(int maxnodes);
-
-/* init.c */
-extern cnodeid_t get_compact_nodeid(void);	/* get compact node id */
-#ifdef	LATER
-extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node);
-extern void init_platform_pda(pda_t *ppda, cpuid_t cpu);
+#if defined(CONFIG_IA64_SGI_SN1)
+#include <asm/sn/sn1/sn_private.h>
+#elif defined(CONFIG_IA64_SGI_SN2)
+#include <asm/sn/sn2/sn_private.h>
 #endif
-extern void per_cpu_init(void);
-extern void per_hub_init(cnodeid_t);
-#ifdef	LATER
-extern cpumask_t boot_cpumask;
-#endif
-extern int is_fine_dirmode(void);
-extern void update_node_information(cnodeid_t);
- 
-#ifdef	LATER
-/* clksupport.c */
-extern void early_counter_intr(eframe_t *);
-#endif
-
-/* hubio.c */
-extern void hubio_init(void);
-extern void hub_merge_clean(nasid_t nasid);
-extern void hub_set_piomode(nasid_t nasid, int conveyor);
-
-/* huberror.c */
-extern void hub_error_init(cnodeid_t);
-extern void dump_error_spool(cpuid_t cpu, void (*pf)(char *, ...));
-extern void hubni_error_handler(char *, int);
-extern int check_ni_errors(void);
-
-/* Used for debugger to signal upper software a breakpoint has taken place */
-
-extern void		*debugger_update;
-extern __psunsigned_t	debugger_stopped;
-
-/* 
- * IP27 piomap, created by hub_pio_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_piomap_s by generic xtalk routines.
- */
-struct hub_piomap_s {
-	struct xtalk_piomap_s	hpio_xtalk_info;/* standard crosstalk pio info */
-	devfs_handle_t		hpio_hub;	/* which hub's mapping registers are set up */
-	short			hpio_holdcnt;	/* count of current users of bigwin mapping */
-	char			hpio_bigwin_num;/* if big window map, which one */
-	int 			hpio_flags;	/* defined below */
-};
-/* hub_piomap flags */
-#define HUB_PIOMAP_IS_VALID		0x1
-#define HUB_PIOMAP_IS_BIGWINDOW		0x2
-#define HUB_PIOMAP_IS_FIXED		0x4
-
-#define	hub_piomap_xt_piomap(hp)	(&hp->hpio_xtalk_info)
-#define	hub_piomap_hub_v(hp)	(hp->hpio_hub)
-#define	hub_piomap_winnum(hp)	(hp->hpio_bigwin_num)
-
-#if TBD
- /* Ensure that hpio_xtalk_info is first */
- #assert (&(((struct hub_piomap_s *)0)->hpio_xtalk_info) == 0)
-#endif
-
-
-/* 
- * IP27 dmamap, created by hub_pio_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_dmamap_s by generic xtalk routines.
- */
-struct hub_dmamap_s {
-	struct xtalk_dmamap_s	hdma_xtalk_info;/* standard crosstalk dma info */
-	devfs_handle_t		hdma_hub;	/* which hub we go through */
-	int			hdma_flags;	/* defined below */
-};
-/* hub_dmamap flags */
-#define HUB_DMAMAP_IS_VALID		0x1
-#define HUB_DMAMAP_USED			0x2
-#define	HUB_DMAMAP_IS_FIXED		0x4
-
-#if TBD
- /* Ensure that hdma_xtalk_info is first */
- #assert (&(((struct hub_dmamap_s *)0)->hdma_xtalk_info) == 0)
-#endif
-
-/* 
- * IP27 interrupt handle, created by hub_intr_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_intr_s by generic xtalk routines.
- */
-struct hub_intr_s {
-	struct xtalk_intr_s	i_xtalk_info;	/* standard crosstalk intr info */
-	ilvl_t			i_swlevel;	/* software level for blocking intr */
-	cpuid_t			i_cpuid;	/* which cpu */
-	int			i_bit;		/* which bit */
-	int			i_flags;
-};
-/* flag values */
-#define HUB_INTR_IS_ALLOCED	0x1	/* for debug: allocated */
-#define HUB_INTR_IS_CONNECTED	0x4	/* for debug: connected to a software driver */
-
-#if TBD
- /* Ensure that i_xtalk_info is first */
- #assert (&(((struct hub_intr_s *)0)->i_xtalk_info) == 0)
-#endif
-
-
-/* IP27 hub-specific information stored under INFO_LBL_HUB_INFO */
-/* TBD: IP27-dependent stuff currently in nodepda.h should be here */
-typedef struct hubinfo_s {
-	nodepda_t			*h_nodepda;	/* pointer to node's private data area */
-	cnodeid_t			h_cnodeid;	/* compact nodeid */
-	nasid_t				h_nasid;	/* nasid */
-
-	/* structures for PIO management */
-	xwidgetnum_t			h_widgetid;	/* my widget # (as viewed from xbow) */
-	struct hub_piomap_s		h_small_window_piomap[HUB_WIDGET_ID_MAX+1];
-	sv_t				h_bwwait;	/* wait for big window to free */
-	spinlock_t			h_bwlock;	/* guard big window piomap's */
-	spinlock_t			h_crblock;      /* gaurd CRB error handling */
-	int				h_num_big_window_fixed;	/* count number of FIXED maps */
-	struct hub_piomap_s		h_big_window_piomap[HUB_NUM_BIG_WINDOW];
-	hub_intr_t			hub_ii_errintr;
-} *hubinfo_t;
-
-#define hubinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
-	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t *)infoptr))
-
-#define hubinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
-	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t)infoptr)
-
-#define	hubinfo_to_hubv(hinfo, hub_v)	(hinfo->h_nodepda->node_vertex)
-
-/*
- * Hub info PIO map access functions.
- */
-#define	hubinfo_bwin_piomap_get(hinfo, win) 	\
-			(&hinfo->h_big_window_piomap[win])
-#define	hubinfo_swin_piomap_get(hinfo, win)	\
-			(&hinfo->h_small_window_piomap[win])
-	
-/* IP27 cpu-specific information stored under INFO_LBL_CPU_INFO */
-/* TBD: IP27-dependent stuff currently in pda.h should be here */
-typedef struct cpuinfo_s {
-#ifdef	LATER
-	pda_t		*ci_cpupda;	/* pointer to CPU's private data area */
-#endif
-	cpuid_t		ci_cpuid;	/* CPU ID */
-} *cpuinfo_t;
-
-#define cpuinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
-	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t *)infoptr))
-
-#define cpuinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
-	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t)infoptr)
-
-/* Special initialization function for xswitch vertices created during startup. */
-extern void xswitch_vertex_init(devfs_handle_t xswitch);
-
-extern xtalk_provider_t hub_provider;
-
-/* du.c */
-int ducons_write(char *buf, int len);
-
-/* memerror.c */
-
-extern void install_eccintr(cpuid_t cpu);
-extern void memerror_get_stats(cnodeid_t cnode,
-			       int *bank_stats, int *bank_stats_max);
-extern void probe_md_errors(nasid_t);
-/* sysctlr.c */
-extern void sysctlr_init(void);
-extern void sysctlr_power_off(int sdonly);
-extern void sysctlr_keepalive(void);
-
-#define valid_cpuid(_x)		(((_x) >= 0) && ((_x) < maxcpus))
-
-/* Useful definitions to get the memory dimm given a physical
- * address.
- */
-#define paddr_dimm(_pa)		((_pa & MD_BANK_MASK) >> MD_BANK_SHFT)
-#define paddr_cnode(_pa)	(NASID_TO_COMPACT_NODEID(NASID_GET(_pa)))
-extern void membank_pathname_get(paddr_t,char *);
-
-/* To redirect the output into the error buffer */
-#define errbuf_print(_s)	printf("#%s",_s)
-
-extern void crbx(nasid_t nasid, void (*pf)(char *, ...));
-void bootstrap(void);
-
-/* sndrv.c */
-extern int sndrv_attach(devfs_handle_t vertex);
 
-#endif /* _ASM_SN_PRIVATE_H */
+#endif /* _ASM_IA64_SN_SN_PRIVATE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sn_sal.h linux/include/asm-ia64/sn/sn_sal.h
--- linux.orig/include/asm-ia64/sn/sn_sal.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sn_sal.h	2002-07-20 01:08:37.000000000 +0000
@@ -1,25 +1,157 @@
-#ifndef _ASM_IA64_SN_SAL_H
-#define _ASM_IA64_SN_SAL_H
+#ifndef _ASM_IA64_SN_SN_SAL_H
+#define _ASM_IA64_SN_SN_SAL_H
 
 /*
  * System Abstraction Layer definitions for IA64
  *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * Copyright (C) 2000, Silicon Graphics.
- * Copyright (C) 2000. Jack Steiner (steiner@sgi.com)
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
 #include <asm/sal.h>
+#include <asm/sn/sn_cpuid.h>
 
 
 // SGI Specific Calls
 #define  SN_SAL_POD_MODE                           0x02000001
 #define  SN_SAL_SYSTEM_RESET                       0x02000002
 #define  SN_SAL_PROBE                              0x02000003
+#define  SN_SAL_GET_CONSOLE_NASID                  0x02000004
+#define	 SN_SAL_GET_KLCONFIG_ADDR		   0x02000005
+#define  SN_SAL_LOG_CE				   0x02000006
+#define  SN_SAL_REGISTER_CE			   0x02000007
+#define  SN_SAL_CONSOLE_PUTC                       0x02000021
+#define  SN_SAL_CONSOLE_GETC                       0x02000022
+#define  SN_SAL_CONSOLE_PUTS                       0x02000023
+#define  SN_SAL_CONSOLE_GETS                       0x02000024
+#define  SN_SAL_CONSOLE_GETS_TIMEOUT               0x02000025
+#define  SN_SAL_CONSOLE_POLL                       0x02000026
+#define  SN_SAL_CONSOLE_INTR                       0x02000027
+
+/*
+ * Service-specific constants
+ */
+#define SAL_CONSOLE_INTR_IN     0       /* manipulate input interrupts */
+#define SAL_CONSOLE_INTR_OUT    1       /* manipulate output low-water
+                                         * interrupts
+                                         */
+#define SAL_CONSOLE_INTR_OFF    0       /* turn the interrupt off */
+#define SAL_CONSOLE_INTR_ON     1       /* turn the interrupt on */
+
+
 
 
 u64 ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr);
 
+/*
+ * Returns the master console nasid, if the call fails, return an illegal
+ * value.
+ */
+static inline u64
+ia64_sn_get_console_nasid(void)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = (uint64_t)0;
+	ret_stuff.v0 = (uint64_t)0;
+	ret_stuff.v1 = (uint64_t)0;
+	ret_stuff.v2 = (uint64_t)0;
+	SAL_CALL(ret_stuff, SN_SAL_GET_CONSOLE_NASID, 0, 0, 0, 0, 0, 0, 0);
+
+	if (ret_stuff.status < 0)
+		return ret_stuff.status;
+
+	/* Master console nasid is in 'v0' */
+	return ret_stuff.v0;
+}
+
+static inline u64
+ia64_sn_get_klconfig_addr(nasid_t nasid)
+{
+	struct ia64_sal_retval ret_stuff;
+	extern u64 klgraph_addr[];
+	int cnodeid;
+
+	cnodeid = nasid_to_cnodeid(nasid);
+	if (klgraph_addr[cnodeid] == 0) {
+		ret_stuff.status = (uint64_t)0;
+		ret_stuff.v0 = (uint64_t)0;
+		ret_stuff.v1 = (uint64_t)0;
+		ret_stuff.v2 = (uint64_t)0;
+		SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
+
+		/*
+	 	* We should panic if a valid cnode nasid does not produce
+	 	* a klconfig address.
+	 	*/
+		if (ret_stuff.status != 0) {
+			panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status);
+		}
+
+		klgraph_addr[cnodeid] = ret_stuff.v0;
+	}
+	return(klgraph_addr[cnodeid]);
+}
+
+/*
+ * Returns the next console character.
+ */
+static inline u64
+ia64_sn_console_getc(int *ch)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = (uint64_t)0;
+	ret_stuff.v0 = (uint64_t)0;
+	ret_stuff.v1 = (uint64_t)0;
+	ret_stuff.v2 = (uint64_t)0;
+	SAL_CALL(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
+
+	/* character is in 'v0' */
+	*ch = (int)ret_stuff.v0;
+
+	return ret_stuff.status;
+}
+
+/*
+ * Sends the given character to the console.
+ */
+static inline u64
+ia64_sn_console_putc(char ch)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = (uint64_t)0;
+	ret_stuff.v0 = (uint64_t)0;
+	ret_stuff.v1 = (uint64_t)0;
+	ret_stuff.v2 = (uint64_t)0;
+	SAL_CALL(ret_stuff, SN_SAL_CONSOLE_PUTC, (uint64_t)ch, 0, 0, 0, 0, 0, 0);
+
+	return ret_stuff.status;
+}
+
+/*
+ * Checks for console input.
+ */
+static inline u64
+ia64_sn_console_check(int *result)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = (uint64_t)0;
+	ret_stuff.v0 = (uint64_t)0;
+	ret_stuff.v1 = (uint64_t)0;
+	ret_stuff.v2 = (uint64_t)0;
+	SAL_CALL(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
+
+	/* result is in 'v0' */
+	*result = (int)ret_stuff.v0;
+
+	return ret_stuff.status;
+}
 
-#endif /* _ASM_IA64_SN_SN1_SAL_H */
+#endif /* _ASM_IA64_SN_SN_SAL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/snconfig.h linux/include/asm-ia64/sn/snconfig.h
--- linux.orig/include/asm-ia64/sn/snconfig.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/snconfig.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,18 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_IA64_SN_SNCONFIG_H
+#define _ASM_IA64_SN_SNCONFIG_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_IA64_SGI_SN1)
+#include <asm/sn/sn1/ip27config.h>
+#elif defined(CONFIG_IA64_SGI_SN2)
+#endif
+
+#endif /* _ASM_IA64_SN_SNCONFIG_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sndrv.h linux/include/asm-ia64/sn/sndrv.h
--- linux.orig/include/asm-ia64/sn/sndrv.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/sndrv.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,39 @@
+#ifndef _ASM_IA64_SN_SNDRV_H
+#define _ASM_IA64_SN_SNDRV_H
+
+/* ioctl commands */
+#define SNDRV_GET_ROUTERINFO		1
+#define SNDRV_GET_INFOSIZE		2
+#define SNDRV_GET_HUBINFO		3
+#define SNDRV_GET_FLASHLOGSIZE		4
+#define SNDRV_SET_FLASHSYNC		5
+#define SNDRV_GET_FLASHLOGDATA		6
+#define SNDRV_GET_FLASHLOGALL		7
+
+#define SNDRV_SET_HISTOGRAM_TYPE	14
+
+#define SNDRV_ELSC_COMMAND		19
+#define	SNDRV_CLEAR_LOG			20
+#define	SNDRV_INIT_LOG			21
+#define	SNDRV_GET_PIMM_PSC		22
+#define SNDRV_SET_PARTITION		23
+#define SNDRV_GET_PARTITION		24
+
+/* see synergy_perf_ioctl() */
+#define SNDRV_GET_SYNERGY_VERSION	30
+#define SNDRV_GET_SYNERGY_STATUS	31
+#define SNDRV_GET_SYNERGYINFO		32
+#define SNDRV_SYNERGY_APPEND		33
+#define SNDRV_SYNERGY_ENABLE		34
+#define SNDRV_SYNERGY_FREQ		35
+
+/* Devices */
+#define SNDRV_UKNOWN_DEVICE		-1
+#define SNDRV_ROUTER_DEVICE		1
+#define SNDRV_HUB_DEVICE		2
+#define SNDRV_ELSC_NVRAM_DEVICE		3
+#define SNDRV_ELSC_CONTROLLER_DEVICE	4
+#define SNDRV_SYSCTL_SUBCH		5
+#define SNDRV_SYNERGY_DEVICE		6
+
+#endif /* _ASM_IA64_SN_SNDRV_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/sv.h linux/include/asm-ia64/sn/sv.h
--- linux.orig/include/asm-ia64/sn/sv.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/sv.h	2002-07-20 01:08:28.000000000 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 Silicon Graphics, Inc.  All rights reserved
+ * Copyright (C) 2000-2001 Silicon Graphics, Inc.  All rights reserved
  *
  * This implemenation of synchronization variables is heavily based on
  * one done by Steve Lord <lord@sgi.com>
@@ -11,8 +11,8 @@
  * Paul Cassella <pwc@sgi.com>
  */
 
-#ifndef SV_H
-#define SV_H
+#ifndef _ASM_IA64_SN_SV_H
+#define _ASM_IA64_SN_SV_H
 
 #include <linux/spinlock.h>
 #include <asm/semaphore.h>
@@ -150,4 +150,4 @@
 #undef _SV_ASSERT
 #endif
 
-#endif
+#endif /* _ASM_IA64_SN_SV_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/synergy.h linux/include/asm-ia64/sn/synergy.h
--- linux.orig/include/asm-ia64/sn/synergy.h	2001-04-12 19:16:36.000000000 +0000
+++ linux/include/asm-ia64/sn/synergy.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,168 +0,0 @@
-#ifndef ASM_IA64_SN_SYNERGY_H
-#define ASM_IA64_SN_SYNERGY_H
-
-#include <linux/config.h>
-
-#include "asm/io.h"
-#include "asm/sn/nodepda.h"
-#include "asm/sn/intr_public.h"
-
-
-/*
- * Definitions for the synergy asic driver
- * 
- * These are for SGI platforms only.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc
- * Copyright (C) 2000 Alan Mayer (ajm@sgi.com)
- */
-
-
-#define SSPEC_BASE	(0xe0000000000)
-#define LB_REG_BASE	(SSPEC_BASE + 0x0)
-
-#define VEC_MASK3A_ADDR	(0x2a0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK3B_ADDR	(0x2a8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK3A	(0x2a0)
-#define VEC_MASK3B	(0x2a8)
-
-#define VEC_MASK2A_ADDR	(0x2b0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK2B_ADDR	(0x2b8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK2A	(0x2b0)
-#define VEC_MASK2B	(0x2b8)
-
-#define VEC_MASK1A_ADDR	(0x2c0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK1B_ADDR	(0x2c8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK1A	(0x2c0)
-#define VEC_MASK1B	(0x2c8)
-
-#define VEC_MASK0A_ADDR	(0x2d0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK0B_ADDR	(0x2d8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK0A	(0x2d0)
-#define VEC_MASK0B	(0x2d8)
-
-#define WRITE_LOCAL_SYNERGY_REG(addr, value)	__synergy_out(addr, value)
-
-#define HUBREG_CAST             (volatile hubreg_t *)
-#define HUB_L(_a)               *(_a)
-#define HUB_S(_a, _d)           *(_a) = (_d)
-
-#define HSPEC_SYNERGY0_0        0x04000000    /* Synergy0 Registers     */
-#define HSPEC_SYNERGY1_0        0x05000000    /* Synergy1 Registers     */
-#define HS_SYNERGY_STRIDE       (HSPEC_SYNERGY1_0 - HSPEC_SYNERGY0_0)
-#define REMOTE_HSPEC(_n, _x)    (HUBREG_CAST (RREG_BASE(_n) + (_x)))
-
-#define RREG_BASE(_n)           (NODE_LREG_BASE(_n))
-#define NODE_LREG_BASE(_n)      (NODE_HSPEC_BASE(_n) + 0x30000000)
-#define NODE_HSPEC_BASE(_n)     (HSPEC_BASE + NODE_OFFSET(_n))
-#ifndef HSPEC_BASE
-#define HSPEC_BASE              (SYN_UNCACHED_SPACE | HSPEC_BASE_SYN)
-#endif
-#define SYN_UNCACHED_SPACE      0xc000000000000000
-#define HSPEC_BASE_SYN          0x00000b0000000000
-#define NODE_OFFSET(_n)         (UINT64_CAST (_n) << NODE_SIZE_BITS)
-#define NODE_SIZE_BITS		33
-
-
-#define RSYN_REG_OFFSET(fsb, reg) (((fsb) ? HSPEC_SYNERGY1_0 : HSPEC_SYNERGY0_0) | (reg))
-
-#define REMOTE_SYNERGY_LOAD(nasid, fsb, reg)  __remote_synergy_in(nasid, fsb, reg)
-#define REMOTE_SYNERGY_STORE(nasid, fsb, reg, val) __remote_synergy_out(nasid, fsb, reg, val)
-
-extern inline uint64_t
-__remote_synergy_in(int nasid, int fsb, uint64_t reg) {
-	volatile uint64_t *addr;
-
-	addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, reg));
-	return (*addr);
-}
-
-extern inline void
-__remote_synergy_out(int nasid, int fsb, uint64_t reg, uint64_t value) {
-	volatile uint64_t *addr;
-
-        addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, (reg<<2)));
-        *(addr+0) = value >> 48;
-        *(addr+1) = value >> 32;
-        *(addr+2) = value >> 16;
-        *(addr+3) = value;
-        __ia64_mf_a();
-}
-
-/* XX this doesn't make a lot of sense. Which fsb?  */
-extern inline void
-__synergy_out(unsigned long addr, unsigned long value)
-{
-	volatile unsigned long *adr = (unsigned long *)
-			(addr | __IA64_UNCACHED_OFFSET);
-
-	*adr = value;
-	__ia64_mf_a();
-}
-
-#define READ_LOCAL_SYNERGY_REG(addr)	__synergy_in(addr)
-
-/* XX this doesn't make a lot of sense. Which fsb? */
-extern inline unsigned long
-__synergy_in(unsigned long addr)
-{
-	unsigned long ret, *adr = (unsigned long *)
-			(addr | __IA64_UNCACHED_OFFSET);
-
-	ret = *adr;
-	__ia64_mf_a();
-	return ret;
-}
-
-struct sn1_intr_action {
-	void (*handler)(int, void *, struct pt_regs *);
-	void *intr_arg;
-	unsigned long flags;
-	struct sn1_intr_action * next;
-};
-
-typedef struct synergy_da_s {
-	hub_intmasks_t	s_intmasks;
-}synergy_da_t;
-
-struct sn1_cnode_action_list {
-	spinlock_t action_list_lock;
-	struct sn1_intr_action *action_list;
-};
-
-#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
-
-/* multiplex the counters every 10 timer interrupts */ 
-#define SYNERGY_PERF_FREQ_DEFAULT 10
-
-/* synergy perf control registers */
-#define PERF_CNTL0_A            0xab0UL /* control A on FSB0 */
-#define PERF_CNTL0_B            0xab8UL /* control B on FSB0 */
-#define PERF_CNTL1_A            0xac0UL /* control A on FSB1 */
-#define PERF_CNTL1_B            0xac8UL /* control B on FSB1 */
-
-/* synergy perf counters */
-#define PERF_CNTR0_A            0xad0UL /* counter A on FSB0 */
-#define PERF_CNTR0_B            0xad8UL /* counter B on FSB0 */
-#define PERF_CNTR1_A            0xaf0UL /* counter A on FSB1 */
-#define PERF_CNTR1_B            0xaf8UL /* counter B on FSB1 */
-
-/* Synergy perf data. Each nodepda keeps a list of these */
-struct synergy_perf_s {
-        uint64_t        intervals;      /* count of active intervals for this event */
-        uint64_t        modesel;        /* mode and sel bits, both A and B registers */
-        struct synergy_perf_s *next;	/* next in circular linked list */
-        uint64_t        counts[2];      /* [0] is synergy-A counter, [1] synergy-B counter */
-};
-
-typedef struct synergy_perf_s synergy_perf_t;
-
-extern void synergy_perf_init(void);
-extern void synergy_perf_update(int);
-
-#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
-
-
-/* Temporary defintions for testing: */
-
-#endif ASM_IA64_SN_SYNERGY_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/systeminfo.h linux/include/asm-ia64/sn/systeminfo.h
--- linux.orig/include/asm-ia64/sn/systeminfo.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/systeminfo.h	2002-07-20 01:08:35.000000000 +0000
@@ -4,11 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_SYSTEMINFO_H
-#define _ASM_SN_SYSTEMINFO_H
+#ifndef _ASM_IA64_SN_SYSTEMINFO_H
+#define _ASM_IA64_SN_SYSTEMINFO_H
+
+#include <linux/types.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -69,4 +70,4 @@
 }
 #endif
 
-#endif /* _ASM_SN_SYSTEMINFO_H */
+#endif /* _ASM_IA64_SN_SYSTEMINFO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/types.h linux/include/asm-ia64/sn/types.h
--- linux.orig/include/asm-ia64/sn/types.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/types.h	2002-07-20 01:08:33.000000000 +0000
@@ -3,30 +3,27 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
-#ifndef _ASM_SN_TYPES_H
-#define _ASM_SN_TYPES_H
+#ifndef _ASM_IA64_SN_TYPES_H
+#define _ASM_IA64_SN_TYPES_H
 
 #include <linux/types.h>
 
 typedef unsigned long 	cpuid_t;
 typedef unsigned long 	cpumask_t;
-/* typedef unsigned long	cnodemask_t; */
 typedef signed short	nasid_t;	/* node id in numa-as-id space */
-typedef signed short	cnodeid_t;	/* node id in compact-id space */
 typedef signed char	partid_t;	/* partition ID type */
 typedef signed short	moduleid_t;	/* user-visible module number type */
 typedef signed short	cmoduleid_t;	/* kernel compact module id type */
 typedef unsigned char	clusterid_t;	/* Clusterid of the cell */
 
-#define __psunsigned_t uint64_t
-#define lock_t uint64_t
+typedef uint64_t __psunsigned_t;
 
 typedef unsigned long iopaddr_t;
 typedef unsigned char uchar_t;
 typedef unsigned long paddr_t;
 typedef unsigned long pfn_t;
 
-#endif /* _ASM_SN_TYPES_H */
+#endif /* _ASM_IA64_SN_TYPES_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/uart16550.h linux/include/asm-ia64/sn/uart16550.h
--- linux.orig/include/asm-ia64/sn/uart16550.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ia64/sn/uart16550.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,227 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_UART16550_H
+#define _ASM_IA64_SN_UART16550_H
+
+
+/*
+ * Definitions for 16550  chip
+ */
+
+	/* defined as offsets from the data register */
+#define REG_DAT     0   /* receive/transmit data */
+#define REG_ICR     1   /* interrupt control register */
+#define REG_ISR     2   /* interrupt status register */
+#define REG_FCR     2   /* fifo control register */
+#define REG_LCR     3   /* line control register */
+#define REG_MCR     4   /* modem control register */
+#define REG_LSR     5   /* line status register */
+#define REG_MSR     6   /* modem status register */
+#define REG_SCR     7   /* Scratch register      */
+#define REG_DLL     0   /* divisor latch (lsb) */
+#define REG_DLH     1   /* divisor latch (msb) */
+#define REG_EFR		2	/* 16650 enhanced feature register */
+
+/*
+ * 16450/16550 Registers Structure.
+ */
+
+/* Line Control Register */
+#define		LCR_WLS0	0x01	/*word length select bit 0 */	
+#define		LCR_WLS1	0x02	/*word length select bit 2 */	
+#define		LCR_STB	0x04		/* number of stop bits */
+#define		LCR_PEN	0x08		/* parity enable */
+#define		LCR_EPS	0x10		/* even parity select */
+#define		LCR_SETBREAK 0x40	/* break key */
+#define		LCR_DLAB	0x80	/* divisor latch access bit */
+#define 	LCR_RXLEN   0x03    /* # of data bits per received/xmitted char */
+#define 	LCR_STOP1   0x00
+#define 	LCR_STOP2   0x04
+#define 	LCR_PAREN   0x08
+#define 	LCR_PAREVN  0x10
+#define 	LCR_PARMARK 0x20
+#define 	LCR_SNDBRK  0x40
+#define 	LCR_DLAB    0x80
+
+
+#define		LCR_BITS5	0x00	/* 5 bits per char */
+#define		LCR_BITS6	0x01	/* 6 bits per char */
+#define		LCR_BITS7	0x02	/* 7 bits per char */
+#define		LCR_BITS8	0x03	/* 8 bits per char */
+
+#define		LCR_MASK_BITS_CHAR 		0x03
+#define 	LCR_MASK_STOP_BITS		0x04
+#define		LCR_MASK_PARITY_BITS	0x18
+
+
+/* Line Status Register */
+#define		LSR_RCA	0x01		/* data ready */
+#define		LSR_OVRRUN	0x02	/* overrun error */
+#define		LSR_PARERR	0x04	/* parity error */
+#define		LSR_FRMERR	0x08	/* framing error */
+#define		LSR_BRKDET 	0x10	/* a break has arrived */
+#define		LSR_XHRE	0x20	/* tx hold reg is now empty */
+#define		LSR_XSRE	0x40	/* tx shift reg is now empty */
+#define		LSR_RFBE	0x80	/* rx FIFO Buffer error */
+
+/* Interrupt Status Regisger */
+#define		ISR_MSTATUS	0x00
+#define		ISR_TxRDY	0x02
+#define		ISR_RxRDY	0x04
+#define		ISR_ERROR_INTR	0x08
+#define		ISR_FFTMOUT 0x0c	/* FIFO Timeout */
+#define		ISR_RSTATUS 0x06	/* Receiver Line status */
+
+/* Interrupt Enable Register */
+#define		ICR_RIEN	0x01	/* Received Data Ready */
+#define		ICR_TIEN	0x02	/* Tx Hold Register Empty */
+#define		ICR_SIEN	0x04	/* Receiver Line Status */
+#define		ICR_MIEN	0x08	/* Modem Status */
+
+/* Modem Control Register */
+#define		MCR_DTR		0x01	/* Data Terminal Ready */
+#define		MCR_RTS		0x02	/* Request To Send */
+#define		MCR_OUT1	0x04	/* Aux output - not used */
+#define		MCR_OUT2	0x08	/* turns intr to 386 on/off */	
+#define		MCR_LOOP	0x10	/* loopback for diagnostics */
+#define		MCR_AFE 	0x20	/* Auto flow control enable */
+
+/* Modem Status Register */
+#define		MSR_DCTS	0x01	/* Delta Clear To Send */
+#define		MSR_DDSR	0x02	/* Delta Data Set Ready */
+#define		MSR_DRI		0x04	/* Trail Edge Ring Indicator */
+#define		MSR_DDCD	0x08	/* Delta Data Carrier Detect */
+#define		MSR_CTS		0x10	/* Clear To Send */
+#define		MSR_DSR		0x20	/* Data Set Ready */
+#define		MSR_RI		0x40	/* Ring Indicator */
+#define		MSR_DCD		0x80	/* Data Carrier Detect */
+
+#define 	DELTAS(x) 	((x)&(MSR_DCTS|MSR_DDSR|MSR_DRI|MSR_DDCD))
+#define 	STATES(x) 	((x)(MSR_CTS|MSR_DSR|MSR_RI|MSR_DCD))
+
+
+#define		FCR_FIFOEN	0x01	/* enable receive/transmit fifo */
+#define		FCR_RxFIFO	0x02	/* enable receive fifo */
+#define		FCR_TxFIFO	0x04	/* enable transmit fifo */
+#define 	FCR_MODE1	0x08	/* change to mode 1 */
+#define		RxLVL0		0x00	/* Rx fifo level at 1	*/
+#define		RxLVL1		0x40	/* Rx fifo level at 4 */
+#define		RxLVL2		0x80	/* Rx fifo level at 8 */
+#define		RxLVL3		0xc0	/* Rx fifo level at 14 */
+
+#define 	FIFOEN		(FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL3 | FCR_MODE1) 
+
+#define		FCT_TxMASK	0x30	/* mask for Tx trigger */
+#define		FCT_RxMASK	0xc0	/* mask for Rx trigger */
+
+/* enhanced festures register */
+#define		EFR_SFLOW	0x0f	/* various S/w Flow Controls */
+#define 	EFR_EIC		0x10	/* Enhanced Interrupt Control bit */
+#define 	EFR_SCD		0x20	/* Special Character Detect */
+#define 	EFR_RTS		0x40	/* RTS flow control */
+#define 	EFR_CTS		0x80	/* CTS flow control */
+
+/* Rx Tx software flow controls in 16650 enhanced mode */
+#define		SFLOW_Tx0	0x00	/* no Xmit flow control */
+#define		SFLOW_Tx1	0x08	/* Transmit Xon1, Xoff1 */
+#define		SFLOW_Tx2	0x04	/* Transmit Xon2, Xoff2 */
+#define		SFLOW_Tx3	0x0c	/* Transmit Xon1,Xon2, Xoff1,Xoff2 */
+#define		SFLOW_Rx0	0x00	/* no Rcv flow control */
+#define		SFLOW_Rx1	0x02	/* Receiver compares Xon1, Xoff1 */
+#define		SFLOW_Rx2	0x01	/* Receiver compares Xon2, Xoff2 */
+
+#define	ASSERT_DTR(x)		(x |= MCR_DTR)
+#define	ASSERT_RTS(x)		(x |= MCR_RTS)
+#define DU_RTS_ASSERTED(x)  (((x) & MCR_RTS) != 0)
+#define DU_RTS_ASSERT(x)    ((x) |= MCR_RTS)
+#define DU_RTS_DEASSERT(x)  ((x) &= ~MCR_RTS)
+
+
+/*
+ * ioctl(fd, I_STR, arg)
+ * use the SIOC_RS422 and SIOC_EXTCLK combination to support MIDI
+ */
+#define SIOC        ('z' << 8)  /* z for z85130 */
+#define SIOC_EXTCLK (SIOC | 1)  /* select/de-select external clock */
+#define SIOC_RS422  (SIOC | 2)  /* select/de-select RS422 protocol */
+#define SIOC_ITIMER (SIOC | 3)  /* upstream timer adjustment */
+#define SIOC_LOOPBACK   (SIOC | 4)  /* diagnostic loopback test mode */
+
+
+/* channel control register */
+#define	DMA_INT_MASK		0xe0	/* ring intr mask */
+#define DMA_INT_TH25		0x20	/* 25% threshold */
+#define DMA_INT_TH50		0x40	/* 50% threshold */
+#define DMA_INT_TH75		0x60	/* 75% threshold */
+#define DMA_INT_EMPTY		0x80	/* ring buffer empty */
+#define DMA_INT_NEMPTY		0xa0	/* ring buffer not empty */
+#define DMA_INT_FULL		0xc0	/* ring buffer full */
+#define DMA_INT_NFULL		0xe0	/* ring buffer not full */
+
+#define DMA_CHANNEL_RESET	0x400	/* reset dma channel */
+#define DMA_ENABLE			0x200	/* enable DMA */
+
+/* peripheral controller intr status bits applicable to serial ports */
+#define ISA_SERIAL0_MASK 		0x03f00000	/* mask for port #1 intrs */
+#define ISA_SERIAL0_DIR			0x00100000	/* device intr request */
+#define ISA_SERIAL0_Tx_THIR		0x00200000	/* Transmit DMA threshold */
+#define ISA_SERIAL0_Tx_PREQ		0x00400000	/* Transmit DMA pair req */
+#define ISA_SERIAL0_Tx_MEMERR	0x00800000	/* Transmit DMA memory err */
+#define ISA_SERIAL0_Rx_THIR		0x01000000	/* Receive DMA threshold  */
+#define ISA_SERIAL0_Rx_OVERRUN	0x02000000	/* Receive DMA over-run  */
+
+#define ISA_SERIAL1_MASK 		0xfc000000	/* mask for port #1 intrs */
+#define ISA_SERIAL1_DIR			0x04000000	/* device intr request */
+#define ISA_SERIAL1_Tx_THIR		0x08000000	/* Transmit DMA threshold */
+#define ISA_SERIAL1_Tx_PREQ		0x10000000	/* Transmit DMA pair req */
+#define ISA_SERIAL1_Tx_MEMERR	0x20000000	/* Transmit DMA memory err */
+#define ISA_SERIAL1_Rx_THIR		0x40000000	/* Receive DMA threshold  */
+#define ISA_SERIAL1_Rx_OVERRUN	0x80000000	/* Receive DMA over-run  */
+
+#define MAX_RING_BLOCKS		128			/* 4096/32 */
+#define MAX_RING_SIZE		4096
+
+/* DMA Input Control Byte */
+#define	DMA_IC_OVRRUN	0x01	/* overrun error */
+#define	DMA_IC_PARERR	0x02	/* parity error */
+#define	DMA_IC_FRMERR	0x04	/* framing error */
+#define	DMA_IC_BRKDET 	0x08	/* a break has arrived */
+#define DMA_IC_VALID	0x80	/* pair is valid */
+
+/* DMA Output Control Byte */
+#define DMA_OC_TxINTR	0x20	/* set Tx intr after processing byte */
+#define DMA_OC_INVALID	0x00	/* invalid pair */
+#define DMA_OC_WTHR		0x40	/* Write byte to THR */
+#define DMA_OC_WMCR		0x80	/* Write byte to MCR */
+#define DMA_OC_DELAY	0xc0	/* time delay before next xmit */
+
+/* ring id's */
+#define RID_SERIAL0_TX	0x4		/* serial port 0, transmit ring buffer */
+#define RID_SERIAL0_RX	0x5		/* serial port 0, receive ring buffer */
+#define RID_SERIAL1_TX	0x6		/* serial port 1, transmit ring buffer */
+#define RID_SERIAL1_RX	0x7		/* serial port 1, receive ring buffer */
+
+#define CLOCK_XIN			22
+#define PRESCALER_DIVISOR	3
+#define CLOCK_ACE			7333333
+
+/*
+ * increment the ring offset. One way to do this would be to add b'100000.
+ * this would let the offset value roll over automatically when it reaches
+ * its maximum value (127). However when we use the offset, we must use
+ * the appropriate bits only by masking with 0xfe0.
+ * The other option is to shift the offset right by 5 bits and look at its
+ * value. Then increment if required and shift back
+ * note: 127 * 2^5 = 4064
+ */
+#define INC_RING_POINTER(x) \
+	( ((x & 0xffe0) < 4064) ? (x += 32) : 0 )
+
+#endif /* _ASM_IA64_SN_UART16550_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/vector.h linux/include/asm-ia64/sn/vector.h
--- linux.orig/include/asm-ia64/sn/vector.h	2001-01-04 23:25:55.000000000 +0000
+++ linux/include/asm-ia64/sn/vector.h	2002-07-20 01:08:24.000000000 +0000
@@ -4,11 +4,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
  */
-#ifndef _ASM_SN_VECTOR_H
-#define _ASM_SN_VECTOR_H
+#ifndef _ASM_IA64_SN_VECTOR_H
+#define _ASM_IA64_SN_VECTOR_H
 
 #include <linux/config.h>
 
@@ -37,7 +36,7 @@
 
 #endif /* RTL */
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #define VECTOR_PARMS		LB_VECTOR_PARMS
 #define VECTOR_ROUTE		LB_VECTOR_ROUTE
 #define VECTOR_DATA		LB_VECTOR_DATA
@@ -66,19 +65,22 @@
 #define VS_ERROR_MASK		LVS_ERROR_MASK
 #endif
 
-#define NET_ERROR_NONE          0       /* No error             */
-#define NET_ERROR_HARDWARE     -1       /* Hardware error       */
-#define NET_ERROR_OVERRUN      -2       /* Extra response(s)    */
-#define NET_ERROR_REPLY        -3       /* Reply parms mismatch */
-#define NET_ERROR_ADDRESS      -4       /* Addr error response  */
-#define NET_ERROR_COMMAND      -5       /* Cmd error response   */
-#define NET_ERROR_PROT         -6       /* Prot error response  */
-#define NET_ERROR_TIMEOUT      -7       /* Too many retries     */
-#define NET_ERROR_VECTOR       -8       /* Invalid vector/path  */
-#define NET_ERROR_ROUTERLOCK   -9       /* Timeout locking rtr  */
-#define NET_ERROR_INVAL	       -10	/* Invalid vector request */
+#define NET_ERROR_NONE		0	/* No error		*/
+#define NET_ERROR_HARDWARE	(-1)	/* Hardware error	*/
+#define NET_ERROR_OVERRUN	(-2)	/* Extra response(s)	*/
+#define NET_ERROR_REPLY		(-3)	/* Reply parms mismatch */
+#define NET_ERROR_ADDRESS	(-4)	/* Addr error response	*/
+#define NET_ERROR_COMMAND	(-5)	/* Cmd error response	*/
+#define NET_ERROR_PROT		(-6)	/* Prot error response	*/
+#define NET_ERROR_TIMEOUT	(-7)	/* Too many retries	*/
+#define NET_ERROR_VECTOR	(-8)	/* Invalid vector/path	*/
+#define NET_ERROR_ROUTERLOCK	(-9)	/* Timeout locking rtr	*/
+#define NET_ERROR_INVAL		(-10)	/* Invalid vector request */
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#include <asm/sn/types.h>
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
 typedef uint64_t              net_reg_t;
 typedef uint64_t              net_vec_t;
 
@@ -114,6 +116,6 @@
 	int addr, net_reg_t *value);
 #endif
 
-#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
+#endif /* __ASSEMBLY__ */
 
-#endif /* _ASM_SN_VECTOR_H */
+#endif /* _ASM_IA64_SN_VECTOR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/xtalk/xbow.h linux/include/asm-ia64/sn/xtalk/xbow.h
--- linux.orig/include/asm-ia64/sn/xtalk/xbow.h	2001-03-07 03:44:34.000000000 +0000
+++ linux/include/asm-ia64/sn/xtalk/xbow.h	2002-07-20 01:08:29.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc.
  * Copyright (C) 2000 by Colin Ngam
  */
 #ifndef _ASM_SN_SN_XTALK_XBOW_H
@@ -17,7 +17,7 @@
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/xtalk/xswitch.h>
-#ifdef LANGUAGE_C
+#ifndef __ASSEMBLY__
 #include <asm/sn/xtalk/xbow_info.h>
 #endif
 
@@ -46,7 +46,7 @@
 
 #define MAX_XBOW_NAME 	16
 
-#if LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef uint32_t      xbowreg_t;
 
 #define XBOWCONST	(xbowreg_t)
@@ -236,7 +236,7 @@
 /* offset of arbitration register, given source widget id */
 #define XBOW_ARB_OFF(wid) 	(XBOW_ARB_IS_UPPER(wid) ? 0x1c : 0x24)
 
-#endif				/* LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 
 #define	XBOW_WID_ID		WIDGET_ID
 #define	XBOW_WID_STAT		WIDGET_STATUS
@@ -402,7 +402,7 @@
 	(XWIDGET_PART_NUM(XWIDGET_ID_READ(nasid, 0)) == XXBOW_WIDGET_PART_NUM)
 
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 /*
  * XBOW Widget 0 Register formats.
  * Format for many of these registers are similar to the standard
@@ -891,5 +891,5 @@
 
 #endif				/* MACROFIELD_LINE */
 
-#endif				/* _LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 #endif                          /* _ASM_SN_SN_XTALK_XBOW_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/xtalk/xbow_info.h linux/include/asm-ia64/sn/xtalk/xbow_info.h
--- linux.orig/include/asm-ia64/sn/xtalk/xbow_info.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/xtalk/xbow_info.h	2002-07-20 01:08:25.000000000 +0000
@@ -4,12 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XBOW_INFO_H
 #define _ASM_SN_XTALK_XBOW_INFO_H
 
+#include <linux/types.h>
+#include <linux/devfs_fs_kernel.h>
+
 #define XBOW_PERF_MODES	       0x03
 #define XBOW_PERF_COUNTERS     0x02
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/xtalk/xswitch.h linux/include/asm-ia64/sn/xtalk/xswitch.h
--- linux.orig/include/asm-ia64/sn/xtalk/xswitch.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/xtalk/xswitch.h	2002-07-20 01:08:39.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XSWITCH_H
 #define _ASM_SN_XTALK_XSWITCH_H
@@ -16,7 +15,10 @@
  * xtalk bus providers.
  */
 
-#if LANGUAGE_C
+#ifndef __ASSEMBLY__
+
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/xtalk/xtalk.h>
 
 typedef struct xswitch_info_s *xswitch_info_t;
 
@@ -54,6 +56,6 @@
 extern int		xswitch_id_get(devfs_handle_t vhdl);
 extern void		xswitch_id_set(devfs_handle_t vhdl,int xbow_num);
 
-#endif				/* LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 
 #endif				/* _ASM_SN_XTALK_XSWITCH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/xtalk/xtalk.h linux/include/asm-ia64/sn/xtalk/xtalk.h
--- linux.orig/include/asm-ia64/sn/xtalk/xtalk.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/xtalk/xtalk.h	2002-07-20 01:08:24.000000000 +0000
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XTALK_H
 #define _ASM_SN_XTALK_XTALK_H
@@ -18,19 +17,19 @@
  */
 typedef char            xwidgetnum_t;	/* xtalk widget number  (0..15) */
 
-#define XWIDGET_NONE		-1
+#define XWIDGET_NONE		(-1)
 
 typedef int xwidget_part_num_t;	/* xtalk widget part number */
 
-#define XWIDGET_PART_NUM_NONE	-1
+#define XWIDGET_PART_NUM_NONE	(-1)
 
 typedef int             xwidget_rev_num_t;	/* xtalk widget revision number */
 
-#define XWIDGET_REV_NUM_NONE	-1
+#define XWIDGET_REV_NUM_NONE	(-1)
 
 typedef int xwidget_mfg_num_t;	/* xtalk widget manufacturing ID */
 
-#define XWIDGET_MFG_NUM_NONE	-1
+#define XWIDGET_MFG_NUM_NONE	(-1)
 
 typedef struct xtalk_piomap_s *xtalk_piomap_t;
 
@@ -57,7 +56,7 @@
 #include <asm/sn/types.h>
 #include <asm/sn/alenlist.h>
 #include <asm/sn/ioerror.h>
-#include <asm/sn/iobus.h>
+#include <asm/sn/driver.h>
 #include <asm/sn/dmamap.h>
 
 struct xwidget_hwid_s;
@@ -205,14 +204,8 @@
 
 typedef int
 xtalk_intr_connect_f    (xtalk_intr_t intr_hdl,		/* xtalk intr resource handle */
-			 intr_func_t intr_func,		/* xtalk intr handler */
-			 void *intr_arg,	/* arg to intr handler */
 			 xtalk_intr_setfunc_f *setfunc,		/* func to set intr hw */
-			 void *setfunc_arg,	/* arg to setfunc. This must be */
-							/* sufficient to determine which */
-							/* interrupt on which board needs */
-							/* to be set. */
-			 void *thread);		/* which intr thread to use */
+			 void *setfunc_arg);	/* arg to setfunc */
 
 typedef void
 xtalk_intr_disconnect_f (xtalk_intr_t intr_hdl);
@@ -400,7 +393,6 @@
 
 extern int		xtalk_device_powerup(devfs_handle_t, xwidgetnum_t);
 extern int		xtalk_device_shutdown(devfs_handle_t, xwidgetnum_t);
-extern int		xtalk_device_inquiry(devfs_handle_t, xwidgetnum_t);
 
 #endif				/* __KERNEL__ */
 #endif				/* _ASM_SN_XTALK_XTALK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/xtalk/xtalk_private.h linux/include/asm-ia64/sn/xtalk/xtalk_private.h
--- linux.orig/include/asm-ia64/sn/xtalk/xtalk_private.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/xtalk/xtalk_private.h	2002-07-20 01:08:27.000000000 +0000
@@ -4,13 +4,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XTALK_PRIVATE_H
 #define _ASM_SN_XTALK_XTALK_PRIVATE_H
 
 #include <asm/sn/ioerror.h>        /* for error function and arg types */
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/xtalk/xtalk.h>
 
 /*
  * xtalk_private.h -- private definitions for xtalk
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/xtalk/xtalkaddrs.h linux/include/asm-ia64/sn/xtalk/xtalkaddrs.h
--- linux.orig/include/asm-ia64/sn/xtalk/xtalkaddrs.h	2001-04-05 19:51:47.000000000 +0000
+++ linux/include/asm-ia64/sn/xtalk/xtalkaddrs.h	2002-07-20 01:08:39.000000000 +0000
@@ -4,13 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc.
  * Copyright (C) 2000 by Colin Ngam
  */
 #ifndef _ASM_SN_XTALK_XTALKADDRS_H
 #define _ASM_SN_XTALK_XTALKADDRS_H
 
-#include <linux/config.h>
 
 /*
  * CrossTalk to SN0 Hub addressing support
@@ -60,19 +59,15 @@
  * This looks very much like a REMOTE_HUB access, except the nodeID
  * is in a different place, and the highest xtalk bit is set.
  */
-
 /* Hub-specific xtalk definitions */
 
 #define HX_MEM_BIT		0L	/* Hub's idea of xtalk memory access */
 #define HX_IO_BIT		1L	/* Hub's idea of xtalk register access */
 #define HX_ACCTYPE_SHIFT	47
 
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
 #define HX_NODE_SHIFT		39
-#endif
 
 #define HX_BIGWIN_SHIFT		28
-
 #define HX_SWIN_SHIFT		23
 
 #define HX_LOCACC		0L	/* local access */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/sn/xtalk/xwidget.h linux/include/asm-ia64/sn/xtalk/xwidget.h
--- linux.orig/include/asm-ia64/sn/xtalk/xwidget.h	2001-01-04 21:00:15.000000000 +0000
+++ linux/include/asm-ia64/sn/xtalk/xwidget.h	2002-07-20 01:08:21.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc.
  * Copyright (C) 2000 by Colin Ngam
  */
 #ifndef __ASM_SN_XTALK_XWIDGET_H__
@@ -15,9 +15,9 @@
  */
 
 #include <asm/sn/xtalk/xtalk.h>
-#if LANGUAGE_C
+#ifndef __ASSEMBLY__
 #include <asm/sn/cdl.h>
-#endif /* LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 #ifdef LITTLE_ENDIAN
 #define WIDGET_ID			0x00
@@ -115,7 +115,7 @@
  * widget target flush register are widget dependent thus will not be
  * defined here
  */
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef uint32_t      widgetreg_t;
 
 /* widget configuration registers */
@@ -267,9 +267,6 @@
 					 async_attach_t aa);
 
 extern int		xwidget_unregister(devfs_handle_t);
-extern void	        xwidget_error_register(devfs_handle_t xwidget,
-						error_handler_f * efunc,
-						error_handler_arg_t einfo);
 
 extern void             xwidget_reset(devfs_handle_t xwidget);
 extern void             xwidget_gfx_reset(devfs_handle_t xwidget);
@@ -289,6 +286,9 @@
 extern xwidget_rev_num_t xwidget_info_rev_num_get(xwidget_info_t xwidget_info);
 extern xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t xwidget_info);
 
+extern xwidgetnum_t hub_widget_id(nasid_t);
+
+
 
 /*
  * TBD: DELETE THIS ENTIRE STRUCTURE!  Equivalent is now in
@@ -303,6 +303,6 @@
 } v_widget_t;
 #endif				/* _KERNEL */
 
-#endif				/* _LANGUAGE_C */
+#endif				/* __ASSEMBLY__ */
 
 #endif				/* __ASM_SN_XTALK_XWIDGET_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/softirq.h linux/include/asm-ia64/softirq.h
--- linux.orig/include/asm-ia64/softirq.h	2001-09-08 19:02:31.000000000 +0000
+++ linux/include/asm-ia64/softirq.h	2002-07-20 01:08:29.000000000 +0000
@@ -3,21 +3,21 @@
 
 /*
  * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <asm/hardirq.h>
 
-#define __local_bh_enable()	do { barrier(); local_bh_count()--; } while (0)
+#define __local_bh_enable()	do { barrier(); really_local_bh_count()--; } while (0)
 
-#define local_bh_disable()	do { local_bh_count()++; barrier(); } while (0)
+#define local_bh_disable()	do { really_local_bh_count()++; barrier(); } while (0)
 #define local_bh_enable()								\
 do {											\
 	__local_bh_enable();								\
-	if (__builtin_expect(local_softirq_pending(), 0) && local_bh_count() == 0)	\
+	if (__builtin_expect(local_softirq_pending(), 0) && really_local_bh_count() == 0)	\
 		do_softirq();								\
 } while (0)
 
 
-#define in_softirq()		(local_bh_count() != 0)
+#define in_softirq()		(really_local_bh_count() != 0)
 
 #endif /* _ASM_IA64_SOFTIRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/spinlock.h linux/include/asm-ia64/spinlock.h
--- linux.orig/include/asm-ia64/spinlock.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/spinlock.h	2002-07-20 01:08:24.000000000 +0000
@@ -3,7 +3,7 @@
 
 /*
  * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  *
  * This file is used for SMP configurations only.
@@ -84,7 +84,7 @@
 	"mov r29 = 1\n"						\
 	";;\n"							\
 	"1:\n"							\
-	"ld4.bias r2 = [%0]\n"					\
+	"ld4 r2 = [%0]\n"					\
 	";;\n"							\
 	"cmp4.eq p0,p7 = r0,r2\n"				\
 	"(p7) br.cond.spnt.few 1b \n"				\
@@ -93,7 +93,7 @@
 	"cmp4.eq p0,p7 = r0, r2\n"				\
 	"(p7) br.cond.spnt.few 1b\n"				\
 	";;\n"							\
-	:: "r"(&(x)->lock) : "r2", "r29", "memory")
+	:: "r"(&(x)->lock) : "ar.ccv", "p7", "r2", "r29", "memory")
 
 #define spin_is_locked(x)	((x)->lock != 0)
 #define spin_unlock(x)		do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0)
@@ -128,7 +128,7 @@
 			      ";;\n"						\
 			      ".previous\n"					\
 			      : "=&r" (tmp)					\
-			      : "r" (rw): "memory");				\
+			      : "r" (rw) : "p6", "memory");			\
 } while(0)
 
 #define read_unlock(rw)								\
@@ -156,13 +156,13 @@
 		"cmp4.eq p0,p7 = r0, r2\n"					\
 		"(p7) br.cond.spnt.few 1b\n"					\
 		";;\n"								\
-		:: "r"(rw) : "r2", "r29", "memory");				\
+		:: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory");		\
 } while(0)
 
-/*
- * clear_bit() has "acq" semantics; we're really need "rel" semantics,
- * but for simplicity, we simply do a fence for now...
- */
-#define write_unlock(x)				({clear_bit(31, (x)); mb();})
+#define write_unlock(x)									\
+({											\
+	smp_mb__before_clear_bit();	/* need barrier before releasing lock... */	\
+	clear_bit(31, (x));								\
+})
 
 #endif /*  _ASM_IA64_SPINLOCK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/system.h linux/include/asm-ia64/system.h
--- linux.orig/include/asm-ia64/system.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/asm-ia64/system.h	2002-07-20 01:08:34.000000000 +0000
@@ -7,8 +7,8 @@
  * on information published in the Processor Abstraction Layer
  * and the System Abstraction Layer manual.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  */
@@ -232,7 +232,7 @@
 		_tmp = __bad_increment_for_ia64_fetch_and_add();		\
 		break;								\
 	}									\
-	(__typeof__(*v)) (_tmp + (i));	/* return new value */			\
+	(__typeof__(*(v))) (_tmp + (i));	/* return new value */		\
 })
 
 /*
@@ -378,12 +378,18 @@
 extern void ia64_save_extra (struct task_struct *task);
 extern void ia64_load_extra (struct task_struct *task);
 
+#if defined(CONFIG_SMP) && defined(CONFIG_PERFMON)
+# define PERFMON_IS_SYSWIDE() (local_cpu_data->pfm_syst_wide != 0)
+#else
+# define PERFMON_IS_SYSWIDE() (0)
+#endif
+
 #define __switch_to(prev,next,last) do {						\
 	if (((prev)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID))	\
-	    || IS_IA32_PROCESS(ia64_task_regs(prev)))					\
+	    || IS_IA32_PROCESS(ia64_task_regs(prev)) || PERFMON_IS_SYSWIDE())	\
 		ia64_save_extra(prev);							\
 	if (((next)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID))	\
-	    || IS_IA32_PROCESS(ia64_task_regs(next)))					\
+	    || IS_IA32_PROCESS(ia64_task_regs(next)) || PERFMON_IS_SYSWIDE())	\
 		ia64_load_extra(next);							\
 	(last) = ia64_switch_to((next));						\
 } while (0)
@@ -405,10 +411,6 @@
 	ia64_psr(ia64_task_regs(prev))->dfh = 1;				\
 	__switch_to(prev,next,last);						\
   } while (0)
-
-/* Return true if this CPU can call the console drivers in printk() */
-#define arch_consoles_callable() (cpu_online_map & (1UL << smp_processor_id()))
-
 #else
 # define switch_to(prev,next,last) do {						\
 	ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next));	\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ia64/unistd.h linux/include/asm-ia64/unistd.h
--- linux.orig/include/asm-ia64/unistd.h	2001-11-09 22:26:17.000000000 +0000
+++ linux/include/asm-ia64/unistd.h	2002-07-20 01:08:25.000000000 +0000
@@ -206,6 +206,7 @@
 #define __NR_getdents64			1214
 #define __NR_getunwind			1215
 #define __NR_readahead			1216
+#define __NR_tkill			1229
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/hw_irq.h linux/include/asm-m68k/hw_irq.h
--- linux.orig/include/asm-m68k/hw_irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-m68k/hw_irq.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,6 @@
+#ifndef __ASM_M68K_HW_IRQ_H
+#define __ASM_M68K_HW_IRQ_H
+
+/* Dummy include. */
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/ide.h linux/include/asm-m68k/ide.h
--- linux.orig/include/asm-m68k/ide.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/include/asm-m68k/ide.h	2002-07-20 01:08:22.000000000 +0000
@@ -89,7 +89,19 @@
 		unsigned unit		: 1;	/* drive select number, 0 or 1 */
 		unsigned head		: 4;	/* always zeros here */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+		unsigned reserved456	: 3;
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned bit0		: 1;
+	} b;
+} control_t;
 
 static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
 			unsigned long flags, const char *device, void *dev_id)
@@ -160,22 +172,20 @@
 #define HD_DATA NULL
 
 
-/* get rid of defs from io.h - ide has its private and conflicting versions */
-#undef inb
-#undef inw
-#undef outb
-#undef outw
-#undef inb_p
-#undef outb_p
+/*
+ * get rid of defs from io.h
+ * ide still has some private and conflicting versions
+ */
 #undef insw
+#undef insl
 #undef outsw
-#undef insw_swapw
-#undef outsw_swapw
+#undef outsl
+
 
-/* 
+/*
  * define IO method and translation,
- * so far only Q40 has ide-if on ISA 
-*/
+ * so far only Q40 has ide-if on ISA
+ */
 #ifndef CONFIG_Q40
 
 #define ADDR_TRANS_B(_addr_) (_addr_)
@@ -187,12 +197,15 @@
 #define ADDR_TRANS_W(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_W(_addr_)) : (_addr_))
 #endif
 
-#define inb(p)     in_8(ADDR_TRANS_B(p))
-#define inb_p(p)     in_8(ADDR_TRANS_B(p))
-#define inw(p)     in_be16(ADDR_TRANS_W(p))
-#define outb(v,p)  out_8(ADDR_TRANS_B(p),v)
-#define outb_p(v,p)  out_8(ADDR_TRANS_B(p),v)
-#define outw(v,p)  out_be16(ADDR_TRANS_W(p),v)
+#define HAVE_ARCH_OUT_BYTE
+
+#define OUT_BYTE(v,p)	out_8(ADDR_TRANS_B((p)), (v))
+#define OUT_WORD(v,p)	out_be16(ADDR_TRANS_W((p)), (v))
+
+#define HAVE_ARCH_IN_BYTE
+
+#define IN_BYTE(p)	in_8(ADDR_TRANS_B((p)))
+#define IN_WORD(p)	in_be16(ADDR_TRANS_W((p)))
 
 #define insw(port, buf, nr) raw_insw(ADDR_TRANS_W(port), buf, nr)
 #define outsw(port, buf, nr) raw_outsw(ADDR_TRANS_W(port), buf, nr)
@@ -201,7 +214,6 @@
 #define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
 
 
-
 #if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
 
 #define insl_swapw(data_reg, buffer, wcount) \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/machdep.h linux/include/asm-m68k/machdep.h
--- linux.orig/include/asm-m68k/machdep.h	2000-11-28 01:57:34.000000000 +0000
+++ linux/include/asm-m68k/machdep.h	2002-07-20 01:08:26.000000000 +0000
@@ -4,7 +4,7 @@
 struct pt_regs;
 struct kbd_repeat;
 struct mktime;
-struct hwclk_time;
+struct rtc_time;
 struct gendisk;
 struct buffer_head;
 
@@ -28,7 +28,7 @@
 extern unsigned long (*mach_gettimeoffset)(void);
 extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
 			   int *min, int *sec);
-extern int (*mach_hwclk)(int, struct hwclk_time*);
+extern int (*mach_hwclk)(int, struct rtc_time*);
 extern int (*mach_set_clock_mmss)(unsigned long);
 extern void (*mach_reset)( void );
 extern void (*mach_halt)( void );
@@ -37,7 +37,6 @@
 extern void (*mach_hd_setup)(char *, int *);
 extern long mach_max_dma_address;
 extern void (*mach_floppy_setup)(char *, int *);
-extern void (*mach_floppy_eject)(void);
 extern void (*mach_heartbeat) (int);
 extern void (*mach_l2_flush) (int);
 extern int mach_sysrq_key;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/motorola_pgtable.h linux/include/asm-m68k/motorola_pgtable.h
--- linux.orig/include/asm-m68k/motorola_pgtable.h	2000-12-05 20:43:48.000000000 +0000
+++ linux/include/asm-m68k/motorola_pgtable.h	2002-07-20 01:08:24.000000000 +0000
@@ -151,9 +151,6 @@
 #define pgd_bad(pgd)		((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE)
 #define pgd_present(pgd)	(pgd_val(pgd) & _PAGE_TABLE)
 #define pgd_clear(pgdp)		({ pgd_val(*pgdp) = 0; })
-/* Permanent address of a page. */
-#define page_address(page)	({ if (!(page)->virtual) BUG(); (page)->virtual; })
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
 #define pte_page(pte)		(mem_map+pte_pagenr(pte))
 
 #define pte_ERROR(e) \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/page.h linux/include/asm-m68k/page.h
--- linux.orig/include/asm-m68k/page.h	2000-11-28 02:00:49.000000000 +0000
+++ linux/include/asm-m68k/page.h	2002-07-20 01:08:36.000000000 +0000
@@ -163,6 +163,7 @@
 #define virt_to_page(kaddr)	(mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
+#ifdef CONFIG_DEBUG_BUGVERBOSE
 #ifndef CONFIG_SUN3
 #define BUG() do { \
 	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
@@ -174,6 +175,11 @@
 	panic("BUG!"); \
 } while (0)
 #endif
+#else
+#define BUG() do { \
+	asm volatile("illegal"); \
+} while (0)
+#endif
 
 #define PAGE_BUG(page) do { \
 	BUG(); \
@@ -181,6 +187,9 @@
 
 #endif /* __ASSEMBLY__ */
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 
 #endif /* _M68K_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/pgalloc.h linux/include/asm-m68k/pgalloc.h
--- linux.orig/include/asm-m68k/pgalloc.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-m68k/pgalloc.h	2002-07-20 01:08:37.000000000 +0000
@@ -127,6 +127,7 @@
 
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_icache_page(vma,pg)              do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 /* Push n pages at kernel virtual address and clear the icache */
 /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/q40_master.h linux/include/asm-m68k/q40_master.h
--- linux.orig/include/asm-m68k/q40_master.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/include/asm-m68k/q40_master.h	2002-07-20 01:08:29.000000000 +0000
@@ -8,7 +8,6 @@
 
 #include <asm/raw_io.h>
 
-
 #define q40_master_addr 0xff000000
 #define q40_rtc_addr    0xff021ffc
 
@@ -22,48 +21,39 @@
 #define Q40_LED_ON()        master_outb(1,LED_REG)
 #define Q40_LED_OFF()       master_outb(0,LED_REG)
 
-#define INTERRUPT_REG       IIRQ_REG  /* "native" ints */
+#define INTERRUPT_REG       IIRQ_REG  /* "native" irqs */
 #define KEY_IRQ_ENABLE_REG  0x08      /**/
-#define KEYBOARD_UNLOCK_REG 0x20      /* clear kb int */
+#define KEYBOARD_UNLOCK_REG 0x20      /* clear kb irq */
 
-#define SAMPLE_ENABLE_REG   0x14      /* generate SAMPLE ints */
+#define SAMPLE_ENABLE_REG   0x14      /* generate SAMPLE irqs */
 #define SAMPLE_RATE_REG     0x2c
 #define SAMPLE_CLEAR_REG    0x28
 #define SAMPLE_LOW          0x00
 #define SAMPLE_HIGH         0x01
 
-#define FRAME_RATE_REG       0x38      /* generate FRAME ints at 200 HZ rate */
-
-#if 0
-#define SER_ENABLE_REG      0x0c      /* allow serial ints to be generated */
-#endif
-#define EXT_ENABLE_REG      0x10      /* ... rest of the ISA ints ... */
+#define FRAME_RATE_REG       0x38      /* generate FRAME irqs at 200 HZ rate */
 
+#define EXT_ENABLE_REG      0x10      /* ... rest of the ISA irqs ... */
 
 #define master_inb(_reg_)      in_8((unsigned char *)q40_master_addr+_reg_)
 #define master_outb(_b_,_reg_)  out_8((unsigned char *)q40_master_addr+_reg_,_b_)
 
-
-/* define some Q40 specific ints */
-#include "q40ints.h"
-
 /* RTC defines */
 
 #define Q40_RTC_BASE (q40_rtc_addr)
 
-#define RTC_YEAR        (*(unsigned char *)(Q40_RTC_BASE+0))
-#define RTC_MNTH        (*(unsigned char *)(Q40_RTC_BASE-4))
-#define RTC_DATE        (*(unsigned char *)(Q40_RTC_BASE-8))
-#define RTC_DOW         (*(unsigned char *)(Q40_RTC_BASE-12))
-#define RTC_HOUR        (*(unsigned char *)(Q40_RTC_BASE-16))
-#define RTC_MINS        (*(unsigned char *)(Q40_RTC_BASE-20))
-#define RTC_SECS        (*(unsigned char *)(Q40_RTC_BASE-24))
-#define RTC_CTRL        (*(unsigned char *)(Q40_RTC_BASE-28))
-
+#define Q40_RTC_YEAR        (*(volatile unsigned char *)(Q40_RTC_BASE+0))
+#define Q40_RTC_MNTH        (*(volatile unsigned char *)(Q40_RTC_BASE-4))
+#define Q40_RTC_DATE        (*(volatile unsigned char *)(Q40_RTC_BASE-8))
+#define Q40_RTC_DOW         (*(volatile unsigned char *)(Q40_RTC_BASE-12))
+#define Q40_RTC_HOUR        (*(volatile unsigned char *)(Q40_RTC_BASE-16))
+#define Q40_RTC_MINS        (*(volatile unsigned char *)(Q40_RTC_BASE-20))
+#define Q40_RTC_SECS        (*(volatile unsigned char *)(Q40_RTC_BASE-24))
+#define Q40_RTC_CTRL        (*(volatile unsigned char *)(Q40_RTC_BASE-28))
 
 /* some control bits */
-#define RTC_READ   64  /* prepare for reading */
-#define RTC_WRITE  128
+#define Q40_RTC_READ   64  /* prepare for reading */
+#define Q40_RTC_WRITE  128
 
 
 /* misc defs */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/q40ints.h linux/include/asm-m68k/q40ints.h
--- linux.orig/include/asm-m68k/q40ints.h	2000-11-28 01:11:26.000000000 +0000
+++ linux/include/asm-m68k/q40ints.h	2002-07-20 01:08:34.000000000 +0000
@@ -11,19 +11,19 @@
 
 /* masks for interrupt regiosters*/
 /* internal, IIRQ_REG */
-#define IRQ_KEYB_MASK    (2)
-#define IRQ_SER_MASK     (1<<2)
-#define IRQ_FRAME_MASK   (1<<3)
-#define IRQ_EXT_MASK     (1<<4)    /* is a EIRQ */
+#define Q40_IRQ_KEYB_MASK    (2)
+#define Q40_IRQ_SER_MASK     (1<<2)
+#define Q40_IRQ_FRAME_MASK   (1<<3)
+#define Q40_IRQ_EXT_MASK     (1<<4)    /* is a EIRQ */
 /* eirq, EIRQ_REG */
-#define IRQ3_MASK        (1)
-#define IRQ4_MASK        (1<<1)
-#define IRQ5_MASK        (1<<2)
-#define IRQ6_MASK        (1<<3)
-#define IRQ7_MASK        (1<<4)
-#define IRQ10_MASK       (1<<5)
-#define IRQ14_MASK       (1<<6)
-#define IRQ15_MASK       (1<<7)
+#define Q40_IRQ3_MASK        (1)
+#define Q40_IRQ4_MASK        (1<<1)
+#define Q40_IRQ5_MASK        (1<<2)
+#define Q40_IRQ6_MASK        (1<<3)
+#define Q40_IRQ7_MASK        (1<<4)
+#define Q40_IRQ10_MASK       (1<<5)
+#define Q40_IRQ14_MASK       (1<<6)
+#define Q40_IRQ15_MASK       (1<<7)
 
 extern unsigned long q40_probe_irq_on (void);
 extern int q40_probe_irq_off (unsigned long irqs);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/resource.h linux/include/asm-m68k/resource.h
--- linux.orig/include/asm-m68k/resource.h	2000-09-22 21:21:20.000000000 +0000
+++ linux/include/asm-m68k/resource.h	2002-07-20 01:08:22.000000000 +0000
@@ -13,7 +13,7 @@
 #define RLIMIT_RSS	5		/* max resident set size */
 #define RLIMIT_NPROC	6		/* max number of processes */
 #define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space*/
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
 #define RLIMIT_AS	9		/* address space limit */
 #define RLIMIT_LOCKS	10		/* maximum file locks held */
 
@@ -27,19 +27,19 @@
 
 #ifdef __KERNEL__
 
-#define INIT_RLIMITS	\
-{                       \
-  {LONG_MAX, LONG_MAX}, \
-  {LONG_MAX, LONG_MAX}, \
-  {LONG_MAX, LONG_MAX}, \
-  {_STK_LIM, LONG_MAX}, \
-  {       0, LONG_MAX}, \
-  {LONG_MAX, LONG_MAX}, \
-  {0, 0},		\
-  {INR_OPEN, INR_OPEN}, \
-  {LONG_MAX, LONG_MAX}, \
-  {LONG_MAX, LONG_MAX}, \
-  {LONG_MAX, LONG_MAX}  \
+#define INIT_RLIMITS					\
+{							\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+        { RLIM_INFINITY, RLIM_INFINITY },		\
 }
 
 #endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/rtc.h linux/include/asm-m68k/rtc.h
--- linux.orig/include/asm-m68k/rtc.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/include/asm-m68k/rtc.h	2002-07-20 01:08:32.000000000 +0000
@@ -14,22 +14,9 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
-
-struct hwclk_time {
-	unsigned	sec;	/* 0..59 */
-	unsigned	min;	/* 0..59 */
-	unsigned	hour;	/* 0..23 */
-	unsigned	day;	/* 1..31 */
-	unsigned	mon;	/* 0..11 */
-	unsigned	year;	/* 70... */
-	int		wday;	/* 0..6, 0 is Sunday, -1 means unknown/don't set */
-};
-
-/* a few implementation details for the emulation : */
-
-extern unsigned gen_rtc_irq_flags; /* which sort(s) of interrupts caused int */
-extern unsigned gen_rtc_irq_ctrl;  /*                             are enabled */
-extern short q40rtc_oldsecs;
+#include <linux/rtc.h>
+#include <linux/delay.h>
+#include <asm/machdep.h>
 
 #define RTC_PIE 0x40		/* periodic interrupt enable */
 #define RTC_AIE 0x20		/* alarm interrupt enable */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/scatterlist.h linux/include/asm-m68k/scatterlist.h
--- linux.orig/include/asm-m68k/scatterlist.h	2001-10-12 22:35:54.000000000 +0000
+++ linux/include/asm-m68k/scatterlist.h	2002-07-20 01:08:38.000000000 +0000
@@ -2,9 +2,18 @@
 #define _M68K_SCATTERLIST_H
 
 struct scatterlist {
-    char *  address;    /* Location data is to be transferred to */
-    unsigned int length;
-    unsigned long dvma_address;
+	/* This will disappear in 2.5.x */
+	char *address;
+
+	/* These two are only valid if ADDRESS member of this
+	 * struct is NULL.
+	 */
+	struct page *page;
+	unsigned int offset;
+
+	unsigned int length;
+
+	__u32 dvma_address; /* A place to hang host-specific addresses at. */
 };
 
 struct mmu_sglist {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/semaphore.h linux/include/asm-m68k/semaphore.h
--- linux.orig/include/asm-m68k/semaphore.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-m68k/semaphore.h	2002-07-20 01:08:36.000000000 +0000
@@ -9,7 +9,6 @@
 #include <linux/wait.h>
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
-#include <linux/stringify.h>
 
 #include <asm/system.h>
 #include <asm/atomic.h>
@@ -95,14 +94,10 @@
 		"subql #1,%0@\n\t"
 		"jmi 2f\n\t"
 		"1:\n"
-		".subsection 1\n"
-		".even\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START(".even\n\t")
 		"2:\tpea 1b\n\t"
 		"jbra __down_failed\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		: /* no outputs */
 		: "a" (sem1)
 		: "memory");
@@ -123,14 +118,10 @@
 		"jmi 2f\n\t"
 		"clrl %0\n"
 		"1:\n"
-		".subsection 1\n"
-		".even\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START(".even\n\t")
 		"2:\tpea 1b\n\t"
 		"jbra __down_failed_interruptible\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		: "=d" (result)
 		: "a" (sem1)
 		: "memory");
@@ -152,14 +143,10 @@
 		"jmi 2f\n\t"
 		"clrl %0\n"
 		"1:\n"
-		".subsection 1\n"
-		".even\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START(".even\n\t")
 		"2:\tpea 1b\n\t"
 		"jbra __down_failed_trylock\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		: "=d" (result)
 		: "a" (sem1)
 		: "memory");
@@ -185,15 +172,11 @@
 		"addql #1,%0@\n\t"
 		"jle 2f\n"
 		"1:\n"
-		".subsection 1\n"
-		".even\n"
-		".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "\n"
-		"_text_lock_" __stringify(KBUILD_BASENAME) ":\n"
-		".endif\n"
+		LOCK_SECTION_START(".even\n\t")
 		"2:\t"
 		"pea 1b\n\t"
 		"jbra __up_wakeup\n"
-		".subsection 0\n"
+		LOCK_SECTION_END
 		: /* no outputs */
 		: "a" (sem1)
 		: "memory");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/serial.h linux/include/asm-m68k/serial.h
--- linux.orig/include/asm-m68k/serial.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-m68k/serial.h	2002-07-20 01:08:30.000000000 +0000
@@ -2,7 +2,7 @@
  * include/asm-m68k/serial.h
  *
  * currently this seems useful only for a Q40,
- * its an almost exact copy of ../asm-alpha/serial.h 
+ * it's an almost exact copy of ../asm-alpha/serial.h 
  *
  */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/siginfo.h linux/include/asm-m68k/siginfo.h
--- linux.orig/include/asm-m68k/siginfo.h	2000-11-28 01:11:26.000000000 +0000
+++ linux/include/asm-m68k/siginfo.h	2002-07-20 01:08:21.000000000 +0000
@@ -117,6 +117,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/sun3_pgtable.h linux/include/asm-m68k/sun3_pgtable.h
--- linux.orig/include/asm-m68k/sun3_pgtable.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/include/asm-m68k/sun3_pgtable.h	2002-07-20 01:08:38.000000000 +0000
@@ -123,9 +123,6 @@
 
 /* FIXME: this is only a guess */
 #define pte_pagenr(pte)		((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
-/* Permanent address of a page. */
-#define page_address(page)	({ if (!(page)->virtual) BUG(); (page)->virtual; })
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
 #define pte_page(pte)		(mem_map+pte_pagenr(pte))
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/system.h linux/include/asm-m68k/system.h
--- linux.orig/include/asm-m68k/system.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-m68k/system.h	2002-07-20 01:08:27.000000000 +0000
@@ -4,6 +4,7 @@
 #include <linux/config.h> /* get configuration macros */
 #include <linux/linkage.h>
 #include <linux/kernel.h>
+#include <linux/init.h>
 #include <asm/segment.h>
 #include <asm/entry.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-m68k/unistd.h linux/include/asm-m68k/unistd.h
--- linux.orig/include/asm-m68k/unistd.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-m68k/unistd.h	2002-07-20 01:08:36.000000000 +0000
@@ -221,7 +221,10 @@
 #define __NR_setgid32		214
 #define __NR_setfsuid32		215
 #define __NR_setfsgid32		216
+#define __NR_pivot_root		217
 #define __NR_getdents64		220
+#define __NR_gettid		221
+#define __NR_tkill		222
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/addrspace.h linux/include/asm-mips/addrspace.h
--- linux.orig/include/asm-mips/addrspace.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/addrspace.h	2002-07-20 01:08:22.000000000 +0000
@@ -4,67 +4,102 @@
  * for more details.
  *
  * Copyright (C) 1996 by Ralf Baechle
- * Copyright (C) 2000 by Maciej W. Rozycki
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
  *
- * Defitions for the address spaces of the MIPS CPUs.
+ * Definitions for the address spaces of the MIPS CPUs.
  */
 #ifndef __ASM_MIPS_ADDRSPACE_H
 #define __ASM_MIPS_ADDRSPACE_H
 
 /*
+ *  Configure language
+ */
+#ifdef __ASSEMBLY__
+#define _ATYPE_
+#define _ATYPE32_
+#define _ATYPE64_
+#else
+#define _ATYPE_		__PTRDIFF_TYPE__
+#define _ATYPE32_	int
+#define _ATYPE64_	long long
+#endif
+
+/*
+ *  32-bit MIPS address spaces
+ */
+#ifdef __ASSEMBLY__
+#define _ACAST32_
+#define _ACAST64_
+#else
+#define _ACAST32_		(_ATYPE_)(_ATYPE32_)	/* widen if necessary */
+#define _ACAST64_		(_ATYPE64_)		/* do _not_ narrow */
+#endif
+
+/*
  * Memory segments (32bit kernel mode addresses)
  */
-#define KUSEG                   0x00000000
-#define KSEG0                   0x80000000
-#define KSEG1                   0xa0000000
-#define KSEG2                   0xc0000000
-#define KSEG3                   0xe0000000
+#define KUSEG			0x00000000
+#define KSEG0			0x80000000
+#define KSEG1			0xa0000000
+#define KSEG2			0xc0000000
+#define KSEG3			0xe0000000
 
-#define K0BASE  KSEG0
+#define K0BASE			KSEG0
 
 /*
  * Returns the kernel segment base of a given address
  */
-#ifndef __ASSEMBLY__
-#define KSEGX(a)                (((unsigned long)(a)) & 0xe0000000)
-#else
-#define KSEGX(a)                ((a) & 0xe0000000)
-#endif
+#define KSEGX(a)		((_ACAST32_ (a)) & 0xe0000000)
 
 /*
  * Returns the physical address of a KSEG0/KSEG1 address
  */
+#define CPHYSADDR(a)		((_ACAST32_ (a)) & 0x1fffffff)
+
 #ifndef __ASSEMBLY__
-#define PHYSADDR(a)		(((unsigned long)(a)) & 0x1fffffff)
-#else
-#define PHYSADDR(a)		((a) & 0x1fffffff)
+#define PHYSADDR(a)		CPHYSADDR(a)
 #endif
 
 /*
  * Map an address to a certain kernel segment
  */
-#ifndef __ASSEMBLY__
-#define KSEG0ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0))
-#define KSEG1ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1))
-#define KSEG2ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2))
-#define KSEG3ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3))
-#else
-#define KSEG0ADDR(a)		(((a) & 0x1fffffff) | KSEG0)
-#define KSEG1ADDR(a)		(((a) & 0x1fffffff) | KSEG1)
-#define KSEG2ADDR(a)		(((a) & 0x1fffffff) | KSEG2)
-#define KSEG3ADDR(a)		(((a) & 0x1fffffff) | KSEG3)
-#endif
+#define KSEG0ADDR(a)		(CPHYSADDR(a) | KSEG0)
+#define KSEG1ADDR(a)		(CPHYSADDR(a) | KSEG1)
+#define KSEG2ADDR(a)		(CPHYSADDR(a) | KSEG2)
+#define KSEG3ADDR(a)		(CPHYSADDR(a) | KSEG3)
 
 /*
  * Memory segments (64bit kernel mode addresses)
  */
-#define XKUSEG                  0x0000000000000000
-#define XKSSEG                  0x4000000000000000
-#define XKPHYS                  0x8000000000000000
-#define XKSEG                   0xc000000000000000
-#define CKSEG0                  0xffffffff80000000
-#define CKSEG1                  0xffffffffa0000000
-#define CKSSEG                  0xffffffffc0000000
-#define CKSEG3                  0xffffffffe0000000
+#define XKUSEG			0x0000000000000000
+#define XKSSEG			0x4000000000000000
+#define XKPHYS			0x8000000000000000
+#define XKSEG			0xc000000000000000
+#define CKSEG0			0xffffffff80000000
+#define CKSEG1			0xffffffffa0000000
+#define CKSSEG			0xffffffffc0000000
+#define CKSEG3			0xffffffffe0000000
+
+/*
+ * Cache modes for XKPHYS address conversion macros
+ */
+#define K_CALG_COH_EXCL1_NOL2	0
+#define K_CALG_COH_SHRL1_NOL2	1
+#define K_CALG_UNCACHED		2
+#define K_CALG_NONCOHERENT	3
+#define K_CALG_COH_EXCL		4
+#define K_CALG_COH_SHAREABLE	5
+#define K_CALG_NOTUSED		6
+#define K_CALG_UNCACHED_ACCEL	7
+
+#define TO_PHYS_MASK		0xfffffffff			/* 36 bit */
+
+/*
+ * 64-bit address conversions
+ */
+#define PHYS_TO_XKSEG_UNCACHED(p)	PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p))
+#define PHYS_TO_XKSEG_CACHED(p)		PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p))
+#define XKPHYS_TO_PHYS(p)		((p) & TO_PHYS_MASK)
+#define PHYS_TO_XKPHYS(cm,a)		(0x8000000000000000 | ((cm)<<59) | (a))
 
 #endif /* __ASM_MIPS_ADDRSPACE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/asm.h linux/include/asm-mips/asm.h
--- linux.orig/include/asm-mips/asm.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/asm.h	2002-07-20 01:08:21.000000000 +0000
@@ -1,11 +1,10 @@
 /*
- * include/asm-mips/asm.h
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2002  Maciej W. Rozycki
  *
  * Some useful macros for MIPS assembler code
  *
@@ -16,6 +15,7 @@
 #ifndef	__ASM_ASM_H
 #define	__ASM_ASM_H
 
+#include <linux/config.h>
 #include <asm/sgidefs.h>
 
 #ifndef CAT
@@ -28,16 +28,6 @@
 #endif
 
 /*
- * Macros to handle different pointer/register sizes for 32/64-bit code
- *
- * 64 bit address space isn't used yet, so we may use the R3000 32 bit
- * defines for now.
- */
-#define PTR	.word
-#define PTRSIZE	4
-#define PTRLOG	2
-
-/*
  * PIC specific declarations
  * Not used for the kernel but here seems to be the right place.
  */
@@ -124,20 +114,20 @@
 		TEXT(string)
 
 #define	TEXT(msg)                                       \
-		.data;                                  \
+		.pushsection .data;			\
 8:		.asciiz	msg;                            \
-		.previous;
+		.popsection;
 
 /*
  * Build text tables
  */
 #define TTABLE(string)                                  \
-		.text;                                  \
+		.pushsection .text;			\
 		.word	1f;                             \
-		.previous;                              \
-		.data;                                  \
-1:		.asciz	string;                         \
-		.previous
+		.popsection				\
+		.pushsection .data;			\
+1:		.asciiz	string;                         \
+		.popsection
 
 /*
  * MIPS IV pref instruction.
@@ -146,15 +136,25 @@
  * MIPS IV implementations are free to treat this as a nop.  The R5000
  * is one of them.  So we should have an option not to use this instruction.
  */
-#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS64)
+#if CONFIG_CPU_HAS_PREFETCH
+
 #define PREF(hint,addr)                                 \
-		pref	hint,addr
+		.set	push;				\
+		.set	mips4;				\
+		pref	hint,addr;			\
+		.set	pop
+
 #define PREFX(hint,addr)                                \
-		prefx	hint,addr
+		.set	push;				\
+		.set	mips4;				\
+		prefx	hint,addr;			\
+		.set	pop
+
 #else
-#define PREF
-#define PREFX
+
+#define PREF(hint,addr)
+#define PREFX(hint,addr)
+
 #endif
 
 /*
@@ -163,14 +163,14 @@
 #if (_MIPS_ISA == _MIPS_ISA_MIPS1)
 #define MOVN(rd,rs,rt)                                  \
 		.set	push;				\
-		.set	noreorder;			\
+		.set	reorder;			\
 		beqz	rt,9f;                          \
 		move	rd,rs;                          \
 		.set	pop;				\
 9:
 #define MOVZ(rd,rs,rt)                                  \
 		.set	push;				\
-		.set	noreorder;			\
+		.set	reorder;			\
 		bnez	rt,9f;                          \
 		move	rd,rt;                          \
 		.set	pop;				\
@@ -181,24 +181,24 @@
 		.set	push;				\
 		.set	noreorder;			\
 		bnezl	rt,9f;                          \
-		move	rd,rs;                          \
+		 move	rd,rs;                          \
 		.set	pop;				\
 9:
 #define MOVZ(rd,rs,rt)                                  \
 		.set	push;				\
 		.set	noreorder;			\
 		beqzl	rt,9f;                          \
-		movz	rd,rs;                          \
+		 move	rd,rs;                          \
 		.set	pop;				\
 9:
 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS64)
+    (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
 #define MOVN(rd,rs,rt)                                  \
 		movn	rd,rs,rt
 #define MOVZ(rd,rs,rt)                                  \
 		movz	rd,rs,rt
-#endif /* MIPS IV, MIPS V or MIPS64 */
+#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
 
 /*
  * Stack alignment
@@ -215,6 +215,10 @@
 #endif
 
 /*
+ * Macros to handle different pointer/register sizes for 32/64-bit code
+ */
+
+/*
  * Size of a register
  */
 #ifdef __mips64
@@ -229,59 +233,54 @@
  */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS32)
-#define REG_S sw
-#define REG_L lw
-#define PTR_SUBU subu
-#define PTR_ADDU addu
+#define REG_S		sw
+#define REG_L		lw
+#define REG_SUBU	subu
+#define REG_ADDU	addu
 #endif
 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
-#define REG_S sd
-#define REG_L ld
-/* We still live in a 32 bit address space ...  */
-#define PTR_SUBU subu
-#define PTR_ADDU addu
+#define REG_S		sd
+#define REG_L		ld
+#define REG_SUBU	dsubu
+#define REG_ADDU	daddu
 #endif
 
 /*
  * How to add/sub/load/store/shift C int variables.
  */
 #if (_MIPS_SZINT == 32)
-#define INT_ADD	add
-#define INT_ADDI	addi
+#define INT_ADD		add
 #define INT_ADDU	addu
+#define INT_ADDI	addi
 #define INT_ADDIU	addiu
-#define INT_SUB	add
-#define INT_SUBI	subi
+#define INT_SUB		sub
 #define INT_SUBU	subu
-#define INT_SUBIU	subu
 #define INT_L		lw
 #define INT_S		sw
-#define LONG_SLL	sll
-#define LONG_SLLV	sllv
-#define LONG_SRL	srl
-#define LONG_SRLV	srlv
-#define LONG_SRA	sra
-#define LONG_SRAV	srav
+#define INT_SLL		sll
+#define INT_SLLV	sllv
+#define INT_SRL		srl
+#define INT_SRLV	srlv
+#define INT_SRA		sra
+#define INT_SRAV	srav
 #endif
 
 #if (_MIPS_SZINT == 64)
-#define INT_ADD	dadd
-#define INT_ADDI	daddi
+#define INT_ADD		dadd
 #define INT_ADDU	daddu
+#define INT_ADDI	daddi
 #define INT_ADDIU	daddiu
-#define INT_SUB	dadd
-#define INT_SUBI	dsubi
+#define INT_SUB		dsub
 #define INT_SUBU	dsubu
-#define INT_SUBIU	dsubu
 #define INT_L		ld
 #define INT_S		sd
-#define LONG_SLL	dsll
-#define LONG_SLLV	dsllv
-#define LONG_SRL	dsrl
-#define LONG_SRLV	dsrlv
-#define LONG_SRA	dsra
-#define LONG_SRAV	dsrav
+#define INT_SLL		dsll
+#define INT_SLLV	dsllv
+#define INT_SRL		dsrl
+#define INT_SRLV	dsrlv
+#define INT_SRA		dsra
+#define INT_SRAV	dsrav
 #endif
 
 /*
@@ -289,13 +288,11 @@
  */
 #if (_MIPS_SZLONG == 32)
 #define LONG_ADD	add
-#define LONG_ADDI	addi
 #define LONG_ADDU	addu
+#define LONG_ADDI	addi
 #define LONG_ADDIU	addiu
-#define LONG_SUB	add
-#define LONG_SUBI	subi
+#define LONG_SUB	sub
 #define LONG_SUBU	subu
-#define LONG_SUBIU	subu
 #define LONG_L		lw
 #define LONG_S		sw
 #define LONG_SLL	sll
@@ -308,13 +305,11 @@
 
 #if (_MIPS_SZLONG == 64)
 #define LONG_ADD	dadd
-#define LONG_ADDI	daddi
 #define LONG_ADDU	daddu
+#define LONG_ADDI	daddi
 #define LONG_ADDIU	daddiu
-#define LONG_SUB	dadd
-#define LONG_SUBI	dsubi
+#define LONG_SUB	dsub
 #define LONG_SUBU	dsubu
-#define LONG_SUBIU	dsubu
 #define LONG_L		ld
 #define LONG_S		sd
 #define LONG_SLL	dsll
@@ -328,17 +323,16 @@
 /*
  * How to add/sub/load/store/shift pointers.
  */
-#if (_MIPS_SZLONG == 32)
-#define PTR_ADD	add
-#define PTR_ADDI	addi
+#if (_MIPS_SZPTR == 32)
+#define PTR_ADD		add
 #define PTR_ADDU	addu
+#define PTR_ADDI	addi
 #define PTR_ADDIU	addiu
-#define PTR_SUB		add
-#define PTR_SUBI	subi
+#define PTR_SUB		sub
 #define PTR_SUBU	subu
-#define PTR_SUBIU	subu
 #define PTR_L		lw
 #define PTR_S		sw
+#define PTR_LA		la
 #define PTR_SLL		sll
 #define PTR_SLLV	sllv
 #define PTR_SRL		srl
@@ -347,19 +341,22 @@
 #define PTR_SRAV	srav
 
 #define PTR_SCALESHIFT	2
+
+#define PTR		.word
+#define PTRSIZE		4
+#define PTRLOG		2
 #endif
 
-#if (_MIPS_SZLONG == 64)
-#define PTR_ADD	dadd
-#define PTR_ADDI	daddi
+#if (_MIPS_SZPTR == 64)
+#define PTR_ADD		dadd
 #define PTR_ADDU	daddu
+#define PTR_ADDI	daddi
 #define PTR_ADDIU	daddiu
-#define PTR_SUB		dadd
-#define PTR_SUBI	dsubi
+#define PTR_SUB		dsub
 #define PTR_SUBU	dsubu
-#define PTR_SUBIU	dsubu
 #define PTR_L		ld
 #define PTR_S		sd
+#define PTR_LA		dla
 #define PTR_SLL		dsll
 #define PTR_SLLV	dsllv
 #define PTR_SRL		dsrl
@@ -368,6 +365,10 @@
 #define PTR_SRAV	dsrav
 
 #define PTR_SCALESHIFT	3
+
+#define PTR		.dword
+#define PTRSIZE		8
+#define PTRLOG		3
 #endif
 
 /*
@@ -375,13 +376,15 @@
  */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS32)
-#define MFC0	mfc0
-#define MTC0	mtc0
+#define MFC0		mfc0
+#define MTC0		mtc0
 #endif
 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
-#define MFC0	dmfc0
-#define MTC0	dmtc0
+#define MFC0		dmfc0
+#define MTC0		dmtc0
 #endif
 
+#define SSNOP		sll zero,zero,1
+
 #endif /* __ASM_ASM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/atomic.h linux/include/asm-mips/atomic.h
--- linux.orig/include/asm-mips/atomic.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/atomic.h	2002-07-20 01:08:21.000000000 +0000
@@ -175,6 +175,7 @@
 		"     sc      %0, %2                        \n"
 		"     beqz    %0, 1b                        \n"
 		"     addu    %0, %1, %3                    \n"
+		"     sync                                  \n"
 		".set pop                                   \n"
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
@@ -195,6 +196,7 @@
 		"     sc    %0, %2                           \n"
 		"     beqz  %0, 1b                           \n"
 		"     subu  %0, %1, %3                       \n"
+		"     sync                                   \n"
 		".set pop                                    \n"
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
@@ -273,10 +275,10 @@
  */
 
 /* Atomic operations are already serializing */
-#define smp_mb__before_atomic_dec()	barrier()
-#define smp_mb__after_atomic_dec()	barrier()
-#define smp_mb__before_atomic_inc()	barrier()
-#define smp_mb__after_atomic_inc()	barrier()
+#define smp_mb__before_atomic_dec()	smp_mb()
+#define smp_mb__after_atomic_dec()	smp_mb()
+#define smp_mb__before_atomic_inc()	smp_mb()
+#define smp_mb__after_atomic_inc()	smp_mb()
 
 #endif /* defined(__KERNEL__) */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/au1000.h linux/include/asm-mips/au1000.h
--- linux.orig/include/asm-mips/au1000.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/au1000.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,9 +1,9 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *	Include file for Alchemy Semiconductor's Au1000 CPU.
+ *	Include file for Alchemy Semiconductor's Au1k CPU.
  *
- * Copyright 2000 MontaVista Software Inc.
+ * Copyright 2000,2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
@@ -31,188 +31,172 @@
 #ifndef _AU1000_H_
 #define _AU1000_H_
 
+#include <linux/delay.h>
+#include <asm/io.h>
+
+/* cpu pipeline flush */
+void static inline au_sync(void)
+{
+	__asm__ volatile ("sync");
+}
+
+void static inline au_sync_udelay(int us)
+{
+	__asm__ volatile ("sync");
+	udelay(us);
+}
+
+void static inline au_sync_delay(int ms)
+{
+	__asm__ volatile ("sync");
+	mdelay(ms);
+}
+
+void static inline outb_sync(u8 val, int reg)
+{
+	outb(val, reg);
+	au_sync();
+}
+
+void static inline outw_sync(u16 val, int reg)
+{
+	outw(val, reg);
+	au_sync();
+}
+
+void static inline outl_sync(u32 val, int reg)
+{
+	outl(val, reg);
+	au_sync();
+}
+
+/* arch/mips/au1000/common/clocks.c */
+extern void set_au1000_speed(unsigned int new_freq);
+extern unsigned int get_au1000_speed(void);
+extern void set_au1000_uart_baud_base(unsigned long new_baud_base);
+extern unsigned long get_au1000_uart_baud_base(void);
+extern void set_au1000_lcd_clock(void);
+extern unsigned int get_au1000_lcd_clock(void);
+
+#ifdef CONFIG_PM
+/* no CP0 timer irq */
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
+#else
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+#endif
+
 /* SDRAM Controller */
-#define CS_MODE_0                0x14000000
-#define CS_MODE_1                0x14000004
-#define CS_MODE_2                0x14000008
-
-#define CS_CONFIG_0              0x1400000C
-#define CS_CONFIG_1              0x14000010
-#define CS_CONFIG_2              0x14000014
-
-#define REFRESH_CONFIG           0x14000018
-#define PRECHARGE_CMD            0x1400001C
-#define AUTO_REFRESH_CMD         0x14000020
-
-#define WRITE_EXTERN_0           0x14000024
-#define WRITE_EXTERN_1           0x14000028
-#define WRITE_EXTERN_2           0x1400002C
+#define MEM_SDMODE0                0xB4000000
+#define MEM_SDMODE1                0xB4000004
+#define MEM_SDMODE2                0xB4000008
+
+#define MEM_SDADDR0                0xB400000C
+#define MEM_SDADDR1                0xB4000010
+#define MEM_SDADDR2                0xB4000014
+
+#define MEM_SDREFCFG               0xB4000018
+#define MEM_SDPRECMD               0xB400001C
+#define MEM_SDAUTOREF              0xB4000020
+
+#define MEM_SDWRMD0                0xB4000024
+#define MEM_SDWRMD1                0xB4000028
+#define MEM_SDWRMD2                0xB400002C
 
-#define SDRAM_SLEEP              0x14000030
-#define TOGGLE_CKE               0x14000034
+#define MEM_SDSLEEP                0xB4000030
+#define MEM_SDSMCKE                0xB4000034
 
 /* Static Bus Controller */
-#define STATIC_CONFIG_0          0x14001000
-#define STATIC_TIMING_0          0x14001004
-#define STATIC_ADDRESS_0         0x14001008
-
-#define STATIC_CONFIG_1          0x14001010
-#define STATIC_TIMING_1          0x14001014
-#define STATIC_ADDRESS_1         0x14001018
-
-#define STATIC_CONFIG_2          0x14001020
-#define STATIC_TIMING_2          0x14001024
-#define STATIC_ADDRESS_2         0x14001028
-
-#define STATIC_CONFIG_3          0x14001030
-#define STATIC_TIMING_3          0x14001034
-#define STATIC_ADDRESS_3         0x14001038
-
-/* DMA Controller 0 */
-#define DMA0_MODE_SET            0x14002000
-#define DMA0_MODE_CLEAR          0x14002004
-#define DMA0_PERIPHERAL_ADDR     0x14002008
-#define DMA0_BUFFER0_START       0x1400200C
-#define DMA0_BUFFER0_COUNT       0x14002010
-#define DMA0_BUFFER1_START       0x14002014
-#define DMA0_BUFFER1_COUNT       0x14002018
-
-/* DMA Controller 1 */
-#define DMA1_MODE_SET            0x14002100
-#define DMA1_MODE_CLEAR          0x14002104
-#define DMA1_PERIPHERAL_ADDR     0x14002108
-#define DMA1_BUFFER0_START       0x1400210C
-#define DMA1_BUFFER0_COUNT       0x14002110
-#define DMA1_BUFFER1_START       0x14002114
-#define DMA1_BUFFER1_COUNT       0x14002118
-
-/* DMA Controller 2 */
-#define DMA2_MODE_SET            0x14002200
-#define DMA2_MODE_CLEAR          0x14002204
-#define DMA2_PERIPHERAL_ADDR     0x14002208
-#define DMA2_BUFFER0_START       0x1400220C
-#define DMA2_BUFFER0_COUNT       0x14002210
-#define DMA2_BUFFER1_START       0x14002214
-#define DMA2_BUFFER1_COUNT       0x14002218
-
-/* DMA Controller 3 */
-#define DMA3_MODE_SET            0x14002300
-#define DMA3_MODE_CLEAR          0x14002304
-#define DMA3_PERIPHERAL_ADDR     0x14002308
-#define DMA3_BUFFER0_START       0x1400230C
-#define DMA3_BUFFER0_COUNT       0x14002310
-#define DMA3_BUFFER1_START       0x14002314
-#define DMA3_BUFFER1_COUNT       0x14002318
-
-/* DMA Controller 4 */
-#define DMA4_MODE_SET            0x14002400
-#define DMA4_MODE_CLEAR          0x14002404
-#define DMA4_PERIPHERAL_ADDR     0x14002408
-#define DMA4_BUFFER0_START       0x1400240C
-#define DMA4_BUFFER0_COUNT       0x14002410
-#define DMA4_BUFFER1_START       0x14002414
-#define DMA4_BUFFER1_COUNT       0x14002418
-
-/* DMA Controller 5 */
-#define DMA5_MODE_SET            0x14002500
-#define DMA5_MODE_CLEAR          0x14002504
-#define DMA5_PERIPHERAL_ADDR     0x14002508
-#define DMA5_BUFFER0_START       0x1400250C
-#define DMA5_BUFFER0_COUNT       0x14002510
-#define DMA5_BUFFER1_START       0x14002514
-#define DMA5_BUFFER1_COUNT       0x14002518
-
-/* DMA Controller 6 */
-#define DMA6_MODE_SET            0x14002600
-#define DMA6_MODE_CLEAR          0x14002604
-#define DMA6_PERIPHERAL_ADDR     0x14002608
-#define DMA6_BUFFER0_START       0x1400260C
-#define DMA6_BUFFER0_COUNT       0x14002610
-#define DMA6_BUFFER1_START       0x14002614
-#define DMA6_BUFFER1_COUNT       0x14002618
-
-/* DMA Controller 7 */
-#define DMA7_MODE_SET            0x14002700
-#define DMA7_MODE_CLEAR          0x14002704
-#define DMA7_PERIPHERAL_ADDR     0x14002708
-#define DMA7_BUFFER0_START       0x1400270C
-#define DMA7_BUFFER0_COUNT       0x14002710
-#define DMA7_BUFFER1_START       0x14002714
-#define DMA7_BUFFER1_COUNT       0x14002718
+#define MEM_STCFG0                 0xB4001000
+#define MEM_STTIME0                0xB4001004
+#define MEM_STADDR0                0xB4001008
+
+#define MEM_STCFG1                 0xB4001010
+#define MEM_STTIME1                0xB4001014
+#define MEM_STADDR1                0xB4001018
+
+#define MEM_STCFG2                 0xB4001020
+#define MEM_STTIME2                0xB4001024
+#define MEM_STADDR2                0xB4001028
+
+#define MEM_STCFG3                 0xB4001030
+#define MEM_STTIME3                0xB4001034
+#define MEM_STADDR3                0xB4001038
 
 /* Interrupt Controller 0 */
-#define INTC0_CONFIG0_READ        0x10400040
-#define INTC0_CONFIG0_SET         0x10400040
-#define INTC0_CONFIG0_CLEAR       0x10400044
-
-#define INTC0_CONFIG1_READ        0x10400048
-#define INTC0_CONFIG1_SET         0x10400048
-#define INTC0_CONFIG1_CLEAR       0x1040004C
-
-#define INTC0_CONFIG2_READ        0x10400050
-#define INTC0_CONFIG2_SET         0x10400050
-#define INTC0_CONFIG2_CLEAR       0x10400054
-
-#define INTC0_REQ0_INT            0x10400054
-#define INTC0_SOURCE_READ         0x10400058
-#define INTC0_SOURCE_SET          0x10400058
-#define INTC0_SOURCE_CLEAR        0x1040005C
-#define INTC0_REQ1_INT            0x1040005C
-
-#define INTC0_ASSIGN_REQ_READ     0x10400060
-#define INTC0_ASSIGN_REQ_SET      0x10400060
-#define INTC0_ASSIGN_REQ_CLEAR    0x10400064
-
-#define INTC0_WAKEUP_READ         0x10400068
-#define INTC0_WAKEUP_SET          0x10400068
-#define INTC0_WAKEUP_CLEAR        0x1040006C
-
-#define INTC0_MASK_READ           0x10400070
-#define INTC0_MASK_SET            0x10400070
-#define INTC0_MASK_CLEAR          0x10400074
-
-#define INTC0_R_EDGE_DETECT       0x10400078
-#define INTC0_R_EDGE_DETECT_CLEAR 0x10400078
-#define INTC0_F_EDGE_DETECT_CLEAR 0x1040007C
+#define IC0_CFG0RD                 0xB0400040
+#define IC0_CFG0SET                0xB0400040
+#define IC0_CFG0CLR                0xB0400044
+
+#define IC0_CFG1RD                 0xB0400048
+#define IC0_CFG1SET                0xB0400048
+#define IC0_CFG1CLR                0xB040004C
+
+#define IC0_CFG2RD                 0xB0400050
+#define IC0_CFG2SET                0xB0400050
+#define IC0_CFG2CLR                0xB0400054
+
+#define IC0_REQ0INT                0xB0400054
+#define IC0_SRCRD                  0xB0400058
+#define IC0_SRCSET                 0xB0400058
+#define IC0_SRCCLR                 0xB040005C
+#define IC0_REQ1INT                0xB040005C
+
+#define IC0_ASSIGNRD               0xB0400060
+#define IC0_ASSIGNSET              0xB0400060
+#define IC0_ASSIGNCLR              0xB0400064
+
+#define IC0_WAKERD                 0xB0400068
+#define IC0_WAKESET                0xB0400068
+#define IC0_WAKECLR                0xB040006C
+
+#define IC0_MASKRD                 0xB0400070
+#define IC0_MASKSET                0xB0400070
+#define IC0_MASKCLR                0xB0400074
+
+#define IC0_RISINGRD               0xB0400078
+#define IC0_RISINGCLR              0xB0400078
+#define IC0_FALLINGRD              0xB040007C
+#define IC0_FALLINGCLR             0xB040007C
 
-#define INTC0_TEST_BIT            0x10400080
+#define IC0_TESTBIT                0xB0400080
 
 /* Interrupt Controller 1 */
-#define INTC1_CONFIG0_READ        0x11800040
-#define INTC1_CONFIG0_SET         0x11800040
-#define INTC1_CONFIG0_CLEAR       0x11800044
-
-#define INTC1_CONFIG1_READ        0x11800048
-#define INTC1_CONFIG1_SET         0x11800048
-#define INTC1_CONFIG1_CLEAR       0x1180004C
-
-#define INTC1_CONFIG2_READ        0x11800050
-#define INTC1_CONFIG2_SET         0x11800050
-#define INTC1_CONFIG2_CLEAR       0x11800054
-
-#define INTC1_REQ0_INT            0x11800054
-#define INTC1_SOURCE_READ         0x11800058
-#define INTC1_SOURCE_SET          0x11800058
-#define INTC1_SOURCE_CLEAR        0x1180005C
-#define INTC1_REQ1_INT            0x1180005C
-
-#define INTC1_ASSIGN_REQ_READ     0x11800060
-#define INTC1_ASSIGN_REQ_SET      0x11800060
-#define INTC1_ASSIGN_REQ_CLEAR    0x11800064
-
-#define INTC1_WAKEUP_READ         0x11800068
-#define INTC1_WAKEUP_SET          0x11800068
-#define INTC1_WAKEUP_CLEAR        0x1180006C
-
-#define INTC1_MASK_READ           0x11800070
-#define INTC1_MASK_SET            0x11800070
-#define INTC1_MASK_CLEAR          0x11800074
-
-#define INTC1_R_EDGE_DETECT       0x11800078
-#define INTC1_R_EDGE_DETECT_CLEAR 0x11800078
-#define INTC1_F_EDGE_DETECT_CLEAR 0x1180007C
+#define IC1_CFG0RD                 0xB1800040
+#define IC1_CFG0SET                0xB1800040
+#define IC1_CFG0CLR                0xB1800044
+
+#define IC1_CFG1RD                 0xB1800048
+#define IC1_CFG1SET                0xB1800048
+#define IC1_CFG1CLR                0xB180004C
+
+#define IC1_CFG2RD                 0xB1800050
+#define IC1_CFG2SET                0xB1800050
+#define IC1_CFG2CLR                0xB1800054
+
+#define IC1_REQ0INT                0xB1800054
+#define IC1_SRCRD                  0xB1800058
+#define IC1_SRCSET                 0xB1800058
+#define IC1_SRCCLR                 0xB180005C
+#define IC1_REQ1INT                0xB180005C
+
+#define IC1_ASSIGNRD               0xB1800060
+#define IC1_ASSIGNSET              0xB1800060
+#define IC1_ASSIGNCLR              0xB1800064
+
+#define IC1_WAKERD                 0xB1800068
+#define IC1_WAKESET                0xB1800068
+#define IC1_WAKECLR                0xB180006C
+
+#define IC1_MASKRD                 0xB1800070
+#define IC1_MASKSET                0xB1800070
+#define IC1_MASKCLR                0xB1800074
+
+#define IC1_RISINGRD               0xB1800078
+#define IC1_RISINGCLR              0xB1800078
+#define IC1_FALLINGRD              0xB180007C
+#define IC1_FALLINGCLR             0xB180007C
 
-#define INTC1_TEST_BIT            0x11800080
+#define IC1_TESTBIT                0xB1800080
 
 /* Interrupt Configuration Modes */
 #define INTC_INT_DISABLED                0
@@ -225,29 +209,31 @@
 
 /* Interrupt Numbers */
 #define AU1000_UART0_INT          0
-#define AU1000_UART1_INT          1
-#define AU1000_UART2_INT          2
+#define AU1000_UART1_INT          1 /* au1000 */
+#define AU1000_UART2_INT          2 /* au1000 */
+
+#define AU1000_PCI_INTA           1 /* au1500 */
+#define AU1000_PCI_INTB           2 /* au1500 */
+
 #define AU1000_UART3_INT          3
-#define AU1000_SSI0_INT           4
-#define AU1000_SSI1_INT           5
-#define AU1000_DMA0_INT           6
-#define AU1000_DMA1_INT           7
-#define AU1000_DMA2_INT           8
-#define AU1000_DMA3_INT           9
-#define AU1000_DMA4_INT           10
-#define AU1000_DMA5_INT           11
-#define AU1000_DMA6_INT           12
-#define AU1000_DMA7_INT           13
-#define AU1000_PC0_INT            14
-#define AU1000_PC0_MATCH0_INT     15
-#define AU1000_PC0_MATCH1_INT     16
-#define AU1000_PC0_MATCH2_INT     17
-#define AU1000_PC1_INT            18
-#define AU1000_PC1_MATCH0_INT     19
-#define AU1000_PC1_MATCH1_INT     20
-#define AU1000_PC1_MATCH2_INT     21
-#define AU1000_IRDA_TX_INT        22
-#define AU1000_IRDA_RX_INT        23
+
+#define AU1000_SSI0_INT           4 /* au1000 */
+#define AU1000_SSI1_INT           5 /* au1000 */
+
+#define AU1000_PCI_INTC           4 /* au1500 */
+#define AU1000_PCI_INTD           5 /* au1500 */
+
+#define AU1000_DMA_INT_BASE       6
+#define AU1000_TOY_INT            14
+#define AU1000_TOY_MATCH0_INT     15
+#define AU1000_TOY_MATCH1_INT     16
+#define AU1000_TOY_MATCH2_INT     17
+#define AU1000_RTC_INT            18
+#define AU1000_RTC_MATCH0_INT     19
+#define AU1000_RTC_MATCH1_INT     20
+#define AU1000_RTC_MATCH2_INT     21
+#define AU1000_IRDA_TX_INT        22 /* au1000 */
+#define AU1000_IRDA_RX_INT        23 /* au1000 */
 #define AU1000_USB_DEV_REQ_INT    24
 #define AU1000_USB_DEV_SUS_INT    25
 #define AU1000_USB_HOST_INT       26
@@ -256,9 +242,9 @@
 #define AU1000_MAC1_DMA_INT       29
 #define AU1000_ETH0_IRQ           AU1000_MAC0_DMA_INT
 #define AU1000_ETH1_IRQ           AU1000_MAC1_DMA_INT
-#define AU1000_I2S_UO_INT         30
-#define AU1000_AC97_INT           31
-#define AU1000_LAST_INTC0_INT     AU1000_AC97_INT
+#define AU1000_I2S_UO_INT         30 /* au1000 */
+#define AU1000_AC97C_INT          31
+#define AU1000_LAST_INTC0_INT     AU1000_AC97C_INT
 #define AU1000_GPIO_0             32
 #define AU1000_GPIO_1             33
 #define AU1000_GPIO_2             34
@@ -275,6 +261,8 @@
 #define AU1000_GPIO_13            45
 #define AU1000_GPIO_14            46
 #define AU1000_GPIO_15            47
+
+/* Au1000 only */
 #define AU1000_GPIO_16            48
 #define AU1000_GPIO_17            49
 #define AU1000_GPIO_18            50
@@ -292,54 +280,124 @@
 #define AU1000_GPIO_30            62
 #define AU1000_GPIO_31            63
 
+/* Au1500 only */
+#define AU1500_GPIO_200           48
+#define AU1500_GPIO_201           49
+#define AU1500_GPIO_202           50
+#define AU1500_GPIO_203           51
+#define AU1500_GPIO_20            52
+#define AU1500_GPIO_204           53
+#define AU1500_GPIO_205           54
+#define AU1500_GPIO_23            55
+#define AU1500_GPIO_24            56
+#define AU1500_GPIO_25            57
+#define AU1500_GPIO_26            58
+#define AU1500_GPIO_27            59
+#define AU1500_GPIO_28            60
+#define AU1500_GPIO_206           61
+#define AU1500_GPIO_207           62
+#define AU1500_GPIO_208_215       63
+
+#define AU1000_MAX_INTR           63
+
 /* Programmable Counters 0 and 1 */
-#define PC_BASE                   0x11900000
-#define PC_COUNTER_CNTRL          (PC_BASE + 0x14)
-  #define PC_CNTRL_E1S            (1<<23)
-  #define PC_CNTRL_T1S            (1<<20)
-  #define PC_CNTRL_M21            (1<<19)
-  #define PC_CNTRL_M11            (1<<18)
-  #define PC_CNTRL_M01            (1<<17)
-  #define PC_CNTRL_C1S            (1<<16)
-  #define PC_CNTRL_BP             (1<<14)
-  #define PC_CNTRL_EN1            (1<<13)
-  #define PC_CNTRL_BT1            (1<<12)
-  #define PC_CNTRL_EN0            (1<<11)
-  #define PC_CNTRL_BT0            (1<<10)
-  #define PC_CNTRL_E0             (1<<8)
-  #define PC_CNTRL_E0S            (1<<7)
-  #define PC_CNTRL_32S            (1<<5)
-  #define PC_CNTRL_T0S            (1<<4)
-  #define PC_CNTRL_M20            (1<<3)
-  #define PC_CNTRL_M10            (1<<2)
-  #define PC_CNTRL_M00            (1<<1)
-  #define PC_CNTRL_C0S            (1<<0)
+#define SYS_BASE                   0xB1900000
+#define SYS_COUNTER_CNTRL          (SYS_BASE + 0x14)
+  #define SYS_CNTRL_E1S            (1<<23)
+  #define SYS_CNTRL_T1S            (1<<20)
+  #define SYS_CNTRL_M21            (1<<19)
+  #define SYS_CNTRL_M11            (1<<18)
+  #define SYS_CNTRL_M01            (1<<17)
+  #define SYS_CNTRL_C1S            (1<<16)
+  #define SYS_CNTRL_BP             (1<<14)
+  #define SYS_CNTRL_EN1            (1<<13)
+  #define SYS_CNTRL_BT1            (1<<12)
+  #define SYS_CNTRL_EN0            (1<<11)
+  #define SYS_CNTRL_BT0            (1<<10)
+  #define SYS_CNTRL_E0             (1<<8)
+  #define SYS_CNTRL_E0S            (1<<7)
+  #define SYS_CNTRL_32S            (1<<5)
+  #define SYS_CNTRL_T0S            (1<<4)
+  #define SYS_CNTRL_M20            (1<<3)
+  #define SYS_CNTRL_M10            (1<<2)
+  #define SYS_CNTRL_M00            (1<<1)
+  #define SYS_CNTRL_C0S            (1<<0)
 
 /* Programmable Counter 0 Registers */
-#define PC0_TRIM                  (PC_BASE + 0)
-#define PC0_COUNTER_WRITE         (PC_BASE + 4)
-#define PC0_MATCH0                (PC_BASE + 8)
-#define PC0_MATCH1                (PC_BASE + 0xC)
-#define PC0_MATCH2                (PC_BASE + 0x10)
-#define PC0_COUNTER_READ          (PC_BASE + 0x40)
+#define SYS_TOYTRIM                 (SYS_BASE + 0)
+#define SYS_TOYWRITE                (SYS_BASE + 4)
+#define SYS_TOYMATCH0               (SYS_BASE + 8)
+#define SYS_TOYMATCH1               (SYS_BASE + 0xC)
+#define SYS_TOYMATCH2               (SYS_BASE + 0x10)
+#define SYS_TOYREAD                 (SYS_BASE + 0x40)
 
 /* Programmable Counter 1 Registers */
-#define PC1_TRIM                  (PC_BASE + 0x44)
-#define PC1_COUNTER_WRITE         (PC_BASE + 0x48)
-#define PC1_MATCH0                (PC_BASE + 0x4C)
-#define PC1_MATCH1                (PC_BASE + 0x50)
-#define PC1_MATCH2                (PC_BASE + 0x54)
-#define PC1_COUNTER_READ          (PC_BASE + 0x58)
+#define SYS_RTCTRIM                 (SYS_BASE + 0x44)
+#define SYS_RTCWRITE                (SYS_BASE + 0x48)
+#define SYS_RTCMATCH0               (SYS_BASE + 0x4C)
+#define SYS_RTCMATCH1               (SYS_BASE + 0x50)
+#define SYS_RTCMATCH2               (SYS_BASE + 0x54)
+#define SYS_RTCREAD                 (SYS_BASE + 0x58)
 
 
 /* I2S Controller */
-#define I2S_DATA                  0x11000000
-#define I2S_CONFIG_STATUS         0x11000001
-#define I2S_CONTROL               0x11000002
+#define I2S_DATA                    0xB1000000
+#define I2S_CONFIG                  0xB1000001
+#define I2S_ENABLE                  0xB1000002
+
+/* USB Host Controller */
+// We pass USB_OHCI_BASE to ioremap, so it needs to be a physical address
+#define USB_OHCI_BASE             0x10100000
+#define USB_OHCI_LEN              0x00100000
+#define USB_HOST_CONFIG           0xB017fffc
+
+/* USB Device Controller */
+#define USBD_EP0RD                0xB0200000
+#define USBD_EP0WR                0xB0200004
+#define USBD_EP2WR                0xB0200008
+#define USBD_EP3WR                0xB020000C
+#define USBD_EP4RD                0xB0200010
+#define USBD_EP5RD                0xB0200014
+#define USBD_INTEN                0xB0200018
+#define USBD_INTSTAT              0xB020001C
+  #define USBDEV_INT_SOF       (1<<12)
+  #define USBDEV_INT_HF_BIT    6
+  #define USBDEV_INT_HF_MASK   (0x3f << USBDEV_INT_HF_BIT)
+  #define USBDEV_INT_CMPLT_BIT  0
+  #define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT)
+#define USBD_CONFIG               0xB0200020
+#define USBD_EP0CS                0xB0200024
+#define USBD_EP2CS                0xB0200028
+#define USBD_EP3CS                0xB020002C
+#define USBD_EP4CS                0xB0200030
+#define USBD_EP5CS                0xB0200034
+  #define USBDEV_CS_SU         (1<<14)
+  #define USBDEV_CS_NAK        (1<<13)
+  #define USBDEV_CS_ACK        (1<<12)
+  #define USBDEV_CS_BUSY       (1<<11)
+  #define USBDEV_CS_TSIZE_BIT  1
+  #define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT)
+  #define USBDEV_CS_STALL      (1<<0)
+#define USBD_EP0RDSTAT            0xB0200040
+#define USBD_EP0WRSTAT            0xB0200044
+#define USBD_EP2WRSTAT            0xB0200048
+#define USBD_EP3WRSTAT            0xB020004C
+#define USBD_EP4RDSTAT            0xB0200050
+#define USBD_EP5RDSTAT            0xB0200054
+  #define USBDEV_FSTAT_FLUSH     (1<<6)
+  #define USBDEV_FSTAT_UF        (1<<5)
+  #define USBDEV_FSTAT_OF        (1<<4)
+  #define USBDEV_FSTAT_FCNT_BIT  0
+  #define USBDEV_FSTAT_FCNT_MASK (0x0f << USBDEV_FSTAT_FCNT_BIT)
+#define USBD_ENABLE               0xB0200058
+  #define USBDEV_ENABLE (1<<1)
+  #define USBDEV_CE     (1<<0)
 
 /* Ethernet Controllers  */
-#define AU1000_ETH0_BASE          0x10500000
-#define AU1000_ETH1_BASE          0x10510000
+#define AU1000_ETH0_BASE          0xB0500000
+#define AU1000_ETH1_BASE          0xB0510000
+#define AU1500_ETH0_BASE	  0xB1500000
+#define AU1500_ETH1_BASE	  0xB1510000
 
 /* 4 byte offsets from AU1000_ETH_BASE */
 #define MAC_CONTROL                     0x0
@@ -384,11 +442,13 @@
 #define MAC_VLAN2_TAG                  0x24
 
 /* Ethernet Controller Enable */
-#define MAC0_ENABLE               0x10520000
-#define MAC1_ENABLE               0x10520004
+#define AU1000_MAC0_ENABLE       0xB0520000
+#define AU1000_MAC1_ENABLE       0xB0520004
+#define AU1500_MAC0_ENABLE       0xB1520000
+#define AU1500_MAC1_ENABLE       0xB1520004
   #define MAC_EN_CLOCK_ENABLE         (1<<0)
   #define MAC_EN_RESET0               (1<<1)
-  #define MAC_EN_TOSS                 (1<<2)
+  #define MAC_EN_TOSS                 (0<<2)
   #define MAC_EN_CACHEABLE            (1<<3)
   #define MAC_EN_RESET1               (1<<4)
   #define MAC_EN_RESET2               (1<<5)
@@ -396,8 +456,8 @@
 
 /* Ethernet Controller DMA Channels */
 
-#define MAC0_TX_DMA_ADDR         0x14004000
-#define MAC1_TX_DMA_ADDR         0x14004200
+#define MAC0_TX_DMA_ADDR         0xB4004000
+#define MAC1_TX_DMA_ADDR         0xB4004200
 /* offsets from MAC_TX_RING_ADDR address */
 #define MAC_TX_BUFF0_STATUS             0x0
   #define TX_FRAME_ABORTED            (1<<0)
@@ -427,8 +487,8 @@
 #define MAC_TX_BUFF3_ADDR               0x34
 #define MAC_TX_BUFF3_LEN                0x38
 
-#define MAC0_RX_DMA_ADDR         0x14004100
-#define MAC1_RX_DMA_ADDR         0x14004300
+#define MAC0_RX_DMA_ADDR         0xB4004100
+#define MAC1_RX_DMA_ADDR         0xB4004300
 /* offsets from MAC_RX_RING_ADDR */
 #define MAC_RX_BUFF0_STATUS              0x0
   #define RX_FRAME_LEN_MASK           0x3fff
@@ -468,10 +528,11 @@
 
 
 /* UARTS 0-3 */
-#define UART0_ADDR                0x11100000
-#define UART1_ADDR                0x11200000
-#define UART2_ADDR                0x11300000
-#define UART3_ADDR                0x11400000
+#define UART_BASE                 0xB1100000
+#define UART0_ADDR                0xB1100000
+#define UART1_ADDR                0xB1200000
+#define UART2_ADDR                0xB1300000
+#define UART3_ADDR                0xB1400000
 
 #define UART_RX		0	/* Receive buffer */
 #define UART_TX		4	/* Transmit buffer */
@@ -482,7 +543,7 @@
 #define UART_MCR	0x18	/* Modem Control Register */
 #define UART_LSR	0x1C	/* Line Status Register */
 #define UART_MSR	0x20	/* Modem Status Register */
-#define UART_CLK	0x28	/* Baud Rat4e Clock Divider */
+#define UART_CLK	0x28	/* Baud Rate Clock Divider */
 #define UART_MOD_CNTRL	0x100	/* Module Control */
 
 #define UART_FCR_ENABLE_FIFO	0x01 /* Enable the FIFO */
@@ -566,70 +627,152 @@
 
 
 /* SSIO */
-#define SSI0_STATUS                0x11600000
-#define SSI0_INT                   0x11600004
-#define SSI0_INT_ENABLE            0x11600008
-#define SSI0_CONFIG                0x11600020
-#define SSI0_ADATA                 0x11600024
-#define SSI0_CLKDIV                0x11600028
-#define SSI0_CONTROL               0x11600100
+#define SSI0_STATUS                0xB1600000
+#define SSI0_INT                   0xB1600004
+#define SSI0_INT_ENABLE            0xB1600008
+#define SSI0_CONFIG                0xB1600020
+#define SSI0_ADATA                 0xB1600024
+#define SSI0_CLKDIV                0xB1600028
+#define SSI0_CONTROL               0xB1600100
 
 /* SSI1 */
-#define SSI1_STATUS                0x11680000
-#define SSI1_INT                   0x11680004
-#define SSI1_INT_ENABLE            0x11680008
-#define SSI1_CONFIG                0x11680020
-#define SSI1_ADATA                 0x11680024
-#define SSI1_CLKDIV                0x11680028
-#define SSI1_CONTROL               0x11680100
+#define SSI1_STATUS                0xB1680000
+#define SSI1_INT                   0xB1680004
+#define SSI1_INT_ENABLE            0xB1680008
+#define SSI1_CONFIG                0xB1680020
+#define SSI1_ADATA                 0xB1680024
+#define SSI1_CLKDIV                0xB1680028
+#define SSI1_CONTROL               0xB1680100
 
 /* IrDA Controller */
-#define IR_RING_PTR_STATUS        0x11500000
-#define IR_RING_BASE_ADDR_H       0x11500004
-#define IR_RING_BASE_ADDR_L       0x11500008
-#define IR_RING_SIZE              0x1150000C
-#define IR_RING_PROMPT            0x11500010
-#define IR_RING_ADDR_CMPR         0x11500014
-#define IR_CONFIG_1               0x11500020
-#define IR_SIR_FLAGS              0x11500024
-#define IR_ENABLE                 0x11500028
-#define IR_READ_PHY_CONFIG        0x1150002C
-#define IR_WRITE_PHY_CONFIG       0x11500030
-#define IR_MAX_PKT_LEN            0x11500034
-#define IR_RX_BYTE_CNT            0x11500038
-#define IR_CONFIG_2               0x1150003C
-#define IR_INTERFACE_CONFIG       0x11500040
+#define IRDA_BASE                 0xB0300000
+#define IR_RING_PTR_STATUS        (IRDA_BASE+0x00)
+#define IR_RING_BASE_ADDR_H       (IRDA_BASE+0x04)
+#define IR_RING_BASE_ADDR_L       (IRDA_BASE+0x08)
+#define IR_RING_SIZE              (IRDA_BASE+0x0C)
+#define IR_RING_PROMPT            (IRDA_BASE+0x10)
+#define IR_RING_ADDR_CMPR         (IRDA_BASE+0x14)
+#define IR_INT_CLEAR              (IRDA_BASE+0x18)
+#define IR_CONFIG_1               (IRDA_BASE+0x20)
+  #define IR_RX_INVERT_LED        (1<<0)
+  #define IR_TX_INVERT_LED        (1<<1)
+  #define IR_ST                   (1<<2)
+  #define IR_SF                   (1<<3)
+  #define IR_SIR                  (1<<4)
+  #define IR_MIR                  (1<<5)
+  #define IR_FIR                  (1<<6)
+  #define IR_16CRC                (1<<7)
+  #define IR_TD                   (1<<8)
+  #define IR_RX_ALL               (1<<9)
+  #define IR_DMA_ENABLE           (1<<10)
+  #define IR_RX_ENABLE            (1<<11)
+  #define IR_TX_ENABLE            (1<<12)
+  #define IR_LOOPBACK             (1<<14)
+  #define IR_SIR_MODE	          (IR_SIR | IR_DMA_ENABLE | \
+		                   IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
+#define IR_SIR_FLAGS              (IRDA_BASE+0x24)
+#define IR_ENABLE                 (IRDA_BASE+0x28)
+  #define IR_RX_STATUS            (1<<9)
+  #define IR_TX_STATUS            (1<<10)
+#define IR_READ_PHY_CONFIG        (IRDA_BASE+0x2C)
+#define IR_WRITE_PHY_CONFIG       (IRDA_BASE+0x30)
+#define IR_MAX_PKT_LEN            (IRDA_BASE+0x34)
+#define IR_RX_BYTE_CNT            (IRDA_BASE+0x38)
+#define IR_CONFIG_2               (IRDA_BASE+0x3C)
+  #define IR_MODE_INV             (1<<0)
+  #define IR_ONE_PIN              (1<<1)
+#define IR_INTERFACE_CONFIG       (IRDA_BASE+0x40)
 
 /* GPIO */
-#define TSTATE_STATE_READ         0x11900100
-#define TSTATE_STATE_SET          0x11900100
-#define OUTPUT_STATE_READ         0x11900108
-#define OUTPUT_STATE_SET          0x11900108
-#define OUTPUT_STATE_CLEAR        0x1190010C
-#define PIN_STATE                 0x11900110
+#define SYS_PINFUNC               0xB190002C
+#define SYS_TRIOUTRD              0xB1900100
+#define SYS_TRIOUTCLR             0xB1900100
+#define SYS_OUTPUTRD              0xB1900108
+#define SYS_OUTPUTSET             0xB1900108
+#define SYS_OUTPUTCLR             0xB190010C
+#define SYS_PINSTATERD            0xB1900110
+
+/* GPIO2, Au1500 only */
+#define GPIO2_BASE                0xB1700000
+#define GPIO2_DIR                 (GPIO2_BASE + 0)
+#define GPIO2_DATA_EN             (GPIO2_BASE + 8)
+#define GPIO2_PIN_STATE           (GPIO2_BASE + 0xC)
+#define GPIO2_INT_MASK            (GPIO2_BASE + 0x10)
+#define GPIO2_CONTROL             (GPIO2_BASE + 0x14)
 
 /* Power Management */
-#define PM_SCRATCH_0                 0x11900018
-#define PM_SCRATCH_1                 0x1190001C
-#define PM_WAKEUP_SOURCE_MASK        0x11900034
-#define PM_ENDIANESS                 0x11900038
-#define PM_POWERUP_CONTROL           0x1190003C
-#define PM_WAKEUP_CAUSE              0x1190005C
-#define PM_SLEEP_POWER               0x11900078
-#define PM_SLEEP                     0x1190007C
+#define SYS_SCRATCH0              0xB1900018
+#define SYS_SCRATCH1              0xB190001C
+#define SYS_WAKEMSK               0xB1900034
+#define SYS_ENDIAN                0xB1900038
+#define SYS_POWERCTRL             0xB190003C
+#define SYS_WAKESRC               0xB190005C
+#define SYS_SLPPWR                0xB1900078
+#define SYS_SLEEP                 0xB190007C
 
 /* Clock Controller */
-#define FQ_CNTRL_1                0x11900020
-#define FQ_CNTRL_2                0x11900024
-#define CLOCK_SOURCE_CNTRL        0x11900028
-#define CPU_PLL_CNTRL             0x11900060
-#define AUX_PLL_CNTRL             0x11900064
+#define SYS_FREQCTRL0             0xB1900020
+#define SYS_FREQCTRL1             0xB1900024
+#define SYS_CLKSRC                0xB1900028
+#define SYS_CPUPLL                0xB1900060
+#define SYS_AUXPLL                0xB1900064
 
 /* AC97 Controller */
-#define AC97_CONFIG               0x10000000
-#define AC97_STATUS               0x10000004
-#define AC97_DATA                 0x10000008
-#define AC97_CMD                  0x1000000C
-#define AC97_CNTRL                0x10000010
+#define AC97C_CONFIG              0xB0000000
+  #define AC97C_RECV_SLOTS_BIT  13
+  #define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT)
+  #define AC97C_XMIT_SLOTS_BIT  3
+  #define AC97C_XMIT_SLOTS_MASK (0x3ff << AC97C_XMIT_SLOTS_BIT)
+  #define AC97C_SG              (1<<2)
+  #define AC97C_SYNC            (1<<1)
+  #define AC97C_RESET           (1<<0)
+#define AC97C_STATUS              0xB0000004
+  #define AC97C_XU              (1<<11)
+  #define AC97C_XO              (1<<10)
+  #define AC97C_RU              (1<<9)
+  #define AC97C_RO              (1<<8)
+  #define AC97C_READY           (1<<7)
+  #define AC97C_CP              (1<<6)
+  #define AC97C_TR              (1<<5)
+  #define AC97C_TE              (1<<4)
+  #define AC97C_TF              (1<<3)
+  #define AC97C_RR              (1<<2)
+  #define AC97C_RE              (1<<1)
+  #define AC97C_RF              (1<<0)
+#define AC97C_DATA                0xB0000008
+#define AC97C_CMD                 0xB000000C
+  #define AC97C_WD_BIT          16
+  #define AC97C_READ            (1<<7)
+  #define AC97C_INDEX_MASK      0x7f
+#define AC97C_CNTRL               0xB0000010
+  #define AC97C_RS              (1<<1)
+  #define AC97C_CE              (1<<0)
+
+/* Au1500 PCI Controller */
+#define Au1500_CFG_BASE           0xB4005000 // virtual, kseg0 addr
+#define Au1500_PCI_CMEM           (Au1500_CFG_BASE + 0)
+#define Au1500_PCI_CFG            (Au1500_CFG_BASE + 4)
+  #define PCI_ERROR ((1<<22) | (1<<23) | (1<<24) | (1<<25) | (1<<26) | (1<<27))
+#define Au1500_PCI_B2BMASK_CCH    (Au1500_CFG_BASE + 8)
+#define Au1500_PCI_B2B0_VID       (Au1500_CFG_BASE + 0xC)
+#define Au1500_PCI_B2B1_ID        (Au1500_CFG_BASE + 0x10)
+#define Au1500_PCI_MWMASK_DEV     (Au1500_CFG_BASE + 0x14)
+#define Au1500_PCI_MWBASE_REV_CCL (Au1500_CFG_BASE + 0x18)
+#define Au1500_PCI_ERR_ADDR       (Au1500_CFG_BASE + 0x1C)
+#define Au1500_PCI_SPEC_INTACK    (Au1500_CFG_BASE + 0x20)
+#define Au1500_PCI_ID             (Au1500_CFG_BASE + 0x100)
+#define Au1500_PCI_STATCMD        (Au1500_CFG_BASE + 0x104)
+#define Au1500_PCI_CLASSREV       (Au1500_CFG_BASE + 0x108)
+#define Au1500_PCI_HDRTYPE        (Au1500_CFG_BASE + 0x10C)
+#define Au1500_PCI_MBAR           (Au1500_CFG_BASE + 0x110)
+
+#define Au1500_PCI_HDR            0xB4005100 // virtual, kseg0 addr
+
+  /* these are all pseudo physical addresses */
+#define Au1500_EXT_CFG            0x20000000
+#define Au1500_PCI_IO_START       0x70000000
+#define Au1500_PCI_IO_END         0x700FFFFF
+#define Au1500_PCI_MEM_START      0x80000000
+#define Au1500_PCI_MEM_END        0x83FFFFFF
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/au1000_dma.h linux/include/asm-mips/au1000_dma.h
--- linux.orig/include/asm-mips/au1000_dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/au1000_dma.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,387 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Defines for using and allocating dma channels on the Alchemy
+ *      Au1000 mips processor.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	stevel@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_AU1000_DMA_H
+#define __ASM_AU1000_DMA_H
+
+#include <asm/io.h>		/* need byte IO */
+#include <linux/spinlock.h>	/* And spinlocks */
+#include <linux/delay.h>
+#include <asm/system.h>
+
+#define NUM_AU1000_DMA_CHANNELS	8
+
+/* DMA Channel Base Addresses */
+#define DMA_CHANNEL_BASE	0xB4002000
+#define DMA_CHANNEL_LEN		0x00000100
+
+/* DMA Channel Register Offsets */
+#define DMA_MODE_SET		0x00000000
+#define DMA_MODE_CLEAR		0x00000004
+/* DMA Mode register bits follow */
+#define DMA_DAH_MASK		(0x0f << 20)
+#define DMA_DID_BIT		16
+#define DMA_DID_MASK		(0x0f << DMA_DID_BIT)
+#define DMA_BE			(1<<13)
+#define DMA_DR			(1<<12)
+#define DMA_TS8			(1<<11)
+#define DMA_DW_BIT		9
+#define DMA_DW_MASK		(0x03 << DMA_DW_BIT)
+#define DMA_DW8			(0 << DMA_DW_BIT)
+#define DMA_DW16		(1 << DMA_DW_BIT)
+#define DMA_DW32		(2 << DMA_DW_BIT)
+#define DMA_NC			(1<<8)
+#define DMA_IE			(1<<7)
+#define DMA_HALT		(1<<6)
+#define DMA_GO			(1<<5)
+#define DMA_AB			(1<<4)
+#define DMA_D1			(1<<3)
+#define DMA_BE1			(1<<2)
+#define DMA_D0			(1<<1)
+#define DMA_BE0			(1<<0)
+
+#define DMA_PERIPHERAL_ADDR       0x00000008
+#define DMA_BUFFER0_START         0x0000000C
+#define DMA_BUFFER1_START         0x00000014
+#define DMA_BUFFER0_COUNT         0x00000010
+#define DMA_BUFFER1_COUNT         0x00000018
+#define DMA_BAH_BIT 16
+#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT)
+#define DMA_COUNT_BIT 0
+#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT)
+
+/* DMA Device ID's follow */
+enum {
+	DMA_ID_UART0_TX = 0,
+	DMA_ID_UART0_RX,
+	DMA_ID_GP04,
+	DMA_ID_GP05,
+	DMA_ID_AC97C_TX,
+	DMA_ID_AC97C_RX,
+	DMA_ID_UART3_TX,
+	DMA_ID_UART3_RX,
+	DMA_ID_USBDEV_EP0_RX,
+	DMA_ID_USBDEV_EP0_TX,
+	DMA_ID_USBDEV_EP2_TX,
+	DMA_ID_USBDEV_EP3_TX,
+	DMA_ID_USBDEV_EP4_RX,
+	DMA_ID_USBDEV_EP5_RX,
+	DMA_ID_I2S_TX,
+	DMA_ID_I2S_RX,
+	DMA_NUM_DEV
+};
+
+struct dma_chan {
+	int dev_id;		// this channel is allocated if >=0, free otherwise
+	unsigned int io;
+	int irq;
+	const char *dev_str;
+	unsigned int fifo_addr;
+	unsigned int mode;
+};
+
+/* These are in arch/mips/au1000/common/dma.c */
+extern struct dma_chan au1000_dma_table[];
+extern int request_au1000_dma(int dev_id, const char *dev_str);
+extern void free_au1000_dma(unsigned int dmanr);
+extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
+				int length, int *eof, void *data);
+extern void dump_au1000_dma_channel(unsigned int dmanr);
+extern spinlock_t au1000_dma_spin_lock;
+
+
+static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr)
+{
+	if (dmanr > NUM_AU1000_DMA_CHANNELS
+	    || au1000_dma_table[dmanr].dev_id < 0)
+		return NULL;
+	return &au1000_dma_table[dmanr];
+}
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&au1000_dma_spin_lock, flags);
+	return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&au1000_dma_spin_lock, flags);
+}
+
+/*
+ * Set the DMA buffer enable bits in the mode register.
+ */
+static __inline__ void enable_dma_buffer0(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	au_writel(DMA_BE0, chan->io + DMA_MODE_SET);
+}
+static __inline__ void enable_dma_buffer1(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	au_writel(DMA_BE1, chan->io + DMA_MODE_SET);
+}
+static __inline__ void enable_dma_buffers(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
+}
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+
+	// set device FIFO address
+	au_writel(virt_to_phys((void *) chan->fifo_addr),
+		  chan->io + DMA_PERIPHERAL_ADDR);
+
+	au_writel(chan->
+		  mode | (chan->dev_id << DMA_DID_BIT) | DMA_IE | DMA_GO,
+		  chan->io + DMA_MODE_SET);
+}
+
+#define DMA_HALT_POLL 0x5000
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+	int i;
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+
+	au_writel(DMA_D1 | DMA_D0 | DMA_GO, chan->io + DMA_MODE_CLEAR);
+
+	// poll the halt bit
+	for (i = 0; i < DMA_HALT_POLL; i++)
+		if (au_readl(chan->io + DMA_MODE_SET) & DMA_HALT)
+			break;
+	if (i == DMA_HALT_POLL) {
+		printk(KERN_INFO "disable_dma: HALT poll expired!\n");
+	} else {
+		// now we can disable the buffers
+		au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
+	}
+}
+
+
+/*
+ * set mode for a specific DMA channel
+ */
+static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	/*
+	 * chan->mode only holds endianess, direction, transfer size, device
+	 * FIFO width, and cacheability info for the channel. Make sure
+	 * anything else is masked off.
+	 */
+	mode &= (DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
+	chan->mode = mode;
+}
+
+static __inline__ int get_dma_active_buffer(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return -1;
+	return (au_readl(chan->io + DMA_MODE_SET) & DMA_AB) ? 1 : 0;
+}
+
+
+/*
+ * set the device FIFO address for a specific DMA channel - only
+ * applicable to GPO4 and GPO5. All the other devices have fixed
+ * FIFO addresses.
+ */
+static __inline__ void set_dma_fifo_addr(unsigned int dmanr,
+					 unsigned int a)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+
+	if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
+		return;
+
+	au_writel(virt_to_phys((void *) a),
+		  chan->io + DMA_PERIPHERAL_ADDR);
+}
+
+/*
+ * Clear the DMA buffer done bits in the mode register.
+ */
+static __inline__ void clear_dma_done0(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
+}
+static __inline__ void clear_dma_done1(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
+}
+
+/*
+ * This does nothing - not applicable to Au1000 DMA.
+ */
+static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+{
+}
+
+/*
+ * Set Buffer 0 transfer address for specific DMA channel.
+ */
+static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	au_writel(a, chan->io + DMA_BUFFER0_START);
+}
+
+/*
+ * Set Buffer 1 transfer address for specific DMA channel.
+ */
+static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	au_writel(a, chan->io + DMA_BUFFER1_START);
+}
+
+
+/*
+ * Set Buffer 0 transfer size (max 64k) for a specific DMA channel.
+ */
+static __inline__ void set_dma_count0(unsigned int dmanr,
+				      unsigned int count)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	count &= DMA_COUNT_MASK;
+	au_writel(count, chan->io + DMA_BUFFER0_COUNT);
+}
+
+/*
+ * Set Buffer 1 transfer size (max 64k) for a specific DMA channel.
+ */
+static __inline__ void set_dma_count1(unsigned int dmanr,
+				      unsigned int count)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	count &= DMA_COUNT_MASK;
+	au_writel(count, chan->io + DMA_BUFFER1_COUNT);
+}
+
+/*
+ * Set both buffer transfer sizes (max 64k) for a specific DMA channel.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr,
+				     unsigned int count)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+	count &= DMA_COUNT_MASK;
+	au_writel(count, chan->io + DMA_BUFFER0_COUNT);
+	au_writel(count, chan->io + DMA_BUFFER1_COUNT);
+}
+
+/*
+ * Returns which buffer has its done bit set in the mode register.
+ * Returns -1 if neither or both done bits set.
+ */
+static __inline__ unsigned int get_dma_buffer_done(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return 0;
+
+    return au_readl(chan->io + DMA_MODE_SET) & (DMA_D0 | DMA_D1);
+}
+
+
+/*
+ * Returns the DMA channel's Buffer Done IRQ number.
+ */
+static __inline__ int get_dma_done_irq(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return -1;
+
+	return chan->irq;
+}
+
+/*
+ * Get DMA residue count. Returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+	int curBufCntReg, count;
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return 0;
+
+	curBufCntReg = (au_readl(chan->io + DMA_MODE_SET) & DMA_AB) ?
+	    DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT;
+
+	count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK;
+
+	if ((chan->mode & DMA_DW_MASK) == DMA_DW16)
+		count <<= 1;
+	else if ((chan->mode & DMA_DW_MASK) == DMA_DW32)
+		count <<= 2;
+
+	return count;
+}
+
+#endif /* __ASM_AU1000_DMA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/au1000_gpio.h linux/include/asm-mips/au1000_gpio.h
--- linux.orig/include/asm-mips/au1000_gpio.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/au1000_gpio.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,56 @@
+/*
+ * FILE NAME au1000_gpio.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	API to Alchemy Au1000 GPIO device.
+ *
+ *  Author: MontaVista Software, Inc.  <source@mvista.com>
+ *          Steve Longerbeam <stevel@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __AU1000_GPIO_H
+#define __AU1000_GPIO_H
+
+#include <linux/ioctl.h>
+
+#define AU1000GPIO_IOC_MAGIC 'A'
+
+#define AU1000GPIO_IN		_IOR (AU1000GPIO_IOC_MAGIC, 0, int)
+#define AU1000GPIO_SET		_IOW (AU1000GPIO_IOC_MAGIC, 1, int)
+#define AU1000GPIO_CLEAR	_IOW (AU1000GPIO_IOC_MAGIC, 2, int)
+#define AU1000GPIO_OUT		_IOW (AU1000GPIO_IOC_MAGIC, 3, int)
+#define AU1000GPIO_TRISTATE	_IOW (AU1000GPIO_IOC_MAGIC, 4, int)
+#define AU1000GPIO_AVAIL_MASK	_IOR (AU1000GPIO_IOC_MAGIC, 5, int)
+
+#ifdef __KERNEL__ 
+extern u32 get_au1000_avail_gpio_mask(void);
+extern int au1000gpio_tristate(u32 data);
+extern int au1000gpio_in(u32 *data);
+extern int au1000gpio_set(u32 data);
+extern int au1000gpio_clear(u32 data);
+extern int au1000gpio_out(u32 data);
+#endif
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/au1000_pcmcia.h linux/include/asm-mips/au1000_pcmcia.h
--- linux.orig/include/asm-mips/au1000_pcmcia.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/au1000_pcmcia.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,93 @@
+/*
+ *
+ * Alchemy Semi Au1000 pcmcia driver include file
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
+ */
+#ifndef __ASM_AU1000_PCMCIA_H
+#define __ASM_AU1000_PCMCIA_H
+
+#include <linux/config.h>
+
+#define AU1000_PCMCIA_POLL_PERIOD    (2*HZ)
+#define AU1000_PCMCIA_IO_SPEED       (255)
+#define AU1000_PCMCIA_MEM_SPEED      (300)
+
+
+struct pcmcia_state {
+  unsigned detect: 1,
+            ready: 1,
+           wrprot: 1,
+	     bvd1: 1,
+	     bvd2: 1,
+            vs_3v: 1,
+            vs_Xv: 1;
+};
+
+
+struct pcmcia_configure {
+  unsigned sock: 8,
+            vcc: 8,
+            vpp: 8,
+         output: 1,
+        speaker: 1,
+          reset: 1;
+};
+
+struct pcmcia_irq_info {
+	unsigned int sock;
+	unsigned int irq;
+};
+
+struct au1000_pcmcia_socket {
+	socket_state_t        cs_state;
+	struct pcmcia_state   k_state;
+	unsigned int          irq;
+	void                  (*handler)(void *, unsigned int);
+	void                  *handler_info;
+	pccard_io_map         io_map[MAX_IO_WIN];
+	pccard_mem_map        mem_map[MAX_WIN];
+	u32                   virt_io, phys_attr, phys_mem;
+	unsigned short        speed_io, speed_attr, speed_mem;
+};
+
+struct pcmcia_init {
+	void (*handler)(int irq, void *dev, struct pt_regs *regs);
+};
+
+struct pcmcia_low_level {
+	int (*init)(struct pcmcia_init *);
+	int (*shutdown)(void);
+	int (*socket_state)(unsigned sock, struct pcmcia_state *);
+	int (*get_irq_info)(struct pcmcia_irq_info *);
+	int (*configure_socket)(const struct pcmcia_configure *);
+};
+
+#ifdef CONFIG_MIPS_PB1000
+extern struct pcmcia_low_level pb1000_pcmcia_ops;
+#elif defined (CONFIG_MIPS_PB1500)
+extern struct pcmcia_low_level pb1500_pcmcia_ops;
+#endif
+
+#endif /* __ASM_AU1000_PCMCIA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/baget/baget.h linux/include/asm-mips/baget/baget.h
--- linux.orig/include/asm-mips/baget/baget.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/baget/baget.h	2002-07-20 01:08:37.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id$
+/*
  * baget.h: Definitions specific to Baget/MIPS machines.
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/baget/vac.h linux/include/asm-mips/baget/vac.h
--- linux.orig/include/asm-mips/baget/vac.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/baget/vac.h	2002-07-20 01:08:33.000000000 +0000
@@ -1,12 +1,11 @@
-/* $Id$
- *
+/*
  * vac.h: Various VIC controller defines.  The VIC is a VME controller
  *        used in Baget/MIPS series.
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  */
-#ifndef _MIPS_VAC_H
-#define _MIPS_VAC_H
+#ifndef _ASM_VAC_H
+#define _ASM_VAC_H
 
 #define VAC_SLSEL1_MASK      0x000
 #define VAC_SLSEL1_BASE      0x100
@@ -197,13 +196,13 @@
 #define VAC_ID               0x2900
 
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef __ASSEMBLY__
 
 #define vac_inb(p)    (*(volatile unsigned char *)(VAC_BASE + (p)))
 #define vac_outb(v,p) (*((volatile unsigned char *)(VAC_BASE + (p))) = v)
 #define vac_inw(p)    (*(volatile unsigned short*)(VAC_BASE + (p)))
 #define vac_outw(v,p) (*((volatile unsigned short*)(VAC_BASE + (p))) = v)
 
-#endif /* __LANGUAGE_ASSEMBLY__ */
+#endif /* !__ASSEMBLY__ */
 
-#endif /* !(_MIPS_VAC_H) */
+#endif /* _ASM_VAC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/baget/vic.h linux/include/asm-mips/baget/vic.h
--- linux.orig/include/asm-mips/baget/vic.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/baget/vic.h	2002-07-20 01:08:25.000000000 +0000
@@ -1,12 +1,11 @@
-/* $Id$
- *
+/*
  * vic.h: Various VIC controller defines.  The VIC is an interrupt controller
  *        used in Baget/MIPS series.
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  */
-#ifndef _MIPS_VIC_H
-#define _MIPS_VIC_H
+#ifndef _ASM_BAGET_VIC_H
+#define _ASM_BAGET_VIC_H
 
 #define VIC_VME_II       0x3
 #define VIC_VME_INT1     0x7
@@ -183,11 +182,11 @@
 #define VIC_BXFER_LEN_HI    0xDF
 #define VIC_SYS_RESET    0xE3
 
-#ifndef __LANGUAGE_ASSEMBLY__
+#ifndef __ASSEMBLY__
 
 #define vic_inb(p)    (*(volatile unsigned char *)(VIC_BASE + (p)))
 #define vic_outb(v,p) (*((volatile unsigned char *)(VIC_BASE + (p))) = v)
 
-#endif /* __LANGUAGE_ASSEMBLY__ */
+#endif /* !__ASSEMBLY__ */
 
-#endif /* !(_MIPS_VIC_H) */
+#endif /* _ASM_BAGET_VIC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/bcache.h linux/include/asm-mips/bcache.h
--- linux.orig/include/asm-mips/bcache.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/bcache.h	2002-07-20 01:08:31.000000000 +0000
@@ -3,8 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1997, 1999, 2000 by Ralf Baechle
- * Copyright (c) 2000 by Silicon Graphics, Inc.
+ * Copyright (c) 1997, 1999 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
  */
 #ifndef _ASM_BCACHE_H
 #define _ASM_BCACHE_H
@@ -12,7 +12,7 @@
 #include <linux/config.h>
 
 /* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent,
-   chipset implemented caches.  On machines with other CPUs the CPU does the
+   chipset implemented caches.  On machines with other CPUs the CPU does the 
    cache thing itself. */
 struct bcache_ops {
 	void (*bc_enable)(void);
@@ -28,22 +28,22 @@
 
 extern struct bcache_ops *bcops;
 
-extern inline void bc_enable(void)
+static inline void bc_enable(void)
 {
 	bcops->bc_enable();
 }
 
-extern inline void bc_disable(void)
+static inline void bc_disable(void)
 {
 	bcops->bc_disable();
 }
 
-extern inline void bc_wback_inv(unsigned long page, unsigned long size)
+static inline void bc_wback_inv(unsigned long page, unsigned long size)
 {
 	bcops->bc_wback_inv(page, size);
 }
 
-extern inline void bc_inv(unsigned long page, unsigned long size)
+static inline void bc_inv(unsigned long page, unsigned long size)
 {
 	bcops->bc_inv(page, size);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/bitops.h linux/include/asm-mips/bitops.h
--- linux.orig/include/asm-mips/bitops.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/bitops.h	2002-07-20 01:08:24.000000000 +0000
@@ -9,6 +9,7 @@
 #ifndef _ASM_BITOPS_H
 #define _ASM_BITOPS_H
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <asm/byteorder.h>		/* sigh ... */
 
@@ -16,13 +17,12 @@
 
 #include <asm/sgidefs.h>
 #include <asm/system.h>
-#include <linux/config.h>
 
 /*
  * clear_bit() doesn't provide any barrier for the compiler.
  */
-#define smp_mb__before_clear_bit()	barrier()
-#define smp_mb__after_clear_bit()	barrier()
+#define smp_mb__before_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	smp_mb()
 
 /*
  * Only disable interrupt for kernel mode stuff to keep usermode stuff
@@ -43,8 +43,6 @@
 
 #ifdef CONFIG_CPU_HAS_LLSC
 
-#include <asm/mipsregs.h>
-
 /*
  * These functions for MIPS ISA > 1 are interrupt and SMP proof and
  * interrupt friendly
@@ -177,6 +175,9 @@
 		"sc\t%2, %1\n\t"
 		"beqz\t%2, 1b\n\t"
 		" and\t%2, %0, %3\n\t"
+#ifdef CONFIG_SMP
+		"sync\n\t"
+#endif
 		".set\treorder"
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << (nr & 0x1f)), "m" (*m)
@@ -229,6 +230,9 @@
 		"sc\t%2, %1\n\t"
 		"beqz\t%2, 1b\n\t"
 		" and\t%2, %0, %3\n\t"
+#ifdef CONFIG_SMP
+		"sync\n\t"
+#endif
 		".set\treorder"
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << (nr & 0x1f)), "m" (*m)
@@ -280,6 +284,9 @@
 		"sc\t%2, %1\n\t"
 		"beqz\t%2, 1b\n\t"
 		" and\t%2, %0, %3\n\t"
+#ifdef CONFIG_SMP
+		"sync\n\t"
+#endif
 		".set\treorder"
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << (nr & 0x1f)), "m" (*m)
@@ -621,8 +628,7 @@
 		"2:"
 		: "=r" (res), "=r" (dummy), "=r" (addr)
 		: "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff),
-		  "2" (addr), "r" (size)
-		: "$1");
+		  "2" (addr), "r" (size));
 
 	return res;
 }
@@ -657,8 +663,7 @@
 			".set\treorder\n"
 			"1:"
 			: "=r" (set), "=r" (dummy)
-			: "0" (0), "1" (1 << bit), "r" (*p)
-			: "$1");
+			: "0" (0), "1" (1 << bit), "r" (*p));
 		if (set < (32 - bit))
 			return set + offset;
 		set = 32 - bit;
@@ -679,30 +684,21 @@
  *
  * Undefined if no zero exists, so code should check against ~0UL first.
  */
-extern __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long word)
 {
-	unsigned int	__res;
-	unsigned int	mask = 1;
+	int b = 0, s;
 
-	__asm__ (
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"move\t%0,$0\n"
-		"1:\tand\t$1,%2,%1\n\t"
-		"beqz\t$1,2f\n\t"
-		"sll\t%1,1\n\t"
-		"bnez\t%1,1b\n\t"
-		"addiu\t%0,1\n\t"
-		".set\tat\n\t"
-		".set\treorder\n"
-		"2:\n\t"
-		: "=&r" (__res), "=r" (mask)
-		: "r" (word), "1" (mask)
-		: "$1");
+	word = ~word;
+	s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s;
+	s =  8; if (word << 24 != 0) s = 0; b += s; word >>= s;
+	s =  4; if (word << 28 != 0) s = 0; b += s; word >>= s;
+	s =  2; if (word << 30 != 0) s = 0; b += s; word >>= s;
+	s =  1; if (word << 31 != 0) s = 0; b += s;
 
-	return __res;
+	return b;
 }
 
+
 #ifdef __KERNEL__
 
 /**
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/bootinfo.h linux/include/asm-mips/bootinfo.h
--- linux.orig/include/asm-mips/bootinfo.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/bootinfo.h	2002-07-20 01:08:28.000000000 +0000
@@ -9,40 +9,38 @@
 #ifndef _ASM_BOOTINFO_H
 #define _ASM_BOOTINFO_H
 
+#include <linux/types.h>
+
 /*
  * Values for machgroup
  */
-#define MACH_GROUP_UNKNOWN      0 /* whatever... */
-#define MACH_GROUP_JAZZ     	1 /* Jazz                                     */
-#define MACH_GROUP_DEC          2 /* Digital Equipment                        */
+#define MACH_GROUP_UNKNOWN      0 /* whatever...                            */
+#define MACH_GROUP_JAZZ     	1 /* Jazz                                   */
+#define MACH_GROUP_DEC          2 /* Digital Equipment                      */
 #define MACH_GROUP_ARC		3 /* Wreckstation Tyne, rPC44, possibly other */
-#define MACH_GROUP_SNI_RM	4 /* Siemens Nixdorf RM series                */
+#define MACH_GROUP_SNI_RM	4 /* Siemens Nixdorf RM series              */
 #define MACH_GROUP_ACN		5
-#define MACH_GROUP_SGI          6 /* Silicon Graphics                         */
-#define MACH_GROUP_COBALT       7 /* Cobalt servers		 	      */
-#define MACH_GROUP_NEC_DDB	8 /* NEC DDB                                  */
-#define MACH_GROUP_BAGET	9 /* Baget                                    */
-#define MACH_GROUP_COSINE      10 /* CoSine Orion                             */
-#define MACH_GROUP_GALILEO     11 /* Galileo Eval Boards                      */
-#define MACH_GROUP_MOMENCO     12 /* Momentum Boards                          */
-#define MACH_GROUP_ITE         13 /* ITE Semi Eval Boards                     */
+#define MACH_GROUP_SGI          6 /* Silicon Graphics                       */
+#define MACH_GROUP_COBALT       7 /* Cobalt servers		 	    */
+#define MACH_GROUP_NEC_DDB	8 /* NEC DDB                                */
+#define MACH_GROUP_BAGET	9 /* Baget                                  */
+#define MACH_GROUP_COSINE      10 /* CoSine Orion                           */
+#define MACH_GROUP_GALILEO     11 /* Galileo Eval Boards                    */
+#define MACH_GROUP_MOMENCO     12 /* Momentum Boards                        */
+#define MACH_GROUP_ITE         13 /* ITE Semi Eval Boards                   */
 #define MACH_GROUP_PHILIPS     14
-#define MACH_GROUP_GLOBESPAN   15 /* Globespan PVR Referrence Board           */
-#define MACH_GROUP_SIBYTE      16 /* Sibyte Eval Boards                       */
-#define MACH_GROUP_TOSHIBA     17 /* Toshiba Reference Systems TSBREF         */
-#define MACH_GROUP_ALCHEMY     18 /* Alchemy Semi Eval Boards*/
-
-#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", "SNI", "ACN",      \
-	"SGI", "Cobalt", "NEC DDB", "Baget", "Cosine", "Galileo", "Momentum", \
-	"ITE", "Philips", "Globepspan", "SiByte", "Toshiba", "Alchemy" }
+#define MACH_GROUP_GLOBESPAN   15 /* Globespan PVR Referrence Board         */
+#define MACH_GROUP_SIBYTE      16 /* Sibyte Eval Boards                     */
+#define MACH_GROUP_TOSHIBA     17 /* Toshiba Reference Systems TSBREF       */
+#define MACH_GROUP_ALCHEMY     18 /* Alchemy Semi Eval Boards               */
+#define MACH_GROUP_NEC_VR41XX  19 /* NEC Vr41xx based boards/gadgets        */
+#define MACH_GROUP_HP_LJ       20 /* Hewlett Packard LaserJet               */
 
 /*
  * Valid machtype values for group unknown (low order halfword of mips_machtype)
  */
 #define MACH_UNKNOWN		0	/* whatever...			*/
 
-#define GROUP_UNKNOWN_NAMES { "unknown" }
-
 /*
  * Valid machtype values for group JAZZ
  */
@@ -50,8 +48,6 @@
 #define MACH_MIPS_MAGNUM_4000	1	/* Mips Magnum 4000 "RC4030"	*/
 #define MACH_OLIVETTI_M700      2	/* Olivetti M700-10 (-15 ??)    */
 
-#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" }
-
 /*
  * Valid machtype for group DEC 
  */
@@ -66,57 +62,44 @@
 #define MACH_DS5500		8	/* DECstation 5500		*/
 #define MACH_DS5800		9	/* DECstation 5800		*/
 
-#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \
-	"DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \
-	"DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \
-	"DECstation 5800" }
-
 /*
  * Valid machtype for group ARC
  */
 #define MACH_DESKSTATION_RPC44  0	/* Deskstation rPC44 */
 #define MACH_DESKSTATION_TYNE	1	/* Deskstation Tyne */
 
-#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" }
-
 /*
  * Valid machtype for group SNI_RM
  */
 #define MACH_SNI_RM200_PCI	0	/* RM200/RM300/RM400 PCI series */
 
-#define GROUP_SNI_RM_NAMES { "RM200 PCI" }
-
 /*
  * Valid machtype for group ACN
  */
 #define MACH_ACN_MIPS_BOARD	0       /* ACN MIPS single board        */
 
-#define GROUP_ACN_NAMES { "ACN" }
-
 /*
  * Valid machtype for group SGI
  */
 #define MACH_SGI_INDY		0	/* R4?K and R5K Indy workstations */
 #define MACH_SGI_CHALLENGE_S	1	/* The Challenge S server */
 #define MACH_SGI_INDIGO2	2	/* The Indigo2 system */
-
-#define GROUP_SGI_NAMES { "Indy", "Challenge S", "Indigo2" }
+#define MACH_SGI_IP27		3	/* Origin 200, Origin 2000, Onyx 2 */
+#define MACH_SGI_IP28		4	/* Indigo2 Impact */
+#define MACH_SGI_IP32		5	/* O2 */
 
 /*
  * Valid machtype for group COBALT
  */
 #define MACH_COBALT_27 		 0	/* Proto "27" hardware */
 
-#define GROUP_COBALT_NAMES { "Microserver 27" }
-
 /*
  * Valid machtype for group NEC DDB
  */
 #define MACH_NEC_DDB5074	 0	/* NEC DDB Vrc-5074 */
 #define MACH_NEC_DDB5476         1      /* NEC DDB Vrc-5476 */
 #define MACH_NEC_DDB5477         2      /* NEC DDB Vrc-5477 */
-
-#define GROUP_NEC_DDB_NAMES { "Vrc-5074", "Vrc-5476", "Vrc-5477"}
+#define MACH_NEC_ROCKHOPPER      3      /* Rockhopper base board */
 
 /*
  * Valid machtype for group BAGET
@@ -124,171 +107,74 @@
 #define MACH_BAGET201		0	/* BT23-201 */
 #define MACH_BAGET202		1	/* BT23-202 */
 
-#define GROUP_BAGET_NAMES { "BT23-201", "BT23-202" }
-
 /*
  * Cosine boards.
  */
 #define MACH_COSINE_ORION	0
 
-#define GROUP_COSINE_NAMES { "Orion" }
-
 /*
  * Valid machtype for group GALILEO
  */
 #define MACH_EV96100		0	/* EV96100 */
 #define MACH_EV64120A		1	/* EV64120A */
 
-#define GROUP_GALILEO_NAMES { "EV96100" , "EV64120A" }
-
 /*
  * Valid machtype for group MOMENCO
  */
-#define MACH_MOMENCO_OCELOT		0
-
-#define GROUP_MOMENCO_NAMES { "Ocelot" }
-
+#define MACH_MOMENCO_OCELOT	0
  
 /*
  * Valid machtype for group ITE
  */
 #define MACH_QED_4N_S01B	0	/* ITE8172 based eval board */
  
-#define GROUP_ITE_NAMES { "QED-4N-S01B" } /* the actual board name */
-	
 /*
  * Valid machtype for group Globespan
  */
 #define MACH_IVR       0                  /* IVR eval board */
 
-#define GROUP_GLOBESPAN_NAMES { "IVR" }   /* the actual board name */   
-
 /*
  * Valid machtype for group PHILIPS
  */
 #define MACH_PHILIPS_NINO	0	/* Nino */
 #define MACH_PHILIPS_VELO	1	/* Velo */
 
-#define GROUP_PHILIPS_NAMES { "Nino" , "Velo" }
-
 /*
  * Valid machtype for group SIBYTE
  */
 #define MACH_SWARM              0
 
-#define GROUP_SIBYTE_NAMES {"SWARM" }
-
 /*
  * Valid machtypes for group Toshiba
  */
 #define MACH_PALLAS		0
 #define MACH_TOPAS		1
 #define MACH_JMR		2
-
-#define GROUP_TOSHIBA_NAMES { "Pallas", "TopasCE", "JMR" }
+#define MACH_TOSHIBA_JMR3927    3      /* JMR-TX3927 CPU/IO board */
 
 /*
  * Valid machtype for group Alchemy
  */
 #define MACH_PB1000	0	         /* Au1000-based eval board */
+#define MACH_PB1500	1	         /* Au1500-based eval board */
  
-#define GROUP_ALCHEMY_NAMES { "PB1000" } /* the actual board name */
-
 /*
- * Valid cputype values
+ * Valid machtype for group NEC_VR41XX
  */
-#define CPU_UNKNOWN		0
-#define CPU_R2000		1
-#define CPU_R3000		2
-#define CPU_R3000A		3
-#define CPU_R3041		4
-#define CPU_R3051		5
-#define CPU_R3052		6
-#define CPU_R3081		7
-#define CPU_R3081E		8
-#define CPU_R4000PC		9
-#define CPU_R4000SC		10
-#define CPU_R4000MC		11
-#define CPU_R4200		12
-#define CPU_R4400PC		13
-#define CPU_R4400SC		14
-#define CPU_R4400MC		15
-#define CPU_R4600		16
-#define CPU_R6000		17
-#define CPU_R6000A		18
-#define CPU_R8000		19
-#define CPU_R10000		20
-#define CPU_R4300		21
-#define CPU_R4650		22
-#define CPU_R4700		23
-#define CPU_R5000		24
-#define CPU_R5000A		25
-#define CPU_R4640		26
-#define CPU_NEVADA		27	/* RM5230, RM5260 */
-#define CPU_RM7000		28
-#define CPU_R5432		29
-#define CPU_4KC			30
-#define CPU_5KC			31
-#define CPU_R4310		32
-#define CPU_SB1			33
-#define CPU_TX3912		34
-#define CPU_TX3922		35
-#define CPU_TX3927		36
-#define CPU_AU1000		37
-#define CPU_4KEC		38
-#define CPU_4KSC		39
-#define CPU_VR41XX		40
-#define CPU_LAST		40
-
-
-#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \
-        "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC",         \
-        "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000",          \
-        "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000",     \
-        "R5000A", "R4640", "Nevada", "RM7000", "R5432", "MIPS 4Kc",          \
-        "MIPS 5Kc", "R4310", "SiByte SB1", "TX3912", "TX3922", "TX3927",     \
-	"Au1000", "MIPS 4KEc", "MIPS 4KSc", "NEC Vr41xx" }
+#define MACH_NEC_OSPREY                0       /* Osprey eval board */
+
+#define CL_SIZE			(256)
 
-#define COMMAND_LINE_SIZE	256
+const char *get_system_type(void);
+
+extern unsigned long mips_machtype;
+extern unsigned long mips_machgroup;
 
 #define BOOT_MEM_MAP_MAX	32
 #define BOOT_MEM_RAM		1
 #define BOOT_MEM_ROM_DATA	2
 #define BOOT_MEM_RESERVED	3
 
-#ifndef __ASSEMBLY__
-
-/*
- * Some machine parameters passed by the bootloaders. 
- */
-
-struct drive_info_struct {
-	char dummy[32];
-};
-
-/* This is the same as in Milo but renamed for the sake of kernel's */
-/* namespace */
-typedef struct mips_arc_DisplayInfo {	/* video adapter information */
-	unsigned short cursor_x;
-	unsigned short cursor_y;
-	unsigned short columns;
-	unsigned short lines;
-} mips_arc_DisplayInfo;
-
-/* default values for drive info */
-#define DEFAULT_DRIVE_INFO { {0,}}
-
-/*
- * These are the kernel variables initialized from
- * the tag. And they have to be initialized to dummy/default
- * values in setup.c (or whereever suitable) so they are in
- * .data section
- */
-extern struct mips_cpu mips_cpu;
-extern unsigned long mips_machtype;
-extern unsigned long mips_machgroup;
-extern unsigned long mips_tlb_entries;
-
 /*
  * A memory map that's built upon what was determined
  * or specified on the command line.
@@ -296,17 +182,14 @@
 struct boot_mem_map {
 	int nr_map;
 	struct {
-		unsigned long addr;	/* start of memory segment */
-		unsigned long size;	/* size of memory segment */
+		phys_t addr;	/* start of memory segment */
+		phys_t size;	/* size of memory segment */
 		long type;		/* type of memory segment */
 	} map[BOOT_MEM_MAP_MAX];
 };
 
 extern struct boot_mem_map boot_mem_map;
 
-extern void add_memory_region(unsigned long start, unsigned long size,
-			      long type);
-
-#endif /* !__ASSEMBLY__ */
+extern void add_memory_region(phys_t start, phys_t size, long type);
 
 #endif /* _ASM_BOOTINFO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/branch.h linux/include/asm-mips/branch.h
--- linux.orig/include/asm-mips/branch.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/branch.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,24 +1,31 @@
 /*
- * Branch and jump emulation.
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
- *
- * $Id: branch.h,v 1.2 1998/04/28 19:37:46 ralf Exp $
+ * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle
  */
+#ifndef _ASM_BRANCH_H
+#define _ASM_BRANCH_H
+
 #include <asm/ptrace.h>
 
-extern inline int delay_slot(struct pt_regs *regs)
+static inline int delay_slot(struct pt_regs *regs)
 {
 	return regs->cp0_cause & CAUSEF_BD;
 }
 
+static inline unsigned long exception_epc(struct pt_regs *regs)
+{
+	if (!delay_slot(regs))
+		return regs->cp0_epc;
+
+	return regs->cp0_epc + 4;
+}
+
 extern int __compute_return_epc(struct pt_regs *regs);
 
-extern inline int compute_return_epc(struct pt_regs *regs)
+static inline int compute_return_epc(struct pt_regs *regs)
 {
 	if (!delay_slot(regs)) {
 		regs->cp0_epc += 4;
@@ -27,3 +34,5 @@
 
 	return __compute_return_epc(regs);
 }
+
+#endif /* _ASM_BRANCH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/bugs.h linux/include/asm-mips/bugs.h
--- linux.orig/include/asm-mips/bugs.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/bugs.h	2002-07-20 01:08:25.000000000 +0000
@@ -1,47 +1,12 @@
 /*
- * Copyright (C) 1995  Waldorf Electronics
- * Copyright (C) 1997, 1999  Ralf Baechle
- */
-#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-
-/*
  * This is included by init/main.c to check for architecture-dependent bugs.
  *
  * Needs:
  *	void check_bugs(void);
  */
+#ifndef __ASM_BUGS_H
+#define __ASM_BUGS_H
 
+extern void check_bugs(void);
 
-static inline void check_wait(void)
-{
-	printk("Checking for 'wait' instruction... ");
-	switch(mips_cpu.cputype) {
-	case CPU_R3081:
-	case CPU_R3081E:
-		cpu_wait = r3081_wait;
-		printk(" available.\n");
-		break;
-	case CPU_R4200: 
-	case CPU_R4300: 
-	case CPU_R4600: 
-	case CPU_R4640: 
-	case CPU_R4650: 
-	case CPU_R4700: 
-	case CPU_R5000: 
-	case CPU_NEVADA:
-	case CPU_RM7000:
-		cpu_wait = r4k_wait;
-		printk(" available.\n");
-		break;
-	default:
-		printk(" unavailable.\n");
-		break;
-	}
-}
-
-static void __init
-check_bugs(void)
-{
-	check_wait();
-}
+#endif /* __ASM_BUGS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/byteorder.h linux/include/asm-mips/byteorder.h
--- linux.orig/include/asm-mips/byteorder.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/byteorder.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: byteorder.h,v 1.8 1998/11/02 09:29:32 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/cache.h linux/include/asm-mips/cache.h
--- linux.orig/include/asm-mips/cache.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/cache.h	2002-07-20 01:08:31.000000000 +0000
@@ -11,7 +11,7 @@
 
 #include <linux/config.h>
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 /*
  * Descriptor for a cache
  */
@@ -21,14 +21,14 @@
 	int ways;
 	int flags;	/* Details like write thru/back, coherent, etc. */
 };
-#endif
+#endif /* !__ASSEMBLY__ */
 
 /*
  * Flag definitions
  */
 #define MIPS_CACHE_NOT_PRESENT 0x00000001
 
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000) || defined(CONFIG_CPU_TX39XX)
 #define L1_CACHE_BYTES		16
 #else
 #define L1_CACHE_BYTES 		32	/* A guess */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/checksum.h linux/include/asm-mips/checksum.h
--- linux.orig/include/asm-mips/checksum.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/checksum.h	2002-07-20 01:08:25.000000000 +0000
@@ -41,7 +41,7 @@
  * Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-extern inline unsigned int csum_and_copy_to_user (const char *src, char *dst,
+static inline unsigned int csum_and_copy_to_user (const char *src, char *dst,
 						  int len, int sum,
 						  int *err_ptr)
 {
@@ -80,10 +80,9 @@
 	"xori\t%0,0xffff\n\t"
 	".set\tat"
 	: "=r" (sum)
-	: "0" (sum)
-	: "$1");
+	: "0" (sum));
 
- 	return sum;
+	return sum;
 }
  
 /*
@@ -133,8 +132,7 @@
 	"2:\t.set\tat\n\t"
 	".set\treorder"
 	: "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy)
-	: "1" (iph), "2" (ihl)
-	: "$1");
+	: "1" (iph), "2" (ihl));
 
 	return csum_fold(sum);
 }
@@ -170,8 +168,7 @@
 #else
 	  "r" (((proto)<<16)+len),
 #endif
-	  "r" (sum)
-	: "$1");
+	  "r" (sum));
 
 	return sum;
 }
@@ -217,48 +214,49 @@
 	"lw\t%1, 0(%2)\t\t\t# four words source address\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 4(%2)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 8(%2)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 12(%2)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 0(%3)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 4(%3)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 8(%3)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 12(%3)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
+
+	"addu\t%0, $1\t\t\t# Add final carry\n\t"
 	".set\tnoat\n\t"
 	".set\tnoreorder"
 	: "=r" (sum), "=r" (proto)
 	: "r" (saddr), "r" (daddr),
-	  "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)
-	: "$1");
+	  "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
 
 	return csum_fold(sum);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/cobalt/cobalt.h linux/include/asm-mips/cobalt/cobalt.h
--- linux.orig/include/asm-mips/cobalt/cobalt.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/cobalt/cobalt.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,107 @@
+/*
+ * Lowlevel hardware stuff for the MIPS based Cobalt microservers.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997 Cobalt Microserver
+ * Copyright (C) 1997 Ralf Baechle
+ * Copyright (C) 2001 Liam Davies (ldavies@agile.tv)
+ *
+ */
+#ifndef __ASM_MIPS_COBALT_H 
+#define __ASM_MIPS_COBALT_H 
+
+/*
+ * COBALT interrupt enable bits
+ */
+#define COBALT_IE_PCI          (1 << 0)
+#define COBALT_IE_FLOPPY       (1 << 1)
+#define COBALT_IE_KEYBOARD     (1 << 2)
+#define COBALT_IE_SERIAL1      (1 << 3)
+#define COBALT_IE_SERIAL2      (1 << 4)
+#define COBALT_IE_PARALLEL     (1 << 5)
+#define COBALT_IE_GPIO         (1 << 6)
+#define COBALT_IE_RTC          (1 << 7)
+
+/*
+ * PCI defines
+ */
+#define COBALT_IE_ETHERNET     (1 << 7)
+#define COBALT_IE_SCSI         (1 << 7)
+
+/*
+ * COBALT Interrupt Level definitions.
+ * These should match the request IRQ id's.
+ */
+#define COBALT_TIMER_IRQ       0
+#define COBALT_KEYBOARD_IRQ    1
+#define COBALT_QUBE_ETH_IRQ    13
+#define COBALT_QUBE_SLOT_IRQ   9
+#define COBALT_RAQ_ETH0_IRQ    4
+#define COBALT_RAQ_ETH1_IRQ    13
+#define COBALT_SCC_IRQ         4
+#define COBALT_SERIAL2_IRQ     4
+#define COBALT_PARALLEL_IRQ    5
+#define COBALT_FLOPPY_IRQ      6 /* needs to be consistent with floppy driver! */
+#define COBALT_SCSI_IRQ        7
+
+/*
+ * PCI configuration space manifest constants.  These are wired into
+ * the board layout according to the PCI spec to enable the software
+ * to probe the hardware configuration space in a well defined manner.
+ *
+ * The PCI_DEVSHFT() macro transforms these values into numbers
+ * suitable for passing as the dev parameter to the various
+ * pcibios_read/write_config routines.
+ */
+#define COBALT_PCICONF_CPU      0x06
+#define COBALT_PCICONF_ETH0     0x07
+#define COBALT_PCICONF_RAQSCSI  0x08
+#define COBALT_PCICONF_VIA      0x09
+#define COBALT_PCICONF_PCISLOT  0x0A
+#define COBALT_PCICONF_ETH1     0x0C
+
+/*
+ * Handling the VIA ISA host bridge.
+ */
+
+#define        VIA_DELAY()                                             \
+{                                                              \
+       unsigned char ctr;                                      \
+       for (ctr=0;ctr<1;ctr++);                                \
+}
+
+#define VIA_PORT_WRITE(x,y)                                    \
+{                                                              \
+       *((volatile unsigned char *) (0xb0000000 | x)) = y;     \
+       VIA_DELAY();                                            \
+}
+
+#define VIA_PORT_READ(x)       (*((unsigned char *) (0xB0000000 | (x))))
+
+#define RESET_VIA_TIMER()                                      \
+       asm("sb\t%1,0x70(%0)\n\t"                               \
+           "lb\$0,0x71(%0)"                                    \
+           : /* No outputs */                                  \
+           : "r" (0xb0000000), "i" (0x0c));
+
+#define VIA_CMOS_ADDR 0x70
+#define VIA_CMOS_DATA 0x71
+
+/*
+ * The Cobalt board id information.  The boards have an ID number wired
+ * into the VIA that is available in the high nibble of register 94.
+ * This register is available in the VIA configuration space through the
+ * interface routines qube_pcibios_read/write_config. See cobalt/pci.c
+ */
+#define VIA_COBALT_BRD_ID_REG  0x94
+#define VIA_COBALT_BRD_REG_to_ID(reg)  ((unsigned char) (reg) >> 4)
+#define COBALT_BRD_ID_QUBE1    0x3
+#define COBALT_BRD_ID_RAQ1     0x4
+#define COBALT_BRD_ID_QUBE2    0x5
+#define COBALT_BRD_ID_RAQ2     0x6
+
+#endif /* __ASM_MIPS_COBALT_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/cpu.h linux/include/asm-mips/cpu.h
--- linux.orig/include/asm-mips/cpu.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/cpu.h	2002-07-20 01:08:26.000000000 +0000
@@ -26,10 +26,8 @@
 
 #define PRID_COMP_LEGACY       0x000000
 #define PRID_COMP_MIPS         0x010000
+#define PRID_COMP_BROADCOM     0x020000
 #define PRID_COMP_ALCHEMY      0x030000
-/* 
- * Don't know who should be here...QED and Sandcraft, maybe?
- */
 #define PRID_COMP_SIBYTE       0x040000
 
 /*
@@ -38,7 +36,8 @@
  * be examined.  These are valid when 23:16 == PRID_COMP_LEGACY
  */
 #define PRID_IMP_R2000		0x0100
-#define PRID_IMP_AU1000	0x0100
+#define PRID_IMP_AU1_REV1	0x0100
+#define PRID_IMP_AU1_REV2	0x0200
 #define PRID_IMP_R3000		0x0200		/* Same as R2000A  */
 #define PRID_IMP_R6000		0x0300		/* Same as R3000A  */
 #define PRID_IMP_R4000		0x0400
@@ -54,13 +53,16 @@
 #define PRID_IMP_R4640		0x2200
 #define PRID_IMP_R4650		0x2200		/* Same as R4640 */
 #define PRID_IMP_R5000		0x2300
+#define PRID_IMP_TX49		0x2d00
 #define PRID_IMP_SONIC		0x2400
 #define PRID_IMP_MAGIC		0x2500
 #define PRID_IMP_RM7000		0x2700
 #define PRID_IMP_NEVADA		0x2800		/* RM5260 ??? */
 #define PRID_IMP_R5432		0x5400
+#define PRID_IMP_R5500		0x5500
 #define PRID_IMP_4KC		0x8000
 #define PRID_IMP_5KC		0x8100
+#define PRID_IMP_20KC		0x8200
 #define PRID_IMP_4KEC		0x8400
 #define PRID_IMP_4KSC		0x8600
 
@@ -86,13 +88,25 @@
 #define PRID_REV_TX3922 	0x0030
 #define PRID_REV_TX3927 	0x0040
 
-#ifndef  _LANGUAGE_ASSEMBLY
+/*
+ * FPU implementation/revision register (CP1 control register 0).
+ *
+ * +---------------------------------+----------------+----------------+
+ * | 0                               | Implementation | Revision       |
+ * +---------------------------------+----------------+----------------+
+ *  31                             16 15             8 7              0
+ */
+
+#define FPIR_IMP_NONE		0x0000
+
+#ifndef __ASSEMBLY__
 /*
  * Capability and feature descriptor structure for MIPS CPU
  */
 struct mips_cpu {
 	unsigned int processor_id;
-	unsigned int cputype;		/* Old "mips_cputype" code */
+	unsigned int fpu_id;
+	unsigned int cputype;
 	int isa_level;
 	int options;
 	int tlbsize;
@@ -102,7 +116,22 @@
 	struct cache_desc tcache;	/* Tertiary/split secondary cache */
 };
 
-#endif
+extern struct mips_cpu mips_cpu;
+
+enum cputype {
+	CPU_UNKNOWN,
+	CPU_R2000, CPU_R3000, CPU_R3000A, CPU_R3041, CPU_R3051, CPU_R3052,
+	CPU_R3081, CPU_R3081E, CPU_R4000PC, CPU_R4000SC, CPU_R4000MC,
+	CPU_R4200, CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600,
+	CPU_R6000, CPU_R6000A, CPU_R8000, CPU_R10000, CPU_R12000, CPU_R4300,
+	CPU_R4650, CPU_R4700, CPU_R5000, CPU_R5000A, CPU_R4640, CPU_NEVADA,
+	CPU_RM7000, CPU_R5432, CPU_4KC, CPU_5KC, CPU_R4310, CPU_SB1,
+	CPU_TX3912, CPU_TX3922, CPU_TX3927, CPU_AU1000, CPU_4KEC, CPU_4KSC,
+	CPU_VR41XX, CPU_R5500, CPU_TX49XX, CPU_TX39XX, CPU_AU1500, CPU_20KC,
+	CPU_LAST
+};
+
+#endif /* !__ASSEMBLY__ */
 
 /*
  * ISA Level encodings
@@ -118,17 +147,20 @@
 /*
  * CPU Option encodings
  */
-#define MIPS_CPU_TLB		0x00000001  /* CPU has TLB */
+#define MIPS_CPU_TLB		0x00000001 /* CPU has TLB */
 /* Leave a spare bit for variant MMU types... */
-#define MIPS_CPU_4KEX		0x00000004  /* "R4K" exception model */
-#define MIPS_CPU_4KTLB		0x00000008  /* "R4K" TLB handler */
-#define MIPS_CPU_FPU		0x00000010  /* CPU has FPU */
-#define MIPS_CPU_32FPR		0x00000020  /* 32 dbl. prec. FP registers */
-#define MIPS_CPU_COUNTER	0x00000040  /* Cycle count/compare */
-#define MIPS_CPU_WATCH		0x00000080  /* watchpoint registers */
-#define MIPS_CPU_MIPS16		0x00000100  /* code compression */
-#define MIPS_CPU_DIVEC		0x00000200  /* dedicated interrupt vector */
-#define MIPS_CPU_VCE		0x00000400  /* virt. coherence conflict possible */
+#define MIPS_CPU_4KEX		0x00000004 /* "R4K" exception model */
+#define MIPS_CPU_4KTLB		0x00000008 /* "R4K" TLB handler */
+#define MIPS_CPU_FPU		0x00000010 /* CPU has FPU */
+#define MIPS_CPU_32FPR		0x00000020 /* 32 dbl. prec. FP registers */
+#define MIPS_CPU_COUNTER	0x00000040 /* Cycle count/compare */
+#define MIPS_CPU_WATCH		0x00000080 /* watchpoint registers */
+#define MIPS_CPU_MIPS16		0x00000100 /* code compression */
+#define MIPS_CPU_DIVEC		0x00000200 /* dedicated interrupt vector */
+#define MIPS_CPU_VCE		0x00000400 /* virt. coherence conflict possible */
 #define MIPS_CPU_CACHE_CDEX	0x00000800 /* Create_Dirty_Exclusive CACHE op */
+#define MIPS_CPU_MCHECK		0x00001000 /* Machine check exception */
+#define MIPS_CPU_EJTAG		0x00002000 /* EJTAG exception */
+#define MIPS_CPU_NOFPUEX	0x00004000 /* no FPU exception */
 
 #endif /* _ASM_CPU_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/current.h linux/include/asm-mips/current.h
--- linux.orig/include/asm-mips/current.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/current.h	2002-07-20 01:08:25.000000000 +0000
@@ -9,11 +9,11 @@
 #ifndef _ASM_CURRENT_H
 #define _ASM_CURRENT_H
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /* MIPS rules... */
 register struct task_struct *current asm("$28");
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_CURRENT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ddb5xxx/ddb5476.h linux/include/asm-mips/ddb5xxx/ddb5476.h
--- linux.orig/include/asm-mips/ddb5xxx/ddb5476.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/ddb5xxx/ddb5476.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,157 @@
+/*
+ * header file specific for ddb5476
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * 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.
+ *
+ */
+
+/*
+ *  Memory map (physical address)
+ *
+ *  Note most of the following address must be properly aligned by the
+ *  corresponding size.  For example, if PCI_IO_SIZE is 16MB, then
+ *  PCI_IO_BASE must be aligned along 16MB boundary.
+ */
+#define DDB_SDRAM_BASE		0x00000000
+#define DDB_SDRAM_SIZE		0x04000000      /* 64MB */
+
+#define	DDB_DCS3_BASE		0x04000000	/* flash 1 */
+#define	DDB_DCS3_SIZE		0x01000000	/* 16MB */
+
+#define	DDB_DCS2_BASE		0x05000000	/* flash 2 */
+#define	DDB_DCS2_SIZE		0x01000000	/* 16MB */
+
+#define DDB_PCI_IO_BASE		0x06000000      
+#define DDB_PCI_IO_SIZE		0x02000000      /* 32 MB */
+
+#define	DDB_PCI_MEM_BASE	0x08000000
+#define	DDB_PCI_MEM_SIZE	0x08000000	/* 128 MB */
+
+#define	DDB_DCS5_BASE		0x13000000	/* DDB status regs */
+#define	DDB_DCS5_SIZE		0x00200000	/* 2MB, 8-bit */
+
+#define	DDB_DCS4_BASE		0x14000000	/* DDB control regs */
+#define	DDB_DCS4_SIZE		0x00200000	/* 2MB, 8-bit */
+
+#define DDB_INTCS_BASE		0x1fa00000      /* VRC5476 control regs */
+#define DDB_INTCS_SIZE		0x00200000      /* 2MB */
+
+#define DDB_BOOTCS_BASE         0x1fc00000      /* Boot ROM / EPROM /Flash */
+#define DDB_BOOTCS_SIZE         0x00200000      /* 2 MB - doc says 4MB */
+
+
+/* aliases */
+#define	DDB_PCI_CONFIG_BASE	DDB_PCI_MEM_BASE
+#define	DDB_PCI_CONFIG_SIZE	DDB_PCI_MEM_SIZE
+
+/* PCI intr ack share PCIW0 with PCI IO */
+#define	DDB_PCI_IACK_BASE	DDB_PCI_IO_BASE
+
+/*
+ * Interrupt mapping
+ *
+ * We have three interrupt controllers:
+ *
+ *   . CPU itself - 8 sources
+ *   . i8259 - 16 sources
+ *   . vrc5476 - 16 sources
+ *
+ *  They connected as follows:
+ *    all vrc5476 interrupts are routed to cpu IP2 (by software setting)
+ *    all i2869 are routed to INTC in vrc5476 (by hardware connection)
+ *
+ *  All VRC5476 PCI interrupts are level-triggered (no ack needed).
+ *  All PCI irq but INTC are active low.
+ */
+
+/* 
+ * irq number block assignment
+ */
+
+#define	NUM_CPU_IRQ		8
+#define	NUM_I8259_IRQ		16
+#define	NUM_VRC5476_IRQ		16
+
+#define	DDB_IRQ_BASE		0
+
+#define	I8259_IRQ_BASE		DDB_IRQ_BASE
+#define	VRC5476_IRQ_BASE	(I8259_IRQ_BASE + NUM_I8259_IRQ)
+#define	CPU_IRQ_BASE		(VRC5476_IRQ_BASE + NUM_VRC5476_IRQ)
+
+/*
+ * vrc5476 irq defs, see page 52-64 of Vrc5074 system controller manual
+ */
+
+#define VRC5476_IRQ_CPCE	0	/* cpu parity error */
+#define VRC5476_IRQ_CNTD	1	/* cpu no target */
+#define VRC5476_IRQ_MCE		2	/* memory check error */
+#define VRC5476_IRQ_DMA		3	/* DMA */
+#define VRC5476_IRQ_UART	4	/* vrc5476 builtin UART, not used */
+#define VRC5476_IRQ_WDOG	5	/* watchdog timer */
+#define VRC5476_IRQ_GPT		6	/* general purpose timer */
+#define VRC5476_IRQ_LBRT	7	/* local bus read timeout */
+#define VRC5476_IRQ_INTA	8	/* PCI INT #A */
+#define VRC5476_IRQ_INTB	9	/* PCI INT #B */
+#define VRC5476_IRQ_INTC	10	/* PCI INT #C */
+#define VRC5476_IRQ_INTD	11	/* PCI INT #D */
+#define VRC5476_IRQ_INTE	12	/* PCI INT #E */
+#define VRC5476_IRQ_RESERVED_13	13	/* reserved  */
+#define VRC5476_IRQ_PCIS	14	/* PCI SERR #  */
+#define VRC5476_IRQ_PCI		15	/* PCI internal error */
+
+/*
+ * i2859 irq assignment
+ */
+#define I8259_IRQ_RESERVED_0	0	
+#define I8259_IRQ_KEYBOARD	1	/* M1543 default */
+#define I8259_IRQ_CASCADE	2
+#define I8259_IRQ_UART_B	3	/* M1543 default, may conflict with RTC according to schematic diagram  */
+#define I8259_IRQ_UART_A	4	/* M1543 default */
+#define I8259_IRQ_PARALLEL	5	/* M1543 default */
+#define I8259_IRQ_RESERVED_6	6
+#define I8259_IRQ_RESERVED_7	7
+#define I8259_IRQ_RTC		8	/* who set this? */
+#define I8259_IRQ_USB		9	/* ddb_setup */
+#define I8259_IRQ_PMU		10	/* ddb_setup */
+#define I8259_IRQ_RESERVED_11	11
+#define I8259_IRQ_RESERVED_12	12	/* m1543_irq_setup */
+#define I8259_IRQ_RESERVED_13	13
+#define I8259_IRQ_HDC1		14	/* default and ddb_setup */
+#define I8259_IRQ_HDC2		15	/* default */
+
+
+/*
+ * misc
+ */
+#define	VRC5476_I8259_CASCADE	VRC5476_IRQ_INTC
+#define	CPU_VRC5476_CASCADE	2
+
+#define is_i8259_irq(irq)       ((irq) < NUM_I8259_IRQ)
+#define nile4_to_irq(n)         ((n)+NUM_I8259_IRQ)
+#define irq_to_nile4(n)         ((n)-NUM_I8259_IRQ)
+
+/*
+ * low-level irq functions
+ */
+#ifndef _LANGUAGE_ASSEMBLY
+extern void nile4_map_irq(int nile4_irq, int cpu_irq);
+extern void nile4_map_irq_all(int cpu_irq);
+extern void nile4_enable_irq(int nile4_irq);
+extern void nile4_disable_irq(int nile4_irq);
+extern void nile4_disable_irq_all(void);
+extern u16 nile4_get_irq_stat(int cpu_irq);
+extern void nile4_enable_irq_output(int cpu_irq);
+extern void nile4_disable_irq_output(int cpu_irq);
+extern void nile4_set_pci_irq_polarity(int pci_irq, int high);
+extern void nile4_set_pci_irq_level_or_edge(int pci_irq, int level);
+extern void nile4_clear_irq(int nile4_irq);
+extern void nile4_clear_irq_mask(u32 mask);
+extern u8 nile4_i8259_iack(void);
+extern void nile4_dump_irq_status(void);        /* Debug */
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ddb5xxx/ddb5477.h linux/include/asm-mips/ddb5xxx/ddb5477.h
--- linux.orig/include/asm-mips/ddb5xxx/ddb5477.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/ddb5xxx/ddb5477.h	2002-07-20 01:08:27.000000000 +0000
@@ -18,7 +18,6 @@
 #define __ASM_DDB5XXX_DDB5477_H
 
 #include <linux/config.h>
-#include <asm/ddb5xxx/ddb5xxx.h>
 
 /*
  * This contains macros that are specific to DDB5477 or renamed from
@@ -28,9 +27,9 @@
 /*
  * renamed PADRs
  */
-#define	DDB_LCS0	DDB_LDCS0
-#define	DDB_LCS1	DDB_LDCS1
-#define	DDB_LCS2	DDB_LDCS2
+#define	DDB_LCS0	DDB_DCS2
+#define	DDB_LCS1	DDB_DCS3
+#define	DDB_LCS2	DDB_DCS4
 #define	DDB_VRC5477	DDB_INTCS
 
 /*
@@ -173,8 +172,10 @@
  *  corresponding size.  For example, if PCI_IO_SIZE is 16MB, then
  *  PCI_IO_BASE must be aligned along 16MB boundary.
  */
+
+/* the actual ram size is detected at run-time */
 #define	DDB_SDRAM_BASE		0x00000000
-#define	DDB_SDRAM_SIZE		0x08000000	/* 128MB, for sure? */
+#define	DDB_MAX_SDRAM_SIZE	0x08000000	/* less than 128MB */
 
 #define	DDB_PCI0_MEM_BASE	0x08000000
 #define	DDB_PCI0_MEM_SIZE	0x08000000	/* 128 MB */
@@ -227,7 +228,7 @@
 /* 
  * debug routines
  */
-#if defined(CONFIG_LL_DEBUG)
+#if defined(CONFIG_DEBUG)
 extern void vrc5477_show_pdar_regs(void);
 extern void vrc5477_show_pci_regs(void);
 extern void vrc5477_show_bar_regs(void);
@@ -235,4 +236,9 @@
 extern void vrc5477_show_all_regs(void);
 #endif
 
+/*
+ * RAM size
+ */
+extern int board_ram_size;
+
 #endif /* __ASM_DDB5XXX_DDB5477_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ddb5xxx/ddb5xxx.h linux/include/asm-mips/ddb5xxx/ddb5xxx.h
--- linux.orig/include/asm-mips/ddb5xxx/ddb5xxx.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/ddb5xxx/ddb5xxx.h	2002-07-20 01:08:21.000000000 +0000
@@ -1,5 +1,4 @@
-/***********************************************************************
- *
+/*
  * Copyright 2001 MontaVista Software Inc.
  * Author: jsun@mvista.com or jsun@junsun.net
  *
@@ -14,7 +13,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  *
- ***********************************************************************
  */
 
 #ifndef __ASM_DDB5XXX_DDB5XXX_H
@@ -23,8 +21,6 @@
 #include <linux/config.h>
 #include <linux/types.h>
 
-#include <asm/ddb5xxx/debug.h>
-
 /*
  *  This file is based on the following documentation:
  *
@@ -49,12 +45,13 @@
 
 #define DDB_SDRAM0	0x0000	/* SDRAM Bank 0 [R/W] */
 #define DDB_SDRAM1	0x0008	/* SDRAM Bank 1 [R/W] */
-#define DDB_LDCS0	0x0010	/* Device Chip-Select 0 [R/W] */
-#define DDB_LDCS1	0x0018	/* Device Chip-Select 1 [R/W] */
-#define DDB_LDCS2	0x0020	/* Device Chip-Select 2 [R/W] */
-#define DDB_LDCS3	0x0028	/* Device Chip-Select 3 [R/W] */
-#define DDB_LDCS4	0x0030	/* Device Chip-Select 4 [R/W] */
-#define DDB_LDCS5	0x0038	/* Device Chip-Select 5 [R/W] */
+#define DDB_DCS2	0x0010	/* Device Chip-Select 2 [R/W] */
+#define DDB_DCS3	0x0018	/* Device Chip-Select 3 [R/W] */
+#define DDB_DCS4	0x0020	/* Device Chip-Select 4 [R/W] */
+#define DDB_DCS5	0x0028	/* Device Chip-Select 5 [R/W] */
+#define DDB_DCS6	0x0030	/* Device Chip-Select 6 [R/W] */
+#define DDB_DCS7	0x0038	/* Device Chip-Select 7 [R/W] */
+#define DDB_DCS8	0x0040	/* Device Chip-Select 8 [R/W] */
 #define DDB_PCIW0	0x0060	/* PCI Address Window 0 [R/W] */
 #define DDB_PCIW1	0x0068	/* PCI Address Window 1 [R/W] */
 #define DDB_INTCS	0x0070	/* Controller Internal Registers and Devices */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ddb5xxx/debug.h linux/include/asm-mips/ddb5xxx/debug.h
--- linux.orig/include/asm-mips/ddb5xxx/debug.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/ddb5xxx/debug.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,42 +0,0 @@
-/***********************************************************************
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * include/asm-mips/ddb5xxx/debug.h
- *     Some debug macros used by ddb code.
- *
- * 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.
- *
- ***********************************************************************
- */
-
-#ifndef __ASM_DDB5XXX_DEBUG_H
-#define __ASM_DDB5XXX_DEBUG_H
-
-#include <linux/config.h>
-
-/*
- * macro for catching spurious errors.  Eable to LL_DEBUG in kernel hacking
- * config menu.
- */
-#ifdef CONFIG_LL_DEBUG
-
-#include <linux/kernel.h>
-
-#define MIPS_ASSERT(x)  if (!(x)) { panic("MIPS_ASSERT failed at %s:%d\n", __FILE__, __LINE__); }
-#define MIPS_VERIFY(x, y) MIPS_ASSERT(x y)
-#define MIPS_DEBUG(x)  do { x; } while (0)
-
-#else
-
-#define MIPS_ASSERT(x)
-#define MIPS_VERIFY(x, y) x
-#define MIPS_DEBUG(x)
-
-#endif
-
-#endif /* __ASM_DDB5XXX_DEBUG_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ddb5xxx/pci.h linux/include/asm-mips/ddb5xxx/pci.h
--- linux.orig/include/asm-mips/ddb5xxx/pci.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/ddb5xxx/pci.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,34 +0,0 @@
-#ifndef __ASM_DDB5XXXX_PCI_H
-#define __ASM_DDB5XXXX_PCI_H
-
-/*
- * This file essentially defines the interface between board
- * specific PCI code and MIPS common PCI code.  Should potentially put
- * into include/asm/pci.h file.
- */
-
-#include <linux/ioport.h>
-#include <linux/pci.h>
-
-/*
- * Each pci channel is a top-level PCI bus seem by CPU.  A machine  with
- * multiple PCI channels may have multiple PCI host controllers or a
- * single controller supporting multiple channels.
- */
-struct pci_channel {
-	struct pci_ops *pci_ops;
-	struct resource *io_resource;
-	struct resource *mem_resource;
-};
-
-/* 
- * each board defines an array of pci_channels, that ends with all NULL entry
- */
-extern struct pci_channel mips_pci_channels[];
-
-/*
- * board supplied pci irq fixup routine
- */
-extern void pcibios_fixup_irqs(void);
-
-#endif  /* __ASM_DDB5XXXX_PCI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/debug.h linux/include/asm-mips/debug.h
--- linux.orig/include/asm-mips/debug.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/debug.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,48 @@
+/*
+ * Debug macros for run-time debugging.  Turned on/off with CONFIG_DEBUG option.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * 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.
+ *
+ */
+
+#ifndef _ASM_DEBUG_H
+#define _ASM_DEBUG_H
+
+#include <linux/config.h>
+
+/*
+ * run-time macros for catching spurious errors.  Eable CONFIG_DEBUG in 
+ * kernel hacking config menu to use them.
+ *
+ * Use them as run-time debugging aid.  NEVER USE THEM AS ERROR HANDLING CODE!!!
+ */
+
+#ifdef CONFIG_DEBUG
+
+#include <linux/kernel.h>
+
+#define db_assert(x)  if (!(x)) { \
+	panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+#define db_warn(x)  if (!(x)) { \
+	printk(KERN_WARNING "warning at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+#define db_verify(x, y) db_assert(x y)
+#define db_verify_warn(x, y) db_warn(x y)
+#define db_run(x)  do { x; } while (0)
+
+#else
+
+#define db_assert(x)
+#define db_warn(x)
+#define db_verify(x, y) x
+#define db_verify_warn(x, y) x
+#define db_run(x)
+
+#endif
+
+#endif /* _ASM_DEBUG_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/interrupts.h linux/include/asm-mips/dec/interrupts.h
--- linux.orig/include/asm-mips/dec/interrupts.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/dec/interrupts.h	2002-07-20 01:08:32.000000000 +0000
@@ -8,77 +8,118 @@
  *
  * Copyright (C) 1997 by Paul M. Antoine.
  * reworked 1998 by Harald Koerfgen.
+ * Copyright (C) 2001, 2002  Maciej W. Rozycki
  */
 
 #ifndef __ASM_DEC_INTERRUPTS_H 
 #define __ASM_DEC_INTERRUPTS_H 
 
-/*
- * DECstation Interrupts
- */
+#include <asm/mipsregs.h>
+
 
 /*
- * This list reflects the priority of the Interrupts.
- * Exception: on kmins we have to handle Memory Error 
- * Interrupts before the TC Interrupts.
+ * The list of possible system devices which provide an
+ * interrupt.  Not all devices exist on a given system.
  */
-#define CLOCK 	0
-#define SCSI_DMA_INT 	1
-#define SCSI_INT	2
-#define ETHER		3
-#define SERIAL		4
-#define TC0		5
-#define TC1		6
-#define TC2		7
-#define MEMORY		8
-#define FPU		9
-#define HALT		10
+#define DEC_IRQ_CASCADE		0	/* cascade from CSR or I/O ASIC */
+
+/* Ordinary interrupts */
+#define DEC_IRQ_AB_RECV		1	/* ACCESS.bus receive */
+#define DEC_IRQ_AB_XMIT		2	/* ACCESS.bus transmit */
+#define DEC_IRQ_DZ11		3	/* DZ11 (DC7085) serial */
+#define DEC_IRQ_ASC		4	/* ASC (NCR53C94) SCSI */
+#define DEC_IRQ_FLOPPY		5	/* 82077 FDC */
+#define DEC_IRQ_FPU		6	/* R3k FPU */
+#define DEC_IRQ_HALT		7	/* HALT button or from ACCESS.Bus */
+#define DEC_IRQ_ISDN		8	/* Am79C30A ISDN */
+#define DEC_IRQ_LANCE		9	/* LANCE (Am7990) Ethernet */
+#define DEC_IRQ_MEMORY		10	/* memory, I/O bus write errors */
+#define DEC_IRQ_PSU		11	/* power supply unit warning */
+#define DEC_IRQ_RTC		12	/* DS1287 RTC */
+#define DEC_IRQ_SCC0		13	/* SCC (Z85C30) serial #0 */
+#define DEC_IRQ_SCC1		14	/* SCC (Z85C30) serial #1 */
+#define DEC_IRQ_SII		15	/* SII (DC7061) SCSI */
+#define DEC_IRQ_TC0		16	/* TURBOchannel slot #0 */
+#define DEC_IRQ_TC1		17	/* TURBOchannel slot #1 */
+#define DEC_IRQ_TC2		18	/* TURBOchannel slot #2 */
+#define DEC_IRQ_TIMER		19	/* ARC periodic timer */
+#define DEC_IRQ_VIDEO		20	/* framebuffer */
+
+/* I/O ASIC DMA interrupts */
+#define DEC_IRQ_ASC_MERR	21	/* ASC memory read error */
+#define DEC_IRQ_ASC_ERR		22	/* ASC page overrun */
+#define DEC_IRQ_ASC_DMA		23	/* ASC buffer pointer loaded */
+#define DEC_IRQ_FLOPPY_ERR	24	/* FDC error */
+#define DEC_IRQ_ISDN_ERR	25	/* ISDN memory read/overrun error */
+#define DEC_IRQ_ISDN_RXDMA	26	/* ISDN recv buffer pointer loaded */
+#define DEC_IRQ_ISDN_TXDMA	27	/* ISDN xmit buffer pointer loaded */
+#define DEC_IRQ_LANCE_MERR	28	/* LANCE memory read error */
+#define DEC_IRQ_SCC0A_RXERR	29	/* SCC0A (printer) receive overrun */
+#define DEC_IRQ_SCC0A_RXDMA	30	/* SCC0A receive half page */
+#define DEC_IRQ_SCC0A_TXERR	31	/* SCC0A xmit memory read/overrun */
+#define DEC_IRQ_SCC0A_TXDMA	32	/* SCC0A transmit page end */
+#define DEC_IRQ_SCC0B_RXERR	33	/* SCC0B (ACCESS.bus) receive overrun */
+#define DEC_IRQ_SCC0B_RXDMA	34	/* SCC0B receive half page */
+#define DEC_IRQ_SCC0B_TXERR	35	/* SCC0B xmit memory read/overrun */
+#define DEC_IRQ_SCC0B_TXDMA	36	/* SCC0B transmit page end */
+#define DEC_IRQ_SCC1A_RXERR	37	/* SCC1A (modem) receive overrun */
+#define DEC_IRQ_SCC1A_RXDMA	38	/* SCC1A receive half page */
+#define DEC_IRQ_SCC1A_TXERR	39	/* SCC1A xmit memory read/overrun */
+#define DEC_IRQ_SCC1A_TXDMA	40	/* SCC1A transmit page end */
+
+/* TC5 & TC6 are virtual slots for KN02's onboard devices */
+#define DEC_IRQ_TC5		DEC_IRQ_ASC	/* virtual PMAZ-AA */
+#define DEC_IRQ_TC6		DEC_IRQ_LANCE	/* virtual PMAD-AA */
+
+#define DEC_NR_INTS		41
+
+
+/* Largest of cpu mask_nr tables. */
+#define DEC_MAX_CPU_INTS	6
+/* Largest of asic mask_nr tables. */
+#define DEC_MAX_ASIC_INTS	9
 
-#define NR_INTS	11
 
-#ifndef __ASSEMBLY__
 /*
- * Data structure to hide the differences between the DECstation Interrupts
- *
- * If asic_mask == NULL, the interrupt is directly handled by the CPU.
- * Otherwise this Interrupt is handled the IRQ Controller.
+ * CPU interrupt bits common to all systems.
  */
+#define DEC_CPU_INR_FPU		7	/* R3k FPU */
+#define DEC_CPU_INR_SW1		1	/* software #1 */
+#define DEC_CPU_INR_SW0		0	/* software #0 */
 
-typedef struct
-{
-	unsigned int	cpu_mask;	/* checking and enabling interrupts in CP0	*/
-	unsigned int	iemask;		/* enabling interrupts in IRQ Controller	*/
-} decint_t;
-
-extern volatile unsigned int *isr;
-				/* address of the interrupt status register  */
-extern volatile unsigned int *imr;
-				/* address of the interrupt mask register    */
-extern decint_t dec_interrupt[NR_INTS];
+#define DEC_CPU_IRQ_BASE	0	/* first IRQ assigned to CPU */
+
+#define DEC_CPU_IRQ_NR(n)	((n) + DEC_CPU_IRQ_BASE)
+#define DEC_CPU_IRQ_MASK(n)	(1 << ((n) + CAUSEB_IP))
+#define DEC_CPU_IRQ_ALL		(0xff << CAUSEB_IP)
+
+
+#ifndef __ASSEMBLY__
 
 /*
- * Interrupt table structure to hide differences between different
- * systems such.
+ * Interrupt table structures to hide differences between systems.
  */
-extern void *cpu_ivec_tbl[8];
-extern long cpu_mask_tbl[8];
-extern long cpu_irq_nr[8];
-extern long asic_irq_nr[32];
-extern long asic_mask_tbl[32];
+typedef union { int i; void *p; } int_ptr;
+extern int dec_interrupt[DEC_NR_INTS];
+extern int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2];
+extern int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2];
+extern int cpu_fpu_mask;
+
 
 /*
  * Common interrupt routine prototypes for all DECStations
  */
-extern void	dec_intr_unimplemented(void);
-extern void	dec_intr_fpu(void);
-extern void	dec_intr_rtc(void);
+extern void kn02_io_int(void);
+extern void kn02xa_io_int(void);
+extern void kn03_io_int(void);
+extern void asic_dma_int(void);
+extern void asic_all_int(void);
+extern void kn02_all_int(void);
+extern void cpu_all_int(void);
 
-extern void	kn02_io_int(void);
-extern void	kn02xa_io_int(void);
-extern void	kn03_io_int(void);
+extern void dec_intr_unimplemented(void);
+extern void asic_intr_unimplemented(void);
 
-extern void	asic_intr_unimplemented(void);
+#endif /* __ASSEMBLY__ */
 
-#endif
 #endif 
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/ioasic.h linux/include/asm-mips/dec/ioasic.h
--- linux.orig/include/asm-mips/dec/ioasic.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/dec/ioasic.h	2002-07-20 01:08:23.000000000 +0000
@@ -1,24 +1,33 @@
 /*
- *  linux/asm-mips/dec/ioasic.h
+ *	include/asm-mips/dec/ioasic.h
  *
- *  Copyright (C) 2000  Maciej W. Rozycki
+ *	DEC I/O ASIC access operations.
  *
- *  DEC I/O ASIC access operations.
+ *	Copyright (C) 2000, 2002  Maciej W. Rozycki
+ *
+ *	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.
  */
 
 #ifndef __ASM_DEC_IOASIC_H
 #define __ASM_DEC_IOASIC_H
 
-extern volatile unsigned int *ioasic_base;
+#include <linux/types.h>
+
+extern volatile u32 *ioasic_base;
 
-extern inline void ioasic_write(unsigned int reg, unsigned int v)
+static inline void ioasic_write(unsigned int reg, u32 v)
 {
 	ioasic_base[reg / 4] = v;
 }
 
-extern inline unsigned int ioasic_read(unsigned int reg)
+static inline u32 ioasic_read(unsigned int reg)
 {
 	return ioasic_base[reg / 4];
 }
 
+extern void init_ioasic_irqs(int base);
+
 #endif /* __ASM_DEC_IOASIC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/ioasic_addrs.h linux/include/asm-mips/dec/ioasic_addrs.h
--- linux.orig/include/asm-mips/dec/ioasic_addrs.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/dec/ioasic_addrs.h	2002-07-20 01:08:26.000000000 +0000
@@ -17,25 +17,25 @@
 
 #define CHUNK_SIZE 0x00040000
 
-#define SYSTEM_ROM 	(0*CHUNK_SIZE)		/* ??? */
-#define IOCTL 		(1*CHUNK_SIZE)
-#define ESAR 		(2*CHUNK_SIZE)
-#define LANCE 		(3*CHUNK_SIZE)
-#define SCC0 		(4*CHUNK_SIZE)
-#define VDAC_HI		(5*CHUNK_SIZE)		/* maxine only */
-#define SCC1 		(6*CHUNK_SIZE)
-#define VDAC_LO		(7*CHUNK_SIZE)		/* maxine only */
-#define TOY 		(8*CHUNK_SIZE)
-#define ISDN 		(9*CHUNK_SIZE)		/* maxine only */
-#define ERRADDR		(9*CHUNK_SIZE)		/* 3maxplus only */
-#define CHKSYN 		(10*CHUNK_SIZE)		/* 3maxplus only */
-#define ACCESS_BUS	(10*CHUNK_SIZE)		/* maxine only */
-#define MCR 		(11*CHUNK_SIZE)		/* 3maxplus only */
-#define FLOPPY 		(11*CHUNK_SIZE)		/* maxine only */
-#define SCSI 		(12*CHUNK_SIZE)
-#define FLOPPY_DMA 	(13*CHUNK_SIZE)		/* maxine only */
-#define SCSI_DMA 	(14*CHUNK_SIZE)
-#define RESERVED_4 	(15*CHUNK_SIZE)
+#define SYSTEM_ROM 	(0*CHUNK_SIZE)		/* board ROM */
+#define IOCTL 		(1*CHUNK_SIZE)		/* I/O ASIC */
+#define ESAR 		(2*CHUNK_SIZE)		/* LANCE MAC address chip */
+#define LANCE 		(3*CHUNK_SIZE)		/* LANCE Ethernet */
+#define SCC0 		(4*CHUNK_SIZE)		/* SCC #0 */
+#define VDAC_HI		(5*CHUNK_SIZE)		/* VDAC (maxine) */
+#define SCC1 		(6*CHUNK_SIZE)		/* SCC #1 (3min, 3max+) */
+#define VDAC_LO		(7*CHUNK_SIZE)		/* VDAC (maxine) */
+#define TOY 		(8*CHUNK_SIZE)		/* RTC */
+#define ISDN 		(9*CHUNK_SIZE)		/* ISDN (maxine) */
+#define ERRADDR		(9*CHUNK_SIZE)		/* bus error address (3max+) */
+#define CHKSYN 		(10*CHUNK_SIZE)		/* ECC syndrome (3max+) */
+#define ACCESS_BUS	(10*CHUNK_SIZE)		/* Access.Bus (maxine) */
+#define MCR 		(11*CHUNK_SIZE)		/* memory control (3max+) */
+#define FLOPPY 		(11*CHUNK_SIZE)		/* FDC (maxine) */
+#define SCSI 		(12*CHUNK_SIZE)		/* ASC SCSI */
+#define FLOPPY_DMA 	(13*CHUNK_SIZE)		/* FDC DMA (maxine) */
+#define SCSI_DMA 	(14*CHUNK_SIZE)		/* ??? */
+#define RESERVED_4 	(15*CHUNK_SIZE)		/* unused? */
 
 /*
  * Offsets for IOCTL registers (relative to (system_base + IOCTL))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/ioasic_ints.h linux/include/asm-mips/dec/ioasic_ints.h
--- linux.orig/include/asm-mips/dec/ioasic_ints.h	2000-02-25 06:52:30.000000000 +0000
+++ linux/include/asm-mips/dec/ioasic_ints.h	2002-07-20 01:08:30.000000000 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Definitions for the interrupt related bits in the JUNKIO Asic
+ * Definitions for the interrupt related bits in the I/O ASIC
  * interrupt status register (and the interrupt mask register, of course)
  *
  * Created with Information from:
@@ -11,99 +11,64 @@
  * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual"
  *
  * and the Mach Sources
+ *
+ * Copyright (C) 199x  the Anonymous
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 
-/* 
- * the upper 16 bits are common to all JUNKIO machines
- * (except the FLOPPY and ISDN bits, which are Maxine sepcific)
- */
-#define SCC0_TRANS_PAGEEND	0x80000000	/* Serial DMA Errors	*/
-#define SCC0_TRANS_MEMRDERR	0x40000000	/* see below		*/
-#define SCC0_RECV_HALFPAGE	0x20000000
-#define	SCC0_RECV_PAGOVRRUN	0x10000000
-#define SCC1_TRANS_PAGEEND	0x08000000	/* end of page reached	*/
-#define SCC1_TRANS_MEMRDERR	0x04000000	/* SCC1 DMA memory err	*/
-#define SCC1_RECV_HALFPAGE	0x02000000	/* SCC1 half page	*/
-#define	SCC1_RECV_PAGOVRRUN	0x01000000	/* SCC1 receive overrun	*/
-#define FLOPPY_DMA_ERROR	0x00800000	/* FDI DMA error	*/
-#define	ISDN_TRANS_PTR_LOADED	0x00400000	/* xmitbuf ptr loaded	*/
-#define ISDN_RECV_PTR_LOADED	0x00200000	/* rcvbuf ptr loaded	*/
-#define ISDN_DMA_MEMRDERR	0x00100000	/* read or ovrrun error	*/
-#define SCSI_PTR_LOADED		0x00080000
-#define SCSI_PAGOVRRUN		0x00040000	/* page overrun? */
-#define SCSI_DMA_MEMRDERR	0x00020000
-#define LANCE_DMA_MEMRDERR	0x00010000
-
-/*
- * the lower 16 bits are system specific
- */
-
-/*
- * The following three seem to be in common
- */
-#define SCSI_CHIP		0x00000200
-#define LANCE_CHIP		0x00000100
-#define SCC1_CHIP		0x00000080	/* NOT on maxine	*/
-#define SCC0_CHIP		0x00000040
+#ifndef __ASM_DEC_IOASIC_INTS_H
+#define __ASM_DEC_IOASIC_INTS_H
 
-/*
- * The rest is different
- */
+/* 
+ * The upper 16 bits are a part of the I/O ASIC's internal DMA engine
+ * and thus are common to all I/O ASIC machines.  The exception is
+ * the Maxine, which makes use of the FLOPPY and ISDN bits (otherwise
+ * unused) and has a different SCC wiring.
+ */
+					/* all systems */
+#define IO_INR_SCC0A_TXDMA	31	/* SCC0A transmit page end */
+#define IO_INR_SCC0A_TXERR	30	/* SCC0A transmit memory read error */
+#define IO_INR_SCC0A_RXDMA	29	/* SCC0A receive half page */
+#define IO_INR_SCC0A_RXERR	28	/* SCC0A receive overrun */
+#define IO_INR_ASC_DMA		19	/* ASC buffer pointer loaded */
+#define IO_INR_ASC_ERR		18	/* ASC page overrun */
+#define IO_INR_ASC_MERR		17	/* ASC memory read error */
+#define IO_INR_LANCE_MERR	16	/* LANCE memory read error */
+
+					/* except Maxine */
+#define IO_INR_SCC1A_TXDMA	27	/* SCC1A transmit page end */
+#define IO_INR_SCC1A_TXERR	26	/* SCC1A transmit memory read error */
+#define IO_INR_SCC1A_RXDMA	25	/* SCC1A receive half page */
+#define IO_INR_SCC1A_RXERR	24	/* SCC1A receive overrun */
+#define IO_INR_RES_23		23	/* unused */
+#define IO_INR_RES_22		22	/* unused */
+#define IO_INR_RES_21		21	/* unused */
+#define IO_INR_RES_20		20	/* unused */
+
+					/* Maxine */
+#define IO_INR_SCC0B_TXDMA	27	/* SCC0B transmit page end */
+#define IO_INR_SCC0B_TXERR	26	/* SCC0B transmit memory read error */
+#define IO_INR_SCC0B_RXDMA	25	/* SCC0B receive half page */
+#define IO_INR_SCC0B_RXERR	24	/* SCC0B receive overrun */
+#define IO_INR_FLOPPY_ERR	23	/* FDC error */
+#define IO_INR_ISDN_TXDMA	22	/* ISDN xmit buffer pointer loaded */
+#define IO_INR_ISDN_RXDMA	21	/* ISDN recv buffer pointer loaded */
+#define IO_INR_ISDN_ERR		20	/* ISDN memory read/overrun error */
 
-/* kmin aka 3min aka kn02ba aka DS5000_1xx */
-#define KMIN_TIMEOUT		0x00001000	/* CPU IO-Write Timeout	*/
-#define KMIN_CLOCK		0x00000020
-#define KMIN_SCSI_FIFO		0x00000004	/* SCSI Data Ready	*/
-
-/* kn02ca aka maxine */
-#define MAXINE_FLOPPY		0x00008000	/* FDI Interrupt        */
-#define MAXINE_TC0		0x00001000	/* TC Option 0      	*/
-#define MAXINE_ISDN		0x00000800	/* ISDN	Chip		*/
-#define MAXINE_FLOPPY_HDS	0x00000080	/* Floppy Status      	*/
-#define MAXINE_TC1		0x00000020	/* TC Option 1		*/
-#define MAXINE_FLOPPY_XDS	0x00000010	/* Floppy Status      	*/
-#define MAXINE_VINT		0x00000008	/* Video Frame		*/
-#define MAXINE_N_VINT		0x00000004	/* Not Video frame	*/
-#define MAXINE_DTOP_TRANS	0x00000002	/* DTI Xmit-Rdy		*/
-#define MAXINE_DTOP_RECV	0x00000001	/* DTI Recv-Available	*/
-
-/* kn03 aka 3max+ aka DS5000_2x0 */
-#define KN03_TC2		0x00002000
-#define KN03_TC1		0x00001000
-#define KN03_TC0		0x00000800
-#define KN03_SCSI_FIFO		0x00000004	/* ??? Info from Mach	*/
+#define IO_INR_DMA		16	/* first DMA IRQ */
 
 /*
- * Now form groups, i.e. all serial interrupts, all SCSI interrupts and so on. 
+ * The lower 16 bits are system-specific and thus defined in
+ * system-specific headers.
  */
-#define SERIAL_INTS	(SCC0_TRANS_PAGEEND | SCC0_TRANS_MEMRDERR | \
-			SCC0_RECV_HALFPAGE | SCC0_RECV_PAGOVRRUN | \
-			SCC1_TRANS_PAGEEND | SCC1_TRANS_MEMRDERR | \
-			SCC1_RECV_HALFPAGE | SCC1_RECV_PAGOVRRUN | \
-			SCC1_CHIP | SCC0_CHIP)
-
-#define XINE_SERIAL_INTS	(SCC0_TRANS_PAGEEND | SCC0_TRANS_MEMRDERR | \
-			SCC0_RECV_HALFPAGE | SCC0_RECV_PAGOVRRUN | \
-			SCC0_CHIP)
-
-#define SCSI_DMA_INTS	(/* SCSI_PTR_LOADED | */ SCSI_PAGOVRRUN | \
-			SCSI_DMA_MEMRDERR)
 
-#define KMIN_SCSI_INTS	(SCSI_PTR_LOADED | SCSI_PAGOVRRUN | \
-			SCSI_DMA_MEMRDERR | SCSI_CHIP | KMIN_SCSI_FIFO)
-
-#define LANCE_INTS	(LANCE_DMA_MEMRDERR | LANCE_CHIP)
-
-/*
- * For future use ...
- */
-#define XINE_FLOPPY_INTS (MAXINE_FLOPPY | MAXINE_FLOPPY_HDS | \
-			FLOPPY_DMA_ERROR | MAXINE_FLOPPY_XDS)
 
-#define XINE_ISDN_INTS	(MAXINE_ISDN | ISDN_TRANS_PTR_LOADED | \
-			ISDN_RECV_PTR_LOADED | ISDN_DMA_MEMRDERR)
+#define IO_IRQ_BASE		8	/* first IRQ assigned to I/O ASIC */
+#define IO_IRQ_LINES		32	/* number of I/O ASIC interrupts */
 
-#define XINE_DTOP_INTS	(MAXINE_DTOP_TRANS | DTOP_RECV | \
-			ISDN_TRANS_PTR_LOADED | ISDN_RECV_PTR_LOADED | \
-			ISDN_DMA_MEMRDERR)
+#define IO_IRQ_NR(n)		((n) + IO_IRQ_BASE)
+#define IO_IRQ_MASK(n)		(1 << (n))
+#define IO_IRQ_ALL		0x0000ffff
+#define IO_IRQ_DMA		0xffff0000
 
+#endif /* __ASM_DEC_IOASIC_INTS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/kn01.h linux/include/asm-mips/dec/kn01.h
--- linux.orig/include/asm-mips/dec/kn01.h	1999-06-26 00:37:53.000000000 +0000
+++ linux/include/asm-mips/dec/kn01.h	2002-07-20 01:08:30.000000000 +0000
@@ -1,15 +1,14 @@
 /*
- * Hardware info about DEC DECstation DS2100/3100 systems (otherwise known
- * as pmax or kn01.
+ * Hardware info about DECstation DS2100/3100 systems (otherwise known as
+ * pmin/pmax or KN01).
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
- * are by curteousy of Chris Fraser.
- *
- * This file is under construction - you were warned!
+ * are by courtesy of Chris Fraser.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #ifndef __ASM_MIPS_DEC_KN01_H 
 #define __ASM_MIPS_DEC_KN01_H 
@@ -18,11 +17,21 @@
 
 /*
  * Some port addresses...
- * FIXME: these addresses are incomplete and need tidying up!
  */
 
 #define KN01_LANCE_BASE (KSEG1ADDR(0x18000000)) /* 0xB8000000 */
 #define KN01_DZ11_BASE	(KSEG1ADDR(0x1c000000)) /* 0xBC000000 */
 #define KN01_RTC_BASE	(KSEG1ADDR(0x1d000000)) /* 0xBD000000 */
 
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN01_CPU_INR_MEMORY	6	/* memory, I/O bus write errors */
+#define KN01_CPU_INR_VIDEO	6	/* framebuffer */
+#define KN01_CPU_INR_RTC	5	/* DS1287 RTC */
+#define KN01_CPU_INR_DZ11	4	/* DZ11 (DC7085) serial */
+#define KN01_CPU_INR_LANCE	3	/* LANCE (Am7990) Ethernet */
+#define KN01_CPU_INR_SII	2	/* SII (DC7061) SCSI */
+
 #endif /* __ASM_MIPS_DEC_KN01_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/kn02.h linux/include/asm-mips/dec/kn02.h
--- linux.orig/include/asm-mips/dec/kn02.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/dec/kn02.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,21 +1,26 @@
 /*
- * Hardware info about DEC DECstation 5000/2xx systems (otherwise known
- * as 3max or kn02.
+ * Hardware info about DECstation 5000/200 systems (otherwise known as
+ * 3max or KN02).
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
- * are by curteousy of Chris Fraser.
- *
- * This file is under construction - you were warned!
+ * are by courtesy of Chris Fraser.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #ifndef __ASM_MIPS_DEC_KN02_H 
 #define __ASM_MIPS_DEC_KN02_H 
 
+#ifndef __ASSEMBLY__
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#endif
+
 #include <asm/addrspace.h>
 
+
 /*
  * Motherboard regs (kseg1 addresses)
  */
@@ -23,21 +28,47 @@
 
 /*
  * Some port addresses...
- * FIXME: these addresses are incomplete and need tidying up!
  */
 #define KN02_RTC_BASE	KSEG1ADDR(0x1fe80000)
 #define KN02_DZ11_BASE	KSEG1ADDR(0x1fe00000)
 
 #define KN02_CSR_BNK32M	(1<<10)			/* 32M stride */
 
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN02_CPU_INR_RES_6	6	/* unused */
+#define KN02_CPU_INR_MEMORY	5	/* memory, I/O bus write errors */
+#define KN02_CPU_INR_RES_4	4	/* unused */
+#define KN02_CPU_INR_RTC	3	/* DS1287 RTC */
+#define KN02_CPU_INR_CASCADE	2	/* CSR cascade */
+
 /*
- * Interrupt enable Bits
+ * CSR interrupt bits.
  */
-#define KN02_SLOT0	(1<<16)
-#define KN02_SLOT1	(1<<17)
-#define KN02_SLOT2	(1<<18)
-#define KN02_SLOT5	(1<<21)
-#define KN02_SLOT6	(1<<22)
-#define KN02_SLOT7	(1<<23)
+#define KN02_CSR_INR_DZ11	7	/* DZ11 (DC7085) serial */
+#define KN02_CSR_INR_LANCE	6	/* LANCE (Am7990) Ethernet */
+#define KN02_CSR_INR_ASC	5	/* ASC (NCR53C94) SCSI */
+#define KN02_CSR_INR_RES_4	4	/* unused */
+#define KN02_CSR_INR_RES_3	3	/* unused */
+#define KN02_CSR_INR_TC2	2	/* TURBOchannel slot #2 */
+#define KN02_CSR_INR_TC1	1	/* TURBOchannel slot #1 */
+#define KN02_CSR_INR_TC0	0	/* TURBOchannel slot #0 */
+
+
+#define KN02_IRQ_BASE		8	/* first IRQ assigned to CSR */
+#define KN02_IRQ_LINES		8	/* number of CSR interrupts */
+
+#define KN02_IRQ_NR(n)		((n) + KN02_IRQ_BASE)
+#define KN02_IRQ_MASK(n)	(1 << (n))
+#define KN02_IRQ_ALL		0xff
+
+
+#ifndef __ASSEMBLY__
+extern u32 cached_kn02_csr;
+extern spinlock_t kn02_lock;
+extern void init_kn02_irqs(int base);
+#endif
 
 #endif /* __ASM_MIPS_DEC_KN02_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/kn02ba.h linux/include/asm-mips/dec/kn02ba.h
--- linux.orig/include/asm-mips/dec/kn02ba.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/dec/kn02ba.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ *	include/asm-mips/dec/kn02ba.h
+ *
+ *	DECstation 5000/1xx (3min or KN02-BA) definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	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.
+ */
+#ifndef __ASM_MIPS_DEC_KN02BA_H 
+#define __ASM_MIPS_DEC_KN02BA_H 
+
+#include <asm/dec/kn02xa.h>		/* For common definitions. */
+
+/*
+ * Some port addresses...
+ */
+#define KN02BA_IOASIC_BASE	KN02XA_IOASIC_BASE	/* I/O ASIC */
+#define KN02BA_RTC_BASE		KN02XA_RTC_BASE		/* RTC */
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN02BA_CPU_INR_HALT	6	/* HALT button */
+#define KN02BA_CPU_INR_CASCADE	5	/* I/O ASIC cascade */
+#define KN02BA_CPU_INR_TC2	4	/* TURBOchannel slot #2 */
+#define KN02BA_CPU_INR_TC1	3	/* TURBOchannel slot #1 */
+#define KN02BA_CPU_INR_TC0	2	/* TURBOchannel slot #0 */
+
+/*
+ * I/O ASIC interrupt bits.  Star marks denote non-IRQ status bits.
+ */
+#define KN02BA_IO_INR_RES_15	15	/* unused */
+#define KN02BA_IO_INR_NVRAM	14	/* (*) NVRAM clear jumper */
+#define KN02BA_IO_INR_RES_13	13	/* unused */
+#define KN02BA_IO_INR_MEMORY	12	/* memory, I/O bus write errors */
+#define KN02BA_IO_INR_RES_11	11	/* unused */
+#define KN02BA_IO_INR_NRMOD	10	/* (*) NRMOD manufacturing jumper */
+#define KN02BA_IO_INR_ASC	9	/* ASC (NCR53C94) SCSI */
+#define KN02BA_IO_INR_LANCE	8	/* LANCE (Am7990) Ethernet */
+#define KN02BA_IO_INR_SCC1	7	/* SCC (Z85C30) serial #1 */
+#define KN02BA_IO_INR_SCC0	6	/* SCC (Z85C30) serial #0 */
+#define KN02BA_IO_INR_RTC	5	/* DS1287 RTC */
+#define KN02BA_IO_INR_PSU	4	/* power supply unit warning */
+#define KN02BA_IO_INR_RES_3	3	/* unused */
+#define KN02BA_IO_INR_ASC_DATA	2	/* SCSI data ready (discouraged?) */
+#define KN02BA_IO_INR_PBNC	1	/* HALT button debouncer */
+#define KN02BA_IO_INR_PBNO	0	/* ~HALT button debouncer */
+
+#endif /* __ASM_MIPS_DEC_KN02BA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/kn02ca.h linux/include/asm-mips/dec/kn02ca.h
--- linux.orig/include/asm-mips/dec/kn02ca.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/dec/kn02ca.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ *	include/asm-mips/dec/kn02ca.h
+ *
+ *	Personal DECstation 5000/xx (Maxine or KN02-CA) definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	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.
+ */
+#ifndef __ASM_MIPS_DEC_KN02CA_H 
+#define __ASM_MIPS_DEC_KN02CA_H 
+
+#include <asm/dec/kn02xa.h>		/* For common definitions. */
+
+/*
+ * Some port addresses...
+ */
+#define KN02CA_IOASIC_BASE	KN02XA_IOASIC_BASE	/* I/O ASIC */
+#define KN02CA_RTC_BASE		KN02XA_RTC_BASE		/* RTC */
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN02CA_CPU_INR_HALT	6	/* HALT from ACCESS.Bus */
+#define KN02CA_CPU_INR_CASCADE	5	/* I/O ASIC cascade */
+#define KN02CA_CPU_INR_MEMORY	4	/* memory, I/O bus write errors */
+#define KN02CA_CPU_INR_RTC	3	/* DS1287 RTC */
+#define KN02CA_CPU_INR_TIMER	2	/* ARC periodic timer */
+
+/*
+ * I/O ASIC interrupt bits.  Star marks denote non-IRQ status bits.
+ */
+#define KN02CA_IO_INR_FLOPPY	15	/* 82077 FDC */
+#define KN02CA_IO_INR_NVRAM	14	/* (*) NVRAM clear jumper */
+#define KN02CA_IO_INR_POWERON	13	/* (*) power-on reset */
+#define KN02CA_IO_INR_TC0	12	/* TURBOchannel slot #0 */
+#define KN02CA_IO_INR_ISDN	11	/* Am79C30A ISDN */
+#define KN02CA_IO_INR_NRMOD	10	/* (*) NRMOD manufacturing jumper */
+#define KN02CA_IO_INR_ASC	9	/* ASC (NCR53C94) SCSI */
+#define KN02CA_IO_INR_LANCE	8	/* LANCE (Am7990) Ethernet */
+#define KN02CA_IO_INR_HDFLOPPY	7	/* (*) HD (1.44MB) floppy status */
+#define KN02CA_IO_INR_SCC0	6	/* SCC (Z85C30) serial #0 */
+#define KN02CA_IO_INR_TC1	5	/* TURBOchannel slot #1 */
+#define KN02CA_IO_INR_XDFLOPPY	4	/* (*) XD (2.88MB) floppy status */
+#define KN02CA_IO_INR_VIDEO	3	/* framebuffer */
+#define KN02CA_IO_INR_XVIDEO	2	/* ~framebuffer */
+#define KN02CA_IO_INR_AB_XMIT	1	/* ACCESS.bus transmit */
+#define KN02CA_IO_INR_AB_RECV	0	/* ACCESS.bus receive */
+
+#endif /* __ASM_MIPS_DEC_KN02CA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/kn02xa.h linux/include/asm-mips/dec/kn02xa.h
--- linux.orig/include/asm-mips/dec/kn02xa.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/dec/kn02xa.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,18 +1,18 @@
 /*
- * Hardware info about DEC DECstation 5000/1xx systems (otherwise known
- * as 3min or kn02ba. Apllies to the Personal DECstations 5000/xx (otherwise known
- * as maxine or kn02ca) as well.
+ * Hardware info common to DECstation 5000/1xx systems (otherwise
+ * known as 3min or kn02ba) and Personal DECstations 5000/xx ones
+ * (otherwise known as maxine or kn02ca).
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
- * are by curteousy of Chris Fraser.
- * Copyright (C) 2000  Maciej W. Rozycki
+ * are by courtesy of Chris Fraser.
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
  *
  * These are addresses which have to be known early in the boot process.
- * For other addresses refer to tc.h ioasic_addrs.h and friends.
+ * For other addresses refer to tc.h, ioasic_addrs.h and friends.
  */
 #ifndef __ASM_MIPS_DEC_KN02XA_H 
 #define __ASM_MIPS_DEC_KN02XA_H 
@@ -21,7 +21,6 @@
 
 /*
  * Some port addresses...
- * FIXME: these addresses are incomplete and need tidying up!
  */
 #define KN02XA_IOASIC_BASE	KSEG1ADDR(0x1c040000)	/* I/O ASIC */
 #define KN02XA_RTC_BASE		KSEG1ADDR(0x1c200000)	/* RTC */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/kn03.h linux/include/asm-mips/dec/kn03.h
--- linux.orig/include/asm-mips/dec/kn03.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/dec/kn03.h	2002-07-20 01:08:35.000000000 +0000
@@ -1,14 +1,16 @@
 /*
- * Hardware info about DEC DECstation 5000/2x0 systems (otherwise known
- * as 3max+ or kn03.
+ * Hardware info about DECstation 5000/2x0 systems (otherwise known as
+ * 3max+) and DECsystem 5900 systems (otherwise known as bigmax) which
+ * differ mechanically but are otherwise identical (both are known as
+ * KN03).
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
- * are by curteousy of Chris Fraser.
- * Copyright (C) 2000  Maciej W. Rozycki
+ * are by courtesy of Chris Fraser.
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
  *
  * These are addresses which have to be known early in the boot process.
  * For other addresses refer to tc.h ioasic_addrs.h and friends.
@@ -20,7 +22,6 @@
 
 /*
  * Some port addresses...
- * FIXME: these addresses are incomplete and need tidying up!
  */
 #define KN03_IOASIC_BASE	KSEG1ADDR(0x1f840000)	/* I/O ASIC */
 #define KN03_RTC_BASE		KSEG1ADDR(0x1fa00000)	/* RTC */
@@ -31,4 +32,34 @@
 
 #define KN03_IOASIC_REG(r)	(KN03_IOASIC_BASE+(r))
 
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN03_CPU_INR_HALT	6	/* HALT button */
+#define KN03_CPU_INR_MEMORY	5	/* memory, I/O bus write errors */
+#define KN03_CPU_INR_RES_4	4	/* unused */
+#define KN03_CPU_INR_RTC	3	/* DS1287 RTC */
+#define KN03_CPU_INR_CASCADE	2	/* I/O ASIC cascade */
+
+/*
+ * I/O ASIC interrupt bits.  Star marks denote non-IRQ status bits.
+ */
+#define KN03_IO_INR_3MAXP	15	/* (*) 3max+/bigmax ID */
+#define KN03_IO_INR_NVRAM	14	/* (*) NVRAM clear jumper */
+#define KN03_IO_INR_TC2		13	/* TURBOchannel slot #2 */
+#define KN03_IO_INR_TC1		12	/* TURBOchannel slot #1 */
+#define KN03_IO_INR_TC0		11	/* TURBOchannel slot #0 */
+#define KN03_IO_INR_NRMOD	10	/* (*) NRMOD manufacturing jumper */
+#define KN03_IO_INR_ASC		9	/* ASC (NCR53C94) SCSI */
+#define KN03_IO_INR_LANCE	8	/* LANCE (Am7990) Ethernet */
+#define KN03_IO_INR_SCC1	7	/* SCC (Z85C30) serial #1 */
+#define KN03_IO_INR_SCC0	6	/* SCC (Z85C30) serial #0 */
+#define KN03_IO_INR_RTC		5	/* DS1287 RTC (?) */
+#define KN03_IO_INR_PSU		4	/* power supply unit warning */
+#define KN03_IO_INR_RES_3	3	/* unused */
+#define KN03_IO_INR_ASC_DATA	2	/* SCSI data ready (discouraged?) (?) */
+#define KN03_IO_INR_PBNC	1	/* HALT button debouncer */
+#define KN03_IO_INR_PBNO	0	/* ~HALT button debouncer */
+
 #endif /* __ASM_MIPS_DEC_KN03_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/kn05.h linux/include/asm-mips/dec/kn05.h
--- linux.orig/include/asm-mips/dec/kn05.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/dec/kn05.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,70 @@
+/*
+ *	include/asm-mips/dec/kn05.h
+ *
+ *	DECstation 5000/260 (4max+ or KN05) and DECsystem 5900-260
+ *	definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	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.
+ *
+ *	WARNING!  All this information is pure guesswork based on the
+ *	ROM.  It is provided here in hope it will give someone some
+ *	food for thought.  No documentation for the KN05 module has
+ *	been located so far.
+ */
+#ifndef __ASM_MIPS_DEC_KN05_H
+#define __ASM_MIPS_DEC_KN05_H
+
+#include <asm/dec/ioasic_addrs.h>
+
+/*
+ * The oncard MB (Memory Buffer) ASIC provides an additional address
+ * decoder.  Certain address ranges within the "high" 16 slots are
+ * passed to the I/O ASIC's decoder like with the KN03.  Others are
+ * handled locally.  "Low" slots are always passed.
+ */
+#define KN05_MB_ROM	(16*CHUNK_SIZE)		/* KN05 card ROM */
+#define KN05_IOCTL	(17*CHUNK_SIZE)		/* I/O ASIC */
+#define KN05_ESAR	(18*CHUNK_SIZE)		/* LANCE MAC address chip */
+#define KN05_LANCE	(19*CHUNK_SIZE)		/* LANCE Ethernet */
+#define KN05_MB_INT	(20*CHUNK_SIZE)		/* MB interrupt register? */
+#define KN05_MB_UNKN_0	(21*CHUNK_SIZE)		/* MB unknown register */
+#define KN05_MB_UNKN_1	(22*CHUNK_SIZE)		/* MB unknown register */
+#define KN05_MB_CSR	(23*CHUNK_SIZE)		/* MB control & status */
+#define KN05_RESERVED_0	(24*CHUNK_SIZE)		/* unused? */
+#define KN05_RESERVED_1	(25*CHUNK_SIZE)		/* unused? */
+#define KN05_RESERVED_2	(26*CHUNK_SIZE)		/* unused? */
+#define KN05_RESERVED_3	(27*CHUNK_SIZE)		/* unused? */
+#define KN05_SCSI	(28*CHUNK_SIZE)		/* ASC SCSI */
+#define KN05_RESERVED_4	(29*CHUNK_SIZE)		/* unused? */
+#define KN05_RESERVED_5	(30*CHUNK_SIZE)		/* unused? */
+#define KN05_RESERVED_6	(31*CHUNK_SIZE)		/* unused? */
+
+/*
+ * Bits for the MB interrupt (?) register.
+ * The register appears read-only.
+ */
+#define KN05_MB_INT_TC		(1<<0)		/* TURBOchannel? */
+#define KN05_MB_INT_RTC		(1<<1)		/* RTC? */
+
+/*
+ * Bits for the MB control & status register.
+ * Set to 0x00bf8001 on my system by the ROM.
+ */
+#define KN05_MB_CSR_PF		(1<<0)		/* ??? */
+#define KN05_MB_CSR_F		(1<<1)		/* ??? */
+#define KN05_MB_CSR_ECC		(0xff<<2)	/* ??? */
+#define KN05_MB_CSR_OD		(1<<10)		/* ??? */
+#define KN05_MB_CSR_CP		(1<<11)		/* ??? */
+#define KN05_MB_CSR_UNC		(1<<12)		/* ??? */
+#define KN05_MB_CSR_IM		(1<<13)		/* ??? */
+#define KN05_MB_CSR_NC		(1<<14)		/* ??? */
+#define KN05_MB_CSR_EE		(1<<15)		/* (bus) Exception Enable? */
+#define KN05_MB_CSR_MSK		(0x1f<<16)	/* ??? */
+#define KN05_MB_CSR_FW		(1<<21)		/* ??? */
+
+#endif /* __ASM_MIPS_DEC_KN05_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/kn230.h linux/include/asm-mips/dec/kn230.h
--- linux.orig/include/asm-mips/dec/kn230.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/dec/kn230.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,26 @@
+/*
+ *	include/asm-mips/dec/kn230.h
+ *
+ *	DECstation 5100 (MIPSmate or KN230) definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	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.
+ */
+#ifndef __ASM_MIPS_DEC_KN230_H 
+#define __ASM_MIPS_DEC_KN230_H 
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN230_CPU_INR_HALT	6	/* HALT button */
+#define KN230_CPU_INR_MEMORY	5	/* memory, I/O bus write errors */
+#define KN230_CPU_INR_RTC	4	/* DS1287 RTC */
+#define KN230_CPU_INR_SII	3	/* SII (DC7061) SCSI */
+#define KN230_CPU_INR_LANCE	3	/* LANCE (Am7990) Ethernet */
+#define KN230_CPU_INR_DZ11	2	/* DZ11 (DC7085) serial */
+
+#endif /* __ASM_MIPS_DEC_KN230_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dec/tcmodule.h linux/include/asm-mips/dec/tcmodule.h
--- linux.orig/include/asm-mips/dec/tcmodule.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/dec/tcmodule.h	2002-07-20 01:08:28.000000000 +0000
@@ -15,10 +15,11 @@
  *
  * Jan.1998 Harald Koerfgen
  */
-#ifndef __ASM_DEC_TCMOULE_H
-#define __ASM_DEC_TCMOULE_H
+#ifndef __ASM_DEC_TCMODULE_H
+#define __ASM_DEC_TCMODULE_H
  
 #define OLDCARD 0x3c0000
+#define NEWCARD 0x000000
 
 #define TC_ROM_WIDTH	0x3e0
 #define TC_ROM_STRIDE	0x3e4
@@ -35,4 +36,4 @@
 #define TC_FLAGS	0x470
 #define TC_ROM_OBJECTS	0x480
 
-#endif /* __ASM_DEC_TCMOULE_H */
+#endif /* __ASM_DEC_TCMODULE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/div64.h linux/include/asm-mips/div64.h
--- linux.orig/include/asm-mips/div64.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/div64.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,6 +1,4 @@
 /*
- * include/asm-mips/div64.h
- * 
  * Copyright (C) 2000  Maciej W. Rozycki
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -16,41 +14,38 @@
  * No traps on overflows for any of these...
  */
 
-#if (_MIPS_ISA == _MIPS_ISA_MIPS1 ) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS32)
-
 #define do_div64_32(res, high, low, base) ({ \
 	unsigned long __quot, __mod; \
-	unsigned long __cf, __tmp, __i; \
+	unsigned long __cf, __tmp, __tmp2, __i; \
 	\
 	__asm__(".set	push\n\t" \
 		".set	noat\n\t" \
 		".set	noreorder\n\t" \
+		"move	%2, $0\n\t" \
+		"move	%3, $0\n\t" \
 		"b	1f\n\t" \
-		" li	%4,0x21\n" \
+		" li	%4, 0x21\n" \
 		"0:\n\t" \
-		"sll	$1,%0,0x1\n\t" \
-		"srl	%3,%0,0x1f\n\t" \
-		"or	%0,$1,$2\n\t" \
-		"sll	%1,%1,0x1\n\t" \
-		"sll	%2,%2,0x1\n" \
+		"sll	$1, %0, 0x1\n\t" \
+		"srl	%3, %0, 0x1f\n\t" \
+		"or	%0, $1, %5\n\t" \
+		"sll	%1, %1, 0x1\n\t" \
+		"sll	%2, %2, 0x1\n" \
 		"1:\n\t" \
-		"bnez	%3,2f\n\t" \
-		"sltu	$2,%0,%z5\n\t" \
-		"bnez	$2,3f\n\t" \
+		"bnez	%3, 2f\n\t" \
+		"sltu	%5, %0, %z6\n\t" \
+		"bnez	%5, 3f\n\t" \
 		"2:\n\t" \
 		" addiu	%4,%4,-1\n\t" \
-		"subu	%0,%0,%z5\n\t" \
-		"addiu	%2,%2,1\n" \
+		"subu	%0, %0, %z6\n\t" \
+		"addiu	%2, %2, 1\n" \
 		"3:\n\t" \
-		"bnez	%4,0b\n\t" \
-		" srl	$2,%1,0x1f\n\t" \
+		"bnez	%4, 0b\n\t" \
+		" srl	%5, %1, 0x1f\n\t" \
 		".set	pop" \
 		: "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
-		  "=&r" (__i) \
-		: "Jr" (base), "0" (high), "1" (low), "2" (0), "3" (0) \
-		/* Aarrgh!  Ran out of gcc's limit on constraints... */ \
-		: "$1", "$2"); \
+		  "=&r" (__i), "=&r" (__tmp2) \
+		: "Jr" (base), "0" (high), "1" (low)); \
 	\
 	(res) = __quot; \
 	__mod; })
@@ -76,39 +71,4 @@
 	(n) = __quot; \
 	__mod; })
 
-#else
-
-#define do_div64_32(res, high, low, base) ({ \
-	unsigned long __quot, __mod, __r0; \
-	\
-	__asm__("dsll32	%2,%z3,0\n\t" \
-		"or	%2,%2,%z4\n\t" \
-		"ddivu	$0,%2,%z5" \
-		: "=h" (__mod), "=l" (__quot), "=&r" (__r0) \
-		: "Jr" (high), "Jr" (low), "Jr" (base)); \
-	\
-	(res) = __quot; \
-	__mod; })
-
-#define do_div(n, base) ({ \
-	unsigned long long __quot; \
-	unsigned long __mod, __r0; \
-	\
-	__quot = (n); \
-	\
-	__asm__("dsll32	%2,%M3,0\n\t" \
-		"or	%2,%2,%L3\n\t" \
-		"ddivu	$0,%2,%z4\n\t" \
-		"mflo	%L1\n\t" \
-		"dsra32	%M1,%L1,0\n\t" \
-		"dsll32	%L1,%L1,0\n\t" \
-		"dsra32	%L1,%L1,0" \
-		: "=h" (__mod), "=r" (__quot), "=&r" (__r0) \
-		: "r" (n), "Jr" (base)); \
-	\
-	(n) = __quot; \
-	__mod; })
-
-#endif
-
 #endif /* _ASM_DIV64_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/dma.h linux/include/asm-mips/dma.h
--- linux.orig/include/asm-mips/dma.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/dma.h	2002-07-20 01:08:21.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: dma.h,v 1.6 1999/12/30 14:22:47 raiko Exp $
+/*
  * linux/include/asm/dma.h: Defines for using and allocating dma channels.
  * Written by Hennus Bergman, 1992.
  * High DMA channel support & info by Hannu Savolainen
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ds1286.h linux/include/asm-mips/ds1286.h
--- linux.orig/include/asm-mips/ds1286.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/ds1286.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: ds1286.h,v 1.1 1998/07/10 01:14:55 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/elf.h linux/include/asm-mips/elf.h
--- linux.orig/include/asm-mips/elf.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/elf.h	2002-07-20 01:08:34.000000000 +0000
@@ -10,6 +10,17 @@
 #define ELF_NGREG	45
 #define ELF_NFPREG	33
 
+/* ELF header e_flags defines. MIPS architecture level. */
+#define EF_MIPS_ARCH_1      0x00000000  /* -mips1 code.  */
+#define EF_MIPS_ARCH_2      0x10000000  /* -mips2 code.  */
+#define EF_MIPS_ARCH_3      0x20000000  /* -mips3 code.  */
+#define EF_MIPS_ARCH_4      0x30000000  /* -mips4 code.  */
+#define EF_MIPS_ARCH_5      0x40000000  /* -mips5 code.  */
+#define EF_MIPS_ARCH_32     0x60000000  /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64     0x70000000  /* MIPS64 code.  */
+#define EF_MIPS_ARCH_32R2   0x80000000  /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64R2   0x90000000  /* MIPS64 code.  */
+
 typedef unsigned long elf_greg_t;
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
@@ -17,8 +28,7 @@
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
 /*
- * This is used to ensure we don't load something for the wrong architecture
- * and also rejects IRIX binaries.
+ * This is used to ensure we don't load something for the wrong architecture.
  */
 #define elf_check_arch(hdr)						\
 ({									\
@@ -27,7 +37,10 @@
 									\
 	if (__h->e_machine != EM_MIPS)					\
 		__res = 0;						\
-	if (__h->e_flags & EF_MIPS_ARCH)				\
+	if (((__h->e_flags & EF_MIPS_ARCH) != EF_MIPS_ARCH_1) &&       	\
+	    ((__h->e_flags & EF_MIPS_ARCH) != EF_MIPS_ARCH_2) &&       	\
+	    ((__h->e_flags & EF_MIPS_ARCH) != EF_MIPS_ARCH_32) &&      	\
+	    ((__h->e_flags & EF_MIPS_ARCH) != EF_MIPS_ARCH_32R2))      	\
 		__res = 0;						\
 									\
 	__res;								\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/errno.h linux/include/asm-mips/errno.h
--- linux.orig/include/asm-mips/errno.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/errno.h	2002-07-20 01:08:22.000000000 +0000
@@ -17,7 +17,7 @@
 #define	EINTR		 4	/* Interrupted system call */
 #define	EIO		 5	/* I/O error */
 #define	ENXIO		 6	/* No such device or address */
-#define	E2BIG		 7	/* Arg list too long */
+#define	E2BIG		 7	/* Argument list too long */
 #define	ENOEXEC		 8	/* Exec format error */
 #define	EBADF		 9	/* Bad file number */
 #define	ECHILD		10	/* No child processes */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/fcntl.h linux/include/asm-mips/fcntl.h
--- linux.orig/include/asm-mips/fcntl.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/fcntl.h	2002-07-20 01:08:29.000000000 +0000
@@ -22,8 +22,8 @@
 #define O_EXCL		0x0400	/* not fcntl */
 #define O_NOCTTY	0x0800	/* not fcntl */
 #define FASYNC		0x1000	/* fcntl, for BSD compatibility */
-#define O_LARGEFILE	0x2000	/* allow large file opens - currently ignored */
-#define O_DIRECT	0x8000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0x2000	/* allow large file opens */
+#define O_DIRECT	0x8000	/* direct disk access hint */
 #define O_DIRECTORY	0x10000	/* must be a directory */
 #define O_NOFOLLOW	0x20000	/* don't follow links */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/fixmap.h linux/include/asm-mips/fixmap.h
--- linux.orig/include/asm-mips/fixmap.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/fixmap.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,104 @@
+/*
+ * fixmap.h: compile-time virtual memory allocation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Ingo Molnar
+ *
+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ */
+
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <asm/page.h>
+#ifdef CONFIG_HIGHMEM
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
+#endif
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special  addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * highger than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+
+/*
+ * on UP currently we will have no trace of the fixmap mechanizm,
+ * no page table allocations, etc. This might change in the
+ * future, say framebuffers for the console driver(s) could be
+ * fix-mapped?
+ */
+enum fixed_addresses {
+#ifdef CONFIG_HIGHMEM
+	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
+	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#endif
+	__end_of_fixed_addresses
+};
+
+extern void __set_fixmap (enum fixed_addresses idx,
+					unsigned long phys, pgprot_t flags);
+
+#define set_fixmap(idx, phys) \
+		__set_fixmap(idx, phys, PAGE_KERNEL)
+/*
+ * Some hardware wants to get fixmapped without caching.
+ */
+#define set_fixmap_nocache(idx, phys) \
+		__set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
+/*
+ * used by vmalloc.c.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap, and leave one page empty
+ * at the top of mem..
+ */
+#define FIXADDR_TOP	(0xffffe000UL)
+#define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
+
+#define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+	/*
+	 * this branch gets completely eliminated after inlining,
+	 * except when someone tries to use fixaddr indices in an
+	 * illegal way. (such as mixing up address types or using
+	 * out-of-range indices).
+	 *
+	 * If it doesn't get removed, the linker will complain
+	 * loudly with a reasonably clear error message..
+	 */
+	if (idx >= __end_of_fixed_addresses)
+		__this_fixmap_does_not_exist();
+
+        return __fix_to_virt(idx);
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/floppy.h linux/include/asm-mips/floppy.h
--- linux.orig/include/asm-mips/floppy.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-mips/floppy.h	2002-07-20 01:08:22.000000000 +0000
@@ -10,10 +10,6 @@
 #ifndef _ASM_FLOPPY_H
 #define _ASM_FLOPPY_H
 
-#include <asm/bootinfo.h>
-#include <asm/jazz.h>
-#include <asm/jazzdma.h>
-
 struct fd_ops {
 	unsigned char (*fd_inb)(unsigned int port);
 	void (*fd_outb)(unsigned char value, unsigned int port);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/fp.h linux/include/asm-mips/fp.h
--- linux.orig/include/asm-mips/fp.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/fp.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,34 +0,0 @@
-/* $Id: fp.h,v 1.1 1998/07/16 19:10:04 ralf Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1998 by Ralf Baechle
- */
-
-/*
- * Activate and deactive the floatingpoint accelerator.
- */
-#define enable_cp1()							\
-	__asm__ __volatile__(						\
-		".set\tpush\n\t"					\
-		".set\tnoat\n\t"					\
-		".set\treorder\n\t"					\
-		"mfc0\t$1,$12\n\t"					\
-		"or\t$1,%0\n\t"						\
-		"mtc0\t$1,$12\n\t"					\
-		".set\tpop"						\
-		: : "r" (ST0_CU1));
-
-#define disable_cp1()							\
-	__asm__ __volatile__(						\
-		".set\tpush\n\t"					\
-		".set\tnoat\n\t"					\
-		".set\treorder\n\t"					\
-		"mfc0\t$1,$12\n\t"					\
-		"or\t$1,%0\n\t"						\
-		"xor\t$1,%0\n\t"					\
-		"mtc0\t$1,$12\n\t"					\
-		".set\tpop"						\
-		: : "r" (ST0_CU1));
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/fpu_emulator.h linux/include/asm-mips/fpu_emulator.h
--- linux.orig/include/asm-mips/fpu_emulator.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/fpu_emulator.h	2002-07-20 01:08:37.000000000 +0000
@@ -1,15 +1,4 @@
 /*
- * Definitiona for the Algorithmics FPU Emulator port into MIPS Linux
- */
-/**************************************************************************
- *
- *  include/asm-mips/fpu_emulator.h
- *
- *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
  *  published by the Free Software Foundation.
@@ -23,13 +12,16 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
- *************************************************************************/
-/* 
  * Further private data for which no space exists in mips_fpu_soft_struct.
  * This should be subsumed into the mips_fpu_soft_struct structure as
  * defined in processor.h as soon as the absurd wired absolute assembler
  * offsets become dynamic at compile time.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  */
+#ifndef _ASM_FPU_EMULATOR_H
+#define _ASM_FPU_EMULATOR_H
 
 struct mips_fpu_emulator_private {
 	unsigned int eir;
@@ -42,3 +34,5 @@
 		unsigned int errors;
 	} stats;
 };
+
+#endif /* _ASM_FPU_EMULATOR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/ev64120.h linux/include/asm-mips/galileo-boards/ev64120.h
--- linux.orig/include/asm-mips/galileo-boards/ev64120.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/ev64120.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,59 @@
+/*
+ *  This is a direct copy of the ev96100.h file, with a global
+ * search and replace.  The numbers are the same.
+ *
+ *  The reason I'm duplicating this is so that the 64120/96100
+ * defines won't be confusing in the source code.
+ */
+#ifndef _MIPS_EV64120_H
+#define _MIPS_EV64120_H
+
+#include <asm/addrspace.h>
+
+/*
+ *   GT64120 config space base address
+ */
+#define GT64120_BASE    (KSEG1ADDR(0x14000000))
+#define MIPS_GT_BASE    GT64120_BASE
+ 
+/*
+ *   PCI Bus allocation
+ */
+#define GT_PCI_MEM_BASE    0x12000000
+#define GT_PCI_MEM_SIZE    0x02000000
+#define GT_PCI_IO_BASE     0x10000000
+#define GT_PCI_IO_SIZE     0x02000000
+#define GT_ISA_IO_BASE     PCI_IO_BASE          
+
+/*
+ *   Duart I/O ports.
+ */
+#define EV64120_COM1_BASE_ADDR  (0x1d000000 + 0x20) 
+#define EV64120_COM2_BASE_ADDR  (0x1d000000 + 0x00)
+
+
+/*
+ *   EV64120 interrupt controller register base.
+ */
+#define EV64120_ICTRL_REGS_BASE   (KSEG1ADDR(0x1f000000))
+
+/*
+ *   EV64120 UART register base.
+ */
+#define EV64120_UART0_REGS_BASE    (KSEG1ADDR(EV64120_COM1_BASE_ADDR))
+#define EV64120_UART1_REGS_BASE    (KSEG1ADDR(EV64120_COM2_BASE_ADDR))
+#define EV64120_BASE_BAUD ( 3686400 / 16 )
+
+
+/*
+ * Because of an error/peculiarity in the Galileo chip, we need to swap the 
+ * bytes when running bigendian.
+ */
+
+#define GT_WRITE(ofs, data)  \
+             *(volatile u32 *)(MIPS_GT_BASE+ofs) = cpu_to_le32(data)
+#define GT_READ(ofs, data)   \
+             *data = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+ofs))
+    
+
+#endif /* !(_MIPS_EV64120_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/ev64120int.h linux/include/asm-mips/galileo-boards/ev64120int.h
--- linux.orig/include/asm-mips/galileo-boards/ev64120int.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/ev64120int.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,36 @@
+#ifndef IRQ_HANDLER_
+#define IRQ_HANDLER_
+
+#define INT_CAUSE_MAIN 0
+#define INT_CAUSE_HIGH 1
+
+#define MAX_CAUSE_REGS 4
+#define MAX_CAUSE_REG_WIDTH 32
+
+void hook_irq_handler (int int_cause , int bit_num , void *isr_ptr);
+int disable_galileo_irq (int int_cause , int bit_num);
+int enable_galileo_irq (int int_cause , int bit_num);
+
+extern struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
+
+/*
+  PCI interrupts will come in on either the INTA or
+  INTD interrups lines, which are mapped to the #2 and
+  #5 interrupt pins of the MIPS.  On our boards, they
+  all either come in on IntD or they all come in on
+  IntA, they aren't mixed. There can be numerous PCI
+  interrupts, so we keep a list of the "requested"
+  interrupt numbers and go through the list whenever
+  we get an IntA/D.
+
+  All PCI interrupts have numbers >= 20 by arbitrary convention.  Any
+  interrupt < 8 is an interrupt that is maskable on the
+  MIPS.
+*/
+
+#define TIMER 4
+#define INTA 2
+#define INTD 5
+
+
+#endif /* IRQ_HANDLER_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/ev96100.h linux/include/asm-mips/galileo-boards/ev96100.h
--- linux.orig/include/asm-mips/galileo-boards/ev96100.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/ev96100.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,55 @@
+/*
+ *
+ */
+#ifndef _MIPS_EV96100_H
+#define _MIPS_EV96100_H
+
+#include <asm/addrspace.h>
+
+/*
+ *   GT64120 config space base address
+ */
+#define GT64120_BASE    (KSEG1ADDR(0x14000000))
+#define MIPS_GT_BASE    GT64120_BASE
+ 
+/*
+ *   PCI Bus allocation
+ */
+#define GT_PCI_MEM_BASE    0x12000000
+#define GT_PCI_MEM_SIZE    0x02000000
+#define GT_PCI_IO_BASE     0x10000000
+#define GT_PCI_IO_SIZE     0x02000000
+#define GT_ISA_IO_BASE     PCI_IO_BASE          
+
+/*
+ *   Duart I/O ports.
+ */
+#define EV96100_COM1_BASE_ADDR  (0xBD000000 + 0x20) 
+#define EV96100_COM2_BASE_ADDR  (0xBD000000 + 0x00)
+
+
+/*
+ *   EV96100 interrupt controller register base.
+ */
+#define EV96100_ICTRL_REGS_BASE   (KSEG1ADDR(0x1f000000))
+
+/*
+ *   EV96100 UART register base.
+ */
+#define EV96100_UART0_REGS_BASE    EV96100_COM1_BASE_ADDR
+#define EV96100_UART1_REGS_BASE    EV96100_COM2_BASE_ADDR
+#define EV96100_BASE_BAUD ( 3686400 / 16 )
+
+
+/*
+ * Because of an error/peculiarity in the Galileo chip, we need to swap the 
+ * bytes when running bigendian.
+ */
+
+#define GT_WRITE(ofs, data)  \
+             *(volatile u32 *)(MIPS_GT_BASE+ofs) = cpu_to_le32(data)
+#define GT_READ(ofs, data)   \
+             data = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+ofs))
+    
+
+#endif /* !(_MIPS_EV96100_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/ev96100int.h linux/include/asm-mips/galileo-boards/ev96100int.h
--- linux.orig/include/asm-mips/galileo-boards/ev96100int.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/ev96100int.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,12 @@
+/*
+ *
+ */
+#ifndef _MIPS_EV96100INT_H
+#define _MIPS_EV96100INT_H
+
+#define EV96100INT_UART_0    6     /* IP 6 */     
+#define EV96100INT_TIMER     7     /* IP 7 */
+
+extern void ev96100int_init(void);
+
+#endif /* !(_MIPS_EV96100_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/evb64120A/cntmr.h linux/include/asm-mips/galileo-boards/evb64120A/cntmr.h
--- linux.orig/include/asm-mips/galileo-boards/evb64120A/cntmr.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/evb64120A/cntmr.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,42 @@
+/* cntmr.h - Timer/Counter interface header file */
+
+/* Copyright - Galileo technology */
+
+#ifndef __INCtimerCounterDrvh 
+#define __INCtimerCounterDrvh
+
+/* includes */
+
+#include "core.h"
+
+/* defines */
+
+#define FIRST_CNTMR   0
+#define LAST_CNTMR    3
+
+#define CNTMR0_READ(pData)\
+        GT_REG_READ(CNTMR0, pData)
+
+#define CNTMR1_READ(pData)\
+        GT_REG_READ(CNTMR1, pData)
+
+#define CNTMR2_READ(pData)\
+        GT_REG_READ(CNTMR2, pData)
+
+#define CNTMR3_READ(pData)\
+        GT_REG_READ(CNTMR3, pData)
+
+/* typedefs */
+
+typedef enum counterTimer{CNTMR_0,CNTMR_1,CNTMR_2,CNTMR_3} CNTMR_NUM;
+typedef enum cntTmrOpModes{COUNTER, TIMER} CNT_TMR_OP_MODES;
+
+bool    cntTmrLoad(unsigned int countNum, unsigned int value);	
+bool    cntTmrSetMode(CNTMR_NUM countNum, CNT_TMR_OP_MODES opMode);
+bool    cntTmrEnable(CNTMR_NUM countNum);  
+bool    cntTmrStart (CNTMR_NUM countNum,unsigned int countValue,
+                   CNT_TMR_OP_MODES opMode);
+unsigned int    cntTmrDisable(CNTMR_NUM countNum);              
+unsigned int    cntTmrRead(CNTMR_NUM countNum);
+
+#endif /* __INCtimerCounterDrvh */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/evb64120A/core.h linux/include/asm-mips/galileo-boards/evb64120A/core.h
--- linux.orig/include/asm-mips/galileo-boards/evb64120A/core.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/evb64120A/core.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,182 @@
+/*
+ * This header file contains simple Read/Write macros for addressing the SDRAM,
+ * devices, GT`s internal registers and PCI (using the PCI`s address space).
+ *
+ * Copyright Galileo Technology.
+ */
+#ifndef __INCcoreh 
+#define __INCcoreh
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/gt64120.h>
+
+#define INTERNAL_REG_BASE_ADDR 0x14000000
+
+#define NO_BIT          0x00000000
+#define BIT0            0x00000001
+#define BIT1            0x00000002
+#define BIT2            0x00000004
+#define BIT3            0x00000008
+#define BIT4            0x00000010
+#define BIT5            0x00000020
+#define BIT6            0x00000040
+#define BIT7            0x00000080
+#define BIT8            0x00000100
+#define BIT9            0x00000200
+#define BIT10           0x00000400
+#define BIT11           0x00000800
+#define BIT12           0x00001000
+#define BIT13           0x00002000
+#define BIT14           0x00004000
+#define BIT15           0x00008000
+#define BIT16           0x00010000
+#define BIT17           0x00020000
+#define BIT18           0x00040000
+#define BIT19           0x00080000
+#define BIT20           0x00100000
+#define BIT21           0x00200000
+#define BIT22           0x00400000
+#define BIT23           0x00800000
+#define BIT24           0x01000000
+#define BIT25           0x02000000
+#define BIT26           0x04000000
+#define BIT27           0x08000000
+#define BIT28           0x10000000
+#define BIT29           0x20000000
+#define BIT30           0x40000000
+#define BIT31           0x80000000
+
+#define _1K             0x00000400
+#define _2K             0x00000800
+#define _4K             0x00001000
+#define _8K             0x00002000
+#define _16K            0x00004000
+#define _32K            0x00008000
+#define _64K            0x00010000
+#define _128K           0x00020000
+#define _256K           0x00040000
+#define _512K           0x00080000
+
+#define _1M             0x00100000
+#define _2M             0x00200000
+#define _3M             0x00300000
+#define _4M             0x00400000
+#define _5M             0x00500000
+#define _6M             0x00600000
+#define _7M             0x00700000
+#define _8M             0x00800000
+#define _9M             0x00900000
+#define _10M            0x00a00000
+#define _11M            0x00b00000
+#define _12M            0x00c00000
+#define _13M            0x00d00000
+#define _14M            0x00e00000
+#define _15M            0x00f00000
+#define _16M            0x01000000
+
+typedef enum _bool{false,true} bool;
+
+#ifndef NULL
+#define NULL 0                                  
+#endif
+
+/* The two following defines are according to MIPS architecture. */
+#define NONE_CACHEABLE			0xa0000000
+#define MIPS_CACHEABLE			0x80000000
+
+/* Read/Write to/from GT`s internal registers */
+#define GT_REG_READ(offset, pData)					\
+do {									\
+	*pData = (*((u32 *)(NONE_CACHEABLE |				\
+		INTERNAL_REG_BASE_ADDR | (offset))));			\
+	*pData = cpu_to_le32(*pData);					\
+} while(0)
+
+#define GT_REG_WRITE(offset, data)					\
+	(*((u32 *)(NONE_CACHEABLE | INTERNAL_REG_BASE_ADDR |		\
+		(offset))) = cpu_to_le32(data))
+
+#define VIRTUAL_TO_PHY(y)	((u32)(y) & (u32)0x5fffffff)
+#define PHY_TO_VIRTUAL(y)	((u32)(y) | NONE_CACHEABLE)
+
+/* Write 32/16/8 bit Non-Cache-able */
+#define WRITE_CHAR(address, data)					\
+	(*((u8 *)((address) | NONE_CACHEABLE)) = (data))
+#define WRITE_SHORT(address, data)					\
+	(*((u16 *)((address) | NONE_CACHEABLE)) = (u16) data)
+#define WRITE_WORD(address, data)					\
+	(*((u32 *)((address) | NONE_CACHEABLE)) = (u32) data)
+
+/* Write 32/16/8 bits Cacheable */
+#define WRITE_CHAR_CACHEABLE(address, data)				\
+	(*((u8 *)((address) | MIPS_CACHEABLE)) = (data))
+                
+#define WRITE_SHORT_CACHEABLE(address, data)				\
+	(*((u16 *)((address) | MIPS_CACHEABLE)) = (u16) data)
+
+#define WRITE_WORD_CACHEABLE(address, data)				\
+	(*((u32 *)((address) | MIPS_CACHEABLE )) = (u32) data)
+
+/* Read 32/16/8 bits NonCacheable - returns data in variable. */
+#define READ_CHAR(address,pData)					\
+	(*(pData) = *((u8 *)((address) | NONE_CACHEABLE)))
+
+#define READ_SHORT(address,pData)					\
+	(*(pData) = *((u16 *)((address) | NONE_CACHEABLE)))
+
+#define READ_WORD(address,pData)					\
+	(*(pData) = *((u32 *)((address) | NONE_CACHEABLE)))
+
+/* Read 32/16/8 bit NonCacheable - returns data direct. */
+#define READCHAR(address)						\
+	(*((u8 *)((address) | NONE_CACHEABLE)))
+
+#define READSHORT(address)						\
+	(*((u16 *)((address) | NONE_CACHEABLE)))
+
+#define READWORD(address)						\
+        (*((u32 *)((address) | NONE_CACHEABLE)))
+
+/* Read 32/16/8 bit Cacheable - returns data in variable. */
+#define READ_CHAR_CACHEABLE(address,pData)				\
+        (*(pData) = *((u8 *)((address) | MIPS_CACHEABLE)))
+
+#define READ_SHORT_CACHEABLE(address,pData)				\
+        (*(pData) = *((u16 *)((address) | MIPS_CACHEABLE)))
+#define READ_WORD_CACHEABLE(address,pData)				\
+        (*(pData) = *((u32 *)((address) | MIPS_CACHEABLE)))
+
+/* Read 32/16/8 bit Cacheable - returns data direct. */
+#define READCHAR_CACHEABLE(address)					\
+	(*((u8 *)((address) | MIPS_CACHEABLE)))
+
+#define READSHORT_CACHEABLE(address)					\
+	(*((u16 *)((address) | MIPS_CACHEABLE)))
+
+#define READWORD_CACHEABLE(address)					\
+	(*((u32 *)((address) | MIPS_CACHEABLE)))
+
+/*
+ * SET_REG_BITS(regOffset,bits) - 
+ * gets register offset and bits: a 32bit value. It set to logic '1' in the  
+ * internal register the bits which given as an input example:
+ * SET_REG_BITS(0x840,BIT3 | BIT24 | BIT30) - set bits: 3,24 and 30 to logic
+ * '1' in register 0x840 while the other bits stays as is.
+ */
+#define SET_REG_BITS(regOffset,bits)					\
+	(*(u32*)(NONE_CACHEABLE | INTERNAL_REG_BASE_ADDR |		\
+		(regOffset)) |= (u32)cpu_to_le32(bits))
+
+/*
+ * RESET_REG_BITS(regOffset,bits) -
+ * gets register offset and bits: a 32bit value. It set to logic '0' in the  
+ * internal register the bits which given as an input example:
+ * RESET_REG_BITS(0x840,BIT3 | BIT24 | BIT30) - set bits: 3,24 and 30 to logic
+ * '0' in register 0x840 while the other bits stays as is.
+ */
+#define RESET_REG_BITS(regOffset,bits)					\
+	(*(u32 *)(NONE_CACHEABLE | INTERNAL_REG_BASE_ADDR |		\
+		(regOffset)) &= ~((u32)cpu_to_le32(bits)))
+
+#endif /* __INCcoreh */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/evb64120A/dma.h linux/include/asm-mips/galileo-boards/evb64120A/dma.h
--- linux.orig/include/asm-mips/galileo-boards/evb64120A/dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/evb64120A/dma.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,80 @@
+/* DMA.h - DMA functions and definitions*/
+
+/* Copyright Galileo Technology. */
+
+#ifndef __INCdmah 
+#define __INCdmah
+
+/* includes */
+
+#include "core.h"
+
+/* defines */
+
+#define FIRST_DMA_ENGINE   0
+#define LAST_DMA_ENGINE    3
+
+#define FLY_BY						BIT0
+#define RD_WR_FLY					BIT1
+#define DECREMENT_SOURCE_ADDRESS	BIT2
+#define HOLD_SOURCE_ADDRESS			BIT3
+#define DECREMENT_DEST_ADDRESS		BIT4
+#define HOLD_DEST_ADDRESS			BIT5
+#define DTL_1BYTE					BIT6 | BIT8
+#define DTL_2BYTES					BIT7 | BIT8
+#define DTL_4BYTES					BIT7
+#define DTL_8BYTES					NO_BIT
+#define DTL_16BYTES					BIT6
+#define DTL_32BYTES					BIT6 | BIT7
+#define DTL_64BYTES					BIT6 | BIT7 | BIT8
+#define NON_CHAIN_MOD				BIT9
+#define INT_EVERY_NULL_POINTER		BIT10
+#define BLOCK_TRANSFER_MODE			BIT11
+#define CHANNEL_ENABLE				BIT12
+#define FETCH_NEXT_RECORED			BIT13
+#define DMA_ACTIVITY_STATUS         BIT14
+#define ALIGN_TOWARD_DEST			BIT15
+#define MASK_DMA_REQ				BIT16
+#define ENABLE_DESCRIPTOR			BIT17
+#define ENABLE_EOT					BIT18
+#define ENABLE_EOT_INTERRUPT		BIT19
+#define ABORT_DMA					BIT20
+#define SOURCE_ADDR_IN_PCI0			BIT21
+#define SOURCE_ADDR_IN_PCI1			BIT22
+#define DEST_ADDR_IN_PCI0			BIT23
+#define DEST_ADDR_IN_PCI1			BIT24
+#define REC_ADDR_IN_PCI0			BIT25
+#define REC_ADDR_IN_PCI1			BIT26
+#define REQ_FROM_TIMER_COUNTER		BIT28
+
+/* typedefs */
+
+typedef enum dmaEngine{DMA_ENG_0,DMA_ENG_1,DMA_ENG_2,DMA_ENG_3} DMA_ENGINE;
+
+/* priority definitions */
+typedef enum prioChan01{ROUND_ROBIN01,CH_1,CH_0} PRIO_CHAN_0_1;
+typedef enum prioChan23{ROUND_ROBIN23,CH_3,CH_2} PRIO_CHAN_2_3;
+typedef enum prioGroup{ROUND_ROBIN,CH_2_3,CH_0_1} PRIO_GROUP;
+typedef enum prioOpt{RETURN_BUS,KEEP_BUS} PRIO_OPT; 
+
+typedef struct dmaRecored
+{
+    unsigned int    ByteCnt;                                            
+    unsigned int    SrcAdd;
+    unsigned int    DestAdd;
+    unsigned int    NextRecPtr;
+} DMA_RECORED;
+
+typedef enum __dma_status{CHANNEL_BUSY,NO_SUCH_CHANNEL,DMA_OK,
+                            GENERAL_ERROR} DMA_STATUS;
+
+DMA_STATUS dmaTransfer (DMA_ENGINE engine,unsigned int sourceAddr,
+                        unsigned int destAddr,unsigned int numOfBytes,
+                        unsigned int command,DMA_RECORED * nextRecoredPointer);
+bool	dmaCommand (DMA_ENGINE channel,unsigned int command);
+bool    isDmaChannelActive (DMA_ENGINE channel);
+
+bool    changeDmaPriority(PRIO_CHAN_0_1 prio_01, PRIO_CHAN_2_3 prio_23, 
+                          PRIO_GROUP prioGrp, PRIO_OPT prioOpt);
+
+#endif /* __INCdmah */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/evb64120A/eeprom_param.h linux/include/asm-mips/galileo-boards/evb64120A/eeprom_param.h
--- linux.orig/include/asm-mips/galileo-boards/evb64120A/eeprom_param.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/evb64120A/eeprom_param.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,53 @@
+#ifndef EEPROM_PARAM_
+#define EEPROM_PARAM_
+#define SDRAM_REGS 0xbf000000
+
+unsigned int galileo_dl(void);
+void (*boot_addr)(int argc, char **argv, char **envp);
+
+#define NETWORK_BT_BIN 0
+#define FLASH_BT 1
+#define SERIAL_BT 2
+#define NETWORK_BT_SREC 3
+
+#define LINUX_OS 0
+#define OTHER_OS 1
+
+/********************************************************************
+ *eeprom_parameters -
+ *
+ *This structure holds the eeprom parameters (usually stored on flash
+ *memory)
+ *The structure is all stored in flash memory except memory_size which
+ *is probed each boot time for the real size of memory on the
+ *evaluation board.
+ *
+ *The structure also holds information that is not used by all
+ *evaluation board, such as the eth?_mac, which holds the MAC addresses
+ *of the built in ethernet ports in the EVB96100 for example, but is
+ *never used by EVB64120A.
+ *
+ *********************************************************************/
+
+struct eeprom_parameters {
+  unsigned int boot_source;
+  unsigned int operating_system;
+  
+  /* network loader parametrs */
+  unsigned int host_ip;
+  unsigned int server_ip;
+  char bootimage[64];
+  
+  /* Board parameters */
+  char eth0_mac[6];
+  char eth1_mac[6];
+  char eth2_mac[6];
+  char eth3_mac[6];
+
+  /* Command Line (usually needed for Linux) */
+  char os_command_line[256];
+  unsigned int entry_point;
+  unsigned memory_size;
+};
+
+#endif /* EEPROM_PARAM_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/evb64120A/flashdrv.h linux/include/asm-mips/galileo-boards/evb64120A/flashdrv.h
--- linux.orig/include/asm-mips/galileo-boards/evb64120A/flashdrv.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/evb64120A/flashdrv.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,81 @@
+/* flashdrv.h - FLASH memory interface header file */
+
+/* Copyright Galileo Technology. */
+
+#ifndef __INCflashdrvh 
+#define __INCflashdrvh
+
+/* includes */
+
+#include "core.h"
+
+/* defines */
+
+/* Supported Flash Manufactures */ 
+
+#define AMD_FLASH       0x01
+#define ST_FLASH        0x20
+#define INTEL_FLASH     0x89
+#define MICRON_FLASH    0x89
+
+/* Supported Flash Devices */
+
+/* AMD Devices */
+#define AM29F400BT      0x2223    
+#define AM29F400BB      0x22AB
+#define AM29LV800BT     0x22DA
+#define AM29LV400BT     0x22B9
+#define AM29LV400BB     0x22BA
+#define AM29LV040B      0x4f
+/* ST Devices */
+#define M29W040         0xE3
+/* INTEL Devices - We have added I before the name defintion.*/
+#define I28F320J3A      0x16
+#define I28F640J3A      0x17
+#define I28F128J3A      0x18
+#define I28F320B3_B     0x8897
+#define I28F320B3_T     0x8896 
+#define I28F160B3_B     0x8891
+#define I28F160B3_T     0x8890
+
+#define POINTER_TO_FLASH           flashParametrs[0] 
+#define FLASH_BASE_ADDRESS         flashParametrs[1] 
+#define FLASH_WIDTH                flashParametrs[2] /* In Bytes */
+#define FLASH_MODE                 flashParametrs[3] /* In bits  */
+#define MANUFACTOR_ID              POINTER_TO_FLASH + 0
+#define VENDOR_ID                  POINTER_TO_FLASH + 1
+#define NUMBER_OF_SECTORS          POINTER_TO_FLASH + 2
+#define FIRST_SECTOR_SIZE          POINTER_TO_FLASH + 3
+#define NUM_OF_DEVICES             FLASH_WIDTH / (FLASH_MODE / 8)
+ 
+/* typedefs */
+
+typedef enum _FlashMode {PURE8,X8 = 8,X16 = 16} FLASHmode;
+/* PURE8 - when using a flash device whice can be configurated only as  
+            8 bit device. */
+/* X8    - when using a flash device which is 16 bit wide but configured to
+           operate in 8 bit mode.*/
+/* X16   - when using a flash device which is 16 bit wide */
+
+bool    flashErase(void);
+bool    flashEraseSector(unsigned int sectorNumber);
+bool    flashWriteWord(unsigned int offset,unsigned int data);
+bool    flashWriteShort(unsigned int offset,unsigned short sdata);
+bool    flashWriteChar(unsigned int offset,unsigned char cdata);
+void    flashReset(void);
+unsigned int    flashInWhichSector(unsigned int offset);
+unsigned int    flashGetSectorSize(unsigned int sectorNumber);
+unsigned int    flashInit(unsigned int baseAddress,unsigned int flashWidth,
+                          FLASHmode FlashMode);
+unsigned int    flashGetNumOfSectors(void);
+unsigned int    flashGetSize(void);
+unsigned int    flashGetSectorOffset(unsigned int sectorNum);
+unsigned int    flashWriteBlock(unsigned int offset,unsigned int numOfByte,
+                        unsigned char * blockAddress);
+unsigned int    flashReadWord(unsigned int offset);
+unsigned char   flashReadChar(unsigned int offset);
+unsigned short  flashReadShort(unsigned int offset);
+unsigned int    flashReadBlock(unsigned int offset,unsigned int numOfByte,
+                               unsigned char * blockAddress);
+#endif /* __INCflashdrvh */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/evb64120A/i2o.h linux/include/asm-mips/galileo-boards/evb64120A/i2o.h
--- linux.orig/include/asm-mips/galileo-boards/evb64120A/i2o.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/evb64120A/i2o.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,61 @@
+/* i2o.h - Header file for the I2O`s interface */
+
+/* Copyright - Galileo technology. */
+
+#ifndef __INCi2oh
+#define __INCi2oh
+
+/* includes */            
+            
+#include "core.h"
+
+/* typedefs */           
+
+typedef enum _i2oMessageReg{MESSAGE_REG_0,MESSAGE_REG_1} I2O_MESSAGE_REG;
+typedef enum _cirQueSize{I20_16K = 0x1,I20_32K = 0x2,I20_64K = 0x4,\
+                  I20_128K = 0x8,I20_256K = 0xc} CIRCULAR_QUEUE_SIZE;
+
+/* Message handle Functions */
+unsigned int    getInBoundMassege(I2O_MESSAGE_REG messageRegNum);
+bool  sendOutBoundMassege(I2O_MESSAGE_REG messageRegNum,unsigned int message);
+bool  checkInBoundIntAndClear(I2O_MESSAGE_REG messageRegNum);
+bool  outBoundMessageAcknowledge(I2O_MESSAGE_REG messageRegNum);
+bool  maskInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum);
+bool  enableInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum);
+bool  maskOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum);
+bool  enableOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum);
+
+/* Doorbell handle Functions */
+unsigned int    readInBoundDoorBellInt(void);
+bool  initiateOutBoundDoorBellInt(unsigned int interruptBits);
+bool  clearInBoundDoorBellInt(unsigned int interruptBits);
+bool  isInBoundDoorBellInterruptSet(void);
+bool  isOutBoundDoorBellInterruptSet(void); /* For acknowledge */
+bool  maskInBoundDoorBellInterrupt(void);
+bool  enableInBoundDoorBellInterrupt(void);
+bool  maskOutBoundDoorBellInterrupt(void);
+bool  enableOutBoundDoorBellInterrupt(void);
+
+/* I2O - Circular Queues handle Functions */
+
+/* initialization */
+bool  circularQueueEnable(CIRCULAR_QUEUE_SIZE cirQueSize,
+                          unsigned int queueBaseAddr);
+
+/* Inbound Post Queue */
+unsigned int    inBoundPostQueuePop(void);
+bool    isInBoundPostQueueInterruptSet(void);
+bool  clearInBoundPostQueueInterrupt(void);
+void    maskInBoundPostQueueInterrupt(void);
+void    enableInBoundPostQueueInterrupt(void);
+/* Outbound Post Queue */
+bool  outBoundPostQueuePush(unsigned int data);
+bool    isOutBoundPostQueueEmpty(void);
+/* Inbound Free Queue */
+bool  inBoundFreeQueuePush(unsigned int data);
+bool    isInBoundFreeQueueEmpty(void);
+/* Outbound Free Queue */
+unsigned int    outBoundFreeQueuePop(void);
+
+#endif  /* __INCi2oh */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/evb64120A/memory.h linux/include/asm-mips/galileo-boards/evb64120A/memory.h
--- linux.orig/include/asm-mips/galileo-boards/evb64120A/memory.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/evb64120A/memory.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,57 @@
+/* Memory.h - Memory mappings and remapping functions declarations */
+
+/* Copyright - Galileo technology. */
+
+#ifndef __INCmemoryh
+#define __INCmemoryh
+
+/* includes */
+
+#include "core.h"
+
+/* defines */
+
+#define DONT_MODIFY     0xffffffff
+#define PARITY_SUPPORT  0x40000000
+
+#define _8BIT           0x00000000
+#define _16BIT          0x00010000
+#define _32BIT          0x00020000
+#define _64BIT          0x00030000
+
+/* typedefs */
+
+typedef enum __memBank{BANK0,BANK1,BANK2,BANK3} MEMORY_BANK;
+typedef enum __device{DEVICE0,DEVICE1,DEVICE2,DEVICE3,BOOT_DEVICE} DEVICE;
+
+
+unsigned int   getMemoryBankBaseAddress(MEMORY_BANK bank);
+unsigned int   getDeviceBaseAddress(DEVICE device);
+unsigned int   getMemoryBankSize(MEMORY_BANK bank);
+unsigned int   getDeviceSize(DEVICE device);
+unsigned int   getDeviceWidth(DEVICE device);
+
+bool mapMemoryBanks0and1(unsigned int bank0Base,unsigned int bank0Length,
+                         unsigned int bank1Base,unsigned int bank1Length);
+bool mapMemoryBanks2and3(unsigned int bank2Base,unsigned int bank2Length,
+                         unsigned int bank3Base,unsigned int bank3Length);
+bool mapDevices0_1and2MemorySpace(unsigned int device0Base,
+                                  unsigned int device0Length,
+                                  unsigned int device1Base,
+                                  unsigned int device1Length,
+                                  unsigned int device2Base,
+                                  unsigned int device2Length);
+bool mapDevices3andBootMemorySpace(unsigned int device3Base,
+                                   unsigned int device3Length,
+                                   unsigned int bootDeviceBase,
+                                   unsigned int bootDeviceLength);
+bool mapInternalRegistersMemorySpace(unsigned int internalRegBase);
+bool modifyDeviceParameters(DEVICE device,unsigned int TurnOff,
+                            unsigned int AccToFirst,unsigned int AccToNext,
+                            unsigned int ALEtoWr, unsigned int WrActive,
+                            unsigned int WrHigh,unsigned int Width,
+                            bool ParitySupport);
+
+bool remapAddress(unsigned int remapReg, unsigned int remapValue);
+#endif /* __INCmemoryh */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/evb64120A/pci.h linux/include/asm-mips/galileo-boards/evb64120A/pci.h
--- linux.orig/include/asm-mips/galileo-boards/evb64120A/pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/evb64120A/pci.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,165 @@
+/* PCI.h - PCI functions header file */
+
+/* Copyright - Galileo technology. */
+
+#ifndef  __INCpcih
+#define  __INCpcih
+
+/* includes */
+
+#include"core.h"
+
+/* defines */
+
+#define PCI0_MASTER_ENABLE(deviceNumber) pci0WriteConfigReg(                  \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,MASTER_ENABLE |                \
+          pci0ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI0_MASTER_DISABLE(deviceNumber) pci0WriteConfigReg(                 \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,~MASTER_ENABLE &               \
+          pci0ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI1_MASTER_ENABLE(deviceNumber) pci1WriteConfigReg(                  \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,MASTER_ENABLE |                \
+          pci1ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI1_MASTER_DISABLE(deviceNumber) pci1WriteConfigReg(                 \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,~MASTER_ENABLE &               \
+          pci1ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI0_MEMORY_ENABLE(deviceNumber) pci0WriteConfigReg(                  \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,MEMORY_ENABLE |                \
+          pci0ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )           
+
+#define PCI1_MEMORY_ENABLE(deviceNumber) pci1WriteConfigReg(                  \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,MEMORY_ENABLE |                \
+          pci1ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI0_IO_ENABLE(deviceNumber) pci0WriteConfigReg(                      \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,I_O_ENABLE |                   \
+          pci0ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI1_IO_ENABLE(deviceNumber) pci1WriteConfigReg(                      \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,I_O_ENABLE |                   \
+          pci1ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI0_SLAVE_ENABLE(deviceNumber) pci0WriteConfigReg(                   \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,MEMORY_ENABLE | I_O_ENABLE |   \
+          pci0ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI1_SLAVE_ENABLE(deviceNumber) pci1WriteConfigReg(                   \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,MEMORY_ENABLE | I_O_ENABLE |   \
+          pci1ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
+
+#define PCI0_DISABLE(deviceNumber) pci0WriteConfigReg(                        \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,0xfffffff8  &                  \
+          pci0ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber))
+
+#define PCI1_DISABLE(deviceNumber) pci1WriteConfigReg(                        \
+          PCI_0STATUS_AND_COMMAND,deviceNumber,0xfffffff8  &                  \
+          pci1ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber))
+
+#define 	MASTER_ENABLE			BIT2  
+#define		MEMORY_ENABLE			BIT1  
+#define		I_O_ENABLE  			BIT0  
+#define     SELF                    0
+/* Agent on the PCI bus may have up to 6 BARS. */
+#define     BAR0                    0x10
+#define     BAR1                    0x14
+#define     BAR2                    0x18
+#define     BAR3                    0x1c
+#define     BAR4                    0x20
+#define     BAR5                    0x24
+   
+
+/* typedefs */
+
+typedef struct pciDevice
+{
+    char            type[20];
+    unsigned int    deviceNum;
+    unsigned int    venID;                                            
+    unsigned int    deviceID;
+    unsigned int    bar0Base;
+    unsigned int    bar0Size;
+    unsigned int    bar0Type;
+    unsigned int    bar1Base;
+    unsigned int    bar1Size;
+    unsigned int    bar1Type;
+    unsigned int    bar2Base;
+    unsigned int    bar2Size;
+    unsigned int    bar2Type;
+    unsigned int    bar3Base;
+    unsigned int    bar3Size;
+    unsigned int    bar3Type;
+    unsigned int    bar4Base;
+    unsigned int    bar4Size;
+    unsigned int    bar4Type;
+    unsigned int    bar5Base;
+    unsigned int    bar5Size;
+    unsigned int    bar5Type;
+} PCI_DEVICE;
+
+void    pci0WriteConfigReg(unsigned int regOffset,unsigned int pciDevNum,
+                           unsigned int data);
+void    pci1WriteConfigReg(unsigned int regOffset,unsigned int pciDevNum,
+                           unsigned int data);
+void    pci0ScanDevices(PCI_DEVICE *pci0Detect,unsigned int numberOfElment);
+void    pci1ScanDevices(PCI_DEVICE *pci1Detect,unsigned int numberOfElment);
+unsigned int    pci0ReadConfigReg (unsigned int regOffset,
+                                   unsigned int pciDevNum);
+unsigned int    pci1ReadConfigReg (unsigned int regOffset,
+                                   unsigned int pciDevNum);
+
+/*      Master`s memory space   */
+
+void    pci0MapIOspace(unsigned int pci0IoBase,unsigned int pci0IoLength);
+void    pci0MapMemory0space(unsigned int pci0Mem0Base,
+                            unsigned int pci0Mem0Length);
+void    pci0MapMemory1space(unsigned int pci0Mem1Base,
+                            unsigned int pci0Mem1Length);
+
+void    pci1MapIOspace(unsigned int pci1IoBase,unsigned int pci1IoLength);
+void    pci1MapMemory0space(unsigned int pci1Mem0Base,
+                            unsigned int pci1Mem0Length);
+void    pci1MapMemory1space(unsigned int pci1Mem1Base,
+                            unsigned int pci1Mem1Length);
+
+unsigned int    pci0GetIOspaceBase(void);
+unsigned int    pci0GetIOspaceSize(void);
+unsigned int    pci0GetMemory0Base(void);
+unsigned int    pci0GetMemory0Size(void);
+unsigned int    pci0GetMemory1Base(void);
+unsigned int    pci0GetMemory1Size(void);
+
+unsigned int    pci1GetIOspaceBase(void);
+unsigned int    pci1GetIOspaceSize(void);
+unsigned int    pci1GetMemory0Base(void);
+unsigned int    pci1GetMemory0Size(void);
+unsigned int    pci1GetMemory1Base(void);
+unsigned int    pci1GetMemory1Size(void);
+
+/*      Slave`s memory space   */
+void    pci0MapInternalRegSpace(unsigned int pci0InternalBase);
+void    pci0MapInternalRegIOSpace(unsigned int pci0InternalBase);
+void    pci0MapMemoryBanks0_1(unsigned int pci0Dram0_1Base,
+                              unsigned int pci0Dram0_1Size);
+void    pci0MapMemoryBanks2_3(unsigned int pci0Dram2_3Base,
+                              unsigned int pci0Dram2_3Size);
+void    pci0MapDevices0_1and2MemorySpace(unsigned int pci0Dev012Base,
+                                         unsigned int pci0Dev012Length);
+void    pci0MapDevices3andBootMemorySpace(unsigned int pci0Dev3andBootBase,
+                                          unsigned int pci0Dev3andBootLength);
+
+void    pci1MapInternalRegSpace(unsigned int pci1InternalBase);
+void    pci1MapInternalRegIOSpace(unsigned int pci1InternalBase);
+void    pci1MapMemoryBanks0_1(unsigned int pci1Dram0_1Base,
+                              unsigned int pci1Dram0_1Size);
+void    pci1MapMemoryBanks2_3(unsigned int pci1Dram2_3Base,
+                              unsigned int pci1Dram2_3Size);
+void    pci1MapDevices0_1and2MemorySpace(unsigned int pci1Dev012Base,
+                                         unsigned int pci1Dev012Length);
+void    pci1MapDevices3andBootMemorySpace(unsigned int pci1Dev3andBootBase,
+                                          unsigned int pci1Dev3andBootLength);
+
+#endif  /* __INCpcih */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/galileo-boards/gt96100.h linux/include/asm-mips/galileo-boards/gt96100.h
--- linux.orig/include/asm-mips/galileo-boards/gt96100.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/galileo-boards/gt96100.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	stevel@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Register offsets of the MIPS GT96100 Advanced Communication Controller.
+ * 
+ */
+#ifndef _GT96100_H
+#define _GT96100_H
+
+/*
+ * Galileo GT96100 internal register base.
+ */
+#define MIPS_GT96100_BASE (KSEG1ADDR(0x14000000))
+
+#define GT96100_WRITE(ofs, data) \
+    *(volatile u32 *)(MIPS_GT96100_BASE+ofs) = cpu_to_le32(data)
+#define GT96100_READ(ofs) \
+    le32_to_cpu(*(volatile u32 *)(MIPS_GT96100_BASE+ofs))
+
+#define GT96100_ETH_IO_SIZE 0x4000
+
+/************************************************************************
+ *  Register offset addresses follow
+ ************************************************************************/
+
+/* CPU Interface Control Registers */
+#define GT96100_CPU_INTERF_CONFIG 0x000000
+
+/* Ethernet Ports */
+#define GT96100_ETH_PHY_ADDR_REG             0x080800 
+#define GT96100_ETH_SMI_REG                  0x080810 
+/*
+  These are offsets to port 0 registers. Add GT96100_ETH_IO_SIZE to
+  get offsets to port 1 registers.
+*/
+#define GT96100_ETH_PORT_CONFIG          0x084800 
+#define GT96100_ETH_PORT_CONFIG_EXT      0x084808 
+#define GT96100_ETH_PORT_COMM            0x084810 
+#define GT96100_ETH_PORT_STATUS          0x084818 
+#define GT96100_ETH_SER_PARAM            0x084820 
+#define GT96100_ETH_HASH_TBL_PTR         0x084828 
+#define GT96100_ETH_FLOW_CNTRL_SRC_ADDR_L    0x084830 
+#define GT96100_ETH_FLOW_CNTRL_SRC_ADDR_H    0x084838 
+#define GT96100_ETH_SDMA_CONFIG          0x084840 
+#define GT96100_ETH_SDMA_COMM            0x084848 
+#define GT96100_ETH_INT_CAUSE            0x084850 
+#define GT96100_ETH_INT_MASK             0x084858 
+#define GT96100_ETH_1ST_RX_DESC_PTR0         0x084880
+#define GT96100_ETH_1ST_RX_DESC_PTR1         0x084884
+#define GT96100_ETH_1ST_RX_DESC_PTR2         0x084888
+#define GT96100_ETH_1ST_RX_DESC_PTR3         0x08488C
+#define GT96100_ETH_CURR_RX_DESC_PTR0        0x0848A0
+#define GT96100_ETH_CURR_RX_DESC_PTR1        0x0848A4
+#define GT96100_ETH_CURR_RX_DESC_PTR2        0x0848A8
+#define GT96100_ETH_CURR_RX_DESC_PTR3        0x0848AC
+#define GT96100_ETH_CURR_TX_DESC_PTR0        0x0848E0
+#define GT96100_ETH_CURR_TX_DESC_PTR1        0x0848E4
+#define GT96100_ETH_MIB_COUNT_BASE           0x085800 
+
+/* SDMAs */
+#define GT96100_SDMA_GROUP_CONFIG           0x101AF0
+/* SDMA Group 0 */
+#define GT96100_SDMA_G0_CHAN0_CONFIG        0x000900 
+#define GT96100_SDMA_G0_CHAN0_COMM          0x000908 
+#define GT96100_SDMA_G0_CHAN0_RX_DESC_BASE      0x008900 
+#define GT96100_SDMA_G0_CHAN0_CURR_RX_DESC_PTR  0x008910
+#define GT96100_SDMA_G0_CHAN0_TX_DESC_BASE      0x00C900 
+#define GT96100_SDMA_G0_CHAN0_CURR_TX_DESC_PTR  0x00C910
+#define GT96100_SDMA_G0_CHAN0_1ST_TX_DESC_PTR   0x00C914
+#define GT96100_SDMA_G0_CHAN1_CONFIG        0x010900
+#define GT96100_SDMA_G0_CHAN1_COMM          0x010908
+#define GT96100_SDMA_G0_CHAN1_RX_DESC_BASE      0x018900 
+#define GT96100_SDMA_G0_CHAN1_CURR_RX_DESC_PTR  0x018910
+#define GT96100_SDMA_G0_CHAN1_TX_DESC_BASE      0x01C900 
+#define GT96100_SDMA_G0_CHAN1_CURR_TX_DESC_PTR  0x01C910
+#define GT96100_SDMA_G0_CHAN1_1ST_TX_DESC_PTR   0x01C914
+#define GT96100_SDMA_G0_CHAN2_CONFIG        0x020900
+#define GT96100_SDMA_G0_CHAN2_COMM          0x020908
+#define GT96100_SDMA_G0_CHAN2_RX_DESC_BASE      0x028900 
+#define GT96100_SDMA_G0_CHAN2_CURR_RX_DESC_PTR  0x028910
+#define GT96100_SDMA_G0_CHAN2_TX_DESC_BASE      0x02C900 
+#define GT96100_SDMA_G0_CHAN2_CURR_TX_DESC_PTR  0x02C910
+#define GT96100_SDMA_G0_CHAN2_1ST_TX_DESC_PTR   0x02C914
+#define GT96100_SDMA_G0_CHAN3_CONFIG        0x030900
+#define GT96100_SDMA_G0_CHAN3_COMM          0x030908
+#define GT96100_SDMA_G0_CHAN3_RX_DESC_BASE      0x038900 
+#define GT96100_SDMA_G0_CHAN3_CURR_RX_DESC_PTR  0x038910
+#define GT96100_SDMA_G0_CHAN3_TX_DESC_BASE      0x03C900 
+#define GT96100_SDMA_G0_CHAN3_CURR_TX_DESC_PTR  0x03C910
+#define GT96100_SDMA_G0_CHAN3_1ST_TX_DESC_PTR   0x03C914
+#define GT96100_SDMA_G0_CHAN4_CONFIG        0x040900
+#define GT96100_SDMA_G0_CHAN4_COMM          0x040908
+#define GT96100_SDMA_G0_CHAN4_RX_DESC_BASE      0x048900 
+#define GT96100_SDMA_G0_CHAN4_CURR_RX_DESC_PTR  0x048910
+#define GT96100_SDMA_G0_CHAN4_TX_DESC_BASE      0x04C900 
+#define GT96100_SDMA_G0_CHAN4_CURR_TX_DESC_PTR  0x04C910
+#define GT96100_SDMA_G0_CHAN4_1ST_TX_DESC_PTR   0x04C914
+#define GT96100_SDMA_G0_CHAN5_CONFIG        0x050900
+#define GT96100_SDMA_G0_CHAN5_COMM          0x050908
+#define GT96100_SDMA_G0_CHAN5_RX_DESC_BASE      0x058900 
+#define GT96100_SDMA_G0_CHAN5_CURR_RX_DESC_PTR  0x058910
+#define GT96100_SDMA_G0_CHAN5_TX_DESC_BASE      0x05C900 
+#define GT96100_SDMA_G0_CHAN5_CURR_TX_DESC_PTR  0x05C910
+#define GT96100_SDMA_G0_CHAN5_1ST_TX_DESC_PTR   0x05C914
+#define GT96100_SDMA_G0_CHAN6_CONFIG        0x060900
+#define GT96100_SDMA_G0_CHAN6_COMM          0x060908
+#define GT96100_SDMA_G0_CHAN6_RX_DESC_BASE      0x068900 
+#define GT96100_SDMA_G0_CHAN6_CURR_RX_DESC_PTR  0x068910
+#define GT96100_SDMA_G0_CHAN6_TX_DESC_BASE      0x06C900 
+#define GT96100_SDMA_G0_CHAN6_CURR_TX_DESC_PTR  0x06C910
+#define GT96100_SDMA_G0_CHAN6_1ST_TX_DESC_PTR   0x06C914
+#define GT96100_SDMA_G0_CHAN7_CONFIG        0x070900
+#define GT96100_SDMA_G0_CHAN7_COMM          0x070908
+#define GT96100_SDMA_G0_CHAN7_RX_DESC_BASE      0x078900
+#define GT96100_SDMA_G0_CHAN7_CURR_RX_DESC_PTR  0x078910
+#define GT96100_SDMA_G0_CHAN7_TX_DESC_BASE      0x07C900 
+#define GT96100_SDMA_G0_CHAN7_CURR_TX_DESC_PTR  0x07C910
+#define GT96100_SDMA_G0_CHAN7_1ST_TX_DESC_PTR   0x07C914
+/* SDMA Group 1 */
+#define GT96100_SDMA_G1_CHAN0_CONFIG        0x100900
+#define GT96100_SDMA_G1_CHAN0_COMM          0x100908
+#define GT96100_SDMA_G1_CHAN0_RX_DESC_BASE      0x108900 
+#define GT96100_SDMA_G1_CHAN0_CURR_RX_DESC_PTR  0x108910
+#define GT96100_SDMA_G1_CHAN0_TX_DESC_BASE      0x10C900 
+#define GT96100_SDMA_G1_CHAN0_CURR_TX_DESC_PTR  0x10C910 
+#define GT96100_SDMA_G1_CHAN0_1ST_TX_DESC_PTR   0x10C914
+#define GT96100_SDMA_G1_CHAN1_CONFIG        0x110900
+#define GT96100_SDMA_G1_CHAN1_COMM          0x110908
+#define GT96100_SDMA_G1_CHAN1_RX_DESC_BASE      0x118900 
+#define GT96100_SDMA_G1_CHAN1_CURR_RX_DESC_PTR  0x118910
+#define GT96100_SDMA_G1_CHAN1_TX_DESC_BASE      0x11C900 
+#define GT96100_SDMA_G1_CHAN1_CURR_TX_DESC_PTR  0x11C910
+#define GT96100_SDMA_G1_CHAN1_1ST_TX_DESC_PTR   0x11C914
+#define GT96100_SDMA_G1_CHAN2_CONFIG        0x120900
+#define GT96100_SDMA_G1_CHAN2_COMM          0x120908
+#define GT96100_SDMA_G1_CHAN2_RX_DESC_BASE      0x128900 
+#define GT96100_SDMA_G1_CHAN2_CURR_RX_DESC_PTR  0x128910
+#define GT96100_SDMA_G1_CHAN2_TX_DESC_BASE      0x12C900 
+#define GT96100_SDMA_G1_CHAN2_CURR_TX_DESC_PTR  0x12C910
+#define GT96100_SDMA_G1_CHAN2_1ST_TX_DESC_PTR   0x12C914
+#define GT96100_SDMA_G1_CHAN3_CONFIG        0x130900
+#define GT96100_SDMA_G1_CHAN3_COMM          0x130908
+#define GT96100_SDMA_G1_CHAN3_RX_DESC_BASE      0x138900 
+#define GT96100_SDMA_G1_CHAN3_CURR_RX_DESC_PTR  0x138910
+#define GT96100_SDMA_G1_CHAN3_TX_DESC_BASE      0x13C900 
+#define GT96100_SDMA_G1_CHAN3_CURR_TX_DESC_PTR  0x13C910
+#define GT96100_SDMA_G1_CHAN3_1ST_TX_DESC_PTR   0x13C914
+#define GT96100_SDMA_G1_CHAN4_CONFIG        0x140900
+#define GT96100_SDMA_G1_CHAN4_COMM          0x140908
+#define GT96100_SDMA_G1_CHAN4_RX_DESC_BASE      0x148900 
+#define GT96100_SDMA_G1_CHAN4_CURR_RX_DESC_PTR  0x148910
+#define GT96100_SDMA_G1_CHAN4_TX_DESC_BASE      0x14C900 
+#define GT96100_SDMA_G1_CHAN4_CURR_TX_DESC_PTR  0x14C910
+#define GT96100_SDMA_G1_CHAN4_1ST_TX_DESC_PTR   0x14C914
+#define GT96100_SDMA_G1_CHAN5_CONFIG        0x150900
+#define GT96100_SDMA_G1_CHAN5_COMM          0x150908
+#define GT96100_SDMA_G1_CHAN5_RX_DESC_BASE      0x158900 
+#define GT96100_SDMA_G1_CHAN5_CURR_RX_DESC_PTR  0x158910
+#define GT96100_SDMA_G1_CHAN5_TX_DESC_BASE      0x15C900 
+#define GT96100_SDMA_G1_CHAN5_CURR_TX_DESC_PTR  0x15C910
+#define GT96100_SDMA_G1_CHAN5_1ST_TX_DESC_PTR   0x15C914
+#define GT96100_SDMA_G1_CHAN6_CONFIG        0x160900
+#define GT96100_SDMA_G1_CHAN6_COMM          0x160908
+#define GT96100_SDMA_G1_CHAN6_RX_DESC_BASE      0x168900 
+#define GT96100_SDMA_G1_CHAN6_CURR_RX_DESC_PTR  0x168910
+#define GT96100_SDMA_G1_CHAN6_TX_DESC_BASE      0x16C900 
+#define GT96100_SDMA_G1_CHAN6_CURR_TX_DESC_PTR  0x16C910
+#define GT96100_SDMA_G1_CHAN6_1ST_TX_DESC_PTR   0x16C914
+#define GT96100_SDMA_G1_CHAN7_CONFIG        0x170900
+#define GT96100_SDMA_G1_CHAN7_COMM          0x170908
+#define GT96100_SDMA_G1_CHAN7_RX_DESC_BASE      0x178900 
+#define GT96100_SDMA_G1_CHAN7_CURR_RX_DESC_PTR  0x178910
+#define GT96100_SDMA_G1_CHAN7_TX_DESC_BASE      0x17C900 
+#define GT96100_SDMA_G1_CHAN7_CURR_TX_DESC_PTR  0x17C910
+#define GT96100_SDMA_G1_CHAN7_1ST_TX_DESC_PTR   0x17C914
+/*  MPSCs  */
+#define GT96100_MPSC0_MAIN_CONFIG_LOW   0x000A00 
+#define GT96100_MPSC0_MAIN_CONFIG_HIGH  0x000A04 
+#define GT96100_MPSC0_PROTOCOL_CONFIG   0x000A08 
+#define GT96100_MPSC_CHAN0_REG1         0x000A0C
+#define GT96100_MPSC_CHAN0_REG2         0x000A10
+#define GT96100_MPSC_CHAN0_REG3         0x000A14
+#define GT96100_MPSC_CHAN0_REG4         0x000A18
+#define GT96100_MPSC_CHAN0_REG5         0x000A1C
+#define GT96100_MPSC_CHAN0_REG6         0x000A20 
+#define GT96100_MPSC_CHAN0_REG7         0x000A24
+#define GT96100_MPSC_CHAN0_REG8         0x000A28
+#define GT96100_MPSC_CHAN0_REG9         0x000A2C
+#define GT96100_MPSC_CHAN0_REG10        0x000A30
+#define GT96100_MPSC_CHAN0_REG11        0x000A34
+#define GT96100_MPSC1_MAIN_CONFIG_LOW   0x008A00 
+#define GT96100_MPSC1_MAIN_CONFIG_HIGH  0x008A04 
+#define GT96100_MPSC1_PROTOCOL_CONFIG   0x008A08 
+#define GT96100_MPSC_CHAN1_REG1         0x008A0C
+#define GT96100_MPSC_CHAN1_REG2         0x008A10
+#define GT96100_MPSC_CHAN1_REG3         0x008A14
+#define GT96100_MPSC_CHAN1_REG4         0x008A18
+#define GT96100_MPSC_CHAN1_REG5         0x008A1C
+#define GT96100_MPSC_CHAN1_REG6         0x008A20
+#define GT96100_MPSC_CHAN1_REG7         0x008A24
+#define GT96100_MPSC_CHAN1_REG8         0x008A28
+#define GT96100_MPSC_CHAN1_REG9         0x008A2C
+#define GT96100_MPSC_CHAN1_REG10        0x008A30
+#define GT96100_MPSC_CHAN1_REG11        0x008A34
+#define GT96100_MPSC2_MAIN_CONFIG_LOW   0x010A00 
+#define GT96100_MPSC2_MAIN_CONFIG_HIGH  0x010A04 
+#define GT96100_MPSC2_PROTOCOL_CONFIG   0x010A08 
+#define GT96100_MPSC_CHAN2_REG1         0x010A0C
+#define GT96100_MPSC_CHAN2_REG2         0x010A10
+#define GT96100_MPSC_CHAN2_REG3         0x010A14
+#define GT96100_MPSC_CHAN2_REG4         0x010A18
+#define GT96100_MPSC_CHAN2_REG5         0x010A1C
+#define GT96100_MPSC_CHAN2_REG6         0x010A20 
+#define GT96100_MPSC_CHAN2_REG7         0x010A24
+#define GT96100_MPSC_CHAN2_REG8         0x010A28
+#define GT96100_MPSC_CHAN2_REG9         0x010A2C
+#define GT96100_MPSC_CHAN2_REG10        0x010A30
+#define GT96100_MPSC_CHAN2_REG11        0x010A34
+#define GT96100_MPSC3_MAIN_CONFIG_LOW   0x018A00 
+#define GT96100_MPSC3_MAIN_CONFIG_HIGH  0x018A04
+#define GT96100_MPSC3_PROTOCOL_CONFIG   0x018A08 
+#define GT96100_MPSC_CHAN3_REG1         0x018A0C
+#define GT96100_MPSC_CHAN3_REG2         0x018A10
+#define GT96100_MPSC_CHAN3_REG3         0x018A14
+#define GT96100_MPSC_CHAN3_REG4         0x018A18
+#define GT96100_MPSC_CHAN3_REG5         0x018A1C
+#define GT96100_MPSC_CHAN3_REG6         0x018A20
+#define GT96100_MPSC_CHAN3_REG7         0x018A24
+#define GT96100_MPSC_CHAN3_REG8         0x018A28
+#define GT96100_MPSC_CHAN3_REG9         0x018A2C
+#define GT96100_MPSC_CHAN3_REG10        0x018A30
+#define GT96100_MPSC_CHAN3_REG11        0x018A34
+#define GT96100_MPSC4_MAIN_CONFIG_LOW   0x020A00 
+#define GT96100_MPSC4_MAIN_CONFIG_HIGH  0x020A04
+#define GT96100_MPSC4_PROTOCOL_CONFIG   0x020A08 
+#define GT96100_MPSC_CHAN4_REG1         0x020A0C
+#define GT96100_MPSC_CHAN4_REG2         0x020A10
+#define GT96100_MPSC_CHAN4_REG3         0x020A14
+#define GT96100_MPSC_CHAN4_REG4         0x020A18
+#define GT96100_MPSC_CHAN4_REG5         0x020A1C
+#define GT96100_MPSC_CHAN4_REG6         0x020A20 
+#define GT96100_MPSC_CHAN4_REG7         0x020A24 
+#define GT96100_MPSC_CHAN4_REG8         0x020A28 
+#define GT96100_MPSC_CHAN4_REG9         0x020A2C 
+#define GT96100_MPSC_CHAN4_REG10        0x020A30
+#define GT96100_MPSC_CHAN4_REG11        0x020A34
+#define GT96100_MPSC5_MAIN_CONFIG_LOW   0x028A00 
+#define GT96100_MPSC5_MAIN_CONFIG_HIGH  0x028A04
+#define GT96100_MPSC5_PROTOCOL_CONFIG   0x028A08 
+#define GT96100_MPSC_CHAN5_REG1         0x028A0C
+#define GT96100_MPSC_CHAN5_REG2         0x028A10
+#define GT96100_MPSC_CHAN5_REG3         0x028A14
+#define GT96100_MPSC_CHAN5_REG4         0x028A18
+#define GT96100_MPSC_CHAN5_REG5         0x028A1C
+#define GT96100_MPSC_CHAN5_REG6         0x028A20
+#define GT96100_MPSC_CHAN5_REG7         0x028A24
+#define GT96100_MPSC_CHAN5_REG8         0x028A28
+#define GT96100_MPSC_CHAN5_REG9         0x028A2C
+#define GT96100_MPSC_CHAN5_REG10        0x028A30
+#define GT96100_MPSC_CHAN5_REG11        0x028A34
+#define GT96100_MPSC6_MAIN_CONFIG_LOW   0x030A00 
+#define GT96100_MPSC6_MAIN_CONFIG_HIGH  0x030A04
+#define GT96100_MPSC6_PROTOCOL_CONFIG   0x030A08 
+#define GT96100_MPSC_CHAN6_REG1         0x030A0C
+#define GT96100_MPSC_CHAN6_REG2         0x030A10
+#define GT96100_MPSC_CHAN6_REG3         0x030A14
+#define GT96100_MPSC_CHAN6_REG4         0x030A18
+#define GT96100_MPSC_CHAN6_REG5         0x030A1C
+#define GT96100_MPSC_CHAN6_REG6         0x030A20
+#define GT96100_MPSC_CHAN6_REG7         0x030A24
+#define GT96100_MPSC_CHAN6_REG8         0x030A28
+#define GT96100_MPSC_CHAN6_REG9         0x030A2C
+#define GT96100_MPSC_CHAN6_REG10        0x030A30
+#define GT96100_MPSC_CHAN6_REG11        0x030A34
+#define GT96100_MPSC7_MAIN_CONFIG_LOW   0x038A00 
+#define GT96100_MPSC7_MAIN_CONFIG_HIGH  0x038A04
+#define GT96100_MPSC7_PROTOCOL_CONFIG   0x038A08 
+#define GT96100_MPSC_CHAN7_REG1         0x038A0C
+#define GT96100_MPSC_CHAN7_REG2         0x038A10
+#define GT96100_MPSC_CHAN7_REG3         0x038A14
+#define GT96100_MPSC_CHAN7_REG4         0x038A18
+#define GT96100_MPSC_CHAN7_REG5         0x038A1C
+#define GT96100_MPSC_CHAN7_REG6         0x038A20
+#define GT96100_MPSC_CHAN7_REG7         0x038A24
+#define GT96100_MPSC_CHAN7_REG8         0x038A28
+#define GT96100_MPSC_CHAN7_REG9         0x038A2C
+#define GT96100_MPSC_CHAN7_REG10        0x038A30
+#define GT96100_MPSC_CHAN7_REG11        0x038A34
+/*  FlexTDMs  */
+/* TDPR0 - Transmit Dual Port RAM. block size 0xff */
+#define GT96100_FXTDM0_TDPR0_BLK0_BASE  0x000B00
+#define GT96100_FXTDM0_TDPR0_BLK1_BASE  0x001B00 
+#define GT96100_FXTDM0_TDPR0_BLK2_BASE  0x002B00 
+#define GT96100_FXTDM0_TDPR0_BLK3_BASE  0x003B00
+/* RDPR0 - Receive Dual Port RAM. block size 0xff */
+#define GT96100_FXTDM0_RDPR0_BLK0_BASE  0x004B00
+#define GT96100_FXTDM0_RDPR0_BLK1_BASE  0x005B00 
+#define GT96100_FXTDM0_RDPR0_BLK2_BASE  0x006B00 
+#define GT96100_FXTDM0_RDPR0_BLK3_BASE  0x007B00 
+#define GT96100_FXTDM0_TX_READ_PTR      0x008B00
+#define GT96100_FXTDM0_RX_READ_PTR      0x008B04
+#define GT96100_FXTDM0_CONFIG       0x008B08
+#define GT96100_FXTDM0_AUX_CHANA_TX 0x008B0C
+#define GT96100_FXTDM0_AUX_CHANA_RX 0x008B10
+#define GT96100_FXTDM0_AUX_CHANB_TX 0x008B14
+#define GT96100_FXTDM0_AUX_CHANB_RX 0x008B18
+#define GT96100_FXTDM1_TDPR1_BLK0_BASE  0x010B00 
+#define GT96100_FXTDM1_TDPR1_BLK1_BASE  0x011B00 
+#define GT96100_FXTDM1_TDPR1_BLK2_BASE  0x012B00 
+#define GT96100_FXTDM1_TDPR1_BLK3_BASE  0x013B00 
+#define GT96100_FXTDM1_RDPR1_BLK0_BASE  0x014B00 
+#define GT96100_FXTDM1_RDPR1_BLK1_BASE  0x015B00 
+#define GT96100_FXTDM1_RDPR1_BLK2_BASE  0x016B00 
+#define GT96100_FXTDM1_RDPR1_BLK3_BASE  0x017B00 
+#define GT96100_FXTDM1_TX_READ_PTR      0x018B00
+#define GT96100_FXTDM1_RX_READ_PTR      0x018B04
+#define GT96100_FXTDM1_CONFIG       0x018B08
+#define GT96100_FXTDM1_AUX_CHANA_TX 0x018B0C
+#define GT96100_FXTDM1_AUX_CHANA_RX 0x018B10
+#define GT96100_FLTDM1_AUX_CHANB_TX 0x018B14
+#define GT96100_FLTDM1_AUX_CHANB_RX 0x018B18
+#define GT96100_FLTDM2_TDPR2_BLK0_BASE  0x020B00
+#define GT96100_FLTDM2_TDPR2_BLK1_BASE  0x021B00 
+#define GT96100_FLTDM2_TDPR2_BLK2_BASE  0x022B00
+#define GT96100_FLTDM2_TDPR2_BLK3_BASE  0x023B00
+#define GT96100_FLTDM2_RDPR2_BLK0_BASE  0x024B00
+#define GT96100_FLTDM2_RDPR2_BLK1_BASE  0x025B00
+#define GT96100_FLTDM2_RDPR2_BLK2_BASE  0x026B00
+#define GT96100_FLTDM2_RDPR2_BLK3_BASE  0x027B00
+#define GT96100_FLTDM2_TX_READ_PTR      0x028B00
+#define GT96100_FLTDM2_RX_READ_PTR      0x028B04
+#define GT96100_FLTDM2_CONFIG       0x028B08
+#define GT96100_FLTDM2_AUX_CHANA_TX 0x028B0C
+#define GT96100_FLTDM2_AUX_CHANA_RX 0x028B10
+#define GT96100_FLTDM2_AUX_CHANB_TX 0x028B14
+#define GT96100_FLTDM2_AUX_CHANB_RX 0x028B18
+#define GT96100_FLTDM3_TDPR3_BLK0_BASE  0x030B00
+#define GT96100_FLTDM3_TDPR3_BLK1_BASE  0x031B00
+#define GT96100_FLTDM3_TDPR3_BLK2_BASE  0x032B00
+#define GT96100_FLTDM3_TDPR3_BLK3_BASE  0x033B00
+#define GT96100_FXTDM3_RDPR3_BLK0_BASE  0x034B00
+#define GT96100_FXTDM3_RDPR3_BLK1_BASE  0x035B00
+#define GT96100_FXTDM3_RDPR3_BLK2_BASE  0x036B00
+#define GT96100_FXTDM3_RDPR3_BLK3_BASE  0x037B00
+#define GT96100_FXTDM3_TX_READ_PTR      0x038B00
+#define GT96100_FXTDM3_RX_READ_PTR      0x038B04
+#define GT96100_FXTDM3_CONFIG       0x038B08
+#define GT96100_FXTDM3_AUX_CHANA_TX 0x038B0C
+#define GT96100_FXTDM3_AUX_CHANA_RX 0x038B10
+#define GT96100_FXTDM3_AUX_CHANB_TX 0x038B14
+#define GT96100_FXTDM3_AUX_CHANB_RX 0x038B18
+/*  Baud Rate Generators  */
+#define GT96100_BRG0_CONFIG     0x102A00 
+#define GT96100_BRG0_BAUD_TUNE  0x102A04 
+#define GT96100_BRG1_CONFIG     0x102A08 
+#define GT96100_BRG1_BAUD_TUNE  0x102A0C 
+#define GT96100_BRG2_CONFIG     0x102A10 
+#define GT96100_BRG2_BAUD_TUNE  0x102A14 
+#define GT96100_BRG3_CONFIG     0x102A18 
+#define GT96100_BRG3_BAUD_TUNE  0x102A1C 
+#define GT96100_BRG4_CONFIG     0x102A20 
+#define GT96100_BRG4_BAUD_TUNE  0x102A24 
+#define GT96100_BRG5_CONFIG     0x102A28 
+#define GT96100_BRG5_BAUD_TUNE  0x102A2C 
+#define GT96100_BRG6_CONFIG     0x102A30 
+#define GT96100_BRG6_BAUD_TUNE  0x102A34 
+#define GT96100_BRG7_CONFIG     0x102A38 
+#define GT96100_BRG7_BAUD_TUNE  0x102A3C 
+/*  Routing Registers  */
+#define GT96100_ROUTE_MAIN      0x101A00 
+#define GT96100_ROUTE_RX_CLOCK  0x101A10 
+#define GT96100_ROUTE_TX_CLOCK  0x101A20 
+/*  General Purpose Ports  */
+#define GT96100_GPP_CONFIG0     0x100A00 
+#define GT96100_GPP_CONFIG1     0x100A04 
+#define GT96100_GPP_CONFIG2     0x100A08 
+#define GT96100_GPP_CONFIG3     0x100A0C 
+#define GT96100_GPP_IO0         0x100A20 
+#define GT96100_GPP_IO1         0x100A24 
+#define GT96100_GPP_IO2         0x100A28 
+#define GT96100_GPP_IO3         0x100A2C 
+#define GT96100_GPP_DATA0       0x100A40 
+#define GT96100_GPP_DATA1       0x100A44 
+#define GT96100_GPP_DATA2       0x100A48 
+#define GT96100_GPP_DATA3       0x100A4C 
+#define GT96100_GPP_LEVEL0      0x100A60 
+#define GT96100_GPP_LEVEL1      0x100A64 
+#define GT96100_GPP_LEVEL2      0x100A68 
+#define GT96100_GPP_LEVEL3      0x100A6C 
+/*  Watchdog  */
+#define GT96100_WD_CONFIG   0x101A80 
+#define GT96100_WD_VALUE    0x101A84 
+/* Communication Unit Arbiter  */
+#define GT96100_COMM_UNIT_ARBTR_CONFIG 0x101AC0
+/*  PCI Arbiters  */
+#define GT96100_PCI0_ARBTR_CONFIG 0x101AE0
+#define GT96100_PCI1_ARBTR_CONFIG 0x101AE4
+/* CIU Arbiter */
+#define GT96100_CIU_ARBITER_CONFIG 0x101AC0
+/* Interrupt Controller */
+#define GT96100_MAIN_CAUSE     0x000C18
+#define GT96100_INT0_MAIN_MASK 0x000C1C
+#define GT96100_INT1_MAIN_MASK 0x000C24
+#define GT96100_HIGH_CAUSE     0x000C98
+#define GT96100_INT0_HIGH_MASK 0x000C9C
+#define GT96100_INT1_HIGH_MASK 0x000CA4
+#define GT96100_INT0_SELECT    0x000C70
+#define GT96100_INT1_SELECT    0x000C74
+#define GT96100_SERIAL_CAUSE   0x103A00
+#define GT96100_SERINT0_MASK   0x103A80
+#define GT96100_SERINT1_MASK   0x103A88
+
+#endif /*  _GT96100_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/gdb-stub.h linux/include/asm-mips/gdb-stub.h
--- linux.orig/include/asm-mips/gdb-stub.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/gdb-stub.h	2002-07-20 01:08:37.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: gdb-stub.h,v 1.3 1998/07/20 17:52:19 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -133,7 +132,7 @@
 
 #define GDB_FR_SIZE		((((GDB_FR_CP0_PRID) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1))
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 /*
  * This is the same as above, but for the high-level
@@ -209,5 +208,5 @@
 
 void set_debug_traps(void);
 
-#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* !__ASSEMBLY__ */
 #endif /* __ASM_MIPS_GDB_STUB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/gfx.h linux/include/asm-mips/gfx.h
--- linux.orig/include/asm-mips/gfx.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/gfx.h	2002-07-20 01:08:23.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/highmem.h linux/include/asm-mips/highmem.h
--- linux.orig/include/asm-mips/highmem.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/highmem.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,99 @@
+/*
+ * highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual addresses.
+ *
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ *		      Gerhard.Wichert@pdb.siemens.de
+ *
+ *
+ * Redesigned the x86 32-bit VM architecture to deal with 
+ * up to 16 Terabyte physical memory. With current x86 CPUs
+ * we now support up to 64 Gigabytes physical RAM.
+ *
+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+ */
+
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/kmap_types.h>
+#include <asm/pgtable.h>
+
+/* undef for production */
+#define HIGHMEM_DEBUG 1
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+extern pte_t *kmap_pte;
+extern pgprot_t kmap_prot;
+extern pte_t *pkmap_page_table;
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define PKMAP_BASE (0xfe000000UL)
+#define LAST_PKMAP 1024
+#define LAST_PKMAP_MASK (LAST_PKMAP-1)
+#define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern void * kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+static inline void *kmap(struct page *page)
+{
+	if (in_interrupt())
+		out_of_line_bug();
+	if (page < highmem_start_page)
+		return page_address(page);
+	return kmap_high(page);
+}
+
+static inline void kunmap(struct page *page)
+{
+	if (in_interrupt())
+		out_of_line_bug();
+	if (page < highmem_start_page)
+		return;
+	kunmap_high(page);
+}
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+static inline void *kmap_atomic(struct page *page, enum km_type type)
+{
+	enum fixed_addresses idx;
+	unsigned long vaddr;
+
+	if (page < highmem_start_page)
+		return page_address(page);
+
+	idx = type + KM_TYPE_NR*smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
+	//local_flush_tlb_page(NULL, vaddr);
+	local_flush_tlb_all();
+
+	return (void*) vaddr;
+}
+
+static inline void kunmap_atomic(void *kvaddr, enum km_type type)
+{
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/hp-lj/asic.h linux/include/asm-mips/hp-lj/asic.h
--- linux.orig/include/asm-mips/hp-lj/asic.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/hp-lj/asic.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,7 @@
+
+typedef enum { IllegalAsic, UnknownAsic, AndrosAsic, HarmonyAsic } AsicId;
+
+AsicId GetAsicId(void);
+
+const char* const GetAsicName(void);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/hw_irq.h linux/include/asm-mips/hw_irq.h
--- linux.orig/include/asm-mips/hw_irq.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/hw_irq.h	2002-07-20 01:08:39.000000000 +0000
@@ -8,6 +8,10 @@
 #ifndef _ASM_HW_IRQ_H
 #define _ASM_HW_IRQ_H
 
+#include <asm/atomic.h>
+
+extern atomic_t irq_err_count;
+
 /* This may not be apropriate for all machines, we'll see ...  */
 static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ide.h linux/include/asm-mips/ide.h
--- linux.orig/include/asm-mips/ide.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/ide.h	2002-07-20 01:08:27.000000000 +0000
@@ -92,6 +92,27 @@
 	} b;
 } select_t;
 
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+#ifdef __MIPSEB__
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+		unsigned reserved456	: 3;
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned bit0		: 1;
+#else
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+#endif
+	} b;
+} control_t;
+
 static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int,void *, struct pt_regs *),
 			unsigned long flags, const char *device, void *dev_id)
 {
@@ -125,6 +146,57 @@
 
 #if defined(__MIPSEB__)
 
+/* get rid of defs from io.h - ide has its private and conflicting versions */
+#ifdef insw
+#undef insw
+#endif
+#ifdef outsw
+#undef outsw
+#endif
+#ifdef insl
+#undef insl
+#endif
+#ifdef outsl
+#undef outsl
+#endif
+
+#define insw(port, addr, count) ide_insw(port, addr, count)
+#define insl(port, addr, count) ide_insl(port, addr, count)
+#define outsw(port, addr, count) ide_outsw(port, addr, count)
+#define outsl(port, addr, count) ide_outsl(port, addr, count)
+
+static inline void ide_insw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u16 *)addr = *(volatile u16 *)(mips_io_port_base + port);
+		addr += 2;
+	}
+}
+
+static inline void ide_outsw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(volatile u16 *)(mips_io_port_base + (port)) = *(u16 *)addr;
+		addr += 2;
+	}
+}
+
+static inline void ide_insl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u32 *)addr = *(volatile u32 *)(mips_io_port_base + port);
+		addr += 4;
+	}
+}
+
+static inline void ide_outsl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(volatile u32 *)(mips_io_port_base + (port)) = *(u32 *)addr;
+		addr += 4;
+	}
+}
+
 #define T_CHAR          (0x0000)        /* char:  don't touch  */
 #define T_SHORT         (0x4000)        /* short: 12 -> 21     */
 #define T_INT           (0x8000)        /* int:   1234 -> 4321 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/inventory.h linux/include/asm-mips/inventory.h
--- linux.orig/include/asm-mips/inventory.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/inventory.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,8 +1,8 @@
 /*
- * $Id:$
+ * Miguel de Icaza
  */
-#ifndef __ASM_MIPS_INVENTORY_H
-#define __ASM_MIPS_INVENTORY_H
+#ifndef __ASM_INVENTORY_H
+#define __ASM_INVENTORY_H
 
 #include <linux/config.h>
 
@@ -25,4 +25,4 @@
 #define add_to_inventory(c,t,o,u,s)
 #define init_inventory()
 #endif
-#endif /* defined(CONFIG_BINFMT_IRIX) */
+#endif /* __ASM_INVENTORY_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/io.h linux/include/asm-mips/io.h
--- linux.orig/include/asm-mips/io.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/io.h	2002-07-20 01:08:33.000000000 +0000
@@ -13,7 +13,9 @@
 
 #include <linux/config.h>
 #include <linux/pagemap.h>
+#include <linux/types.h>
 #include <asm/addrspace.h>
+#include <asm/pgtable-bits.h>
 #include <asm/byteorder.h>
 
 /*
@@ -40,27 +42,17 @@
 #endif
 
 /*
- * This file contains the definitions for the MIPS counterpart of the
- * x86 in/out instructions. This heap of macros and C results in much
- * better code than the approach of doing it in plain C.  The macros
- * result in code that is to fast for certain hardware.  On the other
- * side the performance of the string functions should be improved for
- * sake of certain devices like EIDE disks that do highspeed polled I/O.
- *
- *   Ralf
- *
- * This file contains the definitions for the x86 IO instructions
- * inb/inw/inl/outb/outw/outl and the "string versions" of the same
- * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
- * versions of the single-IO instructions (inb_p/inw_p/..).
- *
- * This file is not meant to be obfuscating: it's just complicated
- * to (a) handle it all in a way that makes gcc able to optimize it
- * as well as possible and (b) trying to avoid writing the same thing
- * over and over again with slight variations and possibly making a
- * mistake somewhere.
+ * <Bacchus> Historically I wrote this stuff the same way as Linus did
+ * because I was young and clueless.  And now it's so jucky that I
+ * don't want to put my eyes on it again to get rid of it :-) 
+ *
+ * I'll do it then, because this code offends both me and my compiler
+ * - particularly the bits of inline asm which end up doing crap like
+ * 'lb $2,$2($5)' -- dwmw2
  */
 
+#define IO_SPACE_LIMIT 0xffff
+
 /*
  * On MIPS I/O ports are memory mapped, so we access them using normal
  * load/store instructions. mips_io_port_base is the virtual address to
@@ -69,7 +61,10 @@
  * instruction, so the lower 16 bits must be zero.  Should be true on
  * on any sane architecture; generic code does not use this assumption.
  */
-extern unsigned long mips_io_port_base;
+extern const unsigned long mips_io_port_base;
+
+#define set_io_port_base(base)	\
+	do { * (unsigned long *) &mips_io_port_base = (base); } while (0)
 
 /*
  * Thanks to James van Artsdalen for a better timing-fix than
@@ -99,15 +94,37 @@
 #endif
 
 /*
- * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/MIPS mapping
+ *     virt_to_phys    -       map virtual addresses to physical
+ *     @address: address to remap
+ *
+ *     The returned physical address is the physical (CPU) mapping for
+ *     the memory address given. It is only valid to use this function on
+ *     addresses directly mapped or allocated via kmalloc. 
+ *
+ *     This function does not give bus mappings for DMA transfers. In
+ *     almost all conceivable cases a device driver should not be using
+ *     this function
  */
-extern inline unsigned long virt_to_phys(volatile void * address)
+
+static inline unsigned long virt_to_phys(volatile void * address)
 {
 	return PHYSADDR(address);
 }
 
-extern inline void * phys_to_virt(unsigned long address)
+/*
+ *     phys_to_virt    -       map physical address to virtual
+ *     @address: address to remap
+ *
+ *     The returned virtual address is a current CPU mapping for
+ *     the memory address given. It is only valid to use this function on
+ *     addresses that have a kernel mapping
+ *
+ *     This function does not handle bus mappings for DMA transfers. In
+ *     almost all conceivable cases a device driver should not be using
+ *     this function
+ */
+
+static inline void * phys_to_virt(unsigned long address)
 {
 	return (void *)KSEG0ADDR(address);
 }
@@ -115,33 +132,76 @@
 /*
  * IO bus memory addresses are also 1:1 with the physical address
  */
-extern inline unsigned long virt_to_bus(volatile void * address)
+static inline unsigned long virt_to_bus(volatile void * address)
 {
 	return PHYSADDR(address);
 }
 
-extern inline void * bus_to_virt(unsigned long address)
+static inline void * bus_to_virt(unsigned long address)
 {
 	return (void *)KSEG0ADDR(address);
 }
 
+#define page_to_bus page_to_phys
+
 /*
  * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped
  * for the processor.
  */
 extern unsigned long isa_slot_offset;
 
-extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+/*
+ * Change "struct page" to physical address.
+ */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define page_to_phys(page)	((u64)(page - mem_map) << PAGE_SHIFT)
+#else
+#define page_to_phys(page)	((page - mem_map) << PAGE_SHIFT)
+#endif
 
-extern inline void *ioremap(unsigned long offset, unsigned long size)
-{
-	return __ioremap(offset, size, _CACHE_UNCACHED);
-}
 
-extern inline void *ioremap_nocache(unsigned long offset, unsigned long size)
-{
-	return __ioremap(offset, size, _CACHE_UNCACHED);
-}
+extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags);
+
+/*
+ *     ioremap         -       map bus memory into CPU space
+ *     @offset:        bus address of the memory
+ *     @size:          size of the resource to map
+ *
+ *     ioremap performs a platform specific sequence of operations to
+ *     make bus memory CPU accessible via the readb/readw/readl/writeb/
+ *     writew/writel functions and the other mmio helpers. The returned
+ *     address is not guaranteed to be usable directly as a virtual
+ *     address. 
+ */
+
+#define ioremap(offset, size)						\
+	__ioremap((offset), (size), _CACHE_UNCACHED)
+
+/*
+ *     ioremap_nocache         -       map bus memory into CPU space
+ *     @offset:        bus address of the memory
+ *     @size:          size of the resource to map
+ *
+ *     ioremap_nocache performs a platform specific sequence of operations to
+ *     make bus memory CPU accessible via the readb/readw/readl/writeb/
+ *     writew/writel functions and the other mmio helpers. The returned
+ *     address is not guaranteed to be usable directly as a virtual
+ *     address. 
+ *
+ *     This version of ioremap ensures that the memory is marked uncachable
+ *     on the CPU as well as honouring existing caching rules from things like
+ *     the PCI bus. Note that there are other caches and buffers on many 
+ *     busses. In paticular driver authors should read up on PCI writes
+ *
+ *     It's useful if some control registers are in such an area and
+ *     write combining or read caching is not desirable:
+ */
+#define ioremap_nocache(offset, size)					\
+	__ioremap((offset), (size), _CACHE_UNCACHED)
+#define ioremap_cacheable_cow(offset, size)				\
+	__ioremap((offset), (size), _CACHE_CACHABLE_COW)
+#define ioremap_uncached_accelerated(offset, size)			\
+	__ioremap((offset), (size), _CACHE_UNCACHED_ACCELERATED)
 
 extern void iounmap(void *addr);
 
@@ -150,26 +210,26 @@
  * 24-31 on SNI.
  * XXX more SNI hacks.
  */
-#define readb(addr) (*(volatile unsigned char *)(addr))
-#define readw(addr) __ioswab16((*(volatile unsigned short *)(addr)))
-#define readl(addr) __ioswab32((*(volatile unsigned int *)(addr)))
-#define __raw_readb readb
-#define __raw_readw readw
-#define __raw_readl readl
-
-#define writeb(b,addr) (*(volatile unsigned char *)(addr)) = (b)
-#define writew(b,addr) (*(volatile unsigned short *)(addr)) = (__ioswab16(b))
-#define writel(b,addr) (*(volatile unsigned int *)(addr)) = (__ioswab32(b))
-#define __raw_writeb writeb
-#define __raw_writew writew
-#define __raw_writel writel
+#define readb(addr)		(*(volatile unsigned char *)(addr))
+#define readw(addr)		__ioswab16((*(volatile unsigned short *)(addr)))
+#define readl(addr)		__ioswab32((*(volatile unsigned int *)(addr)))
+
+#define __raw_readb(addr)	(*(volatile unsigned char *)(addr))
+#define __raw_readw(addr)	(*(volatile unsigned short *)(addr))
+#define __raw_readl(addr)	(*(volatile unsigned int *)(addr))
+
+#define writeb(b,addr) ((*(volatile unsigned char *)(addr)) = (__ioswab8(b)))
+#define writew(b,addr) ((*(volatile unsigned short *)(addr)) = (__ioswab16(b)))
+#define writel(b,addr) ((*(volatile unsigned int *)(addr)) = (__ioswab32(b)))
+
+#define __raw_writeb(b,addr)	((*(volatile unsigned char *)(addr)) = (b))
+#define __raw_writew(w,addr)	((*(volatile unsigned short *)(addr)) = (w))
+#define __raw_writel(l,addr)	((*(volatile unsigned int *)(addr)) = (l))
 
 #define memset_io(a,b,c)	memset((void *)(a),(b),(c))
 #define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
 #define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
 
-/* END SNI HACKS ... */
-
 /*
  * ISA space is 'always mapped' on currently supported MIPS systems, no need
  * to explicitly ioremap() it. The fact that the ISA IO space is mapped
@@ -178,18 +238,17 @@
  * used as the IO-area pointer (it can be iounmapped as well, so the
  * analogy with PCI is quite large):
  */
-#define __ISA_IO_base ((char *)(PAGE_OFFSET))
+#define __ISA_IO_base ((char *)(isa_slot_offset))
 
-#define isa_readb(a) readb(a)
-#define isa_readw(a) readw(a)
-#define isa_readl(a) readl(a)
-#define isa_writeb(b,a) writeb(b,a)
-#define isa_writew(w,a) writew(w,a)
-#define isa_writel(l,a) writel(l,a)
-
-#define isa_memset_io(a,b,c)     memset_io((a),(b),(c))
-#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c))
-#define isa_memcpy_toio(a,b,c)   memcpy_toio((a),(b),(c))
+#define isa_readb(a) readb(__ISA_IO_base + (a))
+#define isa_readw(a) readw(__ISA_IO_base + (a))
+#define isa_readl(a) readl(__ISA_IO_base + (a))
+#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
+#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
+#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
+#define isa_memset_io(a,b,c)		memset_io(__ISA_IO_base + (a),(b),(c))
+#define isa_memcpy_fromio(a,b,c)	memcpy_fromio((a),__ISA_IO_base + (b),(c))
+#define isa_memcpy_toio(a,b,c)		memcpy_toio(__ISA_IO_base + (a),(b),(c))
 
 /*
  * We don't have csum_partial_copy_fromio() yet, so we cheat here and
@@ -198,6 +257,16 @@
 #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
 #define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(b),(c),(d))
 
+/*
+ *     check_signature         -       find BIOS signatures
+ *     @io_addr: mmio address to check 
+ *     @signature:  signature block
+ *     @length: length of signature
+ *
+ *     Perform a signature comparison with the mmio address io_addr. This
+ *     address should have been obtained by ioremap.
+ *     Returns 1 on a match.
+ */
 static inline int check_signature(unsigned long io_addr,
                                   const unsigned char *signature, int length)
 {
@@ -213,209 +282,177 @@
 out:
 	return retval;
 }
-#define isa_check_signature(io, s, l) check_signature(i,s,l)
 
 /*
- * Talk about misusing macros..
+ *     isa_check_signature             -       find BIOS signatures
+ *     @io_addr: mmio address to check 
+ *     @signature:  signature block
+ *     @length: length of signature
+ *
+ *     Perform a signature comparison with the ISA mmio address io_addr.
+ *     Returns 1 on a match.
+ *
+ *     This function is deprecated. New drivers should use ioremap and
+ *     check_signature.
  */
 
-#define __OUT1(s) \
-extern inline void __out##s(unsigned int value, unsigned int port) {
+static inline int isa_check_signature(unsigned long io_addr,
+	const unsigned char *signature, int length)
+{
+	int retval = 0;
+	do {
+		if (isa_readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+	retval = 1;
+out:
+	return retval;
+}
+
 
-#define __OUT2(m) \
-__asm__ __volatile__ ("s" #m "\t%0,%1(%2)"
-
-#define __OUT(m,s,w) \
-__OUT1(s) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); } \
-__OUT1(s##c) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); } \
-__OUT1(s##_p) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); \
-	SLOW_DOWN_IO; } \
-__OUT1(s##c_p) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); \
-	SLOW_DOWN_IO; }
-
-#define __IN1(t,s) \
-extern __inline__ t __in##s(unsigned int port) { t _v;
-
-/*
- * Required nops will be inserted by the assembler
- */
-#define __IN2(m) \
-__asm__ __volatile__ ("l" #m "\t%0,%1(%2)"
-
-#define __IN(t,m,s,w) \
-__IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return __ioswab##w(_v); } \
-__IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return __ioswab##w(_v); } \
-__IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return __ioswab##w(_v); } \
-__IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return __ioswab##w(_v); }
-
-#define __INS1(s) \
-extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) {
-
-#define __INS2(m) \
-if (count) \
-__asm__ __volatile__ ( \
-	".set\tnoreorder\n\t" \
-	".set\tnoat\n" \
-	"1:\tl" #m "\t$1,%4(%5)\n\t" \
-	"subu\t%1,1\n\t" \
-	"s" #m "\t$1,(%0)\n\t" \
-	"bne\t$0,%1,1b\n\t" \
-	"addiu\t%0,%6\n\t" \
-	".set\tat\n\t" \
-	".set\treorder"
-
-#define __INS(m,s,i) \
-__INS1(s) __INS2(m) \
-	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "i" (0), \
-	  "r" (mips_io_port_base+port), "I" (i) \
-	: "$1");} \
-__INS1(s##c) __INS2(m) \
-	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "ir" (port), \
-	  "r" (mips_io_port_base), "I" (i) \
-	: "$1");}
-
-#define __OUTS1(s) \
-extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) {
-
-#define __OUTS2(m) \
-if (count) \
-__asm__ __volatile__ ( \
-        ".set\tnoreorder\n\t" \
-        ".set\tnoat\n" \
-        "1:\tl" #m "\t$1,(%0)\n\t" \
-        "subu\t%1,1\n\t" \
-        "s" #m "\t$1,%4(%5)\n\t" \
-        "bne\t$0,%1,1b\n\t" \
-        "addiu\t%0,%6\n\t" \
-        ".set\tat\n\t" \
-        ".set\treorder"
-
-#define __OUTS(m,s,i) \
-__OUTS1(s) __OUTS2(m) \
-	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
-	: "$1");} \
-__OUTS1(s##c) __OUTS2(m) \
-	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
-	: "$1");}
-
-__IN(unsigned char,b,b,8)
-__IN(unsigned short,h,w,16)
-__IN(unsigned int,w,l,32)
-
-__OUT(b,b,8)
-__OUT(h,w,16)
-__OUT(w,l,32)
-
-__INS(b,b,1)
-__INS(h,w,2)
-__INS(w,l,4)
-
-__OUTS(b,b,1)
-__OUTS(h,w,2)
-__OUTS(w,l,4)
-
-
-/*
- * Note that due to the way __builtin_constant_p() works, you
- *  - can't use it inside an inline function (it will never be true)
- *  - you don't have to worry about side effects within the __builtin..
- */
-#define outb(val,port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outbc((val),(port)) : \
-	__outb((val),(port)))
-
-#define inb(port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__inbc(port) : \
-	__inb(port))
-
-#define outb_p(val,port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outbc_p((val),(port)) : \
-	__outb_p((val),(port)))
-
-#define inb_p(port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__inbc_p(port) : \
-	__inb_p(port))
-
-#define outw(val,port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outwc((val),(port)) : \
-	__outw((val),(port)))
-
-#define inw(port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__inwc(port) : \
-	__inw(port))
-
-#define outw_p(val,port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outwc_p((val),(port)) : \
-	__outw_p((val),(port)))
-
-#define inw_p(port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__inwc_p(port) : \
-	__inw_p(port))
-
-#define outl(val,port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outlc((val),(port)) : \
-	__outl((val),(port)))
-
-#define inl(port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__inlc(port) : \
-	__inl(port))
-
-#define outl_p(val,port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outlc_p((val),(port)) : \
-	__outl_p((val),(port)))
-
-#define inl_p(port) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__inlc_p(port) : \
-	__inl_p(port))
-
-
-#define outsb(port,addr,count) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outsbc((port),(addr),(count)) : \
-	__outsb ((port),(addr),(count)))
-
-#define insb(port,addr,count) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__insbc((port),(addr),(count)) : \
-	__insb((port),(addr),(count)))
-
-#define outsw(port,addr,count) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outswc((port),(addr),(count)) : \
-	__outsw ((port),(addr),(count)))
-
-#define insw(port,addr,count) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__inswc((port),(addr),(count)) : \
-	__insw((port),(addr),(count)))
-
-#define outsl(port,addr,count) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__outslc((port),(addr),(count)) : \
-	__outsl ((port),(addr),(count)))
-
-#define insl(port,addr,count) \
-((__builtin_constant_p((port)) && (port) < 32768) ? \
-	__inslc((port),(addr),(count)) : \
-	__insl((port),(addr),(count)))
 
-#define IO_SPACE_LIMIT 0xffff
+
+#define outb(val,port)							\
+do {									\
+	*(volatile u8 *)(mips_io_port_base + (port)) = __ioswab8(val);	\
+} while(0)
+
+#define outw(val,port)							\
+do {									\
+	*(volatile u16 *)(mips_io_port_base + (port)) = __ioswab16(val);	\
+} while(0)
+
+#define outl(val,port)							\
+do {									\
+	*(volatile u32 *)(mips_io_port_base + (port)) = __ioswab32(val);\
+} while(0)
+
+#define outb_p(val,port)						\
+do {									\
+	*(volatile u8 *)(mips_io_port_base + (port)) = __ioswab8(val);	\
+	SLOW_DOWN_IO;							\
+} while(0)
+
+#define outw_p(val,port)						\
+do {									\
+	*(volatile u16 *)(mips_io_port_base + (port)) = __ioswab16(val);\
+	SLOW_DOWN_IO;							\
+} while(0)
+
+#define outl_p(val,port)						\
+do {									\
+	*(volatile u32 *)(mips_io_port_base + (port)) = __ioswab32(val);\
+	SLOW_DOWN_IO;							\
+} while(0)
+
+#define inb(port) __inb(port)
+#define inw(port) __inw(port)
+#define inl(port) __inl(port)
+#define inb_p(port) __inb_p(port)
+#define inw_p(port) __inw_p(port)
+#define inl_p(port) __inl_p(port)
+
+static inline unsigned char __inb(unsigned long port)
+{
+	return __ioswab8(*(volatile u8 *)(mips_io_port_base + port));
+}
+
+static inline unsigned short __inw(unsigned long port)
+{
+	return __ioswab16(*(volatile u16 *)(mips_io_port_base + port));
+}
+
+static inline unsigned int __inl(unsigned long port)
+{
+	return __ioswab32(*(volatile u32 *)(mips_io_port_base + port));
+}
+
+static inline unsigned char __inb_p(unsigned long port)
+{
+	u8 __val;
+
+	__val = *(volatile u8 *)(mips_io_port_base + port);
+	SLOW_DOWN_IO;
+
+	return __ioswab8(__val);
+}
+
+static inline unsigned short __inw_p(unsigned long port)
+{
+	u16 __val;
+
+	__val = *(volatile u16 *)(mips_io_port_base + port);
+	SLOW_DOWN_IO;
+
+	return __ioswab16(__val);
+}
+
+static inline unsigned int __inl_p(unsigned long port)
+{
+	u32 __val;
+
+	__val = *(volatile u32 *)(mips_io_port_base + port);
+	SLOW_DOWN_IO;
+	return __ioswab32(__val);
+}
+
+#define outsb(port, addr, count) __outsb(port, addr, count)
+#define insb(port, addr, count) __insb(port, addr, count)
+#define outsw(port, addr, count) __outsw(port, addr, count)
+#define insw(port, addr, count) __insw(port, addr, count)
+#define outsl(port, addr, count) __outsl(port, addr, count)
+#define insl(port, addr, count) __insl(port, addr, count)
+
+static inline void __outsb(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		outb(*(u8 *)addr, port);
+		addr++;
+	}
+}
+
+static inline void __insb(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u8 *)addr = inb(port);
+		addr++;
+	}
+}
+
+static inline void __outsw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		outw(*(u16 *)addr, port);
+		addr += 2;
+	}
+}
+
+static inline void __insw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u16 *)addr = inw(port);
+		addr += 2;
+	}
+}
+
+static inline void __outsl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		outl(*(u32 *)addr, port);
+		addr += 4;
+	}
+}
+
+static inline void __insl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u32 *)addr = inl(port);
+		addr += 4;
+	}
+}
 
 /*
  * The caches on some architectures aren't dma-coherent and have need to
@@ -435,6 +472,8 @@
  *    be discarded.  This operation is necessary before dma operations
  *    to the memory.
  */
+#ifdef CONFIG_NONCOHERENT_IO
+
 extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
 extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
 extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
@@ -443,4 +482,12 @@
 #define dma_cache_wback(start,size)	_dma_cache_wback(start,size)
 #define dma_cache_inv(start,size)	_dma_cache_inv(start,size)
 
+#else /* Sane hardware */
+
+#define dma_cache_wback_inv(start,size)	do { (start); (size); } while (0)
+#define dma_cache_wback(start,size)	do { (start); (size); } while (0)
+#define dma_cache_inv(start,size)	do { (start); (size); } while (0)
+
+#endif /* CONFIG_NONCOHERENT_IO */
+
 #endif /* _ASM_IO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/irq.h linux/include/asm-mips/irq.h
--- linux.orig/include/asm-mips/irq.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/irq.h	2002-07-20 01:08:26.000000000 +0000
@@ -39,4 +39,6 @@
 /* Machine specific interrupt initialization  */
 extern void (*irq_setup)(void);
 
+extern void init_generic_irq(void);
+
 #endif /* _ASM_IRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/irq_cpu.h linux/include/asm-mips/irq_cpu.h
--- linux.orig/include/asm-mips/irq_cpu.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/irq_cpu.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,18 @@
+/*
+ *	include/asm-mips/irq_cpu.h
+ *
+ *	MIPS CPU interrupt definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	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.
+ */
+#ifndef __ASM_MIPS_IRQ_CPU_H
+#define __ASM_MIPS_IRQ_CPU_H
+
+extern void mips_cpu_irq_init(int irq_base);
+
+#endif /* __ASM_MIPS_IRQ_CPU_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/isadep.h linux/include/asm-mips/isadep.h
--- linux.orig/include/asm-mips/isadep.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/isadep.h	2002-07-20 01:08:27.000000000 +0000
@@ -10,7 +10,7 @@
 #ifndef __ASM_ISADEP_H
 #define __ASM_ISADEP_H
 
-#if defined(CONFIG_CPU_R3000)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 /*
  * R2000 or R3000
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/it8172/it8172_int.h linux/include/asm-mips/it8172/it8172_int.h
--- linux.orig/include/asm-mips/it8172/it8172_int.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips/it8172/it8172_int.h	2002-07-20 01:08:25.000000000 +0000
@@ -102,12 +102,10 @@
 #define IT8172_PMER_NMI_IRQ      (IT8172_NMI_IRQ_BASE + 4)
 #define IT8172_POWER_NMI_IRQ     (IT8172_NMI_IRQ_BASE + 5)
 
+#define IT8172_LAST_IRQ          (IT8172_POWER_NMI_IRQ)
 /* Finally, let's move over here the mips cpu timer interrupt.
- * This is more or less strictly for statistics.
  */
-#define MIPS_CPU_TIMER_IRQ       (IT8172_NMI_IRQ_BASE + 6)
-
-#define IT8172_INT_END           MIPS_CPU_TIMER_IRQ
+#define MIPS_CPU_TIMER_IRQ       (NR_IRQS-1)
 
 /* 
  * IT8172 Interrupt Controller Registers
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/jazz.h linux/include/asm-mips/jazz.h
--- linux.orig/include/asm-mips/jazz.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/jazz.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,13 +1,12 @@
-/* $Id: jazz.h,v 1.9 1998/09/19 19:19:37 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1995 - 1998 by Andreas Busse and Ralf Baechle
  */
-#ifndef __ASM_MIPS_JAZZ_H 
-#define __ASM_MIPS_JAZZ_H 
+#ifndef __ASM_JAZZ_H 
+#define __ASM_JAZZ_H 
 
 /*
  * The addresses below are virtual address. The mappings are
@@ -71,7 +70,7 @@
 #define LED_E                   0x9e
 #define LED_F                   0x8e
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 extern __inline__ void pica_set_led(unsigned int bits)
 {
@@ -80,7 +79,7 @@
 	*led_register = bits;
 }
 
-#endif
+#endif /* !__ASSEMBLY__ */
 
 /*
  * Base address of the Sonic Ethernet adapter in Jazz machines.
@@ -101,7 +100,7 @@
 #define JAZZ_KEYBOARD_DATA      0xe0005000
 #define JAZZ_KEYBOARD_COMMAND   0xe0005001
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 typedef struct {
 	unsigned char data;
@@ -120,7 +119,7 @@
  */
 #define keyboard_hardware       jazz_keyboard_hardware
 
-#endif
+#endif /* !__ASSEMBLY__ */
 
 /*
  * i8042 keyboard controller for most other Mips machines.
@@ -153,7 +152,7 @@
 /*
  * DRAM configuration register
  */
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 #ifdef __MIPSEL__
 typedef struct {
 	unsigned int bank2 : 3;
@@ -173,7 +172,7 @@
 	unsigned int bank2 : 3;
 } dram_configuration;
 #endif
-#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* !__ASSEMBLY__ */
 
 #define PICA_DRAM_CONFIG        0xe00fffe0
 
@@ -271,9 +270,9 @@
 /*
  * Access the R4030 DMA and I/O Controller
  */
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
-extern inline void r4030_delay(void)
+static inline void r4030_delay(void)
 {
 __asm__ __volatile__(
 	".set\tnoreorder\n\t"
@@ -284,33 +283,33 @@
 	".set\treorder");
 }
 
-extern inline unsigned short r4030_read_reg16(unsigned addr)
+static inline unsigned short r4030_read_reg16(unsigned addr)
 {
 	unsigned short ret = *((volatile unsigned short *)addr);
 	r4030_delay();
 	return ret;
 }
 
-extern inline unsigned int r4030_read_reg32(unsigned addr)
+static inline unsigned int r4030_read_reg32(unsigned addr)
 {
 	unsigned int ret = *((volatile unsigned int *)addr);
 	r4030_delay();
 	return ret;
 }
 
-extern inline void r4030_write_reg16(unsigned addr, unsigned val)
+static inline void r4030_write_reg16(unsigned addr, unsigned val)
 {
 	*((volatile unsigned short *)addr) = val;
 	r4030_delay();
 }
 
-extern inline void r4030_write_reg32(unsigned addr, unsigned val)
+static inline void r4030_write_reg32(unsigned addr, unsigned val)
 {
 	*((volatile unsigned int *)addr) = val;
 	r4030_delay();
 }
 
-#endif /* !LANGUAGE_ASSEMBLY__ */
+#endif /* !__ASSEMBLY__ */
 
 #define JAZZ_FDC_BASE	0xe0003000
 #define JAZZ_RTC_BASE	0xe0004000
@@ -318,4 +317,4 @@
 
 #define JAZZ_EISA_BASE	0xe3000000
 
-#endif /* __ASM_MIPS_JAZZ_H */
+#endif /* __ASM_JAZZ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/jmr3927/ds1742rtc.h linux/include/asm-mips/jmr3927/ds1742rtc.h
--- linux.orig/include/asm-mips/jmr3927/ds1742rtc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/jmr3927/ds1742rtc.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,68 @@
+/* $Id: ds1742rtc.h,v 1.1 2002/02/27 18:57:58 marcelo Exp $
+ *
+ * ds1742rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
+ *
+ *   Based on include/asm-mips/ds1643rtc.h.
+ *
+ * Copyright (C) 1999-2001 Toshiba Corporation
+ * It was written to be part of the Linux operating system.
+ */
+/* permission is hereby granted to copy, modify and redistribute this code
+ * in terms of the GNU Library General Public License, Version 2 or later,
+ * at your option.
+ */
+#ifndef _DS1742RTC_H
+#define _DS1742RTC_H
+
+#include <linux/rtc.h>
+#include <asm/mc146818rtc.h>	/* bad name... */
+
+#define RTC_BRAM_SIZE		0x800
+#define RTC_OFFSET		0x7f8
+
+/**********************************************************************
+ * register summary
+ **********************************************************************/
+#define RTC_CONTROL		(RTC_OFFSET + 0)
+#define RTC_CENTURY		(RTC_OFFSET + 0)
+#define RTC_SECONDS		(RTC_OFFSET + 1)
+#define RTC_MINUTES		(RTC_OFFSET + 2)
+#define RTC_HOURS		(RTC_OFFSET + 3)
+#define RTC_DAY			(RTC_OFFSET + 4)
+#define RTC_DATE		(RTC_OFFSET + 5)
+#define RTC_MONTH		(RTC_OFFSET + 6)
+#define RTC_YEAR		(RTC_OFFSET + 7)
+
+#define RTC_CENTURY_MASK	0x3f
+#define RTC_SECONDS_MASK	0x7f
+#define RTC_DAY_MASK		0x07
+
+/*
+ * Bits in the Control/Century register
+ */
+#define RTC_WRITE		0x80
+#define RTC_READ		0x40
+
+/*
+ * Bits in the Seconds register
+ */
+#define RTC_STOP		0x80
+
+/*
+ * Bits in the Day register
+ */
+#define RTC_BATT_FLAG		0x80
+#define RTC_FREQ_TEST		0x40
+
+/*
+ * Conversion between binary and BCD.
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+#endif /* _DS1742RTC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/jmr3927/irq.h linux/include/asm-mips/jmr3927/irq.h
--- linux.orig/include/asm-mips/jmr3927/irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/jmr3927/irq.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,60 @@
+/*
+ *  linux/include/asm-mips/tx3927/irq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Toshiba Corporation
+ */
+#ifndef __ASM_TX3927_IRQ_H
+#define __ASM_TX3927_IRQ_H
+
+#ifndef _LANGUAGE_ASSEMBLY
+#include <asm/irq.h>
+
+struct tb_irq_space {
+	struct tb_irq_space* next;
+	int start_irqno;
+	int nr_irqs;
+	void (*mask_func)(int irq_nr, int space_id);
+	void (*unmask_func)(int irq_no, int space_id);
+	const char *name;
+	int space_id;
+	int can_share;
+};
+extern struct tb_irq_space* tb_irq_spaces;
+
+static __inline__ void add_tb_irq_space(struct tb_irq_space* sp)
+{
+	sp->next = tb_irq_spaces;
+	tb_irq_spaces = sp;
+}
+
+
+struct pt_regs;
+extern void
+toshibaboards_spurious(struct pt_regs *regs, int irq);
+extern void
+toshibaboards_irqdispatch(struct pt_regs *regs, int irq);
+
+extern struct irqaction *
+toshibaboards_get_irq_action(int irq);
+extern int
+toshibaboards_setup_irq(int irq, struct irqaction * new);
+
+
+#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
+extern void tx_branch_likely_bug_fixup(struct pt_regs *regs);
+#endif
+
+extern int (*toshibaboards_gen_iack)(void);
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#define NR_ISA_IRQS 16
+#define TB_IRQ_IS_ISA(irq)	\
+	(0 <= (irq) && (irq) < NR_ISA_IRQS)
+#define TB_IRQ_TO_ISA_IRQ(irq)	(irq)
+
+#endif /* __ASM_TX3927_IRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/jmr3927/jmr3927.h linux/include/asm-mips/jmr3927/jmr3927.h
--- linux.orig/include/asm-mips/jmr3927/jmr3927.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/jmr3927/jmr3927.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,323 @@
+/*
+ * Defines for the TJSYS JMR-TX3927/JMI-3927IO2/JMY-1394IF.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ */
+#ifndef __ASM_TX3927_JMR3927_H 
+#define __ASM_TX3927_JMR3927_H 
+
+#include <asm/jmr3927/tx3927.h>
+#include <asm/addrspace.h>
+#include <asm/jmr3927/irq.h>
+#ifndef _LANGUAGE_ASSEMBLY
+#include <asm/system.h>
+#endif
+
+/* CS */
+#define JMR3927_ROMCE0	0x1fc00000	/* 4M */
+#define JMR3927_ROMCE1	0x1e000000	/* 4M */
+#define JMR3927_ROMCE2	0x14000000	/* 16M */
+#define JMR3927_ROMCE3	0x10000000	/* 64M */
+#define JMR3927_ROMCE5	0x1d000000	/* 4M */
+#define JMR3927_SDCS0	0x00000000	/* 32M */
+#define JMR3927_SDCS1	0x02000000	/* 32M */
+/* PCI Direct Mappings */
+
+#define JMR3927_PCIMEM	0x08000000
+#define JMR3927_PCIMEM_SIZE	0x08000000	/* 128M */
+#define JMR3927_PCIIO	0x15000000
+#define JMR3927_PCIIO_SIZE	0x01000000	/* 16M */
+
+#define JMR3927_SDRAM_SIZE	0x02000000	/* 32M */
+#define JMR3927_PORT_BASE	KSEG1
+
+/* select indirect initiator access per errata */
+#define JMR3927_INIT_INDIRECT_PCI 
+#define PCI_ISTAT_IDICC           0x1000
+#define PCI_IPCIBE_IBE_LONG       0
+#define PCI_IPCIBE_ICMD_IOREAD    2 
+#define PCI_IPCIBE_ICMD_IOWRITE   3
+#define PCI_IPCIBE_ICMD_MEMREAD   6 
+#define PCI_IPCIBE_ICMD_MEMWRITE  7
+#define PCI_IPCIBE_ICMD_SHIFT     4 
+
+/* Address map (virtual address) */
+#define JMR3927_ROM0_BASE	(KSEG1 + JMR3927_ROMCE0)
+#define JMR3927_ROM1_BASE	(KSEG1 + JMR3927_ROMCE1)
+#define JMR3927_IOC_BASE	(KSEG1 + JMR3927_ROMCE2)
+#define JMR3927_IOB_BASE	(KSEG1 + JMR3927_ROMCE3)
+#define JMR3927_ISAMEM_BASE	(JMR3927_IOB_BASE)
+#define JMR3927_ISAIO_BASE	(JMR3927_IOB_BASE + 0x01000000)
+#define JMR3927_ISAC_BASE	(JMR3927_IOB_BASE + 0x02000000)
+#define JMR3927_LCDVGA_REG_BASE	(JMR3927_IOB_BASE + 0x03000000)
+#define JMR3927_LCDVGA_MEM_BASE	(JMR3927_IOB_BASE + 0x03800000)
+#define JMR3927_JMY1394_BASE	(KSEG1 + JMR3927_ROMCE5)
+#define JMR3927_PREMIER3_BASE	(JMR3927_JMY1394_BASE + 0x00100000)
+#define JMR3927_PCIMEM_BASE	(KSEG1 + JMR3927_PCIMEM)
+#define JMR3927_PCIIO_BASE	(KSEG1 + JMR3927_PCIIO)
+
+#define JMR3927_IOC_REV_ADDR	(JMR3927_IOC_BASE + 0x00000000)
+#define JMR3927_IOC_NVRAMB_ADDR	(JMR3927_IOC_BASE + 0x00010000)
+#define JMR3927_IOC_LED_ADDR	(JMR3927_IOC_BASE + 0x00020000)
+#define JMR3927_IOC_DIPSW_ADDR	(JMR3927_IOC_BASE + 0x00030000)
+#define JMR3927_IOC_BREV_ADDR	(JMR3927_IOC_BASE + 0x00040000)
+#define JMR3927_IOC_DTR_ADDR	(JMR3927_IOC_BASE + 0x00050000)
+#define JMR3927_IOC_INTS1_ADDR	(JMR3927_IOC_BASE + 0x00080000)
+#define JMR3927_IOC_INTS2_ADDR	(JMR3927_IOC_BASE + 0x00090000)
+#define JMR3927_IOC_INTM_ADDR	(JMR3927_IOC_BASE + 0x000a0000)
+#define JMR3927_IOC_INTP_ADDR	(JMR3927_IOC_BASE + 0x000b0000)
+#define JMR3927_IOC_RESET_ADDR	(JMR3927_IOC_BASE + 0x000f0000)
+
+#define JMR3927_ISAC_REV_ADDR	(JMR3927_ISAC_BASE + 0x00000000)
+#define JMR3927_ISAC_EINTS_ADDR	(JMR3927_ISAC_BASE + 0x00200000)
+#define JMR3927_ISAC_EINTM_ADDR	(JMR3927_ISAC_BASE + 0x00300000)
+#define JMR3927_ISAC_NMI_ADDR	(JMR3927_ISAC_BASE + 0x00400000)
+#define JMR3927_ISAC_LED_ADDR	(JMR3927_ISAC_BASE + 0x00500000)
+#define JMR3927_ISAC_INTP_ADDR	(JMR3927_ISAC_BASE + 0x00800000)
+#define JMR3927_ISAC_INTS1_ADDR	(JMR3927_ISAC_BASE + 0x00900000)
+#define JMR3927_ISAC_INTS2_ADDR	(JMR3927_ISAC_BASE + 0x00a00000)
+#define JMR3927_ISAC_INTM_ADDR	(JMR3927_ISAC_BASE + 0x00b00000)
+
+/* Flash ROM */
+#define JMR3927_FLASH_BASE	(JMR3927_ROM0_BASE)
+#define JMR3927_FLASH_SIZE	0x00400000
+
+/* bits for IOC_REV/IOC_BREV/ISAC_REV (high byte) */
+#define JMR3927_IDT_MASK	0xfc
+#define JMR3927_REV_MASK	0x03
+#define JMR3927_IOC_IDT		0xe0
+#define JMR3927_ISAC_IDT	0x20
+
+/* bits for IOC_INTS1/IOC_INTS2/IOC_INTM/IOC_INTP (high byte) */
+#define JMR3927_IOC_INTB_PCIA	0
+#define JMR3927_IOC_INTB_PCIB	1
+#define JMR3927_IOC_INTB_PCIC	2
+#define JMR3927_IOC_INTB_PCID	3
+#define JMR3927_IOC_INTB_MODEM	4
+#define JMR3927_IOC_INTB_INT6	5
+#define JMR3927_IOC_INTB_INT7	6
+#define JMR3927_IOC_INTB_SOFT	7
+#define JMR3927_IOC_INTF_PCIA	(1 << JMR3927_IOC_INTF_PCIA)
+#define JMR3927_IOC_INTF_PCIB	(1 << JMR3927_IOC_INTB_PCIB)
+#define JMR3927_IOC_INTF_PCIC	(1 << JMR3927_IOC_INTB_PCIC)
+#define JMR3927_IOC_INTF_PCID	(1 << JMR3927_IOC_INTB_PCID)
+#define JMR3927_IOC_INTF_MODEM	(1 << JMR3927_IOC_INTB_MODEM)
+#define JMR3927_IOC_INTF_INT6	(1 << JMR3927_IOC_INTB_INT6)
+#define JMR3927_IOC_INTF_INT7	(1 << JMR3927_IOC_INTB_INT7)
+#define JMR3927_IOC_INTF_SOFT	(1 << JMR3927_IOC_INTB_SOFT)
+
+/* bits for IOC_RESET (high byte) */
+#define JMR3927_IOC_RESET_CPU	1
+#define JMR3927_IOC_RESET_PCI	2
+
+/* bits for ISAC_EINTS/ISAC_EINTM (high byte) */
+#define JMR3927_ISAC_EINTB_IOCHK	2
+#define JMR3927_ISAC_EINTB_BWTH	4
+#define JMR3927_ISAC_EINTF_IOCHK	(1 << JMR3927_ISAC_EINTB_IOCHK)
+#define JMR3927_ISAC_EINTF_BWTH	(1 << JMR3927_ISAC_EINTB_BWTH)
+
+/* bits for ISAC_LED (high byte) */
+#define JMR3927_ISAC_LED_ISALED	0x01
+#define JMR3927_ISAC_LED_USRLED	0x02
+
+/* bits for ISAC_INTS/ISAC_INTM/ISAC_INTP (high byte) */
+#define JMR3927_ISAC_INTB_IRQ5	0
+#define JMR3927_ISAC_INTB_IRQKB	1
+#define JMR3927_ISAC_INTB_IRQMOUSE	2
+#define JMR3927_ISAC_INTB_IRQ4	3
+#define JMR3927_ISAC_INTB_IRQ12	4
+#define JMR3927_ISAC_INTB_IRQ3	5
+#define JMR3927_ISAC_INTB_IRQ10	6
+#define JMR3927_ISAC_INTB_ISAER	7
+#define JMR3927_ISAC_INTF_IRQ5	(1 << JMR3927_ISAC_INTB_IRQ5)
+#define JMR3927_ISAC_INTF_IRQKB	(1 << JMR3927_ISAC_INTB_IRQKB)
+#define JMR3927_ISAC_INTF_IRQMOUSE	(1 << JMR3927_ISAC_INTB_IRQMOUSE)
+#define JMR3927_ISAC_INTF_IRQ4	(1 << JMR3927_ISAC_INTB_IRQ4)
+#define JMR3927_ISAC_INTF_IRQ12	(1 << JMR3927_ISAC_INTB_IRQ12)
+#define JMR3927_ISAC_INTF_IRQ3	(1 << JMR3927_ISAC_INTB_IRQ3)
+#define JMR3927_ISAC_INTF_IRQ10	(1 << JMR3927_ISAC_INTB_IRQ10)
+#define JMR3927_ISAC_INTF_ISAER	(1 << JMR3927_ISAC_INTB_ISAER)
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+#if 0
+#define jmr3927_ioc_reg_out(d, a)	((*(volatile unsigned short *)(a)) = (d) << 8)
+#define jmr3927_ioc_reg_in(a)		(((*(volatile unsigned short *)(a)) >> 8) & 0xff)
+#else
+#if defined(__BIG_ENDIAN)
+#define jmr3927_ioc_reg_out(d, a)	((*(volatile unsigned char *)(a)) = (d))
+#define jmr3927_ioc_reg_in(a)		(*(volatile unsigned char *)(a))
+#elif defined(__LITTLE_ENDIAN)
+#define jmr3927_ioc_reg_out(d, a)	((*(volatile unsigned char *)((a)^1)) = (d))
+#define jmr3927_ioc_reg_in(a)		(*(volatile unsigned char *)((a)^1))
+#else
+#error "No Endian"
+#endif
+#endif
+#define jmr3927_isac_reg_out(d, a)	((*(volatile unsigned char *)(a)) = (d))
+#define jmr3927_isac_reg_in(a)		(*(volatile unsigned char *)(a))
+
+extern inline int jmr3927_have_isac(void)
+{
+	unsigned char idt;
+	unsigned long flags;
+	unsigned long romcr3;
+	save_and_cli(flags);
+	romcr3 = tx3927_romcptr->cr[3];
+	tx3927_romcptr->cr[3] &= 0xffffefff;	/* do not wait infinitely */
+	idt = jmr3927_isac_reg_in(JMR3927_ISAC_REV_ADDR) & JMR3927_IDT_MASK;
+	tx3927_romcptr->cr[3] = romcr3;
+	restore_flags(flags);
+	return idt == JMR3927_ISAC_IDT;
+}
+#define jmr3927_have_nvram() \
+	((jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_IDT_MASK) == JMR3927_IOC_IDT)
+
+/* NVRAM macro */
+#define jmr3927_nvram_in(ofs) \
+	jmr3927_ioc_reg_in(JMR3927_IOC_NVRAMB_ADDR + ((ofs) << 1))
+#define jmr3927_nvram_out(d, ofs) \
+	jmr3927_ioc_reg_out(d, JMR3927_IOC_NVRAMB_ADDR + ((ofs) << 1))
+
+/* LED macro */
+#define jmr3927_led_set(n/*0-16*/)	jmr3927_ioc_reg_out(~(n), JMR3927_IOC_LED_ADDR)
+#define jmr3927_io_led_set(n/*0-3*/)	jmr3927_isac_reg_out((n), JMR3927_ISAC_LED_ADDR)
+
+#define jmr3927_led_and_set(n/*0-16*/)	jmr3927_ioc_reg_out((~(n)) & jmr3927_ioc_reg_in(JMR3927_IOC_LED_ADDR), JMR3927_IOC_LED_ADDR)
+
+/* DIPSW4 macro */
+#define jmr3927_dipsw1()	((tx3927_pioptr->din & (1 << 11)) == 0)
+#define jmr3927_dipsw2()	((tx3927_pioptr->din & (1 << 10)) == 0)
+#define jmr3927_dipsw3()	((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 2) == 0)
+#define jmr3927_dipsw4()	((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 1) == 0)
+#define jmr3927_io_dipsw()	(jmr3927_isac_reg_in(JMR3927_ISAC_LED_ADDR) >> 4)
+
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/*
+ * UART defines for serial.h
+ */
+
+/* use Pre-scaler T0 (1/2) */
+#define JMR3927_BASE_BAUD (JMR3927_IMCLK / 2 / 16)
+
+#define UART0_ADDR   0xfffef300
+#define UART1_ADDR   0xfffef400
+#define UART0_INT    JMR3927_IRQ_IRC_SIO0
+#define UART1_INT    JMR3927_IRQ_IRC_SIO1
+#define UART0_FLAGS  ASYNC_BOOT_AUTOCONF
+#define UART1_FLAGS  0
+
+/*
+ * IRQ mappings
+ */
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an JMR machine.  Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define JMR3927_NR_IRQ_IRC	16	/* On-Chip IRC */
+#define JMR3927_NR_IRQ_IOC	8	/* PCI/MODEM/INT[6:7] */
+#define JMR3927_NR_IRQ_ISAC	8	/* ISA */
+
+
+#define JMR3927_IRQ_IRC	NR_ISA_IRQS
+#define JMR3927_IRQ_IOC	(JMR3927_IRQ_IRC + JMR3927_NR_IRQ_IRC)
+#define JMR3927_IRQ_ISAC	(JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC)
+#define JMR3927_IRQ_END	(JMR3927_IRQ_ISAC + JMR3927_NR_IRQ_ISAC)
+#define JMR3927_IRQ_IS_IRC(irq)	(JMR3927_IRQ_IRC <= (irq) && (irq) < JMR3927_IRQ_IOC)
+#define JMR3927_IRQ_IS_IOC(irq)		(JMR3927_IRQ_IOC <= (irq) && (irq) < JMR3927_IRQ_ISAC)
+#define JMR3927_IRQ_IS_ISAC(irq)	(JMR3927_IRQ_ISAC <= (irq) && (irq) < JMR3927_IRQ_END)
+
+#define JMR3927_IRQ_IRC_INT0	(JMR3927_IRQ_IRC + TX3927_IR_INT0)
+#define JMR3927_IRQ_IRC_INT1	(JMR3927_IRQ_IRC + TX3927_IR_INT1)
+#define JMR3927_IRQ_IRC_INT2	(JMR3927_IRQ_IRC + TX3927_IR_INT2)
+#define JMR3927_IRQ_IRC_INT3	(JMR3927_IRQ_IRC + TX3927_IR_INT3)
+#define JMR3927_IRQ_IRC_INT4	(JMR3927_IRQ_IRC + TX3927_IR_INT4)
+#define JMR3927_IRQ_IRC_INT5	(JMR3927_IRQ_IRC + TX3927_IR_INT5)
+#define JMR3927_IRQ_IRC_SIO0	(JMR3927_IRQ_IRC + TX3927_IR_SIO0)
+#define JMR3927_IRQ_IRC_SIO1	(JMR3927_IRQ_IRC + TX3927_IR_SIO1)
+#define JMR3927_IRQ_IRC_SIO(ch)	(JMR3927_IRQ_IRC + TX3927_IR_SIO(ch))
+#define JMR3927_IRQ_IRC_DMA	(JMR3927_IRQ_IRC + TX3927_IR_DMA)
+#define JMR3927_IRQ_IRC_PIO	(JMR3927_IRQ_IRC + TX3927_IR_PIO)
+#define JMR3927_IRQ_IRC_PCI	(JMR3927_IRQ_IRC + TX3927_IR_PCI)
+#define JMR3927_IRQ_IRC_TMR0	(JMR3927_IRQ_IRC + TX3927_IR_TMR0)
+#define JMR3927_IRQ_IRC_TMR1	(JMR3927_IRQ_IRC + TX3927_IR_TMR1)
+#define JMR3927_IRQ_IRC_TMR2	(JMR3927_IRQ_IRC + TX3927_IR_TMR2)
+#define JMR3927_IRQ_IOC_PCIA	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA)
+#define JMR3927_IRQ_IOC_PCIB	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB)
+#define JMR3927_IRQ_IOC_PCIC	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC)
+#define JMR3927_IRQ_IOC_PCID	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCID)
+#define JMR3927_IRQ_IOC_MODEM	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_MODEM)
+#define JMR3927_IRQ_IOC_INT6	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT6)
+#define JMR3927_IRQ_IOC_INT7	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT7)
+#define JMR3927_IRQ_IOC_SOFT	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_SOFT)
+#define JMR3927_IRQ_ISAC_IRQ5	(JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ5)
+#define JMR3927_IRQ_ISAC_IRQKB	(JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQKB)
+#define JMR3927_IRQ_ISAC_IRQMOUSE	(JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQMOUSE)
+#define JMR3927_IRQ_ISAC_IRQ4	(JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ4)
+#define JMR3927_IRQ_ISAC_IRQ12	(JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ12)
+#define JMR3927_IRQ_ISAC_IRQ3	(JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ3)
+#define JMR3927_IRQ_ISAC_IRQ10	(JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ10)
+#define JMR3927_IRQ_ISAC_ISAER	(JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_ISAER)
+
+#if 0	/* auto detect */
+/* RTL8019AS 10M Ether (JMI-3927IO2:JPW2:1-2 Short) */
+#define JMR3927_IRQ_ETHER1	JMR3927_IRQ_IRC_INT0
+#endif
+/* IOC (PCI, MODEM) */
+#define JMR3927_IRQ_IOCINT	JMR3927_IRQ_IRC_INT1
+/* ISAC (ISA, PCMCIA, KEYBOARD, MOUSE) */
+#define JMR3927_IRQ_ISACINT	JMR3927_IRQ_IRC_INT2
+/* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */
+#define JMR3927_IRQ_ETHER0	JMR3927_IRQ_IRC_INT3
+/* Clock Tick (10ms) */
+#define JMR3927_IRQ_TICK	JMR3927_IRQ_IRC_TMR0
+#define JMR3927_IRQ_IDE		JMR3927_IRQ_ISAC_IRQ12
+
+/* IEEE1394 (Note that this may conflicts with RTL8019AS 10M Ether...) */
+#define JMR3927_IRQ_PREMIER3	JMR3927_IRQ_IRC_INT0
+
+/* I/O Ports */
+/* RTL8019AS 10M Ether */
+#define JMR3927_ETHER1_PORT	(JMR3927_ISAIO_BASE - JMR3927_PORT_BASE + 0x280)
+#define JMR3927_KBD_PORT	(JMR3927_ISAIO_BASE - JMR3927_PORT_BASE + 0x00800060)
+#define JMR3927_IDE_PORT	(JMR3927_ISAIO_BASE - JMR3927_PORT_BASE + 0x001001f0)
+
+/* Clocks */
+#define JMR3927_CORECLK	132710400	/* 132.7MHz */
+#define JMR3927_GBUSCLK	(JMR3927_CORECLK / 2)	/* 66.35MHz */
+#define JMR3927_IMCLK	(JMR3927_CORECLK / 4)	/* 33.17MHz */
+
+#define jmr3927_tmrptr		tx3927_tmrptr(0)	/* TMR0 */
+
+
+/*
+ * TX3927 Pin Configuration:
+ *
+ *	PCFG bits		Avail			Dead
+ *	SELSIO[1:0]:11		RXD[1:0], TXD[1:0]	PIO[6:3]
+ *	SELSIOC[0]:1		CTS[0], RTS[0]		INT[5:4]
+ *	SELSIOC[1]:0,SELDSF:0,	GSDAO[0],GPCST[3]	CTS[1], RTS[1],DSF,
+ *	  GDBGE*					  PIO[2:1]
+ *	SELDMA[2]:1		DMAREQ[2],DMAACK[2]	PIO[13:12]
+ *	SELTMR[2:0]:000					TIMER[1:0]
+ *	SELCS:0,SELDMA[1]:0	PIO[11;10]		SDCS_CE[7:6],
+ *							  DMAREQ[1],DMAACK[1]
+ *	SELDMA[0]:1		DMAREQ[0],DMAACK[0]	PIO[9:8]
+ *	SELDMA[3]:1		DMAREQ[3],DMAACK[3]	PIO[15:14]
+ *	SELDONE:1		DMADONE			PIO[7]
+ *
+ * Usable pins are:
+ *	RXD[1;0],TXD[1:0],CTS[0],RTS[0],
+ *	DMAREQ[0,2,3],DMAACK[0,2,3],DMADONE,PIO[0,10,11]
+ *	INT[3:0]
+ */
+
+#endif /* __ASM_TX3927_JMR3927_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/jmr3927/pci.h linux/include/asm-mips/jmr3927/pci.h
--- linux.orig/include/asm-mips/jmr3927/pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/jmr3927/pci.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,64 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * include/asm-mips/jmr3927/pci.h
+ * Based on include/asm-mips/ddb5xxx/pci.h
+ *
+ * This file essentially defines the interface between board
+ * specific PCI code and MIPS common PCI code.  Should potentially put
+ * into include/asm/pci.h file.
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************
+ */
+
+#ifndef __ASM_TX3927_PCI_H
+#define __ASM_TX3927__PCI_H
+
+#include <linux/ioport.h>
+#include <linux/pci.h>
+
+/*
+ * Each pci channel is a top-level PCI bus seem by CPU.  A machine  with
+ * multiple PCI channels may have multiple PCI host controllers or a
+ * single controller supporting multiple channels.
+ */
+struct pci_channel {
+	struct pci_ops *pci_ops;
+	struct resource *io_resource;
+	struct resource *mem_resource;
+};
+
+/* 
+ * each board defines an array of pci_channels, that ends with all NULL entry
+ */
+extern struct pci_channel mips_pci_channels[];
+
+/*
+ * board supplied pci irq fixup routine
+ */
+extern void pcibios_fixup_irqs(void);
+
+#endif  /* __ASM_TX3927_PCI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/jmr3927/tx3927.h linux/include/asm-mips/jmr3927/tx3927.h
--- linux.orig/include/asm-mips/jmr3927/tx3927.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/jmr3927/tx3927.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,365 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Toshiba Corporation
+ */
+#ifndef __ASM_TX3927_H 
+#define __ASM_TX3927_H 
+
+#include <asm/jmr3927/txx927.h>
+
+#define TX3927_SDRAMC_REG	0xfffe8000
+#define TX3927_ROMC_REG		0xfffe9000
+#define TX3927_DMA_REG		0xfffeb000
+#define TX3927_IRC_REG		0xfffec000
+#define TX3927_PCIC_REG		0xfffed000
+#define TX3927_CCFG_REG		0xfffee000
+#define TX3927_NR_TMR	3
+#define TX3927_TMR_REG(ch)	(0xfffef000 + (ch) * 0x100)
+#define TX3927_NR_SIO	2
+#define TX3927_SIO_REG(ch)	(0xfffef300 + (ch) * 0x100)
+#define TX3927_PIO_REG		0xfffef500
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+struct tx3927_sdramc_reg {
+	volatile unsigned long cr[8];
+	volatile unsigned long tr[3];
+	volatile unsigned long cmd;
+	volatile unsigned long smrs[2];
+};
+
+struct tx3927_romc_reg {
+	volatile unsigned long cr[8];
+};
+
+struct tx3927_dma_reg {
+	struct tx3927_dma_ch_reg {
+		volatile unsigned long cha;
+		volatile unsigned long sar;
+		volatile unsigned long dar;
+		volatile unsigned long cntr;
+		volatile unsigned long sair;
+		volatile unsigned long dair;
+		volatile unsigned long ccr;
+		volatile unsigned long csr;
+	} ch[4];
+	volatile unsigned long dbr[8];
+	volatile unsigned long tdhr;
+	volatile unsigned long mcr;
+	volatile unsigned long unused0;
+};
+
+struct tx3927_irc_reg {
+	volatile unsigned long cer;
+	volatile unsigned long cr[2];
+	volatile unsigned long unused0;
+	volatile unsigned long ilr[8];
+	volatile unsigned long unused1[4];
+	volatile unsigned long imr;
+	volatile unsigned long unused2[7];
+	volatile unsigned long scr;
+	volatile unsigned long unused3[7];
+	volatile unsigned long ssr;
+	volatile unsigned long unused4[7];
+	volatile unsigned long csr;
+};
+
+#include <asm/byteorder.h>
+
+#ifdef __BIG_ENDIAN
+#define endian_def_s2(e1,e2)	\
+	volatile unsigned short e1,e2
+#define endian_def_sb2(e1,e2,e3)	\
+	volatile unsigned short e1;volatile unsigned char e2,e3
+#define endian_def_b2s(e1,e2,e3)	\
+	volatile unsigned char e1,e2;volatile unsigned short e3
+#define endian_def_b4(e1,e2,e3,e4)	\
+	volatile unsigned char e1,e2,e3,e4
+#else
+#define endian_def_s2(e1,e2)	\
+	volatile unsigned short e2,e1
+#define endian_def_sb2(e1,e2,e3)	\
+	volatile unsigned char e3,e2;volatile unsigned short e1
+#define endian_def_b2s(e1,e2,e3)	\
+	volatile unsigned short e3;volatile unsigned char e2,e1
+#define endian_def_b4(e1,e2,e3,e4)	\
+	volatile unsigned char e4,e3,e2,e1
+#endif
+
+struct tx3927_pcic_reg {
+	endian_def_s2(did, vid);
+	endian_def_s2(pcistat, pcicmd);
+	endian_def_b4(cc, scc, rpli, rid);
+	endian_def_b4(unused0, ht, mlt, cls);
+	volatile unsigned long ioba;		/* +10 */
+	volatile unsigned long mba;
+	volatile unsigned long unused1[5];
+	endian_def_s2(svid, ssvid);
+	volatile unsigned long unused2;		/* +30 */
+	endian_def_sb2(unused3, unused4, capptr);
+	volatile unsigned long unused5;
+	endian_def_b4(ml, mg, ip, il);
+	volatile unsigned long unused6;		/* +40 */
+	volatile unsigned long istat;
+	volatile unsigned long iim;
+	volatile unsigned long rrt;
+	volatile unsigned long unused7[3];		/* +50 */
+	volatile unsigned long ipbmma;
+	volatile unsigned long ipbioma;		/* +60 */
+	volatile unsigned long ilbmma;
+	volatile unsigned long ilbioma;
+	volatile unsigned long unused8[9];
+	volatile unsigned long tc;		/* +90 */
+	volatile unsigned long tstat;
+	volatile unsigned long tim;
+	volatile unsigned long tccmd;
+	volatile unsigned long pcirrt;		/* +a0 */
+	volatile unsigned long pcirrt_cmd;
+	volatile unsigned long pcirrdt;
+	volatile unsigned long unused9[3];
+	volatile unsigned long tlboap;
+	volatile unsigned long tlbiap;
+	volatile unsigned long tlbmma;		/* +c0 */
+	volatile unsigned long tlbioma;
+	volatile unsigned long sc_msg;
+	volatile unsigned long sc_be;
+	volatile unsigned long tbl;		/* +d0 */
+	volatile unsigned long unused10[3];
+	volatile unsigned long pwmng;		/* +e0 */
+	volatile unsigned long pwmngs;
+	volatile unsigned long unused11[6];
+	volatile unsigned long req_trace;		/* +100 */
+	volatile unsigned long pbapmc;
+	volatile unsigned long pbapms;
+	volatile unsigned long pbapmim;
+	volatile unsigned long bm;		/* +110 */
+	volatile unsigned long cpcibrs;
+	volatile unsigned long cpcibgs;
+	volatile unsigned long pbacs;
+	volatile unsigned long iobas;		/* +120 */
+	volatile unsigned long mbas;
+	volatile unsigned long lbc;
+	volatile unsigned long lbstat;
+	volatile unsigned long lbim;		/* +130 */
+	volatile unsigned long pcistatim;
+	volatile unsigned long ica;
+	volatile unsigned long icd;
+	volatile unsigned long iiadp;		/* +140 */
+	volatile unsigned long iscdp;
+	volatile unsigned long mmas;
+	volatile unsigned long iomas;
+	volatile unsigned long ipciaddr;		/* +150 */
+	volatile unsigned long ipcidata;
+	volatile unsigned long ipcibe;
+};
+
+struct tx3927_ccfg_reg {
+	volatile unsigned long ccfg;
+	volatile unsigned long crir;
+	volatile unsigned long pcfg;
+	volatile unsigned long tear;
+	volatile unsigned long pdcr;
+};
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/*
+ * SDRAMC
+ */
+
+/*
+ * ROMC
+ */
+
+/*
+ * DMA
+ */
+/* bits for MCR */
+#define TX3927_DMA_MCR_EIS(ch)	(0x10000000<<(ch))
+#define TX3927_DMA_MCR_DIS(ch)	(0x01000000<<(ch))
+#define TX3927_DMA_MCR_RSFIF	0x00000080
+#define TX3927_DMA_MCR_FIFUM(ch)	(0x00000008<<(ch))
+#define TX3927_DMA_MCR_LE	0x00000004
+#define TX3927_DMA_MCR_RPRT	0x00000002
+#define TX3927_DMA_MCR_MSTEN	0x00000001
+
+/* bits for CCRn */
+#define TX3927_DMA_CCR_DBINH	0x04000000
+#define TX3927_DMA_CCR_SBINH	0x02000000
+#define TX3927_DMA_CCR_CHRST	0x01000000
+#define TX3927_DMA_CCR_RVBYTE	0x00800000
+#define TX3927_DMA_CCR_ACKPOL	0x00400000
+#define TX3927_DMA_CCR_REQPL	0x00200000
+#define TX3927_DMA_CCR_EGREQ	0x00100000
+#define TX3927_DMA_CCR_CHDN	0x00080000
+#define TX3927_DMA_CCR_DNCTL	0x00060000
+#define TX3927_DMA_CCR_EXTRQ	0x00010000
+#define TX3927_DMA_CCR_INTRQD	0x0000e000
+#define TX3927_DMA_CCR_INTENE	0x00001000
+#define TX3927_DMA_CCR_INTENC	0x00000800
+#define TX3927_DMA_CCR_INTENT	0x00000400
+#define TX3927_DMA_CCR_CHNEN	0x00000200
+#define TX3927_DMA_CCR_XFACT	0x00000100
+#define TX3927_DMA_CCR_SNOP	0x00000080
+#define TX3927_DMA_CCR_DSTINC	0x00000040
+#define TX3927_DMA_CCR_SRCINC	0x00000020
+#define TX3927_DMA_CCR_XFSZ(order)	(((order) << 2) & 0x0000001c)
+#define TX3927_DMA_CCR_XFSZ_1W	TX3927_DMA_CCR_XFSZ(2)
+#define TX3927_DMA_CCR_XFSZ_4W	TX3927_DMA_CCR_XFSZ(4)
+#define TX3927_DMA_CCR_XFSZ_8W	TX3927_DMA_CCR_XFSZ(5)
+#define TX3927_DMA_CCR_XFSZ_16W	TX3927_DMA_CCR_XFSZ(6)
+#define TX3927_DMA_CCR_XFSZ_32W	TX3927_DMA_CCR_XFSZ(7)
+#define TX3927_DMA_CCR_MEMIO	0x00000002
+#define TX3927_DMA_CCR_ONEAD	0x00000001
+
+/* bits for CSRn */
+#define TX3927_DMA_CSR_CHNACT	0x00000100
+#define TX3927_DMA_CSR_ABCHC	0x00000080
+#define TX3927_DMA_CSR_NCHNC	0x00000040
+#define TX3927_DMA_CSR_NTRNFC	0x00000020
+#define TX3927_DMA_CSR_EXTDN	0x00000010
+#define TX3927_DMA_CSR_CFERR	0x00000008
+#define TX3927_DMA_CSR_CHERR	0x00000004
+#define TX3927_DMA_CSR_DESERR	0x00000002
+#define TX3927_DMA_CSR_SORERR	0x00000001
+
+/*
+ * IRC
+ */
+#define TX3927_IR_MAX_LEVEL	7
+
+/* IRCER : Int. Control Enable */
+#define TX3927_IRCER_ICE	0x00000001
+
+/* IRCR : Int. Control */
+#define TX3927_IRCR_LOW	0x00000000
+#define TX3927_IRCR_HIGH	0x00000001
+#define TX3927_IRCR_DOWN	0x00000002
+#define TX3927_IRCR_UP	0x00000003
+
+/* IRSCR : Int. Status Control */
+#define TX3927_IRSCR_EIClrE	0x00000100
+#define TX3927_IRSCR_EIClr_MASK	0x0000000f
+
+/* IRCSR : Int. Current Status */
+#define TX3927_IRCSR_IF	0x00010000
+#define TX3927_IRCSR_ILV_MASK	0x00000700
+#define TX3927_IRCSR_IVL_MASK	0x0000001f
+
+#define TX3927_IR_INT0	0
+#define TX3927_IR_INT1	1
+#define TX3927_IR_INT2	2
+#define TX3927_IR_INT3	3
+#define TX3927_IR_INT4	4
+#define TX3927_IR_INT5	5
+#define TX3927_IR_SIO0	6
+#define TX3927_IR_SIO1	7
+#define TX3927_IR_SIO(ch)	(6 + (ch))
+#define TX3927_IR_DMA	8
+#define TX3927_IR_PIO	9
+#define TX3927_IR_PCI	10
+#define TX3927_IR_TMR0	13
+#define TX3927_IR_TMR1	14
+#define TX3927_IR_TMR2	15
+#define TX3927_NUM_IR	16
+
+/*
+ * PCIC
+ */
+/* bits for PCICMD */
+/* see PCI_COMMAND_XXX in linux/pci.h */
+
+/* bits for PCISTAT */
+/* see PCI_STATUS_XXX in linux/pci.h */
+#define PCI_STATUS_NEW_CAP	0x0010
+
+/* bits for TC */
+#define TX3927_PCIC_TC_OF16E	0x00000020
+#define TX3927_PCIC_TC_IF8E	0x00000010
+#define TX3927_PCIC_TC_OF8E	0x00000008
+
+/* bits for IOBA/MBA */
+/* see PCI_BASE_ADDRESS_XXX in linux/pci.h */
+
+/* bits for PBAPMC */
+#define TX3927_PCIC_PBAPMC_RPBA	0x00000004
+#define TX3927_PCIC_PBAPMC_PBAEN	0x00000002
+#define TX3927_PCIC_PBAPMC_BMCEN	0x00000001
+
+/* bits for LBSTAT/LBIM */
+#define TX3927_PCIC_LBIM_ALL	0x0000003e
+
+/* bits for PCISTATIM (see also PCI_STATUS_XXX in linux/pci.h */
+#define TX3927_PCIC_PCISTATIM_ALL	0x0000f900
+
+/* bits for LBC */
+#define TX3927_PCIC_LBC_IBSE	0x00004000
+#define TX3927_PCIC_LBC_TIBSE	0x00002000
+#define TX3927_PCIC_LBC_TMFBSE	0x00001000
+#define TX3927_PCIC_LBC_HRST	0x00000800
+#define TX3927_PCIC_LBC_SRST	0x00000400
+#define TX3927_PCIC_LBC_EPCAD	0x00000200
+#define TX3927_PCIC_LBC_MSDSE	0x00000100
+#define TX3927_PCIC_LBC_CRR	0x00000080
+#define TX3927_PCIC_LBC_ILMDE	0x00000040
+#define TX3927_PCIC_LBC_ILIDE	0x00000020
+
+#define TX3927_PCIC_IDSEL_AD_TO_SLOT(ad)	((ad) - 11)
+#define TX3927_PCIC_MAX_DEVNU	TX3927_PCIC_IDSEL_AD_TO_SLOT(32)
+
+/*
+ * CCFG
+ */
+/* CCFG : Chip Configuration */
+#define TX3927_CCFG_TLBOFF	0x00020000
+#define TX3927_CCFG_BEOW	0x00010000
+#define TX3927_CCFG_WR	0x00008000
+#define TX3927_CCFG_TOE	0x00004000
+#define TX3927_CCFG_PCIXARB	0x00002000
+#define TX3927_CCFG_PCI3	0x00001000
+#define TX3927_CCFG_PSNP	0x00000800
+#define TX3927_CCFG_PPRI	0x00000400
+#define TX3927_CCFG_PLLM	0x00000030
+#define TX3927_CCFG_ENDIAN	0x00000004
+#define TX3927_CCFG_HALT	0x00000002
+#define TX3927_CCFG_ACEHOLD	0x00000001
+
+/* PCFG : Pin Configuration */
+#define TX3927_PCFG_SYSCLKEN	0x08000000
+#define TX3927_PCFG_SDRCLKEN_ALL	0x07c00000
+#define TX3927_PCFG_SDRCLKEN(ch)	(0x00400000<<(ch))
+#define TX3927_PCFG_PCICLKEN_ALL	0x003c0000
+#define TX3927_PCFG_PCICLKEN(ch)	(0x00040000<<(ch))
+#define TX3927_PCFG_SELALL	0x0003ffff
+#define TX3927_PCFG_SELCS	0x00020000
+#define TX3927_PCFG_SELDSF	0x00010000
+#define TX3927_PCFG_SELSIOC_ALL	0x0000c000
+#define TX3927_PCFG_SELSIOC(ch)	(0x00004000<<(ch))
+#define TX3927_PCFG_SELSIO_ALL	0x00003000
+#define TX3927_PCFG_SELSIO(ch)	(0x00001000<<(ch))
+#define TX3927_PCFG_SELTMR_ALL	0x00000e00
+#define TX3927_PCFG_SELTMR(ch)	(0x00000200<<(ch))
+#define TX3927_PCFG_SELDONE	0x00000100
+#define TX3927_PCFG_INTDMA_ALL	0x000000f0
+#define TX3927_PCFG_INTDMA(ch)	(0x00000010<<(ch))
+#define TX3927_PCFG_SELDMA_ALL	0x0000000f
+#define TX3927_PCFG_SELDMA(ch)	(0x00000001<<(ch))
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+#define tx3927_sdramcptr	((struct tx3927_sdramc_reg *)TX3927_SDRAMC_REG)
+#define tx3927_romcptr		((struct tx3927_romc_reg *)TX3927_ROMC_REG)
+#define tx3927_dmaptr		((struct tx3927_dma_reg *)TX3927_DMA_REG)
+#define tx3927_ircptr		((struct tx3927_irc_reg *)TX3927_IRC_REG)
+#define tx3927_pcicptr		((struct tx3927_pcic_reg *)TX3927_PCIC_REG)
+#define tx3927_ccfgptr		((struct tx3927_ccfg_reg *)TX3927_CCFG_REG)
+#define tx3927_tmrptr(ch)	((struct txx927_tmr_reg *)TX3927_TMR_REG(ch))
+#define tx3927_sioptr(ch)	((struct txx927_sio_reg *)TX3927_SIO_REG(ch))
+#define tx3927_pioptr		((struct txx927_pio_reg *)TX3927_PIO_REG)
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#endif /* __ASM_TX3927_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/jmr3927/txx927.h linux/include/asm-mips/jmr3927/txx927.h
--- linux.orig/include/asm-mips/jmr3927/txx927.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/jmr3927/txx927.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,175 @@
+/*
+ * Common definitions for TX3927/TX4927
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Toshiba Corporation
+ */
+#ifndef __ASM_TXX927_H 
+#define __ASM_TXX927_H 
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+struct txx927_tmr_reg {
+	volatile unsigned long tcr;
+	volatile unsigned long tisr;
+	volatile unsigned long cpra;
+	volatile unsigned long cprb;
+	volatile unsigned long itmr;
+	volatile unsigned long unused0[3];
+	volatile unsigned long ccdr;
+	volatile unsigned long unused1[3];
+	volatile unsigned long pgmr;
+	volatile unsigned long unused2[3];
+	volatile unsigned long wtmr;
+	volatile unsigned long unused3[43];
+	volatile unsigned long trr;
+};
+
+struct txx927_sio_reg {
+	volatile unsigned long lcr;
+	volatile unsigned long dicr;
+	volatile unsigned long disr;
+	volatile unsigned long cisr;
+	volatile unsigned long fcr;
+	volatile unsigned long flcr;
+	volatile unsigned long bgr;
+	volatile unsigned long tfifo;
+	volatile unsigned long rfifo;
+};
+
+struct txx927_pio_reg {
+	volatile unsigned long dout;
+	volatile unsigned long din;
+	volatile unsigned long dir;
+	volatile unsigned long od;
+	volatile unsigned long flag[2];
+	volatile unsigned long pol;
+	volatile unsigned long intc;
+	volatile unsigned long maskcpu;
+	volatile unsigned long maskext;
+};
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+
+/*
+ * TMR
+ */
+/* TMTCR : Timer Control */
+#define TXx927_TMTCR_TCE	0x00000080
+#define TXx927_TMTCR_CCDE	0x00000040
+#define TXx927_TMTCR_CRE	0x00000020
+#define TXx927_TMTCR_ECES	0x00000008
+#define TXx927_TMTCR_CCS	0x00000004
+#define TXx927_TMTCR_TMODE_MASK	0x00000003
+#define TXx927_TMTCR_TMODE_ITVL	0x00000000
+
+/* TMTISR : Timer Int. Status */
+#define TXx927_TMTISR_TPIBS	0x00000004
+#define TXx927_TMTISR_TPIAS	0x00000002
+#define TXx927_TMTISR_TIIS	0x00000001
+
+/* TMTITMR : Interval Timer Mode */
+#define TXx927_TMTITMR_TIIE	0x00008000
+#define TXx927_TMTITMR_TZCE	0x00000001
+
+/*
+ * SIO
+ */
+/* SILCR : Line Control */
+#define TXx927_SILCR_SCS_MASK	0x00000060
+#define TXx927_SILCR_SCS_IMCLK	0x00000000
+#define TXx927_SILCR_SCS_IMCLK_BG	0x00000020
+#define TXx927_SILCR_SCS_SCLK	0x00000040
+#define TXx927_SILCR_SCS_SCLK_BG	0x00000060
+#define TXx927_SILCR_UEPS	0x00000010
+#define TXx927_SILCR_UPEN	0x00000008
+#define TXx927_SILCR_USBL_MASK	0x00000004
+#define TXx927_SILCR_USBL_1BIT	0x00000004
+#define TXx927_SILCR_USBL_2BIT	0x00000000
+#define TXx927_SILCR_UMODE_MASK	0x00000003
+#define TXx927_SILCR_UMODE_8BIT	0x00000000
+#define TXx927_SILCR_UMODE_7BIT	0x00000001
+
+/* SIDICR : DMA/Int. Control */
+#define TXx927_SIDICR_TDE	0x00008000
+#define TXx927_SIDICR_RDE	0x00004000
+#define TXx927_SIDICR_TIE	0x00002000
+#define TXx927_SIDICR_RIE	0x00001000
+#define TXx927_SIDICR_SPIE	0x00000800
+#define TXx927_SIDICR_CTSAC	0x00000600
+#define TXx927_SIDICR_STIE_MASK	0x0000003f
+#define TXx927_SIDICR_STIE_OERS		0x00000020
+#define TXx927_SIDICR_STIE_CTSS		0x00000010
+#define TXx927_SIDICR_STIE_RBRKD	0x00000008
+#define TXx927_SIDICR_STIE_TRDY		0x00000004
+#define TXx927_SIDICR_STIE_TXALS	0x00000002
+#define TXx927_SIDICR_STIE_UBRKD	0x00000001
+
+/* SIDISR : DMA/Int. Status */
+#define TXx927_SIDISR_UBRK	0x00008000
+#define TXx927_SIDISR_UVALID	0x00004000
+#define TXx927_SIDISR_UFER	0x00002000
+#define TXx927_SIDISR_UPER	0x00001000
+#define TXx927_SIDISR_UOER	0x00000800
+#define TXx927_SIDISR_ERI	0x00000400
+#define TXx927_SIDISR_TOUT	0x00000200
+#define TXx927_SIDISR_TDIS	0x00000100
+#define TXx927_SIDISR_RDIS	0x00000080
+#define TXx927_SIDISR_STIS	0x00000040
+#define TXx927_SIDISR_RFDN_MASK	0x0000001f
+
+/* SICISR : Change Int. Status */
+#define TXx927_SICISR_OERS	0x00000020
+#define TXx927_SICISR_CTSS	0x00000010
+#define TXx927_SICISR_RBRKD	0x00000008
+#define TXx927_SICISR_TRDY	0x00000004
+#define TXx927_SICISR_TXALS	0x00000002
+#define TXx927_SICISR_UBRKD	0x00000001
+
+/* SIFCR : FIFO Control */
+#define TXx927_SIFCR_SWRST	0x00008000
+#define TXx927_SIFCR_RDIL_MASK	0x00000180
+#define TXx927_SIFCR_RDIL_1	0x00000000
+#define TXx927_SIFCR_RDIL_4	0x00000080
+#define TXx927_SIFCR_RDIL_8	0x00000100
+#define TXx927_SIFCR_RDIL_12	0x00000180
+#define TXx927_SIFCR_RDIL_MAX	0x00000180
+#define TXx927_SIFCR_TDIL_MASK	0x00000018
+#define TXx927_SIFCR_TDIL_MASK	0x00000018
+#define TXx927_SIFCR_TDIL_1	0x00000000
+#define TXx927_SIFCR_TDIL_4	0x00000001
+#define TXx927_SIFCR_TDIL_8	0x00000010
+#define TXx927_SIFCR_TDIL_MAX	0x00000010
+#define TXx927_SIFCR_TFRST	0x00000004
+#define TXx927_SIFCR_RFRST	0x00000002
+#define TXx927_SIFCR_FRSTE	0x00000001
+#define TXx927_SIO_TX_FIFO	8
+#define TXx927_SIO_RX_FIFO	16
+
+/* SIFLCR : Flow Control */
+#define TXx927_SIFLCR_RCS	0x00001000
+#define TXx927_SIFLCR_TES	0x00000800
+#define TXx927_SIFLCR_RTSSC	0x00000200
+#define TXx927_SIFLCR_RSDE	0x00000100
+#define TXx927_SIFLCR_TSDE	0x00000080
+#define TXx927_SIFLCR_RTSTL_MASK	0x0000001e
+#define TXx927_SIFLCR_RTSTL_MAX	0x0000001e
+#define TXx927_SIFLCR_TBRK	0x00000001
+
+/* SIBGR : Baudrate Control */
+#define TXx927_SIBGR_BCLK_MASK	0x00000300
+#define TXx927_SIBGR_BCLK_T0	0x00000000
+#define TXx927_SIBGR_BCLK_T2	0x00000100
+#define TXx927_SIBGR_BCLK_T4	0x00000200
+#define TXx927_SIBGR_BCLK_T6	0x00000300
+#define TXx927_SIBGR_BRD_MASK	0x000000ff
+
+/*
+ * PIO
+ */
+
+#endif /* __ASM_TXX927_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/keyboard.h linux/include/asm-mips/keyboard.h
--- linux.orig/include/asm-mips/keyboard.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips/keyboard.h	2002-07-20 01:08:32.000000000 +0000
@@ -3,8 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1999, 2001 Ralf Baechle
- * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 1994 - 1999 Ralf Baechle
  */
 #ifndef _ASM_KEYBOARD_H
 #define _ASM_KEYBOARD_H
@@ -15,7 +14,7 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/kd.h>
-#include <asm/bootinfo.h>
+#include <linux/pm.h>
 
 #define DISABLE_KBD_DURING_INTERRUPTS 0
 
@@ -27,8 +26,9 @@
 			   char raw_mode);
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
-extern int pckbd_rate(struct kbd_repeat *rep);
 extern void pckbd_init_hw(void);
+extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *);
+extern pm_callback pm_kbd_request_override;
 extern unsigned char pckbd_sysrq_xlate[128];
 extern void kbd_forward_char (int ch);
 
@@ -37,23 +37,9 @@
 #define kbd_translate		pckbd_translate
 #define kbd_unexpected_up	pckbd_unexpected_up
 #define kbd_leds		pckbd_leds
-#define kbd_rate		pckbd_rate
 #define kbd_init_hw		pckbd_init_hw
 #define kbd_sysrq_xlate         pckbd_sysrq_xlate
 
-#else
-
-extern int kbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int kbd_getkeycode(unsigned int scancode);
-extern int kbd_translate(unsigned char scancode, unsigned char *keycode,
-	char raw_mode);
-extern char kbd_unexpected_up(unsigned char keycode);
-extern void kbd_leds(unsigned char leds);
-extern void kbd_init_hw(void);
-extern unsigned char *kbd_sysrq_xlate;
-
-#endif
-
 #define SYSRQ_KEY 0x54
 
 /* Some stoneage hardware needs delays after some operations.  */
@@ -89,6 +75,22 @@
 #define kbd_write_command(val) kbd_ops->kbd_write_command(val)
 #define kbd_read_status() kbd_ops->kbd_read_status()
 
+#else
+
+extern int kbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int kbd_getkeycode(unsigned int scancode);
+extern int kbd_translate(unsigned char scancode, unsigned char *keycode,
+	char raw_mode);
+extern char kbd_unexpected_up(unsigned char keycode);
+extern void kbd_leds(unsigned char leds);
+extern void kbd_init_hw(void);
+extern unsigned char *kbd_sysrq_xlate;
+
+extern unsigned char kbd_sysrq_key;
+#define SYSRQ_KEY kbd_sysrq_key
+
+#endif
+
 #endif /* __KERNEL */
 
 #endif /* _ASM_KEYBOARD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/kmap_types.h linux/include/asm-mips/kmap_types.h
--- linux.orig/include/asm-mips/kmap_types.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/kmap_types.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,14 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_IRQ,
+	KM_TYPE_NR
+};
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/linux_logo_dec.h linux/include/asm-mips/linux_logo_dec.h
--- linux.orig/include/asm-mips/linux_logo_dec.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/linux_logo_dec.h	2002-07-20 01:08:36.000000000 +0000
@@ -11,7 +11,6 @@
  
 #include <linux/init.h>
 #include <linux/version.h>
-#include <linux/config.h>
 
 #define linux_logo_banner "Linux/MIPSel version " UTS_RELEASE
 #define LINUX_LOGO_COLORS 183
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/linux_logo_sgi.h linux/include/asm-mips/linux_logo_sgi.h
--- linux.orig/include/asm-mips/linux_logo_sgi.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/linux_logo_sgi.h	2002-07-20 01:08:28.000000000 +0000
@@ -8,10 +8,8 @@
  * Copyright (C) 2001 Jan-Benedict Glaw <jbglaw@lug-owl.de>
  *
  */
- 
 #include <linux/init.h>
 #include <linux/version.h>
-#include <linux/config.h>
 
 #define linux_logo_banner "Linux/MIPS version " UTS_RELEASE
 #define LINUX_LOGO_COLORS 212
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/mc146818rtc.h linux/include/asm-mips/mc146818rtc.h
--- linux.orig/include/asm-mips/mc146818rtc.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/mc146818rtc.h	2002-07-20 01:08:37.000000000 +0000
@@ -16,6 +16,8 @@
 #ifndef RTC_PORT
 #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
 #define RTC_PORT(x)	(0x14014800 + (x))
+#elif defined(CONFIG_MIPS_PB1500)
+#define RTC_PORT(x)	(0xAC000000 + (x))
 #else
 #define RTC_PORT(x)	(0x70 + (x))
 #endif
@@ -52,6 +54,8 @@
 #elif defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
 #include <asm/it8172/it8172_int.h>
 #define RTC_IRQ	IT8172_RTC_IRQ
+#elif defined(CONFIG_MIPS_PB1500)
+#undef RTC_IRQ
 #else
 #define RTC_IRQ	8
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/mips-boards/bonito64.h linux/include/asm-mips/mips-boards/bonito64.h
--- linux.orig/include/asm-mips/mips-boards/bonito64.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/mips-boards/bonito64.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,432 @@
+/*
+ * bonito.h
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2001 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This file is the original bonito.h from Algorithmics with minor changes
+ * to fit into linux.
+ */
+
+/*
+ * Bonito Register Map 
+ * Copyright (c) 1999 Algorithmics Ltd
+ *
+ * Algorithmics gives permission for anyone to use and modify this file
+ * without any obligation or license condition except that you retain
+ * this copyright message in any source redistribution in whole or part.
+ *
+ * Updated copies of this and other files can be found at
+ * ftp://ftp.algor.co.uk/pub/bonito/
+ * 
+ * Users of the Bonito controller are warmly recommended to contribute
+ * any useful changes back to Algorithmics (mail to bonito@algor.co.uk).
+ */
+
+/* Revision 1.48 autogenerated on 08/17/99 15:20:01 */
+/* This bonito64 version editted from bonito.h Revision 1.48 on 11/09/00 */
+
+#ifndef _ASM_MIPS_BOARDS_BONITO64_H
+#define _ASM_MIPS_BOARDS_BONITO64_H
+
+#ifdef __ASSEMBLY__
+
+/* offsets from base register */
+#define BONITO(x)	(x)
+
+#else /* !__ASSEMBLY__ */
+
+/* offsets from base pointer, this construct allows optimisation */
+/* static char * const _bonito = PA_TO_KVA1(BONITO_BASE); */
+#define BONITO(x)		*(volatile u32 *)(_bonito + (x))
+
+#endif /* __ASSEMBLY__ */
+
+
+#define BONITO_BOOT_BASE		0x1fc00000
+#define BONITO_BOOT_SIZE		0x00100000
+#define BONITO_BOOT_TOP 		(BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE		0x1c000000
+#define BONITO_FLASH_SIZE		0x03000000
+#define BONITO_FLASH_TOP		(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE		0x1f800000
+#define BONITO_SOCKET_SIZE		0x00400000
+#define BONITO_SOCKET_TOP		(BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 		0x1fe00000
+#define BONITO_REG_SIZE 		0x00040000
+#define BONITO_REG_TOP			(BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 		0x1ff00000
+#define BONITO_DEV_SIZE 		0x00100000
+#define BONITO_DEV_TOP			(BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE		0x10000000
+#define BONITO_PCILO_SIZE		0x0c000000
+#define BONITO_PCILO_TOP		(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE		0x10000000
+#define BONITO_PCILO1_BASE		0x14000000
+#define BONITO_PCILO2_BASE		0x18000000
+#define BONITO_PCIHI_BASE		0x20000000
+#define BONITO_PCIHI_SIZE		0x20000000
+#define BONITO_PCIHI_TOP		(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE		0x1fd00000
+#define BONITO_PCIIO_SIZE		0x00100000
+#define BONITO_PCIIO_TOP		(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE		0x1fe80000
+#define BONITO_PCICFG_SIZE		0x00080000
+#define BONITO_PCICFG_TOP		(BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+ 
+
+/* Bonito Register Bases */
+
+#define BONITO_PCICONFIGBASE		0x00
+#define BONITO_REGBASE			0x100
+
+
+/* PCI Configuration  Registers */
+
+#define BONITO_PCI_REG(x)               BONITO(BONITO_PCICONFIGBASE + (x))
+#define BONITO_PCIDID			BONITO_PCI_REG(0x00)
+#define BONITO_PCICMD			BONITO_PCI_REG(0x04)
+#define BONITO_PCICLASS 		BONITO_PCI_REG(0x08)
+#define BONITO_PCILTIMER		BONITO_PCI_REG(0x0c)
+#define BONITO_PCIBASE0 		BONITO_PCI_REG(0x10)
+#define BONITO_PCIBASE1 		BONITO_PCI_REG(0x14)
+#define BONITO_PCIBASE2 		BONITO_PCI_REG(0x18)
+#define BONITO_PCIEXPRBASE		BONITO_PCI_REG(0x30)
+#define BONITO_PCIINT			BONITO_PCI_REG(0x3c)
+
+#define BONITO_PCICMD_PERR_CLR		0x80000000
+#define BONITO_PCICMD_SERR_CLR		0x40000000
+#define BONITO_PCICMD_MABORT_CLR	0x20000000
+#define BONITO_PCICMD_MTABORT_CLR	0x10000000
+#define BONITO_PCICMD_TABORT_CLR	0x08000000
+#define BONITO_PCICMD_MPERR_CLR 	0x01000000
+#define BONITO_PCICMD_PERRRESPEN	0x00000040
+#define BONITO_PCICMD_ASTEPEN		0x00000080
+#define BONITO_PCICMD_SERREN		0x00000100
+#define BONITO_PCILTIMER_BUSLATENCY	0x0000ff00
+#define BONITO_PCILTIMER_BUSLATENCY_SHIFT	8
+
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG		BONITO(BONITO_REGBASE + 0x00)
+
+#define BONITO_BONPONCFG_SYSCONTROLLERRD	0x00040000
+#define BONITO_BONPONCFG_ROMCS1SAMP	0x00020000
+#define BONITO_BONPONCFG_ROMCS0SAMP	0x00010000
+#define BONITO_BONPONCFG_CPUBIGEND	0x00004000
+/* Added by RPF 11-9-00 */
+#define BONITO_BONPONCFG_BURSTORDER	0x00001000
+/* --- */
+#define BONITO_BONPONCFG_CPUPARITY	0x00002000
+#define BONITO_BONPONCFG_CPUTYPE	0x00000007
+#define BONITO_BONPONCFG_CPUTYPE_SHIFT	0
+#define BONITO_BONPONCFG_PCIRESET_OUT	0x00000008
+#define BONITO_BONPONCFG_IS_ARBITER	0x00000010
+#define BONITO_BONPONCFG_ROMBOOT	0x000000c0
+#define BONITO_BONPONCFG_ROMBOOT_SHIFT	6
+
+#define BONITO_BONPONCFG_ROMBOOT_FLASH	(0x0<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_SOCKET (0x1<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_SDRAM	(0x2<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_CPURESET	(0x3<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+
+#define BONITO_BONPONCFG_ROMCS0WIDTH	0x00000100
+#define BONITO_BONPONCFG_ROMCS1WIDTH	0x00000200
+#define BONITO_BONPONCFG_ROMCS0FAST	0x00000400
+#define BONITO_BONPONCFG_ROMCS1FAST	0x00000800
+#define BONITO_BONPONCFG_CONFIG_DIS	0x00000020
+
+
+/* Other Bonito configuration */
+
+#define BONITO_BONGENCFG_OFFSET         0x4
+#define BONITO_BONGENCFG		BONITO(BONITO_REGBASE + BONITO_BONGENCFG_OFFSET)
+
+#define BONITO_BONGENCFG_DEBUGMODE	0x00000001
+#define BONITO_BONGENCFG_SNOOPEN	0x00000002
+#define BONITO_BONGENCFG_CPUSELFRESET	0x00000004
+
+#define BONITO_BONGENCFG_FORCE_IRQA	0x00000008
+#define BONITO_BONGENCFG_IRQA_ISOUT	0x00000010
+#define BONITO_BONGENCFG_IRQA_FROM_INT1 0x00000020
+#define BONITO_BONGENCFG_BYTESWAP	0x00000040
+
+#define BONITO_BONGENCFG_UNCACHED	0x00000080
+#define BONITO_BONGENCFG_PREFETCHEN	0x00000100
+#define BONITO_BONGENCFG_WBEHINDEN	0x00000200
+#define BONITO_BONGENCFG_CACHEALG	0x00000c00
+#define BONITO_BONGENCFG_CACHEALG_SHIFT 10
+#define BONITO_BONGENCFG_PCIQUEUE	0x00001000
+#define BONITO_BONGENCFG_CACHESTOP	0x00002000
+#define BONITO_BONGENCFG_MSTRBYTESWAP	0x00004000
+#define BONITO_BONGENCFG_BUSERREN	0x00008000
+#define BONITO_BONGENCFG_NORETRYTIMEOUT 0x00010000
+#define BONITO_BONGENCFG_SHORTCOPYTIMEOUT	0x00020000
+
+/* 2. IO & IDE configuration */
+
+#define BONITO_IODEVCFG 		BONITO(BONITO_REGBASE + 0x08)
+
+/* 3. IO & IDE configuration */
+
+#define BONITO_SDCFG			BONITO(BONITO_REGBASE + 0x0c)
+
+/* 4. PCI address map control */
+
+#define BONITO_PCIMAP			BONITO(BONITO_REGBASE + 0x10)
+#define BONITO_PCIMEMBASECFG		BONITO(BONITO_REGBASE + 0x14)
+#define BONITO_PCIMAP_CFG		BONITO(BONITO_REGBASE + 0x18)
+
+/* 5. ICU & GPIO regs */
+ 
+/* GPIO Regs - r/w */
+
+#define BONITO_GPIODATA_OFFSET          0x1c
+#define BONITO_GPIODATA 		BONITO(BONITO_REGBASE + BONITO_GPIODATA_OFFSET)
+#define BONITO_GPIOIE			BONITO(BONITO_REGBASE + 0x20)
+
+/* ICU Configuration Regs - r/w */
+
+#define BONITO_INTEDGE			BONITO(BONITO_REGBASE + 0x24)
+#define BONITO_INTSTEER 		BONITO(BONITO_REGBASE + 0x28)
+#define BONITO_INTPOL			BONITO(BONITO_REGBASE + 0x2c)
+
+/* ICU Enable Regs - IntEn & IntISR are r/o. */
+
+#define BONITO_INTENSET 		BONITO(BONITO_REGBASE + 0x30)
+#define BONITO_INTENCLR 		BONITO(BONITO_REGBASE + 0x34)
+#define BONITO_INTEN			BONITO(BONITO_REGBASE + 0x38)
+#define BONITO_INTISR			BONITO(BONITO_REGBASE + 0x3c)
+
+/* PCI mail boxes */
+
+#define BONITO_PCIMAIL0_OFFSET          0x40
+#define BONITO_PCIMAIL1_OFFSET          0x44
+#define BONITO_PCIMAIL2_OFFSET          0x48
+#define BONITO_PCIMAIL3_OFFSET          0x4c
+#define BONITO_PCIMAIL0 		BONITO(BONITO_REGBASE + 0x40)
+#define BONITO_PCIMAIL1 		BONITO(BONITO_REGBASE + 0x44)
+#define BONITO_PCIMAIL2 		BONITO(BONITO_REGBASE + 0x48)
+#define BONITO_PCIMAIL3 		BONITO(BONITO_REGBASE + 0x4c)
+
+
+/* 6. PCI cache */
+
+#define BONITO_PCICACHECTRL		BONITO(BONITO_REGBASE + 0x50)
+#define BONITO_PCICACHETAG		BONITO(BONITO_REGBASE + 0x54)
+
+#define BONITO_PCIBADADDR		BONITO(BONITO_REGBASE + 0x58)
+#define BONITO_PCIMSTAT 		BONITO(BONITO_REGBASE + 0x5c)
+
+
+/*
+#define BONITO_PCIRDPOST		BONITO(BONITO_REGBASE + 0x60)
+#define BONITO_PCIDATA			BONITO(BONITO_REGBASE + 0x64)
+*/
+
+/* 7. IDE DMA & Copier */
+ 
+#define BONITO_CONFIGBASE		0x000
+#define BONITO_BONITOBASE		0x100
+#define BONITO_LDMABASE 		0x200
+#define BONITO_COPBASE			0x300
+#define BONITO_REG_BLOCKMASK		0x300
+
+#define BONITO_LDMACTRL 		BONITO(BONITO_LDMABASE + 0x0)
+#define BONITO_LDMASTAT 		BONITO(BONITO_LDMABASE + 0x0)
+#define BONITO_LDMAADDR 		BONITO(BONITO_LDMABASE + 0x4)
+#define BONITO_LDMAGO			BONITO(BONITO_LDMABASE + 0x8)
+#define BONITO_LDMADATA 		BONITO(BONITO_LDMABASE + 0xc)
+
+#define BONITO_COPCTRL			BONITO(BONITO_COPBASE + 0x0)
+#define BONITO_COPSTAT			BONITO(BONITO_COPBASE + 0x0)
+#define BONITO_COPPADDR 		BONITO(BONITO_COPBASE + 0x4)
+#define BONITO_COPDADDR 		BONITO(BONITO_COPBASE + 0x8)
+#define BONITO_COPGO			BONITO(BONITO_COPBASE + 0xc)
+
+
+/* ###### Bit Definitions for individual Registers #### */
+
+/* Gen DMA. */
+
+#define BONITO_IDECOPDADDR_DMA_DADDR	0x0ffffffc
+#define BONITO_IDECOPDADDR_DMA_DADDR_SHIFT	2
+#define BONITO_IDECOPPADDR_DMA_PADDR	0xfffffffc
+#define BONITO_IDECOPPADDR_DMA_PADDR_SHIFT	2
+#define BONITO_IDECOPGO_DMA_SIZE	0x0000fffe
+#define BONITO_IDECOPGO_DMA_SIZE_SHIFT	0
+#define BONITO_IDECOPGO_DMA_WRITE	0x00010000
+#define BONITO_IDECOPGO_DMAWCOUNT	0x000f0000
+#define BONITO_IDECOPGO_DMAWCOUNT_SHIFT	16
+
+#define BONITO_IDECOPCTRL_DMA_STARTBIT	0x80000000
+#define BONITO_IDECOPCTRL_DMA_RSTBIT	0x40000000
+
+/* DRAM - sdCfg */
+
+#define BONITO_SDCFG_AROWBITS		0x00000003
+#define BONITO_SDCFG_AROWBITS_SHIFT	0
+#define BONITO_SDCFG_ACOLBITS		0x0000000c
+#define BONITO_SDCFG_ACOLBITS_SHIFT	2
+#define BONITO_SDCFG_ABANKBIT		0x00000010
+#define BONITO_SDCFG_ASIDES		0x00000020
+#define BONITO_SDCFG_AABSENT		0x00000040
+#define BONITO_SDCFG_AWIDTH64		0x00000080
+
+#define BONITO_SDCFG_BROWBITS		0x00000300
+#define BONITO_SDCFG_BROWBITS_SHIFT	8
+#define BONITO_SDCFG_BCOLBITS		0x00000c00
+#define BONITO_SDCFG_BCOLBITS_SHIFT	10
+#define BONITO_SDCFG_BBANKBIT		0x00001000
+#define BONITO_SDCFG_BSIDES		0x00002000
+#define BONITO_SDCFG_BABSENT		0x00004000
+#define BONITO_SDCFG_BWIDTH64		0x00008000
+
+#define BONITO_SDCFG_EXTRDDATA		0x00010000
+#define BONITO_SDCFG_EXTRASCAS		0x00020000
+#define BONITO_SDCFG_EXTPRECH		0x00040000
+#define BONITO_SDCFG_EXTRASWIDTH	0x00180000
+#define BONITO_SDCFG_EXTRASWIDTH_SHIFT	19
+/* Changed by RPF 11-9-00 */
+#define BONITO_SDCFG_DRAMMODESET	0x00200000
+/* --- */
+#define BONITO_SDCFG_DRAMEXTREGS	0x00400000
+#define BONITO_SDCFG_DRAMPARITY 	0x00800000
+/* Added by RPF 11-9-00 */
+#define BONITO_SDCFG_DRAMBURSTLEN 	0x03000000
+#define BONITO_SDCFG_DRAMBURSTLEN_SHIFT	24
+#define BONITO_SDCFG_DRAMMODESET_DONE 	0x80000000
+/* --- */
+
+/* PCI Cache - pciCacheCtrl */
+
+#define BONITO_PCICACHECTRL_CACHECMD	0x00000007
+#define BONITO_PCICACHECTRL_CACHECMD_SHIFT	0
+#define BONITO_PCICACHECTRL_CACHECMDLINE	0x00000018
+#define BONITO_PCICACHECTRL_CACHECMDLINE_SHIFT	3
+#define BONITO_PCICACHECTRL_CMDEXEC	0x00000020
+
+#define BONITO_IODEVCFG_BUFFBIT_CS0	0x00000001
+#define BONITO_IODEVCFG_SPEEDBIT_CS0	0x00000002
+#define BONITO_IODEVCFG_MOREABITS_CS0	0x00000004
+
+#define BONITO_IODEVCFG_BUFFBIT_CS1	0x00000008
+#define BONITO_IODEVCFG_SPEEDBIT_CS1	0x00000010
+#define BONITO_IODEVCFG_MOREABITS_CS1	0x00000020
+
+#define BONITO_IODEVCFG_BUFFBIT_CS2	0x00000040
+#define BONITO_IODEVCFG_SPEEDBIT_CS2	0x00000080
+#define BONITO_IODEVCFG_MOREABITS_CS2	0x00000100
+
+#define BONITO_IODEVCFG_BUFFBIT_CS3	0x00000200
+#define BONITO_IODEVCFG_SPEEDBIT_CS3	0x00000400
+#define BONITO_IODEVCFG_MOREABITS_CS3	0x00000800
+
+#define BONITO_IODEVCFG_BUFFBIT_IDE	0x00001000
+#define BONITO_IODEVCFG_SPEEDBIT_IDE	0x00002000
+#define BONITO_IODEVCFG_WORDSWAPBIT_IDE 0x00004000
+#define BONITO_IODEVCFG_MODEBIT_IDE	0x00008000
+#define BONITO_IODEVCFG_DMAON_IDE	0x001f0000
+#define BONITO_IODEVCFG_DMAON_IDE_SHIFT 16
+#define BONITO_IODEVCFG_DMAOFF_IDE	0x01e00000
+#define BONITO_IODEVCFG_DMAOFF_IDE_SHIFT	21
+#define BONITO_IODEVCFG_EPROMSPLIT	0x02000000
+/* Added by RPF 11-9-00 */
+#define BONITO_IODEVCFG_CPUCLOCKPERIOD	0xfc000000
+#define BONITO_IODEVCFG_CPUCLOCKPERIOD_SHIFT 26
+/* --- */
+
+/* gpio */
+#define BONITO_GPIO_GPIOW		0x000003ff
+#define BONITO_GPIO_GPIOW_SHIFT 	0
+#define BONITO_GPIO_GPIOR		0x01ff0000
+#define BONITO_GPIO_GPIOR_SHIFT 	16
+#define BONITO_GPIO_GPINR		0xfe000000
+#define BONITO_GPIO_GPINR_SHIFT 	25
+#define BONITO_GPIO_IOW(N)		(1<<(BONITO_GPIO_GPIOW_SHIFT+(N)))
+#define BONITO_GPIO_IOR(N)		(1<<(BONITO_GPIO_GPIOR_SHIFT+(N)))
+#define BONITO_GPIO_INR(N)		(1<<(BONITO_GPIO_GPINR_SHIFT+(N)))
+
+/* ICU */
+#define BONITO_ICU_MBOXES		0x0000000f
+#define BONITO_ICU_MBOXES_SHIFT 	0
+#define BONITO_ICU_DMARDY		0x00000010
+#define BONITO_ICU_DMAEMPTY		0x00000020
+#define BONITO_ICU_COPYRDY		0x00000040
+#define BONITO_ICU_COPYEMPTY		0x00000080
+#define BONITO_ICU_COPYERR		0x00000100
+#define BONITO_ICU_PCIIRQ		0x00000200
+#define BONITO_ICU_MASTERERR		0x00000400
+#define BONITO_ICU_SYSTEMERR		0x00000800
+#define BONITO_ICU_DRAMPERR		0x00001000
+#define BONITO_ICU_RETRYERR		0x00002000
+#define BONITO_ICU_GPIOS		0x01ff0000
+#define BONITO_ICU_GPIOS_SHIFT		16
+#define BONITO_ICU_GPINS		0x7e000000
+#define BONITO_ICU_GPINS_SHIFT		25
+#define BONITO_ICU_MBOX(N)		(1<<(BONITO_ICU_MBOXES_SHIFT+(N)))
+#define BONITO_ICU_GPIO(N)		(1<<(BONITO_ICU_GPIOS_SHIFT+(N)))
+#define BONITO_ICU_GPIN(N)		(1<<(BONITO_ICU_GPINS_SHIFT+(N)))
+
+/* pcimap */
+
+#define BONITO_PCIMAP_PCIMAP_LO0	0x0000003f
+#define BONITO_PCIMAP_PCIMAP_LO0_SHIFT	0
+#define BONITO_PCIMAP_PCIMAP_LO1	0x00000fc0
+#define BONITO_PCIMAP_PCIMAP_LO1_SHIFT	6
+#define BONITO_PCIMAP_PCIMAP_LO2	0x0003f000
+#define BONITO_PCIMAP_PCIMAP_LO2_SHIFT	12
+#define BONITO_PCIMAP_PCIMAP_2		0x00040000
+#define BONITO_PCIMAP_WIN(WIN,ADDR)	((((ADDR)>>26) & BONITO_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
+
+#define BONITO_PCIMAP_WINSIZE           (1<<26)
+#define BONITO_PCIMAP_WINOFFSET(ADDR)	((ADDR) & (BONITO_PCIMAP_WINSIZE - 1))
+#define BONITO_PCIMAP_WINBASE(ADDR)	((ADDR) << 26)
+
+/* pcimembaseCfg */
+
+#define BONITO_PCIMEMBASECFG_MASK               0xf0000000
+#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK	0x0000001f
+#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT	0
+#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS	0x000003e0
+#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT	5
+#define BONITO_PCIMEMBASECFG_MEMBASE0_CACHED	0x00000400
+#define BONITO_PCIMEMBASECFG_MEMBASE0_IO	0x00000800
+
+#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK	0x0001f000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK_SHIFT	12
+#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS	0x003e0000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS_SHIFT	17
+#define BONITO_PCIMEMBASECFG_MEMBASE1_CACHED	0x00400000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_IO	0x00800000
+
+#define BONITO_PCIMEMBASECFG_ASHIFT	23
+#define BONITO_PCIMEMBASECFG_AMASK              0x007fffff
+#define BONITO_PCIMEMBASECFGSIZE(WIN,SIZE)	(((~((SIZE)-1))>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)
+#define BONITO_PCIMEMBASECFGBASE(WIN,BASE)	(((BASE)>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS)
+
+#define BONITO_PCIMEMBASECFG_SIZE(WIN,CFG)  (((((~(CFG)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)) << (BONITO_PCIMEMBASECFG_ASHIFT - BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) | BONITO_PCIMEMBASECFG_AMASK)
+
+
+#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG)  ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG)  ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+#define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN,CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+
+#define BONITO_PCITOPHYS(WIN,ADDR,CFG)          ( \
+                                                  (((ADDR) & (~(BONITO_PCIMEMBASECFG_MASK))) & (~(BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG)))) | \
+                                                  (BONITO_PCIMEMBASECFG_ADDRTRANS(WIN,CFG)) \
+                                                )
+
+/* PCICmd */
+
+#define BONITO_PCICMD_MEMEN		0x00000002
+#define BONITO_PCICMD_MSTREN		0x00000004
+
+
+#endif /* _ASM_MIPS_BOARDS_BONITO64_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/mips-boards/generic.h linux/include/asm-mips/mips-boards/generic.h
--- linux.orig/include/asm-mips/mips-boards/generic.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips/mips-boards/generic.h	2002-07-20 01:08:27.000000000 +0000
@@ -25,14 +25,20 @@
 #ifndef _MIPS_GENERIC_H
 #define _MIPS_GENERIC_H
 
+#include <linux/config.h>
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
+#include <asm/mips-boards/bonito64.h>
 
 /*
  * Display register base.
  */
+#if defined(CONFIG_MIPS_SEAD)
+#define ASCII_DISPLAY_POS_BASE     (KSEG1ADDR(0x1f0005c0))
+#else
 #define ASCII_DISPLAY_WORD_BASE    (KSEG1ADDR(0x1f000410))
 #define ASCII_DISPLAY_POS_BASE     (KSEG1ADDR(0x1f000418))
+#endif
 
 
 /*
@@ -44,8 +50,28 @@
 /*
  * Reset register.
  */
+#if defined(CONFIG_MIPS_SEAD)
+#define SOFTRES_REG       (KSEG1ADDR(0x1e800050))
+#define GORESET           0x4d
+#else
 #define SOFTRES_REG       (KSEG1ADDR(0x1f000500))
 #define GORESET           0x42
+#endif
+
+/*
+ * Revision register.
+ */
+#define MIPS_REVISION_REG                  (KSEG1ADDR(0x1fc00010))
+#define MIPS_REVISION_CORID_QED_RM5261     0
+#define MIPS_REVISION_CORID_CORE_LV        1
+#define MIPS_REVISION_CORID_BONITO64       2
+#define MIPS_REVISION_CORID_CORE_20K       3
+#define MIPS_REVISION_CORID_CORE_FPGA      4
+#define MIPS_REVISION_CORID_CORE_MSC       5
+
+#define MIPS_REVISION_CORID (((*(volatile u32 *)(MIPS_REVISION_REG)) >> 10) & 0x3f)
+
+extern unsigned int mips_revision_corid;
 
 
 /*
@@ -67,4 +93,19 @@
 #define GT_PCI_READ(ofs, data)   \
 	data = *(volatile u32 *)(MIPS_GT_BASE+ofs)
 
+/*
+ * Algorithmics Bonito64 system controller register base.
+ */
+static char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE);
+
+/*
+ * MIPS System controller PCI register base.
+ */
+#define MSC01_PCI_REG_BASE  (KSEG1ADDR(0x1bd00000))
+
+#define MSC_WRITE(reg, data)  \
+	*(volatile u32 *)(reg) = data
+#define MSC_READ(reg, data)   \
+	data = *(volatile u32 *)(reg)
+
 #endif  /* !(_MIPS_GENERIC_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/mips-boards/malta.h linux/include/asm-mips/mips-boards/malta.h
--- linux.orig/include/asm-mips/mips-boards/malta.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips/mips-boards/malta.h	2002-07-20 01:08:26.000000000 +0000
@@ -29,9 +29,12 @@
 #include <asm/io.h>
 
 /* 
- * Malta I/O ports base address. 
-*/
-#define MALTA_PORT_BASE      (KSEG1ADDR(0x18000000))
+ * Malta I/O ports base address for the Galileo GT64120 and Algorithmics
+ * Bonito system controllers. 
+ */
+#define MALTA_GT_PORT_BASE      (KSEG1ADDR(0x18000000))
+#define MALTA_BONITO_PORT_BASE  (KSEG1ADDR(0x1fd00000))
+#define MALTA_MSC_PORT_BASE     (KSEG1ADDR(0x18000000))
 
 /* 
  * Malta RTC-device indirect register access.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/mips-boards/msc01_pci.h linux/include/asm-mips/mips-boards/msc01_pci.h
--- linux.orig/include/asm-mips/mips-boards/msc01_pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/mips-boards/msc01_pci.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,244 @@
+/*
+ * mcs01_pci.h
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ * PCI Register definitions for the MIPS System Controller.
+ */
+#ifndef MSC01_PCI_H
+#define MSC01_PCI_H
+
+/*****************************************************************************
+ * Register offset addresses
+ ****************************************************************************/
+
+#define MSC01_PCI_ID_OFS		0x0000
+#define MSC01_PCI_SC2PMBASL_OFS		0x0208
+#define MSC01_PCI_SC2PMMSKL_OFS		0x0218
+#define MSC01_PCI_SC2PMMAPL_OFS		0x0228
+#define MSC01_PCI_SC2PIOBASL_OFS	0x0248
+#define MSC01_PCI_SC2PIOMSKL_OFS	0x0258
+#define MSC01_PCI_SC2PIOMAPL_OFS	0x0268
+#define MSC01_PCI_P2SCMSKL_OFS		0x0308
+#define MSC01_PCI_P2SCMAPL_OFS		0x0318
+#define MSC01_PCI_INTCFG_OFS		0x0600
+#define MSC01_PCI_INTSTAT_OFS		0x0608
+#define MSC01_PCI_CFGADDR_OFS		0x0610
+#define MSC01_PCI_CFGDATA_OFS		0x0618
+#define MSC01_PCI_IACK_OFS		0x0620
+#define MSC01_PCI_HEAD0_OFS		0x2000  /* DevID, VendorID */
+#define MSC01_PCI_HEAD1_OFS		0x2008  /* Status, Command */
+#define MSC01_PCI_HEAD2_OFS		0x2010  /* Class code, RevID */
+#define MSC01_PCI_HEAD3_OFS		0x2018  /* bist, header, latency */
+#define MSC01_PCI_HEAD4_OFS		0x2020  /* BAR 0 */
+#define MSC01_PCI_HEAD5_OFS		0x2028  /* BAR 1 */
+#define MSC01_PCI_HEAD6_OFS		0x2030  /* BAR 2 */
+#define MSC01_PCI_HEAD7_OFS		0x2038  /* BAR 3 */
+#define MSC01_PCI_HEAD8_OFS		0x2040  /* BAR 4 */
+#define MSC01_PCI_HEAD9_OFS		0x2048  /* BAR 5 */
+#define MSC01_PCI_HEAD10_OFS		0x2050  /* CardBus CIS Ptr */
+#define MSC01_PCI_HEAD11_OFS		0x2058  /* SubSystem ID, -VendorID */
+#define MSC01_PCI_HEAD12_OFS		0x2060  /* ROM BAR */
+#define MSC01_PCI_HEAD13_OFS		0x2068  /* Capabilities ptr */
+#define MSC01_PCI_HEAD14_OFS		0x2070  /* reserved */
+#define MSC01_PCI_HEAD15_OFS		0x2078  /* Maxl, ming, intpin, int */
+#define MSC01_PCI_BAR0_OFS		0x2220
+#define MSC01_PCI_CFG_OFS		0x2380
+#define MSC01_PCI_SWAP_OFS		0x2388
+
+
+/*****************************************************************************
+ * Register encodings
+ ****************************************************************************/
+
+#define MSC01_PCI_ID_ID_SHF		16
+#define MSC01_PCI_ID_ID_MSK		0x00ff0000
+#define MSC01_PCI_ID_ID_HOSTBRIDGE	82
+#define MSC01_PCI_ID_MAR_SHF		8
+#define MSC01_PCI_ID_MAR_MSK		0x0000ff00
+#define MSC01_PCI_ID_MIR_SHF		0
+#define MSC01_PCI_ID_MIR_MSK		0x000000ff
+
+#define MSC01_PCI_SC2PMBASL_BAS_SHF	24
+#define MSC01_PCI_SC2PMBASL_BAS_MSK	0xff000000
+
+#define MSC01_PCI_SC2PMMSKL_MSK_SHF	24
+#define MSC01_PCI_SC2PMMSKL_MSK_MSK	0xff000000
+
+#define MSC01_PCI_SC2PMMAPL_MAP_SHF	24
+#define MSC01_PCI_SC2PMMAPL_MAP_MSK	0xff000000
+
+#define MSC01_PCI_SC2PIOBASL_BAS_SHF	24
+#define MSC01_PCI_SC2PIOBASL_BAS_MSK	0xff000000
+
+#define MSC01_PCI_SC2PIOMSKL_MSK_SHF	24
+#define MSC01_PCI_SC2PIOMSKL_MSK_MSK	0xff000000
+
+#define MSC01_PCI_SC2PIOMAPL_MAP_SHF	24
+#define MSC01_PCI_SC2PIOMAPL_MAP_MSK	0xff000000
+
+#define MSC01_PCI_P2SCMSKL_MSK_SHF	24
+#define MSC01_PCI_P2SCMSKL_MSK_MSK	0xff000000
+
+#define MSC01_PCI_P2SCMAPL_MAP_SHF	24
+#define MSC01_PCI_P2SCMAPL_MAP_MSK	0xff000000
+
+#define MSC01_PCI_INTCFG_RST_SHF        10
+#define MSC01_PCI_INTCFG_RST_MSK        0x00000400
+#define MSC01_PCI_INTCFG_RST_BIT        0x00000400
+#define MSC01_PCI_INTCFG_MWE_SHF        9
+#define MSC01_PCI_INTCFG_MWE_MSK        0x00000200
+#define MSC01_PCI_INTCFG_MWE_BIT        0x00000200
+#define MSC01_PCI_INTCFG_DTO_SHF        8
+#define MSC01_PCI_INTCFG_DTO_MSK        0x00000100
+#define MSC01_PCI_INTCFG_DTO_BIT        0x00000100 
+#define MSC01_PCI_INTCFG_MA_SHF         7
+#define MSC01_PCI_INTCFG_MA_MSK         0x00000080
+#define MSC01_PCI_INTCFG_MA_BIT         0x00000080
+#define MSC01_PCI_INTCFG_TA_SHF         6
+#define MSC01_PCI_INTCFG_TA_MSK         0x00000040
+#define MSC01_PCI_INTCFG_TA_BIT         0x00000040
+#define MSC01_PCI_INTCFG_RTY_SHF        5
+#define MSC01_PCI_INTCFG_RTY_MSK        0x00000020
+#define MSC01_PCI_INTCFG_RTY_BIT        0x00000020
+#define MSC01_PCI_INTCFG_MWP_SHF        4
+#define MSC01_PCI_INTCFG_MWP_MSK        0x00000010
+#define MSC01_PCI_INTCFG_MWP_BIT        0x00000010
+#define MSC01_PCI_INTCFG_MRP_SHF        3
+#define MSC01_PCI_INTCFG_MRP_MSK        0x00000008
+#define MSC01_PCI_INTCFG_MRP_BIT        0x00000008
+#define MSC01_PCI_INTCFG_SWP_SHF        2
+#define MSC01_PCI_INTCFG_SWP_MSK        0x00000004
+#define MSC01_PCI_INTCFG_SWP_BIT        0x00000004
+#define MSC01_PCI_INTCFG_SRP_SHF        1
+#define MSC01_PCI_INTCFG_SRP_MSK        0x00000002
+#define MSC01_PCI_INTCFG_SRP_BIT        0x00000002
+#define MSC01_PCI_INTCFG_SE_SHF         0
+#define MSC01_PCI_INTCFG_SE_MSK         0x00000001
+#define MSC01_PCI_INTCFG_SE_BIT         0x00000001
+
+#define MSC01_PCI_INTSTAT_RST_SHF       10
+#define MSC01_PCI_INTSTAT_RST_MSK       0x00000400
+#define MSC01_PCI_INTSTAT_RST_BIT       0x00000400
+#define MSC01_PCI_INTSTAT_MWE_SHF       9
+#define MSC01_PCI_INTSTAT_MWE_MSK       0x00000200
+#define MSC01_PCI_INTSTAT_MWE_BIT       0x00000200
+#define MSC01_PCI_INTSTAT_DTO_SHF       8
+#define MSC01_PCI_INTSTAT_DTO_MSK       0x00000100
+#define MSC01_PCI_INTSTAT_DTO_BIT       0x00000100 
+#define MSC01_PCI_INTSTAT_MA_SHF        7
+#define MSC01_PCI_INTSTAT_MA_MSK        0x00000080
+#define MSC01_PCI_INTSTAT_MA_BIT        0x00000080
+#define MSC01_PCI_INTSTAT_TA_SHF        6
+#define MSC01_PCI_INTSTAT_TA_MSK        0x00000040
+#define MSC01_PCI_INTSTAT_TA_BIT        0x00000040
+#define MSC01_PCI_INTSTAT_RTY_SHF       5
+#define MSC01_PCI_INTSTAT_RTY_MSK       0x00000020
+#define MSC01_PCI_INTSTAT_RTY_BIT       0x00000020
+#define MSC01_PCI_INTSTAT_MWP_SHF       4
+#define MSC01_PCI_INTSTAT_MWP_MSK       0x00000010
+#define MSC01_PCI_INTSTAT_MWP_BIT       0x00000010
+#define MSC01_PCI_INTSTAT_MRP_SHF       3
+#define MSC01_PCI_INTSTAT_MRP_MSK       0x00000008
+#define MSC01_PCI_INTSTAT_MRP_BIT       0x00000008
+#define MSC01_PCI_INTSTAT_SWP_SHF       2
+#define MSC01_PCI_INTSTAT_SWP_MSK       0x00000004
+#define MSC01_PCI_INTSTAT_SWP_BIT       0x00000004
+#define MSC01_PCI_INTSTAT_SRP_SHF       1
+#define MSC01_PCI_INTSTAT_SRP_MSK       0x00000002
+#define MSC01_PCI_INTSTAT_SRP_BIT       0x00000002
+#define MSC01_PCI_INTSTAT_SE_SHF        0
+#define MSC01_PCI_INTSTAT_SE_MSK        0x00000001
+#define MSC01_PCI_INTSTAT_SE_BIT        0x00000001
+
+#define MSC01_PCI_CFGADDR_BNUM_SHF	16
+#define MSC01_PCI_CFGADDR_BNUM_MSK	0x00ff0000
+#define MSC01_PCI_CFGADDR_DNUM_SHF	11
+#define MSC01_PCI_CFGADDR_DNUM_MSK	0x0000f800
+#define MSC01_PCI_CFGADDR_FNUM_SHF	8
+#define MSC01_PCI_CFGADDR_FNUM_MSK	0x00000700
+#define MSC01_PCI_CFGADDR_RNUM_SHF	2
+#define MSC01_PCI_CFGADDR_RNUM_MSK	0x000000fc
+
+#define MSC01_PCI_CFGDATA_DATA_SHF	0
+#define MSC01_PCI_CFGDATA_DATA_MSK	0xffffffff
+
+/* The defines below are ONLY valid for a MEM bar! */
+#define MSC01_PCI_BAR0_SIZE_SHF	        4
+#define MSC01_PCI_BAR0_SIZE_MSK	        0xfffffff0
+#define MSC01_PCI_BAR0_P_SHF	        3
+#define MSC01_PCI_BAR0_P_MSK	        0x00000008
+#define MSC01_PCI_BAR0_P_BIT	        MSC01_PCI_BAR0_P_MSK
+#define MSC01_PCI_BAR0_D_SHF	        1
+#define MSC01_PCI_BAR0_D_MSK	        0x00000006
+#define MSC01_PCI_BAR0_T_SHF	        0
+#define MSC01_PCI_BAR0_T_MSK	        0x00000001
+#define MSC01_PCI_BAR0_T_BIT	        MSC01_PCI_BAR0_T_MSK
+
+
+#define MSC01_PCI_CFG_RA_SHF	        17
+#define MSC01_PCI_CFG_RA_MSK	        0x00020000
+#define MSC01_PCI_CFG_RA_BIT	        MSC01_PCI_CFG_RA_MSK
+#define MSC01_PCI_CFG_G_SHF	        16
+#define MSC01_PCI_CFG_G_MSK	        0x00010000
+#define MSC01_PCI_CFG_G_BIT	        MSC01_PCI_CFG_G_MSK
+#define MSC01_PCI_CFG_EN_SHF	        15
+#define MSC01_PCI_CFG_EN_MSK	        0x00008000
+#define MSC01_PCI_CFG_EN_BIT	        MSC01_PCI_CFG_EN_MSK
+#define MSC01_PCI_CFG_MAXRTRY_SHF       0
+#define MSC01_PCI_CFG_MAXRTRY_MSK       0x000000ff
+
+#define MSC01_PCI_SWAP_IO_SHF		18
+#define MSC01_PCI_SWAP_IO_MSK		0x000c0000
+#define MSC01_PCI_SWAP_MEM_SHF		16
+#define MSC01_PCI_SWAP_MEM_MSK		0x00030000
+#define MSC01_PCI_SWAP_BAR0_SHF		0
+#define MSC01_PCI_SWAP_BAR0_MSK		0x00000003
+#define MSC01_PCI_SWAP_NOSWAP		0
+#define MSC01_PCI_SWAP_BYTESWAP		1
+
+/*****************************************************************************
+ * Registers absolute addresses
+ ****************************************************************************/
+
+#define MSC01_PCI_ID            (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
+#define MSC01_PCI_SC2PMBASL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
+#define MSC01_PCI_SC2PMMSKL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
+#define MSC01_PCI_SC2PMMAPL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
+#define MSC01_PCI_SC2PIOBASL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
+#define MSC01_PCI_SC2PIOMSKL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
+#define MSC01_PCI_SC2PIOMAPL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
+#define MSC01_PCI_P2SCMSKL      (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
+#define MSC01_PCI_P2SCMAPL      (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
+#define MSC01_PCI_INTCFG        (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
+#define MSC01_PCI_INTSTAT       (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
+#define MSC01_PCI_CFGADDR       (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
+#define MSC01_PCI_CFGDATA       (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
+#define MSC01_PCI_IACK		(MSC01_PCI_REG_BASE + MSC01_PCI_IACK_OFS)
+#define MSC01_PCI_HEAD0		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD0_OFS)
+#define MSC01_PCI_HEAD1		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD1_OFS)
+#define MSC01_PCI_HEAD2		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD2_OFS)
+#define MSC01_PCI_HEAD3		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD3_OFS)
+#define MSC01_PCI_HEAD4		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD4_OFS)
+#define MSC01_PCI_HEAD5		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD5_OFS)
+#define MSC01_PCI_HEAD6		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD6_OFS)
+#define MSC01_PCI_HEAD7		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD7_OFS)
+#define MSC01_PCI_HEAD8		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD8_OFS)
+#define MSC01_PCI_HEAD9		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD9_OFS)
+#define MSC01_PCI_HEAD10	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD10_OFS)
+#define MSC01_PCI_HEAD11	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD12	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD13	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD14	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD15        (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_BAR0		(MSC01_PCI_REG_BASE + MSC01_PCI_BAR0_OFS)
+#define MSC01_PCI_CFG		(MSC01_PCI_REG_BASE + MSC01_PCI_CFG_OFS)
+#define MSC01_PCI_SWAP		(MSC01_PCI_REG_BASE + MSC01_PCI_SWAP_OFS)
+
+#endif
+/*****************************************************************************
+ *  End of msc01_pci.h
+ *****************************************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/mips32_cache.h linux/include/asm-mips/mips32_cache.h
--- linux.orig/include/asm-mips/mips32_cache.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/mips32_cache.h	2002-07-20 01:08:39.000000000 +0000
@@ -35,7 +35,7 @@
 #include <asm/asm.h>
 #include <asm/cacheops.h>
 
-extern inline void flush_icache_line_indexed(unsigned long addr)
+static inline void flush_icache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -48,7 +48,7 @@
 		  "i" (Index_Invalidate_I));
 }
 
-extern inline void flush_dcache_line_indexed(unsigned long addr)
+static inline void flush_dcache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -61,7 +61,7 @@
 		  "i" (Index_Writeback_Inv_D));
 }
 
-extern inline void flush_scache_line_indexed(unsigned long addr)
+static inline void flush_scache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -74,7 +74,7 @@
 		  "i" (Index_Writeback_Inv_SD));
 }
 
-extern inline void flush_icache_line(unsigned long addr)
+static inline void flush_icache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -87,7 +87,7 @@
 		  "i" (Hit_Invalidate_I));
 }
 
-extern inline void flush_dcache_line(unsigned long addr)
+static inline void flush_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -100,7 +100,7 @@
 		  "i" (Hit_Writeback_Inv_D));
 }
 
-extern inline void invalidate_dcache_line(unsigned long addr)
+static inline void invalidate_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -113,7 +113,7 @@
 		  "i" (Hit_Invalidate_D));
 }
 
-extern inline void invalidate_scache_line(unsigned long addr)
+static inline void invalidate_scache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -126,7 +126,7 @@
 		  "i" (Hit_Invalidate_SD));
 }
 
-extern inline void flush_scache_line(unsigned long addr)
+static inline void flush_scache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -142,7 +142,7 @@
 /*
  * The next two are for badland addresses like signal trampolines.
  */
-extern inline void protected_flush_icache_line(unsigned long addr)
+static inline void protected_flush_icache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -158,7 +158,7 @@
 		  "i" (Hit_Invalidate_I));
 }
 
-extern inline void protected_writeback_dcache_line(unsigned long addr)
+static inline void protected_writeback_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -186,7 +186,7 @@
 		  "i" (op));
 
 
-extern inline void blast_dcache(void)
+static inline void blast_dcache(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + dcache_size);
@@ -197,7 +197,7 @@
 	}
 }
 
-extern inline void blast_dcache_page(unsigned long page)
+static inline void blast_dcache_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -208,7 +208,7 @@
 	}
 }
 
-extern inline void blast_dcache_page_indexed(unsigned long page)
+static inline void blast_dcache_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -219,7 +219,7 @@
 	}
 }
 
-extern inline void blast_icache(void)
+static inline void blast_icache(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + icache_size);
@@ -230,7 +230,7 @@
 	}
 }
 
-extern inline void blast_icache_page(unsigned long page)
+static inline void blast_icache_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -241,7 +241,7 @@
 	}
 }
 
-extern inline void blast_icache_page_indexed(unsigned long page)
+static inline void blast_icache_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -252,7 +252,7 @@
 	}
 }
 
-extern inline void blast_scache(void)
+static inline void blast_scache(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -263,7 +263,7 @@
 	}
 }
 
-extern inline void blast_scache_page(unsigned long page)
+static inline void blast_scache_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -274,7 +274,7 @@
 	}
 }
 
-extern inline void blast_scache_page_indexed(unsigned long page)
+static inline void blast_scache_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/mipsregs.h linux/include/asm-mips/mipsregs.h
--- linux.orig/include/asm-mips/mipsregs.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/mipsregs.h	2002-07-20 01:08:37.000000000 +0000
@@ -12,6 +12,7 @@
 #ifndef _ASM_MIPSREGS_H
 #define _ASM_MIPSREGS_H
 
+#include <linux/config.h>
 #include <linux/linkage.h>
 
 /*
@@ -52,12 +53,15 @@
 #define CP0_XCONTEXT $20
 #define CP0_FRAMEMASK $21
 #define CP0_DIAGNOSTIC $22
+#define CP0_DEBUG $23
+#define CP0_DEPC $24
 #define CP0_PERFORMANCE $25
 #define CP0_ECC $26
 #define CP0_CACHEERR $27
 #define CP0_TAGLO $28
 #define CP0_TAGHI $29
 #define CP0_ERROREPC $30
+#define CP0_DESAVE $31
 
 /*
  * R4640/R4650 cp0 register names.  These registers are listed
@@ -79,6 +83,12 @@
 #define CP0_S1_DERRADDR0  $26
 #define CP0_S1_DERRADDR1  $27
 #define CP0_S1_INTCONTROL $20
+
+/*
+ *  TX39 Series
+ */
+#define CP0_TX39_CACHE	$7
+
 /*
  * Coprocessor 1 (FPU) register names
  */
@@ -140,102 +150,42 @@
 /*
  * Values for PageMask register
  */
-#include <linux/config.h>
 #ifdef CONFIG_CPU_VR41XX
-#define PM_1K   0x00000000
-#define PM_4K   0x00001800
-#define PM_16K  0x00007800
-#define PM_64K  0x0001f800
-#define PM_256K 0x0007f800
-#else
-#define PM_4K   0x00000000
-#define PM_16K  0x00006000
-#define PM_64K  0x0001e000
-#define PM_256K 0x0007e000
-#define PM_1M   0x001fe000
-#define PM_4M   0x007fe000
-#define PM_16M  0x01ffe000
-#endif
-
-/*
- * Values used for computation of new tlb entries
- */
-#define PL_4K   12
-#define PL_16K  14
-#define PL_64K  16
-#define PL_256K 18
-#define PL_1M   20
-#define PL_4M   22
-#define PL_16M  24
-
-/*
- * Macros to access the system control coprocessor
- */
-#define read_32bit_cp0_register(source)                         \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-	".set\tpush\n\t"					\
-	".set\treorder\n\t"					\
-        "mfc0\t%0,"STR(source)"\n\t"                            \
-	".set\tpop"						\
-        : "=r" (__res));                                        \
-        __res;})
 
-#define read_32bit_cp0_set1_register(source)                    \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-	".set\tpush\n\t"					\
-	".set\treorder\n\t"					\
-        "cfc0\t%0,"STR(source)"\n\t"                            \
-	".set\tpop"						\
-        : "=r" (__res));                                        \
-        __res;})
+/* Why doesn't stupidity hurt ... */
 
-/*
- * For now use this only with interrupts disabled!
- */
-#define read_64bit_cp0_register(source)                         \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-        ".set\tmips3\n\t"                                       \
-        "dmfc0\t%0,"STR(source)"\n\t"                           \
-        ".set\tmips0"                                           \
-        : "=r" (__res));                                        \
-        __res;})
+#define PM_1K		0x00000000
+#define PM_4K		0x00001800
+#define PM_16K		0x00007800
+#define PM_64K		0x0001f800
+#define PM_256K		0x0007f800
 
-#define write_32bit_cp0_register(register,value)                \
-        __asm__ __volatile__(                                   \
-        "mtc0\t%0,"STR(register)"\n\t"				\
-	"nop"							\
-        : : "r" (value));
+#else
 
-#define write_32bit_cp0_set1_register(register,value)           \
-        __asm__ __volatile__(                                   \
-        "ctc0\t%0,"STR(register)"\n\t"				\
-	"nop"							\
-        : : "r" (value));
+#define PM_4K		0x00000000
+#define PM_16K		0x00006000
+#define PM_64K		0x0001e000
+#define PM_256K		0x0007e000
+#define PM_1M		0x001fe000
+#define PM_4M		0x007fe000
+#define PM_16M		0x01ffe000
+#define PM_64M		0x07ffe000
+#define PM_256M		0x1fffe000
 
-#define write_64bit_cp0_register(register,value)                \
-        __asm__ __volatile__(                                   \
-        ".set\tmips3\n\t"                                       \
-        "dmtc0\t%0,"STR(register)"\n\t"                         \
-        ".set\tmips0"                                           \
-        : : "r" (value))
+#endif
 
-/* 
- * This should be changed when we get a compiler that support the MIPS32 ISA. 
+/*
+ * Values used for computation of new tlb entries
  */
-#define read_mips32_cp0_config1()                               \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-	".set\tnoreorder\n\t"                                   \
-	".set\tnoat\n\t"                                        \
-     	".word\t0x40018001\n\t"                                 \
-	"move\t%0,$1\n\t"                                       \
-	".set\tat\n\t"                                          \
-	".set\treorder"                                         \
-	:"=r" (__res));                                         \
-        __res;})
+#define PL_4K		12
+#define PL_16K		14
+#define PL_64K		16
+#define PL_256K		18
+#define PL_1M		20
+#define PL_4M		22
+#define PL_16M		24
+#define PL_64M		26
+#define PL_256M		28
 
 /*
  * R4x00 interrupt enable / cause bits
@@ -261,56 +211,6 @@
 #define C_IRQ4          (1<<14)
 #define C_IRQ5          (1<<15)
 
-#ifndef _LANGUAGE_ASSEMBLY
-/*
- * Manipulate the status register.
- * Mostly used to access the interrupt bits.
- */
-#define __BUILD_SET_CP0(name,register)                          \
-extern __inline__ unsigned int                                  \
-set_cp0_##name(unsigned int set)				\
-{                                                               \
-	unsigned int res;                                       \
-                                                                \
-	res = read_32bit_cp0_register(register);                \
-	res |= set;						\
-	write_32bit_cp0_register(register, res);        	\
-                                                                \
-	return res;                                             \
-}								\
-								\
-extern __inline__ unsigned int                                  \
-clear_cp0_##name(unsigned int clear)				\
-{                                                               \
-	unsigned int res;                                       \
-                                                                \
-	res = read_32bit_cp0_register(register);                \
-	res &= ~clear;						\
-	write_32bit_cp0_register(register, res);		\
-                                                                \
-	return res;                                             \
-}								\
-								\
-extern __inline__ unsigned int                                  \
-change_cp0_##name(unsigned int change, unsigned int new)	\
-{                                                               \
-	unsigned int res;                                       \
-                                                                \
-	res = read_32bit_cp0_register(register);                \
-	res &= ~change;                                         \
-	res |= (new & change);                                  \
-	if(change)                                              \
-		write_32bit_cp0_register(register, res);        \
-                                                                \
-	return res;                                             \
-}
-
-__BUILD_SET_CP0(status,CP0_STATUS)
-__BUILD_SET_CP0(cause,CP0_CAUSE)
-__BUILD_SET_CP0(config,CP0_CONFIG)
-
-#endif /* defined (_LANGUAGE_ASSEMBLY) */
-
 /*
  * Bitfields in the R4xx0 cp0 status register
  */
@@ -419,6 +319,7 @@
 #define  STATUSF_IP15		(1   << 7)
 #define ST0_CH			0x00040000
 #define ST0_SR			0x00100000
+#define ST0_TS			0x00200000
 #define ST0_BEV			0x00400000
 #define ST0_RE			0x02000000
 #define ST0_FR			0x04000000
@@ -480,6 +381,14 @@
 #define CONF_HALT                       (1 << 25)
 
 /*
+ * Bits in the TX49 coprozessor 0 config register.
+ */
+#define TX49_CONF_DC			(1 << 16)
+#define TX49_CONF_IC			(1 << 17)  /* conflict with CONF_SC */
+#define TX49_CONF_HALT			(1 << 18)
+#define TX49_CONF_CWFON			(1 << 27)
+
+/*
  * R10000 performance counter definitions.
  *
  * FIXME: The R10000 performance counter opens a nice way to implement CPU
@@ -535,4 +444,584 @@
 #define CEB_KERNEL	2	/* Count events in kernel mode EXL = ERL = 0 */
 #define CEB_EXL		1	/* Count events with EXL = 1, ERL = 0 */
 
+#ifndef __ASSEMBLY__
+
+/*
+ * Functions to access the r10k performance counter and control registers
+ */
+#define read_r10k_perf_cntr(counter)                            \
+({ unsigned int __res;                                          \
+        __asm__ __volatile__(                                   \
+        "mfpc\t%0, "STR(counter)                                \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define write_r10k_perf_cntr(counter,val)                       \
+        __asm__ __volatile__(                                   \
+        "mtpc\t%0, "STR(counter)                                \
+        : : "r" (val));
+
+#define read_r10k_perf_cntl(counter)                            \
+({ unsigned int __res;                                          \
+        __asm__ __volatile__(                                   \
+        "mfps\t%0, "STR(counter)                                \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define write_r10k_perf_cntl(counter,val)                       \
+        __asm__ __volatile__(                                   \
+        "mtps\t%0, "STR(counter)                                \
+        : : "r" (val));
+
+/*
+ * Macros to access the system control coprocessor
+ */
+#define read_32bit_cp0_register(source)                         \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+	".set\tpush\n\t"					\
+	".set\treorder\n\t"					\
+        "mfc0\t%0,"STR(source)"\n\t"                            \
+	".set\tpop"						\
+        : "=r" (__res));                                        \
+        __res;})
+
+#define read_32bit_cp0_set1_register(source)                    \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+	".set\tpush\n\t"					\
+	".set\treorder\n\t"					\
+        "cfc0\t%0,"STR(source)"\n\t"                            \
+	".set\tpop"						\
+        : "=r" (__res));                                        \
+        __res;})
+
+/*
+ * For now use this only with interrupts disabled!
+ */
+#define read_64bit_cp0_register(source)                         \
+({ unsigned long __res;                                         \
+        __asm__ __volatile__(                                   \
+        ".set\tmips3\n\t"                                       \
+        "dmfc0\t%0,"STR(source)"\n\t"                           \
+        ".set\tmips0"                                           \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define write_32bit_cp0_register(register,value)                \
+        __asm__ __volatile__(                                   \
+        "mtc0\t%0,"STR(register)"\n\t"				\
+	"nop"							\
+        : : "r" (value));
+
+#define write_32bit_cp0_set1_register(register,value)           \
+        __asm__ __volatile__(                                   \
+        "ctc0\t%0,"STR(register)"\n\t"				\
+	"nop"							\
+        : : "r" (value));
+
+#define write_64bit_cp0_register(register,value)                \
+        __asm__ __volatile__(                                   \
+        ".set\tmips3\n\t"                                       \
+        "dmtc0\t%0,"STR(register)"\n\t"                         \
+        ".set\tmips0"                                           \
+        : : "r" (value))
+
+/* 
+ * This should be changed when we get a compiler that support the MIPS32 ISA. 
+ */
+#define read_mips32_cp0_config1()                               \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+	".set\tnoreorder\n\t"                                   \
+	".set\tnoat\n\t"                                        \
+	"#.set\tmips64\n\t"					\
+	"#mfc0\t$1, $16, 1\n\t"					\
+	"#.set\tmips0\n\t"					\
+     	".word\t0x40018001\n\t"                                 \
+	"move\t%0,$1\n\t"                                       \
+	".set\tat\n\t"                                          \
+	".set\treorder"                                         \
+	:"=r" (__res));                                         \
+        __res;})
+
+/*
+ * Macros to access the floating point coprocessor control registers
+ */
+#define read_32bit_cp1_register(source)                         \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+	".set\tpush\n\t"					\
+	".set\treorder\n\t"					\
+        "cfc1\t%0,"STR(source)"\n\t"                            \
+	".set\tpop"						\
+        : "=r" (__res));                                        \
+        __res;})
+
+/* TLB operations. */
+static inline void tlb_probe(void)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"tlbp\n\t"
+		".set pop");
+}
+
+static inline void tlb_read(void)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"tlbr\n\t"
+		".set pop");
+}
+
+static inline void tlb_write_indexed(void)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"tlbwi\n\t"
+		".set pop");
+}
+
+static inline void tlb_write_random(void)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"tlbwr\n\t"
+		".set pop");
+}
+
+/* Dealing with various CP0 mmu/cache related registers. */
+
+
+static inline unsigned long get_pagemask(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $5\n\t"
+		".set pop"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_pagemask(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $5\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && !defined(CONFIG_CPU_MIPS32)
+
+/*
+ * These versions are only needed for systems with more than 38 bits of
+ * physical address space.
+ */
+static inline void set_entrylo0(unsigned long long val)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	__asm__ __volatile__(
+		".set\tmips3\n\t"
+		"dsll\t%L0, %L0, 32\n\t"
+		"dsrl\t%L0, %L0, 32\n\t"
+		"dsll\t%M0, %M0, 32\n\t"
+		"or\t%L0, %L0, %M0\n\t"
+		"dmtc0\t%L0, $2\n\t"
+		".set\tmips0"
+		: : "r" (val));
+	__restore_flags(flags);
+}
+
+static inline void set_entrylo1(unsigned long long val)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	__asm__ __volatile__(
+		".set\tmips3\n\t"
+		"dsll\t%L0, %L0, 32\n\t"
+		"dsrl\t%L0, %L0, 32\n\t"
+		"dsll\t%M0, %M0, 32\n\t"
+		"or\t%L0, %L0, %M0\n\t"
+		"dmtc0\t%L0, $3\n\t"
+		".set\tmips0"
+		: : "r" (val));
+	__restore_flags(flags);
+}
+
+static inline unsigned long long get_entrylo0(void)
+{
+	unsigned long flags, val;
+
+	__save_and_cli(flags);
+	__asm__ __volatile__(
+		".set\tmips3\n\t"
+		"dmfc0\t%M0, $2\n\t"
+		"dsll\t%L0, %M0, 32\n\t"
+		"dsrl\t%M0, %M0, 32\n\t"
+		"dsrl\t%L0, %L0, 32\n\t"
+		".set\tmips0"
+		: "=r" (val));
+	__restore_flags(flags);
+
+	return val;
+}
+
+static inline unsigned long long get_entrylo1(void)
+{
+	unsigned long flags, val;
+
+	__save_and_cli(flags);
+	__asm__ __volatile__(
+		".set\tmips3\n\t"
+		"dmfc0\t%M0, $3\n\t"
+		"dsrl\t%L0, %M0, 32\n\t"
+		"dsrl\t%M0, %M0, 32\n\t"
+		"dsll\t%L0, %L0, 32\n\t"
+		".set\tmips0"
+		: "=r" (val));
+	__restore_flags(flags);
+
+	return val;
+}
+
+#else
+
+static inline void set_entrylo0(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $2\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+static inline void set_entrylo1(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $3\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_entrylo0(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $2\n\t"
+		".set pop" : "=r" (val));
+
+	return val;
+}
+
+static inline unsigned long get_entrylo1(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $3\n\t"
+		".set pop" : "=r" (val));
+
+	return val;
+}
+
+#endif
+
+/* CP0_ENTRYHI register */
+static inline unsigned long get_entryhi(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $10\n\t"
+		".set pop"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void set_entryhi(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $10\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+/* CP0_INDEX register */
+static inline unsigned long get_index(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $0\n\t"
+		".set pop"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_index(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $0\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+/* CP0_WIRED register */
+static inline unsigned long get_wired(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $6\n\t"
+		".set pop"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_wired(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $6\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+/* CP0_STATUS register */
+static inline unsigned int get_status(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $12\n\t"
+		".set pop"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_status(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $12\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_info(void)
+{
+	unsigned long val;
+
+	__asm__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $7\n\t"
+		".set pop"
+		: "=r" (val));
+	return val;
+}
+
+/* CP0_TAGLO and CP0_TAGHI registers */
+static inline unsigned long get_taglo(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $28\n\t"
+		".set pop"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_taglo(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $28\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_taghi(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $29\n\t"
+		".set pop"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_taghi(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $29\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_context(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $4\n\t"
+		".set pop"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void set_context(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $4\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_errorepc(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $30\n\t"
+		".set pop"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void set_errorepc(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"mtc0 %z0, $30\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+/*
+ * Manipulate the status register.
+ * Mostly used to access the interrupt bits.
+ */
+#define __BUILD_SET_CP0(name,register)				\
+static inline unsigned int					\
+set_cp0_##name(unsigned int set)				\
+{								\
+	unsigned int res;					\
+								\
+	res = read_32bit_cp0_register(register);		\
+	res |= set;						\
+	write_32bit_cp0_register(register, res);		\
+								\
+	return res;						\
+}								\
+								\
+static inline unsigned int					\
+clear_cp0_##name(unsigned int clear)				\
+{								\
+	unsigned int res;					\
+								\
+	res = read_32bit_cp0_register(register);		\
+	res &= ~clear;						\
+	write_32bit_cp0_register(register, res);		\
+								\
+	return res;						\
+}								\
+								\
+static inline unsigned int					\
+change_cp0_##name(unsigned int change, unsigned int new)	\
+{								\
+	unsigned int res;					\
+								\
+	res = read_32bit_cp0_register(register);		\
+	res &= ~change;						\
+	res |= (new & change);					\
+	write_32bit_cp0_register(register, res);		\
+								\
+	return res;						\
+}
+
+__BUILD_SET_CP0(status,CP0_STATUS)
+__BUILD_SET_CP0(cause,CP0_CAUSE)
+__BUILD_SET_CP0(config,CP0_CONFIG)
+
+#define __enable_fpu()							\
+do {									\
+	set_cp0_status(ST0_CU1);					\
+	asm("nop;nop;nop;nop");		/* max. hazard */		\
+} while (0)
+
+#define __disable_fpu()							\
+do {									\
+	clear_cp0_status(ST0_CU1);					\
+	/* We don't care about the cp0 hazard here  */			\
+} while (0)
+
+#define enable_fpu()							\
+do {									\
+	if (mips_cpu.options & MIPS_CPU_FPU)				\
+		__enable_fpu();						\
+} while (0)
+
+#define disable_fpu()							\
+do {									\
+	if (mips_cpu.options & MIPS_CPU_FPU)				\
+		__disable_fpu();					\
+} while (0)
+
+#endif /* !__ASSEMBLY__ */
+
 #endif /* _ASM_MIPSREGS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/mmu_context.h linux/include/asm-mips/mmu_context.h
--- linux.orig/include/asm-mips/mmu_context.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/mmu_context.h	2002-07-20 01:08:35.000000000 +0000
@@ -14,12 +14,31 @@
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <asm/pgalloc.h>
+#include <asm/pgtable.h>
 
-/* Fuck.  The f-word is here so you can grep for it :-)  */
-extern unsigned long asid_cache;
-extern pgd_t *current_pgd[];
+/*
+ * For the fast tlb miss handlers, we currently keep a per cpu array
+ * of pointers to the current pgd for each processor. Also, the proc.
+ * id is stuffed into the context register. This should be changed to 
+ * use the processor id via current->processor, where current is stored
+ * in watchhi/lo. The context register should be used to contiguously
+ * map the page tables.
+ */
+#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
+	pgd_current[smp_processor_id()] = (unsigned long)(pgd)
+#define TLBMISS_HANDLER_SETUP() \
+	set_context((unsigned long) smp_processor_id() << (23 + 3)); \
+	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+extern unsigned long pgd_current[];
 
-#if defined(CONFIG_CPU_R3000)
+#ifndef CONFIG_SMP
+#define CPU_CONTEXT(cpu, mm)	(mm)->context
+#else
+#define CPU_CONTEXT(cpu, mm)	(*((unsigned long *)((mm)->context) + cpu))
+#endif
+#define ASID_CACHE(cpu)		cpu_data[cpu].asid_cache
+
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
 #define ASID_INC	0x40
 #define ASID_MASK	0xfc0
@@ -42,22 +61,25 @@
 #define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
 #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
 
-extern inline void
-get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
+static inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
 {
+	unsigned long asid = ASID_CACHE(cpu);
+
 	if (! ((asid += ASID_INC) & ASID_MASK) ) {
-		flush_tlb_all(); /* start new asid cycle */
-		if (!asid)      /* fix version if needed */
+		flush_icache_all();
+		local_flush_tlb_all();	/* start new asid cycle */
+		if (!asid)		/* fix version if needed */
 			asid = ASID_FIRST_VERSION;
 	}
-	mm->context = asid_cache = asid;
+	CPU_CONTEXT(cpu, mm) = ASID_CACHE(cpu) = asid;
 }
 
 /*
  * Initialize the context related info for a new mm_struct
  * instance.
  */
-extern inline int
+static inline int
 init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
 #ifndef CONFIG_SMP
@@ -76,40 +98,41 @@
 	return 0;
 }
 
-extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                              struct task_struct *tsk, unsigned cpu)
 {
-	unsigned long asid = asid_cache;
-
 	/* Check if our ASID is of an older version and thus invalid */
-	if ((next->context ^ asid) & ASID_VERSION_MASK)
-		get_new_mmu_context(next, asid);
+	if ((CPU_CONTEXT(cpu, next) ^ ASID_CACHE(cpu)) & ASID_VERSION_MASK)
+		get_new_mmu_context(next, cpu);
 
-	current_pgd[cpu] = next->pgd;
-	set_entryhi(next->context);
+	set_entryhi(CPU_CONTEXT(cpu, next));
+	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
 }
 
 /*
  * Destroy context related info for an mm_struct that is about
  * to be put to rest.
  */
-extern inline void destroy_context(struct mm_struct *mm)
+static inline void destroy_context(struct mm_struct *mm)
 {
-	/* Nothing to do.  */
+#ifdef CONFIG_SMP
+	if (mm->context)
+		kfree((void *)mm->context);
+#endif
 }
 
 /*
  * After we have set current->mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
  */
-extern inline void
+static inline void
 activate_mm(struct mm_struct *prev, struct mm_struct *next)
 {
 	/* Unconditionally get a new ASID.  */
-	get_new_mmu_context(next, asid_cache);
+	get_new_mmu_context(next, smp_processor_id());
 
-	current_pgd[smp_processor_id()] = next->pgd;
-	set_entryhi(next->context);
+	set_entryhi(CPU_CONTEXT(smp_processor_id(), next));
+	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
 }
 
 #endif /* _ASM_MMU_CONTEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/namei.h linux/include/asm-mips/namei.h
--- linux.orig/include/asm-mips/namei.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/namei.h	2002-07-20 01:08:36.000000000 +0000
@@ -2,11 +2,9 @@
  * linux/include/asm-mips/namei.h
  *
  * Included from linux/fs/namei.c
- *
- * $Id: namei.h,v 1.6 1999/01/04 16:09:23 ralf Exp $
  */
-#ifndef __ASM_MIPS_NAMEI_H
-#define __ASM_MIPS_NAMEI_H
+#ifndef __ASM_NAMEI_H
+#define __ASM_NAMEI_H
 
 #include <linux/config.h>
 
@@ -28,4 +26,4 @@
 
 #endif /* !defined(CONFIG_BINFMT_IRIX) */
 
-#endif /* __ASM_MIPS_NAMEI_H */
+#endif /* __ASM_NAMEI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ng1.h linux/include/asm-mips/ng1.h
--- linux.orig/include/asm-mips/ng1.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/ng1.h	2002-07-20 01:08:33.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ng1hw.h linux/include/asm-mips/ng1hw.h
--- linux.orig/include/asm-mips/ng1hw.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/ng1hw.h	2002-07-20 01:08:26.000000000 +0000
@@ -1,12 +1,9 @@
-/* $Id: ng1hw.h,v 1.4 1999/08/04 06:01:51 ulfc Exp $
- * 
+/*
  * ng1hw.h: Tweaks the newport.h structures and definations to be compatible
  * 	    with IRIX.  Quite ugly, but it works.
  *
  * Copyright (C) 1999 Ulf Carlsson (ulfc@thepuffingroup.com)
- *
  */
-
 #ifndef _SGI_NG1HW_H
 #define _SGI_NG1HW_H
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/nile4.h linux/include/asm-mips/nile4.h
--- linux.orig/include/asm-mips/nile4.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/nile4.h	2002-07-20 01:08:23.000000000 +0000
@@ -7,11 +7,8 @@
  *  This file is based on the following documentation:
  *
  *	NEC Vrc 5074 System Controller Data Sheet, June 1998
- *
- *  $Id: nile4.h,v 1.1 2000/01/26 00:07:45 ralf Exp $
  */
 
-
 #define NILE4_BASE		0xbfa00000
 #define NILE4_SIZE		0x00200000		/* 2 MB */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/paccess.h linux/include/asm-mips/paccess.h
--- linux.orig/include/asm-mips/paccess.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/paccess.h	2002-07-20 01:08:33.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: paccess.h,v 1.1 2000/04/07 12:55:57 raiko Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/page.h linux/include/asm-mips/page.h
--- linux.orig/include/asm-mips/page.h	2000-08-09 20:46:02.000000000 +0000
+++ linux/include/asm-mips/page.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: page.h,v 1.9 2000/02/24 00:13:19 ralf Exp $
- *
+/*
  * Definitions for page handling
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -11,18 +10,55 @@
 #ifndef __ASM_PAGE_H
 #define __ASM_PAGE_H
 
+#include <linux/config.h>
+
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT	12
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_SIZE	(1L << PAGE_SHIFT)
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
 #ifdef __KERNEL__
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
 #define PAGE_BUG(page) do {  BUG(); } while (0)
 
+/*
+ * Prototypes for clear_page / copy_page variants with processor dependant
+ * optimizations.
+ */
+void andes_clear_page(void * page);
+void mips32_clear_page_dc(unsigned long page);
+void mips32_clear_page_sc(unsigned long page);
+void r3k_clear_page(void * page);
+void r4k_clear_page_d16(void * page);
+void r4k_clear_page_d32(void * page);
+void r4k_clear_page_r4600_v1(void * page);
+void r4k_clear_page_r4600_v2(void * page);
+void r4k_clear_page_s16(void * page);
+void r4k_clear_page_s32(void * page);
+void r4k_clear_page_s64(void * page);
+void r4k_clear_page_s128(void * page);
+void r5432_clear_page_d32(void * page);
+void rm7k_clear_page(void * page);
+void sb1_clear_page(void * page);
+void andes_copy_page(void * to, void * from);
+void mips32_copy_page_dc(unsigned long to, unsigned long from);
+void mips32_copy_page_sc(unsigned long to, unsigned long from);
+void r3k_copy_page(void * to, void * from);
+void r4k_copy_page_d16(void * to, void * from);
+void r4k_copy_page_d32(void * to, void * from);
+void r4k_copy_page_r4600_v1(void * to, void * from);
+void r4k_copy_page_r4600_v2(void * to, void * from);
+void r4k_copy_page_s16(void * to, void * from);
+void r4k_copy_page_s32(void * to, void * from);
+void r4k_copy_page_s64(void * to, void * from);
+void r4k_copy_page_s128(void * to, void * from);
+void r5432_copy_page_d32(void * to, void * from);
+void rm7k_copy_page(void * to, void * from);
+void sb1_copy_page(void * to, void * from);
+
 extern void (*_clear_page)(void * page);
 extern void (*_copy_page)(void * to, void * from);
 
@@ -34,7 +70,11 @@
 /*
  * These are used to make use of C type-checking..
  */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+typedef struct { unsigned long long pte; } pte_t;
+#else
 typedef struct { unsigned long pte; } pte_t;
+#endif
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
@@ -44,8 +84,10 @@
 #define pgd_val(x)	((x).pgd)
 #define pgprot_val(x)	((x).pgprot)
 
+#define ptep_buddy(x)	((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
+
 #define __pte(x)	((pte_t) { (x) } )
-#define __pme(x)	((pme_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
 #define __pgd(x)	((pgd_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
@@ -63,10 +105,10 @@
 	return order;
 }
 
-#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+#define PAGE_ALIGN(addr)	(((addr) + PAGE_SIZE - 1) & PAGE_MASK)
 
 /*
  * This handles the memory map.
@@ -78,6 +120,14 @@
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
+#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
+				VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+/*
+ * Memory above this physical address will be considered highmem.
+ */
+#define HIGHMEM_START	(0x20000000)
+
 #endif /* defined (__KERNEL__) */
 
 #endif /* __ASM_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/parport.h linux/include/asm-mips/parport.h
--- linux.orig/include/asm-mips/parport.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/parport.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
  *
  * This file should only be included by drivers/parport/parport_pc.c.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/pb1000.h linux/include/asm-mips/pb1000.h
--- linux.orig/include/asm-mips/pb1000.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/pb1000.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,164 @@
+/*
+ * Alchemy Semi PB1000 Referrence Board
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
+ */
+#ifndef __ASM_PB1000_H
+#define __ASM_PB1000_H
+
+/* PCMCIA PB1000 specific defines */
+#define PCMCIA_MAX_SOCK 0 /* the second socket, 1, is not supported at this time */
+
+#define PB1000_PCR     0xBE000000
+  #define PCR_SLOT_0_VPP0  (1<<0)
+  #define PCR_SLOT_0_VPP1  (1<<1)
+  #define PCR_SLOT_0_VCC0  (1<<2)
+  #define PCR_SLOT_0_VCC1  (1<<3)
+  #define PCR_SLOT_0_RST   (1<<4)
+
+  #define PCR_SLOT_1_VPP0  (1<<8)
+  #define PCR_SLOT_1_VPP1  (1<<9)
+  #define PCR_SLOT_1_VCC0  (1<<10)
+  #define PCR_SLOT_1_VCC1  (1<<11)
+  #define PCR_SLOT_1_RST   (1<<12)
+
+#define PB1000_MDR     0xBE000004
+  #define MDR_PI        (1<<5)  /* pcmcia int latch  */
+  #define MDR_EPI      (1<<14)  /* enable pcmcia int */
+  #define MDR_CPI      (1<<15)  /* clear pcmcia int  */
+
+#define PB1000_ACR1    0xBE000008
+  #define ACR1_SLOT_0_CD1    (1<<0)  /* card detect 1     */
+  #define ACR1_SLOT_0_CD2    (1<<1)  /* card detect 2     */
+  #define ACR1_SLOT_0_READY  (1<<2)  /* ready             */
+  #define ACR1_SLOT_0_STATUS (1<<3)  /* status change     */
+  #define ACR1_SLOT_0_VS1    (1<<4)  /* voltage sense 1   */
+  #define ACR1_SLOT_0_VS2    (1<<5)  /* voltage sense 2   */
+  #define ACR1_SLOT_0_INPACK (1<<6)  /* inpack pin status */
+  #define ACR1_SLOT_1_CD1    (1<<8)  /* card detect 1     */
+  #define ACR1_SLOT_1_CD2    (1<<9)  /* card detect 2     */
+  #define ACR1_SLOT_1_READY  (1<<10) /* ready             */
+  #define ACR1_SLOT_1_STATUS (1<<11) /* status change     */
+  #define ACR1_SLOT_1_VS1    (1<<12) /* voltage sense 1   */
+  #define ACR1_SLOT_1_VS2    (1<<13) /* voltage sense 2   */
+  #define ACR1_SLOT_1_INPACK (1<<14) /* inpack pin status */
+
+#define CPLD_AUX0      0xBE00000C
+#define CPLD_AUX1      0xBE000010
+#define CPLD_AUX2      0xBE000014
+
+/* Voltage levels */
+
+/* VPPEN1 - VPPEN0 */
+#define VPP_GND ((0<<1) | (0<<0))
+#define VPP_5V  ((1<<1) | (0<<0))
+#define VPP_3V  ((0<<1) | (1<<0))
+#define VPP_12V ((0<<1) | (1<<0))
+#define VPP_HIZ ((1<<1) | (1<<0))
+
+/* VCCEN1 - VCCEN0 */
+#define VCC_3V  ((0<<1) | (1<<0))
+#define VCC_5V  ((1<<1) | (0<<0))
+#define VCC_HIZ ((0<<1) | (0<<0))
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT)\
+	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+
+
+/* PCI PB1000 specific defines */
+#define PCI_CONFIG_BASE   0xBA020000 /* the only external slot */
+
+#define SDRAM_DEVID       0xBA010000
+#define SDRAM_CMD         0xBA010004
+#define SDRAM_CLASS       0xBA010008
+#define SDRAM_MISC        0xBA01000C
+#define SDRAM_MBAR        0xBA010010
+
+#define PCI_IO_DATA_PORT  0xBA800000
+
+#define PCI_IO_ADDR       0xBE00001C
+#define PCI_INT_ACK       0xBBC00000
+#define PCI_IO_READ       0xBBC00020
+#define PCI_IO_WRITE      0xBBC00030
+
+#define PCI_BRIDGE_CONFIG 0xBE000018
+
+#define PCI_IO_START      0x10000000
+#define PCI_IO_END        0x1000ffff
+#define PCI_MEM_START     0x18000000
+#define PCI_MEM_END       0x18ffffff
+
+static inline u8 au_pci_io_readb(u32 addr)
+{
+	writel(addr, PCI_IO_ADDR);
+	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG);
+	return (readl(PCI_IO_DATA_PORT) & 0xff);
+}
+
+static inline u16 au_pci_io_readw(u32 addr)
+{
+	writel(addr, PCI_IO_ADDR);
+	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG);
+	return (readl(PCI_IO_DATA_PORT) & 0xffff);
+}
+
+static inline u32 au_pci_io_readl(u32 addr)
+{
+	writel(addr, PCI_IO_ADDR);
+	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff), PCI_BRIDGE_CONFIG);
+	return readl(PCI_IO_DATA_PORT);
+}
+
+static inline void au_pci_io_writeb(u8 val, u32 addr)
+{
+	writel(addr, PCI_IO_ADDR);
+	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG);
+	writel(val, PCI_IO_DATA_PORT);
+}
+
+static inline void au_pci_io_writew(u16 val, u32 addr)
+{
+	writel(addr, PCI_IO_ADDR);
+	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG);
+	writel(val, PCI_IO_DATA_PORT);
+}
+
+static inline void au_pci_io_writel(u32 val, u32 addr)
+{
+	writel(addr, PCI_IO_ADDR);
+	writel(readl(PCI_BRIDGE_CONFIG) & 0xffffcfff, PCI_BRIDGE_CONFIG);
+	writel(val, PCI_IO_DATA_PORT);
+}
+
+static inline void set_sdram_extbyte(void)
+{
+	writel(readl(PCI_BRIDGE_CONFIG) & 0xffffff00, PCI_BRIDGE_CONFIG);
+}
+
+static inline void set_slot_extbyte(void)
+{
+	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffbf00) | 0x18, PCI_BRIDGE_CONFIG);
+}
+#endif /* __ASM_PB1000_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/pb1500.h linux/include/asm-mips/pb1500.h
--- linux.orig/include/asm-mips/pb1500.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/pb1500.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,48 @@
+/*
+ * Alchemy Semi PB1500 Referrence Board
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
+ */
+#ifndef __ASM_PB1500_H
+#define __ASM_PB1500_H
+
+#define PB1500_IDENT          0xAE000000
+#define PB1500_BOARD_STATUS   0xAE000004
+#define PB1500_PCI_PCMCIA     0xAE000010
+  #define PC_DEASSERT_RST           0x80
+  #define PC_DRV_EN                 0x10 
+#define PB1500_G_CONTROL      0xAE000014
+#define PB1500_RST_VDDI       0xAE00001C
+#define PB1500_LEDS           0xAE000018
+
+#define PB1500_HEX_LED        0xAF000004
+#define PB1500_HEX_LED_BLANK  0xAF000008
+
+/* PCMCIA PB1500 specific defines */
+#define PCMCIA_MAX_SOCK 0
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
+
+#endif /* __ASM_PB1500_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/pci.h linux/include/asm-mips/pci.h
--- linux.orig/include/asm-mips/pci.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-mips/pci.h	2002-07-20 01:08:26.000000000 +0000
@@ -7,6 +7,8 @@
 #define _ASM_PCI_H
 
 #include <linux/config.h>
+#include <linux/types.h>
+#include <asm/io.h>			/* for virt_to_bus()  */
 
 #ifdef __KERNEL__
 
@@ -23,12 +25,12 @@
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
 
-extern inline void pcibios_set_master(struct pci_dev *dev)
+static inline void pcibios_set_master(struct pci_dev *dev)
 {
 	/* No special bus mastering setup handling */
 }
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -84,13 +86,13 @@
  * Once the device is given the dma address, the device owns this memory
  * until either pci_unmap_single or pci_dma_sync_single is performed.
  */
-extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
 					size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	dma_cache_wback_inv((unsigned long)ptr, size);
 #endif
 
@@ -105,15 +107,45 @@
  * After this call, reads by the cpu to the buffer are guarenteed to see
  * whatever the device wrote there.
  */
-extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
 				    size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
 	/* Nothing to do */
 }
 
+/*
+ * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
+ * to pci_map_single, but takes a struct page instead of a virtual address
+ */
+static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
+				      unsigned long offset, size_t size,
+                                      int direction)
+{
+	unsigned long addr;
+
+	if (direction == PCI_DMA_NONE)
+		out_of_line_bug();
+
+	addr = (unsigned long) page_address(page);
+	addr += offset;
+#ifdef CONFIG_NONCOHERENT_IO
+	dma_cache_wback_inv(addr, size);
+#endif
+
+	return virt_to_bus((void *)addr);
+}
+
+static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
+				  size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		out_of_line_bug();
+	/* Nothing to do */
+}
+
 /* pci_unmap_{page,single} is a nop so... */
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
@@ -138,17 +170,17 @@
  * Device ownership issues as mentioned above for pci_map_single are
  * the same here.
  */
-extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 			     int nents, int direction)
 {
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	int i;
 #endif
 
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nents; i++, sg++)
 		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
@@ -162,11 +194,11 @@
  * Again, cpu read rules concerning calls here are the same as for
  * pci_unmap_single() above.
  */
-extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 				int nents, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
 	/* Nothing to do */
 }
@@ -181,14 +213,14 @@
  * next point you give the PCI dma address back to the card, the
  * device again owns the buffer.
  */
-extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
 				       dma_addr_t dma_handle,
 				       size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size);
 #endif
 }
@@ -200,19 +232,19 @@
  * The same as pci_dma_sync_single but for a scatter-gather list,
  * same rules and usage.
  */
-extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
 				   struct scatterlist *sg,
 				   int nelems, int direction)
 {
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	int i;
 #endif
 
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
 	/* Make sure that gcc doesn't leave the empty loop body.  */
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	for (i = 0; i < nelems; i++, sg++)
 		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
 #endif
@@ -223,7 +255,7 @@
  * only drive the low 24-bits during PCI bus mastering, then
  * you would pass 0x00ffffff as the mask to this function.
  */
-extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
 {
 	/*
 	 * we fall back to GFP_DMA when the mask isn't all 1s,
@@ -236,6 +268,39 @@
 	return 1;
 }
 
+/* This is always fine. */
+/* Well ...  this actually needs more thought ...  */
+#define pci_dac_dma_supported(pci_dev, mask)	(0)
+
+#if 0
+static __inline__ dma64_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+{
+	return ((dma64_addr_t) page_to_bus(page) +
+		(dma64_addr_t) offset);
+}
+
+static __inline__ struct page *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+	unsigned long poff = (dma_addr >> PAGE_SHIFT);
+
+	return mem_map + poff;
+}
+
+static __inline__ unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+	return (dma_addr & ~PAGE_MASK);
+}
+
+static __inline__ void
+pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr,
+                        size_t len, int direction)
+{
+	/* Nothing to do. */
+}
+#endif
 
 /* Return the index of the PCI controller for device. */
 #define pci_controller_num(pdev)	(0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/pgalloc.h linux/include/asm-mips/pgalloc.h
--- linux.orig/include/asm-mips/pgalloc.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/pgalloc.h	2002-07-20 01:08:37.000000000 +0000
@@ -11,6 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/mm.h>
+#include <asm/fixmap.h>
 
 /* TLB flushing:
  *
@@ -18,14 +19,32 @@
  *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
  *  - flush_tlb_page(mm, vmaddr) flushes a single page
  *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
-extern void flush_tlb_all(void);
-extern void flush_tlb_mm(struct mm_struct *mm);
-extern void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+extern void local_flush_tlb_all(void);
+extern void local_flush_tlb_mm(struct mm_struct *mm);
+extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
 			       unsigned long end);
-extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
+extern void local_flush_tlb_page(struct vm_area_struct *vma,
+                                 unsigned long page);
+
+#ifdef CONFIG_SMP
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *);
+extern void flush_tlb_range(struct mm_struct *, unsigned long, unsigned long);
+extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
 
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+#else /* CONFIG_SMP */
+
+#define flush_tlb_all()			local_flush_tlb_all()
+#define flush_tlb_mm(mm)		local_flush_tlb_mm(mm)
+#define flush_tlb_range(mm,vmaddr,end)	local_flush_tlb_range(mm, vmaddr, end)
+#define flush_tlb_page(vma,page)	local_flush_tlb_page(vma, page)
+
+#endif /* CONFIG_SMP */
+
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
                                       unsigned long start, unsigned long end)
 {
 	/* Nothing to do on MIPS.  */
@@ -50,7 +69,7 @@
 
 extern __inline__ pgd_t *get_pgd_slow(void)
 {
-	pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init;
+	pgd_t *ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGD_ORDER), *init;
 
 	if (ret) {
 		init = pgd_offset(&init_mm, 0);
@@ -83,11 +102,9 @@
 
 extern __inline__ void free_pgd_slow(pgd_t *pgd)
 {
-	free_page((unsigned long)pgd);
+	free_pages((unsigned long)pgd, PGD_ORDER);
 }
 
-extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
-
 extern __inline__ pte_t *get_pte_fast(void)
 {
 	unsigned long *ret;
@@ -162,7 +179,7 @@
 	free_page((unsigned long)pte);
 }
 
-#define pte_free(pte)           pte_free_slow(pte)
+#define pte_free(pte)           pte_free_fast(pte)
 #define pgd_free(pgd)           free_pgd_fast(pgd)
 #define pgd_alloc(mm)           get_pgd_fast()
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/pgtable-bits.h linux/include/asm-mips/pgtable-bits.h
--- linux.orig/include/asm-mips/pgtable-bits.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/pgtable-bits.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,98 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 by Ralf Baechle at alii
+ * Copyright (C) 2001, 2002 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_CACHINGMODES_H
+#define _ASM_CACHINGMODES_H
+
+#include <linux/config.h>
+
+/* Note that we shift the lower 32bits of each EntryLo[01] entry
+ * 6 bits to the left. That way we can convert the PFN into the
+ * physical address by a single 'and' operation and gain 6 additional
+ * bits for storing information which isn't present in a normal
+ * MIPS page table.
+ *
+ * Similar to the Alpha port, we need to keep track of the ref
+ * and mod bits in software.  We have a software "yeah you can read
+ * from this page" bit, and a hardware one which actually lets the
+ * process read from the page.  On the same token we have a software
+ * writable bit and the real hardware one which actually lets the
+ * process write to the page, this keeps a mod bit via the hardware
+ * dirty bit.
+ *
+ * Certain revisions of the R4000 and R5000 have a bug where if a
+ * certain sequence occurs in the last 3 instructions of an executable
+ * page, and the following page is not mapped, the cpu can do
+ * unpredictable things.  The code (when it is written) to deal with
+ * this problem will be in the update_mmu_cache() code for the r4k.
+ */
+#define _PAGE_PRESENT               (1<<0)  /* implemented in software */
+#define _PAGE_READ                  (1<<1)  /* implemented in software */
+#define _PAGE_WRITE                 (1<<2)  /* implemented in software */
+#define _PAGE_ACCESSED              (1<<3)  /* implemented in software */
+#define _PAGE_MODIFIED              (1<<4)  /* implemented in software */
+
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+#define _PAGE_GLOBAL                (1<<8)
+#define _PAGE_VALID                 (1<<9)
+#define _PAGE_SILENT_READ           (1<<9)  /* synonym                 */
+#define _PAGE_DIRTY                 (1<<10) /* The MIPS dirty bit      */
+#define _PAGE_SILENT_WRITE          (1<<10)
+#define _CACHE_UNCACHED             (1<<11)
+#define _CACHE_MASK                 (1<<11)
+#define _CACHE_CACHABLE_NONCOHERENT 0
+
+#else
+#define _PAGE_R4KBUG                (1<<5)  /* workaround for r4k bug  */
+#define _PAGE_GLOBAL                (1<<6)
+#define _PAGE_VALID                 (1<<7)
+#define _PAGE_SILENT_READ           (1<<7)  /* synonym                 */
+#define _PAGE_DIRTY                 (1<<8)  /* The MIPS dirty bit      */
+#define _PAGE_SILENT_WRITE          (1<<8)
+#define _CACHE_MASK                 (7<<9)
+
+#if defined(CONFIG_CPU_SB1)
+
+/* No penalty for being coherent on the SB1, so just
+   use it for "noncoherent" spaces, too.  Shouldn't hurt. */
+
+#define _CACHE_UNCACHED             (2<<9)  
+#define _CACHE_CACHABLE_COW         (5<<9)  
+#define _CACHE_CACHABLE_NONCOHERENT (5<<9)  
+#define _CACHE_UNCACHED_ACCELERATED (7<<9)  
+
+#else
+
+#define _CACHE_CACHABLE_NO_WA       (0<<9)  /* R4600 only              */
+#define _CACHE_CACHABLE_WA          (1<<9)  /* R4600 only              */
+#define _CACHE_UNCACHED             (2<<9)  /* R4[0246]00              */
+#define _CACHE_CACHABLE_NONCOHERENT (3<<9)  /* R4[0246]00              */
+#define _CACHE_CACHABLE_CE          (4<<9)  /* R4[04]00 only           */
+#define _CACHE_CACHABLE_COW         (5<<9)  /* R4[04]00 only           */
+#define _CACHE_CACHABLE_CUW         (6<<9)  /* R4[04]00 only           */
+#define _CACHE_UNCACHED_ACCELERATED (7<<9)  /* R10000 only             */
+
+#endif
+#endif
+
+#define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
+#define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
+
+#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
+
+#ifdef CONFIG_MIPS_UNCACHED
+#define PAGE_CACHABLE_DEFAULT	_CACHE_UNCACHED
+#elif CONFIG_CPU_SB1
+#define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
+#else
+#define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_NONCOHERENT
+#endif
+
+#endif /* _ASM_CACHINGMODES_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/pgtable.h linux/include/asm-mips/pgtable.h
--- linux.orig/include/asm-mips/pgtable.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/pgtable.h	2002-07-20 01:08:30.000000000 +0000
@@ -9,14 +9,13 @@
 #ifndef _ASM_PGTABLE_H
 #define _ASM_PGTABLE_H
 
+#include <linux/config.h>
 #include <asm/addrspace.h>
 #include <asm/page.h>
 
-#ifndef _LANGUAGE_ASSEMBLY
-
 #include <linux/linkage.h>
 #include <asm/cachectl.h>
-#include <linux/config.h>
+#include <asm/fixmap.h>
 
 /* Cache flushing:
  *
@@ -26,18 +25,23 @@
  *  - flush_cache_range(mm, start, end) flushes a range of pages
  *  - flush_page_to_ram(page) write back kernel page to ram
  *  - flush_icache_range(start, end) flush a range of instructions
+ *
+ *  - flush_cache_sigtramp() flush signal trampoline
+ *  - flush_icache_all() flush the entire instruction cache
  */
 extern void (*_flush_cache_all)(void);
 extern void (*___flush_cache_all)(void);
 extern void (*_flush_cache_mm)(struct mm_struct *mm);
 extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
-				 unsigned long end);
-extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
-extern void (*_flush_cache_sigtramp)(unsigned long addr);
+	unsigned long end);
+extern void (*_flush_cache_page)(struct vm_area_struct *vma,
+	unsigned long page);
 extern void (*_flush_page_to_ram)(struct page * page);
 extern void (*_flush_icache_range)(unsigned long start, unsigned long end);
 extern void (*_flush_icache_page)(struct vm_area_struct *vma,
-                                  struct page *page);
+	struct page *page);
+extern void (*_flush_cache_sigtramp)(unsigned long addr);
+extern void (*_flush_icache_all)(void);
 
 #define flush_dcache_page(page)			do { } while (0)
 
@@ -46,12 +50,19 @@
 #define flush_cache_mm(mm)		_flush_cache_mm(mm)
 #define flush_cache_range(mm,start,end)	_flush_cache_range(mm,start,end)
 #define flush_cache_page(vma,page)	_flush_cache_page(vma, page)
-#define flush_cache_sigtramp(addr)	_flush_cache_sigtramp(addr)
 #define flush_page_to_ram(page)		_flush_page_to_ram(page)
 
 #define flush_icache_range(start, end)	_flush_icache_range(start,end)
+#define flush_icache_user_range(vma, page, addr, len) \
+					_flush_icache_page((vma), (page))
 #define flush_icache_page(vma, page) 	_flush_icache_page(vma, page)
 
+#define flush_cache_sigtramp(addr)	_flush_cache_sigtramp(addr)
+#ifdef CONFIG_VTAG_ICACHE
+#define flush_icache_all()		_flush_icache_all()
+#else
+#define flush_icache_all()		do { } while(0)
+#endif
 
 /*
  * - add_wired_entry() add a fixed TLB entry, and move wired register
@@ -77,114 +88,49 @@
  * works even with the cache aliasing problem the R4k and above have.
  */
 
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
-
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define PMD_SHIFT	21
+#else
 #define PMD_SHIFT	22
+#endif
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT	22
+#define PGDIR_SHIFT	PMD_SHIFT
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
-/* Entries per page directory level: we use two-level, so
+/*
+ * Entries per page directory level: we use two-level, so
  * we don't really have any PMD directory physically.
  */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define PTRS_PER_PTE	512
+#define PTRS_PER_PMD	1
+#define PTRS_PER_PGD	2048
+#define PGD_ORDER	1
+#else
 #define PTRS_PER_PTE	1024
 #define PTRS_PER_PMD	1
 #define PTRS_PER_PGD	1024
-#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
+#define PGD_ORDER	0
+#endif
+
+#define USER_PTRS_PER_PGD	(0x80000000UL/PGDIR_SIZE)
 #define FIRST_USER_PGD_NR	0
 
 #define VMALLOC_START     KSEG2
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define VMALLOC_END       KSEG3
-
-/* Note that we shift the lower 32bits of each EntryLo[01] entry
- * 6 bits to the left. That way we can convert the PFN into the
- * physical address by a single 'and' operation and gain 6 additional
- * bits for storing information which isn't present in a normal
- * MIPS page table.
- *
- * Similar to the Alpha port, we need to keep track of the ref
- * and mod bits in software.  We have a software "yeah you can read
- * from this page" bit, and a hardware one which actually lets the
- * process read from the page.  On the same token we have a software
- * writable bit and the real hardware one which actually lets the
- * process write to the page, this keeps a mod bit via the hardware
- * dirty bit.
- *
- * Certain revisions of the R4000 and R5000 have a bug where if a
- * certain sequence occurs in the last 3 instructions of an executable
- * page, and the following page is not mapped, the cpu can do
- * unpredictable things.  The code (when it is written) to deal with
- * this problem will be in the update_mmu_cache() code for the r4k.
- */
-#define _PAGE_PRESENT               (1<<0)  /* implemented in software */
-#define _PAGE_READ                  (1<<1)  /* implemented in software */
-#define _PAGE_WRITE                 (1<<2)  /* implemented in software */
-#define _PAGE_ACCESSED              (1<<3)  /* implemented in software */
-#define _PAGE_MODIFIED              (1<<4)  /* implemented in software */
-
-#if defined(CONFIG_CPU_R3000)
-
-#define _PAGE_GLOBAL                (1<<8)
-#define _PAGE_VALID                 (1<<9)
-#define _PAGE_SILENT_READ           (1<<9)  /* synonym                 */
-#define _PAGE_DIRTY                 (1<<10) /* The MIPS dirty bit      */
-#define _PAGE_SILENT_WRITE          (1<<10)
-#define _CACHE_UNCACHED             (1<<11) /* R4[0246]00              */
-#define _CACHE_MASK                 (1<<11)
-#define _CACHE_CACHABLE_NONCOHERENT 0
-
-#else
-#define _PAGE_R4KBUG                (1<<5)  /* workaround for r4k bug  */
-#define _PAGE_GLOBAL                (1<<6)
-#define _PAGE_VALID                 (1<<7)
-#define _PAGE_SILENT_READ           (1<<7)  /* synonym                 */
-#define _PAGE_DIRTY                 (1<<8)  /* The MIPS dirty bit      */
-#define _PAGE_SILENT_WRITE          (1<<8)
-#define _CACHE_MASK                 (7<<9)
-
-#if defined(CONFIG_CPU_SB1)
-
-/* No penalty for being coherent on the SB1, so just
-   use it for "noncoherent" spaces, too.  Shouldn't hurt. */
-
-#define _CACHE_UNCACHED             (2<<9)  
-#define _CACHE_CACHABLE_COW         (5<<9)  
-#define _CACHE_CACHABLE_NONCOHERENT (5<<9)  
 
+#if CONFIG_HIGHMEM
+# define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)
 #else
-
-#define _CACHE_CACHABLE_NO_WA       (0<<9)  /* R4600 only              */
-#define _CACHE_CACHABLE_WA          (1<<9)  /* R4600 only              */
-#define _CACHE_UNCACHED             (2<<9)  /* R4[0246]00              */
-#define _CACHE_CACHABLE_NONCOHERENT (3<<9)  /* R4[0246]00              */
-#define _CACHE_CACHABLE_CE          (4<<9)  /* R4[04]00 only           */
-#define _CACHE_CACHABLE_COW         (5<<9)  /* R4[04]00 only           */
-#define _CACHE_CACHABLE_CUW         (6<<9)  /* R4[04]00 only           */
-#define _CACHE_CACHABLE_ACCELERATED (7<<9)  /* R10000 only             */
-
+# define VMALLOC_END	(FIXADDR_START-2*PAGE_SIZE)
 #endif
-#endif
-
-#define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
-#define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
 
-#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
-
-#ifdef CONFIG_MIPS_UNCACHED
-#define PAGE_CACHABLE_DEFAULT	_CACHE_UNCACHED
-#else
-#ifdef CONFIG_CPU_SB1
-#define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
-#else
-#define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_NONCOHERENT
-#endif
-#endif
+#include <asm/pgtable-bits.h>
 
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
 #define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
@@ -194,11 +140,11 @@
 #define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_READ | \
 			PAGE_CACHABLE_DEFAULT)
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-			PAGE_CACHABLE_DEFAULT)
+			_PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT)
 #define PAGE_USERIO     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
 			PAGE_CACHABLE_DEFAULT)
-#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-			_CACHE_UNCACHED)
+#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
+			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
 
 /*
  * MIPS can't do page protection for execute, and considers that the same like
@@ -223,14 +169,17 @@
 #define __S110	PAGE_SHARED
 #define __S111	PAGE_SHARED
 
-#if !defined (_LANGUAGE_ASSEMBLY)
-
+#ifdef CONFIG_64BIT_PHYS_ADDR
 #define pte_ERROR(e) \
-	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
+	printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e))
+#else
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#endif
 #define pmd_ERROR(e) \
-	printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
+	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
 #define pgd_ERROR(e) \
-	printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
+	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
 
 extern unsigned long empty_zero_page;
 extern unsigned long zero_page_mask;
@@ -238,21 +187,6 @@
 #define ZERO_PAGE(vaddr) \
 	(virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
 
-/* number of bits that fit into a memory pointer */
-#define BITS_PER_PTR			(8*sizeof(unsigned long))
-
-/* to align the pointer to a pointer address */
-#define PTR_MASK			(~(sizeof(void*)-1))
-
-/*
- * sizeof(void*) == (1 << SIZEOF_PTR_LOG2)
- */
-#define SIZEOF_PTR_LOG2			2
-
-/* to find an entry in a page-table */
-#define PAGE_PTR(address) \
-((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-
 extern void load_pgd(unsigned long pg_dir);
 
 extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)];
@@ -261,31 +195,48 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-extern inline unsigned long pmd_page(pmd_t pmd)
+static inline unsigned long pmd_page(pmd_t pmd)
 {
 	return pmd_val(pmd);
 }
 
-extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 {
 	pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK);
 }
 
-extern inline int pte_none(pte_t pte)    { return !pte_val(pte); }
-extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
+static inline int pte_none(pte_t pte)    { return !(pte_val(pte) & ~_PAGE_GLOBAL); }
+static inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
 
 /* Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
  */
-extern inline void set_pte(pte_t *ptep, pte_t pteval)
+static inline void set_pte(pte_t *ptep, pte_t pteval)
 {
 	*ptep = pteval;
+#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
+	if (pte_val(pteval) & _PAGE_GLOBAL) {
+		pte_t *buddy = ptep_buddy(ptep);
+		/*
+		 * Make sure the buddy is global too (if it's !none,
+		 * it better already be global)
+		 */
+		if (pte_none(*buddy))
+			pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
+	}
+#endif
 }
 
-extern inline void pte_clear(pte_t *ptep)
+static inline void pte_clear(pte_t *ptep)
 {
-	set_pte(ptep, __pte(0));
+#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
+	/* Preserve global status for the pair */
+	if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
+		set_pte(ptep, __pte(_PAGE_GLOBAL));
+	else
+#endif
+		set_pte(ptep, __pte(0));
 }
 
 /*
@@ -298,23 +249,23 @@
 /*
  * Empty pgd/pmd entries point to the invalid_pte_table.
  */
-extern inline int pmd_none(pmd_t pmd)
+static inline int pmd_none(pmd_t pmd)
 {
 	return pmd_val(pmd) == (unsigned long) invalid_pte_table;
 }
 
-extern inline int pmd_bad(pmd_t pmd)
+static inline int pmd_bad(pmd_t pmd)
 {
 	return ((pmd_page(pmd) > (unsigned long) high_memory) ||
 	        (pmd_page(pmd) < PAGE_OFFSET));
 }
 
-extern inline int pmd_present(pmd_t pmd)
+static inline int pmd_present(pmd_t pmd)
 {
 	return (pmd_val(pmd) != (unsigned long) invalid_pte_table);
 }
 
-extern inline void pmd_clear(pmd_t *pmdp)
+static inline void pmd_clear(pmd_t *pmdp)
 {
 	pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
 }
@@ -324,16 +275,15 @@
  * setup: the pgd is never bad, and a pmd always exists (as it's folded
  * into the pgd entry)
  */
-extern inline int pgd_none(pgd_t pgd)		{ return 0; }
-extern inline int pgd_bad(pgd_t pgd)		{ return 0; }
-extern inline int pgd_present(pgd_t pgd)	{ return 1; }
-extern inline void pgd_clear(pgd_t *pgdp)	{ }
+static inline int pgd_none(pgd_t pgd)		{ return 0; }
+static inline int pgd_bad(pgd_t pgd)		{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
+static inline void pgd_clear(pgd_t *pgdp)	{ }
 
 /*
- * Permanent address of a page.  On MIPS we never have highmem, so this
- * is simple.
+ * Permanent address of a page.  Obviously must never be called on a highmem
+ * page.
  */
-#define page_address(page)	((page)->virtual)
 #ifdef CONFIG_CPU_VR41XX
 #define pte_page(x)             (mem_map+(unsigned long)((pte_val(x) >> (PAGE_SHIFT + 2))))
 #else
@@ -344,36 +294,36 @@
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
-extern inline int pte_read(pte_t pte)	{ return pte_val(pte) & _PAGE_READ; }
-extern inline int pte_write(pte_t pte)	{ return pte_val(pte) & _PAGE_WRITE; }
-extern inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & _PAGE_MODIFIED; }
-extern inline int pte_young(pte_t pte)	{ return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_read(pte_t pte)	{ return pte_val(pte) & _PAGE_READ; }
+static inline int pte_write(pte_t pte)	{ return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte)	{ return pte_val(pte) & _PAGE_ACCESSED; }
 
-extern inline pte_t pte_wrprotect(pte_t pte)
+static inline pte_t pte_wrprotect(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
 	return pte;
 }
 
-extern inline pte_t pte_rdprotect(pte_t pte)
+static inline pte_t pte_rdprotect(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
 	return pte;
 }
 
-extern inline pte_t pte_mkclean(pte_t pte)
+static inline pte_t pte_mkclean(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
 	return pte;
 }
 
-extern inline pte_t pte_mkold(pte_t pte)
+static inline pte_t pte_mkold(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
 	return pte;
 }
 
-extern inline pte_t pte_mkwrite(pte_t pte)
+static inline pte_t pte_mkwrite(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_WRITE;
 	if (pte_val(pte) & _PAGE_MODIFIED)
@@ -381,7 +331,7 @@
 	return pte;
 }
 
-extern inline pte_t pte_mkread(pte_t pte)
+static inline pte_t pte_mkread(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_READ;
 	if (pte_val(pte) & _PAGE_ACCESSED)
@@ -389,7 +339,7 @@
 	return pte;
 }
 
-extern inline pte_t pte_mkdirty(pte_t pte)
+static inline pte_t pte_mkdirty(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_MODIFIED;
 	if (pte_val(pte) & _PAGE_WRITE)
@@ -414,7 +364,7 @@
 	return __pgprot(prot);
 }
 
-extern inline pte_t pte_mkyoung(pte_t pte)
+static inline pte_t pte_mkyoung(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_ACCESSED;
 	if (pte_val(pte) & _PAGE_READ)
@@ -426,12 +376,13 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
+
 #ifdef CONFIG_CPU_VR41XX
 #define mk_pte(page, pgprot)                                            \
 ({                                                                      \
         pte_t   __pte;                                                  \
                                                                         \
-        pte_val(__pte) = ((unsigned long)(page - mem_map) << (PAGE_SHIFT + 2)) | \
+        pte_val(__pte) = ((phys_t)(page - mem_map) << (PAGE_SHIFT + 2)) | \
                          pgprot_val(pgprot);                            \
                                                                         \
         __pte;                                                          \
@@ -441,14 +392,14 @@
 ({									\
 	pte_t   __pte;							\
 									\
-	pte_val(__pte) = ((unsigned long)(page - mem_map) << PAGE_SHIFT) | \
+	pte_val(__pte) = ((phys_t)(page - mem_map) << PAGE_SHIFT) | \
 	                 pgprot_val(pgprot);				\
 									\
 	__pte;								\
 })
 #endif
 
-extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
+static inline pte_t mk_pte_phys(phys_t physpage, pgprot_t pgprot)
 {
 #ifdef CONFIG_CPU_VR41XX
         return __pte((physpage << 2) | pgprot_val(pgprot));
@@ -457,32 +408,36 @@
 #endif
 }
 
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
 	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
 }
 
 #define page_pte(page) page_pte_prot(page, __pgprot(0))
 
+#define __pgd_offset(address)	pgd_index(address)
+#define __pmd_offset(address) \
+	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
 #define pgd_index(address)	((address) >> PGDIR_SHIFT)
 
 /* to find an entry in a page-table-directory */
-extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
+static inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
 {
 	return mm->pgd + pgd_index(address);
 }
 
 /* Find an entry in the second-level page table.. */
-extern inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
+static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
 {
 	return (pmd_t *) dir;
 }
 
 /* Find an entry in the third-level page table.. */ 
-extern inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
+static inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
 {
 	return (pte_t *) (pmd_page(*dir)) +
 	       ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
@@ -496,9 +451,19 @@
 extern void update_mmu_cache(struct vm_area_struct *vma,
 				unsigned long address, pte_t pte);
 
-#define SWP_TYPE(x)		(((x).val >> 1) & 0x3f)
+/* Swap entries must have VALID and GLOBAL bits cleared. */
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+#define SWP_TYPE(x)		(((x).val >> 1) & 0x7f)
+#define SWP_OFFSET(x)		((x).val >> 10)
+#define SWP_ENTRY(type,offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 10) })
+#else
+
+#define SWP_TYPE(x)		(((x).val >> 1) & 0x1f)
 #define SWP_OFFSET(x)		((x).val >> 8)
 #define SWP_ENTRY(type,offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+#endif
+
 #define pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)	((pte_t) { (x).val })
 
@@ -507,277 +472,13 @@
 #define PageSkip(page)		(0)
 #define kern_addr_valid(addr)	(1)
 
-/* TLB operations. */
-extern inline void tlb_probe(void)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"tlbp\n\t"
-		".set pop");
-}
-
-extern inline void tlb_read(void)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"tlbr\n\t"
-		".set pop");
-}
-
-extern inline void tlb_write_indexed(void)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"tlbwi\n\t"
-		".set pop");
-}
-
-extern inline void tlb_write_random(void)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"tlbwr\n\t"
-		".set pop");
-}
-
-/* Dealing with various CP0 mmu/cache related registers. */
-
-/* CP0_PAGEMASK register */
-extern inline unsigned long get_pagemask(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $5\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_pagemask(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $5\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */
-extern inline unsigned long get_entrylo0(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(	
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $2\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_entrylo0(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $2\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-extern inline unsigned long get_entrylo1(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $3\n\t"
-		".set pop" : "=r" (val));
-
-	return val;
-}
-
-extern inline void set_entrylo1(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $3\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-/* CP0_ENTRYHI register */
-extern inline unsigned long get_entryhi(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $10\n\t"
-		".set pop"
-		: "=r" (val));
-
-	return val;
-}
-
-extern inline void set_entryhi(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $10\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-/* CP0_INDEX register */
-extern inline unsigned long get_index(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $0\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_index(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $0\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-/* CP0_WIRED register */
-extern inline unsigned long get_wired(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $6\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_wired(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $6\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-extern inline unsigned long get_info(void)
-{
-	unsigned long val;
-
-	__asm__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $7\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-/* CP0_TAGLO and CP0_TAGHI registers */
-extern inline unsigned long get_taglo(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $28\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_taglo(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $28\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-extern inline unsigned long get_taghi(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $29\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_taghi(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $29\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
-/* CP0_CONTEXT register */
-extern inline unsigned long get_context(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $4\n\t"
-		".set pop"
-		: "=r" (val));
-
-	return val;
-}
-
-extern inline void set_context(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mtc0 %z0, $4\n\t"
-		".set pop"
-		: : "Jr" (val));
-}
-
 #include <asm-generic/pgtable.h>
 
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+/*
+ * We provide our own get_unmapped area to cope with the virtual aliasing
+ * constraints placed on us by the cache architecture.
+ */
+#define HAVE_ARCH_UNMAPPED_AREA
 
 #define io_remap_page_range remap_page_range
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/posix_types.h linux/include/asm-mips/posix_types.h
--- linux.orig/include/asm-mips/posix_types.h	2000-07-10 05:18:15.000000000 +0000
+++ linux/include/asm-mips/posix_types.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: posix_types.h,v 1.6 2000/02/04 23:32:54 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/prctl.h linux/include/asm-mips/prctl.h
--- linux.orig/include/asm-mips/prctl.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/prctl.h	2002-07-20 01:08:33.000000000 +0000
@@ -3,7 +3,6 @@
  *
  * The IRIX kernel maps a page at PRDA_ADDRESS with the
  * contents of prda and fills it the bits on prda_sys.
- * $Id$
  */
 
 #ifndef __PRCTL_H__
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/processor.h linux/include/asm-mips/processor.h
--- linux.orig/include/asm-mips/processor.h	2001-10-05 19:11:05.000000000 +0000
+++ linux/include/asm-mips/processor.h	2002-07-20 01:08:23.000000000 +0000
@@ -12,7 +12,7 @@
 #define _ASM_PROCESSOR_H
 
 #include <linux/config.h>
-
+#include <linux/cache.h>
 #include <asm/isadep.h>
 
 /*
@@ -21,38 +21,36 @@
  */
 #define current_text_addr() ({ __label__ _l; _l: &&_l;})
 
-#if !defined (_LANGUAGE_ASSEMBLY)
+#ifndef __ASSEMBLY__
 #include <linux/threads.h>
 #include <asm/cachectl.h>
 #include <asm/mipsregs.h>
 #include <asm/reg.h>
 #include <asm/system.h>
 
-struct mips_cpuinfo {
+struct cpuinfo_mips {
 	unsigned long udelay_val;
 	unsigned long *pgd_quick;
 	unsigned long *pte_quick;
 	unsigned long pgtable_cache_sz;
-};
+	unsigned long asid_cache;
+} __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 /*
  * System setup and hardware flags..
- * XXX: Should go into mips_cpuinfo.
  */
-extern void (*cpu_wait)(void);	/* only available on R4[26]00 and R3081 */
+extern void (*cpu_wait)(void);
 extern void r3081_wait(void);
+extern void r39xx_wait(void);
 extern void r4k_wait(void);
-extern char cyclecounter_available;	/* only available from R4000 upwards. */
 
-extern struct mips_cpuinfo boot_cpu_data;
+extern struct cpuinfo_mips cpu_data[];
 extern unsigned int vced_count, vcei_count;
 
 #ifdef CONFIG_SMP
-extern struct mips_cpuinfo cpu_data[];
 #define current_cpu_data cpu_data[smp_processor_id()]
 #else
-#define cpu_data &boot_cpu_data
-#define current_cpu_data boot_cpu_data
+#define current_cpu_data cpu_data[0]
 #endif
 
 /*
@@ -151,24 +149,9 @@
 	mm_segment_t current_ds;
 	unsigned long irix_trampoline;  /* Wheee... */
 	unsigned long irix_oldctx;
-
-	/*
-	 * These are really only needed if the full FPU emulator is configured.
-	 * Would be made conditional on MIPS_FPU_EMULATOR if it weren't for the
-	 * fact that having offset.h rebuilt differently for different config
-	 * options would be asking for trouble.
-	 *
-	 * Saved EPC during delay-slot emulation (see math-emu/cp1emu.c)
-	 */
-	unsigned long dsemul_epc;
-
-	/*
-	 * Pointer to instruction used to induce address error
-	 */
-	unsigned long dsemul_aerpc;
 };
 
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* !__ASSEMBLY__ */
 
 #define INIT_THREAD  { \
         /* \
@@ -191,19 +174,14 @@
 	/* \
 	 * For now the default is to fix address errors \
 	 */ \
-	MF_FIXADE, { 0 }, 0, 0, \
-	/* \
-	 * dsemul_epc and dsemul_aerpc should never be used uninitialized, \
-	 * but... \
-	 */ \
-	0 ,0 \
+	MF_FIXADE, { 0 }, 0, 0 \
 }
 
 #ifdef __KERNEL__
 
 #define KERNEL_STACK_SIZE 8192
 
-#if !defined (_LANGUAGE_ASSEMBLY)
+#ifndef __ASSEMBLY__
 
 /* Free all resources held by a thread. */
 #define release_thread(thread) do { } while(0)
@@ -217,7 +195,7 @@
 /*
  * Return saved PC of a blocked thread.
  */
-extern inline unsigned long thread_saved_pc(struct thread_struct *t)
+static inline unsigned long thread_saved_pc(struct thread_struct *t)
 {
 	extern void ret_from_fork(void);
 
@@ -225,15 +203,15 @@
 	if (t->reg31 == (unsigned long) ret_from_fork)
 		return t->reg31;
 
-	return ((unsigned long *)t->reg29)[10];
+	return ((unsigned long *)t->reg29)[13];
 }
 
 /*
  * Do necessary setup to start up a newly executed thread.
  */
 #define start_thread(regs, new_pc, new_sp) do {				\
-	/* New thread looses kernel privileges. */			\
-	regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KU_USER;\
+	/* New thread loses kernel and FPU privileges. */	       	\
+	regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU|ST0_CU1)) | KU_USER;\
 	regs->cp0_epc = new_pc;						\
 	regs->regs[29] = new_sp;					\
 	current->thread.current_ds = USER_DS;				\
@@ -261,7 +239,7 @@
 
 #define cpu_relax()	do { } while (0)
 
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* !__ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ptrace.h linux/include/asm-mips/ptrace.h
--- linux.orig/include/asm-mips/ptrace.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/ptrace.h	2002-07-20 01:08:23.000000000 +0000
@@ -12,7 +12,6 @@
 #define _ASM_PTRACE_H
 
 #include <asm/isadep.h>
-#include <linux/types.h>
 
 /* 0 - 31 are integer registers, 32 - 63 are fp registers.  */
 #define FPR_BASE	32
@@ -24,7 +23,7 @@
 #define FPC_CSR		69
 #define FPC_EIR		70
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 /*
  * This struct defines the way the registers are stored on the stack during a
  * system call/exception. As usual the registers k0/k1 aren't being saved.
@@ -49,7 +48,33 @@
 	unsigned long cp0_cause;
 };
 
-#endif /* !(_LANGUAGE_ASSEMBLY) */
+#define __str2(x) #x
+#define __str(x) __str2(x)
+
+#define save_static_function(symbol)                                    \
+__asm__ (                                                               \
+        ".globl\t" #symbol "\n\t"                                       \
+        ".align\t2\n\t"                                                 \
+        ".type\t" #symbol ", @function\n\t"                             \
+        ".ent\t" #symbol ", 0\n"                                        \
+        #symbol":\n\t"                                                  \
+        ".frame\t$29, 0, $31\n\t"                                       \
+        "sw\t$16,"__str(PT_R16)"($29)\t\t\t# save_static_function\n\t"  \
+        "sw\t$17,"__str(PT_R17)"($29)\n\t"                              \
+        "sw\t$18,"__str(PT_R18)"($29)\n\t"                              \
+        "sw\t$19,"__str(PT_R19)"($29)\n\t"                              \
+        "sw\t$20,"__str(PT_R20)"($29)\n\t"                              \
+        "sw\t$21,"__str(PT_R21)"($29)\n\t"                              \
+        "sw\t$22,"__str(PT_R22)"($29)\n\t"                              \
+        "sw\t$23,"__str(PT_R23)"($29)\n\t"                              \
+        "sw\t$30,"__str(PT_R30)"($29)\n\t"                              \
+        ".end\t" #symbol "\n\t"                                         \
+        ".size\t" #symbol",. - " #symbol)
+
+/* Used in declaration of save_static functions.  */
+#define static_unused static __attribute__((unused))
+
+#endif /* !__ASSEMBLY__ */
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
 /* #define PTRACE_GETREGS		12 */
@@ -64,13 +89,13 @@
 /* options set using PTRACE_SETOPTIONS */
 #define PTRACE_O_TRACESYSGOOD	0x00000001
 
-#ifdef _LANGUAGE_ASSEMBLY
+#ifdef __ASSEMBLY__
 #include <asm/offset.h>
 #endif
 
 #ifdef __KERNEL__
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 /*
  * Does the process account for user or for system time?
  */
@@ -79,7 +104,7 @@
 #define instruction_pointer(regs) ((regs)->cp0_epc)
 
 extern void show_regs(struct pt_regs *);
-#endif /* !(_LANGUAGE_ASSEMBLY) */
+#endif /* !__ASSEMBLY__ */
 
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/r4kcache.h linux/include/asm-mips/r4kcache.h
--- linux.orig/include/asm-mips/r4kcache.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/r4kcache.h	2002-07-20 01:08:24.000000000 +0000
@@ -3,8 +3,6 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
- * $Id: r4kcache.h,v 1.7 1997/12/18 13:00:45 ralf Exp $
- *
  * FIXME: Handle split L2 caches.
  */
 #ifndef _MIPS_R4KCACHE_H
@@ -13,7 +11,7 @@
 #include <asm/asm.h>
 #include <asm/cacheops.h>
 
-extern inline void flush_icache_line_indexed(unsigned long addr)
+static inline void flush_icache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -26,7 +24,7 @@
 		  "i" (Index_Invalidate_I));
 }
 
-extern inline void flush_dcache_line_indexed(unsigned long addr)
+static inline void flush_dcache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -39,7 +37,7 @@
 		  "i" (Index_Writeback_Inv_D));
 }
 
-extern inline void flush_scache_line_indexed(unsigned long addr)
+static inline void flush_scache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -52,7 +50,7 @@
 		  "i" (Index_Writeback_Inv_SD));
 }
 
-extern inline void flush_icache_line(unsigned long addr)
+static inline void flush_icache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -65,7 +63,7 @@
 		  "i" (Hit_Invalidate_I));
 }
 
-extern inline void flush_dcache_line(unsigned long addr)
+static inline void flush_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -78,7 +76,7 @@
 		  "i" (Hit_Writeback_Inv_D));
 }
 
-extern inline void invalidate_dcache_line(unsigned long addr)
+static inline void invalidate_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -91,7 +89,7 @@
 		  "i" (Hit_Invalidate_D));
 }
 
-extern inline void invalidate_scache_line(unsigned long addr)
+static inline void invalidate_scache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -104,7 +102,7 @@
 		  "i" (Hit_Invalidate_SD));
 }
 
-extern inline void flush_scache_line(unsigned long addr)
+static inline void flush_scache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -120,7 +118,7 @@
 /*
  * The next two are for badland addresses like signal trampolines.
  */
-extern inline void protected_flush_icache_line(unsigned long addr)
+static inline void protected_flush_icache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -136,7 +134,7 @@
 		  "i" (Hit_Invalidate_I));
 }
 
-extern inline void protected_writeback_dcache_line(unsigned long addr)
+static inline void protected_writeback_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -178,7 +176,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_dcache16(void)
+static inline void blast_dcache16(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + dcache_size);
@@ -189,7 +187,21 @@
 	}
 }
 
-extern inline void blast_dcache16_page(unsigned long page)
+static inline void blast_dcache16_wayLSB(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + mips_cpu.dcache.sets * mips_cpu.dcache.linesz);
+	int way;
+
+	while(start < end) {
+		/* LSB of VA select the way */
+		for (way = 0; way < mips_cpu.dcache.ways; way++)
+			cache16_unroll32(start|way,Index_Writeback_Inv_D);
+		start += 0x200;
+	}
+}
+
+static inline void blast_dcache16_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -200,7 +212,7 @@
 	}
 }
 
-extern inline void blast_dcache16_page_indexed(unsigned long page)
+static inline void blast_dcache16_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -211,7 +223,21 @@
 	}
 }
 
-extern inline void blast_icache16(void)
+static inline void blast_dcache16_page_indexed_wayLSB(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+	int way;
+
+	while(start < end) {
+		/* LSB of VA select the way */
+		for (way = 0; way < mips_cpu.dcache.ways; way++)
+			cache16_unroll32(start|way,Index_Writeback_Inv_D);
+		start += 0x200;
+	}
+}
+
+static inline void blast_icache16(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + icache_size);
@@ -222,7 +248,21 @@
 	}
 }
 
-extern inline void blast_icache16_page(unsigned long page)
+static inline void blast_icache16_wayLSB(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + mips_cpu.icache.sets * mips_cpu.icache.linesz);
+	int way;
+
+	while(start < end) {
+		/* LSB of VA select the way */
+		for (way = 0; way < mips_cpu.icache.ways; way++)
+			cache16_unroll32(start|way,Index_Invalidate_I);
+		start += 0x200;
+	}
+}
+
+static inline void blast_icache16_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -233,7 +273,7 @@
 	}
 }
 
-extern inline void blast_icache16_page_indexed(unsigned long page)
+static inline void blast_icache16_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -244,7 +284,7 @@
 	}
 }
 
-extern inline void blast_scache16(void)
+static inline void blast_scache16(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -255,7 +295,7 @@
 	}
 }
 
-extern inline void blast_scache16_page(unsigned long page)
+static inline void blast_scache16_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -266,7 +306,7 @@
 	}
 }
 
-extern inline void blast_scache16_page_indexed(unsigned long page)
+static inline void blast_scache16_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -303,7 +343,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_dcache32(void)
+static inline void blast_dcache32(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + dcache_size);
@@ -314,6 +354,20 @@
 	}
 }
 
+static inline void blast_dcache32_wayLSB(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + mips_cpu.dcache.sets * mips_cpu.dcache.linesz);
+	int way;
+
+	while(start < end) {
+		/* LSB of VA select the way */
+		for (way = 0; way < mips_cpu.dcache.ways; way++)
+			cache32_unroll32(start|way,Index_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
 /*
  * Call this function only with interrupts disabled or R4600 V2.0 may blow
  * up on you.
@@ -326,7 +380,7 @@
  * (Revision 2.0 device errata from IDT available on http://www.idt.com/
  * in .pdf format.)
  */
-extern inline void blast_dcache32_page(unsigned long page)
+static inline void blast_dcache32_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -343,7 +397,7 @@
 	}
 }
 
-extern inline void blast_dcache32_page_indexed(unsigned long page)
+static inline void blast_dcache32_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -354,7 +408,21 @@
 	}
 }
 
-extern inline void blast_icache32(void)
+static inline void blast_dcache32_page_indexed_wayLSB(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+	int way;
+
+	while(start < end) {
+		/* LSB of VA select the way */
+		for (way = 0; way < mips_cpu.dcache.ways; way++)
+			cache32_unroll32(start|way,Index_Writeback_Inv_D);
+		start += 0x400;
+	}
+}
+
+static inline void blast_icache32(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + icache_size);
@@ -365,7 +433,21 @@
 	}
 }
 
-extern inline void blast_icache32_page(unsigned long page)
+static inline void blast_icache32_wayLSB(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + mips_cpu.icache.sets * mips_cpu.icache.linesz);
+	int way;
+
+	while(start < end) {
+		/* LSB of VA select the way */
+		for (way = 0; way < mips_cpu.icache.ways; way++)
+			cache32_unroll32(start|way,Index_Invalidate_I);
+		start += 0x400;
+	}
+}
+
+static inline void blast_icache32_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -376,7 +458,7 @@
 	}
 }
 
-extern inline void blast_icache32_page_indexed(unsigned long page)
+static inline void blast_icache32_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -387,7 +469,7 @@
 	}
 }
 
-extern inline void blast_scache32(void)
+static inline void blast_scache32(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -398,7 +480,7 @@
 	}
 }
 
-extern inline void blast_scache32_page(unsigned long page)
+static inline void blast_scache32_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -409,7 +491,7 @@
 	}
 }
 
-extern inline void blast_scache32_page_indexed(unsigned long page)
+static inline void blast_scache32_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -446,7 +528,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_scache64(void)
+static inline void blast_scache64(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -457,7 +539,7 @@
 	}
 }
 
-extern inline void blast_scache64_page(unsigned long page)
+static inline void blast_scache64_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -468,7 +550,7 @@
 	}
 }
 
-extern inline void blast_scache64_page_indexed(unsigned long page)
+static inline void blast_scache64_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -505,7 +587,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_scache128(void)
+static inline void blast_scache128(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -516,12 +598,12 @@
 	}
 }
 
-extern inline void blast_scache128_page(unsigned long page)
+static inline void blast_scache128_page(unsigned long page)
 {
 	cache128_unroll32(page,Hit_Writeback_Inv_SD);
 }
 
-extern inline void blast_scache128_page_indexed(unsigned long page)
+static inline void blast_scache128_page_indexed(unsigned long page)
 {
 	cache128_unroll32(page,Index_Writeback_Inv_SD);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/reg.h linux/include/asm-mips/reg.h
--- linux.orig/include/asm-mips/reg.h	2000-02-25 06:52:30.000000000 +0000
+++ linux/include/asm-mips/reg.h	2002-07-20 01:08:38.000000000 +0000
@@ -59,7 +59,7 @@
 #define EF_CP0_EPC		40
 #define EF_CP0_BADVADDR		41
 #define EF_CP0_STATUS		42
-#define EF_CP0_CAUSE		44
+#define EF_CP0_CAUSE		43
 
 #define EF_SIZE			180	/* size in bytes */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/scatterlist.h linux/include/asm-mips/scatterlist.h
--- linux.orig/include/asm-mips/scatterlist.h	2001-10-12 22:35:54.000000000 +0000
+++ linux/include/asm-mips/scatterlist.h	2002-07-20 01:08:26.000000000 +0000
@@ -1,20 +1,20 @@
-#ifndef __ASM_MIPS_SCATTERLIST_H
-#define __ASM_MIPS_SCATTERLIST_H
+#ifndef __ASM_SCATTERLIST_H
+#define __ASM_SCATTERLIST_H
 
 struct scatterlist {
-    char *  address;    /* Location data is to be transferred to */
-    unsigned int length;
-    
-    __u32 dvma_address;
+	char * address;		/* Location data is to be transferred to */
+	struct page * page;	/* Location for highmem page, if any */
+	unsigned int length;
+	__u32 dvma_address;
 };
 
 struct mmu_sglist {
-        char *addr;
-        char *__dont_touch;
-        unsigned int len;
-        __u32 dvma_addr;
+	char *addr;
+	char *__dont_touch;
+	unsigned int len;
+	__u32 dvma_addr;
 };
 
 #define ISA_DMA_THRESHOLD (0x00ffffff)
 
-#endif /* __ASM_MIPS_SCATTERLIST_H */
+#endif /* __ASM_SCATTERLIST_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/semaphore.h linux/include/asm-mips/semaphore.h
--- linux.orig/include/asm-mips/semaphore.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/semaphore.h	2002-07-20 01:08:33.000000000 +0000
@@ -94,6 +94,10 @@
 		__down(sem);
 }
 
+/*
+ * Interruptible try to acquire a semaphore.  If we obtained
+ * it, return zero.  If we were interrupted, returns -EINTR
+ */
 static inline int down_interruptible(struct semaphore * sem)
 {
 	int ret = 0;
@@ -108,6 +112,10 @@
 
 #ifndef CONFIG_CPU_HAS_LLDSCD
 
+/*
+ * Non-blockingly attempt to down() a semaphore.
+ * Returns zero if we acquired it
+ */
 static inline int down_trylock(struct semaphore * sem)
 {
 	int ret = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/serial.h linux/include/asm-mips/serial.h
--- linux.orig/include/asm-mips/serial.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/serial.h	2002-07-20 01:08:37.000000000 +0000
@@ -7,7 +7,6 @@
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
-#include <asm/bootinfo.h>
 #include <asm/jazz.h>
 
 /*
@@ -85,6 +84,15 @@
 #define ATLAS_SERIAL_PORT_DEFNS
 #endif
 
+#ifdef CONFIG_MIPS_COBALT
+#define COBALT_BASE_BAUD  (18432000 / 16)
+#define COBALT_SERIAL_PORT_DEFNS		\
+	/* UART CLK   PORT  IRQ  FLAGS    */ 		\
+	{ 0, COBALT_BASE_BAUD, 0xc800000, 7, STD_COM_FLAGS },   /* ttyS0 */
+#else
+#define COBALT_SERIAL_PORT_DEFNS
+#endif
+
 /*
  * Both Galileo boards have the same UART mappings.
  */
@@ -92,12 +100,14 @@
 #include <asm/galileo-boards/ev96100.h>
 #include <asm/galileo-boards/ev96100int.h>
 #define EV96100_SERIAL_PORT_DEFNS                                  \
-    { baud_base: EV96100_BASE_BAUD, port: EV96100_UART0_REGS_BASE, \
-      irq: EV96100INT_UART_0, flags: STD_COM_FLAGS, type: 0x3,   \
-      iomem_base: EV96100_UART0_REGS_BASE },                       \
-    { baud_base: EV96100_BASE_BAUD, port: EV96100_UART1_REGS_BASE, \
-      irq: EV96100INT_UART_0, flags: STD_COM_FLAGS, type: 0x3,   \
-      iomem_base: EV96100_UART1_REGS_BASE },
+    { baud_base: EV96100_BASE_BAUD, irq: EV96100INT_UART_0, \
+      flags: STD_COM_FLAGS,  \
+      iomem_base: EV96100_UART0_REGS_BASE, iomem_reg_shift: 2, \
+      io_type: SERIAL_IO_MEM }, \
+    { baud_base: EV96100_BASE_BAUD, irq: EV96100INT_UART_0, \
+      flags: STD_COM_FLAGS, \
+      iomem_base: EV96100_UART1_REGS_BASE, iomem_reg_shift: 2, \
+      io_type: SERIAL_IO_MEM },
 #else
 #define EV96100_SERIAL_PORT_DEFNS
 #endif
@@ -149,6 +159,17 @@
 #define AU1000_SERIAL_PORT_DEFNS
 #endif
 
+#ifdef CONFIG_TOSHIBA_JMR3927
+#include <asm/jmr3927/jmr3927.h>
+#define TXX927_SERIAL_PORT_DEFNS                              \
+    { baud_base: JMR3927_BASE_BAUD, port: UART0_ADDR, irq: UART0_INT,  \
+      flags: UART0_FLAGS, type: 1 },                        \
+    { baud_base: JMR3927_BASE_BAUD, port: UART1_ADDR, irq: UART1_INT,  \
+      flags: UART1_FLAGS, type: 1 },     
+#else
+#define TXX927_SERIAL_PORT_DEFNS
+#endif
+
 #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
 #define STD_SERIAL_PORT_DEFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
@@ -262,6 +283,7 @@
 	IVR_SERIAL_PORT_DEFNS           \
 	ITE_SERIAL_PORT_DEFNS           \
 	ATLAS_SERIAL_PORT_DEFNS		\
+	COBALT_SERIAL_PORT_DEFNS	\
 	EV96100_SERIAL_PORT_DEFNS	\
 	JAZZ_SERIAL_PORT_DEFNS		\
 	STD_SERIAL_PORT_DEFNS		\
@@ -269,4 +291,5 @@
 	HUB6_SERIAL_PORT_DFNS		\
 	MOMENCO_OCELOT_SERIAL_PORT_DEFNS\
 	AU1000_SERIAL_PORT_DEFNS	\
+        TXX927_SERIAL_PORT_DEFNS        \
 	DDB5477_SERIAL_PORT_DEFNS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sgi/sgi.h linux/include/asm-mips/sgi/sgi.h
--- linux.orig/include/asm-mips/sgi/sgi.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/sgi/sgi.h	2002-07-20 01:08:26.000000000 +0000
@@ -1,10 +1,10 @@
-/* $Id: sgi.h,v 1.1.1.1 1997/06/01 03:17:12 ralf Exp $
+/*
  * sgi.h: Definitions specific to SGI machines.
  *
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  */
-#ifndef _MIPS_SGI_H
-#define _MIPS_SGI_H
+#ifndef __ASM_SGI_SGI_H
+#define __ASM_SGI_SGI_H
 
 /* UP=UniProcessor MP=MultiProcessor(capable) */
 enum sgi_mach {
@@ -39,4 +39,4 @@
 #define SGI_MSB(regaddr)   ((regaddr) | 0x3)
 #endif
 
-#endif /* !(_MIPS_SGI_H) */
+#endif /* __ASM_SGI_SGI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sgi/sgigio.h linux/include/asm-mips/sgi/sgigio.h
--- linux.orig/include/asm-mips/sgi/sgigio.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sgi/sgigio.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,69 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * sgigio.h: Definitions for GIO bus found on SGI IP22 (and others by linux
+ *           unsupported) machines.
+ *
+ * Copyright (C) 2002 Ladislav Michl
+ */
+#ifndef _ASM_SGI_SGIGIO_H
+#define _ASM_SGI_SGIGIO_H
+
+/*
+ * There is 10MB of GIO address space for GIO64 slot devices
+ * slot#   slot type address range            size
+ * -----   --------- ----------------------- -----
+ *   0     GFX       0x1f000000 - 0x1f3fffff   4MB
+ *   1     EXP0      0x1f400000 - 0x1f5fffff   2MB
+ *   2     EXP1      0x1f600000 - 0x1f9fffff   4MB
+ *
+ * There are un-slotted devices, HPC, I/O and misc devices, which are grouped 
+ * into the HPC address space.
+ *   -     MISC      0x1fb00000 - 0x1fbfffff   1MB
+ *      
+ * Following space is reserved and unused
+ *   -     RESERVED  0x18000000 - 0x1effffff 112MB
+ *
+ * The GIO specification tends to use slot numbers while the MC specification 
+ * tends to use slot types.
+ *
+ * slot0  - the "graphics" (GFX) slot but there is no requirement that 
+ *          a graphics dev may only use this slot
+ * slot1  - this is the "expansion"-slot 0 (EXP0), do not confuse with 
+ *          slot 0 (GFX).
+ * slot2  - this is the "expansion"-slot 1 (EXP1), do not confuse with 
+ *          slot 1 (EXP0).
+ */
+
+#define GIO_SLOT_GFX	0
+#define GIO_SLOT_GIO1	1
+#define GIO_SLOT_GIO2	2
+#define GIO_NUM_SLOTS	3
+
+#define GIO_ANY_ID	0xff
+
+#define GIO_VALID_ID_ONLY	0x01
+#define GIO_IFACE_64		0x02
+#define GIO_HAS_ROM		0x04
+
+struct gio_dev {
+	unsigned char	device;
+	unsigned char	revision;
+	unsigned short	vendor;
+	unsigned char	flags;
+
+	unsigned char	slot_number;
+	unsigned long	base_addr;
+	unsigned int	map_size;
+	
+	char		*name;
+	char		slot_name[5];
+};
+
+extern struct gio_dev* gio_find_device(unsigned char device, const struct gio_dev *from);
+
+extern void sgigio_init(void);
+
+#endif /* _ASM_SGI_SGIGIO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sgi/sgihpc.h linux/include/asm-mips/sgi/sgihpc.h
--- linux.orig/include/asm-mips/sgi/sgihpc.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/sgi/sgihpc.h	2002-07-20 01:08:33.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: sgihpc.h,v 1.2 1999/12/06 23:13:21 ralf Exp $
- *
+/*
  * sgihpc.h: Various HPC I/O controller defines.  The HPC is basically
  *           the approximate functional equivalent of the Sun SYSIO
  *           on SGI INDY machines.
@@ -7,34 +6,35 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org)
  */
-#ifndef _MIPS_SGIHPC_H
-#define _MIPS_SGIHPC_H
+#ifndef __ASM_SGI_SGIHPC_H
+#define __ASM_SGI_SGIHPC_H
 
+#include <linux/types.h>
 #include <asm/page.h>
 
-extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */
-extern int sgi_guiness;  /* GUINESS or FULLHOUSE machine. */
-extern int sgi_boardid;  /* Board revision. */
+extern int sgi_has_ioc2;	/* to know if we have older ioc1 or ioc2. */
+extern int sgi_guiness;		/* GUINESS or FULLHOUSE machine. */
+extern int sgi_boardid;		/* Board revision. */
 
 /* An HPC dma descriptor. */
 struct hpc_dma_desc {
-	unsigned int pbuf;      /* physical address of data buffer */
-	unsigned int cntinfo;   /* counter and info bits */
-#define HPCDMA_EOX    0x80000000 /* last desc in chain for tx */
-#define HPCDMA_EOR    0x80000000 /* last desc in chain for rx */
-#define HPCDMA_EOXP   0x40000000 /* end of packet for tx */
-#define HPCDMA_EORP   0x40000000 /* end of packet for rx */
-#define HPCDMA_XIE    0x20000000 /* irq generated when at end of this desc */
-#define HPCDMA_XIU    0x01000000 /* Tx buffer in use by CPU. */
-#define HPCDMA_EIPC   0x00ff0000 /* SEEQ ethernet special xternal bytecount */
-#define HPCDMA_ETXD   0x00008000 /* set to one by HPC when packet tx'd */
-#define HPCDMA_OWN    0x00004000 /* Denotes ring buffer ownership on rx */
-#define HPCDMA_BCNT   0x00003fff /* size in bytes of this dma buffer */
+	u32 pbuf;	/* physical address of data buffer */
+	u32 cntinfo;	/* counter and info bits */
+#define HPCDMA_EOX	0x80000000 /* last desc in chain for tx */
+#define HPCDMA_EOR	0x80000000 /* last desc in chain for rx */
+#define HPCDMA_EOXP	0x40000000 /* end of packet for tx */
+#define HPCDMA_EORP	0x40000000 /* end of packet for rx */
+#define HPCDMA_XIE	0x20000000 /* irq generated when at end of this desc */
+#define HPCDMA_XIU	0x01000000 /* Tx buffer in use by CPU. */
+#define HPCDMA_EIPC	0x00ff0000 /* SEEQ ethernet special xternal bytecount */
+#define HPCDMA_ETXD	0x00008000 /* set to one by HPC when packet tx'd */
+#define HPCDMA_OWN	0x00004000 /* Denotes ring buffer ownership on rx */
+#define HPCDMA_BCNT	0x00003fff /* size in bytes of this dma buffer */
 
-	unsigned int pnext;     /* paddr of next hpc_dma_desc if any */
+	u32 pnext;	/* paddr of next hpc_dma_desc if any */
 };
 
-typedef volatile unsigned int hpcreg;
+typedef volatile u32 hpcreg;
 
 /* HPC1 stuff. */
 
@@ -42,29 +42,35 @@
 
 /* The set of regs for each HPC3 pbus dma channel. */
 struct hpc3_pbus_dmacregs {
-	hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */
-	hpcreg pbdma_dptr; /* pbus dma channel desc ptr */
+	hpcreg pbdma_bptr;	/* pbus dma channel buffer ptr */
+	hpcreg pbdma_dptr;	/* pbus dma channel desc ptr */
 	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg pbdma_ctrl; /* pbus dma channel control reg */
-#define HPC3_PDMACTRL_SEL  0x00000002 /* little endian transfer */
-#define HPC3_PDMACTRL_RCV  0x00000004 /* direction is receive */
-#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */
-#define HPC3_PDMACTRL_ACT  0x00000010 /* start dma transfer */
-#define HPC3_PDMACTRL_LD   0x00000020 /* load enable for ACT */
-#define HPC3_PDMACTRL_RT   0x00000040 /* Use realtime GIO bus servicing */
-#define HPC3_PDMACTRL_HW   0x0000ff00 /* DMA High-water mark */
-#define HPC3_PDMACTRL_FB   0x003f0000 /* Ptr to beginning of fifo */
-#define HPC3_PDMACTRL_FE   0x3f000000 /* Ptr to end of fifo */
+	hpcreg pbdma_ctrl;	/* pbus dma channel control register has 
+				 * copletely different meaning for read 
+				 * compared with write */
+	/* read */
+#define HPC3_PDMACTRL_INT	0x00000001 /* interrupt (cleared after read) */
+#define HPC3_PDMACTRL_ISACT	0x00000002 /* channel active */
+	/* write */
+#define HPC3_PDMACTRL_SEL	0x00000002 /* little endian transfer */
+#define HPC3_PDMACTRL_RCV	0x00000004 /* direction is receive */
+#define HPC3_PDMACTRL_FLSH	0x00000008 /* enable flush for receive DMA */
+#define HPC3_PDMACTRL_ACT	0x00000010 /* start dma transfer */
+#define HPC3_PDMACTRL_LD	0x00000020 /* load enable for ACT */
+#define HPC3_PDMACTRL_RT	0x00000040 /* Use realtime GIO bus servicing */
+#define HPC3_PDMACTRL_HW	0x0000ff00 /* DMA High-water mark */
+#define HPC3_PDMACTRL_FB	0x003f0000 /* Ptr to beginning of fifo */
+#define HPC3_PDMACTRL_FE	0x3f000000 /* Ptr to end of fifo */
 
 	char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */
 };
 
 /* The HPC3 scsi registers, this does not include external ones. */
 struct hpc3_scsiregs {
-	hpcreg cbptr;   /* current dma buffer ptr, diagnostic use only */
-	hpcreg ndptr;   /* next dma descriptor ptr */
+	hpcreg cbptr;	/* current dma buffer ptr, diagnostic use only */
+	hpcreg ndptr;	/* next dma descriptor ptr */
 	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg bcd;     /* byte count info */
+	hpcreg bcd;	/* byte count info */
 #define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */
 #define HPC3_SBCD_XIE     0x00004000 /* Send IRQ when done with cur buf */
 #define HPC3_SBCD_EOX     0x00008000 /* Indicates this is last buf in chain */
@@ -79,9 +85,9 @@
 #define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */
 #define HPC3_SCTRL_PERR   0x80 /* Bad parity on HPC3 iface to scsi controller */
 
-	hpcreg gfptr;   /* current GIO fifo ptr */
-	hpcreg dfptr;   /* current device fifo ptr */
-	hpcreg dconfig; /* DMA configuration register */
+	hpcreg gfptr;	/* current GIO fifo ptr */
+	hpcreg dfptr;	/* current device fifo ptr */
+	hpcreg dconfig;	/* DMA configuration register */
 #define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */
 #define HPC3_SDCFG_D1   0x00006 /* Cycles to spend in D1 state */
 #define HPC3_SDCFG_D2   0x00038 /* Cycles to spend in D2 state */
@@ -93,7 +99,7 @@
 #define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */
 #define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */
 
-	hpcreg pconfig; /* PIO configuration register */
+	hpcreg pconfig;	/* PIO configuration register */
 #define HPC3_SPCFG_P3   0x0003 /* Cycles to spend in P3 state */
 #define HPC3_SPCFG_P2W  0x001c /* Cycles to spend in P2 state for writes */
 #define HPC3_SPCFG_P2R  0x01e0 /* Cycles to spend in P2 state for reads */
@@ -112,12 +118,12 @@
 	hpcreg rx_cbptr;   /* current dma buffer ptr, diagnostic use only */
 	hpcreg rx_ndptr;   /* next dma descriptor ptr */
 	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg rx_bcd;     /* byte count info */
+	hpcreg rx_bcd;	/* byte count info */
 #define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */
 #define HPC3_ERXBCD_XIE     0x20000000 /* HPC3 interrupts cpu at end of this buf */
 #define HPC3_ERXBCD_EOX     0x80000000 /* flags this as end of descriptor chain */
 
-	hpcreg rx_ctrl;    /* control register */
+	hpcreg rx_ctrl;	/* control register */
 #define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */
 #define HPC3_ERXCTRL_STAT6  0x00000040 /* Rdonly irq status */
 #define HPC3_ERXCTRL_STAT7  0x00000080 /* Rdonlt old/new status bit from Seeq */
@@ -126,15 +132,15 @@
 #define HPC3_ERXCTRL_AMASK  0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */
 #define HPC3_ERXCTRL_RBO    0x00000800 /* Receive buffer overflow if set to 1 */
 
-	hpcreg rx_gfptr;   /* current GIO fifo ptr */
-	hpcreg rx_dfptr;   /* current device fifo ptr */
-	hpcreg _unused2;   /* padding */
-	hpcreg rx_reset;   /* reset register */
-#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */
-#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */
-#define HPC3_ERXRST_LBACK  0x4 /* Enable diagnostic loopback mode of Seeq8003 */
+	hpcreg rx_gfptr;	/* current GIO fifo ptr */
+	hpcreg rx_dfptr;	/* current device fifo ptr */
+	hpcreg _unused2;	/* padding */
+	hpcreg rx_reset;	/* reset register */
+#define HPC3_ERXRST_CRESET 0x1	/* Reset dma channel and external controller */
+#define HPC3_ERXRST_CLRIRQ 0x2	/* Clear channel interrupt */
+#define HPC3_ERXRST_LBACK  0x4	/* Enable diagnostic loopback mode of Seeq8003 */
 
-	hpcreg rx_dconfig; /* DMA configuration register */
+	hpcreg rx_dconfig;	/* DMA configuration register */
 #define HPC3_ERXDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
 #define HPC3_ERXDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
 #define HPC3_ERXDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
@@ -144,7 +150,7 @@
 #define HPC3_ERXDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
 #define HPC3_ERXDCFG_PTO   0x30000 /* Programmed timeout value for above two */
 
-	hpcreg rx_pconfig; /* PIO configuration register */
+	hpcreg rx_pconfig;	/* PIO configuration register */
 #define HPC3_ERXPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
 #define HPC3_ERXPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
 #define HPC3_ERXPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
@@ -153,10 +159,10 @@
 	char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */
 
 	/* Transmitter registers. */
-	hpcreg tx_cbptr;   /* current dma buffer ptr, diagnostic use only */
-	hpcreg tx_ndptr;   /* next dma descriptor ptr */
+	hpcreg tx_cbptr;	/* current dma buffer ptr, diagnostic use only */
+	hpcreg tx_ndptr;	/* next dma descriptor ptr */
 	char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg tx_bcd;     /* byte count info */
+	hpcreg tx_bcd;		/* byte count info */
 #define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */
 #define HPC3_ETXBCD_ESAMP   0x10000000 /* if set, too late to add descriptor */
 #define HPC3_ETXBCD_XIE     0x20000000 /* Interrupt cpu at end of cur desc */
@@ -171,8 +177,8 @@
 #define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */
 #define HPC3_ETXCTRL_AMASK  0x00000400 /* Indicates ACTIVE inhibits PIO's */
 
-	hpcreg tx_gfptr;   /* current GIO fifo ptr */
-	hpcreg tx_dfptr;   /* current device fifo ptr */
+	hpcreg tx_gfptr;	/* current GIO fifo ptr */
+	hpcreg tx_dfptr;	/* current device fifo ptr */
 	char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */
 };
 
@@ -199,79 +205,80 @@
 	 * reliably report bits 9:5 of the hpc3 irq status.  I told
 	 * you it was a peculiar bug. ;-)
 	 */
-	hpcreg istat0;      /* Irq status, only bits <4:0> reliable. */
-#define HPC3_ISTAT_PBIMASK  0x0ff  /* irq bits for pbus devs 0 --> 7 */
-#define HPC3_ISTAT_SC0MASK  0x100  /* irq bit for scsi channel 0 */
-#define HPC3_ISTAT_SC1MASK  0x200  /* irq bit for scsi channel 1 */
-
-	hpcreg gio64_misc;  /* GIO64 misc control bits. */
-#define HPC3_GIOMISC_ERTIME   0x1    /* Enable external timer real time. */
-#define HPC3_GIOMISC_DENDIAN  0x2    /* dma descriptor endian, 1=lit 0=big */
-
-	hpcreg eeprom_data; /* EEPROM data reg. */
-#define HPC3_EEPROM_EPROT     0x01   /* Protect register enable */
-#define HPC3_EEPROM_CSEL      0x02   /* Chip select */
-#define HPC3_EEPROM_ECLK      0x04   /* EEPROM clock */
-#define HPC3_EEPROM_DATO      0x08   /* Data out */
-#define HPC3_EEPROM_DATI      0x10   /* Data in */
-
-	hpcreg istat1;      /* Irq status, only bits <9:5> reliable. */
-	hpcreg gio64_estat; /* GIO64 error interrupt status reg. */
-#define HPC3_GIOESTAT_BLMASK  0x000ff  /* Bus lane where bad parity occurred */
-#define HPC3_GIOESTAT_CTYPE   0x00100  /* Bus cycle type, 0=PIO 1=DMA */
-#define HPC3_GIOESTAT_PIDMSK  0x3f700  /* DMA channel parity identifier */
+	hpcreg istat0;		/* Irq status, only bits <4:0> reliable. */
+
+#define HPC3_ISTAT_PBIMASK	0x0ff	/* irq bits for pbus devs 0 --> 7 */
+#define HPC3_ISTAT_SC0MASK	0x100	/* irq bit for scsi channel 0 */
+#define HPC3_ISTAT_SC1MASK	0x200	/* irq bit for scsi channel 1 */
+
+	hpcreg gio64_misc;	/* GIO64 misc control bits. */
+#define HPC3_GIOMISC_ERTIME	0x1	/* Enable external timer real time. */
+#define HPC3_GIOMISC_DENDIAN	0x2	/* dma descriptor endian, 1=lit 0=big */
+
+	hpcreg eeprom_data;	/* EEPROM data reg. */
+#define HPC3_EEPROM_EPROT	0x01	/* Protect register enable */
+#define HPC3_EEPROM_CSEL	0x02	/* Chip select */
+#define HPC3_EEPROM_ECLK	0x04	/* EEPROM clock */
+#define HPC3_EEPROM_DATO	0x08	/* Data out */
+#define HPC3_EEPROM_DATI	0x10	/* Data in */
+
+	hpcreg istat1;		/* Irq status, only bits <9:5> reliable. */
+	hpcreg gio64_estat;	/* GIO64 error interrupt status reg. */
+#define HPC3_GIOESTAT_BLMASK	0x000ff	/* Bus lane where bad parity occurred */
+#define HPC3_GIOESTAT_CTYPE	0x00100	/* Bus cycle type, 0=PIO 1=DMA */
+#define HPC3_GIOESTAT_PIDMSK	0x3f700	/* DMA channel parity identifier */
 
 	/* Now direct PIO per-HPC3 peripheral access to external regs. */
-	char _unused2[0x13fec]; /* Trust me... */
-	hpcreg scsi0_ext[256];  /* SCSI channel 0 external regs */
-	char _unused3[0x07c00]; /* Trust me... */
-	hpcreg scsi1_ext[256];  /* SCSI channel 1 external regs */
-	char _unused4[0x07c00]; /* It'll only hurt a little... */
+	char _unused2[0x13fec];	/* Trust me... */
+	hpcreg scsi0_ext[256];	/* SCSI channel 0 external regs */
+	char _unused3[0x07c00];	/* Trust me... */
+	hpcreg scsi1_ext[256];	/* SCSI channel 1 external regs */
+	char _unused4[0x07c00];	/* It'll only hurt a little... */
 
-	/* Did DaveM forget the ethernet external regs?
-	 * Anyhow, they're not here and we need some padding instead.
+	/* Ethernet external registers. Noone use them so we need some 
+	 * padding instead.
 	 */
 	char _unused5[0x04000]; /* It'll hurt a lot if you leave this out */
 
 	/* Per-peripheral device external registers and dma/pio control. */
-	hpcreg pbus_extregs[16][256]; /* 2nd indice indexes controller */
-	hpcreg pbus_dmacfgs[8][128]; /* 2nd indice indexes controller */
-#define HPC3_PIODCFG_D3R    0x00000001 /* Cycles to spend in D3 for reads */
-#define HPC3_PIODCFG_D4R    0x0000001e /* Cycles to spend in D4 for reads */
-#define HPC3_PIODCFG_D5R    0x000001e0 /* Cycles to spend in D5 for reads */
-#define HPC3_PIODCFG_D3W    0x00000200 /* Cycles to spend in D3 for writes */
-#define HPC3_PIODCFG_D4W    0x00003c00 /* Cycles to spend in D4 for writes */
-#define HPC3_PIODCFG_D5W    0x0003c000 /* Cycles to spend in D5 for writes */
-#define HPC3_PIODCFG_HWORD  0x00040000 /* Enable 16-bit dma access mode */
-#define HPC3_PIODCFG_EHI    0x00080000 /* Places halfwords on high 16 bits of bus */
-#define HPC3_PIODCFG_RTIME  0x00200000 /* Make this device real time on GIO bus */
-#define HPC3_PIODCFG_BURST  0x07c00000 /* 5 bit burst count for DMA device */
-#define HPC3_PIODCFG_DRQLV  0x08000000 /* Use live pbus_dreq unsynchronized signal */
-
-	hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */
-#define HPC3_PIOPCFG_RP2    0x00001  /* Cycles to spend in P2 state for reads */
-#define HPC3_PIOPCFG_RP3    0x0001e  /* Cycles to spend in P3 state for reads */
-#define HPC3_PIOPCFG_RP4    0x001e0  /* Cycles to spend in P4 state for reads */
-#define HPC3_PIOPCFG_WP2    0x00200  /* Cycles to spend in P2 state for writes */
-#define HPC3_PIOPCFG_WP3    0x03c00  /* Cycles to spend in P3 state for writes */
-#define HPC3_PIOPCFG_WP4    0x3c000  /* Cycles to spend in P4 state for writes */
-#define HPC3_PIOPCFG_HW     0x40000  /* Enable 16-bit PIO accesses */
-#define HPC3_PIOPCFG_EHI    0x80000  /* Place even address bits in bits <15:8> */
+	hpcreg pbus_extregs[16][256];	/* 2nd indice indexes controller */
+	hpcreg pbus_dmacfgs[8][128];	/* 2nd indice indexes controller */
+#define HPC3_PIODCFG_D3R    0x00000001	/* Cycles to spend in D3 for reads */
+#define HPC3_PIODCFG_D4R    0x0000001e	/* Cycles to spend in D4 for reads */
+#define HPC3_PIODCFG_D5R    0x000001e0	/* Cycles to spend in D5 for reads */
+#define HPC3_PIODCFG_D3W    0x00000200	/* Cycles to spend in D3 for writes */
+#define HPC3_PIODCFG_D4W    0x00003c00	/* Cycles to spend in D4 for writes */
+#define HPC3_PIODCFG_D5W    0x0003c000	/* Cycles to spend in D5 for writes */
+#define HPC3_PIODCFG_HWORD  0x00040000	/* Enable 16-bit dma access mode */
+#define HPC3_PIODCFG_EHI    0x00080000	/* Places halfwords on high 16 bits of bus */
+#define HPC3_PIODCFG_RTIME  0x00200000	/* Make this device real time on GIO bus */
+#define HPC3_PIODCFG_BURST  0x07c00000	/* 5 bit burst count for DMA device */
+#define HPC3_PIODCFG_DRQLV  0x08000000	/* Use live pbus_dreq unsynchronized signal */
+
+	hpcreg pbus_piocfgs[64][10];	/* 2nd indice indexes controller */
+#define HPC3_PIOPCFG_RP2    0x00001	/* Cycles to spend in P2 state for reads */
+#define HPC3_PIOPCFG_RP3    0x0001e	/* Cycles to spend in P3 state for reads */
+#define HPC3_PIOPCFG_RP4    0x001e0	/* Cycles to spend in P4 state for reads */
+#define HPC3_PIOPCFG_WP2    0x00200	/* Cycles to spend in P2 state for writes */
+#define HPC3_PIOPCFG_WP3    0x03c00	/* Cycles to spend in P3 state for writes */
+#define HPC3_PIOPCFG_WP4    0x3c000	/* Cycles to spend in P4 state for writes */
+#define HPC3_PIOPCFG_HW     0x40000	/* Enable 16-bit PIO accesses */
+#define HPC3_PIOPCFG_EHI    0x80000	/* Place even address bits in bits <15:8> */
 
 	/* PBUS PROM control regs. */
-	hpcreg pbus_promwe;     /* PROM write enable register */
-#define HPC3_PROM_WENAB     0x1 /* Enable writes to the PROM */
+	hpcreg pbus_promwe;	/* PROM write enable register */
+#define HPC3_PROM_WENAB	    0x1	/* Enable writes to the PROM */
 
 	char _unused6[0x800 - sizeof(hpcreg)];
-	hpcreg pbus_promswap;   /* Chip select swap reg */
-#define HPC3_PROM_SWAP      0x1 /* invert GIO addr bit to select prom0 or prom1 */
+	hpcreg pbus_promswap;	/* Chip select swap reg */
+#define HPC3_PROM_SWAP      0x1	/* invert GIO addr bit to select prom0 or prom1 */
 
 	char _unused7[0x800 - sizeof(hpcreg)];
-	hpcreg pbus_gout;       /* PROM general purpose output reg */
-#define HPC3_PROM_STAT      0x1 /* General purpose status bit in gout */
+	hpcreg pbus_gout;	/* PROM general purpose output reg */
+#define HPC3_PROM_STAT      0x1	/* General purpose status bit in gout */
 
 	char _unused8[0x1000 - sizeof(hpcreg)];
-	hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */
+	hpcreg pbus_promram[16384];	/* 64k of PROM battery backed ram */
 };
 
 /* It is possible to have two HPC3's within the address space on
@@ -280,8 +287,8 @@
  * 1 if present lives at address 0x1fb00000.
  */
 extern struct hpc3_regs *hpc3c0, *hpc3c1;
-#define HPC3_CHIP0_PBASE   0x1fb80000 /* physical */
-#define HPC3_CHIP1_PBASE   0x1fb00000 /* physical */
+#define HPC3_CHIP0_PBASE	0x1fb80000	/* physical */
+#define HPC3_CHIP1_PBASE	0x1fb00000	/* physical */
 
 /* Control and misc status information, these live in pbus channel 6. */
 struct hpc3_miscregs {
@@ -297,35 +304,35 @@
 	hpcreg _unused3;
 	hpcreg read, _unused4;
 	hpcreg dselect;
-#define HPC3_DSELECT_SCLK10MHZ   0x00 /* use 10MHZ serial clock */
-#define HPC3_DSELECT_ISDNB       0x01 /* enable isdn B */
-#define HPC3_DSELECT_ISDNA       0x02 /* enable isdn A */
-#define HPC3_DSELECT_LPR         0x04 /* use parallel DMA */
-#define HPC3_DSELECT_SCLK667MHZ  0x10 /* use 6.67MHZ serial clock */
-#define HPC3_DSELECT_SCLKEXT     0x20 /* use external serial clock */
+#define HPC3_DSELECT_SCLK10MHZ	0x00	/* use 10MHZ serial clock */
+#define HPC3_DSELECT_ISDNB	0x01	/* enable isdn B */
+#define HPC3_DSELECT_ISDNA	0x02	/* enable isdn A */
+#define HPC3_DSELECT_LPR	0x04	/* use parallel DMA */
+#define HPC3_DSELECT_SCLK667MHZ	0x10	/* use 6.67MHZ serial clock */
+#define HPC3_DSELECT_SCLKEXT	0x20	/* use external serial clock */
 
 	hpcreg _unused5;
 	hpcreg write1;
-#define HPC3_WRITE1_PRESET    0x01  /* 0=LPR_RESET, 1=NORMAL */
-#define HPC3_WRITE1_KMRESET   0x02  /* 0=KBDMOUSE_RESET, 1=NORMAL */
-#define HPC3_WRITE1_ERESET    0x04  /* 0=EISA_RESET, 1=NORMAL */
-#define HPC3_WRITE1_GRESET    0x08  /* 0=MAGIC_GIO_RESET, 1=NORMAL */
-#define HPC3_WRITE1_LC0OFF    0x10  /* turn led off (guiness=red, else green) */
-#define HPC3_WRITE1_LC1OFF    0x20  /* turn led off (guiness=green, else amber) */
+#define HPC3_WRITE1_PRESET	0x01	/* 0=LPR_RESET, 1=NORMAL */
+#define HPC3_WRITE1_KMRESET	0x02	/* 0=KBDMOUSE_RESET, 1=NORMAL */
+#define HPC3_WRITE1_ERESET	0x04	/* 0=EISA_RESET, 1=NORMAL */
+#define HPC3_WRITE1_GRESET	0x08	/* 0=MAGIC_GIO_RESET, 1=NORMAL */
+#define HPC3_WRITE1_LC0OFF	0x10	/* turn led off (guiness=red, else green) */
+#define HPC3_WRITE1_LC1OFF	0x20	/* turn led off (guiness=green, else amber) */
 
 	hpcreg _unused6;
 	hpcreg write2;
-#define HPC3_WRITE2_NTHRESH  0x01 /* use 4.5db threshhold */
-#define HPC3_WRITE2_TPSPEED  0x02 /* use 100ohm TP speed */
-#define HPC3_WRITE2_EPSEL    0x04 /* force cable mode: 1=AUI 0=TP */
-#define HPC3_WRITE2_EASEL    0x08 /* 1=autoselect 0=manual cable selection */
-#define HPC3_WRITE2_U1AMODE  0x10 /* 1=PC 0=MAC UART mode */
-#define HPC3_WRITE2_U0AMODE  0x20 /* 1=PC 0=MAC UART mode */
-#define HPC3_WRITE2_MLO      0x40 /* 1=4.75V 0=+5V */
-#define HPC3_WRITE2_MHI      0x80 /* 1=5.25V 0=+5V */
+#define HPC3_WRITE2_NTHRESH	0x01	/* use 4.5db threshhold */
+#define HPC3_WRITE2_TPSPEED	0x02	/* use 100ohm TP speed */
+#define HPC3_WRITE2_EPSEL	0x04	/* force cable mode: 1=AUI 0=TP */
+#define HPC3_WRITE2_EASEL	0x08	/* 1=autoselect 0=manual cable selection */
+#define HPC3_WRITE2_U1AMODE	0x10	/* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_U0AMODE	0x20	/* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_MLO		0x40	/* 1=4.75V 0=+5V */
+#define HPC3_WRITE2_MHI		0x80	/* 1=5.25V 0=+5V */
 };
 extern struct hpc3_miscregs *hpc3mregs;
-#define HPC3_MREGS_PBASE   0x1fbd9800 /* physical */
+#define HPC3_MREGS_PBASE	0x1fbd9800	/* physical */
 
 /* We need software copies of these because they are write only. */
 extern unsigned int sgi_hpc_write1, sgi_hpc_write2;
@@ -369,4 +376,4 @@
 
 extern void sgihpc_init(void);
 
-#endif /* !(_MIPS_SGIHPC_H) */
+#endif /* __ASM_SGI_SGIHPC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sgi/sgimc.h linux/include/asm-mips/sgi/sgimc.h
--- linux.orig/include/asm-mips/sgi/sgimc.h	2001-04-14 03:26:07.000000000 +0000
+++ linux/include/asm-mips/sgi/sgimc.h	2002-07-20 01:08:40.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: sgimc.h,v 1.1.1.1 1997/06/01 03:17:13 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sgi/sgint23.h linux/include/asm-mips/sgi/sgint23.h
--- linux.orig/include/asm-mips/sgi/sgint23.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/sgi/sgint23.h	2002-07-20 01:08:25.000000000 +0000
@@ -8,99 +8,127 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 98, 1999, 2000 Ralf Baechle
  * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections
+ * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz)
  */
 #ifndef _ASM_SGI_SGINT23_H
 #define _ASM_SGI_SGINT23_H
 
 /* These are the virtual IRQ numbers, we divide all IRQ's into
  * 'spaces', the 'space' determines where and how to enable/disable
- * that particular IRQ on an SGI machine.  Add new 'spaces' as new
- * IRQ hardware is supported.
+ * that particular IRQ on an SGI machine. HPC DMA and MC DMA interrups
+ * are not supported this way. Driver is supposed to allocate HPC/MC 
+ * interrupt as shareable and then look to proper status bit (see
+ * HAL2 driver). This will prevent many complications, trust me ;-) 
+ *	--ladis
  */
-#define SGINT_LOCAL0   0   /* INDY has 8 local0 irq levels */
-#define SGINT_LOCAL1   8   /* INDY has 8 local1 irq levels */
-#define SGINT_LOCAL2   16  /* INDY has 8 local2 vectored irq levels */
-#define SGINT_LOCAL3   24  /* INDY has 8 local3 vectored irq levels */
-#define SGINT_GIO      32  /* INDY has 9 GIO irq levels */
-#define SGINT_HPCDMA   41  /* INDY has 11 HPCDMA irq _sources_ */
-#define SGINT_END      52  /* End of 'spaces' */
+#define SGINT_CPU	 0	/* MIPS CPU define 8 interrupt sources */
+#define SGINT_LOCAL0	 8	/* INDY has 8 local0 irq levels */
+#define SGINT_LOCAL1	16	/* INDY has 8 local1 irq levels */
+#define SGINT_LOCAL2	24	/* INDY has 8 local2 vectored irq levels */
+#define SGINT_LOCAL3	32	/* INDY has 8 local3 vectored irq levels */
+#define SGINT_END	40	/* End of 'spaces' */
 
 /*
  * Individual interrupt definitions for the INDY and Indigo2
  */
 
+#define SGI_SOFT_0_IRQ	SGINT_CPU + 0
+#define SGI_SOFT_1_IRQ	SGINT_CPU + 1
+#define SGI_LOCAL_0_IRQ	SGINT_CPU + 2
+#define SGI_LOCAL_1_IRQ	SGINT_CPU + 3
+#define SGI_8254_0_IRQ	SGINT_CPU + 4
+#define SGI_8254_1_IRQ	SGINT_CPU + 5
+#define SGI_BUSERR_IRQ	SGINT_CPU + 6
+#define SGI_TIMER_IRQ	SGINT_CPU + 7
+
+#define SGI_FIFO_IRQ	SGINT_LOCAL0 + 0	/* FIFO full */
+#define SGI_GIO_0_IRQ	SGI_FIFO_IRQ		/* GIO-0 */	
 #define SGI_WD93_0_IRQ	SGINT_LOCAL0 + 1	/* 1st onboard WD93 */
 #define SGI_WD93_1_IRQ	SGINT_LOCAL0 + 2	/* 2nd onboard WD93 */
 #define SGI_ENET_IRQ	SGINT_LOCAL0 + 3	/* onboard ethernet */
+#define SGI_MCDMA_IRQ	SGINT_LOCAL0 + 4	/* MC DMA done */
+#define SGI_PARPORT_IRQ	SGINT_LOCAL0 + 5	/* Parallel port */
+#define SGI_GIO_1_IRQ	SGINT_LOCAL0 + 6	/* GE / GIO-1 / 2nd-HPC */
+#define SGI_MAP_0_IRQ	SGINT_LOCAL0 + 7	/* Mappable interrupt 0 */
 
+#define SGI_GPL0_IRQ	SGINT_LOCAL1 + 0	/* General Purpose LOCAL1_N<0> */
 #define SGI_PANEL_IRQ	SGINT_LOCAL1 + 1	/* front panel */
-
+#define SGI_GPL2_IRQ	SGINT_LOCAL1 + 2	/* General Purpose LOCAL1_N<2> */
+#define SGI_MAP_1_IRQ	SGINT_LOCAL1 + 3	/* Mappable interrupt 1 */
+#define SGI_HPCDMA_IRQ	SGINT_LOCAL1 + 4	/* HPC DMA done */
+#define SGI_ACFAIL_IRQ	SGINT_LOCAL1 + 5	/* AC fail */
+#define SGI_VINO_IRQ	SGINT_LOCAL1 + 6	/* Indy VINO */
+#define SGI_GIO_2_IRQ	SGINT_LOCAL1 + 7	/* Vert retrace / GIO-2 */
+
+/* Mapped interrupts. These interrupts may be mapped to either 0, or 1
+ * We map them to 0 */
+#define SGI_VERT_IRQ	SGINT_LOCAL2 + 0	/* INT3: newport vertical status */
 #define SGI_EISA_IRQ	SGINT_LOCAL2 + 3	/* EISA interrupts */
-#define SGI_KEYBOARD_IRQ	SGINT_LOCAL2 + 4	/* keyboard */
+#define SGI_KEYBD_IRQ	SGINT_LOCAL2 + 4	/* keyboard */
 #define SGI_SERIAL_IRQ	SGINT_LOCAL2 + 5	/* onboard serial */
 
 /* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */
-#define SGI_INT2_BASE 0x1fbd9000 /* physical */
-#define SGI_INT3_BASE 0x1fbd9880 /* physical */
+#define SGI_INT2_BASE	0x1fbd9000	/* physical */
+#define SGI_INT3_BASE	0x1fbd9880	/* physical */
 
 struct sgi_ioc_ints {
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
-	volatile unsigned char istat0;    /* Interrupt status zero */
+	volatile unsigned char istat0;	/* Interrupt status zero */
 #else
-	volatile unsigned char istat0;    /* Interrupt status zero */
+	volatile unsigned char istat0;	/* Interrupt status zero */
 	unsigned char _unused0[3];
 #endif
-#define ISTAT0_FFULL           0x01
-#define ISTAT0_SCSI0           0x02
-#define ISTAT0_SCSI1           0x04
-#define ISTAT0_ENET            0x08
-#define ISTAT0_GFXDMA          0x10
-#define ISTAT0_LPR             0x20
-#define ISTAT0_HPC2            0x40
-#define ISTAT0_LIO2            0x80
-
+#define ISTAT0_FFULL	0x01
+#define ISTAT0_SCSI0	0x02
+#define ISTAT0_SCSI1	0x04
+#define ISTAT0_ENET	0x08
+#define ISTAT0_GFXDMA	0x10
+#define ISTAT0_LPR	0x20
+#define ISTAT0_HPC2	0x40
+#define ISTAT0_LIO2	0x80
+	
 #ifdef __MIPSEB__
 	unsigned char _unused1[3];
-	volatile unsigned char imask0;    /* Interrupt mask zero */
+	volatile unsigned char imask0;	/* Interrupt mask zero */
 	unsigned char _unused2[3];
-	volatile unsigned char istat1;    /* Interrupt status one */
+	volatile unsigned char istat1;	/* Interrupt status one */
 #else
-	volatile unsigned char imask0;    /* Interrupt mask zero */
+	volatile unsigned char imask0;	/* Interrupt mask zero */
 	unsigned char _unused1[3];
-	volatile unsigned char istat1;    /* Interrupt status one */
+	volatile unsigned char istat1;	/* Interrupt status one */
 	unsigned char _unused2[3];
 #endif
-#define ISTAT1_ISDNI           0x01
-#define ISTAT1_PWR             0x02
-#define ISTAT1_ISDNH           0x04
-#define ISTAT1_LIO3            0x08
-#define ISTAT1_HPC3            0x10
-#define ISTAT1_AFAIL           0x20
-#define ISTAT1_VIDEO           0x40
-#define ISTAT1_GIO2            0x80
-
+#define ISTAT1_ISDNI	0x01
+#define ISTAT1_PWR	0x02
+#define ISTAT1_ISDNH	0x04
+#define ISTAT1_LIO3	0x08
+#define ISTAT1_HPC3	0x10
+#define ISTAT1_AFAIL	0x20
+#define ISTAT1_VIDEO	0x40
+#define ISTAT1_GIO2	0x80
+	
 #ifdef __MIPSEB__
 	unsigned char _unused3[3];
-	volatile unsigned char imask1;    /* Interrupt mask one */
+	volatile unsigned char imask1;		/* Interrupt mask one */
 	unsigned char _unused4[3];
-	volatile unsigned char vmeistat;  /* VME interrupt status */
+	volatile unsigned char vmeistat;	/* VME interrupt status */
 	unsigned char _unused5[3];
-	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+	volatile unsigned char cmeimask0;	/* VME interrupt mask zero */
 	unsigned char _unused6[3];
-	volatile unsigned char cmeimask1; /* VME interrupt mask one */
+	volatile unsigned char cmeimask1;	/* VME interrupt mask one */
 	unsigned char _unused7[3];
-	volatile unsigned char cmepol;    /* VME polarity */
+	volatile unsigned char cmepol;		/* VME polarity */
 #else
-	volatile unsigned char imask1;    /* Interrupt mask one */
+	volatile unsigned char imask1;		/* Interrupt mask one */
 	unsigned char _unused3[3];
-	volatile unsigned char vmeistat;  /* VME interrupt status */
+	volatile unsigned char vmeistat;	/* VME interrupt status */
 	unsigned char _unused4[3];
-	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+	volatile unsigned char cmeimask0;	/* VME interrupt mask zero */
 	unsigned char _unused5[3];
-	volatile unsigned char cmeimask1; /* VME interrupt mask one */
+	volatile unsigned char cmeimask1;	/* VME interrupt mask one */
 	unsigned char _unused6[3];
-	volatile unsigned char cmepol;    /* VME polarity */
+	volatile unsigned char cmepol;		/* VME polarity */
 	unsigned char _unused7[3];
 #endif
 };
@@ -108,21 +136,21 @@
 struct sgi_ioc_timers {
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
-	volatile unsigned char tcnt0;  /* counter 0 */
+	volatile unsigned char tcnt0;	/* counter 0 */
 	unsigned char _unused1[3];
-	volatile unsigned char tcnt1;  /* counter 1 */
+	volatile unsigned char tcnt1;	/* counter 1 */
 	unsigned char _unused2[3];
-	volatile unsigned char tcnt2;  /* counter 2 */
+	volatile unsigned char tcnt2;	/* counter 2 */
 	unsigned char _unused3[3];
-	volatile unsigned char tcword; /* control word */
+	volatile unsigned char tcword;	/* control word */
 #else
-	volatile unsigned char tcnt0;  /* counter 0 */
+	volatile unsigned char tcnt0;	/* counter 0 */
 	unsigned char _unused0[3];
-	volatile unsigned char tcnt1;  /* counter 1 */
+	volatile unsigned char tcnt1;	/* counter 1 */
 	unsigned char _unused1[3];
-	volatile unsigned char tcnt2;  /* counter 2 */
+	volatile unsigned char tcnt2;	/* counter 2 */
 	unsigned char _unused2[3];
-	volatile unsigned char tcword; /* control word */
+	volatile unsigned char tcword;	/* control word */
 	unsigned char _unused3[3];
 #endif
 };
@@ -155,22 +183,22 @@
 struct sgi_int2_regs {
 	struct sgi_ioc_ints ints;
 
-	volatile u32 ledbits; 		  /* LED control bits */
-#define INT2_LED_TXCLK         0x01       /* GPI to TXCLK enable */
-#define INT2_LED_SERSLCT0      0x02       /* serial port0: 0=apple 1=pc */
-#define INT2_LED_SERSLCT1      0x04       /* serial port1: 0=apple 1=pc */
-#define INT2_LED_CHEAPER       0x08       /* 0=cheapernet 1=ethernet */
-#define INT2_LED_POWEROFF      0x10       /* Power-off request, active high */
+	volatile u32 ledbits;		/* LED control bits */
+#define INT2_LED_TXCLK		0x01	/* GPI to TXCLK enable */
+#define INT2_LED_SERSLCT0	0x02	/* serial port0: 0=apple 1=pc */
+#define INT2_LED_SERSLCT1	0x04	/* serial port1: 0=apple 1=pc */
+#define INT2_LED_CHEAPER	0x08	/* 0=cheapernet 1=ethernet */
+#define INT2_LED_POWEROFF	0x10	/* Power-off request, active high */
 
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
-	volatile unsigned char tclear;    /* Timer clear strobe address */
+	volatile unsigned char tclear;	/* Timer clear strobe address */
 #else
-	volatile unsigned char tclear;    /* Timer clear strobe address */
+	volatile unsigned char tclear;	/* Timer clear strobe address */
 	unsigned char _unused0[3];
 #endif
-#define INT2_TCLEAR_T0CLR      0x1        /* Clear timer0 IRQ */
-#define INT2_TCLEAR_T1CLR      0x2        /* Clear timer1 IRQ */
+#define INT2_TCLEAR_T0CLR	0x1	/* Clear timer0 IRQ */
+#define INT2_TCLEAR_T1CLR	0x2	/* Clear timer1 IRQ */
 /* I am guesing there are only two unused registers here 
  * but I could be wrong...			- andrewb
  */
@@ -184,12 +212,12 @@
 
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
-	volatile unsigned char tclear;		/* Timer clear strobe address */
+	volatile unsigned char tclear;	/* Timer clear strobe address */
 #else
-	volatile unsigned char tclear;		/* Timer clear strobe address */
+	volatile unsigned char tclear;	/* Timer clear strobe address */
 	unsigned char _unused0[3];
 #endif
-	volatile u32 estatus;			/* Error status reg */
+	volatile u32 estatus;		/* Error status reg */
 	u32 _unused1[2];
 	struct sgi_ioc_timers timers;
 };
@@ -200,7 +228,4 @@
 extern struct sgi_ioc_timers *ioc_timers;
 extern volatile unsigned char *ioc_tclear;
 
-extern void sgint_init(void);
-extern void indy_timer_init(void);
-
 #endif /* _ASM_SGI_SGINT23_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sgialib.h linux/include/asm-mips/sgialib.h
--- linux.orig/include/asm-mips/sgialib.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/sgialib.h	2002-07-20 01:08:27.000000000 +0000
@@ -8,7 +8,6 @@
 
 #include <asm/sgiarcs.h>
 
-extern struct linux_promblock *sgi_pblock;
 extern struct linux_romvec *romvec;
 extern int prom_argc;
 extern char **prom_argv, **prom_envp;
@@ -43,7 +42,7 @@
 extern pcomponent *prom_getsibling(pcomponent *this);
 
 /* Get child component of THIS. */
-extern pcomponent *prom_getchild(pcomponent *this);
+extern pcomponent *ArcGetChild(pcomponent *this);
 
 /* Get parent component of CHILD. */
 extern pcomponent *prom_getparent(pcomponent *child);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sgiarcs.h linux/include/asm-mips/sgiarcs.h
--- linux.orig/include/asm-mips/sgiarcs.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/sgiarcs.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,12 +1,18 @@
-/* $Id: sgiarcs.h,v 1.3 1999/02/25 20:55:08 tsbogend Exp $
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * SGI ARCS firmware interface defines.
+ * ARC firmware interface defines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SGIARCS_H
 #define _ASM_SGIARCS_H
 
+#include <linux/config.h>
 #include <asm/arc/types.h>
 
 /* Various ARCS error codes. */
@@ -71,16 +77,16 @@
 
 /* A prom device tree component. */
 struct linux_component {
-	enum linux_devclass     class;   /* node class */
-	enum linux_devtypes     type;    /* node type */
-	enum linux_identifier   iflags;  /* node flags */
-	unsigned short          vers;    /* node version */
-	unsigned short          rev;     /* node revision */
-	unsigned long           key;     /* completely magic */
-	unsigned long           amask;   /* XXX affinity mask??? */
-	unsigned long           cdsize;  /* size of configuration data */
-	unsigned long           ilen;    /* length of string identifier */
-	char                   *iname;   /* string identifier */
+	enum linux_devclass     class;	/* node class */
+	enum linux_devtypes     type;	/* node type */
+	enum linux_identifier   iflags;	/* node flags */
+	USHORT 			vers;	/* node version */
+	USHORT 			rev;	/* node revision */
+	ULONG 			key;	/* completely magic */
+	ULONG 			amask;	/* XXX affinity mask??? */
+	ULONG			cdsize;	/* size of configuration data */
+	ULONG			ilen;	/* length of string identifier */
+	_PULONG			iname;	/* string identifier */
 };
 typedef struct linux_component pcomponent;
 
@@ -118,9 +124,9 @@
 };
 
 struct linux_mdesc {
-        union linux_memtypes type;
-	unsigned long base;
-	unsigned long pages;
+	union linux_memtypes type;
+	ULONG base;
+	ULONG pages;
 };
 
 /* Time of day descriptor. */
@@ -136,7 +142,7 @@
 
 /* ARCS virtual dirents. */
 struct linux_vdirent {
-	unsigned long namelen;
+	ULONG namelen;
 	unsigned char attr;
 	char fname[32]; /* XXX imperical, should be a define */
 };
@@ -170,110 +176,97 @@
 	struct linux_bigint   begin;
 	struct linux_bigint   end;
 	struct linux_bigint   cur;
-	enum linux_devtypes dtype;
+	enum linux_devtypes   dtype;
 	unsigned long         namelen;
 	unsigned char         attr;
 	char                  name[32]; /* XXX imperical, should be define */
 };
 
+/* This describes the vector containing function pointers to the ARC
+   firmware functions.  */
 struct linux_romvec {
-	/* Load an executable image. */
-	long (*load)(char *file, unsigned long end,
-		     unsigned long *start_pc,
-		     unsigned long *end_addr);
-
-	/* Invoke a standalong image. */
-	long (*invoke)(unsigned long startpc, unsigned long sp,
-		       long argc, char **argv, char **envp);
-
-	/* Load and begin execution of a standalong image. */
-	long (*exec)(char *file, long argc, char **argv, char **envp);
-
-	void (*halt)(void) __attribute__((noreturn)); 	/* Halt the machine. */
-	void (*pdown)(void) __attribute__((noreturn));    /* Power down the machine. */
-	void (*restart)(void) __attribute__((noreturn));  /* XXX soft reset??? */
-	void (*reboot)(void) __attribute__((noreturn));   /* Reboot the machine. */
-	void (*imode)(void) __attribute__((noreturn));    /* Enter PROM interactive mode. */
-	int _unused1; /* padding */
+	LONG	load;			/* Load an executable image. */
+	LONG	invoke;			/* Invoke a standalong image. */
+	LONG	exec;			/* Load and begin execution of a
+					   standalone image. */
+	LONG	halt;			/* Halt the machine. */
+	LONG	pdown;			/* Power down the machine. */
+	LONG	restart;		/* XXX soft reset??? */
+	LONG	reboot;			/* Reboot the machine. */
+	LONG	imode;			/* Enter PROM interactive mode. */
+	LONG	_unused1;		/* Was ReturnFromMain(). */
 
 	/* PROM device tree interface. */
-	pcomponent *(*next_component)(pcomponent *this);
-	pcomponent *(*child_component)(pcomponent *this);
-	pcomponent *(*parent_component)(pcomponent *this);
-	long (*component_data)(void *opaque_data, pcomponent *this);
-	pcomponent *(*child_add)(pcomponent *this,
-				 pcomponent *tmp,
-				 void *opaque_data);
-	long (*comp_del)(pcomponent *this);
-	pcomponent *(*component_by_path)(char *file);
+	LONG	next_component;
+	LONG	child_component;
+	LONG	parent_component;
+	LONG	component_data;
+	LONG	child_add;
+	LONG	comp_del;
+	LONG	component_by_path;
 
 	/* Misc. stuff. */
-	long (*cfg_save)(void);
-	struct linux_sysid *(*get_sysid)(void);
+	LONG	cfg_save;
+	LONG	get_sysid;
 
 	/* Probing for memory. */
-	struct linux_mdesc *(*get_mdesc)(struct linux_mdesc *curr);
-	long _unused2; /* padding */
+	LONG	get_mdesc;
+	LONG	_unused2;		/* was Signal() */
 
-	struct linux_tinfo *(*get_tinfo)(void);
-	unsigned long (*get_rtime)(void);
+	LONG	get_tinfo;
+	LONG	get_rtime;
 
 	/* File type operations. */
-	long (*get_vdirent)(unsigned long fd, struct linux_vdirent *entry,
-			    unsigned long num, unsigned long *count);
-	long (*open)(char *file, enum linux_omode mode, unsigned long *fd);
-	long (*close)(unsigned long fd);
-	long (*read)(unsigned long fd, void *buffer, unsigned long num,
-		     unsigned long *count);
-	long (*get_rstatus)(unsigned long fd);
-	long (*write)(unsigned long fd, void *buffer, unsigned long num,
-		      unsigned long *count);
-	long (*seek)(unsigned long fd, struct linux_bigint *offset,
-		     enum linux_seekmode smode);
-	long (*mount)(char *file, enum linux_mountops op);
+	LONG	get_vdirent;
+	LONG	open;
+	LONG	close;
+	LONG	read;
+	LONG	get_rstatus;
+	LONG	write;
+	LONG	seek;
+	LONG	mount;
 
 	/* Dealing with firmware environment variables. */
-	PCHAR (*get_evar)(CHAR *name);
-	LONG (*set_evar)(PCHAR name, PCHAR value);
+	LONG	get_evar;
+	LONG	set_evar;
 
-	long (*get_finfo)(unsigned long fd, struct linux_finfo *buf);
-	long (*set_finfo)(unsigned long fd, unsigned long flags,
-			  unsigned long mask);
+	LONG	get_finfo;
+	LONG	set_finfo;
 
 	/* Miscellaneous. */
-	void (*cache_flush)(void);
+	LONG	cache_flush;
 };
 
 /* The SGI ARCS parameter block is in a fixed location for standalone
  * programs to access PROM facilities easily.
  */
-struct linux_promblock {
-	long                 magic;       /* magic cookie */
+typedef struct _SYSTEM_PARAMETER_BLOCK {
+	ULONG			magic;		/* magic cookie */
 #define PROMBLOCK_MAGIC      0x53435241
 
-	unsigned long        len;          /* length of parm block */
-	unsigned short       ver;          /* ARCS firmware version */
-	unsigned short       rev;          /* ARCS firmware revision */
-	long                *rs_block;     /* Restart block. */
-	long                *dbg_block;    /* Debug block. */
-	long                *gevect;       /* XXX General vector??? */
-	long                *utlbvect;     /* XXX UTLB vector??? */
-	unsigned long        rveclen;      /* Size of romvec struct. */
-	struct linux_romvec *romvec;       /* Function interface. */
-	unsigned long        pveclen;      /* Length of private vector. */
-	long                *pvector;      /* Private vector. */
-	long                 adap_cnt;     /* Adapter count. */
-	long                 adap_typ0;    /* First adapter type. */
-	long                 adap_vcnt0;   /* Adapter 0 vector count. */
-	long                *adap_vector;  /* Adapter 0 vector ptr. */
-	long                 adap_typ1;    /* Second adapter type. */
-	long                 adap_vcnt1;   /* Adapter 1 vector count. */
-	long                *adap_vector1; /* Adapter 1 vector ptr. */
+	ULONG			len;		/* length of parm block */
+	USHORT			ver;		/* ARCS firmware version */
+	USHORT			rev;		/* ARCS firmware revision */
+	_PLONG			rs_block;	/* Restart block. */
+	_PLONG			dbg_block;	/* Debug block. */
+	_PLONG			gevect;		/* XXX General vector??? */
+	_PLONG			utlbvect;	/* XXX UTLB vector??? */
+	ULONG			rveclen;	/* Size of romvec struct. */
+	_PVOID			romvec;		/* Function interface. */
+	ULONG			pveclen;	/* Length of private vector. */
+	_PVOID			pvector;	/* Private vector. */
+	ULONG			adap_cnt;	/* Adapter count. */
+	ULONG			adap_typ0;	/* First adapter type. */
+	ULONG			adap_vcnt0;	/* Adapter 0 vector count. */
+	_PVOID			adap_vector;	/* Adapter 0 vector ptr. */
+	ULONG			adap_typ1;	/* Second adapter type. */
+	ULONG			adap_vcnt1;	/* Adapter 1 vector count. */
+	_PVOID			adap_vector1;	/* Adapter 1 vector ptr. */
 	/* More adapter vectors go here... */
-};
+} SYSTEM_PARAMETER_BLOCK, *PSYSTEM_PARAMETER_BLOCK;
 
-#define PROMBLOCK ((struct linux_promblock *)0xA0001000UL)
-#define ROMVECTOR ((PROMBLOCK)->romvec)
+#define PROMBLOCK ((PSYSTEM_PARAMETER_BLOCK) (int)0xA0001000)
+#define ROMVECTOR ((struct linux_romvec *) (long)(PROMBLOCK)->romvec)
 
 /* Cache layout parameter block. */
 union linux_cache_key {
@@ -367,4 +360,187 @@
 	int             smax;              /* Max # of symbols. */
 };
 
+/*
+ * Macros for calling a 32-bit ARC implementation from 64-bit code
+ */
+
+#if defined(CONFIG_MIPS64) && defined(CONFIG_ARC32)
+
+#define __arc_clobbers							\
+	"$2","$3","$4","$5","$6","$7","$8","$9","$10","$11",		\
+	"$12","$13","$14","$15","$16","$24","25","$31"
+
+#define ARC_CALL0(dest)							\
+({	long __res;							\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec)							\
+	: __arc_clobbers);						\
+	(unsigned long) __res;						\
+})
+
+#define ARC_CALL1(dest,a1)						\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec), "r" (__a1)					\
+	: __arc_clobbers);						\
+	(unsigned long) __res;						\
+})
+
+#define ARC_CALL2(dest,a1,a2)						\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec), "r" (__a1), "r" (__a2)				\
+	: __arc_clobbers);						\
+	__res;								\
+})
+
+#define ARC_CALL3(dest,a1,a2,a3)					\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
+	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3)		\
+	: __arc_clobbers);						\
+	__res;								\
+})
+
+#define ARC_CALL4(dest,a1,a2,a3,a4)					\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
+	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
+	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3), 		\
+	  "r" (__a4)							\
+	: __arc_clobbers);						\
+	__res;								\
+})
+
+#define ARC_CALL5(dest,a1,a2,a3,a4,a5)					\
+({	long __res;							\
+	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
+	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
+	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
+	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
+	register signed int __a5 = (a5);				\
+	long __vec = (long) romvec->dest;				\
+	__asm__ __volatile__(						\
+	"dsubu\t$29, 32\n\t"						\
+	"sw\t%6, 16($29)\n\t"						\
+	"jalr\t%1\n\t"							\
+	"daddu\t$29, 32\n\t"						\
+	"move\t%0, $2"							\
+	: "=r" (__res), "=r" (__vec)					\
+	: "1" (__vec),							\
+	  "r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4),		\
+	  "r" (__a5)							\
+	: __arc_clobbers);						\
+	__res;								\
+})
+
+#endif /* defined(CONFIG_MIPS64) && defined(CONFIG_ARC32) */
+
+#if (defined(CONFIG_MIPS32) && defined(CONFIG_ARC32)) ||		\
+    (defined(CONFIG_MIPS64) && defined(CONFIG_ARC32))
+
+#define ARC_CALL0(dest)							\
+({	long __res;							\
+	long (*__vec)(void) = (void *) romvec->dest;			\
+									\
+	__res = __vec();						\
+	__res;								\
+})
+
+#define ARC_CALL1(dest,a1)						\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long (*__vec)(long) = (void *) romvec->dest;			\
+									\
+	__res = __vec(__a1);						\
+	__res;								\
+})
+
+#define ARC_CALL2(dest,a1,a2)						\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long __a2 = (long) (a2);					\
+	long (*__vec)(long, long) = (void *) romvec->dest;		\
+									\
+	__res = __vec(__a1, __a2);					\
+	__res;								\
+})
+
+#define ARC_CALL3(dest,a1,a2,a3)					\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long __a2 = (long) (a2);					\
+	long __a3 = (long) (a3);					\
+	long (*__vec)(long, long, long)	= (void *) romvec->dest;	\
+									\
+	__res = __vec(__a1, __a2, __a3);				\
+	__res;								\
+})
+
+#define ARC_CALL4(dest,a1,a2,a3,a4)					\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long __a2 = (long) (a2);					\
+	long __a3 = (long) (a3);					\
+	long __a4 = (long) (a4);					\
+	long (*__vec)(long, long, long, long) = (void *) romvec->dest;	\
+									\
+	__res = __vec(__a1, __a2, __a3, __a4);				\
+	__res;								\
+})
+
+#define ARC_CALL5(dest,a1,a2,a3,a4,a5)					\
+({	long __res;							\
+	long __a1 = (long) (a1);					\
+	long __a2 = (long) (a2);					\
+	long __a3 = (long) (a3);					\
+	long __a4 = (long) (a4);					\
+	long __a5 = (long) (a5);					\
+	long (*__vec)(long, long, long, long, long);			\
+	__vec = (void *) romvec->dest;					\
+									\
+	__res = __vec(__a1, __a2, __a3, __a4, __a5);			\
+	__res;								\
+})
+#endif /* both kernel and ARC either 32-bit or 64-bit */
+
 #endif /* _ASM_SGIARCS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/shmparam.h linux/include/asm-mips/shmparam.h
--- linux.orig/include/asm-mips/shmparam.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/shmparam.h	2002-07-20 01:08:29.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: shmparam.h,v 1.3 2000/01/28 19:46:32 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/64bit.h linux/include/asm-mips/sibyte/64bit.h
--- linux.orig/include/asm-mips/sibyte/64bit.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/64bit.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+#ifndef _SB1_64BIT_H
+#define _SB1_64BIT_H
+
+#include <linux/types.h>
+#include <asm/system.h>
+
+/*
+ * This is annoying...we can't actually write the 64-bit IO register properly
+ * without having access to 64-bit registers...  which doesn't work by default
+ * in o32 format...grrr...
+*/
+
+static inline void out64(u64 val, unsigned long addr)
+{
+	u32 low, high, tmp;
+	unsigned long flags;
+
+	high = val >> 32;
+	low = val & 0xffffffff;
+	__save_and_cli(flags);
+	__asm__ __volatile__ (
+		".set push\t\t\t# out64n"
+		".set noreorder\n"
+		".set noat\n"
+		".set mips4\n"
+		"   dsll32 %0, %2, 0   \n"
+		"   dsll32 $1, %1, 0   \n"
+		"   dsrl32 %0, %0, 0   \n"
+		"   or     $1, $1, %0  \n"
+		"   sd $1, (%3)\n"
+		".set pop\n"
+		: "=&r" (tmp)
+		: "r" (high), "r" (low), "r" (addr));
+	__restore_flags(flags);
+}
+
+static inline u64 in64(unsigned long addr)
+{
+	unsigned long flags;
+	u32 low, high;
+
+	__save_and_cli(flags);
+	__asm__ __volatile__ (
+		".set push\t\t\t# in64\n"
+		".set noreorder\n"
+		".set noat     \n"
+		".set mips4    \n"
+		"  ld     %1, (%2)\n"
+		"  dsra32 %0, %1, 0\n"
+		"  sll    %1, %1, 0\n"
+		".set pop\n"
+		: "=r" (high), "=r" (low)
+		: "r" (addr));
+	__restore_flags(flags);
+
+	return (((u64)high) << 32) | low;
+}
+
+#endif /* _SB1_64BIT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250.h linux/include/asm-mips/sibyte/sb1250.h
--- linux.orig/include/asm-mips/sibyte/sb1250.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+#ifndef _ASM_SIBYTE_SB1250_H
+#define _ASM_SIBYTE_SB1250_H
+
+extern void sb1250_time_init(void);
+extern void sb1250_mask_irq(int cpu, int irq);
+extern void sb1250_unmask_irq(int cpu, int irq);
+extern void sb1250_smp_finish(void);
+
+#define IO_SPACE_BASE 0xa0000000UL
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_defs.h linux/include/asm-mips/sibyte/sb1250_defs.h
--- linux.orig/include/asm-mips/sibyte/sb1250_defs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_defs.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,127 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Global constants and macros		File: sb1250_defs.h	
+    *  
+    *  This file contains macros and definitions used by the other
+    *  include files.
+    *
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+/*  *********************************************************************
+    *  Naming schemes for constants in these files:
+    *  
+    *  M_xxx           MASK constant (identifies bits in a register). 
+    *                  For multi-bit fields, all bits in the field will
+    *                  be set.
+    *
+    *  K_xxx           "Code" constant (value for data in a multi-bit
+    *                  field).  The value is right justified.
+    *
+    *  V_xxx           "Value" constant.  This is the same as the 
+    *                  corresponding "K_xxx" constant, except it is
+    *                  shifted to the correct position in the register.
+    *
+    *  S_xxx           SHIFT constant.  This is the number of bits that
+    *                  a field value (code) needs to be shifted 
+    *                  (towards the left) to put the value in the right
+    *                  position for the register.
+    *
+    *  A_xxx           ADDRESS constant.  This will be a physical 
+    *                  address.  Use the PHYS_TO_K1 macro to generate
+    *                  a K1SEG address.
+    *
+    *  R_xxx           RELATIVE offset constant.  This is an offset from
+    *                  an A_xxx constant (usually the first register in
+    *                  a group).
+    *  
+    *  G_xxx(X)        GET value.  This macro obtains a multi-bit field
+    *                  from a register, masks it, and shifts it to
+    *                  the bottom of the register (retrieving a K_xxx
+    *                  value, for example).
+    *
+    *  V_xxx(X)        VALUE.  This macro computes the value of a
+    *                  K_xxx constant shifted to the correct position
+    *                  in the register.
+    ********************************************************************* */
+
+
+
+
+#ifndef _SB1250_DEFS_H
+#define _SB1250_DEFS_H
+
+/*
+ * Cast to 64-bit number.  Presumably the syntax is different in 
+ * assembly language.
+ *
+ * Note: you'll need to define uint32_t and uint64_t in your headers.
+ */
+
+#if !defined(__ASSEMBLY__)
+#define _SB_MAKE64(x) ((uint64_t)(x))
+#define _SB_MAKE32(x) ((uint32_t)(x))
+#else
+#define _SB_MAKE64(x) (x)
+#define _SB_MAKE32(x) (x)
+#endif
+
+
+/*
+ * Make a mask for 1 bit at position 'n'
+ */
+
+#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n))
+#define _SB_MAKEMASK1_32(n) (_SB_MAKE32(1) << _SB_MAKE32(n))
+
+/*
+ * Make a mask for 'v' bits at position 'n'
+ */
+
+#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n))
+#define _SB_MAKEMASK_32(v,n) (_SB_MAKE32((_SB_MAKE32(1)<<(v))-1) << _SB_MAKE32(n))
+
+/*
+ * Make a value at 'v' at bit position 'n'
+ */
+
+#define _SB_MAKEVALUE(v,n) (_SB_MAKE64(v) << _SB_MAKE64(n))
+#define _SB_MAKEVALUE_32(v,n) (_SB_MAKE32(v) << _SB_MAKE32(n))
+
+#define _SB_GETVALUE(v,n,m) ((_SB_MAKE64(v) & _SB_MAKE64(m)) >> _SB_MAKE64(n))
+#define _SB_GETVALUE_32(v,n,m) ((_SB_MAKE32(v) & _SB_MAKE32(m)) >> _SB_MAKE32(n))
+
+/*
+ * Macros to read/write on-chip registers
+ * XXX should we do the PHYS_TO_K1 here?
+ */
+
+
+#if !defined(__ASSEMBLY__)
+#define SBWRITECSR(csr,val) *((volatile uint64_t *) PHYS_TO_K1(csr)) = (val)
+#define SBREADCSR(csr) (*((volatile uint64_t *) PHYS_TO_K1(csr)))
+#endif /* __ASSEMBLY__ */
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_dma.h linux/include/asm-mips/sibyte/sb1250_dma.h
--- linux.orig/include/asm-mips/sibyte/sb1250_dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_dma.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,416 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  DMA definitions				File: sb1250_dma.h
+    *  
+    *  This module contains constants and macros useful for
+    *  programming the SB1250's DMA controllers, both the data mover
+    *  and the Ethernet DMA.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_DMA_H
+#define _SB1250_DMA_H
+
+
+#include "sb1250_defs.h"
+
+/*  *********************************************************************
+    *  DMA Registers
+    ********************************************************************* */
+
+/* 
+ * Ethernet and Serial DMA Configuration Register 0  (Table 7-4)
+ * Registers: DMA_CONFIG0_MAC_x_RX_CH_0 
+ * Registers: DMA_CONFIG0_MAC_x_TX_CH_0
+ * Registers: DMA_CONFIG0_SER_x_RX
+ * Registers: DMA_CONFIG0_SER_x_TX
+ */
+
+
+#define M_DMA_DROP                  _SB_MAKEMASK1(0)
+#define M_DMA_CHAIN_SEL             _SB_MAKEMASK1(1)
+#define M_DMA_RESERVED1             _SB_MAKEMASK1(2)
+#define M_DMA_EOP_INT_EN            _SB_MAKEMASK1(3)
+#define M_DMA_HWM_INT_EN            _SB_MAKEMASK1(4)
+#define M_DMA_LWM_INT_EN            _SB_MAKEMASK1(5)
+#define M_DMA_TBX_EN                _SB_MAKEMASK1(6)
+#define M_DMA_TDX_EN                _SB_MAKEMASK1(7)
+
+#define S_DMA_INT_PKTCNT            _SB_MAKE64(8)
+#define M_DMA_INT_PKTCNT            _SB_MAKEMASK(8,S_DMA_INT_PKTCNT)
+#define V_DMA_INT_PKTCNT(x)         _SB_MAKEVALUE(x,S_DMA_INT_PKTCNT)
+#define G_DMA_INT_PKTCNT(x)         _SB_GETVALUE(x,S_DMA_INT_PKTCNT,M_DMA_INT_PKTCNT)
+
+#define S_DMA_RINGSZ                _SB_MAKE64(16)
+#define M_DMA_RINGSZ                _SB_MAKEMASK(16,S_DMA_RINGSZ)
+#define V_DMA_RINGSZ(x)             _SB_MAKEVALUE(x,S_DMA_RINGSZ)
+#define G_DMA_RINGSZ(x)             _SB_GETVALUE(x,S_DMA_RINGSZ,M_DMA_RINGSZ)
+
+#define S_DMA_HIGH_WATERMARK        _SB_MAKE64(32)
+#define M_DMA_HIGH_WATERMARK        _SB_MAKEMASK(16,S_DMA_HIGH_WATERMARK)
+#define V_DMA_HIGH_WATERMARK(x)     _SB_MAKEVALUE(x,S_DMA_HIGH_WATERMARK)
+#define G_DMA_HIGH_WATERMARK(x)     _SB_GETVALUE(x,S_DMA_HIGH_WATERMARK,M_DMA_HIGH_WATERMARK)
+
+#define S_DMA_LOW_WATERMARK         _SB_MAKE64(48)
+#define M_DMA_LOW_WATERMARK         _SB_MAKEMASK(16,S_DMA_LOW_WATERMARK)
+#define V_DMA_LOW_WATERMARK(x)      _SB_MAKEVALUE(x,S_DMA_LOW_WATERMARK)
+#define G_DMA_LOW_WATERMARK(x)      _SB_GETVALUE(x,S_DMA_LOW_WATERMARK,M_DMA_LOW_WATERMARK)
+
+/*
+ * Ethernet and Serial DMA Configuration Register 2 (Table 7-5)
+ * Registers: DMA_CONFIG1_MAC_x_RX_CH_0 
+ * Registers: DMA_CONFIG1_DMA_x_TX_CH_0
+ * Registers: DMA_CONFIG1_SER_x_RX
+ * Registers: DMA_CONFIG1_SER_x_TX
+ */
+
+#define M_DMA_HDR_CF_EN             _SB_MAKEMASK1(0)
+#define M_DMA_ASIC_XFR_EN           _SB_MAKEMASK1(1)
+#define M_DMA_PRE_ADDR_EN           _SB_MAKEMASK1(2)
+#define M_DMA_FLOW_CTL_EN           _SB_MAKEMASK1(3)
+#define M_DMA_NO_DSCR_UPDT          _SB_MAKEMASK1(4)
+#define M_DMA_L2CA		    _SB_MAKEMASK1(5)
+
+#define M_DMA_MBZ1                  _SB_MAKEMASK(6,15)
+
+#define S_DMA_HDR_SIZE              _SB_MAKE64(21)
+#define M_DMA_HDR_SIZE              _SB_MAKEMASK(9,S_DMA_HDR_SIZE)
+#define V_DMA_HDR_SIZE(x)           _SB_MAKEVALUE(x,S_DMA_HDR_SIZE)
+#define G_DMA_HDR_SIZE(x)           _SB_GETVALUE(x,S_DMA_HDR_SIZE,M_DMA_HDR_SIZE)
+
+#define M_DMA_MBZ2                  _SB_MAKEMASK(5,32)
+
+#define S_DMA_ASICXFR_SIZE          _SB_MAKE64(37)
+#define M_DMA_ASICXFR_SIZE          _SB_MAKEMASK(9,S_DMA_ASICXFR_SIZE)
+#define V_DMA_ASICXFR_SIZE(x)       _SB_MAKEVALUE(x,S_DMA_ASICXFR_SIZE)
+#define G_DMA_ASICXFR_SIZE(x)       _SB_GETVALUE(x,S_DMA_ASICXFR_SIZE,M_DMA_ASICXFR_SIZE)
+
+#define S_DMA_INT_TIMEOUT           _SB_MAKE64(48)
+#define M_DMA_INT_TIMEOUT           _SB_MAKEMASK(16,S_DMA_INT_TIMEOUT)
+#define V_DMA_INT_TIMEOUT(x)        _SB_MAKEVALUE(x,S_DMA_INT_TIMEOUT)
+#define G_DMA_INT_TIMEOUT(x)        _SB_GETVALUE(x,S_DMA_INT_TIMEOUT,M_DMA_INT_TIMEOUT)
+
+/*
+ * Ethernet and Serial DMA Descriptor base address (Table 7-6)
+ */
+
+#define M_DMA_DSCRBASE_MBZ          _SB_MAKEMASK(4,0)
+
+
+/*
+ * ASIC Mode Base Address (Table 7-7)
+ */
+
+#define M_DMA_ASIC_BASE_MBZ         _SB_MAKEMASK(20,0)
+
+/*
+ * DMA Descriptor Count Registers (Table 7-8)
+ */
+ 
+/* No bitfields */
+
+
+/* 
+ * Current Descriptor Address Register (Table 7-11)
+ */
+
+#define S_DMA_CURDSCR_ADDR          _SB_MAKE64(0)
+#define M_DMA_CURDSCR_ADDR          _SB_MAKEMASK(40,S_DMA_CURDSCR_ADDR)
+#define S_DMA_CURDSCR_COUNT         _SB_MAKE64(48)
+#define M_DMA_CURDSCR_COUNT         _SB_MAKEMASK(16,S_DMA_CURDSCR_COUNT)
+
+/*  *********************************************************************
+    *  DMA Descriptors
+    ********************************************************************* */
+
+/*
+ * Descriptor doubleword "A"  (Table 7-12)
+ */
+
+#define S_DMA_DSCRA_OFFSET          _SB_MAKE64(0)
+#define M_DMA_DSCRA_OFFSET          _SB_MAKEMASK(5,S_DMA_DSCRA_OFFSET)
+
+/* Note: Don't shift the address over, just mask it with the mask below */
+#define S_DMA_DSCRA_A_ADDR          _SB_MAKE64(5)
+#define M_DMA_DSCRA_A_ADDR          _SB_MAKEMASK(35,S_DMA_DSCRA_A_ADDR)
+
+#define M_DMA_DSCRA_A_ADDR_OFFSET   (M_DMA_DSCRA_OFFSET | M_DMA_DSCRA_A_ADDR)
+
+#define S_DMA_DSCRA_A_SIZE          _SB_MAKE64(40)
+#define M_DMA_DSCRA_A_SIZE          _SB_MAKEMASK(9,S_DMA_DSCRA_A_SIZE)
+#define V_DMA_DSCRA_A_SIZE(x)       _SB_MAKEVALUE(x,S_DMA_DSCRA_A_SIZE)
+#define G_DMA_DSCRA_A_SIZE(x)       _SB_GETVALUE(x,S_DMA_DSCRA_A_SIZE,M_DMA_DSCRA_A_SIZE)
+
+#define M_DMA_DSCRA_INTERRUPT       _SB_MAKEMASK1(49)
+#define M_DMA_DSCRA_OFFSETB	    _SB_MAKEMASK1(50)
+
+#define S_DMA_DSCRA_STATUS          _SB_MAKE64(51)
+#define M_DMA_DSCRA_STATUS          _SB_MAKEMASK(13,S_DMA_DSCRA_STATUS)
+#define V_DMA_DSCRA_STATUS(x)       _SB_MAKEVALUE(x,S_DMA_DSCRA_STATUS)
+#define G_DMA_DSCRA_STATUS(x)       _SB_GETVALUE(x,S_DMA_DSCRA_STATUS,M_DMA_DSCRA_STATUS)
+
+/*
+ * Descriptor doubleword "B"  (Table 7-13)
+ */
+
+
+#define S_DMA_DSCRB_OPTIONS         _SB_MAKE64(0)
+#define M_DMA_DSCRB_OPTIONS         _SB_MAKEMASK(4,S_DMA_DSCRB_OPTIONS)
+#define V_DMA_DSCRB_OPTIONS(x)      _SB_MAKEVALUE(x,S_DMA_DSCRB_OPTIONS)
+#define G_DMA_DSCRB_OPTIONS(x)      _SB_GETVALUE(x,S_DMA_DSCRB_OPTIONS,M_DMA_DSCRB_OPTIONS)
+
+#define R_DMA_DSCRB_ADDR            _SB_MAKE64(0x10)
+
+/* Note: Don't shift the address over, just mask it with the mask below */
+#define S_DMA_DSCRB_B_ADDR          _SB_MAKE64(5)
+#define M_DMA_DSCRB_B_ADDR          _SB_MAKEMASK(35,S_DMA_DSCRB_B_ADDR)
+
+#define S_DMA_DSCRB_B_SIZE          _SB_MAKE64(40)
+#define M_DMA_DSCRB_B_SIZE          _SB_MAKEMASK(9,S_DMA_DSCRB_B_SIZE)
+#define V_DMA_DSCRB_B_SIZE(x)       _SB_MAKEVALUE(x,S_DMA_DSCRB_B_SIZE)
+#define G_DMA_DSCRB_B_SIZE(x)       _SB_GETVALUE(x,S_DMA_DSCRB_B_SIZE,M_DMA_DSCRB_B_SIZE)
+
+#define M_DMA_DSCRB_B_VALID         _SB_MAKEMASK1(49)
+
+#define S_DMA_DSCRB_PKT_SIZE        _SB_MAKE64(50)
+#define M_DMA_DSCRB_PKT_SIZE        _SB_MAKEMASK(14,S_DMA_DSCRB_PKT_SIZE)
+#define V_DMA_DSCRB_PKT_SIZE(x)     _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE)
+#define G_DMA_DSCRB_PKT_SIZE(x)     _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE,M_DMA_DSCRB_PKT_SIZE)
+
+/* 
+ * Ethernet Descriptor Status Bits (Table 7-15)
+ */
+
+#define M_DMA_ETHRX_BADIP4CS        _SB_MAKEMASK1(51)
+#define M_DMA_ETHRX_DSCRERR	    _SB_MAKEMASK1(52)
+
+#define S_DMA_ETHRX_RXCH            53
+#define M_DMA_ETHRX_RXCH            _SB_MAKEMASK(2,S_DMA_ETHRX_RXCH)
+#define V_DMA_ETHRX_RXCH(x)         _SB_MAKEVALUE(x,S_DMA_ETHRX_RXCH)
+#define G_DMA_ETHRX_RXCH(x)         _SB_GETVALUE(x,S_DMA_ETHRX_RXCH,M_DMA_ETHRX_RXCH)
+
+#define S_DMA_ETHRX_PKTTYPE         55
+#define M_DMA_ETHRX_PKTTYPE         _SB_MAKEMASK(3,S_DMA_ETHRX_PKTTYPE)
+#define V_DMA_ETHRX_PKTTYPE(x)      _SB_MAKEVALUE(x,S_DMA_ETHRX_PKTTYPE)
+#define G_DMA_ETHRX_PKTTYPE(x)      _SB_GETVALUE(x,S_DMA_ETHRX_PKTTYPE,M_DMA_ETHRX_PKTTYPE)
+
+#define K_DMA_ETHRX_PKTTYPE_IPV4    0
+#define K_DMA_ETHRX_PKTTYPE_ARPV4   1
+#define K_DMA_ETHRX_PKTTYPE_802     2
+#define K_DMA_ETHRX_PKTTYPE_OTHER   3
+#define K_DMA_ETHRX_PKTTYPE_USER0   4
+#define K_DMA_ETHRX_PKTTYPE_USER1   5
+#define K_DMA_ETHRX_PKTTYPE_USER2   6
+#define K_DMA_ETHRX_PKTTYPE_USER3   7
+
+#define M_DMA_ETHRX_MATCH_EXACT     _SB_MAKEMASK1(58)
+#define M_DMA_ETHRX_MATCH_HASH      _SB_MAKEMASK1(59)
+#define M_DMA_ETHRX_BCAST           _SB_MAKEMASK1(60)
+#define M_DMA_ETHRX_MCAST           _SB_MAKEMASK1(61)
+#define M_DMA_ETHRX_BAD	            _SB_MAKEMASK1(62)
+#define M_DMA_ETHRX_SOP             _SB_MAKEMASK1(63)
+
+/*
+ * Ethernet Transmit Status Bits (Table 7-16)
+ */
+
+#define M_DMA_ETHTX_SOP	    	    _SB_MAKEMASK1(63)
+
+/* 
+ * Ethernet Transmit Options (Table 7-17)
+ */
+
+#define K_DMA_ETHTX_NOTSOP          _SB_MAKE64(0x00)
+#define K_DMA_ETHTX_APPENDCRC       _SB_MAKE64(0x01)
+#define K_DMA_ETHTX_REPLACECRC      _SB_MAKE64(0x02)
+#define K_DMA_ETHTX_APPENDCRC_APPENDPAD _SB_MAKE64(0x03)
+#define K_DMA_ETHTX_APPENDVLAN_REPLACECRC _SB_MAKE64(0x04)
+#define K_DMA_ETHTX_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x05)
+#define K_DMA_ETHTX_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x6)
+#define K_DMA_ETHTX_NOMODS          _SB_MAKE64(0x07)
+#define K_DMA_ETHTX_RESERVED1       _SB_MAKE64(0x08)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC _SB_MAKE64(0x09)
+#define K_DMA_ETHTX_REPLACESADDR_REPLACECRC _SB_MAKE64(0x0A)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC_APPENDPAD _SB_MAKE64(0x0B)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDVLAN_REPLACECRC _SB_MAKE64(0x0C)
+#define K_DMA_ETHTX_REPLACESADDR_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x0D)
+#define K_DMA_ETHTX_REPLACESADDR_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x0E)
+#define K_DMA_ETHTX_RESERVED2       _SB_MAKE64(0x0F)
+
+/*
+ * Serial Receive Options (Table 7-18)
+ */
+#define M_DMA_SERRX_CRC_ERROR       _SB_MAKEMASK1(56)
+#define M_DMA_SERRX_ABORT           _SB_MAKEMASK1(57)
+#define M_DMA_SERRX_OCTET_ERROR     _SB_MAKEMASK1(58)
+#define M_DMA_SERRX_LONGFRAME_ERROR _SB_MAKEMASK1(59)
+#define M_DMA_SERRX_SHORTFRAME_ERROR _SB_MAKEMASK1(60)
+#define M_DMA_SERRX_OVERRUN_ERROR   _SB_MAKEMASK1(61)
+#define M_DMA_SERRX_GOOD            _SB_MAKEMASK1(62)
+#define M_DMA_SERRX_SOP             _SB_MAKEMASK1(63)
+
+/*
+ * Serial Transmit Status Bits (Table 7-20)
+ */
+
+#define M_DMA_SERTX_FLAG	    _SB_MAKEMASK1(63)
+
+/*
+ * Serial Transmit Options (Table 7-21)
+ */
+
+#define K_DMA_SERTX_RESERVED        _SB_MAKEMASK1(0)
+#define K_DMA_SERTX_APPENDCRC       _SB_MAKEMASK1(1)
+#define K_DMA_SERTX_APPENDPAD       _SB_MAKEMASK1(2)
+#define K_DMA_SERTX_ABORT           _SB_MAKEMASK1(3)
+
+
+/*  *********************************************************************
+    *  Data Mover Registers
+    ********************************************************************* */
+
+/* 
+ * Data Mover Descriptor Base Address Register (Table 7-22)
+ * Register: DM_DSCR_BASE_0
+ * Register: DM_DSCR_BASE_1
+ * Register: DM_DSCR_BASE_2
+ * Register: DM_DSCR_BASE_3
+ */
+
+#define M_DM_DSCR_BASE_MBZ          _SB_MAKEMASK(3,0)
+
+/*  Note: Just mask the base address and then OR it in. */
+#define S_DM_DSCR_BASE_ADDR         _SB_MAKE64(3)
+#define M_DM_DSCR_BASE_ADDR         _SB_MAKEMASK(36,S_DM_DSCR_BASE_ADDR)
+
+#define S_DM_DSCR_BASE_RINGSZ       _SB_MAKE64(40)
+#define M_DM_DSCR_BASE_RINGSZ       _SB_MAKEMASK(16,S_DM_DSCR_BASE_RINGSZ)
+#define V_DM_DSCR_BASE_RINGSZ(x)    _SB_MAKEVALUE(x,S_DM_DSCR_BASE_RINGSZ)
+#define G_DM_DSCR_BASE_RINGSZ(x)    _SB_GETVALUE(x,S_DM_DSCR_BASE_RINGSZ,M_DM_DSCR_BASE_RINGSZ)
+
+#define S_DM_DSCR_BASE_PRIORITY     _SB_MAKE64(56)
+#define M_DM_DSCR_BASE_PRIORITY     _SB_MAKEMASK(3,S_DM_DSCR_BASE_PRIORITY)
+#define V_DM_DSCR_BASE_PRIORITY(x)  _SB_MAKEVALUE(x,S_DM_DSCR_BASE_PRIORITY)
+#define G_DM_DSCR_BASE_PRIORITY(x)  _SB_GETVALUE(x,S_DM_DSCR_BASE_PRIORITY,M_DM_DSCR_BASE_PRIORITY)
+
+#define K_DM_DSCR_BASE_PRIORITY_1   0
+#define K_DM_DSCR_BASE_PRIORITY_2   1
+#define K_DM_DSCR_BASE_PRIORITY_4   2
+#define K_DM_DSCR_BASE_PRIORITY_8   3
+#define K_DM_DSCR_BASE_PRIORITY_16  4
+
+#define M_DM_DSCR_BASE_ACTIVE       _SB_MAKEMASK1(59)
+#define M_DM_DSCR_BASE_INTERRUPT    _SB_MAKEMASK1(60)
+#define M_DM_DSCR_BASE_RESET        _SB_MAKEMASK1(61)	/* write register */
+#define M_DM_DSCR_BASE_ERROR        _SB_MAKEMASK1(61)	/* read register */
+#define M_DM_DSCR_BASE_ABORT        _SB_MAKEMASK1(62)
+#define M_DM_DSCR_BASE_ENABL        _SB_MAKEMASK1(63)
+
+/* 
+ * Data Mover Descriptor Count Register (Table 7-25)
+ */
+
+/* no bitfields */
+
+/*
+ * Data Mover Current Descriptor Address (Table 7-24)
+ * Register: DM_CUR_DSCR_ADDR_0
+ * Register: DM_CUR_DSCR_ADDR_1
+ * Register: DM_CUR_DSCR_ADDR_2
+ * Register: DM_CUR_DSCR_ADDR_3
+ */
+
+#define S_DM_CUR_DSCR_DSCR_ADDR     _SB_MAKE64(0)
+#define M_DM_CUR_DSCR_DSCR_ADDR     _SB_MAKEMASK(40,S_DM_CUR_DSCR_DSCR_ADDR)
+
+#define S_DM_CUR_DSCR_DSCR_COUNT    _SB_MAKE64(48)
+#define M_DM_CUR_DSCR_DSCR_COUNT    _SB_MAKEMASK(16,S_DM_CUR_DSCR_DSCR_COUNT)
+#define V_DM_CUR_DSCR_DSCR_COUNT(r) _SB_MAKEVALUE(r,S_DM_CUR_DSCR_DSCR_COUNT)
+#define G_DM_CUR_DSCR_DSCR_COUNT(r) _SB_GETVALUE(r,S_DM_CUR_DSCR_DSCR_COUNT,\
+                                     M_DM_CUR_DSCR_DSCR_COUNT)
+
+/*
+ * Data Mover Descriptor Doubleword "A"  (Table 7-26)
+ */
+
+#define S_DM_DSCRA_DST_ADDR         _SB_MAKE64(0)
+#define M_DM_DSCRA_DST_ADDR         _SB_MAKEMASK(40,S_DM_DSCRA_DST_ADDR)
+
+#define M_DM_DSCRA_UN_DEST          _SB_MAKEMASK1(40)
+#define M_DM_DSCRA_UN_SRC           _SB_MAKEMASK1(41)
+#define M_DM_DSCRA_INTERRUPT        _SB_MAKEMASK1(42)
+#define M_DM_DSCRA_THROTTLE         _SB_MAKEMASK1(43)
+
+#define S_DM_DSCRA_DIR_DEST         _SB_MAKE64(44)
+#define M_DM_DSCRA_DIR_DEST         _SB_MAKEMASK(2,S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST(x)      _SB_MAKEVALUE(x,S_DM_DSCRA_DIR_DEST)
+#define G_DM_DSCRA_DIR_DEST(x)      _SB_GETVALUE(x,S_DM_DSCRA_DIR_DEST,M_DM_DSCRA_DIR_DEST)
+
+#define K_DM_DSCRA_DIR_DEST_INCR    0
+#define K_DM_DSCRA_DIR_DEST_DECR    1
+#define K_DM_DSCRA_DIR_DEST_CONST   2
+
+#define V_DM_DSCRA_DIR_DEST_INCR    _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_INCR,S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST_DECR    _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_DECR,S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST_CONST   _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_CONST,S_DM_DSCRA_DIR_DEST)
+
+#define S_DM_DSCRA_DIR_SRC          _SB_MAKE64(46)
+#define M_DM_DSCRA_DIR_SRC          _SB_MAKEMASK(2,S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC(x)       _SB_MAKEVALUE(x,S_DM_DSCRA_DIR_SRC)
+#define G_DM_DSCRA_DIR_SRC(x)       _SB_GETVALUE(x,S_DM_DSCRA_DIR_SRC,M_DM_DSCRA_DIR_SRC)
+
+#define K_DM_DSCRA_DIR_SRC_INCR     0
+#define K_DM_DSCRA_DIR_SRC_DECR     1
+#define K_DM_DSCRA_DIR_SRC_CONST    2
+
+#define V_DM_DSCRA_DIR_SRC_INCR     _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_INCR,S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC_DECR     _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_DECR,S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC_CONST    _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_CONST,S_DM_DSCRA_DIR_SRC)
+
+
+#define M_DM_DSCRA_ZERO_MEM         _SB_MAKEMASK1(48)
+#define M_DM_DSCRA_PREFETCH         _SB_MAKEMASK1(49)
+#define M_DM_DSCRA_L2C_DEST         _SB_MAKEMASK1(50)
+#define M_DM_DSCRA_L2C_SRC          _SB_MAKEMASK1(51)
+
+#define M_DM_DSCRA_RESERVED2        _SB_MAKEMASK(12,52)
+
+/*
+ * Data Mover Descriptor Doubleword "B"  (Table 7-25)
+ */
+
+#define S_DM_DSCRB_SRC_ADDR         _SB_MAKE64(0)
+#define M_DM_DSCRB_SRC_ADDR         _SB_MAKEMASK(40,S_DM_DSCRB_SRC_ADDR)
+
+#define S_DM_DSCRB_SRC_LENGTH       _SB_MAKE64(40)
+#define M_DM_DSCRB_SRC_LENGTH       _SB_MAKEMASK(20,S_DM_DSCRB_SRC_LENGTH)
+#define V_DM_DSCRB_SRC_LENGTH(x)    _SB_MAKEVALUE(x,S_DM_DSCRB_SRC_LENGTH)
+#define G_DM_DSCRB_SRC_LENGTH(x)    _SB_GETVALUE(x,S_DM_DSCRB_SRC_LENGTH,M_DM_DSCRB_SRC_LENGTH)
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_genbus.h linux/include/asm-mips/sibyte/sb1250_genbus.h
--- linux.orig/include/asm-mips/sibyte/sb1250_genbus.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_genbus.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,245 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Generic Bus Constants                     File: sb1250_genbus.h
+    *  
+    *  This module contains constants and macros useful for 
+    *  manipulating the SB1250's Generic Bus interface
+    *  
+    *  SB1250 specification level:  01/02/2002
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_GENBUS_H
+#define _SB1250_GENBUS_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Generic Bus Region Configuration Registers (Table 11-4)
+ */
+
+#define M_IO_RDY_ACTIVE		_SB_MAKEMASK1(0)
+#define M_IO_ENA_RDY		_SB_MAKEMASK1(1)
+
+#define S_IO_WIDTH_SEL		2
+#define M_IO_WIDTH_SEL		_SB_MAKEMASK(2,S_IO_WIDTH_SEL)
+#define K_IO_WIDTH_SEL_1	0
+#define K_IO_WIDTH_SEL_2	1
+#define K_IO_WIDTH_SEL_4	3
+#define V_IO_WIDTH_SEL(x)	_SB_MAKEVALUE(x,S_IO_WIDTH_SEL)
+#define G_IO_WIDTH_SEL(x)	_SB_GETVALUE(x,S_IO_WIDTH_SEL,M_IO_WIDTH_SEL)
+
+#define M_IO_PARITY_ENA		_SB_MAKEMASK1(4)
+#define M_IO_PARITY_ODD		_SB_MAKEMASK1(6)
+#define M_IO_NONMUX		_SB_MAKEMASK1(7)
+
+#define S_IO_TIMEOUT		8
+#define M_IO_TIMEOUT		_SB_MAKEMASK(8,S_IO_TIMEOUT)
+#define V_IO_TIMEOUT(x)		_SB_MAKEVALUE(x,S_IO_TIMEOUT)
+#define G_IO_TIMEOUT(x)		_SB_GETVALUE(x,S_IO_TIMEOUT,M_IO_TIMEOUT)
+
+/*
+ * Generic Bus Region Size register (Table 11-5)
+ */
+
+#define S_IO_MULT_SIZE		0
+#define M_IO_MULT_SIZE		_SB_MAKEMASK(12,S_IO_MULT_SIZE)
+#define V_IO_MULT_SIZE(x)	_SB_MAKEVALUE(x,S_IO_MULT_SIZE)
+#define G_IO_MULT_SIZE(x)	_SB_GETVALUE(x,S_IO_MULT_SIZE,M_IO_MULT_SIZE)
+
+#define S_IO_REGSIZE		16	 /* # bits to shift size for this reg */
+
+/*
+ * Generic Bus Region Address (Table 11-6)
+ */
+
+#define S_IO_START_ADDR		0
+#define M_IO_START_ADDR		_SB_MAKEMASK(14,S_IO_START_ADDR)
+#define V_IO_START_ADDR(x)	_SB_MAKEVALUE(x,S_IO_START_ADDR)
+#define G_IO_START_ADDR(x)	_SB_GETVALUE(x,S_IO_START_ADDR,M_IO_START_ADDR)
+
+#define S_IO_ADDRBASE		16	 /* # bits to shift addr for this reg */
+
+/*
+ * Generic Bus Region 0 Timing Registers (Table 11-7)
+ */
+
+#define S_IO_ALE_WIDTH		0
+#define M_IO_ALE_WIDTH		_SB_MAKEMASK(3,S_IO_ALE_WIDTH)
+#define V_IO_ALE_WIDTH(x)	_SB_MAKEVALUE(x,S_IO_ALE_WIDTH)
+#define G_IO_ALE_WIDTH(x)	_SB_GETVALUE(x,S_IO_ALE_WIDTH,M_IO_ALE_WIDTH)
+
+#define S_IO_ALE_TO_CS		4
+#define M_IO_ALE_TO_CS		_SB_MAKEMASK(2,S_IO_ALE_TO_CS)
+#define V_IO_ALE_TO_CS(x)	_SB_MAKEVALUE(x,S_IO_ALE_TO_CS)
+#define G_IO_ALE_TO_CS(x)	_SB_GETVALUE(x,S_IO_ALE_TO_CS,M_IO_ALE_TO_CS)
+
+#define S_IO_CS_WIDTH		8
+#define M_IO_CS_WIDTH		_SB_MAKEMASK(5,S_IO_CS_WIDTH)
+#define V_IO_CS_WIDTH(x)	_SB_MAKEVALUE(x,S_IO_CS_WIDTH)
+#define G_IO_CS_WIDTH(x)	_SB_GETVALUE(x,S_IO_CS_WIDTH,M_IO_CS_WIDTH)
+
+#define S_IO_RDY_SMPLE		13
+#define M_IO_RDY_SMPLE		_SB_MAKEMASK(3,S_IO_RDY_SMPLE)
+#define V_IO_RDY_SMPLE(x)	_SB_MAKEVALUE(x,S_IO_RDY_SMPLE)
+#define G_IO_RDY_SMPLE(x)	_SB_GETVALUE(x,S_IO_RDY_SMPLE,M_IO_RDY_SMPLE)
+
+
+/*
+ * Generic Bus Timing 1 Registers (Table 11-8)
+ */
+
+#define S_IO_ALE_TO_WRITE	0
+#define M_IO_ALE_TO_WRITE	_SB_MAKEMASK(3,S_IO_ALE_TO_WRITE)
+#define V_IO_ALE_TO_WRITE(x)	_SB_MAKEVALUE(x,S_IO_ALE_TO_WRITE)
+#define G_IO_ALE_TO_WRITE(x)	_SB_GETVALUE(x,S_IO_ALE_TO_WRITE,M_IO_ALE_TO_WRITE)
+
+#define S_IO_WRITE_WIDTH	4
+#define M_IO_WRITE_WIDTH	_SB_MAKEMASK(4,S_IO_WRITE_WIDTH)
+#define V_IO_WRITE_WIDTH(x)	_SB_MAKEVALUE(x,S_IO_WRITE_WIDTH)
+#define G_IO_WRITE_WIDTH(x)	_SB_GETVALUE(x,S_IO_WRITE_WIDTH,M_IO_WRITE_WIDTH)
+
+#define S_IO_IDLE_CYCLE		8
+#define M_IO_IDLE_CYCLE		_SB_MAKEMASK(4,S_IO_IDLE_CYCLE)
+#define V_IO_IDLE_CYCLE(x)	_SB_MAKEVALUE(x,S_IO_IDLE_CYCLE)
+#define G_IO_IDLE_CYCLE(x)	_SB_GETVALUE(x,S_IO_IDLE_CYCLE,M_IO_IDLE_CYCLE)
+
+#define S_IO_OE_TO_CS		12
+#define M_IO_OE_TO_CS		_SB_MAKEMASK(2,S_IO_OE_TO_CS)
+#define V_IO_OE_TO_CS(x)	_SB_MAKEVALUE(x,S_IO_OE_TO_CS)
+#define G_IO_OE_TO_CS(x)	_SB_GETVALUE(x,S_IO_OE_TO_CS,M_IO_OE_TO_CS)
+
+#define S_IO_CS_TO_OE		14
+#define M_IO_CS_TO_OE		_SB_MAKEMASK(2,S_IO_CS_TO_OE)
+#define V_IO_CS_TO_OE(x)	_SB_MAKEVALUE(x,S_IO_CS_TO_OE)
+#define G_IO_CS_TO_OE(x)	_SB_GETVALUE(x,S_IO_CS_TO_OE,M_IO_CS_TO_OE)
+
+/*
+ * Generic Bus Interrupt Status Register (Table 11-9)
+ */
+
+#define M_IO_CS_ERR_INT		_SB_MAKEMASK(0,8)
+#define M_IO_CS0_ERR_INT	_SB_MAKEMASK1(0)
+#define M_IO_CS1_ERR_INT	_SB_MAKEMASK1(1)
+#define M_IO_CS2_ERR_INT	_SB_MAKEMASK1(2)
+#define M_IO_CS3_ERR_INT	_SB_MAKEMASK1(3)
+#define M_IO_CS4_ERR_INT	_SB_MAKEMASK1(4)
+#define M_IO_CS5_ERR_INT	_SB_MAKEMASK1(5)
+#define M_IO_CS6_ERR_INT	_SB_MAKEMASK1(6)
+#define M_IO_CS7_ERR_INT	_SB_MAKEMASK1(7)
+
+#define M_IO_RD_PAR_INT		_SB_MAKEMASK1(9)
+#define M_IO_TIMEOUT_INT	_SB_MAKEMASK1(10)
+#define M_IO_ILL_ADDR_INT	_SB_MAKEMASK1(11)
+#define M_IO_MULT_CS_INT	_SB_MAKEMASK1(12)
+
+/*
+ * PCMCIA configuration register (Table 12-6)
+ */
+
+#define M_PCMCIA_CFG_ATTRMEM	_SB_MAKEMASK1(0)
+#define M_PCMCIA_CFG_3VEN	_SB_MAKEMASK1(1)
+#define M_PCMCIA_CFG_5VEN	_SB_MAKEMASK1(2)
+#define M_PCMCIA_CFG_VPPEN	_SB_MAKEMASK1(3)
+#define M_PCMCIA_CFG_RESET	_SB_MAKEMASK1(4)
+#define M_PCMCIA_CFG_APWRONEN	_SB_MAKEMASK1(5)
+#define M_PCMCIA_CFG_CDMASK	_SB_MAKEMASK1(6)
+#define M_PCMCIA_CFG_WPMASK	_SB_MAKEMASK1(7)
+#define M_PCMCIA_CFG_RDYMASK	_SB_MAKEMASK1(8)
+#define M_PCMCIA_CFG_PWRCTL	_SB_MAKEMASK1(9)
+
+/*
+ * PCMCIA status register (Table 12-7)
+ */
+
+#define M_PCMCIA_STATUS_CD1	_SB_MAKEMASK1(0)
+#define M_PCMCIA_STATUS_CD2	_SB_MAKEMASK1(1)
+#define M_PCMCIA_STATUS_VS1	_SB_MAKEMASK1(2)
+#define M_PCMCIA_STATUS_VS2	_SB_MAKEMASK1(3)
+#define M_PCMCIA_STATUS_WP	_SB_MAKEMASK1(4)
+#define M_PCMCIA_STATUS_RDY	_SB_MAKEMASK1(5)
+#define M_PCMCIA_STATUS_3VEN	_SB_MAKEMASK1(6)
+#define M_PCMCIA_STATUS_5VEN	_SB_MAKEMASK1(7)
+#define M_PCMCIA_STATUS_CDCHG	_SB_MAKEMASK1(8)
+#define M_PCMCIA_STATUS_WPCHG	_SB_MAKEMASK1(9)
+#define M_PCMCIA_STATUS_RDYCHG	_SB_MAKEMASK1(10)
+
+/*
+ * GPIO Interrupt Type Register (table 13-3)
+ */
+
+#define K_GPIO_INTR_DISABLE	0
+#define K_GPIO_INTR_EDGE	1
+#define K_GPIO_INTR_LEVEL	2
+#define K_GPIO_INTR_SPLIT	3
+
+#define S_GPIO_INTR_TYPEX(n)	(((n)/2)*2)
+#define M_GPIO_INTR_TYPEX(n)	_SB_MAKEMASK(2,S_GPIO_INTR_TYPEX(n))
+#define V_GPIO_INTR_TYPEX(n,x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPEX(n))
+#define G_GPIO_INTR_TYPEX(n,x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPEX(n),M_GPIO_INTR_TYPEX(n))
+
+#define S_GPIO_INTR_TYPE0	0
+#define M_GPIO_INTR_TYPE0	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE0)
+#define V_GPIO_INTR_TYPE0(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE0)
+#define G_GPIO_INTR_TYPE0(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE0,M_GPIO_INTR_TYPE0)
+
+#define S_GPIO_INTR_TYPE2	2
+#define M_GPIO_INTR_TYPE2	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE2)
+#define V_GPIO_INTR_TYPE2(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE2)
+#define G_GPIO_INTR_TYPE2(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE2,M_GPIO_INTR_TYPE2)
+
+#define S_GPIO_INTR_TYPE4	4
+#define M_GPIO_INTR_TYPE4	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE4)
+#define V_GPIO_INTR_TYPE4(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE4)
+#define G_GPIO_INTR_TYPE4(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE4,M_GPIO_INTR_TYPE4)
+
+#define S_GPIO_INTR_TYPE6	6
+#define M_GPIO_INTR_TYPE6	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE6)
+#define V_GPIO_INTR_TYPE6(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE6)
+#define G_GPIO_INTR_TYPE6(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE6,M_GPIO_INTR_TYPE6)
+
+#define S_GPIO_INTR_TYPE8	8
+#define M_GPIO_INTR_TYPE8	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE8)
+#define V_GPIO_INTR_TYPE8(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE8)
+#define G_GPIO_INTR_TYPE8(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE8,M_GPIO_INTR_TYPE8)
+
+#define S_GPIO_INTR_TYPE10	10
+#define M_GPIO_INTR_TYPE10	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE10)
+#define V_GPIO_INTR_TYPE10(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE10)
+#define G_GPIO_INTR_TYPE10(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE10,M_GPIO_INTR_TYPE10)
+
+#define S_GPIO_INTR_TYPE12	12
+#define M_GPIO_INTR_TYPE12	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE12)
+#define V_GPIO_INTR_TYPE12(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE12)
+#define G_GPIO_INTR_TYPE12(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE12,M_GPIO_INTR_TYPE12)
+
+#define S_GPIO_INTR_TYPE14	14
+#define M_GPIO_INTR_TYPE14	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE14)
+#define V_GPIO_INTR_TYPE14(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE14)
+#define G_GPIO_INTR_TYPE14(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE14,M_GPIO_INTR_TYPE14)
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_int.h linux/include/asm-mips/sibyte/sb1250_int.h
--- linux.orig/include/asm-mips/sibyte/sb1250_int.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_int.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,239 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Interrupt Mapper definitions		File: sb1250_int.h
+    *  
+    *  This module contains constants for manipulating the SB1250's
+    *  interrupt mapper and definitions for the interrupt sources.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_INT_H
+#define _SB1250_INT_H
+
+#include "sb1250_defs.h"
+
+/*  *********************************************************************
+    *  Interrupt Mapper Constants
+    ********************************************************************* */
+
+/*
+ * Interrupt sources (Table 4-8, UM 0.2)
+ * 
+ * First, the interrupt numbers.
+ */
+
+#define K_INT_WATCHDOG_TIMER_0      0
+#define K_INT_WATCHDOG_TIMER_1      1
+#define K_INT_TIMER_0               2
+#define K_INT_TIMER_1               3
+#define K_INT_TIMER_2               4
+#define K_INT_TIMER_3               5
+#define K_INT_SMB_0                 6
+#define K_INT_SMB_1                 7
+#define K_INT_UART_0                8
+#define K_INT_UART_1                9
+#define K_INT_SER_0                 10
+#define K_INT_SER_1                 11
+#define K_INT_PCMCIA                12
+#define K_INT_ADDR_TRAP             13
+#define K_INT_PERF_CNT              14
+#define K_INT_TRACE_FREEZE          15
+#define K_INT_BAD_ECC               16
+#define K_INT_COR_ECC               17
+#define K_INT_IO_BUS                18
+#define K_INT_MAC_0                 19
+#define K_INT_MAC_1                 20
+#define K_INT_MAC_2                 21
+#define K_INT_DM_CH_0               22
+#define K_INT_DM_CH_1               23
+#define K_INT_DM_CH_2               24
+#define K_INT_DM_CH_3               25
+#define K_INT_MBOX_0                26
+#define K_INT_MBOX_1                27
+#define K_INT_MBOX_2                28
+#define K_INT_MBOX_3                29
+#define K_INT_SPARE_0               30
+#define K_INT_SPARE_1               31
+#define K_INT_GPIO_0                32
+#define K_INT_GPIO_1                33
+#define K_INT_GPIO_2                34
+#define K_INT_GPIO_3                35
+#define K_INT_GPIO_4                36
+#define K_INT_GPIO_5                37
+#define K_INT_GPIO_6                38
+#define K_INT_GPIO_7                39
+#define K_INT_GPIO_8                40
+#define K_INT_GPIO_9                41
+#define K_INT_GPIO_10               42
+#define K_INT_GPIO_11               43
+#define K_INT_GPIO_12               44
+#define K_INT_GPIO_13               45
+#define K_INT_GPIO_14               46
+#define K_INT_GPIO_15               47
+#define K_INT_LDT_FATAL             48
+#define K_INT_LDT_NONFATAL          49
+#define K_INT_LDT_SMI               50
+#define K_INT_LDT_NMI               51
+#define K_INT_LDT_INIT              52
+#define K_INT_LDT_STARTUP           53
+#define K_INT_LDT_EXT               54
+#define K_INT_PCI_ERROR             55
+#define K_INT_PCI_INTA              56
+#define K_INT_PCI_INTB              57
+#define K_INT_PCI_INTC              58
+#define K_INT_PCI_INTD              59
+#define K_INT_SPARE_2               60
+#define K_INT_SPARE_3               61
+#define K_INT_SPARE_4               62
+#define K_INT_SPARE_5               63
+
+/*
+ * Mask values for each interrupt
+ */
+
+#define M_INT_WATCHDOG_TIMER_0      _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_0)
+#define M_INT_WATCHDOG_TIMER_1      _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_1)
+#define M_INT_TIMER_0               _SB_MAKEMASK1(K_INT_TIMER_0)
+#define M_INT_TIMER_1               _SB_MAKEMASK1(K_INT_TIMER_1)
+#define M_INT_TIMER_2               _SB_MAKEMASK1(K_INT_TIMER_2)
+#define M_INT_TIMER_3               _SB_MAKEMASK1(K_INT_TIMER_3)
+#define M_INT_SMB_0                 _SB_MAKEMASK1(K_INT_SMB_0)
+#define M_INT_SMB_1                 _SB_MAKEMASK1(K_INT_SMB_1)
+#define M_INT_UART_0                _SB_MAKEMASK1(K_INT_UART_0)
+#define M_INT_UART_1                _SB_MAKEMASK1(K_INT_UART_1)
+#define M_INT_SER_0                 _SB_MAKEMASK1(K_INT_SER_0)
+#define M_INT_SER_1                 _SB_MAKEMASK1(K_INT_SER_1)
+#define M_INT_PCMCIA                _SB_MAKEMASK1(K_INT_PCMCIA)
+#define M_INT_ADDR_TRAP             _SB_MAKEMASK1(K_INT_ADDR_TRAP)
+#define M_INT_PERF_CNT              _SB_MAKEMASK1(K_INT_PERF_CNT)
+#define M_INT_TRACE_FREEZE          _SB_MAKEMASK1(K_INT_TRACE_FREEZE)
+#define M_INT_BAD_ECC               _SB_MAKEMASK1(K_INT_BAD_ECC)
+#define M_INT_COR_ECC               _SB_MAKEMASK1(K_INT_COR_ECC)
+#define M_INT_IO_BUS                _SB_MAKEMASK1(K_INT_IO_BUS)
+#define M_INT_MAC_0                 _SB_MAKEMASK1(K_INT_MAC_0)
+#define M_INT_MAC_1                 _SB_MAKEMASK1(K_INT_MAC_1)
+#define M_INT_MAC_2                 _SB_MAKEMASK1(K_INT_MAC_2)
+#define M_INT_DM_CH_0               _SB_MAKEMASK1(K_INT_DM_CH_0)
+#define M_INT_DM_CH_1               _SB_MAKEMASK1(K_INT_DM_CH_1)
+#define M_INT_DM_CH_2               _SB_MAKEMASK1(K_INT_DM_CH_2)
+#define M_INT_DM_CH_3               _SB_MAKEMASK1(K_INT_DM_CH_3)
+#define M_INT_MBOX_0                _SB_MAKEMASK1(K_INT_MBOX_0)
+#define M_INT_MBOX_1                _SB_MAKEMASK1(K_INT_MBOX_1)
+#define M_INT_MBOX_2                _SB_MAKEMASK1(K_INT_MBOX_2)
+#define M_INT_MBOX_3                _SB_MAKEMASK1(K_INT_MBOX_3)
+#define M_INT_SPARE_0               _SB_MAKEMASK1(K_INT_SPARE_0)
+#define M_INT_SPARE_1               _SB_MAKEMASK1(K_INT_SPARE_1)
+#define M_INT_GPIO_0                _SB_MAKEMASK1(K_INT_GPIO_0)
+#define M_INT_GPIO_1                _SB_MAKEMASK1(K_INT_GPIO_1)
+#define M_INT_GPIO_2                _SB_MAKEMASK1(K_INT_GPIO_2)
+#define M_INT_GPIO_3                _SB_MAKEMASK1(K_INT_GPIO_3)
+#define M_INT_GPIO_4                _SB_MAKEMASK1(K_INT_GPIO_4)
+#define M_INT_GPIO_5                _SB_MAKEMASK1(K_INT_GPIO_5)
+#define M_INT_GPIO_6                _SB_MAKEMASK1(K_INT_GPIO_6)
+#define M_INT_GPIO_7                _SB_MAKEMASK1(K_INT_GPIO_7)
+#define M_INT_GPIO_8                _SB_MAKEMASK1(K_INT_GPIO_8)
+#define M_INT_GPIO_9                _SB_MAKEMASK1(K_INT_GPIO_9)
+#define M_INT_GPIO_10               _SB_MAKEMASK1(K_INT_GPIO_10)
+#define M_INT_GPIO_11               _SB_MAKEMASK1(K_INT_GPIO_11)
+#define M_INT_GPIO_12               _SB_MAKEMASK1(K_INT_GPIO_12)
+#define M_INT_GPIO_13               _SB_MAKEMASK1(K_INT_GPIO_13)
+#define M_INT_GPIO_14               _SB_MAKEMASK1(K_INT_GPIO_14)
+#define M_INT_GPIO_15               _SB_MAKEMASK1(K_INT_GPIO_15)
+#define M_INT_LDT_FATAL             _SB_MAKEMASK1(K_INT_LDT_FATAL)
+#define M_INT_LDT_NONFATAL          _SB_MAKEMASK1(K_INT_LDT_NONFATAL)
+#define M_INT_LDT_SMI               _SB_MAKEMASK1(K_INT_LDT_SMI)
+#define M_INT_LDT_NMI               _SB_MAKEMASK1(K_INT_LDT_NMI)
+#define M_INT_LDT_INIT              _SB_MAKEMASK1(K_INT_LDT_INIT)
+#define M_INT_LDT_STARTUP           _SB_MAKEMASK1(K_INT_LDT_STARTUP)
+#define M_INT_LDT_EXT               _SB_MAKEMASK1(K_INT_LDT_EXT)
+#define M_INT_PCI_ERROR             _SB_MAKEMASK1(K_INT_PCI_ERROR)
+#define M_INT_PCI_INTA              _SB_MAKEMASK1(K_INT_PCI_INTA)
+#define M_INT_PCI_INTB              _SB_MAKEMASK1(K_INT_PCI_INTB)
+#define M_INT_PCI_INTC              _SB_MAKEMASK1(K_INT_PCI_INTC)
+#define M_INT_PCI_INTD              _SB_MAKEMASK1(K_INT_PCI_INTD)
+#define M_INT_SPARE_2               _SB_MAKEMASK1(K_INT_SPARE_2)
+#define M_INT_SPARE_3               _SB_MAKEMASK1(K_INT_SPARE_3)
+#define M_INT_SPARE_4               _SB_MAKEMASK1(K_INT_SPARE_4)
+#define M_INT_SPARE_5               _SB_MAKEMASK1(K_INT_SPARE_5)
+
+/*
+ * Interrupt mappings
+ */
+
+#define K_INT_MAP_I0	0		/* interrupt pins on processor */
+#define K_INT_MAP_I1	1
+#define K_INT_MAP_I2	2
+#define K_INT_MAP_I3	3
+#define K_INT_MAP_I4	4
+#define K_INT_MAP_I5	5
+#define K_INT_MAP_NMI	6		/* nonmaskable */
+#define K_INT_MAP_DINT	7		/* debug interrupt */
+
+/*
+ * LDT Interrupt Set Register (table 4-5)
+ */
+
+#define S_INT_LDT_INTMSG	      0
+#define M_INT_LDT_INTMSG              _SB_MAKEMASK(3,S_INT_LDT_INTMSG)
+#define V_INT_LDT_INTMSG(x)           _SB_MAKEVALUE(x,S_INT_LDT_INTMSG)
+#define G_INT_LDT_INTMSG(x)           _SB_GETVALUE(x,S_INT_LDT_INTMSG,M_INT_LDT_INTMSG)
+
+#define K_INT_LDT_INTMSG_FIXED	      0
+#define K_INT_LDT_INTMSG_ARBITRATED   1
+#define K_INT_LDT_INTMSG_SMI	      2
+#define K_INT_LDT_INTMSG_NMI	      3
+#define K_INT_LDT_INTMSG_INIT	      4
+#define K_INT_LDT_INTMSG_STARTUP      5
+#define K_INT_LDT_INTMSG_EXTINT	      6
+#define K_INT_LDT_INTMSG_RESERVED     7
+
+#define M_INT_LDT_EDGETRIGGER         0
+#define M_INT_LDT_LEVELTRIGGER        _SB_MAKEMASK1(3)
+
+#define M_INT_LDT_PHYSICALDEST        0
+#define M_INT_LDT_LOGICALDEST         _SB_MAKEMASK1(4)
+
+#define S_INT_LDT_INTDEST             5
+#define M_INT_LDT_INTDEST             _SB_MAKEMASK(10,S_INT_LDT_INTDEST)
+#define V_INT_LDT_INTDEST(x)          _SB_MAKEVALUE(x,S_INT_LDT_INTDEST)
+#define G_INT_LDT_INTDEST(x)          _SB_GETVALUE(x,S_INT_LDT_INTDEST,M_INT_LDT_INTDEST)
+
+#define S_INT_LDT_VECTOR              13
+#define M_INT_LDT_VECTOR              _SB_MAKEMASK(8,S_INT_LDT_VECTOR)
+#define V_INT_LDT_VECTOR(x)           _SB_MAKEVALUE(x,S_INT_LDT_VECTOR)
+#define G_INT_LDT_VECTOR(x)           _SB_GETVALUE(x,S_INT_LDT_VECTOR,M_INT_LDT_VECTOR)
+
+/*
+ * Vector format (Table 4-6)
+ */
+
+#define M_LDTVECT_RAISEINT		0x00
+#define M_LDTVECT_RAISEMBOX             0x40
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_l2c.h linux/include/asm-mips/sibyte/sb1250_l2c.h
--- linux.orig/include/asm-mips/sibyte/sb1250_l2c.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_l2c.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,97 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  L2 Cache constants and macros		File: sb1250_l2c.h
+    *  
+    *  This module contains constants useful for manipulating the
+    *  level 2 cache.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_L2C_H
+#define _SB1250_L2C_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Level 2 Cache Tag register (Table 5-3)
+ */
+
+#define S_L2C_TAG_MBZ               0
+#define M_L2C_TAG_MBZ               _SB_MAKEMASK(5,S_L2C_TAG_MBZ)
+
+#define S_L2C_TAG_INDEX             5
+#define M_L2C_TAG_INDEX             _SB_MAKEMASK(12,S_L2C_TAG_INDEX)
+#define V_L2C_TAG_INDEX(x)          _SB_MAKEVALUE(x,S_L2C_TAG_INDEX)
+#define G_L2C_TAG_INDEX(x)          _SB_GETVALUE(x,S_L2C_TAG_INDEX,M_L2C_TAG_INDEX)
+
+#define S_L2C_TAG_TAG               17
+#define M_L2C_TAG_TAG               _SB_MAKEMASK(23,S_L2C_TAG_TAG)
+#define V_L2C_TAG_TAG(x)            _SB_MAKEVALUE(x,S_L2C_TAG_TAG)
+#define G_L2C_TAG_TAG(x)            _SB_GETVALUE(x,S_L2C_TAG_TAG,M_L2C_TAG_TAG)
+
+#define S_L2C_TAG_ECC               40
+#define M_L2C_TAG_ECC               _SB_MAKEMASK(6,S_L2C_TAG_ECC)
+#define V_L2C_TAG_ECC(x)            _SB_MAKEVALUE(x,S_L2C_TAG_ECC)
+#define G_L2C_TAG_ECC(x)            _SB_GETVALUE(x,S_L2C_TAG_ECC,M_L2C_TAG_ECC)
+
+#define S_L2C_TAG_WAY               46
+#define M_L2C_TAG_WAY               _SB_MAKEMASK(2,S_L2C_TAG_WAY)
+#define V_L2C_TAG_WAY(x)            _SB_MAKEVALUE(x,S_L2C_TAG_WAY)
+#define G_L2C_TAG_WAY(x)            _SB_GETVALUE(x,S_L2C_TAG_WAY,M_L2C_TAG_WAY)
+
+#define M_L2C_TAG_DIRTY             _SB_MAKEMASK1(48)
+#define M_L2C_TAG_VALID             _SB_MAKEMASK1(49)
+
+/*
+ * Format of level 2 cache management address (table 5-2)
+ */
+
+#define S_L2C_MGMT_INDEX            5
+#define M_L2C_MGMT_INDEX            _SB_MAKEMASK(12,S_L2C_MGMT_INDEX)
+#define V_L2C_MGMT_INDEX(x)         _SB_MAKEVALUE(x,S_L2C_MGMT_INDEX)
+#define G_L2C_MGMT_INDEX(x)         _SB_GETVALUE(x,S_L2C_MGMT_INDEX,M_L2C_MGMT_INDEX)
+
+#define S_L2C_MGMT_WAY              17
+#define M_L2C_MGMT_WAY              _SB_MAKEMASK(2,S_L2C_MGMT_WAY)
+#define V_L2C_MGMT_WAY(x)           _SB_MAKEVALUE(x,S_L2C_MGMT_WAY)
+#define G_L2C_MGMT_WAY(x)           _SB_GETVALUE(x,S_L2C_MGMT_WAY,M_L2C_MGMT_WAY)
+
+#define S_L2C_MGMT_TAG              21
+#define M_L2C_MGMT_TAG              _SB_MAKEMASK(6,S_L2C_MGMT_TAG)
+#define V_L2C_MGMT_TAG(x)           _SB_MAKEVALUE(x,S_L2C_MGMT_TAG)
+#define G_L2C_MGMT_TAG(x)           _SB_GETVALUE(x,S_L2C_MGMT_TAG,M_L2C_MGMT_TAG)
+
+#define M_L2C_MGMT_DIRTY            _SB_MAKEMASK1(19)
+#define M_L2C_MGMT_VALID            _SB_MAKEMASK1(20)
+
+#define A_L2C_MGMT_TAG_BASE         0x00D0000000
+
+#define L2C_ENTRIES_PER_WAY       4096
+#define L2C_NUM_WAYS              4
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_ldt.h linux/include/asm-mips/sibyte/sb1250_ldt.h
--- linux.orig/include/asm-mips/sibyte/sb1250_ldt.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_ldt.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,402 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  LDT constants				File: sb1250_ldt.h
+    *  
+    *  This module contains constants and macros to describe 
+    *  the LDT interface on the SB1250.  
+    *  
+    *  SB1250 specification level:  0.2 plus errata
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_LDT_H
+#define _SB1250_LDT_H
+
+#include "sb1250_defs.h"
+
+#define K_LDT_VENDOR_SIBYTE	0x166D
+#define K_LDT_DEVICE_SB1250	0x0002
+
+/*
+ * LDT Interface Type 1 (bridge) configuration header
+ */
+
+#define R_LDT_TYPE1_DEVICEID	0x0000
+#define R_LDT_TYPE1_CMDSTATUS	0x0004
+#define R_LDT_TYPE1_CLASSREV	0x0008
+#define R_LDT_TYPE1_DEVHDR	0x000C
+#define R_LDT_TYPE1_BAR0	0x0010	/* not used */
+#define R_LDT_TYPE1_BAR1	0x0014	/* not used */
+
+#define R_LDT_TYPE1_BUSID	0x0018	/* bus ID register */
+#define R_LDT_TYPE1_SECSTATUS	0x001C	/* secondary status / I/O base/limit */
+#define R_LDT_TYPE1_MEMLIMIT	0x0020
+#define R_LDT_TYPE1_PREFETCH	0x0024
+#define R_LDT_TYPE1_PREF_BASE	0x0028
+#define R_LDT_TYPE1_PREF_LIMIT	0x002C
+#define R_LDT_TYPE1_IOLIMIT	0x0030
+#define R_LDT_TYPE1_CAPPTR	0x0034
+#define R_LDT_TYPE1_ROMADDR	0x0038
+#define R_LDT_TYPE1_BRCTL	0x003C
+#define R_LDT_TYPE1_CMD		0x0040
+#define R_LDT_TYPE1_LINKCTRL	0x0044
+#define R_LDT_TYPE1_LINKFREQ	0x0048
+#define R_LDT_TYPE1_RESERVED1	0x004C
+#define R_LDT_TYPE1_SRICMD	0x0050
+#define R_LDT_TYPE1_SRITXNUM	0x0054
+#define R_LDT_TYPE1_SRIRXNUM	0x0058
+#define R_LDT_TYPE1_ERRSTATUS   0x0068
+#define R_LDT_TYPE1_SRICTRL	0x006C
+#define R_LDT_TYPE1_TXBUFCNT	0x00C8
+#define R_LDT_TYPE1_EXPCRC	0x00DC
+#define R_LDT_TYPE1_RXCRC	0x00F0
+
+
+/*
+ * LDT Device ID register
+ */
+
+#define S_LDT_DEVICEID_VENDOR		0
+#define M_LDT_DEVICEID_VENDOR		_SB_MAKEMASK_32(16,S_LDT_DEVICEID_VENDOR)
+#define V_LDT_DEVICEID_VENDOR(x)	_SB_MAKEVALUE_32(x,S_LDT_DEVICEID_VENDOR)
+#define G_LDT_DEVICEID_VENDOR(x)	_SB_GETVALUE_32(x,S_LDT_DEVICEID_VENDOR,M_LDT_DEVICEID_VENDOR)
+
+#define S_LDT_DEVICEID_DEVICEID		16
+#define M_LDT_DEVICEID_DEVICEID		_SB_MAKEMASK_32(16,S_LDT_DEVICEID_DEVICEID)
+#define V_LDT_DEVICEID_DEVICEID(x)	_SB_MAKEVALUE_32(x,S_LDT_DEVICEID_DEVICEID)
+#define G_LDT_DEVICEID_DEVICEID(x)	_SB_GETVALUE_32(x,S_LDT_DEVICEID_DEVICEID,M_LDT_DEVICEID_DEVICEID)
+
+
+/*
+ * LDT Command Register (Table 8-13)
+ */
+
+#define M_LDT_CMD_IOSPACE_EN		_SB_MAKEMASK1_32(0)
+#define M_LDT_CMD_MEMSPACE_EN		_SB_MAKEMASK1_32(1)
+#define M_LDT_CMD_MASTER_EN		_SB_MAKEMASK1_32(2)
+#define M_LDT_CMD_SPECCYC_EN		_SB_MAKEMASK1_32(3)
+#define M_LDT_CMD_MEMWRINV_EN		_SB_MAKEMASK1_32(4)
+#define M_LDT_CMD_VGAPALSNP_EN		_SB_MAKEMASK1_32(5)
+#define M_LDT_CMD_PARERRRESP		_SB_MAKEMASK1_32(6)
+#define M_LDT_CMD_WAITCYCCTRL		_SB_MAKEMASK1_32(7)
+#define M_LDT_CMD_SERR_EN		_SB_MAKEMASK1_32(8)
+#define M_LDT_CMD_FASTB2B_EN		_SB_MAKEMASK1_32(9)
+
+/*
+ * LDT class and revision registers
+ */
+
+#define S_LDT_CLASSREV_REV		0
+#define M_LDT_CLASSREV_REV		_SB_MAKEMASK_32(8,S_LDT_CLASSREV_REV)
+#define V_LDT_CLASSREV_REV(x)		_SB_MAKEVALUE_32(x,S_LDT_CLASSREV_REV)
+#define G_LDT_CLASSREV_REV(x)		_SB_GETVALUE_32(x,S_LDT_CLASSREV_REV,M_LDT_CLASSREV_REV)
+
+#define S_LDT_CLASSREV_CLASS		8
+#define M_LDT_CLASSREV_CLASS		_SB_MAKEMASK_32(24,S_LDT_CLASSREV_CLASS)
+#define V_LDT_CLASSREV_CLASS(x)		_SB_MAKEVALUE_32(x,S_LDT_CLASSREV_CLASS)
+#define G_LDT_CLASSREV_CLASS(x)		_SB_GETVALUE_32(x,S_LDT_CLASSREV_CLASS,M_LDT_CLASSREV_CLASS)
+
+#define K_LDT_REV			0x01
+#define K_LDT_CLASS			0x060000
+
+/*
+ * Device Header (offset 0x0C)
+ */
+
+#define S_LDT_DEVHDR_CLINESZ		0
+#define M_LDT_DEVHDR_CLINESZ		_SB_MAKEMASK_32(8,S_LDT_DEVHDR_CLINESZ)
+#define V_LDT_DEVHDR_CLINESZ(x)		_SB_MAKEVALUE_32(x,S_LDT_DEVHDR_CLINESZ)
+#define G_LDT_DEVHDR_CLINESZ(x)		_SB_GETVALUE_32(x,S_LDT_DEVHDR_CLINESZ,M_LDT_DEVHDR_CLINESZ)
+
+#define S_LDT_DEVHDR_LATTMR		8
+#define M_LDT_DEVHDR_LATTMR		_SB_MAKEMASK_32(8,S_LDT_DEVHDR_LATTMR)
+#define V_LDT_DEVHDR_LATTMR(x)		_SB_MAKEVALUE_32(x,S_LDT_DEVHDR_LATTMR)
+#define G_LDT_DEVHDR_LATTMR(x)		_SB_GETVALUE_32(x,S_LDT_DEVHDR_LATTMR,M_LDT_DEVHDR_LATTMR)
+
+#define S_LDT_DEVHDR_HDRTYPE		16
+#define M_LDT_DEVHDR_HDRTYPE		_SB_MAKEMASK_32(8,S_LDT_DEVHDR_HDRTYPE)
+#define V_LDT_DEVHDR_HDRTYPE(x)		_SB_MAKEVALUE_32(x,S_LDT_DEVHDR_HDRTYPE)
+#define G_LDT_DEVHDR_HDRTYPE(x)		_SB_GETVALUE_32(x,S_LDT_DEVHDR_HDRTYPE,M_LDT_DEVHDR_HDRTYPE)
+
+#define K_LDT_DEVHDR_HDRTYPE_TYPE1	1
+
+#define S_LDT_DEVHDR_BIST		24
+#define M_LDT_DEVHDR_BIST		_SB_MAKEMASK_32(8,S_LDT_DEVHDR_BIST)
+#define V_LDT_DEVHDR_BIST(x)		_SB_MAKEVALUE_32(x,S_LDT_DEVHDR_BIST)
+#define G_LDT_DEVHDR_BIST(x)		_SB_GETVALUE_32(x,S_LDT_DEVHDR_BIST,M_LDT_DEVHDR_BIST)
+
+
+
+/*
+ * LDT Status Register (Table 8-14).  Note that these constants
+ * assume you've read the command and status register 
+ * together (32-bit read at offset 0x04)
+ *
+ * These bits also apply to the secondary status
+ * register (Table 8-15), offset 0x1C
+ */
+
+#define M_LDT_STATUS_CAPLIST		_SB_MAKEMASK1_32(20)
+#define M_LDT_STATUS_66MHZCAP		_SB_MAKEMASK1_32(21)
+#define M_LDT_STATUS_RESERVED2		_SB_MAKEMASK1_32(22)
+#define M_LDT_STATUS_FASTB2BCAP		_SB_MAKEMASK1_32(23)
+#define M_LDT_STATUS_MSTRDPARERR	_SB_MAKEMASK1_32(24)
+
+#define S_LDT_STATUS_DEVSELTIMING	25
+#define M_LDT_STATUS_DEVSELTIMING	_SB_MAKEMASK_32(2,S_LDT_STATUS_DEVSELTIMING)
+#define V_LDT_STATUS_DEVSELTIMING(x)	_SB_MAKEVALUE_32(x,S_LDT_STATUS_DEVSELTIMING)
+#define G_LDT_STATUS_DEVSELTIMING(x)	_SB_GETVALUE_32(x,S_LDT_STATUS_DEVSELTIMING,M_LDT_STATUS_DEVSELTIMING)
+
+#define M_LDT_STATUS_SIGDTGTABORT	_SB_MAKEMASK1_32(27)
+#define M_LDT_STATUS_RCVDTGTABORT	_SB_MAKEMASK1_32(28)
+#define M_LDT_STATUS_RCVDMSTRABORT	_SB_MAKEMASK1_32(29)
+#define M_LDT_STATUS_SIGDSERR		_SB_MAKEMASK1_32(30)
+#define M_LDT_STATUS_DETPARERR		_SB_MAKEMASK1_32(31)
+
+/*
+ * Bridge Control Register (Table 8-16).  Note that these 
+ * constants assume you've read the register as a 32-bit 
+ * read (offset 0x3C)
+ */
+
+#define M_LDT_BRCTL_PARERRRESP_EN	_SB_MAKEMASK1_32(16)
+#define M_LDT_BRCTL_SERR_EN		_SB_MAKEMASK1_32(17)
+#define M_LDT_BRCTL_ISA_EN		_SB_MAKEMASK1_32(18)
+#define M_LDT_BRCTL_VGA_EN		_SB_MAKEMASK1_32(19)
+#define M_LDT_BRCTL_MSTRABORTMODE	_SB_MAKEMASK1_32(21)
+#define M_LDT_BRCTL_SECBUSRESET		_SB_MAKEMASK1_32(22)
+#define M_LDT_BRCTL_FASTB2B_EN		_SB_MAKEMASK1_32(23)
+#define M_LDT_BRCTL_PRIDISCARD		_SB_MAKEMASK1_32(24)
+#define M_LDT_BRCTL_SECDISCARD		_SB_MAKEMASK1_32(25)
+#define M_LDT_BRCTL_DISCARDSTAT		_SB_MAKEMASK1_32(26)
+#define M_LDT_BRCTL_DISCARDSERR_EN	_SB_MAKEMASK1_32(27)
+
+/*
+ * LDT Command Register (Table 8-17).  Note that these constants
+ * assume you've read the command and status register together
+ * 32-bit read at offset 0x40
+ */
+
+#define M_LDT_CMD_WARMRESET		_SB_MAKEMASK1_32(16)
+#define M_LDT_CMD_DOUBLEENDED		_SB_MAKEMASK1_32(17)
+
+#define S_LDT_CMD_CAPTYPE		29
+#define M_LDT_CMD_CAPTYPE		_SB_MAKEMASK_32(3,S_LDT_CMD_CAPTYPE)
+#define V_LDT_CMD_CAPTYPE(x)		_SB_MAKEVALUE_32(x,S_LDT_CMD_CAPTYPE)
+#define G_LDT_CMD_CAPTYPE(x)		_SB_GETVALUE_32(x,S_LDT_CMD_CAPTYPE,M_LDT_CMD_CAPTYPE)
+
+/*
+ * LDT link control register (Table 8-18), and (Table 8-19)
+ */
+
+#define M_LDT_LINKCTRL_CAPSYNCFLOOD_EN	_SB_MAKEMASK1_32(1)
+#define M_LDT_LINKCTRL_CRCSTARTTEST	_SB_MAKEMASK1_32(2)
+#define M_LDT_LINKCTRL_CRCFORCEERR	_SB_MAKEMASK1_32(3)
+#define M_LDT_LINKCTRL_LINKFAIL		_SB_MAKEMASK1_32(4)
+#define M_LDT_LINKCTRL_INITDONE		_SB_MAKEMASK1_32(5)
+#define M_LDT_LINKCTRL_EOC		_SB_MAKEMASK1_32(6)
+#define M_LDT_LINKCTRL_XMITOFF		_SB_MAKEMASK1_32(7)
+
+#define S_LDT_LINKCTRL_CRCERR		8
+#define M_LDT_LINKCTRL_CRCERR		_SB_MAKEMASK_32(4,S_LDT_LINKCTRL_CRCERR)
+#define V_LDT_LINKCTRL_CRCERR(x)	_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_CRCERR)
+#define G_LDT_LINKCTRL_CRCERR(x)	_SB_GETVALUE_32(x,S_LDT_LINKCTRL_CRCERR,M_LDT_LINKCTRL_CRCERR)
+
+#define S_LDT_LINKCTRL_MAXIN		16
+#define M_LDT_LINKCTRL_MAXIN		_SB_MAKEMASK_32(3,S_LDT_LINKCTRL_MAXIN)
+#define V_LDT_LINKCTRL_MAXIN(x)		_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_MAXIN)
+#define G_LDT_LINKCTRL_MAXIN(x)		_SB_GETVALUE_32(x,S_LDT_LINKCTRL_MAXIN,M_LDT_LINKCTRL_MAXIN)
+
+#define M_LDT_LINKCTRL_DWFCLN		_SB_MAKEMASK1_32(19)
+
+#define S_LDT_LINKCTRL_MAXOUT		20
+#define M_LDT_LINKCTRL_MAXOUT		_SB_MAKEMASK_32(3,S_LDT_LINKCTRL_MAXOUT)
+#define V_LDT_LINKCTRL_MAXOUT(x)	_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_MAXOUT)
+#define G_LDT_LINKCTRL_MAXOUT(x)	_SB_GETVALUE_32(x,S_LDT_LINKCTRL_MAXOUT,M_LDT_LINKCTRL_MAXOUT)
+
+#define M_LDT_LINKCTRL_DWFCOUT		_SB_MAKEMASK1_32(23)
+
+#define S_LDT_LINKCTRL_WIDTHIN		24
+#define M_LDT_LINKCTRL_WIDTHIN		_SB_MAKEMASK_32(3,S_LDT_LINKCTRL_WIDTHIN)
+#define V_LDT_LINKCTRL_WIDTHIN(x)	_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_WIDTHIN)
+#define G_LDT_LINKCTRL_WIDTHIN(x)	_SB_GETVALUE_32(x,S_LDT_LINKCTRL_WIDTHIN,M_LDT_LINKCTRL_WIDTHIN)
+
+#define M_LDT_LINKCTRL_DWFCLIN_EN	_SB_MAKEMASK1_32(27)
+
+#define S_LDT_LINKCTRL_WIDTHOUT		28
+#define M_LDT_LINKCTRL_WIDTHOUT		_SB_MAKEMASK_32(3,S_LDT_LINKCTRL_WIDTHOUT)
+#define V_LDT_LINKCTRL_WIDTHOUT(x)	_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_WIDTHOUT)
+#define G_LDT_LINKCTRL_WIDTHOUT(x)	_SB_GETVALUE_32(x,S_LDT_LINKCTRL_WIDTHOUT,M_LDT_LINKCTRL_WIDTHOUT)
+
+#define M_LDT_LINKCTRL_DWFCOUT_EN	_SB_MAKEMASK1_32(31)
+
+/*
+ * LDT Link frequency register  (Table 8-20) offset 0x48
+ */
+
+#define S_LDT_LINKFREQ_FREQ		8
+#define M_LDT_LINKFREQ_FREQ		_SB_MAKEMASK_32(4,S_LDT_LINKFREQ_FREQ)
+#define V_LDT_LINKFREQ_FREQ(x)		_SB_MAKEVALUE_32(x,S_LDT_LINKFREQ_FREQ)
+#define G_LDT_LINKFREQ_FREQ(x)		_SB_GETVALUE_32(x,S_LDT_LINKFREQ_FREQ,M_LDT_LINKFREQ_FREQ)
+
+#define K_LDT_LINKFREQ_200MHZ		0
+#define K_LDT_LINKFREQ_300MHZ		1
+#define K_LDT_LINKFREQ_400MHZ		2
+#define K_LDT_LINKFREQ_500MHZ		3
+#define K_LDT_LINKFREQ_600MHZ		4
+#define K_LDT_LINKFREQ_800MHZ		5
+#define K_LDT_LINKFREQ_1000MHZ		6
+
+/*
+ * LDT SRI Command Register (Table 8-21).  Note that these constants
+ * assume you've read the command and status register together
+ * 32-bit read at offset 0x50
+ */
+
+#define M_LDT_SRICMD_SIPREADY		_SB_MAKEMASK1_32(16)
+#define M_LDT_SRICMD_SYNCPTRCTL		_SB_MAKEMASK1_32(17)
+#define M_LDT_SRICMD_REDUCESYNCZERO	_SB_MAKEMASK1_32(18)
+#define M_LDT_SRICMD_DISSTARVATIONCNT	_SB_MAKEMASK1_32(19)
+
+#define S_LDT_SRICMD_RXMARGIN		20
+#define M_LDT_SRICMD_RXMARGIN		_SB_MAKEMASK_32(5,S_LDT_SRICMD_RXMARGIN)
+#define V_LDT_SRICMD_RXMARGIN(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICMD_RXMARGIN)
+#define G_LDT_SRICMD_RXMARGIN(x)	_SB_GETVALUE_32(x,S_LDT_SRICMD_RXMARGIN,M_LDT_SRICMD_RXMARGIN)
+
+#define M_LDT_SRICMD_LDTPLLCOMPAT	_SB_MAKEMASK1_32(25)
+
+#define S_LDT_SRICMD_TXINITIALOFFSET	28
+#define M_LDT_SRICMD_TXINITIALOFFSET	_SB_MAKEMASK_32(3,S_LDT_SRICMD_TXINITIALOFFSET)
+#define V_LDT_SRICMD_TXINITIALOFFSET(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICMD_TXINITIALOFFSET)
+#define G_LDT_SRICMD_TXINITIALOFFSET(x)	_SB_GETVALUE_32(x,S_LDT_SRICMD_TXINITIALOFFSET,M_LDT_SRICMD_TXINITIALOFFSET)
+
+#define M_LDT_SRICMD_LINKFREQDIRECT	_SB_MAKEMASK1_32(31)
+
+/*
+ * LDT Error control and status register (Table 8-22) (Table 8-23)
+ */
+
+#define M_LDT_ERRCTL_PROTFATAL_EN	_SB_MAKEMASK1_32(0)
+#define M_LDT_ERRCTL_PROTNONFATAL_EN	_SB_MAKEMASK1_32(1)
+#define M_LDT_ERRCTL_PROTSYNCFLOOD_EN	_SB_MAKEMASK1_32(2)
+#define M_LDT_ERRCTL_OVFFATAL_EN	_SB_MAKEMASK1_32(3)
+#define M_LDT_ERRCTL_OVFNONFATAL_EN	_SB_MAKEMASK1_32(4)
+#define M_LDT_ERRCTL_OVFSYNCFLOOD_EN	_SB_MAKEMASK1_32(5)
+#define M_LDT_ERRCTL_EOCNXAFATAL_EN	_SB_MAKEMASK1_32(6)
+#define M_LDT_ERRCTL_EOCNXANONFATAL_EN	_SB_MAKEMASK1_32(7)
+#define M_LDT_ERRCTL_EOCNXASYNCFLOOD_EN	_SB_MAKEMASK1_32(8)
+#define M_LDT_ERRCTL_CRCFATAL_EN	_SB_MAKEMASK1_32(9)
+#define M_LDT_ERRCTL_CRCNONFATAL_EN	_SB_MAKEMASK1_32(10)
+#define M_LDT_ERRCTL_SERRFATAL_EN	_SB_MAKEMASK1_32(11)
+#define M_LDT_ERRCTL_SRCTAGFATAL_EN	_SB_MAKEMASK1_32(12)
+#define M_LDT_ERRCTL_SRCTAGNONFATAL_EN	_SB_MAKEMASK1_32(13)
+#define M_LDT_ERRCTL_SRCTAGSYNCFLOOD_EN	_SB_MAKEMASK1_32(14)
+#define M_LDT_ERRCTL_MAPNXAFATAL_EN	_SB_MAKEMASK1_32(15)
+#define M_LDT_ERRCTL_MAPNXANONFATAL_EN	_SB_MAKEMASK1_32(16)
+#define M_LDT_ERRCTL_MAPNXASYNCFLOOD_EN	_SB_MAKEMASK1_32(17)
+
+#define M_LDT_ERRCTL_PROTOERR		_SB_MAKEMASK1_32(24)
+#define M_LDT_ERRCTL_OVFERR		_SB_MAKEMASK1_32(25)
+#define M_LDT_ERRCTL_EOCNXAERR		_SB_MAKEMASK1_32(26)
+#define M_LDT_ERRCTL_SRCTAGERR		_SB_MAKEMASK1_32(27)
+#define M_LDT_ERRCTL_MAPNXAERR		_SB_MAKEMASK1_32(28)
+
+/*
+ * SRI Control register (Table 8-24, 8-25)  Offset 0x6C
+ */
+
+#define S_LDT_SRICTRL_NEEDRESP		0
+#define M_LDT_SRICTRL_NEEDRESP		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDRESP)
+#define V_LDT_SRICTRL_NEEDRESP(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDRESP)
+#define G_LDT_SRICTRL_NEEDRESP(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDRESP,M_LDT_SRICTRL_NEEDRESP)
+
+#define S_LDT_SRICTRL_NEEDNPREQ		2
+#define M_LDT_SRICTRL_NEEDNPREQ		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDNPREQ)
+#define V_LDT_SRICTRL_NEEDNPREQ(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDNPREQ)
+#define G_LDT_SRICTRL_NEEDNPREQ(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDNPREQ,M_LDT_SRICTRL_NEEDNPREQ)
+
+#define S_LDT_SRICTRL_NEEDPREQ		4
+#define M_LDT_SRICTRL_NEEDPREQ		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDPREQ)
+#define V_LDT_SRICTRL_NEEDPREQ(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDPREQ)
+#define G_LDT_SRICTRL_NEEDPREQ(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDPREQ,M_LDT_SRICTRL_NEEDPREQ)
+
+#define S_LDT_SRICTRL_WANTRESP		8
+#define M_LDT_SRICTRL_WANTRESP		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTRESP)
+#define V_LDT_SRICTRL_WANTRESP(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTRESP)
+#define G_LDT_SRICTRL_WANTRESP(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTRESP,M_LDT_SRICTRL_WANTRESP)
+
+#define S_LDT_SRICTRL_WANTNPREQ		10
+#define M_LDT_SRICTRL_WANTNPREQ		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTNPREQ)
+#define V_LDT_SRICTRL_WANTNPREQ(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTNPREQ)
+#define G_LDT_SRICTRL_WANTNPREQ(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTNPREQ,M_LDT_SRICTRL_WANTNPREQ)
+
+#define S_LDT_SRICTRL_WANTPREQ		12
+#define M_LDT_SRICTRL_WANTPREQ		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTPREQ)
+#define V_LDT_SRICTRL_WANTPREQ(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTPREQ)
+#define G_LDT_SRICTRL_WANTPREQ(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTPREQ,M_LDT_SRICTRL_WANTPREQ)
+
+#define S_LDT_SRICTRL_BUFRELSPACE	16
+#define M_LDT_SRICTRL_BUFRELSPACE	_SB_MAKEMASK_32(4,S_LDT_SRICTRL_BUFRELSPACE)
+#define V_LDT_SRICTRL_BUFRELSPACE(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_BUFRELSPACE)
+#define G_LDT_SRICTRL_BUFRELSPACE(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_BUFRELSPACE,M_LDT_SRICTRL_BUFRELSPACE)
+
+/*
+ * LDT SRI Transmit Buffer Count register (Table 8-26)
+ */
+
+#define S_LDT_TXBUFCNT_PCMD		0
+#define M_LDT_TXBUFCNT_PCMD		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_PCMD)
+#define V_LDT_TXBUFCNT_PCMD(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_PCMD)
+#define G_LDT_TXBUFCNT_PCMD(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_PCMD,M_LDT_TXBUFCNT_PCMD)
+
+#define S_LDT_TXBUFCNT_PDATA		4
+#define M_LDT_TXBUFCNT_PDATA		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_PDATA)
+#define V_LDT_TXBUFCNT_PDATA(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_PDATA)
+#define G_LDT_TXBUFCNT_PDATA(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_PDATA,M_LDT_TXBUFCNT_PDATA)
+
+#define S_LDT_TXBUFCNT_NPCMD		8
+#define M_LDT_TXBUFCNT_NPCMD		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_NPCMD)
+#define V_LDT_TXBUFCNT_NPCMD(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_NPCMD)
+#define G_LDT_TXBUFCNT_NPCMD(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_NPCMD,M_LDT_TXBUFCNT_NPCMD)
+
+#define S_LDT_TXBUFCNT_NPDATA		12
+#define M_LDT_TXBUFCNT_NPDATA		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_NPDATA)
+#define V_LDT_TXBUFCNT_NPDATA(x)	_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_NPDATA)
+#define G_LDT_TXBUFCNT_NPDATA(x)	_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_NPDATA,M_LDT_TXBUFCNT_NPDATA)
+
+#define S_LDT_TXBUFCNT_RCMD		16
+#define M_LDT_TXBUFCNT_RCMD		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_RCMD)
+#define V_LDT_TXBUFCNT_RCMD(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_RCMD)
+#define G_LDT_TXBUFCNT_RCMD(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_RCMD,M_LDT_TXBUFCNT_RCMD)
+
+#define S_LDT_TXBUFCNT_RDATA		20
+#define M_LDT_TXBUFCNT_RDATA		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_RDATA)
+#define V_LDT_TXBUFCNT_RDATA(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_RDATA)
+#define G_LDT_TXBUFCNT_RDATA(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_RDATA,M_LDT_TXBUFCNT_RDATA)
+
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_mac.h linux/include/asm-mips/sibyte/sb1250_mac.h
--- linux.orig/include/asm-mips/sibyte/sb1250_mac.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_mac.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,533 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  MAC constants and macros			File: sb1250_mac.h
+    *  
+    *  This module contains constants and macros for the SB1250's
+    *  ethernet controllers.
+    *  
+    *  SB1250 specification level:  0.2 plus errata as of 4/10/2001
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_MAC_H
+#define _SB1250_MAC_H
+
+#include "sb1250_defs.h"
+
+/*  *********************************************************************
+    *  Ethernet MAC Registers
+    ********************************************************************* */
+
+/*
+ * MAC Configuration Register (Table 9-13)
+ * Register: MAC_CFG_0
+ * Register: MAC_CFG_1
+ * Register: MAC_CFG_2
+ */
+
+
+/* Updated to spec 0.2 */
+
+#define M_MAC_RESERVED0             _SB_MAKEMASK1(0)
+#define M_MAC_TX_HOLD_SOP_EN        _SB_MAKEMASK1(1)
+#define M_MAC_RETRY_EN              _SB_MAKEMASK1(2)
+#define M_MAC_RET_DRPREQ_EN         _SB_MAKEMASK1(3)
+#define M_MAC_RET_UFL_EN            _SB_MAKEMASK1(4)
+#define M_MAC_BURST_EN              _SB_MAKEMASK1(5)
+
+#define S_MAC_TX_PAUSE              _SB_MAKE64(6)
+#define M_MAC_TX_PAUSE_CNT          _SB_MAKEMASK(3,S_MAC_TX_PAUSE)
+#define V_MAC_TX_PAUSE_CNT(x)       _SB_MAKEVALUE(x,S_MAC_TX_PAUSE)
+
+#define K_MAC_TX_PAUSE_CNT_512      0
+#define K_MAC_TX_PAUSE_CNT_1K       1
+#define K_MAC_TX_PAUSE_CNT_2K       2
+#define K_MAC_TX_PAUSE_CNT_4K       3
+#define K_MAC_TX_PAUSE_CNT_8K       4
+#define K_MAC_TX_PAUSE_CNT_16K      5
+#define K_MAC_TX_PAUSE_CNT_32K      6
+#define K_MAC_TX_PAUSE_CNT_64K      7
+
+#define V_MAC_TX_PAUSE_CNT_512      V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_512)
+#define V_MAC_TX_PAUSE_CNT_1K       V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_1K)
+#define V_MAC_TX_PAUSE_CNT_2K       V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_2K)
+#define V_MAC_TX_PAUSE_CNT_4K       V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_4K)
+#define V_MAC_TX_PAUSE_CNT_8K       V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_8K)
+#define V_MAC_TX_PAUSE_CNT_16K      V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_16K)
+#define V_MAC_TX_PAUSE_CNT_32K      V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_32K)
+#define V_MAC_TX_PAUSE_CNT_64K      V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_64K)
+
+#define M_MAC_RESERVED1             _SB_MAKEMASK(8,9)
+
+#define M_MAC_AP_STAT_EN            _SB_MAKEMASK1(17)
+#define M_MAC_RESERVED2		    _SB_MAKEMASK1(18)
+#define M_MAC_DRP_ERRPKT_EN         _SB_MAKEMASK1(19)
+#define M_MAC_DRP_FCSERRPKT_EN      _SB_MAKEMASK1(20)
+#define M_MAC_DRP_CODEERRPKT_EN     _SB_MAKEMASK1(21)
+#define M_MAC_DRP_DRBLERRPKT_EN     _SB_MAKEMASK1(22)
+#define M_MAC_DRP_RNTPKT_EN         _SB_MAKEMASK1(23)
+#define M_MAC_DRP_OSZPKT_EN         _SB_MAKEMASK1(24)
+#define M_MAC_DRP_LENERRPKT_EN      _SB_MAKEMASK1(25)
+
+#define M_MAC_RESERVED3             _SB_MAKEMASK(6,26)
+
+#define M_MAC_BYPASS_SEL            _SB_MAKEMASK1(32)
+#define M_MAC_HDX_EN                _SB_MAKEMASK1(33)
+
+#define S_MAC_SPEED_SEL             _SB_MAKE64(34)
+#define M_MAC_SPEED_SEL             _SB_MAKEMASK(2,S_MAC_SPEED_SEL)
+#define V_MAC_SPEED_SEL(x)	    _SB_MAKEVALUE(x,S_MAC_SPEED_SEL)
+#define G_MAC_SPEED_SEL(x)	    _SB_GETVALUE(x,S_MAC_SPEED_SEL,M_MAC_SPEED_SEL)
+
+#define K_MAC_SPEED_SEL_10MBPS      0
+#define K_MAC_SPEED_SEL_100MBPS     1
+#define K_MAC_SPEED_SEL_1000MBPS    2
+#define K_MAC_SPEED_SEL_RESERVED    3
+
+#define V_MAC_SPEED_SEL_10MBPS      V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_10MBPS)
+#define V_MAC_SPEED_SEL_100MBPS     V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_100MBPS)
+#define V_MAC_SPEED_SEL_1000MBPS    V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_1000MBPS)
+#define V_MAC_SPEED_SEL_RESERVED    V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_RESERVED)
+
+#define M_MAC_TX_CLK_EDGE_SEL       _SB_MAKEMASK1(36)
+#define M_MAC_LOOPBACK_SEL          _SB_MAKEMASK1(37)
+#define M_MAC_FAST_SYNC             _SB_MAKEMASK1(38)
+#define M_MAC_SS_EN                 _SB_MAKEMASK1(39)
+
+#define S_MAC_BYPASS_CFG	    _SB_MAKE64(40)
+#define M_MAC_BYPASS_CFG            _SB_MAKEMASK(2,S_MAC_BYPASS_CFG)
+#define V_MAC_BYPASS_CFG(x)         _SB_MAKEVALUE(x,S_MAC_BYPASS_CFG)
+#define G_MAC_BYPASS_CFG(x)         _SB_GETVALUE(x,S_MAC_BYPASS_CFG,M_MAC_BYPASS_CFG)
+
+#define K_MAC_BYPASS_GMII	    0
+#define K_MAC_BYPASS_ENCODED        1
+#define K_MAC_BYPASS_SOP            2
+#define K_MAC_BYPASS_EOP            3
+
+#define M_MAC_BYPASS_16             _SB_MAKEMASK1(42)
+#define M_MAC_BYPASS_FCS_CHK	    _SB_MAKEMASK1(43)
+
+#define M_MAC_RESERVED4	    	    _SB_MAKEMASK(2,44)
+
+#define S_MAC_BYPASS_IFG            _SB_MAKE64(46)
+#define M_MAC_BYPASS_IFG            _SB_MAKEMASK(8,S_MAC_BYPASS_IFG)
+#define V_MAC_BYPASS_IFG(x)	    _SB_MAKEVALUE(x,S_MAC_BYPASS_IFG)
+#define G_MAC_BYPASS_IFG(x)	    _SB_GETVALUE(x,S_MAC_BYPASS_IFG,M_MAC_BYPASS_IFG)
+
+#define K_MAC_FC_CMD_DISABLED       0
+#define K_MAC_FC_CMD_ENABLED        1
+#define K_MAC_FC_CMD_ENAB_FALSECARR 2
+
+#define V_MAC_FC_CMD_DISABLED       V_MAC_FC_CMD(K_MAC_FC_CMD_DISABLED)
+#define V_MAC_FC_CMD_ENABLED        V_MAC_FC_CMD(K_MAC_FC_CMD_ENABLED)
+#define V_MAC_FC_CMD_ENAB_FALSECARR V_MAC_FC_CMD(K_MAC_FC_CMD_ENAB_FALSECARR)
+
+#define M_MAC_FC_SEL                _SB_MAKEMASK1(54)
+
+#define S_MAC_FC_CMD                _SB_MAKE64(55)
+#define M_MAC_FC_CMD                _SB_MAKEMASK(2,S_MAC_FC_CMD)
+#define V_MAC_FC_CMD(x)	            _SB_MAKEVALUE(x,S_MAC_FC_CMD)
+#define G_MAC_FC_CMD(x)	            _SB_GETVALUE(x,S_MAC_FC_CMD,M_MAC_FC_CMD)
+
+#define S_MAC_RX_CH_SEL             _SB_MAKE64(57)
+#define M_MAC_RX_CH_SEL             _SB_MAKEMASK(7,S_MAC_RX_CH_SEL)
+#define V_MAC_RX_CH_SEL(x)          _SB_MAKEVALUE(x,S_MAC_RX_CH_SEL)
+#define G_MAC_RX_CH_SEL(x)          _SB_GETVALUE(x,S_MAC_RX_CH_SEL,M_MAC_RX_CH_SEL)
+
+
+/*
+ * MAC Enable Registers
+ * Register: MAC_ENABLE_0
+ * Register: MAC_ENABLE_1
+ * Register: MAC_ENABLE_2
+ */
+
+#define M_MAC_RXDMA_EN0	            _SB_MAKEMASK1(0)
+#define M_MAC_RXDMA_EN1	            _SB_MAKEMASK1(1)
+#define M_MAC_TXDMA_EN0	            _SB_MAKEMASK1(4)
+#define M_MAC_TXDMA_EN1	            _SB_MAKEMASK1(5)
+
+#define M_MAC_PORT_RESET            _SB_MAKEMASK1(8)
+
+#define M_MAC_RX_ENABLE             _SB_MAKEMASK1(10)
+#define M_MAC_TX_ENABLE             _SB_MAKEMASK1(11)
+#define M_MAC_BYP_RX_ENABLE         _SB_MAKEMASK1(12)
+#define M_MAC_BYP_TX_ENABLE         _SB_MAKEMASK1(13)
+
+/*
+ * MAC DMA Control Register
+ * Register: MAC_TXD_CTL_0
+ * Register: MAC_TXD_CTL_1
+ * Register: MAC_TXD_CTL_2
+ */
+
+#define S_MAC_TXD_WEIGHT0	    _SB_MAKE64(0)
+#define M_MAC_TXD_WEIGHT0	    _SB_MAKEMASK(4,S_MAC_TXD_WEIGHT0)
+#define V_MAC_TXD_WEIGHT0(x)        _SB_MAKEVALUE(x,S_MAC_TXD_WEIGHT0)
+#define G_MAC_TXD_WEIGHT0(x)        _SB_GETVALUE(x,S_MAC_TXD_WEIGHT0,M_MAC_TXD_WEIGHT0)
+
+#define S_MAC_TXD_WEIGHT1	    _SB_MAKE64(4)
+#define M_MAC_TXD_WEIGHT1	    _SB_MAKEMASK(4,S_MAC_TXD_WEIGHT1)
+#define V_MAC_TXD_WEIGHT1(x)        _SB_MAKEVALUE(x,S_MAC_TXD_WEIGHT1)
+#define G_MAC_TXD_WEIGHT1(x)        _SB_GETVALUE(x,S_MAC_TXD_WEIGHT1,M_MAC_TXD_WEIGHT1)
+
+/*
+ * MAC Fifo Threshhold registers (Table 9-14)
+ * Register: MAC_THRSH_CFG_0
+ * Register: MAC_THRSH_CFG_1
+ * Register: MAC_THRSH_CFG_2
+ */
+
+#define S_MAC_TX_WR_THRSH           _SB_MAKE64(0)
+#define M_MAC_TX_WR_THRSH           _SB_MAKEMASK(6,S_MAC_TX_WR_THRSH)
+#define V_MAC_TX_WR_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_TX_WR_THRSH)
+#define G_MAC_TX_WR_THRSH(x)        _SB_GETVALUE(x,S_MAC_TX_WR_THRSH,M_MAC_TX_WR_THRSH)
+
+#define S_MAC_TX_RD_THRSH           _SB_MAKE64(8)
+#define M_MAC_TX_RD_THRSH           _SB_MAKEMASK(6,S_MAC_TX_RD_THRSH)
+#define V_MAC_TX_RD_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_TX_RD_THRSH)
+#define G_MAC_TX_RD_THRSH(x)        _SB_GETVALUE(x,S_MAC_TX_RD_THRSH,M_MAC_TX_RD_THRSH)
+
+#define S_MAC_TX_RL_THRSH           _SB_MAKE64(16)
+#define M_MAC_TX_RL_THRSH           _SB_MAKEMASK(4,S_MAC_TX_RL_THRSH)
+#define V_MAC_TX_RL_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_TX_RL_THRSH)
+#define G_MAC_TX_RL_THRSH(x)        _SB_GETVALUE(x,S_MAC_TX_RL_THRSH,M_MAC_TX_RL_THRSH)
+
+#define S_MAC_RX_PL_THRSH           _SB_MAKE64(24)
+#define M_MAC_RX_PL_THRSH           _SB_MAKEMASK(6,S_MAC_RX_PL_THRSH)
+#define V_MAC_RX_PL_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_RX_PL_THRSH)
+#define G_MAC_RX_PL_THRSH(x)        _SB_GETVALUE(x,S_MAC_RX_PL_THRSH,M_MAC_RX_PL_THRSH)
+
+#define S_MAC_RX_RD_THRSH           _SB_MAKE64(32)
+#define M_MAC_RX_RD_THRSH           _SB_MAKEMASK(6,S_MAC_RX_RD_THRSH)
+#define V_MAC_RX_RD_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_RX_RD_THRSH)
+#define G_MAC_RX_RD_THRSH(x)        _SB_GETVALUE(x,S_MAC_RX_RD_THRSH,M_MAC_RX_RD_THRSH)
+
+#define S_MAC_RX_RL_THRSH           _SB_MAKE64(40)
+#define M_MAC_RX_RL_THRSH           _SB_MAKEMASK(6,S_MAC_RX_RL_THRSH)
+#define V_MAC_RX_RL_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_RX_RL_THRSH)
+#define G_MAC_RX_RL_THRSH(x)        _SB_GETVALUE(x,S_MAC_RX_RL_THRSH,M_MAC_RX_RL_THRSH)
+
+/*
+ * MAC Frame Configuration Registers (Table 9-15)
+ * Register: MAC_FRAME_CFG_0
+ * Register: MAC_FRAME_CFG_1
+ * Register: MAC_FRAME_CFG_2
+ */
+
+#define S_MAC_IFG_RX                _SB_MAKE64(0)
+#define M_MAC_IFG_RX                _SB_MAKEMASK(6,S_MAC_IFG_RX)
+#define V_MAC_IFG_RX(x)             _SB_MAKEVALUE(x,S_MAC_IFG_RX)
+#define G_MAC_IFG_RX(x)             _SB_GETVALUE(x,S_MAC_IFG_RX,M_MAC_IFG_RX)
+
+#define S_MAC_IFG_TX                _SB_MAKE64(6)
+#define M_MAC_IFG_TX                _SB_MAKEMASK(6,S_MAC_IFG_TX)
+#define V_MAC_IFG_TX(x)             _SB_MAKEVALUE(x,S_MAC_IFG_TX)
+#define G_MAC_IFG_TX(x)             _SB_GETVALUE(x,S_MAC_IFG_TX,M_MAC_IFG_TX)
+
+#define S_MAC_IFG_THRSH             _SB_MAKE64(12)
+#define M_MAC_IFG_THRSH             _SB_MAKEMASK(6,S_MAC_IFG_THRSH)
+#define V_MAC_IFG_THRSH(x)          _SB_MAKEVALUE(x,S_MAC_IFG_THRSH)
+#define G_MAC_IFG_THRSH(x)          _SB_GETVALUE(x,S_MAC_IFG_THRSH,M_MAC_IFG_THRSH)
+
+#define S_MAC_BACKOFF_SEL           _SB_MAKE64(18)
+#define M_MAC_BACKOFF_SEL           _SB_MAKEMASK(4,S_MAC_BACKOFF_SEL)
+#define V_MAC_BACKOFF_SEL(x)        _SB_MAKEVALUE(x,S_MAC_BACKOFF_SEL)
+#define G_MAC_BACKOFF_SEL(x)        _SB_GETVALUE(x,S_MAC_BACKOFF_SEL,M_MAC_BACKOFF_SEL)
+
+#define S_MAC_LFSR_SEED             _SB_MAKE64(22)
+#define M_MAC_LFSR_SEED             _SB_MAKEMASK(8,S_MAC_LFSR_SEED)
+#define V_MAC_LFSR_SEED(x)          _SB_MAKEVALUE(x,S_MAC_LFSR_SEED)
+#define G_MAC_LFSR_SEED(x)          _SB_GETVALUE(x,S_MAC_LFSR_SEED,M_MAC_LFSR_SEED)
+
+#define S_MAC_SLOT_SIZE             _SB_MAKE64(30)
+#define M_MAC_SLOT_SIZE             _SB_MAKEMASK(10,S_MAC_SLOT_SIZE)
+#define V_MAC_SLOT_SIZE(x)          _SB_MAKEVALUE(x,S_MAC_SLOT_SIZE)
+#define G_MAC_SLOT_SIZE(x)          _SB_GETVALUE(x,S_MAC_SLOT_SIZE,M_MAC_SLOT_SIZE)
+
+#define S_MAC_MIN_FRAMESZ           _SB_MAKE64(40)
+#define M_MAC_MIN_FRAMESZ           _SB_MAKEMASK(8,S_MAC_MIN_FRAMESZ)
+#define V_MAC_MIN_FRAMESZ(x)        _SB_MAKEVALUE(x,S_MAC_MIN_FRAMESZ)
+#define G_MAC_MIN_FRAMESZ(x)        _SB_GETVALUE(x,S_MAC_MIN_FRAMESZ,M_MAC_MIN_FRAMESZ)
+
+#define S_MAC_MAX_FRAMESZ           _SB_MAKE64(48)
+#define M_MAC_MAX_FRAMESZ           _SB_MAKEMASK(16,S_MAC_MAX_FRAMESZ)
+#define V_MAC_MAX_FRAMESZ(x)        _SB_MAKEVALUE(x,S_MAC_MAX_FRAMESZ)
+#define G_MAC_MAX_FRAMESZ(x)        _SB_GETVALUE(x,S_MAC_MAX_FRAMESZ,M_MAC_MAX_FRAMESZ)
+
+/*
+ * These constants are used to configure the fields within the Frame
+ * Configuration Register.  
+ */
+
+#define K_MAC_IFG_RX_10             _SB_MAKE64(18)
+#define K_MAC_IFG_RX_100            _SB_MAKE64(18)
+#define K_MAC_IFG_RX_1000           _SB_MAKE64(6)
+
+#define K_MAC_IFG_TX_10             _SB_MAKE64(20)
+#define K_MAC_IFG_TX_100            _SB_MAKE64(20)
+#define K_MAC_IFG_TX_1000           _SB_MAKE64(8)
+
+#define K_MAC_IFG_THRSH_10          _SB_MAKE64(12)
+#define K_MAC_IFG_THRSH_100         _SB_MAKE64(12)
+#define K_MAC_IFG_THRSH_1000        _SB_MAKE64(4)
+
+#define K_MAC_SLOT_SIZE_10          _SB_MAKE64(0)
+#define K_MAC_SLOT_SIZE_100         _SB_MAKE64(0)
+#define K_MAC_SLOT_SIZE_1000        _SB_MAKE64(0)
+
+#define V_MAC_IFG_RX_10        V_MAC_IFG_RX(K_MAC_IFG_RX_10)
+#define V_MAC_IFG_RX_100       V_MAC_IFG_RX(K_MAC_IFG_RX_100)
+#define V_MAC_IFG_RX_1000      V_MAC_IFG_RX(K_MAC_IFG_RX_1000)
+
+#define V_MAC_IFG_TX_10        V_MAC_IFG_TX(K_MAC_IFG_TX_10)
+#define V_MAC_IFG_TX_100       V_MAC_IFG_TX(K_MAC_IFG_TX_100)
+#define V_MAC_IFG_TX_1000      V_MAC_IFG_TX(K_MAC_IFG_TX_1000)
+
+#define V_MAC_IFG_THRSH_10     V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_10)
+#define V_MAC_IFG_THRSH_100    V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_100)
+#define V_MAC_IFG_THRSH_1000   V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_1000)
+
+#define V_MAC_SLOT_SIZE_10     V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_10)
+#define V_MAC_SLOT_SIZE_100    V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_100)
+#define V_MAC_SLOT_SIZE_1000   V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_1000)
+
+#define K_MAC_MIN_FRAMESZ_DEFAULT   _SB_MAKE64(64)
+#define K_MAC_MAX_FRAMESZ_DEFAULT   _SB_MAKE64(1518)
+
+#define V_MAC_MIN_FRAMESZ_DEFAULT   V_MAC_MIN_FRAMESZ(K_MAC_MIN_FRAMESZ_DEFAULT)
+#define V_MAC_MAX_FRAMESZ_DEFAULT   V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_DEFAULT)
+
+/*
+ * MAC VLAN Tag Registers (Table 9-16)
+ * Register: MAC_VLANTAG_0
+ * Register: MAC_VLANTAG_1
+ * Register: MAC_VLANTAG_2
+ */
+
+/* No bit fields: lower 32 bits of register are the tags */
+
+/*
+ * MAC Status Registers (Table 9-17)
+ * Also used for the MAC Interrupt Mask Register (Table 9-18)
+ * Register: MAC_STATUS_0
+ * Register: MAC_STATUS_1
+ * Register: MAC_STATUS_2
+ * Register: MAC_INT_MASK_0
+ * Register: MAC_INT_MASK_1
+ * Register: MAC_INT_MASK_2
+ */
+
+/* 
+ * Use these constants to shift the appropriate channel
+ * into the CH0 position so the same tests can be used
+ * on each channel.
+ */
+
+#define S_MAC_RX_CH0                _SB_MAKE64(0)
+#define S_MAC_RX_CH1                _SB_MAKE64(8)
+#define S_MAC_TX_CH0                _SB_MAKE64(16)
+#define S_MAC_TX_CH1                _SB_MAKE64(24)
+
+#define S_MAC_TXCHANNELS	    _SB_MAKE64(16)	/* this is 1st TX chan */
+#define S_MAC_CHANWIDTH             _SB_MAKE64(8)	/* bits between channels */
+
+/*
+ *  These are the same as RX channel 0.  The idea here
+ *  is that you'll use one of the "S_" things above
+ *  and pass just the six bits to a DMA-channel-specific ISR
+ */
+#define M_MAC_INT_CHANNEL           _SB_MAKEMASK(8,0)
+#define M_MAC_INT_EOP_COUNT         _SB_MAKEMASK1(0)
+#define M_MAC_INT_EOP_TIMER         _SB_MAKEMASK1(1)
+#define M_MAC_INT_EOP_SEEN          _SB_MAKEMASK1(2)
+#define M_MAC_INT_HWM               _SB_MAKEMASK1(3)
+#define M_MAC_INT_LWM               _SB_MAKEMASK1(4)
+#define M_MAC_INT_DSCR              _SB_MAKEMASK1(5)
+#define M_MAC_INT_ERR               _SB_MAKEMASK1(6)
+#define M_MAC_INT_DZERO             _SB_MAKEMASK1(7)	/* only for TX channels */
+
+
+#define M_MAC_RX_UNDRFL             _SB_MAKEMASK1(40)
+#define M_MAC_RX_OVRFL              _SB_MAKEMASK1(41)
+#define M_MAC_TX_UNDRFL             _SB_MAKEMASK1(42)
+#define M_MAC_TX_OVRFL              _SB_MAKEMASK1(43)
+#define M_MAC_LTCOL_ERR             _SB_MAKEMASK1(44)
+#define M_MAC_EXCOL_ERR             _SB_MAKEMASK1(45)
+#define M_MAC_CNTR_OVRFL_ERR        _SB_MAKEMASK1(46)
+
+#define S_MAC_COUNTER_ADDR          _SB_MAKE64(47)
+#define M_MAC_COUNTER_ADDR          _SB_MAKEMASK(5,S_MAC_COUNTER_ADDR)
+#define V_MAC_COUNTER_ADDR(x)       _SB_MAKEVALUE(x,S_MAC_COUNTER_ADDR)
+#define G_MAC_COUNTER_ADDR(x)       _SB_GETVALUE(x,S_MAC_COUNTER_ADDR,M_MAC_COUNTER_ADDR)
+
+/*
+ * MAC Fifo Pointer Registers (Table 9-19)    [Debug register]
+ * Register: MAC_FIFO_PTRS_0
+ * Register: MAC_FIFO_PTRS_1
+ * Register: MAC_FIFO_PTRS_2
+ */
+
+#define S_MAC_TX_WRPTR              _SB_MAKE64(0)
+#define M_MAC_TX_WRPTR              _SB_MAKEMASK(6,S_MAC_TX_WRPTR)
+#define V_MAC_TX_WRPTR(x)           _SB_MAKEVALUE(x,S_MAC_TX_WRPTR)
+#define G_MAC_TX_WRPTR(x)           _SB_GETVALUE(x,S_MAC_TX_WRPTR,M_MAC_TX_WRPTR)
+
+#define S_MAC_TX_RDPTR              _SB_MAKE64(8)
+#define M_MAC_TX_RDPTR              _SB_MAKEMASK(6,S_MAC_TX_RDPTR)
+#define V_MAC_TX_RDPTR(x)           _SB_MAKEVALUE(x,S_MAC_TX_RDPTR)
+#define G_MAC_TX_RDPTR(x)           _SB_GETVALUE(x,S_MAC_TX_RDPTR,M_MAC_TX_RDPTR)
+
+#define S_MAC_RX_WRPTR              _SB_MAKE64(16)
+#define M_MAC_RX_WRPTR              _SB_MAKEMASK(6,S_MAC_RX_WRPTR)
+#define V_MAC_RX_WRPTR(x)           _SB_MAKEVALUE(x,S_MAC_RX_WRPTR)
+#define G_MAC_RX_WRPTR(x)           _SB_GETVALUE(x,S_MAC_RX_WRPTR,M_MAC_TX_WRPTR)
+
+#define S_MAC_RX_RDPTR              _SB_MAKE64(24)
+#define M_MAC_RX_RDPTR              _SB_MAKEMASK(6,S_MAC_RX_RDPTR)
+#define V_MAC_RX_RDPTR(x)           _SB_MAKEVALUE(x,S_MAC_RX_RDPTR)
+#define G_MAC_RX_RDPTR(x)           _SB_GETVALUE(x,S_MAC_RX_RDPTR,M_MAC_TX_RDPTR)
+
+/*
+ * MAC Fifo End Of Packet Count Registers (Table 9-20)  [Debug register]
+ * Register: MAC_EOPCNT_0
+ * Register: MAC_EOPCNT_1
+ * Register: MAC_EOPCNT_2
+ */
+
+#define S_MAC_TX_EOP_COUNTER        _SB_MAKE64(0)
+#define M_MAC_TX_EOP_COUNTER        _SB_MAKEMASK(6,S_MAC_TX_EOP_COUNTER)
+#define V_MAC_TX_EOP_COUNTER(x)     _SB_MAKEVALUE(x,S_MAC_TX_EOP_COUNTER)
+#define G_MAC_TX_EOP_COUNTER(x)     _SB_GETVALUE(x,S_MAC_TX_EOP_COUNTER,M_MAC_TX_EOP_COUNTER)
+
+#define S_MAC_RX_EOP_COUNTER        _SB_MAKE64(8)
+#define M_MAC_RX_EOP_COUNTER        _SB_MAKEMASK(6,S_MAC_RX_EOP_COUNTER)
+#define V_MAC_RX_EOP_COUNTER(x)     _SB_MAKEVALUE(x,S_MAC_RX_EOP_COUNTER)
+#define G_MAC_RX_EOP_COUNTER(x)     _SB_GETVALUE(x,S_MAC_RX_EOP_COUNTER,M_MAC_RX_EOP_COUNTER)
+
+/*
+ * MAC Recieve Address Filter Exact Match Registers (Table 9-21)
+ * Registers: MAC_ADDR0_0 through MAC_ADDR7_0
+ * Registers: MAC_ADDR0_1 through MAC_ADDR7_1
+ * Registers: MAC_ADDR0_2 through MAC_ADDR7_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Recieve Address Filter Hash Match Registers (Table 9-22)
+ * Registers: MAC_HASH0_0 through MAC_HASH7_0
+ * Registers: MAC_HASH0_1 through MAC_HASH7_1
+ * Registers: MAC_HASH0_2 through MAC_HASH7_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Transmit Source Address Registers (Table 9-23)
+ * Register: MAC_ETHERNET_ADDR_0
+ * Register: MAC_ETHERNET_ADDR_1
+ * Register: MAC_ETHERNET_ADDR_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Packet Type Configuration Register
+ * Register: MAC_TYPE_CFG_0
+ * Register: MAC_TYPE_CFG_1
+ * Register: MAC_TYPE_CFG_2
+ */
+
+#define S_TYPECFG_TYPESIZE      _SB_MAKE64(16)
+
+#define S_TYPECFG_TYPE0		_SB_MAKE64(0)
+#define M_TYPECFG_TYPE0         _SB_MAKEMASK(16,S_TYPECFG_TYPE0)
+#define V_TYPECFG_TYPE0(x)      _SB_MAKEVALUE(x,S_TYPECFG_TYPE0)
+#define G_TYPECFG_TYPE0(x)      _SB_GETVALUE(x,S_TYPECFG_TYPE0,M_TYPECFG_TYPE0)
+
+#define S_TYPECFG_TYPE1		_SB_MAKE64(0)
+#define M_TYPECFG_TYPE1         _SB_MAKEMASK(16,S_TYPECFG_TYPE1)
+#define V_TYPECFG_TYPE1(x)      _SB_MAKEVALUE(x,S_TYPECFG_TYPE1)
+#define G_TYPECFG_TYPE1(x)      _SB_GETVALUE(x,S_TYPECFG_TYPE1,M_TYPECFG_TYPE1)
+
+#define S_TYPECFG_TYPE2		_SB_MAKE64(0)
+#define M_TYPECFG_TYPE2         _SB_MAKEMASK(16,S_TYPECFG_TYPE2)
+#define V_TYPECFG_TYPE2(x)      _SB_MAKEVALUE(x,S_TYPECFG_TYPE2)
+#define G_TYPECFG_TYPE2(x)      _SB_GETVALUE(x,S_TYPECFG_TYPE2,M_TYPECFG_TYPE2)
+
+#define S_TYPECFG_TYPE3		_SB_MAKE64(0)
+#define M_TYPECFG_TYPE3         _SB_MAKEMASK(16,S_TYPECFG_TYPE3)
+#define V_TYPECFG_TYPE3(x)      _SB_MAKEVALUE(x,S_TYPECFG_TYPE3)
+#define G_TYPECFG_TYPE3(x)      _SB_GETVALUE(x,S_TYPECFG_TYPE3,M_TYPECFG_TYPE3)
+
+/*
+ * MAC Receive Address Filter Control Registers (Table 9-24)
+ * Register: MAC_ADFILTER_CFG_0
+ * Register: MAC_ADFILTER_CFG_1
+ * Register: MAC_ADFILTER_CFG_2
+ */
+
+#define M_MAC_ALLPKT_EN	        _SB_MAKEMASK1(0)
+#define M_MAC_UCAST_EN          _SB_MAKEMASK1(1)
+#define M_MAC_UCAST_INV         _SB_MAKEMASK1(2)
+#define M_MAC_MCAST_EN          _SB_MAKEMASK1(3)
+#define M_MAC_MCAST_INV         _SB_MAKEMASK1(4)
+#define M_MAC_BCAST_EN          _SB_MAKEMASK1(5)
+#define M_MAC_DIRECT_INV        _SB_MAKEMASK1(6)
+
+#define S_MAC_IPHDR_OFFSET      _SB_MAKE64(8)
+#define M_MAC_IPHDR_OFFSET      _SB_MAKEMASK(8,S_MAC_IPHDR_OFFSET)
+#define V_MAC_IPHDR_OFFSET(x)	_SB_MAKEVALUE(x,S_MAC_IPHDR_OFFSET)
+#define G_MAC_IPHDR_OFFSET(x)	_SB_GETVALUE(x,S_MAC_IPHDR_OFFSET,M_MAC_IPHDR_OFFSET)
+
+/*
+ * MAC Receive Channel Select Registers (Table 9-25)
+ */
+
+/* no bitfields */
+
+/*
+ * MAC MII Management Interface Registers (Table 9-26)
+ * Register: MAC_MDIO_0
+ * Register: MAC_MDIO_1
+ * Register: MAC_MDIO_2
+ */
+
+#define S_MAC_MDC		0
+#define S_MAC_MDIO_DIR		1
+#define S_MAC_MDIO_OUT		2
+#define S_MAC_GENC		3
+#define S_MAC_MDIO_IN		4
+
+#define M_MAC_MDC		_SB_MAKEMASK1(S_MAC_MDC)
+#define M_MAC_MDIO_DIR		_SB_MAKEMASK1(S_MAC_MDIO_DIR)
+#define M_MAC_MDIO_DIR_INPUT	_SB_MAKEMASK1(S_MAC_MDIO_DIR)
+#define M_MAC_MDIO_OUT		_SB_MAKEMASK1(S_MAC_MDIO_OUT)
+#define M_MAC_GENC		_SB_MAKEMASK1(S_MAC_GENC)
+#define M_MAC_MDIO_IN		_SB_MAKEMASK1(S_MAC_MDIO_IN)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_mc.h linux/include/asm-mips/sibyte/sb1250_mc.h
--- linux.orig/include/asm-mips/sibyte/sb1250_mc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_mc.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,529 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Memory Controller constants              File: sb1250_mc.h       
+    *  
+    *  This module contains constants and macros useful for
+    *  programming the memory controller.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_MC_H
+#define _SB1250_MC_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Memory Channel Config Register (table 6-14)
+ */
+
+#define S_MC_RESERVED0              0
+#define M_MC_RESERVED0              _SB_MAKEMASK(8,S_MC_RESERVED0)
+
+#define S_MC_CHANNEL_SEL            8
+#define M_MC_CHANNEL_SEL            _SB_MAKEMASK(8,S_MC_CHANNEL_SEL)
+#define V_MC_CHANNEL_SEL(x)         _SB_MAKEVALUE(x,S_MC_CHANNEL_SEL)
+#define G_MC_CHANNEL_SEL(x)         _SB_GETVALUE(x,S_MC_CHANNEL_SEL,M_MC_CHANNEL_SEL)
+
+#define S_MC_BANK0_MAP              16
+#define M_MC_BANK0_MAP              _SB_MAKEMASK(4,S_MC_BANK0_MAP)
+#define V_MC_BANK0_MAP(x)           _SB_MAKEVALUE(x,S_MC_BANK0_MAP)
+#define G_MC_BANK0_MAP(x)           _SB_GETVALUE(x,S_MC_BANK0_MAP,M_MC_BANK0_MAP)
+
+#define K_MC_BANK0_MAP_DEFAULT      0x00
+#define V_MC_BANK0_MAP_DEFAULT      V_MC_BANK0_MAP(K_MC_BANK0_MAP_DEFAULT)
+
+#define S_MC_BANK1_MAP              20
+#define M_MC_BANK1_MAP              _SB_MAKEMASK(4,S_MC_BANK1_MAP)
+#define V_MC_BANK1_MAP(x)           _SB_MAKEVALUE(x,S_MC_BANK1_MAP)
+#define G_MC_BANK1_MAP(x)           _SB_GETVALUE(x,S_MC_BANK1_MAP,M_MC_BANK1_MAP)
+
+#define K_MC_BANK1_MAP_DEFAULT      0x08
+#define V_MC_BANK1_MAP_DEFAULT      V_MC_BANK1_MAP(K_MC_BANK1_MAP_DEFAULT)
+
+#define S_MC_BANK2_MAP              24
+#define M_MC_BANK2_MAP              _SB_MAKEMASK(4,S_MC_BANK2_MAP)
+#define V_MC_BANK2_MAP(x)           _SB_MAKEVALUE(x,S_MC_BANK2_MAP)
+#define G_MC_BANK2_MAP(x)           _SB_GETVALUE(x,S_MC_BANK2_MAP,M_MC_BANK2_MAP)
+
+#define K_MC_BANK2_MAP_DEFAULT      0x09
+#define V_MC_BANK2_MAP_DEFAULT      V_MC_BANK2_MAP(K_MC_BANK2_MAP_DEFAULT)
+
+#define S_MC_BANK3_MAP              28
+#define M_MC_BANK3_MAP              _SB_MAKEMASK(4,S_MC_BANK3_MAP)
+#define V_MC_BANK3_MAP(x)           _SB_MAKEVALUE(x,S_MC_BANK3_MAP)
+#define G_MC_BANK3_MAP(x)           _SB_GETVALUE(x,S_MC_BANK3_MAP,M_MC_BANK3_MAP)
+
+#define K_MC_BANK3_MAP_DEFAULT      0x0C
+#define V_MC_BANK3_MAP_DEFAULT      V_MC_BANK3_MAP(K_MC_BANK3_MAP_DEFAULT)
+
+#define M_MC_RESERVED1              _SB_MAKEMASK(8,32)
+
+#define S_MC_QUEUE_SIZE		    40
+#define M_MC_QUEUE_SIZE             _SB_MAKEMASK(4,S_MC_QUEUE_SIZE)
+#define V_MC_QUEUE_SIZE(x)          _SB_MAKEVALUE(x,S_MC_QUEUE_SIZE)
+#define G_MC_QUEUE_SIZE(x)          _SB_GETVALUE(x,S_MC_QUEUE_SIZE,M_MC_QUEUE_SIZE)
+#define V_MC_QUEUE_SIZE_DEFAULT     V_MC_QUEUE_SIZE(0x0A)
+
+#define S_MC_AGE_LIMIT              44
+#define M_MC_AGE_LIMIT              _SB_MAKEMASK(4,S_MC_AGE_LIMIT)
+#define V_MC_AGE_LIMIT(x)           _SB_MAKEVALUE(x,S_MC_AGE_LIMIT)
+#define G_MC_AGE_LIMIT(x)           _SB_GETVALUE(x,S_MC_AGE_LIMIT,M_MC_AGE_LIMIT)
+#define V_MC_AGE_LIMIT_DEFAULT      V_MC_AGE_LIMIT(8)
+
+#define S_MC_WR_LIMIT               48
+#define M_MC_WR_LIMIT               _SB_MAKEMASK(4,S_MC_WR_LIMIT)
+#define V_MC_WR_LIMIT(x)            _SB_MAKEVALUE(x,S_MC_WR_LIMIT)
+#define G_MC_WR_LIMIT(x)            _SB_GETVALUE(x,S_MC_WR_LIMIT,M_MC_WR_LIMIT)
+#define V_MC_WR_LIMIT_DEFAULT       V_MC_WR_LIMIT(5)
+
+#define M_MC_IOB1HIGHPRIORITY	    _SB_MAKEMASK1(52)
+
+#define M_MC_RESERVED2              _SB_MAKEMASK(3,53)
+
+#define S_MC_CS_MODE                56
+#define M_MC_CS_MODE                _SB_MAKEMASK(4,S_MC_CS_MODE)
+#define V_MC_CS_MODE(x)             _SB_MAKEVALUE(x,S_MC_CS_MODE)
+#define G_MC_CS_MODE(x)             _SB_GETVALUE(x,S_MC_CS_MODE,M_MC_CS_MODE)
+
+#define K_MC_CS_MODE_MSB_CS         0
+#define K_MC_CS_MODE_INTLV_CS       15
+#define K_MC_CS_MODE_MIXED_CS_10    12
+#define K_MC_CS_MODE_MIXED_CS_30    6
+#define K_MC_CS_MODE_MIXED_CS_32    3
+
+#define V_MC_CS_MODE_MSB_CS         V_MC_CS_MODE(K_MC_CS_MODE_MSB_CS)
+#define V_MC_CS_MODE_INTLV_CS       V_MC_CS_MODE(K_MC_CS_MODE_INTLV_CS)
+#define V_MC_CS_MODE_MIXED_CS_10    V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_10)
+#define V_MC_CS_MODE_MIXED_CS_30    V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_30)
+#define V_MC_CS_MODE_MIXED_CS_32    V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_32)
+
+#define M_MC_ECC_DISABLE            _SB_MAKEMASK1(60)
+#define M_MC_BERR_DISABLE           _SB_MAKEMASK1(61)
+#define M_MC_FORCE_SEQ              _SB_MAKEMASK1(62)
+#define M_MC_DEBUG                  _SB_MAKEMASK1(63)
+
+#define V_MC_CONFIG_DEFAULT     V_MC_WR_LIMIT_DEFAULT | V_MC_AGE_LIMIT_DEFAULT | \
+				V_MC_BANK0_MAP_DEFAULT | V_MC_BANK1_MAP_DEFAULT | \
+				V_MC_BANK2_MAP_DEFAULT | V_MC_BANK3_MAP_DEFAULT | V_MC_CHANNEL_SEL(0) | \
+                                M_MC_IOB1HIGHPRIORITY | V_MC_QUEUE_SIZE_DEFAULT
+
+
+/*
+ * Memory clock config register (Table 6-15)
+ *
+ * Note: this field has been updated to be consistent with the errata to 0.2
+ */
+
+#define S_MC_CLK_RATIO              0
+#define M_MC_CLK_RATIO              _SB_MAKEMASK(4,S_MC_CLK_RATIO)
+#define V_MC_CLK_RATIO(x)           _SB_MAKEVALUE(x,S_MC_CLK_RATIO)
+#define G_MC_CLK_RATIO(x)           _SB_GETVALUE(x,S_MC_CLK_RATIO,M_MC_CLK_RATIO)
+
+#define K_MC_CLK_RATIO_2X           4
+#define K_MC_CLK_RATIO_25X          5
+#define K_MC_CLK_RATIO_3X           6
+#define K_MC_CLK_RATIO_35X          7
+#define K_MC_CLK_RATIO_4X           8
+#define K_MC_CLK_RATIO_45X	    9
+
+#define V_MC_CLK_RATIO_2X	    V_MC_CLK_RATIO(K_MC_CLK_RATIO_2X)
+#define V_MC_CLK_RATIO_25X          V_MC_CLK_RATIO(K_MC_CLK_RATIO_25X)
+#define V_MC_CLK_RATIO_3X           V_MC_CLK_RATIO(K_MC_CLK_RATIO_3X)
+#define V_MC_CLK_RATIO_35X          V_MC_CLK_RATIO(K_MC_CLK_RATIO_35X)
+#define V_MC_CLK_RATIO_4X           V_MC_CLK_RATIO(K_MC_CLK_RATIO_4X)
+#define V_MC_CLK_RATIO_45X          V_MC_CLK_RATIO(K_MC_CLK_RATIO_45X)
+#define V_MC_CLK_RATIO_DEFAULT      V_MC_CLK_RATIO_25X
+
+#define S_MC_REF_RATE                8
+#define M_MC_REF_RATE                _SB_MAKEMASK(8,S_MC_REF_RATE)
+#define V_MC_REF_RATE(x)             _SB_MAKEVALUE(x,S_MC_REF_RATE)
+#define G_MC_REF_RATE(x)             _SB_GETVALUE(x,S_MC_REF_RATE,M_MC_REF_RATE)
+
+#define K_MC_REF_RATE_100MHz         0x62
+#define K_MC_REF_RATE_133MHz         0x81
+#define K_MC_REF_RATE_200MHz         0xC4 
+
+#define V_MC_REF_RATE_100MHz         V_MC_REF_RATE(K_MC_REF_RATE_100MHz)
+#define V_MC_REF_RATE_133MHz         V_MC_REF_RATE(K_MC_REF_RATE_133MHz)
+#define V_MC_REF_RATE_200MHz         V_MC_REF_RATE(K_MC_REF_RATE_200MHz)
+#define V_MC_REF_RATE_DEFAULT        V_MC_REF_RATE_100MHz
+
+#define S_MC_CLOCK_DRIVE             16
+#define M_MC_CLOCK_DRIVE             _SB_MAKEMASK(4,S_MC_CLOCK_DRIVE)
+#define V_MC_CLOCK_DRIVE(x)          _SB_MAKEVALUE(x,S_MC_CLOCK_DRIVE)
+#define G_MC_CLOCK_DRIVE(x)          _SB_GETVALUE(x,S_MC_CLOCK_DRIVE,M_MC_CLOCK_DRIVE)
+#define V_MC_CLOCK_DRIVE_DEFAULT     V_MC_CLOCK_DRIVE(0xF)
+
+#define S_MC_DATA_DRIVE              20
+#define M_MC_DATA_DRIVE              _SB_MAKEMASK(4,S_MC_DATA_DRIVE)
+#define V_MC_DATA_DRIVE(x)           _SB_MAKEVALUE(x,S_MC_DATA_DRIVE)
+#define G_MC_DATA_DRIVE(x)           _SB_GETVALUE(x,S_MC_DATA_DRIVE,M_MC_DATA_DRIVE)
+#define V_MC_DATA_DRIVE_DEFAULT      V_MC_DATA_DRIVE(0x0)
+
+#define S_MC_ADDR_DRIVE              24
+#define M_MC_ADDR_DRIVE              _SB_MAKEMASK(4,S_MC_ADDR_DRIVE)
+#define V_MC_ADDR_DRIVE(x)           _SB_MAKEVALUE(x,S_MC_ADDR_DRIVE)
+#define G_MC_ADDR_DRIVE(x)           _SB_GETVALUE(x,S_MC_ADDR_DRIVE,M_MC_ADDR_DRIVE)
+#define V_MC_ADDR_DRIVE_DEFAULT      V_MC_ADDR_DRIVE(0x0)
+
+#define M_MC_DLL_BYPASS              _SB_MAKEMASK1(31)
+
+#define S_MC_DQI_SKEW               32
+#define M_MC_DQI_SKEW               _SB_MAKEMASK(8,S_MC_DQI_SKEW)
+#define V_MC_DQI_SKEW(x)            _SB_MAKEVALUE(x,S_MC_DQI_SKEW)
+#define G_MC_DQI_SKEW(x)            _SB_GETVALUE(x,S_MC_DQI_SKEW,M_MC_DQI_SKEW)
+#define V_MC_DQI_SKEW_DEFAULT       V_MC_DQI_SKEW(0)
+
+#define S_MC_DQO_SKEW               40
+#define M_MC_DQO_SKEW               _SB_MAKEMASK(8,S_MC_DQO_SKEW)
+#define V_MC_DQO_SKEW(x)            _SB_MAKEVALUE(x,S_MC_DQO_SKEW)
+#define G_MC_DQO_SKEW(x)            _SB_GETVALUE(x,S_MC_DQO_SKEW,M_MC_DQO_SKEW)
+#define V_MC_DQO_SKEW_DEFAULT       V_MC_DQO_SKEW(0)
+
+#define S_MC_ADDR_SKEW               48
+#define M_MC_ADDR_SKEW               _SB_MAKEMASK(8,S_MC_ADDR_SKEW)
+#define V_MC_ADDR_SKEW(x)            _SB_MAKEVALUE(x,S_MC_ADDR_SKEW)
+#define G_MC_ADDR_SKEW(x)            _SB_GETVALUE(x,S_MC_ADDR_SKEW,M_MC_ADDR_SKEW)
+#define V_MC_ADDR_SKEW_DEFAULT       V_MC_ADDR_SKEW(0x0F)
+
+#define S_MC_DLL_DEFAULT             56
+#define M_MC_DLL_DEFAULT             _SB_MAKEMASK(8,S_MC_DLL_DEFAULT)
+#define V_MC_DLL_DEFAULT(x)          _SB_MAKEVALUE(x,S_MC_DLL_DEFAULT)
+#define G_MC_DLL_DEFAULT(x)          _SB_GETVALUE(x,S_MC_DLL_DEFAULT,M_MC_DLL_DEFAULT)
+#define V_MC_DLL_DEFAULT_DEFAULT     V_MC_DLL_DEFAULT(0x10)
+
+#define V_MC_CLKCONFIG_DEFAULT       V_MC_DLL_DEFAULT_DEFAULT |  \
+                                     V_MC_ADDR_SKEW_DEFAULT | \
+                                     V_MC_DQO_SKEW_DEFAULT | \
+                                     V_MC_DQI_SKEW_DEFAULT | \
+                                     V_MC_ADDR_DRIVE_DEFAULT | \
+                                     V_MC_DATA_DRIVE_DEFAULT | \
+                                     V_MC_CLOCK_DRIVE_DEFAULT | \
+                                     V_MC_REF_RATE_DEFAULT 
+
+
+
+/*
+ * DRAM Command Register (Table 6-13)
+ */
+
+#define S_MC_COMMAND                0
+#define M_MC_COMMAND                _SB_MAKEMASK(4,S_MC_COMMAND)
+#define V_MC_COMMAND(x)             _SB_MAKEVALUE(x,S_MC_COMMAND)
+#define G_MC_COMMAND(x)             _SB_GETVALUE(x,S_MC_COMMAND,M_MC_COMMAND)
+
+#define K_MC_COMMAND_EMRS           0
+#define K_MC_COMMAND_MRS            1
+#define K_MC_COMMAND_PRE            2
+#define K_MC_COMMAND_AR             3
+#define K_MC_COMMAND_SETRFSH        4
+#define K_MC_COMMAND_CLRRFSH        5
+#define K_MC_COMMAND_SETPWRDN       6
+#define K_MC_COMMAND_CLRPWRDN       7
+
+#define V_MC_COMMAND_EMRS           V_MC_COMMAND(K_MC_COMMAND_EMRS)
+#define V_MC_COMMAND_MRS            V_MC_COMMAND(K_MC_COMMAND_MRS)
+#define V_MC_COMMAND_PRE            V_MC_COMMAND(K_MC_COMMAND_PRE)
+#define V_MC_COMMAND_AR             V_MC_COMMAND(K_MC_COMMAND_AR)
+#define V_MC_COMMAND_SETRFSH        V_MC_COMMAND(K_MC_COMMAND_SETRFSH)
+#define V_MC_COMMAND_CLRRFSH        V_MC_COMMAND(K_MC_COMMAND_CLRRFSH)
+#define V_MC_COMMAND_SETPWRDN       V_MC_COMMAND(K_MC_COMMAND_SETPWRDN)
+#define V_MC_COMMAND_CLRPWRDN       V_MC_COMMAND(K_MC_COMMAND_CLRPWRDN)
+
+#define M_MC_CS0                    _SB_MAKEMASK1(4)
+#define M_MC_CS1                    _SB_MAKEMASK1(5)
+#define M_MC_CS2                    _SB_MAKEMASK1(6)
+#define M_MC_CS3                    _SB_MAKEMASK1(7)
+
+/*
+ * DRAM Mode Register (Table 6-14)
+ */
+
+#define S_MC_EMODE                  0
+#define M_MC_EMODE                  _SB_MAKEMASK(15,S_MC_EMODE)
+#define V_MC_EMODE(x)               _SB_MAKEVALUE(x,S_MC_EMODE)
+#define G_MC_EMODE(x)               _SB_GETVALUE(x,S_MC_EMODE,M_MC_EMODE)
+#define V_MC_EMODE_DEFAULT          V_MC_EMODE(0)
+
+#define S_MC_MODE                   16
+#define M_MC_MODE                   _SB_MAKEMASK(15,S_MC_MODE)
+#define V_MC_MODE(x)                _SB_MAKEVALUE(x,S_MC_MODE)
+#define G_MC_MODE(x)                _SB_GETVALUE(x,S_MC_MODE,M_MC_MODE)
+#define V_MC_MODE_DEFAULT           V_MC_MODE(0x22)
+
+#define S_MC_DRAM_TYPE              32
+#define M_MC_DRAM_TYPE              _SB_MAKEMASK(3,S_MC_DRAM_TYPE)
+#define V_MC_DRAM_TYPE(x)           _SB_MAKEVALUE(x,S_MC_DRAM_TYPE)
+#define G_MC_DRAM_TYPE(x)           _SB_GETVALUE(x,S_MC_DRAM_TYPE,M_MC_DRAM_TYPE)
+
+#define K_MC_DRAM_TYPE_JEDEC        0
+#define K_MC_DRAM_TYPE_FCRAM        1
+#define K_MC_DRAM_TYPE_SGRAM	    2
+
+#define V_MC_DRAM_TYPE_JEDEC        V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_JEDEC)
+#define V_MC_DRAM_TYPE_FCRAM        V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_FCRAM)
+#define V_MC_DRAM_TYPE_SGRAM        V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_SGRAM)
+
+#define M_MC_EXTERNALDECODE	    _SB_MAKEMASK1(35)
+
+
+
+
+/*
+ * SDRAM Timing Register  (Table 6-15)
+ */
+
+#define M_MC_w2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(62)
+#define M_MC_r2wIDLE_TWOCYCLES	  _SB_MAKEMASK1(61)
+#define M_MC_r2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(60)
+
+#define S_MC_tFIFO                56
+#define M_MC_tFIFO                _SB_MAKEMASK(4,S_MC_tFIFO)
+#define V_MC_tFIFO(x)             _SB_MAKEVALUE(x,S_MC_tFIFO)
+#define K_MC_tFIFO_DEFAULT        1
+#define V_MC_tFIFO_DEFAULT        V_MC_tFIFO(K_MC_tFIFO_DEFAULT)
+
+#define S_MC_tRFC                 52
+#define M_MC_tRFC                 _SB_MAKEMASK(4,S_MC_tRFC)
+#define V_MC_tRFC(x)              _SB_MAKEVALUE(x,S_MC_tRFC)
+#define K_MC_tRFC_DEFAULT         12
+#define V_MC_tRFC_DEFAULT         V_MC_tRFC(K_MC_tRFC_DEFAULT)
+
+#define S_MC_tCwCr                40
+#define M_MC_tCwCr                _SB_MAKEMASK(4,S_MC_tCwCr)
+#define V_MC_tCwCr(x)             _SB_MAKEVALUE(x,S_MC_tCwCr)
+#define K_MC_tCwCr_DEFAULT        4
+#define V_MC_tCwCr_DEFAULT        V_MC_tCwCr(K_MC_tCwCr_DEFAULT)
+
+#define S_MC_tRCr                 28
+#define M_MC_tRCr                 _SB_MAKEMASK(4,S_MC_tRCr)
+#define V_MC_tRCr(x)              _SB_MAKEVALUE(x,S_MC_tRCr)
+#define K_MC_tRCr_DEFAULT         9
+#define V_MC_tRCr_DEFAULT         V_MC_tRCr(K_MC_tRCr_DEFAULT)
+
+#define S_MC_tRCw                 24
+#define M_MC_tRCw                 _SB_MAKEMASK(4,S_MC_tRCw)
+#define V_MC_tRCw(x)              _SB_MAKEVALUE(x,S_MC_tRCw)
+#define K_MC_tRCw_DEFAULT         10
+#define V_MC_tRCw_DEFAULT         V_MC_tRCw(K_MC_tRCw_DEFAULT)
+
+#define S_MC_tRRD                 20
+#define M_MC_tRRD                 _SB_MAKEMASK(4,S_MC_tRRD)
+#define V_MC_tRRD(x)              _SB_MAKEVALUE(x,S_MC_tRRD)
+#define K_MC_tRRD_DEFAULT         2
+#define V_MC_tRRD_DEFAULT         V_MC_tRRD(K_MC_tRRD_DEFAULT)
+
+#define S_MC_tRP                  16
+#define M_MC_tRP                  _SB_MAKEMASK(4,S_MC_tRP)
+#define V_MC_tRP(x)               _SB_MAKEVALUE(x,S_MC_tRP)
+#define K_MC_tRP_DEFAULT          4
+#define V_MC_tRP_DEFAULT          V_MC_tRP(K_MC_tRP_DEFAULT)
+
+#define S_MC_tCwD                 8
+#define M_MC_tCwD                 _SB_MAKEMASK(4,S_MC_tCwD)
+#define V_MC_tCwD(x)              _SB_MAKEVALUE(x,S_MC_tCwD)
+#define K_MC_tCwD_DEFAULT         1
+#define V_MC_tCwD_DEFAULT         V_MC_tCwD(K_MC_tCwD_DEFAULT)
+
+#define M_tCrDh                   _SB_MAKEMASK1(7)
+
+#define S_MC_tCrD                 4
+#define M_MC_tCrD                 _SB_MAKEMASK(3,S_MC_tCrD)
+#define V_MC_tCrD(x)              _SB_MAKEVALUE(x,S_MC_tCrD)
+#define K_MC_tCrD_DEFAULT         2
+#define V_MC_tCrD_DEFAULT         V_MC_tCrD(K_MC_tCrD_DEFAULT)
+
+#define S_MC_tRCD                 0
+#define M_MC_tRCD                 _SB_MAKEMASK(4,S_MC_tRCD)
+#define V_MC_tRCD(x)              _SB_MAKEVALUE(x,S_MC_tRCD)
+#define K_MC_tRCD_DEFAULT         3
+#define V_MC_tRCD_DEFAULT         V_MC_tRCD(K_MC_tRCD_DEFAULT)
+
+#define V_MC_TIMING_DEFAULT     V_MC_tFIFO(K_MC_tFIFO_DEFAULT) | \
+                                V_MC_tRFC(K_MC_tRFC_DEFAULT) | \
+                                V_MC_tCwCr(K_MC_tCwCr_DEFAULT) | \
+                                V_MC_tRCr(K_MC_tRCr_DEFAULT) | \
+                                V_MC_tRCw(K_MC_tRCw_DEFAULT) | \
+                                V_MC_tRRD(K_MC_tRRD_DEFAULT) | \
+                                V_MC_tRP(K_MC_tRP_DEFAULT) | \
+                                V_MC_tCwD(K_MC_tCwD_DEFAULT) | \
+                                V_MC_tCrD(K_MC_tCrD_DEFAULT) | \
+                                V_MC_tRCD(K_MC_tRCD_DEFAULT) | \
+                                M_MC_r2rIDLE_TWOCYCLES
+
+/*
+ * Errata says these are not the default
+ *                               M_MC_w2rIDLE_TWOCYCLES | \
+ *                               M_MC_r2wIDLE_TWOCYCLES | \
+ */
+
+
+/*
+ * Chip Select Start Address Register (Table 6-17)
+ */
+
+#define S_MC_CS0_START              0
+#define M_MC_CS0_START              _SB_MAKEMASK(16,S_MC_CS0_START)
+#define V_MC_CS0_START(x)           _SB_MAKEVALUE(x,S_MC_CS0_START)
+#define G_MC_CS0_START(x)           _SB_GETVALUE(x,S_MC_CS0_START,M_MC_CS0_START)
+
+#define S_MC_CS1_START              16
+#define M_MC_CS1_START              _SB_MAKEMASK(16,S_MC_CS1_START)
+#define V_MC_CS1_START(x)           _SB_MAKEVALUE(x,S_MC_CS1_START)
+#define G_MC_CS1_START(x)           _SB_GETVALUE(x,S_MC_CS1_START,M_MC_CS1_START)
+
+#define S_MC_CS2_START              32
+#define M_MC_CS2_START              _SB_MAKEMASK(16,S_MC_CS2_START)
+#define V_MC_CS2_START(x)           _SB_MAKEVALUE(x,S_MC_CS2_START)
+#define G_MC_CS2_START(x)           _SB_GETVALUE(x,S_MC_CS2_START,M_MC_CS2_START)
+
+#define S_MC_CS3_START              48
+#define M_MC_CS3_START              _SB_MAKEMASK(16,S_MC_CS3_START)
+#define V_MC_CS3_START(x)           _SB_MAKEVALUE(x,S_MC_CS3_START)
+#define G_MC_CS3_START(x)           _SB_GETVALUE(x,S_MC_CS3_START,M_MC_CS3_START)
+
+/*
+ * Chip Select End Address Register (Table 6-18)
+ */
+
+#define S_MC_CS0_END                0
+#define M_MC_CS0_END                _SB_MAKEMASK(16,S_MC_CS0_END)
+#define V_MC_CS0_END(x)             _SB_MAKEVALUE(x,S_MC_CS0_END)
+#define G_MC_CS0_END(x)             _SB_GETVALUE(x,S_MC_CS0_END,M_MC_CS0_END)
+
+#define S_MC_CS1_END                16
+#define M_MC_CS1_END                _SB_MAKEMASK(16,S_MC_CS1_END)
+#define V_MC_CS1_END(x)             _SB_MAKEVALUE(x,S_MC_CS1_END)
+#define G_MC_CS1_END(x)             _SB_GETVALUE(x,S_MC_CS1_END,M_MC_CS1_END)
+
+#define S_MC_CS2_END                32
+#define M_MC_CS2_END                _SB_MAKEMASK(16,S_MC_CS2_END)
+#define V_MC_CS2_END(x)             _SB_MAKEVALUE(x,S_MC_CS2_END)
+#define G_MC_CS2_END(x)             _SB_GETVALUE(x,S_MC_CS2_END,M_MC_CS2_END)
+
+#define S_MC_CS3_END                48
+#define M_MC_CS3_END                _SB_MAKEMASK(16,S_MC_CS3_END)
+#define V_MC_CS3_END(x)             _SB_MAKEVALUE(x,S_MC_CS3_END)
+#define G_MC_CS3_END(x)             _SB_GETVALUE(x,S_MC_CS3_END,M_MC_CS3_END)
+
+/*
+ * Chip Select Interleave Register (Table 6-19)
+ */
+
+#define S_MC_INTLV_RESERVED         0
+#define M_MC_INTLV_RESERVED         _SB_MAKEMASK(5,S_MC_INTLV_RESERVED)
+
+#define S_MC_INTERLEAVE             7
+#define M_MC_INTERLEAVE             _SB_MAKEMASK(18,S_MC_INTERLEAVE)
+#define V_MC_INTERLEAVE(x)          _SB_MAKEVALUE(x,S_MC_INTERLEAVE)
+
+#define S_MC_INTLV_MBZ              25
+#define M_MC_INTLV_MBZ              _SB_MAKEMASK(39,S_MC_INTLV_MBZ)
+
+/*
+ * Row Address Bits Register (Table 6-20)
+ */
+
+#define S_MC_RAS_RESERVED           0
+#define M_MC_RAS_RESERVED           _SB_MAKEMASK(5,S_MC_RAS_RESERVED)
+
+#define S_MC_RAS_SELECT             12
+#define M_MC_RAS_SELECT             _SB_MAKEMASK(25,S_MC_RAS_SELECT)
+#define V_MC_RAS_SELECT(x)          _SB_MAKEVALUE(x,S_MC_RAS_SELECT)
+
+#define S_MC_RAS_MBZ                37
+#define M_MC_RAS_MBZ                _SB_MAKEMASK(27,S_MC_RAS_MBZ)
+
+
+/*
+ * Column Address Bits Register (Table 6-21)
+ */
+
+#define S_MC_CAS_RESERVED           0
+#define M_MC_CAS_RESERVED           _SB_MAKEMASK(5,S_MC_CAS_RESERVED)
+
+#define S_MC_CAS_SELECT             5
+#define M_MC_CAS_SELECT             _SB_MAKEMASK(18,S_MC_CAS_SELECT)
+#define V_MC_CAS_SELECT(x)          _SB_MAKEVALUE(x,S_MC_CAS_SELECT)
+
+#define S_MC_CAS_MBZ                23
+#define M_MC_CAS_MBZ                _SB_MAKEMASK(41,S_MC_CAS_MBZ)
+
+
+/*
+ * Bank Address Address Bits Register (Table 6-22)
+ */
+
+#define S_MC_BA_RESERVED            0
+#define M_MC_BA_RESERVED            _SB_MAKEMASK(5,S_MC_BA_RESERVED)
+
+#define S_MC_BA_SELECT              5
+#define M_MC_BA_SELECT              _SB_MAKEMASK(20,S_MC_BA_SELECT)
+#define V_MC_BA_SELECT(x)           _SB_MAKEVALUE(x,S_MC_BA_SELECT)
+
+#define S_MC_BA_MBZ                 25
+#define M_MC_BA_MBZ                 _SB_MAKEMASK(39,S_MC_BA_MBZ)
+
+/*
+ * Chip Select Attribute Register (Table 6-23)
+ */
+
+#define K_MC_CS_ATTR_CLOSED         0
+#define K_MC_CS_ATTR_CASCHECK       1
+#define K_MC_CS_ATTR_HINT           2
+#define K_MC_CS_ATTR_OPEN           3
+
+#define S_MC_CS0_PAGE               0
+#define M_MC_CS0_PAGE               _SB_MAKEMASK(2,S_MC_CS0_PAGE)
+#define V_MC_CS0_PAGE(x)            _SB_MAKEVALUE(x,S_MC_CS0_PAGE)
+#define G_MC_CS0_PAGE(x)            _SB_GETVALUE(x,S_MC_CS0_PAGE,M_MC_CS0_PAGE)
+
+#define S_MC_CS1_PAGE               16
+#define M_MC_CS1_PAGE               _SB_MAKEMASK(2,S_MC_CS1_PAGE)
+#define V_MC_CS1_PAGE(x)            _SB_MAKEVALUE(x,S_MC_CS1_PAGE)
+#define G_MC_CS1_PAGE(x)            _SB_GETVALUE(x,S_MC_CS1_PAGE,M_MC_CS1_PAGE)
+
+#define S_MC_CS2_PAGE               32
+#define M_MC_CS2_PAGE               _SB_MAKEMASK(2,S_MC_CS2_PAGE)
+#define V_MC_CS2_PAGE(x)            _SB_MAKEVALUE(x,S_MC_CS2_PAGE)
+#define G_MC_CS2_PAGE(x)            _SB_GETVALUE(x,S_MC_CS2_PAGE,M_MC_CS2_PAGE)
+
+#define S_MC_CS3_PAGE               48
+#define M_MC_CS3_PAGE               _SB_MAKEMASK(2,S_MC_CS3_PAGE)
+#define V_MC_CS3_PAGE(x)            _SB_MAKEVALUE(x,S_MC_CS3_PAGE)
+#define G_MC_CS3_PAGE(x)            _SB_GETVALUE(x,S_MC_CS3_PAGE,M_MC_CS3_PAGE)
+
+/*
+ * ECC Test ECC Register (Table 6-25)
+ */
+
+#define S_MC_ECC_INVERT             0
+#define M_MC_ECC_INVERT             _SB_MAKEMASK(8,S_MC_ECC_INVERT)
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_pci.h linux/include/asm-mips/sibyte/sb1250_pci.h
--- linux.orig/include/asm-mips/sibyte/sb1250_pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_pci.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,250 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  PCI constants				File: sb1250_pci.h
+    *  
+    *  This module contains constants and macros to describe 
+    *  the PCI interface on the SB1250.  
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_PCI_H
+#define _SB1250_PCI_H
+
+#include "sb1250_defs.h"
+
+#define K_PCI_VENDOR_SIBYTE	0x166D
+#define K_PCI_DEVICE_SB1250	0x0001
+
+/*
+ * PCI Interface Type 0 configuration header
+ */
+
+#define R_PCI_TYPE0_DEVICEID	0x0000
+#define R_PCI_TYPE0_CMDSTATUS	0x0004
+#define R_PCI_TYPE0_CLASSREV	0x0008
+#define R_PCI_TYPE0_DEVHDR	0x000C
+#define R_PCI_TYPE0_BAR0	0x0010	/* translated via mapping table */
+#define R_PCI_TYPE0_BAR1	0x0014	/* reserved */
+#define R_PCI_TYPE0_BAR2	0x0018	/* mbox 0 */
+#define R_PCI_TYPE0_BAR3	0x001C	/* mbox 1 */
+#define R_PCI_TYPE0_BAR4	0x0020	/* low memory */
+#define R_PCI_TYPE0_BAR5	0x0024	/* high memory */
+#define R_PCI_TYPE0_CARDBUSCIS	0x0028
+#define R_PCI_TYPE0_SUBSYSID	0x002C
+#define R_PCI_TYPE0_ROMBASE	0x0030
+#define R_PCI_TYPE0_CAPPTR	0x0034	/* not used */
+#define R_PCI_TYPE0_RESERVED1	0x0038
+#define R_PCI_TYPE0_INTGRANT	0x003C	/* interrupt pin and grant latency */
+#define R_PCI_TYPE0_TIMEOUT	0x0040	/* FControl, Timeout */
+#define R_PCI_TYPE0_FCONTROL	0x0040	/* FControl, Timeout */
+#define R_PCI_TYPE0_MAPBASE	0x0044	/* 0x44 through 0x80 - map table */
+#define PCI_TYPE0_MAPENTRIES	32	/* 64 bytes, 32 entries */
+#define R_PCI_TYPE0_ERRORADDR	0x0084
+#define R_PCI_TYPE0_ADDSTATUS	0x0088
+#define R_PCI_TYPE0_SUBSYSSET	0x008C	/* only accessible from ZBBus */
+
+/*
+ * PCI Device ID register
+ */
+
+#define S_PCI_DEVICEID_VENDOR		0
+#define M_PCI_DEVICEID_VENDOR		_SB_MAKEMASK_32(16,S_PCI_DEVICEID_VENDOR)
+#define V_PCI_DEVICEID_VENDOR(x)	_SB_MAKEVALUE_32(x,S_PCI_DEVICEID_VENDOR)
+#define G_PCI_DEVICEID_VENDOR(x)	_SB_GETVALUE_32(x,S_PCI_DEVICEID_VENDOR,M_PCI_DEVICEID_VENDOR)
+
+#define S_PCI_DEVICEID_DEVICEID		16
+#define M_PCI_DEVICEID_DEVICEID		_SB_MAKEMASK_32(16,S_PCI_DEVICEID_DEVICEID)
+#define V_PCI_DEVICEID_DEVICEID(x)	_SB_MAKEVALUE_32(x,S_PCI_DEVICEID_DEVICEID)
+#define G_PCI_DEVICEID_DEVICEID(x)	_SB_GETVALUE_32(x,S_PCI_DEVICEID_DEVICEID,M_PCI_DEVICEID_DEVICEID)
+
+
+/*
+ * PCI Command Register (Table 8-4)
+ */
+
+#define M_PCI_CMD_IOSPACE_EN		_SB_MAKEMASK1_32(0)
+#define M_PCI_CMD_MEMSPACE_EN		_SB_MAKEMASK1_32(1)
+#define M_PCI_CMD_MASTER_EN		_SB_MAKEMASK1_32(2)
+#define M_PCI_CMD_SPECCYC_EN		_SB_MAKEMASK1_32(3)
+#define M_PCI_CMD_MEMWRINV_EN		_SB_MAKEMASK1_32(4)
+#define M_PCI_CMD_VGAPALSNP_EN		_SB_MAKEMASK1_32(5)
+#define M_PCI_CMD_PARERRRESP		_SB_MAKEMASK1_32(6)
+#define M_PCI_CMD_STEPCTRL		_SB_MAKEMASK1_32(7)
+#define M_PCI_CMD_SERR_EN		_SB_MAKEMASK1_32(8)
+#define M_PCI_CMD_FASTB2B_EN		_SB_MAKEMASK1_32(9)
+
+/*
+ * PCI class and revision registers
+ */
+
+#define S_PCI_CLASSREV_REV		0
+#define M_PCI_CLASSREV_REV		_SB_MAKEMASK_32(8,S_PCI_CLASSREV_REV)
+#define V_PCI_CLASSREV_REV(x)		_SB_MAKEVALUE_32(x,S_PCI_CLASSREV_REV)
+#define G_PCI_CLASSREV_REV(x)		_SB_GETVALUE_32(x,S_PCI_CLASSREV_REV,M_PCI_CLASSREV_REV)
+
+#define S_PCI_CLASSREV_CLASS		8
+#define M_PCI_CLASSREV_CLASS		_SB_MAKEMASK_32(24,S_PCI_CLASSREV_CLASS)
+#define V_PCI_CLASSREV_CLASS(x)		_SB_MAKEVALUE_32(x,S_PCI_CLASSREV_CLASS)
+#define G_PCI_CLASSREV_CLASS(x)		_SB_GETVALUE_32(x,S_PCI_CLASSREV_CLASS,M_PCI_CLASSREV_CLASS)
+
+#define K_PCI_REV			0x01
+#define K_PCI_CLASS			0x060000
+
+/*
+ * Device Header (offset 0x0C)
+ */
+
+#define S_PCI_DEVHDR_CLINESZ		0
+#define M_PCI_DEVHDR_CLINESZ		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_CLINESZ)
+#define V_PCI_DEVHDR_CLINESZ(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_CLINESZ)
+#define G_PCI_DEVHDR_CLINESZ(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_CLINESZ,M_PCI_DEVHDR_CLINESZ)
+
+#define S_PCI_DEVHDR_LATTMR		8
+#define M_PCI_DEVHDR_LATTMR		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_LATTMR)
+#define V_PCI_DEVHDR_LATTMR(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_LATTMR)
+#define G_PCI_DEVHDR_LATTMR(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_LATTMR,M_PCI_DEVHDR_LATTMR)
+
+#define S_PCI_DEVHDR_HDRTYPE		16
+#define M_PCI_DEVHDR_HDRTYPE		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_HDRTYPE)
+#define V_PCI_DEVHDR_HDRTYPE(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_HDRTYPE)
+#define G_PCI_DEVHDR_HDRTYPE(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_HDRTYPE,M_PCI_DEVHDR_HDRTYPE)
+
+#define K_PCI_DEVHDR_HDRTYPE_TYPE0	0
+
+#define S_PCI_DEVHDR_BIST		24
+#define M_PCI_DEVHDR_BIST		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_BIST)
+#define V_PCI_DEVHDR_BIST(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_BIST)
+#define G_PCI_DEVHDR_BIST(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_BIST,M_PCI_DEVHDR_BIST)
+
+/*
+ * PCI Status Register (Table 8-5).  Note that these constants
+ * assume you've read the command and status register 
+ * together (32-bit read at offset 0x04)
+ */
+
+#define M_PCI_STATUS_CAPLIST		_SB_MAKEMASK1_32(20)
+#define M_PCI_STATUS_66MHZCAP		_SB_MAKEMASK1_32(21)
+#define M_PCI_STATUS_RESERVED2		_SB_MAKEMASK1_32(22)
+#define M_PCI_STATUS_FASTB2BCAP		_SB_MAKEMASK1_32(23)
+#define M_PCI_STATUS_MSTRDPARERR	_SB_MAKEMASK1_32(24)
+
+#define S_PCI_STATUS_DEVSELTIMING	25
+#define M_PCI_STATUS_DEVSELTIMING	_SB_MAKEMASK_32(2,S_PCI_STATUS_DEVSELTIMING)
+#define V_PCI_STATUS_DEVSELTIMING(x)	_SB_MAKEVALUE_32(x,S_PCI_STATUS_DEVSELTIMING)
+#define G_PCI_STATUS_DEVSELTIMING(x)	_SB_GETVALUE_32(x,S_PCI_STATUS_DEVSELTIMING,M_PCI_STATUS_DEVSELTIMING)
+
+#define M_PCI_STATUS_SIGDTGTABORT	_SB_MAKEMASK1_32(27)
+#define M_PCI_STATUS_RCVDTGTABORT	_SB_MAKEMASK1_32(28)
+#define M_PCI_STATUS_RCVDMSTRABORT	_SB_MAKEMASK1_32(29)
+#define M_PCI_STATUS_SIGDSERR		_SB_MAKEMASK1_32(30)
+#define M_PCI_STATUS_DETPARERR		_SB_MAKEMASK1_32(31)
+
+/*
+ * Device Header Register (Table 8-6, Table 8-7)
+ */
+
+#define S_PCI_DEVHDR_CLINESZ		0
+#define M_PCI_DEVHDR_CLINESZ		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_CLINESZ)
+#define V_PCI_DEVHDR_CLINESZ(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_CLINESZ)
+#define G_PCI_DEVHDR_CLINESZ(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_CLINESZ,M_PCI_DEVHDR_CLINESZ)
+
+#define S_PCI_DEVHDR_LATTIME		8
+#define M_PCI_DEVHDR_LATTIME		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_LATTIME)
+#define V_PCI_DEVHDR_LATTIME(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_LATTIME)
+#define G_PCI_DEVHDR_LATTIME(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_LATTIME,M_PCI_DEVHDR_LATTIME)
+
+#define S_PCI_DEVHDR_HDRTYPE		16
+#define M_PCI_DEVHDR_HDRTYPE		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_HDRTYPE)
+#define V_PCI_DEVHDR_HDRTYPE(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_HDRTYPE)
+#define G_PCI_DEVHDR_HDRTYPE(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_HDRTYPE,M_PCI_DEVHDR_HDRTYPE)
+
+#define S_PCI_DEVHDR_BIST		24
+#define M_PCI_DEVHDR_BIST		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_BIST)
+#define V_PCI_DEVHDR_BIST(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_BIST)
+#define G_PCI_DEVHDR_BIST(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_BIST,M_PCI_DEVHDR_BIST)
+
+/*
+ * Timeout and feature control Register (Table 8-8) (Table 8-9)
+ * Note that these constants assume you've read the timeout/fcontrol register
+ * together (32-bit read at offset 0x40)
+ */
+
+#define S_PCI_TIMEOUT_TRDY		0
+#define M_PCI_TIMEOUT_TRDY		_SB_MAKEMASK_32(8,S_PCI_TIMEOUT_TRDY)
+#define V_PCI_TIMEOUT_TRDY(x)		_SB_MAKEVALUE_32(x,S_PCI_TIMEOUT_TRDY)
+#define G_PCI_TIMEOUT_TRDY(x)		_SB_GETVALUE_32(x,S_PCI_TIMEOUT_TRDY,M_PCI_TIMEOUT_TRDY)
+
+#define S_PCI_TIMEOUT_RETRY		8
+#define M_PCI_TIMEOUT_RETRY		_SB_MAKEMASK_32(8,S_PCI_TIMEOUT_RETRY)
+#define V_PCI_TIMEOUT_RETRY(x)		_SB_MAKEVALUE_32(x,S_PCI_TIMEOUT_RETRY)
+#define G_PCI_TIMEOUT_RETRY(x)		_SB_GETVALUE_32(x,S_PCI_TIMEOUT_RETRY,M_PCI_TIMEOUT_RETRY)
+
+#define M_PCI_FCONTROL_BAR4_EN		_SB_MAKEMASK1_32(16)
+#define M_PCI_FCONTROL_BAR5_EN		_SB_MAKEMASK1_32(17)
+#define M_PCI_FCONTROL_PTP_EN		_SB_MAKEMASK1_32(18)
+#define M_PCI_FCONTROL_ADAPT_RETRY_EN	_SB_MAKEMASK1_32(19)
+
+#define S_PCI_FCONTROL_MIN_TAR_RETRY	20
+#define M_PCI_FCONTROL_MIN_TAR_RETRY	_SB_MAKEMASK_32(3,S_PCI_FCONTROL_MIN_TAR_RETRY)
+#define V_PCI_FCONTROL_MIN_TAR_RETRY(x)	_SB_MAKEVALUE_32(x,S_PCI_FCONTROL_MIN_TAR_RETRY)
+#define G_PCI_FCONTROL_MIN_TAR_RETRY(x)	_SB_GETVALUE_32(x,S_PCI_FCONTROL_MIN_TAR_RETRY,M_PCI_FCONTROL_MIN_TAR_RETRY)
+
+#define S_PCI_FCONTROL_NOM_TAR_RETRY	23
+#define M_PCI_FCONTROL_NOM_TAR_RETRY	_SB_MAKEMASK_32(4,S_PCI_FCONTROL_NOM_TAR_RETRY)
+#define V_PCI_FCONTROL_NOM_TAR_RETRY(x)	_SB_MAKEVALUE_32(x,S_PCI_FCONTROL_NOM_TAR_RETRY)
+#define G_PCI_FCONTROL_NOM_TAR_RETRY(x)	_SB_GETVALUE_32(x,S_PCI_FCONTROL_NOM_TAR_RETRY,M_PCI_FCONTROL_NOM_TAR_RETRY)
+
+#define S_PCI_FCONTROL_MAX_TAR_RETRY	27
+#define M_PCI_FCONTROL_MAX_TAR_RETRY	_SB_MAKEMASK_32(5,S_PCI_FCONTROL_MAX_TAR_RETRY)
+#define V_PCI_FCONTROL_MAX_TAR_RETRY(x)	_SB_MAKEVALUE_32(x,S_PCI_FCONTROL_MAX_TAR_RETRY)
+#define G_PCI_FCONTROL_MAX_TAR_RETRY(x)	_SB_GETVALUE_32(x,S_PCI_FCONTROL_MAX_TAR_RETRY,M_PCI_FCONTROL_MAX_TAR_RETRY)
+
+/*
+ * BAR0 Map Table Entry (Offsets 0x40-0x80) (Table 8-10)
+ */
+
+#define M_PCI_BAR0MAP_ENABLE		_SB_MAKEMASK1_32(0)
+#define M_PCI_BAR0MAP_SENDLDT		_SB_MAKEMASK1_32(1)
+#define S_PCI_BAR0MAP_ADDR		12
+#define M_PCI_BAR0MAP_ADDR		_SB_MAKEMASK_32(20,S_PCI_BAR0MAP_ADDR)
+
+/*
+ * Additional Status Register (Table 8-11)
+ */
+
+#define M_PCI_ASTATUS_HOTPLUG_EN	_SB_MAKEMASK1_32(0)
+#define M_PCI_ASTATUS_SERR_DET		_SB_MAKEMASK1_32(1)
+#define M_PCI_ASTATUS_TRDYERR		_SB_MAKEMASK1_32(2)
+#define M_PCI_ASTATUS_RETRTYERR		_SB_MAKEMASK1_32(3)
+#define M_PCI_ASTATUS_TRDYINTMASK	_SB_MAKEMASK1_32(4)
+#define M_PCI_ASTATUS_RETRYINTMASK	_SB_MAKEMASK1_32(5)
+#define M_PCI_ASTATUS_SIGNALINTA	_SB_MAKEMASK1_32(6)
+
+#endif
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_prof.h linux/include/asm-mips/sibyte/sb1250_prof.h
--- linux.orig/include/asm-mips/sibyte/sb1250_prof.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_prof.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+/*
+ *
+ * Definitions for the sb1250_prof pseudo device.
+ *
+ */
+//#include <sys/param.h>
+//#include <sys/device.h>
+
+#ifndef SB1250_PROF_H
+#define SB1250_PROF_H 1
+
+#define MAXCPUS 1
+#define NEWPIDSIZE 160
+/* The two definitions below must match those in pgather.c */
+#define MAX_COUNTERS 4
+#define MAX_SLOTS 8
+
+#define STATS
+
+typedef struct {
+  u_int8_t  event;
+  u_int8_t  hwcode;     /* pcarch-specific bits identifying desired event */
+  u_int64_t period;     /* 40-bit sampling period during slot */
+} sbprof_mux_counter_t;
+
+typedef struct {
+  sbprof_mux_counter_t
+                counter[MAX_COUNTERS];	/* data for setting up counter */
+  u_int8_t	n;			/* number of counters to use in slot */
+} sbprof_mux_slot_t;
+
+typedef struct {
+  sbprof_mux_slot_t slots[MAX_SLOTS];
+} sbprof_mux_slots;
+
+typedef struct {
+  u_int64_t total;	/* total number of interrupts */
+  u_int64_t dropped;	/* total interrupts when buffers were full */
+  u_int64_t value;	/* initial counter value when slot next entered */
+  u_int32_t start_period_low;	/* counter val for starting a period */
+  u_int8_t  start_period_high;
+  u_int8_t  event;      /* pcarch-specific event_t */
+  u_int8_t  hwcode;	/* pcarch-specific code for event */
+  u_int8_t  inuse;	/* Is counter X slot actually used? */
+} event_counter_state_t;
+
+typedef struct {
+  u_int32_t total;	 /* total for current run of slot */
+  u_int32_t dropped;	 /* dropped for current run of slot */
+  u_int64_t start_period;/* counter value to start a full period */
+} active_counter_state_t;
+
+struct _cpudata1 {
+  /******* page-aligned boundary *********************************************/
+  u_int32_t last_pid;	/* Pid for last sample in buffer (-1 initially) */
+  u_int8_t  curbuf;	/* 2 -> both buffers full at end of last interrupt
+			   1 -> use buffer[1]
+			   0 -> use buffer[0] */
+  u_int8_t  nextbuf;	/* the index of the next buffer to be filled */
+  u_int8_t  nnewpid[2]; /* number of entries set in new_pid[i] */
+  u_int32_t next;       /* index of next free entry in curbuf */
+  int32_t   last_event; /* index of byte just past last event DP_D_EVENTS
+			   message in curbuf that needs the number of events
+			   filled in.  -1 means there is no such message and
+			   that such a message must be entered before
+			   adding event samples.
+			 */
+  /* 16-byte boundary */
+  volatile u_int32_t full[2];
+                        /* full[i] > 0 means buffer[i] needs emptying.
+			   0 to nonzero done by sbprofintr().
+			   nonzero to zero by sbprofioctl().
+			   When nonzero, full[i] is the number of bytes
+			   set in buffer[i].
+			*/
+  u_int32_t threshold;  /* when does the current multiplexing slot expire? */
+  u_int8_t slotid;      /* index into slots[] of current multiplexing slot */
+  u_int8_t nslots;	/* number of slots */
+  u_int8_t needs_scan;
+  u_int8_t pad[1];
+  /******* 32-byte boundary *********************************************/
+  active_counter_state_t cur_slot[MAX_COUNTERS];
+  /******* 32-byte boundary *********************************************/
+  event_counter_state_t event_counter_state[MAX_SLOTS][MAX_COUNTERS];
+  /******* 32-byte boundary *********************************************/
+  u_int32_t overshot[MAX_SLOTS];
+
+  u_int32_t newpid[2][NEWPIDSIZE];  /* new_pid[i][] contains indices of
+				       buffer[i][] where a new_pid message
+				       is encoded and needs to have the
+				       image_id, base addr, and num_inst
+				       fields set by the user-level daemon */
+#ifdef STATS
+  u_int64_t newpidlimit;
+  u_int64_t buflimit;
+#endif
+};
+
+#define SBPROF_BUFSIZE (32*1024 - (sizeof(struct _cpudata1)+1)/2)
+
+typedef struct _cpudata {
+  struct _cpudata1 x;
+  u_int8_t buffer[2][SBPROF_BUFSIZE];
+} cpudata_t;
+
+#define SBPROF_START    _IOW('S', 0x1, sbprof_mux_slots)
+#define SBPROF_STOP     _IO('S', 0x2)
+#define SBPROF_BUFFULL  _IOWR('S', 0x3, int)
+#define SBPROF_BUFEMPTY _IOW('S', 0x4, int)
+
+#if NEWPIDSIZE > 254
+#error "newpidsize too big"
+#endif
+
+#endif /* SB1250_PROF_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_regs.h linux/include/asm-mips/sibyte/sb1250_regs.h
--- linux.orig/include/asm-mips/sibyte/sb1250_regs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_regs.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,744 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Register Definitions                     File: sb1250_regs.h
+    *  
+    *  This module contains the addresses of the on-chip peripherals
+    *  on the SB1250.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_REGS_H
+#define _SB1250_REGS_H
+
+#include "sb1250_defs.h"
+
+
+/*  *********************************************************************
+    *  Some general notes:
+    *  
+    *  For the most part, when there is more than one peripheral
+    *  of the same type on the SOC, the constants below will be
+    *  offsets from the base of each peripheral.  For example,
+    *  the MAC registers are described as offsets from the first
+    *  MAC register, and there will be a MAC_REGISTER() macro
+    *  to calculate the base address of a given MAC.  
+    *  
+    *  The information in this file is based on the SB1250 SOC
+    *  manual version 0.2, July 2000.
+    ********************************************************************* */
+
+
+/*  ********************************************************************* 
+    * Memory Controller Registers
+    ********************************************************************* */
+
+#define A_MC_BASE_0                 0x0010051000
+#define A_MC_BASE_1                 0x0010052000
+#define MC_REGISTER_SPACING         0x1000
+
+#define A_MC_BASE(ctlid)            ((ctlid)*MC_REGISTER_SPACING+A_MC_BASE_0)
+#define A_MC_REGISTER(ctlid,reg)    (A_MC_BASE(ctlid)+(reg))
+
+#define R_MC_CONFIG                 0x0000000100
+#define R_MC_DRAMCMD                0x0000000120
+#define R_MC_DRAMMODE               0x0000000140
+#define R_MC_TIMING1                0x0000000160
+#define R_MC_TIMING2                0x0000000180
+#define R_MC_CS_START               0x00000001A0
+#define R_MC_CS_END                 0x00000001C0
+#define R_MC_CS_INTERLEAVE          0x00000001E0
+#define S_MC_CS_STARTEND            16
+
+#define R_MC_CSX_BASE               0x0000000200
+#define R_MC_CSX_ROW                0x0000000000	/* relative to CSX_BASE, above */
+#define R_MC_CSX_COL                0x0000000020	/* relative to CSX_BASE, above */
+#define R_MC_CSX_BA                 0x0000000040	/* relative to CSX_BASE, above */
+#define MC_CSX_SPACING              0x0000000060	/* relative to CSX_BASE, above */
+
+#define R_MC_CS0_ROW                0x0000000200
+#define R_MC_CS0_COL                0x0000000220
+#define R_MC_CS0_BA                 0x0000000240
+#define R_MC_CS1_ROW                0x0000000260
+#define R_MC_CS1_COL                0x0000000280
+#define R_MC_CS1_BA                 0x00000002A0
+#define R_MC_CS2_ROW                0x00000002C0
+#define R_MC_CS2_COL                0x00000002E0
+#define R_MC_CS2_BA                 0x0000000300
+#define R_MC_CS3_ROW                0x0000000320
+#define R_MC_CS3_COL                0x0000000340
+#define R_MC_CS3_BA                 0x0000000360
+#define R_MC_CS_ATTR                0x0000000380
+#define R_MC_TEST_DATA              0x0000000400
+#define R_MC_TEST_ECC               0x0000000420
+#define R_MC_MCLK_CFG               0x0000000500
+
+/*  ********************************************************************* 
+    * L2 Cache Control Registers
+    ********************************************************************* */
+
+#define A_L2_READ_ADDRESS           0x0010040018
+#define A_L2_EEC_ADDRESS            0x0010040038
+#define A_L2_WAY_DISABLE            0x0010041000
+#define A_L2_MAKEDISABLE(x)         (A_L2_WAY_DISABLE | (((~(x))&0x0F) << 8))
+#define A_L2_MGMT_TAG_BASE          0x00D0000000
+
+/*  ********************************************************************* 
+    * PCI Interface Registers
+    ********************************************************************* */
+
+#define A_PCI_TYPE00_HEADER         0x00DE000000
+#define A_PCI_TYPE01_HEADER         0x00DE000800
+
+
+/*  ********************************************************************* 
+    * Ethernet DMA and MACs
+    ********************************************************************* */
+
+#define A_MAC_BASE_0                0x0010064000
+#define A_MAC_BASE_1                0x0010065000
+#define A_MAC_BASE_2                0x0010066000
+
+#define MAC_SPACING                 0x1000
+#define MAC_DMA_TXRX_SPACING        0x0400
+#define MAC_DMA_CHANNEL_SPACING     0x0100
+#define DMA_RX                      0
+#define DMA_TX                      1
+#define MAC_NUM_DMACHAN		    2		    /* channels per direction */
+
+#define MAC_NUM_PORTS               3
+
+#define A_MAC_CHANNEL_BASE(macnum)                  \
+            (A_MAC_BASE_0 +                         \
+             MAC_SPACING*(macnum))
+
+#define A_MAC_REGISTER(macnum,reg)                  \
+            (A_MAC_BASE_0 +                         \
+             MAC_SPACING*(macnum) + (reg))
+
+
+#define R_MAC_DMA_CHANNELS		0x800 /* Relative to A_MAC_CHANNEL_BASE */
+
+#define A_MAC_DMA_CHANNEL_BASE(macnum,txrx,chan)    \
+             ((A_MAC_CHANNEL_BASE(macnum)) +        \
+             R_MAC_DMA_CHANNELS +                   \
+             (MAC_DMA_TXRX_SPACING*(txrx)) +        \
+             (MAC_DMA_CHANNEL_SPACING*(chan)))
+
+#define R_MAC_DMA_CHANNEL_BASE(txrx,chan)    \
+             (R_MAC_DMA_CHANNELS +                   \
+             (MAC_DMA_TXRX_SPACING*(txrx)) +        \
+             (MAC_DMA_CHANNEL_SPACING*(chan)))
+
+#define A_MAC_DMA_REGISTER(macnum,txrx,chan,reg)           \
+            (A_MAC_DMA_CHANNEL_BASE(macnum,txrx,chan) +    \
+            (reg))
+
+#define R_MAC_DMA_REGISTER(txrx,chan,reg)           \
+            (R_MAC_DMA_CHANNEL_BASE(txrx,chan) +    \
+            (reg))
+
+/* 
+ * DMA channel registers, relative to A_MAC_DMA_CHANNEL_BASE
+ */
+
+#define R_MAC_DMA_CONFIG0               0x00000000
+#define R_MAC_DMA_CONFIG1               0x00000008
+#define R_MAC_DMA_DSCR_BASE             0x00000010
+#define R_MAC_DMA_DSCR_CNT              0x00000018
+#define R_MAC_DMA_CUR_DSCRA             0x00000020
+#define R_MAC_DMA_CUR_DSCRB             0x00000028
+#define R_MAC_DMA_CUR_DSCRADDR          0x00000030
+
+/*
+ * RMON Counters
+ */
+
+#define R_MAC_RMON_TX_BYTES             0x00000000
+#define R_MAC_RMON_COLLISIONS           0x00000008
+#define R_MAC_RMON_LATE_COL             0x00000010
+#define R_MAC_RMON_EX_COL               0x00000018
+#define R_MAC_RMON_FCS_ERROR            0x00000020
+#define R_MAC_RMON_TX_ABORT             0x00000028
+/* Counter #6 (0x30) now reserved */
+#define R_MAC_RMON_TX_BAD               0x00000038
+#define R_MAC_RMON_TX_GOOD              0x00000040
+#define R_MAC_RMON_TX_RUNT              0x00000048
+#define R_MAC_RMON_TX_OVERSIZE          0x00000050
+#define R_MAC_RMON_RX_BYTES             0x00000080
+#define R_MAC_RMON_RX_MCAST             0x00000088
+#define R_MAC_RMON_RX_BCAST             0x00000090
+#define R_MAC_RMON_RX_BAD               0x00000098
+#define R_MAC_RMON_RX_GOOD              0x000000A0
+#define R_MAC_RMON_RX_RUNT              0x000000A8
+#define R_MAC_RMON_RX_OVERSIZE          0x000000B0
+#define R_MAC_RMON_RX_FCS_ERROR         0x000000B8
+#define R_MAC_RMON_RX_LENGTH_ERROR      0x000000C0
+#define R_MAC_RMON_RX_CODE_ERROR        0x000000C8
+#define R_MAC_RMON_RX_ALIGN_ERROR       0x000000D0
+
+/* Updated to spec 0.2 */
+#define R_MAC_CFG                       0x00000100
+#define R_MAC_THRSH_CFG                 0x00000108
+#define R_MAC_VLANTAG                   0x00000110
+#define R_MAC_FRAMECFG                  0x00000118
+#define R_MAC_EOPCNT                    0x00000120
+#define R_MAC_FIFO_PTRS                 0x00000130
+#define R_MAC_ADFILTER_CFG              0x00000200
+#define R_MAC_ETHERNET_ADDR             0x00000208
+#define R_MAC_PKT_TYPE                  0x00000210
+#define R_MAC_HASH_BASE                 0x00000240
+#define R_MAC_ADDR_BASE                 0x00000280
+#define R_MAC_CHLO0_BASE                0x00000300
+#define R_MAC_CHUP0_BASE                0x00000320
+#define R_MAC_ENABLE                    0x00000400
+#define R_MAC_STATUS                    0x00000408
+#define R_MAC_INT_MASK                  0x00000410
+#define R_MAC_TXD_CTL                   0x00000420
+#define R_MAC_MDIO                      0x00000428
+#define R_MAC_DEBUG_STATUS              0x00000448
+
+#define MAC_HASH_COUNT			8
+#define MAC_ADDR_COUNT			8
+#define MAC_CHMAP_COUNT			4
+
+
+/*  ********************************************************************* 
+    * DUART Registers
+    ********************************************************************* */
+
+
+#define R_DUART_NUM_PORTS           2
+
+#define A_DUART                     0x0010060000
+
+#define A_DUART_REG(r)
+
+#define DUART_CHANREG_SPACING       0x100
+#define A_DUART_CHANREG(chan,reg)   (A_DUART + DUART_CHANREG_SPACING*(chan) + (reg))
+#define R_DUART_CHANREG(chan,reg)   (DUART_CHANREG_SPACING*(chan) + (reg))
+
+#define R_DUART_MODE_REG_1	    0x100
+#define R_DUART_MODE_REG_2	    0x110
+#define R_DUART_STATUS              0x120
+#define R_DUART_CLK_SEL             0x130
+#define R_DUART_CMD                 0x150
+#define R_DUART_RX_HOLD             0x160
+#define R_DUART_TX_HOLD             0x170
+
+/*
+ * The IMR and ISR can't be addressed with A_DUART_CHANREG,
+ * so use this macro instead.
+ */
+
+#define R_DUART_AUX_CTRL            0x310
+#define R_DUART_ISR_A               0x320
+#define R_DUART_IMR_A               0x330
+#define R_DUART_ISR_B               0x340
+#define R_DUART_IMR_B               0x350
+#define R_DUART_OUT_PORT            0x360
+#define R_DUART_OPCR                0x370
+
+#define R_DUART_SET_OPR		    0x3B0
+#define R_DUART_CLEAR_OPR	    0x3C0
+
+#define DUART_IMRISR_SPACING        0x20
+
+#define R_DUART_IMRREG(chan)	    (R_DUART_IMR_A + (chan)*DUART_IMRISR_SPACING)
+#define R_DUART_ISRREG(chan)	    (R_DUART_ISR_A + (chan)*DUART_IMRISR_SPACING)
+
+#define A_DUART_IMRREG(chan)	    (A_DUART + R_DUART_IMRREG(chan))
+#define A_DUART_ISRREG(chan)	    (A_DUART + R_DUART_ISRREG(chan))
+
+/*
+ * These constants are the absolute addresses.
+ */
+
+#define A_DUART_MODE_REG_1_A        0x0010060100
+#define A_DUART_MODE_REG_2_A        0x0010060110
+#define A_DUART_STATUS_A            0x0010060120
+#define A_DUART_CLK_SEL_A           0x0010060130
+#define A_DUART_CMD_A               0x0010060150
+#define A_DUART_RX_HOLD_A           0x0010060160
+#define A_DUART_TX_HOLD_A           0x0010060170
+
+#define A_DUART_MODE_REG_1_B        0x0010060200
+#define A_DUART_MODE_REG_2_B        0x0010060210
+#define A_DUART_STATUS_B            0x0010060220
+#define A_DUART_CLK_SEL_B           0x0010060230
+#define A_DUART_CMD_B               0x0010060250
+#define A_DUART_RX_HOLD_B           0x0010060260
+#define A_DUART_TX_HOLD_B           0x0010060270
+
+#define A_DUART_INPORT_CHNG         0x0010060300
+#define A_DUART_AUX_CTRL            0x0010060310
+#define A_DUART_ISR_A               0x0010060320
+#define A_DUART_IMR_A               0x0010060330
+#define A_DUART_ISR_B               0x0010060340
+#define A_DUART_IMR_B               0x0010060350
+#define A_DUART_OUT_PORT            0x0010060360
+#define A_DUART_OPCR                0x0010060370
+#define A_DUART_IN_PORT             0x0010060380
+#define A_DUART_ISR                 0x0010060390
+#define A_DUART_IMR                 0x00100603A0
+#define A_DUART_SET_OPR             0x00100603B0
+#define A_DUART_CLEAR_OPR           0x00100603C0
+#define A_DUART_INPORT_CHNG_A       0x00100603D0
+#define A_DUART_INPORT_CHNG_B       0x00100603E0
+
+/*  ********************************************************************* 
+    * Synchronous Serial Registers
+    ********************************************************************* */
+
+
+#define A_SER_BASE_0                0x0010060400
+#define A_SER_BASE_1                0x0010060800
+#define SER_SPACING                 0x400
+
+#define SER_DMA_TXRX_SPACING        0x80
+
+#define SER_NUM_PORTS               2
+
+#define A_SER_CHANNEL_BASE(sernum)                  \
+            (A_SER_BASE_0 +                         \
+             SER_SPACING*(sernum))
+
+#define A_SER_REGISTER(sernum,reg)                  \
+            (A_SER_BASE_0 +                         \
+             SER_SPACING*(sernum) + (reg))
+
+
+#define R_SER_DMA_CHANNELS		0   /* Relative to A_SER_BASE_x */
+
+#define A_SER_DMA_CHANNEL_BASE(sernum,txrx)    \
+             ((A_SER_CHANNEL_BASE(sernum)) +        \
+             R_SER_DMA_CHANNELS +                   \
+             (SER_DMA_TXRX_SPACING*(txrx)))
+
+#define A_SER_DMA_REGISTER(sernum,txrx,reg)           \
+            (A_SER_DMA_CHANNEL_BASE(sernum,txrx) +    \
+            (reg))
+
+
+/* 
+ * DMA channel registers, relative to A_SER_DMA_CHANNEL_BASE
+ */
+
+#define R_SER_DMA_CONFIG0           0x00000000
+#define R_SER_DMA_CONFIG1           0x00000008
+#define R_SER_DMA_DSCR_BASE         0x00000010
+#define R_SER_DMA_DSCR_CNT          0x00000018
+#define R_SER_DMA_CUR_DSCRA         0x00000020
+#define R_SER_DMA_CUR_DSCRB         0x00000028
+#define R_SER_DMA_CUR_DSCRADDR      0x00000030
+
+#define R_SER_DMA_CONFIG0_RX        0x00000000
+#define R_SER_DMA_CONFIG1_RX        0x00000008
+#define R_SER_DMA_DSCR_BASE_RX      0x00000010
+#define R_SER_DMA_DSCR_COUNT_RX     0x00000018
+#define R_SER_DMA_CUR_DSCR_A_RX     0x00000020
+#define R_SER_DMA_CUR_DSCR_B_RX     0x00000028
+#define R_SER_DMA_CUR_DSCR_ADDR_RX  0x00000030
+
+#define R_SER_DMA_CONFIG0_TX        0x00000080
+#define R_SER_DMA_CONFIG1_TX        0x00000088
+#define R_SER_DMA_DSCR_BASE_TX      0x00000090
+#define R_SER_DMA_DSCR_COUNT_TX     0x00000098
+#define R_SER_DMA_CUR_DSCR_A_TX     0x000000A0
+#define R_SER_DMA_CUR_DSCR_B_TX     0x000000A8
+#define R_SER_DMA_CUR_DSCR_ADDR_TX  0x000000B0
+
+#define R_SER_MODE                  0x00000100
+#define R_SER_MINFRM_SZ             0x00000108
+#define R_SER_MAXFRM_SZ             0x00000110
+#define R_SER_ADDR                  0x00000118
+#define R_SER_USR0_ADDR             0x00000120
+#define R_SER_USR1_ADDR             0x00000128
+#define R_SER_USR2_ADDR             0x00000130
+#define R_SER_USR3_ADDR             0x00000138
+#define R_SER_CMD                   0x00000140
+#define R_SER_TX_RD_THRSH           0x00000160
+#define R_SER_TX_WR_THRSH           0x00000168
+#define R_SER_RX_RD_THRSH           0x00000170
+#define R_SER_LINE_MODE		    0x00000178
+#define R_SER_DMA_ENABLE            0x00000180
+#define R_SER_INT_MASK              0x00000190
+#define R_SER_STATUS                0x00000188
+#define R_SER_STATUS_DEBUG          0x000001A8
+#define R_SER_RX_TABLE_BASE         0x00000200
+#define SER_RX_TABLE_COUNT          16
+#define R_SER_TX_TABLE_BASE         0x00000300
+#define SER_TX_TABLE_COUNT          16
+
+/* RMON Counters */
+#define R_SER_RMON_TX_BYTE_LO       0x000001C0
+#define R_SER_RMON_TX_BYTE_HI       0x000001C8
+#define R_SER_RMON_RX_BYTE_LO       0x000001D0
+#define R_SER_RMON_RX_BYTE_HI       0x000001D8
+#define R_SER_RMON_TX_UNDERRUN      0x000001E0
+#define R_SER_RMON_RX_OVERFLOW      0x000001E8
+#define R_SER_RMON_RX_ERRORS        0x000001F0
+#define R_SER_RMON_RX_BADADDR       0x000001F8
+
+/*  ********************************************************************* 
+    * Generic Bus Registers
+    ********************************************************************* */
+
+#define IO_EXT_CFG_COUNT            8
+
+#define A_IO_EXT_BASE		    0x0010061000
+#define A_IO_EXT_REG(r)		    (A_IO_EXT_BASE + (r))
+
+#define A_IO_EXT_CFG_BASE           0x0010061000
+#define A_IO_EXT_MULT_SIZE_BASE     0x0010061100
+#define A_IO_EXT_START_ADDR_BASE    0x0010061200
+#define A_IO_EXT_TIME_CFG0_BASE     0x0010061600
+#define A_IO_EXT_TIME_CFG1_BASE     0x0010061700
+
+#define IO_EXT_REGISTER_SPACING	    8
+#define A_IO_EXT_CS_BASE(cs)	    (A_IO_EXT_CFG_BASE+IO_EXT_REGISTER_SPACING*(cs))
+#define R_IO_EXT_REG(reg,cs)	    ((cs)*IO_EXT_REGISTER_SPACING + (reg))
+
+#define R_IO_EXT_CFG		    0x0000
+#define R_IO_EXT_MULT_SIZE          0x0100
+#define R_IO_EXT_START_ADDR	    0x0200
+#define R_IO_EXT_TIME_CFG0          0x0600
+#define R_IO_EXT_TIME_CFG1          0x0700
+
+
+#define A_IO_INTERRUPT_STATUS       0x0010061A00
+#define A_IO_INTERRUPT_DATA0        0x0010061A10
+#define A_IO_INTERRUPT_DATA1        0x0010061A18
+#define A_IO_INTERRUPT_DATA2        0x0010061A20
+#define A_IO_INTERRUPT_DATA3        0x0010061A28
+#define A_IO_INTERRUPT_ADDR0        0x0010061A30
+#define A_IO_INTERRUPT_ADDR1        0x0010061A40
+#define A_IO_INTERRUPT_PARITY       0x0010061A50
+#define A_IO_PCMCIA_CFG             0x0010061A60
+#define A_IO_PCMCIA_STATUS          0x0010061A70
+#define A_IO_DRIVE_0		    0x0010061300
+#define A_IO_DRIVE_1		    0x0010061308
+#define A_IO_DRIVE_2		    0x0010061310
+#define A_IO_DRIVE_3		    0x0010061318
+
+#define R_IO_INTERRUPT_STATUS       0x0A00
+#define R_IO_INTERRUPT_DATA0        0x0A10
+#define R_IO_INTERRUPT_DATA1        0x0A18
+#define R_IO_INTERRUPT_DATA2        0x0A20
+#define R_IO_INTERRUPT_DATA3        0x0A28
+#define R_IO_INTERRUPT_ADDR0        0x0A30
+#define R_IO_INTERRUPT_ADDR1        0x0A40
+#define R_IO_INTERRUPT_PARITY       0x0A50
+#define R_IO_PCMCIA_CFG             0x0A60
+#define R_IO_PCMCIA_STATUS          0x0A70
+
+/*  ********************************************************************* 
+    * GPIO Registers
+    ********************************************************************* */
+
+#define A_GPIO_CLR_EDGE             0x0010061A80
+#define A_GPIO_INT_TYPE             0x0010061A88
+#define A_GPIO_INPUT_INVERT         0x0010061A90
+#define A_GPIO_GLITCH               0x0010061A98
+#define A_GPIO_READ                 0x0010061AA0
+#define A_GPIO_DIRECTION            0x0010061AA8
+#define A_GPIO_PIN_CLR              0x0010061AB0
+#define A_GPIO_PIN_SET              0x0010061AB8
+
+#define A_GPIO_BASE		    0x0010061A80
+
+#define R_GPIO_CLR_EDGE             0x00
+#define R_GPIO_INT_TYPE             0x08
+#define R_GPIO_INPUT_INVERT         0x10
+#define R_GPIO_GLITCH               0x18
+#define R_GPIO_READ                 0x20
+#define R_GPIO_DIRECTION            0x28
+#define R_GPIO_PIN_CLR              0x30
+#define R_GPIO_PIN_SET              0x38
+
+/*  ********************************************************************* 
+    * SMBus Registers
+    ********************************************************************* */
+
+#define A_SMB_XTRA_0                0x0010060000
+#define A_SMB_XTRA_1                0x0010060008
+#define A_SMB_FREQ_0                0x0010060010
+#define A_SMB_FREQ_1                0x0010060018
+#define A_SMB_STATUS_0              0x0010060020
+#define A_SMB_STATUS_1              0x0010060028
+#define A_SMB_CMD_0                 0x0010060030
+#define A_SMB_CMD_1                 0x0010060038
+#define A_SMB_START_0               0x0010060040
+#define A_SMB_START_1               0x0010060048
+#define A_SMB_DATA_0                0x0010060050
+#define A_SMB_DATA_1                0x0010060058
+#define A_SMB_CONTROL_0             0x0010060060
+#define A_SMB_CONTROL_1             0x0010060068
+#define A_SMB_PEC_0                 0x0010060070
+#define A_SMB_PEC_1                 0x0010060078
+
+#define A_SMB_0                     0x0010060000
+#define A_SMB_1                     0x0010060008
+#define SMB_REGISTER_SPACING        0x8
+#define A_SMB_BASE(idx)             (A_SMB_0+(idx)*SMB_REGISTER_SPACING)
+#define A_SMB_REGISTER(idx,reg)     (A_SMB_BASE(idx)+(reg))
+
+#define R_SMB_XTRA                  0x0000000000
+#define R_SMB_FREQ                  0x0000000010
+#define R_SMB_STATUS                0x0000000020
+#define R_SMB_CMD                   0x0000000030
+#define R_SMB_START                 0x0000000040
+#define R_SMB_DATA                  0x0000000050
+#define R_SMB_CONTROL               0x0000000060
+#define R_SMB_PEC                   0x0000000070
+
+/*  ********************************************************************* 
+    * Timer Registers
+    ********************************************************************* */
+
+/*
+ * Watchdog timers
+ */
+
+#define A_SCD_WDOG_0		    0x0010020050
+#define A_SCD_WDOG_1                0x0010020150
+#define SCD_WDOG_SPACING            0x100
+#define SCD_NUM_WDOGS		    2
+#define A_SCD_WDOG_BASE(w)          (A_SCD_WDOG_0+SCD_WDOG_SPACING*(w))
+#define A_SCD_WDOG_REGISTER(w,r)    (A_SCD_WDOG_BASE(w) + (r))
+
+#define R_SCD_WDOG_INIT		    0x0000000000
+#define R_SCD_WDOG_CNT		    0x0000000008
+#define R_SCD_WDOG_CFG		    0x0000000010
+
+#define A_SCD_WDOG_INIT_0           0x0010020050
+#define A_SCD_WDOG_CNT_0            0x0010020058
+#define A_SCD_WDOG_CFG_0            0x0010020060
+
+#define A_SCD_WDOG_INIT_1           0x0010020150
+#define A_SCD_WDOG_CNT_1            0x0010020158
+#define A_SCD_WDOG_CFG_1            0x0010020160
+
+/*
+ * Generic timers
+ */
+
+#define A_SCD_TIMER_0		    0x0010020070
+#define A_SCD_TIMER_1               0x0010020078
+#define A_SCD_TIMER_2		    0x0010020170
+#define A_SCD_TIMER_3               0x0010020178
+#define SCD_NUM_TIMERS		    4
+#define A_SCD_TIMER_BASE(w)         (A_SCD_TIMER_0+0x08*((w)&1)+0x100*(((w)&2)>>1))
+#define A_SCD_TIMER_REGISTER(w,r)   (A_SCD_TIMER_BASE(w) + (r))
+
+#define R_SCD_TIMER_INIT	    0x0000000000
+#define R_SCD_TIMER_CNT		    0x0000000010
+#define R_SCD_TIMER_CFG		    0x0000000020
+
+#define A_SCD_TIMER_INIT_0          0x0010020070
+#define A_SCD_TIMER_CNT_0           0x0010020080
+#define A_SCD_TIMER_CFG_0           0x0010020090
+
+#define A_SCD_TIMER_INIT_1          0x0010020078
+#define A_SCD_TIMER_CNT_1           0x0010020088
+#define A_SCD_TIMER_CFG_1           0x0010020098
+
+#define A_SCD_TIMER_INIT_2          0x0010020170
+#define A_SCD_TIMER_CNT_2           0x0010020180
+#define A_SCD_TIMER_CFG_2           0x0010020190
+
+#define A_SCD_TIMER_INIT_3          0x0010020178
+#define A_SCD_TIMER_CNT_3           0x0010020188
+#define A_SCD_TIMER_CFG_3           0x0010020198
+
+/*  ********************************************************************* 
+    * System Control Registers
+    ********************************************************************* */
+
+#define A_SCD_SYSTEM_REVISION       0x0010020000
+#define A_SCD_SYSTEM_CFG            0x0010020008
+
+#define A_SCD_SCRATCH		    0x0010020C10	/* PASS2 */
+
+/*  ********************************************************************* 
+    * System Address Trap Registers
+    ********************************************************************* */
+
+#define A_ADDR_TRAP_INDEX           0x00100200B0
+#define A_ADDR_TRAP_REG             0x00100200B8
+#define A_ADDR_TRAP_UP_0            0x0010020400
+#define A_ADDR_TRAP_UP_1            0x0010020408
+#define A_ADDR_TRAP_UP_2            0x0010020410
+#define A_ADDR_TRAP_UP_3            0x0010020418
+#define A_ADDR_TRAP_DOWN_0          0x0010020420
+#define A_ADDR_TRAP_DOWN_1          0x0010020428
+#define A_ADDR_TRAP_DOWN_2          0x0010020430
+#define A_ADDR_TRAP_DOWN_3          0x0010020438
+#define A_ADDR_TRAP_CFG_0           0x0010020440
+#define A_ADDR_TRAP_CFG_1           0x0010020448
+#define A_ADDR_TRAP_CFG_2           0x0010020450
+#define A_ADDR_TRAP_CFG_3           0x0010020458
+
+
+/*  ********************************************************************* 
+    * System Interrupt Mapper Registers
+    ********************************************************************* */
+
+#define A_IMR_CPU0_BASE                 0x0010020000
+#define A_IMR_CPU1_BASE                 0x0010022000
+#define IMR_REGISTER_SPACING            0x2000
+
+#define A_IMR_MAPPER(cpu) (A_IMR_CPU0_BASE+(cpu)*IMR_REGISTER_SPACING)
+#define A_IMR_REGISTER(cpu,reg) (A_IMR_MAPPER(cpu)+(reg))
+
+#define R_IMR_INTERRUPT_DIAG            0x0010
+#define R_IMR_INTERRUPT_MASK            0x0028
+#define R_IMR_INTERRUPT_TRACE           0x0038
+#define R_IMR_INTERRUPT_SOURCE_STATUS   0x0040
+#define R_IMR_LDT_INTERRUPT_SET         0x0048
+#define R_IMR_LDT_INTERRUPT             0x0018
+#define R_IMR_LDT_INTERRUPT_CLR         0x0020
+#define R_IMR_MAILBOX_CPU               0x00c0
+#define R_IMR_ALIAS_MAILBOX_CPU         0x1000
+#define R_IMR_MAILBOX_SET_CPU           0x00C8
+#define R_IMR_ALIAS_MAILBOX_SET_CPU     0x1008
+#define R_IMR_MAILBOX_CLR_CPU           0x00D0
+#define R_IMR_INTERRUPT_STATUS_BASE     0x0100
+#define R_IMR_INTERRUPT_STATUS_COUNT    7
+#define R_IMR_INTERRUPT_MAP_BASE        0x0200
+#define R_IMR_INTERRUPT_MAP_COUNT       64
+
+/*  ********************************************************************* 
+    * System Performance Counter Registers
+    ********************************************************************* */
+
+#define A_SCD_PERF_CNT_CFG          0x00100204C0
+#define A_SCD_PERF_CNT_0            0x00100204D0
+#define A_SCD_PERF_CNT_1            0x00100204D8
+#define A_SCD_PERF_CNT_2            0x00100204E0
+#define A_SCD_PERF_CNT_3            0x00100204E8
+
+/*  ********************************************************************* 
+    * System Bus Watcher Registers
+    ********************************************************************* */
+
+#define A_SCD_BUS_ERR_STATUS        0x0010020880
+#define A_BUS_ERR_DATA_0            0x00100208A0
+#define A_BUS_ERR_DATA_1            0x00100208A8
+#define A_BUS_ERR_DATA_2            0x00100208B0
+#define A_BUS_ERR_DATA_3            0x00100208B8
+#define A_BUS_L2_ERRORS             0x00100208C0
+#define A_BUS_MEM_IO_ERRORS         0x00100208C8
+
+/*  ********************************************************************* 
+    * System Debug Controller Registers
+    ********************************************************************* */
+
+#define A_SCD_JTAG_BASE             0x0010000000
+
+/*  ********************************************************************* 
+    * System Trace Buffer Registers
+    ********************************************************************* */
+
+#define A_SCD_TRACE_CFG             0x0010020A00
+#define A_SCD_TRACE_READ            0x0010020A08
+#define A_SCD_TRACE_EVENT_0         0x0010020A20
+#define A_SCD_TRACE_EVENT_1         0x0010020A28
+#define A_SCD_TRACE_EVENT_2         0x0010020A30
+#define A_SCD_TRACE_EVENT_3         0x0010020A38
+#define A_SCD_TRACE_SEQUENCE_0      0x0010020A40
+#define A_SCD_TRACE_SEQUENCE_1      0x0010020A48
+#define A_SCD_TRACE_SEQUENCE_2      0x0010020A50
+#define A_SCD_TRACE_SEQUENCE_3      0x0010020A58
+#define A_SCD_TRACE_EVENT_4         0x0010020A60
+#define A_SCD_TRACE_EVENT_5         0x0010020A68
+#define A_SCD_TRACE_EVENT_6         0x0010020A70
+#define A_SCD_TRACE_EVENT_7         0x0010020A78
+#define A_SCD_TRACE_SEQUENCE_4      0x0010020A80
+#define A_SCD_TRACE_SEQUENCE_5      0x0010020A88
+#define A_SCD_TRACE_SEQUENCE_6      0x0010020A90
+#define A_SCD_TRACE_SEQUENCE_7      0x0010020A98
+
+/*  ********************************************************************* 
+    * System Generic DMA Registers
+    ********************************************************************* */
+
+#define A_DM_0		  	    0x0010020B00
+#define A_DM_1		  	    0x0010020B20
+#define A_DM_2			    0x0010020B40
+#define A_DM_3			    0x0010020B60
+#define DM_REGISTER_SPACING	    0x20
+#define DM_NUM_CHANNELS		    4
+#define A_DM_BASE(idx) (A_DM_0 + ((idx) * DM_REGISTER_SPACING))
+#define A_DM_REGISTER(idx,reg) (A_DM_BASE(idx) + (reg))
+
+#define R_DM_DSCR_BASE		    0x0000000000
+#define R_DM_DSCR_COUNT		    0x0000000008
+#define R_DM_CUR_DSCR_ADDR	    0x0000000010
+#define R_DM_DSCR_BASE_DEBUG	    0x0000000018
+
+
+/*  *********************************************************************
+    *  Physical Address Map
+    ********************************************************************* */
+
+#define A_PHYS_MEMORY_0                 _SB_MAKE64(0x0000000000)
+#define A_PHYS_MEMORY_SIZE              _SB_MAKE64((256*1024*1024))
+#define A_PHYS_SYSTEM_CTL               _SB_MAKE64(0x0010000000)
+#define A_PHYS_IO_SYSTEM                _SB_MAKE64(0x0010060000)
+#define A_PHYS_GENBUS			_SB_MAKE64(0x0010090000)
+#define A_PHYS_GENBUS_END		_SB_MAKE64(0x0040000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BYTES_32 _SB_MAKE64(0x0040000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BITS_32  _SB_MAKE64(0x0060000000)
+#define A_PHYS_MEMORY_1                 _SB_MAKE64(0x0080000000)
+#define A_PHYS_MEMORY_2                 _SB_MAKE64(0x0090000000)
+#define A_PHYS_MEMORY_3                 _SB_MAKE64(0x00C0000000)
+#define A_PHYS_L2_CACHE_TEST            _SB_MAKE64(0x00D0000000)
+#define A_PHYS_LDT_SPECIAL_MATCH_BYTES  _SB_MAKE64(0x00D8000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BYTES    _SB_MAKE64(0x00DC000000)
+#define A_PHYS_LDTPCI_CFG_MATCH_BYTES   _SB_MAKE64(0x00DE000000)
+#define A_PHYS_LDT_SPECIAL_MATCH_BITS   _SB_MAKE64(0x00F8000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BITS     _SB_MAKE64(0x00FC000000)
+#define A_PHYS_LDTPCI_CFG_MATCH_BITS    _SB_MAKE64(0x00FE000000)
+#define A_PHYS_MEMORY_EXP               _SB_MAKE64(0x0100000000)
+#define A_PHYS_MEMORY_EXP_SIZE          _SB_MAKE64((508*1024*1024*1024))
+#define A_PHYS_LDT_EXP                  _SB_MAKE64(0x8000000000)
+#define A_PHYS_PCI_FULLACCESS_BYTES     _SB_MAKE64(0xF000000000)
+#define A_PHYS_PCI_FULLACCESS_BITS      _SB_MAKE64(0xF100000000)
+#define A_PHYS_RESERVED                 _SB_MAKE64(0xF200000000)
+#define A_PHYS_RESERVED_SPECIAL_LDT     _SB_MAKE64(0xFD00000000)
+
+#define A_PHYS_L2CACHE_WAY_SIZE         _SB_MAKE64(0x0000020000)
+#define PHYS_L2CACHE_NUM_WAYS           4
+#define A_PHYS_L2CACHE_TOTAL_SIZE       _SB_MAKE64(0x0000080000)
+#define A_PHYS_L2CACHE_WAY0             _SB_MAKE64(0x00D0180000)
+#define A_PHYS_L2CACHE_WAY1             _SB_MAKE64(0x00D01A0000)
+#define A_PHYS_L2CACHE_WAY2             _SB_MAKE64(0x00D01C0000)
+#define A_PHYS_L2CACHE_WAY3             _SB_MAKE64(0x00D01E0000)
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_scd.h linux/include/asm-mips/sibyte/sb1250_scd.h
--- linux.orig/include/asm-mips/sibyte/sb1250_scd.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_scd.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,459 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  SCD Constants and Macros			File: sb1250_scd.h
+    *  
+    *  This module contains constants and macros useful for
+    *  manipulating the System Control and Debug module on the 1250.
+    *  
+    *  SB1250 specification level:  0.2  plus errata as of 11/7/2000
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+#ifndef _SB1250_SCD_H
+#define _SB1250_SCD_H
+
+#include "sb1250_defs.h"
+
+/*  *********************************************************************
+    *  System control/debug registers
+    ********************************************************************* */
+
+/*
+ * System Revision Register (Table 4-1)
+ */
+
+#define M_SYS_RESERVED		    _SB_MAKEMASK(8,0)
+
+#define S_SYS_REVISION              _SB_MAKE64(8)
+#define M_SYS_REVISION              _SB_MAKEMASK(8,S_SYS_REVISION)
+#define V_SYS_REVISION(x)           _SB_MAKEVALUE(x,S_SYS_REVISION)
+#define G_SYS_REVISION(x)           _SB_GETVALUE(x,S_SYS_REVISION,M_SYS_REVISION)
+
+#define K_SYS_REVISION_PASS1	    1
+#define K_SYS_REVISION_PASS2	    3
+#define K_SYS_REVISION_PASS3	    4 /* XXX Unknown */
+
+#define S_SYS_PART                  _SB_MAKE64(16)
+#define M_SYS_PART                  _SB_MAKEMASK(16,S_SYS_PART)
+#define V_SYS_PART(x)               _SB_MAKEVALUE(x,S_SYS_PART)
+#define G_SYS_PART(x)               _SB_GETVALUE(x,S_SYS_PART,M_SYS_PART)
+
+#define K_SYS_PART_SB1250           0x1250
+#define K_SYS_PART_SB1125           0x1125 
+
+#define S_SYS_WID                   _SB_MAKE64(32)
+#define M_SYS_WID                   _SB_MAKEMASK(32,S_SYS_WID)
+#define V_SYS_WID(x)                _SB_MAKEVALUE(x,S_SYS_WID)
+#define G_SYS_WID(x)                _SB_GETVALUE(x,S_SYS_WID,M_SYS_WID)
+
+/*
+ * System Config Register (Table 4-2)
+ * Register: SCD_SYSTEM_CFG
+ */
+
+#define M_SYS_LDT_PLL_BYP           _SB_MAKEMASK1(3)
+#define M_SYS_PCI_SYNC_TEST_MODE    _SB_MAKEMASK1(4)
+#define M_SYS_IOB0_DIV              _SB_MAKEMASK1(5)
+#define M_SYS_IOB1_DIV              _SB_MAKEMASK1(6)
+
+#define S_SYS_PLL_DIV               _SB_MAKE64(7)
+#define M_SYS_PLL_DIV               _SB_MAKEMASK(5,S_SYS_PLL_DIV)
+#define V_SYS_PLL_DIV(x)            _SB_MAKEVALUE(x,S_SYS_PLL_DIV)
+#define G_SYS_PLL_DIV(x)            _SB_GETVALUE(x,S_SYS_PLL_DIV,M_SYS_PLL_DIV)
+
+#define M_SYS_SER0_ENABLE           _SB_MAKEMASK1(12)
+#define M_SYS_SER0_RSTB_EN          _SB_MAKEMASK1(13)
+#define M_SYS_SER1_ENABLE           _SB_MAKEMASK1(14)
+#define M_SYS_SER1_RSTB_EN          _SB_MAKEMASK1(15)
+#define M_SYS_PCMCIA_ENABLE         _SB_MAKEMASK1(16)
+
+#define S_SYS_BOOT_MODE             _SB_MAKE64(17)
+#define M_SYS_BOOT_MODE             _SB_MAKEMASK(2,S_SYS_BOOT_MODE)
+#define V_SYS_BOOT_MODE(x)          _SB_MAKEVALUE(x,S_SYS_BOOT_MODE)
+#define G_SYS_BOOT_MODE(x)          _SB_GETVALUE(x,S_SYS_BOOT_MODE,M_SYS_BOOT_MODE)
+#define K_SYS_BOOT_MODE_ROM32       0
+#define K_SYS_BOOT_MODE_ROM8        1
+#define K_SYS_BOOT_MODE_SMBUS_SMALL 2
+#define K_SYS_BOOT_MODE_SMBUS_BIG   3
+
+#define M_SYS_PCI_HOST              _SB_MAKEMASK1(19)
+#define M_SYS_PCI_ARBITER           _SB_MAKEMASK1(20)
+#define M_SYS_SOUTH_ON_LDT          _SB_MAKEMASK1(21)
+#define M_SYS_BIG_ENDIAN            _SB_MAKEMASK1(22)
+#define M_SYS_GENCLK_EN             _SB_MAKEMASK1(23)
+#define M_SYS_LDT_TEST_EN           _SB_MAKEMASK1(24)
+#define M_SYS_GEN_PARITY_EN         _SB_MAKEMASK1(25)
+
+#define S_SYS_CONFIG                26
+#define M_SYS_CONFIG                _SB_MAKEMASK(6,S_SYS_CONFIG)
+#define V_SYS_CONFIG(x)             _SB_MAKEVALUE(x,S_SYS_CONFIG)
+#define G_SYS_CONFIG(x)             _SB_GETVALUE(x,S_SYS_CONFIG,M_SYS_CONFIG)
+
+/* The following bits are writeable by JTAG only. */
+
+#define M_SYS_CLKSTOP               _SB_MAKEMASK1(32)
+#define M_SYS_CLKSTEP               _SB_MAKEMASK1(33)
+
+#define S_SYS_CLKCOUNT              34
+#define M_SYS_CLKCOUNT              _SB_MAKEMASK(8,S_SYS_CLKCOUNT)
+#define V_SYS_CLKCOUNT(x)           _SB_MAKEVALUE(x,S_SYS_CLKCOUNT)
+#define G_SYS_CLKCOUNT(x)           _SB_GETVALUE(x,S_SYS_CLKCOUNT,M_SYS_CLKCOUNT)
+
+#define M_SYS_PLL_BYPASS            _SB_MAKEMASK1(42)
+
+#define S_SYS_PLL_IREF		    43
+#define M_SYS_PLL_IREF		    _SB_MAKEMASK(2,S_SYS_PLL_IREF)
+
+#define S_SYS_PLL_VCO		    45
+#define M_SYS_PLL_VCO		    _SB_MAKEMASK(2,S_SYS_PLL_VCO)
+
+#define S_SYS_PLL_VREG		    47
+#define M_SYS_PLL_VREG		    _SB_MAKEMASK(2,S_SYS_PLL_VREG)
+
+#define M_SYS_MEM_RESET             _SB_MAKEMASK1(49)
+#define M_SYS_L2C_RESET             _SB_MAKEMASK1(50)
+#define M_SYS_IO_RESET_0            _SB_MAKEMASK1(51)
+#define M_SYS_IO_RESET_1            _SB_MAKEMASK1(52)
+#define M_SYS_SCD_RESET             _SB_MAKEMASK1(53)
+
+/* End of bits writable by JTAG only. */
+
+#define M_SYS_CPU_RESET_0           _SB_MAKEMASK1(54)
+#define M_SYS_CPU_RESET_1           _SB_MAKEMASK1(55)
+
+#define M_SYS_UNICPU0               _SB_MAKEMASK1(56)
+#define M_SYS_UNICPU1               _SB_MAKEMASK1(57)
+
+#define M_SYS_SB_SOFTRES            _SB_MAKEMASK1(58)
+#define M_SYS_EXT_RESET             _SB_MAKEMASK1(59)
+#define M_SYS_SYSTEM_RESET          _SB_MAKEMASK1(60)
+
+#define M_SYS_MISR_MODE             _SB_MAKEMASK1(61)
+#define M_SYS_MISR_RESET            _SB_MAKEMASK1(62)
+
+/*
+ * Mailbox Registers (Table 4-3)
+ * Registers: SCD_MBOX_CPU_x
+ */
+
+#define S_MBOX_INT_3                0
+#define M_MBOX_INT_3                _SB_MAKEMASK(16,S_MBOX_INT_3)
+#define S_MBOX_INT_2                16
+#define M_MBOX_INT_2                _SB_MAKEMASK(16,S_MBOX_INT_2)
+#define S_MBOX_INT_1                32
+#define M_MBOX_INT_1                _SB_MAKEMASK(16,S_MBOX_INT_1)
+#define S_MBOX_INT_0                48
+#define M_MBOX_INT_0                _SB_MAKEMASK(16,S_MBOX_INT_0)
+
+/*
+ * Watchdog Registers (Table 4-8) (Table 4-9) (Table 4-10)
+ * Registers: SCD_WDOG_INIT_CNT_x
+ */
+
+#define V_SCD_WDOG_FREQ             1000000
+
+#define S_SCD_WDOG_INIT             0
+#define M_SCD_WDOG_INIT             _SB_MAKEMASK(13,S_SCD_WDOG_INIT)
+
+#define S_SCD_WDOG_CNT              0
+#define M_SCD_WDOG_CNT              _SB_MAKEMASK(13,S_SCD_WDOG_CNT)
+
+#define M_SCD_WDOG_ENABLE           _SB_MAKEMASK1(0)
+
+/*
+ * Timer Registers (Table 4-11) (Table 4-12) (Table 4-13)
+ */
+
+#define V_SCD_TIMER_FREQ            1000000
+
+#define S_SCD_TIMER_INIT            0
+#define M_SCD_TIMER_INIT            _SB_MAKEMASK(20,S_SCD_TIMER_INIT)
+#define V_SCD_TIMER_INIT(x)         _SB_MAKEVALUE(x,S_SCD_TIMER_INIT)
+#define G_SCD_TIMER_INIT(x)         _SB_GETVALUE(x,S_SCD_TIMER_INIT,M_SCD_TIMER_INIT)
+
+#define S_SCD_TIMER_CNT             0
+#define M_SCD_TIMER_CNT             _SB_MAKEMASK(20,S_SCD_TIMER_CNT)
+#define V_SCD_TIMER_CNT(x)         _SB_MAKEVALUE(x,S_SCD_TIMER_CNT)
+#define G_SCD_TIMER_CNT(x)         _SB_GETVALUE(x,S_SCD_TIMER_CNT,M_SCD_TIMER_CNT)
+
+#define M_SCD_TIMER_ENABLE          _SB_MAKEMASK1(0)
+#define M_SCD_TIMER_MODE            _SB_MAKEMASK1(1)
+#define M_SCD_TIMER_MODE_CONTINUOUS M_SCD_TIMER_MODE
+
+/*
+ * System Performance Counters
+ */
+
+#define S_SPC_CFG_SRC0            0
+#define M_SPC_CFG_SRC0            _SB_MAKEMASK(8,S_SPC_CFG_SRC0)
+#define V_SPC_CFG_SRC0(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC0)
+#define G_SPC_CFG_SRC0(x)         _SB_GETVALUE(x,S_SPC_CFG_SRC0,M_SPC_CFG_SRC0)
+
+#define S_SPC_CFG_SRC1            8
+#define M_SPC_CFG_SRC1            _SB_MAKEMASK(8,S_SPC_CFG_SRC1)
+#define V_SPC_CFG_SRC1(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC1)
+#define G_SPC_CFG_SRC1(x)         _SB_GETVALUE(x,S_SPC_CFG_SRC1,M_SPC_CFG_SRC1)
+
+#define S_SPC_CFG_SRC2            16
+#define M_SPC_CFG_SRC2            _SB_MAKEMASK(8,S_SPC_CFG_SRC2)
+#define V_SPC_CFG_SRC2(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC2)
+#define G_SPC_CFG_SRC2(x)         _SB_GETVALUE(x,S_SPC_CFG_SRC2,M_SPC_CFG_SRC2)
+
+#define S_SPC_CFG_SRC3            24
+#define M_SPC_CFG_SRC3            _SB_MAKEMASK(8,S_SPC_CFG_SRC3)
+#define V_SPC_CFG_SRC3(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC3)
+#define G_SPC_CFG_SRC3(x)         _SB_GETVALUE(x,S_SPC_CFG_SRC3,M_SPC_CFG_SRC3)
+
+#define M_SPC_CFG_CLEAR		_SB_MAKEMASK1(32)
+#define M_SPC_CFG_ENABLE	_SB_MAKEMASK1(33)
+
+
+/*
+ * Bus Watcher
+ */
+
+#define S_SCD_BERR_TID            8
+#define M_SCD_BERR_TID            _SB_MAKEMASK(10,S_SCD_BERR_TID)
+#define V_SCD_BERR_TID(x)         _SB_MAKEVALUE(x,S_SCD_BERR_TID)
+#define G_SCD_BERR_TID(x)         _SB_GETVALUE(x,S_SCD_BERR_TID,M_SCD_BERR_TID)
+
+#define S_SCD_BERR_RID            18
+#define M_SCD_BERR_RID            _SB_MAKEMASK(4,S_SCD_BERR_RID)
+#define V_SCD_BERR_RID(x)         _SB_MAKEVALUE(x,S_SCD_BERR_RID)
+#define G_SCD_BERR_RID(x)         _SB_GETVALUE(x,S_SCD_BERR_RID,M_SCD_BERR_RID)
+
+#define S_SCD_BERR_DCODE            22
+#define M_SCD_BERR_DCODE            _SB_MAKEMASK(3,S_SCD_BERR_DCODE)
+#define V_SCD_BERR_DCODE(x)         _SB_MAKEVALUE(x,S_SCD_BERR_DCODE)
+#define G_SCD_BERR_DCODE(x)         _SB_GETVALUE(x,S_SCD_BERR_DCODE,M_SCD_BERR_DCODE)
+
+#define M_SCD_BERR_MULTERRS	_SB_MAKEMASK1(30)
+
+
+#define S_SCD_L2ECC_CORR_D            0
+#define M_SCD_L2ECC_CORR_D            _SB_MAKEMASK(8,S_SCD_L2ECC_CORR_D)
+#define V_SCD_L2ECC_CORR_D(x)         _SB_MAKEVALUE(x,S_SCD_L2ECC_CORR_D)
+#define G_SCD_L2ECC_CORR_D(x)         _SB_GETVALUE(x,S_SCD_L2ECC_CORR_D,M_SCD_L2ECC_CORR_D)
+
+#define S_SCD_L2ECC_BAD_D            8
+#define M_SCD_L2ECC_BAD_D            _SB_MAKEMASK(8,S_SCD_L2ECC_BAD_D)
+#define V_SCD_L2ECC_BAD_D(x)         _SB_MAKEVALUE(x,S_SCD_L2ECC_BAD_D)
+#define G_SCD_L2ECC_BAD_D(x)         _SB_GETVALUE(x,S_SCD_L2ECC_BAD_D,M_SCD_L2ECC_BAD_D)
+
+#define S_SCD_L2ECC_CORR_T            16
+#define M_SCD_L2ECC_CORR_T            _SB_MAKEMASK(8,S_SCD_L2ECC_CORR_T)
+#define V_SCD_L2ECC_CORR_T(x)         _SB_MAKEVALUE(x,S_SCD_L2ECC_CORR_T)
+#define G_SCD_L2ECC_CORR_T(x)         _SB_GETVALUE(x,S_SCD_L2ECC_CORR_T,M_SCD_L2ECC_CORR_T)
+
+#define S_SCD_L2ECC_BAD_T            24
+#define M_SCD_L2ECC_BAD_T            _SB_MAKEMASK(8,S_SCD_L2ECC_BAD_T)
+#define V_SCD_L2ECC_BAD_T(x)         _SB_MAKEVALUE(x,S_SCD_L2ECC_BAD_T)
+#define G_SCD_L2ECC_BAD_T(x)         _SB_GETVALUE(x,S_SCD_L2ECC_BAD_T,M_SCD_L2ECC_BAD_T)
+
+#define S_SCD_MEM_ECC_CORR            0
+#define M_SCD_MEM_ECC_CORR            _SB_MAKEMASK(8,S_SCD_MEM_ECC_CORR)
+#define V_SCD_MEM_ECC_CORR(x)         _SB_MAKEVALUE(x,S_SCD_MEM_ECC_CORR)
+#define G_SCD_MEM_ECC_CORR(x)         _SB_GETVALUE(x,S_SCD_MEM_ECC_CORR,M_SCD_MEM_ECC_CORR)
+
+#define S_SCD_MEM_ECC_BAD            16
+#define M_SCD_MEM_ECC_BAD            _SB_MAKEMASK(8,S_SCD_MEM_ECC_BAD)
+#define V_SCD_MEM_ECC_BAD(x)         _SB_MAKEVALUE(x,S_SCD_MEM_ECC_BAD)
+#define G_SCD_MEM_ECC_BAD(x)         _SB_GETVALUE(x,S_SCD_MEM_ECC_BAD,M_SCD_MEM_ECC_BAD)
+
+#define S_SCD_MEM_BUSERR            24
+#define M_SCD_MEM_BUSERR            _SB_MAKEMASK(8,S_SCD_MEM_BUSERR)
+#define V_SCD_MEM_BUSERR(x)         _SB_MAKEVALUE(x,S_SCD_MEM_BUSERR)
+#define G_SCD_MEM_BUSERR(x)         _SB_GETVALUE(x,S_SCD_MEM_BUSERR,M_SCD_MEM_BUSERR)
+
+
+/*
+ * Address Trap Registers
+ */
+
+#define M_ATRAP_INDEX		  _SB_MAKEMASK(4,0)
+#define M_ATRAP_ADDRESS		  _SB_MAKEMASK(40,0)
+
+#define S_ATRAP_CFG_CNT            0
+#define M_ATRAP_CFG_CNT            _SB_MAKEMASK(3,S_ATRAP_CFG_CNT)
+#define V_ATRAP_CFG_CNT(x)         _SB_MAKEVALUE(x,S_ATRAP_CFG_CNT)
+#define G_ATRAP_CFG_CNT(x)         _SB_GETVALUE(x,S_ATRAP_CFG_CNT,M_ATRAP_CFG_CNT)
+
+#define M_ATRAP_CFG_WRITE	   _SB_MAKEMASK1(3)
+#define M_ATRAP_CFG_ALL	  	   _SB_MAKEMASK1(4)
+#define M_ATRAP_CFG_INV	   	   _SB_MAKEMASK1(5)
+#define M_ATRAP_CFG_USESRC	   _SB_MAKEMASK1(6)
+#define M_ATRAP_CFG_SRCINV	   _SB_MAKEMASK1(7)
+
+#define S_ATRAP_CFG_AGENTID     8
+#define M_ATRAP_CFG_AGENTID     _SB_MAKEMASK(4,S_ATRAP_CFG_AGENTID)
+#define V_ATRAP_CFG_AGENTID(x)  _SB_MAKEVALUE(x,S_ATRAP_CFG_AGENTID)
+#define G_ATRAP_CFG_AGENTID(x)  _SB_GETVALUE(x,S_ATRAP_CFG_AGENTID,M_ATRAP_CFG_AGENTID)
+
+#define K_BUS_AGENT_CPU0	0
+#define K_BUS_AGENT_CPU1	1
+#define K_BUS_AGENT_IOB0	2
+#define K_BUS_AGENT_IOB1	3
+#define K_BUS_AGENT_SCD	4
+#define K_BUS_AGENT_RESERVED	5
+#define K_BUS_AGENT_L2C	6
+#define K_BUS_AGENT_MC	7
+
+#define S_ATRAP_CFG_CATTR     12
+#define M_ATRAP_CFG_CATTR     _SB_MAKEMASK(3,S_ATRAP_CFG_CATTR)
+#define V_ATRAP_CFG_CATTR(x)  _SB_MAKEVALUE(x,S_ATRAP_CFG_CATTR)
+#define G_ATRAP_CFG_CATTR(x)  _SB_GETVALUE(x,S_ATRAP_CFG_CATTR,M_ATRAP_CFG_CATTR)
+
+#define K_ATRAP_CFG_CATTR_IGNORE	0
+#define K_ATRAP_CFG_CATTR_UNC    	1
+#define K_ATRAP_CFG_CATTR_CACHEABLE	2
+#define K_ATRAP_CFG_CATTR_NONCOH  	3
+#define K_ATRAP_CFG_CATTR_COHERENT	4
+#define K_ATRAP_CFG_CATTR_NOTUNC	5
+#define K_ATRAP_CFG_CATTR_NOTNONCOH	6
+#define K_ATRAP_CFG_CATTR_NOTCOHERENT   7
+
+/*
+ * Trace Buffer Config register
+ */
+
+#define M_SCD_TRACE_CFG_RESET           _SB_MAKEMASK1(0)
+#define M_SCD_TRACE_CFG_START_READ      _SB_MAKEMASK1(1)
+#define M_SCD_TRACE_CFG_START           _SB_MAKEMASK1(2)
+#define M_SCD_TRACE_CFG_STOP            _SB_MAKEMASK1(3)
+#define M_SCD_TRACE_CFG_FREEZE          _SB_MAKEMASK1(4)
+#define M_SCD_TRACE_CFG_FREEZE_FULL     _SB_MAKEMASK1(5)
+#define M_SCD_TRACE_CFG_DEBUG_FULL      _SB_MAKEMASK1(6)
+#define M_SCD_TRACE_CFG_FULL            _SB_MAKEMASK1(7)
+
+#define S_SCD_TRACE_CFG_CUR_ADDR        10
+#define M_SCD_TRACE_CFG_CUR_ADDR        _SB_MAKEMASK(8,S_SCD_TRACE_CFG_CUR_ADDR)
+#define V_SCD_TRACE_CFG_CUR_ADDR(x)     _SB_MAKEVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR)
+#define G_SCD_TRACE_CFG_CUR_ADDR(x)     _SB_GETVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR,M_SCD_TRACE_CFG_CUR_ADDR)
+
+/*
+ * Trace Event registers
+ */
+
+#define S_SCD_TREVT_ADDR_MATCH          0
+#define M_SCD_TREVT_ADDR_MATCH          _SB_MAKEMASK(4,S_SCD_TREVT_ADDR_MATCH)
+#define V_SCD_TREVT_ADDR_MATCH(x)       _SB_MAKEVALUE(x,S_SCD_TREVT_ADDR_MATCH)
+#define G_SCD_TREVT_ADDR_MATCH(x)       _SB_GETVALUE(x,S_SCD_TREVT_ADDR_MATCH,M_SCD_TREVT_ADDR_MATCH)
+
+#define M_SCD_TREVT_REQID_MATCH         _SB_MAKEMASK1(4)
+#define M_SCD_TREVT_DATAID_MATCH        _SB_MAKEMASK1(5)
+#define M_SCD_TREVT_RESPID_MATCH        _SB_MAKEMASK1(6)
+#define M_SCD_TREVT_INTERRUPT           _SB_MAKEMASK1(7)
+#define M_SCD_TREVT_DEBUG_PIN           _SB_MAKEMASK1(9)
+#define M_SCD_TREVT_WRITE               _SB_MAKEMASK1(10)
+#define M_SCD_TREVT_READ                _SB_MAKEMASK1(11)
+
+#define S_SCD_TREVT_REQID               12
+#define M_SCD_TREVT_REQID               _SB_MAKEMASK(4,S_SCD_TREVT_REQID)
+#define V_SCD_TREVT_REQID(x)            _SB_MAKEVALUE(x,S_SCD_TREVT_REQID)
+#define G_SCD_TREVT_REQID(x)            _SB_GETVALUE(x,S_SCD_TREVT_REQID,M_SCD_TREVT_REQID)
+
+#define S_SCD_TREVT_RESPID              16
+#define M_SCD_TREVT_RESPID              _SB_MAKEMASK(4,S_SCD_TREVT_RESPID)
+#define V_SCD_TREVT_RESPID(x)           _SB_MAKEVALUE(x,S_SCD_TREVT_RESPID)
+#define G_SCD_TREVT_RESPID(x)           _SB_GETVALUE(x,S_SCD_TREVT_RESPID,M_SCD_TREVT_RESPID)
+
+#define S_SCD_TREVT_DATAID              20
+#define M_SCD_TREVT_DATAID              _SB_MAKEMASK(4,S_SCD_TREVT_DATAID)
+#define V_SCD_TREVT_DATAID(x)           _SB_MAKEVALUE(x,S_SCD_TREVT_DATAID)
+#define G_SCD_TREVT_DATAID(x)           _SB_GETVALUE(x,S_SCD_TREVT_DATAID,M_SCD_TREVT_DATID)
+
+#define S_SCD_TREVT_COUNT               24
+#define M_SCD_TREVT_COUNT               _SB_MAKEMASK(8,S_SCD_TREVT_COUNT)
+#define V_SCD_TREVT_COUNT(x)            _SB_MAKEVALUE(x,S_SCD_TREVT_COUNT)
+#define G_SCD_TREVT_COUNT(x)            _SB_GETVALUE(x,S_SCD_TREVT_COUNT,M_SCD_TREVT_COUNT)
+
+/*
+ * Trace Sequence registers
+ */
+
+#define S_SCD_TRSEQ_EVENT4              0
+#define M_SCD_TRSEQ_EVENT4              _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT4)
+#define V_SCD_TRSEQ_EVENT4(x)           _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT4)
+#define G_SCD_TRSEQ_EVENT4(x)           _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT4,M_SCD_TRSEQ_EVENT4)
+
+#define S_SCD_TRSEQ_EVENT3              4
+#define M_SCD_TRSEQ_EVENT3              _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT3)
+#define V_SCD_TRSEQ_EVENT3(x)           _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT3)
+#define G_SCD_TRSEQ_EVENT3(x)           _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT3,M_SCD_TRSEQ_EVENT3)
+
+#define S_SCD_TRSEQ_EVENT2              8
+#define M_SCD_TRSEQ_EVENT2              _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT2)
+#define V_SCD_TRSEQ_EVENT2(x)           _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT2)
+#define G_SCD_TRSEQ_EVENT2(x)           _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT2,M_SCD_TRSEQ_EVENT2)
+
+#define S_SCD_TRSEQ_EVENT1              12
+#define M_SCD_TRSEQ_EVENT1              _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT1)
+#define V_SCD_TRSEQ_EVENT1(x)           _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT1)
+#define G_SCD_TRSEQ_EVENT1(x)           _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT1,M_SCD_TRSEQ_EVENT1)
+
+#define K_SCD_TRSEQ_E0                  0
+#define K_SCD_TRSEQ_E1                  1
+#define K_SCD_TRSEQ_E2                  2
+#define K_SCD_TRSEQ_E3                  3
+#define K_SCD_TRSEQ_E0_E1               4
+#define K_SCD_TRSEQ_E1_E2               5
+#define K_SCD_TRSEQ_E2_E3               6
+#define K_SCD_TRSEQ_E0_E1_E2            7
+#define K_SCD_TRSEQ_E0_E1_E2_E3         8
+#define K_SCD_TRSEQ_E0E1                9
+#define K_SCD_TRSEQ_E0E1E2              10
+#define K_SCD_TRSEQ_E0E1E2E3            11
+#define K_SCD_TRSEQ_E0E1_E2             12
+#define K_SCD_TRSEQ_E0E1_E2E3           13
+#define K_SCD_TRSEQ_E0E1_E2_E3          14
+#define K_SCD_TRSEQ_IGNORED             15
+
+#define K_SCD_TRSEQ_TRIGGER_ALL         (V_SCD_TRSEQ_EVENT1(K_SCD_TRSEQ_IGNORED) | \
+                                         V_SCD_TRSEQ_EVENT2(K_SCD_TRSEQ_IGNORED) | \
+                                         V_SCD_TRSEQ_EVENT3(K_SCD_TRSEQ_IGNORED) | \
+                                         V_SCD_TRSEQ_EVENT4(K_SCD_TRSEQ_IGNORED))
+
+#define S_SCD_TRSEQ_FUNCTION            16
+#define M_SCD_TRSEQ_FUNCTION            _SB_MAKEMASK(4,S_SCD_TRSEQ_FUNCTION)
+#define V_SCD_TRSEQ_FUNCTION(x)         _SB_MAKEVALUE(x,S_SCD_TRSEQ_FUNCTION)
+#define G_SCD_TRSEQ_FUNCTION(x)         _SB_GETVALUE(x,S_SCD_TRSEQ_FUNCTION,M_SCD_TRSEQ_FUNCTION)
+
+#define K_SCD_TRSEQ_FUNC_NOP            0
+#define K_SCD_TRSEQ_FUNC_START          1
+#define K_SCD_TRSEQ_FUNC_STOP           2
+#define K_SCD_TRSEQ_FUNC_FREEZE         3
+
+#define V_SCD_TRSEQ_FUNC_NOP            V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_NOP)
+#define V_SCD_TRSEQ_FUNC_START          V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_START)
+#define V_SCD_TRSEQ_FUNC_STOP           V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_STOP)
+#define V_SCD_TRSEQ_FUNC_FREEZE         V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_FREEZE)
+
+#define M_SCD_TRSEQ_ASAMPLE             _SB_MAKEMASK1(18)
+#define M_SCD_TRSEQ_DSAMPLE             _SB_MAKEMASK1(19)
+#define M_SCD_TRSEQ_DEBUGPIN            _SB_MAKEMASK1(20)
+#define M_SCD_TRSEQ_DEBUGCPU            _SB_MAKEMASK1(21)
+#define M_SCD_TRSEQ_CLEARUSE            _SB_MAKEMASK1(22)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_smbus.h linux/include/asm-mips/sibyte/sb1250_smbus.h
--- linux.orig/include/asm-mips/sibyte/sb1250_smbus.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_smbus.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,134 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  SMBUS Constants                          File: sb1250_smbus.h
+    *  
+    *  This module contains constants and macros useful for 
+    *  manipulating the SB1250's SMbus devices.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_SMBUS_H
+#define _SB1250_SMBUS_H
+
+#include "sb1250_defs.h"
+
+/*
+ * SMBus Clock Frequency Register (Table 14-2)
+ */
+
+#define S_SMB_FREQ_DIV              0
+#define M_SMB_FREQ_DIV              _SB_MAKEMASK(13,S_SMB_FREQ_DIV)
+#define V_SMB_FREQ_DIV(x)           _SB_MAKEVALUE(x,S_SMB_FREQ_DIV)
+
+#define K_SMB_FREQ_400KHZ	    0x1F
+#define K_SMB_FREQ_100KHZ	    0x7D
+
+#define S_SMB_CMD                   0
+#define M_SMB_CMD                   _SB_MAKEMASK(8,S_SMB_CMD)
+#define V_SMB_CMD(x)                _SB_MAKEVALUE(x,S_SMB_CMD)
+
+/*
+ * SMBus control register (Table 14-4)
+ */
+
+#define M_SMB_ERR_INTR              _SB_MAKEMASK1(0)
+#define M_SMB_FINISH_INTR           _SB_MAKEMASK1(1)
+#define M_SMB_DATA_OUT              _SB_MAKEMASK1(4)
+#define M_SMB_DATA_DIR              _SB_MAKEMASK1(5)
+#define M_SMB_DATA_DIR_OUTPUT       M_SMB_DATA_DIR
+#define M_SMB_CLK_OUT               _SB_MAKEMASK1(6)
+#define M_SMB_DIRECT_ENABLE         _SB_MAKEMASK1(7)
+
+/*
+ * SMBus status registers (Table 14-5)
+ */
+
+#define M_SMB_BUSY                  _SB_MAKEMASK1(0)
+#define M_SMB_ERROR                 _SB_MAKEMASK1(1)
+#define M_SMB_ERROR_TYPE            _SB_MAKEMASK1(2)
+#define M_SMB_REF                   _SB_MAKEMASK1(6)
+#define M_SMB_DATA_IN               _SB_MAKEMASK1(7)
+
+/*
+ * SMBus Start/Command registers (Table 14-9)
+ */
+
+#define S_SMB_ADDR                  0
+#define M_SMB_ADDR                  _SB_MAKEMASK(7,S_SMB_ADDR)
+#define V_SMB_ADDR(x)               _SB_MAKEVALUE(x,S_SMB_ADDR)
+#define G_SMB_ADDR(x)               _SB_GETVALUE(x,S_SMB_ADDR,M_SMB_ADDR)
+
+#define M_SMB_QDATA                 _SB_MAKEMASK1(7)
+
+#define S_SMB_TT                    8
+#define M_SMB_TT                    _SB_MAKEMASK(3,S_SMB_TT)
+#define V_SMB_TT(x)                 _SB_MAKEVALUE(x,S_SMB_TT)
+#define G_SMB_TT(x)                 _SB_GETVALUE(x,S_SMB_TT,M_SMB_TT)
+
+#define K_SMB_TT_WR1BYTE            0
+#define K_SMB_TT_WR2BYTE            1
+#define K_SMB_TT_WR3BYTE            2
+#define K_SMB_TT_CMD_RD1BYTE        3
+#define K_SMB_TT_CMD_RD2BYTE        4
+#define K_SMB_TT_RD1BYTE            5
+#define K_SMB_TT_QUICKCMD           6
+#define K_SMB_TT_EEPROMREAD         7
+
+#define V_SMB_TT_WR1BYTE	    V_SMB_TT(K_SMB_TT_WR1BYTE)
+#define V_SMB_TT_WR2BYTE	    V_SMB_TT(K_SMB_TT_WR2BYTE)
+#define V_SMB_TT_WR3BYTE	    V_SMB_TT(K_SMB_TT_WR3BYTE)
+#define V_SMB_TT_CMD_RD1BYTE	    V_SMB_TT(K_SMB_TT_CMD_RD1BYTE)
+#define V_SMB_TT_CMD_RD2BYTE	    V_SMB_TT(K_SMB_TT_CMD_RD2BYTE)
+#define V_SMB_TT_RD1BYTE	    V_SMB_TT(K_SMB_TT_RD1BYTE)
+#define V_SMB_TT_QUICKCMD	    V_SMB_TT(K_SMB_TT_QUICKCMD)
+#define V_SMB_TT_EEPROMREAD	    V_SMB_TT(K_SMB_TT_EEPROMREAD)
+
+#define M_SMB_PEC                   _SB_MAKEMASK1(15)
+
+/*
+ * SMBus Data Register (Table 14-6) and SMBus Extra Register (Table 14-7)
+ */
+
+#define S_SMB_LB                    0
+#define M_SMB_LB                    _SB_MAKEMASK(8,S_SMB_LB)
+#define V_SMB_LB(x)                 _SB_MAKEVALUE(x,S_SMB_LB)
+
+#define S_SMB_MB                    8
+#define M_SMB_MB                    _SB_MAKEMASK(8,S_SMB_MB)
+#define V_SMB_MB(x)                 _SB_MAKEVALUE(x,S_SMB_MB)
+
+
+/*
+ * SMBus Packet Error Check register (Table 14-8)
+ */
+
+#define S_SPEC_PEC                  0
+#define M_SPEC_PEC                  _SB_MAKEMASK(8,S_SPEC_PEC)
+#define V_SPEC_MB(x)                _SB_MAKEVALUE(x,S_SPEC_PEC)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_syncser.h linux/include/asm-mips/sibyte/sb1250_syncser.h
--- linux.orig/include/asm-mips/sibyte/sb1250_syncser.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_syncser.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,148 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *
+    *  Synchronous Serial Constants              File: sb1250_syncser.h
+    *
+    *  This module contains constants and macros useful for
+    *  manipulating the SB1250's Synchronous Serial
+    *
+    *  SB1250 specification level:  0.2
+    *
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *
+    *********************************************************************
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_SYNCSER_H
+#define _SB1250_SYNCSER_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Serial Mode Configuration Register
+ */
+
+#define M_SYNCSER_CRC_MODE                 _SB_MAKEMASK1(0)
+#define M_SYNCSER_MSB_FIRST                _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_FLAG_NUM                 2
+#define M_SYNCSER_FLAG_NUM                 _SB_MAKEMASK(4,S_SYNCSER_FLAG_NUM)
+#define V_SYNCSER_FLAG_NUM                 _SB_MAKEVALUE(x,S_SYNCSER_FLAG_NUM)
+
+#define M_SYNCSER_FLAG_EN                  _SB_MAKEMASK1(6)
+#define M_SYNCSER_HDLC_EN                  _SB_MAKEMASK1(7)
+#define M_SYNCSER_LOOP_MODE                _SB_MAKEMASK1(8)
+#define M_SYNCSER_LOOPBACK                 _SB_MAKEMASK1(9)
+
+/*
+ * Serial Clock Source and Line Interface Mode Register
+ */
+
+#define M_SYNCSER_RXCLK_INV                _SB_MAKEMASK1(0)
+#define M_SYNCSER_RXCLK_EXT                _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_RXSYNC_DLY               2
+#define M_SYNCSER_RXSYNC_DLY               _SB_MAKEMASK(2,S_SYNCSER_RXSYNC_DLY)
+#define V_SYNCSER_RXSYNC_DLY(x)            _SB_MAKEVALUE(x,S_SYNCSER_RXSYNC_DLY)
+
+#define M_SYNCSER_RXSYNC_LOW               _SB_MAKEMASK1(4)
+#define M_SYNCSER_RXSTRB_LOW               _SB_MAKEMASK1(5)
+
+#define M_SYNCSER_RXSYNC_EDGE              _SB_MAKEMASK1(6)
+#define M_SYNCSER_RXSYNC_INT               _SB_MAKEMASK1(7)
+
+#define M_SYNCSER_TXCLK_INV                _SB_MAKEMASK1(8)
+#define M_SYNCSER_TXCLK_EXT                _SB_MAKEMASK1(9)
+
+#define S_SYNCSER_TXSYNC_DLY               10
+#define M_SYNCSER_TXSYNC_DLY               _SB_MAKEMASK(2,S_SYNCSER_TXSYNC_DLY)
+#define V_SYNCSER_TXSYNC_DLY(x)            _SB_MAKEVALUE(x,S_SYNCSER_TXSYNC_DLY)
+
+#define M_SYNCSER_TXSYNC_LOW               _SB_MAKEMASK1(12)
+#define M_SYNCSER_TXSTRB_LOW               _SB_MAKEMASK1(13)
+
+#define M_SYNCSER_TXSYNC_EDGE              _SB_MAKEMASK1(14)
+#define M_SYNCSER_TXSYNC_INT               _SB_MAKEMASK1(15)
+
+/*
+ * Serial Command Register
+ */
+
+#define M_SYNCSER_CMD_RX_EN                _SB_MAKEMASK1(0)
+#define M_SYNCSER_CMD_TX_EN                _SB_MAKEMASK1(1)
+#define M_SYNCSER_CMD_RX_RESET             _SB_MAKEMASK1(2)
+#define M_SYNCSER_CMD_TX_RESET             _SB_MAKEMASK1(3)
+#define M_SYNCSER_CMD_TX_PAUSE             _SB_MAKEMASK1(5)
+
+/*
+ * Serial DMA Enable Register
+ */
+
+#define M_SYNCSER_DMA_RX_EN                _SB_MAKEMASK1(0)
+#define M_SYNCSER_DMA_TX_EN                _SB_MAKEMASK1(4)
+
+/*
+ * Serial Status Register
+ */
+
+#define M_SYNCSER_RX_CRCERR                _SB_MAKEMASK1(0)
+#define M_SYNCSER_RX_ABORT                 _SB_MAKEMASK1(1)
+#define M_SYNCSER_RX_OCTET                 _SB_MAKEMASK1(2)
+#define M_SYNCSER_RX_LONGFRM               _SB_MAKEMASK1(3)
+#define M_SYNCSER_RX_SHORTFRM              _SB_MAKEMASK1(4)
+#define M_SYNCSER_RX_OVERRUN               _SB_MAKEMASK1(5)
+#define M_SYNCSER_RX_SYNC_ERR              _SB_MAKEMASK1(6)
+#define M_SYNCSER_TX_CRCERR                _SB_MAKEMASK1(8)
+#define M_SYNCSER_TX_UNDERRUN              _SB_MAKEMASK1(9)
+#define M_SYNCSER_TX_SYNC_ERR              _SB_MAKEMASK1(10)
+#define M_SYNCSER_TX_PAUSE_COMPLETE        _SB_MAKEMASK1(11)
+#define M_SYNCSER_RX_EOP_COUNT             _SB_MAKEMASK1(16)
+#define M_SYNCSER_RX_EOP_TIMER             _SB_MAKEMASK1(17)
+#define M_SYNCSER_RX_EOP_SEEN              _SB_MAKEMASK1(18)
+#define M_SYNCSER_RX_HWM                   _SB_MAKEMASK1(19)
+#define M_SYNCSER_RX_LWM                   _SB_MAKEMASK1(20)
+#define M_SYNCSER_RX_DSCR                  _SB_MAKEMASK1(21)
+#define M_SYNCSER_RX_DERR                  _SB_MAKEMASK1(22)
+#define M_SYNCSER_TX_EOP_COUNT             _SB_MAKEMASK1(24)
+#define M_SYNCSER_TX_EOP_TIMER             _SB_MAKEMASK1(25)
+#define M_SYNCSER_TX_EOP_SEEN              _SB_MAKEMASK1(26)
+#define M_SYNCSER_TX_HWM                   _SB_MAKEMASK1(27)
+#define M_SYNCSER_TX_LWM                   _SB_MAKEMASK1(28)
+#define M_SYNCSER_TX_DSCR                  _SB_MAKEMASK1(29)
+#define M_SYNCSER_TX_DERR                  _SB_MAKEMASK1(30)
+#define M_SYNCSER_TX_DZERO                 _SB_MAKEMASK1(31)
+
+/*
+ * Sequencer Table Entry format
+ */
+
+#define M_SYNCSER_SEQ_LAST                 _SB_MAKEMASK1(0)
+#define M_SYNCSER_SEQ_BYTE                 _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_SEQ_COUNT                2
+#define M_SYNCSER_SEQ_COUNT                _SB_MAKEMASK(4,S_SYNCSER_SEQ_COUNT)
+#define V_SYNCSER_SEQ_COUNT(x)             _SB_MAKEVALUE(x,S_SYNCSER_SEQ_COUNT)
+
+#define M_SYNCSER_SEQ_ENABLE               _SB_MAKEMASK1(6)
+#define M_SYNCSER_SEQ_STROBE               _SB_MAKEMASK1(7)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/sb1250_uart.h linux/include/asm-mips/sibyte/sb1250_uart.h
--- linux.orig/include/asm-mips/sibyte/sb1250_uart.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/sb1250_uart.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,336 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  UART Constants				File: sb1250_uart.h
+    *  
+    *  This module contains constants and macros useful for 
+    *  manipulating the SB1250's UARTs
+    *
+    *  SB1250 specification level:  01/02/2002
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_UART_H
+#define _SB1250_UART_H
+
+#include "sb1250_defs.h"
+
+/* ********************************************************************** 
+   * DUART Registers
+   ********************************************************************** */
+
+/*
+ * DUART Mode Register #1 (Table 10-3)
+ * Register: DUART_MODE_REG_1_A
+ * Register: DUART_MODE_REG_1_B
+ */
+
+#define S_DUART_BITS_PER_CHAR       0
+#define M_DUART_BITS_PER_CHAR       _SB_MAKEMASK(2,S_DUART_BITS_PER_CHAR)
+#define V_DUART_BITS_PER_CHAR(x)    _SB_MAKEVALUE(x,S_DUART_BITS_PER_CHAR)
+
+#define K_DUART_BITS_PER_CHAR_RSV0  0
+#define K_DUART_BITS_PER_CHAR_RSV1  1
+#define K_DUART_BITS_PER_CHAR_7     2
+#define K_DUART_BITS_PER_CHAR_8     3
+
+#define V_DUART_BITS_PER_CHAR_RSV0  V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV0)
+#define V_DUART_BITS_PER_CHAR_RSV1  V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV1)
+#define V_DUART_BITS_PER_CHAR_7     V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_7)
+#define V_DUART_BITS_PER_CHAR_8     V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_8)
+
+
+#define M_DUART_PARITY_TYPE_EVEN    0x00
+#define M_DUART_PARITY_TYPE_ODD     _SB_MAKEMASK1(2)
+
+#define S_DUART_PARITY_MODE          3
+#define M_DUART_PARITY_MODE         _SB_MAKEMASK(2,S_DUART_PARITY_MODE)
+#define V_DUART_PARITY_MODE(x)      _SB_MAKEVALUE(x,S_DUART_PARITY_MODE)
+
+#define K_DUART_PARITY_MODE_ADD       0
+#define K_DUART_PARITY_MODE_ADD_FIXED 1
+#define K_DUART_PARITY_MODE_NONE      2
+
+#define V_DUART_PARITY_MODE_ADD       V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD)
+#define V_DUART_PARITY_MODE_ADD_FIXED V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD_FIXED)
+#define V_DUART_PARITY_MODE_NONE      V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_NONE)
+
+#define M_DUART_ERR_MODE            _SB_MAKEMASK1(5)    /* must be zero */
+
+#define M_DUART_RX_IRQ_SEL_RXRDY    0
+#define M_DUART_RX_IRQ_SEL_RXFULL   _SB_MAKEMASK1(6)
+
+#define M_DUART_RX_RTS_ENA          _SB_MAKEMASK1(7)
+
+/*
+ * DUART Mode Register #2 (Table 10-4)
+ * Register: DUART_MODE_REG_2_A
+ * Register: DUART_MODE_REG_2_B
+ */
+
+#define M_DUART_MODE_RESERVED1      _SB_MAKEMASK(3,0)   /* ignored */
+
+#define M_DUART_STOP_BIT_LEN_2      _SB_MAKEMASK1(3)
+#define M_DUART_STOP_BIT_LEN_1      0
+
+#define M_DUART_TX_CTS_ENA          _SB_MAKEMASK1(4)
+
+#define M_DUART_MODE_RESERVED2      _SB_MAKEMASK1(5)    /* must be zero */
+
+#define S_DUART_CHAN_MODE	    6
+#define M_DUART_CHAN_MODE           _SB_MAKEMASK(2,S_DUART_CHAN_MODE)
+#define V_DUART_CHAN_MODE(x)	    _SB_MAKEVALUE(x,S_DUART_CHAN_MODE)
+
+#define K_DUART_CHAN_MODE_NORMAL    0
+#define K_DUART_CHAN_MODE_LCL_LOOP  2
+#define K_DUART_CHAN_MODE_REM_LOOP  3
+
+#define V_DUART_CHAN_MODE_NORMAL    V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_NORMAL)
+#define V_DUART_CHAN_MODE_LCL_LOOP  V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_LCL_LOOP)
+#define V_DUART_CHAN_MODE_REM_LOOP  V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_REM_LOOP)
+
+/*
+ * DUART Command Register (Table 10-5)
+ * Register: DUART_CMD_A
+ * Register: DUART_CMD_B
+ */
+
+#define M_DUART_RX_EN               _SB_MAKEMASK1(0)
+#define M_DUART_RX_DIS              _SB_MAKEMASK1(1)
+#define M_DUART_TX_EN               _SB_MAKEMASK1(2)
+#define M_DUART_TX_DIS              _SB_MAKEMASK1(3)
+
+#define S_DUART_MISC_CMD	    4
+#define M_DUART_MISC_CMD            _SB_MAKEMASK(3,S_DUART_MISC_CMD)
+#define V_DUART_MISC_CMD(x)         _SB_MAKEVALUE(x,S_DUART_MISC_CMD)
+
+#define K_DUART_MISC_CMD_NOACTION0       0
+#define K_DUART_MISC_CMD_NOACTION1       1
+#define K_DUART_MISC_CMD_RESET_RX        2
+#define K_DUART_MISC_CMD_RESET_TX        3
+#define K_DUART_MISC_CMD_NOACTION4       4
+#define K_DUART_MISC_CMD_RESET_BREAK_INT 5
+#define K_DUART_MISC_CMD_START_BREAK     6
+#define K_DUART_MISC_CMD_STOP_BREAK      7
+
+#define V_DUART_MISC_CMD_NOACTION0       V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION0)
+#define V_DUART_MISC_CMD_NOACTION1       V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION1)
+#define V_DUART_MISC_CMD_RESET_RX        V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_RX)
+#define V_DUART_MISC_CMD_RESET_TX        V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_TX)
+#define V_DUART_MISC_CMD_NOACTION4       V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION4)
+#define V_DUART_MISC_CMD_RESET_BREAK_INT V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_BREAK_INT)
+#define V_DUART_MISC_CMD_START_BREAK     V_DUART_MISC_CMD(K_DUART_MISC_CMD_START_BREAK)
+#define V_DUART_MISC_CMD_STOP_BREAK      V_DUART_MISC_CMD(K_DUART_MISC_CMD_STOP_BREAK)
+
+#define M_DUART_CMD_RESERVED             _SB_MAKEMASK1(7) 
+
+/*
+ * DUART Status Register (Table 10-6)
+ * Register: DUART_STATUS_A
+ * Register: DUART_STATUS_B
+ * READ-ONLY
+ */
+
+#define M_DUART_RX_RDY              _SB_MAKEMASK1(0)
+#define M_DUART_RX_FFUL             _SB_MAKEMASK1(1)
+#define M_DUART_TX_RDY              _SB_MAKEMASK1(2)
+#define M_DUART_TX_EMT              _SB_MAKEMASK1(3)
+#define M_DUART_OVRUN_ERR           _SB_MAKEMASK1(4)
+#define M_DUART_PARITY_ERR          _SB_MAKEMASK1(5)
+#define M_DUART_FRM_ERR             _SB_MAKEMASK1(6)
+#define M_DUART_RCVD_BRK            _SB_MAKEMASK1(7)
+
+/*
+ * DUART Baud Rate Register (Table 10-7)
+ * Register: DUART_CLK_SEL_A 
+ * Register: DUART_CLK_SEL_B
+ */
+
+#define M_DUART_CLK_COUNTER         _SB_MAKEMASK(12,0)
+#define V_DUART_BAUD_RATE(x)        (100000000/((x)*20)-1)
+
+/*
+ * DUART Data Registers (Table 10-8 and 10-9)
+ * Register: DUART_RX_HOLD_A
+ * Register: DUART_RX_HOLD_B
+ * Register: DUART_TX_HOLD_A
+ * Register: DUART_TX_HOLD_B
+ */
+
+#define M_DUART_RX_DATA             _SB_MAKEMASK(8,0)
+#define M_DUART_TX_DATA             _SB_MAKEMASK(8,0)
+
+/*
+ * DUART Input Port Register (Table 10-10)
+ * Register: DUART_IN_PORT
+ */
+
+#define M_DUART_IN_PIN0_VAL         _SB_MAKEMASK1(0)
+#define M_DUART_IN_PIN1_VAL         _SB_MAKEMASK1(1)
+#define M_DUART_IN_PIN2_VAL         _SB_MAKEMASK1(2)
+#define M_DUART_IN_PIN3_VAL         _SB_MAKEMASK1(3)
+#define M_DUART_IN_PIN4_VAL         _SB_MAKEMASK1(4)
+#define M_DUART_IN_PIN5_VAL         _SB_MAKEMASK1(5)
+#define M_DUART_RIN0_PIN            _SB_MAKEMASK1(6)
+#define M_DUART_RIN1_PIN            _SB_MAKEMASK1(7)
+
+/*
+ * DUART Input Port Change Status Register (Tables 10-11, 10-12, and 10-13)
+ * Register: DUART_INPORT_CHNG
+ */
+
+#define S_DUART_IN_PIN_VAL          0
+#define M_DUART_IN_PIN_VAL          _SB_MAKEMASK(4,S_DUART_IN_PIN_VAL)
+
+#define S_DUART_IN_PIN_CHNG         4
+#define M_DUART_IN_PIN_CHNG         _SB_MAKEMASK(4,S_DUART_IN_PIN_CHNG)
+
+/*
+ * DUART Output port control register (Table 10-14)
+ * Register: DUART_OPCR
+ */
+
+#define M_DUART_OPCR_RESERVED0      _SB_MAKEMASK1(0)   /* must be zero */
+#define M_DUART_OPC2_SEL            _SB_MAKEMASK1(1)
+#define M_DUART_OPCR_RESERVED1      _SB_MAKEMASK1(2)   /* must be zero */
+#define M_DUART_OPC3_SEL            _SB_MAKEMASK1(3)
+#define M_DUART_OPCR_RESERVED2      _SB_MAKEMASK(4,4)  /* must be zero */
+
+/*
+ * DUART Aux Control Register (Table 10-15)
+ * Register: DUART_AUX_CTRL
+ */
+
+#define M_DUART_IP0_CHNG_ENA        _SB_MAKEMASK1(0)
+#define M_DUART_IP1_CHNG_ENA        _SB_MAKEMASK1(1)
+#define M_DUART_IP2_CHNG_ENA        _SB_MAKEMASK1(2)
+#define M_DUART_IP3_CHNG_ENA        _SB_MAKEMASK1(3)
+#define M_DUART_ACR_RESERVED        _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Interrupt Status Register (Table 10-16)
+ * Register: DUART_ISR
+ */
+
+#define M_DUART_ISR_TX_A            _SB_MAKEMASK1(0)
+#define M_DUART_ISR_RX_A            _SB_MAKEMASK1(1)
+#define M_DUART_ISR_BRK_A           _SB_MAKEMASK1(2)
+#define M_DUART_ISR_IN_A            _SB_MAKEMASK1(3)
+#define M_DUART_ISR_TX_B            _SB_MAKEMASK1(4)
+#define M_DUART_ISR_RX_B            _SB_MAKEMASK1(5)
+#define M_DUART_ISR_BRK_B           _SB_MAKEMASK1(6)
+#define M_DUART_ISR_IN_B            _SB_MAKEMASK1(7)
+
+/*
+ * DUART Channel A Interrupt Status Register (Table 10-17)
+ * DUART Channel B Interrupt Status Register (Table 10-18)
+ * Register: DUART_ISR_A
+ * Register: DUART_ISR_B
+ */
+
+#define M_DUART_ISR_TX              _SB_MAKEMASK1(0)
+#define M_DUART_ISR_RX              _SB_MAKEMASK1(1)
+#define M_DUART_ISR_BRK             _SB_MAKEMASK1(2)
+#define M_DUART_ISR_IN              _SB_MAKEMASK1(3)
+#define M_DUART_ISR_RESERVED        _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Interrupt Mask Register (Table 10-19)
+ * Register: DUART_IMR
+ */
+
+#define M_DUART_IMR_TX_A            _SB_MAKEMASK1(0)
+#define M_DUART_IMR_RX_A            _SB_MAKEMASK1(1)
+#define M_DUART_IMR_BRK_A           _SB_MAKEMASK1(2)
+#define M_DUART_IMR_IN_A            _SB_MAKEMASK1(3)
+#define M_DUART_IMR_ALL_A	    _SB_MAKEMASK(4,0)
+
+#define M_DUART_IMR_TX_B            _SB_MAKEMASK1(4)
+#define M_DUART_IMR_RX_B            _SB_MAKEMASK1(5)
+#define M_DUART_IMR_BRK_B           _SB_MAKEMASK1(6)
+#define M_DUART_IMR_IN_B            _SB_MAKEMASK1(7)
+#define M_DUART_IMR_ALL_B           _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Channel A Interrupt Mask Register (Table 10-20)
+ * DUART Channel B Interrupt Mask Register (Table 10-21)
+ * Register: DUART_IMR_A
+ * Register: DUART_IMR_B
+ */
+
+#define M_DUART_IMR_TX              _SB_MAKEMASK1(0)
+#define M_DUART_IMR_RX              _SB_MAKEMASK1(1)
+#define M_DUART_IMR_BRK             _SB_MAKEMASK1(2)
+#define M_DUART_IMR_IN              _SB_MAKEMASK1(3)
+#define M_DUART_IMR_ALL		    _SB_MAKEMASK(4,0)
+#define M_DUART_IMR_RESERVED        _SB_MAKEMASK(4,4)
+
+
+/*
+ * DUART Output Port Set Register (Table 10-22)
+ * Register: DUART_SET_OPR
+ */
+
+#define M_DUART_SET_OPR0            _SB_MAKEMASK1(0)
+#define M_DUART_SET_OPR1            _SB_MAKEMASK1(1)
+#define M_DUART_SET_OPR2            _SB_MAKEMASK1(2)
+#define M_DUART_SET_OPR3            _SB_MAKEMASK1(3)
+#define M_DUART_OPSR_RESERVED       _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Output Port Clear Register (Table 10-23)
+ * Register: DUART_CLEAR_OPR
+ */
+
+#define M_DUART_CLR_OPR0            _SB_MAKEMASK1(0)
+#define M_DUART_CLR_OPR1            _SB_MAKEMASK1(1)
+#define M_DUART_CLR_OPR2            _SB_MAKEMASK1(2)
+#define M_DUART_CLR_OPR3            _SB_MAKEMASK1(3)
+#define M_DUART_OPCR_RESERVED       _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Output Port RTS Register (Table 10-24)
+ * Register: DUART_OUT_PORT
+ */
+
+#define M_DUART_OUT_PIN_SET0        _SB_MAKEMASK1(0)
+#define M_DUART_OUT_PIN_SET1        _SB_MAKEMASK1(1)
+#define M_DUART_OUT_PIN_CLR0        _SB_MAKEMASK1(2)
+#define M_DUART_OUT_PIN_CLR1        _SB_MAKEMASK1(3)
+#define M_DUART_OPRR_RESERVED       _SB_MAKEMASK(4,4)
+
+#define M_DUART_OUT_PIN_SET(chan) \
+    (chan == 0 ? M_DUART_OUT_PIN_SET0 : M_DUART_OUT_PIN_SET1)
+#define M_DUART_OUT_PIN_CLR(chan) \
+    (chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1)
+
+/*
+ * XXX To be added: Synchronous Serial definitions
+ */
+
+/* ********************************************************************** */
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/swarm.h linux/include/asm-mips/sibyte/swarm.h
--- linux.orig/include/asm-mips/sibyte/swarm.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/swarm.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+#ifndef _ASM_SIBYTE_SWARM_H
+#define _ASM_SIBYTE_SWARM_H
+
+#define KERNEL_RESERVED_MEM 0x100000
+#define LED_BASE_ADDR 0x100a0020
+
+void swarm_setup(void);
+
+void setleds(char *str); 
+
+#endif /* _ASM_SIBYTE_SWARM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sibyte/swarm_ide.h linux/include/asm-mips/sibyte/swarm_ide.h
--- linux.orig/include/asm-mips/sibyte/swarm_ide.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/sibyte/swarm_ide.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+#ifndef _SWARM_IDE_H
+#define _SWARM_IDE_H
+
+#include <asm/sibyte/sb1250_int.h>
+
+#define SWARM_IDE_BASE        (0xb00b0000-mips_io_port_base)
+#define SWARM_IDE_REG(pcaddr) (SWARM_IDE_BASE + ((pcaddr)<<5))
+#define SWARM_IDE_INT         (K_INT_GPIO_4)
+
+extern ide_ideproc_t swarm_ideproc;
+
+#define swarm_outb(val,port)							\
+do {									\
+	*(volatile u8 *)(mips_io_port_base + (port)) = val;	\
+} while(0)
+
+#define swarm_outw(val,port)							\
+do {									\
+	*(volatile u16 *)(mips_io_port_base + (port)) = val;	\
+} while(0)
+
+#define swarm_outl(val,port)							\
+do {									\
+	*(volatile u32 *)(mips_io_port_base + (port)) = val;\
+} while(0)
+
+static inline unsigned char swarm_inb(unsigned long port)
+{
+	return (*(volatile u8 *)(mips_io_port_base + port));
+}
+
+static inline unsigned short swarm_inw(unsigned long port)
+{
+	return (*(volatile u16 *)(mips_io_port_base + port));
+}
+
+static inline unsigned int swarm_inl(unsigned long port)
+{
+	return (*(volatile u32 *)(mips_io_port_base + port));
+}
+
+
+static inline void swarm_outsb(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		swarm_outb(*(u8 *)addr, port);
+		addr++;
+	}
+}
+
+static inline void swarm_insb(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u8 *)addr = swarm_inb(port);
+		addr++;
+	}
+}
+
+static inline void swarm_outsw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		swarm_outw(*(u16 *)addr, port);
+		addr += 2;
+	}
+}
+
+static inline void swarm_insw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u16 *)addr = swarm_inw(port);
+		addr += 2;
+	}
+}
+
+static inline void swarm_outsl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		swarm_outl(*(u32 *)addr, port);
+		addr += 4;
+	}
+}
+
+static inline void swarm_insl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u32 *)addr = swarm_inl(port);
+		addr += 4;
+	}
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sigcontext.h linux/include/asm-mips/sigcontext.h
--- linux.orig/include/asm-mips/sigcontext.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/sigcontext.h	2002-07-20 01:08:37.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: sigcontext.h,v 1.5 1997/12/16 05:36:43 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -18,10 +17,11 @@
 	unsigned int       sc_status;
 	unsigned long long sc_pc;
 	unsigned long long sc_regs[32];
-	unsigned long long sc_fpregs[32];	/* Unused */
+	unsigned long long sc_fpregs[32];
 	unsigned int       sc_ownedfp;
-	unsigned int       sc_fpc_csr;		/* Unused */
+	unsigned int       sc_fpc_csr;
 	unsigned int       sc_fpc_eir;		/* Unused */
+	unsigned int       sc_used_math;
 	unsigned int       sc_ssflags;		/* Unused */
 	unsigned long long sc_mdhi;
 	unsigned long long sc_mdlo;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/siginfo.h linux/include/asm-mips/siginfo.h
--- linux.orig/include/asm-mips/siginfo.h	2000-05-25 01:38:26.000000000 +0000
+++ linux/include/asm-mips/siginfo.h	2002-07-20 01:08:37.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: siginfo.h,v 1.5 1999/08/18 23:37:49 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -127,6 +126,7 @@
 #define SI_TIMER __SI_CODE(__SI_TIMER,-3) /* sent by timer expiration */
 #define SI_MESGQ	-4	/* sent by real time mesq state change */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
+#define SI_TKILL	-6	/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
@@ -238,7 +238,7 @@
 #ifdef __KERNEL__
 #include <linux/string.h>
 
-extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+static inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
 {
 	if (from->si_code < 0)
 		memcpy(to, from, sizeof(siginfo_t));
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/signal.h linux/include/asm-mips/signal.h
--- linux.orig/include/asm-mips/signal.h	2000-07-10 05:18:15.000000000 +0000
+++ linux/include/asm-mips/signal.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: signal.h,v 1.6 1999/08/18 23:37:49 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/smp.h linux/include/asm-mips/smp.h
--- linux.orig/include/asm-mips/smp.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/smp.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */ 
+
 #ifndef __ASM_MIPS_SMP_H
 #define __ASM_MIPS_SMP_H
 
@@ -6,32 +24,74 @@
 #ifdef CONFIG_SMP
 
 #include <asm/spinlock.h>
+#include <linux/threads.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
 
-
-/* Mappings are straight across.  If we want
-   to add support for disabling cpus and such,
-   we'll have to do what the mips64 port does here */
-#define cpu_logical_map(cpu)	(cpu)
-#define cpu_number_map(cpu)     (cpu)
-
 #define smp_processor_id()  (current->processor)
 
-
-/* I've no idea what the real meaning of this is */
 #define PROC_CHANGE_PENALTY	20
 
+/* Map from cpu id to sequential logical cpu number.  This will only
+   not be idempotent when cpus failed to come on-line.  */
+extern int __cpu_number_map[NR_CPUS];
+#define cpu_number_map(cpu)  __cpu_number_map[cpu]
+
+/* The reverse map from sequential logical cpu number to cpu id.  */
+extern int __cpu_logical_map[NR_CPUS];
+#define cpu_logical_map(cpu)  __cpu_logical_map[cpu]
+
 #define NO_PROC_ID	(-1)
 
-struct smp_fn_call_struct {
-	spinlock_t lock;
-	atomic_t   finished;
-	void (*fn)(void *);
-	void *data;
+struct call_data_struct {
+	void		(*func)(void *);
+	void		*info;
+	atomic_t	started;
+	atomic_t	finished;
+	int		wait;
 };
 
-extern struct smp_fn_call_struct smp_fn_call;
+extern struct call_data_struct *call_data;
+
+/* ipi types that boards must handle, one bit per type   */
+#define SMP_RESCHEDULE_YOURSELF	0x1	/* XXX braindead */
+#define SMP_CALL_FUNCTION	0x2
+
+#if (NR_CPUS <= _MIPS_SZLONG)
+
+typedef unsigned long   cpumask_t;
+
+#define CPUMASK_CLRALL(p)	(p) = 0
+#define CPUMASK_SETB(p, bit)	(p) |= 1 << (bit)
+#define CPUMASK_CLRB(p, bit)	(p) &= ~(1ULL << (bit))
+#define CPUMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
+
+#elif (NR_CPUS <= 128)
+
+/*
+ * The foll should work till 128 cpus.
+ */
+#define CPUMASK_SIZE		(NR_CPUS/_MIPS_SZLONG)
+#define CPUMASK_INDEX(bit)	((bit) >> 6)
+#define CPUMASK_SHFT(bit)	((bit) & 0x3f)
+
+typedef struct {
+	unsigned long	_bits[CPUMASK_SIZE];
+} cpumask_t;
+
+#define	CPUMASK_CLRALL(p)	(p)._bits[0] = 0, (p)._bits[1] = 0
+#define CPUMASK_SETB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] |= \
+					(1ULL << CPUMASK_SHFT(bit))
+#define CPUMASK_CLRB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] &= \
+					~(1ULL << CPUMASK_SHFT(bit))
+#define CPUMASK_TSTB(p, bit)	((p)._bits[CPUMASK_INDEX(bit)] & \
+					(1ULL << CPUMASK_SHFT(bit)))
+
+#else
+#error cpumask macros only defined for 128p kernels
+#endif
+
+extern cpumask_t cpu_online_map;
 
 #endif /* CONFIG_SMP */
 #endif /* __ASM_MIPS_SMP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/smplock.h linux/include/asm-mips/smplock.h
--- linux.orig/include/asm-mips/smplock.h	2000-03-23 20:50:09.000000000 +0000
+++ linux/include/asm-mips/smplock.h	2002-07-20 01:08:30.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: smplock.h,v 1.2 1999/10/09 00:01:43 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/sni.h linux/include/asm-mips/sni.h
--- linux.orig/include/asm-mips/sni.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/sni.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: sni.h,v 1.2 1998/09/19 19:19:39 ralf Exp $
- *
+/*
  * SNI specific definitions
  *
  * This file is subject to the terms and conditions of the GNU General Public
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/softirq.h linux/include/asm-mips/softirq.h
--- linux.orig/include/asm-mips/softirq.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/softirq.h	2002-07-20 01:08:38.000000000 +0000
@@ -13,13 +13,13 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-extern inline void cpu_bh_disable(int cpu)
+static inline void cpu_bh_disable(int cpu)
 {
 	local_bh_count(cpu)++;
 	barrier();
 }
  
-extern inline void __cpu_bh_enable(int cpu)
+static inline void __cpu_bh_enable(int cpu)
 {
 	barrier();
 	local_bh_count(cpu)--;
@@ -40,6 +40,4 @@
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
-#define __cpu_raise_softirq(cpu, nr)	set_bit(nr, &softirq_pending(cpu))
-
 #endif /* _ASM_SOFTIRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/spinlock.h linux/include/asm-mips/spinlock.h
--- linux.orig/include/asm-mips/spinlock.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/spinlock.h	2002-07-20 01:08:40.000000000 +0000
@@ -19,10 +19,10 @@
 
 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
 
-#define spin_lock_init(x)	do { (x)->lock = 0; } while(0);
+#define spin_lock_init(x)	do { (x)->lock = 0; } while(0)
 
 #define spin_is_locked(x)	((x)->lock != 0)
-#define spin_unlock_wait(x)	({ do { barrier(); } while ((x)->lock); })
+#define spin_unlock_wait(x)	do { barrier(); } while ((x)->lock)
 
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
@@ -44,8 +44,8 @@
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
 	".set\treorder"
-	: "=o" (lock->lock), "=&r" (tmp)
-	: "o" (lock->lock)
+	: "=m" (lock->lock), "=&r" (tmp)
+	: "m" (lock->lock)
 	: "memory");
 }
 
@@ -56,8 +56,8 @@
 	"sync\n\t"
 	"sw\t$0, %0\n\t"
 	".set\treorder"	
-	: "=o" (lock->lock)
-	: "o" (lock->lock)
+	: "=m" (lock->lock)
+	: "m" (lock->lock)
 	: "memory");
 }
 
@@ -78,6 +78,8 @@
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
+#define rwlock_init(x)  do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+
 static inline void read_lock(rwlock_t *rw)
 {
 	unsigned int tmp;
@@ -91,8 +93,8 @@
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
 	".set\treorder"	
-	: "=o" (rw->lock), "=&r" (tmp)
-	: "o" (rw->lock)
+	: "=m" (rw->lock), "=&r" (tmp)
+	: "m" (rw->lock)
 	: "memory");
 }
 
@@ -109,9 +111,10 @@
 	"sub\t%1, 1\n\t"
 	"sc\t%1, %0\n\t"
 	"beqz\t%1, 1b\n\t"
+	" sync\n\t"
 	".set\treorder"	
-	: "=o" (rw->lock), "=&r" (tmp)
-	: "o" (rw->lock)
+	: "=m" (rw->lock), "=&r" (tmp)
+	: "m" (rw->lock)
 	: "memory");
 }
 
@@ -128,8 +131,8 @@
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
 	".set\treorder"	
-	: "=o" (rw->lock), "=&r" (tmp)
-	: "o" (rw->lock)
+	: "=m" (rw->lock), "=&r" (tmp)
+	: "m" (rw->lock)
 	: "memory");
 }
 
@@ -140,8 +143,8 @@
 	"sync\n\t"
 	"sw\t$0, %0\n\t"
 	".set\treorder"	
-	: "=o" (rw->lock)
-	: "o" (rw->lock)
+	: "=m" (rw->lock)
+	: "m" (rw->lock)
 	: "memory");
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/stackframe.h linux/include/asm-mips/stackframe.h
--- linux.orig/include/asm-mips/stackframe.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/stackframe.h	2002-07-20 01:08:22.000000000 +0000
@@ -9,12 +9,12 @@
 #ifndef __ASM_STACKFRAME_H
 #define __ASM_STACKFRAME_H
 
+#include <linux/config.h>
 #include <asm/addrspace.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
 #include <asm/asm.h>
 #include <asm/offset.h>
-#include <linux/config.h>
 
 #define SAVE_AT                                          \
 		.set	push;                            \
@@ -48,33 +48,6 @@
 		sw	$23, PT_R23(sp);                 \
 		sw	$30, PT_R30(sp)
 
-#define __str2(x) #x
-#define __str(x) __str2(x)
-
-#define save_static_function(symbol)                                    \
-__asm__ (                                                               \
-        ".globl\t" #symbol "\n\t"                                       \
-        ".align\t2\n\t"                                                 \
-        ".type\t" #symbol ", @function\n\t"                             \
-        ".ent\t" #symbol ", 0\n"                                        \
-        #symbol":\n\t"                                                  \
-        ".frame\t$29, 0, $31\n\t"                                       \
-        "sw\t$16,"__str(PT_R16)"($29)\t\t\t# save_static_function\n\t"  \
-        "sw\t$17,"__str(PT_R17)"($29)\n\t"                              \
-        "sw\t$18,"__str(PT_R18)"($29)\n\t"                              \
-        "sw\t$19,"__str(PT_R19)"($29)\n\t"                              \
-        "sw\t$20,"__str(PT_R20)"($29)\n\t"                              \
-        "sw\t$21,"__str(PT_R21)"($29)\n\t"                              \
-        "sw\t$22,"__str(PT_R22)"($29)\n\t"                              \
-        "sw\t$23,"__str(PT_R23)"($29)\n\t"                              \
-        "sw\t$30,"__str(PT_R30)"($29)\n\t"                              \
-        ".end\t" #symbol "\n\t"                                         \
-        ".size\t" #symbol",. - " #symbol)
-
-/* Used in declaration of save_static functions.  */
-#define static_unused static __attribute__((unused))
-
-
 #ifdef CONFIG_SMP
 #  define GET_SAVED_SP                                   \
                 mfc0    k0, CP0_CONTEXT;                 \
@@ -163,7 +136,7 @@
 		lw	$23, PT_R23(sp);                 \
 		lw	$30, PT_R30(sp)
 
-#if defined(CONFIG_CPU_R3000)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
 #define RESTORE_SOME                                     \
 		.set	push;                            \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/string.h linux/include/asm-mips/string.h
--- linux.orig/include/asm-mips/string.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/string.h	2002-07-20 01:08:21.000000000 +0000
@@ -28,7 +28,7 @@
 	".set\treorder"
 	: "=r" (__dest), "=r" (__src)
         : "0" (__dest), "1" (__src)
-	: "$1","memory");
+	: "memory");
 
   return __xdest;
 }
@@ -56,7 +56,7 @@
 	".set\treorder"
         : "=r" (__dest), "=r" (__src), "=r" (__n)
         : "0" (__dest), "1" (__src), "2" (__n)
-        : "$1","memory");
+        : "memory");
 
   return __dest;
 }
@@ -84,8 +84,7 @@
 	"3:\t.set\tat\n\t"
 	".set\treorder"
 	: "=r" (__cs), "=r" (__ct), "=r" (__res)
-	: "0" (__cs), "1" (__ct)
-	: "$1");
+	: "0" (__cs), "1" (__ct));
 
   return __res;
 }
@@ -116,8 +115,7 @@
 	".set\tat\n\t"
 	".set\treorder"
 	: "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res)
-	: "0" (__cs), "1" (__ct), "2" (__count)
-	: "$1");
+	: "0" (__cs), "1" (__ct), "2" (__count));
 
 	return __res;
 }
@@ -138,18 +136,18 @@
 extern __inline__ void *memscan(void *__addr, int __c, size_t __size)
 {
 	char *__end = (char *)__addr + __size;
+	unsigned char __uc = (unsigned char) __c;
 
 	__asm__(".set\tpush\n\t"
 		".set\tnoat\n\t"
 		".set\treorder\n\t"
 		"1:\tbeq\t%0,%1,2f\n\t"
 		"addiu\t%0,1\n\t"
-		"lb\t$1,-1(%0)\n\t"
+		"lbu\t$1,-1(%0)\n\t"
 		"bne\t$1,%z4,1b\n"
 		"2:\t.set\tpop"
 		: "=r" (__addr), "=r" (__end)
-		: "0" (__addr), "1" (__end), "Jr" (__c)
-		: "$1");
+		: "0" (__addr), "1" (__end), "Jr" (__uc));
 
 	return __addr;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/system.h linux/include/asm-mips/system.h
--- linux.orig/include/asm-mips/system.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/system.h	2002-07-20 01:08:34.000000000 +0000
@@ -21,98 +21,121 @@
 #include <asm/ptrace.h>
 #include <linux/kernel.h>
 
+__asm__ (
+	".macro\t__sti\n\t"
+	".set\tpush\n\t"
+	".set\treorder\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t$1,$12\n\t"
+	"ori\t$1,0x1f\n\t"
+	"xori\t$1,0x1e\n\t"
+	"mtc0\t$1,$12\n\t"
+	".set\tpop\n\t"
+	".endm");
+
 extern __inline__ void
 __sti(void)
 {
 	__asm__ __volatile__(
-		".set\tpush\n\t"
-		".set\treorder\n\t"
-		".set\tnoat\n\t"
-		"mfc0\t$1,$12\n\t"
-		"ori\t$1,0x1f\n\t"
-		"xori\t$1,0x1e\n\t"
-		"mtc0\t$1,$12\n\t"
-		".set\tpop\n\t"
+		"__sti"
 		: /* no outputs */
 		: /* no inputs */
-		: "$1", "memory");
+		: "memory");
 }
 
 /*
- * For cli() we have to insert nops to make shure that the new value
+ * For cli() we have to insert nops to make sure that the new value
  * has actually arrived in the status register before the end of this
  * macro.
  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
  * no nops at all.
  */
+__asm__ (
+	".macro\t__cli\n\t"
+	".set\tpush\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t$1,$12\n\t"
+	"ori\t$1,1\n\t"
+	"xori\t$1,1\n\t"
+	".set\tnoreorder\n\t"
+	"mtc0\t$1,$12\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	".set\tpop\n\t"
+	".endm");
+
 extern __inline__ void
 __cli(void)
 {
 	__asm__ __volatile__(
-		".set\tpush\n\t"
-		".set\treorder\n\t"
-		".set\tnoat\n\t"
-		"mfc0\t$1,$12\n\t"
-		"ori\t$1,1\n\t"
-		"xori\t$1,1\n\t"
-		".set\tnoreorder\n\t"
-		"mtc0\t$1,$12\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		".set\tpop\n\t"
+		"__cli"
 		: /* no outputs */
 		: /* no inputs */
-		: "$1", "memory");
+		: "memory");
 }
 
+__asm__ (
+	".macro\t__save_flags flags\n\t"
+	".set\tpush\n\t"
+	".set\treorder\n\t"
+	"mfc0\t\\flags, $12\n\t"
+	".set\tpop\n\t"
+	".endm");
+
 #define __save_flags(x)							\
 __asm__ __volatile__(							\
-	".set\tpush\n\t"						\
-	".set\treorder\n\t"						\
-	"mfc0\t%0,$12\n\t"						\
-	".set\tpop\n\t"							\
+	"__save_flags %0"						\
 	: "=r" (x))
 
+__asm__ (
+	".macro\t__save_and_cli result\n\t"
+	".set\tpush\n\t"
+	".set\treorder\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t\\result, $12\n\t"
+	"ori\t$1, \\result, 1\n\t"
+	"xori\t$1, 1\n\t"
+	".set\tnoreorder\n\t"
+	"mtc0\t$1, $12\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	".set\tpop\n\t"	
+	".endm");
+
 #define __save_and_cli(x)						\
 __asm__ __volatile__(							\
-	".set\tpush\n\t"						\
-	".set\treorder\n\t"						\
-	".set\tnoat\n\t"						\
-	"mfc0\t%0,$12\n\t"						\
-	"ori\t$1,%0,1\n\t"						\
-	"xori\t$1,1\n\t"						\
-	".set\tnoreorder\n\t"						\
-	"mtc0\t$1,$12\n\t"						\
-	"nop\n\t"							\
-	"nop\n\t"							\
-	"nop\n\t"							\
-	".set\tpop\n\t"							\
+	"__save_and_cli\t%0"						\
 	: "=r" (x)							\
 	: /* no inputs */						\
-	: "$1", "memory")
+	: "memory")
+
+__asm__(".macro\t__restore_flags flags\n\t"
+	".set\tnoreorder\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t$1, $12\n\t"
+	"andi\t\\flags, 1\n\t"
+	"ori\t$1, 1\n\t"
+	"xori\t$1, 1\n\t"
+	"or\t\\flags, $1\n\t"
+	"mtc0\t\\flags, $12\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	".set\tat\n\t"
+	".set\treorder\n\t"
+	".endm");
 
 #define __restore_flags(flags)						\
 do {									\
 	unsigned long __tmp1;						\
 									\
 	__asm__ __volatile__(						\
-		".set\tnoreorder\t\t\t# __restore_flags\n\t"		\
-		".set\tnoat\n\t"					\
-		"mfc0\t$1, $12\n\t"					\
-		"andi\t%0, 1\n\t"					\
-		"ori\t$1, 1\n\t"					\
-		"xori\t$1, 1\n\t"					\
-		"or\t%0, $1\n\t"					\
-		"mtc0\t%0, $12\n\t"					\
-		"nop\n\t"						\
-		"nop\n\t"						\
-		"nop\n\t"						\
-		".set\tat\n\t"						\
-		".set\treorder"						\
+		"__restore_flags\t%0"					\
 		: "=r" (__tmp1)						\
 		: "0" (flags)						\
-		: "$1", "memory");					\
+		: "memory");						\
 } while(0)
 
 #ifdef CONFIG_SMP
@@ -138,10 +161,10 @@
 #endif /* SMP */
 
 /* For spinlocks etc */
-#define local_irq_save(x)	__save_and_cli(x);
-#define local_irq_restore(x)	__restore_flags(x);
-#define local_irq_disable()	__cli();
-#define local_irq_enable()	__sti();
+#define local_irq_save(x)	__save_and_cli(x)
+#define local_irq_restore(x)	__restore_flags(x)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
 
 /*
  * These are probably defined overly paranoid ...
@@ -186,13 +209,13 @@
 #define set_wmb(var, value) \
 do { var = value; wmb(); } while (0)
 
-#if !defined (_LANGUAGE_ASSEMBLY)
+#ifndef __ASSEMBLY__
 /*
  * switch_to(n) should switch tasks to task nr n, first
  * checking that n isn't the current task, in which case it does nothing.
  */
 extern asmlinkage void *resume(void *last, void *next);
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* !__ASSEMBLY__ */
 
 #define prepare_to_switch()	do { } while(0)
 #define switch_to(prev,next,last) \
@@ -210,17 +233,18 @@
 	unsigned long dummy;
 
 	__asm__ __volatile__(
-		".set\tnoreorder\t\t\t# xchg_u32\n\t"
-		".set\tnoat\n\t"
+		".set\tpush\t\t\t\t# xchg_u32\n\t"
+		".set\tnoreorder\n\t"
+		".set\tnomacro\n\t"
 		"ll\t%0, %3\n"
-		"1:\tmove\t$1, %2\n\t"
-		"sc\t$1, %1\n\t"
-		"beqzl\t$1, 1b\n\t"
+		"1:\tmove\t%2, %z4\n\t"
+		"sc\t%2, %1\n\t"
+		"beqzl\t%2, 1b\n\t"
 		" ll\t%0, %3\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (val), "=o" (*m), "=r" (dummy)
-		: "o" (*m), "2" (val)
+		"sync\n\t"
+		".set\tpop"
+		: "=&r" (val), "=m" (*m), "=&r" (dummy)
+		: "R" (*m), "Jr" (val)
 		: "memory");
 
 	return val;
@@ -231,7 +255,7 @@
 	cli();
 	retval = *m;
 	*m = val;
-	restore_flags(flags);
+	restore_flags(flags);	/* implies memory barrier  */
 	return retval;
 #endif /* Processor-dependent optimization */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/time.h linux/include/asm-mips/time.h
--- linux.orig/include/asm-mips/time.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/time.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001 MontaVista Software Inc.
+ * Copyright (C) 2001, 2002, MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
  * include/asm-mips/time.h
@@ -61,6 +61,12 @@
 asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs);
 
 /*
+ * profiling and process accouting is done separately in local_timer_interrupt
+ */
+void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
+
+/*
  * board specific routines required by time_init().
  * board_time_init is defaulted to NULL and can remains so.
  * board_timer_setup must be setup properly in machine setup routine.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/timex.h linux/include/asm-mips/timex.h
--- linux.orig/include/asm-mips/timex.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/timex.h	2002-07-20 01:08:39.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: timex.h,v 1.1 1998/08/25 09:22:03 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/traps.h linux/include/asm-mips/traps.h
--- linux.orig/include/asm-mips/traps.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/traps.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,27 @@
+/*
+ *	include/asm-mips/traps.h
+ *
+ *	Trap handling definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	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.
+ */
+#ifndef __ASM_MIPS_TRAPS_H
+#define __ASM_MIPS_TRAPS_H
+
+/*
+ * Possible status responses for a be_board_handler backend.
+ */
+#define MIPS_BE_DISCARD	0		/* return with no action */
+#define MIPS_BE_FIXUP	1		/* return to the fixup code */
+#define MIPS_BE_FATAL	2		/* treat as an unrecoverable error */
+
+extern int (*be_board_handler)(struct pt_regs *regs, int is_fixup);
+
+extern void bus_error_init(void);
+
+#endif /* __ASM_MIPS_TRAPS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/tx3912.h linux/include/asm-mips/tx3912.h
--- linux.orig/include/asm-mips/tx3912.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/tx3912.h	2002-07-20 01:08:40.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  linux/include/asm-mips/tx3912.h
+ *  include/asm-mips/tx3912.h
  *
  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
  *
@@ -7,562 +7,355 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- *  Register includes for TMPR3912/05 and PR31700 processors
+ *  Registers for TMPR3912/05 and PR31700 processors
  */
-#ifndef __TX3912_H__
-#define __TX3912_H__
+#ifndef _TX3912_H_
+#define _TX3912_H_
 
-#include <asm/addrspace.h>
+/*****************************************************************************
+ *	Clock Subsystem                                                      *
+ *	---------------                                                      *
+ *	Chapter 6 in Philips PR31700 and Toshiba TMPR3905/12 User Manuals    *
+ *****************************************************************************/
+#define TX3912_CLK_CTRL					0x01c0
 
-/******************************************************************************
-*
-* 	01  General macro definitions
-*
-******************************************************************************/
-
-#define REGISTER_BASE   0xb0c00000
-
-#ifndef _LANGUAGE_ASSEMBLY
-
-	#define REG_AT(x)	(*((volatile unsigned long *)(REGISTER_BASE + x)))
-
-#else
-
-	#define REG_AT(x)   (REGISTER_BASE + x)
-
-#endif
-
-#define BIT(x)	(1 << x)
-
-/******************************************************************************
-*
-* 	02  Bus Interface Unit
-*
-******************************************************************************/
-
-#define MemConfig0    REG_AT(0x000)
-#define MemConfig1    REG_AT(0x004)
-#define MemConfig2    REG_AT(0x008)
-#define MemConfig3    REG_AT(0x00c)
-#define MemConfig4    REG_AT(0x010)
-#define MemConfig5    REG_AT(0x014)
-#define MemConfig6    REG_AT(0x018)
-#define MemConfig7    REG_AT(0x01c)
-#define MemConfig8    REG_AT(0x020)
-
-/* Memory config register 1 */
-#define MEM1_ENCS1USER	BIT(21)
-
-/* Memory config register 3 */
-#define MEM3_CARD1ACCVAL_MASK	(BIT(24) | BIT(25) | BIT(26) | BIT(27))
-#define MEM3_CARD1IOEN		BIT(4)
-
-/* Memory config register 4 */
-#define MEM4_ARBITRATIONEN	BIT(29)
-#define MEM4_MEMPOWERDOWN	BIT(16)
-#define MEM4_ENREFRESH1		BIT(15)
-#define MEM4_ENREFRESH0		BIT(14)
-#define MEM4_ENWATCH            BIT(24)
-#define MEM4_WATCHTIMEVAL_MASK  (0xf)
-#define MEM4_WATCHTIMEVAL_SHIFT (20)
-#define MEM4_WATCHTIME_VALUE    (0xf)
-
-/*
- ***********************************************************************
- *								       *
- * 06  Clock Module						       *
- *								       *
- ***********************************************************************
- */
-#define TX3912_CLK_CTRL_BASE			(REGISTER_BASE + 0x1c0)
-
-#define TX3912_CLK_CTRL_CHICLKDIV_MASK		0xff000000
-#define TX3912_CLK_CTRL_CHICLKDIV_SHIFT		24
-#define TX3912_CLK_CTRL_ENCLKTEST		0x00800000
-#define TX3912_CLK_CTRL_CLKTESTSELSIB		0x00400000
-#define TX3912_CLK_CTRL_CHIMCLKSEL		0x00200000
-#define TX3912_CLK_CTRL_CHICLKDIR		0x00100000
-#define TX3912_CLK_CTRL_ENCHIMCLK		0x00080000
-#define TX3912_CLK_CTRL_ENVIDCLK		0x00040000
-#define TX3912_CLK_CTRL_ENMBUSCLK		0x00020000
-#define TX3912_CLK_CTRL_ENSPICLK		0x00010000
-#define TX3912_CLK_CTRL_ENTIMERCLK		0x00008000
-#define TX3912_CLK_CTRL_ENFASTTIMERCLK		0x00004000
-#define TX3912_CLK_CTRL_SIBMCLKDIR		0x00002000
-#define TX3912_CLK_CTRL_RESERVED		0x00001000
-#define TX3912_CLK_CTRL_ENSIBMCLK		0x00000800
-#define TX3912_CLK_CTRL_SIBMCLKDIV_MASK		0x00000700
-#define TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT	8
-#define TX3912_CLK_CTRL_CSERSEL			0x00000080
-#define TX3912_CLK_CTRL_CSERDIV_MASK		0x00000070
-#define TX3912_CLK_CTRL_CSERDIV_SHIFT		4
-#define TX3912_CLK_CTRL_ENCSERCLK		0x00000008
-#define TX3912_CLK_CTRL_ENIRCLK			0x00000004
-#define TX3912_CLK_CTRL_ENUARTACLK		0x00000002
-#define TX3912_CLK_CTRL_ENUARTBCLK		0x00000001
-
-
-
-
-/******************************************************************************
-*
-* 	07  CHI module
-*
-******************************************************************************/
-
-#define CHIControl		REG_AT(0x1D8)
-#define CHIPointerEnable	REG_AT(0x1DC)
-#define CHIReceivePtrA		REG_AT(0x1E0)
-#define CHIReceivePtrB		REG_AT(0x1E4)
-#define CHITransmitPtrA		REG_AT(0x1E8)
-#define CHITransmitPtrB		REG_AT(0x1EC)
-#define CHISize			REG_AT(0x1F0)
-#define CHIReceiveStart		REG_AT(0x1F4)
-#define CHITransmitStart	REG_AT(0x1F8)
-#define CHIHoldingReg		REG_AT(0x1FC)
-
-/* CHI Control Register */
-/* <incomplete!> */
-#define	CHI_RXEN		BIT(2)
-#define	CHI_TXEN		BIT(1)
-#define	CHI_ENCHI		BIT(0)
-
-/******************************************************************************
-*
-*	08  Interrupt module
-*
-******************************************************************************/
-
-/* Register locations */
-
-#define IntStatus1    REG_AT(0x100)
-#define IntStatus2    REG_AT(0x104)
-#define IntStatus3    REG_AT(0x108)
-#define IntStatus4    REG_AT(0x10c)
-#define IntStatus5    REG_AT(0x110)
-#define IntStatus6    REG_AT(0x114)
-
-#define IntClear1     REG_AT(0x100)
-#define IntClear2     REG_AT(0x104)
-#define IntClear3     REG_AT(0x108)
-#define IntClear4     REG_AT(0x10c)
-#define IntClear5     REG_AT(0x110)
-#define IntClear6     REG_AT(0x114)
-
-#define IntEnable1    REG_AT(0x118)
-#define IntEnable2    REG_AT(0x11c)
-#define IntEnable3    REG_AT(0x120)
-#define IntEnable4    REG_AT(0x124)
-#define IntEnable5    REG_AT(0x128)
-#define IntEnable6    REG_AT(0x12c)
-
-/* Interrupt Status Register 1 at offset 100 */
-#define INT1_LCDINT		BIT(31)
-#define INT1_DFINT              BIT(30)
-#define INT1_CHIDMAHALF		BIT(29)
-#define INT1_CHIDMAFULL		BIT(28)
-#define INT1_CHIDMACNTINT       BIT(27)
-#define INT1_CHIRXAINT		BIT(26)
-#define INT1_CHIRXBINT		BIT(25)
-#define INT1_CHIACTINT          BIT(24)
-#define INT1_CHIERRINT          BIT(23)
-#define INT1_SND0_5INT          BIT(22)
-#define INT1_SND1_0INT		BIT(21)
-#define INT1_TEL0_5INT          BIT(20)
-#define INT1_TEL1_0INT          BIT(19)
-#define INT1_SNDDMACNTINT       BIT(18)
-#define INT1_TELDMACNTINT       BIT(17)
-#define INT1_LSNDCLIPINT        BIT(16)
-#define INT1_RSNDCLIPINT        BIT(15)
-#define INT1_VALSNDPOSINT       BIT(14)
-#define INT1_VALSNDNEGINT       BIT(13)
-#define INT1_VALTELPOSINT       BIT(12)
-#define INT1_VALTELNEGINT       BIT(11)
-#define INT1_SNDININT           BIT(10)
-#define INT1_TELININT           BIT(9)
-#define INT1_SIBSF0INT          BIT(8)
-#define INT1_SIBSF1INT          BIT(7)
-#define INT1_SIBIRQPOSINT       BIT(6)
-#define INT1_SIBIRQNEGINT       BIT(5)
-
-/* Interrupt Status Register 2 at offset 104 */
-#define INT2_UARTARXINT		BIT(31)
-#define INT2_UARTARXOVERRUN	BIT(30)
-#define INT2_UARTAFRAMEINT	BIT(29)
-#define INT2_UARTABREAKINT	BIT(28)
-#define INT2_UARTATXINT		BIT(26)
-#define INT2_UARTATXOVERRUN	BIT(25)
-#define INT2_UARTAEMPTY		BIT(24)
-
-#define INT2_UARTBRXINT		BIT(21)
-#define INT2_UARTBRXOVERRUN	BIT(20)
-#define INT2_UARTBFRAMEINT	BIT(29)
-#define INT2_UARTBBREAKINT	BIT(18)
-#define INT2_UARTBTXINT		BIT(16)
-#define INT2_UARTBTXOVERRUN	BIT(15)
-#define INT2_UARTBEMPTY		BIT(14)
-
-#define INT2_UARTA_RX		(BIT(31) | BIT(30) | BIT(29) | BIT(28) | BIT(27))
-#define INT2_UARTA_TX		(BIT(26) | BIT(25) | BIT(24))
-#define INT2_UARTA_DMA		(BIT(23) | BIT(22))
-
-#define INT2_UARTB_RX		(BIT(21) | BIT(20) | BIT(19) | BIT(18) | BIT(17))
-#define INT2_UARTB_TX		(BIT(16) | BIT(15) | BIT(14))
-#define INT2_UARTB_DMA		(BIT(13) | BIT(12))
-
-/* Interrupt Status Register 5 */
-#define INT5_RTCINT	 BIT(31)
-#define INT5_ALARMINT	 BIT(30)
-#define INT5_PERIODICINT BIT(29)
-#define INT5_POSPWRINT 	 BIT(27)
-#define INT5_NEGPWRINT	 BIT(26)
-#define INT5_POSPWROKINT BIT(25)
-#define INT5_NEGPWROKINT BIT(24)
-#define INT5_POSONBUTINT BIT(23)
-#define INT5_NEGONBUTINT BIT(22)
-#define INT5_SPIAVAILINT BIT(21)        /* 0x0020 0000 */
-#define INT5_SPIERRINT   BIT(20)        /* 0x0010 0000 */
-#define INT5_SPIRCVINT	 BIT(19)	/* 0x0008 0000 */
-#define INT5_SPIEMPTYINT BIT(18)	/* 0x0004 0000 */
-#define INT5_IOPOSINT6	 BIT(13)
-#define INT5_IOPOSINT5	 BIT(12)
-#define INT5_IOPOSINT4	 BIT(11)
-#define INT5_IOPOSINT3	 BIT(10)
-#define INT5_IOPOSINT2	 BIT(9)
-#define INT5_IOPOSINT1	 BIT(8)
-#define INT5_IOPOSINT0	 BIT(7)
-#define INT5_IONEGINT6	 BIT(6)
-#define INT5_IONEGINT5	 BIT(5)
-#define INT5_IONEGINT4	 BIT(4)
-#define INT5_IONEGINT3	 BIT(3)
-#define INT5_IONEGINT2	 BIT(2)
-#define INT5_IONEGINT1	 BIT(1)
-#define INT5_IONEGINT0	 BIT(0)
-
-#define INT5_IONEGINT_SHIFT 0
-#define	INT5_IONEGINT_MASK  (0x7F<<INT5_IONEGINT_SHIFT)
-#define INT5_IOPOSINT_SHIFT 7
-#define	INT5_IOPOSINT_MASK  (0x7F<<INT5_IOPOSINT_SHIFT)
-
-/* Interrupt Status Register 6 */
-#define INT6_IRQHIGH	BIT(31)
-#define INT6_IRQLOW	BIT(30)
-#define INT6_INTVECT	(BIT(5) | BIT(4) | BIT(3) | BIT(2))
-
-
-/* Interrupt Enable Register 6 */
-#define INT6_GLOBALEN		BIT(18)
-#define INT6_PWROKINT		BIT(15)
-#define	INT6_ALARMINT		BIT(14)
-#define INT6_PERIODICINT 	BIT(13)
-#define	INT6_MBUSINT		BIT(12)
-#define INT6_UARTARXINT		BIT(11)
-#define INT6_UARTBRXINT		BIT(10)
-#define	INT6_MFIOPOSINT1619	BIT(9)
-#define INT6_IOPOSINT56         BIT(8)
-#define	INT6_MFIONEGINT1619	BIT(7)
-#define INT6_IONEGINT56         BIT(6)
-#define	INT6_MBUSDMAFULLINT	BIT(5)
-#define	INT6_SNDDMACNTINT	BIT(4)
-#define	INT6_TELDMACNTINT	BIT(3)
-#define	INT6_CHIDMACNTINT	BIT(2)
-#define INT6_IOPOSNEGINT0       BIT(1)
-
-/******************************************************************************
-*
-*	09  GPIO and MFIO modules
-*
-******************************************************************************/
-
-#define IOControl   	REG_AT(0x180)
-#define MFIOOutput   	REG_AT(0x184)
-#define MFIODirection  	REG_AT(0x188)
-#define MFIOInput  	REG_AT(0x18c)
-#define MFIOSelect   	REG_AT(0x190)
-#define IOPowerDown   	REG_AT(0x194)
-#define MFIOPowerDown  	REG_AT(0x198)
-
-#define IODIN_MASK      0x0000007f
-#define IODIN_SHIFT     0
-#define IODOUT_MASK     0x00007f00
-#define IODOUT_SHIFT    8
-#define IODIREC_MASK    0x007f0000
-#define IODIREC_SHIFT   16
-#define IODEBSEL_MASK   0x7f000000
-#define IODEBSEL_SHIFT  24
-
-/******************************************************************************
-*
-*	10  IR module
-*
-******************************************************************************/
-
-#define IRControl1                  REG_AT(0x0a0)
-#define IRControl2                  REG_AT(0x0a4)
-
-/* IR Control 1 Register */
-#define IR_CARDRET                  BIT(24)
-#define IR_BAUDVAL_MASK             0x00ff0000
-#define IR_BAUDVAL_SHIFT            16
-#define IR_TESTIR                   BIT(4)
-#define IR_DTINVERT                 BIT(3)
-#define IR_RXPWR                    BIT(2)
-#define IR_ENSTATE                  BIT(1)
-#define IR_ENCONSM                  BIT(0)
-
-/* IR Control 2 Register */
-#define IR_PER_MASK                 0xff000000
-#define IR_PER_SHIFT                24
-#define IR_ONTIME_MASK              0x00ff0000
-#define IR_ONTIME_SHIFT             16
-#define IR_DELAYVAL_MASK            0x0000ff00
-#define IR_DELAYVAL_SHIFT           8
-#define IR_WAITVAL_MASK             0x000000ff
-#define IR_WAITVAL_SHIFT            0
-
-/******************************************************************************
-*
-*	11  Magicbus Module
-*
-******************************************************************************/
-
-#define MbusCntrl1		REG_AT(0x0e0)
-#define MbusCntrl2		REG_AT(0x0e4)
-#define MbusDMACntrl1		REG_AT(0x0e8)
-#define MbusDMACntrl2		REG_AT(0x0ec)
-#define MbusDMACount		REG_AT(0x0f0)
-#define MbusTxReg		REG_AT(0x0f4)
-#define MbusRxReg		REG_AT(0x0f8)
-
-#define	MBUS_CLKPOL		BIT(4)
-#define	MBUS_SLAVE		BIT(3)
-#define	MBUS_FSLAVE		BIT(2)
-#define	MBUS_LONG		BIT(1)
-#define	MBUS_ENMBUS		BIT(0)
-
-/******************************************************************************
-*
-*	12  Power module
-*
-******************************************************************************/
-
-#define PowerControl   	            REG_AT(0x1C4)
-
-#define PWR_ONBUTN                  BIT(31)
-#define PWR_PWRINT                  BIT(30)
-#define PWR_PWROK                   BIT(29)
-#define PWR_VIDRF_MASK              (BIT(28) | BIT(27))
-#define PWR_VIDRF_SHIFT             27
-#define PWR_SLOWBUS                 BIT(26)
-#define PWR_DIVMOD                  BIT(25)
-#define PWR_STPTIMERVAL_MASK        (BIT(15) | BIT(14) | BIT(13) | BIT(12))
-#define PWR_STPTIMERVAL_SHIFT       12
-#define PWR_ENSTPTIMER              BIT(11)
-#define PWR_ENFORCESHUTDWN          BIT(10)
-#define PWR_FORCESHUTDWN            BIT(9)
-#define PWR_FORCESHUTDWNOCC         BIT(8)
-#define PWR_SELC2MS                 BIT(7)
-#define PWR_BPDBVCC3                BIT(5)
-#define PWR_STOPCPU                 BIT(4)
-#define PWR_DBNCONBUTN              BIT(3)
-#define PWR_COLDSTART               BIT(2)
-#define PWR_PWRCS                   BIT(1)
-#define PWR_VCCON                   BIT(0)
-
-/******************************************************************************
-*
-*	13  SIB (Serial Interconnect Bus) Module
-*
-******************************************************************************/
-
-/* Register locations */
-#define SIBSize	      	        REG_AT(0x060)
-#define SIBSoundRXStart	      	REG_AT(0x064)
-#define SIBSoundTXStart         REG_AT(0x068)
-#define SIBTelecomRXStart       REG_AT(0x06C)
-#define SIBTelecomTXStart       REG_AT(0x070)
-#define SIBControl              REG_AT(0x074)
-#define SIBSoundTXRXHolding     REG_AT(0x078)
-#define SIBTelecomTXRXHolding   REG_AT(0x07C)
-#define SIBSubFrame0Control     REG_AT(0x080)
-#define SIBSubFrame1Control     REG_AT(0x084)
-#define SIBSubFrame0Status      REG_AT(0x088)
-#define SIBSubFrame1Status      REG_AT(0x08C)
-#define SIBDMAControl           REG_AT(0x090)
-
-/* SIB Size Register */
-#define SIB_SNDSIZE_MASK        0x3ffc0000
-#define SIB_SNDSIZE_SHIFT       18
-#define SIB_TELSIZE_MASK        0x00003ffc
-#define SIB_TELSIZE_SHIFT       2
-
-/* SIB Control Register */
-#define SIB_SIBIRQ              BIT(31)
-#define SIB_ENCNTTEST           BIT(30)
-#define SIB_ENDMATEST           BIT(29)
-#define SIB_SNDMONO             BIT(28)
-#define SIB_RMONOSNDIN          BIT(27)
-#define SIB_SIBSCLKDIV_MASK     (BIT(26) | BIT(25) | BIT(24))
-#define SIB_SIBSCLKDIV_SHIFT    24
-#define SIB_TEL16               BIT(23)
-#define SIB_TELFSDIV_MASK       0x007f0000
-#define SIB_TELFSDIV_SHIFT      16
-#define SIB_SND16               BIT(15)
-#define SIB_SNDFSDIV_MASK       0x00007f00
-#define SIB_SNDFSDIV_SHIFT      8
-#define SIB_SELTELSF1           BIT(7)
-#define SIB_SELSNDSF1           BIT(6)
-#define SIB_ENTEL               BIT(5)
-#define SIB_ENSND               BIT(4)
-#define SIB_SIBLOOP             BIT(3)
-#define SIB_ENSF1               BIT(2)
-#define SIB_ENSF0               BIT(1)
-#define SIB_ENSIB               BIT(0)
-
-/* SIB Frame Format (SIBSubFrame0Status and SIBSubFrame1Status) */
-#define SIB_REGISTER_EXT        BIT(31)  /* Must be zero */
-#define SIB_ADDRESS_MASK        0x78000000
-#define SIB_ADDRESS_SHIFT       27
-#define SIB_WRITE               BIT(26)
-#define SIB_AUD_VALID           BIT(17)
-#define SIB_TEL_VALID           BIT(16)
-#define SIB_DATA_MASK           0x00ff
-#define SIB_DATA_SHIFT          0
-
-/* SIB DMA Control Register */
-#define SIB_SNDBUFF1TIME        BIT(31)
-#define SIB_SNDDMALOOP          BIT(30)
-#define SIB_SNDDMAPTR_MASK      0x3ffc0000
-#define SIB_SNDDMAPTR_SHIFT     18
-#define SIB_ENDMARXSND          BIT(17)
-#define SIB_ENDMATXSND          BIT(16)
-#define SIB_TELBUFF1TIME        BIT(15)
-#define SIB_TELDMALOOP          BIT(14)
-#define SIB_TELDMAPTR_MASK      0x00003ffc
-#define SIB_TELDMAPTR_SHIFT     2
-#define SIB_ENDMARXTEL          BIT(1)
-#define SIB_ENDMATXTEL          BIT(0)
-
-/******************************************************************************
-*
-* 	14  SPI module
-*
-******************************************************************************/
-
-#define SPIControl		REG_AT(0x160)
-#define SPITransmit		REG_AT(0x164)
-#define SPIReceive		REG_AT(0x164)
-
-#define SPI_SPION		BIT(17)
-#define SPI_EMPTY		BIT(16)
-#define SPI_DELAYVAL_MASK	(BIT(12) | BIT(13) | BIT(14) | BIT(15))
-#define SPI_DELAYVAL_SHIFT	12
-#define	SPI_BAUDRATE_MASK	(BIT(8) | BIT(9) | BIT(10) | BIT(11))
-#define	SPI_BAUDRATE_SHIFT	8
-#define	SPI_PHAPOL		BIT(5)
-#define	SPI_CLKPOL		BIT(4)
-#define	SPI_WORD		BIT(2)
-#define	SPI_LSB			BIT(1)
-#define	SPI_ENSPI		BIT(0)
-
-/******************************************************************************
-*
-*	15  Timer module
-*
-******************************************************************************/
-
-#define RTChigh	      	REG_AT(0x140)
-#define RTClow	        REG_AT(0x144)
-#define RTCalarmHigh    REG_AT(0x148)
-#define RTCalarmLow     REG_AT(0x14c)
-#define RTCtimerControl REG_AT(0x150)
-#define RTCperiodTimer  REG_AT(0x154)
-
-/* RTC Timer Control */
-#define TIM_FREEZEPRE	BIT(7)
-#define TIM_FREEZERTC	BIT(6)
-#define TIM_FREEZETIMER	BIT(5)
-#define TIM_ENPERTIMER	BIT(4)
-#define TIM_RTCCLEAR	BIT(3)
-
-#define	RTC_HIGHMASK	(0xFF)
-
-/* RTC Periodic Timer */
-#define	TIM_PERCNT	0xFFFF0000
-#define	TIM_PERVAL	0x0000FFFF
-
-/* For a system clock frequency of 36.864MHz, the timer counts at one tick
-   every 868nS (ie CLK/32). Therefore 11520 counts gives a 10mS interval
- */
-#define PER_TIMER_COUNT (1152000/HZ)
-
-/*
- ***********************************************************************
- *								       *
- * 15  UART Module						       *
- *								       *
- ***********************************************************************
- */
-#define TX3912_UARTA_BASE       (REGISTER_BASE + 0x0b0)
-#define TX3912_UARTB_BASE       (REGISTER_BASE + 0x0c8)
-
-/*
- * TX3912 UART register offsets
- */
-#define TX3912_UART_CTRL1       0x00
-#define TX3912_UART_CTRL2       0x04
-#define TX3912_UART_DMA_CTRL1   0x08
-#define TX3912_UART_DMA_CTRL2   0x0c
-#define TX3912_UART_DMA_CNT     0x10
-#define TX3912_UART_DATA        0x14
-
-#define UartA_Ctrl1   REG_AT(0x0b0)
-#define UartA_Data    REG_AT(0x0c4)
-
-/*
- * Defines for UART Control Register 1
- */
-#define TX3912_UART_CTRL1_UARTON	0x80000000
-#define UART_TX_EMPTY		BIT(30)
-#define UART_PRX_HOLD_FULL	BIT(29)
-#define UART_RX_HOLD_FULL	BIT(28)
-#define UART_EN_DMA_RX 		BIT(15)
-#define UART_EN_DMA_TX 		BIT(14)
-#define UART_BREAK_HALT 	BIT(12)
-#define UART_DMA_LOOP		BIT(10)
-#define UART_PULSE_THREE	BIT(9)
-#define UART_PULSE_SIX		BIT(8)
-#define UART_DT_INVERT		BIT(7)
-#define UART_DIS_TXD		BIT(6)
-#define UART_LOOPBACK		BIT(4)
-#define TX3912_UART_CTRL1_ENUART	0x00000001
-		 
-#define SER_SEVEN_BIT		BIT(3)
-#define SER_EIGHT_BIT		    0
-#define SER_EVEN_PARITY 	(BIT(2) | BIT(1))
-#define SER_ODD_PARITY  	BIT(1)
-#define SER_NO_PARITY		    0
-#define SER_TWO_STOP		BIT(5)
-#define SER_ONE_STOP		    0
+/*
+ * Clock control register values
+ */
+#define TX3912_CLK_CTRL_CHICLKDIV_MASK			0xff000000
+#define TX3912_CLK_CTRL_ENCLKTEST			0x00800000
+#define TX3912_CLK_CTRL_CLKTESTSELSIB			0x00400000
+#define TX3912_CLK_CTRL_CHIMCLKSEL			0x00200000
+#define TX3912_CLK_CTRL_CHICLKDIR			0x00100000
+#define TX3912_CLK_CTRL_ENCHIMCLK			0x00080000
+#define TX3912_CLK_CTRL_ENVIDCLK			0x00040000
+#define TX3912_CLK_CTRL_ENMBUSCLK			0x00020000
+#define TX3912_CLK_CTRL_ENSPICLK			0x00010000
+#define TX3912_CLK_CTRL_ENTIMERCLK			0x00008000
+#define TX3912_CLK_CTRL_ENFASTTIMERCLK			0x00004000
+#define TX3912_CLK_CTRL_SIBMCLKDIR			0x00002000
+#define TX3912_CLK_CTRL_reserved1			0x00001000
+#define TX3912_CLK_CTRL_ENSIBMCLK			0x00000800
+#define TX3912_CLK_CTRL_SIBMCLKDIV_6			0x00000600
+#define TX3912_CLK_CTRL_SIBMCLKDIV_5			0x00000500
+#define TX3912_CLK_CTRL_SIBMCLKDIV_4			0x00000400
+#define TX3912_CLK_CTRL_SIBMCLKDIV_3			0x00000300
+#define TX3912_CLK_CTRL_SIBMCLKDIV_2			0x00000200
+#define TX3912_CLK_CTRL_SIBMCLKDIV_1			0x00000100
+#define TX3912_CLK_CTRL_CSERSEL				0x00000080
+#define TX3912_CLK_CTRL_CSERDIV_6			0x00000060
+#define TX3912_CLK_CTRL_CSERDIV_5			0x00000050
+#define TX3912_CLK_CTRL_CSERDIV_4			0x00000040
+#define TX3912_CLK_CTRL_CSERDIV_3			0x00000030
+#define TX3912_CLK_CTRL_CSERDIV_2			0x00000020
+#define TX3912_CLK_CTRL_CSERDIV_1			0x00000010
+#define TX3912_CLK_CTRL_ENCSERCLK			0x00000008
+#define TX3912_CLK_CTRL_ENIRCLK				0x00000004
+#define TX3912_CLK_CTRL_ENUARTACLK			0x00000002
+#define TX3912_CLK_CTRL_ENUARTBCLK			0x00000001
+
+
+/*****************************************************************************
+ *	Interrupt Subsystem                                                  *
+ *	-------------------                                                  *
+ *	Chapter 8 in Philips PR31700 and Toshiba TMPR3905/12 User Manuals    *
+ *****************************************************************************/
+#define TX3912_INT1_CLEAR				0x0100
+#define TX3912_INT2_CLEAR				0x0104
+#define TX3912_INT3_CLEAR				0x0108
+#define TX3912_INT4_CLEAR				0x010c
+#define TX3912_INT5_CLEAR				0x0110
+#define TX3912_INT1_ENABLE				0x0118
+#define TX3912_INT2_ENABLE				0x011c
+#define TX3912_INT3_ENABLE				0x0120
+#define TX3912_INT4_ENABLE				0x0124
+#define TX3912_INT5_ENABLE				0x0128
+#define TX3912_INT6_ENABLE				0x012c
+#define TX3912_INT1_STATUS				0x0100
+#define TX3912_INT2_STATUS				0x0104
+#define TX3912_INT3_STATUS				0x0108
+#define TX3912_INT4_STATUS				0x010c
+#define TX3912_INT5_STATUS				0x0110
+#define TX3912_INT6_STATUS				0x0114
 
 /*
- * Defines for UART Control Register 2
- *
- *              3.6864MHz
- * divisors =  ----------- - 1
- *             (baud * 16)
- */
-#define TX3912_UART_CTRL2_B230400	0x000	/*   0 */
-#define TX3912_UART_CTRL2_B115200	0x001	/*   1 */
-#define TX3912_UART_CTRL2_B76800	0x002	/*   2 */
-#define TX3912_UART_CTRL2_B57600	0x003	/*   3 */
-#define TX3912_UART_CTRL2_B38400	0x005	/*   5 */
-#define TX3912_UART_CTRL2_B19200	0x00b	/*  11 */
-#define TX3912_UART_CTRL2_B9600		0x016	/*  22 */
-#define TX3912_UART_CTRL2_B4800		0x02f	/*  47 */
-#define TX3912_UART_CTRL2_B2400		0x05f	/*  95 */
-#define TX3912_UART_CTRL2_B1200		0x0bf	/* 191 */
-#define TX3912_UART_CTRL2_B600		0x17f	/* 383 */
-#define TX3912_UART_CTRL2_B300		0x2ff	/* 767 */
+ * Interrupt 2 register values
+ */
+#define TX3912_INT2_UARTARXINT				0x80000000
+#define TX3912_INT2_UARTARXOVERRUNINT			0x40000000
+#define TX3912_INT2_UARTAFRAMEERRINT			0x20000000
+#define TX3912_INT2_UARTABREAKINT			0x10000000
+#define TX3912_INT2_UARTAPARITYINT			0x08000000
+#define TX3912_INT2_UARTATXINT				0x04000000
+#define TX3912_INT2_UARTATXOVERRUNINT			0x02000000
+#define TX3912_INT2_UARTAEMPTYINT			0x01000000
+#define TX3912_INT2_UARTADMAFULLINT			0x00800000
+#define TX3912_INT2_UARTADMAHALFINT			0x00400000
+#define TX3912_INT2_UARTBRXINT				0x00200000
+#define TX3912_INT2_UARTBRXOVERRUNINT			0x00100000
+#define TX3912_INT2_UARTBFRAMEERRINT			0x00080000
+#define TX3912_INT2_UARTBBREAKINT			0x00040000
+#define TX3912_INT2_UARTBPARITYINT			0x00020000
+#define TX3912_INT2_UARTBTXINT				0x00010000
+#define TX3912_INT2_UARTBTXOVERRUNINT			0x00008000
+#define TX3912_INT2_UARTBEMPTYINT			0x00004000
+#define TX3912_INT2_UARTBDMAFULLINT			0x00002000
+#define TX3912_INT2_UARTBDMAHALFINT			0x00001000
+#define TX3912_INT2_UARTA_RX_BITS			0xf8000000
+#define TX3912_INT2_UARTA_TX_BITS			0x07c00000
+#define TX3912_INT2_UARTB_RX_BITS			0x003e0000
+#define TX3912_INT2_UARTB_TX_BITS			0x0001f000
+
+/*
+ * Interrupt 5 register values
+ */
+#define TX3912_INT5_RTCINT				0x80000000
+#define TX3912_INT5_ALARMINT				0x40000000
+#define TX3912_INT5_PERINT				0x20000000
+#define TX3912_INT5_STPTIMERINT				0x10000000
+#define TX3912_INT5_POSPWRINT				0x08000000
+#define TX3912_INT5_NEGPWRINT				0x04000000
+#define TX3912_INT5_POSPWROKINT				0x02000000
+#define TX3912_INT5_NEGPWROKINT				0x01000000
+#define TX3912_INT5_POSONBUTINT				0x00800000
+#define TX3912_INT5_NEGONBUTINT				0x00400000
+#define TX3912_INT5_SPIBUFAVAILINT			0x00200000
+#define TX3912_INT5_SPIERRINT				0x00100000
+#define TX3912_INT5_SPIRCVINT				0x00080000
+#define TX3912_INT5_SPIEMPTYINT				0x00040000
+#define TX3912_INT5_IRCONSMINT				0x00020000
+#define TX3912_INT5_CARSTINT				0x00010000
+#define TX3912_INT5_POSCARINT				0x00008000
+#define TX3912_INT5_NEGCARINT				0x00004000
+#define TX3912_INT5_IOPOSINT6				0x00002000
+#define TX3912_INT5_IOPOSINT5				0x00001000
+#define TX3912_INT5_IOPOSINT4				0x00000800
+#define TX3912_INT5_IOPOSINT3				0x00000400
+#define TX3912_INT5_IOPOSINT2				0x00000200
+#define TX3912_INT5_IOPOSINT1				0x00000100
+#define TX3912_INT5_IOPOSINT0				0x00000080
+#define TX3912_INT5_IONEGINT6				0x00000040
+#define TX3912_INT5_IONEGINT5				0x00000020
+#define TX3912_INT5_IONEGINT4				0x00000010
+#define TX3912_INT5_IONEGINT3				0x00000008
+#define TX3912_INT5_IONEGINT2				0x00000004
+#define TX3912_INT5_IONEGINT1				0x00000002
+#define TX3912_INT5_IONEGINT0				0x00000001
+
+/*
+ * Interrupt 6 status register values
+ */
+#define TX3912_INT6_STATUS_IRQHIGH			0x80000000
+#define TX3912_INT6_STATUS_IRQLOW			0x40000000
+#define TX3912_INT6_STATUS_reserved6			0x3fffffc0
+#define TX3912_INT6_STATUS_INTVEC_POSNEGPWROKINT	0x0000003c
+#define TX3912_INT6_STATUS_INTVEC_ALARMINT		0x00000038
+#define TX3912_INT6_STATUS_INTVEC_PERINT		0x00000034
+#define TX3912_INT6_STATUS_INTVEC_reserved5		0x00000030
+#define TX3912_INT6_STATUS_INTVEC_UARTARXINT		0x0000002c
+#define TX3912_INT6_STATUS_INTVEC_UARTBRXINT		0x00000028
+#define TX3912_INT6_STATUS_INTVEC_reserved4		0x00000024
+#define TX3912_INT6_STATUS_INTVEC_IOPOSINT65		0x00000020
+#define TX3912_INT6_STATUS_INTVEC_reserved3		0x0000001c
+#define TX3912_INT6_STATUS_INTVEC_IONEGINT65		0x00000018
+#define TX3912_INT6_STATUS_INTVEC_reserved2		0x00000014
+#define TX3912_INT6_STATUS_INTVEC_SNDDMACNTINT		0x00000010
+#define TX3912_INT6_STATUS_INTVEC_TELDMACNTINT		0x0000000c
+#define TX3912_INT6_STATUS_INTVEC_CHIDMACNTINT		0x00000008
+#define TX3912_INT6_STATUS_INTVEC_IOPOSNEGINT0		0x00000004
+#define TX3912_INT6_STATUS_INTVEC_STDHANDLER		0x00000000
+#define TX3912_INT6_STATUS_reserved1			0x00000003
+
+/*
+ * Interrupt 6 enable register values
+ */
+#define TX3912_INT6_ENABLE_reserved5			0xfff80000
+#define TX3912_INT6_ENABLE_GLOBALEN			0x00040000
+#define TX3912_INT6_ENABLE_IRQPRITEST			0x00020000
+#define TX3912_INT6_ENABLE_IRQTEST			0x00010000
+#define TX3912_INT6_ENABLE_PRIORITYMASK_POSNEGPWROKINT	0x00008000
+#define TX3912_INT6_ENABLE_PRIORITYMASK_ALARMINT	0x00004000
+#define TX3912_INT6_ENABLE_PRIORITYMASK_PERINT		0x00002000
+#define TX3912_INT6_ENABLE_PRIORITYMASK_reserved4	0x00001000
+#define TX3912_INT6_ENABLE_PRIORITYMASK_UARTARXINT	0x00000800
+#define TX3912_INT6_ENABLE_PRIORITYMASK_UARTBRXINT	0x00000400
+#define TX3912_INT6_ENABLE_PRIORITYMASK_reserved3	0x00000200
+#define TX3912_INT6_ENABLE_PRIORITYMASK_IOPOSINT65	0x00000100
+#define TX3912_INT6_ENABLE_PRIORITYMASK_reserved2	0x00000080
+#define TX3912_INT6_ENABLE_PRIORITYMASK_IONEGINT65	0x00000040
+#define TX3912_INT6_ENABLE_PRIORITYMASK_reserved1	0x00000020
+#define TX3912_INT6_ENABLE_PRIORITYMASK_SNDDMACNTINT	0x00000010
+#define TX3912_INT6_ENABLE_PRIORITYMASK_TELDMACNTINT	0x00000008
+#define TX3912_INT6_ENABLE_PRIORITYMASK_CHIDMACNTINT	0x00000004
+#define TX3912_INT6_ENABLE_PRIORITYMASK_IOPOSNEGINT0	0x00000002
+#define TX3912_INT6_ENABLE_PRIORITYMASK_STDHANDLER	0x00000001
+#define TX3912_INT6_ENABLE_HIGH_PRIORITY		0x0000ffff
+
+
+/*****************************************************************************
+ *	Power Subsystem                                                      *
+ *	---------------                                                      *
+ *	Chapter 11 in Philips PR31700 User Manual                            *
+ *	Chapter 12 in Toshiba TMPR3905/12 User Manual                        *
+ *****************************************************************************/
+#define TX3912_POWER_CTRL				0x01c4
+
+/*
+ * Power control register values
+ */
+#define TX3912_POWER_CTRL_ONBUTN			0x80000000
+#define TX3912_POWER_CTRL_PWRINT			0x40000000
+#define TX3912_POWER_CTRL_PWROK				0x20000000
+#define TX3912_POWER_CTRL_VIDRF_MASK			0x18000000
+#define TX3912_POWER_CTRL_SLOWBUS			0x04000000
+#define TX3912_POWER_CTRL_DIVMOD			0x02000000
+#define TX3912_POWER_CTRL_reserved2			0x01ff0000
+#define TX3912_POWER_CTRL_STPTIMERVAL_MASK		0x0000f000
+#define TX3912_POWER_CTRL_ENSTPTIMER			0x00000800
+#define TX3912_POWER_CTRL_ENFORCESHUTDWN		0x00000400
+#define TX3912_POWER_CTRL_FORCESHUTDWN			0x00000200
+#define TX3912_POWER_CTRL_FORCESHUTDWNOCC		0x00000100
+#define TX3912_POWER_CTRL_SELC2MS			0x00000080
+#define TX3912_POWER_CTRL_reserved1			0x00000040
+#define TX3912_POWER_CTRL_BPDBVCC3			0x00000020
+#define TX3912_POWER_CTRL_STOPCPU			0x00000010
+#define TX3912_POWER_CTRL_DBNCONBUTN			0x00000008
+#define TX3912_POWER_CTRL_COLDSTART			0x00000004
+#define TX3912_POWER_CTRL_PWRCS				0x00000002
+#define TX3912_POWER_CTRL_VCCON				0x00000001
+
+
+/*****************************************************************************
+ *	Timer Subsystem                                                      *
+ *	---------------                                                      *
+ *	Chapter 14 in Philips PR31700 User Manual                            *
+ *	Chapter 15 in Toshiba TMPR3905/12 User Manual                        *
+ *****************************************************************************/
+#define TX3912_RTC_HIGH					0x0140
+#define TX3912_RTC_LOW					0x0144
+#define TX3912_RTC_ALARM_HIGH				0x0148
+#define TX3912_RTC_ALARM_LOW				0x014c
+#define TX3912_TIMER_CTRL				0x0150
+#define TX3912_TIMER_PERIOD				0x0154
+
+/*
+ * Timer control register values
+ */
+#define TX3912_TIMER_CTRL_FREEZEPRE			0x00000080
+#define TX3912_TIMER_CTRL_FREEZERTC			0x00000040
+#define TX3912_TIMER_CTRL_FREEZETIMER			0x00000020
+#define TX3912_TIMER_CTRL_ENPERTIMER			0x00000010
+#define TX3912_TIMER_CTRL_RTCCLEAR			0x00000008
+#define TX3912_TIMER_CTRL_TESTC8MS			0x00000004
+#define TX3912_TIMER_CTRL_ENTESTCLK			0x00000002
+#define TX3912_TIMER_CTRL_ENRTCTST			0x00000001
+
+/*
+ * The periodic timer has granularity of 868 nanoseconds which
+ * results in a count of (1.152 x 10^6 / 100) in order to achieve
+ * a 10 millisecond periodic system clock.
+ */
+#define TX3912_SYS_TIMER_VALUE				(1152000/HZ)
+
+
+/*****************************************************************************
+ *	UART Subsystem                                                       *
+ *	--------------                                                       *
+ *	Chapter 15 in Philips PR31700 User Manual                            *
+ *	Chapter 16 in Toshiba TMPR3905/12 User Manual                        *
+ *****************************************************************************/
+#define TX3912_UARTA_CTRL1				0x00b0
+#define TX3912_UARTA_CTRL2				0x00b4
+#define TX3912_UARTA_DMA_CTRL1				0x00b8
+#define TX3912_UARTA_DMA_CTRL2				0x00bc
+#define TX3912_UARTA_DMA_CNT				0x00c0
+#define TX3912_UARTA_DATA				0x00c4
+#define TX3912_UARTB_CTRL1				0x00c8
+#define TX3912_UARTB_CTRL2				0x00cc
+#define TX3912_UARTB_DMA_CTRL1				0x00d0
+#define TX3912_UARTB_DMA_CTRL2				0x00d4
+#define TX3912_UARTB_DMA_CNT				0x00d8
+#define TX3912_UARTB_DATA				0x00dc
+
+/*
+ * UART Control Register 1 values
+ */
+#define TX3912_UART_CTRL1_UARTON			0x80000000
+#define TX3912_UART_CTRL1_EMPTY				0x40000000
+#define TX3912_UART_CTRL1_PRXHOLDFULL			0x20000000
+#define TX3912_UART_CTRL1_RXHOLDFULL			0x10000000
+#define TX3912_UART_CTRL1_reserved1			0x0fff0000
+#define TX3912_UART_CTRL1_ENDMARX			0x00008000
+#define TX3912_UART_CTRL1_ENDMATX			0x00004000
+#define TX3912_UART_CTRL1_TESTMODE			0x00002000
+#define TX3912_UART_CTRL1_ENBREAKHALT			0x00001000
+#define TX3912_UART_CTRL1_ENDMATEST			0x00000800
+#define TX3912_UART_CTRL1_ENDMALOOP			0x00000400
+#define TX3912_UART_CTRL1_PULSEOPT1			0x00000200
+#define TX3912_UART_CTRL1_PULSEOPT1			0x00000100
+#define TX3912_UART_CTRL1_DTINVERT			0x00000080
+#define TX3912_UART_CTRL1_DISTXD			0x00000040
+#define TX3912_UART_CTRL1_TWOSTOP			0x00000020
+#define TX3912_UART_CTRL1_LOOPBACK			0x00000010
+#define TX3912_UART_CTRL1_BIT_7				0x00000008
+#define TX3912_UART_CTRL1_EVENPARITY			0x00000004
+#define TX3912_UART_CTRL1_ENPARITY			0x00000002
+#define TX3912_UART_CTRL1_ENUART			0x00000001
+
+/*
+ * UART Control Register 2 values
+ */
+#define TX3912_UART_CTRL2_B230400			0x0000	/*   0 */
+#define TX3912_UART_CTRL2_B115200			0x0001	/*   1 */
+#define TX3912_UART_CTRL2_B76800			0x0002	/*   2 */
+#define TX3912_UART_CTRL2_B57600			0x0003	/*   3 */
+#define TX3912_UART_CTRL2_B38400			0x0005	/*   5 */
+#define TX3912_UART_CTRL2_B19200			0x000b	/*  11 */
+#define TX3912_UART_CTRL2_B9600				0x0016	/*  22 */
+#define TX3912_UART_CTRL2_B4800				0x002f	/*  47 */
+#define TX3912_UART_CTRL2_B2400				0x005f	/*  95 */
+#define TX3912_UART_CTRL2_B1200				0x00bf	/* 191 */
+#define TX3912_UART_CTRL2_B600				0x017f	/* 383 */
+#define TX3912_UART_CTRL2_B300				0x02ff	/* 767 */
+
+/*****************************************************************************
+ *	Video Subsystem                                                      *
+ *	---------------                                                      *
+ *	Chapter 16 in Philips PR31700 User Manual                            *
+ *	Chapter 17 in Toshiba TMPR3905/12 User Manual                        *
+ *****************************************************************************/
+#define TX3912_VIDEO_CTRL1				0x0028
+#define TX3912_VIDEO_CTRL2				0x002c
+#define TX3912_VIDEO_CTRL3				0x0030
+#define TX3912_VIDEO_CTRL4				0x0034
+#define TX3912_VIDEO_CTRL5				0x0038
+#define TX3912_VIDEO_CTRL6				0x003c
+#define TX3912_VIDEO_CTRL7				0x0040
+#define TX3912_VIDEO_CTRL8				0x0044
+#define TX3912_VIDEO_CTRL9				0x0048
+#define TX3912_VIDEO_CTRL10				0x004c
+#define TX3912_VIDEO_CTRL11				0x0050
+#define TX3912_VIDEO_CTRL12				0x0054
+#define TX3912_VIDEO_CTRL13				0x0058
+#define TX3912_VIDEO_CTRL14				0x005c
+
+/*
+ * Video Control Register 1 values
+ */
+#define TX3912_VIDEO_CTRL1_LINECNT			0xffc00000
+#define TX3912_VIDEO_CTRL1_LOADDLY			0x00200000
+#define TX3912_VIDEO_CTRL1_BAUDVAL			0x001f0000
+#define TX3912_VIDEO_CTRL1_VIDDONEVAL			0x0000fe00
+#define TX3912_VIDEO_CTRL1_ENFREEZEFRAME		0x00000100
+#define TX3912_VIDEO_CTRL1_BITSEL_MASK			0x000000c0
+#define TX3912_VIDEO_CTRL1_BITSEL_8BIT_COLOR		0x000000c0
+#define TX3912_VIDEO_CTRL1_BITSEL_4BIT_GRAY		0x00000080
+#define TX3912_VIDEO_CTRL1_BITSEL_2BIT_GRAY		0x00000040
+#define TX3912_VIDEO_CTRL1_DISPSPLIT			0x00000020
+#define TX3912_VIDEO_CTRL1_DISP8			0x00000010
+#define TX3912_VIDEO_CTRL1_DFMODE			0x00000008
+#define TX3912_VIDEO_CTRL1_INVVID			0x00000004
+#define TX3912_VIDEO_CTRL1_DISPON			0x00000002
+#define TX3912_VIDEO_CTRL1_ENVID			0x00000001
 
-#endif	/* __TX3912_H__ */
+#endif	/* _TX3912_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/types.h linux/include/asm-mips/types.h
--- linux.orig/include/asm-mips/types.h	2000-07-10 05:18:15.000000000 +0000
+++ linux/include/asm-mips/types.h	2002-07-20 01:08:24.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: types.h,v 1.3 1999/08/18 23:37:50 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -10,6 +9,8 @@
 #ifndef _ASM_TYPES_H
 #define _ASM_TYPES_H
 
+#include <linux/config.h>
+
 typedef unsigned short umode_t;
 
 /*
@@ -70,7 +71,18 @@
 
 #define BITS_PER_LONG _MIPS_SZLONG
 
-typedef unsigned long dma_addr_t;
+#ifdef CONFIG_64BIT_PHYS_ADDR
+typedef u32 dma_addr_t;
+#else
+typedef u64 dma_addr_t;
+#endif
+typedef u64 dma64_addr_t;
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+typedef unsigned long long phys_t;
+#else
+typedef unsigned long phys_t;
+#endif
 
 #endif /* __KERNEL__ */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/uaccess.h linux/include/asm-mips/uaccess.h
--- linux.orig/include/asm-mips/uaccess.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips/uaccess.h	2002-07-20 01:08:23.000000000 +0000
@@ -56,7 +56,7 @@
 #define access_ok(type,addr,size) \
 __access_ok(((unsigned long)(addr)),(size),__access_mask)
 
-extern inline int verify_area(int type, const void * addr, unsigned long size)
+static inline int verify_area(int type, const void * addr, unsigned long size)
 {
 	return access_ok(type,addr,size) ? 0 : -EFAULT;
 }
@@ -269,103 +269,99 @@
 
 extern size_t __copy_user(void *__to, const void *__from, size_t __n);
 
-#define __copy_to_user(to,from,n) ({ \
-	void *__cu_to; \
-	const void *__cu_from; \
-	long __cu_len; \
-	\
-	__cu_to = (to); \
-	__cu_from = (from); \
-	__cu_len = (n); \
-	__asm__ __volatile__( \
-		"move\t$4, %1\n\t" \
-		"move\t$5, %2\n\t" \
-		"move\t$6, %3\n\t" \
-		__MODULE_JAL(__copy_user) \
-		"move\t%0, $6" \
-		: "=r" (__cu_len) \
-		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
-		: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \
-		  "$24", "$31","memory"); \
-	__cu_len; \
+#define __invoke_copy_to_user(to,from,n) ({				\
+	register void *__cu_to_r __asm__ ("$4");			\
+	register const void *__cu_from_r __asm__ ("$5");		\
+	register long __cu_len_r __asm__ ("$6");			\
+									\
+	__cu_to_r = (to);						\
+	__cu_from_r = (from);						\
+	__cu_len_r = (n);						\
+	__asm__ __volatile__(						\
+		__MODULE_JAL(__copy_user)				\
+	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
+	:								\
+	: "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",		\
+	  "memory");							\
+	__cu_len_r;							\
 })
 
-#define __copy_from_user(to,from,n) ({ \
-	void *__cu_to; \
-	const void *__cu_from; \
-	long __cu_len; \
-	\
-	__cu_to = (to); \
-	__cu_from = (from); \
-	__cu_len = (n); \
-	__asm__ __volatile__( \
-		"move\t$4, %1\n\t" \
-		"move\t$5, %2\n\t" \
-		"move\t$6, %3\n\t" \
-		".set\tnoreorder\n\t" \
-		__MODULE_JAL(__copy_user) \
-		".set\tnoat\n\t" \
-		"addu\t$1, %2, %3\n\t" \
-		".set\tat\n\t" \
-		".set\treorder\n\t" \
-		"move\t%0, $6" \
-		: "=r" (__cu_len) \
-		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
-		: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \
-		  "$24", "$31","memory"); \
-	__cu_len; \
+#define __copy_to_user(to,from,n) ({					\
+	void *__cu_to;							\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	__cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len);	\
+	__cu_len;							\
 })
 
-#define copy_to_user(to,from,n) ({ \
-	void *__cu_to; \
-	const void *__cu_from; \
-	long __cu_len; \
-	\
-	__cu_to = (to); \
-	__cu_from = (from); \
-	__cu_len = (n); \
-	if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \
-		__asm__ __volatile__( \
-			"move\t$4, %1\n\t" \
-			"move\t$5, %2\n\t" \
-			"move\t$6, %3\n\t" \
-			__MODULE_JAL(__copy_user) \
-			"move\t%0, $6" \
-			: "=r" (__cu_len) \
-			: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
-			: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \
-			  "$15", "$24", "$31","memory"); \
-	__cu_len; \
+#define copy_to_user(to,from,n) ({					\
+	void *__cu_to;							\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	if (access_ok(VERIFY_WRITE, __cu_to, __cu_len))			\
+		__cu_len = __invoke_copy_to_user(__cu_to, __cu_from,	\
+		                                 __cu_len);		\
+	__cu_len;							\
 })
 
-#define copy_from_user(to,from,n) ({ \
-	void *__cu_to; \
-	const void *__cu_from; \
-	long __cu_len; \
-	\
-	__cu_to = (to); \
-	__cu_from = (from); \
-	__cu_len = (n); \
-	if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \
-		__asm__ __volatile__( \
-			"move\t$4, %1\n\t" \
-			"move\t$5, %2\n\t" \
-			"move\t$6, %3\n\t" \
-			".set\tnoreorder\n\t" \
-			__MODULE_JAL(__copy_user) \
-			".set\tnoat\n\t" \
-			"addu\t$1, %2, %3\n\t" \
-			".set\tat\n\t" \
-			".set\treorder\n\t" \
-			"move\t%0, $6" \
-			: "=r" (__cu_len) \
-			: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
-			: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \
-			  "$15", "$24", "$31","memory"); \
-	__cu_len; \
+#define __invoke_copy_from_user(to,from,n) ({				\
+	register void *__cu_to_r __asm__ ("$4");			\
+	register const void *__cu_from_r __asm__ ("$5");		\
+	register long __cu_len_r __asm__ ("$6");			\
+									\
+	__cu_to_r = (to);						\
+	__cu_from_r = (from);						\
+	__cu_len_r = (n);						\
+	__asm__ __volatile__(						\
+		".set\tnoreorder\n\t"					\
+		__MODULE_JAL(__copy_user)				\
+		".set\tnoat\n\t"					\
+		"addu\t$1, %1, %2\n\t"					\
+		".set\tat\n\t"						\
+		".set\treorder\n\t"					\
+	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
+	:								\
+	: "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",		\
+	  "memory");							\
+	__cu_len_r;							\
 })
 
-extern inline __kernel_size_t
+#define __copy_from_user(to,from,n) ({					\
+	void *__cu_to;							\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	__cu_len = __invoke_copy_from_user(__cu_to, __cu_from,		\
+	                                   __cu_len);			\
+	__cu_len;							\
+})
+
+#define copy_from_user(to,from,n) ({					\
+	void *__cu_to;							\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	if (access_ok(VERIFY_READ, __cu_from, __cu_len))		\
+		__cu_len = __invoke_copy_from_user(__cu_to, __cu_from,	\
+		                                   __cu_len);		\
+	__cu_len;							\
+})
+
+static inline __kernel_size_t
 __clear_user(void *addr, __kernel_size_t size)
 {
 	__kernel_size_t res;
@@ -394,7 +390,7 @@
  * Returns: -EFAULT if exception before terminator, N if the entire
  * buffer filled, else strlen.
  */
-extern inline long
+static inline long
 __strncpy_from_user(char *__to, const char *__from, long __len)
 {
 	long res;
@@ -412,7 +408,7 @@
 	return res;
 }
 
-extern inline long
+static inline long
 strncpy_from_user(char *__to, const char *__from, long __len)
 {
 	long res;
@@ -431,7 +427,7 @@
 }
 
 /* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-extern inline long __strlen_user(const char *s)
+static inline long __strlen_user(const char *s)
 {
 	long res;
 
@@ -446,7 +442,7 @@
 	return res;
 }
 
-extern inline long strlen_user(const char *s)
+static inline long strlen_user(const char *s)
 {
 	long res;
 
@@ -462,7 +458,7 @@
 }
 
 /* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-extern inline long __strnlen_user(const char *s, long n)
+static inline long __strnlen_user(const char *s, long n)
 {
 	long res;
 
@@ -478,7 +474,7 @@
 	return res;
 }
 
-extern inline long strnlen_user(const char *s, long n)
+static inline long strnlen_user(const char *s, long n)
 {
 	long res;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/ucontext.h linux/include/asm-mips/ucontext.h
--- linux.orig/include/asm-mips/ucontext.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips/ucontext.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: ucontext.h,v 1.2 1999/09/27 16:01:40 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/unaligned.h linux/include/asm-mips/unaligned.h
--- linux.orig/include/asm-mips/unaligned.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/unaligned.h	2002-07-20 01:08:39.000000000 +0000
@@ -18,7 +18,7 @@
  * This could have been implemented in plain C like IA64 but egcs 1.0.3a
  * inflates this to 23 instructions ...
  */
-extern inline unsigned long long __ldq_u(const unsigned long long * __addr)
+static inline unsigned long long __ldq_u(const unsigned long long * __addr)
 {
 	unsigned long long __res;
 
@@ -33,7 +33,7 @@
 /*
  * Load word unaligned.
  */
-extern inline unsigned long __ldl_u(const unsigned int * __addr)
+static inline unsigned long __ldl_u(const unsigned int * __addr)
 {
 	unsigned long __res;
 
@@ -47,7 +47,7 @@
 /*
  * Load halfword unaligned.
  */
-extern inline unsigned long __ldw_u(const unsigned short * __addr)
+static inline unsigned long __ldw_u(const unsigned short * __addr)
 {
 	unsigned long __res;
 
@@ -61,7 +61,7 @@
 /*
  * Store doubleword ununaligned.
  */
-extern inline void __stq_u(unsigned long __val, unsigned long long * __addr)
+static inline void __stq_u(unsigned long __val, unsigned long long * __addr)
 {
 	__asm__("usw\t%1, %0\n\t"
 		"usw\t%D1, 4+%0"
@@ -72,7 +72,7 @@
 /*
  * Store long ununaligned.
  */
-extern inline void __stl_u(unsigned long __val, unsigned int * __addr)
+static inline void __stl_u(unsigned long __val, unsigned int * __addr)
 {
 	__asm__("usw\t%1, %0"
 		: "=m" (*__addr)
@@ -82,7 +82,7 @@
 /*
  * Store word ununaligned.
  */
-extern inline void __stw_u(unsigned long __val, unsigned short * __addr)
+static inline void __stw_u(unsigned long __val, unsigned short * __addr)
 {
 	__asm__("ush\t%1, %0"
 		: "=m" (*__addr)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/unistd.h linux/include/asm-mips/unistd.h
--- linux.orig/include/asm-mips/unistd.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/unistd.h	2002-07-20 01:08:22.000000000 +0000
@@ -4,9 +4,6 @@
  * for more details.
  *
  * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
- *
- * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
- * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
  */
 #ifndef _ASM_UNISTD_H
 #define _ASM_UNISTD_H
@@ -233,31 +230,54 @@
 #define __NR_madvise			(__NR_Linux + 218)
 #define __NR_getdents64			(__NR_Linux + 219)
 #define __NR_fcntl64			(__NR_Linux + 220)
+#define __NR_security			(__NR_Linux + 221)
+#define __NR_gettid			(__NR_Linux + 222)
+#define __NR_readahead			(__NR_Linux + 223)
+#define __NR_setxattr			(__NR_Linux + 224)
+#define __NR_lsetxattr			(__NR_Linux + 225)
+#define __NR_fsetxattr			(__NR_Linux + 226)
+#define __NR_getxattr			(__NR_Linux + 227)
+#define __NR_lgetxattr			(__NR_Linux + 228)
+#define __NR_fgetxattr			(__NR_Linux + 229)
+#define __NR_listxattr			(__NR_Linux + 230)
+#define __NR_llistxattr			(__NR_Linux + 231)
+#define __NR_flistxattr			(__NR_Linux + 232)
+#define __NR_removexattr		(__NR_Linux + 233)
+#define __NR_lremovexattr		(__NR_Linux + 234)
+#define __NR_fremovexattr		(__NR_Linux + 235)
+#define __NR_tkill			(__NR_Linux + 236)
+#define __NR_sendfile64			(__NR_Linux + 237)
+#define __NR_futex			(__NR_Linux + 238)
+#define __NR_sched_setaffinity		(__NR_Linux + 239)
+#define __NR_sched_getaffinity		(__NR_Linux + 240)
 
 /*
  * Offset of the last Linux flavoured syscall
  */
-#define __NR_Linux_syscalls		220
+#define __NR_Linux_syscalls		240
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
 type name(void) \
 { \
-long __res, __err; \
-__asm__ volatile ("li\t$2,%2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name) \
-                  : "$2","$7","$8","$9","$10","$11","$12","$13","$14","$15", \
-		    "$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a3 asm("$7"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %2\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "=r" (__a3) \
+	: "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 /*
@@ -267,189 +287,195 @@
 #define _syscall1(type,name,atype,a) \
 type name(atype a) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4,%3\n\t" \
-		  "li\t$2,%2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-		  : "=r" (__res), "=r" (__err) \
-		  : "i" (__NR_##name),"r" ((long)(a)) \
-		  : "$2","$4","$7","$8","$9","$10","$11","$12","$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a3 asm("$7"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %3\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "=r" (__a3) \
+	: "r" (__a0), "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall2(type,name,atype,a,btype,b) \
-type name(atype a,btype b) \
+type name(atype a, btype b) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4,%3\n\t" \
-                  "move\t$5,%4\n\t" \
-		  "li\t$2,%2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)) \
-                  : "$2","$4","$5","$7","$8","$9","$10","$11","$12","$13", \
-		    "$14","$15", "$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a3 asm("$7"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %4\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "=r" (__a3) \
+	: "r" (__a0), "r" (__a1), "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall3(type,name,atype,a,btype,b,ctype,c) \
-type name (atype a, btype b, ctype c) \
+type name(atype a, btype b, ctype c) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4,%3\n\t" \
-                  "move\t$5,%4\n\t" \
-                  "move\t$6,%5\n\t" \
-		  "li\t$2,%2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)) \
-                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
-		    "$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "=r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
-type name (atype a, btype b, ctype c, dtype d) \
+type name(atype a, btype b, ctype c, dtype d) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4,%3\n\t" \
-                  "move\t$5,%4\n\t" \
-                  "move\t$6,%5\n\t" \
-                  "move\t$7,%6\n\t" \
-		  "li\t$2,%2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)) \
-                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
-		    "$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
+/*
+ * Using those means your brain needs more than an oil change ;-)
+ */
+
 #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-type name (atype a,btype b,ctype c,dtype d,etype e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4,%3\n\t" \
-                  "move\t$5,%4\n\t" \
-                  "move\t$6,%5\n\t" \
-		  "lw\t$2,%7\n\t" \
-                  "move\t$7,%6\n\t" \
-		  "subu\t$29,24\n\t" \
-		  "sw\t$2,16($29)\n\t" \
-		  "li\t$2,%2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7\n\t" \
-		  "addiu\t$29,24" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "m" ((long)(e)) \
-                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
-                    "$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"lw\t$2, %6\n\t" \
+	"subu\t$29, 32\n\t" \
+	"sw\t$2, 16($29)\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	"addiu\t$29, 32\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
+	  "m" ((unsigned long)e) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \
-type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
+type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4,%3\n\t" \
-                  "move\t$5,%4\n\t" \
-                  "move\t$6,%5\n\t" \
-		  "lw\t$2,%7\n\t" \
-		  "lw\t$3,%8\n\t" \
-                  "move\t$7,%6\n\t" \
-		  "subu\t$29,24\n\t" \
-		  "sw\t$2,16($29)\n\t" \
-		  "sw\t$3,20($29)\n\t" \
-		  "li\t$2,%2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7\n\t" \
-		  "addiu\t$29,24" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "m" ((long)(e)), \
-                                      "m" ((long)(f)) \
-                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
-                    "$12","$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"lw\t$2, %6\n\t" \
+	"lw\t$8, %7\n\t" \
+	"subu\t$29, 32\n\t" \
+	"sw\t$2, 16($29)\n\t" \
+	"sw\t$8, 20($29)\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	"addiu\t$29, 32\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
+	  "m" ((unsigned long)e), "m" ((unsigned long)f) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \
-type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \
+type name(atype a, btype b, ctype c, dtype d, etype e, ftype f, gtype g) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4,%3\n\t" \
-                  "move\t$5,%4\n\t" \
-                  "move\t$6,%5\n\t" \
-		  "lw\t$2,%7\n\t" \
-		  "lw\t$3,%8\n\t" \
-                  "move\t$7,%6\n\t" \
-		  "subu\t$29,32\n\t" \
-		  "sw\t$2,16($29)\n\t" \
-		  "lw\t$2,%9\n\t" \
-		  "sw\t$3,20($29)\n\t" \
-		  "sw\t$2,24($29)\n\t" \
-		  "li\t$2,%2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7\n\t" \
-		  "addiu\t$29,32" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "m" ((long)(e)), \
-                                      "m" ((long)(f)), \
-                                      "m" ((long)(g)) \
-                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
-                    "$12","$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"lw\t$2, %6\n\t" \
+	"lw\t$8, %7\n\t" \
+	"lw\t$9, %8\n\t" \
+	"subu\t$29, 32\n\t" \
+	"sw\t$2, 16($29)\n\t" \
+	"sw\t$8, 20($29)\n\t" \
+	"sw\t$9, 24($29)\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	"addiu\t$29, 32\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
+	  "m" ((unsigned long)e), "m" ((unsigned long)f), \
+	  "m" ((unsigned long)g), \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
+
 #ifdef __KERNEL_SYSCALLS__
 
 /*
@@ -483,7 +509,7 @@
 	return waitpid(-1,wait_stat,0);
 }
 
-#endif /* !defined (__KERNEL_SYSCALLS__) */
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* __KERNEL_SYSCALLS__ */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_UNISTD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/vr4181/irq.h linux/include/asm-mips/vr4181/irq.h
--- linux.orig/include/asm-mips/vr4181/irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/vr4181/irq.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,122 @@
+/*
+ * Macros for vr4181 IRQ numbers.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * 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.
+ *
+ */
+
+/*
+ * Strategy:
+ *
+ * Vr4181 has conceptually three levels of interrupt controllers:
+ *  1. the CPU itself with 8 intr level.
+ *  2. system interrupt controller, cascaded from int0 pin in CPU, 32 intrs
+ *  3. GPIO interrupts : forwarding external interrupts to sys intr controller
+ */
+
+/* decide the irq block assignment */
+#define	VR4181_NUM_CPU_IRQ	8
+#define	VR4181_NUM_SYS_IRQ	32
+#define	VR4181_NUM_GPIO_IRQ	16
+
+#define	VR4181_IRQ_BASE		0
+
+#define	VR4181_CPU_IRQ_BASE	VR4181_IRQ_BASE
+#define	VR4181_SYS_IRQ_BASE	(VR4181_CPU_IRQ_BASE + VR4181_NUM_CPU_IRQ)
+#define	VR4181_GPIO_IRQ_BASE	(VR4181_SYS_IRQ_BASE + VR4181_NUM_SYS_IRQ)
+
+/* CPU interrupts */
+
+/* 
+   IP0 - Software interrupt 
+   IP1 - Software interrupt 
+   IP2 - All but battery, high speed modem, and real time clock 
+   IP3 - RTC Long1 (system timer) 
+   IP4 - RTC Long2 
+   IP5 - High Speed Modem (unused on VR4181) 
+   IP6 - Unused 
+   IP7 - Timer interrupt from CPO_COMPARE 
+*/
+
+#define VR4181_IRQ_SW1       (VR4181_CPU_IRQ_BASE + 0)  
+#define VR4181_IRQ_SW2       (VR4181_CPU_IRQ_BASE + 1)  
+#define VR4181_IRQ_INT0      (VR4181_CPU_IRQ_BASE + 2)
+#define VR4181_IRQ_INT1      (VR4181_CPU_IRQ_BASE + 3)
+#define VR4181_IRQ_INT2      (VR4181_CPU_IRQ_BASE + 4)
+#define VR4181_IRQ_INT3      (VR4181_CPU_IRQ_BASE + 5)
+#define VR4181_IRQ_INT4      (VR4181_CPU_IRQ_BASE + 6)
+#define VR4181_IRQ_TIMER     (VR4181_CPU_IRQ_BASE + 7)
+
+
+/* Cascaded from VR4181_IRQ_INT0 (ICU mapped interrupts) */
+
+/* 
+   IP2 - same as VR4181_IRQ_INT1
+   IP8 - This is a cascade to GPIO IRQ's. Do not use.
+   IP16 - same as VR4181_IRQ_INT2
+   IP18 - CompactFlash
+*/
+
+#define VR4181_IRQ_BATTERY   (VR4181_SYS_IRQ_BASE + 0)
+#define VR4181_IRQ_POWER     (VR4181_SYS_IRQ_BASE + 1)
+#define VR4181_IRQ_RTCL1     (VR4181_SYS_IRQ_BASE + 2)
+#define VR4181_IRQ_ETIMER    (VR4181_SYS_IRQ_BASE + 3)
+#define VR4181_IRQ_RFU12     (VR4181_SYS_IRQ_BASE + 4)
+#define VR4181_IRQ_PIU       (VR4181_SYS_IRQ_BASE + 5)
+#define VR4181_IRQ_AIU       (VR4181_SYS_IRQ_BASE + 6)
+#define VR4181_IRQ_KIU       (VR4181_SYS_IRQ_BASE + 7)
+#define VR4181_IRQ_GIU       (VR4181_SYS_IRQ_BASE + 8)
+#define VR4181_IRQ_SIU       (VR4181_SYS_IRQ_BASE + 9)
+#define VR4181_IRQ_RFU18     (VR4181_SYS_IRQ_BASE + 10)
+#define VR4181_IRQ_SOFT      (VR4181_SYS_IRQ_BASE + 11)
+#define VR4181_IRQ_RFU20     (VR4181_SYS_IRQ_BASE + 12)
+#define VR4181_IRQ_DOZEPIU   (VR4181_SYS_IRQ_BASE + 13)
+#define VR4181_IRQ_RFU22     (VR4181_SYS_IRQ_BASE + 14)
+#define VR4181_IRQ_RFU23     (VR4181_SYS_IRQ_BASE + 15)
+#define VR4181_IRQ_RTCL2     (VR4181_SYS_IRQ_BASE + 16)
+#define VR4181_IRQ_LED       (VR4181_SYS_IRQ_BASE + 17)
+#define VR4181_IRQ_ECU       (VR4181_SYS_IRQ_BASE + 18)
+#define VR4181_IRQ_CSU       (VR4181_SYS_IRQ_BASE + 19)
+#define VR4181_IRQ_USB       (VR4181_SYS_IRQ_BASE + 20)
+#define VR4181_IRQ_DMA       (VR4181_SYS_IRQ_BASE + 21)
+#define VR4181_IRQ_LCD       (VR4181_SYS_IRQ_BASE + 22)
+#define VR4181_IRQ_RFU31     (VR4181_SYS_IRQ_BASE + 23)
+#define VR4181_IRQ_RFU32     (VR4181_SYS_IRQ_BASE + 24)
+#define VR4181_IRQ_RFU33     (VR4181_SYS_IRQ_BASE + 25)
+#define VR4181_IRQ_RFU34     (VR4181_SYS_IRQ_BASE + 26)
+#define VR4181_IRQ_RFU35     (VR4181_SYS_IRQ_BASE + 27)
+#define VR4181_IRQ_RFU36     (VR4181_SYS_IRQ_BASE + 28)
+#define VR4181_IRQ_RFU37     (VR4181_SYS_IRQ_BASE + 29)
+#define VR4181_IRQ_RFU38     (VR4181_SYS_IRQ_BASE + 30)
+#define VR4181_IRQ_RFU39     (VR4181_SYS_IRQ_BASE + 31)
+
+/* Cascaded from VR4181_IRQ_GIU */
+#define VR4181_IRQ_GPIO0     (VR4181_GPIO_IRQ_BASE + 0)
+#define VR4181_IRQ_GPIO1     (VR4181_GPIO_IRQ_BASE + 1)
+#define VR4181_IRQ_GPIO2     (VR4181_GPIO_IRQ_BASE + 2)
+#define VR4181_IRQ_GPIO3     (VR4181_GPIO_IRQ_BASE + 3)
+#define VR4181_IRQ_GPIO4     (VR4181_GPIO_IRQ_BASE + 4)
+#define VR4181_IRQ_GPIO5     (VR4181_GPIO_IRQ_BASE + 5)
+#define VR4181_IRQ_GPIO6     (VR4181_GPIO_IRQ_BASE + 6)
+#define VR4181_IRQ_GPIO7     (VR4181_GPIO_IRQ_BASE + 7)
+#define VR4181_IRQ_GPIO8     (VR4181_GPIO_IRQ_BASE + 8)
+#define VR4181_IRQ_GPIO9     (VR4181_GPIO_IRQ_BASE + 9)
+#define VR4181_IRQ_GPIO10    (VR4181_GPIO_IRQ_BASE + 10)
+#define VR4181_IRQ_GPIO11    (VR4181_GPIO_IRQ_BASE + 11)
+#define VR4181_IRQ_GPIO12    (VR4181_GPIO_IRQ_BASE + 12)
+#define VR4181_IRQ_GPIO13    (VR4181_GPIO_IRQ_BASE + 13)
+#define VR4181_IRQ_GPIO14    (VR4181_GPIO_IRQ_BASE + 14)
+#define VR4181_IRQ_GPIO15    (VR4181_GPIO_IRQ_BASE + 15)
+
+
+// Alternative to above GPIO IRQ defines
+#define VR4181_IRQ_GPIO(pin) ((VR4181_IRQ_GPIO0) + (pin))
+
+#define VR4181_IRQ_MAX       (VR4181_IRQ_BASE + VR4181_NUM_CPU_IRQ + \
+                              VR4181_NUM_SYS_IRQ + VR4181_NUM_GPIO_IRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/vr4181/vr4181.h linux/include/asm-mips/vr4181/vr4181.h
--- linux.orig/include/asm-mips/vr4181/vr4181.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/vr4181/vr4181.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,413 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 by Michael Klar
+ * 
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ */
+#ifndef __ASM_VR4181_VR4181_H 
+#define __ASM_VR4181_VR4181_H 
+
+#include <asm/addrspace.h>
+
+#include <asm/vr4181/irq.h>
+
+#ifndef __ASSEMBLY__
+#define __preg8		(volatile unsigned char*)
+#define __preg16	(volatile unsigned short*)
+#define __preg32	(volatile unsigned int*)
+#else
+#define __preg8
+#define __preg16
+#define __preg32
+#endif
+
+// Embedded CPU peripheral registers
+// Note that many of the registers have different physical address for VR4181
+
+// Bus Control Unit (BCU)
+#define VR4181_BCUCNTREG1	__preg16(KSEG1 + 0x0A000000)	/* BCU control register 1 (R/W) */
+#define VR4181_CMUCLKMSK	__preg16(KSEG1 + 0x0A000004)	/* Clock mask register (R/W) */
+#define VR4181_CMUCLKMSK_MSKCSUPCLK  0x0040
+#define VR4181_CMUCLKMSK_MSKAIUPCLK  0x0020
+#define VR4181_CMUCLKMSK_MSKPIUPCLK  0x0010
+#define VR4181_CMUCLKMSK_MSKADUPCLK  0x0008
+#define VR4181_CMUCLKMSK_MSKSIU18M   0x0004
+#define VR4181_CMUCLKMSK_MSKADU18M   0x0002
+#define VR4181_CMUCLKMSK_MSKUSB      0x0001
+#define VR4181_CMUCLKMSK_MSKSIU      VR4181_CMUCLKMSK_MSKSIU18M
+#define VR4181_BCUSPEEDREG	__preg16(KSEG1 + 0x0A00000C)	/* BCU access time parameter (R/W) */
+#define VR4181_BCURFCNTREG	__preg16(KSEG1 + 0x0A000010)	/* BCU refresh control register (R/W) */
+#define VR4181_REVIDREG		__preg16(KSEG1 + 0x0A000014)	/* Revision ID register (R) */
+#define VR4181_CLKSPEEDREG	__preg16(KSEG1 + 0x0A000018)	/* Clock speed register (R) */
+#define VR4181_EDOMCYTREG	__preg16(KSEG1 + 0x0A000300)	/* Memory cycle timing register (R/W) */
+#define VR4181_MEMCFG_REG	__preg16(KSEG1 + 0x0A000304)	/* Memory configuration register (R/W) */
+#define VR4181_MODE_REG		__preg16(KSEG1 + 0x0A000308)	/* SDRAM mode register (R/W) */
+#define VR4181_SDTIMINGREG	__preg16(KSEG1 + 0x0A00030C)	/* SDRAM timing register (R/W) */
+
+// DMA Control Unit (DCU)
+#define VR4181_MICDEST1REG1	__preg16(KSEG1 + 0x0A000020)	/* Microphone destination 1 address register 1 (R/W) */
+#define VR4181_MICDEST1REG2	__preg16(KSEG1 + 0x0A000022)	/* Microphone destination 1 address register 2 (R/W) */
+#define VR4181_MICDEST2REG1	__preg16(KSEG1 + 0x0A000024)	/* Microphone destination 2 address register 1 (R/W) */
+#define VR4181_MICDEST2REG2	__preg16(KSEG1 + 0x0A000026)	/* Microphone destination 2 address register 2 (R/W) */
+#define VR4181_SPKRRC1REG1	__preg16(KSEG1 + 0x0A000028)	/* Speaker Source 1 address register 1 (R/W) */
+#define VR4181_SPKRRC1REG2	__preg16(KSEG1 + 0x0A00002A)	/* Speaker Source 1 address register 2 (R/W) */
+#define VR4181_SPKRRC2REG1	__preg16(KSEG1 + 0x0A00002C)	/* Speaker Source 2 address register 1 (R/W) */
+#define VR4181_SPKRRC2REG2	__preg16(KSEG1 + 0x0A00002E)	/* Speaker Source 2 address register 2 (R/W) */
+#define VR4181_DMARSTREG	__preg16(KSEG1 + 0x0A000040)	/* DMA Reset register (R/W) */
+#define VR4181_AIUDMAMSKREG	__preg16(KSEG1 + 0x0A000046)	/* Audio DMA mask register (R/W) */
+#define VR4181_USBDMAMSKREG	__preg16(KSEG1 + 0x0A000600)	/* USB DMA Mask register (R/W) */
+#define VR4181_USBRXS1AREG1	__preg16(KSEG1 + 0x0A000602)	/* USB Rx source 1 address register 1 (R/W) */
+#define VR4181_USBRXS1AREG2	__preg16(KSEG1 + 0x0A000604)	/* USB Rx source 1 address register 2 (R/W) */
+#define VR4181_USBRXS2AREG1	__preg16(KSEG1 + 0x0A000606)	/* USB Rx source 2 address register 1 (R/W) */
+#define VR4181_USBRXS2AREG2	__preg16(KSEG1 + 0x0A000608)	/* USB Rx source 2 address register 2 (R/W) */
+#define VR4181_USBTXS1AREG1	__preg16(KSEG1 + 0x0A00060A)	/* USB Tx source 1 address register 1 (R/W) */
+#define VR4181_USBTXS1AREG2	__preg16(KSEG1 + 0x0A00060C)	/* USB Tx source 1 address register 2 (R/W) */
+#define VR4181_USBTXS2AREG1	__preg16(KSEG1 + 0x0A00060E)	/* USB Tx source 2 address register 1 (R/W) */
+#define VR4181_USBTXS2AREG2	__preg16(KSEG1 + 0x0A000610)	/* USB Tx source 2 address register 2 (R/W) */
+#define VR4181_USBRXD1AREG1	__preg16(KSEG1 + 0x0A00062A)	/* USB Rx destination 1 address register 1 (R/W) */
+#define VR4181_USBRXD1AREG2	__preg16(KSEG1 + 0x0A00062C)	/* USB Rx destination 1 address register 2 (R/W) */
+#define VR4181_USBRXD2AREG1	__preg16(KSEG1 + 0x0A00062E)	/* USB Rx destination 2 address register 1 (R/W) */
+#define VR4181_USBRXD2AREG2	__preg16(KSEG1 + 0x0A000630)	/* USB Rx destination 2 address register 2 (R/W) */
+#define VR4181_USBTXD1AREG1	__preg16(KSEG1 + 0x0A000632)	/* USB Tx destination 1 address register 1 (R/W) */
+#define VR4181_USBTXD1AREG2	__preg16(KSEG1 + 0x0A000634)	/* USB Tx destination 1 address register 2 (R/W) */
+#define VR4181_USBTXD2AREG1	__preg16(KSEG1 + 0x0A000636)	/* USB Tx destination 2 address register 1 (R/W) */
+#define VR4181_USBTXD2AREG2	__preg16(KSEG1 + 0x0A000638)	/* USB Tx destination 2 address register 2 (R/W) */
+#define VR4181_RxRCLENREG	__preg16(KSEG1 + 0x0A000652)	/* USB Rx record length register (R/W) */
+#define VR4181_TxRCLENREG	__preg16(KSEG1 + 0x0A000654)	/* USB Tx record length register (R/W) */
+#define VR4181_MICRCLENREG	__preg16(KSEG1 + 0x0A000658)	/* Microphone record length register (R/W) */
+#define VR4181_SPKRCLENREG	__preg16(KSEG1 + 0x0A00065A)	/* Speaker record length register (R/W) */
+#define VR4181_USBCFGREG	__preg16(KSEG1 + 0x0A00065C)	/* USB configuration register (R/W) */
+#define VR4181_MICDMACFGREG	__preg16(KSEG1 + 0x0A00065E)	/* Microphone DMA configuration register (R/W) */
+#define VR4181_SPKDMACFGREG	__preg16(KSEG1 + 0x0A000660)	/* Speaker DMA configuration register (R/W) */
+#define VR4181_DMAITRQREG	__preg16(KSEG1 + 0x0A000662)	/* DMA interrupt request register (R/W) */
+#define VR4181_DMACLTREG	__preg16(KSEG1 + 0x0A000664)	/* DMA control register (R/W) */
+#define VR4181_DMAITMKREG	__preg16(KSEG1 + 0x0A000666)	/* DMA interrupt mask register (R/W) */
+
+// ISA Bridge
+#define VR4181_ISABRGCTL	__preg16(KSEG1 + 0x0B0002C0)	/* ISA Bridge Control Register (R/W) */
+#define VR4181_ISABRGSTS	__preg16(KSEG1 + 0x0B0002C2)	/* ISA Bridge Status Register (R/W) */
+#define VR4181_XISACTL		__preg16(KSEG1 + 0x0B0002C4)	/* External ISA Control Register (R/W) */
+
+// Clocked Serial Interface (CSI)
+#define VR4181_CSIMODE		__preg16(KSEG1 + 0x0B000900)	/* CSI Mode Register (R/W) */
+#define VR4181_CSIRXDATA	__preg16(KSEG1 + 0x0B000902)	/* CSI Receive Data Register (R) */
+#define VR4181_CSITXDATA	__preg16(KSEG1 + 0x0B000904)	/* CSI Transmit Data Register (R/W) */
+#define VR4181_CSILSTAT		__preg16(KSEG1 + 0x0B000906)	/* CSI Line Status Register (R/W) */
+#define VR4181_CSIINTMSK	__preg16(KSEG1 + 0x0B000908)	/* CSI Interrupt Mask Register (R/W) */
+#define VR4181_CSIINTSTAT	__preg16(KSEG1 + 0x0B00090a)	/* CSI Interrupt Status Register (R/W) */
+#define VR4181_CSITXBLEN	__preg16(KSEG1 + 0x0B00090c)	/* CSI Transmit Burst Length Register (R/W) */
+#define VR4181_CSIRXBLEN	__preg16(KSEG1 + 0x0B00090e)	/* CSI Receive Burst Length Register (R/W) */
+
+// Interrupt Control Unit (ICU)
+#define VR4181_SYSINT1REG	__preg16(KSEG1 + 0x0A000080)	/* Level 1 System interrupt register 1 (R) */
+#define VR4181_MSYSINT1REG	__preg16(KSEG1 + 0x0A00008C)	/* Level 1 mask system interrupt register 1 (R/W) */
+#define VR4181_NMIREG		__preg16(KSEG1 + 0x0A000098)	/* NMI register (R/W) */
+#define VR4181_SOFTINTREG	__preg16(KSEG1 + 0x0A00009A)	/* Software interrupt register (R/W) */
+#define VR4181_SYSINT2REG	__preg16(KSEG1 + 0x0A000200)	/* Level 1 System interrupt register 2 (R) */
+#define VR4181_MSYSINT2REG	__preg16(KSEG1 + 0x0A000206)	/* Level 1 mask system interrupt register 2 (R/W) */
+#define VR4181_PIUINTREGro	__preg16(KSEG1 + 0x0B000082)	/* Level 2 PIU interrupt register (R) */
+#define VR4181_AIUINTREG	__preg16(KSEG1 + 0x0B000084)	/* Level 2 AIU interrupt register (R) */
+#define VR4181_MPIUINTREG	__preg16(KSEG1 + 0x0B00008E)	/* Level 2 mask PIU interrupt register (R/W) */
+#define VR4181_MAIUINTREG	__preg16(KSEG1 + 0x0B000090)	/* Level 2 mask AIU interrupt register (R/W) */
+#define VR4181_MKIUINTREG	__preg16(KSEG1 + 0x0B000092)	/* Level 2 mask KIU interrupt register (R/W) */
+#define VR4181_KIUINTREG	__preg16(KSEG1 + 0x0B000198)	/* Level 2 KIU interrupt register (R) */
+
+// Power Management Unit (PMU)
+#define VR4181_PMUINTREG	__preg16(KSEG1 + 0x0B0000A0)	/* PMU Status Register (R/W) */
+#define VR4181_PMUINT_POWERSW  0x1	/* Power switch */
+#define VR4181_PMUINT_BATT     0x2	/* Low batt during normal operation */
+#define VR4181_PMUINT_DEADMAN  0x4	/* Deadman's switch */
+#define VR4181_PMUINT_RESET    0x8	/* Reset switch */
+#define VR4181_PMUINT_RTCRESET 0x10	/* RTC Reset */
+#define VR4181_PMUINT_TIMEOUT  0x20	/* HAL Timer Reset */
+#define VR4181_PMUINT_BATTLOW  0x100	/* Battery low */
+#define VR4181_PMUINT_RTC      0x200	/* RTC Alarm */
+#define VR4181_PMUINT_DCD      0x400	/* DCD# */
+#define VR4181_PMUINT_GPIO0    0x1000	/* GPIO0 */
+#define VR4181_PMUINT_GPIO1    0x2000	/* GPIO1 */
+#define VR4181_PMUINT_GPIO2    0x4000	/* GPIO2 */
+#define VR4181_PMUINT_GPIO3    0x8000	/* GPIO3 */
+
+#define VR4181_PMUCNTREG	__preg16(KSEG1 + 0x0B0000A2)	/* PMU Control Register (R/W) */
+#define VR4181_PMUWAITREG	__preg16(KSEG1 + 0x0B0000A8)	/* PMU Wait Counter Register (R/W) */
+#define VR4181_PMUDIVREG	__preg16(KSEG1 + 0x0B0000AC)	/* PMU Divide Mode Register (R/W) */
+#define VR4181_DRAMHIBCTL	__preg16(KSEG1 + 0x0B0000B2)	/* DRAM Hibernate Control Register (R/W) */
+
+// Real Time Clock Unit (RTC)
+#define VR4181_ETIMELREG	__preg16(KSEG1 + 0x0B0000C0)	/* Elapsed Time L Register (R/W) */
+#define VR4181_ETIMEMREG	__preg16(KSEG1 + 0x0B0000C2)	/* Elapsed Time M Register (R/W) */
+#define VR4181_ETIMEHREG	__preg16(KSEG1 + 0x0B0000C4)	/* Elapsed Time H Register (R/W) */
+#define VR4181_ECMPLREG		__preg16(KSEG1 + 0x0B0000C8)	/* Elapsed Compare L Register (R/W) */
+#define VR4181_ECMPMREG		__preg16(KSEG1 + 0x0B0000CA)	/* Elapsed Compare M Register (R/W) */
+#define VR4181_ECMPHREG		__preg16(KSEG1 + 0x0B0000CC)	/* Elapsed Compare H Register (R/W) */
+#define VR4181_RTCL1LREG	__preg16(KSEG1 + 0x0B0000D0)	/* RTC Long 1 L Register (R/W) */
+#define VR4181_RTCL1HREG	__preg16(KSEG1 + 0x0B0000D2)	/* RTC Long 1 H Register (R/W) */
+#define VR4181_RTCL1CNTLREG	__preg16(KSEG1 + 0x0B0000D4)	/* RTC Long 1 Count L Register (R) */
+#define VR4181_RTCL1CNTHREG	__preg16(KSEG1 + 0x0B0000D6)	/* RTC Long 1 Count H Register (R) */
+#define VR4181_RTCL2LREG	__preg16(KSEG1 + 0x0B0000D8)	/* RTC Long 2 L Register (R/W) */
+#define VR4181_RTCL2HREG	__preg16(KSEG1 + 0x0B0000DA)	/* RTC Long 2 H Register (R/W) */
+#define VR4181_RTCL2CNTLREG	__preg16(KSEG1 + 0x0B0000DC)	/* RTC Long 2 Count L Register (R) */
+#define VR4181_RTCL2CNTHREG	__preg16(KSEG1 + 0x0B0000DE)	/* RTC Long 2 Count H Register (R) */
+#define VR4181_RTCINTREG	__preg16(KSEG1 + 0x0B0001DE)	/* RTC Interrupt Register (R/W) */
+
+// Deadman's Switch Unit (DSU)
+#define VR4181_DSUCNTREG	__preg16(KSEG1 + 0x0B0000E0)	/* DSU Control Register (R/W) */
+#define VR4181_DSUSETREG	__preg16(KSEG1 + 0x0B0000E2)	/* DSU Dead Time Set Register (R/W) */
+#define VR4181_DSUCLRREG	__preg16(KSEG1 + 0x0B0000E4)	/* DSU Clear Register (W) */
+#define VR4181_DSUTIMREG	__preg16(KSEG1 + 0x0B0000E6)	/* DSU Elapsed Time Register (R/W) */
+
+// General Purpose I/O Unit (GIU)
+#define VR4181_GPMD0REG		__preg16(KSEG1 + 0x0B000300)	/* GPIO Mode 0 Register (R/W) */
+#define VR4181_GPMD1REG		__preg16(KSEG1 + 0x0B000302)	/* GPIO Mode 1 Register (R/W) */
+#define VR4181_GPMD2REG		__preg16(KSEG1 + 0x0B000304)	/* GPIO Mode 2 Register (R/W) */
+#define VR4181_GPMD3REG		__preg16(KSEG1 + 0x0B000306)	/* GPIO Mode 3 Register (R/W) */
+#define VR4181_GPDATHREG	__preg16(KSEG1 + 0x0B000308)	/* GPIO Data High Register (R/W) */
+#define VR4181_GPDATHREG_GPIO16  0x0001
+#define VR4181_GPDATHREG_GPIO17  0x0002
+#define VR4181_GPDATHREG_GPIO18  0x0004
+#define VR4181_GPDATHREG_GPIO19  0x0008
+#define VR4181_GPDATHREG_GPIO20  0x0010
+#define VR4181_GPDATHREG_GPIO21  0x0020
+#define VR4181_GPDATHREG_GPIO22  0x0040
+#define VR4181_GPDATHREG_GPIO23  0x0080
+#define VR4181_GPDATHREG_GPIO24  0x0100
+#define VR4181_GPDATHREG_GPIO25  0x0200
+#define VR4181_GPDATHREG_GPIO26  0x0400
+#define VR4181_GPDATHREG_GPIO27  0x0800
+#define VR4181_GPDATHREG_GPIO28  0x1000
+#define VR4181_GPDATHREG_GPIO29  0x2000
+#define VR4181_GPDATHREG_GPIO30  0x4000
+#define VR4181_GPDATHREG_GPIO31  0x8000
+#define VR4181_GPDATLREG	__preg16(KSEG1 + 0x0B00030A)	/* GPIO Data Low Register (R/W) */
+#define VR4181_GPDATLREG_GPIO0   0x0001
+#define VR4181_GPDATLREG_GPIO1   0x0002
+#define VR4181_GPDATLREG_GPIO2   0x0004
+#define VR4181_GPDATLREG_GPIO3   0x0008
+#define VR4181_GPDATLREG_GPIO4   0x0010
+#define VR4181_GPDATLREG_GPIO5   0x0020
+#define VR4181_GPDATLREG_GPIO6   0x0040
+#define VR4181_GPDATLREG_GPIO7   0x0080
+#define VR4181_GPDATLREG_GPIO8   0x0100
+#define VR4181_GPDATLREG_GPIO9   0x0200
+#define VR4181_GPDATLREG_GPIO10  0x0400
+#define VR4181_GPDATLREG_GPIO11  0x0800
+#define VR4181_GPDATLREG_GPIO12  0x1000
+#define VR4181_GPDATLREG_GPIO13  0x2000
+#define VR4181_GPDATLREG_GPIO14  0x4000
+#define VR4181_GPDATLREG_GPIO15  0x8000
+#define VR4181_GPINTEN		__preg16(KSEG1 + 0x0B00030C)	/* GPIO Interrupt Enable Register (R/W) */
+#define VR4181_GPINTMSK		__preg16(KSEG1 + 0x0B00030E)	/* GPIO Interrupt Mask Register (R/W) */
+#define VR4181_GPINTTYPH	__preg16(KSEG1 + 0x0B000310)	/* GPIO Interrupt Type High Register (R/W) */
+#define VR4181_GPINTTYPL	__preg16(KSEG1 + 0x0B000312)	/* GPIO Interrupt Type Low Register (R/W) */
+#define VR4181_GPINTSTAT	__preg16(KSEG1 + 0x0B000314)	/* GPIO Interrupt Status Register (R/W) */
+#define VR4181_GPHIBSTH		__preg16(KSEG1 + 0x0B000316)	/* GPIO Hibernate Pin State High Register (R/W) */
+#define VR4181_GPHIBSTL		__preg16(KSEG1 + 0x0B000318)	/* GPIO Hibernate Pin State Low Register (R/W) */
+#define VR4181_GPSICTL		__preg16(KSEG1 + 0x0B00031A)	/* GPIO Serial Interface Control Register (R/W) */
+#define VR4181_KEYEN		__preg16(KSEG1 + 0x0B00031C)	/* Keyboard Scan Pin Enable Register (R/W) */
+#define VR4181_PCS0STRA		__preg16(KSEG1 + 0x0B000320)	/* Programmable Chip Select [0] Start Address Register (R/W) */
+#define VR4181_PCS0STPA		__preg16(KSEG1 + 0x0B000322)	/* Programmable Chip Select [0] Stop Address Register (R/W) */
+#define VR4181_PCS0HIA		__preg16(KSEG1 + 0x0B000324)	/* Programmable Chip Select [0] High Address Register (R/W) */
+#define VR4181_PCS1STRA		__preg16(KSEG1 + 0x0B000326)	/* Programmable Chip Select [1] Start Address Register (R/W) */
+#define VR4181_PCS1STPA		__preg16(KSEG1 + 0x0B000328)	/* Programmable Chip Select [1] Stop Address Register (R/W) */
+#define VR4181_PCS1HIA		__preg16(KSEG1 + 0x0B00032A)	/* Programmable Chip Select [1] High Address Register (R/W) */
+#define VR4181_PCSMODE		__preg16(KSEG1 + 0x0B00032C)	/* Programmable Chip Select Mode Register (R/W) */
+#define VR4181_LCDGPMODE	__preg16(KSEG1 + 0x0B00032E)	/* LCD General Purpose Mode Register (R/W) */
+#define VR4181_MISCREG0		__preg16(KSEG1 + 0x0B000330)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG1		__preg16(KSEG1 + 0x0B000332)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG2		__preg16(KSEG1 + 0x0B000334)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG3		__preg16(KSEG1 + 0x0B000336)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG4		__preg16(KSEG1 + 0x0B000338)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG5		__preg16(KSEG1 + 0x0B00033A)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG6		__preg16(KSEG1 + 0x0B00033C)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG7		__preg16(KSEG1 + 0x0B00033D)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG8		__preg16(KSEG1 + 0x0B000340)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG9		__preg16(KSEG1 + 0x0B000342)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG10	__preg16(KSEG1 + 0x0B000344)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG11	__preg16(KSEG1 + 0x0B000346)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG12	__preg16(KSEG1 + 0x0B000348)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG13	__preg16(KSEG1 + 0x0B00034A)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG14	__preg16(KSEG1 + 0x0B00034C)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_MISCREG15	__preg16(KSEG1 + 0x0B00034E)	/* Misc. R/W Battery Backed Registers for Non-Volatile Storage (R/W) */
+#define VR4181_SECIRQMASKL	VR4181_GPINTEN
+// No SECIRQMASKH for VR4181
+
+// Touch Panel Interface Unit (PIU)
+#define VR4181_PIUCNTREG	__preg16(KSEG1 + 0x0B000122)	/* PIU Control register (R/W) */
+#define VR4181_PIUCNTREG_PIUSEQEN	0x0004
+#define VR4181_PIUCNTREG_PIUPWR		0x0002
+#define VR4181_PIUCNTREG_PADRST		0x0001
+
+#define VR4181_PIUINTREG	__preg16(KSEG1 + 0x0B000124)	/* PIU Interrupt cause register (R/W) */
+#define VR4181_PIUINTREG_OVP		0x8000
+#define VR4181_PIUINTREG_PADCMD		0x0040
+#define VR4181_PIUINTREG_PADADP		0x0020
+#define VR4181_PIUINTREG_PADPAGE1	0x0010
+#define VR4181_PIUINTREG_PADPAGE0	0x0008
+#define VR4181_PIUINTREG_PADDLOST	0x0004
+#define VR4181_PIUINTREG_PENCHG		0x0001
+
+#define VR4181_PIUSIVLREG	__preg16(KSEG1 + 0x0B000126)	/* PIU Data sampling interval register (R/W) */
+#define VR4181_PIUSTBLREG	__preg16(KSEG1 + 0x0B000128)	/* PIU A/D converter start delay register (R/W) */
+#define VR4181_PIUCMDREG	__preg16(KSEG1 + 0x0B00012A)	/* PIU A/D command register (R/W) */
+#define VR4181_PIUASCNREG	__preg16(KSEG1 + 0x0B000130)	/* PIU A/D port scan register (R/W) */
+#define VR4181_PIUAMSKREG	__preg16(KSEG1 + 0x0B000132)	/* PIU A/D scan mask register (R/W) */
+#define VR4181_PIUCIVLREG	__preg16(KSEG1 + 0x0B00013E)	/* PIU Check interval register (R) */
+#define VR4181_PIUPB00REG	__preg16(KSEG1 + 0x0B0002A0)	/* PIU Page 0 Buffer 0 register (R/W) */
+#define VR4181_PIUPB01REG	__preg16(KSEG1 + 0x0B0002A2)	/* PIU Page 0 Buffer 1 register (R/W) */
+#define VR4181_PIUPB02REG	__preg16(KSEG1 + 0x0B0002A4)	/* PIU Page 0 Buffer 2 register (R/W) */
+#define VR4181_PIUPB03REG	__preg16(KSEG1 + 0x0B0002A6)	/* PIU Page 0 Buffer 3 register (R/W) */
+#define VR4181_PIUPB10REG	__preg16(KSEG1 + 0x0B0002A8)	/* PIU Page 1 Buffer 0 register (R/W) */
+#define VR4181_PIUPB11REG	__preg16(KSEG1 + 0x0B0002AA)	/* PIU Page 1 Buffer 1 register (R/W) */
+#define VR4181_PIUPB12REG	__preg16(KSEG1 + 0x0B0002AC)	/* PIU Page 1 Buffer 2 register (R/W) */
+#define VR4181_PIUPB13REG	__preg16(KSEG1 + 0x0B0002AE)	/* PIU Page 1 Buffer 3 register (R/W) */
+#define VR4181_PIUAB0REG	__preg16(KSEG1 + 0x0B0002B0)	/* PIU A/D scan Buffer 0 register (R/W) */
+#define VR4181_PIUAB1REG	__preg16(KSEG1 + 0x0B0002B2)	/* PIU A/D scan Buffer 1 register (R/W) */
+#define VR4181_PIUAB2REG	__preg16(KSEG1 + 0x0B0002B4)	/* PIU A/D scan Buffer 2 register (R/W) */
+#define VR4181_PIUAB3REG	__preg16(KSEG1 + 0x0B0002B6)	/* PIU A/D scan Buffer 3 register (R/W) */
+#define VR4181_PIUPB04REG	__preg16(KSEG1 + 0x0B0002BC)	/* PIU Page 0 Buffer 4 register (R/W) */
+#define VR4181_PIUPB14REG	__preg16(KSEG1 + 0x0B0002BE)	/* PIU Page 1 Buffer 4 register (R/W) */
+
+// Audio Interface Unit (AIU)
+#define VR4181_SODATREG		__preg16(KSEG1 + 0x0B000166)	/* Speaker Output Data Register (R/W) */
+#define VR4181_SCNTREG		__preg16(KSEG1 + 0x0B000168)	/* Speaker Output Control Register (R/W) */
+#define VR4181_MIDATREG		__preg16(KSEG1 + 0x0B000170)	/* Mike Input Data Register (R/W) */
+#define VR4181_MCNTREG		__preg16(KSEG1 + 0x0B000172)	/* Mike Input Control Register (R/W) */
+#define VR4181_DVALIDREG	__preg16(KSEG1 + 0x0B000178)	/* Data Valid Register (R/W) */
+#define VR4181_SEQREG		__preg16(KSEG1 + 0x0B00017A)	/* Sequential Register (R/W) */
+#define VR4181_INTREG		__preg16(KSEG1 + 0x0B00017C)	/* Interrupt Register (R/W) */
+#define VR4181_SDMADATREG	__preg16(KSEG1 + 0x0B000160)	/* Speaker DMA Data Register (R/W) */
+#define VR4181_MDMADATREG	__preg16(KSEG1 + 0x0B000162)	/* Microphone DMA Data Register (R/W) */
+#define VR4181_DAVREF_SETUP	__preg16(KSEG1 + 0x0B000164)	/* DAC Vref setup register (R/W) */
+#define VR4181_SCNVC_END	__preg16(KSEG1 + 0x0B00016E)	/* Speaker sample rate control (R/W) */
+#define VR4181_MIDATREG		__preg16(KSEG1 + 0x0B000170)	/* Microphone Input Data Register (R/W) */
+#define VR4181_MCNTREG		__preg16(KSEG1 + 0x0B000172)	/* Microphone Input Control Register (R/W) */
+#define VR4181_MCNVC_END	__preg16(KSEG1 + 0x0B00017E)	/* Microphone sample rate control (R/W) */
+
+// Keyboard Interface Unit (KIU)
+#define VR4181_KIUDAT0		__preg16(KSEG1 + 0x0B000180)	/* KIU Data0 Register (R/W) */
+#define VR4181_KIUDAT1		__preg16(KSEG1 + 0x0B000182)	/* KIU Data1 Register (R/W) */
+#define VR4181_KIUDAT2		__preg16(KSEG1 + 0x0B000184)	/* KIU Data2 Register (R/W) */
+#define VR4181_KIUDAT3		__preg16(KSEG1 + 0x0B000186)	/* KIU Data3 Register (R/W) */
+#define VR4181_KIUDAT4		__preg16(KSEG1 + 0x0B000188)	/* KIU Data4 Register (R/W) */
+#define VR4181_KIUDAT5		__preg16(KSEG1 + 0x0B00018A)	/* KIU Data5 Register (R/W) */
+#define VR4181_KIUSCANREP	__preg16(KSEG1 + 0x0B000190)	/* KIU Scan/Repeat Register (R/W) */
+#define VR4181_KIUSCANREP_KEYEN      0x8000
+#define VR4181_KIUSCANREP_SCANSTP    0x0008
+#define VR4181_KIUSCANREP_SCANSTART  0x0004
+#define VR4181_KIUSCANREP_ATSTP      0x0002
+#define VR4181_KIUSCANREP_ATSCAN     0x0001
+#define VR4181_KIUSCANS		__preg16(KSEG1 + 0x0B000192)	/* KIU Scan Status Register (R) */
+#define VR4181_KIUWKS		__preg16(KSEG1 + 0x0B000194)	/* KIU Wait Keyscan Stable Register (R/W) */
+#define VR4181_KIUWKI		__preg16(KSEG1 + 0x0B000196)	/* KIU Wait Keyscan Interval Register (R/W) */
+#define VR4181_KIUINT		__preg16(KSEG1 + 0x0B000198)	/* KIU Interrupt Register (R/W) */
+#define VR4181_KIUINT_KDATLOST       0x0004
+#define VR4181_KIUINT_KDATRDY        0x0002
+#define VR4181_KIUINT_SCANINT        0x0001
+#define VR4181_KIUDAT6		__preg16(KSEG1 + 0x0B00018C)	/* Scan Line 6 Key Data Register (R) */
+#define VR4181_KIUDAT7		__preg16(KSEG1 + 0x0B00018E)	/* Scan Line 7 Key Data Register (R) */
+
+// CompactFlash Controller
+#define VR4181_PCCARDINDEX	__preg8(KSEG1 + 0x0B0008E0)	/* PC Card Controller Index Register */
+#define VR4181_PCCARDDATA	__preg8(KSEG1 + 0x0B0008E1)	/* PC Card Controller Data Register */
+#define VR4181_INTSTATREG	__preg16(KSEG1 + 0x0B0008F8)	/* Interrupt Status Register (R/W) */
+#define VR4181_INTMSKREG	__preg16(KSEG1 + 0x0B0008FA)	/* Interrupt Mask Register (R/W) */
+#define VR4181_CFG_REG_1	__preg16(KSEG1 + 0x0B0008FE)	/* Configuration Register 1 */
+
+// LED Control Unit (LED)
+#define VR4181_LEDHTSREG	__preg16(KSEG1 + 0x0B000240)	/* LED H Time Set register (R/W) */
+#define VR4181_LEDLTSREG	__preg16(KSEG1 + 0x0B000242)	/* LED L Time Set register (R/W) */
+#define VR4181_LEDCNTREG	__preg16(KSEG1 + 0x0B000248)	/* LED Control register (R/W) */
+#define VR4181_LEDASTCREG	__preg16(KSEG1 + 0x0B00024A)	/* LED Auto Stop Time Count register (R/W) */
+#define VR4181_LEDINTREG	__preg16(KSEG1 + 0x0B00024C)	/* LED Interrupt register (R/W) */
+
+// Serial Interface Unit (SIU / SIU1 and SIU2)
+#define VR4181_SIURB		__preg8(KSEG1 + 0x0C000010)	/* Receiver Buffer Register (Read) DLAB = 0 (R) */
+#define VR4181_SIUTH		__preg8(KSEG1 + 0x0C000010)	/* Transmitter Holding Register (Write) DLAB = 0 (W) */
+#define VR4181_SIUDLL		__preg8(KSEG1 + 0x0C000010)	/* Divisor Latch (Least Significant Byte) DLAB = 1 (R/W) */
+#define VR4181_SIUIE		__preg8(KSEG1 + 0x0C000011)	/* Interrupt Enable DLAB = 0 (R/W) */
+#define VR4181_SIUDLM		__preg8(KSEG1 + 0x0C000011)	/* Divisor Latch (Most Significant Byte) DLAB = 1 (R/W) */
+#define VR4181_SIUIID		__preg8(KSEG1 + 0x0C000012)	/* Interrupt Identification Register (Read) (R) */
+#define VR4181_SIUFC		__preg8(KSEG1 + 0x0C000012)	/* FIFO Control Register (Write) (W) */
+#define VR4181_SIULC		__preg8(KSEG1 + 0x0C000013)	/* Line Control Register (R/W) */
+#define VR4181_SIUMC		__preg8(KSEG1 + 0x0C000014)	/* MODEM Control Register (R/W) */
+#define VR4181_SIULS		__preg8(KSEG1 + 0x0C000015)	/* Line Status Register (R/W) */
+#define VR4181_SIUMS		__preg8(KSEG1 + 0x0C000016)	/* MODEM Status Register (R/W) */
+#define VR4181_SIUSC		__preg8(KSEG1 + 0x0C000017)	/* Scratch Register (R/W) */
+#define VR4181_SIURESET		__preg8(KSEG1 + 0x0C000019)	/* SIU Reset Register (R/W) */
+#define VR4181_SIUACTMSK	__preg8(KSEG1 + 0x0C00001C)	/* SIU Activity Mask (R/W) */
+#define VR4181_SIUACTTMR	__preg8(KSEG1 + 0x0C00001E)	/* SIU Activity Timer (R/W) */
+#define VR4181_SIURB_2		__preg8(KSEG1 + 0x0C000000)	/* Receive Buffer Register (Read) (R) */
+#define VR4181_SIUTH_2		__preg8(KSEG1 + 0x0C000000)	/* Transmitter Holding Register (Write) (W) */
+#define VR4181_SIUDLL_2		__preg8(KSEG1 + 0x0C000000)	/* Divisor Latch (Least Significant Byte) (R/W) */
+#define VR4181_SIUIE_2		__preg8(KSEG1 + 0x0C000001)	/* Interrupt Enable (DLAB = 0) (R/W) */
+#define VR4181_SIUDLM_2		__preg8(KSEG1 + 0x0C000001)	/* Divisor Latch (Most Significant Byte) (DLAB = 1) (R/W) */
+#define VR4181_SIUIID_2		__preg8(KSEG1 + 0x0C000002)	/* Interrupt Identification Register (Read) (R) */
+#define VR4181_SIUFC_2		__preg8(KSEG1 + 0x0C000002)	/* FIFO Control Register (Write) (W) */
+#define VR4181_SIULC_2		__preg8(KSEG1 + 0x0C000003)	/* Line Control Register (R/W) */
+#define VR4181_SIUMC_2		__preg8(KSEG1 + 0x0C000004)	/* Modem Control Register (R/W) */
+#define VR4181_SIULS_2		__preg8(KSEG1 + 0x0C000005)	/* Line Status Register (R/W) */
+#define VR4181_SIUMS_2		__preg8(KSEG1 + 0x0C000006)	/* Modem Status Register (R/W) */
+#define VR4181_SIUSC_2		__preg8(KSEG1 + 0x0C000007)	/* Scratch Register (R/W) */
+#define VR4181_SIUIRSEL_2	__preg8(KSEG1 + 0x0C000008)	/* SIU IrDA Selectot (R/W) */
+#define VR4181_SIURESET_2	__preg8(KSEG1 + 0x0C000009)	/* SIU Reset Register (R/W) */
+#define VR4181_SIUCSEL_2	__preg8(KSEG1 + 0x0C00000A)	/* IrDA Echo-back Control (R/W) */
+#define VR4181_SIUACTMSK_2	__preg8(KSEG1 + 0x0C00000C)	/* SIU Activity Mask Register (R/W) */
+#define VR4181_SIUACTTMR_2	__preg8(KSEG1 + 0x0C00000E)	/* SIU Activity Timer Register (R/W) */
+
+
+// USB Module
+#define VR4181_USBINFIFO	__preg16(KSEG1 + 0x0B000780)	/* USB Bulk Input FIFO (Bulk In End Point) (W) */
+#define VR4181_USBOUTFIFO	__preg16(KSEG1 + 0x0B000782)	/* USB Bulk Output FIFO (Bulk Out End Point) (R) */
+#define VR4181_USBCTLFIFO	__preg16(KSEG1 + 0x0B000784)	/* USB Control FIFO (Control End Point) (W) */
+#define VR4181_USBSTAT		__preg16(KSEG1 + 0x0B000786)	/* Interrupt Status Register (R/W) */
+#define VR4181_USBINTMSK	__preg16(KSEG1 + 0x0B000788)	/* Interrupt Mask Register (R/W) */
+#define VR4181_USBCTLREG	__preg16(KSEG1 + 0x0B00078A)	/* Control Register (R/W) */
+#define VR4181_USBSTPREG	__preg16(KSEG1 + 0x0B00078C)	/* USB Transfer Stop Register (R/W) */
+
+// LCD Controller
+#define VR4181_HRTOTALREG	__preg16(KSEG1 + 0x0A000400)	/* Horizontal total Register (R/W) */
+#define VR4181_HRVISIBREG	__preg16(KSEG1 + 0x0A000402)	/* Horizontal Visible Register (R/W) */
+#define VR4181_LDCLKSTREG	__preg16(KSEG1 + 0x0A000404)	/* Load clock start Register (R/W) */
+#define VR4181_LDCLKNDREG	__preg16(KSEG1 + 0x0A000406)	/* Load clock end Register (R/W) */
+#define VR4181_VRTOTALREG	__preg16(KSEG1 + 0x0A000408)	/* Vertical Total Register (R/W) */
+#define VR4181_VRVISIBREG	__preg16(KSEG1 + 0x0A00040A)	/* Vertical Visible Register (R/W) */
+#define VR4181_FVSTARTREG	__preg16(KSEG1 + 0x0A00040C)	/* FLM vertical start Register (R/W) */
+#define VR4181_FVENDREG		__preg16(KSEG1 + 0x0A00040E)	/* FLM vertical end Register (R/W) */
+#define VR4181_LCDCTRLREG	__preg16(KSEG1 + 0x0A000410)	/* LCD control Register (R/W) */
+#define VR4181_LCDINRQREG	__preg16(KSEG1 + 0x0A000412)	/* LCD Interrupt request Register (R/W) */
+#define VR4181_LCDCFGREG0	__preg16(KSEG1 + 0x0A000414)	/* LCD Configuration Register 0 (R/W) */
+#define VR4181_LCDCFGREG1	__preg16(KSEG1 + 0x0A000416)	/* LCD Configuration Register 1 (R/W) */
+#define VR4181_FBSTAD1REG	__preg16(KSEG1 + 0x0A000418)	/* Frame Buffer Start Address 1 Register (R/W) */
+#define VR4181_FBSTAD2REG	__preg16(KSEG1 + 0x0A00041A)	/* Frame Buffer Start Address 2 Register (R/W) */
+#define VR4181_FBNDAD1REG	__preg16(KSEG1 + 0x0A000420)	/* Frame Buffer End Address 1 Register (R/W) */
+#define VR4181_FBNDAD2REG	__preg16(KSEG1 + 0x0A000422)	/* Frame Buffer End Address 2 register (R/W) */
+#define VR4181_FHSTARTREG	__preg16(KSEG1 + 0x0A000424)	/* FLM horizontal Start Register (R/W) */
+#define VR4181_FHENDREG		__preg16(KSEG1 + 0x0A000426)	/* FLM horizontal End Register (R/W) */
+#define VR4181_PWRCONREG1	__preg16(KSEG1 + 0x0A000430)	/* Power Control register 1 (R/W) */
+#define VR4181_PWRCONREG2	__preg16(KSEG1 + 0x0A000432)	/* Power Control register 2 (R/W) */
+#define VR4181_LCDIMSKREG	__preg16(KSEG1 + 0x0A000434)	/* LCD Interrupt Mask register (R/W) */
+#define VR4181_CPINDCTREG	__preg16(KSEG1 + 0x0A00047E)	/* Color palette Index and control Register (R/W) */
+#define VR4181_CPALDATREG	__preg32(KSEG1 + 0x0A000480)	/* Color palette data register (32bits Register) (R/W) */
+
+// physical address spaces
+#define VR4181_LCD             0x0a000000
+#define VR4181_INTERNAL_IO_2   0x0b000000
+#define VR4181_INTERNAL_IO_1   0x0c000000
+#define VR4181_ISA_MEM         0x10000000
+#define VR4181_ISA_IO          0x14000000
+#define VR4181_ROM             0x18000000
+
+// This is the base address for IO port decoding to which the 16 bit IO port address
+// is added.  Defining it to 0 will usually cause a kernel oops any time port IO is
+// attempted, which can be handy for turning up parts of the kernel that make
+// incorrect architecture assumptions (by assuming that everything acts like a PC),
+// but we need it correctly defined to use the PCMCIA/CF controller:
+#define VR4181_PORT_BASE	(KSEG1 + VR4181_ISA_IO)
+#define VR4181_ISAMEM_BASE	(KSEG1 + VR4181_ISA_MEM)
+
+#endif /* __ASM_VR4181_VR4181_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/war.h linux/include/asm-mips/war.h
--- linux.orig/include/asm-mips/war.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips/war.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 by Ralf Baechle
+ */
+#ifndef _ASM_WAR_H
+#define _ASM_WAR_H
+
+/*
+ * Pleassures of the R4600 V1.x.  Cite from the IDT R4600 V1.7 errata:
+ *
+ *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
+ *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
+ *      executed if there is no other dcache activity. If the dcache is
+ *      accessed for another instruction immeidately preceding when these
+ *      cache instructions are executing, it is possible that the dcache 
+ *      tag match outputs used by these cache instructions will be 
+ *      incorrect. These cache instructions should be preceded by at least
+ *      four instructions that are not any kind of load or store 
+ *      instruction.
+ *
+ *      This is not allowed:    lw
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              cache       Hit_Writeback_Invalidate_D
+ *
+ *      This is allowed:        lw
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              nop
+ *                              cache       Hit_Writeback_Invalidate_D
+ */
+#define R4600_V1_HIT_DCACHE_WAR
+
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ *
+ * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
+ * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only
+ * operate correctly if the internal data cache refill buffer is empty.  These
+ * CACHE instructions should be separated from any potential data cache miss
+ * by a load instruction to an uncached address to empty the response buffer."
+ * (Revision 2.0 device errata from IDT available on http://www.idt.com/
+ * in .pdf format.)
+ */
+#define R4600_V2_HIT_CACHEOP_WAR
+
+#endif /* _ASM_WAR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips/wbflush.h linux/include/asm-mips/wbflush.h
--- linux.orig/include/asm-mips/wbflush.h	2001-07-02 20:56:40.000000000 +0000
+++ linux/include/asm-mips/wbflush.h	2002-07-20 01:08:26.000000000 +0000
@@ -6,8 +6,6 @@
  * for more details.
  *
  * Copyright (c) 1998 Harald Koerfgen
- *
- * $Id: wbflush.h,v 1.2 1999/08/13 17:07:28 harald Exp $
  */
 #ifndef __ASM_MIPS_WBFLUSH_H
 #define __ASM_MIPS_WBFLUSH_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/addrspace.h linux/include/asm-mips64/addrspace.h
--- linux.orig/include/asm-mips64/addrspace.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/addrspace.h	2002-07-20 01:08:23.000000000 +0000
@@ -5,110 +5,143 @@
  *
  * Copyright (C) 1996, 1999 by Ralf Baechle
  * Copyright (C) 1990, 1999 by Silicon Graphics, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
-#ifndef _ASM_ADDRSPACE_H
-#define _ASM_ADDRSPACE_H
+#ifndef __ASM_MIPS64_ADDRSPACE_H
+#define __ASM_MIPS64_ADDRSPACE_H
 
 #include <linux/config.h>
 
 /*
+ *  Configure language
+ */
+#ifdef __ASSEMBLY__
+#define _ATYPE_
+#define _ATYPE32_
+#define _ATYPE64_
+#else
+#define _ATYPE_		__PTRDIFF_TYPE__
+#define _ATYPE32_	int
+#define _ATYPE64_	long long
+#endif
+
+/*
+ *  32-bit MIPS address spaces
+ */
+#ifdef __ASSEMBLY__
+#define _ACAST32_
+#define _ACAST64_
+#else
+#define _ACAST32_		(_ATYPE_)(_ATYPE32_)	/* widen if necessary */
+#define _ACAST64_		(_ATYPE64_)		/* do _not_ narrow */
+#endif
+
+/*
  * Memory segments (32bit kernel mode addresses)
  */
-#define KUSEG                   0x0000000000000000
-#define KSEG0                   0xffffffff80000000
-#define KSEG1                   0xffffffffa0000000
-#define KSEG2                   0xffffffffc0000000
-#define KSEG3                   0xffffffffe0000000
+#define KUSEG			0x0000000000000000
+#define KSEG0			0xffffffff80000000
+#define KSEG1			0xffffffffa0000000
+#define KSEG2			0xffffffffc0000000
+#define KSEG3			0xffffffffe0000000
 
 /*
  * Returns the kernel segment base of a given address
  */
-#define KSEGX(a)                (((unsigned long)(a)) & 0xe0000000)
+#define KSEGX(a)		((_ACAST64_ (a)) & 0xffffffffe0000000)
 
 /*
  * Returns the physical address of a KSEG0/KSEG1 address
  */
-#define CPHYSADDR(a)		(((unsigned long)(a)) & 0x000000001fffffffUL)
-#define PHYSADDR(a)		(((unsigned long)(a)) & 0x000000ffffffffffUL)
+#define XPHYSADDR(a)		((_ACAST64_ (a)) & 0x000000ffffffffff)
+#define CPHYSADDR(a)		((_ACAST64_ (a)) & 0x000000001fffffff)
+
+#ifndef __ASSEMBLY__
+#define PHYSADDR(a) ({						\
+	const _ATYPE64_ _a = (a);				\
+	_a == _ACAST32_ _a ? CPHYSADDR(_a) : XPHYSADDR(_a); })
+#endif
 
 /*
  * Map an address to a certain kernel segment
  */
-#define KSEG0ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG0))
-#define KSEG1ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG1))
-#define KSEG2ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG2))
-#define KSEG3ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG3))
+#define KSEG0ADDR(a)		(CPHYSADDR(a) | KSEG0)
+#define KSEG1ADDR(a)		(CPHYSADDR(a) | KSEG1)
+#define KSEG2ADDR(a)		(CPHYSADDR(a) | KSEG2)
+#define KSEG3ADDR(a)		(CPHYSADDR(a) | KSEG3)
 
 /*
  * Memory segments (64bit kernel mode addresses)
  */
-#define XKUSEG                  0x0000000000000000
-#define XKSSEG                  0x4000000000000000
-#define XKPHYS                  0x8000000000000000
-#define XKSEG                   0xc000000000000000
-#define CKSEG0                  0xffffffff80000000
-#define CKSEG1                  0xffffffffa0000000
-#define CKSSEG                  0xffffffffc0000000
-#define CKSEG3                  0xffffffffe0000000
+#define XKUSEG			0x0000000000000000
+#define XKSSEG			0x4000000000000000
+#define XKPHYS			0x8000000000000000
+#define XKSEG			0xc000000000000000
+#define CKSEG0			0xffffffff80000000
+#define CKSEG1			0xffffffffa0000000
+#define CKSSEG			0xffffffffc0000000
+#define CKSEG3			0xffffffffe0000000
 
 #if defined (CONFIG_CPU_R4300)						\
     || defined (CONFIG_CPU_R4X00)					\
     || defined (CONFIG_CPU_R5000)					\
     || defined (CONFIG_CPU_NEVADA)
-#define	KUSIZE		0x0000010000000000		/* 2^^40 */
-#define	KUSIZE_64	0x0000010000000000		/* 2^^40 */
-#define	K0SIZE		0x0000001000000000		/* 2^^36 */
-#define	K1SIZE		0x0000001000000000		/* 2^^36 */
-#define	K2SIZE		0x000000ff80000000
-#define	KSEGSIZE	0x000000ff80000000		/* max syssegsz */
-#define TO_PHYS_MASK	0x0000000fffffffff		/* 2^^36 - 1 */
+#define	KUSIZE			0x0000010000000000	/* 2^^40 */
+#define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
+#define	K0SIZE			0x0000001000000000	/* 2^^36 */
+#define	K1SIZE			0x0000001000000000	/* 2^^36 */
+#define	K2SIZE			0x000000ff80000000
+#define	KSEGSIZE		0x000000ff80000000	/* max syssegsz */
+#define TO_PHYS_MASK		0x0000000fffffffff	/* 2^^36 - 1 */
 #endif
 
 #if defined (CONFIG_CPU_R8000)
 /* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */
-#define	KUSIZE		0x0000010000000000		/* 2^^40 */
-#define	KUSIZE_64	0x0000010000000000		/* 2^^40 */
-#define	K0SIZE		0x0000010000000000		/* 2^^40 */
-#define	K1SIZE		0x0000010000000000		/* 2^^40 */
-#define	K2SIZE		0x0001000000000000
-#define	KSEGSIZE	0x0000010000000000		/* max syssegsz */
-#define TO_PHYS_MASK	0x000000ffffffffff		/* 2^^40 - 1 */
+#define	KUSIZE			0x0000010000000000	/* 2^^40 */
+#define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
+#define	K0SIZE			0x0000010000000000	/* 2^^40 */
+#define	K1SIZE			0x0000010000000000	/* 2^^40 */
+#define	K2SIZE			0x0001000000000000
+#define	KSEGSIZE		0x0000010000000000	/* max syssegsz */
+#define TO_PHYS_MASK		0x000000ffffffffff	/* 2^^40 - 1 */
 #endif
 
 #if defined (CONFIG_CPU_R10000)
-#define	KUSIZE		0x0000010000000000		/* 2^^40 */
-#define	KUSIZE_64	0x0000010000000000		/* 2^^40 */
-#define	K0SIZE		0x0000010000000000		/* 2^^40 */
-#define	K1SIZE		0x0000010000000000		/* 2^^40 */
-#define	K2SIZE		0x00000fff80000000
-#define	KSEGSIZE	0x00000fff80000000		/* max syssegsz */
-#define TO_PHYS_MASK	0x000000ffffffffff		/* 2^^40 - 1 */
+#define	KUSIZE			0x0000010000000000	/* 2^^40 */
+#define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
+#define	K0SIZE			0x0000010000000000	/* 2^^40 */
+#define	K1SIZE			0x0000010000000000	/* 2^^40 */
+#define	K2SIZE			0x00000fff80000000
+#define	KSEGSIZE		0x00000fff80000000	/* max syssegsz */
+#define TO_PHYS_MASK		0x000000ffffffffff	/* 2^^40 - 1 */
 #endif
 
 /*
  * Further names for SGI source compatibility.  These are stolen from
  * IRIX's <sys/mips_addrspace.h>.
  */
-#define KUBASE		0
-#define KUSIZE_32	0x0000000080000000	/* KUSIZE for a 32 bit proc */
-#define K0BASE		0xa800000000000000
-#define K0BASE_EXL_WR	K0BASE			/* exclusive on write */
-#define K0BASE_NONCOH	0x9800000000000000	/* noncoherent */
-#define K0BASE_EXL	0xa000000000000000	/* exclusive */
+#define KUBASE			0
+#define KUSIZE_32		0x0000000080000000	/* KUSIZE
+							   for a 32 bit proc */
+#define K0BASE			0xa800000000000000
+#define K0BASE_EXL_WR		K0BASE			/* exclusive on write */
+#define K0BASE_NONCOH		0x9800000000000000	/* noncoherent */
+#define K0BASE_EXL		0xa000000000000000	/* exclusive */
 
 #ifdef CONFIG_SGI_IP27
-#define K1BASE		0x9600000000000000	/* Uncached attr 3, uncac */
+#define K1BASE			0x9600000000000000	/* uncached attr 3,
+							   uncac */
 #else
-#define K1BASE		0x9000000000000000
+#define K1BASE			0x9000000000000000
 #endif
-#define K2BASE		0xc000000000000000
+#define K2BASE			0xc000000000000000
 
 #if !defined (CONFIG_CPU_R8000)
 #define COMPAT_K1BASE32		0xffffffffa0000000
 #define PHYS_TO_COMPATK1(x)	((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
 #endif
 
-#define KDM_TO_PHYS(x)	((unsigned long)(x) & TO_PHYS_MASK)
-#define PHYS_TO_K0(x)	((unsigned long)(x) | K0BASE)
+#define KDM_TO_PHYS(x)		(_ACAST64_ (x) & TO_PHYS_MASK)
+#define PHYS_TO_K0(x)		(_ACAST64_ (x) | K0BASE)
 
-#endif /* _ASM_ADDRSPACE_H */
+#endif /* __ASM_MIPS64_ADDRSPACE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/asm.h linux/include/asm-mips64/asm.h
--- linux.orig/include/asm-mips64/asm.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/asm.h	2002-07-20 01:08:21.000000000 +0000
@@ -6,6 +6,7 @@
  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
  * Copyright (C) 1999 by Silicon Graphics, Inc.
  * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
  *
  * Some useful macros for MIPS assembler code
  *
@@ -105,20 +106,20 @@
 		TEXT(string)
 
 #define	TEXT(msg)                                       \
-		.data;                                  \
+		.pushsection .data;			\
 8:		.asciiz	msg;                            \
-		.previous;
+		.popsection;
 
 /*
  * Build text tables
  */
 #define TTABLE(string)                                  \
-		.text;                                  \
+		.pushsection .text;			\
 		.word	1f;                             \
-		.previous;                              \
-		.data;                                  \
-1:		.asciz	string;                         \
-		.previous
+		.popsection				\
+		.pushsection .data;			\
+1:		.asciiz	string;                         \
+		.popsection
 
 /*
  * MIPS IV pref instruction.
@@ -129,19 +130,30 @@
  */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS64)
+
 #define PREF(hint,addr)                                 \
-		pref	hint,addr
+		.set	push;				\
+		.set	mips4;				\
+		pref	hint,addr;			\
+		.set	pop
+
 #define PREFX(hint,addr)                                \
-		prefx	hint,addr
+		.set	push;				\
+		.set	mips4;				\
+		prefx	hint,addr;			\
+		.set	pop
+
 #else
-#define PREF
-#define PREFX
+
+#define PREF(hint,addr)
+#define PREFX(hint,addr)
+
 #endif
 
 /*
  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
  */
-#if _MIPS_ISA == _MIPS_ISA_MIPS1
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1)
 #define MOVN(rd,rs,rt)                                  \
 		.set	push;				\
 		.set	reorder;			\
@@ -162,24 +174,24 @@
 		.set	push;				\
 		.set	noreorder;			\
 		bnezl	rt,9f;                          \
-		move	rd,rs;                          \
+		 move	rd,rs;                          \
 		.set	pop;				\
 9:
 #define MOVZ(rd,rs,rt)                                  \
 		.set	push;				\
 		.set	noreorder;			\
 		beqzl	rt,9f;                          \
-		movz	rd,rs;                          \
+		 move	rd,rs;                          \
 		.set	pop;				\
 9:
 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS64)
+    (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
 #define MOVN(rd,rs,rt)                                  \
 		movn	rd,rs,rt
 #define MOVZ(rd,rs,rt)                                  \
 		movz	rd,rs,rt
-#endif /* MIPS IV, MIPS V or MIPS64 */
+#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
 
 /*
  * Stack alignment
@@ -196,6 +208,10 @@
 #endif
 
 /*
+ * Macros to handle different pointer/register sizes for 32/64-bit code
+ */
+
+/*
  * Size of a register
  */
 #ifdef __mips64
@@ -210,47 +226,54 @@
  */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS32)
-#define REG_S sw
-#define REG_L lw
-#define PTR_SUBU dsubu
-#define PTR_ADDU daddu
+#define REG_S		sw
+#define REG_L		lw
+#define REG_SUBU	subu
+#define REG_ADDU	addu
 #endif
 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
-#define REG_S sd
-#define REG_L ld
-/* We still live in a 32 bit address space ...  */
-#define PTR_SUBU dsubu
-#define PTR_ADDU daddu
+#define REG_S		sd
+#define REG_L		ld
+#define REG_SUBU	dsubu
+#define REG_ADDU	daddu
 #endif
 
 /*
  * How to add/sub/load/store/shift C int variables.
  */
 #if (_MIPS_SZINT == 32)
-#define INT_ADD	add
-#define INT_ADDI	addi
+#define INT_ADD		add
 #define INT_ADDU	addu
+#define INT_ADDI	addi
 #define INT_ADDIU	addiu
-#define INT_SUB		add
-#define INT_SUBI	subi
+#define INT_SUB		sub
 #define INT_SUBU	subu
-#define INT_SUBIU	subu
 #define INT_L		lw
 #define INT_S		sw
+#define INT_SLL		sll
+#define INT_SLLV	sllv
+#define INT_SRL		srl
+#define INT_SRLV	srlv
+#define INT_SRA		sra
+#define INT_SRAV	srav
 #endif
 
 #if (_MIPS_SZINT == 64)
-#define INT_ADD	dadd
-#define INT_ADDI	daddi
+#define INT_ADD		dadd
 #define INT_ADDU	daddu
+#define INT_ADDI	daddi
 #define INT_ADDIU	daddiu
-#define INT_SUB		dadd
-#define INT_SUBI	dsubi
+#define INT_SUB		dsub
 #define INT_SUBU	dsubu
-#define INT_SUBIU	dsubu
 #define INT_L		ld
 #define INT_S		sd
+#define INT_SLL		dsll
+#define INT_SLLV	dsllv
+#define INT_SRL		dsrl
+#define INT_SRLV	dsrlv
+#define INT_SRA		dsra
+#define INT_SRAV	dsrav
 #endif
 
 /*
@@ -258,13 +281,11 @@
  */
 #if (_MIPS_SZLONG == 32)
 #define LONG_ADD	add
-#define LONG_ADDI	addi
 #define LONG_ADDU	addu
+#define LONG_ADDI	addi
 #define LONG_ADDIU	addiu
-#define LONG_SUB	add
-#define LONG_SUBI	subi
+#define LONG_SUB	sub
 #define LONG_SUBU	subu
-#define LONG_SUBIU	subu
 #define LONG_L		lw
 #define LONG_S		sw
 #define LONG_SLL	sll
@@ -277,13 +298,11 @@
 
 #if (_MIPS_SZLONG == 64)
 #define LONG_ADD	dadd
-#define LONG_ADDI	daddi
 #define LONG_ADDU	daddu
+#define LONG_ADDI	daddi
 #define LONG_ADDIU	daddiu
-#define LONG_SUB	dadd
-#define LONG_SUBI	dsubi
+#define LONG_SUB	dsub
 #define LONG_SUBU	dsubu
-#define LONG_SUBIU	dsubu
 #define LONG_L		ld
 #define LONG_S		sd
 #define LONG_SLL	dsll
@@ -298,16 +317,15 @@
  * How to add/sub/load/store/shift pointers.
  */
 #if (_MIPS_SZPTR == 32)
-#define PTR_ADD	add
-#define PTR_ADDI	addi
+#define PTR_ADD		add
 #define PTR_ADDU	addu
+#define PTR_ADDI	addi
 #define PTR_ADDIU	addiu
-#define PTR_SUB		add
-#define PTR_SUBI	subi
+#define PTR_SUB		sub
 #define PTR_SUBU	subu
-#define PTR_SUBIU	subu
 #define PTR_L		lw
 #define PTR_S		sw
+#define PTR_LA		la
 #define PTR_SLL		sll
 #define PTR_SLLV	sllv
 #define PTR_SRL		srl
@@ -323,16 +341,15 @@
 #endif
 
 #if (_MIPS_SZPTR == 64)
-#define PTR_ADD	dadd
-#define PTR_ADDI	daddi
+#define PTR_ADD		dadd
 #define PTR_ADDU	daddu
+#define PTR_ADDI	daddi
 #define PTR_ADDIU	daddiu
-#define PTR_SUB		dadd
-#define PTR_SUBI	dsubi
+#define PTR_SUB		dsub
 #define PTR_SUBU	dsubu
-#define PTR_SUBIU	dsubu
 #define PTR_L		ld
 #define PTR_S		sd
+#define PTR_LA		dla
 #define PTR_SLL		dsll
 #define PTR_SLLV	dsllv
 #define PTR_SRL		dsrl
@@ -352,13 +369,15 @@
  */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS32)
-#define MFC0	mfc0
-#define MTC0	mtc0
+#define MFC0		mfc0
+#define MTC0		mtc0
 #endif
 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
     (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
-#define MFC0	dmfc0
-#define MTC0	dmtc0
+#define MFC0		dmfc0
+#define MTC0		dmtc0
 #endif
 
+#define SSNOP		sll zero,zero,1
+
 #endif /* __ASM_ASM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/atomic.h linux/include/asm-mips64/atomic.h
--- linux.orig/include/asm-mips64/atomic.h	2001-07-10 04:30:19.000000000 +0000
+++ linux/include/asm-mips64/atomic.h	2002-07-20 01:08:25.000000000 +0000
@@ -88,6 +88,7 @@
 		"sc\t%0,%2\n\t"
 		"beqz\t%0,1b\n\t"
 		"addu\t%0,%1,%3\n\t"
+		"sync\n\t"
 		".set\treorder"
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
@@ -107,6 +108,7 @@
 		"sc\t%0,%2\n\t"
 		"beqz\t%0,1b\n\t"
 		"subu\t%0,%1,%3\n\t"
+		"sync\n\t"
 		".set\treorder"
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
@@ -184,10 +186,10 @@
  */
 
 /* Atomic operations are already serializing */
-#define smp_mb__before_atomic_dec()	barrier()
-#define smp_mb__after_atomic_dec()	barrier()
-#define smp_mb__before_atomic_inc()	barrier()
-#define smp_mb__after_atomic_inc()	barrier()
+#define smp_mb__before_atomic_dec()	smp_mb()
+#define smp_mb__after_atomic_dec()	smp_mb()
+#define smp_mb__before_atomic_inc()	smp_mb()
+#define smp_mb__after_atomic_inc()	smp_mb()
 
 #endif /* defined(__KERNEL__) */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/bcache.h linux/include/asm-mips64/bcache.h
--- linux.orig/include/asm-mips64/bcache.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/bcache.h	2002-07-20 01:08:35.000000000 +0000
@@ -11,8 +11,6 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_BOARD_SCACHE
-
 /* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent,
    chipset implemented caches.  On machines with other CPUs the CPU does the 
    cache thing itself. */
@@ -26,24 +24,26 @@
 extern void indy_sc_init(void);
 extern void sni_pcimt_sc_init(void);
 
+#ifdef CONFIG_BOARD_SCACHE
+
 extern struct bcache_ops *bcops;
 
-extern inline void bc_enable(void)
+static inline void bc_enable(void)
 {
 	bcops->bc_enable();
 }
 
-extern inline void bc_disable(void)
+static inline void bc_disable(void)
 {
 	bcops->bc_disable();
 }
 
-extern inline void bc_wback_inv(unsigned long page, unsigned long size)
+static inline void bc_wback_inv(unsigned long page, unsigned long size)
 {
 	bcops->bc_wback_inv(page, size);
 }
 
-extern inline void bc_inv(unsigned long page, unsigned long size)
+static inline void bc_inv(unsigned long page, unsigned long size)
 {
 	bcops->bc_inv(page, size);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/bitops.h linux/include/asm-mips64/bitops.h
--- linux.orig/include/asm-mips64/bitops.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/bitops.h	2002-07-20 01:08:31.000000000 +0000
@@ -9,8 +9,9 @@
 #ifndef _ASM_BITOPS_H
 #define _ASM_BITOPS_H
 
+#include <linux/config.h>
 #include <linux/types.h>
-#include <linux/byteorder/swab.h>		/* sigh ... */
+#include <asm/byteorder.h>		/* sigh ... */
 
 #ifndef __KERNEL__
 #error "Don't do this, sucker ..."
@@ -18,7 +19,6 @@
 
 #include <asm/system.h>
 #include <asm/sgidefs.h>
-#include <asm/mipsregs.h>
 
 /*
  * set_bit - Atomically set a bit in memory
@@ -30,8 +30,7 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-extern __inline__ void
-set_bit(unsigned long nr, volatile void *addr)
+static inline void set_bit(unsigned long nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
 	unsigned long temp;
@@ -55,7 +54,7 @@
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-extern __inline__ void __set_bit(int nr, volatile void * addr)
+static inline void __set_bit(int nr, volatile void * addr)
 {
 	unsigned long * m = ((unsigned long *) addr) + (nr >> 6);
 
@@ -72,8 +71,7 @@
  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  * in order to ensure changes are visible on other processors.
  */
-extern __inline__ void
-clear_bit(unsigned long nr, volatile void *addr)
+static inline void clear_bit(unsigned long nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
 	unsigned long temp;
@@ -87,8 +85,8 @@
 		: "ir" (~(1UL << (nr & 0x3f))), "m" (*m));
 }
 
-#define smp_mb__before_clear_bit()	barrier()
-#define smp_mb__after_clear_bit()	barrier()
+#define smp_mb__before_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	smp_mb()
 
 /*
  * change_bit - Toggle a bit in memory
@@ -99,8 +97,7 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-extern __inline__ void
-change_bit(unsigned long nr, volatile void *addr)
+static inline void change_bit(unsigned long nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
 	unsigned long temp;
@@ -123,7 +120,7 @@
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-extern __inline__ void __change_bit(int nr, volatile void * addr)
+static inline void __change_bit(int nr, volatile void * addr)
 {
 	unsigned long * m = ((unsigned long *) addr) + (nr >> 6);
 
@@ -138,8 +135,8 @@
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-extern __inline__ unsigned long
-test_and_set_bit(unsigned long nr, volatile void *addr)
+static inline unsigned long test_and_set_bit(unsigned long nr,
+					     volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
 	unsigned long temp, res;
@@ -151,6 +148,9 @@
 		"scd\t%2, %1\n\t"
 		"beqz\t%2, 1b\n\t"
 		" and\t%2, %0, %3\n\t"
+#ifdef CONFIG_SMP
+		"sync\n\t"
+#endif
 		".set\treorder"
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << (nr & 0x3f)), "m" (*m)
@@ -168,8 +168,7 @@
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int
-__test_and_set_bit(int nr, volatile void * addr)
+static inline int __test_and_set_bit(int nr, volatile void *addr)
 {
 	unsigned long mask, retval;
 	long *a = (unsigned long *) addr;
@@ -190,8 +189,8 @@
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-extern __inline__ unsigned long
-test_and_clear_bit(unsigned long nr, volatile void *addr)
+static inline unsigned long test_and_clear_bit(unsigned long nr,
+					       volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
 	unsigned long temp, res;
@@ -204,6 +203,9 @@
 		"scd\t%2, %1\n\t"
 		"beqz\t%2, 1b\n\t"
 		" and\t%2, %0, %3\n\t"
+#ifdef CONFIG_SMP
+		"sync\n\t"
+#endif
 		".set\treorder"
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << (nr & 0x3f)), "m" (*m)
@@ -221,8 +223,7 @@
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int
-__test_and_clear_bit(int nr, volatile void * addr)
+static inline int __test_and_clear_bit(int nr, volatile void * addr)
 {
 	unsigned long mask, retval;
 	unsigned long *a = (unsigned long *) addr;
@@ -243,8 +244,8 @@
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-extern __inline__ unsigned long
-test_and_change_bit(unsigned long nr, volatile void *addr)
+static inline unsigned long test_and_change_bit(unsigned long nr,
+						volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
 	unsigned long temp, res;
@@ -256,6 +257,9 @@
 		"scd\t%2, %1\n\t"
 		"beqz\t%2, 1b\n\t"
 		" and\t%2, %0, %3\n\t"
+#ifdef CONFIG_SMP
+		"sync\n\t"
+#endif
 		".set\treorder"
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << (nr & 0x3f)), "m" (*m)
@@ -273,8 +277,7 @@
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int
-__test_and_change_bit(int nr, volatile void * addr)
+static inline int __test_and_change_bit(int nr, volatile void *addr)
 {
 	unsigned long mask, retval;
 	unsigned long *a = (unsigned long *) addr;
@@ -291,8 +294,7 @@
  * @nr: bit number to test
  * @addr: Address to start counting from
  */
-extern __inline__ unsigned long
-test_bit(int nr, volatile void * addr)
+static inline unsigned long test_bit(int nr, volatile void * addr)
 {
 	return 1UL & (((volatile unsigned long *) addr)[nr >> 6] >> (nr & 0x3f));
 }
@@ -309,8 +311,7 @@
  * Returns the bit-number of the first zero bit, not the number of the byte
  * containing a bit.
  */
-extern __inline__ int
-find_first_zero_bit (void *addr, unsigned size)
+static inline int find_first_zero_bit (void *addr, unsigned size)
 {
 	unsigned long dummy;
 	int res;
@@ -346,8 +347,7 @@
 		"2:"
 		: "=r" (res), "=r" (dummy), "=r" (addr)
 		: "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff),
-		  "2" (addr), "r" (size)
-		: "$1");
+		  "2" (addr), "r" (size));
 
 	return res;
 }
@@ -358,8 +358,7 @@
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-extern __inline__ int
-find_next_zero_bit (void * addr, int size, int offset)
+static inline int find_next_zero_bit (void * addr, int size, int offset)
 {
 	unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
 	int set = 0, bit = offset & 31, res;
@@ -380,8 +379,7 @@
 			".set\treorder\n"
 			"1:"
 			: "=r" (set), "=r" (dummy)
-			: "0" (0), "1" (1 << bit), "r" (*p)
-			: "$1");
+			: "0" (0), "1" (1 << bit), "r" (*p));
 		if (set < (32 - bit))
 			return set + offset;
 		set = 32 - bit;
@@ -402,20 +400,19 @@
  *
  * Undefined if no zero exists, so code should check against ~0UL first.
  */
-extern __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long word)
 {
-	unsigned long k;
+	int b = 0, s;
 
 	word = ~word;
-	k = 63;
-	if (word & 0x00000000ffffffffUL) { k -= 32; word <<= 32; }
-	if (word & 0x0000ffff00000000UL) { k -= 16; word <<= 16; }
-	if (word & 0x00ff000000000000UL) { k -= 8;  word <<= 8;  }
-	if (word & 0x0f00000000000000UL) { k -= 4;  word <<= 4;  }
-	if (word & 0x3000000000000000UL) { k -= 2;  word <<= 2;  }
-	if (word & 0x4000000000000000UL) { k -= 1; }
+        s = 32; if (word << 32 != 0) s = 0; b += s; word >>= s;
+        s = 16; if (word << 48 != 0) s = 0; b += s; word >>= s;
+        s =  8; if (word << 56 != 0) s = 0; b += s; word >>= s;
+        s =  4; if (word << 60 != 0) s = 0; b += s; word >>= s;
+        s =  2; if (word << 62 != 0) s = 0; b += s; word >>= s;
+        s =  1; if (word << 63 != 0) s = 0; b += s;
 
-	return k;
+	return b;
 }
 
 #ifdef __KERNEL__
@@ -453,8 +450,8 @@
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-extern __inline__ unsigned long
-find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+static inline unsigned long find_next_zero_bit(void *addr, unsigned long size,
+					       unsigned long offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
 	unsigned long result = offset & ~63UL;
@@ -501,8 +498,7 @@
 
 #ifdef __MIPSEB__
 
-extern inline int
-ext2_set_bit(int nr,void * addr)
+static inline int ext2_set_bit(int nr,void * addr)
 {
 	int		mask, retval, flags;
 	unsigned char	*ADDR = (unsigned char *) addr;
@@ -516,8 +512,7 @@
 	return retval;
 }
 
-extern inline int
-ext2_clear_bit(int nr, void * addr)
+static inline int ext2_clear_bit(int nr, void * addr)
 {
 	int		mask, retval, flags;
 	unsigned char	*ADDR = (unsigned char *) addr;
@@ -531,8 +526,7 @@
 	return retval;
 }
 
-extern inline int
-ext2_test_bit(int nr, const void * addr)
+static inline int ext2_test_bit(int nr, const void * addr)
 {
 	int			mask;
 	const unsigned char	*ADDR = (const unsigned char *) addr;
@@ -545,8 +539,9 @@
 #define ext2_find_first_zero_bit(addr, size) \
         ext2_find_next_zero_bit((addr), (size), 0)
 
-extern inline unsigned int
-ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+static inline unsigned int ext2_find_next_zero_bit(void *addr,
+						   unsigned long size,
+						   unsigned long offset)
 {
 	unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
 	unsigned int result = offset & ~31UL;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/bootinfo.h linux/include/asm-mips64/bootinfo.h
--- linux.orig/include/asm-mips64/bootinfo.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/bootinfo.h	2002-07-20 01:08:26.000000000 +0000
@@ -1,39 +1,46 @@
 /*
- * bootinfo.h -- Definition of the Linux/MIPS boot information structure
- *
- * Copyright (C) 1995 - 1999 by Ralf Baechle
- * Copyright (C) 1995, 1996 by Stoned Elipot and Paul M. Antoine.
- * Copyright (C) 1999 Ralf Baechle
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive
  * for more details.
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle, Andreas Busse,
+ *                             Stoned Elipot and Paul M. Antoine.
  */
 #ifndef _ASM_BOOTINFO_H
 #define _ASM_BOOTINFO_H
 
+#include <linux/types.h>
+
 /*
  * Values for machgroup
  */
-#define MACH_GROUP_UNKNOWN      0 /* whatever... */
-#define MACH_GROUP_JAZZ     	1 /* Jazz                                     */
-#define MACH_GROUP_DEC          2 /* Digital Equipment                        */
+#define MACH_GROUP_UNKNOWN      0 /* whatever...                            */
+#define MACH_GROUP_JAZZ     	1 /* Jazz                                   */
+#define MACH_GROUP_DEC          2 /* Digital Equipment                      */
 #define MACH_GROUP_ARC		3 /* Wreckstation Tyne, rPC44, possibly other */
-#define MACH_GROUP_SNI_RM	4 /* Siemens Nixdorf RM series                */
+#define MACH_GROUP_SNI_RM	4 /* Siemens Nixdorf RM series              */
 #define MACH_GROUP_ACN		5
-#define MACH_GROUP_SGI          6 /* Silicon Graphics workstations and servers */
-#define MACH_GROUP_COBALT       7 /* Cobalt servers		 	      */
-
-#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", \
-                      "SNI", "ACN", "SGI", "Cobalt" }
+#define MACH_GROUP_SGI          6 /* Silicon Graphics                       */
+#define MACH_GROUP_COBALT       7 /* Cobalt servers		 	    */
+#define MACH_GROUP_NEC_DDB	8 /* NEC DDB                                */
+#define MACH_GROUP_BAGET	9 /* Baget                                  */
+#define MACH_GROUP_COSINE      10 /* CoSine Orion                           */
+#define MACH_GROUP_GALILEO     11 /* Galileo Eval Boards                    */
+#define MACH_GROUP_MOMENCO     12 /* Momentum Boards                        */
+#define MACH_GROUP_ITE         13 /* ITE Semi Eval Boards                   */
+#define MACH_GROUP_PHILIPS     14
+#define MACH_GROUP_GLOBESPAN   15 /* Globespan PVR Referrence Board         */
+#define MACH_GROUP_SIBYTE      16 /* Sibyte Eval Boards                     */
+#define MACH_GROUP_TOSHIBA     17 /* Toshiba Reference Systems TSBREF       */
+#define MACH_GROUP_ALCHEMY     18 /* Alchemy Semi Eval Boards               */
+#define MACH_GROUP_NEC_VR41XX  19 /* NEC Vr41xx based boards/gadgets        */
+#define MACH_GROUP_HP_LJ       20 /* Hewlett Packard LaserJet               */
 
 /*
  * Valid machtype values for group unknown (low order halfword of mips_machtype)
  */
 #define MACH_UNKNOWN		0	/* whatever...			*/
 
-#define GROUP_UNKNOWN_NAMES { "unknown" }
-
 /*
  * Valid machtype values for group JAZZ
  */
@@ -41,8 +48,6 @@
 #define MACH_MIPS_MAGNUM_4000	1	/* Mips Magnum 4000 "RC4030"	*/
 #define MACH_OLIVETTI_M700      2	/* Olivetti M700-10 (-15 ??)    */
 
-#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" }
-
 /*
  * Valid machtype for group DEC 
  */
@@ -57,131 +62,134 @@
 #define MACH_DS5500		8	/* DECstation 5500		*/
 #define MACH_DS5800		9	/* DECstation 5800		*/
 
-#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \
-	"DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \
-	"DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \
-	"DECstation 5800" }
-
 /*
  * Valid machtype for group ARC
  */
 #define MACH_DESKSTATION_RPC44  0	/* Deskstation rPC44 */
 #define MACH_DESKSTATION_TYNE	1	/* Deskstation Tyne */
 
-#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" }
-
 /*
  * Valid machtype for group SNI_RM
  */
 #define MACH_SNI_RM200_PCI	0	/* RM200/RM300/RM400 PCI series */
 
-#define GROUP_SNI_RM_NAMES { "RM200 PCI" }
-
 /*
  * Valid machtype for group ACN
  */
 #define MACH_ACN_MIPS_BOARD	0       /* ACN MIPS single board        */
 
-#define GROUP_ACN_NAMES { "ACN" }
-
 /*
  * Valid machtype for group SGI
  */
 #define MACH_SGI_INDY		0	/* R4?K and R5K Indy workstations */
-#define MACH_SGI_CHALLENGE_S	1       /* The Challenge S server */
+#define MACH_SGI_CHALLENGE_S	1	/* The Challenge S server */
 #define MACH_SGI_INDIGO2	2	/* The Indigo2 system */
 #define MACH_SGI_IP27		3	/* Origin 200, Origin 2000, Onyx 2 */
-
-#define GROUP_SGI_NAMES { "Indy", "Challenge S", "Indigo2", "IP27" }
-
+#define MACH_SGI_IP28		4	/* Indigo2 Impact */
+#define MACH_SGI_IP32		5	/* O2 */
 
 /*
  * Valid machtype for group COBALT
  */
 #define MACH_COBALT_27 		 0	/* Proto "27" hardware */
 
-#define GROUP_COBALT_NAMES { "Microserver 27" }
+/*
+ * Valid machtype for group NEC DDB
+ */
+#define MACH_NEC_DDB5074	 0	/* NEC DDB Vrc-5074 */
+#define MACH_NEC_DDB5476         1      /* NEC DDB Vrc-5476 */
+#define MACH_NEC_DDB5477         2      /* NEC DDB Vrc-5477 */
+#define MACH_NEC_ROCKHOPPER      3      /* Rockhopper base board */
 
 /*
- * Valid cputype values
+ * Valid machtype for group BAGET
  */
-#define CPU_UNKNOWN		0
-#define CPU_R2000		1
-#define CPU_R3000		2
-#define CPU_R3000A		3
-#define CPU_R3041		4
-#define CPU_R3051		5
-#define CPU_R3052		6
-#define CPU_R3081		7
-#define CPU_R3081E		8
-#define CPU_R4000PC		9
-#define CPU_R4000SC		10
-#define CPU_R4000MC		11
-#define CPU_R4200		12
-#define CPU_R4400PC		13
-#define CPU_R4400SC		14
-#define CPU_R4400MC		15
-#define CPU_R4600		16
-#define CPU_R6000		17
-#define CPU_R6000A		18
-#define CPU_R8000		19
-#define CPU_R10000		20
-#define CPU_R4300		21
-#define CPU_R4650		22
-#define CPU_R4700		23
-#define CPU_R5000		24
-#define CPU_R5000A		25
-#define CPU_R4640		26
-#define CPU_NEVADA		27	/* RM5230, RM5260 */
-#define CPU_LAST		27
-
-#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \
-        "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC",         \
-        "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000",          \
-        "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000",     \
-        "R5000A", "R4640", "Nevada" }
-
-#define CL_SIZE      (80)
-
-#define BOOT_MEM_MAP_MAX        32
-#define BOOT_MEM_RAM            1
-#define BOOT_MEM_ROM_DATA       2
-#define BOOT_MEM_RESERVED       3
+#define MACH_BAGET201		0	/* BT23-201 */
+#define MACH_BAGET202		1	/* BT23-202 */
 
-#ifndef _LANGUAGE_ASSEMBLY
+/*
+ * Cosine boards.
+ */
+#define MACH_COSINE_ORION	0
 
 /*
- * Some machine parameters passed by the bootloaders. 
+ * Valid machtype for group GALILEO
  */
+#define MACH_EV96100		0	/* EV96100 */
+#define MACH_EV64120A		1	/* EV64120A */
 
-struct drive_info_struct {
-	char dummy[32];
-};
+/*
+ * Valid machtype for group MOMENCO
+ */
+#define MACH_MOMENCO_OCELOT	0
+ 
+/*
+ * Valid machtype for group ITE
+ */
+#define MACH_QED_4N_S01B	0	/* ITE8172 based eval board */
+ 
+/*
+ * Valid machtype for group Globespan
+ */
+#define MACH_IVR       0                  /* IVR eval board */
+
+/*
+ * Valid machtype for group PHILIPS
+ */
+#define MACH_PHILIPS_NINO	0	/* Nino */
+#define MACH_PHILIPS_VELO	1	/* Velo */
+
+/*
+ * Valid machtype for group SIBYTE
+ */
+#define MACH_SWARM              0
+
+/*
+ * Valid machtypes for group Toshiba
+ */
+#define MACH_PALLAS		0
+#define MACH_TOPAS		1
+#define MACH_JMR		2
+#define MACH_TOSHIBA_JMR3927    3      /* JMR-TX3927 CPU/IO board */
+
+/*
+ * Valid machtype for group Alchemy
+ */
+#define MACH_PB1000	0	         /* Au1000-based eval board */
+#define MACH_PB1500	1	         /* Au1500-based eval board */
+ 
+/*
+ * Valid machtype for group NEC_VR41XX
+ */
+#define MACH_NEC_OSPREY                0       /* Osprey eval board */
+
+#define CL_SIZE			(256)
+
+const char *get_system_type(void);
 
-extern unsigned long mips_memory_upper;
-extern unsigned long mips_cputype;
 extern unsigned long mips_machtype;
 extern unsigned long mips_machgroup;
-extern unsigned long mips_tlb_entries;
+
+#define BOOT_MEM_MAP_MAX	32
+#define BOOT_MEM_RAM		1
+#define BOOT_MEM_ROM_DATA	2
+#define BOOT_MEM_RESERVED	3
 
 /*
  * A memory map that's built upon what was determined
  * or specified on the command line.
  */
 struct boot_mem_map {
-        int nr_map;
-        struct {
-                unsigned long addr;     /* start of memory segment */
-                unsigned long size;     /* size of memory segment */
-                long type;              /* type of memory segment */
-        } map[BOOT_MEM_MAP_MAX];
+	int nr_map;
+	struct {
+		phys_t addr;	/* start of memory segment */
+		phys_t size;	/* size of memory segment */
+		long type;		/* type of memory segment */
+	} map[BOOT_MEM_MAP_MAX];
 };
 
 extern struct boot_mem_map boot_mem_map;
 
-extern void add_memory_region(unsigned long start, unsigned long size,
-                              long type);
-
-#endif /* _LANGUAGE_ASSEMBLY */
+extern void add_memory_region(phys_t start, phys_t size, long type);
 
 #endif /* _ASM_BOOTINFO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/branch.h linux/include/asm-mips64/branch.h
--- linux.orig/include/asm-mips64/branch.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/branch.h	2002-07-20 01:08:25.000000000 +0000
@@ -3,20 +3,29 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Branch and jump emulation.
- *
- * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle
  */
+#ifndef _ASM_BRANCH_H
+#define _ASM_BRANCH_H
+
 #include <asm/ptrace.h>
 
-extern inline int delay_slot(struct pt_regs *regs)
+static inline int delay_slot(struct pt_regs *regs)
 {
 	return regs->cp0_cause & CAUSEF_BD;
 }
 
+static inline unsigned long exception_epc(struct pt_regs *regs)
+{
+	if (!delay_slot(regs))
+		return regs->cp0_epc;
+
+	return regs->cp0_epc + 4;
+}
+
 extern int __compute_return_epc(struct pt_regs *regs);
 
-extern inline int compute_return_epc(struct pt_regs *regs)
+static inline int compute_return_epc(struct pt_regs *regs)
 {
 	if (!delay_slot(regs)) {
 		regs->cp0_epc += 4;
@@ -25,3 +34,5 @@
 
 	return __compute_return_epc(regs);
 }
+
+#endif /* _ASM_BRANCH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/bugs.h linux/include/asm-mips64/bugs.h
--- linux.orig/include/asm-mips64/bugs.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/bugs.h	2002-07-20 01:08:31.000000000 +0000
@@ -1,38 +1,12 @@
 /*
- *  Copyright (C) 1995 Waldorf Electronics
- *  Copyright (C) 1997, 1999 Ralf Baechle
- */
-#include <asm/bootinfo.h>
-
-/*
  * This is included by init/main.c to check for architecture-dependent bugs.
  *
  * Needs:
  *	void check_bugs(void);
  */
+#ifndef __ASM_BUGS_H
+#define __ASM_BUGS_H
 
+extern void check_bugs(void);
 
-static inline void check_wait(void)
-{
-	printk("Checking for 'wait' instruction... ");
-	switch(mips_cputype) {
-	case CPU_R4200: 
-	case CPU_R4300: 
-	case CPU_R4600: 
-	case CPU_R4700: 
-	case CPU_R5000: 
-	case CPU_NEVADA:
-		wait_available = 1;
-		printk(" available.\n");
-		break;
-	default:
-		printk(" unavailable.\n");
-		break;
-	}
-}
-
-static void __init
-check_bugs(void)
-{
-	check_wait();
-}
+#endif /* __ASM_BUGS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/cache.h linux/include/asm-mips64/cache.h
--- linux.orig/include/asm-mips64/cache.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/cache.h	2002-07-20 01:08:35.000000000 +0000
@@ -9,6 +9,20 @@
 #ifndef _ASM_CACHE_H
 #define _ASM_CACHE_H
 
+#include <linux/config.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * Descriptor for a cache
+ */
+struct cache_desc {
+	int linesz;
+	int sets;
+	int ways;
+	int flags;	/* Details like write thru/back, coherent, etc. */
+};
+#endif /* !__ASSEMBLY__ */
+
 /* bytes per L1 cache line */
 #define L1_CACHE_BYTES		(1 << CONFIG_L1_CACHE_SHIFT)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/cacheops.h linux/include/asm-mips64/cacheops.h
--- linux.orig/include/asm-mips64/cacheops.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/cacheops.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,47 @@
+/*
+ * Cache operations for the cache instruction.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) Copyright 1996, 1997 by Ralf Baechle
+ */
+#ifndef	__ASM_MIPS_CACHEOPS_H
+#define	__ASM_MIPS_CACHEOPS_H
+
+/*
+ * Cache Operations
+ */
+#define Index_Invalidate_I      0x00
+#define Index_Writeback_Inv_D   0x01
+#define Index_Invalidate_SI     0x02
+#define Index_Writeback_Inv_SD  0x03
+#define Index_Load_Tag_I	0x04
+#define Index_Load_Tag_D	0x05
+#define Index_Load_Tag_SI	0x06
+#define Index_Load_Tag_SD	0x07
+#define Index_Store_Tag_I	0x08
+#define Index_Store_Tag_D	0x09
+#define Index_Store_Tag_SI	0x0A
+#define Index_Store_Tag_SD	0x0B
+#define Create_Dirty_Excl_D	0x0d
+#define Create_Dirty_Excl_SD	0x0f
+#define Hit_Invalidate_I	0x10
+#define Hit_Invalidate_D	0x11
+#define Hit_Invalidate_SI	0x12
+#define Hit_Invalidate_SD	0x13
+#define Fill			0x14
+#define Hit_Writeback_Inv_D	0x15
+					/* 0x16 is unused */
+#define Hit_Writeback_Inv_SD	0x17
+#define Hit_Writeback_I		0x18
+#define Hit_Writeback_D		0x19
+					/* 0x1a is unused */
+#define Hit_Writeback_SD	0x1b
+					/* 0x1c is unused */
+					/* 0x1e is unused */
+#define Hit_Set_Virtual_SI	0x1e
+#define Hit_Set_Virtual_SD	0x1f
+
+#endif	/* __ASM_MIPS_CACHEOPS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/checksum.h linux/include/asm-mips64/checksum.h
--- linux.orig/include/asm-mips64/checksum.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/checksum.h	2002-07-20 01:08:30.000000000 +0000
@@ -6,6 +6,7 @@
  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) 2001 Thiemo Seufer.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #ifndef _ASM_CHECKSUM_H
 #define _ASM_CHECKSUM_H
@@ -43,7 +44,7 @@
  * Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-extern inline unsigned int csum_and_copy_to_user (const char *src, char *dst,
+static inline unsigned int csum_and_copy_to_user (const char *src, char *dst,
 						  int len, int sum,
 						  int *err_ptr)
 {
@@ -82,8 +83,7 @@
 	"xori\t%0,0xffff\n\t"
 	".set\tat"
 	: "=r" (sum)
-	: "0" (sum)
-	: "$1");
+	: "0" (sum));
 
  	return sum;
 }
@@ -135,8 +135,7 @@
 	"2:\t.set\tat\n\t"
 	".set\treorder"
 	: "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy)
-	: "1" (iph), "2" (ihl)
-	: "$1");
+	: "1" (iph), "2" (ihl));
 
 	return csum_fold(sum);
 }
@@ -144,6 +143,10 @@
 /*
  * computes the checksum of the TCP/UDP pseudo-header
  * returns a 16-bit checksum, already complemented
+ *
+ * Cast unsigned short expressions to unsigned long explicitly
+ * to avoid surprises resulting from implicit promotions to
+ * signed int.  --macro
  */
 static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
 					       unsigned long daddr,
@@ -160,15 +163,14 @@
 	"daddu\t%0, $1\n\t"
 	"dsrl32\t%0, %0, 0\n\t"
 	".set\tat"
-	: "=r" (sum)
+	: "=&r" (sum)
 	: "0" (daddr), "r"(saddr),
 #ifdef __MIPSEL__
-	  "r" ((ntohs(len)<<16)+proto*256),
+	  "r" (((unsigned long)ntohs(len)<<16)+proto*256),
 #else
-	  "r" (((proto)<<16)+len),
+	  "r" (((unsigned long)(proto)<<16)+len),
 #endif
-	  "r" (sum)
-	: "$1");
+	  "r" (sum));
 
 	return sum;
 }
@@ -196,11 +198,11 @@
 }
 
 #define _HAVE_ARCH_IPV6_CSUM
-static inline unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
-						 struct in6_addr *daddr,
-						 __u32 len,
-						 unsigned short proto,
-						 unsigned int sum) 
+static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
+						     struct in6_addr *daddr,
+						     __u32 len,
+						     unsigned short proto,
+						     unsigned int sum) 
 {
 	__asm__(
 	".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t"
@@ -214,48 +216,49 @@
 	"lw\t%1, 0(%2)\t\t\t# four words source address\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 4(%2)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 8(%2)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 12(%2)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 0(%3)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 4(%3)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 8(%3)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
 
 	"lw\t%1, 12(%3)\n\t"
 	"addu\t%0, $1\n\t"
 	"addu\t%0, %1\n\t"
-	"sltu\t$1, %0, $1\n\t"
+	"sltu\t$1, %0, %1\n\t"
+
+	"addu\t%0, $1\t\t\t# Add final carry\n\t"
 	".set\tnoat\n\t"
 	".set\tnoreorder"
-	: "=r" (sum), "=r" (proto)
+	: "=&r" (sum), "=&r" (proto)
 	: "r" (saddr), "r" (daddr),
-	  "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)
-	: "$1");
+	  "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
 
 	return csum_fold(sum);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/cpu.h linux/include/asm-mips64/cpu.h
--- linux.orig/include/asm-mips64/cpu.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/cpu.h	2002-07-20 01:08:26.000000000 +0000
@@ -1,8 +1,4 @@
 /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
  * cpu.h: Values of the PRId register used to match up
  *        various MIPS cpu types.
  *
@@ -11,35 +7,160 @@
 #ifndef _ASM_CPU_H
 #define _ASM_CPU_H
 
+#include <asm/cache.h>
+
+/* Assigned Company values for bits 23:16 of the PRId Register  
+   (CP0 register 15, select 0).  As of the MIPS32 and MIPS64 specs from 
+   MTI, the PRId register is defined in this (backwards compatible)
+   way:
+
+  +----------------+----------------+----------------+----------------+
+  | Company Options| Company ID     | Processor ID   | Revision       |
+  +----------------+----------------+----------------+----------------+
+   31            24 23            16 15             8 7
+
+   I don't have docs for all the previous processors, but my impression is
+   that bits 16-23 have been 0 for all MIPS processors before the MIPS32/64
+   spec.  
+*/
+
+#define PRID_COMP_LEGACY       0x000000
+#define PRID_COMP_MIPS         0x010000
+#define PRID_COMP_BROADCOM     0x020000
+#define PRID_COMP_ALCHEMY      0x030000
+#define PRID_COMP_SIBYTE       0x040000
+
 /*
  * Assigned values for the product ID register.  In order to detect a
  * certain CPU type exactly eventually additional registers may need to
- * be examined.
+ * be examined.  These are valid when 23:16 == PRID_COMP_LEGACY
+ */
+#define PRID_IMP_R2000		0x0100
+#define PRID_IMP_AU1_REV1	0x0100
+#define PRID_IMP_AU1_REV2	0x0200
+#define PRID_IMP_R3000		0x0200		/* Same as R2000A  */
+#define PRID_IMP_R6000		0x0300		/* Same as R3000A  */
+#define PRID_IMP_R4000		0x0400
+#define PRID_IMP_R6000A		0x0600
+#define PRID_IMP_R10000		0x0900
+#define PRID_IMP_R4300		0x0b00
+#define PRID_IMP_VR41XX		0x0c00
+#define PRID_IMP_R12000		0x0e00
+#define PRID_IMP_R8000		0x1000
+#define PRID_IMP_R4600		0x2000
+#define PRID_IMP_R4700		0x2100
+#define PRID_IMP_TX39		0x2200
+#define PRID_IMP_R4640		0x2200
+#define PRID_IMP_R4650		0x2200		/* Same as R4640 */
+#define PRID_IMP_R5000		0x2300
+#define PRID_IMP_TX49		0x2d00
+#define PRID_IMP_SONIC		0x2400
+#define PRID_IMP_MAGIC		0x2500
+#define PRID_IMP_RM7000		0x2700
+#define PRID_IMP_NEVADA		0x2800		/* RM5260 ??? */
+#define PRID_IMP_R5432		0x5400
+#define PRID_IMP_R5500		0x5500
+#define PRID_IMP_4KC		0x8000
+#define PRID_IMP_5KC		0x8100
+#define PRID_IMP_20KC		0x8200
+#define PRID_IMP_4KEC		0x8400
+#define PRID_IMP_4KSC		0x8600
+
+
+#define PRID_IMP_UNKNOWN	0xff00
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
+ */
+
+#define PRID_IMP_SB1            0x0100
+
+/*
+ * Definitions for 7:0 on legacy processors
+ */
+
+
+#define PRID_REV_R4400		0x0040
+#define PRID_REV_R3000A		0x0030
+#define PRID_REV_R3000		0x0020
+#define PRID_REV_R2000A		0x0010
+#define PRID_REV_TX3912 	0x0010
+#define PRID_REV_TX3922 	0x0030
+#define PRID_REV_TX3927 	0x0040
+
+/*
+ * FPU implementation/revision register (CP1 control register 0).
+ *
+ * +---------------------------------+----------------+----------------+
+ * | 0                               | Implementation | Revision       |
+ * +---------------------------------+----------------+----------------+
+ *  31                             16 15             8 7              0
+ */
+
+#define FPIR_IMP_NONE		0x0000
+
+#ifndef __ASSEMBLY__
+/*
+ * Capability and feature descriptor structure for MIPS CPU
+ */
+struct mips_cpu {
+	unsigned int processor_id;
+	unsigned int fpu_id;
+	unsigned int cputype;
+	int isa_level;
+	int options;
+	int tlbsize;
+	struct cache_desc icache;	/* Primary I-cache */
+	struct cache_desc dcache;	/* Primary D or combined I/D cache */
+	struct cache_desc scache;	/* Secondary cache */
+	struct cache_desc tcache;	/* Tertiary/split secondary cache */
+};
+
+extern struct mips_cpu mips_cpu;
+
+enum cputype {
+	CPU_UNKNOWN,
+	CPU_R2000, CPU_R3000, CPU_R3000A, CPU_R3041, CPU_R3051, CPU_R3052,
+	CPU_R3081, CPU_R3081E, CPU_R4000PC, CPU_R4000SC, CPU_R4000MC,
+	CPU_R4200, CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600,
+	CPU_R6000, CPU_R6000A, CPU_R8000, CPU_R10000, CPU_R12000, CPU_R4300,
+	CPU_R4650, CPU_R4700, CPU_R5000, CPU_R5000A, CPU_R4640, CPU_NEVADA,
+	CPU_RM7000, CPU_R5432, CPU_4KC, CPU_5KC, CPU_R4310, CPU_SB1,
+	CPU_TX3912, CPU_TX3922, CPU_TX3927, CPU_AU1000, CPU_4KEC, CPU_4KSC,
+	CPU_VR41XX, CPU_R5500, CPU_TX49XX, CPU_TX39XX, CPU_AU1500, CPU_20KC,
+	CPU_LAST
+};
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * ISA Level encodings
+ */
+#define MIPS_CPU_ISA_I		0x00000001
+#define MIPS_CPU_ISA_II		0x00000002
+#define MIPS_CPU_ISA_III	0x00000003
+#define MIPS_CPU_ISA_IV		0x00000004
+#define MIPS_CPU_ISA_V		0x00000005
+#define MIPS_CPU_ISA_M32	0x00000020
+#define MIPS_CPU_ISA_M64	0x00000040
+
+/*
+ * CPU Option encodings
  */
-#define PRID_IMP_R2000    0x0100
-#define PRID_IMP_R3000    0x0200	/* Same as R2000A  */
-#define PRID_IMP_R6000    0x0300	/* Same as R3000A  */
-#define PRID_IMP_R4000    0x0400
-#define PRID_IMP_R6000A   0x0600
-#define PRID_IMP_R10000   0x0900
-#define PRID_IMP_R4300    0x0b00
-#define PRID_IMP_R12000   0x0e00
-#define PRID_IMP_R8000    0x1000
-#define PRID_IMP_R4600    0x2000
-#define PRID_IMP_R4700    0x2100
-#define PRID_IMP_R4640    0x2200
-#define PRID_IMP_R4650    0x2200	/* Same as R4640 */
-#define PRID_IMP_R5000    0x2300
-#define PRID_IMP_SONIC    0x2400
-#define PRID_IMP_MAGIC    0x2500
-#define PRID_IMP_RM7000   0x2700
-#define PRID_IMP_NEVADA   0x2800
-
-#define PRID_IMP_UNKNOWN  0xff00
-
-#define PRID_REV_R4400    0x0040
-#define PRID_REV_R3000A   0x0030
-#define PRID_REV_R3000    0x0020
-#define PRID_REV_R2000A   0x0010
+#define MIPS_CPU_TLB		0x00000001 /* CPU has TLB */
+/* Leave a spare bit for variant MMU types... */
+#define MIPS_CPU_4KEX		0x00000004 /* "R4K" exception model */
+#define MIPS_CPU_4KTLB		0x00000008 /* "R4K" TLB handler */
+#define MIPS_CPU_FPU		0x00000010 /* CPU has FPU */
+#define MIPS_CPU_32FPR		0x00000020 /* 32 dbl. prec. FP registers */
+#define MIPS_CPU_COUNTER	0x00000040 /* Cycle count/compare */
+#define MIPS_CPU_WATCH		0x00000080 /* watchpoint registers */
+#define MIPS_CPU_MIPS16		0x00000100 /* code compression */
+#define MIPS_CPU_DIVEC		0x00000200 /* dedicated interrupt vector */
+#define MIPS_CPU_VCE		0x00000400 /* virt. coherence conflict possible */
+#define MIPS_CPU_CACHE_CDEX	0x00000800 /* Create_Dirty_Exclusive CACHE op */
+#define MIPS_CPU_MCHECK		0x00001000 /* Machine check exception */
+#define MIPS_CPU_EJTAG		0x00002000 /* EJTAG exception */
+#define MIPS_CPU_NOFPUEX	0x00000000 /* no FPU exception; never set */
 
 #endif /* _ASM_CPU_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/current.h linux/include/asm-mips64/current.h
--- linux.orig/include/asm-mips64/current.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/current.h	2002-07-20 01:08:26.000000000 +0000
@@ -8,10 +8,11 @@
 #ifndef _ASM_CURRENT_H
 #define _ASM_CURRENT_H
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /* MIPS rules... */
 register struct task_struct *current asm("$28");
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
+
 #endif /* _ASM_CURRENT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/div64.h linux/include/asm-mips64/div64.h
--- linux.orig/include/asm-mips64/div64.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/div64.h	2002-07-20 01:08:36.000000000 +0000
@@ -7,6 +7,45 @@
 #define _ASM_DIV64_H
 
 /*
+ * Don't use this one in new code
+ */
+#define do_div64_32(res, high, low, base) ({ \
+	unsigned long __quot, __mod; \
+	unsigned long __cf, __tmp, __tmp2, __i; \
+	\
+	__asm__(".set	push\n\t" \
+		".set	noat\n\t" \
+		".set	noreorder\n\t" \
+		"move	%2, $0\n\t" \
+		"move	%3, $0\n\t" \
+		"b	1f\n\t" \
+		" li	%4, 0x21\n" \
+		"0:\n\t" \
+		"sll	$1, %0, 0x1\n\t" \
+		"srl	%3, %0, 0x1f\n\t" \
+		"or	%0, $1, %5\n\t" \
+		"sll	%1, %1, 0x1\n\t" \
+		"sll	%2, %2, 0x1\n" \
+		"1:\n\t" \
+		"bnez	%3, 2f\n\t" \
+		"sltu	%5, %0, %z6\n\t" \
+		"bnez	%5, 3f\n\t" \
+		"2:\n\t" \
+		" addiu	%4,%4,-1\n\t" \
+		"subu	%0, %0, %z6\n\t" \
+		"addiu	%2, %2, 1\n" \
+		"3:\n\t" \
+		"bnez	%4, 0b\n\t" \
+		" srl	%5, %1, 0x1f\n\t" \
+		".set	pop" \
+		: "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
+		  "=&r" (__i), "=&r" (__tmp2) \
+		: "Jr" (base), "0" (high), "1" (low)); \
+	\
+	(res) = __quot; \
+	__mod; })
+
+/*
  * Hey, we're already 64-bit, no
  * need to play games..
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/elf.h linux/include/asm-mips64/elf.h
--- linux.orig/include/asm-mips64/elf.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/elf.h	2002-07-20 01:08:22.000000000 +0000
@@ -14,6 +14,17 @@
 #define ELF_NGREG	45
 #define ELF_NFPREG	33
 
+/* ELF header e_flags defines. MIPS architecture level. */
+#define EF_MIPS_ARCH_1      0x00000000  /* -mips1 code.  */
+#define EF_MIPS_ARCH_2      0x10000000  /* -mips2 code.  */
+#define EF_MIPS_ARCH_3      0x20000000  /* -mips3 code.  */
+#define EF_MIPS_ARCH_4      0x30000000  /* -mips4 code.  */
+#define EF_MIPS_ARCH_5      0x40000000  /* -mips5 code.  */
+#define EF_MIPS_ARCH_32     0x60000000  /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64     0x70000000  /* MIPS64 code.  */
+#define EF_MIPS_ARCH_32R2   0x80000000  /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64R2   0x90000000  /* MIPS64 code.  */
+
 typedef unsigned long elf_greg_t;
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
@@ -21,8 +32,7 @@
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
 /*
- * This is used to ensure we don't load something for the wrong 
- * architecture or OS.
+ * This is used to ensure we don't load something for the wrong architecture.
  */
 #define elf_check_arch(hdr)						\
 ({									\
@@ -34,6 +44,11 @@
 	if (sizeof(elf_caddr_t) == 8 &&					\
 	    __h->e_ident[EI_CLASS] == ELFCLASS32)			\
 	        __res = 0;						\
+	if (((__h->e_flags & EF_MIPS_ARCH) != EF_MIPS_ARCH_1) &&	\
+	    ((__h->e_flags & EF_MIPS_ARCH) != EF_MIPS_ARCH_2) &&	\
+	    ((__h->e_flags & EF_MIPS_ARCH) != EF_MIPS_ARCH_32) &&	\
+	    ((__h->e_flags & EF_MIPS_ARCH) != EF_MIPS_ARCH_32R2))	\
+                __res = 0;						\
 									\
 	__res;								\
 })
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/errno.h linux/include/asm-mips64/errno.h
--- linux.orig/include/asm-mips64/errno.h	2001-04-14 03:26:07.000000000 +0000
+++ linux/include/asm-mips64/errno.h	2002-07-20 01:08:35.000000000 +0000
@@ -18,7 +18,7 @@
 #define	EINTR		 4	/* Interrupted system call */
 #define	EIO		 5	/* I/O error */
 #define	ENXIO		 6	/* No such device or address */
-#define	E2BIG		 7	/* Arg list too long */
+#define	E2BIG		 7	/* Argument list too long */
 #define	ENOEXEC		 8	/* Exec format error */
 #define	EBADF		 9	/* Bad file number */
 #define	ECHILD		10	/* No child processes */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/exception.h linux/include/asm-mips64/exception.h
--- linux.orig/include/asm-mips64/exception.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/exception.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,76 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics
+ *
+ * Low level exception handling
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+	.macro	__build_clear_none
+	.endm
+
+	.macro	__build_clear_sti
+	STI
+	.endm
+
+	.macro	__build_clear_cli
+	CLI
+	.endm
+
+	.macro	__build_clear_fpe
+	cfc1	a1, fcr31
+	li	a2, ~(0x3f << 12)
+	and	a2, a1
+	ctc1	a2, fcr31
+	STI
+	.endm
+
+	.macro	__build_clear_ade
+	dmfc0	t0, CP0_BADVADDR
+	sd	t0, PT_BVADDR(sp)
+	KMODE
+	.endm
+
+	.macro	__BUILD_silent exception
+	.endm
+
+	/* Gas tries to parse the PRINT argument as a string containing
+	   string escapes and emits bogus warnings if it believes to
+	   recognize an unknown escape code.  So make the arguments
+	   start with an n and gas will believe \n is ok ...  */
+	.macro	__BUILD_verbose	nexception
+	ld	a1, PT_EPC(sp)
+	PRINT("Got \nexception at %016lx\012")
+	.endm
+
+	.macro	__BUILD_count exception
+	.set	reorder
+	ld	t0,exception_count_\exception
+	daddiu	t0, 1
+	sd	t0,exception_count_\exception
+	.set	noreorder
+	.comm	exception_count\exception, 8, 8
+	.endm
+
+	.macro	BUILD_HANDLER exception handler clear verbose
+	.align	5
+	NESTED(handle_\exception, PT_SIZE, sp)
+	.set	noat
+	SAVE_ALL
+	__BUILD_clear_\clear
+	.set	at
+	__BUILD_\verbose \exception
+	move	a0, sp
+	jal	do_\handler
+	j	ret_from_sys_call
+	 nop
+	END(handle_\exception)
+	.endm
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/fcntl.h linux/include/asm-mips64/fcntl.h
--- linux.orig/include/asm-mips64/fcntl.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/fcntl.h	2002-07-20 01:08:22.000000000 +0000
@@ -22,8 +22,8 @@
 #define O_EXCL		0x0400	/* not fcntl */
 #define O_NOCTTY	0x0800	/* not fcntl */
 #define FASYNC		0x1000	/* fcntl, for BSD compatibility */
-#define O_LARGEFILE	0x2000	/* allow large file opens - currently ignored */
-#define O_DIRECT	0x8000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0x2000	/* allow large file opens */
+#define O_DIRECT	0x8000	/* direct disk access hint */
 #define O_DIRECTORY	0x10000	/* must be a directory */
 #define O_NOFOLLOW	0x20000	/* don't follow links */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/floppy.h linux/include/asm-mips64/floppy.h
--- linux.orig/include/asm-mips64/floppy.h	2001-10-25 20:53:55.000000000 +0000
+++ linux/include/asm-mips64/floppy.h	2002-07-20 01:08:27.000000000 +0000
@@ -10,8 +10,6 @@
 #ifndef _ASM_FLOPPY_H
 #define _ASM_FLOPPY_H
 
-#include <asm/bootinfo.h>
-
 struct fd_ops {
 	unsigned char (*fd_inb)(unsigned int port);
 	void (*fd_outb)(unsigned char value, unsigned int port);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/fpu_emulator.h linux/include/asm-mips64/fpu_emulator.h
--- linux.orig/include/asm-mips64/fpu_emulator.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/fpu_emulator.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,38 @@
+/*
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Further private data for which no space exists in mips_fpu_soft_struct.
+ * This should be subsumed into the mips_fpu_soft_struct structure as
+ * defined in processor.h as soon as the absurd wired absolute assembler
+ * offsets become dynamic at compile time.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ */
+#ifndef _ASM_FPU_EMULATOR_H
+#define _ASM_FPU_EMULATOR_H
+
+struct mips_fpu_emulator_private {
+	unsigned int eir;
+	struct {
+		unsigned int emulated;
+		unsigned int loads;
+		unsigned int stores;
+		unsigned int cp1ops;
+		unsigned int cp1xops;
+		unsigned int errors;
+	} stats;
+};
+
+#endif /* _ASM_FPU_EMULATOR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/gdb-stub.h linux/include/asm-mips64/gdb-stub.h
--- linux.orig/include/asm-mips64/gdb-stub.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/gdb-stub.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,212 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 Andreas Busse
+ */
+#ifndef __ASM_MIPS_GDB_STUB_H
+#define __ASM_MIPS_GDB_STUB_H
+
+
+/*
+ * important register numbers
+ */
+
+#define REG_EPC			37
+#define REG_FP			72
+#define REG_SP			29
+
+/*
+ * Stack layout for the GDB exception handler
+ * Derived from the stack layout described in asm-mips/stackframe.h
+ *
+ * The first PTRSIZE*5 bytes are argument save space for C subroutines.
+ */
+#define NUMREGS			90
+
+#define GDB_FR_REG0		(PTRSIZE*5)			/* 0 */
+#define GDB_FR_REG1		((GDB_FR_REG0) + 4)		/* 1 */
+#define GDB_FR_REG2		((GDB_FR_REG1) + 4)		/* 2 */
+#define GDB_FR_REG3		((GDB_FR_REG2) + 4)		/* 3 */
+#define GDB_FR_REG4		((GDB_FR_REG3) + 4)		/* 4 */
+#define GDB_FR_REG5		((GDB_FR_REG4) + 4)		/* 5 */
+#define GDB_FR_REG6		((GDB_FR_REG5) + 4)		/* 6 */
+#define GDB_FR_REG7		((GDB_FR_REG6) + 4)		/* 7 */
+#define GDB_FR_REG8		((GDB_FR_REG7) + 4)		/* 8 */
+#define GDB_FR_REG9	        ((GDB_FR_REG8) + 4)		/* 9 */
+#define GDB_FR_REG10		((GDB_FR_REG9) + 4)		/* 10 */
+#define GDB_FR_REG11		((GDB_FR_REG10) + 4)		/* 11 */
+#define GDB_FR_REG12		((GDB_FR_REG11) + 4)		/* 12 */
+#define GDB_FR_REG13		((GDB_FR_REG12) + 4)		/* 13 */
+#define GDB_FR_REG14		((GDB_FR_REG13) + 4)		/* 14 */
+#define GDB_FR_REG15		((GDB_FR_REG14) + 4)		/* 15 */
+#define GDB_FR_REG16		((GDB_FR_REG15) + 4)		/* 16 */
+#define GDB_FR_REG17		((GDB_FR_REG16) + 4)		/* 17 */
+#define GDB_FR_REG18		((GDB_FR_REG17) + 4)		/* 18 */
+#define GDB_FR_REG19		((GDB_FR_REG18) + 4)		/* 19 */
+#define GDB_FR_REG20		((GDB_FR_REG19) + 4)		/* 20 */
+#define GDB_FR_REG21		((GDB_FR_REG20) + 4)		/* 21 */
+#define GDB_FR_REG22		((GDB_FR_REG21) + 4)		/* 22 */
+#define GDB_FR_REG23		((GDB_FR_REG22) + 4)		/* 23 */
+#define GDB_FR_REG24		((GDB_FR_REG23) + 4)		/* 24 */
+#define GDB_FR_REG25		((GDB_FR_REG24) + 4)		/* 25 */
+#define GDB_FR_REG26		((GDB_FR_REG25) + 4)		/* 26 */
+#define GDB_FR_REG27		((GDB_FR_REG26) + 4)		/* 27 */
+#define GDB_FR_REG28		((GDB_FR_REG27) + 4)		/* 28 */
+#define GDB_FR_REG29		((GDB_FR_REG28) + 4)		/* 29 */
+#define GDB_FR_REG30		((GDB_FR_REG29) + 4)		/* 30 */
+#define GDB_FR_REG31		((GDB_FR_REG30) + 4)		/* 31 */
+	
+/*
+ * Saved special registers
+ */
+#define GDB_FR_STATUS		((GDB_FR_REG31) + 4)		/* 32 */
+#define GDB_FR_LO		((GDB_FR_STATUS) + 4)		/* 33 */
+#define GDB_FR_HI		((GDB_FR_LO) + 4)		/* 34 */
+#define GDB_FR_BADVADDR		((GDB_FR_HI) + 4)		/* 35 */
+#define GDB_FR_CAUSE		((GDB_FR_BADVADDR) + 4)		/* 36 */
+#define GDB_FR_EPC		((GDB_FR_CAUSE) + 4)		/* 37 */
+
+/*
+ * Saved floating point registers
+ */
+#define GDB_FR_FPR0		((GDB_FR_EPC) + 4)		/* 38 */
+#define GDB_FR_FPR1		((GDB_FR_FPR0) + 4)		/* 39 */
+#define GDB_FR_FPR2		((GDB_FR_FPR1) + 4)		/* 40 */
+#define GDB_FR_FPR3		((GDB_FR_FPR2) + 4)		/* 41 */
+#define GDB_FR_FPR4		((GDB_FR_FPR3) + 4)		/* 42 */
+#define GDB_FR_FPR5		((GDB_FR_FPR4) + 4)		/* 43 */
+#define GDB_FR_FPR6		((GDB_FR_FPR5) + 4)		/* 44 */
+#define GDB_FR_FPR7		((GDB_FR_FPR6) + 4)		/* 45 */
+#define GDB_FR_FPR8		((GDB_FR_FPR7) + 4)		/* 46 */
+#define GDB_FR_FPR9		((GDB_FR_FPR8) + 4)		/* 47 */
+#define GDB_FR_FPR10		((GDB_FR_FPR9) + 4)		/* 48 */
+#define GDB_FR_FPR11		((GDB_FR_FPR10) + 4)		/* 49 */
+#define GDB_FR_FPR12		((GDB_FR_FPR11) + 4)		/* 50 */
+#define GDB_FR_FPR13		((GDB_FR_FPR12) + 4)		/* 51 */
+#define GDB_FR_FPR14		((GDB_FR_FPR13) + 4)		/* 52 */
+#define GDB_FR_FPR15		((GDB_FR_FPR14) + 4)		/* 53 */
+#define GDB_FR_FPR16		((GDB_FR_FPR15) + 4)		/* 54 */
+#define GDB_FR_FPR17		((GDB_FR_FPR16) + 4)		/* 55 */
+#define GDB_FR_FPR18		((GDB_FR_FPR17) + 4)		/* 56 */
+#define GDB_FR_FPR19		((GDB_FR_FPR18) + 4)		/* 57 */
+#define GDB_FR_FPR20		((GDB_FR_FPR19) + 4)		/* 58 */
+#define GDB_FR_FPR21		((GDB_FR_FPR20) + 4)		/* 59 */
+#define GDB_FR_FPR22		((GDB_FR_FPR21) + 4)		/* 60 */
+#define GDB_FR_FPR23		((GDB_FR_FPR22) + 4)		/* 61 */
+#define GDB_FR_FPR24		((GDB_FR_FPR23) + 4)		/* 62 */
+#define GDB_FR_FPR25		((GDB_FR_FPR24) + 4)		/* 63 */
+#define GDB_FR_FPR26		((GDB_FR_FPR25) + 4)		/* 64 */
+#define GDB_FR_FPR27		((GDB_FR_FPR26) + 4)		/* 65 */
+#define GDB_FR_FPR28		((GDB_FR_FPR27) + 4)		/* 66 */
+#define GDB_FR_FPR29		((GDB_FR_FPR28) + 4)		/* 67 */
+#define GDB_FR_FPR30		((GDB_FR_FPR29) + 4)		/* 68 */
+#define GDB_FR_FPR31		((GDB_FR_FPR30) + 4)		/* 69 */
+
+#define GDB_FR_FSR		((GDB_FR_FPR31) + 4)		/* 70 */
+#define GDB_FR_FIR		((GDB_FR_FSR) + 4)		/* 71 */
+#define GDB_FR_FRP		((GDB_FR_FIR) + 4)		/* 72 */
+
+#define GDB_FR_DUMMY		((GDB_FR_FRP) + 4)		/* 73, unused ??? */
+
+/*
+ * Again, CP0 registers
+ */
+#define GDB_FR_CP0_INDEX	((GDB_FR_DUMMY) + 4)		/* 74 */
+#define GDB_FR_CP0_RANDOM	((GDB_FR_CP0_INDEX) + 4)	/* 75 */
+#define GDB_FR_CP0_ENTRYLO0	((GDB_FR_CP0_RANDOM) + 4)	/* 76 */
+#define GDB_FR_CP0_ENTRYLO1	((GDB_FR_CP0_ENTRYLO0) + 4)	/* 77 */
+#define GDB_FR_CP0_CONTEXT	((GDB_FR_CP0_ENTRYLO1) + 4)	/* 78 */
+#define GDB_FR_CP0_PAGEMASK	((GDB_FR_CP0_CONTEXT) + 4)	/* 79 */
+#define GDB_FR_CP0_WIRED	((GDB_FR_CP0_PAGEMASK) + 4)	/* 80 */
+#define GDB_FR_CP0_REG7		((GDB_FR_CP0_WIRED) + 4)	/* 81 */
+#define GDB_FR_CP0_REG8		((GDB_FR_CP0_REG7) + 4)		/* 82 */
+#define GDB_FR_CP0_REG9		((GDB_FR_CP0_REG8) + 4)		/* 83 */
+#define GDB_FR_CP0_ENTRYHI	((GDB_FR_CP0_REG9) + 4)		/* 84 */
+#define GDB_FR_CP0_REG11	((GDB_FR_CP0_ENTRYHI) + 4)	/* 85 */
+#define GDB_FR_CP0_REG12	((GDB_FR_CP0_REG11) + 4)	/* 86 */
+#define GDB_FR_CP0_REG13	((GDB_FR_CP0_REG12) + 4)	/* 87 */
+#define GDB_FR_CP0_REG14	((GDB_FR_CP0_REG13) + 4)	/* 88 */
+#define GDB_FR_CP0_PRID		((GDB_FR_CP0_REG14) + 4)	/* 89 */
+
+#define GDB_FR_SIZE		((((GDB_FR_CP0_PRID) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1))
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This is the same as above, but for the high-level
+ * part of the GDB stub.
+ */
+
+struct gdb_regs {
+	/*
+	 * Pad bytes for argument save space on the stack
+	 * 20/40 Bytes for 32/64 bit code
+	 */
+	unsigned long pad0[5];
+
+	/*
+	 * saved main processor registers
+	 */
+	long	 reg0,  reg1,  reg2,  reg3,  reg4,  reg5,  reg6,  reg7;
+	long	 reg8,  reg9, reg10, reg11, reg12, reg13, reg14, reg15;
+	long	reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23;
+	long	reg24, reg25, reg26, reg27, reg28, reg29, reg30, reg31;
+
+	/*
+	 * Saved special registers
+	 */
+	long	cp0_status;
+	long	lo;
+	long	hi;
+	long	cp0_badvaddr;
+	long	cp0_cause;
+	long	cp0_epc;
+
+	/*
+	 * Saved floating point registers
+	 */
+	long	fpr0,  fpr1,  fpr2,  fpr3,  fpr4,  fpr5,  fpr6,  fpr7;
+	long	fpr8,  fpr9,  fpr10, fpr11, fpr12, fpr13, fpr14, fpr15;
+	long	fpr16, fpr17, fpr18, fpr19, fpr20, fpr21, fpr22, fpr23;
+	long	fpr24, fpr25, fpr26, fpr27, fpr28, fpr29, fpr30, fpr31;
+
+	long	cp1_fsr;
+	long	cp1_fir;
+
+	/*
+	 * Frame pointer
+	 */
+	long	frame_ptr;
+	long    dummy;		/* unused */
+	
+	/*
+	 * saved cp0 registers
+	 */
+	long	cp0_index;
+	long	cp0_random;
+	long	cp0_entrylo0;
+	long	cp0_entrylo1;
+	long	cp0_context;
+	long	cp0_pagemask;
+	long	cp0_wired;
+	long	cp0_reg7;
+	long	cp0_reg8;
+	long	cp0_reg9;
+	long	cp0_entryhi;
+	long	cp0_reg11;
+	long	cp0_reg12;
+	long	cp0_reg13;
+	long	cp0_reg14;
+	long	cp0_prid;
+};
+
+/*
+ * Prototypes
+ */
+
+void set_debug_traps(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_MIPS_GDB_STUB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/gt64120.h linux/include/asm-mips64/gt64120.h
--- linux.orig/include/asm-mips64/gt64120.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/gt64120.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,399 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#ifndef _ASM_GT64120_H
+#define _ASM_GT64120_H
+
+#define MSK(n)                    ((1 << (n)) - 1)
+
+/*
+ *  Register offset addresses
+ */
+#define GT_CPU_OFS		0x000
+
+/*
+ * Interrupt Registers
+ */
+#define GT_SCS10LD_OFS		0x008
+#define GT_SCS10HD_OFS		0x010
+#define GT_SCS32LD_OFS		0x018
+#define GT_SCS32HD_OFS		0x020
+#define GT_CS20LD_OFS		0x028
+#define GT_CS20HD_OFS		0x030
+#define GT_CS3BOOTLD_OFS	0x038
+#define GT_CS3BOOTHD_OFS	0x040
+#define GT_PCI0IOLD_OFS		0x048
+#define GT_PCI0IOHD_OFS		0x050
+#define GT_PCI0M0LD_OFS		0x058
+#define GT_PCI0M0HD_OFS		0x060
+#define GT_ISD_OFS		0x068
+#define GT_PCI0M1LD_OFS		0x080
+#define GT_PCI0M1HD_OFS		0x088
+#define GT_PCI1IOLD_OFS		0x090
+#define GT_PCI1IOHD_OFS		0x098
+#define GT_PCI1M0LD_OFS		0x0a0
+#define GT_PCI1M0HD_OFS		0x0a8
+#define GT_PCI1M1LD_OFS		0x0b0
+#define GT_PCI1M1HD_OFS		0x0b8
+
+/*
+ * GT64120A only
+ */
+#define GT_PCI0IOREMAP_OFS	0x0f0
+#define GT_PCI0M0REMAP_OFS	0x0f8
+#define GT_PCI0M1REMAP_OFS	0x100
+#define GT_PCI1IOREMAP_OFS	0x108
+#define GT_PCI1M0REMAP_OFS	0x110
+#define GT_PCI1M1REMAP_OFS	0x118
+
+#define GT_SCS0LD_OFS		0x400	
+#define GT_SCS0HD_OFS		0x404
+#define GT_SCS1LD_OFS		0x408
+#define GT_SCS1HD_OFS		0x40c
+#define GT_SCS2LD_OFS		0x410
+#define GT_SCS2HD_OFS		0x414
+#define GT_SCS3LD_OFS		0x418
+#define GT_SCS3HD_OFS		0x41c
+#define GT_CS0LD_OFS		0x420
+#define GT_CS0HD_OFS		0x424
+#define GT_CS1LD_OFS		0x428
+#define GT_CS1HD_OFS		0x42c
+#define GT_CS2LD_OFS		0x430
+#define GT_CS2HD_OFS		0x434
+#define GT_CS3LD_OFS		0x438
+#define GT_CS3HD_OFS		0x43c
+#define GT_BOOTLD_OFS		0x440
+#define GT_BOOTHD_OFS		0x444
+
+#define GT_SDRAM_B0_OFS	    	0x44c
+#define GT_SDRAM_CFG_OFS	0x448
+#define GT_SDRAM_B2_OFS		0x454
+#define GT_SDRAM_OPMODE_OFS	0x474
+#define GT_SDRAM_BM_OFS		0x478
+#define GT_SDRAM_ADDRDECODE_OFS	0x47c
+
+#define GT_PCI0_CMD_OFS		0xc00	/* GT64120A only */
+#define GT_PCI0_TOR_OFS		0xc04
+#define GT_PCI0_BS_SCS10_OFS    0xc08
+#define GT_PCI0_BS_SCS32_OFS    0xc0c
+#define GT_INTRCAUSE_OFS	0xc18
+#define GT_INTRMASK_OFS		0xc1c	/* GT64120A only */
+#define GT_PCI0_IACK_OFS	0xc34
+#define GT_PCI0_BARE_OFS	0xc3c
+#define GT_HINTRCAUSE_OFS	0xc98	/* GT64120A only */
+#define GT_HINTRMASK_OFS	0xc9c	/* GT64120A only */
+#define GT_PCI1_CFGADDR_OFS	0xcf0	/* GT64120A only */
+#define GT_PCI1_CFGDATA_OFS	0xcf4	/* GT64120A only */
+#define GT_PCI0_CFGADDR_OFS	0xcf8
+#define GT_PCI0_CFGDATA_OFS	0xcfc
+
+
+/*
+ * Timer/Counter.  GT64120A only.
+ */
+#define GT_TC0_OFS		0x850
+#define GT_TC1_OFS		0x854
+#define GT_TC2_OFS		0x858
+#define GT_TC3_OFS		0x85C
+#define GT_TC_CONTROL_OFS	0x864
+
+/*
+ * I2O Support Registers
+ */
+#define INBOUND_MESSAGE_REGISTER0_PCI_SIDE		0x010
+#define INBOUND_MESSAGE_REGISTER1_PCI_SIDE		0x014
+#define OUTBOUND_MESSAGE_REGISTER0_PCI_SIDE		0x018
+#define OUTBOUND_MESSAGE_REGISTER1_PCI_SIDE		0x01c
+#define INBOUND_DOORBELL_REGISTER_PCI_SIDE		0x020
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI_SIDE	0x024
+#define INBOUND_INTERRUPT_MASK_REGISTER_PCI_SIDE	0x028
+#define OUTBOUND_DOORBELL_REGISTER_PCI_SIDE		0x02c
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI_SIDE	0x030
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI_SIDE	0x034
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI_SIDE	0x040
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI_SIDE	0x044
+#define QUEUE_CONTROL_REGISTER_PCI_SIDE			0x050
+#define QUEUE_BASE_ADDRESS_REGISTER_PCI_SIDE		0x054
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI_SIDE	0x060
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI_SIDE	0x064
+#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI_SIDE	0x068
+#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI_SIDE	0x06c
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI_SIDE	0x070
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI_SIDE	0x074
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI_SIDE	0x078
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI_SIDE	0x07c
+
+#define INBOUND_MESSAGE_REGISTER0_CPU_SIDE		0x1c10
+#define INBOUND_MESSAGE_REGISTER1_CPU_SIDE		0x1c14
+#define OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE		0x1c18
+#define OUTBOUND_MESSAGE_REGISTER1_CPU_SIDE		0x1c1c
+#define INBOUND_DOORBELL_REGISTER_CPU_SIDE		0x1c20
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE	0x1c24
+#define INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE	0x1c28
+#define OUTBOUND_DOORBELL_REGISTER_CPU_SIDE		0x1c2c
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE	0x1c30
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE	0x1c34
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU_SIDE	0x1c40
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU_SIDE	0x1c44
+#define QUEUE_CONTROL_REGISTER_CPU_SIDE			0x1c50
+#define QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE		0x1c54
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE	0x1c60
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE	0x1c64
+#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE	0x1c68
+#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE	0x1c6c
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE	0x1c70
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE	0x1c74
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE	0x1c78
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE	0x1c7c
+
+/*
+ *  Register encodings
+ */
+#define GT_CPU_ENDIAN_SHF       12
+#define GT_CPU_ENDIAN_MSK       (MSK(1) << GT_CPU_ENDIAN_SHF)
+#define GT_CPU_ENDIAN_BIT       GT_CPU_ENDIAN_MSK
+#define GT_CPU_WR_SHF		16
+#define GT_CPU_WR_MSK		(MSK(1) << GT_CPU_WR_SHF)
+#define GT_CPU_WR_BIT		GT_CPU_WR_MSK
+#define GT_CPU_WR_DXDXDXDX	0
+#define GT_CPU_WR_DDDD		1
+
+
+#define GT_CFGADDR_CFGEN_SHF	31
+#define GT_CFGADDR_CFGEN_MSK	(MSK(1) << GT_CFGADDR_CFGEN_SHF)
+#define GT_CFGADDR_CFGEN_BIT	GT_CFGADDR_CFGEN_MSK
+
+#define GT_CFGADDR_BUSNUM_SHF	16
+#define GT_CFGADDR_BUSNUM_MSK	(MSK(8) << GT_CFGADDR_BUSNUM_SHF)
+
+#define GT_CFGADDR_DEVNUM_SHF	11
+#define GT_CFGADDR_DEVNUM_MSK	(MSK(5) << GT_CFGADDR_DEVNUM_SHF)
+
+#define GT_CFGADDR_FUNCNUM_SHF	8
+#define GT_CFGADDR_FUNCNUM_MSK	(MSK(3) << GT_CFGADDR_FUNCNUM_SHF)
+
+#define GT_CFGADDR_REGNUM_SHF	2
+#define GT_CFGADDR_REGNUM_MSK	(MSK(6) << GT_CFGADDR_REGNUM_SHF)
+
+
+#define GT_SDRAM_BM_ORDER_SHF	2
+#define GT_SDRAM_BM_ORDER_MSK	(MSK(1) << GT_SDRAM_BM_ORDER_SHF)
+#define GT_SDRAM_BM_ORDER_BIT	GT_SDRAM_BM_ORDER_MSK
+#define GT_SDRAM_BM_ORDER_SUB	1
+#define GT_SDRAM_BM_ORDER_LIN	0
+
+#define GT_SDRAM_BM_RSVD_ALL1	0xffb
+
+
+#define GT_SDRAM_ADDRDECODE_ADDR_SHF	0
+#define GT_SDRAM_ADDRDECODE_ADDR_MSK	(MSK(3) << GT_SDRAM_ADDRDECODE_ADDR_SHF)
+#define GT_SDRAM_ADDRDECODE_ADDR_0	0
+#define GT_SDRAM_ADDRDECODE_ADDR_1	1
+#define GT_SDRAM_ADDRDECODE_ADDR_2	2
+#define GT_SDRAM_ADDRDECODE_ADDR_3	3
+#define GT_SDRAM_ADDRDECODE_ADDR_4	4
+#define GT_SDRAM_ADDRDECODE_ADDR_5	5
+#define GT_SDRAM_ADDRDECODE_ADDR_6	6
+#define GT_SDRAM_ADDRDECODE_ADDR_7	7
+
+
+#define GT_SDRAM_B0_CASLAT_SHF		0
+#define GT_SDRAM_B0_CASLAT_MSK		(MSK(2) << GT_SDRAM_B0__SHF)
+#define GT_SDRAM_B0_CASLAT_2		1
+#define GT_SDRAM_B0_CASLAT_3		2
+
+#define GT_SDRAM_B0_FTDIS_SHF		2
+#define GT_SDRAM_B0_FTDIS_MSK		(MSK(1) << GT_SDRAM_B0_FTDIS_SHF)
+#define GT_SDRAM_B0_FTDIS_BIT		GT_SDRAM_B0_FTDIS_MSK
+
+#define GT_SDRAM_B0_SRASPRCHG_SHF	3
+#define GT_SDRAM_B0_SRASPRCHG_MSK	(MSK(1) << GT_SDRAM_B0_SRASPRCHG_SHF)
+#define GT_SDRAM_B0_SRASPRCHG_BIT	GT_SDRAM_B0_SRASPRCHG_MSK
+#define GT_SDRAM_B0_SRASPRCHG_2		0
+#define GT_SDRAM_B0_SRASPRCHG_3		1
+
+#define GT_SDRAM_B0_B0COMPAB_SHF	4
+#define GT_SDRAM_B0_B0COMPAB_MSK	(MSK(1) << GT_SDRAM_B0_B0COMPAB_SHF)
+#define GT_SDRAM_B0_B0COMPAB_BIT	GT_SDRAM_B0_B0COMPAB_MSK
+
+#define GT_SDRAM_B0_64BITINT_SHF	5
+#define GT_SDRAM_B0_64BITINT_MSK	(MSK(1) << GT_SDRAM_B0_64BITINT_SHF)
+#define GT_SDRAM_B0_64BITINT_BIT	GT_SDRAM_B0_64BITINT_MSK
+#define GT_SDRAM_B0_64BITINT_2		0
+#define GT_SDRAM_B0_64BITINT_4		1
+
+#define GT_SDRAM_B0_BW_SHF		6
+#define GT_SDRAM_B0_BW_MSK		(MSK(1) << GT_SDRAM_B0_BW_SHF)
+#define GT_SDRAM_B0_BW_BIT		GT_SDRAM_B0_BW_MSK
+#define GT_SDRAM_B0_BW_32		0
+#define GT_SDRAM_B0_BW_64		1
+
+#define GT_SDRAM_B0_BLODD_SHF		7
+#define GT_SDRAM_B0_BLODD_MSK		(MSK(1) << GT_SDRAM_B0_BLODD_SHF)
+#define GT_SDRAM_B0_BLODD_BIT		GT_SDRAM_B0_BLODD_MSK
+
+#define GT_SDRAM_B0_PAR_SHF		8
+#define GT_SDRAM_B0_PAR_MSK		(MSK(1) << GT_SDRAM_B0_PAR_SHF)
+#define GT_SDRAM_B0_PAR_BIT		GT_SDRAM_B0_PAR_MSK
+
+#define GT_SDRAM_B0_BYPASS_SHF		9
+#define GT_SDRAM_B0_BYPASS_MSK		(MSK(1) << GT_SDRAM_B0_BYPASS_SHF)
+#define GT_SDRAM_B0_BYPASS_BIT		GT_SDRAM_B0_BYPASS_MSK
+
+#define GT_SDRAM_B0_SRAS2SCAS_SHF	10
+#define GT_SDRAM_B0_SRAS2SCAS_MSK	(MSK(1) << GT_SDRAM_B0_SRAS2SCAS_SHF)
+#define GT_SDRAM_B0_SRAS2SCAS_BIT	GT_SDRAM_B0_SRAS2SCAS_MSK
+#define GT_SDRAM_B0_SRAS2SCAS_2		0
+#define GT_SDRAM_B0_SRAS2SCAS_3		1
+
+#define GT_SDRAM_B0_SIZE_SHF		11
+#define GT_SDRAM_B0_SIZE_MSK		(MSK(1) << GT_SDRAM_B0_SIZE_SHF)
+#define GT_SDRAM_B0_SIZE_BIT		GT_SDRAM_B0_SIZE_MSK
+#define GT_SDRAM_B0_SIZE_16M		0
+#define GT_SDRAM_B0_SIZE_64M		1
+
+#define GT_SDRAM_B0_EXTPAR_SHF		12
+#define GT_SDRAM_B0_EXTPAR_MSK		(MSK(1) << GT_SDRAM_B0_EXTPAR_SHF)
+#define GT_SDRAM_B0_EXTPAR_BIT		GT_SDRAM_B0_EXTPAR_MSK
+
+#define GT_SDRAM_B0_BLEN_SHF		13
+#define GT_SDRAM_B0_BLEN_MSK		(MSK(1) << GT_SDRAM_B0_BLEN_SHF)
+#define GT_SDRAM_B0_BLEN_BIT		GT_SDRAM_B0_BLEN_MSK
+#define GT_SDRAM_B0_BLEN_8		0
+#define GT_SDRAM_B0_BLEN_4		1
+
+
+#define GT_SDRAM_CFG_REFINT_SHF		0
+#define GT_SDRAM_CFG_REFINT_MSK		(MSK(14) << GT_SDRAM_CFG_REFINT_SHF)
+
+#define GT_SDRAM_CFG_NINTERLEAVE_SHF	14
+#define GT_SDRAM_CFG_NINTERLEAVE_MSK    (MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
+#define GT_SDRAM_CFG_NINTERLEAVE_BIT	GT_SDRAM_CFG_NINTERLEAVE_MSK
+
+#define GT_SDRAM_CFG_RMW_SHF		15
+#define GT_SDRAM_CFG_RMW_MSK		(MSK(1) << GT_SDRAM_CFG_RMW_SHF)
+#define GT_SDRAM_CFG_RMW_BIT		GT_SDRAM_CFG_RMW_MSK
+
+#define GT_SDRAM_CFG_NONSTAGREF_SHF	16
+#define GT_SDRAM_CFG_NONSTAGREF_MSK	(MSK(1) << GT_SDRAM_CFG_NONSTAGREF_SHF)
+#define GT_SDRAM_CFG_NONSTAGREF_BIT	GT_SDRAM_CFG_NONSTAGREF_MSK
+
+#define GT_SDRAM_CFG_DUPCNTL_SHF	19
+#define GT_SDRAM_CFG_DUPCNTL_MSK	(MSK(1) << GT_SDRAM_CFG_DUPCNTL_SHF)
+#define GT_SDRAM_CFG_DUPCNTL_BIT	GT_SDRAM_CFG_DUPCNTL_MSK
+
+#define GT_SDRAM_CFG_DUPBA_SHF		20
+#define GT_SDRAM_CFG_DUPBA_MSK		(MSK(1) << GT_SDRAM_CFG_DUPBA_SHF)
+#define GT_SDRAM_CFG_DUPBA_BIT		GT_SDRAM_CFG_DUPBA_MSK
+
+#define GT_SDRAM_CFG_DUPEOT0_SHF	21
+#define GT_SDRAM_CFG_DUPEOT0_MSK	(MSK(1) << GT_SDRAM_CFG_DUPEOT0_SHF)
+#define GT_SDRAM_CFG_DUPEOT0_BIT	GT_SDRAM_CFG_DUPEOT0_MSK
+
+#define GT_SDRAM_CFG_DUPEOT1_SHF	22
+#define GT_SDRAM_CFG_DUPEOT1_MSK	(MSK(1) << GT_SDRAM_CFG_DUPEOT1_SHF)
+#define GT_SDRAM_CFG_DUPEOT1_BIT	GT_SDRAM_CFG_DUPEOT1_MSK
+
+#define GT_SDRAM_OPMODE_OP_SHF		0
+#define GT_SDRAM_OPMODE_OP_MSK		(MSK(3) << GT_SDRAM_OPMODE_OP_SHF)
+#define GT_SDRAM_OPMODE_OP_NORMAL	0
+#define GT_SDRAM_OPMODE_OP_NOP		1
+#define GT_SDRAM_OPMODE_OP_PRCHG	2
+#define GT_SDRAM_OPMODE_OP_MODE		3
+#define GT_SDRAM_OPMODE_OP_CBR		4
+
+
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_SHF	0
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_MSK	(MSK(1) << GT_PCI0_BARE_SWSCS3BOOTDIS_SHF)
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_BIT	GT_PCI0_BARE_SWSCS3BOOTDIS_MSK
+
+#define GT_PCI0_BARE_SWSCS32DIS_SHF	1
+#define GT_PCI0_BARE_SWSCS32DIS_MSK	(MSK(1) << GT_PCI0_BARE_SWSCS32DIS_SHF)
+#define GT_PCI0_BARE_SWSCS32DIS_BIT	GT_PCI0_BARE_SWSCS32DIS_MSK
+	
+#define GT_PCI0_BARE_SWSCS10DIS_SHF	2
+#define GT_PCI0_BARE_SWSCS10DIS_MSK	(MSK(1) << GT_PCI0_BARE_SWSCS10DIS_SHF)
+#define GT_PCI0_BARE_SWSCS10DIS_BIT	GT_PCI0_BARE_SWSCS10DIS_MSK
+
+#define GT_PCI0_BARE_INTIODIS_SHF	3
+#define GT_PCI0_BARE_INTIODIS_MSK	(MSK(1) << GT_PCI0_BARE_INTIODIS_SHF)
+#define GT_PCI0_BARE_INTIODIS_BIT	GT_PCI0_BARE_INTIODIS_MSK
+
+#define GT_PCI0_BARE_INTMEMDIS_SHF	4
+#define GT_PCI0_BARE_INTMEMDIS_MSK	(MSK(1) << GT_PCI0_BARE_INTMEMDIS_SHF)
+#define GT_PCI0_BARE_INTMEMDIS_BIT	GT_PCI0_BARE_INTMEMDIS_MSK
+
+#define GT_PCI0_BARE_CS3BOOTDIS_SHF	5
+#define GT_PCI0_BARE_CS3BOOTDIS_MSK	(MSK(1) << GT_PCI0_BARE_CS3BOOTDIS_SHF)
+#define GT_PCI0_BARE_CS3BOOTDIS_BIT	GT_PCI0_BARE_CS3BOOTDIS_MSK
+
+#define GT_PCI0_BARE_CS20DIS_SHF	6
+#define GT_PCI0_BARE_CS20DIS_MSK	(MSK(1) << GT_PCI0_BARE_CS20DIS_SHF)
+#define GT_PCI0_BARE_CS20DIS_BIT	GT_PCI0_BARE_CS20DIS_MSK
+
+#define GT_PCI0_BARE_SCS32DIS_SHF	7
+#define GT_PCI0_BARE_SCS32DIS_MSK	(MSK(1) << GT_PCI0_BARE_SCS32DIS_SHF)
+#define GT_PCI0_BARE_SCS32DIS_BIT	GT_PCI0_BARE_SCS32DIS_MSK
+
+#define GT_PCI0_BARE_SCS10DIS_SHF	8
+#define GT_PCI0_BARE_SCS10DIS_MSK	(MSK(1) << GT_PCI0_BARE_SCS10DIS_SHF)
+#define GT_PCI0_BARE_SCS10DIS_BIT	GT_PCI0_BARE_SCS10DIS_MSK
+
+
+#define GT_INTRCAUSE_MASABORT0_SHF	18
+#define GT_INTRCAUSE_MASABORT0_MSK	(MSK(1) << GT_INTRCAUSE_MASABORT0_SHF)
+#define GT_INTRCAUSE_MASABORT0_BIT	GT_INTRCAUSE_MASABORT0_MSK
+
+#define GT_INTRCAUSE_TARABORT0_SHF	19
+#define GT_INTRCAUSE_TARABORT0_MSK	(MSK(1) << GT_INTRCAUSE_TARABORT0_SHF)
+#define GT_INTRCAUSE_TARABORT0_BIT	GT_INTRCAUSE_TARABORT0_MSK
+
+
+#define GT_PCI0_CFGADDR_REGNUM_SHF	2
+#define GT_PCI0_CFGADDR_REGNUM_MSK	(MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF)
+#define GT_PCI0_CFGADDR_FUNCTNUM_SHF	8
+#define GT_PCI0_CFGADDR_FUNCTNUM_MSK    (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
+#define GT_PCI0_CFGADDR_DEVNUM_SHF	11
+#define GT_PCI0_CFGADDR_DEVNUM_MSK	(MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF)
+#define GT_PCI0_CFGADDR_BUSNUM_SHF	16
+#define GT_PCI0_CFGADDR_BUSNUM_MSK	(MSK(8) << GT_PCI0_CFGADDR_BUSNUM_SHF)
+#define GT_PCI0_CFGADDR_CONFIGEN_SHF	31
+#define GT_PCI0_CFGADDR_CONFIGEN_MSK	(MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF)
+#define GT_PCI0_CFGADDR_CONFIGEN_BIT	GT_PCI0_CFGADDR_CONFIGEN_MSK
+
+#define GT_PCI0_CMD_MBYTESWAP_SHF       0
+#define GT_PCI0_CMD_MBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
+#define GT_PCI0_CMD_MBYTESWAP_BIT       GT_PCI0_CMD_MBYTESWAP_MSK
+#define GT_PCI0_CMD_MWORDSWAP_SHF       10
+#define GT_PCI0_CMD_MWORDSWAP_MSK       (MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
+#define GT_PCI0_CMD_MWORDSWAP_BIT       GT_PCI0_CMD_MWORDSWAP_MSK
+#define GT_PCI0_CMD_SBYTESWAP_SHF       16
+#define GT_PCI0_CMD_SBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
+#define GT_PCI0_CMD_SBYTESWAP_BIT       GT_PCI0_CMD_SBYTESWAP_MSK
+#define GT_PCI0_CMD_SWORDSWAP_SHF       11
+#define GT_PCI0_CMD_SWORDSWAP_MSK       (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
+#define GT_PCI0_CMD_SWORDSWAP_BIT       GT_PCI0_CMD_SWORDSWAP_MSK
+
+/*
+ *  Misc
+ */
+#define GT_DEF_BASE		0x14000000
+#define GT_DEF_PCI0_MEM0_BASE	0x12000000
+#define GT_MAX_BANKSIZE		(256 * 1024 * 1024)   /* Max 256MB bank */
+#define GT_LATTIM_MIN    	6		      /* Minimum lat	*/
+
+#endif /* _ASM_GT64120_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/hw_irq.h linux/include/asm-mips64/hw_irq.h
--- linux.orig/include/asm-mips64/hw_irq.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips64/hw_irq.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,5 +1,18 @@
-/* This exists merely to satisfy <linux/irq.h>.  There is
-   nothing that would go here of general interest.
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 2001 by Ralf Baechle
+ */
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
 
-   Everything of consequence is in arch/alpha/kernel/irq_impl.h,
-   to be used only in arch/alpha/kernel/.  */
+extern atomic_t irq_err_count;
+
+/* This may not be apropriate for all machines, we'll see ...  */
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+{
+}
+
+#endif /* _ASM_HW_IRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/ide.h linux/include/asm-mips64/ide.h
--- linux.orig/include/asm-mips64/ide.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/ide.h	2002-07-20 01:08:22.000000000 +0000
@@ -85,7 +85,28 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+#ifdef __MIPSEB__
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+		unsigned reserved456	: 3;
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned bit0		: 1;
+#else
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+#endif
+	} b;
+} control_t;
 
 static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int,void *, struct pt_regs *),
 			unsigned long flags, const char *device, void *dev_id)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/inst.h linux/include/asm-mips64/inst.h
--- linux.orig/include/asm-mips64/inst.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/inst.h	2002-07-20 01:08:36.000000000 +0000
@@ -1,11 +1,11 @@
 /*
+ * Format of an instruction in memory.
+ *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Format of an instruction in memory.
- *
- * Copyright (C) 1996 by Ralf Baechle
+ * Copyright (C) 1996, 2000 by Ralf Baechle
  */
 #ifndef _ASM_INST_H
 #define _ASM_INST_H
@@ -21,7 +21,7 @@
 	cop0_op, cop1_op, cop2_op, cop1x_op,
 	beql_op, bnel_op, blezl_op, bgtzl_op,
 	daddi_op, daddiu_op, ldl_op, ldr_op,
-	major_1c_op, major_1d_op, major_1e_op, major_1f_op,
+	major_1c_op, jalx_op, major_1e_op, major_1f_op,
 	lb_op, lh_op, lwl_op, lw_op,
 	lbu_op, lhu_op, lwr_op, lwu_op,
 	sb_op, sh_op, swl_op, sw_op,
@@ -80,6 +80,13 @@
 };
 
 /*
+ * rt field of cop.bc_op opcodes
+ */
+enum bcop_op {
+	bcf_op, bct_op, bcfl_op, bctl_op
+};
+
+/*
  * func field of cop0 coi opcodes.
  */
 enum cop0_coi_func {
@@ -301,4 +308,64 @@
         struct ma_format ma_format;
 };
 
+/* HACHACHAHCAHC ...  */
+
+/* In case some other massaging is needed, keep MIPSInst as wrapper */
+
+#define MIPSInst(x) x
+
+#define I_OPCODE_SFT	26
+#define MIPSInst_OPCODE(x) (MIPSInst(x) >> I_OPCODE_SFT)
+
+#define I_JTARGET_SFT	0
+#define MIPSInst_JTARGET(x) (MIPSInst(x) & 0x03ffffff)
+
+#define I_RS_SFT	21
+#define MIPSInst_RS(x) ((MIPSInst(x) & 0x03e00000) >> I_RS_SFT)
+
+#define I_RT_SFT	16
+#define MIPSInst_RT(x) ((MIPSInst(x) & 0x001f0000) >> I_RT_SFT)
+
+#define I_IMM_SFT	0
+#define MIPSInst_SIMM(x) ((int)((short)(MIPSInst(x) & 0xffff)))
+#define MIPSInst_UIMM(x) (MIPSInst(x) & 0xffff)
+
+#define I_CACHEOP_SFT	18
+#define MIPSInst_CACHEOP(x) ((MIPSInst(x) & 0x001c0000) >> I_CACHEOP_SFT)
+
+#define I_CACHESEL_SFT	16
+#define MIPSInst_CACHESEL(x) ((MIPSInst(x) & 0x00030000) >> I_CACHESEL_SFT)
+
+#define I_RD_SFT	11
+#define MIPSInst_RD(x) ((MIPSInst(x) & 0x0000f800) >> I_RD_SFT)
+
+#define I_RE_SFT	6
+#define MIPSInst_RE(x) ((MIPSInst(x) & 0x000007c0) >> I_RE_SFT)
+
+#define I_FUNC_SFT	0
+#define MIPSInst_FUNC(x) (MIPSInst(x) & 0x0000003f)
+
+#define I_FFMT_SFT	21
+#define MIPSInst_FFMT(x) ((MIPSInst(x) & 0x01e00000) >> I_FFMT_SFT)
+
+#define I_FT_SFT	16
+#define MIPSInst_FT(x) ((MIPSInst(x) & 0x001f0000) >> I_FT_SFT)
+
+#define I_FS_SFT	11
+#define MIPSInst_FS(x) ((MIPSInst(x) & 0x0000f800) >> I_FS_SFT)
+
+#define I_FD_SFT	6
+#define MIPSInst_FD(x) ((MIPSInst(x) & 0x000007c0) >> I_FD_SFT)
+
+#define I_FR_SFT	21
+#define MIPSInst_FR(x) ((MIPSInst(x) & 0x03e00000) >> I_FR_SFT)
+
+#define I_FMA_FUNC_SFT	2
+#define MIPSInst_FMA_FUNC(x) ((MIPSInst(x) & 0x0000003c) >> I_FMA_FUNC_SFT)
+
+#define I_FMA_FFMT_SFT	0
+#define MIPSInst_FMA_FFMT(x) (MIPSInst(x) & 0x00000003)
+
+typedef unsigned int mips_instruction;
+
 #endif /* _ASM_INST_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/io.h linux/include/asm-mips64/io.h
--- linux.orig/include/asm-mips64/io.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/io.h	2002-07-20 01:08:23.000000000 +0000
@@ -14,6 +14,14 @@
 #include <asm/addrspace.h>
 #include <asm/page.h>
 
+#ifdef CONFIG_MIPS_ATLAS
+#include <asm/mips-boards/io.h>
+#endif
+
+#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/io.h>
+#endif
+
 #ifdef CONFIG_SGI_IP22
 #include <asm/sgi/io.h>
 #endif
@@ -22,6 +30,14 @@
 #include <asm/sn/io.h>
 #endif
 
+#ifdef CONFIG_SGI_IP32
+#include <asm/ip32/io.h>
+#endif
+
+#ifdef CONFIG_SIBYTE_SB1250
+#include <asm/sibyte/sb1250_io.h>
+#endif
+
 extern unsigned long bus_to_baddr[256];
 
 /*
@@ -30,29 +46,69 @@
 #undef CONF_SLOWDOWN_IO
 
 /*
- * On MIPS, we have the whole physical address space mapped at all
- * times, so "ioremap()" and "iounmap()" do not need to do anything.
+ * Sane hardware offers swapping of I/O space accesses in hardware; less
+ * sane hardware forces software to fiddle with this ...
+ */
+#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
+
+#define __ioswab8(x) (x)
+#define __ioswab16(x) swab16(x)
+#define __ioswab32(x) swab32(x)
+
+#else
+
+#define __ioswab8(x) (x)
+#define __ioswab16(x) (x)
+#define __ioswab32(x) (x)
+
+#endif
+
+/*
+ * Change "struct page" to physical address.
+ */
+#define page_to_phys(page)	PAGE_TO_PA(page)
+
+/*
+ *     ioremap         -       map bus memory into CPU space
+ *     @offset:        bus address of the memory
+ *     @size:          size of the resource to map
  *
- * We cheat a bit and always return uncachable areas until we've fixed
- * the drivers to handle caching properly.
+ *     ioremap performs a platform specific sequence of operations to
+ *     make bus memory CPU accessible via the readb/readw/readl/writeb/
+ *     writew/writel functions and the other mmio helpers. The returned
+ *     address is not guaranteed to be usable directly as a virtual
+ *     address. 
  */
-extern inline void *
-ioremap(unsigned long offset, unsigned long size)
+static inline void * ioremap(unsigned long offset, unsigned long size)
 {
 	return (void *) (IO_SPACE_BASE | offset);
 }
 
-/* This one maps high address device memory and turns off caching for that
- *  area.  It's useful if some control registers are in such an area and write
- * combining or read caching is not desirable.
+/*
+ *     ioremap_nocache         -       map bus memory into CPU space
+ *     @offset:        bus address of the memory
+ *     @size:          size of the resource to map
+ *
+ *     ioremap_nocache performs a platform specific sequence of operations to
+ *     make bus memory CPU accessible via the readb/readw/readl/writeb/
+ *     writew/writel functions and the other mmio helpers. The returned
+ *     address is not guaranteed to be usable directly as a virtual
+ *     address. 
+ *
+ *     This version of ioremap ensures that the memory is marked uncachable
+ *     on the CPU as well as honouring existing caching rules from things like
+ *     the PCI bus. Note that there are other caches and buffers on many 
+ *     busses. In paticular driver authors should read up on PCI writes
+ *
+ *     It's useful if some control registers are in such an area and
+ *     write combining or read caching is not desirable:
  */
-extern inline void *
-ioremap_nocache (unsigned long offset, unsigned long size)
+static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
 {
 	return (void *) (IO_SPACE_BASE | offset);
 }
 
-extern inline void iounmap(void *addr)
+static inline void iounmap(void *addr)
 {
 }
 
@@ -63,9 +119,17 @@
 #define readw(addr)		(*(volatile unsigned short *) (addr))
 #define readl(addr)		(*(volatile unsigned int *) (addr))
 
+#define __raw_readb(addr)	(*(volatile unsigned char *)(addr))
+#define __raw_readw(addr)	(*(volatile unsigned short *)(addr))
+#define __raw_readl(addr)	(*(volatile unsigned int *)(addr))
+
 #define writeb(b,addr)		(*(volatile unsigned char *) (addr) = (b))
-#define writew(b,addr)		(*(volatile unsigned short *) (addr) = (b))
-#define writel(b,addr)		(*(volatile unsigned int *) (addr) = (b))
+#define writew(w,addr)		(*(volatile unsigned short *) (addr) = (w))
+#define writel(l,addr)		(*(volatile unsigned int *) (addr) = (l))
+
+#define __raw_writeb(b,addr)	((*(volatile unsigned char *)(addr)) = (b))
+#define __raw_writew(w,addr)	((*(volatile unsigned short *)(addr)) = (w))
+#define __raw_writel(l,addr)	((*(volatile unsigned int *)(addr)) = (l))
 
 #define memset_io(a,b,c)	memset((void *) a,(b),(c))
 #define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
@@ -81,7 +145,10 @@
  * instruction, so the lower 16 bits must be zero.  Should be true on
  * on any sane architecture; generic code does not use this assumption.
  */
-extern unsigned long mips_io_port_base;
+extern const unsigned long mips_io_port_base;
+
+#define set_io_port_base(base)  \
+	do { * (unsigned long *) &mips_io_port_base = (base); } while (0)
 
 #define __SLOW_DOWN_IO \
 	__asm__ __volatile__( \
@@ -99,20 +166,59 @@
 #endif
 
 /*
- * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/MIPS mapping
+ *     virt_to_phys    -       map virtual addresses to physical
+ *     @address: address to remap
+ *
+ *     The returned physical address is the physical (CPU) mapping for
+ *     the memory address given. It is only valid to use this function on
+ *     addresses directly mapped or allocated via kmalloc. 
+ *
+ *     This function does not give bus mappings for DMA transfers. In
+ *     almost all conceivable cases a device driver should not be using
+ *     this function
  */
-extern inline unsigned long virt_to_phys(volatile void * address)
+
+static inline unsigned long virt_to_phys(volatile void * address)
 {
 	return (unsigned long)address - PAGE_OFFSET;
 }
 
-extern inline void * phys_to_virt(unsigned long address)
+/*
+ *     phys_to_virt    -       map physical address to virtual
+ *     @address: address to remap
+ *
+ *     The returned virtual address is a current CPU mapping for
+ *     the memory address given. It is only valid to use this function on
+ *     addresses that have a kernel mapping
+ *
+ *     This function does not handle bus mappings for DMA transfers. In
+ *     almost all conceivable cases a device driver should not be using
+ *     this function
+ */
+
+static inline void * phys_to_virt(unsigned long address)
 {
 	return (void *)(address + PAGE_OFFSET);
 }
 
 /*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+static inline unsigned long virt_to_bus(volatile void * address)
+{
+	return (unsigned long)address - PAGE_OFFSET;
+}
+
+static inline void * bus_to_virt(unsigned long address)
+{
+	return (void *)(address + PAGE_OFFSET);
+}
+
+
+/* This is too simpleminded for more sophisticated than dumb hardware ...  */
+#define page_to_bus page_to_phys
+
+/*
  * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped
  * for the processor.  This implies the assumption that there is only
  * one of these busses.
@@ -120,11 +226,41 @@
 extern unsigned long isa_slot_offset;
 
 /*
+ * ISA space is 'always mapped' on currently supported MIPS systems, no need
+ * to explicitly ioremap() it. The fact that the ISA IO space is mapped
+ * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
+ * are physical addresses. The following constant pointer can be
+ * used as the IO-area pointer (it can be iounmapped as well, so the
+ * analogy with PCI is quite large):
+ */
+#define __ISA_IO_base ((char *)(isa_slot_offset))
+
+#define isa_readb(a) readb(__ISA_IO_base + (a))
+#define isa_readw(a) readw(__ISA_IO_base + (a))
+#define isa_readl(a) readl(__ISA_IO_base + (a))
+#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
+#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
+#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
+#define isa_memset_io(a,b,c)		memset_io(__ISA_IO_base + (a),(b),(c))
+#define isa_memcpy_fromio(a,b,c)	memcpy_fromio((a),__ISA_IO_base + (b),(c))
+#define isa_memcpy_toio(a,b,c)		memcpy_toio(__ISA_IO_base + (a),(b),(c))
+
+/*
  * We don't have csum_partial_copy_fromio() yet, so we cheat here and
  * just copy it. The net code will then do the checksum later.
  */
 #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
 
+/*
+ *     check_signature         -       find BIOS signatures
+ *     @io_addr: mmio address to check 
+ *     @signature:  signature block
+ *     @length: length of signature
+ *
+ *     Perform a signature comparison with the mmio address io_addr. This
+ *     address should have been obtained by ioremap.
+ *     Returns 1 on a match.
+ */
 static inline int
 check_signature(unsigned long io_addr, const unsigned char *signature,
                 int length)
@@ -143,11 +279,41 @@
 }
 
 /*
+ *     isa_check_signature             -       find BIOS signatures
+ *     @io_addr: mmio address to check 
+ *     @signature:  signature block
+ *     @length: length of signature
+ *
+ *     Perform a signature comparison with the ISA mmio address io_addr.
+ *     Returns 1 on a match.
+ *
+ *     This function is deprecated. New drivers should use ioremap and
+ *     check_signature.
+ */
+
+static inline int isa_check_signature(unsigned long io_addr,
+	const unsigned char *signature, int length)
+{
+	int retval = 0;
+	do {
+		if (isa_readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+	retval = 1;
+out:
+	return retval;
+}
+
+
+/*
  * Talk about misusing macros..
  */
 
 #define __OUT1(s) \
-extern inline void __out##s(unsigned int value, unsigned long port) {
+static inline void __out##s(unsigned int value, unsigned long port) {
 
 #define __OUT2(m) \
 __asm__ __volatile__ ("s" #m "\t%0,%1(%2)"
@@ -161,7 +327,7 @@
 	SLOW_DOWN_IO; }
 
 #define __IN1(t,s) \
-extern __inline__ t __in##s(unsigned long port) { t _v;
+static inline t __in##s(unsigned long port) { t _v;
 
 /*
  * Required nops will be inserted by the assembler
@@ -176,7 +342,7 @@
 __IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return _v; }
 
 #define __INS1(s) \
-extern inline void __ins##s(unsigned long port, void * addr, unsigned long count) {
+static inline void __ins##s(unsigned long port, void * addr, unsigned long count) {
 
 #define __INS2(m) \
 if (count) \
@@ -194,15 +360,15 @@
 #define __INS(m,s,i) \
 __INS1(s) __INS2(m) \
 	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
-	: "$1");} \
+	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), \
+	  "I" (i));} \
 __INS1(s##c) __INS2(m) \
 	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
-	: "$1");}
+	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), \
+	  "I" (i));}
 
 #define __OUTS1(s) \
-extern inline void __outs##s(unsigned long port, const void * addr, unsigned long count) {
+static inline void __outs##s(unsigned long port, const void * addr, unsigned long count) {
 
 #define __OUTS2(m) \
 if (count) \
@@ -220,12 +386,12 @@
 #define __OUTS(m,s,i) \
 __OUTS1(s) __OUTS2(m) \
 	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
-	: "$1");} \
+	: "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), \
+	  "I" (i));} \
 __OUTS1(s##c) __OUTS2(m) \
 	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
-	: "$1");}
+	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), \
+	  "I" (i));}
 
 __IN(unsigned char,b,b)
 __IN(unsigned short,h,w)
@@ -357,22 +523,7 @@
  *    be discarded.  This operation is necessary before dma operations
  *    to the memory.
  */
-#ifdef CONFIG_COHERENT_IO
-
-/* This is for example for IP27.  */
-extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size)
-{
-}
-
-extern inline void dma_cache_wback(unsigned long start, unsigned long size)
-{
-}
-
-extern inline void dma_cache_inv(unsigned long start, unsigned long size)
-{
-}
-
-#else
+#ifdef CONFIG_NONCOHERENT_IO
 
 extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
 extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
@@ -382,6 +533,12 @@
 #define dma_cache_wback(start,size)	_dma_cache_wback(start,size)
 #define dma_cache_inv(start,size)	_dma_cache_inv(start,size)
 
-#endif
+#else /* Sane hardware */
+
+#define dma_cache_wback_inv(start,size)	do { (start); (size); } while (0)
+#define dma_cache_wback(start,size)	do { (start); (size); } while (0)
+#define dma_cache_inv(start,size)	do { (start); (size); } while (0)
+
+#endif /* CONFIG_NONCOHERENT_IO */
 
 #endif /* _ASM_IO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/ip32/crime.h linux/include/asm-mips64/ip32/crime.h
--- linux.orig/include/asm-mips64/ip32/crime.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/ip32/crime.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,227 @@
+/*
+ * Definitions for the SGI O2 Crime chip.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Harald Koerfgen
+ */
+
+#ifndef __ASM_CRIME_H__
+#define __ASM_CRIME_H__
+
+#include <asm/addrspace.h>
+
+/*
+ * Address map
+ */
+#ifndef __ASSEMBLY__
+#define CRIME_BASE	KSEG1ADDR(0x14000000)
+#else
+#define CRIME_BASE	0xffffffffb4000000
+#endif
+
+#ifndef __ASSEMBLY__
+static inline u64 crime_read_64 (unsigned long __offset) {
+        return *((volatile u64 *) (CRIME_BASE + __offset));
+}
+static inline void crime_write_64 (unsigned long __offset, u64 __val) {
+        *((volatile u64 *) (CRIME_BASE + __offset)) = __val;
+}
+#endif
+
+#undef BIT
+#define BIT(x) (1UL << (x))
+
+/* All CRIME registers are 64 bits */
+#define CRIME_ID		0
+
+#define CRIME_ID_MASK		0xff
+#define CRIME_ID_IDBITS		0xf0
+#define CRIME_ID_IDVALUE	0xa0
+#define CRIME_ID_REV		0x0f
+
+#define CRIME_REV_PETTY		0x00
+#define CRIME_REV_11		0x11
+#define CRIME_REV_13		0x13
+#define CRIME_REV_14		0x14
+
+#define CRIME_CONTROL		(0x00000008)
+#define CRIME_CONTROL_MASK	0x3fff		/* 14-bit registers */
+
+/* CRIME_CONTROL register bits */
+#define CRIME_CONTROL_TRITON_SYSADC	0x2000
+#define CRIME_CONTROL_CRIME_SYSADC	0x1000
+#define CRIME_CONTROL_HARD_RESET	0x0800
+#define CRIME_CONTROL_SOFT_RESET	0x0400
+#define CRIME_CONTROL_DOG_ENA		0x0200
+#define CRIME_CONTROL_ENDIANESS		0x0100
+
+#define CRIME_CONTROL_ENDIAN_BIG	0x0100
+#define CRIME_CONTROL_ENDIAN_LITTLE	0x0000
+
+#define CRIME_CONTROL_CQUEUE_HWM	0x000f
+#define CRIME_CONTROL_CQUEUE_SHFT	0
+#define CRIME_CONTROL_WBUF_HWM		0x00f0
+#define CRIME_CONTROL_WBUF_SHFT		8
+
+#define CRIME_INT_STAT			(0x00000010)
+#define CRIME_INT_MASK			(0x00000018)
+#define CRIME_SOFT_INT			(0x00000020)
+#define CRIME_HARD_INT			(0x00000028)
+
+/* Bits in CRIME_INT_XXX and CRIME_HARD_INT */
+#define MACE_VID_IN1_INT		BIT (0)
+#define MACE_VID_IN2_INT		BIT (1)
+#define MACE_VID_OUT_INT		BIT (2)
+#define MACE_ETHERNET_INT		BIT (3)
+#define MACE_SUPERIO_INT		BIT (4)
+#define MACE_MISC_INT			BIT (5)
+#define MACE_AUDIO_INT			BIT (6)
+#define MACE_PCI_BRIDGE_INT		BIT (7)
+#define MACEPCI_SCSI0_INT		BIT (8)
+#define MACEPCI_SCSI1_INT		BIT (9)
+#define MACEPCI_SLOT0_INT		BIT (10)
+#define MACEPCI_SLOT1_INT		BIT (11)
+#define MACEPCI_SLOT2_INT		BIT (12)
+#define MACEPCI_SHARED0_INT		BIT (13)
+#define MACEPCI_SHARED1_INT		BIT (14)
+#define MACEPCI_SHARED2_INT		BIT (15)
+#define CRIME_GBE0_INT			BIT (16)
+#define CRIME_GBE1_INT			BIT (17)
+#define CRIME_GBE2_INT			BIT (18)
+#define CRIME_GBE3_INT			BIT (19)
+#define CRIME_CPUERR_INT		BIT (20)
+#define CRIME_MEMERR_INT		BIT (21)
+#define CRIME_RE_EMPTY_E_INT		BIT (22)
+#define CRIME_RE_FULL_E_INT		BIT (23)
+#define CRIME_RE_IDLE_E_INT		BIT (24)
+#define CRIME_RE_EMPTY_L_INT		BIT (25)
+#define CRIME_RE_FULL_L_INT		BIT (26)
+#define CRIME_RE_IDLE_L_INT    		BIT (27)
+#define CRIME_SOFT0_INT			BIT (28)
+#define CRIME_SOFT1_INT			BIT (29)
+#define CRIME_SOFT2_INT			BIT (30)
+#define CRIME_SYSCORERR_INT		CRIME_SOFT2_INT
+#define CRIME_VICE_INT			BIT (31)
+
+/* Masks for deciding who handles the interrupt */
+#define CRIME_MACE_INT_MASK		0x8f
+#define CRIME_MACEISA_INT_MASK		0x70
+#define CRIME_MACEPCI_INT_MASK		0xff00
+#define CRIME_CRIME_INT_MASK		0xffff0000
+
+/*
+ * XXX Todo
+ */
+#define CRIME_DOG			(0x00000030)
+/* We are word-play compatible but not misspelling compatible */
+#define MC_GRUFF			CRIME_DOG
+#define CRIME_DOG_MASK			(0x001fffff)
+
+/* CRIME_DOG register bits */
+#define CRIME_DOG_POWER_ON_RESET	(0x00010000)
+#define CRIME_DOG_WARM_RESET		(0x00080000)
+#define CRIME_DOG_TIMEOUT		(CRIME_DOG_POWER_ON_RESET|CRIME_DOG_WARM_RESET)
+#define CRIME_DOG_VALUE			(0x00007fff)	/* ??? */
+
+#define CRIME_TIME			(0x00000038)
+#define CRIME_TIME_MASK			(0x0000ffffffffffff)
+
+#ifdef MASTER_FREQ
+#undef MASTER_FREQ
+#endif
+#define CRIME_MASTER_FREQ		66666500	/* Crime upcounter frequency */
+#define CRIME_NS_PER_TICK		15	/* for delay_calibrate */
+
+#define CRIME_CPU_ERROR_ADDR		(0x00000040)
+#define CRIME_CPU_ERROR_ADDR_MASK	(0x3ffffffff)
+
+#define CRIME_CPU_ERROR_STAT		(0x00000048)
+/* REV_PETTY only! */
+#define CRIME_CPU_ERROR_ENA		(0x00000050)
+
+/*
+ * bit definitions for CRIME/VICE error status and enable registers
+ */
+#define CRIME_CPU_ERROR_MASK           0x7UL   /* cpu error stat is 3 bits */
+#define CRIME_CPU_ERROR_CPU_ILL_ADDR   0x4
+#define CRIME_CPU_ERROR_VICE_WRT_PRTY  0x2
+#define CRIME_CPU_ERROR_CPU_WRT_PRTY   0x1
+
+/*
+ * these are the definitions for the error status/enable  register in
+ * petty crime.  Note that the enable register does not exist in crime
+ * rev 1 and above.
+ */
+#define CRIME_CPU_ERROR_MASK_REV0		0x3ff	/* cpu error stat is 9 bits */
+#define CRIME_CPU_ERROR_CPU_INV_ADDR_RD		0x200
+#define CRIME_CPU_ERROR_VICE_II			0x100
+#define CRIME_CPU_ERROR_VICE_SYSAD		0x80
+#define CRIME_CPU_ERROR_VICE_SYSCMD		0x40
+#define CRIME_CPU_ERROR_VICE_INV_ADDR		0x20
+#define CRIME_CPU_ERROR_CPU_II			0x10
+#define CRIME_CPU_ERROR_CPU_SYSAD		0x8
+#define CRIME_CPU_ERROR_CPU_SYSCMD		0x4
+#define CRIME_CPU_ERROR_CPU_INV_ADDR_WR		0x2
+#define CRIME_CPU_ERROR_CPU_INV_REG_ADDR	0x1
+
+#define CRIME_VICE_ERROR_ADDR		(0x00000058)
+#define CRIME_VICE_ERROR_ADDR_MASK	(0x3fffffff)
+
+#define CRIME_MEM_CONTROL		(0x00000200)
+#define CRIME_MEM_CONTROL_MASK		0x3	/* 25 cent register */
+#define CRIME_MEM_CONTROL_ECC_ENA	0x1
+#define CRIME_MEM_CONTROL_USE_ECC_REPL	0x2
+
+/*
+ * macros for CRIME memory bank control registers.
+ */
+#define CRIME_MEM_BANK_CONTROL(__bank)		(0x00000208 + ((__bank) << 3))
+#define CRIME_MEM_BANK_CONTROL_MSK		0x11f /* 9 bits 7:5 reserved */
+#define CRIME_MEM_BANK_CONTROL_ADDR		0x01f
+#define CRIME_MEM_BANK_CONTROL_SDRAM_SIZE	0x100
+#define CRIME_MEM_BANK_CONTROL_BANK_TO_ADDR(__bank) \
+	(((__bank) & CRIME_MEM_BANK_CONTROL_ADDR) << 25)
+
+#define CRIME_MEM_REFRESH_COUNTER	(0x00000248)
+#define CRIME_MEM_REFRESH_COUNTER_MASK	0x7ff	/* 11-bit register */
+
+#define CRIME_MAXBANKS                 8
+
+/*
+ * CRIME Memory error status register bit definitions
+ */
+#define CRIME_MEM_ERROR_STAT		(0x00000250)
+#define CRIME_MEM_ERROR_STAT_MASK       0x0ff7ffff    /* 28-bit register */
+#define CRIME_MEM_ERROR_MACE_ID		0x0000007f
+#define CRIME_MEM_ERROR_MACE_ACCESS	0x00000080
+#define CRIME_MEM_ERROR_RE_ID		0x00007f00
+#define CRIME_MEM_ERROR_RE_ACCESS	0x00008000
+#define CRIME_MEM_ERROR_GBE_ACCESS	0x00010000
+#define CRIME_MEM_ERROR_VICE_ACCESS	0x00020000
+#define CRIME_MEM_ERROR_CPU_ACCESS	0x00040000
+#define CRIME_MEM_ERROR_RESERVED	0x00080000
+#define CRIME_MEM_ERROR_SOFT_ERR	0x00100000
+#define CRIME_MEM_ERROR_HARD_ERR	0x00200000
+#define CRIME_MEM_ERROR_MULTIPLE	0x00400000
+#define CRIME_MEM_ERROR_MEM_ECC_RD	0x00800000
+#define CRIME_MEM_ERROR_MEM_ECC_RMW	0x01000000
+#define CRIME_MEM_ERROR_INV_MEM_ADDR_RD	0x02000000
+#define CRIME_MEM_ERROR_INV_MEM_ADDR_WR	0x04000000
+#define CRIME_MEM_ERROR_INV_MEM_ADDR_RMW	0x08000000
+
+#define CRIME_MEM_ERROR_ADDR		(0x00000258)
+#define CRIME_MEM_ERROR_ADDR_MASK	0x3fffffff
+
+#define CRIME_MEM_ERROR_ECC_SYN		(0x00000260)
+#define CRIME_MEM_ERROR_ECC_SYN_MASK	0xffffffff
+
+#define CRIME_MEM_ERROR_ECC_CHK		(0x00000268)
+#define CRIME_MEM_ERROR_ECC_CHK_MASK    0xffffffff
+
+#define CRIME_MEM_ERROR_ECC_REPL	(0x00000270)
+#define CRIME_MEM_ERROR_ECC_REPL_MASK	0xffffffff
+
+#endif /* __ASM_CRIME_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/ip32/io.h linux/include/asm-mips64/ip32/io.h
--- linux.orig/include/asm-mips64/ip32/io.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/ip32/io.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,15 @@
+#ifndef __ASM_IP32_IO_H__
+#define __ASM_IP32_IO_H__
+
+#include <asm/ip32/mace.h>
+
+/*#ifdef CONFIG_MIPS_UNCACHED*/
+#define UNCACHEDADDR(x) (0x9000000000000000UL | (u64)(x))
+/*#else
+#define UNCACHEDADDR(x) (x)
+#endif*/
+/*#define UNCACHEDADDR(x) (KSEG1ADDR (x)) */
+#define IO_SPACE_BASE UNCACHEDADDR (MACEPCI_HI_MEMORY)
+#define IO_SPACE_LIMIT 0xffffffffUL
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/ip32/ip32_ints.h linux/include/asm-mips64/ip32/ip32_ints.h
--- linux.orig/include/asm-mips64/ip32/ip32_ints.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/ip32/ip32_ints.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,94 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Harald Koerfgen
+ */
+
+#ifndef __ASM_IP32_INTS_H
+#define __ASM_IP32_INTS_H
+
+/*
+ * This list reflects the assignment of interrupt numbers to
+ * interrupting events.  Order is fairly irrelevant to handling
+ * priority.  This differs from irix.
+ */
+
+/* CPU */
+#define CLOCK_IRQ			0
+
+/* MACE */
+#define MACE_VID_IN1_IRQ		1
+#define MACE_VID_IN2_IRQ		2
+#define MACE_VID_OUT_IRQ		3
+#define MACE_ETHERNET_IRQ		4
+/* SUPERIO, MISC, and AUDIO are MACEISA */
+#define MACE_PCI_BRIDGE_IRQ		8
+
+/* MACEPCI */
+#define MACEPCI_SCSI0_IRQ		9
+#define MACEPCI_SCSI1_IRQ		10
+#define MACEPCI_SLOT0_IRQ		11
+#define MACEPCI_SLOT1_IRQ		12
+#define MACEPCI_SLOT2_IRQ		13
+#define MACEPCI_SHARED0_IRQ		14
+#define MACEPCI_SHARED1_IRQ		15
+#define MACEPCI_SHARED2_IRQ		16
+
+/* CRIME */
+#define CRIME_GBE0_IRQ			17
+#define CRIME_GBE1_IRQ			18
+#define CRIME_GBE2_IRQ			19
+#define CRIME_GBE3_IRQ			20
+#define CRIME_CPUERR_IRQ		21
+#define CRIME_MEMERR_IRQ		22
+#define CRIME_RE_EMPTY_E_IRQ		23
+#define CRIME_RE_FULL_E_IRQ		24
+#define CRIME_RE_IDLE_E_IRQ		25
+#define CRIME_RE_EMPTY_L_IRQ		26
+#define CRIME_RE_FULL_L_IRQ		27
+#define CRIME_RE_IDLE_L_IRQ		28
+#define CRIME_SOFT0_IRQ			29
+#define CRIME_SOFT1_IRQ			30
+#define CRIME_SOFT2_IRQ			31
+#define CRIME_SYSCORERR_IRQ		CRIME_SOFT2_IRQ
+#define CRIME_VICE_IRQ			32
+
+/* MACEISA */
+#define MACEISA_AUDIO_SW_IRQ		33
+#define MACEISA_AUDIO_SC_IRQ		34
+#define MACEISA_AUDIO1_DMAT_IRQ		35
+#define MACEISA_AUDIO1_OF_IRQ		36
+#define MACEISA_AUDIO2_DMAT_IRQ		37
+#define MACEISA_AUDIO2_MERR_IRQ		38
+#define MACEISA_AUDIO3_DMAT_IRQ		39
+#define MACEISA_AUDIO3_MERR_IRQ		40
+#define MACEISA_RTC_IRQ			41
+#define MACEISA_KEYB_IRQ		42
+/* MACEISA_KEYB_POLL is not an IRQ */
+#define MACEISA_MOUSE_IRQ		44
+/* MACEISA_MOUSE_POLL is not an IRQ */
+#define MACEISA_TIMER0_IRQ		46
+#define MACEISA_TIMER1_IRQ		47
+#define MACEISA_TIMER2_IRQ		48
+#define MACEISA_PARALLEL_IRQ		49
+#define MACEISA_PAR_CTXA_IRQ		50
+#define MACEISA_PAR_CTXB_IRQ		51
+#define MACEISA_PAR_MERR_IRQ		52
+#define MACEISA_SERIAL1_IRQ		53
+#define MACEISA_SERIAL1_TDMAT_IRQ	54
+#define MACEISA_SERIAL1_TDMAPR_IRQ	55
+#define MACEISA_SERIAL1_TDMAME_IRQ	56
+#define MACEISA_SERIAL1_RDMAT_IRQ	57
+#define MACEISA_SERIAL1_RDMAOR_IRQ	58
+#define MACEISA_SERIAL2_IRQ		59
+#define MACEISA_SERIAL2_TDMAT_IRQ	60
+#define MACEISA_SERIAL2_TDMAPR_IRQ	61
+#define MACEISA_SERIAL2_TDMAME_IRQ	62
+#define MACEISA_SERIAL2_RDMAT_IRQ	63
+#define MACEISA_SERIAL2_RDMAOR_IRQ	64
+
+#define IP32_IRQ_MAX			MACEISA_SERIAL2_RDMAOR_IRQ
+
+#endif /* __ASM_IP32_INTS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/ip32/mace.h linux/include/asm-mips64/ip32/mace.h
--- linux.orig/include/asm-mips64/ip32/mace.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/ip32/mace.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,254 @@
+/*
+ * Definitions for the SGI O2 Mace chip.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Harald Koerfgen
+ */
+
+#ifndef __ASM_MACE_H__
+#define __ASM_MACE_H__
+
+#include <asm/addrspace.h>
+
+/*
+ * Address map
+ */
+#define MACE_BASE		KSEG1ADDR(0x1f000000)
+#define MACE_PCI		(0x00080000)
+#define MACE_VIN1		(0x00100000)
+#define MACE_VIN2		(0x00180000)
+#define MACE_VOUT		(0x00200000)
+#define MACE_ENET		(0x00280000)
+#define MACE_PERIF		(0x00300000)
+#define MACE_ISA_EXT		(0x00380000)
+
+#define MACE_AUDIO_BASE		(MACE_PERIF		)
+#define MACE_ISA_BASE		(MACE_PERIF + 0x00010000)
+#define MACE_KBDMS_BASE		(MACE_PERIF + 0x00020000)
+#define MACE_I2C_BASE		(MACE_PERIF + 0x00030000)
+#define MACE_UST_BASE		(MACE_PERIF + 0x00040000)
+
+
+#undef BIT
+#define BIT(__bit_offset) (1UL << (__bit_offset))
+
+/*
+ * Mace MACEPCI interface, 32 bit regs
+ */
+#define MACEPCI_ERROR_ADDR		(MACE_PCI	      )
+#define MACEPCI_ERROR_FLAGS		(MACE_PCI + 0x00000004)
+#define MACEPCI_CONTROL			(MACE_PCI + 0x00000008)
+#define MACEPCI_REV			(MACE_PCI + 0x0000000c)
+#define MACEPCI_WFLUSH			(MACE_PCI + 0x0000000c) /* ??? --IV !!! It's for flushing read buffers on PCI MEMORY accesses!!! */
+#define MACEPCI_CONFIG_ADDR		(MACE_PCI + 0x00000cf8)
+#define MACEPCI_CONFIG_DATA		(MACE_PCI + 0x00000cfc)
+#define MACEPCI_LOW_MEMORY		0x1a000000
+#define MACEPCI_LOW_IO			0x18000000
+#define MACEPCI_SWAPPED_VIEW		0
+#define MACEPCI_NATIVE_VIEW		0x40000000
+#define MACEPCI_IO			0x80000000
+/*#define MACEPCI_HI_MEMORY		0x0000000280000000UL * This mipght be just 0x0000000200000000UL 2G more :) (or maybe it is different between 1.1 & 1.5 */ 
+#define MACEPCI_HI_MEMORY		0x0000000200000000UL /* This mipght be just 0x0000000200000000UL 2G more :) (or maybe it is different between 1.1 & 1.5 */ 
+#define MACEPCI_HI_IO			0x0000000100000000UL
+
+/*
+ * Bits in the MACEPCI_CONTROL register
+ */
+#define MACEPCI_CONTROL_INT(x)		BIT(x)
+#define MACEPCI_CONTROL_INT_MASK	0xff
+#define MACEPCI_CONTROL_SERR_ENA	BIT(8)
+#define MACEPCI_CONTROL_ARB_N6		BIT(9)
+#define MACEPCI_CONTROL_PARITY_ERR	BIT(10)
+#define MACEPCI_CONTROL_MRMRA_ENA	BIT(11)
+#define MACEPCI_CONTROL_ARB_N3		BIT(12)
+#define MACEPCI_CONTROL_ARB_N4		BIT(13)
+#define MACEPCI_CONTROL_ARB_N5		BIT(14)
+#define MACEPCI_CONTROL_PARK_LIU	BIT(15)
+#define MACEPCI_CONTROL_INV_INT(x)	BIT(16+x)
+#define MACEPCI_CONTROL_INV_INT_MASK	0x00ff0000
+#define MACEPCI_CONTROL_OVERRUN_INT	BIT(24)
+#define MACEPCI_CONTROL_PARITY_INT	BIT(25)
+#define MACEPCI_CONTROL_SERR_INT	BIT(26)
+#define MACEPCI_CONTROL_IT_INT		BIT(27)
+#define MACEPCI_CONTROL_RE_INT		BIT(28)
+#define MACEPCI_CONTROL_DPED_INT	BIT(29)
+#define MACEPCI_CONTROL_TAR_INT		BIT(30)
+#define MACEPCI_CONTROL_MAR_INT		BIT(31)
+
+/*
+ * Bits in the MACE_PCI error register
+ */
+#define MACEPCI_ERROR_MASTER_ABORT		BIT(31)
+#define MACEPCI_ERROR_TARGET_ABORT		BIT(30)
+#define MACEPCI_ERROR_DATA_PARITY_ERR		BIT(29)
+#define MACEPCI_ERROR_RETRY_ERR		BIT(28)
+#define MACEPCI_ERROR_ILLEGAL_CMD		BIT(27)
+#define MACEPCI_ERROR_SYSTEM_ERR		BIT(26)
+#define MACEPCI_ERROR_INTERRUPT_TEST		BIT(25)
+#define MACEPCI_ERROR_PARITY_ERR		BIT(24)
+#define MACEPCI_ERROR_OVERRUN			BIT(23)
+#define MACEPCI_ERROR_RSVD			BIT(22)
+#define MACEPCI_ERROR_MEMORY_ADDR		BIT(21)
+#define MACEPCI_ERROR_CONFIG_ADDR		BIT(20)
+#define MACEPCI_ERROR_MASTER_ABORT_ADDR_VALID	BIT(19)
+#define MACEPCI_ERROR_TARGET_ABORT_ADDR_VALID	BIT(18)
+#define MACEPCI_ERROR_DATA_PARITY_ADDR_VALID	BIT(17)
+#define MACEPCI_ERROR_RETRY_ADDR_VALID		BIT(16)
+#define MACEPCI_ERROR_SIG_TABORT		BIT(4)
+#define MACEPCI_ERROR_DEVSEL_MASK		0xc0
+#define MACEPCI_ERROR_DEVSEL_FAST		0
+#define MACEPCI_ERROR_DEVSEL_MED		0x40
+#define MACEPCI_ERROR_DEVSEL_SLOW		0x80
+#define MACEPCI_ERROR_FBB			BIT(1)
+#define MACEPCI_ERROR_66MHZ			BIT(0)
+
+/*
+ * Mace timer registers - 64 bit regs (63:32 are UST, 31:0 are MSC)
+ */
+#define MSC_PART(__reg) ((__reg) & 0x00000000ffffffff)
+#define UST_PART(__reg) (((__reg) & 0xffffffff00000000) >> 32)
+
+#define MACE_UST_UST		(MACE_UST_BASE		   ) /* Universial system time */
+#define MACE_UST_COMPARE1	(MACE_UST_BASE + 0x00000008) /* Interrupt compare reg 1 */
+#define MACE_UST_COMPARE2	(MACE_UST_BASE + 0x00000010) /* Interrupt compare reg 2 */
+#define MACE_UST_COMPARE3	(MACE_UST_BASE + 0x00000018) /* Interrupt compare reg 3 */
+#define MACE_UST_PERIOD_NS	960	/* UST Period in ns  */
+
+#define MACE_UST_AIN_MSC	(MACE_UST_BASE + 0x00000020) /* Audio in MSC/UST pair */
+#define MACE_UST_AOUT1_MSC	(MACE_UST_BASE + 0x00000028) /* Audio out 1 MSC/UST pair */
+#define MACE_UST_AOUT2_MSC	(MACE_UST_BASE + 0x00000030) /* Audio out 2 MSC/UST pair */
+#define MACE_VIN1_MSC_UST	(MACE_UST_BASE + 0x00000038) /* Video In 1 MSC/UST pair */
+#define MACE_VIN2_MSC_UST	(MACE_UST_BASE + 0x00000040) /* Video In 2 MSC/UST pair */
+#define MACE_VOUT_MSC_UST	(MACE_UST_BASE + 0x00000048) /* Video out MSC/UST pair */
+
+/*
+ * Mace "ISA" peripherals
+ */
+#define MACEISA_EPP_BASE   	(MACE_ISA_EXT		  )
+#define MACEISA_ECP_BASE   	(MACE_ISA_EXT + 0x00008000)
+#define MACEISA_SER1_BASE	(MACE_ISA_EXT + 0x00010000)
+#define MACEISA_SER2_BASE	(MACE_ISA_EXT + 0x00018000)
+#define MACEISA_RTC_BASE	(MACE_ISA_EXT + 0x00020000)
+#define MACEISA_GAME_BASE	(MACE_ISA_EXT + 0x00030000)
+
+/*
+ * Ringbase address and reset register - 64 bits
+ */
+#define MACEISA_RINGBASE	MACE_ISA_BASE
+
+/*
+ * Flash-ROM/LED/DP-RAM/NIC Controller Register - 64 bits (?)
+ */
+#define MACEISA_FLASH_NIC_REG	(MACE_ISA_BASE + 0x00000008)
+
+/*
+ * Bit definitions for that
+ */
+#define MACEISA_FLASH_WE       BIT(0) /* 1=> Enable FLASH writes */
+#define MACEISA_PWD_CLEAR      BIT(1) /* 1=> PWD CLEAR jumper detected */
+#define MACEISA_NIC_DEASSERT   BIT(2)
+#define MACEISA_NIC_DATA       BIT(3)
+#define MACEISA_LED_RED        BIT(4) /* 1=> Illuminate RED LED */
+#define MACEISA_LED_GREEN      BIT(5) /* 1=> Illuminate GREEN LED */
+#define MACEISA_DP_RAM_ENABLE  BIT(6)
+
+/*
+ * ISA interrupt and status registers - 32 bit
+ */
+#define MACEISA_INT_STAT	(MACE_ISA_BASE + 0x00000014)
+#define MACEISA_INT_MASK	(MACE_ISA_BASE + 0x0000001c)
+
+/*
+ * Bits in the status/mask registers
+ */
+#define MACEISA_AUDIO_SW_INT		BIT (0)
+#define MACEISA_AUDIO_SC_INT		BIT (1)
+#define MACEISA_AUDIO1_DMAT_INT		BIT (2)
+#define MACEISA_AUDIO1_OF_INT		BIT (3)
+#define MACEISA_AUDIO2_DMAT_INT		BIT (4)
+#define MACEISA_AUDIO2_MERR_INT		BIT (5)
+#define MACEISA_AUDIO3_DMAT_INT		BIT (6)
+#define MACEISA_AUDIO3_MERR_INT		BIT (7)
+#define MACEISA_RTC_INT			BIT (8)
+#define MACEISA_KEYB_INT		BIT (9)
+#define MACEISA_KEYB_POLL_INT		BIT (10)
+#define MACEISA_MOUSE_INT		BIT (11)
+#define MACEISA_MOUSE_POLL_INT		BIT (12)
+#define MACEISA_TIMER0_INT		BIT (13)
+#define MACEISA_TIMER1_INT		BIT (14)
+#define MACEISA_TIMER2_INT		BIT (15)
+#define MACEISA_PARALLEL_INT		BIT (16)
+#define MACEISA_PAR_CTXA_INT		BIT (17)
+#define MACEISA_PAR_CTXB_INT		BIT (18)
+#define MACEISA_PAR_MERR_INT		BIT (19)
+#define MACEISA_SERIAL1_INT		BIT (20)
+#define MACEISA_SERIAL1_TDMAT_INT	BIT (21)
+#define MACEISA_SERIAL1_TDMAPR_INT	BIT (22)
+#define MACEISA_SERIAL1_TDMAME_INT	BIT (23)
+#define MACEISA_SERIAL1_RDMAT_INT	BIT (24)
+#define MACEISA_SERIAL1_RDMAOR_INT	BIT (25)
+#define MACEISA_SERIAL2_INT		BIT (26)
+#define MACEISA_SERIAL2_TDMAT_INT	BIT (27)
+#define MACEISA_SERIAL2_TDMAPR_INT	BIT (28)
+#define MACEISA_SERIAL2_TDMAME_INT	BIT (29)
+#define MACEISA_SERIAL2_RDMAT_INT	BIT (30)
+#define MACEISA_SERIAL2_RDMAOR_INT	BIT (31)
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+
+/*
+ * XXX Some of these are probably not needed (or even legal?)
+ */
+static inline u8 mace_read_8 (unsigned long __offset)
+{
+	return *((volatile u8 *) (MACE_BASE + __offset));
+}
+
+static inline u16 mace_read_16 (unsigned long __offset)
+{
+	return *((volatile u16 *) (MACE_BASE + __offset));
+}
+
+static inline u32 mace_read_32 (unsigned long __offset)
+{
+	return *((volatile u32 *) (MACE_BASE + __offset));
+}
+
+static inline u64 mace_read_64 (unsigned long __offset)
+{
+	return *((volatile u64 *) (MACE_BASE + __offset));
+}
+
+static inline void mace_write_8 (unsigned long __offset, u8 __val)
+{
+	*((volatile u8 *) (MACE_BASE + __offset)) = __val;
+}
+
+static inline void mace_write_16 (unsigned long __offset, u16 __val)
+{
+	*((volatile u16 *) (MACE_BASE + __offset)) = __val;
+}
+
+static inline void mace_write_32 (unsigned long __offset, u32 __val)
+{
+	*((volatile u32 *) (MACE_BASE + __offset)) = __val;
+}
+
+static inline void mace_write_64 (unsigned long __offset, u64 __val)
+{
+	*((volatile u64 *) (MACE_BASE + __offset)) = __val;
+}
+
+/* Call it whenever device needs to read data from main memory coherently */
+static inline void mace_inv_read_buffers(void)
+{
+/*	mace_write_32(MACEPCI_WFLUSH,0xffffffff);*/
+}
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __ASM_MACE_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/ip32/machine.h linux/include/asm-mips64/ip32/machine.h
--- linux.orig/include/asm-mips64/ip32/machine.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/ip32/machine.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,21 @@
+/*
+ * machine.h -- Machine/group probing for ip32
+ *
+ * Copyright (C) 2001 Keith M Wesolowski
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_IP32_MACHINE_H
+#define _ASM_IP32_MACHINE_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SGI_IP32
+
+#define SGI_MACH_O2		0x3201
+
+#endif /* CONFIG_SGI_IP32 */
+
+#endif /* _ASM_SGI_MACHINE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/irq_cpu.h linux/include/asm-mips64/irq_cpu.h
--- linux.orig/include/asm-mips64/irq_cpu.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/irq_cpu.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,18 @@
+/*
+ *	include/asm-mips/irq_cpu.h
+ *
+ *	MIPS CPU interrupt definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	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.
+ */
+#ifndef __ASM_MIPS64_IRQ_CPU_H
+#define __ASM_MIPS64_IRQ_CPU_H
+
+extern void mips_cpu_irq_init(int irq_base);
+
+#endif /* __ASM_MIPS64_IRQ_CPU_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/keyboard.h linux/include/asm-mips64/keyboard.h
--- linux.orig/include/asm-mips64/keyboard.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/keyboard.h	2002-07-20 01:08:30.000000000 +0000
@@ -3,37 +3,40 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1999, 2001 Ralf Baechle
- * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 1994 - 1999 Ralf Baechle
  */
 #ifndef _ASM_KEYBOARD_H
 #define _ASM_KEYBOARD_H
 
 #ifdef __KERNEL__
 
+#include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/kd.h>
-#include <asm/bootinfo.h>
+#include <linux/pm.h>
 
 #define DISABLE_KBD_DURING_INTERRUPTS 0
 
+#ifdef CONFIG_PC_KEYB
+
 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
 extern int pckbd_getkeycode(unsigned int scancode);
 extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
 			   char raw_mode);
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
-extern int pckbd_rate(struct kbd_repeat *rep);
 extern void pckbd_init_hw(void);
+extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *);
+extern pm_callback pm_kbd_request_override;
 extern unsigned char pckbd_sysrq_xlate[128];
+extern void kbd_forward_char (int ch);
 
 #define kbd_setkeycode		pckbd_setkeycode
 #define kbd_getkeycode		pckbd_getkeycode
 #define kbd_translate		pckbd_translate
 #define kbd_unexpected_up	pckbd_unexpected_up
 #define kbd_leds		pckbd_leds
-#define kbd_rate		pckbd_rate
 #define kbd_init_hw		pckbd_init_hw
 #define kbd_sysrq_xlate         pckbd_sysrq_xlate
 
@@ -72,6 +75,22 @@
 #define kbd_write_command(val) kbd_ops->kbd_write_command(val)
 #define kbd_read_status() kbd_ops->kbd_read_status()
 
+#else
+
+extern int kbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int kbd_getkeycode(unsigned int scancode);
+extern int kbd_translate(unsigned char scancode, unsigned char *keycode,
+	char raw_mode);
+extern char kbd_unexpected_up(unsigned char keycode);
+extern void kbd_leds(unsigned char leds);
+extern void kbd_init_hw(void);
+extern unsigned char *kbd_sysrq_xlate;
+
+extern unsigned char kbd_sysrq_key;
+#define SYSRQ_KEY kbd_sysrq_key
+
+#endif
+
 #endif /* __KERNEL */
 
 #endif /* _ASM_KEYBOARD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/mips-boards/bonito64.h linux/include/asm-mips64/mips-boards/bonito64.h
--- linux.orig/include/asm-mips64/mips-boards/bonito64.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/mips-boards/bonito64.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,432 @@
+/*
+ * bonito.h
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2001 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This file is the original bonito.h from Algorithmics with minor changes
+ * to fit into linux.
+ */
+
+/*
+ * Bonito Register Map 
+ * Copyright (c) 1999 Algorithmics Ltd
+ *
+ * Algorithmics gives permission for anyone to use and modify this file
+ * without any obligation or license condition except that you retain
+ * this copyright message in any source redistribution in whole or part.
+ *
+ * Updated copies of this and other files can be found at
+ * ftp://ftp.algor.co.uk/pub/bonito/
+ * 
+ * Users of the Bonito controller are warmly recommended to contribute
+ * any useful changes back to Algorithmics (mail to bonito@algor.co.uk).
+ */
+
+/* Revision 1.48 autogenerated on 08/17/99 15:20:01 */
+/* This bonito64 version editted from bonito.h Revision 1.48 on 11/09/00 */
+
+#ifndef _ASM_MIPS_BOARDS_BONITO64_H
+#define _ASM_MIPS_BOARDS_BONITO64_H
+
+#ifdef __ASSEMBLY__
+
+/* offsets from base register */
+#define BONITO(x)	(x)
+
+#else /* !__ASSEMBLY__ */
+
+/* offsets from base pointer, this construct allows optimisation */
+/* static char * const _bonito = PA_TO_KVA1(BONITO_BASE); */
+#define BONITO(x)		*(volatile u32 *)(_bonito + (x))
+
+#endif /* __ASSEMBLY__ */
+
+
+#define BONITO_BOOT_BASE		0x1fc00000
+#define BONITO_BOOT_SIZE		0x00100000
+#define BONITO_BOOT_TOP 		(BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE		0x1c000000
+#define BONITO_FLASH_SIZE		0x03000000
+#define BONITO_FLASH_TOP		(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE		0x1f800000
+#define BONITO_SOCKET_SIZE		0x00400000
+#define BONITO_SOCKET_TOP		(BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 		0x1fe00000
+#define BONITO_REG_SIZE 		0x00040000
+#define BONITO_REG_TOP			(BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 		0x1ff00000
+#define BONITO_DEV_SIZE 		0x00100000
+#define BONITO_DEV_TOP			(BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE		0x10000000
+#define BONITO_PCILO_SIZE		0x0c000000
+#define BONITO_PCILO_TOP		(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE		0x10000000
+#define BONITO_PCILO1_BASE		0x14000000
+#define BONITO_PCILO2_BASE		0x18000000
+#define BONITO_PCIHI_BASE		0x20000000
+#define BONITO_PCIHI_SIZE		0x20000000
+#define BONITO_PCIHI_TOP		(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE		0x1fd00000
+#define BONITO_PCIIO_SIZE		0x00100000
+#define BONITO_PCIIO_TOP		(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE		0x1fe80000
+#define BONITO_PCICFG_SIZE		0x00080000
+#define BONITO_PCICFG_TOP		(BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+ 
+
+/* Bonito Register Bases */
+
+#define BONITO_PCICONFIGBASE		0x00
+#define BONITO_REGBASE			0x100
+
+
+/* PCI Configuration  Registers */
+
+#define BONITO_PCI_REG(x)               BONITO(BONITO_PCICONFIGBASE + (x))
+#define BONITO_PCIDID			BONITO_PCI_REG(0x00)
+#define BONITO_PCICMD			BONITO_PCI_REG(0x04)
+#define BONITO_PCICLASS 		BONITO_PCI_REG(0x08)
+#define BONITO_PCILTIMER		BONITO_PCI_REG(0x0c)
+#define BONITO_PCIBASE0 		BONITO_PCI_REG(0x10)
+#define BONITO_PCIBASE1 		BONITO_PCI_REG(0x14)
+#define BONITO_PCIBASE2 		BONITO_PCI_REG(0x18)
+#define BONITO_PCIEXPRBASE		BONITO_PCI_REG(0x30)
+#define BONITO_PCIINT			BONITO_PCI_REG(0x3c)
+
+#define BONITO_PCICMD_PERR_CLR		0x80000000
+#define BONITO_PCICMD_SERR_CLR		0x40000000
+#define BONITO_PCICMD_MABORT_CLR	0x20000000
+#define BONITO_PCICMD_MTABORT_CLR	0x10000000
+#define BONITO_PCICMD_TABORT_CLR	0x08000000
+#define BONITO_PCICMD_MPERR_CLR 	0x01000000
+#define BONITO_PCICMD_PERRRESPEN	0x00000040
+#define BONITO_PCICMD_ASTEPEN		0x00000080
+#define BONITO_PCICMD_SERREN		0x00000100
+#define BONITO_PCILTIMER_BUSLATENCY	0x0000ff00
+#define BONITO_PCILTIMER_BUSLATENCY_SHIFT	8
+
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG		BONITO(BONITO_REGBASE + 0x00)
+
+#define BONITO_BONPONCFG_SYSCONTROLLERRD	0x00040000
+#define BONITO_BONPONCFG_ROMCS1SAMP	0x00020000
+#define BONITO_BONPONCFG_ROMCS0SAMP	0x00010000
+#define BONITO_BONPONCFG_CPUBIGEND	0x00004000
+/* Added by RPF 11-9-00 */
+#define BONITO_BONPONCFG_BURSTORDER	0x00001000
+/* --- */
+#define BONITO_BONPONCFG_CPUPARITY	0x00002000
+#define BONITO_BONPONCFG_CPUTYPE	0x00000007
+#define BONITO_BONPONCFG_CPUTYPE_SHIFT	0
+#define BONITO_BONPONCFG_PCIRESET_OUT	0x00000008
+#define BONITO_BONPONCFG_IS_ARBITER	0x00000010
+#define BONITO_BONPONCFG_ROMBOOT	0x000000c0
+#define BONITO_BONPONCFG_ROMBOOT_SHIFT	6
+
+#define BONITO_BONPONCFG_ROMBOOT_FLASH	(0x0<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_SOCKET (0x1<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_SDRAM	(0x2<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_CPURESET	(0x3<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+
+#define BONITO_BONPONCFG_ROMCS0WIDTH	0x00000100
+#define BONITO_BONPONCFG_ROMCS1WIDTH	0x00000200
+#define BONITO_BONPONCFG_ROMCS0FAST	0x00000400
+#define BONITO_BONPONCFG_ROMCS1FAST	0x00000800
+#define BONITO_BONPONCFG_CONFIG_DIS	0x00000020
+
+
+/* Other Bonito configuration */
+
+#define BONITO_BONGENCFG_OFFSET         0x4
+#define BONITO_BONGENCFG		BONITO(BONITO_REGBASE + BONITO_BONGENCFG_OFFSET)
+
+#define BONITO_BONGENCFG_DEBUGMODE	0x00000001
+#define BONITO_BONGENCFG_SNOOPEN	0x00000002
+#define BONITO_BONGENCFG_CPUSELFRESET	0x00000004
+
+#define BONITO_BONGENCFG_FORCE_IRQA	0x00000008
+#define BONITO_BONGENCFG_IRQA_ISOUT	0x00000010
+#define BONITO_BONGENCFG_IRQA_FROM_INT1 0x00000020
+#define BONITO_BONGENCFG_BYTESWAP	0x00000040
+
+#define BONITO_BONGENCFG_UNCACHED	0x00000080
+#define BONITO_BONGENCFG_PREFETCHEN	0x00000100
+#define BONITO_BONGENCFG_WBEHINDEN	0x00000200
+#define BONITO_BONGENCFG_CACHEALG	0x00000c00
+#define BONITO_BONGENCFG_CACHEALG_SHIFT 10
+#define BONITO_BONGENCFG_PCIQUEUE	0x00001000
+#define BONITO_BONGENCFG_CACHESTOP	0x00002000
+#define BONITO_BONGENCFG_MSTRBYTESWAP	0x00004000
+#define BONITO_BONGENCFG_BUSERREN	0x00008000
+#define BONITO_BONGENCFG_NORETRYTIMEOUT 0x00010000
+#define BONITO_BONGENCFG_SHORTCOPYTIMEOUT	0x00020000
+
+/* 2. IO & IDE configuration */
+
+#define BONITO_IODEVCFG 		BONITO(BONITO_REGBASE + 0x08)
+
+/* 3. IO & IDE configuration */
+
+#define BONITO_SDCFG			BONITO(BONITO_REGBASE + 0x0c)
+
+/* 4. PCI address map control */
+
+#define BONITO_PCIMAP			BONITO(BONITO_REGBASE + 0x10)
+#define BONITO_PCIMEMBASECFG		BONITO(BONITO_REGBASE + 0x14)
+#define BONITO_PCIMAP_CFG		BONITO(BONITO_REGBASE + 0x18)
+
+/* 5. ICU & GPIO regs */
+ 
+/* GPIO Regs - r/w */
+
+#define BONITO_GPIODATA_OFFSET          0x1c
+#define BONITO_GPIODATA 		BONITO(BONITO_REGBASE + BONITO_GPIODATA_OFFSET)
+#define BONITO_GPIOIE			BONITO(BONITO_REGBASE + 0x20)
+
+/* ICU Configuration Regs - r/w */
+
+#define BONITO_INTEDGE			BONITO(BONITO_REGBASE + 0x24)
+#define BONITO_INTSTEER 		BONITO(BONITO_REGBASE + 0x28)
+#define BONITO_INTPOL			BONITO(BONITO_REGBASE + 0x2c)
+
+/* ICU Enable Regs - IntEn & IntISR are r/o. */
+
+#define BONITO_INTENSET 		BONITO(BONITO_REGBASE + 0x30)
+#define BONITO_INTENCLR 		BONITO(BONITO_REGBASE + 0x34)
+#define BONITO_INTEN			BONITO(BONITO_REGBASE + 0x38)
+#define BONITO_INTISR			BONITO(BONITO_REGBASE + 0x3c)
+
+/* PCI mail boxes */
+
+#define BONITO_PCIMAIL0_OFFSET          0x40
+#define BONITO_PCIMAIL1_OFFSET          0x44
+#define BONITO_PCIMAIL2_OFFSET          0x48
+#define BONITO_PCIMAIL3_OFFSET          0x4c
+#define BONITO_PCIMAIL0 		BONITO(BONITO_REGBASE + 0x40)
+#define BONITO_PCIMAIL1 		BONITO(BONITO_REGBASE + 0x44)
+#define BONITO_PCIMAIL2 		BONITO(BONITO_REGBASE + 0x48)
+#define BONITO_PCIMAIL3 		BONITO(BONITO_REGBASE + 0x4c)
+
+
+/* 6. PCI cache */
+
+#define BONITO_PCICACHECTRL		BONITO(BONITO_REGBASE + 0x50)
+#define BONITO_PCICACHETAG		BONITO(BONITO_REGBASE + 0x54)
+
+#define BONITO_PCIBADADDR		BONITO(BONITO_REGBASE + 0x58)
+#define BONITO_PCIMSTAT 		BONITO(BONITO_REGBASE + 0x5c)
+
+
+/*
+#define BONITO_PCIRDPOST		BONITO(BONITO_REGBASE + 0x60)
+#define BONITO_PCIDATA			BONITO(BONITO_REGBASE + 0x64)
+*/
+
+/* 7. IDE DMA & Copier */
+ 
+#define BONITO_CONFIGBASE		0x000
+#define BONITO_BONITOBASE		0x100
+#define BONITO_LDMABASE 		0x200
+#define BONITO_COPBASE			0x300
+#define BONITO_REG_BLOCKMASK		0x300
+
+#define BONITO_LDMACTRL 		BONITO(BONITO_LDMABASE + 0x0)
+#define BONITO_LDMASTAT 		BONITO(BONITO_LDMABASE + 0x0)
+#define BONITO_LDMAADDR 		BONITO(BONITO_LDMABASE + 0x4)
+#define BONITO_LDMAGO			BONITO(BONITO_LDMABASE + 0x8)
+#define BONITO_LDMADATA 		BONITO(BONITO_LDMABASE + 0xc)
+
+#define BONITO_COPCTRL			BONITO(BONITO_COPBASE + 0x0)
+#define BONITO_COPSTAT			BONITO(BONITO_COPBASE + 0x0)
+#define BONITO_COPPADDR 		BONITO(BONITO_COPBASE + 0x4)
+#define BONITO_COPDADDR 		BONITO(BONITO_COPBASE + 0x8)
+#define BONITO_COPGO			BONITO(BONITO_COPBASE + 0xc)
+
+
+/* ###### Bit Definitions for individual Registers #### */
+
+/* Gen DMA. */
+
+#define BONITO_IDECOPDADDR_DMA_DADDR	0x0ffffffc
+#define BONITO_IDECOPDADDR_DMA_DADDR_SHIFT	2
+#define BONITO_IDECOPPADDR_DMA_PADDR	0xfffffffc
+#define BONITO_IDECOPPADDR_DMA_PADDR_SHIFT	2
+#define BONITO_IDECOPGO_DMA_SIZE	0x0000fffe
+#define BONITO_IDECOPGO_DMA_SIZE_SHIFT	0
+#define BONITO_IDECOPGO_DMA_WRITE	0x00010000
+#define BONITO_IDECOPGO_DMAWCOUNT	0x000f0000
+#define BONITO_IDECOPGO_DMAWCOUNT_SHIFT	16
+
+#define BONITO_IDECOPCTRL_DMA_STARTBIT	0x80000000
+#define BONITO_IDECOPCTRL_DMA_RSTBIT	0x40000000
+
+/* DRAM - sdCfg */
+
+#define BONITO_SDCFG_AROWBITS		0x00000003
+#define BONITO_SDCFG_AROWBITS_SHIFT	0
+#define BONITO_SDCFG_ACOLBITS		0x0000000c
+#define BONITO_SDCFG_ACOLBITS_SHIFT	2
+#define BONITO_SDCFG_ABANKBIT		0x00000010
+#define BONITO_SDCFG_ASIDES		0x00000020
+#define BONITO_SDCFG_AABSENT		0x00000040
+#define BONITO_SDCFG_AWIDTH64		0x00000080
+
+#define BONITO_SDCFG_BROWBITS		0x00000300
+#define BONITO_SDCFG_BROWBITS_SHIFT	8
+#define BONITO_SDCFG_BCOLBITS		0x00000c00
+#define BONITO_SDCFG_BCOLBITS_SHIFT	10
+#define BONITO_SDCFG_BBANKBIT		0x00001000
+#define BONITO_SDCFG_BSIDES		0x00002000
+#define BONITO_SDCFG_BABSENT		0x00004000
+#define BONITO_SDCFG_BWIDTH64		0x00008000
+
+#define BONITO_SDCFG_EXTRDDATA		0x00010000
+#define BONITO_SDCFG_EXTRASCAS		0x00020000
+#define BONITO_SDCFG_EXTPRECH		0x00040000
+#define BONITO_SDCFG_EXTRASWIDTH	0x00180000
+#define BONITO_SDCFG_EXTRASWIDTH_SHIFT	19
+/* Changed by RPF 11-9-00 */
+#define BONITO_SDCFG_DRAMMODESET	0x00200000
+/* --- */
+#define BONITO_SDCFG_DRAMEXTREGS	0x00400000
+#define BONITO_SDCFG_DRAMPARITY 	0x00800000
+/* Added by RPF 11-9-00 */
+#define BONITO_SDCFG_DRAMBURSTLEN 	0x03000000
+#define BONITO_SDCFG_DRAMBURSTLEN_SHIFT	24
+#define BONITO_SDCFG_DRAMMODESET_DONE 	0x80000000
+/* --- */
+
+/* PCI Cache - pciCacheCtrl */
+
+#define BONITO_PCICACHECTRL_CACHECMD	0x00000007
+#define BONITO_PCICACHECTRL_CACHECMD_SHIFT	0
+#define BONITO_PCICACHECTRL_CACHECMDLINE	0x00000018
+#define BONITO_PCICACHECTRL_CACHECMDLINE_SHIFT	3
+#define BONITO_PCICACHECTRL_CMDEXEC	0x00000020
+
+#define BONITO_IODEVCFG_BUFFBIT_CS0	0x00000001
+#define BONITO_IODEVCFG_SPEEDBIT_CS0	0x00000002
+#define BONITO_IODEVCFG_MOREABITS_CS0	0x00000004
+
+#define BONITO_IODEVCFG_BUFFBIT_CS1	0x00000008
+#define BONITO_IODEVCFG_SPEEDBIT_CS1	0x00000010
+#define BONITO_IODEVCFG_MOREABITS_CS1	0x00000020
+
+#define BONITO_IODEVCFG_BUFFBIT_CS2	0x00000040
+#define BONITO_IODEVCFG_SPEEDBIT_CS2	0x00000080
+#define BONITO_IODEVCFG_MOREABITS_CS2	0x00000100
+
+#define BONITO_IODEVCFG_BUFFBIT_CS3	0x00000200
+#define BONITO_IODEVCFG_SPEEDBIT_CS3	0x00000400
+#define BONITO_IODEVCFG_MOREABITS_CS3	0x00000800
+
+#define BONITO_IODEVCFG_BUFFBIT_IDE	0x00001000
+#define BONITO_IODEVCFG_SPEEDBIT_IDE	0x00002000
+#define BONITO_IODEVCFG_WORDSWAPBIT_IDE 0x00004000
+#define BONITO_IODEVCFG_MODEBIT_IDE	0x00008000
+#define BONITO_IODEVCFG_DMAON_IDE	0x001f0000
+#define BONITO_IODEVCFG_DMAON_IDE_SHIFT 16
+#define BONITO_IODEVCFG_DMAOFF_IDE	0x01e00000
+#define BONITO_IODEVCFG_DMAOFF_IDE_SHIFT	21
+#define BONITO_IODEVCFG_EPROMSPLIT	0x02000000
+/* Added by RPF 11-9-00 */
+#define BONITO_IODEVCFG_CPUCLOCKPERIOD	0xfc000000
+#define BONITO_IODEVCFG_CPUCLOCKPERIOD_SHIFT 26
+/* --- */
+
+/* gpio */
+#define BONITO_GPIO_GPIOW		0x000003ff
+#define BONITO_GPIO_GPIOW_SHIFT 	0
+#define BONITO_GPIO_GPIOR		0x01ff0000
+#define BONITO_GPIO_GPIOR_SHIFT 	16
+#define BONITO_GPIO_GPINR		0xfe000000
+#define BONITO_GPIO_GPINR_SHIFT 	25
+#define BONITO_GPIO_IOW(N)		(1<<(BONITO_GPIO_GPIOW_SHIFT+(N)))
+#define BONITO_GPIO_IOR(N)		(1<<(BONITO_GPIO_GPIOR_SHIFT+(N)))
+#define BONITO_GPIO_INR(N)		(1<<(BONITO_GPIO_GPINR_SHIFT+(N)))
+
+/* ICU */
+#define BONITO_ICU_MBOXES		0x0000000f
+#define BONITO_ICU_MBOXES_SHIFT 	0
+#define BONITO_ICU_DMARDY		0x00000010
+#define BONITO_ICU_DMAEMPTY		0x00000020
+#define BONITO_ICU_COPYRDY		0x00000040
+#define BONITO_ICU_COPYEMPTY		0x00000080
+#define BONITO_ICU_COPYERR		0x00000100
+#define BONITO_ICU_PCIIRQ		0x00000200
+#define BONITO_ICU_MASTERERR		0x00000400
+#define BONITO_ICU_SYSTEMERR		0x00000800
+#define BONITO_ICU_DRAMPERR		0x00001000
+#define BONITO_ICU_RETRYERR		0x00002000
+#define BONITO_ICU_GPIOS		0x01ff0000
+#define BONITO_ICU_GPIOS_SHIFT		16
+#define BONITO_ICU_GPINS		0x7e000000
+#define BONITO_ICU_GPINS_SHIFT		25
+#define BONITO_ICU_MBOX(N)		(1<<(BONITO_ICU_MBOXES_SHIFT+(N)))
+#define BONITO_ICU_GPIO(N)		(1<<(BONITO_ICU_GPIOS_SHIFT+(N)))
+#define BONITO_ICU_GPIN(N)		(1<<(BONITO_ICU_GPINS_SHIFT+(N)))
+
+/* pcimap */
+
+#define BONITO_PCIMAP_PCIMAP_LO0	0x0000003f
+#define BONITO_PCIMAP_PCIMAP_LO0_SHIFT	0
+#define BONITO_PCIMAP_PCIMAP_LO1	0x00000fc0
+#define BONITO_PCIMAP_PCIMAP_LO1_SHIFT	6
+#define BONITO_PCIMAP_PCIMAP_LO2	0x0003f000
+#define BONITO_PCIMAP_PCIMAP_LO2_SHIFT	12
+#define BONITO_PCIMAP_PCIMAP_2		0x00040000
+#define BONITO_PCIMAP_WIN(WIN,ADDR)	((((ADDR)>>26) & BONITO_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
+
+#define BONITO_PCIMAP_WINSIZE           (1<<26)
+#define BONITO_PCIMAP_WINOFFSET(ADDR)	((ADDR) & (BONITO_PCIMAP_WINSIZE - 1))
+#define BONITO_PCIMAP_WINBASE(ADDR)	((ADDR) << 26)
+
+/* pcimembaseCfg */
+
+#define BONITO_PCIMEMBASECFG_MASK               0xf0000000
+#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK	0x0000001f
+#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT	0
+#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS	0x000003e0
+#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT	5
+#define BONITO_PCIMEMBASECFG_MEMBASE0_CACHED	0x00000400
+#define BONITO_PCIMEMBASECFG_MEMBASE0_IO	0x00000800
+
+#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK	0x0001f000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK_SHIFT	12
+#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS	0x003e0000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS_SHIFT	17
+#define BONITO_PCIMEMBASECFG_MEMBASE1_CACHED	0x00400000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_IO	0x00800000
+
+#define BONITO_PCIMEMBASECFG_ASHIFT	23
+#define BONITO_PCIMEMBASECFG_AMASK              0x007fffff
+#define BONITO_PCIMEMBASECFGSIZE(WIN,SIZE)	(((~((SIZE)-1))>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)
+#define BONITO_PCIMEMBASECFGBASE(WIN,BASE)	(((BASE)>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS)
+
+#define BONITO_PCIMEMBASECFG_SIZE(WIN,CFG)  (((((~(CFG)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)) << (BONITO_PCIMEMBASECFG_ASHIFT - BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) | BONITO_PCIMEMBASECFG_AMASK)
+
+
+#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG)  ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG)  ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+#define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN,CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+
+#define BONITO_PCITOPHYS(WIN,ADDR,CFG)          ( \
+                                                  (((ADDR) & (~(BONITO_PCIMEMBASECFG_MASK))) & (~(BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG)))) | \
+                                                  (BONITO_PCIMEMBASECFG_ADDRTRANS(WIN,CFG)) \
+                                                )
+
+/* PCICmd */
+
+#define BONITO_PCICMD_MEMEN		0x00000002
+#define BONITO_PCICMD_MSTREN		0x00000004
+
+
+#endif /* _ASM_MIPS_BOARDS_BONITO64_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/mips-boards/generic.h linux/include/asm-mips64/mips-boards/generic.h
--- linux.orig/include/asm-mips64/mips-boards/generic.h	2001-09-09 17:43:01.000000000 +0000
+++ linux/include/asm-mips64/mips-boards/generic.h	2002-07-20 01:08:21.000000000 +0000
@@ -25,14 +25,20 @@
 #ifndef _MIPS_GENERIC_H
 #define _MIPS_GENERIC_H
 
+#include <linux/config.h>
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
+#include <asm/mips-boards/bonito64.h>
 
 /*
  * Display register base.
  */
+#if defined(CONFIG_MIPS_SEAD)
+#define ASCII_DISPLAY_POS_BASE     (KSEG1ADDR(0x1f0005c0))
+#else
 #define ASCII_DISPLAY_WORD_BASE    (KSEG1ADDR(0x1f000410))
 #define ASCII_DISPLAY_POS_BASE     (KSEG1ADDR(0x1f000418))
+#endif
 
 
 /*
@@ -44,8 +50,28 @@
 /*
  * Reset register.
  */
+#if defined(CONFIG_MIPS_SEAD)
+#define SOFTRES_REG       (KSEG1ADDR(0x1e800050))
+#define GORESET           0x4d
+#else
 #define SOFTRES_REG       (KSEG1ADDR(0x1f000500))
 #define GORESET           0x42
+#endif
+
+/*
+ * Revision register.
+ */
+#define MIPS_REVISION_REG                  (KSEG1ADDR(0x1fc00010))
+#define MIPS_REVISION_CORID_QED_RM5261     0
+#define MIPS_REVISION_CORID_CORE_LV        1
+#define MIPS_REVISION_CORID_BONITO64       2
+#define MIPS_REVISION_CORID_CORE_20K       3
+#define MIPS_REVISION_CORID_CORE_FPGA      4
+#define MIPS_REVISION_CORID_CORE_MSC       5
+
+#define MIPS_REVISION_CORID (((*(volatile u32 *)(MIPS_REVISION_REG)) >> 10) & 0x3f)
+
+extern unsigned int mips_revision_corid;
 
 
 /*
@@ -67,4 +93,19 @@
 #define GT_PCI_READ(ofs, data)   \
 	data = *(volatile u32 *)(MIPS_GT_BASE+ofs)
 
+/*
+ * Algorithmics Bonito64 system controller register base.
+ */
+static char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE);
+
+/*
+ * MIPS System controller PCI register base.
+ */
+#define MSC01_PCI_REG_BASE  (KSEG1ADDR(0x1bd00000))
+
+#define MSC_WRITE(reg, data)  \
+	*(volatile u32 *)(reg) = data
+#define MSC_READ(reg, data)   \
+	data = *(volatile u32 *)(reg)
+
 #endif  /* !(_MIPS_GENERIC_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/mips-boards/malta.h linux/include/asm-mips64/mips-boards/malta.h
--- linux.orig/include/asm-mips64/mips-boards/malta.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/mips-boards/malta.h	2002-07-20 01:08:31.000000000 +0000
@@ -29,9 +29,12 @@
 #include <asm/io.h>
 
 /* 
- * Malta I/O ports base address. 
-*/
-#define MALTA_PORT_BASE      (KSEG1ADDR(0x18000000))
+ * Malta I/O ports base address for the Galileo GT64120 and Algorithmics
+ * Bonito system controllers. 
+ */
+#define MALTA_GT_PORT_BASE      (KSEG1ADDR(0x18000000))
+#define MALTA_BONITO_PORT_BASE  (KSEG1ADDR(0x1fd00000))
+#define MALTA_MSC_PORT_BASE     (KSEG1ADDR(0x18000000))
 
 /* 
  * Malta RTC-device indirect register access.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/mips-boards/msc01_pci.h linux/include/asm-mips64/mips-boards/msc01_pci.h
--- linux.orig/include/asm-mips64/mips-boards/msc01_pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/mips-boards/msc01_pci.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,244 @@
+/*
+ * mcs01_pci.h
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ * PCI Register definitions for the MIPS System Controller.
+ */
+#ifndef MSC01_PCI_H
+#define MSC01_PCI_H
+
+/*****************************************************************************
+ * Register offset addresses
+ ****************************************************************************/
+
+#define MSC01_PCI_ID_OFS		0x0000
+#define MSC01_PCI_SC2PMBASL_OFS		0x0208
+#define MSC01_PCI_SC2PMMSKL_OFS		0x0218
+#define MSC01_PCI_SC2PMMAPL_OFS		0x0228
+#define MSC01_PCI_SC2PIOBASL_OFS	0x0248
+#define MSC01_PCI_SC2PIOMSKL_OFS	0x0258
+#define MSC01_PCI_SC2PIOMAPL_OFS	0x0268
+#define MSC01_PCI_P2SCMSKL_OFS		0x0308
+#define MSC01_PCI_P2SCMAPL_OFS		0x0318
+#define MSC01_PCI_INTCFG_OFS		0x0600
+#define MSC01_PCI_INTSTAT_OFS		0x0608
+#define MSC01_PCI_CFGADDR_OFS		0x0610
+#define MSC01_PCI_CFGDATA_OFS		0x0618
+#define MSC01_PCI_IACK_OFS		0x0620
+#define MSC01_PCI_HEAD0_OFS		0x2000  /* DevID, VendorID */
+#define MSC01_PCI_HEAD1_OFS		0x2008  /* Status, Command */
+#define MSC01_PCI_HEAD2_OFS		0x2010  /* Class code, RevID */
+#define MSC01_PCI_HEAD3_OFS		0x2018  /* bist, header, latency */
+#define MSC01_PCI_HEAD4_OFS		0x2020  /* BAR 0 */
+#define MSC01_PCI_HEAD5_OFS		0x2028  /* BAR 1 */
+#define MSC01_PCI_HEAD6_OFS		0x2030  /* BAR 2 */
+#define MSC01_PCI_HEAD7_OFS		0x2038  /* BAR 3 */
+#define MSC01_PCI_HEAD8_OFS		0x2040  /* BAR 4 */
+#define MSC01_PCI_HEAD9_OFS		0x2048  /* BAR 5 */
+#define MSC01_PCI_HEAD10_OFS		0x2050  /* CardBus CIS Ptr */
+#define MSC01_PCI_HEAD11_OFS		0x2058  /* SubSystem ID, -VendorID */
+#define MSC01_PCI_HEAD12_OFS		0x2060  /* ROM BAR */
+#define MSC01_PCI_HEAD13_OFS		0x2068  /* Capabilities ptr */
+#define MSC01_PCI_HEAD14_OFS		0x2070  /* reserved */
+#define MSC01_PCI_HEAD15_OFS		0x2078  /* Maxl, ming, intpin, int */
+#define MSC01_PCI_BAR0_OFS		0x2220
+#define MSC01_PCI_CFG_OFS		0x2380
+#define MSC01_PCI_SWAP_OFS		0x2388
+
+
+/*****************************************************************************
+ * Register encodings
+ ****************************************************************************/
+
+#define MSC01_PCI_ID_ID_SHF		16
+#define MSC01_PCI_ID_ID_MSK		0x00ff0000
+#define MSC01_PCI_ID_ID_HOSTBRIDGE	82
+#define MSC01_PCI_ID_MAR_SHF		8
+#define MSC01_PCI_ID_MAR_MSK		0x0000ff00
+#define MSC01_PCI_ID_MIR_SHF		0
+#define MSC01_PCI_ID_MIR_MSK		0x000000ff
+
+#define MSC01_PCI_SC2PMBASL_BAS_SHF	24
+#define MSC01_PCI_SC2PMBASL_BAS_MSK	0xff000000
+
+#define MSC01_PCI_SC2PMMSKL_MSK_SHF	24
+#define MSC01_PCI_SC2PMMSKL_MSK_MSK	0xff000000
+
+#define MSC01_PCI_SC2PMMAPL_MAP_SHF	24
+#define MSC01_PCI_SC2PMMAPL_MAP_MSK	0xff000000
+
+#define MSC01_PCI_SC2PIOBASL_BAS_SHF	24
+#define MSC01_PCI_SC2PIOBASL_BAS_MSK	0xff000000
+
+#define MSC01_PCI_SC2PIOMSKL_MSK_SHF	24
+#define MSC01_PCI_SC2PIOMSKL_MSK_MSK	0xff000000
+
+#define MSC01_PCI_SC2PIOMAPL_MAP_SHF	24
+#define MSC01_PCI_SC2PIOMAPL_MAP_MSK	0xff000000
+
+#define MSC01_PCI_P2SCMSKL_MSK_SHF	24
+#define MSC01_PCI_P2SCMSKL_MSK_MSK	0xff000000
+
+#define MSC01_PCI_P2SCMAPL_MAP_SHF	24
+#define MSC01_PCI_P2SCMAPL_MAP_MSK	0xff000000
+
+#define MSC01_PCI_INTCFG_RST_SHF        10
+#define MSC01_PCI_INTCFG_RST_MSK        0x00000400
+#define MSC01_PCI_INTCFG_RST_BIT        0x00000400
+#define MSC01_PCI_INTCFG_MWE_SHF        9
+#define MSC01_PCI_INTCFG_MWE_MSK        0x00000200
+#define MSC01_PCI_INTCFG_MWE_BIT        0x00000200
+#define MSC01_PCI_INTCFG_DTO_SHF        8
+#define MSC01_PCI_INTCFG_DTO_MSK        0x00000100
+#define MSC01_PCI_INTCFG_DTO_BIT        0x00000100 
+#define MSC01_PCI_INTCFG_MA_SHF         7
+#define MSC01_PCI_INTCFG_MA_MSK         0x00000080
+#define MSC01_PCI_INTCFG_MA_BIT         0x00000080
+#define MSC01_PCI_INTCFG_TA_SHF         6
+#define MSC01_PCI_INTCFG_TA_MSK         0x00000040
+#define MSC01_PCI_INTCFG_TA_BIT         0x00000040
+#define MSC01_PCI_INTCFG_RTY_SHF        5
+#define MSC01_PCI_INTCFG_RTY_MSK        0x00000020
+#define MSC01_PCI_INTCFG_RTY_BIT        0x00000020
+#define MSC01_PCI_INTCFG_MWP_SHF        4
+#define MSC01_PCI_INTCFG_MWP_MSK        0x00000010
+#define MSC01_PCI_INTCFG_MWP_BIT        0x00000010
+#define MSC01_PCI_INTCFG_MRP_SHF        3
+#define MSC01_PCI_INTCFG_MRP_MSK        0x00000008
+#define MSC01_PCI_INTCFG_MRP_BIT        0x00000008
+#define MSC01_PCI_INTCFG_SWP_SHF        2
+#define MSC01_PCI_INTCFG_SWP_MSK        0x00000004
+#define MSC01_PCI_INTCFG_SWP_BIT        0x00000004
+#define MSC01_PCI_INTCFG_SRP_SHF        1
+#define MSC01_PCI_INTCFG_SRP_MSK        0x00000002
+#define MSC01_PCI_INTCFG_SRP_BIT        0x00000002
+#define MSC01_PCI_INTCFG_SE_SHF         0
+#define MSC01_PCI_INTCFG_SE_MSK         0x00000001
+#define MSC01_PCI_INTCFG_SE_BIT         0x00000001
+
+#define MSC01_PCI_INTSTAT_RST_SHF       10
+#define MSC01_PCI_INTSTAT_RST_MSK       0x00000400
+#define MSC01_PCI_INTSTAT_RST_BIT       0x00000400
+#define MSC01_PCI_INTSTAT_MWE_SHF       9
+#define MSC01_PCI_INTSTAT_MWE_MSK       0x00000200
+#define MSC01_PCI_INTSTAT_MWE_BIT       0x00000200
+#define MSC01_PCI_INTSTAT_DTO_SHF       8
+#define MSC01_PCI_INTSTAT_DTO_MSK       0x00000100
+#define MSC01_PCI_INTSTAT_DTO_BIT       0x00000100 
+#define MSC01_PCI_INTSTAT_MA_SHF        7
+#define MSC01_PCI_INTSTAT_MA_MSK        0x00000080
+#define MSC01_PCI_INTSTAT_MA_BIT        0x00000080
+#define MSC01_PCI_INTSTAT_TA_SHF        6
+#define MSC01_PCI_INTSTAT_TA_MSK        0x00000040
+#define MSC01_PCI_INTSTAT_TA_BIT        0x00000040
+#define MSC01_PCI_INTSTAT_RTY_SHF       5
+#define MSC01_PCI_INTSTAT_RTY_MSK       0x00000020
+#define MSC01_PCI_INTSTAT_RTY_BIT       0x00000020
+#define MSC01_PCI_INTSTAT_MWP_SHF       4
+#define MSC01_PCI_INTSTAT_MWP_MSK       0x00000010
+#define MSC01_PCI_INTSTAT_MWP_BIT       0x00000010
+#define MSC01_PCI_INTSTAT_MRP_SHF       3
+#define MSC01_PCI_INTSTAT_MRP_MSK       0x00000008
+#define MSC01_PCI_INTSTAT_MRP_BIT       0x00000008
+#define MSC01_PCI_INTSTAT_SWP_SHF       2
+#define MSC01_PCI_INTSTAT_SWP_MSK       0x00000004
+#define MSC01_PCI_INTSTAT_SWP_BIT       0x00000004
+#define MSC01_PCI_INTSTAT_SRP_SHF       1
+#define MSC01_PCI_INTSTAT_SRP_MSK       0x00000002
+#define MSC01_PCI_INTSTAT_SRP_BIT       0x00000002
+#define MSC01_PCI_INTSTAT_SE_SHF        0
+#define MSC01_PCI_INTSTAT_SE_MSK        0x00000001
+#define MSC01_PCI_INTSTAT_SE_BIT        0x00000001
+
+#define MSC01_PCI_CFGADDR_BNUM_SHF	16
+#define MSC01_PCI_CFGADDR_BNUM_MSK	0x00ff0000
+#define MSC01_PCI_CFGADDR_DNUM_SHF	11
+#define MSC01_PCI_CFGADDR_DNUM_MSK	0x0000f800
+#define MSC01_PCI_CFGADDR_FNUM_SHF	8
+#define MSC01_PCI_CFGADDR_FNUM_MSK	0x00000700
+#define MSC01_PCI_CFGADDR_RNUM_SHF	2
+#define MSC01_PCI_CFGADDR_RNUM_MSK	0x000000fc
+
+#define MSC01_PCI_CFGDATA_DATA_SHF	0
+#define MSC01_PCI_CFGDATA_DATA_MSK	0xffffffff
+
+/* The defines below are ONLY valid for a MEM bar! */
+#define MSC01_PCI_BAR0_SIZE_SHF	        4
+#define MSC01_PCI_BAR0_SIZE_MSK	        0xfffffff0
+#define MSC01_PCI_BAR0_P_SHF	        3
+#define MSC01_PCI_BAR0_P_MSK	        0x00000008
+#define MSC01_PCI_BAR0_P_BIT	        MSC01_PCI_BAR0_P_MSK
+#define MSC01_PCI_BAR0_D_SHF	        1
+#define MSC01_PCI_BAR0_D_MSK	        0x00000006
+#define MSC01_PCI_BAR0_T_SHF	        0
+#define MSC01_PCI_BAR0_T_MSK	        0x00000001
+#define MSC01_PCI_BAR0_T_BIT	        MSC01_PCI_BAR0_T_MSK
+
+
+#define MSC01_PCI_CFG_RA_SHF	        17
+#define MSC01_PCI_CFG_RA_MSK	        0x00020000
+#define MSC01_PCI_CFG_RA_BIT	        MSC01_PCI_CFG_RA_MSK
+#define MSC01_PCI_CFG_G_SHF	        16
+#define MSC01_PCI_CFG_G_MSK	        0x00010000
+#define MSC01_PCI_CFG_G_BIT	        MSC01_PCI_CFG_G_MSK
+#define MSC01_PCI_CFG_EN_SHF	        15
+#define MSC01_PCI_CFG_EN_MSK	        0x00008000
+#define MSC01_PCI_CFG_EN_BIT	        MSC01_PCI_CFG_EN_MSK
+#define MSC01_PCI_CFG_MAXRTRY_SHF       0
+#define MSC01_PCI_CFG_MAXRTRY_MSK       0x000000ff
+
+#define MSC01_PCI_SWAP_IO_SHF		18
+#define MSC01_PCI_SWAP_IO_MSK		0x000c0000
+#define MSC01_PCI_SWAP_MEM_SHF		16
+#define MSC01_PCI_SWAP_MEM_MSK		0x00030000
+#define MSC01_PCI_SWAP_BAR0_SHF		0
+#define MSC01_PCI_SWAP_BAR0_MSK		0x00000003
+#define MSC01_PCI_SWAP_NOSWAP		0
+#define MSC01_PCI_SWAP_BYTESWAP		1
+
+/*****************************************************************************
+ * Registers absolute addresses
+ ****************************************************************************/
+
+#define MSC01_PCI_ID            (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
+#define MSC01_PCI_SC2PMBASL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
+#define MSC01_PCI_SC2PMMSKL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
+#define MSC01_PCI_SC2PMMAPL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
+#define MSC01_PCI_SC2PIOBASL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
+#define MSC01_PCI_SC2PIOMSKL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
+#define MSC01_PCI_SC2PIOMAPL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
+#define MSC01_PCI_P2SCMSKL      (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
+#define MSC01_PCI_P2SCMAPL      (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
+#define MSC01_PCI_INTCFG        (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
+#define MSC01_PCI_INTSTAT       (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
+#define MSC01_PCI_CFGADDR       (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
+#define MSC01_PCI_CFGDATA       (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
+#define MSC01_PCI_IACK		(MSC01_PCI_REG_BASE + MSC01_PCI_IACK_OFS)
+#define MSC01_PCI_HEAD0		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD0_OFS)
+#define MSC01_PCI_HEAD1		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD1_OFS)
+#define MSC01_PCI_HEAD2		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD2_OFS)
+#define MSC01_PCI_HEAD3		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD3_OFS)
+#define MSC01_PCI_HEAD4		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD4_OFS)
+#define MSC01_PCI_HEAD5		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD5_OFS)
+#define MSC01_PCI_HEAD6		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD6_OFS)
+#define MSC01_PCI_HEAD7		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD7_OFS)
+#define MSC01_PCI_HEAD8		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD8_OFS)
+#define MSC01_PCI_HEAD9		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD9_OFS)
+#define MSC01_PCI_HEAD10	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD10_OFS)
+#define MSC01_PCI_HEAD11	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD12	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD13	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD14	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD15        (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_BAR0		(MSC01_PCI_REG_BASE + MSC01_PCI_BAR0_OFS)
+#define MSC01_PCI_CFG		(MSC01_PCI_REG_BASE + MSC01_PCI_CFG_OFS)
+#define MSC01_PCI_SWAP		(MSC01_PCI_REG_BASE + MSC01_PCI_SWAP_OFS)
+
+#endif
+/*****************************************************************************
+ *  End of msc01_pci.h
+ *****************************************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/mipsregs.h linux/include/asm-mips64/mipsregs.h
--- linux.orig/include/asm-mips64/mipsregs.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/mipsregs.h	2002-07-20 01:08:30.000000000 +0000
@@ -3,13 +3,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994, 1995, 1996, 1997, 1999 by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
  * Modified for further R[236]000 support by Paul M. Antoine, 1996.
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  */
 #ifndef _ASM_MIPSREGS_H
 #define _ASM_MIPSREGS_H
 
+#include <linux/config.h>
 #include <linux/linkage.h>
 
 /*
@@ -30,6 +33,7 @@
 #define CP0_RANDOM $1
 #define CP0_ENTRYLO0 $2
 #define CP0_ENTRYLO1 $3
+#define CP0_CONF $3
 #define CP0_CONTEXT $4
 #define CP0_PAGEMASK $5
 #define CP0_WIRED $6
@@ -49,12 +53,41 @@
 #define CP0_XCONTEXT $20
 #define CP0_FRAMEMASK $21
 #define CP0_DIAGNOSTIC $22
+#define CP0_DEBUG $23
+#define CP0_DEPC $24
 #define CP0_PERFORMANCE $25
 #define CP0_ECC $26
 #define CP0_CACHEERR $27
 #define CP0_TAGLO $28
 #define CP0_TAGHI $29
 #define CP0_ERROREPC $30
+#define CP0_DESAVE $31
+
+/*
+ * R4640/R4650 cp0 register names.  These registers are listed
+ * here only for completeness; without MMU these CPUs are not useable
+ * by Linux.  A future ELKS port might take make Linux run on them
+ * though ...
+ */
+#define CP0_IBASE $0
+#define CP0_IBOUND $1
+#define CP0_DBASE $2
+#define CP0_DBOUND $3
+#define CP0_CALG $17
+#define CP0_IWATCH $18
+#define CP0_DWATCH $19
+
+/* 
+ * Coprocessor 0 Set 1 register names
+ */
+#define CP0_S1_DERRADDR0  $26
+#define CP0_S1_DERRADDR1  $27
+#define CP0_S1_INTCONTROL $20
+
+/*
+ *  TX39 Series
+ */
+#define CP0_TX39_CACHE	$7
 
 /*
  * Coprocessor 1 (FPU) register names
@@ -63,57 +96,96 @@
 #define CP1_STATUS     $31
 
 /*
- * Values for PageMask register
+ * FPU Status Register Values
  */
-#define PM_4K   0x00000000
-#define PM_16K  0x00006000
-#define PM_64K  0x0001e000
-#define PM_256K 0x0007e000
-#define PM_1M   0x001fe000
-#define PM_4M   0x007fe000
-#define PM_16M  0x01ffe000
-
 /*
- * Values used for computation of new tlb entries
+ * Status Register Values
  */
-#define PL_4K   12
-#define PL_16K  14
-#define PL_64K  16
-#define PL_256K 18
-#define PL_1M   20
-#define PL_4M   22
-#define PL_16M  24
+
+#define FPU_CSR_FLUSH   0x01000000      /* flush denormalised results to 0 */
+#define FPU_CSR_COND    0x00800000      /* $fcc0 */
+#define FPU_CSR_COND0   0x00800000      /* $fcc0 */
+#define FPU_CSR_COND1   0x02000000      /* $fcc1 */
+#define FPU_CSR_COND2   0x04000000      /* $fcc2 */
+#define FPU_CSR_COND3   0x08000000      /* $fcc3 */
+#define FPU_CSR_COND4   0x10000000      /* $fcc4 */
+#define FPU_CSR_COND5   0x20000000      /* $fcc5 */
+#define FPU_CSR_COND6   0x40000000      /* $fcc6 */
+#define FPU_CSR_COND7   0x80000000      /* $fcc7 */
+
+/*
+ * X the exception cause indicator
+ * E the exception enable
+ * S the sticky/flag bit
+*/
+#define FPU_CSR_ALL_X 0x0003f000
+#define FPU_CSR_UNI_X   0x00020000
+#define FPU_CSR_INV_X   0x00010000
+#define FPU_CSR_DIV_X   0x00008000
+#define FPU_CSR_OVF_X   0x00004000
+#define FPU_CSR_UDF_X   0x00002000
+#define FPU_CSR_INE_X   0x00001000
+
+#define FPU_CSR_ALL_E   0x00000f80
+#define FPU_CSR_INV_E   0x00000800
+#define FPU_CSR_DIV_E   0x00000400
+#define FPU_CSR_OVF_E   0x00000200
+#define FPU_CSR_UDF_E   0x00000100
+#define FPU_CSR_INE_E   0x00000080
+
+#define FPU_CSR_ALL_S   0x0000007c
+#define FPU_CSR_INV_S   0x00000040
+#define FPU_CSR_DIV_S   0x00000020
+#define FPU_CSR_OVF_S   0x00000010
+#define FPU_CSR_UDF_S   0x00000008
+#define FPU_CSR_INE_S   0x00000004
+
+/* rounding mode */
+#define FPU_CSR_RN      0x0     /* nearest */
+#define FPU_CSR_RZ      0x1     /* towards zero */
+#define FPU_CSR_RU      0x2     /* towards +Infinity */
+#define FPU_CSR_RD      0x3     /* towards -Infinity */
+
 
 /*
- * Macros to access the system control coprocessor
+ * Values for PageMask register
  */
-#define read_32bit_cp0_register(source)                         \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-        "mfc0\t%0,"STR(source)                                  \
-        : "=r" (__res));                                        \
-        __res;})
+#ifdef CONFIG_CPU_VR41XX
 
-#define read_64bit_cp0_register(source)                         \
-({ int __res;                                                   \
-        __asm__ __volatile__(                                   \
-        ".set\tmips3\n\t"                                       \
-        "dmfc0\t%0,"STR(source)"\n\t"                           \
-        ".set\tmips0"                                           \
-        : "=r" (__res));                                        \
-        __res;})
+/* Why doesn't stupidity hurt ... */
 
-#define write_32bit_cp0_register(register,value)                \
-        __asm__ __volatile__(                                   \
-        "mtc0\t%0,"STR(register)                                \
-        : : "r" (value));
+#define PM_1K		0x00000000
+#define PM_4K		0x00001800
+#define PM_16K		0x00007800
+#define PM_64K		0x0001f800
+#define PM_256K		0x0007f800
+
+#else
+
+#define PM_4K		0x00000000
+#define PM_16K		0x00006000
+#define PM_64K		0x0001e000
+#define PM_256K		0x0007e000
+#define PM_1M		0x001fe000
+#define PM_4M		0x007fe000
+#define PM_16M		0x01ffe000
+#define PM_64M		0x07ffe000
+#define PM_256M		0x1fffe000
 
-#define write_64bit_cp0_register(register,value)                \
-        __asm__ __volatile__(                                   \
-        ".set\tmips3\n\t"                                       \
-        "dmtc0\t%0,"STR(register)"\n\t"                         \
-        ".set\tmips0"                                           \
-        : : "r" (value))
+#endif
+
+/*
+ * Values used for computation of new tlb entries
+ */
+#define PL_4K		12
+#define PL_16K		14
+#define PL_64K		16
+#define PL_256K		18
+#define PL_1M		20
+#define PL_4M		22
+#define PL_16M		24
+#define PL_64M		26
+#define PL_256M		28
 
 /*
  * R4x00 interrupt enable / cause bits
@@ -139,31 +211,6 @@
 #define C_IRQ4          (1<<14)
 #define C_IRQ5          (1<<15)
 
-#ifndef _LANGUAGE_ASSEMBLY
-/*
- * Manipulate the status register.
- * Mostly used to access the interrupt bits.
- */
-#define __BUILD_SET_CP0(name,register)                          \
-extern __inline__ unsigned int                                  \
-set_cp0_##name(unsigned int change, unsigned int new)           \
-{                                                               \
-	unsigned int res;                                       \
-                                                                \
-	res = read_32bit_cp0_register(register);                \
-	res &= ~change;                                         \
-	res |= (new & change);                                  \
-	write_32bit_cp0_register(register, res);                \
-                                                                \
-	return res;                                             \
-}
-
-__BUILD_SET_CP0(status,CP0_STATUS)
-__BUILD_SET_CP0(cause,CP0_CAUSE)
-__BUILD_SET_CP0(config,CP0_CONFIG)
-
-#endif /* defined (_LANGUAGE_ASSEMBLY) */
-
 /*
  * Bitfields in the R4xx0 cp0 status register
  */
@@ -181,6 +228,60 @@
 #define ST0_CE			0x00020000
 
 /*
+ * Bitfields in the R[23]000 cp0 status register.
+ */
+#define ST0_IEC                 0x00000001
+#define ST0_KUC			0x00000002
+#define ST0_IEP			0x00000004
+#define ST0_KUP			0x00000008
+#define ST0_IEO			0x00000010
+#define ST0_KUO			0x00000020
+/* bits 6 & 7 are reserved on R[23]000 */
+#define ST0_ISC			0x00010000
+#define ST0_SWC			0x00020000
+#define ST0_CM			0x00080000
+
+/*
+ * Bits specific to the R4640/R4650
+ */
+#define ST0_UM                 (1   <<  4)
+#define ST0_IL                 (1   << 23)
+#define ST0_DL                 (1   << 24)
+
+/*
+ * Bitfields in the TX39 family CP0 Configuration Register 3
+ */
+#define TX39_CONF_ICS_SHIFT	19
+#define TX39_CONF_ICS_MASK	0x00380000
+#define TX39_CONF_ICS_1KB 	0x00000000
+#define TX39_CONF_ICS_2KB 	0x00080000
+#define TX39_CONF_ICS_4KB 	0x00100000
+#define TX39_CONF_ICS_8KB 	0x00180000
+#define TX39_CONF_ICS_16KB 	0x00200000
+
+#define TX39_CONF_DCS_SHIFT	16
+#define TX39_CONF_DCS_MASK	0x00070000
+#define TX39_CONF_DCS_1KB 	0x00000000
+#define TX39_CONF_DCS_2KB 	0x00010000
+#define TX39_CONF_DCS_4KB 	0x00020000
+#define TX39_CONF_DCS_8KB 	0x00030000
+#define TX39_CONF_DCS_16KB 	0x00040000
+
+#define TX39_CONF_CWFON 	0x00004000
+#define TX39_CONF_WBON  	0x00002000
+#define TX39_CONF_RF_SHIFT	10
+#define TX39_CONF_RF_MASK	0x00000c00
+#define TX39_CONF_DOZE		0x00000200
+#define TX39_CONF_HALT		0x00000100
+#define TX39_CONF_LOCK		0x00000080
+#define TX39_CONF_ICE		0x00000020
+#define TX39_CONF_DCE		0x00000010
+#define TX39_CONF_IRSIZE_SHIFT	2
+#define TX39_CONF_IRSIZE_MASK	0x0000000c
+#define TX39_CONF_DRSIZE_SHIFT	0
+#define TX39_CONF_DRSIZE_MASK	0x00000003
+
+/*
  * Status register bits available in all MIPS CPUs.
  */
 #define ST0_IM			0x0000ff00
@@ -200,6 +301,22 @@
 #define  STATUSF_IP6		(1   << 14)
 #define  STATUSB_IP7		15
 #define  STATUSF_IP7		(1   << 15)
+#define  STATUSB_IP8		0
+#define  STATUSF_IP8		(1   << 0)
+#define  STATUSB_IP9		1
+#define  STATUSF_IP9		(1   << 1)
+#define  STATUSB_IP10		2
+#define  STATUSF_IP10		(1   << 2)
+#define  STATUSB_IP11		3
+#define  STATUSF_IP11		(1   << 3)
+#define  STATUSB_IP12		4
+#define  STATUSF_IP12		(1   << 4)
+#define  STATUSB_IP13		5
+#define  STATUSF_IP13		(1   << 5)
+#define  STATUSB_IP14		6
+#define  STATUSF_IP14		(1   << 6)
+#define  STATUSB_IP15		7
+#define  STATUSF_IP15		(1   << 7)
 #define ST0_CH			0x00040000
 #define ST0_SR			0x00100000
 #define ST0_TS			0x00200000
@@ -246,7 +363,7 @@
 #define  CAUSEF_BD		(1   << 31)
 
 /*
- * Bits in the coprocessor 0 config register.
+ * Bits in the coprozessor 0 config register.
  */
 #define CONF_CM_CACHABLE_NO_WA		0
 #define CONF_CM_CACHABLE_WA		1
@@ -260,12 +377,22 @@
 #define CONF_DB				(1 <<  4)
 #define CONF_IB				(1 <<  5)
 #define CONF_SC				(1 << 17)
+#define CONF_AC                         (1 << 23)
+#define CONF_HALT                       (1 << 25)
+
+/*
+ * Bits in the TX49 coprozessor 0 config register.
+ */
+#define TX49_CONF_DC			(1 << 16)
+#define TX49_CONF_IC			(1 << 17)  /* conflict with CONF_SC */
+#define TX49_CONF_HALT			(1 << 18)
+#define TX49_CONF_CWFON			(1 << 27)
 
 /*
  * R10000 performance counter definitions.
  *
  * FIXME: The R10000 performance counter opens a nice way to implement CPU
- *        time accounting with a precision of one cycle.  I don't have
+ *        time accounting with a precission of one cycle.  I don't have
  *        R10000 silicon but just a manual, so ...
  */
 
@@ -317,14 +444,479 @@
 #define CEB_KERNEL	2	/* Count events in kernel mode EXL = ERL = 0 */
 #define CEB_EXL		1	/* Count events with EXL = 1, ERL = 0 */
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
+
 /*
- * Functions to access the performance counter and control registers
+ * Functions to access the r10k performance counter and control registers
  */
-extern asmlinkage unsigned int read_perf_cntr(unsigned int counter);
-extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val);
-extern asmlinkage unsigned int read_perf_cntl(unsigned int counter);
-extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val);
-#endif
+#define read_r10k_perf_cntr(counter)                            \
+({ unsigned int __res;                                          \
+        __asm__ __volatile__(                                   \
+        "mfpc\t%0, "STR(counter)                                \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define write_r10k_perf_cntr(counter,val)                       \
+        __asm__ __volatile__(                                   \
+        "mtpc\t%0, "STR(counter)                                \
+        : : "r" (val));
+
+#define read_r10k_perf_cntl(counter)                            \
+({ unsigned int __res;                                          \
+        __asm__ __volatile__(                                   \
+        "mfps\t%0, "STR(counter)                                \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define write_r10k_perf_cntl(counter,val)                       \
+        __asm__ __volatile__(                                   \
+        "mtps\t%0, "STR(counter)                                \
+        : : "r" (val));
+
+/*
+ * Macros to access the system control coprocessor
+ */
+#define read_32bit_cp0_register(source)                         \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+        "mfc0\t%0,"STR(source)                                  \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define read_64bit_cp0_register(source)                         \
+({ unsigned long __res;                                         \
+        __asm__ __volatile__(                                   \
+        ".set\tmips3\n\t"                                       \
+        "dmfc0\t%0,"STR(source)"\n\t"                           \
+        ".set\tmips0"                                           \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define write_32bit_cp0_register(register,value)                \
+        __asm__ __volatile__(                                   \
+        "mtc0\t%0,"STR(register)                                \
+        : : "r" (value));
+
+#define write_64bit_cp0_register(register,value)                \
+        __asm__ __volatile__(                                   \
+        ".set\tmips3\n\t"                                       \
+        "dmtc0\t%0,"STR(register)"\n\t"                         \
+        ".set\tmips0"                                           \
+        : : "r" (value))
+
+/* 
+ * This should be changed when we get a compiler that support the MIPS32 ISA. 
+ */
+#define read_mips32_cp0_config1()                               \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+	".set\tnoreorder\n\t"                                   \
+	".set\tnoat\n\t"                                        \
+	"#.set\tmips64\n\t"					\
+	"#mfc0\t$1, $16, 1\n\t"					\
+	"#.set\tmips0\n\t"					\
+     	".word\t0x40018001\n\t"                                 \
+	"move\t%0,$1\n\t"                                       \
+	".set\tat\n\t"                                          \
+	".set\treorder"                                         \
+	:"=r" (__res));                                         \
+        __res;})
+
+/*
+ * Macros to access the floating point coprocessor control registers
+ */
+#define read_32bit_cp1_register(source)                         \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+	".set\tpush\n\t"					\
+	".set\treorder\n\t"					\
+        "cfc1\t%0,"STR(source)"\n\t"                            \
+	".set\tpop"						\
+        : "=r" (__res));                                        \
+        __res;})
+
+/* TLB operations. */
+static inline void tlb_probe(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbp\n\t"
+		".set reorder");
+}
+
+static inline void tlb_read(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbr\n\t"
+		".set reorder");
+}
+
+static inline void tlb_write_indexed(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbwi\n\t"
+		".set reorder");
+}
+
+static inline void tlb_write_random(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbwr\n\t"
+		".set reorder");
+}
+
+/* Dealing with various CP0 mmu/cache related registers. */
+
+/* CP0_PAGEMASK register */
+static inline unsigned long get_pagemask(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $5\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_pagemask(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %z0, $5\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */
+static inline unsigned long get_entrylo0(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(	
+		".set noreorder\n\t"
+		"dmfc0 %0, $2\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_entrylo0(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmtc0 %z0, $2\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_entrylo1(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmfc0 %0, $3\n\t"
+		".set reorder" : "=r" (val));
+
+	return val;
+}
+
+static inline void set_entrylo1(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmtc0 %z0, $3\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+/* CP0_ENTRYHI register */
+static inline unsigned long get_entryhi(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmfc0 %0, $10\n\t"
+		".set reorder"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void set_entryhi(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmtc0 %z0, $10\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+/* CP0_INDEX register */
+static inline unsigned int get_index(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $0\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_index(unsigned int val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %z0, $0\n\t"
+		".set reorder\n\t"
+		: : "Jr" (val));
+}
+
+/* CP0_WIRED register */
+static inline unsigned long get_wired(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $6\n\t"
+		".set reorder\n\t"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_wired(unsigned long val)
+{
+	__asm__ __volatile__(
+		"\n\t.set noreorder\n\t"
+		"mtc0 %z0, $6\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_info(void)
+{
+	unsigned long val;
+
+	__asm__(".set push\n\t"
+		".set reorder\n\t"
+		"mfc0 %0, $7\n\t"
+		".set pop"
+		: "=r" (val));
+	return val;
+}
+
+/* CP0_STATUS registers */
+static inline unsigned long get_status(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $12\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_status(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %z0, $12\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+/* CP0_TAGLO and CP0_TAGHI registers */
+static inline unsigned long get_taglo(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $28\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_taglo(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %z0, $28\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_taghi(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mfc0 %0, $29\n\t"
+		".set reorder"
+		: "=r" (val));
+	return val;
+}
+
+static inline void set_taghi(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"mtc0 %z0, $29\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_context(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmfc0 %0, $4\n\t"
+		".set reorder"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void set_context(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmtc0 %z0, $4\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_xcontext(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmfc0 %0, $20\n\t"
+		".set reorder"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void set_xcontext(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"dmtc0 %z0, $20\n\t"
+		".set reorder"
+		: : "Jr" (val));
+}
+
+static inline unsigned long get_errorepc(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"dmfc0 %0, $30\n\t"
+		".set pop"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void set_errorepc(unsigned long val)
+{
+	__asm__ __volatile__(
+		".set push\n\t"
+		".set reorder\n\t"
+		"dmtc0 %z0, $30\n\t"
+		".set pop"
+		: : "Jr" (val));
+}
+
+/*
+ * Manipulate the status register.
+ * Mostly used to access the interrupt bits.
+ */
+#define __BUILD_SET_CP0(name,register)				\
+static inline unsigned int					\
+set_cp0_##name(unsigned int set)				\
+{								\
+	unsigned int res;					\
+								\
+	res = read_32bit_cp0_register(register);		\
+	res |= set;						\
+	write_32bit_cp0_register(register, res);		\
+								\
+	return res;						\
+}								\
+								\
+static inline unsigned int					\
+clear_cp0_##name(unsigned int clear)				\
+{								\
+	unsigned int res;					\
+								\
+	res = read_32bit_cp0_register(register);		\
+	res &= ~clear;						\
+	write_32bit_cp0_register(register, res);		\
+								\
+	return res;						\
+}								\
+								\
+static inline unsigned int					\
+change_cp0_##name(unsigned int change, unsigned int new)	\
+{								\
+	unsigned int res;					\
+								\
+	res = read_32bit_cp0_register(register);		\
+	res &= ~change;						\
+	res |= (new & change);					\
+	if (change)						\
+		write_32bit_cp0_register(register, res);	\
+								\
+	return res;						\
+}
+
+__BUILD_SET_CP0(status,CP0_STATUS)
+__BUILD_SET_CP0(cause,CP0_CAUSE)
+__BUILD_SET_CP0(config,CP0_CONFIG)
+
+#define __enable_fpu()							\
+do {									\
+	set_cp0_status(ST0_CU1);					\
+	asm("nop;nop;nop;nop");		/* max. hazard */		\
+} while (0)
+
+#define __disable_fpu()							\
+do {									\
+	clear_cp0_status(ST0_CU1);					\
+	/* We don't care about the cp0 hazard here  */			\
+} while (0)
+
+#define enable_fpu()							\
+do {									\
+	if (mips_cpu.options & MIPS_CPU_FPU)				\
+		__enable_fpu();						\
+} while (0)
+
+#define disable_fpu()							\
+do {									\
+	if (mips_cpu.options & MIPS_CPU_FPU)				\
+		__disable_fpu();					\
+} while (0)
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_MIPSREGS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/mmu_context.h linux/include/asm-mips64/mmu_context.h
--- linux.orig/include/asm-mips64/mmu_context.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/mmu_context.h	2002-07-20 01:08:25.000000000 +0000
@@ -14,7 +14,7 @@
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <asm/pgalloc.h>
-#include <asm/processor.h>
+#include <asm/pgtable.h>
 
 /*
  * For the fast tlb miss handlers, we currently keep a per cpu array
@@ -27,7 +27,7 @@
 #define TLBMISS_HANDLER_SETUP_PGD(pgd) \
 	pgd_current[smp_processor_id()] = (unsigned long)(pgd)
 #define TLBMISS_HANDLER_SETUP() \
-	set_context((unsigned long) smp_processor_id() << (23 + 3)); \
+	set_context(((long)(&pgd_current[smp_processor_id()])) << 23); \
 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 extern unsigned long pgd_current[];
 
@@ -52,14 +52,15 @@
 #define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
 #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
 
-extern inline void
-get_new_cpu_mmu_context(struct mm_struct *mm, unsigned long cpu)
+static inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
 {
 	unsigned long asid = ASID_CACHE(cpu);
 
 	if (! ((asid += ASID_INC) & ASID_MASK) ) {
-		_flush_tlb_all(); /* start new asid cycle */
-		if (!asid)      /* fix version if needed */
+		flush_icache_all();
+		local_flush_tlb_all();	/* start new asid cycle */
+		if (!asid)		/* fix version if needed */
 			asid = ASID_FIRST_VERSION;
 	}
 	CPU_CONTEXT(cpu, mm) = ASID_CACHE(cpu) = asid;
@@ -69,7 +70,7 @@
  * Initialize the context related info for a new mm_struct
  * instance.
  */
-extern inline int
+static inline int
 init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
 #ifndef CONFIG_SMP
@@ -88,14 +89,14 @@
 	return 0;
 }
 
-extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                              struct task_struct *tsk, unsigned cpu)
 {
 	/* Check if our ASID is of an older version and thus invalid */
 	if ((CPU_CONTEXT(cpu, next) ^ ASID_CACHE(cpu)) & ASID_VERSION_MASK)
-		get_new_cpu_mmu_context(next, cpu);
+		get_new_mmu_context(next, cpu);
 
-	set_entryhi(CPU_CONTEXT(cpu, next) & 0xff);
+	set_entryhi(CPU_CONTEXT(cpu, next));
 	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
 }
 
@@ -103,7 +104,7 @@
  * Destroy context related info for an mm_struct that is about
  * to be put to rest.
  */
-extern inline void destroy_context(struct mm_struct *mm)
+static inline void destroy_context(struct mm_struct *mm)
 {
 #ifdef CONFIG_SMP
 	if (mm->context)
@@ -115,13 +116,13 @@
  * After we have set current->mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
  */
-extern inline void
+static inline void
 activate_mm(struct mm_struct *prev, struct mm_struct *next)
 {
 	/* Unconditionally get a new ASID.  */
-	get_new_cpu_mmu_context(next, smp_processor_id());
+	get_new_mmu_context(next, smp_processor_id());
 
-	set_entryhi(CPU_CONTEXT(smp_processor_id(), next) & 0xff);
+	set_entryhi(CPU_CONTEXT(smp_processor_id(), next));
 	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/page.h linux/include/asm-mips64/page.h
--- linux.orig/include/asm-mips64/page.h	2000-08-09 20:46:02.000000000 +0000
+++ linux/include/asm-mips64/page.h	2002-07-20 01:08:22.000000000 +0000
@@ -18,11 +18,18 @@
 
 #ifdef __KERNEL__
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
 #define PAGE_BUG(page) do {  BUG(); } while (0)
 
+/*
+ * Prototypes for clear_page / copy_page variants with processor dependant
+ * optimizations.
+ */
+void sb1_clear_page(void * page);
+void sb1_copy_page(void * to, void * from);
+
 extern void (*_clear_page)(void * page);
 extern void (*_copy_page)(void * to, void * from);
 
@@ -45,11 +52,25 @@
 #define pgprot_val(x)	((x).pgprot)
 
 #define __pte(x)	((pte_t) { (x) } )
-#define __pme(x)	((pme_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
 #define __pgd(x)	((pgd_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
-#endif /* _LANGUAGE_ASSEMBLY */
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+       		size >>= 1;
+       		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
@@ -57,12 +78,19 @@
 /*
  * This handles the memory map.
  * We handle pages at KSEG0 for kernels with upto 512mb of memory,
- * at XKPHYS for kernels with more than that.
+ * at XKPHYS with a suitable caching mode for kernels with more than that.
  */
-#ifdef CONFIG_SGI_IP22
+#if defined(CONFIG_SGI_IP22) || defined(CONFIG_MIPS_ATLAS) || \
+    defined(CONFIG_MIPS_MALTA)
 #define PAGE_OFFSET	0xffffffff80000000UL
 #endif
-#ifdef CONFIG_SGI_IP27
+#if defined(CONFIG_SGI_IP32)
+#define PAGE_OFFSET	0x9800000000000000UL
+#endif
+#if defined(CONFIG_SGI_IP27)
+#define PAGE_OFFSET	0xa800000000000000UL
+#endif
+#if defined(CONFIG_SIBYTE_SB1250)
 #define PAGE_OFFSET	0xa800000000000000UL
 #endif
 
@@ -73,6 +101,9 @@
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 #endif
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* defined (__KERNEL__) */
 
 #endif /* _ASM_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/pci/bridge.h linux/include/asm-mips64/pci/bridge.h
--- linux.orig/include/asm-mips64/pci/bridge.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/pci/bridge.h	2002-07-20 01:08:31.000000000 +0000
@@ -41,7 +41,7 @@
  *    Bridge address map
  */
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+#ifndef __ASSEMBLY__
 
 /*
  * All accesses to bridge hardware registers must be done
@@ -283,7 +283,7 @@
 } bridge_err_cmdword_t;
 
 #define berr_field	berr_un.berr_st
-#endif	/* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /*
  * The values of these macros can and should be crosschecked
@@ -793,7 +793,7 @@
 #define PCI64_ATTR_RMF_MASK	0x00ff000000000000
 #define PCI64_ATTR_RMF_SHFT	48
 
-#if LANGUAGE_C
+#ifndef __ASSEMBLY__
 /* Address translation entry for mapped pci32 accesses */
 typedef union ate_u {
 	u64	ent;
@@ -809,7 +809,7 @@
 		u64	valid:1;
 	} field;
 } ate_t;
-#endif /* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #define ATE_V		0x01
 #define ATE_CO		0x02
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/pci.h linux/include/asm-mips64/pci.h
--- linux.orig/include/asm-mips64/pci.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-mips64/pci.h	2002-07-20 01:08:25.000000000 +0000
@@ -7,6 +7,8 @@
 #define _ASM_PCI_H
 
 #include <linux/config.h>
+#include <linux/types.h>
+#include <asm/io.h>			/* for virt_to_bus()  */
 
 #ifdef __KERNEL__
 
@@ -23,12 +25,12 @@
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
 
-extern inline void pcibios_set_master(struct pci_dev *dev)
+static inline void pcibios_set_master(struct pci_dev *dev)
 {
 	/* No special bus mastering setup handling */
 }
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -48,6 +50,13 @@
 struct pci_dev;
 
 /*
+ * The PCI address space does equal the physical memory address space.  The
+ * networking and block device layers use this boolean for bounce buffer
+ * decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+/*
  * Allocate and map kernel buffer using consistent mode DMA for a device.
  * hwdev should be valid struct pci_dev pointer for PCI devices,
  * NULL for PCI-like buses (ISA, EISA).
@@ -113,9 +122,9 @@
 					size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	dma_cache_wback_inv((unsigned long)ptr, size);
 #endif
 	return virt_to_bus(ptr);
@@ -133,7 +142,7 @@
 				    size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
 	/* Nothing to do */
 }
@@ -147,6 +156,35 @@
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
 
 /*
+ * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
+ * to pci_map_single, but takes a struct page instead of a virtual address
+ */
+static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
+				      unsigned long offset, size_t size,
+                                      int direction)
+{
+	unsigned long addr;
+
+	if (direction == PCI_DMA_NONE)
+		out_of_line_bug();
+
+	addr = (unsigned long) page_address(page) + offset;
+#ifdef CONFIG_NONCOHERENT_IO
+	dma_cache_wback_inv(addr, size);
+#endif
+
+	return virt_to_bus(addr);
+}
+
+static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
+				  size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		out_of_line_bug();
+	/* Nothing to do */
+}
+
+/*
  * Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
  * above pci_map_single interface.  Here the scatter gather list
@@ -168,14 +206,14 @@
 	int i;
 
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nents; i++, sg++) {
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
 #endif
-		sg->address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(sg->address));
+		sg->dma_address = (char *)(__pa(sg->address));
 	}
 
 	return nents;
@@ -190,7 +228,7 @@
 				int nents, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
 	/* Nothing to do */
 }
@@ -210,8 +248,8 @@
 				       size_t size, int direction)
 {
 	if (direction == PCI_DMA_NONE)
-		BUG();
-#ifndef CONFIG_COHERENT_IO
+		out_of_line_bug();
+#ifdef CONFIG_NONCOHERENT_IO
 	dma_cache_wback_inv((unsigned long)__va(dma_handle - bus_to_baddr[hwdev->bus->number]), size);
 #endif
 }
@@ -227,15 +265,15 @@
 				   struct scatterlist *sg,
 				   int nelems, int direction)
 {
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	int i;
 #endif
 
 	if (direction == PCI_DMA_NONE)
-		BUG();
+		out_of_line_bug();
 
 	/*  Make sure that gcc doesn't leave the empty loop body.  */
-#ifndef CONFIG_COHERENT_IO
+#ifdef CONFIG_NONCOHERENT_IO
 	for (i = 0; i < nelems; i++, sg++)
 		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
 #endif
@@ -255,6 +293,40 @@
 	return 1;
 }
 
+/* This is always fine. */
+/* Well ...  this actually needs more thought ...  */
+#define pci_dac_dma_supported(pci_dev, mask)	(0)
+
+#if 0
+static __inline__ dma64_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+{
+	return ((dma64_addr_t) page_to_bus(page) +
+		(dma64_addr_t) offset);
+}
+
+static __inline__ struct page *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+	unsigned long poff = (dma_addr >> PAGE_SHIFT);
+
+	return mem_map + poff;
+}
+
+static __inline__ unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+	return (dma_addr & ~PAGE_MASK);
+}
+
+static __inline__ void
+pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr,
+                        size_t len, int direction)
+{
+	/* Nothing to do. */
+}
+#endif
+
 /*
  * Return the index of the PCI controller for device.
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/pgalloc.h linux/include/asm-mips64/pgalloc.h
--- linux.orig/include/asm-mips64/pgalloc.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/pgalloc.h	2002-07-20 01:08:30.000000000 +0000
@@ -19,29 +19,30 @@
  *  - flush_tlb_range(mm, start, end) flushes a range of pages
  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
-extern void (*_flush_tlb_all)(void);
-extern void (*_flush_tlb_mm)(struct mm_struct *mm);
-extern void (*_flush_tlb_range)(struct mm_struct *mm, unsigned long start,
+extern void local_flush_tlb_all(void);
+extern void local_flush_tlb_mm(struct mm_struct *mm);
+extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
 			       unsigned long end);
-extern void (*_flush_tlb_page)(struct vm_area_struct *vma, unsigned long page);
+extern void local_flush_tlb_page(struct vm_area_struct *vma,
+                                 unsigned long page);
 
-#ifndef CONFIG_SMP
-
-#define flush_tlb_all()			_flush_tlb_all()
-#define flush_tlb_mm(mm)		_flush_tlb_mm(mm)
-#define flush_tlb_range(mm,vmaddr,end)	_flush_tlb_range(mm, vmaddr, end)
-#define flush_tlb_page(vma,page)	_flush_tlb_page(vma, page)
-
-#else /* CONFIG_SMP */
+#ifdef CONFIG_SMP
 
 extern void flush_tlb_all(void);
 extern void flush_tlb_mm(struct mm_struct *);
 extern void flush_tlb_range(struct mm_struct *, unsigned long, unsigned long);
 extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
 
+#else /* CONFIG_SMP */
+
+#define flush_tlb_all()			local_flush_tlb_all()
+#define flush_tlb_mm(mm)		local_flush_tlb_mm(mm)
+#define flush_tlb_range(mm,vmaddr,end)	local_flush_tlb_range(mm, vmaddr, end)
+#define flush_tlb_page(vma,page)	local_flush_tlb_page(vma, page)
+
 #endif /* CONFIG_SMP */
 
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
                                       unsigned long start, unsigned long end)
 {
 	/* Nothing to do on MIPS.  */
@@ -62,7 +63,7 @@
 
 extern pgd_t *get_pgd_slow(void);
 
-extern inline pgd_t *get_pgd_fast(void)
+static inline pgd_t *get_pgd_fast(void)
 {
 	unsigned long *ret;
 
@@ -77,14 +78,14 @@
 	return (pgd_t *)ret;
 }
 
-extern inline void free_pgd_fast(pgd_t *pgd)
+static inline void free_pgd_fast(pgd_t *pgd)
 {
 	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
 	pgd_quicklist = (unsigned long *) pgd;
 	pgtable_cache_size++;
 }
 
-extern inline void free_pgd_slow(pgd_t *pgd)
+static inline void free_pgd_slow(pgd_t *pgd)
 {
 	free_pages((unsigned long)pgd, 1);
 }
@@ -113,7 +114,7 @@
 
 extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
 
-extern inline pte_t *get_pte_fast(void)
+static inline pte_t *get_pte_fast(void)
 {
 	unsigned long *ret;
 
@@ -125,14 +126,14 @@
 	return (pte_t *)ret;
 }
 
-extern inline void free_pte_fast(pte_t *pte)
+static inline void free_pte_fast(pte_t *pte)
 {
 	*(unsigned long *)pte = (unsigned long) pte_quicklist;
 	pte_quicklist = (unsigned long *) pte;
 	pgtable_cache_size++;
 }
 
-extern inline void free_pte_slow(pte_t *pte)
+static inline void free_pte_slow(pte_t *pte)
 {
 	free_pages((unsigned long)pte, 0);
 }
@@ -161,7 +162,7 @@
 
 extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_preadjusted);
 
-extern inline pmd_t *get_pmd_fast(void)
+static inline pmd_t *get_pmd_fast(void)
 {
 	unsigned long *ret;
 
@@ -175,14 +176,14 @@
 	return (pmd_t *)ret;
 }
 
-extern inline void free_pmd_fast(pmd_t *pmd)
+static inline void free_pmd_fast(pmd_t *pmd)
 {
 	*(unsigned long *)pmd = (unsigned long) pmd_quicklist;
 	pmd_quicklist = (unsigned long *) pmd;
 	pgtable_cache_size++;
 }
 
-extern inline void free_pmd_slow(pmd_t *pmd)
+static inline void free_pmd_slow(pmd_t *pmd)
 {
 	free_pages((unsigned long)pmd, 1);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/pgtable.h linux/include/asm-mips64/pgtable.h
--- linux.orig/include/asm-mips64/pgtable.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/pgtable.h	2002-07-20 01:08:35.000000000 +0000
@@ -9,15 +9,16 @@
 #ifndef _ASM_PGTABLE_H
 #define _ASM_PGTABLE_H
 
+#include <linux/config.h>
 #include <asm/addrspace.h>
 #include <asm/page.h>
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 #include <linux/linkage.h>
-#include <linux/config.h>
 #include <linux/mmzone.h>
 #include <asm/cachectl.h>
+#include <asm/io.h>
 
 /* Cache flushing:
  *
@@ -27,30 +28,30 @@
  *  - flush_cache_range(mm, start, end) flushes a range of pages
  *  - flush_page_to_ram(page) write back kernel page to ram
  */
+extern void (*_flush_cache_all)(void);
+extern void (*___flush_cache_all)(void);
 extern void (*_flush_cache_mm)(struct mm_struct *mm);
 extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
-                                 unsigned long end);
-extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
+	unsigned long end);
+extern void (*_flush_cache_page)(struct vm_area_struct *vma,
+	unsigned long page);
 extern void (*_flush_page_to_ram)(struct page * page);
+extern void (*_flush_icache_range)(unsigned long start, unsigned long end);
+extern void (*_flush_icache_page)(struct vm_area_struct *vma,
+	struct page *page);
+extern void (*_flush_cache_sigtramp)(unsigned long addr);
+extern void (*_flush_icache_all)(void);
 
-#define flush_cache_all()		do { } while(0)
-#define flush_dcache_page(page)		do { } while (0)
+/* These suck ...  */
+extern void (*_flush_cache_l2)(void);
+extern void (*_flush_cache_l1)(void);
 
-#ifndef CONFIG_CPU_R10000
-#define flush_cache_mm(mm)		_flush_cache_mm(mm)
-#define flush_cache_range(mm,start,end)	_flush_cache_range(mm,start,end)
-#define flush_cache_page(vma,page)	_flush_cache_page(vma, page)
-#define flush_page_to_ram(page)		_flush_page_to_ram(page)
 
-#define flush_icache_range(start, end)	_flush_cache_l1()
+#define flush_cache_all()		_flush_cache_all()
+#define __flush_cache_all()		___flush_cache_all()
+#define flush_dcache_page(page)		do { } while (0)
 
-#define flush_icache_page(vma, page)					\
-do {									\
-	unsigned long addr;						\
-	addr = (unsigned long) page_address(page);			\
-	_flush_cache_page(vma, addr);					\
-} while (0)                                                              
-#else /* !CONFIG_CPU_R10000 */
+#ifdef CONFIG_CPU_R10000
 /*
  * Since the r10k handles VCEs in hardware, most of the flush cache
  * routines are not needed. Only the icache on a processor is not
@@ -66,22 +67,44 @@
 #define flush_cache_page(vma,page)	do { } while(0)
 #define flush_page_to_ram(page)		do { } while(0)
 #define flush_icache_range(start, end)	_flush_cache_l1()
+#define flush_icache_user_range(vma, page, addr, len) \
+	flush_icache_page((vma), (page))
 #define flush_icache_page(vma, page)					\
 do {									\
 	if ((vma)->vm_flags & VM_EXEC)					\
-		andes_flush_icache_page(page_address(page));		\
+		andes_flush_icache_page(phys_to_virt(page_to_phys(page))); \
 } while (0)
-#endif /* !CONFIG_CPU_R10000 */
 
-/*
- * The foll cache flushing routines are MIPS specific.
- * flush_cache_l2 is needed only during initialization.
- */
-extern void (*_flush_cache_sigtramp)(unsigned long addr);
-extern void (*_flush_cache_l2)(void);
-extern void (*_flush_cache_l1)(void);
+#else
+
+extern void (*_flush_icache_all)(void);
+extern void (*_flush_icache_range)(unsigned long start, unsigned long end);
+extern void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page);
+
+#define flush_cache_mm(mm)		_flush_cache_mm(mm)
+#define flush_cache_range(mm,start,end)	_flush_cache_range(mm,start,end)
+#define flush_cache_page(vma,page)	_flush_cache_page(vma, page)
+#define flush_page_to_ram(page)		_flush_page_to_ram(page)
+#define flush_icache_range(start, end)	_flush_icache_range(start, end)
+#define flush_icache_user_range(vma, page, addr, len) \
+	flush_icache_page((vma), (page))
+#define flush_icache_page(vma, page)	_flush_icache_page(vma, page)
+#ifdef CONFIG_VTAG_ICACHE
+#define flush_icache_all()		_flush_icache_all()
+#else
+#define flush_icache_all()		do { } while(0)
+#endif
+
+
+#endif /* !CONFIG_CPU_R10000 */
 
 #define flush_cache_sigtramp(addr)	_flush_cache_sigtramp(addr)
+#ifdef CONFIG_VTAG_ICACHE
+#define flush_icache_all()		_flush_icache_all()
+#else
+#define flush_icache_all()		do { } while(0)
+#endif
+
 #define flush_cache_l2()		_flush_cache_l2()
 #define flush_cache_l1()		_flush_cache_l1()
 
@@ -105,7 +128,7 @@
  * vmalloc range translations, which the fault handler looks at.
  */
 
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* !__ASSEMBLY__ */
 
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - 3))
@@ -129,7 +152,7 @@
 #define VMALLOC_START     XKSEG
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
 #define VMALLOC_END       \
-  (VMALLOC_START + ((1 << KPTBL_PAGE_ORDER) * PTRS_PER_PTE * PAGE_SIZE))
+	(VMALLOC_START + ((1 << KPTBL_PAGE_ORDER) * PTRS_PER_PTE * PAGE_SIZE))
 
 /* Note that we shift the lower 32bits of each EntryLo[01] entry
  * 6 bits to the left. That way we can convert the PFN into the
@@ -169,7 +192,7 @@
 #define _CACHE_CACHABLE_CE          (4<<9)  /* R4[04]00 only           */
 #define _CACHE_CACHABLE_COW         (5<<9)  /* R4[04]00 only           */
 #define _CACHE_CACHABLE_CUW         (6<<9)  /* R4[04]00 only           */
-#define _CACHE_CACHABLE_ACCELERATED (7<<9)  /* R10000 only             */
+#define _CACHE_UNCACHED_ACCELERATED (7<<9)  /* R10000 only             */
 #define _CACHE_MASK                 (7<<9)
 
 #define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
@@ -195,11 +218,11 @@
 #define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_READ | \
 			PAGE_CACHABLE_DEFAULT)
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-			PAGE_CACHABLE_DEFAULT)
+			_PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT)
 #define PAGE_USERIO     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
 			_CACHE_UNCACHED)
-#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-			_CACHE_UNCACHED)
+#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
+			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
 
 /*
  * MIPS can't do page protection for execute, and considers that the same like
@@ -224,7 +247,7 @@
 #define __S110	PAGE_SHARED
 #define __S111	PAGE_SHARED
 
-#if !defined (_LANGUAGE_ASSEMBLY)
+#ifndef __ASSEMBLY__
 
 #define pte_ERROR(e) \
 	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
@@ -244,21 +267,6 @@
 #define ZERO_PAGE(vaddr) \
 	(virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
 
-/* number of bits that fit into a memory pointer */
-#define BITS_PER_PTR			(8*sizeof(unsigned long))
-
-/* to align the pointer to a pointer address */
-#define PTR_MASK			(~(sizeof(void*)-1))
-
-/*
- * sizeof(void*) == (1 << SIZEOF_PTR_LOG2)
- */
-#define SIZEOF_PTR_LOG2			3
-
-/* to find an entry in a page-table */
-#define PAGE_PTR(address) \
-((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-
 extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
 extern pte_t empty_bad_page_table[PAGE_SIZE/sizeof(pte_t)];
 extern pmd_t invalid_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
@@ -268,32 +276,32 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-extern inline unsigned long pmd_page(pmd_t pmd)
+static inline unsigned long pmd_page(pmd_t pmd)
 {
 	return pmd_val(pmd);
 }
 
-extern inline unsigned long pgd_page(pgd_t pgd)
+static inline unsigned long pgd_page(pgd_t pgd)
 {
 	return pgd_val(pgd);
 }
 
-extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 {
 	pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK);
 }
 
-extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
 {
 	pgd_val(*pgdp) = (((unsigned long) pmdp) & PAGE_MASK);
 }
 
-extern inline int pte_none(pte_t pte)
+static inline int pte_none(pte_t pte)
 {
 	return !pte_val(pte);
 }
 
-extern inline int pte_present(pte_t pte)
+static inline int pte_present(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_PRESENT;
 }
@@ -303,12 +311,12 @@
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
  */
-extern inline void set_pte(pte_t *ptep, pte_t pteval)
+static inline void set_pte(pte_t *ptep, pte_t pteval)
 {
 	*ptep = pteval;
 }
 
-extern inline void pte_clear(pte_t *ptep)
+static inline void pte_clear(pte_t *ptep)
 {
 	set_pte(ptep, __pte(0));
 }
@@ -323,22 +331,22 @@
 /*
  * Empty pmd entries point to the invalid_pte_table.
  */
-extern inline int pmd_none(pmd_t pmd)
+static inline int pmd_none(pmd_t pmd)
 {
 	return pmd_val(pmd) == (unsigned long) invalid_pte_table;
 }
 
-extern inline int pmd_bad(pmd_t pmd)
+static inline int pmd_bad(pmd_t pmd)
 {
 	return pmd_val(pmd) &~ PAGE_MASK;
 }
 
-extern inline int pmd_present(pmd_t pmd)
+static inline int pmd_present(pmd_t pmd)
 {
 	return pmd_val(pmd) != (unsigned long) invalid_pte_table;
 }
 
-extern inline void pmd_clear(pmd_t *pmdp)
+static inline void pmd_clear(pmd_t *pmdp)
 {
 	pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
 }
@@ -346,31 +354,26 @@
 /*
  * Empty pgd entries point to the invalid_pmd_table.
  */
-extern inline int pgd_none(pgd_t pgd)
+static inline int pgd_none(pgd_t pgd)
 {
 	return pgd_val(pgd) == (unsigned long) invalid_pmd_table;
 }
 
-extern inline int pgd_bad(pgd_t pgd)
+static inline int pgd_bad(pgd_t pgd)
 {
 	return pgd_val(pgd) &~ PAGE_MASK;
 }
 
-extern inline int pgd_present(pgd_t pgd)
+static inline int pgd_present(pgd_t pgd)
 {
 	return pgd_val(pgd) != (unsigned long) invalid_pmd_table;
 }
 
-extern inline void pgd_clear(pgd_t *pgdp)
+static inline void pgd_clear(pgd_t *pgdp)
 {
 	pgd_val(*pgdp) = ((unsigned long) invalid_pmd_table);
 }
 
-/*
- * Permanent address of a page.  On MIPS64 we never have highmem, so this
- * is simple.
- */
-#define page_address(page)	((page)->virtual)
 #ifndef CONFIG_DISCONTIGMEM
 #define pte_page(x)		(mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 #else
@@ -384,51 +387,51 @@
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
-extern inline int pte_read(pte_t pte)
+static inline int pte_read(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_READ;
 }
 
-extern inline int pte_write(pte_t pte)
+static inline int pte_write(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_WRITE;
 }
 
-extern inline int pte_dirty(pte_t pte)
+static inline int pte_dirty(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_MODIFIED;
 }
 
-extern inline int pte_young(pte_t pte)
+static inline int pte_young(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_ACCESSED;
 }
 
-extern inline pte_t pte_wrprotect(pte_t pte)
+static inline pte_t pte_wrprotect(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
 	return pte;
 }
 
-extern inline pte_t pte_rdprotect(pte_t pte)
+static inline pte_t pte_rdprotect(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
 	return pte;
 }
 
-extern inline pte_t pte_mkclean(pte_t pte)
+static inline pte_t pte_mkclean(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
 	return pte;
 }
 
-extern inline pte_t pte_mkold(pte_t pte)
+static inline pte_t pte_mkold(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
 	return pte;
 }
 
-extern inline pte_t pte_mkwrite(pte_t pte)
+static inline pte_t pte_mkwrite(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_WRITE;
 	if (pte_val(pte) & _PAGE_MODIFIED)
@@ -436,7 +439,7 @@
 	return pte;
 }
 
-extern inline pte_t pte_mkread(pte_t pte)
+static inline pte_t pte_mkread(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_READ;
 	if (pte_val(pte) & _PAGE_ACCESSED)
@@ -444,7 +447,7 @@
 	return pte;
 }
 
-extern inline pte_t pte_mkdirty(pte_t pte)
+static inline pte_t pte_mkdirty(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_MODIFIED;
 	if (pte_val(pte) & _PAGE_WRITE)
@@ -452,7 +455,7 @@
 	return pte;
 }
 
-extern inline pte_t pte_mkyoung(pte_t pte)
+static inline pte_t pte_mkyoung(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_ACCESSED;
 	if (pte_val(pte) & _PAGE_READ)
@@ -485,8 +488,8 @@
 #define PAGE_TO_PA(page)	((page - mem_map) << PAGE_SHIFT)
 #else
 #define PAGE_TO_PA(page) \
-		((((page)-(page)->zone->zone_mem_map) << PAGE_SHIFT) \
-		+ ((page)->zone->zone_start_paddr))
+		((((page) - page_zone(page)->zone_mem_map) << PAGE_SHIFT) \
+		  + (page_zone(page)->zone_start_paddr))
 #endif
 #define mk_pte(page, pgprot)						\
 ({									\
@@ -498,12 +501,12 @@
 	__pte;								\
 })
 
-extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
+static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 {
 	return __pte(physpage | pgprot_val(pgprot));
 }
 
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
 	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
 }
@@ -516,20 +519,20 @@
 #define pgd_index(address)	((address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
 
 /* to find an entry in a page-table-directory */
-extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
+static inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
 {
 	return mm->pgd + pgd_index(address);
 }
 
 /* Find an entry in the second-level page table.. */
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
 {
 	return (pmd_t *) pgd_page(*dir) +
 	       ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
 }
 
 /* Find an entry in the third-level page table.. */ 
-extern inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
+static inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
 {
 	return (pte_t *) (pmd_page(*dir)) +
 	       ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
@@ -544,14 +547,15 @@
 extern pgd_t swapper_pg_dir[1024];
 extern void paging_init(void);
 
-extern void (*update_mmu_cache)(struct vm_area_struct *vma,
-				unsigned long address, pte_t pte);
+extern void (*_update_mmu_cache)(struct vm_area_struct *vma,
+	unsigned long address, pte_t pte);
+#define update_mmu_cache(vma, address, pte) _update_mmu_cache(vma, address, pte)
 
 /*
  * Non-present pages:  high 24 bits are offset, next 8 bits type,
  * low 32 bits zero.
  */
-extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
+static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
 { pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; }
 
 #define SWP_TYPE(x)		(((x).val >> 32) & 0xff)
@@ -566,259 +570,19 @@
 #define kern_addr_valid(addr)	(1)
 #endif
 
-/* TLB operations. */
-extern inline void tlb_probe(void)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"tlbp\n\t"
-		".set reorder");
-}
-
-extern inline void tlb_read(void)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"tlbr\n\t"
-		".set reorder");
-}
-
-extern inline void tlb_write_indexed(void)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"tlbwi\n\t"
-		".set reorder");
-}
-
-extern inline void tlb_write_random(void)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"tlbwr\n\t"
-		".set reorder");
-}
-
-/* Dealing with various CP0 mmu/cache related registers. */
-
-/* CP0_PAGEMASK register */
-extern inline unsigned long get_pagemask(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mfc0 %0, $5\n\t"
-		".set reorder"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_pagemask(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mtc0 %z0, $5\n\t"
-		".set reorder"
-		: : "Jr" (val));
-}
-
-/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */
-extern inline unsigned long get_entrylo0(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(	
-		".set noreorder\n\t"
-		"dmfc0 %0, $2\n\t"
-		".set reorder"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_entrylo0(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"dmtc0 %z0, $2\n\t"
-		".set reorder"
-		: : "Jr" (val));
-}
-
-extern inline unsigned long get_entrylo1(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"dmfc0 %0, $3\n\t"
-		".set reorder" : "=r" (val));
-
-	return val;
-}
-
-extern inline void set_entrylo1(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"dmtc0 %z0, $3\n\t"
-		".set reorder"
-		: : "Jr" (val));
-}
-
-/* CP0_ENTRYHI register */
-extern inline unsigned long get_entryhi(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"dmfc0 %0, $10\n\t"
-		".set reorder"
-		: "=r" (val));
-
-	return val;
-}
-
-extern inline void set_entryhi(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"dmtc0 %z0, $10\n\t"
-		".set reorder"
-		: : "Jr" (val));
-}
-
-/* CP0_INDEX register */
-extern inline unsigned int get_index(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mfc0 %0, $0\n\t"
-		".set reorder"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_index(unsigned int val)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mtc0 %z0, $0\n\t"
-		".set reorder\n\t"
-		: : "Jr" (val));
-}
-
-/* CP0_WIRED register */
-extern inline unsigned long get_wired(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mfc0 %0, $6\n\t"
-		".set reorder\n\t"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_wired(unsigned long val)
-{
-	__asm__ __volatile__(
-		"\n\t.set noreorder\n\t"
-		"mtc0 %z0, $6\n\t"
-		".set reorder"
-		: : "Jr" (val));
-}
-
-extern inline unsigned long get_info(void)
-{
-	unsigned long val;
-
-	__asm__(
-		".set push\n\t"
-		".set reorder\n\t"
-		"mfc0 %0, $7\n\t"
-		".set pop"
-		: "=r" (val));
-	return val;
-}
-
-/* CP0_TAGLO and CP0_TAGHI registers */
-extern inline unsigned long get_taglo(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mfc0 %0, $28\n\t"
-		".set reorder"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_taglo(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mtc0 %z0, $28\n\t"
-		".set reorder"
-		: : "Jr" (val));
-}
-
-extern inline unsigned long get_taghi(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mfc0 %0, $29\n\t"
-		".set reorder"
-		: "=r" (val));
-	return val;
-}
-
-extern inline void set_taghi(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"mtc0 %z0, $29\n\t"
-		".set reorder"
-		: : "Jr" (val));
-}
-
-/* CP0_CONTEXT register */
-extern inline unsigned long get_context(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"dmfc0 %0, $4\n\t"
-		".set reorder"
-		: "=r" (val));
-
-	return val;
-}
-
-extern inline void set_context(unsigned long val)
-{
-	__asm__ __volatile__(
-		".set noreorder\n\t"
-		"dmtc0 %z0, $4\n\t"
-		".set reorder"
-		: : "Jr" (val));
-}
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()	do { } while (0)
 
 #include <asm-generic/pgtable.h>
 
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
-
 /*
- * No page table caches to initialise
+ * We provide our own get_unmapped area to cope with the virtual aliasing
+ * constraints placed on us by the cache architecture.
  */
-#define pgtable_cache_init()	do { } while (0)
+#define HAVE_ARCH_UNMAPPED_AREA
+
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_PGTABLE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/posix_types.h linux/include/asm-mips64/posix_types.h
--- linux.orig/include/asm-mips64/posix_types.h	2000-07-10 05:18:15.000000000 +0000
+++ linux/include/asm-mips64/posix_types.h	2002-07-20 01:08:29.000000000 +0000
@@ -26,7 +26,7 @@
 typedef int		__kernel_gid_t;
 typedef unsigned long	__kernel_size_t;
 typedef long		__kernel_ssize_t;
-typedef long		 __kernel_ptrdiff_t;
+typedef long		__kernel_ptrdiff_t;
 typedef long		__kernel_time_t;
 typedef long		__kernel_suseconds_t;
 typedef long		__kernel_clock_t;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/processor.h linux/include/asm-mips64/processor.h
--- linux.orig/include/asm-mips64/processor.h	2001-10-05 19:11:05.000000000 +0000
+++ linux/include/asm-mips64/processor.h	2002-07-20 01:08:37.000000000 +0000
@@ -15,43 +15,27 @@
 
 /*
  * Return current * instruction pointer ("program counter").
- *
- * Two implementations.  The ``la'' version results in shorter code for
- * the kernel which we assume to reside in the 32-bit compat address space.
- * The  ``jal'' version is for use by modules which live in outer space.
- * This is just a single instruction unlike the long dla macro expansion.
  */
-#ifdef MODULE
-#define current_text_addr()						\
-({									\
-	void *_a;							\
-									\
-	__asm__ ("jal\t1f, %0\n\t"					\
-		"1:"							\
-		: "=r" (_a));						\
-									\
-	_a;								\
-})
-#else
 #define current_text_addr()						\
 ({									\
 	void *_a;							\
 									\
-	__asm__ ("dla\t%0, 1f\n\t"					\
-		"1:"							\
-		: "=r" (_a));						\
+	__asm__ ("bal\t1f\t\t\t# current_text_addr\n"			\
+		"1:\tmove\t%0, $31"					\
+		: "=r" (_a)						\
+		:							\
+		: "$31");						\
 									\
 	_a;								\
 })
-#endif
 
-#if !defined (_LANGUAGE_ASSEMBLY)
+#ifndef __ASSEMBLY__
 #include <asm/cachectl.h>
 #include <asm/mipsregs.h>
 #include <asm/reg.h>
 #include <asm/system.h>
 
-#if (defined(CONFIG_SGI_IP27))
+#if defined(CONFIG_SGI_IP27)
 #include <asm/sn/types.h>
 #include <asm/sn/intr_public.h>
 #endif
@@ -71,17 +55,25 @@
 	unsigned char	p_slice;	/* Physical position on node board */
 	hub_intmasks_t	p_intmasks;	/* SN0 per-CPU interrupt masks */
 #endif
+#if 0
+	unsigned long loops_per_sec;
+	unsigned long pgtable_cache_sz;
+	unsigned long ipi_count;
+	unsigned long irq_attempt[NR_IRQS];
+	unsigned long smp_local_irq_count;
+	unsigned long prof_multiplier;
+	unsigned long prof_counter;
+#endif
 } __attribute__((aligned(128)));
 
 /*
  * System setup and hardware flags..
  * XXX: Should go into mips_cpuinfo.
  */
-extern char wait_available;		/* only available on R4[26]00 */
-extern char cyclecounter_available;	/* only available from R4000 upwards. */
-extern char dedicated_iv_available;	/* some embedded MIPS like Nevada */
-extern char vce_available;		/* Supports VCED / VCEI exceptions */
-extern char mips4_available;		/* CPU has MIPS IV ISA or better */
+extern void (*cpu_wait)(void);
+extern void r3081_wait(void);
+extern void r39xx_wait(void);
+extern void r4k_wait(void);
 
 extern unsigned int vced_count, vcei_count;
 extern struct cpuinfo_mips cpu_data[];
@@ -126,7 +118,7 @@
  * is limited to 1TB by the R4000 architecture; R10000 and better can
  * support 16TB.
  */
-#define TASK_SIZE32	   0x80000000UL
+#define TASK_SIZE32	   0x7fff8000UL
 #define TASK_SIZE	0x10000000000UL
 
 /* This decides where the kernel will search for a free chunk of vm
@@ -148,12 +140,18 @@
 };
 
 /*
- * FIXME: no fpu emulator yet (but who cares anyway?)
+ * It would be nice to add some more fields for emulator statistics, but there
+ * are a number of fixed offsets in offset.h and elsewhere that would have to
+ * be recalculated by hand.  So the additional information will be private to
+ * the FPU emulator for now.  See asm-mips/fpu_emulator.h.
  */
+typedef u64 fpureg_t;
 struct mips_fpu_soft_struct {
-	long	dummy;
+	fpureg_t	regs[NUM_FPU_REGS];
+	unsigned int	sr;
 };
 
+
 union mips_fpu_union {
         struct mips_fpu_hard_struct hard;
         struct mips_fpu_soft_struct soft;
@@ -196,7 +194,7 @@
 	unsigned long irix_oldctx;
 };
 
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* !__ASSEMBLY__ */
 
 #define INIT_THREAD  { \
         /* \
@@ -226,7 +224,7 @@
 
 #define KERNEL_STACK_SIZE 0x4000
 
-#if !defined (_LANGUAGE_ASSEMBLY)
+#ifndef __ASSEMBLY__
 
 /* Free all resources held by a thread. */
 #define release_thread(thread) do { } while(0)
@@ -240,7 +238,7 @@
 /*
  * Return saved PC of a blocked thread.
  */
-extern inline unsigned long thread_saved_pc(struct thread_struct *t)
+static inline unsigned long thread_saved_pc(struct thread_struct *t)
 {
 	extern void ret_from_sys_call(void);
 
@@ -292,7 +290,7 @@
 
 #define cpu_relax()	do { } while (0)
 
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* !__ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/ptrace.h linux/include/asm-mips64/ptrace.h
--- linux.orig/include/asm-mips64/ptrace.h	2000-11-29 05:42:04.000000000 +0000
+++ linux/include/asm-mips64/ptrace.h	2002-07-20 01:08:33.000000000 +0000
@@ -9,8 +9,6 @@
 #ifndef _ASM_PTRACE_H
 #define _ASM_PTRACE_H
 
-#include <linux/types.h>
-
 /* 0 - 31 are integer registers, 32 - 63 are fp registers.  */
 #define FPR_BASE	32
 #define PC		64
@@ -21,7 +19,7 @@
 #define FPC_CSR		69
 #define FPC_EIR		70
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 #define abi64_no_regargs						\
 	unsigned long __dummy0,						\
@@ -54,7 +52,7 @@
 	unsigned long cp0_cause;
 };
 
-#endif /* !(_LANGUAGE_ASSEMBLY__) */
+#endif /* !__ASSEMBLY__ */
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
 /* #define PTRACE_GETREGS		12 */
@@ -69,19 +67,16 @@
 /* options set using PTRACE_SETOPTIONS */
 #define PTRACE_O_TRACESYSGOOD	0x00000001
 
-#ifdef _LANGUAGE_ASSEMBLY
+#ifdef __ASSEMBLY__
 #include <asm/offset.h>
-#endif /* (_LANGUAGE_ASSEMBLY__) */
+#endif /* !__ASSEMBLY__ */
 
 #ifdef __KERNEL__
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 #define instruction_pointer(regs) ((regs)->cp0_epc)
 
-extern void (*_show_regs)(struct pt_regs *);
-#define show_regs(regs)	_show_regs(regs)
-
-#endif /* !(_LANGUAGE_ASSEMBLY__) */
+#endif /* !__ASSEMBLY__ */
 
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/r10kcache.h linux/include/asm-mips64/r10kcache.h
--- linux.orig/include/asm-mips64/r10kcache.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/r10kcache.h	2002-07-20 01:08:31.000000000 +0000
@@ -40,7 +40,7 @@
 	__res;								\
 })
 
-extern inline void flush_icache_line_indexed(unsigned long addr)
+static inline void flush_icache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -50,7 +50,7 @@
 		: "r" (addr), "i" (Index_Invalidate_I));
 }
 
-extern inline void flush_dcache_line_indexed(unsigned long addr)
+static inline void flush_dcache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -60,7 +60,7 @@
 		: "r" (addr), "i" (Index_Writeback_Inv_D));
 }
 
-extern inline void flush_scache_line_indexed(unsigned long addr)
+static inline void flush_scache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -70,7 +70,7 @@
 		: "r" (addr), "i" (Index_Writeback_Inv_S));
 }
 
-extern inline void flush_icache_line(unsigned long addr)
+static inline void flush_icache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -80,7 +80,7 @@
 		: "r" (addr), "i" (Hit_Invalidate_I));
 }
 
-extern inline void flush_dcache_line(unsigned long addr)
+static inline void flush_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -90,7 +90,7 @@
 		: "r" (addr), "i" (Hit_Writeback_Inv_D));
 }
 
-extern inline void invalidate_dcache_line(unsigned long addr)
+static inline void invalidate_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -100,7 +100,7 @@
 		: "r" (addr), "i" (Hit_Invalidate_D));
 }
 
-extern inline void invalidate_scache_line(unsigned long addr)
+static inline void invalidate_scache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -110,7 +110,7 @@
 		: "r" (addr), "i" (Hit_Invalidate_S));
 }
 
-extern inline void flush_scache_line(unsigned long addr)
+static inline void flush_scache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -123,7 +123,7 @@
 /*
  * The next two are for badland addresses like signal trampolines.
  */
-extern inline void protected_flush_icache_line(unsigned long addr)
+static inline void protected_flush_icache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -136,7 +136,7 @@
 		: "r" (addr), "i" (Hit_Invalidate_I));
 }
 
-extern inline void protected_writeback_dcache_line(unsigned long addr)
+static inline void protected_writeback_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -189,7 +189,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_dcache32(void)
+static inline void blast_dcache32(void)
 {
 	unsigned long way0 = KSEG0;
 	unsigned long way1 = way0 ^ 1;
@@ -203,7 +203,7 @@
 	}
 }
 
-extern inline void blast_dcache32_page(unsigned long page)
+static inline void blast_dcache32_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -214,7 +214,7 @@
 	}
 }
 
-extern inline void blast_dcache32_page_indexed(unsigned long page)
+static inline void blast_dcache32_page_indexed(unsigned long page)
 {
 	unsigned long way0 = page;
 	unsigned long way1 = page ^ 1;
@@ -268,7 +268,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_icache64(void)
+static inline void blast_icache64(void)
 {
 	unsigned long way0 = KSEG0;
 	unsigned long way1 = way0 ^ 1;
@@ -282,7 +282,7 @@
 	}
 }
 
-extern inline void blast_icache64_page(unsigned long page)
+static inline void blast_icache64_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -293,7 +293,7 @@
 	}
 }
 
-extern inline void blast_icache64_page_indexed(unsigned long page)
+static inline void blast_icache64_page_indexed(unsigned long page)
 {
 	unsigned long way0 = page;
 	unsigned long way1 = page ^ 1;
@@ -307,7 +307,7 @@
 	}
 }
 
-extern inline void blast_scache64(void)
+static inline void blast_scache64(void)
 {
 	unsigned long way0 = KSEG0;
 	unsigned long way1 = way0 ^ 1;
@@ -321,7 +321,7 @@
 	}
 }
 
-extern inline void blast_scache64_page(unsigned long page)
+static inline void blast_scache64_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -332,7 +332,7 @@
 	}
 }
 
-extern inline void blast_scache64_page_indexed(unsigned long page)
+static inline void blast_scache64_page_indexed(unsigned long page)
 {
 	unsigned long way0 = page;
 	unsigned long way1 = page ^ 1;
@@ -386,7 +386,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_scache128(void)
+static inline void blast_scache128(void)
 {
 	unsigned long way0 = KSEG0;
 	unsigned long way1 = way0 ^ 1;
@@ -400,12 +400,12 @@
 	}
 }
 
-extern inline void blast_scache128_page(unsigned long page)
+static inline void blast_scache128_page(unsigned long page)
 {
 	cache128_unroll32(page, Hit_Writeback_Inv_S);
 }
 
-extern inline void blast_scache128_page_indexed(unsigned long page)
+static inline void blast_scache128_page_indexed(unsigned long page)
 {
 	cache128_unroll32(page    , Index_Writeback_Inv_S);
 	cache128_unroll32(page ^ 1, Index_Writeback_Inv_S);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/r4kcache.h linux/include/asm-mips64/r4kcache.h
--- linux.orig/include/asm-mips64/r4kcache.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/r4kcache.h	2002-07-20 01:08:38.000000000 +0000
@@ -15,7 +15,7 @@
 #include <asm/asm.h>
 #include <asm/r4kcacheops.h>
 
-extern inline void flush_icache_line_indexed(unsigned long addr)
+static inline void flush_icache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -25,7 +25,7 @@
 		: "r" (addr), "i" (Index_Invalidate_I));
 }
 
-extern inline void flush_dcache_line_indexed(unsigned long addr)
+static inline void flush_dcache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -35,7 +35,7 @@
 		: "r" (addr), "i" (Index_Writeback_Inv_D));
 }
 
-extern inline void flush_scache_line_indexed(unsigned long addr)
+static inline void flush_scache_line_indexed(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -45,7 +45,7 @@
 		: "r" (addr), "i" (Index_Writeback_Inv_SD));
 }
 
-extern inline void flush_icache_line(unsigned long addr)
+static inline void flush_icache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -55,7 +55,7 @@
 		: "r" (addr), "i" (Hit_Invalidate_I));
 }
 
-extern inline void flush_dcache_line(unsigned long addr)
+static inline void flush_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -65,7 +65,7 @@
 		: "r" (addr), "i" (Hit_Writeback_Inv_D));
 }
 
-extern inline void invalidate_dcache_line(unsigned long addr)
+static inline void invalidate_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -75,7 +75,7 @@
 		: "r" (addr), "i" (Hit_Invalidate_D));
 }
 
-extern inline void invalidate_scache_line(unsigned long addr)
+static inline void invalidate_scache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -85,7 +85,7 @@
 		: "r" (addr), "i" (Hit_Invalidate_SD));
 }
 
-extern inline void flush_scache_line(unsigned long addr)
+static inline void flush_scache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -98,7 +98,7 @@
 /*
  * The next two are for badland addresses like signal trampolines.
  */
-extern inline void protected_flush_icache_line(unsigned long addr)
+static inline void protected_flush_icache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -111,7 +111,7 @@
 		: "r" (addr), "i" (Hit_Invalidate_I));
 }
 
-extern inline void protected_writeback_dcache_line(unsigned long addr)
+static inline void protected_writeback_dcache_line(unsigned long addr)
 {
 	__asm__ __volatile__(
 		".set noreorder\n\t"
@@ -148,7 +148,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_dcache16(void)
+static inline void blast_dcache16(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + dcache_size);
@@ -159,7 +159,7 @@
 	}
 }
 
-extern inline void blast_dcache16_page(unsigned long page)
+static inline void blast_dcache16_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -170,7 +170,7 @@
 	}
 }
 
-extern inline void blast_dcache16_page_indexed(unsigned long page)
+static inline void blast_dcache16_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -181,7 +181,7 @@
 	}
 }
 
-extern inline void blast_icache16(void)
+static inline void blast_icache16(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + icache_size);
@@ -192,7 +192,7 @@
 	}
 }
 
-extern inline void blast_icache16_page(unsigned long page)
+static inline void blast_icache16_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -203,7 +203,7 @@
 	}
 }
 
-extern inline void blast_icache16_page_indexed(unsigned long page)
+static inline void blast_icache16_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -214,7 +214,7 @@
 	}
 }
 
-extern inline void blast_scache16(void)
+static inline void blast_scache16(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -225,7 +225,7 @@
 	}
 }
 
-extern inline void blast_scache16_page(unsigned long page)
+static inline void blast_scache16_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -236,7 +236,7 @@
 	}
 }
 
-extern inline void blast_scache16_page_indexed(unsigned long page)
+static inline void blast_scache16_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -271,7 +271,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_dcache32(void)
+static inline void blast_dcache32(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + dcache_size);
@@ -294,7 +294,7 @@
  * (Revision 2.0 device errata from IDT available on http://www.idt.com/
  * in .pdf format.)
  */
-extern inline void blast_dcache32_page(unsigned long page)
+static inline void blast_dcache32_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -311,7 +311,7 @@
 	}
 }
 
-extern inline void blast_dcache32_page_indexed(unsigned long page)
+static inline void blast_dcache32_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -322,7 +322,7 @@
 	}
 }
 
-extern inline void blast_icache32(void)
+static inline void blast_icache32(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = (start + icache_size);
@@ -333,7 +333,7 @@
 	}
 }
 
-extern inline void blast_icache32_page(unsigned long page)
+static inline void blast_icache32_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -344,7 +344,7 @@
 	}
 }
 
-extern inline void blast_icache32_page_indexed(unsigned long page)
+static inline void blast_icache32_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = (start + PAGE_SIZE);
@@ -355,7 +355,7 @@
 	}
 }
 
-extern inline void blast_scache32(void)
+static inline void blast_scache32(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -366,7 +366,7 @@
 	}
 }
 
-extern inline void blast_scache32_page(unsigned long page)
+static inline void blast_scache32_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -377,7 +377,7 @@
 	}
 }
 
-extern inline void blast_scache32_page_indexed(unsigned long page)
+static inline void blast_scache32_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -412,7 +412,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_scache64(void)
+static inline void blast_scache64(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -423,7 +423,7 @@
 	}
 }
 
-extern inline void blast_scache64_page(unsigned long page)
+static inline void blast_scache64_page(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -434,7 +434,7 @@
 	}
 }
 
-extern inline void blast_scache64_page_indexed(unsigned long page)
+static inline void blast_scache64_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
 	unsigned long end = page + PAGE_SIZE;
@@ -469,7 +469,7 @@
 		: "r" (base),					\
 		  "i" (op));
 
-extern inline void blast_scache128(void)
+static inline void blast_scache128(void)
 {
 	unsigned long start = KSEG0;
 	unsigned long end = KSEG0 + scache_size;
@@ -480,12 +480,12 @@
 	}
 }
 
-extern inline void blast_scache128_page(unsigned long page)
+static inline void blast_scache128_page(unsigned long page)
 {
 	cache128_unroll32(page,Hit_Writeback_Inv_SD);
 }
 
-extern inline void blast_scache128_page_indexed(unsigned long page)
+static inline void blast_scache128_page_indexed(unsigned long page)
 {
 	cache128_unroll32(page,Index_Writeback_Inv_SD);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/reboot.h linux/include/asm-mips64/reboot.h
--- linux.orig/include/asm-mips64/reboot.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/reboot.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,16 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1999, 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_REBOOT_H
+#define _ASM_REBOOT_H
+
+extern void (*_machine_restart)(char *command);
+extern void (*_machine_halt)(void);
+extern void (*_machine_power_off)(void);
+
+#endif /* _ASM_REBOOT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/scatterlist.h linux/include/asm-mips64/scatterlist.h
--- linux.orig/include/asm-mips64/scatterlist.h	2001-10-12 22:35:54.000000000 +0000
+++ linux/include/asm-mips64/scatterlist.h	2002-07-20 01:08:31.000000000 +0000
@@ -2,17 +2,18 @@
 #define __ASM_MIPS64_SCATTERLIST_H
 
 struct scatterlist {
-    char *  address;    /* Location data is to be transferred to */
-    unsigned int length;
-    
-    __u32 dvma_address;
+	char *  address;	/* Location data is to be transferred to */
+	struct page *page;
+	unsigned int length;
+
+	__u32 dma_address;
 };
 
 struct mmu_sglist {
         char *addr;
         char *__dont_touch;
         unsigned int len;
-        __u32 dvma_addr;
+        __u32 dma_addr;
 };
 
 #define ISA_DMA_THRESHOLD (0x00ffffffUL)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/semaphore.h linux/include/asm-mips64/semaphore.h
--- linux.orig/include/asm-mips64/semaphore.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/semaphore.h	2002-07-20 01:08:37.000000000 +0000
@@ -89,6 +89,10 @@
 		__down(sem);
 }
 
+/*
+ * Interruptible try to acquire a semaphore.  If we obtained
+ * it, return zero.  If we were interrupted, returns -EINTR
+ */
 static inline int down_interruptible(struct semaphore * sem)
 {
 	int ret = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/serial.h linux/include/asm-mips64/serial.h
--- linux.orig/include/asm-mips64/serial.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/serial.h	2002-07-20 01:08:32.000000000 +0000
@@ -9,6 +9,8 @@
 #ifndef _ASM_SERIAL_H
 #define _ASM_SERIAL_H
 
+#include <linux/config.h>
+
 /*
  * This assumes you have a 1.8432 MHz clock for your UART.
  *
@@ -18,6 +20,8 @@
  */
 #define BASE_BAUD (1843200 / 16)
 
+#ifdef CONFIG_SGI_IP27
+
 /*
  * Note about serial ports and consoles:
  * For console output, everyone uses the IOC3 UARTA (offset 0x178)
@@ -44,10 +48,54 @@
  *
  * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
  * (IOC3_BAUD = (22000000 / (3*16)))
+ *
+ * At the moment this is only a skeleton definition as we register all serials
+ * at runtime.
  */
 
-#define RS_TABLE_SIZE	64
+#define IP27_SERIAL_PORT_DEFNS
+#else
+#define IP27_SERIAL_PORT_DEFNS
+#endif /* CONFIG_SGI_IP27 */
 
-#define SERIAL_PORT_DFNS
+#ifdef CONFIG_SGI_IP32
+
+#include <asm/ip32/ip32_ints.h>
+
+/*
+ * The IP32 (SGI O2) has standard serial ports (UART 16550A) mapped in memory
+ */
+
+/* Standard COM flags (except for COM4, because of the 8514 problem) */
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
+#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+#else
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF/* | ASYNC_SKIP_TEST*/)
+#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+#endif
+
+#define IP32_SERIAL_PORT_DEFNS				\
+        { baud_base: BASE_BAUD,				\
+	  irq: MACEISA_SERIAL1_IRQ,			\
+          flags: STD_COM_FLAGS,				\
+          iomem_base: (u8*)MACE_BASE+MACEISA_SER1_BASE,	\
+          iomem_reg_shift: 8,				\
+          io_type: SERIAL_IO_MEM},                      \
+        { baud_base: BASE_BAUD,				\
+	  irq: MACEISA_SERIAL2_IRQ,			\
+          flags: STD_COM_FLAGS,				\
+          iomem_base: (u8*)MACE_BASE+MACEISA_SER2_BASE,	\
+          iomem_reg_shift: 8,				\
+          io_type: SERIAL_IO_MEM},                      
+#else
+#define IP32_SERIAL_PORT_DEFNS
+#endif /* CONFIG_SGI_IP31 */
+
+#define SERIAL_PORT_DFNS				\
+	IP27_SERIAL_PORT_DEFNS				\
+	IP32_SERIAL_PORT_DEFNS
+
+#define RS_TABLE_SIZE	64
 
 #endif /* _ASM_SERIAL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sgi/sgihpc.h linux/include/asm-mips64/sgi/sgihpc.h
--- linux.orig/include/asm-mips64/sgi/sgihpc.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sgi/sgihpc.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,8 +1,4 @@
 /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
  * sgihpc.h: Various HPC I/O controller defines.  The HPC is basically
  *           the approximate functional equivalent of the Sun SYSIO
  *           on SGI INDY machines.
@@ -10,34 +6,35 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org)
  */
-#ifndef _ASM_SGI_SGIHPC_H
-#define _ASM_SGI_SGIHPC_H
+#ifndef __ASM_SGI_SGIHPC_H
+#define __ASM_SGI_SGIHPC_H
 
+#include <linux/types.h>
 #include <asm/page.h>
 
-extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */
-extern int sgi_guiness;  /* GUINESS or FULLHOUSE machine. */
-extern int sgi_boardid;  /* Board revision. */
+extern int sgi_has_ioc2;	/* to know if we have older ioc1 or ioc2. */
+extern int sgi_guiness;		/* GUINESS or FULLHOUSE machine. */
+extern int sgi_boardid;		/* Board revision. */
 
 /* An HPC dma descriptor. */
 struct hpc_dma_desc {
-	int pbuf;		 /* physical address of data buffer */
-	int cntinfo;   		 /* counter and info bits */
-#define HPCDMA_EOX    0x80000000 /* last desc in chain for tx */
-#define HPCDMA_EOR    0x80000000 /* last desc in chain for rx */
-#define HPCDMA_EOXP   0x40000000 /* end of packet for tx */
-#define HPCDMA_EORP   0x40000000 /* end of packet for rx */
-#define HPCDMA_XIE    0x20000000 /* irq generated when at end of this desc */
-#define HPCDMA_XIU    0x01000000 /* Tx buffer in use by CPU. */
-#define HPCDMA_EIPC   0x00ff0000 /* SEEQ ethernet special xternal bytecount */
-#define HPCDMA_ETXD   0x00008000 /* set to one by HPC when packet tx'd */
-#define HPCDMA_OWN    0x00004000 /* Denotes ring buffer ownership on rx */
-#define HPCDMA_BCNT   0x00003fff /* size in bytes of this dma buffer */
+	u32 pbuf;	/* physical address of data buffer */
+	u32 cntinfo;	/* counter and info bits */
+#define HPCDMA_EOX	0x80000000 /* last desc in chain for tx */
+#define HPCDMA_EOR	0x80000000 /* last desc in chain for rx */
+#define HPCDMA_EOXP	0x40000000 /* end of packet for tx */
+#define HPCDMA_EORP	0x40000000 /* end of packet for rx */
+#define HPCDMA_XIE	0x20000000 /* irq generated when at end of this desc */
+#define HPCDMA_XIU	0x01000000 /* Tx buffer in use by CPU. */
+#define HPCDMA_EIPC	0x00ff0000 /* SEEQ ethernet special xternal bytecount */
+#define HPCDMA_ETXD	0x00008000 /* set to one by HPC when packet tx'd */
+#define HPCDMA_OWN	0x00004000 /* Denotes ring buffer ownership on rx */
+#define HPCDMA_BCNT	0x00003fff /* size in bytes of this dma buffer */
 
-	int pnext;		 /* paddr of next hpc_dma_desc if any */
+	u32 pnext;	/* paddr of next hpc_dma_desc if any */
 };
 
-typedef volatile unsigned int hpcreg;
+typedef volatile u32 hpcreg;
 
 /* HPC1 stuff. */
 
@@ -45,29 +42,35 @@
 
 /* The set of regs for each HPC3 pbus dma channel. */
 struct hpc3_pbus_dmacregs {
-	hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */
-	hpcreg pbdma_dptr; /* pbus dma channel desc ptr */
+	hpcreg pbdma_bptr;	/* pbus dma channel buffer ptr */
+	hpcreg pbdma_dptr;	/* pbus dma channel desc ptr */
 	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg pbdma_ctrl; /* pbus dma channel control reg */
-#define HPC3_PDMACTRL_SEL  0x00000002 /* little endian transfer */
-#define HPC3_PDMACTRL_RCV  0x00000004 /* direction is receive */
-#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */
-#define HPC3_PDMACTRL_ACT  0x00000010 /* start dma transfer */
-#define HPC3_PDMACTRL_LD   0x00000020 /* load enable for ACT */
-#define HPC3_PDMACTRL_RT   0x00000040 /* Use realtime GIO bus servicing */
-#define HPC3_PDMACTRL_HW   0x0000ff00 /* DMA High-water mark */
-#define HPC3_PDMACTRL_FB   0x003f0000 /* Ptr to beginning of fifo */
-#define HPC3_PDMACTRL_FE   0x3f000000 /* Ptr to end of fifo */
+	hpcreg pbdma_ctrl;	/* pbus dma channel control register has 
+				 * copletely different meaning for read 
+				 * compared with write */
+	/* read */
+#define HPC3_PDMACTRL_INT	0x00000001 /* interrupt (cleared after read) */
+#define HPC3_PDMACTRL_ISACT	0x00000002 /* channel active */
+	/* write */
+#define HPC3_PDMACTRL_SEL	0x00000002 /* little endian transfer */
+#define HPC3_PDMACTRL_RCV	0x00000004 /* direction is receive */
+#define HPC3_PDMACTRL_FLSH	0x00000008 /* enable flush for receive DMA */
+#define HPC3_PDMACTRL_ACT	0x00000010 /* start dma transfer */
+#define HPC3_PDMACTRL_LD	0x00000020 /* load enable for ACT */
+#define HPC3_PDMACTRL_RT	0x00000040 /* Use realtime GIO bus servicing */
+#define HPC3_PDMACTRL_HW	0x0000ff00 /* DMA High-water mark */
+#define HPC3_PDMACTRL_FB	0x003f0000 /* Ptr to beginning of fifo */
+#define HPC3_PDMACTRL_FE	0x3f000000 /* Ptr to end of fifo */
 
 	char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */
 };
 
 /* The HPC3 scsi registers, this does not include external ones. */
 struct hpc3_scsiregs {
-	hpcreg cbptr;   /* current dma buffer ptr, diagnostic use only */
-	hpcreg ndptr;   /* next dma descriptor ptr */
+	hpcreg cbptr;	/* current dma buffer ptr, diagnostic use only */
+	hpcreg ndptr;	/* next dma descriptor ptr */
 	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg bcd;     /* byte count info */
+	hpcreg bcd;	/* byte count info */
 #define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */
 #define HPC3_SBCD_XIE     0x00004000 /* Send IRQ when done with cur buf */
 #define HPC3_SBCD_EOX     0x00008000 /* Indicates this is last buf in chain */
@@ -82,9 +85,9 @@
 #define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */
 #define HPC3_SCTRL_PERR   0x80 /* Bad parity on HPC3 iface to scsi controller */
 
-	hpcreg gfptr;   /* current GIO fifo ptr */
-	hpcreg dfptr;   /* current device fifo ptr */
-	hpcreg dconfig; /* DMA configuration register */
+	hpcreg gfptr;	/* current GIO fifo ptr */
+	hpcreg dfptr;	/* current device fifo ptr */
+	hpcreg dconfig;	/* DMA configuration register */
 #define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */
 #define HPC3_SDCFG_D1   0x00006 /* Cycles to spend in D1 state */
 #define HPC3_SDCFG_D2   0x00038 /* Cycles to spend in D2 state */
@@ -96,7 +99,7 @@
 #define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */
 #define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */
 
-	hpcreg pconfig; /* PIO configuration register */
+	hpcreg pconfig;	/* PIO configuration register */
 #define HPC3_SPCFG_P3   0x0003 /* Cycles to spend in P3 state */
 #define HPC3_SPCFG_P2W  0x001c /* Cycles to spend in P2 state for writes */
 #define HPC3_SPCFG_P2R  0x01e0 /* Cycles to spend in P2 state for reads */
@@ -115,12 +118,12 @@
 	hpcreg rx_cbptr;   /* current dma buffer ptr, diagnostic use only */
 	hpcreg rx_ndptr;   /* next dma descriptor ptr */
 	char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg rx_bcd;     /* byte count info */
+	hpcreg rx_bcd;	/* byte count info */
 #define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */
 #define HPC3_ERXBCD_XIE     0x20000000 /* HPC3 interrupts cpu at end of this buf */
 #define HPC3_ERXBCD_EOX     0x80000000 /* flags this as end of descriptor chain */
 
-	hpcreg rx_ctrl;    /* control register */
+	hpcreg rx_ctrl;	/* control register */
 #define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */
 #define HPC3_ERXCTRL_STAT6  0x00000040 /* Rdonly irq status */
 #define HPC3_ERXCTRL_STAT7  0x00000080 /* Rdonlt old/new status bit from Seeq */
@@ -129,15 +132,15 @@
 #define HPC3_ERXCTRL_AMASK  0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */
 #define HPC3_ERXCTRL_RBO    0x00000800 /* Receive buffer overflow if set to 1 */
 
-	hpcreg rx_gfptr;   /* current GIO fifo ptr */
-	hpcreg rx_dfptr;   /* current device fifo ptr */
-	hpcreg _unused2;   /* padding */
-	hpcreg rx_reset;   /* reset register */
-#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */
-#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */
-#define HPC3_ERXRST_LBACK  0x4 /* Enable diagnostic loopback mode of Seeq8003 */
+	hpcreg rx_gfptr;	/* current GIO fifo ptr */
+	hpcreg rx_dfptr;	/* current device fifo ptr */
+	hpcreg _unused2;	/* padding */
+	hpcreg rx_reset;	/* reset register */
+#define HPC3_ERXRST_CRESET 0x1	/* Reset dma channel and external controller */
+#define HPC3_ERXRST_CLRIRQ 0x2	/* Clear channel interrupt */
+#define HPC3_ERXRST_LBACK  0x4	/* Enable diagnostic loopback mode of Seeq8003 */
 
-	hpcreg rx_dconfig; /* DMA configuration register */
+	hpcreg rx_dconfig;	/* DMA configuration register */
 #define HPC3_ERXDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
 #define HPC3_ERXDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
 #define HPC3_ERXDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
@@ -147,7 +150,7 @@
 #define HPC3_ERXDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
 #define HPC3_ERXDCFG_PTO   0x30000 /* Programmed timeout value for above two */
 
-	hpcreg rx_pconfig; /* PIO configuration register */
+	hpcreg rx_pconfig;	/* PIO configuration register */
 #define HPC3_ERXPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
 #define HPC3_ERXPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
 #define HPC3_ERXPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
@@ -156,10 +159,10 @@
 	char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */
 
 	/* Transmitter registers. */
-	hpcreg tx_cbptr;   /* current dma buffer ptr, diagnostic use only */
-	hpcreg tx_ndptr;   /* next dma descriptor ptr */
+	hpcreg tx_cbptr;	/* current dma buffer ptr, diagnostic use only */
+	hpcreg tx_ndptr;	/* next dma descriptor ptr */
 	char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
-	hpcreg tx_bcd;     /* byte count info */
+	hpcreg tx_bcd;		/* byte count info */
 #define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */
 #define HPC3_ETXBCD_ESAMP   0x10000000 /* if set, too late to add descriptor */
 #define HPC3_ETXBCD_XIE     0x20000000 /* Interrupt cpu at end of cur desc */
@@ -174,8 +177,8 @@
 #define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */
 #define HPC3_ETXCTRL_AMASK  0x00000400 /* Indicates ACTIVE inhibits PIO's */
 
-	hpcreg tx_gfptr;   /* current GIO fifo ptr */
-	hpcreg tx_dfptr;   /* current device fifo ptr */
+	hpcreg tx_gfptr;	/* current GIO fifo ptr */
+	hpcreg tx_dfptr;	/* current device fifo ptr */
 	char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */
 };
 
@@ -202,79 +205,80 @@
 	 * reliably report bits 9:5 of the hpc3 irq status.  I told
 	 * you it was a peculiar bug. ;-)
 	 */
-	hpcreg istat0;      /* Irq status, only bits <4:0> reliable. */
-#define HPC3_ISTAT_PBIMASK  0x0ff  /* irq bits for pbus devs 0 --> 7 */
-#define HPC3_ISTAT_SC0MASK  0x100  /* irq bit for scsi channel 0 */
-#define HPC3_ISTAT_SC1MASK  0x200  /* irq bit for scsi channel 1 */
-
-	hpcreg gio64_misc;  /* GIO64 misc control bits. */
-#define HPC3_GIOMISC_ERTIME   0x1    /* Enable external timer real time. */
-#define HPC3_GIOMISC_DENDIAN  0x2    /* dma descriptor endian, 1=lit 0=big */
-
-	hpcreg eeprom_data; /* EEPROM data reg. */
-#define HPC3_EEPROM_EPROT     0x01   /* Protect register enable */
-#define HPC3_EEPROM_CSEL      0x02   /* Chip select */
-#define HPC3_EEPROM_ECLK      0x04   /* EEPROM clock */
-#define HPC3_EEPROM_DATO      0x08   /* Data out */
-#define HPC3_EEPROM_DATI      0x10   /* Data in */
-
-	hpcreg istat1;      /* Irq status, only bits <9:5> reliable. */
-	hpcreg gio64_estat; /* GIO64 error interrupt status reg. */
-#define HPC3_GIOESTAT_BLMASK  0x000ff  /* Bus lane where bad parity occurred */
-#define HPC3_GIOESTAT_CTYPE   0x00100  /* Bus cycle type, 0=PIO 1=DMA */
-#define HPC3_GIOESTAT_PIDMSK  0x3f700  /* DMA channel parity identifier */
+	hpcreg istat0;		/* Irq status, only bits <4:0> reliable. */
+
+#define HPC3_ISTAT_PBIMASK	0x0ff	/* irq bits for pbus devs 0 --> 7 */
+#define HPC3_ISTAT_SC0MASK	0x100	/* irq bit for scsi channel 0 */
+#define HPC3_ISTAT_SC1MASK	0x200	/* irq bit for scsi channel 1 */
+
+	hpcreg gio64_misc;	/* GIO64 misc control bits. */
+#define HPC3_GIOMISC_ERTIME	0x1	/* Enable external timer real time. */
+#define HPC3_GIOMISC_DENDIAN	0x2	/* dma descriptor endian, 1=lit 0=big */
+
+	hpcreg eeprom_data;	/* EEPROM data reg. */
+#define HPC3_EEPROM_EPROT	0x01	/* Protect register enable */
+#define HPC3_EEPROM_CSEL	0x02	/* Chip select */
+#define HPC3_EEPROM_ECLK	0x04	/* EEPROM clock */
+#define HPC3_EEPROM_DATO	0x08	/* Data out */
+#define HPC3_EEPROM_DATI	0x10	/* Data in */
+
+	hpcreg istat1;		/* Irq status, only bits <9:5> reliable. */
+	hpcreg gio64_estat;	/* GIO64 error interrupt status reg. */
+#define HPC3_GIOESTAT_BLMASK	0x000ff	/* Bus lane where bad parity occurred */
+#define HPC3_GIOESTAT_CTYPE	0x00100	/* Bus cycle type, 0=PIO 1=DMA */
+#define HPC3_GIOESTAT_PIDMSK	0x3f700	/* DMA channel parity identifier */
 
 	/* Now direct PIO per-HPC3 peripheral access to external regs. */
-	char _unused2[0x13fec]; /* Trust me... */
-	hpcreg scsi0_ext[256];  /* SCSI channel 0 external regs */
-	char _unused3[0x07c00]; /* Trust me... */
-	hpcreg scsi1_ext[256];  /* SCSI channel 1 external regs */
-	char _unused4[0x07c00]; /* It'll only hurt a little... */
+	char _unused2[0x13fec];	/* Trust me... */
+	hpcreg scsi0_ext[256];	/* SCSI channel 0 external regs */
+	char _unused3[0x07c00];	/* Trust me... */
+	hpcreg scsi1_ext[256];	/* SCSI channel 1 external regs */
+	char _unused4[0x07c00];	/* It'll only hurt a little... */
 
-	/* Did DaveM forget the ethernet external regs?
-	 * Anyhow, they're not here and we need some padding instead.
+	/* Ethernet external registers. Noone use them so we need some 
+	 * padding instead.
 	 */
 	char _unused5[0x04000]; /* It'll hurt a lot if you leave this out */
 
 	/* Per-peripheral device external registers and dma/pio control. */
-	hpcreg pbus_extregs[16][256]; /* 2nd indice indexes controller */
-	hpcreg pbus_dmacfgs[8][128]; /* 2nd indice indexes controller */
-#define HPC3_PIODCFG_D3R    0x00000001 /* Cycles to spend in D3 for reads */
-#define HPC3_PIODCFG_D4R    0x0000001e /* Cycles to spend in D4 for reads */
-#define HPC3_PIODCFG_D5R    0x000001e0 /* Cycles to spend in D5 for reads */
-#define HPC3_PIODCFG_D3W    0x00000200 /* Cycles to spend in D3 for writes */
-#define HPC3_PIODCFG_D4W    0x00003c00 /* Cycles to spend in D4 for writes */
-#define HPC3_PIODCFG_D5W    0x0003c000 /* Cycles to spend in D5 for writes */
-#define HPC3_PIODCFG_HWORD  0x00040000 /* Enable 16-bit dma access mode */
-#define HPC3_PIODCFG_EHI    0x00080000 /* Places halfwords on high 16 bits of bus */
-#define HPC3_PIODCFG_RTIME  0x00200000 /* Make this device real time on GIO bus */
-#define HPC3_PIODCFG_BURST  0x07c00000 /* 5 bit burst count for DMA device */
-#define HPC3_PIODCFG_DRQLV  0x08000000 /* Use live pbus_dreq unsynchronized signal */
-
-	hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */
-#define HPC3_PIOPCFG_RP2    0x00001  /* Cycles to spend in P2 state for reads */
-#define HPC3_PIOPCFG_RP3    0x0001e  /* Cycles to spend in P3 state for reads */
-#define HPC3_PIOPCFG_RP4    0x001e0  /* Cycles to spend in P4 state for reads */
-#define HPC3_PIOPCFG_WP2    0x00200  /* Cycles to spend in P2 state for writes */
-#define HPC3_PIOPCFG_WP3    0x03c00  /* Cycles to spend in P3 state for writes */
-#define HPC3_PIOPCFG_WP4    0x3c000  /* Cycles to spend in P4 state for writes */
-#define HPC3_PIOPCFG_HW     0x40000  /* Enable 16-bit PIO accesses */
-#define HPC3_PIOPCFG_EHI    0x80000  /* Place even address bits in bits <15:8> */
+	hpcreg pbus_extregs[16][256];	/* 2nd indice indexes controller */
+	hpcreg pbus_dmacfgs[8][128];	/* 2nd indice indexes controller */
+#define HPC3_PIODCFG_D3R    0x00000001	/* Cycles to spend in D3 for reads */
+#define HPC3_PIODCFG_D4R    0x0000001e	/* Cycles to spend in D4 for reads */
+#define HPC3_PIODCFG_D5R    0x000001e0	/* Cycles to spend in D5 for reads */
+#define HPC3_PIODCFG_D3W    0x00000200	/* Cycles to spend in D3 for writes */
+#define HPC3_PIODCFG_D4W    0x00003c00	/* Cycles to spend in D4 for writes */
+#define HPC3_PIODCFG_D5W    0x0003c000	/* Cycles to spend in D5 for writes */
+#define HPC3_PIODCFG_HWORD  0x00040000	/* Enable 16-bit dma access mode */
+#define HPC3_PIODCFG_EHI    0x00080000	/* Places halfwords on high 16 bits of bus */
+#define HPC3_PIODCFG_RTIME  0x00200000	/* Make this device real time on GIO bus */
+#define HPC3_PIODCFG_BURST  0x07c00000	/* 5 bit burst count for DMA device */
+#define HPC3_PIODCFG_DRQLV  0x08000000	/* Use live pbus_dreq unsynchronized signal */
+
+	hpcreg pbus_piocfgs[64][10];	/* 2nd indice indexes controller */
+#define HPC3_PIOPCFG_RP2    0x00001	/* Cycles to spend in P2 state for reads */
+#define HPC3_PIOPCFG_RP3    0x0001e	/* Cycles to spend in P3 state for reads */
+#define HPC3_PIOPCFG_RP4    0x001e0	/* Cycles to spend in P4 state for reads */
+#define HPC3_PIOPCFG_WP2    0x00200	/* Cycles to spend in P2 state for writes */
+#define HPC3_PIOPCFG_WP3    0x03c00	/* Cycles to spend in P3 state for writes */
+#define HPC3_PIOPCFG_WP4    0x3c000	/* Cycles to spend in P4 state for writes */
+#define HPC3_PIOPCFG_HW     0x40000	/* Enable 16-bit PIO accesses */
+#define HPC3_PIOPCFG_EHI    0x80000	/* Place even address bits in bits <15:8> */
 
 	/* PBUS PROM control regs. */
-	hpcreg pbus_promwe;     /* PROM write enable register */
-#define HPC3_PROM_WENAB     0x1 /* Enable writes to the PROM */
+	hpcreg pbus_promwe;	/* PROM write enable register */
+#define HPC3_PROM_WENAB	    0x1	/* Enable writes to the PROM */
 
 	char _unused6[0x800 - sizeof(hpcreg)];
-	hpcreg pbus_promswap;   /* Chip select swap reg */
-#define HPC3_PROM_SWAP      0x1 /* invert GIO addr bit to select prom0 or prom1 */
+	hpcreg pbus_promswap;	/* Chip select swap reg */
+#define HPC3_PROM_SWAP      0x1	/* invert GIO addr bit to select prom0 or prom1 */
 
 	char _unused7[0x800 - sizeof(hpcreg)];
-	hpcreg pbus_gout;       /* PROM general purpose output reg */
-#define HPC3_PROM_STAT      0x1 /* General purpose status bit in gout */
+	hpcreg pbus_gout;	/* PROM general purpose output reg */
+#define HPC3_PROM_STAT      0x1	/* General purpose status bit in gout */
 
 	char _unused8[0x1000 - sizeof(hpcreg)];
-	hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */
+	hpcreg pbus_promram[16384];	/* 64k of PROM battery backed ram */
 };
 
 /* It is possible to have two HPC3's within the address space on
@@ -283,8 +287,8 @@
  * 1 if present lives at address 0x1fb00000.
  */
 extern struct hpc3_regs *hpc3c0, *hpc3c1;
-#define HPC3_CHIP0_PBASE   0x1fb80000 /* physical */
-#define HPC3_CHIP1_PBASE   0x1fb00000 /* physical */
+#define HPC3_CHIP0_PBASE	0x1fb80000	/* physical */
+#define HPC3_CHIP1_PBASE	0x1fb00000	/* physical */
 
 /* Control and misc status information, these live in pbus channel 6. */
 struct hpc3_miscregs {
@@ -300,35 +304,35 @@
 	hpcreg _unused3;
 	hpcreg read, _unused4;
 	hpcreg dselect;
-#define HPC3_DSELECT_SCLK10MHZ   0x00 /* use 10MHZ serial clock */
-#define HPC3_DSELECT_ISDNB       0x01 /* enable isdn B */
-#define HPC3_DSELECT_ISDNA       0x02 /* enable isdn A */
-#define HPC3_DSELECT_LPR         0x04 /* use parallel DMA */
-#define HPC3_DSELECT_SCLK667MHZ  0x10 /* use 6.67MHZ serial clock */
-#define HPC3_DSELECT_SCLKEXT     0x20 /* use external serial clock */
+#define HPC3_DSELECT_SCLK10MHZ	0x00	/* use 10MHZ serial clock */
+#define HPC3_DSELECT_ISDNB	0x01	/* enable isdn B */
+#define HPC3_DSELECT_ISDNA	0x02	/* enable isdn A */
+#define HPC3_DSELECT_LPR	0x04	/* use parallel DMA */
+#define HPC3_DSELECT_SCLK667MHZ	0x10	/* use 6.67MHZ serial clock */
+#define HPC3_DSELECT_SCLKEXT	0x20	/* use external serial clock */
 
 	hpcreg _unused5;
 	hpcreg write1;
-#define HPC3_WRITE1_PRESET    0x01  /* 0=LPR_RESET, 1=NORMAL */
-#define HPC3_WRITE1_KMRESET   0x02  /* 0=KBDMOUSE_RESET, 1=NORMAL */
-#define HPC3_WRITE1_ERESET    0x04  /* 0=EISA_RESET, 1=NORMAL */
-#define HPC3_WRITE1_GRESET    0x08  /* 0=MAGIC_GIO_RESET, 1=NORMAL */
-#define HPC3_WRITE1_LC0OFF    0x10  /* turn led off (guiness=red, else green) */
-#define HPC3_WRITE1_LC1OFF    0x20  /* turn led off (guiness=green, else amber) */
+#define HPC3_WRITE1_PRESET	0x01	/* 0=LPR_RESET, 1=NORMAL */
+#define HPC3_WRITE1_KMRESET	0x02	/* 0=KBDMOUSE_RESET, 1=NORMAL */
+#define HPC3_WRITE1_ERESET	0x04	/* 0=EISA_RESET, 1=NORMAL */
+#define HPC3_WRITE1_GRESET	0x08	/* 0=MAGIC_GIO_RESET, 1=NORMAL */
+#define HPC3_WRITE1_LC0OFF	0x10	/* turn led off (guiness=red, else green) */
+#define HPC3_WRITE1_LC1OFF	0x20	/* turn led off (guiness=green, else amber) */
 
 	hpcreg _unused6;
 	hpcreg write2;
-#define HPC3_WRITE2_NTHRESH  0x01 /* use 4.5db threshhold */
-#define HPC3_WRITE2_TPSPEED  0x02 /* use 100ohm TP speed */
-#define HPC3_WRITE2_EPSEL    0x04 /* force cable mode: 1=AUI 0=TP */
-#define HPC3_WRITE2_EASEL    0x08 /* 1=autoselect 0=manual cable selection */
-#define HPC3_WRITE2_U1AMODE  0x10 /* 1=PC 0=MAC UART mode */
-#define HPC3_WRITE2_U0AMODE  0x20 /* 1=PC 0=MAC UART mode */
-#define HPC3_WRITE2_MLO      0x40 /* 1=4.75V 0=+5V */
-#define HPC3_WRITE2_MHI      0x80 /* 1=5.25V 0=+5V */
+#define HPC3_WRITE2_NTHRESH	0x01	/* use 4.5db threshhold */
+#define HPC3_WRITE2_TPSPEED	0x02	/* use 100ohm TP speed */
+#define HPC3_WRITE2_EPSEL	0x04	/* force cable mode: 1=AUI 0=TP */
+#define HPC3_WRITE2_EASEL	0x08	/* 1=autoselect 0=manual cable selection */
+#define HPC3_WRITE2_U1AMODE	0x10	/* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_U0AMODE	0x20	/* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_MLO		0x40	/* 1=4.75V 0=+5V */
+#define HPC3_WRITE2_MHI		0x80	/* 1=5.25V 0=+5V */
 };
 extern struct hpc3_miscregs *hpc3mregs;
-#define HPC3_MREGS_PBASE   0x1fbd9800 /* physical */
+#define HPC3_MREGS_PBASE	0x1fbd9800	/* physical */
 
 /* We need software copies of these because they are write only. */
 extern unsigned int sgi_hpc_write1, sgi_hpc_write2;
@@ -372,4 +376,4 @@
 
 extern void sgihpc_init(void);
 
-#endif /* _ASM_SGI_SGIHPC_H */
+#endif /* __ASM_SGI_SGIHPC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sgi/sgint23.h linux/include/asm-mips64/sgi/sgint23.h
--- linux.orig/include/asm-mips64/sgi/sgint23.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sgi/sgint23.h	2002-07-20 01:08:33.000000000 +0000
@@ -6,100 +6,129 @@
  * sgint23.h: Defines for the SGI INT2 and INT3 chipsets.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 98, 1999, 2000  Ralf Baechle
+ * Copyright (C) 1997, 98, 1999, 2000 Ralf Baechle
  * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections
+ * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz)
  */
 #ifndef _ASM_SGI_SGINT23_H
 #define _ASM_SGI_SGINT23_H
 
 /* These are the virtual IRQ numbers, we divide all IRQ's into
  * 'spaces', the 'space' determines where and how to enable/disable
- * that particular IRQ on an SGI machine.  Add new 'spaces' as new
- * IRQ hardware is supported.
+ * that particular IRQ on an SGI machine. HPC DMA and MC DMA interrups
+ * are not supported this way. Driver is supposed to allocate HPC/MC 
+ * interrupt as shareable and then look to proper status bit (see
+ * HAL2 driver). This will prevent many complications, trust me ;-) 
+ *	--ladis
  */
-#define SGINT_LOCAL0   0   /* INDY has 8 local0 irq levels */
-#define SGINT_LOCAL1   8   /* INDY has 8 local1 irq levels */
-#define SGINT_LOCAL2   16  /* INDY has 8 local2 vectored irq levels */
-#define SGINT_LOCAL3   24  /* INDY has 8 local3 vectored irq levels */
-#define SGINT_GIO      32  /* INDY has 9 GIO irq levels */
-#define SGINT_HPCDMA   41  /* INDY has 11 HPCDMA irq _sources_ */
-#define SGINT_END      52  /* End of 'spaces' */
+#define SGINT_CPU	 0	/* MIPS CPU define 8 interrupt sources */
+#define SGINT_LOCAL0	 8	/* INDY has 8 local0 irq levels */
+#define SGINT_LOCAL1	16	/* INDY has 8 local1 irq levels */
+#define SGINT_LOCAL2	24	/* INDY has 8 local2 vectored irq levels */
+#define SGINT_LOCAL3	32	/* INDY has 8 local3 vectored irq levels */
+#define SGINT_END	40	/* End of 'spaces' */
 
 /*
  * Individual interrupt definitions for the INDY and Indigo2
  */
+
+#define SGI_SOFT_0_IRQ	SGINT_CPU + 0
+#define SGI_SOFT_1_IRQ	SGINT_CPU + 1
+#define SGI_LOCAL_0_IRQ	SGINT_CPU + 2
+#define SGI_LOCAL_1_IRQ	SGINT_CPU + 3
+#define SGI_8254_0_IRQ	SGINT_CPU + 4
+#define SGI_8254_1_IRQ	SGINT_CPU + 5
+#define SGI_BUSERR_IRQ	SGINT_CPU + 6
+#define SGI_TIMER_IRQ	SGINT_CPU + 7
+
+#define SGI_FIFO_IRQ	SGINT_LOCAL0 + 0	/* FIFO full */
+#define SGI_GIO_0_IRQ	SGI_FIFO_IRQ		/* GIO-0 */	
 #define SGI_WD93_0_IRQ	SGINT_LOCAL0 + 1	/* 1st onboard WD93 */
 #define SGI_WD93_1_IRQ	SGINT_LOCAL0 + 2	/* 2nd onboard WD93 */
 #define SGI_ENET_IRQ	SGINT_LOCAL0 + 3	/* onboard ethernet */
+#define SGI_MCDMA_IRQ	SGINT_LOCAL0 + 4	/* MC DMA done */
+#define SGI_PARPORT_IRQ	SGINT_LOCAL0 + 5	/* Parallel port */
+#define SGI_GIO_1_IRQ	SGINT_LOCAL0 + 6	/* GE / GIO-1 / 2nd-HPC */
+#define SGI_MAP_0_IRQ	SGINT_LOCAL0 + 7	/* Mappable interrupt 0 */
 
+#define SGI_GPL0_IRQ	SGINT_LOCAL1 + 0	/* General Purpose LOCAL1_N<0> */
 #define SGI_PANEL_IRQ	SGINT_LOCAL1 + 1	/* front panel */
-
+#define SGI_GPL2_IRQ	SGINT_LOCAL1 + 2	/* General Purpose LOCAL1_N<2> */
+#define SGI_MAP_1_IRQ	SGINT_LOCAL1 + 3	/* Mappable interrupt 1 */
+#define SGI_HPCDMA_IRQ	SGINT_LOCAL1 + 4	/* HPC DMA done */
+#define SGI_ACFAIL_IRQ	SGINT_LOCAL1 + 5	/* AC fail */
+#define SGI_VINO_IRQ	SGINT_LOCAL1 + 6	/* Indy VINO */
+#define SGI_GIO_2_IRQ	SGINT_LOCAL1 + 7	/* Vert retrace / GIO-2 */
+
+/* Mapped interrupts. These interrupts may be mapped to either 0, or 1
+ * We map them to 0 */
+#define SGI_VERT_IRQ	SGINT_LOCAL2 + 0	/* INT3: newport vertical status */
 #define SGI_EISA_IRQ	SGINT_LOCAL2 + 3	/* EISA interrupts */
-#define SGI_KEYBOARD_IRQ	SGINT_LOCAL2 + 4	/* keyboard */
+#define SGI_KEYBD_IRQ	SGINT_LOCAL2 + 4	/* keyboard */
 #define SGI_SERIAL_IRQ	SGINT_LOCAL2 + 5	/* onboard serial */
 
 /* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */
-#define SGI_INT2_BASE 0x1fbd9000 /* physical */
-#define SGI_INT3_BASE 0x1fbd9880 /* physical */
+#define SGI_INT2_BASE	0x1fbd9000	/* physical */
+#define SGI_INT3_BASE	0x1fbd9880	/* physical */
 
 struct sgi_ioc_ints {
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
-	volatile unsigned char istat0;    /* Interrupt status zero */
+	volatile unsigned char istat0;	/* Interrupt status zero */
 #else
-	volatile unsigned char istat0;    /* Interrupt status zero */
+	volatile unsigned char istat0;	/* Interrupt status zero */
 	unsigned char _unused0[3];
 #endif
-#define ISTAT0_FFULL           0x01
-#define ISTAT0_SCSI0           0x02
-#define ISTAT0_SCSI1           0x04
-#define ISTAT0_ENET            0x08
-#define ISTAT0_GFXDMA          0x10
-#define ISTAT0_LPR             0x20
-#define ISTAT0_HPC2            0x40
-#define ISTAT0_LIO2            0x80
-
+#define ISTAT0_FFULL	0x01
+#define ISTAT0_SCSI0	0x02
+#define ISTAT0_SCSI1	0x04
+#define ISTAT0_ENET	0x08
+#define ISTAT0_GFXDMA	0x10
+#define ISTAT0_LPR	0x20
+#define ISTAT0_HPC2	0x40
+#define ISTAT0_LIO2	0x80
+	
 #ifdef __MIPSEB__
 	unsigned char _unused1[3];
-	volatile unsigned char imask0;    /* Interrupt mask zero */
+	volatile unsigned char imask0;	/* Interrupt mask zero */
 	unsigned char _unused2[3];
-	volatile unsigned char istat1;    /* Interrupt status one */
+	volatile unsigned char istat1;	/* Interrupt status one */
 #else
-	volatile unsigned char imask0;    /* Interrupt mask zero */
+	volatile unsigned char imask0;	/* Interrupt mask zero */
 	unsigned char _unused1[3];
-	volatile unsigned char istat1;    /* Interrupt status one */
+	volatile unsigned char istat1;	/* Interrupt status one */
 	unsigned char _unused2[3];
 #endif
-#define ISTAT1_ISDNI           0x01
-#define ISTAT1_PWR             0x02
-#define ISTAT1_ISDNH           0x04
-#define ISTAT1_LIO3            0x08
-#define ISTAT1_HPC3            0x10
-#define ISTAT1_AFAIL           0x20
-#define ISTAT1_VIDEO           0x40
-#define ISTAT1_GIO2            0x80
-
+#define ISTAT1_ISDNI	0x01
+#define ISTAT1_PWR	0x02
+#define ISTAT1_ISDNH	0x04
+#define ISTAT1_LIO3	0x08
+#define ISTAT1_HPC3	0x10
+#define ISTAT1_AFAIL	0x20
+#define ISTAT1_VIDEO	0x40
+#define ISTAT1_GIO2	0x80
+	
 #ifdef __MIPSEB__
 	unsigned char _unused3[3];
-	volatile unsigned char imask1;    /* Interrupt mask one */
+	volatile unsigned char imask1;		/* Interrupt mask one */
 	unsigned char _unused4[3];
-	volatile unsigned char vmeistat;  /* VME interrupt status */
+	volatile unsigned char vmeistat;	/* VME interrupt status */
 	unsigned char _unused5[3];
-	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+	volatile unsigned char cmeimask0;	/* VME interrupt mask zero */
 	unsigned char _unused6[3];
-	volatile unsigned char cmeimask1; /* VME interrupt mask one */
+	volatile unsigned char cmeimask1;	/* VME interrupt mask one */
 	unsigned char _unused7[3];
-	volatile unsigned char cmepol;    /* VME polarity */
+	volatile unsigned char cmepol;		/* VME polarity */
 #else
-	volatile unsigned char imask1;    /* Interrupt mask one */
+	volatile unsigned char imask1;		/* Interrupt mask one */
 	unsigned char _unused3[3];
-	volatile unsigned char vmeistat;  /* VME interrupt status */
+	volatile unsigned char vmeistat;	/* VME interrupt status */
 	unsigned char _unused4[3];
-	volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+	volatile unsigned char cmeimask0;	/* VME interrupt mask zero */
 	unsigned char _unused5[3];
-	volatile unsigned char cmeimask1; /* VME interrupt mask one */
+	volatile unsigned char cmeimask1;	/* VME interrupt mask one */
 	unsigned char _unused6[3];
-	volatile unsigned char cmepol;    /* VME polarity */
+	volatile unsigned char cmepol;		/* VME polarity */
 	unsigned char _unused7[3];
 #endif
 };
@@ -107,21 +136,21 @@
 struct sgi_ioc_timers {
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
-	volatile unsigned char tcnt0;  /* counter 0 */
+	volatile unsigned char tcnt0;	/* counter 0 */
 	unsigned char _unused1[3];
-	volatile unsigned char tcnt1;  /* counter 1 */
+	volatile unsigned char tcnt1;	/* counter 1 */
 	unsigned char _unused2[3];
-	volatile unsigned char tcnt2;  /* counter 2 */
+	volatile unsigned char tcnt2;	/* counter 2 */
 	unsigned char _unused3[3];
-	volatile unsigned char tcword; /* control word */
+	volatile unsigned char tcword;	/* control word */
 #else
-	volatile unsigned char tcnt0;  /* counter 0 */
+	volatile unsigned char tcnt0;	/* counter 0 */
 	unsigned char _unused0[3];
-	volatile unsigned char tcnt1;  /* counter 1 */
+	volatile unsigned char tcnt1;	/* counter 1 */
 	unsigned char _unused1[3];
-	volatile unsigned char tcnt2;  /* counter 2 */
+	volatile unsigned char tcnt2;	/* counter 2 */
 	unsigned char _unused2[3];
-	volatile unsigned char tcword; /* control word */
+	volatile unsigned char tcword;	/* control word */
 	unsigned char _unused3[3];
 #endif
 };
@@ -154,23 +183,23 @@
 struct sgi_int2_regs {
 	struct sgi_ioc_ints ints;
 
-	volatile u32 ledbits; 		  /* LED control bits */
-#define INT2_LED_TXCLK         0x01       /* GPI to TXCLK enable */
-#define INT2_LED_SERSLCT0      0x02       /* serial port0: 0=apple 1=pc */
-#define INT2_LED_SERSLCT1      0x04       /* serial port1: 0=apple 1=pc */
-#define INT2_LED_CHEAPER       0x08       /* 0=cheapernet 1=ethernet */
-#define INT2_LED_POWEROFF      0x10       /* Power-off request, active high */
+	volatile u32 ledbits;		/* LED control bits */
+#define INT2_LED_TXCLK		0x01	/* GPI to TXCLK enable */
+#define INT2_LED_SERSLCT0	0x02	/* serial port0: 0=apple 1=pc */
+#define INT2_LED_SERSLCT1	0x04	/* serial port1: 0=apple 1=pc */
+#define INT2_LED_CHEAPER	0x08	/* 0=cheapernet 1=ethernet */
+#define INT2_LED_POWEROFF	0x10	/* Power-off request, active high */
 
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
-	volatile unsigned char tclear;    /* Timer clear strobe address */
+	volatile unsigned char tclear;	/* Timer clear strobe address */
 #else
-	volatile unsigned char tclear;    /* Timer clear strobe address */
+	volatile unsigned char tclear;	/* Timer clear strobe address */
 	unsigned char _unused0[3];
 #endif
-#define INT2_TCLEAR_T0CLR      0x1        /* Clear timer0 IRQ */
-#define INT2_TCLEAR_T1CLR      0x2        /* Clear timer1 IRQ */
-/* I am guessing there are only two unused registers here 
+#define INT2_TCLEAR_T0CLR	0x1	/* Clear timer0 IRQ */
+#define INT2_TCLEAR_T1CLR	0x2	/* Clear timer1 IRQ */
+/* I am guesing there are only two unused registers here 
  * but I could be wrong...			- andrewb
  */
 /*	u32 _unused[3]; */
@@ -183,12 +212,12 @@
 
 #ifdef __MIPSEB__
 	unsigned char _unused0[3];
-	volatile unsigned char tclear;		/* Timer clear strobe address */
+	volatile unsigned char tclear;	/* Timer clear strobe address */
 #else
-	volatile unsigned char tclear;		/* Timer clear strobe address */
+	volatile unsigned char tclear;	/* Timer clear strobe address */
 	unsigned char _unused0[3];
 #endif
-	volatile u32 estatus;			/* Error status reg */
+	volatile u32 estatus;		/* Error status reg */
 	u32 _unused1[2];
 	struct sgi_ioc_timers timers;
 };
@@ -199,6 +228,4 @@
 extern struct sgi_ioc_timers *ioc_timers;
 extern volatile unsigned char *ioc_tclear;
 
-extern void indy_timer_init(void);
-
 #endif /* _ASM_SGI_SGINT23_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/64bit.h linux/include/asm-mips64/sibyte/64bit.h
--- linux.orig/include/asm-mips64/sibyte/64bit.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/64bit.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+#ifndef _ASM_SIBYTE_64BIT_H
+#define _ASM_SIBYTE_64BIT_H
+
+#include <linux/types.h>
+
+/* These are provided so as to be able to use common
+   driver code for the 32-bit and 64-bit trees */
+
+extern inline void out64(u64 val, unsigned long addr)
+{
+	*(volatile unsigned long *)addr = val;
+}
+
+extern inline u64 in64(unsigned long addr)
+{
+	return *(volatile unsigned long *)addr;
+}
+
+#endif /* _ASM_SIBYTE_64BIT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250.h linux/include/asm-mips64/sibyte/sb1250.h
--- linux.orig/include/asm-mips64/sibyte/sb1250.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom 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.
+ */
+
+#ifndef _ASM_SIBYTE_SB1250_H
+#define _ASM_SIBYTE_SB1250_H
+
+extern void sb1250_time_init(void);
+extern void sb1250_mask_irq(int cpu, int irq);
+extern void sb1250_unmask_irq(int cpu, int irq);
+extern void sb1250_smp_finish(void);
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_defs.h linux/include/asm-mips64/sibyte/sb1250_defs.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_defs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_defs.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,127 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Global constants and macros		File: sb1250_defs.h	
+    *  
+    *  This file contains macros and definitions used by the other
+    *  include files.
+    *
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+/*  *********************************************************************
+    *  Naming schemes for constants in these files:
+    *  
+    *  M_xxx           MASK constant (identifies bits in a register). 
+    *                  For multi-bit fields, all bits in the field will
+    *                  be set.
+    *
+    *  K_xxx           "Code" constant (value for data in a multi-bit
+    *                  field).  The value is right justified.
+    *
+    *  V_xxx           "Value" constant.  This is the same as the 
+    *                  corresponding "K_xxx" constant, except it is
+    *                  shifted to the correct position in the register.
+    *
+    *  S_xxx           SHIFT constant.  This is the number of bits that
+    *                  a field value (code) needs to be shifted 
+    *                  (towards the left) to put the value in the right
+    *                  position for the register.
+    *
+    *  A_xxx           ADDRESS constant.  This will be a physical 
+    *                  address.  Use the PHYS_TO_K1 macro to generate
+    *                  a K1SEG address.
+    *
+    *  R_xxx           RELATIVE offset constant.  This is an offset from
+    *                  an A_xxx constant (usually the first register in
+    *                  a group).
+    *  
+    *  G_xxx(X)        GET value.  This macro obtains a multi-bit field
+    *                  from a register, masks it, and shifts it to
+    *                  the bottom of the register (retrieving a K_xxx
+    *                  value, for example).
+    *
+    *  V_xxx(X)        VALUE.  This macro computes the value of a
+    *                  K_xxx constant shifted to the correct position
+    *                  in the register.
+    ********************************************************************* */
+
+
+
+
+#ifndef _SB1250_DEFS_H
+#define _SB1250_DEFS_H
+
+/*
+ * Cast to 64-bit number.  Presumably the syntax is different in 
+ * assembly language.
+ *
+ * Note: you'll need to define uint32_t and uint64_t in your headers.
+ */
+
+#if !defined(__ASSEMBLY__)
+#define _SB_MAKE64(x) ((uint64_t)(x))
+#define _SB_MAKE32(x) ((uint32_t)(x))
+#else
+#define _SB_MAKE64(x) (x)
+#define _SB_MAKE32(x) (x)
+#endif
+
+
+/*
+ * Make a mask for 1 bit at position 'n'
+ */
+
+#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n))
+#define _SB_MAKEMASK1_32(n) (_SB_MAKE32(1) << _SB_MAKE32(n))
+
+/*
+ * Make a mask for 'v' bits at position 'n'
+ */
+
+#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n))
+#define _SB_MAKEMASK_32(v,n) (_SB_MAKE32((_SB_MAKE32(1)<<(v))-1) << _SB_MAKE32(n))
+
+/*
+ * Make a value at 'v' at bit position 'n'
+ */
+
+#define _SB_MAKEVALUE(v,n) (_SB_MAKE64(v) << _SB_MAKE64(n))
+#define _SB_MAKEVALUE_32(v,n) (_SB_MAKE32(v) << _SB_MAKE32(n))
+
+#define _SB_GETVALUE(v,n,m) ((_SB_MAKE64(v) & _SB_MAKE64(m)) >> _SB_MAKE64(n))
+#define _SB_GETVALUE_32(v,n,m) ((_SB_MAKE32(v) & _SB_MAKE32(m)) >> _SB_MAKE32(n))
+
+/*
+ * Macros to read/write on-chip registers
+ * XXX should we do the PHYS_TO_K1 here?
+ */
+
+
+#if !defined(__ASSEMBLY__)
+#define SBWRITECSR(csr,val) *((volatile uint64_t *) PHYS_TO_K1(csr)) = (val)
+#define SBREADCSR(csr) (*((volatile uint64_t *) PHYS_TO_K1(csr)))
+#endif /* __ASSEMBLY__ */
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_dma.h linux/include/asm-mips64/sibyte/sb1250_dma.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_dma.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,416 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  DMA definitions				File: sb1250_dma.h
+    *  
+    *  This module contains constants and macros useful for
+    *  programming the SB1250's DMA controllers, both the data mover
+    *  and the Ethernet DMA.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_DMA_H
+#define _SB1250_DMA_H
+
+
+#include "sb1250_defs.h"
+
+/*  *********************************************************************
+    *  DMA Registers
+    ********************************************************************* */
+
+/* 
+ * Ethernet and Serial DMA Configuration Register 0  (Table 7-4)
+ * Registers: DMA_CONFIG0_MAC_x_RX_CH_0 
+ * Registers: DMA_CONFIG0_MAC_x_TX_CH_0
+ * Registers: DMA_CONFIG0_SER_x_RX
+ * Registers: DMA_CONFIG0_SER_x_TX
+ */
+
+
+#define M_DMA_DROP                  _SB_MAKEMASK1(0)
+#define M_DMA_CHAIN_SEL             _SB_MAKEMASK1(1)
+#define M_DMA_RESERVED1             _SB_MAKEMASK1(2)
+#define M_DMA_EOP_INT_EN            _SB_MAKEMASK1(3)
+#define M_DMA_HWM_INT_EN            _SB_MAKEMASK1(4)
+#define M_DMA_LWM_INT_EN            _SB_MAKEMASK1(5)
+#define M_DMA_TBX_EN                _SB_MAKEMASK1(6)
+#define M_DMA_TDX_EN                _SB_MAKEMASK1(7)
+
+#define S_DMA_INT_PKTCNT            _SB_MAKE64(8)
+#define M_DMA_INT_PKTCNT            _SB_MAKEMASK(8,S_DMA_INT_PKTCNT)
+#define V_DMA_INT_PKTCNT(x)         _SB_MAKEVALUE(x,S_DMA_INT_PKTCNT)
+#define G_DMA_INT_PKTCNT(x)         _SB_GETVALUE(x,S_DMA_INT_PKTCNT,M_DMA_INT_PKTCNT)
+
+#define S_DMA_RINGSZ                _SB_MAKE64(16)
+#define M_DMA_RINGSZ                _SB_MAKEMASK(16,S_DMA_RINGSZ)
+#define V_DMA_RINGSZ(x)             _SB_MAKEVALUE(x,S_DMA_RINGSZ)
+#define G_DMA_RINGSZ(x)             _SB_GETVALUE(x,S_DMA_RINGSZ,M_DMA_RINGSZ)
+
+#define S_DMA_HIGH_WATERMARK        _SB_MAKE64(32)
+#define M_DMA_HIGH_WATERMARK        _SB_MAKEMASK(16,S_DMA_HIGH_WATERMARK)
+#define V_DMA_HIGH_WATERMARK(x)     _SB_MAKEVALUE(x,S_DMA_HIGH_WATERMARK)
+#define G_DMA_HIGH_WATERMARK(x)     _SB_GETVALUE(x,S_DMA_HIGH_WATERMARK,M_DMA_HIGH_WATERMARK)
+
+#define S_DMA_LOW_WATERMARK         _SB_MAKE64(48)
+#define M_DMA_LOW_WATERMARK         _SB_MAKEMASK(16,S_DMA_LOW_WATERMARK)
+#define V_DMA_LOW_WATERMARK(x)      _SB_MAKEVALUE(x,S_DMA_LOW_WATERMARK)
+#define G_DMA_LOW_WATERMARK(x)      _SB_GETVALUE(x,S_DMA_LOW_WATERMARK,M_DMA_LOW_WATERMARK)
+
+/*
+ * Ethernet and Serial DMA Configuration Register 2 (Table 7-5)
+ * Registers: DMA_CONFIG1_MAC_x_RX_CH_0 
+ * Registers: DMA_CONFIG1_DMA_x_TX_CH_0
+ * Registers: DMA_CONFIG1_SER_x_RX
+ * Registers: DMA_CONFIG1_SER_x_TX
+ */
+
+#define M_DMA_HDR_CF_EN             _SB_MAKEMASK1(0)
+#define M_DMA_ASIC_XFR_EN           _SB_MAKEMASK1(1)
+#define M_DMA_PRE_ADDR_EN           _SB_MAKEMASK1(2)
+#define M_DMA_FLOW_CTL_EN           _SB_MAKEMASK1(3)
+#define M_DMA_NO_DSCR_UPDT          _SB_MAKEMASK1(4)
+#define M_DMA_L2CA		    _SB_MAKEMASK1(5)
+
+#define M_DMA_MBZ1                  _SB_MAKEMASK(6,15)
+
+#define S_DMA_HDR_SIZE              _SB_MAKE64(21)
+#define M_DMA_HDR_SIZE              _SB_MAKEMASK(9,S_DMA_HDR_SIZE)
+#define V_DMA_HDR_SIZE(x)           _SB_MAKEVALUE(x,S_DMA_HDR_SIZE)
+#define G_DMA_HDR_SIZE(x)           _SB_GETVALUE(x,S_DMA_HDR_SIZE,M_DMA_HDR_SIZE)
+
+#define M_DMA_MBZ2                  _SB_MAKEMASK(5,32)
+
+#define S_DMA_ASICXFR_SIZE          _SB_MAKE64(37)
+#define M_DMA_ASICXFR_SIZE          _SB_MAKEMASK(9,S_DMA_ASICXFR_SIZE)
+#define V_DMA_ASICXFR_SIZE(x)       _SB_MAKEVALUE(x,S_DMA_ASICXFR_SIZE)
+#define G_DMA_ASICXFR_SIZE(x)       _SB_GETVALUE(x,S_DMA_ASICXFR_SIZE,M_DMA_ASICXFR_SIZE)
+
+#define S_DMA_INT_TIMEOUT           _SB_MAKE64(48)
+#define M_DMA_INT_TIMEOUT           _SB_MAKEMASK(16,S_DMA_INT_TIMEOUT)
+#define V_DMA_INT_TIMEOUT(x)        _SB_MAKEVALUE(x,S_DMA_INT_TIMEOUT)
+#define G_DMA_INT_TIMEOUT(x)        _SB_GETVALUE(x,S_DMA_INT_TIMEOUT,M_DMA_INT_TIMEOUT)
+
+/*
+ * Ethernet and Serial DMA Descriptor base address (Table 7-6)
+ */
+
+#define M_DMA_DSCRBASE_MBZ          _SB_MAKEMASK(4,0)
+
+
+/*
+ * ASIC Mode Base Address (Table 7-7)
+ */
+
+#define M_DMA_ASIC_BASE_MBZ         _SB_MAKEMASK(20,0)
+
+/*
+ * DMA Descriptor Count Registers (Table 7-8)
+ */
+ 
+/* No bitfields */
+
+
+/* 
+ * Current Descriptor Address Register (Table 7-11)
+ */
+
+#define S_DMA_CURDSCR_ADDR          _SB_MAKE64(0)
+#define M_DMA_CURDSCR_ADDR          _SB_MAKEMASK(40,S_DMA_CURDSCR_ADDR)
+#define S_DMA_CURDSCR_COUNT         _SB_MAKE64(48)
+#define M_DMA_CURDSCR_COUNT         _SB_MAKEMASK(16,S_DMA_CURDSCR_COUNT)
+
+/*  *********************************************************************
+    *  DMA Descriptors
+    ********************************************************************* */
+
+/*
+ * Descriptor doubleword "A"  (Table 7-12)
+ */
+
+#define S_DMA_DSCRA_OFFSET          _SB_MAKE64(0)
+#define M_DMA_DSCRA_OFFSET          _SB_MAKEMASK(5,S_DMA_DSCRA_OFFSET)
+
+/* Note: Don't shift the address over, just mask it with the mask below */
+#define S_DMA_DSCRA_A_ADDR          _SB_MAKE64(5)
+#define M_DMA_DSCRA_A_ADDR          _SB_MAKEMASK(35,S_DMA_DSCRA_A_ADDR)
+
+#define M_DMA_DSCRA_A_ADDR_OFFSET   (M_DMA_DSCRA_OFFSET | M_DMA_DSCRA_A_ADDR)
+
+#define S_DMA_DSCRA_A_SIZE          _SB_MAKE64(40)
+#define M_DMA_DSCRA_A_SIZE          _SB_MAKEMASK(9,S_DMA_DSCRA_A_SIZE)
+#define V_DMA_DSCRA_A_SIZE(x)       _SB_MAKEVALUE(x,S_DMA_DSCRA_A_SIZE)
+#define G_DMA_DSCRA_A_SIZE(x)       _SB_GETVALUE(x,S_DMA_DSCRA_A_SIZE,M_DMA_DSCRA_A_SIZE)
+
+#define M_DMA_DSCRA_INTERRUPT       _SB_MAKEMASK1(49)
+#define M_DMA_DSCRA_OFFSETB	    _SB_MAKEMASK1(50)
+
+#define S_DMA_DSCRA_STATUS          _SB_MAKE64(51)
+#define M_DMA_DSCRA_STATUS          _SB_MAKEMASK(13,S_DMA_DSCRA_STATUS)
+#define V_DMA_DSCRA_STATUS(x)       _SB_MAKEVALUE(x,S_DMA_DSCRA_STATUS)
+#define G_DMA_DSCRA_STATUS(x)       _SB_GETVALUE(x,S_DMA_DSCRA_STATUS,M_DMA_DSCRA_STATUS)
+
+/*
+ * Descriptor doubleword "B"  (Table 7-13)
+ */
+
+
+#define S_DMA_DSCRB_OPTIONS         _SB_MAKE64(0)
+#define M_DMA_DSCRB_OPTIONS         _SB_MAKEMASK(4,S_DMA_DSCRB_OPTIONS)
+#define V_DMA_DSCRB_OPTIONS(x)      _SB_MAKEVALUE(x,S_DMA_DSCRB_OPTIONS)
+#define G_DMA_DSCRB_OPTIONS(x)      _SB_GETVALUE(x,S_DMA_DSCRB_OPTIONS,M_DMA_DSCRB_OPTIONS)
+
+#define R_DMA_DSCRB_ADDR            _SB_MAKE64(0x10)
+
+/* Note: Don't shift the address over, just mask it with the mask below */
+#define S_DMA_DSCRB_B_ADDR          _SB_MAKE64(5)
+#define M_DMA_DSCRB_B_ADDR          _SB_MAKEMASK(35,S_DMA_DSCRB_B_ADDR)
+
+#define S_DMA_DSCRB_B_SIZE          _SB_MAKE64(40)
+#define M_DMA_DSCRB_B_SIZE          _SB_MAKEMASK(9,S_DMA_DSCRB_B_SIZE)
+#define V_DMA_DSCRB_B_SIZE(x)       _SB_MAKEVALUE(x,S_DMA_DSCRB_B_SIZE)
+#define G_DMA_DSCRB_B_SIZE(x)       _SB_GETVALUE(x,S_DMA_DSCRB_B_SIZE,M_DMA_DSCRB_B_SIZE)
+
+#define M_DMA_DSCRB_B_VALID         _SB_MAKEMASK1(49)
+
+#define S_DMA_DSCRB_PKT_SIZE        _SB_MAKE64(50)
+#define M_DMA_DSCRB_PKT_SIZE        _SB_MAKEMASK(14,S_DMA_DSCRB_PKT_SIZE)
+#define V_DMA_DSCRB_PKT_SIZE(x)     _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE)
+#define G_DMA_DSCRB_PKT_SIZE(x)     _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE,M_DMA_DSCRB_PKT_SIZE)
+
+/* 
+ * Ethernet Descriptor Status Bits (Table 7-15)
+ */
+
+#define M_DMA_ETHRX_BADIP4CS        _SB_MAKEMASK1(51)
+#define M_DMA_ETHRX_DSCRERR	    _SB_MAKEMASK1(52)
+
+#define S_DMA_ETHRX_RXCH            53
+#define M_DMA_ETHRX_RXCH            _SB_MAKEMASK(2,S_DMA_ETHRX_RXCH)
+#define V_DMA_ETHRX_RXCH(x)         _SB_MAKEVALUE(x,S_DMA_ETHRX_RXCH)
+#define G_DMA_ETHRX_RXCH(x)         _SB_GETVALUE(x,S_DMA_ETHRX_RXCH,M_DMA_ETHRX_RXCH)
+
+#define S_DMA_ETHRX_PKTTYPE         55
+#define M_DMA_ETHRX_PKTTYPE         _SB_MAKEMASK(3,S_DMA_ETHRX_PKTTYPE)
+#define V_DMA_ETHRX_PKTTYPE(x)      _SB_MAKEVALUE(x,S_DMA_ETHRX_PKTTYPE)
+#define G_DMA_ETHRX_PKTTYPE(x)      _SB_GETVALUE(x,S_DMA_ETHRX_PKTTYPE,M_DMA_ETHRX_PKTTYPE)
+
+#define K_DMA_ETHRX_PKTTYPE_IPV4    0
+#define K_DMA_ETHRX_PKTTYPE_ARPV4   1
+#define K_DMA_ETHRX_PKTTYPE_802     2
+#define K_DMA_ETHRX_PKTTYPE_OTHER   3
+#define K_DMA_ETHRX_PKTTYPE_USER0   4
+#define K_DMA_ETHRX_PKTTYPE_USER1   5
+#define K_DMA_ETHRX_PKTTYPE_USER2   6
+#define K_DMA_ETHRX_PKTTYPE_USER3   7
+
+#define M_DMA_ETHRX_MATCH_EXACT     _SB_MAKEMASK1(58)
+#define M_DMA_ETHRX_MATCH_HASH      _SB_MAKEMASK1(59)
+#define M_DMA_ETHRX_BCAST           _SB_MAKEMASK1(60)
+#define M_DMA_ETHRX_MCAST           _SB_MAKEMASK1(61)
+#define M_DMA_ETHRX_BAD	            _SB_MAKEMASK1(62)
+#define M_DMA_ETHRX_SOP             _SB_MAKEMASK1(63)
+
+/*
+ * Ethernet Transmit Status Bits (Table 7-16)
+ */
+
+#define M_DMA_ETHTX_SOP	    	    _SB_MAKEMASK1(63)
+
+/* 
+ * Ethernet Transmit Options (Table 7-17)
+ */
+
+#define K_DMA_ETHTX_NOTSOP          _SB_MAKE64(0x00)
+#define K_DMA_ETHTX_APPENDCRC       _SB_MAKE64(0x01)
+#define K_DMA_ETHTX_REPLACECRC      _SB_MAKE64(0x02)
+#define K_DMA_ETHTX_APPENDCRC_APPENDPAD _SB_MAKE64(0x03)
+#define K_DMA_ETHTX_APPENDVLAN_REPLACECRC _SB_MAKE64(0x04)
+#define K_DMA_ETHTX_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x05)
+#define K_DMA_ETHTX_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x6)
+#define K_DMA_ETHTX_NOMODS          _SB_MAKE64(0x07)
+#define K_DMA_ETHTX_RESERVED1       _SB_MAKE64(0x08)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC _SB_MAKE64(0x09)
+#define K_DMA_ETHTX_REPLACESADDR_REPLACECRC _SB_MAKE64(0x0A)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC_APPENDPAD _SB_MAKE64(0x0B)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDVLAN_REPLACECRC _SB_MAKE64(0x0C)
+#define K_DMA_ETHTX_REPLACESADDR_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x0D)
+#define K_DMA_ETHTX_REPLACESADDR_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x0E)
+#define K_DMA_ETHTX_RESERVED2       _SB_MAKE64(0x0F)
+
+/*
+ * Serial Receive Options (Table 7-18)
+ */
+#define M_DMA_SERRX_CRC_ERROR       _SB_MAKEMASK1(56)
+#define M_DMA_SERRX_ABORT           _SB_MAKEMASK1(57)
+#define M_DMA_SERRX_OCTET_ERROR     _SB_MAKEMASK1(58)
+#define M_DMA_SERRX_LONGFRAME_ERROR _SB_MAKEMASK1(59)
+#define M_DMA_SERRX_SHORTFRAME_ERROR _SB_MAKEMASK1(60)
+#define M_DMA_SERRX_OVERRUN_ERROR   _SB_MAKEMASK1(61)
+#define M_DMA_SERRX_GOOD            _SB_MAKEMASK1(62)
+#define M_DMA_SERRX_SOP             _SB_MAKEMASK1(63)
+
+/*
+ * Serial Transmit Status Bits (Table 7-20)
+ */
+
+#define M_DMA_SERTX_FLAG	    _SB_MAKEMASK1(63)
+
+/*
+ * Serial Transmit Options (Table 7-21)
+ */
+
+#define K_DMA_SERTX_RESERVED        _SB_MAKEMASK1(0)
+#define K_DMA_SERTX_APPENDCRC       _SB_MAKEMASK1(1)
+#define K_DMA_SERTX_APPENDPAD       _SB_MAKEMASK1(2)
+#define K_DMA_SERTX_ABORT           _SB_MAKEMASK1(3)
+
+
+/*  *********************************************************************
+    *  Data Mover Registers
+    ********************************************************************* */
+
+/* 
+ * Data Mover Descriptor Base Address Register (Table 7-22)
+ * Register: DM_DSCR_BASE_0
+ * Register: DM_DSCR_BASE_1
+ * Register: DM_DSCR_BASE_2
+ * Register: DM_DSCR_BASE_3
+ */
+
+#define M_DM_DSCR_BASE_MBZ          _SB_MAKEMASK(3,0)
+
+/*  Note: Just mask the base address and then OR it in. */
+#define S_DM_DSCR_BASE_ADDR         _SB_MAKE64(3)
+#define M_DM_DSCR_BASE_ADDR         _SB_MAKEMASK(36,S_DM_DSCR_BASE_ADDR)
+
+#define S_DM_DSCR_BASE_RINGSZ       _SB_MAKE64(40)
+#define M_DM_DSCR_BASE_RINGSZ       _SB_MAKEMASK(16,S_DM_DSCR_BASE_RINGSZ)
+#define V_DM_DSCR_BASE_RINGSZ(x)    _SB_MAKEVALUE(x,S_DM_DSCR_BASE_RINGSZ)
+#define G_DM_DSCR_BASE_RINGSZ(x)    _SB_GETVALUE(x,S_DM_DSCR_BASE_RINGSZ,M_DM_DSCR_BASE_RINGSZ)
+
+#define S_DM_DSCR_BASE_PRIORITY     _SB_MAKE64(56)
+#define M_DM_DSCR_BASE_PRIORITY     _SB_MAKEMASK(3,S_DM_DSCR_BASE_PRIORITY)
+#define V_DM_DSCR_BASE_PRIORITY(x)  _SB_MAKEVALUE(x,S_DM_DSCR_BASE_PRIORITY)
+#define G_DM_DSCR_BASE_PRIORITY(x)  _SB_GETVALUE(x,S_DM_DSCR_BASE_PRIORITY,M_DM_DSCR_BASE_PRIORITY)
+
+#define K_DM_DSCR_BASE_PRIORITY_1   0
+#define K_DM_DSCR_BASE_PRIORITY_2   1
+#define K_DM_DSCR_BASE_PRIORITY_4   2
+#define K_DM_DSCR_BASE_PRIORITY_8   3
+#define K_DM_DSCR_BASE_PRIORITY_16  4
+
+#define M_DM_DSCR_BASE_ACTIVE       _SB_MAKEMASK1(59)
+#define M_DM_DSCR_BASE_INTERRUPT    _SB_MAKEMASK1(60)
+#define M_DM_DSCR_BASE_RESET        _SB_MAKEMASK1(61)	/* write register */
+#define M_DM_DSCR_BASE_ERROR        _SB_MAKEMASK1(61)	/* read register */
+#define M_DM_DSCR_BASE_ABORT        _SB_MAKEMASK1(62)
+#define M_DM_DSCR_BASE_ENABL        _SB_MAKEMASK1(63)
+
+/* 
+ * Data Mover Descriptor Count Register (Table 7-25)
+ */
+
+/* no bitfields */
+
+/*
+ * Data Mover Current Descriptor Address (Table 7-24)
+ * Register: DM_CUR_DSCR_ADDR_0
+ * Register: DM_CUR_DSCR_ADDR_1
+ * Register: DM_CUR_DSCR_ADDR_2
+ * Register: DM_CUR_DSCR_ADDR_3
+ */
+
+#define S_DM_CUR_DSCR_DSCR_ADDR     _SB_MAKE64(0)
+#define M_DM_CUR_DSCR_DSCR_ADDR     _SB_MAKEMASK(40,S_DM_CUR_DSCR_DSCR_ADDR)
+
+#define S_DM_CUR_DSCR_DSCR_COUNT    _SB_MAKE64(48)
+#define M_DM_CUR_DSCR_DSCR_COUNT    _SB_MAKEMASK(16,S_DM_CUR_DSCR_DSCR_COUNT)
+#define V_DM_CUR_DSCR_DSCR_COUNT(r) _SB_MAKEVALUE(r,S_DM_CUR_DSCR_DSCR_COUNT)
+#define G_DM_CUR_DSCR_DSCR_COUNT(r) _SB_GETVALUE(r,S_DM_CUR_DSCR_DSCR_COUNT,\
+                                     M_DM_CUR_DSCR_DSCR_COUNT)
+
+/*
+ * Data Mover Descriptor Doubleword "A"  (Table 7-26)
+ */
+
+#define S_DM_DSCRA_DST_ADDR         _SB_MAKE64(0)
+#define M_DM_DSCRA_DST_ADDR         _SB_MAKEMASK(40,S_DM_DSCRA_DST_ADDR)
+
+#define M_DM_DSCRA_UN_DEST          _SB_MAKEMASK1(40)
+#define M_DM_DSCRA_UN_SRC           _SB_MAKEMASK1(41)
+#define M_DM_DSCRA_INTERRUPT        _SB_MAKEMASK1(42)
+#define M_DM_DSCRA_THROTTLE         _SB_MAKEMASK1(43)
+
+#define S_DM_DSCRA_DIR_DEST         _SB_MAKE64(44)
+#define M_DM_DSCRA_DIR_DEST         _SB_MAKEMASK(2,S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST(x)      _SB_MAKEVALUE(x,S_DM_DSCRA_DIR_DEST)
+#define G_DM_DSCRA_DIR_DEST(x)      _SB_GETVALUE(x,S_DM_DSCRA_DIR_DEST,M_DM_DSCRA_DIR_DEST)
+
+#define K_DM_DSCRA_DIR_DEST_INCR    0
+#define K_DM_DSCRA_DIR_DEST_DECR    1
+#define K_DM_DSCRA_DIR_DEST_CONST   2
+
+#define V_DM_DSCRA_DIR_DEST_INCR    _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_INCR,S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST_DECR    _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_DECR,S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST_CONST   _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_CONST,S_DM_DSCRA_DIR_DEST)
+
+#define S_DM_DSCRA_DIR_SRC          _SB_MAKE64(46)
+#define M_DM_DSCRA_DIR_SRC          _SB_MAKEMASK(2,S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC(x)       _SB_MAKEVALUE(x,S_DM_DSCRA_DIR_SRC)
+#define G_DM_DSCRA_DIR_SRC(x)       _SB_GETVALUE(x,S_DM_DSCRA_DIR_SRC,M_DM_DSCRA_DIR_SRC)
+
+#define K_DM_DSCRA_DIR_SRC_INCR     0
+#define K_DM_DSCRA_DIR_SRC_DECR     1
+#define K_DM_DSCRA_DIR_SRC_CONST    2
+
+#define V_DM_DSCRA_DIR_SRC_INCR     _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_INCR,S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC_DECR     _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_DECR,S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC_CONST    _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_CONST,S_DM_DSCRA_DIR_SRC)
+
+
+#define M_DM_DSCRA_ZERO_MEM         _SB_MAKEMASK1(48)
+#define M_DM_DSCRA_PREFETCH         _SB_MAKEMASK1(49)
+#define M_DM_DSCRA_L2C_DEST         _SB_MAKEMASK1(50)
+#define M_DM_DSCRA_L2C_SRC          _SB_MAKEMASK1(51)
+
+#define M_DM_DSCRA_RESERVED2        _SB_MAKEMASK(12,52)
+
+/*
+ * Data Mover Descriptor Doubleword "B"  (Table 7-25)
+ */
+
+#define S_DM_DSCRB_SRC_ADDR         _SB_MAKE64(0)
+#define M_DM_DSCRB_SRC_ADDR         _SB_MAKEMASK(40,S_DM_DSCRB_SRC_ADDR)
+
+#define S_DM_DSCRB_SRC_LENGTH       _SB_MAKE64(40)
+#define M_DM_DSCRB_SRC_LENGTH       _SB_MAKEMASK(20,S_DM_DSCRB_SRC_LENGTH)
+#define V_DM_DSCRB_SRC_LENGTH(x)    _SB_MAKEVALUE(x,S_DM_DSCRB_SRC_LENGTH)
+#define G_DM_DSCRB_SRC_LENGTH(x)    _SB_GETVALUE(x,S_DM_DSCRB_SRC_LENGTH,M_DM_DSCRB_SRC_LENGTH)
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_genbus.h linux/include/asm-mips64/sibyte/sb1250_genbus.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_genbus.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_genbus.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,245 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Generic Bus Constants                     File: sb1250_genbus.h
+    *  
+    *  This module contains constants and macros useful for 
+    *  manipulating the SB1250's Generic Bus interface
+    *  
+    *  SB1250 specification level:  01/02/2002
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_GENBUS_H
+#define _SB1250_GENBUS_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Generic Bus Region Configuration Registers (Table 11-4)
+ */
+
+#define M_IO_RDY_ACTIVE		_SB_MAKEMASK1(0)
+#define M_IO_ENA_RDY		_SB_MAKEMASK1(1)
+
+#define S_IO_WIDTH_SEL		2
+#define M_IO_WIDTH_SEL		_SB_MAKEMASK(2,S_IO_WIDTH_SEL)
+#define K_IO_WIDTH_SEL_1	0
+#define K_IO_WIDTH_SEL_2	1
+#define K_IO_WIDTH_SEL_4	3
+#define V_IO_WIDTH_SEL(x)	_SB_MAKEVALUE(x,S_IO_WIDTH_SEL)
+#define G_IO_WIDTH_SEL(x)	_SB_GETVALUE(x,S_IO_WIDTH_SEL,M_IO_WIDTH_SEL)
+
+#define M_IO_PARITY_ENA		_SB_MAKEMASK1(4)
+#define M_IO_PARITY_ODD		_SB_MAKEMASK1(6)
+#define M_IO_NONMUX		_SB_MAKEMASK1(7)
+
+#define S_IO_TIMEOUT		8
+#define M_IO_TIMEOUT		_SB_MAKEMASK(8,S_IO_TIMEOUT)
+#define V_IO_TIMEOUT(x)		_SB_MAKEVALUE(x,S_IO_TIMEOUT)
+#define G_IO_TIMEOUT(x)		_SB_GETVALUE(x,S_IO_TIMEOUT,M_IO_TIMEOUT)
+
+/*
+ * Generic Bus Region Size register (Table 11-5)
+ */
+
+#define S_IO_MULT_SIZE		0
+#define M_IO_MULT_SIZE		_SB_MAKEMASK(12,S_IO_MULT_SIZE)
+#define V_IO_MULT_SIZE(x)	_SB_MAKEVALUE(x,S_IO_MULT_SIZE)
+#define G_IO_MULT_SIZE(x)	_SB_GETVALUE(x,S_IO_MULT_SIZE,M_IO_MULT_SIZE)
+
+#define S_IO_REGSIZE		16	 /* # bits to shift size for this reg */
+
+/*
+ * Generic Bus Region Address (Table 11-6)
+ */
+
+#define S_IO_START_ADDR		0
+#define M_IO_START_ADDR		_SB_MAKEMASK(14,S_IO_START_ADDR)
+#define V_IO_START_ADDR(x)	_SB_MAKEVALUE(x,S_IO_START_ADDR)
+#define G_IO_START_ADDR(x)	_SB_GETVALUE(x,S_IO_START_ADDR,M_IO_START_ADDR)
+
+#define S_IO_ADDRBASE		16	 /* # bits to shift addr for this reg */
+
+/*
+ * Generic Bus Region 0 Timing Registers (Table 11-7)
+ */
+
+#define S_IO_ALE_WIDTH		0
+#define M_IO_ALE_WIDTH		_SB_MAKEMASK(3,S_IO_ALE_WIDTH)
+#define V_IO_ALE_WIDTH(x)	_SB_MAKEVALUE(x,S_IO_ALE_WIDTH)
+#define G_IO_ALE_WIDTH(x)	_SB_GETVALUE(x,S_IO_ALE_WIDTH,M_IO_ALE_WIDTH)
+
+#define S_IO_ALE_TO_CS		4
+#define M_IO_ALE_TO_CS		_SB_MAKEMASK(2,S_IO_ALE_TO_CS)
+#define V_IO_ALE_TO_CS(x)	_SB_MAKEVALUE(x,S_IO_ALE_TO_CS)
+#define G_IO_ALE_TO_CS(x)	_SB_GETVALUE(x,S_IO_ALE_TO_CS,M_IO_ALE_TO_CS)
+
+#define S_IO_CS_WIDTH		8
+#define M_IO_CS_WIDTH		_SB_MAKEMASK(5,S_IO_CS_WIDTH)
+#define V_IO_CS_WIDTH(x)	_SB_MAKEVALUE(x,S_IO_CS_WIDTH)
+#define G_IO_CS_WIDTH(x)	_SB_GETVALUE(x,S_IO_CS_WIDTH,M_IO_CS_WIDTH)
+
+#define S_IO_RDY_SMPLE		13
+#define M_IO_RDY_SMPLE		_SB_MAKEMASK(3,S_IO_RDY_SMPLE)
+#define V_IO_RDY_SMPLE(x)	_SB_MAKEVALUE(x,S_IO_RDY_SMPLE)
+#define G_IO_RDY_SMPLE(x)	_SB_GETVALUE(x,S_IO_RDY_SMPLE,M_IO_RDY_SMPLE)
+
+
+/*
+ * Generic Bus Timing 1 Registers (Table 11-8)
+ */
+
+#define S_IO_ALE_TO_WRITE	0
+#define M_IO_ALE_TO_WRITE	_SB_MAKEMASK(3,S_IO_ALE_TO_WRITE)
+#define V_IO_ALE_TO_WRITE(x)	_SB_MAKEVALUE(x,S_IO_ALE_TO_WRITE)
+#define G_IO_ALE_TO_WRITE(x)	_SB_GETVALUE(x,S_IO_ALE_TO_WRITE,M_IO_ALE_TO_WRITE)
+
+#define S_IO_WRITE_WIDTH	4
+#define M_IO_WRITE_WIDTH	_SB_MAKEMASK(4,S_IO_WRITE_WIDTH)
+#define V_IO_WRITE_WIDTH(x)	_SB_MAKEVALUE(x,S_IO_WRITE_WIDTH)
+#define G_IO_WRITE_WIDTH(x)	_SB_GETVALUE(x,S_IO_WRITE_WIDTH,M_IO_WRITE_WIDTH)
+
+#define S_IO_IDLE_CYCLE		8
+#define M_IO_IDLE_CYCLE		_SB_MAKEMASK(4,S_IO_IDLE_CYCLE)
+#define V_IO_IDLE_CYCLE(x)	_SB_MAKEVALUE(x,S_IO_IDLE_CYCLE)
+#define G_IO_IDLE_CYCLE(x)	_SB_GETVALUE(x,S_IO_IDLE_CYCLE,M_IO_IDLE_CYCLE)
+
+#define S_IO_OE_TO_CS		12
+#define M_IO_OE_TO_CS		_SB_MAKEMASK(2,S_IO_OE_TO_CS)
+#define V_IO_OE_TO_CS(x)	_SB_MAKEVALUE(x,S_IO_OE_TO_CS)
+#define G_IO_OE_TO_CS(x)	_SB_GETVALUE(x,S_IO_OE_TO_CS,M_IO_OE_TO_CS)
+
+#define S_IO_CS_TO_OE		14
+#define M_IO_CS_TO_OE		_SB_MAKEMASK(2,S_IO_CS_TO_OE)
+#define V_IO_CS_TO_OE(x)	_SB_MAKEVALUE(x,S_IO_CS_TO_OE)
+#define G_IO_CS_TO_OE(x)	_SB_GETVALUE(x,S_IO_CS_TO_OE,M_IO_CS_TO_OE)
+
+/*
+ * Generic Bus Interrupt Status Register (Table 11-9)
+ */
+
+#define M_IO_CS_ERR_INT		_SB_MAKEMASK(0,8)
+#define M_IO_CS0_ERR_INT	_SB_MAKEMASK1(0)
+#define M_IO_CS1_ERR_INT	_SB_MAKEMASK1(1)
+#define M_IO_CS2_ERR_INT	_SB_MAKEMASK1(2)
+#define M_IO_CS3_ERR_INT	_SB_MAKEMASK1(3)
+#define M_IO_CS4_ERR_INT	_SB_MAKEMASK1(4)
+#define M_IO_CS5_ERR_INT	_SB_MAKEMASK1(5)
+#define M_IO_CS6_ERR_INT	_SB_MAKEMASK1(6)
+#define M_IO_CS7_ERR_INT	_SB_MAKEMASK1(7)
+
+#define M_IO_RD_PAR_INT		_SB_MAKEMASK1(9)
+#define M_IO_TIMEOUT_INT	_SB_MAKEMASK1(10)
+#define M_IO_ILL_ADDR_INT	_SB_MAKEMASK1(11)
+#define M_IO_MULT_CS_INT	_SB_MAKEMASK1(12)
+
+/*
+ * PCMCIA configuration register (Table 12-6)
+ */
+
+#define M_PCMCIA_CFG_ATTRMEM	_SB_MAKEMASK1(0)
+#define M_PCMCIA_CFG_3VEN	_SB_MAKEMASK1(1)
+#define M_PCMCIA_CFG_5VEN	_SB_MAKEMASK1(2)
+#define M_PCMCIA_CFG_VPPEN	_SB_MAKEMASK1(3)
+#define M_PCMCIA_CFG_RESET	_SB_MAKEMASK1(4)
+#define M_PCMCIA_CFG_APWRONEN	_SB_MAKEMASK1(5)
+#define M_PCMCIA_CFG_CDMASK	_SB_MAKEMASK1(6)
+#define M_PCMCIA_CFG_WPMASK	_SB_MAKEMASK1(7)
+#define M_PCMCIA_CFG_RDYMASK	_SB_MAKEMASK1(8)
+#define M_PCMCIA_CFG_PWRCTL	_SB_MAKEMASK1(9)
+
+/*
+ * PCMCIA status register (Table 12-7)
+ */
+
+#define M_PCMCIA_STATUS_CD1	_SB_MAKEMASK1(0)
+#define M_PCMCIA_STATUS_CD2	_SB_MAKEMASK1(1)
+#define M_PCMCIA_STATUS_VS1	_SB_MAKEMASK1(2)
+#define M_PCMCIA_STATUS_VS2	_SB_MAKEMASK1(3)
+#define M_PCMCIA_STATUS_WP	_SB_MAKEMASK1(4)
+#define M_PCMCIA_STATUS_RDY	_SB_MAKEMASK1(5)
+#define M_PCMCIA_STATUS_3VEN	_SB_MAKEMASK1(6)
+#define M_PCMCIA_STATUS_5VEN	_SB_MAKEMASK1(7)
+#define M_PCMCIA_STATUS_CDCHG	_SB_MAKEMASK1(8)
+#define M_PCMCIA_STATUS_WPCHG	_SB_MAKEMASK1(9)
+#define M_PCMCIA_STATUS_RDYCHG	_SB_MAKEMASK1(10)
+
+/*
+ * GPIO Interrupt Type Register (table 13-3)
+ */
+
+#define K_GPIO_INTR_DISABLE	0
+#define K_GPIO_INTR_EDGE	1
+#define K_GPIO_INTR_LEVEL	2
+#define K_GPIO_INTR_SPLIT	3
+
+#define S_GPIO_INTR_TYPEX(n)	(((n)/2)*2)
+#define M_GPIO_INTR_TYPEX(n)	_SB_MAKEMASK(2,S_GPIO_INTR_TYPEX(n))
+#define V_GPIO_INTR_TYPEX(n,x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPEX(n))
+#define G_GPIO_INTR_TYPEX(n,x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPEX(n),M_GPIO_INTR_TYPEX(n))
+
+#define S_GPIO_INTR_TYPE0	0
+#define M_GPIO_INTR_TYPE0	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE0)
+#define V_GPIO_INTR_TYPE0(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE0)
+#define G_GPIO_INTR_TYPE0(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE0,M_GPIO_INTR_TYPE0)
+
+#define S_GPIO_INTR_TYPE2	2
+#define M_GPIO_INTR_TYPE2	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE2)
+#define V_GPIO_INTR_TYPE2(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE2)
+#define G_GPIO_INTR_TYPE2(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE2,M_GPIO_INTR_TYPE2)
+
+#define S_GPIO_INTR_TYPE4	4
+#define M_GPIO_INTR_TYPE4	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE4)
+#define V_GPIO_INTR_TYPE4(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE4)
+#define G_GPIO_INTR_TYPE4(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE4,M_GPIO_INTR_TYPE4)
+
+#define S_GPIO_INTR_TYPE6	6
+#define M_GPIO_INTR_TYPE6	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE6)
+#define V_GPIO_INTR_TYPE6(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE6)
+#define G_GPIO_INTR_TYPE6(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE6,M_GPIO_INTR_TYPE6)
+
+#define S_GPIO_INTR_TYPE8	8
+#define M_GPIO_INTR_TYPE8	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE8)
+#define V_GPIO_INTR_TYPE8(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE8)
+#define G_GPIO_INTR_TYPE8(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE8,M_GPIO_INTR_TYPE8)
+
+#define S_GPIO_INTR_TYPE10	10
+#define M_GPIO_INTR_TYPE10	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE10)
+#define V_GPIO_INTR_TYPE10(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE10)
+#define G_GPIO_INTR_TYPE10(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE10,M_GPIO_INTR_TYPE10)
+
+#define S_GPIO_INTR_TYPE12	12
+#define M_GPIO_INTR_TYPE12	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE12)
+#define V_GPIO_INTR_TYPE12(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE12)
+#define G_GPIO_INTR_TYPE12(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE12,M_GPIO_INTR_TYPE12)
+
+#define S_GPIO_INTR_TYPE14	14
+#define M_GPIO_INTR_TYPE14	_SB_MAKEMASK(2,S_GPIO_INTR_TYPE14)
+#define V_GPIO_INTR_TYPE14(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE14)
+#define G_GPIO_INTR_TYPE14(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE14,M_GPIO_INTR_TYPE14)
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_int.h linux/include/asm-mips64/sibyte/sb1250_int.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_int.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_int.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,239 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Interrupt Mapper definitions		File: sb1250_int.h
+    *  
+    *  This module contains constants for manipulating the SB1250's
+    *  interrupt mapper and definitions for the interrupt sources.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_INT_H
+#define _SB1250_INT_H
+
+#include "sb1250_defs.h"
+
+/*  *********************************************************************
+    *  Interrupt Mapper Constants
+    ********************************************************************* */
+
+/*
+ * Interrupt sources (Table 4-8, UM 0.2)
+ * 
+ * First, the interrupt numbers.
+ */
+
+#define K_INT_WATCHDOG_TIMER_0      0
+#define K_INT_WATCHDOG_TIMER_1      1
+#define K_INT_TIMER_0               2
+#define K_INT_TIMER_1               3
+#define K_INT_TIMER_2               4
+#define K_INT_TIMER_3               5
+#define K_INT_SMB_0                 6
+#define K_INT_SMB_1                 7
+#define K_INT_UART_0                8
+#define K_INT_UART_1                9
+#define K_INT_SER_0                 10
+#define K_INT_SER_1                 11
+#define K_INT_PCMCIA                12
+#define K_INT_ADDR_TRAP             13
+#define K_INT_PERF_CNT              14
+#define K_INT_TRACE_FREEZE          15
+#define K_INT_BAD_ECC               16
+#define K_INT_COR_ECC               17
+#define K_INT_IO_BUS                18
+#define K_INT_MAC_0                 19
+#define K_INT_MAC_1                 20
+#define K_INT_MAC_2                 21
+#define K_INT_DM_CH_0               22
+#define K_INT_DM_CH_1               23
+#define K_INT_DM_CH_2               24
+#define K_INT_DM_CH_3               25
+#define K_INT_MBOX_0                26
+#define K_INT_MBOX_1                27
+#define K_INT_MBOX_2                28
+#define K_INT_MBOX_3                29
+#define K_INT_SPARE_0               30
+#define K_INT_SPARE_1               31
+#define K_INT_GPIO_0                32
+#define K_INT_GPIO_1                33
+#define K_INT_GPIO_2                34
+#define K_INT_GPIO_3                35
+#define K_INT_GPIO_4                36
+#define K_INT_GPIO_5                37
+#define K_INT_GPIO_6                38
+#define K_INT_GPIO_7                39
+#define K_INT_GPIO_8                40
+#define K_INT_GPIO_9                41
+#define K_INT_GPIO_10               42
+#define K_INT_GPIO_11               43
+#define K_INT_GPIO_12               44
+#define K_INT_GPIO_13               45
+#define K_INT_GPIO_14               46
+#define K_INT_GPIO_15               47
+#define K_INT_LDT_FATAL             48
+#define K_INT_LDT_NONFATAL          49
+#define K_INT_LDT_SMI               50
+#define K_INT_LDT_NMI               51
+#define K_INT_LDT_INIT              52
+#define K_INT_LDT_STARTUP           53
+#define K_INT_LDT_EXT               54
+#define K_INT_PCI_ERROR             55
+#define K_INT_PCI_INTA              56
+#define K_INT_PCI_INTB              57
+#define K_INT_PCI_INTC              58
+#define K_INT_PCI_INTD              59
+#define K_INT_SPARE_2               60
+#define K_INT_SPARE_3               61
+#define K_INT_SPARE_4               62
+#define K_INT_SPARE_5               63
+
+/*
+ * Mask values for each interrupt
+ */
+
+#define M_INT_WATCHDOG_TIMER_0      _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_0)
+#define M_INT_WATCHDOG_TIMER_1      _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_1)
+#define M_INT_TIMER_0               _SB_MAKEMASK1(K_INT_TIMER_0)
+#define M_INT_TIMER_1               _SB_MAKEMASK1(K_INT_TIMER_1)
+#define M_INT_TIMER_2               _SB_MAKEMASK1(K_INT_TIMER_2)
+#define M_INT_TIMER_3               _SB_MAKEMASK1(K_INT_TIMER_3)
+#define M_INT_SMB_0                 _SB_MAKEMASK1(K_INT_SMB_0)
+#define M_INT_SMB_1                 _SB_MAKEMASK1(K_INT_SMB_1)
+#define M_INT_UART_0                _SB_MAKEMASK1(K_INT_UART_0)
+#define M_INT_UART_1                _SB_MAKEMASK1(K_INT_UART_1)
+#define M_INT_SER_0                 _SB_MAKEMASK1(K_INT_SER_0)
+#define M_INT_SER_1                 _SB_MAKEMASK1(K_INT_SER_1)
+#define M_INT_PCMCIA                _SB_MAKEMASK1(K_INT_PCMCIA)
+#define M_INT_ADDR_TRAP             _SB_MAKEMASK1(K_INT_ADDR_TRAP)
+#define M_INT_PERF_CNT              _SB_MAKEMASK1(K_INT_PERF_CNT)
+#define M_INT_TRACE_FREEZE          _SB_MAKEMASK1(K_INT_TRACE_FREEZE)
+#define M_INT_BAD_ECC               _SB_MAKEMASK1(K_INT_BAD_ECC)
+#define M_INT_COR_ECC               _SB_MAKEMASK1(K_INT_COR_ECC)
+#define M_INT_IO_BUS                _SB_MAKEMASK1(K_INT_IO_BUS)
+#define M_INT_MAC_0                 _SB_MAKEMASK1(K_INT_MAC_0)
+#define M_INT_MAC_1                 _SB_MAKEMASK1(K_INT_MAC_1)
+#define M_INT_MAC_2                 _SB_MAKEMASK1(K_INT_MAC_2)
+#define M_INT_DM_CH_0               _SB_MAKEMASK1(K_INT_DM_CH_0)
+#define M_INT_DM_CH_1               _SB_MAKEMASK1(K_INT_DM_CH_1)
+#define M_INT_DM_CH_2               _SB_MAKEMASK1(K_INT_DM_CH_2)
+#define M_INT_DM_CH_3               _SB_MAKEMASK1(K_INT_DM_CH_3)
+#define M_INT_MBOX_0                _SB_MAKEMASK1(K_INT_MBOX_0)
+#define M_INT_MBOX_1                _SB_MAKEMASK1(K_INT_MBOX_1)
+#define M_INT_MBOX_2                _SB_MAKEMASK1(K_INT_MBOX_2)
+#define M_INT_MBOX_3                _SB_MAKEMASK1(K_INT_MBOX_3)
+#define M_INT_SPARE_0               _SB_MAKEMASK1(K_INT_SPARE_0)
+#define M_INT_SPARE_1               _SB_MAKEMASK1(K_INT_SPARE_1)
+#define M_INT_GPIO_0                _SB_MAKEMASK1(K_INT_GPIO_0)
+#define M_INT_GPIO_1                _SB_MAKEMASK1(K_INT_GPIO_1)
+#define M_INT_GPIO_2                _SB_MAKEMASK1(K_INT_GPIO_2)
+#define M_INT_GPIO_3                _SB_MAKEMASK1(K_INT_GPIO_3)
+#define M_INT_GPIO_4                _SB_MAKEMASK1(K_INT_GPIO_4)
+#define M_INT_GPIO_5                _SB_MAKEMASK1(K_INT_GPIO_5)
+#define M_INT_GPIO_6                _SB_MAKEMASK1(K_INT_GPIO_6)
+#define M_INT_GPIO_7                _SB_MAKEMASK1(K_INT_GPIO_7)
+#define M_INT_GPIO_8                _SB_MAKEMASK1(K_INT_GPIO_8)
+#define M_INT_GPIO_9                _SB_MAKEMASK1(K_INT_GPIO_9)
+#define M_INT_GPIO_10               _SB_MAKEMASK1(K_INT_GPIO_10)
+#define M_INT_GPIO_11               _SB_MAKEMASK1(K_INT_GPIO_11)
+#define M_INT_GPIO_12               _SB_MAKEMASK1(K_INT_GPIO_12)
+#define M_INT_GPIO_13               _SB_MAKEMASK1(K_INT_GPIO_13)
+#define M_INT_GPIO_14               _SB_MAKEMASK1(K_INT_GPIO_14)
+#define M_INT_GPIO_15               _SB_MAKEMASK1(K_INT_GPIO_15)
+#define M_INT_LDT_FATAL             _SB_MAKEMASK1(K_INT_LDT_FATAL)
+#define M_INT_LDT_NONFATAL          _SB_MAKEMASK1(K_INT_LDT_NONFATAL)
+#define M_INT_LDT_SMI               _SB_MAKEMASK1(K_INT_LDT_SMI)
+#define M_INT_LDT_NMI               _SB_MAKEMASK1(K_INT_LDT_NMI)
+#define M_INT_LDT_INIT              _SB_MAKEMASK1(K_INT_LDT_INIT)
+#define M_INT_LDT_STARTUP           _SB_MAKEMASK1(K_INT_LDT_STARTUP)
+#define M_INT_LDT_EXT               _SB_MAKEMASK1(K_INT_LDT_EXT)
+#define M_INT_PCI_ERROR             _SB_MAKEMASK1(K_INT_PCI_ERROR)
+#define M_INT_PCI_INTA              _SB_MAKEMASK1(K_INT_PCI_INTA)
+#define M_INT_PCI_INTB              _SB_MAKEMASK1(K_INT_PCI_INTB)
+#define M_INT_PCI_INTC              _SB_MAKEMASK1(K_INT_PCI_INTC)
+#define M_INT_PCI_INTD              _SB_MAKEMASK1(K_INT_PCI_INTD)
+#define M_INT_SPARE_2               _SB_MAKEMASK1(K_INT_SPARE_2)
+#define M_INT_SPARE_3               _SB_MAKEMASK1(K_INT_SPARE_3)
+#define M_INT_SPARE_4               _SB_MAKEMASK1(K_INT_SPARE_4)
+#define M_INT_SPARE_5               _SB_MAKEMASK1(K_INT_SPARE_5)
+
+/*
+ * Interrupt mappings
+ */
+
+#define K_INT_MAP_I0	0		/* interrupt pins on processor */
+#define K_INT_MAP_I1	1
+#define K_INT_MAP_I2	2
+#define K_INT_MAP_I3	3
+#define K_INT_MAP_I4	4
+#define K_INT_MAP_I5	5
+#define K_INT_MAP_NMI	6		/* nonmaskable */
+#define K_INT_MAP_DINT	7		/* debug interrupt */
+
+/*
+ * LDT Interrupt Set Register (table 4-5)
+ */
+
+#define S_INT_LDT_INTMSG	      0
+#define M_INT_LDT_INTMSG              _SB_MAKEMASK(3,S_INT_LDT_INTMSG)
+#define V_INT_LDT_INTMSG(x)           _SB_MAKEVALUE(x,S_INT_LDT_INTMSG)
+#define G_INT_LDT_INTMSG(x)           _SB_GETVALUE(x,S_INT_LDT_INTMSG,M_INT_LDT_INTMSG)
+
+#define K_INT_LDT_INTMSG_FIXED	      0
+#define K_INT_LDT_INTMSG_ARBITRATED   1
+#define K_INT_LDT_INTMSG_SMI	      2
+#define K_INT_LDT_INTMSG_NMI	      3
+#define K_INT_LDT_INTMSG_INIT	      4
+#define K_INT_LDT_INTMSG_STARTUP      5
+#define K_INT_LDT_INTMSG_EXTINT	      6
+#define K_INT_LDT_INTMSG_RESERVED     7
+
+#define M_INT_LDT_EDGETRIGGER         0
+#define M_INT_LDT_LEVELTRIGGER        _SB_MAKEMASK1(3)
+
+#define M_INT_LDT_PHYSICALDEST        0
+#define M_INT_LDT_LOGICALDEST         _SB_MAKEMASK1(4)
+
+#define S_INT_LDT_INTDEST             5
+#define M_INT_LDT_INTDEST             _SB_MAKEMASK(10,S_INT_LDT_INTDEST)
+#define V_INT_LDT_INTDEST(x)          _SB_MAKEVALUE(x,S_INT_LDT_INTDEST)
+#define G_INT_LDT_INTDEST(x)          _SB_GETVALUE(x,S_INT_LDT_INTDEST,M_INT_LDT_INTDEST)
+
+#define S_INT_LDT_VECTOR              13
+#define M_INT_LDT_VECTOR              _SB_MAKEMASK(8,S_INT_LDT_VECTOR)
+#define V_INT_LDT_VECTOR(x)           _SB_MAKEVALUE(x,S_INT_LDT_VECTOR)
+#define G_INT_LDT_VECTOR(x)           _SB_GETVALUE(x,S_INT_LDT_VECTOR,M_INT_LDT_VECTOR)
+
+/*
+ * Vector format (Table 4-6)
+ */
+
+#define M_LDTVECT_RAISEINT		0x00
+#define M_LDTVECT_RAISEMBOX             0x40
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_io.h linux/include/asm-mips64/sibyte/sb1250_io.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_io.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_io.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,21 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SGI_IO_H
+#define _ASM_SGI_IO_H
+
+#include <asm/addrspace.h>
+
+#define IO_SPACE_BASE K1BASE
+
+/* For Indigo2.  */
+#define IO_SPACE_LIMIT 0xffff
+
+/* XXX ISA specific functions go here here.  */
+
+#endif /* _ASM_SGI_IO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_l2c.h linux/include/asm-mips64/sibyte/sb1250_l2c.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_l2c.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_l2c.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,97 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  L2 Cache constants and macros		File: sb1250_l2c.h
+    *  
+    *  This module contains constants useful for manipulating the
+    *  level 2 cache.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_L2C_H
+#define _SB1250_L2C_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Level 2 Cache Tag register (Table 5-3)
+ */
+
+#define S_L2C_TAG_MBZ               0
+#define M_L2C_TAG_MBZ               _SB_MAKEMASK(5,S_L2C_TAG_MBZ)
+
+#define S_L2C_TAG_INDEX             5
+#define M_L2C_TAG_INDEX             _SB_MAKEMASK(12,S_L2C_TAG_INDEX)
+#define V_L2C_TAG_INDEX(x)          _SB_MAKEVALUE(x,S_L2C_TAG_INDEX)
+#define G_L2C_TAG_INDEX(x)          _SB_GETVALUE(x,S_L2C_TAG_INDEX,M_L2C_TAG_INDEX)
+
+#define S_L2C_TAG_TAG               17
+#define M_L2C_TAG_TAG               _SB_MAKEMASK(23,S_L2C_TAG_TAG)
+#define V_L2C_TAG_TAG(x)            _SB_MAKEVALUE(x,S_L2C_TAG_TAG)
+#define G_L2C_TAG_TAG(x)            _SB_GETVALUE(x,S_L2C_TAG_TAG,M_L2C_TAG_TAG)
+
+#define S_L2C_TAG_ECC               40
+#define M_L2C_TAG_ECC               _SB_MAKEMASK(6,S_L2C_TAG_ECC)
+#define V_L2C_TAG_ECC(x)            _SB_MAKEVALUE(x,S_L2C_TAG_ECC)
+#define G_L2C_TAG_ECC(x)            _SB_GETVALUE(x,S_L2C_TAG_ECC,M_L2C_TAG_ECC)
+
+#define S_L2C_TAG_WAY               46
+#define M_L2C_TAG_WAY               _SB_MAKEMASK(2,S_L2C_TAG_WAY)
+#define V_L2C_TAG_WAY(x)            _SB_MAKEVALUE(x,S_L2C_TAG_WAY)
+#define G_L2C_TAG_WAY(x)            _SB_GETVALUE(x,S_L2C_TAG_WAY,M_L2C_TAG_WAY)
+
+#define M_L2C_TAG_DIRTY             _SB_MAKEMASK1(48)
+#define M_L2C_TAG_VALID             _SB_MAKEMASK1(49)
+
+/*
+ * Format of level 2 cache management address (table 5-2)
+ */
+
+#define S_L2C_MGMT_INDEX            5
+#define M_L2C_MGMT_INDEX            _SB_MAKEMASK(12,S_L2C_MGMT_INDEX)
+#define V_L2C_MGMT_INDEX(x)         _SB_MAKEVALUE(x,S_L2C_MGMT_INDEX)
+#define G_L2C_MGMT_INDEX(x)         _SB_GETVALUE(x,S_L2C_MGMT_INDEX,M_L2C_MGMT_INDEX)
+
+#define S_L2C_MGMT_WAY              17
+#define M_L2C_MGMT_WAY              _SB_MAKEMASK(2,S_L2C_MGMT_WAY)
+#define V_L2C_MGMT_WAY(x)           _SB_MAKEVALUE(x,S_L2C_MGMT_WAY)
+#define G_L2C_MGMT_WAY(x)           _SB_GETVALUE(x,S_L2C_MGMT_WAY,M_L2C_MGMT_WAY)
+
+#define S_L2C_MGMT_TAG              21
+#define M_L2C_MGMT_TAG              _SB_MAKEMASK(6,S_L2C_MGMT_TAG)
+#define V_L2C_MGMT_TAG(x)           _SB_MAKEVALUE(x,S_L2C_MGMT_TAG)
+#define G_L2C_MGMT_TAG(x)           _SB_GETVALUE(x,S_L2C_MGMT_TAG,M_L2C_MGMT_TAG)
+
+#define M_L2C_MGMT_DIRTY            _SB_MAKEMASK1(19)
+#define M_L2C_MGMT_VALID            _SB_MAKEMASK1(20)
+
+#define A_L2C_MGMT_TAG_BASE         0x00D0000000
+
+#define L2C_ENTRIES_PER_WAY       4096
+#define L2C_NUM_WAYS              4
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_ldt.h linux/include/asm-mips64/sibyte/sb1250_ldt.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_ldt.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_ldt.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,402 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  LDT constants				File: sb1250_ldt.h
+    *  
+    *  This module contains constants and macros to describe 
+    *  the LDT interface on the SB1250.  
+    *  
+    *  SB1250 specification level:  0.2 plus errata
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_LDT_H
+#define _SB1250_LDT_H
+
+#include "sb1250_defs.h"
+
+#define K_LDT_VENDOR_SIBYTE	0x166D
+#define K_LDT_DEVICE_SB1250	0x0002
+
+/*
+ * LDT Interface Type 1 (bridge) configuration header
+ */
+
+#define R_LDT_TYPE1_DEVICEID	0x0000
+#define R_LDT_TYPE1_CMDSTATUS	0x0004
+#define R_LDT_TYPE1_CLASSREV	0x0008
+#define R_LDT_TYPE1_DEVHDR	0x000C
+#define R_LDT_TYPE1_BAR0	0x0010	/* not used */
+#define R_LDT_TYPE1_BAR1	0x0014	/* not used */
+
+#define R_LDT_TYPE1_BUSID	0x0018	/* bus ID register */
+#define R_LDT_TYPE1_SECSTATUS	0x001C	/* secondary status / I/O base/limit */
+#define R_LDT_TYPE1_MEMLIMIT	0x0020
+#define R_LDT_TYPE1_PREFETCH	0x0024
+#define R_LDT_TYPE1_PREF_BASE	0x0028
+#define R_LDT_TYPE1_PREF_LIMIT	0x002C
+#define R_LDT_TYPE1_IOLIMIT	0x0030
+#define R_LDT_TYPE1_CAPPTR	0x0034
+#define R_LDT_TYPE1_ROMADDR	0x0038
+#define R_LDT_TYPE1_BRCTL	0x003C
+#define R_LDT_TYPE1_CMD		0x0040
+#define R_LDT_TYPE1_LINKCTRL	0x0044
+#define R_LDT_TYPE1_LINKFREQ	0x0048
+#define R_LDT_TYPE1_RESERVED1	0x004C
+#define R_LDT_TYPE1_SRICMD	0x0050
+#define R_LDT_TYPE1_SRITXNUM	0x0054
+#define R_LDT_TYPE1_SRIRXNUM	0x0058
+#define R_LDT_TYPE1_ERRSTATUS   0x0068
+#define R_LDT_TYPE1_SRICTRL	0x006C
+#define R_LDT_TYPE1_TXBUFCNT	0x00C8
+#define R_LDT_TYPE1_EXPCRC	0x00DC
+#define R_LDT_TYPE1_RXCRC	0x00F0
+
+
+/*
+ * LDT Device ID register
+ */
+
+#define S_LDT_DEVICEID_VENDOR		0
+#define M_LDT_DEVICEID_VENDOR		_SB_MAKEMASK_32(16,S_LDT_DEVICEID_VENDOR)
+#define V_LDT_DEVICEID_VENDOR(x)	_SB_MAKEVALUE_32(x,S_LDT_DEVICEID_VENDOR)
+#define G_LDT_DEVICEID_VENDOR(x)	_SB_GETVALUE_32(x,S_LDT_DEVICEID_VENDOR,M_LDT_DEVICEID_VENDOR)
+
+#define S_LDT_DEVICEID_DEVICEID		16
+#define M_LDT_DEVICEID_DEVICEID		_SB_MAKEMASK_32(16,S_LDT_DEVICEID_DEVICEID)
+#define V_LDT_DEVICEID_DEVICEID(x)	_SB_MAKEVALUE_32(x,S_LDT_DEVICEID_DEVICEID)
+#define G_LDT_DEVICEID_DEVICEID(x)	_SB_GETVALUE_32(x,S_LDT_DEVICEID_DEVICEID,M_LDT_DEVICEID_DEVICEID)
+
+
+/*
+ * LDT Command Register (Table 8-13)
+ */
+
+#define M_LDT_CMD_IOSPACE_EN		_SB_MAKEMASK1_32(0)
+#define M_LDT_CMD_MEMSPACE_EN		_SB_MAKEMASK1_32(1)
+#define M_LDT_CMD_MASTER_EN		_SB_MAKEMASK1_32(2)
+#define M_LDT_CMD_SPECCYC_EN		_SB_MAKEMASK1_32(3)
+#define M_LDT_CMD_MEMWRINV_EN		_SB_MAKEMASK1_32(4)
+#define M_LDT_CMD_VGAPALSNP_EN		_SB_MAKEMASK1_32(5)
+#define M_LDT_CMD_PARERRRESP		_SB_MAKEMASK1_32(6)
+#define M_LDT_CMD_WAITCYCCTRL		_SB_MAKEMASK1_32(7)
+#define M_LDT_CMD_SERR_EN		_SB_MAKEMASK1_32(8)
+#define M_LDT_CMD_FASTB2B_EN		_SB_MAKEMASK1_32(9)
+
+/*
+ * LDT class and revision registers
+ */
+
+#define S_LDT_CLASSREV_REV		0
+#define M_LDT_CLASSREV_REV		_SB_MAKEMASK_32(8,S_LDT_CLASSREV_REV)
+#define V_LDT_CLASSREV_REV(x)		_SB_MAKEVALUE_32(x,S_LDT_CLASSREV_REV)
+#define G_LDT_CLASSREV_REV(x)		_SB_GETVALUE_32(x,S_LDT_CLASSREV_REV,M_LDT_CLASSREV_REV)
+
+#define S_LDT_CLASSREV_CLASS		8
+#define M_LDT_CLASSREV_CLASS		_SB_MAKEMASK_32(24,S_LDT_CLASSREV_CLASS)
+#define V_LDT_CLASSREV_CLASS(x)		_SB_MAKEVALUE_32(x,S_LDT_CLASSREV_CLASS)
+#define G_LDT_CLASSREV_CLASS(x)		_SB_GETVALUE_32(x,S_LDT_CLASSREV_CLASS,M_LDT_CLASSREV_CLASS)
+
+#define K_LDT_REV			0x01
+#define K_LDT_CLASS			0x060000
+
+/*
+ * Device Header (offset 0x0C)
+ */
+
+#define S_LDT_DEVHDR_CLINESZ		0
+#define M_LDT_DEVHDR_CLINESZ		_SB_MAKEMASK_32(8,S_LDT_DEVHDR_CLINESZ)
+#define V_LDT_DEVHDR_CLINESZ(x)		_SB_MAKEVALUE_32(x,S_LDT_DEVHDR_CLINESZ)
+#define G_LDT_DEVHDR_CLINESZ(x)		_SB_GETVALUE_32(x,S_LDT_DEVHDR_CLINESZ,M_LDT_DEVHDR_CLINESZ)
+
+#define S_LDT_DEVHDR_LATTMR		8
+#define M_LDT_DEVHDR_LATTMR		_SB_MAKEMASK_32(8,S_LDT_DEVHDR_LATTMR)
+#define V_LDT_DEVHDR_LATTMR(x)		_SB_MAKEVALUE_32(x,S_LDT_DEVHDR_LATTMR)
+#define G_LDT_DEVHDR_LATTMR(x)		_SB_GETVALUE_32(x,S_LDT_DEVHDR_LATTMR,M_LDT_DEVHDR_LATTMR)
+
+#define S_LDT_DEVHDR_HDRTYPE		16
+#define M_LDT_DEVHDR_HDRTYPE		_SB_MAKEMASK_32(8,S_LDT_DEVHDR_HDRTYPE)
+#define V_LDT_DEVHDR_HDRTYPE(x)		_SB_MAKEVALUE_32(x,S_LDT_DEVHDR_HDRTYPE)
+#define G_LDT_DEVHDR_HDRTYPE(x)		_SB_GETVALUE_32(x,S_LDT_DEVHDR_HDRTYPE,M_LDT_DEVHDR_HDRTYPE)
+
+#define K_LDT_DEVHDR_HDRTYPE_TYPE1	1
+
+#define S_LDT_DEVHDR_BIST		24
+#define M_LDT_DEVHDR_BIST		_SB_MAKEMASK_32(8,S_LDT_DEVHDR_BIST)
+#define V_LDT_DEVHDR_BIST(x)		_SB_MAKEVALUE_32(x,S_LDT_DEVHDR_BIST)
+#define G_LDT_DEVHDR_BIST(x)		_SB_GETVALUE_32(x,S_LDT_DEVHDR_BIST,M_LDT_DEVHDR_BIST)
+
+
+
+/*
+ * LDT Status Register (Table 8-14).  Note that these constants
+ * assume you've read the command and status register 
+ * together (32-bit read at offset 0x04)
+ *
+ * These bits also apply to the secondary status
+ * register (Table 8-15), offset 0x1C
+ */
+
+#define M_LDT_STATUS_CAPLIST		_SB_MAKEMASK1_32(20)
+#define M_LDT_STATUS_66MHZCAP		_SB_MAKEMASK1_32(21)
+#define M_LDT_STATUS_RESERVED2		_SB_MAKEMASK1_32(22)
+#define M_LDT_STATUS_FASTB2BCAP		_SB_MAKEMASK1_32(23)
+#define M_LDT_STATUS_MSTRDPARERR	_SB_MAKEMASK1_32(24)
+
+#define S_LDT_STATUS_DEVSELTIMING	25
+#define M_LDT_STATUS_DEVSELTIMING	_SB_MAKEMASK_32(2,S_LDT_STATUS_DEVSELTIMING)
+#define V_LDT_STATUS_DEVSELTIMING(x)	_SB_MAKEVALUE_32(x,S_LDT_STATUS_DEVSELTIMING)
+#define G_LDT_STATUS_DEVSELTIMING(x)	_SB_GETVALUE_32(x,S_LDT_STATUS_DEVSELTIMING,M_LDT_STATUS_DEVSELTIMING)
+
+#define M_LDT_STATUS_SIGDTGTABORT	_SB_MAKEMASK1_32(27)
+#define M_LDT_STATUS_RCVDTGTABORT	_SB_MAKEMASK1_32(28)
+#define M_LDT_STATUS_RCVDMSTRABORT	_SB_MAKEMASK1_32(29)
+#define M_LDT_STATUS_SIGDSERR		_SB_MAKEMASK1_32(30)
+#define M_LDT_STATUS_DETPARERR		_SB_MAKEMASK1_32(31)
+
+/*
+ * Bridge Control Register (Table 8-16).  Note that these 
+ * constants assume you've read the register as a 32-bit 
+ * read (offset 0x3C)
+ */
+
+#define M_LDT_BRCTL_PARERRRESP_EN	_SB_MAKEMASK1_32(16)
+#define M_LDT_BRCTL_SERR_EN		_SB_MAKEMASK1_32(17)
+#define M_LDT_BRCTL_ISA_EN		_SB_MAKEMASK1_32(18)
+#define M_LDT_BRCTL_VGA_EN		_SB_MAKEMASK1_32(19)
+#define M_LDT_BRCTL_MSTRABORTMODE	_SB_MAKEMASK1_32(21)
+#define M_LDT_BRCTL_SECBUSRESET		_SB_MAKEMASK1_32(22)
+#define M_LDT_BRCTL_FASTB2B_EN		_SB_MAKEMASK1_32(23)
+#define M_LDT_BRCTL_PRIDISCARD		_SB_MAKEMASK1_32(24)
+#define M_LDT_BRCTL_SECDISCARD		_SB_MAKEMASK1_32(25)
+#define M_LDT_BRCTL_DISCARDSTAT		_SB_MAKEMASK1_32(26)
+#define M_LDT_BRCTL_DISCARDSERR_EN	_SB_MAKEMASK1_32(27)
+
+/*
+ * LDT Command Register (Table 8-17).  Note that these constants
+ * assume you've read the command and status register together
+ * 32-bit read at offset 0x40
+ */
+
+#define M_LDT_CMD_WARMRESET		_SB_MAKEMASK1_32(16)
+#define M_LDT_CMD_DOUBLEENDED		_SB_MAKEMASK1_32(17)
+
+#define S_LDT_CMD_CAPTYPE		29
+#define M_LDT_CMD_CAPTYPE		_SB_MAKEMASK_32(3,S_LDT_CMD_CAPTYPE)
+#define V_LDT_CMD_CAPTYPE(x)		_SB_MAKEVALUE_32(x,S_LDT_CMD_CAPTYPE)
+#define G_LDT_CMD_CAPTYPE(x)		_SB_GETVALUE_32(x,S_LDT_CMD_CAPTYPE,M_LDT_CMD_CAPTYPE)
+
+/*
+ * LDT link control register (Table 8-18), and (Table 8-19)
+ */
+
+#define M_LDT_LINKCTRL_CAPSYNCFLOOD_EN	_SB_MAKEMASK1_32(1)
+#define M_LDT_LINKCTRL_CRCSTARTTEST	_SB_MAKEMASK1_32(2)
+#define M_LDT_LINKCTRL_CRCFORCEERR	_SB_MAKEMASK1_32(3)
+#define M_LDT_LINKCTRL_LINKFAIL		_SB_MAKEMASK1_32(4)
+#define M_LDT_LINKCTRL_INITDONE		_SB_MAKEMASK1_32(5)
+#define M_LDT_LINKCTRL_EOC		_SB_MAKEMASK1_32(6)
+#define M_LDT_LINKCTRL_XMITOFF		_SB_MAKEMASK1_32(7)
+
+#define S_LDT_LINKCTRL_CRCERR		8
+#define M_LDT_LINKCTRL_CRCERR		_SB_MAKEMASK_32(4,S_LDT_LINKCTRL_CRCERR)
+#define V_LDT_LINKCTRL_CRCERR(x)	_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_CRCERR)
+#define G_LDT_LINKCTRL_CRCERR(x)	_SB_GETVALUE_32(x,S_LDT_LINKCTRL_CRCERR,M_LDT_LINKCTRL_CRCERR)
+
+#define S_LDT_LINKCTRL_MAXIN		16
+#define M_LDT_LINKCTRL_MAXIN		_SB_MAKEMASK_32(3,S_LDT_LINKCTRL_MAXIN)
+#define V_LDT_LINKCTRL_MAXIN(x)		_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_MAXIN)
+#define G_LDT_LINKCTRL_MAXIN(x)		_SB_GETVALUE_32(x,S_LDT_LINKCTRL_MAXIN,M_LDT_LINKCTRL_MAXIN)
+
+#define M_LDT_LINKCTRL_DWFCLN		_SB_MAKEMASK1_32(19)
+
+#define S_LDT_LINKCTRL_MAXOUT		20
+#define M_LDT_LINKCTRL_MAXOUT		_SB_MAKEMASK_32(3,S_LDT_LINKCTRL_MAXOUT)
+#define V_LDT_LINKCTRL_MAXOUT(x)	_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_MAXOUT)
+#define G_LDT_LINKCTRL_MAXOUT(x)	_SB_GETVALUE_32(x,S_LDT_LINKCTRL_MAXOUT,M_LDT_LINKCTRL_MAXOUT)
+
+#define M_LDT_LINKCTRL_DWFCOUT		_SB_MAKEMASK1_32(23)
+
+#define S_LDT_LINKCTRL_WIDTHIN		24
+#define M_LDT_LINKCTRL_WIDTHIN		_SB_MAKEMASK_32(3,S_LDT_LINKCTRL_WIDTHIN)
+#define V_LDT_LINKCTRL_WIDTHIN(x)	_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_WIDTHIN)
+#define G_LDT_LINKCTRL_WIDTHIN(x)	_SB_GETVALUE_32(x,S_LDT_LINKCTRL_WIDTHIN,M_LDT_LINKCTRL_WIDTHIN)
+
+#define M_LDT_LINKCTRL_DWFCLIN_EN	_SB_MAKEMASK1_32(27)
+
+#define S_LDT_LINKCTRL_WIDTHOUT		28
+#define M_LDT_LINKCTRL_WIDTHOUT		_SB_MAKEMASK_32(3,S_LDT_LINKCTRL_WIDTHOUT)
+#define V_LDT_LINKCTRL_WIDTHOUT(x)	_SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_WIDTHOUT)
+#define G_LDT_LINKCTRL_WIDTHOUT(x)	_SB_GETVALUE_32(x,S_LDT_LINKCTRL_WIDTHOUT,M_LDT_LINKCTRL_WIDTHOUT)
+
+#define M_LDT_LINKCTRL_DWFCOUT_EN	_SB_MAKEMASK1_32(31)
+
+/*
+ * LDT Link frequency register  (Table 8-20) offset 0x48
+ */
+
+#define S_LDT_LINKFREQ_FREQ		8
+#define M_LDT_LINKFREQ_FREQ		_SB_MAKEMASK_32(4,S_LDT_LINKFREQ_FREQ)
+#define V_LDT_LINKFREQ_FREQ(x)		_SB_MAKEVALUE_32(x,S_LDT_LINKFREQ_FREQ)
+#define G_LDT_LINKFREQ_FREQ(x)		_SB_GETVALUE_32(x,S_LDT_LINKFREQ_FREQ,M_LDT_LINKFREQ_FREQ)
+
+#define K_LDT_LINKFREQ_200MHZ		0
+#define K_LDT_LINKFREQ_300MHZ		1
+#define K_LDT_LINKFREQ_400MHZ		2
+#define K_LDT_LINKFREQ_500MHZ		3
+#define K_LDT_LINKFREQ_600MHZ		4
+#define K_LDT_LINKFREQ_800MHZ		5
+#define K_LDT_LINKFREQ_1000MHZ		6
+
+/*
+ * LDT SRI Command Register (Table 8-21).  Note that these constants
+ * assume you've read the command and status register together
+ * 32-bit read at offset 0x50
+ */
+
+#define M_LDT_SRICMD_SIPREADY		_SB_MAKEMASK1_32(16)
+#define M_LDT_SRICMD_SYNCPTRCTL		_SB_MAKEMASK1_32(17)
+#define M_LDT_SRICMD_REDUCESYNCZERO	_SB_MAKEMASK1_32(18)
+#define M_LDT_SRICMD_DISSTARVATIONCNT	_SB_MAKEMASK1_32(19)
+
+#define S_LDT_SRICMD_RXMARGIN		20
+#define M_LDT_SRICMD_RXMARGIN		_SB_MAKEMASK_32(5,S_LDT_SRICMD_RXMARGIN)
+#define V_LDT_SRICMD_RXMARGIN(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICMD_RXMARGIN)
+#define G_LDT_SRICMD_RXMARGIN(x)	_SB_GETVALUE_32(x,S_LDT_SRICMD_RXMARGIN,M_LDT_SRICMD_RXMARGIN)
+
+#define M_LDT_SRICMD_LDTPLLCOMPAT	_SB_MAKEMASK1_32(25)
+
+#define S_LDT_SRICMD_TXINITIALOFFSET	28
+#define M_LDT_SRICMD_TXINITIALOFFSET	_SB_MAKEMASK_32(3,S_LDT_SRICMD_TXINITIALOFFSET)
+#define V_LDT_SRICMD_TXINITIALOFFSET(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICMD_TXINITIALOFFSET)
+#define G_LDT_SRICMD_TXINITIALOFFSET(x)	_SB_GETVALUE_32(x,S_LDT_SRICMD_TXINITIALOFFSET,M_LDT_SRICMD_TXINITIALOFFSET)
+
+#define M_LDT_SRICMD_LINKFREQDIRECT	_SB_MAKEMASK1_32(31)
+
+/*
+ * LDT Error control and status register (Table 8-22) (Table 8-23)
+ */
+
+#define M_LDT_ERRCTL_PROTFATAL_EN	_SB_MAKEMASK1_32(0)
+#define M_LDT_ERRCTL_PROTNONFATAL_EN	_SB_MAKEMASK1_32(1)
+#define M_LDT_ERRCTL_PROTSYNCFLOOD_EN	_SB_MAKEMASK1_32(2)
+#define M_LDT_ERRCTL_OVFFATAL_EN	_SB_MAKEMASK1_32(3)
+#define M_LDT_ERRCTL_OVFNONFATAL_EN	_SB_MAKEMASK1_32(4)
+#define M_LDT_ERRCTL_OVFSYNCFLOOD_EN	_SB_MAKEMASK1_32(5)
+#define M_LDT_ERRCTL_EOCNXAFATAL_EN	_SB_MAKEMASK1_32(6)
+#define M_LDT_ERRCTL_EOCNXANONFATAL_EN	_SB_MAKEMASK1_32(7)
+#define M_LDT_ERRCTL_EOCNXASYNCFLOOD_EN	_SB_MAKEMASK1_32(8)
+#define M_LDT_ERRCTL_CRCFATAL_EN	_SB_MAKEMASK1_32(9)
+#define M_LDT_ERRCTL_CRCNONFATAL_EN	_SB_MAKEMASK1_32(10)
+#define M_LDT_ERRCTL_SERRFATAL_EN	_SB_MAKEMASK1_32(11)
+#define M_LDT_ERRCTL_SRCTAGFATAL_EN	_SB_MAKEMASK1_32(12)
+#define M_LDT_ERRCTL_SRCTAGNONFATAL_EN	_SB_MAKEMASK1_32(13)
+#define M_LDT_ERRCTL_SRCTAGSYNCFLOOD_EN	_SB_MAKEMASK1_32(14)
+#define M_LDT_ERRCTL_MAPNXAFATAL_EN	_SB_MAKEMASK1_32(15)
+#define M_LDT_ERRCTL_MAPNXANONFATAL_EN	_SB_MAKEMASK1_32(16)
+#define M_LDT_ERRCTL_MAPNXASYNCFLOOD_EN	_SB_MAKEMASK1_32(17)
+
+#define M_LDT_ERRCTL_PROTOERR		_SB_MAKEMASK1_32(24)
+#define M_LDT_ERRCTL_OVFERR		_SB_MAKEMASK1_32(25)
+#define M_LDT_ERRCTL_EOCNXAERR		_SB_MAKEMASK1_32(26)
+#define M_LDT_ERRCTL_SRCTAGERR		_SB_MAKEMASK1_32(27)
+#define M_LDT_ERRCTL_MAPNXAERR		_SB_MAKEMASK1_32(28)
+
+/*
+ * SRI Control register (Table 8-24, 8-25)  Offset 0x6C
+ */
+
+#define S_LDT_SRICTRL_NEEDRESP		0
+#define M_LDT_SRICTRL_NEEDRESP		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDRESP)
+#define V_LDT_SRICTRL_NEEDRESP(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDRESP)
+#define G_LDT_SRICTRL_NEEDRESP(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDRESP,M_LDT_SRICTRL_NEEDRESP)
+
+#define S_LDT_SRICTRL_NEEDNPREQ		2
+#define M_LDT_SRICTRL_NEEDNPREQ		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDNPREQ)
+#define V_LDT_SRICTRL_NEEDNPREQ(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDNPREQ)
+#define G_LDT_SRICTRL_NEEDNPREQ(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDNPREQ,M_LDT_SRICTRL_NEEDNPREQ)
+
+#define S_LDT_SRICTRL_NEEDPREQ		4
+#define M_LDT_SRICTRL_NEEDPREQ		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDPREQ)
+#define V_LDT_SRICTRL_NEEDPREQ(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDPREQ)
+#define G_LDT_SRICTRL_NEEDPREQ(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDPREQ,M_LDT_SRICTRL_NEEDPREQ)
+
+#define S_LDT_SRICTRL_WANTRESP		8
+#define M_LDT_SRICTRL_WANTRESP		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTRESP)
+#define V_LDT_SRICTRL_WANTRESP(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTRESP)
+#define G_LDT_SRICTRL_WANTRESP(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTRESP,M_LDT_SRICTRL_WANTRESP)
+
+#define S_LDT_SRICTRL_WANTNPREQ		10
+#define M_LDT_SRICTRL_WANTNPREQ		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTNPREQ)
+#define V_LDT_SRICTRL_WANTNPREQ(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTNPREQ)
+#define G_LDT_SRICTRL_WANTNPREQ(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTNPREQ,M_LDT_SRICTRL_WANTNPREQ)
+
+#define S_LDT_SRICTRL_WANTPREQ		12
+#define M_LDT_SRICTRL_WANTPREQ		_SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTPREQ)
+#define V_LDT_SRICTRL_WANTPREQ(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTPREQ)
+#define G_LDT_SRICTRL_WANTPREQ(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTPREQ,M_LDT_SRICTRL_WANTPREQ)
+
+#define S_LDT_SRICTRL_BUFRELSPACE	16
+#define M_LDT_SRICTRL_BUFRELSPACE	_SB_MAKEMASK_32(4,S_LDT_SRICTRL_BUFRELSPACE)
+#define V_LDT_SRICTRL_BUFRELSPACE(x)	_SB_MAKEVALUE_32(x,S_LDT_SRICTRL_BUFRELSPACE)
+#define G_LDT_SRICTRL_BUFRELSPACE(x)	_SB_GETVALUE_32(x,S_LDT_SRICTRL_BUFRELSPACE,M_LDT_SRICTRL_BUFRELSPACE)
+
+/*
+ * LDT SRI Transmit Buffer Count register (Table 8-26)
+ */
+
+#define S_LDT_TXBUFCNT_PCMD		0
+#define M_LDT_TXBUFCNT_PCMD		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_PCMD)
+#define V_LDT_TXBUFCNT_PCMD(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_PCMD)
+#define G_LDT_TXBUFCNT_PCMD(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_PCMD,M_LDT_TXBUFCNT_PCMD)
+
+#define S_LDT_TXBUFCNT_PDATA		4
+#define M_LDT_TXBUFCNT_PDATA		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_PDATA)
+#define V_LDT_TXBUFCNT_PDATA(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_PDATA)
+#define G_LDT_TXBUFCNT_PDATA(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_PDATA,M_LDT_TXBUFCNT_PDATA)
+
+#define S_LDT_TXBUFCNT_NPCMD		8
+#define M_LDT_TXBUFCNT_NPCMD		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_NPCMD)
+#define V_LDT_TXBUFCNT_NPCMD(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_NPCMD)
+#define G_LDT_TXBUFCNT_NPCMD(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_NPCMD,M_LDT_TXBUFCNT_NPCMD)
+
+#define S_LDT_TXBUFCNT_NPDATA		12
+#define M_LDT_TXBUFCNT_NPDATA		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_NPDATA)
+#define V_LDT_TXBUFCNT_NPDATA(x)	_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_NPDATA)
+#define G_LDT_TXBUFCNT_NPDATA(x)	_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_NPDATA,M_LDT_TXBUFCNT_NPDATA)
+
+#define S_LDT_TXBUFCNT_RCMD		16
+#define M_LDT_TXBUFCNT_RCMD		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_RCMD)
+#define V_LDT_TXBUFCNT_RCMD(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_RCMD)
+#define G_LDT_TXBUFCNT_RCMD(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_RCMD,M_LDT_TXBUFCNT_RCMD)
+
+#define S_LDT_TXBUFCNT_RDATA		20
+#define M_LDT_TXBUFCNT_RDATA		_SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_RDATA)
+#define V_LDT_TXBUFCNT_RDATA(x)		_SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_RDATA)
+#define G_LDT_TXBUFCNT_RDATA(x)		_SB_GETVALUE_32(x,S_LDT_TXBUFCNT_RDATA,M_LDT_TXBUFCNT_RDATA)
+
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_mac.h linux/include/asm-mips64/sibyte/sb1250_mac.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_mac.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_mac.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,533 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  MAC constants and macros			File: sb1250_mac.h
+    *  
+    *  This module contains constants and macros for the SB1250's
+    *  ethernet controllers.
+    *  
+    *  SB1250 specification level:  0.2 plus errata as of 4/10/2001
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_MAC_H
+#define _SB1250_MAC_H
+
+#include "sb1250_defs.h"
+
+/*  *********************************************************************
+    *  Ethernet MAC Registers
+    ********************************************************************* */
+
+/*
+ * MAC Configuration Register (Table 9-13)
+ * Register: MAC_CFG_0
+ * Register: MAC_CFG_1
+ * Register: MAC_CFG_2
+ */
+
+
+/* Updated to spec 0.2 */
+
+#define M_MAC_RESERVED0             _SB_MAKEMASK1(0)
+#define M_MAC_TX_HOLD_SOP_EN        _SB_MAKEMASK1(1)
+#define M_MAC_RETRY_EN              _SB_MAKEMASK1(2)
+#define M_MAC_RET_DRPREQ_EN         _SB_MAKEMASK1(3)
+#define M_MAC_RET_UFL_EN            _SB_MAKEMASK1(4)
+#define M_MAC_BURST_EN              _SB_MAKEMASK1(5)
+
+#define S_MAC_TX_PAUSE              _SB_MAKE64(6)
+#define M_MAC_TX_PAUSE_CNT          _SB_MAKEMASK(3,S_MAC_TX_PAUSE)
+#define V_MAC_TX_PAUSE_CNT(x)       _SB_MAKEVALUE(x,S_MAC_TX_PAUSE)
+
+#define K_MAC_TX_PAUSE_CNT_512      0
+#define K_MAC_TX_PAUSE_CNT_1K       1
+#define K_MAC_TX_PAUSE_CNT_2K       2
+#define K_MAC_TX_PAUSE_CNT_4K       3
+#define K_MAC_TX_PAUSE_CNT_8K       4
+#define K_MAC_TX_PAUSE_CNT_16K      5
+#define K_MAC_TX_PAUSE_CNT_32K      6
+#define K_MAC_TX_PAUSE_CNT_64K      7
+
+#define V_MAC_TX_PAUSE_CNT_512      V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_512)
+#define V_MAC_TX_PAUSE_CNT_1K       V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_1K)
+#define V_MAC_TX_PAUSE_CNT_2K       V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_2K)
+#define V_MAC_TX_PAUSE_CNT_4K       V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_4K)
+#define V_MAC_TX_PAUSE_CNT_8K       V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_8K)
+#define V_MAC_TX_PAUSE_CNT_16K      V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_16K)
+#define V_MAC_TX_PAUSE_CNT_32K      V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_32K)
+#define V_MAC_TX_PAUSE_CNT_64K      V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_64K)
+
+#define M_MAC_RESERVED1             _SB_MAKEMASK(8,9)
+
+#define M_MAC_AP_STAT_EN            _SB_MAKEMASK1(17)
+#define M_MAC_RESERVED2		    _SB_MAKEMASK1(18)
+#define M_MAC_DRP_ERRPKT_EN         _SB_MAKEMASK1(19)
+#define M_MAC_DRP_FCSERRPKT_EN      _SB_MAKEMASK1(20)
+#define M_MAC_DRP_CODEERRPKT_EN     _SB_MAKEMASK1(21)
+#define M_MAC_DRP_DRBLERRPKT_EN     _SB_MAKEMASK1(22)
+#define M_MAC_DRP_RNTPKT_EN         _SB_MAKEMASK1(23)
+#define M_MAC_DRP_OSZPKT_EN         _SB_MAKEMASK1(24)
+#define M_MAC_DRP_LENERRPKT_EN      _SB_MAKEMASK1(25)
+
+#define M_MAC_RESERVED3             _SB_MAKEMASK(6,26)
+
+#define M_MAC_BYPASS_SEL            _SB_MAKEMASK1(32)
+#define M_MAC_HDX_EN                _SB_MAKEMASK1(33)
+
+#define S_MAC_SPEED_SEL             _SB_MAKE64(34)
+#define M_MAC_SPEED_SEL             _SB_MAKEMASK(2,S_MAC_SPEED_SEL)
+#define V_MAC_SPEED_SEL(x)	    _SB_MAKEVALUE(x,S_MAC_SPEED_SEL)
+#define G_MAC_SPEED_SEL(x)	    _SB_GETVALUE(x,S_MAC_SPEED_SEL,M_MAC_SPEED_SEL)
+
+#define K_MAC_SPEED_SEL_10MBPS      0
+#define K_MAC_SPEED_SEL_100MBPS     1
+#define K_MAC_SPEED_SEL_1000MBPS    2
+#define K_MAC_SPEED_SEL_RESERVED    3
+
+#define V_MAC_SPEED_SEL_10MBPS      V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_10MBPS)
+#define V_MAC_SPEED_SEL_100MBPS     V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_100MBPS)
+#define V_MAC_SPEED_SEL_1000MBPS    V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_1000MBPS)
+#define V_MAC_SPEED_SEL_RESERVED    V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_RESERVED)
+
+#define M_MAC_TX_CLK_EDGE_SEL       _SB_MAKEMASK1(36)
+#define M_MAC_LOOPBACK_SEL          _SB_MAKEMASK1(37)
+#define M_MAC_FAST_SYNC             _SB_MAKEMASK1(38)
+#define M_MAC_SS_EN                 _SB_MAKEMASK1(39)
+
+#define S_MAC_BYPASS_CFG	    _SB_MAKE64(40)
+#define M_MAC_BYPASS_CFG            _SB_MAKEMASK(2,S_MAC_BYPASS_CFG)
+#define V_MAC_BYPASS_CFG(x)         _SB_MAKEVALUE(x,S_MAC_BYPASS_CFG)
+#define G_MAC_BYPASS_CFG(x)         _SB_GETVALUE(x,S_MAC_BYPASS_CFG,M_MAC_BYPASS_CFG)
+
+#define K_MAC_BYPASS_GMII	    0
+#define K_MAC_BYPASS_ENCODED        1
+#define K_MAC_BYPASS_SOP            2
+#define K_MAC_BYPASS_EOP            3
+
+#define M_MAC_BYPASS_16             _SB_MAKEMASK1(42)
+#define M_MAC_BYPASS_FCS_CHK	    _SB_MAKEMASK1(43)
+
+#define M_MAC_RESERVED4	    	    _SB_MAKEMASK(2,44)
+
+#define S_MAC_BYPASS_IFG            _SB_MAKE64(46)
+#define M_MAC_BYPASS_IFG            _SB_MAKEMASK(8,S_MAC_BYPASS_IFG)
+#define V_MAC_BYPASS_IFG(x)	    _SB_MAKEVALUE(x,S_MAC_BYPASS_IFG)
+#define G_MAC_BYPASS_IFG(x)	    _SB_GETVALUE(x,S_MAC_BYPASS_IFG,M_MAC_BYPASS_IFG)
+
+#define K_MAC_FC_CMD_DISABLED       0
+#define K_MAC_FC_CMD_ENABLED        1
+#define K_MAC_FC_CMD_ENAB_FALSECARR 2
+
+#define V_MAC_FC_CMD_DISABLED       V_MAC_FC_CMD(K_MAC_FC_CMD_DISABLED)
+#define V_MAC_FC_CMD_ENABLED        V_MAC_FC_CMD(K_MAC_FC_CMD_ENABLED)
+#define V_MAC_FC_CMD_ENAB_FALSECARR V_MAC_FC_CMD(K_MAC_FC_CMD_ENAB_FALSECARR)
+
+#define M_MAC_FC_SEL                _SB_MAKEMASK1(54)
+
+#define S_MAC_FC_CMD                _SB_MAKE64(55)
+#define M_MAC_FC_CMD                _SB_MAKEMASK(2,S_MAC_FC_CMD)
+#define V_MAC_FC_CMD(x)	            _SB_MAKEVALUE(x,S_MAC_FC_CMD)
+#define G_MAC_FC_CMD(x)	            _SB_GETVALUE(x,S_MAC_FC_CMD,M_MAC_FC_CMD)
+
+#define S_MAC_RX_CH_SEL             _SB_MAKE64(57)
+#define M_MAC_RX_CH_SEL             _SB_MAKEMASK(7,S_MAC_RX_CH_SEL)
+#define V_MAC_RX_CH_SEL(x)          _SB_MAKEVALUE(x,S_MAC_RX_CH_SEL)
+#define G_MAC_RX_CH_SEL(x)          _SB_GETVALUE(x,S_MAC_RX_CH_SEL,M_MAC_RX_CH_SEL)
+
+
+/*
+ * MAC Enable Registers
+ * Register: MAC_ENABLE_0
+ * Register: MAC_ENABLE_1
+ * Register: MAC_ENABLE_2
+ */
+
+#define M_MAC_RXDMA_EN0	            _SB_MAKEMASK1(0)
+#define M_MAC_RXDMA_EN1	            _SB_MAKEMASK1(1)
+#define M_MAC_TXDMA_EN0	            _SB_MAKEMASK1(4)
+#define M_MAC_TXDMA_EN1	            _SB_MAKEMASK1(5)
+
+#define M_MAC_PORT_RESET            _SB_MAKEMASK1(8)
+
+#define M_MAC_RX_ENABLE             _SB_MAKEMASK1(10)
+#define M_MAC_TX_ENABLE             _SB_MAKEMASK1(11)
+#define M_MAC_BYP_RX_ENABLE         _SB_MAKEMASK1(12)
+#define M_MAC_BYP_TX_ENABLE         _SB_MAKEMASK1(13)
+
+/*
+ * MAC DMA Control Register
+ * Register: MAC_TXD_CTL_0
+ * Register: MAC_TXD_CTL_1
+ * Register: MAC_TXD_CTL_2
+ */
+
+#define S_MAC_TXD_WEIGHT0	    _SB_MAKE64(0)
+#define M_MAC_TXD_WEIGHT0	    _SB_MAKEMASK(4,S_MAC_TXD_WEIGHT0)
+#define V_MAC_TXD_WEIGHT0(x)        _SB_MAKEVALUE(x,S_MAC_TXD_WEIGHT0)
+#define G_MAC_TXD_WEIGHT0(x)        _SB_GETVALUE(x,S_MAC_TXD_WEIGHT0,M_MAC_TXD_WEIGHT0)
+
+#define S_MAC_TXD_WEIGHT1	    _SB_MAKE64(4)
+#define M_MAC_TXD_WEIGHT1	    _SB_MAKEMASK(4,S_MAC_TXD_WEIGHT1)
+#define V_MAC_TXD_WEIGHT1(x)        _SB_MAKEVALUE(x,S_MAC_TXD_WEIGHT1)
+#define G_MAC_TXD_WEIGHT1(x)        _SB_GETVALUE(x,S_MAC_TXD_WEIGHT1,M_MAC_TXD_WEIGHT1)
+
+/*
+ * MAC Fifo Threshhold registers (Table 9-14)
+ * Register: MAC_THRSH_CFG_0
+ * Register: MAC_THRSH_CFG_1
+ * Register: MAC_THRSH_CFG_2
+ */
+
+#define S_MAC_TX_WR_THRSH           _SB_MAKE64(0)
+#define M_MAC_TX_WR_THRSH           _SB_MAKEMASK(6,S_MAC_TX_WR_THRSH)
+#define V_MAC_TX_WR_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_TX_WR_THRSH)
+#define G_MAC_TX_WR_THRSH(x)        _SB_GETVALUE(x,S_MAC_TX_WR_THRSH,M_MAC_TX_WR_THRSH)
+
+#define S_MAC_TX_RD_THRSH           _SB_MAKE64(8)
+#define M_MAC_TX_RD_THRSH           _SB_MAKEMASK(6,S_MAC_TX_RD_THRSH)
+#define V_MAC_TX_RD_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_TX_RD_THRSH)
+#define G_MAC_TX_RD_THRSH(x)        _SB_GETVALUE(x,S_MAC_TX_RD_THRSH,M_MAC_TX_RD_THRSH)
+
+#define S_MAC_TX_RL_THRSH           _SB_MAKE64(16)
+#define M_MAC_TX_RL_THRSH           _SB_MAKEMASK(4,S_MAC_TX_RL_THRSH)
+#define V_MAC_TX_RL_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_TX_RL_THRSH)
+#define G_MAC_TX_RL_THRSH(x)        _SB_GETVALUE(x,S_MAC_TX_RL_THRSH,M_MAC_TX_RL_THRSH)
+
+#define S_MAC_RX_PL_THRSH           _SB_MAKE64(24)
+#define M_MAC_RX_PL_THRSH           _SB_MAKEMASK(6,S_MAC_RX_PL_THRSH)
+#define V_MAC_RX_PL_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_RX_PL_THRSH)
+#define G_MAC_RX_PL_THRSH(x)        _SB_GETVALUE(x,S_MAC_RX_PL_THRSH,M_MAC_RX_PL_THRSH)
+
+#define S_MAC_RX_RD_THRSH           _SB_MAKE64(32)
+#define M_MAC_RX_RD_THRSH           _SB_MAKEMASK(6,S_MAC_RX_RD_THRSH)
+#define V_MAC_RX_RD_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_RX_RD_THRSH)
+#define G_MAC_RX_RD_THRSH(x)        _SB_GETVALUE(x,S_MAC_RX_RD_THRSH,M_MAC_RX_RD_THRSH)
+
+#define S_MAC_RX_RL_THRSH           _SB_MAKE64(40)
+#define M_MAC_RX_RL_THRSH           _SB_MAKEMASK(6,S_MAC_RX_RL_THRSH)
+#define V_MAC_RX_RL_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_RX_RL_THRSH)
+#define G_MAC_RX_RL_THRSH(x)        _SB_GETVALUE(x,S_MAC_RX_RL_THRSH,M_MAC_RX_RL_THRSH)
+
+/*
+ * MAC Frame Configuration Registers (Table 9-15)
+ * Register: MAC_FRAME_CFG_0
+ * Register: MAC_FRAME_CFG_1
+ * Register: MAC_FRAME_CFG_2
+ */
+
+#define S_MAC_IFG_RX                _SB_MAKE64(0)
+#define M_MAC_IFG_RX                _SB_MAKEMASK(6,S_MAC_IFG_RX)
+#define V_MAC_IFG_RX(x)             _SB_MAKEVALUE(x,S_MAC_IFG_RX)
+#define G_MAC_IFG_RX(x)             _SB_GETVALUE(x,S_MAC_IFG_RX,M_MAC_IFG_RX)
+
+#define S_MAC_IFG_TX                _SB_MAKE64(6)
+#define M_MAC_IFG_TX                _SB_MAKEMASK(6,S_MAC_IFG_TX)
+#define V_MAC_IFG_TX(x)             _SB_MAKEVALUE(x,S_MAC_IFG_TX)
+#define G_MAC_IFG_TX(x)             _SB_GETVALUE(x,S_MAC_IFG_TX,M_MAC_IFG_TX)
+
+#define S_MAC_IFG_THRSH             _SB_MAKE64(12)
+#define M_MAC_IFG_THRSH             _SB_MAKEMASK(6,S_MAC_IFG_THRSH)
+#define V_MAC_IFG_THRSH(x)          _SB_MAKEVALUE(x,S_MAC_IFG_THRSH)
+#define G_MAC_IFG_THRSH(x)          _SB_GETVALUE(x,S_MAC_IFG_THRSH,M_MAC_IFG_THRSH)
+
+#define S_MAC_BACKOFF_SEL           _SB_MAKE64(18)
+#define M_MAC_BACKOFF_SEL           _SB_MAKEMASK(4,S_MAC_BACKOFF_SEL)
+#define V_MAC_BACKOFF_SEL(x)        _SB_MAKEVALUE(x,S_MAC_BACKOFF_SEL)
+#define G_MAC_BACKOFF_SEL(x)        _SB_GETVALUE(x,S_MAC_BACKOFF_SEL,M_MAC_BACKOFF_SEL)
+
+#define S_MAC_LFSR_SEED             _SB_MAKE64(22)
+#define M_MAC_LFSR_SEED             _SB_MAKEMASK(8,S_MAC_LFSR_SEED)
+#define V_MAC_LFSR_SEED(x)          _SB_MAKEVALUE(x,S_MAC_LFSR_SEED)
+#define G_MAC_LFSR_SEED(x)          _SB_GETVALUE(x,S_MAC_LFSR_SEED,M_MAC_LFSR_SEED)
+
+#define S_MAC_SLOT_SIZE             _SB_MAKE64(30)
+#define M_MAC_SLOT_SIZE             _SB_MAKEMASK(10,S_MAC_SLOT_SIZE)
+#define V_MAC_SLOT_SIZE(x)          _SB_MAKEVALUE(x,S_MAC_SLOT_SIZE)
+#define G_MAC_SLOT_SIZE(x)          _SB_GETVALUE(x,S_MAC_SLOT_SIZE,M_MAC_SLOT_SIZE)
+
+#define S_MAC_MIN_FRAMESZ           _SB_MAKE64(40)
+#define M_MAC_MIN_FRAMESZ           _SB_MAKEMASK(8,S_MAC_MIN_FRAMESZ)
+#define V_MAC_MIN_FRAMESZ(x)        _SB_MAKEVALUE(x,S_MAC_MIN_FRAMESZ)
+#define G_MAC_MIN_FRAMESZ(x)        _SB_GETVALUE(x,S_MAC_MIN_FRAMESZ,M_MAC_MIN_FRAMESZ)
+
+#define S_MAC_MAX_FRAMESZ           _SB_MAKE64(48)
+#define M_MAC_MAX_FRAMESZ           _SB_MAKEMASK(16,S_MAC_MAX_FRAMESZ)
+#define V_MAC_MAX_FRAMESZ(x)        _SB_MAKEVALUE(x,S_MAC_MAX_FRAMESZ)
+#define G_MAC_MAX_FRAMESZ(x)        _SB_GETVALUE(x,S_MAC_MAX_FRAMESZ,M_MAC_MAX_FRAMESZ)
+
+/*
+ * These constants are used to configure the fields within the Frame
+ * Configuration Register.  
+ */
+
+#define K_MAC_IFG_RX_10             _SB_MAKE64(18)
+#define K_MAC_IFG_RX_100            _SB_MAKE64(18)
+#define K_MAC_IFG_RX_1000           _SB_MAKE64(6)
+
+#define K_MAC_IFG_TX_10             _SB_MAKE64(20)
+#define K_MAC_IFG_TX_100            _SB_MAKE64(20)
+#define K_MAC_IFG_TX_1000           _SB_MAKE64(8)
+
+#define K_MAC_IFG_THRSH_10          _SB_MAKE64(12)
+#define K_MAC_IFG_THRSH_100         _SB_MAKE64(12)
+#define K_MAC_IFG_THRSH_1000        _SB_MAKE64(4)
+
+#define K_MAC_SLOT_SIZE_10          _SB_MAKE64(0)
+#define K_MAC_SLOT_SIZE_100         _SB_MAKE64(0)
+#define K_MAC_SLOT_SIZE_1000        _SB_MAKE64(0)
+
+#define V_MAC_IFG_RX_10        V_MAC_IFG_RX(K_MAC_IFG_RX_10)
+#define V_MAC_IFG_RX_100       V_MAC_IFG_RX(K_MAC_IFG_RX_100)
+#define V_MAC_IFG_RX_1000      V_MAC_IFG_RX(K_MAC_IFG_RX_1000)
+
+#define V_MAC_IFG_TX_10        V_MAC_IFG_TX(K_MAC_IFG_TX_10)
+#define V_MAC_IFG_TX_100       V_MAC_IFG_TX(K_MAC_IFG_TX_100)
+#define V_MAC_IFG_TX_1000      V_MAC_IFG_TX(K_MAC_IFG_TX_1000)
+
+#define V_MAC_IFG_THRSH_10     V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_10)
+#define V_MAC_IFG_THRSH_100    V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_100)
+#define V_MAC_IFG_THRSH_1000   V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_1000)
+
+#define V_MAC_SLOT_SIZE_10     V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_10)
+#define V_MAC_SLOT_SIZE_100    V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_100)
+#define V_MAC_SLOT_SIZE_1000   V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_1000)
+
+#define K_MAC_MIN_FRAMESZ_DEFAULT   _SB_MAKE64(64)
+#define K_MAC_MAX_FRAMESZ_DEFAULT   _SB_MAKE64(1518)
+
+#define V_MAC_MIN_FRAMESZ_DEFAULT   V_MAC_MIN_FRAMESZ(K_MAC_MIN_FRAMESZ_DEFAULT)
+#define V_MAC_MAX_FRAMESZ_DEFAULT   V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_DEFAULT)
+
+/*
+ * MAC VLAN Tag Registers (Table 9-16)
+ * Register: MAC_VLANTAG_0
+ * Register: MAC_VLANTAG_1
+ * Register: MAC_VLANTAG_2
+ */
+
+/* No bit fields: lower 32 bits of register are the tags */
+
+/*
+ * MAC Status Registers (Table 9-17)
+ * Also used for the MAC Interrupt Mask Register (Table 9-18)
+ * Register: MAC_STATUS_0
+ * Register: MAC_STATUS_1
+ * Register: MAC_STATUS_2
+ * Register: MAC_INT_MASK_0
+ * Register: MAC_INT_MASK_1
+ * Register: MAC_INT_MASK_2
+ */
+
+/* 
+ * Use these constants to shift the appropriate channel
+ * into the CH0 position so the same tests can be used
+ * on each channel.
+ */
+
+#define S_MAC_RX_CH0                _SB_MAKE64(0)
+#define S_MAC_RX_CH1                _SB_MAKE64(8)
+#define S_MAC_TX_CH0                _SB_MAKE64(16)
+#define S_MAC_TX_CH1                _SB_MAKE64(24)
+
+#define S_MAC_TXCHANNELS	    _SB_MAKE64(16)	/* this is 1st TX chan */
+#define S_MAC_CHANWIDTH             _SB_MAKE64(8)	/* bits between channels */
+
+/*
+ *  These are the same as RX channel 0.  The idea here
+ *  is that you'll use one of the "S_" things above
+ *  and pass just the six bits to a DMA-channel-specific ISR
+ */
+#define M_MAC_INT_CHANNEL           _SB_MAKEMASK(8,0)
+#define M_MAC_INT_EOP_COUNT         _SB_MAKEMASK1(0)
+#define M_MAC_INT_EOP_TIMER         _SB_MAKEMASK1(1)
+#define M_MAC_INT_EOP_SEEN          _SB_MAKEMASK1(2)
+#define M_MAC_INT_HWM               _SB_MAKEMASK1(3)
+#define M_MAC_INT_LWM               _SB_MAKEMASK1(4)
+#define M_MAC_INT_DSCR              _SB_MAKEMASK1(5)
+#define M_MAC_INT_ERR               _SB_MAKEMASK1(6)
+#define M_MAC_INT_DZERO             _SB_MAKEMASK1(7)	/* only for TX channels */
+
+
+#define M_MAC_RX_UNDRFL             _SB_MAKEMASK1(40)
+#define M_MAC_RX_OVRFL              _SB_MAKEMASK1(41)
+#define M_MAC_TX_UNDRFL             _SB_MAKEMASK1(42)
+#define M_MAC_TX_OVRFL              _SB_MAKEMASK1(43)
+#define M_MAC_LTCOL_ERR             _SB_MAKEMASK1(44)
+#define M_MAC_EXCOL_ERR             _SB_MAKEMASK1(45)
+#define M_MAC_CNTR_OVRFL_ERR        _SB_MAKEMASK1(46)
+
+#define S_MAC_COUNTER_ADDR          _SB_MAKE64(47)
+#define M_MAC_COUNTER_ADDR          _SB_MAKEMASK(5,S_MAC_COUNTER_ADDR)
+#define V_MAC_COUNTER_ADDR(x)       _SB_MAKEVALUE(x,S_MAC_COUNTER_ADDR)
+#define G_MAC_COUNTER_ADDR(x)       _SB_GETVALUE(x,S_MAC_COUNTER_ADDR,M_MAC_COUNTER_ADDR)
+
+/*
+ * MAC Fifo Pointer Registers (Table 9-19)    [Debug register]
+ * Register: MAC_FIFO_PTRS_0
+ * Register: MAC_FIFO_PTRS_1
+ * Register: MAC_FIFO_PTRS_2
+ */
+
+#define S_MAC_TX_WRPTR              _SB_MAKE64(0)
+#define M_MAC_TX_WRPTR              _SB_MAKEMASK(6,S_MAC_TX_WRPTR)
+#define V_MAC_TX_WRPTR(x)           _SB_MAKEVALUE(x,S_MAC_TX_WRPTR)
+#define G_MAC_TX_WRPTR(x)           _SB_GETVALUE(x,S_MAC_TX_WRPTR,M_MAC_TX_WRPTR)
+
+#define S_MAC_TX_RDPTR              _SB_MAKE64(8)
+#define M_MAC_TX_RDPTR              _SB_MAKEMASK(6,S_MAC_TX_RDPTR)
+#define V_MAC_TX_RDPTR(x)           _SB_MAKEVALUE(x,S_MAC_TX_RDPTR)
+#define G_MAC_TX_RDPTR(x)           _SB_GETVALUE(x,S_MAC_TX_RDPTR,M_MAC_TX_RDPTR)
+
+#define S_MAC_RX_WRPTR              _SB_MAKE64(16)
+#define M_MAC_RX_WRPTR              _SB_MAKEMASK(6,S_MAC_RX_WRPTR)
+#define V_MAC_RX_WRPTR(x)           _SB_MAKEVALUE(x,S_MAC_RX_WRPTR)
+#define G_MAC_RX_WRPTR(x)           _SB_GETVALUE(x,S_MAC_RX_WRPTR,M_MAC_TX_WRPTR)
+
+#define S_MAC_RX_RDPTR              _SB_MAKE64(24)
+#define M_MAC_RX_RDPTR              _SB_MAKEMASK(6,S_MAC_RX_RDPTR)
+#define V_MAC_RX_RDPTR(x)           _SB_MAKEVALUE(x,S_MAC_RX_RDPTR)
+#define G_MAC_RX_RDPTR(x)           _SB_GETVALUE(x,S_MAC_RX_RDPTR,M_MAC_TX_RDPTR)
+
+/*
+ * MAC Fifo End Of Packet Count Registers (Table 9-20)  [Debug register]
+ * Register: MAC_EOPCNT_0
+ * Register: MAC_EOPCNT_1
+ * Register: MAC_EOPCNT_2
+ */
+
+#define S_MAC_TX_EOP_COUNTER        _SB_MAKE64(0)
+#define M_MAC_TX_EOP_COUNTER        _SB_MAKEMASK(6,S_MAC_TX_EOP_COUNTER)
+#define V_MAC_TX_EOP_COUNTER(x)     _SB_MAKEVALUE(x,S_MAC_TX_EOP_COUNTER)
+#define G_MAC_TX_EOP_COUNTER(x)     _SB_GETVALUE(x,S_MAC_TX_EOP_COUNTER,M_MAC_TX_EOP_COUNTER)
+
+#define S_MAC_RX_EOP_COUNTER        _SB_MAKE64(8)
+#define M_MAC_RX_EOP_COUNTER        _SB_MAKEMASK(6,S_MAC_RX_EOP_COUNTER)
+#define V_MAC_RX_EOP_COUNTER(x)     _SB_MAKEVALUE(x,S_MAC_RX_EOP_COUNTER)
+#define G_MAC_RX_EOP_COUNTER(x)     _SB_GETVALUE(x,S_MAC_RX_EOP_COUNTER,M_MAC_RX_EOP_COUNTER)
+
+/*
+ * MAC Recieve Address Filter Exact Match Registers (Table 9-21)
+ * Registers: MAC_ADDR0_0 through MAC_ADDR7_0
+ * Registers: MAC_ADDR0_1 through MAC_ADDR7_1
+ * Registers: MAC_ADDR0_2 through MAC_ADDR7_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Recieve Address Filter Hash Match Registers (Table 9-22)
+ * Registers: MAC_HASH0_0 through MAC_HASH7_0
+ * Registers: MAC_HASH0_1 through MAC_HASH7_1
+ * Registers: MAC_HASH0_2 through MAC_HASH7_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Transmit Source Address Registers (Table 9-23)
+ * Register: MAC_ETHERNET_ADDR_0
+ * Register: MAC_ETHERNET_ADDR_1
+ * Register: MAC_ETHERNET_ADDR_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Packet Type Configuration Register
+ * Register: MAC_TYPE_CFG_0
+ * Register: MAC_TYPE_CFG_1
+ * Register: MAC_TYPE_CFG_2
+ */
+
+#define S_TYPECFG_TYPESIZE      _SB_MAKE64(16)
+
+#define S_TYPECFG_TYPE0		_SB_MAKE64(0)
+#define M_TYPECFG_TYPE0         _SB_MAKEMASK(16,S_TYPECFG_TYPE0)
+#define V_TYPECFG_TYPE0(x)      _SB_MAKEVALUE(x,S_TYPECFG_TYPE0)
+#define G_TYPECFG_TYPE0(x)      _SB_GETVALUE(x,S_TYPECFG_TYPE0,M_TYPECFG_TYPE0)
+
+#define S_TYPECFG_TYPE1		_SB_MAKE64(0)
+#define M_TYPECFG_TYPE1         _SB_MAKEMASK(16,S_TYPECFG_TYPE1)
+#define V_TYPECFG_TYPE1(x)      _SB_MAKEVALUE(x,S_TYPECFG_TYPE1)
+#define G_TYPECFG_TYPE1(x)      _SB_GETVALUE(x,S_TYPECFG_TYPE1,M_TYPECFG_TYPE1)
+
+#define S_TYPECFG_TYPE2		_SB_MAKE64(0)
+#define M_TYPECFG_TYPE2         _SB_MAKEMASK(16,S_TYPECFG_TYPE2)
+#define V_TYPECFG_TYPE2(x)      _SB_MAKEVALUE(x,S_TYPECFG_TYPE2)
+#define G_TYPECFG_TYPE2(x)      _SB_GETVALUE(x,S_TYPECFG_TYPE2,M_TYPECFG_TYPE2)
+
+#define S_TYPECFG_TYPE3		_SB_MAKE64(0)
+#define M_TYPECFG_TYPE3         _SB_MAKEMASK(16,S_TYPECFG_TYPE3)
+#define V_TYPECFG_TYPE3(x)      _SB_MAKEVALUE(x,S_TYPECFG_TYPE3)
+#define G_TYPECFG_TYPE3(x)      _SB_GETVALUE(x,S_TYPECFG_TYPE3,M_TYPECFG_TYPE3)
+
+/*
+ * MAC Receive Address Filter Control Registers (Table 9-24)
+ * Register: MAC_ADFILTER_CFG_0
+ * Register: MAC_ADFILTER_CFG_1
+ * Register: MAC_ADFILTER_CFG_2
+ */
+
+#define M_MAC_ALLPKT_EN	        _SB_MAKEMASK1(0)
+#define M_MAC_UCAST_EN          _SB_MAKEMASK1(1)
+#define M_MAC_UCAST_INV         _SB_MAKEMASK1(2)
+#define M_MAC_MCAST_EN          _SB_MAKEMASK1(3)
+#define M_MAC_MCAST_INV         _SB_MAKEMASK1(4)
+#define M_MAC_BCAST_EN          _SB_MAKEMASK1(5)
+#define M_MAC_DIRECT_INV        _SB_MAKEMASK1(6)
+
+#define S_MAC_IPHDR_OFFSET      _SB_MAKE64(8)
+#define M_MAC_IPHDR_OFFSET      _SB_MAKEMASK(8,S_MAC_IPHDR_OFFSET)
+#define V_MAC_IPHDR_OFFSET(x)	_SB_MAKEVALUE(x,S_MAC_IPHDR_OFFSET)
+#define G_MAC_IPHDR_OFFSET(x)	_SB_GETVALUE(x,S_MAC_IPHDR_OFFSET,M_MAC_IPHDR_OFFSET)
+
+/*
+ * MAC Receive Channel Select Registers (Table 9-25)
+ */
+
+/* no bitfields */
+
+/*
+ * MAC MII Management Interface Registers (Table 9-26)
+ * Register: MAC_MDIO_0
+ * Register: MAC_MDIO_1
+ * Register: MAC_MDIO_2
+ */
+
+#define S_MAC_MDC		0
+#define S_MAC_MDIO_DIR		1
+#define S_MAC_MDIO_OUT		2
+#define S_MAC_GENC		3
+#define S_MAC_MDIO_IN		4
+
+#define M_MAC_MDC		_SB_MAKEMASK1(S_MAC_MDC)
+#define M_MAC_MDIO_DIR		_SB_MAKEMASK1(S_MAC_MDIO_DIR)
+#define M_MAC_MDIO_DIR_INPUT	_SB_MAKEMASK1(S_MAC_MDIO_DIR)
+#define M_MAC_MDIO_OUT		_SB_MAKEMASK1(S_MAC_MDIO_OUT)
+#define M_MAC_GENC		_SB_MAKEMASK1(S_MAC_GENC)
+#define M_MAC_MDIO_IN		_SB_MAKEMASK1(S_MAC_MDIO_IN)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_mc.h linux/include/asm-mips64/sibyte/sb1250_mc.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_mc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_mc.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,529 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Memory Controller constants              File: sb1250_mc.h       
+    *  
+    *  This module contains constants and macros useful for
+    *  programming the memory controller.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_MC_H
+#define _SB1250_MC_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Memory Channel Config Register (table 6-14)
+ */
+
+#define S_MC_RESERVED0              0
+#define M_MC_RESERVED0              _SB_MAKEMASK(8,S_MC_RESERVED0)
+
+#define S_MC_CHANNEL_SEL            8
+#define M_MC_CHANNEL_SEL            _SB_MAKEMASK(8,S_MC_CHANNEL_SEL)
+#define V_MC_CHANNEL_SEL(x)         _SB_MAKEVALUE(x,S_MC_CHANNEL_SEL)
+#define G_MC_CHANNEL_SEL(x)         _SB_GETVALUE(x,S_MC_CHANNEL_SEL,M_MC_CHANNEL_SEL)
+
+#define S_MC_BANK0_MAP              16
+#define M_MC_BANK0_MAP              _SB_MAKEMASK(4,S_MC_BANK0_MAP)
+#define V_MC_BANK0_MAP(x)           _SB_MAKEVALUE(x,S_MC_BANK0_MAP)
+#define G_MC_BANK0_MAP(x)           _SB_GETVALUE(x,S_MC_BANK0_MAP,M_MC_BANK0_MAP)
+
+#define K_MC_BANK0_MAP_DEFAULT      0x00
+#define V_MC_BANK0_MAP_DEFAULT      V_MC_BANK0_MAP(K_MC_BANK0_MAP_DEFAULT)
+
+#define S_MC_BANK1_MAP              20
+#define M_MC_BANK1_MAP              _SB_MAKEMASK(4,S_MC_BANK1_MAP)
+#define V_MC_BANK1_MAP(x)           _SB_MAKEVALUE(x,S_MC_BANK1_MAP)
+#define G_MC_BANK1_MAP(x)           _SB_GETVALUE(x,S_MC_BANK1_MAP,M_MC_BANK1_MAP)
+
+#define K_MC_BANK1_MAP_DEFAULT      0x08
+#define V_MC_BANK1_MAP_DEFAULT      V_MC_BANK1_MAP(K_MC_BANK1_MAP_DEFAULT)
+
+#define S_MC_BANK2_MAP              24
+#define M_MC_BANK2_MAP              _SB_MAKEMASK(4,S_MC_BANK2_MAP)
+#define V_MC_BANK2_MAP(x)           _SB_MAKEVALUE(x,S_MC_BANK2_MAP)
+#define G_MC_BANK2_MAP(x)           _SB_GETVALUE(x,S_MC_BANK2_MAP,M_MC_BANK2_MAP)
+
+#define K_MC_BANK2_MAP_DEFAULT      0x09
+#define V_MC_BANK2_MAP_DEFAULT      V_MC_BANK2_MAP(K_MC_BANK2_MAP_DEFAULT)
+
+#define S_MC_BANK3_MAP              28
+#define M_MC_BANK3_MAP              _SB_MAKEMASK(4,S_MC_BANK3_MAP)
+#define V_MC_BANK3_MAP(x)           _SB_MAKEVALUE(x,S_MC_BANK3_MAP)
+#define G_MC_BANK3_MAP(x)           _SB_GETVALUE(x,S_MC_BANK3_MAP,M_MC_BANK3_MAP)
+
+#define K_MC_BANK3_MAP_DEFAULT      0x0C
+#define V_MC_BANK3_MAP_DEFAULT      V_MC_BANK3_MAP(K_MC_BANK3_MAP_DEFAULT)
+
+#define M_MC_RESERVED1              _SB_MAKEMASK(8,32)
+
+#define S_MC_QUEUE_SIZE		    40
+#define M_MC_QUEUE_SIZE             _SB_MAKEMASK(4,S_MC_QUEUE_SIZE)
+#define V_MC_QUEUE_SIZE(x)          _SB_MAKEVALUE(x,S_MC_QUEUE_SIZE)
+#define G_MC_QUEUE_SIZE(x)          _SB_GETVALUE(x,S_MC_QUEUE_SIZE,M_MC_QUEUE_SIZE)
+#define V_MC_QUEUE_SIZE_DEFAULT     V_MC_QUEUE_SIZE(0x0A)
+
+#define S_MC_AGE_LIMIT              44
+#define M_MC_AGE_LIMIT              _SB_MAKEMASK(4,S_MC_AGE_LIMIT)
+#define V_MC_AGE_LIMIT(x)           _SB_MAKEVALUE(x,S_MC_AGE_LIMIT)
+#define G_MC_AGE_LIMIT(x)           _SB_GETVALUE(x,S_MC_AGE_LIMIT,M_MC_AGE_LIMIT)
+#define V_MC_AGE_LIMIT_DEFAULT      V_MC_AGE_LIMIT(8)
+
+#define S_MC_WR_LIMIT               48
+#define M_MC_WR_LIMIT               _SB_MAKEMASK(4,S_MC_WR_LIMIT)
+#define V_MC_WR_LIMIT(x)            _SB_MAKEVALUE(x,S_MC_WR_LIMIT)
+#define G_MC_WR_LIMIT(x)            _SB_GETVALUE(x,S_MC_WR_LIMIT,M_MC_WR_LIMIT)
+#define V_MC_WR_LIMIT_DEFAULT       V_MC_WR_LIMIT(5)
+
+#define M_MC_IOB1HIGHPRIORITY	    _SB_MAKEMASK1(52)
+
+#define M_MC_RESERVED2              _SB_MAKEMASK(3,53)
+
+#define S_MC_CS_MODE                56
+#define M_MC_CS_MODE                _SB_MAKEMASK(4,S_MC_CS_MODE)
+#define V_MC_CS_MODE(x)             _SB_MAKEVALUE(x,S_MC_CS_MODE)
+#define G_MC_CS_MODE(x)             _SB_GETVALUE(x,S_MC_CS_MODE,M_MC_CS_MODE)
+
+#define K_MC_CS_MODE_MSB_CS         0
+#define K_MC_CS_MODE_INTLV_CS       15
+#define K_MC_CS_MODE_MIXED_CS_10    12
+#define K_MC_CS_MODE_MIXED_CS_30    6
+#define K_MC_CS_MODE_MIXED_CS_32    3
+
+#define V_MC_CS_MODE_MSB_CS         V_MC_CS_MODE(K_MC_CS_MODE_MSB_CS)
+#define V_MC_CS_MODE_INTLV_CS       V_MC_CS_MODE(K_MC_CS_MODE_INTLV_CS)
+#define V_MC_CS_MODE_MIXED_CS_10    V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_10)
+#define V_MC_CS_MODE_MIXED_CS_30    V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_30)
+#define V_MC_CS_MODE_MIXED_CS_32    V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_32)
+
+#define M_MC_ECC_DISABLE            _SB_MAKEMASK1(60)
+#define M_MC_BERR_DISABLE           _SB_MAKEMASK1(61)
+#define M_MC_FORCE_SEQ              _SB_MAKEMASK1(62)
+#define M_MC_DEBUG                  _SB_MAKEMASK1(63)
+
+#define V_MC_CONFIG_DEFAULT     V_MC_WR_LIMIT_DEFAULT | V_MC_AGE_LIMIT_DEFAULT | \
+				V_MC_BANK0_MAP_DEFAULT | V_MC_BANK1_MAP_DEFAULT | \
+				V_MC_BANK2_MAP_DEFAULT | V_MC_BANK3_MAP_DEFAULT | V_MC_CHANNEL_SEL(0) | \
+                                M_MC_IOB1HIGHPRIORITY | V_MC_QUEUE_SIZE_DEFAULT
+
+
+/*
+ * Memory clock config register (Table 6-15)
+ *
+ * Note: this field has been updated to be consistent with the errata to 0.2
+ */
+
+#define S_MC_CLK_RATIO              0
+#define M_MC_CLK_RATIO              _SB_MAKEMASK(4,S_MC_CLK_RATIO)
+#define V_MC_CLK_RATIO(x)           _SB_MAKEVALUE(x,S_MC_CLK_RATIO)
+#define G_MC_CLK_RATIO(x)           _SB_GETVALUE(x,S_MC_CLK_RATIO,M_MC_CLK_RATIO)
+
+#define K_MC_CLK_RATIO_2X           4
+#define K_MC_CLK_RATIO_25X          5
+#define K_MC_CLK_RATIO_3X           6
+#define K_MC_CLK_RATIO_35X          7
+#define K_MC_CLK_RATIO_4X           8
+#define K_MC_CLK_RATIO_45X	    9
+
+#define V_MC_CLK_RATIO_2X	    V_MC_CLK_RATIO(K_MC_CLK_RATIO_2X)
+#define V_MC_CLK_RATIO_25X          V_MC_CLK_RATIO(K_MC_CLK_RATIO_25X)
+#define V_MC_CLK_RATIO_3X           V_MC_CLK_RATIO(K_MC_CLK_RATIO_3X)
+#define V_MC_CLK_RATIO_35X          V_MC_CLK_RATIO(K_MC_CLK_RATIO_35X)
+#define V_MC_CLK_RATIO_4X           V_MC_CLK_RATIO(K_MC_CLK_RATIO_4X)
+#define V_MC_CLK_RATIO_45X          V_MC_CLK_RATIO(K_MC_CLK_RATIO_45X)
+#define V_MC_CLK_RATIO_DEFAULT      V_MC_CLK_RATIO_25X
+
+#define S_MC_REF_RATE                8
+#define M_MC_REF_RATE                _SB_MAKEMASK(8,S_MC_REF_RATE)
+#define V_MC_REF_RATE(x)             _SB_MAKEVALUE(x,S_MC_REF_RATE)
+#define G_MC_REF_RATE(x)             _SB_GETVALUE(x,S_MC_REF_RATE,M_MC_REF_RATE)
+
+#define K_MC_REF_RATE_100MHz         0x62
+#define K_MC_REF_RATE_133MHz         0x81
+#define K_MC_REF_RATE_200MHz         0xC4 
+
+#define V_MC_REF_RATE_100MHz         V_MC_REF_RATE(K_MC_REF_RATE_100MHz)
+#define V_MC_REF_RATE_133MHz         V_MC_REF_RATE(K_MC_REF_RATE_133MHz)
+#define V_MC_REF_RATE_200MHz         V_MC_REF_RATE(K_MC_REF_RATE_200MHz)
+#define V_MC_REF_RATE_DEFAULT        V_MC_REF_RATE_100MHz
+
+#define S_MC_CLOCK_DRIVE             16
+#define M_MC_CLOCK_DRIVE             _SB_MAKEMASK(4,S_MC_CLOCK_DRIVE)
+#define V_MC_CLOCK_DRIVE(x)          _SB_MAKEVALUE(x,S_MC_CLOCK_DRIVE)
+#define G_MC_CLOCK_DRIVE(x)          _SB_GETVALUE(x,S_MC_CLOCK_DRIVE,M_MC_CLOCK_DRIVE)
+#define V_MC_CLOCK_DRIVE_DEFAULT     V_MC_CLOCK_DRIVE(0xF)
+
+#define S_MC_DATA_DRIVE              20
+#define M_MC_DATA_DRIVE              _SB_MAKEMASK(4,S_MC_DATA_DRIVE)
+#define V_MC_DATA_DRIVE(x)           _SB_MAKEVALUE(x,S_MC_DATA_DRIVE)
+#define G_MC_DATA_DRIVE(x)           _SB_GETVALUE(x,S_MC_DATA_DRIVE,M_MC_DATA_DRIVE)
+#define V_MC_DATA_DRIVE_DEFAULT      V_MC_DATA_DRIVE(0x0)
+
+#define S_MC_ADDR_DRIVE              24
+#define M_MC_ADDR_DRIVE              _SB_MAKEMASK(4,S_MC_ADDR_DRIVE)
+#define V_MC_ADDR_DRIVE(x)           _SB_MAKEVALUE(x,S_MC_ADDR_DRIVE)
+#define G_MC_ADDR_DRIVE(x)           _SB_GETVALUE(x,S_MC_ADDR_DRIVE,M_MC_ADDR_DRIVE)
+#define V_MC_ADDR_DRIVE_DEFAULT      V_MC_ADDR_DRIVE(0x0)
+
+#define M_MC_DLL_BYPASS              _SB_MAKEMASK1(31)
+
+#define S_MC_DQI_SKEW               32
+#define M_MC_DQI_SKEW               _SB_MAKEMASK(8,S_MC_DQI_SKEW)
+#define V_MC_DQI_SKEW(x)            _SB_MAKEVALUE(x,S_MC_DQI_SKEW)
+#define G_MC_DQI_SKEW(x)            _SB_GETVALUE(x,S_MC_DQI_SKEW,M_MC_DQI_SKEW)
+#define V_MC_DQI_SKEW_DEFAULT       V_MC_DQI_SKEW(0)
+
+#define S_MC_DQO_SKEW               40
+#define M_MC_DQO_SKEW               _SB_MAKEMASK(8,S_MC_DQO_SKEW)
+#define V_MC_DQO_SKEW(x)            _SB_MAKEVALUE(x,S_MC_DQO_SKEW)
+#define G_MC_DQO_SKEW(x)            _SB_GETVALUE(x,S_MC_DQO_SKEW,M_MC_DQO_SKEW)
+#define V_MC_DQO_SKEW_DEFAULT       V_MC_DQO_SKEW(0)
+
+#define S_MC_ADDR_SKEW               48
+#define M_MC_ADDR_SKEW               _SB_MAKEMASK(8,S_MC_ADDR_SKEW)
+#define V_MC_ADDR_SKEW(x)            _SB_MAKEVALUE(x,S_MC_ADDR_SKEW)
+#define G_MC_ADDR_SKEW(x)            _SB_GETVALUE(x,S_MC_ADDR_SKEW,M_MC_ADDR_SKEW)
+#define V_MC_ADDR_SKEW_DEFAULT       V_MC_ADDR_SKEW(0x0F)
+
+#define S_MC_DLL_DEFAULT             56
+#define M_MC_DLL_DEFAULT             _SB_MAKEMASK(8,S_MC_DLL_DEFAULT)
+#define V_MC_DLL_DEFAULT(x)          _SB_MAKEVALUE(x,S_MC_DLL_DEFAULT)
+#define G_MC_DLL_DEFAULT(x)          _SB_GETVALUE(x,S_MC_DLL_DEFAULT,M_MC_DLL_DEFAULT)
+#define V_MC_DLL_DEFAULT_DEFAULT     V_MC_DLL_DEFAULT(0x10)
+
+#define V_MC_CLKCONFIG_DEFAULT       V_MC_DLL_DEFAULT_DEFAULT |  \
+                                     V_MC_ADDR_SKEW_DEFAULT | \
+                                     V_MC_DQO_SKEW_DEFAULT | \
+                                     V_MC_DQI_SKEW_DEFAULT | \
+                                     V_MC_ADDR_DRIVE_DEFAULT | \
+                                     V_MC_DATA_DRIVE_DEFAULT | \
+                                     V_MC_CLOCK_DRIVE_DEFAULT | \
+                                     V_MC_REF_RATE_DEFAULT 
+
+
+
+/*
+ * DRAM Command Register (Table 6-13)
+ */
+
+#define S_MC_COMMAND                0
+#define M_MC_COMMAND                _SB_MAKEMASK(4,S_MC_COMMAND)
+#define V_MC_COMMAND(x)             _SB_MAKEVALUE(x,S_MC_COMMAND)
+#define G_MC_COMMAND(x)             _SB_GETVALUE(x,S_MC_COMMAND,M_MC_COMMAND)
+
+#define K_MC_COMMAND_EMRS           0
+#define K_MC_COMMAND_MRS            1
+#define K_MC_COMMAND_PRE            2
+#define K_MC_COMMAND_AR             3
+#define K_MC_COMMAND_SETRFSH        4
+#define K_MC_COMMAND_CLRRFSH        5
+#define K_MC_COMMAND_SETPWRDN       6
+#define K_MC_COMMAND_CLRPWRDN       7
+
+#define V_MC_COMMAND_EMRS           V_MC_COMMAND(K_MC_COMMAND_EMRS)
+#define V_MC_COMMAND_MRS            V_MC_COMMAND(K_MC_COMMAND_MRS)
+#define V_MC_COMMAND_PRE            V_MC_COMMAND(K_MC_COMMAND_PRE)
+#define V_MC_COMMAND_AR             V_MC_COMMAND(K_MC_COMMAND_AR)
+#define V_MC_COMMAND_SETRFSH        V_MC_COMMAND(K_MC_COMMAND_SETRFSH)
+#define V_MC_COMMAND_CLRRFSH        V_MC_COMMAND(K_MC_COMMAND_CLRRFSH)
+#define V_MC_COMMAND_SETPWRDN       V_MC_COMMAND(K_MC_COMMAND_SETPWRDN)
+#define V_MC_COMMAND_CLRPWRDN       V_MC_COMMAND(K_MC_COMMAND_CLRPWRDN)
+
+#define M_MC_CS0                    _SB_MAKEMASK1(4)
+#define M_MC_CS1                    _SB_MAKEMASK1(5)
+#define M_MC_CS2                    _SB_MAKEMASK1(6)
+#define M_MC_CS3                    _SB_MAKEMASK1(7)
+
+/*
+ * DRAM Mode Register (Table 6-14)
+ */
+
+#define S_MC_EMODE                  0
+#define M_MC_EMODE                  _SB_MAKEMASK(15,S_MC_EMODE)
+#define V_MC_EMODE(x)               _SB_MAKEVALUE(x,S_MC_EMODE)
+#define G_MC_EMODE(x)               _SB_GETVALUE(x,S_MC_EMODE,M_MC_EMODE)
+#define V_MC_EMODE_DEFAULT          V_MC_EMODE(0)
+
+#define S_MC_MODE                   16
+#define M_MC_MODE                   _SB_MAKEMASK(15,S_MC_MODE)
+#define V_MC_MODE(x)                _SB_MAKEVALUE(x,S_MC_MODE)
+#define G_MC_MODE(x)                _SB_GETVALUE(x,S_MC_MODE,M_MC_MODE)
+#define V_MC_MODE_DEFAULT           V_MC_MODE(0x22)
+
+#define S_MC_DRAM_TYPE              32
+#define M_MC_DRAM_TYPE              _SB_MAKEMASK(3,S_MC_DRAM_TYPE)
+#define V_MC_DRAM_TYPE(x)           _SB_MAKEVALUE(x,S_MC_DRAM_TYPE)
+#define G_MC_DRAM_TYPE(x)           _SB_GETVALUE(x,S_MC_DRAM_TYPE,M_MC_DRAM_TYPE)
+
+#define K_MC_DRAM_TYPE_JEDEC        0
+#define K_MC_DRAM_TYPE_FCRAM        1
+#define K_MC_DRAM_TYPE_SGRAM	    2
+
+#define V_MC_DRAM_TYPE_JEDEC        V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_JEDEC)
+#define V_MC_DRAM_TYPE_FCRAM        V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_FCRAM)
+#define V_MC_DRAM_TYPE_SGRAM        V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_SGRAM)
+
+#define M_MC_EXTERNALDECODE	    _SB_MAKEMASK1(35)
+
+
+
+
+/*
+ * SDRAM Timing Register  (Table 6-15)
+ */
+
+#define M_MC_w2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(62)
+#define M_MC_r2wIDLE_TWOCYCLES	  _SB_MAKEMASK1(61)
+#define M_MC_r2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(60)
+
+#define S_MC_tFIFO                56
+#define M_MC_tFIFO                _SB_MAKEMASK(4,S_MC_tFIFO)
+#define V_MC_tFIFO(x)             _SB_MAKEVALUE(x,S_MC_tFIFO)
+#define K_MC_tFIFO_DEFAULT        1
+#define V_MC_tFIFO_DEFAULT        V_MC_tFIFO(K_MC_tFIFO_DEFAULT)
+
+#define S_MC_tRFC                 52
+#define M_MC_tRFC                 _SB_MAKEMASK(4,S_MC_tRFC)
+#define V_MC_tRFC(x)              _SB_MAKEVALUE(x,S_MC_tRFC)
+#define K_MC_tRFC_DEFAULT         12
+#define V_MC_tRFC_DEFAULT         V_MC_tRFC(K_MC_tRFC_DEFAULT)
+
+#define S_MC_tCwCr                40
+#define M_MC_tCwCr                _SB_MAKEMASK(4,S_MC_tCwCr)
+#define V_MC_tCwCr(x)             _SB_MAKEVALUE(x,S_MC_tCwCr)
+#define K_MC_tCwCr_DEFAULT        4
+#define V_MC_tCwCr_DEFAULT        V_MC_tCwCr(K_MC_tCwCr_DEFAULT)
+
+#define S_MC_tRCr                 28
+#define M_MC_tRCr                 _SB_MAKEMASK(4,S_MC_tRCr)
+#define V_MC_tRCr(x)              _SB_MAKEVALUE(x,S_MC_tRCr)
+#define K_MC_tRCr_DEFAULT         9
+#define V_MC_tRCr_DEFAULT         V_MC_tRCr(K_MC_tRCr_DEFAULT)
+
+#define S_MC_tRCw                 24
+#define M_MC_tRCw                 _SB_MAKEMASK(4,S_MC_tRCw)
+#define V_MC_tRCw(x)              _SB_MAKEVALUE(x,S_MC_tRCw)
+#define K_MC_tRCw_DEFAULT         10
+#define V_MC_tRCw_DEFAULT         V_MC_tRCw(K_MC_tRCw_DEFAULT)
+
+#define S_MC_tRRD                 20
+#define M_MC_tRRD                 _SB_MAKEMASK(4,S_MC_tRRD)
+#define V_MC_tRRD(x)              _SB_MAKEVALUE(x,S_MC_tRRD)
+#define K_MC_tRRD_DEFAULT         2
+#define V_MC_tRRD_DEFAULT         V_MC_tRRD(K_MC_tRRD_DEFAULT)
+
+#define S_MC_tRP                  16
+#define M_MC_tRP                  _SB_MAKEMASK(4,S_MC_tRP)
+#define V_MC_tRP(x)               _SB_MAKEVALUE(x,S_MC_tRP)
+#define K_MC_tRP_DEFAULT          4
+#define V_MC_tRP_DEFAULT          V_MC_tRP(K_MC_tRP_DEFAULT)
+
+#define S_MC_tCwD                 8
+#define M_MC_tCwD                 _SB_MAKEMASK(4,S_MC_tCwD)
+#define V_MC_tCwD(x)              _SB_MAKEVALUE(x,S_MC_tCwD)
+#define K_MC_tCwD_DEFAULT         1
+#define V_MC_tCwD_DEFAULT         V_MC_tCwD(K_MC_tCwD_DEFAULT)
+
+#define M_tCrDh                   _SB_MAKEMASK1(7)
+
+#define S_MC_tCrD                 4
+#define M_MC_tCrD                 _SB_MAKEMASK(3,S_MC_tCrD)
+#define V_MC_tCrD(x)              _SB_MAKEVALUE(x,S_MC_tCrD)
+#define K_MC_tCrD_DEFAULT         2
+#define V_MC_tCrD_DEFAULT         V_MC_tCrD(K_MC_tCrD_DEFAULT)
+
+#define S_MC_tRCD                 0
+#define M_MC_tRCD                 _SB_MAKEMASK(4,S_MC_tRCD)
+#define V_MC_tRCD(x)              _SB_MAKEVALUE(x,S_MC_tRCD)
+#define K_MC_tRCD_DEFAULT         3
+#define V_MC_tRCD_DEFAULT         V_MC_tRCD(K_MC_tRCD_DEFAULT)
+
+#define V_MC_TIMING_DEFAULT     V_MC_tFIFO(K_MC_tFIFO_DEFAULT) | \
+                                V_MC_tRFC(K_MC_tRFC_DEFAULT) | \
+                                V_MC_tCwCr(K_MC_tCwCr_DEFAULT) | \
+                                V_MC_tRCr(K_MC_tRCr_DEFAULT) | \
+                                V_MC_tRCw(K_MC_tRCw_DEFAULT) | \
+                                V_MC_tRRD(K_MC_tRRD_DEFAULT) | \
+                                V_MC_tRP(K_MC_tRP_DEFAULT) | \
+                                V_MC_tCwD(K_MC_tCwD_DEFAULT) | \
+                                V_MC_tCrD(K_MC_tCrD_DEFAULT) | \
+                                V_MC_tRCD(K_MC_tRCD_DEFAULT) | \
+                                M_MC_r2rIDLE_TWOCYCLES
+
+/*
+ * Errata says these are not the default
+ *                               M_MC_w2rIDLE_TWOCYCLES | \
+ *                               M_MC_r2wIDLE_TWOCYCLES | \
+ */
+
+
+/*
+ * Chip Select Start Address Register (Table 6-17)
+ */
+
+#define S_MC_CS0_START              0
+#define M_MC_CS0_START              _SB_MAKEMASK(16,S_MC_CS0_START)
+#define V_MC_CS0_START(x)           _SB_MAKEVALUE(x,S_MC_CS0_START)
+#define G_MC_CS0_START(x)           _SB_GETVALUE(x,S_MC_CS0_START,M_MC_CS0_START)
+
+#define S_MC_CS1_START              16
+#define M_MC_CS1_START              _SB_MAKEMASK(16,S_MC_CS1_START)
+#define V_MC_CS1_START(x)           _SB_MAKEVALUE(x,S_MC_CS1_START)
+#define G_MC_CS1_START(x)           _SB_GETVALUE(x,S_MC_CS1_START,M_MC_CS1_START)
+
+#define S_MC_CS2_START              32
+#define M_MC_CS2_START              _SB_MAKEMASK(16,S_MC_CS2_START)
+#define V_MC_CS2_START(x)           _SB_MAKEVALUE(x,S_MC_CS2_START)
+#define G_MC_CS2_START(x)           _SB_GETVALUE(x,S_MC_CS2_START,M_MC_CS2_START)
+
+#define S_MC_CS3_START              48
+#define M_MC_CS3_START              _SB_MAKEMASK(16,S_MC_CS3_START)
+#define V_MC_CS3_START(x)           _SB_MAKEVALUE(x,S_MC_CS3_START)
+#define G_MC_CS3_START(x)           _SB_GETVALUE(x,S_MC_CS3_START,M_MC_CS3_START)
+
+/*
+ * Chip Select End Address Register (Table 6-18)
+ */
+
+#define S_MC_CS0_END                0
+#define M_MC_CS0_END                _SB_MAKEMASK(16,S_MC_CS0_END)
+#define V_MC_CS0_END(x)             _SB_MAKEVALUE(x,S_MC_CS0_END)
+#define G_MC_CS0_END(x)             _SB_GETVALUE(x,S_MC_CS0_END,M_MC_CS0_END)
+
+#define S_MC_CS1_END                16
+#define M_MC_CS1_END                _SB_MAKEMASK(16,S_MC_CS1_END)
+#define V_MC_CS1_END(x)             _SB_MAKEVALUE(x,S_MC_CS1_END)
+#define G_MC_CS1_END(x)             _SB_GETVALUE(x,S_MC_CS1_END,M_MC_CS1_END)
+
+#define S_MC_CS2_END                32
+#define M_MC_CS2_END                _SB_MAKEMASK(16,S_MC_CS2_END)
+#define V_MC_CS2_END(x)             _SB_MAKEVALUE(x,S_MC_CS2_END)
+#define G_MC_CS2_END(x)             _SB_GETVALUE(x,S_MC_CS2_END,M_MC_CS2_END)
+
+#define S_MC_CS3_END                48
+#define M_MC_CS3_END                _SB_MAKEMASK(16,S_MC_CS3_END)
+#define V_MC_CS3_END(x)             _SB_MAKEVALUE(x,S_MC_CS3_END)
+#define G_MC_CS3_END(x)             _SB_GETVALUE(x,S_MC_CS3_END,M_MC_CS3_END)
+
+/*
+ * Chip Select Interleave Register (Table 6-19)
+ */
+
+#define S_MC_INTLV_RESERVED         0
+#define M_MC_INTLV_RESERVED         _SB_MAKEMASK(5,S_MC_INTLV_RESERVED)
+
+#define S_MC_INTERLEAVE             7
+#define M_MC_INTERLEAVE             _SB_MAKEMASK(18,S_MC_INTERLEAVE)
+#define V_MC_INTERLEAVE(x)          _SB_MAKEVALUE(x,S_MC_INTERLEAVE)
+
+#define S_MC_INTLV_MBZ              25
+#define M_MC_INTLV_MBZ              _SB_MAKEMASK(39,S_MC_INTLV_MBZ)
+
+/*
+ * Row Address Bits Register (Table 6-20)
+ */
+
+#define S_MC_RAS_RESERVED           0
+#define M_MC_RAS_RESERVED           _SB_MAKEMASK(5,S_MC_RAS_RESERVED)
+
+#define S_MC_RAS_SELECT             12
+#define M_MC_RAS_SELECT             _SB_MAKEMASK(25,S_MC_RAS_SELECT)
+#define V_MC_RAS_SELECT(x)          _SB_MAKEVALUE(x,S_MC_RAS_SELECT)
+
+#define S_MC_RAS_MBZ                37
+#define M_MC_RAS_MBZ                _SB_MAKEMASK(27,S_MC_RAS_MBZ)
+
+
+/*
+ * Column Address Bits Register (Table 6-21)
+ */
+
+#define S_MC_CAS_RESERVED           0
+#define M_MC_CAS_RESERVED           _SB_MAKEMASK(5,S_MC_CAS_RESERVED)
+
+#define S_MC_CAS_SELECT             5
+#define M_MC_CAS_SELECT             _SB_MAKEMASK(18,S_MC_CAS_SELECT)
+#define V_MC_CAS_SELECT(x)          _SB_MAKEVALUE(x,S_MC_CAS_SELECT)
+
+#define S_MC_CAS_MBZ                23
+#define M_MC_CAS_MBZ                _SB_MAKEMASK(41,S_MC_CAS_MBZ)
+
+
+/*
+ * Bank Address Address Bits Register (Table 6-22)
+ */
+
+#define S_MC_BA_RESERVED            0
+#define M_MC_BA_RESERVED            _SB_MAKEMASK(5,S_MC_BA_RESERVED)
+
+#define S_MC_BA_SELECT              5
+#define M_MC_BA_SELECT              _SB_MAKEMASK(20,S_MC_BA_SELECT)
+#define V_MC_BA_SELECT(x)           _SB_MAKEVALUE(x,S_MC_BA_SELECT)
+
+#define S_MC_BA_MBZ                 25
+#define M_MC_BA_MBZ                 _SB_MAKEMASK(39,S_MC_BA_MBZ)
+
+/*
+ * Chip Select Attribute Register (Table 6-23)
+ */
+
+#define K_MC_CS_ATTR_CLOSED         0
+#define K_MC_CS_ATTR_CASCHECK       1
+#define K_MC_CS_ATTR_HINT           2
+#define K_MC_CS_ATTR_OPEN           3
+
+#define S_MC_CS0_PAGE               0
+#define M_MC_CS0_PAGE               _SB_MAKEMASK(2,S_MC_CS0_PAGE)
+#define V_MC_CS0_PAGE(x)            _SB_MAKEVALUE(x,S_MC_CS0_PAGE)
+#define G_MC_CS0_PAGE(x)            _SB_GETVALUE(x,S_MC_CS0_PAGE,M_MC_CS0_PAGE)
+
+#define S_MC_CS1_PAGE               16
+#define M_MC_CS1_PAGE               _SB_MAKEMASK(2,S_MC_CS1_PAGE)
+#define V_MC_CS1_PAGE(x)            _SB_MAKEVALUE(x,S_MC_CS1_PAGE)
+#define G_MC_CS1_PAGE(x)            _SB_GETVALUE(x,S_MC_CS1_PAGE,M_MC_CS1_PAGE)
+
+#define S_MC_CS2_PAGE               32
+#define M_MC_CS2_PAGE               _SB_MAKEMASK(2,S_MC_CS2_PAGE)
+#define V_MC_CS2_PAGE(x)            _SB_MAKEVALUE(x,S_MC_CS2_PAGE)
+#define G_MC_CS2_PAGE(x)            _SB_GETVALUE(x,S_MC_CS2_PAGE,M_MC_CS2_PAGE)
+
+#define S_MC_CS3_PAGE               48
+#define M_MC_CS3_PAGE               _SB_MAKEMASK(2,S_MC_CS3_PAGE)
+#define V_MC_CS3_PAGE(x)            _SB_MAKEVALUE(x,S_MC_CS3_PAGE)
+#define G_MC_CS3_PAGE(x)            _SB_GETVALUE(x,S_MC_CS3_PAGE,M_MC_CS3_PAGE)
+
+/*
+ * ECC Test ECC Register (Table 6-25)
+ */
+
+#define S_MC_ECC_INVERT             0
+#define M_MC_ECC_INVERT             _SB_MAKEMASK(8,S_MC_ECC_INVERT)
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_pci.h linux/include/asm-mips64/sibyte/sb1250_pci.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_pci.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,250 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  PCI constants				File: sb1250_pci.h
+    *  
+    *  This module contains constants and macros to describe 
+    *  the PCI interface on the SB1250.  
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_PCI_H
+#define _SB1250_PCI_H
+
+#include "sb1250_defs.h"
+
+#define K_PCI_VENDOR_SIBYTE	0x166D
+#define K_PCI_DEVICE_SB1250	0x0001
+
+/*
+ * PCI Interface Type 0 configuration header
+ */
+
+#define R_PCI_TYPE0_DEVICEID	0x0000
+#define R_PCI_TYPE0_CMDSTATUS	0x0004
+#define R_PCI_TYPE0_CLASSREV	0x0008
+#define R_PCI_TYPE0_DEVHDR	0x000C
+#define R_PCI_TYPE0_BAR0	0x0010	/* translated via mapping table */
+#define R_PCI_TYPE0_BAR1	0x0014	/* reserved */
+#define R_PCI_TYPE0_BAR2	0x0018	/* mbox 0 */
+#define R_PCI_TYPE0_BAR3	0x001C	/* mbox 1 */
+#define R_PCI_TYPE0_BAR4	0x0020	/* low memory */
+#define R_PCI_TYPE0_BAR5	0x0024	/* high memory */
+#define R_PCI_TYPE0_CARDBUSCIS	0x0028
+#define R_PCI_TYPE0_SUBSYSID	0x002C
+#define R_PCI_TYPE0_ROMBASE	0x0030
+#define R_PCI_TYPE0_CAPPTR	0x0034	/* not used */
+#define R_PCI_TYPE0_RESERVED1	0x0038
+#define R_PCI_TYPE0_INTGRANT	0x003C	/* interrupt pin and grant latency */
+#define R_PCI_TYPE0_TIMEOUT	0x0040	/* FControl, Timeout */
+#define R_PCI_TYPE0_FCONTROL	0x0040	/* FControl, Timeout */
+#define R_PCI_TYPE0_MAPBASE	0x0044	/* 0x44 through 0x80 - map table */
+#define PCI_TYPE0_MAPENTRIES	32	/* 64 bytes, 32 entries */
+#define R_PCI_TYPE0_ERRORADDR	0x0084
+#define R_PCI_TYPE0_ADDSTATUS	0x0088
+#define R_PCI_TYPE0_SUBSYSSET	0x008C	/* only accessible from ZBBus */
+
+/*
+ * PCI Device ID register
+ */
+
+#define S_PCI_DEVICEID_VENDOR		0
+#define M_PCI_DEVICEID_VENDOR		_SB_MAKEMASK_32(16,S_PCI_DEVICEID_VENDOR)
+#define V_PCI_DEVICEID_VENDOR(x)	_SB_MAKEVALUE_32(x,S_PCI_DEVICEID_VENDOR)
+#define G_PCI_DEVICEID_VENDOR(x)	_SB_GETVALUE_32(x,S_PCI_DEVICEID_VENDOR,M_PCI_DEVICEID_VENDOR)
+
+#define S_PCI_DEVICEID_DEVICEID		16
+#define M_PCI_DEVICEID_DEVICEID		_SB_MAKEMASK_32(16,S_PCI_DEVICEID_DEVICEID)
+#define V_PCI_DEVICEID_DEVICEID(x)	_SB_MAKEVALUE_32(x,S_PCI_DEVICEID_DEVICEID)
+#define G_PCI_DEVICEID_DEVICEID(x)	_SB_GETVALUE_32(x,S_PCI_DEVICEID_DEVICEID,M_PCI_DEVICEID_DEVICEID)
+
+
+/*
+ * PCI Command Register (Table 8-4)
+ */
+
+#define M_PCI_CMD_IOSPACE_EN		_SB_MAKEMASK1_32(0)
+#define M_PCI_CMD_MEMSPACE_EN		_SB_MAKEMASK1_32(1)
+#define M_PCI_CMD_MASTER_EN		_SB_MAKEMASK1_32(2)
+#define M_PCI_CMD_SPECCYC_EN		_SB_MAKEMASK1_32(3)
+#define M_PCI_CMD_MEMWRINV_EN		_SB_MAKEMASK1_32(4)
+#define M_PCI_CMD_VGAPALSNP_EN		_SB_MAKEMASK1_32(5)
+#define M_PCI_CMD_PARERRRESP		_SB_MAKEMASK1_32(6)
+#define M_PCI_CMD_STEPCTRL		_SB_MAKEMASK1_32(7)
+#define M_PCI_CMD_SERR_EN		_SB_MAKEMASK1_32(8)
+#define M_PCI_CMD_FASTB2B_EN		_SB_MAKEMASK1_32(9)
+
+/*
+ * PCI class and revision registers
+ */
+
+#define S_PCI_CLASSREV_REV		0
+#define M_PCI_CLASSREV_REV		_SB_MAKEMASK_32(8,S_PCI_CLASSREV_REV)
+#define V_PCI_CLASSREV_REV(x)		_SB_MAKEVALUE_32(x,S_PCI_CLASSREV_REV)
+#define G_PCI_CLASSREV_REV(x)		_SB_GETVALUE_32(x,S_PCI_CLASSREV_REV,M_PCI_CLASSREV_REV)
+
+#define S_PCI_CLASSREV_CLASS		8
+#define M_PCI_CLASSREV_CLASS		_SB_MAKEMASK_32(24,S_PCI_CLASSREV_CLASS)
+#define V_PCI_CLASSREV_CLASS(x)		_SB_MAKEVALUE_32(x,S_PCI_CLASSREV_CLASS)
+#define G_PCI_CLASSREV_CLASS(x)		_SB_GETVALUE_32(x,S_PCI_CLASSREV_CLASS,M_PCI_CLASSREV_CLASS)
+
+#define K_PCI_REV			0x01
+#define K_PCI_CLASS			0x060000
+
+/*
+ * Device Header (offset 0x0C)
+ */
+
+#define S_PCI_DEVHDR_CLINESZ		0
+#define M_PCI_DEVHDR_CLINESZ		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_CLINESZ)
+#define V_PCI_DEVHDR_CLINESZ(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_CLINESZ)
+#define G_PCI_DEVHDR_CLINESZ(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_CLINESZ,M_PCI_DEVHDR_CLINESZ)
+
+#define S_PCI_DEVHDR_LATTMR		8
+#define M_PCI_DEVHDR_LATTMR		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_LATTMR)
+#define V_PCI_DEVHDR_LATTMR(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_LATTMR)
+#define G_PCI_DEVHDR_LATTMR(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_LATTMR,M_PCI_DEVHDR_LATTMR)
+
+#define S_PCI_DEVHDR_HDRTYPE		16
+#define M_PCI_DEVHDR_HDRTYPE		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_HDRTYPE)
+#define V_PCI_DEVHDR_HDRTYPE(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_HDRTYPE)
+#define G_PCI_DEVHDR_HDRTYPE(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_HDRTYPE,M_PCI_DEVHDR_HDRTYPE)
+
+#define K_PCI_DEVHDR_HDRTYPE_TYPE0	0
+
+#define S_PCI_DEVHDR_BIST		24
+#define M_PCI_DEVHDR_BIST		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_BIST)
+#define V_PCI_DEVHDR_BIST(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_BIST)
+#define G_PCI_DEVHDR_BIST(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_BIST,M_PCI_DEVHDR_BIST)
+
+/*
+ * PCI Status Register (Table 8-5).  Note that these constants
+ * assume you've read the command and status register 
+ * together (32-bit read at offset 0x04)
+ */
+
+#define M_PCI_STATUS_CAPLIST		_SB_MAKEMASK1_32(20)
+#define M_PCI_STATUS_66MHZCAP		_SB_MAKEMASK1_32(21)
+#define M_PCI_STATUS_RESERVED2		_SB_MAKEMASK1_32(22)
+#define M_PCI_STATUS_FASTB2BCAP		_SB_MAKEMASK1_32(23)
+#define M_PCI_STATUS_MSTRDPARERR	_SB_MAKEMASK1_32(24)
+
+#define S_PCI_STATUS_DEVSELTIMING	25
+#define M_PCI_STATUS_DEVSELTIMING	_SB_MAKEMASK_32(2,S_PCI_STATUS_DEVSELTIMING)
+#define V_PCI_STATUS_DEVSELTIMING(x)	_SB_MAKEVALUE_32(x,S_PCI_STATUS_DEVSELTIMING)
+#define G_PCI_STATUS_DEVSELTIMING(x)	_SB_GETVALUE_32(x,S_PCI_STATUS_DEVSELTIMING,M_PCI_STATUS_DEVSELTIMING)
+
+#define M_PCI_STATUS_SIGDTGTABORT	_SB_MAKEMASK1_32(27)
+#define M_PCI_STATUS_RCVDTGTABORT	_SB_MAKEMASK1_32(28)
+#define M_PCI_STATUS_RCVDMSTRABORT	_SB_MAKEMASK1_32(29)
+#define M_PCI_STATUS_SIGDSERR		_SB_MAKEMASK1_32(30)
+#define M_PCI_STATUS_DETPARERR		_SB_MAKEMASK1_32(31)
+
+/*
+ * Device Header Register (Table 8-6, Table 8-7)
+ */
+
+#define S_PCI_DEVHDR_CLINESZ		0
+#define M_PCI_DEVHDR_CLINESZ		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_CLINESZ)
+#define V_PCI_DEVHDR_CLINESZ(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_CLINESZ)
+#define G_PCI_DEVHDR_CLINESZ(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_CLINESZ,M_PCI_DEVHDR_CLINESZ)
+
+#define S_PCI_DEVHDR_LATTIME		8
+#define M_PCI_DEVHDR_LATTIME		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_LATTIME)
+#define V_PCI_DEVHDR_LATTIME(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_LATTIME)
+#define G_PCI_DEVHDR_LATTIME(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_LATTIME,M_PCI_DEVHDR_LATTIME)
+
+#define S_PCI_DEVHDR_HDRTYPE		16
+#define M_PCI_DEVHDR_HDRTYPE		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_HDRTYPE)
+#define V_PCI_DEVHDR_HDRTYPE(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_HDRTYPE)
+#define G_PCI_DEVHDR_HDRTYPE(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_HDRTYPE,M_PCI_DEVHDR_HDRTYPE)
+
+#define S_PCI_DEVHDR_BIST		24
+#define M_PCI_DEVHDR_BIST		_SB_MAKEMASK_32(8,S_PCI_DEVHDR_BIST)
+#define V_PCI_DEVHDR_BIST(x)		_SB_MAKEVALUE_32(x,S_PCI_DEVHDR_BIST)
+#define G_PCI_DEVHDR_BIST(x)		_SB_GETVALUE_32(x,S_PCI_DEVHDR_BIST,M_PCI_DEVHDR_BIST)
+
+/*
+ * Timeout and feature control Register (Table 8-8) (Table 8-9)
+ * Note that these constants assume you've read the timeout/fcontrol register
+ * together (32-bit read at offset 0x40)
+ */
+
+#define S_PCI_TIMEOUT_TRDY		0
+#define M_PCI_TIMEOUT_TRDY		_SB_MAKEMASK_32(8,S_PCI_TIMEOUT_TRDY)
+#define V_PCI_TIMEOUT_TRDY(x)		_SB_MAKEVALUE_32(x,S_PCI_TIMEOUT_TRDY)
+#define G_PCI_TIMEOUT_TRDY(x)		_SB_GETVALUE_32(x,S_PCI_TIMEOUT_TRDY,M_PCI_TIMEOUT_TRDY)
+
+#define S_PCI_TIMEOUT_RETRY		8
+#define M_PCI_TIMEOUT_RETRY		_SB_MAKEMASK_32(8,S_PCI_TIMEOUT_RETRY)
+#define V_PCI_TIMEOUT_RETRY(x)		_SB_MAKEVALUE_32(x,S_PCI_TIMEOUT_RETRY)
+#define G_PCI_TIMEOUT_RETRY(x)		_SB_GETVALUE_32(x,S_PCI_TIMEOUT_RETRY,M_PCI_TIMEOUT_RETRY)
+
+#define M_PCI_FCONTROL_BAR4_EN		_SB_MAKEMASK1_32(16)
+#define M_PCI_FCONTROL_BAR5_EN		_SB_MAKEMASK1_32(17)
+#define M_PCI_FCONTROL_PTP_EN		_SB_MAKEMASK1_32(18)
+#define M_PCI_FCONTROL_ADAPT_RETRY_EN	_SB_MAKEMASK1_32(19)
+
+#define S_PCI_FCONTROL_MIN_TAR_RETRY	20
+#define M_PCI_FCONTROL_MIN_TAR_RETRY	_SB_MAKEMASK_32(3,S_PCI_FCONTROL_MIN_TAR_RETRY)
+#define V_PCI_FCONTROL_MIN_TAR_RETRY(x)	_SB_MAKEVALUE_32(x,S_PCI_FCONTROL_MIN_TAR_RETRY)
+#define G_PCI_FCONTROL_MIN_TAR_RETRY(x)	_SB_GETVALUE_32(x,S_PCI_FCONTROL_MIN_TAR_RETRY,M_PCI_FCONTROL_MIN_TAR_RETRY)
+
+#define S_PCI_FCONTROL_NOM_TAR_RETRY	23
+#define M_PCI_FCONTROL_NOM_TAR_RETRY	_SB_MAKEMASK_32(4,S_PCI_FCONTROL_NOM_TAR_RETRY)
+#define V_PCI_FCONTROL_NOM_TAR_RETRY(x)	_SB_MAKEVALUE_32(x,S_PCI_FCONTROL_NOM_TAR_RETRY)
+#define G_PCI_FCONTROL_NOM_TAR_RETRY(x)	_SB_GETVALUE_32(x,S_PCI_FCONTROL_NOM_TAR_RETRY,M_PCI_FCONTROL_NOM_TAR_RETRY)
+
+#define S_PCI_FCONTROL_MAX_TAR_RETRY	27
+#define M_PCI_FCONTROL_MAX_TAR_RETRY	_SB_MAKEMASK_32(5,S_PCI_FCONTROL_MAX_TAR_RETRY)
+#define V_PCI_FCONTROL_MAX_TAR_RETRY(x)	_SB_MAKEVALUE_32(x,S_PCI_FCONTROL_MAX_TAR_RETRY)
+#define G_PCI_FCONTROL_MAX_TAR_RETRY(x)	_SB_GETVALUE_32(x,S_PCI_FCONTROL_MAX_TAR_RETRY,M_PCI_FCONTROL_MAX_TAR_RETRY)
+
+/*
+ * BAR0 Map Table Entry (Offsets 0x40-0x80) (Table 8-10)
+ */
+
+#define M_PCI_BAR0MAP_ENABLE		_SB_MAKEMASK1_32(0)
+#define M_PCI_BAR0MAP_SENDLDT		_SB_MAKEMASK1_32(1)
+#define S_PCI_BAR0MAP_ADDR		12
+#define M_PCI_BAR0MAP_ADDR		_SB_MAKEMASK_32(20,S_PCI_BAR0MAP_ADDR)
+
+/*
+ * Additional Status Register (Table 8-11)
+ */
+
+#define M_PCI_ASTATUS_HOTPLUG_EN	_SB_MAKEMASK1_32(0)
+#define M_PCI_ASTATUS_SERR_DET		_SB_MAKEMASK1_32(1)
+#define M_PCI_ASTATUS_TRDYERR		_SB_MAKEMASK1_32(2)
+#define M_PCI_ASTATUS_RETRTYERR		_SB_MAKEMASK1_32(3)
+#define M_PCI_ASTATUS_TRDYINTMASK	_SB_MAKEMASK1_32(4)
+#define M_PCI_ASTATUS_RETRYINTMASK	_SB_MAKEMASK1_32(5)
+#define M_PCI_ASTATUS_SIGNALINTA	_SB_MAKEMASK1_32(6)
+
+#endif
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_regs.h linux/include/asm-mips64/sibyte/sb1250_regs.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_regs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_regs.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,744 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  Register Definitions                     File: sb1250_regs.h
+    *  
+    *  This module contains the addresses of the on-chip peripherals
+    *  on the SB1250.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_REGS_H
+#define _SB1250_REGS_H
+
+#include "sb1250_defs.h"
+
+
+/*  *********************************************************************
+    *  Some general notes:
+    *  
+    *  For the most part, when there is more than one peripheral
+    *  of the same type on the SOC, the constants below will be
+    *  offsets from the base of each peripheral.  For example,
+    *  the MAC registers are described as offsets from the first
+    *  MAC register, and there will be a MAC_REGISTER() macro
+    *  to calculate the base address of a given MAC.  
+    *  
+    *  The information in this file is based on the SB1250 SOC
+    *  manual version 0.2, July 2000.
+    ********************************************************************* */
+
+
+/*  ********************************************************************* 
+    * Memory Controller Registers
+    ********************************************************************* */
+
+#define A_MC_BASE_0                 0x0010051000
+#define A_MC_BASE_1                 0x0010052000
+#define MC_REGISTER_SPACING         0x1000
+
+#define A_MC_BASE(ctlid)            ((ctlid)*MC_REGISTER_SPACING+A_MC_BASE_0)
+#define A_MC_REGISTER(ctlid,reg)    (A_MC_BASE(ctlid)+(reg))
+
+#define R_MC_CONFIG                 0x0000000100
+#define R_MC_DRAMCMD                0x0000000120
+#define R_MC_DRAMMODE               0x0000000140
+#define R_MC_TIMING1                0x0000000160
+#define R_MC_TIMING2                0x0000000180
+#define R_MC_CS_START               0x00000001A0
+#define R_MC_CS_END                 0x00000001C0
+#define R_MC_CS_INTERLEAVE          0x00000001E0
+#define S_MC_CS_STARTEND            16
+
+#define R_MC_CSX_BASE               0x0000000200
+#define R_MC_CSX_ROW                0x0000000000	/* relative to CSX_BASE, above */
+#define R_MC_CSX_COL                0x0000000020	/* relative to CSX_BASE, above */
+#define R_MC_CSX_BA                 0x0000000040	/* relative to CSX_BASE, above */
+#define MC_CSX_SPACING              0x0000000060	/* relative to CSX_BASE, above */
+
+#define R_MC_CS0_ROW                0x0000000200
+#define R_MC_CS0_COL                0x0000000220
+#define R_MC_CS0_BA                 0x0000000240
+#define R_MC_CS1_ROW                0x0000000260
+#define R_MC_CS1_COL                0x0000000280
+#define R_MC_CS1_BA                 0x00000002A0
+#define R_MC_CS2_ROW                0x00000002C0
+#define R_MC_CS2_COL                0x00000002E0
+#define R_MC_CS2_BA                 0x0000000300
+#define R_MC_CS3_ROW                0x0000000320
+#define R_MC_CS3_COL                0x0000000340
+#define R_MC_CS3_BA                 0x0000000360
+#define R_MC_CS_ATTR                0x0000000380
+#define R_MC_TEST_DATA              0x0000000400
+#define R_MC_TEST_ECC               0x0000000420
+#define R_MC_MCLK_CFG               0x0000000500
+
+/*  ********************************************************************* 
+    * L2 Cache Control Registers
+    ********************************************************************* */
+
+#define A_L2_READ_ADDRESS           0x0010040018
+#define A_L2_EEC_ADDRESS            0x0010040038
+#define A_L2_WAY_DISABLE            0x0010041000
+#define A_L2_MAKEDISABLE(x)         (A_L2_WAY_DISABLE | (((~(x))&0x0F) << 8))
+#define A_L2_MGMT_TAG_BASE          0x00D0000000
+
+/*  ********************************************************************* 
+    * PCI Interface Registers
+    ********************************************************************* */
+
+#define A_PCI_TYPE00_HEADER         0x00DE000000
+#define A_PCI_TYPE01_HEADER         0x00DE000800
+
+
+/*  ********************************************************************* 
+    * Ethernet DMA and MACs
+    ********************************************************************* */
+
+#define A_MAC_BASE_0                0x0010064000
+#define A_MAC_BASE_1                0x0010065000
+#define A_MAC_BASE_2                0x0010066000
+
+#define MAC_SPACING                 0x1000
+#define MAC_DMA_TXRX_SPACING        0x0400
+#define MAC_DMA_CHANNEL_SPACING     0x0100
+#define DMA_RX                      0
+#define DMA_TX                      1
+#define MAC_NUM_DMACHAN		    2		    /* channels per direction */
+
+#define MAC_NUM_PORTS               3
+
+#define A_MAC_CHANNEL_BASE(macnum)                  \
+            (A_MAC_BASE_0 +                         \
+             MAC_SPACING*(macnum))
+
+#define A_MAC_REGISTER(macnum,reg)                  \
+            (A_MAC_BASE_0 +                         \
+             MAC_SPACING*(macnum) + (reg))
+
+
+#define R_MAC_DMA_CHANNELS		0x800 /* Relative to A_MAC_CHANNEL_BASE */
+
+#define A_MAC_DMA_CHANNEL_BASE(macnum,txrx,chan)    \
+             ((A_MAC_CHANNEL_BASE(macnum)) +        \
+             R_MAC_DMA_CHANNELS +                   \
+             (MAC_DMA_TXRX_SPACING*(txrx)) +        \
+             (MAC_DMA_CHANNEL_SPACING*(chan)))
+
+#define R_MAC_DMA_CHANNEL_BASE(txrx,chan)    \
+             (R_MAC_DMA_CHANNELS +                   \
+             (MAC_DMA_TXRX_SPACING*(txrx)) +        \
+             (MAC_DMA_CHANNEL_SPACING*(chan)))
+
+#define A_MAC_DMA_REGISTER(macnum,txrx,chan,reg)           \
+            (A_MAC_DMA_CHANNEL_BASE(macnum,txrx,chan) +    \
+            (reg))
+
+#define R_MAC_DMA_REGISTER(txrx,chan,reg)           \
+            (R_MAC_DMA_CHANNEL_BASE(txrx,chan) +    \
+            (reg))
+
+/* 
+ * DMA channel registers, relative to A_MAC_DMA_CHANNEL_BASE
+ */
+
+#define R_MAC_DMA_CONFIG0               0x00000000
+#define R_MAC_DMA_CONFIG1               0x00000008
+#define R_MAC_DMA_DSCR_BASE             0x00000010
+#define R_MAC_DMA_DSCR_CNT              0x00000018
+#define R_MAC_DMA_CUR_DSCRA             0x00000020
+#define R_MAC_DMA_CUR_DSCRB             0x00000028
+#define R_MAC_DMA_CUR_DSCRADDR          0x00000030
+
+/*
+ * RMON Counters
+ */
+
+#define R_MAC_RMON_TX_BYTES             0x00000000
+#define R_MAC_RMON_COLLISIONS           0x00000008
+#define R_MAC_RMON_LATE_COL             0x00000010
+#define R_MAC_RMON_EX_COL               0x00000018
+#define R_MAC_RMON_FCS_ERROR            0x00000020
+#define R_MAC_RMON_TX_ABORT             0x00000028
+/* Counter #6 (0x30) now reserved */
+#define R_MAC_RMON_TX_BAD               0x00000038
+#define R_MAC_RMON_TX_GOOD              0x00000040
+#define R_MAC_RMON_TX_RUNT              0x00000048
+#define R_MAC_RMON_TX_OVERSIZE          0x00000050
+#define R_MAC_RMON_RX_BYTES             0x00000080
+#define R_MAC_RMON_RX_MCAST             0x00000088
+#define R_MAC_RMON_RX_BCAST             0x00000090
+#define R_MAC_RMON_RX_BAD               0x00000098
+#define R_MAC_RMON_RX_GOOD              0x000000A0
+#define R_MAC_RMON_RX_RUNT              0x000000A8
+#define R_MAC_RMON_RX_OVERSIZE          0x000000B0
+#define R_MAC_RMON_RX_FCS_ERROR         0x000000B8
+#define R_MAC_RMON_RX_LENGTH_ERROR      0x000000C0
+#define R_MAC_RMON_RX_CODE_ERROR        0x000000C8
+#define R_MAC_RMON_RX_ALIGN_ERROR       0x000000D0
+
+/* Updated to spec 0.2 */
+#define R_MAC_CFG                       0x00000100
+#define R_MAC_THRSH_CFG                 0x00000108
+#define R_MAC_VLANTAG                   0x00000110
+#define R_MAC_FRAMECFG                  0x00000118
+#define R_MAC_EOPCNT                    0x00000120
+#define R_MAC_FIFO_PTRS                 0x00000130
+#define R_MAC_ADFILTER_CFG              0x00000200
+#define R_MAC_ETHERNET_ADDR             0x00000208
+#define R_MAC_PKT_TYPE                  0x00000210
+#define R_MAC_HASH_BASE                 0x00000240
+#define R_MAC_ADDR_BASE                 0x00000280
+#define R_MAC_CHLO0_BASE                0x00000300
+#define R_MAC_CHUP0_BASE                0x00000320
+#define R_MAC_ENABLE                    0x00000400
+#define R_MAC_STATUS                    0x00000408
+#define R_MAC_INT_MASK                  0x00000410
+#define R_MAC_TXD_CTL                   0x00000420
+#define R_MAC_MDIO                      0x00000428
+#define R_MAC_DEBUG_STATUS              0x00000448
+
+#define MAC_HASH_COUNT			8
+#define MAC_ADDR_COUNT			8
+#define MAC_CHMAP_COUNT			4
+
+
+/*  ********************************************************************* 
+    * DUART Registers
+    ********************************************************************* */
+
+
+#define R_DUART_NUM_PORTS           2
+
+#define A_DUART                     0x0010060000
+
+#define A_DUART_REG(r)
+
+#define DUART_CHANREG_SPACING       0x100
+#define A_DUART_CHANREG(chan,reg)   (A_DUART + DUART_CHANREG_SPACING*(chan) + (reg))
+#define R_DUART_CHANREG(chan,reg)   (DUART_CHANREG_SPACING*(chan) + (reg))
+
+#define R_DUART_MODE_REG_1	    0x100
+#define R_DUART_MODE_REG_2	    0x110
+#define R_DUART_STATUS              0x120
+#define R_DUART_CLK_SEL             0x130
+#define R_DUART_CMD                 0x150
+#define R_DUART_RX_HOLD             0x160
+#define R_DUART_TX_HOLD             0x170
+
+/*
+ * The IMR and ISR can't be addressed with A_DUART_CHANREG,
+ * so use this macro instead.
+ */
+
+#define R_DUART_AUX_CTRL            0x310
+#define R_DUART_ISR_A               0x320
+#define R_DUART_IMR_A               0x330
+#define R_DUART_ISR_B               0x340
+#define R_DUART_IMR_B               0x350
+#define R_DUART_OUT_PORT            0x360
+#define R_DUART_OPCR                0x370
+
+#define R_DUART_SET_OPR		    0x3B0
+#define R_DUART_CLEAR_OPR	    0x3C0
+
+#define DUART_IMRISR_SPACING        0x20
+
+#define R_DUART_IMRREG(chan)	    (R_DUART_IMR_A + (chan)*DUART_IMRISR_SPACING)
+#define R_DUART_ISRREG(chan)	    (R_DUART_ISR_A + (chan)*DUART_IMRISR_SPACING)
+
+#define A_DUART_IMRREG(chan)	    (A_DUART + R_DUART_IMRREG(chan))
+#define A_DUART_ISRREG(chan)	    (A_DUART + R_DUART_ISRREG(chan))
+
+/*
+ * These constants are the absolute addresses.
+ */
+
+#define A_DUART_MODE_REG_1_A        0x0010060100
+#define A_DUART_MODE_REG_2_A        0x0010060110
+#define A_DUART_STATUS_A            0x0010060120
+#define A_DUART_CLK_SEL_A           0x0010060130
+#define A_DUART_CMD_A               0x0010060150
+#define A_DUART_RX_HOLD_A           0x0010060160
+#define A_DUART_TX_HOLD_A           0x0010060170
+
+#define A_DUART_MODE_REG_1_B        0x0010060200
+#define A_DUART_MODE_REG_2_B        0x0010060210
+#define A_DUART_STATUS_B            0x0010060220
+#define A_DUART_CLK_SEL_B           0x0010060230
+#define A_DUART_CMD_B               0x0010060250
+#define A_DUART_RX_HOLD_B           0x0010060260
+#define A_DUART_TX_HOLD_B           0x0010060270
+
+#define A_DUART_INPORT_CHNG         0x0010060300
+#define A_DUART_AUX_CTRL            0x0010060310
+#define A_DUART_ISR_A               0x0010060320
+#define A_DUART_IMR_A               0x0010060330
+#define A_DUART_ISR_B               0x0010060340
+#define A_DUART_IMR_B               0x0010060350
+#define A_DUART_OUT_PORT            0x0010060360
+#define A_DUART_OPCR                0x0010060370
+#define A_DUART_IN_PORT             0x0010060380
+#define A_DUART_ISR                 0x0010060390
+#define A_DUART_IMR                 0x00100603A0
+#define A_DUART_SET_OPR             0x00100603B0
+#define A_DUART_CLEAR_OPR           0x00100603C0
+#define A_DUART_INPORT_CHNG_A       0x00100603D0
+#define A_DUART_INPORT_CHNG_B       0x00100603E0
+
+/*  ********************************************************************* 
+    * Synchronous Serial Registers
+    ********************************************************************* */
+
+
+#define A_SER_BASE_0                0x0010060400
+#define A_SER_BASE_1                0x0010060800
+#define SER_SPACING                 0x400
+
+#define SER_DMA_TXRX_SPACING        0x80
+
+#define SER_NUM_PORTS               2
+
+#define A_SER_CHANNEL_BASE(sernum)                  \
+            (A_SER_BASE_0 +                         \
+             SER_SPACING*(sernum))
+
+#define A_SER_REGISTER(sernum,reg)                  \
+            (A_SER_BASE_0 +                         \
+             SER_SPACING*(sernum) + (reg))
+
+
+#define R_SER_DMA_CHANNELS		0   /* Relative to A_SER_BASE_x */
+
+#define A_SER_DMA_CHANNEL_BASE(sernum,txrx)    \
+             ((A_SER_CHANNEL_BASE(sernum)) +        \
+             R_SER_DMA_CHANNELS +                   \
+             (SER_DMA_TXRX_SPACING*(txrx)))
+
+#define A_SER_DMA_REGISTER(sernum,txrx,reg)           \
+            (A_SER_DMA_CHANNEL_BASE(sernum,txrx) +    \
+            (reg))
+
+
+/* 
+ * DMA channel registers, relative to A_SER_DMA_CHANNEL_BASE
+ */
+
+#define R_SER_DMA_CONFIG0           0x00000000
+#define R_SER_DMA_CONFIG1           0x00000008
+#define R_SER_DMA_DSCR_BASE         0x00000010
+#define R_SER_DMA_DSCR_CNT          0x00000018
+#define R_SER_DMA_CUR_DSCRA         0x00000020
+#define R_SER_DMA_CUR_DSCRB         0x00000028
+#define R_SER_DMA_CUR_DSCRADDR      0x00000030
+
+#define R_SER_DMA_CONFIG0_RX        0x00000000
+#define R_SER_DMA_CONFIG1_RX        0x00000008
+#define R_SER_DMA_DSCR_BASE_RX      0x00000010
+#define R_SER_DMA_DSCR_COUNT_RX     0x00000018
+#define R_SER_DMA_CUR_DSCR_A_RX     0x00000020
+#define R_SER_DMA_CUR_DSCR_B_RX     0x00000028
+#define R_SER_DMA_CUR_DSCR_ADDR_RX  0x00000030
+
+#define R_SER_DMA_CONFIG0_TX        0x00000080
+#define R_SER_DMA_CONFIG1_TX        0x00000088
+#define R_SER_DMA_DSCR_BASE_TX      0x00000090
+#define R_SER_DMA_DSCR_COUNT_TX     0x00000098
+#define R_SER_DMA_CUR_DSCR_A_TX     0x000000A0
+#define R_SER_DMA_CUR_DSCR_B_TX     0x000000A8
+#define R_SER_DMA_CUR_DSCR_ADDR_TX  0x000000B0
+
+#define R_SER_MODE                  0x00000100
+#define R_SER_MINFRM_SZ             0x00000108
+#define R_SER_MAXFRM_SZ             0x00000110
+#define R_SER_ADDR                  0x00000118
+#define R_SER_USR0_ADDR             0x00000120
+#define R_SER_USR1_ADDR             0x00000128
+#define R_SER_USR2_ADDR             0x00000130
+#define R_SER_USR3_ADDR             0x00000138
+#define R_SER_CMD                   0x00000140
+#define R_SER_TX_RD_THRSH           0x00000160
+#define R_SER_TX_WR_THRSH           0x00000168
+#define R_SER_RX_RD_THRSH           0x00000170
+#define R_SER_LINE_MODE		    0x00000178
+#define R_SER_DMA_ENABLE            0x00000180
+#define R_SER_INT_MASK              0x00000190
+#define R_SER_STATUS                0x00000188
+#define R_SER_STATUS_DEBUG          0x000001A8
+#define R_SER_RX_TABLE_BASE         0x00000200
+#define SER_RX_TABLE_COUNT          16
+#define R_SER_TX_TABLE_BASE         0x00000300
+#define SER_TX_TABLE_COUNT          16
+
+/* RMON Counters */
+#define R_SER_RMON_TX_BYTE_LO       0x000001C0
+#define R_SER_RMON_TX_BYTE_HI       0x000001C8
+#define R_SER_RMON_RX_BYTE_LO       0x000001D0
+#define R_SER_RMON_RX_BYTE_HI       0x000001D8
+#define R_SER_RMON_TX_UNDERRUN      0x000001E0
+#define R_SER_RMON_RX_OVERFLOW      0x000001E8
+#define R_SER_RMON_RX_ERRORS        0x000001F0
+#define R_SER_RMON_RX_BADADDR       0x000001F8
+
+/*  ********************************************************************* 
+    * Generic Bus Registers
+    ********************************************************************* */
+
+#define IO_EXT_CFG_COUNT            8
+
+#define A_IO_EXT_BASE		    0x0010061000
+#define A_IO_EXT_REG(r)		    (A_IO_EXT_BASE + (r))
+
+#define A_IO_EXT_CFG_BASE           0x0010061000
+#define A_IO_EXT_MULT_SIZE_BASE     0x0010061100
+#define A_IO_EXT_START_ADDR_BASE    0x0010061200
+#define A_IO_EXT_TIME_CFG0_BASE     0x0010061600
+#define A_IO_EXT_TIME_CFG1_BASE     0x0010061700
+
+#define IO_EXT_REGISTER_SPACING	    8
+#define A_IO_EXT_CS_BASE(cs)	    (A_IO_EXT_CFG_BASE+IO_EXT_REGISTER_SPACING*(cs))
+#define R_IO_EXT_REG(reg,cs)	    ((cs)*IO_EXT_REGISTER_SPACING + (reg))
+
+#define R_IO_EXT_CFG		    0x0000
+#define R_IO_EXT_MULT_SIZE          0x0100
+#define R_IO_EXT_START_ADDR	    0x0200
+#define R_IO_EXT_TIME_CFG0          0x0600
+#define R_IO_EXT_TIME_CFG1          0x0700
+
+
+#define A_IO_INTERRUPT_STATUS       0x0010061A00
+#define A_IO_INTERRUPT_DATA0        0x0010061A10
+#define A_IO_INTERRUPT_DATA1        0x0010061A18
+#define A_IO_INTERRUPT_DATA2        0x0010061A20
+#define A_IO_INTERRUPT_DATA3        0x0010061A28
+#define A_IO_INTERRUPT_ADDR0        0x0010061A30
+#define A_IO_INTERRUPT_ADDR1        0x0010061A40
+#define A_IO_INTERRUPT_PARITY       0x0010061A50
+#define A_IO_PCMCIA_CFG             0x0010061A60
+#define A_IO_PCMCIA_STATUS          0x0010061A70
+#define A_IO_DRIVE_0		    0x0010061300
+#define A_IO_DRIVE_1		    0x0010061308
+#define A_IO_DRIVE_2		    0x0010061310
+#define A_IO_DRIVE_3		    0x0010061318
+
+#define R_IO_INTERRUPT_STATUS       0x0A00
+#define R_IO_INTERRUPT_DATA0        0x0A10
+#define R_IO_INTERRUPT_DATA1        0x0A18
+#define R_IO_INTERRUPT_DATA2        0x0A20
+#define R_IO_INTERRUPT_DATA3        0x0A28
+#define R_IO_INTERRUPT_ADDR0        0x0A30
+#define R_IO_INTERRUPT_ADDR1        0x0A40
+#define R_IO_INTERRUPT_PARITY       0x0A50
+#define R_IO_PCMCIA_CFG             0x0A60
+#define R_IO_PCMCIA_STATUS          0x0A70
+
+/*  ********************************************************************* 
+    * GPIO Registers
+    ********************************************************************* */
+
+#define A_GPIO_CLR_EDGE             0x0010061A80
+#define A_GPIO_INT_TYPE             0x0010061A88
+#define A_GPIO_INPUT_INVERT         0x0010061A90
+#define A_GPIO_GLITCH               0x0010061A98
+#define A_GPIO_READ                 0x0010061AA0
+#define A_GPIO_DIRECTION            0x0010061AA8
+#define A_GPIO_PIN_CLR              0x0010061AB0
+#define A_GPIO_PIN_SET              0x0010061AB8
+
+#define A_GPIO_BASE		    0x0010061A80
+
+#define R_GPIO_CLR_EDGE             0x00
+#define R_GPIO_INT_TYPE             0x08
+#define R_GPIO_INPUT_INVERT         0x10
+#define R_GPIO_GLITCH               0x18
+#define R_GPIO_READ                 0x20
+#define R_GPIO_DIRECTION            0x28
+#define R_GPIO_PIN_CLR              0x30
+#define R_GPIO_PIN_SET              0x38
+
+/*  ********************************************************************* 
+    * SMBus Registers
+    ********************************************************************* */
+
+#define A_SMB_XTRA_0                0x0010060000
+#define A_SMB_XTRA_1                0x0010060008
+#define A_SMB_FREQ_0                0x0010060010
+#define A_SMB_FREQ_1                0x0010060018
+#define A_SMB_STATUS_0              0x0010060020
+#define A_SMB_STATUS_1              0x0010060028
+#define A_SMB_CMD_0                 0x0010060030
+#define A_SMB_CMD_1                 0x0010060038
+#define A_SMB_START_0               0x0010060040
+#define A_SMB_START_1               0x0010060048
+#define A_SMB_DATA_0                0x0010060050
+#define A_SMB_DATA_1                0x0010060058
+#define A_SMB_CONTROL_0             0x0010060060
+#define A_SMB_CONTROL_1             0x0010060068
+#define A_SMB_PEC_0                 0x0010060070
+#define A_SMB_PEC_1                 0x0010060078
+
+#define A_SMB_0                     0x0010060000
+#define A_SMB_1                     0x0010060008
+#define SMB_REGISTER_SPACING        0x8
+#define A_SMB_BASE(idx)             (A_SMB_0+(idx)*SMB_REGISTER_SPACING)
+#define A_SMB_REGISTER(idx,reg)     (A_SMB_BASE(idx)+(reg))
+
+#define R_SMB_XTRA                  0x0000000000
+#define R_SMB_FREQ                  0x0000000010
+#define R_SMB_STATUS                0x0000000020
+#define R_SMB_CMD                   0x0000000030
+#define R_SMB_START                 0x0000000040
+#define R_SMB_DATA                  0x0000000050
+#define R_SMB_CONTROL               0x0000000060
+#define R_SMB_PEC                   0x0000000070
+
+/*  ********************************************************************* 
+    * Timer Registers
+    ********************************************************************* */
+
+/*
+ * Watchdog timers
+ */
+
+#define A_SCD_WDOG_0		    0x0010020050
+#define A_SCD_WDOG_1                0x0010020150
+#define SCD_WDOG_SPACING            0x100
+#define SCD_NUM_WDOGS		    2
+#define A_SCD_WDOG_BASE(w)          (A_SCD_WDOG_0+SCD_WDOG_SPACING*(w))
+#define A_SCD_WDOG_REGISTER(w,r)    (A_SCD_WDOG_BASE(w) + (r))
+
+#define R_SCD_WDOG_INIT		    0x0000000000
+#define R_SCD_WDOG_CNT		    0x0000000008
+#define R_SCD_WDOG_CFG		    0x0000000010
+
+#define A_SCD_WDOG_INIT_0           0x0010020050
+#define A_SCD_WDOG_CNT_0            0x0010020058
+#define A_SCD_WDOG_CFG_0            0x0010020060
+
+#define A_SCD_WDOG_INIT_1           0x0010020150
+#define A_SCD_WDOG_CNT_1            0x0010020158
+#define A_SCD_WDOG_CFG_1            0x0010020160
+
+/*
+ * Generic timers
+ */
+
+#define A_SCD_TIMER_0		    0x0010020070
+#define A_SCD_TIMER_1               0x0010020078
+#define A_SCD_TIMER_2		    0x0010020170
+#define A_SCD_TIMER_3               0x0010020178
+#define SCD_NUM_TIMERS		    4
+#define A_SCD_TIMER_BASE(w)         (A_SCD_TIMER_0+0x08*((w)&1)+0x100*(((w)&2)>>1))
+#define A_SCD_TIMER_REGISTER(w,r)   (A_SCD_TIMER_BASE(w) + (r))
+
+#define R_SCD_TIMER_INIT	    0x0000000000
+#define R_SCD_TIMER_CNT		    0x0000000010
+#define R_SCD_TIMER_CFG		    0x0000000020
+
+#define A_SCD_TIMER_INIT_0          0x0010020070
+#define A_SCD_TIMER_CNT_0           0x0010020080
+#define A_SCD_TIMER_CFG_0           0x0010020090
+
+#define A_SCD_TIMER_INIT_1          0x0010020078
+#define A_SCD_TIMER_CNT_1           0x0010020088
+#define A_SCD_TIMER_CFG_1           0x0010020098
+
+#define A_SCD_TIMER_INIT_2          0x0010020170
+#define A_SCD_TIMER_CNT_2           0x0010020180
+#define A_SCD_TIMER_CFG_2           0x0010020190
+
+#define A_SCD_TIMER_INIT_3          0x0010020178
+#define A_SCD_TIMER_CNT_3           0x0010020188
+#define A_SCD_TIMER_CFG_3           0x0010020198
+
+/*  ********************************************************************* 
+    * System Control Registers
+    ********************************************************************* */
+
+#define A_SCD_SYSTEM_REVISION       0x0010020000
+#define A_SCD_SYSTEM_CFG            0x0010020008
+
+#define A_SCD_SCRATCH		    0x0010020C10	/* PASS2 */
+
+/*  ********************************************************************* 
+    * System Address Trap Registers
+    ********************************************************************* */
+
+#define A_ADDR_TRAP_INDEX           0x00100200B0
+#define A_ADDR_TRAP_REG             0x00100200B8
+#define A_ADDR_TRAP_UP_0            0x0010020400
+#define A_ADDR_TRAP_UP_1            0x0010020408
+#define A_ADDR_TRAP_UP_2            0x0010020410
+#define A_ADDR_TRAP_UP_3            0x0010020418
+#define A_ADDR_TRAP_DOWN_0          0x0010020420
+#define A_ADDR_TRAP_DOWN_1          0x0010020428
+#define A_ADDR_TRAP_DOWN_2          0x0010020430
+#define A_ADDR_TRAP_DOWN_3          0x0010020438
+#define A_ADDR_TRAP_CFG_0           0x0010020440
+#define A_ADDR_TRAP_CFG_1           0x0010020448
+#define A_ADDR_TRAP_CFG_2           0x0010020450
+#define A_ADDR_TRAP_CFG_3           0x0010020458
+
+
+/*  ********************************************************************* 
+    * System Interrupt Mapper Registers
+    ********************************************************************* */
+
+#define A_IMR_CPU0_BASE                 0x0010020000
+#define A_IMR_CPU1_BASE                 0x0010022000
+#define IMR_REGISTER_SPACING            0x2000
+
+#define A_IMR_MAPPER(cpu) (A_IMR_CPU0_BASE+(cpu)*IMR_REGISTER_SPACING)
+#define A_IMR_REGISTER(cpu,reg) (A_IMR_MAPPER(cpu)+(reg))
+
+#define R_IMR_INTERRUPT_DIAG            0x0010
+#define R_IMR_INTERRUPT_MASK            0x0028
+#define R_IMR_INTERRUPT_TRACE           0x0038
+#define R_IMR_INTERRUPT_SOURCE_STATUS   0x0040
+#define R_IMR_LDT_INTERRUPT_SET         0x0048
+#define R_IMR_LDT_INTERRUPT             0x0018
+#define R_IMR_LDT_INTERRUPT_CLR         0x0020
+#define R_IMR_MAILBOX_CPU               0x00c0
+#define R_IMR_ALIAS_MAILBOX_CPU         0x1000
+#define R_IMR_MAILBOX_SET_CPU           0x00C8
+#define R_IMR_ALIAS_MAILBOX_SET_CPU     0x1008
+#define R_IMR_MAILBOX_CLR_CPU           0x00D0
+#define R_IMR_INTERRUPT_STATUS_BASE     0x0100
+#define R_IMR_INTERRUPT_STATUS_COUNT    7
+#define R_IMR_INTERRUPT_MAP_BASE        0x0200
+#define R_IMR_INTERRUPT_MAP_COUNT       64
+
+/*  ********************************************************************* 
+    * System Performance Counter Registers
+    ********************************************************************* */
+
+#define A_SCD_PERF_CNT_CFG          0x00100204C0
+#define A_SCD_PERF_CNT_0            0x00100204D0
+#define A_SCD_PERF_CNT_1            0x00100204D8
+#define A_SCD_PERF_CNT_2            0x00100204E0
+#define A_SCD_PERF_CNT_3            0x00100204E8
+
+/*  ********************************************************************* 
+    * System Bus Watcher Registers
+    ********************************************************************* */
+
+#define A_SCD_BUS_ERR_STATUS        0x0010020880
+#define A_BUS_ERR_DATA_0            0x00100208A0
+#define A_BUS_ERR_DATA_1            0x00100208A8
+#define A_BUS_ERR_DATA_2            0x00100208B0
+#define A_BUS_ERR_DATA_3            0x00100208B8
+#define A_BUS_L2_ERRORS             0x00100208C0
+#define A_BUS_MEM_IO_ERRORS         0x00100208C8
+
+/*  ********************************************************************* 
+    * System Debug Controller Registers
+    ********************************************************************* */
+
+#define A_SCD_JTAG_BASE             0x0010000000
+
+/*  ********************************************************************* 
+    * System Trace Buffer Registers
+    ********************************************************************* */
+
+#define A_SCD_TRACE_CFG             0x0010020A00
+#define A_SCD_TRACE_READ            0x0010020A08
+#define A_SCD_TRACE_EVENT_0         0x0010020A20
+#define A_SCD_TRACE_EVENT_1         0x0010020A28
+#define A_SCD_TRACE_EVENT_2         0x0010020A30
+#define A_SCD_TRACE_EVENT_3         0x0010020A38
+#define A_SCD_TRACE_SEQUENCE_0      0x0010020A40
+#define A_SCD_TRACE_SEQUENCE_1      0x0010020A48
+#define A_SCD_TRACE_SEQUENCE_2      0x0010020A50
+#define A_SCD_TRACE_SEQUENCE_3      0x0010020A58
+#define A_SCD_TRACE_EVENT_4         0x0010020A60
+#define A_SCD_TRACE_EVENT_5         0x0010020A68
+#define A_SCD_TRACE_EVENT_6         0x0010020A70
+#define A_SCD_TRACE_EVENT_7         0x0010020A78
+#define A_SCD_TRACE_SEQUENCE_4      0x0010020A80
+#define A_SCD_TRACE_SEQUENCE_5      0x0010020A88
+#define A_SCD_TRACE_SEQUENCE_6      0x0010020A90
+#define A_SCD_TRACE_SEQUENCE_7      0x0010020A98
+
+/*  ********************************************************************* 
+    * System Generic DMA Registers
+    ********************************************************************* */
+
+#define A_DM_0		  	    0x0010020B00
+#define A_DM_1		  	    0x0010020B20
+#define A_DM_2			    0x0010020B40
+#define A_DM_3			    0x0010020B60
+#define DM_REGISTER_SPACING	    0x20
+#define DM_NUM_CHANNELS		    4
+#define A_DM_BASE(idx) (A_DM_0 + ((idx) * DM_REGISTER_SPACING))
+#define A_DM_REGISTER(idx,reg) (A_DM_BASE(idx) + (reg))
+
+#define R_DM_DSCR_BASE		    0x0000000000
+#define R_DM_DSCR_COUNT		    0x0000000008
+#define R_DM_CUR_DSCR_ADDR	    0x0000000010
+#define R_DM_DSCR_BASE_DEBUG	    0x0000000018
+
+
+/*  *********************************************************************
+    *  Physical Address Map
+    ********************************************************************* */
+
+#define A_PHYS_MEMORY_0                 _SB_MAKE64(0x0000000000)
+#define A_PHYS_MEMORY_SIZE              _SB_MAKE64((256*1024*1024))
+#define A_PHYS_SYSTEM_CTL               _SB_MAKE64(0x0010000000)
+#define A_PHYS_IO_SYSTEM                _SB_MAKE64(0x0010060000)
+#define A_PHYS_GENBUS			_SB_MAKE64(0x0010090000)
+#define A_PHYS_GENBUS_END		_SB_MAKE64(0x0040000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BYTES_32 _SB_MAKE64(0x0040000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BITS_32  _SB_MAKE64(0x0060000000)
+#define A_PHYS_MEMORY_1                 _SB_MAKE64(0x0080000000)
+#define A_PHYS_MEMORY_2                 _SB_MAKE64(0x0090000000)
+#define A_PHYS_MEMORY_3                 _SB_MAKE64(0x00C0000000)
+#define A_PHYS_L2_CACHE_TEST            _SB_MAKE64(0x00D0000000)
+#define A_PHYS_LDT_SPECIAL_MATCH_BYTES  _SB_MAKE64(0x00D8000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BYTES    _SB_MAKE64(0x00DC000000)
+#define A_PHYS_LDTPCI_CFG_MATCH_BYTES   _SB_MAKE64(0x00DE000000)
+#define A_PHYS_LDT_SPECIAL_MATCH_BITS   _SB_MAKE64(0x00F8000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BITS     _SB_MAKE64(0x00FC000000)
+#define A_PHYS_LDTPCI_CFG_MATCH_BITS    _SB_MAKE64(0x00FE000000)
+#define A_PHYS_MEMORY_EXP               _SB_MAKE64(0x0100000000)
+#define A_PHYS_MEMORY_EXP_SIZE          _SB_MAKE64((508*1024*1024*1024))
+#define A_PHYS_LDT_EXP                  _SB_MAKE64(0x8000000000)
+#define A_PHYS_PCI_FULLACCESS_BYTES     _SB_MAKE64(0xF000000000)
+#define A_PHYS_PCI_FULLACCESS_BITS      _SB_MAKE64(0xF100000000)
+#define A_PHYS_RESERVED                 _SB_MAKE64(0xF200000000)
+#define A_PHYS_RESERVED_SPECIAL_LDT     _SB_MAKE64(0xFD00000000)
+
+#define A_PHYS_L2CACHE_WAY_SIZE         _SB_MAKE64(0x0000020000)
+#define PHYS_L2CACHE_NUM_WAYS           4
+#define A_PHYS_L2CACHE_TOTAL_SIZE       _SB_MAKE64(0x0000080000)
+#define A_PHYS_L2CACHE_WAY0             _SB_MAKE64(0x00D0180000)
+#define A_PHYS_L2CACHE_WAY1             _SB_MAKE64(0x00D01A0000)
+#define A_PHYS_L2CACHE_WAY2             _SB_MAKE64(0x00D01C0000)
+#define A_PHYS_L2CACHE_WAY3             _SB_MAKE64(0x00D01E0000)
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_scd.h linux/include/asm-mips64/sibyte/sb1250_scd.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_scd.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_scd.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,459 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  SCD Constants and Macros			File: sb1250_scd.h
+    *  
+    *  This module contains constants and macros useful for
+    *  manipulating the System Control and Debug module on the 1250.
+    *  
+    *  SB1250 specification level:  0.2  plus errata as of 11/7/2000
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+#ifndef _SB1250_SCD_H
+#define _SB1250_SCD_H
+
+#include "sb1250_defs.h"
+
+/*  *********************************************************************
+    *  System control/debug registers
+    ********************************************************************* */
+
+/*
+ * System Revision Register (Table 4-1)
+ */
+
+#define M_SYS_RESERVED		    _SB_MAKEMASK(8,0)
+
+#define S_SYS_REVISION              _SB_MAKE64(8)
+#define M_SYS_REVISION              _SB_MAKEMASK(8,S_SYS_REVISION)
+#define V_SYS_REVISION(x)           _SB_MAKEVALUE(x,S_SYS_REVISION)
+#define G_SYS_REVISION(x)           _SB_GETVALUE(x,S_SYS_REVISION,M_SYS_REVISION)
+
+#define K_SYS_REVISION_PASS1	    1
+#define K_SYS_REVISION_PASS2	    3
+#define K_SYS_REVISION_PASS3	    4 /* XXX Unknown */
+
+#define S_SYS_PART                  _SB_MAKE64(16)
+#define M_SYS_PART                  _SB_MAKEMASK(16,S_SYS_PART)
+#define V_SYS_PART(x)               _SB_MAKEVALUE(x,S_SYS_PART)
+#define G_SYS_PART(x)               _SB_GETVALUE(x,S_SYS_PART,M_SYS_PART)
+
+#define K_SYS_PART_SB1250           0x1250
+#define K_SYS_PART_SB1125           0x1125 
+
+#define S_SYS_WID                   _SB_MAKE64(32)
+#define M_SYS_WID                   _SB_MAKEMASK(32,S_SYS_WID)
+#define V_SYS_WID(x)                _SB_MAKEVALUE(x,S_SYS_WID)
+#define G_SYS_WID(x)                _SB_GETVALUE(x,S_SYS_WID,M_SYS_WID)
+
+/*
+ * System Config Register (Table 4-2)
+ * Register: SCD_SYSTEM_CFG
+ */
+
+#define M_SYS_LDT_PLL_BYP           _SB_MAKEMASK1(3)
+#define M_SYS_PCI_SYNC_TEST_MODE    _SB_MAKEMASK1(4)
+#define M_SYS_IOB0_DIV              _SB_MAKEMASK1(5)
+#define M_SYS_IOB1_DIV              _SB_MAKEMASK1(6)
+
+#define S_SYS_PLL_DIV               _SB_MAKE64(7)
+#define M_SYS_PLL_DIV               _SB_MAKEMASK(5,S_SYS_PLL_DIV)
+#define V_SYS_PLL_DIV(x)            _SB_MAKEVALUE(x,S_SYS_PLL_DIV)
+#define G_SYS_PLL_DIV(x)            _SB_GETVALUE(x,S_SYS_PLL_DIV,M_SYS_PLL_DIV)
+
+#define M_SYS_SER0_ENABLE           _SB_MAKEMASK1(12)
+#define M_SYS_SER0_RSTB_EN          _SB_MAKEMASK1(13)
+#define M_SYS_SER1_ENABLE           _SB_MAKEMASK1(14)
+#define M_SYS_SER1_RSTB_EN          _SB_MAKEMASK1(15)
+#define M_SYS_PCMCIA_ENABLE         _SB_MAKEMASK1(16)
+
+#define S_SYS_BOOT_MODE             _SB_MAKE64(17)
+#define M_SYS_BOOT_MODE             _SB_MAKEMASK(2,S_SYS_BOOT_MODE)
+#define V_SYS_BOOT_MODE(x)          _SB_MAKEVALUE(x,S_SYS_BOOT_MODE)
+#define G_SYS_BOOT_MODE(x)          _SB_GETVALUE(x,S_SYS_BOOT_MODE,M_SYS_BOOT_MODE)
+#define K_SYS_BOOT_MODE_ROM32       0
+#define K_SYS_BOOT_MODE_ROM8        1
+#define K_SYS_BOOT_MODE_SMBUS_SMALL 2
+#define K_SYS_BOOT_MODE_SMBUS_BIG   3
+
+#define M_SYS_PCI_HOST              _SB_MAKEMASK1(19)
+#define M_SYS_PCI_ARBITER           _SB_MAKEMASK1(20)
+#define M_SYS_SOUTH_ON_LDT          _SB_MAKEMASK1(21)
+#define M_SYS_BIG_ENDIAN            _SB_MAKEMASK1(22)
+#define M_SYS_GENCLK_EN             _SB_MAKEMASK1(23)
+#define M_SYS_LDT_TEST_EN           _SB_MAKEMASK1(24)
+#define M_SYS_GEN_PARITY_EN         _SB_MAKEMASK1(25)
+
+#define S_SYS_CONFIG                26
+#define M_SYS_CONFIG                _SB_MAKEMASK(6,S_SYS_CONFIG)
+#define V_SYS_CONFIG(x)             _SB_MAKEVALUE(x,S_SYS_CONFIG)
+#define G_SYS_CONFIG(x)             _SB_GETVALUE(x,S_SYS_CONFIG,M_SYS_CONFIG)
+
+/* The following bits are writeable by JTAG only. */
+
+#define M_SYS_CLKSTOP               _SB_MAKEMASK1(32)
+#define M_SYS_CLKSTEP               _SB_MAKEMASK1(33)
+
+#define S_SYS_CLKCOUNT              34
+#define M_SYS_CLKCOUNT              _SB_MAKEMASK(8,S_SYS_CLKCOUNT)
+#define V_SYS_CLKCOUNT(x)           _SB_MAKEVALUE(x,S_SYS_CLKCOUNT)
+#define G_SYS_CLKCOUNT(x)           _SB_GETVALUE(x,S_SYS_CLKCOUNT,M_SYS_CLKCOUNT)
+
+#define M_SYS_PLL_BYPASS            _SB_MAKEMASK1(42)
+
+#define S_SYS_PLL_IREF		    43
+#define M_SYS_PLL_IREF		    _SB_MAKEMASK(2,S_SYS_PLL_IREF)
+
+#define S_SYS_PLL_VCO		    45
+#define M_SYS_PLL_VCO		    _SB_MAKEMASK(2,S_SYS_PLL_VCO)
+
+#define S_SYS_PLL_VREG		    47
+#define M_SYS_PLL_VREG		    _SB_MAKEMASK(2,S_SYS_PLL_VREG)
+
+#define M_SYS_MEM_RESET             _SB_MAKEMASK1(49)
+#define M_SYS_L2C_RESET             _SB_MAKEMASK1(50)
+#define M_SYS_IO_RESET_0            _SB_MAKEMASK1(51)
+#define M_SYS_IO_RESET_1            _SB_MAKEMASK1(52)
+#define M_SYS_SCD_RESET             _SB_MAKEMASK1(53)
+
+/* End of bits writable by JTAG only. */
+
+#define M_SYS_CPU_RESET_0           _SB_MAKEMASK1(54)
+#define M_SYS_CPU_RESET_1           _SB_MAKEMASK1(55)
+
+#define M_SYS_UNICPU0               _SB_MAKEMASK1(56)
+#define M_SYS_UNICPU1               _SB_MAKEMASK1(57)
+
+#define M_SYS_SB_SOFTRES            _SB_MAKEMASK1(58)
+#define M_SYS_EXT_RESET             _SB_MAKEMASK1(59)
+#define M_SYS_SYSTEM_RESET          _SB_MAKEMASK1(60)
+
+#define M_SYS_MISR_MODE             _SB_MAKEMASK1(61)
+#define M_SYS_MISR_RESET            _SB_MAKEMASK1(62)
+
+/*
+ * Mailbox Registers (Table 4-3)
+ * Registers: SCD_MBOX_CPU_x
+ */
+
+#define S_MBOX_INT_3                0
+#define M_MBOX_INT_3                _SB_MAKEMASK(16,S_MBOX_INT_3)
+#define S_MBOX_INT_2                16
+#define M_MBOX_INT_2                _SB_MAKEMASK(16,S_MBOX_INT_2)
+#define S_MBOX_INT_1                32
+#define M_MBOX_INT_1                _SB_MAKEMASK(16,S_MBOX_INT_1)
+#define S_MBOX_INT_0                48
+#define M_MBOX_INT_0                _SB_MAKEMASK(16,S_MBOX_INT_0)
+
+/*
+ * Watchdog Registers (Table 4-8) (Table 4-9) (Table 4-10)
+ * Registers: SCD_WDOG_INIT_CNT_x
+ */
+
+#define V_SCD_WDOG_FREQ             1000000
+
+#define S_SCD_WDOG_INIT             0
+#define M_SCD_WDOG_INIT             _SB_MAKEMASK(13,S_SCD_WDOG_INIT)
+
+#define S_SCD_WDOG_CNT              0
+#define M_SCD_WDOG_CNT              _SB_MAKEMASK(13,S_SCD_WDOG_CNT)
+
+#define M_SCD_WDOG_ENABLE           _SB_MAKEMASK1(0)
+
+/*
+ * Timer Registers (Table 4-11) (Table 4-12) (Table 4-13)
+ */
+
+#define V_SCD_TIMER_FREQ            1000000
+
+#define S_SCD_TIMER_INIT            0
+#define M_SCD_TIMER_INIT            _SB_MAKEMASK(20,S_SCD_TIMER_INIT)
+#define V_SCD_TIMER_INIT(x)         _SB_MAKEVALUE(x,S_SCD_TIMER_INIT)
+#define G_SCD_TIMER_INIT(x)         _SB_GETVALUE(x,S_SCD_TIMER_INIT,M_SCD_TIMER_INIT)
+
+#define S_SCD_TIMER_CNT             0
+#define M_SCD_TIMER_CNT             _SB_MAKEMASK(20,S_SCD_TIMER_CNT)
+#define V_SCD_TIMER_CNT(x)         _SB_MAKEVALUE(x,S_SCD_TIMER_CNT)
+#define G_SCD_TIMER_CNT(x)         _SB_GETVALUE(x,S_SCD_TIMER_CNT,M_SCD_TIMER_CNT)
+
+#define M_SCD_TIMER_ENABLE          _SB_MAKEMASK1(0)
+#define M_SCD_TIMER_MODE            _SB_MAKEMASK1(1)
+#define M_SCD_TIMER_MODE_CONTINUOUS M_SCD_TIMER_MODE
+
+/*
+ * System Performance Counters
+ */
+
+#define S_SPC_CFG_SRC0            0
+#define M_SPC_CFG_SRC0            _SB_MAKEMASK(8,S_SPC_CFG_SRC0)
+#define V_SPC_CFG_SRC0(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC0)
+#define G_SPC_CFG_SRC0(x)         _SB_GETVALUE(x,S_SPC_CFG_SRC0,M_SPC_CFG_SRC0)
+
+#define S_SPC_CFG_SRC1            8
+#define M_SPC_CFG_SRC1            _SB_MAKEMASK(8,S_SPC_CFG_SRC1)
+#define V_SPC_CFG_SRC1(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC1)
+#define G_SPC_CFG_SRC1(x)         _SB_GETVALUE(x,S_SPC_CFG_SRC1,M_SPC_CFG_SRC1)
+
+#define S_SPC_CFG_SRC2            16
+#define M_SPC_CFG_SRC2            _SB_MAKEMASK(8,S_SPC_CFG_SRC2)
+#define V_SPC_CFG_SRC2(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC2)
+#define G_SPC_CFG_SRC2(x)         _SB_GETVALUE(x,S_SPC_CFG_SRC2,M_SPC_CFG_SRC2)
+
+#define S_SPC_CFG_SRC3            24
+#define M_SPC_CFG_SRC3            _SB_MAKEMASK(8,S_SPC_CFG_SRC3)
+#define V_SPC_CFG_SRC3(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC3)
+#define G_SPC_CFG_SRC3(x)         _SB_GETVALUE(x,S_SPC_CFG_SRC3,M_SPC_CFG_SRC3)
+
+#define M_SPC_CFG_CLEAR		_SB_MAKEMASK1(32)
+#define M_SPC_CFG_ENABLE	_SB_MAKEMASK1(33)
+
+
+/*
+ * Bus Watcher
+ */
+
+#define S_SCD_BERR_TID            8
+#define M_SCD_BERR_TID            _SB_MAKEMASK(10,S_SCD_BERR_TID)
+#define V_SCD_BERR_TID(x)         _SB_MAKEVALUE(x,S_SCD_BERR_TID)
+#define G_SCD_BERR_TID(x)         _SB_GETVALUE(x,S_SCD_BERR_TID,M_SCD_BERR_TID)
+
+#define S_SCD_BERR_RID            18
+#define M_SCD_BERR_RID            _SB_MAKEMASK(4,S_SCD_BERR_RID)
+#define V_SCD_BERR_RID(x)         _SB_MAKEVALUE(x,S_SCD_BERR_RID)
+#define G_SCD_BERR_RID(x)         _SB_GETVALUE(x,S_SCD_BERR_RID,M_SCD_BERR_RID)
+
+#define S_SCD_BERR_DCODE            22
+#define M_SCD_BERR_DCODE            _SB_MAKEMASK(3,S_SCD_BERR_DCODE)
+#define V_SCD_BERR_DCODE(x)         _SB_MAKEVALUE(x,S_SCD_BERR_DCODE)
+#define G_SCD_BERR_DCODE(x)         _SB_GETVALUE(x,S_SCD_BERR_DCODE,M_SCD_BERR_DCODE)
+
+#define M_SCD_BERR_MULTERRS	_SB_MAKEMASK1(30)
+
+
+#define S_SCD_L2ECC_CORR_D            0
+#define M_SCD_L2ECC_CORR_D            _SB_MAKEMASK(8,S_SCD_L2ECC_CORR_D)
+#define V_SCD_L2ECC_CORR_D(x)         _SB_MAKEVALUE(x,S_SCD_L2ECC_CORR_D)
+#define G_SCD_L2ECC_CORR_D(x)         _SB_GETVALUE(x,S_SCD_L2ECC_CORR_D,M_SCD_L2ECC_CORR_D)
+
+#define S_SCD_L2ECC_BAD_D            8
+#define M_SCD_L2ECC_BAD_D            _SB_MAKEMASK(8,S_SCD_L2ECC_BAD_D)
+#define V_SCD_L2ECC_BAD_D(x)         _SB_MAKEVALUE(x,S_SCD_L2ECC_BAD_D)
+#define G_SCD_L2ECC_BAD_D(x)         _SB_GETVALUE(x,S_SCD_L2ECC_BAD_D,M_SCD_L2ECC_BAD_D)
+
+#define S_SCD_L2ECC_CORR_T            16
+#define M_SCD_L2ECC_CORR_T            _SB_MAKEMASK(8,S_SCD_L2ECC_CORR_T)
+#define V_SCD_L2ECC_CORR_T(x)         _SB_MAKEVALUE(x,S_SCD_L2ECC_CORR_T)
+#define G_SCD_L2ECC_CORR_T(x)         _SB_GETVALUE(x,S_SCD_L2ECC_CORR_T,M_SCD_L2ECC_CORR_T)
+
+#define S_SCD_L2ECC_BAD_T            24
+#define M_SCD_L2ECC_BAD_T            _SB_MAKEMASK(8,S_SCD_L2ECC_BAD_T)
+#define V_SCD_L2ECC_BAD_T(x)         _SB_MAKEVALUE(x,S_SCD_L2ECC_BAD_T)
+#define G_SCD_L2ECC_BAD_T(x)         _SB_GETVALUE(x,S_SCD_L2ECC_BAD_T,M_SCD_L2ECC_BAD_T)
+
+#define S_SCD_MEM_ECC_CORR            0
+#define M_SCD_MEM_ECC_CORR            _SB_MAKEMASK(8,S_SCD_MEM_ECC_CORR)
+#define V_SCD_MEM_ECC_CORR(x)         _SB_MAKEVALUE(x,S_SCD_MEM_ECC_CORR)
+#define G_SCD_MEM_ECC_CORR(x)         _SB_GETVALUE(x,S_SCD_MEM_ECC_CORR,M_SCD_MEM_ECC_CORR)
+
+#define S_SCD_MEM_ECC_BAD            16
+#define M_SCD_MEM_ECC_BAD            _SB_MAKEMASK(8,S_SCD_MEM_ECC_BAD)
+#define V_SCD_MEM_ECC_BAD(x)         _SB_MAKEVALUE(x,S_SCD_MEM_ECC_BAD)
+#define G_SCD_MEM_ECC_BAD(x)         _SB_GETVALUE(x,S_SCD_MEM_ECC_BAD,M_SCD_MEM_ECC_BAD)
+
+#define S_SCD_MEM_BUSERR            24
+#define M_SCD_MEM_BUSERR            _SB_MAKEMASK(8,S_SCD_MEM_BUSERR)
+#define V_SCD_MEM_BUSERR(x)         _SB_MAKEVALUE(x,S_SCD_MEM_BUSERR)
+#define G_SCD_MEM_BUSERR(x)         _SB_GETVALUE(x,S_SCD_MEM_BUSERR,M_SCD_MEM_BUSERR)
+
+
+/*
+ * Address Trap Registers
+ */
+
+#define M_ATRAP_INDEX		  _SB_MAKEMASK(4,0)
+#define M_ATRAP_ADDRESS		  _SB_MAKEMASK(40,0)
+
+#define S_ATRAP_CFG_CNT            0
+#define M_ATRAP_CFG_CNT            _SB_MAKEMASK(3,S_ATRAP_CFG_CNT)
+#define V_ATRAP_CFG_CNT(x)         _SB_MAKEVALUE(x,S_ATRAP_CFG_CNT)
+#define G_ATRAP_CFG_CNT(x)         _SB_GETVALUE(x,S_ATRAP_CFG_CNT,M_ATRAP_CFG_CNT)
+
+#define M_ATRAP_CFG_WRITE	   _SB_MAKEMASK1(3)
+#define M_ATRAP_CFG_ALL	  	   _SB_MAKEMASK1(4)
+#define M_ATRAP_CFG_INV	   	   _SB_MAKEMASK1(5)
+#define M_ATRAP_CFG_USESRC	   _SB_MAKEMASK1(6)
+#define M_ATRAP_CFG_SRCINV	   _SB_MAKEMASK1(7)
+
+#define S_ATRAP_CFG_AGENTID     8
+#define M_ATRAP_CFG_AGENTID     _SB_MAKEMASK(4,S_ATRAP_CFG_AGENTID)
+#define V_ATRAP_CFG_AGENTID(x)  _SB_MAKEVALUE(x,S_ATRAP_CFG_AGENTID)
+#define G_ATRAP_CFG_AGENTID(x)  _SB_GETVALUE(x,S_ATRAP_CFG_AGENTID,M_ATRAP_CFG_AGENTID)
+
+#define K_BUS_AGENT_CPU0	0
+#define K_BUS_AGENT_CPU1	1
+#define K_BUS_AGENT_IOB0	2
+#define K_BUS_AGENT_IOB1	3
+#define K_BUS_AGENT_SCD	4
+#define K_BUS_AGENT_RESERVED	5
+#define K_BUS_AGENT_L2C	6
+#define K_BUS_AGENT_MC	7
+
+#define S_ATRAP_CFG_CATTR     12
+#define M_ATRAP_CFG_CATTR     _SB_MAKEMASK(3,S_ATRAP_CFG_CATTR)
+#define V_ATRAP_CFG_CATTR(x)  _SB_MAKEVALUE(x,S_ATRAP_CFG_CATTR)
+#define G_ATRAP_CFG_CATTR(x)  _SB_GETVALUE(x,S_ATRAP_CFG_CATTR,M_ATRAP_CFG_CATTR)
+
+#define K_ATRAP_CFG_CATTR_IGNORE	0
+#define K_ATRAP_CFG_CATTR_UNC    	1
+#define K_ATRAP_CFG_CATTR_CACHEABLE	2
+#define K_ATRAP_CFG_CATTR_NONCOH  	3
+#define K_ATRAP_CFG_CATTR_COHERENT	4
+#define K_ATRAP_CFG_CATTR_NOTUNC	5
+#define K_ATRAP_CFG_CATTR_NOTNONCOH	6
+#define K_ATRAP_CFG_CATTR_NOTCOHERENT   7
+
+/*
+ * Trace Buffer Config register
+ */
+
+#define M_SCD_TRACE_CFG_RESET           _SB_MAKEMASK1(0)
+#define M_SCD_TRACE_CFG_START_READ      _SB_MAKEMASK1(1)
+#define M_SCD_TRACE_CFG_START           _SB_MAKEMASK1(2)
+#define M_SCD_TRACE_CFG_STOP            _SB_MAKEMASK1(3)
+#define M_SCD_TRACE_CFG_FREEZE          _SB_MAKEMASK1(4)
+#define M_SCD_TRACE_CFG_FREEZE_FULL     _SB_MAKEMASK1(5)
+#define M_SCD_TRACE_CFG_DEBUG_FULL      _SB_MAKEMASK1(6)
+#define M_SCD_TRACE_CFG_FULL            _SB_MAKEMASK1(7)
+
+#define S_SCD_TRACE_CFG_CUR_ADDR        10
+#define M_SCD_TRACE_CFG_CUR_ADDR        _SB_MAKEMASK(8,S_SCD_TRACE_CFG_CUR_ADDR)
+#define V_SCD_TRACE_CFG_CUR_ADDR(x)     _SB_MAKEVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR)
+#define G_SCD_TRACE_CFG_CUR_ADDR(x)     _SB_GETVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR,M_SCD_TRACE_CFG_CUR_ADDR)
+
+/*
+ * Trace Event registers
+ */
+
+#define S_SCD_TREVT_ADDR_MATCH          0
+#define M_SCD_TREVT_ADDR_MATCH          _SB_MAKEMASK(4,S_SCD_TREVT_ADDR_MATCH)
+#define V_SCD_TREVT_ADDR_MATCH(x)       _SB_MAKEVALUE(x,S_SCD_TREVT_ADDR_MATCH)
+#define G_SCD_TREVT_ADDR_MATCH(x)       _SB_GETVALUE(x,S_SCD_TREVT_ADDR_MATCH,M_SCD_TREVT_ADDR_MATCH)
+
+#define M_SCD_TREVT_REQID_MATCH         _SB_MAKEMASK1(4)
+#define M_SCD_TREVT_DATAID_MATCH        _SB_MAKEMASK1(5)
+#define M_SCD_TREVT_RESPID_MATCH        _SB_MAKEMASK1(6)
+#define M_SCD_TREVT_INTERRUPT           _SB_MAKEMASK1(7)
+#define M_SCD_TREVT_DEBUG_PIN           _SB_MAKEMASK1(9)
+#define M_SCD_TREVT_WRITE               _SB_MAKEMASK1(10)
+#define M_SCD_TREVT_READ                _SB_MAKEMASK1(11)
+
+#define S_SCD_TREVT_REQID               12
+#define M_SCD_TREVT_REQID               _SB_MAKEMASK(4,S_SCD_TREVT_REQID)
+#define V_SCD_TREVT_REQID(x)            _SB_MAKEVALUE(x,S_SCD_TREVT_REQID)
+#define G_SCD_TREVT_REQID(x)            _SB_GETVALUE(x,S_SCD_TREVT_REQID,M_SCD_TREVT_REQID)
+
+#define S_SCD_TREVT_RESPID              16
+#define M_SCD_TREVT_RESPID              _SB_MAKEMASK(4,S_SCD_TREVT_RESPID)
+#define V_SCD_TREVT_RESPID(x)           _SB_MAKEVALUE(x,S_SCD_TREVT_RESPID)
+#define G_SCD_TREVT_RESPID(x)           _SB_GETVALUE(x,S_SCD_TREVT_RESPID,M_SCD_TREVT_RESPID)
+
+#define S_SCD_TREVT_DATAID              20
+#define M_SCD_TREVT_DATAID              _SB_MAKEMASK(4,S_SCD_TREVT_DATAID)
+#define V_SCD_TREVT_DATAID(x)           _SB_MAKEVALUE(x,S_SCD_TREVT_DATAID)
+#define G_SCD_TREVT_DATAID(x)           _SB_GETVALUE(x,S_SCD_TREVT_DATAID,M_SCD_TREVT_DATID)
+
+#define S_SCD_TREVT_COUNT               24
+#define M_SCD_TREVT_COUNT               _SB_MAKEMASK(8,S_SCD_TREVT_COUNT)
+#define V_SCD_TREVT_COUNT(x)            _SB_MAKEVALUE(x,S_SCD_TREVT_COUNT)
+#define G_SCD_TREVT_COUNT(x)            _SB_GETVALUE(x,S_SCD_TREVT_COUNT,M_SCD_TREVT_COUNT)
+
+/*
+ * Trace Sequence registers
+ */
+
+#define S_SCD_TRSEQ_EVENT4              0
+#define M_SCD_TRSEQ_EVENT4              _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT4)
+#define V_SCD_TRSEQ_EVENT4(x)           _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT4)
+#define G_SCD_TRSEQ_EVENT4(x)           _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT4,M_SCD_TRSEQ_EVENT4)
+
+#define S_SCD_TRSEQ_EVENT3              4
+#define M_SCD_TRSEQ_EVENT3              _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT3)
+#define V_SCD_TRSEQ_EVENT3(x)           _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT3)
+#define G_SCD_TRSEQ_EVENT3(x)           _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT3,M_SCD_TRSEQ_EVENT3)
+
+#define S_SCD_TRSEQ_EVENT2              8
+#define M_SCD_TRSEQ_EVENT2              _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT2)
+#define V_SCD_TRSEQ_EVENT2(x)           _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT2)
+#define G_SCD_TRSEQ_EVENT2(x)           _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT2,M_SCD_TRSEQ_EVENT2)
+
+#define S_SCD_TRSEQ_EVENT1              12
+#define M_SCD_TRSEQ_EVENT1              _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT1)
+#define V_SCD_TRSEQ_EVENT1(x)           _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT1)
+#define G_SCD_TRSEQ_EVENT1(x)           _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT1,M_SCD_TRSEQ_EVENT1)
+
+#define K_SCD_TRSEQ_E0                  0
+#define K_SCD_TRSEQ_E1                  1
+#define K_SCD_TRSEQ_E2                  2
+#define K_SCD_TRSEQ_E3                  3
+#define K_SCD_TRSEQ_E0_E1               4
+#define K_SCD_TRSEQ_E1_E2               5
+#define K_SCD_TRSEQ_E2_E3               6
+#define K_SCD_TRSEQ_E0_E1_E2            7
+#define K_SCD_TRSEQ_E0_E1_E2_E3         8
+#define K_SCD_TRSEQ_E0E1                9
+#define K_SCD_TRSEQ_E0E1E2              10
+#define K_SCD_TRSEQ_E0E1E2E3            11
+#define K_SCD_TRSEQ_E0E1_E2             12
+#define K_SCD_TRSEQ_E0E1_E2E3           13
+#define K_SCD_TRSEQ_E0E1_E2_E3          14
+#define K_SCD_TRSEQ_IGNORED             15
+
+#define K_SCD_TRSEQ_TRIGGER_ALL         (V_SCD_TRSEQ_EVENT1(K_SCD_TRSEQ_IGNORED) | \
+                                         V_SCD_TRSEQ_EVENT2(K_SCD_TRSEQ_IGNORED) | \
+                                         V_SCD_TRSEQ_EVENT3(K_SCD_TRSEQ_IGNORED) | \
+                                         V_SCD_TRSEQ_EVENT4(K_SCD_TRSEQ_IGNORED))
+
+#define S_SCD_TRSEQ_FUNCTION            16
+#define M_SCD_TRSEQ_FUNCTION            _SB_MAKEMASK(4,S_SCD_TRSEQ_FUNCTION)
+#define V_SCD_TRSEQ_FUNCTION(x)         _SB_MAKEVALUE(x,S_SCD_TRSEQ_FUNCTION)
+#define G_SCD_TRSEQ_FUNCTION(x)         _SB_GETVALUE(x,S_SCD_TRSEQ_FUNCTION,M_SCD_TRSEQ_FUNCTION)
+
+#define K_SCD_TRSEQ_FUNC_NOP            0
+#define K_SCD_TRSEQ_FUNC_START          1
+#define K_SCD_TRSEQ_FUNC_STOP           2
+#define K_SCD_TRSEQ_FUNC_FREEZE         3
+
+#define V_SCD_TRSEQ_FUNC_NOP            V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_NOP)
+#define V_SCD_TRSEQ_FUNC_START          V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_START)
+#define V_SCD_TRSEQ_FUNC_STOP           V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_STOP)
+#define V_SCD_TRSEQ_FUNC_FREEZE         V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_FREEZE)
+
+#define M_SCD_TRSEQ_ASAMPLE             _SB_MAKEMASK1(18)
+#define M_SCD_TRSEQ_DSAMPLE             _SB_MAKEMASK1(19)
+#define M_SCD_TRSEQ_DEBUGPIN            _SB_MAKEMASK1(20)
+#define M_SCD_TRSEQ_DEBUGCPU            _SB_MAKEMASK1(21)
+#define M_SCD_TRSEQ_CLEARUSE            _SB_MAKEMASK1(22)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_smbus.h linux/include/asm-mips64/sibyte/sb1250_smbus.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_smbus.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_smbus.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,134 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  SMBUS Constants                          File: sb1250_smbus.h
+    *  
+    *  This module contains constants and macros useful for 
+    *  manipulating the SB1250's SMbus devices.
+    *  
+    *  SB1250 specification level:  0.2
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_SMBUS_H
+#define _SB1250_SMBUS_H
+
+#include "sb1250_defs.h"
+
+/*
+ * SMBus Clock Frequency Register (Table 14-2)
+ */
+
+#define S_SMB_FREQ_DIV              0
+#define M_SMB_FREQ_DIV              _SB_MAKEMASK(13,S_SMB_FREQ_DIV)
+#define V_SMB_FREQ_DIV(x)           _SB_MAKEVALUE(x,S_SMB_FREQ_DIV)
+
+#define K_SMB_FREQ_400KHZ	    0x1F
+#define K_SMB_FREQ_100KHZ	    0x7D
+
+#define S_SMB_CMD                   0
+#define M_SMB_CMD                   _SB_MAKEMASK(8,S_SMB_CMD)
+#define V_SMB_CMD(x)                _SB_MAKEVALUE(x,S_SMB_CMD)
+
+/*
+ * SMBus control register (Table 14-4)
+ */
+
+#define M_SMB_ERR_INTR              _SB_MAKEMASK1(0)
+#define M_SMB_FINISH_INTR           _SB_MAKEMASK1(1)
+#define M_SMB_DATA_OUT              _SB_MAKEMASK1(4)
+#define M_SMB_DATA_DIR              _SB_MAKEMASK1(5)
+#define M_SMB_DATA_DIR_OUTPUT       M_SMB_DATA_DIR
+#define M_SMB_CLK_OUT               _SB_MAKEMASK1(6)
+#define M_SMB_DIRECT_ENABLE         _SB_MAKEMASK1(7)
+
+/*
+ * SMBus status registers (Table 14-5)
+ */
+
+#define M_SMB_BUSY                  _SB_MAKEMASK1(0)
+#define M_SMB_ERROR                 _SB_MAKEMASK1(1)
+#define M_SMB_ERROR_TYPE            _SB_MAKEMASK1(2)
+#define M_SMB_REF                   _SB_MAKEMASK1(6)
+#define M_SMB_DATA_IN               _SB_MAKEMASK1(7)
+
+/*
+ * SMBus Start/Command registers (Table 14-9)
+ */
+
+#define S_SMB_ADDR                  0
+#define M_SMB_ADDR                  _SB_MAKEMASK(7,S_SMB_ADDR)
+#define V_SMB_ADDR(x)               _SB_MAKEVALUE(x,S_SMB_ADDR)
+#define G_SMB_ADDR(x)               _SB_GETVALUE(x,S_SMB_ADDR,M_SMB_ADDR)
+
+#define M_SMB_QDATA                 _SB_MAKEMASK1(7)
+
+#define S_SMB_TT                    8
+#define M_SMB_TT                    _SB_MAKEMASK(3,S_SMB_TT)
+#define V_SMB_TT(x)                 _SB_MAKEVALUE(x,S_SMB_TT)
+#define G_SMB_TT(x)                 _SB_GETVALUE(x,S_SMB_TT,M_SMB_TT)
+
+#define K_SMB_TT_WR1BYTE            0
+#define K_SMB_TT_WR2BYTE            1
+#define K_SMB_TT_WR3BYTE            2
+#define K_SMB_TT_CMD_RD1BYTE        3
+#define K_SMB_TT_CMD_RD2BYTE        4
+#define K_SMB_TT_RD1BYTE            5
+#define K_SMB_TT_QUICKCMD           6
+#define K_SMB_TT_EEPROMREAD         7
+
+#define V_SMB_TT_WR1BYTE	    V_SMB_TT(K_SMB_TT_WR1BYTE)
+#define V_SMB_TT_WR2BYTE	    V_SMB_TT(K_SMB_TT_WR2BYTE)
+#define V_SMB_TT_WR3BYTE	    V_SMB_TT(K_SMB_TT_WR3BYTE)
+#define V_SMB_TT_CMD_RD1BYTE	    V_SMB_TT(K_SMB_TT_CMD_RD1BYTE)
+#define V_SMB_TT_CMD_RD2BYTE	    V_SMB_TT(K_SMB_TT_CMD_RD2BYTE)
+#define V_SMB_TT_RD1BYTE	    V_SMB_TT(K_SMB_TT_RD1BYTE)
+#define V_SMB_TT_QUICKCMD	    V_SMB_TT(K_SMB_TT_QUICKCMD)
+#define V_SMB_TT_EEPROMREAD	    V_SMB_TT(K_SMB_TT_EEPROMREAD)
+
+#define M_SMB_PEC                   _SB_MAKEMASK1(15)
+
+/*
+ * SMBus Data Register (Table 14-6) and SMBus Extra Register (Table 14-7)
+ */
+
+#define S_SMB_LB                    0
+#define M_SMB_LB                    _SB_MAKEMASK(8,S_SMB_LB)
+#define V_SMB_LB(x)                 _SB_MAKEVALUE(x,S_SMB_LB)
+
+#define S_SMB_MB                    8
+#define M_SMB_MB                    _SB_MAKEMASK(8,S_SMB_MB)
+#define V_SMB_MB(x)                 _SB_MAKEVALUE(x,S_SMB_MB)
+
+
+/*
+ * SMBus Packet Error Check register (Table 14-8)
+ */
+
+#define S_SPEC_PEC                  0
+#define M_SPEC_PEC                  _SB_MAKEMASK(8,S_SPEC_PEC)
+#define V_SPEC_MB(x)                _SB_MAKEVALUE(x,S_SPEC_PEC)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_syncser.h linux/include/asm-mips64/sibyte/sb1250_syncser.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_syncser.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_syncser.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,148 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *
+    *  Synchronous Serial Constants              File: sb1250_syncser.h
+    *
+    *  This module contains constants and macros useful for
+    *  manipulating the SB1250's Synchronous Serial
+    *
+    *  SB1250 specification level:  0.2
+    *
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *
+    *********************************************************************
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_SYNCSER_H
+#define _SB1250_SYNCSER_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Serial Mode Configuration Register
+ */
+
+#define M_SYNCSER_CRC_MODE                 _SB_MAKEMASK1(0)
+#define M_SYNCSER_MSB_FIRST                _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_FLAG_NUM                 2
+#define M_SYNCSER_FLAG_NUM                 _SB_MAKEMASK(4,S_SYNCSER_FLAG_NUM)
+#define V_SYNCSER_FLAG_NUM                 _SB_MAKEVALUE(x,S_SYNCSER_FLAG_NUM)
+
+#define M_SYNCSER_FLAG_EN                  _SB_MAKEMASK1(6)
+#define M_SYNCSER_HDLC_EN                  _SB_MAKEMASK1(7)
+#define M_SYNCSER_LOOP_MODE                _SB_MAKEMASK1(8)
+#define M_SYNCSER_LOOPBACK                 _SB_MAKEMASK1(9)
+
+/*
+ * Serial Clock Source and Line Interface Mode Register
+ */
+
+#define M_SYNCSER_RXCLK_INV                _SB_MAKEMASK1(0)
+#define M_SYNCSER_RXCLK_EXT                _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_RXSYNC_DLY               2
+#define M_SYNCSER_RXSYNC_DLY               _SB_MAKEMASK(2,S_SYNCSER_RXSYNC_DLY)
+#define V_SYNCSER_RXSYNC_DLY(x)            _SB_MAKEVALUE(x,S_SYNCSER_RXSYNC_DLY)
+
+#define M_SYNCSER_RXSYNC_LOW               _SB_MAKEMASK1(4)
+#define M_SYNCSER_RXSTRB_LOW               _SB_MAKEMASK1(5)
+
+#define M_SYNCSER_RXSYNC_EDGE              _SB_MAKEMASK1(6)
+#define M_SYNCSER_RXSYNC_INT               _SB_MAKEMASK1(7)
+
+#define M_SYNCSER_TXCLK_INV                _SB_MAKEMASK1(8)
+#define M_SYNCSER_TXCLK_EXT                _SB_MAKEMASK1(9)
+
+#define S_SYNCSER_TXSYNC_DLY               10
+#define M_SYNCSER_TXSYNC_DLY               _SB_MAKEMASK(2,S_SYNCSER_TXSYNC_DLY)
+#define V_SYNCSER_TXSYNC_DLY(x)            _SB_MAKEVALUE(x,S_SYNCSER_TXSYNC_DLY)
+
+#define M_SYNCSER_TXSYNC_LOW               _SB_MAKEMASK1(12)
+#define M_SYNCSER_TXSTRB_LOW               _SB_MAKEMASK1(13)
+
+#define M_SYNCSER_TXSYNC_EDGE              _SB_MAKEMASK1(14)
+#define M_SYNCSER_TXSYNC_INT               _SB_MAKEMASK1(15)
+
+/*
+ * Serial Command Register
+ */
+
+#define M_SYNCSER_CMD_RX_EN                _SB_MAKEMASK1(0)
+#define M_SYNCSER_CMD_TX_EN                _SB_MAKEMASK1(1)
+#define M_SYNCSER_CMD_RX_RESET             _SB_MAKEMASK1(2)
+#define M_SYNCSER_CMD_TX_RESET             _SB_MAKEMASK1(3)
+#define M_SYNCSER_CMD_TX_PAUSE             _SB_MAKEMASK1(5)
+
+/*
+ * Serial DMA Enable Register
+ */
+
+#define M_SYNCSER_DMA_RX_EN                _SB_MAKEMASK1(0)
+#define M_SYNCSER_DMA_TX_EN                _SB_MAKEMASK1(4)
+
+/*
+ * Serial Status Register
+ */
+
+#define M_SYNCSER_RX_CRCERR                _SB_MAKEMASK1(0)
+#define M_SYNCSER_RX_ABORT                 _SB_MAKEMASK1(1)
+#define M_SYNCSER_RX_OCTET                 _SB_MAKEMASK1(2)
+#define M_SYNCSER_RX_LONGFRM               _SB_MAKEMASK1(3)
+#define M_SYNCSER_RX_SHORTFRM              _SB_MAKEMASK1(4)
+#define M_SYNCSER_RX_OVERRUN               _SB_MAKEMASK1(5)
+#define M_SYNCSER_RX_SYNC_ERR              _SB_MAKEMASK1(6)
+#define M_SYNCSER_TX_CRCERR                _SB_MAKEMASK1(8)
+#define M_SYNCSER_TX_UNDERRUN              _SB_MAKEMASK1(9)
+#define M_SYNCSER_TX_SYNC_ERR              _SB_MAKEMASK1(10)
+#define M_SYNCSER_TX_PAUSE_COMPLETE        _SB_MAKEMASK1(11)
+#define M_SYNCSER_RX_EOP_COUNT             _SB_MAKEMASK1(16)
+#define M_SYNCSER_RX_EOP_TIMER             _SB_MAKEMASK1(17)
+#define M_SYNCSER_RX_EOP_SEEN              _SB_MAKEMASK1(18)
+#define M_SYNCSER_RX_HWM                   _SB_MAKEMASK1(19)
+#define M_SYNCSER_RX_LWM                   _SB_MAKEMASK1(20)
+#define M_SYNCSER_RX_DSCR                  _SB_MAKEMASK1(21)
+#define M_SYNCSER_RX_DERR                  _SB_MAKEMASK1(22)
+#define M_SYNCSER_TX_EOP_COUNT             _SB_MAKEMASK1(24)
+#define M_SYNCSER_TX_EOP_TIMER             _SB_MAKEMASK1(25)
+#define M_SYNCSER_TX_EOP_SEEN              _SB_MAKEMASK1(26)
+#define M_SYNCSER_TX_HWM                   _SB_MAKEMASK1(27)
+#define M_SYNCSER_TX_LWM                   _SB_MAKEMASK1(28)
+#define M_SYNCSER_TX_DSCR                  _SB_MAKEMASK1(29)
+#define M_SYNCSER_TX_DERR                  _SB_MAKEMASK1(30)
+#define M_SYNCSER_TX_DZERO                 _SB_MAKEMASK1(31)
+
+/*
+ * Sequencer Table Entry format
+ */
+
+#define M_SYNCSER_SEQ_LAST                 _SB_MAKEMASK1(0)
+#define M_SYNCSER_SEQ_BYTE                 _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_SEQ_COUNT                2
+#define M_SYNCSER_SEQ_COUNT                _SB_MAKEMASK(4,S_SYNCSER_SEQ_COUNT)
+#define V_SYNCSER_SEQ_COUNT(x)             _SB_MAKEVALUE(x,S_SYNCSER_SEQ_COUNT)
+
+#define M_SYNCSER_SEQ_ENABLE               _SB_MAKEMASK1(6)
+#define M_SYNCSER_SEQ_STROBE               _SB_MAKEMASK1(7)
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250_uart.h linux/include/asm-mips64/sibyte/sb1250_uart.h
--- linux.orig/include/asm-mips64/sibyte/sb1250_uart.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250_uart.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,336 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  UART Constants				File: sb1250_uart.h
+    *  
+    *  This module contains constants and macros useful for 
+    *  manipulating the SB1250's UARTs
+    *
+    *  SB1250 specification level:  01/02/2002
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+
+#ifndef _SB1250_UART_H
+#define _SB1250_UART_H
+
+#include "sb1250_defs.h"
+
+/* ********************************************************************** 
+   * DUART Registers
+   ********************************************************************** */
+
+/*
+ * DUART Mode Register #1 (Table 10-3)
+ * Register: DUART_MODE_REG_1_A
+ * Register: DUART_MODE_REG_1_B
+ */
+
+#define S_DUART_BITS_PER_CHAR       0
+#define M_DUART_BITS_PER_CHAR       _SB_MAKEMASK(2,S_DUART_BITS_PER_CHAR)
+#define V_DUART_BITS_PER_CHAR(x)    _SB_MAKEVALUE(x,S_DUART_BITS_PER_CHAR)
+
+#define K_DUART_BITS_PER_CHAR_RSV0  0
+#define K_DUART_BITS_PER_CHAR_RSV1  1
+#define K_DUART_BITS_PER_CHAR_7     2
+#define K_DUART_BITS_PER_CHAR_8     3
+
+#define V_DUART_BITS_PER_CHAR_RSV0  V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV0)
+#define V_DUART_BITS_PER_CHAR_RSV1  V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV1)
+#define V_DUART_BITS_PER_CHAR_7     V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_7)
+#define V_DUART_BITS_PER_CHAR_8     V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_8)
+
+
+#define M_DUART_PARITY_TYPE_EVEN    0x00
+#define M_DUART_PARITY_TYPE_ODD     _SB_MAKEMASK1(2)
+
+#define S_DUART_PARITY_MODE          3
+#define M_DUART_PARITY_MODE         _SB_MAKEMASK(2,S_DUART_PARITY_MODE)
+#define V_DUART_PARITY_MODE(x)      _SB_MAKEVALUE(x,S_DUART_PARITY_MODE)
+
+#define K_DUART_PARITY_MODE_ADD       0
+#define K_DUART_PARITY_MODE_ADD_FIXED 1
+#define K_DUART_PARITY_MODE_NONE      2
+
+#define V_DUART_PARITY_MODE_ADD       V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD)
+#define V_DUART_PARITY_MODE_ADD_FIXED V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD_FIXED)
+#define V_DUART_PARITY_MODE_NONE      V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_NONE)
+
+#define M_DUART_ERR_MODE            _SB_MAKEMASK1(5)    /* must be zero */
+
+#define M_DUART_RX_IRQ_SEL_RXRDY    0
+#define M_DUART_RX_IRQ_SEL_RXFULL   _SB_MAKEMASK1(6)
+
+#define M_DUART_RX_RTS_ENA          _SB_MAKEMASK1(7)
+
+/*
+ * DUART Mode Register #2 (Table 10-4)
+ * Register: DUART_MODE_REG_2_A
+ * Register: DUART_MODE_REG_2_B
+ */
+
+#define M_DUART_MODE_RESERVED1      _SB_MAKEMASK(3,0)   /* ignored */
+
+#define M_DUART_STOP_BIT_LEN_2      _SB_MAKEMASK1(3)
+#define M_DUART_STOP_BIT_LEN_1      0
+
+#define M_DUART_TX_CTS_ENA          _SB_MAKEMASK1(4)
+
+#define M_DUART_MODE_RESERVED2      _SB_MAKEMASK1(5)    /* must be zero */
+
+#define S_DUART_CHAN_MODE	    6
+#define M_DUART_CHAN_MODE           _SB_MAKEMASK(2,S_DUART_CHAN_MODE)
+#define V_DUART_CHAN_MODE(x)	    _SB_MAKEVALUE(x,S_DUART_CHAN_MODE)
+
+#define K_DUART_CHAN_MODE_NORMAL    0
+#define K_DUART_CHAN_MODE_LCL_LOOP  2
+#define K_DUART_CHAN_MODE_REM_LOOP  3
+
+#define V_DUART_CHAN_MODE_NORMAL    V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_NORMAL)
+#define V_DUART_CHAN_MODE_LCL_LOOP  V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_LCL_LOOP)
+#define V_DUART_CHAN_MODE_REM_LOOP  V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_REM_LOOP)
+
+/*
+ * DUART Command Register (Table 10-5)
+ * Register: DUART_CMD_A
+ * Register: DUART_CMD_B
+ */
+
+#define M_DUART_RX_EN               _SB_MAKEMASK1(0)
+#define M_DUART_RX_DIS              _SB_MAKEMASK1(1)
+#define M_DUART_TX_EN               _SB_MAKEMASK1(2)
+#define M_DUART_TX_DIS              _SB_MAKEMASK1(3)
+
+#define S_DUART_MISC_CMD	    4
+#define M_DUART_MISC_CMD            _SB_MAKEMASK(3,S_DUART_MISC_CMD)
+#define V_DUART_MISC_CMD(x)         _SB_MAKEVALUE(x,S_DUART_MISC_CMD)
+
+#define K_DUART_MISC_CMD_NOACTION0       0
+#define K_DUART_MISC_CMD_NOACTION1       1
+#define K_DUART_MISC_CMD_RESET_RX        2
+#define K_DUART_MISC_CMD_RESET_TX        3
+#define K_DUART_MISC_CMD_NOACTION4       4
+#define K_DUART_MISC_CMD_RESET_BREAK_INT 5
+#define K_DUART_MISC_CMD_START_BREAK     6
+#define K_DUART_MISC_CMD_STOP_BREAK      7
+
+#define V_DUART_MISC_CMD_NOACTION0       V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION0)
+#define V_DUART_MISC_CMD_NOACTION1       V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION1)
+#define V_DUART_MISC_CMD_RESET_RX        V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_RX)
+#define V_DUART_MISC_CMD_RESET_TX        V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_TX)
+#define V_DUART_MISC_CMD_NOACTION4       V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION4)
+#define V_DUART_MISC_CMD_RESET_BREAK_INT V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_BREAK_INT)
+#define V_DUART_MISC_CMD_START_BREAK     V_DUART_MISC_CMD(K_DUART_MISC_CMD_START_BREAK)
+#define V_DUART_MISC_CMD_STOP_BREAK      V_DUART_MISC_CMD(K_DUART_MISC_CMD_STOP_BREAK)
+
+#define M_DUART_CMD_RESERVED             _SB_MAKEMASK1(7) 
+
+/*
+ * DUART Status Register (Table 10-6)
+ * Register: DUART_STATUS_A
+ * Register: DUART_STATUS_B
+ * READ-ONLY
+ */
+
+#define M_DUART_RX_RDY              _SB_MAKEMASK1(0)
+#define M_DUART_RX_FFUL             _SB_MAKEMASK1(1)
+#define M_DUART_TX_RDY              _SB_MAKEMASK1(2)
+#define M_DUART_TX_EMT              _SB_MAKEMASK1(3)
+#define M_DUART_OVRUN_ERR           _SB_MAKEMASK1(4)
+#define M_DUART_PARITY_ERR          _SB_MAKEMASK1(5)
+#define M_DUART_FRM_ERR             _SB_MAKEMASK1(6)
+#define M_DUART_RCVD_BRK            _SB_MAKEMASK1(7)
+
+/*
+ * DUART Baud Rate Register (Table 10-7)
+ * Register: DUART_CLK_SEL_A 
+ * Register: DUART_CLK_SEL_B
+ */
+
+#define M_DUART_CLK_COUNTER         _SB_MAKEMASK(12,0)
+#define V_DUART_BAUD_RATE(x)        (100000000/((x)*20)-1)
+
+/*
+ * DUART Data Registers (Table 10-8 and 10-9)
+ * Register: DUART_RX_HOLD_A
+ * Register: DUART_RX_HOLD_B
+ * Register: DUART_TX_HOLD_A
+ * Register: DUART_TX_HOLD_B
+ */
+
+#define M_DUART_RX_DATA             _SB_MAKEMASK(8,0)
+#define M_DUART_TX_DATA             _SB_MAKEMASK(8,0)
+
+/*
+ * DUART Input Port Register (Table 10-10)
+ * Register: DUART_IN_PORT
+ */
+
+#define M_DUART_IN_PIN0_VAL         _SB_MAKEMASK1(0)
+#define M_DUART_IN_PIN1_VAL         _SB_MAKEMASK1(1)
+#define M_DUART_IN_PIN2_VAL         _SB_MAKEMASK1(2)
+#define M_DUART_IN_PIN3_VAL         _SB_MAKEMASK1(3)
+#define M_DUART_IN_PIN4_VAL         _SB_MAKEMASK1(4)
+#define M_DUART_IN_PIN5_VAL         _SB_MAKEMASK1(5)
+#define M_DUART_RIN0_PIN            _SB_MAKEMASK1(6)
+#define M_DUART_RIN1_PIN            _SB_MAKEMASK1(7)
+
+/*
+ * DUART Input Port Change Status Register (Tables 10-11, 10-12, and 10-13)
+ * Register: DUART_INPORT_CHNG
+ */
+
+#define S_DUART_IN_PIN_VAL          0
+#define M_DUART_IN_PIN_VAL          _SB_MAKEMASK(4,S_DUART_IN_PIN_VAL)
+
+#define S_DUART_IN_PIN_CHNG         4
+#define M_DUART_IN_PIN_CHNG         _SB_MAKEMASK(4,S_DUART_IN_PIN_CHNG)
+
+/*
+ * DUART Output port control register (Table 10-14)
+ * Register: DUART_OPCR
+ */
+
+#define M_DUART_OPCR_RESERVED0      _SB_MAKEMASK1(0)   /* must be zero */
+#define M_DUART_OPC2_SEL            _SB_MAKEMASK1(1)
+#define M_DUART_OPCR_RESERVED1      _SB_MAKEMASK1(2)   /* must be zero */
+#define M_DUART_OPC3_SEL            _SB_MAKEMASK1(3)
+#define M_DUART_OPCR_RESERVED2      _SB_MAKEMASK(4,4)  /* must be zero */
+
+/*
+ * DUART Aux Control Register (Table 10-15)
+ * Register: DUART_AUX_CTRL
+ */
+
+#define M_DUART_IP0_CHNG_ENA        _SB_MAKEMASK1(0)
+#define M_DUART_IP1_CHNG_ENA        _SB_MAKEMASK1(1)
+#define M_DUART_IP2_CHNG_ENA        _SB_MAKEMASK1(2)
+#define M_DUART_IP3_CHNG_ENA        _SB_MAKEMASK1(3)
+#define M_DUART_ACR_RESERVED        _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Interrupt Status Register (Table 10-16)
+ * Register: DUART_ISR
+ */
+
+#define M_DUART_ISR_TX_A            _SB_MAKEMASK1(0)
+#define M_DUART_ISR_RX_A            _SB_MAKEMASK1(1)
+#define M_DUART_ISR_BRK_A           _SB_MAKEMASK1(2)
+#define M_DUART_ISR_IN_A            _SB_MAKEMASK1(3)
+#define M_DUART_ISR_TX_B            _SB_MAKEMASK1(4)
+#define M_DUART_ISR_RX_B            _SB_MAKEMASK1(5)
+#define M_DUART_ISR_BRK_B           _SB_MAKEMASK1(6)
+#define M_DUART_ISR_IN_B            _SB_MAKEMASK1(7)
+
+/*
+ * DUART Channel A Interrupt Status Register (Table 10-17)
+ * DUART Channel B Interrupt Status Register (Table 10-18)
+ * Register: DUART_ISR_A
+ * Register: DUART_ISR_B
+ */
+
+#define M_DUART_ISR_TX              _SB_MAKEMASK1(0)
+#define M_DUART_ISR_RX              _SB_MAKEMASK1(1)
+#define M_DUART_ISR_BRK             _SB_MAKEMASK1(2)
+#define M_DUART_ISR_IN              _SB_MAKEMASK1(3)
+#define M_DUART_ISR_RESERVED        _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Interrupt Mask Register (Table 10-19)
+ * Register: DUART_IMR
+ */
+
+#define M_DUART_IMR_TX_A            _SB_MAKEMASK1(0)
+#define M_DUART_IMR_RX_A            _SB_MAKEMASK1(1)
+#define M_DUART_IMR_BRK_A           _SB_MAKEMASK1(2)
+#define M_DUART_IMR_IN_A            _SB_MAKEMASK1(3)
+#define M_DUART_IMR_ALL_A	    _SB_MAKEMASK(4,0)
+
+#define M_DUART_IMR_TX_B            _SB_MAKEMASK1(4)
+#define M_DUART_IMR_RX_B            _SB_MAKEMASK1(5)
+#define M_DUART_IMR_BRK_B           _SB_MAKEMASK1(6)
+#define M_DUART_IMR_IN_B            _SB_MAKEMASK1(7)
+#define M_DUART_IMR_ALL_B           _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Channel A Interrupt Mask Register (Table 10-20)
+ * DUART Channel B Interrupt Mask Register (Table 10-21)
+ * Register: DUART_IMR_A
+ * Register: DUART_IMR_B
+ */
+
+#define M_DUART_IMR_TX              _SB_MAKEMASK1(0)
+#define M_DUART_IMR_RX              _SB_MAKEMASK1(1)
+#define M_DUART_IMR_BRK             _SB_MAKEMASK1(2)
+#define M_DUART_IMR_IN              _SB_MAKEMASK1(3)
+#define M_DUART_IMR_ALL		    _SB_MAKEMASK(4,0)
+#define M_DUART_IMR_RESERVED        _SB_MAKEMASK(4,4)
+
+
+/*
+ * DUART Output Port Set Register (Table 10-22)
+ * Register: DUART_SET_OPR
+ */
+
+#define M_DUART_SET_OPR0            _SB_MAKEMASK1(0)
+#define M_DUART_SET_OPR1            _SB_MAKEMASK1(1)
+#define M_DUART_SET_OPR2            _SB_MAKEMASK1(2)
+#define M_DUART_SET_OPR3            _SB_MAKEMASK1(3)
+#define M_DUART_OPSR_RESERVED       _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Output Port Clear Register (Table 10-23)
+ * Register: DUART_CLEAR_OPR
+ */
+
+#define M_DUART_CLR_OPR0            _SB_MAKEMASK1(0)
+#define M_DUART_CLR_OPR1            _SB_MAKEMASK1(1)
+#define M_DUART_CLR_OPR2            _SB_MAKEMASK1(2)
+#define M_DUART_CLR_OPR3            _SB_MAKEMASK1(3)
+#define M_DUART_OPCR_RESERVED       _SB_MAKEMASK(4,4)
+
+/*
+ * DUART Output Port RTS Register (Table 10-24)
+ * Register: DUART_OUT_PORT
+ */
+
+#define M_DUART_OUT_PIN_SET0        _SB_MAKEMASK1(0)
+#define M_DUART_OUT_PIN_SET1        _SB_MAKEMASK1(1)
+#define M_DUART_OUT_PIN_CLR0        _SB_MAKEMASK1(2)
+#define M_DUART_OUT_PIN_CLR1        _SB_MAKEMASK1(3)
+#define M_DUART_OPRR_RESERVED       _SB_MAKEMASK(4,4)
+
+#define M_DUART_OUT_PIN_SET(chan) \
+    (chan == 0 ? M_DUART_OUT_PIN_SET0 : M_DUART_OUT_PIN_SET1)
+#define M_DUART_OUT_PIN_CLR(chan) \
+    (chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1)
+
+/*
+ * XXX To be added: Synchronous Serial definitions
+ */
+
+/* ********************************************************************** */
+
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sb1250regs.h linux/include/asm-mips64/sibyte/sb1250regs.h
--- linux.orig/include/asm-mips64/sibyte/sb1250regs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sb1250regs.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+/* Register definitions and offsets for the SB1250 integrated peripherals */
+
+/* Base addresses for each of the cpus */
+#include <asm/addrspace.h>
+
+#define SB1250_SCD_BASE        (KSEG1 + 0x10020000)
+
+/* All the SCD registers are duplicated for each cpu. */
+#define SB1250_CPU0_OFS                 0
+#define SB1250_CPU1_OFS            0x2000
+
+#define SB1250_INT_DIAG         (SB1250_SCD_BASE + 0x10)
+#define SB1250_INT_LDT_SET      (SB1250_SCD_BASE + 0x48)
+#define SB1250_INT_LDT          (SB1250_SCD_BASE + 0x18)
+#define SB1250_INT_LDT_CLR      (SB1250_SCD_BASE + 0x20)
+#define SB1250_INT_MASK         (SB1250_SCD_BASE + 0x28)
+#define SB1250_INT_STATUS       (SB1250_SCD_BASE + 0x100)
+#define SB1250_INT_SRC_STATUS   (SB1250_SCD_BASE + 0x040)
+#define SB1250_INT_TRC          (SB1250_SCD_BASE + 0x38)
+#define SB1250_INT_MAP          (SB1250_SCD_BASE + 0x200)
+
+/* General purpose timer configuration registers */
+#define SB1250_GPT_CFG0         (SB1250_SCD_BASE + 0x090)
+#define SB1250_GPT_CFG1         (SB1250_SCD_BASE + 0x098)
+#define SB1250_GPT_CFG2         (SB1250_SCD_BASE + 0x190)
+#define SB1250_GPT_CFG3         (SB1250_SCD_BASE + 0x198)
+
+#define SB1250_GPT_INT_MAP0     (SB1250_INT_MAP + (2<<3))
+#define SB1250_GPT_INT_MAP1     (SB1250_INT_MAP + (3<<3))
+#define SB1250_GPT_INT_MAP2     (SB1250_INT_MAP + (4<<3))
+#define SB1250_GPT_INT_MAP3     (SB1250_INT_MAP + (5<<3))
+
+/* General purpose timer configuration bitfields */
+#define SB1250_GPT_CFG_ENABLE      0x1
+#define SB1250_GPT_CFG_CONTINUOUS  0x2
+
+/* General purpose timer count initialization registers */
+#define SB1250_GPT_INIT_CNT0    (SB1250_SCD_BASE + 0x070)
+#define SB1250_GPT_INIT_CNT1    (SB1250_SCD_BASE + 0x078)
+#define SB1250_GPT_INIT_CNT2    (SB1250_SCD_BASE + 0x170)
+#define SB1250_GPT_INIT_CNT3    (SB1250_SCD_BASE + 0x178)
+
+/* Interrupt map values */
+#define SB1250_MAP_IP2             0
+#define SB1250_MAP_IP3             1
+#define SB1250_MAP_IP4             2
+#define SB1250_MAP_IP5             3
+#define SB1250_MAP_IP6             4
+#define SB1250_MAP_IP7             5
+#define SB1250_MAP_NMI             6
+#define SB1250_MAP_DEBUG           7
+
+
+/* Owners of the various interrupts at the scd level.  Note this
+   is the pre mapping values. */
+
+#define SB1250_INT_WATCHDOG_0            0
+#define SB1250_INT_WATCHDOG_1            1
+#define SB1250_INT_TIMER_0               2
+#define SB1250_INT_TIMER_1               3
+#define SB1250_INT_TIMER_2               4
+#define SB1250_INT_TIMER_3               5
+#define SB1250_INT_SMB_0                 6
+#define SB1250_INT_SMB_1                 7
+#define SB1250_INT_UART_0                8
+#define SB1250_INT_UART_1                9
+
+/* FIXME!  Need to add the rest */
+ 
+
+/*
+ * There are 2 UARTS.  Technically you can access them via
+ * some unified registers, but the seperated interfaces are 
+ * much cleaner 
+ */
+
+#define SB1250_UART_0_OFS            0x000  
+#define SB1250_UART_1_OFS            0x100  
+
+#define SB1250_DUART_MODE_1   (KSEG1 + 0x10060100)
+#define SB1250_DUART_MODE_2   (KSEG1 + 0x10060110)
+#define SB1250_DUART_CMD      (KSEG1 + 0x10060150)
+#define SB1250_DUART_STATUS   (KSEG1 + 0x10060120)
+#define SB1250_DUART_BAUD     (KSEG1 + 0x10060130)
+#define SB1250_DUART_RX       (KSEG1 + 0x10060160)
+#define SB1250_DUART_TX       (KSEG1 + 0x10060170)
+#define SB1250_DUART_CLK_SEL  (KSEG1 + 0x10060130)
+#define SB1250_DUART_IMR0     (KSEG1 + 0x10060330)
+#define SB1250_DUART_IMR1     (KSEG1 + 0x10060350)
+
+/* 
+ *   Mode register 1 fields 
+ */
+/* Bits per character */
+#define SB1250_DM1_8BPC        0x0
+#define SB1250_DM1_7BPR        0x1
+
+/* Parity type */
+#define SB1250_DM1_EVEN_PAR    0x0
+#define SB1250_DM1_LOW_PAR     0x0
+#define SB1250_DM1_ODD_PAR     0x4
+#define SB1250_DM1_HIGH_PAR    0x4
+
+/* Parity mode */
+#define SB1250_DM1_PAR          0x0
+#define SB1250_DM1_FIXED_PAR    0x8
+#define SB1250_DM1_NO_PAR      0x10
+
+/* Recieve IRQ select */
+#define SB1250_DM1_IRQ_READY   0x00
+#define SB1250_DM1_IRQ_FULL    0x40
+
+/* RTS flow control */
+#define SB1250_DM1_RTS         0x80
+
+/* 
+ *   Mode register 2 fields 
+ */
+/* Stop bit length */
+#define SB1250_DM2_1_STOP_BIT  0x0
+#define SB1250_DM2_2_STOP_BITS 0x8
+
+/* Transmitter CTS flow control enable */
+#define SB1250_DM2_CTS         0x10
+
+/* DUART Channel mode */
+#define SB1250_DM2_LCL_LOOP    0x80
+#define SB1250_DM2_RMT_LOOP    0xc0
+
+/*
+ * Command register fields 
+ */
+/* Any of these can be written */
+#define SB1250_DC_RX_EN        0x1
+#define SB1250_DC_RX_DIS       0x2
+#define SB1250_DC_TX_EN        0x4
+#define SB1250_DC_TX_DIS       0x8
+
+/* Command field possibilities.  At most one of these should be written 
+   at a time */
+#define SB1250_DC_RX_RST      0x20
+#define SB1250_DC_TX_RST      0x30
+#define SB1250_DC_BRK_CHG_RST 0x50
+#define SB1250_DC_BRK_START   0x60
+#define SB1250_DC_BRK_STOP    0x70
+
+/* FINISH ME */
+
+#define SB1250_DS_TX_RDY       0x4
+#define SB1250_DS_RX_RDY       0x1
+#define SB1250_DS_TX_EMT       0x8
+
+/* DUART interrupt source masks for ISR */
+#define SB1250_DIM_TX          0x1
+#define SB1250_DIM_RX          0x2
+#define SB1250_DIM_BRK         0x4
+#define SB1250_DIM_IN          0x8
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/sbmips.h linux/include/asm-mips64/sibyte/sbmips.h
--- linux.orig/include/asm-mips64/sibyte/sbmips.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/sbmips.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,654 @@
+/*  *********************************************************************
+    *  SB1250 Board Support Package
+    *  
+    *  MIPS64 CPU definitions			File: sbmips.h
+    * 
+    *  This module contains constants and macros specific to the
+    *  SB1 MIPS64 core.
+    *  
+    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  
+    *********************************************************************  
+    *
+    *  Copyright 2000,2001
+    *  Broadcom Corporation. 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
+    ********************************************************************* */
+
+#ifndef _SB_MIPS_H
+#define _SB_MIPS_H
+
+/*  *********************************************************************
+    *  Configure language
+    ********************************************************************* */
+
+#if defined(__ASSEMBLY__)
+#define _ATYPE_
+#define _ATYPE32_
+#define _ATYPE64_
+#else
+#define _ATYPE_		(__SIZE_TYPE__)
+#define _ATYPE32_	(int)
+#define _ATYPE64_	(long long)
+#endif
+
+
+/*  *********************************************************************
+    *  Bitfield macros
+    ********************************************************************* */
+
+/*
+ * Make a mask for 1 bit at position 'n'
+ */
+
+#define _MM_MAKEMASK1(n) (1 << (n))
+
+/*
+ * Make a mask for 'v' bits at position 'n'
+ */
+
+#define _MM_MAKEMASK(v,n) (((1<<(v))-1) << (n))
+
+/*
+ * Make a value at 'v' at bit position 'n'
+ */
+
+#define _MM_MAKEVALUE(v,n) ((v) << (n))
+
+/*
+ * Retrieve a value from 'v' at bit position 'n' with 'm' mask bits
+ */
+
+#define _MM_GETVALUE(v,n,m) (((v) & (m)) >> (n))
+
+
+
+/*  *********************************************************************
+    *  32-bit MIPS Address Spaces
+    ********************************************************************* */
+
+#ifdef __ASSEMBLY__
+#define _ACAST32_
+#define _ACAST64_
+#else
+#define _ACAST32_	_ATYPE_ _ATYPE32_	/* widen if necessary */
+#define _ACAST64_		_ATYPE64_	/* do _not_ narrow */
+#endif
+
+/* 32-bit address map */
+#define UBASE		0x00000000		/* user+ mapped */
+#define USIZE		0x80000000
+#define K0BASE 		(_ACAST32_ 0x80000000)	/* kernel unmapped cached */
+#define K0SIZE 		0x20000000
+#define K1BASE 		(_ACAST32_ 0xa0000000)	/* kernel unmapped uncached */
+#define K1SIZE 		0x20000000
+#define KSBASE 		(_ACAST32_ 0xc0000000)	/* supervisor+ mapped */
+#define KSSIZE 		0x20000000
+#define K3BASE 		(_ACAST32_ 0xe0000000)	/* kernel mapped */
+#define K3SIZE 		0x20000000
+
+/* 64-bit address map additions to the above (sign-extended) ranges */
+#define XUBASE		(_ACAST64_ 0x0000000080000000)	/* user+ mapped */
+#define XUSIZE		(_ACAST64_ 0x00000FFF80000000)
+#define XSSEGBASE       (_ACAST64_ 0x4000000000000000)	/* supervisor+ mapped */
+#define XSSEGSIZE	(_ACAST64_ 0x0000100000000000)
+#define XKPHYSBASE      (_ACAST64_ 0x8000000000000000)	/* kernel unmapped */
+#define XKPHYSSIZE	(_ACAST64_ 0x0000100000000000)
+#define XKSEGBASE       (_ACAST64_ 0xC000000000000000)	/* kernel mapped */
+#define XKSEGSIZE	(_ACAST64_ 0x00000FFF80000000)
+
+#define GEN_VECT 	(_ACAST32_ 0x80000080)
+#define UTLB_VECT 	(_ACAST32_ 0x80000000)
+
+/*  *********************************************************************
+    *  Address space coercion macros
+    ********************************************************************* */
+
+#define PHYS_TO_K0(pa)	(K0BASE | (pa))
+#define PHYS_TO_K1(pa)	(K1BASE | (pa))
+#define K0_TO_PHYS(va)	((va) & (K0SIZE-1))
+#define K1_TO_PHYS(va)	((va) & (K1SIZE-1))
+#define K0_TO_K1(va)	((va) | K1SIZE)
+#define K1_TO_K0(va)	((va) & ~K1SIZE)
+
+#define PHYS_TO_XK1(p) (_ACAST64_ (0xffffffffa0000000 | (p)))
+#define XK1_TO_PHYS(p) ((p) & (K1SIZE-1))
+#define PHYS_TO_XKPHYS(cca,p) (_SB_MAKEMASK1(63) | (_SB_MAKE64(cca) << 59) | (p))
+#define PHYS_TO_XKSEG_UNCACHED(p)  PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p))
+#define PHYS_TO_XKSEG_CACHED(p)    PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p))
+#define XKPHYS_TO_PHYS(p) ((p) & _SB_MAKEMASK(0,59))
+
+
+#if !defined(__ASSEMBLY__)
+#define mips_wbflush()  __asm__ __volatile__ ("sync" : : : "memory")
+#define	ISK0SEG(va)	((va) >= K0BASE && (va) <= (K0BASE + K0SIZE - 1))
+#define	ISK1SEG(va)	((va) >= K1BASE && (va) <= (K1BASE + K1SIZE - 1))
+#endif
+
+/*  *********************************************************************
+    *  Register aliases
+    ********************************************************************* */
+
+#if defined(__ASSEMBLY__)
+#define zero		$0
+#define	AT		$1		/* assembler temporaries */
+#define	v0		$2		/* value holders */
+#define	v1		$3
+#define	a0		$4		/* arguments */
+#define	a1		$5
+#define	a2		$6
+#define	a3		$7
+#define	t0		$8		/* temporaries */
+#define	t1		$9
+#define	t2		$10
+#define	t3		$11
+#define	t4		$12
+#define	t5		$13
+#define	t6		$14
+#define	t7		$15
+#define ta0		$12
+#define ta1		$13
+#define ta2		$14
+#define ta3		$15
+#define	s0		$16		/* saved registers */
+#define	s1		$17
+#define	s2		$18
+#define	s3		$19
+#define	s4		$20
+#define	s5		$21
+#define	s6		$22
+#define	s7		$23
+#define	t8		$24		/* temporaries */
+#define	t9		$25
+#define	k0		$26		/* kernel registers */
+#define	k1		$27
+#define	gp		$28		/* global pointer */
+#define	sp		$29		/* stack pointer */
+#define	s8		$30		/* saved register */
+#define	fp		$30		/* frame pointer */
+#define	ra		$31		/* return address */
+#endif
+
+/*  *********************************************************************
+    *  CP0 Registers 
+    ********************************************************************* */
+
+#if defined(__ASSEMBLY__)
+#define C0_INX		$0		/* CP0: TLB Index */
+#define C0_RAND		$1		/* CP0: TLB Random */
+#define C0_TLBLO0	$2		/* CP0: TLB EntryLo0 */
+#define C0_TLBLO	C0_TLBLO0	/* CP0: TLB EntryLo0 */
+#define C0_TLBLO1	$3		/* CP0: TLB EntryLo1 */
+#define C0_CTEXT	$4		/* CP0: Context */
+#define C0_PGMASK	$5		/* CP0: TLB PageMask */
+#define C0_WIRED	$6		/* CP0: TLB Wired */
+#define C0_BADVADDR	$8		/* CP0: Bad Virtual Address */
+#define C0_COUNT 	$9		/* CP0: Count */
+#define C0_TLBHI	$10		/* CP0: TLB EntryHi */
+#define C0_COMPARE	$11		/* CP0: Compare */
+#define C0_SR		$12		/* CP0: Processor Status */
+#define C0_STATUS	C0_SR		/* CP0: Processor Status */
+#define C0_CAUSE	$13		/* CP0: Exception Cause */
+#define C0_EPC		$14		/* CP0: Exception PC */
+#define C0_PRID		$15		/* CP0: Processor Revision Indentifier */
+#define C0_CONFIG	$16		/* CP0: Config */
+#define C0_LLADDR	$17		/* CP0: LLAddr */
+#define C0_WATCHLO	$18		/* CP0: WatchpointLo */
+#define C0_WATCHHI	$19		/* CP0: WatchpointHi */
+#define C0_XCTEXT	$20		/* CP0: XContext */
+#define C0_ECC		$26		/* CP0: ECC */
+#define C0_CACHEERR	$27		/* CP0: CacheErr */
+#define C0_TAGLO	$28		/* CP0: TagLo */
+#define C0_TAGHI	$29		/* CP0: TagHi */
+#define C0_ERREPC	$30		/* CP0: ErrorEPC */
+#else
+#define C0_INX		0		/* CP0: TLB Index */
+#define C0_RAND		1		/* CP0: TLB Random */
+#define C0_TLBLO0	2		/* CP0: TLB EntryLo0 */
+#define C0_TLBLO	C0_TLBLO0	/* CP0: TLB EntryLo0 */
+#define C0_TLBLO1	3		/* CP0: TLB EntryLo1 */
+#define C0_CTEXT	4		/* CP0: Context */
+#define C0_PGMASK	5		/* CP0: TLB PageMask */
+#define C0_WIRED	6		/* CP0: TLB Wired */
+#define C0_BADVADDR	8		/* CP0: Bad Virtual Address */
+#define C0_COUNT 	9		/* CP0: Count */
+#define C0_TLBHI	10		/* CP0: TLB EntryHi */
+#define C0_COMPARE	11		/* CP0: Compare */
+#define C0_SR		12		/* CP0: Processor Status */
+#define C0_STATUS	C0_SR		/* CP0: Processor Status */
+#define C0_CAUSE	13		/* CP0: Exception Cause */
+#define C0_EPC		14		/* CP0: Exception PC */
+#define C0_PRID		15		/* CP0: Processor Revision Indentifier */
+#define C0_CONFIG	16		/* CP0: Config */
+#define C0_LLADDR	17		/* CP0: LLAddr */
+#define C0_WATCHLO	18		/* CP0: WatchpointLo */
+#define C0_WATCHHI	19		/* CP0: WatchpointHi */
+#define C0_XCTEXT	20		/* CP0: XContext */
+#define C0_ECC		26		/* CP0: ECC */
+#define C0_CACHEERR	27		/* CP0: CacheErr */
+#define C0_TAGLO	28		/* CP0: TagLo */
+#define C0_TAGHI	29		/* CP0: TagHi */
+#define C0_ERREPC	30		/* CP0: ErrorEPC */
+#endif
+
+/*  *********************************************************************
+    *  CP1 (floating point) control registers
+    ********************************************************************* */
+
+#define FPA_IRR		0		/* CP1: Implementation/Revision */
+#define FPA_CSR		31		/* CP1: Control/Status */
+
+/*  *********************************************************************
+    *  Macros for generating assembly language routines
+    ********************************************************************* */
+
+#if defined(__ASSEMBLY__)
+
+/* global leaf function (does not call other functions) */
+#define LEAF(name)		\
+  	.globl	name;		\
+  	.ent	name;		\
+name:
+
+/* global alternate entry to (local or global) leaf function */
+#define XLEAF(name)		\
+  	.globl	name;		\
+  	.aent	name;		\
+name:
+
+/* end of a global function */
+#define END(name)		\
+  	.size	name,.-name;	\
+  	.end	name
+
+/* local leaf function (does not call other functions) */
+#define SLEAF(name)		\
+  	.ent	name;		\
+name:
+
+/* local alternate entry to (local or global) leaf function */
+#define SXLEAF(name)		\
+  	.aent	name;		\
+name:
+
+/* end of a local function */
+#define SEND(name)		\
+  	END(name)
+
+/* define & export a symbol */
+#define EXPORT(name)		\
+  	.globl name;		\
+name:
+
+/* import a symbol */
+#define	IMPORT(name, size)	\
+	.extern	name,size
+
+/* define a zero-fill common block (BSS if not overridden) with a global name */
+#define COMM(name,size)		\
+	.comm	name,size
+
+/* define a zero-fill common block (BSS if not overridden) with a local name */
+#define LCOMM(name,size)		\
+  	.lcomm	name,size
+
+#endif
+
+
+/* Floating-Point Control register bits */
+#define CSR_C		0x00800000
+#define CSR_EXC		0x0003f000
+#define CSR_EE		0x00020000
+#define CSR_EV		0x00010000
+#define CSR_EZ		0x00008000
+#define CSR_EO		0x00004000
+#define CSR_EU		0x00002000
+#define CSR_EI		0x00001000
+#define CSR_TV		0x00000800
+#define CSR_TZ		0x00000400
+#define CSR_TO		0x00000200
+#define CSR_TU		0x00000100
+#define CSR_TI		0x00000080
+#define CSR_SV		0x00000040
+#define CSR_SZ		0x00000020
+#define CSR_SO		0x00000010
+#define CSR_SU		0x00000008
+#define CSR_SI		0x00000004
+#define CSR_RM		0x00000003
+
+/* Status Register */
+#define M_SR_CUMASK	_MM_MAKEMASK(4,28)	/* coprocessor usable bits */
+#define M_SR_CU3	_MM_MAKEMASK1(31)	/* coprocessor 3 usable */
+#define M_SR_CU2	_MM_MAKEMASK1(30)	/* coprocessor 2 usable */
+#define M_SR_CU1	_MM_MAKEMASK1(29)	/* coprocessor 1 usable */
+#define M_SR_CU0	_MM_MAKEMASK1(28)	/* coprocessor 0 usable */
+
+#define M_SR_RP		_MM_MAKEMASK1(27)	/* reduced power mode */
+#define M_SR_FR		_MM_MAKEMASK1(26)	/* fpu regs any data */
+#define M_SR_RE		_MM_MAKEMASK1(25)	/* reverse endian */
+#define M_SR_MX		_MM_MAKEMASK1(24)	/* MDMX */
+#define M_SR_PX		_MM_MAKEMASK1(23)	/* 64-bit ops in user mode */
+#define M_SR_BEV	_MM_MAKEMASK1(22)	/* boot exception vectors */
+#define M_SR_TS		_MM_MAKEMASK1(21)	/* TLB is shut down */
+#define M_SR_SR		_MM_MAKEMASK1(20)	/* soft reset */
+#define M_SR_NMI	_MM_MAKEMASK1(19)	/* nonmaskable interrupt */
+
+#define M_SR_IMASK	_MM_MAKEMASK(8,8)	/* all interrupt mask bits */
+
+#define M_SR_IBIT8	_MM_MAKEMASK1(15)	/* individual bits */
+#define M_SR_IBIT7	_MM_MAKEMASK1(14)
+#define M_SR_IBIT6	_MM_MAKEMASK1(13)
+#define M_SR_IBIT5	_MM_MAKEMASK1(12)
+#define M_SR_IBIT4	_MM_MAKEMASK1(11)
+#define M_SR_IBIT3	_MM_MAKEMASK1(10)
+#define M_SR_IBIT2	_MM_MAKEMASK1(9)
+#define M_SR_IBIT1	_MM_MAKEMASK1(8)
+
+#define M_SR_IMASK8	0			/* masks for nested int levels */
+#define M_SR_IMASK7	_MM_MAKEMASK(1,15)
+#define M_SR_IMASK6	_MM_MAKEMASK(2,14)
+#define M_SR_IMASK5	_MM_MAKEMASK(3,13)
+#define M_SR_IMASK4	_MM_MAKEMASK(4,12)
+#define M_SR_IMASK3	_MM_MAKEMASK(5,11)
+#define M_SR_IMASK2	_MM_MAKEMASK(6,10)
+#define M_SR_IMASK1	_MM_MAKEMASK(7,9)
+#define M_SR_IMASK0	_MM_MAKEMASK(8,8)
+
+#define M_SR_KX		_MM_MAKEMASK1(7)	/* 64-bit access for kernel */
+#define M_SR_SX		_MM_MAKEMASK1(6)	/* .. for supervisor */
+#define M_SR_UX		_MM_MAKEMASK1(5)	/* .. for user */
+
+#define S_SR_KSU	3			/* base operating mode mode */
+#define M_SR_KSU	_MM_MAKEMASK(2,S_SR_KSU)
+#define V_SR_KSU(x)	_MM_MAKEVALUE(x,S_SR_KSU)
+#define G_SR_KSU(x)	_MM_GETVALUE(x,S_SR_KSU,M_SR_KSU)
+#define K_SR_KSU_KERNEL	0
+#define K_SR_KSU_SUPR	1
+#define K_SR_KSU_USER	2
+
+#define M_SR_UM		_MM_MAKEMASK1(4)
+#define M_SR_ERL	_MM_MAKEMASK1(2)
+#define M_SR_EXL	_MM_MAKEMASK1(1)
+#define M_SR_IE		_MM_MAKEMASK1(0)
+
+/* 
+ * Cause Register 
+ */
+#define M_CAUSE_BD	_MM_MAKEMASK1(31) /* exception in BD slot */
+
+#define S_CAUSE_CE	28		/* coprocessor error */
+#define M_CAUSE_CE	_MM_MAKEMASK(2,S_CAUSE_CE)
+#define V_CAUSE_CE(x)	_MM_MAKEVALUE(x,S_CAUSE_CE)
+#define G_CAUSE_CE(x)	_MM_GETVALUE(x,S_CAUSE_CE,M_CAUSE_CE)
+
+#define M_CAUSE_IV	_MM_MAKEMASK1(23) /* special interrupt */
+#define M_CAUSE_WP      _MM_MAKEMASK1(22) /* watch interrupt deferred */
+
+#define S_CAUSE_IPMASK	8
+#define M_CAUSE_IPMASK	_MM_MAKEMASK(8,S_CAUSE_IPMASK)
+#define M_CAUSE_IP8	_MM_MAKEMASK1(15)	/* hardware interrupts */
+#define M_CAUSE_IP7	_MM_MAKEMASK1(14)
+#define M_CAUSE_IP6	_MM_MAKEMASK1(13)
+#define M_CAUSE_IP5	_MM_MAKEMASK1(12)
+#define M_CAUSE_IP4	_MM_MAKEMASK1(11)
+#define M_CAUSE_IP3	_MM_MAKEMASK1(10)
+#define M_CAUSE_SW2	_MM_MAKEMASK1(9)	/* software interrupts */
+#define M_CAUSE_SW1	_MM_MAKEMASK1(8)
+
+#define S_CAUSE_EXC	2
+#define M_CAUSE_EXC	_MM_MAKEMASK(5,S_CAUSE_EXC)
+#define V_CAUSE_EXC(x)	_MM_MAKEVALUE(x,S_CAUSE_EXC)
+#define G_CAUSE_EXC(x)	_MM_GETVALUE(x,S_CAUSE_EXC,M_CAUSE_EXC)
+
+/* Exception Code */
+#define K_CAUSE_EXC_INT		0	/* External interrupt */
+#define K_CAUSE_EXC_MOD		1	/* TLB modification */
+#define K_CAUSE_EXC_TLBL	2    	/* TLB miss (Load or Ifetch) */
+#define K_CAUSE_EXC_TLBS	3	/* TLB miss (Save) */
+#define K_CAUSE_EXC_ADEL	4    	/* Address error (Load or Ifetch) */
+#define K_CAUSE_EXC_ADES	5	/* Address error (Save) */
+#define K_CAUSE_EXC_IBE		6	/* Bus error (Ifetch) */
+#define K_CAUSE_EXC_DBE		7	/* Bus error (data load or store) */
+#define K_CAUSE_EXC_SYS		8	/* System call */
+#define K_CAUSE_EXC_BP		9	/* Break point */
+#define K_CAUSE_EXC_RI		10	/* Reserved instruction */
+#define K_CAUSE_EXC_CPU		11	/* Coprocessor unusable */
+#define K_CAUSE_EXC_OVF		12	/* Arithmetic overflow */
+#define K_CAUSE_EXC_TRAP	13	/* Trap exception */
+#define K_CAUSE_EXC_VCEI	14	/* Virtual Coherency Exception (I) */
+#define K_CAUSE_EXC_FPE		15	/* Floating Point Exception */
+#define K_CAUSE_EXC_CP2		16	/* Cp2 Exception */
+#define K_CAUSE_EXC_WATCH	23	/* Watchpoint exception */
+#define K_CAUSE_EXC_VCED	31	/* Virtual Coherency Exception (D) */
+
+#define	K_NTLBENTRIES	64
+
+#define HI_HALF(x)	((x) >> 16)
+#define LO_HALF(x)	((x) & 0xffff)
+
+/* FPU stuff */
+
+#if defined(__ASSEMBLY__)
+#define C1_CSR		$31
+#define C1_FRID		$0
+#else
+#define C1_CSR		31
+#define C1_FRID		0
+#endif
+
+#define S_FCSR_CAUSE	12
+#define M_FCSR_CAUSE	_MM_MAKEMASK(5,S_FCSR_CAUSE)
+#define V_FCSR_CAUSE(x)	_MM_MAKEVALUE(x,S_FCSR_CAUSE)
+#define G_FCSR_CAUSE(x)	_MM_GETVALUE(x,S_FCSR_CAUSE,M_FCSR_CAUSE)
+
+#define S_FCSR_ENABLES	7
+#define M_FCSR_ENABLES	_MM_MAKEMASK(5,S_FCSR_ENABLES)
+#define V_FCSR_ENABLES(x) _MM_MAKEVALUE(x,S_FCSR_ENABLES)
+#define G_FCSR_ENABLES(x) _MM_GETVALUE(x,S_FCSR_ENABLES,M_FCSR_ENABLES)
+
+#define S_FCSR_FLAGS	2
+#define M_FCSR_FLAGS	_MM_MAKEMASK(5,S_FCSR_FLAGS)
+#define V_FCSR_FLAGS(x)	_MM_MAKEVALUE(x,S_FCSR_FLAGS)
+#define G_FCSR_FLAGS(x)	_MM_GETVALUE(x,S_FCSR_FLAGS,M_FCSR_FLAGS)
+
+
+/*
+ * MIPS64 Config Register (select 0)
+ */
+#define M_CFG_CFG1	_MM_MAKEMASK1(31)	/* config1 select1 is impl */
+#define M_CFG_BE        _MM_MAKEMASK1(15)	/* big-endian mode */
+
+#define S_CFG_AT	13			/* Architecture Type */
+#define M_CFG_AT	_MM_MAKEMASK(2,S_CFG_AT)
+#define V_CFG_AT(x)	_MM_MAKEVALUE(x,S_CFG_AT)
+#define G_CFG_AT(x)	_MM_GETVALUE(x,S_CFG_AT,M_CFG_AT)
+#define K_CFG_AT_MIPS32	0
+#define K_CFG_AT_MIPS64_32 1
+#define K_CFG_AT_MIPS64	2
+
+#define S_CFG_AR	10			/* Architecture Revision */
+#define M_CFG_AR        _MM_MAKEMASK(3,S_CFG_AR)
+#define V_CFG_AR(x)	_MM_MAKEVALUE(x,S_CFG_AR)
+#define G_CFG_AR(x)	_MM_GETVALUE(x,S_CFG_AR,M_CFG_AR)
+#define K_CFG_AR_REV1	0
+
+#define S_CFG_MMU	7			/* MMU Type */
+#define M_CFG_MMU       _MM_MAKEMASK(3,S_CFG_MMU)
+#define V_CFG_MMU(x)	_MM_MAKEVALUE(x,S_CFG_MMU)
+#define G_CFG_MMU(x)	_MM_GETVALUE(x,S_CFG_MMU,M_CFG_MMU)
+#define K_CFG_MMU_NONE	0
+#define K_CFG_MMU_TLB	1
+#define K_CFG_MMU_BAT	2
+#define K_CFG_MMU_FIXED	3
+
+#define S_CFG_K0COH	0			/* K0seg coherency */
+#define M_CFG_K0COH	_MM_MAKEMASK(3,S_CFG_K0COH)
+#define V_CFG_K0COH(x)	_MM_MAKEVALUE(x,S_CFG_K0COH)
+#define G_CFG_K0COH(x)	_MM_GETVALUE(x,S_CFG_K0COH,M_CFG_K0COH)
+#define K_CFG_K0COH_UNCACHED	2
+#define K_CFG_K0COH_CACHEABLE	3
+#define K_CFG_K0COH_COHERENT	5
+
+/*
+ * MIPS64 Config Register (select 1)
+ */
+
+#define M_CFG_CFG2	_MM_MAKEMASK1(31)	/* config2 select2 is impl */
+
+#define S_CFG_MMUSIZE	25
+#define M_CFG_MMUSIZE	_MM_MAKEMASK(6,S_CFG_MMUSIZE)
+
+#define S_CFG_IS	22
+#define M_CFG_IS	_MM_MAKEMASK(3,S_CFG_IS)
+#define V_CFG_IS(x)	_MM_MAKEVALUE(x,S_CFG_IS)
+#define G_CFG_IS(x)	_MM_GETVALUE(x,S_CFG_IS,M_CFG_IS)
+
+#define S_CFG_IL	19
+#define M_CFG_IL	_MM_MAKEMASK(S_CFG_IL,3)
+#define V_CFG_IL(x)	_MM_MAKEVALUE(x,S_CFG_IL)
+#define G_CFG_IL(x)	_MM_GETVALUE(x,S_CFG_IL,M_CFG_IL)
+
+#define S_CFG_IA	16
+#define M_CFG_IA	_MM_MAKEMASK(3,S_CFG_IA)
+#define V_CFG_IA(x)	_MM_MAKEVALUE(x,S_CFG_IA)
+#define G_CFG_IA(x)	_MM_GETVALUE(x,S_CFG_IA,M_CFG_IA)
+
+#define S_CFG_DS	13
+#define M_CFG_DS	_MM_MAKEMASK(3,S_CFG_DS)
+#define V_CFG_DS(x)	_MM_MAKEVALUE(x,S_CFG_DS)
+#define G_CFG_DS(x)	_MM_GETVALUE(x,S_CFG_DS,M_CFG_DS)
+
+#define S_CFG_DL	10
+#define M_CFG_DL	_MM_MAKEMASK(3,S_CFG_DL)
+#define V_CFG_DL(x)	_MM_MAKEVALUE(x,S_CFG_DL)
+#define G_CFG_DL(x)	_MM_GETVALUE(x,S_CFG_DL,M_CFG_DL)
+
+#define S_CFG_DA	7
+#define M_CFG_DA	_MM_MAKEMASK(3,S_CFG_DA)
+#define V_CFG_DA(x)	_MM_MAKEVALUE(x,S_CFG_DA)
+#define G_CFG_DA(x)	_MM_GETVALUE(x,S_CFG_DA,M_CFG_DA)
+
+#define M_CFG_PC	_MM_MAKEMASK1(4)	/* perf ctrs present */
+#define M_CFG_WR	_MM_MAKEMASK1(3)	/* watch regs present */
+#define M_CFG_CA	_MM_MAKEMASK1(2)	/* MIPS16 present */
+#define M_CFG_EP	_MM_MAKEMASK1(1)	/* EJTAG present */
+#define M_CFG_FP	_MM_MAKEMASK1(0)	/* FPU present */
+
+
+
+/* 
+ * Primary Cache TagLo 
+ */
+
+#define S_TAGLO_PTAG	8
+#define M_TAGLO_PTAG 	_MM_MAKEMASK(56,S_TAGLO_PTAG)
+
+#define S_TAGLO_PSTATE	6
+#define M_TAGLO_PSTATE	_MM_MAKEMASK(2,S_TAGLO_PSTATE)
+#define V_TAGLO_PSTATE(x) _MM_MAKEVALUE(x,S_TAGLO_PSTATE)
+#define G_TAGLO_PSTATE(x) _MM_GETVALUE(x,S_TAGLO_PSTATE,M_TAGLO_PSTATE)
+#define K_TAGLO_PSTATE_INVAL		0
+#define K_TAGLO_PSTATE_SHARED		1
+#define K_TAGLO_PSTATE_CLEAN_EXCL	2
+#define K_TAGLO_PSTATE_DIRTY_EXCL	3
+
+#define M_TAGLO_LOCK	_MM_MAKEMASK1(5)
+#define M_TAGLO_PARITY	_MM_MAKEMASK1(0)
+
+
+/*
+ * CP0 CacheErr register
+ */
+#define M_CERR_DATA	_MM_MAKEMASK1(31)	/* err in D space */
+#define M_CERR_SCACHE	_MM_MAKEMASK1(30)	/* err in l2, not l1 */
+#define M_CERR_DERR	_MM_MAKEMASK1(29)	/* data error */
+#define M_CERR_TERR	_MM_MAKEMASK1(28)	/* tag error */
+#define M_CERR_EXTRQ	_MM_MAKEMASK1(27)	/* external req caused err */
+#define M_CERR_BPAR	_MM_MAKEMASK1(26)	/* bus parity err */
+#define M_CERR_ADATA	_MM_MAKEMASK1(25)	/* additional data */
+#define M_CERR_IDX	_MM_MAKEMASK(22,0)
+
+
+
+/*
+ * Primary Cache operations
+ */
+#define Index_Invalidate_I               0x0         /* 0       0 */
+#define Index_Writeback_Inv_D            0x1         /* 0       1 */
+#define Index_Invalidate_SI              0x2         /* 0       2 */
+#define Index_Writeback_Inv_SD           0x3         /* 0       3 */
+#define Index_Load_Tag_I                 0x4         /* 1       0 */
+#define Index_Load_Tag_D                 0x5         /* 1       1 */
+#define Index_Load_Tag_SI                0x6         /* 1       2 */
+#define Index_Load_Tag_SD                0x7         /* 1       3 */
+#define Index_Store_Tag_I                0x8         /* 2       0 */
+#define Index_Store_Tag_D                0x9         /* 2       1 */
+#define Index_Store_Tag_SI               0xA         /* 2       2 */
+#define Index_Store_Tag_SD               0xB         /* 2       3 */
+#define Create_Dirty_Exc_D               0xD         /* 3       1 */
+#define Create_Dirty_Exc_SD              0xF         /* 3       3 */
+#define Hit_Invalidate_I                 0x10        /* 4       0 */
+#define Hit_Invalidate_D                 0x11        /* 4       1 */
+#define Hit_Invalidate_SI                0x12        /* 4       2 */
+#define Hit_Invalidate_SD                0x13        /* 4       3 */
+#define Fill_I                           0x14        /* 5       0 */
+#define Hit_Writeback_Inv_D              0x15        /* 5       1 */
+#define Hit_Writeback_Inv_SD             0x17        /* 5       3 */
+#define Hit_Writeback_I                  0x18        /* 6       0 */
+#define Hit_Writeback_D                  0x19        /* 6       1 */
+#define Hit_Writeback_SD                 0x1B        /* 6       3 */
+#define Hit_Set_Virtual_SI               0x1E        /* 7       2 */
+#define Hit_Set_Virtual_SD               0x1F        /* 7       3 */
+
+/* Watchpoint Register */
+#define M_WATCH_PA		0xfffffff8
+#define M_WATCH_R		0x00000002
+#define M_WATCH_W		0x00000001
+
+
+/* TLB entries */
+#define M_TLBHI_ASID		_MM_MAKEMASK(0,8)
+#define M_TLBHI_VPN2		_MM_MAKEMASK(27,13)
+
+#define M_TLBLO_G		_MM_MAKEMASK1(0)
+#define M_TLBLO_V		_MM_MAKEMASK1(1)
+#define M_TLBLO_D		_MM_MAKEMASK1(2)
+
+#define S_TLBLO_CALG		3
+#define M_TLBLO_CALG		_MM_MAKEMASK(3,S_TLBLO_CALG)
+#define V_TLBLO_CALG(x) 	_MM_MAKEVALUE(x,S_TLBLO_CALG)
+#define G_TLBLO_CALG(x) 	_MM_GETVALUE(x,S_TLBLO_CALG,M_TLBLO_CALG)
+
+#define K_CALG_COH_EXCL1_NOL2	0
+#define K_CALG_COH_SHRL1_NOL2	1
+#define K_CALG_UNCACHED		2
+#define K_CALG_NONCOHERENT	3
+#define K_CALG_COH_EXCL		4
+#define K_CALG_COH_SHAREABLE	5
+#define K_CALG_NOTUSED		6
+#define K_CALG_UNCACHED_ACCEL	7
+
+#define S_TLBLO_PFNMASK		6
+#define M_TLBLO_PFNMASK		_MM_MAKEMASK(24,S_TLBLO_PFNMASK)
+#define V_TLBLO_PFNMASK(x) 	_MM_MAKEVALUE(x,S_TLBLO_PFNMASK)
+#define G_TLBLO_PFNMASK(x) 	_MM_GETVALUE(x,S_TLBLO_PFNMASK,M_TLBLO_PFNMASK)
+
+
+
+#endif /* _SB_MIPS_H */
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/swarm.h linux/include/asm-mips64/sibyte/swarm.h
--- linux.orig/include/asm-mips64/sibyte/swarm.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/swarm.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+#ifndef _ASM_SIBYTE_SWARM_H
+#define _ASM_SIBYTE_SWARM_H
+
+#define KERNEL_RESERVED_MEM 0x100000
+#define LED_BASE_ADDR 0x100a0020
+
+void swarm_setup(void);
+void setleds(char *str); 
+
+#endif /* _ASM_SIBYTE_SWARM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sibyte/swarm_ide.h linux/include/asm-mips64/sibyte/swarm_ide.h
--- linux.orig/include/asm-mips64/sibyte/swarm_ide.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/sibyte/swarm_ide.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2001 Broadcom 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.
+ */
+
+#ifndef _SWARM_IDE_H
+#define _SWARM_IDE_H
+
+#include <asm/sibyte/sb1250_int.h>
+
+#define SWARM_IDE_BASE        (0xb00b0000-mips_io_port_base)
+#define SWARM_IDE_REG(pcaddr) (SWARM_IDE_BASE + ((pcaddr)<<5))
+#define SWARM_IDE_INT         (K_INT_GPIO_4)
+
+extern ide_ideproc_t swarm_ideproc;
+
+#define swarm_outb(val,port)							\
+do {									\
+	*(volatile u8 *)(mips_io_port_base + (port)) = val;	\
+} while(0)
+
+#define swarm_outw(val,port)							\
+do {									\
+	*(volatile u16 *)(mips_io_port_base + (port)) = val;	\
+} while(0)
+
+#define swarm_outl(val,port)							\
+do {									\
+	*(volatile u32 *)(mips_io_port_base + (port)) = val;\
+} while(0)
+
+static inline unsigned char swarm_inb(unsigned long port)
+{
+	return (*(volatile u8 *)(mips_io_port_base + port));
+}
+
+static inline unsigned short swarm_inw(unsigned long port)
+{
+	return (*(volatile u16 *)(mips_io_port_base + port));
+}
+
+static inline unsigned int swarm_inl(unsigned long port)
+{
+	return (*(volatile u32 *)(mips_io_port_base + port));
+}
+
+
+static inline void swarm_outsb(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		swarm_outb(*(u8 *)addr, port);
+		addr++;
+	}
+}
+
+static inline void swarm_insb(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u8 *)addr = swarm_inb(port);
+		addr++;
+	}
+}
+
+static inline void swarm_outsw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		swarm_outw(*(u16 *)addr, port);
+		addr += 2;
+	}
+}
+
+static inline void swarm_insw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u16 *)addr = swarm_inw(port);
+		addr += 2;
+	}
+}
+
+static inline void swarm_outsl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		swarm_outl(*(u32 *)addr, port);
+		addr += 4;
+	}
+}
+
+static inline void swarm_insl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u32 *)addr = swarm_inl(port);
+		addr += 4;
+	}
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/siginfo.h linux/include/asm-mips64/siginfo.h
--- linux.orig/include/asm-mips64/siginfo.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/siginfo.h	2002-07-20 01:08:30.000000000 +0000
@@ -127,6 +127,7 @@
 #define SI_TIMER __SI_CODE(__SI_TIMER,-3) /* sent by timer expiration */
 #define SI_MESGQ	-4	/* sent by real time mesq state change */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
+#define SI_TKILL	-6	/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
@@ -238,7 +239,7 @@
 #ifdef __KERNEL__
 #include <linux/string.h>
 
-extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+static inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
 {
 	if (from->si_code < 0)
 		memcpy(to, from, sizeof(siginfo_t));
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/smp.h linux/include/asm-mips64/smp.h
--- linux.orig/include/asm-mips64/smp.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/smp.h	2002-07-20 01:08:31.000000000 +0000
@@ -6,7 +6,6 @@
  * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
  * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
  */
-
 #ifndef __ASM_SMP_H
 #define __ASM_SMP_H
 
@@ -17,23 +16,6 @@
 #include <linux/threads.h>
 #include <linux/irq.h>
 
-#if 0
-struct cpuinfo_mips {				/* XXX  */
-	unsigned long loops_per_sec;
-	unsigned long last_asn;
-	unsigned long *pgd_cache;
-	unsigned long *pte_cache;
-	unsigned long pgtable_cache_sz;
-	unsigned long ipi_count;
-	unsigned long irq_attempt[NR_IRQS];
-	unsigned long smp_local_irq_count;
-	unsigned long prof_multiplier;
-	unsigned long prof_counter;
-} __attribute__((aligned(64)));
-
-extern struct cpuinfo_mips cpu_data[NR_CPUS];
-#endif
-
 #define smp_processor_id()	(current->processor)
 
 #define PROC_CHANGE_PENALTY	20
@@ -51,12 +33,15 @@
 
 #define NO_PROC_ID	(-1)
 
+#define SMP_RESCHEDULE_YOURSELF	0x1	/* XXX braindead */
+#define SMP_CALL_FUNCTION	0x2
+
 #if (NR_CPUS <= _MIPS_SZLONG)
 
 typedef unsigned long   cpumask_t;
 
 #define CPUMASK_CLRALL(p)	(p) = 0
-#define CPUMASK_SETB(p, bit)	(p) |= 1 << (bit)
+#define CPUMASK_SETB(p, bit)	(p) |= 1UL << (bit)
 #define CPUMASK_CLRB(p, bit)	(p) &= ~(1ULL << (bit))
 #define CPUMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
 
@@ -85,4 +70,16 @@
 #error cpumask macros only defined for 128p kernels
 #endif
 
+struct call_data_struct {
+	void		(*func)(void *);
+	void		*info;
+	atomic_t	started;
+	atomic_t	finished;
+	int		wait;
+};
+
+extern struct call_data_struct *call_data;
+
+extern cpumask_t cpu_online_map;
+
 #endif /* __ASM_SMP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/addrs.h linux/include/asm-mips64/sn/addrs.h
--- linux.orig/include/asm-mips64/sn/addrs.h	2000-07-12 22:15:10.000000000 +0000
+++ linux/include/asm-mips64/sn/addrs.h	2002-07-20 01:08:21.000000000 +0000
@@ -11,9 +11,9 @@
 
 #include <linux/config.h>
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 #include <linux/types.h>
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #include <asm/addrspace.h>
 #include <asm/reg.h>
@@ -26,7 +26,7 @@
 #endif
 
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #if defined(CONFIG_SGI_IO)	/* FIXME */
 #define PS_UINT_CAST		(__psunsigned_t)
@@ -38,13 +38,13 @@
 
 #define HUBREG_CAST		(volatile hubreg_t *)
 
-#elif _LANGUAGE_ASSEMBLY
+#else /* __ASSEMBLY__ */
 
 #define PS_UINT_CAST
 #define UINT64_CAST
 #define HUBREG_CAST
 
-#endif
+#endif /* __ASSEMBLY__ */
 
 
 #define NASID_GET_META(_n)	((_n) >> NASID_LOCAL_BITS)
@@ -278,7 +278,7 @@
 					      0x800000 + (_x)))
 #endif /* CONFIG_SGI_IP27 */
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define HUB_L(_a)			*(_a)
 #define	HUB_S(_a, _d)			*(_a) = (_d)
@@ -290,7 +290,7 @@
 #define REMOTE_HUB_PI_L(_n, _sn, _r)	HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
 #define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /*
  * The following macros are used to get to a hub/bridge register, given
@@ -367,7 +367,7 @@
 #define	KLI_KERN_XP		8
 #define	KLI_KERN_PARTID		9
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define KLD_BASE(nasid)		((kldir_ent_t *) KLDIR_ADDR(nasid))
 #define KLD_LAUNCH(nasid)	(KLD_BASE(nasid) + KLI_LAUNCH)
@@ -453,7 +453,7 @@
 
 #define GPDA_ADDR(nasid)	TO_NODE_CAC(nasid, GPDA_OFFSET)
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 
 #endif /* _ASM_SN_ADDRS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/arch.h linux/include/asm-mips64/sn/arch.h
--- linux.orig/include/asm-mips64/sn/arch.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/arch.h	2002-07-20 01:08:28.000000000 +0000
@@ -20,7 +20,7 @@
 #endif
 
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+#ifndef __ASSEMBLY__
 #if !defined(CONFIG_SGI_IO)
 typedef u64	hubreg_t;
 typedef u64	nic_t;
@@ -44,7 +44,7 @@
 #define makespnum(_nasid, _slice)					\
 		(((_nasid) << CPUS_PER_NODE_SHFT) | (_slice))
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+#ifndef __ASSEMBLY__
 
 #define INVALID_NASID		(nasid_t)-1
 #define INVALID_CNODEID		(cnodeid_t)-1
@@ -102,7 +102,7 @@
 
 extern int node_getlastslot(cnodeid_t);
 
-#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
+#endif /* !__ASSEMBLY__ */
 
 #define SLOT_BITMASK    	(MAX_MEM_SLOTS - 1)
 #define SLOT_SIZE		(1LL<<SLOT_SHIFT)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/gda.h linux/include/asm-mips64/sn/gda.h
--- linux.orig/include/asm-mips64/sn/gda.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/gda.h	2002-07-20 01:08:32.000000000 +0000
@@ -41,7 +41,7 @@
 #define G_PARTIDOFF	40
 #define G_TABLEOFF	128
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef struct gda {
 	u32	g_magic;	/* GDA magic number */
@@ -67,7 +67,7 @@
 
 #define GDA ((gda_t*) GDA_ADDR(get_nasid()))
 
-#endif /* __LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 /*
  * Define:	PART_GDA_VERSION
  * Purpose:	Define the minimum version of the GDA required, lower 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/intr.h linux/include/asm-mips64/sn/intr.h
--- linux.orig/include/asm-mips64/sn/intr.h	2000-05-15 19:55:26.000000000 +0000
+++ linux/include/asm-mips64/sn/intr.h	2002-07-20 01:08:21.000000000 +0000
@@ -19,7 +19,7 @@
 
 #include <asm/sn/intr_public.h>
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 /*
  * Macros to manipulate the interrupt register on the calling hub chip.
@@ -43,9 +43,9 @@
 		REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (_level)),	\
                 REMOTE_HUB_L((_hub), PI_INT_PEND0)
 
-#else /* LANGUAGE_ASSEMBLY */
+#else /* __ASSEMBLY__ */
 
-#endif /* LANGUAGE_C */
+#endif /* __ASSEMBLY__ */
 
 /*
  * Hard-coded interrupt levels:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/intr_public.h linux/include/asm-mips64/sn/intr_public.h
--- linux.orig/include/asm-mips64/sn/intr_public.h	2000-05-15 19:55:26.000000000 +0000
+++ linux/include/asm-mips64/sn/intr_public.h	2002-07-20 01:08:32.000000000 +0000
@@ -20,7 +20,7 @@
 #define INTPEND0_MAXMASK	(N_INTPEND0_MASKS - 1)
 #define INTPEND1_MAXMASK	(N_INTPEND1_MASKS - 1)
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 #include <asm/sn/arch.h>
 
 struct intr_vecblk_s;	/* defined in asm/sn/intr.h */
@@ -49,5 +49,5 @@
 	struct intr_vecblk_s	*dispatch1;
 } hub_intmasks_t;
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 #endif /* __ASM_SN_INTR_PUBLIC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/kldir.h linux/include/asm-mips64/sn/kldir.h
--- linux.orig/include/asm-mips64/sn/kldir.h	2000-07-12 22:15:10.000000000 +0000
+++ linux/include/asm-mips64/sn/kldir.h	2002-07-20 01:08:34.000000000 +0000
@@ -127,14 +127,14 @@
  * 0x0   (0K)              +-----------------------------------------+
  */
 
-#ifdef LANGUAGE_ASSEMBLY
+#ifdef __ASSEMBLY__
 #define KLDIR_OFF_MAGIC			0x00
 #define KLDIR_OFF_OFFSET		0x08
 #define KLDIR_OFF_POINTER		0x10
 #define KLDIR_OFF_SIZE			0x18
 #define KLDIR_OFF_COUNT			0x20
 #define KLDIR_OFF_STRIDE		0x28
-#endif /* LANGUAGE_ASSEMBLY */
+#endif /* __ASSEMBLY__ */
 
 #if !defined(CONFIG_SGI_IO)
 
@@ -209,7 +209,7 @@
 
 #endif	/* !CONFIG_SGI_IO */
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef struct kldir_ent_s {
 	u64		magic;		/* Indicates validity of entry      */
 	off_t		offset;		/* Offset from start of node space  */
@@ -225,7 +225,7 @@
 	/* NOTE: These 16 bytes are used in the Partition KLDIR
 	   entry to store partition info. Refer to klpart.h for this. */
 } kldir_ent_t;
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #if defined(CONFIG_SGI_IO)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/klkernvars.h linux/include/asm-mips64/sn/klkernvars.h
--- linux.orig/include/asm-mips64/sn/klkernvars.h	2000-07-10 05:18:15.000000000 +0000
+++ linux/include/asm-mips64/sn/klkernvars.h	2002-07-20 01:08:36.000000000 +0000
@@ -11,7 +11,7 @@
 
 #define KV_MAGIC		0x5f4b565f
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #include <asm/sn/types.h>
 
@@ -23,7 +23,7 @@
 	unsigned long	kv_rw_baseaddr;
 } kern_vars_t;
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_SN_KLKERNVARS_H */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/launch.h linux/include/asm-mips64/sn/launch.h
--- linux.orig/include/asm-mips64/sn/launch.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/launch.h	2002-07-20 01:08:33.000000000 +0000
@@ -60,7 +60,7 @@
  * clears the BUSY flag after control is returned to it.
  */
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef int launch_state_t;
 typedef void (*launch_proc_t)(u64 call_parm);
@@ -117,6 +117,6 @@
 
 #endif /* _STANDALONE */
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_SN_LAUNCH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/nmi.h linux/include/asm-mips64/sn/nmi.h
--- linux.orig/include/asm-mips64/sn/nmi.h	2000-07-10 05:18:15.000000000 +0000
+++ linux/include/asm-mips64/sn/nmi.h	2002-07-20 01:08:37.000000000 +0000
@@ -8,7 +8,7 @@
 #ifndef __ASM_SN_NMI_H
 #define __ASM_SN_NMI_H
 
-#ident "$Revision: 1.2 $"
+#ident "$Revision: 1.2.4.1 $"
 
 #include <asm/sn/addrs.h>
 
@@ -48,7 +48,7 @@
  *
  */
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef struct nmi_s {
 	volatile unsigned long	 magic;		/* Magic number */
@@ -59,13 +59,13 @@
 	volatile unsigned long	 gmaster;	/* Flag true only on global master*/
 } nmi_t;
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /* Following definitions are needed both in the prom & the kernel
  * to identify the format of the nmi cpu register save area in the
  * low memory on each node.
  */
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 struct reg_struct {
 	unsigned long	gpr[32];
@@ -78,7 +78,7 @@
 	unsigned long	nmi_sr;
 };
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /* These are the assembly language offsets into the reg_struct structure */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/sn0/addrs.h linux/include/asm-mips64/sn/sn0/addrs.h
--- linux.orig/include/asm-mips64/sn/sn0/addrs.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/sn0/addrs.h	2002-07-20 01:08:23.000000000 +0000
@@ -99,14 +99,14 @@
 #define NASID_GET(_pa)		(int) ((UINT64_CAST (_pa) >>		\
 					NASID_SHFT) & NASID_BITMASK)
 
-#if _LANGUAGE_C && !defined(_STANDALONE)
+#if !defined(__ASSEMBLY__) && !defined(_STANDALONE)
 #define NODE_SWIN_BASE(nasid, widget)					\
 	((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN)		\
 	: RAW_NODE_SWIN_BASE(nasid, widget))
-#else
+#else /* __ASSEMBLY__ || _STANDALONE */
 #define NODE_SWIN_BASE(nasid, widget) \
      (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
-#endif /* _LANGUAGE_C */
+#endif /* __ASSEMBLY__ || _STANDALONE */
 
 /*
  * The following definitions pertain to the IO special address
@@ -163,11 +163,11 @@
 #define SABLE_LOG_TRIGGER(_map)
 #endif /* SABLE */
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 #define KERN_NMI_ADDR(nasid, slice)					\
                     TO_NODE_UNCAC((nasid), IP27_NMI_KREGS_OFFSET + 	\
 				  (IP27_NMI_KREGS_CPU_SIZE * (slice)))
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #ifdef PROM
 
@@ -272,7 +272,7 @@
 #define KL_UART_DATA	LOCAL_HUB_ADDR(MD_UREG0_1)	/* UART data reg */
 #define KL_I2C_REG	MD_UREG0_0			/* I2C reg */
 
-#if !_LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 /* Address 0x400 to 0x1000 ualias points to cache error eframe + misc
  * CACHE_ERR_SP_PTR could either contain an address to the stack, or
  * the stack could start at CACHE_ERR_SP_PTR
@@ -289,7 +289,7 @@
 #define CACHE_ERR_SP		(CACHE_ERR_SP_PTR - 16)
 #define CACHE_ERR_AREA_SIZE	(ARCS_SPB_OFFSET - CACHE_ERR_EFRAME)
 
-#endif	/* !_LANGUAGE_ASSEMBLY */
+#endif	/* !__ASSEMBLY__ */
 
 #define _ARCSPROM
 
@@ -314,7 +314,7 @@
  * is in place.
  */
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define uchar unsigned char
 
@@ -359,7 +359,7 @@
 #define PUT_INSTALL_STATUS(c,s)		c->Revision = s
 #define GET_INSTALL_STATUS(c)		c->Revision
 
-#endif /* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _STANDALONE */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/sn0/hubio.h linux/include/asm-mips64/sn/sn0/hubio.h
--- linux.orig/include/asm-mips64/sn/sn0/hubio.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/sn0/hubio.h	2002-07-20 01:08:25.000000000 +0000
@@ -169,7 +169,7 @@
 /*
  * The IO LLP control status register and widget control register
  */
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef union hubii_wid_u {
 	u64	wid_reg_value;
@@ -292,7 +292,7 @@
 	} perf_cnt_bits;
 } io_perf_cnt_t;
 
-#endif
+#endif /* !__ASSEMBLY__ */
 
 
 #define LNK_STAT_WORKING	0x2
@@ -440,7 +440,7 @@
 /*
  * Fields in CRB Register A
  */
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef union icrba_u {
 	u64	reg_value;
 	struct {
@@ -500,7 +500,7 @@
 #define	a_valid		icrba_fields_s.valid
 #define	a_iow		icrba_fields_s.iow
 
-#endif /* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #define	IIO_ICRB_ADDR_SHFT	2	/* Shift to get proper address */
 
@@ -523,7 +523,7 @@
 /*
  * Fields in CRB Register B
  */
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef union icrbb_u {
 	u64	reg_value;
 	struct {
@@ -622,7 +622,7 @@
 #define	b_imsg		icrbb_field_s.imsg
 #define	b_initiator	icrbb_field_s.initiator
 
-#endif /* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /*
  * values for field xtsize
@@ -680,7 +680,7 @@
  * Fields in CRB Register C 
  */
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef union icrbc_s {
 	u64	reg_value;
@@ -712,13 +712,13 @@
 #define	c_barrop	icrbc_field_s.barrop
 #define	c_doresp	icrbc_field_s.doresp
 #define	c_gbr	icrbc_field_s.gbr
-#endif /* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /*
  * Fields in CRB Register D
  */
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef union icrbd_s {
 	u64	reg_value;
 	struct {
@@ -751,7 +751,7 @@
 	} hi_ifdr_fields;
 } hubii_ifdr_t;
 
-#endif /* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /*
  * Hardware designed names for the BTE control registers.
@@ -798,7 +798,7 @@
  * IO PIO Read Table Entry format 
  */
 
-#ifdef	_LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef union iprte_a {
 	u64	entry;
@@ -820,7 +820,7 @@
 #define	iprte_init	iprte_fields.initiator
 #define	iprte_addr	iprte_fields.addr
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #define	IPRTE_ADDRSHFT	3
 
@@ -828,7 +828,7 @@
  * Hub IIO PRB Register format.
  */
 
-#ifdef	_LANGUAGE_C
+#ifndef __ASSEMBLY__
 /*
  * Note: Fields bnakctr, anakctr, xtalkctrmode, ovflow fields are 
  * "Status" fields, and should only be used in case of clean up after errors.
@@ -860,7 +860,7 @@
 #define	iprb_anakctr	iprb_fields_s.anakctr
 #define	iprb_xtalkctr	iprb_fields_s.xtalkctr
 
-#endif	/* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /*
  * values for mode field in iprb_t.
@@ -875,7 +875,7 @@
 /*
  * IO CRB entry C_A to E_A : Partial (cache) CRBS
  */
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef union icrbp_a {
 	u64   ip_reg;	    /* the entire register value	*/
 	struct {
@@ -909,7 +909,7 @@
 	} ip_fmt;
 } icrbp_a_t;
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 /*
  * A couple of defines to go with the above structure.
@@ -917,7 +917,7 @@
 #define ICRBP_A_CERR_SHFT	54
 #define ICRBP_A_ERR_MASK	0x3ff
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef union hubii_idsr {
 	u64 iin_reg;
 	struct {
@@ -931,7 +931,7 @@
 	            level : 7;
 	} iin_fmt;
 } hubii_idsr_t;
-#endif /* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 	
 /* 
  * IO BTE Length/Status (IIO_IBLS) register bit field definitions
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/sn0/hubmd.h linux/include/asm-mips64/sn/sn0/hubmd.h
--- linux.orig/include/asm-mips64/sn/sn0/hubmd.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/sn0/hubmd.h	2002-07-20 01:08:33.000000000 +0000
@@ -424,7 +424,7 @@
  * Operations on page migration threshold register
  */
 
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 #ifndef _STANDALONE
 
 /*
@@ -739,7 +739,7 @@
 } md_perf_cnt_t;
 
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 
 #define DIR_ERROR_VALID_MASK	0xe000000000000000
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/sn0/hubni.h linux/include/asm-mips64/sn/sn0/hubni.h
--- linux.orig/include/asm-mips64/sn/sn0/hubni.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/sn0/hubni.h	2002-07-20 01:08:24.000000000 +0000
@@ -11,7 +11,7 @@
 #ifndef _ASM_SGI_SN0_HUBNI_H
 #define _ASM_SGI_SN0_HUBNI_H
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 #include <linux/types.h>
 #endif
 
@@ -226,7 +226,7 @@
 
 #define NLT_EXIT_PORT_MASK (UINT64_CAST 0xf)
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 typedef union	hubni_port_error_u {
 	u64	nipe_reg_value;
@@ -250,6 +250,6 @@
 #define NI_LLP_CB_MAX		0xff
 #define NI_LLP_SN_MAX		0xff
 
-#endif /* LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_SGI_SN0_HUBNI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/sn0/hubpi.h linux/include/asm-mips64/sn/sn0/hubpi.h
--- linux.orig/include/asm-mips64/sn/sn0/hubpi.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/sn0/hubpi.h	2002-07-20 01:08:26.000000000 +0000
@@ -306,7 +306,7 @@
 #define ERR_STACK_SIZE_BYTES(_sz) \
        ((_sz) ? (PI_MIN_STACK_SIZE << ((_sz) - 1)) : 0)
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 /*
  * format of error stack and error status registers.
  */
@@ -359,7 +359,7 @@
 
 typedef u64	rtc_time_t;
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 
 /* Bits in PI_SYSAD_ERRCHK_EN */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/sn/sn0/ip27.h linux/include/asm-mips64/sn/sn0/ip27.h
--- linux.orig/include/asm-mips64/sn/sn0/ip27.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/sn/sn0/ip27.h	2002-07-20 01:08:24.000000000 +0000
@@ -19,7 +19,7 @@
 
 #define TLBLO_HWBITSHIFT	0		/* Shift value, for masking */
 
-#if !_LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 #define CAUSE_BERRINTR 		IE_IRQ5
 
@@ -30,9 +30,9 @@
 #define ECCF_PADDR      4
 #define ECCF_SIZE       (5 * sizeof(long))
 
-#endif /* !_LANGUAGE_ASSEMBLY */
+#endif /* !__ASSEMBLY__ */
 
-#if _LANGUAGE_ASSEMBLY
+#ifdef __ASSEMBLY__
 
 /*
  * KL_GET_CPUNUM (similar to EV_GET_SPNUM for EVEREST platform) reads
@@ -43,7 +43,7 @@
 	dli	proc, LOCAL_HUB(0); 			\
 	ld	proc, PI_CPU_NUM(proc)
 
-#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* __ASSEMBLY__ */
 
 /*
  * R10000 status register interrupt bit mask usage for IP27.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/softirq.h linux/include/asm-mips64/softirq.h
--- linux.orig/include/asm-mips64/softirq.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/softirq.h	2002-07-20 01:08:37.000000000 +0000
@@ -13,13 +13,13 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-extern inline void cpu_bh_disable(int cpu)
+static inline void cpu_bh_disable(int cpu)
 {
 	local_bh_count(cpu)++;
 	barrier();
 }
  
-extern inline void __cpu_bh_enable(int cpu)
+static inline void __cpu_bh_enable(int cpu)
 {
 	barrier();
 	local_bh_count(cpu)--;
@@ -39,19 +39,4 @@
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
-extern inline void __cpu_raise_softirq(int cpu, int nr)
-{
-	unsigned int *m = (unsigned int *) &softirq_pending(cpu);
-	unsigned int temp;
-
-	__asm__ __volatile__(
-		"1:\tll\t%0, %1\t\t\t# __cpu_raise_softirq\n\t"
-		"or\t%0, %2\n\t"
-		"sc\t%0, %1\n\t"
-		"beqz\t%0, 1b"
-		: "=&r" (temp), "=m" (*m)
-		: "ir" (1UL << nr), "m" (*m)
-		: "memory");
-}
-
 #endif /* _ASM_SOFTIRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/spinlock.h linux/include/asm-mips64/spinlock.h
--- linux.orig/include/asm-mips64/spinlock.h	2000-11-29 05:42:04.000000000 +0000
+++ linux/include/asm-mips64/spinlock.h	2002-07-20 01:08:34.000000000 +0000
@@ -19,10 +19,10 @@
 
 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
 
-#define spin_lock_init(x)	do { (x)->lock = 0; } while(0);
+#define spin_lock_init(x)	do { (x)->lock = 0; } while(0)
 
 #define spin_is_locked(x)	((x)->lock != 0)
-#define spin_unlock_wait(x)	({ do { barrier(); } while ((x)->lock); })
+#define spin_unlock_wait(x)	do { barrier(); } while ((x)->lock)
 
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
@@ -44,8 +44,8 @@
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
 	".set\treorder"
-	: "=o" (lock->lock), "=&r" (tmp)
-	: "o" (lock->lock)
+	: "=m" (lock->lock), "=&r" (tmp)
+	: "m" (lock->lock)
 	: "memory");
 }
 
@@ -56,8 +56,8 @@
 	"sync\n\t"
 	"sw\t$0, %0\n\t"
 	".set\treorder"	
-	: "=o" (lock->lock)
-	: "o" (lock->lock)
+	: "=m" (lock->lock)
+	: "m" (lock->lock)
 	: "memory");
 }
 
@@ -95,6 +95,8 @@
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
+#define rwlock_init(x)  do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+
 static inline void read_lock(rwlock_t *rw)
 {
 	unsigned int tmp;
@@ -108,8 +110,8 @@
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
 	".set\treorder"	
-	: "=o" (rw->lock), "=&r" (tmp)
-	: "o" (rw->lock)
+	: "=m" (rw->lock), "=&r" (tmp)
+	: "m" (rw->lock)
 	: "memory");
 }
 
@@ -126,10 +128,10 @@
 	"sub\t%1, 1\n\t"
 	"sc\t%1, %0\n\t"
 	"beqz\t%1, 1b\n\t"
-	"sync\n\t"
+	" sync\n\t"
 	".set\treorder"	
-	: "=o" (rw->lock), "=&r" (tmp)
-	: "o" (rw->lock)
+	: "=m" (rw->lock), "=&r" (tmp)
+	: "m" (rw->lock)
 	: "memory");
 }
 
@@ -146,8 +148,8 @@
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
 	".set\treorder"	
-	: "=o" (rw->lock), "=&r" (tmp)
-	: "o" (rw->lock)
+	: "=m" (rw->lock), "=&r" (tmp)
+	: "m" (rw->lock)
 	: "memory");
 }
 
@@ -158,8 +160,8 @@
 	"sync\n\t"
 	"sw\t$0, %0\n\t"
 	".set\treorder"	
-	: "=o" (rw->lock)
-	: "o" (rw->lock)
+	: "=m" (rw->lock)
+	: "m" (rw->lock)
 	: "memory");
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/stackframe.h linux/include/asm-mips64/stackframe.h
--- linux.orig/include/asm-mips64/stackframe.h	2000-05-13 15:31:25.000000000 +0000
+++ linux/include/asm-mips64/stackframe.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: stackframe.h,v 1.3 1999/12/04 03:59:12 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -18,7 +17,7 @@
 #include <asm/processor.h>
 #include <asm/addrspace.h>
 
-#ifdef _LANGUAGE_C
+#ifndef __ASSEMBLY__
 
 #define __str2(x) #x
 #define __str(x) __str2(x)
@@ -37,9 +36,9 @@
 		: /* No outputs */                       \
 		: "r" (frame))
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
-#ifdef _LANGUAGE_ASSEMBLY
+#ifdef __ASSEMBLY__
 
 		.macro	SAVE_AT
 		.set	push
@@ -76,6 +75,42 @@
 		sd	$30, PT_R30(sp)
 		.endm
 
+#ifdef CONFIG_SMP
+		.macro	get_saved_sp	/* R10000 variation */
+		mfc0	k0, CP0_WATCHLO
+		mfc0	k1, CP0_WATCHHI
+		dsll32	k0, k0, 0	/* Get rid of sign extension */
+		dsrl32	k0, k0, 0	/* Get rid of sign extension */
+		dsll32	k1, k1, 0
+		or	k1, k1, k0
+		li	k0, K0BASE
+		or	k1, k1, k0
+		.endm
+
+		.macro	set_saved_sp	stackp temp
+		mtc0	\stackp, CP0_WATCHLO
+		dsrl32	\temp, \stackp, 0
+		mtc0	\temp, CP0_WATCHHI
+		.endm
+
+		.macro	declare_saved_sp
+		# empty, stackpointer stored in a register
+		.endm
+#else
+		.macro	get_saved_sp	/* Uniprocessor variation */
+		lui	k1, %hi(kernelsp)
+		ld	k1, %lo(kernelsp)(k1)
+		.endm
+
+		.macro	set_saved_sp	stackp temp
+		sd	\stackp, kernelsp
+		.endm
+
+		.macro	declare_saved_sp
+		.comm	kernelsp, 8, 8			# current stackpointer
+		.endm
+#endif
+
 		.macro	SAVE_SOME
 		.set	push
 		.set	reorder
@@ -86,20 +121,7 @@
 		 move	k1, sp
 		.set	reorder
 		/* Called from user mode, new stack. */
-#ifndef CONFIG_SMP
-		lui	k1, %hi(kernelsp)
-		ld	k1, %lo(kernelsp)(k1)
-#else
-		mfc0	k0, CP0_WATCHLO
-		mfc0	k1, CP0_WATCHHI
-		dsll32	k0, k0, 0	/* Get rid of sign extension */
-		dsrl32	k0, k0, 0	/* Get rid of sign extension */
-		dsll32	k1, k1, 0
-		or	k1, k1, k0
-		li	k0, K0BASE
-		or	k1, k1, k0
-		daddiu	k1, k1, KERNEL_STACK_SIZE-32
-#endif
+		get_saved_sp
 8:		move	k0, sp
 		dsubu	sp, k1, PT_SIZE
 		sd	k0, PT_R29(sp)
@@ -242,6 +264,6 @@
 		mtc0	t0, CP0_STATUS
 		.endm
 
-#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_STACKFRAME_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/system.h linux/include/asm-mips64/system.h
--- linux.orig/include/asm-mips64/system.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/system.h	2002-07-20 01:08:34.000000000 +0000
@@ -11,25 +11,30 @@
 #define _ASM_SYSTEM_H
 
 #include <linux/config.h>
-
 #include <asm/sgidefs.h>
+#include <asm/ptrace.h>
 #include <linux/kernel.h>
 
+__asm__ (
+	".macro\t__sti\n\t"
+	".set\tpush\n\t"
+	".set\treorder\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t$1,$12\n\t"
+	"ori\t$1,0x1f\n\t"
+	"xori\t$1,0x1e\n\t"
+	"mtc0\t$1,$12\n\t"
+	".set\tpop\n\t"
+	".endm");
+
 extern __inline__ void
 __sti(void)
 {
 	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"mfc0\t$1,$12\n\t"
-		"ori\t$1,0x1f\n\t"
-		"xori\t$1,0x1e\n\t"
-		"mtc0\t$1,$12\n\t"
-		".set\tat\n\t"
-		".set\treorder"
+		"__sti"
 		: /* no outputs */
 		: /* no inputs */
-		: "$1", "memory");
+		: "memory");
 }
 
 /*
@@ -39,71 +44,93 @@
  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
  * no nops at all.
  */
+__asm__ (
+	".macro\t__cli\n\t"
+	".set\tpush\n\t"
+	".set\treorder\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t$1,$12\n\t"
+	"ori\t$1,1\n\t"
+	"xori\t$1,1\n\t"
+	".set\tnoreorder\n\t"
+	"mtc0\t$1,$12\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	".set\tpop\n\t"
+	".endm");
+
 extern __inline__ void
 __cli(void)
 {
 	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"mfc0\t$1,$12\n\t"
-		"ori\t$1,1\n\t"
-		"xori\t$1,1\n\t"
-		"mtc0\t$1,$12\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		".set\tat\n\t"
-		".set\treorder"
+		"__cli"
 		: /* no outputs */
 		: /* no inputs */
-		: "$1", "memory");
+		: "memory");
 }
 
+__asm__ (
+	".macro\t__save_flags flags\n\t"
+	".set\tpush\n\t"
+	".set\treorder\n\t"
+	"mfc0\t\\flags, $12\n\t"
+	".set\tpop\n\t"
+	".endm");
+
 #define __save_flags(x)							\
 __asm__ __volatile__(							\
-	".set\tnoreorder\n\t"						\
-	"mfc0\t%0,$12\n\t"						\
-	".set\treorder"							\
+	"__save_flags %0"						\
 	: "=r" (x))
 
+__asm__ (
+	".macro\t__save_and_cli result\n\t"
+	".set\tpush\n\t"
+	".set\treorder\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t\\result, $12\n\t"
+	"ori\t$1, \\result, 1\n\t"
+	"xori\t$1, 1\n\t"
+	".set\tnoreorder\n\t"
+	"mtc0\t$1, $12\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	".set\tpop\n\t"	
+	".endm");
+
 #define __save_and_cli(x)						\
 __asm__ __volatile__(							\
-	".set\tnoreorder\n\t"						\
-	".set\tnoat\n\t"						\
-	"mfc0\t%0,$12\n\t"						\
-	"ori\t$1,%0,1\n\t"						\
-	"xori\t$1,1\n\t"						\
-	"mtc0\t$1,$12\n\t"						\
-	"nop\n\t"							\
-	"nop\n\t"							\
-	"nop\n\t"							\
-	".set\tat\n\t"							\
-	".set\treorder"							\
+	"__save_and_cli\t%0"						\
 	: "=r" (x)							\
 	: /* no inputs */						\
-	: "$1", "memory")
+	: "memory")
+
+__asm__(".macro\t__restore_flags flags\n\t"
+	".set\tnoreorder\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t$1, $12\n\t"
+	"andi\t\\flags, 1\n\t"
+	"ori\t$1, 1\n\t"
+	"xori\t$1, 1\n\t"
+	"or\t\\flags, $1\n\t"
+	"mtc0\t\\flags, $12\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	"sll\t$0, $0, 1\t\t\t# nop\n\t"
+	".set\tat\n\t"
+	".set\treorder\n\t"
+	".endm");
 
 #define __restore_flags(flags)						\
 do {									\
 	unsigned long __tmp1;						\
 									\
 	__asm__ __volatile__(						\
-		".set\tnoreorder\t\t\t# __restore_flags\n\t"		\
-		".set\tnoat\n\t"					\
-		"mfc0\t$1, $12\n\t"					\
-		"andi\t%0, 1\n\t"					\
-		"ori\t$1, 1\n\t"					\
-		"xori\t$1, 1\n\t"					\
-		"or\t%0, $1\n\t"					\
-		"mtc0\t%0, $12\n\t"					\
-		"nop\n\t"						\
-		"nop\n\t"						\
-		"nop\n\t"						\
-		".set\tat\n\t"						\
-		".set\treorder"						\
+		"__restore_flags\t%0"					\
 		: "=r" (__tmp1)						\
 		: "0" (flags)						\
-		: "$1", "memory");					\
+		: "memory");						\
 } while(0)
 
 #ifdef CONFIG_SMP
@@ -129,10 +156,10 @@
 #endif /* CONFIG_SMP */
 
 /* For spinlocks etc */
-#define local_irq_save(x)	__save_and_cli(x);
-#define local_irq_restore(x)	__restore_flags(x);
-#define local_irq_disable()	__cli();
-#define local_irq_enable()	__sti();
+#define local_irq_save(x)	__save_and_cli(x)
+#define local_irq_restore(x)	__restore_flags(x)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
 
 /*
  * These are probably defined overly paranoid ...
@@ -165,25 +192,24 @@
 #define set_wmb(var, value) \
 do { var = value; wmb(); } while (0)
 
-#if !defined (_LANGUAGE_ASSEMBLY)
 /*
  * switch_to(n) should switch tasks to task nr n, first
  * checking that n isn't the current task, in which case it does nothing.
  */
 extern asmlinkage void *resume(void *last, void *next);
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 #define prepare_to_switch()	do { } while(0)
 
 extern asmlinkage void lazy_fpu_switch(void *, void *);
 extern asmlinkage void init_fpu(void);
-extern asmlinkage void save_fp(void *);
+extern asmlinkage void save_fp(struct task_struct *);
+extern asmlinkage void restore_fp(struct task_struct *);
 
 #ifdef CONFIG_SMP
 #define SWITCH_DO_LAZY_FPU \
 	if (prev->flags & PF_USEDFPU) { \
 		lazy_fpu_switch(prev, 0); \
-		set_cp0_status(ST0_CU1, ~ST0_CU1); \
+		clear_cp0_status(ST0_CU1); \
 		prev->flags &= ~PF_USEDFPU; \
 	}
 #else /* CONFIG_SMP */
@@ -201,38 +227,40 @@
 	unsigned long dummy;
 
 	__asm__ __volatile__(
-		".set\tnoreorder\t\t\t# xchg_u32\n\t"
-		".set\tnoat\n\t"
+		".set\tpush\t\t\t\t# xchg_u32\n\t"
+		".set\tnoreorder\n\t"
+		".set\tnomacro\n\t"
 		"ll\t%0, %3\n"
-		"1:\tmove\t$1, %2\n\t"
-		"sc\t$1, %1\n\t"
-		"beqzl\t$1, 1b\n\t"
+		"1:\tmove\t%2, %z4\n\t"
+		"sc\t%2, %1\n\t"
+		"beqzl\t%2, 1b\n\t"
 		" ll\t%0, %3\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (val), "=o" (*m), "=r" (dummy)
-		: "o" (*m), "2" (val)
+		"sync\n\t"
+		".set\tpop"
+		: "=&r" (val), "=m" (*m), "=&r" (dummy)
+		: "R" (*m), "Jr" (val)
 		: "memory");
 
 	return val;
 }
 
-extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
+extern __inline__ unsigned long xchg_u64(volatile int * m, unsigned long val)
 {
 	unsigned long dummy;
 
 	__asm__ __volatile__(
-		".set\tnoreorder\t\t\t# xchg_u64\n\t"
-		".set\tnoat\n\t"
+		".set\tpush\t\t\t\t# xchg_u64\n\t"
+		".set\tnoreorder\n\t"
+		".set\tnomacro\n\t"
 		"lld\t%0, %3\n"
-		"1:\tmove\t$1, %2\n\t"
-		"scd\t$1, %1\n\t"
-		"beqzl\t$1, 1b\n\t"
+		"1:\tmove\t%2, %z4\n\t"
+		"scd\t%2, %1\n\t"
+		"beqzl\t%2, 1b\n\t"
 		" lld\t%0, %3\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (val), "=o" (*m), "=r" (dummy)
-		: "o" (*m), "2" (val)
+		"sync\n\t"
+		".set\tpop"
+		: "=&r" (val), "=m" (*m), "=&r" (dummy)
+		: "R" (*m), "Jr" (val)
 		: "memory");
 
 	return val;
@@ -242,8 +270,8 @@
 #define tas(ptr) (xchg((ptr),1))
 
 
-static __inline__ unsigned long
-__xchg(unsigned long x, volatile void * ptr, int size)
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr,
+				   int size)
 {
 	switch (size) {
 		case 4:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/time.h linux/include/asm-mips64/time.h
--- linux.orig/include/asm-mips64/time.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/time.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2001, 2002, MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * include/asm-mips/time.h
+ *     header file for the new style time.c file and time services.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * Please refer to Documentation/MIPS/time.README.
+ */
+
+#ifndef _ASM_TIME_H
+#define _ASM_TIME_H
+
+#include <linux/ptrace.h>               /* for struct pt_regs */
+#include <linux/linkage.h>              /* for asmlinkage */
+#include <linux/rtc.h>                  /* for struct rtc_time */
+
+/* 
+ * RTC ops.  By default, they point a no-RTC functions.
+ *	rtc_get_time - mktime(year, mon, day, hour, min, sec) in seconds.
+ *	rtc_set_time - reverse the above translation and set time to RTC.
+ */
+extern unsigned long (*rtc_get_time)(void);
+extern int (*rtc_set_time)(unsigned long);
+
+/*
+ * to_tm() converts system time back to (year, mon, day, hour, min, sec).
+ * It is intended to help implement rtc_set_time() functions.
+ * Copied from PPC implementation.
+ */
+extern void to_tm(unsigned long tim, struct rtc_time * tm);
+
+/*
+ * do_gettimeoffset(). By default, this func pointer points to 
+ * do_null_gettimeoffset(), which leads to the same resolution as HZ.
+ * Higher resolution versions are vailable, which gives ~1us resolution.
+ */
+extern unsigned long (*do_gettimeoffset)(void);
+
+extern unsigned long null_gettimeoffset(void);
+extern unsigned long fixed_rate_gettimeoffset(void);
+extern unsigned long calibrate_div32_gettimeoffset(void);
+extern unsigned long calibrate_div64_gettimeoffset(void);
+
+/*
+ * high-level timer interrupt routines.
+ */
+extern void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/*
+ * the corresponding low-level timer interrupt routine.
+ */
+asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs);
+
+/*
+ * profiling and process accouting is done separately in local_timer_interrupt
+ */
+void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
+
+/*
+ * board specific routines required by time_init().
+ * board_time_init is defaulted to NULL and can remains so.
+ * board_timer_setup must be setup properly in machine setup routine.
+ */
+struct irqaction;
+extern void (*board_time_init)(void);
+extern void (*board_timer_setup)(struct irqaction *irq);
+
+/*
+ * mips_counter_frequency - must be set if you intend to use
+ * counter as timer interrupt source or use fixed_rate_gettimeoffset.
+ */
+extern unsigned int mips_counter_frequency;
+
+#endif /* _ASM_TIME_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/traps.h linux/include/asm-mips64/traps.h
--- linux.orig/include/asm-mips64/traps.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-mips64/traps.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,27 @@
+/*
+ *	include/asm-mips64/traps.h
+ *
+ *	Trap handling definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	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.
+ */
+#ifndef __ASM_MIPS64_TRAPS_H
+#define __ASM_MIPS64_TRAPS_H
+
+/*
+ * Possible status responses for a be_board_handler backend.
+ */
+#define MIPS_BE_DISCARD	0		/* return with no action */
+#define MIPS_BE_FIXUP	1		/* return to the fixup code */
+#define MIPS_BE_FATAL	2		/* treat as an unrecoverable error */
+
+extern int (*be_board_handler)(struct pt_regs *regs, int is_fixup);
+
+extern void bus_error_init(void);
+
+#endif /* __ASM_MIPS64_TRAPS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/types.h linux/include/asm-mips64/types.h
--- linux.orig/include/asm-mips64/types.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/types.h	2002-07-20 01:08:40.000000000 +0000
@@ -69,7 +69,10 @@
 
 #define BITS_PER_LONG _MIPS_SZLONG
 
-typedef unsigned long dma_addr_t;
+typedef u64 dma_addr_t;
+typedef u64 dma64_addr_t;
+
+typedef unsigned long phys_t;
 
 #endif /* __KERNEL__ */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/uaccess.h linux/include/asm-mips64/uaccess.h
--- linux.orig/include/asm-mips64/uaccess.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/uaccess.h	2002-07-20 01:08:32.000000000 +0000
@@ -56,7 +56,7 @@
 #define access_ok(type,addr,size) \
 	__access_ok(((unsigned long)(addr)),(size),__access_mask)
 
-extern inline int verify_area(int type, const void * addr, unsigned long size)
+static inline int verify_area(int type, const void * addr, unsigned long size)
 {
 	return access_ok(type,addr,size) ? 0 : -EFAULT;
 }
@@ -219,107 +219,106 @@
 
 extern size_t __copy_user(void *__to, const void *__from, size_t __n);
 
-#define __copy_to_user(to,from,n)				\
-({								\
-	void *__cu_to;						\
-	const void *__cu_from;					\
-	long __cu_len;						\
-								\
-	__cu_to = (to);						\
-	__cu_from = (from);					\
-	__cu_len = (n);						\
-	__asm__ __volatile__(					\
-	"move\t$4, %1\n\t"					\
-	"move\t$5, %2\n\t"					\
-	"move\t$6, %3\n\t"					\
-	__MODULE_JAL(__copy_user)				\
-	"move\t%0, $6"						\
-	: "=r" (__cu_len)					\
-	: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len)	\
-	: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12",	\
-	  "$15", "$24", "$31","memory");			\
-	__cu_len;						\
-})
-
-#define __copy_from_user(to,from,n)				\
-({								\
-	void *__cu_to;						\
-	const void *__cu_from;					\
-	long __cu_len;						\
-								\
-	__cu_to = (to);						\
-	__cu_from = (from);					\
-	__cu_len = (n);						\
-	__asm__ __volatile__(					\
-	"move\t$4, %1\n\t"					\
-	"move\t$5, %2\n\t"					\
-	"move\t$6, %3\n\t"					\
-	".set\tnoreorder\n\t"					\
-	__MODULE_JAL(__copy_user)				\
-	".set\tnoat\n\t"					\
-	"daddu\t$1, %2, %3\n\t"					\
-	".set\tat\n\t"						\
-	".set\treorder\n\t"					\
-	"move\t%0, $6"						\
-	: "=r" (__cu_len)					\
-	: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len)	\
-	: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12",	\
-	  "$15", "$24", "$31","memory");			\
-	__cu_len;						\
-})
-
-#define copy_to_user(to,from,n)					\
-({								\
-	void *__cu_to;						\
-	const void *__cu_from;					\
-	long __cu_len;						\
-								\
-	__cu_to = (to);						\
-	__cu_from = (from);					\
-	__cu_len = (n);						\
-	if (access_ok(VERIFY_WRITE, __cu_to, __cu_len))		\
-		__asm__ __volatile__(				\
-		"move\t$4, %1\n\t"				\
-		"move\t$5, %2\n\t"				\
-		"move\t$6, %3\n\t"				\
-		__MODULE_JAL(__copy_user)			\
-		"move\t%0, $6"					\
-		: "=r" (__cu_len)				\
-		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
-		: "$4", "$5", "$6", "$8", "$9", "$10", "$11",	\
-		  "$12", "$15", "$24", "$31","memory");		\
-	__cu_len;						\
-})
-
-#define copy_from_user(to,from,n)				\
-({								\
-	void *__cu_to;						\
-	const void *__cu_from;					\
-	long __cu_len;						\
-								\
-	__cu_to = (to);						\
-	__cu_from = (from);					\
-	__cu_len = (n);						\
-	if (access_ok(VERIFY_READ, __cu_from, __cu_len))	\
-		__asm__ __volatile__(				\
-		"move\t$4, %1\n\t"				\
-		"move\t$5, %2\n\t"				\
-		"move\t$6, %3\n\t"				\
-		".set\tnoreorder\n\t"				\
-		__MODULE_JAL(__copy_user)			\
-		".set\tnoat\n\t"				\
-		"daddu\t$1, %2, %3\n\t"				\
-		".set\tat\n\t"					\
-		".set\treorder\n\t"				\
-		"move\t%0, $6"					\
-		: "=r" (__cu_len)				\
-		: "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
-		: "$4", "$5", "$6", "$8", "$9", "$10", "$11",	\
-		  "$12", "$15", "$24", "$31","memory");		\
-	__cu_len;						\
+#define __invoke_copy_to_user(to,from,n)				\
+({									\
+	register void *__cu_to_r __asm__ ("$4");			\
+	register const void *__cu_from_r __asm__ ("$5");		\
+	register long __cu_len_r __asm__ ("$6");			\
+									\
+	__cu_to_r = (to);						\
+	__cu_from_r = (from);						\
+	__cu_len_r = (n);						\
+	__asm__ __volatile__(						\
+	__MODULE_JAL(__copy_user)					\
+	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
+	:								\
+	: "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",		\
+	  "memory");							\
+	__cu_len_r;							\
+})
+
+#define __copy_to_user(to,from,n)					\
+({									\
+	void *__cu_to;							\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	__cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len);	\
+	__cu_len;							\
+})
+
+#define copy_to_user(to,from,n)						\
+({									\
+	void *__cu_to;							\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	if (access_ok(VERIFY_WRITE, __cu_to, __cu_len))			\
+		__cu_len = __invoke_copy_to_user(__cu_to, __cu_from,	\
+		                                __cu_len);		\
+	__cu_len;							\
+})
+
+#define __invoke_copy_from_user(to,from,n)				\
+({									\
+	register void *__cu_to_r __asm__ ("$4");			\
+	register const void *__cu_from_r __asm__ ("$5");		\
+	register long __cu_len_r __asm__ ("$6");			\
+									\
+	__cu_to_r = (to);						\
+	__cu_from_r = (from);						\
+	__cu_len_r = (n);						\
+	__asm__ __volatile__(						\
+	".set\tnoreorder\n\t"						\
+	__MODULE_JAL(__copy_user)					\
+	".set\tnoat\n\t"						\
+	"daddu\t$1, %1, %2\n\t"						\
+	".set\tat\n\t"							\
+	".set\treorder\n\t"						\
+	"move\t%0, $6"							\
+	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
+	:								\
+	: "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",		\
+	  "memory");							\
+	__cu_len_r;							\
+})
+
+#define __copy_from_user(to,from,n)					\
+({									\
+	void *__cu_to;							\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	__cu_len = __invoke_copy_from_user(__cu_to, __cu_from,		\
+	                                   __cu_len);			\
+	__cu_len;							\
+})
+
+#define copy_from_user(to,from,n)					\
+({									\
+	void *__cu_to;							\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	if (access_ok(VERIFY_READ, __cu_from, __cu_len))		\
+		__cu_len = __invoke_copy_from_user(__cu_to, __cu_from,	\
+		                                   __cu_len);		\
+	__cu_len;							\
 })
 
-extern inline __kernel_size_t
+static inline __kernel_size_t
 __clear_user(void *addr, __kernel_size_t size)
 {
 	__kernel_size_t res;
@@ -351,7 +350,7 @@
  * Returns: -EFAULT if exception before terminator, N if the entire
  * buffer filled, else strlen.
  */
-extern inline long
+static inline long
 __strncpy_from_user(char *__to, const char *__from, long __len)
 {
 	long res;
@@ -369,7 +368,7 @@
 	return res;
 }
 
-extern inline long
+static inline long
 strncpy_from_user(char *__to, const char *__from, long __len)
 {
 	long res;
@@ -388,7 +387,7 @@
 }
 
 /* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-extern inline long __strlen_user(const char *s)
+static inline long __strlen_user(const char *s)
 {
 	long res;
 
@@ -403,7 +402,7 @@
 	return res;
 }
 
-extern inline long strlen_user(const char *s)
+static inline long strlen_user(const char *s)
 {
 	long res;
 
@@ -419,7 +418,7 @@
 }
 
 /* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-extern inline long __strnlen_user(const char *s, long n)
+static inline long __strnlen_user(const char *s, long n)
 {
 	long res;
 
@@ -435,7 +434,7 @@
 	return res;
 }
 
-extern inline long strnlen_user(const char *s, long n)
+static inline long strnlen_user(const char *s, long n)
 {
 	long res;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/unaligned.h linux/include/asm-mips64/unaligned.h
--- linux.orig/include/asm-mips64/unaligned.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-mips64/unaligned.h	2002-07-20 01:08:38.000000000 +0000
@@ -15,7 +15,7 @@
 /*
  * Load quad unaligned.
  */
-extern inline unsigned long __ldq_u(const unsigned long * __addr)
+static inline unsigned long __ldq_u(const unsigned long * __addr)
 {
 	unsigned long __res;
 
@@ -29,7 +29,7 @@
 /*
  * Load long unaligned.
  */
-extern inline unsigned long __ldl_u(const unsigned int * __addr)
+static inline unsigned long __ldl_u(const unsigned int * __addr)
 {
 	unsigned long __res;
 
@@ -43,7 +43,7 @@
 /*
  * Load word unaligned.
  */
-extern inline unsigned long __ldw_u(const unsigned short * __addr)
+static inline unsigned long __ldw_u(const unsigned short * __addr)
 {
 	unsigned long __res;
 
@@ -57,7 +57,7 @@
 /*
  * Store quad ununaligned.
  */
-extern inline void __stq_u(unsigned long __val, unsigned long * __addr)
+static inline void __stq_u(unsigned long __val, unsigned long * __addr)
 {
 	__asm__("usd\t%1, %0"
 		: "=m" (*__addr)
@@ -67,7 +67,7 @@
 /*
  * Store long ununaligned.
  */
-extern inline void __stl_u(unsigned long __val, unsigned int * __addr)
+static inline void __stl_u(unsigned long __val, unsigned int * __addr)
 {
 	__asm__("usw\t%1, %0"
 		: "=m" (*__addr)
@@ -77,7 +77,7 @@
 /*
  * Store word ununaligned.
  */
-extern inline void __stw_u(unsigned long __val, unsigned short * __addr)
+static inline void __stw_u(unsigned long __val, unsigned short * __addr)
 {
 	__asm__("ush\t%1, %0"
 		: "=m" (*__addr)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/unistd.h linux/include/asm-mips64/unistd.h
--- linux.orig/include/asm-mips64/unistd.h	2000-11-29 05:42:04.000000000 +0000
+++ linux/include/asm-mips64/unistd.h	2002-07-20 01:08:30.000000000 +0000
@@ -237,11 +237,31 @@
 #define __NR_Linux32_madvise		(__NR_Linux32 + 218)
 #define __NR_Linux32_getdents64		(__NR_Linux32 + 219)
 #define __NR_Linux32_fcntl64		(__NR_Linux32 + 220)
+#define __NR_Linux32_security		(__NR_Linux32 + 221)
+#define __NR_Linux32_gettid		(__NR_Linux32 + 222)
+#define __NR_Linux32_readahead		(__NR_Linux32 + 223)
+#define __NR_Linux32_setxattr		(__NR_Linux32 + 224)
+#define __NR_Linux32_lsetxattr		(__NR_Linux32 + 225)
+#define __NR_Linux32_fsetxattr		(__NR_Linux32 + 226)
+#define __NR_Linux32_getxattr		(__NR_Linux32 + 227)
+#define __NR_Linux32_lgetxattr		(__NR_Linux32 + 228)
+#define __NR_Linux32_fgetxattr		(__NR_Linux32 + 229)
+#define __NR_Linux32_listxattr		(__NR_Linux32 + 230)
+#define __NR_Linux32_llistxattr		(__NR_Linux32 + 231)
+#define __NR_Linux32_flistxattr		(__NR_Linux32 + 232)
+#define __NR_Linux32_removexattr	(__NR_Linux32 + 233)
+#define __NR_Linux32_lremovexattr	(__NR_Linux32 + 234)
+#define __NR_Linux32_fremovexattr	(__NR_Linux32 + 235)
+#define __NR_Linux32_tkill		(__NR_Linux32 + 236)
+#define __NR_Linux32_sendfile64		(__NR_Linux32 + 237)
+#define __NR_Linux32_futex		(__NR_Linux32 + 238)
+#define __NR_Linux32_sched_setaffinity	(__NR_Linux32 + 239)
+#define __NR_Linux32_sched_getaffinity	(__NR_Linux32 + 240)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux32_syscalls		220
+#define __NR_Linux32_syscalls		240
 
 /*
  * Linux 64-bit syscalls are in the range from 5000 to 5999.
@@ -461,31 +481,54 @@
 #define __NR_mincore			(__NR_Linux + 211)
 #define __NR_madvise			(__NR_Linux + 212)
 #define __NR_getdents64			(__NR_Linux + 213)
+#define __NR__security			(__NR_Linux + 214)
+#define __NR__gettid			(__NR_Linux + 215)
+#define __NR__readahead			(__NR_Linux + 216)
+#define __NR_setxattr			(__NR_Linux + 217)
+#define __NR_lsetxattr			(__NR_Linux + 218)
+#define __NR_fsetxattr			(__NR_Linux + 219)
+#define __NR_getxattr			(__NR_Linux + 220)
+#define __NR_lgetxattr			(__NR_Linux + 221)
+#define __NR_fgetxattr			(__NR_Linux + 222)
+#define __NR_listxattr			(__NR_Linux + 223)
+#define __NR_llistxattr			(__NR_Linux + 224)
+#define __NR_flistxattr			(__NR_Linux + 225)
+#define __NR_removexattr		(__NR_Linux + 226)
+#define __NR_lremovexattr		(__NR_Linux + 227)
+#define __NR_fremovexattr		(__NR_Linux + 228)
+#define __NR_tkill			(__NR_Linux + 229)
+#define __NR_sendfile64			(__NR_Linux + 230)
+#define __NR_futex			(__NR_Linux + 231)
+#define __NR_sched_setaffinity		(__NR_Linux + 232)
+#define __NR_sched_getaffinity		(__NR_Linux + 233)
 
 /*
  * Offset of the last Linux flavoured syscall
  */
-#define __NR_Linux_syscalls		213
+#define __NR_Linux_syscalls		233
 
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __ASSEMBLY__
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
 type name(void) \
 { \
-long __res, __err; \
-__asm__ volatile ("li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name) \
-                  : "$2", "$7","$8","$9","$10","$11","$12","$13","$14","$15", \
-		    "$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a3 asm("$7"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %2\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "=r" (__a3) \
+	: "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 /*
@@ -495,89 +538,94 @@
 #define _syscall1(type,name,atype,a) \
 type name(atype a) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-		  "li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)) \
-                  : "$2","$4","$7","$8","$9","$10","$11","$12","$13","$14", \
-		    "$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a3 asm("$7"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %3\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "=r" (__a3) \
+	: "r" (__a0), "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall2(type,name,atype,a,btype,b) \
-type name(atype a,btype b) \
+type name(atype a, btype b) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-		  "move\t$5, %4\n\t" \
-		  "li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-		  : "=r" (__res), "=r" (__err) \
-		  : "i" (__NR_##name),"r" ((long)(a)), \
-		                      "r" ((long)(b)) \
-		  : "$2","$4","$5","$7","$8","$9","$10","$11","$12","$13","$14","$15", \
-                    "$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a3 asm("$7"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %4\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "=r" (__a3) \
+	: "r" (__a0), "r" (__a1), "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall3(type,name,atype,a,btype,b,ctype,c) \
-type name (atype a, btype b, ctype c) \
+type name(atype a, btype b, ctype c) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-                  "move\t$5, %4\n\t" \
-                  "move\t$6, %5\n\t" \
-		  "li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)) \
-		  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
-		    "$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "=r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
-type name (atype a, btype b, ctype c, dtype d) \
+type name(atype a, btype b, ctype c, dtype d) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-                  "move\t$5, %4\n\t" \
-                  "move\t$6, %5\n\t" \
-                  "move\t$7, %6\n\t" \
-		  "li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)) \
-                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
-		    "$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #if (_MIPS_SIM == _ABIN32) || (_MIPS_SIM == _ABI64)
@@ -585,193 +633,189 @@
 #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
 type name (atype a,btype b,ctype c,dtype d,etype e) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-                  "move\t$5, %4\n\t" \
-                  "move\t$6, %5\n\t" \
-                  "move\t$7, %6\n\t" \
-		  "move\t$8, %7\n\t" \
-		  "sw\t$2, 16($29)\n\t" \
-		  "li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "r" ((long)(e)) \
-                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
-                    "$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	register unsigned long __a4 asm("$8") = (unsigned long) e; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %6\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3), "+r" (__a4) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
+	: "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \
 type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-                  "move\t$5, %4\n\t" \
-                  "move\t$6, %5\n\t" \
-                  "move\t$7, %6\n\t" \
-                  "move\t$8, %7\n\t" \
-                  "move\t$9, %8\n\t" \
-		  "li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "m" ((long)(e)), \
-                                      "m" ((long)(f)) \
-                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
-                    "$12","$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	register unsigned long __a4 asm("$8") = (unsigned long) e; \
+	register unsigned long __a5 asm("$9") = (unsigned long) f; \
+	\
+	__asm__ volatile ( "" \
+	: "+r" (__a5) \
+	: \
+	: "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %6\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3), "+r" (__a4) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
+	: "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \
 type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-                  "move\t$5, %4\n\t" \
-                  "move\t$6, %5\n\t" \
-                  "move\t$7, %6\n\t" \
-                  "move\t$8, %7\n\t" \
-                  "move\t$9, %8\n\t" \
-                  "move\t$10, %9\n\t" \
-		  "li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "r" ((long)(e)), \
-                                      "r" ((long)(f)), \
-                                      "r" ((long)(g)) \
-                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
-                    "$12","$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	register unsigned long __a4 asm("$8") = (unsigned long) e; \
+	register unsigned long __a5 asm("$9") = (unsigned long) f; \
+	register unsigned long __a6 asm("$10") = (unsigned long) g; \
+	\
+	__asm__ volatile ( "" \
+	: "+r" (__a5), "+r" (__a6) \
+	: \
+	: "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"li\t$2, %6\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3), "+r" (__a4) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
+	: "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #else /* not N32 or 64 ABI */
 
-/* These are here for sake of fucking lusercode living in the fucking believe
-   having to fuck around with the syscall interface themselfes.  */
+/*
+ * Using those means your brain needs more than an oil change ;-)
+ */
 
 #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-type name (atype a,btype b,ctype c,dtype d,etype e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-                  "move\t$5, %4\n\t" \
-                  "move\t$6, %5\n\t" \
-		  "lw\t$2, %7\n\t" \
-                  "move\t$7, %6\n\t" \
-		  "subu\t$29, 24\n\t" \
-		  "sw\t$2, 16($29)\n\t" \
-		  "li\t$2, %2\n\t" \
-		  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-		  "addiu\t$29,24" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "m" ((long)(e)) \
-                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
-                    "$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"lw\t$2, %6\n\t" \
+	"subu\t$29, 32\n\t" \
+	"sw\t$2, 16($29)\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	"addiu\t$29, 32\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
+	  "m" ((unsigned long)e) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \
-type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
+type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-                  "move\t$5, %4\n\t" \
-                  "move\t$6, %5\n\t" \
-		  "lw\t$2, %7\n\t" \
-		  "lw\t$3, %8\n\t" \
-                  "move\t$7, %6\n\t" \
-		  "subu\t$29, 24\n\t" \
-		  "sw\t$2, 16($29)\n\t" \
-		  "sw\t$3, 20($29)\n\t" \
-		  "li\t$2, %2\n\t" \
-                  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-		  "addiu\t$29, 24" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "m" ((long)(e)), \
-                                      "m" ((long)(f)) \
-                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
-                    "$12","$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"lw\t$2, %6\n\t" \
+	"lw\t$8, %7\n\t" \
+	"subu\t$29, 32\n\t" \
+	"sw\t$2, 16($29)\n\t" \
+	"sw\t$8, 20($29)\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	"addiu\t$29, 32\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
+	  "m" ((unsigned long)e), "m" ((unsigned long)f) \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \
-type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \
+type name(atype a, btype b, ctype c, dtype d, etype e, ftype f, gtype g) \
 { \
-long __res, __err; \
-__asm__ volatile ("move\t$4, %3\n\t" \
-                  "move\t$5, %4\n\t" \
-                  "move\t$6, %5\n\t" \
-		  "lw\t$2, %7\n\t" \
-		  "lw\t$3, %8\n\t" \
-                  "move\t$7, %6\n\t" \
-		  "subu\t$29, 32\n\t" \
-		  "sw\t$2, 16($29)\n\t" \
-		  "lw\t$2, %9\n\t" \
-		  "sw\t$3, 20($29)\n\t" \
-		  "sw\t$2, 24($29)\n\t" \
-		  "li\t$2, %2\n\t" \
-                  "syscall\n\t" \
-		  "move\t%0, $2\n\t" \
-		  "move\t%1, $7" \
-		  "addiu\t$29, 32" \
-                  : "=r" (__res), "=r" (__err) \
-                  : "i" (__NR_##name),"r" ((long)(a)), \
-                                      "r" ((long)(b)), \
-                                      "r" ((long)(c)), \
-                                      "r" ((long)(d)), \
-                                      "m" ((long)(e)), \
-                                      "m" ((long)(f)), \
-                                      "m" ((long)(g)) \
-                  : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
-                    "$12","$13","$14","$15","$24"); \
-if (__err == 0) \
-	return (type) __res; \
-errno = __res; \
-return -1; \
+	register unsigned long __v0 asm("$2") = __NR_##name; \
+	register unsigned long __a0 asm("$4") = (unsigned long) a; \
+	register unsigned long __a1 asm("$5") = (unsigned long) b; \
+	register unsigned long __a2 asm("$6") = (unsigned long) c; \
+	register unsigned long __a3 asm("$7") = (unsigned long) d; \
+	\
+	__asm__ volatile ( \
+	".set\tnoreorder\n\t" \
+	"lw\t$2, %6\n\t" \
+	"lw\t$8, %7\n\t" \
+	"lw\t$9, %8\n\t" \
+	"subu\t$29, 32\n\t" \
+	"sw\t$2, 16($29)\n\t" \
+	"sw\t$8, 20($29)\n\t" \
+	"sw\t$9, 24($29)\n\t" \
+	"li\t$2, %5\t\t\t# " #name "\n\t" \
+	"syscall\n\t" \
+	"addiu\t$29, 32\n\t" \
+	".set\treorder" \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
+	  "m" ((unsigned long)e), "m" ((unsigned long)f), \
+	  "m" ((unsigned long)g), \
+	: "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	\
+	if (__a3 == 0) \
+		return (type) __v0; \
+	errno = __v0; \
+	return -1; \
 }
 
 #endif
@@ -809,7 +853,7 @@
 	return waitpid(-1,wait_stat,0);
 }
 
-#endif /* !defined (__KERNEL_SYSCALLS__) */
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+#endif /* __KERNEL_SYSCALLS__ */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_UNISTD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/xtalk/xtalk.h linux/include/asm-mips64/xtalk/xtalk.h
--- linux.orig/include/asm-mips64/xtalk/xtalk.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/xtalk/xtalk.h	2002-07-20 01:08:21.000000000 +0000
@@ -12,7 +12,7 @@
 #ifndef _ASM_XTALK_XTALK_H
 #define _ASM_XTALK_XTALK_H
 
-#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
+#ifndef __ASSEMBLY__
 /*
  * User-level device driver visible types
  */
@@ -47,6 +47,6 @@
 #define	XIO_PORT(x)	((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT))
 #define	XIO_PACK(p,o)	((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS))
 
-#endif /* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_XTALK_XTALK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-mips64/xtalk/xwidget.h linux/include/asm-mips64/xtalk/xwidget.h
--- linux.orig/include/asm-mips64/xtalk/xwidget.h	2001-09-09 17:43:02.000000000 +0000
+++ linux/include/asm-mips64/xtalk/xwidget.h	2002-07-20 01:08:24.000000000 +0000
@@ -91,7 +91,7 @@
  * widget target flush register are widget dependent thus will not be
  * defined here
  */
-#if _LANGUAGE_C
+#ifndef __ASSEMBLY__
 typedef u32 widgetreg_t;
 
 /* widget configuration registers */
@@ -162,6 +162,6 @@
 	((hwid2)->mfg_num == XWIDGET_MFG_NUM_NONE) || \
 	((hwid1)->mfg_num == (hwid2)->mfg_num)))
 
-#endif				/* _LANGUAGE_C */
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_XTALK_XWIDGET_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-parisc/ide.h linux/include/asm-parisc/ide.h
--- linux.orig/include/asm-parisc/ide.h	2000-12-05 20:29:39.000000000 +0000
+++ linux/include/asm-parisc/ide.h	2002-07-20 01:08:32.000000000 +0000
@@ -90,7 +90,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+	} b;
+} control_t;
 
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
 #define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-parisc/page.h linux/include/asm-parisc/page.h
--- linux.orig/include/asm-parisc/page.h	2000-12-05 20:29:39.000000000 +0000
+++ linux/include/asm-parisc/page.h	2002-07-20 01:08:28.000000000 +0000
@@ -81,6 +81,9 @@
 #define	virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 
 #endif /* _PARISC_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-parisc/pgalloc.h linux/include/asm-parisc/pgalloc.h
--- linux.orig/include/asm-parisc/pgalloc.h	2001-04-23 22:28:07.000000000 +0000
+++ linux/include/asm-parisc/pgalloc.h	2002-07-20 01:08:40.000000000 +0000
@@ -106,6 +106,9 @@
 #define flush_icache_range(start, end) \
         __flush_icache_range(start, end - start)
 
+#define flush_icache_user_range(vma, page, addr, len) \
+	flush_icache_page((vma), (page))
+
 #define flush_icache_page(vma, page) \
 	__flush_icache_range(page_address(page), PAGE_SIZE)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-parisc/pgtable.h linux/include/asm-parisc/pgtable.h
--- linux.orig/include/asm-parisc/pgtable.h	2001-11-11 18:20:21.000000000 +0000
+++ linux/include/asm-parisc/pgtable.h	2002-07-20 01:08:31.000000000 +0000
@@ -275,7 +275,6 @@
  * Permanent address of a page. Obviously must never be
  * called on a highmem page.
  */
-#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; })
 #define __page_address(page) ({ if (PageHighMem(page)) BUG(); PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT); })
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 #define pte_page(x) (mem_map+pte_pagenr(x))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-parisc/siginfo.h linux/include/asm-parisc/siginfo.h
--- linux.orig/include/asm-parisc/siginfo.h	2000-12-05 20:29:39.000000000 +0000
+++ linux/include/asm-parisc/siginfo.h	2002-07-20 01:08:36.000000000 +0000
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-parisc/unistd.h linux/include/asm-parisc/unistd.h
--- linux.orig/include/asm-parisc/unistd.h	2000-12-05 20:29:39.000000000 +0000
+++ linux/include/asm-parisc/unistd.h	2002-07-20 01:08:21.000000000 +0000
@@ -689,8 +689,10 @@
 
 #define __NR_getpmsg            (__NR_Linux + 196)      /* some people actually want streams */
 #define __NR_putpmsg            (__NR_Linux + 197)      /* some people actually want streams */
+#define __NR_gettid             (__NR_Linux + 198)
+#define __NR_tkill              (__NR_Linux + 199)
 
-#define __NR_Linux_syscalls     197
+#define __NR_Linux_syscalls     199
 
 #define HPUX_GATEWAY_ADDR       0xC0000004
 #define LINUX_GATEWAY_ADDR      0x100
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/btext.h linux/include/asm-ppc/btext.h
--- linux.orig/include/asm-ppc/btext.h	2001-08-28 13:58:33.000000000 +0000
+++ linux/include/asm-ppc/btext.h	2002-07-20 01:08:33.000000000 +0000
@@ -17,11 +17,11 @@
 
 extern unsigned long disp_BAT[2];
 
-extern boot_infos_t *disp_bi;
+extern boot_infos_t disp_bi;
 extern int boot_text_mapped;
 
 void btext_init(boot_infos_t *bi);
-void btext_welcome(boot_infos_t* bi);
+void btext_welcome(void);
 void btext_prepare_BAT(void);
 void btext_setup_display(int width, int height, int depth, int pitch,
 			 unsigned long address);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/commproc.h linux/include/asm-ppc/commproc.h
--- linux.orig/include/asm-ppc/commproc.h	2001-10-08 18:40:13.000000000 +0000
+++ linux/include/asm-ppc/commproc.h	2002-07-20 01:08:38.000000000 +0000
@@ -736,6 +736,10 @@
 	ushort	iic_tbptr;	/* Internal */
 	ushort	iic_tbc;	/* Internal */
 	uint	iic_txtmp;	/* Internal */
+	uint	iic_res;
+	ushort	iic_rpbase;	/* Relocation pointer */
+	ushort	iic_res2;
+	
 } iic_t;
 
 #define BD_IIC_START		((ushort)0x0400)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/cputable.h linux/include/asm-ppc/cputable.h
--- linux.orig/include/asm-ppc/cputable.h	2001-08-28 13:58:33.000000000 +0000
+++ linux/include/asm-ppc/cputable.h	2002-07-20 01:08:34.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.cputable.h 1.3 08/19/01 22:31:46 paulus
+ * BK Id: SCCS/s.cputable.h 1.4 03/19/02 15:04:39 benh
  */
 /*
  *  include/asm-ppc/cputable.h
@@ -67,6 +67,8 @@
 #define CPU_FTR_604_PERF_MON		0x00000080
 #define CPU_FTR_601			0x00000100
 #define CPU_FTR_HPTE_TABLE		0x00000200
+#define CPU_FTR_CAN_NAP			0x00000400
+#define CPU_FTR_L3CR			0x00000800
 
 #ifdef __ASSEMBLY__
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/heathrow.h linux/include/asm-ppc/heathrow.h
--- linux.orig/include/asm-ppc/heathrow.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-ppc/heathrow.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.heathrow.h 1.10 12/01/01 20:09:11 benh
+ * BK Id: SCCS/s.heathrow.h 1.12 03/19/02 15:53:56 benh
  */
 /*
  * heathrow.h: definitions for using the "Heathrow" I/O controller chip.
@@ -25,7 +25,7 @@
  * Bits in feature control register.
  * Bits postfixed with a _N are in inverse logic
  */
-#define HRW_RESET_SCC		0x00000001	/* actually controls transceiver... */
+#define HRW_SCC_TRANS_EN_N	0x00000001	/* Also controls modem power */
 #define HRW_BAY_POWER_N		0x00000002
 #define HRW_BAY_PCI_ENABLE	0x00000004
 #define HRW_BAY_IDE_ENABLE	0x00000008
@@ -51,7 +51,7 @@
 #define HRW_ARB_BYPASS		0x00400000	/* Disable internal PCI arbitrer */
 #define HRW_IDE1_RESET_N	0x00800000	/* Media bay */
 #define HRW_SLOW_SCC_PCLK	0x01000000	/* ??? (0) */
-#define HRW_MODEM_POWER_N	0x02000000	/* Used by internal modem on wallstreet */
+#define HRW_RESET_SCC		0x02000000
 #define HRW_MFDC_CELL_ENABLE	0x04000000	/* ??? (0) */
 #define HRW_USE_MFDC		0x08000000	/* ??? (0) */
 #define HRW_BMAC_IO_ENABLE	0x60000000	/* two bits, not documented in OF */
@@ -60,10 +60,6 @@
 /* We OR those features at boot on desktop G3s */
 #define HRW_DEFAULTS		(HRW_SCCA_IO | HRW_SCCB_IO | HRW_SCC_ENABLE)
 
-/* Those seem to be different on paddington */
-#define PADD_MODEM_POWER_N	0x00000001	/* modem power on paddington */
-#define PADD_RESET_SCC		0x02000000	/* check this please */
-
 /* Looks like Heathrow has some sort of GPIOs as well... */
 #define HRW_GPIO_MODEM_RESET	0x6d
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/ide.h linux/include/asm-ppc/ide.h
--- linux.orig/include/asm-ppc/ide.h	2001-10-08 18:40:13.000000000 +0000
+++ linux/include/asm-ppc/ide.h	2002-07-20 01:08:32.000000000 +0000
@@ -129,6 +129,18 @@
 	} b;
 } select_t;
 
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+		unsigned reserved456	: 3;
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned bit0		: 1;
+	} b;
+} control_t;
+
 #if !defined(ide_request_irq)
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/machdep.h linux/include/asm-ppc/machdep.h
--- linux.orig/include/asm-ppc/machdep.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-ppc/machdep.h	2002-07-20 01:08:30.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.machdep.h 1.27 12/01/01 20:09:11 benh
+ * BK Id: SCCS/s.machdep.h 1.31 03/19/02 14:19:28 benh
  */
 #ifdef __KERNEL__
 #ifndef _PPC_MACHDEP_H
@@ -56,6 +56,9 @@
 	unsigned char 	(*nvram_read_val)(int addr);
 	void		(*nvram_write_val)(int addr, unsigned char val);
 
+	/* Called from prepare_namespace() */
+	void		(*discover_root)(void);
+
 	/* Tons of keyboard stuff. */
 	int		(*kbd_setkeycode)(unsigned int scancode,
 				unsigned int keycode);
@@ -113,7 +116,7 @@
 };
 
 extern struct machdep_calls ppc_md;
-extern char cmd_line[512];
+extern char cmd_line[];
 
 extern void setup_pci_ptrs(void);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/page.h linux/include/asm-ppc/page.h
--- linux.orig/include/asm-ppc/page.h	2001-08-28 13:58:33.000000000 +0000
+++ linux/include/asm-ppc/page.h	2002-07-20 01:08:30.000000000 +0000
@@ -83,8 +83,8 @@
 
 extern void clear_page(void *page);
 extern void copy_page(void *to, void *from);
-#define clear_user_page(page, vaddr)	clear_page(page)
-#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+extern void clear_user_page(void *page, unsigned long vaddr);
+extern void copy_user_page(void *to, void *from, unsigned long vaddr);
 
 /* map phys->virtual and virtual->phys for RAM pages */
 static inline unsigned long ___pa(unsigned long v)
@@ -137,5 +137,9 @@
 }
 
 #endif /* __ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 #endif /* _PPC_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/pgtable.h linux/include/asm-ppc/pgtable.h
--- linux.orig/include/asm-ppc/pgtable.h	2001-11-11 18:20:21.000000000 +0000
+++ linux/include/asm-ppc/pgtable.h	2002-07-20 01:08:28.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pgtable.h 1.15 09/22/01 11:26:52 trini
+ * BK Id: SCCS/s.pgtable.h 1.21 03/12/02 11:49:48 paulus
  */
 #ifdef __KERNEL__
 #ifndef _PPC_PGTABLE_H
@@ -82,13 +82,14 @@
 #define flush_cache_mm(mm)		do { } while (0)
 #define flush_cache_range(mm, a, b)	do { } while (0)
 #define flush_cache_page(vma, p)	do { } while (0)
-#define flush_icache_page(vma, page)	do { } while (0)
+#define flush_page_to_ram(page)		do { } while (0)
 
+extern void flush_icache_user_range(struct vm_area_struct *vma,
+		struct page *page, unsigned long addr, int len);
 extern void flush_icache_range(unsigned long, unsigned long);
-extern void __flush_page_to_ram(unsigned long page_va);
-extern void flush_page_to_ram(struct page *page);
-
-#define flush_dcache_page(page)			do { } while (0)
+extern void __flush_dcache_icache(void *page_va);
+extern void flush_dcache_page(struct page *page);
+extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
 
 extern unsigned long va_to_phys(unsigned long address);
 extern pte_t *va_to_pte(unsigned long address);
@@ -263,15 +264,6 @@
 #define _PAGE_HWWRITE	0
 #endif
 
-/* We can't use _PAGE_HWWRITE on any SMP due to the lack of ability
- * to atomically manage _PAGE_HWWRITE and it's coordination flags,
- * _PAGE_DIRTY or _PAGE_RW.  The SMP systems must manage HWWRITE
- * or its logical equivalent in the MMU management software.
- */
-#if CONFIG_SMP && _PAGE_HWWRITE
-#error "You can't configure SMP and HWWRITE"
-#endif
-
 #define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
 
 /*
@@ -281,7 +273,7 @@
  * another purpose.  -- paulus.
  */
 #define _PAGE_BASE	_PAGE_PRESENT | _PAGE_ACCESSED
-#define _PAGE_WRENABLE	_PAGE_RW | _PAGE_DIRTY
+#define _PAGE_WRENABLE	_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE
 
 #define _PAGE_KERNEL	_PAGE_BASE | _PAGE_WRENABLE | _PAGE_SHARED
 #define _PAGE_IO	_PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED
@@ -341,10 +333,6 @@
 #define	pmd_present(pmd)	((pmd_val(pmd) & PAGE_MASK) != 0)
 #define	pmd_clear(pmdp)		do { pmd_val(*(pmdp)) = 0; } while (0)
 
-/*
- * Permanent address of a page.
- */
-#define page_address(page)	((page)->virtual)
 #define pte_page(x)		(mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 
 #ifndef __ASSEMBLY__
@@ -445,10 +433,18 @@
 }
 
 /*
- * Writing a new value into the PTE doesn't disturb the state of the
- * _PAGE_HASHPTE bit, on those machines which use an MMU hash table.
+ * set_pte stores a linux PTE into the linux page table.
+ * On machines which use an MMU hash table we avoid changing the
+ * _PAGE_HASHPTE bit.
  */
-extern void set_pte(pte_t *ptep, pte_t pte);
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+#if _PAGE_HASHPTE != 0
+	pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
+#else
+	*ptep = pte;
+#endif
+}
 
 static inline int ptep_test_and_clear_young(pte_t *ptep)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/pmac_feature.h linux/include/asm-ppc/pmac_feature.h
--- linux.orig/include/asm-ppc/pmac_feature.h	2002-02-25 19:38:12.000000000 +0000
+++ linux/include/asm-ppc/pmac_feature.h	2002-07-20 01:08:27.000000000 +0000
@@ -38,9 +38,11 @@
  */
 
 /* PowerSurge are the first generation of PCI Pmacs. This include
- * all of the Grand-Central based machines
+ * all of the Grand-Central based machines. We currently don't
+ * differenciate most of them.
  */
 #define PMAC_TYPE_PSURGE		0x10	/* PowerSurge */
+#define PMAC_TYPE_ANS			0x11	/* Apple Network Server */
 
 /* Here is the infamous serie of OHare based machines
  */
@@ -84,12 +86,14 @@
 #define PMAC_TYPE_PISMO			0x46	/* Pismo PowerBook */
 #define PMAC_TYPE_TITANIUM		0x47	/* Titanium PowerBook */
 #define PMAC_TYPE_TITANIUM2		0x48	/* Titanium II PowerBook */
+#define PMAC_TYPE_TITANIUM3		0x49	/* Titanium III PowerBook (with L3) */
 #define PMAC_TYPE_UNKNOWN_CORE99	0x5f
 
 /* MacRISC2 machines based on the Pangea chipset
  */
 #define PMAC_TYPE_PANGEA_IMAC		0x100	/* Flower Power iMac */
 #define PMAC_TYPE_IBOOK2		0x101	/* iBook2 (polycarbonate) */
+#define PMAC_TYPE_FLAT_PANEL_IMAC	0x102	/* Flat panel iMac */
 #define PMAC_TYPE_UNKNOWN_PANGEA	0x10f
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- linux.orig/include/asm-ppc/processor.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-ppc/processor.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.processor.h 1.33 12/01/01 20:09:11 benh
+ * BK Id: SCCS/s.processor.h 1.37 05/06/02 01:37:30 benh
  */
 #ifdef __KERNEL__
 #ifndef __ASM_PPC_PROCESSOR_H
@@ -191,8 +191,11 @@
 #define	  HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
 #define	  HID0_SBCLK	(1<<27)
 #define	  HID0_EICE	(1<<26)
+#define	  HID0_TBEN	(1<<26)		/* Timebase enable - 745x */
 #define	  HID0_ECLK	(1<<25)
 #define	  HID0_PAR	(1<<24)
+#define	  HID0_STEN	(1<<24)		/* Software table search enable - 745x */
+#define	  HID0_HIGH_BAT	(1<<23)		/* Enable high BATs - 7455 */
 #define	  HID0_DOZE	(1<<23)
 #define	  HID0_NAP	(1<<22)
 #define	  HID0_SLEEP	(1<<21)
@@ -208,8 +211,9 @@
 #define	  HID0_SIED	(1<<7)		/* Serial Instr. Execution [Disable] */
 #define	  HID0_DFCA	(1<<6)		/* Data Cache Flush Assist */
 #define   HID0_BTIC	(1<<5)		/* Branch Target Instruction Cache Enable */
+#define   HID0_LRSTK	(1<<4)		/* Link register stack - 745x */
 #define   HID0_ABE	(1<<3)		/* Address Broadcast Enable */
-#define   HID0_FOLD	(1<<3)		/* Branch Folding enable - 7450 */
+#define   HID0_FOLD	(1<<3)		/* Branch Folding enable - 745x */
 #define	  HID0_BHTE	(1<<2)		/* Branch History Table Enable */
 #define	  HID0_BTCD	(1<<1)		/* Branch target cache disable */
 #define	  HID0_NOPDST	(1<<1)		/* No-op dst, dstt, etc. instr. */
@@ -267,6 +271,24 @@
 #define SPRN_L2CR2      0x3f8
 #define	SPRN_L3CR	0x3FA	/* Level 3 Cache Control Regsiter (7450) */
 #define L3CR_L3E		0x80000000	/* L3 enable */
+#define L3CR_L3PE		0x40000000	/* L3 data parity enable */
+#define L3CR_L3APE		0x20000000	/* L3 addr parity enable */
+#define L3CR_L3SIZ		0x10000000	/* L3 size */
+#define L3CR_L3CLKEN		0x08000000	/* L3 clock enable */
+#define L3CR_L3RES		0x04000000	/* L3 special reserved bit */
+#define L3CR_L3CLKDIV		0x03800000	/* L3 clock divisor */
+#define L3CR_L3IO		0x00400000	/* L3 instruction only */
+#define L3CR_L3SPO		0x00040000	/* L3 sample point override */
+#define L3CR_L3CKSP		0x00030000	/* L3 clock sample point */
+#define L3CR_L3PSP		0x0000e000	/* L3 P-clock sample point */
+#define L3CR_L3REP		0x00001000	/* L3 replacement algorithm */
+#define L3CR_L3HWF		0x00000800	/* L3 hardware flush */
+#define L3CR_L3I		0x00000400	/* L3 global invalidate */
+#define L3CR_L3RT		0x00000300	/* L3 SRAM type */
+#define L3CR_L3NIRCA		0x00000080	/* L3 non-integer ratio clock adj. */
+#define L3CR_L3DO		0x00000040	/* L3 data only mode */
+#define L3CR_PMEN		0x00000004	/* L3 private memory enable */
+#define L3CR_PMSIZ		0x00000001	/* L3 private memory size */
 #define SPRN_MSSCR0	0x3f6	/* Memory Subsystem Control Register 0 */
 #define SPRN_MSSSR0	0x3f7	/* Memory Subsystem Status Register 1 */
 #define SPRN_ICTRL	0x3f3	/* Instruction Cache & Interrupt control reg */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/prom.h linux/include/asm-ppc/prom.h
--- linux.orig/include/asm-ppc/prom.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-ppc/prom.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prom.h 1.21 12/01/01 20:09:11 benh
+ * BK Id: SCCS/s.prom.h 1.24 04/09/02 21:01:58 paulus
  */
 /*
  * Definitions for talking to the Open Firmware PROM on
@@ -107,10 +107,11 @@
  * pointer values.  See arch/ppc/kernel/prom.c for how these are used.
  */
 extern unsigned long reloc_offset(void);
+extern unsigned long add_reloc_offset(unsigned long);
+extern unsigned long sub_reloc_offset(unsigned long);
 
-#define PTRRELOC(x)	((typeof(x))((unsigned long)(x) + offset))
-#define PTRUNRELOC(x)	((typeof(x))((unsigned long)(x) - offset))
-#define RELOC(x)	(*PTRRELOC(&(x)))
+#define PTRRELOC(x)	((typeof(x))add_reloc_offset((unsigned long)(x)))
+#define PTRUNRELOC(x)	((typeof(x))sub_reloc_offset((unsigned long)(x)))
 
 #endif /* _PPC_PROM_H */
 #endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/ptrace.h linux/include/asm-ppc/ptrace.h
--- linux.orig/include/asm-ppc/ptrace.h	2001-05-21 22:02:06.000000000 +0000
+++ linux/include/asm-ppc/ptrace.h	2002-07-20 01:08:21.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ptrace.h 1.5 05/17/01 18:14:25 cort
+ * BK Id: SCCS/s.ptrace.h 1.8 01/17/02 23:05:50 paulus
  */
 #ifndef _PPC_PTRACE_H
 #define _PPC_PTRACE_H
@@ -103,5 +103,8 @@
 #define PT_FPR31 (PT_FPR0 + 2*31)
 #define PT_FPSCR (PT_FPR0 + 2*32 + 1)
 
-#endif
+/* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go */
+#define PTRACE_GETVRREGS	18
+#define PTRACE_SETVRREGS	19
 
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/siginfo.h linux/include/asm-ppc/siginfo.h
--- linux.orig/include/asm-ppc/siginfo.h	2001-05-21 22:02:06.000000000 +0000
+++ linux/include/asm-ppc/siginfo.h	2002-07-20 01:08:21.000000000 +0000
@@ -108,6 +108,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/smp.h linux/include/asm-ppc/smp.h
--- linux.orig/include/asm-ppc/smp.h	2001-08-28 13:58:33.000000000 +0000
+++ linux/include/asm-ppc/smp.h	2002-07-20 01:08:27.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.smp.h 1.12 08/16/01 07:49:31 paulus
+ * BK Id: SCCS/s.smp.h 1.14 03/28/02 16:54:23 hozer
  */
 /* smp.h: PPC specific SMP stuff.
  *
@@ -62,6 +62,12 @@
 #define KLOCK_HELD       0xffffffff
 #define KLOCK_CLEAR      0x0
 
+#ifdef CONFIG_750_SMP
+#define smp_send_tlb_invalidate(x) smp_ppc750_send_tlb_invalidate(x)
+#else
+#define smp_send_tlb_invalidate(x) do {} while(0)
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 #else /* !(CONFIG_SMP) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/system.h linux/include/asm-ppc/system.h
--- linux.orig/include/asm-ppc/system.h	2001-08-28 13:58:33.000000000 +0000
+++ linux/include/asm-ppc/system.h	2002-07-20 01:08:34.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.system.h 1.14 08/20/01 14:34:41 paulus
+ * BK Id: SCCS/s.system.h 1.20 03/19/02 15:04:39 benh
  */
 /*
  * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
@@ -58,9 +58,13 @@
 #ifdef CONFIG_6xx
 extern long _get_L2CR(void);
 extern void _set_L2CR(unsigned long);
+extern long _get_L3CR(void);
+extern void _set_L3CR(unsigned long);
 #else
-#define _get_L2CR()	0
+#define _get_L2CR()	0L
 #define _set_L2CR(val)	do { } while(0)
+#define _get_L3CR()	0L
+#define _set_L3CR(val)	do { } while(0)
 #endif
 extern void via_cuda_init(void);
 extern void pmac_nvram_init(void);
@@ -120,10 +124,6 @@
 #define local_irq_save(flags)		__save_and_cli(flags)
 #define local_irq_restore(flags)	__restore_flags(flags)
 
-#endif /* __KERNEL__ */
-
-#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-
 static __inline__ unsigned long
 xchg_u32(volatile void *p, unsigned long val)
 {
@@ -222,4 +222,5 @@
 				    (unsigned long)_n_, sizeof(*(ptr))); \
   })
 
+#endif /* __KERNEL__ */
 #endif /* __PPC_SYSTEM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/uaccess.h linux/include/asm-ppc/uaccess.h
--- linux.orig/include/asm-ppc/uaccess.h	2001-09-12 00:03:33.000000000 +0000
+++ linux/include/asm-ppc/uaccess.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.uaccess.h 1.8 09/11/01 18:10:06 paulus
+ * BK Id: SCCS/s.uaccess.h 1.10 05/21/02 21:44:32 paulus
  */
 #ifdef __KERNEL__
 #ifndef _PPC_UACCESS_H
@@ -272,7 +272,11 @@
 {
 	if (access_ok(VERIFY_WRITE, addr, size))
 		return __clear_user(addr, size);
-	return size? -EFAULT: 0;
+	if ((unsigned long)addr < TASK_SIZE) {
+		unsigned long over = (unsigned long)addr + size - TASK_SIZE;
+		return __clear_user(addr, size - over) + over;
+	}
+	return size;
 }
 
 extern int __strncpy_from_user(char *dst, const char *src, long count);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/unistd.h linux/include/asm-ppc/unistd.h
--- linux.orig/include/asm-ppc/unistd.h	2001-11-03 01:43:54.000000000 +0000
+++ linux/include/asm-ppc/unistd.h	2002-07-20 01:08:27.000000000 +0000
@@ -215,6 +215,7 @@
 #define __NR_madvise		205
 #define __NR_mincore		206
 #define __NR_gettid		207
+#define __NR_tkill		208
 
 #define __NR(n)	#n
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc/zorro.h linux/include/asm-ppc/zorro.h
--- linux.orig/include/asm-ppc/zorro.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc/zorro.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,30 @@
+#ifndef _ASM_PPC_ZORRO_H
+#define _ASM_PPC_ZORRO_H
+
+#include <asm/io.h>
+
+#define z_readb in_8
+#define z_readw in_be16
+#define z_readl in_be32
+
+#define z_writeb(val, port) out_8((port), (val))
+#define z_writew(val, port) out_be16((port), (val))
+#define z_writel(val, port) out_be32((port), (val))
+
+#define z_memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define z_memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define z_memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+extern void *__ioremap(unsigned long address, unsigned long size,
+		       unsigned long flags);
+
+extern void *ioremap(unsigned long address, unsigned long size);
+extern void iounmap(void *addr);
+
+extern void *__ioremap(unsigned long address, unsigned long size,
+                       unsigned long flags);
+
+#define z_ioremap ioremap
+#define z_iounmap iounmap
+
+#endif /* _ASM_ZORRO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/a.out.h linux/include/asm-ppc64/a.out.h
--- linux.orig/include/asm-ppc64/a.out.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/a.out.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,44 @@
+#ifndef __PPC64_A_OUT_H__
+#define __PPC64_A_OUT_H__
+
+#include <asm/ppcdebug.h>
+
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+struct exec
+{
+	unsigned long a_info;	/* Use macros N_MAGIC, etc for access */
+	unsigned a_text;	/* length of text, in bytes */
+	unsigned a_data;	/* length of data, in bytes */
+	unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+	unsigned a_syms;	/* length of symbol table data in file, in bytes */
+	unsigned a_entry;	/* start address */
+	unsigned a_trsize;	/* length of relocation info for text, in bytes */
+	unsigned a_drsize;	/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+#ifdef __KERNEL__
+
+/* 64-bit user address space is less PGDIR_SIZE due to pgd_index() bug. */
+#define STACK_TOP_USER64 (TASK_SIZE_USER64 - PGDIR_SIZE)
+
+/* Give 32-bit user space a full 4G address space to live in. */
+#define STACK_TOP_USER32 (TASK_SIZE_USER32)
+
+#define STACK_TOP (((current->thread.flags & PPC_FLAG_32BIT)||(ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \
+		STACK_TOP_USER32 : STACK_TOP_USER64)
+
+#endif /* __KERNEL__ */
+
+#endif /* __PPC64_A_OUT_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/abs_addr.h linux/include/asm-ppc64/abs_addr.h
--- linux.orig/include/asm-ppc64/abs_addr.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/abs_addr.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,121 @@
+#ifndef _ABS_ADDR_H
+#define _ABS_ADDR_H
+
+#include <linux/config.h>
+
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/types.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+
+typedef u32 msChunks_entry;
+struct msChunks {
+        unsigned long num_chunks;
+        unsigned long chunk_size;
+        unsigned long chunk_shift;
+        unsigned long chunk_mask;
+        msChunks_entry *abs;
+};
+
+extern struct msChunks msChunks;
+
+extern unsigned long msChunks_alloc(unsigned long, unsigned long, unsigned long);
+extern unsigned long reloc_offset(void);
+
+#ifdef CONFIG_MSCHUNKS
+
+static inline unsigned long
+chunk_to_addr(unsigned long chunk)
+{
+	unsigned long offset = reloc_offset();
+	struct msChunks *_msChunks = PTRRELOC(&msChunks);
+
+	return chunk << _msChunks->chunk_shift;
+}
+
+static inline unsigned long
+addr_to_chunk(unsigned long addr)
+{
+	unsigned long offset = reloc_offset();
+	struct msChunks *_msChunks = PTRRELOC(&msChunks);
+
+	return addr >> _msChunks->chunk_shift;
+}
+
+static inline unsigned long
+chunk_offset(unsigned long addr)
+{
+	unsigned long offset = reloc_offset();
+	struct msChunks *_msChunks = PTRRELOC(&msChunks);
+
+	return addr & _msChunks->chunk_mask;
+}
+
+static inline unsigned long
+abs_chunk(unsigned long pchunk)
+{
+	unsigned long offset = reloc_offset();
+	struct msChunks *_msChunks = PTRRELOC(&msChunks);
+	if ( pchunk >= _msChunks->num_chunks ) {
+		return pchunk;
+	}
+	return PTRRELOC(_msChunks->abs)[pchunk];
+}
+
+
+static inline unsigned long
+phys_to_absolute(unsigned long pa)
+{
+	return chunk_to_addr(abs_chunk(addr_to_chunk(pa))) + chunk_offset(pa);
+}
+
+static inline unsigned long
+physRpn_to_absRpn(unsigned long rpn)
+{
+	unsigned long pa = rpn << PAGE_SHIFT;
+	unsigned long aa = phys_to_absolute(pa);
+	return (aa >> PAGE_SHIFT);
+}
+
+static inline unsigned long
+absolute_to_phys(unsigned long aa)
+{
+	return lmb_abs_to_phys(aa);
+}
+
+#else  /* !CONFIG_MSCHUNKS */
+
+#define chunk_to_addr(chunk) ((unsigned long)(chunk))
+#define addr_to_chunk(addr) (addr)
+#define chunk_offset(addr) (0)
+#define abs_chunk(pchunk) (pchunk)
+
+#define phys_to_absolute(pa) (pa)
+#define physRpn_to_absRpn(rpn) (rpn)
+#define absolute_to_phys(aa) (aa)
+
+#endif /* !CONFIG_MSCHUNKS */
+
+
+static inline unsigned long
+virt_to_absolute(unsigned long ea)
+{
+	return phys_to_absolute(__pa(ea));
+}
+
+static inline unsigned long
+absolute_to_virt(unsigned long aa)
+{
+	return (unsigned long)__va(absolute_to_phys(aa));
+}
+
+#endif /* _ABS_ADDR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/atomic.h linux/include/asm-ppc64/atomic.h
--- linux.orig/include/asm-ppc64/atomic.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/atomic.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,180 @@
+/*
+ * PowerPC64 atomic operations
+ *
+ * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * 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.
+ */
+
+#ifndef _ASM_PPC64_ATOMIC_H_ 
+#define _ASM_PPC64_ATOMIC_H_
+
+#include <asm/memory.h>
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v,i)		(((v)->counter) = (i))
+
+static __inline__ void atomic_add(int a, atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%3		# atomic_add\n\
+	add	%0,%2,%0\n\
+	stwcx.	%0,0,%3\n\
+	bne-	1b"
+	: "=&r" (t), "=m" (v->counter)
+	: "r" (a), "r" (&v->counter), "m" (v->counter)
+	: "cc");
+}
+
+static __inline__ int atomic_add_return(int a, atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%2		# atomic_add_return\n\
+	add	%0,%1,%0\n\
+	stwcx.	%0,0,%2\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	: "=&r" (t)
+	: "r" (a), "r" (&v->counter)
+	: "cc", "memory");
+
+	return t;
+}
+
+static __inline__ void atomic_sub(int a, atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%3		# atomic_sub\n\
+	subf	%0,%2,%0\n\
+	stwcx.	%0,0,%3\n\
+	bne-	1b"
+	: "=&r" (t), "=m" (v->counter)
+	: "r" (a), "r" (&v->counter), "m" (v->counter)
+	: "cc");
+}
+
+static __inline__ int atomic_sub_return(int a, atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%2		# atomic_sub_return\n\
+	subf	%0,%1,%0\n\
+	stwcx.	%0,0,%2\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	: "=&r" (t)
+	: "r" (a), "r" (&v->counter)
+	: "cc", "memory");
+
+	return t;
+}
+
+static __inline__ void atomic_inc(atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%2		# atomic_inc\n\
+	addic	%0,%0,1\n\
+	stwcx.	%0,0,%2\n\
+	bne-	1b"
+	: "=&r" (t), "=m" (v->counter)
+	: "r" (&v->counter), "m" (v->counter)
+	: "cc");
+}
+
+static __inline__ int atomic_inc_return(atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%1		# atomic_inc_return\n\
+	addic	%0,%0,1\n\
+	stwcx.	%0,0,%1\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	: "=&r" (t)
+	: "r" (&v->counter)
+	: "cc", "memory");
+
+	return t;
+}
+
+static __inline__ void atomic_dec(atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%2		# atomic_dec\n\
+	addic	%0,%0,-1\n\
+	stwcx.	%0,0,%2\n\
+	bne-	1b"
+	: "=&r" (t), "=m" (v->counter)
+	: "r" (&v->counter), "m" (v->counter)
+	: "cc");
+}
+
+static __inline__ int atomic_dec_return(atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%1		# atomic_dec_return\n\
+	addic	%0,%0,-1\n\
+	stwcx.	%0,0,%1\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	: "=&r" (t)
+	: "r" (&v->counter)
+	: "cc", "memory");
+
+	return t;
+}
+
+#define atomic_sub_and_test(a, v)	(atomic_sub_return((a), (v)) == 0)
+#define atomic_dec_and_test(v)		(atomic_dec_return((v)) == 0)
+
+/*
+ * Atomically test *v and decrement if it is greater than 0.
+ * The function returns the old value of *v minus 1.
+ */
+static __inline__ int atomic_dec_if_positive(atomic_t *v)
+{
+	int t;
+
+	__asm__ __volatile__(
+"1:	lwarx	%0,0,%1		# atomic_dec_if_positive\n\
+	addic.	%0,%0,-1\n\
+	blt-	2f\n\
+	stwcx.	%0,0,%1\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	"\n\
+2:"	: "=&r" (t)
+	: "r" (&v->counter)
+	: "cc", "memory");
+
+	return t;
+}
+
+#define smp_mb__before_atomic_dec()     smp_mb()
+#define smp_mb__after_atomic_dec()      smp_mb()
+#define smp_mb__before_atomic_inc()     smp_mb()
+#define smp_mb__after_atomic_inc()      smp_mb()
+
+#endif /* _ASM_PPC64_ATOMIC_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/bitops.h linux/include/asm-ppc64/bitops.h
--- linux.orig/include/asm-ppc64/bitops.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/bitops.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,431 @@
+/*
+ * PowerPC64 atomic bit operations.
+ * Dave Engebretsen, Todd Inglett, Don Reed, Pat McCarthy, Peter Bergner,
+ * Anton Blanchard
+ *
+ * Originally taken from the 32b PPC code.  Modified to use 64b values for
+ * the various counters & memory references.
+ *
+ * Bitops are odd when viewed on big-endian systems.  They were designed
+ * on little endian so the size of the bitset doesn't matter (low order bytes
+ * come first) as long as the bit in question is valid.
+ *
+ * Bits are "tested" often using the C expression (val & (1<<nr)) so we do
+ * our best to stay compatible with that.  The assumption is that val will
+ * be unsigned long for such tests.  As such, we assume the bits are stored
+ * as an array of unsigned long (the usual case is a single unsigned long,
+ * of course).  Here's an example bitset with bit numbering:
+ *
+ *   |63..........0|127........64|195.......128|255.......196|
+ *
+ * This leads to a problem. If an int, short or char is passed as a bitset
+ * it will be a bad memory reference since we want to store in chunks
+ * of unsigned long (64 bits here) size.
+ *
+ * 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.
+ */
+
+#ifndef _PPC64_BITOPS_H
+#define _PPC64_BITOPS_H
+
+#ifdef __KERNEL__
+
+#include <asm/byteorder.h>
+#include <asm/memory.h>
+
+/*
+ * clear_bit doesn't imply a memory barrier
+ */
+#define smp_mb__before_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	smp_mb()
+
+static __inline__ int test_bit(unsigned long nr, __const__ volatile void *addr)
+{
+	return (1UL & (((__const__ long *) addr)[nr >> 6] >> (nr & 63)));
+}
+
+static __inline__ void set_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long old;
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	__asm__ __volatile__(
+"1:	ldarx	%0,0,%3		# set_bit\n\
+	or	%0,%0,%2\n\
+	stdcx.	%0,0,%3\n\
+	bne-	1b"
+	: "=&r" (old), "=m" (*p)
+	: "r" (mask), "r" (p), "m" (*p)
+	: "cc");
+}
+
+static __inline__ void clear_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long old;
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	__asm__ __volatile__(
+"1:	ldarx	%0,0,%3		# clear_bit\n\
+	andc	%0,%0,%2\n\
+	stdcx.	%0,0,%3\n\
+	bne-	1b"
+	: "=&r" (old), "=m" (*p)
+	: "r" (mask), "r" (p), "m" (*p)
+	: "cc");
+}
+
+static __inline__ void change_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long old;
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	__asm__ __volatile__(
+"1:	ldarx	%0,0,%3		# change_bit\n\
+	xor	%0,%0,%2\n\
+	stdcx.	%0,0,%3\n\
+	bne-	1b"
+	: "=&r" (old), "=m" (*p)
+	: "r" (mask), "r" (p), "m" (*p)
+	: "cc");
+}
+
+static __inline__ int test_and_set_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long old, t;
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	__asm__ __volatile__(
+	EIEIO_ON_SMP
+"1:	ldarx	%0,0,%3		# test_and_set_bit\n\
+	or	%1,%0,%2 \n\
+	stdcx.	%1,0,%3 \n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	: "=&r" (old), "=&r" (t)
+	: "r" (mask), "r" (p)
+	: "cc", "memory");
+
+	return (old & mask) != 0;
+}
+
+static __inline__ int test_and_clear_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long old, t;
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	__asm__ __volatile__(
+	EIEIO_ON_SMP
+"1:	ldarx	%0,0,%3		# test_and_clear_bit\n\
+	andc	%1,%0,%2\n\
+	stdcx.	%1,0,%3\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	: "=&r" (old), "=&r" (t)
+	: "r" (mask), "r" (p)
+	: "cc", "memory");
+
+	return (old & mask) != 0;
+}
+
+static __inline__ int test_and_change_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long old, t;
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	__asm__ __volatile__(
+	EIEIO_ON_SMP
+"1:	ldarx	%0,0,%3		# test_and_change_bit\n\
+	xor	%1,%0,%2\n\
+	stdcx.	%1,0,%3\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	: "=&r" (old), "=&r" (t)
+	: "r" (mask), "r" (p)
+	: "cc", "memory");
+
+	return (old & mask) != 0;
+}
+
+/*
+ * non-atomic versions
+ */
+static __inline__ void __set_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	*p |= mask;
+}
+
+static __inline__ void __clear_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	*p &= ~mask;
+}
+
+static __inline__ void __change_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+
+	*p ^= mask;
+}
+
+static __inline__ int __test_and_set_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+	unsigned long old = *p;
+
+	*p = old | mask;
+	return (old & mask) != 0;
+}
+
+static __inline__ int __test_and_clear_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+	unsigned long old = *p;
+
+	*p = old & ~mask;
+	return (old & mask) != 0;
+}
+
+static __inline__ int __test_and_change_bit(unsigned long nr, volatile void *addr)
+{
+	unsigned long mask = 1UL << (nr & 0x3f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
+	unsigned long old = *p;
+
+	*p = old ^ mask;
+	return (old & mask) != 0;
+}
+
+/*
+ * Return the zero-based bit position (from RIGHT TO LEFT, 63 -> 0) of the
+ * most significant (left-most) 1-bit in a double word.
+ */
+static __inline__ int __ilog2(unsigned long x)
+{
+	int lz;
+
+	asm ("cntlzd %0,%1" : "=r" (lz) : "r" (x));
+	return 63 - lz;
+}
+
+/* Return the zero-based bit position
+ *  from RIGHT TO LEFT  63 --> 0
+ *   of the most significant (left-most) 1-bit in an 8-byte area.
+ */
+static __inline__ long cnt_trailing_zeros(unsigned long mask)
+{
+        long cnt;
+
+	asm(
+"	addi	%0,%1,-1	\n\
+	andc	%0,%0,%1	\n\
+	cntlzd	%0,%0		\n\
+	subfic	%0,%0,64"
+	: "=r" (cnt)
+	: "r" (mask));
+	return cnt;
+}
+
+
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ *    Determines the bit position of the LEAST significant
+ *    (rightmost) 0 bit in the specified DOUBLE-WORD.
+ *    The returned bit position will be zero-based, starting
+ *    from the right side (63 - 0).
+ *    the code should check against ~0UL first..
+ */
+static __inline__ unsigned long ffz(unsigned long x)
+{
+	u32  tempRC;
+
+	/* Change all of x's 1s to 0s and 0s to 1s in x.
+	 * And insure at least 1 zero exists in the 8 byte area.
+	 */
+	if ((x = ~x) == 0)
+		/* no zero exists anywhere in the 8 byte area. */
+		return 64;
+
+	/* Calculate the bit position of the least significant '1' bit in x
+	 * (since x has been changed this will actually be the least
+	 * significant '0' bit in the original x).
+	 * Note: (x & -x) gives us a mask that is the LEAST significant
+	 * (RIGHT-most) 1-bit of the value in x.
+	 */
+	tempRC = __ilog2(x & -x);
+
+	return tempRC;
+}
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static __inline__ int ffs(int x)
+{
+	int result = ffz(~x);
+	return x ? result+1 : 0;
+}
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+extern unsigned long find_next_zero_bit(void * addr, unsigned long size,
+					unsigned long offset);
+/*
+ * The optimizer actually does good code for this case..
+ */
+#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
+
+/* Bitmap functions for the ext2 filesystem. */
+#define _EXT2_HAVE_ASM_BITOPS_
+
+static __inline__ int ext2_set_bit(int nr, void* addr)
+{
+	/* This method needs to take into account the fact that the ext2 file system represents
+	 *  it's bitmaps as "little endian" unsigned integers.
+	 * Note: this method is not atomic, but ext2 does not need it to be.
+	 */
+	int mask;
+	int oldbit;
+	unsigned char* ADDR = (unsigned char*) addr;
+
+	/* Determine the BYTE containing the specified bit
+	 * (nr) - important as if we go to a byte there are no
+	 * little endian concerns.
+	 */
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);  /* Create a mask to the bit within this byte. */
+	oldbit = *ADDR & mask;  /* Save the bit's previous value. */
+	*ADDR |= mask;  /* Turn the bit on. */
+	return oldbit;  /* Return the bit's previous value. */
+}
+
+static __inline__ int ext2_clear_bit(int nr, void* addr)
+{
+	/* This method needs to take into account the fact that the ext2 file system represents
+	 * | it's bitmaps as "little endian" unsigned integers.
+	 * Note: this method is not atomic, but ext2 does not need it to be.
+	 */
+        int     mask;
+        int oldbit;
+        unsigned char* ADDR = (unsigned char*) addr;
+
+	/* Determine the BYTE containing the specified bit (nr)
+	 *  - important as if we go to a byte there are no little endian concerns.
+	 */
+        ADDR += nr >> 3;
+        mask = 1 << (nr & 0x07);  /* Create a mask to the bit within this byte. */
+        oldbit = *ADDR & mask;  /* Save the bit's previous value. */
+        *ADDR = *ADDR & ~mask;  /* Turn the bit off. */
+        return oldbit;  /* Return the bit's previous value. */
+}
+
+static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
+{
+	/* This method needs to take into account the fact that the ext2 file system represents
+	 * | it's bitmaps as "little endian" unsigned integers.
+	 * Determine the BYTE containing the specified bit (nr),
+	 *   then shift to the right the correct number of bits and return that bit's value.
+	 */
+	__const__ unsigned char	*ADDR = (__const__ unsigned char *) addr;
+	return (ADDR[nr >> 3] >> (nr & 7)) & 1;
+}
+
+/* Returns the bit position of the most significant 1 bit in a WORD. */
+static __inline__ int ext2_ilog2(unsigned int x)
+{
+        int lz;
+
+        asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
+        return 31 - lz;
+}
+
+/* ext2_ffz = ext2's Find First Zero.
+ *    Determines the bit position of the LEAST significant (rightmost) 0 bit in the specified WORD.
+ *    The returned bit position will be zero-based, starting from the right side (31 - 0).
+ */
+static __inline__ int ext2_ffz(unsigned int x)
+{
+	u32  tempRC;
+	/* Change all of x's 1s to 0s and 0s to 1s in x.  And insure at least 1 zero exists in the word. */
+	if ((x = ~x) == 0)
+		/* no zero exists anywhere in the 4 byte area. */
+		return 32;
+	/* Calculate the bit position of the least significant '1' bit in x
+	 * (since x has been changed this will actually be the least
+	 * significant '0' bit in the original x).
+	 * Note: (x & -x) gives us a mask that is the LEAST significant
+	 * (RIGHT-most) 1-bit of the value in x.
+	 */
+	tempRC = ext2_ilog2(x & -x);
+	return tempRC;
+}
+
+static __inline__ u32 ext2_find_next_zero_bit(void* addr, u32 size, u32 offset)
+{
+	/* This method needs to take into account the fact that the ext2 file system represents
+	 * | it's bitmaps as "little endian" unsigned integers.
+	 */
+        unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+        unsigned int result = offset & ~31;
+        unsigned int tmp;
+
+        if (offset >= size)
+                return size;
+        size -= result;
+        offset &= 31;
+        if (offset) {
+                tmp = cpu_to_le32p(p++);
+                tmp |= ~0U >> (32-offset); /* bug or feature ? */
+                if (size < 32)
+                        goto found_first;
+                if (tmp != ~0)
+                        goto found_middle;
+                size -= 32;
+                result += 32;
+        }
+        while (size >= 32) {
+                if ((tmp = cpu_to_le32p(p++)) != ~0)
+                        goto found_middle;
+                result += 32;
+                size -= 32;
+        }
+        if (!size)
+                return result;
+        tmp = cpu_to_le32p(p);
+found_first:
+        tmp |= ~0 << size;
+        if (tmp == ~0)          /* Are any bits zero? */
+                return result + size; /* Nope. */
+found_middle:
+        return result + ext2_ffz(tmp);
+}
+
+#define ext2_find_first_zero_bit(addr, size) ext2_find_next_zero_bit((addr), (size), 0)
+
+#endif /* __KERNEL__ */
+#endif /* _PPC64_BITOPS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/bootinfo.h linux/include/asm-ppc64/bootinfo.h
--- linux.orig/include/asm-ppc64/bootinfo.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/bootinfo.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,70 @@
+/*
+ * Non-machine dependent bootinfo structure.  Basic idea
+ * borrowed from the m68k.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@ppc.kernel.org>
+ * Copyright (c) 2001 PPC64 Team, IBM Corp 
+ *
+ * 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.
+ */
+
+
+#ifndef _PPC64_BOOTINFO_H
+#define _PPC64_BOOTINFO_H
+
+#include <asm/types.h>
+
+/* We use a u32 for the type of the fields since they're written by
+ * the bootloader which is a 32-bit process and read by the kernel
+ * which is a 64-bit process.  This way they can both agree on the
+ * size of the type.
+ */
+typedef u32 bi_rec_field;
+
+struct bi_record {
+	bi_rec_field tag;	/* tag ID */
+	bi_rec_field size;	/* size of record (in bytes) */
+	bi_rec_field data[0];	/* data */
+};
+
+#define BI_FIRST		0x1010  /* first record - marker */
+#define BI_LAST			0x1011	/* last record - marker */
+#define BI_CMD_LINE		0x1012
+#define BI_BOOTLOADER_ID	0x1013
+#define BI_INITRD		0x1014
+#define BI_SYSMAP		0x1015
+#define BI_MACHTYPE		0x1016
+
+static __inline__ struct bi_record * bi_rec_init(unsigned long addr)
+{
+	struct bi_record *bi_recs;
+	bi_recs = (struct bi_record *)_ALIGN(addr, PAGE_SIZE);
+	bi_recs->size = 0;
+	return bi_recs;
+}
+
+static __inline__ struct bi_record * bi_rec_alloc(struct bi_record *rec,
+						  unsigned long args)
+{
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	rec->size = sizeof(struct bi_record) + args*sizeof(bi_rec_field);
+	return rec;
+}
+
+static __inline__ struct bi_record * bi_rec_alloc_bytes(struct bi_record *rec,
+							unsigned long bytes)
+{
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	rec->size = sizeof(struct bi_record) + bytes;
+	return rec;
+}
+
+static __inline__ struct bi_record * bi_rec_next(struct bi_record *rec)
+{
+	return (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+#endif /* _PPC64_BOOTINFO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/bugs.h linux/include/asm-ppc64/bugs.h
--- linux.orig/include/asm-ppc64/bugs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/bugs.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,8 @@
+/*
+ * This file is included by 'init/main.c' to check for architecture-dependent
+ * bugs.
+ *
+ */
+
+static void check_bugs(void) {
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/byteorder.h linux/include/asm-ppc64/byteorder.h
--- linux.orig/include/asm-ppc64/byteorder.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/byteorder.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,95 @@
+#ifndef _PPC64_BYTEORDER_H
+#define _PPC64_BYTEORDER_H
+
+/*
+ *  
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/types.h>
+
+#ifdef __GNUC__
+
+static __inline__ __u16 ld_le16(const volatile __u16 *addr)
+{
+	__u16 val;
+
+	__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+	return val;
+}
+
+static __inline__ void st_le16(volatile __u16 *addr, const __u16 val)
+{
+	__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+}
+
+static __inline__ __u32 ld_le32(const volatile __u32 *addr)
+{
+	__u32 val;
+
+	__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+	return val;
+}
+
+static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
+{
+	__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+}
+
+#if 0
+static __inline__ __const__ __u16 ___arch__swab16(__u16 value)
+{
+	__u16 result;
+
+	__asm__("rlwimi %0,%1,8,16,23"
+	    : "=r" (result)
+	    : "r" (value), "0" (value >> 8));
+	return result;
+}
+
+static __inline__ __const__ __u32 ___arch__swab32(__u32 value)
+{
+	__u32 result;
+
+	__asm__("rlwimi %0,%1,24,16,23\n\t"
+	    "rlwimi %0,%1,8,8,15\n\t"
+	    "rlwimi %0,%1,24,0,7"
+	    : "=r" (result)
+	    : "r" (value), "0" (value >> 24));
+	return result;
+}
+
+static __inline__ __const__ __u64 ___arch__swab64(__u64 value)
+{
+	__u64 result;
+#error implement me
+}
+
+#define __arch__swab16(x) ___arch__swab16(x)
+#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab64(x) ___arch__swab64(x)
+
+#endif
+
+/* The same, but returns converted value from the location pointer by addr. */
+#define __arch__swab16p(addr) ld_le16(addr)
+#define __arch__swab32p(addr) ld_le32(addr)
+
+/* The same, but do the conversion in situ, ie. put the value back to addr. */
+#define __arch__swab16s(addr) st_le16(addr,*addr)
+#define __arch__swab32s(addr) st_le32(addr,*addr)
+
+#endif /* __GNUC__ */
+
+/* MIKEC: What does __BYTEORDER_HAS_U64__ mean? */
+#ifndef __STRICT_ANSI__
+#define __BYTEORDER_HAS_U64__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _PPC64_BYTEORDER_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/cache.h linux/include/asm-ppc64/cache.h
--- linux.orig/include/asm-ppc64/cache.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/cache.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,13 @@
+/*
+ * 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.
+ */
+#ifndef __ARCH_PPC64_CACHE_H
+#define __ARCH_PPC64_CACHE_H
+
+/* bytes per L1 cache line */
+#define L1_CACHE_BYTES	128
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/checksum.h linux/include/asm-ppc64/checksum.h
--- linux.orig/include/asm-ppc64/checksum.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/checksum.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,115 @@
+#ifndef _PPC64_CHECKSUM_H
+#define _PPC64_CHECKSUM_H
+
+/*
+ * 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 is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.  ihl is the number
+ * of 32-bit words and is always >= 5.
+ */
+extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+extern unsigned short csum_tcpudp_magic(unsigned long saddr,
+					unsigned long daddr,
+					unsigned short len,
+					unsigned short proto,
+					unsigned int sum);
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern unsigned int csum_partial(const unsigned char * buff, int len,
+				 unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src to dst while it
+ * checksums
+ */
+unsigned int csum_partial_copy(const char *src, char *dst, 
+			       int len, unsigned int sum);
+
+extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
+					      int len, unsigned int sum,
+					      int *src_err, int *dst_err);
+/*
+ * the same as csum_partial, but copies from user space.
+ */
+
+unsigned int csum_partial_copy_fromuser(const char *src, 
+					char *dst, 
+					int len, 
+					unsigned int sum,
+					int *src_err);
+
+unsigned int csum_partial_copy_nocheck(const char *src, 
+				       char *dst, 
+				       int len, 
+				       unsigned int sum);
+
+/*
+ * turns a 32-bit partial checksum (e.g. from csum_partial) into a
+ * 1's complement 16-bit checksum.
+ */
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	unsigned int tmp;
+
+	/* swap the two 16-bit halves of sum */
+	__asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));
+	/* if there is a carry from adding the two 16-bit halves,
+	   it will carry from the lower half into the upper half,
+	   giving us the correct sum in the upper half. */
+	sum = ~(sum + tmp) >> 16;
+	return sum;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
+	return csum_fold(csum_partial(buff, len, 0));
+}
+
+#define csum_partial_copy_from_user(src, dst, len, sum, errp)   \
+        csum_partial_copy_generic((src), (dst), (len), (sum), (errp), 0)
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)   \
+        csum_partial_copy_generic((src), (dst), (len), (sum), 0, 0)
+
+static inline u32 csum_tcpudp_nofold(u32 saddr,
+                                     u32 daddr,
+                                     unsigned short len,
+                                     unsigned short proto,
+                                     unsigned int sum)
+{
+	unsigned long s = sum;
+
+	s += saddr;
+	s += daddr;
+	s += (proto << 16) + len;
+	s += (s >> 32);
+	return (u32) s;
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/current.h linux/include/asm-ppc64/current.h
--- linux.orig/include/asm-ppc64/current.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/current.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,15 @@
+#ifndef _PPC64_CURRENT_H
+#define _PPC64_CURRENT_H
+
+/*
+ * 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.
+ *
+ * Use r13 for current since the ppc64 ABI reserves it - Anton
+ */
+
+register struct task_struct *current asm ("r13");
+
+#endif /* !(_PPC64_CURRENT_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/delay.h linux/include/asm-ppc64/delay.h
--- linux.orig/include/asm-ppc64/delay.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/delay.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,46 @@
+#ifndef _PPC64_DELAY_H
+#define _PPC64_DELAY_H
+
+/*
+ * Copyright 1996, Paul Mackerras.
+ *
+ * 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.
+ *
+ * PPC64 Support added by Dave Engebretsen, Todd Inglett, Mike Corrigan,
+ * Anton Blanchard.
+ */
+
+extern unsigned long tb_ticks_per_usec;
+
+/* define these here to prevent circular dependencies */ 
+#define __HMT_low()	asm volatile("or 1,1,1")
+#define __HMT_medium()	asm volatile("or 2,2,2")
+
+static inline unsigned long __get_tb(void)
+{
+	unsigned long rval;
+
+	asm volatile("mftb %0" : "=r" (rval));
+	return rval;
+}
+
+static inline void __delay(unsigned long loops)
+{
+	unsigned long start = __get_tb();
+
+	while((__get_tb()-start) < loops)
+		__HMT_low();
+}
+
+static inline void udelay(unsigned long usecs)
+{
+	unsigned long loops = tb_ticks_per_usec * usecs;
+
+	__delay(loops);
+	__HMT_medium();
+}
+
+#endif /* _PPC64_DELAY_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/div64.h linux/include/asm-ppc64/div64.h
--- linux.orig/include/asm-ppc64/div64.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/div64.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,18 @@
+#ifndef __PPC_DIV64
+#define __PPC_DIV64
+
+/* Copyright 2001 PPC64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+#define do_div(n,base) ({ \
+	int __res; \
+	__res = ((unsigned long) (n)) % (unsigned) (base); \
+	(n) = ((unsigned long) (n)) / (unsigned) (base); \
+	__res; })
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/dma.h linux/include/asm-ppc64/dma.h
--- linux.orig/include/asm-ppc64/dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/dma.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,326 @@
+/* 
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen
+ * and John Boyd, Nov. 1992.
+ * Changes for ppc sound by Christoph Nadig
+ *
+ * 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.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+#include <linux/config.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+#include <asm/system.h>
+
+#ifndef MAX_DMA_CHANNELS
+#define MAX_DMA_CHANNELS	8
+#endif
+
+/* The maximum address that we can perform a DMA transfer to on this platform */
+/* Doesn't really apply... */
+#define MAX_DMA_ADDRESS  (~0UL)
+
+#define dma_outb	outb
+#define dma_inb		inb
+
+/*
+ * NOTES about DMA transfers:
+ *
+ *  controller 1: channels 0-3, byte operations, ports 00-1F
+ *  controller 2: channels 4-7, word operations, ports C0-DF
+ *
+ *  - ALL registers are 8 bits only, regardless of transfer size
+ *  - channel 4 is not used - cascades 1 into 2.
+ *  - channels 0-3 are byte - addresses/counts are for physical bytes
+ *  - channels 5-7 are word - addresses/counts are for physical words
+ *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+ *  - transfer count loaded to registers is 1 less than actual count
+ *  - controller 2 offsets are all even (2x offsets for controller 1)
+ *  - page registers for 5-7 don't use data bit 0, represent 128K pages
+ *  - page registers for 0-3 use bit 0, represent 64K pages
+ *
+ * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory.  
+ * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing.
+ * Note that addresses loaded into registers must be _physical_ addresses,
+ * not logical addresses (which may differ if paging is active).
+ *
+ *  Address mapping for channels 0-3:
+ *
+ *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
+ *    |  ...  |   |  ... |   |  ... |
+ *    |  ...  |   |  ... |   |  ... |
+ *    |  ...  |   |  ... |   |  ... |
+ *   P7  ...  P0  A7 ... A0  A7 ... A0   
+ * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
+ *
+ *  Address mapping for channels 5-7:
+ *
+ *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
+ *    |  ...  |   \   \   ... \  \  \  ... \  \
+ *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
+ *    |  ...  |     \   \   ... \  \  \  ... \
+ *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
+ * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
+ *
+ * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+ * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+ * the hardware level, so odd-byte transfers aren't possible).
+ *
+ * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+ * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation. 
+ *
+ */
+
+/* 8237 DMA controllers */
+#define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
+#define IO_DMA2_BASE	0xC0	/* 16 bit master DMA, ch 4(=slave input)..7 */
+
+/* DMA controller registers */
+#define DMA1_CMD_REG		0x08	/* command register (w) */
+#define DMA1_STAT_REG		0x08	/* status register (r) */
+#define DMA1_REQ_REG            0x09    /* request register (w) */
+#define DMA1_MASK_REG		0x0A	/* single-channel mask (w) */
+#define DMA1_MODE_REG		0x0B	/* mode register (w) */
+#define DMA1_CLEAR_FF_REG	0x0C	/* clear pointer flip-flop (w) */
+#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
+#define DMA1_RESET_REG		0x0D	/* Master Clear (w) */
+#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
+#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
+
+#define DMA2_CMD_REG		0xD0	/* command register (w) */
+#define DMA2_STAT_REG		0xD0	/* status register (r) */
+#define DMA2_REQ_REG            0xD2    /* request register (w) */
+#define DMA2_MASK_REG		0xD4	/* single-channel mask (w) */
+#define DMA2_MODE_REG		0xD6	/* mode register (w) */
+#define DMA2_CLEAR_FF_REG	0xD8	/* clear pointer flip-flop (w) */
+#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
+#define DMA2_RESET_REG		0xDA	/* Master Clear (w) */
+#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
+#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
+
+#define DMA_ADDR_0              0x00    /* DMA address registers */
+#define DMA_ADDR_1              0x02
+#define DMA_ADDR_2              0x04
+#define DMA_ADDR_3              0x06
+#define DMA_ADDR_4              0xC0
+#define DMA_ADDR_5              0xC4
+#define DMA_ADDR_6              0xC8
+#define DMA_ADDR_7              0xCC
+
+#define DMA_CNT_0               0x01    /* DMA count registers */
+#define DMA_CNT_1               0x03
+#define DMA_CNT_2               0x05
+#define DMA_CNT_3               0x07
+#define DMA_CNT_4               0xC2
+#define DMA_CNT_5               0xC6
+#define DMA_CNT_6               0xCA
+#define DMA_CNT_7               0xCE
+
+#define DMA_LO_PAGE_0              0x87    /* DMA page registers */
+#define DMA_LO_PAGE_1              0x83
+#define DMA_LO_PAGE_2              0x81
+#define DMA_LO_PAGE_3              0x82
+#define DMA_LO_PAGE_5              0x8B
+#define DMA_LO_PAGE_6              0x89
+#define DMA_LO_PAGE_7              0x8A
+
+#define DMA_HI_PAGE_0              0x487    /* DMA page registers */
+#define DMA_HI_PAGE_1              0x483
+#define DMA_HI_PAGE_2              0x481
+#define DMA_HI_PAGE_3              0x482
+#define DMA_HI_PAGE_5              0x48B
+#define DMA_HI_PAGE_6              0x489
+#define DMA_HI_PAGE_7              0x48A
+
+#define DMA1_EXT_REG               0x40B
+#define DMA2_EXT_REG               0x4D6
+
+#define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+#define DMA_AUTOINIT   	 0x10
+
+extern spinlock_t  dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_spin_lock, flags);
+	return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+	unsigned char ucDmaCmd=0x00;
+
+	if (dmanr != 4)
+	{
+		dma_outb(0, DMA2_MASK_REG);  /* This may not be enabled */
+		dma_outb(ucDmaCmd, DMA2_CMD_REG);  /* Enable group */
+	}
+	if (dmanr<=3)
+	{
+		dma_outb(dmanr,  DMA1_MASK_REG);
+		dma_outb(ucDmaCmd, DMA1_CMD_REG);  /* Enable group */
+	} else
+	{
+		dma_outb(dmanr & 3,  DMA2_MASK_REG);
+	}
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+	if (dmanr<=3)
+		dma_outb(dmanr | 4,  DMA1_MASK_REG);
+	else
+		dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+	if (dmanr<=3)
+		dma_outb(0,  DMA1_CLEAR_FF_REG);
+	else
+		dma_outb(0,  DMA2_CLEAR_FF_REG);
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+	if (dmanr<=3)
+		dma_outb(mode | dmanr,  DMA1_MODE_REG);
+	else
+		dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
+}
+
+/* Set only the page register bits of the transfer address.
+ * This is used for successive transfers when we know the contents of
+ * the lower 16 bits of the DMA current address register, but a 64k boundary
+ * may have been crossed.
+ */
+static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
+{
+	switch(dmanr) {
+		case 0:
+			dma_outb(pagenr, DMA_LO_PAGE_0);
+                        dma_outb(pagenr>>8, DMA_HI_PAGE_0);
+			break;
+		case 1:
+			dma_outb(pagenr, DMA_LO_PAGE_1);
+                        dma_outb(pagenr>>8, DMA_HI_PAGE_1);
+			break;
+		case 2:
+			dma_outb(pagenr, DMA_LO_PAGE_2);
+			dma_outb(pagenr>>8, DMA_HI_PAGE_2); 
+			break;
+		case 3:
+			dma_outb(pagenr, DMA_LO_PAGE_3);
+			dma_outb(pagenr>>8, DMA_HI_PAGE_3); 
+			break;
+	        case 5:
+		        dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5);
+                        dma_outb(pagenr>>8, DMA_HI_PAGE_5);
+			break;
+		case 6:
+		        dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6);
+			dma_outb(pagenr>>8, DMA_HI_PAGE_6);
+			break;
+		case 7:
+		        dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7);
+			dma_outb(pagenr>>8, DMA_HI_PAGE_7);
+		  break;
+	}
+}
+
+
+/* Set transfer address & page bits for specific DMA channel.
+ * Assumes dma flipflop is clear.
+ */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
+{
+	if (dmanr <= 3)  {
+	    dma_outb( phys & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+            dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+	}  else  {
+	    dma_outb( (phys>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+	    dma_outb( (phys>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+	}
+	set_dma_page(dmanr, phys>>16);
+}
+
+
+/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+ * a specific DMA channel.
+ * You must ensure the parameters are valid.
+ * NOTE: from a manual: "the number of transfers is one more
+ * than the initial word count"! This is taken into account.
+ * Assumes dma flip-flop is clear.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+        count--;
+	if (dmanr <= 3)  {
+	    dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+	    dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+        } else {
+	    dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+	    dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+        }
+}
+
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
+ * Assumes DMA flip-flop is clear.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+	unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+					 : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+
+	/* using short to get 16-bit wrap around */
+	unsigned short count;
+
+	count = 1 + dma_inb(io_port);
+	count += dma_inb(io_port) << 8;
+	
+	return (dmanr <= 3)? count : (count<<1);
+}
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;                                        
+#else                                                         
+#define isa_dma_bridge_buggy   (0)
+#endif
+#endif /* _ASM_DMA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/eeh.h linux/include/asm-ppc64/eeh.h
--- linux.orig/include/asm-ppc64/eeh.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/eeh.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,152 @@
+/* 
+ * eeh.h
+ * Copyright (C) 2001  Dave Engebretsen & Todd Inglett IBM 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
+ */
+
+/* Start Change Log
+ * 2001/10/27 : engebret : Created.
+ * End Change Log 
+ */
+
+#ifndef _EEH_H
+#define _EEH_H
+
+struct pci_dev;
+
+#define IO_UNMAPPED_REGION_ID 0xaUL
+
+#define IO_TOKEN_TO_ADDR(token) ((((unsigned long)(token)) & 0xFFFFFFFF) | (0xEUL << 60))
+/* Flag bits encoded in the 3 unused function bits of devfn */
+#define EEH_TOKEN_DISABLED (1UL << 34UL)	/* eeh is disabled for this token */
+#define IS_EEH_TOKEN_DISABLED(token) ((unsigned long)(token) & EEH_TOKEN_DISABLED)
+
+#define EEH_STATE_OVERRIDE 1   /* IOA does not require eeh traps */
+#define EEH_STATE_FAILURE  16  /* */
+
+/* This is for profiling only */
+extern unsigned long eeh_total_mmio_ffs;
+
+extern int eeh_implemented;
+
+void eeh_init(void);
+static inline int is_eeh_implemented(void) { return eeh_implemented; }
+int eeh_get_state(unsigned long ea);
+unsigned long eeh_check_failure(void *token, unsigned long val);
+
+#define EEH_DISABLE		0
+#define EEH_ENABLE		1
+#define EEH_RELEASE_LOADSTORE	2
+#define EEH_RELEASE_DMA		3
+int eeh_set_option(struct pci_dev *dev, int options);
+
+/* Given a PCI device check if eeh should be configured or not.
+ * This may look at firmware properties and/or kernel cmdline options.
+ */
+int is_eeh_configured(struct pci_dev *dev);
+
+/* Generate an EEH token.
+ * The high nibble of the offset is cleared, otherwise bounds checking is performed.
+ * Use IO_TOKEN_TO_ADDR(token) to translate this token back to a mapped virtual addr.
+ * Do NOT do this to perform IO -- use the read/write macros!
+ */
+unsigned long eeh_token(unsigned long phb,
+			unsigned long bus,
+			unsigned long devfn,
+			unsigned long offset);
+
+extern void *memcpy(void *, const void *, unsigned long);
+extern void *memset(void *,int, unsigned long);
+
+/* EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
+ *
+ * Order this macro for performance.
+ * If EEH is off for a device and it is a memory BAR, ioremap will
+ * map it to the IOREGION.  In this case addr == vaddr and since these
+ * should be in registers we compare them first.  Next we check for
+ * all ones which is perhaps fastest as ~val.  Finally we weed out
+ * EEH disabled IO BARs.
+ *
+ * If this macro yields TRUE, the caller relays to eeh_check_failure()
+ * which does further tests out of line.
+ */
+/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && ~(val) == 0 && !IS_EEH_TOKEN_DISABLED(addr)) */
+/* This version is rearranged to collect some profiling data */
+#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (~(val) == 0 && (++eeh_total_mmio_ffs, (vaddr) != (addr) && !IS_EEH_TOKEN_DISABLED(addr)))
+
+/* 
+ * MMIO read/write operations with EEH support.
+ *
+ * addr: 64b token of the form 0xA0PPBBDDyyyyyyyy
+ *       0xA0     : Unmapped MMIO region
+ *       PP       : PHB index (starting at zero)
+ *	 BB	  : PCI Bus number under given PHB
+ *	 DD	  : PCI devfn under given bus
+ *       yyyyyyyy : Virtual address offset
+ * 
+ * An actual virtual address is produced from this token
+ * by masking into the form:
+ *   0xE0000000yyyyyyyy
+ */
+static inline u8 eeh_readb(void *addr) {
+	volatile u8 *vaddr = (volatile u8 *)IO_TOKEN_TO_ADDR(addr);
+	u8 val = in_8(vaddr);
+	if (EEH_POSSIBLE_ERROR(addr, vaddr, val))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_writeb(u8 val, void *addr) {
+	volatile u8 *vaddr = (volatile u8 *)IO_TOKEN_TO_ADDR(addr);
+	out_8(vaddr, val);
+}
+static inline u16 eeh_readw(void *addr) {
+	volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
+	u16 val = in_le16(vaddr);
+	if (EEH_POSSIBLE_ERROR(addr, vaddr, val))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_writew(u16 val, void *addr) {
+	volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
+	out_le16(vaddr, val);
+}
+static inline u32 eeh_readl(void *addr) {
+	volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
+	u32 val = in_le32(vaddr);
+	if (EEH_POSSIBLE_ERROR(addr, vaddr, val))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_writel(u32 val, void *addr) {
+	volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
+	out_le32(vaddr, val);
+}
+
+static inline void eeh_memset_io(void *addr, int c, unsigned long n) {
+	void *vaddr = (void *)IO_TOKEN_TO_ADDR(addr);
+	memset(vaddr, c, n);
+}
+static inline void eeh_memcpy_fromio(void *dest, void *src, unsigned long n) {
+	void *vsrc = (void *)IO_TOKEN_TO_ADDR(src);
+	memcpy(dest, vsrc, n);
+	/* look for ffff's here at dest[n] */
+}
+static inline void eeh_memcpy_toio(void *dest, void *src, unsigned long n) {
+	void *vdest = (void *)IO_TOKEN_TO_ADDR(dest);
+	memcpy(vdest, src, n);
+}
+
+#endif /* _EEH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/elf.h linux/include/asm-ppc64/elf.h
--- linux.orig/include/asm-ppc64/elf.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/elf.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,149 @@
+#ifndef __PPC64_ELF_H
+#define __PPC64_ELF_H
+
+/*
+ * ELF register definitions..
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <asm/ptrace.h>
+
+#define ELF_NGREG	48	/* includes nip, msr, lr, etc. */
+#define ELF_NFPREG	33	/* includes fpscr */
+#define ELF_NVRREG	33	/* includes vscr */
+
+typedef unsigned long elf_greg_t64;
+typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
+
+typedef unsigned int elf_greg_t32;
+typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#ifndef ELF_ARCH
+# define ELF_ARCH	EM_PPC64
+# define ELF_CLASS	ELFCLASS64
+# define ELF_DATA	ELFDATA2MSB
+  typedef elf_greg_t64 elf_greg_t;
+  typedef elf_gregset_t64 elf_gregset_t;
+# define elf_addr_t unsigned long
+# define elf_caddr_t char *
+#else
+  /* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */
+  typedef elf_greg_t32 elf_greg_t;
+  typedef elf_gregset_t32 elf_gregset_t;
+# define elf_addr_t u32
+# define elf_caddr_t u32
+#endif
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         (0x08000000)
+
+/* Common routine for both 32-bit and 64-bit processes */
+#define ELF_CORE_COPY_REGS(gregs, regs) elf_core_copy_regs(gregs, regs);
+static inline void
+elf_core_copy_regs(elf_gregset_t dstRegs, struct pt_regs* srcRegs)
+{
+	int i;
+
+	int numGPRS = ((sizeof(struct pt_regs)/sizeof(elf_greg_t64)) < ELF_NGREG) ? (sizeof(struct pt_regs)/sizeof(elf_greg_t64)) : ELF_NGREG;
+
+	for (i=0; i < numGPRS; i++)
+		dstRegs[i] = (elf_greg_t)((elf_greg_t64 *)srcRegs)[i];
+}
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  This could be done in userspace,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM	(NULL)
+
+
+#define ELF_PLAT_INIT(_r, load_addr)	do { \
+	memset(_r->gpr, 0, sizeof(_r->gpr)); \
+	_r->ctr = _r->link = _r->xer = _r->ccr = 0; \
+	_r->gpr[2] = load_addr; \
+} while (0)
+
+
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2)				\
+do {	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
+		current->thread.flags |= PPC_FLAG_32BIT;	\
+	else							\
+		current->thread.flags &= ~PPC_FLAG_32BIT;	\
+	if (ibcs2)						\
+		set_personality(PER_SVR4);			\
+	else if (current->personality != PER_LINUX32)		\
+		set_personality(PER_LINUX);			\
+} while (0)
+#endif
+
+/*
+ * We need to put in some extra aux table entries to tell glibc what
+ * the cache block size is, so it can use the dcbz instruction safely.
+ */
+#define AT_DCACHEBSIZE		19
+#define AT_ICACHEBSIZE		20
+#define AT_UCACHEBSIZE		21
+/* A special ignored type value for PPC, for glibc compatibility.  */
+#define AT_IGNOREPPC		22
+
+extern int dcache_bsize;
+extern int icache_bsize;
+extern int ucache_bsize;
+
+/*
+ * The requirements here are:
+ * - keep the final alignment of sp (sp & 0xf)
+ * - make sure the 32-bit value at the first 16 byte aligned position of
+ *   AUXV is greater than 16 for glibc compatibility.
+ *   AT_IGNOREPPC is used for that.
+ * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
+ *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+ */
+#define DLINFO_ARCH_ITEMS	3
+#define ARCH_DLINFO							\
+do {									\
+	sp -= DLINFO_ARCH_ITEMS * 2;					\
+	NEW_AUX_ENT(0, AT_DCACHEBSIZE, dcache_bsize);			\
+	NEW_AUX_ENT(1, AT_ICACHEBSIZE, icache_bsize);			\
+	NEW_AUX_ENT(2, AT_UCACHEBSIZE, ucache_bsize);			\
+	/*								\
+	 * Now handle glibc compatibility.				\
+	 */								\
+	sp -= 2*2;							\
+	NEW_AUX_ENT(0, AT_IGNOREPPC, AT_IGNOREPPC);			\
+	NEW_AUX_ENT(1, AT_IGNOREPPC, AT_IGNOREPPC);			\
+ } while (0)
+
+#endif /* __PPC64_ELF_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/errno.h linux/include/asm-ppc64/errno.h
--- linux.orig/include/asm-ppc64/errno.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/errno.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,145 @@
+#ifndef _PPC64_ERRNO_H
+#define _PPC64_ERRNO_H
+
+/* 
+ * 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.
+ */
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+#define	EDEADLOCK	58	/* File locking deadlock error */
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+/* Should never be seen by user programs */
+#define ERESTARTSYS	512
+#define ERESTARTNOINTR	513
+#define ERESTARTNOHAND	514	/* restart if no handler.. */
+#define ENOIOCTLCMD	515	/* No ioctl command */
+
+#define _LAST_ERRNO	515
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/fcntl.h linux/include/asm-ppc64/fcntl.h
--- linux.orig/include/asm-ppc64/fcntl.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/fcntl.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,99 @@
+#ifndef _PPC64_FCNTL_H
+#define _PPC64_FCNTL_H
+
+/*
+ * 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.
+ */
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	   0003
+#define O_RDONLY	     00
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* not fcntl */
+#define O_EXCL		   0200	/* not fcntl */
+#define O_NOCTTY	   0400	/* not fcntl */
+#define O_TRUNC		  01000	/* not fcntl */
+#define O_APPEND	  02000
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		 010000
+#define FASYNC		 020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY      040000	/* must be a directory */
+#define O_NOFOLLOW      0100000	/* don't follow links */
+#define O_LARGEFILE     0200000
+#define O_DIRECT	0400000	/* direct disk access hint - currently ignored */
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+#ifdef __KERNEL__
+#define F_POSIX		1
+#define F_FLOCK		2
+#define F_BROKEN	4	/* broken flock() emulation */
+#endif /* __KERNEL__ */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* _PPC64_FCNTL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/flight_recorder.h linux/include/asm-ppc64/flight_recorder.h
--- linux.orig/include/asm-ppc64/flight_recorder.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/flight_recorder.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,55 @@
+/************************************************************************
+ * flight_recorder.h                                                    *
+ ************************************************************************
+ * This code supports the a generic flight recorder.                    *
+ * Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    * 
+ *                                                                      *
+ * 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                                          *
+ ************************************************************************
+ * See the fight_recorder.c file for useage deails.                     *
+ ************************************************************************/
+#include <linux/kernel.h>
+
+/************************************************************************
+ * Generic Flight Recorder Structure                                    *
+ ************************************************************************/
+struct flightRecorder {                 /* Structure Defination         */
+	char  Signature[8];                /* Eye Catcher                  */
+	int   Size;			            /* Size of Flight Recorder      */
+	int   Flags;                       /* Format Flags.                */				
+	char* StartPointer;                /* Buffer Starting Address      */
+	char* EndPointer;                  /* Buffer Ending Address        */
+	char* NextPointer;                 /* Next Entry Address           */
+	char* WrapPointer;                 /* Point at which buffer wraps  */
+	char* Buffer;                      /* Where the data log is.       */
+};
+typedef struct flightRecorder FlightRecorder;
+
+/************************************************************************
+ * Forware declares
+ ************************************************************************/
+FlightRecorder* alloc_Flight_Recorder(FlightRecorder* FrPtr, char* Signature, int SizeOfFr);
+void            fr_Log_Entry(FlightRecorder* LogFr, const char *fmt, ...);
+int             fr_Dump(FlightRecorder* Fr, char *Buffer, int BufferLen);
+
+/************************************************************************
+ * Sample Macro to make life easier using the flight_recorder. 
+ * TestFr is a global value.
+ * To use them: TESTFR("Test Loop value is &d",Loop");
+ ************************************************************************/
+#define LOGFR(...) (fr_Log_Entry(__VA_ARGS__))
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/floppy.h linux/include/asm-ppc64/floppy.h
--- linux.orig/include/asm-ppc64/floppy.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/floppy.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,105 @@
+/*
+ * Architecture specific parts of the Floppy driver
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995
+ */
+#ifndef __ASM_PPC64_FLOPPY_H
+#define __ASM_PPC64_FLOPPY_H
+
+#include <linux/config.h>
+
+#define fd_inb(port)			inb_p(port)
+#define fd_outb(port,value)		outb_p(port,value)
+
+#define fd_enable_dma()         enable_dma(FLOPPY_DMA)
+#define fd_disable_dma()        disable_dma(FLOPPY_DMA)
+#define fd_request_dma()        request_dma(FLOPPY_DMA,"floppy")
+#define fd_free_dma()           free_dma(FLOPPY_DMA)
+#define fd_clear_dma_ff()       clear_dma_ff(FLOPPY_DMA)
+#define fd_set_dma_mode(mode)   set_dma_mode(FLOPPY_DMA,mode)
+#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA,count)
+#define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
+#define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
+#define fd_cacheflush(addr,size) /* nothing */
+#define fd_request_irq()        request_irq(FLOPPY_IRQ, floppy_interrupt, \
+					    SA_INTERRUPT|SA_SAMPLE_RANDOM, \
+				            "floppy", NULL)
+#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
+
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+
+#define fd_dma_setup(addr,size,mode,io) ppc64_fd_dma_setup(addr,size,mode,io)
+
+static __inline__ int 
+ppc64_fd_dma_setup(char *addr, unsigned long size, int mode, int io)
+{
+	static unsigned long prev_size;
+	static dma_addr_t bus_addr = 0;
+	static char *prev_addr;
+	static int prev_dir;
+	int dir;
+
+	dir = (mode == DMA_MODE_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE;
+
+	if (bus_addr 
+	    && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
+		/* different from last time -- unmap prev */
+		pci_unmap_single(NULL, bus_addr, prev_size, prev_dir);
+		bus_addr = 0;
+	}
+
+	if (!bus_addr)	/* need to map it */ {
+		bus_addr = pci_map_single(NULL, addr, size, dir);
+	}
+
+	/* remember this one as prev */
+	prev_addr = addr;
+	prev_size = size;
+	prev_dir = dir;
+
+	fd_clear_dma_ff();
+	fd_cacheflush(addr, size);
+	fd_set_dma_mode(mode);
+	set_dma_addr(FLOPPY_DMA, bus_addr);
+	fd_set_dma_count(size);
+	virtual_dma_port = io;
+	fd_enable_dma();
+
+	return 0;
+}
+
+#endif /* CONFIG_PCI */
+
+__inline__ void virtual_dma_init(void)
+{
+	/* Nothing to do on PowerPC */
+}
+
+static int FDC1 = 0x3f0;
+static int FDC2 = -1;
+
+/*
+ * Again, the CMOS information not available
+ */
+#define FLOPPY0_TYPE 6
+#define FLOPPY1_TYPE 0
+
+#define N_FDC 2			/* Don't change this! */
+#define N_DRIVE 8
+
+#define FLOPPY_MOTOR_MASK 0xf0
+
+/*
+ * The PowerPC has no problems with floppy DMA crossing 64k borders.
+ */
+#define CROSS_64KB(a,s)	(0)
+
+#define EXTRA_FLOPPY_PARAMS
+
+#endif /* __ASM_PPC64_FLOPPY_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/hardirq.h linux/include/asm-ppc64/hardirq.h
--- linux.orig/include/asm-ppc64/hardirq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/hardirq.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,100 @@
+#ifdef __KERNEL__
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+/*
+ * Use a brlock for the global irq lock, based on sparc64.
+ * Anton Blanchard <anton@au1.ibm.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.
+ */
+
+#include <linux/config.h>
+#include <linux/brlock.h>
+#include <linux/spinlock.h>
+
+
+typedef struct {
+	unsigned long __softirq_pending;
+#ifndef CONFIG_SMP
+	unsigned int __local_irq_count;
+#else
+	unsigned int __unused_on_SMP;		/* We use brlocks on SMP */
+#endif
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	unsigned long __unused;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+/* Note that local_irq_count() is replaced by ppc64 specific version for SMP */
+
+#ifndef CONFIG_SMP
+#define irq_enter(cpu)		(local_irq_count(cpu)++)
+#define irq_exit(cpu)		(local_irq_count(cpu)--)
+#else
+#undef local_irq_count
+#define local_irq_count(cpu)	(__brlock_array[cpu][BR_GLOBALIRQ_LOCK])
+#define irq_enter(cpu)		br_read_lock(BR_GLOBALIRQ_LOCK)
+#define irq_exit(cpu)		br_read_unlock(BR_GLOBALIRQ_LOCK)
+#endif
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() ({ int __cpu = smp_processor_id(); \
+	(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
+
+/* This tests only the local processors hw IRQ context disposition.  */
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define synchronize_irq()	barrier()
+
+#else /* CONFIG_SMP */
+
+static __inline__ int irqs_running(void)
+{
+	int i;
+
+	for (i = 0; i < smp_num_cpus; i++)
+		if (local_irq_count(cpu_logical_map(i)))
+			return 1;
+	return 0;
+}
+
+extern unsigned char global_irq_holder;
+
+static inline void release_irqlock(int cpu)
+{
+	/* if we didn't own the irq lock, just ignore... */
+	if(global_irq_holder == (unsigned char) cpu) {
+		global_irq_holder = NO_PROC_ID;
+		br_write_unlock(BR_GLOBALIRQ_LOCK);
+	}
+}
+
+static inline int hardirq_trylock(int cpu)
+{
+	spinlock_t *lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
+
+	return (!local_irq_count(cpu) && !spin_is_locked(lock));
+}
+
+#define hardirq_endlock(cpu)    do { (void)(cpu); } while (0)
+
+extern void synchronize_irq(void);
+
+#endif /* CONFIG_SMP */
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_HARDIRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/hdreg.h linux/include/asm-ppc64/hdreg.h
--- linux.orig/include/asm-ppc64/hdreg.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/hdreg.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,22 @@
+/*
+ *  linux/include/asm-ppc/hdreg.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ *
+ * 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 file contains the ppc architecture specific IDE code.
+ */
+
+#ifndef __ASMPPC64_HDREG_H
+#define __ASMPPC64_HDREG_H
+
+typedef unsigned long ide_ioreg_t;
+
+#endif /* __ASMPPC64_HDREG_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/hw_irq.h linux/include/asm-ppc64/hw_irq.h
--- linux.orig/include/asm-ppc64/hw_irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/hw_irq.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ *
+ * Use inline IRQs where possible - Anton Blanchard <anton@au.ibm.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.
+ */
+#ifdef __KERNEL__
+#ifndef _PPC64_HW_IRQ_H
+#define _PPC64_HW_IRQ_H
+
+#include <linux/config.h>
+#include <asm/irq.h>
+
+int timer_interrupt(struct pt_regs *);
+
+#ifdef CONFIG_PPC_ISERIES
+
+extern void __no_use_sti(void);
+extern void __no_use_cli(void);
+extern void __no_use_restore_flags(unsigned long);
+extern unsigned long __no_use_save_flags(void);
+extern void __no_use_set_lost(unsigned long);
+extern void __no_lpq_restore_flags(unsigned long);
+
+#define __cli()			__no_use_cli()
+#define __sti()			__no_use_sti()
+#define __save_flags(flags)	((flags) = __no_use_save_flags())
+#define __restore_flags(flags)	__no_use_restore_flags((unsigned long)flags)
+#define __save_and_cli(flags)	({__save_flags(flags);__cli();})
+
+#else
+
+#define __save_flags(flags)	((flags) = mfmsr())
+#define __restore_flags(flags)	mtmsrd(flags)
+
+static inline void __cli(void)
+{
+	unsigned long msr;
+	msr = mfmsr();
+	mtmsrd(msr & ~MSR_EE);
+	__asm__ __volatile__("": : :"memory");
+}
+
+static inline void __sti(void)
+{
+	unsigned long msr;
+	__asm__ __volatile__("": : :"memory");
+	msr = mfmsr();
+	mtmsrd(msr | MSR_EE);
+}
+
+static inline void __do_save_and_cli(unsigned long *flags)
+{
+	unsigned long msr;
+	msr = mfmsr();
+	*flags = msr;
+	mtmsrd(msr & ~MSR_EE);
+	__asm__ __volatile__("": : :"memory");
+}
+
+#define __save_and_cli(flags)          __do_save_and_cli(&flags)
+
+#endif /* CONFIG_PPC_ISERIES */
+
+#define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);})
+#define unmask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->enable) irq_desc[irq].handler->enable(irq);})
+#define ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);})
+
+/* Should we handle this via lost interrupts and IPIs or should we don't care like
+ * we do now ? --BenH.
+ */
+struct hw_interrupt_type;
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
+
+#endif /* _PPC64_HW_IRQ_H */
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvCall.h linux/include/asm-ppc64/iSeries/HvCall.h
--- linux.orig/include/asm-ppc64/iSeries/HvCall.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvCall.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,202 @@
+/*
+ * HvCall.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//===========================================================================
+//
+//	This file contains the "hypervisor call" interface which is used to
+//	drive the hypervisor from the OS.
+//
+//===========================================================================
+
+//-------------------------------------------------------------------
+// Standard Includes
+//-------------------------------------------------------------------
+#ifndef  _HVCALLSC_H
+#include "HvCallSc.h"
+#endif
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+#include <asm/paca.h>
+
+//-------------------------------------------------------------------
+// Constants
+//-------------------------------------------------------------------
+#ifndef _HVCALL_H
+#define _HVCALL_H
+/*
+enum HvCall_ReturnCode
+{
+	HvCall_Good		= 0,
+	HvCall_Partial		= 1,
+	HvCall_NotOwned		= 2,
+	HvCall_NotFreed		= 3,
+	HvCall_UnspecifiedError	= 4
+};
+
+enum HvCall_TypeOfSIT
+{
+	HvCall_ReduceOnly	= 0,
+	HvCall_Unconditional	= 1
+};
+
+enum HvCall_TypeOfYield
+{
+	HvCall_YieldTimed	= 0,	// Yield until specified time
+	HvCall_YieldToActive	= 1,	// Yield until all active procs have run
+	HvCall_YieldToProc	= 2	// Yield until the specified processor has run
+};
+
+enum HvCall_InterruptMasks
+{
+	HvCall_MaskIPI		= 0x00000001,
+	HvCall_MaskLpEvent	= 0x00000002,
+	HvCall_MaskLpProd	= 0x00000004,
+	HvCall_MaskTimeout	= 0x00000008
+};
+
+enum HvCall_VaryOffChunkRc
+{
+	HvCall_VaryOffSucceeded		= 0,
+	HvCall_VaryOffWithdrawn		= 1,
+	HvCall_ChunkInLoadArea		= 2,
+	HvCall_ChunkInHPT		= 3,
+	HvCall_ChunkNotAccessible	= 4,
+	HvCall_ChunkInUse		= 5
+};
+*/
+
+/* Type of yield for HvCallBaseYieldProcessor */
+#define HvCall_YieldTimed 	0	// Yield until specified time (tb)
+#define HvCall_YieldToActive	1	// Yield until all active procs have run
+#define HvCall_YieldToProc	2	// Yield until the specified processor has run
+
+/* interrupt masks for setEnabledInterrupts */
+#define HvCall_MaskIPI		0x00000001
+#define HvCall_MaskLpEvent	0x00000002
+#define HvCall_MaskLpProd	0x00000004
+#define HvCall_MaskTimeout	0x00000008
+
+/* Log buffer formats                       */
+#define HvCall_LogBuffer_ASCII          0
+#define HvCall_LogBuffer_EBCDIC         1
+
+#define HvCallBaseAckDeferredInts			HvCallBase +  0
+#define HvCallBaseCpmPowerOff				HvCallBase +  1
+#define HvCallBaseGetHwPatch				HvCallBase +  2
+#define HvCallBaseReIplSpAttn				HvCallBase +  3
+#define HvCallBaseSetASR				HvCallBase +  4
+#define HvCallBaseSetASRAndRfi				HvCallBase +  5 
+#define HvCallBaseSetIMR				HvCallBase +  6
+#define HvCallBaseSendIPI				HvCallBase +  7
+#define HvCallBaseTerminateMachine			HvCallBase +  8
+#define HvCallBaseTerminateMachineSrc			HvCallBase +  9
+#define HvCallBaseProcessPlicInterrupts			HvCallBase + 10
+#define HvCallBaseIsPrimaryCpmOrMsdIpl			HvCallBase + 11
+#define HvCallBaseSetVirtualSIT				HvCallBase + 12
+#define HvCallBaseVaryOffThisProcessor			HvCallBase + 13
+#define HvCallBaseVaryOffMemoryChunk			HvCallBase + 14
+#define HvCallBaseVaryOffInteractivePercentage		HvCallBase + 15
+#define HvCallBaseSendLpProd				HvCallBase + 16
+#define HvCallBaseSetEnabledInterrupts			HvCallBase + 17
+#define HvCallBaseYieldProcessor			HvCallBase + 18
+#define HvCallBaseVaryOffSharedProcUnits		HvCallBase + 19
+#define HvCallBaseSetVirtualDecr			HvCallBase + 20
+#define HvCallBaseClearLogBuffer			HvCallBase + 21
+#define HvCallBaseGetLogBufferCodePage			HvCallBase + 22
+#define HvCallBaseGetLogBufferFormat			HvCallBase + 23
+#define HvCallBaseGetLogBufferLength			HvCallBase + 24
+#define HvCallBaseReadLogBuffer 			HvCallBase + 25
+#define HvCallBaseSetLogBufferFormatAndCodePage		HvCallBase + 26
+#define HvCallBaseWriteLogBuffer               		HvCallBase + 27
+#define HvCallBaseRouter28				HvCallBase + 28
+#define HvCallBaseRouter29				HvCallBase + 29
+#define HvCallBaseRouter30				HvCallBase + 30
+//=====================================================================================
+static inline void		HvCall_setVirtualDecr(void)
+{
+	/* Ignore any error return codes - most likely means that the target value for the
+	 * LP has been increased and this vary off would bring us below the new target. */
+	HvCall0(HvCallBaseSetVirtualDecr);
+}
+//=====================================================================
+static inline void		HvCall_yieldProcessor(unsigned typeOfYield, u64 yieldParm)
+{
+	HvCall2( HvCallBaseYieldProcessor, typeOfYield, yieldParm );
+}
+//=====================================================================
+static inline void		HvCall_setEnabledInterrupts(u64 enabledInterrupts)
+{
+	HvCall1(HvCallBaseSetEnabledInterrupts,enabledInterrupts);
+}
+
+//=====================================================================
+static inline void		HvCall_clearLogBuffer(HvLpIndex lpindex)
+{
+	HvCall1(HvCallBaseClearLogBuffer,lpindex);
+}
+
+//=====================================================================
+static inline u32  		HvCall_getLogBufferCodePage(HvLpIndex lpindex)
+{
+	u32 retVal = HvCall1(HvCallBaseGetLogBufferCodePage,lpindex);
+	return retVal;
+}
+
+//=====================================================================
+static inline int  		HvCall_getLogBufferFormat(HvLpIndex lpindex)
+{
+	int retVal = HvCall1(HvCallBaseGetLogBufferFormat,lpindex);
+	return retVal;
+}
+
+//=====================================================================
+static inline u32  		HvCall_getLogBufferLength(HvLpIndex lpindex)
+{
+	u32 retVal = HvCall1(HvCallBaseGetLogBufferLength,lpindex);
+	return retVal;
+}
+
+//=====================================================================
+static inline void  		HvCall_setLogBufferFormatAndCodepage(int format, u32 codePage)
+{
+	HvCall2(HvCallBaseSetLogBufferFormatAndCodePage,format, codePage);
+}
+
+//=====================================================================
+int HvCall_readLogBuffer(HvLpIndex lpindex, void *buffer, u64 bufLen);
+void HvCall_writeLogBuffer(const void *buffer, u64 bufLen);
+
+//=====================================================================
+static inline void		HvCall_sendIPI(struct paca_struct * targetPaca)
+{
+	HvCall1( HvCallBaseSendIPI, targetPaca->xPacaIndex );
+}
+
+//=====================================================================
+static inline void		HvCall_terminateMachineSrc(void)
+{
+	HvCall0( HvCallBaseTerminateMachineSrc );
+}
+
+
+#endif // _HVCALL_H
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvCallCfg.h linux/include/asm-ppc64/iSeries/HvCallCfg.h
--- linux.orig/include/asm-ppc64/iSeries/HvCallCfg.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvCallCfg.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,219 @@
+/*
+ * HvCallCfg.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//=====================================================================================
+//
+//	This file contains the "hypervisor call" interface which is used to
+//	drive the hypervisor from the OS.
+//
+//=====================================================================================
+
+//-------------------------------------------------------------------
+// Standard Includes
+//-------------------------------------------------------------------
+#ifndef  _HVCALLSC_H
+#include "HvCallSc.h"
+#endif
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+//-------------------------------------------------------------------------------------
+// Constants
+//-------------------------------------------------------------------------------------
+#ifndef _HVCALLCFG_H
+#define _HVCALLCFG_H
+
+enum HvCallCfg_ReqQual
+{
+	HvCallCfg_Cur	= 0,
+	HvCallCfg_Init	= 1,
+	HvCallCfg_Max	= 2,
+	HvCallCfg_Min	= 3
+};
+
+#define HvCallCfgGetLps					HvCallCfg +  0
+#define HvCallCfgGetActiveLpMap				HvCallCfg +  1
+#define HvCallCfgGetLpVrmIndex				HvCallCfg +  2
+#define HvCallCfgGetLpMinSupportedPlicVrmIndex		HvCallCfg +  3
+#define HvCallCfgGetLpMinCompatablePlicVrmIndex		HvCallCfg +  4
+#define HvCallCfgGetLpVrmName				HvCallCfg +  5 
+#define HvCallCfgGetSystemPhysicalProcessors		HvCallCfg +  6
+#define HvCallCfgGetPhysicalProcessors			HvCallCfg +  7
+#define HvCallCfgGetSystemMsChunks			HvCallCfg +  8
+#define HvCallCfgGetMsChunks				HvCallCfg +  9
+#define HvCallCfgGetInteractivePercentage		HvCallCfg + 10
+#define HvCallCfgIsBusDedicated				HvCallCfg + 11
+#define HvCallCfgGetBusOwner				HvCallCfg + 12
+#define HvCallCfgGetBusAllocation			HvCallCfg + 13
+#define HvCallCfgGetBusUnitOwner			HvCallCfg + 14
+#define HvCallCfgGetBusUnitAllocation			HvCallCfg + 15
+#define HvCallCfgGetVirtualBusPool			HvCallCfg + 16
+#define HvCallCfgGetBusUnitInterruptProc		HvCallCfg + 17
+#define HvCallCfgGetConfiguredBusUnitsForIntProc	HvCallCfg + 18
+#define HvCallCfgGetRioSanBusPool			HvCallCfg + 19
+#define HvCallCfgGetSharedPoolIndex			HvCallCfg + 20
+#define HvCallCfgGetSharedProcUnits			HvCallCfg + 21
+#define HvCallCfgGetNumProcsInSharedPool		HvCallCfg + 22
+#define HvCallCfgRouter23				HvCallCfg + 23
+#define HvCallCfgRouter24				HvCallCfg + 24
+#define HvCallCfgRouter25				HvCallCfg + 25
+#define HvCallCfgRouter26				HvCallCfg + 26
+#define HvCallCfgRouter27				HvCallCfg + 27
+#define HvCallCfgGetMinRuntimeMsChunks			HvCallCfg + 28
+#define HvCallCfgSetMinRuntimeMsChunks			HvCallCfg + 29
+#define HvCallCfgGetVirtualLanIndexMap			HvCallCfg + 30
+#define HvCallCfgGetLpExecutionMode			HvCallCfg + 31
+#define HvCallCfgGetHostingLpIndex 			HvCallCfg + 32
+
+//====================================================================
+static inline HvLpIndex	HvCallCfg_getLps(void)
+{
+	HvLpIndex retVal = HvCall0(HvCallCfgGetLps);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//====================================================================
+static inline int		HvCallCfg_isBusDedicated(u64 busIndex)
+{
+	int retVal = HvCall1(HvCallCfgIsBusDedicated,busIndex);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//====================================================================
+static inline HvLpIndex	HvCallCfg_getBusOwner(u64 busIndex)
+{
+	HvLpIndex retVal = HvCall1(HvCallCfgGetBusOwner,busIndex);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//====================================================================
+static inline HvLpIndexMap	HvCallCfg_getBusAllocation(u64 busIndex)
+{
+	HvLpIndexMap retVal = HvCall1(HvCallCfgGetBusAllocation,busIndex);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//====================================================================
+static inline HvLpIndexMap	HvCallCfg_getActiveLpMap(void)
+{
+	HvLpIndexMap retVal = HvCall0(HvCallCfgGetActiveLpMap);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//====================================================================
+static inline HvLpVirtualLanIndexMap	HvCallCfg_getVirtualLanIndexMap(HvLpIndex lp)
+{
+	// This is a new function in V5R1 so calls to this on older 
+	// hypervisors will return -1
+	u64 retVal = HvCall1(HvCallCfgGetVirtualLanIndexMap, lp);
+	if(retVal == -1)
+		retVal = 0;
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline u64		HvCallCfg_getSystemMsChunks(void)
+{
+	u64 retVal = HvCall0(HvCallCfgGetSystemMsChunks);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline u64		HvCallCfg_getMsChunks(HvLpIndex lp,enum HvCallCfg_ReqQual qual)
+{
+	u64 retVal = HvCall2(HvCallCfgGetMsChunks,lp,qual);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline u64		HvCallCfg_getMinRuntimeMsChunks(HvLpIndex lp)
+{
+	// NOTE: This function was added in v5r1 so older hypervisors will return a -1 value
+	u64 retVal = HvCall1(HvCallCfgGetMinRuntimeMsChunks,lp);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline u64		HvCallCfg_setMinRuntimeMsChunks(u64 chunks)
+{
+	u64 retVal = HvCall1(HvCallCfgSetMinRuntimeMsChunks,chunks);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline u64		HvCallCfg_getSystemPhysicalProcessors(void)
+{
+	u64 retVal = HvCall0(HvCallCfgGetSystemPhysicalProcessors);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline u64		HvCallCfg_getPhysicalProcessors(HvLpIndex lp,enum HvCallCfg_ReqQual qual)
+{
+	u64 retVal = HvCall2(HvCallCfgGetPhysicalProcessors,lp,qual);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline u64		HvCallCfg_getConfiguredBusUnitsForInterruptProc(HvLpIndex lp,
+										u16 hvLogicalProcIndex)
+{
+	u64 retVal = HvCall2(HvCallCfgGetConfiguredBusUnitsForIntProc,lp,hvLogicalProcIndex);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+
+}
+//==================================================================
+static inline HvLpSharedPoolIndex	HvCallCfg_getSharedPoolIndex(HvLpIndex lp)
+{
+	HvLpSharedPoolIndex retVal =
+		HvCall1(HvCallCfgGetSharedPoolIndex,lp);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+
+}
+//==================================================================
+static inline u64	HvCallCfg_getSharedProcUnits(HvLpIndex lp,enum HvCallCfg_ReqQual qual)
+{
+	u64 retVal = HvCall2(HvCallCfgGetSharedProcUnits,lp,qual);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+
+}
+//==================================================================
+static inline u64	HvCallCfg_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI)
+{
+	u16 retVal = HvCall1(HvCallCfgGetNumProcsInSharedPool,sPI);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+
+}
+//==================================================================
+static inline HvLpIndex	HvCallCfg_getHostingLpIndex(HvLpIndex lp)
+{
+	u64 retVal = HvCall1(HvCallCfgGetHostingLpIndex,lp);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+
+}
+
+#endif // _HVCALLCFG_H
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvCallEvent.h linux/include/asm-ppc64/iSeries/HvCallEvent.h
--- linux.orig/include/asm-ppc64/iSeries/HvCallEvent.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvCallEvent.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,335 @@
+/*
+ * HvCallEvent.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//==================================================================
+//
+//	This file contains the "hypervisor call" interface which is used to
+//	drive the hypervisor from the OS.
+//
+//==================================================================
+
+//-------------------------------------------------------------------
+// Standard Includes
+//-------------------------------------------------------------------
+#ifndef  _HVCALLSC_H
+#include <asm/iSeries/HvCallSc.h>
+#endif
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+#include <asm/abs_addr.h>
+
+//-------------------------------------------------------------------
+// Other Includes
+//-------------------------------------------------------------------
+
+//-------------------------------------------------------------------
+// Constants
+//-------------------------------------------------------------------
+#ifndef _HVCALLEVENT_H
+#define _HVCALLEVENT_H
+
+struct HvLpEvent;
+
+typedef u8 HvLpEvent_Type;
+typedef u8 HvLpEvent_AckInd;
+typedef u8 HvLpEvent_AckType;
+
+struct	HvCallEvent_PackedParms
+{
+	u8		xAckType:1;
+	u8		xAckInd:1;
+	u8		xRsvd:1;
+	u8		xTargetLp:5;
+	u8		xType;
+	u16		xSubtype;
+	HvLpInstanceId	xSourceInstId;
+	HvLpInstanceId	xTargetInstId;
+};
+
+typedef u8 HvLpDma_Direction;
+typedef u8 HvLpDma_AddressType;
+
+struct	HvCallEvent_PackedDmaParms
+{
+	u8		xDirection:1;
+	u8		xLocalAddrType:1;
+	u8		xRemoteAddrType:1;
+	u8		xRsvd1:5;
+	HvLpIndex	xRemoteLp;
+	u8		xType;
+	u8		xRsvd2;
+	HvLpInstanceId	xLocalInstId;
+	HvLpInstanceId	xRemoteInstId;
+};
+
+typedef u64 HvLpEvent_Rc;
+typedef u64 HvLpDma_Rc;
+
+#define HvCallEventAckLpEvent				HvCallEvent +  0
+#define HvCallEventCancelLpEvent			HvCallEvent +  1
+#define HvCallEventCloseLpEventPath			HvCallEvent +  2
+#define HvCallEventDmaBufList				HvCallEvent +  3
+#define HvCallEventDmaSingle				HvCallEvent +  4
+#define HvCallEventDmaToSp				HvCallEvent +  5 
+#define HvCallEventGetOverflowLpEvents			HvCallEvent +  6
+#define HvCallEventGetSourceLpInstanceId		HvCallEvent +  7
+#define HvCallEventGetTargetLpInstanceId		HvCallEvent +  8
+#define HvCallEventOpenLpEventPath			HvCallEvent +  9
+#define HvCallEventSetLpEventStack			HvCallEvent + 10
+#define HvCallEventSignalLpEvent			HvCallEvent + 11
+#define HvCallEventSignalLpEventParms			HvCallEvent + 12
+#define HvCallEventSetInterLpQueueIndex			HvCallEvent + 13
+#define HvCallEventSetLpEventQueueInterruptProc		HvCallEvent + 14
+#define HvCallEventRouter15				HvCallEvent + 15
+
+//======================================================================
+static inline void		HvCallEvent_getOverflowLpEvents(u8 queueIndex)
+{
+	HvCall1(HvCallEventGetOverflowLpEvents,queueIndex);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//======================================================================
+static inline void		HvCallEvent_setInterLpQueueIndex(u8 queueIndex)
+{
+	HvCall1(HvCallEventSetInterLpQueueIndex,queueIndex);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//======================================================================
+static inline void		HvCallEvent_setLpEventStack(u8 queueIndex,
+					     char * eventStackAddr,
+					     u32 eventStackSize)
+{
+	u64 abs_addr;
+	abs_addr = virt_to_absolute( (unsigned long) eventStackAddr );
+
+	HvCall3(HvCallEventSetLpEventStack, queueIndex, abs_addr, eventStackSize);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//======================================================================
+static inline void		HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex,
+							  u16 lpLogicalProcIndex)
+{
+	HvCall2(HvCallEventSetLpEventQueueInterruptProc,queueIndex,lpLogicalProcIndex);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//=====================================================================
+static inline HvLpEvent_Rc HvCallEvent_signalLpEvent(struct HvLpEvent* event)
+{
+	u64 abs_addr;
+	HvLpEvent_Rc retVal;
+#ifdef DEBUG_SENDEVENT
+	printk("HvCallEvent_signalLpEvent: *event = %016lx\n ", (unsigned long)event);
+#endif
+	abs_addr = virt_to_absolute( (unsigned long) event );
+	retVal = (HvLpEvent_Rc)HvCall1(HvCallEventSignalLpEvent, abs_addr);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//=====================================================================
+static inline HvLpEvent_Rc  HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
+					   HvLpEvent_Type type,
+					   u16 subtype,
+					   HvLpEvent_AckInd ackInd,
+					   HvLpEvent_AckType ackType,
+					   HvLpInstanceId sourceInstanceId,
+					   HvLpInstanceId targetInstanceId,
+					   u64 correlationToken,
+					   u64 eventData1,
+					   u64 eventData2,
+					   u64 eventData3,
+					   u64 eventData4,
+					   u64 eventData5)
+{
+	HvLpEvent_Rc retVal;
+
+	// Pack the misc bits into a single Dword to pass to PLIC
+	union
+	{
+		struct HvCallEvent_PackedParms	parms;
+		u64		dword;
+	} packed;
+	packed.parms.xAckType	= ackType;
+	packed.parms.xAckInd	= ackInd;
+	packed.parms.xRsvd	= 0;
+	packed.parms.xTargetLp	= targetLp;
+	packed.parms.xType	= type;
+	packed.parms.xSubtype	= subtype;
+	packed.parms.xSourceInstId	= sourceInstanceId;
+	packed.parms.xTargetInstId	= targetInstanceId;
+
+	retVal = (HvLpEvent_Rc)HvCall7(HvCallEventSignalLpEventParms,
+				       packed.dword,
+				       correlationToken,
+				       eventData1,eventData2,
+				       eventData3,eventData4,
+				       eventData5);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//====================================================================
+static inline HvLpEvent_Rc	HvCallEvent_ackLpEvent(struct HvLpEvent* event)
+{
+	u64 abs_addr;
+	HvLpEvent_Rc retVal;
+	abs_addr = virt_to_absolute( (unsigned long) event );
+
+	retVal = (HvLpEvent_Rc)HvCall1(HvCallEventAckLpEvent, abs_addr);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//====================================================================
+static inline HvLpEvent_Rc   HvCallEvent_cancelLpEvent(struct HvLpEvent* event)
+{
+	u64 abs_addr;
+	HvLpEvent_Rc retVal;
+	abs_addr = virt_to_absolute( (unsigned long) event );
+
+	retVal = (HvLpEvent_Rc)HvCall1(HvCallEventCancelLpEvent, abs_addr);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline HvLpInstanceId	HvCallEvent_getSourceLpInstanceId(HvLpIndex targetLp, HvLpEvent_Type type)
+{
+	HvLpInstanceId retVal;	
+	retVal = HvCall2(HvCallEventGetSourceLpInstanceId,targetLp,type);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline HvLpInstanceId	HvCallEvent_getTargetLpInstanceId(HvLpIndex targetLp, HvLpEvent_Type type)
+{
+	HvLpInstanceId retVal;	
+	retVal = HvCall2(HvCallEventGetTargetLpInstanceId,targetLp,type);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//===================================================================
+static inline void		HvCallEvent_openLpEventPath(HvLpIndex targetLp,
+					     HvLpEvent_Type type)
+{
+	HvCall2(HvCallEventOpenLpEventPath,targetLp,type);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//===================================================================
+static inline void		HvCallEvent_closeLpEventPath(HvLpIndex targetLp,
+					      HvLpEvent_Type type)
+{
+	HvCall2(HvCallEventCloseLpEventPath,targetLp,type);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//===================================================================
+static inline HvLpDma_Rc	HvCallEvent_dmaBufList(HvLpEvent_Type type,
+					HvLpIndex remoteLp,
+					HvLpDma_Direction direction,
+					HvLpInstanceId localInstanceId,
+					HvLpInstanceId remoteInstanceId,
+					HvLpDma_AddressType localAddressType,
+					HvLpDma_AddressType remoteAddressType,
+					// Do these need to be converted to
+					// absolute addresses?
+					u64 localBufList,
+					u64 remoteBufList,
+
+					u32 transferLength)
+{
+	HvLpDma_Rc retVal;	
+	// Pack the misc bits into a single Dword to pass to PLIC
+	union
+	{
+		struct HvCallEvent_PackedDmaParms	parms;
+		u64		dword;
+	} packed;
+	packed.parms.xDirection		= direction;
+	packed.parms.xLocalAddrType	= localAddressType;
+	packed.parms.xRemoteAddrType	= remoteAddressType;
+	packed.parms.xRsvd1		= 0;
+	packed.parms.xRemoteLp		= remoteLp;
+	packed.parms.xType		= type;
+	packed.parms.xRsvd2		= 0;
+	packed.parms.xLocalInstId	= localInstanceId;
+	packed.parms.xRemoteInstId	= remoteInstanceId;
+
+	retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaBufList,
+				     packed.dword,
+				     localBufList,
+				     remoteBufList,
+				     transferLength);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//=================================================================
+static inline HvLpDma_Rc	HvCallEvent_dmaSingle(HvLpEvent_Type type,
+				       HvLpIndex remoteLp,
+				       HvLpDma_Direction direction,
+				       HvLpInstanceId localInstanceId,
+				       HvLpInstanceId remoteInstanceId,
+				       HvLpDma_AddressType localAddressType,
+				       HvLpDma_AddressType remoteAddressType,
+				       u64 localAddrOrTce,
+				       u64 remoteAddrOrTce,
+				       u32 transferLength)
+{
+	HvLpDma_Rc retVal;	
+	// Pack the misc bits into a single Dword to pass to PLIC
+	union
+	{
+		struct HvCallEvent_PackedDmaParms	parms;
+		u64		dword;
+	} packed;
+	packed.parms.xDirection		= direction;
+	packed.parms.xLocalAddrType	= localAddressType;
+	packed.parms.xRemoteAddrType	= remoteAddressType;
+	packed.parms.xRsvd1		= 0;
+	packed.parms.xRemoteLp		= remoteLp;
+	packed.parms.xType		= type;
+	packed.parms.xRsvd2		= 0;
+	packed.parms.xLocalInstId	= localInstanceId;
+	packed.parms.xRemoteInstId	= remoteInstanceId;
+
+	retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle,
+				     packed.dword,
+				     localAddrOrTce,
+				     remoteAddrOrTce,
+				     transferLength);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//=================================================================
+static inline HvLpDma_Rc	HvCallEvent_dmaToSp(void* local, u32 remote, u32 length, HvLpDma_Direction dir)
+{
+	u64 abs_addr;
+	HvLpDma_Rc retVal;
+	abs_addr = virt_to_absolute( (unsigned long) local );
+    
+	retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaToSp, 
+				     abs_addr,
+				     remote,
+				     length,
+				     dir);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//================================================================
+
+#endif // _HVCALLEVENT_H
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvCallHpt.h linux/include/asm-ppc64/iSeries/HvCallHpt.h
--- linux.orig/include/asm-ppc64/iSeries/HvCallHpt.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvCallHpt.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,143 @@
+/*
+ * HvCallHpt.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//============================================================================
+//
+//	This file contains the "hypervisor call" interface which is used to
+//	drive the hypervisor from the OS.
+//
+//============================================================================
+
+//-------------------------------------------------------------------
+// Standard Includes
+//-------------------------------------------------------------------
+#ifndef  _HVCALLSC_H
+#include "HvCallSc.h"
+#endif
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+//-------------------------------------------------------------------
+// Other Includes
+//-------------------------------------------------------------------
+
+#ifndef _PPC_MMU_H
+#include <asm/mmu.h>
+#endif
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+#ifndef _HVCALLHPT_H
+#define _HVCALLHPT_H
+
+#define HvCallHptGetHptAddress		HvCallHpt +  0
+#define HvCallHptGetHptPages		HvCallHpt +  1
+#define HvCallHptSetPp			HvCallHpt +  5
+#define HvCallHptSetSwBits		HvCallHpt +  6
+#define HvCallHptUpdate			HvCallHpt +  7
+#define HvCallHptInvalidateNoSyncICache	HvCallHpt +  8
+#define HvCallHptGet			HvCallHpt + 11
+#define HvCallHptFindNextValid		HvCallHpt + 12
+#define HvCallHptFindValid		HvCallHpt + 13
+#define HvCallHptAddValidate		HvCallHpt + 16
+#define HvCallHptInvalidateSetSwBitsGet HvCallHpt + 18
+
+
+//============================================================================
+static inline u64		HvCallHpt_getHptAddress(void)
+{
+	u64 retval = HvCall0(HvCallHptGetHptAddress);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retval;
+}
+//============================================================================
+static inline u64		HvCallHpt_getHptPages(void)
+{	
+	u64 retval = HvCall0(HvCallHptGetHptPages);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retval;
+}
+//=============================================================================
+static inline void		HvCallHpt_setPp(u32 hpteIndex, u8 value)
+{
+	HvCall2( HvCallHptSetPp, hpteIndex, value );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//=============================================================================
+static inline void		HvCallHpt_setSwBits(u32 hpteIndex, u8 bitson, u8 bitsoff )
+{
+	HvCall3( HvCallHptSetSwBits, hpteIndex, bitson, bitsoff );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//=============================================================================
+static inline void		HvCallHpt_invalidateNoSyncICache(u32 hpteIndex)
+						
+{
+	HvCall1( HvCallHptInvalidateNoSyncICache, hpteIndex );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//=============================================================================
+static inline u64		HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson, u8 bitsoff )
+						
+{
+	u64 compressedStatus;
+	compressedStatus = HvCall4( HvCallHptInvalidateSetSwBitsGet, hpteIndex, bitson, bitsoff, 1 );
+	HvCall1( HvCallHptInvalidateNoSyncICache, hpteIndex );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return compressedStatus;
+}
+//=============================================================================
+static inline u64		HvCallHpt_findValid( struct _HPTE *hpte, u64 vpn )
+{
+	u64 retIndex = HvCall3Ret16( HvCallHptFindValid, hpte, vpn, 0, 0 );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retIndex;
+}
+//=============================================================================
+static inline u64		HvCallHpt_findNextValid( struct _HPTE *hpte, u32 hpteIndex, u8 bitson, u8 bitsoff )
+{
+	u64 retIndex = HvCall3Ret16( HvCallHptFindNextValid, hpte, hpteIndex, bitson, bitsoff );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retIndex;
+}
+//=============================================================================
+static inline void		HvCallHpt_get( struct _HPTE *hpte, u32 hpteIndex )
+{
+	HvCall2Ret16( HvCallHptGet, hpte, hpteIndex, 0 );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//============================================================================
+static inline void		HvCallHpt_addValidate( u32 hpteIndex,
+						       u32 hBit,
+						       struct _HPTE *hpte )
+						
+{
+	HvCall4( HvCallHptAddValidate, hpteIndex,
+		 hBit, (*((u64 *)hpte)), (*(((u64 *)hpte)+1)) );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+
+
+//=============================================================================
+
+#endif // _HVCALLHPT_H
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvCallPci.h linux/include/asm-ppc64/iSeries/HvCallPci.h
--- linux.orig/include/asm-ppc64/iSeries/HvCallPci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvCallPci.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,697 @@
+/************************************************************************/
+/* Provides the Hypervisor PCI calls for iSeries Linux Parition.        */
+/* Copyright (C) 20yy  <Wayne G Holm> <IBM 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created, Jan 9, 2001                                               */
+/************************************************************************/
+//============================================================================
+//							 Header File Id
+// Name______________:	HvCallPci.H
+//
+// Description_______:
+//
+//	This file contains the "hypervisor call" interface which is used to
+//	drive the hypervisor from SLIC.
+//
+//============================================================================
+
+//-------------------------------------------------------------------
+// Forward declarations 
+//-------------------------------------------------------------------
+
+//-------------------------------------------------------------------
+// Standard Includes
+//-------------------------------------------------------------------
+#ifndef  _HVCALLSC_H
+#include "HvCallSc.h"
+#endif
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+//-------------------------------------------------------------------
+// Other Includes
+//-------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+#ifndef _HVCALLPCI_H
+#define _HVCALLPCI_H
+
+struct HvCallPci_DsaAddr { // make sure this struct size is 64-bits total
+	u16		busNumber;
+	u8		subBusNumber; 
+	u8		deviceId;     
+	u8		barNumber;
+	u8		reserved[3];
+};
+union HvDsaMap {
+	u64	DsaAddr;
+	struct HvCallPci_DsaAddr Dsa;
+};
+
+struct HvCallPci_LoadReturn {
+	u64		rc;
+	u64		value;
+};
+
+enum HvCallPci_DeviceType {HvCallPci_NodeDevice	= 1,
+                        HvCallPci_SpDevice	= 2,	
+                        HvCallPci_IopDevice     = 3,	
+                        HvCallPci_BridgeDevice	= 4,	
+                        HvCallPci_MultiFunctionDevice = 5,	
+                        HvCallPci_IoaDevice	= 6	
+};
+
+
+struct HvCallPci_DeviceInfo {
+	u32	deviceType;		// See DeviceType enum for values
+};
+    
+struct HvCallPci_BusUnitInfo {
+	u32	sizeReturned;		// length of data returned
+	u32	deviceType;		// see DeviceType enum for values
+};
+
+struct HvCallPci_BridgeInfo {
+	struct HvCallPci_BusUnitInfo busUnitInfo;  // Generic bus unit info
+	u8		subBusNumber;		// Bus number of secondary bus
+	u8		maxAgents;		// Max idsels on secondary bus
+        u8              maxSubBusNumber;        // Max Sub Bus
+	u8		logicalSlotNumber;	// Logical Slot Number for IOA 
+};
+    
+
+//  Maximum BusUnitInfo buffer size.  Provided for clients so they can allocate
+//  a buffer big enough for any type of bus unit.  Increase as needed.
+enum {HvCallPci_MaxBusUnitInfoSize = 128};
+
+struct HvCallPci_BarParms {
+	u64		vaddr;
+	u64		raddr;
+	u64		size;
+	u64		protectStart;
+	u64		protectEnd;
+	u64		relocationOffset;
+	u64		pciAddress;		
+	u64		reserved[3];
+};					
+
+enum HvCallPci_VpdType {
+	HvCallPci_BusVpd		= 1,
+	HvCallPci_BusAdapterVpd	= 2
+};
+
+#define HvCallPciConfigLoad8		HvCallPci + 0
+#define HvCallPciConfigLoad16		HvCallPci + 1
+#define HvCallPciConfigLoad32		HvCallPci + 2
+#define HvCallPciConfigStore8		HvCallPci + 3
+#define HvCallPciConfigStore16		HvCallPci + 4
+#define HvCallPciConfigStore32		HvCallPci + 5
+#define HvCallPciEoi			HvCallPci + 16
+#define HvCallPciGetBarParms		HvCallPci + 18
+#define HvCallPciMaskFisr		HvCallPci + 20
+#define HvCallPciUnmaskFisr		HvCallPci + 21
+#define HvCallPciSetSlotReset		HvCallPci + 25
+#define HvCallPciGetDeviceInfo		HvCallPci + 27
+#define HvCallPciGetCardVpd		HvCallPci + 28
+#define HvCallPciBarLoad8		HvCallPci + 40
+#define HvCallPciBarLoad16		HvCallPci + 41
+#define HvCallPciBarLoad32		HvCallPci + 42
+#define HvCallPciBarLoad64		HvCallPci + 43
+#define HvCallPciBarStore8		HvCallPci + 44
+#define HvCallPciBarStore16		HvCallPci + 45
+#define HvCallPciBarStore32		HvCallPci + 46
+#define HvCallPciBarStore64		HvCallPci + 47
+#define HvCallPciMaskInterrupts		HvCallPci + 48
+#define HvCallPciUnmaskInterrupts	HvCallPci + 49
+#define HvCallPciGetBusUnitInfo		HvCallPci + 50
+
+//============================================================================
+static inline u64	HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber,
+					      u8 deviceId, u32 offset,
+					      u8 *value)
+{
+	struct HvCallPci_DsaAddr dsa;
+	struct HvCallPci_LoadReturn retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumber;
+	dsa.subBusNumber = subBusNumber;
+	dsa.deviceId = deviceId;
+
+	HvCall3Ret16(HvCallPciConfigLoad8, &retVal, *(u64 *)&dsa, offset, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	*value = retVal.value;
+
+	return retVal.rc;
+}
+//============================================================================
+static inline u64	HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
+					      u8 deviceId, u32 offset,
+					      u16 *value)
+{
+	struct HvCallPci_DsaAddr dsa;
+	struct HvCallPci_LoadReturn retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumber;
+	dsa.subBusNumber = subBusNumber;
+	dsa.deviceId = deviceId;
+
+	HvCall3Ret16(HvCallPciConfigLoad16, &retVal, *(u64 *)&dsa, offset, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	*value = retVal.value;
+
+	return retVal.rc;
+}
+//============================================================================
+static inline u64	HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber,
+					      u8 deviceId, u32 offset,
+					      u32 *value)
+{
+	struct HvCallPci_DsaAddr dsa;
+	struct HvCallPci_LoadReturn retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumber;
+	dsa.subBusNumber = subBusNumber;
+	dsa.deviceId = deviceId;
+
+	HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	*value = retVal.value;
+
+	return retVal.rc;
+}
+//============================================================================
+static inline u64	HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
+					      u8 deviceId, u32 offset,
+					      u8  value)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumber;
+	dsa.subBusNumber = subBusNumber;
+	dsa.deviceId = deviceId;
+
+	retVal = HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_configStore16(u16 busNumber, u8 subBusNumber,
+					      u8 deviceId, u32 offset,
+					      u16  value)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumber;
+	dsa.subBusNumber = subBusNumber;
+	dsa.deviceId = deviceId;
+
+	retVal = HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_configStore32(u16 busNumber, u8 subBusNumber,
+					      u8 deviceId, u32 offset,
+					      u32  value)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumber;
+	dsa.subBusNumber = subBusNumber;
+	dsa.deviceId = deviceId;
+
+	retVal = HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_barLoad8(u16	busNumberParm,
+					   u8		subBusParm,
+					   u8		deviceIdParm,
+					   u8		barNumberParm,
+					   u64		offsetParm,
+					   u8*		valueParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	struct HvCallPci_LoadReturn retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	HvCall3Ret16(HvCallPciBarLoad8, &retVal, *(u64 *)&dsa, offsetParm, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	*valueParm = retVal.value;
+
+	return retVal.rc;
+}
+//============================================================================
+static inline u64	HvCallPci_barLoad16(u16	busNumberParm,
+					   u8		subBusParm,
+					   u8		deviceIdParm,
+					   u8		barNumberParm,
+					   u64		offsetParm,
+					   u16*		valueParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	struct HvCallPci_LoadReturn retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	HvCall3Ret16(HvCallPciBarLoad16, &retVal, *(u64 *)&dsa, offsetParm, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	*valueParm = retVal.value;
+
+	return retVal.rc;
+}
+//============================================================================
+static inline u64	HvCallPci_barLoad32(u16	busNumberParm,
+					   u8		subBusParm,
+					   u8		deviceIdParm,
+					   u8		barNumberParm,
+					   u64		offsetParm,
+					   u32*		valueParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	struct HvCallPci_LoadReturn retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	HvCall3Ret16(HvCallPciBarLoad32, &retVal, *(u64 *)&dsa, offsetParm, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	*valueParm = retVal.value;
+
+	return retVal.rc;
+}
+//============================================================================
+static inline u64	HvCallPci_barLoad64(u16	busNumberParm,
+					   u8		subBusParm,
+					   u8		deviceIdParm,
+					   u8		barNumberParm,
+					   u64		offsetParm,
+					   u64*		valueParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	struct HvCallPci_LoadReturn retVal;
+
+	*((u64*)&dsa) = 0;				
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	HvCall3Ret16(HvCallPciBarLoad64, &retVal, *(u64 *)&dsa, offsetParm, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	*valueParm = retVal.value;
+
+	return retVal.rc;
+}
+//============================================================================
+static inline u64	HvCallPci_barStore8(u16	busNumberParm,
+					    u8		subBusParm,
+					    u8		deviceIdParm,
+					    u8		barNumberParm,
+					    u64		offsetParm,
+					    u8		valueParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;
+				
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	retVal = HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm, valueParm, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_barStore16(u16	busNumberParm,
+					     u8		subBusParm,
+					     u8		deviceIdParm,
+					     u8		barNumberParm,
+					     u64	offsetParm,
+					     u16	valueParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;
+				
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	retVal = HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm, valueParm, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_barStore32(u16	busNumberParm,
+					     u8		subBusParm,
+					     u8		deviceIdParm,
+					     u8		barNumberParm,
+					     u64	offsetParm,
+					     u32	valueParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;
+				
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	retVal = HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm, valueParm, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_barStore64(u16	busNumberParm,
+					     u8		subBusParm,
+					     u8		deviceIdParm,
+					     u8		barNumberParm,
+					     u64	offsetParm,
+					     u64	valueParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;
+				
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	retVal = HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm, valueParm, 0);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_eoi(u16	busNumberParm,
+				      u8	subBusParm,  
+				      u8	deviceIdParm)
+{
+	struct HvCallPci_DsaAddr dsa;
+	struct HvCallPci_LoadReturn retVal;
+
+	*((u64*)&dsa) = 0;
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+
+	HvCall1Ret16(HvCallPciEoi, &retVal, *(u64*)&dsa);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal.rc;
+}
+//============================================================================
+static inline u64	HvCallPci_getBarParms(u16	busNumberParm,
+					      u8	subBusParm,  
+					      u8	deviceIdParm,
+					      u8	barNumberParm,
+					      u64	parms,
+					      u32	sizeofParms)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+	dsa.barNumber = barNumberParm;
+
+	retVal = HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_maskFisr(u16	busNumberParm,
+					   u8	subBusParm,  
+					   u8	deviceIdParm,
+					   u64	fisrMask)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;		
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+
+	retVal = HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_unmaskFisr(u16	busNumberParm,
+					     u8		subBusParm,  
+					     u8		deviceIdParm,
+					     u64	fisrMask)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;		
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+
+	retVal = HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_setSlotReset(u16		busNumberParm,
+					       u8		subBusParm,
+					       u8		deviceIdParm,
+					       u64		onNotOff)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+
+	retVal = HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_getDeviceInfo(u16	busNumberParm,
+						u8	subBusParm,  
+						u8	deviceNumberParm,
+						u64     parms,
+						u32	sizeofParms)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceNumberParm << 4;
+
+	retVal = HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_maskInterrupts(u16	busNumberParm,
+						 u8	subBusParm,  
+						 u8	deviceIdParm,
+						 u64	interruptMask)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;		
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+
+	retVal = HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+static inline u64	HvCallPci_unmaskInterrupts(u16	busNumberParm,
+						 u8		subBusParm,  
+						 u8		deviceIdParm,
+						 u64		interruptMask)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;		
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+
+	retVal = HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+
+static inline u64	HvCallPci_getBusUnitInfo(u16		busNumberParm,
+						 u8		subBusParm,  
+						 u8		deviceIdParm,
+						 u64            parms,
+						 u32		sizeofParms)
+{
+	struct HvCallPci_DsaAddr dsa;
+	u64 retVal;
+
+	*((u64*)&dsa) = 0;		
+
+	dsa.busNumber = busNumberParm;
+	dsa.subBusNumber = subBusParm;
+	dsa.deviceId = deviceIdParm;
+
+	retVal = HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms, sizeofParms);
+
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+
+	return retVal;
+}
+//============================================================================
+
+static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, u16 sizeParm)
+{
+	int xRetSize;
+	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusVpd);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	if (xRc == -1)
+		xRetSize = -1;
+	else
+		xRetSize = xRc & 0xFFFF;
+	return xRetSize;
+}
+//============================================================================
+
+static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm, u16 sizeParm)
+{
+	int xRetSize;
+	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusAdapterVpd);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	if (xRc == -1)
+		xRetSize = -1;
+	else
+		xRetSize = xRc & 0xFFFF;
+	return xRetSize;
+}
+//============================================================================
+#endif // _HVCALLPCI_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvCallSc.h linux/include/asm-ppc64/iSeries/HvCallSc.h
--- linux.orig/include/asm-ppc64/iSeries/HvCallSc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvCallSc.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ * HvCallSc.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+#ifndef _HVCALLSC_H
+#define _HVCALLSC_H
+
+#define HvCallBase		0x8000000000000000
+#define HvCallCfg		0x8002000000000000
+#define HvCallEvent		0x8003000000000000
+#define HvCallHpt		0x8004000000000000
+#define HvCallPci		0x8005000000000000
+#define HvCallSm		0x8007000000000000
+#define HvCallXm		0x8009000000000000
+
+u64 HvCall0( u64 );
+u64 HvCall1( u64, u64 );
+u64 HvCall2( u64, u64, u64 );
+u64 HvCall3( u64, u64, u64, u64 );
+u64 HvCall4( u64, u64, u64, u64, u64 );
+u64 HvCall5( u64, u64, u64, u64, u64, u64 );
+u64 HvCall6( u64, u64, u64, u64, u64, u64, u64 );
+u64 HvCall7( u64, u64, u64, u64, u64, u64, u64, u64 );
+
+u64 HvCall0Ret16( u64, void * );
+u64 HvCall1Ret16( u64, void *, u64 );
+u64 HvCall2Ret16( u64, void *, u64, u64 );
+u64 HvCall3Ret16( u64, void *, u64, u64, u64 );
+u64 HvCall4Ret16( u64, void *, u64, u64, u64, u64 );
+u64 HvCall5Ret16( u64, void *, u64, u64, u64, u64, u64 );
+u64 HvCall6Ret16( u64, void *, u64, u64, u64, u64, u64, u64 );
+u64 HvCall7Ret16( u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64 );
+
+#endif /* _HVCALLSC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvCallSm.h linux/include/asm-ppc64/iSeries/HvCallSm.h
--- linux.orig/include/asm-ppc64/iSeries/HvCallSm.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvCallSm.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,58 @@
+/*
+ * HvCallSm.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//============================================================================
+//
+//	This file contains the "hypervisor call" interface which is used to
+//	drive the hypervisor from the OS.
+//
+//============================================================================
+
+//-------------------------------------------------------------------
+// Standard Includes
+//-------------------------------------------------------------------
+#ifndef  _HVCALLSC_H
+#include "HvCallSc.h"
+#endif
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+#ifndef _HVCALLSM_H
+#define _HVCALLSM_H
+
+#define HvCallSmGet64BitsOfAccessMap	HvCallSm  + 11
+
+
+//============================================================================
+static inline u64		HvCallSm_get64BitsOfAccessMap(
+					HvLpIndex lpIndex, u64 indexIntoBitMap )
+{
+	u64 retval = HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex,
+			     indexIntoBitMap );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retval;
+}
+//============================================================================
+#endif // _HVCALLSM_H
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvCallXm.h linux/include/asm-ppc64/iSeries/HvCallXm.h
--- linux.orig/include/asm-ppc64/iSeries/HvCallXm.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvCallXm.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,106 @@
+//============================================================================
+//							 Header File Id
+// Name______________:	HvCallXm.H
+//
+// Description_______:
+//
+//	This file contains the "hypervisor call" interface which is used to
+//	drive the hypervisor from SLIC.
+//
+//============================================================================
+
+//-------------------------------------------------------------------
+// Forward declarations 
+//-------------------------------------------------------------------
+
+//-------------------------------------------------------------------
+// Standard Includes
+//-------------------------------------------------------------------
+#ifndef  _HVCALLSC_H
+#include "HvCallSc.h"
+#endif
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+//-------------------------------------------------------------------
+// Other Includes
+//-------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+#ifndef _HVCALLXM_H
+#define _HVCALLXM_H
+
+#define HvCallXmGetTceTableParms	HvCallXm +  0
+#define HvCallXmTestBus			HvCallXm +  1
+#define HvCallXmConnectBusUnit		HvCallXm +  2
+#define HvCallXmLoadTod			HvCallXm +  8
+#define HvCallXmTestBusUnit		HvCallXm +  9
+#define HvCallXmSetTce			HvCallXm + 11
+#define HvCallXmSetTces			HvCallXm + 13
+
+
+
+//============================================================================
+static inline void		HvCallXm_getTceTableParms(u64 cb)
+{
+	HvCall1(HvCallXmGetTceTableParms, cb);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+}
+//============================================================================
+static inline u64		HvCallXm_setTce(u64 tceTableToken, u64 tceOffset, u64 tce)
+{	
+	u64 retval = HvCall3(HvCallXmSetTce, tceTableToken, tceOffset, tce );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retval;
+}
+//============================================================================
+static inline u64		HvCallXm_setTces(u64 tceTableToken, u64 tceOffset, u64 numTces, u64 tce1, u64 tce2, u64 tce3, u64 tce4)
+{	
+	u64 retval = HvCall7(HvCallXmSetTces, tceTableToken, tceOffset, numTces,
+			     tce1, tce2, tce3, tce4 );
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retval;
+}
+//=============================================================================
+static inline u64	HvCallXm_testBus(u16 busNumber)
+{
+	u64 retVal = HvCall1(HvCallXmTestBus, busNumber);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//=====================================================================================
+static inline u64	HvCallXm_testBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId)
+{
+	u64 busUnitNumber = (subBusNumber << 8) | deviceId;
+	u64 retVal = HvCall2(HvCallXmTestBusUnit, busNumber, busUnitNumber);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//=====================================================================================
+static inline u64	HvCallXm_connectBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId,
+						u64 interruptToken)
+{
+	u64 busUnitNumber = (subBusNumber << 8) | deviceId;
+	u64 queueIndex = 0; // HvLpConfig::mapDsaToQueueIndex(HvLpDSA(busNumber, xBoard, xCard));  
+
+	u64 retVal = HvCall5(HvCallXmConnectBusUnit, busNumber, busUnitNumber,
+			     interruptToken, 0, queueIndex);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//=====================================================================================
+static inline u64	HvCallXm_loadTod(void)
+{
+	u64 retVal = HvCall0(HvCallXmLoadTod);
+	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return retVal;
+}
+//=====================================================================================
+
+#endif // _HVCALLXM_H
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvLpConfig.h linux/include/asm-ppc64/iSeries/HvLpConfig.h
--- linux.orig/include/asm-ppc64/iSeries/HvLpConfig.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvLpConfig.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,292 @@
+/*
+ * HvLpConfig.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//===========================================================================
+//
+//      This file contains the interface to the LPAR configuration data
+//  to determine which resources should be allocated to each partition.
+//
+//===========================================================================
+
+#ifndef  _HVCALLCFG_H
+#include "HvCallCfg.h"
+#endif
+
+#ifndef  _HVTYPES_H
+#include <asm/iSeries/HvTypes.h>
+#endif
+
+#ifndef  _ITLPNACA_H
+#include <asm/iSeries/ItLpNaca.h>
+#endif
+
+#ifndef  _LPARDATA_H
+#include <asm/iSeries/LparData.h>
+#endif
+
+#ifndef _HVLPCONFIG_H
+#define _HVLPCONFIG_H
+
+//-------------------------------------------------------------------
+// Constants
+//-------------------------------------------------------------------
+
+extern HvLpIndex HvLpConfig_getLpIndex_outline(void);
+
+//===================================================================
+static inline HvLpIndex	HvLpConfig_getLpIndex(void)
+{
+	return itLpNaca.xLpIndex;
+}
+//===================================================================
+static inline HvLpIndex	HvLpConfig_getPrimaryLpIndex(void)
+{
+	return itLpNaca.xPrimaryLpIndex;
+}
+//=================================================================
+static inline HvLpIndex	HvLpConfig_getLps(void)
+{
+	return HvCallCfg_getLps();
+}
+//=================================================================
+static inline HvLpIndexMap	HvLpConfig_getActiveLpMap(void)
+{
+	return HvCallCfg_getActiveLpMap();
+}
+//=================================================================
+static inline u64		HvLpConfig_getSystemMsMegs(void)
+{
+	return HvCallCfg_getSystemMsChunks() / HVCHUNKSPERMEG;
+}
+//=================================================================
+static inline u64		HvLpConfig_getSystemMsChunks(void)
+{
+	return HvCallCfg_getSystemMsChunks();
+}
+//=================================================================
+static inline u64		HvLpConfig_getSystemMsPages(void)
+{
+	return HvCallCfg_getSystemMsChunks() * HVPAGESPERCHUNK;
+}
+//================================================================
+static inline u64		HvLpConfig_getMsMegs(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur) / HVCHUNKSPERMEG;
+}
+//================================================================
+static inline u64		HvLpConfig_getMsChunks(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur);
+}
+//================================================================
+static inline u64		HvLpConfig_getMsPages(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur) * HVPAGESPERCHUNK;
+}
+//================================================================
+static inline u64		HvLpConfig_getMinMsMegs(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min) / HVCHUNKSPERMEG;
+}
+//================================================================
+static inline u64		HvLpConfig_getMinMsChunks(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min);
+}
+//================================================================
+static inline u64		HvLpConfig_getMinMsPages(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min) * HVPAGESPERCHUNK;
+}
+//================================================================
+static inline u64		HvLpConfig_getMinRuntimeMsMegs(void)
+{
+	return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) / HVCHUNKSPERMEG;
+}
+//===============================================================
+static inline u64		HvLpConfig_getMinRuntimeMsChunks(void)
+{
+	return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex());
+}
+//===============================================================
+static inline u64		HvLpConfig_getMinRuntimeMsPages(void)
+{
+	return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) * HVPAGESPERCHUNK;
+}
+//===============================================================
+static inline u64		HvLpConfig_getMaxMsMegs(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max) / HVCHUNKSPERMEG;
+}
+//===============================================================
+static inline u64		HvLpConfig_getMaxMsChunks(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max);
+}
+//===============================================================
+static inline u64		HvLpConfig_getMaxMsPages(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max) * HVPAGESPERCHUNK;
+}
+//===============================================================
+static inline u64		HvLpConfig_getInitMsMegs(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init) / HVCHUNKSPERMEG;
+}
+//===============================================================
+static inline u64		HvLpConfig_getInitMsChunks(void)
+{
+	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init);
+}
+//===============================================================
+static inline u64		HvLpConfig_getInitMsPages(void)
+{    return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init) * HVPAGESPERCHUNK;
+}
+//===============================================================
+static inline u64		HvLpConfig_getSystemPhysicalProcessors(void)
+{
+	return HvCallCfg_getSystemPhysicalProcessors();
+}
+//===============================================================
+static inline u64		HvLpConfig_getSystemLogicalProcessors(void)
+{
+	return HvCallCfg_getSystemPhysicalProcessors() * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
+}
+//===============================================================
+static inline u64		HvLpConfig_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI)
+{
+	return HvCallCfg_getNumProcsInSharedPool(sPI);
+}
+//===============================================================
+static inline u64		HvLpConfig_getPhysicalProcessors(void)
+{
+	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Cur);
+}
+//===============================================================
+static inline u64		HvLpConfig_getLogicalProcessors(void)
+{
+	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Cur) * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
+}
+//===============================================================
+static inline HvLpSharedPoolIndex	HvLpConfig_getSharedPoolIndex(void)
+{
+	return HvCallCfg_getSharedPoolIndex(HvLpConfig_getLpIndex());
+}
+//===============================================================
+static inline u64		HvLpConfig_getSharedProcUnits(void)
+{
+	return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Cur);
+}
+//===============================================================
+static inline u64		HvLpConfig_getMinSharedProcUnits(void)
+{
+	return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Min);
+}
+//===============================================================
+static inline u64		HvLpConfig_getMaxSharedProcUnits(void)
+{
+	return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Max);
+}
+//===============================================================
+static inline u64		HvLpConfig_getMinPhysicalProcessors(void)
+{
+	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Min);
+}
+//===============================================================
+static inline u64		HvLpConfig_getMinLogicalProcessors(void)
+{
+	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Min) * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
+}
+//===============================================================
+static inline u64		HvLpConfig_getMaxPhysicalProcessors(void)
+{
+	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Max);
+}
+//===============================================================
+static inline u64		HvLpConfig_getMaxLogicalProcessors(void)
+{
+	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Max) * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
+}
+//===============================================================
+static inline u64		HvLpConfig_getInitPhysicalProcessors(void)
+{
+	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Init);
+}
+//===============================================================
+static inline u64		HvLpConfig_getInitLogicalProcessors(void)
+{
+	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Init) * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
+}
+//================================================================
+static inline HvLpVirtualLanIndexMap	HvLpConfig_getVirtualLanIndexMap(void)
+{
+	return HvCallCfg_getVirtualLanIndexMap(HvLpConfig_getLpIndex_outline());
+}
+//===============================================================
+static inline HvLpVirtualLanIndexMap	HvLpConfig_getVirtualLanIndexMapForLp(HvLpIndex lp)
+{
+	return HvCallCfg_getVirtualLanIndexMap(lp);
+}
+//================================================================
+static inline HvLpIndex	HvLpConfig_getBusOwner(HvBusNumber busNumber)
+{
+	return HvCallCfg_getBusOwner(busNumber);
+}
+//===============================================================
+static inline int		HvLpConfig_isBusDedicated(HvBusNumber busNumber)
+{
+	return HvCallCfg_isBusDedicated(busNumber);
+}
+//================================================================
+static inline HvLpIndexMap	HvLpConfig_getBusAllocation(HvBusNumber busNumber)
+{
+	return HvCallCfg_getBusAllocation(busNumber);
+}
+//================================================================
+// returns the absolute real address of the load area
+static inline u64		HvLpConfig_getLoadAddress(void)
+{
+	return itLpNaca.xLoadAreaAddr & 0x7fffffffffffffff;
+}
+//================================================================
+static inline u64		HvLpConfig_getLoadPages(void)
+{
+	return itLpNaca.xLoadAreaChunks * HVPAGESPERCHUNK;
+}
+//================================================================
+static inline int		HvLpConfig_isBusOwnedByThisLp(HvBusNumber busNumber)
+{
+	HvLpIndex busOwner = HvLpConfig_getBusOwner(busNumber);
+	return (busOwner == HvLpConfig_getLpIndex());
+}
+//================================================================
+static inline int         HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1, HvLpIndex lp2)
+{
+	HvLpVirtualLanIndexMap virtualLanIndexMap1 = HvCallCfg_getVirtualLanIndexMap( lp1 );
+	HvLpVirtualLanIndexMap virtualLanIndexMap2 = HvCallCfg_getVirtualLanIndexMap( lp2 );
+	return ((virtualLanIndexMap1 & virtualLanIndexMap2) != 0);
+}
+//================================================================
+static inline HvLpIndex		HvLpConfig_getHostingLpIndex(HvLpIndex lp)
+{
+	return HvCallCfg_getHostingLpIndex(lp);
+}
+//================================================================
+
+#endif // _HVLPCONFIG_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvLpEvent.h linux/include/asm-ppc64/iSeries/HvLpEvent.h
--- linux.orig/include/asm-ppc64/iSeries/HvLpEvent.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvLpEvent.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,144 @@
+/*
+ * HvLpEvent.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//======================================================================
+//
+//	This file contains the class for HV events in the system.
+//
+//=====================================================================
+#ifndef _HVLPEVENT_H
+#define _HVLPEVENT_H
+
+#include <asm/types.h>
+#include <asm/ptrace.h>
+#include <asm/iSeries/HvTypes.h>
+#ifndef _HVCALLEVENT_H
+#include <asm/iSeries/HvCallEvent.h>
+#endif
+
+
+//=====================================================================
+//
+// HvLpEvent is the structure for Lp Event messages passed between
+// partitions through PLIC. 
+//
+//=====================================================================
+
+struct HvEventFlags
+{
+	u8	xValid:1;		// Indicates a valid request	x00-x00
+	u8	xRsvd1:4;		// Reserved			...
+	u8	xAckType:1;		// Immediate or deferred	...
+	u8	xAckInd:1;		// Indicates if ACK required	...
+	u8	xFunction:1;		// Interrupt or Acknowledge	...
+};
+
+
+struct HvLpEvent
+{
+	struct HvEventFlags xFlags;	// Event flags			x00-x00
+	u8	xType;			// Type of message		x01-x01
+	u16	xSubtype;		// Subtype for event		x02-x03
+	u8	xSourceLp;		// Source LP			x04-x04
+	u8	xTargetLp;		// Target LP			x05-x05
+	u8	xSizeMinus1;		// Size of Derived class - 1	x06-x06
+	u8	xRc;			// RC for Ack flows		x07-x07
+	u16	xSourceInstanceId;	// Source sides instance id	x08-x09
+	u16	xTargetInstanceId;	// Target sides instance id	x0A-x0B
+	union {
+		u32	xSubtypeData;	// Data usable by the subtype	x0C-x0F
+		u16	xSubtypeDataShort[2];	// Data as 2 shorts
+		u8	xSubtypeDataChar[4];	// Data as 4 chars
+	} x;
+
+	u64	xCorrelationToken;	// Unique value for source/type x10-x17
+};
+
+// Lp Event handler function
+typedef void (*LpEventHandler)(struct HvLpEvent *, struct pt_regs *);
+
+// Register a handler for an event type
+//  returns 0 on success
+extern int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler hdlr);
+
+// Unregister a handler for an event type
+//  returns 0 on success
+//  Unregister will fail if there are any paths open for the type
+extern int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType );
+
+// Open an Lp Event Path for an event type
+//  returns 0 on success
+//  openPath will fail if there is no handler registered for the event type.
+//  The lpIndex specified is the partition index for the target partition
+//  (for VirtualIo, VirtualLan and SessionMgr) other types specify zero) 
+extern int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex );
+
+
+// Close an Lp Event Path for a type and partition
+//  returns 0 on sucess
+extern int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex );
+
+#define HvLpEvent_Type_Hypervisor 0
+#define HvLpEvent_Type_MachineFac 1
+#define HvLpEvent_Type_SessionMgr 2
+#define HvLpEvent_Type_SpdIo      3
+#define HvLpEvent_Type_VirtualBus 4
+#define HvLpEvent_Type_PciIo      5
+#define HvLpEvent_Type_RioIo      6
+#define HvLpEvent_Type_VirtualLan 7
+#define HvLpEvent_Type_VirtualIo  8
+#define HvLpEvent_Type_NumTypes   9
+
+#define HvLpEvent_Rc_Good 0
+#define HvLpEvent_Rc_BufferNotAvailable 1
+#define HvLpEvent_Rc_Cancelled 2
+#define HvLpEvent_Rc_GenericError 3
+#define HvLpEvent_Rc_InvalidAddress 4
+#define HvLpEvent_Rc_InvalidPartition 5
+#define HvLpEvent_Rc_InvalidSize 6
+#define HvLpEvent_Rc_InvalidSubtype 7
+#define HvLpEvent_Rc_InvalidSubtypeData 8
+#define HvLpEvent_Rc_InvalidType 9
+#define HvLpEvent_Rc_PartitionDead 10
+#define HvLpEvent_Rc_PathClosed 11
+#define HvLpEvent_Rc_SubtypeError 12
+
+#define HvLpEvent_Function_Ack 0
+#define HvLpEvent_Function_Int 1
+
+#define HvLpEvent_AckInd_NoAck 0
+#define HvLpEvent_AckInd_DoAck 1
+
+#define HvLpEvent_AckType_ImmediateAck 0
+#define HvLpEvent_AckType_DeferredAck 1
+
+#define HvLpDma_Direction_LocalToRemote 0
+#define HvLpDma_Direction_RemoteToLocal 1
+
+#define HvLpDma_AddressType_TceIndex 0
+#define HvLpDma_AddressType_RealAddress 1
+
+#define HvLpDma_Rc_Good 0
+#define HvLpDma_Rc_Error 1
+#define HvLpDma_Rc_PartitionDead 2
+#define HvLpDma_Rc_PathClosed 3
+#define HvLpDma_Rc_InvalidAddress 4
+#define HvLpDma_Rc_InvalidLength 5
+
+#endif // _HVLPEVENT_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvReleaseData.h linux/include/asm-ppc64/iSeries/HvReleaseData.h
--- linux.orig/include/asm-ppc64/iSeries/HvReleaseData.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvReleaseData.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,70 @@
+/*
+ * HvReleaseData.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//=============================================================================
+//
+//   This control block contains the critical information about the 
+//   release so that it can be changed in the future (ie, the virtual 
+//   address of the OS's NACA).
+//
+//-----------------------------------------------------------------------------
+// Standard Includes
+//-----------------------------------------------------------------------------
+#ifndef	_PPC64_TYPES_H
+#include	<asm/types.h>
+#endif
+
+#ifndef _HVRELEASEDATA_H
+#define _HVRELEASEDATA_H
+
+//=============================================================================
+//
+//	When we IPL a secondary partition, we will check if if the 
+//	secondary xMinPlicVrmIndex > the primary xVrmIndex.  
+//	If it is then this tells PLIC that this secondary is not 
+//	supported running on this "old" of a level of PLIC.
+//
+//	Likewise, we will compare the primary xMinSlicVrmIndex to 
+//	the secondary xVrmIndex. 
+//	If the primary xMinSlicVrmDelta > secondary xVrmDelta then we 
+//	know that this PLIC does not support running an OS "that old".
+//
+//=============================================================================
+
+struct	HvReleaseData
+{
+	u32	xDesc;			// Descriptor	"HvRD" ebcdic	x00-x03
+	u16	xSize;			// Size of this control block	x04-x05
+	u16	xVpdAreasPtrOffset;	// Offset in NACA of ItVpdAreas	x06-x07
+	struct  naca_struct * xSlicNacaAddr; // Virt addr of SLIC NACA  x08-x0F
+	u32	xMsNucDataOffset;	// Offset of Linux Mapping Data x10-x13
+	u32	xRsvd1;			// Reserved			x14-x17
+	u16	xTagsMode:1;		// 0 == tags active, 1 == tags inactive
+	u16	xAddressSize:1;		// 0 == 64-bit, 1 == 32-bit
+	u16	xNoSharedProcs:1;	// 0 == shared procs, 1 == no shared
+	u16	xNoHMT:1;		// 0 == allow HMT, 1 == no HMT
+	u16	xRsvd2:12;		// Reserved			x18-x19
+	u16	xVrmIndex;		// VRM Index of OS image	x1A-x1B
+	u16	xMinSupportedPlicVrmIndex;// Min PLIC level  (soft)	x1C-x1D
+	u16	xMinCompatablePlicVrmIndex;// Min PLIC levelP (hard)	x1E-x1F
+	char	xVrmName[12];		// Displayable name  		x20-x2B
+	char	xRsvd3[20];		// Reserved			x2C-x3F
+};
+
+#endif // _HVRELEASEDATA_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/HvTypes.h linux/include/asm-ppc64/iSeries/HvTypes.h
--- linux.orig/include/asm-ppc64/iSeries/HvTypes.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/HvTypes.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,127 @@
+/*
+ * HvTypes.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//===========================================================================
+//                                                             Header File Id
+// Name______________:  HvTypes.H
+//
+// Description_______:
+//
+//	General typedefs for the hypervisor.
+//
+// Declared Class(es):
+//
+//===========================================================================
+
+#ifndef _PPC_TYPES_H
+#include        <asm/types.h>
+#endif
+
+
+#ifndef _HVTYPES_H
+#define _HVTYPES_H
+
+//-------------------------------------------------------------------
+// Typedefs
+//-------------------------------------------------------------------
+typedef u8	HvLpIndex;
+typedef u16	HvLpInstanceId;
+typedef u64     HvLpTOD;
+typedef u64     HvLpSystemSerialNum;
+typedef u8      HvLpDeviceSerialNum[12];
+typedef u16     HvLpSanHwSet;
+typedef u16     HvLpBus;
+typedef u16     HvLpBoard;
+typedef u16     HvLpCard;
+typedef u8      HvLpDeviceType[4];
+typedef u8      HvLpDeviceModel[3];
+typedef u64     HvIoToken;
+typedef u8      HvLpName[8];
+typedef u32	HvIoId;
+typedef u64	HvRealMemoryIndex;
+typedef u32     HvLpIndexMap;		// Must hold HvMaxArchitectedLps bits!!!
+typedef u16	HvLpVrmIndex;
+typedef u32	HvXmGenerationId;
+typedef u8	HvLpBusPool;			
+typedef u8	HvLpSharedPoolIndex;		
+typedef u16	HvLpSharedProcUnitsX100;
+typedef u8	HvLpVirtualLanIndex;
+typedef u16	HvLpVirtualLanIndexMap;	// Must hold HvMaxArchitectedVirtualLans bits!!!
+typedef u16	HvBusNumber;		// Hypervisor Bus Number
+typedef u8	HvSubBusNumber;		// Hypervisor SubBus Number
+typedef u8	HvAgentId;		// Hypervisor DevFn
+
+
+#define HVMAXARCHITECTEDLPS 32
+#define HVCHUNKSIZE 256 * 1024
+#define HVPAGESIZE 4 * 1024
+#define HVLPMINMEGSPRIMARY 256
+#define HVLPMINMEGSSECONDARY 64
+#define HVCHUNKSPERMEG 4
+#define HVPAGESPERMEG 256
+#define HVPAGESPERCHUNK 64
+ 
+#define HvMaxArchitectedLps 		((HvLpIndex)HVMAXARCHITECTEDLPS)
+#define HvMaxArchitectedVirtualLans	((HvLpVirtualLanIndex)16)
+#define HvLpIndexInvalid		((HvLpIndex)0xff)
+
+//--------------------------------------------------------------------
+// Enums for the sub-components under PLIC
+// Used in HvCall  and HvPrimaryCall
+//--------------------------------------------------------------------
+enum   HvCallCompIds
+{
+	HvCallCompId = 0,
+	HvCallCpuCtlsCompId = 1,
+	HvCallCfgCompId = 2,
+	HvCallEventCompId = 3,
+	HvCallHptCompId = 4,
+	HvCallPciCompId = 5,
+	HvCallSlmCompId = 6,
+	HvCallSmCompId = 7,
+	HvCallSpdCompId = 8,
+	HvCallXmCompId = 9,
+	HvCallRioCompId = 10, 
+	HvCallRsvd3CompId = 11,
+	HvCallRsvd2CompId = 12,
+	HvCallRsvd1CompId = 13,
+	HvCallMaxCompId = 14,
+	HvPrimaryCallCompId = 0,    
+	HvPrimaryCallCfgCompId = 1,
+	HvPrimaryCallPciCompId = 2,    
+	HvPrimaryCallSmCompId = 3,
+	HvPrimaryCallSpdCompId = 4,
+	HvPrimaryCallXmCompId = 5,
+	HvPrimaryCallRioCompId = 6, 
+	HvPrimaryCallRsvd7CompId = 7,
+	HvPrimaryCallRsvd6CompId = 8,
+	HvPrimaryCallRsvd5CompId = 9,
+	HvPrimaryCallRsvd4CompId = 10,
+	HvPrimaryCallRsvd3CompId = 11,
+	HvPrimaryCallRsvd2CompId = 12,
+	HvPrimaryCallRsvd1CompId = 13,
+	HvPrimaryCallMaxCompId = HvCallMaxCompId     
+};
+
+struct HvLpBufferList {
+	u64 addr;
+	u64 len;
+};
+
+#endif // _HVTYPES_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/IoHriMainStore.h linux/include/asm-ppc64/iSeries/IoHriMainStore.h
--- linux.orig/include/asm-ppc64/iSeries/IoHriMainStore.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/IoHriMainStore.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,167 @@
+/*
+ * IoHriMainStore.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+#ifndef _IOHRIMAINSTORE_H
+#define _IOHRIMAINSTORE_H
+
+/* Main Store Vpd for Condor,iStar,sStar */
+struct IoHriMainStoreSegment4 {    
+	u8	msArea0Exists:1;
+	u8	msArea1Exists:1;
+	u8	msArea2Exists:1;
+	u8	msArea3Exists:1;
+	u8	reserved1:4;
+	u8	reserved2;
+
+	u8	msArea0Functional:1;
+	u8	msArea1Functional:1;
+	u8	msArea2Functional:1;
+	u8	msArea3Functional:1;
+	u8	reserved3:4;
+	u8	reserved4;
+
+	u32	totalMainStore;
+
+	u64	msArea0Ptr;
+	u64	msArea1Ptr;
+	u64	msArea2Ptr;
+	u64	msArea3Ptr;
+
+	u32	cardProductionLevel;
+
+	u32	msAdrHole;
+
+	u8	msArea0HasRiserVpd:1;
+	u8	msArea1HasRiserVpd:1;
+	u8	msArea2HasRiserVpd:1;
+	u8	msArea3HasRiserVpd:1;
+	u8	reserved5:4;	
+	u8	reserved6;
+	u16	reserved7;
+
+	u8	reserved8[28];
+
+	u64	nonInterleavedBlocksStartAdr;
+	u64	nonInterleavedBlocksEndAdr;
+};
+
+/* Main Store VPD for Power4 */
+struct IoHriMainStoreChipInfo1 {
+	u32	chipMfgID	__attribute((packed));
+	char	chipECLevel[4]	__attribute((packed));
+};
+
+struct IoHriMainStoreVpdIdData {
+	char	typeNumber[4];
+	char	modelNumber[4];
+	char	partNumber[12];
+	char	serialNumber[12];
+};
+
+struct IoHriMainStoreVpdFruData {
+	char	fruLabel[8]	__attribute((packed));
+	u8	numberOfSlots	__attribute((packed));
+	u8	pluggingType	__attribute((packed));
+	u16	slotMapIndex	__attribute((packed));
+};
+
+struct IoHriMainStoreAdrRangeBlock {
+	void *	blockStart      __attribute((packed));
+	void *	blockEnd        __attribute((packed));
+	u32	blockProcChipId __attribute((packed));
+};
+
+#define MaxAreaAdrRangeBlocks 4
+
+struct IoHriMainStoreArea4 {
+	u32	msVpdFormat			__attribute((packed));
+	u8	containedVpdType		__attribute((packed));
+	u8	reserved1			__attribute((packed));
+	u16	reserved2			__attribute((packed));
+
+	u64	msExists			__attribute((packed));
+	u64	msFunctional			__attribute((packed));
+
+	u32	memorySize			__attribute((packed));
+	u32	procNodeId			__attribute((packed));
+
+	u32	numAdrRangeBlocks		__attribute((packed));
+	struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks] __attribute((packed));
+
+	struct IoHriMainStoreChipInfo1	chipInfo0	__attribute((packed));
+	struct IoHriMainStoreChipInfo1	chipInfo1	__attribute((packed));
+	struct IoHriMainStoreChipInfo1	chipInfo2	__attribute((packed));
+	struct IoHriMainStoreChipInfo1	chipInfo3	__attribute((packed));
+	struct IoHriMainStoreChipInfo1	chipInfo4	__attribute((packed));
+	struct IoHriMainStoreChipInfo1	chipInfo5	__attribute((packed));
+	struct IoHriMainStoreChipInfo1	chipInfo6	__attribute((packed));
+	struct IoHriMainStoreChipInfo1	chipInfo7	__attribute((packed));
+
+	void *   msRamAreaArray			__attribute((packed));
+	u32	msRamAreaArrayNumEntries	__attribute((packed));
+	u32	msRamAreaArrayEntrySize		__attribute((packed));
+
+	u32	numaDimmExists			__attribute((packed));
+	u32	numaDimmFunctional		__attribute((packed));
+	void *	numaDimmArray			__attribute((packed));
+	u32	numaDimmArrayNumEntries		__attribute((packed));
+	u32	numaDimmArrayEntrySize		__attribute((packed));
+
+	struct IoHriMainStoreVpdIdData  idData	__attribute((packed));
+
+	u64	powerData			__attribute((packed));
+	u64	cardAssemblyPartNum		__attribute((packed));
+	u64	chipSerialNum			__attribute((packed));
+
+	u64	reserved3			__attribute((packed));
+	char	reserved4[16]			__attribute((packed));
+
+	struct IoHriMainStoreVpdFruData fruData	__attribute((packed));
+
+	u8	vpdPortNum			__attribute((packed));
+	u8	reserved5			__attribute((packed));
+	u8	frameId				__attribute((packed));
+	u8	rackUnit			__attribute((packed));
+	char	asciiKeywordVpd[256]		__attribute((packed));
+	u32	reserved6			__attribute((packed));
+};
+
+
+struct IoHriMainStoreSegment5 {    
+	u16	reserved1;
+	u8	reserved2;
+	u8	msVpdFormat;
+
+	u32	totalMainStore;
+	u64	maxConfiguredMsAdr;
+
+	struct IoHriMainStoreArea4*	msAreaArray;
+	u32	msAreaArrayNumEntries;
+	u32	msAreaArrayEntrySize;
+
+	u32	msAreaExists;    
+	u32	msAreaFunctional;
+
+	u64	reserved3;
+};
+
+
+
+#endif // _IOHRIMAINSTORE_H
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/IoHriProcessorVpd.h linux/include/asm-ppc64/iSeries/IoHriProcessorVpd.h
--- linux.orig/include/asm-ppc64/iSeries/IoHriProcessorVpd.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/IoHriProcessorVpd.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,90 @@
+/*
+ * IoHriProcessorVpd.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//===================================================================
+//
+//	This struct maps Processor Vpd that is DMAd to SLIC by CSP 
+//
+
+#ifndef	_TYPES_H
+#include <asm/types.h>
+#endif
+
+#ifndef _IOHRIPROCESSORVPD_H
+#define _IOHRIPROCESSORVPD_H
+
+struct IoHriProcessorVpd
+{
+
+	u8	xFormat;		// VPD format indicator		x00-x00
+	u8	xProcStatus:8;		// Processor State		x01-x01
+	u8	xSecondaryThreadCount;	// Secondary thread cnt		x02-x02
+	u8	xSrcType:1;		// Src Type			x03-x03
+	u8	xSrcSoft:1;		// Src stay soft		...
+	u8	xSrcParable:1;		// Src parable			...
+	u8	xRsvd1:5;		// Reserved			...
+	u16	xHvPhysicalProcIndex;	// Hypervisor physical proc index04-x05
+	u16	xRsvd2;			// Reserved			x06-x07
+	u32	xHwNodeId;		// Hardware node id		x08-x0B
+	u32	xHwProcId;		// Hardware processor id	x0C-x0F
+	
+	u32	xTypeNum;		// Card Type/CCIN number	x10-x13
+	u32	xModelNum;		// Model/Feature number		x14-x17
+	u64	xSerialNum;		// Serial number		x18-x1F
+	char xPartNum[12];		// Book Part or FPU number	x20-x2B
+	char xMfgID[4];			// Manufacturing ID		x2C-x2F
+
+	u32	xProcFreq;		// Processor Frequency		x30-x33
+	u32	xTimeBaseFreq;		// Time Base Frequency		x34-x37
+
+	u32	xChipEcLevel;		// Chip EC Levels		x38-x3B
+	u32	xProcIdReg;		// PIR SPR value		x3C-x3F
+	u32	xPVR;			// PVR value			x40-x43
+	u8	xRsvd3[12];		// Reserved			x44-x4F
+
+	u32	xInstCacheSize;		// Instruction cache size in KB	x50-x53
+	u32	xInstBlockSize;		// Instruction cache block size	x54-x57
+	u32	xDataCacheOperandSize;	// Data cache operand size	x58-x5B
+	u32	xInstCacheOperandSize;	// Inst cache operand size	x5C-x5F
+
+	u32	xDataL1CacheSizeKB;	// L1 data cache size in KB	x60-x63
+	u32	xDataL1CacheLineSize;	// L1 data cache block size	x64-x67
+	u64	xRsvd4;			// Reserved			x68-x6F
+
+	u32	xDataL2CacheSizeKB;	// L2 data cache size in KB	x70-x73
+	u32	xDataL2CacheLineSize;	// L2 data cache block size	x74-x77
+	u64	xRsvd5;			// Reserved			x78-x7F
+
+	u32	xDataL3CacheSizeKB;	// L3 data cache size in KB	x80-x83
+	u32	xDataL3CacheLineSize;	// L3 data cache block size	x84-x87
+	u64	xRsvd6;			// Reserved			x88-x8F
+   
+	u64	xFruLabel;		// Card Location Label		x90-x97
+	u8	xSlotsOnCard;		// Slots on card (0=no slots)	x98-x98
+	u8	xPartLocFlag;		// Location flag (0-pluggable 1-imbedded) x99-x99
+	u16	xSlotMapIndex;		// Index in slot map table	x9A-x9B
+	u8	xSmartCardPortNo;	// Smart card port number	x9C-x9C
+	u8	xRsvd7;			// Reserved			x9D-x9D
+	u16	xFrameIdAndRackUnit;	// Frame ID and rack unit adr	x9E-x9F
+    
+	u8	xRsvd8[24];		// Reserved			xA0-xB7
+
+	char xProcSrc[72];		// CSP format SRC		xB8-xFF
+};
+#endif // _IOHRIPROCESSORVPD_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/ItIplParmsReal.h linux/include/asm-ppc64/iSeries/ItIplParmsReal.h
--- linux.orig/include/asm-ppc64/iSeries/ItIplParmsReal.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/ItIplParmsReal.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,78 @@
+/*
+ * ItIplParmsReal.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//==============================================================================
+//
+//	This struct maps the IPL Parameters DMA'd from the SP.                  
+//
+// Warning:
+//	This data must map in exactly 64 bytes and match the architecture for
+//	the IPL parms
+//
+//=============================================================================
+
+
+//-------------------------------------------------------------------
+// Standard Includes
+//-------------------------------------------------------------------
+#ifndef	_PPC_TYPES_H
+#include	<asm/types.h>
+#endif
+
+#ifndef _ITIPLPARMSREAL_H
+#define _ITIPLPARMSREAL_H
+
+struct ItIplParmsReal
+{
+	u8	xFormat;		// Defines format of IplParms		x00-x00
+	u8	xRsvd01:6;		// Reserved				x01-x01
+	u8	xAlternateSearch:1;	// Alternate search indicator		...
+	u8	xUaSupplied:1;		// UA Supplied on programmed IPL	...
+	u8	xLsUaFormat;		// Format byte for UA			x02-x02
+	u8	xRsvd02;		// Reserved				x03-x03
+	u32	xLsUa;			// LS UA				x04-x07
+	u32	xUnusedLsLid;		// First OS LID to load			x08-x0B
+	u16	xLsBusNumber;		// LS Bus Number			x0C-x0D
+	u8	xLsCardAdr;		// LS Card Address			x0E-x0E
+	u8	xLsBoardAdr;		// LS Board Address			x0F-x0F
+	u32	xRsvd03;		// Reserved				x10-x13
+	u8	xSpcnPresent:1;		// SPCN present				x14-x14
+	u8	xCpmPresent:1;		// CPM present				...
+	u8	xRsvd04:6;		// Reserved				...
+	u8	xRsvd05:4;		// Reserved				x15-x15
+	u8	xKeyLock:4;		// Keylock setting			...
+	u8	xRsvd06:6;		// Reserved				x16-x16
+	u8	xIplMode:2;		// Ipl mode (A|B|C|D)			...
+	u8	xHwIplType;		// Fast v slow v slow EC HW IPL		x17-x17
+	u16	xCpmEnabledIpl:1;	// CPM in effect when IPL initiated	x18-x19
+	u16	xPowerOnResetIpl:1;	// Indicate POR condition		...
+	u16	xMainStorePreserved:1;	// Main Storage is preserved		...
+	u16	xRsvd07:13;		// Reserved				...
+	u16	xIplSource:16;		// Ipl source				x1A-x1B
+	u8	xIplReason:8;		// Reason for this IPL			x1C-x1C
+	u8	xRsvd08;		// Reserved				x1D-x1D
+	u16	xRsvd09;		// Reserved				x1E-x1F
+	u16	xSysBoxType;		// System Box Type			x20-x21
+	u16	xSysProcType;		// System Processor Type		x22-x23
+	u32	xRsvd10;		// Reserved				x24-x27
+	u64	xRsvd11;		// Reserved				x28-x2F
+	u64	xRsvd12;		// Reserved				x30-x37
+	u64	xRsvd13;		// Reserved				x38-x3F
+};
+#endif // _ITIPLPARMSREAL_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/ItLpNaca.h linux/include/asm-ppc64/iSeries/ItLpNaca.h
--- linux.orig/include/asm-ppc64/iSeries/ItLpNaca.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/ItLpNaca.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,90 @@
+/*
+ * ItLpNaca.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//=============================================================================
+//
+//	This control block contains the data that is shared between the
+//	hypervisor (PLIC) and the OS.
+//
+//=============================================================================
+
+
+#ifndef _ITLPNACA_H
+#define _ITLPNACA_H
+
+struct ItLpNaca
+{
+//=============================================================================
+// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
+//=============================================================================
+	u32	xDesc;			// Eye catcher			x00-x03
+	u16	xSize;			// Size of this class		x04-x05
+	u16	xIntHdlrOffset;		// Offset to IntHdlr array	x06-x07
+	u8	xMaxIntHdlrEntries;	// Number of entries in array	x08-x08
+	u8	xPrimaryLpIndex;	// LP Index of Primary		x09-x09
+	u8	xServiceLpIndex;	// LP Ind of Service Focal Pointx0A-x0A
+	u8	xLpIndex;		// LP Index			x0B-x0B
+	u16	xMaxLpQueues;		// Number of allocated queues	x0C-x0D
+	u16	xLpQueueOffset;		// Offset to start of LP queues	x0E-x0F
+	u8	xPirEnvironMode:8;	// Piranha or hardware		x10-x10
+	u8	xPirConsoleMode:8;	// Piranha console indicator	x11-x11
+	u8	xPirDasdMode:8;		// Piranha dasd indicator	x12-x12
+	u8	xRsvd1_0[5];		// Reserved for Piranha related	x13-x17
+	u8	xLparInstalled:1;	// Is LPAR installed on system	x18-x1F
+	u8	xSysPartitioned:1;	// Is the system partitioned	...
+	u8	xHwSyncedTBs:1;		// Hardware synced TBs		...
+	u8	xIntProcUtilHmt:1;	// Utilize HMT for interrupts	...
+	u8	xRsvd1_1:4;		// Reserved			...
+	u8	xSpVpdFormat:8;		// VPD areas are in CSP format	...
+	u8	xIntProcRatio:8;	// Ratio of int procs to procs	...
+	u8	xRsvd1_2[5];		// Reserved			...
+	u16	xRsvd1_3;		// Reserved			x20-x21
+	u16	xPlicVrmIndex;		// VRM index of PLIC		x22-x23
+	u16	xMinSupportedSlicVrmInd;// Min supported OS VRM index	x24-x25
+	u16	xMinCompatableSlicVrmInd;// Min compatable OS VRM index x26-x27
+	u64	xLoadAreaAddr;		// ER address of load area	x28-x2F
+	u32	xLoadAreaChunks;	// Chunks for the load area	x30-x33
+	u32	xPaseSysCallCRMask;	// Mask used to test CR before  x34-x37
+	// doing an ASR switch on PASE
+	// system call.
+	u64	xSlicSegmentTablePtr;   // Pointer to Slic seg table.   x38-x3f
+	u8	xRsvd1_4[64];		//         			x40-x7F 
+   
+//=============================================================================
+// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
+//=============================================================================
+	u8	xRsvd2_0[128];		// Reserved			x00-x7F
+
+//=============================================================================
+// CACHE_LINE_3-6 0x0100 - 0x02FF Contains LP Queue indicators
+// NB: Padding required to keep xInterrruptHdlr at x300 which is required 
+// for v4r4 PLIC.
+//=============================================================================
+	u8	xOldLpQueue[128];	// LP Queue needed for v4r4	100-17F
+	u8	xRsvd3_0[384];		// Reserved			180-2FF
+//=============================================================================
+// CACHE_LINE_7-8 0x0300 - 0x03FF Contains the address of the OS interrupt
+//  handlers
+//=============================================================================
+	u64	xInterruptHdlr[32];	// Interrupt handlers		300-x3FF
+};
+
+//=============================================================================
+
+#endif // _ITLPNACA_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/ItLpPaca.h linux/include/asm-ppc64/iSeries/ItLpPaca.h
--- linux.orig/include/asm-ppc64/iSeries/ItLpPaca.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/ItLpPaca.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,134 @@
+/*
+ * ItLpPaca.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//=============================================================================
+//                                   
+//	This control block contains the data that is shared between the 
+//	hypervisor (PLIC) and the OS.
+//    
+//
+//----------------------------------------------------------------------------
+#ifndef  _PPC_TYPES_H
+#include <asm/types.h>
+#endif
+
+#ifndef _ITLPPACA_H
+#define _ITLPPACA_H
+
+
+struct ItLpPaca
+{
+//=============================================================================
+// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
+// NOTE: The xDynXyz fields are fields that will be dynamically changed by 
+// PLIC when preparing to bring a processor online or when dispatching a 
+// virtual processor!
+//=============================================================================
+	u32	xDesc;			// Eye catcher 0xD397D781	x00-x03
+	u16	xSize;			// Size of this struct		x04-x05
+	u16	xRsvd1_0;		// Reserved			x06-x07
+	u16	xRsvd1_1:14;		// Reserved			x08-x09
+	u8	xSharedProc:1;		// Shared processor indicator	...
+	u8	xSecondaryThread:1;	// Secondary thread indicator	...
+	volatile u8 xDynProcStatus:8;	// Dynamic Status of this proc	x0A-x0A
+	u8	xSecondaryThreadCnt;	// Secondary thread count	x0B-x0B
+	volatile u16 xDynHvPhysicalProcIndex;// Dynamic HV Physical Proc Index0C-x0D
+	volatile u16 xDynHvLogicalProcIndex;// Dynamic HV Logical Proc Indexx0E-x0F
+	u32	xDecrVal;   		// Value for Decr programming 	x10-x13
+	u32	xPMCVal;       		// Value for PMC regs         	x14-x17
+	volatile u32 xDynHwNodeId;	// Dynamic Hardware Node id	x18-x1B
+	volatile u32 xDynHwProcId;	// Dynamic Hardware Proc Id	x1C-x1F
+	volatile u32 xDynPIR;		// Dynamic ProcIdReg value	x20-x23
+	u32	xDseiData;           	// DSEI data                  	x24-x27
+	u64	xSPRG3;               	// SPRG3 value                	x28-x2F
+	u8	xRsvd1_3[80];		// Reserved			x30-x7F
+   
+//=============================================================================
+// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
+//=============================================================================
+	// This Dword contains a byte for each type of interrupt that can occur.  
+	// The IPI is a count while the others are just a binary 1 or 0.
+	union {
+		u64	xAnyInt;
+		struct {
+			u16	xRsvd;		// Reserved - cleared by #mpasmbl
+			u8	xXirrInt;	// Indicates xXirrValue is valid or Immed IO
+			u8	xIpiCnt;	// IPI Count
+			u8	xDecrInt;	// DECR interrupt occurred
+			u8	xPdcInt;	// PDC interrupt occurred
+			u8	xQuantumInt;	// Interrupt quantum reached
+			u8	xOldPlicDeferredExtInt;	// Old PLIC has a deferred XIRR pending
+		} xFields;
+	} xIntDword;
+
+	// Whenever any fields in this Dword are set then PLIC will defer the 
+	// processing of external interrupts.  Note that PLIC will store the 
+	// XIRR directly into the xXirrValue field so that another XIRR will 
+	// not be presented until this one clears.  The layout of the low 
+	// 4-bytes of this Dword is upto SLIC - PLIC just checks whether the 
+	// entire Dword is zero or not.  A non-zero value in the low order 
+	// 2-bytes will result in SLIC being granted the highest thread 
+	// priority upon return.  A 0 will return to SLIC as medium priority.
+	u64	xPlicDeferIntsArea;	// Entire Dword
+
+	// Used to pass the real SRR0/1 from PLIC to SLIC as well as to 
+	// pass the target SRR0/1 from SLIC to PLIC on a SetAsrAndRfid.
+	u64     xSavedSrr0;             // Saved SRR0                   x10-x17
+	u64     xSavedSrr1;             // Saved SRR1                   x18-x1F
+
+	// Used to pass parms from the OS to PLIC for SetAsrAndRfid
+	u64     xSavedGpr3;             // Saved GPR3                   x20-x27
+	u64     xSavedGpr4;             // Saved GPR4                   x28-x2F
+	u64     xSavedGpr5;             // Saved GPR5                   x30-x37
+
+	u8	xRsvd2_1;		// Reserved			x38-x38
+	u8      xCpuCtlsTaskAttributes; // Task attributes for cpuctls  x39-x39
+	u8      xFPRegsInUse;           // FP regs in use               x3A-x3A
+	u8      xPMCRegsInUse;          // PMC regs in use              x3B-x3B
+	volatile u32  xSavedDecr;	// Saved Decr Value             x3C-x3F
+	volatile u64  xEmulatedTimeBase;// Emulated TB for this thread  x40-x47
+	volatile u64  xCurPLICLatency;	// Unaccounted PLIC latency     x48-x4F
+	u64     xTotPLICLatency;        // Accumulated PLIC latency     x50-x57   
+	u64     xWaitStateCycles;       // Wait cycles for this proc    x58-x5F
+	u64     xEndOfQuantum;          // TB at end of quantum         x60-x67
+	u64     xPDCSavedSPRG1;         // Saved SPRG1 for PMC int      x68-x6F
+	u64     xPDCSavedSRR0;          // Saved SRR0 for PMC int       x70-x77
+	volatile u32 xVirtualDecr;	// Virtual DECR for shared procsx78-x7B
+	u32	    xRsvd2_2;		// Reserved			x7C-x7F
+
+//=============================================================================
+// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors
+//=============================================================================
+	// This is the xYieldCount.  An "odd" value (low bit on) means that 
+	// the processor is yielded (either because of an OS yield or a PLIC 
+	// preempt).  An even value implies that the processor is currently 
+	// executing.
+	// NOTE: This value will ALWAYS be zero for dedicated processors and 
+	// will NEVER be zero for shared processors (ie, initialized to a 1).
+	volatile u32 xYieldCount;	// PLIC increments each dispatchx00-x03
+	u8	xRsvd3_0[124];		// Reserved                     x04-x7F         
+
+//=============================================================================
+// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data
+//=============================================================================
+	u8      xPmcSaveArea[256];	// PMC interrupt Area           x00-xFF
+
+
+};
+#endif // _ITLPPACA_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/ItLpQueue.h linux/include/asm-ppc64/iSeries/ItLpQueue.h
--- linux.orig/include/asm-ppc64/iSeries/ItLpQueue.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/ItLpQueue.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,99 @@
+/*
+ * ItLpQueue.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//=============================================================================
+//
+//	This control block defines the simple LP queue structure that is 
+//	shared between the hypervisor (PLIC) and the OS in order to send 
+//	events to an LP.  
+//    
+
+#ifndef _PPC_TYPES_H
+#include <asm/types.h>
+#endif
+#include <asm/ptrace.h>
+
+
+struct HvLpEvent;
+
+
+#ifndef _ITLPQUEUE_H
+#define _ITLPQUEUE_H
+
+#define ITMaxLpQueues 8
+
+#define NotUsed		0	// Queue will not be used by PLIC
+#define DedicatedIo	1	// Queue dedicated to IO processor specified
+#define DedicatedLp	2	// Queue dedicated to LP specified
+#define Shared		3	// Queue shared for both IO and LP
+
+#define LpEventStackSize 4096
+#define LpEventMaxSize   256
+#define LpEventAlign	 64
+
+struct ItLpQueue
+{
+//
+//  The xSlicCurEventPtr is the pointer to the next event stack entry that will
+//  become valid.  The OS must peek at this entry to determine if it is valid.
+//  PLIC will set the valid indicator as the very last store into that entry.
+//
+//  When the OS has completed processing of the event then it will mark the event
+//  as invalid so that PLIC knows it can store into that event location again.
+//
+// If the event stack fills and there are overflow events, then PLIC will set 
+// the xPlicOverflowIntPending flag in which case the OS will have to fetch the 
+// additional LP events once they have drained the event stack.
+//
+// The first 16-bytes are known by both the OS and PLIC.  The remainder of the
+// cache line is for use by the OS.
+//
+//=============================================================================
+	u8	xPlicOverflowIntPending;// 0x00 Overflow events are pending
+	u8	xPlicStatus;		// 0x01 DedicatedIo or DedicatedLp or NotUsed
+	u16	xSlicLogicalProcIndex;	// 0x02 Logical Proc Index for correlation
+	u8	xPlicRsvd[12];		// 0x04
+	char*	xSlicCurEventPtr;	// 0x10
+	char*	xSlicLastValidEventPtr;	// 0x18
+	char*	xSlicEventStackPtr;	// 0x20
+	u8	xIndex;			// 0x28 unique sequential index.
+	u8	xSlicRsvd[3];		// 0x29-2b
+	u32	xInUseWord;		// 0x2C
+	u64	xLpIntCount;		// 0x30 Total Lp Int msgs processed
+	u64	xLpIntCountByType[9];	// 0x38-0x7F Event counts by type
+};
+
+extern struct ItLpQueue xItLpQueue;
+
+extern struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * );
+extern int ItLpQueue_isLpIntPending( struct ItLpQueue * ); 
+extern unsigned ItLpQueue_process( struct ItLpQueue *, struct pt_regs * );
+extern void ItLpQueue_clearValid( struct HvLpEvent * );
+
+static __inline__ void process_iSeries_events( void )
+{
+	__asm__ __volatile__ (
+	"	li	0,0x5555	\n\
+		sc"
+	: : : "r0", "r3" );	
+}
+
+
+//=============================================================================
+#endif // _ITLPQUEUE_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/ItLpRegSave.h linux/include/asm-ppc64/iSeries/ItLpRegSave.h
--- linux.orig/include/asm-ppc64/iSeries/ItLpRegSave.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/ItLpRegSave.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,87 @@
+/*
+ * ItLpRegSave.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//=====================================================================================
+//
+//	This control block contains the data that is shared between PLIC
+//	and the OS
+//    
+//
+
+#ifndef _ITLPREGSAVE_H
+#define _ITLPREGSAVE_H
+
+struct ItLpRegSave
+{
+	u32	xDesc;		// Eye catcher  "LpRS" ebcdic	000-003
+	u16	xSize;		// Size of this class		004-005
+	u8	xInUse;         // Area is live                 006-007
+	u8	xRsvd1[9]; 	// Reserved			007-00F
+
+	u8      xFixedRegSave[352]; // Fixed Register Save Area 010-16F 
+	u32	xCTRL;		// Control Register		170-173
+	u32	xDEC;		// Decrementer			174-177    
+	u32	xFPSCR;		// FP Status and Control Reg	178-17B
+	u32	xPVR;		// Processor Version Number	17C-17F
+    
+	u64	xMMCR0;		// Monitor Mode Control Reg 0	180-187
+	u32	xPMC1;		// Perf Monitor Counter 1	188-18B
+	u32	xPMC2;		// Perf Monitor Counter 2	18C-18F
+	u32	xPMC3;		// Perf Monitor Counter 3	190-193
+	u32	xPMC4;		// Perf Monitor Counter 4	194-197
+	u32	xPIR;		// Processor ID Reg		198-19B
+    
+	u32	xMMCR1;		// Monitor Mode Control Reg 1	19C-19F
+	u32	xMMCRA;		// Monitor Mode Control Reg A	1A0-1A3
+	u32	xPMC5;		// Perf Monitor Counter 5	1A4-1A7
+	u32	xPMC6;		// Perf Monitor Counter 6	1A8-1AB
+	u32	xPMC7;		// Perf Monitor Counter 7	1AC-1AF
+	u32	xPMC8;		// Perf Monitor Counter 8	1B0-1B3
+	u32	xTSC;		// Thread Switch Control	1B4-1B7
+	u32	xTST;		// Thread Switch Timeout	1B8-1BB
+	u32	xRsvd;          // Reserved                     1BC-1BF
+
+	u64	xACCR;		// Address Compare Control Reg	1C0-1C7
+	u64	xIMR;		// Instruction Match Register	1C8-1CF    
+	u64	xSDR1;		// Storage Description Reg 1	1D0-1D7    
+	u64	xSPRG0;		// Special Purpose Reg General0	1D8-1DF
+	u64	xSPRG1;		// Special Purpose Reg General1	1E0-1E7
+	u64	xSPRG2;		// Special Purpose Reg General2	1E8-1EF
+	u64	xSPRG3;		// Special Purpose Reg General3	1F0-1F7
+	u64	xTB;		// Time Base Register		1F8-1FF
+   
+	u64	xFPR[32];	// Floating Point Registers	200-2FF
+
+	u64	xMSR;		// Machine State Register  	300-307
+	u64	xNIA;		// Next Instruction Address	308-30F
+
+	u64	xDABR;		// Data Address Breakpoint Reg	310-317
+	u64	xIABR;		// Inst Address Breakpoint Reg	318-31F
+
+	u64	xHID0;		// HW Implementation Dependent0	320-327
+
+	u64	xHID4;		// HW Implementation Dependent4	328-32F
+	u64	xSCOMd;		// SCON Data Reg (SPRG4)       	330-337
+	u64	xSCOMc;		// SCON Command Reg (SPRG5)    	338-33F
+	u64	xSDAR;		// Sample Data Address Register	340-347
+	u64	xSIAR;		// Sample Inst Address Register	348-34F
+
+	u8	xRsvd3[176];	// Reserved			350-3FF
+};
+#endif // _ITLPREGSAVE_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/ItSpCommArea.h linux/include/asm-ppc64/iSeries/ItSpCommArea.h
--- linux.orig/include/asm-ppc64/iSeries/ItSpCommArea.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/ItSpCommArea.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,39 @@
+/*
+ * ItSpCommArea.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+
+#ifndef _ITSPCOMMAREA_H
+#define _ITSPCOMMAREA_H
+
+
+struct SpCommArea
+{
+	u32	xDesc;			// Descriptor (only in new formats)	000-003
+	u8	xFormat;		// Format (only in new formats)		004-004
+	u8	xRsvd1[11];		// Reserved				005-00F
+	u64	xRawTbAtIplStart;	// Raw HW TB value when IPL is started	010-017
+	u64	xRawTodAtIplStart;	// Raw HW TOD value when IPL is started	018-01F
+	u64	xBcdTimeAtIplStart;	// BCD time when IPL is started		020-027
+	u64	xBcdTimeAtOsStart;	// BCD time when OS passed control	028-02F
+	u8	xRsvd2[80];		// Reserved				030-07F
+};
+
+extern struct SpCommArea xSpCommArea;
+
+#endif /* _ITSPCOMMAREA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/ItVpdAreas.h linux/include/asm-ppc64/iSeries/ItVpdAreas.h
--- linux.orig/include/asm-ppc64/iSeries/ItVpdAreas.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/ItVpdAreas.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,100 @@
+/*
+ * ItVpdAreas.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+//=====================================================================================
+//
+//      This file defines the address and length of all of the VPD area passed to
+//	the OS from PLIC (most of which start from the SP).
+//
+
+#ifndef _PPC_TYPES_H
+#include        <asm/types.h>
+#endif
+
+
+#ifndef _ITVPDAREAS_H
+#define _ITVPDAREAS_H
+
+// VPD Entry index is carved in stone - cannot be changed (easily).
+#define ItVpdCecVpd				   0
+#define ItVpdDynamicSpace			   1
+#define ItVpdExtVpd				   2
+#define ItVpdExtVpdOnPanel			   3
+#define ItVpdFirstPaca				   4
+#define ItVpdIoVpd				   5
+#define ItVpdIplParms				   6
+#define ItVpdMsVpd				   7
+#define ItVpdPanelVpd				   8
+#define ItVpdLpNaca				   9
+#define ItVpdBackplaneAndMaybeClockCardVpd        10 
+#define ItVpdRecoveryLogBuffer		          11
+#define ItVpdSpCommArea				  12
+#define ItVpdSpLogBuffer			  13
+#define ItVpdSpLogBufferSave			  14
+#define ItVpdSpCardVpd				  15
+#define ItVpdFirstProcVpd			  16	
+#define ItVpdApModelVpd				  17
+#define ItVpdClockCardVpd			  18
+#define ItVpdBusExtCardVpd			  19
+#define ItVpdProcCapacityVpd			  20
+#define ItVpdInteractiveCapacityVpd		  21
+#define ItVpdFirstSlotLabel			  22
+#define ItVpdFirstLpQueue			  23
+#define ItVpdFirstL3CacheVpd			  24	
+#define ItVpdFirstProcFruVpd			  25
+
+#define ItVpdMaxEntries				  26
+
+
+#define ItDmaMaxEntries				  10
+
+#define ItVpdAreasMaxSlotLabels		 192 
+
+
+struct SlicVpdAdrs {
+	u32	pad1;
+	void *  vpdAddr;
+};
+
+
+struct	ItVpdAreas
+{
+	u32	xSlicDesc;		// Descriptor				000-003
+	u16	xSlicSize;		// Size of this control block		004-005
+	u16	xPlicAdjustVpdLens:1;	// Flag to indicate new interface 	006-007
+	u16	xRsvd1:15;		// Reserved bits			...
+	u16	xSlicVpdEntries;	// Number of VPD entries		008-009
+	u16	xSlicDmaEntries;	// Number of DMA entries		00A-00B
+	u16	xSlicMaxLogicalProcs;	// Maximum logical processors		00C-00D
+	u16	xSlicMaxPhysicalProcs;	// Maximum physical processors		00E-00F
+	u16	xSlicDmaToksOffset;	// Offset into this of array		010-011
+	u16	xSlicVpdAdrsOffset;	// Offset into this of array		012-013
+	u16	xSlicDmaLensOffset;	// Offset into this of array		014-015
+	u16	xSlicVpdLensOffset;	// Offset into this of array		016-017
+	u16	xSlicMaxSlotLabels;	// Maximum number of slot labels	018-019
+	u16	xSlicMaxLpQueues;	// Maximum number of LP Queues		01A-01B
+	u8	xRsvd2[4];		// Reserved				01C-01F
+	u64	xRsvd3[12];		// Reserved				020-07F
+	u32	xPlicDmaLens[ItDmaMaxEntries];// Array of DMA lengths		080-0A7
+	u32	xPlicDmaToks[ItDmaMaxEntries];// Array of DMA tokens		0A8-0CF
+	u32	xSlicVpdLens[ItVpdMaxEntries];// Array of VPD lengths		0D0-12F
+	void * xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers	130-1EF
+};
+
+#endif // _ITVPDAREAS_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/LparData.h linux/include/asm-ppc64/iSeries/LparData.h
--- linux.orig/include/asm-ppc64/iSeries/LparData.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/LparData.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,55 @@
+/*
+ * LparData.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+#ifndef	_PPC_TYPES_H
+#include	<asm/types.h>
+#endif
+
+#ifndef _LPARDATA_H
+#define _LPARDATA_H
+
+#include <asm/types.h>
+#include <asm/page.h>
+#include <asm/abs_addr.h>
+
+#include <asm/naca.h>
+#include <asm/iSeries/ItLpNaca.h>
+#include <asm/iSeries/ItLpPaca.h>
+#include <asm/iSeries/ItLpRegSave.h>
+#include <asm/paca.h>
+#include <asm/iSeries/HvReleaseData.h>
+#include <asm/iSeries/LparMap.h>
+#include <asm/iSeries/ItVpdAreas.h>
+#include <asm/iSeries/ItIplParmsReal.h>
+#include <asm/iSeries/ItLpQueue.h>
+#include <asm/iSeries/IoHriProcessorVpd.h>
+#include <asm/page.h>
+
+extern struct LparMap	xLparMap;
+extern struct HvReleaseData hvReleaseData;
+extern struct ItLpNaca	itLpNaca;
+extern struct ItIplParmsReal xItIplParmsReal;
+extern struct IoHriProcessorVpd xIoHriProcessorVpd[];
+extern struct ItLpQueue xItLpQueue;
+extern struct ItVpdAreas itVpdAreas;
+extern u64    xMsVpd[];
+extern struct msChunks msChunks;
+
+
+#endif /* _LPARDATA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/LparMap.h linux/include/asm-ppc64/iSeries/LparMap.h
--- linux.orig/include/asm-ppc64/iSeries/LparMap.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/LparMap.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,70 @@
+/*
+ * LparMap.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+#ifndef	_PPC_TYPES_H
+#include	<asm/types.h>
+#endif
+
+#ifndef _LPARMAP_H
+#define _LPARMAP_H
+
+/* The iSeries hypervisor will set up mapping for one or more 
+ * ESID/VSID pairs (in SLB/segment registers) and will set up
+ * mappings of one or more ranges of pages to VAs.
+ * We will have the hypervisor set up the ESID->VSID mapping
+ * for the four kernel segments (C-F).  With shared processors,
+ * the hypervisor will clear all segment registers and reload
+ * these four whenever the processor is switched from one 
+ * partition to another.
+ */
+
+/* The Vsid and Esid identified below will be used by the hypervisor
+ * to set up a memory mapping for part of the load area before giving
+ * control to the Linux kernel.  The load area is 64 MB, but this must
+ * not attempt to map the whole load area.  The Hashed Page Table may
+ * need to be located within the load area (if the total partition size
+ * is 64 MB), but cannot be mapped.  Typically, this should specify
+ * to map half (32 MB) of the load area.
+ * 
+ * The hypervisor will set up page table entries for the number of 
+ * pages specified.
+ *
+ * In 32-bit mode, the hypervisor will load all four of the
+ * segment registers (identified by the low-order four bits of the 
+ * Esid field.  In 64-bit mode, the hypervisor will load one SLB
+ * entry to map the Esid to the Vsid.
+*/
+
+// Hypervisor initially maps 32MB of the load area 
+#define HvPagesToMap 8192
+
+struct LparMap
+{
+	u64	  xNumberEsids;		// Number of ESID/VSID pairs (1)
+	u64	  xNumberRanges;	// Number of VA ranges to map (1)
+	u64	  xSegmentTableOffs;	// Page number within load area of seg table (0)
+	u64	  xRsvd[5];		// Reserved (0)
+	u64	  xKernelEsid;  	// Esid used to map kernel load (0x0C00000000)	
+	u64	  xKernelVsid;		// Vsid used to map kernel load (0x0C00000000)
+	u64	  xPages;		// Number of pages to be mapped	(8192)
+	u64	  xOffset;		// Offset from start of load area (0)
+	u64	  xVPN;			// Virtual Page Number (0x000C000000000000)
+};
+
+#endif /* _LPARMAP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/XmPciLpEvent.h linux/include/asm-ppc64/iSeries/XmPciLpEvent.h
--- linux.orig/include/asm-ppc64/iSeries/XmPciLpEvent.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/XmPciLpEvent.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,18 @@
+
+#ifndef	__XMPCILPEVENT_H__
+#define	__XMPCILPEVENT_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int XmPciLpEvent_init(void);
+void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XMPCILPEVENT_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/iSeries_FlightRecorder.h linux/include/asm-ppc64/iSeries/iSeries_FlightRecorder.h
--- linux.orig/include/asm-ppc64/iSeries/iSeries_FlightRecorder.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/iSeries_FlightRecorder.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,85 @@
+#ifndef _ISERIES_FLIGHTRECORDER_H
+#define _ISERIES_FLIGHTRECORDER_H
+/************************************************************************/
+/* File iSeries_FlightRecorder.h created by Allan Trautman Jan 22 2001. */
+/************************************************************************/
+/* This code supports the pci interface on the IBM iSeries systems.     */
+/* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
+/*                                                                      */
+/* 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created, Jan 22, 2001                                              */
+/*   Added Time stamp methods. Apr 12, 2001                             */
+/* End Change Activity                                                  */
+/************************************************************************/
+/* This is a generic Flight Recorder, simply stuffs line entries into a */
+/* buffer for debug purposes.                                           */
+/*                                                                      */
+/* To use,                                                              */ 
+/* 1. Create one, make it global so it isn't on the stack.              */
+/*     FlightRecorder  PciFlightRecorder;                               */
+/*                                                                      */
+/* 2. Optionally create a pointer to it, just makes it easier to use.   */
+/*     FlightRecorder* PciFr = &PciFlightRecorder;                      */
+/*                                                                      */
+/* 3. Initialize with you signature.                                    */
+/*          iSeries_Fr_Initialize(PciFr, "Pci Flight Recorder");        */
+/*                                                                      */
+/* 4. Log entries.                                                      */ 
+/*          PciFr->logEntry(PciFr,"In Main");                           */
+/*                                                                      */
+/* 5. Later, you can find the Flight Recorder by looking in the         */
+/*    System.map                                                        */
+/************************************************************************/
+struct iSeries_FlightRecorder;          /* Forward declares             */
+struct rtc_time;
+void   logEntry(struct iSeries_FlightRecorder*, char* Text);
+void   logTime( struct iSeries_FlightRecorder*, char* Text);
+void   logDate( struct iSeries_FlightRecorder*, char* Text);
+#define FlightRecorderSize 4096 
+
+/************************************************************************/
+/* Generic Flight Recorder Structure                                    */
+/************************************************************************/
+struct iSeries_FlightRecorder {         /* Structure Defination         */
+	char  Signature[16];                /* Eye Catcher                  */
+	char* StartingPointer;              /* Buffer Starting Address      */
+	char* CurrentPointer;               /* Next Entry Address           */
+	int   WrapCount;                    /* Number of Buffer Wraps       */
+	void  (*logEntry)(struct iSeries_FlightRecorder*,char*);
+	void  (*logTime) (struct iSeries_FlightRecorder*,char*);
+	void  (*logDate) (struct iSeries_FlightRecorder*,char*);
+	char  Buffer[FlightRecorderSize];
+};
+
+typedef struct iSeries_FlightRecorder FlightRecorder;	/* Short Name   */
+extern void iSeries_Fr_Initialize(FlightRecorder*, char* Signature);
+/************************************************************************/
+/* extern void iSeries_LogFr_Entry(  FlightRecorder*, char* Text);      */
+/* extern void iSeries_LogFr_Date(   FlightRecorder*, char* Text);      */
+/* extern void iSeries_LogFr_Time(   FlightRecorder*, char* Text);      */
+/************************************************************************/
+/* PCI Flight Recorder Helpers                                          */
+/************************************************************************/
+extern FlightRecorder* PciFr;            /* Ptr to Pci Fr               */
+extern char*           PciFrBuffer;      /* Ptr to Fr Work Buffer       */
+#define ISERIES_PCI_FR(buffer)      PciFr->logEntry(PciFr,buffer);
+#define ISERIES_PCI_FR_TIME(buffer) PciFr->logTime(PciFr,buffer);
+#define ISERIES_PCI_FR_DATE(buffer) PciFr->logDate(PciFr,buffer);
+
+#endif /* _ISERIES_FLIGHTRECORDER_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/iSeries_VpdInfo.h linux/include/asm-ppc64/iSeries/iSeries_VpdInfo.h
--- linux.orig/include/asm-ppc64/iSeries/iSeries_VpdInfo.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/iSeries_VpdInfo.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,56 @@
+#ifndef _ISERIES_VPDINFO_H
+#define _ISERIES_VPDINFO_H
+/************************************************************************/
+/* File iSeries_VpdInfo.h created by Allan Trautman Feb 08 2001.        */
+/************************************************************************/
+/* This code supports the location data fon on the IBM iSeries systems. */
+/* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
+/*                                                                      */
+/* 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created, Feg  8, 2001                                              */
+/*   Reformated for Card, March 8, 2001                                 */
+/* End Change Activity                                                  */
+/************************************************************************/
+
+struct pci_dev; 		/* Forward Declare                      */
+/************************************************************************/
+/* Location Data extracted from the VPD list and device info.           */
+/************************************************************************/
+struct LocationDataStruct {	/* Location data structure for device   */
+	u16  Bus;		/* iSeries Bus Number		    0x00*/
+	u16  Board;		/* iSeries Board                    0x02*/
+	u8   FrameId;		/* iSeries spcn Frame Id            0x04*/
+	u8   PhbId;		/* iSeries Phb Location             0x05*/
+	u16  Card;		/* iSeries Card Slot                0x06*/
+	char CardLocation[4];	/* Char format of planar vpd        0x08*/
+	u8   AgentId;		/* iSeries AgentId                  0x0C*/
+	u8   SecondaryAgentId;	/* iSeries Secondary Agent Id       0x0D*/
+	u8   LinuxBus;		/* Linux Bus Number                 0x0E*/
+	u8   LinuxDevFn;	/* Linux Device Function            0x0F*/
+};
+typedef struct LocationDataStruct  LocationData;
+#define LOCATION_DATA_SIZE      16
+
+/************************************************************************/
+/* Protypes                                                             */
+/************************************************************************/
+extern LocationData* iSeries_GetLocationData(struct pci_dev* PciDev);
+extern int           iSeries_Device_Information(struct pci_dev*,char*, int);
+
+#endif /* _ISERIES_VPDINFO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/iSeries_dma.h linux/include/asm-ppc64/iSeries/iSeries_dma.h
--- linux.orig/include/asm-ppc64/iSeries/iSeries_dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/iSeries_dma.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,97 @@
+/*
+ * iSeries_dma.h
+ * Copyright (C) 2001  Mike Corrigan IBM 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
+ */
+
+#ifndef _ISERIES_DMA_H
+#define _ISERIES_DMA_H
+
+#include <asm/types.h>
+#ifndef __LINUX_SPINLOCK_H
+#include <linux/spinlock.h>
+#endif
+
+// NUM_TCE_LEVELS defines the largest contiguous block
+// of dma (tce) space we can get.  NUM_TCE_LEVELS = 10 
+// allows up to 2**9 pages (512 * 4096) = 2 MB
+#define NUM_TCE_LEVELS 10
+
+#define NO_TCE ((dma_addr_t)-1)
+
+// Tces come in two formats, one for the virtual bus and a different
+// format for PCI
+#define TCE_VB  0
+#define TCE_PCI 1
+
+
+union Tce {
+   	u64	wholeTce;
+	struct {
+		u64	cacheBits	:6;	/* Cache hash bits - not used */
+		u64	rsvd		:6;	
+		u64	rpn		:40;	/* Absolute page number */
+		u64	valid		:1;	/* Tce is valid (vb only) */
+		u64	allIo		:1;	/* Tce is valid for all lps (vb only) */
+		u64	lpIndex		:8;	/* LpIndex for user of TCE (vb only) */
+		u64	pciWrite	:1;	/* Write allowed (pci only) */
+		u64	readWrite	:1;	/* Read allowed (pci), Write allowed
+						   (vb) */
+	} tceBits;
+};
+
+struct Bitmap {
+	unsigned long	numBits;
+	unsigned long	numBytes;
+	unsigned char * map;
+};
+
+struct MultiLevelBitmap {
+	unsigned long 	maxLevel;
+	struct Bitmap 	level[NUM_TCE_LEVELS];
+};
+
+struct TceTable {
+	u64	busNumber;
+	u64	size;
+	u64	startOffset;
+	u64	index;
+	spinlock_t	lock;
+	struct MultiLevelBitmap mlbm;
+};
+
+struct HvTceTableManagerCB {
+	u64	busNumber;		/* Bus number for this tce table */
+	u64	start;			/* Will be NULL for secondary */
+	u64	totalSize;		/* Size (in pages) of whole table */
+	u64	startOffset;		/* Index into real tce table of the
+					   start of our section */
+	u64	size;			/* Size (in pages) of our section */
+	u64	index;			/* Index of this tce table (token?) */
+	u16	maxTceTableIndex;	/* Max number of tables for partition */
+	u8	virtualBusFlag;		/* Flag to indicate virtual bus */
+	u8	rsvd[5];
+};
+
+extern struct TceTable virtBusTceTable;	/* Tce table for virtual bus */
+
+extern struct TceTable * build_tce_table( struct HvTceTableManagerCB *,
+					  struct TceTable *);
+extern void              create_virtual_bus_tce_table( void );
+
+extern void		 create_pci_bus_tce_table( unsigned busNumber );
+
+#endif // _ISERIES_DMA_H
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/iSeries_fixup.h linux/include/asm-ppc64/iSeries/iSeries_fixup.h
--- linux.orig/include/asm-ppc64/iSeries/iSeries_fixup.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/iSeries_fixup.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,25 @@
+
+#ifndef	__ISERIES_FIXUP_H__
+#define	__ISERIES_FIXUP_H__
+#include <linux/pci.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void iSeries_fixup (void);
+void iSeries_fixup_bus (struct pci_bus*);
+unsigned int iSeries_scan_slot (struct pci_dev*, u16, u8, u8);
+
+
+/* Need to store information related to the PHB bucc and make it accessible to the hose */
+struct iSeries_hose_arch_data {
+	u32 hvBusNumber;
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ISERIES_FIXUP_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/iSeries_io.h linux/include/asm-ppc64/iSeries/iSeries_io.h
--- linux.orig/include/asm-ppc64/iSeries/iSeries_io.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/iSeries_io.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,46 @@
+#include <linux/config.h>
+
+#ifdef CONFIG_PPC_ISERIES
+#ifndef _ISERIES_IO_H
+#define _ISERIES_IO_H
+#include <linux/types.h>
+/************************************************************************/
+/* File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000.      */
+/************************************************************************/
+/* Remaps the io.h for the iSeries Io                                   */
+/* Copyright (C) 20yy  Allan H Trautman, IBM 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created December 28, 2000                                          */
+/* End Change Activity                                                  */
+/************************************************************************/
+extern u8   iSeries_Read_Byte(void* IoAddress);
+extern u16  iSeries_Read_Word(void* IoAddress);
+extern u32  iSeries_Read_Long(void* IoAddress);
+extern void iSeries_Write_Byte(u8  IoData,void* IoAddress);
+extern void iSeries_Write_Word(u16 IoData,void* IoAddress);
+extern void iSeries_Write_Long(u32 IoData,void* IoAddress);
+
+extern void* iSeries_memset_io(void *dest, char x, size_t n);
+extern void* iSeries_memcpy_toio(void *dest, void *source, size_t n);
+extern void* iSeries_memcpy_fromio(void *dest, void *source, size_t n);
+
+#endif /*  _ISERIES_IO_H         */
+#endif /*  CONFIG_PPC_ISERIES  */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/iSeries_irq.h linux/include/asm-ppc64/iSeries/iSeries_irq.h
--- linux.orig/include/asm-ppc64/iSeries/iSeries_irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/iSeries_irq.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,27 @@
+
+#ifndef	__ISERIES_IRQ_H__
+#define	__ISERIES_IRQ_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned int iSeries_startup_IRQ(unsigned int);
+void iSeries_shutdown_IRQ(unsigned int);
+void iSeries_enable_IRQ(unsigned int);
+void iSeries_disable_IRQ(unsigned int);
+void iSeries_end_IRQ(unsigned int);
+void iSeries_init_IRQ(void);
+void iSeries_init_irqMap(int);
+int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
+int  iSeries_assign_IRQ(int, HvBusNumber, HvSubBusNumber, HvAgentId);
+void iSeries_activate_IRQs(void);
+
+int XmPciLpEvent_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ISERIES_IRQ_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/iSeries_pci.h linux/include/asm-ppc64/iSeries/iSeries_pci.h
--- linux.orig/include/asm-ppc64/iSeries/iSeries_pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/iSeries_pci.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,127 @@
+#ifndef _ISERIES_64_PCI_H
+#define _ISERIES_64_PCI_H
+/************************************************************************/
+/* File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001.    */
+/************************************************************************/
+/* Define some useful macros for the iSeries pci routines.              */
+/* Copyright (C) 20yy  Allan H Trautman, IBM 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                                          */
+/************************************************************************/
+/* Change Activity:                                                     */
+/*   Created Feb 20, 2001                                               */
+/*   Added device reset, March 22, 2001                                 */
+/*   Ported to ppc64, May 25, 2001                                      */
+/* End Change Activity                                                  */
+/************************************************************************/
+#include <asm/iSeries/HvCallPci.h>
+
+struct pci_dev;				/* For Forward Reference        */
+struct iSeries_Device_Node;
+/************************************************************************/
+/* Gets iSeries Bus, SubBus, of DevFn using pci_dev* structure          */
+/************************************************************************/
+#define ISERIES_BUS(DevPtr)    DevPtr->DsaAddr.busNumber
+#define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.subBusNumber
+#define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.deviceId
+#define ISERIES_DEVFUN(DevPtr) DevPtr->DevFn
+#define ISERIES_DSA(DevPtr)   (*(u64*)&DevPtr->DsaAddr)
+#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node*)PciDev->sysdata)
+
+#define EADsMaxAgents 7
+/************************************************************************************/
+/* Decodes Linux DevFn to iSeries DevFn, bridge device, or function.                */
+/* For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h                      */
+/************************************************************************************/
+#define ISERIES_DECODE_DEVFN(linuxdevfn)  (((linuxdevfn & 0x71) << 1) | (linuxdevfn & 0x07))
+#define ISERIES_DECODE_DEVICE(linuxdevfn) (((linuxdevfn & 0x38) >> 3) |(((linuxdevfn & 0x40) >> 2) + 0x10))
+#define ISERIES_DECODE_FUNCTION(linuxdevfn) (linuxdevfn & 0x07)
+#define ISERIES_PCI_AGENTID(idsel,func)	((idsel & 0x0F) << 4) | (func  & 0x07)
+
+#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus)   ((subbus >> 5) & 0x7)
+#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
+
+#define ISERIES_ENCODE_DEVICE(agentid)	((0x10) | ((agentid&0x20)>>2) | (agentid&07))
+/************************************************************************************/
+/* Converts Virtual Address to Real Address for Hypervisor calls                    */
+/************************************************************************************/
+#define REALADDR(virtaddr)  (0x8000000000000000 | (virt_to_absolute((u64)virtaddr) ))
+
+/************************************************************************************/
+/* Define TRUE and FALSE Values for Al                                              */
+/************************************************************************************/
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/************************************************************************/
+/* iSeries Device Information                                           */
+/************************************************************************/
+struct iSeries_Device_Node {
+	struct list_head Device_List;    /* Must be first for cast to wo*/
+	struct pci_dev*  PciDev;         /* Pointer to pci_dev structure*/
+        struct HvCallPci_DsaAddr DsaAddr;/* Direct Select Address       */
+                                         /* busNumber,subBusNumber,     */ 
+	                                 /* deviceId, barNumber         */
+	HvAgentId        AgentId;	 /* Hypervisor DevFn            */
+	int              DevFn;          /* Linux devfn                 */
+	int              BarOffset;
+	int              Irq;            /* Assigned IRQ                */
+	int              ReturnCode;	 /* Return Code Holder          */
+	int              IoRetry;        /* Current Retry Count         */
+	int              Flags;          /* Possible flags(disable/bist)*/
+	u16              Vendor;         /* Vendor ID                   */
+	u8               LogicalSlot;    /* Hv Slot Index for Tces      */
+	struct TceTable* DevTceTable;    /* Device TCE Table            */ 
+	u8               PhbId;          /* Phb Card is on.             */
+	u16              Board;          /* Board Number                */
+	u8               FrameId;	 /* iSeries spcn Frame Id       */
+	char             CardLocation[4];/* Char format of planar vpd   */
+	char             Location[20];   /* Frame  1, Card C10          */
+};
+/************************************************************************/
+/* Location Data extracted from the VPD list and device info.           */
+/************************************************************************/
+struct LocationDataStruct { 	/* Location data structure for device  */
+	u16  Bus;               /* iSeries Bus Number              0x00*/
+	u16  Board;             /* iSeries Board                   0x02*/
+	u8   FrameId;           /* iSeries spcn Frame Id           0x04*/
+	u8   PhbId;             /* iSeries Phb Location            0x05*/
+	u8   AgentId;           /* iSeries AgentId                 0x06*/
+	u8   Card;
+	char CardLocation[4];      
+};
+typedef struct LocationDataStruct  LocationData;
+#define LOCATION_DATA_SIZE      48
+/************************************************************************/
+/* Flight Recorder tracing                                              */
+/************************************************************************/
+extern int  iSeries_Set_PciTraceFlag(int TraceFlag);
+extern int  iSeries_Get_PciTraceFlag(void);
+
+/************************************************************************/
+/* Functions                                                            */
+/************************************************************************/
+extern LocationData* iSeries_GetLocationData(struct pci_dev* PciDev);
+extern int           iSeries_Device_Information(struct pci_dev*,char*, int);
+extern void          iSeries_Get_Location_Code(struct iSeries_Device_Node*);
+extern int           iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime);
+
+#endif /* _ISERIES_64_PCI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/iSeries_proc.h linux/include/asm-ppc64/iSeries/iSeries_proc.h
--- linux.orig/include/asm-ppc64/iSeries/iSeries_proc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/iSeries_proc.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * iSeries_proc.h
+ * Copyright (C) 2001  Kyle A. Lucke IBM 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
+ */
+
+
+/* Change Activity: */
+/* End Change Activity */
+
+#ifndef _ISERIES_PROC_H
+#define _ISERIES_PROC_H
+
+#include <linux/proc_fs.h>
+
+extern void iSeries_proc_early_init(void);
+extern void iSeries_proc_create(void);
+
+typedef void (*iSeriesProcFunction)(struct proc_dir_entry *iSeries_proc);
+
+extern void iSeries_proc_callback(iSeriesProcFunction initFunction);
+
+#endif /* _iSeries_PROC_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/mf.h linux/include/asm-ppc64/iSeries/mf.h
--- linux.orig/include/asm-ppc64/iSeries/mf.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/mf.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,83 @@
+/*
+ * mf.h
+ * Copyright (C) 2001  Troy D. Armstrong IBM Corporation
+ *
+ * This modules exists as an interface between a Linux secondary partition
+ * running on an iSeries and the primary partition's Virtual Service
+ * Processor (VSP) object.  The VSP has final authority over powering on/off
+ * all partitions in the iSeries.  It also provides miscellaneous low-level
+ * machine facility type operations.
+ *
+ * 
+ * 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
+ */
+
+#ifndef MF_H_INCLUDED
+#define MF_H_INCLUDED
+
+#include <asm/iSeries/HvTypes.h>
+#include <asm/iSeries/HvLpEvent.h>
+
+struct rtc_time;
+
+typedef void (*MFCompleteHandler)( void * clientToken, int returnCode );
+
+extern void mf_allocateLpEvents( HvLpIndex targetLp,
+				 HvLpEvent_Type type,
+				 unsigned size,
+				 unsigned amount,
+				 MFCompleteHandler hdlr,
+				 void * userToken );
+
+extern void mf_deallocateLpEvents( HvLpIndex targetLp,
+				   HvLpEvent_Type type,
+				   unsigned count,
+				   MFCompleteHandler hdlr,
+				   void * userToken );
+
+extern void mf_powerOff( void );
+
+extern void mf_reboot( void );
+
+extern void mf_displaySrc( u32 word );
+extern void mf_displayProgress( u16 value );
+
+extern void mf_clearSrc( void );
+
+extern void mf_init( void );
+
+extern void mf_setSide(char side);
+
+extern char mf_getSide(void);
+
+extern void mf_setCmdLine(const char *cmdline, int size, u64 side);
+
+extern int  mf_getCmdLine(char *cmdline, int *size, u64 side);
+
+extern void mf_getSrcHistory(char *buffer, int size);
+
+extern int mf_setVmlinuxChunk(const char *buffer, int size, int offset, u64 side);
+
+extern int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side);
+
+extern int mf_setRtcTime(unsigned long time);
+
+extern int mf_getRtcTime(unsigned long *time);
+
+extern int mf_getRtc( struct rtc_time * tm );
+
+extern int mf_setRtc( struct rtc_time * tm );
+
+#endif /* MF_H_INCLUDED */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/mf_proc.h linux/include/asm-ppc64/iSeries/mf_proc.h
--- linux.orig/include/asm-ppc64/iSeries/mf_proc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/mf_proc.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,33 @@
+/*
+ * mf_proc.h
+ * Copyright (C) 2001  Kyle A. Lucke IBM 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
+ */
+
+
+/* Change Activity: */
+/* End Change Activity */
+
+#ifndef _MF_PROC_H
+#define _MF_PROC_H
+
+#include <linux/proc_fs.h>
+
+void mf_proc_init(struct proc_dir_entry *iSeries_proc);
+
+
+#endif /* _MF_PROC_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/iSeries/veth-proc.h linux/include/asm-ppc64/iSeries/veth-proc.h
--- linux.orig/include/asm-ppc64/iSeries/veth-proc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/iSeries/veth-proc.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ * veth-proc.h
+ * Copyright (C) 2001  Kyle A. Lucke IBM 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
+ */
+
+
+/* Change Activity: */
+/* End Change Activity */
+
+#ifndef _VETH_PROC_H
+#define _VETH_PROC_H
+
+#include <linux/proc_fs.h>
+
+void veth_proc_init(struct proc_dir_entry *iSeries_proc);
+
+#endif /* _VETH-PROC_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ide.h linux/include/asm-ppc64/ide.h
--- linux.orig/include/asm-ppc64/ide.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ide.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,82 @@
+/*
+ *  linux/include/asm-ppc/ide.h
+ *
+ *  Copyright (C) 1994-1996 Linus Torvalds & authors
+ *
+ * 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 file contains the ppc64 architecture specific IDE code.
+ */
+
+#ifndef __ASMPPC64_IDE_H
+#define __ASMPPC64_IDE_H
+
+#ifdef __KERNEL__
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS	4
+#endif
+
+#define ide__sti()	__sti()
+
+void ppc64_ide_fix_driveid(struct hd_driveid *id);
+#define ide_fix_driveid(id)	ppc64_ide_fix_driveid((id))
+
+static __inline__ int ide_default_irq(ide_ioreg_t base) { return 0; }
+static __inline__ ide_ioreg_t ide_default_io_base(int index) { return 0; }
+
+static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
+	}
+	if (irq != NULL)
+		*irq = 0;
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
+}
+
+static __inline__ void ide_init_default_hwifs(void)
+{
+}
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned head		: 4;	/* always zeros here */
+		unsigned unit		: 1;	/* drive select number, 0 or 1 */
+		unsigned bit5		: 1;	/* always 1 */
+		unsigned lba		: 1;	/* using LBA instead of CHS */
+		unsigned bit7		: 1;	/* always 1 */
+	} b;
+	} select_t;
+
+#define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
+#define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
+#define ide_check_region(from,extent)		check_region((from), (extent))
+#define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
+#define ide_release_region(from,extent)		release_region((from), (extent))
+
+/*
+ * The following are not needed for the non-m68k ports
+ */
+#define ide_ack_intr(hwif)		(1)
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMPPC64_IDE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/init.h linux/include/asm-ppc64/init.h
--- linux.orig/include/asm-ppc64/init.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/init.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,29 @@
+#ifndef _PPC64_INIT_H
+#define _PPC64_INIT_H
+
+#include <linux/init.h>
+
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 90 /* egcs */
+/* DRENG add back in when we get section attribute support */
+#define __chrp __attribute__ ((__section__ (".text.chrp")))
+#define __chrpdata __attribute__ ((__section__ (".data.chrp")))
+#define __chrpfunc(__argchrp) \
+	__argchrp __chrp; \
+	__argchrp
+
+/* this is actually just common chrp/pmac code, not OF code -- Cort */
+#define __openfirmware __attribute__ ((__section__ (".text.openfirmware")))
+#define __openfirmwaredata __attribute__ ((__section__ (".data.openfirmware")))
+#define __openfirmwarefunc(__argopenfirmware) \
+	__argopenfirmware __openfirmware; \
+	__argopenfirmware
+	
+#else /* not egcs */
+
+#define __openfirmware
+#define __openfirmwaredata
+#define __openfirmwarefunc(x) x
+
+#endif /* egcs */
+
+#endif /* _PPC64_INIT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/io.h linux/include/asm-ppc64/io.h
--- linux.orig/include/asm-ppc64/io.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/io.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,318 @@
+#ifndef _PPC64_IO_H
+#define _PPC64_IO_H
+
+/* 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <asm/byteorder.h>
+#ifdef CONFIG_PPC_ISERIES 
+#include <asm/iSeries/iSeries_io.h>
+#endif  
+#include <asm/memory.h>
+#include <asm/delay.h>
+
+#define SIO_CONFIG_RA	0x398
+#define SIO_CONFIG_RD	0x399
+
+#define SLOW_DOWN_IO
+/* Define this if you want to see virt_to_* messages */
+#undef __IO_DEBUG
+
+extern unsigned long isa_io_base;
+extern unsigned long isa_mem_base;
+extern unsigned long pci_io_base;
+extern unsigned long pci_dram_offset;
+extern int have_print;
+#define _IO_BASE	isa_io_base
+#define _ISA_MEM_BASE	isa_mem_base
+#define PCI_DRAM_OFFSET	pci_dram_offset
+
+#ifdef CONFIG_PPC_ISERIES
+#define readb(addr)		iSeries_Read_Byte((void*)(addr))  
+#define readw(addr)		iSeries_Read_Word((void*)(addr))  
+#define readl(addr)		iSeries_Read_Long((void*)(addr))
+#define writeb(data, addr)	iSeries_Write_Byte(data,((void*)(addr)))
+#define writew(data, addr)	iSeries_Write_Word(data,((void*)(addr)))
+#define writel(data, addr)	iSeries_Write_Long(data,((void*)(addr)))
+#define memset_io(a,b,c)	iSeries_memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	iSeries_memcpy_fromio((void *)(a), (void *)(b), (c))
+#define memcpy_toio(a,b,c)	iSeries_memcpy_toio((void *)(a), (void *)(b), (c))
+#define inb(addr)		readb(((unsigned long)(addr)))  
+#define inw(addr)		readw(((unsigned long)(addr)))  
+#define inl(addr)		readl(((unsigned long)(addr)))
+#define outb(data,addr)		writeb(data,((unsigned long)(addr)))  
+#define outw(data,addr)		writew(data,((unsigned long)(addr)))  
+#define outl(data,addr)		writel(data,((unsigned long)(addr)))
+#else
+#define IS_MAPPED_VADDR(port)	((unsigned long)(port) >> 60UL)
+#define readb(addr)		eeh_readb((void*)(addr))  
+#define readw(addr)		eeh_readw((void*)(addr))  
+#define readl(addr)		eeh_readl((void*)(addr))
+#define writeb(data, addr)	eeh_writeb((data), ((void*)(addr)))
+#define writew(data, addr)	eeh_writew((data), ((void*)(addr)))
+#define writel(data, addr)	eeh_writel((data), ((void*)(addr)))
+#define memset_io(a,b,c)	eeh_memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	eeh_memcpy_fromio((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	eeh_memcpy_toio((void *)(a),(b),(c))
+#define inb(port)		_inb((unsigned long)port)
+#define outb(val, port)		_outb(val, (unsigned long)port)
+#define inw(port)		_inw((unsigned long)port)
+#define outw(val, port)		_outw(val, (unsigned long)port)
+#define inl(port)		_inl((unsigned long)port)
+#define outl(val, port)		_outl(val, (unsigned long)port)
+#endif
+
+
+/*
+ * output pause versions need a delay at least for the
+ * w83c105 ide controller in a p610.
+ */
+#define inb_p(port)             inb(port)
+#define outb_p(val, port)       (udelay(1), outb((val), (port)))
+#define inw_p(port)             inw(port)
+#define outw_p(val, port)       (udelay(1), outw((val), (port)))
+#define inl_p(port)             inl(port)
+#define outl_p(val, port)       (udelay(1), outl((val, (port)))
+
+/*
+ * The insw/outsw/insl/outsl macros don't do byte-swapping.
+ * They are only used in practice for transferring buffers which
+ * are arrays of bytes, and byte-swapping is not appropriate in
+ * that case.  - paulus */
+#define _IOMAP_VADDR(port) (IS_MAPPED_VADDR(port) ? (port) : (port)+_IO_BASE)
+#define insb(port, buf, ns)	_insb((u8 *)(_IOMAP_VADDR(port)), (buf), (ns))
+#define outsb(port, buf, ns)	_outsb((u8 *)(_IOMAP_VADDR(port)), (buf), (ns))
+#define insw(port, buf, ns)	_insw_ns((u16 *)(_IOMAP_VADDR(port)), (buf), (ns))
+#define outsw(port, buf, ns)	_outsw_ns((u16 *)(_IOMAP_VADDR(port)), (buf), (ns))
+#define insl(port, buf, nl)	_insl_ns((u32 *)(_IOMAP_VADDR(port)), (buf), (nl))
+#define outsl(port, buf, nl)	_outsl_ns((u32 *)(_IOMAP_VADDR(port)), (buf), (nl))
+
+extern void _insb(volatile u8 *port, void *buf, int ns);
+extern void _outsb(volatile u8 *port, const void *buf, int ns);
+extern void _insw(volatile u16 *port, void *buf, int ns);
+extern void _outsw(volatile u16 *port, const void *buf, int ns);
+extern void _insl(volatile u32 *port, void *buf, int nl);
+extern void _outsl(volatile u32 *port, const void *buf, int nl);
+extern void _insw_ns(volatile u16 *port, void *buf, int ns);
+extern void _outsw_ns(volatile u16 *port, const void *buf, int ns);
+extern void _insl_ns(volatile u32 *port, void *buf, int nl);
+extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
+
+/*
+ * The *_ns versions below don't do byte-swapping.
+ * Neither do the standard versions now, these are just here
+ * for older code.
+ */
+#define insw_ns(port, buf, ns)	_insw_ns((u16 *)(_IOMAP_VADDR(port)), (buf), (ns))
+#define outsw_ns(port, buf, ns)	_outsw_ns((u16 *)(_IOMAP_VADDR(port)), (buf), (ns))
+#define insl_ns(port, buf, nl)	_insl_ns((u32 *)(_IOMAP_VADDR(port)), (buf), (nl))
+#define outsl_ns(port, buf, nl)	_outsl_ns((u32 *)(_IOMAP_VADDR(port)), (buf), (nl))
+
+
+#define IO_SPACE_LIMIT ~(0UL)
+#define MEM_SPACE_LIMIT ~(0UL)
+
+
+#ifdef __KERNEL__
+/*
+ * Map in an area of physical address space, for accessing
+ * I/O devices etc.
+ */
+extern void *__ioremap(unsigned long address, unsigned long size,
+		       unsigned long flags);
+extern void *ioremap(unsigned long address, unsigned long size);
+#define ioremap_nocache(addr, size)	ioremap((addr), (size))
+extern void iounmap(void *addr);
+
+/*
+ * Change virtual addresses to physical addresses and vv, for
+ * addresses in the area where the kernel has the RAM mapped.
+ */
+extern inline unsigned long virt_to_phys(volatile void * address)
+{
+#ifdef __IO_DEBUG
+	printk("virt_to_phys: 0x%08lx -> 0x%08lx\n", 
+			(unsigned long) address,
+			__pa((unsigned long)address));
+#endif
+	return __pa((unsigned long)address);
+}
+
+extern inline void * phys_to_virt(unsigned long address)
+{
+#ifdef __IO_DEBUG
+	printk("phys_to_virt: 0x%08lx -> 0x%08lx\n", address, __va(address));
+#endif
+	return (void *) __va(address);
+}
+
+#endif /* __KERNEL__ */
+
+extern inline void iosync(void)
+{
+        __asm__ __volatile__ ("sync" : : : "memory");
+}
+
+/* Enforce in-order execution of data I/O. 
+ * No distinction between read/write on PPC; use eieio for all three.
+ */
+#define iobarrier_rw() eieio()
+#define iobarrier_r()  eieio()
+#define iobarrier_w()  eieio()
+
+/*
+ * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
+ * Until we can validate all required device drivers are weakc safe, an
+ * excess of syncs before the MMIO operations will make things work.  On 
+ * sstar, sync time is << than mmio time, so this should not be a big impact.
+ */
+extern inline int in_8(volatile unsigned char *addr)
+{
+	int ret;
+
+	__asm__ __volatile__("sync; lbz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr));
+	return ret;
+}
+
+extern inline void out_8(volatile unsigned char *addr, int val)
+{
+	__asm__ __volatile__("sync; stb%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
+}
+
+extern inline int in_le16(volatile unsigned short *addr)
+{
+	int ret;
+
+	__asm__ __volatile__("sync; lhbrx %0,0,%1; sync" : "=r" (ret) :
+			      "r" (addr), "m" (*addr));
+	return ret;
+}
+
+extern inline int in_be16(volatile unsigned short *addr)
+{
+	int ret;
+
+	__asm__ __volatile__("sync; lhz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr));
+	return ret;
+}
+
+extern inline void out_le16(volatile unsigned short *addr, int val)
+{
+	__asm__ __volatile__("sync; sthbrx %1,0,%2; sync" : "=m" (*addr) :
+			      "r" (val), "r" (addr));
+}
+
+extern inline void out_be16(volatile unsigned short *addr, int val)
+{
+	__asm__ __volatile__("sync; sth%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
+}
+
+extern inline unsigned in_le32(volatile unsigned *addr)
+{
+	unsigned ret;
+
+	__asm__ __volatile__("sync; lwbrx %0,0,%1; sync" : "=r" (ret) :
+			     "r" (addr), "m" (*addr));
+	return ret;
+}
+
+extern inline unsigned in_be32(volatile unsigned *addr)
+{
+	unsigned ret;
+
+	__asm__ __volatile__("sync; lwz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr));
+	return ret;
+}
+
+extern inline void out_le32(volatile unsigned *addr, int val)
+{
+	__asm__ __volatile__("sync; stwbrx %1,0,%2; sync" : "=m" (*addr) :
+			     "r" (val), "r" (addr));
+}
+
+extern inline void out_be32(volatile unsigned *addr, int val)
+{
+	__asm__ __volatile__("sync; stw%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
+}
+
+#ifndef CONFIG_PPC_ISERIES 
+#include <asm/eeh.h>
+
+static inline u8 _inb(unsigned long port) {
+	if (IS_MAPPED_VADDR(port))
+		return readb((void *)port);
+	else if (_IO_BASE)
+		return in_8((u8 *)((port)+_IO_BASE));
+	else
+		return 0xff;
+}
+static inline void _outb(u8 val, unsigned long port) {
+	if (IS_MAPPED_VADDR(port))
+		return writeb(val, (void *)port);
+	else if (_IO_BASE)
+		out_8((u8 *)((port)+_IO_BASE), val);
+}
+static inline u16 _inw(unsigned long port) {
+	if (IS_MAPPED_VADDR(port))
+		return readw((void *)port);
+	else if (_IO_BASE)
+		return in_le16((u16 *)((port)+_IO_BASE));
+	else
+		return 0xffff;
+}
+static inline void _outw(u16 val, unsigned long port) {
+	if (IS_MAPPED_VADDR(port))
+		return writew(val, (void *)port);
+	else if (_IO_BASE)
+		out_le16((u16 *)((port)+_IO_BASE), val);
+}
+static inline u32 _inl(unsigned long port) {
+	if (IS_MAPPED_VADDR(port))
+		return readl((void *)port);
+	else if (_IO_BASE)
+		return in_le32((u32 *)((port)+_IO_BASE));
+	else
+		return 0xffffffff;
+}
+static inline void _outl(u32 val, unsigned long port) {
+	if (IS_MAPPED_VADDR(port))
+		return writel(val, (void *)port);
+	else if (_IO_BASE)
+		out_le32((u32 *)((port)+_IO_BASE), val);
+}
+#endif
+
+#ifdef __KERNEL__
+static inline int check_signature(unsigned long io_addr,
+	const unsigned char *signature, int length)
+{
+	int retval = 0;
+#ifndef CONFIG_PPC_ISERIES 
+	do {
+		if (readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+	retval = 1;
+out:
+#endif
+	return retval;
+}
+
+/* Nothing to do */
+
+#define dma_cache_inv(_start,_size)		do { } while (0)
+#define dma_cache_wback(_start,_size)		do { } while (0)
+#define dma_cache_wback_inv(_start,_size)	do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _PPC64_IO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ioctl.h linux/include/asm-ppc64/ioctl.h
--- linux.orig/include/asm-ppc64/ioctl.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ioctl.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,64 @@
+#ifndef _PPC64_IOCTL_H
+#define _PPC64_IOCTL_H
+
+
+/*
+ * This was copied from the alpha as it's a bit cleaner there.
+ *                         -- Cort
+ *
+ * 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.
+ */
+
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	13
+#define _IOC_DIRBITS	3
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
+ * And this turns out useful to catch old ioctl numbers in header
+ * files for us.
+ */
+#define _IOC_NONE	1U
+#define _IOC_READ	2U
+#define _IOC_WRITE	4U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode them.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* various drivers, such as the pcmcia stuff, need these... */
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _PPC64_IOCTL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ioctls.h linux/include/asm-ppc64/ioctls.h
--- linux.orig/include/asm-ppc64/ioctls.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ioctls.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,115 @@
+#ifndef _ASM_PPC64_IOCTLS_H
+#define _ASM_PPC64_IOCTLS_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/ioctl.h>
+
+#define FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+#define FIOQSIZE        _IOR('f', 128, loff_t)
+
+#define TIOCGETP	_IOR('t', 8, struct sgttyb)
+#define TIOCSETP	_IOW('t', 9, struct sgttyb)
+#define TIOCSETN	_IOW('t', 10, struct sgttyb)	/* TIOCSETP wo flush */
+
+#define TIOCSETC	_IOW('t', 17, struct tchars)
+#define TIOCGETC	_IOR('t', 18, struct tchars)
+#define TCGETS		_IOR('t', 19, struct termios)
+#define TCSETS		_IOW('t', 20, struct termios)
+#define TCSETSW		_IOW('t', 21, struct termios)
+#define TCSETSF		_IOW('t', 22, struct termios)
+
+#define TCGETA		_IOR('t', 23, struct termio)
+#define TCSETA		_IOW('t', 24, struct termio)
+#define TCSETAW		_IOW('t', 25, struct termio)
+#define TCSETAF		_IOW('t', 28, struct termio)
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCGLTC	_IOR('t', 116, struct ltchars)
+#define TIOCSLTC	_IOW('t', 117, struct ltchars)
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+
+#define TIOCSTI		0x5412
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+# define TIOCM_LE	0x001
+# define TIOCM_DTR	0x002
+# define TIOCM_RTS	0x004
+# define TIOCM_ST	0x008
+# define TIOCM_SR	0x010
+# define TIOCM_CTS	0x020
+# define TIOCM_CAR	0x040
+# define TIOCM_RNG	0x080
+# define TIOCM_DSR	0x100
+# define TIOCM_CD	TIOCM_CAR
+# define TIOCM_RI	TIOCM_RNG
+
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+# define TIOCPKT_DATA		 0
+# define TIOCPKT_FLUSHREAD	 1
+# define TIOCPKT_FLUSHWRITE	 2
+# define TIOCPKT_STOP		 4
+# define TIOCPKT_START		 8
+# define TIOCPKT_NOSTOP		16
+# define TIOCPKT_DOSTOP		32
+
+
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+#endif /* _ASM_PPC64_IOCTLS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ipc.h linux/include/asm-ppc64/ipc.h
--- linux.orig/include/asm-ppc64/ipc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ipc.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,33 @@
+#ifndef __PPC64_IPC_H__
+#define __PPC64_IPC_H__
+
+/* 
+ * These are used to wrap system calls on PowerPC.
+ *
+ * See arch/ppc/kernel/syscalls.c for ugly details..
+ *
+ * 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.
+ */
+struct ipc_kludge {
+	u32 msgp;
+	s32 msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif /* __PPC64_IPC_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ipcbuf.h linux/include/asm-ppc64/ipcbuf.h
--- linux.orig/include/asm-ppc64/ipcbuf.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ipcbuf.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,28 @@
+#ifndef __PPC64_IPCBUF_H__
+#define __PPC64_IPCBUF_H__
+
+/*
+ * The ipc64_perm structure for the PPC is identical to kern_ipc_perm
+ * as we have always had 32-bit UIDs and GIDs in the kernel.
+ *
+ * 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.
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t	key;
+	__kernel_uid_t	uid;
+	__kernel_gid_t	gid;
+	__kernel_uid_t	cuid;
+	__kernel_gid_t	cgid;
+	__kernel_mode_t	mode;
+	unsigned int	seq;
+	unsigned int	__pad1;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif /* __PPC64_IPCBUF_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/irq.h linux/include/asm-ppc64/irq.h
--- linux.orig/include/asm-ppc64/irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/irq.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,55 @@
+#ifdef __KERNEL__
+#ifndef _ASM_IRQ_H
+#define _ASM_IRQ_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/atomic.h>
+
+extern void disable_irq(unsigned int);
+extern void disable_irq_nosync(unsigned int);
+extern void enable_irq(unsigned int);
+
+/*
+ * this is the maximum number of virtual irqs we will use.
+ */
+#define NR_IRQS			512
+
+#define NUM_8259_INTERRUPTS	16
+
+/* Interrupt numbers are virtual in case they are sparsely
+ * distributed by the hardware.
+ */
+#define NR_HW_IRQS		8192
+extern unsigned short real_irq_to_virt_map[NR_HW_IRQS];
+extern unsigned short virt_irq_to_real_map[NR_IRQS];
+/* Create a mapping for a real_irq if it doesn't already exist.
+ * Return the virtual irq as a convenience.
+ */
+unsigned long virt_irq_create_mapping(unsigned long real_irq);
+
+/* These funcs map irqs between real and virtual */
+static inline unsigned long real_irq_to_virt(unsigned long real_irq) {
+	return real_irq_to_virt_map[real_irq];
+}
+static inline unsigned long virt_irq_to_real(unsigned long virt_irq) {
+	return virt_irq_to_real_map[virt_irq];
+}
+
+/*
+ * This gets called from serial.c, which is now used on
+ * powermacs as well as prep/chrp boxes.
+ * Prep and chrp both have cascaded 8259 PICs.
+ */
+static __inline__ int irq_cannonicalize(int irq)
+{
+	return irq;
+}
+
+#endif /* _ASM_IRQ_H */
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/keyboard.h linux/include/asm-ppc64/keyboard.h
--- linux.orig/include/asm-ppc64/keyboard.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/keyboard.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,115 @@
+/*
+ *  linux/include/asm-ppc/keyboard.h
+ *
+ *  Created 3 Nov 1996 by Geert Uytterhoeven
+ *  Modified for Power Macintosh by Paul Mackerras
+ *
+ * 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 file contains the ppc architecture specific keyboard definitions -
+ * like the intel pc for prep systems, different for power macs.
+ */
+
+#ifndef __ASMPPC64_KEYBOARD_H
+#define __ASMPPC64_KEYBOARD_H
+
+#ifdef __KERNEL__
+
+#include <linux/adb.h>
+#include <asm/machdep.h>
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/kd.h>
+#include <asm/io.h>
+
+#define KEYBOARD_IRQ			1
+#define DISABLE_KBD_DURING_INTERRUPTS	0
+#define INIT_KBD
+
+static inline int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+	if ( ppc_md.kbd_setkeycode )
+		return ppc_md.kbd_setkeycode(scancode, keycode);
+	else
+		return 0;
+}
+  
+static inline int kbd_getkeycode(unsigned int scancode)
+{
+	if ( ppc_md.kbd_getkeycode )
+		return ppc_md.kbd_getkeycode(scancode);
+	else
+		return 0;
+}
+  
+static inline int kbd_translate(unsigned char keycode, unsigned char *keycodep,
+				char raw_mode)
+{
+	if ( ppc_md.kbd_translate )
+		return ppc_md.kbd_translate(keycode, keycodep, raw_mode);
+	else
+		return 0;
+}
+  
+static inline int kbd_unexpected_up(unsigned char keycode)
+{
+	if ( ppc_md.kbd_unexpected_up )
+		return ppc_md.kbd_unexpected_up(keycode);
+	else
+		return 0;
+}
+  
+static inline void kbd_leds(unsigned char leds)
+{
+	if ( ppc_md.kbd_leds )
+		ppc_md.kbd_leds(leds);
+}
+
+static inline void kbd_init_hw(void)
+{
+	if ( ppc_md.kbd_init_hw )
+		ppc_md.kbd_init_hw();
+}
+
+#define kbd_sysrq_xlate	(ppc_md.ppc_kbd_sysrq_xlate)
+
+extern unsigned long SYSRQ_KEY;
+#define E1_PAUSE	119		/* PAUSE key */
+
+/* resource allocation */
+#define kbd_request_region()
+#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
+                                             "keyboard", NULL)
+
+/* How to access the keyboard macros on this platform.  */
+#define kbd_read_input() inb(KBD_DATA_REG)
+static inline int kbd_read_status(void) {
+	int ret = inb(0x64);
+	return (ret == 0xff) ? 0 : ret;	/* translate float to bad status. */
+}
+#define kbd_write_output(val) outb(val, KBD_DATA_REG)
+#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
+
+/* Some stoneage hardware needs delays after some operations.  */
+#define kbd_pause() do { } while(0)
+
+/*
+ * Machine specific bits for the PS/2 driver
+ */
+
+#define AUX_IRQ 12
+
+#define aux_request_irq(hand, dev_id)					\
+	request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
+
+#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMPPC64_KEYBOARD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/kgdb.h linux/include/asm-ppc64/kgdb.h
--- linux.orig/include/asm-ppc64/kgdb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/kgdb.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,53 @@
+/* 
+ * kgdb.h: Defines and declarations for serial line source level
+ *         remote debugging of the Linux kernel using gdb.
+ *
+ * PPC Mods (C) 1998 Michael Tesch (tesch@cs.wisc.edu)
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * 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.
+ */
+#ifndef _PPC64_KGDB_H
+#define _PPC64_KGDB_H
+
+#ifndef __ASSEMBLY__
+/* To initialize the serial, first thing called */
+extern void zs_kgdb_hook(int tty_num);
+/* To init the kgdb engine. (called by serial hook)*/
+extern void set_debug_traps(void);
+
+/* To enter the debugger explicitly. */
+extern void breakpoint(void);
+
+/* For taking exceptions
+ * these are defined in traps.c
+ */
+extern void (*debugger)(struct pt_regs *regs);
+extern int (*debugger_bpt)(struct pt_regs *regs);
+extern int (*debugger_sstep)(struct pt_regs *regs);
+extern int (*debugger_iabr_match)(struct pt_regs *regs);
+extern int (*debugger_dabr_match)(struct pt_regs *regs);
+extern void (*debugger_fault_handler)(struct pt_regs *regs);
+
+/* What we bring to the party */
+int kgdb_bpt(struct pt_regs *regs);
+int kgdb_sstep(struct pt_regs *regs);
+void kgdb(struct pt_regs *regs);
+int kgdb_iabr_match(struct pt_regs *regs);
+int kgdb_dabr_match(struct pt_regs *regs);
+static void kgdb_fault_handler(struct pt_regs *regs);
+static void handle_exception (struct pt_regs *regs);
+
+/*
+ * external low-level support routines (ie macserial.c)
+ */
+extern void kgdb_interruptible(int); /* control interrupts from serial */
+extern void putDebugChar(char);   /* write a single character      */
+extern char getDebugChar(void);   /* read and return a single char */
+
+#endif /* !(__ASSEMBLY__) */
+#endif /* !(_PPC64_KGDB_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/linux_logo.h linux/include/asm-ppc64/linux_logo.h
--- linux.orig/include/asm-ppc64/linux_logo.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/linux_logo.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,26 @@
+/*
+ * include/asm-ppc64/linux_logo.h: A linux logo to be displayed on boot
+ * (pinched from the sparc port).
+ *
+ * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *
+ * You can put anything here, but:
+ * LINUX_LOGO_COLORS has to be less than 224
+ * values have to start from 0x20
+ * (i.e. linux_logo_{red,green,blue}[0] is color 0x20)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+ 
+#include <linux/init.h>
+
+#define linux_logo_banner "Linux/PPC-64 version " UTS_RELEASE
+
+#define LINUX_LOGO_HEIGHT	80
+#define LINUX_LOGO_WIDTH	80
+
+#include <linux/linux_logo.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/lmb.h linux/include/asm-ppc64/lmb.h
--- linux.orig/include/asm-ppc64/lmb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/lmb.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,109 @@
+#ifndef _PPC64_LMB_H
+#define _PPC64_LMB_H
+
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 2001 Peter Bergner, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/prom.h>
+
+extern unsigned long reloc_offset(void);
+
+#define MAX_LMB_REGIONS 64
+
+union lmb_reg_property { 
+	struct reg_property32 addr32[MAX_LMB_REGIONS];
+	struct reg_property64 addr64[MAX_LMB_REGIONS];
+};
+
+#define LMB_MEMORY_AREA	1
+#define LMB_IO_AREA	2
+
+struct lmb_property {
+	unsigned long base;
+	unsigned long physbase;
+	unsigned long size;
+	unsigned long type;
+};
+
+struct lmb_region {
+	unsigned long cnt;
+	unsigned long size;
+	unsigned long iosize;
+	unsigned long lcd_size;		/* Least Common Denominator */
+	struct lmb_property region[MAX_LMB_REGIONS+1];
+};
+
+struct lmb {
+	unsigned long debug;
+	struct lmb_region memory;
+	struct lmb_region reserved;
+};
+
+extern struct lmb lmb;
+
+extern void lmb_init(void);
+extern void lmb_analyze(void);
+extern long lmb_add(unsigned long, unsigned long);
+#ifdef CONFIG_MSCHUNKS
+extern long lmb_add_io(unsigned long base, unsigned long size);
+#endif /* CONFIG_MSCHUNKS */
+extern long lmb_reserve(unsigned long, unsigned long);
+extern unsigned long lmb_alloc(unsigned long, unsigned long);
+extern unsigned long lmb_phys_mem_size(void);
+extern unsigned long lmb_end_of_DRAM(void);
+extern unsigned long lmb_abs_to_phys(unsigned long);
+extern void lmb_dump(char *);
+
+static inline unsigned long
+lmb_addrs_overlap(unsigned long base1, unsigned long size1,
+                  unsigned long base2, unsigned long size2)
+{
+        return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
+}
+
+static inline long
+lmb_regions_overlap(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+{
+	unsigned long base1 = rgn->region[r1].base;
+        unsigned long size1 = rgn->region[r1].size;
+	unsigned long base2 = rgn->region[r2].base;
+        unsigned long size2 = rgn->region[r2].size;
+
+	return lmb_addrs_overlap(base1,size1,base2,size2);
+}
+
+static inline long
+lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
+		   unsigned long base2, unsigned long size2)
+{
+	if ( base2 == base1 + size1 ) {
+		return 1;
+	} else if ( base1 == base2 + size2 ) {
+		return -1;
+	}
+	return 0;
+}
+
+static inline long
+lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+{
+	unsigned long base1 = rgn->region[r1].base;
+        unsigned long size1 = rgn->region[r1].size;
+        unsigned long type1 = rgn->region[r1].type;
+	unsigned long base2 = rgn->region[r2].base;
+        unsigned long size2 = rgn->region[r2].size;
+        unsigned long type2 = rgn->region[r2].type;
+
+	return (type1 == type2) && lmb_addrs_adjacent(base1,size1,base2,size2);
+}
+
+#endif /* _PPC64_LMB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/machdep.h linux/include/asm-ppc64/machdep.h
--- linux.orig/include/asm-ppc64/machdep.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/machdep.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,150 @@
+#ifdef __KERNEL__
+#ifndef _PPC_MACHDEP_H
+#define _PPC_MACHDEP_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/seq_file.h>
+
+struct pt_regs;
+struct pci_bus;	
+struct pci_dev;
+struct kbd_repeat;
+struct device_node;
+struct TceTable;
+struct rtc_time;
+
+struct machdep_calls {
+	/* High use functions in the first cachelines, low use functions
+	 * follow.  DRENG collect profile data.
+	 */
+	void            (*hpte_invalidate)(unsigned long slot);
+
+	void            (*hpte_updatepp)(long slot, 
+					 unsigned long newpp, 
+					 unsigned long va);
+	void            (*hpte_updateboltedpp)(unsigned long newpp, 
+					       unsigned long ea);
+	unsigned long	(*hpte_getword0)(unsigned long slot);
+
+	long		(*hpte_find)( unsigned long vpn );
+
+	long		(*hpte_selectslot)(unsigned long vpn); 
+
+	void		(*hpte_create_valid)(unsigned long slot,
+					     unsigned long vpn,
+					     unsigned long prpn,
+					     unsigned hash, 
+					     void * ptep,
+					     unsigned hpteflags, 
+					     unsigned bolted);
+	void		(*tce_build)(struct TceTable * tbl,
+				     long tcenum,
+				     unsigned long uaddr,
+				     int direction);
+	void		(*tce_free_one)(struct TceTable *tbl,
+				        long tcenum);    
+
+	void		(*smp_message_pass)(int target,
+					    int msg, 
+					    unsigned long data,
+					    int wait);
+	int		(*smp_probe)(void);
+	void		(*smp_kick_cpu)(int nr);
+	void		(*smp_setup_cpu)(int nr);
+
+	void		(*setup_arch)(void);
+	/* Optional, may be NULL. */
+	void		(*setup_residual)(struct seq_file *m, int cpu_id);
+	/* Optional, may be NULL. */
+	void		(*get_cpuinfo)(struct seq_file *m);
+	/* Optional, may be NULL. */
+	unsigned int	(*irq_cannonicalize)(unsigned int irq);
+	void		(*init_IRQ)(void);
+	void		(*init_ras_IRQ)(void);
+	int		(*get_irq)(struct pt_regs *);
+	void		(*post_irq)( struct pt_regs *, int );
+	
+	/* A general init function, called by ppc_init in init/main.c.
+	   May be NULL. */
+	void		(*init)(void);
+
+	void		(*restart)(char *cmd);
+	void		(*power_off)(void);
+	void		(*halt)(void);
+
+	long		(*time_init)(void); /* Optional, may be NULL */
+	int		(*set_rtc_time)(struct rtc_time *);
+	void		(*get_rtc_time)(struct rtc_time *);
+	void		(*get_boot_time)(struct rtc_time *);
+	void		(*calibrate_decr)(void);
+
+  	void		(*progress)(char *, unsigned short);
+
+	unsigned char 	(*nvram_read_val)(int addr);
+	void		(*nvram_write_val)(int addr, unsigned char val);
+
+/* Tons of keyboard stuff. */
+	int		(*kbd_setkeycode)(unsigned int scancode,
+				unsigned int keycode);
+	int		(*kbd_getkeycode)(unsigned int scancode);
+	int		(*kbd_translate)(unsigned char scancode,
+				unsigned char *keycode,
+				char raw_mode);
+	char		(*kbd_unexpected_up)(unsigned char keycode);
+	void		(*kbd_leds)(unsigned char leds);
+	void		(*kbd_init_hw)(void);
+#ifdef CONFIG_MAGIC_SYSRQ
+	unsigned char 	*ppc_kbd_sysrq_xlate;
+#endif
+
+	/* Debug interface.  Low level I/O to some terminal device */
+	void		(*udbg_putc)(unsigned char c);
+	unsigned char	(*udbg_getc)(void);
+	int		(*udbg_getc_poll)(void);
+
+	/* PCI interfaces */
+	int (*pcibios_read_config_byte)(struct device_node *dn, int offset, u8 *val);
+	int (*pcibios_read_config_word)(struct device_node *dn, int offset, u16 *val);
+	int (*pcibios_read_config_dword)(struct device_node *dn, int offset, u32 *val);
+	int (*pcibios_write_config_byte)(struct device_node *dn, int offset, u8 val);
+	int (*pcibios_write_config_word)(struct device_node *dn, int offset, u16 val);
+	int (*pcibios_write_config_dword)(struct device_node *dn, int offset, u32 val);
+
+	/* Called after scanning the bus, before allocating
+	 * resources
+	 */
+	void (*pcibios_fixup)(void);
+
+       /* Called for each PCI bus in the system
+        * when it's probed
+        */
+	void (*pcibios_fixup_bus)(struct pci_bus *);
+
+       /* Called when pci_enable_device() is called (initial=0) or
+        * when a device with no assigned resource is found (initial=1).
+        * Returns 0 to allow assignement/enabling of the device
+        */
+        int  (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
+
+	void* (*pci_dev_io_base)(unsigned char bus, unsigned char devfn, int physical);
+	void* (*pci_dev_mem_base)(unsigned char bus, unsigned char devfn);
+	int (*pci_dev_root_bridge)(unsigned char bus, unsigned char devfn);
+
+	/* this is for modules, since _machine can be a define -- Cort */
+	int ppc_machine;
+};
+
+extern struct machdep_calls ppc_md;
+extern char cmd_line[512];
+
+extern void setup_pci_ptrs(void);
+
+#endif /* _PPC_MACHDEP_H */
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/mc146818rtc.h linux/include/asm-ppc64/mc146818rtc.h
--- linux.orig/include/asm-ppc64/mc146818rtc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/mc146818rtc.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ *
+ * 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.
+ */
+#ifndef __ASM_PPC64_MC146818RTC_H
+#define __ASM_PPC64_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x)	(0x70 + (x))
+#define RTC_ALWAYS_BCD	1	/* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* __ASM_PPC64_MC146818RTC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/md.h linux/include/asm-ppc64/md.h
--- linux.orig/include/asm-ppc64/md.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/md.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,17 @@
+/* 
+ * md.h: High speed xor_block operation for RAID4/5 
+ *
+ * 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.
+ */
+ 
+#ifndef __ASM_MD_H
+#define __ASM_MD_H
+
+/* #define HAVE_ARCH_XORBLOCK */
+
+#define MD_XORBLOCK_ALIGNMENT	sizeof(long)
+
+#endif /* __ASM_MD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/memory.h linux/include/asm-ppc64/memory.h
--- linux.orig/include/asm-ppc64/memory.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/memory.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,44 @@
+#ifndef _ASM_PPC64_MEMORY_H_ 
+#define _ASM_PPC64_MEMORY_H_ 
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+
+/*
+ * Arguably the bitops and *xchg operations don't imply any memory barrier
+ * or SMP ordering, but in fact a lot of drivers expect them to imply
+ * both, since they do on x86 cpus.
+ */
+#ifdef CONFIG_SMP
+#define EIEIO_ON_SMP	"eieio\n"
+#define ISYNC_ON_SMP	"\n\tisync"
+#else
+#define EIEIO_ON_SMP
+#define ISYNC_ON_SMP
+#endif
+
+static inline void eieio(void)
+{
+	__asm__ __volatile__ ("eieio" : : : "memory");
+}
+
+static inline void isync(void)
+{
+	__asm__ __volatile__ ("isync" : : : "memory");
+}
+
+#ifdef CONFIG_SMP
+#define eieio_on_smp()	eieio()
+#define isync_on_smp()	isync()
+#else
+#define eieio_on_smp()	__asm__ __volatile__("": : :"memory")
+#define isync_on_smp()	__asm__ __volatile__("": : :"memory")
+#endif
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/mman.h linux/include/asm-ppc64/mman.h
--- linux.orig/include/asm-ppc64/mman.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/mman.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,45 @@
+#ifndef __PPC64_MMAN_H__
+#define __PPC64_MMAN_H__
+
+/*
+ * 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.
+ */
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+#define MAP_RENAME      MAP_ANONYMOUS   /* In SunOS terminology */
+#define MAP_NORESERVE   0x40            /* don't reserve swap pages */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT     0x2000          /* lock all currently mapped pages */
+#define MCL_FUTURE      0x4000          /* lock all additions to address space */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __PPC64_MMAN_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/mmu.h linux/include/asm-ppc64/mmu.h
--- linux.orig/include/asm-ppc64/mmu.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/mmu.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,384 @@
+/*
+ * PowerPC memory management structures
+ *
+ * Dave Engebretsen & Mike Corrigan <{engebret|mikejc}@us.ibm.com>
+ *   PPC64 rework.
+ *
+ * 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.
+ */
+
+#ifndef _PPC64_MMU_H_
+#define _PPC64_MMU_H_
+
+#ifndef __ASSEMBLY__
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+/*
+ * Define the size of the cache used for segment table entries.  The first
+ * entry is used as a cache pointer, therefore the actual number of entries
+ * stored is one less than defined here.  Do not change this value without
+ * considering the impact it will have on the layout of the paca in paca.h.
+ */
+#define STAB_CACHE_SIZE 16
+
+/*
+ * Hardware Segment Lookaside Buffer Entry
+ * This structure has been padded out to two 64b doublewords (actual SLBE's are
+ * 94 bits).  This padding facilites use by the segment management
+ * instructions.
+ */
+typedef struct {
+	unsigned long esid: 36; /* Effective segment ID */
+	unsigned long resv0:20; /* Reserved */
+	unsigned long v:     1; /* Entry valid (v=1) or invalid */
+	unsigned long resv1: 1; /* Reserved */
+	unsigned long ks:    1; /* Supervisor (privileged) state storage key */
+	unsigned long kp:    1; /* Problem state storage key */
+	unsigned long n:     1; /* No-execute if n=1 */
+	unsigned long resv2: 3; /* padding to a 64b boundary */
+} ste_dword0;
+
+typedef struct {
+	unsigned long vsid: 52; /* Virtual segment ID */
+	unsigned long resv0:12; /* Padding to a 64b boundary */
+} ste_dword1;
+
+typedef struct _STE {
+	union {
+		unsigned long dword0;
+		ste_dword0    dw0;
+	} dw0;
+
+	union {
+		unsigned long dword1;
+		ste_dword1    dw1;
+	} dw1;
+} STE;
+
+typedef struct {
+	unsigned long esid: 36; /* Effective segment ID */
+	unsigned long v:     1; /* Entry valid (v=1) or invalid */
+	unsigned long null1:15; /* padding to a 64b boundary */
+	unsigned long index:12; /* Index to select SLB entry. Used by slbmte */
+} slb_dword0;
+
+typedef struct {
+	unsigned long vsid: 52; /* Virtual segment ID */
+	unsigned long ks:    1; /* Supervisor (privileged) state storage key */
+	unsigned long kp:    1; /* Problem state storage key */
+	unsigned long n:     1; /* No-execute if n=1 */
+	unsigned long l:     1; /* Virt pages are large (l=1) or 4KB (l=0) */
+	unsigned long c:     1; /* Class */
+	unsigned long resv0: 7; /* Padding to a 64b boundary */
+} slb_dword1;
+
+typedef struct _SLBE {
+	union {
+		unsigned long dword0;
+		slb_dword0    dw0;
+	} dw0;
+
+	union {
+		unsigned long dword1;
+		slb_dword1    dw1;
+	} dw1;
+} SLBE;
+
+/*
+ * This structure is used in paca.h where the layout depends on the 
+ * size being 24B.
+ */
+typedef struct {
+        unsigned long   real;
+        unsigned long   virt;
+        unsigned long   next_round_robin;
+} STAB;
+
+/* Hardware Page Table Entry */
+
+#define HPTES_PER_GROUP 8
+
+typedef struct {
+	unsigned long avpn:57; /* vsid | api == avpn  */
+	unsigned long :     2; /* Software use */
+	unsigned long bolted: 1; /* HPTE is "bolted" */
+	unsigned long :     1; /* Software use */
+	unsigned long l:    1; /* Virtual page is large (L=1) or 4 KB (L=0) */
+	unsigned long h:    1; /* Hash function identifier */
+	unsigned long v:    1; /* Valid (v=1) or invalid (v=0) */
+} Hpte_dword0;
+
+typedef struct {
+	unsigned long :     6; /* unused - padding */
+	unsigned long ac:   1; /* Address compare */
+	unsigned long r:    1; /* Referenced */
+	unsigned long c:    1; /* Changed */
+	unsigned long w:	1; /* Write-thru cache mode */
+	unsigned long i:	1; /* Cache inhibited */
+	unsigned long m:	1; /* Memory coherence required */
+	unsigned long g:	1; /* Guarded */
+	unsigned long n:	1; /* No-execute */
+	unsigned long pp:   2; /* Page protection bits 1:2 */
+} Hpte_flags;
+
+typedef struct {
+	unsigned long pp0:  1; /* Page protection bit 0 */
+	unsigned long :     1; /* Reserved */
+	unsigned long rpn: 50; /* Real page number */
+	unsigned long :     2; /* Reserved */
+	unsigned long ac:   1; /* Address compare */ 
+	unsigned long r:    1; /* Referenced */
+	unsigned long c:    1; /* Changed */
+	unsigned long w:	1; /* Write-thru cache mode */
+	unsigned long i:	1; /* Cache inhibited */
+	unsigned long m:	1; /* Memory coherence required */
+	unsigned long g:	1; /* Guarded */
+	unsigned long n:	1; /* No-execute */
+	unsigned long pp:	2; /* Page protection bits 1:2 */
+} Hpte_dword1;
+
+typedef struct {
+	char padding[6];	   	/* padding */
+	unsigned long :       6;	/* padding */ 
+	unsigned long flags: 10;	/* HPTE flags */
+} Hpte_dword1_flags;
+
+typedef struct _HPTE {
+	union {
+		unsigned long dword0;
+		Hpte_dword0   dw0;
+	} dw0;
+
+	union {
+		unsigned long dword1;
+		struct {
+			unsigned long pp0:  1; /* Page protection bit 0 */
+			unsigned long ts:   1; /* Tag set bit */ 
+			unsigned long rpn: 50; /* Real page number */
+			unsigned long :     2; /* Unused */
+			unsigned long ac:   1; /* Address compare bit */
+			unsigned long r:    1; /* Referenced */
+			unsigned long c:    1; /* Changed */
+			unsigned long w:    1; /* Write-thru cache mode */
+			unsigned long i:    1; /* Cache inhibited */
+			unsigned long m:    1; /* Memory coherence */
+			unsigned long g:    1; /* Guarded */
+			unsigned long n:    1; /* No-execute page if N=1 */
+			unsigned long pp:   2; /* Page protection bit 1:2 */
+		} dw1;
+	} dw1;
+} HPTE; 
+
+/* Values for PP (assumes Ks=0, Kp=1) */
+/* pp0 will always be 0 for linux     */
+#define PP_RWXX	0	/* Supervisor read/write, User none */
+#define PP_RWRX 1	/* Supervisor read/write, User read */
+#define PP_RWRW 2	/* Supervisor read/write, User read/write */
+#define PP_RXRX 3	/* Supervisor read,       User read */
+
+
+typedef struct {
+	HPTE *		htab;
+	unsigned long	htab_num_ptegs;
+	unsigned long	htab_hash_mask;
+	unsigned long	next_round_robin;
+	unsigned long   last_kernel_address;
+} HTAB;
+
+extern HTAB htab_data;
+
+void invalidate_hpte( unsigned long slot );
+long select_hpte_slot( unsigned long vpn );
+void create_valid_hpte( unsigned long slot, unsigned long vpn,
+			unsigned long prpn, unsigned hash,
+			void * ptep, unsigned hpteflags,
+			unsigned bolted );
+
+#define PD_SHIFT (10+12)		/* Page directory */
+#define PD_MASK  0x02FF
+#define PT_SHIFT (12)			/* Page Table */
+#define PT_MASK  0x02FF
+
+static inline unsigned long hpt_hash(unsigned long vpn, int large)
+{
+	unsigned long vsid;
+	unsigned long page;
+
+	if (large) {
+		vsid = vpn >> 4;
+		page = vpn & 0xf;
+	} else {
+		vsid = vpn >> 16;
+		page = vpn & 0xffff;
+	}
+
+	return (vsid & 0x7fffffffff) ^ page;
+}
+
+#define PG_SHIFT (12)			/* Page Entry */
+
+extern __inline__ void _tlbie( unsigned long va )
+{
+	__asm__ __volatile__ ( " \n\
+		clrldi	%0,%0,16 \n\
+		ptesync		 \n\
+		tlbie	%0	 \n\
+		eieio		 \n\
+		tlbsync		 \n\
+		ptesync"
+		: : "r" (va) : "memory" );
+}
+ 
+#endif /* __ASSEMBLY__ */
+
+/* Block size masks */
+#define BL_128K	0x000
+#define BL_256K 0x001
+#define BL_512K 0x003
+#define BL_1M   0x007
+#define BL_2M   0x00F
+#define BL_4M   0x01F
+#define BL_8M   0x03F
+#define BL_16M  0x07F
+#define BL_32M  0x0FF
+#define BL_64M  0x1FF
+#define BL_128M 0x3FF
+#define BL_256M 0x7FF
+
+/* Used to set up SDR1 register */
+#define HASH_TABLE_SIZE_64K	0x00010000
+#define HASH_TABLE_SIZE_128K	0x00020000
+#define HASH_TABLE_SIZE_256K	0x00040000
+#define HASH_TABLE_SIZE_512K	0x00080000
+#define HASH_TABLE_SIZE_1M	0x00100000
+#define HASH_TABLE_SIZE_2M	0x00200000
+#define HASH_TABLE_SIZE_4M	0x00400000
+#define HASH_TABLE_MASK_64K	0x000   
+#define HASH_TABLE_MASK_128K	0x001   
+#define HASH_TABLE_MASK_256K	0x003   
+#define HASH_TABLE_MASK_512K	0x007
+#define HASH_TABLE_MASK_1M	0x00F   
+#define HASH_TABLE_MASK_2M	0x01F   
+#define HASH_TABLE_MASK_4M	0x03F   
+
+/* These are the Ks and Kp from the PowerPC books.  For proper operation,
+ * Ks = 0, Kp = 1.
+ */
+#define MI_AP		786
+#define MI_Ks		0x80000000	/* Should not be set */
+#define MI_Kp		0x40000000	/* Should always be set */
+
+/* The effective page number register.  When read, contains the information
+ * about the last instruction TLB miss.  When MI_RPN is written, bits in
+ * this register are used to create the TLB entry.
+ */
+#define MI_EPN		787
+#define MI_EPNMASK	0xfffff000	/* Effective page number for entry */
+#define MI_EVALID	0x00000200	/* Entry is valid */
+#define MI_ASIDMASK	0x0000000f	/* ASID match value */
+					/* Reset value is undefined */
+
+/* A "level 1" or "segment" or whatever you want to call it register.
+ * For the instruction TLB, it contains bits that get loaded into the
+ * TLB entry when the MI_RPN is written.
+ */
+#define MI_TWC		789
+#define MI_APG		0x000001e0	/* Access protection group (0) */
+#define MI_GUARDED	0x00000010	/* Guarded storage */
+#define MI_PSMASK	0x0000000c	/* Mask of page size bits */
+#define MI_PS8MEG	0x0000000c	/* 8M page size */
+#define MI_PS512K	0x00000004	/* 512K page size */
+#define MI_PS4K_16K	0x00000000	/* 4K or 16K page size */
+#define MI_SVALID	0x00000001	/* Segment entry is valid */
+					/* Reset value is undefined */
+
+/* Real page number.  Defined by the pte.  Writing this register
+ * causes a TLB entry to be created for the instruction TLB, using
+ * additional information from the MI_EPN, and MI_TWC registers.
+ */
+#define MI_RPN		790
+
+/* Define an RPN value for mapping kernel memory to large virtual
+ * pages for boot initialization.  This has real page number of 0,
+ * large page size, shared page, cache enabled, and valid.
+ * Also mark all subpages valid and write access.
+ */
+#define MI_BOOTINIT	0x000001fd
+
+#define MD_CTR		792	/* Data TLB control register */
+#define MD_GPM		0x80000000	/* Set domain manager mode */
+#define MD_PPM		0x40000000	/* Set subpage protection */
+#define MD_CIDEF	0x20000000	/* Set cache inhibit when MMU dis */
+#define MD_WTDEF	0x10000000	/* Set writethrough when MMU dis */
+#define MD_RSV4I	0x08000000	/* Reserve 4 TLB entries */
+#define MD_TWAM		0x04000000	/* Use 4K page hardware assist */
+#define MD_PPCS		0x02000000	/* Use MI_RPN prob/priv state */
+#define MD_IDXMASK	0x00001f00	/* TLB index to be loaded */
+#define MD_RESETVAL	0x04000000	/* Value of register at reset */
+
+#define M_CASID		793	/* Address space ID (context) to match */
+#define MC_ASIDMASK	0x0000000f	/* Bits used for ASID value */
+
+
+/* These are the Ks and Kp from the PowerPC books.  For proper operation,
+ * Ks = 0, Kp = 1.
+ */
+#define MD_AP		794
+#define MD_Ks		0x80000000	/* Should not be set */
+#define MD_Kp		0x40000000	/* Should always be set */
+
+/* The effective page number register.  When read, contains the information
+ * about the last instruction TLB miss.  When MD_RPN is written, bits in
+ * this register are used to create the TLB entry.
+ */
+#define MD_EPN		795
+#define MD_EPNMASK	0xfffff000	/* Effective page number for entry */
+#define MD_EVALID	0x00000200	/* Entry is valid */
+#define MD_ASIDMASK	0x0000000f	/* ASID match value */
+					/* Reset value is undefined */
+
+/* The pointer to the base address of the first level page table.
+ * During a software tablewalk, reading this register provides the address
+ * of the entry associated with MD_EPN.
+ */
+#define M_TWB		796
+#define	M_L1TB		0xfffff000	/* Level 1 table base address */
+#define M_L1INDX	0x00000ffc	/* Level 1 index, when read */
+					/* Reset value is undefined */
+
+/* A "level 1" or "segment" or whatever you want to call it register.
+ * For the data TLB, it contains bits that get loaded into the TLB entry
+ * when the MD_RPN is written.  It is also provides the hardware assist
+ * for finding the PTE address during software tablewalk.
+ */
+#define MD_TWC		797
+#define MD_L2TB		0xfffff000	/* Level 2 table base address */
+#define MD_L2INDX	0xfffffe00	/* Level 2 index (*pte), when read */
+#define MD_APG		0x000001e0	/* Access protection group (0) */
+#define MD_GUARDED	0x00000010	/* Guarded storage */
+#define MD_PSMASK	0x0000000c	/* Mask of page size bits */
+#define MD_PS8MEG	0x0000000c	/* 8M page size */
+#define MD_PS512K	0x00000004	/* 512K page size */
+#define MD_PS4K_16K	0x00000000	/* 4K or 16K page size */
+#define MD_WT		0x00000002	/* Use writethrough page attribute */
+#define MD_SVALID	0x00000001	/* Segment entry is valid */
+					/* Reset value is undefined */
+
+
+/* Real page number.  Defined by the pte.  Writing this register
+ * causes a TLB entry to be created for the data TLB, using
+ * additional information from the MD_EPN, and MD_TWC registers.
+ */
+#define MD_RPN		798
+
+/* This is a temporary storage register that could be used to save
+ * a processor working register during a tablewalk.
+ */
+#define M_TW		799
+
+#endif /* _PPC64_MMU_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/mmu_context.h linux/include/asm-ppc64/mmu_context.h
--- linux.orig/include/asm-ppc64/mmu_context.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/mmu_context.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,193 @@
+#ifndef __PPC64_MMU_CONTEXT_H
+#define __PPC64_MMU_CONTEXT_H
+
+#include <linux/spinlock.h>	
+#include <linux/kernel.h>	
+#include <linux/mm.h>	
+#include <asm/mmu.h>	
+#include <asm/ppcdebug.h>	
+
+/*
+ * Copyright (C) 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+#define NO_CONTEXT		0
+#define FIRST_USER_CONTEXT	0x10    /* First 16 reserved for kernel */
+#define LAST_USER_CONTEXT	0x8000  /* Same as PID_MAX for now... */
+#define NUM_USER_CONTEXT	(LAST_USER_CONTEXT-FIRST_USER_CONTEXT)
+
+/* Choose whether we want to implement our context
+ * number allocator as a LIFO or FIFO queue.
+ */
+#if 1
+#define MMU_CONTEXT_LIFO
+#else
+#define MMU_CONTEXT_FIFO
+#endif
+
+struct mmu_context_queue_t {
+	spinlock_t lock;
+	long head;
+	long tail;
+	long size;
+	mm_context_t elements[LAST_USER_CONTEXT];
+};
+
+extern struct mmu_context_queue_t mmu_context_queue;
+
+static inline void
+enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern void flush_stab(void);
+
+/*
+ * The context number queue has underflowed.
+ * Meaning: we tried to push a context number that was freed
+ * back onto the context queue and the queue was already full.
+ */
+static inline void
+mmu_context_underflow(void)
+{
+	printk(KERN_DEBUG "mmu_context_underflow\n");
+	panic("mmu_context_underflow");
+}
+
+
+/*
+ * Set up the context for a new address space.
+ */
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	long head, size;
+
+	spin_lock( &mmu_context_queue.lock );
+
+	if ( (size = mmu_context_queue.size) <= 0 ) {
+		spin_unlock( &mmu_context_queue.lock );
+		return -ENOMEM;
+	}
+
+	head = mmu_context_queue.head;
+	mm->context = mmu_context_queue.elements[head];
+
+	head = (head < LAST_USER_CONTEXT-1) ? head+1 : 0;
+	mmu_context_queue.head = head;
+	mmu_context_queue.size = size-1;
+
+	spin_unlock( &mmu_context_queue.lock );
+
+	return 0;
+}
+
+/*
+ * We're finished using the context for an address space.
+ */
+static inline void
+destroy_context(struct mm_struct *mm)
+{
+	long index, size = mmu_context_queue.size;
+
+	spin_lock( &mmu_context_queue.lock );
+
+	if ( (size = mmu_context_queue.size) >= NUM_USER_CONTEXT ) {
+		spin_unlock( &mmu_context_queue.lock );
+		mmu_context_underflow();
+	}
+
+#ifdef MMU_CONTEXT_LIFO
+	index = mmu_context_queue.head;
+	index = (index > 0) ? index-1 : LAST_USER_CONTEXT-1;
+	mmu_context_queue.head = index;
+#else
+	index = mmu_context_queue.tail;
+	index = (index < LAST_USER_CONTEXT-1) ? index+1 : 0;
+	mmu_context_queue.tail = index;
+#endif
+
+	mmu_context_queue.size = size+1;
+	mmu_context_queue.elements[index] = mm->context;
+
+	spin_unlock( &mmu_context_queue.lock );
+}
+
+
+/*
+ * switch_mm is the entry point called from the architecture independent
+ * code in kernel/sched.c
+ */
+static inline void
+switch_mm(struct mm_struct *prev, struct mm_struct *next,
+	  struct task_struct *tsk, int cpu)
+{
+	tsk->thread.pgdir = next->pgd;	/* cache the pgdir in the thread 
+					   maybe not needed any more */
+	flush_stab();
+}
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+static inline void
+activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
+{
+	current->thread.pgdir = mm->pgd;
+	flush_stab();
+}
+
+
+#define VSID_RANDOMIZER 42470972311
+#define VSID_MASK	0xfffffffff
+
+
+/* This is only valid for kernel (including vmalloc, imalloc and bolted) EA's
+ */
+static inline unsigned long
+get_kernel_vsid( unsigned long ea )
+{
+	unsigned long ordinal, vsid;
+	
+	ordinal = (((ea >> 28) & 0x1fffff) * LAST_USER_CONTEXT) | (ea >> 60);
+	vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK;
+
+	ifppcdebug(PPCDBG_HTABSTRESS) {
+		/* For debug, this path creates a very poor vsid distribuition.
+		 * A user program can access virtual addresses in the form
+		 * 0x0yyyyxxxx000 where yyyy = xxxx to cause multiple mappings
+		 * to hash to the same page table group.
+		 */ 
+		ordinal = ((ea >> 28) & 0x1fff) | (ea >> 44);
+		vsid = ordinal & VSID_MASK;
+	}
+
+	return vsid;
+} 
+
+/* This is only valid for user EA's (user EA's do not exceed 2^41 (EADDR_SIZE))
+ */
+static inline unsigned long
+get_vsid( unsigned long context, unsigned long ea )
+{
+	unsigned long ordinal, vsid;
+
+	ordinal = (((ea >> 28) & 0x1fffff) * LAST_USER_CONTEXT) | context;
+	vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK;
+
+	ifppcdebug(PPCDBG_HTABSTRESS) {
+		/* See comment above. */
+		ordinal = ((ea >> 28) & 0x1fff) | (context << 16);
+		vsid = ordinal & VSID_MASK;
+	}
+
+	return vsid;
+}
+
+#endif /* __PPC64_MMU_CONTEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/module.h linux/include/asm-ppc64/module.h
--- linux.orig/include/asm-ppc64/module.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/module.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,18 @@
+#ifndef _ASM_PPC64_MODULE_H
+#define _ASM_PPC64_MODULE_H
+/*
+ * This file contains the PPC architecture specific module code.
+ *
+ * Copyright (C) 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define arch_init_modules(x)	do { } while (0)
+#define module_arch_init(x)  (0)
+#endif /* _ASM_PPC64_MODULE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/msgbuf.h linux/include/asm-ppc64/msgbuf.h
--- linux.orig/include/asm-ppc64/msgbuf.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/msgbuf.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,27 @@
+#ifndef _PPC64_MSGBUF_H
+#define _PPC64_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure for the PPC architecture.
+ *
+ * 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.
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused1;
+	unsigned long  __unused2;
+};
+
+#endif /* _PPC64_MSGBUF_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/naca.h linux/include/asm-ppc64/naca.h
--- linux.orig/include/asm-ppc64/naca.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/naca.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,40 @@
+#ifndef _NACA_H
+#define _NACA_H
+
+/* 
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/types.h>
+
+struct naca_struct {
+	void *xItVpdAreas;
+	void *xRamDisk;
+	u64 xRamDiskSize;		/* In pages */
+	struct paca_struct *paca;	/* Ptr to an array of pacas */
+	u64 debug_switch;		/* Bits to control debug printing */
+	u16 processorCount;		/* # of physical processors */
+	u16 dCacheL1LineSize;		/* Line size of L1 DCache in bytes */
+	u16 dCacheL1LogLineSize;	/* Log-2 of DCache line size */
+	u16 dCacheL1LinesPerPage;	/* DCache lines per page */
+	u16 iCacheL1LineSize;		/* Line size of L1 ICache in bytes */
+	u16 iCacheL1LogLineSize;	/* Log-2 of ICache line size */
+	u16 iCacheL1LinesPerPage;	/* ICache lines per page */
+	u16 slb_size;			/* SLB size in entries */
+	u64 physicalMemorySize;		/* Size of real memory in bytes */
+	u64 pftSize;			/* Log base 2 of page table size */
+	u64 serialPortAddr;		/* Phyical address of serial port */
+	u8 interrupt_controller;	/* Type of interrupt controller */ 
+	u8 resv0;    			/* Type of interrupt controller */
+	u16 platform;			/* Platform flags */
+	u8 resv1[12];			/* Padding */
+};
+
+extern struct naca_struct *naca;
+
+#endif /* _NACA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/namei.h linux/include/asm-ppc64/namei.h
--- linux.orig/include/asm-ppc64/namei.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/namei.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,23 @@
+/* 
+ * linux/include/asm-ppc/namei.h
+ * Adapted from linux/include/asm-alpha/namei.h
+ *
+ * Included from linux/fs/namei.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.
+ */
+
+#ifndef __PPC64_NAMEI_H
+#define __PPC64_NAMEI_H
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif /* __PPC64_NAMEI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/nvram.h linux/include/asm-ppc64/nvram.h
--- linux.orig/include/asm-ppc64/nvram.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/nvram.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,39 @@
+/*
+ * PreP compliant NVRAM access
+ * This needs to be updated for PPC64
+ *
+ * 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.
+ */
+
+#ifndef _PPC64_NVRAM_H
+#define _PPC64_NVRAM_H
+
+#define NVRAM_AS0  0x74
+#define NVRAM_AS1  0x75
+#define NVRAM_DATA 0x77
+
+
+/* RTC Offsets */
+
+#define MOTO_RTC_SECONDS	0x1FF9
+#define MOTO_RTC_MINUTES	0x1FFA
+#define MOTO_RTC_HOURS		0x1FFB
+#define MOTO_RTC_DAY_OF_WEEK	0x1FFC
+#define MOTO_RTC_DAY_OF_MONTH	0x1FFD
+#define MOTO_RTC_MONTH		0x1FFE
+#define MOTO_RTC_YEAR		0x1FFF
+#define MOTO_RTC_CONTROLA       0x1FF8
+#define MOTO_RTC_CONTROLB       0x1FF9
+
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+#endif /* _PPC64_NVRAM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/paca.h linux/include/asm-ppc64/paca.h
--- linux.orig/include/asm-ppc64/paca.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/paca.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,163 @@
+#ifndef _PPC64_PACA_H
+#define _PPC64_PACA_H
+
+/*============================================================================
+ *                                                         Header File Id
+ * Name______________:	paca.h
+ *
+ * Description_______:
+ *
+ * This control block defines the PACA which defines the processor 
+ * specific data for each logical processor on the system.  
+ * There are some pointers defined that are utilized by PLIC.
+ *
+ * C 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */    
+#include	<asm/types.h>
+
+#define N_EXC_STACK    2
+
+/*-----------------------------------------------------------------------------
+ * Other Includes
+ *-----------------------------------------------------------------------------
+ */
+#include	<asm/iSeries/ItLpPaca.h>
+#include	<asm/iSeries/ItLpRegSave.h>
+#include	<asm/iSeries/ItLpQueue.h>
+#include	<asm/rtas.h>
+#include	<asm/mmu.h>
+#include	<asm/processor.h>
+
+/* A paca entry is required for each logical processor.  On systems
+ * that support hardware multi-threading, this is equal to twice the
+ * number of physical processors.  On LPAR systems, we are required
+ * to have space for the maximum number of logical processors we
+ * could ever possibly have.  Currently, we are limited to allocating
+ * 24 processors to a partition which gives 48 logical processors on
+ * an HMT box.  Therefore, we reserve this many paca entries.
+ */
+#define MAX_PROCESSORS 24
+#define MAX_PACAS MAX_PROCESSORS * 2
+
+extern struct paca_struct paca[];
+#define get_paca() ((struct paca_struct *)mfspr(SPRG3))
+
+/*============================================================================
+ * Name_______:	paca
+ *
+ * Description:
+ *
+ *	Defines the layout of the paca.  
+ *
+ *	This structure is not directly accessed by PLIC or the SP except
+ *	for the first two pointers that point to the ItLpPaca area and the
+ *	ItLpRegSave area for this processor.  Both the ItLpPaca and
+ *	ItLpRegSave objects are currently contained within the
+ *	PACA but they do not need to be.
+ *
+ *============================================================================
+ */
+struct paca_struct {
+/*=====================================================================================
+ * CACHE_LINE_1 0x0000 - 0x007F
+ *=====================================================================================
+ */
+	struct ItLpPaca *xLpPacaPtr;	/* Pointer to LpPaca for PLIC		0x00 */
+	struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC	0x08 */
+	u64 xCurrent;  		        /* Pointer to current			0x10 */
+	u16 xPacaIndex;			/* Logical processor number		0x18 */
+	u16 xHwProcNum;			/* Actual Hardware Processor Number	0x1a */
+	u32 default_decr;		/* Default decrementer value		0x1c */	
+	u64 xHrdIntStack;		/* Stack for hardware interrupts	0x20 */
+	u64 xKsave;			/* Saved Kernel stack addr or zero	0x28 */
+	u64 pvr;			/* Processor version register		0x30 */
+	u8 *exception_sp;		/*					0x38 */
+
+	struct ItLpQueue *lpQueuePtr;	/* LpQueue handled by this processor    0x40 */
+	u64  xTOC;			/* Kernel TOC address			0x48 */
+	STAB xStab_data;		/* Segment table information		0x50,0x58,0x60 */
+	u8 xSegments[STAB_CACHE_SIZE];	/* Cache of used stab entries		0x68,0x70 */
+	u8 xProcEnabled;		/* 1=soft enabled			0x78 */
+	u8 xHrdIntCount;		/* Count of active hardware interrupts  0x79  */
+	u8 prof_enabled;		/* 1=iSeries profiling enabled          0x7A */
+	u8 resv1[5];			/*					0x7B-0x7F */
+
+/*=====================================================================================
+ * CACHE_LINE_2 0x0080 - 0x00FF
+ *=====================================================================================
+ */
+	u64 *pgd_cache;			/*					0x00 */
+	u64 *pmd_cache;			/*					0x08 */
+	u64 *pte_cache;			/*					0x10 */
+	u64 pgtable_cache_sz;		/*					0x18 */
+	u64 next_jiffy_update_tb;	/* TB value for next jiffy update	0x20 */
+	u32 lpEvent_count;		/* lpEvents processed			0x28 */
+	u32 prof_multiplier;		/*					0x2C */
+	u32 prof_counter;		/*					0x30 */
+	u32 prof_shift;			/* iSeries shift for profile bucket size0x34 */
+	u32 *prof_buffer;		/* iSeries profiling buffer		0x38 */
+	u32 *prof_stext;		/* iSeries start of kernel text		0x40 */
+	u32 prof_len;			/* iSeries length of profile buffer -1	0x48 */
+	u8  rsvd2[128-76];		/*					0x4C */
+
+/*=====================================================================================
+ * CACHE_LINE_3 0x0100 - 0x017F
+ *=====================================================================================
+ */
+	u8		xProcStart;	/* At startup, processor spins until	0x100 */
+  					/* xProcStart becomes non-zero. */
+	u8		rsvd3[127];
+
+/*=====================================================================================
+ * CACHE_LINE_4-8  0x0180 - 0x03FF Contains ItLpPaca
+ *=====================================================================================
+ */
+	struct ItLpPaca xLpPaca;	/* Space for ItLpPaca */
+
+/*=====================================================================================
+ * CACHE_LINE_9-16 0x0400 - 0x07FF Contains ItLpRegSave
+ *=====================================================================================
+ */
+	struct ItLpRegSave xRegSav;	/* Register save for proc */
+
+/*=====================================================================================
+ * CACHE_LINE_17-18 0x0800 - 0x0EFF Reserved
+ *=====================================================================================
+ */
+	struct rtas_args xRtas;		/* Per processor RTAS struct */
+	u64 xR1;			/* r1 save for RTAS calls */
+	u64 xSavedMsr;			/* Old msr saved here by HvCall */
+	u8 rsvd5[256-16-sizeof(struct rtas_args)];
+
+/*=====================================================================================
+ * CACHE_LINE_19-30 0x0800 - 0x0EFF Reserved
+ *=====================================================================================
+ */
+	u8 rsvd6[0x600];
+
+/*=====================================================================================
+ * CACHE_LINE_31 0x0F00 - 0x0F7F Exception stack
+ *=====================================================================================
+ */
+	u8 exception_stack[N_EXC_STACK*EXC_FRAME_SIZE];
+
+/*=====================================================================================
+ * CACHE_LINE_32 0x0F80 - 0x0FFF Reserved
+ *=====================================================================================
+ */
+	u8 rsvd7[0x80];                  /* Give the stack some rope ... */
+
+/*=====================================================================================
+ * Page 2 Reserved for guard page.  Also used as a stack early in SMP boots before
+ *        relocation is enabled.
+ *=====================================================================================
+ */
+	u8 guard[0x1000];               /* ... and then hang 'em         */ 
+};
+
+#endif /* _PPC64_PACA_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/page.h linux/include/asm-ppc64/page.h
--- linux.orig/include/asm-ppc64/page.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/page.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,239 @@
+#ifndef _PPC64_PAGE_H
+#define _PPC64_PAGE_H
+
+/*
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+#define PAGE_OFFSET_MASK (PAGE_SIZE-1)
+
+#define SID_SHIFT       28
+#define SID_MASK        0xfffffffff
+#define GET_ESID(x)     (((x) >> SID_SHIFT) & SID_MASK)
+
+/* Define an illegal instr to trap on the bug.
+ * We don't use 0 because that marks the end of a function
+ * in the ELF ABI.  That's "Boo Boo" in case you wonder...
+ */
+#define BUG_OPCODE .long 0x00b00b00  /* For asm */
+#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+#include <asm/naca.h>
+
+#define STRICT_MM_TYPECHECKS
+
+#define REGION_SIZE   4UL
+#define OFFSET_SIZE   60UL
+#define REGION_SHIFT  60UL
+#define OFFSET_SHIFT  0UL
+#define REGION_MASK   (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
+#define REGION_STRIDE (1UL << REGION_SHIFT)
+
+#ifdef ___powerpc64__
+typedef union ppc64_va {
+        struct {
+                unsigned long off : OFFSET_SIZE;  /* intra-region offset */
+                unsigned long reg : REGION_SIZE;  /* region number */
+        } f;
+        unsigned long l;
+        void *p;
+} ppc64_va;
+#endif /* ___powerpc64__ */
+       
+static __inline__ void clear_page(void *addr)
+{
+	unsigned long lines, line_size;
+
+	line_size = naca->dCacheL1LineSize; 
+	lines = naca->dCacheL1LinesPerPage;
+
+	__asm__ __volatile__(
+"  	mtctr  	%1\n\
+1:      dcbz  	0,%0\n\
+	add	%0,%0,%3\n\
+	bdnz+	1b"
+        : "=r" (addr)
+        : "r" (lines), "0" (addr), "r" (line_size)
+	: "ctr", "memory");
+}
+
+extern void copy_page(void *to, void *from);
+struct page;
+extern void clear_user_page(void *page, unsigned long vaddr);
+extern void copy_user_page(void *to, void *from, unsigned long vaddr);
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking.  
+ * Entries in the pte table are 64b, while entries in the pgd & pmd are 32b.
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned int  pmd; } pmd_t;
+typedef struct { unsigned int  pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).pmd)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef unsigned int  pmd_t;
+typedef unsigned int  pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)	(x)
+#define pmd_val(x)	(x)
+#define pgd_val(x)	(x)
+#define pgprot_val(x)	(x)
+
+#define __pte(x)	(x)
+#define __pmd(x)	(x)
+#define __pgd(x)	(x)
+#define __pgprot(x)	(x)
+
+#endif
+
+#ifdef CONFIG_XMON
+#include <asm/ptrace.h>
+extern void xmon(struct pt_regs *excp);
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	xmon(0); \
+} while (0)
+#else
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	__asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
+} while (0)
+#endif
+
+#define PAGE_BUG(page) do { BUG(); } while (0)
+
+/*
+ * XXX A bug in the current ppc64 compiler prevents an optimisation
+ * where a divide is replaced by a multiply by shifted inverse. For
+ * the moment use page->virtaul
+ */
+#define WANT_PAGE_VIRTUAL 1
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
+
+#endif /* __ASSEMBLY__ */
+
+/* align addr on a size boundry - adjust address up/down if needed */
+#define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1)))
+
+/* align addr on a size boundry - adjust address up if needed */
+#define _ALIGN(addr,size)     _ALIGN_UP(addr,size)
+
+/* to align the pointer to the (next) double word boundary */
+#define DOUBLEWORD_ALIGN(addr)	_ALIGN(addr,sizeof(unsigned long))
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	_ALIGN(addr, PAGE_SIZE)
+
+#ifdef MODULE
+#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
+#else
+#define __page_aligned \
+	__attribute__((__aligned__(PAGE_SIZE), \
+		__section__(".data.page_aligned")))
+#endif
+
+
+/* This must match the -Ttext linker address            */
+/* Note: tophys & tovirt make assumptions about how     */
+/*       KERNELBASE is defined for performance reasons. */
+/*       When KERNELBASE moves, those macros may have   */
+/*             to change!                               */
+#define PAGE_OFFSET     0xC000000000000000
+#define KERNELBASE      PAGE_OFFSET
+#define VMALLOCBASE     0xD000000000000000
+#define IOREGIONBASE    0xE000000000000000
+#define BOLTEDBASE      0xB000000000000000
+
+#define IO_REGION_ID       (IOREGIONBASE>>REGION_SHIFT)
+#define VMALLOC_REGION_ID  (VMALLOCBASE>>REGION_SHIFT)
+#define KERNEL_REGION_ID   (KERNELBASE>>REGION_SHIFT)
+#define BOLTED_REGION_ID   (BOLTEDBASE>>REGION_SHIFT)
+#define USER_REGION_ID     (0UL)
+#define REGION_ID(X)	   (((unsigned long)(X))>>REGION_SHIFT)
+
+/*
+ * Define valid/invalid EA bits (for all ranges)
+ */
+#define VALID_EA_BITS   (0x000001ffffffffffUL)
+#define INVALID_EA_BITS (~(REGION_MASK|VALID_EA_BITS))
+
+#define IS_VALID_REGION_ID(x) \
+        (((x) == USER_REGION_ID) || ((x) >= BOLTED_REGION_ID))
+#define IS_VALID_EA(x) \
+        ((!((x) & INVALID_EA_BITS)) && IS_VALID_REGION_ID(REGION_ID(x)))
+
+#define __bpn_to_ba(x) ((((unsigned long)(x))<<PAGE_SHIFT) + KERNELBASE)
+#define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT)
+
+#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
+
+/* Given that physical addresses do not map 1-1 to absolute addresses, we
+ * use these macros to better specify exactly what we want to do.
+ * The only restriction on their use is that the absolute address
+ * macros cannot be used until after the LMB structure has been
+ * initialized in prom.c.  -Peter
+ */
+#define __v2p(x) ((void *) __pa(x))
+#define __v2a(x) ((void *) phys_to_absolute(__pa(x)))
+#define __p2a(x) ((void *) phys_to_absolute(x))
+#define __p2v(x) ((void *) __va(x))
+#define __a2p(x) ((void *) absolute_to_phys(x))
+#define __a2v(x) ((void *) __va(absolute_to_phys(x)))
+
+#define virt_to_page(kaddr) (mem_map+(__pa((unsigned long)kaddr) >> PAGE_SHIFT))
+
+#define VALID_PAGE(page)    ((page - mem_map) < max_mapnr)
+
+#define MAP_NR(addr)        (__pa(addr) >> PAGE_SHIFT)
+
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif /* __KERNEL__ */
+#endif /* _PPC64_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/param.h linux/include/asm-ppc64/param.h
--- linux.orig/include/asm-ppc64/param.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/param.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,41 @@
+#ifndef _ASM_PPC64_PARAM_H
+#define _ASM_PPC64_PARAM_H
+
+/*
+ * 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.
+ */
+
+#ifndef HZ
+#define HZ 100
+#ifdef __KERNEL__
+#if HZ == 100
+/* ppc (like X86) is defined to provide userspace with a world where HZ=100
+   We have to do this, (x*const)/const2 isnt optimised out because its not
+   a null operation as it might overflow.. */
+#define hz_to_std(a) (a)
+#else
+#define hz_to_std(a) ((a)*(100/HZ)+((a)*(100%HZ))/HZ)
+#endif
+#endif
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC	HZ	/* frequency at which times() counts */
+#endif
+
+#endif /* _ASM_PPC64_PARAM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/parport.h linux/include/asm-ppc64/parport.h
--- linux.orig/include/asm-ppc64/parport.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/parport.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,18 @@
+/*
+ * parport.h: platform-specific PC-style parport initialisation
+ *
+ * Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
+ *
+ * This file should only be included by drivers/parport/parport_pc.c.
+ */
+
+#ifndef _ASM_PPC64_PARPORT_H
+#define _ASM_PPC64_PARPORT_H
+
+static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
+static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
+{
+	return parport_pc_find_isa_ports (autoirq, autodma);
+}
+
+#endif /* !(_ASM_PPC_PARPORT_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/pci-bridge.h linux/include/asm-ppc64/pci-bridge.h
--- linux.orig/include/asm-ppc64/pci-bridge.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/pci-bridge.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,114 @@
+#ifdef __KERNEL__
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+
+/*
+ * 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.
+ */
+
+struct device_node;
+struct pci_controller;
+
+/*
+ * pci_io_base returns the memory address at which you can access
+ * the I/O space for PCI bus number `bus' (or NULL on error).
+ */
+extern void *pci_bus_io_base(unsigned int bus);
+extern unsigned long pci_bus_io_base_phys(unsigned int bus);
+extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+/* Get the PCI host controller for an OF device */
+extern struct pci_controller*
+pci_find_hose_for_OF_device(struct device_node* node);
+
+enum phb_types { 
+	phb_type_unknown    = 0x0,
+	phb_type_hypervisor = 0x1,
+	phb_type_python     = 0x10,
+	phb_type_speedwagon = 0x11
+};
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	char what[8];                     /* Eye catcher      */
+	enum phb_types type;              /* Type of hardware */
+	struct pci_controller *next;
+	struct pci_bus *bus;
+	void *arch_data;
+
+	int first_busno;
+	int last_busno;
+
+	void *io_base_virt;
+	unsigned long io_base_phys;
+
+	/* Some machines (PReP) have a non 1:1 mapping of
+	 * the PCI memory space in the CPU bus space
+	 */
+	unsigned long pci_mem_offset;
+	unsigned long pci_io_offset;
+
+	struct pci_ops *ops;
+	volatile unsigned long *cfg_addr;
+	volatile unsigned char *cfg_data;
+	volatile unsigned long *phb_regs;
+	volatile unsigned long *chip_regs;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource io_resource;
+	struct resource mem_resources[3];
+	int mem_resource_count;
+	int    global_number;		
+	int    local_number;		
+	int    system_bus_number;	
+	unsigned long buid;
+	unsigned long dma_window_base_cur;
+	unsigned long dma_window_size;
+};
+
+
+/* This version handles the new Uni-N host bridge, the iobase is now
+ * a per-device thing. I also added the memory base so PReP can
+ * be fixed to return 0xc0000000 (I didn't actually implement it)
+ *
+ * pci_dev_io_base() returns either a virtual (ioremap'ed) address or
+ * a physical address. In-kernel clients will use logical while the
+ * sys_pciconfig_iobase syscall returns a physical one to userland.
+ */
+void *pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical);
+void *pci_dev_mem_base(unsigned char bus, unsigned char devfn);
+
+/* Returns the root-bridge number (Uni-N number) of a device */
+int pci_dev_root_bridge(unsigned char bus, unsigned char devfn);
+
+/*
+ * pci_device_loc returns the bus number and device/function number
+ * for a device on a PCI bus, given its device_node struct.
+ * It returns 0 if OK, -1 on error.
+ */
+int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr,
+		   unsigned char *devfn_ptr);
+
+struct bridge_data {
+	volatile unsigned int *cfg_addr;
+	volatile unsigned char *cfg_data;
+	void *io_base;		/* virtual */
+	unsigned long io_base_phys;
+	int bus_number;
+	int max_bus;
+	struct bridge_data *next;
+	struct device_node *node;
+};
+
+#endif
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/pci.h linux/include/asm-ppc64/pci.h
--- linux.orig/include/asm-ppc64/pci.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/pci.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,151 @@
+#ifndef __PPC64_PCI_H
+#define __PPC64_PCI_H
+#ifdef __KERNEL__
+
+/*
+ * 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.
+ */
+
+/* Values for the `which' argument to sys_pciconfig_iobase syscall.  */
+#define IOBASE_BRIDGE_NUMBER	0
+#define IOBASE_MEMORY		1
+#define IOBASE_IO		2
+#define IOBASE_ISA_IO           3
+#define IOBASE_ISA_MEM          4
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+ * already-configured bus numbers - to be used for buggy BIOSes
+ * or architectures with incomplete PCI setup by the loader.
+ */
+extern int pcibios_assign_all_busses(void);
+
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0x10000000
+
+extern inline void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+extern inline void pcibios_penalize_isa_irq(int irq)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+
+struct pci_dev;
+#define REG_SAVE_SIZE 64
+/************************************************************************
+ * Structure to hold the data for PCI Register Save/Restore functions.  *
+ ************************************************************************/
+struct pci_config_reg_save_area {
+	struct pci_dev* PciDev;	    /* Pointer to device(Sanity Check)     */ 
+	int    Flags;               /* Control & Info Flags                */
+	int    RCode;               /* Return Code on Save/Restore         */
+	int    Register;            /* Pointer to current register.        */
+	u8     Regs[REG_SAVE_SIZE]; /* Save Area                           */ 
+};
+/************************************************************************
+ * Functions to support device reset                                    *
+ ************************************************************************/
+extern int   pci_reset_device(struct pci_dev*, int, int);
+extern int   pci_save_config_regs(struct pci_dev*,struct pci_config_reg_save_area*);
+extern int   pci_restore_config_regs(struct pci_dev*,struct pci_config_reg_save_area*);
+extern char* pci_card_location(struct pci_dev*);
+
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				  dma_addr_t *dma_handle);
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+
+extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+					size_t size, int direction);
+extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+                             size_t size, int direction);
+extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+                      int nents, int direction);
+extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+                         int nents, int direction);
+
+extern void pSeries_pcibios_init_early(void);
+
+extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+				       dma_addr_t dma_handle,
+				       size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	/* nothing to do */
+}
+
+extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+				   struct scatterlist *sg,
+				   int nelems, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	/* nothing to do */
+}
+
+/* Return whether the given PCI device DMA address mask can
+ * be supported properly.  For example, if your device can
+ * only drive the low 24-bits during PCI bus mastering, then
+ * you would pass 0x00ffffff as the mask to this function.
+ */
+extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+	return 1;
+}
+
+/* Return the index of the PCI controller for device PDEV. */
+extern int pci_controller_num(struct pci_dev *pdev);
+
+struct vm_area_struct;
+/* Map a range of PCI memory or I/O space for a device into user space */
+int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine);
+
+/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
+#define HAVE_PCI_MMAP	1
+
+#define sg_dma_address(sg)	((sg)->dma_address)
+#define sg_dma_len(sg)		((sg)->dma_length)
+
+#define pci_map_page(dev, page, off, size, dir) \
+		pci_map_single(dev, (page_address(page) + (off)), size, dir)
+#define pci_unmap_page(dev,addr,sz,dir) pci_unmap_single(dev,addr,sz,dir)
+
+/* pci_unmap_{single,page} is not a nop, thus... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
+	dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		\
+	__u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME)			\
+	((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)		\
+	(((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME)			\
+	((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
+	(((PTR)->LEN_NAME) = (VAL))
+
+#define pci_dac_dma_supported(pci_dev, mask)	(0)
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(0)
+	
+#endif	/* __KERNEL__ */
+
+#endif /* __PPC64_PCI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/pci_dma.h linux/include/asm-ppc64/pci_dma.h
--- linux.orig/include/asm-ppc64/pci_dma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/pci_dma.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,100 @@
+/*
+ * pci_dma.h
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM 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
+ */
+
+#ifndef _PCI_DMA_H
+#define _PCI_DMA_H
+
+#include <asm/types.h>
+#include <linux/spinlock.h>
+
+/*
+ * NUM_TCE_LEVELS defines the largest contiguous block
+ * of dma (tce) space we can get.  NUM_TCE_LEVELS = 10 
+ * allows up to 2**9 pages (512 * 4096) = 2 MB
+ */
+#define NUM_TCE_LEVELS 10
+
+#define NO_TCE ((dma_addr_t)-1)
+
+/*
+ * Tces come in two formats, one for the virtual bus and a different
+ * format for PCI
+ */
+#define TCE_VB  0
+#define TCE_PCI 1
+
+union Tce {
+   	u64 wholeTce;
+	struct {
+		u64 cacheBits	:6;	/* Cache hash bits - not used */
+		u64 rsvd	:6;
+		u64 rpn		:40;	/* Absolute page number */
+		u64 valid	:1;	/* Tce is valid (vb only) */
+		u64 allIo	:1;	/* Tce is valid for all lps (vb only) */
+		u64 lpIndex	:8;	/* LpIndex for user of TCE (vb only) */
+		u64 pciWrite	:1;	/* Write allowed (pci only) */
+		u64 readWrite	:1;	/* Read allowed (pci), Write allowed (vb) */
+	} tceBits;
+};
+
+struct Bitmap {
+	unsigned long	numBits;
+	unsigned long	numBytes;
+	unsigned char * map;
+};
+
+struct MultiLevelBitmap {
+	unsigned long 	maxLevel;
+	struct Bitmap 	level[NUM_TCE_LEVELS];
+};
+
+struct TceTable {
+	u64	busNumber;
+	u64	size;
+	u64	startOffset;
+	u64     base;                   /* pSeries native only */
+	u64	index;
+	u64	tceType;
+	spinlock_t lock;
+	struct MultiLevelBitmap mlbm;
+};
+
+struct TceTableManagerCB {
+	u64	busNumber;		/* Bus number for this tce table */
+	u64	start;			/* Will be NULL for secondary */
+	u64	totalSize;		/* Size (in pages) of whole table */
+	u64	startOffset;		/* Index into real tce table of the
+					   start of our section */
+	u64	size;			/* Size (in pages) of our section */
+	u64	index;			/* Index of this tce table (token?) */
+	u16	maxTceTableIndex;	/* Max num of tables for partition */
+	u8	virtualBusFlag;		/* Flag to indicate virtual bus */
+ 	u8	logicalSlot;		/* IOA Tce Slot Index */
+ 	u8	rsvd[4];
+};
+
+extern struct TceTable virtBusTceTable;	/* Tce table for virtual bus */
+
+extern void create_tce_tables(void);
+extern void create_pci_bus_tce_table(unsigned long);
+
+void tce_init_pSeries(void);
+void tce_init_iSeries(void);
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/pgalloc.h linux/include/asm-ppc64/pgalloc.h
--- linux.orig/include/asm-ppc64/pgalloc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/pgalloc.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,127 @@
+#ifndef _PPC64_PGALLOC_H
+#define _PPC64_PGALLOC_H
+
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
+
+/*
+ * 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.
+ */
+#define quicklists      get_paca()
+
+#define pgd_quicklist 		(quicklists->pgd_cache)
+#define pmd_quicklist 		(quicklists->pmd_cache)
+#define pte_quicklist 		(quicklists->pte_cache)
+#define pgtable_cache_size 	(quicklists->pgtable_cache_sz)
+
+static inline pgd_t*
+pgd_alloc_one_fast (struct mm_struct *mm)
+{
+	unsigned long *ret = pgd_quicklist;
+
+	if (ret != NULL) {
+		pgd_quicklist = (unsigned long *)(*ret);
+		ret[0] = 0;
+		--pgtable_cache_size;
+	} else
+		ret = NULL;
+	return (pgd_t *) ret;
+}
+
+static inline pgd_t*
+pgd_alloc (struct mm_struct *mm)
+{
+	/* the VM system never calls pgd_alloc_one_fast(), so we do it here. */
+	pgd_t *pgd = pgd_alloc_one_fast(mm);
+
+	if (pgd == NULL) {
+		pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
+		if (pgd != NULL)
+			clear_page(pgd);
+	}
+	return pgd;
+}
+
+static inline void
+pgd_free (pgd_t *pgd)
+{
+	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+	pgd_quicklist = (unsigned long *) pgd;
+	++pgtable_cache_size;
+}
+
+#define pgd_populate(MM, PGD, PMD)	pgd_set(PGD, PMD)
+
+static inline pmd_t*
+pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr)
+{
+	unsigned long *ret = (unsigned long *)pmd_quicklist;
+
+	if (ret != NULL) {
+		pmd_quicklist = (unsigned long *)(*ret);
+		ret[0] = 0;
+		--pgtable_cache_size;
+	}
+	return (pmd_t *)ret;
+}
+
+static inline pmd_t*
+pmd_alloc_one (struct mm_struct *mm, unsigned long addr)
+{
+	pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
+
+	if (pmd != NULL)
+		clear_page(pmd);
+	return pmd;
+}
+
+static inline void
+pmd_free (pmd_t *pmd)
+{
+	*(unsigned long *)pmd = (unsigned long) pmd_quicklist;
+	pmd_quicklist = (unsigned long *) pmd;
+	++pgtable_cache_size;
+}
+
+#define pmd_populate(MM, PMD, PTE)	pmd_set(PMD, PTE)
+
+static inline pte_t*
+pte_alloc_one_fast (struct mm_struct *mm, unsigned long addr)
+{
+	unsigned long *ret = (unsigned long *)pte_quicklist;
+
+	if (ret != NULL) {
+		pte_quicklist = (unsigned long *)(*ret);
+		ret[0] = 0;
+		--pgtable_cache_size;
+	}
+	return (pte_t *)ret;
+}
+
+
+static inline pte_t*
+pte_alloc_one (struct mm_struct *mm, unsigned long addr)
+{
+	pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL);
+
+	if (pte != NULL)
+		clear_page(pte);
+	return pte;
+}
+
+static inline void
+pte_free (pte_t *pte)
+{
+	*(unsigned long *)pte = (unsigned long) pte_quicklist;
+	pte_quicklist = (unsigned long *) pte;
+	++pgtable_cache_size;
+}
+
+extern int do_check_pgt_cache(int, int);
+
+#endif /* _PPC64_PGALLOC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/pgtable.h linux/include/asm-ppc64/pgtable.h
--- linux.orig/include/asm-ppc64/pgtable.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/pgtable.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,444 @@
+#ifndef _PPC64_PGTABLE_H
+#define _PPC64_PGTABLE_H
+
+/*
+ * This file contains the functions and defines necessary to modify and use
+ * the ppc64 hashed page table.
+ */
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>		/* For TASK_SIZE */
+#include <asm/mmu.h>
+#include <asm/page.h>
+#endif /* __ASSEMBLY__ */
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - 3) + (PAGE_SHIFT - 2))
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/*
+ * Entries per page directory level.  The PTE level must use a 64b record
+ * for each page table entry.  The PMD and PGD level use a 32b record for 
+ * each entry by assuming that each entry is page aligned.
+ */
+#define PTE_INDEX_SIZE  9
+#define PMD_INDEX_SIZE  10
+#define PGD_INDEX_SIZE  10
+
+#define PTRS_PER_PTE	(1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD	(1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PGD	(1 << PGD_INDEX_SIZE)
+
+#if 0
+/* DRENG / PPPBBB This is a compiler bug!!! */
+#define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
+#else
+#define USER_PTRS_PER_PGD	(1024)
+#endif
+#define FIRST_USER_PGD_NR	0
+
+#define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
+                    PGD_INDEX_SIZE + PAGE_SHIFT) 
+
+/*
+ * Define the address range of the vmalloc VM area.
+ */
+#define VMALLOC_START (0xD000000000000000)
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END   (VMALLOC_START + VALID_EA_BITS)
+
+/*
+ * Define the address range of the imalloc VM area.
+ * (used for ioremap)
+ */
+#define IMALLOC_START (ioremap_bot)
+#define IMALLOC_VMADDR(x) ((unsigned long)(x))
+#define IMALLOC_BASE  (0xE000000000000000)
+#define IMALLOC_END   (IMALLOC_BASE + VALID_EA_BITS)
+
+/*
+ * Define the address range mapped virt <-> physical
+ */
+#define KRANGE_START KERNELBASE
+#define KRANGE_END   (KRANGE_START + VALID_EA_BITS)
+
+/*
+ * Define the user address range
+ */
+#define USER_START (0UL)
+#define USER_END   (USER_START + VALID_EA_BITS)
+
+
+/*
+ * Bits in a linux-style PTE.  These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible.
+ */
+#define _PAGE_PRESENT	0x001UL	/* software: pte contains a translation */
+#define _PAGE_USER	0x002UL	/* matches one of the PP bits */
+#define _PAGE_RW	0x004UL	/* software: user write access allowed */
+#define _PAGE_GUARDED	0x008UL
+#define _PAGE_COHERENT	0x010UL	/* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE	0x020UL	/* I: cache inhibit */
+#define _PAGE_WRITETHRU	0x040UL	/* W: cache write-through */
+#define _PAGE_DIRTY	0x080UL	/* C: page changed */
+#define _PAGE_ACCESSED	0x100UL	/* R: page referenced */
+#define _PAGE_HPTENOIX	0x200UL /* software: pte HPTE slot unknown */
+#define _PAGE_HASHPTE	0x400UL	/* software: pte has an associated HPTE */
+#define _PAGE_EXEC	0x800UL	/* software: i-cache coherence required */
+#define _PAGE_SECONDARY 0x8000UL /* software: HPTE is in secondary group */
+#define _PAGE_GROUP_IX  0x7000UL /* software: HPTE index within group */
+/* Bits 0x7000 identify the index within an HPT Group */
+#define _PAGE_HPTEFLAGS (_PAGE_HASHPTE | _PAGE_HPTENOIX | _PAGE_SECONDARY | _PAGE_GROUP_IX)
+/* PAGE_MASK gives the right answer below, but only by accident */
+/* It should be preserving the high 48 bits and then specifically */
+/* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
+#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HPTEFLAGS)
+
+#define _PAGE_BASE	_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT
+
+#define _PAGE_WRENABLE	_PAGE_RW | _PAGE_DIRTY 
+
+/* __pgprot defined in asm-ppc64/page.h */
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+
+#define PAGE_SHARED	__pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
+#define PAGE_SHARED_X	__pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_COPY	__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_READONLY	__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_KERNEL	__pgprot(_PAGE_BASE | _PAGE_WRENABLE)
+#define PAGE_KERNEL_CI	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
+			       _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
+
+/*
+ * The PowerPC can only do execute protection on a segment (256MB) basis,
+ * not on a page basis.  So we consider execute permission the same as read.
+ * Also, write permissions imply read permissions.
+ * This is the closest we can get..
+ */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY_X
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY_X
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY_X
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY_X
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY_X
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED_X
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY_X
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED_X
+
+#ifndef __ASSEMBLY__
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page))
+#endif /* __ASSEMBLY__ */
+
+/* shift to put page number into pte */
+#define PTE_SHIFT (16)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * mk_pte_phys takes a physical address as input 
+ *
+ * mk_pte takes a (struct page *) as input
+ */
+
+#define mk_pte_phys(physpage,pgprot)                                      \
+({									  \
+	pte_t pte;							  \
+	pte_val(pte) = (((physpage)<<(PTE_SHIFT-PAGE_SHIFT)) | pgprot_val(pgprot)); \
+	pte;							          \
+})
+
+#define mk_pte(page,pgprot)                                               \
+({									  \
+	pte_t pte;							  \
+	pte_val(pte) = ((unsigned long)((page) - mem_map) << PTE_SHIFT) |   \
+                        pgprot_val(pgprot);                               \
+	pte;							          \
+})
+
+#define pte_modify(_pte, newprot) \
+  (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
+
+#define pte_none(pte)		((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0)
+#define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
+
+/* pte_clear moved to later in this file */
+
+#define pte_pagenr(x)		((unsigned long)((pte_val(x) >> PTE_SHIFT)))
+#define pte_page(x)		(mem_map+pte_pagenr(x))
+
+#define pmd_set(pmdp, ptep) 	(pmd_val(*(pmdp)) = (__ba_to_bpn(ptep)))
+#define pmd_none(pmd)		(!pmd_val(pmd))
+#define	pmd_bad(pmd)		((pmd_val(pmd)) == 0)
+#define	pmd_present(pmd)	((pmd_val(pmd)) != 0)
+#define	pmd_clear(pmdp)		(pmd_val(*(pmdp)) = 0)
+#define pmd_page(pmd)		(__bpn_to_ba(pmd_val(pmd)))
+#define pgd_set(pgdp, pmdp)	(pgd_val(*(pgdp)) = (__ba_to_bpn(pmdp)))
+#define pgd_none(pgd)		(!pgd_val(pgd))
+#define pgd_bad(pgd)		((pgd_val(pgd)) == 0)
+#define pgd_present(pgd)	(pgd_val(pgd) != 0UL)
+#define pgd_clear(pgdp)		(pgd_val(*(pgdp)) = 0UL)
+#define pgd_page(pgd)		(__bpn_to_ba(pgd_val(pgd))) 
+
+/* 
+ * Find an entry in a page-table-directory.  We combine the address region 
+ * (the high order N bits) and the pgd portion of the address.
+ */
+#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD -1))
+
+#define pgd_offset(mm, address)	 ((mm)->pgd + pgd_index(address))
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(dir,addr) \
+  ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
+
+/* Find an entry in the third-level page table.. */
+#define pte_offset(dir,addr) \
+  ((pte_t *) pmd_page(*(dir)) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+
+/* to find an entry in a kernel page-table-directory */
+/* This now only contains the vmalloc pages */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* to find an entry in the ioremap page-table-directory */
+#define pgd_offset_i(address) (ioremap_pgd + pgd_index(address))
+
+/*
+ * Given a pointer to an mem_map[] entry, return the kernel virtual
+ * address corresponding to that page.
+ */
+#define page_address(page) ((page)->virtual)
+
+#define pages_to_mb(x)		((x) >> (20-PAGE_SHIFT))
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+extern inline int pte_read(pte_t pte)  { return pte_val(pte) & _PAGE_USER;}
+extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;}
+extern inline int pte_exec(pte_t pte)  { return pte_val(pte) & _PAGE_EXEC;}
+extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
+extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
+
+extern inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
+extern inline void pte_cache(pte_t pte)   { pte_val(pte) &= ~_PAGE_NO_CACHE; }
+
+extern inline pte_t pte_rdprotect(pte_t pte) {
+	pte_val(pte) &= ~_PAGE_USER; return pte; }
+extern inline pte_t pte_exprotect(pte_t pte) {
+	pte_val(pte) &= ~_PAGE_EXEC; return pte; }
+extern inline pte_t pte_wrprotect(pte_t pte) {
+	pte_val(pte) &= ~(_PAGE_RW); return pte; }
+extern inline pte_t pte_mkclean(pte_t pte) {
+	pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
+extern inline pte_t pte_mkold(pte_t pte) {
+	pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+
+extern inline pte_t pte_mkread(pte_t pte) {
+	pte_val(pte) |= _PAGE_USER; return pte; }
+extern inline pte_t pte_mkexec(pte_t pte) {
+	pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; }
+extern inline pte_t pte_mkwrite(pte_t pte) {
+	pte_val(pte) |= _PAGE_RW; return pte; }
+extern inline pte_t pte_mkdirty(pte_t pte) {
+	pte_val(pte) |= _PAGE_DIRTY; return pte; }
+extern inline pte_t pte_mkyoung(pte_t pte) {
+	pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+
+/* Atomic PTE updates */
+
+static inline unsigned long pte_update( pte_t *p, unsigned long clr,
+					unsigned long set )
+{
+	unsigned long old, tmp;
+
+	__asm__ __volatile__("\n\
+1:	ldarx	%0,0,%3	\n\
+	andc	%1,%0,%4 \n\
+	or	%1,%1,%5 \n\
+	stdcx.	%1,0,%3 \n\
+	bne-	1b"
+	: "=&r" (old), "=&r" (tmp), "=m" (*p)
+	: "r" (p), "r" (clr), "r" (set), "m" (*p)
+	: "cc" );
+	return old;
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+	return (pte_update(ptep, _PAGE_ACCESSED, 0) & _PAGE_ACCESSED) != 0;
+}
+
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+	return (pte_update(ptep, _PAGE_DIRTY, 0) & _PAGE_DIRTY) != 0;
+}
+
+static inline pte_t ptep_get_and_clear(pte_t *ptep)
+{
+	return __pte(pte_update(ptep, ~_PAGE_HPTEFLAGS, 0));
+}
+
+static inline void ptep_set_wrprotect(pte_t *ptep)
+{
+	pte_update(ptep, _PAGE_RW, 0);
+}
+
+static inline void ptep_mkdirty(pte_t *ptep)
+{
+	pte_update(ptep, 0, _PAGE_DIRTY);
+}
+
+#define pte_same(A,B)	(((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+
+/*
+ * set_pte stores a linux PTE into the linux page table.
+ * On machines which use an MMU hash table we avoid changing the
+ * _PAGE_HASHPTE bit.
+ */
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+	pte_update(ptep, ~_PAGE_HPTEFLAGS, pte_val(pte) & ~_PAGE_HPTEFLAGS);
+}
+
+static inline void pte_clear(pte_t * ptep)
+{
+	pte_update(ptep, ~_PAGE_HPTEFLAGS, 0);
+}
+
+struct mm_struct;
+struct vm_area_struct;
+extern void local_flush_tlb_all(void);
+extern void local_flush_tlb_mm(struct mm_struct *mm);
+extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+			    unsigned long end);
+
+#define flush_tlb_all local_flush_tlb_all
+#define flush_tlb_mm local_flush_tlb_mm
+#define flush_tlb_page local_flush_tlb_page
+#define flush_tlb_range local_flush_tlb_range
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				unsigned long start, unsigned long end)
+{
+	/* PPC has hw page tables. */
+}
+
+/*
+ * No cache flushing is required when address mappings are
+ * changed, because the caches on PowerPCs are physically
+ * addressed.
+ */
+#define flush_cache_all()		do { } while (0)
+#define flush_cache_mm(mm)		do { } while (0)
+#define flush_cache_range(mm, a, b)	do { } while (0)
+#define flush_cache_page(vma, p)	do { } while (0)
+#define flush_page_to_ram(page)		do { } while (0)
+
+extern void flush_icache_user_range(struct vm_area_struct *vma,
+			struct page *page, unsigned long addr, int len);
+extern void flush_icache_range(unsigned long, unsigned long);
+extern void __flush_dcache_icache(void *page_va);
+extern void flush_dcache_page(struct page *page);
+extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+
+extern unsigned long va_to_phys(unsigned long address);
+extern pte_t *va_to_pte(unsigned long address);
+extern unsigned long ioremap_bot, ioremap_base;
+
+#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
+
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e))
+
+extern pgd_t swapper_pg_dir[1024];
+extern pgd_t ioremap_dir[1024];
+
+extern void paging_init(void);
+
+/*
+ * Page tables may have changed.  We don't need to do anything here
+ * as entries are faulted into the hash table by the low-level
+ * data/instruction access exception handlers.
+ */
+/*
+ * We won't be able to use update_mmu_cache to update the 
+ * hardware page table because we need to update the pte
+ * as well, but we don't get the address of the pte, only
+ * its value.
+ */
+#define update_mmu_cache(vma, addr, pte)	do { } while (0)
+
+extern void flush_hash_segments(unsigned low_vsid, unsigned high_vsid);
+extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t *ptep);
+extern void build_valid_hpte(unsigned long vsid, unsigned long ea, 
+			     unsigned long pa, pte_t * ptep, 
+			     unsigned hpteflags, unsigned bolted );
+
+/* Encode and de-code a swap entry */
+#define SWP_TYPE(entry)			(((entry).val >> 1) & 0x3f)
+#define SWP_OFFSET(entry)		((entry).val >> 8)
+#define SWP_ENTRY(type, offset)		((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+#define pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) >> PTE_SHIFT })
+#define swp_entry_to_pte(x)		((pte_t) { (x).val << PTE_SHIFT })
+
+/*
+ * kern_addr_valid is intended to indicate whether an address is a valid
+ * kernel address.  Most 32-bit archs define it as always true (like this)
+ * but most 64-bit archs actually perform a test.  What should we do here?
+ * The only use is in fs/ncpfs/dir.c
+ */
+#define kern_addr_valid(addr)	(1)
+
+#define io_remap_page_range remap_page_range 
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()	do { } while (0)
+
+extern void updateBoltedHptePP(unsigned long newpp, unsigned long ea);
+extern void hpte_init_pSeries(void);
+extern void hpte_init_iSeries(void);
+
+extern void make_pte(HPTE * htab, unsigned long va, unsigned long pa,
+		int mode, unsigned long hash_mask, int large);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _PPC64_PGTABLE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/pmc.h linux/include/asm-ppc64/pmc.h
--- linux.orig/include/asm-ppc64/pmc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/pmc.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,121 @@
+/* 
+ * pmc.h
+ * Copyright (C) 2001  Dave Engebretsen & Mike Corrigan IBM Corporation.
+ *
+ * The PPC64 PMC subsystem encompases both the hardware PMC registers and 
+ * a set of software event counters.  An interface is provided via the
+ * proc filesystem which can be used to access this subsystem.
+ *
+ * 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
+ */
+
+/* Start Change Log
+ * 2001/06/05 : engebret : Created.
+ * End Change Log 
+ */
+
+#ifndef _PPC64_TYPES_H
+#include        <asm/types.h>
+#endif
+
+#ifndef _PMC_H
+#define _PMC_H
+
+#define STAB_ENTRY_MAX 64
+
+struct _pmc_hw
+{
+	u64 mmcr0; 
+	u64 mmcr1; 
+	u64 mmcra; 
+
+	u64 pmc1; 
+	u64 pmc2; 
+	u64 pmc3; 
+	u64 pmc4; 
+	u64 pmc5; 
+	u64 pmc6; 
+	u64 pmc7; 
+	u64 pmc8; 
+};
+
+struct _pmc_sw
+{
+	u64 stab_faults;           /* Count of faults on the stab      */
+	u64 stab_capacity_castouts;/* Count of castouts from the stab  */
+	u64 stab_invalidations;	   /* Count of invalidations from the  */
+                                   /*   stab, not including castouts   */
+	u64 stab_entry_use[STAB_ENTRY_MAX]; 
+
+	u64 htab_primary_overflows;
+	u64 htab_capacity_castouts;
+	u64 htab_read_to_write_fault;
+};
+
+#define PMC_HW_TEXT_ENTRY_COUNT (sizeof(struct _pmc_hw) / sizeof(u64))
+#define PMC_SW_TEXT_ENTRY_COUNT (sizeof(struct _pmc_sw) / sizeof(u64))
+#define PMC_TEXT_ENTRY_SIZE  64
+
+struct _pmc_sw_text {
+	char buffer[PMC_SW_TEXT_ENTRY_COUNT * PMC_TEXT_ENTRY_SIZE];
+};
+
+struct _pmc_hw_text {
+	char buffer[PMC_HW_TEXT_ENTRY_COUNT * PMC_TEXT_ENTRY_SIZE];
+};
+
+extern struct _pmc_sw pmc_sw_system;
+extern struct _pmc_sw pmc_sw_cpu[];
+
+extern struct _pmc_sw_text pmc_sw_text;
+extern struct _pmc_hw_text pmc_hw_text;
+extern char *ppc64_pmc_stab(int file);
+extern char *ppc64_pmc_htab(int file);
+extern char *ppc64_pmc_hw(int file);
+
+void *btmalloc(unsigned long size);
+void btfree(void *addr);
+
+#if 1
+#define PMC_SW_PROCESSOR(F)      pmc_sw_cpu[smp_processor_id()].F++
+#define PMC_SW_PROCESSOR_A(F, E) (pmc_sw_cpu[smp_processor_id()].F[(E)])++
+#define PMC_SW_SYSTEM(F)         pmc_sw_system.F++
+#else
+#define PMC_SW_PROCESSOR(F)   do {;} while (0)
+#define PMC_SW_PROCESSOR_A(F) do {;} while (0)
+#define PMC_SW_SYSTEM(F)      do {;} while (0)
+#endif
+
+#define MMCR0 795
+#define MMCR1 798
+#define MMCRA 786
+#define PMC1  787
+#define PMC2  788
+#define PMC3  789
+#define PMC4  790
+#define PMC5  791
+#define PMC6  792
+#define PMC7  793
+#define PMC8  794
+
+#define PMC_CONTROL_CPI 1
+#define PMC_CONTROL_TLB 2
+
+/* To find an entry in the bolted page-table-directory */
+#define pgd_offset_b(address) (bolted_pgd + pgd_index(address))
+#define BTMALLOC_START 0xB000000000000000
+#define BTMALLOC_END   0xB0000000ffffffff /* 4 GB Max-more or less arbitrary */
+
+#endif /* _PMC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/poll.h linux/include/asm-ppc64/poll.h
--- linux.orig/include/asm-ppc64/poll.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/poll.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,31 @@
+#ifndef __PPC64_POLL_H
+#define __PPC64_POLL_H
+
+/*
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+#define POLLRDNORM	0x0040
+#define POLLRDBAND	0x0080
+#define POLLWRNORM	0x0100
+#define POLLWRBAND	0x0200
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif /* __PPC64_POLL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/posix_types.h linux/include/asm-ppc64/posix_types.h
--- linux.orig/include/asm-ppc64/posix_types.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/posix_types.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,126 @@
+#ifndef _PPC64_POSIX_TYPES_H
+#define _PPC64_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ *
+ * 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.
+ */
+#if 0
+# define DRENG_TYPES
+#endif
+
+#ifdef DRENG_TYPES
+typedef unsigned long	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned long  	__kernel_nlink_t;
+#else
+typedef unsigned int	__kernel_dev_t;
+typedef unsigned int	__kernel_ino_t;
+typedef unsigned int  	__kernel_nlink_t;
+#endif
+typedef unsigned int	__kernel_mode_t;
+typedef long		__kernel_off_t;
+typedef long long	__kernel_loff_t;
+typedef int		__kernel_pid_t;
+typedef int             __kernel_ipc_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef long		__kernel_ssize_t;
+typedef long		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned int	__kernel_old_uid_t;
+typedef unsigned int	__kernel_old_gid_t;
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+#ifndef __GNUC__
+
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define	__FD_ZERO(set)	\
+  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
+
+#else /* __GNUC__ */
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
+    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+/* With GNU C, use inline functions instead so args are evaluated only once: */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
+{ 
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+{
+	unsigned long *tmp = (unsigned long *)p->fds_bits;
+	int i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+		      case 16:
+			tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+			tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+
+		      case 8:
+			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+
+		      case 4:
+			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+			return;
+		}
+	}
+	i = __FDSET_LONGS;
+	while (i) {
+		i--;
+		*tmp = 0;
+		tmp++;
+	}
+}
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#endif /* __GNUC__ */
+#endif /* _PPC64_POSIX_TYPES_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ppc32.h linux/include/asm-ppc64/ppc32.h
--- linux.orig/include/asm-ppc64/ppc32.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ppc32.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,232 @@
+#ifndef _PPC64_PPC32_H
+#define _PPC64_PPC32_H
+
+#include <asm/siginfo.h>
+#include <asm/signal.h>
+
+/*
+ * Data types and macros for providing 32b PowerPC support.
+ * 
+ * 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.
+ */
+
+#ifndef __KERNEL_STRICT_NAMES
+#include <linux/types.h>
+typedef __kernel_fsid_t __kernel_fsid_t32;
+#endif
+
+/* Use this to get at 32-bit user passed pointers. */
+/* Things to consider: the low-level assembly stub does
+   srl x, 0, x for first four arguments, so if you have
+   pointer to something in the first four arguments, just
+   declare it as a pointer, not u32. On the other side, 
+   arguments from 5th onwards should be declared as u32
+   for pointers, and need AA() around each usage.
+   A() macro should be used for places where you e.g.
+   have some internal variable u32 and just want to get
+   rid of a compiler warning. AA() has to be used in
+   places where you want to convert a function argument
+   to 32bit pointer or when you e.g. access pt_regs
+   structure and want to consider 32bit registers only.
+   -
+ */
+#define A(__x) ((unsigned long)(__x))
+#define AA(__x)				\
+({	unsigned long __ret;		\
+	__asm__ ("clrldi	%0, %0, 32"	\
+		 : "=r" (__ret)		\
+		 : "0" (__x));		\
+	__ret;				\
+})
+
+/* These are here to support 32-bit syscalls on a 64-bit kernel. */
+typedef unsigned int           __kernel_size_t32;
+typedef int                    __kernel_ssize_t32;
+typedef int                    __kernel_ptrdiff_t32;
+typedef int                    __kernel_time_t32;
+typedef int                    __kernel_clock_t32;
+typedef int                    __kernel_pid_t32;
+typedef unsigned short         __kernel_ipc_pid_t32;
+typedef unsigned int           __kernel_uid_t32;
+typedef unsigned int           __kernel_gid_t32;
+typedef unsigned int           __kernel_dev_t32;
+typedef unsigned int           __kernel_ino_t32;
+typedef unsigned int           __kernel_mode_t32;
+typedef unsigned int           __kernel_umode_t32;
+typedef short                  __kernel_nlink_t32;
+typedef int                    __kernel_daddr_t32;
+typedef int                    __kernel_off_t32;
+typedef unsigned int           __kernel_caddr_t32;
+typedef int 		       __kernel_loff_t32;
+/* typedef __kernel_fsid_t        __kernel_fsid_t32; */
+
+struct statfs32 {
+	int f_type;
+	int f_bsize;
+	int f_blocks;
+	int f_bfree;
+	int f_bavail;
+	int f_files;
+	int f_ffree;
+	__kernel_fsid_t32 f_fsid;
+	int f_namelen;  /* SunOS ignores this field. */
+	int f_spare[6];
+};
+
+typedef union sigval32 {
+	int sival_int;
+	unsigned int sival_ptr;
+} sigval_t32;
+
+typedef struct siginfo32 {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t32 _pid;		/* sender's pid */
+			unsigned int _uid;		/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t32 _pid;		/* sender's pid */
+			unsigned int _uid;		/* sender's uid */
+			sigval_t32 _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t32 _pid;		/* which child */
+			unsigned int _uid;		/* sender's uid */
+			int _status;			/* exit code */
+			__kernel_clock_t32 _utime;
+			__kernel_clock_t32 _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
+		struct {
+			u32 _addr; /* faulting insn/memory ref. */
+			int _trapno;
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t32;
+
+#define __old_sigset_t32	old_sigset_t32
+#define __old_sigaction32	old_sigaction32
+
+typedef unsigned int __old_sigset_t32;
+struct __old_sigaction32 {
+	unsigned		sa_handler;
+	__old_sigset_t32  	sa_mask;
+	unsigned int    	sa_flags;
+	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
+};
+
+
+
+#define _PPC32_NSIG	       64
+#define _PPC32_NSIG_BPW	       32
+#define _PPC32_NSIG_WORDS	       (_PPC32_NSIG / _PPC32_NSIG_BPW)
+
+typedef struct {
+       unsigned int sig[_PPC32_NSIG_WORDS];
+} sigset32_t;
+
+struct sigaction32 {
+       unsigned int  sa_handler;	/* Really a pointer, but need to deal 
+					     with 32 bits */
+       unsigned int sa_flags;
+       unsigned int sa_restorer;	/* Another 32 bit pointer */
+       sigset32_t sa_mask;		/* A 32 bit mask */
+};
+
+typedef struct sigaltstack_32 {
+	unsigned int ss_sp;
+	int ss_flags;
+	__kernel_size_t32 ss_size;
+} stack_32_t;
+
+struct flock32 {
+	short l_type;
+	short l_whence;
+	__kernel_off_t32 l_start;
+	__kernel_off_t32 l_len;
+	__kernel_pid_t32 l_pid;
+	short __unused;
+};
+
+struct stat32 {
+	__kernel_dev_t32   st_dev; /* 2 */
+	/* __kernel_dev_t32 __pad1; */ /* 2 */
+	__kernel_ino_t32   st_ino; /* 4  */
+	__kernel_mode_t32  st_mode; /* 2  */
+	short   	   st_nlink; /* 2 */
+	__kernel_uid_t32   st_uid; /* 2 */
+	__kernel_gid_t32   st_gid; /* 2 */
+	__kernel_dev_t32   st_rdev; /* 2 */
+	/* __kernel_dev_t32 __pad2; */ /* 2 */
+	__kernel_off_t32   st_size; /* 4 */
+	__kernel_off_t32   st_blksize; /* 4 */
+	__kernel_off_t32   st_blocks; /* 4 */
+	__kernel_time_t32  st_atime; /* 4 */
+	unsigned int       __unused1; /* 4 */
+	__kernel_time_t32  st_mtime; /* 4 */
+	unsigned int       __unused2; /* 4 */
+	__kernel_time_t32  st_ctime; /* 4 */
+	unsigned int       __unused3; /* 4 */
+	unsigned int  __unused4[2]; /* 2*4 */
+};
+
+struct __old_kernel_stat32
+{
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned int   st_size;
+	unsigned int   st_atime;
+	unsigned int   st_mtime;
+	unsigned int   st_ctime;
+};
+
+struct sigcontext32_struct {
+	unsigned int	_unused[4];
+	int		signal;
+	unsigned int	handler;
+	unsigned int	oldmask;
+	u32 regs;  /* 4 byte pointer to the pt_regs32 structure. */
+};
+
+struct ucontext32 { 
+	unsigned int	  uc_flags;
+	unsigned int 	  uc_link;
+	stack_32_t	  uc_stack;
+	struct sigcontext32_struct uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+
+#endif  /* _PPC64_PPC32_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ppc_asm.tmpl linux/include/asm-ppc64/ppc_asm.tmpl
--- linux.orig/include/asm-ppc64/ppc_asm.tmpl	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ppc_asm.tmpl	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,115 @@
+/* Condition Register Bit Fields */
+
+#define	cr0	0
+#define	cr1	1
+#define	cr2	2
+#define	cr3	3
+#define	cr4	4
+#define	cr5	5
+#define	cr6	6
+#define	cr7	7
+
+
+/* General Purpose Registers (GPRs) */
+
+#define	r0	0
+#define	r1	1
+#define	r2	2
+#define	r3	3
+#define	r4	4
+#define	r5	5
+#define	r6	6
+#define	r7	7
+#define	r8	8
+#define	r9	9
+#define	r10	10
+#define	r11	11
+#define	r12	12
+#define	r13	13
+#define	r14	14
+#define	r15	15
+#define	r16	16
+#define	r17	17
+#define	r18	18
+#define	r19	19
+#define	r20	20
+#define	r21	21
+#define	r22	22
+#define	r23	23
+#define	r24	24
+#define	r25	25
+#define	r26	26
+#define	r27	27
+#define	r28	28
+#define	r29	29
+#define	r30	30
+#define	r31	31
+
+
+/* Floating Point Registers (FPRs) */
+
+#define	fr0	0
+#define	fr1	1
+#define	fr2	2
+#define	fr3	3
+#define	fr4	4
+#define	fr5	5
+#define	fr6	6
+#define	fr7	7
+#define	fr8	8
+#define	fr9	9
+#define	fr10	10
+#define	fr11	11
+#define	fr12	12
+#define	fr13	13
+#define	fr14	14
+#define	fr15	15
+#define	fr16	16
+#define	fr17	17
+#define	fr18	18
+#define	fr19	19
+#define	fr20	20
+#define	fr21	21
+#define	fr22	22
+#define	fr23	23
+#define	fr24	24
+#define	fr25	25
+#define	fr26	26
+#define	fr27	27
+#define	fr28	28
+#define	fr29	29
+#define	fr30	30
+#define	fr31	31
+
+#define	vr0	0
+#define	vr1	1
+#define	vr2	2
+#define	vr3	3
+#define	vr4	4
+#define	vr5	5
+#define	vr6	6
+#define	vr7	7
+#define	vr8	8
+#define	vr9	9
+#define	vr10	10
+#define	vr11	11
+#define	vr12	12
+#define	vr13	13
+#define	vr14	14
+#define	vr15	15
+#define	vr16	16
+#define	vr17	17
+#define	vr18	18
+#define	vr19	19
+#define	vr20	20
+#define	vr21	21
+#define	vr22	22
+#define	vr23	23
+#define	vr24	24
+#define	vr25	25
+#define	vr26	26
+#define	vr27	27
+#define	vr28	28
+#define	vr29	29
+#define	vr30	30
+#define	vr31	31
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ppcdebug.h linux/include/asm-ppc64/ppcdebug.h
--- linux.orig/include/asm-ppc64/ppcdebug.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ppcdebug.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,119 @@
+#ifndef __PPCDEBUG_H
+#define __PPCDEBUG_H
+/********************************************************************
+ * Author: Adam Litke, IBM Corp
+ * (c) 2001
+ *
+ * This file contains definitions and macros for a runtime debugging
+ * system for ppc64 (This should also work on 32 bit with a few    
+ * adjustments.                                                   
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ ********************************************************************/
+
+#include <linux/config.h>
+#include <asm/udbg.h>
+#include <stdarg.h>
+
+#define PPCDBG_BITVAL(X)     ((1UL)<<((unsigned long)(X)))
+
+/* Defined below are the bit positions of various debug flags in the
+ * debug_switch variable (defined in naca.h).
+ * -- When adding new values, please enter them into trace names below -- 
+ *
+ * Values 62 & 63 can be used to stress the hardware page table management
+ * code.  They must be set statically, any attempt to change them dynamically
+ * would be a very bad idea.
+ */
+#define PPCDBG_MMINIT        PPCDBG_BITVAL(0)
+#define PPCDBG_MM            PPCDBG_BITVAL(1)
+#define PPCDBG_SYS32         PPCDBG_BITVAL(2)
+#define PPCDBG_SYS32NI       PPCDBG_BITVAL(3)
+#define PPCDBG_SYS32X	     PPCDBG_BITVAL(4)
+#define PPCDBG_SYS32M	     PPCDBG_BITVAL(5)
+#define PPCDBG_SYS64         PPCDBG_BITVAL(6)
+#define PPCDBG_SYS64NI       PPCDBG_BITVAL(7)
+#define PPCDBG_SYS64X	     PPCDBG_BITVAL(8)
+#define PPCDBG_SIGNAL        PPCDBG_BITVAL(9)
+#define PPCDBG_SIGNALXMON    PPCDBG_BITVAL(10)
+#define PPCDBG_BINFMT32      PPCDBG_BITVAL(11)
+#define PPCDBG_BINFMT64      PPCDBG_BITVAL(12)
+#define PPCDBG_BINFMTXMON    PPCDBG_BITVAL(13)
+#define PPCDBG_BINFMT_32ADDR PPCDBG_BITVAL(14)
+#define PPCDBG_ALIGNFIXUP    PPCDBG_BITVAL(15)
+#define PPCDBG_TCEINIT       PPCDBG_BITVAL(16)
+#define PPCDBG_TCE           PPCDBG_BITVAL(17)
+#define PPCDBG_PHBINIT       PPCDBG_BITVAL(18)
+#define PPCDBG_SMP           PPCDBG_BITVAL(19)
+#define PPCDBG_BOOT          PPCDBG_BITVAL(20)
+#define PPCDBG_BUSWALK       PPCDBG_BITVAL(21)
+#define PPCDBG_HTABSTRESS    PPCDBG_BITVAL(62)
+#define PPCDBG_HTABSIZE      PPCDBG_BITVAL(63)
+#define PPCDBG_NONE          (0UL)
+#define PPCDBG_ALL           (0xffffffffUL)
+
+/* The default initial value for the debug switch */
+#define PPC_DEBUG_DEFAULT    0 
+/* #define PPC_DEBUG_DEFAULT    PPCDBG_ALL        */
+
+#define PPCDBG_NUM_FLAGS     64
+
+#ifdef WANT_PPCDBG_TAB
+/* A table of debug switch names to allow name lookup in xmon 
+ * (and whoever else wants it.
+ */
+char *trace_names[PPCDBG_NUM_FLAGS] = {
+	/* Known debug names */
+	"mminit", 	"mm",
+	"syscall32", 	"syscall32_ni", "syscall32x",	"syscall32m",
+	"syscall64", 	"syscall64_ni", "syscall64x",
+	"signal",	"signal_xmon",
+	"binfmt32",	"binfmt64",	"binfmt_xmon",	"binfmt_32addr",
+	"alignfixup",   "tceinit",      "tce",          "phb_init",     
+	"smp",          "boot",         "buswalk"
+};
+#else
+extern char *trace_names[64];
+#endif /* WANT_PPCDBG_TAB */
+
+#ifdef CONFIG_PPCDBG
+/* Macro to conditionally print debug based on debug_switch */
+#define PPCDBG(...) udbg_ppcdbg(__VA_ARGS__)
+
+/* Macro to conditionally call a debug routine based on debug_switch */
+#define PPCDBGCALL(FLAGS,FUNCTION) ifppcdebug(FLAGS) FUNCTION
+
+/* Macros to test for debug states */
+#define ifppcdebug(FLAGS) if (udbg_ifdebug(FLAGS))
+#define ppcdebugset(FLAGS) (udbg_ifdebug(FLAGS))
+#define PPCDBG_BINFMT ((current->thread.flags & PPC_FLAG_32BIT) ? PPCDBG_BINFMT32 : PPCDBG_BINFMT64)
+
+#ifdef CONFIG_XMON
+#define PPCDBG_ENTER_DEBUGGER() xmon(0)
+#define PPCDBG_ENTER_DEBUGGER_REGS(X) xmon(X)
+#endif
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#define PPCDBG_ENTER_DEBUGGER() kdb(KDB_REASON_CALL, 0, 0)
+#endif
+
+#else
+#define PPCDBG(...) do {;} while (0)
+#define PPCDBGCALL(FLAGS,FUNCTION) do {;} while (0)
+#define ifppcdebug(...) if (0)
+#define ppcdebugset(FLAGS) (0)
+#endif /* CONFIG_PPCDBG */
+
+#ifndef PPCDBG_ENTER_DEBUGGER
+#define PPCDBG_ENTER_DEBUGGER() do {;} while(0)
+#endif
+
+#ifndef PPCDBG_ENTER_DEBUGGER_REGS
+#define PPCDBG_ENTER_DEBUGGER_REGS(A) do {;} while(0)
+#endif
+
+#endif /*__PPCDEBUG_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/proc_fs.h linux/include/asm-ppc64/proc_fs.h
--- linux.orig/include/asm-ppc64/proc_fs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/proc_fs.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,33 @@
+#ifndef _PPC64_PROC_FS_H
+#define _PPC64_PROC_FS_H
+/*
+ * proc_fs.h
+ * Copyright (C) 2001  Mike Corrigan  IBM 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
+ */
+
+/* Change Activity: */
+/* tgall -- merge of iSeries/iSeries_proc.h and proc_pmc.h */
+/* End Change Activity */
+
+#include <linux/proc_fs.h>
+
+void pmc_proc_init(struct proc_dir_entry *iSeries_proc);
+void proc_ppc64_init(void);
+
+#include <asm/iSeries/iSeries_proc.h>
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/proc_pmc.h linux/include/asm-ppc64/proc_pmc.h
--- linux.orig/include/asm-ppc64/proc_pmc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/proc_pmc.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,33 @@
+/*
+ * pmc_proc.h
+ * Copyright (C) 2001  Mike Corrigan  IBM 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
+ */
+
+
+/* Change Activity: */
+/* End Change Activity */
+
+#ifndef _PMC_PROC_H
+#define _PMC_PROC_H
+
+#include <linux/proc_fs.h>
+
+void pmc_proc_init(struct proc_dir_entry *iSeries_proc);
+void proc_ppc64_init(void);
+
+#endif /* _PMC_PROC_H */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/processor.h linux/include/asm-ppc64/processor.h
--- linux.orig/include/asm-ppc64/processor.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/processor.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,743 @@
+#ifndef __ASM_PPC64_PROCESSOR_H
+#define __ASM_PPC64_PROCESSOR_H
+
+/*
+ * Copyright (C) 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/stringify.h>
+#ifndef __ASSEMBLY__
+#include <asm/atomic.h>
+#include <asm/ppcdebug.h>
+#include <asm/a.out.h>
+#endif
+#include <asm/ptrace.h>
+#include <asm/types.h>
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+/* Machine State Register (MSR) Fields */
+#define MSR_SF_LG	63              /* Enable 64 bit mode */
+#define MSR_ISF_LG	61              /* Interrupt 64b mode valid on 630 */
+#define MSR_HV_LG 	60              /* Hypervisor state */
+#define MSR_VEC_LG	25	        /* Enable AltiVec */
+#define MSR_POW_LG	18		/* Enable Power Management */
+#define MSR_WE_LG	18		/* Wait State Enable */
+#define MSR_TGPR_LG	17		/* TLB Update registers in use */
+#define MSR_CE_LG	17		/* Critical Interrupt Enable */
+#define MSR_ILE_LG	16		/* Interrupt Little Endian */
+#define MSR_EE_LG	15		/* External Interrupt Enable */
+#define MSR_PR_LG	14		/* Problem State / Privilege Level */
+#define MSR_FP_LG	13		/* Floating Point enable */
+#define MSR_ME_LG	12		/* Machine Check Enable */
+#define MSR_FE0_LG	11		/* Floating Exception mode 0 */
+#define MSR_SE_LG	10		/* Single Step */
+#define MSR_BE_LG	9		/* Branch Trace */
+#define MSR_DE_LG	9 		/* Debug Exception Enable */
+#define MSR_FE1_LG	8		/* Floating Exception mode 1 */
+#define MSR_IP_LG	6		/* Exception prefix 0x000/0xFFF */
+#define MSR_IR_LG	5 		/* Instruction Relocate */
+#define MSR_DR_LG	4 		/* Data Relocate */
+#define MSR_PE_LG	3		/* Protection Enable */
+#define MSR_PX_LG	2		/* Protection Exclusive Mode */
+#define MSR_RI_LG	1		/* Recoverable Exception */
+#define MSR_LE_LG	0 		/* Little Endian */
+
+#ifdef __ASSEMBLY__
+#define __MASK(X)	(1<<(X))
+#else
+#define __MASK(X)	(1UL<<(X))
+#endif
+
+#define MSR_SF		__MASK(MSR_SF_LG)	/* Enable 64 bit mode */
+#define MSR_ISF		__MASK(MSR_ISF_LG)	/* Interrupt 64b mode valid on 630 */
+#define MSR_HV 		__MASK(MSR_HV_LG)	/* Hypervisor state */
+#define MSR_VEC		__MASK(MSR_VEC_LG)	/* Enable AltiVec */
+#define MSR_POW		__MASK(MSR_POW_LG)	/* Enable Power Management */
+#define MSR_WE		__MASK(MSR_WE_LG)	/* Wait State Enable */
+#define MSR_TGPR	__MASK(MSR_TGPR_LG)	/* TLB Update registers in use */
+#define MSR_CE		__MASK(MSR_CE_LG)	/* Critical Interrupt Enable */
+#define MSR_ILE		__MASK(MSR_ILE_LG)	/* Interrupt Little Endian */
+#define MSR_EE		__MASK(MSR_EE_LG)	/* External Interrupt Enable */
+#define MSR_PR		__MASK(MSR_PR_LG)	/* Problem State / Privilege Level */
+#define MSR_FP		__MASK(MSR_FP_LG)	/* Floating Point enable */
+#define MSR_ME		__MASK(MSR_ME_LG)	/* Machine Check Enable */
+#define MSR_FE0		__MASK(MSR_FE0_LG)	/* Floating Exception mode 0 */
+#define MSR_SE		__MASK(MSR_SE_LG)	/* Single Step */
+#define MSR_BE		__MASK(MSR_BE_LG)	/* Branch Trace */
+#define MSR_DE		__MASK(MSR_DE_LG)	/* Debug Exception Enable */
+#define MSR_FE1		__MASK(MSR_FE1_LG)	/* Floating Exception mode 1 */
+#define MSR_IP		__MASK(MSR_IP_LG)	/* Exception prefix 0x000/0xFFF */
+#define MSR_IR		__MASK(MSR_IR_LG)	/* Instruction Relocate */
+#define MSR_DR		__MASK(MSR_DR_LG)	/* Data Relocate */
+#define MSR_PE		__MASK(MSR_PE_LG)	/* Protection Enable */
+#define MSR_PX		__MASK(MSR_PX_LG)	/* Protection Exclusive Mode */
+#define MSR_RI		__MASK(MSR_RI_LG)	/* Recoverable Exception */
+#define MSR_LE		__MASK(MSR_LE_LG)	/* Little Endian */
+
+#define MSR_		MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF
+#define MSR_KERNEL      MSR_ | MSR_SF | MSR_HV
+
+#define MSR_USER32	MSR_ | MSR_PR | MSR_EE
+#define MSR_USER64	MSR_USER32 | MSR_SF
+
+/* Floating Point Status and Control Register (FPSCR) Fields */
+
+#define FPSCR_FX	0x80000000	/* FPU exception summary */
+#define FPSCR_FEX	0x40000000	/* FPU enabled exception summary */
+#define FPSCR_VX	0x20000000	/* Invalid operation summary */
+#define FPSCR_OX	0x10000000	/* Overflow exception summary */
+#define FPSCR_UX	0x08000000	/* Underflow exception summary */
+#define FPSCR_ZX	0x04000000	/* Zero-devide exception summary */
+#define FPSCR_XX	0x02000000	/* Inexact exception summary */
+#define FPSCR_VXSNAN	0x01000000	/* Invalid op for SNaN */
+#define FPSCR_VXISI	0x00800000	/* Invalid op for Inv - Inv */
+#define FPSCR_VXIDI	0x00400000	/* Invalid op for Inv / Inv */
+#define FPSCR_VXZDZ	0x00200000	/* Invalid op for Zero / Zero */
+#define FPSCR_VXIMZ	0x00100000	/* Invalid op for Inv * Zero */
+#define FPSCR_VXVC	0x00080000	/* Invalid op for Compare */
+#define FPSCR_FR	0x00040000	/* Fraction rounded */
+#define FPSCR_FI	0x00020000	/* Fraction inexact */
+#define FPSCR_FPRF	0x0001f000	/* FPU Result Flags */
+#define FPSCR_FPCC	0x0000f000	/* FPU Condition Codes */
+#define FPSCR_VXSOFT	0x00000400	/* Invalid op for software request */
+#define FPSCR_VXSQRT	0x00000200	/* Invalid op for square root */
+#define FPSCR_VXCVI	0x00000100	/* Invalid op for integer convert */
+#define FPSCR_VE	0x00000080	/* Invalid op exception enable */
+#define FPSCR_OE	0x00000040	/* IEEE overflow exception enable */
+#define FPSCR_UE	0x00000020	/* IEEE underflow exception enable */
+#define FPSCR_ZE	0x00000010	/* IEEE zero divide exception enable */
+#define FPSCR_XE	0x00000008	/* FP inexact exception enable */
+#define FPSCR_NI	0x00000004	/* FPU non IEEE-Mode */
+#define FPSCR_RN	0x00000003	/* FPU rounding control */
+
+/* Special Purpose Registers (SPRNs)*/
+
+#define	SPRN_CDBCR	0x3D7	/* Cache Debug Control Register */
+#define	SPRN_CTR	0x009	/* Count Register */
+#define	SPRN_DABR	0x3F5	/* Data Address Breakpoint Register */
+#define	SPRN_DAC1	0x3F6	/* Data Address Compare 1 */
+#define	SPRN_DAC2	0x3F7	/* Data Address Compare 2 */
+#define	SPRN_DAR	0x013	/* Data Address Register */
+#define	SPRN_DBAT0L	0x219	/* Data BAT 0 Lower Register */
+#define	SPRN_DBAT0U	0x218	/* Data BAT 0 Upper Register */
+#define	SPRN_DBAT1L	0x21B	/* Data BAT 1 Lower Register */
+#define	SPRN_DBAT1U	0x21A	/* Data BAT 1 Upper Register */
+#define	SPRN_DBAT2L	0x21D	/* Data BAT 2 Lower Register */
+#define	SPRN_DBAT2U	0x21C	/* Data BAT 2 Upper Register */
+#define	SPRN_DBAT3L	0x21F	/* Data BAT 3 Lower Register */
+#define	SPRN_DBAT3U	0x21E	/* Data BAT 3 Upper Register */
+#define	SPRN_DBCR	0x3F2	/* Debug Control Regsiter */
+#define	  DBCR_EDM	0x80000000
+#define	  DBCR_IDM	0x40000000
+#define	  DBCR_RST(x)	(((x) & 0x3) << 28)
+#define	    DBCR_RST_NONE       	0
+#define	    DBCR_RST_CORE       	1
+#define	    DBCR_RST_CHIP       	2
+#define	    DBCR_RST_SYSTEM		3
+#define	  DBCR_IC	0x08000000	/* Instruction Completion Debug Evnt */
+#define	  DBCR_BT	0x04000000	/* Branch Taken Debug Event */
+#define	  DBCR_EDE	0x02000000	/* Exception Debug Event */
+#define	  DBCR_TDE	0x01000000	/* TRAP Debug Event */
+#define	  DBCR_FER	0x00F80000	/* First Events Remaining Mask */
+#define	  DBCR_FT	0x00040000	/* Freeze Timers on Debug Event */
+#define	  DBCR_IA1	0x00020000	/* Instr. Addr. Compare 1 Enable */
+#define	  DBCR_IA2	0x00010000	/* Instr. Addr. Compare 2 Enable */
+#define	  DBCR_D1R	0x00008000	/* Data Addr. Compare 1 Read Enable */
+#define	  DBCR_D1W	0x00004000	/* Data Addr. Compare 1 Write Enable */
+#define	  DBCR_D1S(x)	(((x) & 0x3) << 12)	/* Data Adrr. Compare 1 Size */
+#define	    DAC_BYTE	0
+#define	    DAC_HALF	1
+#define	    DAC_WORD	2
+#define	    DAC_QUAD	3
+#define	  DBCR_D2R	0x00000800	/* Data Addr. Compare 2 Read Enable */
+#define	  DBCR_D2W	0x00000400	/* Data Addr. Compare 2 Write Enable */
+#define	  DBCR_D2S(x)	(((x) & 0x3) << 8)	/* Data Addr. Compare 2 Size */
+#define	  DBCR_SBT	0x00000040	/* Second Branch Taken Debug Event */
+#define	  DBCR_SED	0x00000020	/* Second Exception Debug Event */
+#define	  DBCR_STD	0x00000010	/* Second Trap Debug Event */
+#define	  DBCR_SIA	0x00000008	/* Second IAC Enable */
+#define	  DBCR_SDA	0x00000004	/* Second DAC Enable */
+#define	  DBCR_JOI	0x00000002	/* JTAG Serial Outbound Int. Enable */
+#define	  DBCR_JII	0x00000001	/* JTAG Serial Inbound Int. Enable */
+#define	SPRN_DBCR0	0x3F2	/* Debug Control Register 0 */
+#define	SPRN_DBCR1	0x3BD	/* Debug Control Register 1 */
+#define	SPRN_DBSR	0x3F0	/* Debug Status Register */
+#define	SPRN_DCCR	0x3FA	/* Data Cache Cacheability Register */
+#define	  DCCR_NOCACHE		0	/* Noncacheable */
+#define	  DCCR_CACHE		1	/* Cacheable */
+#define	SPRN_DCMP	0x3D1	/* Data TLB Compare Register */
+#define	SPRN_DCWR	0x3BA	/* Data Cache Write-thru Register */
+#define	  DCWR_COPY		0	/* Copy-back */
+#define	  DCWR_WRITE		1	/* Write-through */
+#define	SPRN_DEAR	0x3D5	/* Data Error Address Register */
+#define	SPRN_DEC	0x016	/* Decrement Register */
+#define	SPRN_DMISS	0x3D0	/* Data TLB Miss Register */
+#define	SPRN_DSISR	0x012	/* Data Storage Interrupt Status Register */
+#define	SPRN_EAR	0x11A	/* External Address Register */
+#define	SPRN_ESR	0x3D4	/* Exception Syndrome Register */
+#define	  ESR_IMCP	0x80000000	/* Instr. Machine Check - Protection */
+#define	  ESR_IMCN	0x40000000	/* Instr. Machine Check - Non-config */
+#define	  ESR_IMCB	0x20000000	/* Instr. Machine Check - Bus error */
+#define	  ESR_IMCT	0x10000000	/* Instr. Machine Check - Timeout */
+#define	  ESR_PIL	0x08000000	/* Program Exception - Illegal */
+#define	  ESR_PPR	0x04000000	/* Program Exception - Priveleged */
+#define	  ESR_PTR	0x02000000	/* Program Exception - Trap */
+#define	  ESR_DST	0x00800000	/* Storage Exception - Data miss */
+#define	  ESR_DIZ	0x00400000	/* Storage Exception - Zone fault */
+#define	SPRN_EVPR	0x3D6	/* Exception Vector Prefix Register */
+#define	SPRN_HASH1	0x3D2	/* Primary Hash Address Register */
+#define	SPRN_HASH2	0x3D3	/* Secondary Hash Address Resgister */
+#define	SPRN_HID0	0x3F0	/* Hardware Implementation Register 0 */
+#define	  HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
+#define	  HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
+#define	  HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
+#define	  HID0_SBCLK	(1<<27)
+#define	  HID0_EICE	(1<<26)
+#define	  HID0_ECLK	(1<<25)
+#define	  HID0_PAR	(1<<24)
+#define	  HID0_DOZE	(1<<23)
+#define	  HID0_NAP	(1<<22)
+#define	  HID0_SLEEP	(1<<21)
+#define	  HID0_DPM	(1<<20)
+#define	  HID0_ICE	(1<<15)		/* Instruction Cache Enable */
+#define	  HID0_DCE	(1<<14)		/* Data Cache Enable */
+#define	  HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
+#define	  HID0_DLOCK	(1<<12)		/* Data Cache Lock */
+#define	  HID0_ICFI	(1<<11)		/* Instr. Cache Flash Invalidate */
+#define	  HID0_DCI	(1<<10)		/* Data Cache Invalidate */
+#define   HID0_SPD	(1<<9)		/* Speculative disable */
+#define   HID0_SGE	(1<<7)		/* Store Gathering Enable */
+#define	  HID0_SIED	(1<<7)		/* Serial Instr. Execution [Disable] */
+#define   HID0_BTIC	(1<<5)		/* Branch Target Instruction Cache Enable */
+#define   HID0_ABE	(1<<3)		/* Address Broadcast Enable */
+#define	  HID0_BHTE	(1<<2)		/* Branch History Table Enable */
+#define	  HID0_BTCD	(1<<1)		/* Branch target cache disable */
+#define	SPRN_MSRDORM	0x3F1	/* Hardware Implementation Register 1 */
+#define	SPRN_IABR	0x3F2	/* Instruction Address Breakpoint Register */
+#define	SPRN_NIADORM	0x3F3	/* Hardware Implementation Register 2 */
+#define	SPRN_TSC 	0x3FD	/* Thread switch control */
+#define	SPRN_TST 	0x3FC	/* Thread switch timeout */
+#define	SPRN_IAC1	0x3F4	/* Instruction Address Compare 1 */
+#define	SPRN_IAC2	0x3F5	/* Instruction Address Compare 2 */
+#define	SPRN_IBAT0L	0x211	/* Instruction BAT 0 Lower Register */
+#define	SPRN_IBAT0U	0x210	/* Instruction BAT 0 Upper Register */
+#define	SPRN_IBAT1L	0x213	/* Instruction BAT 1 Lower Register */
+#define	SPRN_IBAT1U	0x212	/* Instruction BAT 1 Upper Register */
+#define	SPRN_IBAT2L	0x215	/* Instruction BAT 2 Lower Register */
+#define	SPRN_IBAT2U	0x214	/* Instruction BAT 2 Upper Register */
+#define	SPRN_IBAT3L	0x217	/* Instruction BAT 3 Lower Register */
+#define	SPRN_IBAT3U	0x216	/* Instruction BAT 3 Upper Register */
+#define	SPRN_ICCR	0x3FB	/* Instruction Cache Cacheability Register */
+#define	  ICCR_NOCACHE		0	/* Noncacheable */
+#define	  ICCR_CACHE		1	/* Cacheable */
+#define	SPRN_ICDBDR	0x3D3	/* Instruction Cache Debug Data Register */
+#define	SPRN_ICMP	0x3D5	/* Instruction TLB Compare Register */
+#define	SPRN_ICTC	0x3FB	/* Instruction Cache Throttling Control Reg */
+#define	SPRN_IMISS	0x3D4	/* Instruction TLB Miss Register */
+#define	SPRN_IMMR	0x27E  	/* Internal Memory Map Register */
+#define	SPRN_L2CR	0x3F9	/* Level 2 Cache Control Regsiter */
+#define	SPRN_LR		0x008	/* Link Register */
+#define	SPRN_MMCR0	0x3B8	/* Monitor Mode Control Register 0 */
+#define	SPRN_MMCR1	0x3BC	/* Monitor Mode Control Register 1 */
+#define	SPRN_PBL1	0x3FC	/* Protection Bound Lower 1 */
+#define	SPRN_PBL2	0x3FE	/* Protection Bound Lower 2 */
+#define	SPRN_PBU1	0x3FD	/* Protection Bound Upper 1 */
+#define	SPRN_PBU2	0x3FF	/* Protection Bound Upper 2 */
+#define	SPRN_PID	0x3B1	/* Process ID */
+#define	SPRN_PIR	0x3FF	/* Processor Identification Register */
+#define	SPRN_PIT	0x3DB	/* Programmable Interval Timer */
+#define	SPRN_PMC1	0x3B9	/* Performance Counter Register 1 */
+#define	SPRN_PMC2	0x3BA	/* Performance Counter Register 2 */
+#define	SPRN_PMC3	0x3BD	/* Performance Counter Register 3 */
+#define	SPRN_PMC4	0x3BE	/* Performance Counter Register 4 */
+#define	SPRN_PVR	0x11F	/* Processor Version Register */
+#define	SPRN_RPA	0x3D6	/* Required Physical Address Register */
+#define	SPRN_SDA	0x3BF	/* Sampled Data Address Register */
+#define	SPRN_SDR1	0x019	/* MMU Hash Base Register */
+#define	SPRN_SGR	0x3B9	/* Storage Guarded Register */
+#define	  SGR_NORMAL		0
+#define	  SGR_GUARDED		1
+#define	SPRN_SIA	0x3BB	/* Sampled Instruction Address Register */
+#define	SPRN_SPRG0	0x110	/* Special Purpose Register General 0 */
+#define	SPRN_SPRG1	0x111	/* Special Purpose Register General 1 */
+#define	SPRN_SPRG2	0x112	/* Special Purpose Register General 2 */
+#define	SPRN_SPRG3	0x113	/* Special Purpose Register General 3 */
+#define	SPRN_SRR0	0x01A	/* Save/Restore Register 0 */
+#define	SPRN_SRR1	0x01B	/* Save/Restore Register 1 */
+#define	SPRN_SRR2	0x3DE	/* Save/Restore Register 2 */
+#define	SPRN_SRR3 	0x3DF	/* Save/Restore Register 3 */
+#define	SPRN_TBHI	0x3DC	/* Time Base High */
+#define	SPRN_TBHU	0x3CC	/* Time Base High User-mode */
+#define	SPRN_TBLO	0x3DD	/* Time Base Low */
+#define	SPRN_TBLU	0x3CD	/* Time Base Low User-mode */
+#define	SPRN_TBRL	0x10D	/* Time Base Read Lower Register */
+#define	SPRN_TBRU	0x10C	/* Time Base Read Upper Register */
+#define	SPRN_TBWL	0x11D	/* Time Base Write Lower Register */
+#define	SPRN_TBWU	0x11C	/* Time Base Write Upper Register */
+#define	SPRN_TCR	0x3DA	/* Timer Control Register */
+#define	  TCR_WP(x)		(((x)&0x3)<<30)	/* WDT Period */
+#define	    WP_2_17		0		/* 2^17 clocks */
+#define	    WP_2_21		1		/* 2^21 clocks */
+#define	    WP_2_25		2		/* 2^25 clocks */
+#define	    WP_2_29		3		/* 2^29 clocks */
+#define	  TCR_WRC(x)		(((x)&0x3)<<28)	/* WDT Reset Control */
+#define	    WRC_NONE		0		/* No reset will occur */
+#define	    WRC_CORE		1		/* Core reset will occur */
+#define	    WRC_CHIP		2		/* Chip reset will occur */
+#define	    WRC_SYSTEM		3		/* System reset will occur */
+#define	  TCR_WIE		0x08000000	/* WDT Interrupt Enable */
+#define	  TCR_PIE		0x04000000	/* PIT Interrupt Enable */
+#define	  TCR_FP(x)		(((x)&0x3)<<24)	/* FIT Period */
+#define	    FP_2_9		0		/* 2^9 clocks */
+#define	    FP_2_13		1		/* 2^13 clocks */
+#define	    FP_2_17		2		/* 2^17 clocks */
+#define	    FP_2_21		3		/* 2^21 clocks */
+#define	  TCR_FIE		0x00800000	/* FIT Interrupt Enable */
+#define	  TCR_ARE		0x00400000	/* Auto Reload Enable */
+#define	SPRN_THRM1	0x3FC	/* Thermal Management Register 1 */
+#define	  THRM1_TIN		(1<<0)
+#define	  THRM1_TIV		(1<<1)
+#define	  THRM1_THRES		(0x7f<<2)
+#define	  THRM1_TID		(1<<29)
+#define	  THRM1_TIE		(1<<30)
+#define	  THRM1_V		(1<<31)
+#define	SPRN_THRM2	0x3FD	/* Thermal Management Register 2 */
+#define	SPRN_THRM3	0x3FE	/* Thermal Management Register 3 */
+#define	  THRM3_E		(1<<31)
+#define	SPRN_TSR	0x3D8	/* Timer Status Register */
+#define	  TSR_ENW		0x80000000	/* Enable Next Watchdog */
+#define	  TSR_WIS		0x40000000	/* WDT Interrupt Status */
+#define	  TSR_WRS(x)		(((x)&0x3)<<28)	/* WDT Reset Status */
+#define	    WRS_NONE		0		/* No WDT reset occurred */
+#define	    WRS_CORE		1		/* WDT forced core reset */
+#define	    WRS_CHIP		2		/* WDT forced chip reset */
+#define	    WRS_SYSTEM		3		/* WDT forced system reset */
+#define	  TSR_PIS		0x08000000	/* PIT Interrupt Status */
+#define	  TSR_FIS		0x04000000	/* FIT Interrupt Status */
+#define	SPRN_UMMCR0	0x3A8	/* User Monitor Mode Control Register 0 */
+#define	SPRN_UMMCR1	0x3AC	/* User Monitor Mode Control Register 0 */
+#define	SPRN_UPMC1	0x3A9	/* User Performance Counter Register 1 */
+#define	SPRN_UPMC2	0x3AA	/* User Performance Counter Register 2 */
+#define	SPRN_UPMC3	0x3AD	/* User Performance Counter Register 3 */
+#define	SPRN_UPMC4	0x3AE	/* User Performance Counter Register 4 */
+#define	SPRN_USIA	0x3AB	/* User Sampled Instruction Address Register */
+#define	SPRN_XER	0x001	/* Fixed Point Exception Register */
+#define	SPRN_ZPR	0x3B0	/* Zone Protection Register */
+
+/* Short-hand versions for a number of the above SPRNs */
+
+#define	CTR	SPRN_CTR	/* Counter Register */
+#define	DAR	SPRN_DAR	/* Data Address Register */
+#define	DABR	SPRN_DABR	/* Data Address Breakpoint Register */
+#define	DBAT0L	SPRN_DBAT0L	/* Data BAT 0 Lower Register */
+#define	DBAT0U	SPRN_DBAT0U	/* Data BAT 0 Upper Register */
+#define	DBAT1L	SPRN_DBAT1L	/* Data BAT 1 Lower Register */
+#define	DBAT1U	SPRN_DBAT1U	/* Data BAT 1 Upper Register */
+#define	DBAT2L	SPRN_DBAT2L	/* Data BAT 2 Lower Register */
+#define	DBAT2U	SPRN_DBAT2U	/* Data BAT 2 Upper Register */
+#define	DBAT3L	SPRN_DBAT3L	/* Data BAT 3 Lower Register */
+#define	DBAT3U	SPRN_DBAT3U	/* Data BAT 3 Upper Register */
+#define	DCMP	SPRN_DCMP      	/* Data TLB Compare Register */
+#define	DEC	SPRN_DEC       	/* Decrement Register */
+#define	DMISS	SPRN_DMISS     	/* Data TLB Miss Register */
+#define	DSISR	SPRN_DSISR	/* Data Storage Interrupt Status Register */
+#define	EAR	SPRN_EAR       	/* External Address Register */
+#define	HASH1	SPRN_HASH1	/* Primary Hash Address Register */
+#define	HASH2	SPRN_HASH2	/* Secondary Hash Address Register */
+#define	HID0	SPRN_HID0	/* Hardware Implementation Register 0 */
+#define	MSRDORM	SPRN_MSRDORM	/* MSR Dormant Register */
+#define	NIADORM	SPRN_NIADORM	/* NIA Dormant Register */
+#define	TSC    	SPRN_TSC 	/* Thread switch control */
+#define	TST    	SPRN_TST 	/* Thread switch timeout */
+#define	IABR	SPRN_IABR      	/* Instruction Address Breakpoint Register */
+#define	IBAT0L	SPRN_IBAT0L	/* Instruction BAT 0 Lower Register */
+#define	IBAT0U	SPRN_IBAT0U	/* Instruction BAT 0 Upper Register */
+#define	IBAT1L	SPRN_IBAT1L	/* Instruction BAT 1 Lower Register */
+#define	IBAT1U	SPRN_IBAT1U	/* Instruction BAT 1 Upper Register */
+#define	IBAT2L	SPRN_IBAT2L	/* Instruction BAT 2 Lower Register */
+#define	IBAT2U	SPRN_IBAT2U	/* Instruction BAT 2 Upper Register */
+#define	IBAT3L	SPRN_IBAT3L	/* Instruction BAT 3 Lower Register */
+#define	IBAT3U	SPRN_IBAT3U	/* Instruction BAT 3 Upper Register */
+#define	ICMP	SPRN_ICMP	/* Instruction TLB Compare Register */
+#define	IMISS	SPRN_IMISS	/* Instruction TLB Miss Register */
+#define	IMMR	SPRN_IMMR      	/* PPC 860/821 Internal Memory Map Register */
+#define	L2CR	SPRN_L2CR    	/* PPC 750 L2 control register */
+#define	LR	SPRN_LR
+#define	PVR	SPRN_PVR	/* Processor Version */
+#define	PIR	SPRN_PIR	/* Processor ID */
+#define	RPA	SPRN_RPA	/* Required Physical Address Register */
+#define	SDR1	SPRN_SDR1      	/* MMU hash base register */
+#define	SPR0	SPRN_SPRG0	/* Supervisor Private Registers */
+#define	SPR1	SPRN_SPRG1
+#define	SPR2	SPRN_SPRG2
+#define	SPR3	SPRN_SPRG3
+#define	SPRG0   SPRN_SPRG0
+#define	SPRG1   SPRN_SPRG1
+#define	SPRG2   SPRN_SPRG2
+#define	SPRG3   SPRN_SPRG3
+#define	SRR0	SPRN_SRR0	/* Save and Restore Register 0 */
+#define	SRR1	SPRN_SRR1	/* Save and Restore Register 1 */
+#define	TBRL	SPRN_TBRL	/* Time Base Read Lower Register */
+#define	TBRU	SPRN_TBRU	/* Time Base Read Upper Register */
+#define	TBWL	SPRN_TBWL	/* Time Base Write Lower Register */
+#define	TBWU	SPRN_TBWU	/* Time Base Write Upper Register */
+#define ICTC	1019
+#define	THRM1	SPRN_THRM1	/* Thermal Management Register 1 */
+#define	THRM2	SPRN_THRM2	/* Thermal Management Register 2 */
+#define	THRM3	SPRN_THRM3	/* Thermal Management Register 3 */
+#define	XER	SPRN_XER
+
+
+/* Device Control Registers */
+
+#define	DCRN_BEAR	0x090	/* Bus Error Address Register */
+#define	DCRN_BESR	0x091	/* Bus Error Syndrome Register */
+#define	  BESR_DSES    	0x80000000	/* Data-Side Error Status */
+#define	  BESR_DMES	0x40000000	/* DMA Error Status */
+#define	  BESR_RWS	0x20000000	/* Read/Write Status */
+#define	  BESR_ETMASK	0x1C000000	/* Error Type */
+#define	    ET_PROT	0
+#define	    ET_PARITY	1
+#define	    ET_NCFG	2
+#define	    ET_BUSERR	4
+#define	    ET_BUSTO	6
+#define	DCRN_DMACC0	0x0C4	/* DMA Chained Count Register 0 */
+#define	DCRN_DMACC1	0x0CC	/* DMA Chained Count Register 1 */
+#define	DCRN_DMACC2	0x0D4	/* DMA Chained Count Register 2 */
+#define	DCRN_DMACC3	0x0DC    /* DMA Chained Count Register 3 */
+#define	DCRN_DMACR0	0x0C0    /* DMA Channel Control Register 0 */
+#define	DCRN_DMACR1	0x0C8    /* DMA Channel Control Register 1 */
+#define	DCRN_DMACR2	0x0D0    /* DMA Channel Control Register 2 */
+#define	DCRN_DMACR3	0x0D8    /* DMA Channel Control Register 3 */
+#define	DCRN_DMACT0	0x0C1    /* DMA Count Register 0 */
+#define	DCRN_DMACT1	0x0C9    /* DMA Count Register 1 */
+#define	DCRN_DMACT2	0x0D1    /* DMA Count Register 2 */
+#define	DCRN_DMACT3	0x0D9    /* DMA Count Register 3 */
+#define	DCRN_DMADA0	0x0C2    /* DMA Destination Address Register 0 */
+#define	DCRN_DMADA1	0x0CA    /* DMA Destination Address Register 1 */
+#define	DCRN_DMADA2	0x0D2    /* DMA Destination Address Register 2 */
+#define	DCRN_DMADA3	0x0DA    /* DMA Destination Address Register 3 */
+#define	DCRN_DMASA0	0x0C3    /* DMA Source Address Register 0 */
+#define	DCRN_DMASA1	0x0CB    /* DMA Source Address Register 1 */
+#define	DCRN_DMASA2	0x0D3    /* DMA Source Address Register 2 */
+#define	DCRN_DMASA3	0x0DB    /* DMA Source Address Register 3 */
+#define	DCRN_DMASR	0x0E0    /* DMA Status Register */
+#define	DCRN_EXIER	0x042    /* External Interrupt Enable Register */
+#define	  EXIER_CIE	0x80000000	/* Critical Interrupt Enable */
+#define	  EXIER_SRIE	0x08000000	/* Serial Port Rx Int. Enable */
+#define	  EXIER_STIE	0x04000000	/* Serial Port Tx Int. Enable */
+#define	  EXIER_JRIE	0x02000000	/* JTAG Serial Port Rx Int. Enable */
+#define	  EXIER_JTIE	0x01000000	/* JTAG Serial Port Tx Int. Enable */
+#define	  EXIER_D0IE	0x00800000	/* DMA Channel 0 Interrupt Enable */
+#define	  EXIER_D1IE	0x00400000	/* DMA Channel 1 Interrupt Enable */
+#define	  EXIER_D2IE	0x00200000	/* DMA Channel 2 Interrupt Enable */
+#define	  EXIER_D3IE	0x00100000	/* DMA Channel 3 Interrupt Enable */
+#define	  EXIER_E0IE	0x00000010	/* External Interrupt 0 Enable */
+#define	  EXIER_E1IE	0x00000008	/* External Interrupt 1 Enable */
+#define	  EXIER_E2IE	0x00000004	/* External Interrupt 2 Enable */
+#define	  EXIER_E3IE	0x00000002	/* External Interrupt 3 Enable */
+#define	  EXIER_E4IE	0x00000001	/* External Interrupt 4 Enable */
+#define	DCRN_EXISR	0x040    /* External Interrupt Status Register */
+#define	DCRN_IOCR	0x0A0    /* Input/Output Configuration Register */
+#define	  IOCR_E0TE	0x80000000
+#define	  IOCR_E0LP	0x40000000
+#define	  IOCR_E1TE	0x20000000
+#define	  IOCR_E1LP	0x10000000
+#define	  IOCR_E2TE	0x08000000
+#define	  IOCR_E2LP	0x04000000
+#define	  IOCR_E3TE	0x02000000
+#define	  IOCR_E3LP	0x01000000
+#define	  IOCR_E4TE	0x00800000
+#define	  IOCR_E4LP	0x00400000
+#define	  IOCR_EDT     	0x00080000
+#define	  IOCR_SOR     	0x00040000
+#define	  IOCR_EDO	0x00008000
+#define	  IOCR_2XC	0x00004000
+#define	  IOCR_ATC	0x00002000
+#define	  IOCR_SPD	0x00001000
+#define	  IOCR_BEM	0x00000800
+#define	  IOCR_PTD	0x00000400
+#define	  IOCR_ARE	0x00000080
+#define	  IOCR_DRC	0x00000020
+#define	  IOCR_RDM(x)	(((x) & 0x3) << 3)
+#define	  IOCR_TCS	0x00000004
+#define	  IOCR_SCS	0x00000002
+#define	  IOCR_SPC	0x00000001
+
+
+/* Processor Version Register */
+
+/* Processor Version Register (PVR) field extraction */
+
+#define	PVR_VER(pvr)  (((pvr) >>  16) & 0xFFFF)	/* Version field */
+#define	PVR_REV(pvr)  (((pvr) >>   0) & 0xFFFF)	/* Revison field */
+
+/* Processor Version Numbers */
+#define	PV_PULSAR	0x0034
+#define	PV_POWER4	0x0035
+#define	PV_ICESTAR	0x0036
+#define	PV_SSTAR	0x0037
+#define	PV_630        	0x0040
+#define	PV_630p	        0x0041
+
+/* Platforms supported by PPC64 */
+#define PLATFORM_PSERIES      0x0100
+#define PLATFORM_PSERIES_LPAR 0x0101
+#define PLATFORM_ISERIES_LPAR 0x0201
+	
+/*
+ * List of interrupt controllers.
+ */
+#define IC_INVALID    0
+#define IC_OPEN_PIC   1
+#define IC_PPC_XIC    2
+
+#define XGLUE(a,b) a##b
+#define GLUE(a,b) XGLUE(a,b)
+
+/*
+ * Begining of traceback info work for asm functions.
+ */
+#define TB_ASM		0x000C000000000000
+#define TB_GLOBALLINK	0x0000800000000000
+#define TB_IS_EPROL	0x0000400000000000
+#define TB_HAS_TBOFF	0x0000200000000000
+#define TB_INT_PROC	0x0000100000000000
+#define TB_HAS_CTL	0x0000080000000000
+#define TB_TOCLESS	0x0000040000000000
+#define TB_FP_PRESENT	0x0000020000000000
+#define TB_LOG_ABORT	0x0000010000000000
+#define TB_INT_HNDL	0x0000008000000000
+#define TB_NAME_PRESENT	0x0000004000000000
+#define TB_SAVES_CR	0x0000000200000000
+#define TB_SAVES_LR	0x0000000100000000
+#define TB_STORES_BC	0x0000000080000000
+#define TB_PARMINFO	0x000000000000FFFF
+#define TB_DEFAULT	TB_ASM | TB_HAS_TBOFF | TB_NAME_PRESENT
+
+#ifdef __ASSEMBLY__
+
+#define _GLOBAL(name) \
+	.section ".text"; \
+	.align 2 ; \
+	.globl name; \
+	.globl GLUE(.,name); \
+	.section ".opd","aw"; \
+name: \
+	.quad GLUE(.,name); \
+	.quad .TOC.@tocbase; \
+	.quad 0; \
+	.previous; \
+	.type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _STATIC(name) \
+	.section ".text"; \
+	.align 2 ; \
+	.section ".opd","aw"; \
+name: \
+	.quad GLUE(.,name); \
+	.quad .TOC.@tocbase; \
+	.quad 0; \
+	.previous; \
+	.type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _TRACEBACK(NAME) \
+GLUE(.LT,NAME): ;\
+	.long 0 ;\
+	.llong TB_DEFAULT ;\
+	.long GLUE(.LT,NAME)-GLUE(.,NAME) ;\
+	.short GLUE(GLUE(.LT,NAME),_procname_end)-GLUE(GLUE(.LT,NAME),_procname_start) ;\
+GLUE(GLUE(.LT,NAME),_procname_start): ;\
+	.ascii __stringify(NAME) ;\
+GLUE(GLUE(.LT,NAME),_procname_end):
+
+#endif /* __ASSEMBLY__ */
+
+
+/* Macros for setting and retrieving special purpose registers */
+
+#define mfmsr()		({unsigned long rval; \
+			asm volatile("mfmsr %0" : "=r" (rval)); rval;})
+
+#define mtmsrd(v)	asm volatile("mtmsrd %0" : : "r" (v))
+
+#define mfspr(rn)	({unsigned long rval; \
+			asm volatile("mfspr %0," __stringify(rn) \
+				     : "=r" (rval)); rval;})
+#define mtspr(rn, v)	asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
+
+#define mftb()		({unsigned long rval;	\
+			asm volatile("mftb %0" : "=r" (rval)); rval;})
+
+/* iSeries CTRL register (for runlatch) */
+
+#define CTRLT		0x098
+#define CTRLF		0x088
+#define RUNLATCH	0x0001
+#define RUN_FLAG	0x0002
+
+/* Macros for adjusting thread priority (hardware multi-threading) */
+#define HMT_low()	asm volatile("or 1,1,1")
+#define HMT_medium()	asm volatile("or 2,2,2")
+#define HMT_high()	asm volatile("or 3,3,3")
+
+/* Size of an exception stack frame contained in the paca. */
+#define EXC_FRAME_SIZE 64
+
+#define mfasr()		({unsigned long rval; \
+			asm volatile("mfasr %0" : "=r" (rval)); rval;})
+
+#ifndef __ASSEMBLY__
+extern int have_of;
+
+struct task_struct;
+void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
+void release_thread(struct task_struct *);
+
+/*
+ * Create a new kernel thread.
+ */
+extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/* Lazy FPU handling on uni-processor */
+extern struct task_struct *last_task_used_math;
+
+
+#ifdef __KERNEL__
+/* 64-bit user address space is 41-bits (2TBs user VM) */
+#define TASK_SIZE_USER64 (0x0000020000000000UL)
+
+/* 
+ * 32-bit user address space is 4GB - 1 page 
+ * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT
+ */
+#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE))
+
+#define TASK_SIZE ((current->thread.flags & PPC_FLAG_32BIT) ? \
+		TASK_SIZE_USER32 : TASK_SIZE_USER64)
+#endif /* __KERNEL__ */
+
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE_USER32 (STACK_TOP_USER32 / 4)
+#define TASK_UNMAPPED_BASE_USER64 (STACK_TOP_USER64 / 4)
+
+#define TASK_UNMAPPED_BASE (((current->thread.flags & PPC_FLAG_32BIT)||(ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \
+		TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+struct thread_struct {
+	unsigned long	ksp;		/* Kernel stack pointer */
+	struct pt_regs	*regs;		/* Pointer to saved register state */
+	mm_segment_t	fs;		/* for get_fs() validation */
+	void		*pgdir;		/* root of page-table tree */
+	signed long     last_syscall;
+	unsigned long	flags;
+	double		fpr[32];	/* Complete floating point set */
+	unsigned long	fpscr_pad;	/* fpr ... fpscr must be contiguous */
+	unsigned long	fpscr;		/* Floating point status */
+};
+
+#define PPC_FLAG_32BIT		0x01
+#define PPC_FLAG_RUN_LIGHT	RUN_FLAG
+
+#define INIT_SP		(sizeof(init_stack) + (unsigned long) &init_stack)
+
+#define INIT_THREAD  { \
+	INIT_SP, /* ksp */ \
+	(struct pt_regs *)INIT_SP - 1, /* regs */ \
+	KERNEL_DS, /*fs*/ \
+	swapper_pg_dir, /* pgdir */ \
+	0, /* last_syscall */ \
+	PPC_FLAG_RUN_LIGHT, /* flags */ \
+	{0}, 0, 0 \
+}
+
+/*
+ * Note: the vm_start and vm_end fields here should *not*
+ * be in kernel space.  (Could vm_end == vm_start perhaps?)
+ */
+#define IOREMAP_MMAP { &ioremap_mm, 0, 0x1000, NULL, \
+		    PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, \
+		    1, NULL, NULL }
+
+extern struct mm_struct ioremap_mm;
+
+/*
+ * Return saved PC of a blocked thread. For now, this is the "user" PC
+ */
+static inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	return (t->regs) ? t->regs->nip : 0;
+}
+
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+#define forget_segments()		do { } while (0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+#define KSTK_ESP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
+
+/*
+ * NOTE! The task struct and the stack go together
+ */
+#define THREAD_SIZE (4*PAGE_SIZE)
+struct task_struct * alloc_task_struct(void);
+        
+void free_task_struct(struct task_struct *);
+#define get_task_struct(tsk)	atomic_inc(&virt_to_page(tsk)->count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+#define cpu_relax()     do { } while (0)
+
+/*
+ * Prefetch macros.
+ */
+#define ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCHW
+#define ARCH_HAS_SPINLOCK_PREFETCH
+
+extern inline void prefetch(const void *x)
+{
+	__asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
+}
+
+extern inline void prefetchw(const void *x)
+{
+	__asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
+}
+
+#define spin_lock_prefetch(x)	prefetchw(x)
+
+#endif /* ASSEMBLY */
+
+#endif /* __ASM_PPC64_PROCESSOR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/prom.h linux/include/asm-ppc64/prom.h
--- linux.orig/include/asm-ppc64/prom.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/prom.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,202 @@
+#ifndef _PPC64_PROM_H
+#define _PPC64_PROM_H
+
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ *
+ * 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.
+ */
+
+#define PTRRELOC(x)     ((typeof(x))((unsigned long)(x) - offset))
+#define PTRUNRELOC(x)   ((typeof(x))((unsigned long)(x) + offset))
+#define RELOC(x)        (*PTRRELOC(&(x)))
+
+#define LONG_LSW(X) (((unsigned long)X) & 0xffffffff)
+#define LONG_MSW(X) (((unsigned long)X) >> 32)
+
+typedef u32 phandle;
+typedef void *ihandle;
+typedef u32 phandle32;
+typedef u32 ihandle32;
+
+extern char *prom_display_paths[];
+extern unsigned int prom_num_displays;
+
+struct address_range {
+	unsigned long space;
+	unsigned long address;
+	unsigned long size;
+};
+
+struct interrupt_info {
+	int	line;
+	int	sense;		/* +ve/-ve logic, edge or level, etc. */
+};
+
+struct pci_address {
+	u32 a_hi;
+	u32 a_mid;
+	u32 a_lo;
+};
+
+struct pci_range32 {
+	struct pci_address child_addr;
+	unsigned int  parent_addr;
+  	unsigned long size; 
+};
+
+struct pci_range64 {
+	struct pci_address child_addr;
+  	unsigned long parent_addr;
+        unsigned long size; 
+};
+
+union pci_range {
+	struct {
+		struct pci_address addr;
+		u32 phys;
+		u32 size_hi;
+	} pci32;
+	struct {
+		struct pci_address addr;
+		u32 phys_hi;
+		u32 phys_lo;
+		u32 size_hi;
+		u32 size_lo;
+	} pci64;
+};
+
+struct _of_tce_table {
+	phandle node;
+	unsigned long base;
+	unsigned long size;
+};
+
+struct reg_property {
+	unsigned long address;
+	unsigned long size;
+};
+
+struct reg_property32 {
+	unsigned int address;
+	unsigned int size;
+};
+
+struct reg_property64 {
+	unsigned long address;
+	unsigned long size;
+};
+
+struct translation_property {
+	unsigned long virt;
+	unsigned long size;
+	unsigned long phys;
+	unsigned int flags;
+};
+
+struct property {
+	char	*name;
+	int	length;
+	unsigned char *value;
+	struct property *next;
+};
+
+/* NOTE: the device_node contains PCI specific info for pci devices.
+ * This perhaps could be hung off the device_node with another struct,
+ * but for now it is directly in the node.  The phb ptr is a good
+ * indication of a real PCI node.  Other nodes leave these fields zeroed.
+ */
+struct pci_controller;
+struct TceTable;
+struct device_node {
+	char	*name;
+	char	*type;
+	phandle	node;
+	int	n_addrs;
+	struct	address_range *addrs;
+	int	n_intrs;
+	struct	interrupt_info *intrs;
+	char	*full_name;
+	int	busno;			/* for pci devices */
+	int	devfn;			/* for pci devices */
+	struct  pci_controller *phb;	/* for pci devices */
+	int	status;			/* current status of device */
+	struct	TceTable *tce_table;	/* for phb's or bridges */
+#define DN_STATUS_BIST_FAILED (1<<0)
+	struct	property *properties;
+	struct	device_node *parent;
+	struct	device_node *child;
+	struct	device_node *sibling;
+	struct	device_node *next;	/* next device of same type */
+	struct	device_node *allnext;	/* next in list of all nodes */
+};
+
+typedef u32 prom_arg_t;
+
+struct prom_args {
+        u32 service;
+        u32 nargs;
+        u32 nret;
+        prom_arg_t args[10];
+        prom_arg_t *rets;     /* Pointer to return values in args[16]. */
+};
+
+typedef struct {
+	u32  printf;	/* void (*printf)(char *, ...); */
+	u32  memdump;	/* void (*memdump)(unsigned char *, unsigned long); */
+	u32  dummy;		/* void (*dummy)(void); */
+} yaboot_debug_t;
+
+struct prom_t {
+	unsigned long entry;
+	ihandle chosen;
+	int cpu;
+	ihandle stdout;
+	ihandle disp_node;
+	struct prom_args args;
+	unsigned long version;
+	unsigned long encode_phys_size;
+	struct bi_record *bi_recs;
+#ifdef DEBUG_YABOOT
+	yaboot_debug_t *yaboot;
+#endif
+};
+
+extern struct prom_t prom;
+
+/* Prototypes */
+extern void abort(void);
+extern unsigned long prom_init(unsigned long, unsigned long, unsigned long,
+    unsigned long, unsigned long, yaboot_debug_t *);
+extern void prom_print(const char *msg);
+extern void relocate_nodes(void);
+extern void finish_device_tree(void);
+extern struct device_node *find_devices(const char *name);
+extern struct device_node *find_type_devices(const char *type);
+extern struct device_node *find_path_device(const char *path);
+extern struct device_node *find_compatible_devices(const char *type,
+						   const char *compat);
+extern struct device_node *find_pci_device_OFnode(unsigned char bus,
+	unsigned char dev_fn);
+extern struct device_node *find_all_nodes(void);
+extern int device_is_compatible(struct device_node *device, const char *);
+extern int machine_is_compatible(const char *compat);
+extern unsigned char *get_property(struct device_node *node, const char *name,
+				   int *lenp);
+extern void print_properties(struct device_node *node);
+extern int prom_n_addr_cells(struct device_node* np);
+extern int prom_n_size_cells(struct device_node* np);
+extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
+extern void prom_drawstring(const char *c);
+extern void prom_drawhex(unsigned long v);
+extern void prom_drawchar(char c);
+
+#endif /* _PPC64_PROM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ptrace.h linux/include/asm-ppc64/ptrace.h
--- linux.orig/include/asm-ppc64/ptrace.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ptrace.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,146 @@
+#ifndef _PPC64_PTRACE_H
+#define _PPC64_PTRACE_H
+
+/*
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ *
+ * this should only contain volatile regs
+ * since we can keep non-volatile in the thread_struct
+ * should set this up when only volatiles are saved
+ * by intr code.
+ *
+ * Since this is going on the stack, *CARE MUST BE TAKEN* to insure
+ * that the overall structure is a multiple of 16 bytes in length.
+ *
+ * Note that the offsets of the fields in this struct correspond with
+ * the PT_* values below.  This simplifies arch/ppc/kernel/ptrace.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.
+ */
+
+#define INIT_TASK_SIZE			4*PAGE_SIZE
+
+#ifndef __ASSEMBLY__
+#define PPC_REG unsigned long
+struct pt_regs {
+	PPC_REG gpr[32];
+	PPC_REG nip;
+	PPC_REG msr;
+	PPC_REG orig_gpr3;	/* Used for restarting system calls */
+	PPC_REG ctr;
+	PPC_REG link;
+	PPC_REG xer;
+	PPC_REG ccr;
+	PPC_REG softe;		/* Soft enabled/disabled */
+	PPC_REG trap;		/* Reason for being here */
+	PPC_REG dar;		/* Fault registers */
+	PPC_REG dsisr;
+	PPC_REG result; 	/* Result of a system call */
+};
+
+#define PPC_REG_32 unsigned int
+struct pt_regs32 {
+	PPC_REG_32 gpr[32];
+	PPC_REG_32 nip;
+	PPC_REG_32 msr;
+	PPC_REG_32 orig_gpr3;	/* Used for restarting system calls */
+	PPC_REG_32 ctr;
+	PPC_REG_32 link;
+	PPC_REG_32 xer;
+	PPC_REG_32 ccr;
+	PPC_REG_32 mq;		/* 601 only (not used at present) */
+				/* Used on APUS to hold IPL value. */
+	PPC_REG_32 trap;		/* Reason for being here */
+	PPC_REG_32 dar;		/* Fault registers */
+	PPC_REG_32 dsisr;
+	PPC_REG_32 result; 	/* Result of a system call */
+};
+
+#endif
+
+#define STACK_FRAME_OVERHEAD	112	/* size of minimum stack frame */
+
+/* Size of stack frame allocated when calling signal handler. */
+/* FIXME: What should this be on 64-bit kernel (64 for 32-bit) */
+#define __SIGNAL_FRAMESIZE	64
+#define __SIGNAL_FRAMESIZE32	64
+
+#define instruction_pointer(regs) ((regs)->nip)
+#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
+
+/*
+ * Offsets used by 'ptrace' system call interface.
+ */
+#define PT_R0	0
+#define PT_R1	1
+#define PT_R2	2
+#define PT_R3	3
+#define PT_R4	4
+#define PT_R5	5
+#define PT_R6	6
+#define PT_R7	7
+#define PT_R8	8
+#define PT_R9	9
+#define PT_R10	10
+#define PT_R11	11
+#define PT_R12	12
+#define PT_R13	13
+#define PT_R14	14
+#define PT_R15	15
+#define PT_R16	16
+#define PT_R17	17
+#define PT_R18	18
+#define PT_R19	19
+#define PT_R20	20
+#define PT_R21	21
+#define PT_R22	22
+#define PT_R23	23
+#define PT_R24	24
+#define PT_R25	25
+#define PT_R26	26
+#define PT_R27	27
+#define PT_R28	28
+#define PT_R29	29
+#define PT_R30	30
+#define PT_R31	31
+
+#define PT_NIP	32
+#define PT_MSR	33
+#ifdef __KERNEL__
+#define PT_ORIG_R3 34
+#endif
+#define PT_CTR	35
+#define PT_LNK	36
+#define PT_XER	37
+#define PT_CCR	38
+#define PT_SOFTE 39
+#define PT_RESULT 43
+
+#define PT_FPR0	48
+#ifdef __KERNEL__
+#define PT_FPSCR (PT_FPR0 + 32 + 1)	  /* each FP reg occupies 1 slot in this space */
+#define PT_FPSCR32 (PT_FPR0 + 2*32 + 1)	  /* To the 32-bit user - each FP reg occupies 2 slots in this space */
+#else
+#define PT_FPSCR (PT_FPR0 + 2*32 + 1)	/* each FP reg occupies 2 slots in this space -- Fix when 64-bit apps. */
+#endif
+
+/* Additional PTRACE requests implemented on PowerPC. */
+#define PPC_PTRACE_GETREGS	      0x99  /* Get GPRs 0 - 31 */
+#define PPC_PTRACE_SETREGS	      0x98  /* Set GPRs 0 - 31 */
+#define PPC_PTRACE_GETFPREGS	    0x97  /* Get FPRs 0 - 31 */
+#define PPC_PTRACE_SETFPREGS	    0x96  /* Set FPRs 0 - 31 */
+#define PPC_PTRACE_PEEKTEXT_3264  0x95  /* Read word at location ADDR on a 64-bit process from a 32-bit process. */
+#define PPC_PTRACE_PEEKDATA_3264  0x94  /* Read word at location ADDR on a 64-bit process from a 32-bit process. */
+#define PPC_PTRACE_POKETEXT_3264  0x93  /* Write word at location ADDR on a 64-bit process from a 32-bit process. */
+#define PPC_PTRACE_POKEDATA_3264  0x92  /* Write word at location ADDR on a 64-bit process from a 32-bit process. */
+#define PPC_PTRACE_PEEKUSR_3264   0x91  /* Read a register (specified by ADDR) out of the "user area" on a 64-bit process from a 32-bit process. */
+#define PPC_PTRACE_POKEUSR_3264   0x90  /* Write DATA into location ADDR within the "user area" on a 64-bit process from a 32-bit process. */
+
+
+#endif /* _PPC64_PTRACE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/resource.h linux/include/asm-ppc64/resource.h
--- linux.orig/include/asm-ppc64/resource.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/resource.h	2002-07-20 01:08:40.000000000 +0000
@@ -0,0 +1,53 @@
+#ifndef _PPC64_RESOURCE_H
+#define _PPC64_RESOURCE_H
+
+/*
+ * Copyright (C) 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit(?) */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+#ifdef __KERNEL__
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+
+#define INIT_RLIMITS							\
+{									\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _PPC64_RESOURCE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/rtas.h linux/include/asm-ppc64/rtas.h
--- linux.orig/include/asm-ppc64/rtas.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/rtas.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,143 @@
+#ifndef _PPC64_RTAS_H
+#define _PPC64_RTAS_H
+
+#include <linux/spinlock.h>
+
+/*
+ * Definitions for talking to the RTAS on CHRP machines.
+ *
+ * Copyright (C) 2001 Peter Bergner
+ * Copyright (C) 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+#define RTAS_UNKNOWN_SERVICE (-1)
+/*
+ * In general to call RTAS use rtas_token("string") to lookup
+ * an RTAS token for the given string (e.g. "event-scan").
+ * To actually perform the call use
+ *    ret = rtas_call(token, n_in, n_out, ...)
+ * Where n_in is the number of input parameters and
+ *       n_out is the number of output parameters
+ *
+ * If the "string" is invalid on this system, RTAS_UNKOWN_SERVICE
+ * will be returned as a token.  rtas_call() does look for this
+ * token and error out gracefully so rtas_call(rtas_token("str"), ...)
+ * may be safely used for one-shot calls to RTAS.
+ *
+ */
+
+typedef u32 rtas_arg_t;
+
+struct rtas_args {
+	u32 token;
+	u32 nargs;
+	u32 nret; 
+	rtas_arg_t args[16];
+#if 0
+	spinlock_t lock;
+#endif
+	rtas_arg_t *rets;     /* Pointer to return values in args[]. */
+};  
+
+struct rtas_t {
+	unsigned long entry;		/* physical address pointer */
+	unsigned long base;		/* physical address pointer */
+	unsigned long size;
+	spinlock_t lock;
+
+	struct device_node *dev;	/* virtual address pointer */
+};
+
+/* Event classes */
+#define INTERNAL_ERROR		0x80000000 /* set bit 0 */
+#define EPOW_WARNING		0x40000000 /* set bit 1 */
+#define POWERMGM_EVENTS		0x20000000 /* set bit 2 */
+#define HOTPLUG_EVENTS		0x10000000 /* set bit 3 */
+#define EVENT_SCAN_ALL_EVENTS	0xf0000000
+
+/* event-scan returns */
+#define SEVERITY_FATAL		0x5
+#define SEVERITY_ERROR		0x4
+#define SEVERITY_ERROR_SYNC	0x3
+#define SEVERITY_WARNING	0x2
+#define SEVERITY_EVENT		0x1
+#define SEVERITY_NO_ERROR	0x0
+#define DISP_FULLY_RECOVERED	0x0
+#define DISP_LIMITED_RECOVERY	0x1
+#define DISP_NOT_RECOVERED	0x2
+#define PART_PRESENT		0x0
+#define PART_NOT_PRESENT	0x1
+#define INITIATOR_UNKNOWN	0x0
+#define INITIATOR_CPU		0x1
+#define INITIATOR_PCI		0x2
+#define INITIATOR_ISA		0x3
+#define INITIATOR_MEMORY	0x4
+#define INITIATOR_POWERMGM	0x5
+#define TARGET_UNKNOWN		0x0
+#define TARGET_CPU		0x1
+#define TARGET_PCI		0x2
+#define TARGET_ISA		0x3
+#define TARGET_MEMORY		0x4
+#define TARGET_POWERMGM		0x5
+#define TYPE_RETRY		0x01
+#define TYPE_TCE_ERR		0x02
+#define TYPE_INTERN_DEV_FAIL	0x03
+#define TYPE_TIMEOUT		0x04
+#define TYPE_DATA_PARITY	0x05
+#define TYPE_ADDR_PARITY	0x06
+#define TYPE_CACHE_PARITY	0x07
+#define TYPE_ADDR_INVALID	0x08
+#define TYPE_ECC_UNCORR		0x09
+#define TYPE_ECC_CORR		0x0a
+#define TYPE_EPOW		0x40
+/* I don't add PowerMGM events right now, this is a different topic */ 
+#define TYPE_PMGM_POWER_SW_ON	0x60
+#define TYPE_PMGM_POWER_SW_OFF	0x61
+#define TYPE_PMGM_LID_OPEN	0x62
+#define TYPE_PMGM_LID_CLOSE	0x63
+#define TYPE_PMGM_SLEEP_BTN	0x64
+#define TYPE_PMGM_WAKE_BTN	0x65
+#define TYPE_PMGM_BATTERY_WARN	0x66
+#define TYPE_PMGM_BATTERY_CRIT	0x67
+#define TYPE_PMGM_SWITCH_TO_BAT	0x68
+#define TYPE_PMGM_SWITCH_TO_AC	0x69
+#define TYPE_PMGM_KBD_OR_MOUSE	0x6a
+#define TYPE_PMGM_ENCLOS_OPEN	0x6b
+#define TYPE_PMGM_ENCLOS_CLOSED	0x6c
+#define TYPE_PMGM_RING_INDICATE	0x6d
+#define TYPE_PMGM_LAN_ATTENTION	0x6e
+#define TYPE_PMGM_TIME_ALARM	0x6f
+#define TYPE_PMGM_CONFIG_CHANGE	0x70
+#define TYPE_PMGM_SERVICE_PROC	0x71
+
+struct rtas_error_log {
+	unsigned long version:8;		/* Architectural version */
+	unsigned long severity:3;		/* Severity level of error */
+	unsigned long disposition:2;		/* Degree of recovery */
+	unsigned long extended:1;		/* extended log present? */
+	unsigned long /* reserved */ :2;	/* Reserved for future use */
+	unsigned long initiator:4;		/* Initiator of event */
+	unsigned long target:4;			/* Target of failed operation */
+	unsigned long type:8;			/* General event or error*/
+	unsigned long extended_log_length:32;	/* length in bytes */
+	unsigned char buffer[1];		/* allocated by klimit bump */
+};
+
+extern struct rtas_t rtas;
+
+extern void enter_rtas(struct rtas_args *);
+extern int rtas_token(const char *service);
+extern long rtas_call(int token, int, int, unsigned long *, ...);
+extern void phys_call_rtas(int, int, int, ...);
+extern void phys_call_rtas_display_status(char);
+extern void call_rtas_display_status(char);
+extern void rtas_restart(char *cmd);
+extern void rtas_power_off(void);
+extern void rtas_halt(void);
+
+#endif /* _PPC64_RTAS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/rwsem.h linux/include/asm-ppc64/rwsem.h
--- linux.orig/include/asm-ppc64/rwsem.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/rwsem.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,139 @@
+/*
+ * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff
+ * in lib/rwsem.c.  Adapted largely from include/asm-i386/rwsem.h
+ * by Paul Mackerras <paulus@samba.org>.
+ *
+ * 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.
+ */
+
+#ifndef _PPC64_RWSEM_H
+#define _PPC64_RWSEM_H
+
+#ifdef __KERNEL__
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+
+/*
+ * the semaphore definition
+ */
+struct rw_semaphore {
+	/* XXX this should be able to be an atomic_t  -- paulus */
+	signed int		count;
+#define RWSEM_UNLOCKED_VALUE		0x00000000
+#define RWSEM_ACTIVE_BIAS		0x00000001
+#define RWSEM_ACTIVE_MASK		0x0000ffff
+#define RWSEM_WAITING_BIAS		(-0x00010000)
+#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+	spinlock_t		wait_lock;
+	struct list_head	wait_list;
+#if RWSEM_DEBUG
+	int			debug;
+#endif
+};
+
+/*
+ * initialisation
+ */
+#if RWSEM_DEBUG
+#define __RWSEM_DEBUG_INIT      , 0
+#else
+#define __RWSEM_DEBUG_INIT	/* */
+#endif
+
+#define __RWSEM_INITIALIZER(name) \
+	{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+	  LIST_HEAD_INIT((name).wait_list) \
+	  __RWSEM_DEBUG_INIT }
+
+#define DECLARE_RWSEM(name)		\
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
+
+static inline void init_rwsem(struct rw_semaphore *sem)
+{
+	sem->count = RWSEM_UNLOCKED_VALUE;
+	spin_lock_init(&sem->wait_lock);
+	INIT_LIST_HEAD(&sem->wait_list);
+#if RWSEM_DEBUG
+	sem->debug = 0;
+#endif
+}
+
+/*
+ * lock for reading
+ */
+static inline void __down_read(struct rw_semaphore *sem)
+{
+	if (atomic_inc_return((atomic_t *)(&sem->count)) >= 0)
+		smp_wmb();
+	else
+		rwsem_down_read_failed(sem);
+}
+
+/*
+ * lock for writing
+ */
+static inline void __down_write(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+				(atomic_t *)(&sem->count));
+	if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
+		smp_wmb();
+	else
+		rwsem_down_write_failed(sem);
+}
+
+/*
+ * unlock after reading
+ */
+static inline void __up_read(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	smp_wmb();
+	tmp = atomic_dec_return((atomic_t *)(&sem->count));
+	if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
+		rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void __up_write(struct rw_semaphore *sem)
+{
+	smp_wmb();
+	if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+			      (atomic_t *)(&sem->count)) < 0)
+		rwsem_wake(sem);
+}
+
+/*
+ * implement atomic add functionality
+ */
+static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+{
+	atomic_add(delta, (atomic_t *)(&sem->count));
+}
+
+/*
+ * implement exchange and add functionality
+ */
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+{
+	smp_mb();
+	return atomic_add_return(delta, (atomic_t *)(&sem->count));
+}
+
+#endif /* __KERNEL__ */
+#endif /* _PPC_RWSEM_XADD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/scatterlist.h linux/include/asm-ppc64/scatterlist.h
--- linux.orig/include/asm-ppc64/scatterlist.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/scatterlist.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,29 @@
+#ifndef _PPC64_SCATTERLIST_H
+#define _PPC64_SCATTERLIST_H
+
+/*
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+#include <asm/dma.h>
+
+struct scatterlist {
+	char *address;		/* Virtual addr data is to be transferred to */
+	struct page *page;	/* Location for highmem page, if any */
+	unsigned int offset;	/* for highmem, page offset */
+	unsigned int length;
+
+	/* For TCE support */
+	u32 dma_address;
+	u32 dma_length;
+};
+
+#define ISA_DMA_THRESHOLD	(~0UL)
+
+#endif /* !(_PPC64_SCATTERLIST_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/segment.h linux/include/asm-ppc64/segment.h
--- linux.orig/include/asm-ppc64/segment.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/segment.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,6 @@
+#ifndef __PPC64_SEGMENT_H
+#define __PPC64_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif /* __PPC64_SEGMENT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/semaphore.h linux/include/asm-ppc64/semaphore.h
--- linux.orig/include/asm-ppc64/semaphore.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/semaphore.h	2002-07-20 01:08:23.000000000 +0000
@@ -0,0 +1,135 @@
+#ifndef _PPC64_SEMAPHORE_H
+#define _PPC64_SEMAPHORE_H
+
+/*
+ * Swiped from asm-sparc/semaphore.h and modified
+ * -- Cort (cort@cs.nmt.edu)
+ *
+ * Stole some rw spinlock-based semaphore stuff from asm-alpha/semaphore.h
+ * -- Ani Joshi (ajoshi@unixbox.com)
+ *
+ * Remove spinlock-based RW semaphores; RW semaphore definitions are
+ * now in rwsem.h and we use the the generic lib/rwsem.c implementation.
+ * Rework semaphores to use atomic_dec_if_positive.
+ * -- Paul Mackerras (paulus@samba.org)
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+struct semaphore {
+	/*
+	 * Note that any negative value of count is equivalent to 0,
+	 * but additionally indicates that some process(es) might be
+	 * sleeping on `wait'.
+	 */
+	atomic_t count;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name, count) \
+	{ ATOMIC_INIT(count), \
+	  __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	  __SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name, 1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC(name, 1)
+#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC(name, 0)
+
+static inline void sema_init (struct semaphore *sem, int val)
+{
+	atomic_set(&sem->count, val);
+	init_waitqueue_head(&sem->wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (long)&sem->__magic;
+#endif
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+extern void __down(struct semaphore * sem);
+extern int  __down_interruptible(struct semaphore * sem);
+extern void __up(struct semaphore * sem);
+
+extern inline void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	/*
+	 * Try to get the semaphore, take the slow path if we fail.
+	 */
+	if (atomic_dec_return(&sem->count) < 0)
+		__down(sem);
+	smp_wmb();
+}
+
+extern inline int down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	if (atomic_dec_return(&sem->count) < 0)
+		ret = __down_interruptible(sem);
+	smp_wmb();
+	return ret;
+}
+
+extern inline int down_trylock(struct semaphore * sem)
+{
+	int ret;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	ret = atomic_dec_if_positive(&sem->count) < 0;
+	smp_wmb();
+	return ret;
+}
+
+extern inline void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	smp_wmb();
+	if (atomic_inc_return(&sem->count) <= 0)
+		__up(sem);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* !(_PPC64_SEMAPHORE_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/sembuf.h linux/include/asm-ppc64/sembuf.h
--- linux.orig/include/asm-ppc64/sembuf.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/sembuf.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,27 @@
+#ifndef _PPC64_SEMBUF_H
+#define _PPC64_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for PPC architecture.
+ *
+ *
+ * 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.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;	/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;	/* last semop time */
+	__kernel_time_t	sem_ctime;	/* last change time */
+	unsigned long	sem_nsems;	/* no. of semaphores in array */
+
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif /* _PPC64_SEMBUF_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/serial.h linux/include/asm-ppc64/serial.h
--- linux.orig/include/asm-ppc64/serial.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/serial.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,128 @@
+/*
+ * include/asm-ppc/serial.h
+ */
+
+#include <linux/config.h>
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ *
+ * 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.
+ */
+#define BASE_BAUD ( 1843200 / 16 )
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define RS_TABLE_SIZE  64
+#else
+#define RS_TABLE_SIZE  4
+#endif
+
+/* Standard COM flags (except for COM4, because of the 8514 problem) */
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
+#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+#else
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+#endif
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define FOURPORT_FLAGS ASYNC_FOURPORT
+#define ACCENT_FLAGS 0
+#define BOCA_FLAGS 0
+#define HUB6_FLAGS 0
+#endif
+	
+/*
+ * The following define the access methods for the HUB6 card. All
+ * access is through two ports for all 24 possible chips. The card is
+ * selected through the high 2 bits, the port on that card with the
+ * "middle" 3 bits, and the register on that port with the bottom
+ * 3 bits.
+ *
+ * While the access port and interrupt is configurable, the default
+ * port locations are 0x302 for the port control register, and 0x303
+ * for the data read/write register. Normally, the interrupt is at irq3
+ * but can be anything from 3 to 7 inclusive. Note that using 3 will
+ * require disabling com2.
+ */
+
+#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
+
+#define STD_SERIAL_PORT_DEFNS			\
+	/* UART CLK   PORT IRQ     FLAGS        */			\
+	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
+	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
+	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
+	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
+
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define EXTRA_SERIAL_PORT_DEFNS			\
+	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
+	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
+	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
+	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
+	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
+	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
+	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
+	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
+	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
+	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
+	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
+	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
+	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
+	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
+	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
+	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
+	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
+	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
+	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
+	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
+	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
+	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
+	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
+	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
+	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
+	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
+	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
+	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
+#else
+#define EXTRA_SERIAL_PORT_DEFNS
+#endif
+
+/* You can have up to four HUB6's in the system, but I've only
+ * included two cards here for a total of twelve ports.
+ */
+#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
+#define HUB6_SERIAL_PORT_DFNS		\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
+	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
+#else
+#define HUB6_SERIAL_PORT_DFNS
+#endif
+
+#define MCA_SERIAL_PORT_DFNS
+
+#define SERIAL_PORT_DFNS		\
+	STD_SERIAL_PORT_DEFNS		\
+	EXTRA_SERIAL_PORT_DEFNS		\
+	HUB6_SERIAL_PORT_DFNS		\
+	MCA_SERIAL_PORT_DFNS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/setup.h linux/include/asm-ppc64/setup.h
--- linux.orig/include/asm-ppc64/setup.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/setup.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,6 @@
+#ifndef _PPC_SETUP_H
+#define _PPC_SETUP_H
+
+/* This is a place holder include */
+
+#endif /* _PPC_SETUP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/shmbuf.h linux/include/asm-ppc64/shmbuf.h
--- linux.orig/include/asm-ppc64/shmbuf.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/shmbuf.h	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,43 @@
+#ifndef _PPC64_SHMBUF_H
+#define _PPC64_SHMBUF_H
+
+/* 
+ * The shmid64_ds structure for PPC64 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ *
+ * 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.
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	__kernel_time_t		shm_ctime;	/* last change time */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _PPC64_SHMBUF_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/shmparam.h linux/include/asm-ppc64/shmparam.h
--- linux.orig/include/asm-ppc64/shmparam.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/shmparam.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,13 @@
+#ifndef _PPC64_SHMPARAM_H
+#define _PPC64_SHMPARAM_H
+
+/*
+ * 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.
+ */
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _PPC64_SHMPARAM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/sigcontext.h linux/include/asm-ppc64/sigcontext.h
--- linux.orig/include/asm-ppc64/sigcontext.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/sigcontext.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,21 @@
+#ifndef _ASM_PPC64_SIGCONTEXT_H
+#define _ASM_PPC64_SIGCONTEXT_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/ptrace.h>
+
+struct sigcontext_struct {
+	unsigned long	_unused[4];
+	int		signal;
+	unsigned long	handler;
+	unsigned long	oldmask;
+	struct pt_regs 	*regs;
+};
+
+#endif /* _ASM_PPC64_SIGCONTEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/siginfo.h linux/include/asm-ppc64/siginfo.h
--- linux.orig/include/asm-ppc64/siginfo.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/siginfo.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,240 @@
+#ifndef _PPC64_SIGINFO_H
+#define _PPC64_SIGINFO_H
+
+/* Copied from i386 from alpha. */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			uid_t _uid;		/* sender's uid */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#define si_uid		_sifields._kill._uid
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+#define SI_DETHREAD	-7		/* sent by execve() killing subsidiary threads */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif /* _PPC64_SIGINFO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/signal.h linux/include/asm-ppc64/signal.h
--- linux.orig/include/asm-ppc64/signal.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/signal.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,146 @@
+#ifndef _ASMPPC64_SIGNAL_H
+#define _ASMPPC64_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#define _NSIG		64
+#define _NSIG_BPW	64
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#endif /* _ASMPPC64_SIGNAL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/smp.h linux/include/asm-ppc64/smp.h
--- linux.orig/include/asm-ppc64/smp.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/smp.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,72 @@
+/* 
+ * smp.h: PPC64 specific SMP code.
+ *
+ * Original was a copy of sparc smp.h.  Now heavily modified
+ * for PPC.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996-2001 Cort Dougan <cort@fsmlabs.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.
+ */
+
+#ifdef __KERNEL__
+#ifndef _PPC64_SMP_H
+#define _PPC64_SMP_H
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#ifdef CONFIG_SMP
+
+#ifndef __ASSEMBLY__
+
+#include <asm/paca.h>
+
+struct current_set_struct {
+	struct task_struct *task;
+	unsigned long *sp_real;
+};
+
+extern unsigned long cpu_online_map;
+
+extern void smp_message_pass(int target, int msg, unsigned long data, int wait);
+extern void smp_store_cpu_info(int id);
+extern void smp_send_tlb_invalidate(int);
+extern void smp_send_xmon_break(int cpu);
+struct pt_regs;
+extern void smp_message_recv(int, struct pt_regs *);
+
+#define NO_PROC_ID		0xFF            /* No processor magic marker */
+#define PROC_CHANGE_PENALTY	20
+
+/* 1 to 1 mapping on PPC -- Cort */
+#define cpu_logical_map(cpu) (cpu)
+#define cpu_number_map(x) (x)
+extern volatile unsigned long cpu_callin_map[NR_CPUS];
+
+#define smp_processor_id() (get_paca()->xPacaIndex)
+#define hard_smp_processor_id() (get_paca()->xHwProcNum)
+#define get_hard_smp_processor_id(CPU) (paca[(CPU)].xHwProcNum)
+
+
+
+/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
+ *
+ * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up
+ * in /proc/interrupts will be wrong!!! --Troy */
+#define PPC_MSG_CALL_FUNCTION   0
+#define PPC_MSG_RESCHEDULE      1
+#define PPC_MSG_INVALIDATE_TLB  2
+#define PPC_MSG_XMON_BREAK      3
+
+void smp_init_iSeries(void);
+void smp_init_pSeries(void);
+
+#endif /* __ASSEMBLY__ */
+#endif /* !(CONFIG_SMP) */
+#endif /* !(_PPC64_SMP_H) */
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/smplock.h linux/include/asm-ppc64/smplock.h
--- linux.orig/include/asm-ppc64/smplock.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/smplock.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,56 @@
+/*
+ * <asm/smplock.h>
+ *
+ * Default SMP lock implementation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+extern spinlock_t kernel_flag;
+
+#define kernel_locked()		spin_is_locked(&kernel_flag)
+
+/*
+ * Release global kernel lock and global interrupt lock
+ */
+#define release_kernel_lock(task, cpu) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_unlock(&kernel_flag); \
+	release_irqlock(cpu); \
+	__sti(); \
+} while (0)
+
+/*
+ * Re-acquire the kernel lock
+ */
+#define reacquire_kernel_lock(task) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_lock(&kernel_flag); \
+} while (0)
+
+
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously,
+ * so we only need to worry about other
+ * CPU's.
+ */
+extern __inline__ void lock_kernel(void)
+{
+	if (!++current->lock_depth)
+		spin_lock(&kernel_flag);
+}
+
+extern __inline__ void unlock_kernel(void)
+{
+	if (--current->lock_depth < 0)
+		spin_unlock(&kernel_flag);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/socket.h linux/include/asm-ppc64/socket.h
--- linux.orig/include/asm-ppc64/socket.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/socket.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,71 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_RCVLOWAT	16
+#define SO_SNDLOWAT	17
+#define SO_RCVTIMEO	18
+#define SO_SNDTIMEO	19
+#define SO_PASSCRED	20
+#define SO_PEERCRED	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER	26
+#define SO_DETACH_FILTER	27
+
+#define SO_PEERNAME		28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN           30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* _ASM_SOCKET_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/sockios.h linux/include/asm-ppc64/sockios.h
--- linux.orig/include/asm-ppc64/sockios.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/sockios.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,19 @@
+#ifndef _ASM_PPC64_SOCKIOS_H
+#define _ASM_PPC64_SOCKIOS_H
+
+/*
+ * 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.
+ */
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* _ASM_PPC64_SOCKIOS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/softirq.h linux/include/asm-ppc64/softirq.h
--- linux.orig/include/asm-ppc64/softirq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/softirq.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,29 @@
+#ifndef __ASM_SOFTIRQ_H
+#define __ASM_SOFTIRQ_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+
+#define local_bh_disable()	do { local_bh_count(smp_processor_id())++; barrier(); } while (0)
+#define __local_bh_enable()	do { barrier(); local_bh_count(smp_processor_id())--; } while (0)
+
+#define local_bh_enable()  \
+do {                                                    \
+        if (!--local_bh_count(smp_processor_id())       \
+            && softirq_pending(smp_processor_id())) {   \
+                do_softirq();                           \
+        }                                               \
+} while (0)
+
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#endif	/* __ASM_SOFTIRQ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/spinlock.h linux/include/asm-ppc64/spinlock.h
--- linux.orig/include/asm-ppc64/spinlock.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/spinlock.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,215 @@
+#ifndef __ASM_SPINLOCK_H
+#define __ASM_SPINLOCK_H
+
+/*
+ * Simple spin lock operations.  
+ *
+ * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * Type of int is used as a full 64b word is not necessary.
+ *
+ * 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.
+ */
+typedef struct {
+	volatile unsigned int lock;
+} spinlock_t;
+
+#ifdef __KERNEL__
+#define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
+
+#define spin_is_locked(x)	((x)->lock != 0)
+
+static __inline__ int spin_trylock(spinlock_t *lock)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+"1:	lwarx		%0,0,%1		# spin_trylock\n\
+	cmpwi		0,%0,0\n\
+	li		%0,0\n\
+	bne-		2f\n\
+	li		%0,1\n\
+	stwcx.		%0,0,%1\n\
+	bne-		1b\n\
+	isync\n\
+2:"	: "=&r"(tmp)
+	: "r"(&lock->lock)
+	: "cr0", "memory");
+
+	return tmp;
+}
+
+static __inline__ void spin_lock(spinlock_t *lock)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	"b		2f		# spin_lock\n\
+1:	or		1,1,1		# spin at low priority\n\
+	lwzx		%0,0,%1\n\
+	cmpwi		0,%0,0\n\
+	bne+		1b\n\
+	or		2,2,2		# back to medium priority\n\
+2:	lwarx		%0,0,%1\n\
+	cmpwi		0,%0,0\n\
+	bne-		1b\n\
+	stwcx.		%2,0,%1\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp)
+	: "r"(&lock->lock), "r"(1)
+	: "cr0", "memory");
+}
+
+static __inline__ void spin_unlock(spinlock_t *lock)
+{
+	__asm__ __volatile__("lwsync	# spin_unlock": : :"memory");
+	lock->lock = 0;
+}
+
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+typedef struct {
+	volatile signed int lock;
+} rwlock_t;
+
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
+
+static __inline__ int read_trylock(rwlock_t *rw)
+{
+	unsigned int tmp;
+	unsigned int ret;
+
+	__asm__ __volatile__(
+"1:	lwarx		%0,0,%2		# read_trylock\n\
+	li		%1,0\n\
+	extsw		%0,%0\n\
+	addic.		%0,%0,1\n\
+	ble-		2f\n\
+	stwcx.		%0,0,%2\n\
+	bne-		1b\n\
+	li		%1,1\n\
+	isync\n\
+2:"	: "=&r"(tmp), "=&r"(ret)
+	: "r"(&rw->lock)
+	: "cr0", "memory");
+
+	return ret;
+}
+
+static __inline__ void read_lock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	"b		2f		# read_lock\n\
+1:	or		1,1,1		# spin at low priority\n\
+	lwax		%0,0,%1\n\
+	cmpwi		0,%0,0\n\
+	blt+		1b\n\
+	or		2,2,2		# back to medium priority\n\
+2:	lwarx		%0,0,%1\n\
+	extsw		%0,%0\n\
+	addic.		%0,%0,1\n\
+	ble-		1b\n\
+	stwcx.		%0,0,%1\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp)
+	: "r"(&rw->lock)
+	: "cr0", "memory");
+}
+
+static __inline__ void read_unlock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	"lwsync				# read_unlock\n\
+1:	lwarx		%0,0,%1\n\
+	addic		%0,%0,-1\n\
+	stwcx.		%0,0,%1\n\
+	bne-		1b"
+	: "=&r"(tmp)
+	: "r"(&rw->lock)
+	: "cr0", "memory");
+}
+
+static __inline__ int write_trylock(rwlock_t *rw)
+{
+	unsigned int tmp;
+	unsigned int ret;
+
+	__asm__ __volatile__(
+"1:	lwarx		%0,0,%2		# write_trylock\n\
+	cmpwi		0,%0,0\n\
+	li		%1,0\n\
+	bne-		2f\n\
+	stwcx.		%3,0,%2\n\
+	bne-		1b\n\
+	li		%1,1\n\
+	isync\n\
+2:"	: "=&r"(tmp), "=&r"(ret)
+	: "r"(&rw->lock), "r"(-1)
+	: "cr0", "memory");
+
+	return ret;
+}
+
+static __inline__ void write_lock(rwlock_t *rw)
+{
+	unsigned int tmp;
+
+	__asm__ __volatile__(
+	"b		2f		# write_lock\n\
+1:	or		1,1,1		# spin at low priority\n\
+	lwax		%0,0,%1\n\
+	cmpwi		0,%0,0\n\
+	bne+		1b\n\
+	or		2,2,2		# back to medium priority\n\
+2:	lwarx		%0,0,%1\n\
+	cmpwi		0,%0,0\n\
+	bne-		1b\n\
+	stwcx.		%2,0,%1\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp)
+	: "r"(&rw->lock), "r"(-1)
+	: "cr0", "memory");
+}
+
+static __inline__ void write_unlock(rwlock_t *rw)
+{
+	__asm__ __volatile__("lwsync		# write_unlock": : :"memory");
+	rw->lock = 0;
+}
+
+static __inline__ int is_read_locked(rwlock_t *rw)
+{
+	return rw->lock > 0;
+}
+
+static __inline__ int is_write_locked(rwlock_t *rw)
+{
+	return rw->lock < 0;
+}
+
+#define spin_lock_init(x)      do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
+#define spin_unlock_wait(x)    do { barrier(); } while(spin_is_locked(x))
+
+#define rwlock_init(x)         do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SPINLOCK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/stat.h linux/include/asm-ppc64/stat.h
--- linux.orig/include/asm-ppc64/stat.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/stat.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,71 @@
+#ifndef _PPC64_STAT_H
+#define _PPC64_STAT_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	dev_t		st_dev;
+	ino_t		st_ino;
+	mode_t		st_mode;
+	nlink_t		st_nlink;
+	uid_t 		st_uid;
+	gid_t 		st_gid;
+	dev_t		st_rdev;
+	off_t		st_size;
+	unsigned long  	st_blksize;
+	unsigned long  	st_blocks;
+	unsigned long  	st_atime;
+	unsigned long  	__unused1;
+	unsigned long  	st_mtime;
+	unsigned long  	__unused2;
+	unsigned long  	st_ctime;
+	unsigned long  	__unused3;
+	unsigned long  	__unused4;
+	unsigned long  	__unused5;
+};
+
+/* This matches struct stat64 in glibc2.1. */
+struct stat64 {
+	unsigned long st_dev; 		/* Device.  */
+	unsigned long st_ino;		/* File serial number.  */
+	unsigned int st_mode;		/* File mode.  */
+	unsigned int st_nlink;		/* Link count.  */
+	unsigned int st_uid;		/* User ID of the file's owner.  */
+	unsigned int st_gid;		/* Group ID of the file's group. */
+	unsigned long st_rdev; 		/* Device number, if device.  */
+	unsigned short __pad2;
+	long st_size;			/* Size of file, in bytes.  */
+	int  st_blksize;		/* Optimal block size for I/O.  */
+
+	long st_blocks;			/* Number 512-byte blocks allocated. */
+	int   st_atime;			/* Time of last access.  */
+	unsigned int  __unused1;
+	int   st_mtime;			/* Time of last modification.  */
+	unsigned int  __unused2;
+	int   st_ctime;			/* Time of last status change.  */
+	unsigned int   __unused3;
+	unsigned int   __unused4;
+	unsigned int   __unused5;
+};
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/statfs.h linux/include/asm-ppc64/statfs.h
--- linux.orig/include/asm-ppc64/statfs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/statfs.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,29 @@
+#ifndef _PPC64_STATFS_H
+#define _PPC64_STATFS_H
+
+/*
+ * 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.
+ */
+
+#ifndef __KERNEL_STRICT_NAMES
+#include <linux/types.h>
+typedef __kernel_fsid_t	fsid_t;
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif  /* _PPC64_STATFS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/string.h linux/include/asm-ppc64/string.h
--- linux.orig/include/asm-ppc64/string.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/string.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,36 @@
+#ifndef _PPC64_STRING_H_
+#define _PPC64_STRING_H_
+
+/*
+ * 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.
+ */
+
+#define __HAVE_ARCH_STRCPY
+#define __HAVE_ARCH_STRNCPY
+#define __HAVE_ARCH_STRLEN
+#define __HAVE_ARCH_STRCMP
+#define __HAVE_ARCH_STRCAT
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMCMP
+#define __HAVE_ARCH_MEMCHR
+
+extern int strcasecmp(const char *, const char *);
+extern int strncasecmp(const char *, const char *, int);
+extern char * strcpy(char *,const char *);
+extern char * strncpy(char *,const char *, __kernel_size_t);
+extern __kernel_size_t strlen(const char *);
+extern int strcmp(const char *,const char *);
+extern char * strcat(char *, const char *);
+extern void * memset(void *,int,__kernel_size_t);
+extern void * memcpy(void *,const void *,__kernel_size_t);
+extern void * memmove(void *,const void *,__kernel_size_t);
+extern int memcmp(const void *,const void *,__kernel_size_t);
+extern void * memchr(const void *,int,__kernel_size_t);
+
+#endif /* _PPC64_STRING_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/system.h linux/include/asm-ppc64/system.h
--- linux.orig/include/asm-ppc64/system.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/system.h	2002-07-20 01:08:32.000000000 +0000
@@ -0,0 +1,274 @@
+#ifndef __PPC64_SYSTEM_H
+#define __PPC64_SYSTEM_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kdev_t.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/hw_irq.h>
+#include <asm/memory.h>
+
+/*
+ * System defines.
+ */
+#define KERNEL_START_PHYS	0x800000 
+#define KERNEL_START	        (PAGE_OFFSET+KERNEL_START_PHYS)
+#define START_ADDR	        (PAGE_OFFSET+KERNEL_START_PHYS+0x00000)
+
+/*
+ * Memory barrier.
+ * The sync instruction guarantees that all memory accesses initiated
+ * by this processor have been performed (with respect to all other
+ * mechanisms that access memory).  The eieio instruction is a barrier
+ * providing an ordering (separately) for (a) cacheable stores and (b)
+ * loads and stores to non-cacheable memory (e.g. I/O devices).
+ *
+ * mb() prevents loads and stores being reordered across this point.
+ * rmb() prevents loads being reordered across this point.
+ * wmb() prevents stores being reordered across this point.
+ *
+ * We can use the eieio instruction for wmb, but since it doesn't
+ * give any ordering guarantees about loads, we have to use the
+ * stronger but slower sync instruction for mb and rmb.
+ */
+#define mb()   __asm__ __volatile__ ("sync" : : : "memory")
+#define rmb()  __asm__ __volatile__ ("lwsync" : : : "memory")
+#define wmb()  __asm__ __volatile__ ("eieio" : : : "memory")
+
+#define set_mb(var, value)	do { var = value; mb(); } while (0)
+#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#else
+#define smp_mb()	__asm__ __volatile__("": : :"memory")
+#define smp_rmb()	__asm__ __volatile__("": : :"memory")
+#define smp_wmb()	__asm__ __volatile__("": : :"memory")
+#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_XMON
+extern void xmon_irq(int, void *, struct pt_regs *);
+extern void xmon(struct pt_regs *excp);
+#endif
+
+extern void print_backtrace(unsigned long *);
+extern void show_regs(struct pt_regs * regs);
+extern void flush_instruction_cache(void);
+extern void hard_reset_now(void);
+extern void poweroff_now(void);
+extern int _get_PVR(void);
+extern long _get_L2CR(void);
+extern void _set_L2CR(unsigned long);
+extern void via_cuda_init(void);
+extern void pmac_nvram_init(void);
+extern void pmac_find_display(void);
+extern void giveup_fpu(struct task_struct *);
+extern void enable_kernel_fp(void);
+extern void giveup_altivec(struct task_struct *);
+extern void load_up_altivec(struct task_struct *);
+extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
+extern void cvt_df(double *from, float *to, unsigned long *fpscr);
+extern int abs(int);
+extern void cacheable_memzero(void *p, unsigned int nb);
+
+struct device_node;
+
+struct task_struct;
+#define prepare_to_switch()	do { } while(0)
+#define switch_to(prev,next,last) _switch_to((prev),(next),&(last))
+extern void _switch_to(struct task_struct *, struct task_struct *,
+		       struct task_struct **);
+
+struct thread_struct;
+extern struct task_struct *_switch(struct thread_struct *prev,
+				   struct thread_struct *next);
+
+struct pt_regs;
+extern void dump_regs(struct pt_regs *);
+
+#ifndef CONFIG_SMP
+
+#define cli()	__cli()
+#define sti()	__sti()
+#define save_flags(flags)	__save_flags(flags)
+#define restore_flags(flags)	__restore_flags(flags)
+#define save_and_cli(flags)	__save_and_cli(flags)
+
+#else /* CONFIG_SMP */
+
+extern void __global_cli(void);
+extern void __global_sti(void);
+extern unsigned long __global_save_flags(void);
+extern void __global_restore_flags(unsigned long);
+#define cli() __global_cli()
+#define sti() __global_sti()
+#define save_flags(x) ((x)=__global_save_flags())
+#define restore_flags(x) __global_restore_flags(x)
+
+#endif /* !CONFIG_SMP */
+
+#define local_irq_disable()		__cli()
+#define local_irq_enable()		__sti()
+#define local_irq_save(flags)		__save_and_cli(flags)
+#define local_irq_restore(flags)	__restore_flags(flags)
+
+static __inline__ int __is_processor(unsigned long pv)
+{
+      unsigned long pvr;
+      asm volatile("mfspr %0, 0x11F" : "=r" (pvr)); 
+      return(PVR_VER(pvr) == pv);
+}
+
+/*
+ * Atomic exchange
+ *
+ * Changes the memory location '*ptr' to be val and returns
+ * the previous value stored there.
+ *
+ * Inline asm pulled from arch/ppc/kernel/misc.S so ppc64
+ * is more like most of the other architectures.
+ */
+static __inline__ unsigned long
+__xchg_u32(volatile int *m, unsigned long val)
+{
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+	EIEIO_ON_SMP
+"1:	lwarx %0,0,%3		# __xchg_u32\n\
+	stwcx. %2,0,%3\n\
+2:	bne- 1b"
+	ISYNC_ON_SMP
+ 	: "=&r" (dummy), "=m" (*m)
+	: "r" (val), "r" (m)
+	: "cc", "memory");
+
+	return (dummy);
+}
+
+static __inline__ unsigned long
+__xchg_u64(volatile long *m, unsigned long val)
+{
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+	EIEIO_ON_SMP
+"1:	ldarx %0,0,%3		# __xchg_u64\n\
+	stdcx. %2,0,%3\n\
+2:	bne- 1b"
+	ISYNC_ON_SMP
+	: "=&r" (dummy), "=m" (*m)
+	: "r" (val), "r" (m)
+	: "cc", "memory");
+
+	return (dummy);
+}
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid xchg().
+ */
+extern void __xchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__xchg(volatile void *ptr, unsigned long x, int size)
+{
+	switch (size) {
+	case 4:
+		return __xchg_u32(ptr, x);
+	case 8:
+		return __xchg_u64(ptr, x);
+	}
+	__xchg_called_with_bad_pointer();
+	return x;
+}
+
+#define xchg(ptr,x)							     \
+  ({									     \
+     __typeof__(*(ptr)) _x_ = (x);					     \
+     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
+  })
+
+#define tas(ptr) (xchg((ptr),1))
+
+#define __HAVE_ARCH_CMPXCHG	1
+
+static __inline__ unsigned long
+__cmpxchg_u32(volatile int *p, int old, int new)
+{
+	int prev;
+
+	__asm__ __volatile__ (
+	EIEIO_ON_SMP
+"1:	lwarx	%0,0,%2		# __cmpxchg_u32\n\
+	cmpw	0,%0,%3\n\
+	bne-	2f\n\
+	stwcx.	%4,0,%2\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	"\n\
+2:"
+	: "=&r" (prev), "=m" (*p)
+	: "r" (p), "r" (old), "r" (new), "m" (*p)
+	: "cc", "memory");
+
+	return prev;
+}
+
+static __inline__ unsigned long
+__cmpxchg_u64(volatile long *p, unsigned long old, unsigned long new)
+{
+	int prev;
+
+	__asm__ __volatile__ (
+	EIEIO_ON_SMP
+"1:	ldarx	%0,0,%2		# __cmpxchg_u64\n\
+	cmpd	0,%0,%3\n\
+	bne-	2f\n\
+	stdcx.	%4,0,%2\n\
+	bne-	1b"
+	ISYNC_ON_SMP
+	"\n\
+2:"
+	: "=&r" (prev), "=m" (*p)
+	: "r" (p), "r" (old), "r" (new), "m" (*p)
+	: "cc", "memory");
+
+	return prev;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid cmpxchg().  */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+	switch (size) {
+	case 4:
+		return __cmpxchg_u32(ptr, old, new);
+	case 8:
+		return __cmpxchg_u64(ptr, old, new);
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
+
+#define cmpxchg(ptr,o,n)						 \
+  ({									 \
+     __typeof__(*(ptr)) _o_ = (o);					 \
+     __typeof__(*(ptr)) _n_ = (n);					 \
+     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		 \
+				    (unsigned long)_n_, sizeof(*(ptr))); \
+  })
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/termbits.h linux/include/asm-ppc64/termbits.h
--- linux.orig/include/asm-ppc64/termbits.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/termbits.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,192 @@
+#ifndef _PPC64_TERMBITS_H
+#define _PPC64_TERMBITS_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+/*
+ * termios type and macro definitions.  Be careful about adding stuff
+ * to this file since it's used in GNU libc and there are strict rules
+ * concerning namespace pollution.
+ */
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_cc[NCCS];		/* control characters */
+	cc_t c_line;			/* line discipline (== c_cc[19]) */
+	speed_t c_ispeed;		/* input speed */
+	speed_t c_ospeed;		/* output speed */
+};
+
+/* c_cc characters */
+#define VINTR 	         0
+#define VQUIT 	         1
+#define VERASE 	         2
+#define VKILL	         3
+#define VEOF	         4
+#define VMIN	         5
+#define VEOL	         6
+#define VTIME	         7
+#define VEOL2	         8
+#define VSWTC	         9
+#define VWERASE 	10
+#define VREPRINT	11
+#define VSUSP 		12
+#define VSTART		13
+#define VSTOP		14
+#define VLNEXT		15
+#define VDISCARD	16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IXON	0001000
+#define IXOFF	0002000
+#define IXANY	0004000
+#define IUCLC	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define ONLCR	0000002
+#define OLCUC	0000004
+
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+
+#define OFILL	00000100
+#define OFDEL	00000200
+#define NLDLY	00001400
+#define   NL0	00000000
+#define   NL1	00000400
+#define   NL2	00001000
+#define   NL3	00001400
+#define TABDLY	00006000
+#define   TAB0	00000000
+#define   TAB1	00002000
+#define   TAB2	00004000
+#define   TAB3	00006000
+#define CRDLY	00030000
+#define   CR0	00000000
+#define   CR1	00010000
+#define   CR2	00020000
+#define   CR3	00030000
+#define FFDLY	00040000
+#define   FF0	00000000
+#define   FF1	00040000
+#define BSDLY	00100000
+#define   BS0	00000000
+#define   BS1	00100000
+#define VTDLY	00200000
+#define   VT0	00000000
+#define   VT1	00200000
+#define XTABS	01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
+
+/* c_cflag bit meaning */
+#define CBAUD	0000377
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define  EXTA   B19200
+#define  EXTB   B38400
+#define  CBAUDEX 0000000
+#define  B57600   00020
+#define  B115200  00021
+#define  B230400  00022
+#define  B460800  00023
+#define  B500000  00024
+#define  B576000  00025
+#define  B921600  00026
+#define B1000000  00027
+#define B1152000  00030
+#define B1500000  00031
+#define B2000000  00032
+#define B2500000  00033
+#define B3000000  00034
+#define B3500000  00035
+#define B4000000  00036
+
+#define CSIZE	00001400
+#define   CS5	00000000
+#define   CS6	00000400
+#define   CS7	00001000
+#define   CS8	00001400
+
+#define CSTOPB	00002000
+#define CREAD	00004000
+#define PARENB	00010000
+#define PARODD	00020000
+#define HUPCL	00040000
+
+#define CLOCAL	00100000
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0x00000080
+#define ICANON	0x00000100
+#define XCASE	0x00004000
+#define ECHO	0x00000008
+#define ECHOE	0x00000002
+#define ECHOK	0x00000004
+#define ECHONL	0x00000010
+#define NOFLSH	0x80000000
+#define TOSTOP	0x00400000
+#define ECHOCTL	0x00000040
+#define ECHOPRT	0x00000020
+#define ECHOKE	0x00000001
+#define FLUSHO	0x00800000
+#define PENDIN	0x20000000
+#define IEXTEN	0x00000400
+
+/* Values for the ACTION argument to `tcflow'.  */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* Values for the QUEUE_SELECTOR argument to `tcflush'.  */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'.  */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* _PPC64_TERMBITS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/termios.h linux/include/asm-ppc64/termios.h
--- linux.orig/include/asm-ppc64/termios.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/termios.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,236 @@
+#ifndef _PPC64_TERMIOS_H
+#define _PPC64_TERMIOS_H
+
+/*
+ * Liberally adapted from alpha/termios.h.  In particular, the c_cc[]
+ * fields have been reordered so that termio & termios share the
+ * common subset in the same order (for brain dead programs that don't
+ * know or care about the differences).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+struct sgttyb {
+	char	sg_ispeed;
+	char	sg_ospeed;
+	char	sg_erase;
+	char	sg_kill;
+	short	sg_flags;
+};
+
+struct tchars {
+	char	t_intrc;
+	char	t_quitc;
+	char	t_startc;
+	char	t_stopc;
+	char	t_eofc;
+	char	t_brkc;
+};
+
+struct ltchars {
+	char	t_suspc;
+	char	t_dsuspc;
+	char	t_rprntc;
+	char	t_flushc;
+	char	t_werasc;
+	char	t_lnextc;
+};
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 10
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* c_cc characters */
+#define _VINTR	0
+#define _VQUIT	1
+#define _VERASE	2
+#define _VKILL	3
+#define _VEOF	4
+#define _VMIN	5
+#define _VEOL	6
+#define _VTIME	7
+#define _VEOL2	8
+#define _VSWTC	9
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+
+#ifdef __KERNEL__
+/*                   ^C  ^\ del  ^U  ^D   1   0   0   0   0  ^W  ^R  ^Z  ^Q  ^S  ^V  ^U  */
+#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" 
+#endif
+
+#define FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+
+#define TIOCGETP	_IOR('t', 8, struct sgttyb)
+#define TIOCSETP	_IOW('t', 9, struct sgttyb)
+#define TIOCSETN	_IOW('t', 10, struct sgttyb)	/* TIOCSETP wo flush */
+
+#define TIOCSETC	_IOW('t', 17, struct tchars)
+#define TIOCGETC	_IOR('t', 18, struct tchars)
+#define TCGETS		_IOR('t', 19, struct termios)
+#define TCSETS		_IOW('t', 20, struct termios)
+#define TCSETSW		_IOW('t', 21, struct termios)
+#define TCSETSF		_IOW('t', 22, struct termios)
+
+#define TCGETA		_IOR('t', 23, struct termio)
+#define TCSETA		_IOW('t', 24, struct termio)
+#define TCSETAW		_IOW('t', 25, struct termio)
+#define TCSETAF		_IOW('t', 28, struct termio)
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCGLTC	_IOR('t', 116, struct ltchars)
+#define TIOCSLTC	_IOW('t', 117, struct ltchars)
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+
+#define TIOCSTI		0x5412
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	(termios)->x = (0xffff0000 & (termios)->x) | __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _PPC64_TERMIOS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/time.h linux/include/asm-ppc64/time.h
--- linux.orig/include/asm-ppc64/time.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/time.h	2002-07-20 01:08:29.000000000 +0000
@@ -0,0 +1,103 @@
+/*
+ * Common time prototypes and such for all ppc machines.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) to merge
+ * Paul Mackerras' version and mine for PReP and Pmac.
+ *
+ * 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.
+ */
+
+#ifndef __PPC64_TIME_H
+#define __PPC64_TIME_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/processor.h>
+#include <asm/paca.h>
+#include <asm/iSeries/HvCall.h>
+
+/* time.c */
+extern unsigned long tb_ticks_per_jiffy;
+extern unsigned long tb_ticks_per_usec;
+extern unsigned long tb_ticks_per_sec;
+extern unsigned long tb_to_xs;
+extern unsigned      tb_to_us;
+extern unsigned long tb_last_stamp;
+
+struct rtc_time;
+extern void to_tm(int tim, struct rtc_time * tm);
+extern time_t last_rtc_update;
+
+/*
+ * By putting all of this stuff into a single struct we 
+ * reduce the number of cache lines touched by do_gettimeofday.
+ * Both by collecting all of the data in one cache line and
+ * by touching only one TOC entry
+ */
+struct gettimeofday_vars {
+	unsigned long tb_to_xs;
+	unsigned long stamp_xsec;
+};
+
+struct gettimeofday_struct {
+	unsigned long tb_orig_stamp;
+	unsigned long tb_ticks_per_sec;
+	struct gettimeofday_vars vars[2];
+	struct gettimeofday_vars * volatile varp;
+	unsigned      var_idx;
+	unsigned      tb_to_us;
+};
+
+struct div_result {
+	unsigned long result_high;
+	unsigned long result_low;
+};
+
+int via_calibrate_decr(void);
+
+static __inline__ unsigned long get_tb(void)
+{
+	return mftb();
+}
+
+/* Accessor functions for the decrementer register. */
+static __inline__ unsigned int get_dec(void)
+{
+	return (mfspr(SPRN_DEC));
+}
+
+static __inline__ void set_dec(int val)
+{
+	struct paca_struct *lpaca = get_paca();
+	int cur_dec;
+
+	if ( lpaca->xLpPaca.xSharedProc ) {
+		lpaca->xLpPaca.xVirtualDecr = val;
+		cur_dec = get_dec();
+		if ( cur_dec > val )
+			HvCall_setVirtualDecr();
+	} else {
+		mtspr(SPRN_DEC, val);
+	}
+}
+
+extern __inline__ unsigned long tb_ticks_since(unsigned long tstamp) {
+	return get_tb() - tstamp;
+}
+
+#define mulhwu(x,y) \
+({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+#define mulhdu(x,y) \
+({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+
+
+unsigned mulhwu_scale_factor(unsigned, unsigned);
+void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
+		   unsigned divisor, struct div_result *dr );
+#endif /* __KERNEL__ */
+#endif /* __PPC64_TIME_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/timex.h linux/include/asm-ppc64/timex.h
--- linux.orig/include/asm-ppc64/timex.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/timex.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,31 @@
+/*
+ * linux/include/asm-ppc/timex.h
+ *
+ * PPC64 architecture timex specifications
+ *
+ * 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.
+ */
+#ifndef _ASMPPC64_TIMEX_H
+#define _ASMPPC64_TIMEX_H
+
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+extern cycles_t cacheflush_time;
+
+static inline cycles_t get_cycles(void)
+{
+	cycles_t ret;
+
+	__asm__ __volatile__("mftb %0" : "=r" (ret) : );
+	return ret;
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/tlb.h linux/include/asm-ppc64/tlb.h
--- linux.orig/include/asm-ppc64/tlb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/tlb.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1 @@
+#include <asm-generic/tlb.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/types.h linux/include/asm-ppc64/types.h
--- linux.orig/include/asm-ppc64/types.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/types.h	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,69 @@
+#ifndef _PPC64_TYPES_H
+#define _PPC64_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ *
+ * 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.
+ */
+
+typedef unsigned int umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+typedef __signed__ long __s64;
+typedef unsigned long __u64;
+
+typedef struct {
+	__u32 u[4];
+} __attribute((aligned(16))) __vector128;
+
+#ifdef __KERNEL__
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long s64;
+typedef unsigned long u64;
+
+typedef __vector128 vector128;
+
+#define BITS_PER_LONG 64
+
+/* PCI dma addresses are 32-bits wide.  Ignore PCI64 for now, since
+   we'll typically be sending it all through iommu tables anyway.  */
+typedef u32 dma_addr_t;
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+
+#endif /* _PPC64_TYPES_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/uaccess.h linux/include/asm-ppc64/uaccess.h
--- linux.orig/include/asm-ppc64/uaccess.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/uaccess.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,285 @@
+#ifndef _PPC64_UACCESS_H
+#define _PPC64_UACCESS_H
+
+/* 
+ * 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.
+ */
+
+#ifndef __ASSEMBLY__
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <asm/processor.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+
+#define KERNEL_DS	((mm_segment_t) { 0 })
+#define USER_DS		((mm_segment_t) { 1 })
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(current->thread.fs)
+#define set_fs(val)	(current->thread.fs = (val))
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
+#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
+#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size) ? 0 : -EFAULT;
+}
+
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+extern void sort_exception_table(void);
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the uglyness from the user.
+ *
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ *
+ * As we use the same address space for kernel and user data on the
+ * PowerPC, we can just do these as direct assignments.  (Of course, the
+ * exception handling means that it's no longer "just"...)
+ */
+#define get_user(x,ptr) \
+  __get_user_check((x),(ptr),sizeof(*(ptr)))
+#define put_user(x,ptr) \
+  __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+#define __get_user(x,ptr) \
+  __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __put_user(x,ptr) \
+  __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+extern long __put_user_bad(void);
+
+#define __put_user_nocheck(x,ptr,size)			\
+({							\
+	long __pu_err;					\
+	__put_user_size((x),(ptr),(size),__pu_err);	\
+	__pu_err;					\
+})
+
+#define __put_user_check(x,ptr,size)				\
+({								\
+	long __pu_err = -EFAULT;				\
+	__typeof__(*(ptr)) *__pu_addr = (ptr);			\
+	if (access_ok(VERIFY_WRITE,__pu_addr,size))		\
+		__put_user_size((x),__pu_addr,(size),__pu_err);	\
+	__pu_err;						\
+})
+
+#define __put_user_size(x,ptr,size,retval)			\
+do {								\
+	retval = 0;						\
+	switch (size) {						\
+	  case 1: __put_user_asm(x,ptr,retval,"stb"); break;	\
+	  case 2: __put_user_asm(x,ptr,retval,"sth"); break;	\
+	  case 4: __put_user_asm(x,ptr,retval,"stw"); break;	\
+	  case 8: __put_user_asm(x,ptr,retval,"std"); break; 	\
+	  default: __put_user_bad();				\
+	}							\
+} while (0)
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct *)(x))
+
+/*
+ * We don't tell gcc that we are accessing memory, but this is OK
+ * because we do not write to any memory gcc knows about, so there
+ * are no aliasing issues.
+ */
+#define __put_user_asm(x, addr, err, op)			\
+	__asm__ __volatile__(					\
+		"1:	"op" %1,0(%2)\n"			\
+		"2:\n"						\
+		".section .fixup,\"ax\"\n"			\
+		"3:	li %0,%3\n"				\
+		"	b 2b\n"					\
+		".previous\n"					\
+		".section __ex_table,\"a\"\n"			\
+		"	.align 3\n"				\
+		"	.llong 1b,3b\n"				\
+		".previous"					\
+		: "=r"(err)					\
+		: "r"(x), "b"(addr), "i"(-EFAULT), "0"(err))
+
+
+#define __get_user_nocheck(x,ptr,size)				\
+({								\
+	long __gu_err, __gu_val;				\
+	__get_user_size(__gu_val,(ptr),(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;			\
+	__gu_err;						\
+})
+
+#define __get_user_check(x,ptr,size)					\
+({									\
+	long __gu_err = -EFAULT, __gu_val = 0;				\
+	const __typeof__(*(ptr)) *__gu_addr = (ptr);			\
+	if (access_ok(VERIFY_READ,__gu_addr,size))			\
+		__get_user_size(__gu_val,__gu_addr,(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_size(x,ptr,size,retval)			\
+do {								\
+	retval = 0;						\
+	switch (size) {						\
+	  case 1: __get_user_asm(x,ptr,retval,"lbz"); break;	\
+	  case 2: __get_user_asm(x,ptr,retval,"lhz"); break;	\
+	  case 4: __get_user_asm(x,ptr,retval,"lwz"); break;	\
+	  case 8: __get_user_asm(x,ptr,retval,"ld");  break;    \
+	  default: (x) = __get_user_bad();			\
+	}							\
+} while (0)
+
+#define __get_user_asm(x, addr, err, op)		\
+	__asm__ __volatile__(				\
+		"1:	"op" %1,0(%2)\n"		\
+		"2:\n"					\
+		".section .fixup,\"ax\"\n"		\
+		"3:	li %0,%3\n"			\
+		"	li %1,0\n"			\
+		"	b 2b\n"				\
+		".previous\n"				\
+		".section __ex_table,\"a\"\n"		\
+		"	.align 3\n"			\
+		"	.llong 1b,3b\n"			\
+		".previous"				\
+		: "=r"(err), "=r"(x)			\
+		: "b"(addr), "i"(-EFAULT), "0"(err))
+
+/* more complex routines */
+
+extern unsigned long __copy_tofrom_user(void *to, const void *from, unsigned long size);
+
+extern inline unsigned long
+copy_from_user(void *to, const void *from, unsigned long n)
+{
+	unsigned long over;
+
+	if (access_ok(VERIFY_READ, from, n))
+		return __copy_tofrom_user(to, from, n);
+	if ((unsigned long)from < TASK_SIZE) {
+		over = (unsigned long)from + n - TASK_SIZE;
+		return __copy_tofrom_user(to, from, n - over) + over;
+	}
+	return n;
+}
+
+extern inline unsigned long
+copy_to_user(void *to, const void *from, unsigned long n)
+{
+	unsigned long over;
+
+	if (access_ok(VERIFY_WRITE, to, n))
+		return __copy_tofrom_user(to, from, n);
+	if ((unsigned long)to < TASK_SIZE) {
+		over = (unsigned long)to + n - TASK_SIZE;
+		return __copy_tofrom_user(to, from, n - over) + over;
+	}
+	return n;
+}
+
+#define __copy_from_user(to, from, size) \
+	__copy_tofrom_user((to), (from), (size))
+#define __copy_to_user(to, from, size) \
+	__copy_tofrom_user((to), (from), (size))
+
+extern unsigned long __clear_user(void *addr, unsigned long size);
+
+extern inline unsigned long
+clear_user(void *addr, unsigned long size)
+{
+	if (access_ok(VERIFY_WRITE, addr, size))
+		return __clear_user(addr, size);
+	return size? -EFAULT: 0;
+}
+
+extern int __strncpy_from_user(char *dst, const char *src, long count);
+
+extern inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+	if (access_ok(VERIFY_READ, src, 1))
+		return __strncpy_from_user(dst, src, count);
+	return -EFAULT;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+
+extern int __strnlen_user(const char *str, long len, unsigned long top);
+
+/*
+ * Returns the length of the string at str (including the null byte),
+ * or 0 if we hit a page we can't access,
+ * or something > len if we didn't find a null byte.
+ *
+ * The `top' parameter to __strnlen_user is to make sure that
+ * we can never overflow from the user area into kernel space.
+ */
+extern __inline__ int strnlen_user(const char *str, long len)
+{
+	unsigned long top = __kernel_ok? ~0UL: TASK_SIZE - 1;
+
+	if ((unsigned long)str > top)
+		return 0;
+	return __strnlen_user(str, len, top);
+}
+
+#define strlen_user(str)	strnlen_user((str), 0x7ffffffe)
+
+#endif  /* __ASSEMBLY__ */
+
+#endif	/* _PPC64_UACCESS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/ucontext.h linux/include/asm-ppc64/ucontext.h
--- linux.orig/include/asm-ppc64/ucontext.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/ucontext.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,22 @@
+#ifndef _ASMPPC64_UCONTEXT_H
+#define _ASMPPC64_UCONTEXT_H
+
+#include <asm/sigcontext.h>
+
+/* Copied from i386. 
+ *
+ * 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.
+ */
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext_struct uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* _ASMPPC64_UCONTEXT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/udbg.h linux/include/asm-ppc64/udbg.h
--- linux.orig/include/asm-ppc64/udbg.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/udbg.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,27 @@
+#ifndef __UDBG_HDR
+#define __UDBG_HDR
+
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+void udbg_init_uart(void *comport);
+void udbg_putc(unsigned char c);
+unsigned char udbg_getc(void);
+int udbg_getc_poll(void);
+void udbg_puts(const char *s);
+int udbg_write(const char *s, int n);
+int udbg_read(char *buf, int buflen);
+void udbg_puthex(unsigned long val);
+void udbg_printSP(const char *s);
+void udbg_printf(const char *fmt, ...);
+void udbg_ppcdbg(unsigned long flags, const char *fmt, ...);
+unsigned long udbg_ifdebug(unsigned long flags);
+
+void udbg_init_uart(void *comport);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/unaligned.h linux/include/asm-ppc64/unaligned.h
--- linux.orig/include/asm-ppc64/unaligned.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/unaligned.h	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,21 @@
+#ifndef __PPC64_UNALIGNED_H
+#define __PPC64_UNALIGNED_H
+
+/*
+ * The PowerPC can do unaligned accesses itself in big endian mode. 
+ *
+ * The strange macros are there to make sure these can't
+ * be misused in a way that makes them not work on other
+ * architectures where unaligned accesses aren't as simple.
+ *
+ * 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.
+ */
+
+#define get_unaligned(ptr) (*(ptr))
+
+#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+
+#endif /* __PPC64_UNALIGNED_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/unistd.h linux/include/asm-ppc64/unistd.h
--- linux.orig/include/asm-ppc64/unistd.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/unistd.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,443 @@
+#ifndef _ASM_PPC_UNISTD_H_
+#define _ASM_PPC_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ *
+ * 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.
+ */
+
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		110
+#define __NR_vhangup		111
+#define __NR_idle		112
+#define __NR_vm86		113
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_modify_ldt		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_query_module	166
+#define __NR_poll		167
+#define __NR_nfsservctl		168
+#define __NR_setresgid		169
+#define __NR_getresgid		170
+#define __NR_prctl		171
+#define __NR_rt_sigreturn	172
+#define __NR_rt_sigaction	173
+#define __NR_rt_sigprocmask	174
+#define __NR_rt_sigpending	175
+#define __NR_rt_sigtimedwait	176
+#define __NR_rt_sigqueueinfo	177
+#define __NR_rt_sigsuspend	178
+#define __NR_pread		179
+#define __NR_pwrite		180
+#define __NR_chown		181
+#define __NR_getcwd		182
+#define __NR_capget		183
+#define __NR_capset		184
+#define __NR_sigaltstack	185
+#define __NR_sendfile		186
+#define __NR_getpmsg		187	/* some people actually want streams */
+#define __NR_putpmsg		188	/* some people actually want streams */
+#define __NR_vfork		189
+#define __NR_ugetrlimit		190	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_pciconfig_read	198
+#define __NR_pciconfig_write	199
+#define __NR_pciconfig_iobase	200
+#define __NR_multiplexer	201
+#define __NR_getdents64		202
+#define __NR_pivot_root		203
+#define __NR_fcntl64		204
+#define __NR_madvise		205
+#define __NR_mincore		206
+#define __NR_gettid		207
+#if 0 /* Reserved syscalls */
+#define __NR_tkill		208
+#define __NR_setxattr		209
+#define __NR_lsetxattr		210
+#define __NR_fsetxattr		211
+#define __NR_getxattr		212
+#define __NR_lgetxattr		213
+#define __NR_fgetxattr		214
+#define __NR_listxattr		215
+#define __NR_llistxattr		216
+#define __NR_flistxattr		217
+#define __NR_removexattr	218
+#define __NR_lremovexattr	219
+#define __NR_fremovexattr	220
+#define __NR_futex		221
+#endif
+
+#define __NR(n)	#n
+
+
+#define __syscall_return(type) \
+	return (__sc_err & 0x10000000 ? errno = __sc_ret, __sc_ret = -1 : 0), \
+	       (type) __sc_ret
+
+#define __syscall_clobbers \
+	"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
+
+#define _syscall0(type,name)						\
+type name(void)								\
+{									\
+	unsigned long __sc_ret, __sc_err;				\
+	{								\
+		register unsigned long __sc_0 __asm__ ("r0");		\
+		register unsigned long __sc_3 __asm__ ("r3");		\
+									\
+		__sc_0 = __NR_##name;					\
+		__asm__ __volatile__					\
+			("sc           \n\t"				\
+			 "mfcr %1      "				\
+			: "=&r" (__sc_3), "=&r" (__sc_0)		\
+			: "0"   (__sc_3), "1"   (__sc_0)		\
+			: __syscall_clobbers);				\
+		__sc_ret = __sc_3;					\
+		__sc_err = __sc_0;					\
+	}								\
+	__syscall_return (type);					\
+}
+
+#define _syscall1(type,name,type1,arg1)					\
+type name(type1 arg1)							\
+{									\
+	unsigned long __sc_ret, __sc_err;				\
+	{								\
+		register unsigned long __sc_0 __asm__ ("r0");		\
+		register unsigned long __sc_3 __asm__ ("r3");		\
+									\
+		__sc_3 = (unsigned long) (arg1);			\
+		__sc_0 = __NR_##name;					\
+		__asm__ __volatile__					\
+			("sc           \n\t"				\
+			 "mfcr %1      "				\
+			: "=&r" (__sc_3), "=&r" (__sc_0)		\
+			: "0"   (__sc_3), "1"   (__sc_0)		\
+			: __syscall_clobbers);				\
+		__sc_ret = __sc_3;					\
+		__sc_err = __sc_0;					\
+	}								\
+	__syscall_return (type);					\
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2)			\
+type name(type1 arg1, type2 arg2)					\
+{									\
+	unsigned long __sc_ret, __sc_err;				\
+	{								\
+		register unsigned long __sc_0 __asm__ ("r0");		\
+		register unsigned long __sc_3 __asm__ ("r3");		\
+		register unsigned long __sc_4 __asm__ ("r4");		\
+									\
+		__sc_3 = (unsigned long) (arg1);			\
+		__sc_4 = (unsigned long) (arg2);			\
+		__sc_0 = __NR_##name;					\
+		__asm__ __volatile__					\
+			("sc           \n\t"				\
+			 "mfcr %1      "				\
+			: "=&r" (__sc_3), "=&r" (__sc_0)		\
+			: "0"   (__sc_3), "1"   (__sc_0),		\
+			  "r"   (__sc_4)				\
+			: __syscall_clobbers);				\
+		__sc_ret = __sc_3;					\
+		__sc_err = __sc_0;					\
+	}								\
+	__syscall_return (type);					\
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
+type name(type1 arg1, type2 arg2, type3 arg3)				\
+{									\
+	unsigned long __sc_ret, __sc_err;				\
+	{								\
+		register unsigned long __sc_0 __asm__ ("r0");		\
+		register unsigned long __sc_3 __asm__ ("r3");		\
+		register unsigned long __sc_4 __asm__ ("r4");		\
+		register unsigned long __sc_5 __asm__ ("r5");		\
+									\
+		__sc_3 = (unsigned long) (arg1);			\
+		__sc_4 = (unsigned long) (arg2);			\
+		__sc_5 = (unsigned long) (arg3);			\
+		__sc_0 = __NR_##name;					\
+		__asm__ __volatile__					\
+			("sc           \n\t"				\
+			 "mfcr %1      "				\
+			: "=&r" (__sc_3), "=&r" (__sc_0)		\
+			: "0"   (__sc_3), "1"   (__sc_0),		\
+			  "r"   (__sc_4),				\
+			  "r"   (__sc_5)				\
+			: __syscall_clobbers);				\
+		__sc_ret = __sc_3;					\
+		__sc_err = __sc_0;					\
+	}								\
+	__syscall_return (type);					\
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)		\
+{									\
+	unsigned long __sc_ret, __sc_err;				\
+	{								\
+		register unsigned long __sc_0 __asm__ ("r0");		\
+		register unsigned long __sc_3 __asm__ ("r3");		\
+		register unsigned long __sc_4 __asm__ ("r4");		\
+		register unsigned long __sc_5 __asm__ ("r5");		\
+		register unsigned long __sc_6 __asm__ ("r6");		\
+									\
+		__sc_3 = (unsigned long) (arg1);			\
+		__sc_4 = (unsigned long) (arg2);			\
+		__sc_5 = (unsigned long) (arg3);			\
+		__sc_6 = (unsigned long) (arg4);			\
+		__sc_0 = __NR_##name;					\
+		__asm__ __volatile__					\
+			("sc           \n\t"				\
+			 "mfcr %1      "				\
+			: "=&r" (__sc_3), "=&r" (__sc_0)		\
+			: "0"   (__sc_3), "1"   (__sc_0),		\
+			  "r"   (__sc_4),				\
+			  "r"   (__sc_5),				\
+			  "r"   (__sc_6)				\
+			: __syscall_clobbers);				\
+		__sc_ret = __sc_3;					\
+		__sc_err = __sc_0;					\
+	}								\
+	__syscall_return (type);					\
+}
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
+{									\
+	unsigned long __sc_ret, __sc_err;				\
+	{								\
+		register unsigned long __sc_0 __asm__ ("r0");		\
+		register unsigned long __sc_3 __asm__ ("r3");		\
+		register unsigned long __sc_4 __asm__ ("r4");		\
+		register unsigned long __sc_5 __asm__ ("r5");		\
+		register unsigned long __sc_6 __asm__ ("r6");		\
+		register unsigned long __sc_7 __asm__ ("r7");		\
+									\
+		__sc_3 = (unsigned long) (arg1);			\
+		__sc_4 = (unsigned long) (arg2);			\
+		__sc_5 = (unsigned long) (arg3);			\
+		__sc_6 = (unsigned long) (arg4);			\
+		__sc_7 = (unsigned long) (arg5);			\
+		__sc_0 = __NR_##name;					\
+		__asm__ __volatile__					\
+			("sc           \n\t"				\
+			 "mfcr %1      "				\
+			: "=&r" (__sc_3), "=&r" (__sc_0)		\
+			: "0"   (__sc_3), "1"   (__sc_0),		\
+			  "r"   (__sc_4),				\
+			  "r"   (__sc_5),				\
+			  "r"   (__sc_6),				\
+			  "r"   (__sc_7)				\
+			: __syscall_clobbers);				\
+		__sc_ret = __sc_3;					\
+		__sc_err = __sc_0;					\
+	}								\
+	__syscall_return (type);					\
+}
+
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * Forking from kernel space will result in the child getting a new,
+ * empty kernel stack area.  Thus the child cannot access automatic
+ * variables set in the parent unless they are in registers, and the
+ * procedure where the fork was done cannot return to its caller in
+ * the child.
+ */
+
+/*
+ * System call prototypes.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,pause)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat) 
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif /* __KERNEL_SYSCALLS__ */
+
+#endif /* _ASM_PPC_UNISTD_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/user.h linux/include/asm-ppc64/user.h
--- linux.orig/include/asm-ppc64/user.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/user.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,58 @@
+#ifndef _PPC_USER_H
+#define _PPC_USER_H
+
+/* Adapted from <asm-alpha/user.h> 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd, NOT the osf-core).  The file contents
+ * are as follows:
+ *
+ *  upage: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page long.
+ *  data: The data segment follows next.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ *  stack: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these in order to be able
+ *	to write an integer number of pages.
+ */
+struct user {
+	struct pt_regs	regs;			/* entire machine state */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	struct regs *	u_ar0;			/* help gdb find registers */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _PPC_USER_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/vc_ioctl.h linux/include/asm-ppc64/vc_ioctl.h
--- linux.orig/include/asm-ppc64/vc_ioctl.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/vc_ioctl.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,50 @@
+#ifndef _LINUX_VC_IOCTL_H
+#define _LINUX_VC_IOCTL_H
+
+/*
+ * 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.
+ */
+
+struct vc_mode {
+	int	height;
+	int	width;
+	int	depth;
+	int	pitch;
+	int	mode;
+	char	name[32];
+	unsigned long fb_address;
+	unsigned long cmap_adr_address;
+	unsigned long cmap_data_address;
+	unsigned long disp_reg_address;
+};
+
+#define VC_GETMODE	0x7667
+#define VC_SETMODE	0x7668
+#define VC_INQMODE	0x7669
+
+#define VC_SETCMAP      0x766a
+#define VC_GETCMAP      0x766b
+
+#define VC_POWERMODE	0x766c
+
+/* Values for the argument to the VC_POWERMODE ioctl */
+#define VC_POWERMODE_INQUIRY	(-1)
+#define VESA_NO_BLANKING	0
+#define VESA_VSYNC_SUSPEND	1
+#define VESA_HSYNC_SUSPEND	2
+#define VESA_POWERDOWN		3
+
+#ifdef __KERNEL__
+extern int console_getmode(struct vc_mode *);
+extern int console_setmode(struct vc_mode *, int);
+extern int console_setcmap(int, unsigned char *, unsigned char *,
+			   unsigned char *);
+extern int console_powermode(int);
+extern struct vc_mode display_info;
+extern struct fb_info *console_fb_info;
+#endif
+
+#endif /* _LINUX_VC_IOCTL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/vga.h linux/include/asm-ppc64/vga.h
--- linux.orig/include/asm-ppc64/vga.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/vga.h	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,50 @@
+/*
+ *	Access to VGA videoram
+ *
+ *	(c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_ASM_VGA_H_
+#define _LINUX_ASM_VGA_H_
+
+#include <asm/io.h>
+
+#include <linux/config.h>
+
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
+
+#define VT_BUF_HAVE_RW
+/*
+ *  These are only needed for supporting VGA or MDA text mode, which use little
+ *  endian byte ordering.
+ *  In other cases, we can optimize by using native byte ordering and
+ *  <linux/vt_buffer.h> has already done the right job for us.
+ */
+
+extern inline void scr_writew(u16 val, volatile u16 *addr)
+{
+    st_le16(addr, val);
+}
+
+extern inline u16 scr_readw(volatile const u16 *addr)
+{
+    return ld_le16(addr);
+}
+
+#define VT_BUF_HAVE_MEMCPYW
+#define scr_memcpyw	memcpy
+
+#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
+
+extern unsigned long vgacon_remap_base;
+#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0))
+
+#define vga_readb(x) (*(x))
+#define vga_writeb(x,y) (*(y) = (x))
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-ppc64/xor.h linux/include/asm-ppc64/xor.h
--- linux.orig/include/asm-ppc64/xor.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-ppc64/xor.h	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/atomic.h linux/include/asm-s390/atomic.h
--- linux.orig/include/asm-s390/atomic.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-s390/atomic.h	2002-07-20 01:08:25.000000000 +0000
@@ -34,21 +34,8 @@
                              : "=&d" (old_val), "=&d" (new_val)		\
 			     : "a" (ptr), "d" (op_val) : "cc" );
 
-static __inline__ int atomic_read(atomic_t *v)
-{
-        int retval;
-        __asm__ __volatile__("bcr      15,0\n\t"
-                             "l        %0,%1"
-                             : "=d" (retval) : "m" (*v) );
-        return retval;
-}
-
-static __inline__ void atomic_set(atomic_t *v, int i)
-{
-        __asm__ __volatile__("st  %1,%0\n\t"
-                             "bcr 15,0"
-                             : "=m" (*v) : "d" (i) );
-}
+#define atomic_read(v)          ((v)->counter)
+#define atomic_set(v,i)         (((v)->counter) = (i))
 
 static __inline__ void atomic_add(int i, atomic_t *v)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/bitops.h linux/include/asm-s390/bitops.h
--- linux.orig/include/asm-s390/bitops.h	2001-07-25 21:12:02.000000000 +0000
+++ linux/include/asm-s390/bitops.h	2002-07-20 01:08:23.000000000 +0000
@@ -54,28 +54,29 @@
  */
 static __inline__ void set_bit_cs(int nr, volatile void * addr)
 {
+	unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lhi   1,3\n"          /* CS must be aligned on 4 byte b. */
-             "   nr    1,%1\n"         /* isolate last 2 bits of address */
-             "   xr    %1,1\n"         /* make addr % 4 == 0 */
-             "   sll   1,3\n"
-             "   ar    %0,1\n"         /* add alignement to bitnr */
+             "   lhi   %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   nr    %2,%1\n"        /* isolate last 2 bits of address */
+             "   xr    %1,%2\n"        /* make addr % 4 == 0 */
+             "   sll   %2,3\n"
+             "   ar    %0,%2\n"        /* add alignement to bitnr */
 #endif
-             "   lhi   1,31\n"
-             "   nr    1,%0\n"         /* make shift value */
-             "   xr    %0,1\n"
+             "   lhi   %2,31\n"
+             "   nr    %2,%0\n"        /* make shift value */
+             "   xr    %0,%2\n"
              "   srl   %0,3\n"
-             "   lhi   2,1\n"
+             "   lhi   %3,1\n"
              "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
-             "   sll   2,0(1)\n"       /* make OR mask */
+             "   sll   %3,0(%2)\n"       /* make OR mask */
              "   l     %0,0(%1)\n"
-             "0: lr    1,%0\n"         /* CS loop starts here */
-             "   or    1,2\n"          /* set bit */
-             "   cs    %0,1,0(%1)\n"
+             "0: lr    %2,%0\n"         /* CS loop starts here */
+             "   or    %2,%3\n"          /* set bit */
+             "   cs    %0,%2,0(%1)\n"
              "   jl    0b"
-             : "+a" (nr), "+a" (addr) :
-             : "cc", "memory", "1", "2" );
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
+             : "cc", "memory" );
 }
 
 /*
@@ -83,30 +84,31 @@
  */
 static __inline__ void clear_bit_cs(int nr, volatile void * addr)
 {
-        static const int mask = -1;
+        static const int minusone = -1;
+	unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lhi   1,3\n"          /* CS must be aligned on 4 byte b. */
-             "   nr    1,%1\n"         /* isolate last 2 bits of address */
-             "   xr    %1,1\n"         /* make addr % 4 == 0 */
-             "   sll   1,3\n"
-             "   ar    %0,1\n"         /* add alignement to bitnr */
+             "   lhi   %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   nr    %2,%1\n"        /* isolate last 2 bits of address */
+             "   xr    %1,%2\n"        /* make addr % 4 == 0 */
+             "   sll   %2,3\n"
+             "   ar    %0,%2\n"        /* add alignement to bitnr */
 #endif
-             "   lhi   1,31\n"
-             "   nr    1,%0\n"         /* make shift value */
-             "   xr    %0,1\n"
+             "   lhi   %2,31\n"
+             "   nr    %2,%0\n"        /* make shift value */
+             "   xr    %0,%2\n"
              "   srl   %0,3\n"
-             "   lhi   2,1\n"
+             "   lhi   %3,1\n"
              "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
-             "   sll   2,0(1)\n"
-             "   x     2,%2\n"         /* make AND mask */
+             "   sll   %3,0(%2)\n"
+             "   x     %3,%4\n"        /* make AND mask */
              "   l     %0,0(%1)\n"
-             "0: lr    1,%0\n"         /* CS loop starts here */
-             "   nr    1,2\n"          /* clear bit */
-             "   cs    %0,1,0(%1)\n"
+             "0: lr    %2,%0\n"        /* CS loop starts here */
+             "   nr    %2,%3\n"        /* clear bit */
+             "   cs    %0,%2,0(%1)\n"
              "   jl    0b"
-             : "+a" (nr), "+a" (addr) : "m" (mask)
-             : "cc", "memory", "1", "2" );
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask)
+             : "m" (minusone) : "cc", "memory" );
 }
 
 /*
@@ -114,28 +116,29 @@
  */
 static __inline__ void change_bit_cs(int nr, volatile void * addr)
 {
+	unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lhi   1,3\n"          /* CS must be aligned on 4 byte b. */
-             "   nr    1,%1\n"         /* isolate last 2 bits of address */
-             "   xr    %1,1\n"         /* make addr % 4 == 0 */
-             "   sll   1,3\n"
-             "   ar    %0,1\n"         /* add alignement to bitnr */
+             "   lhi   %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   nr    %2,%1\n"        /* isolate last 2 bits of address */
+             "   xr    %1,%2\n"        /* make addr % 4 == 0 */
+             "   sll   %2,3\n"
+             "   ar    %0,%2\n"        /* add alignement to bitnr */
 #endif
-             "   lhi   1,31\n"
-             "   nr    1,%0\n"         /* make shift value */
-             "   xr    %0,1\n"
+             "   lhi   %2,31\n"
+             "   nr    %2,%0\n"        /* make shift value */
+             "   xr    %0,%2\n"
              "   srl   %0,3\n"
-             "   lhi   2,1\n"
+             "   lhi   %3,1\n"
              "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
-             "   sll   2,0(1)\n"       /* make XR mask */
+             "   sll   %3,0(%2)\n"     /* make XR mask */
              "   l     %0,0(%1)\n"
-             "0: lr    1,%0\n"         /* CS loop starts here */
-             "   xr    1,2\n"          /* change bit */
-             "   cs    %0,1,0(%1)\n"
+             "0: lr    %2,%0\n"        /* CS loop starts here */
+             "   xr    %2,%3\n"        /* change bit */
+             "   cs    %0,%2,0(%1)\n"
              "   jl    0b"
-             : "+a" (nr), "+a" (addr) : 
-             : "cc", "memory", "1", "2" );
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) : 
+             : "cc", "memory" );
 }
 
 /*
@@ -143,30 +146,31 @@
  */
 static __inline__ int test_and_set_bit_cs(int nr, volatile void * addr)
 {
+	unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lhi   1,3\n"          /* CS must be aligned on 4 byte b. */
-             "   nr    1,%1\n"         /* isolate last 2 bits of address */
-             "   xr    %1,1\n"         /* make addr % 4 == 0 */
-             "   sll   1,3\n"
-             "   ar    %0,1\n"         /* add alignement to bitnr */
+             "   lhi   %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   nr    %2,%1\n"        /* isolate last 2 bits of address */
+             "   xr    %1,%2\n"        /* make addr % 4 == 0 */
+             "   sll   %2,3\n"
+             "   ar    %0,%2\n"        /* add alignement to bitnr */
 #endif
-             "   lhi   1,31\n"
-             "   nr    1,%0\n"         /* make shift value */
-             "   xr    %0,1\n"
+             "   lhi   %2,31\n"
+             "   nr    %2,%0\n"        /* make shift value */
+             "   xr    %0,%2\n"
              "   srl   %0,3\n"
+             "   lhi   %3,1\n"
              "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
-             "   lhi   2,1\n"
-             "   sll   2,0(1)\n"       /* make OR mask */
+             "   sll   %3,0(%2)\n"     /* make OR mask */
              "   l     %0,0(%1)\n"
-             "0: lr    1,%0\n"         /* CS loop starts here */
-             "   or    1,2\n"          /* set bit */
-             "   cs    %0,1,0(%1)\n"
+             "0: lr    %2,%0\n"        /* CS loop starts here */
+             "   or    %2,%3\n"        /* set bit */
+             "   cs    %0,%2,0(%1)\n"
              "   jl    0b\n"
-             "   nr    %0,2\n"         /* isolate old bit */
-             : "+a" (nr), "+a" (addr) :
-             : "cc", "memory", "1", "2" );
-        return nr;
+             "   nr    %0,%3\n"        /* isolate old bit */
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
+             : "cc", "memory" );
+        return nr != 0;
 }
 
 /*
@@ -174,32 +178,33 @@
  */
 static __inline__ int test_and_clear_bit_cs(int nr, volatile void * addr)
 {
-        static const int mask = -1;
+        static const int minusone = -1;
+	unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lhi   1,3\n"          /* CS must be aligned on 4 byte b. */
-             "   nr    1,%1\n"         /* isolate last 2 bits of address */
-             "   xr    %1,1\n"         /* make addr % 4 == 0 */
-             "   sll   1,3\n"
-             "   ar    %0,1\n"         /* add alignement to bitnr */
+             "   lhi   %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   nr    %2,%1\n"        /* isolate last 2 bits of address */
+             "   xr    %1,%2\n"        /* make addr % 4 == 0 */
+             "   sll   %2,3\n"
+             "   ar    %0,%2\n"        /* add alignement to bitnr */
 #endif
-             "   lhi   1,31\n"
-             "   nr    1,%0\n"         /* make shift value */
-             "   xr    %0,1\n"
+             "   lhi   %2,31\n"
+             "   nr    %2,%0\n"        /* make shift value */
+             "   xr    %0,%2\n"
              "   srl   %0,3\n"
+             "   lhi   %3,1\n"
              "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
-             "   lhi   2,1\n"
-             "   sll   2,0(1)\n"
-             "   x     2,%2\n"         /* make AND mask */
+             "   sll   %3,0(%2)\n"
              "   l     %0,0(%1)\n"
-             "0: lr    1,%0\n"         /* CS loop starts here */
-             "   nr    1,2\n"          /* clear bit */
-             "   cs    %0,1,0(%1)\n"
+             "   x     %3,%4\n"        /* make AND mask */
+             "0: lr    %2,%0\n"        /* CS loop starts here */
+             "   nr    %2,%3\n"        /* clear bit */
+             "   cs    %0,%2,0(%1)\n"
              "   jl    0b\n"
-             "   x     2,%2\n"
-             "   nr    %0,2\n"         /* isolate old bit */
-             : "+a" (nr), "+a" (addr) : "m" (mask)
-             : "cc", "memory", "1", "2" );
+             "   x     %3,%4\n"
+             "   nr    %0,%3\n"         /* isolate old bit */
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask)
+             : "m" (minusone) : "cc", "memory" );
         return nr;
 }
 
@@ -208,30 +213,31 @@
  */
 static __inline__ int test_and_change_bit_cs(int nr, volatile void * addr)
 {
+	unsigned long bits, mask;
         __asm__ __volatile__(
 #if ALIGN_CS == 1
-             "   lhi   1,3\n"          /* CS must be aligned on 4 byte b. */
-             "   nr    1,%1\n"         /* isolate last 2 bits of address */
-             "   xr    %1,1\n"         /* make addr % 4 == 0 */
-             "   sll   1,3\n"
-             "   ar    %0,1\n"         /* add alignement to bitnr */
+             "   lhi   %2,3\n"         /* CS must be aligned on 4 byte b. */
+             "   nr    %2,%1\n"        /* isolate last 2 bits of address */
+             "   xr    %1,%2\n"        /* make addr % 4 == 0 */
+             "   sll   %2,3\n"
+             "   ar    %0,%2\n"        /* add alignement to bitnr */
 #endif
-             "   lhi   1,31\n"
-             "   nr    1,%0\n"         /* make shift value */
-             "   xr    %0,1\n"
+             "   lhi   %2,31\n"
+             "   nr    %2,%0\n"        /* make shift value */
+             "   xr    %0,%2\n"
              "   srl   %0,3\n"
+             "   lhi   %3,1\n"
              "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
-             "   lhi   2,1\n"
-             "   sll   2,0(1)\n"       /* make OR mask */
+             "   sll   %3,0(%2)\n"     /* make OR mask */
              "   l     %0,0(%1)\n"
-             "0: lr    1,%0\n"         /* CS loop starts here */
-             "   xr    1,2\n"          /* change bit */
-             "   cs    %0,1,0(%1)\n"
+             "0: lr    %2,%0\n"        /* CS loop starts here */
+             "   xr    %2,%3\n"        /* change bit */
+             "   cs    %0,%2,0(%1)\n"
              "   jl    0b\n"
-             "   nr    %0,2\n"         /* isolate old bit */
-             : "+a" (nr), "+a" (addr) :
-             : "cc", "memory", "1", "2" );
-        return nr;
+             "   nr    %0,%3\n"        /* isolate old bit */
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
+             : "cc", "memory" );
+        return nr != 0;
 }
 #endif /* CONFIG_SMP */
 
@@ -240,17 +246,18 @@
  */
 static __inline__ void __set_bit(int nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         __asm__ __volatile__(
-             "   lhi   2,24\n"
-             "   lhi   1,7\n"
-             "   xr    2,%0\n"
-             "   nr    1,%0\n"
-             "   srl   2,3\n"
-             "   la    2,0(2,%1)\n"
-             "   la    1,0(1,%2)\n"
-             "   oc    0(1,2),0(1)"
-             :  : "r" (nr), "a" (addr), "a" (&_oi_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lhi   %1,24\n"
+             "   lhi   %0,7\n"
+             "   xr    %1,%2\n"
+             "   nr    %0,%2\n"
+             "   srl   %1,3\n"
+             "   la    %1,0(%1,%3)\n"
+             "   la    %0,0(%0,%4)\n"
+             "   oc    0(1,%1),0(%0)"
+             : "=&a" (reg1), "=&a" (reg2)
+             : "r" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
 }
 
 static __inline__ void 
@@ -319,17 +326,18 @@
 static __inline__ void 
 __clear_bit(int nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         __asm__ __volatile__(
-             "   lhi   2,24\n"
-             "   lhi   1,7\n"
-             "   xr    2,%0\n"
-             "   nr    1,%0\n"
-             "   srl   2,3\n"
-             "   la    2,0(2,%1)\n"
-             "   la    1,0(1,%2)\n"
-             "   nc    0(1,2),0(1)"
-             :  : "r" (nr), "a" (addr), "a" (&_ni_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lhi   %1,24\n"
+             "   lhi   %0,7\n"
+             "   xr    %1,%2\n"
+             "   nr    %0,%2\n"
+             "   srl   %1,3\n"
+             "   la    %1,0(%1,%3)\n"
+             "   la    %0,0(%0,%4)\n"
+             "   nc    0(1,%1),0(%0)"
+             : "=&a" (reg1), "=&a" (reg2)
+             : "r" (nr), "a" (addr), "a" (&_ni_bitmap) : "cc", "memory" );
 }
 
 static __inline__ void 
@@ -397,17 +405,18 @@
  */
 static __inline__ void __change_bit(int nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         __asm__ __volatile__(
-             "   lhi   2,24\n"
-             "   lhi   1,7\n"
-             "   xr    2,%0\n"
-             "   nr    1,%0\n"
-             "   srl   2,3\n"
-             "   la    2,0(2,%1)\n"
-             "   la    1,0(1,%2)\n"
-             "   xc    0(1,2),0(1)"
-             :  : "r" (nr), "a" (addr), "a" (&_oi_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lhi   %1,24\n"
+             "   lhi   %0,7\n"
+             "   xr    %1,%2\n"
+             "   nr    %0,%2\n"
+             "   srl   %1,3\n"
+             "   la    %1,0(%1,%3)\n"
+             "   la    %0,0(%0,%4)\n"
+             "   xc    0(1,%1),0(%0)"
+             : "=&a" (reg1), "=&a" (reg2)
+             : "r" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
 }
 
 static __inline__ void 
@@ -475,24 +484,22 @@
  */
 static __inline__ int test_and_set_bit_simple(int nr, volatile void * addr)
 {
-        static const int mask = 1;
+	unsigned long reg1, reg2;
         int oldbit;
         __asm__ __volatile__(
-             "   lhi   1,24\n"
-             "   lhi   2,7\n"
-             "   xr    1,%1\n"
-             "   nr    2,1\n"
-             "   srl   1,3\n"
-             "   la    1,0(1,%2)\n"
-             "   ic    %0,0(1)\n"
-             "   srl   %0,0(2)\n"
-             "   n     %0,%4\n"
-             "   la    2,0(2,%3)\n"
-             "   oc    0(1,1),0(2)"
-             : "=d&" (oldbit) : "r" (nr), "a" (addr),
-               "a" (&_oi_bitmap), "m" (mask)
-             : "cc", "memory", "1", "2" );
-        return oldbit;
+             "   lhi   %1,24\n"
+             "   lhi   %2,7\n"
+             "   xr    %1,%3\n"
+             "   nr    %2,%3\n"
+             "   srl   %1,3\n"
+             "   la    %1,0(%1,%4)\n"
+             "   ic    %0,0(%1)\n"
+             "   srl   %0,0(%2)\n"
+             "   la    %2,0(%2,%5)\n"
+             "   oc    0(1,%1),0(%2)"
+             : "=d&" (oldbit), "=&a" (reg1), "=&a" (reg2)
+             : "r" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
+        return oldbit & 1;
 }
 #define __test_and_set_bit(X,Y)		test_and_set_bit_simple(X,Y)
 
@@ -501,25 +508,23 @@
  */
 static __inline__ int test_and_clear_bit_simple(int nr, volatile void * addr)
 {
-        static const int mask = 1;
+	unsigned long reg1, reg2;
         int oldbit;
 
         __asm__ __volatile__(
-             "   lhi   1,24\n"
-             "   lhi   2,7\n"
-             "   xr    1,%1\n"
-             "   nr    2,1\n"
-             "   srl   1,3\n"
-             "   la    1,0(1,%2)\n"
-             "   ic    %0,0(1)\n"
-             "   srl   %0,0(2)\n"
-             "   n     %0,%4\n"
-             "   la    2,0(2,%3)\n"
-             "   nc    0(1,1),0(2)"
-             : "=d&" (oldbit) : "r" (nr), "a" (addr),
-               "a" (&_ni_bitmap), "m" (mask)
-             : "cc", "memory", "1", "2" );
-        return oldbit;
+             "   lhi   %1,24\n"
+             "   lhi   %2,7\n"
+             "   xr    %1,%3\n"
+             "   nr    %2,%3\n"
+             "   srl   %1,3\n"
+             "   la    %1,0(%1,%4)\n"
+             "   ic    %0,0(%1)\n"
+             "   srl   %0,0(%2)\n"
+             "   la    %2,0(%2,%5)\n"
+             "   nc    0(1,%1),0(%2)"
+             : "=d&" (oldbit), "=&a" (reg1), "=&a" (reg2)
+             : "r" (nr), "a" (addr), "a" (&_ni_bitmap) : "cc", "memory" );
+        return oldbit & 1;
 }
 #define __test_and_clear_bit(X,Y)	test_and_clear_bit_simple(X,Y)
 
@@ -528,25 +533,23 @@
  */
 static __inline__ int test_and_change_bit_simple(int nr, volatile void * addr)
 {
-        static const int mask = 1;
+	unsigned long reg1, reg2;
         int oldbit;
 
         __asm__ __volatile__(
-             "   lhi   1,24\n"
-             "   lhi   2,7\n"
-             "   xr    1,%1\n"
-             "   nr    2,1\n"
-             "   srl   1,3\n"
-             "   la    1,0(1,%2)\n"
-             "   ic    %0,0(1)\n"
-             "   srl   %0,0(2)\n"
-             "   n     %0,%4\n"
-             "   la    2,0(2,%3)\n"
-             "   xc    0(1,1),0(2)"
-             : "=d&" (oldbit) : "r" (nr), "a" (addr),
-               "a" (&_oi_bitmap), "m" (mask)
-             : "cc", "memory", "1", "2" );
-        return oldbit;
+             "   lhi   %1,24\n"
+             "   lhi   %2,7\n"
+             "   xr    %1,%3\n"
+             "   nr    %2,%1\n"
+             "   srl   %1,3\n"
+             "   la    %1,0(%1,%4)\n"
+             "   ic    %0,0(%1)\n"
+             "   srl   %0,0(%2)\n"
+             "   la    %2,0(%2,%5)\n"
+             "   xc    0(1,%1),0(%2)"
+             : "=d&" (oldbit), "=&a" (reg1), "=&a" (reg2)
+             : "r" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
+        return oldbit & 1;
 }
 #define __test_and_change_bit(X,Y)	test_and_change_bit_simple(X,Y)
 
@@ -573,22 +576,20 @@
 
 static __inline__ int __test_bit(int nr, volatile void * addr)
 {
-        static const int mask = 1;
+	unsigned long reg1, reg2;
         int oldbit;
 
         __asm__ __volatile__(
-             "   lhi   2,24\n"
-             "   lhi   1,7\n"
-             "   xr    2,%1\n"
-             "   nr    1,%1\n"
-             "   srl   2,3\n"
-             "   ic    %0,0(2,%2)\n"
-             "   srl   %0,0(1)\n"
-             "   n     %0,%3"
-             : "=d&" (oldbit) : "r" (nr), "a" (addr),
-               "m" (mask)
-             : "cc", "1", "2" );
-        return oldbit;
+             "   lhi   %2,24\n"
+             "   lhi   %1,7\n"
+             "   xr    %2,%3\n"
+             "   nr    %1,%3\n"
+             "   srl   %2,3\n"
+             "   ic    %0,0(%2,%4)\n"
+             "   srl   %0,0(%1)"
+             : "=d&" (oldbit), "=&a" (reg1), "=&a" (reg2)
+             : "r" (nr), "a" (addr) : "cc" );
+        return oldbit & 1;
 }
 
 static __inline__ int __constant_test_bit(int nr, volatile void * addr) {
@@ -605,48 +606,46 @@
  */
 static __inline__ int find_first_zero_bit(void * addr, unsigned size)
 {
-        static const int mask = 0xffL;
+	unsigned long cmp, count;
         int res;
 
         if (!size)
                 return 0;
-        __asm__("   lhi  0,-1\n"
-                "   lr   1,%1\n"
-                "   ahi  1,31\n"
-                "   srl  1,5\n"
-                "   sr   2,2\n"
-                "0: c    0,0(2,%2)\n"
+        __asm__("   lhi  %1,-1\n"
+                "   lr   %2,%3\n"
+                "   slr  %0,%0\n"
+                "   ahi  %2,31\n"
+                "   srl  %2,5\n"
+                "0: c    %1,0(%0,%4)\n"
                 "   jne  1f\n"
-                "   ahi  2,4\n"
-                "   brct 1,0b\n"
-                "   lr   2,%1\n"
+                "   ahi  %0,4\n"
+                "   brct %2,0b\n"
+                "   lr   %0,%3\n"
                 "   j    4f\n"
-                "1: l    1,0(2,%2)\n"
-                "   sll  2,3\n"
-                "   tml  1,0xFFFF\n"
+                "1: l    %2,0(%0,%4)\n"
+                "   sll  %0,3\n"
+                "   lhi  %1,0xff\n"
+                "   tml  %2,0xffff\n"
                 "   jno  2f\n"
-                "   ahi  2,16\n"
-                "   srl  1,16\n"
-                "2: tml  1,0x00FF\n"
+                "   ahi  %0,16\n"
+                "   srl  %2,16\n"
+                "2: tml  %2,0x00ff\n"
                 "   jno  3f\n"
-                "   ahi  2,8\n"
-                "   srl  1,8\n"
-                "3: n    1,%3\n"
-                "   ic   1,0(1,%4)\n"
-                "   n    1,%3\n"
-                "   ar   2,1\n"
-                "4: lr   %0,2"
-                : "=d" (res) : "a" (size), "a" (addr),
-                  "m" (mask), "a" (&_zb_findmap)
-                : "cc", "0", "1", "2" );
+                "   ahi  %0,8\n"
+                "   srl  %2,8\n"
+                "3: nr   %2,%1\n"
+                "   ic   %2,0(%2,%5)\n"
+                "   alr  %0,%2\n"
+                "4:"
+                : "=&a" (res), "=&d" (cmp), "=&a" (count)
+                : "a" (size), "a" (addr), "a" (&_zb_findmap) : "cc" );
         return (res < size) ? res : size;
 }
 
 static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
 {
-        static const int mask = 0xffL;
         unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
-        unsigned long bitvec;
+        unsigned long bitvec, reg;
         int set, bit = offset & 31, res;
 
         if (bit) {
@@ -654,23 +653,21 @@
                  * Look for zero in first word
                  */
                 bitvec = (*p) >> bit;
-                __asm__("   lr   1,%1\n"
-                        "   sr   %0,%0\n"
-                        "   tml  1,0xFFFF\n"
+                __asm__("   slr  %0,%0\n"
+                        "   lhi  %2,0xff\n"
+                        "   tml  %1,0xffff\n"
                         "   jno  0f\n"
                         "   ahi  %0,16\n"
-                        "   srl  1,16\n"
-                        "0: tml  1,0x00FF\n"
+                        "   srl  %1,16\n"
+                        "0: tml  %1,0x00ff\n"
                         "   jno  1f\n"
                         "   ahi  %0,8\n"
-                        "   srl  1,8\n"
-                        "1: n    1,%2\n"
-                        "   ic   1,0(1,%3)\n"
-                        "   n    1,%2\n"
-                        "   ar   %0,1"
-                        : "=d&" (set) : "d" (bitvec),
-                          "m" (mask), "a" (&_zb_findmap)
-                          : "cc", "1" );
+                        "   srl  %1,8\n"
+                        "1: nr   %1,%2\n"
+                        "   ic   %1,0(%1,%3)\n"
+                        "   alr  %0,%1"
+                        : "=&d" (set), "+a" (bitvec), "=&d" (reg)
+                        : "a" (&_zb_findmap) : "cc" );
                 if (set < (32 - bit))
                         return set + offset;
                 offset += 32 - bit;
@@ -689,27 +686,24 @@
  */
 static __inline__ unsigned long ffz(unsigned long word)
 {
-        static const int mask = 0xffL;
+	unsigned long reg;
         int result;
 
-        __asm__("   lr   1,%1\n"
-                "   sr   %0,%0\n"
-                "   tml  1,0xFFFF\n"
+        __asm__("   slr  %0,%0\n"
+                "   lhi  %2,0xff\n"
+                "   tml  %1,0xffff\n"
                 "   jno  0f\n"
                 "   ahi  %0,16\n"
-                "   srl  1,16\n"
-                "0: tml  1,0x00FF\n"
+                "   srl  %1,16\n"
+                "0: tml  %1,0x00ff\n"
                 "   jno  1f\n"
                 "   ahi  %0,8\n"
-                "   srl  1,8\n"
-                "1: n    1,%2\n"
-                "   ic   1,0(1,%3)\n"
-                "   n    1,%2\n"
-                "   ar   %0,1"
-                : "=d&" (result) : "d" (word), 
-                  "m" (mask), "a" (&_zb_findmap)
-                : "cc", "1" );
-
+                "   srl  %1,8\n"
+                "1: nr   %1,%2\n"
+                "   ic   %1,0(%1,%3)\n"
+                "   alr  %0,%1"
+                : "=&d" (result), "+a" (word), "=&d" (reg)
+                : "a" (&_zb_findmap) : "cc" );
         return result;
 }
 
@@ -725,29 +719,28 @@
 
         if (x == 0)
           return 0;
-        __asm__("    lr   %%r1,%1\n"
-                "    sr   %0,%0\n"
-                "    tml  %%r1,0xFFFF\n"
+        __asm__("    slr  %0,%0\n"
+                "    tml  %1,0xffff\n"
                 "    jnz  0f\n"
                 "    ahi  %0,16\n"
-                "    srl  %%r1,16\n"
-                "0:  tml  %%r1,0x00FF\n"
+                "    srl  %1,16\n"
+                "0:  tml  %1,0x00ff\n"
                 "    jnz  1f\n"
                 "    ahi  %0,8\n"
-                "    srl  %%r1,8\n"
-                "1:  tml  %%r1,0x000F\n"
+                "    srl  %1,8\n"
+                "1:  tml  %1,0x000f\n"
                 "    jnz  2f\n"
                 "    ahi  %0,4\n"
-                "    srl  %%r1,4\n"
-                "2:  tml  %%r1,0x0003\n"
+                "    srl  %1,4\n"
+                "2:  tml  %1,0x0003\n"
                 "    jnz  3f\n"
                 "    ahi  %0,2\n"
-                "    srl  %%r1,2\n"
-                "3:  tml  %%r1,0x0001\n"
+                "    srl  %1,2\n"
+                "3:  tml  %1,0x0001\n"
                 "    jnz  4f\n"
                 "    ahi  %0,1\n"
                 "4:"
-                : "=&d" (r) : "d" (x) : "cc", "1" );
+                : "=&d" (r), "+d" (x) : : "cc" );
         return r+1;
 }
 
@@ -778,40 +771,40 @@
 #define ext2_test_bit(nr, addr)      test_bit((nr)^24, addr)
 static __inline__ int ext2_find_first_zero_bit(void *vaddr, unsigned size)
 {
+	unsigned long cmp, count;
         int res;
 
         if (!size)
                 return 0;
-        __asm__("   lhi  0,-1\n"
-                "   lr   1,%1\n"
-                "   ahi  1,31\n"
-                "   srl  1,5\n"
-                "   sr   2,2\n"
-                "0: c    0,0(2,%2)\n"
+        __asm__("   lhi  %1,-1\n"
+                "   lr   %2,%3\n"
+                "   ahi  %2,31\n"
+                "   srl  %2,5\n"
+                "   slr  %0,%0\n"
+                "0: cl   %1,0(%0,%4)\n"
                 "   jne  1f\n"
-                "   ahi  2,4\n"
-                "   brct 1,0b\n"
-                "   lr   2,%1\n"
+                "   ahi  %0,4\n"
+                "   brct %2,0b\n"
+                "   lr   %0,%3\n"
                 "   j    4f\n"
-                "1: l    1,0(2,%2)\n"
-                "   sll  2,3\n"
-                "   lhi  0,0xff\n"
-                "   ahi  2,24\n"
-                "   tmh  1,0xFFFF\n"
+                "1: l    %2,0(%0,%4)\n"
+                "   sll  %0,3\n"
+                "   ahi  %0,24\n"
+                "   lhi  %1,0xff\n"
+                "   tmh  %2,0xffff\n"
                 "   jo   2f\n"
-                "   ahi  2,-16\n"
-                "   srl  1,16\n"
-                "2: tml  1,0xFF00\n"
+                "   ahi  %0,-16\n"
+                "   srl  %2,16\n"
+                "2: tml  %2,0xff00\n"
                 "   jo   3f\n"
-                "   ahi  2,-8\n"
-                "   srl  1,8\n"
-                "3: nr   1,0\n"
-                "   ic   1,0(1,%3)\n"
-                "   ar   2,1\n"
-                "4: lr   %0,2"
-                : "=d" (res) : "a" (size), "a" (vaddr),
-                  "a" (&_zb_findmap)
-                  : "cc", "0", "1", "2" );
+                "   ahi  %0,-8\n"
+                "   srl  %2,8\n"
+                "3: nr   %2,%1\n"
+                "   ic   %2,0(%2,%5)\n"
+                "   alr  %0,%2\n"
+                "4:"
+                : "=&a" (res), "=&d" (cmp), "=&a" (count)
+                : "a" (size), "a" (vaddr), "a" (&_zb_findmap) : "cc" );
         return (res < size) ? res : size;
 }
 
@@ -820,7 +813,7 @@
 {
         unsigned long *addr = vaddr;
         unsigned long *p = addr + (offset >> 5);
-        unsigned long word;
+        unsigned long word, reg;
         int bit = offset & 31UL, res;
 
         if (offset >= size)
@@ -835,21 +828,20 @@
 		word >>= bit;
                 res = bit;
                 /* Look for zero in first longword */
-                __asm__("   lhi  0,0xff\n"
+                __asm__("   lhi  %2,0xff\n"
                         "   tml  %1,0xffff\n"
-                	"   jno   0f\n"
+                	"   jno  0f\n"
                 	"   ahi  %0,16\n"
                 	"   srl  %1,16\n"
                 	"0: tml  %1,0x00ff\n"
                 	"   jno  1f\n"
                 	"   ahi  %0,8\n"
                 	"   srl  %1,8\n"
-                	"1: nr   %1,0\n"
-                	"   ic   %1,0(%1,%2)\n"
+                	"1: nr   %1,%2\n"
+                	"   ic   %1,0(%1,%3)\n"
                 	"   alr  %0,%1"
-                	: "+&d" (res), "+&a" (word)
-                  	: "a" (&_zb_findmap)
-                	: "cc", "0" );
+                	: "+&d" (res), "+&a" (word), "=&d" (reg)
+                  	: "a" (&_zb_findmap) : "cc" );
                 if (res < 32)
 			return (p - addr)*32 + res;
                 p++;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/debug.h linux/include/asm-s390/debug.h
--- linux.orig/include/asm-s390/debug.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390/debug.h	2002-07-20 01:08:21.000000000 +0000
@@ -54,7 +54,7 @@
 #define DEBUG_DATA(entry) (char*)(entry + 1) /* data is stored behind */
                                              /* the entry information */
 
-#define STCK(x)	asm volatile ("STCK %0" : "=m" (x) : : "cc" )
+#define STCK(x)	asm volatile ("STCK 0(%0)" : : "a" (&(x)) : "memory", "cc")
 
 typedef struct __debug_entry debug_entry_t;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/ebcdic.h linux/include/asm-s390/ebcdic.h
--- linux.orig/include/asm-s390/ebcdic.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-s390/ebcdic.h	2002-07-20 01:08:34.000000000 +0000
@@ -24,7 +24,7 @@
 extern __inline__ 
 void codepage_convert(const __u8 *codepage, volatile __u8 * addr, int nr)
 {
-	if (nr <= 0)
+	if (nr-- <= 0)
 		return;
         __asm__ __volatile__(
 		"   bras 1,1f\n"
@@ -34,7 +34,7 @@
 		"1: ahi  %1,-256\n"
 		"   jp   0b\n"
 		"   ex   %1,0(1)"
-                : "+&a" (addr), "+&a" (nr-1)
+                : "+&a" (addr), "+&a" (nr)
                 : "a" (codepage) : "cc", "memory", "1" );
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/ide.h linux/include/asm-s390/ide.h
--- linux.orig/include/asm-s390/ide.h	2000-05-12 18:41:44.000000000 +0000
+++ linux/include/asm-s390/ide.h	2002-07-20 01:08:37.000000000 +0000
@@ -26,7 +26,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+	} b;
+} control_t;
 
 #define ide_request_irq(irq,hand,flg,dev,id)	do {} while (0)
 #define ide_free_irq(irq,dev_id)		do {} while (0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/irq.h linux/include/asm-s390/irq.h
--- linux.orig/include/asm-s390/irq.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-s390/irq.h	2002-07-20 01:08:31.000000000 +0000
@@ -630,11 +630,6 @@
                 "   .align 8\n"
                 "   .quad 0b,2b\n"
                 ".previous"
-                "    lr   1,%1\n"
-                "    msch 0(%2)\n"
-                "0:  ipm  %0\n"
-                "    srl  %0,28\n"
-                "1:\n"
 #else
                 ".section .fixup,\"ax\"\n"
                 "2:  l    %0,%3\n"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/lowcore.h linux/include/asm-s390/lowcore.h
--- linux.orig/include/asm-s390/lowcore.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390/lowcore.h	2002-07-20 01:08:36.000000000 +0000
@@ -185,12 +185,12 @@
 extern struct _lowcore *lowcore_ptr[];
 
 #ifndef CONFIG_SMP
-#define get_cpu_lowcore(cpu)    S390_lowcore
-#define safe_get_cpu_lowcore(cpu) S390_lowcore
+#define get_cpu_lowcore(cpu)      (&S390_lowcore)
+#define safe_get_cpu_lowcore(cpu) (&S390_lowcore)
 #else
-#define get_cpu_lowcore(cpu)    (*lowcore_ptr[cpu])
+#define get_cpu_lowcore(cpu)      (lowcore_ptr[(cpu)])
 #define safe_get_cpu_lowcore(cpu) \
-        ((cpu)==smp_processor_id() ? S390_lowcore:(*lowcore_ptr[(cpu)]))
+        ((cpu) == smp_processor_id() ? &S390_lowcore : lowcore_ptr[(cpu)])
 #endif
 #endif /* __ASSEMBLY__ */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/page.h linux/include/asm-s390/page.h
--- linux.orig/include/asm-s390/page.h	2001-07-25 21:12:02.000000000 +0000
+++ linux/include/asm-s390/page.h	2002-07-20 01:08:27.000000000 +0000
@@ -120,6 +120,9 @@
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 
 #endif /* _S390_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/pgtable.h linux/include/asm-s390/pgtable.h
--- linux.orig/include/asm-s390/pgtable.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390/pgtable.h	2002-07-20 01:08:29.000000000 +0000
@@ -42,6 +42,7 @@
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_icache_range(start, end)          do { } while (0)
 #define flush_icache_page(vma,pg)               do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 /*
  * The S390 doesn't have any external MMU info: the kernel page
@@ -238,10 +239,6 @@
 	*pteptr = pteval;
 }
 
-/*
- * Permanent address of a page.
- */
-#define page_address(page) ((page)->virtual)
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/processor.h linux/include/asm-s390/processor.h
--- linux.orig/include/asm-s390/processor.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390/processor.h	2002-07-20 01:08:36.000000000 +0000
@@ -16,6 +16,7 @@
 #include <asm/page.h>
 #include <asm/ptrace.h>
 
+#ifdef __KERNEL__
 /*
  * Default implementation of macro that returns current
  * instruction pointer ("program counter").
@@ -64,8 +65,7 @@
 #define THREAD_SIZE (2*PAGE_SIZE)
 
 typedef struct {
-        unsigned long seg;
-        unsigned long acc4;
+        unsigned long ar4;
 } mm_segment_t;
 
 /* if you change the thread_struct structure, you must
@@ -82,8 +82,6 @@
         __u32   error_code;            /* error-code of last prog-excep.   */
         __u32   prot_addr;             /* address of protection-excep.     */
         __u32   trap_no;
-        /* perform syscall argument validation (get/set_fs) */
-        mm_segment_t fs;
         per_struct per_info;/* Must be aligned on an 4 byte boundary*/
 	/* Used to give failing instruction back to user for ieee exceptions */
 	addr_t  ieee_instruction_pointer; 
@@ -99,7 +97,6 @@
                     sizeof(init_stack) + (__u32) &init_stack,     \
               (__pa((__u32) &swapper_pg_dir[0]) + _SEGMENT_TABLE),\
                      0,0,0,                                       \
-                     (mm_segment_t) { 0,1},                       \
                      (per_struct) {{{{0,}}},0,0,0,0,{{0,}}},      \
                      0, 0                                         \
 }
@@ -138,8 +135,8 @@
 }
 
 unsigned long get_wchan(struct task_struct *p);
-#define __KSTK_PTREGS(tsk) \
-	((struct pt_regs *)((unsigned long) tsk+THREAD_SIZE) - 1)
+#define __KSTK_PTREGS(tsk) ((struct pt_regs *) \
+	(((unsigned long) tsk + THREAD_SIZE - sizeof(struct pt_regs)) & -8L))
 #define KSTK_EIP(tsk)	(__KSTK_PTREGS(tsk)->psw.addr)
 #define KSTK_ESP(tsk)	(__KSTK_PTREGS(tsk)->gprs[15])
 
@@ -171,6 +168,46 @@
 #define PSW_PROBLEM_STATE       0x00010000UL
 
 /*
+ * Set PSW mask to specified value, while leaving the
+ * PSW addr pointing to the next instruction.
+ */
+
+static inline void __load_psw_mask (unsigned long mask)
+{
+	unsigned long addr;
+
+	psw_t psw;
+	psw.mask = mask;
+
+	asm volatile (
+		"    basr %0,0\n"
+		"0:  ahi  %0,1f-0b\n"
+		"    st   %0,4(%1)\n"
+		"    lpsw 0(%1)\n"
+		"1:"
+		: "=&d" (addr) : "a" (&psw) : "memory", "cc" );
+}
+ 
+/*
+ * Function to stop a processor until an interruption occured
+ */
+static inline void enabled_wait(void)
+{
+	unsigned long reg;
+	psw_t wait_psw;
+
+	wait_psw.mask = 0x070e0000;
+	asm volatile (
+		"    basr %0,0\n"
+		"0:  la   %0,1f-0b(%0)\n"
+		"    st   %0,4(%1)\n"
+		"    oi   4(%1),0x80\n"
+		"    lpsw 0(%1)\n"
+		"1:"
+		: "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
+}
+
+/*
  * Function to drop a processor into disabled wait state
  */
 
@@ -206,4 +243,6 @@
                       : : "a" (dw_psw), "a" (&ctl_buf) : "cc" );
 }
 
+#endif
+
 #endif                                 /* __ASM_S390_PROCESSOR_H           */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/ptrace.h linux/include/asm-s390/ptrace.h
--- linux.orig/include/asm-s390/ptrace.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390/ptrace.h	2002-07-20 01:08:27.000000000 +0000
@@ -174,7 +174,6 @@
 	__u32 acrs[NUM_ACRS];
 	__u32 orig_gpr2;
 	__u32 trap;
-        __u32 old_ilc;
 };
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/rwsem.h linux/include/asm-s390/rwsem.h
--- linux.orig/include/asm-s390/rwsem.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-s390/rwsem.h	2002-07-20 01:08:24.000000000 +0000
@@ -0,0 +1,209 @@
+#ifndef _S390_RWSEM_H
+#define _S390_RWSEM_H
+
+/*
+ *  include/asm-s390/rwsem.h
+ *
+ *  S390 version
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *
+ *  Based on asm-alpha/semaphore.h and asm-i386/rwsem.h
+ */
+
+/*
+ *
+ * The MSW of the count is the negated number of active writers and waiting
+ * lockers, and the LSW is the total number of active locks
+ *
+ * The lock count is initialized to 0 (no active and no waiting lockers).
+ *
+ * When a writer subtracts WRITE_BIAS, it'll get 0xffff0001 for the case of an
+ * uncontended lock. This can be determined because XADD returns the old value.
+ * Readers increment by 1 and see a positive value when uncontended, negative
+ * if there are writers (and maybe) readers waiting (in which case it goes to
+ * sleep).
+ *
+ * The value of WAITING_BIAS supports up to 32766 waiting processes. This can
+ * be extended to 65534 by manually checking the whole MSW rather than relying
+ * on the S flag.
+ *
+ * The value of ACTIVE_BIAS supports up to 65535 active processes.
+ *
+ * This should be totally fair - if anything is waiting, a process that wants a
+ * lock will go to the back of the queue. When the currently active lock is
+ * released, if there's a writer at the front of the queue, then that and only
+ * that will be woken up; if there's a bunch of consequtive readers at the
+ * front, then they'll all be woken up, but no other readers will be.
+ */
+
+#ifndef _LINUX_RWSEM_H
+#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
+#endif
+
+#ifdef __KERNEL__
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+struct rwsem_waiter;
+
+extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *);
+
+/*
+ * the semaphore definition
+ */
+struct rw_semaphore {
+	signed long		count;
+	spinlock_t		wait_lock;
+	struct list_head	wait_list;
+};
+
+#define RWSEM_UNLOCKED_VALUE	0x00000000
+#define RWSEM_ACTIVE_BIAS	0x00000001
+#define RWSEM_ACTIVE_MASK	0x0000ffff
+#define RWSEM_WAITING_BIAS	(-0x00010000)
+#define RWSEM_ACTIVE_READ_BIAS	RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS	(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+
+/*
+ * initialisation
+ */
+#define __RWSEM_INITIALIZER(name) \
+{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) }
+
+#define DECLARE_RWSEM(name) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+static inline void init_rwsem(struct rw_semaphore *sem)
+{
+	sem->count = RWSEM_UNLOCKED_VALUE;
+	spin_lock_init(&sem->wait_lock);
+	INIT_LIST_HEAD(&sem->wait_list);
+}
+
+/*
+ * lock for reading
+ */
+static inline void __down_read(struct rw_semaphore *sem)
+{
+	signed long old, new;
+
+	__asm__ __volatile__(
+		"   l    %0,0(%2)\n"
+		"0: lr   %1,%0\n"
+		"   ahi  %1,%3\n"
+		"   cs   %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
+		: "cc", "memory" );
+	if (old < 0)
+		rwsem_down_read_failed(sem);
+}
+
+/*
+ * lock for writing
+ */
+static inline void __down_write(struct rw_semaphore *sem)
+{
+	signed long old, new, tmp;
+
+	tmp = RWSEM_ACTIVE_WRITE_BIAS;
+	__asm__ __volatile__(
+		"   l    %0,0(%2)\n"
+		"0: lr   %1,%0\n"
+		"   a    %1,%3\n"
+		"   cs   %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "m" (tmp)
+		: "cc", "memory" );
+	if (old != 0)
+		rwsem_down_write_failed(sem);
+}
+
+/*
+ * unlock after reading
+ */
+static inline void __up_read(struct rw_semaphore *sem)
+{
+	signed long old, new;
+
+	__asm__ __volatile__(
+		"   l    %0,0(%2)\n"
+		"0: lr   %1,%0\n"
+		"   ahi  %1,%3\n"
+		"   cs   %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS)
+		: "cc", "memory" );
+	if (new < 0)
+		if ((new & RWSEM_ACTIVE_MASK) == 0)
+			rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void __up_write(struct rw_semaphore *sem)
+{
+	signed long old, new, tmp;
+
+	tmp = -RWSEM_ACTIVE_WRITE_BIAS;
+	__asm__ __volatile__(
+		"   l    %0,0(%2)\n"
+		"0: lr   %1,%0\n"
+		"   a    %1,%3\n"
+		"   cs   %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "m" (tmp)
+		: "cc", "memory" );
+	if (new < 0)
+		if ((new & RWSEM_ACTIVE_MASK) == 0)
+			rwsem_wake(sem);
+}
+
+/*
+ * implement atomic add functionality
+ */
+static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
+{
+	signed long old, new;
+
+	__asm__ __volatile__(
+		"   l    %0,0(%2)\n"
+		"0: lr   %1,%0\n"
+		"   ar   %1,%3\n"
+		"   cs   %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "d" (delta)
+		: "cc", "memory" );
+}
+
+/*
+ * implement exchange and add functionality
+ */
+static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
+{
+	signed long old, new;
+
+	__asm__ __volatile__(
+		"   l    %0,0(%2)\n"
+		"0: lr   %1,%0\n"
+		"   ar   %1,%3\n"
+		"   cs   %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "d" (delta)
+		: "cc", "memory" );
+	return new;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _S390_RWSEM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/siginfo.h linux/include/asm-s390/siginfo.h
--- linux.orig/include/asm-s390/siginfo.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390/siginfo.h	2002-07-20 01:08:32.000000000 +0000
@@ -115,6 +115,7 @@
 #define SI_MESGQ	-3	/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4	/* sent by AIO completion */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
+#define SI_TKILL	-6	/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/sigp.h linux/include/asm-s390/sigp.h
--- linux.orig/include/asm-s390/sigp.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390/sigp.h	2002-07-20 01:08:37.000000000 +0000
@@ -129,6 +129,6 @@
    return ccode;
 }
 
-#endif __SIGP__
+#endif /* __SIGP__ */
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/spinlock.h linux/include/asm-s390/spinlock.h
--- linux.orig/include/asm-s390/spinlock.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390/spinlock.h	2002-07-20 01:08:37.000000000 +0000
@@ -29,22 +29,24 @@
 
 extern inline void spin_lock(spinlock_t *lp)
 {
-        __asm__ __volatile("    bras  1,1f\n"
+	unsigned int reg1, reg2;
+        __asm__ __volatile("    bras  %0,1f\n"
                            "0:  diag  0,0,68\n"
-                           "1:  slr   0,0\n"
-                           "    cs    0,1,0(%0)\n"
+                           "1:  slr   %1,%1\n"
+                           "    cs    %1,%0,0(%2)\n"
                            "    jl    0b\n"
-                           : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
+                           : "=&d" (reg1), "=&d" (reg2)
+			   : "a" (&lp->lock) : "cc", "memory" );
 }
 
 extern inline int spin_trylock(spinlock_t *lp)
 {
-	unsigned long result;
+	unsigned long result, reg;
 	__asm__ __volatile("    slr   %0,%0\n"
-			   "    basr  1,0\n"
-			   "0:  cs    %0,1,0(%1)"
-			   : "=&d" (result)
-			   : "a" (&lp->lock) : "1", "cc", "memory" );
+			   "    basr  %1,0\n"
+			   "0:  cs    %0,%1,0(%2)"
+			   : "=&d" (result), "=&d" (reg)
+			   : "a" (&lp->lock) : "cc", "memory" );
 	return !result;
 }
 
@@ -82,7 +84,7 @@
                      "   la    3,1(2)\n"     /* one more reader */ \
                      "   cs    2,3,0(%0)\n"  /* try to write new value */ \
                      "   jl    0b"       \
-                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
 
 #define read_unlock(rw) \
         asm volatile("   l     2,0(%0)\n"   \
@@ -92,7 +94,7 @@
                      "   ahi   3,-1\n"    /* one less reader */ \
                      "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
 
 #define write_lock(rw) \
         asm volatile("   lhi   3,1\n"    \
@@ -102,7 +104,7 @@
                      "1: slr   2,2\n"     /* old lock value must be 0 */ \
                      "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
 
 #define write_unlock(rw) \
         asm volatile("   slr   3,3\n"     /* new lock value = 0 */ \
@@ -112,6 +114,6 @@
                      "   sll   2,31\n"    /* old lock value must be 0x80000000 */ \
                      "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
 
 #endif /* __ASM_SPINLOCK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/system.h linux/include/asm-s390/system.h
--- linux.orig/include/asm-s390/system.h	2001-07-25 21:12:02.000000000 +0000
+++ linux/include/asm-s390/system.h	2002-07-20 01:08:36.000000000 +0000
@@ -12,6 +12,7 @@
 #define __ASM_SYSTEM_H
 
 #include <linux/config.h>
+#include <asm/types.h>
 #ifdef __KERNEL__
 #include <asm/lowcore.h>
 #endif
@@ -23,7 +24,7 @@
                 break;                                                       \
 	save_fp_regs1(&prev->thread.fp_regs);                                \
 	restore_fp_regs1(&next->thread.fp_regs);              		     \
-	last = resume(&prev->thread,&next->thread);                          \
+	last = resume(prev,next);					     \
 } while (0)
 
 struct task_struct;
@@ -97,8 +98,6 @@
                                 : "+d&" (x) : "a" (ptr)
                                 : "memory", "cc", "0" );
                         break;
-               default:
-                        abort();
         }
         return x;
 }
@@ -132,24 +131,24 @@
 #define __sti() ({ \
         __u8 dummy; \
         __asm__ __volatile__ ( \
-                "stosm %0,0x03" : "=m" (dummy) : : "memory"); \
+                "stosm 0(%0),0x03" : : "a" (&dummy) : "memory"); \
         })
 
 #define __cli() ({ \
         __u32 flags; \
         __asm__ __volatile__ ( \
-                "stnsm %0,0xFC" : "=m" (flags) : : "memory"); \
+                "stnsm 0(%0),0xFC" : : "a" (&flags) : "memory"); \
         flags; \
         })
 
 #define __save_flags(x) \
-        __asm__ __volatile__("stosm %0,0" : "=m" (x) : : "memory")
+        __asm__ __volatile__("stosm 0(%0),0" : : "a" (&x) : "memory")
 
 #define __restore_flags(x) \
-        __asm__ __volatile__("ssm   %0" : : "m" (x) : "memory")
+        __asm__ __volatile__("ssm   0(%0)" : : "a" (&x) : "memory")
 
 #define __load_psw(psw) \
-	__asm__ __volatile__("lpsw %0" : : "m" (psw) : "cc" );
+	__asm__ __volatile__("lpsw 0(%0)" : : "a" (&psw) : "cc" );
 
 #define __ctl_load(array, low, high) ({ \
 	__asm__ __volatile__ ( \
@@ -244,7 +243,7 @@
 #endif
 
 #ifdef __KERNEL__
-extern struct task_struct *resume(void *,void *);
+extern struct task_struct *resume(void *, void *);
 
 extern int save_fp_regs1(s390_fp_regs *fpregs);
 extern void save_fp_regs(s390_fp_regs *fpregs);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/timex.h linux/include/asm-s390/timex.h
--- linux.orig/include/asm-s390/timex.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390/timex.h	2002-07-20 01:08:22.000000000 +0000
@@ -25,8 +25,16 @@
 {
 	cycles_t cycles;
 
-	__asm__("stck  %0" : "=m" (cycles) : : "cc");
+	__asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
 	return cycles >> 2;
 }
 
+static inline unsigned long long get_clock (void)
+{
+	unsigned long long clk;
+
+	__asm__("stck 0(%0)" : : "a" (&(clk)) : "memory", "cc");
+	return clk;
+}
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/uaccess.h linux/include/asm-s390/uaccess.h
--- linux.orig/include/asm-s390/uaccess.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390/uaccess.h	2002-07-20 01:08:28.000000000 +0000
@@ -28,21 +28,21 @@
  * For historical reasons, these macros are grossly misnamed.
  */
 
-#define MAKE_MM_SEG(s,a)  ((mm_segment_t) { (s),(a) })
+#define MAKE_MM_SEG(a)  ((mm_segment_t) { (a) })
 
 
-#define KERNEL_DS       MAKE_MM_SEG(0x7FFFFFFF,0)
-#define USER_DS         MAKE_MM_SEG(PAGE_OFFSET,1)
+#define KERNEL_DS       MAKE_MM_SEG(0)
+#define USER_DS         MAKE_MM_SEG(1)
 
 #define get_ds()        (KERNEL_DS)
-#define get_fs()        (current->thread.fs)
-#define set_fs(x)       ({asm volatile("sar   4,%0"::"a" (x.acc4)); \
-                         current->thread.fs = (x);})
+#define get_fs()        (current->addr_limit)
+#define set_fs(x)       ({asm volatile("sar   4,%0"::"a" ((x).ar4)); \
+                         current->addr_limit = (x);})
 
-#define segment_eq(a,b) ((a).acc4 == (b).acc4)
+#define segment_eq(a,b) ((a).ar4 == (b).ar4)
 
 
-#define __access_ok(addr,size) ((((long) addr + size)&0x7FFFFFFFL) < current->addr_limit.seg)
+#define __access_ok(addr,size) (1)
 
 #define access_ok(type,addr,size) __access_ok(addr,size)
 
@@ -197,38 +197,34 @@
  */
 #define __put_user(x, ptr)                                      \
 ({                                                              \
+        __typeof__(*(ptr)) *__pu_addr = (ptr);                  \
+        __typeof__(*(ptr)) __x = (x);                           \
         int __pu_err;                                           \
         switch (sizeof (*(ptr))) {                              \
-                case 1:                                         \
-                        __pu_err = __put_user_asm_1((__u8)(__u32)x,(ptr));\
-                        break;                                  \
-                case 2:                                         \
-                        __pu_err = __put_user_asm_2((__u16)(__u32)x,(ptr));\
-                        break;                                  \
-                case 4:                                         \
-                        __pu_err = __put_user_asm_4((__u32) x,(ptr));\
-                        break;                                  \
-		case 8:						\
-			__pu_err = __put_user_asm_8((__u64) x,(ptr));\
-			break;					\
-                default:                                        \
+        case 1:                                                 \
+                __pu_err = __put_user_asm_1((__u8)(__u32) __x,  \
+                                            __pu_addr);         \
+                break;                                          \
+        case 2:                                                 \
+                __pu_err = __put_user_asm_2((__u16)(__u32) __x, \
+                                            __pu_addr);         \
+                break;                                          \
+        case 4:                                                 \
+                __pu_err = __put_user_asm_4((__u32) __x,        \
+                                            __pu_addr);         \
+                break;                                          \
+        case 8:                                                 \
+                __pu_err = __put_user_asm_8((__u64) __x,        \
+                                            __pu_addr);         \
+                break;                                          \
+        default:                                                \
                 __pu_err = __put_user_bad();                    \
                 break;                                          \
          }                                                      \
         __pu_err;                                               \
 })
 
-#define put_user(x, ptr)                                        \
-({                                                              \
-        long __pu_err = -EFAULT;                                \
-        __typeof__(*(ptr)) *__pu_addr = (ptr);                  \
-        __typeof__(*(ptr)) __x = (x);                           \
-        if (__access_ok((long)__pu_addr,sizeof(*(ptr)))) {      \
-                __pu_err = 0;                                   \
-                __put_user((__x), (__pu_addr));                 \
-        }                                                       \
-        __pu_err;                                               \
-})
+#define put_user(x, ptr) __put_user(x, ptr)
 
 extern int __put_user_bad(void);
 
@@ -336,42 +332,32 @@
 
 #define __get_user(x, ptr)                                      \
 ({                                                              \
+        __typeof__(ptr) __gu_addr = (ptr);                      \
+        __typeof__(*(ptr)) __x;                                 \
         int __gu_err;                                           \
-        switch (sizeof(*(ptr))) {                               \
-                case 1:                                         \
-                        __get_user_asm_1(x,ptr,__gu_err);       \
-                        break;                                  \
-                case 2:                                         \
-                        __get_user_asm_2(x,ptr,__gu_err);       \
-                        break;                                  \
-                case 4:                                         \
-                        __get_user_asm_4(x,ptr,__gu_err);       \
-                        break;                                  \
-                case 8:                                         \
-                        __get_user_asm_8(x,ptr,__gu_err);       \
-                        break;                                  \
-                default:                                        \
-                        (x) = 0;                                \
-                        __gu_err = __get_user_bad();            \
+        switch (sizeof(*(__gu_addr))) {                         \
+        case 1:                                                 \
+                __get_user_asm_1(__x, __gu_addr, __gu_err);     \
+                break;                                          \
+        case 2:                                                 \
+                __get_user_asm_2(__x, __gu_addr, __gu_err);     \
+                break;                                          \
+        case 4:                                                 \
+                __get_user_asm_4(__x, __gu_addr, __gu_err);     \
+                break;                                          \
+        case 8:                                                 \
+                __get_user_asm_8(__x, __gu_addr, __gu_err);     \
+                break;                                          \
+        default:                                                \
+                __x = 0;                                        \
+                __gu_err = __get_user_bad();                    \
                 break;                                          \
         }                                                       \
+        (x) = __x;                                              \
         __gu_err;                                               \
 })
 
-#define get_user(x, ptr)                                        \
-({                                                              \
-        long __gu_err = -EFAULT;                                \
-        __typeof__(ptr) __gu_addr = (ptr);                      \
-        __typeof__(*(ptr)) __x;                                 \
-        if (__access_ok((long)__gu_addr,sizeof(*(ptr)))) {      \
-                __gu_err = 0;                                   \
-                __get_user((__x), (__gu_addr));                 \
-                (x) = __x;                                      \
-        }                                                       \
-        else                                                    \
-                (x) = 0;                                        \
-        __gu_err;                                               \
-})
+#define get_user(x, ptr) __get_user(x, ptr)
 
 extern int __get_user_bad(void);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390/unistd.h linux/include/asm-s390/unistd.h
--- linux.orig/include/asm-s390/unistd.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390/unistd.h	2002-07-20 01:08:37.000000000 +0000
@@ -211,7 +211,12 @@
 #define __NR_mincore            218
 #define __NR_madvise            219
 #define __NR_getdents64		220
-
+#define __NR_fcntl64		221
+/*
+ * Numbers 224-235 are reserved for posix acl
+ */
+#define __NR_gettid		236
+#define __NR_tkill		237
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/atomic.h linux/include/asm-s390x/atomic.h
--- linux.orig/include/asm-s390x/atomic.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-s390x/atomic.h	2002-07-20 01:08:27.000000000 +0000
@@ -34,21 +34,8 @@
                              : "=&d" (old_val), "=&d" (new_val)		\
 			     : "a" (ptr), "d" (op_val) : "cc" );
 
-static __inline__ int atomic_read(atomic_t *v)
-{
-        int retval;
-        __asm__ __volatile__("bcr      15,0\n\t"
-                             "l        %0,%1"
-                             : "=d" (retval) : "m" (*v) );
-        return retval;
-}
-
-static __inline__ void atomic_set(atomic_t *v, int i)
-{
-        __asm__ __volatile__("st  %1,%0\n\t"
-                             "bcr 15,0"
-                             : "=m" (*v) : "d" (i) );
-}
+#define atomic_read(v)          ((v)->counter)
+#define atomic_set(v,i)         (((v)->counter) = (i))
 
 static __inline__ void atomic_add(int i, atomic_t *v)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/bitops.h linux/include/asm-s390x/bitops.h
--- linux.orig/include/asm-s390x/bitops.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-s390x/bitops.h	2002-07-20 01:08:40.000000000 +0000
@@ -79,7 +79,7 @@
              "   ogr   %2,%3\n"        /* set bit */
              "   csg   %0,%2,0(%1)\n"
              "   jl    0b"
-             : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
              : "cc", "memory" );
 }
 
@@ -110,7 +110,7 @@
              "   ngr   %2,%3\n"        /* clear bit */
              "   csg   %0,%2,0(%1)\n"
              "   jl    0b"
-             : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
              : "cc", "memory" );
 }
 
@@ -140,7 +140,7 @@
              "   xgr   %2,%3\n"        /* change bit */
              "   csg   %0,%2,0(%1)\n"
              "   jl    0b"
-             : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) : 
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) : 
              : "cc", "memory" );
 }
 
@@ -172,7 +172,7 @@
              "   csg   %0,%2,0(%1)\n"
              "   jl    0b\n"
              "   ngr   %0,%3\n"        /* isolate old bit */
-             : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
              : "cc", "memory" );
         return nr != 0;
 }
@@ -205,7 +205,7 @@
              "   csg   %0,%2,0(%1)\n"
              "   jl    0b\n"
              "   xgr   %0,%2\n"        /* isolate old bit */
-             : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
              : "cc", "memory" );
         return nr != 0;
 }
@@ -238,7 +238,7 @@
              "   csg   %0,%2,0(%1)\n"
              "   jl    0b\n"
              "   ngr   %0,%3\n"        /* isolate old bit */
-             : "+a" (nr), "+a" (addr), "=a" (bits), "=d" (mask) :
+             : "+a" (nr), "+a" (addr), "=&a" (bits), "=&d" (mask) :
              : "cc", "memory" );
         return nr != 0;
 }
@@ -249,17 +249,18 @@
  */
 static __inline__ void __set_bit(unsigned long nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         __asm__ __volatile__(
-             "   lghi  2,56\n"
-             "   lghi  1,7\n"
-             "   xgr   2,%0\n"
-             "   nr    1,%0\n"
-             "   srlg  2,2,3\n"
-             "   la    2,0(2,%1)\n"
-             "   la    1,0(1,%2)\n"
-             "   oc    0(1,2),0(1)"
-             :  : "a" (nr), "a" (addr), "a" (&_oi_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lghi  %1,56\n"
+             "   lghi  %0,7\n"
+             "   xgr   %1,%2\n"
+             "   nr    %0,%2\n"
+             "   srlg  %1,%1,3\n"
+             "   la    %1,0(%1,%3)\n"
+             "   la    %0,0(%0,%4)\n"
+             "   oc    0(1,%1),0(%0)"
+             : "=&a" (reg1), "=&a" (reg2)
+             : "a" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
 }
 
 static __inline__ void 
@@ -328,17 +329,18 @@
 static __inline__ void 
 __clear_bit(unsigned long nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         __asm__ __volatile__(
-             "   lghi  2,56\n"
-             "   lghi  1,7\n"
-             "   xgr   2,%0\n"
-             "   nr    1,%0\n"
-             "   srlg  2,2,3\n"
-             "   la    2,0(2,%1)\n"
-             "   la    1,0(1,%2)\n"
-             "   nc    0(1,2),0(1)"
-             :  : "d" (nr), "a" (addr), "a" (&_ni_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lghi  %1,56\n"
+             "   lghi  %0,7\n"
+             "   xgr   %1,%2\n"
+             "   nr    %0,%2\n"
+             "   srlg  %1,%1,3\n"
+             "   la    %1,0(%1,%3)\n"
+             "   la    %0,0(%0,%4)\n"
+             "   nc    0(1,%1),0(%0)"
+             : "=&a" (reg1), "=&a" (reg2)
+	     : "d" (nr), "a" (addr), "a" (&_ni_bitmap) : "cc", "memory" );
 }
 
 static __inline__ void 
@@ -406,17 +408,18 @@
  */
 static __inline__ void __change_bit(unsigned long nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         __asm__ __volatile__(
-             "   lghi  2,56\n"
-             "   lghi  1,7\n"
-             "   xgr   2,%0\n"
-             "   nr    1,%0\n"
-             "   srlg  2,2,3\n"
-             "   la    2,0(2,%1)\n"
-             "   la    1,0(1,%2)\n"
-             "   xc    0(1,2),0(1)"
-             :  : "d" (nr), "a" (addr), "a" (&_oi_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lghi  %1,56\n"
+             "   lghi  %0,7\n"
+             "   xgr   %1,%2\n"
+             "   nr    %0,%2\n"
+             "   srlg  %1,%1,3\n"
+             "   la    %1,0(%1,%3)\n"
+             "   la    %0,0(%0,%4)\n"
+             "   xc    0(1,%1),0(%0)"
+             : "=&a" (reg1), "=&a" (reg2)
+	     : "d" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
 }
 
 static __inline__ void 
@@ -485,20 +488,21 @@
 static __inline__ int
 test_and_set_bit_simple(unsigned long nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         int oldbit;
         __asm__ __volatile__(
-             "   lghi  1,56\n"
-             "   lghi  2,7\n"
-             "   xgr   1,%1\n"
-             "   nr    2,%1\n"
-             "   srlg  1,1,3\n"
-             "   la    1,0(1,%2)\n"
-             "   ic    %0,0(1)\n"
-             "   srl   %0,0(2)\n"
-             "   la    2,0(2,%3)\n"
-             "   oc    0(1,1),0(2)"
-             : "=&d" (oldbit) : "d" (nr), "a" (addr), "a" (&_oi_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lghi  %1,56\n"
+             "   lghi  %2,7\n"
+             "   xgr   %1,%3\n"
+             "   nr    %2,%3\n"
+             "   srlg  %1,%1,3\n"
+             "   la    %1,0(%1,%4)\n"
+             "   ic    %0,0(%1)\n"
+             "   srl   %0,0(%2)\n"
+             "   la    %2,0(%2,%5)\n"
+             "   oc    0(1,%1),0(%2)"
+             : "=&d" (oldbit), "=&a" (reg1), "=&a" (reg2)
+	     : "d" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
         return oldbit & 1;
 }
 #define __test_and_set_bit(X,Y)		test_and_set_bit_simple(X,Y)
@@ -509,21 +513,22 @@
 static __inline__ int
 test_and_clear_bit_simple(unsigned long nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         int oldbit;
 
         __asm__ __volatile__(
-             "   lghi  1,56\n"
-             "   lghi  2,7\n"
-             "   xgr   1,%1\n"
-             "   nr    2,%1\n"
-             "   srlg  1,1,3\n"
-             "   la    1,0(1,%2)\n"
-             "   ic    %0,0(1)\n"
-             "   srl   %0,0(2)\n"
-             "   la    2,0(2,%3)\n"
-             "   nc    0(1,1),0(2)"
-             : "=&d" (oldbit) : "d" (nr), "a" (addr), "a" (&_ni_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lghi  %1,56\n"
+             "   lghi  %2,7\n"
+             "   xgr   %1,%3\n"
+             "   nr    %2,%3\n"
+             "   srlg  %1,%1,3\n"
+             "   la    %1,0(%1,%4)\n"
+             "   ic    %0,0(%1)\n"
+             "   srl   %0,0(%2)\n"
+             "   la    %2,0(%2,%5)\n"
+             "   nc    0(1,%1),0(%2)"
+             : "=&d" (oldbit), "=&a" (reg1), "=&a" (reg2)
+	     : "d" (nr), "a" (addr), "a" (&_ni_bitmap) : "cc", "memory" );
         return oldbit & 1;
 }
 #define __test_and_clear_bit(X,Y)	test_and_clear_bit_simple(X,Y)
@@ -534,21 +539,22 @@
 static __inline__ int
 test_and_change_bit_simple(unsigned long nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         int oldbit;
 
         __asm__ __volatile__(
-             "   lghi  1,56\n"
-             "   lghi  2,7\n"
-             "   xgr   1,%1\n"
-             "   nr    2,%1\n"
-             "   srlg  1,1,3\n"
-             "   la    1,0(1,%2)\n"
-             "   ic    %0,0(1)\n"
-             "   srl   %0,0(2)\n"
-             "   la    2,0(2,%3)\n"
-             "   xc    0(1,1),0(2)"
-             : "=&d" (oldbit) : "d" (nr), "a" (addr), "a" (&_oi_bitmap)
-             : "cc", "memory", "1", "2" );
+             "   lghi  %1,56\n"
+             "   lghi  %2,7\n"
+             "   xgr   %1,%3\n"
+             "   nr    %2,%3\n"
+             "   srlg  %1,%1,3\n"
+             "   la    %1,0(%1,%4)\n"
+             "   ic    %0,0(%1)\n"
+             "   srl   %0,0(%2)\n"
+             "   la    %2,0(%2,%5)\n"
+             "   xc    0(1,%1),0(%2)"
+             : "=&d" (oldbit), "=&a" (reg1), "=&a" (reg2)
+	     : "d" (nr), "a" (addr), "a" (&_oi_bitmap) : "cc", "memory" );
         return oldbit & 1;
 }
 #define __test_and_change_bit(X,Y)	test_and_change_bit_simple(X,Y)
@@ -576,18 +582,19 @@
 
 static __inline__ int __test_bit(unsigned long nr, volatile void * addr)
 {
+	unsigned long reg1, reg2;
         int oldbit;
 
         __asm__ __volatile__(
-             "   lghi  2,56\n"
-             "   lghi  1,7\n"
-             "   xgr   2,%1\n"
-             "   nr    1,%1\n"
-             "   srlg  2,2,3\n"
-             "   ic    %0,0(2,%2)\n"
-             "   srl   %0,0(1)\n"
-             : "=&d" (oldbit) : "d" (nr), "a" (addr)
-             : "cc", "1", "2" );
+             "   lghi  %2,56\n"
+             "   lghi  %1,7\n"
+             "   xgr   %2,%3\n"
+             "   nr    %1,%3\n"
+             "   srlg  %2,%2,3\n"
+             "   ic    %0,0(%2,%4)\n"
+             "   srl   %0,0(%1)\n"
+             : "=&d" (oldbit), "=&a" (reg1), "=&a" (reg2)
+	     : "d" (nr), "a" (addr) : "cc" );
         return oldbit & 1;
 }
 
@@ -607,42 +614,42 @@
 static __inline__ unsigned long
 find_first_zero_bit(void * addr, unsigned long size)
 {
-        unsigned long res;
+        unsigned long res, cmp, count;
 
         if (!size)
                 return 0;
-        __asm__("   lghi  0,-1\n"
-                "   lgr   1,%1\n"
+        __asm__("   lghi  %1,-1\n"
+                "   lgr   %2,%3\n"
                 "   slgr  %0,%0\n"
-                "   aghi  1,63\n"
-                "   srlg  1,1,6\n"
-                "0: cg    0,0(%0,%2)\n"
+                "   aghi  %2,63\n"
+                "   srlg  %2,%2,6\n"
+                "0: cg    %1,0(%0,%4)\n"
                 "   jne   1f\n"
                 "   aghi  %0,8\n"
-                "   brct  1,0b\n"
-                "   lgr   %0,%1\n"
+                "   brct  %2,0b\n"
+                "   lgr   %0,%3\n"
                 "   j     5f\n"
-                "1: lg    1,0(%0,%2)\n"
+                "1: lg    %2,0(%0,%4)\n"
                 "   sllg  %0,%0,3\n"
-                "   clr   1,0\n"
+                "   clr   %2,%1\n"
 		"   jne   2f\n"
 		"   aghi  %0,32\n"
-                "   srlg  1,1,32\n"
-		"2: lghi  0,0xff\n"
-                "   tmll  1,0xffff\n"
+                "   srlg  %2,%2,32\n"
+		"2: lghi  %1,0xff\n"
+                "   tmll  %2,0xffff\n"
                 "   jno   3f\n"
                 "   aghi  %0,16\n"
-                "   srl   1,16\n"
-                "3: tmll  1,0x00ff\n"
+                "   srl   %2,16\n"
+                "3: tmll  %2,0x00ff\n"
                 "   jno   4f\n"
                 "   aghi  %0,8\n"
-                "   srl   1,8\n"
-                "4: ngr   1,0\n"
-                "   ic    1,0(1,%3)\n"
-                "   algr  %0,1\n"
+                "   srl   %2,8\n"
+                "4: ngr   %2,%1\n"
+                "   ic    %2,0(%2,%5)\n"
+                "   algr  %0,%2\n"
                 "5:"
-                : "=&a" (res) : "a" (size), "a" (addr), "a" (&_zb_findmap)
-                : "cc", "0", "1" );
+                : "=&a" (res), "=&d" (cmp), "=&a" (count)
+		: "a" (size), "a" (addr), "a" (&_zb_findmap) : "cc" );
         return (res < size) ? res : size;
 }
 
@@ -650,7 +657,7 @@
 find_next_zero_bit (void * addr, unsigned long size, unsigned long offset)
 {
         unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
-        unsigned long bitvec;
+        unsigned long bitvec, reg;
         unsigned long set, bit = offset & 63, res;
 
         if (bit) {
@@ -658,28 +665,26 @@
                  * Look for zero in first word
                  */
                 bitvec = (*p) >> bit;
-                __asm__("   lhi  0,-1\n"
-                        "   lgr  1,%1\n"
+                __asm__("   lhi  %2,-1\n"
                         "   slgr %0,%0\n"
-                        "   clr  1,0\n"
+                        "   clr  %1,%2\n"
                         "   jne  0f\n"
                         "   aghi %0,32\n"
-                        "   srlg 1,1,32\n"
-			"0: lghi 0,0xff\n"
-                        "   tmll 1,0xffff\n"
+                        "   srlg %1,%1,32\n"
+			"0: lghi %2,0xff\n"
+                        "   tmll %1,0xffff\n"
                         "   jno  1f\n"
                         "   aghi %0,16\n"
-                        "   srlg 1,1,16\n"
-                        "1: tmll 1,0x00ff\n"
+                        "   srlg %1,%1,16\n"
+                        "1: tmll %1,0x00ff\n"
                         "   jno  2f\n"
                         "   aghi %0,8\n"
-                        "   srlg 1,1,8\n"
-                        "2: ngr  1,0\n"
-                        "   ic   1,0(1,%2)\n"
-                        "   algr %0,1"
-                        : "=&d" (set) 
-                        : "d" (bitvec), "a" (&_zb_findmap)
-                        : "cc", "0", "1" );
+                        "   srlg %1,%1,8\n"
+                        "2: ngr  %1,%2\n"
+                        "   ic   %1,0(%1,%3)\n"
+                        "   algr %0,%1"
+                        : "=&d" (set), "+a" (bitvec), "=&d" (reg)
+                        : "a" (&_zb_findmap) : "cc" );
                 if (set < (64 - bit))
                         return set + offset;
                 offset += 64 - bit;
@@ -698,31 +703,29 @@
  */
 static __inline__ unsigned long ffz(unsigned long word)
 {
+	unsigned long reg;
         int result;
 
-        __asm__("   lhi  0,-1\n"
-                "   lgr  1,%1\n"
+        __asm__("   lhi  %2,-1\n"
                 "   slgr %0,%0\n"
-                "   clr  1,0\n"
+                "   clr  %1,%2\n"
                 "   jne  0f\n"
                 "   aghi %0,32\n"
-                "   srlg 1,1,32\n"
-                "0: lghi 0,0xff\n"
-                "   tmll 1,0xffff\n"
+                "   srlg %1,%1,32\n"
+                "0: lghi %2,0xff\n"
+                "   tmll %1,0xffff\n"
                 "   jno  1f\n"
                 "   aghi %0,16\n"
-                "   srlg 1,1,16\n"
-                "1: tmll 1,0x00ff\n"
+                "   srlg %1,%1,16\n"
+                "1: tmll %1,0x00ff\n"
                 "   jno  2f\n"
                 "   aghi %0,8\n"
-                "   srlg 1,1,8\n"
-                "2: ngr  1,0\n"
-                "   ic   1,0(1,%2)\n"
-                "   algr %0,1"
-                : "=&d" (result)
-                : "d" (word), "a" (&_zb_findmap)
-                : "cc", "0", "1" );
-
+                "   srlg %1,%1,8\n"
+                "2: ngr  %1,%2\n"
+                "   ic   %1,0(%1,%3)\n"
+                "   algr %0,%1"
+                : "=&d" (result), "+a" (word), "=&d" (reg)
+                : "a" (&_zb_findmap) : "cc" );
         return result;
 }
 
@@ -738,29 +741,28 @@
 
         if (x == 0)
           return 0;
-        __asm__("    lr   1,%1\n"
-                "    slr  %0,%0\n"
-                "    tml  1,0xFFFF\n"
+        __asm__("    slr  %0,%0\n"
+                "    tml  %1,0xffff\n"
                 "    jnz  0f\n"
                 "    ahi  %0,16\n"
-                "    srl  1,16\n"
-                "0:  tml  1,0x00FF\n"
+                "    srl  %1,16\n"
+                "0:  tml  %1,0x00ff\n"
                 "    jnz  1f\n"
                 "    ahi  %0,8\n"
-                "    srl  1,8\n"
-                "1:  tml  1,0x000F\n"
+                "    srl  %1,8\n"
+                "1:  tml  %1,0x000f\n"
                 "    jnz  2f\n"
                 "    ahi  %0,4\n"
-                "    srl  1,4\n"
-                "2:  tml  1,0x0003\n"
+                "    srl  %1,4\n"
+                "2:  tml  %1,0x0003\n"
                 "    jnz  3f\n"
                 "    ahi  %0,2\n"
-                "    srl  1,2\n"
-                "3:  tml  1,0x0001\n"
+                "    srl  %1,2\n"
+                "3:  tml  %1,0x0001\n"
                 "    jnz  4f\n"
                 "    ahi  %0,1\n"
                 "4:"
-                : "=&d" (r) : "d" (x) : "cc", "1" );
+                : "=&d" (r), "+d" (x) : : "cc" );
         return r+1;
 }
 
@@ -792,42 +794,42 @@
 static __inline__ unsigned long
 ext2_find_first_zero_bit(void *vaddr, unsigned long size)
 {
-        unsigned long res;
+        unsigned long res, cmp, count;
 
         if (!size)
                 return 0;
-        __asm__("   lghi  0,-1\n"
-                "   lgr   1,%1\n"
-                "   aghi  1,63\n"
-                "   srlg  1,1,6\n"
+        __asm__("   lghi  %1,-1\n"
+                "   lgr   %2,%3\n"
+                "   aghi  %2,63\n"
+                "   srlg  %2,%2,6\n"
                 "   slgr  %0,%0\n"
-                "0: clg   0,0(%0,%2)\n"
+                "0: clg   %1,0(%0,%4)\n"
                 "   jne   1f\n"
                 "   aghi  %0,8\n"
-                "   brct  1,0b\n"
-                "   lgr   %0,%1\n"
+                "   brct  %2,0b\n"
+                "   lgr   %0,%3\n"
                 "   j     5f\n"
-                "1: cl    0,0(%0,%2)\n"
+                "1: cl    %1,0(%0,%4)\n"
 		"   jne   2f\n"
 		"   aghi  %0,4\n"
-		"2: l     1,0(%0,%2)\n"
+		"2: l     %2,0(%0,%4)\n"
                 "   sllg  %0,%0,3\n"
                 "   aghi  %0,24\n"
-                "   lghi  0,0xff\n"
-                "   tmlh  1,0xffff\n"
+                "   lghi  %1,0xff\n"
+                "   tmlh  %2,0xffff\n"
                 "   jo    3f\n"
                 "   aghi  %0,-16\n"
-                "   srl   1,16\n"
-                "3: tmll  1,0xff00\n"
+                "   srl   %2,16\n"
+                "3: tmll  %2,0xff00\n"
                 "   jo    4f\n"
                 "   aghi  %0,-8\n"
-                "   srl   1,8\n"
-                "4: ngr   1,0\n"
-                "   ic    1,0(1,%3)\n"
-                "   algr  %0,1\n"
+                "   srl   %2,8\n"
+                "4: ngr   %2,%1\n"
+                "   ic    %2,0(%2,%5)\n"
+                "   algr  %0,%2\n"
                 "5:"
-                : "=&a" (res) : "a" (size), "a" (vaddr), "a" (&_zb_findmap)
-                : "cc", "0", "1" );
+                : "=&a" (res), "=&d" (cmp), "=&a" (count)
+		: "a" (size), "a" (vaddr), "a" (&_zb_findmap) : "cc" );
         return (res < size) ? res : size;
 }
 
@@ -836,7 +838,7 @@
 {
         unsigned long *addr = vaddr;
         unsigned long *p = addr + (offset >> 6);
-        unsigned long word;
+        unsigned long word, reg;
         unsigned long bit = offset & 63UL, res;
 
         if (offset >= size)
@@ -848,30 +850,28 @@
                 word >>= bit;
                 res = bit;
                 /* Look for zero in first 8 byte word */
-                __asm__("   lgr  1,%1\n"
-                        "   lghi 0,0xff\n"
-			"   tmll 1,0xffff\n"
+                __asm__("   lghi %2,0xff\n"
+			"   tmll %1,0xffff\n"
 			"   jno  2f\n"
 			"   ahi  %0,16\n"
-			"   srlg 1,1,16\n"
-                	"0: tmll 1,0xffff\n"
+			"   srlg %1,%1,16\n"
+                	"0: tmll %1,0xffff\n"
                         "   jno  2f\n"
                         "   ahi  %0,16\n"
-                        "   srlg 1,1,16\n"
-                        "1: tmll 1,0xffff\n"
+                        "   srlg %1,%1,16\n"
+                        "1: tmll %1,0xffff\n"
                         "   jno  2f\n"
                         "   ahi  %0,16\n"
-                        "   srl  1,16\n"
-                        "2: tmll 1,0x00ff\n"
+                        "   srl  %1,16\n"
+                        "2: tmll %1,0x00ff\n"
                 	"   jno  3f\n"
                 	"   ahi  %0,8\n"
-                	"   srl  1,8\n"
-                	"3: ngr  1,0\n"
-                	"   ic   1,0(1,%2)\n"
-                	"   alr  %0,1"
-                	: "+&d" (res) 
-                  	: "d" (word), "a" (&_zb_findmap)
-                	: "cc", "0", "1" );
+                	"   srl  %1,8\n"
+                	"3: ngr  %1,%2\n"
+                	"   ic   %1,0(%1,%3)\n"
+                	"   alr  %0,%1"
+                	: "+&d" (res), "+a" (word), "=&d" (reg)
+                  	: "a" (&_zb_findmap) : "cc" );
                 if (res < 64)
 			return (p - addr)*64 + res;
                 p++;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/debug.h linux/include/asm-s390x/debug.h
--- linux.orig/include/asm-s390x/debug.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390x/debug.h	2002-07-20 01:08:38.000000000 +0000
@@ -54,7 +54,7 @@
 #define DEBUG_DATA(entry) (char*)(entry + 1) /* data is stored behind */
                                              /* the entry information */
 
-#define STCK(x)	asm volatile ("STCK %0" : "=m" (x) : : "cc" )
+#define STCK(x)	asm volatile ("STCK 0(%0)" : : "a" (&(x)) : "memory", "cc")
 
 typedef struct __debug_entry debug_entry_t;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/ebcdic.h linux/include/asm-s390x/ebcdic.h
--- linux.orig/include/asm-s390x/ebcdic.h	2001-07-04 18:50:39.000000000 +0000
+++ linux/include/asm-s390x/ebcdic.h	2002-07-20 01:08:33.000000000 +0000
@@ -24,7 +24,7 @@
 extern __inline__ void
 codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr)
 {
-	if (nr <= 0)
+	if (nr-- <= 0)
 		return;
         __asm__ __volatile__(
 		"   bras  1,1f\n"
@@ -34,7 +34,7 @@
 		"1: ahi   %1,-256\n"
 		"   jp    0b\n"
 		"   ex    %1,0(1)"
-		: "+&a" (addr), "+&a" (nr-1)
+		: "+&a" (addr), "+&a" (nr)
 		: "a" (codepage) : "cc", "memory", "1" );
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/ide.h linux/include/asm-s390x/ide.h
--- linux.orig/include/asm-s390x/ide.h	2001-02-13 22:13:44.000000000 +0000
+++ linux/include/asm-s390x/ide.h	2002-07-20 01:08:22.000000000 +0000
@@ -26,7 +26,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+	} b;
+} control_t;
 
 #define ide_request_irq(irq,hand,flg,dev,id)	do {} while (0)
 #define ide_free_irq(irq,dev_id)		do {} while (0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/irq.h linux/include/asm-s390x/irq.h
--- linux.orig/include/asm-s390x/irq.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-s390x/irq.h	2002-07-20 01:08:33.000000000 +0000
@@ -630,11 +630,6 @@
                 "   .align 8\n"
                 "   .quad 0b,2b\n"
                 ".previous"
-                "    lr   1,%1\n"
-                "    msch 0(%2)\n"
-                "0:  ipm  %0\n"
-                "    srl  %0,28\n"
-                "1:\n"
 #else
                 ".section .fixup,\"ax\"\n"
                 "2:  l    %0,%3\n"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/lowcore.h linux/include/asm-s390x/lowcore.h
--- linux.orig/include/asm-s390x/lowcore.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390x/lowcore.h	2002-07-20 01:08:39.000000000 +0000
@@ -62,7 +62,7 @@
 #define _SVC_PSW_MASK        0x0400000180000000
 #define _MCCK_PSW_MASK       0x0400000180000000
 #define _IO_PSW_MASK         0x0400000180000000
-#define _USER_PSW_MASK       0x0701C00180000000
+#define _USER_PSW_MASK       0x0705C00180000000
 #define _WAIT_PSW_MASK       0x0706000180000000
 #define _DW_PSW_MASK         0x0002000180000000
 
@@ -200,12 +200,12 @@
 extern struct _lowcore *lowcore_ptr[];
 
 #ifndef CONFIG_SMP
-#define get_cpu_lowcore(cpu)    S390_lowcore
-#define safe_get_cpu_lowcore(cpu) S390_lowcore
+#define get_cpu_lowcore(cpu)      (&S390_lowcore)
+#define safe_get_cpu_lowcore(cpu) (&S390_lowcore)
 #else
-#define get_cpu_lowcore(cpu)    (*lowcore_ptr[cpu])
+#define get_cpu_lowcore(cpu)      (lowcore_ptr[(cpu)])
 #define safe_get_cpu_lowcore(cpu) \
-        ((cpu)==smp_processor_id() ? S390_lowcore:(*lowcore_ptr[(cpu)]))
+        ((cpu) == smp_processor_id() ? &S390_lowcore : lowcore_ptr[(cpu)])
 #endif
 #endif /* __ASSEMBLY__ */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/page.h linux/include/asm-s390x/page.h
--- linux.orig/include/asm-s390x/page.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390x/page.h	2002-07-20 01:08:22.000000000 +0000
@@ -117,6 +117,9 @@
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif                                 /* __KERNEL__                       */
 
 #endif                                 /* _S390_PAGE_H                     */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/pgtable.h linux/include/asm-s390x/pgtable.h
--- linux.orig/include/asm-s390x/pgtable.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390x/pgtable.h	2002-07-20 01:08:34.000000000 +0000
@@ -38,6 +38,7 @@
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_icache_range(start, end)          do { } while (0)
 #define flush_icache_page(vma,pg)               do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 /*
  * The S390 doesn't have any external MMU info: the kernel page
@@ -233,10 +234,6 @@
 	*pteptr = pteval;
 }
 
-/*
- * Permanent address of a page.
- */
-#define page_address(page) ((page)->virtual)
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/processor.h linux/include/asm-s390x/processor.h
--- linux.orig/include/asm-s390x/processor.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390x/processor.h	2002-07-20 01:08:30.000000000 +0000
@@ -149,8 +149,8 @@
 }
 
 unsigned long get_wchan(struct task_struct *p);
-#define __KSTK_PTREGS(tsk) \
-	((struct pt_regs *)((unsigned long) tsk+THREAD_SIZE) - 1)
+#define __KSTK_PTREGS(tsk) ((struct pt_regs *) \
+        (((unsigned long) tsk + THREAD_SIZE - sizeof(struct pt_regs)) & -8L))
 #define KSTK_EIP(tsk)	(__KSTK_PTREGS(tsk)->psw.addr)
 #define KSTK_ESP(tsk)	(__KSTK_PTREGS(tsk)->gprs[15])
 
@@ -182,6 +182,43 @@
 #define PSW_PROBLEM_STATE       0x0001000000000000UL
 
 /*
+ * Set PSW mask to specified value, while leaving the
+ * PSW addr pointing to the next instruction.
+ */
+
+static inline void __load_psw_mask (unsigned long mask)
+{
+	unsigned long addr;
+
+	psw_t psw;
+	psw.mask = mask;
+
+	asm volatile (
+		"    larl  %0,1f\n"
+		"    stg   %0,8(%1)\n"
+		"    lpswe 0(%1)\n"
+		"1:"
+		: "=&d" (addr) : "a" (&psw) : "memory", "cc" );
+}
+
+/*
+ * Function to stop a processor until an interruption occured
+ */
+static inline void enabled_wait(void)
+{
+	unsigned long reg;
+	psw_t wait_psw;
+
+	wait_psw.mask = 0x0706000180000000;
+	asm volatile (
+		"    larl  %0,0f\n"
+		"    stg   %0,8(%1)\n"
+		"    lpswe 0(%1)\n"
+		"0:"
+		: "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
+}
+
+/*
  * Function to drop a processor into disabled wait state
  */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/ptrace.h linux/include/asm-s390x/ptrace.h
--- linux.orig/include/asm-s390x/ptrace.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390x/ptrace.h	2002-07-20 01:08:28.000000000 +0000
@@ -154,7 +154,6 @@
 	__u32 acrs[NUM_ACRS];
 	__u64 orig_gpr2;
 	__u32 trap;
-	__u32 old_ilc;
 } __attribute__ ((packed));
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/rwsem.h linux/include/asm-s390x/rwsem.h
--- linux.orig/include/asm-s390x/rwsem.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-s390x/rwsem.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,209 @@
+#ifndef _S390X_RWSEM_H
+#define _S390X_RWSEM_H
+
+/*
+ *  include/asm-s390x/rwsem.h
+ *
+ *  S390 version
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *
+ *  Based on asm-alpha/semaphore.h and asm-i386/rwsem.h
+ */
+
+/*
+ *
+ * The MSW of the count is the negated number of active writers and waiting
+ * lockers, and the LSW is the total number of active locks
+ *
+ * The lock count is initialized to 0 (no active and no waiting lockers).
+ *
+ * When a writer subtracts WRITE_BIAS, it'll get 0xffff0001 for the case of an
+ * uncontended lock. This can be determined because XADD returns the old value.
+ * Readers increment by 1 and see a positive value when uncontended, negative
+ * if there are writers (and maybe) readers waiting (in which case it goes to
+ * sleep).
+ *
+ * The value of WAITING_BIAS supports up to 32766 waiting processes. This can
+ * be extended to 65534 by manually checking the whole MSW rather than relying
+ * on the S flag.
+ *
+ * The value of ACTIVE_BIAS supports up to 65535 active processes.
+ *
+ * This should be totally fair - if anything is waiting, a process that wants a
+ * lock will go to the back of the queue. When the currently active lock is
+ * released, if there's a writer at the front of the queue, then that and only
+ * that will be woken up; if there's a bunch of consequtive readers at the
+ * front, then they'll all be woken up, but no other readers will be.
+ */
+
+#ifndef _LINUX_RWSEM_H
+#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
+#endif
+
+#ifdef __KERNEL__
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+struct rwsem_waiter;
+
+extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *);
+
+/*
+ * the semaphore definition
+ */
+struct rw_semaphore {
+	signed long		count;
+	spinlock_t		wait_lock;
+	struct list_head	wait_list;
+};
+
+#define RWSEM_UNLOCKED_VALUE	0x0000000000000000L
+#define RWSEM_ACTIVE_BIAS	0x0000000000000001L
+#define RWSEM_ACTIVE_MASK	0x00000000ffffffffL
+#define RWSEM_WAITING_BIAS	(-0x0000000100000000L)
+#define RWSEM_ACTIVE_READ_BIAS	RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS	(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+
+/*
+ * initialisation
+ */
+#define __RWSEM_INITIALIZER(name) \
+{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) }
+
+#define DECLARE_RWSEM(name) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+static inline void init_rwsem(struct rw_semaphore *sem)
+{
+	sem->count = RWSEM_UNLOCKED_VALUE;
+	spin_lock_init(&sem->wait_lock);
+	INIT_LIST_HEAD(&sem->wait_list);
+}
+
+/*
+ * lock for reading
+ */
+static inline void __down_read(struct rw_semaphore *sem)
+{
+	signed long old, new;
+
+	__asm__ __volatile__(
+		"   lg   %0,0(%2)\n"
+		"0: lgr  %1,%0\n"
+		"   aghi %1,%3\n"
+		"   csg  %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
+		: "cc", "memory" );
+	if (old < 0)
+		rwsem_down_read_failed(sem);
+}
+
+/*
+ * lock for writing
+ */
+static inline void __down_write(struct rw_semaphore *sem)
+{
+	signed long old, new, tmp;
+
+	tmp = RWSEM_ACTIVE_WRITE_BIAS;
+	__asm__ __volatile__(
+		"   lg   %0,0(%2)\n"
+		"0: lgr  %1,%0\n"
+		"   ag   %1,%3\n"
+		"   csg  %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "m" (tmp)
+		: "cc", "memory" );
+	if (old != 0)
+		rwsem_down_write_failed(sem);
+}
+
+/*
+ * unlock after reading
+ */
+static inline void __up_read(struct rw_semaphore *sem)
+{
+	signed long old, new;
+
+	__asm__ __volatile__(
+		"   lg   %0,0(%2)\n"
+		"0: lgr  %1,%0\n"
+		"   aghi %1,%3\n"
+		"   csg  %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS)
+		: "cc", "memory" );
+	if (new < 0)
+		if ((int) new == 0)
+			rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void __up_write(struct rw_semaphore *sem)
+{
+	signed long old, new, tmp;
+
+	tmp = -RWSEM_ACTIVE_WRITE_BIAS;
+	__asm__ __volatile__(
+		"   lg   %0,0(%2)\n"
+		"0: lgr  %1,%0\n"
+		"   ag   %1,%3\n"
+		"   csg  %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "m" (tmp)
+		: "cc", "memory" );
+	if (new < 0)
+		if ((int) new == 0)
+			rwsem_wake(sem);
+}
+
+/*
+ * implement atomic add functionality
+ */
+static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
+{
+	signed long old, new;
+
+	__asm__ __volatile__(
+		"   lg   %0,0(%2)\n"
+		"0: lgr  %1,%0\n"
+		"   agr  %1,%3\n"
+		"   csg  %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "d" (delta)
+		: "cc", "memory" );
+}
+
+/*
+ * implement exchange and add functionality
+ */
+static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
+{
+	signed long old, new;
+
+	__asm__ __volatile__(
+		"   lg   %0,0(%2)\n"
+		"0: lgr  %1,%0\n"
+		"   agr  %1,%3\n"
+		"   csg  %0,%1,0(%2)\n"
+		"   jl   0b"
+                : "=&d" (old), "=&d" (new)
+		: "a" (&sem->count), "d" (delta)
+		: "cc", "memory" );
+	return new;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _S390X_RWSEM_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/siginfo.h linux/include/asm-s390x/siginfo.h
--- linux.orig/include/asm-s390x/siginfo.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390x/siginfo.h	2002-07-20 01:08:39.000000000 +0000
@@ -115,6 +115,7 @@
 #define SI_MESGQ	-3	/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4	/* sent by AIO completion */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
+#define SI_TKILL	-6	/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/sigp.h linux/include/asm-s390x/sigp.h
--- linux.orig/include/asm-s390x/sigp.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390x/sigp.h	2002-07-20 01:08:34.000000000 +0000
@@ -130,6 +130,6 @@
    return ccode;
 }
 
-#endif __SIGP__
+#endif /* __SIGP__ */
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/spinlock.h linux/include/asm-s390x/spinlock.h
--- linux.orig/include/asm-s390x/spinlock.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/asm-s390x/spinlock.h	2002-07-20 01:08:27.000000000 +0000
@@ -29,22 +29,24 @@
 
 extern inline void spin_lock(spinlock_t *lp)
 {
-        __asm__ __volatile("    bras  1,1f\n"
+	unsigned long reg1, reg2;
+        __asm__ __volatile("    bras  %1,1f\n"
                            "0:  # diag  0,0,68\n"
-                           "1:  slr   0,0\n"
-                           "    cs    0,1,0(%0)\n"
+                           "1:  slr   %0,%0\n"
+                           "    cs    %0,%1,0(%2)\n"
                            "    jl    0b\n"
-                           : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
+                           : "=&d" (reg1), "=&d" (reg2)
+                           : "a" (&lp->lock) : "cc", "memory" );
 }
 
 extern inline int spin_trylock(spinlock_t *lp)
 {
-	unsigned int result;
+	unsigned int result, reg;
 	__asm__ __volatile("    slr   %0,%0\n"
-			   "    basr  1,0\n"
-			   "0:  cs    %0,1,0(%1)"
-			   : "=&d" (result)
-			   : "a" (&lp->lock) : "1", "cc", "memory" );
+			   "    basr  %1,0\n"
+			   "0:  cs    %0,%1,0(%2)"
+			   : "=&d" (result), "=&d" (reg)
+			   : "a" (&lp->lock) : "cc", "memory" );
 	return !result;
 }
 
@@ -82,7 +84,7 @@
                      "   la    3,1(2)\n"   /* one more reader */  \
                      "   csg   2,3,0(%0)\n" /* try to write new value */ \
                      "   jl    0b"       \
-                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
 
 #define read_unlock(rw) \
         asm volatile("   lg    2,0(%0)\n"   \
@@ -92,7 +94,7 @@
                      "   bctgr 3,0\n"    /* one less reader */ \
                      "   csg   2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
 
 #define write_lock(rw) \
         asm volatile("   llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
@@ -101,7 +103,7 @@
                      "1: slgr  2,2\n"      /* old lock value must be 0 */ \
                      "   csg   2,3,0(%0)\n" \
                      "   jl    0b"         \
-                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
 
 #define write_unlock(rw) \
         asm volatile("   slgr  3,3\n"      /* new lock value = 0 */ \
@@ -110,7 +112,7 @@
                      "1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\
                      "   csg   2,3,0(%0)\n"   \
                      "   jl    0b"         \
-                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" )
 
 #endif /* __ASM_SPINLOCK_H */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/system.h linux/include/asm-s390x/system.h
--- linux.orig/include/asm-s390x/system.h	2001-07-25 21:12:03.000000000 +0000
+++ linux/include/asm-s390x/system.h	2002-07-20 01:08:40.000000000 +0000
@@ -12,6 +12,7 @@
 #define __ASM_SYSTEM_H
 
 #include <linux/config.h>
+#include <asm/types.h>
 #ifdef __KERNEL__
 #include <asm/lowcore.h>
 #endif
@@ -23,7 +24,7 @@
                 break;                                                       \
 	save_fp_regs(&prev->thread.fp_regs);                                 \
 	restore_fp_regs(&next->thread.fp_regs);              		     \
-	last = resume(&prev->thread,&next->thread);                          \
+	last = resume(prev,next);					     \
 } while (0)
 
 struct task_struct;
@@ -110,8 +111,6 @@
                                 : "+d" (x) : "a" (ptr)
                                 : "memory", "cc", "0" );
                         break;
-               default:
-                        abort();
         }
         return x;
 }
@@ -144,24 +143,24 @@
 #define __sti() ({ \
         unsigned long dummy; \
         __asm__ __volatile__ ( \
-                "stosm %0,0x03" : "=m" (dummy) : : "memory"); \
+                "stosm 0(%0),0x03" : : "a" (&dummy) : "memory"); \
         })
 
 #define __cli() ({ \
         unsigned long flags; \
         __asm__ __volatile__ ( \
-                "stnsm %0,0xFC" : "=m" (flags) : : "memory"); \
+                "stnsm 0(%0),0xFC" : : "a" (&flags) : "memory"); \
         flags; \
         })
 
 #define __save_flags(x) \
-        __asm__ __volatile__("stosm %0,0" : "=m" (x) : : "memory")
+        __asm__ __volatile__("stosm 0(%0),0" : : "a" (&x) : "memory")
 
 #define __restore_flags(x) \
-        __asm__ __volatile__("ssm   %0" : : "m" (x) : "memory")
+        __asm__ __volatile__("ssm   0(%0)" : : "a" (&x) : "memory")
 
 #define __load_psw(psw) \
-        __asm__ __volatile__("lpswe %0" : : "m" (psw) : "cc" );
+        __asm__ __volatile__("lpswe 0(%0)" : : "a" (&psw) : "cc" );
 
 #define __ctl_load(array, low, high) ({ \
 	__asm__ __volatile__ ( \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/timex.h linux/include/asm-s390x/timex.h
--- linux.orig/include/asm-s390x/timex.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390x/timex.h	2002-07-20 01:08:28.000000000 +0000
@@ -25,8 +25,16 @@
 {
 	cycles_t cycles;
 
-	__asm__("stck  %0" : "=m" (cycles) : : "cc");
+	__asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
 	return cycles >> 2;
 }
 
+static inline unsigned long long get_clock (void)
+{
+	unsigned long long clock;
+
+	__asm__("stck 0(%0)" : : "a" (&(clock)) : "memory", "cc");
+	return clock;
+}
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/uaccess.h linux/include/asm-s390x/uaccess.h
--- linux.orig/include/asm-s390x/uaccess.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-s390x/uaccess.h	2002-07-20 01:08:24.000000000 +0000
@@ -175,42 +175,37 @@
  */
 #define __put_user(x, ptr)                                      \
 ({                                                              \
+        __typeof__(*(ptr)) *__pu_addr = (ptr);                  \
+        __typeof__(*(ptr)) __x = (x);                           \
         int __pu_err;                                           \
-        switch (sizeof (*(ptr))) {                              \
-                case 1:                                         \
-                        __pu_err = __put_user_asm_1((__u8)(__u64)(x),(ptr));\
-                        break;                                  \
-                case 2:                                         \
-                        __pu_err = __put_user_asm_2((__u16)(__u64)(x),(ptr));\
-                        break;                                  \
-                case 4:                                         \
-                        __pu_err = __put_user_asm_4((__u32)(__u64)(x),(ptr));\
-                        break;                                  \
-                case 8:                                         \
-                        __pu_err = __put_user_asm_8((__u64)(x),(ptr));\
-                        break;                                  \
-                default:                                        \
+        switch (sizeof (*(__pu_addr))) {                        \
+        case 1:                                                 \
+                __pu_err = __put_user_asm_1((__u8)(__u64)(__x), \
+                                            __pu_addr);         \
+                break;                                          \
+        case 2:                                                 \
+                __pu_err = __put_user_asm_2((__u16)(__u64)(__x),\
+                                            __pu_addr);         \
+                break;                                          \
+        case 4:                                                 \
+                __pu_err = __put_user_asm_4((__u32)(__u64)(__x),\
+                                            __pu_addr);         \
+                break;                                          \
+        case 8:                                                 \
+                __pu_err = __put_user_asm_8((__u64)(__x),       \
+                                            __pu_addr);         \
+                break;                                          \
+        default:                                                \
                 __pu_err = __put_user_bad();                    \
                 break;                                          \
          }                                                      \
         __pu_err;                                               \
 })
 
-#define put_user(x, ptr)                                        \
-({                                                              \
-        long __pu_err = -EFAULT;                                \
-        __typeof__(*(ptr)) *__pu_addr = (ptr);                  \
-        __typeof__(*(ptr)) __x = (x);                           \
-        if (__access_ok((long)__pu_addr,sizeof(*(ptr)))) {      \
-                __pu_err = 0;                                   \
-                __put_user((__x), (__pu_addr));                 \
-        }                                                       \
-        __pu_err;                                               \
-})
+#define put_user(x, ptr) __put_user(x, ptr)
 
 extern int __put_user_bad(void);
 
-
 #define __get_user_asm_8(x, ptr, err)                                      \
 ({                                                                         \
         __asm__ __volatile__ (  "   sr    %1,%1\n"                         \
@@ -293,42 +288,32 @@
 
 #define __get_user(x, ptr)                                      \
 ({                                                              \
+        __typeof__(ptr) __gu_addr = (ptr);                      \
+        __typeof__(*(ptr)) __x;                                 \
         int __gu_err;                                           \
         switch (sizeof(*(ptr))) {                               \
-                case 1:                                         \
-                        __get_user_asm_1(x,ptr,__gu_err);       \
-                        break;                                  \
-                case 2:                                         \
-                        __get_user_asm_2(x,ptr,__gu_err);       \
-                        break;                                  \
-                case 4:                                         \
-                        __get_user_asm_4(x,ptr,__gu_err);       \
-                        break;                                  \
-                case 8:                                         \
-                        __get_user_asm_8(x,ptr,__gu_err);       \
-                        break;                                  \
-                default:                                        \
-                        (x) = 0;                                \
-                        __gu_err = __get_user_bad();            \
+        case 1:                                                 \
+                __get_user_asm_1(__x,__gu_addr,__gu_err);       \
+                break;                                          \
+        case 2:                                                 \
+                __get_user_asm_2(__x,__gu_addr,__gu_err);       \
+                break;                                          \
+        case 4:                                                 \
+                __get_user_asm_4(__x,__gu_addr,__gu_err);       \
+                break;                                          \
+        case 8:                                                 \
+                __get_user_asm_8(__x,__gu_addr,__gu_err);       \
+                break;                                          \
+        default:                                                \
+                __x = 0;                                        \
+                __gu_err = __get_user_bad();                    \
                 break;                                          \
         }                                                       \
+        (x) = __x;                                              \
         __gu_err;                                               \
 })
 
-#define get_user(x, ptr)                                        \
-({                                                              \
-        long __gu_err = -EFAULT;                                \
-        __typeof__(ptr) __gu_addr = (ptr);                      \
-        __typeof__(*(ptr)) __x;                                 \
-        if (__access_ok((long)__gu_addr,sizeof(*(ptr)))) {      \
-                __gu_err = 0;                                   \
-                __get_user((__x), (__gu_addr));                 \
-                (x) = __x;                                      \
-        }                                                       \
-        else                                                    \
-                (x) = 0;                                        \
-        __gu_err;                                               \
-})
+#define get_user(x, ptr) __get_user(x, ptr)
 
 extern int __get_user_bad(void);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-s390x/unistd.h linux/include/asm-s390x/unistd.h
--- linux.orig/include/asm-s390x/unistd.h	2001-10-11 16:43:38.000000000 +0000
+++ linux/include/asm-s390x/unistd.h	2002-07-20 01:08:26.000000000 +0000
@@ -180,7 +180,11 @@
 #define __NR_pivot_root         217
 #define __NR_mincore            218
 #define __NR_madvise            219
-#define __NR_getdents64         220
+/*
+ * Numbers 224-235 are reserved for posix acl
+ */
+#define __NR_gettid		236
+#define __NR_tkill		237
 
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sh/ide.h linux/include/asm-sh/ide.h
--- linux.orig/include/asm-sh/ide.h	2001-09-08 19:29:09.000000000 +0000
+++ linux/include/asm-sh/ide.h	2002-07-20 01:08:29.000000000 +0000
@@ -116,7 +116,19 @@
 		unsigned lba		: 1;	/* using LBA instead of CHS */
 		unsigned bit7		: 1;	/* always 1 */
 	} b;
-	} select_t;
+} select_t;
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit0		: 1;
+		unsigned nIEN		: 1;	/* device INTRQ to host */
+		unsigned SRST		: 1;	/* host soft reset bit */
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned reserved456	: 3;
+		unsigned HOB		: 1;	/* 48-bit address ordering */
+	} b;
+} control_t;
 
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
 #define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sh/pgtable.h linux/include/asm-sh/pgtable.h
--- linux.orig/include/asm-sh/pgtable.h	2001-11-11 18:20:21.000000000 +0000
+++ linux/include/asm-sh/pgtable.h	2002-07-20 01:08:37.000000000 +0000
@@ -41,6 +41,7 @@
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_icache_range(start, end)		do { } while (0)
 #define flush_icache_page(vma,pg)		do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 #define flush_cache_sigtramp(vaddr)		do { } while (0)
 
 #define p3_cache_init()				do { } while (0)
@@ -64,6 +65,7 @@
 
 #define flush_page_to_ram(page)			do { } while (0)
 #define flush_icache_page(vma,pg)		do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 /* Initialization of P3 area for copy_user_page */
 extern void p3_cache_init(void);
@@ -206,11 +208,6 @@
 #define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
 #define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
 
-/*
- * Permanent address of a page. Obviously must never be
- * called on a highmem page.
- */
-#define page_address(page)  ((page)->virtual) /* P1 address of the page */
 #define pages_to_mb(x)	((x) >> (20-PAGE_SHIFT))
 #define pte_page(x) 	phys_to_page(pte_val(x)&PTE_PHYS_MASK)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sh/siginfo.h linux/include/asm-sh/siginfo.h
--- linux.orig/include/asm-sh/siginfo.h	2001-01-04 21:19:13.000000000 +0000
+++ linux/include/asm-sh/siginfo.h	2002-07-20 01:08:32.000000000 +0000
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sh/unistd.h linux/include/asm-sh/unistd.h
--- linux.orig/include/asm-sh/unistd.h	2000-10-02 18:57:34.000000000 +0000
+++ linux/include/asm-sh/unistd.h	2002-07-20 01:08:31.000000000 +0000
@@ -231,6 +231,8 @@
 #define __NR_madvise		219
 #define __NR_getdents64		220
 #define __NR_fcntl64		221
+#define __NR_gettid		222
+#define __NR_tkill		223
 
 /* user-visible error numbers are in the range -1 - -125: see <asm-sh/errno.h> */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/apc.h linux/include/asm-sparc/apc.h
--- linux.orig/include/asm-sparc/apc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-sparc/apc.h	2002-07-20 01:08:21.000000000 +0000
@@ -0,0 +1,64 @@
+/* apc - Driver definitions for power management functions
+ * of Aurora Personality Chip (APC) on SPARCstation-4/5 and 
+ * derivatives
+ *
+ * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
+ *
+ */
+
+#ifndef _SPARC_APC_H
+#define _SPARC_APC_H
+
+#include <linux/ioctl.h>
+
+#define APC_IOC	'A'
+
+#define APCIOCGFANCTL _IOR(APC_IOC, 0x00, int)	/* Get fan speed	*/
+#define APCIOCSFANCTL _IOW(APC_IOC, 0x01, int)	/* Set fan speed	*/
+
+#define APCIOCGCPWR   _IOR(APC_IOC, 0x02, int)	/* Get CPOWER state	*/
+#define APCIOCSCPWR   _IOW(APC_IOC, 0x03, int)	/* Set CPOWER state	*/
+
+#define APCIOCGBPORT   _IOR(APC_IOC, 0x04, int)	/* Get BPORT state 	*/
+#define APCIOCSBPORT   _IOW(APC_IOC, 0x05, int)	/* Set BPORT state	*/
+
+/*
+ * Register offsets
+ */
+#define APC_IDLE_REG	0x00
+#define APC_FANCTL_REG	0x20
+#define APC_CPOWER_REG	0x24
+#define APC_BPORT_REG	0x30
+
+#define APC_REGMASK		0x01
+#define APC_BPMASK		0x03
+
+/*
+ * IDLE - CPU standby values (set to initiate standby)
+ */
+#define APC_IDLE_ON		0x01
+
+/*
+ * FANCTL - Fan speed control state values
+ */
+#define APC_FANCTL_HI	0x00	/* Fan speed high	*/
+#define APC_FANCTL_LO	0x01	/* Fan speed low	*/
+
+/*
+ * CPWR - Convenience power outlet state values 
+ */
+#define APC_CPOWER_ON	0x00	/* Conv power on	*/
+#define APC_CPOWER_OFF	0x01	/* Conv power off	*/
+
+/*
+ * BPA/BPB - Read-Write "Bit Ports" state values (reset to 0 at power-on)
+ *
+ * WARNING: Internal usage of bit ports is platform dependent--
+ * don't modify BPORT settings unless you know what you are doing.
+ * 
+ * On SS5 BPA seems to toggle onboard ethernet loopback... -E
+ */
+#define APC_BPORT_A		0x01	/* Bit Port A		*/
+#define APC_BPORT_B		0x02	/* Bit Port B		*/
+
+#endif /* !(_SPARC_APC_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/checksum.h linux/include/asm-sparc/checksum.h
--- linux.orig/include/asm-sparc/checksum.h	2001-10-30 23:08:11.000000000 +0000
+++ linux/include/asm-sparc/checksum.h	2002-07-20 01:08:21.000000000 +0000
@@ -16,6 +16,7 @@
  *      RFC1071 Computing the Internet Checksum
  */
  
+#include <linux/in6.h>
 #include <asm/uaccess.h>
 #include <asm/cprefix.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/ide.h linux/include/asm-sparc/ide.h
--- linux.orig/include/asm-sparc/ide.h	2000-06-20 00:59:39.000000000 +0000
+++ linux/include/asm-sparc/ide.h	2002-07-20 01:08:37.000000000 +0000
@@ -84,6 +84,18 @@
 	} b;
 } select_t;
 
+typedef union {
+	unsigned int all		: 8;	/* all of the bits together */
+	struct {
+		unsigned int HOB	: 1;	/* 48-bit address ordering */
+		unsigned int reserved456: 3;
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned int SRST	: 1;	/* host soft reset bit */
+		unsigned int nIEN	: 1;	/* device INTRQ to host */
+		unsigned int bit0	: 1;
+	} b;
+} control_t;
+
 static __inline__ int ide_request_irq(unsigned int irq,
 				      void (*handler)(int, void *, struct pt_regs *),
 				      unsigned long flags, const char *name, void *devid)
@@ -203,79 +215,93 @@
 	/* __flush_dcache_range((unsigned long)src, end); */ /* P3 see hme */
 }
 
-#define T_CHAR          (0x0000)        /* char:  don't touch  */
-#define T_SHORT         (0x4000)        /* short: 12 -> 21     */
-#define T_INT           (0x8000)        /* int:   1234 -> 4321 */
-#define T_TEXT          (0xc000)        /* text:  12 -> 21     */
-
-#define T_MASK_TYPE     (0xc000)
-#define T_MASK_COUNT    (0x3fff)
-
-#define D_CHAR(cnt)     (T_CHAR  | (cnt))
-#define D_SHORT(cnt)    (T_SHORT | (cnt))
-#define D_INT(cnt)      (T_INT   | (cnt))
-#define D_TEXT(cnt)     (T_TEXT  | (cnt))
-
-static u_short driveid_types[] = {
-	D_SHORT(10),	/* config - vendor2 */
-	D_TEXT(20),	/* serial_no */
-	D_SHORT(3),	/* buf_type - ecc_bytes */
-	D_TEXT(48),	/* fw_rev - model */
-	D_CHAR(2),	/* max_multsect - vendor3 */
-	D_SHORT(1),	/* dword_io */
-	D_CHAR(2),	/* vendor4 - capability */
-	D_SHORT(1),	/* reserved50 */
-	D_CHAR(4),	/* vendor5 - tDMA */
-	D_SHORT(4),	/* field_valid - cur_sectors */
-	D_INT(1),	/* cur_capacity */
-	D_CHAR(2),	/* multsect - multsect_valid */
-	D_INT(1),	/* lba_capacity */
-	D_SHORT(194)	/* dma_1word - reservedyy */
-};
-
-#define num_driveid_types       (sizeof(driveid_types)/sizeof(*driveid_types))
-
 static __inline__ void ide_fix_driveid(struct hd_driveid *id)
 {
-	u_char *p = (u_char *)id;
-	int i, j, cnt;
-	u_char t;
-
-	for (i = 0; i < num_driveid_types; i++) {
-		cnt = driveid_types[i] & T_MASK_COUNT;
-		switch (driveid_types[i] & T_MASK_TYPE) {
-		case T_CHAR:
-			p += cnt;
-			break;
-		case T_SHORT:
-			for (j = 0; j < cnt; j++) {
-				t = p[0];
-				p[0] = p[1];
-				p[1] = t;
-				p += 2;
-			}
-			break;
-		case T_INT:
-			for (j = 0; j < cnt; j++) {
-				t = p[0];
-				p[0] = p[3];
-				p[3] = t;
-				t = p[1];
-				p[1] = p[2];
-				p[2] = t;
-				p += 4;
-			}
-			break;
-		case T_TEXT:
-			for (j = 0; j < cnt; j += 2) {
-				t = p[0];
-				p[0] = p[1];
-				p[1] = t;
-				p += 2;
-			}
-			break;
-		};
-	}
+	int i;
+	u16 *stringcast;
+
+	id->config         = __le16_to_cpu(id->config);
+	id->cyls           = __le16_to_cpu(id->cyls);
+	id->reserved2      = __le16_to_cpu(id->reserved2);
+	id->heads          = __le16_to_cpu(id->heads);
+	id->track_bytes    = __le16_to_cpu(id->track_bytes);
+	id->sector_bytes   = __le16_to_cpu(id->sector_bytes);
+	id->sectors        = __le16_to_cpu(id->sectors);
+	id->vendor0        = __le16_to_cpu(id->vendor0);
+	id->vendor1        = __le16_to_cpu(id->vendor1);
+	id->vendor2        = __le16_to_cpu(id->vendor2);
+	stringcast = (u16 *)&id->serial_no[0];
+	for (i = 0; i < (20/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	id->buf_type       = __le16_to_cpu(id->buf_type);
+	id->buf_size       = __le16_to_cpu(id->buf_size);
+	id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
+	stringcast = (u16 *)&id->fw_rev[0];
+	for (i = 0; i < (8/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	stringcast = (u16 *)&id->model[0];
+	for (i = 0; i < (40/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	id->dword_io       = __le16_to_cpu(id->dword_io);
+	id->reserved50     = __le16_to_cpu(id->reserved50);
+	id->field_valid    = __le16_to_cpu(id->field_valid);
+	id->cur_cyls       = __le16_to_cpu(id->cur_cyls);
+	id->cur_heads      = __le16_to_cpu(id->cur_heads);
+	id->cur_sectors    = __le16_to_cpu(id->cur_sectors);
+	id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);
+	id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);
+	id->lba_capacity   = __le32_to_cpu(id->lba_capacity);
+	id->dma_1word      = __le16_to_cpu(id->dma_1word);
+	id->dma_mword      = __le16_to_cpu(id->dma_mword);
+	id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
+	id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);
+	id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
+	id->eide_pio       = __le16_to_cpu(id->eide_pio);
+	id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
+	for (i = 0; i < 2; i++)
+		id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
+        for (i = 0; i < 4; i++)
+                id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
+	id->queue_depth	   = __le16_to_cpu(id->queue_depth);
+	for (i = 0; i < 4; i++)
+		id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
+	id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
+	id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
+	id->command_set_1  = __le16_to_cpu(id->command_set_1);
+	id->command_set_2  = __le16_to_cpu(id->command_set_2);
+	id->cfsse          = __le16_to_cpu(id->cfsse);
+	id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);
+	id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);
+	id->csf_default    = __le16_to_cpu(id->csf_default);
+	id->dma_ultra      = __le16_to_cpu(id->dma_ultra);
+	id->word89         = __le16_to_cpu(id->word89);
+	id->word90         = __le16_to_cpu(id->word90);
+	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
+	id->word92         = __le16_to_cpu(id->word92);
+	id->hw_config      = __le16_to_cpu(id->hw_config);
+	id->acoustic       = __le16_to_cpu(id->acoustic);
+	for (i = 0; i < 5; i++)
+		id->words95_99[i]  = __le16_to_cpu(id->words95_99[i]);
+	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
+	for (i = 0; i < 22; i++)
+		id->words104_125[i]   = __le16_to_cpu(id->words104_125[i]);
+	id->last_lun       = __le16_to_cpu(id->last_lun);
+	id->word127        = __le16_to_cpu(id->word127);
+	id->dlf            = __le16_to_cpu(id->dlf);
+	id->csfo           = __le16_to_cpu(id->csfo);
+	for (i = 0; i < 26; i++)
+		id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
+	id->word156        = __le16_to_cpu(id->word156);
+	for (i = 0; i < 3; i++)
+		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
+	id->cfa_power      = __le16_to_cpu(id->cfa_power);
+	for (i = 0; i < 14; i++)
+		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
+	for (i = 0; i < 31; i++)
+		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
+	for (i = 0; i < 48; i++)
+		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
+	id->integrity_word  = __le16_to_cpu(id->integrity_word);
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/ioctls.h linux/include/asm-sparc/ioctls.h
--- linux.orig/include/asm-sparc/ioctls.h	1998-10-04 17:22:44.000000000 +0000
+++ linux/include/asm-sparc/ioctls.h	2002-07-20 01:08:35.000000000 +0000
@@ -51,8 +51,8 @@
 #define TIOCMBIC	_IOW('t', 107, int)
 #define TIOCMBIS	_IOW('t', 108, int)
 #define TIOCMSET	_IOW('t', 109, int)
-#define __TIOCSTART       _IO('t', 110) /* SunOS Specific */
-#define __TIOCSTOP        _IO('t', 111) /* SunOS Specific */
+#define TIOCSTART       _IO('t', 110)
+#define TIOCSTOP        _IO('t', 111)
 #define TIOCPKT		_IOW('t', 112, int)
 #define TIOCNOTTY	_IO('t', 113)
 #define TIOCSTI		_IOW('t', 114, char)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/keyboard.h linux/include/asm-sparc/keyboard.h
--- linux.orig/include/asm-sparc/keyboard.h	2001-08-28 14:09:44.000000000 +0000
+++ linux/include/asm-sparc/keyboard.h	2002-07-20 01:08:35.000000000 +0000
@@ -40,7 +40,6 @@
 #define kbd_init			pcikbd_init
 
 #define compute_shiftstate		pci_compute_shiftstate
-#define keyboard_wait_for_keypress	pci_wait_for_keypress
 #define getkeycode			pci_getkeycode
 #define setkeycode			pci_setkeycode
 #define getledstate			pci_getledstate
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/page.h linux/include/asm-sparc/page.h
--- linux.orig/include/asm-sparc/page.h	2000-10-30 22:34:12.000000000 +0000
+++ linux/include/asm-sparc/page.h	2002-07-20 01:08:30.000000000 +0000
@@ -179,6 +179,9 @@
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 
 #endif /* _SPARC_PAGE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/pgalloc.h linux/include/asm-sparc/pgalloc.h
--- linux.orig/include/asm-sparc/pgalloc.h	2001-10-21 17:36:54.000000000 +0000
+++ linux/include/asm-sparc/pgalloc.h	2002-07-20 01:08:24.000000000 +0000
@@ -117,7 +117,6 @@
 
 static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	BUG();
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/pgtable.h linux/include/asm-sparc/pgtable.h
--- linux.orig/include/asm-sparc/pgtable.h	2001-11-13 17:16:05.000000000 +0000
+++ linux/include/asm-sparc/pgtable.h	2002-07-20 01:08:22.000000000 +0000
@@ -293,9 +293,6 @@
 #define page_pte_prot(page, prot)	mk_pte(page, prot)
 #define page_pte(page)			page_pte_prot(page, __pgprot(0))
 
-/* Permanent address of a page. */
-#define page_address(page)  ((page)->virtual)
-
 BTFIXUPDEF_CALL(struct page *, pte_page, pte_t)
 #define pte_page(pte) BTFIXUP_CALL(pte_page)(pte)
 
@@ -348,6 +345,7 @@
 extern unsigned int pg_iobits;
 
 #define flush_icache_page(vma, pg)      do { } while(0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 /* Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/sbus.h linux/include/asm-sparc/sbus.h
--- linux.orig/include/asm-sparc/sbus.h	2000-02-18 23:07:20.000000000 +0000
+++ linux/include/asm-sparc/sbus.h	2002-07-20 01:08:27.000000000 +0000
@@ -94,7 +94,8 @@
         for((device) = (bus)->devices; (device); (device)=(device)->next)
         
 #define for_all_sbusdev(device, bus) \
-	for((bus) = sbus_root, ((device) = (bus) ? (bus)->devices : 0); (bus); (device)=((device)->next ? (device)->next : ((bus) = (bus)->next, (bus) ? (bus)->devices : 0)))
+	for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \
+		for ((device) = (bus)->devices; (device); (device) = (device)->next)
 
 /* Driver DVMA interfaces. */
 #define sbus_can_dma_64bit(sdev)	(0) /* actually, sparc_cpu_model==sun4d */
@@ -111,13 +112,13 @@
 #define	SBUS_DMA_NONE		3
 
 /* All the rest use streaming mode mappings. */
-extern u32 sbus_map_single(struct sbus_dev *, void *, long, int);
-extern void sbus_unmap_single(struct sbus_dev *, u32, long, int);
+extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int);
+extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t, int);
 extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int, int);
 extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int);
 
 /* Finally, allow explicit synchronization of streamable mappings. */
-extern void sbus_dma_sync_single(struct sbus_dev *, u32, long, int);
+extern void sbus_dma_sync_single(struct sbus_dev *, dma_addr_t, size_t, int);
 extern void sbus_dma_sync_sg(struct sbus_dev *, struct scatterlist *, int, int);
 
 #endif /* !(_SPARC_SBUS_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/siginfo.h linux/include/asm-sparc/siginfo.h
--- linux.orig/include/asm-sparc/siginfo.h	2000-06-20 00:59:39.000000000 +0000
+++ linux/include/asm-sparc/siginfo.h	2002-07-20 01:08:24.000000000 +0000
@@ -112,6 +112,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h
--- linux.orig/include/asm-sparc/unistd.h	2001-10-21 17:36:54.000000000 +0000
+++ linux/include/asm-sparc/unistd.h	2002-07-20 01:08:24.000000000 +0000
@@ -202,7 +202,7 @@
 #define __NR_query_module	184 /* Linux Specific				   */
 #define __NR_setpgid            185 /* Common                                      */
 /* #define __NR_pathconf        186    SunOS Specific                              */
-/* #define __NR_fpathconf       187    SunOS Specific                              */
+#define __NR_tkill              187 /* SunOS: fpathconf                            */
 /* #define __NR_sysconf         188    SunOS Specific                              */
 #define __NR_uname              189 /* Linux Specific                              */
 #define __NR_init_module        190 /* Linux Specific                              */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/checksum.h linux/include/asm-sparc64/checksum.h
--- linux.orig/include/asm-sparc64/checksum.h	2001-04-27 05:17:26.000000000 +0000
+++ linux/include/asm-sparc64/checksum.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.17 2001/04/24 01:09:12 davem Exp $ */
+/* $Id: checksum.h,v 1.17.2.1 2002/03/01 11:40:54 davem Exp $ */
 #ifndef __SPARC64_CHECKSUM_H
 #define __SPARC64_CHECKSUM_H
 
@@ -16,6 +16,7 @@
  *      RFC1071 Computing the Internet Checksum
  */
 
+#include <linux/in6.h> 
 #include <asm/uaccess.h> 
 
 /* computes the checksum of a memory block at buff, length len,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/elf.h linux/include/asm-sparc64/elf.h
--- linux.orig/include/asm-sparc64/elf.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-sparc64/elf.h	2002-07-20 01:08:32.000000000 +0000
@@ -21,8 +21,39 @@
 
 typedef unsigned long elf_greg_t;
 
-#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+#define ELF_NGREG 36
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+/* Format of 64-bit elf_gregset_t is:
+ * 	G0 --> G7
+ * 	O0 --> O7
+ * 	L0 --> L7
+ * 	I0 --> I7
+ *	TSTATE
+ *	TPC
+ *	TNPC
+ *	Y
+ */
+#include <asm/psrcompat.h>
+#define ELF_CORE_COPY_REGS(__elf_regs, __pt_regs)	\
+do {	unsigned long *dest = &(__elf_regs[0]);		\
+	struct pt_regs *src = (__pt_regs);		\
+	unsigned long *sp;				\
+	int i;						\
+	for(i = 0; i < 16; i++)				\
+		dest[i] = src->u_regs[i];		\
+	/* Don't try this at home kids... */		\
+	set_fs(USER_DS);				\
+	sp = (unsigned long *)				\
+	 ((src->u_regs[14] + STACK_BIAS)		\
+	  & 0xfffffffffffffff8UL);			\
+	for(i = 0; i < 16; i++)				\
+		__get_user(dest[i+16], &sp[i]);		\
+	set_fs(KERNEL_DS);				\
+	dest[32] = src->tstate;				\
+	dest[33] = src->tpc;				\
+	dest[34] = src->tnpc;				\
+	dest[35] = src->y;				\
+} while (0);
 
 typedef struct {
 	unsigned long	pr_regs[32];
@@ -76,7 +107,7 @@
 		flags &= ~SPARC_FLAG_32BIT;		\
 	if (flags != current->thread.flags) {		\
 		/* flush_thread will update pgd cache */\
-		current->thread.flags = flags;		\
+		current->thread.flags |= SPARC_FLAG_ABI_PENDING; \
 	}						\
 							\
 	if (ibcs2)					\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/fhc.h linux/include/asm-sparc64/fhc.h
--- linux.orig/include/asm-sparc64/fhc.h	1999-12-21 06:05:52.000000000 +0000
+++ linux/include/asm-sparc64/fhc.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: fhc.h,v 1.5 1999/09/21 14:39:29 davem Exp $
+/* $Id: fhc.h,v 1.5.2.1 2002/03/01 10:04:01 davem Exp $
  * fhc.h: Structures for central/fhc pseudo driver on Sunfire/Starfire/Wildfire.
  *
  * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
@@ -86,10 +86,10 @@
 #define  FHC_BSR_NIA		0x0000001c /* Jumper, bit 18 in PROM space       */
 #define  FHC_BSR_SI		0x00000001 /* Spare input pin value              */
 #define FHC_PREGS_ECC	0x40UL	/* FHC ECC Control Register (16 bits) */
-#define FHC_PREGS_JCTRL	0x50UL	/* FHC JTAG Control Register */
+#define FHC_PREGS_JCTRL	0xf0UL	/* FHC JTAG Control Register */
 #define  FHC_JTAG_CTRL_MENAB	0x80000000 /* Indicates this is JTAG Master	 */
 #define  FHC_JTAG_CTRL_MNONE	0x40000000 /* Indicates no JTAG Master present	 */
-#define FHC_PREGS_JCMD	0x60UL	/* FHC JTAG Command Register */
+#define FHC_PREGS_JCMD	0x100UL	/* FHC JTAG Command Register */
 	unsigned long			ireg;	/* FHC IGN reg */
 #define FHC_IREG_IGN	0x00UL	/* This FHC's IGN */
 	unsigned long			ffregs;	/* FHC fanfail regs */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/head.h linux/include/asm-sparc64/head.h
--- linux.orig/include/asm-sparc64/head.h	1997-08-16 16:51:10.000000000 +0000
+++ linux/include/asm-sparc64/head.h	2002-07-20 01:08:32.000000000 +0000
@@ -1,9 +1,11 @@
-/* $Id: head.h,v 1.30 1997/08/08 08:34:33 jj Exp $ */
+/* $Id: head.h,v 1.30.8.1 2002/03/03 10:31:56 davem Exp $ */
 #ifndef _SPARC64_HEAD_H
 #define _SPARC64_HEAD_H
 
 #include <asm/pstate.h>
 
-#define KERNBASE    0x400000
+#define KERNBASE	0x400000
+
+#define	PTREGS_OFF	(STACK_BIAS + REGWIN_SZ)
 
 #endif /* !(_SPARC64_HEAD_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/ide.h linux/include/asm-sparc64/ide.h
--- linux.orig/include/asm-sparc64/ide.h	2001-10-01 16:19:56.000000000 +0000
+++ linux/include/asm-sparc64/ide.h	2002-07-20 01:08:33.000000000 +0000
@@ -80,6 +80,18 @@
 	} b;
 } select_t;
 
+typedef union {
+	unsigned int all		: 8;	/* all of the bits together */
+	struct {
+		unsigned int HOB	: 1;	/* 48-bit address ordering */
+		unsigned int reserved456: 3;
+		unsigned bit3		: 1;	/* ATA-2 thingy */
+		unsigned int SRST	: 1;	/* host soft reset bit */
+		unsigned int nIEN	: 1;	/* device INTRQ to host */
+		unsigned int bit0	: 1;
+	} b;
+} control_t;
+
 static __inline__ int ide_request_irq(unsigned int irq,
 				      void (*handler)(int, void *, struct pt_regs *),
 				      unsigned long flags, const char *name, void *devid)
@@ -220,79 +232,93 @@
 #endif
 }
 
-#define T_CHAR          (0x0000)        /* char:  don't touch  */
-#define T_SHORT         (0x4000)        /* short: 12 -> 21     */
-#define T_INT           (0x8000)        /* int:   1234 -> 4321 */
-#define T_TEXT          (0xc000)        /* text:  12 -> 21     */
-
-#define T_MASK_TYPE     (0xc000)
-#define T_MASK_COUNT    (0x3fff)
-
-#define D_CHAR(cnt)     (T_CHAR  | (cnt))
-#define D_SHORT(cnt)    (T_SHORT | (cnt))
-#define D_INT(cnt)      (T_INT   | (cnt))
-#define D_TEXT(cnt)     (T_TEXT  | (cnt))
-
-static u_short driveid_types[] = {
-	D_SHORT(10),	/* config - vendor2 */
-	D_TEXT(20),	/* serial_no */
-	D_SHORT(3),	/* buf_type - ecc_bytes */
-	D_TEXT(48),	/* fw_rev - model */
-	D_CHAR(2),	/* max_multsect - vendor3 */
-	D_SHORT(1),	/* dword_io */
-	D_CHAR(2),	/* vendor4 - capability */
-	D_SHORT(1),	/* reserved50 */
-	D_CHAR(4),	/* vendor5 - tDMA */
-	D_SHORT(4),	/* field_valid - cur_sectors */
-	D_INT(1),	/* cur_capacity */
-	D_CHAR(2),	/* multsect - multsect_valid */
-	D_INT(1),	/* lba_capacity */
-	D_SHORT(194)	/* dma_1word - reservedyy */
-};
-
-#define num_driveid_types       (sizeof(driveid_types)/sizeof(*driveid_types))
-
 static __inline__ void ide_fix_driveid(struct hd_driveid *id)
 {
-	u_char *p = (u_char *)id;
-	int i, j, cnt;
-	u_char t;
-
-	for (i = 0; i < num_driveid_types; i++) {
-		cnt = driveid_types[i] & T_MASK_COUNT;
-		switch (driveid_types[i] & T_MASK_TYPE) {
-		case T_CHAR:
-			p += cnt;
-			break;
-		case T_SHORT:
-			for (j = 0; j < cnt; j++) {
-				t = p[0];
-				p[0] = p[1];
-				p[1] = t;
-				p += 2;
-			}
-			break;
-		case T_INT:
-			for (j = 0; j < cnt; j++) {
-				t = p[0];
-				p[0] = p[3];
-				p[3] = t;
-				t = p[1];
-				p[1] = p[2];
-				p[2] = t;
-				p += 4;
-			}
-			break;
-		case T_TEXT:
-			for (j = 0; j < cnt; j += 2) {
-				t = p[0];
-				p[0] = p[1];
-				p[1] = t;
-				p += 2;
-			}
-			break;
-		};
-	}
+	int i;
+	u16 *stringcast;
+
+	id->config         = __le16_to_cpu(id->config);
+	id->cyls           = __le16_to_cpu(id->cyls);
+	id->reserved2      = __le16_to_cpu(id->reserved2);
+	id->heads          = __le16_to_cpu(id->heads);
+	id->track_bytes    = __le16_to_cpu(id->track_bytes);
+	id->sector_bytes   = __le16_to_cpu(id->sector_bytes);
+	id->sectors        = __le16_to_cpu(id->sectors);
+	id->vendor0        = __le16_to_cpu(id->vendor0);
+	id->vendor1        = __le16_to_cpu(id->vendor1);
+	id->vendor2        = __le16_to_cpu(id->vendor2);
+	stringcast = (u16 *)&id->serial_no[0];
+	for (i = 0; i < (20/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	id->buf_type       = __le16_to_cpu(id->buf_type);
+	id->buf_size       = __le16_to_cpu(id->buf_size);
+	id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
+	stringcast = (u16 *)&id->fw_rev[0];
+	for (i = 0; i < (8/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	stringcast = (u16 *)&id->model[0];
+	for (i = 0; i < (40/2); i++)
+	        stringcast[i] = __le16_to_cpu(stringcast[i]);
+	id->dword_io       = __le16_to_cpu(id->dword_io);
+	id->reserved50     = __le16_to_cpu(id->reserved50);
+	id->field_valid    = __le16_to_cpu(id->field_valid);
+	id->cur_cyls       = __le16_to_cpu(id->cur_cyls);
+	id->cur_heads      = __le16_to_cpu(id->cur_heads);
+	id->cur_sectors    = __le16_to_cpu(id->cur_sectors);
+	id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);
+	id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);
+	id->lba_capacity   = __le32_to_cpu(id->lba_capacity);
+	id->dma_1word      = __le16_to_cpu(id->dma_1word);
+	id->dma_mword      = __le16_to_cpu(id->dma_mword);
+	id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
+	id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);
+	id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
+	id->eide_pio       = __le16_to_cpu(id->eide_pio);
+	id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
+	for (i = 0; i < 2; i++)
+		id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
+        for (i = 0; i < 4; i++)
+                id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
+	id->queue_depth	   = __le16_to_cpu(id->queue_depth);
+	for (i = 0; i < 4; i++)
+		id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
+	id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
+	id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
+	id->command_set_1  = __le16_to_cpu(id->command_set_1);
+	id->command_set_2  = __le16_to_cpu(id->command_set_2);
+	id->cfsse          = __le16_to_cpu(id->cfsse);
+	id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);
+	id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);
+	id->csf_default    = __le16_to_cpu(id->csf_default);
+	id->dma_ultra      = __le16_to_cpu(id->dma_ultra);
+	id->word89         = __le16_to_cpu(id->word89);
+	id->word90         = __le16_to_cpu(id->word90);
+	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
+	id->word92         = __le16_to_cpu(id->word92);
+	id->hw_config      = __le16_to_cpu(id->hw_config);
+	id->acoustic       = __le16_to_cpu(id->acoustic);
+	for (i = 0; i < 5; i++)
+		id->words95_99[i]  = __le16_to_cpu(id->words95_99[i]);
+	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
+	for (i = 0; i < 22; i++)
+		id->words104_125[i]   = __le16_to_cpu(id->words104_125[i]);
+	id->last_lun       = __le16_to_cpu(id->last_lun);
+	id->word127        = __le16_to_cpu(id->word127);
+	id->dlf            = __le16_to_cpu(id->dlf);
+	id->csfo           = __le16_to_cpu(id->csfo);
+	for (i = 0; i < 26; i++)
+		id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
+	id->word156        = __le16_to_cpu(id->word156);
+	for (i = 0; i < 3; i++)
+		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
+	id->cfa_power      = __le16_to_cpu(id->cfa_power);
+	for (i = 0; i < 14; i++)
+		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
+	for (i = 0; i < 31; i++)
+		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
+	for (i = 0; i < 48; i++)
+		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
+	id->integrity_word  = __le16_to_cpu(id->integrity_word);
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/ioctls.h linux/include/asm-sparc64/ioctls.h
--- linux.orig/include/asm-sparc64/ioctls.h	1998-04-15 00:44:24.000000000 +0000
+++ linux/include/asm-sparc64/ioctls.h	2002-07-20 01:08:21.000000000 +0000
@@ -52,8 +52,8 @@
 #define TIOCMBIC	_IOW('t', 107, int)
 #define TIOCMBIS	_IOW('t', 108, int)
 #define TIOCMSET	_IOW('t', 109, int)
-#define __TIOCSTART       _IO('t', 110) /* SunOS Specific */
-#define __TIOCSTOP        _IO('t', 111) /* SunOS Specific */
+#define TIOCSTART       _IO('t', 110)
+#define TIOCSTOP        _IO('t', 111)
 #define TIOCPKT		_IOW('t', 112, int)
 #define TIOCNOTTY	_IO('t', 113)
 #define TIOCSTI		_IOW('t', 114, char)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/irq.h linux/include/asm-sparc64/irq.h
--- linux.orig/include/asm-sparc64/irq.h	2001-03-26 02:14:21.000000000 +0000
+++ linux/include/asm-sparc64/irq.h	2002-07-20 01:08:37.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: irq.h,v 1.20 2001/03/09 01:31:40 davem Exp $
+/* $Id: irq.h,v 1.20.2.1 2002/03/03 10:31:56 davem Exp $
  * irq.h: IRQ registers on the 64-bit Sparc.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -11,10 +11,8 @@
 #include <linux/config.h>
 #include <linux/linkage.h>
 #include <linux/kernel.h>
-
-struct devid_cookie {
-	int dummy;
-};
+#include <asm/pil.h>
+#include <asm/ptrace.h>
 
 /* You should not mess with this directly. That's the job of irq.c.
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/keyboard.h linux/include/asm-sparc64/keyboard.h
--- linux.orig/include/asm-sparc64/keyboard.h	2001-08-28 14:09:44.000000000 +0000
+++ linux/include/asm-sparc64/keyboard.h	2002-07-20 01:08:37.000000000 +0000
@@ -38,7 +38,6 @@
 #define kbd_init			pcikbd_init
 
 #define compute_shiftstate		pci_compute_shiftstate
-#define keyboard_wait_for_keypress	pci_wait_for_keypress
 #define getkeycode			pci_getkeycode
 #define setkeycode			pci_setkeycode
 #define getledstate			pci_getledstate
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/page.h linux/include/asm-sparc64/page.h
--- linux.orig/include/asm-sparc64/page.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/asm-sparc64/page.h	2002-07-20 01:08:34.000000000 +0000
@@ -30,6 +30,9 @@
 
 #define PAGE_BUG(page)	BUG()
 
+/* Sparc64 is slow at multiplication, we prefer to use some extra space. */
+#define WANT_PAGE_VIRTUAL 1
+
 extern void _clear_page(void *page);
 #define clear_page(X)	_clear_page((void *)(X))
 extern void clear_user_page(void *page, unsigned long vaddr);
@@ -153,6 +156,9 @@
 
 #endif /* !(__ASSEMBLY__) */
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* !(__KERNEL__) */
 
 #endif /* !(_SPARC64_PAGE_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/pgalloc.h linux/include/asm-sparc64/pgalloc.h
--- linux.orig/include/asm-sparc64/pgalloc.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-sparc64/pgalloc.h	2002-07-20 01:08:34.000000000 +0000
@@ -100,13 +100,6 @@
 
 #endif /* ! CONFIG_SMP */
 
-#define VPTE_BASE_SPITFIRE	0xfffffffe00000000
-#if 1
-#define VPTE_BASE_CHEETAH	VPTE_BASE_SPITFIRE
-#else
-#define VPTE_BASE_CHEETAH	0xffe0000000000000
-#endif
-
 extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start,
 					  unsigned long end)
 {
@@ -128,8 +121,6 @@
 			vpte_base + (s >> (PAGE_SHIFT - 3)),
 			vpte_base + (e >> (PAGE_SHIFT - 3)));
 }
-#undef VPTE_BASE_SPITFIRE
-#undef VPTE_BASE_CHEETAH
 
 /* Page table allocation/freeing. */
 #ifdef CONFIG_SMP
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h
--- linux.orig/include/asm-sparc64/pgtable.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/asm-sparc64/pgtable.h	2002-07-20 01:08:22.000000000 +0000
@@ -243,8 +243,7 @@
 #define pte_mkold(pte)		(__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_ACCESSED))
 
 /* Permanent address of a page. */
-#define __page_address(page)	((page)->virtual)
-#define page_address(page)	({ __page_address(page); })
+#define __page_address(page)	page_address(page)
 
 #define pte_page(x) (mem_map+(((pte_val(x)&_PAGE_PADDR)-phys_base)>>PAGE_SHIFT))
 
@@ -277,6 +276,7 @@
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
 #define flush_icache_page(vma, pg)	do { } while(0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 /* Make a non-present pseudo-TTE. */
 extern inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/pil.h linux/include/asm-sparc64/pil.h
--- linux.orig/include/asm-sparc64/pil.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/asm-sparc64/pil.h	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,26 @@
+/* $Id: pil.h,v 1.1.2.1 2002/03/03 10:31:56 davem Exp $ */
+#ifndef _SPARC64_PIL_H
+#define _SPARC64_PIL_H
+
+/* To avoid some locking problems, we hard allocate certain PILs
+ * for SMP cross call messages that must do a etrap/rtrap.
+ *
+ * A cli() does not block the cross call delivery, so when SMP
+ * locking is an issue we reschedule the event into a PIL interrupt
+ * which is blocked by cli().
+ *
+ * In fact any XCALL which has to etrap/rtrap has a problem because
+ * it is difficult to prevent rtrap from running BH's, and that would
+ * need to be done if the XCALL arrived while %pil==15.
+ */
+#define PIL_SMP_CALL_FUNC	1
+#define PIL_SMP_RECEIVE_SIGNAL	2
+#define PIL_SMP_CAPTURE		3
+
+#ifndef __ASSEMBLY__
+#define PIL_RESERVED(PIL)	((PIL) == PIL_SMP_CALL_FUNC || \
+				 (PIL) == PIL_SMP_RECEIVE_SIGNAL || \
+				 (PIL) == PIL_SMP_CAPTURE)
+#endif
+
+#endif /* !(_SPARC64_PIL_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h
--- linux.orig/include/asm-sparc64/processor.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/asm-sparc64/processor.h	2002-07-20 01:08:22.000000000 +0000
@@ -39,9 +39,25 @@
  * address that the kernel will allocate out.
  */
 #define VA_BITS		44
+#ifndef __ASSEMBLY__
 #define VPTE_SIZE	(1UL << (VA_BITS - PAGE_SHIFT + 3))
+#else
+#define VPTE_SIZE	(1 << (VA_BITS - PAGE_SHIFT + 3))
+#endif
 #define TASK_SIZE	((unsigned long)-VPTE_SIZE)
 
+/*
+ * The vpte base must be able to hold the entire vpte, half
+ * of which lives above, and half below, the base. And it
+ * is placed as close to the highest address range as possible.
+ */
+#define VPTE_BASE_SPITFIRE	(-(VPTE_SIZE/2))
+#if 1
+#define VPTE_BASE_CHEETAH	VPTE_BASE_SPITFIRE
+#else
+#define VPTE_BASE_CHEETAH	0xffe0000000000000
+#endif
+
 #ifndef __ASSEMBLY__
 
 #define NSWINS		7
@@ -92,6 +108,7 @@
 #define SPARC_FLAG_32BIT        0x04    /* task is older 32-bit binary		*/
 #define SPARC_FLAG_NEWCHILD     0x08    /* task is just-spawned child process	*/
 #define SPARC_FLAG_PERFCTR	0x10    /* task has performance counters active	*/
+#define SPARC_FLAG_ABI_PENDING	0x20    /* change of SPARC_FLAG_32BIT pending	*/
 
 #define FAULT_CODE_WRITE	0x01	/* Write access, implies D-TLB		*/
 #define FAULT_CODE_DTLB		0x02	/* Miss happened in D-TLB		*/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/sbus.h linux/include/asm-sparc64/sbus.h
--- linux.orig/include/asm-sparc64/sbus.h	2000-02-18 23:07:20.000000000 +0000
+++ linux/include/asm-sparc64/sbus.h	2002-07-20 01:08:27.000000000 +0000
@@ -87,7 +87,8 @@
         for((device) = (bus)->devices; (device); (device)=(device)->next)
         
 #define for_all_sbusdev(device, bus) \
-	for((bus) = sbus_root, ((device) = (bus) ? (bus)->devices : 0); (bus); (device)=((device)->next ? (device)->next : ((bus) = (bus)->next, (bus) ? (bus)->devices : 0)))
+	for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \
+		for ((device) = (bus)->devices; (device); (device) = (device)->next)
 
 /* Driver DVMA interfaces. */
 #define sbus_can_dma_64bit(sdev)	(1)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/siginfo.h linux/include/asm-sparc64/siginfo.h
--- linux.orig/include/asm-sparc64/siginfo.h	2000-05-25 01:38:26.000000000 +0000
+++ linux/include/asm-sparc64/siginfo.h	2002-07-20 01:08:39.000000000 +0000
@@ -172,6 +172,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/system.h linux/include/asm-sparc64/system.h
--- linux.orig/include/asm-sparc64/system.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/asm-sparc64/system.h	2002-07-20 01:08:22.000000000 +0000
@@ -145,9 +145,9 @@
 #define flush_register_windows flushw_all
 #define prepare_to_switch flushw_all
 
-#ifndef CONFIG_DEBUG_SPINLOCk
+#ifndef CONFIG_DEBUG_SPINLOCK
 #define CHECK_LOCKS(PREV)	do { } while(0)
-#else /* CONFIG_DEBUG_SPINLOCk */
+#else /* CONFIG_DEBUG_SPINLOCK */
 #define CHECK_LOCKS(PREV)						\
 if ((PREV)->thread.smp_lock_count) {					\
 	unsigned long rpc;						\
@@ -161,7 +161,7 @@
 	printk(KERN_CRIT "(%s)[%d]: Sched caller %016lx\n",		\
 	       (PREV)->comm, (PREV)->pid, rpc);				\
 }
-#endif /* !(CONFIG_DEBUG_SPINLOCk) */
+#endif /* !(CONFIG_DEBUG_SPINLOCK) */
 
 	/* See what happens when you design the chip correctly?
 	 *
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/timex.h linux/include/asm-sparc64/timex.h
--- linux.orig/include/asm-sparc64/timex.h	2001-09-20 21:11:58.000000000 +0000
+++ linux/include/asm-sparc64/timex.h	2002-07-20 01:08:37.000000000 +0000
@@ -16,7 +16,7 @@
 typedef unsigned long cycles_t;
 #define get_cycles() \
 ({	cycles_t ret; \
-	__asm__("rd	%%tick, %0" : "=r" (ret)); \
+	__asm__ __volatile__("rd	%%tick, %0" : "=r" (ret)); \
 	ret; \
 })
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/unistd.h linux/include/asm-sparc64/unistd.h
--- linux.orig/include/asm-sparc64/unistd.h	2001-10-21 17:36:54.000000000 +0000
+++ linux/include/asm-sparc64/unistd.h	2002-07-20 01:08:27.000000000 +0000
@@ -202,7 +202,7 @@
 #define __NR_query_module	184 /* Linux Specific				   */
 #define __NR_setpgid            185 /* Common                                      */
 /* #define __NR_pathconf        186    SunOS Specific                              */
-/* #define __NR_fpathconf       187    SunOS Specific                              */
+#define __NR_tkill              187 /* SunOS: fpathconf                            */
 /* #define __NR_sysconf         188    SunOS Specific                              */
 #define __NR_uname              189 /* Linux Specific                              */
 #define __NR_init_module        190 /* Linux Specific                              */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/asm-sparc64/xor.h linux/include/asm-sparc64/xor.h
--- linux.orig/include/asm-sparc64/xor.h	2001-11-04 17:31:57.000000000 +0000
+++ linux/include/asm-sparc64/xor.h	2002-07-20 01:08:34.000000000 +0000
@@ -47,344 +47,344 @@
 /* ??? We set and use %asi instead of using ASI_BLK_P directly because gas
    currently does not accept symbolic constants for the ASI specifier.  */
 
-__asm__ ("
-	.text
-	.globl xor_vis_2
-	.type xor_vis_2,@function
-xor_vis_2:
-	rd	%fprs, %o5
-	andcc	%o5, FPRS_FEF|FPRS_DU, %g0
-	be,pt	%icc, 0f
-	 sethi	%hi(VISenter), %g1
-	jmpl	%g1 + %lo(VISenter), %g7
-	 add	%g7, 8, %g7
-0:	wr	%g0, FPRS_FEF, %fprs
-	rd	%asi, %g1
-	wr	%g0, ASI_BLK_P, %asi
-	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%o0, 128, %o0
-	ldda	[%o1] %asi, %f0
-	ldda	[%o2] %asi, %f16
-
-2:	ldda	[%o1 + 64] %asi, %f32
-	fxor	%f0, %f16, %f16
-	fxor	%f2, %f18, %f18
-	fxor	%f4, %f20, %f20
-	fxor	%f6, %f22, %f22
-	fxor	%f8, %f24, %f24
-	fxor	%f10, %f26, %f26
-	fxor	%f12, %f28, %f28
-	fxor	%f14, %f30, %f30
-	stda	%f16, [%o1] %asi
-	ldda	[%o2 + 64] %asi, %f48
-	ldda	[%o1 + 128] %asi, %f0
-	fxor	%f32, %f48, %f48
-	fxor	%f34, %f50, %f50
-	add	%o1, 128, %o1
-	fxor	%f36, %f52, %f52
-	add	%o2, 128, %o2
-	fxor	%f38, %f54, %f54
-	subcc	%o0, 128, %o0
-	fxor	%f40, %f56, %f56
-	fxor	%f42, %f58, %f58
-	fxor	%f44, %f60, %f60
-	fxor	%f46, %f62, %f62
-	stda	%f48, [%o1 - 64] %asi
-	bne,pt	%xcc, 2b
-	 ldda	[%o2] %asi, %f16
-
-	ldda	[%o1 + 64] %asi, %f32
-	fxor	%f0, %f16, %f16
-	fxor	%f2, %f18, %f18
-	fxor	%f4, %f20, %f20
-	fxor	%f6, %f22, %f22
-	fxor	%f8, %f24, %f24
-	fxor	%f10, %f26, %f26
-	fxor	%f12, %f28, %f28
-	fxor	%f14, %f30, %f30
-	stda	%f16, [%o1] %asi
-	ldda	[%o2 + 64] %asi, %f48
-	membar	#Sync
-	fxor	%f32, %f48, %f48
-	fxor	%f34, %f50, %f50
-	fxor	%f36, %f52, %f52
-	fxor	%f38, %f54, %f54
-	fxor	%f40, %f56, %f56
-	fxor	%f42, %f58, %f58
-	fxor	%f44, %f60, %f60
-	fxor	%f46, %f62, %f62
-	stda	%f48, [%o1 + 64] %asi
-	membar	#Sync|#StoreStore|#StoreLoad
-	wr	%g1, %g0, %asi
-	retl
-	  wr	%g0, 0, %fprs
-	.size xor_vis_2, .-xor_vis_2
-
-
-	.globl xor_vis_3
-	.type xor_vis_3,@function
-xor_vis_3:
-	rd	%fprs, %o5
-	andcc	%o5, FPRS_FEF|FPRS_DU, %g0
-	be,pt	%icc, 0f
-	 sethi	%hi(VISenter), %g1
-	jmpl	%g1 + %lo(VISenter), %g7
-	 add	%g7, 8, %g7
-0:	wr	%g0, FPRS_FEF, %fprs
-	rd	%asi, %g1
-	wr	%g0, ASI_BLK_P, %asi
-	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%o0, 64, %o0
-	ldda	[%o1] %asi, %f0
-	ldda	[%o2] %asi, %f16
-
-3:	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f48
-	fxor	%f2, %f18, %f50
-	add	%o1, 64, %o1
-	fxor	%f4, %f20, %f52
-	fxor	%f6, %f22, %f54
-	add	%o2, 64, %o2
-	fxor	%f8, %f24, %f56
-	fxor	%f10, %f26, %f58
-	fxor	%f12, %f28, %f60
-	fxor	%f14, %f30, %f62
-	ldda	[%o1] %asi, %f0
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	add	%o3, 64, %o3
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	subcc	%o0, 64, %o0
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	stda	%f48, [%o1 - 64] %asi
-	bne,pt	%xcc, 3b
-	 ldda	[%o2] %asi, %f16
-
-	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f48
-	fxor	%f2, %f18, %f50
-	fxor	%f4, %f20, %f52
-	fxor	%f6, %f22, %f54
-	fxor	%f8, %f24, %f56
-	fxor	%f10, %f26, %f58
-	fxor	%f12, %f28, %f60
-	fxor	%f14, %f30, %f62
-	membar	#Sync
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	stda	%f48, [%o1] %asi
-	membar	#Sync|#StoreStore|#StoreLoad
-	wr	%g1, %g0, %asi
-	retl
-	 wr	%g0, 0, %fprs
-	.size xor_vis_3, .-xor_vis_3
-
-
-	.globl xor_vis_4
-	.type xor_vis_4,@function
-xor_vis_4:
-	rd	%fprs, %o5
-	andcc	%o5, FPRS_FEF|FPRS_DU, %g0
-	be,pt	%icc, 0f
-	 sethi	%hi(VISenter), %g1
-	jmpl	%g1 + %lo(VISenter), %g7
-	 add	%g7, 8, %g7
-0:	wr	%g0, FPRS_FEF, %fprs
-	rd	%asi, %g1
-	wr	%g0, ASI_BLK_P, %asi
-	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%o0, 64, %o0
-	ldda	[%o1] %asi, %f0
-	ldda	[%o2] %asi, %f16
-
-4:	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f16
-	fxor	%f2, %f18, %f18
-	add	%o1, 64, %o1
-	fxor	%f4, %f20, %f20
-	fxor	%f6, %f22, %f22
-	add	%o2, 64, %o2
-	fxor	%f8, %f24, %f24
-	fxor	%f10, %f26, %f26
-	fxor	%f12, %f28, %f28
-	fxor	%f14, %f30, %f30
-	ldda	[%o4] %asi, %f48
-	fxor	%f16, %f32, %f32
-	fxor	%f18, %f34, %f34
-	fxor	%f20, %f36, %f36
-	fxor	%f22, %f38, %f38
-	add	%o3, 64, %o3
-	fxor	%f24, %f40, %f40
-	fxor	%f26, %f42, %f42
-	fxor	%f28, %f44, %f44
-	fxor	%f30, %f46, %f46
-	ldda	[%o1] %asi, %f0
-	fxor	%f32, %f48, %f48
-	fxor	%f34, %f50, %f50
-	fxor	%f36, %f52, %f52
-	add	%o4, 64, %o4
-	fxor	%f38, %f54, %f54
-	fxor	%f40, %f56, %f56
-	fxor	%f42, %f58, %f58
-	subcc	%o0, 64, %o0
-	fxor	%f44, %f60, %f60
-	fxor	%f46, %f62, %f62
-	stda	%f48, [%o1 - 64] %asi
-	bne,pt	%xcc, 4b
-	 ldda	[%o2] %asi, %f16
-
-	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f16
-	fxor	%f2, %f18, %f18
-	fxor	%f4, %f20, %f20
-	fxor	%f6, %f22, %f22
-	fxor	%f8, %f24, %f24
-	fxor	%f10, %f26, %f26
-	fxor	%f12, %f28, %f28
-	fxor	%f14, %f30, %f30
-	ldda	[%o4] %asi, %f48
-	fxor	%f16, %f32, %f32
-	fxor	%f18, %f34, %f34
-	fxor	%f20, %f36, %f36
-	fxor	%f22, %f38, %f38
-	fxor	%f24, %f40, %f40
-	fxor	%f26, %f42, %f42
-	fxor	%f28, %f44, %f44
-	fxor	%f30, %f46, %f46
-	membar	#Sync
-	fxor	%f32, %f48, %f48
-	fxor	%f34, %f50, %f50
-	fxor	%f36, %f52, %f52
-	fxor	%f38, %f54, %f54
-	fxor	%f40, %f56, %f56
-	fxor	%f42, %f58, %f58
-	fxor	%f44, %f60, %f60
-	fxor	%f46, %f62, %f62
-	stda	%f48, [%o1] %asi
-	membar	#Sync|#StoreStore|#StoreLoad
-	wr	%g1, %g0, %asi
-	retl
-	 wr	%g0, 0, %fprs
-	.size xor_vis_4, .-xor_vis_4
-
-
-	.globl xor_vis_5
-	.type xor_vis_5,@function
-xor_vis_5:
-	mov	%o5, %g5
-	rd	%fprs, %o5
-	andcc	%o5, FPRS_FEF|FPRS_DU, %g0
-	be,pt	%icc, 0f
-	 sethi	%hi(VISenter), %g1
-	jmpl	%g1 + %lo(VISenter), %g7
-	 add	%g7, 8, %g7
-0:	wr	%g0, FPRS_FEF, %fprs
-	mov	%g5, %o5
-	rd	%asi, %g1
-	wr	%g0, ASI_BLK_P, %asi
-	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%o0, 64, %o0
-	ldda	[%o1] %asi, %f0
-	ldda	[%o2] %asi, %f16
-
-5:	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f48
-	fxor	%f2, %f18, %f50
-	add	%o1, 64, %o1
-	fxor	%f4, %f20, %f52
-	fxor	%f6, %f22, %f54
-	add	%o2, 64, %o2
-	fxor	%f8, %f24, %f56
-	fxor	%f10, %f26, %f58
-	fxor	%f12, %f28, %f60
-	fxor	%f14, %f30, %f62
-	ldda	[%o4] %asi, %f16
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	add	%o3, 64, %o3
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	ldda	[%o5] %asi, %f32
-	fxor	%f48, %f16, %f48
-	fxor	%f50, %f18, %f50
-	add	%o4, 64, %o4
-	fxor	%f52, %f20, %f52
-	fxor	%f54, %f22, %f54
-	add	%o5, 64, %o5
-	fxor	%f56, %f24, %f56
-	fxor	%f58, %f26, %f58
-	fxor	%f60, %f28, %f60
-	fxor	%f62, %f30, %f62
-	ldda	[%o1] %asi, %f0
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	subcc	%o0, 64, %o0
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	stda	%f48, [%o1 - 64] %asi
-	bne,pt	%xcc, 5b
-	 ldda	[%o2] %asi, %f16
-
-	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f48
-	fxor	%f2, %f18, %f50
-	fxor	%f4, %f20, %f52
-	fxor	%f6, %f22, %f54
-	fxor	%f8, %f24, %f56
-	fxor	%f10, %f26, %f58
-	fxor	%f12, %f28, %f60
-	fxor	%f14, %f30, %f62
-	ldda	[%o4] %asi, %f16
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	ldda	[%o5] %asi, %f32
-	fxor	%f48, %f16, %f48
-	fxor	%f50, %f18, %f50
-	fxor	%f52, %f20, %f52
-	fxor	%f54, %f22, %f54
-	fxor	%f56, %f24, %f56
-	fxor	%f58, %f26, %f58
-	fxor	%f60, %f28, %f60
-	fxor	%f62, %f30, %f62
-	membar	#Sync
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	stda	%f48, [%o1] %asi
-	membar	#Sync|#StoreStore|#StoreLoad
-	wr	%g1, %g0, %asi
-	retl
-	 wr	%g0, 0, %fprs
-	.size xor_vis_5, .-xor_vis_5
+__asm__ ("\n\
+	.text\n\
+	.globl xor_vis_2\n\
+	.type xor_vis_2,@function\n\
+xor_vis_2:\n\
+	rd	%fprs, %o5\n\
+	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
+	be,pt	%icc, 0f\n\
+	 sethi	%hi(VISenter), %g1\n\
+	jmpl	%g1 + %lo(VISenter), %g7\n\
+	 add	%g7, 8, %g7\n\
+0:	wr	%g0, FPRS_FEF, %fprs\n\
+	rd	%asi, %g1\n\
+	wr	%g0, ASI_BLK_P, %asi\n\
+	membar	#LoadStore|#StoreLoad|#StoreStore\n\
+	sub	%o0, 128, %o0\n\
+	ldda	[%o1] %asi, %f0\n\
+	ldda	[%o2] %asi, %f16\n\
+\n\
+2:	ldda	[%o1 + 64] %asi, %f32\n\
+	fxor	%f0, %f16, %f16\n\
+	fxor	%f2, %f18, %f18\n\
+	fxor	%f4, %f20, %f20\n\
+	fxor	%f6, %f22, %f22\n\
+	fxor	%f8, %f24, %f24\n\
+	fxor	%f10, %f26, %f26\n\
+	fxor	%f12, %f28, %f28\n\
+	fxor	%f14, %f30, %f30\n\
+	stda	%f16, [%o1] %asi\n\
+	ldda	[%o2 + 64] %asi, %f48\n\
+	ldda	[%o1 + 128] %asi, %f0\n\
+	fxor	%f32, %f48, %f48\n\
+	fxor	%f34, %f50, %f50\n\
+	add	%o1, 128, %o1\n\
+	fxor	%f36, %f52, %f52\n\
+	add	%o2, 128, %o2\n\
+	fxor	%f38, %f54, %f54\n\
+	subcc	%o0, 128, %o0\n\
+	fxor	%f40, %f56, %f56\n\
+	fxor	%f42, %f58, %f58\n\
+	fxor	%f44, %f60, %f60\n\
+	fxor	%f46, %f62, %f62\n\
+	stda	%f48, [%o1 - 64] %asi\n\
+	bne,pt	%xcc, 2b\n\
+	 ldda	[%o2] %asi, %f16\n\
+\n\
+	ldda	[%o1 + 64] %asi, %f32\n\
+	fxor	%f0, %f16, %f16\n\
+	fxor	%f2, %f18, %f18\n\
+	fxor	%f4, %f20, %f20\n\
+	fxor	%f6, %f22, %f22\n\
+	fxor	%f8, %f24, %f24\n\
+	fxor	%f10, %f26, %f26\n\
+	fxor	%f12, %f28, %f28\n\
+	fxor	%f14, %f30, %f30\n\
+	stda	%f16, [%o1] %asi\n\
+	ldda	[%o2 + 64] %asi, %f48\n\
+	membar	#Sync\n\
+	fxor	%f32, %f48, %f48\n\
+	fxor	%f34, %f50, %f50\n\
+	fxor	%f36, %f52, %f52\n\
+	fxor	%f38, %f54, %f54\n\
+	fxor	%f40, %f56, %f56\n\
+	fxor	%f42, %f58, %f58\n\
+	fxor	%f44, %f60, %f60\n\
+	fxor	%f46, %f62, %f62\n\
+	stda	%f48, [%o1 + 64] %asi\n\
+	membar	#Sync|#StoreStore|#StoreLoad\n\
+	wr	%g1, %g0, %asi\n\
+	retl\n\
+	  wr	%g0, 0, %fprs\n\
+	.size xor_vis_2, .-xor_vis_2\n\
+\n\
+\n\
+	.globl xor_vis_3\n\
+	.type xor_vis_3,@function\n\
+xor_vis_3:\n\
+	rd	%fprs, %o5\n\
+	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
+	be,pt	%icc, 0f\n\
+	 sethi	%hi(VISenter), %g1\n\
+	jmpl	%g1 + %lo(VISenter), %g7\n\
+	 add	%g7, 8, %g7\n\
+0:	wr	%g0, FPRS_FEF, %fprs\n\
+	rd	%asi, %g1\n\
+	wr	%g0, ASI_BLK_P, %asi\n\
+	membar	#LoadStore|#StoreLoad|#StoreStore\n\
+	sub	%o0, 64, %o0\n\
+	ldda	[%o1] %asi, %f0\n\
+	ldda	[%o2] %asi, %f16\n\
+\n\
+3:	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f48\n\
+	fxor	%f2, %f18, %f50\n\
+	add	%o1, 64, %o1\n\
+	fxor	%f4, %f20, %f52\n\
+	fxor	%f6, %f22, %f54\n\
+	add	%o2, 64, %o2\n\
+	fxor	%f8, %f24, %f56\n\
+	fxor	%f10, %f26, %f58\n\
+	fxor	%f12, %f28, %f60\n\
+	fxor	%f14, %f30, %f62\n\
+	ldda	[%o1] %asi, %f0\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	add	%o3, 64, %o3\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	subcc	%o0, 64, %o0\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	stda	%f48, [%o1 - 64] %asi\n\
+	bne,pt	%xcc, 3b\n\
+	 ldda	[%o2] %asi, %f16\n\
+\n\
+	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f48\n\
+	fxor	%f2, %f18, %f50\n\
+	fxor	%f4, %f20, %f52\n\
+	fxor	%f6, %f22, %f54\n\
+	fxor	%f8, %f24, %f56\n\
+	fxor	%f10, %f26, %f58\n\
+	fxor	%f12, %f28, %f60\n\
+	fxor	%f14, %f30, %f62\n\
+	membar	#Sync\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	stda	%f48, [%o1] %asi\n\
+	membar	#Sync|#StoreStore|#StoreLoad\n\
+	wr	%g1, %g0, %asi\n\
+	retl\n\
+	 wr	%g0, 0, %fprs\n\
+	.size xor_vis_3, .-xor_vis_3\n\
+\n\
+\n\
+	.globl xor_vis_4\n\
+	.type xor_vis_4,@function\n\
+xor_vis_4:\n\
+	rd	%fprs, %o5\n\
+	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
+	be,pt	%icc, 0f\n\
+	 sethi	%hi(VISenter), %g1\n\
+	jmpl	%g1 + %lo(VISenter), %g7\n\
+	 add	%g7, 8, %g7\n\
+0:	wr	%g0, FPRS_FEF, %fprs\n\
+	rd	%asi, %g1\n\
+	wr	%g0, ASI_BLK_P, %asi\n\
+	membar	#LoadStore|#StoreLoad|#StoreStore\n\
+	sub	%o0, 64, %o0\n\
+	ldda	[%o1] %asi, %f0\n\
+	ldda	[%o2] %asi, %f16\n\
+\n\
+4:	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f16\n\
+	fxor	%f2, %f18, %f18\n\
+	add	%o1, 64, %o1\n\
+	fxor	%f4, %f20, %f20\n\
+	fxor	%f6, %f22, %f22\n\
+	add	%o2, 64, %o2\n\
+	fxor	%f8, %f24, %f24\n\
+	fxor	%f10, %f26, %f26\n\
+	fxor	%f12, %f28, %f28\n\
+	fxor	%f14, %f30, %f30\n\
+	ldda	[%o4] %asi, %f48\n\
+	fxor	%f16, %f32, %f32\n\
+	fxor	%f18, %f34, %f34\n\
+	fxor	%f20, %f36, %f36\n\
+	fxor	%f22, %f38, %f38\n\
+	add	%o3, 64, %o3\n\
+	fxor	%f24, %f40, %f40\n\
+	fxor	%f26, %f42, %f42\n\
+	fxor	%f28, %f44, %f44\n\
+	fxor	%f30, %f46, %f46\n\
+	ldda	[%o1] %asi, %f0\n\
+	fxor	%f32, %f48, %f48\n\
+	fxor	%f34, %f50, %f50\n\
+	fxor	%f36, %f52, %f52\n\
+	add	%o4, 64, %o4\n\
+	fxor	%f38, %f54, %f54\n\
+	fxor	%f40, %f56, %f56\n\
+	fxor	%f42, %f58, %f58\n\
+	subcc	%o0, 64, %o0\n\
+	fxor	%f44, %f60, %f60\n\
+	fxor	%f46, %f62, %f62\n\
+	stda	%f48, [%o1 - 64] %asi\n\
+	bne,pt	%xcc, 4b\n\
+	 ldda	[%o2] %asi, %f16\n\
+\n\
+	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f16\n\
+	fxor	%f2, %f18, %f18\n\
+	fxor	%f4, %f20, %f20\n\
+	fxor	%f6, %f22, %f22\n\
+	fxor	%f8, %f24, %f24\n\
+	fxor	%f10, %f26, %f26\n\
+	fxor	%f12, %f28, %f28\n\
+	fxor	%f14, %f30, %f30\n\
+	ldda	[%o4] %asi, %f48\n\
+	fxor	%f16, %f32, %f32\n\
+	fxor	%f18, %f34, %f34\n\
+	fxor	%f20, %f36, %f36\n\
+	fxor	%f22, %f38, %f38\n\
+	fxor	%f24, %f40, %f40\n\
+	fxor	%f26, %f42, %f42\n\
+	fxor	%f28, %f44, %f44\n\
+	fxor	%f30, %f46, %f46\n\
+	membar	#Sync\n\
+	fxor	%f32, %f48, %f48\n\
+	fxor	%f34, %f50, %f50\n\
+	fxor	%f36, %f52, %f52\n\
+	fxor	%f38, %f54, %f54\n\
+	fxor	%f40, %f56, %f56\n\
+	fxor	%f42, %f58, %f58\n\
+	fxor	%f44, %f60, %f60\n\
+	fxor	%f46, %f62, %f62\n\
+	stda	%f48, [%o1] %asi\n\
+	membar	#Sync|#StoreStore|#StoreLoad\n\
+	wr	%g1, %g0, %asi\n\
+	retl\n\
+	 wr	%g0, 0, %fprs\n\
+	.size xor_vis_4, .-xor_vis_4\n\
+\n\
+\n\
+	.globl xor_vis_5\n\
+	.type xor_vis_5,@function\n\
+xor_vis_5:\n\
+	mov	%o5, %g5\n\
+	rd	%fprs, %o5\n\
+	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
+	be,pt	%icc, 0f\n\
+	 sethi	%hi(VISenter), %g1\n\
+	jmpl	%g1 + %lo(VISenter), %g7\n\
+	 add	%g7, 8, %g7\n\
+0:	wr	%g0, FPRS_FEF, %fprs\n\
+	mov	%g5, %o5\n\
+	rd	%asi, %g1\n\
+	wr	%g0, ASI_BLK_P, %asi\n\
+	membar	#LoadStore|#StoreLoad|#StoreStore\n\
+	sub	%o0, 64, %o0\n\
+	ldda	[%o1] %asi, %f0\n\
+	ldda	[%o2] %asi, %f16\n\
+\n\
+5:	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f48\n\
+	fxor	%f2, %f18, %f50\n\
+	add	%o1, 64, %o1\n\
+	fxor	%f4, %f20, %f52\n\
+	fxor	%f6, %f22, %f54\n\
+	add	%o2, 64, %o2\n\
+	fxor	%f8, %f24, %f56\n\
+	fxor	%f10, %f26, %f58\n\
+	fxor	%f12, %f28, %f60\n\
+	fxor	%f14, %f30, %f62\n\
+	ldda	[%o4] %asi, %f16\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	add	%o3, 64, %o3\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	ldda	[%o5] %asi, %f32\n\
+	fxor	%f48, %f16, %f48\n\
+	fxor	%f50, %f18, %f50\n\
+	add	%o4, 64, %o4\n\
+	fxor	%f52, %f20, %f52\n\
+	fxor	%f54, %f22, %f54\n\
+	add	%o5, 64, %o5\n\
+	fxor	%f56, %f24, %f56\n\
+	fxor	%f58, %f26, %f58\n\
+	fxor	%f60, %f28, %f60\n\
+	fxor	%f62, %f30, %f62\n\
+	ldda	[%o1] %asi, %f0\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	subcc	%o0, 64, %o0\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	stda	%f48, [%o1 - 64] %asi\n\
+	bne,pt	%xcc, 5b\n\
+	 ldda	[%o2] %asi, %f16\n\
+\n\
+	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f48\n\
+	fxor	%f2, %f18, %f50\n\
+	fxor	%f4, %f20, %f52\n\
+	fxor	%f6, %f22, %f54\n\
+	fxor	%f8, %f24, %f56\n\
+	fxor	%f10, %f26, %f58\n\
+	fxor	%f12, %f28, %f60\n\
+	fxor	%f14, %f30, %f62\n\
+	ldda	[%o4] %asi, %f16\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	ldda	[%o5] %asi, %f32\n\
+	fxor	%f48, %f16, %f48\n\
+	fxor	%f50, %f18, %f50\n\
+	fxor	%f52, %f20, %f52\n\
+	fxor	%f54, %f22, %f54\n\
+	fxor	%f56, %f24, %f56\n\
+	fxor	%f58, %f26, %f58\n\
+	fxor	%f60, %f28, %f60\n\
+	fxor	%f62, %f30, %f62\n\
+	membar	#Sync\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	stda	%f48, [%o1] %asi\n\
+	membar	#Sync|#StoreStore|#StoreLoad\n\
+	wr	%g1, %g0, %asi\n\
+	retl\n\
+	 wr	%g0, 0, %fprs\n\
+	.size xor_vis_5, .-xor_vis_5\n\
 ");
 
 static struct xor_block_template xor_block_VIS = {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/ac97_codec.h linux/include/linux/ac97_codec.h
--- linux.orig/include/linux/ac97_codec.h	2001-11-22 19:49:20.000000000 +0000
+++ linux/include/linux/ac97_codec.h	2002-07-20 01:08:24.000000000 +0000
@@ -32,7 +32,7 @@
 #define AC97_PCM_FRONT_DAC_RATE   0x002C       /* PCM Front DAC Rate */
 #define AC97_PCM_SURR_DAC_RATE    0x002E       /* PCM Surround DAC Rate */
 #define AC97_PCM_LFE_DAC_RATE     0x0030       /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE      0x0032       /* PCM LR DAC Rate */
+#define AC97_PCM_LR_ADC_RATE      0x0032       /* PCM LR ADC Rate */
 #define AC97_PCM_MIC_ADC_RATE     0x0034       /* PCM MIC ADC Rate */
 #define AC97_CENTER_LFE_MASTER    0x0036       /* Center + LFE Master Volume */
 #define AC97_SURROUND_MASTER      0x0038       /* Surround (Rear) Master Volume */
@@ -143,6 +143,39 @@
 #define AC97_PWR_PR6              0x4000       /* HP amp powerdown */
 #define AC97_PWR_PR7              0x8000       /* Modem off - if supported */
 
+/* extended audio ID register bit defines */
+#define AC97_EXTID_VRA            0x0001
+#define AC97_EXTID_DRA            0x0002
+#define AC97_EXTID_SPDIF          0x0004
+#define AC97_EXTID_VRM            0x0008
+#define AC97_EXTID_DSA0           0x0010
+#define AC97_EXTID_DSA1           0x0020
+#define AC97_EXTID_CDAC           0x0040
+#define AC97_EXTID_SDAC           0x0080
+#define AC97_EXTID_LDAC           0x0100
+#define AC97_EXTID_AMAP           0x0200
+#define AC97_EXTID_REV0           0x0400
+#define AC97_EXTID_REV1           0x0800
+#define AC97_EXTID_ID0            0x4000
+#define AC97_EXTID_ID1            0x8000
+
+/* extended status register bit defines */
+#define AC97_EXTSTAT_VRA          0x0001
+#define AC97_EXTSTAT_DRA          0x0002
+#define AC97_EXTSTAT_SPDIF        0x0004
+#define AC97_EXTSTAT_VRM          0x0008
+#define AC97_EXTSTAT_SPSA0        0x0010
+#define AC97_EXTSTAT_SPSA1        0x0020
+#define AC97_EXTSTAT_CDAC         0x0040
+#define AC97_EXTSTAT_SDAC         0x0080
+#define AC97_EXTSTAT_LDAC         0x0100
+#define AC97_EXTSTAT_MADC         0x0200
+#define AC97_EXTSTAT_SPCV         0x0400
+#define AC97_EXTSTAT_PRI          0x0800
+#define AC97_EXTSTAT_PRJ          0x1000
+#define AC97_EXTSTAT_PRK          0x2000
+#define AC97_EXTSTAT_PRL          0x4000
+
 /* useful power states */
 #define AC97_PWR_D0               0x0000      /* everything on */
 #define AC97_PWR_D1              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/acpi_serial.h linux/include/linux/acpi_serial.h
--- linux.orig/include/linux/acpi_serial.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/linux/acpi_serial.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,103 +0,0 @@
-/*
- *  linux/include/linux/acpi_serial.h
- *
- *  Copyright (C) 2000  Hewlett-Packard Co.
- *  Copyright (C) 2000  Khalid Aziz <khalid_aziz@hp.com>
- *
- *  Definitions for ACPI defined serial ports (headless console and 
- *  debug ports)
- *
- */
-
-extern void setup_serial_acpi(void *);
-
-/* ACPI table signatures */
-#define ACPI_SPCRT_SIGNATURE	"SPCR"
-#define ACPI_DBGPT_SIGNATURE	"DBGP"
-
-/* Interface type as defined in ACPI serial port tables */
-#define ACPI_SERIAL_INTFC_16550	0
-#define ACPI_SERIAL_INTFC_16450	1
-
-/* Interrupt types for ACPI serial port tables */
-#define ACPI_SERIAL_INT_PCAT	0x01
-#define ACPI_SERIAL_INT_APIC	0x02
-#define ACPI_SERIAL_INT_SAPIC	0x04
-
-/* Baud rates as defined in ACPI serial port tables */
-#define ACPI_SERIAL_BAUD_9600		3
-#define ACPI_SERIAL_BAUD_19200		4
-#define ACPI_SERIAL_BAUD_57600		6
-#define ACPI_SERIAL_BAUD_115200		7
-
-/* Parity as defined in ACPI serial port tables */
-#define ACPI_SERIAL_PARITY_NONE		0
-
-/* Flow control methods as defined in ACPI serial port tables */
-#define ACPI_SERIAL_FLOW_DCD	0x01
-#define ACPI_SERIAL_FLOW_RTS	0x02
-#define ACPI_SERIAL_FLOW_XON	0x04
-
-/* Terminal types as defined in ACPI serial port tables */
-#define ACPI_SERIAL_TERM_VT100		0
-#define ACPI_SERIAL_TERM_VT100X	1
-
-/* PCI Flags as defined by SPCR table */
-#define ACPI_SERIAL_PCIFLAG_PNP	0x00000001
-
-/* Space ID as defined in base address structure in ACPI serial port tables */
-#define ACPI_SERIAL_MEM_SPACE		0
-#define ACPI_SERIAL_IO_SPACE		1
-#define ACPI_SERIAL_PCICONF_SPACE	2
-
-/* 
- * Generic Register Address Structure - as defined by Microsoft 
- * in http://www.microsoft.com/hwdev/onnow/download/LFreeACPI.doc
- *
-*/
-typedef struct {
-	u8  space_id;
-	u8  bit_width;
-	u8  bit_offset;
-	u8  resv;
-	u32 addrl;
-	u32 addrh;
-} gen_regaddr;
-
-/* Space ID for generic register address structure */
-#define REGADDR_SPACE_SYSMEM	0
-#define REGADDR_SPACE_SYSIO	1
-#define REGADDR_SPACE_PCICONFIG	2
-
-/* Serial Port Console Redirection and Debug Port Table formats */
-typedef struct {
-	u8 signature[4];
-	u32 length;
-	u8  rev;
-	u8  chksum;
-	u8  oemid[6];
-	u8  oem_tabid[8];
-	u32 oem_rev;
-	u8  creator_id[4];
-	u32 creator_rev;
-	u8  intfc_type;
-	u8  resv1[3];
-	gen_regaddr base_addr;
-	u8  int_type;
-	u8  irq;
-	u8  global_int[4];
-	u8  baud;
-	u8  parity;
-	u8  stop_bits;
-	u8  flow_ctrl;
-	u8  termtype;
-	u8  language;
-	u16 pci_dev_id;
-	u16 pci_vendor_id;
-	u8  pci_bus;
-	u8  pci_dev;
-	u8  pci_func;
-	u8  pci_flags[4];
-	u8  pci_seg;
-	u32 resv2;
-} acpi_ser_t;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/agp_backend.h linux/include/linux/agp_backend.h
--- linux.orig/include/linux/agp_backend.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/linux/agp_backend.h	2002-07-20 01:08:29.000000000 +0000
@@ -48,6 +48,7 @@
 	INTEL_I815,
 	INTEL_I820,
 	INTEL_I830_M,
+	INTEL_I845_G,
 	INTEL_I840,
 	INTEL_I845,
 	INTEL_I850,
@@ -69,12 +70,15 @@
 	ALI_M1631,
 	ALI_M1632,
 	ALI_M1641,
+	ALI_M1644,
 	ALI_M1647,
 	ALI_M1651,
+	ALI_M1671,
 	ALI_GENERIC,
 	SVWRKS_HE,
 	SVWRKS_LE,
-	SVWRKS_GENERIC
+	SVWRKS_GENERIC,
+	HP_ZX1,
 };
 
 typedef struct _agp_version {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/atmbr2684.h linux/include/linux/atmbr2684.h
--- linux.orig/include/linux/atmbr2684.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/atmbr2684.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,101 @@
+#ifndef _LINUX_ATMBR2684_H
+#define _LINUX_ATMBR2684_H
+
+#include <linux/atm.h>
+#include <linux/if.h>		/* For IFNAMSIZ */
+
+/*
+ * Type of media we're bridging (ethernet, token ring, etc)  Currently only
+ * ethernet is supported
+ */
+#define BR2684_MEDIA_ETHERNET	(0)	/* 802.3 */
+#define BR2684_MEDIA_802_4	(1)	/* 802.4 */
+#define BR2684_MEDIA_TR		(2)	/* 802.5 - token ring */
+#define BR2684_MEDIA_FDDI	(3)
+#define BR2684_MEDIA_802_6	(4)	/* 802.6 */
+
+/*
+ * Is there FCS inbound on this VC?  This currently isn't supported.
+ */
+#define BR2684_FCSIN_NO		(0)
+#define BR2684_FCSIN_IGNORE	(1)
+#define BR2684_FCSIN_VERIFY	(2)
+
+/*
+ * Is there FCS outbound on this VC?  This currently isn't supported.
+ */
+#define BR2684_FCSOUT_NO	(0)
+#define BR2684_FCSOUT_SENDZERO	(1)
+#define BR2684_FCSOUT_GENERATE	(2)
+
+/*
+ * Does this VC include LLC encapsulation?
+ */
+#define BR2684_ENCAPS_VC	(0)	/* VC-mux */
+#define BR2684_ENCAPS_LLC	(1)
+#define BR2684_ENCAPS_AUTODETECT (2)	/* Unsuported */
+
+/*
+ * This is for the ATM_NEWBACKENDIF call - these are like socket families:
+ * the first element of the structure is the backend number and the rest
+ * is per-backend specific
+ */
+struct atm_newif_br2684 {
+	atm_backend_t	backend_num;	/* ATM_BACKEND_BR2684 */
+	int		media;		/* BR2684_MEDIA_* */
+	char		ifname[IFNAMSIZ];
+	int		mtu;
+};
+
+/*
+ * This structure is used to specify a br2684 interface - either by a
+ * positive integer (returned by ATM_NEWBACKENDIF) or the interfaces name
+ */
+#define BR2684_FIND_BYNOTHING	(0)
+#define BR2684_FIND_BYNUM	(1)
+#define BR2684_FIND_BYIFNAME	(2)
+struct br2684_if_spec {
+	int method;			/* BR2684_FIND_* */
+	union {
+		char		ifname[IFNAMSIZ];
+		int		devnum;
+	} spec;
+};
+
+/*
+ * This is for the ATM_SETBACKEND call - these are like socket families:
+ * the first element of the structure is the backend number and the rest
+ * is per-backend specific
+ */
+struct atm_backend_br2684 {
+	atm_backend_t	backend_num;	/* ATM_BACKEND_BR2684 */
+	struct br2684_if_spec ifspec;
+	int	fcs_in;		/* BR2684_FCSIN_* */
+	int	fcs_out;	/* BR2684_FCSOUT_* */
+	int	fcs_auto;	/* 1: fcs_{in,out} disabled if no FCS rx'ed */
+	int	encaps;		/* BR2684_ENCAPS_* */
+	int	has_vpiid;	/* 1: use vpn_id - Unsupported */
+	__u8	vpn_id[7];
+	int	send_padding;	/* unsupported */
+	int	min_size;	/* we will pad smaller packets than this */
+};
+
+/*
+ * The BR2684_SETFILT ioctl is an experimental mechanism for folks
+ * terminating a large number of IP-only vcc's.  When netfilter allows
+ * efficient per-if in/out filters, this support will be removed
+ */
+struct br2684_filter {
+	__u32	prefix;		/* network byte order */
+	__u32	netmask;	/* 0 = disable filter */
+};
+
+struct br2684_filter_set {
+	struct br2684_if_spec ifspec;
+	struct br2684_filter filter;
+};
+
+#define BR2684_SETFILT	_IOW( 'a', ATMIOC_BACKEND + 0, \
+				struct br2684_filter_set)
+
+#endif /* _LINUX_ATMBR2684_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/atmdev.h linux/include/linux/atmdev.h
--- linux.orig/include/linux/atmdev.h	2001-11-22 19:49:02.000000000 +0000
+++ linux/include/linux/atmdev.h	2002-07-20 01:08:30.000000000 +0000
@@ -95,6 +95,8 @@
 					/* enable or disable single-copy */
 #define ATM_SETBACKEND	_IOW('a',ATMIOC_SPECIAL+2,atm_backend_t)
 					/* set backend handler */
+#define ATM_NEWBACKENDIF _IOW('a',ATMIOC_SPECIAL+3,atm_backend_t)
+					/* use backend to make new if */
 
 /*
  * These are backend handkers that can be set via the ATM_SETBACKEND call
@@ -103,7 +105,7 @@
  */
 #define ATM_BACKEND_RAW		0	
 #define ATM_BACKEND_PPP		1	/* PPPoATM - RFC2364 */
-#define ATM_BACKEND_BR_2684	2	/* Bridged RFC1483/2684 */
+#define ATM_BACKEND_BR2684	2	/* Bridged RFC1483/2684 */
 
 /* for ATM_GETTYPE */
 #define ATM_ITFTYP_LEN	8	/* maximum length of interface type name */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/auto_fs.h linux/include/linux/auto_fs.h
--- linux.orig/include/linux/auto_fs.h	2001-11-22 19:46:40.000000000 +0000
+++ linux/include/linux/auto_fs.h	2002-07-20 01:08:21.000000000 +0000
@@ -45,7 +45,7 @@
  * If so, 32-bit user-space code should be backwards compatible.
  */
 
-#if defined(__sparc__) || defined(__mips__)
+#if defined(__sparc__) || defined(__mips__) || defined(__s390__)
 typedef unsigned int autofs_wqt_t;
 #else
 typedef unsigned long autofs_wqt_t;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/blk.h linux/include/linux/blk.h
--- linux.orig/include/linux/blk.h	2001-11-22 19:48:07.000000000 +0000
+++ linux/include/linux/blk.h	2002-07-20 01:08:30.000000000 +0000
@@ -59,8 +59,6 @@
 void add_blkdev_randomness(int major);
 
 extern int floppy_init(void);
-extern void rd_load(void);
-extern int rd_init(void);
 extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
 extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
 extern int rd_image_start;	/* starting block # of image */
@@ -70,7 +68,6 @@
 #define INITRD_MINOR 250 /* shouldn't collide with /dev/ram* too soon ... */
 
 extern unsigned long initrd_start,initrd_end;
-extern int mount_initrd; /* zero if initrd should not be mounted */
 extern int initrd_below_start_ok; /* 1 if it is not an error if initrd_start < memory_start */
 void initrd_init(void);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux.orig/include/linux/blkdev.h	2001-11-26 13:29:17.000000000 +0000
+++ linux/include/linux/blkdev.h	2002-07-20 01:08:28.000000000 +0000
@@ -30,6 +30,7 @@
 	kdev_t rq_dev;
 	int cmd;		/* READ or WRITE */
 	int errors;
+	unsigned long start_time;
 	unsigned long sector;
 	unsigned long nr_sectors;
 	unsigned long hard_sector, hard_nr_sectors;
@@ -79,6 +80,16 @@
 	struct request_list	rq[2];
 
 	/*
+	 * The total number of requests on each queue
+	 */
+	int nr_requests;
+
+	/*
+	 * Batching threshold for sleep/wakeup decisions
+	 */
+	int batch_requests;
+
+	/*
 	 * Together with queue_head for cacheline sharing
 	 */
 	struct list_head	queue_head;
@@ -119,9 +130,9 @@
 	spinlock_t		queue_lock;
 
 	/*
-	 * Tasks wait here for free request
+	 * Tasks wait here for free read and write requests
 	 */
-	wait_queue_head_t	wait_for_request;
+	wait_queue_head_t	wait_for_requests[2];
 };
 
 struct blk_dev_struct {
@@ -157,6 +168,7 @@
 /*
  * Access functions for manipulating queue properties
  */
+extern int blk_grow_request_list(request_queue_t *q, int nr_requests);
 extern void blk_init_queue(request_queue_t *, request_fn_proc *);
 extern void blk_cleanup_queue(request_queue_t *);
 extern void blk_queue_headactive(request_queue_t *, int);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/brlvger.h linux/include/linux/brlvger.h
--- linux.orig/include/linux/brlvger.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/brlvger.h	2002-07-20 01:08:22.000000000 +0000
@@ -0,0 +1,57 @@
+/*
+ *      Tieman Voyager braille display USB driver.
+ *
+ *      Copyright 2001-2002 Stephane Dalton <sdalton@videotron.ca>
+ *                      and Stéphane Doyon  <s.doyon@videotron.ca>
+ *            Maintained by Stéphane Doyon  <s.doyon@videotron.ca>.
+ */
+/*
+ *  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
+ */
+
+#ifndef _LINUX_BRLVGER_H
+#define _LINUX_BRLVGER_H
+
+/* Ioctl request codes */
+#define BRLVGER_GET_INFO	0
+#define BRLVGER_DISPLAY_ON	2
+#define BRLVGER_DISPLAY_OFF	3
+#define BRLVGER_BUZZ		4
+
+/* Number of supported devices, and range of covered minors */
+#define MAX_NR_BRLVGER_DEVS	4
+
+/* Base minor for the char devices */
+#define BRLVGER_MINOR		128
+
+/* Size of some fields */
+#define BRLVGER_HWVER_SIZE	2
+#define BRLVGER_FWVER_SIZE	200 /* arbitrary, a long string */
+#define BRLVGER_SERIAL_BIN_SIZE	8
+#define BRLVGER_SERIAL_SIZE	((2*BRLVGER_SERIAL_BIN_SIZE)+1)
+
+struct brlvger_info {
+	__u8 driver_version[12];
+	__u8 driver_banner[200];
+
+	__u32 display_length;
+	/* All other char[] fields are strings except this one.
+	   Hardware version: first byte is major, second byte is minor. */
+	__u8 hwver[BRLVGER_HWVER_SIZE];
+	__u8 fwver[BRLVGER_FWVER_SIZE];
+	__u8 serialnum[BRLVGER_SERIAL_SIZE];
+};
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/byteorder/generic.h linux/include/linux/byteorder/generic.h
--- linux.orig/include/linux/byteorder/generic.h	2000-01-20 18:48:36.000000000 +0000
+++ linux/include/linux/byteorder/generic.h	2002-07-20 01:08:21.000000000 +0000
@@ -157,7 +157,7 @@
 extern unsigned short int	htons(unsigned short int);
 
 
-#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__)
+#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) && !defined(__STRICT_ANSI__)
 
 #define ___htonl(x) __cpu_to_be32(x)
 #define ___htons(x) __cpu_to_be16(x)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/cciss_ioctl.h linux/include/linux/cciss_ioctl.h
--- linux.orig/include/linux/cciss_ioctl.h	2001-05-01 23:05:00.000000000 +0000
+++ linux/include/linux/cciss_ioctl.h	2002-07-20 01:08:34.000000000 +0000
@@ -169,6 +169,11 @@
   BYTE			   *buf;
 } IOCTL_Command_struct;
 
+typedef struct _LogvolInfo_struct{
+   __u32	LunID;
+   int		num_opens;  /* number of opens on the logical volume */
+   int		num_parts;  /* number of partitions configured on logvol */
+} LogvolInfo_struct;
 
 #define CCISS_GETPCIINFO _IOR(CCISS_IOC_MAGIC, 1, cciss_pci_info_struct)
 
@@ -182,8 +187,9 @@
 #define CCISS_GETBUSTYPES  _IOR(CCISS_IOC_MAGIC, 7, BusTypes_type)
 #define CCISS_GETFIRMVER   _IOR(CCISS_IOC_MAGIC, 8, FirmwareVer_type)
 #define CCISS_GETDRIVVER   _IOR(CCISS_IOC_MAGIC, 9, DriverVer_type)
-#define CCISS_REVALIDVOLS  _IO(CCISS_IOC_MAGIC, 10)
+#define CCISS_REVALIDVOLS  _IO(CCISS_IOC_MAGIC, 10) /* obsolete */
 #define CCISS_PASSTHRU	   _IOWR(CCISS_IOC_MAGIC, 11, IOCTL_Command_struct)
+#define CCISS_GETLUNINFO  _IOR(CCISS_IOC_MAGIC, 17, LogvolInfo_struct)
 
 
 #endif  
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/coda_fs_i.h linux/include/linux/coda_fs_i.h
--- linux.orig/include/linux/coda_fs_i.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/coda_fs_i.h	2002-07-20 01:08:31.000000000 +0000
@@ -20,12 +20,24 @@
         struct ViceFid     c_fid;	/* Coda identifier */
         u_short	           c_flags;     /* flags (see below) */
 	struct list_head   c_cilist;    /* list of all coda inodes */
-	struct file	  *c_container; /* container file for this cnode */
-	unsigned int       c_contcount; /* refcount for container file */
+	int		   c_mapcount;	/* how often is this inode mmapped */
         struct coda_cred   c_cached_cred; /* credentials of cached perms */
         unsigned int       c_cached_perm; /* cached access permissions */
 };
 
+/*
+ * coda fs file private data
+ */
+#define CODA_MAGIC 0xC0DAC0DA
+struct coda_file_info {
+	int		 cfi_magic;	/* magic number */
+	int		 cfi_mapcount;  /* how often this file is mapped */
+	struct file	*cfi_container;	/* container file for this cnode */
+	struct coda_cred cfi_cred;	/* credentials of opener */
+};
+
+#define CODA_FTOC(file) ((struct coda_file_info *)((file)->private_data))
+
 /* flags */
 #define C_VATTR       0x1   /* Validity of vattr in inode */
 #define C_FLUSH       0x2   /* used after a flush */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/coda_linux.h linux/include/linux/coda_linux.h
--- linux.orig/include/linux/coda_linux.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/linux/coda_linux.h	2002-07-20 01:08:27.000000000 +0000
@@ -21,6 +21,7 @@
 #include <linux/wait.h>		
 #include <linux/types.h>
 #include <linux/fs.h>
+#include <linux/coda_fs_i.h>
 
 /* operations */
 extern struct inode_operations coda_dir_inode_operations;
@@ -45,7 +46,6 @@
 
 /* global variables */
 extern int coda_debug;
-extern int coda_print_entry;
 extern int coda_access_cache;
 extern int coda_fake_statfs;
 
@@ -54,7 +54,6 @@
 static __inline__ char *coda_i2s(struct inode *);
 static __inline__ void coda_flag_inode(struct inode *, int flag);
 char *coda_f2s(ViceFid *f);
-char *coda_f2s2(ViceFid *f);
 int coda_isroot(struct inode *i);
 int coda_iscontrol(const char *name, size_t length);
 
@@ -92,22 +91,19 @@
     printk(format, ## a); }                                       \
 } while (0)
 
-#define CODA_ALLOC(ptr, cast, size)                                       \
-do {                                                                      \
-    if (size < PAGE_SIZE) {                                               \
-        ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL);            \
-        CDEBUG(D_MALLOC, "kmalloced: %lx at %p.\n", (long)size, ptr);     \
-     }  else {                                                            \
-        ptr = (cast)vmalloc((unsigned long) size);                        \
-	CDEBUG(D_MALLOC, "vmalloced: %lx at %p .\n", (long)size, ptr);}   \
-    if (ptr == 0) {                                                       \
+#define CODA_ALLOC(ptr, cast, size) do { \
+    if (size < PAGE_SIZE) \
+        ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL); \
+    else \
+        ptr = (cast)vmalloc((unsigned long) size); \
+    if (!ptr) \
         printk("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
-    }                                                                     \
-    else memset( ptr, 0, size );                                          \
+    else memset( ptr, 0, size ); \
 } while (0)
 
 
-#define CODA_FREE(ptr,size) do {if (size < PAGE_SIZE) { kfree((ptr)); CDEBUG(D_MALLOC, "kfreed: %lx at %p.\n", (long) size, ptr); } else { vfree((ptr)); CDEBUG(D_MALLOC, "vfreed: %lx at %p.\n", (long) size, ptr);} } while (0)
+#define CODA_FREE(ptr,size) \
+    do { if (size < PAGE_SIZE) kfree((ptr)); else vfree((ptr)); } while (0)
 
 /* inode to cnode access functions */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/coda_psdev.h linux/include/linux/coda_psdev.h
--- linux.orig/include/linux/coda_psdev.h	2001-04-25 23:18:54.000000000 +0000
+++ linux/include/linux/coda_psdev.h	2002-07-20 01:08:37.000000000 +0000
@@ -11,6 +11,7 @@
 	struct venus_comm * sbi_vcomm;
 	struct super_block *sbi_sb;
 	struct list_head    sbi_cihead;
+	struct semaphore    sbi_iget4_mutex;
 };
 
 /* communication pending/processing queues */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/console.h linux/include/linux/console.h
--- linux.orig/include/linux/console.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/console.h	2002-07-20 01:08:34.000000000 +0000
@@ -97,7 +97,6 @@
 	void	(*write)(struct console *, const char *, unsigned);
 	int	(*read)(struct console *, const char *, unsigned);
 	kdev_t	(*device)(struct console *);
-	int	(*wait_key)(struct console *);
 	void	(*unblank)(void);
 	int	(*setup)(struct console *, char *);
 	short	flags;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/cramfs_fs.h linux/include/linux/cramfs_fs.h
--- linux.orig/include/linux/cramfs_fs.h	2001-07-19 23:14:53.000000000 +0000
+++ linux/include/linux/cramfs_fs.h	2002-07-20 01:08:30.000000000 +0000
@@ -24,6 +24,12 @@
 #define CRAMFS_OFFSET_WIDTH 26
 
 /*
+ * Since inode.namelen is a unsigned 6-bit number, the maximum cramfs
+ * path length is 63 << 2 = 252.
+ */
+#define CRAMFS_MAXPATHLEN (((1 << CRAMFS_NAMELEN_WIDTH) - 1) << 2)
+
+/*
  * Reasonably terse representation of the inode data.
  */
 struct cramfs_inode {
@@ -52,14 +58,14 @@
  * Superblock information at the beginning of the FS.
  */
 struct cramfs_super {
-	u32 magic;		/* 0x28cd3d45 - random number */
-	u32 size;		/* length in bytes */
-	u32 flags;		/* 0 */
-	u32 future;		/* 0 */
-	u8 signature[16];	/* "Compressed ROMFS" */
+	u32 magic;			/* 0x28cd3d45 - random number */
+	u32 size;			/* length in bytes */
+	u32 flags;			/* feature flags */
+	u32 future;			/* reserved for future use */
+	u8 signature[16];		/* "Compressed ROMFS" */
 	struct cramfs_info fsid;	/* unique filesystem info */
-	u8 name[16];		/* user-defined name */
-	struct cramfs_inode root;	/* Root inode data */
+	u8 name[16];			/* user-defined name */
+	struct cramfs_inode root;	/* root inode data */
 };
 
 /*
@@ -79,7 +85,10 @@
  * if (flags & ~CRAMFS_SUPPORTED_FLAGS).  Maybe that should be
  * changed to test super.future instead.
  */
-#define CRAMFS_SUPPORTED_FLAGS (0x7ff)
+#define CRAMFS_SUPPORTED_FLAGS	( 0x000000ff \
+				| CRAMFS_FLAG_HOLES \
+				| CRAMFS_FLAG_WRONG_SIGNATURE \
+				| CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
 
 /* Uncompression interfaces to the underlying zlib */
 int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/crc32.h linux/include/linux/crc32.h
--- linux.orig/include/linux/crc32.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/crc32.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,49 @@
+/*
+ * crc32.h for early Linux 2.4.19pre kernel inclusion
+ * This defines ether_crc_le() and ether_crc() as inline functions
+ * This is slated to change to using the library crc32 functions
+ * as kernel 2.5.2 included at some future date.
+ */
+#ifndef _LINUX_CRC32_H
+#define _LINUX_CRC32_H
+
+#include <linux/types.h>
+
+/* The little-endian AUTODIN II ethernet CRC calculation.
+   N.B. Do not use for bulk data, use a table-based routine instead.
+   This is common code and should be moved to net/core/crc.c */
+static unsigned const ethernet_polynomial_le = 0xedb88320U;
+static inline unsigned ether_crc_le(int length, unsigned char *data)
+{
+	unsigned int crc = 0xffffffff;	/* Initial value. */
+	while(--length >= 0) {
+		unsigned char current_octet = *data++;
+		int bit;
+		for (bit = 8; --bit >= 0; current_octet >>= 1) {
+			if ((crc ^ current_octet) & 1) {
+				crc >>= 1;
+				crc ^= ethernet_polynomial_le;
+			} else
+				crc >>= 1;
+		}
+	}
+	return crc;
+}
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+	int crc = -1;
+	while (--length >= 0) {
+		unsigned char current_octet = *data++;
+		int bit;
+		for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+			crc = (crc << 1) ^
+				((crc < 0) ^ (current_octet & 1) ?
+				 ethernet_polynomial : 0);
+		}
+	}
+	return crc;
+}
+
+#endif /* _LINUX_CRC32_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/dcache.h linux/include/linux/dcache.h
--- linux.orig/include/linux/dcache.h	2001-11-22 19:46:18.000000000 +0000
+++ linux/include/linux/dcache.h	2002-07-20 01:08:36.000000000 +0000
@@ -244,7 +244,7 @@
 {
 	if (dentry) {
 		if (!atomic_read(&dentry->d_count))
-			BUG();
+			out_of_line_bug();
 		atomic_inc(&dentry->d_count);
 	}
 	return dentry;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/devfs_fs_kernel.h linux/include/linux/devfs_fs_kernel.h
--- linux.orig/include/linux/devfs_fs_kernel.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/linux/devfs_fs_kernel.h	2002-07-20 01:08:39.000000000 +0000
@@ -3,7 +3,7 @@
 
 #include <linux/fs.h>
 #include <linux/config.h>
-#include <linux/locks.h>
+#include <linux/spinlock.h>
 #include <linux/kdev_t.h>
 #include <linux/types.h>
 
@@ -46,14 +46,6 @@
 
 typedef struct devfs_entry * devfs_handle_t;
 
-
-#ifdef CONFIG_BLK_DEV_INITRD
-#  define ROOT_DEVICE_NAME ((real_root_dev ==ROOT_DEV) ? root_device_name:NULL)
-#else
-#  define ROOT_DEVICE_NAME root_device_name
-#endif
-
-
 #ifdef CONFIG_DEVFS_FS
 
 struct unique_numspace
@@ -62,7 +54,7 @@
     unsigned char sem_initialised;
     unsigned int num_free;          /*  Num free in bits       */
     unsigned int length;            /*  Array length in bytes  */
-    __u32 *bits;
+    unsigned long *bits;
     struct semaphore semaphore;
 };
 
@@ -124,7 +116,6 @@
 					 int number);
 
 extern void mount_devfs_fs (void);
-extern void devfs_make_root (const char *name);
 
 #else  /*  CONFIG_DEVFS_FS  */
 
@@ -320,10 +311,6 @@
 {
     return;
 }
-static inline void devfs_make_root (const char *name)
-{
-    return;
-}
 #endif  /*  CONFIG_DEVFS_FS  */
 
 #endif  /*  _LINUX_DEVFS_FS_KERNEL_H  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/dnotify.h linux/include/linux/dnotify.h
--- linux.orig/include/linux/dnotify.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/dnotify.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,21 +1,20 @@
 /*
  * Directory notification for Linux
  *
- * Copyright 2000 (C) Stephen Rothwell
+ * Copyright (C) 2000,2002 Stephen Rothwell
  */
 
 struct dnotify_struct {
 	struct dnotify_struct *	dn_next;
-	int			dn_magic;
 	unsigned long		dn_mask;	/* Events to be notified
 						   see linux/fcntl.h */
 	int			dn_fd;
 	struct file *		dn_filp;
+	fl_owner_t		dn_owner;
 };
 
-#define DNOTIFY_MAGIC	0x444E4F54
-
 extern void __inode_dir_notify(struct inode *, unsigned long);
+extern void dnotify_flush(struct file *filp, fl_owner_t id);
 extern int fcntl_dirnotify(int, struct file *, unsigned long);
 
 static inline void inode_dir_notify(struct inode *inode, unsigned long event)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/ethtool.h linux/include/linux/ethtool.h
--- linux.orig/include/linux/ethtool.h	2001-11-19 23:19:42.000000000 +0000
+++ linux/include/linux/ethtool.h	2002-07-20 01:08:29.000000000 +0000
@@ -4,6 +4,9 @@
  * Copyright (C) 1998 David S. Miller (davem@redhat.com)
  * Copyright 2001 Jeff Garzik <jgarzik@mandrakesoft.com>
  * Portions Copyright 2001 Sun Microsystems (thockin@sun.com)
+ * Portions Copyright 2002 Intel (eli.kupermann@intel.com,
+ *                                christopher.leech@intel.com,
+ *                                scott.feldman@intel.com)
  */
 
 #ifndef _LINUX_ETHTOOL_H
@@ -36,7 +39,8 @@
 	char	bus_info[ETHTOOL_BUSINFO_LEN];	/* Bus info for this IF. */
 				/* For PCI devices, use pci_dev->slot_name. */
 	char	reserved1[32];
-	char	reserved2[24];
+	char	reserved2[20];
+	u32	testinfo_len;
 	u32	eedump_len;	/* Size of data from ETHTOOL_GEEPROM (bytes) */
 	u32	regdump_len;	/* Size of data from ETHTOOL_GREGS (bytes) */
 };
@@ -72,6 +76,172 @@
 	u32	len; /* in bytes */
 	u8	data[0];
 };
+
+/* for configuring coalescing parameters of chip */
+struct ethtool_coalesce {
+	u32	cmd;	/* ETHTOOL_{G,S}COALESCE */
+
+	/* How many usecs to delay an RX interrupt after
+	 * a packet arrives.  If 0, only rx_max_coalesced_frames
+	 * is used.
+	 */
+	u32	rx_coalesce_usecs;
+
+	/* How many packets to delay an RX interrupt after
+	 * a packet arrives.  If 0, only rx_coalesce_usecs is
+	 * used.  It is illegal to set both usecs and max frames
+	 * to zero as this would cause RX interrupts to never be
+	 * generated.
+	 */
+	u32	rx_max_coalesced_frames;
+
+	/* Same as above two parameters, except that these values
+	 * apply while an IRQ is being services by the host.  Not
+	 * all cards support this feature and the values are ignored
+	 * in that case.
+	 */
+	u32	rx_coalesce_usecs_irq;
+	u32	rx_max_coalesced_frames_irq;
+
+	/* How many usecs to delay a TX interrupt after
+	 * a packet is sent.  If 0, only tx_max_coalesced_frames
+	 * is used.
+	 */
+	u32	tx_coalesce_usecs;
+
+	/* How many packets to delay a TX interrupt after
+	 * a packet is sent.  If 0, only tx_coalesce_usecs is
+	 * used.  It is illegal to set both usecs and max frames
+	 * to zero as this would cause TX interrupts to never be
+	 * generated.
+	 */
+	u32	tx_max_coalesced_frames;
+
+	/* Same as above two parameters, except that these values
+	 * apply while an IRQ is being services by the host.  Not
+	 * all cards support this feature and the values are ignored
+	 * in that case.
+	 */
+	u32	tx_coalesce_usecs_irq;
+	u32	tx_max_coalesced_frames_irq;
+
+	/* How many usecs to delay in-memory statistics
+	 * block updates.  Some drivers do not have an in-memory
+	 * statistic block, and in such cases this value is ignored.
+	 * This value must not be zero.
+	 */
+	u32	stats_block_coalesce_usecs;
+
+	/* Adaptive RX/TX coalescing is an algorithm implemented by
+	 * some drivers to improve latency under low packet rates and
+	 * improve throughput under high packet rates.  Some drivers
+	 * only implement one of RX or TX adaptive coalescing.  Anything
+	 * not implemented by the driver causes these values to be
+	 * silently ignored.
+	 */
+	u32	use_adaptive_rx_coalesce;
+	u32	use_adaptive_tx_coalesce;
+
+	/* When the packet rate (measured in packets per second)
+	 * is below pkt_rate_low, the {rx,tx}_*_low parameters are
+	 * used.
+	 */
+	u32	pkt_rate_low;
+	u32	rx_coalesce_usecs_low;
+	u32	rx_max_coalesced_frames_low;
+	u32	tx_coalesce_usecs_low;
+	u32	tx_max_coalesced_frames_low;
+
+	/* When the packet rate is below pkt_rate_high but above
+	 * pkt_rate_low (both measured in packets per second) the
+	 * normal {rx,tx}_* coalescing parameters are used.
+	 */
+
+	/* When the packet rate is (measured in packets per second)
+	 * is above pkt_rate_high, the {rx,tx}_*_high parameters are
+	 * used.
+	 */
+	u32	pkt_rate_high;
+	u32	rx_coalesce_usecs_high;
+	u32	rx_max_coalesced_frames_high;
+	u32	tx_coalesce_usecs_high;
+	u32	tx_max_coalesced_frames_high;
+
+	/* How often to do adaptive coalescing packet rate sampling,
+	 * measured in seconds.  Must not be zero.
+	 */
+	u32	rate_sample_interval;
+};
+
+/* for configuring RX/TX ring parameters */
+struct ethtool_ringparam {
+	u32	cmd;	/* ETHTOOL_{G,S}RINGPARAM */
+
+	/* Read only attributes.  These indicate the maximum number
+	 * of pending RX/TX ring entries the driver will allow the
+	 * user to set.
+	 */
+	u32	rx_max_pending;
+	u32	rx_mini_max_pending;
+	u32	rx_jumbo_max_pending;
+	u32	tx_max_pending;
+
+	/* Values changeable by the user.  The valid values are
+	 * in the range 1 to the "*_max_pending" counterpart above.
+	 */
+	u32	rx_pending;
+	u32	rx_mini_pending;
+	u32	rx_jumbo_pending;
+	u32	tx_pending;
+};
+
+/* for configuring link flow control parameters */
+struct ethtool_pauseparam {
+	u32	cmd;	/* ETHTOOL_{G,S}PAUSEPARAM */
+
+	/* If the link is being auto-negotiated (via ethtool_cmd.autoneg
+	 * being true) the user may set 'autonet' here non-zero to have the
+	 * pause parameters be auto-negotiated too.  In such a case, the
+	 * {rx,tx}_pause values below determine what capabilities are
+	 * advertised.
+	 *
+	 * If 'autoneg' is zero or the link is not being auto-negotiated,
+	 * then {rx,tx}_pause force the driver to use/not-use pause
+	 * flow control.
+	 */
+	u32	autoneg;
+	u32	rx_pause;
+	u32	tx_pause;
+};
+
+#define ETH_GSTRING_LEN		32
+enum ethtool_stringset {
+	ETH_SS_TEST		= 0,
+	ETH_SS_STATS,
+};
+
+/* for passing string sets for data tagging */
+struct ethtool_gstrings {
+	u32	cmd;		/* ETHTOOL_GSTRINGS */
+	u32	string_set;	/* string set id e.c. ETH_SS_TEST, etc*/
+	u32	len;		/* number of strings in the string set */
+	u8	data[0];
+};
+
+enum ethtool_test_flags {
+	ETH_TEST_FL_OFFLINE	= (1 << 0),	/* online / offline */
+	ETH_TEST_FL_FAILED	= (1 << 1),	/* test passed / failed */
+};
+
+/* for requesting NIC test and getting results*/
+struct ethtool_test {
+	u32	cmd;		/* ETHTOOL_TEST */
+	u32	flags;		/* ETH_TEST_FL_xxx */
+	u32	reserved;
+	u32	len;		/* result length, in number of u64 elements */
+	u64	data[0];
+};
+
 /* CMDs currently supported */
 #define ETHTOOL_GSET		0x00000001 /* Get settings. */
 #define ETHTOOL_SSET		0x00000002 /* Set settings, privileged. */
@@ -82,9 +252,26 @@
 #define ETHTOOL_GMSGLVL		0x00000007 /* Get driver message level */
 #define ETHTOOL_SMSGLVL		0x00000008 /* Set driver msg level, priv. */
 #define ETHTOOL_NWAY_RST	0x00000009 /* Restart autonegotiation, priv. */
-#define ETHTOOL_GLINK		0x0000000a /* Get link status */
+#define ETHTOOL_GLINK		0x0000000a /* Get link status (ethtool_value) */
 #define ETHTOOL_GEEPROM		0x0000000b /* Get EEPROM data */
-#define ETHTOOL_SEEPROM		0x0000000c /* Set EEPROM data */
+#define ETHTOOL_SEEPROM		0x0000000c /* Set EEPROM data, priv. */
+#define ETHTOOL_GCOALESCE	0x0000000e /* Get coalesce config */
+#define ETHTOOL_SCOALESCE	0x0000000f /* Set coalesce config, priv. */
+#define ETHTOOL_GRINGPARAM	0x00000010 /* Get ring parameters */
+#define ETHTOOL_SRINGPARAM	0x00000011 /* Set ring parameters, priv. */
+#define ETHTOOL_GPAUSEPARAM	0x00000012 /* Get pause parameters */
+#define ETHTOOL_SPAUSEPARAM	0x00000013 /* Set pause parameters, priv. */
+#define ETHTOOL_GRXCSUM		0x00000014 /* Get RX hw csum enable (ethtool_value) */
+#define ETHTOOL_SRXCSUM		0x00000015 /* Set RX hw csum enable (ethtool_value) */
+#define ETHTOOL_GTXCSUM		0x00000016 /* Get TX hw csum enable (ethtool_value) */
+#define ETHTOOL_STXCSUM		0x00000017 /* Set TX hw csum enable (ethtool_value) */
+#define ETHTOOL_GSG		0x00000018 /* Get scatter-gather enable
+					    * (ethtool_value) */
+#define ETHTOOL_SSG		0x00000019 /* Set scatter-gather enable
+					    * (ethtool_value), priv. */
+#define ETHTOOL_TEST		0x0000001a /* execute NIC self-test, priv. */
+#define ETHTOOL_GSTRINGS	0x0000001b /* get specified string set */
+#define ETHTOOL_PHYS_ID		0x0000001c /* identify the NIC */
 
 /* compatibility with older code */
 #define SPARC_ETH_GSET		ETHTOOL_GSET
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/ext2_fs_i.h linux/include/linux/ext2_fs_i.h
--- linux.orig/include/linux/ext2_fs_i.h	2001-09-17 20:16:30.000000000 +0000
+++ linux/include/linux/ext2_fs_i.h	2002-07-20 01:08:36.000000000 +0000
@@ -25,7 +25,6 @@
 	__u32	i_faddr;
 	__u8	i_frag_no;
 	__u8	i_frag_size;
-	__u16	i_osync;
 	__u32	i_file_acl;
 	__u32	i_dir_acl;
 	__u32	i_dtime;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/fb.h linux/include/linux/fb.h
--- linux.orig/include/linux/fb.h	2000-12-11 21:16:53.000000000 +0000
+++ linux/include/linux/fb.h	2002-07-20 01:08:31.000000000 +0000
@@ -93,6 +93,20 @@
 #define FB_ACCEL_IGS_CYBER2010	34	/* CyberPro 2010		*/
 #define FB_ACCEL_IGS_CYBER5000	35	/* CyberPro 5000		*/
 #define FB_ACCEL_SIS_GLAMOUR    36	/* SiS 300/630/540              */
+#define FB_ACCEL_3DLABS_PERMEDIA3 37	/* 3Dlabs Permedia 3		*/
+#define FB_ACCEL_ATI_RADEON	38	/* ATI Radeon family		*/
+
+
+#define FB_ACCEL_NEOMAGIC_NM2070 90	/* NeoMagic NM2070              */
+#define FB_ACCEL_NEOMAGIC_NM2090 91	/* NeoMagic NM2090              */
+#define FB_ACCEL_NEOMAGIC_NM2093 92	/* NeoMagic NM2093              */
+#define FB_ACCEL_NEOMAGIC_NM2097 93	/* NeoMagic NM2097              */
+#define FB_ACCEL_NEOMAGIC_NM2160 94	/* NeoMagic NM2160              */
+#define FB_ACCEL_NEOMAGIC_NM2200 95	/* NeoMagic NM2200              */
+#define FB_ACCEL_NEOMAGIC_NM2230 96	/* NeoMagic NM2230              */
+#define FB_ACCEL_NEOMAGIC_NM2360 97	/* NeoMagic NM2360              */
+#define FB_ACCEL_NEOMAGIC_NM2380 98	/* NeoMagic NM2380              */
+
 
 struct fb_fix_screeninfo {
 	char id[16];			/* identification string eg "TT Builtin" */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/fd.h linux/include/linux/fd.h
--- linux.orig/include/linux/fd.h	1999-08-13 19:16:16.000000000 +0000
+++ linux/include/linux/fd.h	2002-07-20 01:08:31.000000000 +0000
@@ -369,10 +369,4 @@
 #define FDEJECT _IO(2, 0x5a)
 /* eject the disk */
 
-
-#ifdef __KERNEL__
-/* eject the boot floppy (if we need the drive for a different root floppy) */
-void floppy_eject(void);
-#endif
-
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/file.h linux/include/linux/file.h
--- linux.orig/include/linux/file.h	2000-08-23 18:22:26.000000000 +0000
+++ linux/include/linux/file.h	2002-07-20 01:08:21.000000000 +0000
@@ -71,30 +71,7 @@
 	write_unlock(&files->file_lock);
 }
 
-/*
- * Install a file pointer in the fd array.  
- *
- * The VFS is full of places where we drop the files lock between
- * setting the open_fds bitmap and installing the file in the file
- * array.  At any such point, we are vulnerable to a dup2() race
- * installing a file in the array before us.  We need to detect this and
- * fput() the struct file we are about to overwrite in this case.
- *
- * It should never happen - if we allow dup2() do it, _really_ bad things
- * will follow.
- */
-
-static inline void fd_install(unsigned int fd, struct file * file)
-{
-	struct files_struct *files = current->files;
-	
-	write_lock(&files->file_lock);
-	if (files->fd[fd])
-		BUG();
-	files->fd[fd] = file;
-	write_unlock(&files->file_lock);
-}
-
+void fd_install(unsigned int fd, struct file * file);
 void put_files_struct(struct files_struct *fs);
 
 #endif /* __LINUX_FILE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/fs.h linux/include/linux/fs.h
--- linux.orig/include/linux/fs.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/fs.h	2002-07-20 01:08:29.000000000 +0000
@@ -217,7 +217,7 @@
 	BH_New,		/* 1 if the buffer is new and not yet written out */
 	BH_Async,	/* 1 if the buffer is under end_buffer_io_async I/O */
 	BH_Wait_IO,	/* 1 if we should write out this buffer */
-	BH_launder,	/* 1 if we should throttle on this buffer */
+	BH_Launder,	/* 1 if we can throttle on this buffer */
 	BH_JBD,		/* 1 if it has an attached journal_head */
 
 	BH_PrivateStart,/* not a state bit, but the first bit available
@@ -225,6 +225,8 @@
 			 */
 };
 
+#define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
+
 /*
  * Try to keep the most commonly used fields in single cache lines (16
  * bytes) to improve performance.  This ordering should be
@@ -279,6 +281,7 @@
 #define buffer_mapped(bh)	__buffer_state(bh,Mapped)
 #define buffer_new(bh)		__buffer_state(bh,New)
 #define buffer_async(bh)	__buffer_state(bh,Async)
+#define buffer_launder(bh)	__buffer_state(bh,Launder)
 
 #define bh_offset(bh)		((unsigned long)(bh)->b_data & ~PAGE_MASK)
 
@@ -550,6 +553,14 @@
 
 #define	MAX_NON_LFS	((1UL<<31) - 1)
 
+/* Page cache limit. The filesystems should put that into their s_maxbytes 
+   limits, otherwise bad things can happen in VM. */ 
+#if BITS_PER_LONG==32
+#define MAX_LFS_FILESIZE	(((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) 
+#elif BITS_PER_LONG==64
+#define MAX_LFS_FILESIZE 	0x7fffffffffffffff
+#endif
+
 #define FL_POSIX	1
 #define FL_FLOCK	2
 #define FL_BROKEN	4	/* broken flock() emulation */
@@ -984,6 +995,7 @@
 extern struct vfsmount *kern_mount(struct file_system_type *);
 extern int may_umount(struct vfsmount *);
 extern long do_mount(char *, char *, char *, unsigned long, void *);
+extern void umount_tree(struct vfsmount *);
 
 #define kern_umount mntput
 
@@ -1102,7 +1114,7 @@
 
 extern int fs_may_remount_ro(struct super_block *);
 
-extern int try_to_free_buffers(struct page *, unsigned int);
+extern int FASTCALL(try_to_free_buffers(struct page *, unsigned int));
 extern void refile_buffer(struct buffer_head * buf);
 extern void create_empty_buffers(struct page *, kdev_t, unsigned long);
 extern void end_buffer_io_sync(struct buffer_head *bh, int uptodate);
@@ -1153,9 +1165,13 @@
 extern void FASTCALL(__mark_dirty(struct buffer_head *bh));
 extern void FASTCALL(__mark_buffer_dirty(struct buffer_head *bh));
 extern void FASTCALL(mark_buffer_dirty(struct buffer_head *bh));
+extern void FASTCALL(buffer_insert_inode_queue(struct buffer_head *, struct inode *));
 extern void FASTCALL(buffer_insert_inode_data_queue(struct buffer_head *, struct inode *));
 
-#define atomic_set_buffer_dirty(bh) test_and_set_bit(BH_Dirty, &(bh)->b_state)
+static inline int atomic_set_buffer_dirty(struct buffer_head *bh)
+{
+	return test_and_set_bit(BH_Dirty, &bh->b_state);
+}
 
 static inline void mark_buffer_async(struct buffer_head * bh, int on)
 {
@@ -1180,7 +1196,6 @@
 	bh->b_end_io(bh, 0);
 }
 
-extern void buffer_insert_inode_queue(struct buffer_head *, struct inode *);
 static inline void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
 {
 	mark_buffer_dirty(bh);
@@ -1208,10 +1223,15 @@
 extern int fsync_super(struct super_block *);
 extern int fsync_no_super(kdev_t);
 extern void sync_inodes_sb(struct super_block *);
-extern int osync_inode_buffers(struct inode *);
-extern int osync_inode_data_buffers(struct inode *);
-extern int fsync_inode_buffers(struct inode *);
-extern int fsync_inode_data_buffers(struct inode *);
+extern int fsync_buffers_list(struct list_head *);
+static inline int fsync_inode_buffers(struct inode *inode)
+{
+	return fsync_buffers_list(&inode->i_dirty_buffers);
+}
+static inline int fsync_inode_data_buffers(struct inode *inode)
+{
+	return fsync_buffers_list(&inode->i_dirty_data_buffers);
+}
 extern int inode_has_buffers(struct inode *);
 extern int filemap_fdatasync(struct address_space *);
 extern int filemap_fdatawait(struct address_space *);
@@ -1365,6 +1385,8 @@
 		__bforget(buf);
 }
 extern int set_blocksize(kdev_t, int);
+extern int sb_set_blocksize(struct super_block *, int);
+extern int sb_min_blocksize(struct super_block *, int);
 extern struct buffer_head * bread(kdev_t, int, int);
 static inline struct buffer_head * sb_bread(struct super_block *sb, int block)
 {
@@ -1427,7 +1449,12 @@
 extern struct inode_operations page_symlink_inode_operations;
 
 extern int vfs_readdir(struct file *, filldir_t, void *);
+extern int dcache_dir_open(struct inode *, struct file *);
+extern int dcache_dir_close(struct inode *, struct file *);
+extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
+extern int dcache_dir_fsync(struct file *, struct dentry *, int);
 extern int dcache_readdir(struct file *, void *, filldir_t);
+extern struct file_operations dcache_dir_ops;
 
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(kdev_t);
@@ -1448,11 +1475,9 @@
 
 
 extern void show_buffers(void);
-extern void mount_root(void);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 extern unsigned int real_root_dev;
-extern int change_root(kdev_t, const char *);
 #endif
 
 extern ssize_t char_read(struct file *, char *, size_t, loff_t *);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/gameport.h linux/include/linux/gameport.h
--- linux.orig/include/linux/gameport.h	2001-11-22 19:49:20.000000000 +0000
+++ linux/include/linux/gameport.h	2002-07-20 01:08:34.000000000 +0000
@@ -38,6 +38,7 @@
 struct gameport {
 
 	void *private;
+	void *driver;
 
 	int number;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/genhd.h linux/include/linux/genhd.h
--- linux.orig/include/linux/genhd.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/genhd.h	2002-07-20 01:08:26.000000000 +0000
@@ -63,6 +63,22 @@
 	unsigned long nr_sects;
 	devfs_handle_t de;              /* primary (master) devfs entry  */
 	int number;                     /* stupid old code wastes space  */
+
+	/* Performance stats: */
+	unsigned int ios_in_flight;
+	unsigned int io_ticks;
+	unsigned int last_idle_time;
+	unsigned int last_queue_change;
+	unsigned int aveq;
+	
+	unsigned int rd_ios;
+	unsigned int rd_merges;
+	unsigned int rd_ticks;
+	unsigned int rd_sectors;
+	unsigned int wr_ios;
+	unsigned int wr_merges;
+	unsigned int wr_ticks;
+	unsigned int wr_sectors;	
 };
 
 #define GENHD_FL_REMOVABLE  1
@@ -92,6 +108,7 @@
 extern void add_gendisk(struct gendisk *gp);
 extern void del_gendisk(struct gendisk *gp);
 extern struct gendisk *get_gendisk(kdev_t dev);
+extern int walk_gendisk(int (*walk)(struct gendisk *, void *), void *);
 
 #endif  /*  __KERNEL__  */
 
@@ -242,6 +259,19 @@
 
 char *disk_name (struct gendisk *hd, int minor, char *buf);
 
+/*
+ * disk_round_stats is used to round off the IO statistics for a disk
+ * for a complete clock tick.
+ */
+void disk_round_stats(struct hd_struct *hd);
+
+/* 
+ * Account for the completion of an IO request (used by drivers which 
+ * bypass the normal end_request processing) 
+ */
+struct request;
+void req_finished_io(struct request *);
+
 extern void devfs_register_partitions (struct gendisk *dev, int minor,
 				       int unregister);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/hcdp_serial.h linux/include/linux/hcdp_serial.h
--- linux.orig/include/linux/hcdp_serial.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/hcdp_serial.h	2002-07-20 01:08:26.000000000 +0000
@@ -0,0 +1,84 @@
+/*
+ *  linux/include/linux/hcdp_serial.h
+ *
+ *  Copyright (C) 2002  Hewlett-Packard Co.
+ *  Copyright (C) 2002  Khalid Aziz <khalid_aziz@hp.com>
+ *
+ *  Definitions for HCDP defined serial ports (Serial console and 
+ *  debug ports)
+ *
+ */
+#ifndef _LINUX_HCDP_SERIAL_H
+#define _LINUX_HCDP_SERIAL_H
+
+/* ACPI table signatures */
+#define HCDP_SIG_LEN		4
+#define HCDP_SIGNATURE		"HCDP"
+
+/* Space ID as defined in ACPI generic address structure */
+#define ACPI_MEM_SPACE		0
+#define ACPI_IO_SPACE		1
+#define ACPI_PCICONF_SPACE	2
+
+/* 
+ * Maximum number of HCDP devices we want to read in
+ */
+#define MAX_HCDP_DEVICES	6
+
+/*
+ * Default base baud rate if clock rate is 0 in HCDP table.
+ */
+#define DEFAULT_BAUD_BASE	115200
+
+/* 
+ * ACPI Generic Address Structure 
+ */
+typedef struct {
+	u8  space_id;
+	u8  bit_width;
+	u8  bit_offset;
+	u8  resv;
+	u32 addrlo;
+	u32 addrhi;
+} acpi_gen_addr;
+
+/* HCDP Device descriptor entry types */
+#define HCDP_DEV_CONSOLE	0
+#define HCDP_DEV_DEBUG		1
+
+/* HCDP Device descriptor type */
+typedef struct {
+	u8	type;
+	u8	bits;
+	u8	parity;
+	u8	stop_bits;
+	u8	pci_seg;
+	u8	pci_bus;
+	u8	pci_dev;
+	u8	pci_func;
+	u64	baud;
+	acpi_gen_addr	base_addr;
+	u16	pci_dev_id;
+	u16	pci_vendor_id;
+	u32	global_int;
+	u32	clock_rate;
+	u8	pci_prog_intfc;
+	u8	resv;
+} hcdp_dev_t;
+
+/* HCDP Table format */
+typedef struct {
+	u8	signature[4];
+	u32	len;
+	u8	rev;
+	u8	chksum;
+	u8	oemid[6];
+	u8	oem_tabid[8];
+	u32	oem_rev;
+	u8	creator_id[4];
+	u32	creator_rev;
+	u32	num_entries;
+	hcdp_dev_t	hcdp_dev[MAX_HCDP_DEVICES];
+} hcdp_t;
+
+#endif	/* _LINUX_HCDP_SERIAL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/hdreg.h linux/include/linux/hdreg.h
--- linux.orig/include/linux/hdreg.h	2001-11-22 19:46:18.000000000 +0000
+++ linux/include/linux/hdreg.h	2002-07-20 01:08:35.000000000 +0000
@@ -6,104 +6,269 @@
  * Various sources.  
  */
 
-#define HD_IRQ 14		/* the standard disk interrupt */
+#define HD_IRQ 14			/* the standard disk interrupt */
 
 /* ide.c has its own port definitions in "ide.h" */
 
 /* Hd controller regs. Ref: IBM AT Bios-listing */
-#define HD_DATA		0x1f0	/* _CTL when writing */
-#define HD_ERROR	0x1f1	/* see err-bits */
-#define HD_NSECTOR	0x1f2	/* nr of sectors to read/write */
-#define HD_SECTOR	0x1f3	/* starting sector */
-#define HD_LCYL		0x1f4	/* starting cylinder */
-#define HD_HCYL		0x1f5	/* high byte of starting cyl */
-#define HD_CURRENT	0x1f6	/* 101dhhhh , d=drive, hhhh=head */
-#define HD_STATUS	0x1f7	/* see status-bits */
-#define HD_FEATURE HD_ERROR	/* same io address, read=error, write=feature */
-#define HD_PRECOMP HD_FEATURE	/* obsolete use of this port - predates IDE */
-#define HD_COMMAND HD_STATUS	/* same io address, read=status, write=cmd */
+#define HD_DATA		0x1f0		/* _CTL when writing */
+#define HD_ERROR	0x1f1		/* see err-bits */
+#define HD_NSECTOR	0x1f2		/* nr of sectors to read/write */
+#define HD_SECTOR	0x1f3		/* starting sector */
+#define HD_LCYL		0x1f4		/* starting cylinder */
+#define HD_HCYL		0x1f5		/* high byte of starting cyl */
+#define HD_CURRENT	0x1f6		/* 101dhhhh , d=drive, hhhh=head */
+#define HD_STATUS	0x1f7		/* see status-bits */
+#define HD_FEATURE	HD_ERROR	/* same io address, read=error, write=feature */
+#define HD_PRECOMP	HD_FEATURE	/* obsolete use of this port - predates IDE */
+#define HD_COMMAND	HD_STATUS	/* same io address, read=status, write=cmd */
 
-#define HD_CMD		0x3f6	/* used for resets */
-#define HD_ALTSTATUS	0x3f6	/* same as HD_STATUS but doesn't clear irq */
+#define HD_CMD		0x3f6		/* used for resets */
+#define HD_ALTSTATUS	0x3f6		/* same as HD_STATUS but doesn't clear irq */
 
 /* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */
 
 /* Bits of HD_STATUS */
-#define ERR_STAT	0x01
-#define INDEX_STAT	0x02
-#define ECC_STAT	0x04	/* Corrected error */
-#define DRQ_STAT	0x08
-#define SEEK_STAT	0x10
-#define WRERR_STAT	0x20
-#define READY_STAT	0x40
-#define BUSY_STAT	0x80
-
-/* Values for HD_COMMAND */
-#define WIN_RESTORE		0x10
-#define WIN_READ		0x20
-#define WIN_WRITE		0x30
-#define WIN_WRITE_VERIFY	0x3C
-#define WIN_VERIFY		0x40
-#define WIN_FORMAT		0x50
-#define WIN_INIT		0x60
-#define WIN_SEEK		0x70
-#define WIN_DIAGNOSE		0x90
-#define WIN_SPECIFY		0x91	/* set drive geometry translation */
-#define WIN_IDLEIMMEDIATE	0xE1	/* force drive to become "ready" */
-#define WIN_SETIDLE1		0xE3
-#define WIN_SETIDLE2		0x97
-
-#define WIN_STANDBYNOW1		0xE0
-#define WIN_STANDBYNOW2		0x94
-#define WIN_SLEEPNOW1		0xE6
-#define WIN_SLEEPNOW2		0x99
-#define WIN_CHECKPOWERMODE1	0xE5
-#define WIN_CHECKPOWERMODE2	0x98
-
-#define WIN_DOORLOCK		0xDE	/* lock door on removable drives */
-#define WIN_DOORUNLOCK		0xDF	/* unlock door on removable drives */
-
-#define WIN_MULTREAD		0xC4	/* read sectors using multiple mode */
-#define WIN_MULTWRITE		0xC5	/* write sectors using multiple mode */
-#define WIN_SETMULT		0xC6	/* enable/disable multiple mode */
-#define WIN_IDENTIFY		0xEC	/* ask drive to identify itself	*/
-#define WIN_IDENTIFY_DMA	0xEE	/* same as WIN_IDENTIFY, but DMA */
-#define WIN_SETFEATURES		0xEF	/* set special drive features */
-#define WIN_READDMA		0xC8	/* read sectors using DMA transfers */
-#define WIN_WRITEDMA		0xCA	/* write sectors using DMA transfers */
-
-#define WIN_QUEUED_SERVICE	0xA2	/* */
-#define WIN_READDMA_QUEUED	0xC7	/* read sectors using Queued DMA transfers */
-#define WIN_WRITEDMA_QUEUED	0xCC	/* write sectors using Queued DMA transfers */
-
-#define WIN_READ_BUFFER		0xE4	/* force read only 1 sector */
-#define WIN_WRITE_BUFFER	0xE8	/* force write only 1 sector */
-
-#define WIN_SMART		0xB0	/* self-monitoring and reporting */
-
-/* Additional drive command codes used by ATAPI devices. */
-#define WIN_PIDENTIFY		0xA1	/* identify ATAPI device	*/
-#define WIN_SRST		0x08	/* ATAPI soft reset command */
-#define WIN_PACKETCMD		0xA0	/* Send a packet command. */
+#define ERR_STAT		0x01
+#define INDEX_STAT		0x02
+#define ECC_STAT		0x04	/* Corrected error */
+#define DRQ_STAT		0x08
+#define SEEK_STAT		0x10
+#define WRERR_STAT		0x20
+#define READY_STAT		0x40
+#define BUSY_STAT		0x80
 
-#define DISABLE_SEAGATE		0xFB
-#define EXABYTE_ENABLE_NEST	0xF0
+/* Bits for HD_ERROR */
+#define MARK_ERR		0x01	/* Bad address mark */
+#define TRK0_ERR		0x02	/* couldn't find track 0 */
+#define ABRT_ERR		0x04	/* Command aborted */
+#define MCR_ERR			0x08	/* media change request */
+#define ID_ERR			0x10	/* ID field not found */
+#define MC_ERR			0x20	/* media changed */
+#define ECC_ERR			0x40	/* Uncorrectable ECC error */
+#define BBD_ERR			0x80	/* pre-EIDE meaning:  block marked bad */
+#define ICRC_ERR		0x80	/* new meaning:  CRC error during transfer */
 
-/* WIN_SMART sub-commands */
+/*
+ * Command Header sizes for IOCTL commands
+ *	HDIO_DRIVE_CMD, HDIO_DRIVE_TASK, and HDIO_DRIVE_TASKFILE
+ */
+
+#if 0
+#include <asm/hdreg.h>
+typedef ide_ioreg_t task_ioreg_t;
+#else
+typedef unsigned char task_ioreg_t;
+#endif
+
+#define HDIO_DRIVE_CMD_HDR_SIZE		4*sizeof(task_ioreg_t)
+#define HDIO_DRIVE_TASK_HDR_SIZE	8*sizeof(task_ioreg_t)
+#define HDIO_DRIVE_HOB_HDR_SIZE		8*sizeof(task_ioreg_t)
+
+#define IDE_DRIVE_TASK_INVALID		-1
+#define IDE_DRIVE_TASK_NO_DATA		0
+#define IDE_DRIVE_TASK_SET_XFER		1
+
+#define IDE_DRIVE_TASK_IN		2
+
+#define IDE_DRIVE_TASK_OUT		3
+#define IDE_DRIVE_TASK_RAW_WRITE	4
+
+struct hd_drive_cmd_hdr {
+	task_ioreg_t command;
+	task_ioreg_t sector_number;
+	task_ioreg_t feature;
+	task_ioreg_t sector_count;
+};
 
-#define SMART_READ_VALUES	0xd0
-#define SMART_READ_THRESHOLDS	0xd1
-#define SMART_AUTOSAVE		0xd2
-#define SMART_SAVE		0xd3
-#define SMART_IMMEDIATE_OFFLINE	0xd4
-#define SMART_READ_LOG_SECTOR	0xd5
-#define SMART_WRITE_LOG_SECTOR	0xd6
-#define SMART_WRITE_THRESHOLDS	0xd7
-#define SMART_ENABLE		0xd8
-#define SMART_DISABLE		0xd9
-#define SMART_STATUS		0xda
-#define SMART_AUTO_OFFLINE	0xdb
+typedef struct hd_drive_task_hdr {
+	task_ioreg_t data;
+	task_ioreg_t feature;
+	task_ioreg_t sector_count;
+	task_ioreg_t sector_number;
+	task_ioreg_t low_cylinder;
+	task_ioreg_t high_cylinder;
+	task_ioreg_t device_head;
+	task_ioreg_t command;
+} task_struct_t;
+
+typedef struct hd_drive_hob_hdr {
+	task_ioreg_t data;
+	task_ioreg_t feature;
+	task_ioreg_t sector_count;
+	task_ioreg_t sector_number;
+	task_ioreg_t low_cylinder;
+	task_ioreg_t high_cylinder;
+	task_ioreg_t device_head;
+	task_ioreg_t control;
+} hob_struct_t;
+
+typedef union ide_reg_valid_s {
+	unsigned all				: 16;
+	struct {
+		unsigned data			: 1;
+		unsigned error_feature		: 1;
+		unsigned sector			: 1;
+		unsigned nsector		: 1;
+		unsigned lcyl			: 1;
+		unsigned hcyl			: 1;
+		unsigned select			: 1;
+		unsigned status_command		: 1;
+
+		unsigned data_hob		: 1;
+		unsigned error_feature_hob	: 1;
+		unsigned sector_hob		: 1;
+		unsigned nsector_hob		: 1;
+		unsigned lcyl_hob		: 1;
+		unsigned hcyl_hob		: 1;
+		unsigned select_hob		: 1;
+		unsigned control_hob		: 1;
+	} b;
+} ide_reg_valid_t;
 
+/*
+ * Define standard taskfile in/out register
+ */
+#define IDE_TASKFILE_STD_OUT_FLAGS	0xFE
+#define IDE_TASKFILE_STD_IN_FLAGS	0xFE
+#define IDE_HOB_STD_OUT_FLAGS		0xC0
+#define IDE_HOB_STD_IN_FLAGS		0xC0
+
+typedef struct ide_task_request_s {
+	task_ioreg_t	io_ports[8];
+	task_ioreg_t	hob_ports[8];
+	ide_reg_valid_t	out_flags;
+	ide_reg_valid_t	in_flags;
+	int		data_phase;
+	int		req_cmd;
+	unsigned long	out_size;
+	unsigned long	in_size;
+} ide_task_request_t;
+
+typedef struct ide_ioctl_request_s {
+	ide_task_request_t	*task_request;
+	unsigned char		*out_buffer;
+	unsigned char		*in_buffer;
+} ide_ioctl_request_t;
+
+#define TASKFILE_INVALID		0x7fff
+#define TASKFILE_48			0x8000
+
+#define TASKFILE_NO_DATA		0x0000
+
+#define TASKFILE_IN			0x0001
+#define TASKFILE_MULTI_IN		0x0002
+
+#define TASKFILE_OUT			0x0004
+#define TASKFILE_MULTI_OUT		0x0008
+#define TASKFILE_IN_OUT			0x0010
+
+#define TASKFILE_IN_DMA			0x0020
+#define TASKFILE_OUT_DMA		0x0040
+#define TASKFILE_IN_DMAQ		0x0080
+#define TASKFILE_OUT_DMAQ		0x0100
+
+#define TASKFILE_P_IN			0x0200
+#define TASKFILE_P_OUT			0x0400
+#define TASKFILE_P_IN_DMA		0x0800
+#define TASKFILE_P_OUT_DMA		0x1000
+#define TASKFILE_P_IN_DMAQ		0x2000
+#define TASKFILE_P_OUT_DMAQ		0x4000
+
+/* ATA/ATAPI Commands pre T13 Spec */
+#define WIN_NOP				0x00
+#define CFA_REQ_EXT_ERROR_CODE		0x03 /* CFA Request Extended Error Code */
+#define WIN_SRST			0x08 /* ATAPI soft reset command */
+#define WIN_DEVICE_RESET		0x08
+#define WIN_RESTORE			0x10
+#define WIN_READ			0x20 /* 28-Bit */
+#define WIN_READ_EXT			0x24 /* 48-Bit */
+#define WIN_READDMA_EXT			0x25 /* 48-Bit */
+#define WIN_READDMA_QUEUED_EXT		0x26 /* 48-Bit */
+#define WIN_READ_NATIVE_MAX_EXT		0x27 /* 48-Bit */
+#define WIN_MULTREAD_EXT		0x29 /* 48-Bit */
+#define WIN_WRITE			0x30 /* 28-Bit */
+#define WIN_WRITE_EXT			0x34 /* 48-Bit */
+#define WIN_WRITEDMA_EXT		0x35 /* 48-Bit */
+#define WIN_WRITEDMA_QUEUED_EXT		0x36 /* 48-Bit */
+#define WIN_SET_MAX_EXT			0x37 /* 48-Bit */
+#define CFA_WRITE_SECT_WO_ERASE		0x38 /* CFA Write Sectors without erase */
+#define WIN_MULTWRITE_EXT		0x39 /* 48-Bit */
+#define WIN_WRITE_VERIFY		0x3C /* 28-Bit */
+#define WIN_VERIFY			0x40 /* 28-Bit - Read Verify Sectors */
+#define WIN_VERIFY_EXT			0x42 /* 48-Bit */
+#define WIN_FORMAT			0x50
+#define WIN_INIT			0x60
+#define WIN_SEEK			0x70
+#define CFA_TRANSLATE_SECTOR		0x87 /* CFA Translate Sector */
+#define WIN_DIAGNOSE			0x90
+#define WIN_SPECIFY			0x91 /* set drive geometry translation */
+#define WIN_DOWNLOAD_MICROCODE		0x92
+#define WIN_STANDBYNOW2			0x94
+#define WIN_SETIDLE2			0x97
+#define WIN_CHECKPOWERMODE2		0x98
+#define WIN_SLEEPNOW2			0x99
+#define WIN_PACKETCMD			0xA0 /* Send a packet command. */
+#define WIN_PIDENTIFY			0xA1 /* identify ATAPI device	*/
+#define WIN_QUEUED_SERVICE		0xA2
+#define WIN_SMART			0xB0 /* self-monitoring and reporting */
+#define CFA_ERASE_SECTORS       	0xC0
+#define WIN_MULTREAD			0xC4 /* read sectors using multiple mode*/
+#define WIN_MULTWRITE			0xC5 /* write sectors using multiple mode */
+#define WIN_SETMULT			0xC6 /* enable/disable multiple mode */
+#define WIN_READDMA_QUEUED		0xC7 /* read sectors using Queued DMA transfers */
+#define WIN_READDMA			0xC8 /* read sectors using DMA transfers */
+#define WIN_WRITEDMA			0xCA /* write sectors using DMA transfers */
+#define WIN_WRITEDMA_QUEUED		0xCC /* write sectors using Queued DMA transfers */
+#define CFA_WRITE_MULTI_WO_ERASE	0xCD /* CFA Write multiple without erase */
+#define WIN_GETMEDIASTATUS		0xDA	
+#define WIN_DOORLOCK			0xDE /* lock door on removable drives */
+#define WIN_DOORUNLOCK			0xDF /* unlock door on removable drives */
+#define WIN_STANDBYNOW1			0xE0
+#define WIN_IDLEIMMEDIATE		0xE1 /* force drive to become "ready" */
+#define WIN_STANDBY             	0xE2 /* Set device in Standby Mode */
+#define WIN_SETIDLE1			0xE3
+#define WIN_READ_BUFFER			0xE4 /* force read only 1 sector */
+#define WIN_CHECKPOWERMODE1		0xE5
+#define WIN_SLEEPNOW1			0xE6
+#define WIN_FLUSH_CACHE			0xE7
+#define WIN_WRITE_BUFFER		0xE8 /* force write only 1 sector */
+#define WIN_FLUSH_CACHE_EXT		0xEA /* 48-Bit */
+#define WIN_IDENTIFY			0xEC /* ask drive to identify itself	*/
+#define WIN_MEDIAEJECT			0xED
+#define WIN_IDENTIFY_DMA		0xEE /* same as WIN_IDENTIFY, but DMA */
+#define WIN_SETFEATURES			0xEF /* set special drive features */
+#define EXABYTE_ENABLE_NEST		0xF0
+#define WIN_SECURITY_SET_PASS		0xF1
+#define WIN_SECURITY_UNLOCK		0xF2
+#define WIN_SECURITY_ERASE_PREPARE	0xF3
+#define WIN_SECURITY_ERASE_UNIT		0xF4
+#define WIN_SECURITY_FREEZE_LOCK	0xF5
+#define WIN_SECURITY_DISABLE		0xF6
+#define WIN_READ_NATIVE_MAX		0xF8 /* return the native maximum address */
+#define WIN_SET_MAX			0xF9
+#define DISABLE_SEAGATE			0xFB
+
+/* WIN_SMART sub-commands */
+
+#define SMART_READ_VALUES		0xD0
+#define SMART_READ_THRESHOLDS		0xD1
+#define SMART_AUTOSAVE			0xD2
+#define SMART_SAVE			0xD3
+#define SMART_IMMEDIATE_OFFLINE		0xD4
+#define SMART_READ_LOG_SECTOR		0xD5
+#define SMART_WRITE_LOG_SECTOR		0xD6
+#define SMART_WRITE_THRESHOLDS		0xD7
+#define SMART_ENABLE			0xD8
+#define SMART_DISABLE			0xD9
+#define SMART_STATUS			0xDA
+#define SMART_AUTO_OFFLINE		0xDB
+
+/* Password used in TF4 & TF5 executing SMART commands */
+
+#define SMART_LCYL_PASS			0x4F
+#define SMART_HCYL_PASS			0xC2
+		
 /* WIN_SETFEATURES sub-commands */
 
 #define SETFEATURES_EN_WCACHE	0x02	/* Enable write cache */
@@ -131,6 +296,7 @@
 #define SETFEATURES_DIS_DEFECT	0x04	/* Disable Defect Management */
 #define SETFEATURES_EN_APM	0x05	/* Enable advanced power management */
 #define SETFEATURES_DIS_MSN	0x31	/* Disable Media Status Notification */
+#define SETFEATURES_EN_AAM	0x42	/* Enable Automatic Acoustic Management */
 #define SETFEATURES_DIS_RLA	0x55	/* Disable read look-ahead feature */
 #define SETFEATURES_EN_RI	0x5D	/* Enable release interrupt */
 #define SETFEATURES_EN_SI	0x5E	/* Enable SERVICE interrupt */
@@ -141,29 +307,19 @@
 #define SETFEATURES_EN_MSN	0x95	/* Enable Media Status Notification */
 #define SETFEATURES_EN_RLA	0xAA	/* Enable read look-ahead feature */
 #define SETFEATURES_PREFETCH	0xAB	/* Sets drive prefetch value */
+#define SETFEATURES_DIS_AAM	0xC2	/* Disable Automatic Acoustic Management */
 #define SETFEATURES_EN_RPOD	0xCC	/* Enable reverting to power on defaults */
 #define SETFEATURES_DIS_RI	0xDD	/* Disable release interrupt */
 #define SETFEATURES_DIS_SI	0xDE	/* Disable SERVICE interrupt */
 
 /* WIN_SECURITY sub-commands */
 
-#define SECURITY_SET_PASSWORD		0xBA	/* 0xF1 */
-#define SECURITY_UNLOCK			0xBB	/* 0xF2 */
-#define SECURITY_ERASE_PREPARE		0xBC	/* 0xF3 */
-#define SECURITY_ERASE_UNIT		0xBD	/* 0xF4 */
-#define SECURITY_FREEZE_LOCK		0xBE	/* 0xF5 */
-#define SECURITY_DISABLE_PASSWORD	0xBF	/* 0xF6 */
-
-/* Bits for HD_ERROR */
-#define MARK_ERR	0x01	/* Bad address mark */
-#define TRK0_ERR	0x02	/* couldn't find track 0 */
-#define ABRT_ERR	0x04	/* Command aborted */
-#define MCR_ERR		0x08	/* media change request */
-#define ID_ERR		0x10	/* ID field not found */
-#define MC_ERR		0x20	/* media changed */
-#define ECC_ERR		0x40	/* Uncorrectable ECC error */
-#define	BBD_ERR		0x80	/* pre-EIDE meaning:  block marked bad */
-#define	ICRC_ERR	0x80	/* new meaning:  CRC error during transfer */
+#define SECURITY_SET_PASSWORD		0xBA
+#define SECURITY_UNLOCK			0xBB
+#define SECURITY_ERASE_PREPARE		0xBC
+#define SECURITY_ERASE_UNIT		0xBD
+#define SECURITY_FREEZE_LOCK		0xBE
+#define SECURITY_DISABLE_PASSWORD	0xBF
 
 struct hd_geometry {
       unsigned char heads;
@@ -172,6 +328,14 @@
       unsigned long start;
 };
 
+/* BIG GEOMETRY */
+struct hd_big_geometry {
+	unsigned char heads;
+	unsigned char sectors;
+	unsigned int cylinders;
+	unsigned long start;
+};
+
 /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */
 #define HDIO_GETGEO		0x0301	/* get device geometry */
 #define HDIO_GET_UNMASKINTR	0x0302	/* get current unmask setting */
@@ -186,9 +350,10 @@
 #define HDIO_GET_IDENTITY	0x030d	/* get IDE identification info */
 #define HDIO_GET_WCACHE		0x030e	/* get write cache mode on|off */
 #define HDIO_GET_ACOUSTIC	0x030f	/* get acoustic value */
+#define	HDIO_GET_ADDRESS	0x0310	/* */
 
 #define HDIO_GET_BUSSTATE	0x031a	/* get the bus state of the hwif */
-#define HDIO_TRISTATE_HWIF	0x031b	/* OBSOLETE - use SET_BUSSTATE */
+#define HDIO_TRISTATE_HWIF	0x031b	/* execute a channel tristate */
 #define HDIO_DRIVE_RESET	0x031c	/* execute a device reset */
 #define HDIO_DRIVE_TASKFILE	0x031d	/* execute raw taskfile */
 #define HDIO_DRIVE_TASK		0x031e	/* execute task and special drive command */
@@ -211,6 +376,7 @@
 #define HDIO_SET_ACOUSTIC	0x032c	/* change acoustic behavior */
 #define HDIO_SET_BUSSTATE	0x032d	/* set the bus state of the hwif */
 #define HDIO_SET_QDMA		0x032e	/* change use-qdma flag */
+#define HDIO_SET_ADDRESS	0x032f	/* change lba addressing modes */
 
 /* bus states */
 enum {
@@ -219,34 +385,30 @@
 	BUSSTATE_TRISTATE
 };
 
-/* BIG GEOMETRY */
-struct hd_big_geometry {
-	unsigned char heads;
-	unsigned char sectors;
-	unsigned int cylinders;
-	unsigned long start;
-};
-
 /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x033n/0x033n */
 #define HDIO_GETGEO_BIG		0x0330	/* */
 #define HDIO_GETGEO_BIG_RAW	0x0331	/* */
 
 #define __NEW_HD_DRIVE_ID
-/* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */
+/* structure returned by HDIO_GET_IDENTITY,
+ * as per ANSI NCITS ATA6 rev.1b spec
+ */
 struct hd_driveid {
 	unsigned short	config;		/* lots of obsolete bit flags */
-	unsigned short	cyls;		/* "physical" cyls */
+	unsigned short	cyls;		/* Obsolete, "physical" cyls */
 	unsigned short	reserved2;	/* reserved (word 2) */
-	unsigned short	heads;		/* "physical" heads */
+	unsigned short	heads;		/* Obsolete, "physical" heads */
 	unsigned short	track_bytes;	/* unformatted bytes per track */
 	unsigned short	sector_bytes;	/* unformatted bytes per sector */
-	unsigned short	sectors;	/* "physical" sectors per track */
+	unsigned short	sectors;	/* Obsolete, "physical" sectors per track */
 	unsigned short	vendor0;	/* vendor unique */
 	unsigned short	vendor1;	/* vendor unique */
-	unsigned short	vendor2;	/* vendor unique */
+	unsigned short	vendor2;	/* Retired vendor unique */
 	unsigned char	serial_no[20];	/* 0 = not_specified */
-	unsigned short	buf_type;
-	unsigned short	buf_size;	/* 512 byte increments; 0 = not_specified */
+	unsigned short	buf_type;	/* Retired */
+	unsigned short	buf_size;	/* Retired, 512 byte increments
+					 * 0 = not_specified
+					 */
 	unsigned short	ecc_bytes;	/* for r/w long cmds; 0 = not_specified */
 	unsigned char	fw_rev[8];	/* 0 = not_specified */
 	unsigned char	model[40];	/* 0 = not_specified */
@@ -254,72 +416,223 @@
 	unsigned char	vendor3;	/* vendor unique */
 	unsigned short	dword_io;	/* 0=not_implemented; 1=implemented */
 	unsigned char	vendor4;	/* vendor unique */
-	unsigned char	capability;	/* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/
+	unsigned char	capability;	/* (upper byte of word 49)
+					 *  3:	IORDYsup
+					 *  2:	IORDYsw
+					 *  1:	LBA
+					 *  0:	DMA
+					 */
 	unsigned short	reserved50;	/* reserved (word 50) */
-	unsigned char	vendor5;	/* vendor unique */
-	unsigned char	tPIO;		/* 0=slow, 1=medium, 2=fast */
-	unsigned char	vendor6;	/* vendor unique */
-	unsigned char	tDMA;		/* 0=slow, 1=medium, 2=fast */
-	unsigned short	field_valid;	/* bits 0:cur_ok 1:eide_ok */
-	unsigned short	cur_cyls;	/* logical cylinders */
-	unsigned short	cur_heads;	/* logical heads */
-	unsigned short	cur_sectors;	/* logical sectors per track */
-	unsigned short	cur_capacity0;	/* logical total sectors on drive */
-	unsigned short	cur_capacity1;	/*  (2 words, misaligned int)     */
+	unsigned char	vendor5;	/* Obsolete, vendor unique */
+	unsigned char	tPIO;		/* Obsolete, 0=slow, 1=medium, 2=fast */
+	unsigned char	vendor6;	/* Obsolete, vendor unique */
+	unsigned char	tDMA;		/* Obsolete, 0=slow, 1=medium, 2=fast */
+	unsigned short	field_valid;	/* (word 53)
+					 *  2:	ultra_ok	word  88
+					 *  1:	eide_ok		words 64-70
+					 *  0:	cur_ok		words 54-58
+					 */
+	unsigned short	cur_cyls;	/* Obsolete, logical cylinders */
+	unsigned short	cur_heads;	/* Obsolete, l heads */
+	unsigned short	cur_sectors;	/* Obsolete, l sectors per track */
+	unsigned short	cur_capacity0;	/* Obsolete, l total sectors on drive */
+	unsigned short	cur_capacity1;	/* Obsolete, (2 words, misaligned int)     */
 	unsigned char	multsect;	/* current multiple sector count */
 	unsigned char	multsect_valid;	/* when (bit0==1) multsect is ok */
-	unsigned int	lba_capacity;	/* total number of sectors */
-	unsigned short	dma_1word;	/* single-word dma info */
+	unsigned int	lba_capacity;	/* Obsolete, total number of sectors */
+	unsigned short	dma_1word;	/* Obsolete, single-word dma info */
 	unsigned short	dma_mword;	/* multiple-word dma info */
 	unsigned short  eide_pio_modes; /* bits 0:mode3 1:mode4 */
 	unsigned short  eide_dma_min;	/* min mword dma cycle time (ns) */
 	unsigned short  eide_dma_time;	/* recommended mword dma cycle time (ns) */
 	unsigned short  eide_pio;       /* min cycle time (ns), no IORDY  */
 	unsigned short  eide_pio_iordy; /* min cycle time (ns), with IORDY */
-	unsigned short	words69_70[2];	/* reserved words 69-70 */
+	unsigned short	words69_70[2];	/* reserved words 69-70
+					 * future command overlap and queuing
+					 */
 	/* HDIO_GET_IDENTITY currently returns only words 0 through 70 */
-	unsigned short	words71_74[4];	/* reserved words 71-74 */
-	unsigned short  queue_depth;	/*  */
+	unsigned short	words71_74[4];	/* reserved words 71-74
+					 * for IDENTIFY PACKET DEVICE command
+					 */
+	unsigned short  queue_depth;	/* (word 75)
+					 * 15:5	reserved
+					 *  4:0	Maximum queue depth -1
+					 */
 	unsigned short  words76_79[4];	/* reserved words 76-79 */
-	unsigned short  major_rev_num;	/*  */
-	unsigned short  minor_rev_num;	/*  */
-	unsigned short  command_set_1;	/* bits 0:Smart 1:Security 2:Removable 3:PM */
-	unsigned short  command_set_2;	/* bits 14:Smart Enabled 13:0 zero */
-	unsigned short  cfsse;		/* command set-feature supported extensions */
-	unsigned short  cfs_enable_1;	/* command set-feature enabled */
-	unsigned short  cfs_enable_2;	/* command set-feature enabled */
-	unsigned short  csf_default;	/* command set-feature default */
-	unsigned short  dma_ultra;	/*  */
+	unsigned short  major_rev_num;	/* (word 80) */
+	unsigned short  minor_rev_num;	/* (word 81) */
+	unsigned short  command_set_1;	/* (word 82) supported
+					 * 15:	Obsolete
+					 * 14:	NOP command
+					 * 13:	READ_BUFFER
+					 * 12:	WRITE_BUFFER
+					 * 11:	Obsolete
+					 * 10:	Host Protected Area
+					 *  9:	DEVICE Reset
+					 *  8:	SERVICE Interrupt
+					 *  7:	Release Interrupt
+					 *  6:	look-ahead
+					 *  5:	write cache
+					 *  4:	PACKET Command
+					 *  3:	Power Management Feature Set
+					 *  2:	Removable Feature Set
+					 *  1:	Security Feature Set
+					 *  0:	SMART Feature Set
+					 */
+	unsigned short  command_set_2;	/* (word 83)
+					 * 15:	Shall be ZERO
+					 * 14:	Shall be ONE
+					 * 13:	FLUSH CACHE EXT
+					 * 12:	FLUSH CACHE
+					 * 11:	Device Configuration Overlay
+					 * 10:	48-bit Address Feature Set
+					 *  9:	Automatic Acoustic Management
+					 *  8:	SET MAX security
+					 *  7:	reserved 1407DT PARTIES
+					 *  6:	SetF sub-command Power-Up
+					 *  5:	Power-Up in Standby Feature Set
+					 *  4:	Removable Media Notification
+					 *  3:	APM Feature Set
+					 *  2:	CFA Feature Set
+					 *  1:	READ/WRITE DMA QUEUED
+					 *  0:	Download MicroCode
+					 */
+	unsigned short  cfsse;		/* (word 84)
+					 * cmd set-feature supported extensions
+					 * 15:	Shall be ZERO
+					 * 14:	Shall be ONE
+					 * 13:3	reserved
+					 *  2:	Media Serial Number Valid
+					 *  1:	SMART selt-test supported
+					 *  0:	SMART error logging
+					 */
+	unsigned short  cfs_enable_1;	/* (word 85)
+					 * command set-feature enabled
+					 * 15:	Obsolete
+					 * 14:	NOP command
+					 * 13:	READ_BUFFER
+					 * 12:	WRITE_BUFFER
+					 * 11:	Obsolete
+					 * 10:	Host Protected Area
+					 *  9:	DEVICE Reset
+					 *  8:	SERVICE Interrupt
+					 *  7:	Release Interrupt
+					 *  6:	look-ahead
+					 *  5:	write cache
+					 *  4:	PACKET Command
+					 *  3:	Power Management Feature Set
+					 *  2:	Removable Feature Set
+					 *  1:	Security Feature Set
+					 *  0:	SMART Feature Set
+					 */
+	unsigned short  cfs_enable_2;	/* (word 86)
+					 * command set-feature enabled
+					 * 15:	Shall be ZERO
+					 * 14:	Shall be ONE
+					 * 13:	FLUSH CACHE EXT
+					 * 12:	FLUSH CACHE
+					 * 11:	Device Configuration Overlay
+					 * 10:	48-bit Address Feature Set
+					 *  9:	Automatic Acoustic Management
+					 *  8:	SET MAX security
+					 *  7:	reserved 1407DT PARTIES
+					 *  6:	SetF sub-command Power-Up
+					 *  5:	Power-Up in Standby Feature Set
+					 *  4:	Removable Media Notification
+					 *  3:	APM Feature Set
+					 *  2:	CFA Feature Set
+					 *  1:	READ/WRITE DMA QUEUED
+					 *  0:	Download MicroCode
+					 */
+	unsigned short  csf_default;	/* (word 87)
+					 * command set-feature default
+					 * 15:	Shall be ZERO
+					 * 14:	Shall be ONE
+					 * 13:3	reserved
+					 *  2:	Media Serial Number Valid
+					 *  1:	SMART selt-test supported
+					 *  0:	SMART error logging
+					 */
+	unsigned short  dma_ultra;	/* (word 88) */
 	unsigned short	word89;		/* reserved (word 89) */
 	unsigned short	word90;		/* reserved (word 90) */
 	unsigned short	CurAPMvalues;	/* current APM values */
 	unsigned short	word92;		/* reserved (word 92) */
-	unsigned short	hw_config;	/* hardware config */
-	unsigned short  words94_125[32];/* reserved words 94-125 */
-	unsigned short	last_lun;	/* reserved (word 126) */
-	unsigned short	word127;	/* reserved (word 127) */
-	unsigned short	dlf;		/* device lock function
+	unsigned short	hw_config;	/* hardware config (word 93)
+					 * 15:
+					 * 14:
+					 * 13:
+					 * 12:
+					 * 11:
+					 * 10:
+					 *  9:
+					 *  8:
+					 *  7:
+					 *  6:
+					 *  5:
+					 *  4:
+					 *  3:
+					 *  2:
+					 *  1:
+					 *  0:
+					 */
+	unsigned short	acoustic;	/* (word 94)
+					 * 15:8	Vendor's recommended value
+					 *  7:0	current value
+					 */
+	unsigned short	words95_99[5];	/* reserved words 95-99 */
+#if 0
+	unsigned short	words100_103[4]	;/* reserved words 100-103 */
+#else
+	unsigned long long lba_capacity_2;/* 48-bit total number of sectors */
+#endif
+	unsigned short	words104_125[22];/* reserved words 104-125 */
+	unsigned short	last_lun;	/* (word 126) */
+	unsigned short	word127;	/* (word 127) Feature Set
+					 * Removable Media Notification
+					 * 15:2	reserved
+					 *  1:0	00 = not supported
+					 *	01 = supported
+					 *	10 = reserved
+					 *	11 = reserved
+					 */
+	unsigned short	dlf;		/* (word 128)
+					 * device lock function
 					 * 15:9	reserved
-					 * 8	security level 1:max 0:high
-					 * 7:6	reserved
-					 * 5	enhanced erase
-					 * 4	expire
-					 * 3	frozen
-					 * 2	locked
-					 * 1	en/disabled
-					 * 0	capability
+					 *  8	security level 1:max 0:high
+					 *  7:6	reserved
+					 *  5	enhanced erase
+					 *  4	expire
+					 *  3	frozen
+					 *  2	locked
+					 *  1	en/disabled
+					 *  0	capability
 					 */
-	unsigned short  csfo;		/* current set features options
+	unsigned short  csfo;		/*  (word 129)
+					 * current set features options
 					 * 15:4	reserved
-					 * 3	auto reassign
-					 * 2	reverting
-					 * 1	read-look-ahead
-					 * 0	write cache
+					 *  3:	auto reassign
+					 *  2:	reverting
+					 *  1:	read-look-ahead
+					 *  0:	write cache
 					 */
 	unsigned short	words130_155[26];/* reserved vendor words 130-155 */
-	unsigned short	word156;
+	unsigned short	word156;	/* reserved vendor word 156 */
 	unsigned short	words157_159[3];/* reserved vendor words 157-159 */
-	unsigned short	words160_255[95];/* reserved words 160-255 */
+	unsigned short	cfa_power;	/* (word 160) CFA Power Mode
+					 * 15 word 160 supported
+					 * 14 reserved
+					 * 13
+					 * 12
+					 * 11:0
+					 */
+	unsigned short	words161_175[14];/* Reserved for CFA */
+	unsigned short	words176_205[31];/* Current Media Serial Number */
+	unsigned short	words206_254[48];/* reserved words 206-254 */
+	unsigned short	integrity_word;	/* (word 255)
+					 * 15:8 Checksum
+					 *  7:0 Signature
+					 */
 };
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/hiddev.h linux/include/linux/hiddev.h
--- linux.orig/include/linux/hiddev.h	2001-09-12 22:34:06.000000000 +0000
+++ linux/include/linux/hiddev.h	2002-07-20 01:08:29.000000000 +0000
@@ -185,7 +185,7 @@
 #else
 static inline void *hiddev_connect(struct hid_device *hid) { return NULL; }
 static inline void hiddev_disconnect(struct hid_device *hid) { }
-static inline void hiddev_event(struct hid_device *hid, unsigned int usage, int value) { }
+static inline void hiddev_hid_event(struct hid_device *hid, unsigned int usage, int value) { }
 static inline int hiddev_init(void) { return 0; }
 static inline void hiddev_exit(void) { }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/highmem.h linux/include/linux/highmem.h
--- linux.orig/include/linux/highmem.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/highmem.h	2002-07-20 01:08:28.000000000 +0000
@@ -64,7 +64,7 @@
 	char *kaddr;
 
 	if (offset + size > PAGE_SIZE)
-		BUG();
+		out_of_line_bug();
 	kaddr = kmap(page);
 	memset(kaddr + offset, 0, size);
 	flush_dcache_page(page);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/i2o.h linux/include/linux/i2o.h
--- linux.orig/include/linux/i2o.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/i2o.h	2002-07-20 01:08:28.000000000 +0000
@@ -81,9 +81,9 @@
 struct i2o_pci
 {
 	int		irq;
-	int		queue_buggy:3;	/* Don't send a lot of messages */
 	int		short_req:1;	/* Use small block sizes        */
 	int		dpt:1;		/* Don't quiesce                */
+	int		promise:1;	/* Promise controller		*/
 #ifdef CONFIG_MTRR
 	int		mtrr_reg0;
 	int		mtrr_reg1;
@@ -112,9 +112,9 @@
 	atomic_t users;
 	struct i2o_device *devices;		/* I2O device chain */
 	struct i2o_controller *next;		/* Controller chain */
-	volatile u32 *post_port;		/* Inbout port */
-	volatile u32 *reply_port;		/* Outbound port */
-	volatile u32 *irq_mask;			/* Interrupt register */
+	unsigned long post_port;		/* Inbout port address */
+	unsigned long reply_port;		/* Outbound port address */
+	unsigned long irq_mask;			/* Interrupt register address */
 
 	/* Dynamic LCT related data */
 	struct semaphore lct_sem;
@@ -126,8 +126,8 @@
 	i2o_lct *dlct;				/* Temp LCT */
 	i2o_hrt *hrt;				/* HW Resource Table */
 
-	u32 mem_offset;				/* MFA offset */
-	u32 mem_phys;				/* MFA physical */
+	unsigned long mem_offset;		/* MFA offset */
+	unsigned long mem_phys;			/* MFA physical */
 
 	int battery:1;				/* Has a battery backup */
 	int io_alloc:1;				/* An I/O resource was allocated */
@@ -295,6 +295,13 @@
 	I2O_REPLY_WRITE32(c, m);
 }
 
+/*
+ *	Endian handling wrapped into the macro - keeps the core code
+ *	cleaner.
+ */
+ 
+#define i2o_raw_writel(val, mem)	__raw_writel(cpu_to_le32(val), mem)
+
 extern struct i2o_controller *i2o_find_controller(int);
 extern void i2o_unlock_controller(struct i2o_controller *);
 extern struct i2o_controller *i2o_controller_chain;
@@ -339,13 +346,66 @@
 extern void i2o_run_queue(struct i2o_controller *);
 extern int i2o_delete_controller(struct i2o_controller *);
 
+/*
+ *	Cache strategies
+ */
+ 
+ 
+/*	The NULL strategy leaves everything up to the controller. This tends to be a
+ *	pessimal but functional choice.
+ */
+#define CACHE_NULL		0
+/*	Prefetch data when reading. We continually attempt to load the next 32 sectors
+ *	into the controller cache. 
+ */
+#define CACHE_PREFETCH		1
+/*	Prefetch data when reading. We sometimes attempt to load the next 32 sectors
+ *	into the controller cache. When an I/O is less <= 8K we assume its probably
+ *	not sequential and don't prefetch (default)
+ */
+#define CACHE_SMARTFETCH	2
+/*	Data is written to the cache and then out on to the disk. The I/O must be
+ *	physically on the medium before the write is acknowledged (default without
+ *	NVRAM)
+ */
+#define CACHE_WRITETHROUGH	17
+/*	Data is written to the cache and then out on to the disk. The controller
+ *	is permitted to write back the cache any way it wants. (default if battery
+ *	backed NVRAM is present). It can be useful to set this for swap regardless of
+ *	battery state.
+ */
+#define CACHE_WRITEBACK		18
+/*	Optimise for under powered controllers, especially on RAID1 and RAID0. We
+ *	write large I/O's directly to disk bypassing the cache to avoid the extra
+ *	memory copy hits. Small writes are writeback cached
+ */
+#define CACHE_SMARTBACK		19
+/*	Optimise for under powered controllers, especially on RAID1 and RAID0. We
+ *	write large I/O's directly to disk bypassing the cache to avoid the extra
+ *	memory copy hits. Small writes are writethrough cached. Suitable for devices
+ *	lacking battery backup
+ */
+#define CACHE_SMARTTHROUGH	20
+
+/*
+ *	Ioctl structures
+ */
+ 
+
+#define 	BLKI2OGRSTRAT	_IOR('2', 1, int) 
+#define 	BLKI2OGWSTRAT	_IOR('2', 2, int) 
+#define 	BLKI2OSRSTRAT	_IOW('2', 3, int) 
+#define 	BLKI2OSWSTRAT	_IOW('2', 4, int) 
+
+
+
 
 /*
- * I2O Function codes
+ *	I2O Function codes
  */
 
 /*
- * Executive Class
+ *	Executive Class
  */
 #define	I2O_CMD_ADAPTER_ASSIGN		0xB3
 #define	I2O_CMD_ADAPTER_READ		0xB2
@@ -416,6 +476,7 @@
 #define I2O_CMD_BLOCK_MUNLOCK		0x4B
 #define I2O_CMD_BLOCK_MMOUNT		0x41
 #define I2O_CMD_BLOCK_MEJECT		0x43
+#define I2O_CMD_BLOCK_POWER		0x70
 
 #define I2O_PRIVATE_MSG			0xFF
 
@@ -574,6 +635,7 @@
 #define EIGHT_WORD_MSG_SIZE	0x00080000
 #define NINE_WORD_MSG_SIZE	0x00090000
 #define TEN_WORD_MSG_SIZE	0x000A0000
+#define ELEVEN_WORD_MSG_SIZE	0x000B0000
 #define I2O_MESSAGE_SIZE(x)	((x)<<16)
 
 
@@ -582,10 +644,10 @@
 #define ADAPTER_TID		0
 #define HOST_TID		1
 
-#define MSG_FRAME_SIZE		128
+#define MSG_FRAME_SIZE		64	/* i2o_scsi assumes >= 32 */
 #define NMBR_MSG_FRAMES		128
 
-#define MSG_POOL_SIZE		16384
+#define MSG_POOL_SIZE		(MSG_FRAME_SIZE*NMBR_MSG_FRAMES*sizeof(u32))
 
 #define I2O_POST_WAIT_OK	0
 #define I2O_POST_WAIT_TIMEOUT	-ETIMEDOUT
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/ide.h linux/include/linux/ide.h
--- linux.orig/include/linux/ide.h	2001-11-22 19:48:07.000000000 +0000
+++ linux/include/linux/ide.h	2002-07-20 01:08:28.000000000 +0000
@@ -65,13 +65,14 @@
 /*
  * IDE_DRIVE_CMD is used to implement many features of the hdparm utility
  */
-#define IDE_DRIVE_CMD		99	/* (magic) undef to reduce kernel size*/
+#define IDE_DRIVE_CMD			99	/* (magic) undef to reduce kernel size*/
+
+#define IDE_DRIVE_TASK			98
 
 /*
- * IDE_DRIVE_TASK is used to implement many features needed for raw tasks
+ * IDE_DRIVE_TASKFILE is used to implement many features needed for raw tasks
  */
-#define IDE_DRIVE_TASK		98
-#define IDE_DRIVE_CMD_AEB	98
+#define IDE_DRIVE_TASKFILE		97
 
 /*
  *  "No user-serviceable parts" beyond this point  :)
@@ -120,6 +121,17 @@
 #define IDE_FEATURE_OFFSET	IDE_ERROR_OFFSET
 #define IDE_COMMAND_OFFSET	IDE_STATUS_OFFSET
 
+#define IDE_DATA_OFFSET_HOB	(0)
+#define IDE_ERROR_OFFSET_HOB	(1)
+#define IDE_NSECTOR_OFFSET_HOB	(2)
+#define IDE_SECTOR_OFFSET_HOB	(3)
+#define IDE_LCYL_OFFSET_HOB	(4)
+#define IDE_HCYL_OFFSET_HOB	(5)
+#define IDE_SELECT_OFFSET_HOB	(6)
+#define IDE_CONTROL_OFFSET_HOB	(7)
+
+#define IDE_FEATURE_OFFSET_HOB	IDE_ERROR_OFFSET_HOB
+
 #define IDE_DATA_REG		(HWIF(drive)->io_ports[IDE_DATA_OFFSET])
 #define IDE_ERROR_REG		(HWIF(drive)->io_ports[IDE_ERROR_OFFSET])
 #define IDE_NSECTOR_REG		(HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET])
@@ -131,6 +143,16 @@
 #define IDE_CONTROL_REG		(HWIF(drive)->io_ports[IDE_CONTROL_OFFSET])
 #define IDE_IRQ_REG		(HWIF(drive)->io_ports[IDE_IRQ_OFFSET])
 
+#define IDE_DATA_REG_HOB	(HWIF(drive)->io_ports[IDE_DATA_OFFSET])
+#define IDE_ERROR_REG_HOB	(HWIF(drive)->io_ports[IDE_ERROR_OFFSET])
+#define IDE_NSECTOR_REG_HOB	(HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET])
+#define IDE_SECTOR_REG_HOB	(HWIF(drive)->io_ports[IDE_SECTOR_OFFSET])
+#define IDE_LCYL_REG_HOB	(HWIF(drive)->io_ports[IDE_LCYL_OFFSET])
+#define IDE_HCYL_REG_HOB	(HWIF(drive)->io_ports[IDE_HCYL_OFFSET])
+#define IDE_SELECT_REG_HOB	(HWIF(drive)->io_ports[IDE_SELECT_OFFSET])
+#define IDE_STATUS_REG_HOB	(HWIF(drive)->io_ports[IDE_STATUS_OFFSET])
+#define IDE_CONTROL_REG_HOB	(HWIF(drive)->io_ports[IDE_CONTROL_OFFSET])
+
 #define IDE_FEATURE_REG		IDE_ERROR_REG
 #define IDE_COMMAND_REG		IDE_STATUS_REG
 #define IDE_ALTSTATUS_REG	IDE_CONTROL_REG
@@ -156,11 +178,21 @@
 #define PARTN_BITS	6	/* number of minor dev bits for partitions */
 #define PARTN_MASK	((1<<PARTN_BITS)-1)	/* a useful bit mask */
 #define MAX_DRIVES	2	/* per interface; 2 assumed by lots of code */
-#define SECTOR_WORDS	(512 / 4)	/* number of 32bit words per sector */
+#define CASCADE_DRIVES	8	/* per interface; 8|2 assumed by lots of code */
+#define SECTOR_SIZE	512
+#define SECTOR_WORDS	(SECTOR_SIZE / 4)	/* number of 32bit words per sector */
 #define IDE_LARGE_SEEK(b1,b2,t)	(((b1) > (b2) + (t)) || ((b2) > (b1) + (t)))
 #define IDE_MIN(a,b)	((a)<(b) ? (a):(b))
 #define IDE_MAX(a,b)	((a)>(b) ? (a):(b))
 
+#ifndef SPLIT_WORD
+#  define SPLIT_WORD(W,HB,LB) ((HB)=(W>>8), (LB)=(W-((W>>8)<<8)))
+#endif
+#ifndef MAKE_WORD
+#  define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB))
+#endif
+
+
 /*
  * Timeouts for various operations:
  */
@@ -170,8 +202,7 @@
 #else
 #define WAIT_READY	(3*HZ/100)	/* 30msec - should be instantaneous */
 #endif /* CONFIG_APM || CONFIG_APM_MODULE */
-#define WAIT_PIDENTIFY	(10*HZ)	/* 10sec  - should be less than 3ms (?)
-				            if all ATAPI CD is closed at boot */
+#define WAIT_PIDENTIFY	(10*HZ)	/* 10sec  - should be less than 3ms (?), if all ATAPI CD is closed at boot */
 #define WAIT_WORSTCASE	(30*HZ)	/* 30sec  - worst case when spinning up */
 #define WAIT_CMD	(10*HZ)	/* 10sec  - maximum wait for an IRQ to happen */
 #define WAIT_MIN_SLEEP	(2*HZ/100)	/* 20msec - minimum sleep time */
@@ -209,6 +240,11 @@
 		(drive)->quirk_list = hwif->quirkproc(drive);	\
 }
 
+#define HOST(hwif,chipset)					\
+{								\
+	return ((hwif)->chipset == chipset) ? 1 : 0;		\
+}
+
 #define IDE_DEBUG(lineno) \
 	printk("%s,%s,line=%d\n", __FILE__, __FUNCTION__, (lineno))
 
@@ -223,6 +259,18 @@
 #endif
 
 /*
+ * hwif_chipset_t is used to keep track of the specific hardware
+ * chipset used by each IDE interface, if known.
+ */
+typedef enum {	ide_unknown,	ide_generic,	ide_pci,
+		ide_cmd640,	ide_dtc2278,	ide_ali14xx,
+		ide_qd65xx,	ide_umc8672,	ide_ht6560b,
+		ide_pdc4030,	ide_rz1000,	ide_trm290,
+		ide_cmd646,	ide_cy82c693,	ide_4drives,
+		ide_pmac,	ide_etrax100
+} hwif_chipset_t;
+
+/*
  * Structure to hold all information about the location of this port
  */
 typedef struct hw_regs_s {
@@ -231,6 +279,7 @@
 	int		dma;			/* our dma entry */
 	ide_ack_intr_t	*ack_intr;		/* acknowledge interrupt */
 	void		*priv;			/* interface specific data */
+	hwif_chipset_t  chipset;
 } hw_regs_t;
 
 /*
@@ -259,16 +308,20 @@
 #ifndef HAVE_ARCH_OUT_BYTE
 #ifdef REALLY_FAST_IO
 #define OUT_BYTE(b,p)          outb((b),(p))
+#define OUT_WORD(w,p)          outw((w),(p))
 #else
 #define OUT_BYTE(b,p)          outb_p((b),(p))
+#define OUT_WORD(w,p)          outw_p((w),(p))
 #endif
 #endif
 
 #ifndef HAVE_ARCH_IN_BYTE
 #ifdef REALLY_FAST_IO
-#define IN_BYTE(p)             (byte)inb_p(p)
-#else
 #define IN_BYTE(p)             (byte)inb(p)
+#define IN_WORD(p)             (short)inw(p)
+#else
+#define IN_BYTE(p)             (byte)inb_p(p)
+#define IN_WORD(p)             (short)inw_p(p)
 #endif
 #endif
 
@@ -328,6 +381,7 @@
 	unsigned autotune	: 2;	/* 1=autotune, 2=noautotune, 0=default */
 	unsigned remap_0_to_1	: 2;	/* 0=remap if ezdrive, 1=remap, 2=noremap */
 	unsigned ata_flash	: 1;	/* 1=present, 0=default */
+	unsigned	addressing;	/* : 2; 0=28-bit, 1=48-bit, 2=64-bit */
 	byte		scsi;		/* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */
 	byte		media;		/* disk, cdrom, tape, floppy, ... */
 	select_t	select;		/* basic drive/head select reg value */
@@ -340,7 +394,7 @@
 	byte		bad_wstat;	/* used for ignoring WRERR_STAT */
 	byte		nowerr;		/* used for ignoring WRERR_STAT */
 	byte		sect0;		/* offset of first sector for DM6:DDO */
-	byte 		usage;		/* current "open()" count for drive */
+	unsigned int	usage;		/* current "open()" count for drive */
 	byte 		head;		/* "real" number of heads */
 	byte		sect;		/* "real" sectors per track */
 	byte		bios_head;	/* BIOS/fdisk/LILO number of heads */
@@ -348,6 +402,7 @@
 	unsigned int	bios_cyl;	/* BIOS/fdisk/LILO number of cyls */
 	unsigned int	cyl;		/* "real" number of cyls */
 	unsigned long	capacity;	/* total number of sectors */
+	unsigned long long capacity48;	/* total number of sectors */
 	unsigned int	drive_data;	/* for use by tuneproc/selectproc as needed */
 	void		  *hwif;	/* actually (ide_hwif_t *) */
 	wait_queue_head_t wqueue;	/* used to wait for drive in open() */
@@ -369,6 +424,8 @@
 	byte		init_speed;	/* transfer rate set at boot */
 	byte		current_speed;	/* current transfer rate set */
 	byte		dn;		/* now wide spread use */
+	byte		wcache;		/* status of write cache */
+	byte		acoustic;	/* acoustic management */
 	unsigned int	failures;	/* current failure count */
 	unsigned int	max_failures;	/* maximum allowed failure count */
 } ide_drive_t;
@@ -438,19 +495,7 @@
 /*
  * ide soft-power support
  */
-typedef int (ide_busproc_t) (struct hwif_s *, int);
-
-/*
- * hwif_chipset_t is used to keep track of the specific hardware
- * chipset used by each IDE interface, if known.
- */
-typedef enum {	ide_unknown,	ide_generic,	ide_pci,
-		ide_cmd640,	ide_dtc2278,	ide_ali14xx,
-		ide_qd65xx,	ide_umc8672,	ide_ht6560b,
-		ide_pdc4030,	ide_rz1000,	ide_trm290,
-		ide_cmd646,	ide_cy82c693,	ide_4drives,
-		ide_pmac,       ide_etrax100
-} hwif_chipset_t;
+typedef int (ide_busproc_t) (ide_drive_t *, int);
 
 #define IDE_CHIPSET_PCI_MASK	\
     ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
@@ -521,7 +566,6 @@
 	byte		bus_state;	/* power state of the IDE bus */
 } ide_hwif_t;
 
-
 /*
  * Status returned from various ide_ functions
  */
@@ -533,7 +577,9 @@
 /*
  *  internal ide interrupt handler type
  */
+typedef ide_startstop_t (ide_pre_handler_t)(ide_drive_t *, struct request *);
 typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
+typedef ide_startstop_t (ide_post_handler_t)(ide_drive_t *);
 
 /*
  * when ide_timer_expiry fires, invoke a handler of this type
@@ -554,6 +600,8 @@
 	ide_expiry_t		*expiry;	/* queried upon timeouts */
 } ide_hwgroup_t;
 
+/* structure attached to the request for IDE_TASK_CMDS */
+
 /*
  * configurable drive settings
  */
@@ -604,6 +652,8 @@
 #ifdef CONFIG_PROC_FS
 void proc_ide_create(void);
 void proc_ide_destroy(void);
+void recreate_proc_ide_device(ide_hwif_t *, ide_drive_t *);
+void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *);
 void destroy_proc_ide_drives(ide_hwif_t *);
 void create_proc_ide_interfaces(void);
 void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data);
@@ -636,6 +686,8 @@
 #define IDE_SUBDRIVER_VERSION	1
 
 typedef int		(ide_cleanup_proc)(ide_drive_t *);
+typedef int		(ide_standby_proc)(ide_drive_t *);
+typedef int		(ide_flushcache_proc)(ide_drive_t *);
 typedef ide_startstop_t	(ide_do_request_proc)(ide_drive_t *, struct request *, unsigned long);
 typedef void		(ide_end_request_proc)(byte, ide_hwgroup_t *);
 typedef int		(ide_ioctl_proc)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
@@ -647,7 +699,9 @@
 typedef unsigned long	(ide_capacity_proc)(ide_drive_t *);
 typedef ide_startstop_t	(ide_special_proc)(ide_drive_t *);
 typedef void		(ide_setting_proc)(ide_drive_t *);
-typedef int		(ide_driver_reinit_proc)(ide_drive_t *);
+typedef int		(ide_reinit_proc)(ide_drive_t *);
+typedef void		(ata_prebuilder_proc)(ide_drive_t *);
+typedef void		(atapi_prebuilder_proc)(ide_drive_t *);
 
 typedef struct ide_driver_s {
 	const char			*name;
@@ -657,6 +711,8 @@
 	unsigned supports_dma		: 1;
 	unsigned supports_dsc_overlap	: 1;
 	ide_cleanup_proc		*cleanup;
+	ide_standby_proc		*standby;
+	ide_flushcache_proc		*flushcache;
 	ide_do_request_proc		*do_request;
 	ide_end_request_proc		*end_request;
 	ide_ioctl_proc			*ioctl;
@@ -668,7 +724,9 @@
 	ide_capacity_proc		*capacity;
 	ide_special_proc		*special;
 	ide_proc_entry_t		*proc;
-	ide_driver_reinit_proc		*driver_reinit;
+	ide_reinit_proc			*reinit;
+	ata_prebuilder_proc		*ata_prebuilder;
+	atapi_prebuilder_proc		*atapi_prebuilder;
 } ide_driver_t;
 
 #define DRIVER(drive)		((ide_driver_t *)((drive)->driver))
@@ -727,6 +785,8 @@
 void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
 void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
 
+int drive_is_ready (ide_drive_t *drive);
+
 /*
  * This is used on exit from the driver, to designate the next irq handler
  * and also to start the safety timer.
@@ -748,7 +808,7 @@
  * Issue a simple drive command
  * The drive must be selected beforehand.
  */
-void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler);
+void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler);
 
 /*
  * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
@@ -843,24 +903,92 @@
 /*
  * Clean up after success/failure of an explicit drive cmd.
  * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD).
+ * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASK_MASK).
  */
 void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err);
 
 /*
- * Issue ATA command and wait for completion.
+ * Issue ATA command and wait for completion. use for implementing commands in kernel
  */
 int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *buf);
+
 int ide_wait_cmd_task (ide_drive_t *drive, byte *buf);
+ 
+typedef struct ide_task_s {
+	task_ioreg_t		tfRegister[8];
+	task_ioreg_t		hobRegister[8];
+	ide_reg_valid_t		tf_out_flags;
+	ide_reg_valid_t		tf_in_flags;
+	int			data_phase;
+	int			command_type;
+	ide_pre_handler_t	*prehandler;
+	ide_handler_t		*handler;
+	ide_post_handler_t	*posthandler;
+	void			*special;	/* valid_t generally */
+	struct request		*rq;		/* copy of request */
+	unsigned long		block;		/* copy of block */
+} ide_task_t;
+
+typedef struct pkt_task_s {
+	task_ioreg_t		tfRegister[8];
+	int			data_phase;
+	int			command_type;
+	ide_handler_t		*handler;
+	void			*special;
+	struct request		*rq;		/* copy of request */
+	unsigned long		block;		/* copy of block */
+} pkt_task_t;
+
+/*
+ * taskfile io for disks for now...
+ */
+ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task);
+
+/*
+ * Builds request from ide_ioctl
+ */
+void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, ide_handler_t *handler);
+
+/*
+ * Special Flagged Register Validation Caller
+ */
+// ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task);
+
+ide_startstop_t set_multmode_intr (ide_drive_t *drive);
+ide_startstop_t set_geometry_intr (ide_drive_t *drive);
+ide_startstop_t recal_intr (ide_drive_t *drive);
+ide_startstop_t task_no_data_intr (ide_drive_t *drive);
+ide_startstop_t task_in_intr (ide_drive_t *drive);
+ide_startstop_t task_mulin_intr (ide_drive_t *drive);
+ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq);
+ide_startstop_t task_out_intr (ide_drive_t *drive);
+ide_startstop_t task_mulout_intr (ide_drive_t *drive);
+void ide_init_drive_taskfile (struct request *rq);
+
+int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf);
+
+int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *cmd, byte *buf);
+
+ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile);
+ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile);
+/* Expects args is a full set of TF registers and parses the command type */
+int ide_cmd_type_parser (ide_task_t *args);
+
+int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+
+#ifdef CONFIG_PKT_TASK_IOCTL
+int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+#endif /* CONFIG_PKT_TASK_IOCTL */
 
 void ide_delay_50ms (void);
 int system_bus_clock(void);
 
 byte ide_auto_reduce_xfer (ide_drive_t *drive);
 int ide_driveid_update (ide_drive_t *drive);
-int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature);
+int ide_ata66_check (ide_drive_t *drive, ide_task_t *args);
 int ide_config_drive_speed (ide_drive_t *drive, byte speed);
 byte eighty_ninty_three (ide_drive_t *drive);
-int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature);
+int set_transfer (ide_drive_t *drive, ide_task_t *args);
 
 /*
  * ide_system_bus_speed() returns what we think is the system VESA/PCI
@@ -905,23 +1033,30 @@
 extern ide_proc_entry_t generic_subdriver_entries[];
 #endif
 
+int ide_reinit_drive (ide_drive_t *drive);
+
 #ifdef _IDE_C
 #ifdef CONFIG_BLK_DEV_IDE
 int ideprobe_init (void);
 #endif /* CONFIG_BLK_DEV_IDE */
 #ifdef CONFIG_BLK_DEV_IDEDISK
+int idedisk_reinit (ide_drive_t *drive);
 int idedisk_init (void);
 #endif /* CONFIG_BLK_DEV_IDEDISK */
 #ifdef CONFIG_BLK_DEV_IDECD
+int ide_cdrom_reinit (ide_drive_t *drive);
 int ide_cdrom_init (void);
 #endif /* CONFIG_BLK_DEV_IDECD */
 #ifdef CONFIG_BLK_DEV_IDETAPE
+int idetape_reinit (ide_drive_t *drive);
 int idetape_init (void);
 #endif /* CONFIG_BLK_DEV_IDETAPE */
 #ifdef CONFIG_BLK_DEV_IDEFLOPPY
+int idefloppy_reinit (ide_drive_t *drive);
 int idefloppy_init (void);
 #endif /* CONFIG_BLK_DEV_IDEFLOPPY */
 #ifdef CONFIG_BLK_DEV_IDESCSI
+int idescsi_reinit (ide_drive_t *drive);
 int idescsi_init (void);
 #endif /* CONFIG_BLK_DEV_IDESCSI */
 #endif /* _IDE_C */
@@ -961,4 +1096,7 @@
 
 void hwif_unregister (ide_hwif_t *hwif);
 
+void export_ide_init_queue (ide_drive_t *drive);
+byte export_probe_for_drive (ide_drive_t *drive);
+
 #endif /* _IDE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/if_bonding.h linux/include/linux/if_bonding.h
--- linux.orig/include/linux/if_bonding.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/if_bonding.h	2002-07-20 01:08:30.000000000 +0000
@@ -51,7 +51,7 @@
 #define BOND_STATE_ACTIVE       0   /* link is active */
 #define BOND_STATE_BACKUP       1   /* link is backup */
 
-#define MAX_BONDS               1   /* Maximum number of devices to support */
+#define BOND_DEFAULT_MAX_BONDS  1   /* Default maximum number of devices to support */
 
 typedef struct ifbond {
 	__s32 bond_mode;
@@ -76,6 +76,7 @@
 	short  delay;
 	char   link;    /* one of BOND_LINK_XXXX */
 	char   state;   /* one of BOND_STATE_XXXX */
+	unsigned short original_flags;
 	u32 link_failure_count;
 } slave_t;
 
@@ -104,6 +105,8 @@
 #endif /* CONFIG_PROC_FS */
 	struct bonding *next_bond;
 	struct net_device *device;
+	struct dev_mc_list *mc_list;
+	unsigned short flags;
 } bonding_t;
 #endif /* __KERNEL__ */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/if_pppox.h linux/include/linux/if_pppox.h
--- linux.orig/include/linux/if_pppox.h	2001-11-22 19:47:14.000000000 +0000
+++ linux/include/linux/if_pppox.h	2002-07-20 01:08:27.000000000 +0000
@@ -126,13 +126,14 @@
 extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd,
 			       unsigned long arg);
 
-/* PPPoE socket states */
+/* PPPoX socket states */
 enum {
     PPPOX_NONE		= 0,  /* initial state */
     PPPOX_CONNECTED	= 1,  /* connection established ==TCP_ESTABLISHED */
     PPPOX_BOUND		= 2,  /* bound to ppp device */
     PPPOX_RELAY		= 4,  /* forwarding is enabled */
-    PPPOX_DEAD		= 8
+    PPPOX_ZOMBIE	= 8,  /* dead, but still bound to ppp device */
+    PPPOX_DEAD		= 16  /* dead, useless, please clean me up!*/
 };
 
 extern struct ppp_channel_ops pppoe_chan_ops;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/if_vlan.h linux/include/linux/if_vlan.h
--- linux.orig/include/linux/if_vlan.h	2001-11-22 19:50:06.000000000 +0000
+++ linux/include/linux/if_vlan.h	2002-07-20 01:08:28.000000000 +0000
@@ -52,70 +52,16 @@
    unsigned short       h_vlan_encapsulated_proto; /* packet type ID field (or len) */
 };
 
-/*  Find a VLAN device by the MAC address of it's Ethernet device, and
- *  it's VLAN ID.  The default configuration is to have VLAN's scope
- *  to be box-wide, so the MAC will be ignored.  The mac will only be
- *  looked at if we are configured to have a seperate set of VLANs per
- *  each MAC addressable interface.  Note that this latter option does
- *  NOT follow the spec for VLANs, but may be useful for doing very
- *  large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs.
- */
-struct net_device *find_802_1Q_vlan_dev(struct net_device* real_dev,
-                                        unsigned short VID); /* vlan.c */
+#define VLAN_VID_MASK	0xfff
 
 /* found in af_inet.c */
 extern int (*vlan_ioctl_hook)(unsigned long arg);
 
-/* found in vlan_dev.c */
-struct net_device_stats* vlan_dev_get_stats(struct net_device* dev);
-int vlan_dev_rebuild_header(struct sk_buff *skb);
-int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
-                  struct packet_type* ptype);
-int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
-                         unsigned short type, void *daddr, void *saddr,
-                         unsigned len);
-int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
-int vlan_dev_set_mac_address(struct net_device *dev, void* addr);
-int vlan_dev_open(struct net_device* dev);
-int vlan_dev_stop(struct net_device* dev);
-int vlan_dev_init(struct net_device* dev);
-void vlan_dev_destruct(struct net_device* dev);
-void vlan_dev_copy_and_sum(struct sk_buff *dest, unsigned char *src,
-                           int length, int base);
-int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
-int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
-int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val);
-
-/* VLAN multicast stuff */
-/* Delete all of the MC list entries from this vlan device.  Also deals
- * with the underlying device...
- */
-void vlan_flush_mc_list(struct net_device* dev);
-/* copy the mc_list into the vlan_info structure. */
-void vlan_copy_mc_list(struct dev_mc_list* mc_list, struct vlan_dev_info* vlan_info);
-/** dmi is a single entry into a dev_mc_list, a single node.  mc_list is
- *  an entire list, and we'll iterate through it.
- */
-int vlan_should_add_mc(struct dev_mc_list *dmi, struct dev_mc_list *mc_list);
-/** Taken from Gleb + Lennert's VLAN code, and modified... */
-void vlan_dev_set_multicast_list(struct net_device *vlan_dev);
-
-int vlan_collection_add_vlan(struct vlan_collection* vc, unsigned short vlan_id,
-                             unsigned short flags);
-int vlan_collection_remove_vlan(struct vlan_collection* vc,
-                                struct net_device* vlan_dev);
-int vlan_collection_remove_vlan_id(struct vlan_collection* vc, unsigned short vlan_id);
-
-/* found in vlan.c */
-/* Our listing of VLAN group(s) */
-extern struct vlan_group* p802_1Q_vlan_list;
-
 #define VLAN_NAME "vlan"
 
 /* if this changes, algorithm will have to be reworked because this
  * depends on completely exhausting the VLAN identifier space.  Thus
- * it gives constant time look-up, but it many cases it wastes memory.
+ * it gives constant time look-up, but in many cases it wastes memory.
  */
 #define VLAN_GROUP_ARRAY_LEN 4096
 
@@ -170,56 +116,73 @@
 
 /* inline functions */
 
-/* Used in vlan_skb_recv */
-static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
+static inline struct net_device_stats *vlan_dev_get_stats(struct net_device *dev)
 {
-	if (VLAN_DEV_INFO(skb->dev)->flags & 1) {
-		skb = skb_share_check(skb, GFP_ATOMIC);
-		if (skb) {
-			/* Lifted from Gleb's VLAN code... */
-			memmove(skb->data - ETH_HLEN,
-				skb->data - VLAN_ETH_HLEN, 12);
-			skb->mac.raw += VLAN_HLEN;
-		}
-	}
-
-	return skb;
+	return &(VLAN_DEV_INFO(dev)->dev_stats);
 }
 
-static inline unsigned short vlan_dev_get_egress_qos_mask(struct net_device* dev,
-							  struct sk_buff* skb)
+static inline __u32 vlan_get_ingress_priority(struct net_device *dev,
+					      unsigned short vlan_tag)
 {
-	struct vlan_priority_tci_mapping *mp =
-		VLAN_DEV_INFO(dev)->egress_priority_map[(skb->priority & 0xF)];
+	struct vlan_dev_info *vip = VLAN_DEV_INFO(dev);
 
-	while (mp) {
-		if (mp->priority == skb->priority) {
-			return mp->vlan_qos; /* This should already be shifted to mask
-					      * correctly with the VLAN's TCI
-					      */
-		}
-		mp = mp->next;
-	}
-	return 0;
+	return vip->ingress_priority_map[(vlan_tag >> 13) & 0x7];
 }
 
-static inline int vlan_dmi_equals(struct dev_mc_list *dmi1,
-                                  struct dev_mc_list *dmi2)
-{
-	return ((dmi1->dmi_addrlen == dmi2->dmi_addrlen) &&
-		(memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0));
-}
+/* VLAN tx hw acceleration helpers. */
+struct vlan_skb_tx_cookie {
+	u32	magic;
+	u32	vlan_tag;
+};
 
-static inline void vlan_destroy_mc_list(struct dev_mc_list *mc_list)
+#define VLAN_TX_COOKIE_MAGIC	0x564c414e	/* "VLAN" in ascii. */
+#define VLAN_TX_SKB_CB(__skb)	((struct vlan_skb_tx_cookie *)&((__skb)->cb[0]))
+#define vlan_tx_tag_present(__skb) \
+	(VLAN_TX_SKB_CB(__skb)->magic == VLAN_TX_COOKIE_MAGIC)
+#define vlan_tx_tag_get(__skb)	(VLAN_TX_SKB_CB(__skb)->vlan_tag)
+
+/* VLAN rx hw acceleration helper.  This acts like netif_rx().  */
+static inline int vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
+				  unsigned short vlan_tag)
 {
-	struct dev_mc_list *dmi = mc_list;
-	struct dev_mc_list *next;
+	struct net_device_stats *stats;
 
-	while(dmi) {
-		next = dmi->next;
-		kfree(dmi);
-		dmi = next;
+	skb->dev = grp->vlan_devices[vlan_tag & VLAN_VID_MASK];
+	if (skb->dev == NULL) {
+		kfree_skb(skb);
+
+		/* Not NET_RX_DROP, this is not being dropped
+		 * due to congestion.
+		 */
+		return 0;
 	}
+
+	skb->dev->last_rx = jiffies;
+
+	stats = vlan_dev_get_stats(skb->dev);
+	stats->rx_packets++;
+	stats->rx_bytes += skb->len;
+
+	skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tag);
+	switch (skb->pkt_type) {
+	case PACKET_BROADCAST:
+		break;
+
+	case PACKET_MULTICAST:
+		stats->multicast++;
+		break;
+
+	case PACKET_OTHERHOST:
+		/* Our lower layer thinks this is not local, let's make sure.
+		 * This allows the VLAN to have a different MAC than the underlying
+		 * device, and still route correctly.
+		 */
+		if (!memcmp(skb->mac.ethernet->h_dest, skb->dev->dev_addr, ETH_ALEN))
+			skb->pkt_type = PACKET_HOST;
+		break;
+	};
+
+	return netif_rx(skb);
 }
 
 #endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/inet.h linux/include/linux/inet.h
--- linux.orig/include/linux/inet.h	2000-10-02 21:14:29.000000000 +0000
+++ linux/include/linux/inet.h	2002-07-20 01:08:29.000000000 +0000
@@ -45,7 +45,6 @@
 #ifdef __KERNEL__
 
 extern void		inet_proto_init(struct net_proto *pro);
-extern char		*in_ntoa(__u32 in);
 extern __u32		in_aton(const char *str);
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/inetdevice.h linux/include/linux/inetdevice.h
--- linux.orig/include/linux/inetdevice.h	2001-07-26 20:52:39.000000000 +0000
+++ linux/include/linux/inetdevice.h	2002-07-20 01:08:25.000000000 +0000
@@ -18,6 +18,7 @@
 	int	mc_forwarding;
 	int	tag;
 	int     arp_filter;
+	int	medium_id;
 	void	*sysctl;
 };
 
@@ -48,6 +49,7 @@
 #define IN_DEV_TX_REDIRECTS(in_dev)	(ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects)
 #define IN_DEV_SEC_REDIRECTS(in_dev)	(ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
 #define IN_DEV_IDTAG(in_dev)		((in_dev)->cnf.tag)
+#define IN_DEV_MEDIUM_ID(in_dev)	((in_dev)->cnf.medium_id)
 
 #define IN_DEV_RX_REDIRECTS(in_dev) \
 	((IN_DEV_FORWARD(in_dev) && \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/input.h linux/include/linux/input.h
--- linux.orig/include/linux/input.h	2001-09-12 22:34:06.000000000 +0000
+++ linux/include/linux/input.h	2002-07-20 01:08:35.000000000 +0000
@@ -307,6 +307,9 @@
 
 #define KEY_UNKNOWN		220
 
+#define KEY_BRIGHTNESSDOWN	224
+#define KEY_BRIGHTNESSUP	225
+
 #define BTN_MISC		0x100
 #define BTN_0			0x100
 #define BTN_1			0x101
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/irq.h linux/include/linux/irq.h
--- linux.orig/include/linux/irq.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/irq.h	2002-07-20 01:08:34.000000000 +0000
@@ -76,4 +76,4 @@
 
 #endif
 
-#endif /* __asm_h */
+#endif /* __irq_h */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/jbd.h linux/include/linux/jbd.h
--- linux.orig/include/linux/jbd.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/jbd.h	2002-07-20 01:08:39.000000000 +0000
@@ -352,7 +352,7 @@
 	 */
 	struct journal_head *	t_async_datalist;
 	
-	/* Doubly-linked circular list of all forget buffers (superceded
+	/* Doubly-linked circular list of all forget buffers (superseded
            buffers which we can un-checkpoint once this transaction
            commits) */
 	struct journal_head *	t_forget;
@@ -793,7 +793,7 @@
 #define BJ_SyncData	1	/* Normal data: flush before commit */
 #define BJ_AsyncData	2	/* writepage data: wait on it before commit */
 #define BJ_Metadata	3	/* Normal journaled metadata */
-#define BJ_Forget	4	/* Buffer superceded by this transaction */
+#define BJ_Forget	4	/* Buffer superseded by this transaction */
 #define BJ_IO		5	/* Buffer is for temporary IO use */
 #define BJ_Shadow	6	/* Buffer contents being shadowed to the log */
 #define BJ_LogCtl	7	/* Buffer contains log descriptors */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/jffs2.h linux/include/linux/jffs2.h
--- linux.orig/include/linux/jffs2.h	2001-09-14 21:04:07.000000000 +0000
+++ linux/include/linux/jffs2.h	2002-07-20 01:08:31.000000000 +0000
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: jffs2.h,v 1.18 2001/03/25 22:36:12 dwmw2 Exp $
+ * $Id: jffs2.h,v 1.19 2001/10/09 13:20:23 dwmw2 Exp $
  *
  */
 
@@ -103,7 +103,7 @@
 	__u16 nodetype;
 	__u32 totlen; /* So we can skip over nodes we don't grok */
 	__u32 hdr_crc;
-};
+} __attribute__((packed));
 
 struct jffs2_raw_dirent
 {
@@ -121,7 +121,7 @@
 	__u32 node_crc;
 	__u32 name_crc;
 	__u8 name[0];
-};
+} __attribute__((packed));
 
 /* The JFFS2 raw inode structure: Used for storage on physical media.  */
 /* The uid, gid, atime, mtime and ctime members could be longer, but 
@@ -153,7 +153,7 @@
 	__u32 data_crc;   /* CRC for the (compressed) data.  */
 	__u32 node_crc;   /* CRC for the raw inode (excluding data)  */
 //	__u8 data[dsize];
-};
+} __attribute__((packed));
 
 union jffs2_node_union {
 	struct jffs2_raw_inode i;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/jffs2_fs_sb.h linux/include/linux/jffs2_fs_sb.h
--- linux.orig/include/linux/jffs2_fs_sb.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/jffs2_fs_sb.h	2002-07-20 01:08:22.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: jffs2_fs_sb.h,v 1.16 2001/09/18 20:15:18 dwmw2 Exp $ */
+/* $Id: jffs2_fs_sb.h,v 1.16.2.1 2002/02/23 14:13:34 dwmw2 Exp $ */
 
 #ifndef _JFFS2_FS_SB
 #define _JFFS2_FS_SB
@@ -12,6 +12,7 @@
 #define INOCACHE_HASHSIZE 1
 
 #define JFFS2_SB_FLAG_RO 1
+#define JFFS2_SB_FLAG_MOUNTING 2
 
 /* A struct for the overall file system control.  Pointers to
    jffs2_sb_info structs are named `c' in the source code.  
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/kbd_kern.h linux/include/linux/kbd_kern.h
--- linux.orig/include/linux/kbd_kern.h	2001-11-22 19:47:23.000000000 +0000
+++ linux/include/linux/kbd_kern.h	2002-07-20 01:08:29.000000000 +0000
@@ -140,7 +140,6 @@
 int getkeycode(unsigned int scancode);
 int setkeycode(unsigned int scancode, unsigned int keycode);
 void compute_shiftstate(void);
-int keyboard_wait_for_keypress(struct console *);
 
 /* defkeymap.c */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/kd.h linux/include/linux/kd.h
--- linux.orig/include/linux/kd.h	2001-11-22 19:47:07.000000000 +0000
+++ linux/include/linux/kd.h	2002-07-20 01:08:29.000000000 +0000
@@ -26,8 +26,8 @@
 #define KDGETLED	0x4B31	/* return current led state */
 #define KDSETLED	0x4B32	/* set led state [lights, not flags] */
 #define 	LED_SCR		0x01	/* scroll lock led */
-#define 	LED_CAP		0x04	/* caps lock led */
 #define 	LED_NUM		0x02	/* num lock led */
+#define 	LED_CAP		0x04	/* caps lock led */
 
 #define KDGKBTYPE	0x4B33	/* get keyboard type */
 #define 	KB_84		0x01
@@ -89,10 +89,10 @@
 #define KDSKBMETA	0x4B63	/* sets meta key handling mode */
 
 #define		K_SCROLLLOCK	0x01
-#define		K_CAPSLOCK	0x02
-#define		K_NUMLOCK	0x04
+#define		K_NUMLOCK	0x02
+#define		K_CAPSLOCK	0x04
 #define	KDGKBLED	0x4B64	/* get led flags (not lights) */
-#define KDSKBLED	0x4B65	/* set led flags (not lights) */
+#define	KDSKBLED	0x4B65	/* set led flags (not lights) */
 
 struct kbentry {
 	unsigned char kb_table;
@@ -132,19 +132,6 @@
 
 #define KDSIGACCEPT	0x4B4E	/* accept kbd generated signals */
 
-struct hwclk_time {
-	unsigned	sec;	/* 0..59 */
-	unsigned	min;	/* 0..59 */
-	unsigned	hour;	/* 0..23 */
-	unsigned	day;	/* 1..31 */
-	unsigned	mon;	/* 0..11 */
-	unsigned	year;	/* 70... */
-	int		wday;	/* 0..6, 0 is Sunday, -1 means unknown/don't set */
-};
-
-#define KDGHWCLK        0x4B50	/* get hardware clock */
-#define KDSHWCLK        0x4B51  /* set hardware clock */
-
 struct kbd_repeat {
 	int delay;	/* in msec; <= 0: don't change */
 	int rate;	/* in msec; <= 0: don't change */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/kdev_t.h linux/include/linux/kdev_t.h
--- linux.orig/include/linux/kdev_t.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/kdev_t.h	2002-07-20 01:08:30.000000000 +0000
@@ -76,12 +76,13 @@
 extern const char * kdevname(kdev_t);	/* note: returns pointer to static data! */
 
 /* 2.5.x compatibility */
-
-#define mk_kdev(a,b) MKDEV(a,b)
-#define major(d) MAJOR(d)
-#define minor(d) MINOR(d)
-#define kdev_same(a,b) (a==b)
-#define kdev_none(d) (!(d))
+#define mk_kdev(a,b)	MKDEV(a,b)
+#define major(d)	MAJOR(d)
+#define minor(d)	MINOR(d)
+#define kdev_same(a,b)	((a) == (b))
+#define kdev_none(d)	(!(d))
+#define kdev_val(d)	((unsigned int)(d))
+#define val_to_kdev(d)	((kdev_t)(d))
 
 /*
 As long as device numbers in the outside world have 16 bits only,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/kernel.h linux/include/linux/kernel.h
--- linux.orig/include/linux/kernel.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/kernel.h	2002-07-20 01:08:21.000000000 +0000
@@ -11,6 +11,7 @@
 #include <linux/linkage.h>
 #include <linux/stddef.h>
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 /* Optimization barrier */
 /* The "volatile" is due to gcc bugs */
@@ -161,6 +162,9 @@
 #define max_t(type,x,y) \
 	({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
 
+extern void __out_of_line_bug(int line) ATTRIB_NORET;
+#define out_of_line_bug() __out_of_line_bug(__LINE__)
+
 #endif /* __KERNEL__ */
 
 #define SI_LOAD_SHIFT	16
@@ -181,4 +185,6 @@
 	char _f[20-2*sizeof(long)-sizeof(int)];	/* Padding: libc5 uses this.. */
 };
 
-#endif
+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
+
+#endif /* _LINUX_KERNEL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/kernel_stat.h linux/include/linux/kernel_stat.h
--- linux.orig/include/linux/kernel_stat.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/kernel_stat.h	2002-07-20 01:08:34.000000000 +0000
@@ -29,9 +29,6 @@
 #if !defined(CONFIG_ARCH_S390)
 	unsigned int irqs[NR_CPUS][NR_IRQS];
 #endif
-	unsigned int ipackets, opackets;
-	unsigned int ierrors, oerrors;
-	unsigned int collisions;
 	unsigned int context_swtch;
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/keyboard.h linux/include/linux/keyboard.h
--- linux.orig/include/linux/keyboard.h	2001-11-22 19:47:07.000000000 +0000
+++ linux/include/linux/keyboard.h	2002-07-20 01:08:26.000000000 +0000
@@ -26,7 +26,6 @@
 extern const int max_vals[];
 extern unsigned short *key_maps[MAX_NR_KEYMAPS];
 extern unsigned short plain_map[NR_KEYS];
-extern wait_queue_head_t keypress_wait;
 extern unsigned char keyboard_type;
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/lvm.h linux/include/linux/lvm.h
--- linux.orig/include/linux/lvm.h	2001-11-11 18:09:32.000000000 +0000
+++ linux/include/linux/lvm.h	2002-07-20 01:08:23.000000000 +0000
@@ -3,28 +3,28 @@
  * kernel/lvm.h
  * tools/lib/lvm.h
  *
- * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
+ * Copyright (C) 1997 - 2001  Heinz Mauelshagen, Sistina Software
  *
  * February-November 1997
  * May-July 1998
  * January-March,July,September,October,Dezember 1999
  * January,February,July,November 2000
- * January 2001
+ * January-March,June,July 2001
  *
  * lvm 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, or (at your option)
  * any later version.
- * 
+ *
  * lvm 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA. 
+ * Boston, MA 02111-1307, USA.
  *
  */
 
@@ -52,8 +52,7 @@
  *    08/12/1999 - changed LVM_LV_SIZE_MAX macro to reflect current 1TB limit
  *    01/01/2000 - extended lv_v2 core structure by wait_queue member
  *    12/02/2000 - integrated Andrea Arcagnelli's snapshot work
- *    14/02/2001 - changed LVM_SNAPSHOT_MIN_CHUNK to 1 page
- *    18/02/2000 - seperated user and kernel space parts by 
+ *    18/02/2000 - seperated user and kernel space parts by
  *                 #ifdef them with __KERNEL__
  *    08/03/2000 - implemented cluster/shared bits for vg_access
  *    26/06/2000 - implemented snapshot persistency and resizing support
@@ -61,11 +60,18 @@
  *    12/11/2000 - removed unneeded timestamp definitions
  *    24/12/2000 - removed LVM_TO_{CORE,DISK}*, use cpu_{from, to}_le*
  *                 instead - Christoph Hellwig
- *    01/03/2001 - Rename VG_CREATE to VG_CREATE_OLD and add new VG_CREATE
+ *    22/01/2001 - Change ulong to uint32_t
+ *    14/02/2001 - changed LVM_SNAPSHOT_MIN_CHUNK to 1 page
+ *    20/02/2001 - incremented IOP version to 11 because of incompatible
+ *                 change in VG activation (in order to support devfs better)
+ *    01/03/2001 - Revert to IOP10 and add VG_CREATE_OLD call for compatibility
  *    08/03/2001 - new lv_t (in core) version number 5: changed page member
  *                 to (struct kiobuf *) to use for COW exception table io
- *    23/03/2001 - Change a (presumably) mistyped pv_t* to an lv_t*
- *    26/03/2001 - changed lv_v4 to lv_v5 in structure definition [HM]
+ *    26/03/2001 - changed lv_v4 to lv_v5 in structure definition (HM)
+ *    21/06/2001 - changed BLOCK_SIZE back to 1024 for non S/390
+ *    22/06/2001 - added Andreas Dilger's PE on 4k boundary alignment enhancements
+ *    19/07/2001 - added rwsem compatibility macros for 2.2 kernels
+ *    13/11/2001 - reduced userspace inclusion of kernel headers to a minimum
  *
  */
 
@@ -73,10 +79,10 @@
 #ifndef _LVM_H_INCLUDE
 #define _LVM_H_INCLUDE
 
-#define LVM_RELEASE_NAME "1.0.1-rc4(ish)"
-#define LVM_RELEASE_DATE "03/10/2001"
+#define LVM_RELEASE_NAME "1.0.3"
+#define LVM_RELEASE_DATE "19/02/2002"
 
-#define _LVM_KERNEL_H_VERSION   "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
+#define	_LVM_KERNEL_H_VERSION	"LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")"
 
 #include <linux/version.h>
 
@@ -98,16 +104,26 @@
    #define DEBUG_READ
    #define DEBUG_GENDISK
    #define DEBUG_VG_CREATE
-   #define DEBUG_LVM_BLK_OPEN
+   #define DEBUG_DEVICE
    #define DEBUG_KFREE
  */
-#endif				/* #ifdef __KERNEL__ */
 
 #include <linux/kdev_t.h>
 #include <linux/list.h>
-
 #include <asm/types.h>
 #include <linux/major.h>
+#else
+/* This prevents the need to include <linux/list.h> which
+   causes problems on some platforms. It's not nice but then
+   neither is the alternative. */
+struct list_head {
+        struct list_head *next, *prev;
+};
+#define __KERNEL__
+#include <linux/kdev_t.h>
+#undef __KERNEL__
+#endif				/* #ifndef __KERNEL__ */
+
 
 #ifdef __KERNEL__
 #include <linux/spinlock.h>
@@ -115,6 +131,7 @@
 #include <asm/semaphore.h>
 #endif				/* #ifdef __KERNEL__ */
 
+
 #include <asm/page.h>
 
 #if !defined ( LVM_BLK_MAJOR) || !defined ( LVM_CHAR_MAJOR)
@@ -125,7 +142,7 @@
 #undef	BLOCK_SIZE
 #endif
 
-#ifdef CONFIG_ARCH_S390 
+#ifdef CONFIG_ARCH_S390
 #define BLOCK_SIZE	4096
 #else
 #define BLOCK_SIZE	1024
@@ -189,6 +206,43 @@
 
 
 /*
+ * VGDA: default disk spaces and offsets
+ *
+ *   There's space after the structures for later extensions.
+ *   The physical volume structure holds offset and size definitions
+ *   for itself (well, kind of redundant ;-) and all other structure{s| arrays};
+ *
+ *   In recent versions since LVM 0.9.1 we align to 4k offsets in order to ease
+ *   future kernel reads of the metadata.
+ *
+ *   offset               what                               size
+ *   ---------------      --------------------------------   ------------
+ *   0                    physical volume structure          pv->pv_on_disk.size
+ *                                                           (~500 byte)
+ *   pv->vg_on_disk.base  volume group structure             pv->vg_on_disk.size
+ *
+ *   pv->uuidlist_on_disk.base                               128 byte each
+ *                        uuidlist of physical volumes
+ *                        holding one uuid per physical volume
+ *
+ *   pv->lv_on_disk.base  logical volume structures;         pv->lv_on_disk.size
+ *                        one structure per logical volume   (~300 byte each)
+ *
+ *   pv->pe_on_disk.base  physical extent alloc. structs     pv->pe_on_disk.size
+ *                        one strcuture per physical extent  (4 byte each)
+ *
+ *   End of disk -        first physical extent              default 4 megabyte
+ *   PE total *
+ *   PE size
+ *   (rounded to 64k offset today)
+ *
+ *   pv->pe_on_disk.base + pv->pe_on_disk.size == start of first physical extent
+ *
+ */
+
+/* DONT TOUCH THESE !!! */
+
+/*
  * LVM_PE_T_MAX corresponds to:
  *
  * 8KB PE size can map a ~512 MB logical volume at the cost of 1MB memory,
@@ -199,7 +253,7 @@
  *
  * Maximum PE size of 16GB gives a maximum logical volume size of 1024 TB.
  *
- * AFAIK, the actual kernels limit this to 1 TB.
+ * AFAIK, the actual kernels limit this to 2 TB.
  *
  * Should be a sufficient spectrum ;*)
  */
@@ -217,8 +271,9 @@
 #define	LVM_MAX_STRIPES		128	/* max # of stripes */
 #define	LVM_MAX_SIZE            ( 1024LU * 1024 / SECTOR_SIZE * 1024 * 1024)	/* 1TB[sectors] */
 #define	LVM_MAX_MIRRORS    	2	/* future use */
-#define	LVM_MIN_READ_AHEAD	2	/* minimum read ahead sectors */
-#define	LVM_MAX_READ_AHEAD	120	/* maximum read ahead sectors */
+#define	LVM_MIN_READ_AHEAD	0	/* minimum read ahead sectors */
+#define	LVM_DEFAULT_READ_AHEAD	1024	/* sectors for 512k scsi segments */
+#define	LVM_MAX_READ_AHEAD	10000	/* maximum read ahead sectors */
 #define	LVM_MAX_LV_IO_TIMEOUT	60	/* seconds I/O timeout (future use) */
 #define	LVM_PARTITION           0xfe	/* LVM partition id */
 #define	LVM_NEW_PARTITION       0x8e	/* new LVM partition id (10/09/1999) */
@@ -298,7 +353,12 @@
 #endif
 
 /* lock the logical volume manager */
+#if LVM_DRIVER_IOP_VERSION > 11
+#define	LVM_LOCK_LVM            _IO ( 0xfe, 0x9A)
+#else
+/* This is actually the same as _IO ( 0xff, 0x00), oops.  Remove for IOP 12+ */
 #define	LVM_LOCK_LVM            _IO ( 0xfe, 0x100)
+#endif
 /* END ioctls */
 
 
@@ -495,9 +555,9 @@
 	uint lv_read_ahead;
 
 	/* delta to version 1 starts here */
-       struct lv_v5 *lv_snapshot_org;
-       struct lv_v5 *lv_snapshot_prev;
-       struct lv_v5 *lv_snapshot_next;
+	struct lv_v5 *lv_snapshot_org;
+	struct lv_v5 *lv_snapshot_prev;
+	struct lv_v5 *lv_snapshot_next;
 	lv_block_exception_t *lv_block_exception;
 	uint lv_remap_ptr;
 	uint lv_remap_end;
@@ -661,6 +721,7 @@
 } lv_snapshot_use_rate_req_t;
 
 
+
 /* useful inlines */
 static inline ulong round_up(ulong n, ulong size) {
 	size--;
@@ -671,6 +732,7 @@
 	return round_up(n, size) / size;
 }
 
+/* FIXME: nasty capital letters */
 static int inline LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg_t *vg, lv_t *lv) {
 	return vg->pe_size / lv->lv_chunk_size;
 }
@@ -693,4 +755,6 @@
 	return entries;
 }
 
+
 #endif				/* #ifndef _LVM_H_INCLUDE */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/major.h linux/include/linux/major.h
--- linux.orig/include/linux/major.h	2001-09-18 06:23:40.000000000 +0000
+++ linux/include/linux/major.h	2002-07-20 01:08:29.000000000 +0000
@@ -140,6 +140,8 @@
 
 #define LVM_CHAR_MAJOR	109	/* Logical Volume Manager */
 
+#define	UMEM_MAJOR	116	/* http://www.umem.com/ Battery Backed RAM */
+
 #define RTF_MAJOR	150
 #define RAW_MAJOR	162
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/miscdevice.h linux/include/linux/miscdevice.h
--- linux.orig/include/linux/miscdevice.h	2001-11-22 19:47:07.000000000 +0000
+++ linux/include/linux/miscdevice.h	2002-07-20 01:08:23.000000000 +0000
@@ -13,6 +13,7 @@
 #define APOLLO_MOUSE_MINOR 7
 #define PC110PAD_MINOR 9
 #define ADB_MOUSE_MINOR 10
+#define MK712_MINOR 15			/* MK712 touch screen */
 #define WATCHDOG_MINOR		130	/* Watchdog timer     */
 #define TEMP_MINOR		131	/* Temperature Sensor */
 #define RTC_MINOR 135
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/mm.h linux/include/linux/mm.h
--- linux.orig/include/linux/mm.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/linux/mm.h	2002-07-20 01:08:23.000000000 +0000
@@ -15,6 +15,7 @@
 
 extern unsigned long max_mapnr;
 extern unsigned long num_physpages;
+extern unsigned long num_mappedpages;
 extern void * high_memory;
 extern int page_cluster;
 /* The inactive_clean lists are per zone. */
@@ -159,12 +160,23 @@
 					   updated asynchronously */
 	struct list_head lru;		/* Pageout list, eg. active_list;
 					   protected by pagemap_lru_lock !! */
-	wait_queue_head_t wait;		/* Page locked?  Stand in line... */
 	struct page **pprev_hash;	/* Complement to *next_hash. */
 	struct buffer_head * buffers;	/* Buffer maps us to a disk block. */
+
+	/*
+	 * On machines where all RAM is mapped into kernel address space,
+	 * we can simply calculate the virtual address. On machines with
+	 * highmem some memory is mapped into kernel virtual memory
+	 * dynamically, so we need a place to store that address.
+	 * Note that this field could be 16 bits on x86 ... ;)
+	 *
+	 * Architectures with slow multiplication can define
+	 * WANT_PAGE_VIRTUAL in asm/page.h
+	 */
+#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
 	void *virtual;			/* Kernel virtual address (NULL if
 					   not kmapped, ie. highmem) */
-	struct zone_struct *zone;	/* Memory zone we are in. */
+#endif /* CONFIG_HIGMEM || WANT_PAGE_VIRTUAL */
 } mem_map_t;
 
 /*
@@ -239,7 +251,7 @@
  * - private pages which have been modified may need to be swapped out
  *   to swap space and (later) to be read back into memory.
  * During disk I/O, PG_locked is used. This bit is set before I/O
- * and reset when I/O completes. page->wait is a wait queue of all
+ * and reset when I/O completes. page_waitqueue(page) is a wait queue of all
  * tasks waiting for the I/O on this page to complete.
  * PG_uptodate tells whether the page's contents is valid.
  * When a read completes, the page becomes uptodate, unless a disk I/O
@@ -301,6 +313,61 @@
 #define SetPageChecked(page)	set_bit(PG_checked, &(page)->flags)
 #define PageLaunder(page)	test_bit(PG_launder, &(page)->flags)
 #define SetPageLaunder(page)	set_bit(PG_launder, &(page)->flags)
+#define ClearPageLaunder(page)	clear_bit(PG_launder, &(page)->flags)
+
+/*
+ * The zone field is never updated after free_area_init_core()
+ * sets it, so none of the operations on it need to be atomic.
+ */
+#define NODE_SHIFT 4
+#define ZONE_SHIFT (BITS_PER_LONG - 8)
+
+struct zone_struct;
+extern struct zone_struct *zone_table[];
+
+static inline zone_t *page_zone(struct page *page)
+{
+	return zone_table[page->flags >> ZONE_SHIFT];
+}
+
+static inline void set_page_zone(struct page *page, unsigned long zone_num)
+{
+	page->flags &= ~(~0UL << ZONE_SHIFT);
+	page->flags |= zone_num << ZONE_SHIFT;
+}
+
+/*
+ * In order to avoid #ifdefs within C code itself, we define
+ * set_page_address to a noop for non-highmem machines, where
+ * the field isn't useful.
+ * The same is true for page_address() in arch-dependent code.
+ */
+#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
+
+#define set_page_address(page, address)			\
+	do {						\
+		(page)->virtual = (address);		\
+	} while(0)
+
+#else /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
+#define set_page_address(page, address)  do { } while(0)
+#endif /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
+
+/*
+ * Permanent address of a page. Obviously must never be
+ * called on a highmem page.
+ */
+#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
+
+#define page_address(page) ((page)->virtual)
+
+#else /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
+
+#define page_address(page)						\
+	__va( (((page) - page_zone(page)->zone_mem_map) << PAGE_SHIFT)	\
+			+ page_zone(page)->zone_start_paddr)
+
+#endif /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
 
 extern void FASTCALL(set_page_dirty(struct page *));
 
@@ -603,6 +670,8 @@
 
 extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
 
+extern struct page * vmalloc_to_page(void *addr);
+
 #endif /* __KERNEL__ */
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/mmzone.h linux/include/linux/mmzone.h
--- linux.orig/include/linux/mmzone.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/mmzone.h	2002-07-20 01:08:22.000000000 +0000
@@ -7,6 +7,7 @@
 #include <linux/config.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/wait.h>
 
 /*
  * Free memory management - zoned buddy allocator.
@@ -48,6 +49,35 @@
 	free_area_t		free_area[MAX_ORDER];
 
 	/*
+	 * wait_table		-- the array holding the hash table
+	 * wait_table_size	-- the size of the hash table array
+	 * wait_table_shift	-- wait_table_size
+	 * 				== BITS_PER_LONG (1 << wait_table_bits)
+	 *
+	 * The purpose of all these is to keep track of the people
+	 * waiting for a page to become available and make them
+	 * runnable again when possible. The trouble is that this
+	 * consumes a lot of space, especially when so few things
+	 * wait on pages at a given time. So instead of using
+	 * per-page waitqueues, we use a waitqueue hash table.
+	 *
+	 * The bucket discipline is to sleep on the same queue when
+	 * colliding and wake all in that wait queue when removing.
+	 * When something wakes, it must check to be sure its page is
+	 * truly available, a la thundering herd. The cost of a
+	 * collision is great, but given the expected load of the
+	 * table, they should be so rare as to be outweighed by the
+	 * benefits from the saved space.
+	 *
+	 * __wait_on_page() and unlock_page() in mm/filemap.c, are the
+	 * primary users of these fields, and in mm/page_alloc.c
+	 * free_area_init_core() performs the initialization of them.
+	 */
+	wait_queue_head_t	* wait_table;
+	unsigned long		wait_table_size;
+	unsigned long		wait_table_shift;
+
+	/*
 	 * Discontig memory support fields.
 	 */
 	struct pglist_data	*zone_pgdat;
@@ -132,11 +162,15 @@
 
 #define NODE_DATA(nid)		(&contig_page_data)
 #define NODE_MEM_MAP(nid)	mem_map
+#define MAX_NR_NODES		1
 
 #else /* !CONFIG_DISCONTIGMEM */
 
 #include <asm/mmzone.h>
 
+/* page->zone is currently 8 bits ... */
+#define MAX_NR_NODES		(255 / MAX_NR_ZONES)
+
 #endif /* !CONFIG_DISCONTIGMEM */
 
 #define MAP_ALIGN(x)	((((x) % sizeof(mem_map_t)) == 0) ? (x) : ((x) + \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/mtd/compatmac.h linux/include/linux/mtd/compatmac.h
--- linux.orig/include/linux/mtd/compatmac.h	2000-12-11 21:16:42.000000000 +0000
+++ linux/include/linux/mtd/compatmac.h	2002-07-20 01:08:31.000000000 +0000
@@ -190,8 +190,8 @@
 
 #if LINUX_VERSION_CODE < 0x20300
 #include <linux/interrupt.h>
-#define spin_lock_bh(lock) do {start_bh_atomic();spin_lock(lock);}while(0);
-#define spin_unlock_bh(lock) do {spin_unlock(lock);end_bh_atomic();}while(0);
+#define spin_lock_bh(lock) do {start_bh_atomic();spin_lock(lock);} while(0)
+#define spin_unlock_bh(lock) do {spin_unlock(lock);end_bh_atomic();} while(0)
 #else
 #include <asm/softirq.h>
 #include <linux/spinlock.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/mtd/concat.h linux/include/linux/mtd/concat.h
--- linux.orig/include/linux/mtd/concat.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/mtd/concat.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,23 @@
+/*
+ * MTD device concatenation layer definitions
+ *
+ * (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
+ *
+ * This code is GPL
+ *
+ * $Id: concat.h,v 1.1 2002/03/08 16:34:36 rkaiser Exp $
+ */
+
+#ifndef MTD_CONCAT_H
+#define MTD_CONCAT_H
+
+
+struct mtd_info *mtd_concat_create(
+    struct mtd_info *subdev[],  /* subdevices to concatenate */
+    int num_devs,               /* number of subdevices      */
+    char *name);                /* name for the new device   */
+
+void mtd_concat_destroy(struct mtd_info *mtd);
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/mtd/partitions.h linux/include/linux/mtd/partitions.h
--- linux.orig/include/linux/mtd/partitions.h	2001-06-12 17:30:27.000000000 +0000
+++ linux/include/linux/mtd/partitions.h	2002-07-20 01:08:40.000000000 +0000
@@ -5,7 +5,7 @@
  *
  * This code is GPL
  *
- * $Id: partitions.h,v 1.6 2001/03/17 17:10:21 dwmw2 Exp $
+ * $Id: partitions.h,v 1.8 2002/03/08 16:34:36 rkaiser Exp $
  */
 
 #ifndef MTD_PARTITIONS_H
@@ -26,14 +26,14 @@
  * 	will extend to the end of the master MTD device.
  * offset: absolute starting position within the master MTD device; if 
  * 	defined as MTDPART_OFS_APPEND, the partition will start where the 
- * 	previous one ended.
+ * 	previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
  * mask_flags: contains flags that have to be masked (removed) from the 
  * 	master MTD flag set for the corresponding MTD partition.
  * 	For example, to force a read-only partition, simply adding 
  * 	MTD_WRITEABLE to the mask_flags will do the trick.
  *
  * Note: writeable partitions require their size and offset be 
- * erasesize aligned.
+ * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
  */ 
 
 struct mtd_partition {
@@ -41,8 +41,10 @@
 	u_int32_t size;		/* partition size */
 	u_int32_t offset;		/* offset within the master MTD space */
 	u_int32_t mask_flags;	/* master MTD flags to mask out for this partition */
+	struct mtd_info **mtdp;	/* pointer to store the MTD object */
 };
 
+#define MTDPART_OFS_NXTBLK	(-2)
 #define MTDPART_OFS_APPEND	(-1)
 #define MTDPART_SIZ_FULL	(0)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/namespace.h linux/include/linux/namespace.h
--- linux.orig/include/linux/namespace.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/namespace.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,42 @@
+#ifndef _NAMESPACE_H_
+#define _NAMESPACE_H_
+#ifdef __KERNEL__
+
+struct namespace {
+	atomic_t		count;
+	struct vfsmount *	root;
+	struct list_head	list;
+	struct rw_semaphore	sem;
+};
+
+static inline void put_namespace(struct namespace *namespace)
+{
+	if (atomic_dec_and_test(&namespace->count)) {
+		down_write(&namespace->sem);
+		spin_lock(&dcache_lock);
+		umount_tree(namespace->root);
+		spin_unlock(&dcache_lock);
+		up_write(&namespace->sem);
+		kfree(namespace);
+	}
+}
+
+static inline void exit_namespace(struct task_struct *p)
+{
+	struct namespace *namespace = p->namespace;
+	if (namespace) {
+		task_lock(p);
+		p->namespace = NULL;
+		task_unlock(p);
+		put_namespace(namespace);
+	}
+}
+extern int copy_namespace(int, struct task_struct *);
+
+static inline void get_namespace(struct namespace *namespace)
+{
+	atomic_inc(&namespace->count);
+}
+
+#endif
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/nbd.h linux/include/linux/nbd.h
--- linux.orig/include/linux/nbd.h	2001-10-16 02:29:05.000000000 +0000
+++ linux/include/linux/nbd.h	2002-07-20 01:08:39.000000000 +0000
@@ -68,8 +68,9 @@
 	struct socket * sock;
 	struct file * file; 		/* If == NULL, device is not ready, yet	*/
 	int magic;			/* FIXME: not if debugging is off	*/
+	spinlock_t queue_lock;
 	struct list_head queue_head;	/* Requests are added here...			*/
-	struct semaphore queue_lock;
+	struct semaphore tx_lock;
 };
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/netdevice.h linux/include/linux/netdevice.h
--- linux.orig/include/linux/netdevice.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/netdevice.h	2002-07-20 01:08:33.000000000 +0000
@@ -40,6 +40,7 @@
 #endif
 
 struct divert_blk;
+struct vlan_group;
 
 #define HAVE_ALLOC_NETDEV		/* feature macro: alloc_xxxdev
 					   functions are available. */
@@ -278,6 +279,10 @@
 	struct net_device_stats* (*get_stats)(struct net_device *dev);
 	struct iw_statistics*	(*get_wireless_stats)(struct net_device *dev);
 
+	/* List of functions to handle Wireless Extensions (instead of ioctl).
+	 * See <net/iw_handler.h> for details. Jean II */
+	struct iw_handler_def *	wireless_handlers;
+
 	/*
 	 * This marks the end of the "visible" part of the structure. All
 	 * fields hereafter are internal to the system, and may change at
@@ -353,6 +358,10 @@
 #define NETIF_F_DYNALLOC	16	/* Self-dectructable device. */
 #define NETIF_F_HIGHDMA		32	/* Can DMA to high memory. */
 #define NETIF_F_FRAGLIST	64	/* Scatter/gather IO. */
+#define NETIF_F_HW_VLAN_TX	128	/* Transmit VLAN hw acceleration */
+#define NETIF_F_HW_VLAN_RX	256	/* Receive VLAN hw acceleration */
+#define NETIF_F_HW_VLAN_FILTER	512	/* Receive filtering on VLAN */
+#define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
 
 	/* Called after device is detached from network. */
 	void			(*uninit)(struct net_device *dev);
@@ -394,6 +403,13 @@
 #define HAVE_TX_TIMEOUT
 	void			(*tx_timeout) (struct net_device *dev);
 
+	void			(*vlan_rx_register)(struct net_device *dev,
+						    struct vlan_group *grp);
+	void			(*vlan_rx_add_vid)(struct net_device *dev,
+						   unsigned short vid);
+	void			(*vlan_rx_kill_vid)(struct net_device *dev,
+						    unsigned short vid);
+
 	int			(*hard_header_parse)(struct sk_buff *skb,
 						     unsigned char *haddr);
 	int			(*neigh_setup)(struct net_device *dev, struct neigh_parms *);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/netfilter_arp/arp_tables.h linux/include/linux/netfilter_arp/arp_tables.h
--- linux.orig/include/linux/netfilter_arp/arp_tables.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/netfilter_arp/arp_tables.h	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,342 @@
+/*
+ * 	Format of an ARP firewall descriptor
+ *
+ * 	src, tgt, src_mask, tgt_mask, arpop, arpop_mask are always stored in
+ *	network byte order.
+ * 	flags are stored in host byte order (of course).
+ */
+
+#ifndef _ARPTABLES_H
+#define _ARPTABLES_H
+
+#ifdef __KERNEL__
+#include <linux/if.h>
+#include <linux/types.h>
+#include <linux/in.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#endif
+
+#include <linux/netfilter_arp.h>
+
+#define ARPT_FUNCTION_MAXNAMELEN 30
+#define ARPT_TABLE_MAXNAMELEN 32
+
+#define ARPT_DEV_ADDR_LEN_MAX 16
+
+struct arpt_devaddr_info {
+	char addr[ARPT_DEV_ADDR_LEN_MAX];
+	char mask[ARPT_DEV_ADDR_LEN_MAX];
+};
+
+/* Yes, Virginia, you have to zero the padding. */
+struct arpt_arp {
+	/* Source and target IP addr */
+	struct in_addr src, tgt;
+	/* Mask for src and target IP addr */
+	struct in_addr smsk, tmsk;
+
+	/* Device hw address length, src+target device addresses */
+	u_int8_t arhln, arhln_mask;
+	struct arpt_devaddr_info src_devaddr;
+	struct arpt_devaddr_info tgt_devaddr;
+
+	/* ARP operation code. */
+	u_int16_t arpop, arpop_mask;
+
+	/* ARP hardware address and protocol address format. */
+	u_int16_t arhrd, arhrd_mask;
+	u_int16_t arpro, arpro_mask;
+
+	/* The protocol address length is only accepted if it is 4
+	 * so there is no use in offering a way to do filtering on it.
+	 */
+
+	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+	/* Flags word */
+	u_int8_t flags;
+	/* Inverse flags */
+	u_int16_t invflags;
+};
+
+struct arpt_entry_target
+{
+	union {
+		struct {
+			u_int16_t target_size;
+
+			/* Used by userspace */
+			char name[ARPT_FUNCTION_MAXNAMELEN];
+		} user;
+		struct {
+			u_int16_t target_size;
+
+			/* Used inside the kernel */
+			struct arpt_target *target;
+		} kernel;
+
+		/* Total length */
+		u_int16_t target_size;
+	} u;
+
+	unsigned char data[0];
+};
+
+struct arpt_standard_target
+{
+	struct arpt_entry_target target;
+	int verdict;
+};
+
+struct arpt_counters
+{
+	u_int64_t pcnt, bcnt;			/* Packet and byte counters */
+};
+
+/* Values for "flag" field in struct arpt_ip (general arp structure).
+ * No flags defined yet.
+ */
+#define ARPT_F_MASK		0x00	/* All possible flag bits mask. */
+
+/* Values for "inv" field in struct arpt_arp. */
+#define ARPT_INV_VIA_IN		0x0001	/* Invert the sense of IN IFACE. */
+#define ARPT_INV_VIA_OUT	0x0002	/* Invert the sense of OUT IFACE */
+#define ARPT_INV_SRCIP		0x0004	/* Invert the sense of SRC IP. */
+#define ARPT_INV_TGTIP		0x0008	/* Invert the sense of TGT IP. */
+#define ARPT_INV_SRCDEVADDR	0x0010	/* Invert the sense of SRC DEV ADDR. */
+#define ARPT_INV_TGTDEVADDR	0x0020	/* Invert the sense of TGT DEV ADDR. */
+#define ARPT_INV_ARPOP		0x0040	/* Invert the sense of ARP OP. */
+#define ARPT_INV_ARPHRD		0x0080	/* Invert the sense of ARP HRD. */
+#define ARPT_INV_ARPPRO		0x0100	/* Invert the sense of ARP PRO. */
+#define ARPT_INV_ARPHLN		0x0200	/* Invert the sense of ARP HLN. */
+#define ARPT_INV_MASK		0x007F	/* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules.  Consists of 3
+   parts which are 1) general ARP header stuff 2) match specific
+   stuff 3) the target to perform if the rule matches */
+struct arpt_entry
+{
+	struct arpt_arp arp;
+
+	/* Size of arpt_entry + matches */
+	u_int16_t target_offset;
+	/* Size of arpt_entry + matches + target */
+	u_int16_t next_offset;
+
+	/* Back pointer */
+	unsigned int comefrom;
+
+	/* Packet and byte counters. */
+	struct arpt_counters counters;
+
+	/* The matches (if any), then the target. */
+	unsigned char elems[0];
+};
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use a raw
+ * socket for this. Instead we check rights in the calls.
+ */
+#define ARPT_BASE_CTL		96	/* base for firewall socket options */
+
+#define ARPT_SO_SET_REPLACE		(ARPT_BASE_CTL)
+#define ARPT_SO_SET_ADD_COUNTERS	(ARPT_BASE_CTL + 1)
+#define ARPT_SO_SET_MAX			ARPT_SO_SET_ADD_COUNTERS
+
+#define ARPT_SO_GET_INFO		(ARPT_BASE_CTL)
+#define ARPT_SO_GET_ENTRIES		(ARPT_BASE_CTL + 1)
+#define ARPT_SO_GET_MAX			ARPT_SO_GET_ENTRIES
+
+/* CONTINUE verdict for targets */
+#define ARPT_CONTINUE 0xFFFFFFFF
+
+/* For standard target */
+#define ARPT_RETURN (-NF_MAX_VERDICT - 1)
+
+/* The argument to ARPT_SO_GET_INFO */
+struct arpt_getinfo
+{
+	/* Which table: caller fills this in. */
+	char name[ARPT_TABLE_MAXNAMELEN];
+
+	/* Kernel fills these in. */
+	/* Which hook entry points are valid: bitmask */
+	unsigned int valid_hooks;
+
+	/* Hook entry points: one per netfilter hook. */
+	unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_ARP_NUMHOOKS];
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Size of entries. */
+	unsigned int size;
+};
+
+/* The argument to ARPT_SO_SET_REPLACE. */
+struct arpt_replace
+{
+	/* Which table. */
+	char name[ARPT_TABLE_MAXNAMELEN];
+
+	/* Which hook entry points are valid: bitmask.  You can't
+           change this. */
+	unsigned int valid_hooks;
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Total size of new entries */
+	unsigned int size;
+
+	/* Hook entry points. */
+	unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_ARP_NUMHOOKS];
+
+	/* Information about old entries: */
+	/* Number of counters (must be equal to current number of entries). */
+	unsigned int num_counters;
+	/* The old entries' counters. */
+	struct arpt_counters *counters;
+
+	/* The entries (hang off end: not really an array). */
+	struct arpt_entry entries[0];
+};
+
+/* The argument to ARPT_SO_ADD_COUNTERS. */
+struct arpt_counters_info
+{
+	/* Which table. */
+	char name[ARPT_TABLE_MAXNAMELEN];
+
+	unsigned int num_counters;
+
+	/* The counters (actually `number' of these). */
+	struct arpt_counters counters[0];
+};
+
+/* The argument to ARPT_SO_GET_ENTRIES. */
+struct arpt_get_entries
+{
+	/* Which table: user fills this in. */
+	char name[ARPT_TABLE_MAXNAMELEN];
+
+	/* User fills this in: total entry size. */
+	unsigned int size;
+
+	/* The entries. */
+	struct arpt_entry entrytable[0];
+};
+
+/* Standard return verdict, or do jump. */
+#define ARPT_STANDARD_TARGET ""
+/* Error verdict. */
+#define ARPT_ERROR_TARGET "ERROR"
+
+/* Helper functions */
+static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e)
+{
+	return (void *)e + e->target_offset;
+}
+
+/* fn returns 0 to continue iteration */
+#define ARPT_ENTRY_ITERATE(entries, size, fn, args...)		\
+({								\
+	unsigned int __i;					\
+	int __ret = 0;						\
+	struct arpt_entry *__entry;				\
+								\
+	for (__i = 0; __i < (size); __i += __entry->next_offset) { \
+		__entry = (void *)(entries) + __i;		\
+								\
+		__ret = fn(__entry , ## args);			\
+		if (__ret != 0)					\
+			break;					\
+	}							\
+	__ret;							\
+})
+
+/*
+ *	Main firewall chains definitions and global var's definitions.
+ */
+#ifdef __KERNEL__
+
+/* Registration hooks for targets. */
+struct arpt_target
+{
+	struct list_head list;
+
+	const char name[ARPT_FUNCTION_MAXNAMELEN];
+
+	/* Returns verdict. */
+	unsigned int (*target)(struct sk_buff **pskb,
+			       unsigned int hooknum,
+			       const struct net_device *in,
+			       const struct net_device *out,
+			       const void *targinfo,
+			       void *userdata);
+
+	/* Called when user tries to insert an entry of this type:
+           hook_mask is a bitmask of hooks from which it can be
+           called. */
+	/* Should return true or false. */
+	int (*checkentry)(const char *tablename,
+			  const struct arpt_entry *e,
+			  void *targinfo,
+			  unsigned int targinfosize,
+			  unsigned int hook_mask);
+
+	/* Called when entry of this type deleted. */
+	void (*destroy)(void *targinfo, unsigned int targinfosize);
+
+	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
+	struct module *me;
+};
+
+extern int arpt_register_target(struct arpt_target *target);
+extern void arpt_unregister_target(struct arpt_target *target);
+
+/* Furniture shopping... */
+struct arpt_table
+{
+	struct list_head list;
+
+	/* A unique name... */
+	char name[ARPT_TABLE_MAXNAMELEN];
+
+	/* Seed table: copied in register_table */
+	struct arpt_replace *table;
+
+	/* What hooks you will enter on */
+	unsigned int valid_hooks;
+
+	/* Lock for the curtain */
+	rwlock_t lock;
+
+	/* Man behind the curtain... */
+	struct arpt_table_info *private;
+
+	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
+	struct module *me;
+};
+
+extern int arpt_register_table(struct arpt_table *table);
+extern void arpt_unregister_table(struct arpt_table *table);
+extern unsigned int arpt_do_table(struct sk_buff **pskb,
+				  unsigned int hook,
+				  const struct net_device *in,
+				  const struct net_device *out,
+				  struct arpt_table *table,
+				  void *userdata);
+
+#define ARPT_ALIGN(s) (((s) + (__alignof__(struct arpt_entry)-1)) & ~(__alignof__(struct arpt_entry)-1))
+#endif /*__KERNEL__*/
+#endif /* _ARPTABLES_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/netfilter_arp.h linux/include/linux/netfilter_arp.h
--- linux.orig/include/linux/netfilter_arp.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/netfilter_arp.h	2002-07-20 01:08:38.000000000 +0000
@@ -0,0 +1,19 @@
+#ifndef __LINUX_ARP_NETFILTER_H
+#define __LINUX_ARP_NETFILTER_H
+
+/* ARP-specific defines for netfilter.
+ * (C)2002 Rusty Russell IBM -- This code is GPL.
+ */
+
+#include <linux/config.h>
+#include <linux/netfilter.h>
+
+/* There is no PF_ARP. */
+#define NF_ARP		0
+
+/* ARP Hooks */
+#define NF_ARP_IN	0
+#define NF_ARP_OUT	1
+#define NF_ARP_NUMHOOKS	2
+
+#endif /* __LINUX_ARP_NETFILTER_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/netfilter_ipv4/ip_conntrack.h linux/include/linux/netfilter_ipv4/ip_conntrack.h
--- linux.orig/include/linux/netfilter_ipv4/ip_conntrack.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/netfilter_ipv4/ip_conntrack.h	2002-07-20 01:08:33.000000000 +0000
@@ -82,10 +82,7 @@
 #endif
 
 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
-
-#if defined(CONFIG_IP_NF_IRC) || defined(CONFIG_IP_NF_IRC_MODULE)
 #include <linux/netfilter_ipv4/ip_conntrack_irc.h>
-#endif
 
 struct ip_conntrack
 {
@@ -125,9 +122,7 @@
 
 	union {
 		struct ip_ct_ftp ct_ftp_info;
-#if defined(CONFIG_IP_NF_IRC) || defined(CONFIG_IP_NF_IRC_MODULE)
 		struct ip_ct_irc ct_irc_info;
-#endif
 	} help;
 
 #ifdef CONFIG_IP_NF_NAT_NEEDED
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/netfilter_ipv4/ip_conntrack_protocol.h linux/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
--- linux.orig/include/linux/netfilter_ipv4/ip_conntrack_protocol.h	2001-04-27 21:15:01.000000000 +0000
+++ linux/include/linux/netfilter_ipv4/ip_conntrack_protocol.h	2002-07-20 01:08:40.000000000 +0000
@@ -42,6 +42,9 @@
 	int (*new)(struct ip_conntrack *conntrack, struct iphdr *iph,
 		   size_t len);
 
+	/* Called when a conntrack entry is destroyed */
+	void (*destroy)(struct ip_conntrack *conntrack);
+
 	/* Module (if any) which this is connected to. */
 	struct module *me;
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/netfilter_ipv4/ip_nat.h linux/include/linux/netfilter_ipv4/ip_nat.h
--- linux.orig/include/linux/netfilter_ipv4/ip_nat.h	2001-04-25 22:00:28.000000000 +0000
+++ linux/include/linux/netfilter_ipv4/ip_nat.h	2002-07-20 01:08:35.000000000 +0000
@@ -11,8 +11,13 @@
 	IP_NAT_MANIP_DST
 };
 
+#ifndef CONFIG_IP_NF_NAT_LOCAL
 /* SRC manip occurs only on POST_ROUTING */
 #define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING)
+#else
+/* SRC manip occurs POST_ROUTING or LOCAL_IN */
+#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
+#endif
 
 /* 2.3.19 (I hope) will define this in linux/netfilter_ipv4.h. */
 #ifndef SO_ORIGINAL_DST
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/nfs_flushd.h linux/include/linux/nfs_flushd.h
--- linux.orig/include/linux/nfs_flushd.h	2001-11-22 19:47:41.000000000 +0000
+++ linux/include/linux/nfs_flushd.h	2002-07-20 01:08:40.000000000 +0000
@@ -32,7 +32,6 @@
  */
 extern int		nfs_reqlist_alloc(struct nfs_server *);
 extern void		nfs_reqlist_free(struct nfs_server *);
-extern int		nfs_reqlist_init(struct nfs_server *);
 extern void		nfs_reqlist_exit(struct nfs_server *);
 extern void		nfs_wake_flushd(void);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- linux.orig/include/linux/nfs_fs.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/linux/nfs_fs.h	2002-07-20 01:08:32.000000000 +0000
@@ -78,6 +78,7 @@
 #define NFS_CONGESTED(inode)		(RPC_CONGESTED(NFS_CLIENT(inode)))
 #define NFS_COOKIEVERF(inode)		((inode)->u.nfs_i.cookieverf)
 #define NFS_READTIME(inode)		((inode)->u.nfs_i.read_cache_jiffies)
+#define NFS_MTIME_UPDATE(inode)		((inode)->u.nfs_i.cache_mtime_jiffies)
 #define NFS_CACHE_CTIME(inode)		((inode)->u.nfs_i.read_cache_ctime)
 #define NFS_CACHE_MTIME(inode)		((inode)->u.nfs_i.read_cache_mtime)
 #define NFS_CACHE_ISIZE(inode)		((inode)->u.nfs_i.read_cache_isize)
@@ -100,7 +101,6 @@
 #define NFS_STALE(inode)		(NFS_FLAGS(inode) & NFS_INO_STALE)
 
 #define NFS_FILEID(inode)		((inode)->u.nfs_i.fileid)
-#define NFS_FSID(inode)			((inode)->u.nfs_i.fsid)
 
 /* Inode Flags */
 #define NFS_USE_READDIRPLUS(inode)	((NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS) ? 1 : 0)
@@ -153,6 +153,7 @@
 extern int nfs_open(struct inode *, struct file *);
 extern int nfs_release(struct inode *, struct file *);
 extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
+extern int nfs_check_stale(struct inode *);
 extern int nfs_notify_change(struct dentry *, struct iattr *);
 
 /*
@@ -165,10 +166,12 @@
 static __inline__ struct rpc_cred *
 nfs_file_cred(struct file *file)
 {
-	struct rpc_cred *cred = (struct rpc_cred *)(file->private_data);
+	struct rpc_cred *cred = NULL;
+	if (file)
+		cred = (struct rpc_cred *)file->private_data;
 #ifdef RPC_DEBUG
 	if (cred && cred->cr_magic != RPCAUTH_CRED_MAGIC)
-		BUG();
+		out_of_line_bug();
 #endif
 	return cred;
 }
@@ -273,6 +276,9 @@
 extern int  nfs_mount(struct sockaddr_in *, char *, struct nfs_fh *);
 extern int  nfs3_mount(struct sockaddr_in *, char *, struct nfs_fh *);
 
+/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
+extern u32 root_nfs_parse_addr(char *name); /*__init*/
+
 /*
  * inline functions
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/nfs_fs_i.h linux/include/linux/nfs_fs_i.h
--- linux.orig/include/linux/nfs_fs_i.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/nfs_fs_i.h	2002-07-20 01:08:32.000000000 +0000
@@ -12,7 +12,6 @@
 	/*
 	 * The 64bit 'inode number'
 	 */
-	__u64 fsid;
 	__u64 fileid;
 
 	/*
@@ -50,6 +49,12 @@
 	unsigned long		attrtimeo_timestamp;
 
 	/*
+	 * Timestamp that dates the change made to read_cache_mtime.
+	 * This is of use for dentry revalidation
+	 */
+	unsigned long		cache_mtime_jiffies;
+
+	/*
 	 * This is the cookie verifier used for NFSv3 readdir
 	 * operations
 	 */
@@ -68,11 +73,6 @@
 				ncommit,
 				npages;
 
-	/* Flush daemon info */
-	struct inode		*hash_next,
-				*hash_prev;
-	unsigned long		nextscan;
-
 	/* Credentials for shared mmap */
 	struct rpc_cred		*mm_cred;
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/nfs_page.h linux/include/linux/nfs_page.h
--- linux.orig/include/linux/nfs_page.h	2001-11-22 19:47:41.000000000 +0000
+++ linux/include/linux/nfs_page.h	2002-07-20 01:08:25.000000000 +0000
@@ -41,9 +41,10 @@
 
 #define NFS_WBACK_BUSY(req)	(test_bit(PG_BUSY,&(req)->wb_flags))
 
-extern	struct nfs_page *nfs_create_request(struct file *, struct inode *,
+extern	struct nfs_page *nfs_create_request(struct rpc_cred *, struct inode *,
 					    struct page *,
 					    unsigned int, unsigned int);
+extern	void nfs_clear_request(struct nfs_page *req);
 extern	void nfs_release_request(struct nfs_page *req);
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/nfsd/export.h linux/include/linux/nfsd/export.h
--- linux.orig/include/linux/nfsd/export.h	2001-11-22 19:47:20.000000000 +0000
+++ linux/include/linux/nfsd/export.h	2002-07-20 01:08:21.000000000 +0000
@@ -54,11 +54,13 @@
 	int			cl_naddr;
 	struct in_addr		cl_addr[NFSCLNT_ADDRMAX];
 	struct svc_uidmap *	cl_umap;
-	struct svc_export *	cl_export[NFSCLNT_EXPMAX];
+	struct list_head	cl_export[NFSCLNT_EXPMAX];
+	struct list_head	cl_list;
 };
 
 struct svc_export {
-	struct svc_export *	ex_next;
+	struct list_head	ex_hash;
+	struct list_head	ex_list;
 	char			ex_path[NFS_MAXPATHLEN+1];
 	struct svc_export *	ex_parent;
 	struct svc_client *	ex_client;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/nfsd/interface.h linux/include/linux/nfsd/interface.h
--- linux.orig/include/linux/nfsd/interface.h	2001-10-04 05:57:36.000000000 +0000
+++ linux/include/linux/nfsd/interface.h	2002-07-20 01:08:35.000000000 +0000
@@ -12,12 +12,15 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_NFSD_MODULE
+#ifndef CONFIG_NFSD
+# ifdef CONFIG_MODULES
 
 extern struct nfsd_linkage {
 	long (*do_nfsservctl)(int cmd, void *argp, void *resp);
+	struct module *owner;
 } * nfsd_linkage;
 
+# endif
 #endif
 
 #endif /* LINUX_NFSD_INTERFACE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/nls.h linux/include/linux/nls.h
--- linux.orig/include/linux/nls.h	2001-11-22 19:47:11.000000000 +0000
+++ linux/include/linux/nls.h	2002-07-20 01:08:31.000000000 +0000
@@ -18,7 +18,7 @@
 };
 
 /* this value hold the maximum octet of charset */
-#define NLS_MAX_CHARSET_SIZE 3
+#define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */
 
 /* nls.c */
 extern int register_nls(struct nls_table *);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/parport.h linux/include/linux/parport.h
--- linux.orig/include/linux/parport.h	2001-11-14 22:52:47.000000000 +0000
+++ linux/include/linux/parport.h	2002-07-20 01:08:33.000000000 +0000
@@ -458,7 +458,10 @@
 extern int parport_negotiate (struct parport *, int mode);
 extern ssize_t parport_write (struct parport *, const void *buf, size_t len);
 extern ssize_t parport_read (struct parport *, void *buf, size_t len);
+
+#define PARPORT_INACTIVITY_O_NONBLOCK 1
 extern long parport_set_timeout (struct pardevice *, long inactivity);
+
 extern int parport_wait_event (struct parport *, long timeout);
 extern int parport_wait_peripheral (struct parport *port,
 				    unsigned char mask,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/pci.h linux/include/linux/pci.h
--- linux.orig/include/linux/pci.h	2001-11-22 19:46:30.000000000 +0000
+++ linux/include/linux/pci.h	2002-07-20 01:08:36.000000000 +0000
@@ -376,7 +376,7 @@
 	struct resource dma_resource[DEVICE_COUNT_DMA];
 	struct resource irq_resource[DEVICE_COUNT_IRQ];
 
-	char		name[80];	/* device name */
+	char		name[90];	/* device name */
 	char		slot_name[8];	/* slot name */
 	int		active;		/* ISAPnP: device is active */
 	int		ro;		/* ISAPnP: read only */
@@ -479,7 +479,7 @@
 	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
 	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
 	int  (*save_state) (struct pci_dev *dev, u32 state);    /* Save Device Context */
-	int  (*suspend)(struct pci_dev *dev, u32 state);	/* Device suspended */
+	int  (*suspend) (struct pci_dev *dev, u32 state);	/* Device suspended */
 	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */
 	int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);   /* Enable wake event */
 };
@@ -561,6 +561,10 @@
 int pci_enable_device(struct pci_dev *dev);
 void pci_disable_device(struct pci_dev *dev);
 void pci_set_master(struct pci_dev *dev);
+#define HAVE_PCI_SET_MWI
+int pci_set_mwi(struct pci_dev *dev);
+void pci_clear_mwi(struct pci_dev *dev);
+int pdev_set_mwi(struct pci_dev *dev);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_assign_resource(struct pci_dev *dev, int i);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- linux.orig/include/linux/pci_ids.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/pci_ids.h	2002-07-20 01:08:34.000000000 +0000
@@ -133,6 +133,7 @@
 #define PCI_DEVICE_ID_COMPAQ_1280	0x3033
 #define PCI_DEVICE_ID_COMPAQ_TRIFLEX	0x4000
 #define PCI_DEVICE_ID_COMPAQ_6010	0x6010
+#define PCI_DEVICE_ID_COMPAQ_TACHYON	0xa0fc
 #define PCI_DEVICE_ID_COMPAQ_SMART2P	0xae10
 #define PCI_DEVICE_ID_COMPAQ_NETEL100	0xae32
 #define PCI_DEVICE_ID_COMPAQ_NETEL10	0xae34
@@ -346,6 +347,8 @@
 #define PCI_DEVICE_ID_IBM_MPIC		0x0046
 #define PCI_DEVICE_ID_IBM_3780IDSP	0x007d
 #define PCI_DEVICE_ID_IBM_CHUKAR	0x0096
+#define PCI_DEVICE_ID_IBM_CPC710_PCI64	0x00fc
+#define PCI_DEVICE_ID_IBM_CPC710_PCI32	0x0105
 #define	PCI_DEVICE_ID_IBM_405GP		0x0156
 #define PCI_DEVICE_ID_IBM_SERVERAIDI960	0x01bd
 #define PCI_DEVICE_ID_IBM_MPIC_2	0xffff
@@ -443,6 +446,7 @@
 #define PCI_DEVICE_ID_NEC_PCX2		0x0046
 #define PCI_DEVICE_ID_NEC_NILE4		0x005a
 #define PCI_DEVICE_ID_NEC_VRC5476       0x009b
+#define PCI_DEVICE_ID_NEC_VRC5477_AC97  0x00a6
 
 #define PCI_VENDOR_ID_FD		0x1036
 #define PCI_DEVICE_ID_FD_36C70		0x0000
@@ -505,6 +509,9 @@
 #define PCI_DEVICE_ID_HP_DIVA1		0x1049
 #define PCI_DEVICE_ID_HP_DIVA2		0x104A
 #define PCI_DEVICE_ID_HP_SP2_0		0x104B
+#define PCI_DEVICE_ID_HP_ZX1_SBA	0x1229
+#define PCI_DEVICE_ID_HP_ZX1_IOC	0x122a
+#define PCI_DEVICE_ID_HP_ZX1_LBA	0x122e
 
 #define PCI_VENDOR_ID_PCTECH		0x1042
 #define PCI_DEVICE_ID_PCTECH_RZ1000	0x1000
@@ -535,10 +542,6 @@
 #define PCI_DEVICE_ID_ELSA_MICROLINK	0x1000
 #define PCI_DEVICE_ID_ELSA_QS3000	0x3000
 
-#define PCI_VENDOR_ID_ELSA		0x1048
-#define PCI_DEVICE_ID_ELSA_MICROLINK	0x1000
-#define PCI_DEVICE_ID_ELSA_QS3000	0x3000
-
 #define PCI_VENDOR_ID_SGS		0x104a
 #define PCI_DEVICE_ID_SGS_2000		0x0008
 #define PCI_DEVICE_ID_SGS_1764		0x0009
@@ -595,6 +598,7 @@
 #define PCI_DEVICE_ID_MOTOROLA_MPC106	0x0002
 #define PCI_DEVICE_ID_MOTOROLA_RAVEN	0x4801
 #define PCI_DEVICE_ID_MOTOROLA_FALCON	0x4802
+#define PCI_DEVICE_ID_MOTOROLA_HAWK	0x4803
 #define PCI_DEVICE_ID_MOTOROLA_CPX8216	0x4806
 
 #define PCI_VENDOR_ID_PROMISE		0x105a
@@ -602,10 +606,14 @@
 #define PCI_DEVICE_ID_PROMISE_20267	0x4d30
 #define PCI_DEVICE_ID_PROMISE_20246	0x4d33
 #define PCI_DEVICE_ID_PROMISE_20262	0x4d38
+#define PCI_DEVICE_ID_PROMISE_20263	0x0D38
 #define PCI_DEVICE_ID_PROMISE_20268	0x4d68
-#define PCI_DEVICE_ID_PROMISE_20268R	0x6268
+#define PCI_DEVICE_ID_PROMISE_20270	0x6268
 #define PCI_DEVICE_ID_PROMISE_20269	0x4d69
+#define PCI_DEVICE_ID_PROMISE_20271	0x6269
 #define PCI_DEVICE_ID_PROMISE_20275	0x1275
+#define PCI_DEVICE_ID_PROMISE_20276	0x5275
+#define PCI_DEVICE_ID_PROMISE_20277	0x7275
 #define PCI_DEVICE_ID_PROMISE_5300	0x5300
 
 #define PCI_VENDOR_ID_N9		0x105d
@@ -807,6 +815,7 @@
 #define PCI_DEVICE_ID_AL_M1621          0x1621
 #define PCI_DEVICE_ID_AL_M1631          0x1631
 #define PCI_DEVICE_ID_AL_M1641          0x1641
+#define PCI_DEVICE_ID_AL_M1644          0x1644
 #define PCI_DEVICE_ID_AL_M1647          0x1647
 #define PCI_DEVICE_ID_AL_M1651          0x1651
 #define PCI_DEVICE_ID_AL_M1543		0x1543
@@ -923,6 +932,10 @@
 #define PCI_VENDOR_ID_TTI		0x1103
 #define PCI_DEVICE_ID_TTI_HPT343	0x0003
 #define PCI_DEVICE_ID_TTI_HPT366	0x0004
+#define PCI_DEVICE_ID_TTI_HPT372	0x0005
+#define PCI_DEVICE_ID_TTI_HPT302	0x0006
+#define PCI_DEVICE_ID_TTI_HPT371	0x0007
+#define PCI_DEVICE_ID_TTI_HPT374	0x0008
 
 #define PCI_VENDOR_ID_VIA		0x1106
 #define PCI_DEVICE_ID_VIA_8363_0	0x0305
@@ -959,11 +972,12 @@
 #define PCI_DEVICE_ID_VIA_8233_7	0x3065
 #define PCI_DEVICE_ID_VIA_82C686_6	0x3068
 #define PCI_DEVICE_ID_VIA_8233_0	0x3074
+#define PCI_DEVICE_ID_VIA_8633_0	0x3091
+#define PCI_DEVICE_ID_VIA_8367_0	0x3099
 #define PCI_DEVICE_ID_VIA_8622		0x3102
 #define PCI_DEVICE_ID_VIA_8233C_0	0x3109
 #define PCI_DEVICE_ID_VIA_8361		0x3112
-#define PCI_DEVICE_ID_VIA_8633_0	0x3091
-#define PCI_DEVICE_ID_VIA_8367_0	0x3099
+#define PCI_DEVICE_ID_VIA_8233A		0x3147
 #define PCI_DEVICE_ID_VIA_86C100A	0x6100
 #define PCI_DEVICE_ID_VIA_8231		0x8231
 #define PCI_DEVICE_ID_VIA_8231_4	0x8235
@@ -973,7 +987,7 @@
 #define PCI_DEVICE_ID_VIA_82C597_1	0x8597
 #define PCI_DEVICE_ID_VIA_82C598_1	0x8598
 #define PCI_DEVICE_ID_VIA_8601_1	0x8601
-#define PCI_DEVICE_ID_VIA_8505_1	0X8605
+#define PCI_DEVICE_ID_VIA_8505_1	0x8605
 #define PCI_DEVICE_ID_VIA_8633_1	0xB091
 #define PCI_DEVICE_ID_VIA_8367_1	0xB099
 
@@ -1094,12 +1108,18 @@
 #define PCI_DEVICE_ID_SERVERWORKS_LE	  0x0009
 #define PCI_DEVICE_ID_SERVERWORKS_CIOB30  0x0010
 #define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011
+#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4	  0x0200
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5	  0x0201
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6    0x0203
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221
+#define PCI_DEVICE_ID_SERVERWORKS_GCLE    0x0225
+#define PCI_DEVICE_ID_SERVERWORKS_GCLE2   0x0227
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
 
 #define PCI_VENDOR_ID_SBE		0x1176
@@ -1112,6 +1132,11 @@
 #define PCI_DEVICE_ID_TOSHIBA_TOPIC95	0x060a
 #define PCI_DEVICE_ID_TOSHIBA_TOPIC97	0x060f
 
+#define PCI_VENDOR_ID_TOSHIBA_2		0x102f
+#define PCI_DEVICE_ID_TOSHIBA_TX3927	0x000a
+#define PCI_DEVICE_ID_TOSHIBA_TC35815CF	0x0030
+#define PCI_DEVICE_ID_TOSHIBA_TX4927	0x0180
+
 #define PCI_VENDOR_ID_RICOH		0x1180
 #define PCI_DEVICE_ID_RICOH_RL5C465	0x0465
 #define PCI_DEVICE_ID_RICOH_RL5C466	0x0466
@@ -1287,13 +1312,9 @@
 #define PCI_VENDOR_ID_ITE		0x1283
 #define PCI_DEVICE_ID_ITE_IT8172G	0x8172
 #define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
-
-#define PCI_VENDOR_ID_ITE		0x1283
-#define PCI_DEVICE_ID_ITE_IT8172G	0x8172
-
-#define PCI_VENDOR_ID_ITE			0x1283
 #define PCI_DEVICE_ID_ITE_8872		0x8872
 
+#define PCI_DEVICE_ID_ITE_IT8330G_0    0xe886
 
 /* formerly Platform Tech */
 #define PCI_VENDOR_ID_ESS_OLD		0x1285
@@ -1458,6 +1479,8 @@
 #define PCI_DEVICE_ID_LAVA_DSERIAL	0x0100 /* 2x 16550 */
 #define PCI_DEVICE_ID_LAVA_QUATRO_A	0x0101 /* 2x 16550, half of 4 port */
 #define PCI_DEVICE_ID_LAVA_QUATRO_B	0x0102 /* 2x 16550, half of 4 port */
+#define PCI_DEVICE_ID_LAVA_OCTO_A	0x0180 /* 4x 16550A, half of 8 port */
+#define PCI_DEVICE_ID_LAVA_OCTO_B	0x0181 /* 4x 16550A, half of 8 port */
 #define PCI_DEVICE_ID_LAVA_PORT_PLUS	0x0200 /* 2x 16650 */
 #define PCI_DEVICE_ID_LAVA_QUAD_A	0x0201 /* 2x 16650, half of 4 port */
 #define PCI_DEVICE_ID_LAVA_QUAD_B	0x0202 /* 2x 16650, half of 4 port */
@@ -1474,9 +1497,9 @@
 #define PCI_VENDOR_ID_OXSEMI		0x1415
 #define PCI_DEVICE_ID_OXSEMI_12PCI840	0x8403
 #define PCI_DEVICE_ID_OXSEMI_16PCI954	0x9501
-#define PCI_DEVICE_ID_OXSEMI_16PCI952	0x950A
 #define PCI_DEVICE_ID_OXSEMI_16PCI95N	0x9511
 #define PCI_DEVICE_ID_OXSEMI_16PCI954PP	0x9513
+#define PCI_DEVICE_ID_OXSEMI_16PCI952	0x9521
 
 #define PCI_VENDOR_ID_AIRONET		0x14b9
 #define PCI_DEVICE_ID_AIRONET_4800_1	0x0001
@@ -1506,7 +1529,11 @@
 #define PCI_VENDOR_ID_BROADCOM		0x14e4
 #define PCI_DEVICE_ID_TIGON3_5700	0x1644
 #define PCI_DEVICE_ID_TIGON3_5701	0x1645
+#define PCI_DEVICE_ID_TIGON3_5702	0x1646
 #define PCI_DEVICE_ID_TIGON3_5703	0x1647
+#define PCI_DEVICE_ID_TIGON3_5702FE	0x164d
+#define PCI_DEVICE_ID_TIGON3_5702X	0x16a6
+#define PCI_DEVICE_ID_TIGON3_5703X	0x16a7
 
 #define PCI_VENDOR_ID_SYBA		0x1592
 #define PCI_DEVICE_ID_SYBA_2P_EPP	0x0782
@@ -1521,6 +1548,10 @@
 #define PCI_VENDOR_ID_PDC		0x15e9
 #define PCI_DEVICE_ID_PDC_1841		0x1841
 
+#define PCI_VENDOR_ID_ALTIMA		0x173b
+#define PCI_DEVICE_ID_ALTIMA_AC1000	0x03e8
+#define PCI_DEVICE_ID_ALTIMA_AC9100	0x03ea
+
 #define PCI_VENDOR_ID_SYMPHONY		0x1c1c
 #define PCI_DEVICE_ID_SYMPHONY_101	0x0001
 
@@ -1571,13 +1602,15 @@
 #define PCI_DEVICE_ID_S3_ViRGE_MXPMV	0x8c03
 #define PCI_DEVICE_ID_S3_SONICVIBES	0xca00
 
+#define PCI_VENDOR_ID_DUNORD		0x5544
+#define PCI_DEVICE_ID_DUNORD_I3000	0x0001
+#define PCI_VENDOR_ID_GENROCO		0x5555
+#define PCI_DEVICE_ID_GENROCO_HFP832	0x0003
+
 #define PCI_VENDOR_ID_DCI		0x6666
 #define PCI_DEVICE_ID_DCI_PCCOM4	0x0001
 #define PCI_DEVICE_ID_DCI_PCCOM8	0x0002
 
-#define PCI_VENDOR_ID_GENROCO		0x5555
-#define PCI_DEVICE_ID_GENROCO_HFP832	0x0003
-
 #define PCI_VENDOR_ID_INTEL		0x8086
 #define PCI_DEVICE_ID_INTEL_21145	0x0039
 #define PCI_DEVICE_ID_INTEL_82375	0x0482
@@ -1631,16 +1664,6 @@
 #define PCI_DEVICE_ID_INTEL_82801BA_2	0x2443
 #define PCI_DEVICE_ID_INTEL_82801BA_3	0x2444
 #define PCI_DEVICE_ID_INTEL_82801BA_4	0x2445
-#define PCI_DEVICE_ID_INTEL_82801CA_0	0x2480
-#define PCI_DEVICE_ID_INTEL_82801CA_2	0x2482
-#define PCI_DEVICE_ID_INTEL_82801CA_3	0x2483
-#define PCI_DEVICE_ID_INTEL_82801CA_4	0x2484
-#define PCI_DEVICE_ID_INTEL_82801CA_5	0x2485
-#define PCI_DEVICE_ID_INTEL_82801CA_6	0x2486
-#define PCI_DEVICE_ID_INTEL_82801CA_7	0x2487
-#define PCI_DEVICE_ID_INTEL_82801CA_10	0x248a
-#define PCI_DEVICE_ID_INTEL_82801CA_11	0x248b
-#define PCI_DEVICE_ID_INTEL_82801CA_12	0x248c
 #define PCI_DEVICE_ID_INTEL_82801BA_5	0x2446
 #define PCI_DEVICE_ID_INTEL_82801BA_6	0x2448
 #define PCI_DEVICE_ID_INTEL_82801BA_7	0x2449
@@ -1648,6 +1671,13 @@
 #define PCI_DEVICE_ID_INTEL_82801BA_9	0x244b
 #define PCI_DEVICE_ID_INTEL_82801BA_10	0x244c
 #define PCI_DEVICE_ID_INTEL_82801BA_11	0x244e
+#define PCI_DEVICE_ID_INTEL_82801E_0	0x2450
+#define PCI_DEVICE_ID_INTEL_82801E_2	0x2452
+#define PCI_DEVICE_ID_INTEL_82801E_3	0x2453
+#define PCI_DEVICE_ID_INTEL_82801E_9	0x2459
+#define PCI_DEVICE_ID_INTEL_82801E_11	0x245b
+#define PCI_DEVICE_ID_INTEL_82801E_13	0x245d
+#define PCI_DEVICE_ID_INTEL_82801E_14	0x245e
 #define PCI_DEVICE_ID_INTEL_82801CA_0	0x2480
 #define PCI_DEVICE_ID_INTEL_82801CA_2	0x2482
 #define PCI_DEVICE_ID_INTEL_82801CA_3	0x2483
@@ -1658,6 +1688,15 @@
 #define PCI_DEVICE_ID_INTEL_82801CA_10	0x248a
 #define PCI_DEVICE_ID_INTEL_82801CA_11	0x248b
 #define PCI_DEVICE_ID_INTEL_82801CA_12	0x248c
+#define PCI_DEVICE_ID_INTEL_82801DB_0	0x24c0
+#define PCI_DEVICE_ID_INTEL_82801DB_2	0x24c2
+#define PCI_DEVICE_ID_INTEL_82801DB_3	0x24c3
+#define PCI_DEVICE_ID_INTEL_82801DB_4	0x24c4
+#define PCI_DEVICE_ID_INTEL_82801DB_5	0x24c5
+#define PCI_DEVICE_ID_INTEL_82801DB_6	0x24c6
+#define PCI_DEVICE_ID_INTEL_82801DB_7	0x24c7
+#define PCI_DEVICE_ID_INTEL_82801DB_11	0x24cb
+#define PCI_DEVICE_ID_INTEL_82801DB_13	0x24cd
 #define PCI_DEVICE_ID_INTEL_80310	0x530d
 #define PCI_DEVICE_ID_INTEL_82810_MC1	0x7120
 #define PCI_DEVICE_ID_INTEL_82810_IG1	0x7121
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/personality.h linux/include/linux/personality.h
--- linux.orig/include/linux/personality.h	2001-09-10 20:04:33.000000000 +0000
+++ linux/include/linux/personality.h	2002-07-20 01:08:37.000000000 +0000
@@ -62,6 +62,8 @@
 	PER_RISCOS =		0x000c,
 	PER_SOLARIS =		0x000d | STICKY_TIMEOUTS,
 	PER_UW7 =		0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+	PER_HPUX =		0x000f,
+	PER_OSF4 =		0x0010,			 /* OSF/1 v4 */
 	PER_MASK =		0x00ff,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/pm.h linux/include/linux/pm.h
--- linux.orig/include/linux/pm.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/pm.h	2002-07-20 01:08:38.000000000 +0000
@@ -103,8 +103,8 @@
 	void		*data;
 
 	unsigned long	 flags;
-	int		 state;
-	int		 prev_state;
+	unsigned long	 state;
+	unsigned long	 prev_state;
 
 	struct list_head entry;
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/pmu.h linux/include/linux/pmu.h
--- linux.orig/include/linux/pmu.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/pmu.h	2002-07-20 01:08:24.000000000 +0000
@@ -75,6 +75,8 @@
 	PMU_HEATHROW_BASED,	/* PowerBook G3 series */
 	PMU_PADDINGTON_BASED,	/* 1999 PowerBook G3 */
 	PMU_KEYLARGO_BASED,	/* Core99 motherboard (PMU99) */
+	PMU_68K_V1,		/* 68K PMU, version 1 */
+	PMU_68K_V2, 		/* 68K PMU, version 2 */
 };
 
 /* PMU PMU_POWER_EVENTS commands */
@@ -113,6 +115,8 @@
 #define PMU_IOC_HAS_ADB		_IOR('B', 4, sizeof(__u32*)) 
 /* out param: u32*	can_sleep: 0 or 1 */
 #define PMU_IOC_CAN_SLEEP	_IOR('B', 5, sizeof(__u32*)) 
+/* no param */
+#define PMU_IOC_GRAB_BACKLIGHT	_IOR('B', 6, 0) 
 
 #ifdef __KERNEL__
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- linux.orig/include/linux/proc_fs.h	2001-11-22 19:46:23.000000000 +0000
+++ linux/include/linux/proc_fs.h	2002-07-20 01:08:21.000000000 +0000
@@ -132,6 +132,12 @@
  */
 extern void proc_rtas_init(void);
 
+/*
+ * PPC64
+ */ 
+extern void proc_ppc64_init(void);
+extern void iSeries_proc_create(void);
+
 extern struct proc_dir_entry *proc_symlink(const char *,
 		struct proc_dir_entry *, const char *);
 extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/quotaops.h linux/include/linux/quotaops.h
--- linux.orig/include/linux/quotaops.h	2001-11-22 19:46:52.000000000 +0000
+++ linux/include/linux/quotaops.h	2002-07-20 01:08:30.000000000 +0000
@@ -41,7 +41,7 @@
 static __inline__ void DQUOT_INIT(struct inode *inode)
 {
 	if (!inode->i_sb)
-		BUG();
+		out_of_line_bug();
 	lock_kernel();
 	if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
 		inode->i_sb->dq_op->initialize(inode, -1);
@@ -53,7 +53,7 @@
 	lock_kernel();
 	if (IS_QUOTAINIT(inode)) {
 		if (!inode->i_sb)
-			BUG();
+			out_of_line_bug();
 		inode->i_sb->dq_op->drop(inode);	/* Ops must be set when there's any quota... */
 	}
 	unlock_kernel();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/reiserfs_fs.h linux/include/linux/reiserfs_fs.h
--- linux.orig/include/linux/reiserfs_fs.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/reiserfs_fs.h	2002-07-20 01:08:32.000000000 +0000
@@ -204,7 +204,15 @@
 #define REISERFS_VALID_FS    1
 #define REISERFS_ERROR_FS    2
 
-
+//
+// there are 5 item types currently
+//
+#define TYPE_STAT_DATA 0
+#define TYPE_INDIRECT 1
+#define TYPE_DIRECT 2
+#define TYPE_DIRENTRY 3 
+#define TYPE_MAXTYPE 3 
+#define TYPE_ANY 15 // FIXME: comment is required
 
 /***************************************************************************/
 /*                       KEY & ITEM HEAD                                   */
@@ -240,7 +248,7 @@
 {
     offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2;
     tmp.linear = le64_to_cpu( tmp.linear );
-    return tmp.offset_v2.k_type;
+    return (tmp.offset_v2.k_type <= TYPE_MAXTYPE)?tmp.offset_v2.k_type:TYPE_ANY;
 }
  
 static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type )
@@ -390,15 +398,6 @@
 #define put_block_num(p, i, v) put_unaligned(cpu_to_le32(v), (p) + (i))
 
 //
-// there are 5 item types currently
-//
-#define TYPE_STAT_DATA 0
-#define TYPE_INDIRECT 1
-#define TYPE_DIRECT 2
-#define TYPE_DIRENTRY 3 
-#define TYPE_ANY 15 // FIXME: comment is required
-
-//
 // in old version uniqueness field shows key type
 //
 #define V1_SD_UNIQUENESS 0
@@ -718,11 +717,41 @@
 #define set_sd_v1_first_direct_byte(sdp,v) \
                                 ((sdp)->sd_first_direct_byte = cpu_to_le32(v))
 
+#include <linux/ext2_fs.h>
+
+/* inode flags stored in sd_attrs (nee sd_reserved) */
+
+/* we want common flags to have the same values as in ext2,
+   so chattr(1) will work without problems */
+#define REISERFS_IMMUTABLE_FL EXT2_IMMUTABLE_FL
+#define REISERFS_SYNC_FL      EXT2_SYNC_FL
+#define REISERFS_NOATIME_FL   EXT2_NOATIME_FL
+#define REISERFS_NODUMP_FL    EXT2_NODUMP_FL
+#define REISERFS_SECRM_FL     EXT2_SECRM_FL
+#define REISERFS_UNRM_FL      EXT2_UNRM_FL
+#define REISERFS_COMPR_FL     EXT2_COMPR_FL
+/* persistent flag to disable tails on per-file basic.
+   Note, that is inheritable: mark directory with this and
+   all new files inside will not have tails. 
+
+   Teodore Tso allocated EXT2_NODUMP_FL (0x00008000) for this. Change
+   numeric constant to ext2 macro when available. */
+#define REISERFS_NOTAIL_FL    (0x00008000) /* EXT2_NOTAIL_FL */
+
+/* persistent flags that file inherits from the parent directory */
+#define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL |	\
+				REISERFS_SYNC_FL |	\
+				REISERFS_NOATIME_FL |	\
+				REISERFS_NODUMP_FL |	\
+				REISERFS_SECRM_FL |	\
+				REISERFS_COMPR_FL |	\
+				REISERFS_NOTAIL_FL )
+
 /* Stat Data on disk (reiserfs version of UFS disk inode minus the
    address blocks) */
 struct stat_data {
     __u16 sd_mode;	/* file type, permissions */
-    __u16 sd_reserved;
+    __u16 sd_attrs;     /* persistent inode flags */
     __u32 sd_nlink;	/* number of hard links */
     __u64 sd_size;	/* file size */
     __u32 sd_uid;		/* owner */
@@ -775,6 +804,8 @@
 #define set_sd_v2_rdev(sdp,v)   ((sdp)->u.sd_rdev = cpu_to_le32(v))
 #define sd_v2_generation(sdp)   (le32_to_cpu((sdp)->u.sd_generation))
 #define set_sd_v2_generation(sdp,v) ((sdp)->u.sd_generation = cpu_to_le32(v))
+#define sd_v2_attrs(sdp)         (le16_to_cpu((sdp)->sd_attrs))
+#define set_sd_v2_attrs(sdp,v)   ((sdp)->sd_attrs = cpu_to_le16(v))
 
 
 /***************************************************************************/
@@ -1203,6 +1234,13 @@
   struct virtual_item * vn_vi;	/* array of items (including a new one, excluding item to be deleted) */
 };
 
+/* used by directory items when creating virtual nodes */
+struct direntry_uarea {
+    int flags;
+    __u16 entry_count;
+    __u16 entry_sizes[1];
+} __attribute__ ((__packed__)) ;
+
 
 /***************************************************************************/
 /*                  TREE BALANCE                                           */
@@ -1365,7 +1403,7 @@
 
 extern struct item_operations stat_data_ops, indirect_ops, direct_ops, 
   direntry_ops;
-extern struct item_operations * item_ops [4];
+extern struct item_operations * item_ops [TYPE_ANY + 1];
 
 #define op_bytes_number(ih,bsize)                    item_ops[le_ih_k_type (ih)]->bytes_number (ih, bsize)
 #define op_is_left_mergeable(key,bsize)              item_ops[le_key_k_type (le_key_version (key), key)]->is_left_mergeable (key, bsize)
@@ -1701,6 +1739,9 @@
 int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode);
 void reiserfs_update_sd (struct reiserfs_transaction_handle *th, struct inode * inode);
 
+void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode );
+void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs );
+
 /* namei.c */
 inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
 int search_by_entry_key (struct super_block * sb, const struct cpu_key * key, 
@@ -1792,8 +1833,14 @@
 				     int n_size);
 
 /* fix_nodes.c */
+#ifdef CONFIG_REISERFS_CHECK
 void * reiserfs_kmalloc (size_t size, int flags, struct super_block * s);
 void reiserfs_kfree (const void * vp, size_t size, struct super_block * s);
+#else
+#define reiserfs_kmalloc(x, y, z) kmalloc(x, y)
+#define reiserfs_kfree(x, y, z) kfree(x)
+#endif
+
 int fix_nodes (int n_op_mode, struct tree_balance * p_s_tb, 
 	       struct item_head * p_s_ins_ih, const void *);
 void unfix_nodes (struct tree_balance *);
@@ -1824,6 +1871,7 @@
 void check_leaf (struct buffer_head * bh);
 void check_internal (struct buffer_head * bh);
 void print_statistics (struct super_block * s);
+char * reiserfs_hashname(int code);
 
 /* lbalance.c */
 int leaf_move_items (int shift_mode, struct tree_balance * tb, int mov_num, int mov_bytes, struct buffer_head * Snew);
@@ -1918,6 +1966,12 @@
  
 /* ioctl's command */
 #define REISERFS_IOC_UNPACK		_IOW(0xCD,1,long)
+/* define following flags to be the same as in ext2, so that chattr(1),
+   lsattr(1) will work with us. */
+#define REISERFS_IOC_GETFLAGS           EXT2_IOC_GETFLAGS
+#define REISERFS_IOC_SETFLAGS           EXT2_IOC_SETFLAGS
+#define REISERFS_IOC_GETVERSION 	EXT2_IOC_GETVERSION
+#define REISERFS_IOC_SETVERSION         EXT2_IOC_SETVERSION
  			         
 #endif /* _LINUX_REISER_FS_H */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/reiserfs_fs_i.h linux/include/linux/reiserfs_fs_i.h
--- linux.orig/include/linux/reiserfs_fs_i.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/linux/reiserfs_fs_i.h	2002-07-20 01:08:30.000000000 +0000
@@ -33,6 +33,9 @@
 
     __u32 i_first_direct_byte; // offset of first byte stored in direct item.
 
+    /* copy of persistent inode flags read from sd_attrs. */
+    __u32 i_attrs;
+
     int i_prealloc_block; /* first unused block of a sequence of unused blocks */
     int i_prealloc_count; /* length of that sequence */
     struct list_head i_prealloc_list;	/* per-transaction list of inodes which
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/reiserfs_fs_sb.h linux/include/linux/reiserfs_fs_sb.h
--- linux.orig/include/linux/reiserfs_fs_sb.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/reiserfs_fs_sb.h	2002-07-20 01:08:37.000000000 +0000
@@ -61,9 +61,19 @@
                                    superblock. -Hans */
   __u16 s_reserved;
   __u32 s_inode_generation;
-  char s_unused[124] ;			/* zero filled by mkreiserfs */
+  __u32 s_flags;		       /* Right now used only by inode-attributes, if enabled */
+  unsigned char s_uuid[16];            /* filesystem unique identifier */
+  unsigned char s_label[16];           /* filesystem volume label */
+  char s_unused[88] ;                  /* zero filled by mkreiserfs and
+                                        * reiserfs_convert_objectid_map_v1()
+                                        * so any additions must be updated
+                                        * there as well. */
 } __attribute__ ((__packed__));
 
+typedef enum {
+  reiserfs_attrs_cleared       = 0x00000001,
+} reiserfs_super_block_flags;
+
 #define SB_SIZE (sizeof(struct reiserfs_super_block))
 /* struct reiserfs_super_block accessors/mutators
  * since this is a disk structure, it will always be in 
@@ -330,6 +340,12 @@
   stat_cnt_t search_by_key_fs_changed;
   stat_cnt_t search_by_key_restarted;
 
+  stat_cnt_t insert_item_restarted;
+  stat_cnt_t paste_into_item_restarted;
+  stat_cnt_t cut_from_item_restarted;
+  stat_cnt_t delete_solid_item_restarted;
+  stat_cnt_t delete_item_restarted;
+
   stat_cnt_t leaked_oid;
   stat_cnt_t leaves_removable;
 
@@ -472,6 +488,8 @@
 #define REISERFS_TEST3 13
 #define REISERFS_TEST4 14 
 
+#define REISERFS_ATTRS (15)
+
 #define reiserfs_r5_hash(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << FORCE_R5_HASH))
 #define reiserfs_rupasov_hash(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << FORCE_RUPASOV_HASH))
 #define reiserfs_tea_hash(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << FORCE_TEA_HASH))
@@ -484,6 +502,7 @@
 #define dont_have_tails(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << NOTAIL))
 #define replay_only(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REPLAYONLY))
 #define reiserfs_dont_log(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_NOLOG))
+#define reiserfs_attrs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_ATTRS))
 #define old_format_only(s) ((s)->u.reiserfs_sb.s_properties & (1 << REISERFS_3_5))
 #define convert_reiserfs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_CONVERT))
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/rtnetlink.h linux/include/linux/rtnetlink.h
--- linux.orig/include/linux/rtnetlink.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/rtnetlink.h	2002-07-20 01:08:29.000000000 +0000
@@ -587,7 +587,7 @@
 
 #define ASSERT_RTNL() do { if (down_trylock(&rtnl_sem) == 0)  { up(&rtnl_sem); \
 printk("RTNL: assertion failed at " __FILE__ "(%d)\n", __LINE__); } \
-		   } while(0);
+		   } while(0)
 #define BUG_TRAP(x) if (!(x)) { printk("KERNEL: assertion (" #x ") failed at " __FILE__ "(%d)\n", __LINE__); }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/sched.h linux/include/linux/sched.h
--- linux.orig/include/linux/sched.h	2001-12-21 17:42:03.000000000 +0000
+++ linux/include/linux/sched.h	2002-07-20 01:08:25.000000000 +0000
@@ -42,6 +42,7 @@
 #define CLONE_VFORK	0x00004000	/* set if the parent wants the child to wake it up on mm_release */
 #define CLONE_PARENT	0x00008000	/* set if we want to have the same parent as the cloner */
 #define CLONE_THREAD	0x00010000	/* Same thread group? */
+#define CLONE_NEWNS	0x00020000	/* New namespace group? */
 
 #define CLONE_SIGNAL	(CLONE_SIGHAND | CLONE_THREAD)
 
@@ -79,7 +80,9 @@
 #include <linux/time.h>
 #include <linux/param.h>
 #include <linux/resource.h>
+#ifdef __KERNEL__
 #include <linux/timer.h>
+#endif
 
 #include <asm/processor.h>
 
@@ -166,6 +169,7 @@
  */
 #define NR_OPEN_DEFAULT BITS_PER_LONG
 
+struct namespace;
 /*
  * Open file table structure
  */
@@ -199,7 +203,9 @@
 }
 
 /* Maximum number of active map areas.. This is a random (large) number */
-#define MAX_MAP_COUNT	(65536)
+#define DEFAULT_MAX_MAP_COUNT	(65536)
+
+extern int max_map_count;
 
 struct mm_struct {
 	struct vm_area_struct * mmap;		/* list of VMAs */
@@ -389,6 +395,8 @@
 	struct fs_struct *fs;
 /* open file information */
 	struct files_struct *files;
+/* namespace */
+	struct namespace *namespace;
 /* signal handlers */
 	spinlock_t sigmask_lock;	/* Protects signal and blocked */
 	struct signal_struct *sig;
@@ -450,6 +458,8 @@
 #define MAX_COUNTER	(20*HZ/100)
 #define DEF_NICE	(0)
 
+asmlinkage long sys_sched_yield(void);
+#define yield()	sys_sched_yield()
 
 /*
  * The default (Linux) execution domain.
@@ -610,6 +620,7 @@
 extern void proc_caches_init(void);
 extern void flush_signals(struct task_struct *);
 extern void flush_signal_handlers(struct task_struct *);
+extern void sig_exit(int, int, struct siginfo *);
 extern int dequeue_signal(sigset_t *, siginfo_t *);
 extern void block_all_signals(int (*notifier)(void *priv), void *priv,
 			      sigset_t *mask);
@@ -870,9 +881,14 @@
 #define for_each_task(p) \
 	for (p = &init_task ; (p = p->next_task) != &init_task ; )
 
+#define for_each_thread(task) \
+	for (task = next_thread(current) ; task != current ; task = next_thread(task))
+
 #define next_thread(p) \
 	list_entry((p)->thread_group.next, struct task_struct, thread_group)
 
+#define thread_group_leader(p)	(p->pid == p->tgid)
+
 static inline void del_from_runqueue(struct task_struct * p)
 {
 	nr_running--;
@@ -888,7 +904,8 @@
 
 static inline void unhash_process(struct task_struct *p)
 {
-	if (task_on_runqueue(p)) BUG();
+	if (task_on_runqueue(p))
+		out_of_line_bug();
 	write_lock_irq(&tasklist_lock);
 	nr_threads--;
 	unhash_pid(p);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/seq_file.h linux/include/linux/seq_file.h
--- linux.orig/include/linux/seq_file.h	2001-11-11 19:23:14.000000000 +0000
+++ linux/include/linux/seq_file.h	2002-07-20 01:08:36.000000000 +0000
@@ -12,6 +12,7 @@
 	loff_t index;
 	struct semaphore sem;
 	struct seq_operations *op;
+	void *private;
 };
 
 struct seq_operations {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/serial.h linux/include/linux/serial.h
--- linux.orig/include/linux/serial.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/serial.h	2002-07-20 01:08:28.000000000 +0000
@@ -80,7 +80,6 @@
 #define SERIAL_IO_PORT	0
 #define SERIAL_IO_HUB6	1
 #define SERIAL_IO_MEM	2
-#define SERIAL_IO_GSC	3
 
 struct serial_uart_config {
 	char	*name;
@@ -182,11 +181,8 @@
 /* Allow complicated architectures to specify rs_table[] at run time */
 extern int early_serial_setup(struct serial_struct *req);
 
-#ifdef CONFIG_ACPI
-/* tty ports reserved for the ACPI serial console port and debug port */
-#define ACPI_SERIAL_CONSOLE_PORT        4
-#define ACPI_SERIAL_DEBUG_PORT          5
-#endif
+/* tty port reserved for the HCDP serial console port */
+#define HCDP_SERIAL_CONSOLE_PORT	4
 
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SERIAL_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/serialP.h linux/include/linux/serialP.h
--- linux.orig/include/linux/serialP.h	2001-11-22 19:47:23.000000000 +0000
+++ linux/include/linux/serialP.h	2002-07-20 01:08:25.000000000 +0000
@@ -157,6 +157,9 @@
 	struct pci_dev		*dev;
 };
 
+extern int pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable);
+extern int pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable);
+
 #ifndef PCI_ANY_ID
 #define PCI_ANY_ID (~0)
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/sisfb.h linux/include/linux/sisfb.h
--- linux.orig/include/linux/sisfb.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/linux/sisfb.h	2002-07-20 01:08:27.000000000 +0000
@@ -20,6 +20,7 @@
 #define HASVB_303       	0x40
 #define HASVB_CHRONTEL  	0x80
 
+/* Never change the order of the following enum */
 typedef enum _SIS_CHIP_TYPE {
 	SIS_VGALegacy = 0,
 	SIS_300,
@@ -32,7 +33,8 @@
 	SIS_315PRO,
 	SIS_640,
 	SIS_740,
-	SIS_330, 
+	SIS_650,
+	SIS_330,
 	MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
 
@@ -88,6 +90,7 @@
 	unsigned long mmio_base;
 	char  *mmio_vbase; 
 	unsigned long vga_base;
+	unsigned long mtrr;
 
 	int    video_bpp;
 	int    video_width;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/skbuff.h linux/include/linux/skbuff.h
--- linux.orig/include/linux/skbuff.h	2001-11-22 19:46:26.000000000 +0000
+++ linux/include/linux/skbuff.h	2002-07-20 01:08:23.000000000 +0000
@@ -588,7 +588,7 @@
 
 static inline struct sk_buff *skb_dequeue(struct sk_buff_head *list)
 {
-	long flags;
+	unsigned long flags;
 	struct sk_buff *result;
 
 	spin_lock_irqsave(&list->lock, flags);
@@ -737,7 +737,7 @@
 
 static inline struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
 {
-	long flags;
+	unsigned long flags;
 	struct sk_buff *result;
 
 	spin_lock_irqsave(&list->lock, flags);
@@ -756,9 +756,9 @@
 	return skb->len - skb->data_len;
 }
 
-#define SKB_PAGE_ASSERT(skb) do { if (skb_shinfo(skb)->nr_frags) BUG(); } while (0)
-#define SKB_FRAG_ASSERT(skb) do { if (skb_shinfo(skb)->frag_list) BUG(); } while (0)
-#define SKB_LINEAR_ASSERT(skb) do { if (skb_is_nonlinear(skb)) BUG(); } while (0)
+#define SKB_PAGE_ASSERT(skb) do { if (skb_shinfo(skb)->nr_frags) out_of_line_bug(); } while (0)
+#define SKB_FRAG_ASSERT(skb) do { if (skb_shinfo(skb)->frag_list) out_of_line_bug(); } while (0)
+#define SKB_LINEAR_ASSERT(skb) do { if (skb_is_nonlinear(skb)) out_of_line_bug(); } while (0)
 
 /*
  *	Add data to an sk_buff
@@ -826,7 +826,7 @@
 {
 	skb->len-=len;
 	if (skb->len < skb->data_len)
-		BUG();
+		out_of_line_bug();
 	return 	skb->data+=len;
 }
 
@@ -1094,7 +1094,7 @@
 {
 #ifdef CONFIG_HIGHMEM
 	if (in_irq())
-		BUG();
+		out_of_line_bug();
 
 	local_bh_disable();
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/slab.h linux/include/linux/slab.h
--- linux.orig/include/linux/slab.h	2001-12-21 17:42:04.000000000 +0000
+++ linux/include/linux/slab.h	2002-07-20 01:08:36.000000000 +0000
@@ -62,10 +62,6 @@
 extern void kfree(const void *);
 
 extern int FASTCALL(kmem_cache_reap(int));
-extern int slabinfo_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data);
-extern int slabinfo_write_proc(struct file *file, const char *buffer,
-			   unsigned long count, void *data);
 
 /* System wide caches */
 extern kmem_cache_t	*vm_area_cachep;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/spinlock.h linux/include/linux/spinlock.h
--- linux.orig/include/linux/spinlock.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/spinlock.h	2002-07-20 01:08:36.000000000 +0000
@@ -35,6 +35,23 @@
 						if (!__r) local_bh_enable();   \
 						__r; })
 
+/* Must define these before including other files, inline functions need them */
+
+#include <linux/stringify.h>
+
+#define LOCK_SECTION_NAME			\
+	".text.lock." __stringify(KBUILD_BASENAME)
+
+#define LOCK_SECTION_START(extra)		\
+	".subsection 1\n\t"			\
+	extra					\
+	".ifndef " LOCK_SECTION_NAME "\n\t"	\
+	LOCK_SECTION_NAME ":\n\t"		\
+	".endif\n\t"
+
+#define LOCK_SECTION_END			\
+	".previous\n\t"
+
 #ifdef CONFIG_SMP
 #include <asm/spinlock.h>
 
@@ -138,4 +155,20 @@
 extern int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
 #endif
 
+#ifdef CONFIG_SMP
+#include <linux/cache.h>
+
+typedef union {
+    spinlock_t lock;
+    char fill_up[(SMP_CACHE_BYTES)];
+} spinlock_cacheline_t __attribute__ ((aligned(SMP_CACHE_BYTES)));
+
+#else	/* SMP */
+
+typedef struct {
+    spinlock_t lock;
+} spinlock_cacheline_t;
+
+
+#endif
 #endif /* __LINUX_SPINLOCK_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/sunrpc/xprt.h linux/include/linux/sunrpc/xprt.h
--- linux.orig/include/linux/sunrpc/xprt.h	2001-11-22 19:47:20.000000000 +0000
+++ linux/include/linux/sunrpc/xprt.h	2002-07-20 01:08:38.000000000 +0000
@@ -120,6 +120,11 @@
 #define rq_rnr			rq_rcv_buf.io_nr
 #define rq_rlen			rq_rcv_buf.io_len
 
+#define XPRT_LAST_FRAG		(1 << 0)
+#define XPRT_COPY_RECM		(1 << 1)
+#define XPRT_COPY_XID		(1 << 2)
+#define XPRT_COPY_DATA		(1 << 3)
+
 struct rpc_xprt {
 	struct socket *		sock;		/* BSD socket layer */
 	struct sock *		inet;		/* INET layer */
@@ -140,18 +145,17 @@
 	unsigned long		sockstate;	/* Socket state */
 	unsigned char		shutdown   : 1,	/* being shut down */
 				nocong	   : 1,	/* no congestion control */
-				stream     : 1,	/* TCP */
-				tcp_more   : 1;	/* more record fragments */
+				stream     : 1;	/* TCP */
 
 	/*
 	 * State of TCP reply receive stuff
 	 */
-	u32			tcp_recm;	/* Fragment header */
-	u32			tcp_xid;	/* Current XID */
-	unsigned int		tcp_reclen,	/* fragment length */
-				tcp_offset,	/* fragment offset */
-				tcp_copied;	/* copied to request */
-	struct list_head	rx_pending;	/* receive pending list */
+	u32			tcp_recm,	/* Fragment header */
+				tcp_xid,	/* Current XID */
+				tcp_reclen,	/* fragment length */
+				tcp_offset;	/* fragment offset */
+	unsigned long		tcp_copied,	/* copied to request */
+				tcp_flags;
 
 	/*
 	 * Send stuff
@@ -185,8 +189,6 @@
 void			xprt_release(struct rpc_task *);
 void			xprt_reconnect(struct rpc_task *);
 int			xprt_clear_backlog(struct rpc_xprt *);
-int			xprt_tcp_pending(void);
-void			__rpciod_tcp_dispatcher(void);
 
 #define XPRT_WSPACE	0
 #define XPRT_CONNECT	1
@@ -200,13 +202,6 @@
 #define xprt_test_and_set_connected(xp)	(test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
 #define xprt_clear_connected(xp)	(clear_bit(XPRT_CONNECT, &(xp)->sockstate))
 
-static inline
-void rpciod_tcp_dispatcher(void)
-{
-	if (xprt_tcp_pending())
-		__rpciod_tcp_dispatcher();
-}
-
 #endif /* __KERNEL__*/
 
 #endif /* _LINUX_SUNRPC_XPRT_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/swap.h linux/include/linux/swap.h
--- linux.orig/include/linux/swap.h	2001-11-22 19:46:19.000000000 +0000
+++ linux/include/linux/swap.h	2002-07-20 01:08:23.000000000 +0000
@@ -90,7 +90,10 @@
 extern atomic_t nr_async_pages;
 extern atomic_t page_cache_size;
 extern atomic_t buffermem_pages;
-extern spinlock_t pagecache_lock;
+
+extern spinlock_cacheline_t pagecache_lock_cacheline;
+#define pagecache_lock (pagecache_lock_cacheline.lock)
+
 extern void __remove_inode_page(struct page *);
 
 /* Incomplete types for prototype declarations: */
@@ -156,7 +159,8 @@
 asmlinkage long sys_swapoff(const char *);
 asmlinkage long sys_swapon(const char *, int);
 
-extern spinlock_t pagemap_lru_lock;
+extern spinlock_cacheline_t pagemap_lru_lock_cacheline;
+#define pagemap_lru_lock pagemap_lru_lock_cacheline.lock
 
 extern void FASTCALL(mark_page_accessed(struct page *));
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/sysctl.h linux/include/linux/sysctl.h
--- linux.orig/include/linux/sysctl.h	2001-11-26 13:29:17.000000000 +0000
+++ linux/include/linux/sysctl.h	2002-07-20 01:08:22.000000000 +0000
@@ -140,8 +140,9 @@
 	VM_PAGERDAEMON=8,	/* struct: Control kswapd behaviour */
 	VM_PGT_CACHE=9,		/* struct: Set page table cache parameters */
 	VM_PAGE_CLUSTER=10,	/* int: set number of pages to swap together */
-       VM_MIN_READAHEAD=12,    /* Min file readahead */
-       VM_MAX_READAHEAD=13     /* Max file readahead */
+	VM_MAX_MAP_COUNT=11,	/* int: Maximum number of active map areas */
+	VM_MIN_READAHEAD=12,    /* Min file readahead */
+	VM_MAX_READAHEAD=13,    /* Max file readahead */
 };
 
 
@@ -289,7 +290,8 @@
 	NET_TCP_ADV_WIN_SCALE=87,
 	NET_IPV4_NONLOCAL_BIND=88,
 	NET_IPV4_ICMP_RATELIMIT=89,
-	NET_IPV4_ICMP_RATEMASK=90
+	NET_IPV4_ICMP_RATEMASK=90,
+	NET_TCP_TW_REUSE=91
 };
 
 enum {
@@ -334,7 +336,8 @@
 	NET_IPV4_CONF_BOOTP_RELAY=10,
 	NET_IPV4_CONF_LOG_MARTIANS=11,
 	NET_IPV4_CONF_TAG=12,
-	NET_IPV4_CONF_ARPFILTER=13
+	NET_IPV4_CONF_ARPFILTER=13,
+	NET_IPV4_CONF_MEDIUM_ID=14,
 };
 
 /* /proc/sys/net/ipv6 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/sysrq.h linux/include/linux/sysrq.h
--- linux.orig/include/linux/sysrq.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/sysrq.h	2002-07-20 01:08:22.000000000 +0000
@@ -105,7 +105,7 @@
 
 /* Deferred actions */
 
-extern int emergency_sync_scheduled;
+extern volatile int emergency_sync_scheduled;
 
 #define EMERG_SYNC 1
 #define EMERG_REMOUNT 2
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/telephony.h linux/include/linux/telephony.h
--- linux.orig/include/linux/telephony.h	2001-09-07 16:28:37.000000000 +0000
+++ linux/include/linux/telephony.h	2002-07-20 01:08:22.000000000 +0000
@@ -228,8 +228,8 @@
 * indicate the current state of the hookswitch.  The pstn_ring bit
 * indicates that the DAA on a LineJACK card has detected ring voltage on
 * the PSTN port.  The caller_id bit indicates that caller_id data has been
-* recieved and is available.  The pstn_wink bit indicates that the DAA on
-* the LineJACK has recieved a wink from the telco switch.  The f0, f1, f2
+* received and is available.  The pstn_wink bit indicates that the DAA on
+* the LineJACK has received a wink from the telco switch.  The f0, f1, f2
 * and f3 bits indicate that the filter has been triggered by detecting the
 * frequency programmed into that filter.
 *
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/trdevice.h linux/include/linux/trdevice.h
--- linux.orig/include/linux/trdevice.h	2001-03-26 02:24:31.000000000 +0000
+++ linux/include/linux/trdevice.h	2002-07-20 01:08:29.000000000 +0000
@@ -31,6 +31,9 @@
 extern int		tr_header(struct sk_buff *skb, struct net_device *dev,
 				   unsigned short type, void *daddr,
 				   void *saddr, unsigned len);
+extern void		tr_source_route(struct sk_buff *skb,
+					struct trh_hdr *trh,
+					struct net_device *dev);
 extern int		tr_rebuild_header(struct sk_buff *skb);
 extern unsigned short	tr_type_trans(struct sk_buff *skb, struct net_device *dev);
 extern struct net_device *init_trdev(struct net_device *dev, int sizeof_priv);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/types.h linux/include/linux/types.h
--- linux.orig/include/linux/types.h	2001-11-22 19:46:18.000000000 +0000
+++ linux/include/linux/types.h	2002-07-20 01:08:31.000000000 +0000
@@ -41,7 +41,7 @@
 typedef __kernel_gid_t		gid_t;
 #endif /* __KERNEL__ */
 
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#if defined(__GNUC__)
 typedef __kernel_loff_t		loff_t;
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/udf_167.h linux/include/linux/udf_167.h
--- linux.orig/include/linux/udf_167.h	2001-06-12 02:15:27.000000000 +0000
+++ linux/include/linux/udf_167.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,786 +0,0 @@
-#if !defined(_LINUX_UDF_167_H)
-#define _LINUX_UDF_167_H
-/*
- * udf_167.h
- *
- * DESCRIPTION
- *	Definitions from the ECMA 167 standard.
- *	http://www.ecma.ch/
- *
- *	These abbreviations are used to keep the symbols short:
- *		Alloc	Allocation
- *		App	Application
- *		Attr	Attribute
- *		Char	Characters
- *		Desc	Descriptor
- *		Descs	Descriptors
- *		Ext	Extent
- *		Ident	Identifier
- *		Imp	Implementation
- *		Lvl	Level
- *		Max	Maximum
- *		Num	Number
- *		Ptr	Pointer
- *		Seq	Sequence
- *		Std	Standard
- *		Struct	Structure
- *		Vol	Volume
- *	The symbols are otherwise identical to the standard, and the
- *	sections of the standard to refer to are indicated.
- *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
- * COPYRIGHT
- *	This file is distributed under the terms of the GNU General Public
- *	License (GPL). Copies of the GPL can be obtained from:
- *		ftp://prep.ai.mit.edu/pub/gnu/GPL
- *	Each contributing author retains all rights to their own work.
- *
- * HISTORY
- *	July 12, 1997 - Andrew E. Mileski
- *	Adapted from the ECMA-167 standard.
- *
- * 10/2/98 dgb	Adaptation
- * 10/4/98 	Changes by HJA Sandkuyl
- * 10/7/98	Changed FILE_EXISTENCE to FILE_HIDDEN, per UDF 2.0 spec
- * 11/26/98	Modifed some entries for UDF 1.5/2.0
- * 11/26/98 bf  Fixed typos, non-linux types, more structures
- * 12/5/98 dgb  Adjusted structure and content of include files.
- */
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#define Uint8	__u8
-#define Sint8	__s8
-#define Uint16	__u16
-#define Sint16	__s16
-#define Uint32	__u32
-#define Sint32	__s32
-#define Uint64	__u64
-#define Sint64	__s64
-typedef Uint8	dstring;
-#else
-#define Uint8	unsigned char
-#define Sint8	char
-#define Uint16	unsigned short
-#define Sint16	short
-#define Uint32	unsigned int
-#define Sint32	int
-#define Uint64	unsigned long long
-#define Sint64	long long
-typedef Uint8	dstring;
-#endif
-
-/* make sure all structures are packed! */
-#pragma pack(1)
-
-/* CS0 Charspec (ECMA 167 1/7.2.1) */
-typedef struct {
-	Uint8 charSetType;
-	Uint8 charSetInfo[63];
-} charspec;
-
-/* Timestamp (ECMA 167 1/7.3) */
-typedef struct {
-	Uint16 typeAndTimezone;
-	Uint16 year;
-	Uint8 month;
-	Uint8 day;
-	Uint8 hour;
-	Uint8 minute;
-	Uint8 second;
-	Uint8 centiseconds;
-	Uint8 hundredsOfMicroseconds;
-	Uint8 microseconds;
-} timestamp;
-
-/* Timestamp types (ECMA 167 1/7.3.1) */
-#define TIMESTAMP_TYPE_CUT		0x0000U
-#define TIMESTAMP_TYPE_LOCAL		0x0001U
-#define TIMESTAMP_TYPE_AGREEMENT	0x0002U
-
-/* Entity Identifier (ECMA 167 1/7.4) */
-typedef struct {
-	Uint8 flags;
-	Uint8 ident[23];
-	Uint8 identSuffix[8];
-} EntityID;
-#define regid EntityID
-
-/* Entity identifier flags (ECMA 167 1/7.4.1) */
-#define ENTITYID_FLAGS_DIRTY		0x01U
-#define ENTITYID_FLAGS_PROTECTED	0x02U
-
-/* Volume Structure Descriptor (ECMA 167 2/9.1) */
-#define STD_ID_LEN	5
-struct VolStructDesc {
-	Uint8 structType;
-	Uint8 stdIdent[STD_ID_LEN];
-	Uint8 structVersion;
-	Uint8 structData[2041];
-};
-
-/* Std structure identifiers (ECMA 167 2/9.1.2) */
-#define STD_ID_BEA01	"BEA01"
-#define STD_ID_BOOT2	"BOOT2"
-#define STD_ID_CD001	"CD001"
-#define STD_ID_CDW02	"CDW02"
-#define STD_ID_NSR02	"NSR02"
-#define STD_ID_NSR03	"NSR03"
-#define STD_ID_TEA01	"TEA01"
-
-/* Beginning Extended Area Descriptor (ECMA 167 2/9.2) */
-struct BeginningExtendedAreaDesc {
-	Uint8 structType;
-	Uint8 stdIdent[STD_ID_LEN];
-	Uint8 structVersion;
-	Uint8 structData[2041];
-};
-
-/* Terminating Extended Area Descriptor (ECMA 167 2/9.3) */
-struct TerminatingExtendedAreaDesc {
-	Uint8 structType;
-	Uint8 stdIdent[STD_ID_LEN];
-	Uint8 structVersion;
-	Uint8 structData[2041];
-};
-
-/* Boot Descriptor (ECMA 167 2/9.4) */
-struct BootDesc {
-	Uint8 structType;
-	Uint8 stdIdent[STD_ID_LEN];
-	Uint8 structVersion;
-	Uint8 reserved1;
-	EntityID architectureType;
-	EntityID bootIdent;
-	Uint32 bootExtLocation;
-	Uint32 bootExtLength;
-	Uint64 loadAddress;
-	Uint64 startAddress;
-	timestamp descCreationDateAndTime;
-	Uint16 flags;
-	Uint8 reserved2[32];
-	Uint8 bootUse[1906];
-};
-
-/* Boot flags (ECMA 167 2/9.4.12) */
-#define BOOT_FLAGS_ERASE	1
-
-/* Extent Descriptor (ECMA 167 3/7.1) */
-typedef struct {
-	Uint32 extLength;
-	Uint32 extLocation;
-} extent_ad;
-
-/* Descriptor Tag (ECMA 167 3/7.2) */
-typedef struct {
-	Uint16 tagIdent;
-	Uint16 descVersion;
-	Uint8 tagChecksum;
-	Uint8 reserved;
-	Uint16 tagSerialNum;
-	Uint16 descCRC;
-	Uint16 descCRCLength;
-	Uint32 tagLocation;
-} tag;
-
-/* Tag Identifiers (ECMA 167 3/7.2.1) */
-#define TID_UNUSED_DESC			0x0000U
-#define TID_PRIMARY_VOL_DESC		0x0001U
-#define TID_ANCHOR_VOL_DESC_PTR		0x0002U
-#define TID_VOL_DESC_PTR		0x0003U
-#define TID_IMP_USE_VOL_DESC		0x0004U
-#define TID_PARTITION_DESC		0x0005U
-#define TID_LOGICAL_VOL_DESC		0x0006U
-#define TID_UNALLOC_SPACE_DESC		0x0007U
-#define TID_TERMINATING_DESC		0x0008U
-#define TID_LOGICAL_VOL_INTEGRITY_DESC	0x0009U
-
-/* Tag Identifiers (ECMA 167 4/7.2.1) */
-#define TID_FILE_SET_DESC		0x0100U
-#define TID_FILE_IDENT_DESC		0x0101U
-#define TID_ALLOC_EXTENT_DESC		0x0102U
-#define TID_INDIRECT_ENTRY		0x0103U
-#define TID_TERMINAL_ENTRY		0x0104U
-#define TID_FILE_ENTRY			0x0105U
-#define TID_EXTENDED_ATTRE_HEADER_DESC	0x0106U
-#define TID_UNALLOCATED_SPACE_ENTRY	0x0107U
-#define TID_SPACE_BITMAP_DESC		0x0108U
-#define TID_PARTITION_INTEGRITY_ENTRY	0x0109U
-#define TID_EXTENDED_FILE_ENTRY		0x010AU
-
-/* NSR Descriptor (ECMA 167 3/9.1) */
-struct NSRDesc {
-	Uint8 structType;
-	Uint8 stdIdent[STD_ID_LEN];
-	Uint8 structVersion;
-	Uint8 reserved;
-	Uint8 structData[2040];
-};
-	
-/* Primary Volume Descriptor (ECMA 167 3/10.1) */
-struct PrimaryVolDesc {
-	tag descTag;
-	Uint32 volDescSeqNum;
-	Uint32 primaryVolDescNum;
-	dstring volIdent[32];
-	Uint16 volSeqNum;
-	Uint16 maxVolSeqNum;
-	Uint16 interchangeLvl;
-	Uint16 maxInterchangeLvl;
-	Uint32 charSetList;
-	Uint32 maxCharSetList;
-	dstring volSetIdent[128];
-	charspec descCharSet;
-	charspec explanatoryCharSet;
-	extent_ad volAbstract;
-	extent_ad volCopyright;
-	EntityID appIdent;
-	timestamp recordingDateAndTime;
-	EntityID impIdent;
-	Uint8 impUse[64];
-	Uint32 predecessorVolDescSeqLocation;
-	Uint16 flags;
-	Uint8 reserved[22];
-};
-
-/* Primary volume descriptor flags (ECMA 167 3/10.1.21) */
-#define VOL_SET_IDENT	1
-
-/* Anchor Volume Descriptor Pointer (ECMA 167 3/10.2) */
-struct AnchorVolDescPtr {
-	tag descTag;
-	extent_ad mainVolDescSeqExt;
-	extent_ad reserveVolDescSeqExt;
-	Uint8 reserved[480];
-};
-
-/* Volume Descriptor Pointer (ECMA 167 3/10.3) */
-struct VolDescPtr {
-	tag descTag;
-	Uint32 volDescSeqNum;
-	extent_ad nextVolDescSeqExt;
-	Uint8 reserved[484];
-};
-
-/* Implementation Use Volume Descriptor (ECMA 167 3/10.4) */
-struct ImpUseVolDesc {
-	tag descTag;
-	Uint32 volDescSeqNum;
-	EntityID impIdent;
-	Uint8 impUse[460];
-};
-
-/* Partition Descriptor (ECMA 167 3/10.5) */
-struct PartitionDesc {
-	tag descTag;
-	Uint32 volDescSeqNum;
-	Uint16 partitionFlags;
-	Uint16 partitionNumber;
-	EntityID partitionContents;
-	Uint8 partitionContentsUse[128];
-	Uint32 accessType;
-	Uint32 partitionStartingLocation;
-	Uint32 partitionLength;
-	EntityID impIdent;
-	Uint8 impUse[128];
-	Uint8 reserved[156];
-};
-
-/* Partition Flags (ECMA 167 3/10.5.3) */
-#define PARTITION_FLAGS_ALLOC	1
-
-/* Partition Contents (ECMA 167 3/10.5.5) */
-#define PARTITION_CONTENTS_FDC01	"+FDC01"
-#define PARTITION_CONTENTS_CD001	"+CD001"
-#define PARTITION_CONTENTS_CDW02	"+CDW02"
-#define PARTITION_CONTENTS_NSR02	"+NSR02"
-#define PARTITION_CONTENTS_NSR03	"+NSR03"
-
-/* Partition Access Types (ECMA 167 3/10.5.7) */
-#define PARTITION_ACCESS_NONE	0
-#define PARTITION_ACCESS_R	1
-#define PARTITION_ACCESS_WO	2
-#define PARTITION_ACCESS_RW	3
-#define PARTITION_ACCESS_OW	4
-
-/* Logical Volume Descriptor (ECMA 167 3/10.6) */
-struct LogicalVolDesc {
-	tag descTag;
-	Uint32 volDescSeqNum;
-	charspec descCharSet;
-	dstring logicalVolIdent[128];
-	Uint32 logicalBlockSize;
-	EntityID domainIdent;
-	Uint8 logicalVolContentsUse[16]; /* used to find fileset */
-	Uint32 mapTableLength;
-	Uint32 numPartitionMaps;
-	EntityID impIdent;
-	Uint8 impUse[128];
-	extent_ad integritySeqExt;
-	Uint8 partitionMaps[0];
-};
-
-/* Generic Partition Map (ECMA 167 3/10.7.1) */
-struct GenericPartitionMap {
-	Uint8 partitionMapType;
-	Uint8 partitionMapLength;
-	Uint8 partitionMapping[0];
-};
-
-/* Partition Map Type (ECMA 167 3/10.7.1.1) */
-#define PARTITION_MAP_TYPE_NONE		0
-#define PARTITION_MAP_TYPE_1		1
-#define PARTITION_MAP_TYPE_2		2
-
-/* Type 1 Partition Map (ECMA 167 3/10.7.2) */
-struct GenericPartitionMap1 {
-	Uint8 partitionMapType;
-	Uint8 partitionMapLength;
-	Uint16 volSeqNum;
-	Uint16 partitionNum;
-};
-
-/* Type 2 Partition Map (ECMA 167 3/10.7.3) */
-struct GenericPartitionMap2 {
-	Uint8 partitionMapType; /* 2 */
-	Uint8 partitionMapLength; 
-	Uint8 partitionIdent[62];
-};
-
-/* Unallocated Space Descriptor (ECMA 167 3/10.8) */
-struct UnallocatedSpaceDesc {
-	tag descTag;
-	Uint32 volDescSeqNum;
-	Uint32 numAllocDescs;
-	extent_ad allocDescs[0];
-};
-
-/* Terminating Descriptor (ECMA 3/10.9) */
-struct TerminatingDesc {
-	tag descTag;
-	Uint8 reserved[496];
-};
-
-struct GenericDesc
-{
-        tag descTag;
-        Uint32 volDescSeqNum;
-};
-
-/* Logical Volume Integrity Descriptor (ECMA 167 3/10.10) */
-struct LogicalVolIntegrityDesc {
-	tag descTag;
-	timestamp recordingDateAndTime;
-	Uint32 integrityType;
-	extent_ad nextIntegrityExt;
-	Uint8 logicalVolContentsUse[32];
-	Uint32 numOfPartitions;
-	Uint32 lengthOfImpUse;
-	Uint32 freeSpaceTable[0];
-	Uint32 sizeTable[0];
-	Uint8 impUse[0];
-};
-
-/* Integrity Types (ECMA 167 3/10.10.3) */
-#define INTEGRITY_TYPE_OPEN	0
-#define INTEGRITY_TYPE_CLOSE	1
-
-/* Recorded Address (ECMA 167 4/7.1) */
-typedef struct {
-	Uint32 logicalBlockNum;
-	Uint16 partitionReferenceNum;
-} lb_addr;
-
-/* Extent interpretation (ECMA 167 4/14.14.1.1) */
-#define EXTENT_RECORDED_ALLOCATED               0x00
-#define EXTENT_NOT_RECORDED_ALLOCATED           0x01
-#define EXTENT_NOT_RECORDED_NOT_ALLOCATED       0x02
-#define EXTENT_NEXT_EXTENT_ALLOCDECS            0x03
-
-/* Long Allocation Descriptor (ECMA 167 4/14.14.2) */
-typedef struct {
-	Uint32 extLength;
-	lb_addr extLocation;
-	Uint8 impUse[6];
-} long_ad;
-	/* upper 2 bits of extLength indicate type */
-
-/* File Set Descriptor (ECMA 167 4/14.1) */
-struct FileSetDesc {
-	tag descTag;
-	timestamp recordingDateAndTime;
-	Uint16 interchangeLvl;
-	Uint16 maxInterchangeLvl;
-	Uint32 charSetList;
-	Uint32 maxCharSetList;
-	Uint32 fileSetNum;
-	Uint32 fileSetDescNum;
-	charspec logicalVolIdentCharSet;
-	dstring logicalVolIdent[128];
-	charspec fileSetCharSet;
-	dstring fileSetIdent[32];
-	dstring copyrightFileIdent[32];
-	dstring abstractFileIdent[32];
-	long_ad rootDirectoryICB;
-	EntityID domainIdent;
-	long_ad nextExt;
-	long_ad streamDirectoryICB;
-	Uint8 reserved[32];
-};
-
-/* Short Allocation Descriptor (ECMA 167 4/14.14.1) */
-typedef struct {
-	Uint32 extLength;
-	Uint32 extPosition;
-} short_ad;
-
-/* Partition Header Descriptor (ECMA 167 4/14.3) */
-struct PartitionHeaderDesc {
-	short_ad unallocatedSpaceTable;
-	short_ad unallocatedSpaceBitmap;
-	short_ad partitionIntegrityTable;
-	short_ad freedSpaceTable;
-	short_ad freedSpaceBitmap;
-	Uint8 reserved[88];
-};
-
-/* File Identifier Descriptor (ECMA 167 4/14.4) */
-struct FileIdentDesc
-{
-	tag descTag;
-	Uint16 fileVersionNum; /* 1 */
-	Uint8 fileCharacteristics;
-	Uint8 lengthFileIdent;
-	long_ad icb;
-	Uint16 lengthOfImpUse;
-	Uint8 impUse[0];
-	Uint8 fileIdent[0];
-	Uint8 padding[0];
-};
-
-/* File Characteristics (ECMA 167 4/14.4.3) */
-#define FILE_HIDDEN	1
-#define FILE_DIRECTORY	2
-#define FILE_DELETED	4
-#define FILE_PARENT	8
-#define FILE_METADATA	0x10 /* UDF 2.0 */
-
-/* Allocation Ext Descriptor (ECMA 167 4/14.5) */
-struct AllocExtDesc
-{
-	tag descTag;
-	Uint32 previousAllocExtLocation;
-	Uint32 lengthAllocDescs;
-};
-
-/* ICB Tag (ECMA 167 4/14.6) */
-typedef struct {
-	Uint32 priorRecordedNumDirectEntries;
-	Uint16 strategyType;
-	Uint16 strategyParameter;
-	Uint16 numEntries;
-	Uint8 reserved;
-	Uint8 fileType;
-	lb_addr parentICBLocation;
-	Uint16 flags;
-} icbtag;
-
-/* ICB File Type (ECMA 167 4/14.6.6) */
-#define FILE_TYPE_NONE		0x00U
-#define FILE_TYPE_UNALLOC	0x01U
-#define FILE_TYPE_INTEGRITY	0x02U
-#define FILE_TYPE_INDIRECT	0x03U
-#define FILE_TYPE_DIRECTORY	0x04U
-#define FILE_TYPE_REGULAR	0x05U
-#define FILE_TYPE_BLOCK		0x06U
-#define FILE_TYPE_CHAR		0x07U
-#define FILE_TYPE_EXTENDED	0x08U
-#define FILE_TYPE_FIFO		0x09U
-#define FILE_TYPE_SOCKET	0x0aU
-#define FILE_TYPE_TERMINAL	0x0bU
-#define FILE_TYPE_SYMLINK	0x0cU
-#define FILE_TYPE_STREAMDIR	0x0dU /* ECMA 167 4/13 */
-
-/* ICB Flags (ECMA 167 4/14.6.8) */
-#define ICB_FLAG_ALLOC_MASK	0x0007U
-#define ICB_FLAG_SORTED		0x0008U
-#define ICB_FLAG_NONRELOCATABLE	0x0010U
-#define ICB_FLAG_ARCHIVE	0x0020U
-#define ICB_FLAG_SETUID		0x0040U
-#define ICB_FLAG_SETGID		0x0080U
-#define ICB_FLAG_STICKY		0x0100U
-#define ICB_FLAG_CONTIGUOUS	0x0200U
-#define ICB_FLAG_SYSTEM		0x0400U
-#define ICB_FLAG_TRANSFORMED	0x0800U
-#define ICB_FLAG_MULTIVERSIONS	0x1000U
-
-/* ICB Flags Allocation type(ECMA 167 4/14.6.8) */
-#define ICB_FLAG_AD_SHORT	0
-#define ICB_FLAG_AD_LONG	1
-#define ICB_FLAG_AD_EXTENDED	2
-#define ICB_FLAG_AD_IN_ICB	3
-
-/* Indirect Entry (ECMA 167 4/14.7) */
-struct IndirectEntry {
-	tag descTag;
-	icbtag icbTag;
-	long_ad indirectICB;
-};
-
-/* Terminal Entry (ECMA 167 4/14.8) */
-struct TerminalEntry {
-	tag descTag;
-	icbtag icbTag;
-};
-
-/* File Entry (ECMA 167 4/14.9) */
-struct FileEntry {
-	tag			descTag;
-	icbtag		icbTag;
-	Uint32		uid;
-	Uint32		gid;
-	Uint32		permissions;
-	Uint16		fileLinkCount;
-	Uint8		recordFormat;
-	Uint8		recordDisplayAttr;
-	Uint32		recordLength;
-	Uint64		informationLength;
-	Uint64		logicalBlocksRecorded;
-	timestamp	accessTime;
-	timestamp	modificationTime;
-	timestamp	attrTime;
-	Uint32		checkpoint;
-	long_ad		extendedAttrICB;
-	EntityID	impIdent;
-	Uint64		uniqueID; /* 0= root, 16- (2^32-1) */
-	Uint32		lengthExtendedAttr;
-	Uint32		lengthAllocDescs;
-	Uint8		extendedAttr[0];
-	Uint8		allocDescs[0];
-};
-
-/* File Permissions (ECMA 167 4/14.9.5) */
-#define PERM_O_EXEC	0x00000001U
-#define PERM_O_WRITE	0x00000002U
-#define PERM_O_READ	0x00000004U
-#define PERM_O_CHATTR	0x00000008U
-#define PERM_O_DELETE	0x00000010U
-#define PERM_G_EXEC	0x00000020U
-#define PERM_G_WRITE	0x00000040U
-#define PERM_G_READ	0x00000080U
-#define PERM_G_CHATTR	0x00000100U
-#define PERM_G_DELETE	0x00000200U
-#define PERM_U_EXEC	0x00000400U
-#define PERM_U_WRITE	0x00000800U
-#define PERM_U_READ	0x00001000U
-#define PERM_U_CHATTR	0x00002000U
-#define PERM_U_DELETE	0x00004000U
-
-/* File Record Format (ECMA 167 4/14.9.7) */
-#define RECORD_FMT_NONE			0
-#define RECORD_FMT_FIXED_PAD		1
-#define RECORD_FMT_FIXED		2
-#define RECORD_FMT_VARIABLE8		3
-#define RECORD_FMT_VARIABLE16		4
-#define RECORD_FMT_VARIABLE16_MSB	5
-#define RECORD_FMT_VARIABLE32		6
-#define RECORD_FMT_PRINT		7
-#define RECORD_FMT_LF			8
-#define RECORD_FMT_CR			9
-#define RECORD_FMT_CRLF			10
-#define RECORD_FMT_LFCR			10
-
-/* Extended Attribute Header Descriptor (ECMA 167 4/14.10.1) */
-struct ExtendedAttrHeaderDesc {
-	tag descTag;
-	Uint32 impAttrLocation;
-	Uint32 appAttrLocation;
-};
-
-/* Generic Attribute Format (ECMA 4/14.10.2) */
-struct GenericAttrFormat {
-	Uint32 attrType;
-	Uint8 attrSubtype;
-	Uint8 reserved[3];
-	Uint32 attrLength;
-	Uint8 attrData[0];
-};
-
-/* Character Set Attribute Format (ECMA 4/14.10.3) */
-struct CharSetAttrFormat {
-	Uint32 attrType;		/* 1 */
-	Uint8 attrSubtype;		/* 1 */
-	Uint8 reserved[3];
-	Uint32 attrLength;
-	Uint32 escapeSeqLength;
-	Uint8 charSetType;
-	Uint8 escapeSeq[0];
-};
-
-/* Alternate Permissions (ECMA 167 4/14.10.4) */
-struct AlternatePermissionsExtendedAttr {
-	Uint32 attrType;		/* 3 */
-	Uint8 attrSubtype;		/* 1 */
-	Uint8 reserved[3];
-	Uint32 attrLength;
-	Uint16 ownerIdent;
-	Uint16 groupIdent;
-	Uint16 permission;
-};
-
-/* File Times Extended Attribute (ECMA 167 4/14.10.5) */
-struct FileTimesExtendedAttr {
-	Uint32 attrType;		/* 5 */
-	Uint8 attrSubtype;		/* 1 */
-	Uint8 reserved[3];
-	Uint32 attrLength;
-	Uint32 dataLength;
-	Uint32 fileTimeExistence;
-	Uint8 fileTimes;
-};
-
-/* FileTimeExistence (ECMA 167 4/14.10.5.6) */
-#define FTE_CREATION	0
-#define FTE_DELETION	2
-#define FTE_EFFECTIVE	3
-#define FTE_BACKUP	5
-
-/* Information Times Extended Attribute (ECMA 167 4/14.10.6) */
-struct InfoTimesExtendedAttr {
-	Uint32 attrType;		/* 6 */
-	Uint8 attrSubtype;		/* 1 */
-	Uint8 reserved[3];
-	Uint32 attrLength;
-	Uint32 dataLength;
-	Uint32 infoTimeExistence;
-	Uint8 infoTimes[0];
-};
-
-/* Device Specification Extended Attribute (ECMA 167 4/14.10.7) */
-struct DeviceSpecificationExtendedAttr {
-	Uint32 attrType;		/* 12 */
-	Uint8 attrSubtype;		/* 1 */
-	Uint8 reserved[3];
-	Uint32 attrLength;
-	Uint32 impUseLength;
-	Uint32 majorDeviceIdent;
-	Uint32 minorDeviceIdent;
-	Uint8 impUse[0];
-};
-
-/* Implementation Use Extended Attr (ECMA 167 4/14.10.8) */
-struct ImpUseExtendedAttr {
-	Uint32 attrType;		/* 2048 */
-	Uint8 attrSubtype;		/* 1 */
-	Uint8 reserved[3];
-	Uint32 attrLength;
-	Uint32 impUseLength;
-	EntityID impIdent;
-	Uint8 impUse[0];
-};
-
-/* Application Use Extended Attribute (ECMA 167 4/14.10.9) */
-struct AppUseExtendedAttr {
-	Uint32 attrType;		/* 65536 */
-	Uint8 attrSubtype;		/* 1 */
-	Uint8 reserved[3];
-	Uint32 attrLength;
-	Uint32 appUseLength;
-	EntityID appIdent;
-	Uint8 appUse[0];
-};
-
-#define EXTATTR_CHAR_SET	1
-#define EXTATTR_ALT_PERMS	3
-#define EXTATTR_FILE_TIMES	5
-#define EXTATTR_INFO_TIMES	6
-#define EXTATTR_DEV_SPEC	12
-#define EXTATTR_IMP_USE		2048
-#define EXTATTR_APP_USE		65536
-
-
-/* Unallocated Space Entry (ECMA 167 4/14.11) */
-struct UnallocatedSpaceEntry {
-	tag descTag;
-	icbtag icbTag;
-	Uint32 lengthAllocDescs;
-	Uint8 allocDescs[0];
-};
-
-/* Space Bitmap Descriptor (ECMA 167 4/14.12) */
-struct SpaceBitmapDesc {
-	tag descTag;
-	Uint32 numOfBits;
-	Uint32 numOfBytes;
-	Uint8 bitmap[0];
-};
-
-/* Partition Integrity Entry (ECMA 167 4/14.13) */
-struct PartitionIntegrityEntry {
-	tag descTag;
-	icbtag icbTag;
-	timestamp recordingDateAndTime;
-	Uint8 integrityType;
-	Uint8 reserved[175];
-	EntityID impIdent;
-	Uint8 impUse[256];
-};
-
-/* Extended Allocation Descriptor (ECMA 167 4/14.14.3) */
-typedef struct { /* ECMA 167 4/14.14.3 */
-	Uint32 extLength;
-	Uint32 recordedLength;
-	Uint32 informationLength;
-	lb_addr extLocation;
-} ext_ad;
-
-/* Logical Volume Header Descriptor (ECMA 167 4/14.5) */
-struct LogicalVolHeaderDesc {
-	Uint64 uniqueID;
-	Uint8 reserved[24];
-};
-
-/* Path Component (ECMA 167 4/14.16.1) */
-struct PathComponent {
-	Uint8 componentType;
-	Uint8 lengthComponentIdent;
-	Uint16 componentFileVersionNum;
-	dstring componentIdent[0];
-};
-
-/* File Entry (ECMA 167 4/14.17) */
-struct ExtendedFileEntry {
-	tag			descTag;
-	icbtag		icbTag;
-	Uint32		uid;
-	Uint32		gid;
-	Uint32		permissions;
-	Uint16		fileLinkCount;
-	Uint8		recordFormat;
-	Uint8		recordDisplayAttr;
-	Uint32		recordLength;
-	Uint64		informationLength;
-	Uint64		objectSize;
-	Uint64		logicalBlocksRecorded;
-	timestamp	accessTime;
-	timestamp	modificationTime;
-	timestamp	createTime;
-	timestamp	attrTime;
-	Uint32		checkpoint;
-	Uint32		reserved;
-	long_ad		extendedAttrICB;
-	long_ad		streamDirectoryICB;
-	EntityID	impIdent;
-	Uint64		uniqueID;
-	Uint32		lengthExtendedAttr;
-	Uint32		lengthAllocDescs;
-	Uint8		extendedAttr[0];
-	Uint8		allocDescs[0];
-};
-#pragma pack()
-
-#endif /* !defined(_LINUX_UDF_167_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/udf_fs.h linux/include/linux/udf_fs.h
--- linux.orig/include/linux/udf_fs.h	2001-10-11 15:59:24.000000000 +0000
+++ linux/include/linux/udf_fs.h	2002-07-20 01:08:27.000000000 +0000
@@ -30,15 +30,16 @@
  * HISTORY
  *
  */
+#include <linux/config.h>
 
-#if !defined(_LINUX_UDF_FS_H)
-#define _LINUX_UDF_FS_H
+#ifndef _UDF_FS_H
+#define _UDF_FS_H 1
 
 #define UDF_PREALLOCATE
 #define UDF_DEFAULT_PREALLOC_BLOCKS	8
 
-#define UDFFS_DATE			"2001/10/10"
-#define UDFFS_VERSION			"0.9.5"
+#define UDFFS_DATE			"2002/03/11"
+#define UDFFS_VERSION			"0.9.6"
 
 #if !defined(UDFFS_RW)
 
@@ -66,4 +67,4 @@
 #define udf_info(f, a...) \
 		printk (KERN_INFO "UDF-fs INFO " f, ##a);
 
-#endif /* !defined(_LINUX_UDF_FS_H) */
+#endif /* _UDF_FS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/udf_fs_i.h linux/include/linux/udf_fs_i.h
--- linux.orig/include/linux/udf_fs_i.h	2001-07-02 21:10:02.000000000 +0000
+++ linux/include/linux/udf_fs_i.h	2002-07-20 01:08:24.000000000 +0000
@@ -15,17 +15,17 @@
  *	Each contributing author retains all rights to their own work.
  */
 
-#if !defined(_LINUX_UDF_FS_I_H)
-#define _LINUX_UDF_FS_I_H
+#ifndef _UDF_FS_I_H
+#define _UDF_FS_I_H 1
 
 #ifdef __KERNEL__
 
-#ifndef _LINUX_UDF_167_H
+#ifndef _ECMA_167_H
 typedef struct
 {
 	__u32 logicalBlockNum;
 	__u16 partitionReferenceNum;
-} lb_addr;
+} __attribute__ ((packed)) lb_addr;
 #endif
 
 struct udf_inode_info
@@ -58,4 +58,4 @@
 #define UDF_GETVOLIDENT _IOR('l', 0x42, void *)
 #define UDF_RELOCATE_BLOCKS _IOWR('l', 0x43, long)
 
-#endif /* !defined(_LINUX_UDF_FS_I_H) */
+#endif /* _UDF_FS_I_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/udf_fs_sb.h linux/include/linux/udf_fs_sb.h
--- linux.orig/include/linux/udf_fs_sb.h	2001-10-11 15:59:24.000000000 +0000
+++ linux/include/linux/udf_fs_sb.h	2002-07-20 01:08:33.000000000 +0000
@@ -15,8 +15,8 @@
  *	Each contributing author retains all rights to their own work.
  */
 
-#if !defined(_LINUX_UDF_FS_SB_H)
-#define _LINUX_UDF_FS_SB_H
+#ifndef _UDF_FS_SB_H
+#define _UDF_FS_SB_H 1
 
 #pragma pack(1)
 
@@ -115,4 +115,4 @@
 	struct inode		*s_vat;
 };
 
-#endif /* !defined(_LINUX_UDF_FS_SB_H) */
+#endif /* _UDF_FS_SB_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/udf_udf.h linux/include/linux/udf_udf.h
--- linux.orig/include/linux/udf_udf.h	2001-07-02 21:10:02.000000000 +0000
+++ linux/include/linux/udf_udf.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,231 +0,0 @@
-#if !defined(_LINUX_UDF_UDF_H)
-#define _LINUX_UDF_UDF_H
-/*
- * udf_udf.h
- *
- * PURPOSE
- *	OSTA-UDF(tm) format specification [based on ECMA 167 standard].
- *	http://www.osta.org/
- *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
- * COPYRIGHT
- *	This file is distributed under the terms of the GNU General Public
- *	License (GPL). Copies of the GPL can be obtained from:
- *		ftp://prep.ai.mit.edu/pub/gnu/GPL
- *	Each contributing author retains all rights to their own work.
- *
- * HISTORY
- *	July 1, 1997 - Andrew E. Mileski
- *	Written, tested, and released.
- *
- * 10/2/98 dgb	changed UDF_ID_DEVELOPER
- * 11/26/98 bf  changed UDF_ID_DEVELOPER, 
- * 12/5/98 dgb  updated include file hierarchy, more UDF definitions
- */
-
-/* based on ECMA 167 structure definitions */
-#include <linux/udf_167.h>
-
-#pragma pack(1)
-
-/* -------- Basic types and constants ----------- */
-/* UDF character set (UDF 1.50 2.1.2) */
-#define UDF_CHAR_SET_TYPE	0
-#define UDF_CHAR_SET_INFO	"OSTA Compressed Unicode"
-
-#define UDF_ID_DEVELOPER	"*Linux UDFFS"
- 
-/* UDF 1.02 2.2.6.4 */
-struct LogicalVolIntegrityDescImpUse
-{
-	EntityID	impIdent;
-	Uint32		numFiles;
-	Uint32		numDirs;
-	Uint16		minUDFReadRev;
-	Uint16		minUDFWriteRev;
-	Uint16		maxUDFWriteRev;
-};
-
-/* UDF 1.02 2.2.7.2 */
-/* LVInformation may be present in ImpUseVolDesc.impUse */
-struct ImpUseVolDescImpUse
-{
-	charspec	LVICharset;
-	dstring		logicalVolIdent[128];
-	dstring		LVInfo1[36];
-	dstring		LVInfo2[36];
-	dstring		LVInfo3[36];
-	EntityID	impIdent;
-	Uint8		impUse[128];
-};
-
-struct UdfPartitionMap2
-{
-        Uint8           partitionMapType;
-        Uint8           partitionMapLength;
-        Uint8           reserved1[2];
-        EntityID        partIdent;
-        Uint16          volSeqNum;
-        Uint16          partitionNum;
-        Uint8           reserved2[24];
-};
-
-/* UDF 1.5 2.2.8 */
-struct VirtualPartitionMap
-{
-	Uint8		partitionMapType;	/* 2 */
-	Uint8		partitionMapLength;	/* 64 */
-	Uint8		reserved1[2];		/* #00 */
-	EntityID	partIdent;
-	Uint16		volSeqNum;
-	Uint16		partitionNum;
-	Uint8		reserved2[24];		/* #00 */
-};
-
-/* UDF 1.5 2.2.9 */
-struct SparablePartitionMap
-{
-	Uint8		partitionMapType;	/* 2 */
-	Uint8		partitionMapLength;	/* 64 */
-	Uint8		reserved1[2];		/* #00 */
-	EntityID	partIdent;		/* Flags = 0 */
-						/* Id = UDF_ID_SPARABLE */
-						/* IdSuf = 2.1.5.3 */
-	Uint16		volSeqNum;
-	Uint16		partitionNum;
-	Uint16		packetLength;		/* 32 */
-	Uint8		numSparingTables;
-	Uint8		reserved2[1];		/* #00 */
-	Uint32		sizeSparingTable;
-	Uint32		locSparingTable[4];
-};
- 
-/* DVD Copyright Management Info, see UDF 1.02 3.3.4.5.1.2 */
-/* when ImpUseExtendedAttr.impIdent= "*UDF DVD CGMS Info" */
-struct DVDCopyrightImpUse {
-	Uint16 headerChecksum;
-	Uint8  CGMSInfo;
-	Uint8  dataType;
-	Uint8  protectionSystemInfo[4];
-};
-
-/* the impUse of long_ad used in AllocDescs  - UDF 1.02 2.3.10.1 */
-struct ADImpUse
-{
-	Uint16 flags;
-	Uint8  impUse[4];
-};
-
-/* UDF 1.02 2.3.10.1 */
-#define UDF_EXTENT_LENGTH_MASK		0x3FFFFFFF
-#define UDF_EXTENT_FLAG_MASK		0xc0000000
-#define UDF_EXTENT_FLAG_ERASED		0x40000000
-
-/* 
- * Important!  VirtualAllocationTables are 
- * very different between 1.5 and 2.0!
- */
-
-/* ----------- 1.5 ------------- */
-/* UDF 1.5 2.2.10 */
-#define FILE_TYPE_VAT15		0x0U
-
-/* UDF 1.5 2.2.10 - VAT layout: */
-struct VirutalAllocationTable15 {
-	Uint32 VirtualSector[0];
-	EntityID	ident;
-	Uint32	previousVATICB;
-   };  
-/* where number of VirtualSector's is (VATSize-36)/4 */
-
-/* ----------- 2.0 ------------- */
-/* UDF 2.0 2.2.10 */
-#define FILE_TYPE_VAT20		0xf8U
-
-/* UDF 2.0 2.2.10 (different from 1.5!) */
-struct VirtualAllocationTable20 {
-	Uint16 lengthHeader;
-	Uint16 lengthImpUse;
-	dstring logicalVolIdent[128];
-	Uint32	previousVatICBLoc;
-	Uint32  numFIDSFiles;
-	Uint32  numFIDSDirectories; /* non-parent */
-	Uint16  minReadRevision;
-	Uint16	minWriteRevision;
-	Uint16  maxWriteRevision;
-	Uint16  reserved;
-	Uint8	impUse[0];
-	Uint32  vatEntry[0];
-};
-
-/* ----------- 2.01 ------------- */
-/* UDF 2.01 6.11 */
-#define FILE_TYPE_REALTIME	0xf9U
-
-/* Sparing maps, see UDF 1.5 2.2.11 */
-typedef struct {
-	Uint32  origLocation;
-	Uint32  mappedLocation;
-} SparingEntry;
-
-/* sparing maps, see UDF 2.0 2.2.11 */
-struct SparingTable {
-	tag 	descTag;
-	EntityID sparingIdent; /* *UDF Sparing Table */
-	Uint16   reallocationTableLen;
-	Uint16   reserved;	/* #00 */
-	Uint32   sequenceNum;
-	SparingEntry mapEntry[0];
-};
-
-/* Entity Identifiers (UDF 1.50 6.1) */
-#define	UDF_ID_COMPLIANT	"*OSTA UDF Compliant"
-#define UDF_ID_LV_INFO		"*UDF LV Info"
-#define UDF_ID_FREE_EA		"*UDF FreeEASpace"
-#define UDF_ID_FREE_APP_EA	"*UDF FreeAppEASpace"
-#define UDF_ID_DVD_CGMS		"*UDF DVD CGMS Info"
-#define UDF_ID_OS2_EA		"*UDF OS/2 EA"
-#define UDF_ID_OS2_EA_LENGTH	"*UDF OS/2 EALength"
-#define UDF_ID_MAC_VOLUME	"*UDF Mac VolumeInfo"
-#define UDF_ID_MAC_FINDER	"*UDF Mac FinderInfo"
-#define UDF_ID_MAC_UNIQUE	"*UDF Mac UniqueIDTable"
-#define UDF_ID_MAC_RESOURCE	"*UDF Mac ResourceFork"
-#define UDF_ID_VIRTUAL		"*UDF Virtual Partition"
-#define UDF_ID_SPARABLE		"*UDF Sparable Partition"
-#define UDF_ID_ALLOC		"*UDF Virtual Alloc Tbl"
-#define UDF_ID_SPARING		"*UDF Sparing Table"
-
-/* Operating System Identifiers (UDF 1.50 6.3) */
-#define UDF_OS_CLASS_UNDEF	0x00U
-#define UDF_OS_CLASS_DOS	0x01U
-#define UDF_OS_CLASS_OS2	0x02U
-#define UDF_OS_CLASS_MAC	0x03U
-#define UDF_OS_CLASS_UNIX	0x04U
-#define UDF_OS_CLASS_WIN95	0x05U
-#define UDF_OS_CLASS_WINNT	0x06U
-#define UDF_OS_ID_UNDEF		0x00U
-#define UDF_OS_ID_DOS		0x00U
-#define UDF_OS_ID_OS2		0x00U
-#define UDF_OS_ID_MAC		0x00U
-#define UDF_OS_ID_UNIX		0x00U
-#define UDF_OS_ID_WIN95		0x00U
-#define UDF_OS_ID_WINNT		0x00U
-#define UDF_OS_ID_AIX		0x01U
-#define UDF_OS_ID_SOLARIS	0x02U
-#define UDF_OS_ID_HPUX		0x03U
-#define UDF_OS_ID_IRIX		0x04U
-#define UDF_OS_ID_LINUX		0x05U
-#define UDF_OS_ID_MKLINUX	0x06U
-#define UDF_OS_ID_FREEBSD	0x07U
-
-#define UDF_NAME_PAD	4
-#define UDF_NAME_LEN	255
-#define UDF_PATH_LEN	1023
-
-#pragma pack()
-
-#endif /* !defined(_LINUX_UDF_FMT_H) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/umem.h linux/include/linux/umem.h
--- linux.orig/include/linux/umem.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/linux/umem.h	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,130 @@
+
+/*
+ * This file contains defines for the
+ *   Micro Memory MM5415
+ * family PCI Memory Module with Battery Backup.
+ *
+ * Copyright Micro Memory INC 2001.  All rights reserved.
+ * Release under the terms of the GNU GENERAL PUBLIC LICENSE version 2.
+ * See the file COPYING.
+ */
+
+#ifndef _DRIVERS_BLOCK_MM_H
+#define _DRIVERS_BLOCK_MM_H
+
+
+#define IRQ_TIMEOUT (1 * HZ)
+
+/* CSR register definition */
+#define MEMCTRLSTATUS_MAGIC	0x00
+#define  MM_MAGIC_VALUE		(unsigned char)0x59
+
+#define MEMCTRLSTATUS_BATTERY	0x04
+#define  BATTERY_1_DISABLED	0x01
+#define  BATTERY_1_FAILURE	0x02
+#define  BATTERY_2_DISABLED	0x04
+#define  BATTERY_2_FAILURE	0x08
+
+#define MEMCTRLSTATUS_MEMORY	0x07
+#define  MEM_128_MB		0xfe
+#define  MEM_256_MB		0xfc
+#define  MEM_512_MB		0xf8
+#define  MEM_1_GB		0xf0
+#define  MEM_2_GB		0xe0
+
+#define MEMCTRLCMD_LEDCTRL	0x08
+#define  LED_REMOVE		2
+#define  LED_FAULT		4
+#define  LED_POWER		6
+#define	 LED_FLIP		255
+#define  LED_OFF		0x00
+#define  LED_ON			0x01
+#define  LED_FLASH_3_5		0x02
+#define  LED_FLASH_7_0		0x03
+#define  LED_POWER_ON		0x00
+#define  LED_POWER_OFF		0x01
+#define  USER_BIT1		0x01
+#define  USER_BIT2		0x02
+
+#define MEMORY_INITIALIZED	USER_BIT1
+
+#define MEMCTRLCMD_ERRCTRL	0x0C
+#define  EDC_NONE_DEFAULT	0x00
+#define  EDC_NONE		0x01
+#define  EDC_STORE_READ		0x02
+#define  EDC_STORE_CORRECT	0x03
+
+#define MEMCTRLCMD_ERRCNT	0x0D
+#define MEMCTRLCMD_ERRSTATUS	0x0E
+
+#define ERROR_DATA_LOG		0x20
+#define ERROR_ADDR_LOG		0x28
+#define ERROR_COUNT		0x3D
+#define ERROR_SYNDROME		0x3E
+#define ERROR_CHECK		0x3F
+
+#define DMA_PCI_ADDR		0x40
+#define DMA_LOCAL_ADDR		0x48
+#define DMA_TRANSFER_SIZE	0x50
+#define DMA_DESCRIPTOR_ADDR	0x58
+#define DMA_SEMAPHORE_ADDR	0x60
+#define DMA_STATUS_CTRL		0x68
+#define  DMASCR_GO		0x00001
+#define  DMASCR_TRANSFER_READ	0x00002
+#define  DMASCR_CHAIN_EN	0x00004
+#define  DMASCR_SEM_EN		0x00010
+#define  DMASCR_DMA_COMP_EN	0x00020
+#define  DMASCR_CHAIN_COMP_EN	0x00040
+#define  DMASCR_ERR_INT_EN	0x00080
+#define  DMASCR_PARITY_INT_EN	0x00100
+#define  DMASCR_ANY_ERR		0x00800
+#define  DMASCR_MBE_ERR		0x01000
+#define  DMASCR_PARITY_ERR_REP	0x02000
+#define  DMASCR_PARITY_ERR_DET	0x04000
+#define  DMASCR_SYSTEM_ERR_SIG	0x08000
+#define  DMASCR_TARGET_ABT	0x10000
+#define  DMASCR_MASTER_ABT	0x20000
+#define  DMASCR_DMA_COMPLETE	0x40000
+#define  DMASCR_CHAIN_COMPLETE	0x80000
+
+/* 
+3.SOME PCs HAVE HOST BRIDGES WHICH APPARENTLY DO NOT CORRECTLY HANDLE 
+READ-LINE (0xE) OR READ-MULTIPLE (0xC) PCI COMMAND CODES DURING DMA 
+TRANSFERS. IN OTHER SYSTEMS THESE COMMAND CODES WILL CAUSE THE HOST BRIDGE 
+TO ALLOW LONGER BURSTS DURING DMA READ OPERATIONS. THE UPPER FOUR BITS 
+(31..28) OF THE DMA CSR HAVE BEEN MADE PROGRAMMABLE, SO THAT EITHER A 0x6, 
+AN 0xE OR A 0xC CAN BE WRITTEN TO THEM TO SET THE COMMAND CODE USED DURING 
+DMA READ OPERATIONS.
+*/
+#define        DMASCR_READ   0x60000000
+#define        DMASCR_READLINE   0xE0000000
+#define        DMASCR_READMULTI   0xC0000000
+
+
+#define DMASCR_ERROR_MASK	(DMASCR_MASTER_ABT | DMASCR_TARGET_ABT | DMASCR_SYSTEM_ERR_SIG | DMASCR_PARITY_ERR_DET | DMASCR_MBE_ERR | DMASCR_ANY_ERR)
+#define DMASCR_HARD_ERROR	(DMASCR_MASTER_ABT | DMASCR_TARGET_ABT | DMASCR_SYSTEM_ERR_SIG | DMASCR_PARITY_ERR_DET | DMASCR_MBE_ERR)
+
+#define WINDOWMAP_WINNUM	0x7B
+
+#define DMA_READ_FROM_HOST 0
+#define DMA_WRITE_TO_HOST 1
+
+struct mm_dma_desc {
+	u64	pci_addr;
+	u64	local_addr;
+	u32	transfer_size;
+	u32	zero1;
+	u64	next_desc_addr;
+	u64	sem_addr;
+	u32	control_bits;
+	u32	zero2;
+
+	dma_addr_t data_dma_handle;
+
+	/* Copy of the bits */
+	u64	sem_control_bits;
+} __attribute__((aligned(8)));
+
+#define PCI_VENDOR_ID_MICRO_MEMORY		0x1332
+#define PCI_DEVICE_ID_MICRO_MEMORY_5415CN	0x5415
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/usb.h linux/include/linux/usb.h
--- linux.orig/include/linux/usb.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/linux/usb.h	2002-07-20 01:08:34.000000000 +0000
@@ -429,6 +429,8 @@
 #define USB_QUEUE_BULK          0x0010
 #define USB_NO_FSBR		0x0020
 #define USB_ZERO_PACKET         0x0040  // Finish bulk OUTs always with zero length packet
+#define URB_NO_INTERRUPT	0x0080	/* HINT: no non-error interrupt needed */
+					/* ... less overhead for QUEUE_BULK */
 #define USB_TIMEOUT_KILLED	0x1000	// only set by HCD!
 
 typedef struct
@@ -733,6 +735,22 @@
 	atomic_t refcnt;
 };
 
+/*
+ * As of USB 2.0, full/low speed devices are segregated into trees.
+ * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
+ * The other type grows from high speed hubs when they connect to
+ * full/low speed devices using "Transaction Translators" (TTs).
+ *
+ * TTs should only be known to the hub driver, and high speed bus
+ * drivers (only EHCI for now).  They affect periodic scheduling and
+ * sometimes control/bulk error recovery.
+ */
+struct usb_tt {
+	struct usb_device	*hub;	/* upstream highspeed hub */
+	int			multi;	/* true means one TT per port */
+};
+
+
 /* This is arbitrary.
  * From USB 2.0 spec Table 11-13, offset 7, a hub can
  * have up to 255 ports. The most yet reported is 10.
@@ -748,8 +766,8 @@
 		USB_SPEED_HIGH				/* usb 2.0 */
 	} speed;
 
-	struct usb_device *tt;		/* usb1.1 device on usb2.0 bus */
-	int ttport;			/* device/hub port on that tt */
+	struct usb_tt	*tt; 		/* low/full speed dev, highspeed hub */
+	int		ttport;		/* device port on that tt hub */
 
 	atomic_t refcnt;		/* Reference count */
 	struct semaphore serialize;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/videodev.h linux/include/linux/videodev.h
--- linux.orig/include/linux/videodev.h	2001-11-09 22:11:15.000000000 +0000
+++ linux/include/linux/videodev.h	2002-07-20 01:08:37.000000000 +0000
@@ -4,6 +4,18 @@
 #include <linux/types.h>
 #include <linux/version.h>
 
+#if 0
+/*
+ * v4l2 is still work-in-progress, integration planed for 2.5.x
+ *   v4l2 project homepage:   http://www.thedirks.org/v4l2/
+ *   patches available from:  http://bytesex.org/patches/
+ */ 
+# define HAVE_V4L2 1
+# include <linux/videodev2.h>
+#else
+# undef HAVE_V4L2
+#endif
+
 #ifdef __KERNEL__
 
 #include <linux/poll.h>
@@ -12,24 +24,30 @@
 struct video_device
 {
 	struct module *owner;
-	char name[32];
-	int type;
+     	char name[32];
+ 	int type;       /* v4l1 */
+ 	int type2;      /* v4l2 */
 	int hardware;
+	int minor;
 
+	/* old, obsolete interface -- dropped in 2.5.x, don't use it */
 	int (*open)(struct video_device *, int mode);
 	void (*close)(struct video_device *);
 	long (*read)(struct video_device *, char *, unsigned long, int noblock);
-	/* Do we need a write method ? */
 	long (*write)(struct video_device *, const char *, unsigned long, int noblock);
-#if LINUX_VERSION_CODE >= 0x020100
 	unsigned int (*poll)(struct video_device *, struct file *, poll_table *);
-#endif
 	int (*ioctl)(struct video_device *, unsigned int , void *);
 	int (*mmap)(struct video_device *, const char *, unsigned long);
-	int (*initialize)(struct video_device *);	
+	int (*initialize)(struct video_device *);       
+
+ 	/* new interface -- we will use file_operations directly
+ 	 * like soundcore does. */
+ 	struct file_operations *fops;
 	void *priv;		/* Used to be 'private' but that upsets C++ */
-	int busy;
-	int minor;
+
+	/* for videodev.c intenal usage -- don't touch */
+	int users;
+	struct semaphore lock;
 	devfs_handle_t devfs_handle;
 };
 
@@ -42,8 +60,15 @@
 #define VFL_TYPE_VTX		3
 
 extern void video_unregister_device(struct video_device *);
-#endif
+extern struct video_device* video_devdata(struct file*);
 
+extern int video_exclusive_open(struct inode *inode, struct file *file);
+extern int video_exclusive_release(struct inode *inode, struct file *file);
+extern int video_usercopy(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg,
+			  int (*func)(struct inode *inode, struct file *file,
+				      unsigned int cmd, void *arg));
+#endif /* __KERNEL__ */
 
 #define VID_TYPE_CAPTURE	1	/* Can capture */
 #define VID_TYPE_TUNER		2	/* Can tune */
@@ -149,6 +174,7 @@
 #define VIDEO_AUDIO_VOLUME	4
 #define VIDEO_AUDIO_BASS	8
 #define VIDEO_AUDIO_TREBLE	16	
+#define VIDEO_AUDIO_BALANCE	32
 	char    name[16];
 #define VIDEO_SOUND_MONO	1
 #define VIDEO_SOUND_STEREO	2
@@ -378,4 +404,10 @@
 #define VID_HARDWARE_MEYE	32	/* Sony Vaio MotionEye cameras */
 #define VID_HARDWARE_CPIA2	33
 
-#endif
+#endif /* __LINUX_VIDEODEV_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/wanrouter.h linux/include/linux/wanrouter.h
--- linux.orig/include/linux/wanrouter.h	2001-11-22 19:50:06.000000000 +0000
+++ linux/include/linux/wanrouter.h	2002-07-20 01:08:31.000000000 +0000
@@ -475,7 +475,6 @@
 
 #include <linux/fs.h>		/* support for device drivers */
 #include <linux/proc_fs.h>	/* proc filesystem pragmatics */
-#include <linux/inet.h>		/* in_aton(), in_ntoa() prototypes */
 #include <linux/netdevice.h>	/* support for network drivers */
 /*----------------------------------------------------------------------------
  * WAN device data space.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/wireless.h linux/include/linux/wireless.h
--- linux.orig/include/linux/wireless.h	2001-11-22 19:47:12.000000000 +0000
+++ linux/include/linux/wireless.h	2002-07-20 01:08:38.000000000 +0000
@@ -1,9 +1,10 @@
 /*
  * This file define a set of standard wireless extensions
  *
- * Version :	12	5.10.01
+ * Version :	13	6.12.01
  *
  * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
  */
 
 #ifndef _LINUX_WIRELESS_H
@@ -11,6 +12,8 @@
 
 /************************** DOCUMENTATION **************************/
 /*
+ * Initial APIs (1996 -> onward) :
+ * -----------------------------
  * Basically, the wireless extensions are for now a set of standard ioctl
  * call + /proc/net/wireless
  *
@@ -27,16 +30,27 @@
  * We have the list of command plus a structure descibing the
  * data exchanged...
  * Note that to add these ioctl, I was obliged to modify :
- *	net/core/dev.c (two place + add include)
- *	net/ipv4/af_inet.c (one place + add include)
+ *	# net/core/dev.c (two place + add include)
+ *	# net/ipv4/af_inet.c (one place + add include)
  *
  * /proc/net/wireless is a copy of /proc/net/dev.
  * We have a structure for data passed from the driver to /proc/net/wireless
  * Too add this, I've modified :
- *	net/core/dev.c (two other places)
- *	include/linux/netdevice.h (one place)
- *	include/linux/proc_fs.h (one place)
+ *	# net/core/dev.c (two other places)
+ *	# include/linux/netdevice.h (one place)
+ *	# include/linux/proc_fs.h (one place)
+ *
+ * New driver API (2001 -> onward) :
+ * -------------------------------
+ * This file is only concerned with the user space API and common definitions.
+ * The new driver API is defined and documented in :
+ *	# include/net/iw_handler.h
  *
+ * Note as well that /proc/net/wireless implementation has now moved in :
+ *	# include/linux/wireless.c
+ *
+ * Other comments :
+ * --------------
  * Do not add here things that are redundant with other mechanisms
  * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
  * wireless specific.
@@ -54,16 +68,14 @@
 #include <linux/socket.h>		/* for "struct sockaddr" et al	*/
 #include <linux/if.h>			/* for IFNAMSIZ and co... */
 
-/**************************** CONSTANTS ****************************/
-
-/* --------------------------- VERSION --------------------------- */
+/***************************** VERSION *****************************/
 /*
  * This constant is used to know the availability of the wireless
  * extensions and to know which version of wireless extensions it is
  * (there is some stuff that will be added in the future...)
  * I just plan to increment with each new version.
  */
-#define WIRELESS_EXT	12
+#define WIRELESS_EXT	13
 
 /*
  * Changes :
@@ -123,12 +135,20 @@
  *	- Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
  *	- Add new statistics (frag, retry, beacon)
  *	- Add average quality (for user space calibration)
+ *
+ * V12 to V13
+ * ----------
+ *	- Document creation of new driver API.
+ *	- Extract union iwreq_data from struct iwreq (for new driver API).
+ *	- Rename SIOCSIWNAME as SIOCSIWCOMMIT
  */
 
+/**************************** CONSTANTS ****************************/
+
 /* -------------------------- IOCTL LIST -------------------------- */
 
 /* Basic operations */
-#define SIOCSIWNAME	0x8B00		/* Unused */
+#define SIOCSIWCOMMIT	0x8B00		/* Commit pending changes to driver */
 #define SIOCGIWNAME	0x8B01		/* get name == wireless protocol */
 #define SIOCSIWNWID	0x8B02		/* set network id (the cell) */
 #define SIOCGIWNWID	0x8B03		/* get network id */
@@ -414,13 +434,49 @@
 
 /* ------------------------ IOCTL REQUEST ------------------------ */
 /*
+ * This structure defines the payload of an ioctl, and is used 
+ * below.
+ *
+ * Note that this structure should fit on the memory footprint
+ * of iwreq (which is the same as ifreq), which mean a max size of
+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ * You should check this when increasing the structures defined
+ * above in this file...
+ */
+union	iwreq_data
+{
+	/* Config - generic */
+	char		name[IFNAMSIZ];
+	/* Name : used to verify the presence of  wireless extensions.
+	 * Name of the protocol/provider... */
+
+	struct iw_point	essid;		/* Extended network name */
+	struct iw_param	nwid;		/* network id (or domain - the cell) */
+	struct iw_freq	freq;		/* frequency or channel :
+					 * 0-1000 = channel
+					 * > 1000 = frequency in Hz */
+
+	struct iw_param	sens;		/* signal level threshold */
+	struct iw_param	bitrate;	/* default bit rate */
+	struct iw_param	txpower;	/* default transmit power */
+	struct iw_param	rts;		/* RTS threshold threshold */
+	struct iw_param	frag;		/* Fragmentation threshold */
+	__u32		mode;		/* Operation mode */
+	struct iw_param	retry;		/* Retry limits & lifetime */
+
+	struct iw_point	encoding;	/* Encoding stuff : tokens */
+	struct iw_param	power;		/* PM duration/timeout */
+
+	struct sockaddr	ap_addr;	/* Access point address */
+
+	struct iw_point	data;		/* Other large parameters */
+};
+
+/*
  * The structure to exchange data for ioctl.
  * This structure is the same as 'struct ifreq', but (re)defined for
  * convenience...
- *
- * Note that it should fit on the same memory footprint !
- * You should check this when increasing the above structures (16 octets)
- * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ * Do I need to remind you about structure size (32 octets) ?
  */
 struct	iwreq 
 {
@@ -429,35 +485,8 @@
 		char	ifrn_name[IFNAMSIZ];	/* if name, e.g. "eth0" */
 	} ifr_ifrn;
 
-	/* Data part */
-	union
-	{
-		/* Config - generic */
-		char		name[IFNAMSIZ];
-		/* Name : used to verify the presence of  wireless extensions.
-		 * Name of the protocol/provider... */
-
-		struct iw_point	essid;	/* Extended network name */
-		struct iw_param	nwid;	/* network id (or domain - the cell) */
-		struct iw_freq	freq;	/* frequency or channel :
-					 * 0-1000 = channel
-					 * > 1000 = frequency in Hz */
-
-		struct iw_param	sens;		/* signal level threshold */
-		struct iw_param	bitrate;	/* default bit rate */
-		struct iw_param	txpower;	/* default transmit power */
-		struct iw_param	rts;		/* RTS threshold threshold */
-		struct iw_param	frag;		/* Fragmentation threshold */
-		__u32		mode;		/* Operation mode */
-		struct iw_param	retry;		/* Retry limits & lifetime */
-
-		struct iw_point	encoding;	/* Encoding stuff : tokens */
-		struct iw_param	power;		/* PM duration/timeout */
-
-		struct sockaddr	ap_addr;	/* Access point address */
-
-		struct iw_point	data;		/* Other large parameters */
-	}	u;
+	/* Data part (defined just above) */
+	union	iwreq_data	u;
 };
 
 /* -------------------------- IOCTL DATA -------------------------- */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/linux/zorro.h linux/include/linux/zorro.h
--- linux.orig/include/linux/zorro.h	2001-11-22 19:46:17.000000000 +0000
+++ linux/include/linux/zorro.h	2002-07-20 01:08:21.000000000 +0000
@@ -155,6 +155,8 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 
+#include <asm/zorro.h>
+
 struct zorro_dev {
     struct ExpansionRom rom;
     zorro_id id;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/math-emu/op-1.h linux/include/math-emu/op-1.h
--- linux.orig/include/math-emu/op-1.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/math-emu/op-1.h	2002-07-20 01:08:28.000000000 +0000
@@ -25,7 +25,7 @@
 #ifndef    __MATH_EMU_OP_1_H__
 #define    __MATH_EMU_OP_1_H__
 
-#define _FP_FRAC_DECL_1(X)	_FP_W_TYPE X##_f
+#define _FP_FRAC_DECL_1(X)	_FP_W_TYPE X##_f=0
 #define _FP_FRAC_COPY_1(D,S)	(D##_f = S##_f)
 #define _FP_FRAC_SET_1(X,I)	(X##_f = I)
 #define _FP_FRAC_HIGH_1(X)	(X##_f)
@@ -58,6 +58,7 @@
 #define _FP_FRAC_NEGP_1(X)	((_FP_WS_TYPE)X##_f < 0)
 #define _FP_FRAC_ZEROP_1(X)	(X##_f == 0)
 #define _FP_FRAC_OVERP_1(fs,X)	(X##_f & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_1(fs,X)	(X##_f &= ~_FP_OVERFLOW_##fs)
 #define _FP_FRAC_EQ_1(X, Y)	(X##_f == Y##_f)
 #define _FP_FRAC_GE_1(X, Y)	(X##_f >= Y##_f)
 #define _FP_FRAC_GT_1(X, Y)	(X##_f > Y##_f)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/math-emu/op-2.h linux/include/math-emu/op-2.h
--- linux.orig/include/math-emu/op-2.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/math-emu/op-2.h	2002-07-20 01:08:24.000000000 +0000
@@ -114,6 +114,7 @@
 #define _FP_FRAC_NEGP_2(X)	((_FP_WS_TYPE)X##_f1 < 0)
 #define _FP_FRAC_ZEROP_2(X)	((X##_f1 | X##_f0) == 0)
 #define _FP_FRAC_OVERP_2(fs,X)	(_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_2(fs,X)	(_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
 #define _FP_FRAC_EQ_2(X, Y)	(X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
 #define _FP_FRAC_GT_2(X, Y)	\
   (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/math-emu/op-4.h linux/include/math-emu/op-4.h
--- linux.orig/include/math-emu/op-4.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/math-emu/op-4.h	2002-07-20 01:08:32.000000000 +0000
@@ -132,6 +132,7 @@
 #define _FP_FRAC_ZEROP_4(X)     ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
 #define _FP_FRAC_NEGP_4(X)      ((_FP_WS_TYPE)X##_f[3] < 0)
 #define _FP_FRAC_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
 
 #define _FP_FRAC_EQ_4(X,Y)				\
  (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1]		\
@@ -645,7 +646,7 @@
     X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);	\
     X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
     X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
-  } while (0);
+  } while (0)
 
 #define _FP_FRAC_CONV_4_1(dfs, sfs, D, S)				\
    do {									\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/math-emu/op-common.h linux/include/math-emu/op-common.h
--- linux.orig/include/math-emu/op-common.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/math-emu/op-common.h	2002-07-20 01:08:33.000000000 +0000
@@ -25,7 +25,7 @@
 #define __MATH_EMU_OP_COMMON_H__
 
 #define _FP_DECL(wc, X)			\
-  _FP_I_TYPE X##_c, X##_s, X##_e;	\
+  _FP_I_TYPE X##_c=0, X##_s=0, X##_e=0;	\
   _FP_FRAC_DECL_##wc(X)
 
 /*
@@ -97,11 +97,10 @@
 	_FP_ROUND(wc, X);					\
 	if (_FP_FRAC_OVERP_##wc(fs, X))				\
 	  {							\
-	    _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1));		\
+	    _FP_FRAC_CLEAR_OVERP_##wc(fs, X);			\
 	    X##_e++;						\
 	  }							\
-	else							\
-	  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
+	_FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
 	if (X##_e >= _FP_EXPMAX_##fs)				\
 	  {							\
 	    /* overflow */					\
@@ -766,25 +765,27 @@
   do {									\
     if (r)								\
       {									\
+        unsigned rtype ur_;						\
 	X##_c = FP_CLS_NORMAL;						\
 									\
 	if ((X##_s = (r < 0)))						\
 	  r = -r;							\
 									\
+	ur_ = (unsigned rtype) r;					\
 	if (rsize <= _FP_W_TYPE_SIZE)					\
-	  __FP_CLZ(X##_e, r);						\
+	  __FP_CLZ(X##_e, ur_);						\
 	else								\
-	  __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), 	\
-		     (_FP_W_TYPE)r);					\
+	  __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), 	\
+		     (_FP_W_TYPE)ur_);					\
 	if (rsize < _FP_W_TYPE_SIZE)					\
 		X##_e -= (_FP_W_TYPE_SIZE - rsize);			\
 	X##_e = rsize - X##_e - 1;					\
 									\
 	if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)	\
-	  __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize);	\
-	r &= ~((rtype)1 << X##_e);					\
-	_FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize);	\
-	_FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));		\
+	  __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
+	_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);			\
+	if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0)			\
+	  _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));	\
       }									\
     else								\
       {									\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/math-emu/soft-fp.h linux/include/math-emu/soft-fp.h
--- linux.orig/include/math-emu/soft-fp.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/math-emu/soft-fp.h	2002-07-20 01:08:32.000000000 +0000
@@ -154,11 +154,11 @@
 
 #define _FP_CLS_COMBINE(x,y)	(((x) << 2) | (y))
 
-#include "op-1.h"
-#include "op-2.h"
-#include "op-4.h"
-#include "op-8.h"
-#include "op-common.h"
+#include <math-emu/op-1.h>
+#include <math-emu/op-2.h>
+#include <math-emu/op-4.h>
+#include <math-emu/op-8.h>
+#include <math-emu/op-common.h>
 
 /* Sigh.  Silly things longlong.h needs.  */
 #define UWtype		_FP_W_TYPE
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/bluetooth.h linux/include/net/bluetooth/bluetooth.h
--- linux.orig/include/net/bluetooth/bluetooth.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/bluetooth.h	2002-07-20 01:08:34.000000000 +0000
@@ -23,7 +23,7 @@
 */
 
 /*
- *  $Id: bluetooth.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
+ *  $Id: bluetooth.h,v 1.9 2002/05/06 21:11:55 maxk Exp $
  */
 
 #ifndef __BLUETOOTH_H
@@ -31,17 +31,62 @@
 
 #include <asm/types.h>
 #include <asm/byteorder.h>
+#include <linux/poll.h>
+#include <net/sock.h>
 
 #ifndef AF_BLUETOOTH
 #define AF_BLUETOOTH	31
 #define PF_BLUETOOTH	AF_BLUETOOTH
 #endif
 
+/* Reserv for core and drivers use */
+#define BLUEZ_SKB_RESERVE       8
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
 #define BTPROTO_L2CAP   0
 #define BTPROTO_HCI     1
+#define BTPROTO_SCO   	2
+#define BTPROTO_RFCOMM	3
+#define BTPROTO_BNEP	4
 
 #define SOL_HCI     0
 #define SOL_L2CAP   6
+#define SOL_SCO     17
+#define SOL_RFCOMM  18
+
+/* Debugging */
+#ifdef CONFIG_BLUEZ_DEBUG
+
+#define HCI_CORE_DEBUG		1
+#define HCI_SOCK_DEBUG		1
+#define HCI_UART_DEBUG		1
+#define HCI_USB_DEBUG		1
+//#define HCI_DATA_DUMP		1
+
+#define L2CAP_DEBUG		1
+#define SCO_DEBUG		1
+#define AF_BLUETOOTH_DEBUG	1
+
+#endif /* CONFIG_BLUEZ_DEBUG */
+
+extern void bluez_dump(char *pref, __u8 *buf, int count);
+
+#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95
+#define __func__ __FUNCTION__
+#endif
+
+#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
+#define BT_DBG(fmt, arg...)  printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
+#define BT_ERR(fmt, arg...)  printk(KERN_ERR  "%s: " fmt "\n" , __func__ , ## arg)
+
+#ifdef HCI_DATA_DUMP
+#define BT_DMP(buf, len)    bluez_dump(__func__, buf, len)
+#else
+#define BT_DMP(D...)
+#endif
 
 /* Connection and socket states */
 enum {
@@ -50,6 +95,7 @@
 	BT_BOUND,
 	BT_LISTEN,
 	BT_CONNECT,
+	BT_CONNECT2,
 	BT_CONFIG,
 	BT_DISCONN,
 	BT_CLOSED
@@ -66,7 +112,8 @@
 	__u8 b[6];
 } __attribute__((packed)) bdaddr_t;
 
-#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
+#define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
+#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
 
 /* Copy, swap, convert BD Address */
 static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
@@ -82,6 +129,91 @@
 char *batostr(bdaddr_t *ba);
 bdaddr_t *strtoba(char *str);
 
+/* Common socket structures and functions */
+
+#define bluez_pi(sk) ((struct bluez_pinfo *) &sk->protinfo)
+#define bluez_sk(pi) ((struct sock *) \
+	((void *)pi - (unsigned long)(&((struct sock *)0)->protinfo)))
+
+struct bluez_pinfo {
+	bdaddr_t	src;
+	bdaddr_t	dst;
+
+	struct list_head accept_q;
+	struct sock *parent;
+};
+
+struct bluez_sock_list {
+	struct sock *head;
+	rwlock_t     lock;
+};
+
+int  bluez_sock_register(int proto, struct net_proto_family *ops);
+int  bluez_sock_unregister(int proto);
+void bluez_sock_init(struct socket *sock, struct sock *sk);
+void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
+void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
+int  bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm);
+uint bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
+int  bluez_sock_w4_connect(struct sock *sk, int flags);
+
+void bluez_accept_enqueue(struct sock *parent, struct sock *sk);
+struct sock * bluez_accept_dequeue(struct sock *parent, struct socket *newsock);
+
+/* Skb helpers */
+struct bluez_skb_cb {
+	int    incomming;
+};
+#define bluez_cb(skb)	((struct bluez_skb_cb *)(skb->cb)) 
+
+static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
+{
+	struct sk_buff *skb;
+
+	if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
+		skb_reserve(skb, BLUEZ_SKB_RESERVE);
+		bluez_cb(skb)->incomming  = 0;
+	}
+	return skb;
+}
+
+static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len, 
+						       int nb, int *err)
+{
+	struct sk_buff *skb;
+
+	if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
+		skb_reserve(skb, BLUEZ_SKB_RESERVE);
+		bluez_cb(skb)->incomming  = 0;
+	}
+
+	return skb;
+}
+
+static inline int skb_frags_no(struct sk_buff *skb)
+{
+	register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
+	register int n = 1;
+
+	for (; frag; frag=frag->next, n++);
+	return n;
+}
+
+int hci_core_init(void);
+int hci_core_cleanup(void);
+int hci_sock_init(void);
+int hci_sock_cleanup(void);
+
 int bterr(__u16 code);
 
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(x)
+#endif
+
+#ifndef list_for_each_safe
+#define list_for_each_safe(pos, n, head) \
+	for (pos = (head)->next, n = pos->next; pos != (head); \
+		pos = n, n = pos->next)
+#endif
+
 #endif /* __BLUETOOTH_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/bluez.h linux/include/net/bluetooth/bluez.h
--- linux.orig/include/net/bluetooth/bluez.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/bluez.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,124 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- *  $Id: bluez.h,v 1.4 2001/08/03 04:19:49 maxk Exp $
- */
-
-#ifndef __IF_BLUEZ_H
-#define __IF_BLUEZ_H
-
-#include <net/sock.h>
-
-#define BLUEZ_MAX_PROTO 	2
-
-/* Reserv for core and drivers use */
-#define BLUEZ_SKB_RESERVE	8
-
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-/* Debugging */
-#ifdef BLUEZ_DEBUG
-
-#define HCI_CORE_DEBUG		1
-#define HCI_SOCK_DEBUG		1
-#define HCI_UART_DEBUG		1
-#define HCI_USB_DEBUG		1
-//#define HCI_DATA_DUMP		1
-
-#define L2CAP_DEBUG			1
-
-#endif /* BLUEZ_DEBUG */
-
-extern void bluez_dump(char *pref, __u8 *buf, int count);
-
-#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
-#define DBG(fmt, arg...) printk(KERN_INFO __FUNCTION__ ": " fmt "\n" , ## arg)
-#define ERR(fmt, arg...) printk(KERN_ERR  __FUNCTION__ ": " fmt "\n" , ## arg)
-
-#ifdef HCI_DATA_DUMP
-#define DMP(buf, len)    bluez_dump(__FUNCTION__, buf, len)
-#else
-#define DMP(D...)
-#endif
-
-/* ----- Sockets ------ */
-struct bluez_sock_list {
-	struct sock *head;
-	rwlock_t     lock;
-};
-
-extern int  bluez_sock_register(int proto, struct net_proto_family *ops);
-extern int  bluez_sock_unregister(int proto);
-
-extern void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
-extern void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
-
-/* ----- SKB helpers ----- */
-struct bluez_skb_cb {
-	int    incomming;
-};
-#define bluez_cb(skb)	((struct bluez_skb_cb *)(skb->cb)) 
-
-static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
-{
-	struct sk_buff *skb;
-
-	if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-		skb_reserve(skb, BLUEZ_SKB_RESERVE);
-		bluez_cb(skb)->incomming  = 0;
-	}
-	return skb;
-}
-
-static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len, 
-						       int nb, int *err)
-{
-	struct sk_buff *skb;
-
-	if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-		skb_reserve(skb, BLUEZ_SKB_RESERVE);
-		bluez_cb(skb)->incomming  = 0;
-	}
-
-	return skb;
-}
-
-static inline int skb_frags_no(struct sk_buff *skb)
-{
-	register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-	register int n = 1;
-
-	for (; frag; frag=frag->next, n++);
-	return n;
-}
-
-extern int hci_core_init(void);
-extern int hci_core_cleanup(void);
-extern int hci_sock_init(void);
-extern int hci_sock_cleanup(void);
-
-#endif /* __IF_BLUEZ_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/hci.h linux/include/net/bluetooth/hci.h
--- linux.orig/include/net/bluetooth/hci.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/hci.h	2002-07-20 01:08:32.000000000 +0000
@@ -23,16 +23,16 @@
 */
 
 /*
- *  $Id: hci.h,v 1.15 2001/08/05 06:02:15 maxk Exp $
+ *  $Id: hci.h,v 1.4 2002/04/18 22:26:15 maxk Exp $
  */
 
 #ifndef __HCI_H
 #define __HCI_H
 
-#include <asm/byteorder.h>
-
-#define HCI_MAX_DEV 	8
-#define HCI_MAX_FRAME_SIZE	2048
+#define HCI_MAX_ACL_SIZE	1024
+#define HCI_MAX_SCO_SIZE	255
+#define HCI_MAX_EVENT_SIZE	260
+#define HCI_MAX_FRAME_SIZE	(HCI_MAX_ACL_SIZE + 4)
 
 /* HCI dev events */
 #define HCI_DEV_REG	1
@@ -41,41 +41,54 @@
 #define HCI_DEV_DOWN	4
 
 /* HCI device types */
-#define HCI_UART 	0
+#define HCI_VHCI	0
 #define HCI_USB		1
-#define HCI_VHCI	2
-
-/* HCI device modes */
-#define HCI_NORMAL 	0x0001
-#define HCI_RAW		0x0002
-#define HCI_MODE_MASK   (HCI_NORMAL | HCI_RAW)
-#define HCI_SOCK	0x1000
-
-/* HCI device states */
-#define HCI_INIT	0x0010
-#define HCI_UP 		0x0020
-#define HCI_RUNNING	0x0040
+#define HCI_PCCARD	2
+#define HCI_UART 	3
+#define HCI_RS232 	4
 
 /* HCI device flags */
-#define HCI_PSCAN	0x0100
-#define HCI_ISCAN	0x0200
-#define HCI_AUTH	0x0400
+enum {
+	HCI_UP,
+	HCI_INIT,
+	HCI_RUNNING,
+
+	HCI_PSCAN,
+	HCI_ISCAN,
+	HCI_AUTH,
+	HCI_ENCRYPT,
+	HCI_INQUIRY,
 
-/* HCI Ioctl defines */
+	HCI_RAW
+};
+
+/* HCI ioctl defines */
 #define HCIDEVUP        _IOW('H', 201, int)
 #define HCIDEVDOWN      _IOW('H', 202, int)
 #define HCIDEVRESET     _IOW('H', 203, int)
-#define HCIRESETSTAT    _IOW('H', 204, int)
-#define HCIGETINFO      _IOR('H', 205, int)
-#define HCIGETDEVLIST   _IOR('H', 206, int)
-#define HCISETRAW       _IOW('H', 207, int)
-#define HCISETSCAN      _IOW('H', 208, int)
-#define HCISETAUTH      _IOW('H', 209, int)
-#define HCIINQUIRY      _IOR('H', 210, int)
-#define HCISETPTYPE     _IOW('H', 211, int)
+#define HCIDEVRESTAT    _IOW('H', 204, int)
+
+#define HCIGETDEVLIST   _IOR('H', 210, int)
+#define HCIGETDEVINFO   _IOR('H', 211, int)
 #define HCIGETCONNLIST  _IOR('H', 212, int)
+#define HCIGETCONNINFO  _IOR('H', 213, int)
 
-#ifndef __NO_HCI_DEFS
+#define HCISETRAW       _IOW('H', 220, int)
+#define HCISETSCAN      _IOW('H', 221, int)
+#define HCISETAUTH      _IOW('H', 222, int)
+#define HCISETENCRYPT   _IOW('H', 223, int)
+#define HCISETPTYPE     _IOW('H', 224, int)
+#define HCISETLINKPOL   _IOW('H', 225, int)
+#define HCISETLINKMODE  _IOW('H', 226, int)
+#define HCISETACLMTU    _IOW('H', 227, int)
+#define HCISETSCOMTU    _IOW('H', 228, int)
+
+#define HCIINQUIRY      _IOR('H', 240, int)
+
+/* HCI timeouts */
+#define HCI_CONN_TIMEOUT 	(HZ * 40)
+#define HCI_DISCONN_TIMEOUT 	(HZ * 2)
+#define HCI_CONN_IDLE_TIMEOUT	(HZ * 60)
 
 /* HCI Packet types */
 #define HCI_COMMAND_PKT		0x01
@@ -92,6 +105,13 @@
 #define HCI_DH3 	0x0800
 #define HCI_DH5 	0x8000
 
+#define HCI_HV1		0x0020
+#define HCI_HV2		0x0040
+#define HCI_HV3		0x0080
+
+#define SCO_PTYPE_MASK	(HCI_HV1 | HCI_HV2 | HCI_HV3)
+#define ACL_PTYPE_MASK	(~SCO_PTYPE_MASK)
+
 /* ACL flags */
 #define ACL_CONT		0x0001
 #define ACL_START		0x0002
@@ -125,6 +145,19 @@
 #define LMP_PSCHEME	0x02
 #define LMP_PCONTROL	0x04
 
+/* Link policies */
+#define HCI_LP_RSWITCH	0x0001
+#define HCI_LP_HOLD	0x0002
+#define HCI_LP_SNIFF	0x0004
+#define HCI_LP_PARK	0x0008
+
+/* Link mode */
+#define HCI_LM_ACCEPT	0x8000
+#define HCI_LM_MASTER	0x0001
+#define HCI_LM_AUTH	0x0002
+#define HCI_LM_ENCRYPT	0x0004
+#define HCI_LM_TRUSTED	0x0008
+
 /* -----  HCI Commands ----- */
 /* OGF & OCF values */
 
@@ -137,9 +170,10 @@
 	__u8  hci_ver;
 	__u16 hci_rev;
 	__u8  lmp_ver;
-	__u16 man_name;
-	__u16 lmp_sub;
+	__u16 manufacturer;
+	__u16 lmp_subver;
 } __attribute__ ((packed)) read_local_version_rp;
+#define READ_LOCAL_VERSION_RP_SIZE 9
 
 #define OCF_READ_LOCAL_FEATURES	0x0003
 typedef struct {
@@ -165,18 +199,24 @@
 /* Host Controller and Baseband */
 #define OGF_HOST_CTL	0x03
 #define OCF_RESET		0x0003
+#define OCF_READ_AUTH_ENABLE	0x001F
 #define OCF_WRITE_AUTH_ENABLE	0x0020
-	#define AUTH_DISABLED			0x00
-	#define AUTH_ENABLED			0x01
+	#define AUTH_DISABLED		0x00
+	#define AUTH_ENABLED		0x01
+
+#define OCF_READ_ENCRYPT_MODE	0x0021
+#define OCF_WRITE_ENCRYPT_MODE	0x0022
+	#define ENCRYPT_DISABLED	0x00
+	#define ENCRYPT_P2P		0x01
+	#define ENCRYPT_BOTH		0x02
 
 #define OCF_WRITE_CA_TIMEOUT  	0x0016	
 #define OCF_WRITE_PG_TIMEOUT  	0x0018
 
 #define OCF_WRITE_SCAN_ENABLE 	0x001A
-	#define SCANS_DISABLED		0x00
-	#define IS_ENA_PS_DIS		0x01
-	#define IS_DIS_PS_ENA		0x02
-	#define IS_ENA_PS_ENA		0x03
+	#define SCAN_DISABLED		0x00
+	#define SCAN_INQUIRY		0x01
+	#define SCAN_PAGE		0x02
 
 #define OCF_SET_EVENT_FLT	0x0005
 typedef struct {
@@ -226,9 +266,18 @@
 } __attribute__ ((packed)) write_class_of_dev_cp;
 #define WRITE_CLASS_OF_DEV_CP_SIZE 3
 
+#define OCF_HOST_BUFFER_SIZE	0x0033
+typedef struct {
+	__u16 	acl_mtu;
+	__u8 	sco_mtu;
+	__u16 	acl_max_pkt;
+	__u16	sco_max_pkt;
+} __attribute__ ((packed)) host_buffer_size_cp;
+#define HOST_BUFFER_SIZE_CP_SIZE 7
+
 /* Link Control */
 #define OGF_LINK_CTL	0x01 
-#define OCF_CREATE_CONN	0x0005
+#define OCF_CREATE_CONN		0x0005
 typedef struct {
 	bdaddr_t bdaddr;
 	__u16 	pkt_type;
@@ -246,6 +295,13 @@
 } __attribute__ ((packed)) accept_conn_req_cp;
 #define ACCEPT_CONN_REQ_CP_SIZE	7
 
+#define OCF_REJECT_CONN_REQ	0x000a
+typedef struct {
+	bdaddr_t bdaddr;
+	__u8 	reason;
+} __attribute__ ((packed)) reject_conn_req_cp;
+#define REJECT_CONN_REQ_CP_SIZE	7
+
 #define OCF_DISCONNECT	0x0006
 typedef struct {
 	__u16 	handle;
@@ -253,17 +309,134 @@
 } __attribute__ ((packed)) disconnect_cp;
 #define DISCONNECT_CP_SIZE 3
 
+#define OCF_ADD_SCO	0x0007
+typedef struct {
+	__u16 	handle;
+	__u16 	pkt_type;
+} __attribute__ ((packed)) add_sco_cp;
+#define ADD_SCO_CP_SIZE 4
+
 #define OCF_INQUIRY		0x0001
 typedef struct {
 	__u8 	lap[3];
-	__u8 	lenght;
+	__u8 	length;
 	__u8	num_rsp;
 } __attribute__ ((packed)) inquiry_cp;
 #define INQUIRY_CP_SIZE 5
 
-#define OGF_LINK_POLICY	 	0x02   /* Link Policy */
+typedef struct {
+	__u8     status;
+	bdaddr_t bdaddr;
+} __attribute__ ((packed)) status_bdaddr_rp;
+#define STATUS_BDADDR_RP_SIZE 7
+
+#define OCF_LINK_KEY_REPLY	0x000B
+#define OCF_LINK_KEY_NEG_REPLY	0x000C
+typedef struct {
+	bdaddr_t bdaddr;
+	__u8     link_key[16];
+} __attribute__ ((packed)) link_key_reply_cp;
+#define LINK_KEY_REPLY_CP_SIZE 22
+
+#define OCF_PIN_CODE_REPLY	0x000D
+#define OCF_PIN_CODE_NEG_REPLY	0x000E
+typedef struct {
+	bdaddr_t bdaddr;
+	__u8	 pin_len;
+	__u8	 pin_code[16];
+} __attribute__ ((packed)) pin_code_reply_cp;
+#define PIN_CODE_REPLY_CP_SIZE 23
+
+#define OCF_CHANGE_CONN_PTYPE	0x000F
+typedef struct {
+	__u16	 handle;
+	__u16	 pkt_type;
+} __attribute__ ((packed)) change_conn_ptype_cp;
+#define CHANGE_CONN_PTYPE_CP_SIZE 4
 
-/* --------- HCI Events --------- */
+#define OCF_AUTH_REQUESTED	0x0011
+typedef struct {
+	__u16	 handle;
+} __attribute__ ((packed)) auth_requested_cp;
+#define AUTH_REQUESTED_CP_SIZE 2
+
+#define OCF_SET_CONN_ENCRYPT	0x0013
+typedef struct {
+	__u16	 handle;
+	__u8	 encrypt;
+} __attribute__ ((packed)) set_conn_encrypt_cp;
+#define SET_CONN_ENCRYPT_CP_SIZE 3
+
+#define OCF_REMOTE_NAME_REQ	0x0019
+typedef struct {
+	bdaddr_t bdaddr;
+	__u8     pscan_rep_mode;
+	__u8     pscan_mode;
+	__u16    clock_offset;
+} __attribute__ ((packed)) remote_name_req_cp;
+#define REMOTE_NAME_REQ_CP_SIZE 10
+
+#define OCF_READ_REMOTE_FEATURES 0x001B
+typedef struct {
+	__u16   handle;
+} __attribute__ ((packed)) read_remote_features_cp;
+#define READ_REMOTE_FEATURES_CP_SIZE 2
+
+#define OCF_READ_REMOTE_VERSION 0x001D
+typedef struct {
+	__u16   handle;
+} __attribute__ ((packed)) read_remote_version_cp;
+#define READ_REMOTE_VERSION_CP_SIZE 2
+
+/* Link Policy */
+#define OGF_LINK_POLICY	 0x02   
+#define OCF_ROLE_DISCOVERY	0x0009
+typedef struct {
+	__u16	handle;
+} __attribute__ ((packed)) role_discovery_cp;
+#define ROLE_DISCOVERY_CP_SIZE 2
+typedef struct {
+	__u8    status;
+	__u16	handle;
+	__u8    role;
+} __attribute__ ((packed)) role_discovery_rp;
+#define ROLE_DISCOVERY_RP_SIZE 4
+
+#define OCF_READ_LINK_POLICY	0x000C
+typedef struct {
+	__u16	handle;
+} __attribute__ ((packed)) read_link_policy_cp;
+#define READ_LINK_POLICY_CP_SIZE 2
+typedef struct {
+	__u8    status;
+	__u16	handle;
+	__u16   policy;
+} __attribute__ ((packed)) read_link_policy_rp;
+#define READ_LINK_POLICY_RP_SIZE 5
+
+#define OCF_SWITCH_ROLE	0x000B
+typedef struct {
+	bdaddr_t bdaddr;
+	__u8     role;
+} __attribute__ ((packed)) switch_role_cp;
+#define SWITCH_ROLE_CP_SIZE 7
+
+#define OCF_WRITE_LINK_POLICY	0x000D
+typedef struct {
+	__u16	handle;
+	__u16   policy;
+} __attribute__ ((packed)) write_link_policy_cp;
+#define WRITE_LINK_POLICY_CP_SIZE 4
+typedef struct {
+	__u8    status;
+	__u16	handle;
+} __attribute__ ((packed)) write_link_policy_rp;
+#define WRITE_LINK_POLICY_RP_SIZE 3
+
+/* Status params */
+#define OGF_STATUS_PARAM 	0x05
+
+/* ---- HCI Events ---- */
 #define EVT_INQUIRY_COMPLETE 	0x01
 
 #define EVT_INQUIRY_RESULT 	0x02
@@ -272,7 +445,7 @@
 	__u8	pscan_rep_mode;
 	__u8	pscan_period_mode;
 	__u8	pscan_mode;
-	__u8	class[3];
+	__u8	dev_class[3];
 	__u16	clock_offset;
 } __attribute__ ((packed)) inquiry_info;
 #define INQUIRY_INFO_SIZE 14
@@ -303,6 +476,44 @@
 } __attribute__ ((packed)) evt_disconn_complete;
 #define EVT_DISCONN_COMPLETE_SIZE 4
 
+#define EVT_AUTH_COMPLETE	0x06
+typedef struct {
+	__u8 	status;
+	__u16 	handle;
+} __attribute__ ((packed)) evt_auth_complete;
+#define EVT_AUTH_COMPLETE_SIZE 3
+
+#define EVT_REMOTE_NAME_REQ_COMPLETE	0x07
+typedef struct {
+	__u8 	 status;
+	bdaddr_t bdaddr;
+	__u8 	 name[248];
+} __attribute__ ((packed)) evt_remote_name_req_complete;
+#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
+
+#define EVT_ENCRYPT_CHANGE	0x08
+typedef struct {
+	__u8 	status;
+	__u16 	handle;
+	__u8	encrypt;
+} __attribute__ ((packed)) evt_encrypt_change;
+#define EVT_ENCRYPT_CHANGE_SIZE 5
+
+#define EVT_QOS_SETUP_COMPLETE 0x0D
+typedef struct {
+	__u8	service_type;
+	__u32	token_rate;
+	__u32	peak_bandwidth;
+	__u32	latency;
+	__u32	delay_variation;
+} __attribute__ ((packed)) hci_qos;
+typedef struct {
+	__u8	status;
+	__u16	handle;
+	hci_qos qos;
+} __attribute__ ((packed)) evt_qos_setup_complete;
+#define EVT_QOS_SETUP_COMPLETE_SIZE 20
+
 #define EVT_CMD_COMPLETE 	0x0e
 typedef struct {
 	__u8 	ncmd;
@@ -321,16 +532,78 @@
 #define EVT_NUM_COMP_PKTS	0x13
 typedef struct {
 	__u8 	num_hndl;
-	/* variable lenght part */
+	/* variable length part */
 } __attribute__ ((packed)) evt_num_comp_pkts;
 #define EVT_NUM_COMP_PKTS_SIZE 1
 
-#define EVT_HCI_DEV_EVENT	0xfd
+#define EVT_ROLE_CHANGE		0x12
+typedef struct {
+	__u8 	 status;
+	bdaddr_t bdaddr;
+	__u8     role;
+} __attribute__ ((packed)) evt_role_change;
+#define EVT_ROLE_CHANGE_SIZE 1
+
+#define EVT_PIN_CODE_REQ        0x16
+typedef struct {
+	bdaddr_t bdaddr;
+} __attribute__ ((packed)) evt_pin_code_req;
+#define EVT_PIN_CODE_REQ_SIZE 6
+
+#define EVT_LINK_KEY_REQ        0x17
+typedef struct {
+	bdaddr_t bdaddr;
+} __attribute__ ((packed)) evt_link_key_req;
+#define EVT_LINK_KEY_REQ_SIZE 6
+
+#define EVT_LINK_KEY_NOTIFY	0x18
+typedef struct {
+	bdaddr_t bdaddr;
+	__u8	 link_key[16];
+	__u8	 key_type;
+} __attribute__ ((packed)) evt_link_key_notify;
+#define EVT_LINK_KEY_NOTIFY_SIZE 23
+
+#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B
+typedef struct {
+	__u8    status;
+	__u16   handle;
+	__u8    features[8];
+} __attribute__ ((packed)) evt_read_remote_features_complete;
+#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
+
+#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
+typedef struct {
+	__u8    status;
+	__u16   handle;
+	__u8    lmp_ver;
+	__u16   manufacturer;
+	__u16   lmp_subver;
+} __attribute__ ((packed)) evt_read_remote_version_complete;
+#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
+
+/* Internal events generated by BlueZ stack */
+#define EVT_STACK_INTERNAL	0xfd
+typedef struct {
+	__u16   type;
+	__u8 	data[0];
+} __attribute__ ((packed)) evt_stack_internal;
+#define EVT_STACK_INTERNAL_SIZE 2
+
+#define EVT_SI_DEVICE  	0x01
+typedef struct {
+	__u16   event;
+	__u16 	dev_id;
+} __attribute__ ((packed)) evt_si_device;
+#define EVT_SI_DEVICE_SIZE 4
+
+#define EVT_SI_SECURITY	0x02
 typedef struct {
 	__u16 	event;
-	__u16 	param;
-} __attribute__ ((packed)) evt_hci_dev_event;
-#define EVT_HCI_DEV_EVENT_SIZE 4
+	__u16   proto;
+	__u16   subproto;
+	__u8    incomming;
+} __attribute__ ((packed)) evt_si_security;
 
 /* --------  HCI Packet structures  -------- */
 #define HCI_TYPE_LEN	1
@@ -369,14 +642,14 @@
 #define acl_handle(h)		(h & 0x0fff)
 #define acl_flags(h)		(h >> 12)
 
-#endif /* _NO_HCI_DEFS */
-
 /* HCI Socket options */
-#define HCI_DATA_DIR	0x0001
-#define HCI_FILTER	0x0002
+#define HCI_DATA_DIR	1
+#define HCI_FILTER	2
+#define HCI_TIME_STAMP	3
 
 /* HCI CMSG flags */
 #define HCI_CMSG_DIR	0x0001
+#define HCI_CMSG_TSTAMP	0x0002
 
 struct sockaddr_hci {
 	sa_family_t    hci_family;
@@ -387,27 +660,29 @@
 struct hci_filter {
 	__u32 type_mask;
 	__u32 event_mask[2];
+	__u16 opcode;
 };
 
-struct hci_dev_req {
-	__u16 dev_id;
-	__u32 dev_opt;
-};
-
-struct hci_dev_list_req {
-	__u16  dev_num;
-	struct hci_dev_req dev_req[0];	/* hci_dev_req structures */
-};
-
-struct hci_inquiry_req {
-	__u16 dev_id;
-	__u16 flags;
-	__u8  lap[3];
-	__u8  length;
-	__u8  num_rsp;
-};
-#define IREQ_CACHE_FLUSH 0x0001
+#define HCI_FLT_TYPE_BITS	31
+#define HCI_FLT_EVENT_BITS	63
+#define HCI_FLT_OGF_BITS	63
+#define HCI_FLT_OCF_BITS	127
+
+#if BITS_PER_LONG == 64
+static inline void hci_set_bit(int nr, void *addr)
+{
+	*((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31));
+}
+static inline int hci_test_bit(int nr, void *addr)
+{
+	return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
+}
+#else
+#define hci_set_bit	set_bit
+#define hci_test_bit	test_bit
+#endif
 
+/* Ioctl requests structures */
 struct hci_dev_stats {
 	__u32 err_rx;
 	__u32 err_tx;
@@ -433,11 +708,13 @@
 	__u8  features[8];
 
 	__u32 pkt_type;
+	__u32 link_policy;
+	__u32 link_mode;
 
 	__u16 acl_mtu;
-	__u16 acl_max;
+	__u16 acl_pkts;
 	__u16 sco_mtu;
-	__u16 sco_max;
+	__u16 sco_pkts;
 
 	struct hci_dev_stats stat;
 };
@@ -445,6 +722,20 @@
 struct hci_conn_info {
 	__u16    handle;
 	bdaddr_t bdaddr;
+	__u8	 type;
+	__u8	 out;
+	__u16	 state;
+	__u32	 link_mode;
+};
+
+struct hci_dev_req {
+	__u16 dev_id;
+	__u32 dev_opt;
+};
+
+struct hci_dev_list_req {
+	__u16  dev_num;
+	struct hci_dev_req dev_req[0];	/* hci_dev_req structures */
 };
 
 struct hci_conn_list_req {
@@ -453,4 +744,26 @@
 	struct hci_conn_info conn_info[0];
 };
 
+struct hci_conn_info_req {
+	bdaddr_t bdaddr;
+	__u8     type;
+	struct   hci_conn_info conn_info[0];
+};
+
+struct hci_inquiry_req {
+	__u16 dev_id;
+	__u16 flags;
+	__u8  lap[3];
+	__u8  length;
+	__u8  num_rsp;
+};
+#define IREQ_CACHE_FLUSH 0x0001
+
+struct hci_remotename_req {
+	__u16 dev_id;
+	__u16 flags;
+	bdaddr_t bdaddr;
+	__u8  name[248];
+};
+
 #endif /* __HCI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/hci_core.h linux/include/net/bluetooth/hci_core.h
--- linux.orig/include/net/bluetooth/hci_core.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/hci_core.h	2002-07-20 01:08:37.000000000 +0000
@@ -23,7 +23,7 @@
 */
 
 /* 
- * $Id: hci_core.h,v 1.11 2001/08/05 06:02:15 maxk Exp $ 
+ * $Id: hci_core.h,v 1.4 2002/06/25 22:04:43 maxk Exp $ 
  */
 
 #ifndef __HCI_CORE_H
@@ -32,14 +32,12 @@
 #include <net/bluetooth/hci.h>
 
 /* HCI upper protocols */
-#define HCI_MAX_PROTO 	1
 #define HCI_PROTO_L2CAP	0
+#define HCI_PROTO_SCO	1
 
 #define HCI_INIT_TIMEOUT (HZ * 10)
 
-/* ----- Inquiry cache ----- */
-#define INQUIRY_CACHE_AGE_MAX   (HZ*5)    // 5 seconds
-#define INQUIRY_ENTRY_AGE_MAX   (HZ*60)   // 60 seconds
+/* HCI Core structures */
 
 struct inquiry_entry {
 	struct inquiry_entry 	*next;
@@ -53,111 +51,180 @@
 	struct inquiry_entry 	*list;
 };
 
-static inline void inquiry_cache_init(struct inquiry_cache *cache)
-{
-	spin_lock_init(&cache->lock);
-	cache->list = NULL;
-}
+struct conn_hash {
+	struct list_head list;
+	spinlock_t       lock;
+	unsigned int     num;
+};
 
-static inline void inquiry_cache_lock(struct inquiry_cache *cache)
-{
-	spin_lock(&cache->lock);
-}
+struct hci_dev {
+	struct list_head list;
+	spinlock_t	lock;
+	atomic_t 	refcnt;
 
-static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
-{
-	spin_unlock(&cache->lock);
-}
+	char		name[8];
+	unsigned long	flags;
+	__u16		id;
+	__u8	 	type;
+	bdaddr_t	bdaddr;
+	__u8		features[8];
 
-static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
-{
-	spin_lock_bh(&cache->lock);
-}
+	__u16		pkt_type;
+	__u16		link_policy;
+	__u16		link_mode;
+	
+	atomic_t 	cmd_cnt;
+	unsigned int 	acl_cnt;
+	unsigned int 	sco_cnt;
 
-static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
-{
-	spin_unlock_bh(&cache->lock);
-}
+	unsigned int	acl_mtu;
+	unsigned int 	sco_mtu;
+	unsigned int	acl_pkts;
+	unsigned int	sco_pkts;
 
-static inline long inquiry_cache_age(struct inquiry_cache *cache)
-{
-	return jiffies - cache->timestamp;
-}
+	unsigned long   cmd_last_tx;
+	unsigned long   acl_last_tx;
+	unsigned long   sco_last_tx;
+	
+	struct tasklet_struct 	cmd_task;
+	struct tasklet_struct	rx_task;
+	struct tasklet_struct 	tx_task;
 
-static inline long inquiry_entry_age(struct inquiry_entry *e)
-{
-	return jiffies - e->timestamp;
-}
-extern void inquiry_cache_flush(struct inquiry_cache *cache);
+	struct sk_buff_head	rx_q;
+	struct sk_buff_head 	raw_q;
+	struct sk_buff_head 	cmd_q;
 
-struct hci_dev;
+	struct sk_buff     	*sent_cmd;
+
+	struct semaphore	req_lock;
+	wait_queue_head_t	req_wait_q;
+	__u32			req_status;
+	__u32			req_result;
+
+	struct inquiry_cache 	inq_cache;
+	struct conn_hash 	conn_hash;
+
+	struct hci_dev_stats 	stat;
+
+	void			*driver_data;
+	void			*core_data;
+
+	atomic_t 		promisc;
+
+	int (*open)(struct hci_dev *hdev);
+	int (*close)(struct hci_dev *hdev);
+	int (*flush)(struct hci_dev *hdev);
+	int (*send)(struct sk_buff *skb);
+	void (*destruct)(struct hci_dev *hdev);
+	int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
+};
 
-/* ----- HCI Connections ----- */
 struct hci_conn {
 	struct list_head list;
+
+	atomic_t	 refcnt;
+	spinlock_t	 lock;
+
 	bdaddr_t         dst;
 	__u16            handle;
+	__u16            state;
 	__u8		 type;
-	unsigned int     sent;
+	__u8		 out;
+	__u32		 link_mode;
+	unsigned long	 pend;
+	
+	unsigned int	 sent;
+	
+	struct sk_buff_head data_q;
 
+	struct timer_list timer;
+	
 	struct hci_dev 	*hdev;
 	void		*l2cap_data;
+	void		*sco_data;
 	void		*priv;
 
-	struct sk_buff_head data_q;
+	struct hci_conn *link;
 };
 
-struct conn_hash {
-	struct list_head list;
-	spinlock_t       lock;
-	unsigned int     num;
-};
+extern struct hci_proto *hci_proto[];
+extern struct list_head hdev_list;
+extern spinlock_t hdev_list_lock;
+
+/* ----- Inquiry cache ----- */
+#define INQUIRY_CACHE_AGE_MAX   (HZ*30)   // 30 seconds
+#define INQUIRY_ENTRY_AGE_MAX   (HZ*60)   // 60 seconds
+
+#define inquiry_cache_lock(c)		spin_lock(&c->lock)
+#define inquiry_cache_unlock(c)		spin_unlock(&c->lock)
+#define inquiry_cache_lock_bh(c)	spin_lock_bh(&c->lock)
+#define inquiry_cache_unlock_bh(c)	spin_unlock_bh(&c->lock)
 
-static inline void conn_hash_init(struct conn_hash *h)
+static inline void inquiry_cache_init(struct hci_dev *hdev)
 {
-	INIT_LIST_HEAD(&h->list);
-	spin_lock_init(&h->lock);
-	h->num = 0;	
+	struct inquiry_cache *c = &hdev->inq_cache;
+	spin_lock_init(&c->lock);
+	c->list = NULL;
 }
 
-static inline void conn_hash_lock(struct conn_hash *h)
+static inline long inquiry_cache_age(struct hci_dev *hdev)
 {
-	spin_lock(&h->lock);
+	struct inquiry_cache *c = &hdev->inq_cache;
+	return jiffies - c->timestamp;
 }
 
-static inline void conn_hash_unlock(struct conn_hash *h)
+static inline long inquiry_entry_age(struct inquiry_entry *e)
 {
-	spin_unlock(&h->lock);
+	return jiffies - e->timestamp;
 }
 
-static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info);
+void inquiry_cache_flush(struct hci_dev *hdev);
+int  inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf);
+
+/* ----- HCI Connections ----- */
+enum {
+	HCI_CONN_AUTH_PEND,
+	HCI_CONN_ENCRYPT_PEND
+};
+
+#define hci_conn_lock(c)	spin_lock(&c->lock)
+#define hci_conn_unlock(c)	spin_unlock(&c->lock)
+#define hci_conn_lock_bh(c)	spin_lock_bh(&c->lock)
+#define hci_conn_unlock_bh(c)	spin_unlock_bh(&c->lock)
+
+#define conn_hash_lock(d)	spin_lock(&d->conn_hash->lock)
+#define conn_hash_unlock(d)	spin_unlock(&d->conn_hash->lock)
+#define conn_hash_lock_bh(d)	spin_lock_bh(&d->conn_hash->lock)
+#define conn_hash_unlock_bh(d)	spin_unlock_bh(&d->conn_hash->lock)
+
+static inline void conn_hash_init(struct hci_dev *hdev)
 {
-	list_add(&c->list, &h->list);
-	h->num++;
+	struct conn_hash *h = &hdev->conn_hash;
+	INIT_LIST_HEAD(&h->list);
+	spin_lock_init(&h->lock);
+	h->num = 0;	
 }
 
-static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
+static inline void conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
 {
-	conn_hash_lock(h);
-	__conn_hash_add(h, handle, c);
-	conn_hash_unlock(h);
+	struct conn_hash *h = &hdev->conn_hash;
+	list_add(&c->list, &h->list);
+	h->num++;
 }
 
-static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
+static inline void conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
 {
+	struct conn_hash *h = &hdev->conn_hash;
 	list_del(&c->list);
 	h->num--;
 }
 
-static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
-{
-	conn_hash_lock(h);
-	__conn_hash_del(h, c);
-	conn_hash_unlock(h);
-}
-
-static inline  struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
+static inline struct hci_conn *conn_hash_lookup_handle(struct hci_dev *hdev,
+	       				__u16 handle)
 {
+	register struct conn_hash *h = &hdev->conn_hash;
 	register struct list_head *p;
 	register struct hci_conn  *c;
 
@@ -169,101 +236,89 @@
         return NULL;
 }
 
-static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
+static inline struct hci_conn *conn_hash_lookup_ba(struct hci_dev *hdev,
+					__u8 type, bdaddr_t *ba)
 {
-	struct hci_conn *conn;
+	register struct conn_hash *h = &hdev->conn_hash;
+	register struct list_head *p;
+	register struct hci_conn  *c;
 
-	conn_hash_lock(h);
-	conn = __conn_hash_lookup(h, handle);
-	conn_hash_unlock(h);
-	return conn;
+	list_for_each(p, &h->list) {
+		c = list_entry(p, struct hci_conn, list);
+		if (c->type == type && !bacmp(&c->dst, ba))
+			return c;
+	}
+        return NULL;
 }
 
-/* ----- HCI Devices ----- */
-struct hci_dev {
-	atomic_t 	refcnt;
-
-	char		name[8];
-	__u32	 	flags;
-	__u16		id;
-	__u8	 	type;
-	bdaddr_t	bdaddr;
-	__u8		features[8];
-
-	__u16		pkt_type;
+void hci_acl_connect(struct hci_conn *conn);
+void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
+void hci_add_sco(struct hci_conn *conn, __u16 handle);
 
-	atomic_t 	cmd_cnt;
-	unsigned int 	acl_cnt;
-	unsigned int 	sco_cnt;
+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
+int    hci_conn_del(struct hci_conn *conn);
+void   hci_conn_hash_flush(struct hci_dev *hdev);
 
-	unsigned int	acl_mtu;
-	unsigned int 	sco_mtu;
-	unsigned int	acl_max;
-	unsigned int	sco_max;
-
-	void		*driver_data;
-	void		*l2cap_data;
-	void		*priv;
-
-	struct tasklet_struct 	cmd_task;
-	struct tasklet_struct	rx_task;
-	struct tasklet_struct 	tx_task;
-
-	struct sk_buff_head	rx_q;
-	struct sk_buff_head 	raw_q;
-	struct sk_buff_head 	cmd_q;
-
-	struct sk_buff     	*sent_cmd;
-
-	struct semaphore	req_lock;
-	wait_queue_head_t	req_wait_q;
-	__u32			req_status;
-	__u32			req_result;
-
-	struct inquiry_cache 	inq_cache;
-
-	struct conn_hash 	conn_hash;
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
+int hci_conn_auth(struct hci_conn *conn);
+int hci_conn_encrypt(struct hci_conn *conn);
 
-	struct hci_dev_stats 	stat;
-
-	int (*open)(struct hci_dev *hdev);
-	int (*close)(struct hci_dev *hdev);
-	int (*flush)(struct hci_dev *hdev);
-	int (*send)(struct sk_buff *skb);
-};
+static inline void hci_conn_set_timer(struct hci_conn *conn, long timeout)
+{
+	mod_timer(&conn->timer, jiffies + timeout);
+}
 
-static inline void hci_dev_hold(struct hci_dev *hdev)
+static inline void hci_conn_del_timer(struct hci_conn *conn)
 {
-	atomic_inc(&hdev->refcnt);
+	del_timer(&conn->timer);
 }
 
-static inline void hci_dev_put(struct hci_dev *hdev)
+static inline void hci_conn_hold(struct hci_conn *conn)
 {
-	atomic_dec(&hdev->refcnt);
+	atomic_inc(&conn->refcnt);
+	hci_conn_del_timer(conn);
 }
 
-extern struct hci_dev *hci_dev_get(int index);
-extern int hci_register_dev(struct hci_dev *hdev);
-extern int hci_unregister_dev(struct hci_dev *hdev);
-extern int hci_dev_open(__u16 dev);
-extern int hci_dev_close(__u16 dev);
-extern int hci_dev_reset(__u16 dev);
-extern int hci_dev_reset_stat(__u16 dev);
-extern int hci_dev_info(unsigned long arg);
-extern int hci_dev_list(unsigned long arg);
-extern int hci_dev_setscan(unsigned long arg);
-extern int hci_dev_setauth(unsigned long arg);
-extern int hci_dev_setptype(unsigned long arg);
-extern int hci_conn_list(unsigned long arg);
-extern int hci_inquiry(unsigned long arg);
+static inline void hci_conn_put(struct hci_conn *conn)
+{
+	if (atomic_dec_and_test(&conn->refcnt) && conn->out)
+		hci_conn_set_timer(conn, HCI_DISCONN_TIMEOUT);
+}
 
-extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
-extern __u32 hci_dev_getmode(struct hci_dev *hdev);
+/* ----- HCI Devices ----- */
+static inline void hci_dev_put(struct hci_dev *d)
+{ 
+	if (atomic_dec_and_test(&d->refcnt))
+		d->destruct(d);
+}
+#define hci_dev_hold(d)		atomic_inc(&d->refcnt)
+
+#define hci_dev_lock(d)		spin_lock(&d->lock)
+#define hci_dev_unlock(d)	spin_unlock(&d->lock)
+#define hci_dev_lock_bh(d)	spin_lock_bh(&d->lock)
+#define hci_dev_unlock_bh(d)	spin_unlock_bh(&d->lock)
+
+struct hci_dev *hci_dev_get(int index);
+struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
+int hci_register_dev(struct hci_dev *hdev);
+int hci_unregister_dev(struct hci_dev *hdev);
+int hci_dev_open(__u16 dev);
+int hci_dev_close(__u16 dev);
+int hci_dev_reset(__u16 dev);
+int hci_dev_reset_stat(__u16 dev);
+int hci_dev_cmd(unsigned int cmd, unsigned long arg);
+int hci_get_dev_list(unsigned long arg);
+int hci_get_dev_info(unsigned long arg);
+int hci_get_conn_list(unsigned long arg);
+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
+int hci_inquiry(unsigned long arg);
 
-extern int hci_recv_frame(struct sk_buff *skb);
+int  hci_recv_frame(struct sk_buff *skb);
+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
 /* ----- LMP capabilities ----- */
 #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
+#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT)
 
 /* ----- HCI tasks ----- */
 static inline void hci_sched_cmd(struct hci_dev *hdev)
@@ -284,43 +339,132 @@
 /* ----- HCI protocols ----- */
 struct hci_proto {
 	char 		*name;
-	__u32		id;
-	__u32		flags;
+	unsigned int 	id;
+	unsigned long	flags;
 
 	void		*priv;
 
-	int (*connect_ind) 	(struct hci_dev *hdev, bdaddr_t *bdaddr);
-	int (*connect_cfm)	(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *conn);
+	int (*connect_ind) 	(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
+	int (*connect_cfm)	(struct hci_conn *conn, __u8 status);
 	int (*disconn_ind)	(struct hci_conn *conn, __u8 reason);
-	int (*recv_acldata)	(struct hci_conn *conn, struct sk_buff *skb , __u16 flags);
+	int (*recv_acldata)	(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
 	int (*recv_scodata)	(struct hci_conn *conn, struct sk_buff *skb);
+	int (*auth_cfm)		(struct hci_conn *conn, __u8 status);
+	int (*encrypt_cfm)	(struct hci_conn *conn, __u8 status);
 };
 
-extern int hci_register_proto(struct hci_proto *hproto);
-extern int hci_unregister_proto(struct hci_proto *hproto);
-extern int hci_register_notifier(struct notifier_block *nb);
-extern int hci_unregister_notifier(struct notifier_block *nb);
-extern int hci_connect(struct hci_dev * hdev, bdaddr_t * bdaddr);
-extern int hci_disconnect(struct hci_conn *conn, __u8 reason);
-extern int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void * param);
-extern int hci_send_raw(struct sk_buff *skb);
-extern int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
-extern int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
+static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
+{
+	register struct hci_proto *hp;
+	int mask = 0;
+	
+	hp = hci_proto[HCI_PROTO_L2CAP];
+	if (hp && hp->connect_ind)
+		mask |= hp->connect_ind(hdev, bdaddr, type);
+
+	hp = hci_proto[HCI_PROTO_SCO];
+	if (hp && hp->connect_ind)
+		mask |= hp->connect_ind(hdev, bdaddr, type);
+
+	return mask;
+}
+
+static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
+{
+	register struct hci_proto *hp;
+
+	hp = hci_proto[HCI_PROTO_L2CAP];
+	if (hp && hp->connect_cfm)
+		hp->connect_cfm(conn, status);
+
+	hp = hci_proto[HCI_PROTO_SCO];
+	if (hp && hp->connect_cfm)
+		hp->connect_cfm(conn, status);
+}
+
+static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
+{
+	register struct hci_proto *hp;
+
+	hp = hci_proto[HCI_PROTO_L2CAP];
+	if (hp && hp->disconn_ind)
+		hp->disconn_ind(conn, reason);
+
+	hp = hci_proto[HCI_PROTO_SCO];
+	if (hp && hp->disconn_ind)
+		hp->disconn_ind(conn, reason);
+}
+
+static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
+{
+	register struct hci_proto *hp;
+
+	hp = hci_proto[HCI_PROTO_L2CAP];
+	if (hp && hp->auth_cfm)
+		hp->auth_cfm(conn, status);
+
+	hp = hci_proto[HCI_PROTO_SCO];
+	if (hp && hp->auth_cfm)
+		hp->auth_cfm(conn, status);
+}
+
+static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
+{
+	register struct hci_proto *hp;
+
+	hp = hci_proto[HCI_PROTO_L2CAP];
+	if (hp && hp->encrypt_cfm)
+		hp->encrypt_cfm(conn, status);
+
+	hp = hci_proto[HCI_PROTO_SCO];
+	if (hp && hp->encrypt_cfm)
+		hp->encrypt_cfm(conn, status);
+}
+
+int hci_register_proto(struct hci_proto *hproto);
+int hci_unregister_proto(struct hci_proto *hproto);
+int hci_register_notifier(struct notifier_block *nb);
+int hci_unregister_notifier(struct notifier_block *nb);
+
+int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
+int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
+int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
+int hci_send_raw(struct sk_buff *skb);
+
+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
+
+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
 
 /* ----- HCI Sockets ----- */
-extern void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
+void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
 
 /* HCI info for socket */
-#define hci_pi(sk)	((struct hci_pinfo *) &sk->protinfo)
+#define hci_pi(sk)	((struct hci_pinfo *) &sk->tp_pinfo)
 struct hci_pinfo {
 	struct hci_dev 	  *hdev;
 	struct hci_filter filter;
 	__u32             cmsg_mask;
 };
 
+/* HCI security filter */
+#define HCI_SFLT_MAX_OGF 4
+
+struct hci_sec_filter {
+	__u32 type_mask;
+	__u32 event_mask[2];
+	__u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
+};
+
+
 /* ----- HCI requests ----- */
 #define HCI_REQ_DONE	  0
 #define HCI_REQ_PEND	  1
 #define HCI_REQ_CANCELED  2
 
+#define hci_req_lock(d)		down(&d->req_lock)
+#define hci_req_unlock(d)	up(&d->req_lock)
+
+void hci_req_complete(struct hci_dev *hdev, int result);
+void hci_req_cancel(struct hci_dev *hdev, int err);
+
 #endif /* __HCI_CORE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/hci_uart.h linux/include/net/bluetooth/hci_uart.h
--- linux.orig/include/net/bluetooth/hci_uart.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/hci_uart.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,62 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * $Id: hci_uart.h,v 1.2 2001/06/02 01:40:08 maxk Exp $
- */
-
-#ifndef N_HCI
-#define N_HCI	15
-#endif
-
-#ifdef __KERNEL__
-
-#define tty2n_hci(tty)  ((struct n_hci *)((tty)->disc_data))
-#define n_hci2tty(n_hci) ((n_hci)->tty)
-
-struct n_hci {
-	struct tty_struct *tty;
-	struct hci_dev hdev;
-
-	struct sk_buff_head txq;
-	unsigned long tx_state;
-
-	spinlock_t rx_lock;
-	unsigned long rx_state;
-	unsigned long rx_count;
-	struct sk_buff *rx_skb;
-};
-
-/* Transmit states  */
-#define TRANS_SENDING		1
-#define TRANS_WAKEUP		2
-
-/* Receiver States */
-#define WAIT_PACKET_TYPE	0
-#define WAIT_EVENT_HDR	 	1
-#define WAIT_ACL_HDR		2
-#define WAIT_SCO_HDR		3
-#define WAIT_DATA	        4
-
-#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/hci_usb.h linux/include/net/bluetooth/hci_usb.h
--- linux.orig/include/net/bluetooth/hci_usb.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/hci_usb.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,68 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * $Id: hci_usb.h,v 1.3 2001/06/02 01:40:08 maxk Exp $
- */
-
-#ifdef __KERNEL__
-
-/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
-#define HCI_DEV_CLASS        0xe0	/* Wireless class */
-#define HCI_DEV_SUBCLASS     0x01	/* RF subclass */
-#define HCI_DEV_PROTOCOL     0x01	/* Bluetooth programming protocol */
-
-#define HCI_CTRL_REQ	     0x20
-
-struct hci_usb {
-	struct usb_device 	*udev;
-
-	devrequest		dev_req;
-	struct urb 		*ctrl_urb;
-	struct urb		*intr_urb;
-	struct urb		*read_urb;
-	struct urb		*write_urb;
-
-	__u8			*read_buf;
-	__u8			*intr_buf;
-	struct sk_buff		*intr_skb;
-	int			intr_count;
-
-	__u8			bulk_out_ep_addr;
-	__u8			bulk_in_ep_addr;
-	__u8			intr_in_ep_addr;
-	__u8			intr_in_interval;
-
-	struct hci_dev		hdev;
-
-	unsigned long		tx_state;
-	struct sk_buff_head	tx_ctrl_q;
-	struct sk_buff_head	tx_write_q;
-};
-
-/* Transmit states  */
-#define HCI_TX_CTRL	1
-#define HCI_TX_WRITE	2
-
-#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/hci_vhci.h linux/include/net/bluetooth/hci_vhci.h
--- linux.orig/include/net/bluetooth/hci_vhci.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/hci_vhci.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,50 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * $Id: hci_vhci.h,v 1.2 2001/08/01 01:02:20 maxk Exp $
- */
-
-#ifndef __HCI_VHCI_H
-#define __HCI_VHCI_H
-
-#ifdef __KERNEL__
-
-struct hci_vhci_struct {
-	struct hci_dev       hdev;
-	__u32                flags;
-	wait_queue_head_t    read_wait;
-	struct sk_buff_head  readq;
-	struct fasync_struct *fasync;
-};
-
-/* VHCI device flags */
-#define VHCI_FASYNC		0x0010
-
-#endif /* __KERNEL__ */
-
-#define VHCI_DEV	"/dev/vhci"
-#define VHCI_MINOR	250
-
-#endif /* __HCI_VHCI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/l2cap.h linux/include/net/bluetooth/l2cap.h
--- linux.orig/include/net/bluetooth/l2cap.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/l2cap.h	2002-07-20 01:08:27.000000000 +0000
@@ -23,22 +23,17 @@
 */
 
 /*
- *  $Id: l2cap.h,v 1.5 2001/06/14 21:28:26 maxk Exp $
+ *  $Id: l2cap.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
  */
 
 #ifndef __L2CAP_H
 #define __L2CAP_H
 
-#include <asm/types.h>
-#include <asm/byteorder.h>
-
 /* L2CAP defaults */
 #define L2CAP_DEFAULT_MTU 	672
 #define L2CAP_DEFAULT_FLUSH_TO	0xFFFF
 
 #define L2CAP_CONN_TIMEOUT 	(HZ * 40)
-#define L2CAP_DISCONN_TIMEOUT 	(HZ * 2)
-#define L2CAP_CONN_IDLE_TIMEOUT	(HZ * 60)
 
 /* L2CAP socket address */
 struct sockaddr_l2 {
@@ -47,17 +42,12 @@
 	bdaddr_t	l2_bdaddr;
 };
 
-/* set/get sockopt defines */
-#define L2CAP_OPTIONS  0x01
+/* Socket options */
+#define L2CAP_OPTIONS	0x01
 struct l2cap_options {
 	__u16 omtu;
 	__u16 imtu;
 	__u16 flush_to;
-	__u32 token_rate;
-	__u32 bucket_size;
-	__u32 pick_band;
-	__u32 latency;
-	__u32 delay_var;
 };
 
 #define L2CAP_CONNINFO  0x02
@@ -65,6 +55,26 @@
 	__u16 hci_handle;
 };
 
+#define L2CAP_LM	0x03
+#define L2CAP_LM_MASTER		0x0001
+#define L2CAP_LM_AUTH		0x0002
+#define L2CAP_LM_ENCRYPT	0x0004
+#define L2CAP_LM_TRUSTED	0x0008
+
+#define L2CAP_QOS	0x04
+struct l2cap_qos {
+	__u16 service_type;
+	__u32 token_rate;
+	__u32 token_bucket_size;
+	__u32 peak_bandwidth;
+	__u32 latency;
+	__u32 delay_variation;
+};
+
+#define L2CAP_SERV_NO_TRAFFIC	0x00
+#define L2CAP_SERV_BEST_EFFORT	0x01
+#define L2CAP_SERV_GUARANTEED	0x02
+
 /* L2CAP command codes */
 #define L2CAP_COMMAND_REJ 0x01
 #define L2CAP_CONN_REQ    0x02
@@ -79,7 +89,6 @@
 #define L2CAP_INFO_RSP    0x0b
 
 /* L2CAP structures */
-
 typedef struct {
 	__u16      len;
 	__u16      cid;
@@ -112,11 +121,17 @@
 } __attribute__ ((packed))	l2cap_conn_rsp;
 #define L2CAP_CONN_RSP_SIZE	8
 
-#define L2CAP_CONN_SUCCESS    0x0000
-#define L2CAP_CONN_PEND       0x0001
-#define L2CAP_CONN_BAD_PSM    0x0002
-#define L2CAP_CONN_SEC_BLOCK  0x0003
-#define L2CAP_CONN_NO_MEM     0x0004
+/* connect result */
+#define L2CAP_CR_SUCCESS    0x0000
+#define L2CAP_CR_PEND       0x0001
+#define L2CAP_CR_BAD_PSM    0x0002
+#define L2CAP_CR_SEC_BLOCK  0x0003
+#define L2CAP_CR_NO_MEM     0x0004
+
+/* connect status */
+#define L2CAP_CS_NO_INFO      0x0000
+#define L2CAP_CS_AUTHEN_PEND  0x0001
+#define L2CAP_CS_AUTHOR_PEND  0x0002
 
 typedef struct {
 	__u16      dcid;
@@ -147,6 +162,8 @@
 #define L2CAP_CONF_FLUSH_TO	0x02
 #define L2CAP_CONF_QOS		0x03
 
+#define L2CAP_CONF_MAX_SIZE	22
+
 typedef struct {
 	__u16      dcid;
 	__u16      scid;
@@ -159,4 +176,70 @@
 } __attribute__ ((packed)) 	l2cap_disconn_rsp;
 #define L2CAP_DISCONN_RSP_SIZE	4
 
+typedef struct {
+	__u16       type;
+	__u8        data[0];
+} __attribute__ ((packed))	l2cap_info_req;
+#define L2CAP_INFO_REQ_SIZE	2
+
+typedef struct {
+	__u16       type;
+	__u16       result;
+	__u8        data[0];
+} __attribute__ ((packed))	l2cap_info_rsp;
+#define L2CAP_INFO_RSP_SIZE	4
+
+/* ----- L2CAP connections ----- */
+struct l2cap_chan_list {
+	struct sock	*head;
+	rwlock_t	lock;
+	long		num;
+};
+
+struct l2cap_conn {
+	struct hci_conn	*hcon;
+
+	bdaddr_t 	*dst;
+	bdaddr_t 	*src;
+	
+	unsigned int    mtu;
+
+	spinlock_t	lock;
+	
+	struct sk_buff *rx_skb;
+	__u32		rx_len;
+	__u8		rx_ident;
+	__u8		tx_ident;
+
+	struct l2cap_chan_list chan_list;
+};
+
+/* ----- L2CAP channel and socket info ----- */
+#define l2cap_pi(sk)   ((struct l2cap_pinfo *) &sk->tp_pinfo)
+
+struct l2cap_pinfo {
+	__u16		psm;
+	__u16		dcid;
+	__u16		scid;
+
+	__u16		imtu;
+	__u16		omtu;
+	__u16		flush_to;
+	
+	__u32		link_mode;
+
+	__u8		conf_state;
+	__u16		conf_mtu;
+
+	__u8		ident;
+
+	struct l2cap_conn 	*conn;
+	struct sock 		*next_c;
+	struct sock 		*prev_c;
+};
+
+#define CONF_REQ_SENT    0x01
+#define CONF_INPUT_DONE  0x02
+#define CONF_OUTPUT_DONE 0x04
+
 #endif /* __L2CAP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/l2cap_core.h linux/include/net/bluetooth/l2cap_core.h
--- linux.orig/include/net/bluetooth/l2cap_core.h	2001-09-07 16:28:38.000000000 +0000
+++ linux/include/net/bluetooth/l2cap_core.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,144 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- *  $Id: l2cap_core.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
- */
-
-#ifndef __L2CAP_CORE_H
-#define __L2CAP_CORE_H
-
-#ifdef __KERNEL__
-
-/* ----- L2CAP interface ----- */
-struct l2cap_iff {
-	struct list_head list;
-	struct hci_dev   *hdev;
-	bdaddr_t         *bdaddr;
-	__u16            mtu;
-	spinlock_t       lock;
-	struct list_head conn_list;
-};
-
-static inline void l2cap_iff_lock(struct l2cap_iff *iff)
-{
-	spin_lock(&iff->lock);
-}
-
-static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
-{
-	spin_unlock(&iff->lock);
-}
-
-/* ----- L2CAP connections ----- */
-struct l2cap_chan_list {
-	struct sock	*head;
-	rwlock_t	lock;
-	long		num;
-};
-
-struct l2cap_conn {
-	struct l2cap_iff *iff;
-	struct list_head list;
-
-	struct hci_conn	 *hconn;
-
-	__u16		state;
-	__u8		out;
-	bdaddr_t	src;
-	bdaddr_t	dst;
-
-	spinlock_t	lock;
-	atomic_t	refcnt;
-
-	struct sk_buff *rx_skb;
-	__u32		rx_len;
-	__u8		rx_ident;
-	__u8		tx_ident;
-
-	struct l2cap_chan_list chan_list;
-
-	struct timer_list timer;
-};
-
-static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
-{
-	list_add(&c->list, &iff->conn_list);
-}
-
-static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
-{
-	list_del(&c->list);
-}
-
-/* ----- L2CAP channel and socket info ----- */
-#define l2cap_pi(sk)   ((struct l2cap_pinfo *) &sk->protinfo)
-
-struct l2cap_accept_q {
-	struct sock 	*head;
-	struct sock 	*tail;
-};
-
-struct l2cap_pinfo {
-	bdaddr_t	src;
-	bdaddr_t	dst;
-	__u16		psm;
-	__u16		dcid;
-	__u16		scid;
-	__u32		flags;
-
-	__u16		imtu;
-	__u16		omtu;
-	__u16		flush_to;
-
-	__u8		conf_state;
-	__u16		conf_mtu;
-
-	__u8		ident;
-
-	struct l2cap_conn 	*conn;
-	struct sock 		*next_c;
-	struct sock 		*prev_c;
-
-	struct sock *parent;
-	struct sock *next_q;
-	struct sock *prev_q;
-
-	struct l2cap_accept_q accept_q;
-};
-
-#define CONF_REQ_SENT    0x01
-#define CONF_INPUT_DONE  0x02
-#define CONF_OUTPUT_DONE 0x04
-
-extern struct bluez_sock_list l2cap_sk_list;
-extern struct list_head  l2cap_iff_list;
-extern rwlock_t l2cap_rt_lock;
-
-extern void l2cap_register_proc(void);
-extern void l2cap_unregister_proc(void);
-
-#endif /* __KERNEL__ */
-
-#endif /* __L2CAP_CORE_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/bluetooth/sco.h linux/include/net/bluetooth/sco.h
--- linux.orig/include/net/bluetooth/sco.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/net/bluetooth/sco.h	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,81 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ *  $Id: sco.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
+ */
+
+#ifndef __SCO_H
+#define __SCO_H
+
+/* SCO defaults */
+#define SCO_DEFAULT_MTU 	500
+#define SCO_DEFAULT_FLUSH_TO	0xFFFF
+
+#define SCO_CONN_TIMEOUT 	(HZ * 40)
+#define SCO_DISCONN_TIMEOUT 	(HZ * 2)
+#define SCO_CONN_IDLE_TIMEOUT	(HZ * 60)
+
+/* SCO socket address */
+struct sockaddr_sco {
+	sa_family_t	sco_family;
+	bdaddr_t	sco_bdaddr;
+};
+
+/* set/get sockopt defines */
+#define SCO_OPTIONS  0x01
+struct sco_options {
+	__u16 mtu;
+};
+
+#define SCO_CONNINFO  0x02
+struct sco_conninfo {
+	__u16 hci_handle;
+};
+
+/* ---- SCO connections ---- */
+struct sco_conn {
+	struct hci_conn	*hcon;
+
+	bdaddr_t 	*dst;
+	bdaddr_t 	*src;
+	
+	spinlock_t	lock;
+	struct sock 	*sk;
+
+	unsigned int    mtu;
+};
+
+#define sco_conn_lock(c)	spin_lock(&c->lock);
+#define sco_conn_unlock(c)	spin_unlock(&c->lock);
+
+/* ----- SCO socket info ----- */
+#define sco_pi(sk)   ((struct sco_pinfo *) &sk->tp_pinfo)
+
+struct sco_pinfo {
+	__u32		flags;
+	struct sco_conn	*conn;
+};
+
+#endif /* __SCO_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/irda/au1000_ircc.h linux/include/net/irda/au1000_ircc.h
--- linux.orig/include/net/irda/au1000_ircc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/net/irda/au1000_ircc.h	2002-07-20 01:08:28.000000000 +0000
@@ -0,0 +1,128 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 IrDA driver.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef AU1000_IRCC_H
+#define AU1000_IRCC_H
+
+#include <linux/time.h>
+
+#include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+
+#define NUM_IR_IFF          1
+#define NUM_IR_DESC        64
+#define RING_SIZE_4       0x0
+#define RING_SIZE_16      0x3
+#define RING_SIZE_64      0xF
+#define MAX_NUM_IR_DESC    64
+#define MAX_BUF_SIZE     2048
+
+#define BPS_115200          0
+#define BPS_57600           1
+#define BPS_38400           2
+#define BPS_19200           5
+#define BPS_9600           11
+#define BPS_2400           47
+
+/* Ring descriptor flags */
+#define AU_OWN           (1<<7) /* tx,rx */
+
+#define IR_DIS_CRC       (1<<6) /* tx */
+#define IR_BAD_CRC       (1<<5) /* tx */
+#define IR_NEED_PULSE    (1<<4) /* tx */
+#define IR_FORCE_UNDER   (1<<3) /* tx */
+#define IR_DISABLE_TX    (1<<2) /* tx */
+#define IR_HW_UNDER      (1<<0) /* tx */
+#define IR_TX_ERROR      (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER)
+
+#define IR_PHY_ERROR     (1<<6) /* rx */
+#define IR_CRC_ERROR     (1<<5) /* rx */
+#define IR_MAX_LEN       (1<<4) /* rx */
+#define IR_FIFO_OVER     (1<<3) /* rx */
+#define IR_SIR_ERROR     (1<<2) /* rx */
+#define IR_RX_ERROR      (IR_PHY_ERROR|IR_CRC_ERROR| \
+		IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR)
+
+typedef struct db_dest {
+	struct db_dest *pnext;
+	volatile u32 *vaddr;
+	dma_addr_t dma_addr;
+} db_dest_t;
+
+
+typedef struct ring_desc {
+	u8 count_0;               /* 7:0  */
+	u8 count_1;               /* 12:8 */
+	u8 reserved;
+	u8 flags;
+	u8 addr_0;                /* 7:0   */
+	u8 addr_1;                /* 15:8  */
+	u8 addr_2;                /* 23:16 */
+	u8 addr_3;                /* 31:24 */
+} ring_dest_t;
+
+
+/* Private data for each instance */
+struct au1k_private {
+
+	db_dest_t *pDBfree;
+	db_dest_t db[2*NUM_IR_DESC];
+	volatile ring_dest_t *rx_ring[NUM_IR_DESC];
+	volatile ring_dest_t *tx_ring[NUM_IR_DESC];
+	db_dest_t *rx_db_inuse[NUM_IR_DESC];
+	db_dest_t *tx_db_inuse[NUM_IR_DESC];
+	u32 rx_head;
+	u32 tx_head;
+	u32 tx_tail;
+	u32 tx_full;
+
+	iobuff_t rx_buff;
+
+	struct net_device *netdev;
+	struct net_device_stats stats;
+	
+	struct timeval stamp;
+	struct timeval now;
+	struct qos_info		qos;
+	struct irlap_cb		*irlap;
+	
+	u8 open;
+	u32 flags;               /* Interface flags */
+	u32 speed;
+	u32 newspeed;
+	
+	u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */
+	struct timer_list timer;
+
+	spinlock_t lock;           /* For serializing operations */
+        struct pm_dev *dev;
+};
+#endif /* AU1000_IRCC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/irda/irlap.h linux/include/net/irda/irlap.h
--- linux.orig/include/net/irda/irlap.h	2001-09-13 23:26:52.000000000 +0000
+++ linux/include/net/irda/irlap.h	2002-07-20 01:08:34.000000000 +0000
@@ -11,6 +11,7 @@
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
+ *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -44,6 +45,7 @@
 #define LAP_ADDR_HEADER 1  /* IrLAP Address Header */
 #define LAP_CTRL_HEADER 1  /* IrLAP Control Header */
 
+/* May be different when we get VFIR */
 #define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER)
 
 #define BROADCAST  0xffffffff /* Broadcast device address */
@@ -210,9 +212,8 @@
 void irlap_init_qos_capabilities(struct irlap_cb *, struct qos_info *);
 void irlap_apply_default_connection_parameters(struct irlap_cb *self);
 void irlap_apply_connection_parameters(struct irlap_cb *self, int now);
-void irlap_set_local_busy(struct irlap_cb *self, int status);
 
-#define IRLAP_GET_HEADER_SIZE(self) 2 /* Will be different when we get VFIR */
+#define IRLAP_GET_HEADER_SIZE(self) (LAP_MAX_HEADER)
 #define IRLAP_GET_TX_QUEUE_LEN(self) skb_queue_len(&self->txq)
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/irda/irlap_event.h linux/include/net/irda/irlap_event.h
--- linux.orig/include/net/irda/irlap_event.h	2001-11-09 22:22:17.000000000 +0000
+++ linux/include/net/irda/irlap_event.h	2002-07-20 01:08:21.000000000 +0000
@@ -134,7 +134,6 @@
 
 void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, 
 		    struct sk_buff *skb, struct irlap_info *info);
-void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state);
 void irlap_print_event(IRLAP_EVENT event);
 
 extern int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/iw_handler.h linux/include/net/iw_handler.h
--- linux.orig/include/net/iw_handler.h	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/net/iw_handler.h	2002-07-20 01:08:33.000000000 +0000
@@ -0,0 +1,374 @@
+/*
+ * This file define the new driver API for Wireless Extensions
+ *
+ * Version :	2	6.12.01
+ *
+ * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ * Copyright (c) 2001 Jean Tourrilhes, All Rights Reserved.
+ */
+
+#ifndef _IW_HANDLER_H
+#define _IW_HANDLER_H
+
+/************************** DOCUMENTATION **************************/
+/*
+ * Initial driver API (1996 -> onward) :
+ * -----------------------------------
+ * The initial API just sends the IOCTL request received from user space
+ * to the driver (via the driver ioctl handler). The driver has to
+ * handle all the rest...
+ *
+ * The initial API also defines a specific handler in struct net_device
+ * to handle wireless statistics.
+ *
+ * The initial APIs served us well and has proven a reasonably good design.
+ * However, there is a few shortcommings :
+ *	o No events, everything is a request to the driver.
+ *	o Large ioctl function in driver with gigantic switch statement
+ *	  (i.e. spaghetti code).
+ *	o Driver has to mess up with copy_to/from_user, and in many cases
+ *	  does it unproperly. Common mistakes are :
+ *		* buffer overflows (no checks or off by one checks)
+ *		* call copy_to/from_user with irq disabled
+ *	o The user space interface is tied to ioctl because of the use
+ *	  copy_to/from_user.
+ *
+ * New driver API (2001 -> onward) :
+ * -------------------------------
+ * The new driver API is just a bunch of standard functions (handlers),
+ * each handling a specific Wireless Extension. The driver just export
+ * the list of handler it supports, and those will be called apropriately.
+ *
+ * I tried to keep the main advantage of the previous API (simplicity,
+ * efficiency and light weight), and also I provide a good dose of backward
+ * compatibility (most structures are the same, driver can use both API
+ * simultaneously, ...).
+ * Hopefully, I've also addressed the shortcomming of the initial API.
+ *
+ * The advantage of the new API are :
+ *	o Handling of Extensions in driver broken in small contained functions
+ *	o Tighter checks of ioctl before calling the driver
+ *	o Flexible commit strategy (at least, the start of it)
+ *	o Backward compatibility (can be mixed with old API)
+ *	o Driver doesn't have to worry about memory and user-space issues
+ * The last point is important for the following reasons :
+ *	o You are now able to call the new driver API from any API you
+ *		want (including from within other parts of the kernel).
+ *	o Common mistakes are avoided (buffer overflow, user space copy
+ *		with irq disabled and so on).
+ *
+ * The Drawback of the new API are :
+ *	o bloat (especially kernel)
+ *	o need to migrate existing drivers to new API
+ * My initial testing shows that the new API adds around 3kB to the kernel
+ * and save between 0 and 5kB from a typical driver.
+ * Also, as all structures and data types are unchanged, the migration is
+ * quite straightforward (but tedious).
+ *
+ * ---
+ *
+ * The new driver API is defined below in this file. User space should
+ * not be aware of what's happening down there...
+ *
+ * A new kernel wrapper is in charge of validating the IOCTLs and calling
+ * the appropriate driver handler. This is implemented in :
+ *	# net/core/wireless.c
+ *
+ * The driver export the list of handlers in :
+ *	# include/linux/netdevice.h (one place)
+ *
+ * The new driver API is available for WIRELESS_EXT >= 13.
+ * Good luck with migration to the new API ;-)
+ */
+
+/* ---------------------- THE IMPLEMENTATION ---------------------- */
+/*
+ * Some of the choice I've made are pretty controversials. Defining an
+ * API is very much weighting compromises. This goes into some of the
+ * details and the thinking behind the implementation.
+ *
+ * Implementation goals :
+ * --------------------
+ * The implementation goals were as follow :
+ *	o Obvious : you should not need a PhD to understand what's happening,
+ *		the benefit is easier maintainance.
+ *	o Flexible : it should accomodate a wide variety of driver
+ *		implementations and be as flexible as the old API.
+ *	o Lean : it should be efficient memory wise to minimise the impact
+ *		on kernel footprint.
+ *	o Transparent to user space : the large number of user space
+ *		applications that use Wireless Extensions should not need
+ *		any modifications.
+ *
+ * Array of functions versus Struct of functions
+ * ---------------------------------------------
+ * 1) Having an array of functions allow the kernel code to access the
+ * handler in a single lookup, which is much more efficient (think hash
+ * table here).
+ * 2) The only drawback is that driver writer may put their handler in
+ * the wrong slot. This is trivial to test (I set the frequency, the
+ * bitrate changes). Once the handler is in the proper slot, it will be
+ * there forever, because the array is only extended at the end.
+ * 3) Backward/forward compatibility : adding new handler just require
+ * extending the array, so you can put newer driver in older kernel
+ * without having to patch the kernel code (and vice versa).
+ *
+ * All handler are of the same generic type
+ * ----------------------------------------
+ * That's a feature !!!
+ * 1) Having a generic handler allow to have generic code, which is more
+ * efficient. If each of the handler was individually typed I would need
+ * to add a big switch in the kernel (== more bloat). This solution is
+ * more scalable, adding new Wireless Extensions doesn't add new code.
+ * 2) You can use the same handler in different slots of the array. For
+ * hardware, it may be more efficient or logical to handle multiple
+ * Wireless Extensions with a single function, and the API allow you to
+ * do that. (An example would be a single record on the card to control
+ * both bitrate and frequency, the handler would read the old record,
+ * modify it according to info->cmd and rewrite it).
+ *
+ * Functions prototype uses union iwreq_data
+ * -----------------------------------------
+ * Some would have prefered functions defined this way :
+ *	static int mydriver_ioctl_setrate(struct net_device *dev, 
+ *					  long rate, int auto)
+ * 1) The kernel code doesn't "validate" the content of iwreq_data, and
+ * can't do it (different hardware may have different notion of what a
+ * valid frequency is), so we don't pretend that we do it.
+ * 2) The above form is not extendable. If I want to add a flag (for
+ * example to distinguish setting max rate and basic rate), I would
+ * break the prototype. Using iwreq_data is more flexible.
+ * 3) Also, the above form is not generic (see above).
+ * 4) I don't expect driver developper using the wrong field of the
+ * union (Doh !), so static typechecking doesn't add much value.
+ * 5) Lastly, you can skip the union by doing :
+ *	static int mydriver_ioctl_setrate(struct net_device *dev,
+ *					  struct iw_request_info *info,
+ *					  struct iw_param *rrq,
+ *					  char *extra)
+ * And then adding the handler in the array like this :
+ *        (iw_handler) mydriver_ioctl_setrate,             // SIOCSIWRATE
+ *
+ * Using functions and not a registry
+ * ----------------------------------
+ * Another implementation option would have been for every instance to
+ * define a registry (a struct containing all the Wireless Extensions)
+ * and only have a function to commit the registry to the hardware.
+ * 1) This approach can be emulated by the current code, but not
+ * vice versa.
+ * 2) Some drivers don't keep any configuration in the driver, for them
+ * adding such a registry would be a significant bloat.
+ * 3) The code to translate from Wireless Extension to native format is
+ * needed anyway, so it would not reduce significantely the amount of code.
+ * 4) The current approach only selectively translate Wireless Extensions
+ * to native format and only selectively set, whereas the registry approach
+ * would require to translate all WE and set all parameters for any single
+ * change.
+ * 5) For many Wireless Extensions, the GET operation return the current
+ * dynamic value, not the value that was set.
+ *
+ * This header is <net/iw_handler.h>
+ * ---------------------------------
+ * 1) This header is kernel space only and should not be exported to
+ * user space. Headers in "include/linux/" are exported, headers in
+ * "include/net/" are not.
+ *
+ * Mixed 32/64 bit issues
+ * ----------------------
+ * The Wireless Extensions are designed to be 64 bit clean, by using only
+ * datatypes with explicit storage size.
+ * There are some issues related to kernel and user space using different
+ * memory model, and in particular 64bit kernel with 32bit user space.
+ * The problem is related to struct iw_point, that contains a pointer
+ * that *may* need to be translated.
+ * This is quite messy. The new API doesn't solve this problem (it can't),
+ * but is a step in the right direction :
+ * 1) Meta data about each ioctl is easily available, so we know what type
+ * of translation is needed.
+ * 2) The move of data between kernel and user space is only done in a single
+ * place in the kernel, so adding specific hooks in there is possible.
+ * 3) In the long term, it allows to move away from using ioctl as the
+ * user space API.
+ *
+ * So many comments and so few code
+ * --------------------------------
+ * That's a feature. Comments won't bloat the resulting kernel binary.
+ */
+
+/***************************** INCLUDES *****************************/
+
+#include <linux/wireless.h>		/* IOCTL user space API */
+
+/***************************** VERSION *****************************/
+/*
+ * This constant is used to know which version of the driver API is
+ * available. Hopefully, this will be pretty stable and no changes
+ * will be needed...
+ * I just plan to increment with each new version.
+ */
+#define IW_HANDLER_VERSION	2
+
+/**************************** CONSTANTS ****************************/
+
+/* Special error message for the driver to indicate that we
+ * should do a commit after return from the iw_handler */
+#define EIWCOMMIT	EINPROGRESS
+
+/* Flags available in struct iw_request_info */
+#define IW_REQUEST_FLAG_NONE	0x0000	/* No flag so far */
+
+/* Type of headers we know about (basically union iwreq_data) */
+#define IW_HEADER_TYPE_NULL	0	/* Not available */
+#define IW_HEADER_TYPE_CHAR	2	/* char [IFNAMSIZ] */
+#define IW_HEADER_TYPE_UINT	4	/* __u32 */
+#define IW_HEADER_TYPE_FREQ	5	/* struct iw_freq */
+#define IW_HEADER_TYPE_POINT	6	/* struct iw_point */
+#define IW_HEADER_TYPE_PARAM	7	/* struct iw_param */
+#define IW_HEADER_TYPE_ADDR	8	/* struct sockaddr */
+
+/* Handling flags */
+/* Most are not implemented. I just use them as a reminder of some
+ * cool features we might need one day ;-) */
+#define IW_DESCR_FLAG_NONE	0x0000	/* Obvious */
+/* Wrapper level flags */
+#define IW_DESCR_FLAG_DUMP	0x0001	/* Not part of the dump command */
+#define IW_DESCR_FLAG_EVENT	0x0002	/* Generate an event on SET */
+#define IW_DESCR_FLAG_RESTRICT	0x0004	/* GET request is ROOT only */
+/* Driver level flags */
+#define IW_DESCR_FLAG_WAIT	0x0100	/* Wait for driver event */
+
+/****************************** TYPES ******************************/
+
+/* ----------------------- WIRELESS HANDLER ----------------------- */
+/*
+ * A wireless handler is just a standard function, that looks like the
+ * ioctl handler.
+ * We also define there how a handler list look like... As the Wireless
+ * Extension space is quite dense, we use a simple array, which is faster
+ * (that's the perfect hash table ;-).
+ */
+
+/*
+ * Meta data about the request passed to the iw_handler.
+ * Most handlers can safely ignore what's in there.
+ * The 'cmd' field might come handy if you want to use the same handler
+ * for multiple command...
+ * This struct is also my long term insurance. I can add new fields here
+ * without breaking the prototype of iw_handler...
+ */
+struct iw_request_info
+{
+	__u16		cmd;		/* Wireless Extension command */
+	__u16		flags;		/* More to come ;-) */
+};
+
+/*
+ * This is how a function handling a Wireless Extension should look
+ * like (both get and set, standard and private).
+ */
+typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra);
+
+/*
+ * This define all the handler that the driver export.
+ * As you need only one per driver type, please use a static const
+ * shared by all driver instances... Same for the members...
+ * This will be linked from net_device in <linux/netdevice.h>
+ */
+struct iw_handler_def
+{
+	/* Number of handlers defined (more precisely, index of the
+	 * last defined handler + 1) */
+	__u16			num_standard;
+	__u16			num_private;
+	/* Number of private arg description */
+	__u16			num_private_args;
+
+	/* Array of handlers for standard ioctls
+	 * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
+	 */
+	iw_handler *		standard;
+
+	/* Array of handlers for private ioctls
+	 * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV]
+	 */
+	iw_handler *		private;
+
+	/* Arguments of private handler. This one is just a list, so you
+	 * can put it in any order you want and should not leave holes...
+	 * We will automatically export that to user space... */
+	struct iw_priv_args *	private_args;
+
+	/* In the long term, get_wireless_stats will move from
+	 * 'struct net_device' to here, to minimise bloat. */
+};
+
+/* ----------------------- WIRELESS EVENTS ----------------------- */
+/*
+ * Currently we don't support events, so let's just plan for the
+ * future...
+ */
+
+/*
+ * A Wireless Event.
+ */
+// How do we define short header ? We don't want a flag on length.
+// Probably a flag on event ? Highest bit to zero...
+struct iw_event
+{
+	__u16		length;			/* Lenght of this stuff */
+	__u16		event;			/* Wireless IOCTL */
+	union	iwreq_data	header;		/* IOCTL fixed payload */
+	char		extra[0];		/* Optional IOCTL data */
+};
+
+/* ---------------------- IOCTL DESCRIPTION ---------------------- */
+/*
+ * One of the main goal of the new interface is to deal entirely with
+ * user space/kernel space memory move.
+ * For that, we need to know :
+ *	o if iwreq is a pointer or contain the full data
+ *	o what is the size of the data to copy
+ *
+ * For private IOCTLs, we use the same rules as used by iwpriv and
+ * defined in struct iw_priv_args.
+ *
+ * For standard IOCTLs, things are quite different and we need to
+ * use the stuctures below. Actually, this struct is also more
+ * efficient, but that's another story...
+ */
+
+/*
+ * Describe how a standard IOCTL looks like.
+ */
+struct iw_ioctl_description
+{
+	__u8	header_type;		/* NULL, iw_point or other */
+	__u8	token_type;		/* Future */
+	__u16	token_size;		/* Granularity of payload */
+	__u16	min_tokens;		/* Min acceptable token number */
+	__u16	max_tokens;		/* Max acceptable token number */
+	__u32	flags;			/* Special handling of the request */
+};
+
+/* Need to think of short header translation table. Later. */
+
+/**************************** PROTOTYPES ****************************/
+/*
+ * Functions part of the Wireless Extensions (defined in net/core/wireless.c).
+ * Those may be called only within the kernel.
+ */
+
+/* First : function strictly used inside the kernel */
+
+/* Handle /proc/net/wireless, called in net/code/dev.c */
+extern int dev_get_wireless_info(char * buffer, char **start, off_t offset,
+				 int length);
+
+/* Handle IOCTLs, called in net/code/dev.c */
+extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
+
+/* Second : functions that may be called by driver modules */
+/* None yet */
+
+#endif	/* _LINUX_WIRELESS_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/ndisc.h linux/include/net/ndisc.h
--- linux.orig/include/net/ndisc.h	2001-11-22 19:47:42.000000000 +0000
+++ linux/include/net/ndisc.h	2002-07-20 01:08:29.000000000 +0000
@@ -42,11 +42,7 @@
 struct nd_msg {
         struct icmp6hdr	icmph;
         struct in6_addr	target;
-        struct {
-                __u8	opt_type;
-                __u8	opt_len;
-                __u8	link_addr[MAX_ADDR_LEN];
-        } opt;
+	__u8		opt[0];
 };
 
 struct ra_msg {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/pkt_sched.h linux/include/net/pkt_sched.h
--- linux.orig/include/net/pkt_sched.h	2001-11-22 19:47:12.000000000 +0000
+++ linux/include/net/pkt_sched.h	2002-07-20 01:08:28.000000000 +0000
@@ -8,6 +8,7 @@
 #define PSCHED_CLOCK_SOURCE	PSCHED_JIFFIES
 
 #include <linux/config.h>
+#include <linux/types.h>
 #include <linux/pkt_sched.h>
 #include <net/pkt_cls.h>
 
@@ -221,7 +222,7 @@
 
 #define PSCHED_EXPORTLIST_2
 
-#if ~0UL == 0xFFFFFFFF
+#if BITS_PER_LONG <= 32
 
 #define PSCHED_WATCHER unsigned long
 
@@ -358,8 +359,8 @@
 #define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2))
 #define PSCHED_TDIFF_SAFE(tv1, tv2, bound, guard) \
 ({ \
-	   long __delta = (tv1) - (tv2); \
-	   if ( __delta > (bound)) {  __delta = (bound); guard; } \
+	   long long __delta = (tv1) - (tv2); \
+	   if ( __delta > (long long)(bound)) {  __delta = (bound); guard; } \
 	   __delta; \
 })
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/route.h linux/include/net/route.h
--- linux.orig/include/net/route.h	2002-02-25 19:38:13.000000000 +0000
+++ linux/include/net/route.h	2002-07-20 01:08:21.000000000 +0000
@@ -110,6 +110,10 @@
         unsigned int out_hit;
         unsigned int out_slow_tot;
         unsigned int out_slow_mc;
+        unsigned int gc_total;
+        unsigned int gc_ignored;
+        unsigned int gc_goal_miss;
+        unsigned int gc_dst_overflow;
 } ____cacheline_aligned_in_smp;
 
 extern struct ip_rt_acct *ip_rt_acct;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/sock.h linux/include/net/sock.h
--- linux.orig/include/net/sock.h	2001-12-21 17:42:04.000000000 +0000
+++ linux/include/net/sock.h	2002-07-20 01:08:27.000000000 +0000
@@ -283,9 +283,9 @@
 	/* Data for direct copy to user */
 	struct {
 		struct sk_buff_head	prequeue;
-		int			memory;
 		struct task_struct	*task;
 		struct iovec		*iov;
+		int			memory;
 		int			len;
 	} ucopy;
 
@@ -484,7 +484,7 @@
 do {	spin_lock_init(&((__sk)->lock.slock)); \
 	(__sk)->lock.users = 0; \
 	init_waitqueue_head(&((__sk)->lock.wq)); \
-} while(0);
+} while(0)
 
 struct sock {
 	/* Socket demultiplex comparisons on incoming packets. */
@@ -1221,16 +1221,13 @@
 
 #define SOCK_MIN_SNDBUF 2048
 #define SOCK_MIN_RCVBUF 256
-/* Must be less or equal SOCK_MIN_SNDBUF */
-#define SOCK_MIN_WRITE_SPACE	SOCK_MIN_SNDBUF
 
 /*
  *	Default write policy as shown to user space via poll/select/SIGIO
- *	Kernel internally doesn't use the MIN_WRITE_SPACE threshold.
  */
 static inline int sock_writeable(struct sock *sk) 
 {
-	return sock_wspace(sk) >= SOCK_MIN_WRITE_SPACE;
+	return atomic_read(&sk->wmem_alloc) < (sk->sndbuf / 2);
 }
 
 static inline int gfp_any(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/net/tcp.h linux/include/net/tcp.h
--- linux.orig/include/net/tcp.h	2001-11-22 19:47:22.000000000 +0000
+++ linux/include/net/tcp.h	2002-07-20 01:08:25.000000000 +0000
@@ -75,7 +75,7 @@
  */
 struct tcp_bind_bucket {
 	unsigned short		port;
-	unsigned short		fastreuse;
+	signed short		fastreuse;
 	struct tcp_bind_bucket	*next;
 	struct sock		*owners;
 	struct tcp_bind_bucket	**pprev;
@@ -460,6 +460,7 @@
 extern int sysctl_tcp_rmem[3];
 extern int sysctl_tcp_app_win;
 extern int sysctl_tcp_adv_win_scale;
+extern int sysctl_tcp_tw_reuse;
 
 extern atomic_t tcp_memory_allocated;
 extern atomic_t tcp_sockets_allocated;
@@ -498,7 +499,7 @@
 	__u16			rmt_port;
 	__u16			mss;
 	__u8			retrans;
-	__u8			index;
+	__u8			__pad;
 	__u16	snd_wscale : 4, 
 		rcv_wscale : 4, 
 		tstamp_ok : 1,
@@ -568,9 +569,7 @@
 							 struct sk_buff *skb,
 							 struct open_request *req,
 							 struct dst_entry *dst);
-	
-	int			(*hash_connecting)	(struct sock *sk);
-
+    
 	int			(*remember_stamp)	(struct sock *sk);
 
 	__u16			net_header_len;
@@ -772,8 +771,7 @@
 					       struct sockaddr *uaddr,
 					       int addr_len);
 
-extern int			tcp_connect(struct sock *sk,
-					    struct sk_buff *skb);
+extern int			tcp_connect(struct sock *sk);
 
 extern struct sk_buff *		tcp_make_synack(struct sock *sk,
 						struct dst_entry *dst,
@@ -821,6 +819,11 @@
 
 extern const char timer_bug_msg[];
 
+/* Read 'sendfile()'-style from a TCP socket */
+typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
+				unsigned int, size_t);
+extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
+			 sk_read_actor_t recv_actor);
 
 static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
 {
@@ -1329,7 +1332,8 @@
 		if (tp->ucopy.memory > sk->rcvbuf) {
 			struct sk_buff *skb1;
 
-			if (sk->lock.users) BUG();
+			if (sk->lock.users)
+				out_of_line_bug();
 
 			while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
 				sk->backlog_rcv(sk, skb1);
@@ -1825,6 +1829,6 @@
 	return 1;
 }
 
-#define TCP_CHECK_TIMER(sk) do { } while (0);
+#define TCP_CHECK_TIMER(sk) do { } while (0)
 
 #endif	/* _TCP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/pcmcia/ss.h linux/include/pcmcia/ss.h
--- linux.orig/include/pcmcia/ss.h	2001-10-11 16:43:29.000000000 +0000
+++ linux/include/pcmcia/ss.h	2002-07-20 01:08:34.000000000 +0000
@@ -86,6 +86,7 @@
 #define SS_SPKR_ENA	0x0100
 #define SS_OUTPUT_ENA	0x0200
 #define SS_DEBOUNCED	0x0400	/* Tell driver that the debounce delay has ended */
+#define SS_ZVCARD	0x0800
 
 /* Flags for I/O port and memory windows */
 #define MAP_ACTIVE	0x01
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/include/scsi/sg.h linux/include/scsi/sg.h
--- linux.orig/include/scsi/sg.h	2001-12-21 17:42:04.000000000 +0000
+++ linux/include/scsi/sg.h	2002-07-20 01:08:34.000000000 +0000
@@ -9,11 +9,15 @@
 Original driver (sg.h):
 *       Copyright (C) 1992 Lawrence Foard
 Version 2 and 3 extensions to driver:
-*       Copyright (C) 1998 - 2001 Douglas Gilbert
+*       Copyright (C) 1998 - 2002 Douglas Gilbert
 
-    Version: 3.1.22 (20011208)
+    Version: 3.1.23 (20020318)
     This version is for 2.4 series kernels.
 
+    Changes since 3.1.22 (20011208)
+	- change EACCES to EPERM when O_RDONLY is insufficient
+	- suppress newlines in host string ( /proc/scsi/sg/host_strs output)
+	- fix xfer direction, old interface, short reply_len [Travers Carter]
     Changes since 3.1.21 (20011029)
     	- add support for SG_FLAG_MMAP_IO [permit mmap() on sg devices]
     	- update documentation pointers in this header
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/init/do_mounts.c linux/init/do_mounts.c
--- linux.orig/init/do_mounts.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/init/do_mounts.c	2002-07-20 01:08:31.000000000 +0000
@@ -0,0 +1,1010 @@
+#define __KERNEL_SYSCALLS__
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/unistd.h>
+#include <linux/ctype.h>
+#include <linux/blk.h>
+#include <linux/fd.h>
+#include <linux/tty.h>
+#include <linux/init.h>
+
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/nfs_mount.h>
+#include <linux/minix_fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/romfs_fs.h>
+
+#define BUILD_CRAMDISK
+
+extern int get_filesystem_list(char * buf);
+
+asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
+	 unsigned long flags, void *data);
+asmlinkage long sys_mkdir(char *name, int mode);
+asmlinkage long sys_chdir(char *name);
+asmlinkage long sys_chroot(char *name);
+asmlinkage long sys_unlink(char *name);
+asmlinkage long sys_symlink(char *old, char *new);
+asmlinkage long sys_mknod(char *name, int mode, dev_t dev);
+asmlinkage long sys_umount(char *name, int flags);
+asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
+static int __initdata mount_initrd = 1;
+
+static int __init no_initrd(char *str)
+{
+	mount_initrd = 0;
+	return 1;
+}
+
+__setup("noinitrd", no_initrd);
+#else
+static int __initdata mount_initrd = 0;
+#endif
+
+int __initdata rd_doload;	/* 1 = load RAM disk, 0 = don't load */
+
+int root_mountflags = MS_RDONLY | MS_VERBOSE;
+static char root_device_name[64];
+
+/* this is initialized in init/main.c */
+kdev_t ROOT_DEV;
+
+static int do_devfs = 0;
+
+static int __init load_ramdisk(char *str)
+{
+	rd_doload = simple_strtol(str,NULL,0) & 3;
+	return 1;
+}
+__setup("load_ramdisk=", load_ramdisk);
+
+static int __init readonly(char *str)
+{
+	if (*str)
+		return 0;
+	root_mountflags |= MS_RDONLY;
+	return 1;
+}
+
+static int __init readwrite(char *str)
+{
+	if (*str)
+		return 0;
+	root_mountflags &= ~MS_RDONLY;
+	return 1;
+}
+
+__setup("ro", readonly);
+__setup("rw", readwrite);
+
+static struct dev_name_struct {
+	const char *name;
+	const int num;
+} root_dev_names[] __initdata = {
+	{ "nfs",     0x00ff },
+	{ "hda",     0x0300 },
+	{ "hdb",     0x0340 },
+	{ "loop",    0x0700 },
+	{ "hdc",     0x1600 },
+	{ "hdd",     0x1640 },
+	{ "hde",     0x2100 },
+	{ "hdf",     0x2140 },
+	{ "hdg",     0x2200 },
+	{ "hdh",     0x2240 },
+	{ "hdi",     0x3800 },
+	{ "hdj",     0x3840 },
+	{ "hdk",     0x3900 },
+	{ "hdl",     0x3940 },
+	{ "hdm",     0x5800 },
+	{ "hdn",     0x5840 },
+	{ "hdo",     0x5900 },
+	{ "hdp",     0x5940 },
+	{ "hdq",     0x5A00 },
+	{ "hdr",     0x5A40 },
+	{ "hds",     0x5B00 },
+	{ "hdt",     0x5B40 },
+	{ "sda",     0x0800 },
+	{ "sdb",     0x0810 },
+	{ "sdc",     0x0820 },
+	{ "sdd",     0x0830 },
+	{ "sde",     0x0840 },
+	{ "sdf",     0x0850 },
+	{ "sdg",     0x0860 },
+	{ "sdh",     0x0870 },
+	{ "sdi",     0x0880 },
+	{ "sdj",     0x0890 },
+	{ "sdk",     0x08a0 },
+	{ "sdl",     0x08b0 },
+	{ "sdm",     0x08c0 },
+	{ "sdn",     0x08d0 },
+	{ "sdo",     0x08e0 },
+	{ "sdp",     0x08f0 },
+	{ "ada",     0x1c00 },
+	{ "adb",     0x1c10 },
+	{ "adc",     0x1c20 },
+	{ "add",     0x1c30 },
+	{ "ade",     0x1c40 },
+	{ "fd",      0x0200 },
+	{ "md",      0x0900 },	     
+	{ "xda",     0x0d00 },
+	{ "xdb",     0x0d40 },
+	{ "ram",     0x0100 },
+	{ "scd",     0x0b00 },
+	{ "mcd",     0x1700 },
+	{ "cdu535",  0x1800 },
+	{ "sonycd",  0x1800 },
+	{ "aztcd",   0x1d00 },
+	{ "cm206cd", 0x2000 },
+	{ "gscd",    0x1000 },
+	{ "sbpcd",   0x1900 },
+	{ "eda",     0x2400 },
+	{ "edb",     0x2440 },
+	{ "pda",	0x2d00 },
+	{ "pdb",	0x2d10 },
+	{ "pdc",	0x2d20 },
+	{ "pdd",	0x2d30 },
+	{ "pcd",	0x2e00 },
+	{ "pf",		0x2f00 },
+	{ "apblock", APBLOCK_MAJOR << 8},
+	{ "ddv", DDV_MAJOR << 8},
+	{ "jsfd",    JSFD_MAJOR << 8},
+#if defined(CONFIG_ARCH_S390)
+	{ "dasda", (DASD_MAJOR << MINORBITS) },
+	{ "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
+	{ "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
+	{ "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
+	{ "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
+	{ "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
+	{ "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
+	{ "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
+#endif
+#if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
+	{ "ida/c0d0p",0x4800 },
+	{ "ida/c0d1p",0x4810 },
+	{ "ida/c0d2p",0x4820 },
+	{ "ida/c0d3p",0x4830 },
+	{ "ida/c0d4p",0x4840 },
+	{ "ida/c0d5p",0x4850 },
+	{ "ida/c0d6p",0x4860 },
+	{ "ida/c0d7p",0x4870 },
+	{ "ida/c0d8p",0x4880 },
+	{ "ida/c0d9p",0x4890 },
+	{ "ida/c0d10p",0x48A0 },
+	{ "ida/c0d11p",0x48B0 },
+	{ "ida/c0d12p",0x48C0 },
+	{ "ida/c0d13p",0x48D0 },
+	{ "ida/c0d14p",0x48E0 },
+	{ "ida/c0d15p",0x48F0 },
+#endif
+#if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
+	{ "cciss/c0d0p",0x6800 },
+	{ "cciss/c0d1p",0x6810 },
+	{ "cciss/c0d2p",0x6820 },
+	{ "cciss/c0d3p",0x6830 },
+	{ "cciss/c0d4p",0x6840 },
+	{ "cciss/c0d5p",0x6850 },
+	{ "cciss/c0d6p",0x6860 },
+	{ "cciss/c0d7p",0x6870 },
+	{ "cciss/c0d8p",0x6880 },
+	{ "cciss/c0d9p",0x6890 },
+	{ "cciss/c0d10p",0x68A0 },
+	{ "cciss/c0d11p",0x68B0 },
+	{ "cciss/c0d12p",0x68C0 },
+	{ "cciss/c0d13p",0x68D0 },
+	{ "cciss/c0d14p",0x68E0 },
+	{ "cciss/c0d15p",0x68F0 },
+#endif
+	{ "ataraid/d0p",0x7200 },
+	{ "ataraid/d1p",0x7210 },
+	{ "ataraid/d2p",0x7220 },
+	{ "ataraid/d3p",0x7230 },
+	{ "ataraid/d4p",0x7240 },
+	{ "ataraid/d5p",0x7250 },
+	{ "ataraid/d6p",0x7260 },
+	{ "ataraid/d7p",0x7270 },
+	{ "ataraid/d8p",0x7280 },
+	{ "ataraid/d9p",0x7290 },
+	{ "ataraid/d10p",0x72A0 },
+	{ "ataraid/d11p",0x72B0 },
+	{ "ataraid/d12p",0x72C0 },
+	{ "ataraid/d13p",0x72D0 },
+	{ "ataraid/d14p",0x72E0 },
+	{ "ataraid/d15p",0x72F0 },
+	{ "nftla", 0x5d00 },
+	{ "nftlb", 0x5d10 },
+	{ "nftlc", 0x5d20 },
+	{ "nftld", 0x5d30 },
+	{ "ftla", 0x2c00 },
+	{ "ftlb", 0x2c08 },
+	{ "ftlc", 0x2c10 },
+	{ "ftld", 0x2c18 },
+	{ "mtdblock", 0x1f00 },
+	{ NULL, 0 }
+};
+
+kdev_t __init name_to_kdev_t(char *line)
+{
+	int base = 0;
+
+	if (strncmp(line,"/dev/",5) == 0) {
+		struct dev_name_struct *dev = root_dev_names;
+		line += 5;
+		do {
+			int len = strlen(dev->name);
+			if (strncmp(line,dev->name,len) == 0) {
+				line += len;
+				base = dev->num;
+				break;
+			}
+			dev++;
+		} while (dev->name);
+	}
+	return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
+}
+
+static int __init root_dev_setup(char *line)
+{
+	int i;
+	char ch;
+
+	ROOT_DEV = name_to_kdev_t(line);
+	memset (root_device_name, 0, sizeof root_device_name);
+	if (strncmp (line, "/dev/", 5) == 0) line += 5;
+	for (i = 0; i < sizeof root_device_name - 1; ++i)
+	{
+	    ch = line[i];
+	    if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
+	    root_device_name[i] = ch;
+	}
+	return 1;
+}
+
+__setup("root=", root_dev_setup);
+
+static char * __initdata root_mount_data;
+static int __init root_data_setup(char *str)
+{
+	root_mount_data = str;
+	return 1;
+}
+
+static char * __initdata root_fs_names;
+static int __init fs_names_setup(char *str)
+{
+	root_fs_names = str;
+	return 1;
+}
+
+__setup("rootflags=", root_data_setup);
+__setup("rootfstype=", fs_names_setup);
+
+static void __init get_fs_names(char *page)
+{
+	char *s = page;
+
+	if (root_fs_names) {
+		strcpy(page, root_fs_names);
+		while (*s++) {
+			if (s[-1] == ',')
+				s[-1] = '\0';
+		}
+	} else {
+		int len = get_filesystem_list(page);
+		char *p, *next;
+
+		page[len] = '\0';
+		for (p = page-1; p; p = next) {
+			next = strchr(++p, '\n');
+			if (*p++ != '\t')
+				continue;
+			while ((*s++ = *p++) != '\n')
+				;
+			s[-1] = '\0';
+		}
+	}
+	*s = '\0';
+}
+static void __init mount_block_root(char *name, int flags)
+{
+	char *fs_names = __getname();
+	char *p;
+
+	get_fs_names(fs_names);
+retry:
+	for (p = fs_names; *p; p += strlen(p)+1) {
+		int err = sys_mount(name, "/root", p, flags, root_mount_data);
+		switch (err) {
+			case 0:
+				goto out;
+			case -EACCES:
+				flags |= MS_RDONLY;
+				goto retry;
+			case -EINVAL:
+				continue;
+		}
+	        /*
+		 * Allow the user to distinguish between failed open
+		 * and bad superblock on root device.
+		 */
+		printk ("VFS: Cannot open root device \"%s\" or %s\n",
+			root_device_name, kdevname (ROOT_DEV));
+		printk ("Please append a correct \"root=\" boot option\n");
+		panic("VFS: Unable to mount root fs on %s",
+			kdevname(ROOT_DEV));
+	}
+	panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
+out:
+	putname(fs_names);
+	sys_chdir("/root");
+	ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+	printk("VFS: Mounted root (%s filesystem)%s.\n",
+		current->fs->pwdmnt->mnt_sb->s_type->name,
+		(current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
+}
+ 
+#ifdef CONFIG_ROOT_NFS
+static int __init mount_nfs_root(void)
+{
+	void *data = nfs_root_data();
+
+	if (data && sys_mount("/dev/root","/root","nfs",root_mountflags,data) == 0)
+		return 1;
+	return 0;
+}
+#endif
+
+static int __init create_dev(char *name, kdev_t dev, char *devfs_name)
+{
+	void *handle;
+	char path[64];
+	int n;
+
+	sys_unlink(name);
+	if (!do_devfs)
+		return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev));
+
+	handle = devfs_find_handle(NULL, dev ? NULL : devfs_name,
+				MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1);
+	if (!handle)
+		return -1;
+	n = devfs_generate_path(handle, path + 5, sizeof (path) - 5);
+	if (n < 0)
+		return -1;
+	return sys_symlink(path + n + 5, name);
+}
+
+#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
+static void __init change_floppy(char *fmt, ...)
+{
+	struct termios termios;
+	char buf[80];
+	char c;
+	int fd;
+	va_list args;
+	va_start(args, fmt);
+	vsprintf(buf, fmt, args);
+	va_end(args);
+	fd = open("/dev/root", O_RDWR | O_NDELAY, 0);
+	if (fd >= 0) {
+		sys_ioctl(fd, FDEJECT, 0);
+		close(fd);
+	}
+	printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
+	fd = open("/dev/console", O_RDWR, 0);
+	if (fd >= 0) {
+		sys_ioctl(fd, TCGETS, (long)&termios);
+		termios.c_lflag &= ~ICANON;
+		sys_ioctl(fd, TCSETSF, (long)&termios);
+		read(fd, &c, 1);
+		termios.c_lflag |= ICANON;
+		sys_ioctl(fd, TCSETSF, (long)&termios);
+		close(fd);
+	}
+}
+#endif
+
+#ifdef CONFIG_BLK_DEV_RAM
+
+int __initdata rd_prompt = 1;	/* 1 = prompt for RAM disk, 0 = don't prompt */
+
+static int __init prompt_ramdisk(char *str)
+{
+	rd_prompt = simple_strtol(str,NULL,0) & 1;
+	return 1;
+}
+__setup("prompt_ramdisk=", prompt_ramdisk);
+
+int __initdata rd_image_start;		/* starting block # of image */
+
+static int __init ramdisk_start_setup(char *str)
+{
+	rd_image_start = simple_strtol(str,NULL,0);
+	return 1;
+}
+__setup("ramdisk_start=", ramdisk_start_setup);
+
+static int __init crd_load(int in_fd, int out_fd);
+
+/*
+ * This routine tries to find a RAM disk image to load, and returns the
+ * number of blocks to read for a non-compressed image, 0 if the image
+ * is a compressed image, and -1 if an image with the right magic
+ * numbers could not be found.
+ *
+ * We currently check for the following magic numbers:
+ * 	minix
+ * 	ext2
+ *	romfs
+ * 	gzip
+ */
+static int __init 
+identify_ramdisk_image(int fd, int start_block)
+{
+	const int size = 512;
+	struct minix_super_block *minixsb;
+	struct ext2_super_block *ext2sb;
+	struct romfs_super_block *romfsb;
+	int nblocks = -1;
+	unsigned char *buf;
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (buf == 0)
+		return -1;
+
+	minixsb = (struct minix_super_block *) buf;
+	ext2sb = (struct ext2_super_block *) buf;
+	romfsb = (struct romfs_super_block *) buf;
+	memset(buf, 0xe5, size);
+
+	/*
+	 * Read block 0 to test for gzipped kernel
+	 */
+	lseek(fd, start_block * BLOCK_SIZE, 0);
+	read(fd, buf, size);
+
+	/*
+	 * If it matches the gzip magic numbers, return -1
+	 */
+	if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
+		printk(KERN_NOTICE
+		       "RAMDISK: Compressed image found at block %d\n",
+		       start_block);
+		nblocks = 0;
+		goto done;
+	}
+
+	/* romfs is at block zero too */
+	if (romfsb->word0 == ROMSB_WORD0 &&
+	    romfsb->word1 == ROMSB_WORD1) {
+		printk(KERN_NOTICE
+		       "RAMDISK: romfs filesystem found at block %d\n",
+		       start_block);
+		nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
+		goto done;
+	}
+
+	/*
+	 * Read block 1 to test for minix and ext2 superblock
+	 */
+	lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
+	read(fd, buf, size);
+
+	/* Try minix */
+	if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
+	    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
+		printk(KERN_NOTICE
+		       "RAMDISK: Minix filesystem found at block %d\n",
+		       start_block);
+		nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
+		goto done;
+	}
+
+	/* Try ext2 */
+	if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
+		printk(KERN_NOTICE
+		       "RAMDISK: ext2 filesystem found at block %d\n",
+		       start_block);
+		nblocks = le32_to_cpu(ext2sb->s_blocks_count);
+		goto done;
+	}
+
+	printk(KERN_NOTICE
+	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
+	       start_block);
+	
+done:
+	lseek(fd, start_block * BLOCK_SIZE, 0);
+	kfree(buf);
+	return nblocks;
+}
+#endif
+
+static int __init rd_load_image(char *from)
+{
+	int res = 0;
+
+#ifdef CONFIG_BLK_DEV_RAM
+	int in_fd, out_fd;
+	int nblocks, rd_blocks, devblocks, i;
+	char *buf;
+	unsigned short rotate = 0;
+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+	char rotator[4] = { '|' , '/' , '-' , '\\' };
+#endif
+
+	out_fd = open("/dev/ram", O_RDWR, 0);
+	if (out_fd < 0)
+		goto out;
+
+	in_fd = open(from, O_RDONLY, 0);
+	if (in_fd < 0)
+		goto noclose_input;
+
+	nblocks = identify_ramdisk_image(in_fd, rd_image_start);
+	if (nblocks < 0)
+		goto done;
+
+	if (nblocks == 0) {
+#ifdef BUILD_CRAMDISK
+		if (crd_load(in_fd, out_fd) == 0)
+			goto successful_load;
+#else
+		printk(KERN_NOTICE
+		       "RAMDISK: Kernel does not support compressed "
+		       "RAM disk images\n");
+#endif
+		goto done;
+	}
+
+	/*
+	 * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
+	 * rd_load_image will work only with filesystem BLOCK_SIZE wide!
+	 * So make sure to use 1k blocksize while generating ext2fs
+	 * ramdisk-images.
+	 */
+	if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
+		rd_blocks = 0;
+	else
+		rd_blocks >>= 1;
+
+	if (nblocks > rd_blocks) {
+		printk("RAMDISK: image too big! (%d/%d blocks)\n",
+		       nblocks, rd_blocks);
+		goto done;
+	}
+		
+	/*
+	 * OK, time to copy in the data
+	 */
+	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
+	if (buf == 0) {
+		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
+		goto done;
+	}
+
+	if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
+		devblocks = 0;
+	else
+		devblocks >>= 1;
+
+	if (strcmp(from, "/dev/initrd") == 0)
+		devblocks = nblocks;
+
+	if (devblocks == 0) {
+		printk(KERN_ERR "RAMDISK: could not determine device size\n");
+		goto done;
+	}
+
+	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ", 
+		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
+	for (i=0; i < nblocks; i++) {
+		if (i && (i % devblocks == 0)) {
+			printk("done disk #%d.\n", i/devblocks);
+			rotate = 0;
+			if (close(in_fd)) {
+				printk("Error closing the disk.\n");
+				goto noclose_input;
+			}
+			change_floppy("disk #%d", i/devblocks+1);
+			in_fd = open(from, O_RDONLY, 0);
+			if (in_fd < 0)  {
+				printk("Error opening disk.\n");
+				goto noclose_input;
+			}
+			printk("Loading disk #%d... ", i/devblocks+1);
+		}
+		read(in_fd, buf, BLOCK_SIZE);
+		write(out_fd, buf, BLOCK_SIZE);
+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+		if (!(i % 16)) {
+			printk("%c\b", rotator[rotate & 0x3]);
+			rotate++;
+		}
+#endif
+	}
+	printk("done.\n");
+	kfree(buf);
+
+successful_load:
+	res = 1;
+done:
+	close(in_fd);
+noclose_input:
+	close(out_fd);
+out:
+	sys_unlink("/dev/ram");
+#endif
+	return res;
+}
+
+static int __init rd_load_disk(int n)
+{
+#ifdef CONFIG_BLK_DEV_RAM
+	if (rd_prompt)
+		change_floppy("root floppy disk to be loaded into RAM disk");
+	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
+#endif
+	return rd_load_image("/dev/root");
+}
+
+#ifdef CONFIG_DEVFS_FS
+
+static void __init convert_name(char *prefix, char *name, char *p, int part)
+{
+	int host, bus, target, lun;
+	char dest[64];
+	char src[64];
+	char *base = p - 1;
+
+	/*  Decode "c#b#t#u#"  */
+	if (*p++ != 'c')
+		return;
+	host = simple_strtol(p, &p, 10);
+	if (*p++ != 'b')
+		return;
+	bus = simple_strtol(p, &p, 10);
+	if (*p++ != 't')
+		return;
+	target = simple_strtol(p, &p, 10);
+	if (*p++ != 'u')
+		return;
+	lun = simple_strtol(p, &p, 10);
+	if (!part)
+		sprintf(dest, "%s/host%d/bus%d/target%d/lun%d",
+				prefix, host, bus, target, lun);
+	else if (*p++ == 'p')
+		sprintf(dest, "%s/host%d/bus%d/target%d/lun%d/part%s",
+				prefix, host, bus, target, lun, p);
+	else
+		sprintf(dest, "%s/host%d/bus%d/target%d/lun%d/disc",
+				prefix, host, bus, target, lun);
+	*base = '\0';
+	sprintf(src, "/dev/%s", name);
+	sys_mkdir(src, 0755);
+	*base = '/';
+	sprintf(src, "/dev/%s", name);
+	sys_symlink(dest, src);
+}
+
+static void __init devfs_make_root(char *name)
+{
+
+	if (!strncmp(name, "sd/", 3))
+		convert_name("../scsi", name, name+3, 1);
+	else if (!strncmp(name, "sr/", 3))
+		convert_name("../scsi", name, name+3, 0);
+	else if (!strncmp(name, "ide/hd/", 7))
+		convert_name("..", name, name + 7, 1);
+	else if (!strncmp(name, "ide/cd/", 7))
+		convert_name("..", name, name + 7, 0);
+}
+#else
+static void __init devfs_make_root(char *name)
+{
+}
+#endif
+
+static void __init mount_root(void)
+{
+#ifdef CONFIG_ROOT_NFS
+	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
+		if (mount_nfs_root()) {
+			sys_chdir("/root");
+			ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+			printk("VFS: Mounted root (nfs filesystem).\n");
+			return;
+		}
+		printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
+		ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
+	}
+#endif
+	devfs_make_root(root_device_name);
+	create_dev("/dev/root", ROOT_DEV, root_device_name);
+#ifdef CONFIG_BLK_DEV_FD
+	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
+		/* rd_doload is 2 for a dual initrd/ramload setup */
+		if (rd_doload==2) {
+			if (rd_load_disk(1)) {
+				ROOT_DEV = MKDEV(RAMDISK_MAJOR, 1);
+				create_dev("/dev/root", ROOT_DEV, NULL);
+			}
+		} else
+			change_floppy("root floppy");
+	}
+#endif
+	mount_block_root("/dev/root", root_mountflags);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static int do_linuxrc(void * shell)
+{
+	static char *argv[] = { "linuxrc", NULL, };
+	extern char * envp_init[];
+
+	sys_chdir("/root");
+	sys_mount(".", "/", NULL, MS_MOVE, NULL);
+	sys_chroot(".");
+
+	mount_devfs_fs ();
+
+	close(0);close(1);close(2);
+	setsid();
+	(void) open("/dev/console",O_RDWR,0);
+	(void) dup(0);
+	(void) dup(0);
+	return execve(shell, argv, envp_init);
+}
+
+#endif
+
+static void __init handle_initrd(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	int ram0 = kdev_t_to_nr(MKDEV(RAMDISK_MAJOR,0));
+	int error;
+	int i, pid;
+
+	create_dev("/dev/root.old", ram0, NULL);
+	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
+	sys_mkdir("/old", 0700);
+	sys_chdir("/old");
+
+	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
+	if (pid > 0) {
+		while (pid != wait(&i)) {
+			current->policy |= SCHED_YIELD;
+			schedule();
+		}
+	}
+
+	sys_mount("..", ".", NULL, MS_MOVE, NULL);
+	sys_umount("/old/dev", 0);
+
+	if (real_root_dev == ram0) {
+		sys_chdir("/old");
+		return;
+	}
+
+	ROOT_DEV = real_root_dev;
+	mount_root();
+
+	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
+	error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
+	if (!error)
+		printk("okay\n");
+	else {
+		int fd = open("/dev/root.old", O_RDWR, 0);
+		printk("failed\n");
+		printk(KERN_NOTICE "Unmounting old root\n");
+		sys_umount("/old", MNT_DETACH);
+		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
+		if (fd < 0) {
+			error = fd;
+		} else {
+			error = sys_ioctl(fd, BLKFLSBUF, 0);
+			close(fd);
+		}
+		printk(!error ? "okay\n" : "failed\n");
+	}
+#endif
+}
+
+static int __init initrd_load(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
+	create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
+#endif
+	return rd_load_image("/dev/initrd");
+}
+
+/*
+ * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
+ */
+void prepare_namespace(void)
+{
+	int is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
+#ifdef CONFIG_ALL_PPC
+	extern void arch_discover_root(void);
+	arch_discover_root();
+#endif /* CONFIG_ALL_PPC */
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (!initrd_start)
+		mount_initrd = 0;
+	real_root_dev = ROOT_DEV;
+#endif
+	sys_mkdir("/dev", 0700);
+	sys_mkdir("/root", 0700);
+	sys_mknod("/dev/console", S_IFCHR|0600, MKDEV(TTYAUX_MAJOR, 1));
+#ifdef CONFIG_DEVFS_FS
+	sys_mount("devfs", "/dev", "devfs", 0, NULL);
+	do_devfs = 1;
+#endif
+
+	create_dev("/dev/root", ROOT_DEV, NULL);
+	if (mount_initrd) {
+		if (initrd_load() && ROOT_DEV != MKDEV(RAMDISK_MAJOR, 0)) {
+			handle_initrd();
+			goto out;
+		}
+	} else if (is_floppy && rd_doload && rd_load_disk(0))
+		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	mount_root();
+out:
+	sys_umount("/dev", 0);
+	sys_mount(".", "/", NULL, MS_MOVE, NULL);
+	sys_chroot(".");
+	mount_devfs_fs ();
+}
+
+#ifdef BUILD_CRAMDISK
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+
+#ifndef memzero
+#define memzero(s, n)     memset ((s), 0, (n))
+#endif
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define INBUFSIZ 4096
+#define WSIZE 0x8000    /* window size--must be a power of two, and */
+			/*  at least 32K for zip's deflate method */
+
+static uch *inbuf;
+static uch *window;
+
+static unsigned insize;  /* valid bytes in inbuf */
+static unsigned inptr;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt;  /* bytes in output buffer */
+static int exit_code;
+static long bytes_out;
+static int crd_infd, crd_outfd;
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+		
+/* Diagnostic functions (stubbed out) */
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+#define STATIC static
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+#include "../lib/inflate.c"
+
+static void __init *malloc(int size)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+
+static void __init free(void *where)
+{
+	kfree(where);
+}
+
+static void __init gzip_mark(void **ptr)
+{
+}
+
+static void __init gzip_release(void **ptr)
+{
+}
+
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int __init fill_inbuf(void)
+{
+	if (exit_code) return -1;
+	
+	insize = read(crd_infd, inbuf, INBUFSIZ);
+	if (insize == 0) return -1;
+
+	inptr = 1;
+
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void __init flush_window(void)
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in, ch;
+    
+    write(crd_outfd, window, outcnt);
+    in = window;
+    for (n = 0; n < outcnt; n++) {
+	    ch = *in++;
+	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void __init error(char *x)
+{
+	printk(KERN_ERR "%s", x);
+	exit_code = 1;
+}
+
+static int __init crd_load(int in_fd, int out_fd)
+{
+	int result;
+
+	insize = 0;		/* valid bytes in inbuf */
+	inptr = 0;		/* index of next byte to be processed in inbuf */
+	outcnt = 0;		/* bytes in output buffer */
+	exit_code = 0;
+	bytes_out = 0;
+	crc = (ulg)0xffffffffL; /* shift register contents */
+
+	crd_infd = in_fd;
+	crd_outfd = out_fd;
+	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
+	if (inbuf == 0) {
+		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
+		return -1;
+	}
+	window = kmalloc(WSIZE, GFP_KERNEL);
+	if (window == 0) {
+		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
+		kfree(inbuf);
+		return -1;
+	}
+	makecrc();
+	result = gunzip();
+	kfree(inbuf);
+	kfree(window);
+	return result;
+}
+
+#endif  /* BUILD_CRAMDISK */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/init/main.c linux/init/main.c
--- linux.orig/init/main.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/init/main.c	2002-07-20 01:08:27.000000000 +0000
@@ -106,9 +106,6 @@
 #if defined(CONFIG_SYSVIPC)
 extern void ipc_init(void);
 #endif
-#ifdef CONFIG_PERFMON
-extern void perfmon_init(void);
-#endif
 
 /*
  * Boot command-line arguments
@@ -121,17 +118,10 @@
 
 int rows, cols;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
-#endif
-
-int root_mountflags = MS_RDONLY;
 char *execute_command;
-char root_device_name[64];
-
 
 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
-static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
+char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 
 static int __init profile_setup(char *str)
 {
@@ -142,175 +132,6 @@
 
 __setup("profile=", profile_setup);
 
-
-static struct dev_name_struct {
-	const char *name;
-	const int num;
-} root_dev_names[] __initdata = {
-	{ "nfs",     0x00ff },
-	{ "hda",     0x0300 },
-	{ "hdb",     0x0340 },
-	{ "loop",    0x0700 },
-	{ "hdc",     0x1600 },
-	{ "hdd",     0x1640 },
-	{ "hde",     0x2100 },
-	{ "hdf",     0x2140 },
-	{ "hdg",     0x2200 },
-	{ "hdh",     0x2240 },
-	{ "hdi",     0x3800 },
-	{ "hdj",     0x3840 },
-	{ "hdk",     0x3900 },
-	{ "hdl",     0x3940 },
-	{ "hdm",     0x5800 },
-	{ "hdn",     0x5840 },
-	{ "hdo",     0x5900 },
-	{ "hdp",     0x5940 },
-	{ "hdq",     0x5A00 },
-	{ "hdr",     0x5A40 },
-	{ "hds",     0x5B00 },
-	{ "hdt",     0x5B40 },
-	{ "sda",     0x0800 },
-	{ "sdb",     0x0810 },
-	{ "sdc",     0x0820 },
-	{ "sdd",     0x0830 },
-	{ "sde",     0x0840 },
-	{ "sdf",     0x0850 },
-	{ "sdg",     0x0860 },
-	{ "sdh",     0x0870 },
-	{ "sdi",     0x0880 },
-	{ "sdj",     0x0890 },
-	{ "sdk",     0x08a0 },
-	{ "sdl",     0x08b0 },
-	{ "sdm",     0x08c0 },
-	{ "sdn",     0x08d0 },
-	{ "sdo",     0x08e0 },
-	{ "sdp",     0x08f0 },
-	{ "ada",     0x1c00 },
-	{ "adb",     0x1c10 },
-	{ "adc",     0x1c20 },
-	{ "add",     0x1c30 },
-	{ "ade",     0x1c40 },
-	{ "fd",      0x0200 },
-	{ "md",      0x0900 },	     
-	{ "xda",     0x0d00 },
-	{ "xdb",     0x0d40 },
-	{ "ram",     0x0100 },
-	{ "scd",     0x0b00 },
-	{ "mcd",     0x1700 },
-	{ "cdu535",  0x1800 },
-	{ "sonycd",  0x1800 },
-	{ "aztcd",   0x1d00 },
-	{ "cm206cd", 0x2000 },
-	{ "gscd",    0x1000 },
-	{ "sbpcd",   0x1900 },
-	{ "eda",     0x2400 },
-	{ "edb",     0x2440 },
-	{ "pda",	0x2d00 },
-	{ "pdb",	0x2d10 },
-	{ "pdc",	0x2d20 },
-	{ "pdd",	0x2d30 },
-	{ "pcd",	0x2e00 },
-	{ "pf",		0x2f00 },
-	{ "apblock", APBLOCK_MAJOR << 8},
-	{ "ddv", DDV_MAJOR << 8},
-	{ "jsfd",    JSFD_MAJOR << 8},
-#if defined(CONFIG_ARCH_S390)
-	{ "dasda", (DASD_MAJOR << MINORBITS) },
-	{ "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
-	{ "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
-	{ "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
-	{ "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
-	{ "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
-	{ "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
-	{ "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
-#endif
-#if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
-	{ "ida/c0d0p",0x4800 },
-	{ "ida/c0d1p",0x4810 },
-	{ "ida/c0d2p",0x4820 },
-	{ "ida/c0d3p",0x4830 },
-	{ "ida/c0d4p",0x4840 },
-	{ "ida/c0d5p",0x4850 },
-	{ "ida/c0d6p",0x4860 },
-	{ "ida/c0d7p",0x4870 },
-	{ "ida/c0d8p",0x4880 },
-	{ "ida/c0d9p",0x4890 },
-	{ "ida/c0d10p",0x48A0 },
-	{ "ida/c0d11p",0x48B0 },
-	{ "ida/c0d12p",0x48C0 },
-	{ "ida/c0d13p",0x48D0 },
-	{ "ida/c0d14p",0x48E0 },
-	{ "ida/c0d15p",0x48F0 },
-#endif
-#if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
-	{ "cciss/c0d0p",0x6800 },
-	{ "cciss/c0d1p",0x6810 },
-	{ "cciss/c0d2p",0x6820 },
-	{ "cciss/c0d3p",0x6830 },
-	{ "cciss/c0d4p",0x6840 },
-	{ "cciss/c0d5p",0x6850 },
-	{ "cciss/c0d6p",0x6860 },
-	{ "cciss/c0d7p",0x6870 },
-	{ "cciss/c0d8p",0x6880 },
-	{ "cciss/c0d9p",0x6890 },
-	{ "cciss/c0d10p",0x68A0 },
-	{ "cciss/c0d11p",0x68B0 },
-	{ "cciss/c0d12p",0x68C0 },
-	{ "cciss/c0d13p",0x68D0 },
-	{ "cciss/c0d14p",0x68E0 },
-	{ "cciss/c0d15p",0x68F0 },
-#endif
-	{ "nftla", 0x5d00 },
-	{ "nftlb", 0x5d10 },
-	{ "nftlc", 0x5d20 },
-	{ "nftld", 0x5d30 },
-	{ "ftla", 0x2c00 },
-	{ "ftlb", 0x2c08 },
-	{ "ftlc", 0x2c10 },
-	{ "ftld", 0x2c18 },
-	{ "mtdblock", 0x1f00 },
-	{ NULL, 0 }
-};
-
-kdev_t __init name_to_kdev_t(char *line)
-{
-	int base = 0;
-
-	if (strncmp(line,"/dev/",5) == 0) {
-		struct dev_name_struct *dev = root_dev_names;
-		line += 5;
-		do {
-			int len = strlen(dev->name);
-			if (strncmp(line,dev->name,len) == 0) {
-				line += len;
-				base = dev->num;
-				break;
-			}
-			dev++;
-		} while (dev->name);
-	}
-	return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
-}
-
-static int __init root_dev_setup(char *line)
-{
-	int i;
-	char ch;
-
-	ROOT_DEV = name_to_kdev_t(line);
-	memset (root_device_name, 0, sizeof root_device_name);
-	if (strncmp (line, "/dev/", 5) == 0) line += 5;
-	for (i = 0; i < sizeof root_device_name - 1; ++i)
-	{
-	    ch = line[i];
-	    if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
-	    root_device_name[i] = ch;
-	}
-	return 1;
-}
-
-__setup("root=", root_dev_setup);
-
 static int __init checksetup(char *line)
 {
 	struct kernel_param *p;
@@ -377,22 +198,6 @@
 		(loops_per_jiffy/(5000/HZ)) % 100);
 }
 
-static int __init readonly(char *str)
-{
-	if (*str)
-		return 0;
-	root_mountflags |= MS_RDONLY;
-	return 1;
-}
-
-static int __init readwrite(char *str)
-{
-	if (*str)
-		return 0;
-	root_mountflags &= ~MS_RDONLY;
-	return 1;
-}
-
 static int __init debug_kernel(char *str)
 {
 	if (*str)
@@ -409,8 +214,6 @@
 	return 1;
 }
 
-__setup("ro", readonly);
-__setup("rw", readwrite);
 __setup("debug", debug_kernel);
 __setup("quiet", quiet_kernel);
 
@@ -545,7 +348,6 @@
 asmlinkage void __init start_kernel(void)
 {
 	char * command_line;
-	unsigned long mempages;
 	extern char saved_command_line[];
 /*
  * Interrupts are still disabled. Do necessary setups, then
@@ -596,16 +398,21 @@
 	kmem_cache_sizes_init();
 	pgtable_cache_init();
 
-#ifdef CONFIG_PERFMON
-	perfmon_init();
-#endif
-	mempages = num_physpages;
-
-	fork_init(mempages);
+	/*
+	 * For architectures that have highmem, num_mappedpages represents
+	 * the amount of memory the kernel can use.  For other architectures
+	 * it's the same as the total pages.  We need both numbers because
+	 * some subsystems need to initialize based on how much memory the
+	 * kernel can use.
+	 */
+	if (num_mappedpages == 0)
+		num_mappedpages = num_physpages;
+  
+	fork_init(num_mappedpages);
 	proc_caches_init();
-	vfs_caches_init(mempages);
-	buffer_init(mempages);
-	page_cache_init(mempages);
+	vfs_caches_init(num_physpages);
+	buffer_init(num_physpages);
+	page_cache_init(num_physpages);
 #if defined(CONFIG_ARCH_S390)
 	ccwcache_init();
 #endif
@@ -628,21 +435,6 @@
 	rest_init();
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static int do_linuxrc(void * shell)
-{
-	static char *argv[] = { "linuxrc", NULL, };
-
-	close(0);close(1);close(2);
-	setsid();
-	(void) open("/dev/console",O_RDWR,0);
-	(void) dup(0);
-	(void) dup(0);
-	return execve(shell, argv, envp_init);
-}
-
-#endif
-
 struct task_struct *child_reaper = &init_task;
 
 static void __init do_initcalls(void)
@@ -746,61 +538,7 @@
 #endif
 }
 
-extern void rd_load(void);
-extern void initrd_load(void);
-
-/*
- * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
- */
-static void prepare_namespace(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	int real_root_mountflags = root_mountflags;
-	if (!initrd_start)
-		mount_initrd = 0;
-	if (mount_initrd)
-		root_mountflags &= ~MS_RDONLY;
-	real_root_dev = ROOT_DEV;
-#endif
-
-#ifdef CONFIG_BLK_DEV_RAM
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (mount_initrd)
-		initrd_load();
-	else
-#endif
-	rd_load();
-#endif
-
-	/* Mount the root filesystem.. */
-	mount_root();
-
-	mount_devfs_fs ();
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	root_mountflags = real_root_mountflags;
-	if (mount_initrd && ROOT_DEV != real_root_dev
-	    && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
-		int error;
-		int i, pid;
-
-		pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
-		if (pid > 0) {
-			while (pid != wait(&i)) {
-				current->policy |= SCHED_YIELD;
-				schedule();
-			}
-		}
-		if (MAJOR(real_root_dev) != RAMDISK_MAJOR
-		     || MINOR(real_root_dev) != 0) {
-			error = change_root(real_root_dev,"/initrd");
-			if (error)
-				printk(KERN_ERR "Change root to /initrd: "
-				    "error %d\n",error);
-		}
-	}
-#endif
-}
+extern void prepare_namespace(void);
 
 static int init(void * unused)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/ipc/sem.c linux/ipc/sem.c
--- linux.orig/ipc/sem.c	2001-09-30 19:26:42.000000000 +0000
+++ linux/ipc/sem.c	2002-07-20 01:08:33.000000000 +0000
@@ -643,6 +643,7 @@
 		for (un = sma->undo; un; un = un->id_next)
 			un->semadj[semnum] = 0;
 		curr->semval = val;
+		curr->sempid = current->pid;
 		sma->sem_ctime = CURRENT_TIME;
 		/* maybe some queued-up processes were waiting for this */
 		update_queue(sma);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/ipc/shm.c linux/ipc/shm.c
--- linux.orig/ipc/shm.c	2001-12-21 17:42:04.000000000 +0000
+++ linux/ipc/shm.c	2002-07-20 01:08:37.000000000 +0000
@@ -117,12 +117,14 @@
  *
  * @shp: struct to free
  *
- * It has to be called with shp and shm_ids.sem locked
+ * It has to be called with shp and shm_ids.sem locked,
+ * but returns with shp unlocked and freed.
  */
 static void shm_destroy (struct shmid_kernel *shp)
 {
 	shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	shm_rmid (shp->id);
+	shm_unlock(shp->id);
 	shmem_lock(shp->shm_file, 0);
 	fput (shp->shm_file);
 	kfree (shp);
@@ -150,8 +152,8 @@
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_flags & SHM_DEST)
 		shm_destroy (shp);
-
-	shm_unlock(id);
+	else
+		shm_unlock(id);
 	up (&shm_ids.sem);
 }
 
@@ -511,11 +513,9 @@
 			shp->shm_flags |= SHM_DEST;
 			/* Do not find it any more */
 			shp->shm_perm.key = IPC_PRIVATE;
+			shm_unlock(shmid);
 		} else
 			shm_destroy (shp);
-
-		/* Unlock */
-		shm_unlock(shmid);
 		up(&shm_ids.sem);
 		return err;
 	}
@@ -653,7 +653,8 @@
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_flags & SHM_DEST)
 		shm_destroy (shp);
-	shm_unlock(shmid);
+	else
+		shm_unlock(shmid);
 	up (&shm_ids.sem);
 
 	*raddr = (unsigned long) user_addr;
@@ -672,16 +673,19 @@
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *shmd, *shmdnext;
+	int retval = -EINVAL;
 
 	down_write(&mm->mmap_sem);
 	for (shmd = mm->mmap; shmd; shmd = shmdnext) {
 		shmdnext = shmd->vm_next;
 		if (shmd->vm_ops == &shm_vm_ops
-		    && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr)
+		    && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr) {
 			do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start);
+			retval = 0;
+		}
 	}
 	up_write(&mm->mmap_sem);
-	return 0;
+	return retval;
 }
 
 #ifdef CONFIG_PROC_FS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/acct.c linux/kernel/acct.c
--- linux.orig/kernel/acct.c	2001-03-19 20:35:08.000000000 +0000
+++ linux/kernel/acct.c	2002-07-20 01:08:38.000000000 +0000
@@ -277,6 +277,7 @@
 	struct acct ac;
 	mm_segment_t fs;
 	unsigned long vsize;
+	unsigned long flim;
 
 	/*
 	 * First check to see if there is enough free_space to continue
@@ -338,8 +339,14 @@
          */
 	fs = get_fs();
 	set_fs(KERNEL_DS);
+	/*
+ 	 * Accounting records are not subject to resource limits.
+ 	 */
+	flim = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 	file->f_op->write(file, (char *)&ac,
 			       sizeof(struct acct), &file->f_pos);
+	current->rlim[RLIMIT_FSIZE].rlim_cur = flim;
 	set_fs(fs);
 }
 
@@ -354,7 +361,7 @@
 		file = acct_file;
 		get_file(file);
 		unlock_kernel();
-		do_acct_process(exitcode, acct_file);
+		do_acct_process(exitcode, file);
 		fput(file);
 	} else
 		unlock_kernel();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/exit.c linux/kernel/exit.c
--- linux.orig/kernel/exit.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/kernel/exit.c	2002-07-20 01:08:31.000000000 +0000
@@ -12,6 +12,7 @@
 #include <linux/completion.h>
 #include <linux/personality.h>
 #include <linux/tty.h>
+#include <linux/namespace.h>
 #ifdef CONFIG_BSD_PROCESS_ACCT
 #include <linux/acct.h>
 #endif
@@ -151,7 +152,7 @@
 
 /*
  * When we die, we re-parent all our children.
- * Try to give them to another thread in our process
+ * Try to give them to another thread in our thread
  * group, and if no such member exists, give it to
  * the global child reaper process (ie "init")
  */
@@ -161,8 +162,14 @@
 
 	read_lock(&tasklist_lock);
 
-	/* Next in our thread group */
-	reaper = next_thread(father);
+	/* Next in our thread group, if they're not already exiting */
+	reaper = father;
+	do {
+		reaper = next_thread(reaper);
+		if (!(reaper->flags & PF_EXITING))
+			break;
+	} while (reaper != father);
+
 	if (reaper == father)
 		reaper = child_reaper;
 
@@ -316,7 +323,7 @@
 	mm_release();
 	if (mm) {
 		atomic_inc(&mm->mm_count);
-		if (mm != tsk->active_mm) BUG();
+		BUG_ON(mm != tsk->active_mm);
 		/* more a memory barrier than a real lock */
 		task_lock(tsk);
 		tsk->mm = NULL;
@@ -452,6 +459,7 @@
 	sem_exit();
 	__exit_files(tsk);
 	__exit_fs(tsk);
+	exit_namespace(tsk);
 	exit_sighand(tsk);
 	exit_thread();
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/fork.c linux/kernel/fork.c
--- linux.orig/kernel/fork.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/kernel/fork.c	2002-07-20 01:08:25.000000000 +0000
@@ -19,7 +19,9 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/completion.h>
+#include <linux/namespace.h>
 #include <linux/personality.h>
+#include <linux/compiler.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -85,12 +87,13 @@
 {
 	static int next_safe = PID_MAX;
 	struct task_struct *p;
-	int pid;
+	int pid, beginpid;
 
 	if (flags & CLONE_PID)
 		return current->pid;
 
 	spin_lock(&lastpid_lock);
+	beginpid = last_pid;
 	if((++last_pid) & 0xffff8000) {
 		last_pid = 300;		/* Skip daemons etc. */
 		goto inside;
@@ -110,12 +113,16 @@
 						last_pid = 300;
 					next_safe = PID_MAX;
 				}
+				if(unlikely(last_pid == beginpid))
+					goto nomorepids;
 				goto repeat;
 			}
 			if(p->pid > last_pid && next_safe > p->pid)
 				next_safe = p->pid;
 			if(p->pgrp > last_pid && next_safe > p->pgrp)
 				next_safe = p->pgrp;
+			if(p->tgid > last_pid && next_safe > p->tgid)
+				next_safe = p->tgid;
 			if(p->session > last_pid && next_safe > p->session)
 				next_safe = p->session;
 		}
@@ -125,6 +132,11 @@
 	spin_unlock(&lastpid_lock);
 
 	return pid;
+
+nomorepids:
+	read_unlock(&tasklist_lock);
+	spin_unlock(&lastpid_lock);
+	return 0;
 }
 
 static inline int dup_mmap(struct mm_struct * mm)
@@ -251,7 +263,7 @@
  */
 inline void __mmdrop(struct mm_struct *mm)
 {
-	if (mm == &init_mm) BUG();
+	BUG_ON(mm == &init_mm);
 	pgd_free(mm->pgd);
 	destroy_context(mm);
 	free_mm(mm);
@@ -336,6 +348,9 @@
 	if (!mm_init(mm))
 		goto fail_nomem;
 
+	if (init_new_context(tsk,mm))
+		goto free_pt;
+
 	down_write(&oldmm->mmap_sem);
 	retval = dup_mmap(mm);
 	up_write(&oldmm->mmap_sem);
@@ -348,9 +363,6 @@
 	 */
 	copy_segments(tsk, mm);
 
-	if (init_new_context(tsk,mm))
-		goto free_pt;
-
 good_mm:
 	tsk->mm = mm;
 	tsk->active_mm = mm;
@@ -569,6 +581,9 @@
 	struct task_struct *p;
 	struct completion vfork;
 
+	if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
+		return -EINVAL;
+
 	retval = -EPERM;
 
 	/* 
@@ -620,6 +635,8 @@
 
 	copy_flags(clone_flags, p);
 	p->pid = get_pid(clone_flags);
+	if (p->pid == 0 && current->pid != 0)
+		goto bad_fork_cleanup;
 
 	p->run_list.next = NULL;
 	p->run_list.prev = NULL;
@@ -671,9 +688,11 @@
 		goto bad_fork_cleanup_fs;
 	if (copy_mm(clone_flags, p))
 		goto bad_fork_cleanup_sighand;
+	if (copy_namespace(clone_flags, p))
+		goto bad_fork_cleanup_mm;
 	retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
 	if (retval)
-		goto bad_fork_cleanup_mm;
+		goto bad_fork_cleanup_namespace;
 	p->semundo = NULL;
 	
 	/* Our parent execution domain becomes current domain
@@ -710,10 +729,10 @@
 	/* Need tasklist lock for parent etc handling! */
 	write_lock_irq(&tasklist_lock);
 
-	/* CLONE_PARENT and CLONE_THREAD re-use the old parent */
+	/* CLONE_PARENT re-uses the old parent */
 	p->p_opptr = current->p_opptr;
 	p->p_pptr = current->p_pptr;
-	if (!(clone_flags & (CLONE_PARENT | CLONE_THREAD))) {
+	if (!(clone_flags & CLONE_PARENT)) {
 		p->p_opptr = current;
 		if (!(p->ptrace & PT_PTRACED))
 			p->p_pptr = current;
@@ -740,6 +759,8 @@
 fork_out:
 	return retval;
 
+bad_fork_cleanup_namespace:
+	exit_namespace(p);
 bad_fork_cleanup_mm:
 	exit_mm(p);
 bad_fork_cleanup_sighand:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/kmod.c linux/kernel/kmod.c
--- linux.orig/kernel/kmod.c	2001-07-18 01:23:50.000000000 +0000
+++ linux/kernel/kmod.c	2002-07-20 01:08:31.000000000 +0000
@@ -24,6 +24,8 @@
 #include <linux/unistd.h>
 #include <linux/kmod.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/namespace.h>
 #include <linux/completion.h>
 
 #include <asm/uaccess.h>
@@ -36,6 +38,7 @@
 	struct fs_struct *our_fs, *init_fs;
 	struct dentry *root, *pwd;
 	struct vfsmount *rootmnt, *pwdmnt;
+	struct namespace *our_ns, *init_ns;
 
 	/*
 	 * Make modprobe's fs context be a copy of init's.
@@ -55,6 +58,11 @@
 	 */
 
 	init_fs = init_task.fs;
+	init_ns = init_task.namespace;
+	get_namespace(init_ns);
+	our_ns = current->namespace;
+	current->namespace = init_ns;
+	put_namespace(our_ns);
 	read_lock(&init_fs->lock);
 	rootmnt = mntget(init_fs->rootmnt);
 	root = dget(init_fs->root);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/ksyms.c linux/kernel/ksyms.c
--- linux.orig/kernel/ksyms.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/kernel/ksyms.c	2002-07-20 01:08:22.000000000 +0000
@@ -108,6 +108,7 @@
 EXPORT_SYMBOL(kfree);
 EXPORT_SYMBOL(vfree);
 EXPORT_SYMBOL(__vmalloc);
+EXPORT_SYMBOL(vmalloc_to_page);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(remap_page_range);
 EXPORT_SYMBOL(max_mapnr);
@@ -164,6 +165,7 @@
 EXPORT_SYMBOL(set_buffer_async_io); /* for reiserfs_writepage */
 EXPORT_SYMBOL(__mark_buffer_dirty);
 EXPORT_SYMBOL(__mark_inode_dirty);
+EXPORT_SYMBOL(fd_install);
 EXPORT_SYMBOL(get_empty_filp);
 EXPORT_SYMBOL(init_private_file);
 EXPORT_SYMBOL(filp_open);
@@ -186,6 +188,8 @@
 EXPORT_SYMBOL(write_inode_now);
 EXPORT_SYMBOL(notify_change);
 EXPORT_SYMBOL(set_blocksize);
+EXPORT_SYMBOL(sb_set_blocksize);
+EXPORT_SYMBOL(sb_min_blocksize);
 EXPORT_SYMBOL(getblk);
 EXPORT_SYMBOL(cdget);
 EXPORT_SYMBOL(cdput);
@@ -269,7 +273,12 @@
 EXPORT_SYMBOL(lease_get_mtime);
 EXPORT_SYMBOL(lock_may_read);
 EXPORT_SYMBOL(lock_may_write);
+EXPORT_SYMBOL(dcache_dir_open);
+EXPORT_SYMBOL(dcache_dir_close);
+EXPORT_SYMBOL(dcache_dir_lseek);
+EXPORT_SYMBOL(dcache_dir_fsync);
 EXPORT_SYMBOL(dcache_readdir);
+EXPORT_SYMBOL(dcache_dir_ops);
 
 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
 EXPORT_SYMBOL(default_llseek);
@@ -438,6 +447,7 @@
 EXPORT_SYMBOL(interruptible_sleep_on_timeout);
 EXPORT_SYMBOL(schedule);
 EXPORT_SYMBOL(schedule_timeout);
+EXPORT_SYMBOL(sys_sched_yield);
 EXPORT_SYMBOL(jiffies);
 EXPORT_SYMBOL(xtime);
 EXPORT_SYMBOL(do_gettimeofday);
@@ -452,6 +462,7 @@
 
 /* misc */
 EXPORT_SYMBOL(panic);
+EXPORT_SYMBOL(__out_of_line_bug);
 EXPORT_SYMBOL(sprintf);
 EXPORT_SYMBOL(snprintf);
 EXPORT_SYMBOL(sscanf);
@@ -501,8 +512,7 @@
 /* Added to make file system as module */
 EXPORT_SYMBOL(sys_tz);
 EXPORT_SYMBOL(file_fsync);
-EXPORT_SYMBOL(fsync_inode_buffers);
-EXPORT_SYMBOL(fsync_inode_data_buffers);
+EXPORT_SYMBOL(fsync_buffers_list);
 EXPORT_SYMBOL(clear_inode);
 EXPORT_SYMBOL(___strtok);
 EXPORT_SYMBOL(init_special_inode);
@@ -512,6 +522,7 @@
 EXPORT_SYMBOL(insert_inode_hash);
 EXPORT_SYMBOL(remove_inode_hash);
 EXPORT_SYMBOL(buffer_insert_inode_queue);
+EXPORT_SYMBOL(buffer_insert_inode_data_queue);
 EXPORT_SYMBOL(make_bad_inode);
 EXPORT_SYMBOL(is_bad_inode);
 EXPORT_SYMBOL(event);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/panic.c linux/kernel/panic.c
--- linux.orig/kernel/panic.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/kernel/panic.c	2002-07-20 01:08:34.000000000 +0000
@@ -96,6 +96,10 @@
 #endif
 	sti();
 	for(;;) {
+#if defined(__i386__) && defined(CONFIG_VT) 
+		extern void panic_blink(void);
+		panic_blink(); 
+#endif
 		CHECK_EMERGENCY_SYNC
 	}
 }
@@ -120,3 +124,23 @@
 }
 
 int tainted = 0;
+
+/*
+ * A BUG() call in an inline function in a header should be avoided,
+ * because it can seriously bloat the kernel.  So here we have
+ * helper functions.
+ * We lose the BUG()-time file-and-line info this way, but it's
+ * usually not very useful from an inline anyway.  The backtrace
+ * tells us what we want to know.
+ */
+
+void __out_of_line_bug(int line)
+{
+	printk("kernel BUG in header file at line %d\n", line);
+
+	BUG();
+
+	/* Satisfy __attribute__((noreturn)) */
+	for ( ; ; )
+		;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/pm.c linux/kernel/pm.c
--- linux.orig/kernel/pm.c	2001-04-06 17:51:19.000000000 +0000
+++ linux/kernel/pm.c	2002-07-20 01:08:27.000000000 +0000
@@ -162,7 +162,7 @@
 	case PM_SUSPEND:
 	case PM_RESUME:
 		prev_state = dev->state;
-		next_state = (int) data;
+		next_state = (unsigned long) data;
 		if (prev_state != next_state) {
 			if (dev->callback)
 				status = (*dev->callback)(dev, rqst, data);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/printk.c linux/kernel/printk.c
--- linux.orig/kernel/printk.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/kernel/printk.c	2002-07-20 01:08:36.000000000 +0000
@@ -29,7 +29,7 @@
 
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_MULTIQUAD
+#if defined(CONFIG_MULTIQUAD) || defined(CONFIG_IA64)
 #define LOG_BUF_LEN	(65536)
 #elif defined(CONFIG_ARCH_S390)
 #define LOG_BUF_LEN	(131072)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/ptrace.c linux/kernel/ptrace.c
--- linux.orig/kernel/ptrace.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/kernel/ptrace.c	2002-07-20 01:08:40.000000000 +0000
@@ -164,7 +164,7 @@
 		if (write) {
 			memcpy(maddr + offset, buf, bytes);
 			flush_page_to_ram(page);
-			flush_icache_page(vma, page);
+			flush_icache_user_range(vma, page, addr, len);
 		} else {
 			memcpy(buf, maddr + offset, bytes);
 			flush_page_to_ram(page);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/sched.c linux/kernel/sched.c
--- linux.orig/kernel/sched.c	2001-12-21 17:42:04.000000000 +0000
+++ linux/kernel/sched.c	2002-07-20 01:08:29.000000000 +0000
@@ -556,7 +556,7 @@
 
 	spin_lock_prefetch(&runqueue_lock);
 
-	if (!current->active_mm) BUG();
+	BUG_ON(!current->active_mm);
 need_resched_back:
 	prev = current;
 	this_cpu = prev->processor;
@@ -675,12 +675,12 @@
 		struct mm_struct *mm = next->mm;
 		struct mm_struct *oldmm = prev->active_mm;
 		if (!mm) {
-			if (next->active_mm) BUG();
+			BUG_ON(next->active_mm);
 			next->active_mm = oldmm;
 			atomic_inc(&oldmm->mm_count);
 			enter_lazy_tlb(oldmm, next, this_cpu);
 		} else {
-			if (next->active_mm != mm) BUG();
+			BUG_ON(next->active_mm != mm);
 			switch_mm(oldmm, mm, next, this_cpu);
 		}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/signal.c linux/kernel/signal.c
--- linux.orig/kernel/signal.c	2001-11-22 00:26:27.000000000 +0000
+++ linux/kernel/signal.c	2002-07-20 01:08:33.000000000 +0000
@@ -142,6 +142,35 @@
 	}
 }
 
+/*
+ * sig_exit - cause the current task to exit due to a signal.
+ */
+
+void
+sig_exit(int sig, int exit_code, struct siginfo *info)
+{
+	struct task_struct *t;
+
+	sigaddset(&current->pending.signal, sig);
+	recalc_sigpending(current);
+	current->flags |= PF_SIGNALED;
+
+	/* Propagate the signal to all the tasks in
+	 *  our thread group
+	 */
+	if (info && (unsigned long)info != 1
+	    && info->si_code != SI_TKILL) {
+		read_lock(&tasklist_lock);
+		for_each_thread(t) {
+			force_sig_info(sig, info, t);
+		}
+		read_unlock(&tasklist_lock);
+	}
+
+	do_exit(exit_code);
+	/* NOTREACHED */
+}
+
 /* Notify the system that a driver wants to block all signals for this
  * process, and wants to be notified if any signals at all were to be
  * sent/acted upon.  If the notifier routine returns non-zero, then the
@@ -519,7 +548,7 @@
 	if (bad_signal(sig, info, t))
 		goto out_nolock;
 
-	/* The null signal is a permissions and process existance probe.
+	/* The null signal is a permissions and process existence probe.
 	   No signal is actually delivered.  Same goes for zombies. */
 	ret = 0;
 	if (!sig || !t->sig)
@@ -592,7 +621,7 @@
 		retval = -ESRCH;
 		read_lock(&tasklist_lock);
 		for_each_task(p) {
-			if (p->pgrp == pgrp) {
+			if (p->pgrp == pgrp && thread_group_leader(p)) {
 				int err = send_sig_info(sig, info, p);
 				if (retval)
 					retval = err;
@@ -639,8 +668,15 @@
 	read_lock(&tasklist_lock);
 	p = find_task_by_pid(pid);
 	error = -ESRCH;
-	if (p)
+	if (p) {
+		if (!thread_group_leader(p)) {
+                       struct task_struct *tg;
+                       tg = find_task_by_pid(p->tgid);
+                       if (tg)
+                               p = tg;
+                }
 		error = send_sig_info(sig, info, p);
+	}
 	read_unlock(&tasklist_lock);
 	return error;
 }
@@ -663,7 +699,7 @@
 
 		read_lock(&tasklist_lock);
 		for_each_task(p) {
-			if (p->pid > 1 && p != current) {
+			if (p->pid > 1 && p != current && thread_group_leader(p)) {
 				int err = send_sig_info(sig, info, p);
 				++count;
 				if (err != -EPERM)
@@ -988,6 +1024,36 @@
 	return kill_something_info(sig, &info, pid);
 }
 
+/*
+ *  Kill only one task, even if it's a CLONE_THREAD task.
+ */
+asmlinkage long
+sys_tkill(int pid, int sig)
+{
+       struct siginfo info;
+       int error;
+       struct task_struct *p;
+
+       /* This is only valid for single tasks */
+       if (pid <= 0)
+           return -EINVAL;
+
+       info.si_signo = sig;
+       info.si_errno = 0;
+       info.si_code = SI_TKILL;
+       info.si_pid = current->pid;
+       info.si_uid = current->uid;
+
+       read_lock(&tasklist_lock);
+       p = find_task_by_pid(pid);
+       error = -ESRCH;
+       if (p) {
+               error = send_sig_info(sig, &info, p);
+       }
+       read_unlock(&tasklist_lock);
+       return error;
+}
+
 asmlinkage long
 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo)
 {
@@ -1047,6 +1113,7 @@
 		    || (k->sa.sa_handler == SIG_DFL
 			&& (sig == SIGCONT ||
 			    sig == SIGCHLD ||
+			    sig == SIGURG ||
 			    sig == SIGWINCH))) {
 			spin_lock_irq(&current->sigmask_lock);
 			if (rm_sig_from_queue(sig, current))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/softirq.c linux/kernel/softirq.c
--- linux.orig/kernel/softirq.c	2001-10-31 18:26:02.000000000 +0000
+++ linux/kernel/softirq.c	2002-07-20 01:08:29.000000000 +0000
@@ -62,7 +62,7 @@
 {
 	int cpu = smp_processor_id();
 	__u32 pending;
-	long flags;
+	unsigned long flags;
 	__u32 mask;
 
 	if (in_interrupt())
@@ -130,7 +130,7 @@
 
 void raise_softirq(unsigned int nr)
 {
-	long flags;
+	unsigned long flags;
 
 	local_irq_save(flags);
 	cpu_raise_softirq(smp_processor_id(), nr);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/sys.c linux/kernel/sys.c
--- linux.orig/kernel/sys.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/kernel/sys.c	2002-07-20 01:08:25.000000000 +0000
@@ -655,8 +655,8 @@
 			wmb();
 		}
 		current->euid = euid;
-		current->fsuid = euid;
 	}
+	current->fsuid = current->euid;
 	if (suid != (uid_t) -1)
 		current->suid = suid;
 
@@ -701,8 +701,8 @@
 			wmb();
 		}
 		current->egid = egid;
-		current->fsgid = egid;
 	}
+	current->fsgid = current->egid;
 	if (rgid != (gid_t) -1)
 		current->gid = rgid;
 	if (sgid != (gid_t) -1)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/sysctl.c linux/kernel/sysctl.c
--- linux.orig/kernel/sysctl.c	2001-12-21 17:42:04.000000000 +0000
+++ linux/kernel/sysctl.c	2002-07-20 01:08:25.000000000 +0000
@@ -275,6 +275,8 @@
 	&vm_min_readahead,sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_MAX_READAHEAD, "max-readahead",
 	&vm_max_readahead,sizeof(int), 0644, NULL, &proc_dointvec},
+	{VM_MAX_MAP_COUNT, "max_map_count",
+	 &max_map_count, sizeof(int), 0644, NULL, &proc_dointvec},
 	{0}
 };
 
@@ -483,11 +485,11 @@
 }
 
 /**
- * register_sysctl_table - register a sysctl heirarchy
+ * register_sysctl_table - register a sysctl hierarchy
  * @table: the top-level table structure
  * @insert_at_head: whether the entry should be inserted in front or at the end
  *
- * Register a sysctl table heirarchy. @table should be a filled in ctl_table
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
  * array. An entry with a ctl_name of 0 terminates the table. 
  *
  * The members of the &ctl_table structure are used as follows:
@@ -571,7 +573,7 @@
 }
 
 /**
- * unregister_sysctl_table - unregister a sysctl table heirarchy
+ * unregister_sysctl_table - unregister a sysctl table hierarchy
  * @header: the header returned from register_sysctl_table
  *
  * Unregisters the sysctl table and all children. proc entries may not
@@ -984,7 +986,7 @@
 	vleft = table->maxlen / sizeof(int);
 	left = *lenp;
 	
-	for (; left && vleft--; i++, first=0) {
+	for (; left && vleft--; i++, min++, max++, first=0) {
 		if (write) {
 			while (left) {
 				char c;
@@ -1020,9 +1022,7 @@
 			buffer += len;
 			left -= len;
 
-			if (min && val < *min++)
-				continue;
-			if (max && val > *max++)
+			if ((min && val < *min) || (max && val > *max))
 				continue;
 			*i = val;
 		} else {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/time.c linux/kernel/time.c
--- linux.orig/kernel/time.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/kernel/time.c	2002-07-20 01:08:28.000000000 +0000
@@ -216,6 +216,11 @@
 		
 	/* Now we validate the data before disabling interrupts */
 
+	if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+	  /* singleshot must not be used with any other mode bits */
+		if (txc->modes != ADJ_OFFSET_SINGLESHOT)
+			return -EINVAL;
+
 	if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
 	  /* adjustment Offset limited to +- .512 seconds */
 		if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/kernel/timer.c linux/kernel/timer.c
--- linux.orig/kernel/timer.c	2001-10-08 17:41:41.000000000 +0000
+++ linux/kernel/timer.c	2002-07-20 01:08:30.000000000 +0000
@@ -101,6 +101,8 @@
 	(struct timer_vec *)&tv1, &tv2, &tv3, &tv4, &tv5
 };
 
+static struct list_head * run_timer_list_running;
+
 #define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0]))
 
 void init_timervecs (void)
@@ -128,7 +130,9 @@
 	unsigned long idx = expires - timer_jiffies;
 	struct list_head * vec;
 
-	if (idx < TVR_SIZE) {
+	if (run_timer_list_running)
+		vec = run_timer_list_running;
+	else if (idx < TVR_SIZE) {
 		int i = expires & TVR_MASK;
 		vec = tv1.vec + i;
 	} else if (idx < 1 << (TVR_BITS + TVN_BITS)) {
@@ -289,6 +293,7 @@
 {
 	spin_lock_irq(&timerlist_lock);
 	while ((long)(jiffies - timer_jiffies) >= 0) {
+		LIST_HEAD(queued);
 		struct list_head *head, *curr;
 		if (!tv1.index) {
 			int n = 1;
@@ -296,6 +301,7 @@
 				cascade_timers(tvecs[n]);
 			} while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
 		}
+		run_timer_list_running = &queued;
 repeat:
 		head = tv1.vec + tv1.index;
 		curr = head->next;
@@ -317,8 +323,18 @@
 			timer_exit();
 			goto repeat;
 		}
+		run_timer_list_running = NULL;
 		++timer_jiffies; 
 		tv1.index = (tv1.index + 1) & TVR_MASK;
+
+		curr = queued.next;
+		while (curr != &queued) {
+			struct timer_list *timer;
+
+			timer = list_entry(curr, struct timer_list, list);
+			curr = curr->next;
+			internal_add_timer(timer);
+		}			
 	}
 	spin_unlock_irq(&timerlist_lock);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/lib/Makefile linux/lib/Makefile
--- linux.orig/lib/Makefile	2001-09-17 22:31:15.000000000 +0000
+++ linux/lib/Makefile	2002-07-20 01:08:24.000000000 +0000
@@ -8,7 +8,7 @@
 
 L_TARGET := lib.a
 
-export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o
+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o
 
 obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/lib/rbtree.c linux/lib/rbtree.c
--- linux.orig/lib/rbtree.c	2001-09-17 22:30:23.000000000 +0000
+++ linux/lib/rbtree.c	2002-07-20 01:08:25.000000000 +0000
@@ -20,6 +20,7 @@
 */
 
 #include <linux/rbtree.h>
+#include <linux/module.h>
 
 static void __rb_rotate_left(rb_node_t * node, rb_root_t * root)
 {
@@ -125,6 +126,7 @@
 
 	root->rb_node->rb_color = RB_BLACK;
 }
+EXPORT_SYMBOL(rb_insert_color);
 
 static void __rb_erase_color(rb_node_t * node, rb_node_t * parent,
 			     rb_root_t * root)
@@ -291,3 +293,4 @@
 	if (color == RB_BLACK)
 		__rb_erase_color(child, parent, root);
 }
+EXPORT_SYMBOL(rb_erase);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/lib/string.c linux/lib/string.c
--- linux.orig/lib/string.c	2001-04-27 21:35:50.000000000 +0000
+++ linux/lib/string.c	2002-07-20 01:08:31.000000000 +0000
@@ -452,7 +452,7 @@
 int memcmp(const void * cs,const void * ct,size_t count)
 {
 	const unsigned char *su1, *su2;
-	signed char res = 0;
+	int res = 0;
 
 	for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
 		if ((res = *su1 - *su2) != 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/Makefile linux/mm/Makefile
--- linux.orig/mm/Makefile	2001-10-24 22:21:18.000000000 +0000
+++ linux/mm/Makefile	2002-07-20 01:08:38.000000000 +0000
@@ -9,7 +9,7 @@
 
 O_TARGET := mm.o
 
-export-objs := shmem.o filemap.o
+export-objs := shmem.o filemap.o memory.o page_alloc.o
 
 obj-y	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
 	    vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/bootmem.c linux/mm/bootmem.c
--- linux.orig/mm/bootmem.c	2001-12-21 17:42:04.000000000 +0000
+++ linux/mm/bootmem.c	2002-07-20 01:08:31.000000000 +0000
@@ -18,6 +18,7 @@
 #include <linux/bootmem.h>
 #include <linux/mmzone.h>
 #include <asm/dma.h>
+#include <asm/io.h>
 
 /*
  * Access to this subsystem has to be serialized externally. (this is
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/filemap.c linux/mm/filemap.c
--- linux.orig/mm/filemap.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/mm/filemap.c	2002-07-20 01:08:32.000000000 +0000
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/iobuf.h>
-#include <linux/compiler.h>
 
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
@@ -53,7 +52,7 @@
 EXPORT_SYMBOL(vm_min_readahead);
 
 
-spinlock_t pagecache_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+spinlock_cacheline_t pagecache_lock_cacheline  = {SPIN_LOCK_UNLOCKED};
 /*
  * NOTE: to avoid deadlocking you must never acquire the pagemap_lru_lock 
  *	with the pagecache_lock held.
@@ -63,7 +62,7 @@
  *		pagemap_lru_lock ->
  *			pagecache_lock
  */
-spinlock_t pagemap_lru_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+spinlock_cacheline_t pagemap_lru_lock_cacheline = {SPIN_LOCK_UNLOCKED};
 
 #define CLUSTER_PAGES		(1 << page_cluster)
 #define CLUSTER_OFFSET(x)	(((x) >> page_cluster) << page_cluster)
@@ -120,7 +119,8 @@
  */
 void __remove_inode_page(struct page *page)
 {
-	if (PageDirty(page)) BUG();
+	if (PageDirty(page) && !PageSwapCache(page))
+		BUG();
 	remove_page_from_inode_queue(page);
 	remove_page_from_hash_queue(page);
 }
@@ -555,7 +555,7 @@
 	spin_lock(&pagecache_lock);
 
         while (!list_empty(&mapping->dirty_pages)) {
-		struct page *page = list_entry(mapping->dirty_pages.next, struct page, list);
+		struct page *page = list_entry(mapping->dirty_pages.prev, struct page, list);
 
 		list_del(&page->list);
 		list_add(&page->list, &mapping->locked_pages);
@@ -745,6 +745,67 @@
 	return 0;
 }
 
+/*
+ * Knuth recommends primes in approximately golden ratio to the maximum
+ * integer representable by a machine word for multiplicative hashing.
+ * Chuck Lever verified the effectiveness of this technique:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ *
+ * These primes are chosen to be bit-sparse, that is operations on
+ * them can use shifts and additions instead of multiplications for
+ * machines where multiplications are slow.
+ */
+#if BITS_PER_LONG == 32
+/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e370001UL
+#elif BITS_PER_LONG == 64
+/*  2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL
+#else
+#error Define GOLDEN_RATIO_PRIME for your wordsize.
+#endif
+
+/*
+ * In order to wait for pages to become available there must be
+ * waitqueues associated with pages. By using a hash table of
+ * waitqueues where the bucket discipline is to maintain all
+ * waiters on the same queue and wake all when any of the pages
+ * become available, and for the woken contexts to check to be
+ * sure the appropriate page became available, this saves space
+ * at a cost of "thundering herd" phenomena during rare hash
+ * collisions.
+ */
+static inline wait_queue_head_t *page_waitqueue(struct page *page)
+{
+	const zone_t *zone = page_zone(page);
+	wait_queue_head_t *wait = zone->wait_table;
+	unsigned long hash = (unsigned long)page;
+
+#if BITS_PER_LONG == 64
+	/*  Sigh, gcc can't optimise this alone like it does for 32 bits. */
+	unsigned long n = hash;
+	n <<= 18;
+	hash -= n;
+	n <<= 33;
+	hash -= n;
+	n <<= 3;
+	hash += n;
+	n <<= 3;
+	hash -= n;
+	n <<= 4;
+	hash += n;
+	n <<= 2;
+	hash += n;
+#else
+	/* On some cpus multiply is faster, on others gcc will do shifts */
+	hash *= GOLDEN_RATIO_PRIME;
+#endif
+
+	hash >>= zone->wait_table_shift;
+
+	return &wait[hash];
+}
+
 /* 
  * Wait for a page to get unlocked.
  *
@@ -754,10 +815,11 @@
  */
 void ___wait_on_page(struct page *page)
 {
+	wait_queue_head_t *waitqueue = page_waitqueue(page);
 	struct task_struct *tsk = current;
 	DECLARE_WAITQUEUE(wait, tsk);
 
-	add_wait_queue(&page->wait, &wait);
+	add_wait_queue(waitqueue, &wait);
 	do {
 		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
 		if (!PageLocked(page))
@@ -765,19 +827,23 @@
 		sync_page(page);
 		schedule();
 	} while (PageLocked(page));
-	tsk->state = TASK_RUNNING;
-	remove_wait_queue(&page->wait, &wait);
+	__set_task_state(tsk, TASK_RUNNING);
+	remove_wait_queue(waitqueue, &wait);
 }
 
+/*
+ * Unlock the page and wake up sleepers in ___wait_on_page.
+ */
 void unlock_page(struct page *page)
 {
-	clear_bit(PG_launder, &(page)->flags);
+	wait_queue_head_t *waitqueue = page_waitqueue(page);
+	ClearPageLaunder(page);
 	smp_mb__before_clear_bit();
 	if (!test_and_clear_bit(PG_locked, &(page)->flags))
 		BUG();
 	smp_mb__after_clear_bit(); 
-	if (waitqueue_active(&(page)->wait))
-	wake_up(&(page)->wait);
+	if (waitqueue_active(waitqueue))
+		wake_up_all(waitqueue);
 }
 
 /*
@@ -786,10 +852,11 @@
  */
 static void __lock_page(struct page *page)
 {
+	wait_queue_head_t *waitqueue = page_waitqueue(page);
 	struct task_struct *tsk = current;
 	DECLARE_WAITQUEUE(wait, tsk);
 
-	add_wait_queue_exclusive(&page->wait, &wait);
+	add_wait_queue_exclusive(waitqueue, &wait);
 	for (;;) {
 		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
 		if (PageLocked(page)) {
@@ -799,10 +866,9 @@
 		if (!TryLockPage(page))
 			break;
 	}
-	tsk->state = TASK_RUNNING;
-	remove_wait_queue(&page->wait, &wait);
+	__set_task_state(tsk, TASK_RUNNING);
+	remove_wait_queue(waitqueue, &wait);
 }
-	
 
 /*
  * Get an exclusive lock on the page, optimistically
@@ -2133,6 +2199,9 @@
 	int ret = 0;
 	struct file * file = vma->vm_file;
 
+	if ( (flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED) )
+		return -EBUSY;
+
 	if (file && (vma->vm_flags & VM_SHARED)) {
 		ret = filemap_sync(vma, start, end-start, flags);
 
@@ -2174,23 +2243,26 @@
 		goto out;
 	if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
 		goto out;
+	if ((flags & MS_ASYNC) && (flags & MS_SYNC))
+		goto out;
+
 	error = 0;
 	if (end == start)
 		goto out;
 	/*
 	 * If the interval [start,end) covers some unmapped address ranges,
-	 * just ignore them, but return -EFAULT at the end.
+	 * just ignore them, but return -ENOMEM at the end.
 	 */
 	vma = find_vma(current->mm, start);
 	unmapped_error = 0;
 	for (;;) {
 		/* Still start < end. */
-		error = -EFAULT;
+		error = -ENOMEM;
 		if (!vma)
 			goto out;
 		/* Here start < vma->vm_end. */
 		if (start < vma->vm_start) {
-			unmapped_error = -EFAULT;
+			unmapped_error = -ENOMEM;
 			start = vma->vm_start;
 		}
 		/* Here vma->vm_start <= start < vma->vm_end. */
@@ -2338,7 +2410,7 @@
 	int error = 0;
 
 	/* This caps the number of vma's this process can own */
-	if (vma->vm_mm->map_count > MAX_MAP_COUNT)
+	if (vma->vm_mm->map_count > max_map_count)
 		return -ENOMEM;
 
 	if (start == vma->vm_start) {
@@ -2886,7 +2958,7 @@
 	 */
 	err = -EFBIG;
 	
-	if (limit != RLIM_INFINITY) {
+	if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) {
 		if (pos >= limit) {
 			send_sig(SIGXFSZ, current, 0);
 			goto out;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/highmem.c linux/mm/highmem.c
--- linux.orig/mm/highmem.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/mm/highmem.c	2002-07-20 01:08:24.000000000 +0000
@@ -32,7 +32,8 @@
  */
 static int pkmap_count[LAST_PKMAP];
 static unsigned int last_pkmap_nr;
-static spinlock_t kmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static spinlock_cacheline_t kmap_lock_cacheline = {SPIN_LOCK_UNLOCKED};
+#define kmap_lock  kmap_lock_cacheline.lock
 
 pte_t * pkmap_page_table;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/memory.c linux/mm/memory.c
--- linux.orig/mm/memory.c	2002-02-25 19:38:13.000000000 +0000
+++ linux/mm/memory.c	2002-07-20 01:08:35.000000000 +0000
@@ -44,6 +44,7 @@
 #include <linux/iobuf.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
+#include <linux/module.h>
 
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
@@ -51,6 +52,7 @@
 
 unsigned long max_mapnr;
 unsigned long num_physpages;
+unsigned long num_mappedpages;
 void * high_memory;
 struct page *highmem_start_page;
 
@@ -144,6 +146,7 @@
 void clear_page_tables(struct mm_struct *mm, unsigned long first, int nr)
 {
 	pgd_t * page_dir = mm->pgd;
+	unsigned long	last = first + nr;
 
 	spin_lock(&mm->page_table_lock);
 	page_dir += first;
@@ -153,6 +156,8 @@
 	} while (--nr);
 	spin_unlock(&mm->page_table_lock);
 
+	flush_tlb_pgtables(mm, first * PGDIR_SIZE, last * PGDIR_SIZE);
+	
 	/* keep the page table cache within bounds */
 	check_pgt_cache();
 }
@@ -524,6 +529,8 @@
 	goto out;
 }
 
+EXPORT_SYMBOL(get_user_pages);
+
 /*
  * Force in an entire range of pages from the current process's user VA,
  * and pin them in physical memory.  
@@ -1467,3 +1474,24 @@
 			len, write, 0, NULL, NULL);
 	return ret == len ? 0 : -1;
 }
+
+struct page * vmalloc_to_page(void * vmalloc_addr)
+{
+	unsigned long addr = (unsigned long) vmalloc_addr;
+	struct page *page = NULL;
+	pmd_t *pmd;
+	pte_t *pte;
+	pgd_t *pgd;
+	
+	pgd = pgd_offset_k(addr);
+	if (!pgd_none(*pgd)) {
+		pmd = pmd_offset(pgd, addr);
+		if (!pmd_none(*pmd)) {
+			pte = pte_offset(pmd, addr);
+			if (pte_present(*pte)) {
+				page = pte_page(*pte);
+			}
+		}
+	}
+	return page;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/mmap.c linux/mm/mmap.c
--- linux.orig/mm/mmap.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/mm/mmap.c	2002-07-20 01:08:24.000000000 +0000
@@ -45,6 +45,7 @@
 };
 
 int sysctl_overcommit_memory;
+int max_map_count = DEFAULT_MAX_MAP_COUNT;
 
 /* Check that a process has enough memory to allocate a
  * new virtual mapping.
@@ -413,7 +414,7 @@
 		return -EINVAL;
 
 	/* Too many mappings? */
-	if (mm->map_count > MAX_MAP_COUNT)
+	if (mm->map_count > max_map_count)
 		return -ENOMEM;
 
 	/* Obtain the address to map to. we verify (or select) it and ensure
@@ -478,7 +479,6 @@
 	}
 
 	/* Clear old maps */
-	error = -ENOMEM;
 munmap_back:
 	vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
 	if (vma && vma->vm_start < addr + len) {
@@ -548,7 +548,30 @@
 	 * Answer: Yes, several device drivers can do it in their
 	 *         f_op->mmap method. -DaveM
 	 */
-	addr = vma->vm_start;
+	if (addr != vma->vm_start) {
+		/*
+		 * It is a bit too late to pretend changing the virtual
+		 * area of the mapping, we just corrupted userspace
+		 * in the do_munmap, so FIXME (not in 2.4 to avoid breaking
+		 * the driver API).
+		 */
+		struct vm_area_struct * stale_vma;
+		/* Since addr changed, we rely on the mmap op to prevent 
+		 * collisions with existing vmas and just use find_vma_prepare 
+		 * to update the tree pointers.
+		 */
+		addr = vma->vm_start;
+		stale_vma = find_vma_prepare(mm, addr, &prev,
+						&rb_link, &rb_parent);
+		/*
+		 * Make sure the lowlevel driver did its job right.
+		 */
+		if (unlikely(stale_vma && stale_vma->vm_start < vma->vm_end)) {
+			printk(KERN_ERR "buggy mmap operation: [<%p>]\n",
+				file ? file->f_op->mmap : NULL);
+			BUG();
+		}
+	}
 
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	if (correct_wcount)
@@ -885,7 +908,6 @@
 	end_index = pgd_index(last);
 	if (end_index > start_index) {
 		clear_page_tables(mm, start_index, end_index - start_index);
-		flush_tlb_pgtables(mm, first & PGDIR_MASK, last & PGDIR_MASK);
 	}
 }
 
@@ -919,7 +941,7 @@
 
 	/* If we'll make "hole", check the vm areas limit */
 	if ((mpnt->vm_start < addr && mpnt->vm_end > addr+len)
-	    && mm->map_count >= MAX_MAP_COUNT)
+	    && mm->map_count >= max_map_count)
 		return -ENOMEM;
 
 	/*
@@ -1040,16 +1062,13 @@
 	    > current->rlim[RLIMIT_AS].rlim_cur)
 		return -ENOMEM;
 
-	if (mm->map_count > MAX_MAP_COUNT)
+	if (mm->map_count > max_map_count)
 		return -ENOMEM;
 
 	if (!vm_enough_memory(len >> PAGE_SHIFT))
 		return -ENOMEM;
 
-	flags = calc_vm_flags(PROT_READ|PROT_WRITE|PROT_EXEC,
-				MAP_FIXED|MAP_PRIVATE) | mm->def_flags;
-
-	flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+	flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
 
 	/* Can we just expand an old anonymous mapping? */
 	if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags))
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/mprotect.c linux/mm/mprotect.c
--- linux.orig/mm/mprotect.c	2001-09-17 22:30:23.000000000 +0000
+++ linux/mm/mprotect.c	2002-07-20 01:08:34.000000000 +0000
@@ -284,7 +284,7 @@
 	down_write(&current->mm->mmap_sem);
 
 	vma = find_vma_prev(current->mm, start, &prev);
-	error = -EFAULT;
+	error = -ENOMEM;
 	if (!vma || vma->vm_start > start)
 		goto out;
 
@@ -317,7 +317,7 @@
 		nstart = tmp;
 		vma = next;
 		if (!vma || vma->vm_start != nstart) {
-			error = -EFAULT;
+			error = -ENOMEM;
 			goto out;
 		}
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/oom_kill.c linux/mm/oom_kill.c
--- linux.orig/mm/oom_kill.c	2001-11-04 01:05:25.000000000 +0000
+++ linux/mm/oom_kill.c	2002-07-20 01:08:21.000000000 +0000
@@ -110,8 +110,7 @@
 
 /*
  * Simple selection loop. We chose the process with the highest
- * number of 'points'. We need the locks to make sure that the
- * list of task structs doesn't change while we look the other way.
+ * number of 'points'. We expect the caller will lock the tasklist.
  *
  * (not docbooked, we don't want this one cluttering up the manual)
  */
@@ -121,7 +120,6 @@
 	struct task_struct *p = NULL;
 	struct task_struct *chosen = NULL;
 
-	read_lock(&tasklist_lock);
 	for_each_task(p) {
 		if (p->pid) {
 			int points = badness(p);
@@ -131,7 +129,6 @@
 			}
 		}
 	}
-	read_unlock(&tasklist_lock);
 	return chosen;
 }
 
@@ -170,16 +167,19 @@
  */
 static void oom_kill(void)
 {
-	struct task_struct *p = select_bad_process(), *q;
+	struct task_struct *p, *q;
+
+	read_lock(&tasklist_lock);
+	p = select_bad_process();
 
 	/* Found nothing?!?! Either we hang forever, or we panic. */
 	if (p == NULL)
 		panic("Out of memory and no killable processes...\n");
 
 	/* kill all processes that share the ->mm (i.e. all threads) */
-	read_lock(&tasklist_lock);
 	for_each_task(q) {
-		if(q->mm == p->mm) oom_kill_task(q);
+		if (q->mm == p->mm)
+			oom_kill_task(q);
 	}
 	read_unlock(&tasklist_lock);
 
@@ -198,7 +198,7 @@
  */
 void out_of_memory(void)
 {
-	static unsigned long first, last, count;
+	static unsigned long first, last, count, lastkill;
 	unsigned long now, since;
 
 	/*
@@ -235,8 +235,18 @@
 		return;
 
 	/*
+	 * If we just killed a process, wait a while
+	 * to give that task a chance to exit. This
+	 * avoids killing multiple processes needlessly.
+	 */
+	since = now - lastkill;
+	if (since < HZ*5)
+		return;
+
+	/*
 	 * Ok, really out of memory. Kill something.
 	 */
+	lastkill = now;
 	oom_kill();
 
 reset:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/page_alloc.c linux/mm/page_alloc.c
--- linux.orig/mm/page_alloc.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/mm/page_alloc.c	2002-07-20 01:08:24.000000000 +0000
@@ -1,6 +1,9 @@
 /*
  *  linux/mm/page_alloc.c
  *
+ *  Manages the free list, the system allocates free pages here.
+ *  Note that kmalloc() lives in slab.c
+ *
  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *  Swap reorganised 29.12.95, Stephen Tweedie
  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
@@ -17,49 +20,55 @@
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
 #include <linux/slab.h>
-#include <linux/compiler.h>
+#include <linux/module.h>
 
 int nr_swap_pages;
 int nr_active_pages;
 int nr_inactive_pages;
-struct list_head inactive_list;
-struct list_head active_list;
+LIST_HEAD(inactive_list);
+LIST_HEAD(active_list);
 pg_data_t *pgdat_list;
 
+/* Used to look up the address of the struct zone encoded in page->zone */
+zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
+EXPORT_SYMBOL(zone_table);
+
 static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
 static int zone_balance_ratio[MAX_NR_ZONES] __initdata = { 128, 128, 128, };
 static int zone_balance_min[MAX_NR_ZONES] __initdata = { 20 , 20, 20, };
 static int zone_balance_max[MAX_NR_ZONES] __initdata = { 255 , 255, 255, };
 
 /*
- * Free_page() adds the page to the free lists. This is optimized for
- * fast normal cases (no error jumps taken normally).
- *
- * The way to optimize jumps for gcc-2.2.2 is to:
- *  - select the "normal" case and put it inside the if () { XXX }
- *  - no else-statements if you can avoid them
- *
- * With the above two rules, you get a straight-line execution path
- * for the normal case, giving better asm-code.
- */
-
-#define memlist_init(x) INIT_LIST_HEAD(x)
-#define memlist_add_head list_add
-#define memlist_add_tail list_add_tail
-#define memlist_del list_del
-#define memlist_entry list_entry
-#define memlist_next(x) ((x)->next)
-#define memlist_prev(x) ((x)->prev)
-
-/*
  * Temporary debugging check.
  */
-#define BAD_RANGE(zone,x) (((zone) != (x)->zone) || (((x)-mem_map) < (zone)->zone_start_mapnr) || (((x)-mem_map) >= (zone)->zone_start_mapnr+(zone)->size))
+#define BAD_RANGE(zone, page)						\
+(									\
+	(((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size))	\
+	|| (((page) - mem_map) < (zone)->zone_start_mapnr)		\
+	|| ((zone) != page_zone(page))					\
+)
 
 /*
- * Buddy system. Hairy. You really aren't expected to understand this
+ * Freeing function for a buddy system allocator.
+ *
+ * The concept of a buddy system is to maintain direct-mapped table
+ * (containing bit values) for memory blocks of various "orders".
+ * The bottom level table contains the map for the smallest allocatable
+ * units of memory (here, pages), and each level above it describes
+ * pairs of units from the levels below, hence, "buddies".
+ * At a high level, all that happens here is marking the table entry
+ * at the bottom level available, and propagating the changes upward
+ * as necessary, plus some accounting needed to play nicely with other
+ * parts of the VM system.
+ * At each level, we keep one bit for each pair of blocks, which
+ * is set to 1 iff only one of the pair is allocated.  So when we
+ * are allocating or freeing one, we can derive the state of the
+ * other.  That is, if we allocate a small block, and both were   
+ * free, the remainder of the region must be split into blocks.   
+ * If a block is freed, and its buddy is also free, then this
+ * triggers coalescing into a block of larger size.            
  *
- * Hint: -mask = 1+~mask
+ * -- wli
  */
 
 static void FASTCALL(__free_pages_ok (struct page *page, unsigned int order));
@@ -82,12 +91,8 @@
 		BUG();
 	if (!VALID_PAGE(page))
 		BUG();
-	if (PageSwapCache(page))
-		BUG();
 	if (PageLocked(page))
 		BUG();
-	if (PageLRU(page))
-		BUG();
 	if (PageActive(page))
 		BUG();
 	page->flags &= ~((1<<PG_referenced) | (1<<PG_dirty));
@@ -96,7 +101,7 @@
 		goto local_freelist;
  back_local_freelist:
 
-	zone = page->zone;
+	zone = page_zone(page);
 
 	mask = (~0UL) << order;
 	base = zone->zone_mem_map;
@@ -123,6 +128,8 @@
 			break;
 		/*
 		 * Move the buddy up one level.
+		 * This code is taking advantage of the identity:
+		 * 	-mask = 1+~mask
 		 */
 		buddy1 = base + (page_idx ^ -mask);
 		buddy2 = base + page_idx;
@@ -131,13 +138,13 @@
 		if (BAD_RANGE(zone,buddy2))
 			BUG();
 
-		memlist_del(&buddy1->list);
+		list_del(&buddy1->list);
 		mask <<= 1;
 		area++;
 		index >>= 1;
 		page_idx &= mask;
 	}
-	memlist_add_head(&(base + page_idx)->list, &area->free_list);
+	list_add(&(base + page_idx)->list, &area->free_list);
 
 	spin_unlock_irqrestore(&zone->lock, flags);
 	return;
@@ -167,7 +174,7 @@
 		area--;
 		high--;
 		size >>= 1;
-		memlist_add_head(&(page)->list, &(area)->free_list);
+		list_add(&(page)->list, &(area)->free_list);
 		MARK_USED(index, high, area);
 		index += size;
 		page += size;
@@ -189,15 +196,15 @@
 	spin_lock_irqsave(&zone->lock, flags);
 	do {
 		head = &area->free_list;
-		curr = memlist_next(head);
+		curr = head->next;
 
 		if (curr != head) {
 			unsigned int index;
 
-			page = memlist_entry(curr, struct page, list);
+			page = list_entry(curr, struct page, list);
 			if (BAD_RANGE(zone,page))
 				BUG();
-			memlist_del(curr);
+			list_del(curr);
 			index = page - zone->zone_mem_map;
 			if (curr_order != MAX_ORDER-1)
 				MARK_USED(index, curr_order, area);
@@ -261,7 +268,7 @@
 			entry = local_pages->next;
 			do {
 				tmp = list_entry(entry, struct page, list);
-				if (tmp->index == order && memclass(tmp->zone, classzone)) {
+				if (tmp->index == order && memclass(page_zone(tmp), classzone)) {
 					list_del(entry);
 					current->nr_local_pages--;
 					set_page_count(tmp, 1);
@@ -273,8 +280,6 @@
 						BUG();
 					if (!VALID_PAGE(page))
 						BUG();
-					if (PageSwapCache(page))
-						BUG();
 					if (PageLocked(page))
 						BUG();
 					if (PageLRU(page))
@@ -317,6 +322,8 @@
 
 	zone = zonelist->zones;
 	classzone = *zone;
+	if (classzone == NULL)
+		return NULL;
 	min = 1UL << order;
 	for (;;) {
 		zone_t *z = *(zone++);
@@ -552,8 +559,7 @@
 				curr = head;
 				nr = 0;
 				for (;;) {
-					curr = memlist_next(curr);
-					if (curr == head)
+					if ((curr = curr->next) == head)
 						break;
 					nr++;
 				}
@@ -623,6 +629,48 @@
 	} 
 }
 
+/*
+ * Helper functions to size the waitqueue hash table.
+ * Essentially these want to choose hash table sizes sufficiently
+ * large so that collisions trying to wait on pages are rare.
+ * But in fact, the number of active page waitqueues on typical
+ * systems is ridiculously low, less than 200. So this is even
+ * conservative, even though it seems large.
+ *
+ * The constant PAGES_PER_WAITQUEUE specifies the ratio of pages to
+ * waitqueues, i.e. the size of the waitq table given the number of pages.
+ */
+#define PAGES_PER_WAITQUEUE	256
+
+static inline unsigned long wait_table_size(unsigned long pages)
+{
+	unsigned long size = 1;
+
+	pages /= PAGES_PER_WAITQUEUE;
+
+	while (size < pages)
+		size <<= 1;
+
+	/*
+	 * Once we have dozens or even hundreds of threads sleeping
+	 * on IO we've got bigger problems than wait queue collision.
+	 * Limit the size of the wait table to a reasonable size.
+	 */
+	size = min(size, 4096UL);
+
+	return size;
+}
+
+/*
+ * This is an integer logarithm so that shifts can be used later
+ * to extract the more random high bits from the multiplicative
+ * hash function before the remainder is taken.
+ */
+static inline unsigned long wait_table_bits(unsigned long size)
+{
+	return ffz(~size);
+}
+
 #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
 
 /*
@@ -635,7 +683,6 @@
 	unsigned long *zones_size, unsigned long zone_start_paddr, 
 	unsigned long *zholes_size, struct page *lmem_map)
 {
-	struct page *p;
 	unsigned long i, j;
 	unsigned long map_size;
 	unsigned long totalpages, offset, realtotalpages;
@@ -656,9 +703,6 @@
 			
 	printk("On node %d totalpages: %lu\n", nid, realtotalpages);
 
-	INIT_LIST_HEAD(&active_list);
-	INIT_LIST_HEAD(&inactive_list);
-
 	/*
 	 * Some architectures (with lots of mem and discontinous memory
 	 * maps) have to search for a good mem_map area:
@@ -678,24 +722,13 @@
 	pgdat->node_start_mapnr = (lmem_map - mem_map);
 	pgdat->nr_zones = 0;
 
-	/*
-	 * Initially all pages are reserved - free ones are freed
-	 * up by free_all_bootmem() once the early boot process is
-	 * done.
-	 */
-	for (p = lmem_map; p < lmem_map + totalpages; p++) {
-		set_page_count(p, 0);
-		SetPageReserved(p);
-		init_waitqueue_head(&p->wait);
-		memlist_init(&p->list);
-	}
-
 	offset = lmem_map - mem_map;	
 	for (j = 0; j < MAX_NR_ZONES; j++) {
 		zone_t *zone = pgdat->node_zones + j;
 		unsigned long mask;
 		unsigned long size, realsize;
 
+		zone_table[nid * MAX_NR_ZONES + j] = zone;
 		realsize = size = zones_size[j];
 		if (zholes_size)
 			realsize -= zholes_size[j];
@@ -710,6 +743,20 @@
 		if (!size)
 			continue;
 
+		/*
+		 * The per-page waitqueue mechanism uses hashed waitqueues
+		 * per zone.
+		 */
+		zone->wait_table_size = wait_table_size(size);
+		zone->wait_table_shift =
+			BITS_PER_LONG - wait_table_bits(zone->wait_table_size);
+		zone->wait_table = (wait_queue_head_t *)
+			alloc_bootmem_node(pgdat, zone->wait_table_size
+						* sizeof(wait_queue_head_t));
+
+		for(i = 0; i < zone->wait_table_size; ++i)
+			init_waitqueue_head(zone->wait_table + i);
+
 		pgdat->nr_zones = j+1;
 
 		mask = (realsize / zone_balance_ratio[j]);
@@ -728,11 +775,19 @@
 		if ((zone_start_paddr >> PAGE_SHIFT) & (zone_required_alignment-1))
 			printk("BUG: wrong zone alignment, it will crash\n");
 
+		/*
+		 * Initially all pages are reserved - free ones are freed
+		 * up by free_all_bootmem() once the early boot process is
+		 * done. Non-atomic initialization, single-pass.
+		 */
 		for (i = 0; i < size; i++) {
 			struct page *page = mem_map + offset + i;
-			page->zone = zone;
+			set_page_zone(page, nid * MAX_NR_ZONES + j);
+			set_page_count(page, 0);
+			SetPageReserved(page);
+			INIT_LIST_HEAD(&page->list);
 			if (j != ZONE_HIGHMEM)
-				page->virtual = __va(zone_start_paddr);
+				set_page_address(page, __va(zone_start_paddr));
 			zone_start_paddr += PAGE_SIZE;
 		}
 
@@ -740,7 +795,7 @@
 		for (i = 0; ; i++) {
 			unsigned long bitmap_size;
 
-			memlist_init(&zone->free_area[i].free_list);
+			INIT_LIST_HEAD(&zone->free_area[i].free_list);
 			if (i == MAX_ORDER-1) {
 				zone->free_area[i].map = NULL;
 				break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/page_io.c linux/mm/page_io.c
--- linux.orig/mm/page_io.c	2001-11-19 23:19:42.000000000 +0000
+++ linux/mm/page_io.c	2002-07-20 01:08:25.000000000 +0000
@@ -97,8 +97,6 @@
 		PAGE_BUG(page);
 	if (!PageSwapCache(page))
 		PAGE_BUG(page);
-	if (page->mapping != &swapper_space)
-		PAGE_BUG(page);
 	if (!rw_swap_page_base(rw, entry, page))
 		UnlockPage(page);
 }
@@ -114,14 +112,14 @@
 	
 	if (!PageLocked(page))
 		PAGE_BUG(page);
-	if (PageSwapCache(page))
-		PAGE_BUG(page);
 	if (page->mapping)
 		PAGE_BUG(page);
 	/* needs sync_page to wait I/O completation */
 	page->mapping = &swapper_space;
-	if (!rw_swap_page_base(rw, entry, page))
-		UnlockPage(page);
-	wait_on_page(page);
+	if (rw_swap_page_base(rw, entry, page))
+		lock_page(page);
+	if (!block_flushpage(page, 0))
+		PAGE_BUG(page);
 	page->mapping = NULL;
+	UnlockPage(page);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/shmem.c linux/mm/shmem.c
--- linux.orig/mm/shmem.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/mm/shmem.c	2002-07-20 01:08:34.000000000 +0000
@@ -41,7 +41,6 @@
 static struct address_space_operations shmem_aops;
 static struct file_operations shmem_file_operations;
 static struct inode_operations shmem_inode_operations;
-static struct file_operations shmem_dir_operations;
 static struct inode_operations shmem_dir_inode_operations;
 static struct vm_operations_struct shmem_vm_ops;
 
@@ -49,6 +48,8 @@
 static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
 atomic_t shmem_nrpages = ATOMIC_INIT(0); /* Not used right now */
 
+static struct page *shmem_getpage_locked(struct shmem_inode_info *, struct inode *, unsigned long);
+
 #define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
 
 /*
@@ -313,6 +314,7 @@
 static void shmem_truncate (struct inode * inode)
 {
 	unsigned long index;
+	unsigned long partial;
 	unsigned long freed = 0;
 	struct shmem_inode_info * info = SHMEM_I(inode);
 
@@ -320,6 +322,28 @@
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 	spin_lock (&info->lock);
 	index = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	partial = inode->i_size & ~PAGE_CACHE_MASK;
+
+	if (partial) {
+		swp_entry_t *entry = shmem_swp_entry(info, index-1, 0);
+		struct page *page;
+		/*
+		 * This check is racy: it's faintly possible that page
+		 * was assigned to swap during truncate_inode_pages,
+		 * and now assigned to file; but better than nothing.
+		 */
+		if (!IS_ERR(entry) && entry->val) {
+			spin_unlock(&info->lock);
+			page = shmem_getpage_locked(info, inode, index-1);
+			if (!IS_ERR(page)) {
+				memclear_highpage_flush(page, partial,
+					PAGE_CACHE_SIZE - partial);
+				UnlockPage(page);
+				page_cache_release(page);
+			}
+			spin_lock(&info->lock);
+		}
+	}
 
 	while (index < info->next_index) 
 		freed += shmem_truncate_indirect(info, index);
@@ -347,28 +371,30 @@
 	clear_inode(inode);
 }
 
-static int shmem_clear_swp (swp_entry_t entry, swp_entry_t *ptr, int size) {
+static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *ptr, swp_entry_t *eptr)
+{
 	swp_entry_t *test;
 
-	for (test = ptr; test < ptr + size; test++) {
-		if (test->val == entry.val) {
-			swap_free (entry);
-			*test = (swp_entry_t) {0};
+	for (test = ptr; test < eptr; test++) {
+		if (test->val == entry.val)
 			return test - ptr;
-		}
 	}
 	return -1;
 }
 
-static int shmem_unuse_inode (struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
+static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
 {
 	swp_entry_t *ptr;
 	unsigned long idx;
 	int offset;
-	
+
 	idx = 0;
+	ptr = info->i_direct;
 	spin_lock (&info->lock);
-	offset = shmem_clear_swp (entry, info->i_direct, SHMEM_NR_DIRECT);
+	offset = info->next_index;
+	if (offset > SHMEM_NR_DIRECT)
+		offset = SHMEM_NR_DIRECT;
+	offset = shmem_find_swp(entry, ptr, ptr + offset);
 	if (offset >= 0)
 		goto found;
 
@@ -377,13 +403,18 @@
 		ptr = shmem_swp_entry(info, idx, 0);
 		if (IS_ERR(ptr))
 			continue;
-		offset = shmem_clear_swp (entry, ptr, ENTRIES_PER_PAGE);
+		offset = info->next_index - idx;
+		if (offset > ENTRIES_PER_PAGE)
+			offset = ENTRIES_PER_PAGE;
+		offset = shmem_find_swp(entry, ptr, ptr + offset);
 		if (offset >= 0)
 			goto found;
 	}
 	spin_unlock (&info->lock);
 	return 0;
 found:
+	swap_free(entry);
+	ptr[offset] = (swp_entry_t) {0};
 	delete_from_swap_cache(page);
 	add_to_page_cache(page, info->inode->i_mapping, offset + idx);
 	SetPageDirty(page);
@@ -394,7 +425,7 @@
 }
 
 /*
- * unuse_shmem() search for an eventually swapped out shmem page.
+ * shmem_unuse() search for an eventually swapped out shmem page.
  */
 void shmem_unuse(swp_entry_t entry, struct page *page)
 {
@@ -405,8 +436,12 @@
 	list_for_each(p, &shmem_inodes) {
 		info = list_entry(p, struct shmem_inode_info, list);
 
-		if (shmem_unuse_inode(info, entry, page))
+		if (info->swapped && shmem_unuse_inode(info, entry, page)) {
+			/* move head to start search for next from here */
+			list_del(&shmem_inodes);
+			list_add_tail(&shmem_inodes, p);
 			break;
+		}
 	}
 	spin_unlock (&shmem_ilock);
 }
@@ -696,13 +731,13 @@
 			inode->i_op = &shmem_inode_operations;
 			inode->i_fop = &shmem_file_operations;
 			spin_lock (&shmem_ilock);
-			list_add (&SHMEM_I(inode)->list, &shmem_inodes);
+			list_add_tail(&SHMEM_I(inode)->list, &shmem_inodes);
 			spin_unlock (&shmem_ilock);
 			break;
 		case S_IFDIR:
 			inode->i_nlink++;
 			inode->i_op = &shmem_dir_inode_operations;
-			inode->i_fop = &shmem_dir_operations;
+			inode->i_fop = &dcache_dir_ops;
 			break;
 		case S_IFLNK:
 			break;
@@ -870,7 +905,6 @@
 fail_write:
 	status = -EFAULT;
 	ClearPageUptodate(page);
-	kunmap(page);
 	goto unlock;
 }
 
@@ -987,8 +1021,8 @@
 	struct inode * inode = shmem_get_inode(dir->i_sb, mode, dev);
 	int error = -ENOSPC;
 
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	if (inode) {
+		dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 		d_instantiate(dentry, inode);
 		dget(dentry); /* Extra count - pin the dentry in core */
 		error = 0;
@@ -1088,19 +1122,25 @@
  */
 static int shmem_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
 {
-	int error = -ENOTEMPTY;
+	struct inode *inode;
 
-	if (shmem_empty(new_dentry)) {
-		struct inode *inode = new_dentry->d_inode;
-		if (inode) {
-			inode->i_ctime = CURRENT_TIME;
-			inode->i_nlink--;
-			dput(new_dentry);
-		}
-		error = 0;
-		old_dentry->d_inode->i_ctime = old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	if (!shmem_empty(new_dentry)) 
+		return -ENOTEMPTY;
+
+	inode = new_dentry->d_inode;
+	if (inode) {
+		inode->i_ctime = CURRENT_TIME;
+		inode->i_nlink--;
+		dput(new_dentry);
 	}
-	return error;
+	inode = old_dentry->d_inode;
+	if (S_ISDIR(inode->i_mode)) {
+		old_dir->i_nlink--;
+		new_dir->i_nlink++;
+	}
+
+	inode->i_ctime = old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	return 0;
 }
 
 static int shmem_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
@@ -1117,25 +1157,29 @@
 		return error;
 
 	len = strlen(symname) + 1;
-	if (len > PAGE_CACHE_SIZE)
-		return -ENAMETOOLONG;
-		
 	inode = dentry->d_inode;
 	info = SHMEM_I(inode);
 	inode->i_size = len-1;
+	inode->i_op = &shmem_symlink_inline_operations;
+
 	if (len <= sizeof(struct shmem_inode_info)) {
 		/* do it inline */
 		memcpy(info, symname, len);
-		inode->i_op = &shmem_symlink_inline_operations;
 	} else {
+		if (len > PAGE_CACHE_SIZE) {
+			error = -ENAMETOOLONG;
+			goto rmnod;
+		}
+		inode->i_op = &shmem_symlink_inode_operations;
 		spin_lock (&shmem_ilock);
-		list_add (&info->list, &shmem_inodes);
+		list_add_tail(&info->list, &shmem_inodes);
 		spin_unlock (&shmem_ilock);
 		down(&info->sem);
 		page = shmem_getpage_locked(info, inode, 0);
 		if (IS_ERR(page)) {
 			up(&info->sem);
-			return PTR_ERR(page);
+			error = PTR_ERR(page);
+			goto rmnod;
 		}
 		kaddr = kmap(page);
 		memcpy(kaddr, symname, len);
@@ -1144,10 +1188,14 @@
 		UnlockPage(page);
 		page_cache_release(page);
 		up(&info->sem);
-		inode->i_op = &shmem_symlink_inode_operations;
 	}
 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	return 0;
+
+rmnod:
+	if (!shmem_unlink(dir, dentry))
+		d_delete(dentry);
+	return error;
 }
 
 static int shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
@@ -1346,14 +1394,6 @@
 	truncate:	shmem_truncate,
 };
 
-static struct file_operations shmem_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	dcache_readdir,
-#ifdef CONFIG_TMPFS
-	fsync:		shmem_sync_file,
-#endif
-};
-
 static struct inode_operations shmem_dir_inode_operations = {
 #ifdef CONFIG_TMPFS
 	create:		shmem_create,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/slab.c linux/mm/slab.c
--- linux.orig/mm/slab.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/mm/slab.c	2002-07-20 01:08:29.000000000 +0000
@@ -73,6 +73,7 @@
 #include	<linux/interrupt.h>
 #include	<linux/init.h>
 #include	<linux/compiler.h>
+#include	<linux/seq_file.h>
 #include	<asm/uaccess.h>
 
 /*
@@ -448,7 +449,7 @@
 		 * eliminates "false sharing".
 		 * Note for systems short on memory removing the alignment will
 		 * allow tighter packing of the smaller caches. */
-		sprintf(name,"size-%Zd",sizes->cs_size);
+		snprintf(name, sizeof(name), "size-%Zd",sizes->cs_size);
 		if (!(sizes->cs_cachep =
 			kmem_cache_create(name, sizes->cs_size,
 					0, SLAB_HWCACHE_ALIGN, NULL, NULL))) {
@@ -460,7 +461,7 @@
 			offslab_limit = sizes->cs_size-sizeof(slab_t);
 			offslab_limit /= 2;
 		}
-		sprintf(name, "size-%Zd(DMA)",sizes->cs_size);
+		snprintf(name, sizeof(name), "size-%Zd(DMA)",sizes->cs_size);
 		sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0,
 			      SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL);
 		if (!sizes->cs_dmacachep)
@@ -666,8 +667,7 @@
 	 * Always checks flags, a caller might be expecting debug
 	 * support which isn't available.
 	 */
-	if (flags & ~CREATE_MASK)
-		BUG();
+	BUG_ON(flags & ~CREATE_MASK);
 
 	/* Get cache's description obj. */
 	cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
@@ -911,14 +911,13 @@
 #define drain_cpu_caches(cachep)	do { } while (0)
 #endif
 
-static int __kmem_cache_shrink(kmem_cache_t *cachep)
+/*
+ * Called with the &cachep->spinlock held, returns number of slabs released
+ */
+static int __kmem_cache_shrink_locked(kmem_cache_t *cachep)
 {
 	slab_t *slabp;
-	int ret;
-
-	drain_cpu_caches(cachep);
-
-	spin_lock_irq(&cachep->spinlock);
+	int ret = 0;
 
 	/* If the cache is growing, stop shrinking. */
 	while (!cachep->growing) {
@@ -937,9 +936,22 @@
 
 		spin_unlock_irq(&cachep->spinlock);
 		kmem_slab_destroy(cachep, slabp);
+		ret++;
 		spin_lock_irq(&cachep->spinlock);
 	}
-	ret = !list_empty(&cachep->slabs_full) || !list_empty(&cachep->slabs_partial);
+	return ret;
+}
+
+static int __kmem_cache_shrink(kmem_cache_t *cachep)
+{
+	int ret;
+
+	drain_cpu_caches(cachep);
+
+	spin_lock_irq(&cachep->spinlock);
+	__kmem_cache_shrink_locked(cachep);
+	ret = !list_empty(&cachep->slabs_full) ||
+		!list_empty(&cachep->slabs_partial);
 	spin_unlock_irq(&cachep->spinlock);
 	return ret;
 }
@@ -949,14 +961,22 @@
  * @cachep: The cache to shrink.
  *
  * Releases as many slabs as possible for a cache.
- * To help debugging, a zero exit status indicates all slabs were released.
+ * Returns number of pages released.
  */
 int kmem_cache_shrink(kmem_cache_t *cachep)
 {
+	int ret;
+
 	if (!cachep || in_interrupt() || !is_chained_kmem_cache(cachep))
 		BUG();
 
-	return __kmem_cache_shrink(cachep);
+	drain_cpu_caches(cachep);
+  
+	spin_lock_irq(&cachep->spinlock);
+	ret = __kmem_cache_shrink_locked(cachep);
+	spin_unlock_irq(&cachep->spinlock);
+
+	return ret << cachep->gfporder;
 }
 
 /**
@@ -1831,31 +1851,56 @@
 }
 
 #ifdef CONFIG_PROC_FS
-/* /proc/slabinfo
- *	cache-name num-active-objs total-objs
- *	obj-size num-active-slabs total-slabs
- *	num-pages-per-slab
- */
-#define FIXUP(t)				\
-	do {					\
-		if (len <= off) {		\
-			off -= len;		\
-			len = 0;		\
-		} else {			\
-			if (len-off > count)	\
-				goto t;		\
-		}				\
-	} while (0)
 
-static int proc_getdata (char*page, char**start, off_t off, int count)
+static void *s_start(struct seq_file *m, loff_t *pos)
 {
+	loff_t n = *pos;
 	struct list_head *p;
-	int len = 0;
 
-	/* Output format version, so at least we can change it without _too_
-	 * many complaints.
-	 */
-	len += sprintf(page+len, "slabinfo - version: 1.1"
+	down(&cache_chain_sem);
+	if (!n)
+		return (void *)1;
+	p = &cache_cache.next;
+	while (--n) {
+		p = p->next;
+		if (p == &cache_cache.next)
+			return NULL;
+	}
+	return list_entry(p, kmem_cache_t, next);
+}
+
+static void *s_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	kmem_cache_t *cachep = p;
+	++*pos;
+	if (p == (void *)1)
+		return &cache_cache;
+	cachep = list_entry(cachep->next.next, kmem_cache_t, next);
+	return cachep == &cache_cache ? NULL : cachep;
+}
+
+static void s_stop(struct seq_file *m, void *p)
+{
+	up(&cache_chain_sem);
+}
+
+static int s_show(struct seq_file *m, void *p)
+{
+	kmem_cache_t *cachep = p;
+	struct list_head *q;
+	slab_t		*slabp;
+	unsigned long	active_objs;
+	unsigned long	num_objs;
+	unsigned long	active_slabs = 0;
+	unsigned long	num_slabs;
+	const char *name; 
+
+	if (p == (void*)1) {
+		/*
+		 * Output format version, so at least we can change it
+		 * without _too_ many complaints.
+		 */
+		seq_puts(m, "slabinfo - version: 1.1"
 #if STATS
 				" (statistics)"
 #endif
@@ -1863,109 +1908,91 @@
 				" (SMP)"
 #endif
 				"\n");
-	FIXUP(got_data);
-
-	down(&cache_chain_sem);
-	p = &cache_cache.next;
-	do {
-		kmem_cache_t	*cachep;
-		struct list_head *q;
-		slab_t		*slabp;
-		unsigned long	active_objs;
-		unsigned long	num_objs;
-		unsigned long	active_slabs = 0;
-		unsigned long	num_slabs;
-		cachep = list_entry(p, kmem_cache_t, next);
+		return 0;
+	}
 
-		spin_lock_irq(&cachep->spinlock);
-		active_objs = 0;
-		num_slabs = 0;
-		list_for_each(q,&cachep->slabs_full) {
-			slabp = list_entry(q, slab_t, list);
-			if (slabp->inuse != cachep->num)
-				BUG();
-			active_objs += cachep->num;
-			active_slabs++;
-		}
-		list_for_each(q,&cachep->slabs_partial) {
-			slabp = list_entry(q, slab_t, list);
-			if (slabp->inuse == cachep->num || !slabp->inuse)
-				BUG();
-			active_objs += slabp->inuse;
-			active_slabs++;
-		}
-		list_for_each(q,&cachep->slabs_free) {
-			slabp = list_entry(q, slab_t, list);
-			if (slabp->inuse)
-				BUG();
-			num_slabs++;
-		}
-		num_slabs+=active_slabs;
-		num_objs = num_slabs*cachep->num;
+	spin_lock_irq(&cachep->spinlock);
+	active_objs = 0;
+	num_slabs = 0;
+	list_for_each(q,&cachep->slabs_full) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse != cachep->num)
+			BUG();
+		active_objs += cachep->num;
+		active_slabs++;
+	}
+	list_for_each(q,&cachep->slabs_partial) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse == cachep->num || !slabp->inuse)
+			BUG();
+		active_objs += slabp->inuse;
+		active_slabs++;
+	}
+	list_for_each(q,&cachep->slabs_free) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse)
+			BUG();
+		num_slabs++;
+	}
+	num_slabs+=active_slabs;
+	num_objs = num_slabs*cachep->num;
 
-		len += sprintf(page+len, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
-			cachep->name, active_objs, num_objs, cachep->objsize,
-			active_slabs, num_slabs, (1<<cachep->gfporder));
+	name = cachep->name; 
+	{
+	char tmp; 
+	if (__get_user(tmp, name)) 
+		name = "broken"; 
+	}       
+
+	seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
+		name, active_objs, num_objs, cachep->objsize,
+		active_slabs, num_slabs, (1<<cachep->gfporder));
 
 #if STATS
-		{
-			unsigned long errors = cachep->errors;
-			unsigned long high = cachep->high_mark;
-			unsigned long grown = cachep->grown;
-			unsigned long reaped = cachep->reaped;
-			unsigned long allocs = cachep->num_allocations;
+	{
+		unsigned long errors = cachep->errors;
+		unsigned long high = cachep->high_mark;
+		unsigned long grown = cachep->grown;
+		unsigned long reaped = cachep->reaped;
+		unsigned long allocs = cachep->num_allocations;
 
-			len += sprintf(page+len, " : %6lu %7lu %5lu %4lu %4lu",
-					high, allocs, grown, reaped, errors);
-		}
+		seq_printf(m, " : %6lu %7lu %5lu %4lu %4lu",
+				high, allocs, grown, reaped, errors);
+	}
 #endif
 #ifdef CONFIG_SMP
-		{
-			cpucache_t *cc = cc_data(cachep);
-			unsigned int batchcount = cachep->batchcount;
-			unsigned int limit;
-
-			if (cc)
-				limit = cc->limit;
-			else
-				limit = 0;
-			len += sprintf(page+len, " : %4u %4u",
-					limit, batchcount);
-		}
+	{
+		cpucache_t *cc = cc_data(cachep);
+		unsigned int batchcount = cachep->batchcount;
+		unsigned int limit;
+
+		if (cc)
+			limit = cc->limit;
+		else
+			limit = 0;
+		seq_printf(m, " : %4u %4u",
+				limit, batchcount);
+	}
 #endif
 #if STATS && defined(CONFIG_SMP)
-		{
-			unsigned long allochit = atomic_read(&cachep->allochit);
-			unsigned long allocmiss = atomic_read(&cachep->allocmiss);
-			unsigned long freehit = atomic_read(&cachep->freehit);
-			unsigned long freemiss = atomic_read(&cachep->freemiss);
-			len += sprintf(page+len, " : %6lu %6lu %6lu %6lu",
-					allochit, allocmiss, freehit, freemiss);
-		}
+	{
+		unsigned long allochit = atomic_read(&cachep->allochit);
+		unsigned long allocmiss = atomic_read(&cachep->allocmiss);
+		unsigned long freehit = atomic_read(&cachep->freehit);
+		unsigned long freemiss = atomic_read(&cachep->freemiss);
+		seq_printf(m, " : %6lu %6lu %6lu %6lu",
+				allochit, allocmiss, freehit, freemiss);
+	}
 #endif
-		len += sprintf(page+len,"\n");
-		spin_unlock_irq(&cachep->spinlock);
-		FIXUP(got_data_up);
-		p = cachep->next.next;
-	} while (p != &cache_cache.next);
-got_data_up:
-	up(&cache_chain_sem);
-
-got_data:
-	*start = page+off;
-	return len;
+	spin_unlock_irq(&cachep->spinlock);
+	seq_putc(m, '\n');
+	return 0;
 }
 
 /**
- * slabinfo_read_proc - generates /proc/slabinfo
- * @page: scratch area, one page long
- * @start: pointer to the pointer to the output buffer
- * @off: offset within /proc/slabinfo the caller is interested in
- * @count: requested len in bytes
- * @eof: eof marker
- * @data: unused
+ * slabinfo_op - iterator that generates /proc/slabinfo
  *
- * The contents of the buffer are
+ * Output layout:
  * cache-name
  * num-active-objs
  * total-objs
@@ -1975,28 +2002,24 @@
  * num-pages-per-slab
  * + further values on SMP and with statistics enabled
  */
-int slabinfo_read_proc (char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = proc_getdata(page, start, off, count);
-	len -= (*start-page);
-	if (len <= count)
-		*eof = 1;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
+
+struct seq_operations slabinfo_op = {
+	start:	s_start,
+	next:	s_next,
+	stop:	s_stop,
+	show:	s_show
+};
 
 #define MAX_SLABINFO_WRITE 128
 /**
- * slabinfo_write_proc - SMP tuning for the slab allocator
+ * slabinfo_write - SMP tuning for the slab allocator
  * @file: unused
  * @buffer: user buffer
  * @count: data len
  * @data: unused
  */
-int slabinfo_write_proc (struct file *file, const char *buffer,
-				unsigned long count, void *data)
+ssize_t slabinfo_write(struct file *file, const char *buffer,
+				size_t count, loff_t *ppos)
 {
 #ifdef CONFIG_SMP
 	char kbuf[MAX_SLABINFO_WRITE+1], *tmp;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/swapfile.c linux/mm/swapfile.c
--- linux.orig/mm/swapfile.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/mm/swapfile.c	2002-07-20 01:08:28.000000000 +0000
@@ -14,7 +14,6 @@
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/shm.h>
-#include <linux/compiler.h>
 
 #include <asm/pgtable.h>
 
@@ -672,10 +671,7 @@
 		 * private" pages, but they are handled by tmpfs files.
 		 * Note shmem_unuse already deleted its from swap cache.
 		 */
-		swcount = *swap_map;
-		if ((swcount > 0) != PageSwapCache(page))
-			BUG();
-		if ((swcount > 1) && PageDirty(page)) {
+		if ((*swap_map > 1) && PageDirty(page) && PageSwapCache(page)) {
 			rw_swap_page(WRITE, page);
 			lock_page(page);
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/mm/vmscan.c linux/mm/vmscan.c
--- linux.orig/mm/vmscan.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/mm/vmscan.c	2002-07-20 01:08:26.000000000 +0000
@@ -20,7 +20,6 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/file.h>
-#include <linux/compiler.h>
 
 #include <asm/pgalloc.h>
 
@@ -58,7 +57,7 @@
 		return 0;
 
 	/* Don't bother replenishing zones not under pressure.. */
-	if (!memclass(page->zone, classzone))
+	if (!memclass(page_zone(page), classzone))
 		return 0;
 
 	if (TryLockPage(page))
@@ -234,8 +233,7 @@
 	pgdir = pgd_offset(mm, address);
 
 	end = vma->vm_end;
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
 	do {
 		count = swap_out_pgd(mm, vma, pgdir, address, end, count, classzone);
 		if (!count)
@@ -354,10 +352,8 @@
 
 		page = list_entry(entry, struct page, lru);
 
-		if (unlikely(!PageLRU(page)))
-			BUG();
-		if (unlikely(PageActive(page)))
-			BUG();
+		BUG_ON(!PageLRU(page));
+		BUG_ON(PageActive(page));
 
 		list_del(entry);
 		list_add(entry, &inactive_list);
@@ -369,7 +365,7 @@
 		if (unlikely(!page_count(page)))
 			continue;
 
-		if (!memclass(page->zone, classzone))
+		if (!memclass(page_zone(page), classzone))
 			continue;
 
 		/* Racy check to avoid trylocking when not worthwhile */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/802/Makefile linux/net/802/Makefile
--- linux.orig/net/802/Makefile	2001-10-30 23:08:12.000000000 +0000
+++ linux/net/802/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -57,4 +57,5 @@
 include $(TOPDIR)/Rules.make
 
 cl2llc.c: cl2llc.pre
+	@rm -f $@
 	sed -f ./pseudo/opcd2num.sed cl2llc.pre >cl2llc.c
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/802/cl2llc.pre linux/net/802/cl2llc.pre
--- linux.orig/net/802/cl2llc.pre	2001-11-09 22:11:15.000000000 +0000
+++ linux/net/802/cl2llc.pre	2002-07-20 01:08:32.000000000 +0000
@@ -96,7 +96,7 @@
 				else
 					llc_interpret_pseudo_code(lp, REJECT1, skb, NO_FRAME);
 				break;
-			default:
+			default:;
 		}
 		if(lp->llc_callbacks)
 		{
@@ -497,7 +497,7 @@
 				else
 					lp->f_flag = fr->i_hdr.i_pflag;
 				break;
-			default:
+			default:;
 		}
 		pc++;	
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/802/tr.c linux/net/802/tr.c
--- linux.orig/net/802/tr.c	2000-10-16 19:42:53.000000000 +0000
+++ linux/net/802/tr.c	2002-07-20 01:08:24.000000000 +0000
@@ -36,7 +36,8 @@
 #include <linux/init.h>
 #include <net/arp.h>
 
-static void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev);
+void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh,
+		     struct net_device *dev);
 static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev);
 static void rif_check_expire(unsigned long dummy);
 
@@ -65,7 +66,7 @@
  *	up a lot.
  */
  
-rif_cache rif_table[RIF_TABLE_SIZE]={ NULL, };
+rif_cache rif_table[RIF_TABLE_SIZE];
 
 static spinlock_t rif_lock = SPIN_LOCK_UNLOCKED;
 
@@ -230,7 +231,8 @@
  *	We try to do source routing... 
  */
 
-static void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev) 
+void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh,
+		     struct net_device *dev) 
 {
 	int i, slack;
 	unsigned int hash;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/8021q/vlan.c linux/net/8021q/vlan.c
--- linux.orig/net/8021q/vlan.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/8021q/vlan.c	2002-07-20 01:08:29.000000000 +0000
@@ -8,7 +8,9 @@
  * 
  * Fixes:
  *              Fix for packet capture - Nick Eggleston <nick@dccinc.com>;
- *
+ *		Add HW acceleration hooks - David S. Miller <davem@redhat.com>;
+ *		Correct all the locking - David S. Miller <davem@redhat.com>;
+ *		Use hash table for VLAN groups - David S. Miller <davem@redhat.com>
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -37,12 +39,15 @@
 /* Global VLAN variables */
 
 /* Our listing of VLAN group(s) */
-struct vlan_group *p802_1Q_vlan_list;
+struct vlan_group *vlan_group_hash[VLAN_GRP_HASH_SIZE];
+spinlock_t vlan_group_lock = SPIN_LOCK_UNLOCKED;
+#define vlan_grp_hashfn(IDX)	((((IDX) >> VLAN_GRP_HASH_SHIFT) ^ (IDX)) & VLAN_GRP_HASH_MASK)
 
 static char vlan_fullname[] = "802.1Q VLAN Support";
 static unsigned int vlan_version = 1;
-static unsigned int vlan_release = 6;
-static char vlan_copyright[] = " Ben Greear <greearb@candelatech.com>";
+static unsigned int vlan_release = 7;
+static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
+static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
 
 static int vlan_device_event(struct notifier_block *, unsigned long, void *);
 
@@ -55,9 +60,6 @@
 /* Determines interface naming scheme. */
 unsigned short vlan_name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
 
-/* Counter for how many NON-VLAN protos we've received on a VLAN. */
-unsigned long vlan_bad_proto_recvd = 0;
-
 /* DO reorder the header by default */
 unsigned short vlan_default_dev_flags = 1;
 
@@ -83,6 +85,8 @@
 
 	printk(VLAN_INF "%s v%u.%u %s\n",
 	       vlan_fullname, vlan_version, vlan_release, vlan_copyright);
+	printk(VLAN_INF "All bugs added by %s\n",
+	       vlan_buggyright);
 
 	/* proc file system initialization */
 	err = vlan_proc_init();
@@ -100,71 +104,83 @@
 
 	vlan_ioctl_hook = vlan_ioctl_handler;
 
-	printk(VLAN_INF "%s Initialization complete.\n", VLAN_NAME);
 	return 0;
 }
 
 /*
- * Cleanup of groups before exit
- */
-
-static void vlan_group_cleanup(void)
-{
-	struct vlan_group *grp = NULL;
-	struct vlan_group *nextgroup;
-
-	for (grp = p802_1Q_vlan_list; (grp != NULL);) {
-		nextgroup = grp->next;
-		kfree(grp);
-		grp = nextgroup;
-	}
-	p802_1Q_vlan_list = NULL;
-}
-
-/*
  *     Module 'remove' entry point.
  *     o delete /proc/net/router directory and static entries.
  */ 
 static void __exit vlan_cleanup_module(void)
 {
+	int i;
+
+	/* This table must be empty if there are no module
+	 * references left.
+	 */
+	for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) {
+		if (vlan_group_hash[i] != NULL)
+			BUG();
+	}
+
 	/* Un-register us from receiving netdevice events */
 	unregister_netdevice_notifier(&vlan_notifier_block);
 
 	dev_remove_pack(&vlan_packet_type);
 	vlan_proc_cleanup();
-	vlan_group_cleanup();
 	vlan_ioctl_hook = NULL;
 }
 
 module_init(vlan_proto_init);
 module_exit(vlan_cleanup_module);
 
-/**  Will search linearly for now, based on device index.  Could
- * hash, or directly link, this some day. --Ben
- * TODO:  Potential performance issue here.  Linear search where N is
- *        the number of 'real' devices used by VLANs.
- */
-struct vlan_group* vlan_find_group(int real_dev_ifindex)
+/* Must be invoked with vlan_group_lock held. */
+static struct vlan_group *__vlan_find_group(int real_dev_ifindex)
 {
-	struct vlan_group *grp = NULL;
+	struct vlan_group *grp;
 
-	br_read_lock_bh(BR_NETPROTO_LOCK);
-	for (grp = p802_1Q_vlan_list;
-	     ((grp != NULL) && (grp->real_dev_ifindex != real_dev_ifindex));
+	for (grp = vlan_group_hash[vlan_grp_hashfn(real_dev_ifindex)];
+	     grp != NULL;
 	     grp = grp->next) {
-		/* nothing */ ;
+		if (grp->real_dev_ifindex == real_dev_ifindex)
+			break;
 	}
-	br_read_unlock_bh(BR_NETPROTO_LOCK);
 
 	return grp;
 }
 
-/*  Find the protocol handler.  Assumes VID < 0xFFF.
+/* Must hold vlan_group_lock. */
+static void __grp_hash(struct vlan_group *grp)
+{
+	struct vlan_group **head;
+
+	head = &vlan_group_hash[vlan_grp_hashfn(grp->real_dev_ifindex)];
+	grp->next = *head;
+	*head = grp;
+}
+
+/* Must hold vlan_group_lock. */
+static void __grp_unhash(struct vlan_group *grp)
+{
+	struct vlan_group *next, **pprev;
+
+	pprev = &vlan_group_hash[vlan_grp_hashfn(grp->real_dev_ifindex)];
+	next = *pprev;
+	while (next != grp) {
+		pprev = &next->next;
+		next = *pprev;
+	}
+	*pprev = grp->next;
+}
+
+/*  Find the protocol handler.  Assumes VID < VLAN_VID_MASK.
+ *
+ * Must be invoked with vlan_group_lock held.
  */
-struct net_device *find_802_1Q_vlan_dev(struct net_device *real_dev,
-                                        unsigned short VID)
+struct net_device *__find_vlan_dev(struct net_device *real_dev,
+				   unsigned short VID)
 {
-	struct vlan_group *grp = vlan_find_group(real_dev->ifindex);
+	struct vlan_group *grp = __vlan_find_group(real_dev->ifindex);
 
 	if (grp)
                 return grp->vlan_devices[VID];
@@ -172,109 +188,143 @@
 	return NULL;
 }
 
-/** This method will explicitly do a dev_put on the device if do_dev_put
- * is TRUE.  This gets around a difficulty with reference counting, and
- * the unregister-by-name (below).  If do_locks is true, it will grab
- * a lock before un-registering.  If do_locks is false, it is assumed that
- * the lock has already been grabbed externally...  --Ben
+/* This returns 0 if everything went fine.
+ * It will return 1 if the group was killed as a result.
+ * A negative return indicates failure.
+ *
+ * The RTNL lock must be held.
  */
-int unregister_802_1Q_vlan_dev(int real_dev_ifindex, unsigned short vlan_id,
-			       int do_dev_put, int do_locks)
+static int unregister_vlan_dev(struct net_device *real_dev,
+			       unsigned short vlan_id)
 {
 	struct net_device *dev = NULL;
+	int real_dev_ifindex = real_dev->ifindex;
 	struct vlan_group *grp;
+	int i, ret;
 
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG __FUNCTION__ ": VID: %i\n", vlan_id);
 #endif
 
 	/* sanity check */
-	if ((vlan_id >= 0xFFF) || (vlan_id <= 0))
+	if ((vlan_id >= VLAN_VID_MASK) || (vlan_id <= 0))
 		return -EINVAL;
 
-	grp = vlan_find_group(real_dev_ifindex);
+	spin_lock_bh(&vlan_group_lock);
+	grp = __vlan_find_group(real_dev_ifindex);
+	spin_unlock_bh(&vlan_group_lock);
+
+	ret = 0;
+
 	if (grp) {
 		dev = grp->vlan_devices[vlan_id];
 		if (dev) {
 			/* Remove proc entry */
 			vlan_proc_rem_dev(dev);
 
-			/* Take it out of our own structures */
-			grp->vlan_devices[vlan_id] = NULL;
+			/* Take it out of our own structures, but be sure to
+			 * interlock with HW accelerating devices or SW vlan
+			 * input packet processing.
+			 */
+			if (real_dev->features &
+			    (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER)) {
+				real_dev->vlan_rx_kill_vid(real_dev, vlan_id);
+			} else {
+				br_write_lock(BR_NETPROTO_LOCK);
+				grp->vlan_devices[vlan_id] = NULL;
+				br_write_unlock(BR_NETPROTO_LOCK);
+			}
 
-			/* Take it out of the global list of devices.
-			 *  NOTE:  This deletes dev, don't access it again!!
+			/* Caller unregisters (and if necessary, puts)
+			 * VLAN device, but we get rid of the reference to
+			 * real_dev here.
 			 */
+			dev_put(real_dev);
 
-			if (do_dev_put)
-				dev_put(dev);
+			/* If the group is now empty, kill off the
+			 * group.
+			 */
+			for (i = 0; i < VLAN_VID_MASK; i++)
+				if (grp->vlan_devices[i])
+					break;
+
+			if (i == VLAN_VID_MASK) {
+				if (real_dev->features & NETIF_F_HW_VLAN_RX)
+					real_dev->vlan_rx_register(real_dev, NULL);
+
+				spin_lock_bh(&vlan_group_lock);
+				__grp_unhash(grp);
+				spin_unlock_bh(&vlan_group_lock);
 
-			/* TODO:  Please review this code. */
-			if (do_locks) {
-				rtnl_lock();
-				unregister_netdevice(dev);
-				rtnl_unlock();
-			} else {
-				unregister_netdevice(dev);
+				ret = 1;
 			}
 
 			MOD_DEC_USE_COUNT;
 		}
 	}
-        
-        return 0;
+
+        return ret;
 }
 
-int unregister_802_1Q_vlan_device(const char *vlan_IF_name)
+static int unregister_vlan_device(const char *vlan_IF_name)
 {
 	struct net_device *dev = NULL;
+	int ret;
 
-#ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": unregister VLAN by name, name -:%s:-\n",
-	       vlan_IF_name);
-#endif
 
 	dev = dev_get_by_name(vlan_IF_name);
+	ret = -EINVAL;
 	if (dev) {
 		if (dev->priv_flags & IFF_802_1Q_VLAN) {
-			return unregister_802_1Q_vlan_dev(
-				VLAN_DEV_INFO(dev)->real_dev->ifindex,
-				(unsigned short)(VLAN_DEV_INFO(dev)->vlan_id),
-				1 /* do dev_put */, 1 /* do locking */);
+			rtnl_lock();
+
+			ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
+						  VLAN_DEV_INFO(dev)->vlan_id);
+
+			dev_put(dev);
+			unregister_netdevice(dev);
+
+			rtnl_unlock();
+
+			if (ret == 1)
+				ret = 0;
 		} else {
 			printk(VLAN_ERR __FUNCTION__
 			       ": ERROR:	Tried to remove a non-vlan device "
 			       "with VLAN code, name: %s  priv_flags: %hX\n",
 			       dev->name, dev->priv_flags);
 			dev_put(dev);
-			return -EPERM;
+			ret = -EPERM;
 		}
 	} else {
 #ifdef VLAN_DEBUG
 		printk(VLAN_DBG __FUNCTION__ ": WARNING: Could not find dev.\n");
 #endif
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+
+	return ret;
 }
 
 /*  Attach a VLAN device to a mac address (ie Ethernet Card).
  *  Returns the device that was created, or NULL if there was
  *  an error of some kind.
  */
-struct net_device *register_802_1Q_vlan_device(const char* eth_IF_name,
+static struct net_device *register_vlan_device(const char *eth_IF_name,
 					       unsigned short VLAN_ID)
 {
 	struct vlan_group *grp;
 	struct net_device *new_dev;
 	struct net_device *real_dev; /* the ethernet device */
 	int malloc_size = 0;
+	int r;
 
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG __FUNCTION__ ": if_name -:%s:-	vid: %i\n",
 	       eth_IF_name, VLAN_ID);
 #endif
 
-	if (VLAN_ID >= 0xfff)
+	if (VLAN_ID >= VLAN_VID_MASK)
 		goto out_ret_null;
 
 	/* find the device relating to eth_IF_name. */
@@ -282,14 +332,47 @@
 	if (!real_dev)
 		goto out_ret_null;
 
-	/* TODO:  Make sure this device can really handle having a VLAN attached
-	 * to it...
+	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
+		printk(VLAN_DBG __FUNCTION__ ": VLANs not supported on %s.\n",
+		       real_dev->name);
+		goto out_put_dev;
+	}
+
+	if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
+	    (real_dev->vlan_rx_register == NULL ||
+	     real_dev->vlan_rx_kill_vid == NULL)) {
+		printk(VLAN_DBG __FUNCTION__ ": Device %s has buggy VLAN hw accel.\n",
+		       real_dev->name);
+		goto out_put_dev;
+	}
+
+	if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
+	    (real_dev->vlan_rx_add_vid == NULL ||
+	     real_dev->vlan_rx_kill_vid == NULL)) {
+		printk(VLAN_DBG __FUNCTION__ ": Device %s has buggy VLAN hw accel.\n",
+		       real_dev->name);
+		goto out_put_dev;
+	}
+
+	/* From this point on, all the data structures must remain
+	 * consistent.
+	 */
+	rtnl_lock();
+
+	/* The real device must be up and operating in order to
+	 * assosciate a VLAN device with it.
 	 */
-	if (find_802_1Q_vlan_dev(real_dev, VLAN_ID)) {
+	if (!(real_dev->flags & IFF_UP))
+		goto out_unlock;
+
+	spin_lock_bh(&vlan_group_lock);
+	r = (__find_vlan_dev(real_dev, VLAN_ID) != NULL);
+	spin_unlock_bh(&vlan_group_lock);
+
+	if (r) {
 		/* was already registered. */
 		printk(VLAN_DBG __FUNCTION__ ": ALREADY had VLAN registered\n");
-		dev_put(real_dev);
-		return NULL;
+		goto out_unlock;
 	}
 
 	malloc_size = (sizeof(struct net_device));
@@ -298,15 +381,14 @@
 		     new_dev, malloc_size);
 
 	if (new_dev == NULL)
-		goto out_put_dev;
+		goto out_unlock;
 
 	memset(new_dev, 0, malloc_size);
 
-	/* set us up to not use a Qdisc, as the underlying Hardware device
+	/* Set us up to have no queue, as the underlying Hardware device
 	 * can do all the queueing we could want.
 	 */
-	/* new_dev->qdisc_sleeping = &noqueue_qdisc;   Not needed it seems. */
-	new_dev->tx_queue_len = 0; /* This should effectively give us no queue. */
+	new_dev->tx_queue_len = 0;
 
 	/* Gotta set up the fields for the device. */
 #ifdef VLAN_DEBUG
@@ -368,8 +450,11 @@
 	/* TODO: maybe just assign it to be ETHERNET? */
 	new_dev->type = real_dev->type;
 
-	/* Regular ethernet + 4 bytes (18 total). */
-	new_dev->hard_header_len = VLAN_HLEN + real_dev->hard_header_len;
+	new_dev->hard_header_len = real_dev->hard_header_len;
+	if (!(real_dev->features & NETIF_F_HW_VLAN_TX)) {
+		/* Regular ethernet + 4 bytes (18 total). */
+		new_dev->hard_header_len += VLAN_HLEN;
+	}
 
 	new_dev->priv = kmalloc(sizeof(struct vlan_dev_info),
 				GFP_KERNEL);
@@ -377,10 +462,8 @@
 		     new_dev->priv,
 		     sizeof(struct vlan_dev_info));
 	    
-	if (new_dev->priv == NULL) {
-		kfree(new_dev);
-		goto out_put_dev;
-	}
+	if (new_dev->priv == NULL)
+		goto out_free_newdev;
 
 	memset(new_dev->priv, 0, sizeof(struct vlan_dev_info));
 
@@ -390,15 +473,21 @@
 
 	new_dev->open = vlan_dev_open;
 	new_dev->stop = vlan_dev_stop;
-	new_dev->hard_header = vlan_dev_hard_header;
 
-	new_dev->hard_start_xmit = vlan_dev_hard_start_xmit;
-	new_dev->rebuild_header = vlan_dev_rebuild_header;
+	if (real_dev->features & NETIF_F_HW_VLAN_TX) {
+		new_dev->hard_header = real_dev->hard_header;
+		new_dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
+		new_dev->rebuild_header = real_dev->rebuild_header;
+	} else {
+		new_dev->hard_header = vlan_dev_hard_header;
+		new_dev->hard_start_xmit = vlan_dev_hard_start_xmit;
+		new_dev->rebuild_header = vlan_dev_rebuild_header;
+	}
 	new_dev->hard_header_parse = real_dev->hard_header_parse;
 	new_dev->set_mac_address = vlan_dev_set_mac_address;
 	new_dev->set_multicast_list = vlan_dev_set_multicast_list;
 
-	VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through 0xFFF */
+	VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
 	VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
 	VLAN_DEV_INFO(new_dev)->dent = NULL;
 	VLAN_DEV_INFO(new_dev)->flags = vlan_default_dev_flags;
@@ -411,37 +500,39 @@
 	/* So, got the sucker initialized, now lets place
 	 * it into our local structure.
 	 */
-	grp = vlan_find_group(real_dev->ifindex);
+	spin_lock_bh(&vlan_group_lock);
+	grp = __vlan_find_group(real_dev->ifindex);
+	spin_unlock_bh(&vlan_group_lock);
+
+	/* Note, we are running under the RTNL semaphore
+	 * so it cannot "appear" on us.
+	 */
 	if (!grp) { /* need to add a new group */
 		grp = kmalloc(sizeof(struct vlan_group), GFP_KERNEL);
-		VLAN_MEM_DBG("grp malloc, addr: %p  size: %i\n",
-			     grp, sizeof(struct vlan_group));
-		if (!grp) {
-			kfree(new_dev->priv);
-			VLAN_FMEM_DBG("new_dev->priv free, addr: %p\n",
-				      new_dev->priv);
-			kfree(new_dev);
-			VLAN_FMEM_DBG("new_dev free, addr: %p\n", new_dev);
-
-			goto out_put_dev;
-		}
+		if (!grp)
+			goto out_free_newdev_priv;
 					
-		printk(KERN_ALERT "VLAN REGISTER:  Allocated new group.\n");
+		/* printk(KERN_ALERT "VLAN REGISTER:  Allocated new group.\n"); */
 		memset(grp, 0, sizeof(struct vlan_group));
 		grp->real_dev_ifindex = real_dev->ifindex;
 
-		br_write_lock_bh(BR_NETPROTO_LOCK);
-		grp->next = p802_1Q_vlan_list;
-		p802_1Q_vlan_list = grp;
-		br_write_unlock_bh(BR_NETPROTO_LOCK);
+		spin_lock_bh(&vlan_group_lock);
+		__grp_hash(grp);
+		spin_unlock_bh(&vlan_group_lock);
+
+		if (real_dev->features & NETIF_F_HW_VLAN_RX)
+			real_dev->vlan_rx_register(real_dev, grp);
 	}
 	    
 	grp->vlan_devices[VLAN_ID] = new_dev;
+
 	vlan_proc_add_dev(new_dev); /* create it's proc entry */
 
-	/* TODO: Please check this: RTNL   --Ben */
-	rtnl_lock();
+	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
+		real_dev->vlan_rx_add_vid(real_dev, VLAN_ID);
+
 	register_netdevice(new_dev);
+
 	rtnl_unlock();
 	    
 	/* NOTE:  We have a reference to the real device,
@@ -453,6 +544,15 @@
 #endif
 	return new_dev;
 
+out_free_newdev_priv:
+	kfree(new_dev->priv);
+
+out_free_newdev:
+	kfree(new_dev);
+
+out_unlock:
+	rtnl_unlock();
+
 out_put_dev:
 	dev_put(real_dev);
 
@@ -464,78 +564,78 @@
 {
 	struct net_device *dev = (struct net_device *)(ptr);
 	struct vlan_group *grp = NULL;
-	int i = 0;
+	int i, flgs;
 	struct net_device *vlandev = NULL;
 
+	spin_lock_bh(&vlan_group_lock);
+	grp = __vlan_find_group(dev->ifindex);
+	spin_unlock_bh(&vlan_group_lock);
+
+	if (!grp)
+		goto out;
+
+	/* It is OK that we do not hold the group lock right now,
+	 * as we run under the RTNL lock.
+	 */
+
 	switch (event) {
 	case NETDEV_CHANGEADDR:
-		/* Ignore for now */
-		break;
-
 	case NETDEV_GOING_DOWN:
 		/* Ignore for now */
 		break;
 
 	case NETDEV_DOWN:
-		/* TODO:  Please review this code. */
-		/* put all related VLANs in the down state too. */
-		for (grp = p802_1Q_vlan_list; grp != NULL; grp = grp->next) {
-			int flgs = 0;
-
-			for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
-				vlandev = grp->vlan_devices[i];
-				if (!vlandev ||
-				    (VLAN_DEV_INFO(vlandev)->real_dev != dev) ||
-				    (!(vlandev->flags & IFF_UP)))
-					continue;
-
-				flgs = vlandev->flags;
-				flgs &= ~IFF_UP;
-				dev_change_flags(vlandev, flgs);
-			}
+		/* Put all VLANs for this dev in the down state too.  */
+		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+			vlandev = grp->vlan_devices[i];
+			if (!vlandev)
+				continue;
+
+			flgs = vlandev->flags;
+			if (!(flgs & IFF_UP))
+				continue;
+
+			dev_change_flags(vlandev, flgs & ~IFF_UP);
 		}
 		break;
 
 	case NETDEV_UP:
-		/* TODO:  Please review this code. */
-		/* put all related VLANs in the down state too. */
-		for (grp = p802_1Q_vlan_list; grp != NULL; grp = grp->next) {
-			int flgs;
-
-			for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
-				vlandev = grp->vlan_devices[i];
-				if (!vlandev ||
-				    (VLAN_DEV_INFO(vlandev)->real_dev != dev) ||
-				    (vlandev->flags & IFF_UP))
-					continue;
+		/* Put all VLANs for this dev in the up state too.  */
+		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+			vlandev = grp->vlan_devices[i];
+			if (!vlandev)
+				continue;
 				
-				flgs = vlandev->flags;
-				flgs |= IFF_UP;
-				dev_change_flags(vlandev, flgs);
-			}
+			flgs = vlandev->flags;
+			if (flgs & IFF_UP)
+				continue;
+
+			dev_change_flags(vlandev, flgs | IFF_UP);
 		}
 		break;
 		
 	case NETDEV_UNREGISTER:
-		/* TODO:  Please review this code. */
-		/* delete all related VLANs. */
-		for (grp = p802_1Q_vlan_list; grp != NULL; grp = grp->next) {
-			for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
-				vlandev = grp->vlan_devices[i];
-				if (!vlandev ||
-				    (VLAN_DEV_INFO(vlandev)->real_dev != dev))
-					continue;
-
-				unregister_802_1Q_vlan_dev(
-					VLAN_DEV_INFO(vlandev)->real_dev->ifindex,
-					VLAN_DEV_INFO(vlandev)->vlan_id,
-					0, 0);
-				vlandev = NULL;
-			}
+		/* Delete all VLANs for this dev. */
+		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+			int ret;
+
+			vlandev = grp->vlan_devices[i];
+			if (!vlandev)
+				continue;
+
+			ret = unregister_vlan_dev(dev,
+						  VLAN_DEV_INFO(vlandev)->vlan_id);
+
+			unregister_netdev(vlandev);
+
+			/* Group was destroyed? */
+			if (ret == 1)
+				break;
 		}
 		break;
 	};
 
+out:
 	return NOTIFY_DONE;
 }
 
@@ -612,7 +712,7 @@
 		 * talk to:  args.dev1	 We also have the
 		 * VLAN ID:  args.u.VID
 		 */
-		if (register_802_1Q_vlan_device(args.device1, args.u.VID)) {
+		if (register_vlan_device(args.device1, args.u.VID)) {
 			err = 0;
 		} else {
 			err = -EINVAL;
@@ -623,7 +723,7 @@
 		/* Here, the args.dev1 is the actual VLAN we want
 		 * to get rid of.
 		 */
-		err = unregister_802_1Q_vlan_device(args.device1);
+		err = unregister_vlan_device(args.device1);
 		break;
 
 	default:
@@ -636,4 +736,4 @@
 	return err;
 }
 
-
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/8021q/vlan.h linux/net/8021q/vlan.h
--- linux.orig/net/8021q/vlan.h	2001-10-30 23:08:12.000000000 +0000
+++ linux/net/8021q/vlan.h	2002-07-20 01:08:38.000000000 +0000
@@ -30,14 +30,48 @@
 
 extern unsigned short vlan_name_type;
 
-/* Counter for how many NON-VLAN protos we've received on a VLAN. */
-extern unsigned long vlan_bad_proto_recvd;
-
 int vlan_ioctl_handler(unsigned long arg);
 
-/* Add some headers for the public VLAN methods. */
-int unregister_802_1Q_vlan_device(const char* vlan_IF_name);
-struct net_device *register_802_1Q_vlan_device(const char* eth_IF_name,
-                                               unsigned short VID);
+#define VLAN_GRP_HASH_SHIFT	5
+#define VLAN_GRP_HASH_SIZE	(1 << VLAN_GRP_HASH_SHIFT)
+#define VLAN_GRP_HASH_MASK	(VLAN_GRP_HASH_SIZE - 1)
+extern struct vlan_group *vlan_group_hash[VLAN_GRP_HASH_SIZE];
+extern spinlock_t vlan_group_lock;
+
+/*  Find a VLAN device by the MAC address of it's Ethernet device, and
+ *  it's VLAN ID.  The default configuration is to have VLAN's scope
+ *  to be box-wide, so the MAC will be ignored.  The mac will only be
+ *  looked at if we are configured to have a seperate set of VLANs per
+ *  each MAC addressable interface.  Note that this latter option does
+ *  NOT follow the spec for VLANs, but may be useful for doing very
+ *  large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs.
+ *
+ *  Must be invoked with vlan_group_lock held and that lock MUST NOT
+ *  be dropped until a reference is obtained on the returned device.
+ *  You may drop the lock earlier if you are running under the RTNL
+ *  semaphore, however.
+ */
+struct net_device *__find_vlan_dev(struct net_device* real_dev,
+				   unsigned short VID); /* vlan.c */
+
+/* found in vlan_dev.c */
+int vlan_dev_rebuild_header(struct sk_buff *skb);
+int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
+                  struct packet_type* ptype);
+int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
+                         unsigned short type, void *daddr, void *saddr,
+                         unsigned len);
+int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
+int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
+int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
+int vlan_dev_set_mac_address(struct net_device *dev, void* addr);
+int vlan_dev_open(struct net_device* dev);
+int vlan_dev_stop(struct net_device* dev);
+int vlan_dev_init(struct net_device* dev);
+void vlan_dev_destruct(struct net_device* dev);
+int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
+int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
+int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val);
+void vlan_dev_set_multicast_list(struct net_device *vlan_dev);
 
 #endif /* !(__BEN_VLAN_802_1Q_INC__) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/8021q/vlan_dev.c linux/net/8021q/vlan_dev.c
--- linux.orig/net/8021q/vlan_dev.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/8021q/vlan_dev.c	2002-07-20 01:08:39.000000000 +0000
@@ -38,12 +38,6 @@
 #include <linux/if_vlan.h>
 #include <net/ip.h>
 
-struct net_device_stats *vlan_dev_get_stats(struct net_device *dev)
-{
-	return &(((struct vlan_dev_info *)(dev->priv))->dev_stats);
-}
-
-
 /*
  *	Rebuild the Ethernet MAC header. This is called after an ARP
  *	(or in future other address resolution) has completed on this
@@ -78,6 +72,21 @@
 	return 0;
 }
 
+static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
+{
+	if (VLAN_DEV_INFO(skb->dev)->flags & 1) {
+		skb = skb_share_check(skb, GFP_ATOMIC);
+		if (skb) {
+			/* Lifted from Gleb's VLAN code... */
+			memmove(skb->data - ETH_HLEN,
+				skb->data - VLAN_ETH_HLEN, 12);
+			skb->mac.raw += VLAN_HLEN;
+		}
+	}
+
+	return skb;
+}
+
 /*
  *	Determine the packet's protocol ID. The rule here is that we 
  *	assume 802.3 if the type field is short enough to be a length.
@@ -113,7 +122,7 @@
 	/* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */
 	vlan_TCI = ntohs(vhdr->h_vlan_TCI);
 
-	vid = (vlan_TCI & 0xFFF);
+	vid = (vlan_TCI & VLAN_VID_MASK);
 
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG __FUNCTION__ ": skb: %p vlan_id: %hx\n",
@@ -124,11 +133,18 @@
 	 * and then go on as usual.
 	 */
 
-	/* we have 12 bits of vlan ID. */
-	/* If it's NULL, we will tag it to be junked below */
-	skb->dev = find_802_1Q_vlan_dev(dev, vid);
+	/* We have 12 bits of vlan ID.
+	 *
+	 * We must not drop the vlan_group_lock until we hold a
+	 * reference to the device (netif_rx does that) or we
+	 * fail.
+	 */
 
+	spin_lock_bh(&vlan_group_lock);
+	skb->dev = __find_vlan_dev(dev, vid);
 	if (!skb->dev) {
+		spin_unlock_bh(&vlan_group_lock);
+
 #ifdef VLAN_DEBUG
 		printk(VLAN_DBG __FUNCTION__ ": ERROR:	No net_device for VID: %i on dev: %s [%i]\n",
 		       (unsigned int)(vid), dev->name, dev->ifindex);
@@ -137,6 +153,8 @@
 		return -1;
 	}
 
+	skb->dev->last_rx = jiffies;
+
 	/* Bump the rx counters for the VLAN device. */
 	stats = vlan_dev_get_stats(skb->dev);
 	stats->rx_packets++;
@@ -149,6 +167,8 @@
 	 */
 
 	if (dev != VLAN_DEV_INFO(skb->dev)->real_dev) {
+		spin_unlock_bh(&vlan_group_lock);
+
 #ifdef VLAN_DEBUG
 		printk(VLAN_DBG __FUNCTION__ ": dropping skb: %p because came in on wrong device, dev: %s  real_dev: %s, skb_dev: %s\n",
 		       skb, dev->name, VLAN_DEV_INFO(skb->dev)->real_dev->name, skb->dev->name);
@@ -161,7 +181,7 @@
 	/*
 	 * Deal with ingress priority mapping.
 	 */
-	skb->priority = VLAN_DEV_INFO(skb->dev)->ingress_priority_map[(ntohs(vhdr->h_vlan_TCI) >> 13) & 0x7];
+	skb->priority = vlan_get_ingress_priority(skb->dev, ntohs(vhdr->h_vlan_TCI));
 
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG __FUNCTION__ ": priority: %lu  for TCI: %hu (hbo)\n",
@@ -174,9 +194,12 @@
 	switch (skb->pkt_type) {
 	case PACKET_BROADCAST: /* Yeah, stats collect these together.. */
 		// stats->broadcast ++; // no such counter :-(
+		break;
+
 	case PACKET_MULTICAST:
 		stats->multicast++;
 		break;
+
 	case PACKET_OTHERHOST: 
 		/* Our lower layer thinks this is not local, let's make sure.
 		 * This allows the VLAN to have a different MAC than the underlying
@@ -215,6 +238,7 @@
 			/* TODO:  Add a more specific counter here. */
 			stats->rx_errors++;
 		}
+		spin_unlock_bh(&vlan_group_lock);
 		return 0;
 	}
 
@@ -243,6 +267,7 @@
 			/* TODO:  Add a more specific counter here. */
 			stats->rx_errors++;
 		}
+		spin_unlock_bh(&vlan_group_lock);
 		return 0;
 	}
 
@@ -265,6 +290,24 @@
 		/* TODO:  Add a more specific counter here. */
 		stats->rx_errors++;
 	}
+	spin_unlock_bh(&vlan_group_lock);
+	return 0;
+}
+
+static inline unsigned short vlan_dev_get_egress_qos_mask(struct net_device* dev,
+							  struct sk_buff* skb)
+{
+	struct vlan_priority_tci_mapping *mp =
+		VLAN_DEV_INFO(dev)->egress_priority_map[(skb->priority & 0xF)];
+
+	while (mp) {
+		if (mp->priority == skb->priority) {
+			return mp->vlan_qos; /* This should already be shifted to mask
+					      * correctly with the VLAN's TCI
+					      */
+		}
+		mp = mp->next;
+	}
 	return 0;
 }
 
@@ -396,8 +439,9 @@
 	 */
 
 	if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) {
+		unsigned short veth_TCI;
+
 		/* This is not a VLAN frame...but we can fix that! */
-		unsigned short veth_TCI = 0;
 		VLAN_DEV_INFO(dev)->cnt_encap_on_xmit++;
 
 #ifdef VLAN_DEBUG
@@ -453,65 +497,44 @@
 	       veth->h_vlan_proto, veth->h_vlan_TCI, veth->h_vlan_encapsulated_proto);
 #endif
 
-	dev_queue_xmit(skb);
 	stats->tx_packets++; /* for statics only */
 	stats->tx_bytes += skb->len;
-	return 0;
-}
 
-int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
-{
-	/* TODO: gotta make sure the underlying layer can handle it,
-	 * maybe an IFF_VLAN_CAPABLE flag for devices?
-	 */
-	if (VLAN_DEV_INFO(dev)->real_dev->mtu < new_mtu)
-		return -ERANGE;
-
-	dev->mtu = new_mtu;
+	dev_queue_xmit(skb);
 
-	return new_mtu;
+	return 0;
 }
 
-int vlan_dev_open(struct net_device *dev)
+int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_UP))
-		return -ENETDOWN;
+	struct net_device_stats *stats = vlan_dev_get_stats(dev);
+	struct vlan_skb_tx_cookie *cookie;
 
-	return 0;
-}
+	stats->tx_packets++;
+	stats->tx_bytes += skb->len;
 
-int vlan_dev_stop(struct net_device *dev)
-{
-	vlan_flush_mc_list(dev);
-	return 0;
-}
+	skb->dev = VLAN_DEV_INFO(dev)->real_dev;
+	cookie = VLAN_TX_SKB_CB(skb);
+	cookie->magic = VLAN_TX_COOKIE_MAGIC;
+	cookie->vlan_tag = (VLAN_DEV_INFO(dev)->vlan_id |
+			    vlan_dev_get_egress_qos_mask(dev, skb));
+
+	dev_queue_xmit(skb);
 
-int vlan_dev_init(struct net_device *dev)
-{
-	/* TODO:  figure this out, maybe do nothing?? */
 	return 0;
 }
 
-void vlan_dev_destruct(struct net_device *dev)
+int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if (dev) {
-		vlan_flush_mc_list(dev);
-		if (dev->priv) {
-			dev_put(VLAN_DEV_INFO(dev)->real_dev);
-			if (VLAN_DEV_INFO(dev)->dent) {
-				printk(KERN_ERR __FUNCTION__ ": dent is NOT NULL!\n");
-
-				/* If we ever get here, there is a serious bug
-				 * that must be fixed.
-				 */
-			}
+	/* TODO: gotta make sure the underlying layer can handle it,
+	 * maybe an IFF_VLAN_CAPABLE flag for devices?
+	 */
+	if (VLAN_DEV_INFO(dev)->real_dev->mtu < new_mtu)
+		return -ERANGE;
 
-			kfree(dev->priv);
+	dev->mtu = new_mtu;
 
-			VLAN_FMEM_DBG("dev->priv free, addr: %p\n", dev->priv);
-			dev->priv = NULL;
-		}
-	}
+	return new_mtu;
 }
 
 int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
@@ -642,6 +665,124 @@
 	return 0;
 }
 
+static inline int vlan_dmi_equals(struct dev_mc_list *dmi1,
+                                  struct dev_mc_list *dmi2)
+{
+	return ((dmi1->dmi_addrlen == dmi2->dmi_addrlen) &&
+		(memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0));
+}
+
+/** dmi is a single entry into a dev_mc_list, a single node.  mc_list is
+ *  an entire list, and we'll iterate through it.
+ */
+static int vlan_should_add_mc(struct dev_mc_list *dmi, struct dev_mc_list *mc_list)
+{
+	struct dev_mc_list *idmi;
+
+	for (idmi = mc_list; idmi != NULL; ) {
+		if (vlan_dmi_equals(dmi, idmi)) {
+			if (dmi->dmi_users > idmi->dmi_users)
+				return 1;
+			else
+				return 0;
+		} else {
+			idmi = idmi->next;
+		}
+	}
+
+	return 1;
+}
+
+static inline void vlan_destroy_mc_list(struct dev_mc_list *mc_list)
+{
+	struct dev_mc_list *dmi = mc_list;
+	struct dev_mc_list *next;
+
+	while(dmi) {
+		next = dmi->next;
+		kfree(dmi);
+		dmi = next;
+	}
+}
+
+static void vlan_copy_mc_list(struct dev_mc_list *mc_list, struct vlan_dev_info *vlan_info)
+{
+	struct dev_mc_list *dmi, *new_dmi;
+
+	vlan_destroy_mc_list(vlan_info->old_mc_list);
+	vlan_info->old_mc_list = NULL;
+
+	for (dmi = mc_list; dmi != NULL; dmi = dmi->next) {
+		new_dmi = kmalloc(sizeof(*new_dmi), GFP_ATOMIC);
+		if (new_dmi == NULL) {
+			printk(KERN_ERR "vlan: cannot allocate memory. "
+			       "Multicast may not work properly from now.\n");
+			return;
+		}
+
+		/* Copy whole structure, then make new 'next' pointer */
+		*new_dmi = *dmi;
+		new_dmi->next = vlan_info->old_mc_list;
+		vlan_info->old_mc_list = new_dmi;
+	}
+}
+
+static void vlan_flush_mc_list(struct net_device *dev)
+{
+	struct dev_mc_list *dmi = dev->mc_list;
+
+	while (dmi) {
+		dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+		printk(KERN_INFO "%s: del %.2x:%.2x:%.2x:%.2x:%.2x:%.2x mcast address from vlan interface\n",
+		       dev->name,
+		       dmi->dmi_addr[0],
+		       dmi->dmi_addr[1],
+		       dmi->dmi_addr[2],
+		       dmi->dmi_addr[3],
+		       dmi->dmi_addr[4],
+		       dmi->dmi_addr[5]);
+		dmi = dev->mc_list;
+	}
+
+	/* dev->mc_list is NULL by the time we get here. */
+	vlan_destroy_mc_list(VLAN_DEV_INFO(dev)->old_mc_list);
+	VLAN_DEV_INFO(dev)->old_mc_list = NULL;
+}
+
+int vlan_dev_open(struct net_device *dev)
+{
+	if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_UP))
+		return -ENETDOWN;
+
+	return 0;
+}
+
+int vlan_dev_stop(struct net_device *dev)
+{
+	vlan_flush_mc_list(dev);
+	return 0;
+}
+
+int vlan_dev_init(struct net_device *dev)
+{
+	/* TODO:  figure this out, maybe do nothing?? */
+	return 0;
+}
+
+void vlan_dev_destruct(struct net_device *dev)
+{
+	if (dev) {
+		vlan_flush_mc_list(dev);
+		if (dev->priv) {
+			if (VLAN_DEV_INFO(dev)->dent)
+				BUG();
+
+			kfree(dev->priv);
+			dev->priv = NULL;
+		}
+	}
+}
+
 /** Taken from Gleb + Lennert's VLAN code, and modified... */
 void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
 {
@@ -707,68 +848,3 @@
 		vlan_copy_mc_list(vlan_dev->mc_list, VLAN_DEV_INFO(vlan_dev));
 	}
 }
-
-/** dmi is a single entry into a dev_mc_list, a single node.  mc_list is
- *  an entire list, and we'll iterate through it.
- */
-int vlan_should_add_mc(struct dev_mc_list *dmi, struct dev_mc_list *mc_list)
-{
-	struct dev_mc_list *idmi;
-
-	for (idmi = mc_list; idmi != NULL; ) {
-		if (vlan_dmi_equals(dmi, idmi)) {
-			if (dmi->dmi_users > idmi->dmi_users)
-				return 1;
-			else
-				return 0;
-		} else {
-			idmi = idmi->next;
-		}
-	}
-
-	return 1;
-}
-
-void vlan_copy_mc_list(struct dev_mc_list *mc_list, struct vlan_dev_info *vlan_info)
-{
-	struct dev_mc_list *dmi, *new_dmi;
-
-	vlan_destroy_mc_list(vlan_info->old_mc_list);
-	vlan_info->old_mc_list = NULL;
-
-	for (dmi = mc_list; dmi != NULL; dmi = dmi->next) {
-		new_dmi = kmalloc(sizeof(*new_dmi), GFP_ATOMIC);
-		if (new_dmi == NULL) {
-			printk(KERN_ERR "vlan: cannot allocate memory. "
-			       "Multicast may not work properly from now.\n");
-			return;
-		}
-
-		/* Copy whole structure, then make new 'next' pointer */
-		*new_dmi = *dmi;
-		new_dmi->next = vlan_info->old_mc_list;
-		vlan_info->old_mc_list = new_dmi;
-	}
-}
-
-void vlan_flush_mc_list(struct net_device *dev)
-{
-	struct dev_mc_list *dmi = dev->mc_list;
-
-	while (dmi) {
-		dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
-		printk(KERN_INFO "%s: del %.2x:%.2x:%.2x:%.2x:%.2x:%.2x mcast address from vlan interface\n",
-		       dev->name,
-		       dmi->dmi_addr[0],
-		       dmi->dmi_addr[1],
-		       dmi->dmi_addr[2],
-		       dmi->dmi_addr[3],
-		       dmi->dmi_addr[4],
-		       dmi->dmi_addr[5]);
-		dmi = dev->mc_list;
-	}
-
-	/* dev->mc_list is NULL by the time we get here. */
-	vlan_destroy_mc_list(VLAN_DEV_INFO(dev)->old_mc_list);
-	VLAN_DEV_INFO(dev)->old_mc_list = NULL;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/8021q/vlanproc.c linux/net/8021q/vlanproc.c
--- linux.orig/net/8021q/vlanproc.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/8021q/vlanproc.c	2002-07-20 01:08:32.000000000 +0000
@@ -273,7 +273,7 @@
 {
 	struct net_device *vlandev = NULL;
 	struct vlan_group *grp = NULL;
-	int i = 0;
+	int h, i;
 	char *nm_type = NULL;
 	struct vlan_dev_info *dev_info = NULL;
 
@@ -293,46 +293,34 @@
 		nm_type = "UNKNOWN";
 	}
 
-	cnt += sprintf(buf + cnt, "Name-Type: %s  bad_proto_recvd: %lu\n",
-		       nm_type, vlan_bad_proto_recvd);
+	cnt += sprintf(buf + cnt, "Name-Type: %s\n", nm_type);
 
-	for (grp = p802_1Q_vlan_list; grp != NULL; grp = grp->next) {
-		/* loop through all devices for this device */
-#ifdef VLAN_DEBUG
-		printk(VLAN_DBG __FUNCTION__ ": found a group, addr: %p\n",grp);
-#endif
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
-			vlandev = grp->vlan_devices[i];
-			if (!vlandev)
-				continue;
-#ifdef VLAN_DEBUG
-			printk(VLAN_DBG __FUNCTION__
-			       ": found a vlan_dev, addr: %p\n", vlandev);
-#endif
-			if ((cnt + 100) > VLAN_PROC_BUFSZ) {
-				if ((cnt+strlen(term_msg)) < VLAN_PROC_BUFSZ)
-					cnt += sprintf(buf+cnt, "%s", term_msg);
-
-				return cnt;
-			}
-			if (!vlandev->priv) {
-				printk(KERN_ERR __FUNCTION__
-				       ": ERROR: vlandev->priv is NULL\n");
-				continue;
-			}
+	spin_lock_bh(&vlan_group_lock);
+	for (h = 0; h < VLAN_GRP_HASH_SIZE; h++) {
+		for (grp = vlan_group_hash[h]; grp != NULL; grp = grp->next) {
+			for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+				vlandev = grp->vlan_devices[i];
+				if (!vlandev)
+					continue;
+
+				if ((cnt + 100) > VLAN_PROC_BUFSZ) {
+					if ((cnt+strlen(term_msg)) < VLAN_PROC_BUFSZ)
+						cnt += sprintf(buf+cnt, "%s", term_msg);
 
-			dev_info = VLAN_DEV_INFO(vlandev);
+					goto out;
+				}
 
-#ifdef VLAN_DEBUG
-			printk(VLAN_DBG __FUNCTION__
-			       ": got a good vlandev, addr: %p\n",
-			       VLAN_DEV_INFO(vlandev));
-#endif
-			cnt += sprintf(buf + cnt, "%-15s| %d  | %s\n",
-				       vlandev->name, dev_info->vlan_id,
-				       dev_info->real_dev->name);
+				dev_info = VLAN_DEV_INFO(vlandev);
+				cnt += sprintf(buf + cnt, "%-15s| %d  | %s\n",
+					       vlandev->name,
+					       dev_info->vlan_id,
+					       dev_info->real_dev->name);
+			}
 		}
 	}
+out:
+	spin_unlock_bh(&vlan_group_lock);
+
 	return cnt;
 }
 
@@ -366,11 +354,7 @@
 	int cnt = 0;
 	int i;
 
-#ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": vlandev: %p\n", vlandev);
-#endif
-
-	if ((vlandev == NULL) || (!vlandev->priv_flags & IFF_802_1Q_VLAN))
+	if ((vlandev == NULL) || (!(vlandev->priv_flags & IFF_802_1Q_VLAN)))
 		return 0;
 
 	dev_info = VLAN_DEV_INFO(vlandev);
@@ -427,7 +411,7 @@
 
 	cnt += sprintf(buf + cnt, "EGRESSS priority Mappings: ");
 
-	for (i = 0; i<16; i++) {
+	for (i = 0; i < 16; i++) {
 		mp = dev_info->egress_priority_map[i];
 		while (mp) {
 			cnt += sprintf(buf + cnt, "%lu:%hu ",
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/Config.in linux/net/Config.in
--- linux.orig/net/Config.in	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/Config.in	2002-07-20 01:08:28.000000000 +0000
@@ -43,18 +43,23 @@
       if [ "$CONFIG_INET" = "y" -a "$CONFIG_ATM_LANE" != "n" ]; then
 	 tristate '    Multi-Protocol Over ATM (MPOA) support' CONFIG_ATM_MPOA
       fi
+      tristate '  RFC1483/2684 Bridged protocols' CONFIG_ATM_BR2684
+      if [ "$CONFIG_ATM_BR2684" != "n" ]; then
+            bool '    Per-VC IP filter kludge' CONFIG_ATM_BR2684_IPFILTER
+      fi
    fi
-
-   dep_tristate '802.1Q VLAN Support (EXPERIMENTAL)' CONFIG_VLAN_8021Q $CONFIG_EXPERIMENTAL
-
 fi
+tristate '802.1Q VLAN Support' CONFIG_VLAN_8021Q
 
 comment ' '
 tristate 'The IPX protocol' CONFIG_IPX
 if [ "$CONFIG_IPX" != "n" ]; then
    source net/ipx/Config.in
 fi
+
 tristate 'Appletalk protocol support' CONFIG_ATALK
+source drivers/net/appletalk/Config.in
+
 tristate 'DECnet Support' CONFIG_DECNET
 if [ "$CONFIG_DECNET" != "n" ]; then
    source net/decnet/Config.in
@@ -70,10 +75,10 @@
 #   fi
    if [ "$CONFIG_INET" = "y" ]; then
       tristate 'Acorn Econet/AUN protocols (EXPERIMENTAL)' CONFIG_ECONET
-   fi
-   if [ "$CONFIG_ECONET" != "n" ]; then
-      bool '  AUN over UDP' CONFIG_ECONET_AUNUDP
-      bool '  Native Econet' CONFIG_ECONET_NATIVE
+      if [ "$CONFIG_ECONET" != "n" ]; then
+	 bool '  AUN over UDP' CONFIG_ECONET_AUNUDP
+	 bool '  Native Econet' CONFIG_ECONET_NATIVE
+      fi
    fi
    tristate 'WAN router' CONFIG_WAN_ROUTER
    bool 'Fast switching (read help!)' CONFIG_NET_FASTROUTE
@@ -89,4 +94,9 @@
 #bool 'Network code profiler' CONFIG_NET_PROFILE
 endmenu
 
+mainmenu_option next_comment
+comment 'Network testing'
+tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN
+endmenu
+
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/Makefile linux/net/Makefile
--- linux.orig/net/Makefile	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/Makefile	2002-07-20 01:08:34.000000000 +0000
@@ -7,7 +7,7 @@
 
 O_TARGET :=	network.o
 
-mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched
+mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core
 export-objs :=	netsyms.o
 
 subdir-y :=	core ethernet
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/atm/Makefile linux/net/atm/Makefile
--- linux.orig/net/atm/Makefile	2001-11-09 22:11:15.000000000 +0000
+++ linux/net/atm/Makefile	2002-07-20 01:08:26.000000000 +0000
@@ -21,6 +21,15 @@
 NEED_IPCOM = ipcommon.o
 endif
 
+ifeq ($(CONFIG_ATM_BR2684),y)
+  NEED_IPCOM = ipcommon.o
+else
+  ifeq ($(CONFIG_ATM_BR2684),m)
+	NEED_IPCOM = ipcommon.o
+  endif
+endif
+obj-$(CONFIG_ATM_BR2684) += br2684.o
+
 ifeq ($(CONFIG_NET_SCH_ATM),y)
 NEED_IPCOM = ipcommon.o
 endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/atm/br2684.c linux/net/atm/br2684.c
--- linux.orig/net/atm/br2684.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/atm/br2684.c	2002-07-20 01:08:37.000000000 +0000
@@ -0,0 +1,804 @@
+/*
+Experimental ethernet netdevice using ATM AAL5 as underlying carrier
+(RFC1483 obsoleted by RFC2684) for Linux 2.4
+Author: Marcell GAL, 2000, XDSL Ltd, Hungary
+*/
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/ip.h>
+#include <asm/uaccess.h>
+#include <net/arp.h>
+
+#include <linux/atmbr2684.h>
+
+#include "ipcommon.h"
+
+/*
+ * Define this to use a version of the code which interacts with the higher
+ * layers in a more intellegent way, by always reserving enough space for
+ * our header at the begining of the packet.  However, there may still be
+ * some problems with programs like tcpdump.  In 2.5 we'll sort out what
+ * we need to do to get this perfect.  For now we just will copy the packet
+ * if we need space for the header
+ */
+/* #define FASTER_VERSION */
+
+#ifdef DEBUG
+#define DPRINTK(format, args...) printk(KERN_DEBUG "br2684: " format, ##args)
+#else
+#define DPRINTK(format, args...)
+#endif
+
+#ifdef SKB_DEBUG
+static void skb_debug(const struct sk_buff *skb)
+{
+#define NUM2PRINT 50
+	char buf[NUM2PRINT * 3 + 1];	/* 3 chars per byte */
+	int i = 0;
+	for (i = 0; i < skb->len && i < NUM2PRINT; i++) {
+		sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+	}
+	printk(KERN_DEBUG "br2684: skb: %s\n", buf);
+}
+#else
+#define skb_debug(skb)	do {} while (0)
+#endif
+
+static unsigned char llc_oui_pid_pad[] =
+    { 0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00 };
+#define PADLEN	(2)
+
+enum br2684_encaps {
+	e_vc  = BR2684_ENCAPS_VC,
+	e_llc = BR2684_ENCAPS_LLC,
+};
+
+struct br2684_vcc {
+	struct atm_vcc  *atmvcc;
+	struct br2684_dev *brdev;
+	/* keep old push,pop functions for chaining */
+	void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb);
+	/* void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); */
+	enum br2684_encaps encaps;
+	struct list_head brvccs;
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+	struct br2684_filter filter;
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+#ifndef FASTER_VERSION
+	unsigned copies_needed, copies_failed;
+#endif /* FASTER_VERSION */
+};
+
+struct br2684_dev {
+	struct net_device net_dev;
+	struct list_head br2684_devs;
+	int number;
+	struct list_head brvccs; /* one device <=> one vcc (before xmas) */
+	struct net_device_stats stats;
+	int mac_was_set;
+};
+
+/*
+ * This lock should be held for writing any time the list of devices or
+ * their attached vcc's could be altered.  It should be held for reading
+ * any time these are being queried.  Note that we sometimes need to
+ * do read-locking under interrupt context, so write locking must block
+ * the current CPU's interrupts
+ */
+static rwlock_t devs_lock = RW_LOCK_UNLOCKED;
+
+static LIST_HEAD(br2684_devs);
+
+static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev)
+{
+	return (struct br2684_dev *) ((char *) (net_dev) -
+	    (unsigned long) (&((struct br2684_dev *) 0)->net_dev));
+}
+
+static inline struct br2684_dev *list_entry_brdev(const struct list_head *le)
+{
+	return list_entry(le, struct br2684_dev, br2684_devs);
+}
+
+static inline struct br2684_vcc *BR2684_VCC(const struct atm_vcc *atmvcc)
+{
+	return (struct br2684_vcc *) (atmvcc->user_back);
+}
+
+static inline struct br2684_vcc *list_entry_brvcc(const struct list_head *le)
+{
+	return list_entry(le, struct br2684_vcc, brvccs);
+}
+
+/* Caller should hold read_lock(&devs_lock) */
+static struct br2684_dev *br2684_find_dev(const struct br2684_if_spec *s)
+{
+	struct list_head *lh;
+	struct br2684_dev *brdev;
+	switch (s->method) {
+	case BR2684_FIND_BYNUM:
+		list_for_each(lh, &br2684_devs) {
+			brdev = list_entry_brdev(lh);
+			if (brdev->number == s->spec.devnum)
+				return brdev;
+		}
+		break;
+	case BR2684_FIND_BYIFNAME:
+		list_for_each(lh, &br2684_devs) {
+			brdev = list_entry_brdev(lh);
+			if (!strncmp(brdev->net_dev.name, s->spec.ifname,
+			    sizeof brdev->net_dev.name))
+				return brdev;
+		}
+		break;
+	}
+	return NULL;
+}
+
+/*
+ * Send a packet out a particular vcc.  Not to useful right now, but paves
+ * the way for multiple vcc's per itf.  Returns true if we can send,
+ * otherwise false
+ */
+static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
+	struct br2684_vcc *brvcc)
+{
+	struct atm_vcc *atmvcc;
+#ifdef FASTER_VERSION
+	if (brvcc->encaps == e_llc)
+		memcpy(skb_push(skb, 8), llc_oui_pid_pad, 8);
+	/* last 2 bytes of llc_oui_pid_pad are managed by header routines;
+	   yes, you got it: 8 + 2 = sizeof(llc_oui_pid_pad)
+	 */
+#else
+	int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
+	if (skb_headroom(skb) < minheadroom) {
+		struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
+		brvcc->copies_needed++;
+		dev_kfree_skb(skb);
+		if (skb2 == NULL) {
+			brvcc->copies_failed++;
+			return 0;
+		}
+		skb = skb2;
+	}
+	skb_push(skb, minheadroom);
+	if (brvcc->encaps == e_llc)
+		memcpy(skb->data, llc_oui_pid_pad, 10);
+	else
+		memset(skb->data, 0, 2);
+#endif /* FASTER_VERSION */
+	skb_debug(skb);
+
+	ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
+	DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
+	if (!atm_may_send(atmvcc, skb->truesize)) {
+		/* we free this here for now, because we cannot know in a higher 
+			layer whether the skb point it supplied wasn't freed yet.
+			now, it always is.
+		*/
+		dev_kfree_skb(skb);
+		return 0;
+		}
+	atomic_add(skb->truesize, &atmvcc->tx_inuse);
+	ATM_SKB(skb)->iovcnt = 0;
+	ATM_SKB(skb)->atm_options = atmvcc->atm_options;
+	brdev->stats.tx_packets++;
+	brdev->stats.tx_bytes += skb->len;
+	atmvcc->send(atmvcc, skb);
+	return 1;
+}
+
+static inline struct br2684_vcc *pick_outgoing_vcc(struct sk_buff *skb,
+	struct br2684_dev *brdev)
+{
+	return list_empty(&brdev->brvccs) ? NULL :
+	    list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */
+}
+
+static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct br2684_dev *brdev = BRPRIV(dev);
+	struct br2684_vcc *brvcc;
+
+	DPRINTK("br2684_start_xmit, skb->dst=%p\n", skb->dst);
+	read_lock(&devs_lock);
+	brvcc = pick_outgoing_vcc(skb, brdev);
+	if (brvcc == NULL) {
+		DPRINTK("no vcc attached to dev %s\n", dev->name);
+		brdev->stats.tx_errors++;
+		brdev->stats.tx_carrier_errors++;
+		/* netif_stop_queue(dev); */
+		dev_kfree_skb(skb);
+		read_unlock(&devs_lock);
+		return -EUNATCH;
+	}
+	if (!br2684_xmit_vcc(skb, brdev, brvcc)) {
+		/*
+		 * We should probably use netif_*_queue() here, but that
+		 * involves added complication.  We need to walk before
+		 * we can run
+		 */
+		/* don't free here! this pointer might be no longer valid!
+		dev_kfree_skb(skb);
+		*/
+		brdev->stats.tx_errors++;
+		brdev->stats.tx_fifo_errors++;
+	}
+	read_unlock(&devs_lock);
+	return 0;
+}
+
+static struct net_device_stats *br2684_get_stats(struct net_device *dev)
+{
+	DPRINTK("br2684_get_stats\n");
+	return &BRPRIV(dev)->stats;
+}
+
+#ifdef FASTER_VERSION
+/*
+ * These mirror eth_header and eth_header_cache.  They are not usually
+ * exported for use in modules, so we grab them from net_device
+ * after ether_setup() is done with it.  Bit of a hack.
+ */
+static int (*my_eth_header)(struct sk_buff *, struct net_device *,
+	unsigned short, void *, void *, unsigned);
+static int (*my_eth_header_cache)(struct neighbour *, struct hh_cache *);
+
+static int
+br2684_header(struct sk_buff *skb, struct net_device *dev,
+	      unsigned short type, void *daddr, void *saddr, unsigned len)
+{
+	u16 *pad_before_eth;
+	int t = my_eth_header(skb, dev, type, daddr, saddr, len);
+	if (t > 0) {
+		pad_before_eth = (u16 *) skb_push(skb, 2);
+		*pad_before_eth = 0;
+		return dev->hard_header_len;	/* or return 16; ? */
+	} else
+		return t;
+}
+
+static int
+br2684_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+{
+/* hh_data is 16 bytes long. if encaps is ether-llc we need 24, so
+xmit will add the additional header part in that case */
+	u16 *pad_before_eth = (u16 *)(hh->hh_data);
+	int t = my_eth_header_cache(neigh, hh);
+	DPRINTK("br2684_header_cache, neigh=%p, hh_cache=%p\n", neigh, hh);
+	if (t < 0)
+		return t;
+	else {
+		*pad_before_eth = 0;
+		hh->hh_len = PADLEN + ETH_HLEN;
+	}
+	return 0;
+}
+
+/*
+ * This is similar to eth_type_trans, which cannot be used because of
+ * our dev->hard_header_len
+ */
+static inline unsigned short br_type_trans(struct sk_buff *skb,
+					       struct net_device *dev)
+{
+	struct ethhdr *eth;
+	unsigned char *rawp;
+	eth = skb->mac.ethernet;
+
+	if (*eth->h_dest & 1) {
+		if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0)
+			skb->pkt_type = PACKET_BROADCAST;
+		else
+			skb->pkt_type = PACKET_MULTICAST;
+	}
+
+	else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN))
+		skb->pkt_type = PACKET_OTHERHOST;
+
+	if (ntohs(eth->h_proto) >= 1536)
+		return eth->h_proto;
+
+	rawp = skb->data;
+
+	/*
+	 * This is a magic hack to spot IPX packets. Older Novell breaks
+	 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
+	 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
+	 * won't work for fault tolerant netware but does for the rest.
+	 */
+	if (*(unsigned short *) rawp == 0xFFFF)
+		return htons(ETH_P_802_3);
+
+	/*
+	 * Real 802.2 LLC
+	 */
+	return htons(ETH_P_802_2);
+}
+#endif /* FASTER_VERSION */
+
+/*
+ * We remember when the MAC gets set, so we don't override it later with
+ * the ESI of the ATM card of the first VC
+ */
+static int (*my_eth_mac_addr)(struct net_device *, void *);
+static int br2684_mac_addr(struct net_device *dev, void *p)
+{
+	int err = my_eth_mac_addr(dev, p);
+	if (!err)
+		BRPRIV(dev)->mac_was_set = 1;
+	return err;
+}
+
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+/* this IOCTL is experimental. */
+static int br2684_setfilt(struct atm_vcc *atmvcc, unsigned long arg)
+{
+	struct br2684_vcc *brvcc;
+	struct br2684_filter_set fs;
+
+	if (copy_from_user(&fs, (void *) arg, sizeof fs))
+		return -EFAULT;
+	if (fs.ifspec.method != BR2684_FIND_BYNOTHING) {
+		/*
+		 * This is really a per-vcc thing, but we can also search
+		 * by device
+		 */
+		struct br2684_dev *brdev;
+		read_lock(&devs_lock);
+		brdev = br2684_find_dev(&fs.ifspec);
+		if (brdev == NULL || list_empty(&brdev->brvccs) ||
+		    brdev->brvccs.next != brdev->brvccs.prev)  /* >1 VCC */
+			brvcc = NULL;
+		else
+			brvcc = list_entry_brvcc(brdev->brvccs.next);
+		read_unlock(&devs_lock);
+		if (brvcc == NULL)
+			return -ESRCH;
+	} else
+		brvcc = BR2684_VCC(atmvcc);
+	memcpy(&brvcc->filter, &fs.filter, sizeof(brvcc->filter));
+	return 0;
+}
+
+/* Returns 1 if packet should be dropped */
+static inline int
+packet_fails_filter(u16 type, struct br2684_vcc *brvcc, struct sk_buff *skb)
+{
+	if (brvcc->filter.netmask == 0)
+		return 0;			/* no filter in place */
+	if (type == __constant_htons(ETH_P_IP) &&
+	    (((struct iphdr *) (skb->data))->daddr & brvcc->filter.
+	     netmask) == brvcc->filter.prefix)
+		return 0;
+	if (type == __constant_htons(ETH_P_ARP))
+		return 0;
+	/* TODO: we should probably filter ARPs too.. don't want to have
+	 *   them returning values that don't make sense, or is that ok?
+	 */
+	return 1;		/* drop */
+}
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+
+static void br2684_close_vcc(struct br2684_vcc *brvcc)
+{
+	DPRINTK("removing VCC %p from dev %p\n", brvcc, brvcc->brdev);
+	write_lock_irq(&devs_lock);
+	list_del(&brvcc->brvccs);
+	write_unlock_irq(&devs_lock);
+	brvcc->atmvcc->user_back = NULL;	/* what about vcc->recvq ??? */
+	brvcc->old_push(brvcc->atmvcc, NULL);	/* pass on the bad news */
+	kfree(brvcc);
+	MOD_DEC_USE_COUNT;
+}
+
+/* when AAL5 PDU comes in: */
+static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
+{
+	struct br2684_vcc *brvcc = BR2684_VCC(atmvcc);
+	struct br2684_dev *brdev = brvcc->brdev;
+	int plen = sizeof(llc_oui_pid_pad) + ETH_HLEN;
+
+	DPRINTK("br2684_push\n");
+
+	if (skb == NULL) {	/* skb==NULL means VCC is being destroyed */
+		br2684_close_vcc(brvcc);
+		if (list_empty(&brdev->brvccs)) {
+			read_lock(&devs_lock);
+			list_del(&brdev->br2684_devs);
+			read_unlock(&devs_lock);
+			unregister_netdev(&brdev->net_dev);
+			kfree(brdev);
+		}
+		return;
+	}
+
+	skb_debug(skb);
+	atm_return(atmvcc, skb->truesize);
+	DPRINTK("skb from brdev %p\n", brdev);
+	if (brvcc->encaps == e_llc) {
+		/* let us waste some time for checking the encapsulation.
+		   Note, that only 7 char is checked so frames with a valid FCS
+		   are also accepted (but FCS is not checked of course) */
+		if (memcmp(skb->data, llc_oui_pid_pad, 7)) {
+			brdev->stats.rx_errors++;
+			dev_kfree_skb(skb);
+			return;
+		}
+	} else {
+		plen = PADLEN + ETH_HLEN;	/* pad, dstmac,srcmac, ethtype */
+		/* first 2 chars should be 0 */
+		if (*((u16 *) (skb->data)) != 0) {
+			brdev->stats.rx_errors++;
+			dev_kfree_skb(skb);
+			return;
+		}
+	}
+	if (skb->len < plen) {
+		brdev->stats.rx_errors++;
+		dev_kfree_skb(skb);	/* dev_ not needed? */
+		return;
+	}
+
+#ifdef FASTER_VERSION
+	/* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier,
+	   than should be. What else should I set? */
+	skb_pull(skb, plen);
+	skb->mac.raw = ((char *) (skb->data)) - ETH_HLEN;
+	skb->pkt_type = PACKET_HOST;
+#ifdef CONFIG_BR2684_FAST_TRANS
+	skb->protocol = ((u16 *) skb->data)[-1];
+#else				/* some protocols might require this: */
+	skb->protocol = br_type_trans(skb, &brdev->net_dev);
+#endif /* CONFIG_BR2684_FAST_TRANS */
+#else
+	skb_pull(skb, plen - ETH_HLEN);
+	skb->protocol = eth_type_trans(skb, &brdev->net_dev);
+#endif /* FASTER_VERSION */
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+	if (packet_fails_filter(skb->protocol, brvcc, skb)) {
+		brdev->stats.rx_dropped++;
+		dev_kfree_skb(skb);
+		return;
+	}
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+	skb->dev = &brdev->net_dev;
+	ATM_SKB(skb)->vcc = atmvcc;	/* needed ? */
+	DPRINTK("received packet's protocol: %x\n", ntohs(skb->protocol));
+	skb_debug(skb);
+	if (!(brdev->net_dev.flags & IFF_UP)) { /* sigh, interface is down */
+		brdev->stats.rx_dropped++;
+		dev_kfree_skb(skb);
+		return;
+	}
+	brdev->stats.rx_packets++;
+	brdev->stats.rx_bytes += skb->len;
+	netif_rx(skb);
+}
+
+static int br2684_regvcc(struct atm_vcc *atmvcc, unsigned long arg)
+{
+/* assign a vcc to a dev
+Note: we do not have explicit unassign, but look at _push()
+*/
+	int err;
+	struct br2684_vcc *brvcc;
+	struct sk_buff_head copy;
+	struct sk_buff *skb;
+	struct br2684_dev *brdev;
+	struct atm_backend_br2684 be;
+
+	MOD_INC_USE_COUNT;
+	if (copy_from_user(&be, (void *) arg, sizeof be)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+	write_lock_irq(&devs_lock);
+	brdev = br2684_find_dev(&be.ifspec);
+	if (brdev == NULL) {
+		printk(KERN_ERR
+		    "br2684: tried to attach to non-existant device\n");
+		err = -ENXIO;
+		goto error;
+	}
+	if (atmvcc->push == NULL) {
+		err = -EBADFD;
+		goto error;
+	}
+	if (!list_empty(&brdev->brvccs)) {	/* Only 1 VCC/dev right now */
+		err = -EEXIST;
+		goto error;
+	}
+	if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO ||
+	    be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps !=
+	    BR2684_ENCAPS_VC && be.encaps != BR2684_ENCAPS_LLC) ||
+	    be.min_size != 0) {
+		err = -EINVAL;
+		goto error;
+	}
+	brvcc = kmalloc(sizeof(struct br2684_vcc), GFP_KERNEL);
+	if (!brvcc) {
+		err = -ENOMEM;
+		goto error;
+	}
+	memset(brvcc, 0, sizeof(struct br2684_vcc));
+	DPRINTK("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, be.encaps,
+		brvcc);
+	if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) {
+		unsigned char *esi = atmvcc->dev->esi;
+		if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5])
+			memcpy(brdev->net_dev.dev_addr, esi,
+			    brdev->net_dev.addr_len);
+		else
+			brdev->net_dev.dev_addr[2] = 1;
+	}
+	list_add(&brvcc->brvccs, &brdev->brvccs);
+	write_unlock_irq(&devs_lock);
+	brvcc->brdev = brdev;
+	brvcc->atmvcc = atmvcc;
+	atmvcc->user_back = brvcc;
+	brvcc->encaps = (enum br2684_encaps) be.encaps;
+	brvcc->old_push = atmvcc->push;
+	barrier();
+	atmvcc->push = br2684_push;
+	skb_queue_head_init(&copy);
+	skb_migrate(&atmvcc->recvq, &copy);
+	while ((skb = skb_dequeue(&copy))) {
+		BRPRIV(skb->dev)->stats.rx_bytes -= skb->len;
+		BRPRIV(skb->dev)->stats.rx_packets--;
+		br2684_push(atmvcc, skb);
+	}
+	return 0;
+    error:
+	write_unlock_irq(&devs_lock);
+	MOD_DEC_USE_COUNT;
+	return err;
+}
+
+static int br2684_create(unsigned long arg)
+{
+	int err;
+	struct br2684_dev *brdev;
+	struct atm_newif_br2684 ni;
+
+	DPRINTK("br2684_create\n");
+	/*
+	 * We track module use by vcc's NOT the devices they're on.  We're
+	 * protected here against module death by the kernel_lock, but if
+	 * we need to sleep we should make sure that the module doesn't
+	 * disappear under us.
+	 */
+	MOD_INC_USE_COUNT;
+	if (copy_from_user(&ni, (void *) arg, sizeof ni)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+	if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) {
+		MOD_DEC_USE_COUNT;
+		return -EINVAL;
+	}
+	if ((brdev = kmalloc(sizeof(struct br2684_dev), GFP_KERNEL)) == NULL) {
+		MOD_DEC_USE_COUNT;
+		return -ENOMEM;
+	}
+	memset(brdev, 0, sizeof(struct br2684_dev));
+	INIT_LIST_HEAD(&brdev->brvccs);
+
+	write_lock_irq(&devs_lock);
+	brdev->number = list_empty(&br2684_devs) ? 1 :
+	    list_entry_brdev(br2684_devs.prev)->number + 1;
+	list_add_tail(&brdev->br2684_devs, &br2684_devs);
+	write_unlock_irq(&devs_lock);
+
+	if (ni.ifname[0] != '\0') {
+		memcpy(brdev->net_dev.name, ni.ifname,
+		    sizeof(brdev->net_dev.name));
+		brdev->net_dev.name[sizeof(brdev->net_dev.name) - 1] = '\0';
+	} else
+		sprintf(brdev->net_dev.name, "nas%d", brdev->number);
+	DPRINTK("registered netdev %s\n", brdev->net_dev.name);
+	ether_setup(&brdev->net_dev);
+	brdev->mac_was_set = 0;
+#ifdef FASTER_VERSION
+	my_eth_header = brdev->net_dev.hard_header;
+	brdev->net_dev.hard_header = br2684_header;
+	my_eth_header_cache = brdev->net_dev.hard_header_cache;
+	brdev->net_dev.hard_header_cache = br2684_header_cache;
+	brdev->net_dev.hard_header_len = sizeof(llc_oui_pid_pad) + ETH_HLEN;	/* 10 + 14 */
+#endif
+	my_eth_mac_addr = brdev->net_dev.set_mac_address;
+	brdev->net_dev.set_mac_address = br2684_mac_addr;
+	brdev->net_dev.hard_start_xmit = br2684_start_xmit;
+	brdev->net_dev.get_stats = br2684_get_stats;
+
+	/* open, stop, do_ioctl ? */
+	err = register_netdev(&brdev->net_dev);
+	MOD_DEC_USE_COUNT;
+	if (err < 0) {
+		printk(KERN_ERR "br2684_create: register_netdev failed\n");
+		write_lock_irq(&devs_lock);
+		list_del(&brdev->br2684_devs);
+		write_unlock_irq(&devs_lock);
+		kfree(brdev);
+		return err;
+	}
+	return 0;
+}
+
+/*
+ * This handles ioctls actually performed on our vcc - we must return
+ * -ENOIOCTLCMD for any unrecognized ioctl
+ */
+static int br2684_ioctl(struct atm_vcc *atmvcc, unsigned int cmd,
+	unsigned long arg)
+{
+	int err;
+	switch(cmd) {
+	case ATM_SETBACKEND:
+	case ATM_NEWBACKENDIF: {
+		atm_backend_t b;
+		MOD_INC_USE_COUNT;
+		err = get_user(b, (atm_backend_t *) arg);
+		MOD_DEC_USE_COUNT;
+		if (err)
+			return -EFAULT;
+		if (b != ATM_BACKEND_BR2684)
+			return -ENOIOCTLCMD;
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		if (cmd == ATM_SETBACKEND)
+			return br2684_regvcc(atmvcc, arg);
+		else
+			return br2684_create(arg);
+		}
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+	case BR2684_SETFILT:
+		if (atmvcc->push != br2684_push)
+			return -ENOIOCTLCMD;
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		MOD_INC_USE_COUNT;
+		err = br2684_setfilt(atmvcc, arg);
+		MOD_DEC_USE_COUNT;
+		return err;
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+	}
+	return -ENOIOCTLCMD;
+}
+
+/* Never put more than 256 bytes in at once */
+static int br2684_proc_engine(loff_t pos, char *buf)
+{
+	struct list_head *lhd, *lhc;
+	struct br2684_dev *brdev;
+	struct br2684_vcc *brvcc;
+	list_for_each(lhd, &br2684_devs) {
+		brdev = list_entry_brdev(lhd);
+		if (pos-- == 0)
+			return sprintf(buf, "dev %.16s: num=%d, mac=%02X:%02X:"
+			    "%02X:%02X:%02X:%02X (%s)\n", brdev->net_dev.name,
+			    brdev->number,
+			    brdev->net_dev.dev_addr[0],
+			    brdev->net_dev.dev_addr[1],
+			    brdev->net_dev.dev_addr[2],
+			    brdev->net_dev.dev_addr[3],
+			    brdev->net_dev.dev_addr[4],
+			    brdev->net_dev.dev_addr[5],
+			    brdev->mac_was_set ? "set" : "auto");
+		list_for_each(lhc, &brdev->brvccs) {
+			brvcc = list_entry_brvcc(lhc);
+			if (pos-- == 0)
+				return sprintf(buf, "  vcc %d.%d.%d: encaps=%s"
+#ifndef FASTER_VERSION
+				    ", failed copies %u/%u"
+#endif /* FASTER_VERSION */
+				    "\n", brvcc->atmvcc->dev->number,
+				    brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
+				    (brvcc->encaps == e_llc) ? "LLC" : "VC"
+#ifndef FASTER_VERSION
+				    , brvcc->copies_failed
+				    , brvcc->copies_needed
+#endif /* FASTER_VERSION */
+				    );
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+#define b1(var, byte)	((u8 *) &brvcc->filter.var)[byte]
+#define bs(var)		b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3)
+			if (brvcc->filter.netmask != 0 && pos-- == 0)
+				return sprintf(buf, "    filter=%d.%d.%d.%d/"
+				    "%d.%d.%d.%d\n", bs(prefix), bs(netmask));
+#undef bs
+#undef b1
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+		}
+	}
+	return 0;
+}
+
+static ssize_t br2684_proc_read(struct file *file, char *buf, size_t count,
+	loff_t *pos)
+{
+	unsigned long page;
+	int len = 0, x, left;
+	page = get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+	left = PAGE_SIZE - 256;
+	if (count < left)
+		left = count;
+	read_lock(&devs_lock);
+	for (;;) {
+		x = br2684_proc_engine(*pos, &((char *) page)[len]);
+		if (x == 0)
+			break;
+		if (x > left)
+			/*
+			 * This should only happen if the user passed in
+			 * a "count" too small for even one line
+			 */
+			x = -EINVAL;
+		if (x < 0) {
+			len = x;
+			break;
+		}
+		len += x;
+		left -= x;
+		(*pos)++;
+		if (left < 256)
+			break;
+	}
+	read_unlock(&devs_lock);
+	if (len > 0 && copy_to_user(buf, (char *) page, len))
+		len = -EFAULT;
+	free_page(page);
+	return len;
+}
+
+static struct file_operations br2684_proc_operations = {
+	read: br2684_proc_read,
+};
+
+extern struct proc_dir_entry *atm_proc_root;	/* from proc.c */
+
+extern int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
+
+/* the following avoids some spurious warnings from the compiler */
+#define UNUSED __attribute__((unused))
+
+static int __init UNUSED br2684_init(void)
+{
+	struct proc_dir_entry *p;
+	if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL)
+		return -ENOMEM;
+	p->proc_fops = &br2684_proc_operations;
+	br2684_ioctl_hook = br2684_ioctl;
+	return 0;
+}
+
+static void __exit UNUSED br2684_exit(void)
+{
+	struct br2684_dev *brdev;
+	br2684_ioctl_hook = NULL;
+	remove_proc_entry("br2684", atm_proc_root);
+	while (!list_empty(&br2684_devs)) {
+		brdev = list_entry_brdev(br2684_devs.next);
+		unregister_netdev(&brdev->net_dev);
+		list_del(&brdev->br2684_devs);
+		kfree(brdev);
+	}
+}
+
+module_init(br2684_init);
+module_exit(br2684_exit);
+
+MODULE_AUTHOR("Marcell GAL");
+MODULE_DESCRIPTION("RFC2684 bridged protocols over ATM/AAL5");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/atm/common.c linux/net/atm/common.c
--- linux.orig/net/atm/common.c	2001-11-09 22:11:15.000000000 +0000
+++ linux/net/atm/common.c	2002-07-20 01:08:37.000000000 +0000
@@ -63,6 +63,13 @@
 EXPORT_SYMBOL(pppoatm_ioctl_hook);
 #endif
 
+#if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
+int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
+#endif
+#ifdef CONFIG_ATM_BR2684_MODULE
+EXPORT_SYMBOL(br2684_ioctl_hook);
+#endif
+
 #include "resources.h"		/* atm_find_dev */
 #include "common.h"		/* prototypes */
 #include "protocols.h"		/* atm_init_<transport> */
@@ -785,6 +792,14 @@
 			goto done;
 	}
 #endif
+#if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
+	if (br2684_ioctl_hook) {
+		ret_val = br2684_ioctl_hook(vcc, cmd, arg);
+		if (ret_val != -ENOIOCTLCMD)
+			goto done;
+	}
+#endif
+
 	if (get_user(buf,&((struct atmif_sioc *) arg)->arg)) {
 		ret_val = -EFAULT;
 		goto done;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/atm/pppoatm.c linux/net/atm/pppoatm.c
--- linux.orig/net/atm/pppoatm.c	2001-11-09 22:11:15.000000000 +0000
+++ linux/net/atm/pppoatm.c	2002-07-20 01:08:25.000000000 +0000
@@ -125,7 +125,7 @@
 	pvcc = atmvcc_to_pvcc(atmvcc);
 	atmvcc->push = pvcc->old_push;
 	atmvcc->pop = pvcc->old_pop;
-	tasklet_disable(&pvcc->wakeup_tasklet);
+	tasklet_kill(&pvcc->wakeup_tasklet);
 	ppp_unregister_channel(&pvcc->chan);
 	atmvcc->user_back = NULL;
 	kfree(pvcc);
@@ -363,3 +363,4 @@
 
 MODULE_AUTHOR("Mitchell Blank Jr <mitch@sfgoth.com>");
 MODULE_DESCRIPTION("RFC2364 PPP over ATM/AAL5");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/atm/resources.c linux/net/atm/resources.c
--- linux.orig/net/atm/resources.c	2001-11-09 22:11:15.000000000 +0000
+++ linux/net/atm/resources.c	2002-07-20 01:08:33.000000000 +0000
@@ -27,170 +27,188 @@
 struct atm_vcc *nodev_vccs = NULL;
 extern spinlock_t atm_dev_lock;
 
-
-static struct atm_dev *alloc_atm_dev(const char *type)
+/* Caller must hold atm_dev_lock. */
+static struct atm_dev *__alloc_atm_dev(const char *type)
 {
 	struct atm_dev *dev;
 
-	dev = kmalloc(sizeof(*dev),GFP_KERNEL);
-	if (!dev) return NULL;
-	memset(dev,0,sizeof(*dev));
+	dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
+	if (!dev)
+		return NULL;
+	memset(dev, 0, sizeof(*dev));
 	dev->type = type;
 	dev->signal = ATM_PHY_SIG_UNKNOWN;
 	dev->link_rate = ATM_OC3_PCR;
 	dev->next = NULL;
 
-	spin_lock(&atm_dev_lock);
-
 	dev->prev = last_dev;
 
-	if (atm_devs) last_dev->next = dev;
-	else atm_devs = dev;
+	if (atm_devs)
+		last_dev->next = dev;
+	else
+		atm_devs = dev;
 	last_dev = dev;
-	spin_unlock(&atm_dev_lock);
+
 	return dev;
 }
 
-
-static void free_atm_dev(struct atm_dev *dev)
+/* Caller must hold atm_dev_lock. */
+static void __free_atm_dev(struct atm_dev *dev)
 {
-	spin_lock (&atm_dev_lock);
-	
-	if (dev->prev) dev->prev->next = dev->next;
-	else atm_devs = dev->next;
-	if (dev->next) dev->next->prev = dev->prev;
-	else last_dev = dev->prev;
+	if (dev->prev)
+		dev->prev->next = dev->next;
+	else
+		atm_devs = dev->next;
+
+	if (dev->next)
+		dev->next->prev = dev->prev;
+	else
+		last_dev = dev->prev;
+
 	kfree(dev);
-	
-	spin_unlock (&atm_dev_lock);
 }
 
-
+/* Caller must hold atm_dev_lock. */
 struct atm_dev *atm_find_dev(int number)
 {
 	struct atm_dev *dev;
 
 	for (dev = atm_devs; dev; dev = dev->next)
-		if (dev->ops && dev->number == number) return dev;
+		if (dev->ops && dev->number == number)
+			return dev;
 	return NULL;
 }
 
-
-struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
-    int number,atm_dev_flags_t *flags)
+struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
+				 int number, atm_dev_flags_t *flags)
 {
 	struct atm_dev *dev;
 
-	dev = alloc_atm_dev(type);
+	spin_lock(&atm_dev_lock);
+
+	dev = __alloc_atm_dev(type);
 	if (!dev) {
 		printk(KERN_ERR "atm_dev_register: no space for dev %s\n",
-		    type);
-		return NULL;
+		       type);
+		goto done;
 	}
 	if (number != -1) {
 		if (atm_find_dev(number)) {
-			free_atm_dev(dev);
-			return NULL;
+			__free_atm_dev(dev);
+			dev = NULL;
+			goto done;
 		}
 		dev->number = number;
-	}
-	else {
+	} else {
 		dev->number = 0;
-		while (atm_find_dev(dev->number)) dev->number++;
+		while (atm_find_dev(dev->number))
+			dev->number++;
 	}
 	dev->vccs = dev->last = NULL;
 	dev->dev_data = NULL;
 	barrier();
 	dev->ops = ops;
-	if (flags) dev->flags = *flags;
-	else memset(&dev->flags,0,sizeof(dev->flags));
-	memset((void *) &dev->stats,0,sizeof(dev->stats));
+	if (flags)
+		dev->flags = *flags;
+	else
+		memset(&dev->flags, 0, sizeof(dev->flags));
+	memset(&dev->stats, 0, sizeof(dev->stats));
+
 #ifdef CONFIG_PROC_FS
-	if (ops->proc_read)
+	if (ops->proc_read) {
 		if (atm_proc_dev_register(dev) < 0) {
 			printk(KERN_ERR "atm_dev_register: "
-			    "atm_proc_dev_register failed for dev %s\n",type);
-			spin_unlock (&atm_dev_lock);		
-			free_atm_dev(dev);
-			return NULL;
+			       "atm_proc_dev_register failed for dev %s\n",
+			       type);
+			__free_atm_dev(dev);
+			dev = NULL;
+			goto done;
 		}
+	}
 #endif
-	spin_unlock (&atm_dev_lock);		
+
+done:
+	spin_unlock(&atm_dev_lock);		
+
 	return dev;
 }
 
-
 void atm_dev_deregister(struct atm_dev *dev)
 {
 #ifdef CONFIG_PROC_FS
-	if (dev->ops->proc_read) atm_proc_dev_deregister(dev);
+	if (dev->ops->proc_read)
+		atm_proc_dev_deregister(dev);
 #endif
-	free_atm_dev(dev);
+	spin_lock(&atm_dev_lock);
+	__free_atm_dev(dev);
+	spin_unlock(&atm_dev_lock);
 }
 
-
 void shutdown_atm_dev(struct atm_dev *dev)
 {
 	if (dev->vccs) {
-		set_bit(ATM_DF_CLOSE,&dev->flags);
+		set_bit(ATM_DF_CLOSE, &dev->flags);
 		return;
 	}
-	if (dev->ops->dev_close) dev->ops->dev_close(dev);
+	if (dev->ops->dev_close)
+		dev->ops->dev_close(dev);
 	atm_dev_deregister(dev);
 }
 
-
 /* Handler for sk->destruct, invoked by sk_free() */
 static void atm_free_sock(struct sock *sk)
 {
 	kfree(sk->protinfo.af_atm);
 }
 
-
 struct sock *alloc_atm_vcc_sk(int family)
 {
 	struct sock *sk;
 	struct atm_vcc *vcc;
 
 	sk = sk_alloc(family, GFP_KERNEL, 1);
-	if (!sk) return NULL;
+	if (!sk)
+		return NULL;
 	vcc = sk->protinfo.af_atm = kmalloc(sizeof(*vcc),GFP_KERNEL);
 	if (!vcc) {
 		sk_free(sk);
 		return NULL;
 	}
-	sock_init_data(NULL,sk);
+	sock_init_data(NULL, sk);
 	sk->destruct = atm_free_sock;
 	memset(vcc,0,sizeof(*vcc));
 	vcc->sk = sk;
-	if (nodev_vccs) nodev_vccs->prev = vcc;
+	if (nodev_vccs)
+		nodev_vccs->prev = vcc;
 	vcc->prev = NULL;
 	vcc->next = nodev_vccs;
 	nodev_vccs = vcc;
 	return sk;
 }
 
-
 static void unlink_vcc(struct atm_vcc *vcc,struct atm_dev *hold_dev)
 {
-	if (vcc->prev) vcc->prev->next = vcc->next;
-	else if (vcc->dev) vcc->dev->vccs = vcc->next;
-	    else nodev_vccs = vcc->next;
-	if (vcc->next) vcc->next->prev = vcc->prev;
-	else if (vcc->dev) vcc->dev->last = vcc->prev;
+	if (vcc->prev)
+		vcc->prev->next = vcc->next;
+	else if (vcc->dev)
+		vcc->dev->vccs = vcc->next;
+	else
+		nodev_vccs = vcc->next;
+	if (vcc->next)
+		vcc->next->prev = vcc->prev;
+	else if (vcc->dev)
+		vcc->dev->last = vcc->prev;
 	if (vcc->dev && vcc->dev != hold_dev && !vcc->dev->vccs &&
 	    test_bit(ATM_DF_CLOSE,&vcc->dev->flags))
 		shutdown_atm_dev(vcc->dev);
 }
 
-
 void free_atm_vcc_sk(struct sock *sk)
 {
-	unlink_vcc(sk->protinfo.af_atm,NULL);
+	unlink_vcc(sk->protinfo.af_atm, NULL);
 	sk_free(sk);
 }
 
-
 void bind_vcc(struct atm_vcc *vcc,struct atm_dev *dev)
 {
 	unlink_vcc(vcc,dev);
@@ -198,19 +216,20 @@
 	if (dev) {
 		vcc->next = NULL;
 		vcc->prev = dev->last;
-		if (dev->vccs) dev->last->next = vcc;
-		else dev->vccs = vcc;
+		if (dev->vccs)
+			dev->last->next = vcc;
+		else
+			dev->vccs = vcc;
 		dev->last = vcc;
-	}
-	else {
-		if (nodev_vccs) nodev_vccs->prev = vcc;
+	} else {
+		if (nodev_vccs)
+			nodev_vccs->prev = vcc;
 		vcc->next = nodev_vccs;
 		vcc->prev = NULL;
 		nodev_vccs = vcc;
 	}
 }
 
-
 EXPORT_SYMBOL(atm_dev_register);
 EXPORT_SYMBOL(atm_dev_deregister);
 EXPORT_SYMBOL(atm_find_dev);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- linux.orig/net/ax25/af_ax25.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ax25/af_ax25.c	2002-07-20 01:08:33.000000000 +0000
@@ -1863,6 +1863,7 @@
 
 MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
 MODULE_DESCRIPTION("The amateur radio AX.25 link layer protocol");
+MODULE_LICENSE("GPL");
 
 static void __exit ax25_exit(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/Config.in linux/net/bluetooth/Config.in
--- linux.orig/net/bluetooth/Config.in	2001-06-12 02:15:27.000000000 +0000
+++ linux/net/bluetooth/Config.in	2002-07-20 01:08:27.000000000 +0000
@@ -9,6 +9,7 @@
 
    if [ "$CONFIG_BLUEZ" != "n" ]; then
       dep_tristate 'L2CAP protocol support' CONFIG_BLUEZ_L2CAP $CONFIG_BLUEZ
+      dep_tristate 'SCO links support' CONFIG_BLUEZ_SCO $CONFIG_BLUEZ
       source drivers/bluetooth/Config.in
    fi
    endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/Makefile linux/net/bluetooth/Makefile
--- linux.orig/net/bluetooth/Makefile	2001-06-12 02:15:27.000000000 +0000
+++ linux/net/bluetooth/Makefile	2002-07-20 01:08:27.000000000 +0000
@@ -3,18 +3,15 @@
 #
 O_TARGET	:= bluetooth.o
 
-list-multi	:= hci.o l2cap.o
+list-multi	:= bluez.o
 export-objs	:= syms.o
-hci-objs	:= af_bluetooth.o hci_core.o hci_sock.o lib.o syms.o
-l2cap-objs	:= l2cap_core.o l2cap_proc.o
+bluez-objs	:= af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o lib.o syms.o
 
-obj-$(CONFIG_BLUEZ) += hci.o
+obj-$(CONFIG_BLUEZ) += bluez.o
 obj-$(CONFIG_BLUEZ_L2CAP) += l2cap.o
+obj-$(CONFIG_BLUEZ_SCO) += sco.o
 
 include $(TOPDIR)/Rules.make
 
-hci.o: $(hci-objs)
-	$(LD) -r -o $@ $(hci-objs)
-
-l2cap.o: $(l2cap-objs)
-	$(LD) -r -o $@ $(l2cap-objs)
+bluez.o: $(bluez-objs)
+	$(LD) -r -o $@ $(bluez-objs)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/af_bluetooth.c linux/net/bluetooth/af_bluetooth.c
--- linux.orig/net/bluetooth/af_bluetooth.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/net/bluetooth/af_bluetooth.c	2002-07-20 01:08:27.000000000 +0000
@@ -25,14 +25,15 @@
 /*
  * BlueZ Bluetooth address family and sockets.
  *
- * $Id: af_bluetooth.c,v 1.4 2001/07/05 18:42:44 maxk Exp $
+ * $Id: af_bluetooth.c,v 1.6 2002/06/25 22:03:39 maxk Exp $
  */
-#define VERSION "1.1"
+#define VERSION "2.1"
 
 #include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/types.h>
+#include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
@@ -40,6 +41,7 @@
 #include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <net/sock.h>
 
@@ -48,62 +50,71 @@
 #endif
 
 #include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
+
+#ifndef AF_BLUETOOTH_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#endif
 
 /* Bluetooth sockets */
-static struct net_proto_family *bluez_sock[BLUEZ_MAX_PROTO];
+#define BLUEZ_MAX_PROTO	5
+static struct net_proto_family *bluez_proto[BLUEZ_MAX_PROTO];
 
 int bluez_sock_register(int proto, struct net_proto_family *ops)
 {
-	if (proto > BLUEZ_MAX_PROTO)
+	if (proto >= BLUEZ_MAX_PROTO)
 		return -EINVAL;
 
-	if (bluez_sock[proto])
+	if (bluez_proto[proto])
 		return -EEXIST;
 
-	bluez_sock[proto] = ops;
+	bluez_proto[proto] = ops;
 	return 0;
 }
 
 int bluez_sock_unregister(int proto)
 {
-	if (proto > BLUEZ_MAX_PROTO)
+	if (proto >= BLUEZ_MAX_PROTO)
 		return -EINVAL;
 
-	if (!bluez_sock[proto])
+	if (!bluez_proto[proto])
 		return -ENOENT;
 
-	bluez_sock[proto] = NULL;
+	bluez_proto[proto] = NULL;
 	return 0;
 }
 
 static int bluez_sock_create(struct socket *sock, int proto)
 {
-	if (proto > BLUEZ_MAX_PROTO)
+	if (proto >= BLUEZ_MAX_PROTO)
 		return -EINVAL;
 
 #if defined(CONFIG_KMOD)
-	if (!bluez_sock[proto]) {
+	if (!bluez_proto[proto]) {
 		char module_name[30];
 		sprintf(module_name, "bt-proto-%d", proto);
 		request_module(module_name);
 	}
 #endif
 
-	if (!bluez_sock[proto])
+	if (!bluez_proto[proto])
 		return -ENOENT;
 
-	return bluez_sock[proto]->create(sock, proto);
+	return bluez_proto[proto]->create(sock, proto);
+}
+
+void bluez_sock_init(struct socket *sock, struct sock *sk)
+{ 
+	sock_init_data(sock, sk);
+	INIT_LIST_HEAD(&bluez_pi(sk)->accept_q);
 }
 
 void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
 {
 	write_lock(&l->lock);
-
 	sk->next = l->head;
 	l->head = sk;
 	sock_hold(sk);
-
 	write_unlock(&l->lock);
 }
 
@@ -122,6 +133,162 @@
 	write_unlock(&l->lock);
 }
 
+void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
+{
+	BT_DBG("parent %p, sk %p", parent, sk);
+
+	sock_hold(sk);
+	list_add_tail(&bluez_pi(sk)->accept_q, &bluez_pi(parent)->accept_q);
+	bluez_pi(sk)->parent = parent;
+	parent->ack_backlog++;
+}
+
+static void bluez_accept_unlink(struct sock *sk)
+{
+	BT_DBG("sk %p state %d", sk, sk->state);
+
+	list_del_init(&bluez_pi(sk)->accept_q);
+	bluez_pi(sk)->parent->ack_backlog--;
+	bluez_pi(sk)->parent = NULL;
+	sock_put(sk);
+}
+
+struct sock *bluez_accept_dequeue(struct sock *parent, struct socket *newsock)
+{
+	struct list_head *p, *n;
+	struct bluez_pinfo *pi;
+	struct sock *sk;
+	
+	BT_DBG("parent %p", parent);
+
+	list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
+		pi = list_entry(p, struct bluez_pinfo, accept_q);
+		sk = bluez_sk(pi);
+		
+		lock_sock(sk);
+		if (sk->state == BT_CLOSED) {
+			release_sock(sk);
+			bluez_accept_unlink(sk);
+			continue;
+		}
+		
+		if (sk->state == BT_CONNECTED || !newsock) {
+			bluez_accept_unlink(sk);
+			if (newsock)
+				sock_graft(sk, newsock);
+			release_sock(sk);
+			return sk;
+		}
+		release_sock(sk);
+	}
+	return NULL;
+}
+
+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
+{
+	int noblock = flags & MSG_DONTWAIT;
+	struct sock *sk = sock->sk;
+	struct sk_buff *skb;
+	int copied, err;
+
+	BT_DBG("sock %p sk %p len %d", sock, sk, len);
+
+	if (flags & (MSG_OOB))
+		return -EOPNOTSUPP;
+
+	if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
+		if (sk->shutdown & RCV_SHUTDOWN)
+			return 0;
+		return err;
+	}
+
+	msg->msg_namelen = 0;
+
+	copied = skb->len;
+	if (len < copied) {
+		msg->msg_flags |= MSG_TRUNC;
+		copied = len;
+	}
+
+	skb->h.raw = skb->data;
+	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+
+	skb_free_datagram(sk, skb);
+
+	return err ? : copied;
+}
+
+unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
+{
+	struct sock *sk = sock->sk;
+	unsigned int mask;
+
+	BT_DBG("sock %p, sk %p", sock, sk);
+
+	poll_wait(file, sk->sleep, wait);
+	mask = 0;
+
+	if (sk->err || !skb_queue_empty(&sk->error_queue))
+		mask |= POLLERR;
+
+	if (sk->shutdown == SHUTDOWN_MASK)
+		mask |= POLLHUP;
+
+	if (!skb_queue_empty(&sk->receive_queue) || 
+			!list_empty(&bluez_pi(sk)->accept_q) ||
+			(sk->shutdown & RCV_SHUTDOWN))
+		mask |= POLLIN | POLLRDNORM;
+
+	if (sk->state == BT_CLOSED)
+		mask |= POLLHUP;
+
+	if (sock_writeable(sk))
+		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+	else
+		set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
+
+	return mask;
+}
+
+int bluez_sock_w4_connect(struct sock *sk, int flags)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
+	int err = 0;
+
+	BT_DBG("sk %p", sk);
+
+	add_wait_queue(sk->sleep, &wait);
+	while (sk->state != BT_CONNECTED) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (!timeo) {
+			err = -EAGAIN;
+			break;
+		}
+
+		release_sock(sk);
+		timeo = schedule_timeout(timeo);
+		lock_sock(sk);
+
+		err = 0;
+		if (sk->state == BT_CONNECTED)
+			break;
+
+		if (sk->err) {
+			err = sock_error(sk);
+			break;
+		}
+
+		if (signal_pending(current)) {
+			err = sock_intr_errno(timeo);
+			break;
+		}
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(sk->sleep, &wait);
+	return err;
+}
+
 struct net_proto_family bluez_sock_family_ops =
 {
 	PF_BLUETOOTH, bluez_sock_create
@@ -129,9 +296,9 @@
 
 int bluez_init(void)
 {
-	INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
+	BT_INFO("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
 		 VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	proc_mkdir("bluetooth", NULL);
 
@@ -164,5 +331,6 @@
 module_exit(bluez_cleanup);
 
 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
+MODULE_DESCRIPTION("BlueZ Core ver " VERSION);
+MODULE_LICENSE("GPL");
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/hci_conn.c linux/net/bluetooth/hci_conn.c
--- linux.orig/net/bluetooth/hci_conn.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/bluetooth/hci_conn.c	2002-07-20 01:08:36.000000000 +0000
@@ -0,0 +1,434 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * HCI Connection handling.
+ *
+ * $Id: hci_conn.c,v 1.3 2002/06/25 22:03:39 maxk Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <net/sock.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifndef HCI_CORE_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#endif
+
+void hci_acl_connect(struct hci_conn *conn)
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct inquiry_entry *ie;
+	create_conn_cp cp;
+
+	BT_DBG("%p", conn);
+
+	conn->state = BT_CONNECT;
+	conn->out   = 1;
+	conn->link_mode = HCI_LM_MASTER;
+
+	memset(&cp, 0, sizeof(cp));
+	bacpy(&cp.bdaddr, &conn->dst);
+
+	if ((ie = inquiry_cache_lookup(hdev, &conn->dst)) &&
+			inquiry_entry_age(ie) > INQUIRY_ENTRY_AGE_MAX) {
+		cp.pscan_rep_mode = ie->info.pscan_rep_mode;
+		cp.pscan_mode     = ie->info.pscan_mode;
+		cp.clock_offset   = ie->info.clock_offset | __cpu_to_le16(0x8000);
+	}
+
+	cp.pkt_type = __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
+	if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
+		cp.role_switch	= 0x01;
+	else
+		cp.role_switch	= 0x00;
+		
+	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN,
+				CREATE_CONN_CP_SIZE, &cp);
+}
+
+void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
+{
+	disconnect_cp cp;
+
+	BT_DBG("%p", conn);
+
+	conn->state = BT_DISCONN;
+
+	cp.handle = __cpu_to_le16(conn->handle);
+	cp.reason = reason;
+	hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT,
+				DISCONNECT_CP_SIZE, &cp);
+}
+
+void hci_add_sco(struct hci_conn *conn, __u16 handle)
+{
+	struct hci_dev *hdev = conn->hdev;
+	add_sco_cp cp;
+
+	BT_DBG("%p", conn);
+
+	conn->state = BT_CONNECT;
+	conn->out = 1;
+
+	cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
+	cp.handle   = __cpu_to_le16(handle);
+
+	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, ADD_SCO_CP_SIZE, &cp);
+}
+
+static void hci_conn_timeout(unsigned long arg)
+{
+	struct hci_conn *conn = (void *)arg;
+	struct hci_dev  *hdev = conn->hdev;
+
+	BT_DBG("conn %p state %d", conn, conn->state);
+
+	if (atomic_read(&conn->refcnt))
+		return;
+
+	hci_dev_lock(hdev);
+ 	if (conn->state == BT_CONNECTED)
+		hci_acl_disconn(conn, 0x13);
+	else
+		conn->state = BT_CLOSED;
+	hci_dev_unlock(hdev);
+	return;
+}
+
+static void hci_conn_init_timer(struct hci_conn *conn)
+{
+	init_timer(&conn->timer);
+	conn->timer.function = hci_conn_timeout;
+	conn->timer.data = (unsigned long)conn;
+}
+
+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
+{
+	struct hci_conn *conn;
+
+	BT_DBG("%s dst %s", hdev->name, batostr(dst));
+
+	if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
+		return NULL;
+	memset(conn, 0, sizeof(struct hci_conn));
+
+	bacpy(&conn->dst, dst);
+	conn->type   = type;
+	conn->hdev   = hdev;
+	conn->state  = BT_OPEN;
+
+	skb_queue_head_init(&conn->data_q);
+	hci_conn_init_timer(conn);
+
+	atomic_set(&conn->refcnt, 0);
+
+	hci_dev_hold(hdev);
+
+	tasklet_disable(&hdev->tx_task);
+	conn_hash_add(hdev, conn);
+	tasklet_enable(&hdev->tx_task);
+
+	return conn;
+}
+
+int hci_conn_del(struct hci_conn *conn)
+{
+	struct hci_dev  *hdev = conn->hdev;
+
+	BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
+	
+	hci_conn_del_timer(conn);
+
+	if (conn->type == SCO_LINK) {
+		struct hci_conn *acl = conn->link;
+		if (acl) {
+			acl->link = NULL;
+			hci_conn_put(acl);
+		}
+	} else {
+		struct hci_conn *sco = conn->link;
+		if (sco)
+			sco->link = NULL;
+
+		/* Unacked frames */
+		hdev->acl_cnt += conn->sent;
+	}
+
+	tasklet_disable(&hdev->tx_task);
+	conn_hash_del(hdev, conn);
+	tasklet_enable(&hdev->tx_task);
+
+	skb_queue_purge(&conn->data_q);
+
+	hci_dev_put(hdev);
+
+	kfree(conn);
+	return 0;
+}
+
+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
+{
+	int use_src = bacmp(src, BDADDR_ANY);
+	struct hci_dev *hdev = NULL;
+	struct list_head *p;
+
+	BT_DBG("%s -> %s", batostr(src), batostr(dst));
+
+	spin_lock_bh(&hdev_list_lock);
+
+	list_for_each(p, &hdev_list) {
+		struct hci_dev *d;
+		d = list_entry(p, struct hci_dev, list);
+		
+		if (!test_bit(HCI_UP, &d->flags))
+			continue;
+
+		/* Simple routing: 
+	 	 * 	No source address - find interface with bdaddr != dst 
+	 	 *	Source address 	  - find interface with bdaddr == src 
+	 	 */
+
+		if (use_src) {
+			if (!bacmp(&d->bdaddr, src)) {
+				hdev = d; break;
+			}
+		} else {
+			if (bacmp(&d->bdaddr, dst)) {
+				hdev = d; break;
+			}
+		}
+	}
+
+	if (hdev)
+		hci_dev_hold(hdev);
+
+	spin_unlock_bh(&hdev_list_lock);
+	return hdev;
+}
+
+/* Create SCO or ACL connection.
+ * Device _must_ be locked */
+struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
+{
+	struct hci_conn *acl;
+
+	BT_DBG("%s dst %s", hdev->name, batostr(dst));
+
+	if (!(acl = conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
+		if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
+			return NULL;
+	}
+
+	hci_conn_hold(acl);
+
+	if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
+		hci_acl_connect(acl);
+
+	if (type == SCO_LINK) {
+		struct hci_conn *sco;
+
+		if (!(sco = conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
+			if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
+				hci_conn_put(acl);
+				return NULL;
+			}
+		}
+		acl->link = sco;
+		sco->link = acl;
+
+		hci_conn_hold(sco);
+
+		if (acl->state == BT_CONNECTED && 
+				(sco->state == BT_OPEN || sco->state == BT_CLOSED))
+			hci_add_sco(sco, acl->handle);
+
+		return sco;
+	} else {
+		return acl;
+	}
+}
+
+/* Authenticate remote device */
+int hci_conn_auth(struct hci_conn *conn)
+{
+	BT_DBG("conn %p", conn);
+	
+	if (conn->link_mode & HCI_LM_AUTH)
+		return 1;
+	
+	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
+		auth_requested_cp ar;
+		ar.handle = __cpu_to_le16(conn->handle);
+		hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED,
+				AUTH_REQUESTED_CP_SIZE, &ar);
+	}
+	return 0;
+}
+
+/* Enable encryption */
+int hci_conn_encrypt(struct hci_conn *conn)
+{
+	BT_DBG("conn %p", conn);
+	
+	if (conn->link_mode & HCI_LM_ENCRYPT)
+		return 1;
+	
+	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+		return 0;
+
+	if (hci_conn_auth(conn)) {
+		set_conn_encrypt_cp ce;
+		ce.handle  = __cpu_to_le16(conn->handle);
+		ce.encrypt = 1; 
+		hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT,
+				SET_CONN_ENCRYPT_CP_SIZE, &ce);
+	}
+	return 0;
+}
+
+/* Drop all connection on the device */
+void hci_conn_hash_flush(struct hci_dev *hdev)
+{
+	struct conn_hash *h = &hdev->conn_hash;
+        struct list_head *p;
+
+	BT_DBG("hdev %s", hdev->name);
+
+	p = h->list.next;
+	while (p != &h->list) {
+		struct hci_conn *c;
+
+		c = list_entry(p, struct hci_conn, list);
+		p = p->next;
+
+		c->state = BT_CLOSED;
+
+		hci_proto_disconn_ind(c, 0x16);
+		hci_conn_del(c);
+	}
+}
+
+int hci_get_conn_list(unsigned long arg)
+{
+	struct hci_conn_list_req req, *cl;
+	struct hci_conn_info *ci;
+	struct hci_dev *hdev;
+	struct list_head *p;
+	int n = 0, size;
+
+	if (copy_from_user(&req, (void *) arg, sizeof(req)))
+		return -EFAULT;
+
+	if (!(hdev = hci_dev_get(req.dev_id)))
+		return -ENODEV;
+
+	size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
+
+	if (verify_area(VERIFY_WRITE, (void *)arg, size))
+		return -EFAULT;
+
+	if (!(cl = (void *) kmalloc(size, GFP_KERNEL)))
+		return -ENOMEM;
+	ci = cl->conn_info;
+
+	hci_dev_lock_bh(hdev);
+	list_for_each(p, &hdev->conn_hash.list) {
+		register struct hci_conn *c;
+		c = list_entry(p, struct hci_conn, list);
+
+		bacpy(&(ci + n)->bdaddr, &c->dst);
+		(ci + n)->handle = c->handle;
+		(ci + n)->type  = c->type;
+		(ci + n)->out   = c->out;
+		(ci + n)->state = c->state;
+		(ci + n)->link_mode = c->link_mode;
+		n++;
+	}
+	hci_dev_unlock_bh(hdev);
+
+	cl->dev_id = hdev->id;
+	cl->conn_num = n;
+	size = n * sizeof(struct hci_conn_info) + sizeof(req);
+
+	hci_dev_put(hdev);
+
+	copy_to_user((void *) arg, cl, size);
+	kfree(cl);
+
+	return 0;
+}
+
+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
+{
+	struct hci_conn_info_req req;
+	struct hci_conn_info ci;
+	struct hci_conn *conn;
+	char *ptr = (void *) arg + sizeof(req);
+
+	if (copy_from_user(&req, (void *) arg, sizeof(req)))
+		return -EFAULT;
+
+	if (verify_area(VERIFY_WRITE, ptr, sizeof(ci)))
+		return -EFAULT;
+
+	hci_dev_lock_bh(hdev);
+	conn = conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
+	if (conn) {
+		bacpy(&ci.bdaddr, &conn->dst);
+		ci.handle = conn->handle;
+		ci.type  = conn->type;
+		ci.out   = conn->out;
+		ci.state = conn->state;
+		ci.link_mode = conn->link_mode;
+	}
+	hci_dev_unlock_bh(hdev);
+
+	if (!conn)
+		return -ENOENT;
+
+	copy_to_user(ptr, &ci, sizeof(ci));
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/hci_core.c linux/net/bluetooth/hci_core.c
--- linux.orig/net/bluetooth/hci_core.c	2001-11-09 22:21:21.000000000 +0000
+++ linux/net/bluetooth/hci_core.c	2002-07-20 01:08:29.000000000 +0000
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI Core.
  *
- * $Id: hci_core.c,v 1.22 2001/08/03 04:19:50 maxk Exp $
+ * $Id: hci_core.c,v 1.7 2002/06/25 22:03:39 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -50,12 +50,11 @@
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
 #include <net/bluetooth/hci_core.h>
 
 #ifndef HCI_CORE_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
 static void hci_cmd_task(unsigned long arg);
@@ -63,279 +62,43 @@
 static void hci_tx_task(unsigned long arg);
 static void hci_notify(struct hci_dev *hdev, int event);
 
-static rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
+rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
 
 /* HCI device list */
-struct hci_dev *hdev_list[HCI_MAX_DEV];
+LIST_HEAD(hdev_list);
 spinlock_t hdev_list_lock;
-#define GET_HDEV(a) (hdev_list[a])
 
-/* HCI protocol list */
-struct hci_proto *hproto_list[HCI_MAX_PROTO];
-#define GET_HPROTO(a) (hproto_list[a])
+/* HCI protocols */
+#define HCI_MAX_PROTO	2
+struct hci_proto *hci_proto[HCI_MAX_PROTO];
 
 /* HCI notifiers list */
-struct notifier_block *hci_dev_notifier;
+static struct notifier_block *hci_notifier;
 
-/* HCI device notifications */
-int hci_register_notifier(struct notifier_block *nb)
-{
-	int err, i;
-	struct hci_dev *hdev;
-
-	if ((err = notifier_chain_register(&hci_dev_notifier, nb)))
-		return err;
-
-	/* Notify about already registered devices */
-	spin_lock(&hdev_list_lock);
-	for (i = 0; i < HCI_MAX_DEV; i++) {
-		if (!(hdev = GET_HDEV(i)))
-			continue;
-		if (hdev->flags & HCI_UP)
-			(*nb->notifier_call)(nb, HCI_DEV_UP, hdev);
-	}
-	spin_unlock(&hdev_list_lock);
-
-	return 0;
-}
-
-int hci_unregister_notifier(struct notifier_block *nb)
-{
-	return notifier_chain_unregister(&hci_dev_notifier, nb);
-}
-
-static inline void hci_notify(struct hci_dev *hdev, int event)
-{
-	notifier_call_chain(&hci_dev_notifier, event, hdev);
-}
-
-/* Get HCI device by index (device is locked on return)*/
-struct hci_dev *hci_dev_get(int index)
-{
-	struct hci_dev *hdev;
-	DBG("%d", index);
-
-	if (index < 0 || index >= HCI_MAX_DEV)
-		return NULL;
-
-	spin_lock(&hdev_list_lock);
-	if ((hdev = GET_HDEV(index)))
-		hci_dev_hold(hdev);
-	spin_unlock(&hdev_list_lock);
-
-	return hdev;
-}
-
-/* Flush inquiry cache */
-void inquiry_cache_flush(struct inquiry_cache *cache)
-{
-	struct inquiry_entry *next = cache->list, *e;
-
-	DBG("cache %p", cache);
-
-	cache->list = NULL;
-	while ((e = next)) {
-		next = e->next;
-		kfree(e);
-	}
-}
-
-/* Lookup by bdaddr.
- * Cache must be locked. */
-static struct inquiry_entry * __inquiry_cache_lookup(struct inquiry_cache *cache, bdaddr_t *bdaddr)
-{
-	struct inquiry_entry *e;
-
-	DBG("cache %p, %s", cache, batostr(bdaddr));
-
-	for (e = cache->list; e; e = e->next)
-		if (!bacmp(&e->info.bdaddr, bdaddr))
-			break;
-
-	return e;
-}
-
-static void inquiry_cache_update(struct inquiry_cache *cache, inquiry_info *info)
-{
-	struct inquiry_entry *e;
-
-	DBG("cache %p, %s", cache, batostr(&info->bdaddr));
-
-	inquiry_cache_lock(cache);
-
-	if (!(e = __inquiry_cache_lookup(cache, &info->bdaddr))) {
-		/* Entry not in the cache. Add new one. */
-		if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-			goto unlock;
-		memset(e, 0, sizeof(struct inquiry_entry));
-		e->next     = cache->list;
-		cache->list = e;
-	}
 
-	memcpy(&e->info, info, sizeof(inquiry_info));
-	e->timestamp = jiffies;
-	cache->timestamp = jiffies;
-unlock:
-	inquiry_cache_unlock(cache);
-}
-
-static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
-{
-	inquiry_info *info = (inquiry_info *) buf;
-	struct inquiry_entry *e;
-	int copied = 0;
-
-	inquiry_cache_lock(cache);
-
-	for (e = cache->list; e && copied < num; e = e->next, copied++)
-		memcpy(info++, &e->info, sizeof(inquiry_info));
-
-	inquiry_cache_unlock(cache);
-
-	DBG("cache %p, copied %d", cache, copied);
-	return copied;
-}
-
-/* --------- BaseBand connections --------- */
-static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
-{
-	struct hci_conn *conn;
-
-	DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
-
-	if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
-		ERR("%s handle 0x%x already exists", hdev->name, handle);
-		return NULL;
-	}
-
-	if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-		return NULL;
-	memset(conn, 0, sizeof(struct hci_conn));
-
-	bacpy(&conn->dst, dst);
-	conn->handle = handle;
-	conn->type   = type;
-	conn->hdev   = hdev;
-
-	skb_queue_head_init(&conn->data_q);
-
-	hci_dev_hold(hdev);
-	conn_hash_add(&hdev->conn_hash, handle, conn);
-
-	return conn;
-}
+/* ---- HCI notifications ---- */
 
-static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
-{
-	DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
-
-	conn_hash_del(&hdev->conn_hash, conn);
-	hci_dev_put(hdev);
-
-	/* Unacked frames */
-	hdev->acl_cnt += conn->sent;
-
-	skb_queue_purge(&conn->data_q);
-
-	kfree(conn);
-	return 0;
-}
-
-/* Drop all connection on the device */
-static void hci_conn_hash_flush(struct hci_dev *hdev)
+int hci_register_notifier(struct notifier_block *nb)
 {
-	struct conn_hash *h = &hdev->conn_hash;
-	struct hci_proto *hp;
-        struct list_head *p;
-
-	DBG("hdev %s", hdev->name);
-
-	p = h->list.next;
-	while (p != &h->list) {
-		struct hci_conn *c;
-
-		c = list_entry(p, struct hci_conn, list);
-		p = p->next;
-
-		if (c->type == ACL_LINK) {
-			/* ACL link notify L2CAP layer */
-			if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-				hp->disconn_ind(c, 0x16);
-		} else {
-			/* SCO link (no notification) */
-		}
-
-		hci_conn_del(hdev, c);
-	}
+	return notifier_chain_register(&hci_notifier, nb);
 }
 
-int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
+int hci_unregister_notifier(struct notifier_block *nb)
 {
-	struct inquiry_cache *cache = &hdev->inq_cache;
-	struct inquiry_entry *e;
-	create_conn_cp cc;
-	__u16 clock_offset;
-
-	DBG("%s bdaddr %s", hdev->name, batostr(bdaddr));
-
-	if (!(hdev->flags & HCI_UP))
-		return -ENODEV;
-
-	inquiry_cache_lock_bh(cache);
-
-	if (!(e = __inquiry_cache_lookup(cache, bdaddr)) || inquiry_entry_age(e) > INQUIRY_ENTRY_AGE_MAX) {
-		cc.pscan_rep_mode = 0;
-		cc.pscan_mode     = 0;
-		clock_offset      = 0;
-	} else {
-		cc.pscan_rep_mode = e->info.pscan_rep_mode;
-		cc.pscan_mode     = e->info.pscan_mode;
-		clock_offset      = __le16_to_cpu(e->info.clock_offset) & 0x8000;
-	}
-
-	inquiry_cache_unlock_bh(cache);
-
-	bacpy(&cc.bdaddr, bdaddr);
-	cc.pkt_type	= __cpu_to_le16(hdev->pkt_type);
-	cc.clock_offset	= __cpu_to_le16(clock_offset);
-
-	if (lmp_rswitch_capable(hdev))
-		cc.role_switch	= 0x01;
-	else
-		cc.role_switch	= 0x00;
-		
-	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
-
-	return 0;
+	return notifier_chain_unregister(&hci_notifier, nb);
 }
 
-int hci_disconnect(struct hci_conn *conn, __u8 reason)
+void hci_notify(struct hci_dev *hdev, int event)
 {
-	disconnect_cp dc;
-
-	DBG("conn %p handle %d", conn, conn->handle);
-
-	dc.handle = __cpu_to_le16(conn->handle);
-	dc.reason = reason;
-	hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, DISCONNECT_CP_SIZE, &dc);
-
-	return 0;
+	notifier_call_chain(&hci_notifier, event, hdev);
 }
 
-/* --------- HCI request handling ------------ */
-static inline void hci_req_lock(struct hci_dev *hdev)
-{
-	down(&hdev->req_lock);
-}
 
-static inline void hci_req_unlock(struct hci_dev *hdev)
-{
-	up(&hdev->req_lock);
-}
+/* ---- HCI requests ---- */
 
-static inline void hci_req_complete(struct hci_dev *hdev, int result)
+void hci_req_complete(struct hci_dev *hdev, int result)
 {
-	DBG("%s result 0x%2.2x", hdev->name, result);
+	BT_DBG("%s result 0x%2.2x", hdev->name, result);
 
 	if (hdev->req_status == HCI_REQ_PEND) {
 		hdev->req_result = result;
@@ -344,9 +107,9 @@
 	}
 }
 
-static inline void hci_req_cancel(struct hci_dev *hdev, int err)
+void hci_req_cancel(struct hci_dev *hdev, int err)
 {
-	DBG("%s err 0x%2.2x", hdev->name, err);
+	BT_DBG("%s err 0x%2.2x", hdev->name, err);
 
 	if (hdev->req_status == HCI_REQ_PEND) {
 		hdev->req_result = err;
@@ -356,23 +119,22 @@
 }
 
 /* Execute request and wait for completion. */
-static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
-                         unsigned long opt, __u32 timeout)
+static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), unsigned long opt, __u32 timeout)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	int err = 0;
 
-	DBG("%s start", hdev->name);
+	BT_DBG("%s start", hdev->name);
 
 	hdev->req_status = HCI_REQ_PEND;
 
 	add_wait_queue(&hdev->req_wait_q, &wait);
-	current->state = TASK_INTERRUPTIBLE;
+	set_current_state(TASK_INTERRUPTIBLE);
 
 	req(hdev, opt);
 	schedule_timeout(timeout);
 
-	current->state = TASK_RUNNING;
+	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&hdev->req_wait_q, &wait);
 
 	if (signal_pending(current))
@@ -394,7 +156,7 @@
 
 	hdev->req_status = hdev->req_result = 0;
 
-	DBG("%s end: err %d", hdev->name, err);
+	BT_DBG("%s end: err %d", hdev->name, err);
 
 	return err;
 }
@@ -412,10 +174,9 @@
 	return ret;
 }
 
-/* --------- HCI requests ---------- */
 static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
 {
-	DBG("%s %ld", hdev->name, opt);
+	BT_DBG("%s %ld", hdev->name, opt);
 
 	/* Reset device */
 	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
@@ -423,10 +184,10 @@
 
 static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 {
-	set_event_flt_cp ec;
+	set_event_flt_cp ef;
 	__u16 param;
 
-	DBG("%s %ld", hdev->name, opt);
+	BT_DBG("%s %ld", hdev->name, opt);
 
 	/* Mandatory initialization */
 
@@ -436,14 +197,27 @@
 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
 	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
 
+#if 0
+	/* Host buffer size */
+	{
+		host_buffer_size_cp bs;
+		bs.acl_mtu = __cpu_to_le16(HCI_MAX_ACL_SIZE);
+		bs.sco_mtu = HCI_MAX_SCO_SIZE;
+		bs.acl_max_pkt = __cpu_to_le16(0xffff);
+		bs.sco_max_pkt = __cpu_to_le16(0xffff);
+		hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE,
+				HOST_BUFFER_SIZE_CP_SIZE, &bs);
+	}
+#endif
+
 	/* Read BD Address */
 	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
 
 	/* Optional initialization */
 
 	/* Clear Event Filters */
-	ec.flt_type  = FLT_CLEAR_ALL;
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
+	ef.flt_type  = FLT_CLEAR_ALL;
+	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ef);
 
 	/* Page timeout ~20 secs */
 	param = __cpu_to_le16(0x8000);
@@ -458,7 +232,7 @@
 {
 	__u8 scan = opt;
 
-	DBG("%s %x", hdev->name, scan);
+	BT_DBG("%s %x", hdev->name, scan);
 
 	/* Inquiry and Page scans */
 	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
@@ -468,116 +242,269 @@
 {
 	__u8 auth = opt;
 
-	DBG("%s %x", hdev->name, auth);
+	BT_DBG("%s %x", hdev->name, auth);
 
 	/* Authentication */
 	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
 }
 
-static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
+static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
 {
-	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
-	inquiry_cp ic;
+	__u8 encrypt = opt;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s %x", hdev->name, encrypt);
 
-	/* Start Inquiry */
-	memcpy(&ic.lap, &ir->lap, 3);
-	ic.lenght  = ir->length;
-	ic.num_rsp = ir->num_rsp;
-	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
+	/* Authentication */
+	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
 }
 
-/* HCI ioctl helpers */
-int hci_dev_open(__u16 dev)
+/* Get HCI device by index. 
+ * Device is locked on return. */
+struct hci_dev *hci_dev_get(int index)
 {
 	struct hci_dev *hdev;
-	int ret = 0;
-
-	if (!(hdev = hci_dev_get(dev)))
-		return -ENODEV;
+	struct list_head *p;
 
-	DBG("%s %p", hdev->name, hdev);
+	BT_DBG("%d", index);
 
-	hci_req_lock(hdev);
+	if (index < 0)
+		return NULL;
 
-	if (hdev->flags & HCI_UP) {
-		ret = -EALREADY;
-		goto done;
+	spin_lock(&hdev_list_lock);
+	list_for_each(p, &hdev_list) {
+		hdev = list_entry(p, struct hci_dev, list);
+		if (hdev->id == index) {
+			hci_dev_hold(hdev);
+			goto done;
+		}
 	}
+	hdev = NULL;
+done:
+	spin_unlock(&hdev_list_lock);
+	return hdev;
+}
 
-	if (hdev->open(hdev)) {
-		ret = -EIO;
-		goto done;
-	}
+/* ---- Inquiry support ---- */
+void inquiry_cache_flush(struct hci_dev *hdev)
+{
+	struct inquiry_cache *cache = &hdev->inq_cache;
+	struct inquiry_entry *next  = cache->list, *e;
 
-	if (hdev->flags & HCI_NORMAL) {
-		atomic_set(&hdev->cmd_cnt, 1);
-		hdev->flags |= HCI_INIT;
+	BT_DBG("cache %p", cache);
 
-		//__hci_request(hdev, hci_reset_req, 0, HZ);
-		ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
-       
-		hdev->flags &= ~HCI_INIT;
+	cache->list = NULL;
+	while ((e = next)) {
+		next = e->next;
+		kfree(e);
 	}
+}
 
-	if (!ret) {
-		hdev->flags |= HCI_UP;
-		hci_notify(hdev, HCI_DEV_UP);
-	} else {	
-		/* Init failed, cleanup */
-		tasklet_kill(&hdev->rx_task);
-		tasklet_kill(&hdev->tx_task);
-		tasklet_kill(&hdev->cmd_task);
+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct inquiry_cache *cache = &hdev->inq_cache;
+	struct inquiry_entry *e;
 
-		skb_queue_purge(&hdev->cmd_q);
-		skb_queue_purge(&hdev->rx_q);
+	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
 
-		if (hdev->flush)
-			hdev->flush(hdev);
+	for (e = cache->list; e; e = e->next)
+		if (!bacmp(&e->info.bdaddr, bdaddr))
+			break;
+	return e;
+}
 
-		if (hdev->sent_cmd) {
-			kfree_skb(hdev->sent_cmd);
-			hdev->sent_cmd = NULL;
-		}
+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info)
+{
+	struct inquiry_cache *cache = &hdev->inq_cache;
+	struct inquiry_entry *e;
 
-		hdev->close(hdev);
-	}
+	BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
 
-done:
-	hci_req_unlock(hdev);
-	hci_dev_put(hdev);
+	if (!(e = inquiry_cache_lookup(hdev, &info->bdaddr))) {
+		/* Entry not in the cache. Add new one. */
+		if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
+			return;
+		memset(e, 0, sizeof(struct inquiry_entry));
+		e->next     = cache->list;
+		cache->list = e;
+	}
 
-	return ret;
+	memcpy(&e->info, info, sizeof(inquiry_info));
+	e->timestamp = jiffies;
+	cache->timestamp = jiffies;
 }
 
-int hci_dev_close(__u16 dev)
+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
 {
-	struct hci_dev *hdev;
+	struct inquiry_cache *cache = &hdev->inq_cache;
+	inquiry_info *info = (inquiry_info *) buf;
+	struct inquiry_entry *e;
+	int copied = 0;
 
-	if (!(hdev = hci_dev_get(dev)))
-		return -ENODEV;
+	for (e = cache->list; e && copied < num; e = e->next, copied++)
+		memcpy(info++, &e->info, sizeof(inquiry_info));
 
-	DBG("%s %p", hdev->name, hdev);
+	BT_DBG("cache %p, copied %d", cache, copied);
+	return copied;
+}
 
-	hci_req_cancel(hdev, ENODEV);
-	hci_req_lock(hdev);
+static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
+{
+	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
+	inquiry_cp ic;
 
-	if (!(hdev->flags & HCI_UP))
-		goto done;
+	BT_DBG("%s", hdev->name);
 
-	/* Kill RX and TX tasks */
-	tasklet_kill(&hdev->rx_task);
-	tasklet_kill(&hdev->tx_task);
+	if (test_bit(HCI_INQUIRY, &hdev->flags))
+		return;
 
-	inquiry_cache_flush(&hdev->inq_cache);
+	/* Start Inquiry */
+	memcpy(&ic.lap, &ir->lap, 3);
+	ic.length  = ir->length;
+	ic.num_rsp = ir->num_rsp;
+	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
+}
 
-	hci_conn_hash_flush(hdev);
+int hci_inquiry(unsigned long arg)
+{
+	struct hci_inquiry_req ir;
+	struct hci_dev *hdev;
+	int err = 0, do_inquiry = 0;
+	long timeo;
+	__u8 *buf, *ptr;
 
-	/* Clear flags */
-	hdev->flags &= HCI_SOCK;
-	hdev->flags |= HCI_NORMAL;
+	ptr = (void *) arg;
+	if (copy_from_user(&ir, ptr, sizeof(ir)))
+		return -EFAULT;
+
+	if (!(hdev = hci_dev_get(ir.dev_id)))
+		return -ENODEV;
+
+	hci_dev_lock_bh(hdev);
+	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 
+					ir.flags & IREQ_CACHE_FLUSH) {
+		inquiry_cache_flush(hdev);
+		do_inquiry = 1;
+	}
+	hci_dev_unlock_bh(hdev);
+
+	timeo = ir.length * 2 * HZ;
+	if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
+		goto done;
+
+	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
+	 * copy it to the user space.
+	 */
+	if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto done;
+	}
+
+	hci_dev_lock_bh(hdev);
+	ir.num_rsp = inquiry_cache_dump(hdev, ir.num_rsp, buf);
+	hci_dev_unlock_bh(hdev);
+
+	BT_DBG("num_rsp %d", ir.num_rsp);
+
+	if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + 
+				(sizeof(inquiry_info) * ir.num_rsp))) {
+		copy_to_user(ptr, &ir, sizeof(ir));
+		ptr += sizeof(ir);
+	        copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
+	} else 
+		err = -EFAULT;
+
+	kfree(buf);
+
+done:
+	hci_dev_put(hdev);
+	return err;
+}
+
+/* ---- HCI ioctl helpers ---- */
+
+int hci_dev_open(__u16 dev)
+{
+	struct hci_dev *hdev;
+	int ret = 0;
+
+	if (!(hdev = hci_dev_get(dev)))
+		return -ENODEV;
+
+	BT_DBG("%s %p", hdev->name, hdev);
+
+	hci_req_lock(hdev);
+
+	if (test_bit(HCI_UP, &hdev->flags)) {
+		ret = -EALREADY;
+		goto done;
+	}
+
+	if (hdev->open(hdev)) {
+		ret = -EIO;
+		goto done;
+	}
+
+	if (!test_bit(HCI_RAW, &hdev->flags)) {
+		atomic_set(&hdev->cmd_cnt, 1);
+		set_bit(HCI_INIT, &hdev->flags);
+
+		//__hci_request(hdev, hci_reset_req, 0, HZ);
+		ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
+       
+		clear_bit(HCI_INIT, &hdev->flags);
+	}
+
+	if (!ret) {
+		set_bit(HCI_UP, &hdev->flags);
+		hci_notify(hdev, HCI_DEV_UP);
+	} else {	
+		/* Init failed, cleanup */
+		tasklet_kill(&hdev->rx_task);
+		tasklet_kill(&hdev->tx_task);
+		tasklet_kill(&hdev->cmd_task);
+
+		skb_queue_purge(&hdev->cmd_q);
+		skb_queue_purge(&hdev->rx_q);
+
+		if (hdev->flush)
+			hdev->flush(hdev);
+
+		if (hdev->sent_cmd) {
+			kfree_skb(hdev->sent_cmd);
+			hdev->sent_cmd = NULL;
+		}
+
+		hdev->close(hdev);
+		hdev->flags = 0;
+	}
+
+done:
+	hci_req_unlock(hdev);
+	hci_dev_put(hdev);
+	return ret;
+}
+
+static int hci_dev_do_close(struct hci_dev *hdev)
+{
+	BT_DBG("%s %p", hdev->name, hdev);
+
+	hci_req_cancel(hdev, ENODEV);
+	hci_req_lock(hdev);
+
+	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
+		hci_req_unlock(hdev);
+		return 0;
+	}
+
+	/* Kill RX and TX tasks */
+	tasklet_kill(&hdev->rx_task);
+	tasklet_kill(&hdev->tx_task);
 
+	hci_dev_lock_bh(hdev);
+	inquiry_cache_flush(hdev);
+	hci_conn_hash_flush(hdev);
+	hci_dev_unlock_bh(hdev);
+	
 	hci_notify(hdev, HCI_DEV_DOWN);
 
 	if (hdev->flush)
@@ -586,9 +513,9 @@
 	/* Reset device */
 	skb_queue_purge(&hdev->cmd_q);
 	atomic_set(&hdev->cmd_cnt, 1);
-	hdev->flags |= HCI_INIT;
-	__hci_request(hdev, hci_reset_req, 0, HZ);
-	hdev->flags &= ~HCI_INIT;
+	set_bit(HCI_INIT, &hdev->flags);
+	__hci_request(hdev, hci_reset_req, 0, HZ/4);
+	clear_bit(HCI_INIT, &hdev->flags);
 
 	/* Kill cmd task */
 	tasklet_kill(&hdev->cmd_task);
@@ -605,17 +532,28 @@
 	}
 
 	/* After this point our queues are empty
-	 * and no tasks are scheduled.
-	 */
+	 * and no tasks are scheduled. */
 	hdev->close(hdev);
 
-done:
-	hci_req_unlock(hdev);
-	hci_dev_put(hdev);
+	/* Clear flags */
+	hdev->flags = 0;
 
+	hci_req_unlock(hdev);
 	return 0;
 }
 
+int hci_dev_close(__u16 dev)
+{
+	struct hci_dev *hdev;
+	int err;
+	
+	if (!(hdev = hci_dev_get(dev)))
+		return -ENODEV;
+	err = hci_dev_do_close(hdev);
+	hci_dev_put(hdev);
+	return err;
+}
+
 int hci_dev_reset(__u16 dev)
 {
 	struct hci_dev *hdev;
@@ -627,16 +565,17 @@
 	hci_req_lock(hdev);
 	tasklet_disable(&hdev->tx_task);
 
-	if (!(hdev->flags & HCI_UP))
+	if (!test_bit(HCI_UP, &hdev->flags))
 		goto done;
 
 	/* Drop queues */
 	skb_queue_purge(&hdev->rx_q);
 	skb_queue_purge(&hdev->cmd_q);
 
-	inquiry_cache_flush(&hdev->inq_cache);
-
+	hci_dev_lock_bh(hdev);
+	inquiry_cache_flush(hdev);
 	hci_conn_hash_flush(hdev);
+	hci_dev_unlock_bh(hdev);
 
 	if (hdev->flush)
 		hdev->flush(hdev);
@@ -650,7 +589,6 @@
 	tasklet_enable(&hdev->tx_task);
 	hci_req_unlock(hdev);
 	hci_dev_put(hdev);
-
 	return ret;
 }
 
@@ -669,30 +607,11 @@
 	return ret;
 }
 
-int hci_dev_setauth(unsigned long arg)
-{
-	struct hci_dev *hdev;
-	struct hci_dev_req dr;
-	int ret = 0;
-
-	if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-		return -EFAULT;
-
-	if (!(hdev = hci_dev_get(dr.dev_id)))
-		return -ENODEV;
-
-	ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-
-	hci_dev_put(hdev);
-
-	return ret;
-}
-
-int hci_dev_setscan(unsigned long arg)
+int hci_dev_cmd(unsigned int cmd, unsigned long arg)
 {
 	struct hci_dev *hdev;
 	struct hci_dev_req dr;
-	int ret = 0;
+	int err = 0;
 
 	if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
 		return -EFAULT;
@@ -700,45 +619,75 @@
 	if (!(hdev = hci_dev_get(dr.dev_id)))
 		return -ENODEV;
 
-	ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-
-	hci_dev_put(hdev);
+	switch (cmd) {
+	case HCISETAUTH:
+		err = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
+		break;
 
-	return ret;
-}
+	case HCISETENCRYPT:
+		if (!lmp_encrypt_capable(hdev)) {
+			err = -EOPNOTSUPP;
+			break;
+		}
 
-int hci_dev_setptype(unsigned long arg)
-{
-	struct hci_dev *hdev;
-	struct hci_dev_req dr;
-	int ret = 0;
+		if (!test_bit(HCI_AUTH, &hdev->flags)) {
+			/* Auth must be enabled first */
+			err = hci_request(hdev, hci_auth_req,
+					dr.dev_opt, HCI_INIT_TIMEOUT);
+			if (err)
+				break;
+		}
+			
+		err = hci_request(hdev, hci_encrypt_req,
+					dr.dev_opt, HCI_INIT_TIMEOUT);
+		break;
+	
+	case HCISETSCAN:
+		err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
+		break;
+	
+	case HCISETPTYPE:
+		hdev->pkt_type = (__u16) dr.dev_opt;
+		break;
+		
+	case HCISETLINKPOL:
+		hdev->link_policy = (__u16) dr.dev_opt;
+		break;
 
-	if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-		return -EFAULT;
+	case HCISETLINKMODE:
+		hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT);
+		break;
 
-	if (!(hdev = hci_dev_get(dr.dev_id)))
-		return -ENODEV;
+	case HCISETACLMTU:
+		hdev->acl_mtu  = *((__u16 *)&dr.dev_opt + 1);
+		hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0);
+		break;
 
-	hdev->pkt_type = (__u16) dr.dev_opt;
+	case HCISETSCOMTU:
+		hdev->sco_mtu  = *((__u16 *)&dr.dev_opt + 1);
+		hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0);
+		break;
 
+	default:
+		err = -EINVAL;
+		break;
+	}	
 	hci_dev_put(hdev);
-
-	return ret;
+	return err;
 }
 
-int hci_dev_list(unsigned long arg)
+int hci_get_dev_list(unsigned long arg)
 {
 	struct hci_dev_list_req *dl;
 	struct hci_dev_req *dr;
-	struct hci_dev *hdev;
-	int i, n, size;
+	struct list_head *p;
+	int n = 0, size;
 	__u16 dev_num;
 
 	if (get_user(dev_num, (__u16 *) arg))
 		return -EFAULT;
 
-	/* Avoid long loop, overflow */
-	if (dev_num > 2048)
+	if (!dev_num)
 		return -EINVAL;
 	
 	size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
@@ -751,12 +700,13 @@
 	dr = dl->dev_req;
 
 	spin_lock_bh(&hdev_list_lock);
-	for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
-		if ((hdev = hdev_list[i])) {
-			(dr + n)->dev_id  = hdev->id;
-			(dr + n)->dev_opt = hdev->flags;
-			n++;
-		}
+	list_for_each(p, &hdev_list) {
+		struct hci_dev *hdev;
+		hdev = list_entry(p, struct hci_dev, list);
+		(dr + n)->dev_id  = hdev->id;
+		(dr + n)->dev_opt = hdev->flags;
+		if (++n >= dev_num)
+			break;
 	}
 	spin_unlock_bh(&hdev_list_lock);
 
@@ -764,11 +714,12 @@
 	size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
 
 	copy_to_user((void *) arg, dl, size);
+	kfree(dl);
 
 	return 0;
 }
 
-int hci_dev_info(unsigned long arg)
+int hci_get_dev_info(unsigned long arg)
 {
 	struct hci_dev *hdev;
 	struct hci_dev_info di;
@@ -786,9 +737,11 @@
 	di.flags    = hdev->flags;
 	di.pkt_type = hdev->pkt_type;
 	di.acl_mtu  = hdev->acl_mtu;
-	di.acl_max  = hdev->acl_max;
+	di.acl_pkts = hdev->acl_pkts;
 	di.sco_mtu  = hdev->sco_mtu;
-	di.sco_max  = hdev->sco_max;
+	di.sco_pkts = hdev->sco_pkts;
+	di.link_policy = hdev->link_policy;
+	di.link_mode   = hdev->link_mode;
 
 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
 	memcpy(&di.features, &hdev->features, sizeof(di.features));
@@ -801,258 +754,149 @@
 	return err;
 }
 
-__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
-{
-	__u32 omode = hdev->flags & HCI_MODE_MASK;
-
-	hdev->flags &= ~HCI_MODE_MASK;
-	hdev->flags |= (mode & HCI_MODE_MASK);
 
-	return omode;
-}
+/* ---- Interface to HCI drivers ---- */
 
-__u32 hci_dev_getmode(struct hci_dev *hdev)
+/* Register HCI device */
+int hci_register_dev(struct hci_dev *hdev)
 {
-	return hdev->flags & HCI_MODE_MASK;
-}
+	struct list_head *head = &hdev_list, *p;
+	int id = 0;
 
-int hci_conn_list(unsigned long arg)
-{
-	struct hci_conn_list_req req, *cl;
-	struct hci_conn_info *ci;
-	struct hci_dev *hdev;
-	struct list_head *p;
-	int n = 0, size;
+	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
-	if (copy_from_user(&req, (void *) arg, sizeof(req)))
-		return -EFAULT;
+	if (!hdev->open || !hdev->close || !hdev->destruct)
+		return -EINVAL;
 
-	if (!(hdev = hci_dev_get(req.dev_id)))
-		return -ENODEV;
+	spin_lock_bh(&hdev_list_lock);
 
-	/* Set a limit to avoid overlong loops, and also numeric overflow - AC */
-	if(req.conn_num < 2048)
-		return -EINVAL;
+	/* Find first available device id */
+	list_for_each(p, &hdev_list) {
+	       	if (list_entry(p, struct hci_dev, list)->id != id)
+			break;
+		head = p; id++;
+	}
 	
-	size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
+	sprintf(hdev->name, "hci%d", id);
+	hdev->id = id;
+	list_add(&hdev->list, head);
 
-	if (!(cl = kmalloc(size, GFP_KERNEL)))
-		return -ENOMEM;
-	ci = cl->conn_info;
+	atomic_set(&hdev->refcnt, 1);
+	spin_lock_init(&hdev->lock);
+			
+	hdev->flags = 0;
+	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
+	hdev->link_mode = (HCI_LM_ACCEPT);
 
-	local_bh_disable();
-	conn_hash_lock(&hdev->conn_hash);
-	list_for_each(p, &hdev->conn_hash.list) {
-		register struct hci_conn *c;
-		c = list_entry(p, struct hci_conn, list);
+	tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
+	tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
+	tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
 
-		(ci + n)->handle = c->handle;
-		bacpy(&(ci + n)->bdaddr, &c->dst);
-		n++;
-	}
-	conn_hash_unlock(&hdev->conn_hash);
-	local_bh_enable();
-
-	cl->dev_id = hdev->id;
-	cl->conn_num = n;
-	size = n * sizeof(struct hci_conn_info) + sizeof(req);
+	skb_queue_head_init(&hdev->rx_q);
+	skb_queue_head_init(&hdev->cmd_q);
+	skb_queue_head_init(&hdev->raw_q);
 
-	hci_dev_put(hdev);
+	init_waitqueue_head(&hdev->req_wait_q);
+	init_MUTEX(&hdev->req_lock);
 
-	if(copy_to_user((void *) arg, cl, size))
-		return -EFAULT;
-	return 0;
+	inquiry_cache_init(hdev);
+
+	conn_hash_init(hdev);
+
+	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
+
+	atomic_set(&hdev->promisc, 0);
+		
+	hci_notify(hdev, HCI_DEV_REG);
+
+	MOD_INC_USE_COUNT;
+
+	spin_unlock_bh(&hdev_list_lock);
+
+	return id;
 }
 
-int hci_inquiry(unsigned long arg)
+/* Unregister HCI device */
+int hci_unregister_dev(struct hci_dev *hdev)
 {
-	struct inquiry_cache *cache;
-	struct hci_inquiry_req ir;
-	struct hci_dev *hdev;
-	int err = 0, do_inquiry = 0;
-	long timeo;
-	__u8 *buf, *ptr;
+	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
-	ptr = (void *) arg;
-	if (copy_from_user(&ir, ptr, sizeof(ir)))
-		return -EFAULT;
+	spin_lock_bh(&hdev_list_lock);
+	list_del(&hdev->list);
+	spin_unlock_bh(&hdev_list_lock);
 
-	if (!(hdev = hci_dev_get(ir.dev_id)))
-		return -ENODEV;
+	hci_dev_do_close(hdev);
 
-	cache = &hdev->inq_cache;
+	hci_notify(hdev, HCI_DEV_UNREG);
+	hci_dev_put(hdev);
 
-	inquiry_cache_lock(cache);
-	if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
-		inquiry_cache_flush(cache);
-		do_inquiry = 1;
-	}
-	inquiry_cache_unlock(cache);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
 
-	/* Limit inquiry time, also avoid overflows */
+/* Receive frame from HCI drivers */
+int hci_recv_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 
-	if(ir.length > 2048 || ir.num_rsp > 2048)
-	{
-		err = -EINVAL;
-		goto done;
+	if (!hdev || (!test_bit(HCI_UP, &hdev->flags) && 
+				!test_bit(HCI_INIT, &hdev->flags)) ) {
+		kfree_skb(skb);
+		return -1;
 	}
 
-	timeo = ir.length * 2 * HZ;
-	if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-		goto done;
+	BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
-	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
-	 * copy it to the user space.
-	 */
-	if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto done;
-	}
-	ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
-
-	DBG("num_rsp %d", ir.num_rsp);
-
-	if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
-		copy_to_user(ptr, &ir, sizeof(ir));
-		ptr += sizeof(ir);
-	        copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-	} else 
-		err = -EFAULT;
-
-	kfree(buf);
-
-done:
-	hci_dev_put(hdev);
-
-	return err;
-}
-
-/* Interface to HCI drivers */
-
-/* Register HCI device */
-int hci_register_dev(struct hci_dev *hdev)
-{
-	int i;
-
-	DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-	/* Find free slot */
-	spin_lock_bh(&hdev_list_lock);
-	for (i = 0; i < HCI_MAX_DEV; i++) {
-		if (!hdev_list[i]) {
-			hdev_list[i] = hdev;
-
-			sprintf(hdev->name, "hci%d", i);
-			atomic_set(&hdev->refcnt, 0);
-			hdev->id    = i;
-			hdev->flags = HCI_NORMAL;
-
-			hdev->pkt_type = (HCI_DM1 | HCI_DH1);
-
-			tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
-			tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-			tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
-
-			skb_queue_head_init(&hdev->rx_q);
-			skb_queue_head_init(&hdev->cmd_q);
-			skb_queue_head_init(&hdev->raw_q);
-
-			init_waitqueue_head(&hdev->req_wait_q);
-			init_MUTEX(&hdev->req_lock);
-
-			inquiry_cache_init(&hdev->inq_cache);
-
-			conn_hash_init(&hdev->conn_hash);
-
-			memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
-
-			hci_notify(hdev, HCI_DEV_REG);
-
-			MOD_INC_USE_COUNT;
-			break;
-		}
-	}
-	spin_unlock_bh(&hdev_list_lock);
-
-	return (i == HCI_MAX_DEV) ? -1 : i;
-}
-
-/* Unregister HCI device */
-int hci_unregister_dev(struct hci_dev *hdev)
-{
-	int i;
-
-	DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-	if (hdev->flags & HCI_UP)
-		hci_dev_close(hdev->id);
-
-	/* Find device slot */
-	spin_lock(&hdev_list_lock);
-	for (i = 0; i < HCI_MAX_DEV; i++) {
-		if (hdev_list[i] == hdev) {
-			hdev_list[i] = NULL;
-			MOD_DEC_USE_COUNT;
-			break;
-		}
-	}
-	spin_unlock(&hdev_list_lock);
-
-	hci_notify(hdev, HCI_DEV_UNREG);
-
-	/* Sleep while device is in use */
-	while (atomic_read(&hdev->refcnt)) {
-		int sleep_cnt = 100;
-
-		DBG("%s sleeping on lock %d", hdev->name, atomic_read(&hdev->refcnt));
+	/* Incomming skb */
+	bluez_cb(skb)->incomming = 1;
 
-		sleep_on_timeout(&hdev->req_wait_q, HZ*10);
-		if (!(--sleep_cnt))
-			break;
-	}
+	/* Time stamp */
+	do_gettimeofday(&skb->stamp);
 
+	/* Queue frame for rx task */
+	skb_queue_tail(&hdev->rx_q, skb);
+	hci_sched_rx(hdev);
 	return 0;
 }
 
-/* Interface to upper protocols */
+/* ---- Interface to upper protocols ---- */
 
 /* Register/Unregister protocols.
- * hci_task_lock is used to ensure that no tasks are running.
- */
-int hci_register_proto(struct hci_proto *hproto)
+ * hci_task_lock is used to ensure that no tasks are running. */
+int hci_register_proto(struct hci_proto *hp)
 {
 	int err = 0;
 
-	DBG("%p name %s", hproto, hproto->name);
+	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
 
-	if (hproto->id >= HCI_MAX_PROTO)
+	if (hp->id >= HCI_MAX_PROTO)
 		return -EINVAL;
 
 	write_lock_bh(&hci_task_lock);
 
-	if (!hproto_list[hproto->id])
-		hproto_list[hproto->id] = hproto;
+	if (!hci_proto[hp->id])
+		hci_proto[hp->id] = hp;
 	else
-		err = -1;
+		err = -EEXIST;
 
 	write_unlock_bh(&hci_task_lock);
 
 	return err;
 }
 
-int hci_unregister_proto(struct hci_proto *hproto)
+int hci_unregister_proto(struct hci_proto *hp)
 {
 	int err = 0;
 
-	DBG("%p name %s", hproto, hproto->name);
+	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
 
-	if (hproto->id > HCI_MAX_PROTO)
+	if (hp->id >= HCI_MAX_PROTO)
 		return -EINVAL;
 
 	write_lock_bh(&hci_task_lock);
 
-	if (hproto_list[hproto->id])
-		hproto_list[hproto->id] = NULL;
+	if (hci_proto[hp->id])
+		hci_proto[hp->id] = NULL;
 	else
 		err = -ENOENT;
 
@@ -1070,10 +914,14 @@
 		return -ENODEV;
 	}
 
-	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+	BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+
+	if (atomic_read(&hdev->promisc)) {
+		/* Time stamp */
+	        do_gettimeofday(&skb->stamp);
 
-	if (hdev->flags & HCI_SOCK)
 		hci_send_to_sock(hdev, skb);
+	}
 
 	/* Get rid of skb owner, prior to sending to the driver. */
 	skb_orphan(skb);
@@ -1081,94 +929,6 @@
 	return hdev->send(skb);
 }
 
-/* Connection scheduler */
-static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
-{
-	struct conn_hash *h = &hdev->conn_hash;
-	struct hci_conn *conn = NULL;
-	int num = 0, min = 0xffff;
-        struct list_head *p;
-
-	conn_hash_lock(h);
-	list_for_each(p, &h->list) {
-		register struct hci_conn *c;
-
-		c = list_entry(p, struct hci_conn, list);
-
-		if (c->type != type || skb_queue_empty(&c->data_q))
-			continue;
-		num++;
-
-		if (c->sent < min) {
-			min  = c->sent;
-			conn = c;
-		}
-	}
-	conn_hash_unlock(h);
-
-	if (conn) {
-		int q = hdev->acl_cnt / num;
-		*quote = q ? q : 1;
-	} else
-		*quote = 0;
-
-	DBG("conn %p quote %d", conn, *quote);
-
-	return conn;
-}
-
-static inline void hci_sched_acl(struct hci_dev *hdev)
-{
-	struct hci_conn *conn;
-	struct sk_buff *skb;
-	int quote;
-
-	DBG("%s", hdev->name);
-
-	while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-		while (quote && (skb = skb_dequeue(&conn->data_q))) {
-			DBG("skb %p len %d", skb, skb->len);
-
-			hci_send_frame(skb);
-
-			conn->sent++;
-			hdev->acl_cnt--;
-			quote--;
-		}
-	}
-}
-
-/* Schedule SCO */
-static inline void hci_sched_sco(struct hci_dev *hdev)
-{
-	/* FIXME: For now we queue SCO packets to the raw queue 
-
-		while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
-			hci_send_frame(skb);
-			conn->sco_sent++;
-			hdev->sco_cnt--;
-		}
-	*/
-}
-
-/* Get data from the previously sent command */
-static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
-{
-	hci_command_hdr *hc;
-
-	if (!hdev->sent_cmd)
-		return NULL;
-
-	hc = (void *) hdev->sent_cmd->data;
-
-	if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-		return NULL;
-
-	DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
-
-	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
-}
-
 /* Send raw HCI frame */
 int hci_send_raw(struct sk_buff *skb)
 {
@@ -1179,9 +939,9 @@
 		return -ENODEV;
 	}
 
-	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+	BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
-	if (hdev->flags & HCI_NORMAL) {
+	if (!test_bit(HCI_RAW, &hdev->flags)) {
 		/* Queue frame according it's type */
 		switch (skb->pkt_type) {
 		case HCI_COMMAND_PKT:
@@ -1210,10 +970,10 @@
 	hci_command_hdr *hc;
 	struct sk_buff *skb;
 
-	DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
+	BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
 
 	if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-		ERR("%s Can't allocate memory for HCI command", hdev->name);
+		BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
 		return -ENOMEM;
 	}
 	
@@ -1224,7 +984,7 @@
 	if (plen)
 		memcpy(skb_put(skb, plen), param, plen);
 
-	DBG("skb len %d", skb->len);
+	BT_DBG("skb len %d", skb->len);
 
 	skb->pkt_type = HCI_COMMAND_PKT;
 	skb->dev = (void *) hdev;
@@ -1234,10 +994,28 @@
 	return 0;
 }
 
+/* Get data from the previously sent command */
+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
+{
+	hci_command_hdr *hc;
+
+	if (!hdev->sent_cmd)
+		return NULL;
+
+	hc = (void *) hdev->sent_cmd->data;
+
+	if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
+		return NULL;
+
+	BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
+
+	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
+}
+
 /* Send ACL data */
 static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
 {
-	int len = skb->len;	
+	int len = skb->len;
 	hci_acl_hdr *ah;
 
 	ah = (hci_acl_hdr *) skb_push(skb, HCI_ACL_HDR_SIZE);
@@ -1252,7 +1030,7 @@
 	struct hci_dev *hdev = conn->hdev;
 	struct sk_buff *list;
 
-	DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
+	BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
 
 	skb->dev = (void *) hdev;
 	skb->pkt_type = HCI_ACLDATA_PKT;
@@ -1260,12 +1038,12 @@
 
 	if (!(list = skb_shinfo(skb)->frag_list)) {
 		/* Non fragmented */
-		DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
+		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
 		
 		skb_queue_tail(&conn->data_q, skb);
 	} else {
 		/* Fragmented */
-		DBG("%s frag %p len %d", hdev->name, skb, skb->len);
+		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
 
 		skb_shinfo(skb)->frag_list = NULL;
 
@@ -1280,7 +1058,7 @@
 			skb->pkt_type = HCI_ACLDATA_PKT;
 			hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
 		
-			DBG("%s frag %p len %d", hdev->name, skb, skb->len);
+			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
 
 			__skb_queue_tail(&conn->data_q, skb);
 		} while (list);
@@ -1298,7 +1076,7 @@
 	struct hci_dev *hdev = conn->hdev;
 	hci_sco_hdr hs;
 
-	DBG("%s len %d", hdev->name, skb->len);
+	BT_DBG("%s len %d", hdev->name, skb->len);
 
 	if (skb->len > hdev->sco_mtu) {
 		kfree_skb(skb);
@@ -1315,544 +1093,119 @@
 	skb->pkt_type = HCI_SCODATA_PKT;
 	skb_queue_tail(&conn->data_q, skb);
 	hci_sched_tx(hdev);
-
 	return 0;
 }
 
-/* Handle HCI Event packets */
-
-/* Command Complete OGF LINK_CTL  */
-static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-{
-	DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	default:
-		DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-		break;
-	};
-}
-
-/* Command Complete OGF LINK_POLICY  */
-static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-{
-	DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	default:
-		DBG("%s: Command complete: ogf LINK_POLICY ocf %x", hdev->name, ocf);
-		break;
-	};
-}
-
-/* Command Complete OGF HOST_CTL  */
-static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-{
-	__u8 status, param;
-	void *sent;
-
-
-	DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	case OCF_RESET:
-		status = *((__u8 *) skb->data);
-
-		hci_req_complete(hdev, status);
-		break;
-
-	case OCF_SET_EVENT_FLT:
-		status = *((__u8 *) skb->data);
-
-		if (status) {
-			DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-		} else {
-			DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-		}
-		break;
-
-	case OCF_WRITE_AUTH_ENABLE:
-		if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
-			break;
-
-		status = *((__u8 *) skb->data);
-		param  = *((__u8 *) sent);
-
-		if (!status) {
-			if (param == AUTH_ENABLED)
-				hdev->flags |= HCI_AUTH;
-			else
-				hdev->flags &= ~HCI_AUTH;
-		}
-		hci_req_complete(hdev, status);
-		break;
-
-	case OCF_WRITE_CA_TIMEOUT:
-		status = *((__u8 *) skb->data);
-
-		if (status) {
-			DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-		} else {
-			DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-		}
-		break;
-
-	case OCF_WRITE_PG_TIMEOUT:
-		status = *((__u8 *) skb->data);
-
-		if (status) {
-			DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-		} else {
-			DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-		}
-		break;
-
-	case OCF_WRITE_SCAN_ENABLE:
-		if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
-			break;
-		status = *((__u8 *) skb->data);
-		param  = *((__u8 *) sent);
-
-		DBG("param 0x%x", param);
-
-		if (!status) {
-			switch (param) {
-			case IS_ENA_PS_ENA:
-				hdev->flags |=  HCI_PSCAN | HCI_ISCAN;
-				break;
-
-			case IS_ENA_PS_DIS:
-				hdev->flags &= ~HCI_PSCAN;
-				hdev->flags |=  HCI_ISCAN;
-				break;
-
-			case IS_DIS_PS_ENA:
-				hdev->flags &= ~HCI_ISCAN;
-				hdev->flags |=  HCI_PSCAN;
-				break;
-
-			default:
-				hdev->flags &= ~(HCI_ISCAN | HCI_PSCAN);
-				break;
-			};
-		}
-		hci_req_complete(hdev, status);
-		break;
-
-	default:
-		DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-		break;
-	};
-}
-
-/* Command Complete OGF INFO_PARAM  */
-static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-{
-	read_local_features_rp *lf;
-	read_buffer_size_rp *bs;
-	read_bd_addr_rp *ba;
-
-	DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	case OCF_READ_LOCAL_FEATURES:
-		lf = (read_local_features_rp *) skb->data;
-
-		if (lf->status) {
-			DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-			break;
-		}
-
-		memcpy(hdev->features, lf->features, sizeof(hdev->features));
-
-		/* Adjust default settings according to features 
-		 * supported by device. */
-		if (hdev->features[0] & LMP_3SLOT)
-			hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
-
-		if (hdev->features[0] & LMP_5SLOT)
-			hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
-
-		DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
-
-		break;
-
-	case OCF_READ_BUFFER_SIZE:
-		bs = (read_buffer_size_rp *) skb->data;
-
-		if (bs->status) {
-			DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-			break;
-		}
-
-		hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-		hdev->sco_mtu = bs->sco_mtu;
-		hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-		hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
-
-		DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-		    hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
-
-		break;
-
-	case OCF_READ_BD_ADDR:
-		ba = (read_bd_addr_rp *) skb->data;
-
-		if (!ba->status) {
-			bacpy(&hdev->bdaddr, &ba->bdaddr);
-		} else {
-			DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-		}
-
-		hci_req_complete(hdev, ba->status);
-		break;
-
-	default:
-		DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-		break;
-	};
-}
+/* ---- HCI TX task (outgoing data) ---- */
 
-/* Command Status OGF LINK_CTL  */
-static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+/* HCI Connection scheduler */
+static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
 {
-	struct hci_proto * hp;
-
-	DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	case OCF_CREATE_CONN:
-		if (status) {
-			create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
-
-			if (!cc)
-				break;
+	struct conn_hash *h = &hdev->conn_hash;
+	struct hci_conn  *conn = NULL;
+	int num = 0, min = ~0;
+        struct list_head *p;
 
-			DBG("%s Create connection error: status 0x%x %s", hdev->name,
-			    status, batostr(&cc->bdaddr));
+	/* We don't have to lock device here. Connections are always 
+	 * added and removed with TX task disabled. */
+	list_for_each(p, &h->list) {
+		struct hci_conn *c;
+		c = list_entry(p, struct hci_conn, list);
 
-			/* Notify upper protocols */
-			if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm) {
-				tasklet_disable(&hdev->tx_task);
-				hp->connect_cfm(hdev, &cc->bdaddr, status, NULL);
-				tasklet_enable(&hdev->tx_task);
-			}
-		}
-		break;
+		if (c->type != type || c->state != BT_CONNECTED
+				|| skb_queue_empty(&c->data_q))
+			continue;
+		num++;
 
-	case OCF_INQUIRY:
-		if (status) {
-			DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-			hci_req_complete(hdev, status);
+		if (c->sent < min) {
+			min  = c->sent;
+			conn = c;
 		}
-		break;
-
-	default:
-		DBG("%s Command status: ogf LINK_CTL ocf %x", hdev->name, ocf);
-		break;
-	};
-}
-
-/* Command Status OGF LINK_POLICY */
-static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
-{
-	DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	default:
-		DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-		break;
-	};
-}
-
-/* Command Status OGF HOST_CTL */
-static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-{
-	DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	default:
-		DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-		break;
-	};
-}
-
-/* Command Status OGF INFO_PARAM  */
-static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
-{
-	DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	default:
-		DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-		break;
-	};
-}
-
-/* Inquiry Complete */
-static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	__u8 status = *((__u8 *) skb->data);
+	}
 
-	DBG("%s status %d", hdev->name, status);
+	if (conn) {
+		int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
+		int q = cnt / num;
+		*quote = q ? q : 1;
+	} else
+		*quote = 0;
 
-	hci_req_complete(hdev, status);
+	BT_DBG("conn %p quote %d", conn, *quote);
+	return conn;
 }
 
-/* Inquiry Result */
-static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_sched_acl(struct hci_dev *hdev)
 {
-	inquiry_info *info = (inquiry_info *) (skb->data + 1);
-	int num_rsp = *((__u8 *) skb->data);
-
-	DBG("%s num_rsp %d", hdev->name, num_rsp);
+	struct hci_conn *conn;
+	struct sk_buff *skb;
+	int quote;
 
-	for (; num_rsp; num_rsp--)
-		inquiry_cache_update(&hdev->inq_cache, info++);
-}
+	BT_DBG("%s", hdev->name);
 
-/* Connect Request */
-static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	evt_conn_request *cr = (evt_conn_request *) skb->data;
-	struct hci_proto *hp;
-	accept_conn_req_cp ac;
-	int accept = 0;
+	/* ACL tx timeout must be longer than maximum
+	 * link supervision timeout (40.9 seconds) */
+	if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45)) {
+		BT_ERR("%s ACL tx timeout", hdev->name);
+		hdev->acl_cnt++;
+	}
 
-	DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
+	while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
+		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+			BT_DBG("skb %p len %d", skb, skb->len);
+			hci_send_frame(skb);
+			hdev->acl_last_tx = jiffies;
 
-	/* Notify upper protocols */
-	if (cr->link_type == ACL_LINK) {
-		/* ACL link notify L2CAP */
-		if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
-			tasklet_disable(&hdev->tx_task);
-			accept = hp->connect_ind(hdev, &cr->bdaddr);
-			tasklet_enable(&hdev->tx_task);
+			hdev->acl_cnt--;
+			conn->sent++;
 		}
-	} else {
-		/* SCO link (no notification) */
-		/* FIXME: Should be accept it here or let the requester (app) accept it ? */
-		accept = 1;
-	}
-
-	if (accept) {
-		/* Connection accepted by upper layer */
-		bacpy(&ac.bdaddr, &cr->bdaddr);
-		ac.role = 0x01; /* Remain slave */
-		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac);
-	} else {
-		/* Connection rejected by upper layer */
-		/* FIXME: 
-		 * Should we use HCI reject here ?
-		 */
-		return;
 	}
 }
 
-/* Connect Complete */
-static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+/* Schedule SCO */
+static inline void hci_sched_sco(struct hci_dev *hdev)
 {
-	evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-	struct hci_conn *conn = NULL;
-	struct hci_proto *hp;
-
-	DBG("%s", hdev->name);
-
-	tasklet_disable(&hdev->tx_task);
-
-	if (!cc->status)
- 		conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
+	struct hci_conn *conn;
+	struct sk_buff *skb;
+	int quote;
 
-	/* Notify upper protocols */
-	if (cc->link_type == ACL_LINK) {
-		/* ACL link notify L2CAP layer */
-		if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
-			hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
-	} else {
-		/* SCO link (no notification) */
-	}
+	BT_DBG("%s", hdev->name);
 
-	tasklet_enable(&hdev->tx_task);
-}
+	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
+		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+			BT_DBG("skb %p len %d", skb, skb->len);
+			hci_send_frame(skb);
 
-/* Disconnect Complete */
-static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-	struct hci_conn *conn = NULL;
-	struct hci_proto *hp;
-	__u16 handle = __le16_to_cpu(dc->handle);
-
-	DBG("%s", hdev->name);
-
-	if (!dc->status && (conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-		tasklet_disable(&hdev->tx_task);
-
-		/* Notify upper protocols */
-		if (conn->type == ACL_LINK) {
-			/* ACL link notify L2CAP layer */
-			if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-				hp->disconn_ind(conn, dc->reason);
-		} else {
-			/* SCO link (no notification) */
+			conn->sent++;
+			if (conn->sent == ~0)
+				conn->sent = 0;
 		}
-
-		hci_conn_del(hdev, conn);
-
-		tasklet_enable(&hdev->tx_task);
 	}
 }
 
-/* Number of completed packets */
-static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_tx_task(unsigned long arg)
 {
-	evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-	__u16 *ptr;
-	int i;
-
-	skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
-
-	DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
+	struct hci_dev *hdev = (struct hci_dev *) arg;
+	struct sk_buff *skb;
 
-	if (skb->len < nc->num_hndl * 4) {
-		DBG("%s bad parameters", hdev->name);
-		return;
-	}
+	read_lock(&hci_task_lock);
 
-	tasklet_disable(&hdev->tx_task);
+	BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
 
-	for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-		struct hci_conn *conn;
-		__u16 handle, count;
+	/* Schedule queues and send stuff to HCI driver */
 
-		handle = __le16_to_cpu(get_unaligned(ptr++));
-		count  = __le16_to_cpu(get_unaligned(ptr++));
+	hci_sched_acl(hdev);
 
-		hdev->acl_cnt += count;
+	hci_sched_sco(hdev);
 
-		if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
-			conn->sent -= count;
-	}
+	/* Send next queued raw (unknown type) packet */
+	while ((skb = skb_dequeue(&hdev->raw_q)))
+		hci_send_frame(skb);
 
-	tasklet_enable(&hdev->tx_task);
-	
-	hci_sched_tx(hdev);
+	read_unlock(&hci_task_lock);
 }
 
-static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	hci_event_hdr *he = (hci_event_hdr *) skb->data;
-	evt_cmd_status *cs;
-	evt_cmd_complete *ec;
-	__u16 opcode, ocf, ogf;
-
-	skb_pull(skb, HCI_EVENT_HDR_SIZE);
 
-	DBG("%s evt 0x%x", hdev->name, he->evt);
-
-	switch (he->evt) {
-	case EVT_NUM_COMP_PKTS:
-		hci_num_comp_pkts_evt(hdev, skb);
-		break;
-
-	case EVT_INQUIRY_COMPLETE:
-		hci_inquiry_complete_evt(hdev, skb);
-		break;
-
-	case EVT_INQUIRY_RESULT:
-		hci_inquiry_result_evt(hdev, skb);
-		break;
-
-	case EVT_CONN_REQUEST:
-		hci_conn_request_evt(hdev, skb);
-		break;
-
-	case EVT_CONN_COMPLETE:
-		hci_conn_complete_evt(hdev, skb);
-		break;
-
-	case EVT_DISCONN_COMPLETE:
-		hci_disconn_complete_evt(hdev, skb);
-		break;
-
-	case EVT_CMD_STATUS:
-		cs = (evt_cmd_status *) skb->data;
-		skb_pull(skb, EVT_CMD_STATUS_SIZE);
-				
-		opcode = __le16_to_cpu(cs->opcode);
-		ogf = cmd_opcode_ogf(opcode);
-		ocf = cmd_opcode_ocf(opcode);
-
-		switch (ogf) {
-		case OGF_INFO_PARAM:
-			hci_cs_info_param(hdev, ocf, cs->status);
-			break;
-
-		case OGF_HOST_CTL:
-			hci_cs_host_ctl(hdev, ocf, cs->status);
-			break;
-
-		case OGF_LINK_CTL:
-			hci_cs_link_ctl(hdev, ocf, cs->status);
-			break;
-
-		case OGF_LINK_POLICY:
-			hci_cs_link_policy(hdev, ocf, cs->status);
-			break;
-
-		default:
-			DBG("%s Command Status OGF %x", hdev->name, ogf);
-			break;
-		};
-
-		if (cs->ncmd) {
-			atomic_set(&hdev->cmd_cnt, 1);
-			if (!skb_queue_empty(&hdev->cmd_q))
-				hci_sched_cmd(hdev);
-		}
-		break;
-
-	case EVT_CMD_COMPLETE:
-		ec = (evt_cmd_complete *) skb->data;
-		skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
-
-		opcode = __le16_to_cpu(ec->opcode);
-		ogf = cmd_opcode_ogf(opcode);
-		ocf = cmd_opcode_ocf(opcode);
-
-		switch (ogf) {
-		case OGF_INFO_PARAM:
-			hci_cc_info_param(hdev, ocf, skb);
-			break;
-
-		case OGF_HOST_CTL:
-			hci_cc_host_ctl(hdev, ocf, skb);
-			break;
-
-		case OGF_LINK_CTL:
-			hci_cc_link_ctl(hdev, ocf, skb);
-			break;
-
-		case OGF_LINK_POLICY:
-			hci_cc_link_policy(hdev, ocf, skb);
-			break;
-
-		default:
-			DBG("%s Command Completed OGF %x", hdev->name, ogf);
-			break;
-		};
-
-		if (ec->ncmd) {
-			atomic_set(&hdev->cmd_cnt, 1);
-			if (!skb_queue_empty(&hdev->cmd_q))
-				hci_sched_cmd(hdev);
-		}
-		break;
-	};
-
-	kfree_skb(skb);
-	hdev->stat.evt_rx++;
-}
+/* ----- HCI RX task (incomming data proccessing) ----- */
 
 /* ACL data packet */
 static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1867,51 +1220,86 @@
 	flags  = acl_flags(handle);
 	handle = acl_handle(handle);
 
-	DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
+	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
 
-	if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
+	hdev->stat.acl_rx++;
+
+	hci_dev_lock(hdev);
+	conn = conn_hash_lookup_handle(hdev, handle);
+	hci_dev_unlock(hdev);
+	
+	if (conn) {
 		register struct hci_proto *hp;
 
 		/* Send to upper protocol */
-		if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
+		if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
 			hp->recv_acldata(conn, skb, flags);
-			goto sent;
+			return;
 		}
 	} else {
-		ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
+		BT_ERR("%s ACL packet for unknown connection handle %d", 
+			hdev->name, handle);
 	}
 
 	kfree_skb(skb);
-sent:
-	hdev->stat.acl_rx++;
 }
 
 /* SCO data packet */
 static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	DBG("%s len %d", hdev->name, skb->len);
+	hci_sco_hdr *sh = (void *) skb->data;
+	struct hci_conn *conn;
+	__u16 handle;
+
+	skb_pull(skb, HCI_SCO_HDR_SIZE);
+
+	handle = __le16_to_cpu(sh->handle);
+
+	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
 
-	kfree_skb(skb);
 	hdev->stat.sco_rx++;
+
+	hci_dev_lock(hdev);
+	conn = conn_hash_lookup_handle(hdev, handle);
+	hci_dev_unlock(hdev);
+	
+	if (conn) {
+		register struct hci_proto *hp;
+
+		/* Send to upper protocol */
+		if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
+			hp->recv_scodata(conn, skb);
+			return;
+		}
+	} else {
+		BT_ERR("%s SCO packet for unknown connection handle %d", 
+			hdev->name, handle);
+	}
+
+	kfree_skb(skb);
 }
 
-/* ----- HCI tasks ----- */
 void hci_rx_task(unsigned long arg)
 {
 	struct hci_dev *hdev = (struct hci_dev *) arg;
 	struct sk_buff *skb;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	read_lock(&hci_task_lock);
 
 	while ((skb = skb_dequeue(&hdev->rx_q))) {
-		if (hdev->flags & HCI_SOCK) {
+		if (atomic_read(&hdev->promisc)) {
 			/* Send copy to the sockets */
 			hci_send_to_sock(hdev, skb);
 		}
 
-		if (hdev->flags & HCI_INIT) {
+		if (test_bit(HCI_RAW, &hdev->flags)) {
+			kfree_skb(skb);
+			continue;
+		}
+
+		if (test_bit(HCI_INIT, &hdev->flags)) {
 			/* Don't process data packets in this states. */
 			switch (skb->pkt_type) {
 			case HCI_ACLDATA_PKT:
@@ -1921,64 +1309,43 @@
 			};
 		}
 
-		if (hdev->flags & HCI_NORMAL) {
-			/* Process frame */
-			switch (skb->pkt_type) {
-			case HCI_EVENT_PKT:
-				hci_event_packet(hdev, skb);
-				break;
+		/* Process frame */
+		switch (skb->pkt_type) {
+		case HCI_EVENT_PKT:
+			hci_event_packet(hdev, skb);
+			break;
 
-			case HCI_ACLDATA_PKT:
-				DBG("%s ACL data packet", hdev->name);
-				hci_acldata_packet(hdev, skb);
-				break;
+		case HCI_ACLDATA_PKT:
+			BT_DBG("%s ACL data packet", hdev->name);
+			hci_acldata_packet(hdev, skb);
+			break;
 
-			case HCI_SCODATA_PKT:
-				DBG("%s SCO data packet", hdev->name);
-				hci_scodata_packet(hdev, skb);
-				break;
+		case HCI_SCODATA_PKT:
+			BT_DBG("%s SCO data packet", hdev->name);
+			hci_scodata_packet(hdev, skb);
+			break;
 
-			default:
-				kfree_skb(skb);
-				break;
-			};
-		} else {
+		default:
 			kfree_skb(skb);
+			break;
 		}
 	}
 
 	read_unlock(&hci_task_lock);
 }
 
-static void hci_tx_task(unsigned long arg)
-{
-	struct hci_dev *hdev = (struct hci_dev *) arg;
-	struct sk_buff *skb;
-
-	read_lock(&hci_task_lock);
-
-	DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
-
-	/* Schedule queues and send stuff to HCI driver */
-
-	hci_sched_acl(hdev);
-
-	hci_sched_sco(hdev);
-
-	/* Send next queued raw (unknown type) packet */
-	while ((skb = skb_dequeue(&hdev->raw_q)))
-		hci_send_frame(skb);
-
-	read_unlock(&hci_task_lock);
-}
-
 static void hci_cmd_task(unsigned long arg)
 {
 	struct hci_dev *hdev = (struct hci_dev *) arg;
 	struct sk_buff *skb;
 
-	DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
+	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
 
+	if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
+		BT_ERR("%s command tx timeout", hdev->name);
+		atomic_set(&hdev->cmd_cnt, 1);
+	}
+	
 	/* Send queued commands */
 	if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
 		if (hdev->sent_cmd)
@@ -1987,6 +1354,7 @@
 		if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
 			atomic_dec(&hdev->cmd_cnt);
 			hci_send_frame(skb);
+			hdev->cmd_last_tx = jiffies;
 		} else {
 			skb_queue_head(&hdev->cmd_q, skb);
 			hci_sched_cmd(hdev);
@@ -1994,27 +1362,7 @@
 	}
 }
 
-/* Receive frame from HCI drivers */
-int hci_recv_frame(struct sk_buff *skb)
-{
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-
-	if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
-		kfree_skb(skb);
-		return -1;
-	}
-
-	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-	/* Incomming skb */
-	bluez_cb(skb)->incomming = 1;
-
-	/* Queue frame for rx task */
-	skb_queue_tail(&hdev->rx_q, skb);
-	hci_sched_rx(hdev);
-
-	return 0;
-}
+/* ---- Initialization ---- */
 
 int hci_core_init(void)
 {
@@ -2028,5 +1376,3 @@
 {
 	return 0;
 }
-
-MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/hci_event.c linux/net/bluetooth/hci_event.c
--- linux.orig/net/bluetooth/hci_event.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/bluetooth/hci_event.c	2002-07-20 01:08:39.000000000 +0000
@@ -0,0 +1,874 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * HCI Events.
+ *
+ * $Id: hci_event.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <net/sock.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifndef HCI_CORE_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#endif
+
+/* Handle HCI Event packets */
+
+/* Command Complete OGF LINK_CTL  */
+static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+{
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Complete OGF LINK_POLICY  */
+static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+{
+	struct hci_conn *conn;
+	role_discovery_rp *rd;
+
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	case OCF_ROLE_DISCOVERY: 
+		rd = (void *) skb->data;
+
+		if (rd->status)
+			break;
+		
+		hci_dev_lock(hdev);
+	
+		conn = conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
+		if (conn) {
+			if (rd->role)
+				conn->link_mode &= ~HCI_LM_MASTER;
+			else
+				conn->link_mode |= HCI_LM_MASTER;
+		}
+			
+		hci_dev_unlock(hdev);
+		break;
+
+	default:
+		BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", 
+				hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Complete OGF HOST_CTL  */
+static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+{
+	__u8 status, param;
+	void *sent;
+
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	case OCF_RESET:
+		status = *((__u8 *) skb->data);
+		hci_req_complete(hdev, status);
+		break;
+
+	case OCF_SET_EVENT_FLT:
+		status = *((__u8 *) skb->data);
+		if (status) {
+			BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
+		} else {
+			BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
+		}
+		break;
+
+	case OCF_WRITE_AUTH_ENABLE:
+		sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
+		if (!sent)
+			break;
+
+		status = *((__u8 *) skb->data);
+		param  = *((__u8 *) sent);
+
+		if (!status) {
+			if (param == AUTH_ENABLED)
+				set_bit(HCI_AUTH, &hdev->flags);
+			else
+				clear_bit(HCI_AUTH, &hdev->flags);
+		}
+		hci_req_complete(hdev, status);
+		break;
+
+	case OCF_WRITE_ENCRYPT_MODE:
+		sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
+		if (!sent)
+			break;
+
+		status = *((__u8 *) skb->data);
+		param  = *((__u8 *) sent);
+
+		if (!status) {
+			if (param)
+				set_bit(HCI_ENCRYPT, &hdev->flags);
+			else
+				clear_bit(HCI_ENCRYPT, &hdev->flags);
+		}
+		hci_req_complete(hdev, status);
+		break;
+
+	case OCF_WRITE_CA_TIMEOUT:
+		status = *((__u8 *) skb->data);
+		if (status) {
+			BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
+		} else {
+			BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
+		}
+		break;
+
+	case OCF_WRITE_PG_TIMEOUT:
+		status = *((__u8 *) skb->data);
+		if (status) {
+			BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
+		} else {
+			BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
+		}
+		break;
+
+	case OCF_WRITE_SCAN_ENABLE:
+		sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
+		if (!sent)
+			break;
+		status = *((__u8 *) skb->data);
+		param  = *((__u8 *) sent);
+
+		BT_DBG("param 0x%x", param);
+
+		if (!status) {
+			clear_bit(HCI_PSCAN, &hdev->flags);
+			clear_bit(HCI_ISCAN, &hdev->flags);
+			if (param & SCAN_INQUIRY) 
+				set_bit(HCI_ISCAN, &hdev->flags);
+
+			if (param & SCAN_PAGE) 
+				set_bit(HCI_PSCAN, &hdev->flags);
+		}
+		hci_req_complete(hdev, status);
+		break;
+
+	case OCF_HOST_BUFFER_SIZE:
+		status = *((__u8 *) skb->data);
+		if (status) {
+			BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
+			hci_req_complete(hdev, status);
+		}
+		break;
+
+	default:
+		BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Complete OGF INFO_PARAM  */
+static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+{
+	read_local_features_rp *lf;
+	read_buffer_size_rp *bs;
+	read_bd_addr_rp *ba;
+
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	case OCF_READ_LOCAL_FEATURES:
+		lf = (read_local_features_rp *) skb->data;
+
+		if (lf->status) {
+			BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
+			break;
+		}
+
+		memcpy(hdev->features, lf->features, sizeof(hdev->features));
+
+		/* Adjust default settings according to features 
+		 * supported by device. */
+		if (hdev->features[0] & LMP_3SLOT)
+			hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
+
+		if (hdev->features[0] & LMP_5SLOT)
+			hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
+
+		if (hdev->features[1] & LMP_HV2)
+			hdev->pkt_type |= (HCI_HV2);
+
+		if (hdev->features[1] & LMP_HV3)
+			hdev->pkt_type |= (HCI_HV3);
+
+		BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
+
+		break;
+
+	case OCF_READ_BUFFER_SIZE:
+		bs = (read_buffer_size_rp *) skb->data;
+
+		if (bs->status) {
+			BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
+			hci_req_complete(hdev, bs->status);
+			break;
+		}
+
+		hdev->acl_mtu  = __le16_to_cpu(bs->acl_mtu);
+		hdev->sco_mtu  = bs->sco_mtu ? bs->sco_mtu : 64;
+		hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
+		hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
+
+		BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
+		    hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
+		break;
+
+	case OCF_READ_BD_ADDR:
+		ba = (read_bd_addr_rp *) skb->data;
+
+		if (!ba->status) {
+			bacpy(&hdev->bdaddr, &ba->bdaddr);
+		} else {
+			BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
+		}
+
+		hci_req_complete(hdev, ba->status);
+		break;
+
+	default:
+		BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Status OGF LINK_CTL  */
+static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
+{
+	struct hci_conn *conn;
+	create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
+
+	if (!cc)
+		return;
+
+	hci_dev_lock(hdev);
+	
+	conn = conn_hash_lookup_ba(hdev, ACL_LINK, &cc->bdaddr);
+
+	BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name, 
+			status, batostr(&cc->bdaddr), conn);
+
+	if (status) {
+		if (conn) {
+			conn->state = BT_CLOSED;
+			hci_proto_connect_cfm(conn, status);
+			hci_conn_del(conn);
+		}
+	} else {
+		if (!conn) {
+			conn = hci_conn_add(hdev, ACL_LINK, &cc->bdaddr);
+			if (conn) {
+				conn->out = 1;
+				conn->link_mode |= HCI_LM_MASTER;
+			} else
+				BT_ERR("No memmory for new connection");
+		}
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	case OCF_CREATE_CONN:
+		hci_cs_create_conn(hdev, status);
+		break;
+
+	case OCF_ADD_SCO:
+		if (status) {
+			struct hci_conn *acl, *sco;
+			add_sco_cp *cp = hci_sent_cmd_data(hdev, 
+						OGF_LINK_CTL, OCF_ADD_SCO);
+			__u16 handle;
+
+			if (!cp)
+				break;
+
+			handle = __le16_to_cpu(cp->handle);
+
+			BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
+
+			hci_dev_lock(hdev);
+	
+			acl = conn_hash_lookup_handle(hdev, handle);
+			if (!acl || !(sco = acl->link)) {
+				hci_dev_unlock(hdev);
+				break;
+			}
+
+			sco->state = BT_CLOSED;
+
+			hci_proto_connect_cfm(sco, status);
+			hci_conn_del(sco);
+
+			hci_dev_unlock(hdev);
+		}
+		break;
+
+	case OCF_INQUIRY:
+		if (status) {
+			BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
+			hci_req_complete(hdev, status);
+		} else {
+			set_bit(HCI_INQUIRY, &hdev->flags);
+		}
+		break;
+
+	default:
+		BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d", 
+			hdev->name, ocf, status);
+		break;
+	};
+}
+
+/* Command Status OGF LINK_POLICY */
+static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Status OGF HOST_CTL */
+static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Status OGF INFO_PARAM  */
+static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Inquiry Complete */
+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+
+	BT_DBG("%s status %d", hdev->name, status);
+
+	clear_bit(HCI_INQUIRY, &hdev->flags);
+	hci_req_complete(hdev, status);
+}
+
+/* Inquiry Result */
+static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	inquiry_info *info = (inquiry_info *) (skb->data + 1);
+	int num_rsp = *((__u8 *) skb->data);
+
+	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+	hci_dev_lock(hdev);
+	for (; num_rsp; num_rsp--)
+		inquiry_cache_update(hdev, info++);
+	hci_dev_unlock(hdev);
+}
+
+/* Connect Request */
+static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_conn_request *cr = (evt_conn_request *) skb->data;
+	int mask = hdev->link_mode;
+
+	BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
+			batostr(&cr->bdaddr), cr->link_type);
+
+	mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);
+
+	if (mask & HCI_LM_ACCEPT) {
+		/* Connection accepted */
+		struct hci_conn *conn;
+		accept_conn_req_cp ac;
+
+		hci_dev_lock(hdev);
+		conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
+		if (!conn) {
+			if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
+				BT_ERR("No memmory for new connection");
+				hci_dev_unlock(hdev);
+				return;
+			}
+		}
+		conn->state = BT_CONNECT;
+		hci_dev_unlock(hdev);
+
+		bacpy(&ac.bdaddr, &cr->bdaddr);
+	
+		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+			ac.role = 0x00; /* Become master */
+		else
+			ac.role = 0x01; /* Remain slave */
+
+		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, 
+				ACCEPT_CONN_REQ_CP_SIZE, &ac);
+	} else {
+		/* Connection rejected */
+		reject_conn_req_cp rc;
+
+		bacpy(&rc.bdaddr, &cr->bdaddr);
+		rc.reason = 0x0f;
+		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,
+				REJECT_CONN_REQ_CP_SIZE, &rc);
+	}
+}
+
+/* Connect Complete */
+static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_conn_complete *cc = (evt_conn_complete *) skb->data;
+	struct hci_conn *conn = NULL;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+	
+	conn = conn_hash_lookup_ba(hdev, cc->link_type, &cc->bdaddr);
+	if (!conn) {
+		hci_dev_unlock(hdev);
+		return;
+	}
+
+	if (!cc->status) {
+		conn->handle = __le16_to_cpu(cc->handle);
+		conn->state  = BT_CONNECTED;
+
+		if (test_bit(HCI_AUTH, &hdev->flags))
+			conn->link_mode |= HCI_LM_AUTH;
+		
+		if (test_bit(HCI_ENCRYPT, &hdev->flags))
+			conn->link_mode |= HCI_LM_ENCRYPT;
+
+
+		/* Set link policy */
+		if (conn->type == ACL_LINK && hdev->link_policy) {
+			write_link_policy_cp lp;
+			lp.handle = cc->handle;
+			lp.policy = __cpu_to_le16(hdev->link_policy);
+			hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,
+				WRITE_LINK_POLICY_CP_SIZE, &lp);
+		}
+
+		/* Set packet type for incomming connection */
+		if (!conn->out) {
+			change_conn_ptype_cp cp;
+			cp.handle = cc->handle;
+			cp.pkt_type = (conn->type == ACL_LINK) ? 
+				__cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
+				__cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
+
+			hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE,
+				CHANGE_CONN_PTYPE_CP_SIZE, &cp);
+		}
+	} else
+		conn->state = BT_CLOSED;
+
+	if (conn->type == ACL_LINK) {
+		struct hci_conn *sco = conn->link;
+		if (sco) {
+			if (!cc->status)
+				hci_add_sco(sco, conn->handle);
+			else {
+				hci_proto_connect_cfm(sco, cc->status);
+				hci_conn_del(sco);
+			}
+		}
+	}
+
+	hci_proto_connect_cfm(conn, cc->status);
+	if (cc->status)
+		hci_conn_del(conn);
+
+	hci_dev_unlock(hdev);
+}
+
+/* Disconnect Complete */
+static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
+	struct hci_conn *conn = NULL;
+	__u16 handle = __le16_to_cpu(dc->handle);
+
+	BT_DBG("%s status %d", hdev->name, dc->status);
+
+	if (dc->status)
+		return;
+
+	hci_dev_lock(hdev);
+	
+	conn = conn_hash_lookup_handle(hdev, handle);
+	if (conn) {
+		conn->state = BT_CLOSED;
+		hci_proto_disconn_ind(conn, dc->reason);
+		hci_conn_del(conn);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+/* Number of completed packets */
+static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
+	__u16 *ptr;
+	int i;
+
+	skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
+
+	BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
+
+	if (skb->len < nc->num_hndl * 4) {
+		BT_DBG("%s bad parameters", hdev->name);
+		return;
+	}
+
+	tasklet_disable(&hdev->tx_task);
+
+	for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
+		struct hci_conn *conn;
+		__u16  handle, count;
+
+		handle = __le16_to_cpu(get_unaligned(ptr++));
+		count  = __le16_to_cpu(get_unaligned(ptr++));
+
+		conn = conn_hash_lookup_handle(hdev, handle);
+		if (conn) {
+			conn->sent -= count;
+
+			if (conn->type == SCO_LINK) {
+				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+					hdev->sco_cnt = hdev->sco_pkts;
+			} else {
+				if ((hdev->acl_cnt += count) > hdev->acl_pkts)
+					hdev->acl_cnt = hdev->acl_pkts;
+			}
+		}
+	}
+	hci_sched_tx(hdev);
+
+	tasklet_enable(&hdev->tx_task);
+}
+
+/* Role Change */
+static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_role_change *rc = (evt_role_change *) skb->data;
+	struct hci_conn *conn = NULL;
+
+	BT_DBG("%s status %d", hdev->name, rc->status);
+
+	if (rc->status)
+		return;
+
+	hci_dev_lock(hdev);
+	
+	conn = conn_hash_lookup_ba(hdev, ACL_LINK, &rc->bdaddr);
+	if (conn) {
+		if (rc->role)
+			conn->link_mode &= ~HCI_LM_MASTER;
+		else 
+			conn->link_mode |= HCI_LM_MASTER;
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+/* Authentication Complete */
+static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_auth_complete *ac = (evt_auth_complete *) skb->data;
+	struct hci_conn *conn = NULL;
+	__u16 handle = __le16_to_cpu(ac->handle);
+
+	BT_DBG("%s status %d", hdev->name, ac->status);
+
+	hci_dev_lock(hdev);
+	
+	conn = conn_hash_lookup_handle(hdev, handle);
+	if (conn) {
+		if (!ac->status)
+			conn->link_mode |= HCI_LM_AUTH;
+		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
+
+		hci_proto_auth_cfm(conn, ac->status);
+		
+		if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
+			if (!ac->status) {
+				set_conn_encrypt_cp ce;
+				ce.handle  = __cpu_to_le16(conn->handle);
+				ce.encrypt = 1;
+				hci_send_cmd(conn->hdev, OGF_LINK_CTL,
+						OCF_SET_CONN_ENCRYPT,
+						SET_CONN_ENCRYPT_CP_SIZE, &ce);
+			} else {
+				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+				hci_proto_encrypt_cfm(conn, ac->status);
+			}
+		}
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+/* Encryption Change */
+static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_encrypt_change *ec = (evt_encrypt_change *) skb->data;
+	struct hci_conn *conn = NULL;
+	__u16 handle = __le16_to_cpu(ec->handle);
+
+	BT_DBG("%s status %d", hdev->name, ec->status);
+
+	hci_dev_lock(hdev);
+	
+	conn = conn_hash_lookup_handle(hdev, handle);
+	if (conn) {
+		if (!ec->status) {
+		       	if (ec->encrypt)
+				conn->link_mode |= HCI_LM_ENCRYPT;
+			else
+				conn->link_mode &= ~HCI_LM_ENCRYPT;
+		}
+		clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+		
+		hci_proto_encrypt_cfm(conn, ec->status);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	hci_event_hdr *he = (hci_event_hdr *) skb->data;
+	evt_cmd_status *cs;
+	evt_cmd_complete *ec;
+	__u16 opcode, ocf, ogf;
+
+	skb_pull(skb, HCI_EVENT_HDR_SIZE);
+
+	BT_DBG("%s evt 0x%x", hdev->name, he->evt);
+
+	switch (he->evt) {
+	case EVT_NUM_COMP_PKTS:
+		hci_num_comp_pkts_evt(hdev, skb);
+		break;
+
+	case EVT_INQUIRY_COMPLETE:
+		hci_inquiry_complete_evt(hdev, skb);
+		break;
+
+	case EVT_INQUIRY_RESULT:
+		hci_inquiry_result_evt(hdev, skb);
+		break;
+
+	case EVT_CONN_REQUEST:
+		hci_conn_request_evt(hdev, skb);
+		break;
+
+	case EVT_CONN_COMPLETE:
+		hci_conn_complete_evt(hdev, skb);
+		break;
+
+	case EVT_DISCONN_COMPLETE:
+		hci_disconn_complete_evt(hdev, skb);
+		break;
+
+	case EVT_ROLE_CHANGE:
+		hci_role_change_evt(hdev, skb);
+		break;
+
+	case EVT_AUTH_COMPLETE:
+		hci_auth_complete_evt(hdev, skb);
+		break;
+
+	case EVT_ENCRYPT_CHANGE:
+		hci_encrypt_change_evt(hdev, skb);
+		break;
+
+	case EVT_CMD_STATUS:
+		cs = (evt_cmd_status *) skb->data;
+		skb_pull(skb, EVT_CMD_STATUS_SIZE);
+				
+		opcode = __le16_to_cpu(cs->opcode);
+		ogf = cmd_opcode_ogf(opcode);
+		ocf = cmd_opcode_ocf(opcode);
+
+		switch (ogf) {
+		case OGF_INFO_PARAM:
+			hci_cs_info_param(hdev, ocf, cs->status);
+			break;
+
+		case OGF_HOST_CTL:
+			hci_cs_host_ctl(hdev, ocf, cs->status);
+			break;
+
+		case OGF_LINK_CTL:
+			hci_cs_link_ctl(hdev, ocf, cs->status);
+			break;
+
+		case OGF_LINK_POLICY:
+			hci_cs_link_policy(hdev, ocf, cs->status);
+			break;
+
+		default:
+			BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
+			break;
+		};
+
+		if (cs->ncmd) {
+			atomic_set(&hdev->cmd_cnt, 1);
+			if (!skb_queue_empty(&hdev->cmd_q))
+				hci_sched_cmd(hdev);
+		}
+		break;
+
+	case EVT_CMD_COMPLETE:
+		ec = (evt_cmd_complete *) skb->data;
+		skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
+
+		opcode = __le16_to_cpu(ec->opcode);
+		ogf = cmd_opcode_ogf(opcode);
+		ocf = cmd_opcode_ocf(opcode);
+
+		switch (ogf) {
+		case OGF_INFO_PARAM:
+			hci_cc_info_param(hdev, ocf, skb);
+			break;
+
+		case OGF_HOST_CTL:
+			hci_cc_host_ctl(hdev, ocf, skb);
+			break;
+
+		case OGF_LINK_CTL:
+			hci_cc_link_ctl(hdev, ocf, skb);
+			break;
+
+		case OGF_LINK_POLICY:
+			hci_cc_link_policy(hdev, ocf, skb);
+			break;
+
+		default:
+			BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
+			break;
+		};
+
+		if (ec->ncmd) {
+			atomic_set(&hdev->cmd_cnt, 1);
+			if (!skb_queue_empty(&hdev->cmd_q))
+				hci_sched_cmd(hdev);
+		}
+		break;
+	};
+
+	kfree_skb(skb);
+	hdev->stat.evt_rx++;
+}
+
+/* General internal stack event */
+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
+{
+	hci_event_hdr *eh;
+	evt_stack_internal *si;
+	struct sk_buff *skb;
+	int size;
+	void *ptr;
+
+	size = HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE + dlen;
+	skb  = bluez_skb_alloc(size, GFP_ATOMIC);
+	if (!skb)
+		return;
+
+	ptr = skb_put(skb, size);
+
+	eh = ptr;
+       	eh->evt  = EVT_STACK_INTERNAL;
+	eh->plen = EVT_STACK_INTERNAL_SIZE + dlen;
+	ptr += HCI_EVENT_HDR_SIZE;
+
+	si = ptr;
+	si->type = type;
+	memcpy(si->data, data, dlen);
+	
+	skb->pkt_type = HCI_EVENT_PKT;
+	skb->dev = (void *) hdev;
+	hci_send_to_sock(hdev, skb);
+	kfree_skb(skb);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/hci_sock.c linux/net/bluetooth/hci_sock.c
--- linux.orig/net/bluetooth/hci_sock.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/net/bluetooth/hci_sock.c	2002-07-20 01:08:22.000000000 +0000
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI socket layer.
  *
- * $Id: hci_sock.c,v 1.9 2001/08/05 06:02:16 maxk Exp $
+ * $Id: hci_sock.c,v 1.4 2002/04/18 22:26:14 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -51,43 +51,48 @@
 #include <asm/uaccess.h>
 
 #include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
 #include <net/bluetooth/hci_core.h>
 
 #ifndef HCI_SOCK_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
-/* HCI socket interface */
+/* ----- HCI socket interface ----- */
+
+/* Security filter */
+static struct hci_sec_filter hci_sec_filter = {
+	/* Packet types */
+	0x10,
+	/* Events */
+	{ 0xd9fe, 0x0 },
+	/* Commands */
+	{
+		/* OGF_LINK_CTL */
+		{ 0x2a000002, 0x0, 0x0, 0x0 },
+		/* OGF_LINK_POLICY */
+		{ 0x1200, 0x0, 0x0, 0x0     },
+		/* OGF_HOST_CTL */
+		{ 0x80100000, 0xa, 0x0, 0x0 },
+		/* OGF_INFO_PARAM */
+		{ 0x22a, 0x0, 0x0, 0x0      }
+	}
+};
 
 static struct bluez_sock_list hci_sk_list = {
 	lock: RW_LOCK_UNLOCKED
 };
 
-static struct sock *hci_sock_lookup(struct hci_dev *hdev)
-{
-	struct sock *sk;
-
-	read_lock(&hci_sk_list.lock);
-	for (sk = hci_sk_list.head; sk; sk = sk->next) {
-		if (hci_pi(sk)->hdev == hdev)
-			break;
-	}
-	read_unlock(&hci_sk_list.lock);
-	return sk;
-}
-
 /* Send frame to RAW socket */
 void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct sock * sk;
 
-	DBG("hdev %p len %d", hdev, skb->len);
+	BT_DBG("hdev %p len %d", hdev, skb->len);
 
 	read_lock(&hci_sk_list.lock);
 	for (sk = hci_sk_list.head; sk; sk = sk->next) {
-		struct hci_filter *flt;	
+		struct hci_filter *flt;
 		struct sk_buff *nskb;
 
 		if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
@@ -100,13 +105,19 @@
 		/* Apply filter */
 		flt = &hci_pi(sk)->filter;
 
-		if (!test_bit(skb->pkt_type, &flt->type_mask))
+		if (!hci_test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
 			continue;
 
 		if (skb->pkt_type == HCI_EVENT_PKT) {
-			register int evt = (*(__u8 *)skb->data & 63);
+			register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
+			
+			if (!hci_test_bit(evt, &flt->event_mask))
+				continue;
 
-			if (!test_bit(evt, &flt->event_mask))
+			if (flt->opcode && ((evt == EVT_CMD_COMPLETE && 
+					flt->opcode != *(__u16 *)(skb->data + 3)) ||
+					(evt == EVT_CMD_STATUS && 
+					flt->opcode != *(__u16 *)(skb->data + 4))))
 				continue;
 		}
 
@@ -116,8 +127,9 @@
 		/* Put type byte before the data */
 		memcpy(skb_push(nskb, 1), &nskb->pkt_type, 1);
 
-		skb_queue_tail(&sk->receive_queue, nskb);
-		sk->data_ready(sk, nskb->len);
+		if (sock_queue_rcv_skb(sk, nskb))
+			kfree_skb(nskb);
+		
 	}
 	read_unlock(&hci_sk_list.lock);
 }
@@ -127,7 +139,7 @@
 	struct sock *sk = sock->sk;
 	struct hci_dev *hdev = hci_pi(sk)->hdev;
 
-	DBG("sock %p sk %p", sock, sk);
+	BT_DBG("sock %p sk %p", sock, sk);
 
 	if (!sk)
 		return 0;
@@ -135,9 +147,7 @@
 	bluez_sock_unlink(&hci_sk_list, sk);
 
 	if (hdev) {
-		if (!hci_sock_lookup(hdev))
-			hdev->flags &= ~HCI_SOCK;
-
+		atomic_dec(&hdev->promisc);
 		hci_dev_put(hdev);
 	}
 
@@ -149,24 +159,55 @@
 	sock_put(sk);
 
 	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
-static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+/* Ioctls that require bound socket */ 
+static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
 {
-	struct sock *sk = sock->sk;
 	struct hci_dev *hdev = hci_pi(sk)->hdev;
-	__u32 mode;
 
-	DBG("cmd %x arg %lx", cmd, arg);
+	if (!hdev)
+		return -EBADFD;
 
 	switch (cmd) {
-	case HCIGETINFO:
-		return hci_dev_info(arg);
+	case HCISETRAW:
+		if (!capable(CAP_NET_ADMIN))
+			return -EACCES;
 
+		if (arg)
+			set_bit(HCI_RAW, &hdev->flags);
+		else
+			clear_bit(HCI_RAW, &hdev->flags);
+
+		return 0;
+
+	case HCIGETCONNINFO:
+		return hci_get_conn_info(hdev, arg);
+
+	default:
+		if (hdev->ioctl)
+			return hdev->ioctl(hdev, cmd, arg);
+		return -EINVAL;
+	}
+}
+
+static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+	struct sock *sk = sock->sk;
+	int err;
+
+	BT_DBG("cmd %x arg %lx", cmd, arg);
+
+	switch (cmd) {
 	case HCIGETDEVLIST:
-		return hci_dev_list(arg);
+		return hci_get_dev_list(arg);
+
+	case HCIGETDEVINFO:
+		return hci_get_dev_info(arg);
+
+	case HCIGETCONNLIST:
+		return hci_get_conn_list(arg);
 
 	case HCIDEVUP:
 		if (!capable(CAP_NET_ADMIN))
@@ -183,48 +224,31 @@
 			return -EACCES;
 		return hci_dev_reset(arg);
 
-	case HCIRESETSTAT:
+	case HCIDEVRESTAT:
 		if (!capable(CAP_NET_ADMIN))
 			return -EACCES;
 		return hci_dev_reset_stat(arg);
 
 	case HCISETSCAN:
-		if (!capable(CAP_NET_ADMIN))
-			return -EACCES;
-		return hci_dev_setscan(arg);
-
 	case HCISETAUTH:
-		if (!capable(CAP_NET_ADMIN))
-			return -EACCES;
-		return hci_dev_setauth(arg);
-
-	case HCISETRAW:
-		if (!capable(CAP_NET_ADMIN))
-			return -EACCES;
-
-		if (!hdev)
-			return -EBADFD;
-
-		if (arg)
-			mode = HCI_RAW;
-		else
-			mode = HCI_NORMAL;
-
-		return hci_dev_setmode(hdev, mode);
-
+	case HCISETENCRYPT:
 	case HCISETPTYPE:
+	case HCISETLINKPOL:
+	case HCISETLINKMODE:
+	case HCISETACLMTU:
+	case HCISETSCOMTU:
 		if (!capable(CAP_NET_ADMIN))
 			return -EACCES;
-		return hci_dev_setptype(arg);
+		return hci_dev_cmd(cmd, arg);
 
 	case HCIINQUIRY:
 		return hci_inquiry(arg);
 
-	case HCIGETCONNLIST:
-		return hci_conn_list(arg);
-
 	default:
-		return -EINVAL;
+		lock_sock(sk);
+		err = hci_sock_bound_ioctl(sk, cmd, arg);
+		release_sock(sk);
+		return err;
 	};
 }
 
@@ -233,28 +257,35 @@
 	struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
 	struct sock *sk = sock->sk;
 	struct hci_dev *hdev = NULL;
+	int err = 0;
 
-	DBG("sock %p sk %p", sock, sk);
+	BT_DBG("sock %p sk %p", sock, sk);
 
 	if (!haddr || haddr->hci_family != AF_BLUETOOTH)
 		return -EINVAL;
 
+	lock_sock(sk);
+
 	if (hci_pi(sk)->hdev) {
-		/* Already bound */
-		return 0;
+		err = -EALREADY;
+		goto done;
 	}
 
 	if (haddr->hci_dev != HCI_DEV_NONE) {
-		if (!(hdev = hci_dev_get(haddr->hci_dev)))
-			return -ENODEV;
+		if (!(hdev = hci_dev_get(haddr->hci_dev))) {
+			err = -ENODEV;
+			goto done;
+		}
 
-		hdev->flags |= HCI_SOCK;
+		atomic_inc(&hdev->promisc);
 	}
 
 	hci_pi(sk)->hdev = hdev;
 	sk->state = BT_BOUND;
 
-	return 0;
+done:
+	release_sock(sk);
+	return err;
 }
 
 static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
@@ -262,73 +293,44 @@
 	struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
 	struct sock *sk = sock->sk;
 
-	DBG("sock %p sk %p", sock, sk);
+	BT_DBG("sock %p sk %p", sock, sk);
+
+	lock_sock(sk);
 
 	*addr_len = sizeof(*haddr);
 	haddr->hci_family = AF_BLUETOOTH;
 	haddr->hci_dev    = hci_pi(sk)->hdev->id;
 
+	release_sock(sk);
 	return 0;
 }
 
-static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-                            struct scm_cookie *scm)
-{
-	struct sock *sk = sock->sk;
-	struct hci_dev *hdev = hci_pi(sk)->hdev;
-	struct sk_buff *skb;
-	int err;
-
-	DBG("sock %p sk %p", sock, sk);
-
-	if (msg->msg_flags & MSG_OOB)
-		return -EOPNOTSUPP;
-
-	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-		return -EINVAL;
-
-	if (!hdev)
-		return -EBADFD;
-
-	if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-		return err;
-
-	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-		kfree_skb(skb);
-		return -EFAULT;
-	}
-
-	skb->dev = (void *) hdev;
-	skb->pkt_type = *((unsigned char *) skb->data);
-	skb_pull(skb, 1);
-
-	/* Send frame to HCI core */
-	hci_send_raw(skb);
-
-	return len;
-}
-
 static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
 {
 	__u32 mask = hci_pi(sk)->cmsg_mask;
 
 	if (mask & HCI_CMSG_DIR)
         	put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
+
+	if (mask & HCI_CMSG_TSTAMP)
+        	put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
 }
  
-static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
-                            int flags, struct scm_cookie *scm)
+static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
 {
 	int noblock = flags & MSG_DONTWAIT;
 	struct sock *sk = sock->sk;
 	struct sk_buff *skb;
 	int copied, err;
 
-	DBG("sock %p sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
-	if (flags & (MSG_OOB | MSG_PEEK))
+	if (flags & (MSG_OOB))
 		return -EOPNOTSUPP;
 
+	if (sk->state == BT_CLOSED)
+		return 0;
+
 	if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
 		return err;
 
@@ -343,28 +345,95 @@
 	skb->h.raw = skb->data;
 	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
-	if (hci_pi(sk)->cmsg_mask)
-		hci_sock_cmsg(sk, msg, skb);
-
+	hci_sock_cmsg(sk, msg, skb);
+	
 	skb_free_datagram(sk, skb);
 
 	return err ? : copied;
 }
 
+static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
+                            struct scm_cookie *scm)
+{
+	struct sock *sk = sock->sk;
+	struct hci_dev *hdev;
+	struct sk_buff *skb;
+	int err;
+
+	BT_DBG("sock %p sk %p", sock, sk);
+
+	if (msg->msg_flags & MSG_OOB)
+		return -EOPNOTSUPP;
+
+	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
+		return -EINVAL;
+
+	if (len < 4)
+		return -EINVAL;
+	
+	lock_sock(sk);
+
+	if (!(hdev = hci_pi(sk)->hdev)) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
+		goto done;
+
+	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+		err = -EFAULT;
+		goto drop;
+	}
+
+	skb->pkt_type = *((unsigned char *) skb->data);
+	skb_pull(skb, 1);
+
+	if (!capable(CAP_NET_RAW)) {
+		err = -EPERM;
+
+		if (skb->pkt_type == HCI_COMMAND_PKT) {
+			__u16 opcode = __le16_to_cpu(*(__u16 *)skb->data);
+			__u16 ogf = cmd_opcode_ogf(opcode) - 1;
+			__u16 ocf = cmd_opcode_ocf(opcode) & HCI_FLT_OCF_BITS;
+
+			if (ogf > HCI_SFLT_MAX_OGF ||
+					!hci_test_bit(ocf, &hci_sec_filter.ocf_mask[ogf]))
+				goto drop;
+		} else
+			goto drop;
+	}
+		
+	/* Send frame to HCI core */
+	skb->dev = (void *) hdev;
+	hci_send_raw(skb);
+	err = len;
+
+done:
+	release_sock(sk);
+	return err;
+
+drop:
+	kfree_skb(skb);
+	goto done;
+}
+
 int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
 {
 	struct sock *sk = sock->sk;
-	struct hci_filter flt;
+	struct hci_filter flt = { opcode: 0 };
 	int err = 0, opt = 0;
 
-	DBG("sk %p, opt %d", sk, optname);
+	BT_DBG("sk %p, opt %d", sk, optname);
 
 	lock_sock(sk);
 
 	switch (optname) {
 	case HCI_DATA_DIR:
-		if (get_user(opt, (int *)optval))
-			return -EFAULT;
+		if (get_user(opt, (int *)optval)) {
+			err = -EFAULT;
+			break;
+		}
 
 		if (opt)
 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
@@ -372,12 +441,31 @@
 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
 		break;
 
+	case HCI_TIME_STAMP:
+		if (get_user(opt, (int *)optval)) {
+			err = -EFAULT;
+			break;
+		}
+
+		if (opt)
+			hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
+		else
+			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
+		break;
+
 	case HCI_FILTER:
 		len = MIN(len, sizeof(struct hci_filter));
 		if (copy_from_user(&flt, optval, len)) {
 			err = -EFAULT;
 			break;
 		}
+
+		if (!capable(CAP_NET_RAW)) {
+			flt.type_mask     &= hci_sec_filter.type_mask;
+			flt.event_mask[0] &= hci_sec_filter.event_mask[0];
+			flt.event_mask[1] &= hci_sec_filter.event_mask[1];
+		}
+		
 		memcpy(&hci_pi(sk)->filter, &flt, len);
 		break;
 
@@ -409,6 +497,16 @@
 			return -EFAULT;
 		break;
 
+	case HCI_TIME_STAMP:
+		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
+			opt = 1;
+		else 
+			opt = 0;
+
+		if (put_user(opt, optval))
+			return -EFAULT;
+		break;
+
 	case HCI_FILTER:
 		len = MIN(len, sizeof(struct hci_filter));
 		if (copy_to_user(optval, &hci_pi(sk)->filter, len))
@@ -446,7 +544,7 @@
 {
 	struct sock *sk;
 
-	DBG("sock %p", sock);
+	BT_DBG("sock %p", sock);
 
 	if (sock->type != SOCK_RAW)
 		return -ESOCKTNOSUPPORT;
@@ -464,44 +562,31 @@
 	sk->protocol = protocol;
 	sk->state    = BT_OPEN;
 
-	/* Initialize filter */
-	hci_pi(sk)->filter.type_mask  = (1<<HCI_EVENT_PKT);
-	hci_pi(sk)->filter.event_mask[0] = ~0L;
-	hci_pi(sk)->filter.event_mask[1] = ~0L;
-
 	bluez_sock_link(&hci_sk_list, sk);
 
 	MOD_INC_USE_COUNT;
-
 	return 0;
 }
 
 static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
 	struct hci_dev *hdev = (struct hci_dev *) ptr;
-	struct sk_buff *skb;
-
-	DBG("hdev %s event %ld", hdev->name, event);
+	evt_si_device sd;
+	
+	BT_DBG("hdev %s event %ld", hdev->name, event);
 
 	/* Send event to sockets */
-	if ((skb = bluez_skb_alloc(HCI_EVENT_HDR_SIZE + EVT_HCI_DEV_EVENT_SIZE, GFP_ATOMIC))) {
-		hci_event_hdr eh = { EVT_HCI_DEV_EVENT, EVT_HCI_DEV_EVENT_SIZE };
-		evt_hci_dev_event he = { event, hdev->id };
-
-		skb->pkt_type = HCI_EVENT_PKT;
-		memcpy(skb_put(skb, HCI_EVENT_HDR_SIZE), &eh, HCI_EVENT_HDR_SIZE);
-		memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
-
-		hci_send_to_sock(NULL, skb);
-		kfree_skb(skb);
-	}
-
+	sd.event  = event;
+	sd.dev_id = hdev->id;
+	hci_si_event(NULL, EVT_SI_DEVICE, EVT_SI_DEVICE_SIZE, &sd);
+	
 	if (event == HCI_DEV_UNREG) {
 		struct sock *sk;
 
 		/* Detach sockets from device */
 		read_lock(&hci_sk_list.lock);
 		for (sk = hci_sk_list.head; sk; sk = sk->next) {
+			bh_lock_sock(sk);
 			if (hci_pi(sk)->hdev == hdev) {
 				hci_pi(sk)->hdev = NULL;
 				sk->err = EPIPE;
@@ -510,6 +595,7 @@
 
 				hci_dev_put(hdev);
 			}
+			bh_unlock_sock(sk);
 		}
 		read_unlock(&hci_sk_list.lock);
 	}
@@ -529,21 +615,19 @@
 int hci_sock_init(void)
 {
 	if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
-		ERR("Can't register HCI socket");
+		BT_ERR("Can't register HCI socket");
 		return -EPROTO;
 	}
 
 	hci_register_notifier(&hci_sock_nblock);
-
 	return 0;
 }
 
 int hci_sock_cleanup(void)
 {
 	if (bluez_sock_unregister(BTPROTO_HCI))
-		ERR("Can't unregister HCI socket");
+		BT_ERR("Can't unregister HCI socket");
 
 	hci_unregister_notifier(&hci_sock_nblock);
-
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/l2cap.c linux/net/bluetooth/l2cap.c
--- linux.orig/net/bluetooth/l2cap.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/bluetooth/l2cap.c	2002-07-20 01:08:34.000000000 +0000
@@ -0,0 +1,2050 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * BlueZ L2CAP core and sockets.
+ *
+ * $Id: l2cap.c,v 1.8 2002/04/19 00:01:39 maxk Exp $
+ */
+#define VERSION "2.0"
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <net/sock.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
+
+#ifndef L2CAP_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#endif
+
+static struct proto_ops l2cap_sock_ops;
+
+struct bluez_sock_list l2cap_sk_list = {
+	lock: RW_LOCK_UNLOCKED
+};
+
+static int l2cap_conn_del(struct hci_conn *conn, int err);
+
+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
+static void l2cap_chan_del(struct sock *sk, int err);
+static int  l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
+
+static void __l2cap_sock_close(struct sock *sk, int reason);
+static void l2cap_sock_close(struct sock *sk);
+static void l2cap_sock_kill(struct sock *sk);
+
+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
+
+/* ----- L2CAP timers ------ */
+static void l2cap_sock_timeout(unsigned long arg)
+{
+	struct sock *sk = (struct sock *) arg;
+
+	BT_DBG("sock %p state %d", sk, sk->state);
+
+	bh_lock_sock(sk);
+	__l2cap_sock_close(sk, ETIMEDOUT);
+	bh_unlock_sock(sk);
+
+	l2cap_sock_kill(sk);
+	sock_put(sk);
+}
+
+static void l2cap_sock_set_timer(struct sock *sk, long timeout)
+{
+	BT_DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
+
+	if (!mod_timer(&sk->timer, jiffies + timeout))
+		sock_hold(sk);
+}
+
+static void l2cap_sock_clear_timer(struct sock *sk)
+{
+	BT_DBG("sock %p state %d", sk, sk->state);
+
+	if (timer_pending(&sk->timer) && del_timer(&sk->timer))
+		__sock_put(sk);
+}
+
+static void l2cap_sock_init_timer(struct sock *sk)
+{
+	init_timer(&sk->timer);
+	sk->timer.function = l2cap_sock_timeout;
+	sk->timer.data = (unsigned long)sk;
+}
+
+/* -------- L2CAP connections --------- */
+static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, __u8 status)
+{
+	struct l2cap_conn *conn;
+
+	if ((conn = hcon->l2cap_data))
+		return conn;
+
+	if (status)
+		return conn;
+
+	if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_ATOMIC)))
+		return NULL;
+	memset(conn, 0, sizeof(struct l2cap_conn));
+
+	hcon->l2cap_data = conn;
+	conn->hcon = hcon;
+	
+	conn->mtu = hcon->hdev->acl_mtu;
+	conn->src = &hcon->hdev->bdaddr;
+	conn->dst = &hcon->dst;
+	
+	spin_lock_init(&conn->lock);
+	conn->chan_list.lock = RW_LOCK_UNLOCKED;
+
+	BT_DBG("hcon %p conn %p", hcon, conn);
+
+	MOD_INC_USE_COUNT;
+	return conn;
+}
+
+static int l2cap_conn_del(struct hci_conn *hcon, int err)
+{
+	struct l2cap_conn *conn;
+	struct sock *sk;
+
+	if (!(conn = hcon->l2cap_data)) 
+		return 0;
+
+	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
+
+	if (conn->rx_skb)
+		kfree_skb(conn->rx_skb);
+
+	/* Kill channels */
+	while ((sk = conn->chan_list.head)) {
+		bh_lock_sock(sk);
+		l2cap_chan_del(sk, err);
+		bh_unlock_sock(sk);
+		l2cap_sock_kill(sk);
+	}
+
+	hcon->l2cap_data = NULL;
+	kfree(conn);
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+int l2cap_connect(struct sock *sk)
+{
+	bdaddr_t *src = &bluez_pi(sk)->src;
+	bdaddr_t *dst = &bluez_pi(sk)->dst;
+	struct l2cap_conn *conn;
+	struct hci_conn   *hcon;
+	struct hci_dev    *hdev;
+	int err = 0;
+
+	BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
+
+	if (!(hdev = hci_get_route(dst, src)))
+		return -EHOSTUNREACH;
+
+	hci_dev_lock_bh(hdev);
+
+	err = -ENOMEM;
+
+	hcon = hci_connect(hdev, ACL_LINK, dst);
+	if (!hcon)
+		goto done;
+
+	conn = l2cap_conn_add(hcon, 0);
+	if (!conn) {
+		hci_conn_put(hcon);
+		goto done;
+	}
+
+	err = 0;
+
+	/* Update source addr of the socket */
+	bacpy(src, conn->src);
+
+	l2cap_chan_add(conn, sk, NULL);
+
+	sk->state = BT_CONNECT;
+	l2cap_sock_set_timer(sk, sk->sndtimeo);
+
+	if (hcon->state == BT_CONNECTED) {
+		if (sk->type == SOCK_SEQPACKET) {
+			l2cap_conn_req req;
+			req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
+			req.psm  = l2cap_pi(sk)->psm;
+			l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
+		} else {
+			l2cap_sock_clear_timer(sk);
+			sk->state = BT_CONNECTED;
+		}
+	}
+
+done:
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+	return err;
+}
+
+/* -------- Socket interface ---------- */
+static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
+{
+	bdaddr_t *src = &addr->l2_bdaddr;
+	__u16 psm = addr->l2_psm;
+	struct sock *sk;
+
+	for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
+		if (l2cap_pi(sk)->psm == psm &&
+		    !bacmp(&bluez_pi(sk)->src, src))
+			break;
+	}
+
+	return sk;
+}
+
+/* Find socket listening on psm and source bdaddr.
+ * Returns closest match.
+ */
+static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
+{
+	struct sock *sk, *sk1 = NULL;
+
+	read_lock(&l2cap_sk_list.lock);
+
+	for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
+		if (sk->state != BT_LISTEN)
+			continue;
+
+		if (l2cap_pi(sk)->psm == psm) {
+			/* Exact match. */
+			if (!bacmp(&bluez_pi(sk)->src, src))
+				break;
+
+			/* Closest match */
+			if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
+				sk1 = sk;
+		}
+	}
+
+	read_unlock(&l2cap_sk_list.lock);
+	return sk ? sk : sk1;
+}
+
+static void l2cap_sock_destruct(struct sock *sk)
+{
+	BT_DBG("sk %p", sk);
+
+	skb_queue_purge(&sk->receive_queue);
+	skb_queue_purge(&sk->write_queue);
+
+	MOD_DEC_USE_COUNT;
+}
+
+static void l2cap_sock_cleanup_listen(struct sock *parent)
+{
+	struct sock *sk;
+
+	BT_DBG("parent %p", parent);
+
+	/* Close not yet accepted channels */
+	while ((sk = bluez_accept_dequeue(parent, NULL)))
+		l2cap_sock_close(sk);
+
+	parent->state  = BT_CLOSED;
+	parent->zapped = 1;
+}
+
+/* Kill socket (only if zapped and orphan)
+ * Must be called on unlocked socket.
+ */
+static void l2cap_sock_kill(struct sock *sk)
+{
+	if (!sk->zapped || sk->socket)
+		return;
+
+	BT_DBG("sk %p state %d", sk, sk->state);
+
+	/* Kill poor orphan */
+	bluez_sock_unlink(&l2cap_sk_list, sk);
+	sk->dead = 1;
+	sock_put(sk);
+}
+
+/* Close socket.
+ */
+static void __l2cap_sock_close(struct sock *sk, int reason)
+{
+	BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
+
+	switch (sk->state) {
+	case BT_LISTEN:
+		l2cap_sock_cleanup_listen(sk);
+		break;
+
+	case BT_CONNECTED:
+	case BT_CONFIG:
+		if (sk->type == SOCK_SEQPACKET) {
+			struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+			l2cap_disconn_req req;
+
+			sk->state = BT_DISCONN;
+			l2cap_sock_set_timer(sk, HZ * 5);
+
+			req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+			req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
+			l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
+		} else {
+			l2cap_chan_del(sk, reason);
+		}
+		break;
+
+	case BT_CONNECT:
+	case BT_CONNECT2:
+	case BT_DISCONN:
+		l2cap_chan_del(sk, reason);
+		break;
+
+	default:
+		sk->zapped = 1;
+		break;
+	};
+}
+
+/* Must be called on unlocked socket. */
+static void l2cap_sock_close(struct sock *sk)
+{
+	l2cap_sock_clear_timer(sk);
+
+	lock_sock(sk);
+	__l2cap_sock_close(sk, ECONNRESET);
+	release_sock(sk);
+
+	l2cap_sock_kill(sk);
+}
+
+static void l2cap_sock_init(struct sock *sk, struct sock *parent)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+
+	BT_DBG("sk %p", sk);
+
+	if (parent) {
+		sk->type = parent->type;
+
+		pi->imtu = l2cap_pi(parent)->imtu;
+		pi->omtu = l2cap_pi(parent)->omtu;
+		pi->link_mode = l2cap_pi(parent)->link_mode;
+	} else {
+		pi->imtu = L2CAP_DEFAULT_MTU;
+		pi->omtu = 0;
+		pi->link_mode = 0;
+	}
+
+	/* Default config options */
+	pi->conf_mtu = L2CAP_DEFAULT_MTU;
+	pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+}
+
+static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
+{
+	struct sock *sk;
+
+	if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
+		return NULL;
+
+	bluez_sock_init(sock, sk);
+	
+	sk->zapped   = 0;
+
+	sk->destruct = l2cap_sock_destruct;
+	sk->sndtimeo = L2CAP_CONN_TIMEOUT;
+
+	sk->protocol = proto;
+	sk->state    = BT_OPEN;
+
+	l2cap_sock_init_timer(sk);
+
+	bluez_sock_link(&l2cap_sk_list, sk);
+
+	MOD_INC_USE_COUNT;
+	return sk;
+}
+
+static int l2cap_sock_create(struct socket *sock, int protocol)
+{
+	struct sock *sk;
+
+	BT_DBG("sock %p", sock);
+
+	sock->state = SS_UNCONNECTED;
+
+	if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
+		return -ESOCKTNOSUPPORT;
+
+	sock->ops = &l2cap_sock_ops;
+
+	if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
+		return -ENOMEM;
+
+	l2cap_sock_init(sk, NULL);
+	return 0;
+}
+
+static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+{
+	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
+
+	if (!addr || addr->sa_family != AF_BLUETOOTH)
+		return -EINVAL;
+
+	lock_sock(sk);
+
+	if (sk->state != BT_OPEN) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	write_lock(&l2cap_sk_list.lock);
+
+	if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
+		err = -EADDRINUSE;
+		goto unlock;
+	}
+
+	/* Save source address */
+	bacpy(&bluez_pi(sk)->src, &la->l2_bdaddr);
+	l2cap_pi(sk)->psm = la->l2_psm;
+	sk->state = BT_BOUND;
+
+unlock:
+	write_unlock(&l2cap_sk_list.lock);
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
+{
+	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	lock_sock(sk);
+
+	BT_DBG("sk %p", sk);
+
+	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
+		err = -EINVAL;
+		goto done;
+	}
+
+	if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
+		err = -EINVAL;
+		goto done;
+	}
+
+	switch(sk->state) {
+	case BT_CONNECT:
+	case BT_CONNECT2:
+	case BT_CONFIG:
+		/* Already connecting */
+		goto wait;
+
+	case BT_CONNECTED:
+		/* Already connected */
+		goto done;
+
+	case BT_OPEN:
+	case BT_BOUND:
+		/* Can connect */
+		break;
+
+	default:
+		err = -EBADFD;
+		goto done;
+	}
+
+	/* Set destination address and psm */
+	bacpy(&bluez_pi(sk)->dst, &la->l2_bdaddr);
+	l2cap_pi(sk)->psm = la->l2_psm;
+
+	if ((err = l2cap_connect(sk)))
+		goto done;
+
+wait:
+	err = bluez_sock_w4_connect(sk, flags);
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+int l2cap_sock_listen(struct socket *sock, int backlog)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	BT_DBG("sk %p backlog %d", sk, backlog);
+
+	lock_sock(sk);
+
+	if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	if (!l2cap_pi(sk)->psm) {
+		err = -EINVAL;
+		goto done;
+	}
+
+	sk->max_ack_backlog = backlog;
+	sk->ack_backlog = 0;
+	sk->state = BT_LISTEN;
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct sock *sk = sock->sk, *nsk;
+	long timeo;
+	int err = 0;
+
+	lock_sock(sk);
+
+	if (sk->state != BT_LISTEN) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
+
+	BT_DBG("sk %p timeo %ld", sk, timeo);
+
+	/* Wait for an incoming connection. (wake-one). */
+	add_wait_queue_exclusive(sk->sleep, &wait);
+	while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (!timeo) {
+			err = -EAGAIN;
+			break;
+		}
+
+		release_sock(sk);
+		timeo = schedule_timeout(timeo);
+		lock_sock(sk);
+
+		if (sk->state != BT_LISTEN) {
+			err = -EBADFD;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			err = sock_intr_errno(timeo);
+			break;
+		}
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(sk->sleep, &wait);
+
+	if (err)
+		goto done;
+
+	newsock->state = SS_CONNECTED;
+
+	BT_DBG("new socket %p", nsk);
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
+{
+	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
+	struct sock *sk = sock->sk;
+
+	BT_DBG("sock %p, sk %p", sock, sk);
+
+	addr->sa_family = AF_BLUETOOTH;
+	*len = sizeof(struct sockaddr_l2);
+
+	if (peer)
+		bacpy(&la->l2_bdaddr, &bluez_pi(sk)->dst);
+	else
+		bacpy(&la->l2_bdaddr, &bluez_pi(sk)->src);
+
+	la->l2_psm = l2cap_pi(sk)->psm;
+
+	return 0;
+}
+
+static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	BT_DBG("sock %p, sk %p", sock, sk);
+
+	if (sk->err)
+		return sock_error(sk);
+
+	if (msg->msg_flags & MSG_OOB)
+		return -EOPNOTSUPP;
+
+	lock_sock(sk);
+
+	if (sk->state == BT_CONNECTED)
+		err = l2cap_chan_send(sk, msg, len);
+	else
+		err = -ENOTCONN;
+
+	release_sock(sk);
+	return err;
+}
+
+static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+{
+	struct sock *sk = sock->sk;
+	struct l2cap_options opts;
+	int err = 0, len;
+	__u32 opt;
+
+	BT_DBG("sk %p", sk);
+
+	lock_sock(sk);
+
+	switch (optname) {
+	case L2CAP_OPTIONS:
+		len = MIN(sizeof(opts), optlen);
+		if (copy_from_user((char *)&opts, optval, len)) {
+			err = -EFAULT;
+			break;
+		}
+		l2cap_pi(sk)->imtu  = opts.imtu;
+		l2cap_pi(sk)->omtu  = opts.omtu;
+		break;
+
+	case L2CAP_LM:
+		if (get_user(opt, (__u32 *)optval)) {
+			err = -EFAULT;
+			break;
+		}
+
+		l2cap_pi(sk)->link_mode = opt;
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	};
+
+	release_sock(sk);
+	return err;
+}
+
+static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
+{
+	struct sock *sk = sock->sk;
+	struct l2cap_options opts;
+	struct l2cap_conninfo cinfo;
+	int len, err = 0; 
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+
+	lock_sock(sk);
+
+	switch (optname) {
+	case L2CAP_OPTIONS:
+		opts.imtu     = l2cap_pi(sk)->imtu;
+		opts.omtu     = l2cap_pi(sk)->omtu;
+		opts.flush_to = l2cap_pi(sk)->flush_to;
+
+		len = MIN(len, sizeof(opts));
+		if (copy_to_user(optval, (char *)&opts, len))
+			err = -EFAULT;
+
+		break;
+
+	case L2CAP_LM:
+		if (put_user(l2cap_pi(sk)->link_mode, (__u32 *)optval))
+			err = -EFAULT;
+		break;
+
+	case L2CAP_CONNINFO:
+		if (sk->state != BT_CONNECTED) {
+			err = -ENOTCONN;
+			break;
+		}
+
+		cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
+
+		len = MIN(len, sizeof(cinfo));
+		if (copy_to_user(optval, (char *)&cinfo, len))
+			err = -EFAULT;
+
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	};
+
+	release_sock(sk);
+	return err;
+}
+
+static int l2cap_sock_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+
+	BT_DBG("sock %p, sk %p", sock, sk);
+
+	if (!sk)
+		return 0;
+
+	sock_orphan(sk);
+	l2cap_sock_close(sk);
+	return 0;
+}
+
+/* --------- L2CAP channels --------- */
+static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
+{
+	struct sock *s;
+
+	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
+		if (l2cap_pi(s)->dcid == cid)
+			break;
+	}
+
+	return s;
+}
+
+static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
+{
+	struct sock *s;
+
+	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
+		if (l2cap_pi(s)->scid == cid)
+			break;
+	}
+
+	return s;
+}
+
+/* Find channel with given SCID.
+ * Returns locked socket */
+static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
+{
+	struct sock *s;
+	read_lock(&l->lock);
+	s = __l2cap_get_chan_by_scid(l, cid);
+	if (s) bh_lock_sock(s);
+	read_unlock(&l->lock);
+	return s;
+}
+
+static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
+{
+	__u16 cid = 0x0040;
+
+	for (; cid < 0xffff; cid++) {
+		if(!__l2cap_get_chan_by_scid(l, cid))
+			return cid;
+	}
+
+	return 0;
+}
+
+static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
+{
+	sock_hold(sk);
+
+	if (l->head)
+		l2cap_pi(l->head)->prev_c = sk;
+
+	l2cap_pi(sk)->next_c = l->head;
+	l2cap_pi(sk)->prev_c = NULL;
+	l->head = sk;
+}
+
+static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
+{
+	struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
+
+	write_lock(&l->lock);
+	if (sk == l->head)
+		l->head = next;
+
+	if (next)
+		l2cap_pi(next)->prev_c = prev;
+	if (prev)
+		l2cap_pi(prev)->next_c = next;
+	write_unlock(&l->lock);
+
+	__sock_put(sk);
+}
+
+static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+
+	BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
+
+	l2cap_pi(sk)->conn = conn;
+
+	if (sk->type == SOCK_SEQPACKET) {
+		/* Alloc CID for normal socket */
+		l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
+	} else {
+		/* Raw socket can send only signalling messages */
+		l2cap_pi(sk)->scid = 0x0001;
+		l2cap_pi(sk)->dcid = 0x0001;
+		l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
+	}
+
+	__l2cap_chan_link(l, sk);
+
+	if (parent)
+		bluez_accept_enqueue(parent, sk);
+}
+
+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+	write_lock(&l->lock);
+	__l2cap_chan_add(conn, sk, parent);
+	write_unlock(&l->lock);
+}
+
+/* Delete channel. 
+ * Must be called on the locked socket. */
+static void l2cap_chan_del(struct sock *sk, int err)
+{
+	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+	struct sock *parent = bluez_pi(sk)->parent;
+
+	l2cap_sock_clear_timer(sk);
+
+	BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
+
+	if (conn) { 
+		/* Unlink from channel list */
+		l2cap_chan_unlink(&conn->chan_list, sk);
+		l2cap_pi(sk)->conn = NULL;
+		hci_conn_put(conn->hcon);
+	}
+
+	sk->state = BT_CLOSED;
+	sk->err   = err;
+	sk->zapped = 1;
+
+	if (parent)
+		parent->data_ready(parent, 0);
+	else
+		sk->state_change(sk);
+}
+
+static void l2cap_conn_ready(struct l2cap_conn *conn)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+	struct sock *sk;
+
+	BT_DBG("conn %p", conn);
+
+	read_lock(&l->lock);
+
+	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+		bh_lock_sock(sk);
+
+		if (sk->type != SOCK_SEQPACKET) {
+			l2cap_sock_clear_timer(sk);
+			sk->state = BT_CONNECTED;
+			sk->state_change(sk);
+		} else if (sk->state == BT_CONNECT) {
+			l2cap_conn_req req;
+			req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
+			req.psm  = l2cap_pi(sk)->psm;
+			l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
+		}
+
+		bh_unlock_sock(sk);
+	}
+
+	read_unlock(&l->lock);
+}
+
+static void l2cap_chan_ready(struct sock *sk)
+{
+	struct sock *parent = bluez_pi(sk)->parent;
+
+	BT_DBG("sk %p, parent %p", sk, parent);
+
+	l2cap_pi(sk)->conf_state = 0;
+	l2cap_sock_clear_timer(sk);
+
+	if (!parent) {
+		/* Outgoing channel.
+		 * Wake up socket sleeping on connect.
+		 */
+		sk->state = BT_CONNECTED;
+		sk->state_change(sk);
+	} else {
+		/* Incomming channel.
+		 * Wake up socket sleeping on accept.
+		 */
+		parent->data_ready(parent, 0);
+	}
+}
+
+/* Copy frame to all raw sockets on that connection */
+void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+	struct sk_buff *nskb;
+	struct sock * sk;
+
+	BT_DBG("conn %p", conn);
+
+	read_lock(&l->lock);
+	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+		if (sk->type != SOCK_RAW)
+			continue;
+
+		/* Don't send frame to the socket it came from */
+		if (skb->sk == sk)
+			continue;
+
+		if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
+			continue;
+
+		if (sock_queue_rcv_skb(sk, nskb))
+			kfree_skb(nskb);
+	}
+	read_unlock(&l->lock);
+}
+
+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
+{
+	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+	struct sk_buff *skb, **frag;
+	int err, size, count, sent=0;
+	l2cap_hdr *lh;
+
+	/* Check outgoing MTU */
+	if (len > l2cap_pi(sk)->omtu)
+		return -EINVAL;
+
+	BT_DBG("sk %p len %d", sk, len);
+
+	/* First fragment (with L2CAP header) */
+	count = MIN(conn->mtu - L2CAP_HDR_SIZE, len);
+	size  = L2CAP_HDR_SIZE + count;
+	if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
+		return err;
+
+	/* Create L2CAP header */
+	lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->len = __cpu_to_le16(len);
+	lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+
+	if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
+		err = -EFAULT;
+		goto fail;
+	}
+
+	sent += count;
+	len  -= count;
+
+	/* Continuation fragments (no L2CAP header) */
+	frag = &skb_shinfo(skb)->frag_list;
+	while (len) {
+		count = MIN(conn->mtu, len);
+
+		*frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
+		if (!*frag)
+			goto fail;
+		
+		if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
+			err = -EFAULT;
+			goto fail;
+		}
+
+		sent += count;
+		len  -= count;
+
+		frag = &(*frag)->next;
+	}
+
+	if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
+		goto fail;
+
+	return sent;
+
+fail:
+	kfree_skb(skb);
+	return err;
+}
+
+/* --------- L2CAP signalling commands --------- */
+static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
+{
+	__u8 id;
+
+	/* Get next available identificator.
+	 *    1 - 199 are used by kernel.
+	 *  200 - 254 are used by utilities like l2ping, etc 
+	 */
+
+	spin_lock(&conn->lock);
+
+	if (++conn->tx_ident > 199)
+		conn->tx_ident = 1;
+
+	id = conn->tx_ident;
+
+	spin_unlock(&conn->lock);
+
+	return id;
+}
+
+static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
+				__u8 code, __u8 ident, __u16 dlen, void *data)
+{
+	struct sk_buff *skb, **frag;
+	l2cap_cmd_hdr *cmd;
+	l2cap_hdr *lh;
+	int len, count;
+
+	BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
+
+	len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
+	count = MIN(conn->mtu, len);
+	
+	skb = bluez_skb_alloc(count, GFP_ATOMIC);
+	if (!skb)
+		return NULL;
+
+	lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
+	lh->cid = __cpu_to_le16(0x0001);
+
+	cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
+	cmd->code  = code;
+	cmd->ident = ident;
+	cmd->len   = __cpu_to_le16(dlen);
+
+	if (dlen) {
+		count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
+		memcpy(skb_put(skb, count), data, count);
+		data += count;
+	}
+
+	len -= skb->len;
+	
+	/* Continuation fragments (no L2CAP header) */
+	frag = &skb_shinfo(skb)->frag_list;
+	while (len) {
+		count = MIN(conn->mtu, len);
+
+		*frag = bluez_skb_alloc(count, GFP_ATOMIC);
+		if (!*frag)
+			goto fail;
+		
+		memcpy(skb_put(*frag, count), data, count);
+
+		len  -= count;
+		data += count;
+		
+		frag = &(*frag)->next;
+	}
+
+	return skb;
+
+fail:
+	kfree_skb(skb);
+	return NULL;
+}
+
+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
+{
+	__u8 ident = l2cap_get_ident(conn);
+	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
+
+	BT_DBG("code 0x%2.2x", code);
+
+	if (!skb)
+		return -ENOMEM;
+	return hci_send_acl(conn->hcon, skb, 0);
+}
+
+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
+{
+	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
+
+	BT_DBG("code 0x%2.2x", code);
+
+	if (!skb)
+		return -ENOMEM;
+	return hci_send_acl(conn->hcon, skb, 0);
+}
+
+static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
+{
+	l2cap_conf_opt *opt = *ptr;
+	int len;
+
+	len = L2CAP_CONF_OPT_SIZE + opt->len;
+	*ptr += len;
+
+	*type = opt->type;
+	*olen = opt->len;
+
+	switch (opt->len) {
+	case 1:
+		*val = *((__u8 *) opt->val);
+		break;
+
+	case 2:
+		*val = __le16_to_cpu(*((__u16 *)opt->val));
+		break;
+
+	case 4:
+		*val = __le32_to_cpu(*((__u32 *)opt->val));
+		break;
+
+	default:
+		*val = (unsigned long) opt->val;
+		break;
+	};
+
+	BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
+	return len;
+}
+
+static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
+{
+	int type, hint, olen; 
+	unsigned long val;
+	void *ptr = data;
+
+	BT_DBG("sk %p len %d", sk, len);
+
+	while (len >= L2CAP_CONF_OPT_SIZE) {
+		len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
+
+		hint  = type & 0x80;
+		type &= 0x7f;
+
+		switch (type) {
+		case L2CAP_CONF_MTU:
+			l2cap_pi(sk)->conf_mtu = val;
+			break;
+
+		case L2CAP_CONF_FLUSH_TO:
+			l2cap_pi(sk)->flush_to = val;
+			break;
+
+		case L2CAP_CONF_QOS:
+			break;
+		
+		default:
+			if (hint)
+				break;
+
+			/* FIXME: Reject unknown option */
+			break;
+		};
+	}
+}
+
+static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val)
+{
+	register l2cap_conf_opt *opt = *ptr;
+
+	BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
+
+	opt->type = type;
+	opt->len  = len;
+
+	switch (len) {
+	case 1:
+		*((__u8 *) opt->val)  = val;
+		break;
+
+	case 2:
+		*((__u16 *) opt->val) = __cpu_to_le16(val);
+		break;
+
+	case 4:
+		*((__u32 *) opt->val) = __cpu_to_le32(val);
+		break;
+
+	default:
+		memcpy(opt->val, (void *) val, len);
+		break;
+	};
+
+	*ptr += L2CAP_CONF_OPT_SIZE + len;
+}
+
+static int l2cap_build_conf_req(struct sock *sk, void *data)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	l2cap_conf_req *req = (l2cap_conf_req *) data;
+	void *ptr = req->data;
+
+	BT_DBG("sk %p", sk);
+
+	if (pi->imtu != L2CAP_DEFAULT_MTU)
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
+
+	/* FIXME. Need actual value of the flush timeout */
+	//if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
+	//   l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
+
+	req->dcid  = __cpu_to_le16(pi->dcid);
+	req->flags = __cpu_to_le16(0);
+
+	return ptr - data;
+}
+
+static inline int l2cap_conf_output(struct sock *sk, void **ptr)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	int result = 0;
+
+	/* Configure output options and let the other side know
+	 * which ones we don't like.
+	 */
+	if (pi->conf_mtu < pi->omtu) {
+		l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+		result = L2CAP_CONF_UNACCEPT;
+	} else {
+		pi->omtu = pi->conf_mtu;
+	}
+
+	BT_DBG("sk %p result %d", sk, result);
+	return result;
+}
+
+static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
+{
+	l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
+	void *ptr = rsp->data;
+
+	BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
+
+	if (result)
+		*result = l2cap_conf_output(sk, &ptr);
+
+	rsp->scid   = __cpu_to_le16(l2cap_pi(sk)->dcid);
+	rsp->result = __cpu_to_le16(result ? *result : 0);
+	rsp->flags  = __cpu_to_le16(0);
+
+	return ptr - data;
+}
+
+static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+{
+	struct l2cap_chan_list *list = &conn->chan_list;
+	l2cap_conn_req *req = (l2cap_conn_req *) data;
+	l2cap_conn_rsp rsp;
+	struct sock *sk, *parent;
+	int result = 0, status = 0;
+
+	__u16 dcid = 0, scid = __le16_to_cpu(req->scid);
+	__u16 psm  = req->psm;
+
+	BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
+
+	/* Check if we have socket listening on psm */
+	if (!(parent = l2cap_get_sock_listen(conn->src, psm))) {
+		result = L2CAP_CR_BAD_PSM;
+		goto resp;
+	}
+
+	write_lock(&list->lock);
+	bh_lock_sock(parent);
+
+	result = L2CAP_CR_NO_MEM;
+
+	/* Check if we already have channel with that dcid */
+	if (__l2cap_get_chan_by_dcid(list, scid))
+		goto unlock;
+
+	/* Check for backlog size */
+	if (parent->ack_backlog > parent->max_ack_backlog) {
+		BT_DBG("backlog full %d", parent->ack_backlog); 
+		goto unlock;
+	}
+
+	if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
+		goto unlock;
+
+	l2cap_sock_init(sk, parent);
+
+	bacpy(&bluez_pi(sk)->src, conn->src);
+	bacpy(&bluez_pi(sk)->dst, conn->dst);
+	l2cap_pi(sk)->psm  = psm;
+	l2cap_pi(sk)->dcid = scid;
+	
+	hci_conn_hold(conn->hcon);
+
+	__l2cap_chan_add(conn, sk, parent);
+	dcid = l2cap_pi(sk)->scid;
+
+	l2cap_sock_set_timer(sk, sk->sndtimeo);
+
+	/* Service level security */
+	result = L2CAP_CR_PEND;
+	status = L2CAP_CS_AUTHEN_PEND;
+	sk->state = BT_CONNECT2;
+	l2cap_pi(sk)->ident = cmd->ident;
+	
+	if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) {
+		if (!hci_conn_encrypt(conn->hcon))
+			goto unlock;
+	} else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) {
+		if (!hci_conn_auth(conn->hcon))
+			goto unlock;
+	}
+
+	sk->state = BT_CONFIG;
+	result = status = 0;
+
+unlock:
+	bh_unlock_sock(parent);
+	write_unlock(&list->lock);
+
+resp:
+	rsp.scid   = __cpu_to_le16(scid);
+	rsp.dcid   = __cpu_to_le16(dcid);
+	rsp.result = __cpu_to_le16(result);
+	rsp.status = __cpu_to_le16(status);
+	l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
+	return 0;
+}
+
+static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+{
+	l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
+	__u16 scid, dcid, result, status;
+	struct sock *sk;
+	char req[128];
+
+	scid   = __le16_to_cpu(rsp->scid);
+	dcid   = __le16_to_cpu(rsp->dcid);
+	result = __le16_to_cpu(rsp->result);
+	status = __le16_to_cpu(rsp->status);
+
+	BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+		return -ENOENT;
+
+	switch (result) {
+	case L2CAP_CR_SUCCESS:
+		sk->state = BT_CONFIG;
+		l2cap_pi(sk)->dcid = dcid;
+		l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
+
+		l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
+		break;
+
+	case L2CAP_CR_PEND:
+		break;
+
+	default:
+		l2cap_chan_del(sk, ECONNREFUSED);
+		break;
+	}
+
+	bh_unlock_sock(sk);
+	return 0;
+}
+
+static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+{
+	l2cap_conf_req * req = (l2cap_conf_req *) data;
+	__u16 dcid, flags;
+	__u8 rsp[64];
+	struct sock *sk;
+	int result;
+
+	dcid  = __le16_to_cpu(req->dcid);
+	flags = __le16_to_cpu(req->flags);
+
+	BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
+		return -ENOENT;
+
+	l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
+
+	if (flags & 0x01) {
+		/* Incomplete config. Send empty response. */
+		l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
+		goto unlock;
+	}
+
+	/* Complete config. */
+	l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
+
+	if (result)
+		goto unlock;
+
+	/* Output config done */
+	l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
+
+	if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
+		sk->state = BT_CONNECTED;
+		l2cap_chan_ready(sk);
+	} else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
+		char req[64];
+		l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
+	}
+
+unlock:
+	bh_unlock_sock(sk);
+	return 0;
+}
+
+static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+{
+	l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
+	__u16 scid, flags, result;
+	struct sock *sk;
+	int err = 0;
+
+	scid   = __le16_to_cpu(rsp->scid);
+	flags  = __le16_to_cpu(rsp->flags);
+	result = __le16_to_cpu(rsp->result);
+
+	BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+		return -ENOENT;
+
+	if (result) {
+		l2cap_disconn_req req;
+
+		/* They didn't like our options. Well... we do not negotiate.
+		 * Close channel.
+		 */
+		sk->state = BT_DISCONN;
+		l2cap_sock_set_timer(sk, HZ * 5);
+
+		req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+		req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
+		l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
+		goto done;
+	}
+
+	if (flags & 0x01)
+		goto done;
+
+	/* Input config done */
+	l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
+
+	if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
+		sk->state = BT_CONNECTED;
+		l2cap_chan_ready(sk);
+	}
+
+done:
+	bh_unlock_sock(sk);
+	return err;
+}
+
+static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+{
+	l2cap_disconn_req *req = (l2cap_disconn_req *) data;
+	l2cap_disconn_rsp rsp;
+	__u16 dcid, scid;
+	struct sock *sk;
+
+	scid = __le16_to_cpu(req->scid);
+	dcid = __le16_to_cpu(req->dcid);
+
+	BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
+		return 0;
+
+	rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
+	rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+	l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
+
+	sk->shutdown = SHUTDOWN_MASK;
+	
+	l2cap_chan_del(sk, ECONNRESET);
+	bh_unlock_sock(sk);
+
+	l2cap_sock_kill(sk);
+	return 0;
+}
+
+static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+{
+	l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
+	__u16 dcid, scid;
+	struct sock *sk;
+
+	scid = __le16_to_cpu(rsp->scid);
+	dcid = __le16_to_cpu(rsp->dcid);
+
+	BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+		return 0;
+	l2cap_chan_del(sk, ECONNABORTED);
+	bh_unlock_sock(sk);
+
+	l2cap_sock_kill(sk);
+	return 0;
+}
+
+static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	__u8 *data = skb->data;
+	int len = skb->len;
+	l2cap_cmd_hdr cmd;
+	int err = 0;
+
+	while (len >= L2CAP_CMD_HDR_SIZE) {
+		memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
+		data += L2CAP_CMD_HDR_SIZE;
+		len  -= L2CAP_CMD_HDR_SIZE;
+
+		cmd.len = __le16_to_cpu(cmd.len);
+
+		BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
+
+		if (cmd.len > len || !cmd.ident) {
+			BT_DBG("corrupted command");
+			break;
+		}
+
+		switch (cmd.code) {
+		case L2CAP_CONN_REQ:
+			err = l2cap_connect_req(conn, &cmd, data);
+			break;
+
+		case L2CAP_CONN_RSP:
+			err = l2cap_connect_rsp(conn, &cmd, data);
+			break;
+
+		case L2CAP_CONF_REQ:
+			err = l2cap_config_req(conn, &cmd, data);
+			break;
+
+		case L2CAP_CONF_RSP:
+			err = l2cap_config_rsp(conn, &cmd, data);
+			break;
+
+		case L2CAP_DISCONN_REQ:
+			err = l2cap_disconnect_req(conn, &cmd, data);
+			break;
+
+		case L2CAP_DISCONN_RSP:
+			err = l2cap_disconnect_rsp(conn, &cmd, data);
+			break;
+
+		case L2CAP_COMMAND_REJ:
+			/* FIXME: We should process this */
+			l2cap_raw_recv(conn, skb);
+			break;
+
+		case L2CAP_ECHO_REQ:
+			l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
+			break;
+
+		case L2CAP_ECHO_RSP:
+		case L2CAP_INFO_REQ:
+		case L2CAP_INFO_RSP:
+			l2cap_raw_recv(conn, skb);
+			break;
+
+		default:
+			BT_ERR("Uknown signaling command 0x%2.2x", cmd.code);
+			err = -EINVAL;
+			break;
+		};
+
+		if (err) {
+			l2cap_cmd_rej rej;
+			BT_DBG("error %d", err);
+
+			/* FIXME: Map err to a valid reason. */
+			rej.reason = __cpu_to_le16(0);
+			l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
+		}
+
+		data += cmd.len;
+		len  -= cmd.len;
+	}
+
+	kfree_skb(skb);
+}
+
+static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
+{
+	struct sock *sk;
+
+	sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
+	if (!sk) {
+		BT_DBG("unknown cid 0x%4.4x", cid);
+		goto drop;
+	}
+
+	BT_DBG("sk %p, len %d", sk, skb->len);
+
+	if (sk->state != BT_CONNECTED)
+		goto drop;
+
+	if (l2cap_pi(sk)->imtu < skb->len)
+		goto drop;
+
+	/* If socket recv buffers overflows we drop data here 
+	 * which is *bad* because L2CAP has to be reliable. 
+	 * But we don't have any other choice. L2CAP doesn't 
+	 * provide flow control mechanism */ 
+	
+	if (!sock_queue_rcv_skb(sk, skb))
+		goto done;
+
+drop:
+	kfree_skb(skb);
+
+done:
+	if (sk) bh_unlock_sock(sk);
+	return 0;
+}
+
+static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	l2cap_hdr *lh = (l2cap_hdr *) skb->data;
+	__u16 cid, len;
+
+	skb_pull(skb, L2CAP_HDR_SIZE);
+	cid = __le16_to_cpu(lh->cid);
+	len = __le16_to_cpu(lh->len);
+
+	BT_DBG("len %d, cid 0x%4.4x", len, cid);
+
+	if (cid == 0x0001)
+		l2cap_sig_channel(conn, skb);
+	else	
+		l2cap_data_channel(conn, cid, skb);
+}
+
+/* ------------ L2CAP interface with lower layer (HCI) ------------- */
+
+static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
+{
+	int exact = 0, lm1 = 0, lm2 = 0;
+	register struct sock *sk;
+
+	if (type != ACL_LINK)
+		return 0;
+
+	BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+
+	/* Find listening sockets and check their link_mode */
+	read_lock(&l2cap_sk_list.lock);
+	for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
+		if (sk->state != BT_LISTEN)
+			continue;
+
+		if (!bacmp(&bluez_pi(sk)->src, bdaddr)) {
+			lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
+			exact++;
+		} else if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
+			lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
+	}
+	read_unlock(&l2cap_sk_list.lock);
+
+	return exact ? lm1 : lm2;
+}
+
+static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
+{
+	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
+
+	if (hcon->type != ACL_LINK)
+		return 0;
+
+	if (!status) {
+		struct l2cap_conn *conn;
+
+		conn = l2cap_conn_add(hcon, status);
+		if (conn)
+			l2cap_conn_ready(conn);
+	} else 
+		l2cap_conn_del(hcon, bterr(status));
+	
+	return 0;
+}
+
+static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
+{
+	BT_DBG("hcon %p reason %d", hcon, reason);
+
+	if (hcon->type != ACL_LINK)
+		return 0;
+
+	l2cap_conn_del(hcon, bterr(reason));
+	return 0;
+}
+
+static int l2cap_auth_cfm(struct hci_conn *hcon, __u8 status)
+{
+	struct l2cap_chan_list *l;
+	struct l2cap_conn *conn;
+	l2cap_conn_rsp rsp;
+	struct sock *sk;
+	int result;
+	
+	if (!(conn = hcon->l2cap_data))
+		return 0;
+	l = &conn->chan_list;
+
+	BT_DBG("conn %p", conn);
+
+	read_lock(&l->lock);
+
+	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+		bh_lock_sock(sk);
+
+		if (sk->state != BT_CONNECT2 ||
+				(l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT)) {
+			bh_unlock_sock(sk);
+			continue;
+		}
+
+		if (!status) {
+			sk->state = BT_CONFIG;
+			result = 0;
+		} else {
+			sk->state = BT_DISCONN;
+			l2cap_sock_set_timer(sk, HZ/10);
+			result = L2CAP_CR_SEC_BLOCK;
+		}
+
+		rsp.scid   = __cpu_to_le16(l2cap_pi(sk)->dcid);
+		rsp.dcid   = __cpu_to_le16(l2cap_pi(sk)->scid);
+		rsp.result = __cpu_to_le16(result);
+		rsp.status = __cpu_to_le16(0);
+		l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
+			L2CAP_CONN_RSP_SIZE, &rsp);
+
+		bh_unlock_sock(sk);
+	}
+
+	read_unlock(&l->lock);
+	return 0;
+}
+
+static int l2cap_encrypt_cfm(struct hci_conn *hcon, __u8 status)
+{
+	struct l2cap_chan_list *l;
+	struct l2cap_conn *conn;
+	l2cap_conn_rsp rsp;
+	struct sock *sk;
+	int result;
+	
+	if (!(conn = hcon->l2cap_data))
+		return 0;
+	l = &conn->chan_list;
+
+	BT_DBG("conn %p", conn);
+
+	read_lock(&l->lock);
+
+	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+		bh_lock_sock(sk);
+
+		if (sk->state != BT_CONNECT2) {
+			bh_unlock_sock(sk);
+			continue;
+		}
+
+		if (!status) {
+			sk->state = BT_CONFIG;
+			result = 0;
+		} else {
+			sk->state = BT_DISCONN;
+			l2cap_sock_set_timer(sk, HZ/10);
+			result = L2CAP_CR_SEC_BLOCK;
+		}
+
+		rsp.scid   = __cpu_to_le16(l2cap_pi(sk)->dcid);
+		rsp.dcid   = __cpu_to_le16(l2cap_pi(sk)->scid);
+		rsp.result = __cpu_to_le16(result);
+		rsp.status = __cpu_to_le16(0);
+		l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP, 
+			L2CAP_CONN_RSP_SIZE, &rsp);
+
+		bh_unlock_sock(sk);
+	}
+
+	read_unlock(&l->lock);
+	return 0;
+}
+
+static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, __u16 flags)
+{
+	struct l2cap_conn *conn = hcon->l2cap_data;
+
+	if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
+		goto drop;
+
+	BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
+
+	if (flags & ACL_START) {
+		int flen, tlen, size;
+		l2cap_hdr *lh;
+
+		if (conn->rx_len) {
+			BT_ERR("Unexpected start frame (len %d)", skb->len);
+			kfree_skb(conn->rx_skb);
+			conn->rx_skb = NULL;
+			conn->rx_len = 0;
+		}
+
+		if (skb->len < L2CAP_HDR_SIZE) {
+			BT_ERR("Frame is too small (len %d)", skb->len);
+			goto drop;
+		}
+
+		lh = (l2cap_hdr *)skb->data;
+		tlen = __le16_to_cpu(lh->len);
+		flen = skb->len - L2CAP_HDR_SIZE;
+
+		BT_DBG("Start: total len %d, frag len %d", tlen, flen);
+
+		if (flen == tlen) {
+			/* Complete frame received */
+			l2cap_recv_frame(conn, skb);
+			return 0;
+		}
+
+		/* Allocate skb for the complete frame (with header) */
+		size = L2CAP_HDR_SIZE + tlen;
+		if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
+			goto drop;
+
+		memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
+		conn->rx_len = tlen - flen;
+	} else {
+		BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
+
+		if (!conn->rx_len) {
+			BT_ERR("Unexpected continuation frame (len %d)", skb->len);
+			goto drop;
+		}
+
+		if (skb->len > conn->rx_len) {
+			BT_ERR("Fragment is too large (len %d, expect %d)",
+					skb->len, conn->rx_len);
+			kfree_skb(conn->rx_skb);
+			conn->rx_skb = NULL;
+			conn->rx_len = 0;
+			goto drop;
+		}
+
+		memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
+		conn->rx_len -= skb->len;
+
+		if (!conn->rx_len) {
+			/* Complete frame received */
+			l2cap_recv_frame(conn, conn->rx_skb);
+			conn->rx_skb = NULL;
+		}
+	}
+
+drop:
+	kfree_skb(skb);
+	return 0;
+}
+
+/* ----- Proc fs support ------ */
+static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
+{
+	struct l2cap_pinfo *pi;
+	struct sock *sk;
+	char *ptr = buf;
+
+	write_lock(&list->lock);
+
+	for (sk = list->head; sk; sk = sk->next) {
+		pi = l2cap_pi(sk);
+		ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
+				batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst), 
+				sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
+				pi->link_mode);
+	}
+
+	write_unlock(&list->lock);
+
+	ptr += sprintf(ptr, "\n");
+	return ptr - buf;
+}
+
+static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
+{
+	char *ptr = buf;
+	int len;
+
+	BT_DBG("count %d, offset %ld", count, offset);
+
+	ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
+	len  = ptr - buf;
+
+	if (len <= count + offset)
+		*eof = 1;
+
+	*start = buf + offset;
+	len -= offset;
+
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+
+static struct proto_ops l2cap_sock_ops = {
+	family:		PF_BLUETOOTH,
+	release:	l2cap_sock_release,
+	bind:		l2cap_sock_bind,
+	connect:	l2cap_sock_connect,
+	listen:		l2cap_sock_listen,
+	accept:		l2cap_sock_accept,
+	getname:	l2cap_sock_getname,
+	sendmsg:	l2cap_sock_sendmsg,
+	recvmsg:	bluez_sock_recvmsg,
+	poll:		bluez_sock_poll,
+	socketpair:	sock_no_socketpair,
+	ioctl:		sock_no_ioctl,
+	shutdown:	sock_no_shutdown,
+	setsockopt:	l2cap_sock_setsockopt,
+	getsockopt:	l2cap_sock_getsockopt,
+	mmap:		sock_no_mmap
+};
+
+static struct net_proto_family l2cap_sock_family_ops = {
+	family:		PF_BLUETOOTH,
+	create:		l2cap_sock_create
+};
+
+static struct hci_proto l2cap_hci_proto = {
+	name:		"L2CAP",
+	id:		HCI_PROTO_L2CAP,
+	connect_ind:	l2cap_connect_ind,
+	connect_cfm:	l2cap_connect_cfm,
+	disconn_ind:	l2cap_disconn_ind,
+	recv_acldata:	l2cap_recv_acldata,
+	auth_cfm:	l2cap_auth_cfm,
+	encrypt_cfm:	l2cap_encrypt_cfm
+};
+
+int __init l2cap_init(void)
+{
+	int err;
+
+	if ((err = bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
+		BT_ERR("Can't register L2CAP socket");
+		return err;
+	}
+
+	if ((err = hci_register_proto(&l2cap_hci_proto))) {
+		BT_ERR("Can't register L2CAP protocol");
+		return err;
+	}
+
+	create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
+
+	BT_INFO("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	return 0;
+}
+
+void l2cap_cleanup(void)
+{
+	remove_proc_entry("bluetooth/l2cap", NULL);
+
+	/* Unregister socket and protocol */
+	if (bluez_sock_unregister(BTPROTO_L2CAP))
+		BT_ERR("Can't unregister L2CAP socket");
+
+	if (hci_unregister_proto(&l2cap_hci_proto))
+		BT_ERR("Can't unregister L2CAP protocol");
+}
+
+module_init(l2cap_init);
+module_exit(l2cap_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/l2cap_core.c linux/net/bluetooth/l2cap_core.c
--- linux.orig/net/bluetooth/l2cap_core.c	2001-09-30 19:26:08.000000000 +0000
+++ linux/net/bluetooth/l2cap_core.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,2316 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * BlueZ L2CAP core and sockets.
- *
- * $Id: l2cap_core.c,v 1.19 2001/08/03 04:19:50 maxk Exp $
- */
-#define VERSION "1.1"
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <linux/interrupt.h>
-#include <linux/socket.h>
-#include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/list.h>
-#include <net/sock.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
-#include <net/bluetooth/hci_core.h>
-#include <net/bluetooth/l2cap.h>
-#include <net/bluetooth/l2cap_core.h>
-
-#ifndef L2CAP_DEBUG
-#undef  DBG
-#define DBG( A... )
-#endif
-
-struct proto_ops l2cap_sock_ops;
-
-struct bluez_sock_list l2cap_sk_list = {
-	lock: RW_LOCK_UNLOCKED
-};
-
-struct list_head l2cap_iff_list = LIST_HEAD_INIT(l2cap_iff_list);
-rwlock_t l2cap_rt_lock = RW_LOCK_UNLOCKED;
-
-static int  l2cap_conn_del(struct l2cap_conn *conn, int err);
-
-static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
-static void l2cap_chan_del(struct sock *sk, int err);
-static int  l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
-
-static void l2cap_sock_close(struct sock *sk);
-static void l2cap_sock_kill(struct sock *sk);
-
-static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
-static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
-
-/* -------- L2CAP interfaces & routing --------- */
-/* Add/delete L2CAP interface.
- * Must be called with locked rt_lock
- */ 
-
-static void l2cap_iff_add(struct hci_dev *hdev)
-{
-	struct l2cap_iff *iff;
-
-	DBG("%s", hdev->name);
-
-	DBG("iff_list %p next %p prev %p", &l2cap_iff_list, l2cap_iff_list.next, l2cap_iff_list.prev);
-
-	/* Allocate new interface and lock HCI device */
-	if (!(iff = kmalloc(sizeof(struct l2cap_iff), GFP_KERNEL))) {
-		ERR("Can't allocate new interface %s", hdev->name);
-		return;
-	}
-	memset(iff, 0, sizeof(struct l2cap_iff));
-
-	hci_dev_hold(hdev);
-	hdev->l2cap_data = iff;
-	iff->hdev   = hdev;
-	iff->mtu    = hdev->acl_mtu - HCI_ACL_HDR_SIZE;
-	iff->bdaddr = &hdev->bdaddr;
-
-	spin_lock_init(&iff->lock);
-	INIT_LIST_HEAD(&iff->conn_list);
-
-	list_add(&iff->list, &l2cap_iff_list);
-}
-
-static void l2cap_iff_del(struct hci_dev *hdev)
-{
-	struct l2cap_iff *iff;
-
-	if (!(iff = hdev->l2cap_data))
-		return;
-
-	DBG("%s iff %p", hdev->name, iff);
-
-	list_del(&iff->list);
-
-	l2cap_iff_lock(iff);
-
-	/* Drop connections */
-	while (!list_empty(&iff->conn_list)) {
-		struct l2cap_conn *c;
-
-		c = list_entry(iff->conn_list.next, struct l2cap_conn, list);
-		l2cap_conn_del(c, ENODEV);
-	}
-
-	l2cap_iff_unlock(iff);
-
-	/* Unlock HCI device */
-	hdev->l2cap_data = NULL;
-	hci_dev_put(hdev);
-
-	kfree(iff);
-}
-
-/* Get route. Returns L2CAP interface.
- * Must be called with locked rt_lock
- */
-static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
-{
-	struct list_head *p;
-	int use_src;
-
-	DBG("%s -> %s", batostr(src), batostr(dst));
-
-	use_src = bacmp(src, BDADDR_ANY) ? 0 : 1;
-	
-	/* Simple routing: 
-	 * 	No source address - find interface with bdaddr != dst 
-	 *	Source address 	  - find interface with bdaddr == src 
-	 */
-
-	list_for_each(p, &l2cap_iff_list) {
-		struct l2cap_iff *iff;
-
-		iff = list_entry(p, struct l2cap_iff, list);
-
-		if (use_src && !bacmp(iff->bdaddr, src))
-			return iff;
-		else if (bacmp(iff->bdaddr, dst))
-			return iff;
-	}
-	return NULL;
-}
-
-/* ----- L2CAP timers ------ */
-static void l2cap_sock_timeout(unsigned long arg)
-{
-	struct sock *sk = (struct sock *) arg;
-
-	DBG("sock %p state %d", sk, sk->state);
-
-	bh_lock_sock(sk);
-	switch (sk->state) {
-	case BT_DISCONN:
-		l2cap_chan_del(sk, ETIMEDOUT);
-		break;
-
-	default:
-		sk->err = ETIMEDOUT;
-		sk->state_change(sk);
-		break;
-	};
-	bh_unlock_sock(sk);
-
-	l2cap_sock_kill(sk);
-	sock_put(sk);
-}
-
-static void l2cap_sock_set_timer(struct sock *sk, long timeout)
-{
-	DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
-
-	if (!mod_timer(&sk->timer, jiffies + timeout))
-		sock_hold(sk);
-}
-
-static void l2cap_sock_clear_timer(struct sock *sk)
-{
-	DBG("sock %p state %d", sk, sk->state);
-
-	if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-		__sock_put(sk);
-}
-
-static void l2cap_sock_init_timer(struct sock *sk)
-{
-	init_timer(&sk->timer);
-	sk->timer.function = l2cap_sock_timeout;
-	sk->timer.data = (unsigned long)sk;
-}
-
-static void l2cap_conn_timeout(unsigned long arg)
-{
-	struct l2cap_conn *conn = (void *)arg;
-	
-	DBG("conn %p state %d", conn, conn->state);
-
-	if (conn->state == BT_CONNECTED) {
-		hci_disconnect(conn->hconn, 0x13);
-	}
-		
-	return;
-}
-
-static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
-{
-	DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
-
-	mod_timer(&conn->timer, jiffies + timeout);
-}
-
-static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
-{
-	DBG("conn %p state %d", conn, conn->state);
-
-	del_timer(&conn->timer);
-}
-
-static void l2cap_conn_init_timer(struct l2cap_conn *conn)
-{
-	init_timer(&conn->timer);
-	conn->timer.function = l2cap_conn_timeout;
-	conn->timer.data = (unsigned long)conn;
-}
-
-/* -------- L2CAP connections --------- */
-/* Add new connection to the interface.
- * Interface must be locked
- */
-static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
-{
-	struct l2cap_conn *conn;
-	bdaddr_t *src = iff->bdaddr;
-
-	if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_KERNEL)))
-		return NULL;
-
-	memset(conn, 0, sizeof(struct l2cap_conn));
-
-	conn->state = BT_OPEN;
-	conn->iff   = iff;
-	bacpy(&conn->src, src);
-	bacpy(&conn->dst, dst);
-
-	spin_lock_init(&conn->lock);
-	conn->chan_list.lock = RW_LOCK_UNLOCKED;
-
-	l2cap_conn_init_timer(conn);
-	
-	__l2cap_conn_link(iff, conn);
-
-	DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
-
-	MOD_INC_USE_COUNT;
-
-	return conn;
-}
-
-/* Delete connection on the interface.
- * Interface must be locked
- */
-static int l2cap_conn_del(struct l2cap_conn *conn, int err)
-{
-	struct sock *sk;
-
-	DBG("conn %p, state %d, err %d", conn, conn->state, err);
-
-	l2cap_conn_clear_timer(conn);
-	__l2cap_conn_unlink(conn->iff, conn);
-
-	conn->state = BT_CLOSED;
-
-	if (conn->rx_skb)
-		kfree_skb(conn->rx_skb);
-
-	/* Kill channels */
-	while ((sk = conn->chan_list.head)) {
-		bh_lock_sock(sk);
-		l2cap_sock_clear_timer(sk);
-		l2cap_chan_del(sk, err);
-		bh_unlock_sock(sk);
-
-		l2cap_sock_kill(sk);
-	}
-
-	kfree(conn);
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
-{
-	struct list_head *p;
-
-	list_for_each(p, &iff->conn_list) {
-		struct l2cap_conn *c;
-
-		c = list_entry(p, struct l2cap_conn, list);
-		if (!bacmp(&c->dst, dst))
-			return c;
-	}
-	return NULL;
-}
-
-int l2cap_connect(struct sock *sk)
-{
-	bdaddr_t *src = &l2cap_pi(sk)->src;
-	bdaddr_t *dst = &l2cap_pi(sk)->dst;
-	struct l2cap_conn *conn;
-	struct l2cap_iff *iff;
-	int err = 0;
-
-	DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
-
-	read_lock_bh(&l2cap_rt_lock);
-
-	/* Get route to remote BD address */
-	if (!(iff = l2cap_get_route(src, dst))) {
-		err = -EHOSTUNREACH;
-		goto done;
-	}
-
-	/* Update source addr of the socket */
-	bacpy(src, iff->bdaddr);
-
-	l2cap_iff_lock(iff);
-
-	if (!(conn = l2cap_get_conn_by_addr(iff, dst))) {
-		/* Connection doesn't exist */
-		if (!(conn = l2cap_conn_add(iff, dst))) {
-			l2cap_iff_unlock(iff);
-			err = -ENOMEM;
-			goto done;
-		}
-		conn->out = 1;
-	}
-
-	l2cap_iff_unlock(iff);
-
-	l2cap_chan_add(conn, sk, NULL);
-
-	sk->state = BT_CONNECT;
-	l2cap_sock_set_timer(sk, sk->sndtimeo);
-
-	switch (conn->state) {
-	case BT_CONNECTED:
-		if (sk->type == SOCK_SEQPACKET) {
-			l2cap_conn_req req;
-			req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-			req.psm  = l2cap_pi(sk)->psm;
-			l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-		} else {
-			l2cap_sock_clear_timer(sk);
-			sk->state = BT_CONNECTED;
-		}
-		break;
-
-	case BT_CONNECT:
-		break;
-
-	default:
-		/* Create ACL connection */
-		conn->state = BT_CONNECT;
-		hci_connect(iff->hdev, dst);
-		break;
-	};
-
-done:
-	read_unlock_bh(&l2cap_rt_lock);
-	return err;
-}
-
-/* ------ Channel queues for listening sockets ------ */
-void l2cap_accept_queue(struct sock *parent, struct sock *sk)
-{
-	struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-
-	DBG("parent %p, sk %p", parent, sk);
-
-	sock_hold(sk);
-	l2cap_pi(sk)->parent = parent;
-	l2cap_pi(sk)->next_q = NULL;
-
-	if (!q->head) {
-		q->head = q->tail = sk;
-	} else {
-		struct sock *tail = q->tail;
-
-		l2cap_pi(sk)->prev_q = tail;
-		l2cap_pi(tail)->next_q = sk;
-		q->tail = sk;
-	}
-
-	parent->ack_backlog++;
-}
-
-void l2cap_accept_unlink(struct sock *sk)
-{
-	struct sock *parent = l2cap_pi(sk)->parent;
-	struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-	struct sock *next, *prev;
-
-	DBG("sk %p", sk);
-
-	next = l2cap_pi(sk)->next_q;
-	prev = l2cap_pi(sk)->prev_q;
-
-	if (sk == q->head)
-		q->head = next;
-	if (sk == q->tail)
-		q->tail = prev;
-
-	if (next)
-		l2cap_pi(next)->prev_q = prev;
-	if (prev)
-		l2cap_pi(prev)->next_q = next;
-
-	l2cap_pi(sk)->parent = NULL;
-
-	parent->ack_backlog--;
-	__sock_put(sk);
-}
-
-/* Get next connected channel in queue. */
-struct sock *l2cap_accept_dequeue(struct sock *parent, int state)
-{
-	struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-	struct sock *sk;
-
-	for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
-		if (!state || sk->state == state) {
-			l2cap_accept_unlink(sk);
-			break;
-		}
-	}
-
-	DBG("parent %p, sk %p", parent, sk);
-
-	return sk;
-}
-
-/* -------- Socket interface ---------- */
-static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
-{
-	bdaddr_t *src = &addr->l2_bdaddr;
-	__u16 psm = addr->l2_psm;
-	struct sock *sk;
-
-	for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-		if (l2cap_pi(sk)->psm == psm &&
-		    !bacmp(&l2cap_pi(sk)->src, src))
-			break;
-	}
-
-	return sk;
-}
-
-/* Find socket listening on psm and source bdaddr.
- * Returns closest match.
- */
-static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
-{
-	struct sock *sk, *sk1 = NULL;
-
-	read_lock(&l2cap_sk_list.lock);
-
-	for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-		struct l2cap_pinfo *pi;
-
-		if (sk->state != BT_LISTEN)
-			continue;
-
-		pi = l2cap_pi(sk);
-
-		if (pi->psm == psm) {
-			/* Exact match. */
-			if (!bacmp(&pi->src, src))
-				break;
-
-			/* Closest match */
-			if (!bacmp(&pi->src, BDADDR_ANY))
-				sk1 = sk;
-		}
-	}
-
-	read_unlock(&l2cap_sk_list.lock);
-
-	return sk ? sk : sk1;
-}
-
-static void l2cap_sock_destruct(struct sock *sk)
-{
-	DBG("sk %p", sk);
-
-	skb_queue_purge(&sk->receive_queue);
-	skb_queue_purge(&sk->write_queue);
-
-	MOD_DEC_USE_COUNT;
-}
-
-static void l2cap_sock_cleanup_listen(struct sock *parent)
-{
-	struct sock *sk;
-
-	DBG("parent %p", parent);
-
-	/* Close not yet accepted channels */
-	while ((sk = l2cap_accept_dequeue(parent, 0)))
-		l2cap_sock_close(sk);
-
-	parent->state  = BT_CLOSED;
-	parent->zapped = 1;
-}
-
-/* Kill socket (only if zapped and orphan)
- * Must be called on unlocked socket.
- */
-static void l2cap_sock_kill(struct sock *sk)
-{
-	if (!sk->zapped || sk->socket)
-		return;
-
-	DBG("sk %p state %d", sk, sk->state);
-
-	/* Kill poor orphan */
-	bluez_sock_unlink(&l2cap_sk_list, sk);
-	sk->dead = 1;
-	sock_put(sk);
-}
-
-/* Close socket.
- * Must be called on unlocked socket.
- */
-static void l2cap_sock_close(struct sock *sk)
-{
-	struct l2cap_conn *conn;
-
-	l2cap_sock_clear_timer(sk);
-
-	lock_sock(sk);
-
-	conn = l2cap_pi(sk)->conn;
-
-	DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
-
-	switch (sk->state) {
-	case BT_LISTEN:
-		l2cap_sock_cleanup_listen(sk);
-		break;
-
-	case BT_CONNECTED:
-	case BT_CONFIG:
-		if (sk->type == SOCK_SEQPACKET) {
-			l2cap_disconn_req req;
-
-			sk->state = BT_DISCONN;
-
-			req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-			req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-			l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-
-			l2cap_sock_set_timer(sk, sk->sndtimeo);
-		} else {
-			l2cap_chan_del(sk, ECONNRESET);
-		}
-		break;
-
-	case BT_CONNECT:
-	case BT_DISCONN:
-		l2cap_chan_del(sk, ECONNRESET);
-		break;
-
-	default:
-		sk->zapped = 1;
-		break;
-	};
-
-	release_sock(sk);
-
-	l2cap_sock_kill(sk);
-}
-
-static void l2cap_sock_init(struct sock *sk, struct sock *parent)
-{
-	struct l2cap_pinfo *pi = l2cap_pi(sk);
-
-	DBG("sk %p", sk);
-
-	if (parent) {
-		sk->type = parent->type;
-
-		pi->imtu = l2cap_pi(parent)->imtu;
-		pi->omtu = l2cap_pi(parent)->omtu;
-	} else {
-		pi->imtu = L2CAP_DEFAULT_MTU;
-		pi->omtu = 0;
-	}
-
-	/* Default config options */
-	pi->conf_mtu = L2CAP_DEFAULT_MTU;
-	pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
-}
-
-static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
-{
-	struct sock *sk;
-
-	if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-		return NULL;
-
-	sock_init_data(sock, sk);
-
-	sk->zapped   = 0;
-
-	sk->destruct = l2cap_sock_destruct;
-	sk->sndtimeo = L2CAP_CONN_TIMEOUT;
-
-	sk->protocol = proto;
-	sk->state    = BT_OPEN;
-
-	l2cap_sock_init_timer(sk);
-
-	bluez_sock_link(&l2cap_sk_list, sk);
-
-	MOD_INC_USE_COUNT;
-
-	return sk;
-}
-
-static int l2cap_sock_create(struct socket *sock, int protocol)
-{
-	struct sock *sk;
-
-	DBG("sock %p", sock);
-
-	sock->state = SS_UNCONNECTED;
-
-	if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
-		return -ESOCKTNOSUPPORT;
-
-	sock->ops = &l2cap_sock_ops;
-
-	if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-		return -ENOMEM;
-
-	l2cap_sock_init(sk, NULL);
-
-	return 0;
-}
-
-static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-{
-	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-	struct sock *sk = sock->sk;
-	int err = 0;
-
-	DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
-
-	if (!addr || addr->sa_family != AF_BLUETOOTH)
-		return -EINVAL;
-
-	lock_sock(sk);
-
-	if (sk->state != BT_OPEN) {
-		err = -EBADFD;
-		goto done;
-	}
-
-	write_lock(&l2cap_sk_list.lock);
-
-	if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
-		err = -EADDRINUSE;
-		goto unlock;
-	}
-
-	/* Save source address */
-	bacpy(&l2cap_pi(sk)->src, &la->l2_bdaddr);
-	l2cap_pi(sk)->psm = la->l2_psm;
-	sk->state = BT_BOUND;
-
-unlock:
-	write_unlock(&l2cap_sk_list.lock);
-
-done:
-	release_sock(sk);
-
-	return err;
-}
-
-static int l2cap_sock_w4_connect(struct sock *sk, int flags)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
-	int err = 0;
-
-	DBG("sk %p", sk);
-
-	add_wait_queue(sk->sleep, &wait);
-	current->state = TASK_INTERRUPTIBLE;
-
-	while (sk->state != BT_CONNECTED) {
-		if (!timeo) {
-			err = -EAGAIN;
-			break;
-		}
-
-		release_sock(sk);
-		timeo = schedule_timeout(timeo);
-		lock_sock(sk);
-
-		err = 0;
-		if (sk->state == BT_CONNECTED)
-			break;
-
-		if (sk->err) {
-			err = sock_error(sk);
-			break;
-		}
-
-		if (signal_pending(current)) {
-			err = sock_intr_errno(timeo);
-			break;
-		}
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(sk->sleep, &wait);
-
-	return err;
-}
-
-static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-{
-	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-	struct sock *sk = sock->sk;
-	int err = 0;
-
-	lock_sock(sk);
-
-	DBG("sk %p", sk);
-
-	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-		err = -EINVAL;
-		goto done;
-	}
-
-	if (sk->state != BT_OPEN && sk->state != BT_BOUND) {
-		err = -EBADFD;
-		goto done;
-	}
-
-	if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-		err = -EINVAL;
-		goto done;
-	}
-
-	/* Set destination address and psm */
-	bacpy(&l2cap_pi(sk)->dst, &la->l2_bdaddr);
-	l2cap_pi(sk)->psm = la->l2_psm;
-
-	if ((err = l2cap_connect(sk)))
-		goto done;
-
-	err = l2cap_sock_w4_connect(sk, flags);
-
-done:
-	release_sock(sk);
-	return err;
-}
-
-int l2cap_sock_listen(struct socket *sock, int backlog)
-{
-	struct sock *sk = sock->sk;
-	int err = 0;
-
-	DBG("sk %p backlog %d", sk, backlog);
-
-	lock_sock(sk);
-
-	if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-		err = -EBADFD;
-		goto done;
-	}
-
-	if (!l2cap_pi(sk)->psm) {
-		err = -EINVAL;
-		goto done;
-	}
-
-	sk->max_ack_backlog = backlog;
-	sk->ack_backlog = 0;
-	sk->state = BT_LISTEN;
-
-done:
-	release_sock(sk);
-	return err;
-}
-
-int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	struct sock *sk = sock->sk, *ch;
-	long timeo;
-	int err = 0;
-
-	lock_sock(sk);
-
-	if (sk->state != BT_LISTEN) {
-		err = -EBADFD;
-		goto done;
-	}
-
-	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-
-	DBG("sk %p timeo %ld", sk, timeo);
-
-	/* Wait for an incoming connection. (wake-one). */
-	add_wait_queue_exclusive(sk->sleep, &wait);
-	current->state = TASK_INTERRUPTIBLE;
-	while (!(ch = l2cap_accept_dequeue(sk, BT_CONNECTED))) {
-		if (!timeo) {
-			err = -EAGAIN;
-			break;
-		}
-
-		release_sock(sk);
-		timeo = schedule_timeout(timeo);
-		lock_sock(sk);
-
-		if (sk->state != BT_LISTEN) {
-			err = -EBADFD;
-			break;
-		}
-
-		if (signal_pending(current)) {
-			err = sock_intr_errno(timeo);
-			break;
-		}
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(sk->sleep, &wait);
-
-	if (err)
-		goto done;
-
-	sock_graft(ch, newsock);
-	newsock->state = SS_CONNECTED;
-
-	DBG("new socket %p", ch);
-
-done:
-	release_sock(sk);
-
-	return err;
-}
-
-static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-{
-	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-	struct sock *sk = sock->sk;
-
-	DBG("sock %p, sk %p", sock, sk);
-
-	addr->sa_family = AF_BLUETOOTH;
-	*len = sizeof(struct sockaddr_l2);
-
-	if (peer)
-		bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->dst);
-	else
-		bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->src);
-
-	la->l2_psm = l2cap_pi(sk)->psm;
-
-	return 0;
-}
-
-static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-{
-	struct sock *sk = sock->sk;
-	int err = 0;
-
-	DBG("sock %p, sk %p", sock, sk);
-
-	if (sk->err)
-		return sock_error(sk);
-
-	if (msg->msg_flags & MSG_OOB)
-		return -EOPNOTSUPP;
-
-	lock_sock(sk);
-
-	if (sk->state == BT_CONNECTED)
-		err = l2cap_chan_send(sk, msg, len);
-	else
-		err = -ENOTCONN;
-
-	release_sock(sk);
-	return err;
-}
-
-static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
-{
-	struct sock *sk = sock->sk;
-	int noblock = flags & MSG_DONTWAIT;
-	int copied, err;
-	struct sk_buff *skb;
-
-	DBG("sock %p, sk %p", sock, sk);
-
-	if (flags & (MSG_OOB))
-		return -EOPNOTSUPP;
-
-	if (sk->state == BT_CLOSED)
-		return 0;
-
-	if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
-		return err;
-
-	msg->msg_namelen = 0;
-
-	copied = skb->len;
-	if (len < copied) {
-		msg->msg_flags |= MSG_TRUNC;
-		copied = len;
-	}
-
-	skb->h.raw = skb->data;
-	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-
-	skb_free_datagram(sk, skb);
-
-	return err ? : copied;
-}
-
-int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-{
-	struct sock *sk = sock->sk;
-	struct l2cap_options opts;
-	int err = 0;
-
-	DBG("sk %p", sk);
-
-	lock_sock(sk);
-
-	switch (optname) {
-	case L2CAP_OPTIONS:
-		if (copy_from_user((char *)&opts, optval, optlen)) {
-			err = -EFAULT;
-			break;
-		}
-		l2cap_pi(sk)->imtu = opts.imtu;
-		l2cap_pi(sk)->omtu = opts.omtu;
-		break;
-
-	default:
-		err = -ENOPROTOOPT;
-		break;
-	};
-
-	release_sock(sk);
-	return err;
-}
-
-int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-{
-	struct sock *sk = sock->sk;
-	struct l2cap_options opts;
-	struct l2cap_conninfo cinfo;
-	int len, err = 0; 
-
-	if (get_user(len, optlen))
-		return -EFAULT;
-
-	lock_sock(sk);
-
-	switch (optname) {
-	case L2CAP_OPTIONS:
-		opts.imtu     = l2cap_pi(sk)->imtu;
-		opts.omtu     = l2cap_pi(sk)->omtu;
-		opts.flush_to = l2cap_pi(sk)->flush_to;
-
-		len = MIN(len, sizeof(opts));
-		if (copy_to_user(optval, (char *)&opts, len))
-			err = -EFAULT;
-
-		break;
-
-	case L2CAP_CONNINFO:
-		if (sk->state != BT_CONNECTED) {
-			err = -ENOTCONN;
-			break;
-		}
-
-		cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
-
-		len = MIN(len, sizeof(cinfo));
-		if (copy_to_user(optval, (char *)&cinfo, len))
-			err = -EFAULT;
-
-		break;
-
-	default:
-		err = -ENOPROTOOPT;
-		break;
-	};
-
-	release_sock(sk);
-	return err;
-}
-
-static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
-{
-	struct sock *sk = sock->sk;
-	struct l2cap_accept_q *aq;
-	unsigned int mask;
-
-	DBG("sock %p, sk %p", sock, sk);
-
-	poll_wait(file, sk->sleep, wait);
-	mask = 0;
-
-	if (sk->err || !skb_queue_empty(&sk->error_queue))
-		mask |= POLLERR;
-
-	if (sk->shutdown == SHUTDOWN_MASK)
-		mask |= POLLHUP;
-
-	aq = &l2cap_pi(sk)->accept_q;
-	if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
-		mask |= POLLIN | POLLRDNORM;
-
-	if (sk->state == BT_CLOSED)
-		mask |= POLLHUP;
-
-	if (sock_writeable(sk))
-		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-	else
-		set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-
-	return mask;
-}
-
-static int l2cap_sock_release(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-
-	DBG("sock %p, sk %p", sock, sk);
-
-	if (!sk)
-		return 0;
-
-	sock_orphan(sk);
-
-	l2cap_sock_close(sk);
-
-	return 0;
-}
-
-/* --------- L2CAP channels --------- */
-static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
-{
-	struct sock *s;
-
-	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-		if (l2cap_pi(s)->dcid == cid)
-			break;
-	}
-
-	return s;
-}
-
-static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
-{
-	struct sock *s;
-
-	read_lock(&l->lock);
-	s = __l2cap_get_chan_by_dcid(l, cid);
-	read_unlock(&l->lock);
-
-	return s;
-}
-
-static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-{
-	struct sock *s;
-
-	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-		if (l2cap_pi(s)->scid == cid)
-			break;
-	}
-
-	return s;
-}
-static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-{
-	struct sock *s;
-
-	read_lock(&l->lock);
-	s = __l2cap_get_chan_by_scid(l, cid);
-	read_unlock(&l->lock);
-
-	return s;
-}
-
-static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
-{
-	struct sock *s;
-
-	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-		if (l2cap_pi(s)->ident == ident)
-			break;
-	}
-
-	return s;
-}
-
-static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
-{
-	struct sock *s;
-
-	read_lock(&l->lock);
-	s = __l2cap_get_chan_by_ident(l, ident);
-	read_unlock(&l->lock);
-
-	return s;
-}
-
-static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
-{
-	__u16 cid = 0x0040;
-
-	for (; cid < 0xffff; cid++) {
-		if(!__l2cap_get_chan_by_scid(l, cid))
-			return cid;
-	}
-
-	return 0;
-}
-
-static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
-{
-	sock_hold(sk);
-
-	if (l->head)
-		l2cap_pi(l->head)->prev_c = sk;
-
-	l2cap_pi(sk)->next_c = l->head;
-	l2cap_pi(sk)->prev_c = NULL;
-	l->head = sk;
-}
-
-static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
-{
-	struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
-
-	write_lock(&l->lock);
-	if (sk == l->head)
-		l->head = next;
-
-	if (next)
-		l2cap_pi(next)->prev_c = prev;
-	if (prev)
-		l2cap_pi(prev)->next_c = next;
-	write_unlock(&l->lock);
-
-	__sock_put(sk);
-}
-
-static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-{
-	struct l2cap_chan_list *l = &conn->chan_list;
-
-	DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
-
-	l2cap_conn_clear_timer(conn);
-
-	atomic_inc(&conn->refcnt);
-	l2cap_pi(sk)->conn = conn;
-
-	if (sk->type == SOCK_SEQPACKET) {
-		/* Alloc CID for normal socket */
-		l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-	} else {
-		/* Raw socket can send only signalling messages */
-		l2cap_pi(sk)->scid = 0x0001;
-		l2cap_pi(sk)->dcid = 0x0001;
-		l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-	}
-
-	__l2cap_chan_link(l, sk);
-
-	if (parent)
-		l2cap_accept_queue(parent, sk);
-}
-
-static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-{
-	struct l2cap_chan_list *l = &conn->chan_list;
-
-	write_lock(&l->lock);
-	__l2cap_chan_add(conn, sk, parent);
-	write_unlock(&l->lock);
-}
-
-/* Delete channel. 
- * Must be called on the locked socket. */
-static void l2cap_chan_del(struct sock *sk, int err)
-{
-	struct l2cap_conn *conn;
-	struct sock *parent;
-
-	conn = l2cap_pi(sk)->conn;
-	parent = l2cap_pi(sk)->parent;
-
-	DBG("sk %p, conn %p, err %d", sk, conn, err);
-
-	if (parent) {
-		/* Unlink from parent accept queue */
-		bh_lock_sock(parent);
-		l2cap_accept_unlink(sk);
-		bh_unlock_sock(parent);
-	}
-
-	if (conn) { 
-		long timeout;
-
-		/* Unlink from channel list */
-		l2cap_chan_unlink(&conn->chan_list, sk);
-		l2cap_pi(sk)->conn = NULL;
-
-		if (conn->out)
-			timeout = L2CAP_DISCONN_TIMEOUT;
-		else
-			timeout = L2CAP_CONN_IDLE_TIMEOUT;
-		
-		if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
-			/* Schedule Baseband disconnect */
-			l2cap_conn_set_timer(conn, timeout);
-		}
-	}
-
-	sk->state  = BT_CLOSED;
-	sk->err    = err;
-	sk->state_change(sk);
-
-	sk->zapped = 1;
-}
-
-static void l2cap_conn_ready(struct l2cap_conn *conn)
-{
-	struct l2cap_chan_list *l = &conn->chan_list;
-	struct sock *sk;
-
-	DBG("conn %p", conn);
-
-	read_lock(&l->lock);
-
-	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-		bh_lock_sock(sk);
-
-		if (sk->type != SOCK_SEQPACKET) {
-			sk->state = BT_CONNECTED;
-			sk->state_change(sk);
-			l2cap_sock_clear_timer(sk);
-		} else if (sk->state == BT_CONNECT) {
-			l2cap_conn_req req;
-			req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-			req.psm  = l2cap_pi(sk)->psm;
-			l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-
-			l2cap_sock_set_timer(sk, sk->sndtimeo);
-		}
-
-		bh_unlock_sock(sk);
-	}
-
-	read_unlock(&l->lock);
-}
-
-static void l2cap_chan_ready(struct sock *sk)
-{
-	struct sock *parent = l2cap_pi(sk)->parent;
-
-	DBG("sk %p, parent %p", sk, parent);
-
-	l2cap_pi(sk)->conf_state = 0;
-	l2cap_sock_clear_timer(sk);
-
-	if (!parent) {
-		/* Outgoing channel.
-		 * Wake up socket sleeping on connect.
-		 */
-		sk->state = BT_CONNECTED;
-		sk->state_change(sk);
-	} else {
-		/* Incomming channel.
-		 * Wake up socket sleeping on accept.
-		 */
-		parent->data_ready(parent, 1);
-	}
-}
-
-/* Copy frame to all raw sockets on that connection */
-void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
-{
-	struct l2cap_chan_list *l = &conn->chan_list;
-	struct sk_buff *nskb;
-	struct sock * sk;
-
-	DBG("conn %p", conn);
-
-	read_lock(&l->lock);
-	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-		if (sk->type != SOCK_RAW)
-			continue;
-
-		/* Don't send frame to the socket it came from */
-		if (skb->sk == sk)
-			continue;
-
-		if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-			continue;
-
-		skb_queue_tail(&sk->receive_queue, nskb);
-		sk->data_ready(sk, nskb->len);
-	}
-	read_unlock(&l->lock);
-}
-
-static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
-{
-	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-	struct sk_buff *skb, **frag;
-	int err, size, count, sent=0;
-	l2cap_hdr *lh;
-
-	/* Check outgoing MTU */
-	if (len > l2cap_pi(sk)->omtu)
-		return -EINVAL;
-
-	DBG("sk %p len %d", sk, len);
-
-	/* First fragment (with L2CAP header) */
-	count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
-	size  = L2CAP_HDR_SIZE + count;
-	if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
-		return err;
-
-	/* Create L2CAP header */
-	lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-	lh->len = __cpu_to_le16(len);
-	lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-
-	if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-		err = -EFAULT;
-		goto fail;
-	}
-
-	sent += count;
-	len  -= count;
-
-	/* Continuation fragments (no L2CAP header) */
-	frag = &skb_shinfo(skb)->frag_list;
-	while (len) {
-		count = MIN(conn->iff->mtu, len);
-
-		*frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-		if (!*frag)
-			goto fail;
-		
-		if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-			err = -EFAULT;
-			goto fail;
-		}
-
-		sent += count;
-		len  -= count;
-
-		frag = &(*frag)->next;
-	}
-
-	if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
-		goto fail;
-
-	return sent;
-
-fail:
-	kfree_skb(skb);
-	return err;
-}
-
-/* --------- L2CAP signalling commands --------- */
-static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
-{
-	__u8 id;
-
-	/* Get next available identificator.
-	 *    1 - 199 are used by kernel.
-	 *  200 - 254 are used by utilities like l2ping, etc 
-	 */
-
-	spin_lock(&conn->lock);
-
-	if (++conn->tx_ident > 199)
-		conn->tx_ident = 1;
-
-	id = conn->tx_ident;
-
-	spin_unlock(&conn->lock);
-
-	return id;
-}
-
-static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
-{
-	struct sk_buff *skb;
-	l2cap_cmd_hdr *cmd;
-	l2cap_hdr *lh;
-	int size;
-
-	DBG("code 0x%2.2x, ident 0x%2.2x, len %d", code, ident, len);
-
-	size = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + len;
-	if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-		return NULL;
-
-	lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-	lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + len);
-	lh->cid = __cpu_to_le16(0x0001);
-
-	cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-	cmd->code  = code;
-	cmd->ident = ident;
-	cmd->len   = __cpu_to_le16(len);
-
-	if (len)
-		memcpy(skb_put(skb, len), data, len);
-
-	return skb;
-}
-
-static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
-{
-	struct sk_buff *skb;
-	__u8 ident;
-
-	DBG("code 0x%2.2x", code);
-
-	ident = l2cap_get_ident(conn);
-	if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-		return -ENOMEM;
-	return hci_send_acl(conn->hconn, skb, 0);
-}
-
-static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
-{
-	struct sk_buff *skb;
-
-	DBG("code 0x%2.2x", code);
-
-	if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-		return -ENOMEM;
-	return hci_send_acl(conn->hconn, skb, 0);
-}
-
-static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
-{
-	l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
-	int len;
-
-	*type = opt->type;
-	switch (opt->len) {
-	case 1:
-		*val = *((__u8 *) opt->val);
-		break;
-
-	case 2:
-		*val = __le16_to_cpu(*((__u16 *)opt->val));
-		break;
-
-	case 4:
-		*val = __le32_to_cpu(*((__u32 *)opt->val));
-		break;
-
-	default:
-		*val = 0L;
-		break;
-	};
-
-	DBG("type 0x%2.2x len %d val 0x%8.8x", *type, opt->len, *val);
-
-	len = L2CAP_CONF_OPT_SIZE + opt->len;
-
-	*ptr += len;
-
-	return len;
-}
-
-static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
-{
-	__u8 type, hint; __u32 val;
-	__u8 *ptr = data;
-
-	DBG("sk %p len %d", sk, len);
-
-	while (len >= L2CAP_CONF_OPT_SIZE) {
-		len -= l2cap_get_conf_opt(&ptr, &type, &val);
-
-		hint  = type & 0x80;
-		type &= 0x7f;
-
-		switch (type) {
-		case L2CAP_CONF_MTU:
-			l2cap_pi(sk)->conf_mtu = val;
-			break;
-
-		case L2CAP_CONF_FLUSH_TO:
-			l2cap_pi(sk)->flush_to = val;
-			break;
-
-		case L2CAP_CONF_QOS:
-			break;
-		
-		default:
-			if (hint)
-				break;
-
-			/* FIXME: Reject unknon option */
-			break;
-		};
-	}
-}
-
-static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
-{
-	register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
-
-	DBG("type 0x%2.2x len %d val 0x%8.8x", type, len, val);
-
-	opt->type = type;
-	opt->len  = len;
-	switch (len) {
-	case 1:
-		*((__u8 *) opt->val)  = val;
-		break;
-
-	case 2:
-		*((__u16 *) opt->val) = __cpu_to_le16(val);
-		break;
-
-	case 4:
-		*((__u32 *) opt->val) = __cpu_to_le32(val);
-		break;
-	};
-
-	*ptr += L2CAP_CONF_OPT_SIZE + len;
-}
-
-static int l2cap_build_conf_req(struct sock *sk, __u8 *data)
-{
-	struct l2cap_pinfo *pi = l2cap_pi(sk);
-	l2cap_conf_req *req = (l2cap_conf_req *) data;
-	__u8 *ptr = req->data;
-
-	DBG("sk %p", sk);
-
-	if (pi->imtu != L2CAP_DEFAULT_MTU)
-		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
-
-	/* FIXME. Need actual value of the flush timeout */
-	//if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-	//   l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
-
-	req->dcid  = __cpu_to_le16(pi->dcid);
-	req->flags = __cpu_to_le16(0);
-
-	return ptr - data;
-}
-
-static int l2cap_conf_output(struct sock *sk, __u8 **ptr)
-{
-	struct l2cap_pinfo *pi = l2cap_pi(sk);
-	int result = 0;
-
-	/* Configure output options and let other side know
-	 * which ones we don't like.
-	 */
-	if (pi->conf_mtu < pi->omtu) {
-		l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, l2cap_pi(sk)->omtu);
-		result = L2CAP_CONF_UNACCEPT;
-	} else {
-		pi->omtu = pi->conf_mtu;
-	}
-
-	DBG("sk %p result %d", sk, result);
-	return result;
-}
-
-static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
-{
-	l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-	__u8 *ptr = rsp->data;
-
-	DBG("sk %p complete %d", sk, result ? 1 : 0);
-
-	if (result)
-		*result = l2cap_conf_output(sk, &ptr);
-
-	rsp->scid   = __cpu_to_le16(l2cap_pi(sk)->dcid);
-	rsp->result = __cpu_to_le16(result ? *result : 0);
-	rsp->flags  = __cpu_to_le16(0);
-
-	return ptr - data;
-}
-
-static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-{
-	struct l2cap_chan_list *list = &conn->chan_list;
-	l2cap_conn_req *req = (l2cap_conn_req *) data;
-	l2cap_conn_rsp rsp;
-	struct sock *sk, *parent;
-
-	__u16 scid = __le16_to_cpu(req->scid);
-	__u16 psm  = req->psm;
-
-	DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
-
-	/* Check if we have socket listening on psm */
-	if (!(parent = l2cap_get_sock_listen(&conn->src, psm)))
-		goto reject;
-
-	bh_lock_sock(parent);
-	write_lock(&list->lock);
-
-	/* Check if we already have channel with that dcid */
-	if (__l2cap_get_chan_by_dcid(list, scid))
-		goto unlock;
-
-	/* Check for backlog size */
-	if (parent->ack_backlog > parent->max_ack_backlog)
-		goto unlock;
-
-	if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
-		goto unlock;
-
-	l2cap_sock_init(sk, parent);
-
-	bacpy(&l2cap_pi(sk)->src, &conn->src);
-	bacpy(&l2cap_pi(sk)->dst, &conn->dst);
-	l2cap_pi(sk)->psm  = psm;
-	l2cap_pi(sk)->dcid = scid;
-
-	__l2cap_chan_add(conn, sk, parent);
-	sk->state = BT_CONFIG;
-
-	write_unlock(&list->lock);
-	bh_unlock_sock(parent);
-
-	rsp.dcid   = __cpu_to_le16(l2cap_pi(sk)->scid);
-	rsp.scid   = __cpu_to_le16(l2cap_pi(sk)->dcid);
-	rsp.result = __cpu_to_le16(0);
-	rsp.status = __cpu_to_le16(0);
-	l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
-
-	return 0;
-
-unlock:
-	write_unlock(&list->lock);
-	bh_unlock_sock(parent);
-
-reject:
-	rsp.scid   = __cpu_to_le16(scid);
-	rsp.dcid   = __cpu_to_le16(0);
-	rsp.status = __cpu_to_le16(0);
-	rsp.result = __cpu_to_le16(L2CAP_CONN_NO_MEM);
-	l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
-
-	return 0;
-}
-
-static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-{
-	l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-	__u16 scid, dcid, result, status;
-	struct sock *sk;
-
-	scid   = __le16_to_cpu(rsp->scid);
-	dcid   = __le16_to_cpu(rsp->dcid);
-	result = __le16_to_cpu(rsp->result);
-	status = __le16_to_cpu(rsp->status);
-
-	DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
-
-	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-		return -ENOENT;
-
-	bh_lock_sock(sk);
-
-	if (!result) {
-		char req[64];
-
-		sk->state = BT_CONFIG;
-		l2cap_pi(sk)->dcid = dcid;
-		l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
-
-		l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-	} else {
-		l2cap_chan_del(sk, ECONNREFUSED);
-	}
-
-	bh_unlock_sock(sk);
-	return 0;
-}
-
-static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-{
-	l2cap_conf_req * req = (l2cap_conf_req *) data;
-	__u16 dcid, flags;
-	__u8 rsp[64];
-	struct sock *sk;
-	int result;
-
-	dcid  = __le16_to_cpu(req->dcid);
-	flags = __le16_to_cpu(req->flags);
-
-	DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
-
-	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-		return -ENOENT;
-
-	bh_lock_sock(sk);
-
-	l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
-
-	if (flags & 0x01) {
-		/* Incomplete config. Send empty response. */
-		l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-		goto unlock;
-	}
-
-	/* Complete config. */
-	l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
-
-	if (result)
-		goto unlock;
-
-	/* Output config done */
-	l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
-
-	if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
-		sk->state = BT_CONNECTED;
-		l2cap_chan_ready(sk);
-	} else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
-		char req[64];
-		l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-	}
-
-unlock:
-	bh_unlock_sock(sk);
-
-	return 0;
-}
-
-static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-{
-	l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-	__u16 scid, flags, result;
-	struct sock *sk;
-	int err = 0;
-
-	scid   = __le16_to_cpu(rsp->scid);
-	flags  = __le16_to_cpu(rsp->flags);
-	result = __le16_to_cpu(rsp->result);
-
-	DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
-
-	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-		return -ENOENT;
-
-	bh_lock_sock(sk);
-
-	if (result) {
-		l2cap_disconn_req req;
-
-		/* They didn't like our options. Well... we do not negotiate.
-		 * Close channel.
-		 */
-		sk->state = BT_DISCONN;
-
-		req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-		req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-		l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-
-		l2cap_sock_set_timer(sk, sk->sndtimeo);
-		goto done;
-	}
-
-	if (flags & 0x01)
-		goto done;
-
-	/* Input config done */
-	l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
-
-	if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
-		sk->state = BT_CONNECTED;
-		l2cap_chan_ready(sk);
-	}
-
-done:
-	bh_unlock_sock(sk);
-
-	return err;
-}
-
-static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-{
-	l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-	l2cap_disconn_rsp rsp;
-	__u16 dcid, scid;
-	struct sock *sk;
-
-	scid = __le16_to_cpu(req->scid);
-	dcid = __le16_to_cpu(req->dcid);
-
-	DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
-
-	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-		return 0;
-
-	bh_lock_sock(sk);
-
-	rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-	rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-	l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
-
-	l2cap_chan_del(sk, ECONNRESET);
-
-	bh_unlock_sock(sk);
-
-	l2cap_sock_kill(sk);
-
-	return 0;
-}
-
-static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-{
-	l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-	__u16 dcid, scid;
-	struct sock *sk;
-
-	scid = __le16_to_cpu(rsp->scid);
-	dcid = __le16_to_cpu(rsp->dcid);
-
-	DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
-
-	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-		return -ENOENT;
-
-	bh_lock_sock(sk);
-	l2cap_sock_clear_timer(sk);
-	l2cap_chan_del(sk, ECONNABORTED);
-	bh_unlock_sock(sk);
-
-	l2cap_sock_kill(sk);
-
-	return 0;
-}
-
-static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
-{
-	__u8 *data = skb->data;
-	int len = skb->len;
-	l2cap_cmd_hdr cmd;
-	int err = 0;
-
-	while (len >= L2CAP_CMD_HDR_SIZE) {
-		memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-		data += L2CAP_CMD_HDR_SIZE;
-		len  -= L2CAP_CMD_HDR_SIZE;
-
-		cmd.len = __le16_to_cpu(cmd.len);
-
-		DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
-
-		if (cmd.len > len || !cmd.ident) {
-			DBG("corrupted command");
-			break;
-		}
-
-		switch (cmd.code) {
-		case L2CAP_CONN_REQ:
-			err = l2cap_connect_req(conn, &cmd, data);
-			break;
-
-		case L2CAP_CONN_RSP:
-			err = l2cap_connect_rsp(conn, &cmd, data);
-			break;
-
-		case L2CAP_CONF_REQ:
-			err = l2cap_config_req(conn, &cmd, data);
-			break;
-
-		case L2CAP_CONF_RSP:
-			err = l2cap_config_rsp(conn, &cmd, data);
-			break;
-
-		case L2CAP_DISCONN_REQ:
-			err = l2cap_disconnect_req(conn, &cmd, data);
-			break;
-
-		case L2CAP_DISCONN_RSP:
-			err = l2cap_disconnect_rsp(conn, &cmd, data);
-			break;
-
-		case L2CAP_COMMAND_REJ:
-			/* FIXME: We should process this */
-			l2cap_raw_recv(conn, skb);
-			break;
-
-		case L2CAP_ECHO_REQ:
-			l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-			break;
-
-		case L2CAP_ECHO_RSP:
-		case L2CAP_INFO_REQ:
-		case L2CAP_INFO_RSP:
-			l2cap_raw_recv(conn, skb);
-			break;
-
-		default:
-			ERR("Uknown signaling command 0x%2.2x", cmd.code);
-			err = -EINVAL;
-			break;
-		};
-
-		if (err) {
-			l2cap_cmd_rej rej;
-			DBG("error %d", err);
-
-			/* FIXME: Map err to a valid reason. */
-			rej.reason = __cpu_to_le16(0);
-			l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-		}
-
-		data += cmd.len;
-		len  -= cmd.len;
-	}
-
-	kfree_skb(skb);
-}
-
-static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
-{
-	struct sock *sk;
-
-	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, cid))) {
-		DBG("unknown cid 0x%4.4x", cid);
-		goto drop;
-	}
-
-	DBG("sk %p, len %d", sk, skb->len);
-
-	if (sk->state != BT_CONNECTED)
-		goto drop;
-
-	if (l2cap_pi(sk)->imtu < skb->len)
-		goto drop;
-
-	skb_queue_tail(&sk->receive_queue, skb);
-	sk->data_ready(sk, skb->len);
-
-	return 0;
-
-drop:
-	kfree_skb(skb);
-
-	return 0;
-}
-
-static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
-{
-	l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-	__u16 cid, len;
-
-	skb_pull(skb, L2CAP_HDR_SIZE);
-	cid = __le16_to_cpu(lh->cid);
-	len = __le16_to_cpu(lh->len);
-
-	DBG("len %d, cid 0x%4.4x", len, cid);
-
-	if (cid == 0x0001)
-		l2cap_sig_channel(conn, skb);
-	else	
-		l2cap_data_channel(conn, cid, skb);
-}
-
-/* ------------ L2CAP interface with lower layer (HCI) ------------- */
-static int l2cap_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	struct hci_dev *hdev = (struct hci_dev *) ptr;
-
-	DBG("hdev %s, event %ld", hdev->name, event);
-
-	write_lock(&l2cap_rt_lock);
-
-	switch (event) {
-	case HCI_DEV_UP:
-		l2cap_iff_add(hdev);
-		break;
-
-	case HCI_DEV_DOWN:
-		l2cap_iff_del(hdev);
-		break;
-	};
-
-	write_unlock(&l2cap_rt_lock);
-
-	return NOTIFY_DONE;
-}
-
-int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
-{
-	struct l2cap_iff *iff;
-
-	DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-
-	if (!(iff = hdev->l2cap_data)) {
-		ERR("unknown interface");
-		return 0;
-	}
-
-	/* Always accept connection */
-	return 1;
-}
-
-int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *hconn)
-{
-	struct l2cap_conn *conn;
-	struct l2cap_iff *iff;
-	int err = 0;
-
-	DBG("hdev %s bdaddr %s hconn %p", hdev->name, batostr(bdaddr), hconn);
-
-	if (!(iff = hdev->l2cap_data)) {
-		ERR("unknown interface");
-		return 0;
-	}
-
-	l2cap_iff_lock(iff);
-
-	conn = l2cap_get_conn_by_addr(iff, bdaddr);
-
-	if (conn) {
-		/* Outgoing connection */
-		DBG("Outgoing connection: %s -> %s, %p, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), conn, status);
-
-		if (!status && hconn) {
-			conn->state = BT_CONNECTED;
-			conn->hconn = hconn;
-
-			hconn->l2cap_data = (void *)conn;
-
-			/* Establish channels */
-			l2cap_conn_ready(conn);
-		} else {
-			l2cap_conn_del(conn, bterr(status));
-		}
-	} else {
-		/* Incomming connection */
-		DBG("Incomming connection: %s -> %s, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), status);
-	
-		if (status || !hconn)
-			goto done;
-
-		if (!(conn = l2cap_conn_add(iff, bdaddr))) {
-			err = -ENOMEM;
-			goto done;
-		}
-
-		conn->hconn = hconn;
-		hconn->l2cap_data = (void *)conn;
-
-		conn->state = BT_CONNECTED;
-	}
-
-done:
-	l2cap_iff_unlock(iff);
-
-	return err;
-}
-
-int l2cap_disconn_ind(struct hci_conn *hconn, __u8 reason)
-{
-	struct l2cap_conn *conn = hconn->l2cap_data;
-
-	DBG("hconn %p reason %d", hconn, reason);
-
-	if (!conn) {
-		ERR("unknown connection");
-		return 0;
-	}
-	conn->hconn = NULL;
-
-	l2cap_iff_lock(conn->iff);
-	l2cap_conn_del(conn, bterr(reason));
-	l2cap_iff_unlock(conn->iff);
-
-	return 0;
-}
-
-int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
-{
-	struct l2cap_conn *conn = hconn->l2cap_data;
-
-	if (!conn) {
-		ERR("unknown connection %p", hconn);
-		goto drop;
-	}
-
-	DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
-
-	if (flags & ACL_START) {
-		int flen, tlen, size;
-		l2cap_hdr *lh;
-
-		if (conn->rx_len) {
-			ERR("Unexpected start frame (len %d)", skb->len);
-			kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-			conn->rx_len = 0;
-		}
-
-		if (skb->len < L2CAP_HDR_SIZE) {
-			ERR("Frame is too small (len %d)", skb->len);
-			goto drop;
-		}
-
-		lh = (l2cap_hdr *)skb->data;
-		tlen = __le16_to_cpu(lh->len);
-		flen = skb->len - L2CAP_HDR_SIZE;
-
-		DBG("Start: total len %d, frag len %d", tlen, flen);
-
-		if (flen == tlen) {
-			/* Complete frame received */
-			l2cap_recv_frame(conn, skb);
-			return 0;
-		}
-
-		/* Allocate skb for the complete frame (with header) */
-		size = L2CAP_HDR_SIZE + tlen;
-		if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-			goto drop;
-
-		memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-
-		conn->rx_len = tlen - flen;
-	} else {
-		DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
-
-		if (!conn->rx_len) {
-			ERR("Unexpected continuation frame (len %d)", skb->len);
-			goto drop;
-		}
-
-		if (skb->len > conn->rx_len) {
-			ERR("Fragment is too large (len %d)", skb->len);
-			kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-			goto drop;
-		}
-
-		memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-		conn->rx_len -= skb->len;
-
-		if (!conn->rx_len) {
-			/* Complete frame received */
-			l2cap_recv_frame(conn, conn->rx_skb);
-			conn->rx_skb = NULL;
-		}
-	}
-
-drop:
-	kfree_skb(skb);
-	return 0;
-}
-
-struct proto_ops l2cap_sock_ops = {
-	family:		PF_BLUETOOTH,
-	release:	l2cap_sock_release,
-	bind:		l2cap_sock_bind,
-	connect:	l2cap_sock_connect,
-	listen:		l2cap_sock_listen,
-	accept:		l2cap_sock_accept,
-	getname:	l2cap_sock_getname,
-	sendmsg:	l2cap_sock_sendmsg,
-	recvmsg:	l2cap_sock_recvmsg,
-	poll:		l2cap_sock_poll,
-	socketpair:	sock_no_socketpair,
-	ioctl:		sock_no_ioctl,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	l2cap_sock_setsockopt,
-	getsockopt:	l2cap_sock_getsockopt,
-	mmap:		sock_no_mmap
-};
-
-struct net_proto_family l2cap_sock_family_ops = {
-	family:		PF_BLUETOOTH,
-	create:		l2cap_sock_create
-};
-
-struct hci_proto l2cap_hci_proto = {
-	name:		"L2CAP",
-	id:		HCI_PROTO_L2CAP,
-	connect_ind:	l2cap_connect_ind,
-	connect_cfm:	l2cap_connect_cfm,
-	disconn_ind:	l2cap_disconn_ind,
-	recv_acldata:	l2cap_recv_acldata,
-};
-
-struct notifier_block l2cap_nblock = {
-	notifier_call: l2cap_dev_event
-};
-
-int __init l2cap_init(void)
-{
-	INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-		VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
-	if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
-		ERR("Can't register L2CAP socket");
-		return -EPROTO;
-	}
-
-	if (hci_register_proto(&l2cap_hci_proto) < 0) {
-		ERR("Can't register L2CAP protocol");
-		return -EPROTO;
-	}
-
-	hci_register_notifier(&l2cap_nblock);
-
-	l2cap_register_proc();
-
-	return 0;
-}
-
-void l2cap_cleanup(void)
-{
-	l2cap_unregister_proc();
-
-	/* Unregister socket, protocol and notifier */
-	if (bluez_sock_unregister(BTPROTO_L2CAP))
-		ERR("Can't unregister L2CAP socket");
-
-	if (hci_unregister_proto(&l2cap_hci_proto) < 0)
-		ERR("Can't unregister L2CAP protocol");
-
-	hci_unregister_notifier(&l2cap_nblock);
-
-	/* We _must_ not have any sockets and/or connections
-	 * at this stage.
-	 */
-
-	/* Free interface list and unlock HCI devices */
-	{
-		struct list_head *list = &l2cap_iff_list;
-
-		while (!list_empty(list)) {
-			struct l2cap_iff *iff;
-
-			iff = list_entry(list->next, struct l2cap_iff, list);
-			l2cap_iff_del(iff->hdev);
-		}
-	}
-}
-
-module_init(l2cap_init);
-module_exit(l2cap_cleanup);
-
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
-MODULE_LICENSE("GPL");
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/l2cap_proc.c linux/net/bluetooth/l2cap_proc.c
--- linux.orig/net/bluetooth/l2cap_proc.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/net/bluetooth/l2cap_proc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,165 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * BlueZ L2CAP proc fs support.
- *
- * $Id: l2cap_proc.c,v 1.2 2001/06/02 01:40:09 maxk Exp $
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <linux/interrupt.h>
-#include <linux/socket.h>
-#include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/list.h>
-#include <net/sock.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <net/bluetooth/bluez.h>
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-#include <net/bluetooth/l2cap_core.h>
-
-#ifndef L2CAP_DEBUG
-#undef  DBG
-#define DBG( A... )
-#endif
-
-/* ----- PROC fs support ----- */
-static int l2cap_conn_dump(char *buf, struct l2cap_iff *iff)
-{
-	struct list_head *p;
-	char *ptr = buf;
-
-	list_for_each(p, &iff->conn_list) {
-		struct l2cap_conn *c;
-
-		c = list_entry(p, struct l2cap_conn, list);
-		ptr += sprintf(ptr, "    %p %d %p %p %s %s\n", 
-				c, c->state, c->iff, c->hconn, batostr(&c->src), batostr(&c->dst));
-	}
-
-	return ptr - buf;
-}
-
-static int l2cap_iff_dump(char *buf)
-{
-	struct list_head *p;
-	char *ptr = buf;
-
-	ptr += sprintf(ptr, "Interfaces:\n");
-
-	write_lock(&l2cap_rt_lock);
-
-	list_for_each(p, &l2cap_iff_list) {
-		struct l2cap_iff *iff;
-
-		iff = list_entry(p, struct l2cap_iff, list);
-
-		ptr += sprintf(ptr, "  %s %p %p\n", iff->hdev->name, iff, iff->hdev);
-		
-		l2cap_iff_lock(iff);
-		ptr += l2cap_conn_dump(ptr, iff);
-		l2cap_iff_unlock(iff);
-	}
-
-	write_unlock(&l2cap_rt_lock);
-
-	ptr += sprintf(ptr, "\n");
-
-	return ptr - buf;
-}
-
-static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
-{
-	struct l2cap_pinfo *pi;
-	struct sock *sk;
-	char *ptr = buf;
-
-	ptr += sprintf(ptr, "Sockets:\n");
-
-	write_lock(&list->lock);
-
-	for (sk = list->head; sk; sk = sk->next) {
-		pi = l2cap_pi(sk);
-		ptr += sprintf(ptr, "  %p %d %p %d %s %s 0x%4.4x 0x%4.4x %d %d\n", sk, sk->state, pi->conn, pi->psm,
-		               batostr(&pi->src), batostr(&pi->dst), pi->scid, pi->dcid, pi->imtu, pi->omtu );
-	}
-
-	write_unlock(&list->lock);
-
-	ptr += sprintf(ptr, "\n");
-
-	return ptr - buf;
-}
-
-static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-{
-	char *ptr = buf;
-	int len;
-
-	DBG("count %d, offset %ld", count, offset);
-
-	ptr += l2cap_iff_dump(ptr);
-	ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-	len  = ptr - buf;
-
-	if (len <= count + offset)
-		*eof = 1;
-
-	*start = buf + offset;
-	len -= offset;
-
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-
-	return len;
-}
-
-void l2cap_register_proc(void)
-{
-	create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
-}
-
-void l2cap_unregister_proc(void)
-{
-	remove_proc_entry("bluetooth/l2cap", NULL);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/lib.c linux/net/bluetooth/lib.c
--- linux.orig/net/bluetooth/lib.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/net/bluetooth/lib.c	2002-07-20 01:08:24.000000000 +0000
@@ -25,7 +25,7 @@
 /*
  * BlueZ kernel library.
  *
- * $Id: lib.c,v 1.3 2001/06/22 23:14:23 maxk Exp $
+ * $Id: lib.c,v 1.2 2002/06/20 19:55:08 maxk Exp $
  */
 
 #include <linux/kernel.h>
@@ -105,7 +105,7 @@
 		return EACCES;
 
 	case 0x06:
-		return EINVAL;
+		return EBADE;
 
 	case 0x07:
 		return ENOMEM;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/sco.c linux/net/bluetooth/sco.c
--- linux.orig/net/bluetooth/sco.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/bluetooth/sco.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,1013 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * BlueZ SCO sockets.
+ *
+ * $Id: sco.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
+ */
+#define VERSION "0.2"
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <net/sock.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/sco.h>
+
+#ifndef SCO_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#endif
+
+static struct proto_ops sco_sock_ops;
+
+static struct bluez_sock_list sco_sk_list = {
+	lock: RW_LOCK_UNLOCKED
+};
+
+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
+static void sco_chan_del(struct sock *sk, int err);
+static inline struct sock * sco_chan_get(struct sco_conn *conn);
+
+static int  sco_conn_del(struct hci_conn *conn, int err);
+
+static void sco_sock_close(struct sock *sk);
+static void sco_sock_kill(struct sock *sk);
+
+/* ----- SCO timers ------ */
+static void sco_sock_timeout(unsigned long arg)
+{
+	struct sock *sk = (struct sock *) arg;
+
+	BT_DBG("sock %p state %d", sk, sk->state);
+
+	bh_lock_sock(sk);
+	sk->err = ETIMEDOUT;
+	sk->state_change(sk);
+	bh_unlock_sock(sk);
+
+	sco_sock_kill(sk);
+	sock_put(sk);
+}
+
+static void sco_sock_set_timer(struct sock *sk, long timeout)
+{
+	BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
+
+	if (!mod_timer(&sk->timer, jiffies + timeout))
+		sock_hold(sk);
+}
+
+static void sco_sock_clear_timer(struct sock *sk)
+{
+	BT_DBG("sock %p state %d", sk, sk->state);
+
+	if (timer_pending(&sk->timer) && del_timer(&sk->timer))
+		__sock_put(sk);
+}
+
+static void sco_sock_init_timer(struct sock *sk)
+{
+	init_timer(&sk->timer);
+	sk->timer.function = sco_sock_timeout;
+	sk->timer.data = (unsigned long)sk;
+}
+
+/* -------- SCO connections --------- */
+static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
+{
+	struct hci_dev *hdev = hcon->hdev;
+	struct sco_conn *conn;
+
+	if ((conn = hcon->sco_data))
+		return conn;
+
+	if (status)
+		return conn;
+
+	if (!(conn = kmalloc(sizeof(struct sco_conn), GFP_ATOMIC)))
+		return NULL;
+	memset(conn, 0, sizeof(struct sco_conn));
+
+	spin_lock_init(&conn->lock);
+
+	hcon->sco_data = conn;
+	conn->hcon = hcon;
+
+	conn->src = &hdev->bdaddr;
+	conn->dst = &hcon->dst;
+	
+	if (hdev->sco_mtu > 0)
+		conn->mtu = hdev->sco_mtu;
+	else
+		conn->mtu = 60;
+
+	BT_DBG("hcon %p conn %p", hcon, conn);
+
+	MOD_INC_USE_COUNT;
+	return conn;
+}
+
+static int sco_conn_del(struct hci_conn *hcon, int err)
+{
+	struct sco_conn *conn;
+	struct sock *sk;
+
+	if (!(conn = hcon->sco_data)) 
+		return 0;
+
+	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
+
+	/* Kill socket */
+	if ((sk = sco_chan_get(conn))) {
+		bh_lock_sock(sk);
+		sco_sock_clear_timer(sk);
+		sco_chan_del(sk, err);
+		bh_unlock_sock(sk);
+		sco_sock_kill(sk);
+	}
+
+	hcon->sco_data = NULL;
+	kfree(conn);
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+int sco_connect(struct sock *sk)
+{
+	bdaddr_t *src = &bluez_pi(sk)->src;
+	bdaddr_t *dst = &bluez_pi(sk)->dst;
+	struct sco_conn *conn;
+	struct hci_conn *hcon;
+	struct hci_dev  *hdev;
+	int err = 0;
+
+	BT_DBG("%s -> %s", batostr(src), batostr(dst));
+
+	if (!(hdev = hci_get_route(dst, src)))
+		return -EHOSTUNREACH;
+
+	hci_dev_lock_bh(hdev);
+
+	err = -ENOMEM;
+
+	hcon = hci_connect(hdev, SCO_LINK, dst);
+	if (!hcon)
+		goto done;
+
+	conn = sco_conn_add(hcon, 0);
+	if (!conn) {
+		hci_conn_put(hcon);
+		goto done;
+	}
+
+	/* Update source addr of the socket */
+	bacpy(src, conn->src);
+
+	err = sco_chan_add(conn, sk, NULL);
+	if (err)
+		goto done;
+
+	if (hcon->state == BT_CONNECTED) {
+		sco_sock_clear_timer(sk);
+		sk->state = BT_CONNECTED;
+	} else {
+		sk->state = BT_CONNECT;
+		sco_sock_set_timer(sk, sk->sndtimeo);
+	}
+done:
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+	return err;
+}
+
+static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
+{
+	struct sco_conn *conn = sco_pi(sk)->conn;
+	struct sk_buff *skb;
+	int err, count;
+
+	/* Check outgoing MTU */
+	if (len > conn->mtu)
+		return -EINVAL;
+
+	BT_DBG("sk %p len %d", sk, len);
+
+	count = MIN(conn->mtu, len);
+	if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
+		return err;
+
+	if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
+		err = -EFAULT;
+		goto fail;
+	}
+
+	if ((err = hci_send_sco(conn->hcon, skb)) < 0)
+		goto fail;
+
+	return count;
+
+fail:
+	kfree_skb(skb);
+	return err;
+}
+
+static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
+{
+	struct sock *sk = sco_chan_get(conn);
+
+	if (!sk)
+		goto drop;
+
+	BT_DBG("sk %p len %d", sk, skb->len);
+
+	if (sk->state != BT_CONNECTED)
+		goto drop;
+
+	if (!sock_queue_rcv_skb(sk, skb))
+		return;
+
+drop:
+	kfree_skb(skb);
+	return;
+}
+
+/* -------- Socket interface ---------- */
+static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
+{
+	struct sock *sk;
+
+	for (sk = sco_sk_list.head; sk; sk = sk->next) {
+		if (!bacmp(&bluez_pi(sk)->src, ba))
+			break;
+	}
+
+	return sk;
+}
+
+/* Find socket listening on source bdaddr.
+ * Returns closest match.
+ */
+static struct sock *sco_get_sock_listen(bdaddr_t *src)
+{
+	struct sock *sk, *sk1 = NULL;
+
+	read_lock(&sco_sk_list.lock);
+
+	for (sk = sco_sk_list.head; sk; sk = sk->next) {
+		if (sk->state != BT_LISTEN)
+			continue;
+
+		/* Exact match. */
+		if (!bacmp(&bluez_pi(sk)->src, src))
+			break;
+
+		/* Closest match */
+		if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
+			sk1 = sk;
+	}
+
+	read_unlock(&sco_sk_list.lock);
+
+	return sk ? sk : sk1;
+}
+
+static void sco_sock_destruct(struct sock *sk)
+{
+	BT_DBG("sk %p", sk);
+
+	skb_queue_purge(&sk->receive_queue);
+	skb_queue_purge(&sk->write_queue);
+
+	MOD_DEC_USE_COUNT;
+}
+
+static void sco_sock_cleanup_listen(struct sock *parent)
+{
+	struct sock *sk;
+
+	BT_DBG("parent %p", parent);
+
+	/* Close not yet accepted channels */
+	while ((sk = bluez_accept_dequeue(parent, NULL)))
+		sco_sock_close(sk);
+
+	parent->state  = BT_CLOSED;
+	parent->zapped = 1;
+}
+
+/* Kill socket (only if zapped and orphan)
+ * Must be called on unlocked socket.
+ */
+static void sco_sock_kill(struct sock *sk)
+{
+	if (!sk->zapped || sk->socket)
+		return;
+
+	BT_DBG("sk %p state %d", sk, sk->state);
+
+	/* Kill poor orphan */
+	bluez_sock_unlink(&sco_sk_list, sk);
+	sk->dead = 1;
+	sock_put(sk);
+}
+
+/* Close socket.
+ * Must be called on unlocked socket.
+ */
+static void sco_sock_close(struct sock *sk)
+{
+	struct sco_conn *conn;
+
+	sco_sock_clear_timer(sk);
+
+	lock_sock(sk);
+
+	conn = sco_pi(sk)->conn;
+
+	BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
+
+	switch (sk->state) {
+	case BT_LISTEN:
+		sco_sock_cleanup_listen(sk);
+		break;
+
+	case BT_CONNECTED:
+	case BT_CONFIG:
+	case BT_CONNECT:
+	case BT_DISCONN:
+		sco_chan_del(sk, ECONNRESET);
+		break;
+
+	default:
+		sk->zapped = 1;
+		break;
+	};
+
+	release_sock(sk);
+
+	sco_sock_kill(sk);
+}
+
+static void sco_sock_init(struct sock *sk, struct sock *parent)
+{
+	BT_DBG("sk %p", sk);
+
+	if (parent) 
+		sk->type = parent->type;
+}
+
+static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
+{
+	struct sock *sk;
+
+	if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
+		return NULL;
+
+	bluez_sock_init(sock, sk);
+
+	sk->zapped   = 0;
+
+	sk->destruct = sco_sock_destruct;
+	sk->sndtimeo = SCO_CONN_TIMEOUT;
+
+	sk->protocol = proto;
+	sk->state    = BT_OPEN;
+
+	sco_sock_init_timer(sk);
+
+	bluez_sock_link(&sco_sk_list, sk);
+
+	MOD_INC_USE_COUNT;
+	return sk;
+}
+
+static int sco_sock_create(struct socket *sock, int protocol)
+{
+	struct sock *sk;
+
+	BT_DBG("sock %p", sock);
+
+	sock->state = SS_UNCONNECTED;
+
+	if (sock->type != SOCK_SEQPACKET)
+		return -ESOCKTNOSUPPORT;
+
+	sock->ops = &sco_sock_ops;
+
+	if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
+		return -ENOMEM;
+
+	sco_sock_init(sk, NULL);
+	return 0;
+}
+
+static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+{
+	struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
+	struct sock *sk = sock->sk;
+	bdaddr_t *src = &sa->sco_bdaddr;
+	int err = 0;
+
+	BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
+
+	if (!addr || addr->sa_family != AF_BLUETOOTH)
+		return -EINVAL;
+
+	lock_sock(sk);
+
+	if (sk->state != BT_OPEN) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	write_lock(&sco_sk_list.lock);
+
+	if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
+		err = -EADDRINUSE;
+		goto unlock;
+	}
+
+	/* Save source address */
+	bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr);
+	sk->state = BT_BOUND;
+
+unlock:
+	write_unlock(&sco_sk_list.lock);
+
+done:
+	release_sock(sk);
+
+	return err;
+}
+
+static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
+{
+	struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+
+	BT_DBG("sk %p", sk);
+
+	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
+		return -EINVAL;
+
+	if (sk->state != BT_OPEN && sk->state != BT_BOUND)
+		return -EBADFD;
+
+	if (sk->type != SOCK_SEQPACKET)
+		return -EINVAL;
+
+	lock_sock(sk);
+
+	/* Set destination address and psm */
+	bacpy(&bluez_pi(sk)->dst, &sa->sco_bdaddr);
+
+	if ((err = sco_connect(sk)))
+		goto done;
+
+	err = bluez_sock_w4_connect(sk, flags);
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+int sco_sock_listen(struct socket *sock, int backlog)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	BT_DBG("sk %p backlog %d", sk, backlog);
+
+	lock_sock(sk);
+
+	if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	sk->max_ack_backlog = backlog;
+	sk->ack_backlog = 0;
+	sk->state = BT_LISTEN;
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct sock *sk = sock->sk, *ch;
+	long timeo;
+	int err = 0;
+
+	lock_sock(sk);
+
+	if (sk->state != BT_LISTEN) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
+
+	BT_DBG("sk %p timeo %ld", sk, timeo);
+
+	/* Wait for an incoming connection. (wake-one). */
+	add_wait_queue_exclusive(sk->sleep, &wait);
+	while (!(ch = bluez_accept_dequeue(sk, newsock))) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (!timeo) {
+			err = -EAGAIN;
+			break;
+		}
+
+		release_sock(sk);
+		timeo = schedule_timeout(timeo);
+		lock_sock(sk);
+
+		if (sk->state != BT_LISTEN) {
+			err = -EBADFD;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			err = sock_intr_errno(timeo);
+			break;
+		}
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(sk->sleep, &wait);
+
+	if (err)
+		goto done;
+
+	newsock->state = SS_CONNECTED;
+
+	BT_DBG("new socket %p", ch);
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
+{
+	struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
+	struct sock *sk = sock->sk;
+
+	BT_DBG("sock %p, sk %p", sock, sk);
+
+	addr->sa_family = AF_BLUETOOTH;
+	*len = sizeof(struct sockaddr_sco);
+
+	if (peer)
+		bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->dst);
+	else
+		bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->src);
+
+	return 0;
+}
+
+static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	BT_DBG("sock %p, sk %p", sock, sk);
+
+	if (sk->err)
+		return sock_error(sk);
+
+	if (msg->msg_flags & MSG_OOB)
+		return -EOPNOTSUPP;
+
+	lock_sock(sk);
+
+	if (sk->state == BT_CONNECTED)
+		err = sco_send_frame(sk, msg, len);
+	else
+		err = -ENOTCONN;
+
+	release_sock(sk);
+	return err;
+}
+
+int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	BT_DBG("sk %p", sk);
+
+	lock_sock(sk);
+
+	switch (optname) {
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	};
+
+	release_sock(sk);
+	return err;
+}
+
+int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
+{
+	struct sock *sk = sock->sk;
+	struct sco_options opts;
+	struct sco_conninfo cinfo;
+	int len, err = 0; 
+
+	BT_DBG("sk %p", sk);
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+
+	lock_sock(sk);
+
+	switch (optname) {
+	case SCO_OPTIONS:
+		if (sk->state != BT_CONNECTED) {
+			err = -ENOTCONN;
+			break;
+		}
+		
+		opts.mtu = sco_pi(sk)->conn->mtu;
+
+		BT_INFO("mtu %d", opts.mtu);
+
+		len = MIN(len, sizeof(opts));
+		if (copy_to_user(optval, (char *)&opts, len))
+			err = -EFAULT;
+
+		break;
+
+	case SCO_CONNINFO:
+		if (sk->state != BT_CONNECTED) {
+			err = -ENOTCONN;
+			break;
+		}
+
+		cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
+
+		len = MIN(len, sizeof(cinfo));
+		if (copy_to_user(optval, (char *)&cinfo, len))
+			err = -EFAULT;
+
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	};
+
+	release_sock(sk);
+	return err;
+}
+
+static int sco_sock_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+
+	BT_DBG("sock %p, sk %p", sock, sk);
+
+	if (!sk)
+		return 0;
+
+	sock_orphan(sk);
+	sco_sock_close(sk);
+
+	return 0;
+}
+
+static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
+{
+	BT_DBG("conn %p", conn);
+
+	sco_pi(sk)->conn = conn;
+	conn->sk = sk;
+
+	if (parent)
+		bluez_accept_enqueue(parent, sk);
+}
+
+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
+{
+	int err = 0;
+
+	sco_conn_lock(conn);
+	if (conn->sk) {
+		err = -EBUSY;
+	} else {
+		__sco_chan_add(conn, sk, parent);
+	}
+	sco_conn_unlock(conn);
+	return err;
+}
+
+static inline struct sock * sco_chan_get(struct sco_conn *conn)
+{
+	struct sock *sk = NULL;
+	sco_conn_lock(conn);
+	sk = conn->sk;
+	sco_conn_unlock(conn);
+	return sk;
+}
+
+/* Delete channel. 
+ * Must be called on the locked socket. */
+static void sco_chan_del(struct sock *sk, int err)
+{
+	struct sco_conn *conn;
+
+	conn = sco_pi(sk)->conn;
+
+	BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
+
+	if (conn) { 
+		sco_conn_lock(conn);
+		conn->sk = NULL;
+		sco_pi(sk)->conn = NULL;
+		sco_conn_unlock(conn);
+		hci_conn_put(conn->hcon);
+	}
+
+	sk->state = BT_CLOSED;
+	sk->err   = err;
+	sk->state_change(sk);
+
+	sk->zapped = 1;
+}
+
+static void sco_conn_ready(struct sco_conn *conn)
+{
+	struct sock *parent, *sk;
+
+	BT_DBG("conn %p", conn);
+
+	sco_conn_lock(conn);
+
+	if ((sk = conn->sk)) {
+		sco_sock_clear_timer(sk);
+		bh_lock_sock(sk);
+		sk->state = BT_CONNECTED;
+		sk->state_change(sk);
+		bh_unlock_sock(sk);
+	} else {
+		parent = sco_get_sock_listen(conn->src);
+		if (!parent)
+			goto done;
+
+		bh_lock_sock(parent);
+
+		sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
+		if (!sk) {
+			bh_unlock_sock(parent);
+                	goto done;
+		}
+
+		sco_sock_init(sk, parent);
+
+		bacpy(&bluez_pi(sk)->src, conn->src);
+		bacpy(&bluez_pi(sk)->dst, conn->dst);
+
+		hci_conn_hold(conn->hcon);
+        	__sco_chan_add(conn, sk, parent);
+
+        	sk->state = BT_CONNECTED;
+
+		/* Wake up parent */
+		parent->data_ready(parent, 1);
+	
+        	bh_unlock_sock(parent);
+	}
+
+done:
+	sco_conn_unlock(conn);
+}
+
+/* ----- SCO interface with lower layer (HCI) ----- */
+int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
+{
+	BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+
+	/* Always accept connection */
+	return HCI_LM_ACCEPT;
+}
+
+int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
+{
+	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
+
+	if (hcon->type != SCO_LINK)
+		return 0;
+
+	if (!status) {
+		struct sco_conn *conn;
+
+		conn = sco_conn_add(hcon, status);
+		if (conn)
+			sco_conn_ready(conn);
+	} else 
+		sco_conn_del(hcon, bterr(status));
+	
+	return 0;
+}
+
+int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
+{
+	BT_DBG("hcon %p reason %d", hcon, reason);
+
+	if (hcon->type != SCO_LINK)
+		return 0;
+
+	sco_conn_del(hcon, bterr(reason));
+	return 0;
+}
+
+int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
+{
+	struct sco_conn *conn = hcon->sco_data;
+
+	if (!conn)
+		goto drop;
+
+	BT_DBG("conn %p len %d", conn, skb->len);
+
+	if (skb->len) {
+		sco_recv_frame(conn, skb);
+		return 0;
+	}
+
+drop:
+	kfree_skb(skb);	
+	return 0;
+}
+
+/* ----- Proc fs support ------ */
+static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
+{
+	struct sco_pinfo *pi;
+	struct sock *sk;
+	char *ptr = buf;
+
+	write_lock(&list->lock);
+
+	for (sk = list->head; sk; sk = sk->next) {
+		pi = sco_pi(sk);
+		ptr += sprintf(ptr, "%s %s %d\n",
+				batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
+				sk->state); 
+	}
+
+	write_unlock(&list->lock);
+
+	ptr += sprintf(ptr, "\n");
+
+	return ptr - buf;
+}
+
+static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
+{
+	char *ptr = buf;
+	int len;
+
+	BT_DBG("count %d, offset %ld", count, offset);
+
+	ptr += sco_sock_dump(ptr, &sco_sk_list);
+	len  = ptr - buf;
+
+	if (len <= count + offset)
+		*eof = 1;
+
+	*start = buf + offset;
+	len -= offset;
+
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+
+static struct proto_ops sco_sock_ops = {
+	family:		PF_BLUETOOTH,
+	release:	sco_sock_release,
+	bind:		sco_sock_bind,
+	connect:	sco_sock_connect,
+	listen:		sco_sock_listen,
+	accept:		sco_sock_accept,
+	getname:	sco_sock_getname,
+	sendmsg:	sco_sock_sendmsg,
+	recvmsg:	bluez_sock_recvmsg,
+	poll:		bluez_sock_poll,
+	socketpair:	sock_no_socketpair,
+	ioctl:		sock_no_ioctl,
+	shutdown:	sock_no_shutdown,
+	setsockopt:	sco_sock_setsockopt,
+	getsockopt:	sco_sock_getsockopt,
+	mmap:		sock_no_mmap
+};
+
+static struct net_proto_family sco_sock_family_ops = {
+	family:		PF_BLUETOOTH,
+	create:		sco_sock_create
+};
+
+static struct hci_proto sco_hci_proto = {
+	name:		"SCO",
+	id:		HCI_PROTO_SCO,
+	connect_ind:	sco_connect_ind,
+	connect_cfm:	sco_connect_cfm,
+	disconn_ind:	sco_disconn_ind,
+	recv_scodata:	sco_recv_scodata,
+};
+
+int __init sco_init(void)
+{
+	int err;
+
+	if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
+		BT_ERR("Can't register SCO socket layer");
+		return err;
+	}
+
+	if ((err = hci_register_proto(&sco_hci_proto))) {
+		BT_ERR("Can't register SCO protocol");
+		return err;
+	}
+
+	create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
+
+	BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	return 0;
+}
+
+void sco_cleanup(void)
+{
+	int err;
+
+	remove_proc_entry("bluetooth/sco", NULL);
+
+	/* Unregister socket, protocol and notifier */
+	if ((err = bluez_sock_unregister(BTPROTO_SCO)))
+		BT_ERR("Can't unregister SCO socket layer %d", err);
+
+	if ((err = hci_unregister_proto(&sco_hci_proto)))
+		BT_ERR("Can't unregister SCO protocol %d", err);
+}
+
+module_init(sco_init);
+module_exit(sco_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ SCO ver " VERSION);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bluetooth/syms.c linux/net/bluetooth/syms.c
--- linux.orig/net/bluetooth/syms.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/net/bluetooth/syms.c	2002-07-20 01:08:22.000000000 +0000
@@ -25,7 +25,7 @@
 /*
  * BlueZ symbols.
  *
- * $Id: syms.c,v 1.1 2001/07/12 19:31:24 maxk Exp $
+ * $Id: syms.c,v 1.1 2002/03/08 21:06:59 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -39,7 +39,6 @@
 #include <linux/socket.h>
 
 #include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
 #include <net/bluetooth/hci_core.h>
 
 /* HCI Core */
@@ -47,17 +46,18 @@
 EXPORT_SYMBOL(hci_unregister_dev);
 EXPORT_SYMBOL(hci_register_proto);
 EXPORT_SYMBOL(hci_unregister_proto);
-EXPORT_SYMBOL(hci_register_notifier);
-EXPORT_SYMBOL(hci_unregister_notifier);
 
+EXPORT_SYMBOL(hci_get_route);
 EXPORT_SYMBOL(hci_connect);
-EXPORT_SYMBOL(hci_disconnect);
 EXPORT_SYMBOL(hci_dev_get);
+EXPORT_SYMBOL(hci_conn_auth);
+EXPORT_SYMBOL(hci_conn_encrypt);
 
 EXPORT_SYMBOL(hci_recv_frame);
 EXPORT_SYMBOL(hci_send_acl);
 EXPORT_SYMBOL(hci_send_sco);
 EXPORT_SYMBOL(hci_send_raw);
+EXPORT_SYMBOL(hci_si_event);
 
 /* BlueZ lib */
 EXPORT_SYMBOL(bluez_dump);
@@ -68,5 +68,11 @@
 /* BlueZ sockets */
 EXPORT_SYMBOL(bluez_sock_register);
 EXPORT_SYMBOL(bluez_sock_unregister);
+EXPORT_SYMBOL(bluez_sock_init);
 EXPORT_SYMBOL(bluez_sock_link);
 EXPORT_SYMBOL(bluez_sock_unlink);
+EXPORT_SYMBOL(bluez_sock_recvmsg);
+EXPORT_SYMBOL(bluez_sock_poll);
+EXPORT_SYMBOL(bluez_accept_enqueue);
+EXPORT_SYMBOL(bluez_accept_dequeue);
+EXPORT_SYMBOL(bluez_sock_w4_connect);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bridge/br_forward.c linux/net/bridge/br_forward.c
--- linux.orig/net/bridge/br_forward.c	2001-08-15 08:54:35.000000000 +0000
+++ linux/net/bridge/br_forward.c	2002-07-20 01:08:31.000000000 +0000
@@ -48,12 +48,8 @@
 
 static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb)
 {
-	struct net_device *indev;
-
-	indev = skb->dev;
 	skb->dev = to->dev;
-
-	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, indev, skb->dev,
+	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
 			__br_forward_finish);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/bridge/br_input.c linux/net/bridge/br_input.c
--- linux.orig/net/bridge/br_input.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/bridge/br_input.c	2002-07-20 01:08:29.000000000 +0000
@@ -161,8 +161,10 @@
 handle_special_frame:
 	if (!dest[5]) {
 		br_stp_handle_bpdu(skb);
+		read_unlock(&br->lock);
 		return;
 	}
 
+	read_unlock(&br->lock);
 	kfree_skb(skb);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/core/Makefile linux/net/core/Makefile
--- linux.orig/net/core/Makefile	2001-10-30 23:08:12.000000000 +0000
+++ linux/net/core/Makefile	2002-07-20 01:08:33.000000000 +0000
@@ -26,5 +26,9 @@
 obj-$(CONFIG_NETFILTER) += netfilter.o
 obj-$(CONFIG_NET_DIVERT) += dv.o
 obj-$(CONFIG_NET_PROFILE) += profile.o
+obj-$(CONFIG_NET_PKTGEN) += pktgen.o
+obj-$(CONFIG_NET_RADIO) += wireless.o
+# Ugly. I wish all wireless drivers were moved in drivers/net/wireless
+obj-$(CONFIG_NET_PCMCIA_RADIO) += wireless.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/core/dev.c linux/net/core/dev.c
--- linux.orig/net/core/dev.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/core/dev.c	2002-07-20 01:08:37.000000000 +0000
@@ -102,6 +102,7 @@
 #include <linux/module.h>
 #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
+#include <net/iw_handler.h>
 #endif	/* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
 #ifdef CONFIG_PLIP
 extern int plip_init(void);
@@ -444,7 +445,7 @@
 
 /* 
    Return value is changed to int to prevent illegal usage in future.
-   It is still legal to use to check for device existance.
+   It is still legal to use to check for device existence.
 
    User should understand, that the result returned by this function
    is meaningless, if it was not issued under rtnl semaphore.
@@ -1796,122 +1797,6 @@
 #endif	/* CONFIG_PROC_FS */
 
 
-#ifdef WIRELESS_EXT
-#ifdef CONFIG_PROC_FS
-
-/*
- * Print one entry of /proc/net/wireless
- * This is a clone of /proc/net/dev (just above)
- */
-static int sprintf_wireless_stats(char *buffer, struct net_device *dev)
-{
-	/* Get stats from the driver */
-	struct iw_statistics *stats = (dev->get_wireless_stats ?
-				       dev->get_wireless_stats(dev) :
-				       (struct iw_statistics *) NULL);
-	int size;
-
-	if (stats != (struct iw_statistics *) NULL) {
-		size = sprintf(buffer,
-			       "%6s: %04x  %3d%c  %3d%c  %3d%c  %6d %6d %6d %6d %6d   %6d\n",
-			       dev->name,
-			       stats->status,
-			       stats->qual.qual,
-			       stats->qual.updated & 1 ? '.' : ' ',
-			       stats->qual.level,
-			       stats->qual.updated & 2 ? '.' : ' ',
-			       stats->qual.noise,
-			       stats->qual.updated & 4 ? '.' : ' ',
-			       stats->discard.nwid,
-			       stats->discard.code,
-			       stats->discard.fragment,
-			       stats->discard.retries,
-			       stats->discard.misc,
-			       stats->miss.beacon);
-		stats->qual.updated = 0;
-	}
-	else
-		size = 0;
-
-	return size;
-}
-
-/*
- * Print info for /proc/net/wireless (print all entries)
- * This is a clone of /proc/net/dev (just above)
- */
-static int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-			  int length)
-{
-	int		len = 0;
-	off_t		begin = 0;
-	off_t		pos = 0;
-	int		size;
-	
-	struct net_device *	dev;
-
-	size = sprintf(buffer,
-		       "Inter-| sta-|   Quality        |   Discarded packets               | Missed\n"
-		       " face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon\n"
-			);
-	
-	pos += size;
-	len += size;
-
-	read_lock(&dev_base_lock);
-	for (dev = dev_base; dev != NULL; dev = dev->next) {
-		size = sprintf_wireless_stats(buffer + len, dev);
-		len += size;
-		pos = begin + len;
-
-		if (pos < offset) {
-			len = 0;
-			begin = pos;
-		}
-		if (pos > offset + length)
-			break;
-	}
-	read_unlock(&dev_base_lock);
-
-	*start = buffer + (offset - begin);	/* Start of wanted data */
-	len -= (offset - begin);		/* Start slop */
-	if (len > length)
-		len = length;			/* Ending slop */
-	if (len < 0)
-		len = 0;
-
-	return len;
-}
-#endif	/* CONFIG_PROC_FS */
-
-/*
- *	Allow programatic access to /proc/net/wireless even if /proc
- *	doesn't exist... Also more efficient...
- */
-static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
-{
-	/* Get stats from the driver */
-	struct iw_statistics *stats = (dev->get_wireless_stats ?
-				       dev->get_wireless_stats(dev) :
-				       (struct iw_statistics *) NULL);
-
-	if (stats != (struct iw_statistics *) NULL) {
-		struct iwreq *	wrq = (struct iwreq *)ifr;
-
-		/* Copy statistics to the user buffer */
-		if(copy_to_user(wrq->u.data.pointer, stats,
-				sizeof(struct iw_statistics)))
-			return -EFAULT;
-
-		/* Check if we need to clear the update flag */
-		if(wrq->u.data.flags != 0)
-			stats->qual.updated = 0;
-		return(0);
-	} else
-		return -EOPNOTSUPP;
-}
-#endif	/* WIRELESS_EXT */
-
 /**
  *	netdev_set_master	-	set up master/slave pair
  *	@slave: slave device
@@ -2209,11 +2094,6 @@
 			notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
 			return 0;
 
-#ifdef WIRELESS_EXT
-		case SIOCGIWSTATS:
-			return dev_iwstats(dev, ifr);
-#endif	/* WIRELESS_EXT */
-
 		/*
 		 *	Unknown or private ioctl
 		 */
@@ -2239,17 +2119,6 @@
 				return -EOPNOTSUPP;
 			}
 
-#ifdef WIRELESS_EXT
-			if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
-				if (dev->do_ioctl) {
-					if (!netif_device_present(dev))
-						return -ENODEV;
-					return dev->do_ioctl(dev, ifr, cmd);
-				}
-				return -EOPNOTSUPP;
-			}
-#endif	/* WIRELESS_EXT */
-
 	}
 	return -EINVAL;
 }
@@ -2431,7 +2300,8 @@
 				}
 				dev_load(ifr.ifr_name);
 				rtnl_lock();
-				ret = dev_ifsioc(&ifr, cmd);
+				/* Follow me in net/core/wireless.c */
+				ret = wireless_process_ioctl(&ifr, cmd);
 				rtnl_unlock();
 				if (!ret && IW_IS_GET(cmd) &&
 				    copy_to_user(arg, &ifr, sizeof(struct ifreq)))
@@ -2856,6 +2726,7 @@
 	proc_net_create("dev", 0, dev_get_info);
 	create_proc_read_entry("net/softnet_stat", 0, 0, dev_proc_stats, NULL);
 #ifdef WIRELESS_EXT
+	/* Available in net/core/wireless.c */
 	proc_net_create("wireless", 0, dev_get_wireless_info);
 #endif	/* WIRELESS_EXT */
 #endif	/* CONFIG_PROC_FS */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/core/neighbour.c linux/net/core/neighbour.c
--- linux.orig/net/core/neighbour.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/core/neighbour.c	2002-07-20 01:08:23.000000000 +0000
@@ -54,12 +54,6 @@
 static int neigh_glbl_allocs;
 static struct neigh_table *neigh_tables;
 
-#if defined(__i386__) && defined(CONFIG_SMP)
-#define ASSERT_WL(n) if ((int)((n)->lock.lock) > 0) { printk("WL assertion failed at " __FILE__ "(%d):" __FUNCTION__ "\n", __LINE__); }
-#else
-#define ASSERT_WL(n) do { } while(0)
-#endif
-
 /*
    Neighbour hash table buckets are protected with rwlock tbl->lock.
 
@@ -484,8 +478,6 @@
 
 	NEIGH_PRINTK2("neigh %p is suspecteded.\n", neigh);
 
-	ASSERT_WL(neigh);
-
 	neigh->output = neigh->ops->output;
 
 	for (hh = neigh->hh; hh; hh = hh->hh_next)
@@ -503,8 +495,6 @@
 
 	NEIGH_PRINTK2("neigh %p is connected.\n", neigh);
 
-	ASSERT_WL(neigh);
-
 	neigh->output = neigh->ops->connected_output;
 
 	for (hh = neigh->hh; hh; hh = hh->hh_next)
@@ -529,7 +519,6 @@
 	unsigned long now = jiffies;
 	u8 state = n->nud_state;
 
-	ASSERT_WL(n);
 	if (state&(NUD_NOARP|NUD_PERMANENT))
 		return;
 	if (state&NUD_REACHABLE) {
@@ -1239,6 +1228,7 @@
 	read_lock(&neigh_tbl_lock);
 	for (tbl=neigh_tables; tbl; tbl = tbl->next) {
 		int err = 0;
+		int override = 1;
 		struct neighbour *n;
 
 		if (tbl->family != ndm->ndm_family)
@@ -1266,6 +1256,7 @@
 		if (n) {
 			if (nlh->nlmsg_flags&NLM_F_EXCL)
 				err = -EEXIST;
+			override = nlh->nlmsg_flags&NLM_F_REPLACE;
 		} else if (!(nlh->nlmsg_flags&NLM_F_CREATE))
 			err = -ENOENT;
 		else {
@@ -1278,7 +1269,7 @@
 		if (err == 0) {
 			err = neigh_update(n, nda[NDA_LLADDR-1] ? RTA_DATA(nda[NDA_LLADDR-1]) : NULL,
 					   ndm->ndm_state,
-					   nlh->nlmsg_flags&NLM_F_REPLACE, 0);
+					   override, 0);
 		}
 		if (n)
 			neigh_release(n);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/core/netfilter.c linux/net/core/netfilter.c
--- linux.orig/net/core/netfilter.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/core/netfilter.c	2002-07-20 01:08:36.000000000 +0000
@@ -83,8 +83,7 @@
 /* Do exclusive ranges overlap? */
 static inline int overlap(int min1, int max1, int min2, int max2)
 {
-	return (min1 >= min2 && min1 < max2)
-		|| (max1 > min2 && max1 <= max2);
+	return max1 > min2 && min1 < max2;
 }
 
 /* Functions to register sockopt ranges (exclusive). */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/core/pktgen.c linux/net/core/pktgen.c
--- linux.orig/net/core/pktgen.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/core/pktgen.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,719 @@
+/* $Id: pktgen.c,v 1.1.2.1 2002/03/01 12:15:05 davem Exp $
+ * pktgen.c: Packet Generator for performance evaluation.
+ *
+ * Copyright 2001, 2002 by Robert Olsson <robert.olsson@its.uu.se>
+ *                                 Uppsala University, Sweden
+ *
+ * A tool for loading the network with preconfigurated packets.
+ * The tool is implemented as a linux module.  Parameters are output 
+ * device, IPG (interpacket gap), number of packets, and whether
+ * to use multiple SKBs or just the same one.
+ * pktgen uses the installed interface's output routine.
+ *
+ * Additional hacking by:
+ *
+ * Jens.Laas@data.slu.se
+ * Improved by ANK. 010120.
+ * Improved by ANK even more. 010212.
+ * MAC address typo fixed. 010417 --ro
+ * Integrated.  020301 --DaveM
+ * Added multiskb option 020301 --DaveM
+ * Scaling of results. 020417--sigurdur@linpro.no
+ *
+ * See Documentation/networking/pktgen.txt for how to use this.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/inet.h>
+#include <asm/byteorder.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/proc_fs.h>
+#include <linux/if_arp.h>
+#include <net/checksum.h>
+#include <asm/timex.h>
+
+#define cycles()	((u32)get_cycles())
+
+static char version[] __initdata = 
+  "pktgen.c: v1.1 020418: Packet Generator for packet performance testing.\n";
+
+/* Parameters */
+static char pg_outdev[32], pg_dst[32];
+static int pkt_size = ETH_ZLEN;
+static int nfrags = 0;
+static __u32 pg_count = 100000;  /* Default No packets to send */
+static __u32 pg_ipg = 0;  /* Default Interpacket gap in nsec */
+static int pg_multiskb = 0; /* Use multiple SKBs during packet gen. */
+
+static int debug;
+static int forced_stop;
+static int pg_cpu_speed;
+static int pg_busy;
+
+static __u8 hh[14] = { 
+
+  /* Overrun by /proc config  */
+
+    0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB, 
+
+    /* We fill in SRC address later */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00
+};
+
+static unsigned char *pg_dstmac = hh;
+static char pg_result[512];
+
+static struct net_device *pg_setup_inject(u32 *saddrp)
+{
+	struct net_device *odev;
+	int p1, p2;
+	u32 saddr;
+
+	rtnl_lock();
+	odev = __dev_get_by_name(pg_outdev);
+	if (!odev) {
+		sprintf(pg_result, "No such netdevice: \"%s\"", pg_outdev);
+		goto out_unlock;
+	}
+
+	if (odev->type != ARPHRD_ETHER) {
+		sprintf(pg_result, "Not ethernet device: \"%s\"", pg_outdev);
+		goto out_unlock;
+	}
+
+	if (!netif_running(odev)) {
+		sprintf(pg_result, "Device is down: \"%s\"", pg_outdev);
+		goto out_unlock;
+	}
+
+	for (p1 = 6, p2 = 0; p1 < odev->addr_len + 6; p1++)
+		hh[p1] = odev->dev_addr[p2++];
+
+	saddr = 0;
+	if (odev->ip_ptr) {
+		struct in_device *in_dev = odev->ip_ptr;
+
+		if (in_dev->ifa_list)
+			saddr = in_dev->ifa_list->ifa_address;
+	}
+	atomic_inc(&odev->refcnt);
+	rtnl_unlock();
+
+	*saddrp = saddr;
+	return odev;
+
+out_unlock:
+	rtnl_unlock();
+	return NULL;
+}
+
+static u32 idle_acc_lo, idle_acc_hi;
+
+static void nanospin(int pg_ipg)
+{
+	u32 idle_start, idle;
+
+	idle_start = cycles();
+
+	for (;;) {
+		barrier();
+		idle = cycles() - idle_start;
+		if (idle * 1000 >= pg_ipg * pg_cpu_speed)
+			break;
+	}
+	idle_acc_lo += idle;
+	if (idle_acc_lo < idle)
+		idle_acc_hi++;
+}
+
+static int calc_mhz(void)
+{
+	struct timeval start, stop;
+	u32 start_s, elapsed;
+
+	do_gettimeofday(&start);
+	start_s = cycles();
+	do {
+		barrier();
+		elapsed = cycles() - start_s;
+		if (elapsed == 0)
+			return 0;
+	} while (elapsed < 1000 * 50000);
+	do_gettimeofday(&stop);
+	return elapsed/(stop.tv_usec-start.tv_usec+1000000*(stop.tv_sec-start.tv_sec));
+}
+
+static void cycles_calibrate(void)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		int res = calc_mhz();
+		if (res > pg_cpu_speed)
+			pg_cpu_speed = res;
+	}
+}
+
+static struct sk_buff *fill_packet(struct net_device *odev, __u32 saddr)
+{
+	struct sk_buff *skb;
+	__u8 *eth;
+	struct udphdr *udph;
+	int datalen, iplen;
+	struct iphdr *iph;
+
+	skb = alloc_skb(pkt_size + 64 + 16, GFP_ATOMIC);
+	if (!skb) {
+		sprintf(pg_result, "No memory");
+		return NULL;
+	}
+
+	skb_reserve(skb, 16);
+
+	/*  Reserve for ethernet and IP header  */
+	eth = (__u8 *) skb_push(skb, 14);
+	iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
+	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
+
+	/*  Copy the ethernet header  */
+	memcpy(eth, hh, 14);
+
+	datalen = pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */
+	if (datalen < 0)
+		datalen = 0;
+
+	udph->source = htons(9);
+	udph->dest = htons(9);
+	udph->len = htons(datalen + 8); /* DATA + udphdr */
+	udph->check = 0;  /* No checksum */
+
+	iph->ihl = 5;
+	iph->version = 4;
+	iph->ttl = 3;
+	iph->tos = 0;
+	iph->protocol = IPPROTO_UDP; /* UDP */
+	iph->saddr = saddr;
+	iph->daddr = in_aton(pg_dst);
+	iph->frag_off = 0;
+	iplen = 20 + 8 + datalen;
+	iph->tot_len = htons(iplen);
+	iph->check = 0;
+	iph->check = ip_fast_csum((void *) iph, iph->ihl);
+	skb->protocol = __constant_htons(ETH_P_IP);
+	skb->mac.raw = ((u8 *)iph) - 14;
+	skb->dev = odev;
+	skb->pkt_type = PACKET_HOST;
+
+	if (nfrags <= 0) {
+		skb_put(skb, datalen);
+	} else {
+		int frags = nfrags;
+		int i;
+
+		if (frags > MAX_SKB_FRAGS)
+			frags = MAX_SKB_FRAGS;
+		if (datalen > frags*PAGE_SIZE) {
+			skb_put(skb, datalen-frags*PAGE_SIZE);
+			datalen = frags*PAGE_SIZE;
+		}
+
+		i = 0;
+		while (datalen > 0) {
+			struct page *page = alloc_pages(GFP_KERNEL, 0);
+			skb_shinfo(skb)->frags[i].page = page;
+			skb_shinfo(skb)->frags[i].page_offset = 0;
+			skb_shinfo(skb)->frags[i].size =
+				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+			datalen -= skb_shinfo(skb)->frags[i].size;
+			skb->len += skb_shinfo(skb)->frags[i].size;
+			skb->data_len += skb_shinfo(skb)->frags[i].size;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+
+		while (i < frags) {
+			int rem;
+
+			if (i == 0)
+				break;
+
+			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
+			if (rem == 0)
+				break;
+
+			skb_shinfo(skb)->frags[i - 1].size -= rem;
+
+			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];
+			get_page(skb_shinfo(skb)->frags[i].page);
+			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;
+			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;
+			skb_shinfo(skb)->frags[i].size = rem;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+	}
+
+	return skb;
+}
+
+
+static void pg_inject(void)
+{
+	u32 saddr;
+	struct net_device *odev;
+	struct sk_buff *skb;
+	struct timeval start, stop;
+	u32 total, idle;
+	u32 pc, lcount;
+	char *p = pg_result;
+	u32  pkt_rate, data_rate;
+	char rate_unit;
+
+	odev = pg_setup_inject(&saddr);
+	if (!odev)
+		return;
+
+	skb = fill_packet(odev, saddr);
+	if (skb == NULL)
+		goto out_reldev;
+
+	forced_stop = 0;
+	idle_acc_hi = 0;
+	idle_acc_lo = 0;
+	pc = 0;
+	lcount = pg_count;
+	do_gettimeofday(&start);
+
+	for(;;) {
+		spin_lock_bh(&odev->xmit_lock);
+		if (!netif_queue_stopped(odev)) {
+			struct sk_buff *skb2 = skb;
+
+			if (pg_multiskb)
+				skb2 = skb_copy(skb, GFP_ATOMIC);
+			else
+				atomic_inc(&skb->users);
+			if (!skb2)
+				goto skip;
+			if (odev->hard_start_xmit(skb2, odev)) {
+				kfree_skb(skb2);
+				if (net_ratelimit())
+					printk(KERN_INFO "Hard xmit error\n");
+			}
+			pc++;
+		}
+	skip:
+		spin_unlock_bh(&odev->xmit_lock);
+
+		if (pg_ipg)
+			nanospin(pg_ipg);
+		if (forced_stop)
+			goto out_intr;
+		if (signal_pending(current))
+			goto out_intr;
+
+		if (--lcount == 0) {
+			if (atomic_read(&skb->users) != 1) {
+				u32 idle_start, idle;
+
+				idle_start = cycles();
+				while (atomic_read(&skb->users) != 1) {
+					if (signal_pending(current))
+						goto out_intr;
+					schedule();
+				}
+				idle = cycles() - idle_start;
+				idle_acc_lo += idle;
+				if (idle_acc_lo < idle)
+					idle_acc_hi++;
+			}
+			break;
+		}
+
+		if (netif_queue_stopped(odev) || current->need_resched) {
+			u32 idle_start, idle;
+
+			idle_start = cycles();
+			do {
+				if (signal_pending(current))
+					goto out_intr;
+				if (!netif_running(odev))
+					goto out_intr;
+				if (current->need_resched)
+					schedule();
+				else
+					do_softirq();
+			} while (netif_queue_stopped(odev));
+			idle = cycles() - idle_start;
+			idle_acc_lo += idle;
+			if (idle_acc_lo < idle)
+				idle_acc_hi++;
+		}
+	}
+
+	do_gettimeofday(&stop);
+
+	total = (stop.tv_sec - start.tv_sec) * 1000000 +
+		stop.tv_usec - start.tv_usec;
+
+	if (total == 0) total = 1;  /* division by zero protection */
+ 
+	idle = (((idle_acc_hi<<20)/pg_cpu_speed)<<12)+idle_acc_lo/pg_cpu_speed;
+
+	
+	/* 
+	   Rounding errors is around 1% on pkt_rate when total
+	   is just over 100.000. When total is big (total >=
+	   4.295 sec) pc need to be more than 430 to keep
+	   rounding errors below 1%. Shouldn't be a problem:)
+	   
+	   */
+
+	if (total < 100000) 
+		pkt_rate = (pc*1000000)/total;
+	else if (total < 0xFFFFFFFF/1000)        /* overflow protection: 2^32/1000 */
+		pkt_rate = (pc*1000)/(total/1000);		  
+	else if (total <  0xFFFFFFFF/100)     
+		pkt_rate = (pc*100)/(total/10000);		  
+	else if (total < 0xFFFFFFFF/10)     
+		pkt_rate = (pc*10)/(total/100000);		  
+	else
+		pkt_rate = (pc/(total/1000000));
+	
+	data_rate = (pkt_rate*pkt_size);
+	if (data_rate > 1024*1024 ) {   /* 10 MB/s */
+		data_rate = data_rate / (1024*1024);
+		rate_unit = 'M';
+	} else {
+		data_rate = data_rate / 1024;
+		rate_unit = 'K';
+	}
+	
+	p += sprintf(p, "OK: %u(c%u+d%u) usec, %u (%dbyte,%dfrags) %upps %u%cB/sec",
+		     total, total-idle, idle,
+		     pc, skb->len, skb_shinfo(skb)->nr_frags,
+		     pkt_rate, data_rate, rate_unit
+		);
+	
+
+out_relskb:
+	kfree_skb(skb);
+out_reldev:
+        dev_put(odev);
+	return;
+
+out_intr:
+	sprintf(pg_result, "Interrupted");
+	goto out_relskb;
+}
+
+/* proc/net/pg */
+
+static struct proc_dir_entry *pg_proc_ent = 0;
+static struct proc_dir_entry *pg_busy_proc_ent = 0;
+
+static int proc_pg_busy_read(char *buf , char **start, off_t offset,
+			     int len, int *eof, void *data)
+{
+	char *p;
+  
+	p = buf;
+	p += sprintf(p, "%d\n", pg_busy);
+	*eof = 1;
+  
+	return p-buf;
+}
+
+static int proc_pg_read(char *buf , char **start, off_t offset,
+			int len, int *eof, void *data)
+{
+	char *p;
+	int i;
+  
+	p = buf;
+	p += sprintf(p, "Params: count=%u pkt_size=%u frags %d ipg %u multiskb %d odev \"%s\" dst %s dstmac ",
+		     pg_count, pkt_size, nfrags, pg_ipg, pg_multiskb,
+		     pg_outdev, pg_dst);
+	for (i = 0; i < 6; i++)
+		p += sprintf(p, "%02X%s", pg_dstmac[i], i == 5 ? "\n" : ":");
+
+	if (pg_result[0])
+		p += sprintf(p, "Result: %s\n", pg_result);
+	else
+		p += sprintf(p, "Result: Idle\n");
+	*eof = 1;
+
+	return p - buf;
+}
+
+static int count_trail_chars(const char *buffer, unsigned int maxlen)
+{
+	int i;
+
+	for (i = 0; i < maxlen; i++) {
+		switch (buffer[i]) {
+		case '\"':
+		case '\n':
+		case '\r':
+		case '\t':
+		case ' ':
+		case '=':
+			break;
+		default:
+			goto done;
+		};
+	}
+done:
+	return i;
+}
+
+static unsigned long num_arg(const char *buffer, unsigned long maxlen, 
+			     unsigned long *num)
+{
+	int i = 0;
+
+	*num = 0;
+  
+	for(; i < maxlen; i++) {
+		if ((buffer[i] >= '0') && (buffer[i] <= '9')) {
+			*num *= 10;
+			*num += buffer[i] -'0';
+		} else
+			break;
+	}
+	return i;
+}
+
+static int strn_len(const char *buffer, unsigned int maxlen)
+{
+	int i = 0;
+
+	for(; i < maxlen; i++) {
+		switch (buffer[i]) {
+		case '\"':
+		case '\n':
+		case '\r':
+		case '\t':
+		case ' ':
+			goto done_str;
+		default:
+		};
+	}
+done_str:
+	return i;
+}
+
+static int proc_pg_write(struct file *file, const char *buffer,
+			 unsigned long count, void *data)
+{
+	int i = 0, max, len;
+	char name[16], valstr[32];
+	unsigned long value = 0;
+  
+	if (count < 1) {
+		sprintf(pg_result, "Wrong command format");
+		return -EINVAL;
+	}
+  
+	max = count - i;
+	i += count_trail_chars(&buffer[i], max);
+  
+	/* Read variable name */
+
+	len = strn_len(&buffer[i], sizeof(name) - 1);
+	memset(name, 0, sizeof(name));
+	strncpy(name, &buffer[i], len);
+	i += len;
+  
+	max = count -i;
+	len = count_trail_chars(&buffer[i], max);
+	i += len;
+
+	if (debug)
+		printk("pg: %s,%lu\n", name, count);
+
+	/* Only stop is allowed when we are running */
+  
+	if (!strcmp(name, "stop")) {
+		forced_stop = 1;
+		if (pg_busy)
+			strcpy(pg_result, "Stopping");
+		return count;
+	}
+
+	if (pg_busy) {
+		strcpy(pg_result, "Busy");
+		return -EINVAL;
+	}
+
+	if (!strcmp(name, "pkt_size")) {
+		len = num_arg(&buffer[i], 10, &value);
+		i += len;
+		if (value < 14+20+8)
+			value = 14+20+8;
+		pkt_size = value;
+		sprintf(pg_result, "OK: pkt_size=%u", pkt_size);
+		return count;
+	}
+	if (!strcmp(name, "frags")) {
+		len = num_arg(&buffer[i], 10, &value);
+		i += len;
+		nfrags = value;
+		sprintf(pg_result, "OK: frags=%u", nfrags);
+		return count;
+	}
+	if (!strcmp(name, "ipg")) {
+		len = num_arg(&buffer[i], 10, &value);
+		i += len;
+		pg_ipg = value;
+		sprintf(pg_result, "OK: ipg=%u", pg_ipg);
+		return count;
+	}
+	if (!strcmp(name, "multiskb")) {
+		len = num_arg(&buffer[i], 10, &value);
+		i += len;
+		pg_multiskb = (value ? 1 : 0);
+		sprintf(pg_result, "OK: multiskb=%d", pg_multiskb);
+		return count;
+	}
+	if (!strcmp(name, "count")) {
+		len = num_arg(&buffer[i], 10, &value);
+		i += len;
+		if (value != 0) {
+			pg_count = value;
+			sprintf(pg_result, "OK: count=%u", pg_count);
+		} else 
+			sprintf(pg_result, "ERROR: no point in sending 0 packets. Leaving count=%u", pg_count);
+		return count;
+	}
+	if (!strcmp(name, "odev")) {
+		len = strn_len(&buffer[i], sizeof(pg_outdev) - 1);
+		memset(pg_outdev, 0, sizeof(pg_outdev));
+		strncpy(pg_outdev, &buffer[i], len);
+		i += len;
+		sprintf(pg_result, "OK: odev=%s", pg_outdev);
+		return count;
+	}
+	if (!strcmp(name, "dst")) {
+		len = strn_len(&buffer[i], sizeof(pg_dst) - 1);
+		memset(pg_dst, 0, sizeof(pg_dst));
+		strncpy(pg_dst, &buffer[i], len);
+		if(debug)
+			printk("pg: dst set to: %s\n", pg_dst);
+		i += len;
+		sprintf(pg_result, "OK: dst=%s", pg_dst);
+		return count;
+	}
+	if (!strcmp(name, "dstmac")) {
+		char *v = valstr;
+		unsigned char *m = pg_dstmac;
+
+		len = strn_len(&buffer[i], sizeof(valstr) - 1);
+		memset(valstr, 0, sizeof(valstr));
+		strncpy(valstr, &buffer[i], len);
+		i += len;
+
+		for(*m = 0;*v && m < pg_dstmac + 6; v++) {
+			if (*v >= '0' && *v <= '9') {
+				*m *= 16;
+				*m += *v - '0';
+			}
+			if (*v >= 'A' && *v <= 'F') {
+				*m *= 16;
+				*m += *v - 'A' + 10;
+			}
+			if (*v >= 'a' && *v <= 'f') {
+				*m *= 16;
+				*m += *v - 'a' + 10;
+			}
+			if (*v == ':') {
+				m++;
+				*m = 0;
+			}
+		}	  
+		sprintf(pg_result, "OK: dstmac");
+		return count;
+	}
+
+	if (!strcmp(name, "inject") || !strcmp(name, "start")) {
+		MOD_INC_USE_COUNT;
+		pg_busy = 1;
+		strcpy(pg_result, "Starting");
+		pg_inject();
+		pg_busy = 0;
+		MOD_DEC_USE_COUNT;
+		return count;
+	}
+
+	sprintf(pg_result, "No such parameter \"%s\"", name);
+	return -EINVAL;
+}
+
+static int __init pg_init(void)
+{
+	printk(version);
+	cycles_calibrate();
+	if (pg_cpu_speed == 0) {
+		printk("pktgen: Error: your machine does not have working cycle counter.\n");
+		return -EINVAL;
+	}
+	pg_proc_ent = create_proc_entry("net/pg", 0600, 0);
+	if (!pg_proc_ent) {
+		printk("pktgen: Error: cannot create net/pg procfs entry.\n");
+		return -ENOMEM;
+	}
+	pg_proc_ent->read_proc = proc_pg_read;
+	pg_proc_ent->write_proc = proc_pg_write;
+	pg_proc_ent->data = 0;
+
+	pg_busy_proc_ent = create_proc_entry("net/pg_busy", 0, 0);
+	if (!pg_busy_proc_ent) {
+		printk("pktgen: Error: cannot create net/pg_busy procfs entry.\n");
+		remove_proc_entry("net/pg", NULL);
+		return -ENOMEM;
+	}
+	pg_busy_proc_ent->read_proc = proc_pg_busy_read;
+	pg_busy_proc_ent->data = 0;
+
+	return 0;
+}
+
+static void __exit pg_cleanup(void)
+{
+	remove_proc_entry("net/pg", NULL);
+	remove_proc_entry("net/pg_busy", NULL);
+}
+
+module_init(pg_init);
+module_exit(pg_cleanup);
+
+MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se");
+MODULE_DESCRIPTION("Packet Generator tool");
+MODULE_LICENSE("GPL");
+MODULE_PARM(pg_count, "i");
+MODULE_PARM(pg_ipg, "i");
+MODULE_PARM(pg_cpu_speed, "i");
+MODULE_PARM(pg_multiskb, "i");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/core/skbuff.c linux/net/core/skbuff.c
--- linux.orig/net/core/skbuff.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/core/skbuff.c	2002-07-20 01:08:27.000000000 +0000
@@ -748,7 +748,7 @@
 			if (skb_cloned(skb)) {
 				if (!realloc)
 					BUG();
-				if (!pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+				if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
 					return -ENOMEM;
 			}
 			if (len <= offset) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/core/sock.c linux/net/core/sock.c
--- linux.orig/net/core/sock.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/core/sock.c	2002-07-20 01:08:38.000000000 +0000
@@ -108,6 +108,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
+#include <linux/tcp.h>
 #include <linux/init.h>
 
 #include <asm/uaccess.h>
@@ -626,7 +627,7 @@
 		sysctl_wmem_max = 32767;
 		sysctl_rmem_max = 32767;
 		sysctl_wmem_default = 32767;
-		sysctl_wmem_default = 32767;
+		sysctl_rmem_default = 32767;
 	} else if (num_physpages >= 131072) {
 		sysctl_wmem_max = 131071;
 		sysctl_rmem_max = 131071;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/core/wireless.c linux/net/core/wireless.c
--- linux.orig/net/core/wireless.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/core/wireless.c	2002-07-20 01:08:27.000000000 +0000
@@ -0,0 +1,733 @@
+/*
+ * This file implement the Wireless Extensions APIs.
+ *
+ * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
+ *
+ * (As all part of the Linux kernel, this file is GPL)
+ */
+
+/************************** DOCUMENTATION **************************/
+/*
+ * API definition :
+ * --------------
+ * See <linux/wireless.h> for details of the APIs and the rest.
+ *
+ * History :
+ * -------
+ *
+ * v1 - 5.12.01 - Jean II
+ *	o Created this file.
+ *
+ * v2 - 13.12.01 - Jean II
+ *	o Move /proc/net/wireless stuff from net/core/dev.c to here
+ *	o Make Wireless Extension IOCTLs go through here
+ *	o Added iw_handler handling ;-)
+ *	o Added standard ioctl description
+ *	o Initial dumb commit strategy based on orinoco.c
+ */
+
+/***************************** INCLUDES *****************************/
+
+#include <asm/uaccess.h>		/* copy_to_user() */
+#include <linux/config.h>		/* Not needed ??? */
+#include <linux/types.h>		/* off_t */
+#include <linux/netdevice.h>		/* struct ifreq, dev_get_by_name() */
+
+#include <linux/wireless.h>		/* Pretty obvious */
+#include <net/iw_handler.h>		/* New driver API */
+
+/**************************** CONSTANTS ****************************/
+
+/* This will be turned on later on... */
+#undef WE_STRICT_WRITE		/* Check write buffer size */
+
+/* Debuging stuff */
+#undef WE_IOCTL_DEBUG		/* Debug IOCTL API */
+
+/************************* GLOBAL VARIABLES *************************/
+/*
+ * You should not use global variables, because or re-entrancy.
+ * On our case, it's only const, so it's OK...
+ */
+static const struct iw_ioctl_description	standard_ioctl[] = {
+	/* SIOCSIWCOMMIT (internal) */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCGIWNAME */
+	{ IW_HEADER_TYPE_CHAR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
+	/* SIOCSIWNWID */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
+	/* SIOCGIWNWID */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
+	/* SIOCSIWFREQ */
+	{ IW_HEADER_TYPE_FREQ, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
+	/* SIOCGIWFREQ */
+	{ IW_HEADER_TYPE_FREQ, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
+	/* SIOCSIWMODE */
+	{ IW_HEADER_TYPE_UINT, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
+	/* SIOCGIWMODE */
+	{ IW_HEADER_TYPE_UINT, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
+	/* SIOCSIWSENS */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCGIWSENS */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCSIWRANGE */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCGIWRANGE */
+	{ IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_range), IW_DESCR_FLAG_DUMP},
+	/* SIOCSIWPRIV */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCGIWPRIV (handled directly by us) */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCSIWSTATS */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCGIWSTATS (handled directly by us) */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
+	/* SIOCSIWSPY */
+	{ IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
+	/* SIOCGIWSPY */
+	{ IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
+	/* -- hole -- */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* -- hole -- */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCSIWAP */
+	{ IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
+	/* SIOCGIWAP */
+	{ IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
+	/* -- hole -- */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCGIWAPLIST */
+	{ IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
+	/* -- hole -- */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* -- hole -- */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCSIWESSID */
+	{ IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_EVENT},
+	/* SIOCGIWESSID */
+	{ IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_DUMP},
+	/* SIOCSIWNICKN */
+	{ IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
+	/* SIOCGIWNICKN */
+	{ IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
+	/* -- hole -- */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* -- hole -- */
+	{ IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
+	/* SIOCSIWRATE */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCGIWRATE */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCSIWRTS */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCGIWRTS */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCSIWFRAG */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCGIWFRAG */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCSIWTXPOW */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCGIWTXPOW */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCSIWRETRY */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCGIWRETRY */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCSIWENCODE */
+	{ IW_HEADER_TYPE_POINT, 4, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
+	/* SIOCGIWENCODE */
+	{ IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT},
+	/* SIOCSIWPOWER */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+	/* SIOCGIWPOWER */
+	{ IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
+};
+
+/* Size (in bytes) of the various private data types */
+char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
+
+/************************ COMMON SUBROUTINES ************************/
+/*
+ * Stuff that may be used in various place or doesn't fit in one
+ * of the section below.
+ */
+
+/* ---------------------------------------------------------------- */
+/*
+ * Return the driver handler associated with a specific Wireless Extension.
+ * Called from various place, so make sure it remains efficient.
+ */
+static inline iw_handler get_handler(struct net_device *dev,
+				     unsigned int cmd)
+{
+	unsigned int	index;		/* MUST be unsigned */
+
+	/* Check if we have some wireless handlers defined */
+	if(dev->wireless_handlers == NULL)
+		return NULL;
+
+	/* Try as a standard command */
+	index = cmd - SIOCIWFIRST;
+	if(index < dev->wireless_handlers->num_standard)
+		return dev->wireless_handlers->standard[index];
+
+	/* Try as a private command */
+	index = cmd - SIOCIWFIRSTPRIV;
+	if(index < dev->wireless_handlers->num_private)
+		return dev->wireless_handlers->private[index];
+
+	/* Not found */
+	return NULL;
+}
+
+/* ---------------------------------------------------------------- */
+/*
+ * Get statistics out of the driver
+ */
+static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
+{
+	return (dev->get_wireless_stats ?
+		dev->get_wireless_stats(dev) :
+		(struct iw_statistics *) NULL);
+	/* In the future, get_wireless_stats may move from 'struct net_device'
+	 * to 'struct iw_handler_def', to de-bloat struct net_device.
+	 * Definitely worse a thought... */
+}
+
+/* ---------------------------------------------------------------- */
+/*
+ * Call the commit handler in the driver
+ * (if exist and if conditions are right)
+ *
+ * Note : our current commit strategy is currently pretty dumb,
+ * but we will be able to improve on that...
+ * The goal is to try to agreagate as many changes as possible
+ * before doing the commit. Drivers that will define a commit handler
+ * are usually those that need a reset after changing parameters, so
+ * we want to minimise the number of reset.
+ * A cool idea is to use a timer : at each "set" command, we re-set the
+ * timer, when the timer eventually fires, we call the driver.
+ * Hopefully, more on that later.
+ *
+ * Also, I'm waiting to see how many people will complain about the
+ * netif_running(dev) test. I'm open on that one...
+ * Hopefully, the driver will remember to do a commit in "open()" ;-)
+ */
+static inline int call_commit_handler(struct net_device *	dev)
+{
+	if((netif_running(dev)) &&
+	   (dev->wireless_handlers->standard[0] != NULL)) {
+		/* Call the commit handler on the driver */
+		return dev->wireless_handlers->standard[0](dev, NULL,
+							   NULL, NULL);
+	} else
+		return 0;		/* Command completed successfully */
+}
+
+/* ---------------------------------------------------------------- */
+/*
+ * Number of private arguments
+ */
+static inline int get_priv_size(__u16	args)
+{
+	int	num = args & IW_PRIV_SIZE_MASK;
+	int	type = (args & IW_PRIV_TYPE_MASK) >> 12;
+
+	return num * priv_type_size[type];
+}
+
+
+/******************** /proc/net/wireless SUPPORT ********************/
+/*
+ * The /proc/net/wireless file is a human readable user-space interface
+ * exporting various wireless specific statistics from the wireless devices.
+ * This is the most popular part of the Wireless Extensions ;-)
+ *
+ * This interface is a pure clone of /proc/net/dev (in net/core/dev.c).
+ * The content of the file is basically the content of "struct iw_statistics".
+ */
+
+#ifdef CONFIG_PROC_FS
+
+/* ---------------------------------------------------------------- */
+/*
+ * Print one entry (line) of /proc/net/wireless
+ */
+static inline int sprintf_wireless_stats(char *buffer, struct net_device *dev)
+{
+	/* Get stats from the driver */
+	struct iw_statistics *stats;
+	int size;
+
+	stats = get_wireless_stats(dev);
+	if (stats != (struct iw_statistics *) NULL) {
+		size = sprintf(buffer,
+			       "%6s: %04x  %3d%c  %3d%c  %3d%c  %6d %6d %6d %6d %6d   %6d\n",
+			       dev->name,
+			       stats->status,
+			       stats->qual.qual,
+			       stats->qual.updated & 1 ? '.' : ' ',
+			       stats->qual.level,
+			       stats->qual.updated & 2 ? '.' : ' ',
+			       stats->qual.noise,
+			       stats->qual.updated & 4 ? '.' : ' ',
+			       stats->discard.nwid,
+			       stats->discard.code,
+			       stats->discard.fragment,
+			       stats->discard.retries,
+			       stats->discard.misc,
+			       stats->miss.beacon);
+		stats->qual.updated = 0;
+	}
+	else
+		size = 0;
+
+	return size;
+}
+
+/* ---------------------------------------------------------------- */
+/*
+ * Print info for /proc/net/wireless (print all entries)
+ */
+int dev_get_wireless_info(char * buffer, char **start, off_t offset,
+			  int length)
+{
+	int		len = 0;
+	off_t		begin = 0;
+	off_t		pos = 0;
+	int		size;
+	
+	struct net_device *	dev;
+
+	size = sprintf(buffer,
+		       "Inter-| sta-|   Quality        |   Discarded packets               | Missed\n"
+		       " face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon\n"
+			);
+	
+	pos += size;
+	len += size;
+
+	read_lock(&dev_base_lock);
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+		size = sprintf_wireless_stats(buffer + len, dev);
+		len += size;
+		pos = begin + len;
+
+		if (pos < offset) {
+			len = 0;
+			begin = pos;
+		}
+		if (pos > offset + length)
+			break;
+	}
+	read_unlock(&dev_base_lock);
+
+	*start = buffer + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin);		/* Start slop */
+	if (len > length)
+		len = length;			/* Ending slop */
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+#endif	/* CONFIG_PROC_FS */
+
+/************************** IOCTL SUPPORT **************************/
+/*
+ * The original user space API to configure all those Wireless Extensions
+ * is through IOCTLs.
+ * In there, we check if we need to call the new driver API (iw_handler)
+ * or just call the driver ioctl handler.
+ */
+
+/* ---------------------------------------------------------------- */
+/*
+ *	Allow programatic access to /proc/net/wireless even if /proc
+ *	doesn't exist... Also more efficient...
+ */
+static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
+{
+	/* Get stats from the driver */
+	struct iw_statistics *stats;
+
+	stats = get_wireless_stats(dev);
+	if (stats != (struct iw_statistics *) NULL) {
+		struct iwreq *	wrq = (struct iwreq *)ifr;
+
+		/* Copy statistics to the user buffer */
+		if(copy_to_user(wrq->u.data.pointer, stats,
+				sizeof(struct iw_statistics)))
+			return -EFAULT;
+
+		/* Check if we need to clear the update flag */
+		if(wrq->u.data.flags != 0)
+			stats->qual.updated = 0;
+		return 0;
+	} else
+		return -EOPNOTSUPP;
+}
+
+/* ---------------------------------------------------------------- */
+/*
+ * Export the driver private handler definition
+ * They will be picked up by tools like iwpriv...
+ */
+static inline int ioctl_export_private(struct net_device *	dev,
+				       struct ifreq *		ifr)
+{
+	struct iwreq *				iwr = (struct iwreq *) ifr;
+
+	/* Check if the driver has something to export */
+	if((dev->wireless_handlers->num_private_args == 0) ||
+	   (dev->wireless_handlers->private_args == NULL))
+		return -EOPNOTSUPP;
+
+	/* Check NULL pointer */
+	if(iwr->u.data.pointer == NULL)
+		return -EFAULT;
+#ifdef WE_STRICT_WRITE
+	/* Check if there is enough buffer up there */
+	if(iwr->u.data.length < (SIOCIWLASTPRIV - SIOCIWFIRSTPRIV + 1))
+		return -E2BIG;
+#endif	/* WE_STRICT_WRITE */
+
+	/* Set the number of available ioctls. */
+	iwr->u.data.length = dev->wireless_handlers->num_private_args;
+
+	/* Copy structure to the user buffer. */
+	if (copy_to_user(iwr->u.data.pointer,
+			 dev->wireless_handlers->private_args,
+			 sizeof(struct iw_priv_args) * iwr->u.data.length))
+		return -EFAULT;
+
+	return 0;
+}
+
+/* ---------------------------------------------------------------- */
+/*
+ * Wrapper to call a standard Wireless Extension handler.
+ * We do various checks and also take care of moving data between
+ * user space and kernel space.
+ */
+static inline int ioctl_standard_call(struct net_device *	dev,
+				      struct ifreq *		ifr,
+				      unsigned int		cmd,
+				      iw_handler		handler)
+{
+	struct iwreq *				iwr = (struct iwreq *) ifr;
+	const struct iw_ioctl_description *	descr;
+	struct iw_request_info			info;
+	int					ret = -EINVAL;
+
+	/* Get the description of the IOCTL */
+	descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
+
+#ifdef WE_IOCTL_DEBUG
+	printk(KERN_DEBUG "%s : Found standard handler for 0x%04X\n",
+	       ifr->ifr_name, cmd);
+	printk(KERN_DEBUG "Header type : %d, token type : %d, token_size : %d, max_token : %d\n", descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
+#endif	/* WE_IOCTL_DEBUG */
+
+	/* Prepare the call */
+	info.cmd = cmd;
+	info.flags = 0;
+
+	/* Check if we have a pointer to user space data or not */
+	if(descr->header_type != IW_HEADER_TYPE_POINT) {
+		/* No extra arguments. Trivial to handle */
+		ret = handler(dev, &info, &(iwr->u), NULL);
+	} else {
+		char *	extra;
+		int	err;
+
+		/* Check what user space is giving us */
+		if(IW_IS_SET(cmd)) {
+			/* Check NULL pointer */
+			if((iwr->u.data.pointer == NULL) &&
+			   (iwr->u.data.length != 0))
+				return -EFAULT;
+			/* Check if number of token fits within bounds */
+			if(iwr->u.data.length > descr->max_tokens)
+				return -E2BIG;
+			if(iwr->u.data.length < descr->min_tokens)
+				return -EINVAL;
+		} else {
+			/* Check NULL pointer */
+			if(iwr->u.data.pointer == NULL)
+				return -EFAULT;
+#ifdef WE_STRICT_WRITE
+			/* Check if there is enough buffer up there */
+			if(iwr->u.data.length < descr->max_tokens)
+				return -E2BIG;
+#endif	/* WE_STRICT_WRITE */
+		}
+
+#ifdef WE_IOCTL_DEBUG
+		printk(KERN_DEBUG "Malloc %d bytes\n",
+		       descr->max_tokens * descr->token_size);
+#endif	/* WE_IOCTL_DEBUG */
+
+		/* Always allocate for max space. Easier, and won't last
+		 * long... */
+		extra = kmalloc(descr->max_tokens * descr->token_size,
+				GFP_KERNEL);
+		if (extra == NULL) {
+			return -ENOMEM;
+		}
+
+		/* If it is a SET, get all the extra data in here */
+		if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
+			err = copy_from_user(extra, iwr->u.data.pointer,
+					     iwr->u.data.length *
+					     descr->token_size);
+			if (err) {
+				kfree(extra);
+				return -EFAULT;
+			}
+#ifdef WE_IOCTL_DEBUG
+			printk(KERN_DEBUG "Got %d bytes\n",
+			       iwr->u.data.length * descr->token_size);
+#endif	/* WE_IOCTL_DEBUG */
+		}
+
+		/* Call the handler */
+		ret = handler(dev, &info, &(iwr->u), extra);
+
+		/* If we have something to return to the user */
+		if (!ret && IW_IS_GET(cmd)) {
+			err = copy_to_user(iwr->u.data.pointer, extra,
+					   iwr->u.data.length *
+					   descr->token_size);
+			if (err)
+				ret =  -EFAULT;				   
+#ifdef WE_IOCTL_DEBUG
+			printk(KERN_DEBUG "Wrote %d bytes\n",
+			       iwr->u.data.length * descr->token_size);
+#endif	/* WE_IOCTL_DEBUG */
+		}
+
+		/* Cleanup - I told you it wasn't that long ;-) */
+		kfree(extra);
+	}
+
+	/* Call commit handler if needed and defined */
+	if(ret == -EIWCOMMIT)
+		ret = call_commit_handler(dev);
+
+	/* Here, we will generate the appropriate event if needed */
+
+	return ret;
+}
+
+/* ---------------------------------------------------------------- */
+/*
+ * Wrapper to call a private Wireless Extension handler.
+ * We do various checks and also take care of moving data between
+ * user space and kernel space.
+ * It's not as nice and slimline as the standard wrapper. The cause
+ * is struct iw_priv_args, which was not really designed for the
+ * job we are going here.
+ *
+ * IMPORTANT : This function prevent to set and get data on the same
+ * IOCTL and enforce the SET/GET convention. Not doing it would be
+ * far too hairy...
+ * If you need to set and get data at the same time, please don't use
+ * a iw_handler but process it in your ioctl handler (i.e. use the
+ * old driver API).
+ */
+static inline int ioctl_private_call(struct net_device *	dev,
+				     struct ifreq *		ifr,
+				     unsigned int		cmd,
+				     iw_handler		handler)
+{
+	struct iwreq *			iwr = (struct iwreq *) ifr;
+	struct iw_priv_args *		descr = NULL;
+	struct iw_request_info		info;
+	int				extra_size = 0;
+	int				i;
+	int				ret = -EINVAL;
+
+	/* Get the description of the IOCTL */
+	for(i = 0; i < dev->wireless_handlers->num_private_args; i++)
+		if(cmd == dev->wireless_handlers->private_args[i].cmd) {
+			descr = &(dev->wireless_handlers->private_args[i]);
+			break;
+		}
+
+#ifdef WE_IOCTL_DEBUG
+	printk(KERN_DEBUG "%s : Found private handler for 0x%04X\n",
+	       ifr->ifr_name, cmd);
+	if(descr) {
+		printk(KERN_DEBUG "Name %s, set %X, get %X\n",
+		       descr->name, descr->set_args, descr->get_args);
+	}
+#endif	/* WE_IOCTL_DEBUG */
+
+	/* Compute the size of the set/get arguments */
+	if(descr != NULL) {
+		if(IW_IS_SET(cmd)) {
+			/* Size of set arguments */
+			extra_size = get_priv_size(descr->set_args);
+
+			/* Does it fits in iwr ? */
+			if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
+			   (extra_size < IFNAMSIZ))
+				extra_size = 0;
+		} else {
+			/* Size of set arguments */
+			extra_size = get_priv_size(descr->get_args);
+
+			/* Does it fits in iwr ? */
+			if((descr->get_args & IW_PRIV_SIZE_FIXED) &&
+			   (extra_size < IFNAMSIZ))
+				extra_size = 0;
+		}
+	}
+
+	/* Prepare the call */
+	info.cmd = cmd;
+	info.flags = 0;
+
+	/* Check if we have a pointer to user space data or not. */
+	if(extra_size == 0) {
+		/* No extra arguments. Trivial to handle */
+		ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u));
+	} else {
+		char *	extra;
+		int	err;
+
+		/* Check what user space is giving us */
+		if(IW_IS_SET(cmd)) {
+			/* Check NULL pointer */
+			if((iwr->u.data.pointer == NULL) &&
+			   (iwr->u.data.length != 0))
+				return -EFAULT;
+
+			/* Does it fits within bounds ? */
+			if(iwr->u.data.length > (descr->set_args &
+						 IW_PRIV_SIZE_MASK))
+				return -E2BIG;
+		} else {
+			/* Check NULL pointer */
+			if(iwr->u.data.pointer == NULL)
+				return -EFAULT;
+		}
+
+#ifdef WE_IOCTL_DEBUG
+		printk(KERN_DEBUG "Malloc %d bytes\n", extra_size);
+#endif	/* WE_IOCTL_DEBUG */
+
+		/* Always allocate for max space. Easier, and won't last
+		 * long... */
+		extra = kmalloc(extra_size, GFP_KERNEL);
+		if (extra == NULL) {
+			return -ENOMEM;
+		}
+
+		/* If it is a SET, get all the extra data in here */
+		if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
+			err = copy_from_user(extra, iwr->u.data.pointer,
+					     extra_size);
+			if (err) {
+				kfree(extra);
+				return -EFAULT;
+			}
+#ifdef WE_IOCTL_DEBUG
+			printk(KERN_DEBUG "Got %d elem\n", iwr->u.data.length);
+#endif	/* WE_IOCTL_DEBUG */
+		}
+
+		/* Call the handler */
+		ret = handler(dev, &info, &(iwr->u), extra);
+
+		/* If we have something to return to the user */
+		if (!ret && IW_IS_GET(cmd)) {
+			err = copy_to_user(iwr->u.data.pointer, extra,
+					   extra_size);
+			if (err)
+				ret =  -EFAULT;				   
+#ifdef WE_IOCTL_DEBUG
+			printk(KERN_DEBUG "Wrote %d elem\n",
+			       iwr->u.data.length);
+#endif	/* WE_IOCTL_DEBUG */
+		}
+
+		/* Cleanup - I told you it wasn't that long ;-) */
+		kfree(extra);
+	}
+
+
+	/* Call commit handler if needed and defined */
+	if(ret == -EIWCOMMIT)
+		ret = call_commit_handler(dev);
+
+	return ret;
+}
+
+/* ---------------------------------------------------------------- */
+/*
+ * Main IOCTl dispatcher. Called from the main networking code
+ * (dev_ioctl() in net/core/dev.c).
+ * Check the type of IOCTL and call the appropriate wrapper...
+ */
+int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
+{
+	struct net_device *dev;
+	iw_handler	handler;
+
+	/* Permissions are already checked in dev_ioctl() before calling us.
+	 * The copy_to/from_user() of ifr is also dealt with in there */
+
+	/* Make sure the device exist */
+	if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
+		return -ENODEV;
+
+	/* A bunch of special cases, then the generic case...
+	 * Note that 'cmd' is already filtered in dev_ioctl() with
+	 * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
+	switch(cmd) 
+	{
+		case SIOCGIWSTATS:
+			/* Get Wireless Stats */
+			return dev_iwstats(dev, ifr);
+
+		case SIOCGIWPRIV:
+			/* Check if we have some wireless handlers defined */
+			if(dev->wireless_handlers != NULL) {
+				/* We export to user space the definition of
+				 * the private handler ourselves */
+				return ioctl_export_private(dev, ifr);
+			}
+			// ## Fall-through for old API ##
+		default:
+			/* Generic IOCTL */
+			/* Basic check */
+			if (!netif_device_present(dev))
+				return -ENODEV;
+			/* New driver API : try to find the handler */
+			handler = get_handler(dev, cmd);
+			if(handler != NULL) {
+				/* Standard and private are not the same */
+				if(cmd < SIOCIWFIRSTPRIV)
+					return ioctl_standard_call(dev,
+								   ifr,
+								   cmd,
+								   handler);
+				else
+					return ioctl_private_call(dev,
+								  ifr,
+								  cmd,
+								  handler);
+			}
+			/* Old driver API : call driver ioctl handler */
+			if (dev->do_ioctl) {
+				return dev->do_ioctl(dev, ifr, cmd);
+			}
+			return -EOPNOTSUPP;
+	}
+	/* Not reached */
+	return -EINVAL;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/econet/af_econet.c linux/net/econet/af_econet.c
--- linux.orig/net/econet/af_econet.c	2001-06-30 02:38:26.000000000 +0000
+++ linux/net/econet/af_econet.c	2002-07-20 01:08:37.000000000 +0000
@@ -1128,3 +1128,5 @@
 
 module_init(econet_proto_init);
 module_exit(econet_proto_exit);
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- linux.orig/net/ipv4/af_inet.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/ipv4/af_inet.c	2002-07-20 01:08:26.000000000 +0000
@@ -620,13 +620,6 @@
 		if (sk->state != TCP_CLOSE) 
 			goto out;
 
-		err = -EAGAIN;
-		if (sk->num == 0) {
-			if (sk->prot->get_port(sk, 0) != 0)
-				goto out;
-			sk->sport = htons(sk->num);
-		}
-
 		err = sk->prot->connect(sk, uaddr, addr_len);
 		if (err < 0)
 			goto out;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/arp.c linux/net/ipv4/arp.c
--- linux.orig/net/ipv4/arp.c	2001-09-07 18:01:20.000000000 +0000
+++ linux/net/ipv4/arp.c	2002-07-20 01:08:31.000000000 +0000
@@ -112,7 +112,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-
+#include <linux/netfilter_arp.h>
 
 /*
  *	Interface to generic neighbour cache.
@@ -450,6 +450,32 @@
 }
 
 /*
+ * Check if we can use proxy ARP for this path
+ */
+
+static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
+{
+	struct in_device *out_dev;
+	int imi, omi = -1;
+
+	if (!IN_DEV_PROXY_ARP(in_dev))
+		return 0;
+
+	if ((imi = IN_DEV_MEDIUM_ID(in_dev)) == 0)
+		return 1;
+	if (imi == -1)
+		return 0;
+
+	/* place to check for proxy_arp for routes */
+
+	if ((out_dev = in_dev_get(rt->u.dst.dev)) != NULL) {
+		omi = IN_DEV_MEDIUM_ID(out_dev);
+		in_dev_put(out_dev);
+	}
+	return (omi != imi && omi != -1);
+}
+
+/*
  *	Interface to link layer: send routine and receive handler.
  */
 
@@ -561,7 +587,8 @@
 	arp_ptr+=dev->addr_len;
 	memcpy(arp_ptr, &dest_ip, 4);
 
-	dev_queue_xmit(skb);
+	/* Send it off, maybe filter it using firewalling first.  */
+	NF_HOOK(NF_ARP, NF_ARP_OUT, skb, NULL, dev, dev_queue_xmit);
 	return;
 
 out:
@@ -574,45 +601,31 @@
 }
 
 /*
- *	Receive an arp request by the device layer.
+ *	Process an arp request.
  */
 
-int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+int arp_process(struct sk_buff *skb)
 {
-	struct arphdr *arp = skb->nh.arph;
-	unsigned char *arp_ptr= (unsigned char *)(arp+1);
+	struct net_device *dev = skb->dev;
+	struct in_device *in_dev = in_dev_get(dev);
+	struct arphdr *arp;
+	unsigned char *arp_ptr;
 	struct rtable *rt;
 	unsigned char *sha, *tha;
 	u32 sip, tip;
 	u16 dev_type = dev->type;
 	int addr_type;
-	struct in_device *in_dev = in_dev_get(dev);
 	struct neighbour *n;
 
-/*
- *	The hardware length of the packet should match the hardware length
- *	of the device.  Similarly, the hardware types should match.  The
- *	device should be ARP-able.  Also, if pln is not 4, then the lookup
- *	is not from an IP number.  We can't currently handle this, so toss
- *	it. 
- */  
-	if (in_dev == NULL ||
-	    arp->ar_hln != dev->addr_len    || 
-	    dev->flags & IFF_NOARP ||
-	    skb->pkt_type == PACKET_OTHERHOST ||
-	    skb->pkt_type == PACKET_LOOPBACK ||
-	    arp->ar_pln != 4)
+	/* arp_rcv below verifies the ARP header, verifies the device
+	 * is ARP'able, and linearizes the SKB (if needed).
+	 */
+
+	if (in_dev == NULL)
 		goto out;
 
-	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-		goto out_of_mem;
-
-	if (skb_is_nonlinear(skb)) {
-		if (skb_linearize(skb, GFP_ATOMIC) != 0)
-			goto freeskb;
-		arp = skb->nh.arph;
-		arp_ptr= (unsigned char *)(arp+1);
-	}
+	arp = skb->nh.arph;
+	arp_ptr= (unsigned char *)(arp+1);
 
 	switch (dev_type) {
 	default:	
@@ -768,7 +781,7 @@
 		} else if (IN_DEV_FORWARD(in_dev)) {
 			if ((rt->rt_flags&RTCF_DNAT) ||
 			    (addr_type == RTN_UNICAST  && rt->u.dst.dev != dev &&
-			     (IN_DEV_PROXY_ARP(in_dev) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
+			     (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
 				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
 				if (n)
 					neigh_release(n);
@@ -827,13 +840,41 @@
 out:
 	if (in_dev)
 		in_dev_put(in_dev);
-freeskb:
 	kfree_skb(skb);
-out_of_mem:
 	return 0;
 }
 
 
+/*
+ *	Receive an arp request from the device layer.
+ */
+
+int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+{
+	struct arphdr *arp = skb->nh.arph;
+
+	if (arp->ar_hln != dev->addr_len ||
+	    dev->flags & IFF_NOARP ||
+	    skb->pkt_type == PACKET_OTHERHOST ||
+	    skb->pkt_type == PACKET_LOOPBACK ||
+	    arp->ar_pln != 4)
+		goto freeskb;
+
+	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+		goto out_of_mem;
+
+	if (skb_is_nonlinear(skb)) {
+		if (skb_linearize(skb, GFP_ATOMIC) != 0)
+			goto freeskb;
+	}
+
+	return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
+
+freeskb:
+	kfree_skb(skb);
+out_of_mem:
+	return 0;
+}
 
 /*
  *	User level interface (ioctl, /proc)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/devinet.c linux/net/ipv4/devinet.c
--- linux.orig/net/ipv4/devinet.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/ipv4/devinet.c	2002-07-20 01:08:29.000000000 +0000
@@ -1032,7 +1032,7 @@
 static struct devinet_sysctl_table
 {
 	struct ctl_table_header *sysctl_header;
-	ctl_table devinet_vars[14];
+	ctl_table devinet_vars[15];
 	ctl_table devinet_dev[2];
 	ctl_table devinet_conf_dir[2];
 	ctl_table devinet_proto_dir[2];
@@ -1066,6 +1066,9 @@
 	{NET_IPV4_CONF_PROXY_ARP, "proxy_arp",
          &ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL,
          &proc_dointvec},
+	{NET_IPV4_CONF_MEDIUM_ID, "medium_id",
+         &ipv4_devconf.medium_id, sizeof(int), 0644, NULL,
+         &proc_dointvec},
 	{NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
          &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
          &proc_dointvec},
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
--- linux.orig/net/ipv4/fib_frontend.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/ipv4/fib_frontend.c	2002-07-20 01:08:36.000000000 +0000
@@ -579,6 +579,9 @@
 	switch (event) {
 	case NETDEV_UP:
 		fib_add_ifaddr(ifa);
+#ifdef CONFIG_IP_ROUTE_MULTIPATH
+		fib_sync_up(ifa->ifa_dev->dev);
+#endif
 		rt_cache_flush(-1);
 		break;
 	case NETDEV_DOWN:
@@ -601,6 +604,11 @@
 	struct net_device *dev = ptr;
 	struct in_device *in_dev = __in_dev_get(dev);
 
+	if (event == NETDEV_UNREGISTER) {
+		fib_disable_ip(dev, 2);
+		return NOTIFY_DONE;
+	}
+
 	if (!in_dev)
 		return NOTIFY_DONE;
 
@@ -617,9 +625,6 @@
 	case NETDEV_DOWN:
 		fib_disable_ip(dev, 0);
 		break;
-	case NETDEV_UNREGISTER:
-		fib_disable_ip(dev, 1);
-		break;
 	case NETDEV_CHANGEMTU:
 	case NETDEV_CHANGE:
 		rt_cache_flush(0);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
--- linux.orig/net/ipv4/fib_semantics.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/fib_semantics.c	2002-07-20 01:08:27.000000000 +0000
@@ -56,6 +56,8 @@
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 
+static spinlock_t fib_multipath_lock = SPIN_LOCK_UNLOCKED;
+
 #define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \
 for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
 
@@ -183,6 +185,7 @@
 			continue;
 		for_nexthops(fi) {
 			if (nh->nh_dev == dev && nh->nh_gw == gw &&
+			    nh->nh_scope == RT_SCOPE_LINK &&
 			    !(nh->nh_flags&RTNH_F_DEAD)) {
 				read_unlock(&fib_info_lock);
 				return 0;
@@ -377,15 +380,23 @@
 		/* It is not necessary, but requires a bit of thinking */
 		if (key.scope < RT_SCOPE_LINK)
 			key.scope = RT_SCOPE_LINK;
-
 		if ((err = fib_lookup(&key, &res)) != 0)
 			return err;
+		err = -EINVAL;
+		if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
+			goto out;
 		nh->nh_scope = res.scope;
 		nh->nh_oif = FIB_RES_OIF(res);
-		nh->nh_dev = FIB_RES_DEV(res);
-		if (nh->nh_dev)
-			atomic_inc(&nh->nh_dev->refcnt);
+		if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL)
+			goto out;
+		atomic_inc(&nh->nh_dev->refcnt);
+		err = -ENETDOWN;
+		if (!(nh->nh_dev->flags & IFF_UP))
+			goto out;
+		err = 0;
+out:
 		fib_res_put(&res);
+		return err;
 	} else {
 		struct in_device *in_dev;
 
@@ -869,11 +880,19 @@
 					 nh->nh_scope != scope) {
 					nh->nh_flags |= RTNH_F_DEAD;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
+					spin_lock_bh(&fib_multipath_lock);
 					fi->fib_power -= nh->nh_power;
 					nh->nh_power = 0;
+					spin_unlock_bh(&fib_multipath_lock);
 #endif
 					dead++;
 				}
+#ifdef CONFIG_IP_ROUTE_MULTIPATH
+				if (force > 1 && nh->nh_dev == dev) {
+					dead = fi->fib_nhs;
+					break;
+				}
+#endif
 			} endfor_nexthops(fi)
 			if (dead == fi->fib_nhs) {
 				fi->fib_flags |= RTNH_F_DEAD;
@@ -911,8 +930,10 @@
 			if (nh->nh_dev != dev || __in_dev_get(dev) == NULL)
 				continue;
 			alive++;
+			spin_lock_bh(&fib_multipath_lock);
 			nh->nh_power = 0;
 			nh->nh_flags &= ~RTNH_F_DEAD;
+			spin_unlock_bh(&fib_multipath_lock);
 		} endfor_nexthops(fi)
 
 		if (alive > 0) {
@@ -933,6 +954,7 @@
 	struct fib_info *fi = res->fi;
 	int w;
 
+	spin_lock_bh(&fib_multipath_lock);
 	if (fi->fib_power <= 0) {
 		int power = 0;
 		change_nexthops(fi) {
@@ -942,12 +964,12 @@
 			}
 		} endfor_nexthops(fi);
 		fi->fib_power = power;
-#if 1
 		if (power <= 0) {
-			printk(KERN_CRIT "impossible 777\n");
+			spin_unlock_bh(&fib_multipath_lock);
+			/* Race condition: route has just become dead. */
+			res->nh_sel = 0;
 			return;
 		}
-#endif
 	}
 
 
@@ -963,15 +985,15 @@
 				nh->nh_power--;
 				fi->fib_power--;
 				res->nh_sel = nhsel;
+				spin_unlock_bh(&fib_multipath_lock);
 				return;
 			}
 		}
 	} endfor_nexthops(fi);
 
-#if 1
-	printk(KERN_CRIT "impossible 888\n");
-#endif
-	return;
+	/* Race condition: route has just become dead. */
+	res->nh_sel = 0;
+	spin_unlock_bh(&fib_multipath_lock);
 }
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- linux.orig/net/ipv4/icmp.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/icmp.c	2002-07-20 01:08:33.000000000 +0000
@@ -139,6 +139,8 @@
   { EHOSTUNREACH,	1 }	/*	ICMP_PREC_CUTOFF	*/
 };
 
+extern int sysctl_ip_default_ttl;
+
 /* Control parameters for ECHO replies. */
 int sysctl_icmp_echo_ignore_all;
 int sysctl_icmp_echo_ignore_broadcasts;
@@ -354,6 +356,7 @@
 	icmp_out_count(icmp_param->data.icmph.type);
 
 	sk->protinfo.af_inet.tos = skb->nh.iph->tos;
+	sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl;
 	daddr = ipc.addr = rt->rt_src;
 	ipc.opt = NULL;
 	if (icmp_param->replyopts.optlen) {
@@ -498,6 +501,7 @@
 	icmp_param.offset=skb_in->nh.raw - skb_in->data;
 	icmp_out_count(icmp_param.data.icmph.type);
 	icmp_socket->sk->protinfo.af_inet.tos = tos;
+	icmp_socket->sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl;
 	ipc.addr = iph->saddr;
 	ipc.opt = &icmp_param.replyopts;
 	if (icmp_param.replyopts.srr) {
@@ -876,7 +880,7 @@
  
 int icmp_rcv(struct sk_buff *skb)
 {
-	struct icmphdr *icmph = skb->h.icmph;
+	struct icmphdr *icmph;
 	struct rtable *rt = (struct rtable*)skb->dst;
 
 	ICMP_INC_STATS_BH(IcmpInMsgs);
@@ -895,6 +899,8 @@
 	if (!pskb_pull(skb, sizeof(struct icmphdr)))
 		goto error;
 
+	icmph = skb->h.icmph;
+
 	/*
 	 *	18 is the highest 'known' ICMP type. Anything else is a mystery
 	 *
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/ip_gre.c linux/net/ipv4/ip_gre.c
--- linux.orig/net/ipv4/ip_gre.c	2001-10-30 23:08:12.000000000 +0000
+++ linux/net/ipv4/ip_gre.c	2002-07-20 01:08:39.000000000 +0000
@@ -760,7 +760,10 @@
 	}
 
 	df = tiph->frag_off;
-	mtu = rt->u.dst.pmtu - tunnel->hlen;
+	if (df)
+		mtu = rt->u.dst.pmtu - tunnel->hlen;
+	else
+		mtu = skb->dst ? skb->dst->pmtu : dev->mtu;
 
 	if (skb->protocol == __constant_htons(ETH_P_IP)) {
 		if (skb->dst && mtu < skb->dst->pmtu && mtu >= 68)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/ip_input.c linux/net/ipv4/ip_input.c
--- linux.orig/net/ipv4/ip_input.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/ip_input.c	2002-07-20 01:08:24.000000000 +0000
@@ -224,8 +224,6 @@
 	nf_debug_ip_local_deliver(skb);
 #endif /*CONFIG_NETFILTER_DEBUG*/
 
-	if (!pskb_may_pull(skb, ihl))
-		goto out;
 	__skb_pull(skb, ihl);
 
 #ifdef CONFIG_NETFILTER
@@ -279,7 +277,6 @@
 			sock_put(raw_sk);
 		} else if (!flag) {		/* Free and report errors */
 			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0);	
-out:
 			kfree_skb(skb);
 		}
 	}
@@ -346,7 +343,6 @@
 			goto drop;
 		iph = skb->nh.iph;
 
-		skb->ip_summed = 0;
 		if (ip_options_compile(NULL, skb))
 			goto inhdr_error;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
--- linux.orig/net/ipv4/ip_output.c	2001-10-17 21:16:39.000000000 +0000
+++ linux/net/ipv4/ip_output.c	2002-07-20 01:08:35.000000000 +0000
@@ -5,7 +5,7 @@
  *
  *		The Internet Protocol (IP) output module.
  *
- * Version:	$Id: ip_output.c,v 1.99 2001/10/15 12:34:50 davem Exp $
+ * Version:	$Id: ip_output.c,v 1.99.2.1 2002/03/10 04:26:08 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -134,9 +134,10 @@
 	iph->version  = 4;
 	iph->ihl      = 5;
 	iph->tos      = sk->protinfo.af_inet.tos;
-	iph->frag_off = 0;
 	if (ip_dont_fragment(sk, &rt->u.dst))
-		iph->frag_off |= htons(IP_DF);
+		iph->frag_off = htons(IP_DF);
+	else
+		iph->frag_off = 0;
 	iph->ttl      = sk->protinfo.af_inet.ttl;
 	iph->daddr    = rt->rt_dst;
 	iph->saddr    = rt->rt_src;
@@ -307,9 +308,6 @@
 	if (skb->len > rt->u.dst.pmtu)
 		goto fragment;
 
-	if (ip_dont_fragment(sk, &rt->u.dst))
-		iph->frag_off |= __constant_htons(IP_DF);
-
 	ip_select_ident(iph, &rt->u.dst, sk);
 
 	/* Add an IP checksum. */
@@ -323,8 +321,8 @@
 		/* Reject packet ONLY if TCP might fragment
 		 * it itself, if were careful enough.
 		 */
-		iph->frag_off |= __constant_htons(IP_DF);
-		NETDEBUG(printk(KERN_DEBUG "sending pkt_too_big to self\n"));
+		NETDEBUG(printk(KERN_DEBUG "sending pkt_too_big (len[%u] pmtu[%u]) to self\n",
+				skb->len, rt->u.dst.pmtu));
 
 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
 			  htonl(rt->u.dst.pmtu));
@@ -383,7 +381,10 @@
 	iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0));
 	*((__u16 *)iph)	= htons((4 << 12) | (5 << 8) | (sk->protinfo.af_inet.tos & 0xff));
 	iph->tot_len = htons(skb->len);
-	iph->frag_off = 0;
+	if (ip_dont_fragment(sk, &rt->u.dst))
+		iph->frag_off = __constant_htons(IP_DF);
+	else
+		iph->frag_off = 0;
 	iph->ttl      = sk->protinfo.af_inet.ttl;
 	iph->protocol = sk->protocol;
 	iph->saddr    = rt->rt_src;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/ipconfig.c linux/net/ipv4/ipconfig.c
--- linux.orig/net/ipv4/ipconfig.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/ipconfig.c	2002-07-20 01:08:23.000000000 +0000
@@ -1105,13 +1105,47 @@
 #endif /* CONFIG_PROC_FS */
 
 /*
+ *  Extract IP address from the parameter string if needed. Note that we
+ *  need to have root_server_addr set _before_ IPConfig gets called as it
+ *  can override it.
+ */
+u32 __init root_nfs_parse_addr(char *name)
+{
+	u32 addr;
+	int octets = 0;
+	char *cp, *cq;
+
+	cp = cq = name;
+	while (octets < 4) {
+		while (*cp >= '0' && *cp <= '9')
+			cp++;
+		if (cp == cq || cp - cq > 3)
+			break;
+		if (*cp == '.' || octets == 3)
+			octets++;
+		if (octets < 4)
+			cp++;
+		cq = cp;
+	}
+	if (octets == 4 && (*cp == ':' || *cp == '\0')) {
+		if (*cp == ':')
+			*cp++ = '\0';
+		addr = in_aton(name);
+		strcpy(name, cp);
+	} else
+		addr = INADDR_NONE;
+
+	return addr;
+}
+
+/*
  *	IP Autoconfig dispatcher.
  */
 
 static int __init ip_auto_config(void)
 {
-	int retries = CONF_OPEN_RETRIES;
 	unsigned long jiff;
+	u32 addr;
 
 #ifdef CONFIG_PROC_FS
 	proc_net_create("pnp", 0, pnp_get_info);
@@ -1122,7 +1156,9 @@
 
 	DBG(("IP-Config: Entered.\n"));
 
+#ifdef IPCONFIG_DYNAMIC
  try_try_again:
+#endif
 	/* Give hardware a chance to settle */
 	jiff = jiffies + CONF_PRE_OPEN;
 	while (time_before(jiffies, jiff))
@@ -1152,6 +1188,8 @@
 	    ic_first_dev->next) {
 #ifdef IPCONFIG_DYNAMIC
 
+		int retries = CONF_OPEN_RETRIES;
+
 		if (ic_dynamic() < 0) {
 			ic_close_devs();
 
@@ -1197,6 +1235,10 @@
 		ic_dev = ic_first_dev->dev;
 	}
 
+	addr = root_nfs_parse_addr(root_server_path);
+	if (root_server_addr == INADDR_NONE)
+		root_server_addr = addr;
+
 	/*
 	 * Use defaults whereever applicable.
 	 */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/ipip.c linux/net/ipv4/ipip.c
--- linux.orig/net/ipv4/ipip.c	2001-10-17 21:16:39.000000000 +0000
+++ linux/net/ipv4/ipip.c	2002-07-20 01:08:37.000000000 +0000
@@ -572,7 +572,11 @@
 		goto tx_error;
 	}
 
-	mtu = rt->u.dst.pmtu - sizeof(struct iphdr);
+	if (tiph->frag_off)
+		mtu = rt->u.dst.pmtu - sizeof(struct iphdr);
+	else
+		mtu = skb->dst ? skb->dst->pmtu : dev->mtu;
+
 	if (mtu < 68) {
 		tunnel->stat.collisions++;
 		ip_rt_put(rt);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/Config.in linux/net/ipv4/netfilter/Config.in
--- linux.orig/net/ipv4/netfilter/Config.in	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/Config.in	2002-07-20 01:08:36.000000000 +0000
@@ -47,6 +47,7 @@
       define_bool CONFIG_IP_NF_NAT_NEEDED y
       dep_tristate '    MASQUERADE target support' CONFIG_IP_NF_TARGET_MASQUERADE $CONFIG_IP_NF_NAT
       dep_tristate '    REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT
+      bool '    NAT of local connections (READ HELP)' CONFIG_IP_NF_NAT_LOCAL
       if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
         dep_tristate '    Basic SNMP-ALG support (EXPERIMENTAL)' CONFIG_IP_NF_NAT_SNMP_BASIC $CONFIG_IP_NF_NAT
       fi
@@ -75,12 +76,15 @@
     dep_tristate '    MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE
   fi
   dep_tristate '  LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES
-  if [ "$CONFIG_NETLINK" != "n" ]; then
-     dep_tristate '  ULOG target support' CONFIG_IP_NF_TARGET_ULOG $CONFIG_NETLINK $CONFIG_IP_NF_IPTABLES
-  fi
+  dep_tristate '  ULOG target support' CONFIG_IP_NF_TARGET_ULOG $CONFIG_IP_NF_IPTABLES
   dep_tristate '  TCPMSS target support' CONFIG_IP_NF_TARGET_TCPMSS $CONFIG_IP_NF_IPTABLES
 fi
 
+tristate 'ARP tables support' CONFIG_IP_NF_ARPTABLES
+if [ "$CONFIG_IP_NF_ARPTABLES" != "n" ]; then
+  dep_tristate '  ARP packet filtering' CONFIG_IP_NF_ARPFILTER $CONFIG_IP_NF_ARPTABLES 
+fi
+
 # Backwards compatibility modules: only if you don't build in the others.
 if [ "$CONFIG_IP_NF_CONNTRACK" != "y" ]; then
   if [ "$CONFIG_IP_NF_IPTABLES" != "y" ]; then
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile
--- linux.orig/net/ipv4/netfilter/Makefile	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/Makefile	2002-07-20 01:08:28.000000000 +0000
@@ -9,7 +9,7 @@
 
 O_TARGET := netfilter.o
 
-export-objs = ip_conntrack_standalone.o ip_conntrack_ftp.o ip_fw_compat.o ip_nat_standalone.o ip_tables.o
+export-objs = ip_conntrack_standalone.o ip_conntrack_ftp.o ip_fw_compat.o ip_nat_standalone.o ip_tables.o arp_tables.o
 
 # Multipart objects.
 list-multi		:= ip_conntrack.o iptable_nat.o ipfwadm.o ipchains.o
@@ -31,15 +31,13 @@
 # connection tracking
 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
 
-# IRC support
-obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
-obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
-
 # connection tracking helpers
 obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
+obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
 
 # NAT helpers 
 obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
+obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
 
 # generic IP tables 
 obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
@@ -77,6 +75,12 @@
 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
 
+# generic ARP tables
+obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
+
+# just filtering instance of ARP tables for now
+obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
+
 # backwards compatibility 
 obj-$(CONFIG_IP_NF_COMPAT_IPCHAINS) += ipchains.o
 obj-$(CONFIG_IP_NF_COMPAT_IPFWADM) += ipfwadm.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/arp_tables.c linux/net/ipv4/netfilter/arp_tables.c
--- linux.orig/net/ipv4/netfilter/arp_tables.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/ipv4/netfilter/arp_tables.c	2002-07-20 01:08:35.000000000 +0000
@@ -0,0 +1,1313 @@
+/*
+ * Packet matching code for ARP packets.
+ *
+ * Based heavily, if not almost entirely, upon ip_tables.c framework.
+ *
+ * Some ARP specific bits are:
+ *
+ * Copyright (C) 2002 David S. Miller (davem@redhat.com)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+
+#include <linux/netfilter_arp/arp_tables.h>
+
+/*#define DEBUG_ARP_TABLES*/
+/*#define DEBUG_ARP_TABLES_USER*/
+
+#ifdef DEBUG_ARP_TABLES
+#define dprintf(format, args...)  printk(format , ## args)
+#else
+#define dprintf(format, args...)
+#endif
+
+#ifdef DEBUG_ARP_TABLES_USER
+#define duprintf(format, args...) printk(format , ## args)
+#else
+#define duprintf(format, args...)
+#endif
+
+#ifdef CONFIG_NETFILTER_DEBUG
+#define ARP_NF_ASSERT(x)					\
+do {								\
+	if (!(x))						\
+		printk("ARP_NF_ASSERT: %s:%s:%u\n",		\
+		       __FUNCTION__, __FILE__, __LINE__);	\
+} while(0)
+#else
+#define ARP_NF_ASSERT(x)
+#endif
+#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
+
+static DECLARE_MUTEX(arpt_mutex);
+
+#define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
+#define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
+#include <linux/netfilter_ipv4/lockhelp.h>
+#include <linux/netfilter_ipv4/listhelp.h>
+
+struct arpt_table_info {
+	unsigned int size;
+	unsigned int number;
+	unsigned int initial_entries;
+	unsigned int hook_entry[NF_ARP_NUMHOOKS];
+	unsigned int underflow[NF_ARP_NUMHOOKS];
+	char entries[0] __attribute__((aligned(SMP_CACHE_BYTES)));
+};
+
+static LIST_HEAD(arpt_target);
+static LIST_HEAD(arpt_tables);
+#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
+
+#ifdef CONFIG_SMP
+#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
+#else
+#define TABLE_OFFSET(t,p) 0
+#endif
+
+static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
+				      char *hdr_addr, int len)
+{
+	int i, ret;
+
+	if (len > ARPT_DEV_ADDR_LEN_MAX)
+		len = ARPT_DEV_ADDR_LEN_MAX;
+
+	ret = 0;
+	for (i = 0; i < len; i++)
+		ret |= (hdr_addr[i] ^ ap->addr[i]) & ap->mask[i];
+
+	return (ret != 0);
+}
+
+/* Returns whether packet matches rule or not. */
+static inline int arp_packet_match(const struct arphdr *arphdr,
+				   struct net_device *dev,
+				   const char *indev,
+				   const char *outdev,
+				   const struct arpt_arp *arpinfo)
+{
+	char *arpptr = (char *)(arphdr + 1);
+	char *src_devaddr, *tgt_devaddr;
+	u32 *src_ipaddr, *tgt_ipaddr;
+	int i, ret;
+
+#define FWINV(bool,invflg) ((bool) ^ !!(arpinfo->invflags & invflg))
+
+	if (FWINV((arphdr->ar_op & arpinfo->arpop_mask) != arpinfo->arpop,
+		  ARPT_INV_ARPOP)) {
+		dprintf("ARP operation field mismatch.\n");
+		dprintf("ar_op: %04x info->arpop: %04x info->arpop_mask: %04x\n",
+			arphdr->ar_op, arpinfo->arpop, arpinfo->arpop_mask);
+		return 0;
+	}
+
+	if (FWINV((arphdr->ar_hrd & arpinfo->arhrd_mask) != arpinfo->arhrd,
+		  ARPT_INV_ARPHRD)) {
+		dprintf("ARP hardware address format mismatch.\n");
+		dprintf("ar_hrd: %04x info->arhrd: %04x info->arhrd_mask: %04x\n",
+			arphdr->ar_hrd, arpinfo->arhrd, arpinfo->arhrd_mask);
+		return 0;
+	}
+
+	if (FWINV((arphdr->ar_pro & arpinfo->arpro_mask) != arpinfo->arpro,
+		  ARPT_INV_ARPPRO)) {
+		dprintf("ARP protocol address format mismatch.\n");
+		dprintf("ar_pro: %04x info->arpro: %04x info->arpro_mask: %04x\n",
+			arphdr->ar_pro, arpinfo->arpro, arpinfo->arpro_mask);
+		return 0;
+	}
+
+	if (FWINV((arphdr->ar_hln & arpinfo->arhln_mask) != arpinfo->arhln,
+		  ARPT_INV_ARPHLN)) {
+		dprintf("ARP hardware address length mismatch.\n");
+		dprintf("ar_hln: %02x info->arhln: %02x info->arhln_mask: %02x\n",
+			arphdr->ar_hln, arpinfo->arhln, arpinfo->arhln_mask);
+	}
+
+	src_devaddr = arpptr;
+	arpptr += dev->addr_len;
+	src_ipaddr = (u32 *) arpptr;
+	arpptr += sizeof(u32);
+	tgt_devaddr = arpptr;
+	arpptr += dev->addr_len;
+	tgt_ipaddr = (u32 *) arpptr;
+
+	if (FWINV(arp_devaddr_compare(&arpinfo->src_devaddr, src_devaddr, dev->addr_len),
+		  ARPT_INV_SRCDEVADDR) ||
+	    FWINV(arp_devaddr_compare(&arpinfo->tgt_devaddr, tgt_devaddr, dev->addr_len),
+		  ARPT_INV_TGTDEVADDR)) {
+		dprintf("Source or target device address mismatch.\n");
+
+		return 0;
+	}
+
+	if (FWINV(((*src_ipaddr) & arpinfo->smsk.s_addr) != arpinfo->src.s_addr,
+		  ARPT_INV_SRCIP) ||
+	    FWINV((((*tgt_ipaddr) & arpinfo->tmsk.s_addr) != arpinfo->tgt.s_addr),
+		  ARPT_INV_TGTIP)) {
+		dprintf("Source or target IP address mismatch.\n");
+
+		dprintf("SRC: %u.%u.%u.%u. Mask: %u.%u.%u.%u. Target: %u.%u.%u.%u.%s\n",
+			NIPQUAD(*src_ipaddr),
+			NIPQUAD(arpinfo->smsk.s_addr),
+			NIPQUAD(arpinfo->src.s_addr),
+			arpinfo->invflags & ARPT_INV_SRCIP ? " (INV)" : "");
+		dprintf("TGT: %u.%u.%u.%u Mask: %u.%u.%u.%u Target: %u.%u.%u.%u.%s\n",
+			NIPQUAD(*tgt_ipaddr),
+			NIPQUAD(arpinfo->tmsk.s_addr),
+			NIPQUAD(arpinfo->tgt.s_addr),
+			arpinfo->invflags & ARPT_INV_TGTIP ? " (INV)" : "");
+		return 0;
+	}
+
+	/* Look for ifname matches; this should unroll nicely. */
+	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+		ret |= (((const unsigned long *)indev)[i]
+			^ ((const unsigned long *)arpinfo->iniface)[i])
+			& ((const unsigned long *)arpinfo->iniface_mask)[i];
+	}
+
+	if (FWINV(ret != 0, ARPT_INV_VIA_IN)) {
+		dprintf("VIA in mismatch (%s vs %s).%s\n",
+			indev, arpinfo->iniface,
+			arpinfo->invflags&ARPT_INV_VIA_IN ?" (INV)":"");
+		return 0;
+	}
+
+	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+		ret |= (((const unsigned long *)outdev)[i]
+			^ ((const unsigned long *)arpinfo->outiface)[i])
+			& ((const unsigned long *)arpinfo->outiface_mask)[i];
+	}
+
+	if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) {
+		dprintf("VIA out mismatch (%s vs %s).%s\n",
+			outdev, arpinfo->outiface,
+			arpinfo->invflags&ARPT_INV_VIA_OUT ?" (INV)":"");
+		return 0;
+	}
+
+	return 1;
+}
+
+static inline int arp_checkentry(const struct arpt_arp *arp)
+{
+	if (arp->flags & ~ARPT_F_MASK) {
+		duprintf("Unknown flag bits set: %08X\n",
+			 arp->flags & ~ARPT_F_MASK);
+		return 0;
+	}
+	if (arp->invflags & ~ARPT_INV_MASK) {
+		duprintf("Unknown invflag bits set: %08X\n",
+			 arp->invflags & ~ARPT_INV_MASK);
+		return 0;
+	}
+
+	return 1;
+}
+
+static unsigned int arpt_error(struct sk_buff **pskb,
+			       unsigned int hooknum,
+			       const struct net_device *in,
+			       const struct net_device *out,
+			       const void *targinfo,
+			       void *userinfo)
+{
+	if (net_ratelimit())
+		printk("arp_tables: error: '%s'\n", (char *)targinfo);
+
+	return NF_DROP;
+}
+
+static inline struct arpt_entry *get_entry(void *base, unsigned int offset)
+{
+	return (struct arpt_entry *)(base + offset);
+}
+
+unsigned int arpt_do_table(struct sk_buff **pskb,
+			   unsigned int hook,
+			   const struct net_device *in,
+			   const struct net_device *out,
+			   struct arpt_table *table,
+			   void *userdata)
+{
+	static const char nulldevname[IFNAMSIZ] = { 0 };
+	unsigned int verdict = NF_DROP;
+	struct arphdr *arp = (*pskb)->nh.arph;
+	int hotdrop = 0;
+	struct arpt_entry *e, *back;
+	const char *indev, *outdev;
+	void *table_base;
+
+	indev = in ? in->name : nulldevname;
+	outdev = out ? out->name : nulldevname;
+
+	read_lock_bh(&table->lock);
+	table_base = (void *)table->private->entries
+		+ TABLE_OFFSET(table->private,
+			       cpu_number_map(smp_processor_id()));
+	e = get_entry(table_base, table->private->hook_entry[hook]);
+	back = get_entry(table_base, table->private->underflow[hook]);
+
+	do {
+		if (arp_packet_match(arp, (*pskb)->dev, indev, outdev, &e->arp)) {
+			struct arpt_entry_target *t;
+			int hdr_len;
+
+			hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) +
+				(2 * (*pskb)->dev->addr_len);
+			ADD_COUNTER(e->counters, hdr_len, 1);
+
+			t = arpt_get_target(e);
+
+			/* Standard target? */
+			if (!t->u.kernel.target->target) {
+				int v;
+
+				v = ((struct arpt_standard_target *)t)->verdict;
+				if (v < 0) {
+					/* Pop from stack? */
+					if (v != ARPT_RETURN) {
+						verdict = (unsigned)(-v) - 1;
+						break;
+					}
+					e = back;
+					back = get_entry(table_base,
+							 back->comefrom);
+					continue;
+				}
+				if (table_base + v
+				    != (void *)e + e->next_offset) {
+					/* Save old back ptr in next entry */
+					struct arpt_entry *next
+						= (void *)e + e->next_offset;
+					next->comefrom =
+						(void *)back - table_base;
+
+					/* set back pointer to next entry */
+					back = next;
+				}
+
+				e = get_entry(table_base, v);
+			} else {
+				/* Targets which reenter must return
+				 * abs. verdicts
+				 */
+				verdict = t->u.kernel.target->target(pskb,
+								     hook,
+								     in, out,
+								     t->data,
+								     userdata);
+
+				/* Target might have changed stuff. */
+				arp = (*pskb)->nh.arph;
+
+				if (verdict == ARPT_CONTINUE)
+					e = (void *)e + e->next_offset;
+				else
+					/* Verdict */
+					break;
+			}
+		} else {
+			e = (void *)e + e->next_offset;
+		}
+	} while (!hotdrop);
+	read_unlock_bh(&table->lock);
+
+	if (hotdrop)
+		return NF_DROP;
+	else
+		return verdict;
+}
+
+static inline void *find_inlist_lock_noload(struct list_head *head,
+					    const char *name,
+					    int *error,
+					    struct semaphore *mutex)
+{
+	void *ret;
+
+	*error = down_interruptible(mutex);
+	if (*error != 0)
+		return NULL;
+
+	ret = list_named_find(head, name);
+	if (!ret) {
+		*error = -ENOENT;
+		up(mutex);
+	}
+	return ret;
+}
+
+#ifndef CONFIG_KMOD
+#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
+#else
+static void *
+find_inlist_lock(struct list_head *head,
+		 const char *name,
+		 const char *prefix,
+		 int *error,
+		 struct semaphore *mutex)
+{
+	void *ret;
+
+	ret = find_inlist_lock_noload(head, name, error, mutex);
+	if (!ret) {
+		char modulename[ARPT_FUNCTION_MAXNAMELEN + strlen(prefix) + 1];
+		strcpy(modulename, prefix);
+		strcat(modulename, name);
+		duprintf("find_inlist: loading `%s'.\n", modulename);
+		request_module(modulename);
+		ret = find_inlist_lock_noload(head, name, error, mutex);
+	}
+
+	return ret;
+}
+#endif
+
+static inline struct arpt_table *find_table_lock(const char *name, int *error, struct semaphore *mutex)
+{
+	return find_inlist_lock(&arpt_tables, name, "arptable_", error, mutex);
+}
+
+static inline struct arpt_target *find_target_lock(const char *name, int *error, struct semaphore *mutex)
+{
+	return find_inlist_lock(&arpt_target, name, "arpt_", error, mutex);
+}
+
+/* All zeroes == unconditional rule. */
+static inline int unconditional(const struct arpt_arp *arp)
+{
+	unsigned int i;
+
+	for (i = 0; i < sizeof(*arp)/sizeof(__u32); i++)
+		if (((__u32 *)arp)[i])
+			return 0;
+
+	return 1;
+}
+
+/* Figures out from what hook each rule can be called: returns 0 if
+ * there are loops.  Puts hook bitmask in comefrom.
+ */
+static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int valid_hooks)
+{
+	unsigned int hook;
+
+	/* No recursion; use packet counter to save back ptrs (reset
+	 * to 0 as we leave), and comefrom to save source hook bitmask.
+	 */
+	for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) {
+		unsigned int pos = newinfo->hook_entry[hook];
+		struct arpt_entry *e
+			= (struct arpt_entry *)(newinfo->entries + pos);
+
+		if (!(valid_hooks & (1 << hook)))
+			continue;
+
+		/* Set initial back pointer. */
+		e->counters.pcnt = pos;
+
+		for (;;) {
+			struct arpt_standard_target *t
+				= (void *)arpt_get_target(e);
+
+			if (e->comefrom & (1 << NF_ARP_NUMHOOKS)) {
+				printk("arptables: loop hook %u pos %u %08X.\n",
+				       hook, pos, e->comefrom);
+				return 0;
+			}
+			e->comefrom
+				|= ((1 << hook) | (1 << NF_ARP_NUMHOOKS));
+
+			/* Unconditional return/END. */
+			if (e->target_offset == sizeof(struct arpt_entry)
+			    && (strcmp(t->target.u.user.name,
+				       ARPT_STANDARD_TARGET) == 0)
+			    && t->verdict < 0
+			    && unconditional(&e->arp)) {
+				unsigned int oldpos, size;
+
+				/* Return: backtrack through the last
+				 * big jump.
+				 */
+				do {
+					e->comefrom ^= (1<<NF_ARP_NUMHOOKS);
+					oldpos = pos;
+					pos = e->counters.pcnt;
+					e->counters.pcnt = 0;
+
+					/* We're at the start. */
+					if (pos == oldpos)
+						goto next;
+
+					e = (struct arpt_entry *)
+						(newinfo->entries + pos);
+				} while (oldpos == pos + e->next_offset);
+
+				/* Move along one */
+				size = e->next_offset;
+				e = (struct arpt_entry *)
+					(newinfo->entries + pos + size);
+				e->counters.pcnt = pos;
+				pos += size;
+			} else {
+				int newpos = t->verdict;
+
+				if (strcmp(t->target.u.user.name,
+					   ARPT_STANDARD_TARGET) == 0
+				    && newpos >= 0) {
+					/* This a jump; chase it. */
+					duprintf("Jump rule %u -> %u\n",
+						 pos, newpos);
+				} else {
+					/* ... this is a fallthru */
+					newpos = pos + e->next_offset;
+				}
+				e = (struct arpt_entry *)
+					(newinfo->entries + newpos);
+				e->counters.pcnt = pos;
+				pos = newpos;
+			}
+		}
+		next:
+		duprintf("Finished chain %u\n", hook);
+	}
+	return 1;
+}
+
+static inline int standard_check(const struct arpt_entry_target *t,
+				 unsigned int max_offset)
+{
+	struct arpt_standard_target *targ = (void *)t;
+
+	/* Check standard info. */
+	if (t->u.target_size
+	    != ARPT_ALIGN(sizeof(struct arpt_standard_target))) {
+		duprintf("arpt_standard_check: target size %u != %Zu\n",
+			 t->u.target_size,
+			 ARPT_ALIGN(sizeof(struct arpt_standard_target)));
+		return 0;
+	}
+
+	if (targ->verdict >= 0
+	    && targ->verdict > max_offset - sizeof(struct arpt_entry)) {
+		duprintf("arpt_standard_check: bad verdict (%i)\n",
+			 targ->verdict);
+		return 0;
+	}
+
+	if (targ->verdict < -NF_MAX_VERDICT - 1) {
+		duprintf("arpt_standard_check: bad negative verdict (%i)\n",
+			 targ->verdict);
+		return 0;
+	}
+	return 1;
+}
+
+static struct arpt_target arpt_standard_target;
+
+static inline int check_entry(struct arpt_entry *e, const char *name, unsigned int size,
+			      unsigned int *i)
+{
+	struct arpt_entry_target *t;
+	struct arpt_target *target;
+	int ret;
+
+	if (!arp_checkentry(&e->arp)) {
+		duprintf("arp_tables: arp check failed %p %s.\n", e, name);
+		return -EINVAL;
+	}
+
+	t = arpt_get_target(e);
+	target = find_target_lock(t->u.user.name, &ret, &arpt_mutex);
+	if (!target) {
+		duprintf("check_entry: `%s' not found\n", t->u.user.name);
+		goto out;
+	}
+	if (target->me)
+		__MOD_INC_USE_COUNT(target->me);
+	t->u.kernel.target = target;
+	up(&arpt_mutex);
+
+	if (t->u.kernel.target == &arpt_standard_target) {
+		if (!standard_check(t, size)) {
+			ret = -EINVAL;
+			goto out;
+		}
+	} else if (t->u.kernel.target->checkentry
+		   && !t->u.kernel.target->checkentry(name, e, t->data,
+						      t->u.target_size
+						      - sizeof(*t),
+						      e->comefrom)) {
+		if (t->u.kernel.target->me)
+			__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
+		duprintf("arp_tables: check failed for `%s'.\n",
+			 t->u.kernel.target->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	(*i)++;
+	return 0;
+
+out:
+	return ret;
+}
+
+static inline int check_entry_size_and_hooks(struct arpt_entry *e,
+					     struct arpt_table_info *newinfo,
+					     unsigned char *base,
+					     unsigned char *limit,
+					     const unsigned int *hook_entries,
+					     const unsigned int *underflows,
+					     unsigned int *i)
+{
+	unsigned int h;
+
+	if ((unsigned long)e % __alignof__(struct arpt_entry) != 0
+	    || (unsigned char *)e + sizeof(struct arpt_entry) >= limit) {
+		duprintf("Bad offset %p\n", e);
+		return -EINVAL;
+	}
+
+	if (e->next_offset
+	    < sizeof(struct arpt_entry) + sizeof(struct arpt_entry_target)) {
+		duprintf("checking: element %p size %u\n",
+			 e, e->next_offset);
+		return -EINVAL;
+	}
+
+	/* Check hooks & underflows */
+	for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
+		if ((unsigned char *)e - base == hook_entries[h])
+			newinfo->hook_entry[h] = hook_entries[h];
+		if ((unsigned char *)e - base == underflows[h])
+			newinfo->underflow[h] = underflows[h];
+	}
+
+	/* FIXME: underflows must be unconditional, standard verdicts
+           < 0 (not ARPT_RETURN). --RR */
+
+	/* Clear counters and comefrom */
+	e->counters = ((struct arpt_counters) { 0, 0 });
+	e->comefrom = 0;
+
+	(*i)++;
+	return 0;
+}
+
+static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
+{
+	struct arpt_entry_target *t;
+
+	if (i && (*i)-- == 0)
+		return 1;
+
+	t = arpt_get_target(e);
+	if (t->u.kernel.target->destroy)
+		t->u.kernel.target->destroy(t->data,
+					    t->u.target_size - sizeof(*t));
+	if (t->u.kernel.target->me)
+		__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
+
+	return 0;
+}
+
+/* Checks and translates the user-supplied table segment (held in
+ * newinfo).
+ */
+static int translate_table(const char *name,
+			   unsigned int valid_hooks,
+			   struct arpt_table_info *newinfo,
+			   unsigned int size,
+			   unsigned int number,
+			   const unsigned int *hook_entries,
+			   const unsigned int *underflows)
+{
+	unsigned int i;
+	int ret;
+
+	newinfo->size = size;
+	newinfo->number = number;
+
+	/* Init all hooks to impossible value. */
+	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+		newinfo->hook_entry[i] = 0xFFFFFFFF;
+		newinfo->underflow[i] = 0xFFFFFFFF;
+	}
+
+	duprintf("translate_table: size %u\n", newinfo->size);
+	i = 0;
+
+	/* Walk through entries, checking offsets. */
+	ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+				 check_entry_size_and_hooks,
+				 newinfo,
+				 newinfo->entries,
+				 newinfo->entries + size,
+				 hook_entries, underflows, &i);
+	duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
+	if (ret != 0)
+		return ret;
+
+	if (i != number) {
+		duprintf("translate_table: %u not %u entries\n",
+			 i, number);
+		return -EINVAL;
+	}
+
+	/* Check hooks all assigned */
+	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+		/* Only hooks which are valid */
+		if (!(valid_hooks & (1 << i)))
+			continue;
+		if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
+			duprintf("Invalid hook entry %u %u\n",
+				 i, hook_entries[i]);
+			return -EINVAL;
+		}
+		if (newinfo->underflow[i] == 0xFFFFFFFF) {
+			duprintf("Invalid underflow %u %u\n",
+				 i, underflows[i]);
+			return -EINVAL;
+		}
+	}
+
+	if (!mark_source_chains(newinfo, valid_hooks)) {
+		duprintf("Looping hook\n");
+		return -ELOOP;
+	}
+
+	/* Finally, each sanity check must pass */
+	i = 0;
+	ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+				 check_entry, name, size, &i);
+
+	if (ret != 0) {
+		ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+				   cleanup_entry, &i);
+		return ret;
+	}
+
+	/* And one copy for every other CPU */
+	for (i = 1; i < smp_num_cpus; i++) {
+		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
+		       newinfo->entries,
+		       SMP_ALIGN(newinfo->size));
+	}
+
+	return ret;
+}
+
+static struct arpt_table_info *replace_table(struct arpt_table *table,
+					     unsigned int num_counters,
+					     struct arpt_table_info *newinfo,
+					     int *error)
+{
+	struct arpt_table_info *oldinfo;
+
+	/* Do the substitution. */
+	write_lock_bh(&table->lock);
+	/* Check inside lock: is the old number correct? */
+	if (num_counters != table->private->number) {
+		duprintf("num_counters != table->private->number (%u/%u)\n",
+			 num_counters, table->private->number);
+		write_unlock_bh(&table->lock);
+		*error = -EAGAIN;
+		return NULL;
+	}
+	oldinfo = table->private;
+	table->private = newinfo;
+	newinfo->initial_entries = oldinfo->initial_entries;
+	write_unlock_bh(&table->lock);
+
+	return oldinfo;
+}
+
+/* Gets counters. */
+static inline int add_entry_to_counter(const struct arpt_entry *e,
+				       struct arpt_counters total[],
+				       unsigned int *i)
+{
+	ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+	(*i)++;
+	return 0;
+}
+
+static void get_counters(const struct arpt_table_info *t,
+			 struct arpt_counters counters[])
+{
+	unsigned int cpu;
+	unsigned int i;
+
+	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+		i = 0;
+		ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+				   t->size,
+				   add_entry_to_counter,
+				   counters,
+				   &i);
+	}
+}
+
+static int copy_entries_to_user(unsigned int total_size,
+				struct arpt_table *table,
+				void *userptr)
+{
+	unsigned int off, num, countersize;
+	struct arpt_entry *e;
+	struct arpt_counters *counters;
+	int ret = 0;
+
+	/* We need atomic snapshot of counters: rest doesn't change
+	 * (other than comefrom, which userspace doesn't care
+	 * about).
+	 */
+	countersize = sizeof(struct arpt_counters) * table->private->number;
+	counters = vmalloc(countersize);
+
+	if (counters == NULL)
+		return -ENOMEM;
+
+	/* First, sum counters... */
+	memset(counters, 0, countersize);
+	write_lock_bh(&table->lock);
+	get_counters(table->private, counters);
+	write_unlock_bh(&table->lock);
+
+	/* ... then copy entire thing from CPU 0... */
+	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+		ret = -EFAULT;
+		goto free_counters;
+	}
+
+	/* FIXME: use iterator macros --RR */
+	/* ... then go back and fix counters and names */
+	for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
+		struct arpt_entry_target *t;
+
+		e = (struct arpt_entry *)(table->private->entries + off);
+		if (copy_to_user(userptr + off
+				 + offsetof(struct arpt_entry, counters),
+				 &counters[num],
+				 sizeof(counters[num])) != 0) {
+			ret = -EFAULT;
+			goto free_counters;
+		}
+
+		t = arpt_get_target(e);
+		if (copy_to_user(userptr + off + e->target_offset
+				 + offsetof(struct arpt_entry_target,
+					    u.user.name),
+				 t->u.kernel.target->name,
+				 strlen(t->u.kernel.target->name)+1) != 0) {
+			ret = -EFAULT;
+			goto free_counters;
+		}
+	}
+
+ free_counters:
+	vfree(counters);
+	return ret;
+}
+
+static int get_entries(const struct arpt_get_entries *entries,
+		       struct arpt_get_entries *uptr)
+{
+	int ret;
+	struct arpt_table *t;
+
+	t = find_table_lock(entries->name, &ret, &arpt_mutex);
+	if (t) {
+		duprintf("t->private->number = %u\n",
+			 t->private->number);
+		if (entries->size == t->private->size)
+			ret = copy_entries_to_user(t->private->size,
+						   t, uptr->entrytable);
+		else {
+			duprintf("get_entries: I've got %u not %u!\n",
+				 t->private->size,
+				 entries->size);
+			ret = -EINVAL;
+		}
+		up(&arpt_mutex);
+	} else
+		duprintf("get_entries: Can't find %s!\n",
+			 entries->name);
+
+	return ret;
+}
+
+static int do_replace(void *user, unsigned int len)
+{
+	int ret;
+	struct arpt_replace tmp;
+	struct arpt_table *t;
+	struct arpt_table_info *newinfo, *oldinfo;
+	struct arpt_counters *counters;
+
+	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+		return -EFAULT;
+
+	/* Hack: Causes ipchains to give correct error msg --RR */
+	if (len != sizeof(tmp) + tmp.size)
+		return -ENOPROTOOPT;
+
+	/* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
+	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
+		return -ENOMEM;
+
+	newinfo = vmalloc(sizeof(struct arpt_table_info)
+			  + SMP_ALIGN(tmp.size) * smp_num_cpus);
+	if (!newinfo)
+		return -ENOMEM;
+
+	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+			   tmp.size) != 0) {
+		ret = -EFAULT;
+		goto free_newinfo;
+	}
+
+	counters = vmalloc(tmp.num_counters * sizeof(struct arpt_counters));
+	if (!counters) {
+		ret = -ENOMEM;
+		goto free_newinfo;
+	}
+	memset(counters, 0, tmp.num_counters * sizeof(struct arpt_counters));
+
+	ret = translate_table(tmp.name, tmp.valid_hooks,
+			      newinfo, tmp.size, tmp.num_entries,
+			      tmp.hook_entry, tmp.underflow);
+	if (ret != 0)
+		goto free_newinfo_counters;
+
+	duprintf("arp_tables: Translated table\n");
+
+	t = find_table_lock(tmp.name, &ret, &arpt_mutex);
+	if (!t)
+		goto free_newinfo_counters_untrans;
+
+	/* You lied! */
+	if (tmp.valid_hooks != t->valid_hooks) {
+		duprintf("Valid hook crap: %08X vs %08X\n",
+			 tmp.valid_hooks, t->valid_hooks);
+		ret = -EINVAL;
+		goto free_newinfo_counters_untrans_unlock;
+	}
+
+	oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
+	if (!oldinfo)
+		goto free_newinfo_counters_untrans_unlock;
+
+	/* Update module usage count based on number of rules */
+	duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
+		oldinfo->number, oldinfo->initial_entries, newinfo->number);
+	if (t->me && (oldinfo->number <= oldinfo->initial_entries) &&
+ 	    (newinfo->number > oldinfo->initial_entries))
+		__MOD_INC_USE_COUNT(t->me);
+	else if (t->me && (oldinfo->number > oldinfo->initial_entries) &&
+	 	 (newinfo->number <= oldinfo->initial_entries))
+		__MOD_DEC_USE_COUNT(t->me);
+
+	/* Get the old counters. */
+	get_counters(oldinfo, counters);
+	/* Decrease module usage counts and free resource */
+	ARPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
+	vfree(oldinfo);
+	/* Silent error: too late now. */
+	copy_to_user(tmp.counters, counters,
+		     sizeof(struct arpt_counters) * tmp.num_counters);
+	vfree(counters);
+	up(&arpt_mutex);
+	return 0;
+
+ free_newinfo_counters_untrans_unlock:
+	up(&arpt_mutex);
+ free_newinfo_counters_untrans:
+	ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL);
+ free_newinfo_counters:
+	vfree(counters);
+ free_newinfo:
+	vfree(newinfo);
+	return ret;
+}
+
+/* We're lazy, and add to the first CPU; overflow works its fey magic
+ * and everything is OK.
+ */
+static inline int add_counter_to_entry(struct arpt_entry *e,
+				       const struct arpt_counters addme[],
+				       unsigned int *i)
+{
+
+	ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
+
+	(*i)++;
+	return 0;
+}
+
+static int do_add_counters(void *user, unsigned int len)
+{
+	unsigned int i;
+	struct arpt_counters_info tmp, *paddc;
+	struct arpt_table *t;
+	int ret;
+
+	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+		return -EFAULT;
+
+	if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct arpt_counters))
+		return -EINVAL;
+
+	paddc = vmalloc(len);
+	if (!paddc)
+		return -ENOMEM;
+
+	if (copy_from_user(paddc, user, len) != 0) {
+		ret = -EFAULT;
+		goto free;
+	}
+
+	t = find_table_lock(tmp.name, &ret, &arpt_mutex);
+	if (!t)
+		goto free;
+
+	write_lock_bh(&t->lock);
+	if (t->private->number != paddc->num_counters) {
+		ret = -EINVAL;
+		goto unlock_up_free;
+	}
+
+	i = 0;
+	ARPT_ENTRY_ITERATE(t->private->entries,
+			   t->private->size,
+			   add_counter_to_entry,
+			   paddc->counters,
+			   &i);
+ unlock_up_free:
+	write_unlock_bh(&t->lock);
+	up(&arpt_mutex);
+ free:
+	vfree(paddc);
+
+	return ret;
+}
+
+static int do_arpt_set_ctl(struct sock *sk, int cmd, void *user, unsigned int len)
+{
+	int ret;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	switch (cmd) {
+	case ARPT_SO_SET_REPLACE:
+		ret = do_replace(user, len);
+		break;
+
+	case ARPT_SO_SET_ADD_COUNTERS:
+		ret = do_add_counters(user, len);
+		break;
+
+	default:
+		duprintf("do_arpt_set_ctl:  unknown request %i\n", cmd);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int do_arpt_get_ctl(struct sock *sk, int cmd, void *user, int *len)
+{
+	int ret;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	switch (cmd) {
+	case ARPT_SO_GET_INFO: {
+		char name[ARPT_TABLE_MAXNAMELEN];
+		struct arpt_table *t;
+
+		if (*len != sizeof(struct arpt_getinfo)) {
+			duprintf("length %u != %Zu\n", *len,
+				 sizeof(struct arpt_getinfo));
+			ret = -EINVAL;
+			break;
+		}
+
+		if (copy_from_user(name, user, sizeof(name)) != 0) {
+			ret = -EFAULT;
+			break;
+		}
+		name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
+		t = find_table_lock(name, &ret, &arpt_mutex);
+		if (t) {
+			struct arpt_getinfo info;
+
+			info.valid_hooks = t->valid_hooks;
+			memcpy(info.hook_entry, t->private->hook_entry,
+			       sizeof(info.hook_entry));
+			memcpy(info.underflow, t->private->underflow,
+			       sizeof(info.underflow));
+			info.num_entries = t->private->number;
+			info.size = t->private->size;
+			strcpy(info.name, name);
+
+			if (copy_to_user(user, &info, *len) != 0)
+				ret = -EFAULT;
+			else
+				ret = 0;
+
+			up(&arpt_mutex);
+		}
+	}
+	break;
+
+	case ARPT_SO_GET_ENTRIES: {
+		struct arpt_get_entries get;
+
+		if (*len < sizeof(get)) {
+			duprintf("get_entries: %u < %Zu\n", *len, sizeof(get));
+			ret = -EINVAL;
+		} else if (copy_from_user(&get, user, sizeof(get)) != 0) {
+			ret = -EFAULT;
+		} else if (*len != sizeof(struct arpt_get_entries) + get.size) {
+			duprintf("get_entries: %u != %Zu\n", *len,
+				 sizeof(struct arpt_get_entries) + get.size);
+			ret = -EINVAL;
+		} else
+			ret = get_entries(&get, user);
+		break;
+	}
+
+	default:
+		duprintf("do_arpt_get_ctl: unknown request %i\n", cmd);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+/* Registration hooks for targets. */
+int arpt_register_target(struct arpt_target *target)
+{
+	int ret;
+
+	MOD_INC_USE_COUNT;
+	ret = down_interruptible(&arpt_mutex);
+	if (ret != 0) {
+		MOD_DEC_USE_COUNT;
+		return ret;
+	}
+	if (!list_named_insert(&arpt_target, target)) {
+		duprintf("arpt_register_target: `%s' already in list!\n",
+			 target->name);
+		ret = -EINVAL;
+		MOD_DEC_USE_COUNT;
+	}
+	up(&arpt_mutex);
+	return ret;
+}
+
+void arpt_unregister_target(struct arpt_target *target)
+{
+	down(&arpt_mutex);
+	LIST_DELETE(&arpt_target, target);
+	up(&arpt_mutex);
+	MOD_DEC_USE_COUNT;
+}
+
+int arpt_register_table(struct arpt_table *table)
+{
+	int ret;
+	struct arpt_table_info *newinfo;
+	static struct arpt_table_info bootstrap
+		= { 0, 0, 0, { 0 }, { 0 }, { } };
+
+	MOD_INC_USE_COUNT;
+	newinfo = vmalloc(sizeof(struct arpt_table_info)
+			  + SMP_ALIGN(table->table->size) * smp_num_cpus);
+	if (!newinfo) {
+		ret = -ENOMEM;
+		MOD_DEC_USE_COUNT;
+		return ret;
+	}
+	memcpy(newinfo->entries, table->table->entries, table->table->size);
+
+	ret = translate_table(table->name, table->valid_hooks,
+			      newinfo, table->table->size,
+			      table->table->num_entries,
+			      table->table->hook_entry,
+			      table->table->underflow);
+	duprintf("arpt_register_table: translate table gives %d\n", ret);
+	if (ret != 0) {
+		vfree(newinfo);
+		MOD_DEC_USE_COUNT;
+		return ret;
+	}
+
+	ret = down_interruptible(&arpt_mutex);
+	if (ret != 0) {
+		vfree(newinfo);
+		MOD_DEC_USE_COUNT;
+		return ret;
+	}
+
+	/* Don't autoload: we'd eat our tail... */
+	if (list_named_find(&arpt_tables, table->name)) {
+		ret = -EEXIST;
+		goto free_unlock;
+	}
+
+	/* Simplifies replace_table code. */
+	table->private = &bootstrap;
+	if (!replace_table(table, 0, newinfo, &ret))
+		goto free_unlock;
+
+	duprintf("table->private->number = %u\n",
+		 table->private->number);
+	
+	/* save number of initial entries */
+	table->private->initial_entries = table->private->number;
+
+	table->lock = RW_LOCK_UNLOCKED;
+	list_prepend(&arpt_tables, table);
+
+ unlock:
+	up(&arpt_mutex);
+	return ret;
+
+ free_unlock:
+	vfree(newinfo);
+	MOD_DEC_USE_COUNT;
+	goto unlock;
+}
+
+void arpt_unregister_table(struct arpt_table *table)
+{
+	down(&arpt_mutex);
+	LIST_DELETE(&arpt_tables, table);
+	up(&arpt_mutex);
+
+	/* Decrease module usage counts and free resources */
+	ARPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+			   cleanup_entry, NULL);
+	vfree(table->private);
+	MOD_DEC_USE_COUNT;
+}
+
+/* The built-in targets: standard (NULL) and error. */
+static struct arpt_target arpt_standard_target
+= { { NULL, NULL }, ARPT_STANDARD_TARGET, NULL, NULL, NULL };
+static struct arpt_target arpt_error_target
+= { { NULL, NULL }, ARPT_ERROR_TARGET, arpt_error, NULL, NULL };
+
+static struct nf_sockopt_ops arpt_sockopts
+= { { NULL, NULL }, PF_INET, ARPT_BASE_CTL, ARPT_SO_SET_MAX+1, do_arpt_set_ctl,
+    ARPT_BASE_CTL, ARPT_SO_GET_MAX+1, do_arpt_get_ctl, 0, NULL  };
+
+#ifdef CONFIG_PROC_FS
+static inline int print_name(const struct arpt_table *t,
+			     off_t start_offset, char *buffer, int length,
+			     off_t *pos, unsigned int *count)
+{
+	if ((*count)++ >= start_offset) {
+		unsigned int namelen;
+
+		namelen = sprintf(buffer + *pos, "%s\n", t->name);
+		if (*pos + namelen > length) {
+			/* Stop iterating */
+			return 1;
+		}
+		*pos += namelen;
+	}
+	return 0;
+}
+
+static int arpt_get_tables(char *buffer, char **start, off_t offset, int length)
+{
+	off_t pos = 0;
+	unsigned int count = 0;
+
+	if (down_interruptible(&arpt_mutex) != 0)
+		return 0;
+
+	LIST_FIND(&arpt_tables, print_name, struct arpt_table *,
+		  offset, buffer, length, &pos, &count);
+
+	up(&arpt_mutex);
+
+	/* `start' hack - see fs/proc/generic.c line ~105 */
+	*start=(char *)((unsigned long)count-offset);
+	return pos;
+}
+#endif /*CONFIG_PROC_FS*/
+
+static int __init init(void)
+{
+	int ret;
+
+	/* Noone else will be downing sem now, so we won't sleep */
+	down(&arpt_mutex);
+	list_append(&arpt_target, &arpt_standard_target);
+	list_append(&arpt_target, &arpt_error_target);
+	up(&arpt_mutex);
+
+	/* Register setsockopt */
+	ret = nf_register_sockopt(&arpt_sockopts);
+	if (ret < 0) {
+		duprintf("Unable to register sockopts.\n");
+		return ret;
+	}
+
+#ifdef CONFIG_PROC_FS
+	{
+		struct proc_dir_entry *proc;
+
+		proc = proc_net_create("arp_tables_names", 0, arpt_get_tables);
+		if (!proc) {
+			nf_unregister_sockopt(&arpt_sockopts);
+			return -ENOMEM;
+		}
+		proc->owner = THIS_MODULE;
+	}
+#endif
+
+	printk("arp_tables: (C) 2002 David S. Miller\n");
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	nf_unregister_sockopt(&arpt_sockopts);
+#ifdef CONFIG_PROC_FS
+	proc_net_remove("arp_tables_names");
+#endif
+}
+
+EXPORT_SYMBOL(arpt_register_table);
+EXPORT_SYMBOL(arpt_unregister_table);
+EXPORT_SYMBOL(arpt_do_table);
+EXPORT_SYMBOL(arpt_register_target);
+EXPORT_SYMBOL(arpt_unregister_target);
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/arptable_filter.c linux/net/ipv4/netfilter/arptable_filter.c
--- linux.orig/net/ipv4/netfilter/arptable_filter.c	1970-01-01 00:00:00.000000000 +0000
+++ linux/net/ipv4/netfilter/arptable_filter.c	2002-07-20 01:08:25.000000000 +0000
@@ -0,0 +1,174 @@
+/*
+ * Filtering ARP tables module.
+ *
+ * Copyright (C) 2002 David S. Miller (davem@redhat.com)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/netfilter_arp/arp_tables.h>
+
+#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT))
+
+/* Standard entry. */
+struct arpt_standard
+{
+	struct arpt_entry entry;
+	struct arpt_standard_target target;
+};
+
+struct arpt_error_target
+{
+	struct arpt_entry_target target;
+	char errorname[ARPT_FUNCTION_MAXNAMELEN];
+};
+
+struct arpt_error
+{
+	struct arpt_entry entry;
+	struct arpt_error_target target;
+};
+
+static struct
+{
+	struct arpt_replace repl;
+	struct arpt_standard entries[2];
+	struct arpt_error term;
+} initial_table __initdata
+= { { "filter", FILTER_VALID_HOOKS, 3,
+      sizeof(struct arpt_standard) * 2 + sizeof(struct arpt_error),
+      { [NF_ARP_IN] 0,
+	[NF_ARP_OUT] sizeof(struct arpt_standard) },
+      { [NF_ARP_IN] 0,
+	[NF_ARP_OUT] sizeof(struct arpt_standard), },
+      0, NULL, { } },
+    {
+	    /* ARP_IN */
+	    {
+		    {
+			    {
+				    { 0 }, { 0 }, { 0 }, { 0 },
+				    0, 0,
+				    { { 0, }, { 0, } },
+				    { { 0, }, { 0, } },
+				    0, 0,
+				    0, 0,
+				    0, 0,
+				    "", "", { 0 }, { 0 },
+				    0, 0
+			    },
+			    sizeof(struct arpt_entry),
+			    sizeof(struct arpt_standard),
+			    0,
+			    { 0, 0 }, { } },
+		    { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
+		      -NF_ACCEPT - 1 }
+	    },
+	    /* ARP_OUT */
+	    {
+		    {
+			    {
+				    { 0 }, { 0 }, { 0 }, { 0 },
+				    0, 0,
+				    { { 0, }, { 0, } },
+				    { { 0, }, { 0, } },
+				    0, 0,
+				    0, 0,
+				    0, 0,
+				    "", "", { 0 }, { 0 },
+				    0, 0
+			    },
+			    sizeof(struct arpt_entry),
+			    sizeof(struct arpt_standard),
+			    0,
+			    { 0, 0 }, { } },
+		    { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
+		      -NF_ACCEPT - 1 }
+	    }
+    },
+    /* ERROR */
+    {
+	    {
+		    {
+			    { 0 }, { 0 }, { 0 }, { 0 },
+			    0, 0,
+			    { { 0, }, { 0, } },
+			    { { 0, }, { 0, } },
+			    0, 0,
+			    0, 0,
+			    0, 0,
+			    "", "", { 0 }, { 0 },
+			    0, 0
+		    },
+		    sizeof(struct arpt_entry),
+		    sizeof(struct arpt_error),
+		    0,
+		    { 0, 0 }, { } },
+	    { { { { ARPT_ALIGN(sizeof(struct arpt_error_target)), ARPT_ERROR_TARGET } },
+		{ } },
+	      "ERROR"
+	    }
+    }
+};
+
+static struct arpt_table packet_filter
+= { { NULL, NULL }, "filter", &initial_table.repl,
+    FILTER_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL, THIS_MODULE };
+
+/* The work comes in here from netfilter.c */
+static unsigned int arpt_hook(unsigned int hook,
+			      struct sk_buff **pskb,
+			      const struct net_device *in,
+			      const struct net_device *out,
+			      int (*okfn)(struct sk_buff *))
+{
+	return arpt_do_table(pskb, hook, in, out, &packet_filter, NULL);
+}
+
+static struct nf_hook_ops arpt_ops[]
+= { { { NULL, NULL }, arpt_hook, NF_ARP, NF_ARP_IN, 0 },
+    { { NULL, NULL }, arpt_hook, NF_ARP, NF_ARP_OUT, 0 }
+};
+
+static int __init init(void)
+{
+	int ret;
+
+	/* Register table */
+	ret = arpt_register_table(&packet_filter);
+	if (ret < 0)
+		return ret;
+
+	/* Register hooks */
+	ret = nf_register_hook(&arpt_ops[0]);
+	if (ret < 0)
+		goto cleanup_table;
+
+	ret = nf_register_hook(&arpt_ops[1]);
+	if (ret < 0)
+		goto cleanup_hook0;
+
+	return ret;
+
+cleanup_hook0:
+	nf_unregister_hook(&arpt_ops[0]);
+
+cleanup_table:
+	arpt_unregister_table(&packet_filter);
+
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < sizeof(arpt_ops)/sizeof(struct nf_hook_ops); i++)
+		nf_unregister_hook(&arpt_ops[i]);
+
+	arpt_unregister_table(&packet_filter);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_conntrack_core.c linux/net/ipv4/netfilter/ip_conntrack_core.c
--- linux.orig/net/ipv4/netfilter/ip_conntrack_core.c	2001-08-07 15:30:50.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_conntrack_core.c	2002-07-20 01:08:21.000000000 +0000
@@ -175,6 +175,7 @@
 destroy_conntrack(struct nf_conntrack *nfct)
 {
 	struct ip_conntrack *ct = (struct ip_conntrack *)nfct;
+	struct ip_conntrack_protocol *proto;
 
 	IP_NF_ASSERT(atomic_read(&nfct->use) == 0);
 	IP_NF_ASSERT(!timer_pending(&ct->timeout));
@@ -182,6 +183,13 @@
 	if (ct->master.master)
 		nf_conntrack_put(&ct->master);
 
+	/* To make sure we don't get any weird locking issues here:
+	 * destroy_conntrack() MUST NOT be called with a write lock
+	 * to ip_conntrack_lock!!! -HW */
+	proto = find_proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
+	if (proto && proto->destroy)
+		proto->destroy(ct);
+
 	if (ip_conntrack_destroyed)
 		ip_conntrack_destroyed(ct);
 	kmem_cache_free(ip_conntrack_cachep, ct);
@@ -489,9 +497,9 @@
 		/* Try dropping from random chain, or else from the
                    chain about to put into (in case they're trying to
                    bomb one hash chain). */
-		if (drop_next >= ip_conntrack_htable_size)
-			drop_next = 0;
-		if (!early_drop(&ip_conntrack_hash[drop_next++])
+		unsigned int next = (drop_next++)%ip_conntrack_htable_size;
+
+		if (!early_drop(&ip_conntrack_hash[next])
 		    && !early_drop(&ip_conntrack_hash[hash])) {
 			if (net_ratelimit())
 				printk(KERN_WARNING
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_conntrack_proto_generic.c linux/net/ipv4/netfilter/ip_conntrack_proto_generic.c
--- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2001-04-27 21:15:01.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2002-07-20 01:08:32.000000000 +0000
@@ -57,5 +57,5 @@
 struct ip_conntrack_protocol ip_conntrack_generic_protocol
 = { { NULL, NULL }, 0, "unknown",
     generic_pkt_to_tuple, generic_invert_tuple, generic_print_tuple,
-    generic_print_conntrack, established, new, NULL };
+    generic_print_conntrack, established, new, NULL, NULL };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_conntrack_proto_icmp.c linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
--- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2001-04-27 21:15:01.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2002-07-20 01:08:22.000000000 +0000
@@ -113,4 +113,4 @@
 struct ip_conntrack_protocol ip_conntrack_protocol_icmp
 = { { NULL, NULL }, IPPROTO_ICMP, "icmp",
     icmp_pkt_to_tuple, icmp_invert_tuple, icmp_print_tuple,
-    icmp_print_conntrack, icmp_packet, icmp_new, NULL };
+    icmp_print_conntrack, icmp_packet, icmp_new, NULL, NULL };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2001-04-27 21:15:01.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2002-07-20 01:08:35.000000000 +0000
@@ -230,4 +230,4 @@
 struct ip_conntrack_protocol ip_conntrack_protocol_tcp
 = { { NULL, NULL }, IPPROTO_TCP, "tcp",
     tcp_pkt_to_tuple, tcp_invert_tuple, tcp_print_tuple, tcp_print_conntrack,
-    tcp_packet, tcp_new, NULL };
+    tcp_packet, tcp_new, NULL, NULL };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_conntrack_proto_udp.c linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c
--- linux.orig/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2001-04-27 21:15:01.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2002-07-20 01:08:21.000000000 +0000
@@ -71,4 +71,4 @@
 struct ip_conntrack_protocol ip_conntrack_protocol_udp
 = { { NULL, NULL }, IPPROTO_UDP, "udp",
     udp_pkt_to_tuple, udp_invert_tuple, udp_print_tuple, udp_print_conntrack,
-    udp_packet, udp_new, NULL };
+    udp_packet, udp_new, NULL, NULL };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_conntrack_standalone.c linux/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux.orig/net/ipv4/netfilter/ip_conntrack_standalone.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_conntrack_standalone.c	2002-07-20 01:08:35.000000000 +0000
@@ -15,6 +15,7 @@
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
 #include <linux/version.h>
+#include <linux/brlock.h>
 #include <net/checksum.h>
 
 #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
@@ -35,6 +36,11 @@
 struct module *ip_conntrack_module = THIS_MODULE;
 MODULE_LICENSE("GPL");
 
+static int kill_proto(const struct ip_conntrack *i, void *data)
+{
+	return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == 
+			*((u_int8_t *) data));
+}
 
 static unsigned int
 print_tuple(char *buffer, const struct ip_conntrack_tuple *tuple,
@@ -304,12 +310,24 @@
 	return ret;
 }
 
-/* FIXME: Implement this --RR */
-#if 0
 void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
 {
+	WRITE_LOCK(&ip_conntrack_lock);
+
+	/* find_proto() returns proto_generic in case there is no protocol 
+	 * helper. So this should be enough - HW */
+	LIST_DELETE(&protocol_list, proto);
+	WRITE_UNLOCK(&ip_conntrack_lock);
+	
+	/* Somebody could be still looking at the proto in bh. */
+	br_write_lock_bh(BR_NETPROTO_LOCK);
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
+
+	/* Remove all contrack entries for this protocol */
+	ip_ct_selective_cleanup(kill_proto, &proto->proto);
+
+	MOD_DEC_USE_COUNT;
 }
-#endif
 
 static int __init init(void)
 {
@@ -325,6 +343,7 @@
 module_exit(fini);
 
 EXPORT_SYMBOL(ip_conntrack_protocol_register);
+EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
 EXPORT_SYMBOL(invert_tuplepr);
 EXPORT_SYMBOL(ip_conntrack_alter_reply);
 EXPORT_SYMBOL(ip_conntrack_destroyed);
@@ -335,6 +354,7 @@
 EXPORT_SYMBOL(ip_ct_selective_cleanup);
 EXPORT_SYMBOL(ip_ct_refresh);
 EXPORT_SYMBOL(ip_conntrack_expect_related);
+EXPORT_SYMBOL(ip_conntrack_unexpect_related);
 EXPORT_SYMBOL(ip_conntrack_tuple_taken);
 EXPORT_SYMBOL(ip_ct_gather_frags);
 EXPORT_SYMBOL(ip_conntrack_htable_size);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_fw_compat_redir.c linux/net/ipv4/netfilter/ip_fw_compat_redir.c
--- linux.orig/net/ipv4/netfilter/ip_fw_compat_redir.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_fw_compat_redir.c	2002-07-20 01:08:27.000000000 +0000
@@ -43,7 +43,7 @@
 		   netplay... */					 \
 		printk("ASSERT: %s:%i(%s)\n",				 \
 		       __FILE__, __LINE__, __FUNCTION__);		 \
-} while(0);
+} while(0)
 #else
 #define IP_NF_ASSERT(x)
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_nat_core.c linux/net/ipv4/netfilter/ip_nat_core.c
--- linux.orig/net/ipv4/netfilter/ip_nat_core.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_nat_core.c	2002-07-20 01:08:26.000000000 +0000
@@ -314,6 +314,7 @@
 			 * do_extra_mangle last time. */
 			*other_ipp = saved_ip;
 
+#ifdef CONFIG_IP_NF_NAT_LOCAL
 			if (hooknum == NF_IP_LOCAL_OUT
 			    && *var_ipp != orig_dstip
 			    && !do_extra_mangle(*var_ipp, other_ipp)) {
@@ -324,6 +325,7 @@
 				 * anyway. */
 				continue;
 			}
+#endif
 
 			/* Count how many others map onto this. */
 			score = count_maps(tuple->src.ip, tuple->dst.ip,
@@ -367,11 +369,13 @@
 		else {
 			/* Only do extra mangle when required (breaks
                            socket binding) */
+#ifdef CONFIG_IP_NF_NAT_LOCAL
 			if (tuple->dst.ip != mr->range[0].min_ip
 			    && hooknum == NF_IP_LOCAL_OUT
 			    && !do_extra_mangle(mr->range[0].min_ip,
 						&tuple->src.ip))
 				return NULL;
+#endif
 			tuple->dst.ip = mr->range[0].min_ip;
 		}
 	}
@@ -494,7 +498,10 @@
 static unsigned int opposite_hook[NF_IP_NUMHOOKS]
 = { [NF_IP_PRE_ROUTING] = NF_IP_POST_ROUTING,
     [NF_IP_POST_ROUTING] = NF_IP_PRE_ROUTING,
-    [NF_IP_LOCAL_OUT] = NF_IP_POST_ROUTING
+#ifdef CONFIG_IP_NF_NAT_LOCAL
+    [NF_IP_LOCAL_OUT] = NF_IP_LOCAL_IN,
+    [NF_IP_LOCAL_IN] = NF_IP_LOCAL_OUT,
+#endif
 };
 
 unsigned int
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_nat_rule.c linux/net/ipv4/netfilter/ip_nat_rule.c
--- linux.orig/net/ipv4/netfilter/ip_nat_rule.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_nat_rule.c	2002-07-20 01:08:34.000000000 +0000
@@ -140,8 +140,12 @@
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
 
+#ifdef CONFIG_IP_NF_NAT_LOCAL
 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
 		     || hooknum == NF_IP_LOCAL_OUT);
+#else
+	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING);
+#endif
 
 	ct = ip_conntrack_get(*pskb, &ctinfo);
 
@@ -210,7 +214,7 @@
 
 	/* Only allow these for NAT. */
 	if (strcmp(tablename, "nat") != 0) {
-		DEBUGP("SNAT: wrong table %s\n", tablename);
+		DEBUGP("DNAT: wrong table %s\n", tablename);
 		return 0;
 	}
 
@@ -218,6 +222,14 @@
 		DEBUGP("DNAT: hook mask 0x%x bad\n", hook_mask);
 		return 0;
 	}
+	
+#ifndef CONFIG_IP_NF_NAT_LOCAL
+	if (hook_mask & (1 << NF_IP_LOCAL_OUT)) {
+		DEBUGP("DNAT: CONFIG_IP_NF_NAT_LOCAL not enabled\n");
+		return 0;
+	}
+#endif
+
 	return 1;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_nat_standalone.c linux/net/ipv4/netfilter/ip_nat_standalone.c
--- linux.orig/net/ipv4/netfilter/ip_nat_standalone.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_nat_standalone.c	2002-07-20 01:08:29.000000000 +0000
@@ -41,7 +41,8 @@
 #define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING"  \
 			   : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \
 			      : ((hooknum) == NF_IP_LOCAL_OUT ? "LOCAL_OUT"  \
-				 : "*ERROR*")))
+			         : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN"  \
+				    : "*ERROR*")))
 
 static unsigned int
 ip_nat_fn(unsigned int hooknum,
@@ -94,6 +95,12 @@
 		}
 		/* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
 	case IP_CT_NEW:
+#ifdef CONFIG_IP_NF_NAT_LOCAL
+		/* LOCAL_IN hook doesn't have a chain and thus doesn't care
+		 * about new packets -HW */
+		if (hooknum == NF_IP_LOCAL_IN)
+			return NF_ACCEPT;
+#endif
 		info = &ct->nat.info;
 
 		WRITE_LOCK(&ip_nat_lock);
@@ -204,6 +211,11 @@
 static struct nf_hook_ops ip_nat_local_out_ops
 = { { NULL, NULL }, ip_nat_local_fn, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_NAT_DST };
 
+#ifdef CONFIG_IP_NF_NAT_LOCAL
+static struct nf_hook_ops ip_nat_local_in_ops
+= { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_NAT_SRC };
+#endif
+
 /* Protocol registration. */
 int ip_nat_protocol_register(struct ip_nat_protocol *proto)
 {
@@ -272,6 +284,13 @@
 		printk("ip_nat_init: can't register local out hook.\n");
 		goto cleanup_outops;
 	}
+#ifdef CONFIG_IP_NF_NAT_LOCAL
+	ret = nf_register_hook(&ip_nat_local_in_ops);
+	if (ret < 0) {
+		printk("ip_nat_init: can't register local in hook.\n");
+		goto cleanup_localoutops;
+	}
+#endif
 	if (ip_conntrack_module)
 		__MOD_INC_USE_COUNT(ip_conntrack_module);
 	return ret;
@@ -279,6 +298,10 @@
  cleanup:
 	if (ip_conntrack_module)
 		__MOD_DEC_USE_COUNT(ip_conntrack_module);
+#ifdef CONFIG_IP_NF_NAT_LOCAL
+	nf_unregister_hook(&ip_nat_local_in_ops);
+ cleanup_localoutops:
+#endif
 	nf_unregister_hook(&ip_nat_local_out_ops);
  cleanup_outops:
 	nf_unregister_hook(&ip_nat_out_ops);
@@ -307,6 +330,8 @@
 module_exit(fini);
 
 EXPORT_SYMBOL(ip_nat_setup_info);
+EXPORT_SYMBOL(ip_nat_protocol_register);
+EXPORT_SYMBOL(ip_nat_protocol_unregister);
 EXPORT_SYMBOL(ip_nat_helper_register);
 EXPORT_SYMBOL(ip_nat_helper_unregister);
 EXPORT_SYMBOL(ip_nat_expect_register);
@@ -315,4 +340,5 @@
 EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
 EXPORT_SYMBOL(ip_nat_seq_adjust);
 EXPORT_SYMBOL(ip_nat_delete_sack);
+EXPORT_SYMBOL(ip_nat_used_tuple);
 MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ip_queue.c linux/net/ipv4/netfilter/ip_queue.c
--- linux.orig/net/ipv4/netfilter/ip_queue.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/ip_queue.c	2002-07-20 01:08:37.000000000 +0000
@@ -464,7 +464,7 @@
 	return netlink_unicast(nfnl, skb, nlq->peer.pid, MSG_DONTWAIT);
 }
 
-#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0);
+#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
 
 static __inline__ void netlink_receive_user_skb(struct sk_buff *skb)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ipchains_core.c linux/net/ipv4/netfilter/ipchains_core.c
--- linux.orig/net/ipv4/netfilter/ipchains_core.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/ipchains_core.c	2002-07-20 01:08:31.000000000 +0000
@@ -549,7 +549,7 @@
 			strcpy(outskb->data+sizeof(__u32)*2, rif);
 			memcpy(outskb->data+sizeof(__u32)*2+IFNAMSIZ, ip,
 			       len-(sizeof(__u32)*2+IFNAMSIZ));
-			netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_KERNEL);
+			netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
 		}
 		else {
 #endif
@@ -723,6 +723,7 @@
 						      src_port, dst_port,
 						      count, tcpsyn)) {
 					ret = FW_BLOCK;
+					cleanup(chain, 0, slot);
 					goto out;
 				}
 				break;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ipt_REJECT.c linux/net/ipv4/netfilter/ipt_REJECT.c
--- linux.orig/net/ipv4/netfilter/ipt_REJECT.c	2001-10-06 15:50:28.000000000 +0000
+++ linux/net/ipv4/netfilter/ipt_REJECT.c	2002-07-20 01:08:30.000000000 +0000
@@ -39,7 +39,8 @@
 	struct tcphdr *otcph, *tcph;
 	struct rtable *rt;
 	unsigned int otcplen;
-	u_int16_t tmp;
+	u_int16_t tmp_port;
+	u_int32_t tmp_addr;
 	int needs_ack;
 
 	/* IP header checks: fragment, too short. */
@@ -78,10 +79,12 @@
 	tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
 
 	/* Swap source and dest */
-	nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
-	tmp = tcph->source;
+	tmp_addr = nskb->nh.iph->saddr;
+	nskb->nh.iph->saddr = nskb->nh.iph->daddr;
+	nskb->nh.iph->daddr = tmp_addr;
+	tmp_port = tcph->source;
 	tcph->source = tcph->dest;
-	tcph->dest = tmp;
+	tcph->dest = tmp_port;
 
 	/* Truncate to length (no data) */
 	tcph->doff = sizeof(struct tcphdr)/4;
@@ -234,11 +237,8 @@
 	iph->tos=tos;
 	iph->tot_len = htons(length);
 
-	/* This abbreviates icmp->send->ip_build_xmit->ip_dont_fragment */
-	if (!ipv4_config.no_pmtu_disc
-	    && !(rt->u.dst.mxlock&(1<<RTAX_MTU)))
-		iph->frag_off = htons(IP_DF);
-	else iph->frag_off = 0;
+	/* PMTU discovery never applies to ICMP packets. */
+	iph->frag_off = 0;
 
 	iph->ttl = MAXTTL;
 	ip_select_ident(iph, &rt->u.dst, NULL);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/netfilter/ipt_ULOG.c linux/net/ipv4/netfilter/ipt_ULOG.c
--- linux.orig/net/ipv4/netfilter/ipt_ULOG.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/netfilter/ipt_ULOG.c	2002-07-20 01:08:38.000000000 +0000
@@ -29,7 +29,7 @@
  *   Specify, after how many clock ticks (intel: 100 per second) the queue
  * should be flushed even if it is not full yet.
  *
- * ipt_ULOG.c,v 1.15 2002/01/18 21:33:19 laforge Exp
+ * ipt_ULOG.c,v 1.18 2002/04/16 07:33:00 laforge Exp
  */
 
 #include <linux/module.h>
@@ -61,7 +61,7 @@
 #define DEBUGP(format, args...)
 #endif
 
-#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format, ## args); } while (0);
+#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format, ## args); } while (0)
 
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
 MODULE_DESCRIPTION("IP tables userspace logging module");
@@ -339,10 +339,28 @@
 
 static void __exit fini(void)
 {
+	ulog_buff_t *ub;
+	int i;
+
 	DEBUGP("ipt_ULOG: cleanup_module\n");
 
 	ipt_unregister_target(&ipt_ulog_reg);
 	sock_release(nflognl->socket);
+
+	/* remove pending timers and free allocated skb's */
+	for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
+		ub = &ulog_buffers[i];
+		if (timer_pending(&ub->timer)) {
+			DEBUGP("timer was pending, deleting\n");
+			del_timer(&ub->timer);
+		}
+
+		if (ub->skb) {
+			kfree_skb(ub->skb);
+			ub->skb = NULL;
+		}
+	}
+
 }
 
 module_init(init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/raw.c linux/net/ipv4/raw.c
--- linux.orig/net/ipv4/raw.c	2001-07-10 23:11:43.000000000 +0000
+++ linux/net/ipv4/raw.c	2002-07-20 01:08:22.000000000 +0000
@@ -5,7 +5,7 @@
  *
  *		RAW - implementation of IP "raw" sockets.
  *
- * Version:	$Id: raw.c,v 1.63 2001/07/10 04:29:01 davem Exp $
+ * Version:	$Id: raw.c,v 1.63.2.1 2002/03/05 12:47:34 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -631,7 +631,7 @@
 	      srcp  = sp->num;
 
 	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
-		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
+		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
 		i, src, srcp, dest, destp, sp->state, 
 		atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
 		0, 0L, 0,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/route.c linux/net/ipv4/route.c
--- linux.orig/net/ipv4/route.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/route.c	2002-07-20 01:08:40.000000000 +0000
@@ -286,7 +286,7 @@
         for (lcpu = 0; lcpu < smp_num_cpus; lcpu++) {
                 i = cpu_logical_map(lcpu);
 
-		len += sprintf(buffer+len, "%08x  %08x %08x %08x %08x %08x %08x %08x  %08x %08x %08x\n",
+		len += sprintf(buffer+len, "%08x  %08x %08x %08x %08x %08x %08x %08x  %08x %08x %08x %08x %08x %08x %08x \n",
 			       dst_entries,		       
 			       rt_cache_stat[i].in_hit,
 			       rt_cache_stat[i].in_slow_tot,
@@ -298,7 +298,13 @@
 
 			       rt_cache_stat[i].out_hit,
 			       rt_cache_stat[i].out_slow_tot,
-			       rt_cache_stat[i].out_slow_mc
+			       rt_cache_stat[i].out_slow_mc, 
+
+			       rt_cache_stat[i].gc_total,
+			       rt_cache_stat[i].gc_ignored,
+			       rt_cache_stat[i].gc_goal_miss,
+			       rt_cache_stat[i].gc_dst_overflow
+
 			);
 	}
 	len -= offset;
@@ -499,9 +505,14 @@
 	 * Garbage collection is pretty expensive,
 	 * do not make it too frequently.
 	 */
+
+	rt_cache_stat[smp_processor_id()].gc_total++;
+
 	if (now - last_gc < ip_rt_gc_min_interval &&
-	    atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size)
+	    atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) {
+		rt_cache_stat[smp_processor_id()].gc_ignored++;
 		goto out;
+	}
 
 	/* Calculate number of entries, which we want to expire now. */
 	goal = atomic_read(&ipv4_dst_ops.entries) -
@@ -567,6 +578,8 @@
 		     We will not spin here for long time in any case.
 		 */
 
+		rt_cache_stat[smp_processor_id()].gc_goal_miss++;
+
 		if (expire == 0)
 			break;
 
@@ -583,7 +596,8 @@
 	if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size)
 		goto out;
 	if (net_ratelimit())
-		printk("dst cache overflow\n");
+		printk(KERN_WARNING "dst cache overflow\n");
+	rt_cache_stat[smp_processor_id()].gc_dst_overflow++;
 	return 1;
 
 work_done:
@@ -657,7 +671,7 @@
 			}
 
 			if (net_ratelimit())
-				printk("Neighbour table overflow.\n");
+				printk(KERN_WARNING "Neighbour table overflow.\n");
 			rt_drop(rt);
 			return -ENOBUFS;
 		}
@@ -667,8 +681,8 @@
 #if RT_CACHE_DEBUG >= 2
 	if (rt->u.rt_next) {
 		struct rtable *trt;
-		printk("rt_cache @%02x: %u.%u.%u.%u", hash,
-				NIPQUAD(rt->rt_dst));
+		printk(KERN_DEBUG "rt_cache @%02x: %u.%u.%u.%u", hash,
+		       NIPQUAD(rt->rt_dst));
 		for (trt = rt->u.rt_next; trt; trt = trt->u.rt_next)
 			printk(" . %u.%u.%u.%u", NIPQUAD(trt->rt_dst));
 		printk("\n");
@@ -2454,7 +2468,7 @@
 
 #ifdef CONFIG_NET_CLS_ROUTE
 	for (order = 0;
-	     (PAGE_SIZE << order) < 256 * sizeof(ip_rt_acct) * NR_CPUS; order++)
+	     (PAGE_SIZE << order) < 256 * sizeof(struct ip_rt_acct) * NR_CPUS; order++)
 		/* NOTHING */;
 	ip_rt_acct = (struct ip_rt_acct *)__get_free_pages(GFP_KERNEL, order);
 	if (!ip_rt_acct)
@@ -2487,7 +2501,7 @@
 	if (!rt_hash_table)
 		panic("Failed to allocate IP route cache hash table\n");
 
-	printk("IP: routing cache hash table of %u buckets, %ldKbytes\n",
+	printk(KERN_INFO "IP: routing cache hash table of %u buckets, %ldKbytes\n",
 	       rt_hash_mask,
 	       (long) (rt_hash_mask * sizeof(struct rt_hash_bucket)) / 1024);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/syncookies.c linux/net/ipv4/syncookies.c
--- linux.orig/net/ipv4/syncookies.c	2001-10-30 23:08:12.000000000 +0000
+++ linux/net/ipv4/syncookies.c	2002-07-20 01:08:22.000000000 +0000
@@ -14,8 +14,6 @@
  *  Missing: IPv6 support. 
  */
 
-#include <linux/config.h>
-#if defined(CONFIG_SYN_COOKIES) 
 #include <linux/tcp.h>
 #include <linux/slab.h>
 #include <linux/random.h>
@@ -192,4 +190,3 @@
 	ret = get_cookie_sock(sk, skb, req, &rt->u.dst);
 out:	return ret;
 }
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/sysctl_net_ipv4.c linux/net/ipv4/sysctl_net_ipv4.c
--- linux.orig/net/ipv4/sysctl_net_ipv4.c	2001-10-30 23:08:12.000000000 +0000
+++ linux/net/ipv4/sysctl_net_ipv4.c	2002-07-20 01:08:38.000000000 +0000
@@ -219,6 +219,8 @@
 	 &sysctl_icmp_ratelimit, sizeof(int), 0644, NULL, &proc_dointvec},
 	{NET_IPV4_ICMP_RATEMASK, "icmp_ratemask",
 	 &sysctl_icmp_ratemask, sizeof(int), 0644, NULL, &proc_dointvec},
+	{NET_TCP_TW_REUSE, "tcp_tw_reuse",
+	 &sysctl_tcp_tw_reuse, sizeof(int), 0644, NULL, &proc_dointvec},
 	{0}
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- linux.orig/net/ipv4/tcp.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/ipv4/tcp.c	2002-07-20 01:08:30.000000000 +0000
@@ -251,6 +251,7 @@
 #include <linux/poll.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <linux/fs.h>
 
 #include <net/icmp.h>
 #include <net/tcp.h>
@@ -1157,7 +1158,8 @@
 
 			from += copy;
 			copied += copy;
-			seglen -= copy;
+			if ((seglen -= copy) == 0 && iovlen == 0)
+				goto out;
 
 			if (skb->len != mss_now || (flags&MSG_OOB))
 				continue;
@@ -1376,6 +1378,84 @@
 	tp->ucopy.memory = 0;
 }
 
+static inline
+struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
+{
+	struct sk_buff *skb;
+	u32 offset;
+
+	skb_queue_walk(&sk->receive_queue, skb) {
+		offset = seq - TCP_SKB_CB(skb)->seq;
+		if (skb->h.th->syn)
+			offset--;
+		if (offset < skb->len || skb->h.th->fin) {
+			*off = offset;
+			return skb;
+		}
+	}
+	return NULL;
+}
+
+/*
+ * This routine provides an alternative to tcp_recvmsg() for routines
+ * that would like to handle copying from skbuffs directly in 'sendfile'
+ * fashion.
+ * Note:
+ *	- It is assumed that the socket was locked by the caller.
+ *	- The routine does not block.
+ *	- At present, there is no support for reading OOB data
+ *	  or for 'peeking' the socket using this routine
+ *	  (although both would be easy to implement).
+ */
+int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
+		  sk_read_actor_t recv_actor)
+{
+	struct sk_buff *skb;
+	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+	u32 seq = tp->copied_seq;
+	u32 offset;
+	int copied = 0;
+
+	if (sk->state == TCP_LISTEN)
+		return -ENOTCONN;
+	while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
+		if (offset < skb->len) {
+			size_t used, len;
+
+			len = skb->len - offset;
+			/* Stop reading if we hit a patch of urgent data */
+			if (tp->urg_data) {
+				u32 urg_offset = tp->urg_seq - seq;
+				if (urg_offset < len)
+					len = urg_offset;
+				if (!len)
+					break;
+			}
+			used = recv_actor(desc, skb, offset, len);
+			if (used <= len) {
+				seq += used;
+				copied += used;
+				offset += used;
+			}
+			if (offset != skb->len)
+				break;
+		}
+		if (skb->h.th->fin) {
+			tcp_eat_skb(sk, skb);
+			++seq;
+			break;
+		}
+		tcp_eat_skb(sk, skb);
+		if (!desc->count)
+			break;
+	}
+	tp->copied_seq = seq;
+	/* Clean up data we have read: This will do ACK frames. */
+	if (copied)
+		cleanup_rbuf(sk, copied);
+	return copied;
+}
+
 /*
  *	This routine copies from a sock struct into the user buffer. 
  *
@@ -1582,6 +1662,12 @@
 				}
 			}
 		}
+		if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) {
+			if (net_ratelimit())
+				printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n",
+				       current->comm, current->pid);
+			peek_seq = tp->copied_seq;
+		}
 		continue;
 
 	found_ok_skb:
@@ -1791,7 +1877,7 @@
 
 #ifdef TCP_DEBUG
 	if (sk->zapped) {
-		printk("TCP: double destroy sk=%p\n", sk);
+		printk(KERN_DEBUG "TCP: double destroy sk=%p\n", sk);
 		sock_hold(sk);
 	}
 	sk->zapped = 1;
@@ -2552,7 +2638,7 @@
 		sysctl_tcp_rmem[2] = 2*43689;
 	}
 
-	printk("TCP: Hash tables configured (established %d bind %d)\n",
+	printk(KERN_INFO "TCP: Hash tables configured (established %d bind %d)\n",
 	       tcp_ehash_size<<1, tcp_bhash_size);
 
 	tcpdiag_init();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- linux.orig/net/ipv4/tcp_input.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/tcp_input.c	2002-07-20 01:08:28.000000000 +0000
@@ -124,9 +124,6 @@
 	len = skb->len;
 	if (len >= tp->ack.rcv_mss) {
 		tp->ack.rcv_mss = len;
-		/* Dubious? Rather, it is final cut. 8) */
-		if (tcp_flag_word(skb->h.th)&TCP_REMNANT)
-			tp->ack.pending |= TCP_ACK_PUSHED;
 	} else {
 		/* Otherwise, we make more careful check taking into account,
 		 * that SACKs block is variable.
@@ -461,13 +458,13 @@
 		if (after(tp->snd_una, tp->rtt_seq)) {
 			if (tp->mdev_max < tp->rttvar)
 				tp->rttvar -= (tp->rttvar-tp->mdev_max)>>2;
-			tp->rtt_seq = tp->snd_una;
+			tp->rtt_seq = tp->snd_nxt;
 			tp->mdev_max = TCP_RTO_MIN;
 		}
 	} else {
 		/* no previous measure. */
 		tp->srtt = m<<3;	/* take the measured time to be rtt */
-		tp->mdev = m<<2;	/* make sure rto = 3*rtt */
+		tp->mdev = m<<1;	/* make sure rto = 3*rtt */
 		tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN);
 		tp->rtt_seq = tp->snd_nxt;
 	}
@@ -1763,6 +1760,7 @@
 			acked |= FLAG_DATA_ACKED;
 		} else {
 			acked |= FLAG_SYN_ACKED;
+			tp->retrans_stamp = 0;
 		}
 
 		if (sacked) {
@@ -3850,6 +3848,7 @@
 	switch (sk->state) {
 	case TCP_CLOSE_WAIT:
 	case TCP_CLOSING:
+	case TCP_LAST_ACK:
 		if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt))
 			break;
 	case TCP_FIN_WAIT1:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- linux.orig/net/ipv4/tcp_ipv4.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/tcp_ipv4.c	2002-07-20 01:08:31.000000000 +0000
@@ -64,6 +64,8 @@
 #include <linux/ipsec.h>
 
 extern int sysctl_ip_dynaddr;
+extern int sysctl_ip_default_ttl;
+int sysctl_tcp_tw_reuse = 0;
 
 /* Check TCP sequence numbers in ICMP packets. */
 #define ICMP_MIN_LENGTH 8
@@ -162,23 +164,24 @@
 	local_bh_enable();
 }
 
-static inline void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, unsigned short snum) 
-{ 
-	sk->num = snum; 
+static inline void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, unsigned short snum)
+{
+	sk->num = snum;
 	if ((sk->bind_next = tb->owners) != NULL)
 		tb->owners->bind_pprev = &sk->bind_next;
 	tb->owners = sk;
 	sk->bind_pprev = &tb->owners;
 	sk->prev = (struct sock *) tb;
-} 
+}
 
 static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
-{ 
+{
 	struct sock *sk2 = tb->owners;
 	int sk_reuse = sk->reuse;
 	
 	for( ; sk2 != NULL; sk2 = sk2->bind_next) {
 		if (sk != sk2 &&
+		    sk2->reuse <= 1 &&
 		    sk->bound_dev_if == sk2->bound_dev_if) {
 			if (!sk_reuse	||
 			    !sk2->reuse	||
@@ -190,8 +193,8 @@
 			}
 		}
 	}
-	return sk2 != NULL; 
-} 
+	return sk2 != NULL;
+}
 
 /* Obtain a reference to a local port for the given sock,
  * if snum is zero it means select any available local port.
@@ -244,12 +247,14 @@
 				break;
 	}
 	if (tb != NULL && tb->owners != NULL) {
-		if (tb->fastreuse != 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
+		if (sk->reuse > 1)
+			goto success;
+		if (tb->fastreuse > 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
 			goto success;
 		} else {
-			ret = 1; 
+			ret = 1;
 			if (tcp_bind_conflict(sk, tb))
-				goto fail_unlock; 
+				goto fail_unlock;
 		}
 	}
 	ret = 1;
@@ -266,7 +271,7 @@
 		tb->fastreuse = 0;
 success:
 	if (sk->prev == NULL)
-		tcp_bind_hash(sk, tb, snum); 
+		tcp_bind_hash(sk, tb, snum);
 	BUG_TRAP(sk->prev == (struct sock *) tb);
  	ret = 0;
 
@@ -337,13 +342,13 @@
 	}
 }
 
-static __inline__ void __tcp_v4_hash(struct sock *sk)
+static __inline__ void __tcp_v4_hash(struct sock *sk, const int listen_possible)
 {
 	struct sock **skp;
 	rwlock_t *lock;
 
 	BUG_TRAP(sk->pprev==NULL);
-	if(sk->state == TCP_LISTEN) {
+	if(listen_possible && sk->state == TCP_LISTEN) {
 		skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)];
 		lock = &tcp_lhash_lock;
 		tcp_listen_wlock();
@@ -358,7 +363,7 @@
 	sk->pprev = skp;
 	sock_prot_inc_use(sk->prot);
 	write_unlock(lock);
-	if (sk->state == TCP_LISTEN)
+	if (listen_possible && sk->state == TCP_LISTEN)
 		wake_up(&tcp_lhash_wait);
 }
 
@@ -366,7 +371,7 @@
 {
 	if (sk->state != TCP_CLOSE) {
 		local_bh_disable();
-		__tcp_v4_hash(sk);
+		__tcp_v4_hash(sk, 1);
 		local_bh_enable();
 	}
 }
@@ -375,6 +380,9 @@
 {
 	rwlock_t *lock;
 
+	if (!sk->pprev)
+		goto ende;
+
 	if (sk->state == TCP_LISTEN) {
 		local_bh_disable();
 		tcp_listen_wlock();
@@ -393,6 +401,8 @@
 		sock_prot_dec_use(sk->prot);
 	}
 	write_unlock_bh(lock);
+
+ ende:
 	if (sk->state == TCP_LISTEN)
 		wake_up(&tcp_lhash_wait);
 }
@@ -530,19 +540,21 @@
 					  skb->h.th->source);
 }
 
-static int tcp_v4_check_established(struct sock *sk)
+/* called with local bh disabled */
+static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
+				      struct tcp_tw_bucket **twp)
 {
 	u32 daddr = sk->rcv_saddr;
 	u32 saddr = sk->daddr;
 	int dif = sk->bound_dev_if;
 	TCP_V4_ADDR_COOKIE(acookie, saddr, daddr)
-	__u32 ports = TCP_COMBINED_PORTS(sk->dport, sk->num);
-	int hash = tcp_hashfn(daddr, sk->num, saddr, sk->dport);
+	__u32 ports = TCP_COMBINED_PORTS(sk->dport, lport);
+	int hash = tcp_hashfn(daddr, lport, saddr, sk->dport);
 	struct tcp_ehash_bucket *head = &tcp_ehash[hash];
 	struct sock *sk2, **skp;
 	struct tcp_tw_bucket *tw;
 
-	write_lock_bh(&head->lock);
+	write_lock(&head->lock);
 
 	/* Check TIME-WAIT sockets first. */
 	for(skp = &(head + tcp_ehash_size)->chain; (sk2=*skp) != NULL;
@@ -566,7 +578,9 @@
 			   fall back to VJ's scheme and use initial
 			   timestamp retrieved from peer table.
 			 */
-			if (tw->ts_recent_stamp) {
+			if (tw->ts_recent_stamp &&
+			    (!twp || (sysctl_tcp_tw_reuse &&
+				      xtime.tv_sec - tw->ts_recent_stamp > 1))) {
 				if ((tp->write_seq = tw->snd_nxt+65535+2) == 0)
 					tp->write_seq = 1;
 				tp->ts_recent = tw->ts_recent;
@@ -587,6 +601,10 @@
 	}
 
 unique:
+	/* Must record num and sport now. Otherwise we will see
+	 * in hash table socket with a funny identity. */
+	sk->num = lport;
+	sk->sport = htons(lport);
 	BUG_TRAP(sk->pprev==NULL);
 	if ((sk->next = *skp) != NULL)
 		(*skp)->pprev = &sk->next;
@@ -595,15 +613,16 @@
 	sk->pprev = skp;
 	sk->hashent = hash;
 	sock_prot_inc_use(sk->prot);
-	write_unlock_bh(&head->lock);
+	write_unlock(&head->lock);
 
-	if (tw) {
+	if (twp) {
+		*twp = tw;
+		NET_INC_STATS_BH(TimeWaitRecycled);
+	} else if (tw) {
 		/* Silly. Should hash-dance instead... */
-		local_bh_disable();
 		tcp_tw_deschedule(tw);
 		tcp_timewait_kill(tw);
 		NET_INC_STATS_BH(TimeWaitRecycled);
-		local_bh_enable();
 
 		tcp_tw_put(tw);
 	}
@@ -611,34 +630,120 @@
 	return 0;
 
 not_unique:
-	write_unlock_bh(&head->lock);
+	write_unlock(&head->lock);
 	return -EADDRNOTAVAIL;
 }
 
-/* Hash SYN-SENT socket to established hash table after
- * checking that it is unique. Note, that without kernel lock
- * we MUST make these two operations atomically.
- *
- * Optimization: if it is bound and tcp_bind_bucket has the only
- * owner (us), we need not to scan established bucket.
+/*
+ * Bind a port for a connect operation and hash it.
  */
-
-int tcp_v4_hash_connecting(struct sock *sk)
+static int tcp_v4_hash_connect(struct sock *sk)
 {
 	unsigned short snum = sk->num;
-	struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(snum)];
-	struct tcp_bind_bucket *tb = (struct tcp_bind_bucket *)sk->prev;
+	struct tcp_bind_hashbucket *head;
+	struct tcp_bind_bucket *tb;
+
+	if (snum == 0) {
+		int rover;
+		int low = sysctl_local_port_range[0];
+		int high = sysctl_local_port_range[1];
+		int remaining = (high - low) + 1;
+		struct tcp_tw_bucket *tw = NULL;
+
+		local_bh_disable();
+
+		/* TODO. Actually it is not so bad idea to remove
+		 * tcp_portalloc_lock before next submission to Linus.
+		 * As soon as we touch this place at all it is time to think.
+		 *
+		 * Now it protects single _advisory_ variable tcp_port_rover,
+		 * hence it is mostly useless.
+		 * Code will work nicely if we just delete it, but
+		 * I am afraid in contented case it will work not better or
+		 * even worse: another cpu just will hit the same bucket
+		 * and spin there.
+		 * So some cpu salt could remove both contention and
+		 * memory pingpong. Any ideas how to do this in a nice way?
+		 */
+		spin_lock(&tcp_portalloc_lock);
+		rover = tcp_port_rover;
+
+		do {
+			rover++;
+			if ((rover < low) || (rover > high))
+				rover = low;
+			head = &tcp_bhash[tcp_bhashfn(rover)];
+			spin_lock(&head->lock);		
+
+			/* Does not bother with rcv_saddr checks,
+			 * because the established check is already
+			 * unique enough.
+			 */
+			for (tb = head->chain; tb; tb = tb->next) {
+				if (tb->port == rover) {
+					BUG_TRAP(tb->owners != NULL);
+					if (tb->fastreuse >= 0)
+						goto next_port;
+					if (!__tcp_v4_check_established(sk, rover, &tw))
+						goto ok;
+					goto next_port;
+				}
+			}
+
+			tb = tcp_bucket_create(head, rover);
+			if (!tb) {
+				spin_unlock(&head->lock);
+				break;
+			}
+			tb->fastreuse = -1;
+			goto ok;
+
+		next_port:
+			spin_unlock(&head->lock);
+		} while (--remaining > 0);
+		tcp_port_rover = rover;
+		spin_unlock(&tcp_portalloc_lock);
+
+		local_bh_enable();
 
+		return -EADDRNOTAVAIL;
+
+	ok:
+		/* All locks still held and bhs disabled */
+		tcp_port_rover = rover;
+		spin_unlock(&tcp_portalloc_lock);
+
+		tcp_bind_hash(sk, tb, rover);
+		if (!sk->pprev) {
+			sk->sport = htons(rover);
+			__tcp_v4_hash(sk, 0);
+		}
+		spin_unlock(&head->lock);
+
+		if (tw) {
+			tcp_tw_deschedule(tw);
+			tcp_timewait_kill(tw);
+			tcp_tw_put(tw);
+		}
+
+		local_bh_enable();
+		return 0;
+	}
+
+	head  = &tcp_bhash[tcp_bhashfn(snum)];
+	tb  = (struct tcp_bind_bucket *)sk->prev;
 	spin_lock_bh(&head->lock);
 	if (tb->owners == sk && sk->bind_next == NULL) {
-		__tcp_v4_hash(sk);
+		__tcp_v4_hash(sk, 0);
 		spin_unlock_bh(&head->lock);
 		return 0;
 	} else {
-		spin_unlock_bh(&head->lock);
-
+		int ret;
+		spin_unlock(&head->lock);
 		/* No definite answer... Walk to established hash table */
-		return tcp_v4_check_established(sk);
+		ret = __tcp_v4_check_established(sk, snum, NULL);
+		local_bh_enable();
+		return ret;
 	}
 }
 
@@ -647,7 +752,6 @@
 {
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
 	struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
-	struct sk_buff *buff;
 	struct rtable *rt;
 	u32 daddr, nexthop;
 	int tmp;
@@ -682,12 +786,6 @@
 	if (!sk->protinfo.af_inet.opt || !sk->protinfo.af_inet.opt->srr)
 		daddr = rt->rt_dst;
 
-	err = -ENOBUFS;
-	buff = alloc_skb(MAX_TCP_HEADER + 15, sk->allocation);
-
-	if (buff == NULL)
-		goto failure;
-
 	if (!sk->saddr)
 		sk->saddr = rt->rt_src;
 	sk->rcv_saddr = sk->saddr;
@@ -718,22 +816,36 @@
 	sk->dport = usin->sin_port;
 	sk->daddr = daddr;
 
+	tp->ext_header_len = 0;
+	if (sk->protinfo.af_inet.opt)
+		tp->ext_header_len = sk->protinfo.af_inet.opt->optlen;
+
+	tp->mss_clamp = 536;
+
+	/* Socket identity is still unknown (sport may be zero).
+	 * However we set state to SYN-SENT and not releasing socket
+	 * lock select source port, enter ourselves into the hash tables and
+	 * complete initalization after this.
+	 */
+	tcp_set_state(sk, TCP_SYN_SENT);
+	err = tcp_v4_hash_connect(sk);
+	if (err)
+		goto failure;
+
 	if (!tp->write_seq)
 		tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
 							   sk->sport, usin->sin_port);
 
-	tp->ext_header_len = 0;
-	if (sk->protinfo.af_inet.opt)
-		tp->ext_header_len = sk->protinfo.af_inet.opt->optlen;
 	sk->protinfo.af_inet.id = tp->write_seq^jiffies;
 
-	tp->mss_clamp = 536;
+	err = tcp_connect(sk);
+	if (err)
+		goto failure;
 
-	err = tcp_connect(sk, buff);
-	if (err == 0)
-		return 0;
+	return 0;
 
 failure:
+	tcp_set_state(sk, TCP_CLOSE);
 	__sk_dst_reset(sk);
 	sk->route_caps = 0;
 	sk->dport = 0;
@@ -786,7 +898,6 @@
 	req->expires = jiffies + TCP_TIMEOUT_INIT;
 	req->retrans = 0;
 	req->sk = NULL;
-	req->index = h;
 	req->dl_next = lopt->syn_table[h];
 
 	write_lock(&tp->syn_wait_lock);
@@ -1072,6 +1183,7 @@
 	arg.n_iov = 1;
 	arg.csumoffset = offsetof(struct tcphdr, check) / 2; 
 
+	tcp_socket->sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl;
 	ip_send_reply(tcp_socket->sk, skb, &arg, sizeof rth);
 
 	TCP_INC_STATS_BH(TcpOutSegs);
@@ -1387,7 +1499,6 @@
 			NETDEBUG(if (net_ratelimit()) \
 				printk(KERN_DEBUG "TCP: drop open request from %u.%u.%u.%u/%u\n", \
 					NIPQUAD(saddr), ntohs(skb->h.th->source)));
-			TCP_INC_STATS_BH(TcpAttemptFails);
 			dst_release(dst);
 			goto drop_and_free;
 		}
@@ -1456,7 +1567,7 @@
 	newtp->advmss = dst->advmss;
 	tcp_initialize_rcv_mss(newsk);
 
-	__tcp_v4_hash(newsk);
+	__tcp_v4_hash(newsk, 0);
 	__tcp_inherit_port(sk, newsk);
 
 	return newsk;
@@ -1876,7 +1987,6 @@
 	tcp_v4_rebuild_header,
 	tcp_v4_conn_request,
 	tcp_v4_syn_recv_sock,
-	tcp_v4_hash_connecting,
 	tcp_v4_remember_stamp,
 	sizeof(struct iphdr),
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/tcp_minisocks.c linux/net/ipv4/tcp_minisocks.c
--- linux.orig/net/ipv4/tcp_minisocks.c	2001-10-01 16:19:57.000000000 +0000
+++ linux/net/ipv4/tcp_minisocks.c	2002-07-20 01:08:28.000000000 +0000
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_minisocks.c,v 1.14 2001/09/21 21:27:34 davem Exp $
+ * Version:	$Id: tcp_minisocks.c,v 1.14.2.1 2002/03/05 04:30:08 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -75,17 +75,16 @@
 	/* Disassociate with bind bucket. */
 	bhead = &tcp_bhash[tcp_bhashfn(tw->num)];
 	spin_lock(&bhead->lock);
-	if ((tb = tw->tb) != NULL) {
-		if(tw->bind_next)
-			tw->bind_next->bind_pprev = tw->bind_pprev;
-		*(tw->bind_pprev) = tw->bind_next;
-		tw->tb = NULL;
-		if (tb->owners == NULL) {
-			if (tb->next)
-				tb->next->pprev = tb->pprev;
-			*(tb->pprev) = tb->next;
-			kmem_cache_free(tcp_bucket_cachep, tb);
-		}
+	tb = tw->tb;
+	if(tw->bind_next)
+		tw->bind_next->bind_pprev = tw->bind_pprev;
+	*(tw->bind_pprev) = tw->bind_next;
+	tw->tb = NULL;
+	if (tb->owners == NULL) {
+		if (tb->next)
+			tb->next->pprev = tb->pprev;
+		*(tb->pprev) = tb->next;
+		kmem_cache_free(tcp_bucket_cachep, tb);
 	}
 	spin_unlock(&bhead->lock);
 
@@ -304,9 +303,23 @@
 	struct tcp_bind_hashbucket *bhead;
 	struct sock **head, *sktw;
 
+	/* Step 1: Put TW into bind hash. Original socket stays there too.
+	   Note, that any socket with sk->num!=0 MUST be bound in binding
+	   cache, even if it is closed.
+	 */
+	bhead = &tcp_bhash[tcp_bhashfn(sk->num)];
+	spin_lock(&bhead->lock);
+	tw->tb = (struct tcp_bind_bucket *)sk->prev;
+	BUG_TRAP(sk->prev!=NULL);
+	if ((tw->bind_next = tw->tb->owners) != NULL)
+		tw->tb->owners->bind_pprev = &tw->bind_next;
+	tw->tb->owners = (struct sock*)tw;
+	tw->bind_pprev = &tw->tb->owners;
+	spin_unlock(&bhead->lock);
+
 	write_lock(&ehead->lock);
 
-	/* Step 1: Remove SK from established hash. */
+	/* Step 2: Remove SK from established hash. */
 	if (sk->pprev) {
 		if(sk->next)
 			sk->next->pprev = sk->pprev;
@@ -315,7 +328,7 @@
 		sock_prot_dec_use(sk->prot);
 	}
 
-	/* Step 2: Hash TW into TIMEWAIT half of established hash table. */
+	/* Step 3: Hash TW into TIMEWAIT half of established hash table. */
 	head = &(ehead + tcp_ehash_size)->chain;
 	sktw = (struct sock *)tw;
 	if((sktw->next = *head) != NULL)
@@ -325,20 +338,6 @@
 	atomic_inc(&tw->refcnt);
 
 	write_unlock(&ehead->lock);
-
-	/* Step 3: Put TW into bind hash. Original socket stays there too.
-	   Note, that any socket with sk->num!=0 MUST be bound in binding
-	   cache, even if it is closed.
-	 */
-	bhead = &tcp_bhash[tcp_bhashfn(sk->num)];
-	spin_lock(&bhead->lock);
-	tw->tb = (struct tcp_bind_bucket *)sk->prev;
-	BUG_TRAP(sk->prev!=NULL);
-	if ((tw->bind_next = tw->tb->owners) != NULL)
-		tw->tb->owners->bind_pprev = &tw->bind_next;
-	tw->tb->owners = (struct sock*)tw;
-	tw->bind_pprev = &tw->tb->owners;
-	spin_unlock(&bhead->lock);
 }
 
 /* 
@@ -783,6 +782,8 @@
 			newtp->ack.last_seg_size = skb->len-newtp->tcp_header_len;
 		newtp->mss_clamp = req->mss;
 		TCP_ECN_openreq_child(newtp, req);
+
+		TCP_INC_STATS_BH(TcpPassiveOpens);
 	}
 	return newsk;
 }
@@ -846,8 +847,38 @@
 	/* Further reproduces section "SEGMENT ARRIVES"
 	   for state SYN-RECEIVED of RFC793.
 	   It is broken, however, it does not work only
-	   when SYNs are crossed, which is impossible in our
-	   case.
+	   when SYNs are crossed.
+
+	   You would think that SYN crossing is impossible here, since
+	   we should have a SYN_SENT socket (from connect()) on our end,
+	   but this is not true if the crossed SYNs were sent to both
+	   ends by a malicious third party.  We must defend against this,
+	   and to do that we first verify the ACK (as per RFC793, page
+	   36) and reset if it is invalid.  Is this a true full defense?
+	   To convince ourselves, let us consider a way in which the ACK
+	   test can still pass in this 'malicious crossed SYNs' case.
+	   Malicious sender sends identical SYNs (and thus identical sequence
+	   numbers) to both A and B:
+
+		A: gets SYN, seq=7
+		B: gets SYN, seq=7
+
+	   By our good fortune, both A and B select the same initial
+	   send sequence number of seven :-)
+
+		A: sends SYN|ACK, seq=7, ack_seq=8
+		B: sends SYN|ACK, seq=7, ack_seq=8
+
+	   So we are now A eating this SYN|ACK, ACK test passes.  So
+	   does sequence test, SYN is truncated, and thus we consider
+	   it a bare ACK.
+
+	   If tp->defer_accept, we silently drop this bare ACK.  Otherwise,
+	   we create an established connection.  Both ends (listening sockets)
+	   accept the new incoming connection and try to talk to each other. 8-)
+
+	   Note: This case is both harmless, and rare.  Possibility is about the
+	   same as us discovering intelligent life on another plant tomorrow.
 
 	   But generally, we should (RFC lies!) to accept ACK
 	   from SYNACK both here and in tcp_rcv_state_process().
@@ -859,6 +890,22 @@
 	   before attempt to create socket.
 	 */
 
+	/* RFC793 page 36: "If the connection is in any non-synchronized state ...
+	 *                  and the incoming segment acknowledges something not yet
+	 *                  sent (the segment carries an unaccaptable ACK) ...
+	 *                  a reset is sent."
+	 */
+	if (!(flg & TCP_FLAG_ACK))
+		return NULL;
+
+	/* Invalid ACK: reset will be sent by listening socket */
+	if (TCP_SKB_CB(skb)->ack_seq != req->snt_isn+1)
+		return sk;
+	/* Also, it would be not so bad idea to check rcv_tsecr, which
+	 * is essentially ACK extension and too early or too late values
+	 * should cause reset in unsynchronized states.
+	 */
+
 	/* RFC793: "first check sequence number". */
 
 	if (paws_reject || !tcp_in_window(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
@@ -888,19 +935,6 @@
 	if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN))
 		goto embryonic_reset;
 
-	/* RFC793: "fifth check the ACK field" */
-
-	if (!(flg & TCP_FLAG_ACK))
-		return NULL;
-
-	/* Invalid ACK: reset will be sent by listening socket */
-	if (TCP_SKB_CB(skb)->ack_seq != req->snt_isn+1)
-		return sk;
-	/* Also, it would be not so bad idea to check rcv_tsecr, which
-	 * is essentially ACK extension and too early or too late values
-	 * should cause reset in unsynchronized states.
-	 */
-
 	/* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
 	if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == req->rcv_isn+1) {
 		req->acked = 1;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- linux.orig/net/ipv4/tcp_output.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/ipv4/tcp_output.c	2002-07-20 01:08:26.000000000 +0000
@@ -38,6 +38,7 @@
 
 #include <net/tcp.h>
 
+#include <linux/compiler.h>
 #include <linux/smp_lock.h>
 
 /* People can turn this off for buggy TCP's found in printers etc. */
@@ -1157,14 +1158,14 @@
 	return skb;
 }
 
-int tcp_connect(struct sock *sk, struct sk_buff *buff)
+/* 
+ * Do all connect socket setups that can be done AF independent.
+ */ 
+static inline void tcp_connect_init(struct sock *sk)
 {
 	struct dst_entry *dst = __sk_dst_get(sk);
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
 
-	/* Reserve space for headers. */
-	skb_reserve(buff, MAX_TCP_HEADER);
-
 	/* We'll fix this up when we get a response from the other end.
 	 * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
 	 */
@@ -1191,14 +1192,6 @@
 
 	tp->rcv_ssthresh = tp->rcv_wnd;
 
-	/* Socket identity change complete, no longer
-	 * in TCP_CLOSE, so enter ourselves into the
-	 * hash tables.
-	 */
-	tcp_set_state(sk,TCP_SYN_SENT);
-	if (tp->af_specific->hash_connecting(sk))
-		goto err_out;
-
 	sk->err = 0;
 	sk->done = 0;
 	tp->snd_wnd = 0;
@@ -1212,6 +1205,24 @@
 	tp->rto = TCP_TIMEOUT_INIT;
 	tp->retransmits = 0;
 	tcp_clear_retrans(tp);
+}
+
+/*
+ * Build a SYN and send it off.
+ */ 
+int tcp_connect(struct sock *sk)
+{
+	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+	struct sk_buff *buff;
+
+	tcp_connect_init(sk);
+
+	buff = alloc_skb(MAX_TCP_HEADER + 15, sk->allocation);
+	if (unlikely(buff == NULL))
+		return -ENOBUFS;
+
+	/* Reserve space for headers. */
+	skb_reserve(buff, MAX_TCP_HEADER);
 
 	TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN;
 	TCP_ECN_send_syn(tp, buff);
@@ -1234,11 +1245,6 @@
 	/* Timer for repeating the SYN until an answer. */
 	tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
 	return 0;
-
-err_out:
-	tcp_set_state(sk,TCP_CLOSE);
-	kfree_skb(buff);
-	return -EADDRNOTAVAIL;
 }
 
 /* Send out a delayed ack, the caller does the policy checking
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/udp.c linux/net/ipv4/udp.c
--- linux.orig/net/ipv4/udp.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv4/udp.c	2002-07-20 01:08:27.000000000 +0000
@@ -5,7 +5,7 @@
  *
  *		The User Datagram Protocol (UDP).
  *
- * Version:	$Id: udp.c,v 1.100.2.1 2002/01/12 07:39:23 davem Exp $
+ * Version:	$Id: udp.c,v 1.100.2.4 2002/03/05 12:47:34 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -712,6 +712,8 @@
 {
 	struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
 	struct rtable *rt;
+	u32 saddr;
+	int oif;
 	int err;
 
 	
@@ -723,8 +725,16 @@
 
 	sk_dst_reset(sk);
 
-	err = ip_route_connect(&rt, usin->sin_addr.s_addr, sk->saddr,
-			       RT_CONN_FLAGS(sk), sk->bound_dev_if);
+	oif = sk->bound_dev_if;
+	saddr = sk->saddr;
+	if (MULTICAST(usin->sin_addr.s_addr)) {
+		if (!oif)
+			oif = sk->protinfo.af_inet.mc_index;
+		if (!saddr)
+			saddr = sk->protinfo.af_inet.mc_addr;
+	}
+	err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr,
+			       RT_CONN_FLAGS(sk), oif);
 	if (err)
 		return err;
 	if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) {
@@ -889,7 +899,9 @@
 	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
 		goto no_header;
 
-	ulen = ntohs(skb->h.uh->len);
+  	uh = skb->h.uh;
+
+	ulen = ntohs(uh->len);
 
 	if (ulen > len || ulen < sizeof(*uh))
 		goto short_packet;
@@ -897,8 +909,6 @@
 	if (pskb_trim(skb, ulen))
 		goto short_packet;
 
-  	uh = skb->h.uh;
-
 	if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
 		goto csum_error;
 
@@ -928,7 +938,14 @@
 	return(0);
 
 short_packet:
-	NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "UDP: short packet: %d/%d\n", ulen, len));
+	NETDEBUG(if (net_ratelimit())
+		 printk(KERN_DEBUG "UDP: short packet: %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",
+			NIPQUAD(saddr),
+			ntohs(uh->source),
+			ulen,
+			len,
+			NIPQUAD(daddr),
+			ntohs(uh->dest)));
 no_header:
 	UDP_INC_STATS_BH(UdpInErrors);
 	kfree_skb(skb);
@@ -961,7 +978,7 @@
 	destp = ntohs(sp->dport);
 	srcp  = ntohs(sp->sport);
 	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
-		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
+		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
 		i, src, srcp, dest, destp, sp->state, 
 		atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
 		0, 0L, 0,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv4/utils.c linux/net/ipv4/utils.c
--- linux.orig/net/ipv4/utils.c	2000-10-10 17:33:52.000000000 +0000
+++ linux/net/ipv4/utils.c	2002-07-20 01:08:36.000000000 +0000
@@ -43,21 +43,6 @@
 
 
 /*
- *	Display an IP address in readable format. 
- */
- 
-char *in_ntoa(__u32 in)
-{
-	static char buff[18];
-	char *p;
-
-	p = (char *) &in;
-	sprintf(buff, "%d.%d.%d.%d",
-		(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
-	return(buff);
-}
-
-/*
  *	Convert an ASCII string to binary IP. 
  */
  
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/addrconf.c linux/net/ipv6/addrconf.c
--- linux.orig/net/ipv6/addrconf.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/ipv6/addrconf.c	2002-07-20 01:08:33.000000000 +0000
@@ -62,6 +62,8 @@
 
 #include <asm/uaccess.h>
 
+#define IPV6_MAX_ADDRESSES 16
+
 /* Set to 3 to get tracing... */
 #define ACONF_DEBUG 2
 
@@ -586,6 +588,18 @@
 	return err;
 }
 
+int ipv6_count_addresses(struct inet6_dev *idev)
+{
+	int cnt = 0;
+	struct inet6_ifaddr *ifp;
+
+	read_lock_bh(&idev->lock);
+	for (ifp=idev->addr_list; ifp; ifp=ifp->if_next)
+		cnt++;
+	read_unlock_bh(&idev->lock);
+	return cnt;
+}
+
 int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev)
 {
 	struct inet6_ifaddr * ifp;
@@ -895,8 +909,12 @@
 		ifp = ipv6_get_ifaddr(&addr, dev);
 
 		if (ifp == NULL && valid_lft) {
-			ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len,
-					    addr_type&IPV6_ADDR_SCOPE_MASK, 0);
+			/* Do not allow to create too much of autoconfigured
+			 * addresses; this would be too easy way to crash kernel.
+			 */
+			if (ipv6_count_addresses(in6_dev) < IPV6_MAX_ADDRESSES)
+				ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len,
+						    addr_type&IPV6_ADDR_SCOPE_MASK, 0);
 
 			if (ifp == NULL) {
 				in6_dev_put(in6_dev);
@@ -1815,7 +1833,7 @@
 		break;
 	case RTM_DELADDR:
 		addrconf_leave_solict(ifp->idev->dev, &ifp->addr);
-		if (!ipv6_chk_addr(&ifp->addr, ifp->idev->dev))
+		if (!ipv6_chk_addr(&ifp->addr, NULL))
 			ip6_rt_addr_del(&ifp->addr, ifp->idev->dev);
 		break;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/ndisc.c linux/net/ipv6/ndisc.c
--- linux.orig/net/ipv6/ndisc.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv6/ndisc.c	2002-07-20 01:08:23.000000000 +0000
@@ -356,7 +356,7 @@
 	ipv6_addr_copy(&msg->target, solicited_addr);
 
 	if (inc_opt)
-		ndisc_fill_option((void*)&msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
+		ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
 
 	/* checksum */
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(solicited_addr, daddr, len, 
@@ -417,7 +417,7 @@
 	ipv6_addr_copy(&msg->target, solicit);
 
 	if (send_llinfo)
-		ndisc_fill_option((void*)&msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
+		ndisc_fill_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
 
 	/* checksum */
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
@@ -567,6 +567,11 @@
 			printk(KERN_WARNING "ICMP RA: source address is not linklocal\n");
 		return;
 	}
+	if (optlen < 0) {
+		if (net_ratelimit())
+			printk(KERN_WARNING "ICMP RA: packet too short\n");
+		return;
+	}
 
 	/*
 	 *	set the RA_RECV flag in the interface
@@ -923,7 +928,7 @@
 	u8 *opt;
 
 	opt = skb->h.raw;
-	opt += sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
+	opt += sizeof(struct nd_msg);
 	opt = ndisc_find_option(opt, skb->dev->addr_len+2, skb->tail - opt, ND_OPT_SOURCE_LL_ADDR);
 
 	return neigh_event_ns(&nd_tbl, opt, saddr, skb->dev);
@@ -931,12 +936,11 @@
 
 static __inline__ int ndisc_recv_na(struct neighbour *neigh, struct sk_buff *skb)
 {
-	struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
 	u8 *opt;
+	struct nd_msg *msg = (struct nd_msg*) skb->h.raw;
 
-	opt = skb->h.raw;
-	opt += sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
-	opt = ndisc_find_option(opt, skb->dev->addr_len+2, skb->tail - opt, ND_OPT_TARGET_LL_ADDR);
+	opt = ndisc_find_option(msg->opt, skb->dev->addr_len+2,
+				skb->tail - msg->opt, ND_OPT_TARGET_LL_ADDR);
 
 	return neigh_update(neigh, opt,
 			    msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
@@ -957,7 +961,6 @@
 	struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
 	struct neighbour *neigh;
 	struct inet6_ifaddr *ifp;
-	unsigned int payload_len;
 
 	__skb_push(skb, skb->data-skb->h.raw);
 
@@ -980,11 +983,9 @@
 	 *	(Some checking in ndisc_find_option)
 	 */
 
-	payload_len = ntohs(skb->nh.ipv6h->payload_len);
 	switch (msg->icmph.icmp6_type) {
 	case NDISC_NEIGHBOUR_SOLICITATION:
-		/* XXX: import nd_neighbor_solicit from glibc netinet/icmp6.h */
-		if (payload_len < 8+16) {
+		if (skb->len < sizeof(struct nd_msg)) {
 			if (net_ratelimit())
 				printk(KERN_WARNING "ICMP NS: packet too short\n");
 			return 0;
@@ -1064,12 +1065,13 @@
 
 				neigh = ndisc_recv_ns(saddr, skb);
 
-				if (neigh) {
+				if (neigh || !dev->hard_header) {
 					ndisc_send_na(dev, neigh, saddr, &ifp->addr, 
 						      ifp->idev->cnf.forwarding, 1, 
 						      ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, 
 						      1);
-					neigh_release(neigh);
+					if (neigh)
+						neigh_release(neigh);
 				}
 			}
 			in6_ifa_put(ifp);
@@ -1113,8 +1115,7 @@
 		return 0;
 
 	case NDISC_NEIGHBOUR_ADVERTISEMENT:
-		/* XXX: import nd_neighbor_advert from glibc netinet/icmp6.h */
-		if (payload_len < 16+8 ) {
+		if (skb->len < sizeof(struct nd_msg)) {
 			if (net_ratelimit())
 				printk(KERN_WARNING "ICMP NA: packet too short\n");
 			return 0;
@@ -1175,35 +1176,12 @@
 		break;
 
 	case NDISC_ROUTER_ADVERTISEMENT:
-		/* XXX: import nd_router_advert from glibc netinet/icmp6.h */
-		if (payload_len < 8+4+4) {
-			if (net_ratelimit())
-				printk(KERN_WARNING "ICMP RA: packet too short\n");
-			return 0;
-		}
 		ndisc_router_discovery(skb);
 		break;
 
 	case NDISC_REDIRECT:
-		/* XXX: import nd_redirect from glibc netinet/icmp6.h */
-		if (payload_len < 8+16+16) {
-			if (net_ratelimit())
-				printk(KERN_WARNING "ICMP redirect: packet too short\n");
-			return 0;
-		}
 		ndisc_redirect_rcv(skb);
 		break;
-
-	case NDISC_ROUTER_SOLICITATION:
-		/* No RS support in the kernel, but we do some required checks */
-
-		/* XXX: import nd_router_solicit from glibc netinet/icmp6.h */
-		if (payload_len < 8) {
-			if (net_ratelimit())
-				printk(KERN_WARNING "ICMP RS: packet too short\n");
-			return 0;
-		}
-		break;
 	};
 
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/netfilter/ip6_queue.c linux/net/ipv6/netfilter/ip6_queue.c
--- linux.orig/net/ipv6/netfilter/ip6_queue.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv6/netfilter/ip6_queue.c	2002-07-20 01:08:31.000000000 +0000
@@ -518,7 +518,7 @@
 	return netlink_unicast(nfnl, skb, nlq6->peer.pid, MSG_DONTWAIT);
 }
 
-#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0);
+#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
 
 static __inline__ void netlink_receive_user_skb(struct sk_buff *skb)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/netfilter/ip6_tables.c linux/net/ipv6/netfilter/ip6_tables.c
--- linux.orig/net/ipv6/netfilter/ip6_tables.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv6/netfilter/ip6_tables.c	2002-07-20 01:08:32.000000000 +0000
@@ -110,7 +110,7 @@
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
 #ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*cpu_number_map(p))
+#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
 #else
 #define TABLE_OFFSET(t,p) 0
 #endif
@@ -336,7 +336,8 @@
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private, smp_processor_id());
+		+ TABLE_OFFSET(table->private, 
+				cpu_number_map(smp_processor_id()));
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -426,7 +427,7 @@
 #endif
 				/* Target might have changed stuff. */
 				ipv6 = (*pskb)->nh.ipv6h;
-				protohdr = (u_int32_t *)ipv6 + IPV6_HDR_LEN;
+				protohdr = (u_int32_t *)((void *)ipv6 + IPV6_HDR_LEN);
 				datalen = (*pskb)->len - IPV6_HDR_LEN;
 
 				if (verdict == IP6T_CONTINUE)
@@ -913,7 +914,7 @@
 
 	/* And one copy for every other CPU */
 	for (i = 1; i < smp_num_cpus; i++) {
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size*i),
+		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
 		       newinfo->entries,
 		       SMP_ALIGN(newinfo->size));
 	}
@@ -1795,9 +1796,15 @@
 	}
 
 #ifdef CONFIG_PROC_FS
-	if (!proc_net_create("ip6_tables_names", 0, ip6t_get_tables)) {
-		nf_unregister_sockopt(&ip6t_sockopts);
-		return -ENOMEM;
+	{
+		struct proc_dir_entry *proc;
+		proc = proc_net_create("ip6_tables_names", 0,
+					ip6t_get_tables);
+		if (!proc) {
+			nf_unregister_sockopt(&ip6t_sockopts);
+			return -ENOMEM;
+		}
+		proc->owner = THIS_MODULE;
 	}
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/netfilter/ip6t_mac.c linux/net/ipv6/netfilter/ip6t_mac.c
--- linux.orig/net/ipv6/netfilter/ip6t_mac.c	2001-10-30 23:08:12.000000000 +0000
+++ linux/net/ipv6/netfilter/ip6t_mac.c	2002-07-20 01:08:39.000000000 +0000
@@ -34,8 +34,10 @@
 		   unsigned int hook_mask)
 {
 	if (hook_mask
-	    & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN))) {
-		printk("ip6t_mac: only valid for PRE_ROUTING or LOCAL_IN.\n");
+	    & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN)
+		| (1 << NF_IP6_FORWARD))) {
+		printk("ip6t_mac: only valid for PRE_ROUTING, LOCAL_IN or"
+		       " FORWARD\n");
 		return 0;
 	}
 
@@ -60,3 +62,5 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MAC address matching module for IPv6");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/raw.c linux/net/ipv6/raw.c
--- linux.orig/net/ipv6/raw.c	2001-09-20 21:12:56.000000000 +0000
+++ linux/net/ipv6/raw.c	2002-07-20 01:08:33.000000000 +0000
@@ -7,10 +7,11 @@
  *
  *	Adapted from linux/net/ipv4/raw.c
  *
- *	$Id: raw.c,v 1.50 2001/09/18 22:29:10 davem Exp $
+ *	$Id: raw.c,v 1.50.2.1 2002/03/05 12:47:34 davem Exp $
  *
  *	Fixes:
  *	Hideaki YOSHIFUJI	:	sin6_scope_id support
+ *	YOSHIFUJI,H.@USAGI	:	raw checksum (RFC2292(bis) compliance) 
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -278,6 +279,16 @@
 
 static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
 {
+#if defined(CONFIG_FILTER)
+	if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
+		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
+			IP6_INC_STATS_BH(Ip6InDiscards);
+			kfree_skb(skb);
+			return 0;
+		}
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
+#endif
 	/* Charge it to the socket. */
 	if (sock_queue_rcv_skb(sk,skb)<0) {
 		IP6_INC_STATS_BH(Ip6InDiscards);
@@ -298,9 +309,33 @@
  */
 int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
 {
+	if (!sk->tp_pinfo.tp_raw.checksum)
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
+		if (skb->ip_summed == CHECKSUM_HW) {
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+			if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+					    &skb->nh.ipv6h->daddr,
+					    skb->len, sk->num, skb->csum)) {
+				NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "raw v6 hw csum failure.\n"));
+				skb->ip_summed = CHECKSUM_NONE;
+			}
+		}
+		if (skb->ip_summed == CHECKSUM_NONE)
+			skb->csum = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+						     &skb->nh.ipv6h->daddr,
+						     skb->len, sk->num, 0);
+	}
+
 	if (sk->protinfo.af_inet.hdrincl) {
-		__skb_push(skb, skb->nh.raw - skb->data);
-		skb->h.raw = skb->nh.raw;
+		if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
+		    (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
+			IP6_INC_STATS_BH(Ip6InDiscards);
+			kfree_skb(skb);
+			return 0;
+		}
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
 
 	rawv6_rcv_skb(sk, skb);
@@ -339,7 +374,17 @@
   		msg->msg_flags |= MSG_TRUNC;
   	}
 
-	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
+		err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	} else if (msg->msg_flags&MSG_TRUNC) {
+		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
+			goto csum_copy_err;
+		err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	} else {
+		err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov);
+		if (err == -EINVAL)
+			goto csum_copy_err;
+	}
 	if (err)
 		goto out_free;
 
@@ -366,6 +411,27 @@
 	skb_free_datagram(sk, skb);
 out:
 	return err;
+
+csum_copy_err:
+	/* Clear queue. */
+	if (flags&MSG_PEEK) {
+		int clear = 0;
+		spin_lock_irq(&sk->receive_queue.lock);
+		if (skb == skb_peek(&sk->receive_queue)) {
+			__skb_unlink(skb, &sk->receive_queue);
+			clear = 1;
+		}
+		spin_unlock_irq(&sk->receive_queue.lock);
+		if (clear)
+			kfree_skb(skb);
+	}
+
+	/* Error for blocking case is chosen to masquerade
+	   as some normal condition.
+	 */
+	err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
+	IP6_INC_STATS_USER(Ip6InDiscards);
+	goto out_free;
 }
 
 /*
@@ -415,11 +481,18 @@
 		hdr->cksum = csum_ipv6_magic(addr, daddr, hdr->len,
 					     hdr->proto, hdr->cksum);
 		
-		if (opt->offset < len) {
+		if (opt->offset + 1 < len) {
 			__u16 *csum;
 
 			csum = (__u16 *) (buff + opt->offset);
-			*csum = hdr->cksum;
+			if (*csum) {
+				/* in case cksum was not initialized */
+				__u32 sum = hdr->cksum;
+				sum += *csum;
+				*csum = hdr->cksum = (sum + (sum>>16));
+			} else {
+				*csum = hdr->cksum;
+			}
 		} else {
 			if (net_ratelimit())
 				printk(KERN_DEBUG "icmp: cksum offset too big\n");
@@ -647,6 +720,10 @@
 
 	switch (optname) {
 		case IPV6_CHECKSUM:
+			/* You may get strange result with a positive odd offset;
+			   RFC2292bis agrees with me. */
+			if (val > 0 && (val&1))
+				return(-EINVAL);
 			if (val < 0) {
 				opt->checksum = 0;
 			} else {
@@ -744,6 +821,11 @@
 
 static int rawv6_init_sk(struct sock *sk)
 {
+	if (sk->num == IPPROTO_ICMPV6){
+		struct raw6_opt *opt = &sk->tp_pinfo.tp_raw;
+		opt->checksum = 1;
+		opt->offset = 2;
+	}
 	return(0);
 }
 
@@ -761,7 +843,7 @@
 	srcp  = sp->num;
 	sprintf(tmpbuf,
 		"%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
-		"%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
+		"%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
 		i,
 		src->s6_addr32[0], src->s6_addr32[1],
 		src->s6_addr32[2], src->s6_addr32[3], srcp,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/sit.c linux/net/ipv6/sit.c
--- linux.orig/net/ipv6/sit.c	2001-10-01 16:19:56.000000000 +0000
+++ linux/net/ipv6/sit.c	2002-07-20 01:08:40.000000000 +0000
@@ -64,7 +64,8 @@
 static int ipip6_tunnel_init(struct net_device *dev);
 
 static struct net_device ipip6_fb_tunnel_dev = {
-	"sit0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, ipip6_fb_tunnel_init,
+	name: 		"sit0", 
+	init:		ipip6_fb_tunnel_init,
 };
 
 static struct ip_tunnel ipip6_fb_tunnel = {
@@ -517,7 +518,11 @@
 		goto tx_error;
 	}
 
-	mtu = rt->u.dst.pmtu - sizeof(struct iphdr);
+	if (tiph->frag_off)
+		mtu = rt->u.dst.pmtu - sizeof(struct iphdr);
+	else
+		mtu = skb->dst ? skb->dst->pmtu : dev->mtu;
+
 	if (mtu < 68) {
 		tunnel->stat.collisions++;
 		ip_rt_put(rt);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- linux.orig/net/ipv6/tcp_ipv6.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/ipv6/tcp_ipv6.c	2002-07-20 01:08:22.000000000 +0000
@@ -133,7 +133,7 @@
 				break;
 	}
 	if (tb != NULL && tb->owners != NULL) {
-		if (tb->fastreuse != 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
+		if (tb->fastreuse > 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
 			goto success;
 		} else {
 			struct sock *sk2 = tb->owners;
@@ -366,22 +366,22 @@
 }
 
 static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
-					      struct ipv6hdr *ip6h,
-					      struct tcphdr *th,
-					      int iif,
-					      struct open_request ***prevp)
+					      struct open_request ***prevp,
+					      __u16 rport,
+					      struct in6_addr *raddr,
+					      struct in6_addr *laddr,
+					      int iif)
 {
 	struct tcp_listen_opt *lopt = tp->listen_opt;
 	struct open_request *req, **prev;  
-	__u16 rport = th->source;
 
-	for (prev = &lopt->syn_table[tcp_v6_synq_hash(&ip6h->saddr, rport)];
+	for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport)];
 	     (req = *prev) != NULL;
 	     prev = &req->dl_next) {
 		if (req->rmt_port == rport &&
 		    req->class->family == AF_INET6 &&
-		    !ipv6_addr_cmp(&req->af.v6_req.rmt_addr, &ip6h->saddr) &&
-		    !ipv6_addr_cmp(&req->af.v6_req.loc_addr, &ip6h->daddr) &&
+		    !ipv6_addr_cmp(&req->af.v6_req.rmt_addr, raddr) &&
+		    !ipv6_addr_cmp(&req->af.v6_req.loc_addr, laddr) &&
 		    (!req->af.v6_req.iif || req->af.v6_req.iif == iif)) {
 			BUG_TRAP(req->sk == NULL);
 			*prevp = prev;
@@ -486,11 +486,21 @@
 	return -EADDRNOTAVAIL;
 }
 
-static int tcp_v6_hash_connecting(struct sock *sk)
+static int tcp_v6_hash_connect(struct sock *sk)
 {
-	unsigned short snum = sk->num;
-	struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(snum)];
-	struct tcp_bind_bucket *tb = head->chain;
+	struct tcp_bind_hashbucket *head;
+	struct tcp_bind_bucket *tb;
+
+	/* XXX */ 
+	if (sk->num == 0) { 
+		int err = tcp_v6_get_port(sk, sk->num);
+		if (err)
+			return err;
+		sk->sport = htons(sk->num); 	
+	}
+
+	head = &tcp_bhash[tcp_bhashfn(sk->num)];
+	tb = head->chain;
 
 	spin_lock_bh(&head->lock);
 
@@ -520,7 +530,6 @@
 	struct in6_addr saddr_buf;
 	struct flowi fl;
 	struct dst_entry *dst;
-	struct sk_buff *buff;
 	int addr_type;
 	int err;
 
@@ -660,27 +669,25 @@
 		tp->ext_header_len = np->opt->opt_flen+np->opt->opt_nflen;
 	tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
-	err = -ENOBUFS;
-	buff = alloc_skb(MAX_TCP_HEADER + 15, sk->allocation);
-
-	if (buff == NULL)
-		goto failure;
-
 	sk->dport = usin->sin6_port;
 
-	/*
-	 *	Init variables
-	 */
+	tcp_set_state(sk, TCP_SYN_SENT); 
+	err = tcp_v6_hash_connect(sk); 
+	if (err)
+		goto late_failure;
 
 	if (!tp->write_seq)
 		tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
 							     np->daddr.s6_addr32,
 							     sk->sport, sk->dport);
+	err = tcp_connect(sk);
+	if (err)
+		goto late_failure;
 
-	err = tcp_connect(sk, buff);
-	if (err == 0)
-		return 0;
+	return 0;
 
+late_failure:
+	tcp_set_state(sk, TCP_CLOSE); 
 failure:
 	__sk_dst_reset(sk);
 	sk->dport = 0;
@@ -692,8 +699,6 @@
 		int type, int code, int offset, __u32 info)
 {
 	struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
-	struct in6_addr *saddr = &hdr->saddr;
-	struct in6_addr *daddr = &hdr->daddr;
 	struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
 	struct ipv6_pinfo *np;
 	struct sock *sk;
@@ -701,7 +706,7 @@
 	struct tcp_opt *tp; 
 	__u32 seq;
 
-	sk = tcp_v6_lookup(daddr, th->dest, saddr, th->source, skb->dev->ifindex);
+	sk = tcp_v6_lookup(&hdr->daddr, th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
 
 	if (sk == NULL) {
 		ICMP6_INC_STATS_BH(Icmp6InErrors);
@@ -773,15 +778,12 @@
 	/* Might be for an open_request */
 	switch (sk->state) {
 		struct open_request *req, **prev;
-		struct ipv6hdr hd;
 	case TCP_LISTEN:
 		if (sk->lock.users)
 			goto out;
 
-		/* Grrrr - fix this later. */
-		ipv6_addr_copy(&hd.saddr, saddr);
-		ipv6_addr_copy(&hd.daddr, daddr); 
-		req = tcp_v6_search_req(tp, &hd, th, tcp_v6_iif(skb), &prev);
+		req = tcp_v6_search_req(tp, &prev, th->dest, &hdr->daddr,
+					&hdr->saddr, tcp_v6_iif(skb));
 		if (!req)
 			goto out;
 
@@ -1088,7 +1090,8 @@
 	struct sock *nsk;
 
 	/* Find possible connection requests. */
-	req = tcp_v6_search_req(tp, skb->nh.ipv6h, th, tcp_v6_iif(skb), &prev);
+	req = tcp_v6_search_req(tp, &prev, th->source, &skb->nh.ipv6h->saddr,
+				&skb->nh.ipv6h->daddr, tcp_v6_iif(skb));
 	if (req)
 		return tcp_check_req(sk, skb, req, prev);
 
@@ -1123,7 +1126,6 @@
 	req->sk = NULL;
 	req->expires = jiffies + TCP_TIMEOUT_INIT;
 	req->retrans = 0;
-	req->index = h;
 	req->dl_next = lopt->syn_table[h];
 
 	write_lock(&tp->syn_wait_lock);
@@ -1762,7 +1764,6 @@
 	tcp_v6_rebuild_header,
 	tcp_v6_conn_request,
 	tcp_v6_syn_recv_sock,
-	tcp_v6_hash_connecting,
 	tcp_v6_remember_stamp,
 	sizeof(struct ipv6hdr),
 
@@ -1782,7 +1783,6 @@
 	tcp_v4_rebuild_header,
 	tcp_v6_conn_request,
 	tcp_v6_syn_recv_sock,
-	tcp_v4_hash_connecting,
 	tcp_v4_remember_stamp,
 	sizeof(struct iphdr),
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/ipv6/udp.c linux/net/ipv6/udp.c
--- linux.orig/net/ipv6/udp.c	2001-09-07 18:01:21.000000000 +0000
+++ linux/net/ipv6/udp.c	2002-07-20 01:08:30.000000000 +0000
@@ -7,7 +7,7 @@
  *
  *	Based on linux/ipv4/udp.c
  *
- *	$Id: udp.c,v 1.64 2001/09/01 00:31:50 davem Exp $
+ *	$Id: udp.c,v 1.64.2.1 2002/03/05 12:47:34 davem Exp $
  *
  *	Fixes:
  *	Hideaki YOSHIFUJI	:	sin6_scope_id support
@@ -292,6 +292,8 @@
 				return -EINVAL;
 			}
 			sk->bound_dev_if = usin->sin6_scope_id;
+			if (!sk->bound_dev_if && (addr_type&IPV6_ADDR_MULTICAST))
+				fl.oif = np->mcast_oif;
 		}
 
 		/* Connect to link-local address requires an interface */
@@ -316,6 +318,9 @@
 	fl.uli_u.ports.dport = sk->dport;
 	fl.uli_u.ports.sport = sk->sport;
 
+	if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST))
+		fl.oif = np->mcast_oif;
+
 	if (flowlabel) {
 		if (flowlabel->opt && flowlabel->opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
@@ -498,7 +503,7 @@
 {
 #if defined(CONFIG_FILTER)
 	if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
-		if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
+		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
 			UDP6_INC_STATS_BH(UdpInErrors);
 			IP6_INC_STATS_BH(Ip6InDiscards);
 			kfree_skb(skb);
@@ -916,7 +921,7 @@
 	srcp  = ntohs(sp->sport);
 	sprintf(tmpbuf,
 		"%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
-		"%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
+		"%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
 		i,
 		src->s6_addr32[0], src->s6_addr32[1],
 		src->s6_addr32[2], src->s6_addr32[3], srcp,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/irda/af_irda.c linux/net/irda/af_irda.c
--- linux.orig/net/irda/af_irda.c	2001-12-21 17:42:05.000000000 +0000
+++ linux/net/irda/af_irda.c	2002-07-20 01:08:31.000000000 +0000
@@ -1025,29 +1025,27 @@
 	/* Now the loop */
 	if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
 		return -EINPROGRESS;
-		
-	cli();	/* To avoid races on the sleep */
-	
-	/* A Connect Ack with Choke or timeout or failed routing will go to
-	 * closed.  */
+
+	/* Here, there is a race condition : the state may change between
+	 * our test and the sleep, via irda_connect_confirm().
+	 * The way to workaround that is to sleep with a timeout, so that
+	 * we don't sleep forever and check the state when waking up.
+	 * 50ms is plenty good enough, because the LAP is already connected.
+	 * Jean II */
 	while (sk->state == TCP_SYN_SENT) {
-		interruptible_sleep_on(sk->sleep);
+		interruptible_sleep_on_timeout(sk->sleep, HZ/20);
 		if (signal_pending(current)) {
-			sti();
 			return -ERESTARTSYS;
 		}
 	}
 	
 	if (sk->state != TCP_ESTABLISHED) {
-		sti();
 		sock->state = SS_UNCONNECTED;
 		return sock_error(sk);	/* Always set at this point */
 	}
 	
 	sock->state = SS_CONNECTED;
 	
-	sti();
-	
 	/* At this point, IrLMP has assigned our source address */
 	self->saddr = irttp_get_saddr(self->tsap);
 
@@ -1710,7 +1708,7 @@
 
 		if (sk->state == TCP_ESTABLISHED) {
 			if ((self->tx_flow == FLOW_START) && 
-			    (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE))
+			    sock_writeable(sk))
 			{
 				mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
 			}
@@ -1718,13 +1716,13 @@
 		break;
 	case SOCK_SEQPACKET:
 		if ((self->tx_flow == FLOW_START) && 
-		    (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE))
+		    sock_writeable(sk))
 		{	
 			mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
 		}
 		break;
 	case SOCK_DGRAM:
-		if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE)
+		if (sock_writeable(sk))
 			mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
 		break;
 	default:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/irda/irlap.c linux/net/irda/irlap.c
--- linux.orig/net/irda/irlap.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/irda/irlap.c	2002-07-20 01:08:33.000000000 +0000
@@ -131,7 +131,7 @@
 	/* FIXME: should we get our own field? */
 	dev->atalk_ptr = self;
 
-	irlap_next_state(self, LAP_OFFLINE);
+	self->state = LAP_OFFLINE;
 
 	/* Initialize transmit queue */
 	skb_queue_head_init(&self->txq);
@@ -155,7 +155,7 @@
 
 	self->N3 = 3; /* # connections attemts to try before giving up */
 	
-	irlap_next_state(self, LAP_NDM);
+	self->state = LAP_NDM;
 
 	hashbin_insert(irlap, (irda_queue_t *) self, self->saddr, NULL);
 
@@ -346,25 +346,21 @@
 	else
 		skb->data[1] = I_FRAME;
 
+	/* Add at the end of the queue (keep ordering) - Jean II */
+	skb_queue_tail(&self->txq, skb);
+
 	/* 
 	 *  Send event if this frame only if we are in the right state 
 	 *  FIXME: udata should be sent first! (skb_queue_head?)
 	 */
   	if ((self->state == LAP_XMIT_P) || (self->state == LAP_XMIT_S)) {
-		/*
-		 *  Check if the transmit queue contains some unsent frames,
-		 *  and if so, make sure they are sent first
-		 */
-		if (!skb_queue_empty(&self->txq)) {
-			skb_queue_tail(&self->txq, skb);
-			skb = skb_dequeue(&self->txq);
-			
-			ASSERT(skb != NULL, return;);
-		}
-		irlap_do_event(self, SEND_I_CMD, skb, NULL);
-		kfree_skb(skb);
-	} else
-		skb_queue_tail(&self->txq, skb);
+		/* If we are not already processing the Tx queue, trigger
+		 * transmission immediately - Jean II */
+		if((skb_queue_len(&self->txq) <= 1) && (!self->local_busy))
+			irlap_do_event(self, DATA_REQUEST, skb, NULL);
+		/* Otherwise, the packets will be sent normally at the
+		 * next pf-poll - Jean II */
+	}
 }
 
 /*
@@ -1013,6 +1009,7 @@
 	self->window_size = self->qos_tx.window_size.value;
 	self->window      = self->qos_tx.window_size.value;
 
+#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
 	/*
 	 *  Calculate how many bytes it is possible to transmit before the
 	 *  link must be turned around
@@ -1020,6 +1017,8 @@
 	self->line_capacity = 
 		irlap_max_line_capacity(self->qos_tx.baud_rate.value,
 					self->qos_tx.max_turn_time.value);
+	self->bytes_left = self->line_capacity;
+#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
 
 	
 	/* 
@@ -1082,24 +1081,6 @@
 	IRDA_DEBUG(4, "Setting N2 = %d\n", self->N2);
 }
 
-/*
- * Function irlap_set_local_busy (self, status)
- *
- *    
- *
- */
-void irlap_set_local_busy(struct irlap_cb *self, int status)
-{
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
-	self->local_busy = status;
-	
-	if (status)
-		IRDA_DEBUG(0, __FUNCTION__ "(), local busy ON\n");
-	else
-		IRDA_DEBUG(0, __FUNCTION__ "(), local busy OFF\n");
-}
-
 #ifdef CONFIG_PROC_FS
 /*
  * Function irlap_proc_read (buf, start, offset, len, unused)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/irda/irlap_event.c linux/net/irda/irlap_event.c
--- linux.orig/net/irda/irlap_event.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/irda/irlap_event.c	2002-07-20 01:08:24.000000000 +0000
@@ -252,6 +252,9 @@
 		 * that will change the state away form XMIT
 		 */
 		if (skb_queue_len(&self->txq)) {
+			/* Prevent race conditions with irlap_data_request() */
+			self->local_busy = TRUE;
+
 			/* Try to send away all queued data frames */
 			while ((skb = skb_dequeue(&self->txq)) != NULL) {
 				ret = (*state[self->state])(self, SEND_I_CMD,
@@ -260,6 +263,8 @@
 				if (ret == -EPROTO)
 					break; /* Try again later! */
 			}
+			/* Finished transmitting */
+			self->local_busy = FALSE;
 		} else if (self->disconnect_pending) {
 			self->disconnect_pending = FALSE;
 			
@@ -282,25 +287,15 @@
  *    Switches state and provides debug information
  *
  */
-void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state) 
+static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state) 
 {	
+	/*
 	if (!self || self->magic != LAP_MAGIC)
 		return;
 	
 	IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[state]);
-
+	*/
 	self->state = state;
-
-#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
-	/*
-	 *  If we are swithing away from a XMIT state then we are allowed to 
-	 *  transmit a maximum number of bytes again when we enter the XMIT 
-	 *  state again. Since its possible to "switch" from XMIT to XMIT,
-	 *  we cannot do this when swithing into the XMIT state :-)
-	 */
-	if ((state != LAP_XMIT_P) && (state != LAP_XMIT_S))
-		self->bytes_left = self->line_capacity;
-#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
 }
 
 /*
@@ -1017,6 +1012,12 @@
 		IRDA_DEBUG(3, __FUNCTION__ "(), POLL_TIMER_EXPIRED (%ld)\n",
 			   jiffies);
 		irlap_send_rr_frame(self, CMD_FRAME);
+		/* Return to NRM properly - Jean II  */
+		self->window = self->window_size;
+#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
+		/* Allowed to transmit a maximum number of bytes again. */
+		self->bytes_left = self->line_capacity;
+#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
 		irlap_start_final_timer(self, self->final_timeout);
 		irlap_next_state(self, LAP_NRM_P);
 		break;
@@ -1029,6 +1030,10 @@
 		self->retry_count = 0;
 		irlap_next_state(self, LAP_PCLOSE);
 		break;
+	case DATA_REQUEST:
+		/* Nothing to do, irlap_do_event() will send the packet
+		 * when we return... - Jean II */
+		break;
 	default:
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", 
 			   irlap_event[event]);
@@ -1645,12 +1650,17 @@
 			 */
 			if (skb->len > self->bytes_left) {
 				skb_queue_head(&self->txq, skb_get(skb));
+
 				/*
 				 *  Switch to NRM_S, this is only possible
 				 *  when we are in secondary mode, since we 
 				 *  must be sure that we don't miss any RR
 				 *  frames
 				 */
+				self->window = self->window_size;
+				self->bytes_left = self->line_capacity;
+				irlap_start_wd_timer(self, self->wd_timeout);
+
 				irlap_next_state(self, LAP_NRM_S);
 
 				return -EPROTO; /* Try again later */
@@ -1688,6 +1698,10 @@
 		irlap_start_wd_timer(self, self->wd_timeout);
 		irlap_next_state(self, LAP_SCLOSE);
 		break;
+	case DATA_REQUEST:
+		/* Nothing to do, irlap_do_event() will send the packet
+		 * when we return... - Jean II */
+		break;
 	default:
 		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", 
 			   irlap_event[event]);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/irda/irlap_frame.c linux/net/irda/irlap_frame.c
--- linux.orig/net/irda/irlap_frame.c	2001-11-09 22:22:17.000000000 +0000
+++ linux/net/irda/irlap_frame.c	2002-07-20 01:08:29.000000000 +0000
@@ -768,6 +768,9 @@
 {
 	struct sk_buff *tx_skb;
 
+	/* Stop P timer */
+	del_timer(&self->poll_timer);
+		
 	/* Is this reliable or unreliable data? */
 	if (skb->data[1] == I_FRAME) {
 		
@@ -793,23 +796,15 @@
 		 *  skb, since retransmitted need to set or clear the poll
 		 *  bit depending on when they are sent.  
 		 */
-		/* Stop P timer */
-		del_timer(&self->poll_timer);
-		
 		tx_skb->data[1] |= PF_BIT;
 		
 		self->vs = (self->vs + 1) % 8;
 		self->ack_required = FALSE;
-		self->window = self->window_size;
-
-		irlap_start_final_timer(self, self->final_timeout);
 
 		irlap_send_i_frame(self, tx_skb, CMD_FRAME);
 	} else {
 		IRDA_DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n");
 
-		del_timer(&self->poll_timer);
-
 		if (self->ack_required) {
 			irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
 			irlap_send_rr_frame(self, CMD_FRAME);
@@ -818,9 +813,15 @@
 			skb->data[1] |= PF_BIT;
 			irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
 		}
-		self->window = self->window_size;
-		irlap_start_final_timer(self, self->final_timeout);
 	}
+
+	self->window = self->window_size;
+#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
+	/* We are allowed to transmit a maximum number of bytes again. */
+	self->bytes_left = self->line_capacity;
+#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
+
+	irlap_start_final_timer(self, self->final_timeout);
 }
 
 /*
@@ -858,11 +859,8 @@
 		tx_skb->data[1] |= PF_BIT;
 		
 		self->vs = (self->vs + 1) % 8; 
-		self->window = self->window_size;
 		self->ack_required = FALSE;
 		
-		irlap_start_wd_timer(self, self->wd_timeout);
-
 		irlap_send_i_frame(self, tx_skb, RSP_FRAME); 
 	} else {
 		if (self->ack_required) {
@@ -873,10 +871,15 @@
 			skb->data[1] |= PF_BIT;
 			irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
 		}
-		self->window = self->window_size;
-
-		irlap_start_wd_timer(self, self->wd_timeout);
 	}
+
+	self->window = self->window_size;
+#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
+	/* We are allowed to transmit a maximum number of bytes again. */
+	self->bytes_left = self->line_capacity;
+#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
+
+	irlap_start_wd_timer(self, self->wd_timeout);
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/irda/irnet/irnet.h linux/net/irda/irnet/irnet.h
--- linux.orig/net/irda/irnet/irnet.h	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/irda/irnet/irnet.h	2002-07-20 01:08:26.000000000 +0000
@@ -206,6 +206,11 @@
  *	  just after clearing it. *blush*.
  *	o Use newly created irttp_listen() to fix potential crash when LAP
  *	  destroyed before irnet module removed.
+ *
+ * v10 - 4.3.2 - Jean II
+ *	o When receiving a disconnect indication, don't reenable the
+ *	  PPP Tx queue, this will trigger a reconnect. Instead, close
+ *	  the channel, which will kill pppd...
  */
 
 /***************************** INCLUDES *****************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/irda/irnet/irnet_irda.c linux/net/irda/irnet/irnet_irda.c
--- linux.orig/net/irda/irnet/irnet_irda.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/irda/irnet/irnet_irda.c	2002-07-20 01:08:23.000000000 +0000
@@ -1122,9 +1122,10 @@
       irttp_close_tsap(self->tsap);
       self->tsap = NULL;
 
-      /* Flush (drain) ppp_generic Tx queue (most often we have blocked it) */
+      /* Cleanup & close the PPP channel, which will kill pppd and the rest */
       if(self->ppp_open)
-	ppp_output_wakeup(&self->chan);
+	ppp_unregister_channel(&self->chan);
+      self->ppp_open = 0;
     }
   /* Cleanup the socket in case we want to reconnect */
   self->stsap_sel = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/khttpd/main.c linux/net/khttpd/main.c
--- linux.orig/net/khttpd/main.c	2001-03-26 02:14:25.000000000 +0000
+++ linux/net/khttpd/main.c	2002-07-20 01:08:23.000000000 +0000
@@ -390,3 +390,5 @@
 
 	module_init(khttpd_init)
 	module_exit(khttpd_cleanup)
+
+	MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/khttpd/sockets.c linux/net/khttpd/sockets.c
--- linux.orig/net/khttpd/sockets.c	2000-03-27 18:35:57.000000000 +0000
+++ linux/net/khttpd/sockets.c	2002-07-20 01:08:25.000000000 +0000
@@ -82,7 +82,7 @@
 	
 	MainSocket = sock;
 	
-	EnterFunction("StartListening");
+	LeaveFunction("StartListening");
 	return 1; 
 }	
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/lapb/lapb_iface.c linux/net/lapb/lapb_iface.c
--- linux.orig/net/lapb/lapb_iface.c	2001-09-07 16:28:38.000000000 +0000
+++ linux/net/lapb/lapb_iface.c	2002-07-20 01:08:34.000000000 +0000
@@ -407,5 +407,6 @@
 
 MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
 MODULE_DESCRIPTION("The X.25 Link Access Procedure B link layer protocol");
+MODULE_LICENSE("GPL");
 
 module_init(lapb_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/netlink/netlink_dev.c linux/net/netlink/netlink_dev.c
--- linux.orig/net/netlink/netlink_dev.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/netlink/netlink_dev.c	2002-07-20 01:08:33.000000000 +0000
@@ -98,11 +98,6 @@
 	return sock_recvmsg(sock, &msg, count, msg.msg_flags);
 }
 
-static loff_t netlink_lseek(struct file * file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
 static int netlink_open(struct inode * inode, struct file * file)
 {
 	unsigned int minor = MINOR(inode->i_rdev);
@@ -166,7 +161,7 @@
 
 static struct file_operations netlink_fops = {
 	owner:		THIS_MODULE,
-	llseek:		netlink_lseek,
+	llseek:		no_llseek,
 	read:		netlink_read,
 	write:		netlink_write,
 	poll:		netlink_poll,
@@ -211,6 +206,8 @@
 
 #ifdef MODULE
 
+MODULE_LICENSE("GPL");
+
 int init_module(void)
 {
 	printk(KERN_INFO "Network Kernel/User communications module 0.04\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- linux.orig/net/netrom/af_netrom.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/netrom/af_netrom.c	2002-07-20 01:08:37.000000000 +0000
@@ -31,7 +31,9 @@
  *	NET/ROM 007	Jonathan(G4KLX)	New timer architecture.
  *					Impmented Idle timer.
  *			Arnaldo C. Melo s/suser/capable/, micro cleanups
- *			Jeroen (PE1RXQ)	Use sock_orphan() on release.
+ *			Jeroen(PE1RXQ)	Use sock_orphan() on release.
+ *			Tomi(OH2BNS)	Better frame type checking.
+ *					Device refcnt fixes.
  */
 
 #include <linux/config.h>
@@ -128,6 +130,7 @@
 
 	if ((s = nr_list) == sk) {
 		nr_list = s->next;
+		dev_put(sk->protinfo.nr->device);
 		restore_flags(flags);
 		return;
 	}
@@ -135,6 +138,7 @@
 	while (s != NULL && s->next != NULL) {
 		if (s->next == sk) {
 			s->next = sk->next;
+			dev_put(sk->protinfo.nr->device);
 			restore_flags(flags);
 			return;
 		}
@@ -616,16 +620,20 @@
 	 * Only the super user can set an arbitrary user callsign.
 	 */
 	if (addr->fsa_ax25.sax25_ndigis == 1) {
-		if (!capable(CAP_NET_BIND_SERVICE))
+		if (!capable(CAP_NET_BIND_SERVICE)) {
+			dev_put(dev);
 			return -EACCES;
+		}
 		sk->protinfo.nr->user_addr   = addr->fsa_digipeater[0];
 		sk->protinfo.nr->source_addr = addr->fsa_ax25.sax25_call;
 	} else {
 		source = &addr->fsa_ax25.sax25_call;
 
 		if ((user = ax25_findbyuid(current->euid)) == NULL) {
-			if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE))
+			if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
+				dev_put(dev);
 				return -EPERM;
+			}
 			user = source;
 		}
 
@@ -680,8 +688,10 @@
 		source = (ax25_address *)dev->dev_addr;
 
 		if ((user = ax25_findbyuid(current->euid)) == NULL) {
-			if (ax25_uid_policy && !capable(CAP_NET_ADMIN))
+			if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) {
+				dev_put(dev);
 				return -EPERM;
+			}
 			user = source;
 		}
 
@@ -976,6 +986,8 @@
 	sk->ack_backlog++;
 	make->pair = sk;
 
+	dev_hold(make->protinfo.nr->device);
+
 	nr_insert_socket(make);
 
 	skb_queue_head(&sk->receive_queue, skb);
@@ -1336,6 +1348,7 @@
 
 MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
 MODULE_DESCRIPTION("The amateur radio NET/ROM network and transport layer protocol");
+MODULE_LICENSE("GPL");
 
 static void __exit nr_exit(void)
 {
@@ -1364,7 +1377,6 @@
 			dev_nr[i].priv = NULL;
 			unregister_netdev(&dev_nr[i]);
 		}
-		kfree(dev_nr[i].name);
 	}
 
 	kfree(dev_nr);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/netrom/nr_loopback.c linux/net/netrom/nr_loopback.c
--- linux.orig/net/netrom/nr_loopback.c	2001-06-28 00:10:55.000000000 +0000
+++ linux/net/netrom/nr_loopback.c	2002-07-20 01:08:32.000000000 +0000
@@ -85,6 +85,9 @@
 		if (dev == NULL || nr_rx_frame(skb, dev) == 0)
 			kfree_skb(skb);
 
+		if (dev != NULL)
+			dev_put(dev);
+
 		if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
 			nr_set_loopback_timer();
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/netrom/nr_route.c linux/net/netrom/nr_route.c
--- linux.orig/net/netrom/nr_route.c	2000-12-29 22:44:46.000000000 +0000
+++ linux/net/netrom/nr_route.c	2002-07-20 01:08:40.000000000 +0000
@@ -19,6 +19,7 @@
  *			Alan Cox(GW4PTS) Added the firewall hooks.
  *	NET/ROM 006	Jonathan(G4KLX)	Added the setting of digipeated neighbours.
  *			Tomi(OH2BNS)	Routing quality and link failure changes.
+ *					Device refcnt fixes.
  */
 
 #include <linux/errno.h>
@@ -66,11 +67,15 @@
 	struct nr_node  *nr_node;
 	struct nr_neigh *nr_neigh;
 	struct nr_route nr_route;
+	struct net_device *tdev;
 	unsigned long flags;
 	int i, found;
 
-	if (nr_dev_get(nr) != NULL)	/* Can't add routes to ourself */
+	/* Can't add routes to ourself */
+	if ((tdev = nr_dev_get(nr)) != NULL) {
+		dev_put(tdev);
 		return -EINVAL;
+	}
 
 	for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next)
 		if (ax25cmp(nr, &nr_node->callsign) == 0)
@@ -124,6 +129,8 @@
 			memcpy(nr_neigh->digipeat, ax25_digi, sizeof(ax25_digi));
 		}
 
+		dev_hold(nr_neigh->dev);
+
 		save_flags(flags);
 		cli();
 
@@ -294,6 +301,7 @@
 	if ((s = nr_neigh_list) == nr_neigh) {
 		nr_neigh_list = nr_neigh->next;
 		restore_flags(flags);
+		dev_put(nr_neigh->dev);
 		if (nr_neigh->digipeat != NULL)
 			kfree(nr_neigh->digipeat);
 		kfree(nr_neigh);
@@ -304,6 +312,7 @@
 		if (s->next == nr_neigh) {
 			s->next = nr_neigh->next;
 			restore_flags(flags);
+			dev_put(nr_neigh->dev);
 			if (nr_neigh->digipeat != NULL)
 				kfree(nr_neigh->digipeat);
 			kfree(nr_neigh);
@@ -404,6 +413,8 @@
 		memcpy(nr_neigh->digipeat, ax25_digi, sizeof(ax25_digi));
 	}
 
+	dev_hold(nr_neigh->dev);
+
 	save_flags(flags);
 	cli();
 
@@ -570,6 +581,10 @@
 			if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
 				first = dev;
 	}
+
+	if (first != NULL)
+		dev_hold(first);
+
 	read_unlock(&dev_base_lock);
 
 	return first;
@@ -620,6 +635,7 @@
 {
 	struct nr_route_struct nr_route;
 	struct net_device *dev;
+	int ret;
 
 	switch (cmd) {
 
@@ -628,23 +644,30 @@
 				return -EFAULT;
 			if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
 				return -EINVAL;
-			if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS)
+			if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS) {
+				dev_put(dev);
 				return -EINVAL;
+			}
 			switch (nr_route.type) {
 				case NETROM_NODE:
-					return nr_add_node(&nr_route.callsign,
+					ret = nr_add_node(&nr_route.callsign,
 						nr_route.mnemonic,
 						&nr_route.neighbour,
 						nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
 						dev, nr_route.quality,
 						nr_route.obs_count);
+					break;
 				case NETROM_NEIGH:
-					return nr_add_neigh(&nr_route.callsign,
+					ret = nr_add_neigh(&nr_route.callsign,
 						nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
 						dev, nr_route.quality);
+					break;
 				default:
-					return -EINVAL;
+					ret = -EINVAL;
+					break;
 			}
+			dev_put(dev);
+			return ret;
 
 		case SIOCDELRT:
 			if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
@@ -653,14 +676,19 @@
 				return -EINVAL;
 			switch (nr_route.type) {
 				case NETROM_NODE:
-					return nr_del_node(&nr_route.callsign,
+					ret = nr_del_node(&nr_route.callsign,
 						&nr_route.neighbour, dev);
+					break;
 				case NETROM_NEIGH:
-					return nr_del_neigh(&nr_route.callsign,
+					ret = nr_del_neigh(&nr_route.callsign,
 						dev, nr_route.quality);
+					break;
 				default:
-					return -EINVAL;
+					ret = -EINVAL;
+					break;
 			}
+			dev_put(dev);
+			return ret;
 
 		case SIOCNRDECOBS:
 			return nr_dec_obs();
@@ -717,10 +745,15 @@
 			    ax25->ax25_dev->dev, 0, sysctl_netrom_obsolescence_count_initialiser);
 
 	if ((dev = nr_dev_get(nr_dest)) != NULL) {	/* Its for me */
+		int ret;
+
 		if (ax25 == NULL)			/* Its from me */
-			return nr_loopback_queue(skb);
+			ret = nr_loopback_queue(skb);
 		else
-			return nr_rx_frame(skb, dev);
+			ret = nr_rx_frame(skb, dev);
+
+		dev_put(dev);
+		return ret;
 	}
 
 	if (!sysctl_netrom_routing_control && ax25 != NULL)
@@ -747,6 +780,8 @@
 
 	nr_neigh->ax25 = ax25_send_frame(skb, 256, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev);
 
+	dev_put(dev);
+
 	return (nr_neigh->ax25 != NULL);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/netsyms.c linux/net/netsyms.c
--- linux.orig/net/netsyms.c	2002-02-25 19:38:14.000000000 +0000
+++ linux/net/netsyms.c	2002-07-20 01:08:34.000000000 +0000
@@ -364,7 +364,6 @@
 EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
 EXPORT_SYMBOL(tcp_v4_do_rcv);
 EXPORT_SYMBOL(tcp_v4_connect);
-EXPORT_SYMBOL(tcp_v4_hash_connecting);
 EXPORT_SYMBOL(tcp_unhash);
 EXPORT_SYMBOL(udp_prot);
 EXPORT_SYMBOL(tcp_prot);
@@ -409,6 +408,8 @@
 
 #endif
 
+EXPORT_SYMBOL(tcp_read_sock);
+
 EXPORT_SYMBOL(netlink_set_err);
 EXPORT_SYMBOL(netlink_broadcast);
 EXPORT_SYMBOL(netlink_unicast);
@@ -447,7 +448,6 @@
 EXPORT_SYMBOL(dev_open);
 
 /* Used by other modules */
-EXPORT_SYMBOL(in_ntoa);
 EXPORT_SYMBOL(xrlim_allow);
 
 EXPORT_SYMBOL(ip_rcv);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/packet/af_packet.c linux/net/packet/af_packet.c
--- linux.orig/net/packet/af_packet.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/packet/af_packet.c	2002-07-20 01:08:25.000000000 +0000
@@ -355,6 +355,8 @@
 	if (dev->hard_header) {
 		skb->data -= dev->hard_header_len;
 		skb->tail -= dev->hard_header_len;
+		if (len < dev->hard_header_len)
+			skb->nh.raw = skb->data;
 	}
 
 	/* Returns -EFAULT on error */
@@ -1660,7 +1662,7 @@
 			pg_vec[i] = __get_free_pages(GFP_KERNEL, order);
 			if (!pg_vec[i])
 				goto out_free_pgvec;
-
+			memset((void *)(pg_vec[i]), 0, PAGE_SIZE << order);
 			pend = virt_to_page(pg_vec[i] + (PAGE_SIZE << order) - 1);
 			for (page = virt_to_page(pg_vec[i]); page <= pend; page++)
 				SetPageReserved(page);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/rose/af_rose.c linux/net/rose/af_rose.c
--- linux.orig/net/rose/af_rose.c	2002-02-25 19:38:15.000000000 +0000
+++ linux/net/rose/af_rose.c	2002-07-20 01:08:37.000000000 +0000
@@ -26,6 +26,7 @@
  *
  *  ROSE 0.63	Jean-Paul(F6FBB) Fixed wrong length of L3 packets
  *					Added CLEAR_REQUEST facilities
+ *  ROSE 0.64	Jean-Paul(F6FBB) Fixed null pointer in rose_kill_by_device
  */
 
 #include <linux/config.h>
@@ -227,7 +228,8 @@
 	for (s = rose_list; s != NULL; s = s->next) {
 		if (s->protinfo.rose->device == dev) {
 			rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
-			s->protinfo.rose->neighbour->use--;
+			if (s->protinfo.rose->neighbour)
+				s->protinfo.rose->neighbour->use--;
 			s->protinfo.rose->device = NULL;
 		}
 	}
@@ -1433,7 +1435,7 @@
 
 static struct net_device *dev_rose;
 
-static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.63 for AX25.037 Linux 2.4\n";
+static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.64 for AX25.037 Linux 2.4\n";
 
 static int __init rose_proto_init(void)
 {
@@ -1488,6 +1490,7 @@
 
 MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
 MODULE_DESCRIPTION("The amateur radio ROSE network layer protocol");
+MODULE_LICENSE("GPL");
 
 static void __exit rose_exit(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sched/sch_api.c linux/net/sched/sch_api.c
--- linux.orig/net/sched/sch_api.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/sched/sch_api.c	2002-07-20 01:08:35.000000000 +0000
@@ -1117,7 +1117,7 @@
 	psched_timer.expires = jiffies + 1*HZ;
 #else
 	unsigned long now = jiffies;
-	psched_time_base = ((u64)now)<<PSCHED_JSCALE;
+	psched_time_base += ((u64)(now-psched_time_mark))<<PSCHED_JSCALE;
 	psched_time_mark = now;
 	psched_timer.expires = now + 60*60*HZ;
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sched/sch_generic.c linux/net/sched/sch_generic.c
--- linux.orig/net/sched/sch_generic.c	2000-08-18 17:26:25.000000000 +0000
+++ linux/net/sched/sch_generic.c	2002-07-20 01:08:23.000000000 +0000
@@ -280,7 +280,7 @@
 	list = ((struct sk_buff_head*)qdisc->data) +
 		prio2band[skb->priority&TC_PRIO_MAX];
 
-	if (list->qlen <= skb->dev->tx_queue_len) {
+	if (list->qlen <= qdisc->dev->tx_queue_len) {
 		__skb_queue_tail(list, skb);
 		qdisc->q.qlen++;
 		return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sched/sch_gred.c linux/net/sched/sch_gred.c
--- linux.orig/net/sched/sch_gred.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/sched/sch_gred.c	2002-07-20 01:08:31.000000000 +0000
@@ -7,7 +7,7 @@
  *              as published by the Free Software Foundation; either version
  *              2 of the License, or (at your option) any later version.
  *
- * Authors:    J Hadi Salim (hadi@nortelnetworks.com) 1998,1999
+ * Authors:    J Hadi Salim (hadi@cyberus.ca) 1998-2002
  *
  *             991129: -  Bug fix with grio mode
  *		       - a better sing. AvgQ mode with Grio(WRED)
@@ -436,7 +436,7 @@
 		if (table->tab[table->def] == NULL) {
 			table->tab[table->def]=
 				kmalloc(sizeof(struct gred_sched_data), GFP_KERNEL);
-			if (NULL == table->tab[ctl->DP])
+			if (NULL == table->tab[table->def])
 				return -ENOMEM;
 
 			memset(table->tab[table->def], 0,
@@ -498,7 +498,7 @@
 {
 	unsigned long qave;
 	struct rtattr *rta;
-	struct tc_gred_qopt *opt;
+	struct tc_gred_qopt *opt = NULL ;
 	struct tc_gred_qopt *dst;
 	struct gred_sched *table = (struct gred_sched *)sch->data;
 	struct gred_sched_data *q;
@@ -520,7 +520,6 @@
 
 	if (!table->initd) {
 		DPRINTK("NO GRED Queues setup!\n");
-		return -1;
 	}
 
 	for (i=0;i<MAX_DPs;i++) {
@@ -577,9 +576,12 @@
 	RTA_PUT(skb, TCA_GRED_PARMS, sizeof(struct tc_gred_qopt)*MAX_DPs, opt);
 	rta->rta_len = skb->tail - b;
 
+	kfree(opt);
 	return skb->len;
 
 rtattr_failure:
+	if (opt)
+		kfree(opt);
 	DPRINTK("gred_dump: FAILURE!!!!\n");
 
 /* also free the opt struct here */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sched/sch_ingress.c linux/net/sched/sch_ingress.c
--- linux.orig/net/sched/sch_ingress.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/sched/sch_ingress.c	2002-07-20 01:08:29.000000000 +0000
@@ -43,6 +43,9 @@
 #define PRIV(sch) ((struct ingress_qdisc_data *) (sch)->data)
 
 
+/* Thanks to Doron Oz for this hack
+*/
+static int nf_registered = 0; 
 
 struct ingress_qdisc_data {
 	struct Qdisc		*q;
@@ -143,19 +146,25 @@
 	 * Unlike normal "enqueue" functions, ingress_enqueue returns a
 	 * firewall FW_* code.
 	 */
-	switch (result) {
 #ifdef CONFIG_NET_CLS_POLICE
+	switch (result) {
 		case TC_POLICE_SHOT:
 			result = NF_DROP;
+			sch->stats.drops++;
 			break;
 		case TC_POLICE_RECLASSIFY: /* DSCP remarking here ? */
 		case TC_POLICE_OK:
 		case TC_POLICE_UNSPEC:
 		default:
+			sch->stats.packets++;
+			sch->stats.bytes += skb->len;
 			result = NF_ACCEPT;
 			break;
-#endif
 	};
+#else
+	sch->stats.packets++;
+	sch->stats.bytes += skb->len;
+#endif
 
 	skb->tc_index = TC_H_MIN(res.classid);
 	return result;
@@ -236,22 +245,21 @@
 {
 	struct ingress_qdisc_data *p = PRIV(sch);
 
+	if (!nf_registered) {
+		if (nf_register_hook(&ing_ops) < 0) {
+			printk("ingress qdisc registration error \n");
+			goto error;
+			}
+		nf_registered++;
+	}
+
 	DPRINTK("ingress_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt);
 	memset(p, 0, sizeof(*p));
 	p->filter_list = NULL;
 	p->q = &noop_qdisc;
-#ifndef MODULE
-	if (nf_register_hook(&ing_ops) < 0) {
-		printk("Unable to register ingress \n");
-		goto error;
-	}
-#endif
-	DPRINTK("ingress_init: qdisc %p\n", sch);
 	MOD_INC_USE_COUNT;
 	return 0;
-#ifndef MODULE
 error:
-#endif
 	return -EINVAL;
 }
 
@@ -295,12 +303,9 @@
 /* for future use */
 	qdisc_destroy(p->q);
 #endif
-
-#ifndef MODULE
-	nf_unregister_hook(&ing_ops);
-#endif
-
+ 
 	MOD_DEC_USE_COUNT;
+
 }
 
 
@@ -356,6 +361,7 @@
 	ingress_dump,			/* dump */
 };
 
+
 #ifdef MODULE
 int init_module(void)
 {
@@ -366,20 +372,15 @@
 		return ret;
 	}
 
-        if (nf_register_hook(&ing_ops) < 0) {
-		printk("Unable to register ingress on hook \n");
-		unregister_qdisc(&ingress_qdisc_ops);
-		return 0;
-	}
-
 	return ret;
 }
 
 
 void cleanup_module(void) 
 {
-	nf_unregister_hook(&ing_ops);
 	unregister_qdisc(&ingress_qdisc_ops);
+	if (nf_registered)
+		nf_unregister_hook(&ing_ops);
 }
 #endif
 MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sched/sch_prio.c linux/net/sched/sch_prio.c
--- linux.orig/net/sched/sch_prio.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/sched/sch_prio.c	2002-07-20 01:08:34.000000000 +0000
@@ -327,6 +327,7 @@
 
 	if (cl - 1 > q->bands)
 		return -ENOENT;
+	tcm->tcm_handle |= TC_H_MIN(cl);
 	if (q->queues[cl-1])
 		tcm->tcm_info = q->queues[cl-1]->handle;
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sched/sch_sfq.c linux/net/sched/sch_sfq.c
--- linux.orig/net/sched/sch_sfq.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/sched/sch_sfq.c	2002-07-20 01:08:33.000000000 +0000
@@ -105,6 +105,7 @@
 /* Parameters */
 	int		perturb_period;
 	unsigned	quantum;	/* Allotment per round: MUST BE >= MTU */
+	int		limit;
 
 /* Variables */
 	struct timer_list perturb_timer;
@@ -275,7 +276,7 @@
 			q->tail = x;
 		}
 	}
-	if (++sch->q.qlen < SFQ_DEPTH-1) {
+	if (++sch->q.qlen < q->limit-1) {
 		sch->stats.bytes += skb->len;
 		sch->stats.packets++;
 		return 0;
@@ -310,7 +311,7 @@
 			q->tail = x;
 		}
 	}
-	if (++sch->q.qlen < SFQ_DEPTH-1)
+	if (++sch->q.qlen < q->limit - 1)
 		return 0;
 
 	sch->stats.drops++;
@@ -390,6 +391,11 @@
 	sch_tree_lock(sch);
 	q->quantum = ctl->quantum ? : psched_mtu(sch->dev);
 	q->perturb_period = ctl->perturb_period*HZ;
+	if (ctl->limit)
+		q->limit = min_t(u32, ctl->limit, SFQ_DEPTH);
+
+	while (sch->q.qlen >= q->limit-1)
+		sfq_drop(sch);
 
 	del_timer(&q->perturb_timer);
 	if (q->perturb_period) {
@@ -416,6 +422,7 @@
 		q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH;
 		q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH;
 	}
+	q->limit = SFQ_DEPTH;
 	q->max_depth = 0;
 	q->tail = SFQ_DEPTH;
 	if (opt == NULL) {
@@ -448,9 +455,9 @@
 	opt.quantum = q->quantum;
 	opt.perturb_period = q->perturb_period/HZ;
 
-	opt.limit = SFQ_DEPTH;
+	opt.limit = q->limit;
 	opt.divisor = SFQ_HASH_DIVISOR;
-	opt.flows = SFQ_DEPTH;
+	opt.flows = q->limit;
 
 	RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/socket.c linux/net/socket.c
--- linux.orig/net/socket.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/socket.c	2002-07-20 01:08:32.000000000 +0000
@@ -86,7 +86,6 @@
 #include <linux/netfilter.h>
 
 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
-static loff_t sock_lseek(struct file *file, loff_t offset, int whence);
 static ssize_t sock_read(struct file *file, char *buf,
 			 size_t size, loff_t *ppos);
 static ssize_t sock_write(struct file *file, const char *buf,
@@ -113,7 +112,7 @@
  */
 
 static struct file_operations socket_file_ops = {
-	llseek:		sock_lseek,
+	llseek:		no_llseek,
 	read:		sock_read,
 	write:		sock_write,
 	poll:		sock_poll,
@@ -527,15 +526,6 @@
 
 
 /*
- *	Sockets are not seekable.
- */
-
-static loff_t sock_lseek(struct file *file, loff_t offset, int whence)
-{
-	return -ESPIPE;
-}
-
-/*
  *	Read data from a socket. ubuf is a user mode pointer. We make sure the user
  *	area ubuf...ubuf+size-1 is writable before asking the protocol.
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sunrpc/pmap_clnt.c linux/net/sunrpc/pmap_clnt.c
--- linux.orig/net/sunrpc/pmap_clnt.c	2001-09-21 18:24:50.000000000 +0000
+++ linux/net/sunrpc/pmap_clnt.c	2002-07-20 01:08:37.000000000 +0000
@@ -87,8 +87,6 @@
 }
 
 #ifdef CONFIG_ROOT_NFS
-char *in_ntoa(__u32 in);
-
 int
 rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
 {
@@ -100,7 +98,7 @@
 	dprintk("RPC:      rpc_getport_external(%u.%u.%u.%u, %d, %d, %d)\n",
 			NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
 
-	strcpy(hostname, in_ntoa(sin->sin_addr.s_addr));
+	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
 	if (!(pmap_clnt = pmap_create(hostname, sin, prot)))
 		return -EACCES;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sunrpc/sched.c linux/net/sunrpc/sched.c
--- linux.orig/net/sunrpc/sched.c	2002-02-25 19:38:15.000000000 +0000
+++ linux/net/sunrpc/sched.c	2002-07-20 01:08:38.000000000 +0000
@@ -699,9 +699,6 @@
 
 	dprintk("RPC:      rpc_schedule enter\n");
 	while (1) {
-		/* Ensure equal rights for tcp tasks... */
-		rpciod_tcp_dispatcher();
-
 		spin_lock_bh(&rpc_queue_lock);
 		if (!(task = schedq.task)) {
 			spin_unlock_bh(&rpc_queue_lock);
@@ -1039,7 +1036,7 @@
 static inline int
 rpciod_task_pending(void)
 {
-	return schedq.task != NULL || xprt_tcp_pending();
+	return schedq.task != NULL;
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sunrpc/stats.c linux/net/sunrpc/stats.c
--- linux.orig/net/sunrpc/stats.c	2001-10-11 18:17:22.000000000 +0000
+++ linux/net/sunrpc/stats.c	2002-07-20 01:08:40.000000000 +0000
@@ -20,6 +20,7 @@
 #include <linux/proc_fs.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svcsock.h>
+#include <linux/init.h>
 
 #define RPCDBG_FACILITY	RPCDBG_MISC
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/sunrpc/xprt.c linux/net/sunrpc/xprt.c
--- linux.orig/net/sunrpc/xprt.c	2001-12-21 17:42:06.000000000 +0000
+++ linux/net/sunrpc/xprt.c	2002-07-20 01:08:26.000000000 +0000
@@ -63,12 +63,10 @@
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/udp.h>
+#include <net/tcp.h>
 
 #include <asm/uaccess.h>
 
-/* Following value should be > 32k + RPC overhead */
-#define XPRT_MIN_WRITE_SPACE (35000 + SOCK_MIN_WRITE_SPACE)
-
 extern spinlock_t rpc_queue_lock;
 
 /*
@@ -90,7 +88,6 @@
 static void	xprt_reconn_status(struct rpc_task *task);
 static struct socket *xprt_create_socket(int, struct rpc_timeout *);
 static int	xprt_bind_socket(struct rpc_xprt *, struct socket *);
-static void	xprt_remove_pending(struct rpc_xprt *);
 
 #ifdef RPC_DEBUG_DATA
 /*
@@ -272,43 +269,6 @@
 }
 
 /*
- * Read data from socket
- */
-static int
-xprt_recvmsg(struct rpc_xprt *xprt, struct iovec *iov, int nr, unsigned len, unsigned shift)
-{
-	struct socket	*sock = xprt->sock;
-	struct msghdr	msg;
-	mm_segment_t	oldfs;
-	struct iovec	niv[MAX_IOVEC];
-	int		result;
-
-	if (!sock)
-		return -ENOTCONN;
-
-	msg.msg_flags   = MSG_DONTWAIT|MSG_NOSIGNAL;
-	msg.msg_iov	= iov;
-	msg.msg_iovlen	= nr;
-	msg.msg_name	= NULL;
-	msg.msg_namelen = 0;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-
-	/* Adjust the iovec if we've already filled it */
-	if (shift)
-		xprt_move_iov(&msg, niv, shift);
-
-	oldfs = get_fs(); set_fs(get_ds());
-	result = sock_recvmsg(sock, &msg, len, MSG_DONTWAIT);
-	set_fs(oldfs);
-
-	dprintk("RPC:      xprt_recvmsg(iov %p, len %d) = %d\n",
-						iov, len, result);
-	return result;
-}
-
-
-/*
  * Adjust RPC congestion window
  * We use a time-smoothed congestion estimator to avoid heavy oscillation.
  */
@@ -425,7 +385,6 @@
 {
 	dprintk("RPC:      disconnected transport %p\n", xprt);
 	xprt_clear_connected(xprt);
-	xprt_remove_pending(xprt);
 	rpc_wake_up_status(&xprt->pending, -ENOTCONN);
 }
 
@@ -439,7 +398,7 @@
 {
 	struct rpc_xprt	*xprt = task->tk_xprt;
 	struct socket	*sock = xprt->sock;
-	struct sock	*inet = xprt->inet;
+	struct sock	*inet;
 	int		status;
 
 	dprintk("RPC: %4d xprt_reconnect %p connected %d\n",
@@ -460,8 +419,10 @@
 	if (xprt_connected(xprt))
 		goto out_write;
 
+	if (sock && sock->state != SS_UNCONNECTED)
+		xprt_close(xprt);
 	status = -ENOTCONN;
-	if (!inet) {
+	if (!(inet = xprt->inet)) {
 		/* Create an unconnected socket */
 		if (!(sock = xprt_create_socket(xprt->prot, &xprt->timeout)))
 			goto defer;
@@ -469,14 +430,6 @@
 		inet = sock->sk;
 	}
 
-	xprt_disconnect(xprt);
-
-	/* Reset TCP record info */
-	xprt->tcp_offset = 0;
-	xprt->tcp_reclen = 0;
-	xprt->tcp_copied = 0;
-	xprt->tcp_more = 0;
-
 	/* Now connect it asynchronously. */
 	dprintk("RPC: %4d connecting new socket\n", task->tk_pid);
 	status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
@@ -499,17 +452,21 @@
 			goto defer;
 		}
 
+		/* Protect against TCP socket state changes */
+		lock_sock(inet);
 		dprintk("RPC: %4d connect status %d connected %d\n",
 				task->tk_pid, status, xprt_connected(xprt));
 
-		spin_lock_bh(&xprt->sock_lock);
-		if (!xprt_connected(xprt)) {
+		if (inet->state != TCP_ESTABLISHED) {
 			task->tk_timeout = xprt->timeout.to_maxval;
+			/* if the socket is already closing, delay 5 secs */
+			if ((1<<inet->state) & ~(TCP_SYN_SENT|TCP_SYN_RECV))
+				task->tk_timeout = 5*HZ;
 			rpc_sleep_on(&xprt->sending, task, xprt_reconn_status, NULL);
-			spin_unlock_bh(&xprt->sock_lock);
+			release_sock(inet);
 			return;
 		}
-		spin_unlock_bh(&xprt->sock_lock);
+		release_sock(inet);
 	}
 defer:
 	if (status < 0) {
@@ -728,309 +685,229 @@
 		wake_up_interruptible(sk->sleep);
 }
 
+typedef struct {
+	struct sk_buff *skb;
+	unsigned offset;
+	size_t count;
+} skb_reader_t;
+
+/*
+ * Copy from an skb into memory and shrink the skb.
+ */
+static inline size_t
+tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
+{
+	if (len > desc->count)
+		len = desc->count;
+	skb_copy_bits(desc->skb, desc->offset, p, len);
+	desc->offset += len;
+	desc->count -= len;
+	return len;
+}
+
 /*
  * TCP read fragment marker
  */
-static inline int
-tcp_read_fraghdr(struct rpc_xprt *xprt)
+static inline void
+tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
 {
-	struct iovec	riov;
-	int		want, result;
+	size_t len, used;
+	char *p;
 
-	if (xprt->tcp_offset >= sizeof(xprt->tcp_recm))
-		goto done;
-
-	want = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
-	dprintk("RPC:      reading header (%d bytes)\n", want);
-	do {
-		riov.iov_base = ((u8*) &xprt->tcp_recm) + xprt->tcp_offset;
-		riov.iov_len  = want;
-		result = xprt_recvmsg(xprt, &riov, 1, want, 0);
-		if (result < 0)
-			return result;
-		xprt->tcp_offset += result;
-		want -= result;
-	} while (want);
-
-	/* Get the record length and mask out the last fragment bit */
+	p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
+	len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
+	used = tcp_copy_data(desc, p, len);
+	xprt->tcp_offset += used;
+	if (used != len)
+		return;
 	xprt->tcp_reclen = ntohl(xprt->tcp_recm);
-	xprt->tcp_more = (xprt->tcp_reclen & 0x80000000) ? 0 : 1;
+	if (xprt->tcp_reclen & 0x80000000)
+		xprt->tcp_flags |= XPRT_LAST_FRAG;
+	else
+		xprt->tcp_flags &= ~XPRT_LAST_FRAG;
 	xprt->tcp_reclen &= 0x7fffffff;
-
-	dprintk("RPC:      New record reclen %d morefrags %d\n",
-				   xprt->tcp_reclen, xprt->tcp_more);
- done:
-	return xprt->tcp_reclen + sizeof(xprt->tcp_recm) - xprt->tcp_offset;
+	xprt->tcp_flags &= ~XPRT_COPY_RECM;
+	xprt->tcp_offset = 0;
+	/* Sanity check of the record length */
+	if (xprt->tcp_reclen < 4) {
+		printk(KERN_ERR "RPC: Invalid TCP record fragment length\n");
+		xprt_disconnect(xprt);
+	}
+	dprintk("RPC:      reading TCP record fragment of length %d\n",
+			xprt->tcp_reclen);
 }
 
-/*
- * TCP read xid
- */
-static inline int
-tcp_read_xid(struct rpc_xprt *xprt, int avail)
+static void
+tcp_check_recm(struct rpc_xprt *xprt)
 {
-	struct iovec	riov;
-	int		want, result;
-
-	if (xprt->tcp_copied >= sizeof(xprt->tcp_xid) || !avail)
-		goto done;
-	want = min_t(unsigned int, sizeof(xprt->tcp_xid) - xprt->tcp_copied, avail);
-	do {
-		dprintk("RPC:      reading xid (%d bytes)\n", want);
-		riov.iov_base = ((u8*) &xprt->tcp_xid) + xprt->tcp_copied;
-		riov.iov_len  = want;
-		result = xprt_recvmsg(xprt, &riov, 1, want, 0);
-		if (result < 0)
-			return result;
-		xprt->tcp_copied += result;
-		xprt->tcp_offset += result;
-		want  -= result;
-		avail -= result;
-	} while (want);
- done:
-	return avail;
+	if (xprt->tcp_offset == xprt->tcp_reclen) {
+		xprt->tcp_flags |= XPRT_COPY_RECM;
+		xprt->tcp_offset = 0;
+		if (xprt->tcp_flags & XPRT_LAST_FRAG) {
+			xprt->tcp_flags &= ~XPRT_COPY_DATA;
+			xprt->tcp_flags |= XPRT_COPY_XID;
+			xprt->tcp_copied = 0;
+		}
+	}
 }
 
 /*
- * TCP read and complete request
+ * TCP read xid
  */
-static inline int
-tcp_read_request(struct rpc_xprt *xprt, struct rpc_rqst *req, int avail)
+static inline void
+tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
 {
-	int	want, result;
-
-	if (req->rq_rlen <= xprt->tcp_copied || !avail)
-		goto done;
-	want = min_t(unsigned int, req->rq_rlen - xprt->tcp_copied, avail);
-	do {
-		dprintk("RPC: %4d TCP receiving %d bytes\n",
-			req->rq_task->tk_pid, want);
+	size_t len, used;
+	char *p;
 
-		result = xprt_recvmsg(xprt, req->rq_rvec, req->rq_rnr, want, xprt->tcp_copied);
-		if (result < 0)
-			return result;
-		xprt->tcp_copied += result;
-		xprt->tcp_offset += result;
-		avail  -= result;
-		want   -= result;
-	} while (want);
-
- done:
-	if (req->rq_rlen > xprt->tcp_copied && xprt->tcp_more)
-		return avail;
-	dprintk("RPC: %4d received reply complete\n", req->rq_task->tk_pid);
-	xprt_complete_rqst(xprt, req, xprt->tcp_copied);
-
-	return avail;
-}
-
-/*
- * TCP discard extra bytes from a short read
- */
-static inline int
-tcp_read_discard(struct rpc_xprt *xprt, int avail)
-{
-	struct iovec	riov;
-	static u8	dummy[64];
-	int		want, result = 0;
-
-	while (avail) {
-		want = min_t(unsigned int, avail, sizeof(dummy));
-		riov.iov_base = dummy;
-		riov.iov_len  = want;
-		dprintk("RPC:      TCP skipping %d bytes\n", want);
-		result = xprt_recvmsg(xprt, &riov, 1, want, 0);
-		if (result < 0)
-			return result;
-		xprt->tcp_offset += result;
-		avail  -= result;
-	}
-	return avail;
+	len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
+	dprintk("RPC:      reading XID (%Zu bytes)\n", len);
+	p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
+	used = tcp_copy_data(desc, p, len);
+	xprt->tcp_offset += used;
+	if (used != len)
+		return;
+	xprt->tcp_flags &= ~XPRT_COPY_XID;
+	xprt->tcp_flags |= XPRT_COPY_DATA;
+	xprt->tcp_copied = 4;
+	dprintk("RPC:      reading reply for XID %08x\n", xprt->tcp_xid);
+	tcp_check_recm(xprt);
 }
 
 /*
- * TCP record receive routine
- * This is not the most efficient code since we call recvfrom thrice--
- * first receiving the record marker, then the XID, then the data.
- * 
- * The optimal solution would be a RPC support in the TCP layer, which
- * would gather all data up to the next record marker and then pass us
- * the list of all TCP segments ready to be copied.
+ * TCP read and complete request
  */
-static int
-tcp_input_record(struct rpc_xprt *xprt)
+static inline void
+tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
 {
-	struct rpc_rqst	*req = NULL;
-	struct rpc_task	*task = NULL;
-	int		avail, result;
-
-	dprintk("RPC:      tcp_input_record\n");
-
-	if (xprt->shutdown)
-		return -EIO;
-	if (!xprt_connected(xprt))
-		return -ENOTCONN;
-
-	/* Read in a new fragment marker if necessary */
-	/* Can we ever really expect to get completely empty fragments? */
-	if ((result = tcp_read_fraghdr(xprt)) < 0)
-		return result;
-	avail = result;
-
-	/* Read in the xid if necessary */
-	if ((result = tcp_read_xid(xprt, avail)) < 0)
-		return result;
-	if (!(avail = result))
-		goto out_ok;
+	struct rpc_rqst *req;
+	struct iovec *iov;
+	char *p;
+	unsigned long skip;
+	size_t len, used;
+	int n;
 
 	/* Find and lock the request corresponding to this xid */
 	req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
-	if (req) {
-		task = req->rq_task;
-		/* Read in the request data */
-		result = tcp_read_request(xprt,  req, avail);
-		rpc_unlock_task(task);
-		if (result < 0)
-			return result;
-		avail = result;
+	if (!req) {
+		xprt->tcp_flags &= ~XPRT_COPY_DATA;
+		dprintk("RPC:      XID %08x request not found!\n",
+				xprt->tcp_xid);
+		return;
 	}
-
-	/* Skip over any trailing bytes on short reads */
-	if ((result = tcp_read_discard(xprt, avail)) < 0)
-		return result;
-
- out_ok:
-	dprintk("RPC:      tcp_input_record done (off %d reclen %d copied %d)\n",
-			xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_copied);
-	result = xprt->tcp_reclen;
-	xprt->tcp_reclen = 0;
-	xprt->tcp_offset = 0;
-	if (!xprt->tcp_more)
-		xprt->tcp_copied = 0;
-	return result;
-}
-
-/*
- *	TCP task queue stuff
- */
-LIST_HEAD(rpc_xprt_pending);	/* List of xprts having pending tcp requests */
-
-static inline
-void tcp_rpciod_queue(void)
-{
-	rpciod_wake_up();
-}
-
-int xprt_tcp_pending(void)
-{
-	int retval;
-
-	spin_lock_bh(&rpc_queue_lock);
-	retval = !list_empty(&rpc_xprt_pending);
-	spin_unlock_bh(&rpc_queue_lock);
-	return retval;
-}
-
-static inline
-void xprt_append_pending(struct rpc_xprt *xprt)
-{
-	spin_lock_bh(&rpc_queue_lock);
-	if (list_empty(&xprt->rx_pending)) {
-		list_add(&xprt->rx_pending, rpc_xprt_pending.prev);
-		dprintk("RPC:     xprt queue %p\n", xprt);
-		tcp_rpciod_queue();
+	skip = xprt->tcp_copied;
+	iov = req->rq_rvec;
+	for (n = req->rq_rnr; n != 0; n--, iov++) {
+		if (skip >= iov->iov_len) {
+			skip -= iov->iov_len;
+			continue;
+		}
+		p = iov->iov_base;
+		len = iov->iov_len;
+		if (skip) {
+			p += skip;
+			len -= skip;
+			skip = 0;
+		}
+		if (xprt->tcp_offset + len > xprt->tcp_reclen)
+			len = xprt->tcp_reclen - xprt->tcp_offset;
+		used = tcp_copy_data(desc, p, len);
+		xprt->tcp_copied += used;
+		xprt->tcp_offset += used;
+		if (used != len)
+			break;
+		if (xprt->tcp_copied == req->rq_rlen) {
+			xprt->tcp_flags &= ~XPRT_COPY_DATA;
+			break;
+		}
+		if (xprt->tcp_offset == xprt->tcp_reclen) {
+			if (xprt->tcp_flags & XPRT_LAST_FRAG)
+				xprt->tcp_flags &= ~XPRT_COPY_DATA;
+			break;
+		}
 	}
-	spin_unlock_bh(&rpc_queue_lock);
-}
 
-static
-void xprt_remove_pending(struct rpc_xprt *xprt)
-{
-	spin_lock_bh(&rpc_queue_lock);
-	if (!list_empty(&xprt->rx_pending)) {
-		list_del(&xprt->rx_pending);
-		INIT_LIST_HEAD(&xprt->rx_pending);
+	if (!(xprt->tcp_flags & XPRT_COPY_DATA)) {
+		dprintk("RPC: %4d received reply complete\n",
+				req->rq_task->tk_pid);
+		xprt_complete_rqst(xprt, req, xprt->tcp_copied);
 	}
-	spin_unlock_bh(&rpc_queue_lock);
+	rpc_unlock_task(req->rq_task); 
+	tcp_check_recm(xprt);
 }
 
-static inline
-struct rpc_xprt *xprt_remove_pending_next(void)
+/*
+ * TCP discard extra bytes from a short read
+ */
+static inline void
+tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
 {
-	struct rpc_xprt	*xprt = NULL;
+	size_t len;
 
-	spin_lock_bh(&rpc_queue_lock);
-	if (!list_empty(&rpc_xprt_pending)) {
-		xprt = list_entry(rpc_xprt_pending.next, struct rpc_xprt, rx_pending);
-		list_del(&xprt->rx_pending);
-		INIT_LIST_HEAD(&xprt->rx_pending);
-	}
-	spin_unlock_bh(&rpc_queue_lock);
-	return xprt;
+	len = xprt->tcp_reclen - xprt->tcp_offset;
+	if (len > desc->count)
+		len = desc->count;
+	desc->count -= len;
+	desc->offset += len;
+	xprt->tcp_offset += len;
+	tcp_check_recm(xprt);
 }
 
 /*
- *	This is protected from tcp_data_ready and the stack as its run
- *	inside of the RPC I/O daemon
+ * TCP record receive routine
+ * We first have to grab the record marker, then the XID, then the data.
  */
-void
-__rpciod_tcp_dispatcher(void)
+static int
+tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
+		unsigned int offset, size_t len)
 {
-	struct rpc_xprt *xprt;
-	int safe_retry = 0, result;
-
-	dprintk("rpciod_tcp_dispatcher: Queue Running\n");
-
-	/*
-	 *	Empty each pending socket
-	 */
-	while ((xprt = xprt_remove_pending_next()) != NULL) {
-		dprintk("rpciod_tcp_dispatcher: Processing %p\n", xprt);
-
-		do {
-			result = tcp_input_record(xprt);
-		} while (result >= 0);
+	struct rpc_xprt *xprt = (struct rpc_xprt *)rd_desc->buf;
+	skb_reader_t desc = { skb, offset, len };
 
-		if (safe_retry++ > 200) {
-			schedule();
-			safe_retry = 0;
+	dprintk("RPC:      tcp_data_recv\n");
+	do {
+		/* Read in a new fragment marker if necessary */
+		/* Can we ever really expect to get completely empty fragments? */
+		if (xprt->tcp_flags & XPRT_COPY_RECM) {
+			tcp_read_fraghdr(xprt, &desc);
+			continue;
 		}
-	}
+		/* Read in the xid if necessary */
+		if (xprt->tcp_flags & XPRT_COPY_XID) {
+			tcp_read_xid(xprt, &desc);
+			continue;
+		}
+		/* Read in the request data */
+		if (xprt->tcp_flags & XPRT_COPY_DATA) {
+			tcp_read_request(xprt, &desc);
+			continue;
+		}
+		/* Skip over any trailing bytes on short reads */
+		tcp_read_discard(xprt, &desc);
+	} while (desc.count && xprt_connected(xprt));
+	dprintk("RPC:      tcp_data_recv done\n");
+	return len - desc.count;
 }
 
-/*
- *	data_ready callback for TCP. We can't just jump into the
- *	tcp recvmsg functions inside of the network receive bh or
- * 	bad things occur. We queue it to pick up after networking
- *	is done.
- */
- 
-static void tcp_data_ready(struct sock *sk, int len)
+static void tcp_data_ready(struct sock *sk, int bytes)
 {
-	struct rpc_xprt	*xprt;
+	struct rpc_xprt *xprt;
+	read_descriptor_t rd_desc;
 
 	dprintk("RPC:      tcp_data_ready...\n");
-	if (!(xprt = xprt_from_sock(sk)))
-	{
-		printk("Not a socket with xprt %p\n", sk);
-		goto out;
+	if (!(xprt = xprt_from_sock(sk))) {
+		printk("RPC:      tcp_data_ready socket info not found!\n");
+		return;
 	}
-
 	if (xprt->shutdown)
-		goto out;
-
-	xprt_append_pending(xprt);
+		return;
 
-	dprintk("RPC:      tcp_data_ready client %p\n", xprt);
-	dprintk("RPC:      state %x conn %d dead %d zapped %d\n",
-				sk->state, xprt_connected(xprt),
-				sk->dead, sk->zapped);
- out:
-	if (sk->sleep && waitqueue_active(sk->sleep))
-		wake_up_interruptible(sk->sleep);
+	/* We use rd_desc to pass struct xprt to tcp_data_recv */
+	rd_desc.buf = (char *)xprt;
+	rd_desc.count = 65536;
+	tcp_read_sock(sk, &rd_desc, tcp_data_recv);
 }
 
-
 static void
 tcp_state_change(struct sock *sk)
 {
@@ -1047,6 +924,13 @@
 	case TCP_ESTABLISHED:
 		if (xprt_test_and_set_connected(xprt))
 			break;
+
+		/* Reset TCP record info */
+		xprt->tcp_offset = 0;
+		xprt->tcp_reclen = 0;
+		xprt->tcp_copied = 0;
+		xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
+
 		spin_lock(&xprt->sock_lock);
 		if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending)
 			rpc_wake_up_task(xprt->snd_task);
@@ -1069,7 +953,7 @@
  * low.
  */
 static void
-tcp_write_space(struct sock *sk)
+xprt_write_space(struct sock *sk)
 {
 	struct rpc_xprt	*xprt;
 	struct socket	*sock;
@@ -1098,32 +982,6 @@
 	}
 }
 
-static void
-udp_write_space(struct sock *sk)
-{
-	struct rpc_xprt *xprt;
-
-	if (!(xprt = xprt_from_sock(sk)))
-		return;
-	if (xprt->shutdown)
-		return;
-
-
-	/* Wait until we have enough socket memory */
-	if (sock_wspace(sk) < min_t(int, sk->sndbuf,XPRT_MIN_WRITE_SPACE))
-		return;
-
-	if (!xprt_test_and_set_wspace(xprt)) {
-		spin_lock(&xprt->sock_lock);
-		if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending)
-			rpc_wake_up_task(xprt->snd_task);
-		spin_unlock(&xprt->sock_lock);
-	}
-
-	if (sk->sleep && waitqueue_active(sk->sleep))
-		wake_up_interruptible(sk->sleep);
-}
-
 /*
  * RPC receive timeout handler.
  */
@@ -1496,8 +1354,6 @@
 	req->rq_next = NULL;
 	xprt->free = xprt->slot;
 
-	INIT_LIST_HEAD(&xprt->rx_pending);
-
 	dprintk("RPC:      created transport %p\n", xprt);
 	
 	xprt_bind_socket(xprt, sock);
@@ -1542,15 +1398,14 @@
 	xprt->old_write_space = sk->write_space;
 	if (xprt->prot == IPPROTO_UDP) {
 		sk->data_ready = udp_data_ready;
-		sk->write_space = udp_write_space;
 		sk->no_check = UDP_CSUM_NORCV;
 		xprt_set_connected(xprt);
 	} else {
 		sk->data_ready = tcp_data_ready;
 		sk->state_change = tcp_state_change;
-		sk->write_space = tcp_write_space;
 		xprt_clear_connected(xprt);
 	}
+	sk->write_space = xprt_write_space;
 
 	/* Reset to new socket */
 	xprt->sock = sock;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/unix/af_unix.c linux/net/unix/af_unix.c
--- linux.orig/net/unix/af_unix.c	2002-02-25 19:38:16.000000000 +0000
+++ linux/net/unix/af_unix.c	2002-07-20 01:08:38.000000000 +0000
@@ -8,7 +8,7 @@
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
  *
- * Version:	$Id: af_unix.c,v 1.126.2.4 2002/01/14 07:07:41 davem Exp $
+ * Version:	$Id: af_unix.c,v 1.126.2.5 2002/03/05 12:47:34 davem Exp $
  *
  * Fixes:
  *		Linus Torvalds	:	Assorted bug cures.
@@ -1752,7 +1752,7 @@
 	{
 		unix_state_rlock(s);
 
-		len+=sprintf(buffer+len,"%p: %08X %08X %08X %04X %02X %5ld",
+		len+=sprintf(buffer+len,"%p: %08X %08X %08X %04X %02X %5lu",
 			s,
 			atomic_read(&s->refcnt),
 			0,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/wanrouter/af_wanpipe.c linux/net/wanrouter/af_wanpipe.c
--- linux.orig/net/wanrouter/af_wanpipe.c	2001-09-30 19:26:42.000000000 +0000
+++ linux/net/wanrouter/af_wanpipe.c	2002-07-20 01:08:35.000000000 +0000
@@ -110,7 +110,7 @@
  *         passes the packet to the driver. Before each send(), a poll
  *         routine checks the sock resources The maximum value of
  *         packet sent counter is 1, thus if one packet is queued, the
- *         application will block untill that packet is passed to the
+ *         application will block until that packet is passed to the
  *         driver.
  *
  *   RECEIVE:
@@ -121,7 +121,7 @@
  *      return code, the driver knows whether the packet was
  *      sucessfully queued.  If the socket queue is full, 
  *      protocol flow control is used by the driver, if any, 
- *      to slow down the traffic untill the sock queue is free.
+ *      to slow down the traffic until the sock queue is free.
  *
  *      Every time a packet arrives into a socket queue the 
  *      socket wakes up processes which are waiting to receive
@@ -2396,7 +2396,7 @@
 
 
 			/* Check if data buffers are pending for transmission,
-                         * if so, check wheter user wants to wait untill data
+                         * if so, check whether user wants to wait until data
                          * is transmitted, or clear a call and drop packets */
                           
 			if (atomic_read(&sk->wmem_alloc) || check_driver_busy(sk)){
@@ -2432,7 +2432,7 @@
 
 
 			/* Check if data buffers are pending for transmission,
-                         * if so, check wheter user wants to wait untill data
+                         * if so, check whether user wants to wait until data
                          * is transmitted, or reset a call and drop packets */
                           
 			if (atomic_read(&sk->wmem_alloc) || check_driver_busy(sk)){
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/net/x25/af_x25.c linux/net/x25/af_x25.c
--- linux.orig/net/x25/af_x25.c	2001-09-10 14:58:35.000000000 +0000
+++ linux/net/x25/af_x25.c	2002-07-20 01:08:34.000000000 +0000
@@ -1357,6 +1357,7 @@
 
 MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
 MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
+MODULE_LICENSE("GPL");
 
 static void __exit x25_exit(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/Menuconfig linux/scripts/Menuconfig
--- linux.orig/scripts/Menuconfig	2001-08-05 20:12:41.000000000 +0000
+++ linux/scripts/Menuconfig	2002-07-20 01:08:26.000000000 +0000
@@ -54,7 +54,7 @@
 # Change a lot of places to call set_x_info uniformly.
 # Take out message about preparing version (old sound driver cruft).
 #
-# 13 Dec 1998, Riley H Williams <rhw@memalpha.cx>
+# 13 Dec 1998, Riley H Williams <Riley@Williams.Name>
 # When an error occurs, actually display the error message as well as
 # our comments thereon.
 #
@@ -73,6 +73,10 @@
 # - Support for multiple conditions in dep_tristate().
 # - Implemented new functions: define_tristate(), define_int(), define_hex(),
 #   define_string(), dep_bool().
+#
+# 12 November 2001, Keith Owens <kaos@ocs.com.au>
+# Escape double quotes on eval so the quotes are still there on the second
+# evaluation, required to handle strings with special characters.
 # 
 
 
@@ -105,11 +109,11 @@
     eval x=\$$1
     if [ -z "$x" ]; then
 	eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" arch/$ARCH/defconfig`
-	eval x=\${$1:-"$2"}
+	eval x=\${$1:-\"$2\"}
 	eval $1=$x
 	eval INFO_$1="' (NEW)'"
     fi
-    eval info="\$INFO_$1"
+    eval info=\"\$INFO_$1\"
 }
 
 #
@@ -151,7 +155,7 @@
 }
 
 function define_string () {
-	eval $1="$2"
+	eval $1=\"$2\"
 }
 
 #
@@ -333,7 +337,7 @@
 
 	while [ -n "$2" ]
 	do
-		if eval [ "_\$$2" = "_y" ]
+		if eval [ \"_\$$2\" = \"_y\" ]
 		then
 			current=$1
 			break
@@ -548,9 +552,9 @@
 			# we avoid them:
 			if expr "$answer" : '0$' '|' "$answer" : '[1-9][0-9]*$' '|' "$answer" : '-[1-9][0-9]*$' >/dev/null
 			then
-				eval $2="$answer"
+				eval $2=\"$answer\"
 			else
-				eval $2="$3"
+				eval $2=\"$3\"
 				echo -en "\007"
 				${DIALOG} --backtitle "$backtitle" \
 					--infobox "You have made an invalid entry." 3 43
@@ -581,9 +585,9 @@
 
 			if expr "$answer" : '[0-9a-fA-F][0-9a-fA-F]*$' >/dev/null
 			then
-				eval $2="$answer"
+				eval $2=\"$answer\"
 			else
-				eval $2="$3"
+				eval $2=\"$3\"
 				echo -en "\007"
 				${DIALOG} --backtitle "$backtitle" \
 					--infobox "You have made an invalid entry." 3 43
@@ -681,9 +685,9 @@
 	do
 		if [ "$2" = "$choice" ]
 		then
-			eval $2="y"
+			eval $2=\"y\"
 		else
-			eval $2="n"
+			eval $2=\"n\"
 		fi
 		
 		shift ; shift
@@ -694,7 +698,7 @@
 # Call awk, and watch for error codes, etc.
 #
 function callawk () {
-awk "$1" || echo "Awk died with error code $?. Giving up." || exit 1
+awk "$1" || { echo "Awk died with error code $?. Giving up."; exit 1; }
 }
 
 #
@@ -946,9 +950,9 @@
 
 			[ "_" = "_$ALT_CONFIG" ] && break
 
-			if eval [ -r "$ALT_CONFIG" ]
+			if eval [ -r \"$ALT_CONFIG\" ]
 			then
-				eval load_config_file "$ALT_CONFIG"
+				eval load_config_file \"$ALT_CONFIG\"
 				break
 			else
 				echo -ne "\007"
@@ -1072,12 +1076,12 @@
 	#
 	function bool () {
 		set_x_info "$2" "n"
-		eval define_bool "$2" "$x"
+		eval define_bool \"$2\" \"$x\"
 	}
 
 	function tristate () {
 		set_x_info "$2" "n"
-		eval define_tristate "$2" "$x"
+		eval define_tristate \"$2\" \"$x\"
 	}
 
 	function dep_tristate () {
@@ -1143,19 +1147,19 @@
 	}
 
 	function define_hex () {
-		eval $1="$2"
+		eval $1=\"$2\"
                	echo "$1=$2"			>>$CONFIG
 		echo "#define $1 0x${2##*[x,X]}"	>>$CONFIG_H
 	}
 
 	function define_int () {
-		eval $1="$2"
+		eval $1=\"$2\"
 		echo "$1=$2" 			>>$CONFIG
 		echo "#define $1 ($2)"		>>$CONFIG_H
 	}
 
 	function define_string () {
-		eval $1="$2"
+		eval $1=\"$2\"
 		echo "$1=\"$2\""		>>$CONFIG
 		echo "#define $1 \"$2\""	>>$CONFIG_H
 	}
@@ -1165,7 +1169,7 @@
 	}
 
 	function define_tristate () {
-		eval $1="$2"
+		eval $1=\"$2\"
 
    		case "$2" in
          	y)
@@ -1204,7 +1208,7 @@
 		set -- $choices
 		while [ -n "$2" ]
 		do
-			if eval [ "_\$$2" = "_y" ]
+			if eval [ \"_\$$2\" = \"_y\" ]
 			then
 				current=$1
 				break
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/cramfs/GNUmakefile linux/scripts/cramfs/GNUmakefile
--- linux.orig/scripts/cramfs/GNUmakefile	2001-07-19 23:14:53.000000000 +0000
+++ linux/scripts/cramfs/GNUmakefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-CC = gcc
-CFLAGS = -W -Wall -O2 -g
-CPPFLAGS = -I../../include
-LDLIBS = -lz
-PROGS = mkcramfs cramfsck
-
-all: $(PROGS)
-
-distclean clean:
-	rm -f $(PROGS)
-
-.PHONY: all clean
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/cramfs/cramfsck.c linux/scripts/cramfs/cramfsck.c
--- linux.orig/scripts/cramfs/cramfsck.c	2001-07-19 23:14:53.000000000 +0000
+++ linux/scripts/cramfs/cramfsck.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,588 +0,0 @@
-/*
- * cramfsck - check a cramfs file system
- *
- * Copyright (C) 2000-2001 Transmeta 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
- *
- * 1999/12/03: Linus Torvalds (cramfs tester and unarchive program)
- * 2000/06/03: Daniel Quinlan (CRC and length checking program)
- * 2000/06/04: Daniel Quinlan (merged programs, added options, support
- *                            for special files, preserve permissions and
- *                            ownership, cramfs superblock v2, bogus mode
- *                            test, pathname length test, etc.)
- * 2000/06/06: Daniel Quinlan (support for holes, pretty-printing,
- *                            symlink size test)
- * 2000/07/11: Daniel Quinlan (file length tests, start at offset 0 or 512,
- *                            fsck-compatible exit codes)
- * 2000/07/15: Daniel Quinlan (initial support for block devices)
- */
-
-/* compile-time options */
-#define INCLUDE_FS_TESTS	/* include cramfs checking and extraction */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/fcntl.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <assert.h>
-#include <getopt.h>
-#include <sys/sysmacros.h>
-#include <utime.h>
-#include <sys/ioctl.h>
-#define _LINUX_STRING_H_
-#include <linux/fs.h>
-#include <linux/cramfs_fs.h>
-#include <zlib.h>
-
-static const char *progname = "cramfsck";
-
-static int fd;			/* ROM image file descriptor */
-static char *filename;		/* ROM image filename */
-struct cramfs_super *super;	/* just find the cramfs superblock once */
-static int opt_verbose = 0;	/* 1 = verbose (-v), 2+ = very verbose (-vv) */
-#ifdef INCLUDE_FS_TESTS
-static int opt_extract = 0;	/* extract cramfs (-x) */
-char *extract_dir = NULL;	/* extraction directory (-x) */
-
-unsigned long start_inode = 1 << 28;	/* start of first non-root inode */
-unsigned long end_inode = 0;		/* end of the directory structure */
-unsigned long start_data = 1 << 28;	/* start of the data (256 MB = max) */
-unsigned long end_data = 0;		/* end of the data */
-/* true?  cramfs_super < start_inode < end_inode <= start_data <= end_data */
-static uid_t euid;			/* effective UID */
-
-#define PAD_SIZE 512
-#define PAGE_CACHE_SIZE (4096)
-
-/* Guarantee access to at least 8kB at a time */
-#define ROMBUFFER_BITS	13
-#define ROMBUFFERSIZE	(1 << ROMBUFFER_BITS)
-#define ROMBUFFERMASK	(ROMBUFFERSIZE-1)
-static char read_buffer[ROMBUFFERSIZE * 2];
-static unsigned long read_buffer_block = ~0UL;
-
-/* Uncompressing data structures... */
-static char outbuffer[PAGE_CACHE_SIZE*2];
-z_stream stream;
-
-#endif /* INCLUDE_FS_TESTS */
-
-/* Input status of 0 to print help and exit without an error. */
-static void usage(int status)
-{
-	FILE *stream = status ? stderr : stdout;
-
-	fprintf(stream, "usage: %s [-hv] [-x dir] file\n"
-		" -h         print this help\n"
-		" -x dir     extract into dir\n"
-		" -v         be more verbose\n"
-		" file       file to test\n", progname);
-
-	exit(status);
-}
-
-#ifdef INCLUDE_FS_TESTS
-void print_node(char type, struct cramfs_inode *i, char *name)
-{
-	char info[10];
-
-	if (S_ISCHR(i->mode) || (S_ISBLK(i->mode))) {
-		/* major/minor numbers can be as high as 2^12 or 4096 */
-		snprintf(info, 10, "%4d,%4d", major(i->size), minor(i->size));
-	}
-	else {
-		/* size be as high as 2^24 or 16777216 */
-		snprintf(info, 10, "%9d", i->size);
-	}
-
-	printf("%c %04o %s %5d:%-3d %s\n",
-	       type, i->mode & ~S_IFMT, info, i->uid, i->gid, name);
-}
-
-/*
- * Create a fake "blocked" access
- */
-static void *romfs_read(unsigned long offset)
-{
-	unsigned int block = offset >> ROMBUFFER_BITS;
-	if (block != read_buffer_block) {
-		read_buffer_block = block;
-		lseek(fd, block << ROMBUFFER_BITS, SEEK_SET);
-		read(fd, read_buffer, ROMBUFFERSIZE * 2);
-	}
-	return read_buffer + (offset & ROMBUFFERMASK);
-}
-
-static struct cramfs_inode *cramfs_iget(struct cramfs_inode * i)
-{
-	struct cramfs_inode *inode = malloc(sizeof(struct cramfs_inode));
-	*inode = *i;
-	return inode;
-}
-
-static struct cramfs_inode *iget(unsigned int ino)
-{
-	return cramfs_iget(romfs_read(ino));
-}
-
-void iput(struct cramfs_inode *inode)
-{
-	free(inode);
-}
-
-/*
- * Return the offset of the root directory,
- * or 0 if none.
- */
-static struct cramfs_inode *read_super(void)
-{
-	unsigned long offset;
-
-	offset = super->root.offset << 2;
-	if (super->magic != CRAMFS_MAGIC)
-		return NULL;
-	if (memcmp(super->signature, CRAMFS_SIGNATURE, sizeof(super->signature)) != 0)
-		return NULL;
-	if (offset < sizeof(super))
-		return NULL;
-	return cramfs_iget(&super->root);
-}
-
-static int uncompress_block(void *src, int len)
-{
-	int err;
-
-	stream.next_in = src;
-	stream.avail_in = len;
-
-	stream.next_out = (unsigned char *) outbuffer;
-	stream.avail_out = PAGE_CACHE_SIZE*2;
-
-	inflateReset(&stream);
-
-	err = inflate(&stream, Z_FINISH);
-	if (err != Z_STREAM_END) {
-		fprintf(stderr, "%s: error %d while decompressing! %p(%d)\n",
-			filename, err, src, len);
-		exit(4);
-	}
-	return stream.total_out;
-}
-
-static void change_file_status(char *path, struct cramfs_inode *i)
-{
-	struct utimbuf epoch = { 0, 0 };
-
-	if (euid == 0) {
-		if (lchown(path, i->uid, i->gid) < 0) {
-			perror(path);
-			exit(8);
-		}
-		if (S_ISLNK(i->mode))
-			return;
-		if ((S_ISUID | S_ISGID) & i->mode) {
-			if (chmod(path, i->mode) < 0) {
-				perror(path);
-				exit(8);
-			}
-		}
-	}
-	if (S_ISLNK(i->mode))
-		return;
-	if (utime(path, &epoch) < 0) {
-		perror(path);
-		exit(8);
-	}
-}
-
-static void do_symlink(char *path, struct cramfs_inode *i)
-{
-	unsigned long offset = i->offset << 2;
-	unsigned long curr = offset + 4;
-	unsigned long next = *(u32 *) romfs_read(offset);
-	unsigned long size;
-
-	if (next > end_data) {
-		end_data = next;
-	}
-
-	size = uncompress_block(romfs_read(curr), next - curr);
-	if (size != i->size) {
-		fprintf(stderr, "%s: size error in symlink `%s'\n",
-			filename, path);
-		exit(4);
-	}
-	outbuffer[size] = 0;
-	if (opt_verbose) {
-		char *str;
-
-		str = malloc(strlen(outbuffer) + strlen(path) + 5);
-		strcpy(str, path);
-		strncat(str, " -> ", 4);
-		strncat(str, outbuffer, size);
-
-		print_node('l', i, str);
-		if (opt_verbose > 1) {
-			printf("  uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr);
-		}
-	}
-	if (opt_extract) {
-		symlink(outbuffer, path);
-		change_file_status(path, i);
-	}
-}
-
-static void do_special_inode(char *path, struct cramfs_inode *i)
-{
-	dev_t devtype = 0;
-	char type;
-
-	if (S_ISCHR(i->mode)) {
-		devtype = i->size;
-		type = 'c';
-	}
-	else if (S_ISBLK(i->mode)) {
-		devtype = i->size;
-		type = 'b';
-	}
-	else if (S_ISFIFO(i->mode))
-		type = 'p';
-	else if (S_ISSOCK(i->mode))
-		type = 's';
-	else {
-		fprintf(stderr, "%s: bogus mode on `%s' (%o)\n", filename, path, i->mode);
-		exit(4);
-	}
-
-	if (opt_verbose) {
-		print_node(type, i, path);
-	}
-
-	if (opt_extract) {
-		if (mknod(path, i->mode, devtype) < 0) {
-			perror(path);
-			exit(8);
-		}
-		change_file_status(path, i);
-	}
-}
-
-static void do_uncompress(int fd, unsigned long offset, unsigned long size)
-{
-	unsigned long curr = offset + 4 * ((size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE);
-
-	do {
-		unsigned long out = PAGE_CACHE_SIZE;
-		unsigned long next = *(u32 *) romfs_read(offset);
-
-		if (next > end_data) {
-			end_data = next;
-		}
-
-		offset += 4;
-		if (curr == next) {
-			if (opt_verbose > 1) {
-				printf("  hole at %ld (%d)\n", curr, PAGE_CACHE_SIZE);
-			}
-			if (size < PAGE_CACHE_SIZE)
-				out = size;
-			memset(outbuffer, 0x00, out);
-		}
-		else {
-			if (opt_verbose > 1) {
-				printf("  uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr);
-			}
-			out = uncompress_block(romfs_read(curr), next - curr);
-		}
-		if (size >= PAGE_CACHE_SIZE) {
-			if (out != PAGE_CACHE_SIZE) {
-				fprintf(stderr, "%s: Non-block (%ld) bytes\n", filename, out);
-				exit(4);
-			}
-		} else {
-			if (out != size) {
-				fprintf(stderr, "%s: Non-size (%ld vs %ld) bytes\n", filename, out, size);
-				exit(4);
-			}
-		}
-		size -= out;
-		if (opt_extract) {
-			write(fd, outbuffer, out);
-		}
-		curr = next;
-	} while (size);
-}
-
-static void expand_fs(int pathlen, char *path, struct cramfs_inode *inode)
-{
-	if (S_ISDIR(inode->mode)) {
-		int count = inode->size;
-		unsigned long offset = inode->offset << 2;
-		char *newpath = malloc(pathlen + 256);
-
-		if (count > 0 && offset < start_inode) {
-			start_inode = offset;
-		}
-		/* XXX - need to check end_inode for empty case? */
-		memcpy(newpath, path, pathlen);
-		newpath[pathlen] = '/';
-		pathlen++;
-		if (opt_verbose) {
-			print_node('d', inode, path);
-		}
-		if (opt_extract) {
-			mkdir(path, inode->mode);
-			change_file_status(path, inode);
-		}
-		while (count > 0) {
-			struct cramfs_inode *child = iget(offset);
-			int size;
-			int newlen = child->namelen << 2;
-
-			size = sizeof(struct cramfs_inode) + newlen;
-			count -= size;
-
-			offset += sizeof(struct cramfs_inode);
-
-			memcpy(newpath + pathlen, romfs_read(offset), newlen);
-			newpath[pathlen + newlen] = 0;
-			if ((pathlen + newlen) - strlen(newpath) > 3) {
-				fprintf(stderr, "%s: invalid cramfs--bad path length\n", filename);
-				exit(4);
-			}
-			expand_fs(strlen(newpath), newpath, child);
-
-			offset += newlen;
-
-			if (offset > end_inode) {
-				end_inode = offset;
-			}
-		}
-		return;
-	}
-	if (S_ISREG(inode->mode)) {
-		int fd = 0;
-		unsigned long offset = inode->offset << 2;
-
-		if (offset > 0 && offset < start_data) {
-			start_data = offset;
-		}
-		if (opt_verbose) {
-			print_node('f', inode, path);
-		}
-		if (opt_extract) {
-			fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, inode->mode);
-		}
-		if (inode->size) {
-			do_uncompress(fd, offset, inode->size);
-		}
-		if (opt_extract) {
-			close(fd);
-			change_file_status(path, inode);
-		}
-		return;
-	}
-	if (S_ISLNK(inode->mode)) {
-		unsigned long offset = inode->offset << 2;
-
-		if (offset < start_data) {
-			start_data = offset;
-		}
-		do_symlink(path, inode);
-		return;
-	}
-	else {
-		do_special_inode(path, inode);
-		return;
-	}
-}
-#endif /* INCLUDE_FS_TESTS */
-
-int main(int argc, char **argv)
-{
-	void *buf;
-	size_t length;
-	struct stat st;
-	u32 crc_old, crc_new;
-#ifdef INCLUDE_FS_TESTS
-	struct cramfs_inode *root;
-#endif /* INCLUDE_FS_TESTS */
-	int c;			/* for getopt */
-	int start = 0;
-
-	if (argc)
-		progname = argv[0];
-
-	/* command line options */
-	while ((c = getopt(argc, argv, "hx:v")) != EOF) {
-		switch (c) {
-		case 'h':
-			usage(0);
-		case 'x':
-#ifdef INCLUDE_FS_TESTS
-			opt_extract = 1;
-			extract_dir = malloc(strlen(optarg) + 1);
-			strcpy(extract_dir, optarg);
-			break;
-#else /*  not INCLUDE_FS_TESTS */
-			fprintf(stderr, "%s: compiled without -x support\n",
-				progname);
-			exit(16);
-#endif /* not INCLUDE_FS_TESTS */
-		case 'v':
-			opt_verbose++;
-			break;
-		}
-	}
-
-	if ((argc - optind) != 1)
-		usage(16);
-	filename = argv[optind];
-
-	/* find the physical size of the file or block device */
-	if (lstat(filename, &st) < 0) {
-		perror(filename);
-		exit(8);
-	}
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		perror(filename);
-		exit(8);
-	}
-	if (S_ISBLK(st.st_mode)) {
-		if (ioctl(fd, BLKGETSIZE, &length) < 0) {
-			fprintf(stderr, "%s: warning--unable to determine filesystem size \n", filename);
-			exit(4);
-		}
-		length = length * 512;
-	}
-	else if (S_ISREG(st.st_mode)) {
-		length = st.st_size;
-	}
-	else {
-		fprintf(stderr, "%s is not a block device or file\n", filename);
-		exit(8);
-	}
-
-	if (length < sizeof(struct cramfs_super)) {
-		fprintf(stderr, "%s: invalid cramfs--file length too short\n", filename);
-		exit(4);
-	}
-
-	if (S_ISBLK(st.st_mode)) {
-		/* nasty because mmap of block devices fails */
-		buf = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-		read(fd, buf, length);
-	}
-	else {
-		/* nice and easy */
-		buf = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
-	}
-
-	/* XXX - this could be cleaner... */
-	if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) {
-		start = 0;
-		super = (struct cramfs_super *) buf;
-	}
-	else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) &&
-		 ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC)))
-	{
-		start = PAD_SIZE;
-		super = (struct cramfs_super *) (buf + PAD_SIZE);
-	}
-	else {
-		fprintf(stderr, "%s: invalid cramfs--wrong magic\n", filename);
-		exit(4);
-	}
-
-	if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) {
-		/* length test */
-		if (length < super->size) {
-			fprintf(stderr, "%s: invalid cramfs--file length too short\n", filename);
-			exit(4);
-		}
-		else if (length > super->size) {
-			fprintf(stderr, "%s: warning--file length too long, padded image?\n", filename);
-		}
-
-		/* CRC test */
-		crc_old = super->fsid.crc;
-		super->fsid.crc = crc32(0L, Z_NULL, 0);
-		crc_new = crc32(0L, Z_NULL, 0);
-		crc_new = crc32(crc_new, (unsigned char *) buf+start, super->size - start);
-		if (crc_new != crc_old) {
-			fprintf(stderr, "%s: invalid cramfs--crc error\n", filename);
-			exit(4);
-		}
-	}
-	else {
-		fprintf(stderr, "%s: warning--old cramfs image, no CRC\n",
-			filename);
-	}
-
-#ifdef INCLUDE_FS_TESTS
-	super = (struct cramfs_super *) malloc(sizeof(struct cramfs_super));
-	if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) {
-		memcpy(super, buf, sizeof(struct cramfs_super));
-	}
-	else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) &&
-		 ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC)))
-	{
-		memcpy(super, (buf + PAD_SIZE), sizeof(struct cramfs_super));
-	}
-
-	munmap(buf, length);
-
-	/* file format test, uses fake "blocked" accesses */
-	root = read_super();
-	umask(0);
-	euid = geteuid();
-	if (!root) {
-		fprintf(stderr, "%s: invalid cramfs--bad superblock\n",
-			filename);
-		exit(4);
-	}
-	stream.next_in = NULL;
-	stream.avail_in = 0;
-	inflateInit(&stream);
-
-	if (!extract_dir) {
-		extract_dir = "root";
-	}
-
-	expand_fs(strlen(extract_dir), extract_dir, root);
-	inflateEnd(&stream);
-
-	if (start_data != 1 << 28  && end_inode != start_data) {
-		fprintf(stderr, "%s: invalid cramfs--directory data end (%ld) != file data start (%ld)\n", filename, end_inode, start_data);
-		exit(4);
-	}
-	if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) {
-		if (end_data > super->size) {
-			fprintf(stderr, "%s: invalid cramfs--invalid file data offset\n", filename);
-			exit(4);
-		}
-	}
-#endif /* INCLUDE_FS_TESTS */
-
-	exit(0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/cramfs/mkcramfs.c linux/scripts/cramfs/mkcramfs.c
--- linux.orig/scripts/cramfs/mkcramfs.c	2001-07-19 23:14:53.000000000 +0000
+++ linux/scripts/cramfs/mkcramfs.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,776 +0,0 @@
-/*
- * mkcramfs - make a cramfs file system
- *
- * Copyright (C) 1999-2001 Transmeta 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
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/fcntl.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <assert.h>
-#include <getopt.h>
-#include <linux/cramfs_fs.h>
-#include <zlib.h>
-
-#define PAD_SIZE 512		/* only 0 and 512 supported by kernel */
-
-static const char *progname = "mkcramfs";
-
-/* N.B. If you change the disk format of cramfs, please update fs/cramfs/README. */
-
-/* Input status of 0 to print help and exit without an error. */
-static void usage(int status)
-{
-	FILE *stream = status ? stderr : stdout;
-
-	fprintf(stream, "usage: %s [-h] [-e edition] [-i file] [-n name] dirname outfile\n"
-		" -h         print this help\n"
-		" -E         make all warnings errors (non-zero exit status)\n"
-		" -e edition set edition number (part of fsid)\n"
-		" -i file    insert a file image into the filesystem (requires >= 2.4.0)\n"
-		" -n name    set name of cramfs filesystem\n"
-		" -p         pad by %d bytes for boot code\n"
-		" -s         sort directory entries (old option, ignored)\n"
-		" -z         make explicit holes (requires >= 2.3.39)\n"
-		" dirname    root of the filesystem to be compressed\n"
-		" outfile    output file\n", progname, PAD_SIZE);
-
-	exit(status);
-}
-
-#define PAGE_CACHE_SIZE (4096)
-/* The kernel assumes PAGE_CACHE_SIZE as block size. */
-static unsigned int blksize = PAGE_CACHE_SIZE;
-static long total_blocks = 0, total_nodes = 1; /* pre-count the root node */
-static int image_length = 0;
-
-/*
- * If opt_holes is set, then mkcramfs can create explicit holes in the
- * data, which saves 26 bytes per hole (which is a lot smaller a
- * saving than most most filesystems).
- *
- * Note that kernels up to at least 2.3.39 don't support cramfs holes,
- * which is why this is turned off by default.
- */
-static int opt_edition = 0;
-static int opt_errors = 0;
-static int opt_holes = 0;
-static int opt_pad = 0;
-static char *opt_image = NULL;
-static char *opt_name = NULL;
-
-static int warn_dev, warn_gid, warn_namelen, warn_skip, warn_size, warn_uid;
-
-#ifndef MIN
-# define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
-#endif
-
-/* In-core version of inode / directory entry. */
-struct entry {
-	/* stats */
-	char *name;
-	unsigned int mode, size, uid, gid;
-
-	/* FS data */
-	void *uncompressed;
-        /* points to other identical file */
-        struct entry *same;
-        unsigned int offset;            /* pointer to compressed data in archive */
-	unsigned int dir_offset;	/* Where in the archive is the directory entry? */
-
-	/* organization */
-	struct entry *child; /* null for non-directories and empty directories */
-	struct entry *next;
-};
-
-/*
- * The longest file name component to allow for in the input directory tree.
- * Ext2fs (and many others) allow up to 255 bytes.  A couple of filesystems
- * allow longer (e.g. smbfs 1024), but there isn't much use in supporting
- * >255-byte names in the input directory tree given that such names get
- * truncated to 255 bytes when written to cramfs.
- */
-#define MAX_INPUT_NAMELEN 255
-
-static int find_identical_file(struct entry *orig,struct entry *newfile)
-{
-        if(orig==newfile) return 1;
-        if(!orig) return 0;
-        if(orig->size==newfile->size && orig->uncompressed && !memcmp(orig->uncompressed,newfile->uncompressed,orig->size)) {
-                newfile->same=orig;
-                return 1;
-        }
-        return find_identical_file(orig->child,newfile) ||
-                   find_identical_file(orig->next,newfile);
-}
-
-static void eliminate_doubles(struct entry *root,struct entry *orig) {
-        if(orig) {
-                if(orig->size && orig->uncompressed)
-			find_identical_file(root,orig);
-                eliminate_doubles(root,orig->child);
-                eliminate_doubles(root,orig->next);
-        }
-}
-
-/*
- * We define our own sorting function instead of using alphasort which
- * uses strcoll and changes ordering based on locale information.
- */
-static int cramsort (const void *a, const void *b)
-{
-	return strcmp ((*(const struct dirent **) a)->d_name,
-		       (*(const struct dirent **) b)->d_name);
-}
-
-static unsigned int parse_directory(struct entry *root_entry, const char *name, struct entry **prev, loff_t *fslen_ub)
-{
-	struct dirent **dirlist;
-	int totalsize = 0, dircount, dirindex;
-	char *path, *endpath;
-	size_t len = strlen(name);
-
-	/* Set up the path. */
-	/* TODO: Reuse the parent's buffer to save memcpy'ing and duplication. */
-	path = malloc(len + 1 + MAX_INPUT_NAMELEN + 1);
-	if (!path) {
-		perror(NULL);
-		exit(8);
-	}
-	memcpy(path, name, len);
-	endpath = path + len;
-	*endpath = '/';
-	endpath++;
-
-        /* read in the directory and sort */
-        dircount = scandir(name, &dirlist, 0, cramsort);
-
-	if (dircount < 0) {
-		perror(name);
-		exit(8);
-	}
-
-	/* process directory */
-	for (dirindex = 0; dirindex < dircount; dirindex++) {
-		struct dirent *dirent;
-		struct entry *entry;
-		struct stat st;
-		int size;
-		size_t namelen;
-
-		dirent = dirlist[dirindex];
-
-		/* Ignore "." and ".." - we won't be adding them to the archive */
-		if (dirent->d_name[0] == '.') {
-			if (dirent->d_name[1] == '\0')
-				continue;
-			if (dirent->d_name[1] == '.') {
-				if (dirent->d_name[2] == '\0')
-					continue;
-			}
-		}
-		namelen = strlen(dirent->d_name);
-		if (namelen > MAX_INPUT_NAMELEN) {
-			fprintf(stderr,
-				"Very long (%u bytes) filename `%s' found.\n"
-				" Please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile.  Exiting.\n",
-				namelen, dirent->d_name);
-			exit(8);
-		}
-		memcpy(endpath, dirent->d_name, namelen + 1);
-
-		if (lstat(path, &st) < 0) {
-			perror(endpath);
-			warn_skip = 1;
-			continue;
-		}
-		entry = calloc(1, sizeof(struct entry));
-		if (!entry) {
-			perror(NULL);
-			exit(8);
-		}
-		entry->name = strdup(dirent->d_name);
-		if (!entry->name) {
-			perror(NULL);
-			exit(8);
-		}
-		if (namelen > 255) {
-			/* Can't happen when reading from ext2fs. */
-
-			/* TODO: we ought to avoid chopping in half
-			   multi-byte UTF8 characters. */
-			entry->name[namelen = 255] = '\0';
-			warn_namelen = 1;
-		}
-		entry->mode = st.st_mode;
-		entry->size = st.st_size;
-		entry->uid = st.st_uid;
-		if (entry->uid >= 1 << CRAMFS_UID_WIDTH)
-			warn_uid = 1;
-		entry->gid = st.st_gid;
-		if (entry->gid >= 1 << CRAMFS_GID_WIDTH)
-			/* TODO: We ought to replace with a default
-                           gid instead of truncating; otherwise there
-                           are security problems.  Maybe mode should
-                           be &= ~070.  Same goes for uid once Linux
-                           supports >16-bit uids. */
-			warn_gid = 1;
-		size = sizeof(struct cramfs_inode) + ((namelen + 3) & ~3);
-		*fslen_ub += size;
-		if (S_ISDIR(st.st_mode)) {
-			entry->size = parse_directory(root_entry, path, &entry->child, fslen_ub);
-		} else if (S_ISREG(st.st_mode)) {
-			/* TODO: We ought to open files in do_compress, one
-			   at a time, instead of amassing all these memory
-			   maps during parse_directory (which don't get used
-			   until do_compress anyway).  As it is, we tend to
-			   get EMFILE errors (especially if mkcramfs is run
-			   by non-root).
-
-			   While we're at it, do analagously for symlinks
-			   (which would just save a little memory). */
-			int fd = open(path, O_RDONLY);
-			if (fd < 0) {
-				perror(path);
-				warn_skip = 1;
-				continue;
-			}
-			if (entry->size) {
-				if ((entry->size >= 1 << CRAMFS_SIZE_WIDTH)) {
-					warn_size = 1;
-					entry->size = (1 << CRAMFS_SIZE_WIDTH) - 1;
-				}
-
-				entry->uncompressed = mmap(NULL, entry->size, PROT_READ, MAP_PRIVATE, fd, 0);
-				if (-1 == (int) (long) entry->uncompressed) {
-					perror("mmap");
-					exit(8);
-				}
-			}
-			close(fd);
-		} else if (S_ISLNK(st.st_mode)) {
-			entry->uncompressed = malloc(entry->size);
-			if (!entry->uncompressed) {
-				perror(NULL);
-				exit(8);
-			}
-			if (readlink(path, entry->uncompressed, entry->size) < 0) {
-				perror(path);
-				warn_skip = 1;
-				continue;
-			}
-		} else if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
-			/* maybe we should skip sockets */
-			entry->size = 0;
-		} else {
-			entry->size = st.st_rdev;
-			if (entry->size & -(1<<CRAMFS_SIZE_WIDTH))
-				warn_dev = 1;
-		}
-
-		if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
-			int blocks = ((entry->size - 1) / blksize + 1);
-
-			/* block pointers & data expansion allowance + data */
-			if(entry->size)
-				*fslen_ub += (4+26)*blocks + entry->size + 3;
-                }
-
-		/* Link it into the list */
-		*prev = entry;
-		prev = &entry->next;
-		totalsize += size;
-	}
-	free(path);
-	free(dirlist);		/* allocated by scandir() with malloc() */
-	return totalsize;
-}
-
-/* Returns sizeof(struct cramfs_super), which includes the root inode. */
-static unsigned int write_superblock(struct entry *root, char *base, int size)
-{
-	struct cramfs_super *super = (struct cramfs_super *) base;
-	unsigned int offset = sizeof(struct cramfs_super) + image_length;
-
-	if (opt_pad) {
-		offset += opt_pad;
-	}
-
-	super->magic = CRAMFS_MAGIC;
-	super->flags = CRAMFS_FLAG_FSID_VERSION_2 | CRAMFS_FLAG_SORTED_DIRS;
-	if (opt_holes)
-		super->flags |= CRAMFS_FLAG_HOLES;
-	if (image_length > 0)
-		super->flags |= CRAMFS_FLAG_SHIFTED_ROOT_OFFSET;
-	super->size = size;
-	memcpy(super->signature, CRAMFS_SIGNATURE, sizeof(super->signature));
-
-	super->fsid.crc = crc32(0L, Z_NULL, 0);
-	super->fsid.edition = opt_edition;
-	super->fsid.blocks = total_blocks;
-	super->fsid.files = total_nodes;
-
-	memset(super->name, 0x00, sizeof(super->name));
-	if (opt_name)
-		strncpy(super->name, opt_name, sizeof(super->name));
-	else
-		strncpy(super->name, "Compressed", sizeof(super->name));
-
-	super->root.mode = root->mode;
-	super->root.uid = root->uid;
-	super->root.gid = root->gid;
-	super->root.size = root->size;
-	super->root.offset = offset >> 2;
-
-	return offset;
-}
-
-static void set_data_offset(struct entry *entry, char *base, unsigned long offset)
-{
-	struct cramfs_inode *inode = (struct cramfs_inode *) (base + entry->dir_offset);
-#ifdef DEBUG
-	assert ((offset & 3) == 0);
-#endif /* DEBUG */
-	if (offset >= (1 << (2 + CRAMFS_OFFSET_WIDTH))) {
-		fprintf(stderr, "filesystem too big.  Exiting.\n");
-		exit(8);
-	}
-	inode->offset = (offset >> 2);
-}
-
-
-/*
- * We do a width-first printout of the directory
- * entries, using a stack to remember the directories
- * we've seen.
- */
-#define MAXENTRIES (100)
-static unsigned int write_directory_structure(struct entry *entry, char *base, unsigned int offset)
-{
-	int stack_entries = 0;
-	struct entry *entry_stack[MAXENTRIES];
-
-	for (;;) {
-		int dir_start = stack_entries;
-		while (entry) {
-			struct cramfs_inode *inode = (struct cramfs_inode *) (base + offset);
-			size_t len = strlen(entry->name);
-
-			entry->dir_offset = offset;
-
-			inode->mode = entry->mode;
-			inode->uid = entry->uid;
-			inode->gid = entry->gid;
-			inode->size = entry->size;
-			inode->offset = 0;
-			/* Non-empty directories, regfiles and symlinks will
-			   write over inode->offset later. */
-
-			offset += sizeof(struct cramfs_inode);
-			total_nodes++;	/* another node */
-			memcpy(base + offset, entry->name, len);
-			/* Pad up the name to a 4-byte boundary */
-			while (len & 3) {
-				*(base + offset + len) = '\0';
-				len++;
-			}
-			inode->namelen = len >> 2;
-			offset += len;
-
-			/* TODO: this may get it wrong for chars >= 0x80.
-			   Most filesystems use UTF8 encoding for filenames,
-			   whereas the console is a single-byte character
-			   set like iso-latin-1. */
-			printf("  %s\n", entry->name);
-			if (entry->child) {
-				if (stack_entries >= MAXENTRIES) {
-					fprintf(stderr, "Exceeded MAXENTRIES.  Raise this value in mkcramfs.c and recompile.  Exiting.\n");
-					exit(8);
-				}
-				entry_stack[stack_entries] = entry;
-				stack_entries++;
-			}
-			entry = entry->next;
-		}
-
-		/*
-		 * Reverse the order the stack entries pushed during
-                 * this directory, for a small optimization of disk
-                 * access in the created fs.  This change makes things
-                 * `ls -UR' order.
-		 */
-		{
-			struct entry **lo = entry_stack + dir_start;
-			struct entry **hi = entry_stack + stack_entries;
-			struct entry *tmp;
-
-			while (lo < --hi) {
-				tmp = *lo;
-				*lo++ = *hi;
-				*hi = tmp;
-			}
-		}
-
-		/* Pop a subdirectory entry from the stack, and recurse. */
-		if (!stack_entries)
-			break;
-		stack_entries--;
-		entry = entry_stack[stack_entries];
-
-		set_data_offset(entry, base, offset);
-		printf("'%s':\n", entry->name);
-		entry = entry->child;
-	}
-	return offset;
-}
-
-static int is_zero(char const *begin, unsigned len)
-{
-	if (opt_holes)
-		/* Returns non-zero iff the first LEN bytes from BEGIN are
-		   all NULs. */
-		return (len-- == 0 ||
-			(begin[0] == '\0' &&
-			 (len-- == 0 ||
-			  (begin[1] == '\0' &&
-			   (len-- == 0 ||
-			    (begin[2] == '\0' &&
-			     (len-- == 0 ||
-			      (begin[3] == '\0' &&
-			       memcmp(begin, begin + 4, len) == 0))))))));
-	else
-		/* Never create holes. */
-		return 0;
-}
-
-/*
- * One 4-byte pointer per block and then the actual blocked
- * output. The first block does not need an offset pointer,
- * as it will start immediately after the pointer block;
- * so the i'th pointer points to the end of the i'th block
- * (i.e. the start of the (i+1)'th block or past EOF).
- *
- * Note that size > 0, as a zero-sized file wouldn't ever
- * have gotten here in the first place.
- */
-static unsigned int do_compress(char *base, unsigned int offset, char const *name, char *uncompressed, unsigned int size)
-{
-	unsigned long original_size = size;
-	unsigned long original_offset = offset;
-	unsigned long new_size;
-	unsigned long blocks = (size - 1) / blksize + 1;
-	unsigned long curr = offset + 4 * blocks;
-	int change;
-
-	total_blocks += blocks;
-
-	do {
-		unsigned long len = 2 * blksize;
-		unsigned int input = size;
-		if (input > blksize)
-			input = blksize;
-		size -= input;
-		if (!is_zero (uncompressed, input)) {
-			compress(base + curr, &len, uncompressed, input);
-			curr += len;
-		}
-		uncompressed += input;
-
-		if (len > blksize*2) {
-			/* (I don't think this can happen with zlib.) */
-			printf("AIEEE: block \"compressed\" to > 2*blocklength (%ld)\n", len);
-			exit(8);
-		}
-
-		*(u32 *) (base + offset) = curr;
-		offset += 4;
-	} while (size);
-
-	curr = (curr + 3) & ~3;
-	new_size = curr - original_offset;
-	/* TODO: Arguably, original_size in these 2 lines should be
-	   st_blocks * 512.  But if you say that then perhaps
-	   administrative data should also be included in both. */
-	change = new_size - original_size;
-	printf("%6.2f%% (%+d bytes)\t%s\n",
-	       (change * 100) / (double) original_size, change, name);
-
-	return curr;
-}
-
-
-/*
- * Traverse the entry tree, writing data for every item that has
- * non-null entry->compressed (i.e. every symlink and non-empty
- * regfile).
- */
-static unsigned int write_data(struct entry *entry, char *base, unsigned int offset)
-{
-	do {
-		if (entry->uncompressed) {
-                        if(entry->same) {
-                                set_data_offset(entry, base, entry->same->offset);
-                                entry->offset=entry->same->offset;
-                        } else {
-                                set_data_offset(entry, base, offset);
-                                entry->offset=offset;
-                                offset = do_compress(base, offset, entry->name, entry->uncompressed, entry->size);
-                        }
-		}
-		else if (entry->child)
-			offset = write_data(entry->child, base, offset);
-                entry=entry->next;
-	} while (entry);
-	return offset;
-}
-
-static unsigned int write_file(char *file, char *base, unsigned int offset)
-{
-	int fd;
-	char *buf;
-
-	fd = open(file, O_RDONLY);
-	if (fd < 0) {
-		perror(file);
-		exit(8);
-	}
-	buf = mmap(NULL, image_length, PROT_READ, MAP_PRIVATE, fd, 0);
-	memcpy(base + offset, buf, image_length);
-	munmap(buf, image_length);
-	close (fd);
-	/* Pad up the image_length to a 4-byte boundary */
-	while (image_length & 3) {
-		*(base + offset + image_length) = '\0';
-		image_length++;
-	}
-	return (offset + image_length);
-}
-
-/*
- * Maximum size fs you can create is roughly 256MB.  (The last file's
- * data must begin within 256MB boundary but can extend beyond that.)
- *
- * Note that if you want it to fit in a ROM then you're limited to what the
- * hardware and kernel can support (64MB?).
- */
-#define MAXFSLEN ((((1 << CRAMFS_OFFSET_WIDTH) - 1) << 2) /* offset */ \
-		  + (1 << CRAMFS_SIZE_WIDTH) - 1 /* filesize */ \
-		  + (1 << CRAMFS_SIZE_WIDTH) * 4 / PAGE_CACHE_SIZE /* block pointers */ )
-
-
-/*
- * Usage:
- *
- *      mkcramfs directory-name outfile
- *
- * where "directory-name" is simply the root of the directory
- * tree that we want to generate a compressed filesystem out
- * of.
- */
-int main(int argc, char **argv)
-{
-	struct stat st;		/* used twice... */
-	struct entry *root_entry;
-	char *rom_image;
-	ssize_t offset, written;
-	int fd;
-	/* initial guess (upper-bound) of required filesystem size */
-	loff_t fslen_ub = sizeof(struct cramfs_super);
-	char const *dirname, *outfile;
-	u32 crc = crc32(0L, Z_NULL, 0);
-	int c;			/* for getopt */
-
-	total_blocks = 0;
-
-	if (argc)
-		progname = argv[0];
-
-	/* command line options */
-	while ((c = getopt(argc, argv, "hEe:i:n:psz")) != EOF) {
-		switch (c) {
-		case 'h':
-			usage(0);
-		case 'E':
-			opt_errors = 1;
-			break;
-		case 'e':
-			opt_edition = atoi(optarg);
-			break;
-		case 'i':
-			opt_image = optarg;
-			if (lstat(opt_image, &st) < 0) {
-				perror(opt_image);
-				exit(16);
-			}
-			image_length = st.st_size; /* may be padded later */
-			fslen_ub += (image_length + 3); /* 3 is for padding */
-			break;
-		case 'n':
-			opt_name = optarg;
-			break;
-		case 'p':
-			opt_pad = PAD_SIZE;
-			fslen_ub += PAD_SIZE;
-			break;
-		case 's':
-			/* old option, ignored */
-			break;
-		case 'z':
-			opt_holes = 1;
-			break;
-		}
-	}
-
-	if ((argc - optind) != 2)
-		usage(16);
-	dirname = argv[optind];
-	outfile = argv[optind + 1];
-
-	if (stat(dirname, &st) < 0) {
-		perror(dirname);
-		exit(16);
-	}
-	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
-
-	root_entry = calloc(1, sizeof(struct entry));
-	if (!root_entry) {
-		perror(NULL);
-		exit(8);
-	}
-	root_entry->mode = st.st_mode;
-	root_entry->uid = st.st_uid;
-	root_entry->gid = st.st_gid;
-
-	root_entry->size = parse_directory(root_entry, dirname, &root_entry->child, &fslen_ub);
-
-	/* always allocate a multiple of blksize bytes because that's
-           what we're going to write later on */
-	fslen_ub = ((fslen_ub - 1) | (blksize - 1)) + 1;
-
-	if (fslen_ub > MAXFSLEN) {
-		fprintf(stderr,
-			"warning: guestimate of required size (upper bound) is %LdMB, but maximum image size is %uMB.  We might die prematurely.\n",
-			fslen_ub >> 20,
-			MAXFSLEN >> 20);
-		fslen_ub = MAXFSLEN;
-	}
-
-        /* find duplicate files. TODO: uses the most inefficient algorithm
-           possible. */
-        eliminate_doubles(root_entry,root_entry);
-
-	/* TODO: Why do we use a private/anonymous mapping here
-           followed by a write below, instead of just a shared mapping
-           and a couple of ftruncate calls?  Is it just to save us
-           having to deal with removing the file afterwards?  If we
-           really need this huge anonymous mapping, we ought to mmap
-           in smaller chunks, so that the user doesn't need nn MB of
-           RAM free.  If the reason is to be able to write to
-           un-mmappable block devices, then we could try shared mmap
-           and revert to anonymous mmap if the shared mmap fails. */
-	rom_image = mmap(NULL, fslen_ub?fslen_ub:1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-
-	if (-1 == (int) (long) rom_image) {
-		perror("ROM image map");
-		exit(8);
-	}
-
-	/* Skip the first opt_pad bytes for boot loader code */
-	offset = opt_pad;
-	memset(rom_image, 0x00, opt_pad);
-
-	/* Skip the superblock and come back to write it later. */
-	offset += sizeof(struct cramfs_super);
-
-	/* Insert a file image. */
-	if (opt_image) {
-		printf("Including: %s\n", opt_image);
-		offset = write_file(opt_image, rom_image, offset);
-	}
-
-	offset = write_directory_structure(root_entry->child, rom_image, offset);
-	printf("Directory data: %d bytes\n", offset);
-
-	offset = write_data(root_entry, rom_image, offset);
-
-	/* We always write a multiple of blksize bytes, so that
-           losetup works. */
-	offset = ((offset - 1) | (blksize - 1)) + 1;
-	printf("Everything: %d kilobytes\n", offset >> 10);
-
-	/* Write the superblock now that we can fill in all of the fields. */
-	write_superblock(root_entry, rom_image+opt_pad, offset);
-	printf("Super block: %d bytes\n", sizeof(struct cramfs_super));
-
-	/* Put the checksum in. */
-	crc = crc32(crc, (rom_image+opt_pad), (offset-opt_pad));
-	((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = crc;
-	printf("CRC: %x\n", crc);
-
-	/* Check to make sure we allocated enough space. */
-	if (fslen_ub < offset) {
-		fprintf(stderr, "not enough space allocated for ROM image (%Ld allocated, %d used)\n",
-			fslen_ub, offset);
-		exit(8);
-	}
-
-	written = write(fd, rom_image, offset);
-	if (written < 0) {
-		perror("ROM image");
-		exit(8);
-	}
-	if (offset != written) {
-		fprintf(stderr, "ROM image write failed (%d %d)\n", written, offset);
-		exit(8);
-	}
-
-	/* (These warnings used to come at the start, but they scroll off the
-           screen too quickly.) */
-	if (warn_namelen) /* (can't happen when reading from ext2fs) */
-		fprintf(stderr, /* bytes, not chars: think UTF8. */
-			"warning: filenames truncated to 255 bytes.\n");
-	if (warn_skip)
-		fprintf(stderr, "warning: files were skipped due to errors.\n");
-	if (warn_size)
-		fprintf(stderr,
-			"warning: file sizes truncated to %luMB (minus 1 byte).\n",
-			1L << (CRAMFS_SIZE_WIDTH - 20));
-	if (warn_uid) /* (not possible with current Linux versions) */
-		fprintf(stderr,
-			"warning: uids truncated to %u bits.  (This may be a security concern.)\n",
-			CRAMFS_UID_WIDTH);
-	if (warn_gid)
-		fprintf(stderr,
-			"warning: gids truncated to %u bits.  (This may be a security concern.)\n",
-			CRAMFS_GID_WIDTH);
-	if (warn_dev)
-		fprintf(stderr,
-			"WARNING: device numbers truncated to %u bits.  This almost certainly means\n"
-			"that some device files will be wrong.\n",
-			CRAMFS_OFFSET_WIDTH);
-	if (opt_errors &&
-	    (warn_namelen||warn_skip||warn_size||warn_uid||warn_gid||warn_dev))
-		exit(8);
-	return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/kernel-doc linux/scripts/kernel-doc
--- linux.orig/scripts/kernel-doc	2001-10-05 19:06:51.000000000 +0000
+++ linux/scripts/kernel-doc	2002-07-20 01:08:35.000000000 +0000
@@ -233,9 +233,17 @@
 # CAVEAT EMPTOR!  Some of the others I localised may not want to be which
 # could cause "use of undefined value" or other bugs.
 my ($function, %function_table,%parametertypes,$declaration_purpose);
-my ($type,$file,$declaration_name,$return_type);
+my ($type,$declaration_name,$return_type);
 my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
 
+# Generated docbook code is inserted in a template at a point where 
+# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
+# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
+# We keep track of number of generated entries and generate a dummy
+# if needs be to ensure the expanded template can be postprocessed
+# into html.
+my $section_counter = 0;
+
 my $lineprefix="";
 
 # states
@@ -870,7 +878,7 @@
     my ($parameter, $section);
     my $count;
 
-    print ".TH \"$args{'module'}\" 9 \"$args{'function'}\" \"$man_date\" \"API Manual\" LINUX\n";
+    print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"25 May 1998\" \"Kernel Hacker's Manual\" LINUX\n";
 
     print ".SH NAME\n";
     print $args{'function'}." \\- ".$args{'purpose'}."\n";
@@ -896,13 +904,13 @@
 	$parenth = "";
     }
 
-    print ".SH Arguments\n";
+    print ".SH ARGUMENTS\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
 	print ".IP \"".$parameter."\" 12\n";
 	output_highlight($args{'parameterdescs'}{$parameter});
     }
     foreach $section (@{$args{'sectionlist'}}) {
-	print ".SH \"$section\"\n";
+	print ".SH \"", uc $section, "\"\n";
 	output_highlight($args{'sections'}{$section});
     }
 }
@@ -1158,6 +1166,7 @@
 	( $function_only == 2 && !defined($function_table{$name})))
     {
         &$func(@_);
+	$section_counter++;
     }
 }
 
@@ -1168,6 +1177,7 @@
     no strict 'refs';
     my $func = "output_intro_".$output_mode;
     &$func(@_);
+    $section_counter++;
 }
 
 ##
@@ -1195,7 +1205,7 @@
 	# ignore embedded structs or unions
 	$members =~ s/{.*}//g;
 
-	create_parameterlist($members, ';');
+	create_parameterlist($members, ';', $file);
 
 	output_declaration($declaration_name,
 			   'struct',
@@ -1211,7 +1221,8 @@
 			   });
     }
     else {
-        print STDERR "Cannot parse struct or union!\n";
+        print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
+	++$errors;
     }
 }
 
@@ -1228,8 +1239,8 @@
 	    push @parameterlist, $arg;
 	    if (!$parameterdescs{$arg}) {
 	        $parameterdescs{$arg} = $undescribed;
-	        print STDERR "Warning($file:$.): Enum value '$arg' ".
-		    "described in enum '$declaration_name'\n";
+	        print STDERR "Warning(${file}:$.): Enum value '$arg' ".
+		    "not described in enum '$declaration_name'\n";
 	    }
 
 	}
@@ -1246,7 +1257,8 @@
 			   });
     }
     else {
-        print STDERR "Cannot parse enum!\n";
+        print STDERR "Error(${file}:$.): Cannot parse enum!\n";
+	++$errors;
     }
 }
 
@@ -1272,13 +1284,15 @@
 			   });
     }
     else {
-        print STDERR "Cannot parse typedef!\n";
+        print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
+	++$errors;
     }
 }
 
-sub create_parameterlist($$) {
+sub create_parameterlist($$$) {
     my $args = shift;
     my $splitter = shift;
+    my $file = shift;
     my $type;
     my $param;
 
@@ -1332,7 +1346,7 @@
 	    $parameterdescs{$param} = $undescribed;
 
 	    if (($type eq 'function') || ($type eq 'enum')) {
-	        print STDERR "Warning($file:$.): Function parameter ".
+	        print STDERR "Warning(${file}:$.): Function parameter ".
 		    "or member '$param' not " .
 		    "described in '$declaration_name'\n";
 	    }
@@ -1392,9 +1406,9 @@
 	$declaration_name = $2;
 	my $args = $3;
 
-	create_parameterlist($args, ',');
+	create_parameterlist($args, ',', $file);
     } else {
-	print STDERR "Error($.): cannot understand prototype: '$prototype'\n";
+	print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n";
 	++$errors;
 	return;
     }
@@ -1456,8 +1470,9 @@
     $state = 0;
 }
 
-sub process_state3_function($) { 
+sub process_state3_function($$) { 
     my $x = shift;
+    my $file = shift;
 
     if ($x =~ m#\s*/\*\s+MACDOC\s*#io) {
 	# do nothing
@@ -1474,8 +1489,9 @@
     }
 }
 
-sub process_state3_type($) { 
+sub process_state3_type($$) { 
     my $x = shift;
+    my $file = shift;
 
     $x =~ s@/\*.*?\*/@@gos;	# strip comments.
     $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
@@ -1504,6 +1520,7 @@
     my ($file) = @_;
     my $identifier;
     my $func;
+    my $initial_section_counter = $section_counter;
 
     if (defined($source_map{$file})) {
 	$file = $source_map{$file};
@@ -1515,6 +1532,7 @@
 	return;
     }
 
+    $section_counter = 0;
     while (<IN>) {
 	if ($state == 0) {
 	    if (/$doc_start/o) {
@@ -1555,10 +1573,10 @@
 		}
 
 		if ($verbose) {
-		    print STDERR "Info($.): Scanning doc for $identifier\n";
+		    print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
 		}
 	    } else {
-		print STDERR "WARN($.): Cannot understand $_ on line $.",
+		print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
 		" - I thought it was a doc line\n";
 		++$errors;
 		$state = 0;
@@ -1612,14 +1630,14 @@
 		}
 	    } else {
 		# i dont know - bad line?  ignore.
-		print STDERR "WARNING($.): bad line: $_"; 
+		print STDERR "Warning(${file}:$.): bad line: $_"; 
 		++$errors;
 	    }
 	} elsif ($state == 3) {	# scanning for function { (end of prototype)
 	    if ($decl_type eq 'function') {
-	        process_state3_function($_);
+	        process_state3_function($_, $file);
 	    } else {
-	        process_state3_type($_);
+	        process_state3_type($_, $file);
 	    }
 	} elsif ($state == 4) {
 		# Documentation block
@@ -1671,5 +1689,35 @@
         	}
           }
     }
+    if ($initial_section_counter == $section_counter) {
+	print STDERR "Warning(${file}): no structured comments found\n";
+	if ($output_mode eq "sgml") {
+	    # The template wants at least one RefEntry here; make one.
+	    print "<refentry>\n";
+	    print " <refnamediv>\n";
+	    print "  <refname>\n";
+	    print "   ${file}\n";
+	    print "  </refname>\n";
+	    print "  <refpurpose>\n";
+	    print "   Document generation inconsistency\n";
+	    print "  </refpurpose>\n";
+	    print " </refnamediv>\n";
+	    print " <refsect1>\n";
+	    print "  <title>\n";
+	    print "   Oops\n";
+	    print "  </title>\n";
+	    print "  <warning>\n";
+	    print "   <para>\n";
+	    print "    The template for this document tried to insert\n";
+	    print "    the structured comment from the file\n";
+	    print "    <filename>${file}</filename> at this point,\n";
+	    print "    but none was found.\n";
+	    print "    This dummy section is inserted to allow\n";
+	    print "    generation to continue.\n";
+	    print "   </para>\n";
+	    print "  </warning>\n";
+	    print " </refsect1>\n";
+	    print "</refentry>\n";
+	}
+    }
 }
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/mkdep.c linux/scripts/mkdep.c
--- linux.orig/scripts/mkdep.c	2001-09-14 21:40:00.000000000 +0000
+++ linux/scripts/mkdep.c	2002-07-20 01:08:31.000000000 +0000
@@ -268,7 +268,7 @@
 
 	for (i = 0; i < len; i++) {
 	    char c = name[i];
-	    if (isupper(c)) c = tolower(c);
+	    if (isupper((int)c)) c = tolower((int)c);
 	    if (c == '_')   c = '/';
 	    pc[i] = c;
 	}
@@ -496,7 +496,7 @@
 
 /* \<CONFIG_(\w*) */
 cee:
-	if (next >= map+2 && (isalnum(next[-2]) || next[-2] == '_'))
+	if (next >= map+2 && (isalnum((int)next[-2]) || next[-2] == '_'))
 		goto start;
 	GETNEXT NOTCASE('O', __start);
 	GETNEXT NOTCASE('N', __start);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/mkspec linux/scripts/mkspec
--- linux.orig/scripts/mkspec	2002-02-25 19:38:16.000000000 +0000
+++ linux/scripts/mkspec	2002-07-20 01:08:22.000000000 +0000
@@ -6,6 +6,22 @@
 #	The only gothic bit here is redefining install_post to avoid 
 #	stripping the symbols from files in the kernel which we want
 #
+#	Patched for non-x86 by Opencon (L) 2002 <opencon@rio.skydome.net>
+#
+# That's the voodoo to see if it's a x86.
+ISX86=`arch | grep -ie i.86`
+if [ ! -z $ISX86 ]; then
+	PC=1
+else
+	PC=0
+fi
+# starting to output the spec
+if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then
+	PROVIDES=kernel-drm
+fi
+
+PROVIDES="$PROVIDES kernel-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
+
 echo "Name: kernel"
 echo "Summary: The Linux Kernel"
 echo "Version: "$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION | sed -e "s/-//g"
@@ -19,6 +35,7 @@
 echo -n "Source: kernel-$VERSION.$PATCHLEVEL.$SUBLEVEL"
 echo "$EXTRAVERSION.tar.gz" | sed -e "s/-//g"
 echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root"
+echo "Provides: $PROVIDES"
 echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
 echo ""
 echo "%description"
@@ -28,13 +45,26 @@
 echo "%setup -q"
 echo ""
 echo "%build"
-echo "make oldconfig dep clean bzImage modules"
+# This is the first 'disagreement' between x86 and other archs.
+if [ $PC = 1 ]; then 
+	echo "make oldconfig dep clean bzImage modules"
+else
+	echo "make oldconfig dep clean vmlinux modules"
+fi
+# Back on track
 echo ""
 echo "%install"
 echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules'
 echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make modules_install'
-echo 'cp arch/i386/boot/bzImage $RPM_BUILD_ROOT'"/boot/vmlinuz-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
+# And that's the second
+if [ $PC = 1 ]; then
+	echo 'cp arch/i386/boot/bzImage $RPM_BUILD_ROOT'"/boot/vmlinuz-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
+else
+	echo 'cp vmlinux $RPM_BUILD_ROOT'"/boot/vmlinux-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
+fi
+# Back on track, again
 echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
+echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
 echo ""
 echo "%clean"
 echo '#echo -rf $RPM_BUILD_ROOT'
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/patch-kernel linux/scripts/patch-kernel
--- linux.orig/scripts/patch-kernel	2001-11-09 22:12:54.000000000 +0000
+++ linux/scripts/patch-kernel	2002-07-20 01:08:30.000000000 +0000
@@ -46,6 +46,15 @@
 patchdir=${2-.}
 stopvers=${3-imnotaversion}
 
+if [ "$1" = -h -o "$1" = --help -o ! -r "$sourcedir/Makefile" ]; then
+cat << USAGE
+usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
+  The source directory defaults to /usr/src/linux, and
+  the patch directory defaults to the current directory.
+USAGE
+exit 1
+fi
+
 # See if we have any -ac options
 for PARM in $*
 do
@@ -59,7 +68,7 @@
 # ---------------------------------------------------------------------------
 # Find a file, first parameter is basename of file
 # it tries many compression mechanisms and sets variables to say how to get it
-function findFile {
+findFile () {
   filebase=$1;
 
   if [ -r ${filebase}.gz ]; then
@@ -97,7 +106,7 @@
 # Apply a patch and check it goes in cleanly
 # First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension
 
-function applyPatch {
+applyPatch () {
   echo -n "Applying $1 (${name})... "
   if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir
   then
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/split-include.c linux/scripts/split-include.c
--- linux.orig/scripts/split-include.c	2001-10-08 18:46:09.000000000 +0000
+++ linux/scripts/split-include.c	2002-07-20 01:08:32.000000000 +0000
@@ -115,10 +115,10 @@
 
 	/* Make the output file name. */
 	str_config += sizeof("CONFIG_") - 1;
-	for (itarget = 0; !isspace(str_config[itarget]); itarget++)
+	for (itarget = 0; !isspace((int)str_config[itarget]); itarget++)
 	{
 	    char c = str_config[itarget];
-	    if (isupper(c)) c = tolower(c);
+	    if (isupper((int)c)) c = tolower((int)c);
 	    if (c == '_')   c = '/';
 	    ptarget[itarget] = c;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/split-man linux/scripts/split-man
--- linux.orig/scripts/split-man	1970-01-01 00:00:00.000000000 +0000
+++ linux/scripts/split-man	2002-07-20 01:08:30.000000000 +0000
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+#
+#      split-man: create man pages from kernel-doc -man output
+#
+# Author:	Tim Waugh <twaugh@redhat.com>
+# Modified by:	Christoph Hellwig <hch@infradead.org>
+#
+
+use strict;
+
+die "$0: where do I put the results?\n" unless ($#ARGV >= 0);
+die "$0: can't create $ARGV[0]: $!\n" unless mkdir $ARGV[0], 0777;
+
+my $state = 0;
+
+while (<STDIN>) {
+	s/&amp;(\w+)/\\fB\1\\fP/g; # fix smgl uglinesses
+	if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) {
+		close OUT unless ($state++ == 0);
+		my $fn = "$ARGV[0]/$1.9";
+		if (open OUT, ">$fn") {
+			print STDERR "creating $fn\n";
+		} else {
+			die "can't open $fn: $!\n";
+		}
+
+		print OUT $_;
+	} elsif ($state != 0) {
+		print OUT $_;
+	}
+}
+
+close OUT;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/tkgen.c linux/scripts/tkgen.c
--- linux.orig/scripts/tkgen.c	2001-04-06 17:42:55.000000000 +0000
+++ linux/scripts/tkgen.c	2002-07-20 01:08:39.000000000 +0000
@@ -620,11 +620,11 @@
 	case token_int:
 	    if ( cfg->value && *cfg->value == '$' )
 	    {
-		int index = get_varnum( cfg->value+1 );
+		int i = get_varnum( cfg->value+1 );
 		printf( "\n" );
-		if ( ! vartable[index].global_written )
+		if ( ! vartable[i].global_written )
 		{
-		    global( vartable[index].name );
+		    global( vartable[i].name );
 		}
 		printf( "\t" );
 	    }
@@ -989,7 +989,6 @@
 static void end_proc( struct kconfig * scfg, int menu_num )
 {
     struct kconfig * cfg;
-    int i;
 
     printf( "\n\n\n" );
     printf( "\tfocus $w\n" );
@@ -1084,6 +1083,7 @@
 	    {
 		if ( cfg->token == token_tristate )
 		{
+		    int i;
 		    if ( ! vartable[cfg->nameindex].global_written )
 		    {
 			vartable[cfg->nameindex].global_written = 1;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/tkparse.c linux/scripts/tkparse.c
--- linux.orig/scripts/tkparse.c	2000-10-08 16:30:40.000000000 +0000
+++ linux/scripts/tkparse.c	2002-07-20 01:08:21.000000000 +0000
@@ -74,12 +74,12 @@
 
 
 /*
- * Find index of a specyfic variable in the symbol table.
+ * Find index of a specific variable in the symbol table.
  * Create a new entry if it does not exist yet.
  */
-#define VARTABLE_SIZE 2048
-struct variable vartable[VARTABLE_SIZE];
+struct variable *vartable;
 int max_varnum = 0;
+static int vartable_size = 0;
 
 int get_varnum( char * name )
 {
@@ -88,8 +88,13 @@
     for ( i = 1; i <= max_varnum; i++ )
 	if ( strcmp( vartable[i].name, name ) == 0 )
 	    return i;
-    if (max_varnum > VARTABLE_SIZE-1)
-	syntax_error( "Too many variables defined." );
+    while (max_varnum+1 >= vartable_size) {
+	vartable = realloc(vartable, (vartable_size += 1000)*sizeof(*vartable));
+	if (!vartable) {
+	    fprintf(stderr, "tkparse realloc vartable failed\n");
+	    exit(1);
+	}
+    }
     vartable[++max_varnum].name = malloc( strlen( name )+1 );
     strcpy( vartable[max_varnum].name, name );
     return max_varnum;
@@ -818,5 +823,6 @@
     do_source        ( "-"         );
     fix_conditionals ( config_list );
     dump_tk_script   ( config_list );
+    free(vartable);
     return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/scripts/tkparse.h linux/scripts/tkparse.h
--- linux.orig/scripts/tkparse.h	2000-02-21 04:13:10.000000000 +0000
+++ linux/scripts/tkparse.h	2002-07-20 01:08:28.000000000 +0000
@@ -115,7 +115,7 @@
     char	global_written;
 };
 
-extern struct variable vartable[];
+extern struct variable *vartable;
 extern int max_varnum;
 
 /*
